[
  {
    "path": ".gitignore",
    "content": "# Uncomment these types if you want even more clean repository. But be careful.\n# It can make harm to an existing project source. Read explanations below.\n#\n# Resource files are binaries containing manifest, project icon and version info.\n# They can not be viewed as text or compared by diff-tools. Consider replacing them with .rc files.\n#*.res\n#\n# Type library file (binary). In old Delphi versions it should be stored.\n# Since Delphi 2009 it is produced from .ridl file and can safely be ignored.\n#*.tlb\n#\n# Diagram Portfolio file. Used by the diagram editor up to Delphi 7.\n# Uncomment this if you are not using diagrams or use newer Delphi version.\n#*.ddp\n#\n# Visual LiveBindings file. Added in Delphi XE2.\n# Uncomment this if you are not using LiveBindings Designer.\n#*.vlb\n#\n# Deployment Manager configuration file for your project. Added in Delphi XE2.\n# Uncomment this if it is not mobile development and you do not use remote debug feature.\n#*.deployproj\n#\n\n# Delphi compiler-generated binaries (safe to delete)\n*.exe\n*.dll\n*.bpl\n*.bpi\n*.dcp\n*.so\n*.apk\n*.drc\n*.map\n*.dres\n*.rsm\n*.tds\n*.dcu\n*.lib\n\n# Delphi autogenerated files (duplicated info)\n*.cfg\n*Resource.rc\n\n# Delphi local files (user-specific info)\n*.local\n*.identcache\n*.projdata\n*.tvsconfig\n*.dsk\n\n# Delphi history and backups\n__history/\n*.~*\n\n# Castalia statistics file\n*.stat\n\n# Repository ignore\n*.ini\n*.zip\nbackend/logs/*.txt\nloc/\ntest/\nfrontend/__history/\nfrontend/logs/\nfrontend/patches/\n*.txaPackage\nfrontend/profiles/\n"
  },
  {
    "path": "LICENSE.txt",
    "content": "                          MOZILLA PUBLIC LICENSE\n                                Version 1.1\n\n                              ---------------\n\n1. Definitions.\n\n     1.0.1. \"Commercial Use\" means distribution or otherwise making the\n     Covered Code available to a third party.\n\n     1.1. \"Contributor\" means each entity that creates or contributes to\n     the creation of Modifications.\n\n     1.2. \"Contributor Version\" means the combination of the Original\n     Code, prior Modifications used by a Contributor, and the Modifications\n     made by that particular Contributor.\n\n     1.3. \"Covered Code\" means the Original Code or Modifications or the\n     combination of the Original Code and Modifications, in each case\n     including portions thereof.\n\n     1.4. \"Electronic Distribution Mechanism\" means a mechanism generally\n     accepted in the software development community for the electronic\n     transfer of data.\n\n     1.5. \"Executable\" means Covered Code in any form other than Source\n     Code.\n\n     1.6. \"Initial Developer\" means the individual or entity identified\n     as the Initial Developer in the Source Code notice required by Exhibit\n     A.\n\n     1.7. \"Larger Work\" means a work which combines Covered Code or\n     portions thereof with code not governed by the terms of this License.\n\n     1.8. \"License\" means this document.\n\n     1.8.1. \"Licensable\" means having the right to grant, to the maximum\n     extent possible, whether at the time of the initial grant or\n     subsequently acquired, any and all of the rights conveyed herein.\n\n     1.9. \"Modifications\" means any addition to or deletion from the\n     substance or structure of either the Original Code or any previous\n     Modifications. When Covered Code is released as a series of files, a\n     Modification is:\n          A. Any addition to or deletion from the contents of a file\n          containing Original Code or previous Modifications.\n\n          B. Any new file that contains any part of the Original Code or\n          previous Modifications.\n\n     1.10. \"Original Code\" means Source Code of computer software code\n     which is described in the Source Code notice required by Exhibit A as\n     Original Code, and which, at the time of its release under this\n     License is not already Covered Code governed by this License.\n\n     1.10.1. \"Patent Claims\" means any patent claim(s), now owned or\n     hereafter acquired, including without limitation,  method, process,\n     and apparatus claims, in any patent Licensable by grantor.\n\n     1.11. \"Source Code\" means the preferred form of the Covered Code for\n     making modifications to it, including all modules it contains, plus\n     any associated interface definition files, scripts used to control\n     compilation and installation of an Executable, or source code\n     differential comparisons against either the Original Code or another\n     well known, available Covered Code of the Contributor's choice. The\n     Source Code can be in a compressed or archival form, provided the\n     appropriate decompression or de-archiving software is widely available\n     for no charge.\n\n     1.12. \"You\" (or \"Your\")  means an individual or a legal entity\n     exercising rights under, and complying with all of the terms of, this\n     License or a future version of this License issued under Section 6.1.\n     For legal entities, \"You\" includes any entity which controls, is\n     controlled by, or is under common control with You. For purposes of\n     this definition, \"control\" means (a) the power, direct or indirect,\n     to cause the direction or management of such entity, whether by\n     contract or otherwise, or (b) ownership of more than fifty percent\n     (50%) of the outstanding shares or beneficial ownership of such\n     entity.\n\n2. Source Code License.\n\n     2.1. The Initial Developer Grant.\n     The Initial Developer hereby grants You a world-wide, royalty-free,\n     non-exclusive license, subject to third party intellectual property\n     claims:\n          (a)  under intellectual property rights (other than patent or\n          trademark) Licensable by Initial Developer to use, reproduce,\n          modify, display, perform, sublicense and distribute the Original\n          Code (or portions thereof) with or without Modifications, and/or\n          as part of a Larger Work; and\n\n          (b) under Patents Claims infringed by the making, using or\n          selling of Original Code, to make, have made, use, practice,\n          sell, and offer for sale, and/or otherwise dispose of the\n          Original Code (or portions thereof).\n\n          (c) the licenses granted in this Section 2.1(a) and (b) are\n          effective on the date Initial Developer first distributes\n          Original Code under the terms of this License.\n\n          (d) Notwithstanding Section 2.1(b) above, no patent license is\n          granted: 1) for code that You delete from the Original Code; 2)\n          separate from the Original Code;  or 3) for infringements caused\n          by: i) the modification of the Original Code or ii) the\n          combination of the Original Code with other software or devices.\n\n     2.2. Contributor Grant.\n     Subject to third party intellectual property claims, each Contributor\n     hereby grants You a world-wide, royalty-free, non-exclusive license\n\n          (a)  under intellectual property rights (other than patent or\n          trademark) Licensable by Contributor, to use, reproduce, modify,\n          display, perform, sublicense and distribute the Modifications\n          created by such Contributor (or portions thereof) either on an\n          unmodified basis, with other Modifications, as Covered Code\n          and/or as part of a Larger Work; and\n\n          (b) under Patent Claims infringed by the making, using, or\n          selling of  Modifications made by that Contributor either alone\n          and/or in combination with its Contributor Version (or portions\n          of such combination), to make, use, sell, offer for sale, have\n          made, and/or otherwise dispose of: 1) Modifications made by that\n          Contributor (or portions thereof); and 2) the combination of\n          Modifications made by that Contributor with its Contributor\n          Version (or portions of such combination).\n\n          (c) the licenses granted in Sections 2.2(a) and 2.2(b) are\n          effective on the date Contributor first makes Commercial Use of\n          the Covered Code.\n\n          (d)    Notwithstanding Section 2.2(b) above, no patent license is\n          granted: 1) for any code that Contributor has deleted from the\n          Contributor Version; 2)  separate from the Contributor Version;\n          3)  for infringements caused by: i) third party modifications of\n          Contributor Version or ii)  the combination of Modifications made\n          by that Contributor with other software  (except as part of the\n          Contributor Version) or other devices; or 4) under Patent Claims\n          infringed by Covered Code in the absence of Modifications made by\n          that Contributor.\n\n3. Distribution Obligations.\n\n     3.1. Application of License.\n     The Modifications which You create or to which You contribute are\n     governed by the terms of this License, including without limitation\n     Section 2.2. The Source Code version of Covered Code may be\n     distributed only under the terms of this License or a future version\n     of this License released under Section 6.1, and You must include a\n     copy of this License with every copy of the Source Code You\n     distribute. You may not offer or impose any terms on any Source Code\n     version that alters or restricts the applicable version of this\n     License or the recipients' rights hereunder. However, You may include\n     an additional document offering the additional rights described in\n     Section 3.5.\n\n     3.2. Availability of Source Code.\n     Any Modification which You create or to which You contribute must be\n     made available in Source Code form under the terms of this License\n     either on the same media as an Executable version or via an accepted\n     Electronic Distribution Mechanism to anyone to whom you made an\n     Executable version available; and if made available via Electronic\n     Distribution Mechanism, must remain available for at least twelve (12)\n     months after the date it initially became available, or at least six\n     (6) months after a subsequent version of that particular Modification\n     has been made available to such recipients. You are responsible for\n     ensuring that the Source Code version remains available even if the\n     Electronic Distribution Mechanism is maintained by a third party.\n\n     3.3. Description of Modifications.\n     You must cause all Covered Code to which You contribute to contain a\n     file documenting the changes You made to create that Covered Code and\n     the date of any change. You must include a prominent statement that\n     the Modification is derived, directly or indirectly, from Original\n     Code provided by the Initial Developer and including the name of the\n     Initial Developer in (a) the Source Code, and (b) in any notice in an\n     Executable version or related documentation in which You describe the\n     origin or ownership of the Covered Code.\n\n     3.4. Intellectual Property Matters\n          (a) Third Party Claims.\n          If Contributor has knowledge that a license under a third party's\n          intellectual property rights is required to exercise the rights\n          granted by such Contributor under Sections 2.1 or 2.2,\n          Contributor must include a text file with the Source Code\n          distribution titled \"LEGAL\" which describes the claim and the\n          party making the claim in sufficient detail that a recipient will\n          know whom to contact. If Contributor obtains such knowledge after\n          the Modification is made available as described in Section 3.2,\n          Contributor shall promptly modify the LEGAL file in all copies\n          Contributor makes available thereafter and shall take other steps\n          (such as notifying appropriate mailing lists or newsgroups)\n          reasonably calculated to inform those who received the Covered\n          Code that new knowledge has been obtained.\n\n          (b) Contributor APIs.\n          If Contributor's Modifications include an application programming\n          interface and Contributor has knowledge of patent licenses which\n          are reasonably necessary to implement that API, Contributor must\n          also include this information in the LEGAL file.\n\n               (c)    Representations.\n          Contributor represents that, except as disclosed pursuant to\n          Section 3.4(a) above, Contributor believes that Contributor's\n          Modifications are Contributor's original creation(s) and/or\n          Contributor has sufficient rights to grant the rights conveyed by\n          this License.\n\n     3.5. Required Notices.\n     You must duplicate the notice in Exhibit A in each file of the Source\n     Code.  If it is not possible to put such notice in a particular Source\n     Code file due to its structure, then You must include such notice in a\n     location (such as a relevant directory) where a user would be likely\n     to look for such a notice.  If You created one or more Modification(s)\n     You may add your name as a Contributor to the notice described in\n     Exhibit A.  You must also duplicate this License in any documentation\n     for the Source Code where You describe recipients' rights or ownership\n     rights relating to Covered Code.  You may choose to offer, and to\n     charge a fee for, warranty, support, indemnity or liability\n     obligations to one or more recipients of Covered Code. However, You\n     may do so only on Your own behalf, and not on behalf of the Initial\n     Developer or any Contributor. You must make it absolutely clear than\n     any such warranty, support, indemnity or liability obligation is\n     offered by You alone, and You hereby agree to indemnify the Initial\n     Developer and every Contributor for any liability incurred by the\n     Initial Developer or such Contributor as a result of warranty,\n     support, indemnity or liability terms You offer.\n\n     3.6. Distribution of Executable Versions.\n     You may distribute Covered Code in Executable form only if the\n     requirements of Section 3.1-3.5 have been met for that Covered Code,\n     and if You include a notice stating that the Source Code version of\n     the Covered Code is available under the terms of this License,\n     including a description of how and where You have fulfilled the\n     obligations of Section 3.2. The notice must be conspicuously included\n     in any notice in an Executable version, related documentation or\n     collateral in which You describe recipients' rights relating to the\n     Covered Code. You may distribute the Executable version of Covered\n     Code or ownership rights under a license of Your choice, which may\n     contain terms different from this License, provided that You are in\n     compliance with the terms of this License and that the license for the\n     Executable version does not attempt to limit or alter the recipient's\n     rights in the Source Code version from the rights set forth in this\n     License. If You distribute the Executable version under a different\n     license You must make it absolutely clear that any terms which differ\n     from this License are offered by You alone, not by the Initial\n     Developer or any Contributor. You hereby agree to indemnify the\n     Initial Developer and every Contributor for any liability incurred by\n     the Initial Developer or such Contributor as a result of any such\n     terms You offer.\n\n     3.7. Larger Works.\n     You may create a Larger Work by combining Covered Code with other code\n     not governed by the terms of this License and distribute the Larger\n     Work as a single product. In such a case, You must make sure the\n     requirements of this License are fulfilled for the Covered Code.\n\n4. Inability to Comply Due to Statute or Regulation.\n\n     If it is impossible for You to comply with any of the terms of this\n     License with respect to some or all of the Covered Code due to\n     statute, judicial order, or regulation then You must: (a) comply with\n     the terms of this License to the maximum extent possible; and (b)\n     describe the limitations and the code they affect. Such description\n     must be included in the LEGAL file described in Section 3.4 and must\n     be included with all distributions of the Source Code. Except to the\n     extent prohibited by statute or regulation, such description must be\n     sufficiently detailed for a recipient of ordinary skill to be able to\n     understand it.\n\n5. Application of this License.\n\n     This License applies to code to which the Initial Developer has\n     attached the notice in Exhibit A and to related Covered Code.\n\n6. Versions of the License.\n\n     6.1. New Versions.\n     Netscape Communications Corporation (\"Netscape\") may publish revised\n     and/or new versions of the License from time to time. Each version\n     will be given a distinguishing version number.\n\n     6.2. Effect of New Versions.\n     Once Covered Code has been published under a particular version of the\n     License, You may always continue to use it under the terms of that\n     version. You may also choose to use such Covered Code under the terms\n     of any subsequent version of the License published by Netscape. No one\n     other than Netscape has the right to modify the terms applicable to\n     Covered Code created under this License.\n\n     6.3. Derivative Works.\n     If You create or use a modified version of this License (which you may\n     only do in order to apply it to code which is not already Covered Code\n     governed by this License), You must (a) rename Your license so that\n     the phrases \"Mozilla\", \"MOZILLAPL\", \"MOZPL\", \"Netscape\",\n     \"MPL\", \"NPL\" or any confusingly similar phrase do not appear in your\n     license (except to note that your license differs from this License)\n     and (b) otherwise make it clear that Your version of the license\n     contains terms which differ from the Mozilla Public License and\n     Netscape Public License. (Filling in the name of the Initial\n     Developer, Original Code or Contributor in the notice described in\n     Exhibit A shall not of themselves be deemed to be modifications of\n     this License.)\n\n7. DISCLAIMER OF WARRANTY.\n\n     COVERED CODE IS PROVIDED UNDER THIS LICENSE ON AN \"AS IS\" BASIS,\n     WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,\n     WITHOUT LIMITATION, WARRANTIES THAT THE COVERED CODE IS FREE OF\n     DEFECTS, MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE OR NON-INFRINGING.\n     THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE COVERED CODE\n     IS WITH YOU. SHOULD ANY COVERED CODE PROVE DEFECTIVE IN ANY RESPECT,\n     YOU (NOT THE INITIAL DEVELOPER OR ANY OTHER CONTRIBUTOR) ASSUME THE\n     COST OF ANY NECESSARY SERVICING, REPAIR OR CORRECTION. THIS DISCLAIMER\n     OF WARRANTY CONSTITUTES AN ESSENTIAL PART OF THIS LICENSE. NO USE OF\n     ANY COVERED CODE IS AUTHORIZED HEREUNDER EXCEPT UNDER THIS DISCLAIMER.\n\n8. TERMINATION.\n\n     8.1.  This License and the rights granted hereunder will terminate\n     automatically if You fail to comply with terms herein and fail to cure\n     such breach within 30 days of becoming aware of the breach. All\n     sublicenses to the Covered Code which are properly granted shall\n     survive any termination of this License. Provisions which, by their\n     nature, must remain in effect beyond the termination of this License\n     shall survive.\n\n     8.2.  If You initiate litigation by asserting a patent infringement\n     claim (excluding declatory judgment actions) against Initial Developer\n     or a Contributor (the Initial Developer or Contributor against whom\n     You file such action is referred to as \"Participant\")  alleging that:\n\n     (a)  such Participant's Contributor Version directly or indirectly\n     infringes any patent, then any and all rights granted by such\n     Participant to You under Sections 2.1 and/or 2.2 of this License\n     shall, upon 60 days notice from Participant terminate prospectively,\n     unless if within 60 days after receipt of notice You either: (i)\n     agree in writing to pay Participant a mutually agreeable reasonable\n     royalty for Your past and future use of Modifications made by such\n     Participant, or (ii) withdraw Your litigation claim with respect to\n     the Contributor Version against such Participant.  If within 60 days\n     of notice, a reasonable royalty and payment arrangement are not\n     mutually agreed upon in writing by the parties or the litigation claim\n     is not withdrawn, the rights granted by Participant to You under\n     Sections 2.1 and/or 2.2 automatically terminate at the expiration of\n     the 60 day notice period specified above.\n\n     (b)  any software, hardware, or device, other than such Participant's\n     Contributor Version, directly or indirectly infringes any patent, then\n     any rights granted to You by such Participant under Sections 2.1(b)\n     and 2.2(b) are revoked effective as of the date You first made, used,\n     sold, distributed, or had made, Modifications made by that\n     Participant.\n\n     8.3.  If You assert a patent infringement claim against Participant\n     alleging that such Participant's Contributor Version directly or\n     indirectly infringes any patent where such claim is resolved (such as\n     by license or settlement) prior to the initiation of patent\n     infringement litigation, then the reasonable value of the licenses\n     granted by such Participant under Sections 2.1 or 2.2 shall be taken\n     into account in determining the amount or value of any payment or\n     license.\n\n     8.4.  In the event of termination under Sections 8.1 or 8.2 above,\n     all end user license agreements (excluding distributors and resellers)\n     which have been validly granted by You or any distributor hereunder\n     prior to termination shall survive termination.\n\n9. LIMITATION OF LIABILITY.\n\n     UNDER NO CIRCUMSTANCES AND UNDER NO LEGAL THEORY, WHETHER TORT\n     (INCLUDING NEGLIGENCE), CONTRACT, OR OTHERWISE, SHALL YOU, THE INITIAL\n     DEVELOPER, ANY OTHER CONTRIBUTOR, OR ANY DISTRIBUTOR OF COVERED CODE,\n     OR ANY SUPPLIER OF ANY OF SUCH PARTIES, BE LIABLE TO ANY PERSON FOR\n     ANY INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES OF ANY\n     CHARACTER INCLUDING, WITHOUT LIMITATION, DAMAGES FOR LOSS OF GOODWILL,\n     WORK STOPPAGE, COMPUTER FAILURE OR MALFUNCTION, OR ANY AND ALL OTHER\n     COMMERCIAL DAMAGES OR LOSSES, EVEN IF SUCH PARTY SHALL HAVE BEEN\n     INFORMED OF THE POSSIBILITY OF SUCH DAMAGES. THIS LIMITATION OF\n     LIABILITY SHALL NOT APPLY TO LIABILITY FOR DEATH OR PERSONAL INJURY\n     RESULTING FROM SUCH PARTY'S NEGLIGENCE TO THE EXTENT APPLICABLE LAW\n     PROHIBITS SUCH LIMITATION. SOME JURISDICTIONS DO NOT ALLOW THE\n     EXCLUSION OR LIMITATION OF INCIDENTAL OR CONSEQUENTIAL DAMAGES, SO\n     THIS EXCLUSION AND LIMITATION MAY NOT APPLY TO YOU.\n\n10. U.S. GOVERNMENT END USERS.\n\n     The Covered Code is a \"commercial item,\" as that term is defined in\n     48 C.F.R. 2.101 (Oct. 1995), consisting of \"commercial computer\n     software\" and \"commercial computer software documentation,\" as such\n     terms are used in 48 C.F.R. 12.212 (Sept. 1995). Consistent with 48\n     C.F.R. 12.212 and 48 C.F.R. 227.7202-1 through 227.7202-4 (June 1995),\n     all U.S. Government End Users acquire Covered Code with only those\n     rights set forth herein.\n\n11. MISCELLANEOUS.\n\n     This License represents the complete agreement concerning subject\n     matter hereof. If any provision of this License is held to be\n     unenforceable, such provision shall be reformed only to the extent\n     necessary to make it enforceable. This License shall be governed by\n     California law provisions (except to the extent applicable law, if\n     any, provides otherwise), excluding its conflict-of-law provisions.\n     With respect to disputes in which at least one party is a citizen of,\n     or an entity chartered or registered to do business in the United\n     States of America, any litigation relating to this License shall be\n     subject to the jurisdiction of the Federal Courts of the Northern\n     District of California, with venue lying in Santa Clara County,\n     California, with the losing party responsible for costs, including\n     without limitation, court costs and reasonable attorneys' fees and\n     expenses. The application of the United Nations Convention on\n     Contracts for the International Sale of Goods is expressly excluded.\n     Any law or regulation which provides that the language of a contract\n     shall be construed against the drafter shall not apply to this\n     License.\n\n12. RESPONSIBILITY FOR CLAIMS.\n\n     As between Initial Developer and the Contributors, each party is\n     responsible for claims and damages arising, directly or indirectly,\n     out of its utilization of rights under this License and You agree to\n     work with Initial Developer and Contributors to distribute such\n     responsibility on an equitable basis. Nothing herein is intended or\n     shall be deemed to constitute any admission of liability.\n\n13. MULTIPLE-LICENSED CODE.\n\n     Initial Developer may designate portions of the Covered Code as\n     \"Multiple-Licensed\".  \"Multiple-Licensed\" means that the Initial\n     Developer permits you to utilize portions of the Covered Code under\n     Your choice of the NPL or the alternative licenses, if any, specified\n     by the Initial Developer in the file described in Exhibit A.\n\nEXHIBIT A -Mozilla Public License.\n\n     ``The contents of this file are subject to the Mozilla Public License\n     Version 1.1 (the \"License\"); you may not use this file except in\n     compliance with the License. You may obtain a copy of the License at\n     http://www.mozilla.org/MPL/\n\n     Software distributed under the License is distributed on an \"AS IS\"\n     basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the\n     License for the specific language governing rights and limitations\n     under the License.\n\n     The Original Code is ______________________________________.\n\n     The Initial Developer of the Original Code is ________________________.\n     Portions created by ______________________ are Copyright (C) ______\n     _______________________. All Rights Reserved.\n\n     Contributor(s): ______________________________________.\n\n     Alternatively, the contents of this file may be used under the terms\n     of the _____ license (the  \"[___] License\"), in which case the\n     provisions of [______] License are applicable instead of those\n     above.  If you wish to allow use of your version of this file only\n     under the terms of the [____] License and not to allow others to use\n     your version of this file under the MPL, indicate your decision by\n     deleting  the provisions above and replace  them with the notice and\n     other provisions required by the [___] License.  If you do not delete\n     the provisions above, a recipient may use your version of this file\n     under either the MPL or the [___] License.\"\n\n     [NOTE: The text of this Exhibit A may differ slightly from the text of\n     the notices in the Source Code files of the Original Code. You should\n     use the text of this Exhibit A rather than the text found in the\n     Original Code Source Code for Your Modifications.]"
  },
  {
    "path": "README.md",
    "content": "# smash\nA tool for performing automatic conflict resolution between multiple Bethesda Plugin Files for TES and Fallout games.\n\n## explanation\nCharacters, items, quests, music tracks, leveled lists, weathers, magical effects, etc. are all represented in plugin files as records.  When multiple mods modify the same records, only the last loaded mod's changes get used by the game (with some exceptions).  This is known as the rule of one.  Many plugin patches combine the changes of multiple mods to resolve conflicts, but there is no way to create and distribute patches for every possible combination of conflicting mods.  This is where tools like Mator Smash come in.  Mator Smash allows for conflict resolution patches to be generated following rules, known as \"Smash Settings\".  This allows users to quickly and efficiently combine the edits of multiple mods.\n\n## intended usage\nUse Mator Smash to generate a patch, then verify the changes in the patch in xEdit.  Fix any conflicts that were not resolved correctly.  Smashed patches should be usable without a manual verification step, but can in certain rare cases lead to crashes/unintended behavior in game.  If you run into issues please report them [here](https://github.com/matortheeternal/smash/issues).  You can safely disable or delete your smashed patch at any time.\n\n# resources\nIf you're looking for support or want to contribute, join the [Modding Tools discord server](https://discord.gg/GUfRdpT).\n\nYou can find additional information and discussion on the [Nexus Mods](https://www.nexusmods.com/skyrim/mods/90987) mod page, in the [STEP forum topic](http://forum.step-project.com/topic/6936-wip-mator-smash/), and in the [Nexus Mods forum topic](https://forums.nexusmods.com/index.php?/topic/3707015-wip-mator-smash-the-conflict-resolution-revolution/)."
  },
  {
    "path": "design/code snippets/GetMasterElement.pas",
    "content": "{for j := 0 to ElementCount(ae) - 1 do begin\n  ne := ebi(ae, j);\n  if (SortKey(ne, false) = sk) then begin\n    Result := ne;\n    break;\n  end;\nend;}\n\n{for j := 0 to ElementCount(ae) - 1 do begin\n  ne := ebi(ae, j);\n  if (gav(ne) = sk) then begin\n    Result := ne;\n    break;\n  end;\nend;}\n\nfunction ElementByKey(e: IwbElement; key: string; bUseSortKey: boolean): IwbElement;\nvar\n  i: Integer;\n  c: IwbContainerElementRef;\nbegin\n  if not Supports(e, IwbContainerElementRef, c) then \n    exit;\n  \n  // loop through children elements\n  for i := 0 to Pred(c.ElementCount) do begin\n    element := c.Elements[i];\n    // get sort key if bUseSortKey, else get values key\n    if bUseSortKey then\n      eKey := element.SortKey[false]\n    else\n      eKey := GetAllValues(element);\n    // if keys match result is current element\n    if eKey = key then begin\n      Result := element;\n      break;\n    end;\n  end;\nend;\n\nfunction GetMasterElement(src, se: IwbElement; dstRec: IwbMainRecord): IwbElement;\nvar\n  i: integer;\n  path, key: string;\n  mstRec, ovr: IwbMainRecord;\n  mst: IwbElement;\n  sorted: boolean;\nbegin\n  Result := nil;\n  mstRec := MasterOrSelf(dstRec);\n  path := IndexedPath(src);\n  bSorted := IsSorted(src);\n  \n  // if sorted, use SortKey, else use GetAllValues\n  if bSorted then \n    key := se.SortKey[false]\n  else\n    key := GetAllValues(se);\n    \n  // debug message\n  if debugGetMaster then \n    Tracker.Write('  Called GetMasterElement at path '+p+' looking for Key '+key);\n    \n  // loop from override 0 to the second to last override\n  // last override is in our patch, we don't want to process that one\n  for i := 0 to mstRec.OverrideCount - 2 do begin\n    ovr := mst.Overrides[i];\n    mst := ElementByIndexedPath[(mstRec, p);\n    Result := ElementByKey(mst, key, bSorted);\n    \n    // break if we found a subrecord matching the sortkey\n    if Result <> nil then\n      break;\n  end;\nend;\n"
  },
  {
    "path": "design/code snippets/Mator Smash v0.9.pas",
    "content": "{\n  Mator Smash v0.9.6\n  created by matortheeternal\n  \n  * DESCRIPTION *\n  This script will make a patch similar to a bashed patch.\n}\n\nunit smash;\n\nuses mteFunctions;\n\nconst\n  vs = 'v0.9.6';\n  settingsPath = scriptsPath + 'smash\\settings\\';\n  dashes = '-----------------------------------------------------------';\n  // these booleans control logging\n  debugGetMaster = false;\n  debugArrays = false;\n  listOverrides = false;\n  showChanges = false;\n  showTraversal = false;\n  showSkips = false;\n  showTypeStrings = false;\n  showRecTimes = false;\n  verbose = false;\n  disableStyles = false;\n  // maximum records to be smashed\n  maxRecords = 100000;\n  splitChar = '#13';\n \nvar\n  slRecords, slSettings, slOptions, slFiles, slSubrecords, \n  slGlobalSubrecords, recordTree, subrecordTree, include: TStringList;\n  lstSettings: TList;\n  userFile: IInterface;\n  global_records, global_subrecords, global_recordMode, \n  global_subrecordMode, global_setting: string;\n  makeNewLine: boolean;\n  AssetPath: string;\n  checkboxImages: TCustomImageList;\n  \n\n\n{===========================================================}\n{ SETTING FORM }\n\nconst\n  cChecked = 1;\n  cUnChecked = 2;\n  cPartiallyChecked = 3;\n\nvar\n  sfrm: TForm;\n  meInclude, meSubrecords: TMemo;\n  tv: TTreeView;\n  btnOk, btnCancel: TButton;\n  \n\n{\n  SetChildren\n  Sets the StateIndex attribute of all the children of @node \n  to @state.  Uses recursion.\n}\nprocedure SetChildren(node: TTreeNode; state: Integer);\nvar\n  tmp: TTreeNode;\nbegin\n  // exit if we don't have a node to work with\n  if not Assigned(node) then exit;\n\n  // loop through children setting StateIndex to state\n  // if child has children, recurse into that child\n  tmp := node.getFirstChild;\n  while Assigned(tmp) do begin\n    tmp.StateIndex := state;\n    if tmp.HasChildren then\n      SetChildren(tmp, state);\n    tmp := tmp.getNextSibling;\n  end;\nend;\n\n{\n  UpdateParent\n  Calculates and sets the StateIndex attribute for @node based\n  on the StateIndex values of its children.  Uses recursion to \n  update parents of the parent that was updated.\n}\nprocedure UpdateParent(node: TTreeNode);\nvar\n  tmp: TTreeNode;\n  state: Integer;\nbegin\n  // exit if we don't have a node to work with\n  if not Assigned(node) then exit;\n\n  // parent state is checked if all siblings are checked\n  state := cChecked;\n  tmp := node.getFirstChild;\n  while Assigned(tmp) do begin\n    if tmp.StateIndex <> cChecked then begin\n      state := cPartiallyChecked;\n      break;\n    end;\n    tmp := tmp.getNextSibling;\n  end;\n\n  // parent state is unchecked if all siblings are unchecked\n  if state = cPartiallyChecked then begin\n    state := cUnChecked;\n    tmp := node.getFirstChild;\n    while Assigned(tmp) do begin\n      if tmp.StateIndex <> cUnChecked then begin\n        state := cPartiallyChecked;\n        break;\n      end;\n      tmp := tmp.getNextSibling;\n    end;\n  end;\n\n  // set state, recurse to next parent\n  node.StateIndex := state;\n  tmp := node.Parent;\n  UpdateParent(tmp);\nend;\n\n{\n  CheckBoxManager\n  Manages checkboxes in the TTreeView.  Changes the StateIndex \n  of the checkbox associated with @node.  Uses SetChildren and\n  UpdateParent.  Called by tvClick and tvKeyDown.\n}\nprocedure CheckBoxManager(node: TTreeNode);\nbegin\n  // exit if we don't have a node to work with\n  if not Assigned(node) then exit;\n  \n  // if unchecked or partially checked, set to checked and\n  // set all children to checked, update parents\n  if (node.StateIndex = cUnChecked)\n  or (node.StateIndex = cPartiallyChecked) then begin\n    node.StateIndex := cChecked;\n    UpdateParent(node.Parent);\n    SetChildren(node, cChecked);\n  end\n  // if checked, set to unchecked and set all children to\n  // unchecked, update parents\n  else if node.StateIndex = cChecked then begin\n    node.StateIndex := cUnChecked;\n    UpdateParent(node.Parent);\n    SetChildren(node, cUnChecked);\n  end;\nend;\n\n{\n  tvClick\n  Event handler for when the user clicks anywhere in the \n  TreeView.  If the user clicks on a checkbox it calls \n  CheckBoxManager to toggle the state of the selected\n  checkbox.\n}\nprocedure tvClick(Sender: TObject; Button: TMouseButton;\n  Shift: TShiftState; X, Y: Integer);\nvar\n  HT: THitTests;\nbegin\n  HT := tv.GetHitTestInfoAt(X, Y);\n  if (HT - [htOnStateIcon] <> HT) then\n    CheckBoxManager(tv.Selected);\nend;\n\n{\n  tvKeyDown\n  Event handler for when the user presses a key while the \n  TreeView is focused.  If the user presses space we call \n  CheckBoxManager to toggle the state of the selected \n  checkbox.\n}\nprocedure tvKeyDown(Sender: TObject; var Key: Word;\n  Shift: TShiftState);\nbegin\n  if (Key = VK_SPACE) and Assigned(tv.Selected) then\n    CheckBoxManager(tv.Selected);\nend;\n\n{\n  tvExpanding\n  Event handler for when the user expands a node in the\n  TreeView.  If we haven't loaded the subrecords for the\n  record represented by @node, we call LoadNodes.\n}\nprocedure tvExpanding(Sender: TObject; node: TTreeNode; \n  var AllowExpansion: Boolean);\nvar\n  i: integer;\nbegin\n  if not Assigned(node.getFirstChild) then exit;\n  \n  // if we haven't loaded subrecord data yet, attempt to\n  // load it from the subrecord stringlist\n  if node.getFirstChild.Text = 'Elements' then begin\n    // find record signature in subrecords stringlist\n    // exit if not found\n    i := subrecordTree.IndexOf(node.Text);\n    if i = -1 then exit;\n    \n    // load nodes from the subrecords stringlist\n    // starting at the first subrecord\n    LoadNodes(subrecordTree, tv, node, i + 1, 2);\n    \n    // delete 'Elements' placeholder node\n    node.getFirstChild.Delete;\n  end;\nend;\n\n{\n  LeadingSpaces\n  Calculates the number of leading spaces in a PChar string\n  and returns it as an integer.\n}\nfunction LeadingSpaces(var s: PChar): integer;\nvar\n  i: integer;\nbegin\n  Result := 0;\n  i := 1;\n  while (true) do begin\n    if s[i] = ' ' then \n      Inc(Result)\n    else\n      exit;\n    Inc(i);\n  end;\nend;\n\n{\n  LoadNodes\n  Loads nodes from @sl into @tv as children of @node.  Starts\n  at index @i in the stringlist and adds children which have\n  leading spaces matching @cws.  If there are more leading \n  spaces than @cws, we use recursion to add the list item as\n  a child of the current list item @curNode.  If there are\n  fewer leading spaces than @cws we exit.\n}\nprocedure LoadNodes(var sl: TStringList; tv: TTreeView; node: TTreeNode; \n  var i: integer; cws: integer);\nvar\n  lws: integer;\n  p: PChar;\n  curNode: TTreeNode;\nbegin\n  curNode := node;\n  while (true) do begin\n    // exit if we reached the end of the stringlist\n    if i > sl.Count - 1 then exit; \n    p := sl[i];\n    lws := LeadingSpaces(p);\n    \n    // if lws matches cws, add as child of current node\n    // (we're on the right level)\n    if lws = cws then begin\n      curNode := tv.Items.AddChild(node, Trim(sl[i]));\n      curNode.StateIndex := node.StateIndex;\n    end \n    // if leading spaces of the current item exceeds cws,\n    // recurse to add as child of the last added node\n    // (we need to go down a level)\n    else if lws > cws then begin\n      LoadNodes(sl, tv, curNode, i, lws);\n      continue;\n    end\n    // if cws exceeds lws, exit\n    // (we need to go up a level)\n    else\n      exit;\n    \n    // go to next item in list\n    Inc(i);\n  end;\nend;\n\n{\n  FindNode\n  Finds a node matching @s as a child of @node.\n}\nfunction FindNode(node: TTreeNode; const s: string): TTreeNode;\nvar\n  tmp: TTreeNode;\nbegin\n  Result := nil;\n  tmp := node.getFirstChild;\n  while (Assigned(tmp)) do begin\n    if (tmp.Text = s) then begin\n      Result := tmp;\n      exit;\n    end;\n    tmp := tmp.getNextSibling;\n  end;\nend;\n\n{\n  DisableNodes\n  Disables nodes from @sl in @tv found as children of @node.  \n  Starts at index @i in the stringlist and locates children \n  which have leading spaces matching @cws.  If there are more \n  leading spaces than @cws, we use recursion to find the list\n  item in the current item @curNode.  If there are fewer leading \n  spaces than @cws we exit.\n}\nprocedure DisableNodes(var sl: TStringList; tv: TTreeView; node: TTreeNode; \n  var i: integer; cws: integer);\nvar\n  lws: integer;\n  p: PChar;\n  curNode: TTreeNode;\nbegin\n  curNode := node;\n  while (true) do begin\n    // exit if we reached the end of the stringlist\n    if i > sl.Count - 1 then exit; \n    p := sl[i];\n    lws := LeadingSpaces(p);\n    \n    // if lws matches cws, find and disable\n    if lws = cws then begin\n      curNode := FindNode(node, Trim(sl[i]));\n      if not Assigned(curNode) then begin\n        Inc(i);\n        continue;\n      end;\n      if i + 1 = sl.Count then begin\n        curNode.StateIndex := cUnChecked;\n      end\n      else begin\n        p := sl[i+1];\n        lws := LeadingSpaces(p);\n        if lws > cws then begin\n          tvExpanding(nil, curNode, true);\n          curNode.StateIndex := cPartiallyChecked;\n        end\n        else begin\n          curNode.StateIndex := cUnChecked;\n        end;\n      end;\n    end \n    // if leading spaces of the current item exceeds cws,\n    // recurse to find in the last added node\n    // (we need to go down a level)\n    else if lws > cws then begin\n      DisableNodes(sl, tv, curNode, i, lws);\n      continue;\n    end\n    // if cws exceeds lws, exit\n    // (we need to go up a level)\n    else\n      exit;\n    \n    // go to next item in list\n    Inc(i);\n  end;\nend;\n\n{\n  MakeBold\n  Changes the style of @lbl to bold.\n}\nprocedure MakeBold(lbl: TLabel);\nbegin\n  if not disableStyles then begin\n    lbl.WordWrap := false;\n    lbl.Font.Style := lbl.Font.Style + [fsBold];\n  end;\nend;\n\n{\n  SettingFormResize\n  Event to fire when the setting form is resized\n}\nprocedure SettingFormResize(Sender: TObject);\nbegin\n  tv.Width := sfrm.Width - 48;\n  tv.Height := sfrm.Height - 155;\n  btnOk.Top := sfrm.Height - 86;\n  btnOk.Left := sfrm.Width div 2 - btnOk.Width - 8;\n  btnCancel.Top := btnOk.Top;\n  btnCancel.Left := btnOk.Left + btnOk.Width + 16;\nend;\n\n{\n  CreateIncludeList\n  Recursively traverses a TreeView starting at @node adding node \n  text properties to @sl, with @depth concatenated before each text \n  item.\n}\nprocedure CreateIncludeList(var sl: TStringList; node: TTreeNode; depth: string);\nvar\n  tmp: TTreeNode;\nbegin\n  if (not node.HasChildren) then exit;\n  \n  tmp := node.getFirstChild;\n  while (Assigned(tmp)) do begin\n    if (tmp.StateIndex = cUnChecked) then\n      sl.Add(depth + tmp.Text)\n    else if (tmp.HasChildren) and (tmp.StateIndex = cPartiallyChecked) then begin\n      sl.Add(depth + tmp.Text);\n      CreateIncludeList(sl, tmp, depth + '  ');\n    end;\n    tmp := tmp.getNextSibling;\n  end;\nend;\n\n{\n  SettingForm\n  Used to create or edit setting presets.\n}\nprocedure SettingForm(Sender: TObject);\nvar\n  lblName, lblRecords, lblSubrecords: TLabel;\n  edName: TEdit;\n  ini, template: TMemIni;\n  usingTemplate: boolean;\n  caption: string;\n  node: TTreeNode;\n  ndx: integer;\nbegin\n  // assign template\n  include := TStringList.Create;\n  caption := TButton(Sender).Caption;\n  usingTemplate := caption <> 'New setting';\n  if lst.ItemIndex > -1 then\n    template := TMemIniFile(lstSettings[slSettings.IndexOf(lst.Items[lst.ItemIndex])])\n  else\n    usingTemplate := false;\n  \n  sfrm := TForm.Create(nil);\n  try\n    // set up form\n    sfrm.Width := 400;\n    sfrm.Height := 600;\n    sfrm.Position := poScreenCenter;\n    sfrm.Caption := 'Create new Smash Setting';\n    sfrm.Constraints.MinHeight := 400;\n    sfrm.Constraints.MinWidth := 286;\n    \n    // make label and edit for name\n    lblName := cLabel(sfrm, sfrm, 16, 16, 0, 0, 'Name: ', '');\n    edName := cEdit(sfrm, sfrm, lblName.Top, lblName.Left + lblName.Width + 8, 0, 200, '', '');\n    \n    // make tree view\n    tv := TTreeView.Create(sfrm);\n    tv.Parent := sfrm;\n    tv.Left := lblName.Left;\n    tv.Top := lblName.Top + lblName.Height + 20;\n    tv.Width := sfrm.Width - 48;\n    tv.Height := sfrm.Height - 155;\n    tv.Indent := 19;\n    tv.ReadOnly := true;\n    tv.StateImages := checkboxImages;\n    tv.OnMouseDown := tvClick;\n    tv.OnKeyDown := tvKeyDown;\n    tv.OnExpanding := tvExpanding;\n    \n    // construct ok and cancel buttons\n    btnOk := TButton.Create(sfrm);\n    btnOk.Parent := sfrm;\n    btnOk.Left := sfrm.Width div 2 - btnOk.Width - 8;\n    btnOk.Top := sfrm.Height - 86;\n    btnOk.Caption := 'OK';\n    btnOk.ModalResult := mrOK;\n    \n    btnCancel := TButton.Create(sfrm);\n    btnCancel.Parent := sfrm;\n    btnCancel.Left := btnOk.Left + btnOk.Width + 16;\n    btnCancel.Top := btnOk.Top;\n    btnCancel.Caption := 'Cancel';\n    btnCancel.ModalResult := mrCancel;\n    \n    // load record nodes\n    node := tv.Items.Add(nil, 'Records');\n    if usingTemplate then\n      node.StateIndex := cChecked\n    else \n      node.StateIndex := cUnChecked;\n    LoadNodes(recordTree, tv, node, 0, 0);\n    \n    // if using template, load values from it for form\n    if usingTemplate then begin\n      edName.Caption := template.ReadString('Setting', 'Name', '');\n      if caption = 'Copy setting' then begin\n        sfrm.Caption := 'Copy Smash Setting';\n        edName.Caption := 'Copy of '+edName.Caption;\n      end\n      else if caption = 'Edit setting' then begin\n        sfrm.Caption := 'Edit Smash Setting';\n        edName.Enabled := false;\n      end;\n      \n      include.LoadFromFile(settingsPath + edName.Caption + '.ini');\n      ndx := include.IndexOf('[Tree]') + 1;\n      if (ndx < include.Count) then begin\n        if (include[ndx] <> '') then begin\n          DisableNodes(include, tv, node, ndx, 0);\n          node.StateIndex := cPartiallyChecked;\n        end;\n      end;\n    end;\n    \n    // set onresize event\n    sfrm.OnResize := SettingFormResize;\n    \n    // if user clicks ok, save to ini and update lists\n    if sfrm.ShowModal = mrOk then begin\n      ini := TMemIniFile.Create(settingsPath + edName.Caption + '.ini');\n      ini.WriteString('Setting', 'Name', edName.Caption);\n      ini.UpdateFile;\n      \n      include.LoadFromFile(settingsPath + edName.Caption + '.ini');\n      ndx := include.IndexOf('[Tree]');\n      if (ndx = -1) then\n        include.Add('[Tree]')\n      else begin\n        Inc(ndx);\n        while (include.Count > ndx) do\n          include.Delete(ndx);\n      end;\n      CreateIncludeList(include, node, '');\n      include.SaveToFile(settingsPath + edName.Caption + '.ini');\n      \n      if (slSettings.IndexOf(edName.Caption) = -1) then begin\n        lstSettings.Add(ini);\n        slSettings.Add(edName.Caption);\n        lst.Items.Add(edName.Caption);\n      end\n      else\n        lstSettings[slSettings.IndexOf(edName.Caption)] := ini;\n    end;\n  finally\n    sfrm.Free;\n  end;\nend;\n\n\n{===========================================================}\n{ SETTING MANAGER FORM }\n\nvar\n  btnDetails, btnEdit, btnCopy, btnDel: TButton;\n  gear: TPicture;\n  lst: TListBox;\n\n  \n{\n  ToggleButtons\n  Toggles btnEdit, btnCopy, btnDelete.\n}\nprocedure ToggleButtons(Sender: TObject);\nvar\n  b: boolean;\nbegin\n  b := (TListBox(Sender).ItemIndex > -1);\n  btnEdit.Enabled := b; btnCopy.Enabled := b; btnDel.Enabled := b;\nend;\n\n{\n  DeleteSetting\n  Deletes the currently selected setting.\n}\nprocedure DeleteSetting(Sender: TObject);\nvar\n  s: string;\nbegin\n  if lst.ItemIndex > -1 then begin\n    s := lst.Items[lst.ItemIndex];\n    lstSettings.Delete(slSettings.IndexOf(s));\n    slSettings.Delete(slSettings.IndexOf(s));\n    lst.Items.Delete(lst.ItemIndex);\n    lst.ItemIndex := -1;\n    DeleteFile(settingsPath + s + '.ini');\n  end;\nend;\n\n{\n  UpdateSettings\n  Updates the setting comboboxes for OptionsForm\n}\nprocedure UpdateSettings;\nvar\n  i, ndx: integer;\n  cb: TComboBox;\n  s: string;\nbegin\n  for i := 0 to pnlCount - 1 do begin\n    cb := TComboBox(pnlArray[i].Components[1]);\n    s := cb.Items[cb.ItemIndex];\n    cb.Items.Text := slSettings.Text;\n    if cb.Items.IndexOf(s) > -1 then\n      cb.ItemIndex := cb.Items.IndexOf(s)\n    else\n      cb.ItemIndex := 0;\n  end;\n  \n  // update global setting combobox\n  s := gscb.Items[gscb.ItemIndex];\n  gscb.Items.Text := slSettings.Text;\n  if gscb.Items.IndexOf(s) > -1 then\n    gscb.ItemIndex := gscb.Items.IndexOf(s)\n  else\n    gscb.ItemIndex := 0;\nend;\n\n{\n  SettingManager\n  Used by the user to view, edit, and create settings.\n}\nprocedure SettingManager;\nvar\n  ofrm: TForm;\n  i, h: integer;\n  btnNew, btnOk : TButton;\nbegin\n  ofrm := TForm.Create(nil);\n  try\n    ofrm.Caption := 'Advanced Options';\n    ofrm.Width := 400;\n    ofrm.Position := poScreenCenter;\n    ofrm.Height := 300;\n    \n    h := slSettings.Count * 15 + 85;\n    if h > 500 then\n      h := 500;\n    if h > ofrm.Height then\n      ofrm.Height := h;\n    \n    // list box of settings\n    lst := TListBox.Create(ofrm);\n    lst.Parent := ofrm;\n    lst.Top := 8;\n    lst.Left := 8;\n    lst.Height := ofrm.Height - 105;\n    lst.Width := ofrm.Width - 145;\n    for i := 0 to slSettings.Count - 1 do\n      lst.Items.Add(slSettings[i]);\n    lst.OnClick := ToggleButtons;\n    \n    // new setting button\n    btnNew := cButton(ofrm, ofrm, 8, lst.Left + lst.Width + 8, 0, 100, 'New setting');\n    btnNew.OnClick := SettingForm;\n    // edit setting button\n    btnEdit := cButton(ofrm, ofrm, btnNew.Top + btnNew.Height + 8, btnNew.Left, 0, 100, 'Edit setting');\n    btnEdit.OnClick := SettingForm;\n    btnEdit.Enabled := false;\n    // copy setting button\n    btnCopy := cButton(ofrm, ofrm, btnEdit.Top + btnEdit.Height + 8, btnNew.Left, 0, 100, 'Copy Setting');\n    btnCopy.OnClick := SettingForm;\n    btnCopy.Enabled := false;\n    // delete setting button\n    btnDel := cButton(ofrm, ofrm, btnCopy.Top + btnCopy.Height + 8, btnNew.Left, 0, 100, 'Delete setting');\n    btnDel.OnClick := DeleteSetting;\n    btnDel.Enabled := false;\n    // OK button\n    btnOk := cButton(ofrm, ofrm, ofrm.Height - 80, ofrm.Width div 2 - 40, 0, 0, 'OK');\n    btnOk.ModalResult := mrOk;\n    \n    ofrm.ShowModal;\n  finally\n    ofrm.free;\n  end;\n  UpdateSettings;\nend;\n\n\n{===========================================================}\n{ PLUGIN DETAILS FORM }\n\n\n{\n  GetGroupOverrides\n}\nfunction GetGroupOverrides(f: IInterface): string;\nvar\n  i: integer;\n  e: IInterface;\nbegin\n  for i := 0 to ElementCount(f) - 1 do begin\n    e := ebi(f, i);\n    if Signature(e) = 'TES4' then continue;\n    Result := Result + GroupSignature(e) + ': '+IntToStr(OverrideRecordCount(e))+' overrides'#13#10;\n  end;\nend;\n\n{\n  PluginDetails\n  Form which shows advanced details on a plugin\n}\nprocedure PluginDetails(Sender: TObject);\nvar\n  f, e: IInterface;\n  i: integer;\n  fn, author, records, overrides, desc, masters, groups: string;\n  pfrm: TForm;\n  lbl: TLabel;\n  sb: TScrollBox;\n  memo: TMemo;\nbegin\n  // find file\n  fn := TLabel(Sender).Caption;\n  fn := Copy(fn, Pos(']', fn) + 2, Length(fn));\n  f := FileByName(fn);\n  \n  // get data\n  author := geev(ebi(f, 0), 'CNAM');\n  records := IntToStr(RecordCount(f));\n  overrides := IntToStr(OverrideRecordCount(f));\n  desc := geev(ebi(f, 0), 'SNAM');\n  e := ebn(ebi(f, 0), 'Master Files');\n  for i := 0 to ElementCount(e) - 1 do\n    masters := masters + geev(ebi(e, i), 'MAST') + #13#10;\n  groups := GetGroupOverrides(f);\n    \n  // display form\n  pfrm := TForm.Create(nil);\n  try\n    pfrm.Caption := fn;\n    pfrm.Width := 400;\n    pfrm.Height := 600;\n    pfrm.Position := poScreenCenter;\n    \n    lbl := cLabel(pfrm, pfrm, 8, 8, 0, 150, 'Filename:', '');\n    MakeBold(lbl);\n    lbl := cLabel(pfrm, pfrm, lbl.Top, 160, 0, 200, fn, '');\n    lbl := cLabel(pfrm, pfrm, lbl.Top + 22, 8, 0, 150, 'Author:', '');\n    MakeBold(lbl);\n    lbl := cLabel(pfrm, pfrm, lbl.Top, 160, 0, 200, author, '');\n    lbl := cLabel(pfrm, pfrm, lbl.Top + 22, 8, 0, 150, 'Number of records:', '');\n    MakeBold(lbl);\n    lbl := cLabel(pfrm, pfrm, lbl.Top, 160, 0, 200, records, '');\n    lbl := cLabel(pfrm, pfrm, lbl.Top + 22, 8, 0, 150, 'Number of overrides:', '');\n    MakeBold(lbl);\n    lbl := cLabel(pfrm, pfrm, lbl.Top, 160, 0, 200, overrides, '');\n    lbl := cLabel(pfrm, pfrm, lbl.Top + 22, 8, 0, 150, 'Description:', '');\n    MakeBold(lbl);\n    memo := cMemo(pfrm, pfrm, lbl.Top + 22, 16, 100, 348, true, true, ssVertical, desc);\n    lbl := cLabel(pfrm, pfrm, memo.Top + memo.Height + 16, 8, 0, 150, 'Masters:', '');\n    MakeBold(lbl);\n    memo := cMemo(pfrm, pfrm, lbl.Top + 22, 16, 100, 348, true, true, ssVertical, masters);\n    lbl := cLabel(pfrm, pfrm, memo.Top + memo.Height + 16, 8, 0, 150, 'Record groups:', '');\n    MakeBold(lbl);\n    memo := cMemo(pfrm, pfrm, lbl.Top + 22, 16, 150, 348, true, true, ssVertical, groups);\n    \n    pfrm.ShowModal;\n  finally\n    pfrm.Free;\n  end;\nend;\n\n\n{===========================================================}\n{ OPTIONS FORM }\n\nvar\n  frm: TForm;\n  gscb: TComboBox;\n  pnlArray: Array[0..255] of TPanel;\n  pnlCount: integer;\n\n  \n{\n  OptionsForm\n  Form from which the user can access the setting manager,\n  plugin details, and set the settings to be used when smashing\n  the loaded plugins.\n}\nfunction OptionsForm: boolean;\nvar\n  i, height, m: integer;\n  btnSmash, btnCancel: TButton;\n  optionslbl, fnlbl, gslbl: TLabel;\n  cb: TComboBox;\n  f: IInterface;\n  fn, author, s: string;\n  imgOptions: TImage;\n  pnl: TPanel;\n  holder: TObject;\n  sb: TScrollBar;\nbegin\n  Result := false;\n  frm := TForm.Create(nil);\n  try\n    frm.Caption := 'Mator Smash Options';\n    frm.Width := 550;\n    frm.Position := poScreenCenter;\n    frm.Height := 400;\n    for i := 0 to FileCount - 1 do begin\n      f := FileByIndex(i);\n      fn := GetFileName(f);\n      author := geev(ebi(f, 0), 'CNAM');\n      if (Pos(fn, bethesdaFiles) > 0) or (Pos('Mator Smash', author) > 0) then Continue;\n      Inc(m);\n    end;\n    height := m*40 + 170;\n    if height > (Screen.Height - 100) then begin\n      frm.Height := Screen.Height - 100;\n      sb := TScrollBox.Create(frm);\n      sb.Parent := frm;\n      sb.Height := Screen.Height - 210;\n      sb.Width := frm.Width - 20;\n      sb.Align := alTop;\n      holder := sb;\n    end\n    else begin\n      frm.Height := height;\n      holder := frm;\n    end;\n    \n    optionslbl := cLabel(frm, holder, 8, 8, 0, 450, \n      'Set the options you want to use for smashing the following plugins:', '');\n    \n    pnlCount := 0;\n    for i := 0 to FileCount - 1 do begin\n      f := FileByIndex(i);\n      fn := GetFileName(f);\n      author := geev(ebi(f, 0), 'CNAM');\n      if Pos(fn, bethesdaFiles) > 0 then\n        continue;\n      if Pos('Mator Smash', author) > 0 then\n        continue;\n      \n      pnlArray[pnlCount] := TPanel.Create(frm);\n      pnlArray[pnlCount].Parent := holder;\n      pnlArray[pnlCount].Left := 0;\n      pnlArray[pnlCount].Top := 30 + pnlCount*40;\n      pnlArray[pnlCount].Width := holder.Width - 25;\n      pnlArray[pnlCount].BevelOuter := bvNone;\n      pnlArray[pnlCount].BevelInner := bvNone; // or bvLowered\n      pnlArray[pnlCount].BorderStyle := bsNone; // or bsSingle\n      \n      fnlbl := cLabel(pnlArray[pnlCount], pnlArray[pnlCount], 14, 24, 0, 0, '['+IntToHex(i - 1, 2)+'] '+fn, '');\n      fnlbl.OnClick := PluginDetails;\n      MakeBold(fnlbl);\n      \n      cb := TComboBox.Create(pnlArray[pnlCount]);\n      cb.Parent := pnlArray[pnlCount];\n      cb.Style := csDropDownList;\n      cb.Items := slSettings;\n      cb.ItemIndex := 0;\n      if slSettings.IndexOf('default') > -1 then\n        cb.ItemIndex := slSettings.IndexOf('default');\n      cb.Top := 12;\n      cb.Width := 150;\n      cb.Left := holder.Width - cb.Width - 40;\n      \n      slFiles.Add(fn);\n      Inc(pnlCount);\n    end;\n    \n    // create global setting controls\n    gslbl := cLabel(frm, holder, pnlArray[pnlCount - 1].Top + pnlArray[pnlCount - 1].Height + 16,\n      optionslbl.Left, 0, 70, 'Global setting: ', '');\n    gscb := TComboBox.Create(frm);\n    gscb.Parent := holder;\n    gscb.Top := gslbl.Top;\n    gscb.Left := gslbl.Left + gslbl.Width + 16;\n    gscb.Width := 150;\n    gscb.Style := csDropDownList;\n    gscb.Items := slSettings;\n    gscb.ItemIndex := 0;\n    if slSettings.IndexOf('default') > -1 then\n      gscb.ItemIndex := slSettings.IndexOf('default');\n    \n    pnl := TPanel.Create(frm);\n    pnl.Parent := frm;\n    pnl.BevelOuter := bvNone;\n    pnl.Align := alBottom;\n    pnl.Height := 50;\n    \n    imgOptions := cImage(pnl, pnl, pnl.Height - 40, frm.Width - 50, 24, 24, gear, 'Advanced Options');\n    imgOptions.OnClick := SettingManager;\n    \n    // create ok/cancel buttons\n    btnSmash := cButton(frm, pnl, pnl.Height - 40, frm.Width div 2 - 88, 0, 0, 'Smash!');\n    btnSmash.ModalResult := mrOk;\n    btnCancel := cButton(frm, pnl, btnSmash.Top, btnSmash.Left + btnSmash.Width + 16, 0, 0, 'Cancel');\n    btnCancel.ModalResult := mrCancel;\n    \n    if frm.ShowModal = mrOk then begin\n      for i := 0 to pnlCount - 1 do begin\n        s := TComboBox(pnlArray[i].Components[1]).Text;\n        slOptions.Add(s);\n      end;\n      global_setting := gscb.Text;\n      Result := true;\n    end;\n  finally\n    frm.Free;\n  end;\nend;\n\n\n{===========================================================}\n{ SMASHING METHODS }\n\nvar\n  pb: TProgressBar;\n  memo: TMemo;\n  lbl: TLabel;\n\n\n{\n  LogMessage\n  Adds @msg to the log stringlist\n}\nprocedure LogMessage(msg: string);\nbegin\n  memo.Lines.add(msg);\n  Application.processmessages;\nend;\n\n{\n  GetMasterElement\n  Gets the first instance of an element (the master)\n}\nfunction GetMasterElement(src, se, dstrec: IInterface): IInterface;\nvar\n  i, j, ndx: integer;\n  p, sk: string;\n  ovr, ae, ne, mst: IInterface;\n  sorted: boolean;\nbegin\n  Result := nil;\n  mst := MasterOrSelf(dstrec);\n  p := IndexedPath(src);\n  sk := SortKey(se, false);\n  sorted := not (sk = '');\n  // if sorted, look for an element matching sort key\n  if sorted then begin\n    if debugGetMaster then LogMessage('  Called GetMasterElement at path '+p+' looking for SortKey '+SortKey(se, false));\n    // loop from override 0 to the second to last override\n    for i := 0 to OverrideCount(mst) - 2 do begin\n      ovr := OverrideByIndex(mst, i);\n      ae := ebp(mst, p);\n      for j := 0 to ElementCount(ae) - 1 do begin\n        ne := ebi(ae, j);\n        if (SortKey(ne, false) = sk) then begin\n          Result := ne;\n          break;\n        end;\n      end;\n      // break if we found a subrecord matching the sortkey\n      if Result <> nil then\n        break;\n    end;\n  end \n  // if unsorted, look for the element using gav\n  else begin\n    sk := gav(se);\n    if debugGetMaster then LogMessage('  Called GetMasterElement at path '+p+' looking for '+sk);\n    ae := ebp(mst, p);\n    for i := 0 to OverrideCount(mst) - 1 do begin\n      ovr := OverrideByIndex(mst, i);\n      ae := ebp(ovr, p);\n      for j := 0 to ElementCount(ae) - 1 do begin\n        ne := ebi(ae, j);\n        if (gav(ne) = sk) then begin\n          Result := ne;\n          break;\n        end;\n      end;\n    end;\n  end;\nend;\n  \n{\n  nbsOverrideCount\n  Non-Bethesda Override Count\n}\nfunction nbsOverrideCount(r: IInterface): integer;\nvar\n  i: integer;\n  fn: string;\nbegin\n  Result := 0;\n  for i := 0 to OverrideCount(r) - 1 do begin\n    fn := GetFileName(GetFile(OverrideByIndex(r, i)));\n    if Pos(fn, bethesdaFiles) = 0 then\n      Result := Result + 1;\n  end;\nend;\n\n{\n  BuildSortKeyList\n  Puts the sort keys of elements in a stringlist\n}\nprocedure BuildSortKeyList(element: IInterface; var sl: TStringList);\nvar\n  i, n: integer;\n  childElement: IInterface;\n  sk, skAdj: string;\nbegin\n  for i := 0 to ElementCount(element) - 1 do begin\n    childElement := ebi(element, i);\n    sk := SortKey(childElement, false);\n    skAdj := sk;\n    n := 0;\n    while sl.IndexOf(skAdj) > -1 do begin\n      Inc(n);\n      skAdj := sk + '-' + IntTostr(n);\n    end;\n    if debugArrays and (n > 0) then LogMessage('    Adjusted SortKey: '+skAdj);\n    sl.Add(skAdj);\n  end;\nend;\n\n{\n  MergeSortedArray\n  Merges sorted array elements\n}\nprocedure MergeSortedArray(mst, src, dst, dstrec: IInterface; depth: string; ini: TMemIniFile);\nvar\n  i, m_ndx, s_ndx, d_ndx, n: integer;\n  me, se, de, ne: IInterface;\n  slMst, slDst, slSrc: TStringList;\n  useValues: boolean;\n  dts, ets, sk: string;\nbegin\n  // Step 1: build lists of elements in each array for easy comparison\n  slMst := TStringList.Create;\n  slSrc := TStringList.Create;\n  slDst := TStringList.Create;\n  slDst.Sorted := true;\n  BuildSortKeyList(mst, slMst);\n  BuildSortKeyList(src, slSrc);\n  BuildSortKeyList(dst, slDst);\n  \n  // Step 2: Remove elements that are in mst and dst, but missing from src\n  for i := 0 to slMst.Count - 1 do begin\n    s_ndx := slSrc.IndexOf(slMst[i]);\n    d_ndx := slDst.IndexOf(slMst[i]);\n    \n    if (s_ndx = -1) and (d_ndx > -1) then begin\n      if debugArrays then LogMessage('      > Removing element '+Path(ebi(dst, d_ndx))+' with key: '+slDst[d_ndx]);\n      RemoveElement(dst, ebi(dst, d_ndx));\n      slDst.Delete(d_ndx);\n    end;\n  end;\n  \n  // Step 3: Copy array elements in src that aren't in mst.\n  for i := 0 to slSrc.Count - 1 do begin\n    d_ndx := slDst.IndexOf(slSrc[i]);\n    m_ndx := slMst.IndexOf(slSrc[i]);\n    \n    se := ebi(src, i);\n    dts := DefTypeString(se);\n    ets := ElementTypeString(se);\n    if (d_ndx = -1) and (m_ndx = -1) then begin\n      if debugArrays then LogMessage('      > Adding element '+IntToStr(i)+' at '+Path(dst)+' with key: '+slSrc[i]);\n      ne := ElementAssign(dst, HighInteger, se, false);\n      if debugArrays then LogMessage('      > '+gav(ne));\n      slDst.Add(slSrc[i]);\n    end\n    // Step 3.5: If array element is in dst and has subelements, traverse it.\n    else if (d_ndx > -1) and ((dts = 'dtStruct') or (ets = 'etSubRecordArray')) then begin\n\t    if showTraversal then LogMessage('      > Traversing element '+Path(se)+' with key: '+slSrc[i]);\n      if showTraversal and debugArrays then LogMessage('      > Source Element: '+gav(se)+\n        #13#10'      > Destination Element: '+gav(ebi(dst, d_ndx)));\n      try\n        rcore(se, GetMasterElement(src, se, dstrec), ebi(dst, d_ndx), dstrec, depth + '    ', ini);\n      except on x : Exception do begin\n          LogMessage('      !! rcore exception: '+x.Message);\n        end;\n      end;\n    end\n    else if (d_ndx > -1) and (ets = 'etSubRecordStruct') then begin\n\t    if showTraversal then LogMessage('      > Traversing element '+Path(se)+' with key: '+slSrc[i]);\n      if showTraversal and debugArrays then LogMessage('      > Source Element: '+gav(se)+\n        #13#10'      > Destination Element: '+gav(ebi(dst, d_ndx)));\n      try\n        rcore(se, GetMasterElement(src, se, dstrec), ebi(dst, d_ndx), dstrec, depth + '    ', ini);\n      except on x : Exception do begin\n          LogMessage('      !! rcore exception: '+x.Message);\n        end;\n      end;\n    end;\n  end;\n  \n  // Step 4: Free lists.\n  slMst.Free;\n  slSrc.Free;\n  slDst.Free;\nend;\n\n{\n  BuildElementList\n  Puts the values of elements in a stringlist\n}\nprocedure BuildElementList(element: IInterface; var sl: TStringList);\nvar\n  i, n: integer;\n  childElement: IInterface;\n  values, valuesAdj: string;\nbegin\n  for i := 0 to ElementCount(element) - 1 do begin\n    childElement := ebi(element, i);\n    values := gav(childElement);\n    valuesAdj := values;\n    n := 0;\n    while (sl.IndexOf(valuesAdj) > -1) do begin\n      Inc(n);\n      valuesAdj := values + IntToStr(n);\n    end;\n    sl.Add(valuesAdj);\n  end;\nend;\n\n{\n  MergeUnsortedArray\n  Merges unsorted array elements\n}\nprocedure MergeUnsortedArray(mst, src, dst, dstrec: IInterface; depth: string; ini: TMemIniFile);\nvar\n  i, m_ndx, s_ndx, d_ndx: integer;\n  me, se, de: IInterface;\n  slMst, slSrc, slDst: TStringList;\n  useValues: boolean;\n  dts, ets: string;\nbegin\n  // Step 1: build lists of elements in each array for easy comparison\n  slMst := TStringList.Create;\n  slSrc := TStringList.Create;\n  slDst := TStringList.Create;\n  BuildElementList(mst, slMst);\n  BuildElementList(src, slSrc);\n  BuildElementList(dst, slDst);\n  \n  // Step 2: Remove elements that are in mst and dst, but missing from src\n  for i := 0 to slMst.Count - 1 do begin\n    s_ndx := slSrc.IndexOf(slMst[i]);\n    d_ndx := slDst.IndexOf(slMst[i]);\n    \n    if (s_ndx = -1) and (d_ndx > -1) then begin\n      if debugArrays then LogMessage('      > Removing element at '+Path(dst)+' with values: '+slMst[i]);\n      RemoveElement(dst, d_ndx);\n      slDst.Delete(d_ndx);\n    end;\n  end;\n  \n  // Step 3: Copy array elements in src that aren't in mst or dst\n  for i := 0 to slSrc.Count - 1 do begin\n    d_ndx := slDst.IndexOf(slSrc[i]);\n    m_ndx := slMst.IndexOf(slSrc[i]);\n    se := ebi(src, i);\n    //if debugArrays then LogMessage('Looking to copy '+slSrc[i]);\n    if (m_ndx = -1) and (d_ndx = -1) then begin\n      if debugArrays then LogMessage('      > Adding element at '+Path(dst)+' with values: '+slSrc[i]);\n      ElementAssign(dst, HighInteger, se, false);\n      slDst.Add(slSrc[i]);\n    end;\n  end;\n  \n  // Step 4: Free lists.\n  slMst.Free;\n  slSrc.Free;\n  slDst.Free;\nend;\n\n{\n  ListHasMatch\n  Check if a list has a matching subrecord\n}\nfunction ListHasMatch(var sl: TStringList; input: string): boolean;\nvar\n  i: integer;\n  ex: string;\nbegin\n  Result := false;\n  for i := 0 to sl.Count - 1 do begin\n    ex := sl[i];\n    if (Pos('*', ex) > 0) then begin\n      SetChar(ex, Pos('*', ex), '');\n      if (Pos(ex, input) > 0) then begin\n        Result := true;\n        exit;\n      end;\n    end\n    else if (ex = input) then begin\n      Result := true;\n      exit;\n    end;\n  end;\nend;\n\n{\n  SkipRecord\n  Returns whether or not a record should be skipped\n}\nfunction SkipRecord(rec: IInterface; records, recordMode: string): boolean;\nvar\n  s: string;\nbegin\n  s := Signature(rec);\n  Result := ((Pos(s, records) > 0) and (recordMode = '0'))\n    or ((Pos(s, records) = 0) and (recordMode = '1'))\n    or ((Pos(s, global_records) > 0) and (global_recordMode = '0')) \n    or ((Pos(s, global_records) = 0) and (global_recordMode = '1'))\nend;\n\n{\n  SkipSubrecord\n  Check if a subrecord should be skipped\n}\nfunction SkipSubrecord(subrecord: IInterface; ini: TMemIniFile): boolean;\nvar\n  subrecords, subrecordMode, subrecordPath: string;\n  match, globalMatch: boolean;\nbegin\n  // load subrecord settings\n  subrecordMode := ini.ReadString('Setting', 'subrecordMode', '0');\n  \n  // path string\n  subrecordPath := Path(subrecord);\n  \n  // result boolean\n  match := ListHasMatch(slSubrecords, subrecordPath);\n  globalMatch := ListHasMatch(slGlobalSubrecords, subrecordPath);\n  Result := ((subrecordMode = '0') and (match))\n    or ((subrecordMode = '1') and not (match))\n    or ((global_subrecordMode = '0') and (globalMatch)) \n    or ((global_subrecordMode = '1') and not (globalMatch));\nend;\n\n{\n  AddElementsToList\n  Adds children elements to a stringlist\n}\nprocedure AddElementsToList(element: IInterface; var sl: TStringList);\nvar\n  i: integer;\n  childElement: IInterface;\nbegin\n  for i := 0 to ElementCount(element) - 1 do begin\n    childElement := ebi(element, i);\n    sl.Add(Name(childElement));\n  end;\nend;\n\n{\n  IsValueElement\n  Checks if an element is a value element\n}\nfunction IsValueElement(elementType: string): boolean;\nbegin\n  Result := (elementType = 'dtInteger') \n    or (elementType = 'dtFloat') \n    or (elementType = 'dtUnion') \n    or (elementType = 'dtByteArray')\n    or (elementType = 'dtString') \n    or (elementType = 'dtLString') \n    or (elementType = 'dtLenString');\nend;\n\n{\n  rcore\n  Recursively Copy Overridden Elements\n}\nprocedure rcore(src, mst, dst, dstrec: IInterface; depth: string; ini: TMemIniFile);\nvar\n  i, j, k, max: integer;\n  se, me, de, sse, mse, kse, kme, kde, xse: IInterface;\n  mv, sv, ets, dts, cts, cas, ctsrc, subrecords, subrecordMode: string;\n  diff: TRecordDiff;\n  slDst, slMst: TStringList;\n  skip: boolean;\nbegin\n  // initialize stringlists\n  slDst := TStringList.Create; // list of destination elements\n  slMst := TStringList.Create; // list of master elements\n  \n  // copy elements from source to destination if missing\n  AddElementsToList(dst, slDst);\n  AddElementsToList(mst, slMst);\n  for i := 0 to ElementCount(src) - 1 do begin\n    se := ebi(src, i);\n    // if the element isn't in the destination record\n    // and wasn't in the master record, copy it to the destination\n    // if it isn't in the destination but is in the master it means\n    // that it was deleted and shouldn't be copied.\n    if (slDst.IndexOf(Name(se)) = -1) \n    and (slMst.IndexOf(Name(se)) = -1) then\n      wbCopyElementToRecord(se, dst, false, true);\n  end;\n  \n  // loop through subelements\n  i := 0;\n  j := 0;\n  while i < ElementCount(src) do begin\n    // assign source, destination, master elements\n    // ensure index out of bounds doesn't occur by not reassigning\n    // past the last element\n    if i < ElementCount(src) then\n      se := ebi(src, i);\n    if j < ElementCount(dst) then\n      de := ebi(dst, j);\n    me := ebn(mst, Name(se));\n    \n    // DefType and ElementType strings\n    ets := ElementTypeString(se);\n    dts := DefTypeString(se);\n    \n    // skip record header, copy record flags\n    if Name(se) = 'Record Header' then begin\n      wbCopyElementToRecord(ebp(se, 'Record Flags'), dst, false, true);\n      Inc(i);\n      Inc(j);\n      continue;\n    end;\n    // skip subrecordsToSkip\n    skip := SkipSubrecord(se, ini);\n    if skip then begin\n      if showSkips then LogMessage('    Skipping '+Path(se));\n      Inc(i);\n      Inc(j);\n      continue;\n    end;\n    \n    // debug messages\n    if showTraversal then LogMessage('    '+Path(se));\n    if showTypeStrings then LogMessage('    ets: '+ets+'  dts: '+dts);\n    \n    // if destination element doesn't match source element\n    if (Name(se) <> Name(de)) then begin\n      // if we're not at the end of the destination elements\n      // proceed to next destination element\n      // else proceed to next source element\n      if (j < ElementCount(dst)) then\n        Inc(j)\n      else\n        Inc(i);\n      continue;\n    end;\n    \n    // deal with subrecord arrays\n    if (ets = 'etSubRecordArray') or (dts = 'dtArray') then begin\n      // if sorted, deal with sorted array\n      if IsSorted(se) then begin\n        if debugArrays then LogMessage('    Sorted array found: '+Path(se));\n        try\n          MergeSortedArray(me, se, de, dstrec, depth, ini);\n        except on x : Exception do\n          LogMessage('      !! MergeSortedArray exception: '+x.Message);\n        end;\n      end\n      // else deal with unsorted etSubRecordArray\n      else if (ets = 'etSubRecordArray') then begin\n        if debugArrays then LogMessage('    Unsorted etSubRecordArray found: '+Path(se));\n        try \n          MergeUnsortedArray(me, se, de, dstrec, depth, ini);\n        except on x : Exception do\n          LogMessage('      !! MergeUnsortedArray exception: '+x.Message);\n        end;\n      end\n      // else deal with unsorted dtArray\n      else begin\n        if debugArrays then LogMessage('    Unsorted dtArray found: '+Path(se));\n        try \n          MergeUnsortedArray(me, se, de, dstrec, depth, ini);\n          //rcore(se, me, de, dstrec, depth + ' ', ini);\n        except on x : Exception do\n          LogMessage('      !! MergeUnsortedArray exception: '+x.Message);\n        end;\n      end;\n    end\n    \n    // else recurse deeper\n    else if (ElementCount(se) > 0) and (dts <> 'dtInteger') then begin\n      try\n        rcore(se, me, de, dstrec, depth + '    ', ini);\n      except on x : Exception do\n        LogMessage('      !! rcore exception in element '+Path(se)+': '+x.Message);\n      end;\n    end\n    \n    // else copy element if value differs from master\n    else if IsValueElement(dts) and (GetEditValue(se) <> GetEditValue(me)) then begin\n      if (Assigned(me)) and showChanges then begin\n        if (not showTraversal) then LogMessage('    '+Path(se));\n        LogMessage('      > Found differing values: '+GetEditValue(se)+' and '+GetEditValue(me));\n      end;\n      // try to copy element value to destination element from source element\n      try \n        SetEditValue(de, GetEditValue(se));\n      except on x : Exception do\n        LogMessage('      !! Copy element value exception: '+x.Message);\n      end;\n    end;\n    \n    // proceed to next subelement\n    Inc(i);\n    Inc(j);\n  end;\n  \n  slDst.Free;\n  slMst.Free;\nend;\n\n{\n  IsSmashedPatch\n  Checks if @f is a smashed patch\n}\nfunction IsSmashedPatch(f: IInterface): boolean;\nvar\n  author: string;\nbegin\n  author := geev(ElementByIndex(f, 0), 'CNAM');\n  Result := (Pos('Mator Smash', author) = 1); \nend;\n\n{\n  SmashRecord\n  Smashes @rec into @smashFile.\n}\nprocedure SmashRecord(rec, smashFile: IInterface);\nvar\n  i: integer;\n  fn, author: string;\n  f, ovr, mr: IInterface;\n  ini: TMemIniFile;\nbegin\n  // loop through record's overrides\n  for i := 0 to OverrideCount(rec) - 1 do begin\n    ovr := OverrideByIndex(rec, i);\n    f := GetFile(ovr);\n    fn := GetFileName(f);\n    \n    // skip overrides in bethesda files\n    if (Pos(fn, bethesdaFiles) > 0) then\n      continue;\n    // skip overrides in smashed patches\n    if (IsSmashedPatch(f)) then \n      continue;\n    // skip ctIdenticalToMaster overrides\n    if (ConflictThisForMainRecord(ovr) = ctIdenticalToMaster) then\n      continue;\n    \n    // if master record is not assigned, copy winning override to smashed patch\n    if (not Assigned(mr)) then begin\n      try\n        mr := wbCopyElementToFile(WinningOverride(ovr), smashFile, false, true);\n      except on x: Exception do\n        LogMessage('      !! Exception copying record '+Name(rec)+' : '+x.Message);\n      end;\n    end;\n    \n    // look up setting for this file\n    try\n      ini := TMemIniFile(lstSettings[slSettings.IndexOf(slOptions[slFiles.IndexOf(fn)])]);\n    except on x : Exception do\n      LogMessage('Setting lookup exception : '+x.Message);\n    end;\n    \n    // recursively copy overriden elements\n    try\n      if makeNewLine then LogMessage('');\n      LogMessage('Smashing record '+Name(rec)+' from file: '+fn);\n      slSubrecords.Text := StringReplace(ini.ReadString('Setting', 'subrecords', ''), '#13', #13, [rfReplaceAll]);\n      rcore(ovr, rec, mr, mr, '    ', ini);\n    except on x : Exception do\n      LogMessage('    !! Exception smashing record '+Name(rec)+' : '+x.Message);\n    end;\n  end;\nend;\n\n\n{===========================================================}\n{ MAIN EXECUTION }\n\n\n{\n  ShowDetails\n  Enables the visibilty of the TMemo log\n}\nprocedure ShowDetails;\nbegin\n  frm.Height := 600;\n  frm.Position := poScreenCenter;\n  memo.Height := frm.Height - 150;\n  btnDetails.Visible := false;\n  memo.Visible := true;\nend;\n\n{\n  InitializeSettings\n  Loads settings from files\n}\nprocedure InitializeSettings;\nvar\n  i: integer;\n  ini: TMemIniFile;\n  s: string;\n  info: TSearchRec;\nbegin\n  // create lists\n  slSettings := TStringList.Create;\n  lstSettings := TList.Create;\n  \n  // load settings\n  SetCurrentDir(settingsPath);\n  if FindFirst(settingsPath+'*.ini', faAnyFile, info) = 0 then begin\n    repeat\n      lstSettings.Add(TMemIniFile.Create(settingsPath + info.Name));\n    until FindNext(info) <> 0;\n  end;\n  \n  // add setting strings\n  for i := 0 to lstSettings.Count - 1 do begin\n    s := TMemIniFile(lstSettings[i]).ReadString('Setting', 'Name', '');\n    slSettings.Add(s);\n  end;\nend;\n\n{\n  FreeMemory\n  Frees memory used by script\n}\nprocedure FreeMemory;\nbegin\n  gear.Free; slOptions.Free; slFiles.Free; slSettings.Free;\n  lstSettings.Free;\nend;\n\n{\n  Initialize\n  Load assets, settings, display forms, show progress bar, perform \n  main smashing procedure.\n}\nfunction Initialize: integer;\nvar\n  f, r: IInterface;\n  i, j, k: integer;\n  fn, rn, records, recordMode, logFileName, fdt: string;\n  ini: TMemIniFile;\n  tStart, tRec: TDateTime;\n  diff: double;\n  pic: TPicture;\n  bmpChecked, bmpUnChecked, bmpPChecked: TBitmap;\nbegin\n  // load tree stringlists\n  AssetPath := ScriptsPath + 'smash\\assets\\';\n  recordTree := TStringList.Create;\n  recordTree.LoadFromFile(AssetPath + 'RecordTree.txt');\n  subrecordTree := TStringList.Create;\n  subrecordTree.LoadFromFile(AssetPath + 'SubrecordTree.txt');\n  include := TStringList.Create;\n  \n  // load checkbox images\n  checkboxImages := TCustomImageList.Create(nil);\n  pic := TPicture.Create;\n  \n  bmpChecked := TBitmap.Create;\n  bmpUnChecked := TBitmap.Create;\n  bmpPChecked := TBitmap.Create;\n  \n  pic.LoadFromFile(AssetPath + 'Check.bmp');\n  bmpChecked.SetSize(17, 17);\n  bmpChecked.Canvas.Draw(0, 0, pic.Graphic);  \n  \n  pic.LoadFromFile(AssetPath + 'UnCheck.bmp');\n  bmpUnChecked.SetSize(17, 17);\n  bmpUnChecked.Canvas.Draw(0, 0, pic.Graphic);  \n  \n  pic.LoadFromFile(AssetPath + 'PartialCheck.bmp');\n  bmpPChecked.SetSize(17, 17);\n  bmpPChecked.Canvas.Draw(0, 0, pic.Graphic);  \n\n  checkboxImages.Add(bmpChecked, nil);\n  checkboxImages.Add(bmpChecked, nil);\n  checkboxImages.Add(bmpUnChecked, nil);\n  checkboxImages.Add(bmpPChecked, nil);\n  \n  // track time\n  tStart := Now;\n  \n  // stringlist creation\n  slOptions := TStringList.Create;\n  slFiles := TStringList.Create;\n  slSubrecords := TStringList.Create;\n  slGlobalSubrecords := TStringList.Create;\n  makeNewLine := showSkips or showTraversal or debugGetMaster or debugArrays \n    or showChanges or showTypeStrings or showRecTimes;\n  \n  // load gui elements\n  gear := TPicture.Create;\n  gear.LoadFromFile(AssetPath + 'gear.png');\n  \n  // load setting files\n  InitializeSettings;\n  \n  // set up for saving log\n  ForceDirectories(ScriptsPath + '\\smash\\logs');\n  fdt := FormatDateTime('mmddyy_hhnnss', Now);\n  logFileName := ScriptsPath + '\\smash\\logs\\smash' + fdt + '.txt';\n  \n  // initial options form\n  if OptionsForm then begin\n    frm := TForm.Create(nil);\n    try \n      frm.Caption := 'Mator Smash!';\n      frm.Width := 700;\n      frm.Position := poScreenCenter;\n      frm.Height := 150;\n      \n      // make progress label\n      lbl := cLabel(frm, frm, 20, 20, 30, 600, 'Initializing...', '');\n      \n      // make progress bar\n      pb := TProgressBar.Create(frm);\n      pb.Parent := frm;\n      pb.Top := 40;\n      pb.Left := 20;\n      pb.Width := frm.Width - 55;\n      pb.Height := 20;\n      pb.Step := 1;\n      pb.Min := 0;\n      pb.Position := 0;\n      \n      // make log memo\n      memo := cMemo(frm, frm, 70, 20, 0, pb.Width, false, true, ssBoth, '');\n      memo.Visible := false;\n      \n      // make details button\n      btnDetails := cButton(frm, frm, pb.Top + pb.Height + 8, pb.Left, 0, 100, 'Show Details');\n      btnDetails.OnClick := ShowDetails;\n      \n      // display form, initial logging messages\n      frm.Show;\n      application.processmessages;\n      LogMessage(dashes);\n      LogMessage('Mator Smash '+vs+': Makes a smashed patch.');\n      LogMessage(dashes);\n     \n      // create stringlists\n      slRecords := TStringList.Create;\n      \n      // load global settings\n      ini := TMemIniFile(lstSettings[slSettings.IndexOf(global_setting)]);\n      global_records := StringReplace(ini.ReadString('Setting', 'records', ''), splitChar, #13#10, [rfReplaceall]);\n      global_recordMode := ini.ReadString('Setting', 'recordMode', '0');\n      global_subrecords := StringReplace(ini.ReadString('Setting', 'subrecords', ''), splitChar, #13#10, [rfReplaceall]);\n      global_subrecordMode := ini.ReadString('Setting', 'subrecordMode', '0');\n      slGlobalSubrecords.Text := global_subrecords;\n     \n      // see if a smashed patch is loaded\n      for i := 0 to FileCount - 1 do begin\n        f := FileByIndex(i);\n        // if smashed patch found, break\n        if (IsSmashedPatch(f)) then begin\n          userFile := f;\n          break;\n        end;\n      end;\n     \n      // make userFile if not found\n      lbl.Caption := 'Assigning smashed patch.';\n      application.processmessages;\n      if not Assigned(userFile) then\n        userFile := AddNewFile;\n      if not Assigned(userFile) then begin\n        LogMessage('Smashed patch not assigned, terminating script');\n        FreeMemory;\n        frm.Free;\n        Result := -1;\n        exit;\n      end;\n      \n      // set userFile author to Mator Smash\n      lbl.Caption := 'Adding masters to smashed patch.';\n      application.processmessages;\n      seev(ebi(userFile, 0), 'CNAM', 'Mator Smash '+vs);\n      // add masters to userFile\n      for i := 0 to FileCount - 3 do begin\n        f := FileByLoadOrder(i);\n        if (IsSmashedPatch(f)) then\n          break;\n        fn := GetFileName(f);\n        AddMasterIfMissing(userFile, fn);\n      end;\n     \n      // loop through all loaded files\n      k := 0;\n      tRec := Now;\n      for i := 0 to FileCount - 1 do begin\n        f := FileByIndex(i);\n        fn := GetFileName(f);\n        \n        // skip bethesda files, we're not patching them\n        if Pos(fn, bethesdaFiles) > 0 then\n          continue;\n        // if smashed patch found, break\n        if (IsSmashedPatch(f)) then\n          break;\n        \n        // build list of records with multiple overrides\n        lbl.Caption := 'Processing '+fn;\n        LogMessage('Processing '+fn);\n        application.processmessages;\n        // load ini settings\n        ini := TMemIniFile(lstSettings[slSettings.IndexOf(slOptions[k])]);\n        records := StringReplace(ini.ReadString('Setting', 'records', ''), splitChar, #13#10, [rfReplaceAll]);\n        recordMode := ini.ReadString('Setting', 'recordMode', '0');\n        \n        // loop through records\n        for j := 0 to RecordCount(f) - 1 do begin\n          r := MasterOrSelf(RecordByIndex(f, j));\n          if (OverrideCount(r) <= 1) then\n            continue;\n          // skip records according to ini settings\n          if SkipRecord(r, records, recordMode) then \n            continue;\n          rn := Name(r);\n          if (nbsOverrideCount(r) > 1) then\n            if (ConflictThisForMainRecord(WinningOverride(r)) <> ctOverride) then\n              if slRecords.IndexOf(rn) = -1 then begin\n                slRecords.AddObject(rn, TObject(r));\n              end;\n        end;\n        Inc(k);\n      end;\n      diff := (Now - tRec) * 86400;\n      LogMessage(FormatFloat('0.###', diff) + ' seconds spent processing records.');\n     \n      // test list of records\n      if listOverrides then begin\n        LogMessage('');\n        for i := 0 to slRecords.Count - 1 do begin\n          r := ObjectToElement(slRecords.Objects[i]);\n          LogMessage(slRecords[i]+' ('+IntToStr(OverrideCount(r))+' overrides)');\n          for j := 0 to OverrideCount(r) - 1 do\n            LogMessage('    Override #'+IntToStr(j)+': '+GetFileName(GetFile(OverrideByIndex(r, j))));\n        end;\n      end;\n     \n      // smash records that have been overridden multiple times\n      lbl.Caption := 'Smashing records (1/'+IntToStr(slRecords.Count)+')';\n      application.processmessages;\n      pb.Max := slRecords.Count;\n      LogMessage('');\n      for i := 0 to slRecords.Count - 1 do begin\n        tRec := Now;\n        if i = maxRecords then break;\n        // smash record\n        r := ObjectToElement(slRecords.Objects[i]);\n        SmashRecord(r, userFile);\n        // update label, print debug message to log after smashing record\n        lbl.Caption := 'Smashing records ('+IntToStr(i + 2)+'/'+IntToStr(slRecords.Count)+')';\n        pb.Position := pb.Position + 1;\n        if showRecTimes then begin\n          diff := (Now - tRec) * 86400;\n          LogMessage('  '+FormatFloat('0.###', diff) + 's');\n        end;\n        application.processmessages;\n      end;\n      \n      // sort and clean masters\n      SortMasters(userFile);\n      CleanMasters(userFile);\n      \n      // finishing messages\n      lbl.Caption := 'All done.';\n      LogMessage(#13#10+dashes);\n      LogMessage('Smashing complete.  '+IntToStr(RecordCount(userfile))+' records smashed.');\n      diff := (Now - tStart) * 86400;\n      LogMessage('Completed in ' + FormatFloat('0.###', diff) + ' seconds.');\n      memo.Lines.SaveToFile(logFileName);\n      application.processmessages;\n      \n      if (memo.Visible) then begin\n        frm.Visible := false;\n        frm.ShowModal;\n      end;\n    except on x : Exception do begin\n        // smash failed\n        LogMessage(#13#10'Smash failed.  Exception: '+x.Message);\n        memo.Lines.SaveToFile(logFileName);\n        pb.Position := 0;\n        lbl.Caption := 'Smash Failed.  Exception: '+x.Message;\n        if not memo.Visible then ShowDetails;\n        frm.Visible := false;\n        frm.ShowModal;\n        Application.processmessages;\n      end;\n    end;\n    frm.Free;\n  end;\n\n  // free memory\n  FreeMemory;\n\n  // call RemoveFilter() to update TES5Edit GUI\n  try\n    RemoveFilter();\n  except on Exception do\n    AddMessage(#13#10'You''re not using the latest version of xEdit, so the script couldn''t update the GUI.');\n    AddMessage('Right click in the plugin view and click \"Remove Filter\" to update the GUI manually.');\n  end;\nend;\n\nend.\n"
  },
  {
    "path": "design/code snippets/better build algorithm.pas",
    "content": "procedure LoadElementData(var sl: TStringList; container: IwbContainerElementRef);\nvar\n  innerContainer: IwbContainerElementRef;\n  element: IwbElement;\nbegin\n  // loop through container's elements\n  for i := 0 to Pred(container.ElementCount) do begin\n    element := container.Elements[i];\n    //if bOverridesOnly and (ConflictThis(element) = ctIdenticalToMaster) then\n      //continue;\n    index := sl.IndexOf(element.Name);\n    // create new element name item if missing\n    if index = -1 then\n      index := sl.Add(element.Name);\n    // traverse children of element, if it has any\n    if Supports(element, IwbContainerElementRef, innerContainer) then\n      if innerContainer.ElementCount > 0 then begin\n        if not Assigned(sl.Objects[index]) then \n          sl.Objects[index] := TStringList.Create;\n        LoadElementData(TStringList(sl.Objects[index]), innerContainer); \n      end;\n  end;\nend;\n\nprocedure LoadRecordData(var sl: TStringList; f: IwbFile);\nvar\n  i, index: Integer;\n  container: IwbContainerElementRef;\n  rec: IwbMainRecord;\nbegin\n  // loop through file's records\n  for i := 0 to Pred(f.RecordCount) do begin\n    rec := f.Records[i];\n    // skip excluded signatures\n    if HasSignature(rec.Signature, excludedSignatures) then \n      continue;\n    // skip non-override records\n    if bOverridesOnly and not IsOverride(rec) then\n      continue;\n    index := sl.IndexOf(rec.Signature);\n    // add new record signature item if missing\n    if index = -1 then\n      index := sl.AddObject(rec.Signature, TStringList.Create);\n    if Supports(rec, IwbContainerElementRef, container) then\n      LoadElementData(TStringList(sl.Objects[index]), container);\n  end;\nend;\n\nprocedure StringsToNodes(node: TTreeNode; var sl: TStringList);\nvar\n  child: TTreeNode;\n  i: Integer;\nbegin\n  for i := 0 to Pred(sl.Count) do begin\n    child := TreeView.Items.AddChild(node, sl[i]);\n    child.Data := TElementData.Create(0, false, false, false);\n    if Assigned(sl.Objects[i]) then\n      StringsToNodes(child, TStringList(sl.Objects[i]));\n  end;\nend;\n\nprocedure TTreeThread.Execute;\nvar\n  i: Integer;\n  plugin: TPlugin;\nbegin\n  // ?\n  \n  // BODY\n  sl := TStringList.Create;\n  sl.Sorted := true;\n  for i := 0 to Pred(pluginsToHandle.Count) do begin\n    plugin := TPlugin(pluginsToHandle[i]);\n    LoadRecordData(sl, plugin._File);\n  end;\n  rootNode := TreeView.Items.Add(nil, 'Records');\n  StringsToNodes(rootNode, sl);\n  \n  //?\nend;\n\nfunction GetConflictThis(element: IwbElement): TConflictThis;\nvar\n  mainRecord, master, winning: IwbMainRecord;\nbegin\n  mainRecord := element.ContainingMainRecord;\n  if mainRecord.ConflictPriority = cpIgnore then\n    Result := ctIgnored\n  else if mainRecord.OverrideCount = 0 then\n    Result := ctOnlyOne\n  else begin  \n    master := mainRecord.Master;\n    winning := mainRecord.WinningOverride;\n    \n    masterElement := master.ElementByPath(element.Path);\n    winningElement := winning.ElementByPath(element.Path);\n  end;\nend;"
  },
  {
    "path": "design/notes/algorithm problems.txt",
    "content": "1. Elements with the same name"
  },
  {
    "path": "design/notes/handling.txt",
    "content": "Things to handle: ignoring deletions, treat as single entity, priority, linking\n\nIgnoring deletions:\nWhen applied to an element, ignore deletions in any of its children elements.\n-- boolean set to rcore\n-- leads us to not call \"delete elements if missing\"\n-- passed to HandleArray\n\nTreat as single entity:\nWhen applied to an element, any change in that its children's values leads us to copy the entire element to replace the destination element.\n-- boolean set to rcore\n-- rcore made into a function that returns true whenever a change occurs\n-- rcore doesn't call CopyElementValue when a value is different, simply returning true instead\n-- HandleArray also made into a function that returns true whenever a change occurs\n-- Array handlers return true when they detect an element has been added/deleted/changed\n\nPriority:\nOverrides load order on a per-element basis.  When priority for an element in a record in a file exceeds the priority of the same element in other files we use that element in destination record.  (remove?)\n\nLinking:\n"
  },
  {
    "path": "design/notes/high level design.txt",
    "content": "Smash\n\nQ: Do we want profiles?\nA: Yes, because a user may have multiple load orders or games they want to use smash with.\n\nQ: Do we want a backend?\nA: Yes. We want to serve up smash settings, plugin action recommendations, and program updates.\n\nQ: What will be the main actions of the user within the program?\nA: Create a new smashed patch, view/edit smash settings, view a plugin's record makeup, adjust program settings, update the program, download new smash settings, view the help file, submit smash settings, submit plugin action recommendations, build smashed patches, delete smashed patches, rebuild smashed patches, ...\n\nQ: What attributes will a smashed patch have?\nA: Plugins, plugin, date built, name, filename, smash setting, status, hashes, fails, files.\n\nQ: What attributes with a smash setting have?\nA: A tree of records/subrecord options (process [boolean], treat as single entity [boolean], priority [byte], preserve deletions [boolean]), applicable plugin makeup (record group breakdown), hash, and a name.  All smash settings will be inclusive.\n\nQ: What functionality will smash patch generation make use of?\nA: \n- Recursive traversal of records and subrecords\n- Record and subrecord skipping based on smash setting\n- Single-entity subrecord handling\n- Sorted array handling\n- Unsorted array handling\n- Record/subrecord priority\n- Record/subrecord preserve deletions option\n- Subrecord/record priority handling\n- Subrecord linking (possibly)\n\nQ: What information should we expose on plugins and their record makeup?\nA: What record groups are in the plugin.  How many records are in each record group.  The breakdown of new records/override records in the plugin.  The breakdown of new records/overrides in each record group.  A plugin dependency tree.  A breakdown of all record conflicts in the user's load order/between a selected set of plugins.  A breakdown of the elements that conflict in the user's load order/between a selected set of plugins.\n\nQ: What attributes will a plugin recommendation have?\nA: Plugin filename, plugin hash, smash setting name, smash setting hash.\n\nQ: How will setting recommendations be computed?\nA: Each setting will be compared against the plugin to see how many of the conflicts from the plugin it takes care of, and how well it matches the plugin's record makeup."
  },
  {
    "path": "design/notes/linking explanation.txt",
    "content": "1. we have a set of plugins\n2. each plugin has a smash setting\n3. each smash setting has a definition for certain records\n4. each record definition has a node for each element\n5. we can link a node in a record definition to another node\n\n--\n\nIf a element's value changes in a record in a file, and another element is linked to that element, the element that's linked will be copied from the record we're processing to the patch (if it exists).\n\n\nMASTER:   R2:       R3:       R4:         SMASHED RECORD:\nA: 1      A: 2      A: 1      A: 1        A: 1\nB: 2      B: 2      B: 2      B: 2        B: 2\nC: 3      C: 4      C: 5      C: 3        C: 5\n\n                    LINK A to C\n                    Whenever C changes, copy A\n                    \n                    "
  },
  {
    "path": "design/notes/todos 1024.txt",
    "content": "1. Plugin recommendations \"dictionary\"\n2. Plugin information form (and on main form?)\n3. Backend"
  },
  {
    "path": "frontend/MatorSmash.dpr",
    "content": "﻿{*******************************************************************************\n\n     The contents of this file are subject to the Mozilla Public License\n     Version 1.1 (the \"License\"); you may not use this file except in\n     compliance with the License. You may obtain a copy of the License at\n     http://www.mozilla.org/MPL/\n\n     Software distributed under the License is distributed on an \"AS IS\"\n     basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the\n     License for the specific language governing rights and limitations\n     under the License.\n\n*******************************************************************************}\n\nprogram MatorSmash;\n\n{$R 'smash.res' 'smash.rc'}\n\nuses\n  Forms,\n  Dialogs,\n  Controls,\n  SysUtils,\n  // lib\\mte\n  CRC32 in '..\\lib\\mte\\CRC32.pas',\n  mteBase in '..\\lib\\mte\\mteBase.pas',\n  mteChangeLogForm in '..\\lib\\mte\\mteChangeLogForm.pas',\n  mteHelpers in '..\\lib\\mte\\mteHelpers.pas',\n  mteLogger in '..\\lib\\mte\\mteLogger.pas',\n  mteLogging in '..\\lib\\mte\\mteLogging.pas',\n  mtePluginSelectionForm in '..\\lib\\mte\\mtePluginSelectionForm.pas',\n  mteProgressForm in '..\\lib\\mte\\mteProgressForm.pas',\n  mteTaskHandler in '..\\lib\\mte\\mteTaskHandler.pas',\n  RttiIni in '..\\lib\\mte\\RttiIni.pas',\n  RttiJson in '..\\lib\\mte\\RttiJson.pas',\n  RttiTranslation in '..\\lib\\mte\\RttiTranslation.pas',\n  W7Taskbar in '..\\lib\\mte\\W7Taskbar.pas',\n  // lib\\xedit\n  wbBSA in '..\\lib\\xedit\\wbBSA.pas',\n  wbDefinitionsFNV in '..\\lib\\xedit\\wbDefinitionsFNV.pas',\n  wbDefinitionsFO3 in '..\\lib\\xedit\\wbDefinitionsFO3.pas',\n  wbDefinitionsFO4 in '..\\lib\\xedit\\wbDefinitionsFO4.pas',\n  wbDefinitionsTES3 in '..\\lib\\xedit\\wbDefinitionsTES3.pas',\n  wbDefinitionsTES4 in '..\\lib\\xedit\\wbDefinitionsTES4.pas',\n  wbDefinitionsTES5 in '..\\lib\\xedit\\wbDefinitionsTES5.pas',\n  wbHelpers in '..\\lib\\xedit\\wbHelpers.pas',\n  wbImplementation in '..\\lib\\xedit\\wbImplementation.pas',\n  wbInterface in '..\\lib\\xedit\\wbInterface.pas',\n  wbLocalization in '..\\lib\\xedit\\wbLocalization.pas',\n  wbSort in '..\\lib\\xedit\\wbSort.pas',\n  wbStreams in '..\\lib\\xedit\\wbStreams.pas',\n  // Smash\n  msConfiguration in 'msConfiguration.pas',\n  msCore in 'msCore.pas',\n  msLoader in 'msLoader.pas',\n  msConflict in 'msConflict.pas',\n  msChoicePanel in 'msChoicePanel.pas',\n  msSmash in 'msSmash.pas',\n  msAlgorithm in 'msAlgorithm.pas',\n  msProfileForm in 'msProfileForm.pas' {ProfileForm},\n  msProfilePanel in 'msProfilePanel.pas',\n  msSmashForm in 'msSmashForm.pas' {SmashForm},\n  msThreads in 'msThreads.pas',\n  msOptionsForm in 'msOptionsForm.pas' {OptionsForm},\n  msSplashForm in 'msSplashForm.pas' {SplashForm},\n  msEditForm in 'msEditForm.pas' {EditForm},\n  msSettingsManager in 'msSettingsManager.pas' {SettingsManager},\n  msPluginSelectionForm in 'msPluginSelectionForm.pas' {MiniPluginSelectionForm},\n  msConflictForm in 'msConflictForm.pas' {ConflictForm},\n  msTagManager in 'msTagManager.pas' {TagManager},\n  msTagHelper in 'msTagHelper.pas' {TagHelper};\n\n{$R *.res}\n{$MAXSTACKSIZE 2097152}\n\nconst\n  IMAGE_FILE_LARGE_ADDRESS_AWARE = $0020;\n\n\n{$SetPEFlags IMAGE_FILE_LARGE_ADDRESS_AWARE}\n\nvar\n  bProfileProvided, bUseUTF8: boolean;\n  sParam, sProfile, sPath: string;\n  i: Integer;\n  aSettings: TSettings;\nbegin\n  // set important vars\n  SysUtils.FormatSettings.DecimalSeparator := '.';\n  Application.HintHidePause := 8000;\n  //ReportMemoryLeaksOnShutdown := true;\n  PathList.Values['ProgramPath'] := ExtractFilePath(ParamStr(0));\n\n  // get current profile if profile switch provided\n  for i := 1 to ParamCount do begin\n    sParam := ParamStr(i);\n    if sParam = '-profile' then\n      sProfile := ParamStr(i + 1);\n    if sParam = '-utf8' then\n      wbStringEncoding := seUTF8;\n  end;\n  bProfileProvided := sProfile <> '';\n  sPath := Format('%sprofiles\\%s\\settings.ini', [ProgramPath, sProfile]);\n  if bProfileProvided and FileExists(sPath) then begin\n    aSettings := TSettings.Create;\n    TRttiIni.Load(sPath, aSettings);\n    CurrentProfile := TProfile.Create(aSettings.profile);\n    CurrentProfile.gameMode := aSettings.gameMode;\n    CurrentProfile.gamePath := aSettings.gamePath;\n    aSettings.Free;\n  end;\n\n  // initialize application\n  Application.Initialize;\n  ForceDirectories(PathList.Values['ProgramPath'] + 'profiles');\n  LoadSettings;\n  LoadStatistics;\n\n  // have user select game mode\n  if not bProfileProvided then begin\n    ProfileForm := TProfileForm.Create(nil);\n    if not (ProfileForm.ShowModal = mrOk) then\n      exit;\n    ProfileForm.Free;\n  end;\n\n  // run main application\n  Application.Title := 'Mator Smash';\n  Application.CreateForm(TSmashForm, SmashForm);\n  Application.CreateForm(TProfileForm, ProfileForm);\n  Application.CreateForm(TOptionsForm, OptionsForm);\n  Application.CreateForm(TSplashForm, SplashForm);\n  Application.CreateForm(TEditForm, EditForm);\n  Application.CreateForm(TSettingsManager, SettingsManager);\n  Application.CreateForm(TMiniPluginSelectionForm, MiniPluginSelectionForm);\n  Application.CreateForm(TConflictForm, ConflictForm);\n  Application.CreateForm(TTagManager, TagManager);\n  Application.CreateForm(TTagHelper, TagHelper);\n  Application.Run;\nend.\n"
  },
  {
    "path": "frontend/MatorSmash.dproj",
    "content": "﻿\t<Project xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n\t\t<PropertyGroup>\n\t\t\t<ProjectGuid>{12317C9C-736E-45A4-8CB7-E43FF92DD93C}</ProjectGuid>\n\t\t\t<MainSource>MatorSmash.dpr</MainSource>\n\t\t\t<Base>True</Base>\n\t\t\t<Config Condition=\"'$(Config)'==''\">Release</Config>\n\t\t\t<AppType>Application</AppType>\n\t\t\t<FrameworkType>VCL</FrameworkType>\n\t\t\t<DCC_DCCCompiler>DCC32</DCC_DCCCompiler>\n\t\t\t<ProjectVersion>13.4</ProjectVersion>\n\t\t\t<Platform Condition=\"'$(Platform)'==''\">Win32</Platform>\n\t\t\t<TargetedPlatforms>1</TargetedPlatforms>\n\t\t\t<Platform>Win32</Platform>\n\t\t</PropertyGroup>\n\t\t<PropertyGroup Condition=\"'$(Config)'=='Base' or '$(Base)'!=''\">\n\t\t\t<Base>true</Base>\n\t\t</PropertyGroup>\n\t\t<PropertyGroup Condition=\"'$(Config)'=='Debug' or '$(Cfg_2)'!=''\">\n\t\t\t<Cfg_2>true</Cfg_2>\n\t\t\t<CfgParent>Base</CfgParent>\n\t\t\t<Base>true</Base>\n\t\t</PropertyGroup>\n\t\t<PropertyGroup Condition=\"'$(Config)'=='DebugLite' or '$(Cfg_4)'!=''\">\n\t\t\t<Cfg_4>true</Cfg_4>\n\t\t\t<CfgParent>Base</CfgParent>\n\t\t\t<Base>true</Base>\n\t\t</PropertyGroup>\n\t\t<PropertyGroup Condition=\"'$(Config)'=='Release' or '$(Cfg_1)'!=''\">\n\t\t\t<Cfg_1>true</Cfg_1>\n\t\t\t<CfgParent>Base</CfgParent>\n\t\t\t<Base>true</Base>\n\t\t</PropertyGroup>\n\t\t<PropertyGroup Condition=\"'$(Base)'!=''\">\n\t\t\t<DCC_UsePackage>vcl;rtl;vclx;vclactnband;xmlrtl;VclSmp;vclimg;svnui;svn;bdertl;TeeUI;TeeDB;Tee;vcldb;dbrtl;vcldbx;vcltouch;dsnap;dsnapcon;vclib;ibxpress;adortl;IndyCore;IndySystem;IndyProtocols;inet;intrawebdb_110_150;Intraweb_110_150;vclie;websnap;webdsnap;inetdb;inetdbbde;inetdbxpress;soaprtl;vclribbon;dbexpress;DbxCommonDriver;DataSnapIndy10ServerTransport;DataSnapProviderClient;DataSnapClient;dbxcds;DbxClientDriver;DataSnapServer;AzureCloud;DBXInterBaseDriver;DBXMySQLDriver;DBXFirebirdDriver;DBXSybaseASEDriver;DBXSybaseASADriver;DBXOracleDriver;DBXMSSQLDriver;DBXInformixDriver;DBXDb2Driver</DCC_UsePackage>\n\t\t\t<DCC_UnitSearchPath>..\\lib\\Imaging\\ZLib;..\\lib\\abbrevia\\source;..\\lib\\Imaging;..\\lib\\xedit;..\\lib\\mte;..\\lib\\superobject;..\\lib\\xedit\\zlib;..\\lib\\xedit\\lz4;$(DCC_UnitSearchPath)</DCC_UnitSearchPath>\n\t\t\t<DCC_SYMBOL_DEPRECATED>false</DCC_SYMBOL_DEPRECATED>\n\t\t\t<DCC_WIDECHAR_REDUCED>false</DCC_WIDECHAR_REDUCED>\n\t\t\t<DCC_SYMBOL_PLATFORM>false</DCC_SYMBOL_PLATFORM>\n\t\t\t<DCC_UNIT_PLATFORM>false</DCC_UNIT_PLATFORM>\n\t\t\t<DCC_COMBINING_SIGNED_UNSIGNED>false</DCC_COMBINING_SIGNED_UNSIGNED>\n\t\t\t<Icon_MainIcon>TES5Edit_Icon.ico</Icon_MainIcon>\n\t\t\t<DCC_IMPLICIT_STRING_CAST>false</DCC_IMPLICIT_STRING_CAST>\n\t\t\t<DCC_COMPARING_SIGNED_UNSIGNED>false</DCC_COMPARING_SIGNED_UNSIGNED>\n\t\t\t<Manifest_File>None</Manifest_File>\n\t\t\t<VerInfo_Locale>3081</VerInfo_Locale>\n\t\t\t<VerInfo_Keys>CompanyName=;FileDescription=;FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductName=;ProductVersion=1.0.0.0;Comments=</VerInfo_Keys>\n\t\t\t<DCC_Namespace>Vcl;Vcl.Imaging;Vcl.Touch;Vcl.Samples;Vcl.Shell;System;Xml;Data;Datasnap;Web;Soap;Winapi;FMX;System.Win;$(DCC_Namespace)</DCC_Namespace>\n\t\t\t<DCC_E>false</DCC_E>\n\t\t\t<DCC_ImageBase>00400000</DCC_ImageBase>\n\t\t\t<DCC_F>false</DCC_F>\n\t\t\t<DCC_S>false</DCC_S>\n\t\t\t<DCC_N>false</DCC_N>\n\t\t\t<DCC_K>false</DCC_K>\n\t\t</PropertyGroup>\n\t\t<PropertyGroup Condition=\"'$(Cfg_2)'!=''\">\n\t\t\t<DCC_GenerateStackFrames>true</DCC_GenerateStackFrames>\n\t\t\t<DCC_Define>DEBUG;NX_EXCEPTION_LOG_IN_APP_FOLDER;$(DCC_Define)</DCC_Define>\n\t\t\t<DCC_MapFile>3</DCC_MapFile>\n\t\t\t<ILINK_MapFileType>DetailedSegments</ILINK_MapFileType>\n\t\t</PropertyGroup>\n\t\t<PropertyGroup Condition=\"'$(Cfg_4)'!=''\">\n\t\t\t<DCC_ExeOutput>.\\DebugLite</DCC_ExeOutput>\n\t\t\t<DCC_Define>DEBUG;NX_EXCEPTION_LOG_IN_APP_FOLDER;LiteVersion;$(DCC_Define)</DCC_Define>\n\t\t\t<DCC_MapFile>3</DCC_MapFile>\n\t\t\t<ILINK_MapFileType>DetailedSegments</ILINK_MapFileType>\n\t\t\t<DCC_GenerateStackFrames>true</DCC_GenerateStackFrames>\n\t\t</PropertyGroup>\n\t\t<PropertyGroup Condition=\"'$(Cfg_1)'!=''\">\n\t\t\t<DCC_DebugInformation>false</DCC_DebugInformation>\n\t\t\t<DCC_IOChecking>false</DCC_IOChecking>\n\t\t\t<DCC_LocalDebugSymbols>false</DCC_LocalDebugSymbols>\n\t\t\t<DCC_AssertionsAtRuntime>false</DCC_AssertionsAtRuntime>\n\t\t\t<DCC_ImportedDataReferences>false</DCC_ImportedDataReferences>\n\t\t\t<DCC_SymbolReferenceInfo>0</DCC_SymbolReferenceInfo>\n\t\t</PropertyGroup>\n\t\t<ItemGroup>\n\t\t\t<DelphiCompile Include=\"MatorSmash.dpr\">\n\t\t\t\t<MainSource>MainSource</MainSource>\n\t\t\t</DelphiCompile>\n\t\t\t<RcCompile Include=\"smash.rc\">\n\t\t\t\t<ContainerId>RC</ContainerId>\n\t\t\t\t<ContainerId>RC</ContainerId>\n\t\t\t\t<Form>smash.res</Form>\n\t\t\t</RcCompile>\n\t\t\t<DCCReference Include=\"..\\lib\\mte\\CRC32.pas\"/>\n\t\t\t<DCCReference Include=\"..\\lib\\mte\\mteBase.pas\"/>\n\t\t\t<DCCReference Include=\"..\\lib\\mte\\mteChangeLogForm.pas\"/>\n\t\t\t<DCCReference Include=\"..\\lib\\mte\\mteHelpers.pas\"/>\n\t\t\t<DCCReference Include=\"..\\lib\\mte\\mteLogger.pas\"/>\n\t\t\t<DCCReference Include=\"..\\lib\\mte\\mteLogging.pas\"/>\n\t\t\t<DCCReference Include=\"..\\lib\\mte\\mtePluginSelectionForm.pas\"/>\n\t\t\t<DCCReference Include=\"..\\lib\\mte\\mteProgressForm.pas\"/>\n\t\t\t<DCCReference Include=\"..\\lib\\mte\\mteTaskHandler.pas\"/>\n\t\t\t<DCCReference Include=\"..\\lib\\mte\\RttiIni.pas\"/>\n\t\t\t<DCCReference Include=\"..\\lib\\mte\\RttiJson.pas\"/>\n\t\t\t<DCCReference Include=\"..\\lib\\mte\\RttiTranslation.pas\"/>\n\t\t\t<DCCReference Include=\"..\\lib\\mte\\W7Taskbar.pas\"/>\n\t\t\t<DCCReference Include=\"..\\lib\\xedit\\wbBSA.pas\"/>\n\t\t\t<DCCReference Include=\"..\\lib\\xedit\\wbDefinitionsFNV.pas\"/>\n\t\t\t<DCCReference Include=\"..\\lib\\xedit\\wbDefinitionsFO3.pas\"/>\n\t\t\t<DCCReference Include=\"..\\lib\\xedit\\wbDefinitionsFO4.pas\"/>\n\t\t\t<DCCReference Include=\"..\\lib\\xedit\\wbDefinitionsTES3.pas\"/>\n\t\t\t<DCCReference Include=\"..\\lib\\xedit\\wbDefinitionsTES4.pas\"/>\n\t\t\t<DCCReference Include=\"..\\lib\\xedit\\wbDefinitionsTES5.pas\"/>\n\t\t\t<DCCReference Include=\"..\\lib\\xedit\\wbHelpers.pas\"/>\n\t\t\t<DCCReference Include=\"..\\lib\\xedit\\wbImplementation.pas\"/>\n\t\t\t<DCCReference Include=\"..\\lib\\xedit\\wbInterface.pas\"/>\n\t\t\t<DCCReference Include=\"..\\lib\\xedit\\wbLocalization.pas\"/>\n\t\t\t<DCCReference Include=\"..\\lib\\xedit\\wbSort.pas\"/>\n\t\t\t<DCCReference Include=\"..\\lib\\xedit\\wbStreams.pas\"/>\n\t\t\t<DCCReference Include=\"msConfiguration.pas\"/>\n\t\t\t<DCCReference Include=\"msCore.pas\"/>\n\t\t\t<DCCReference Include=\"msLoader.pas\"/>\n\t\t\t<DCCReference Include=\"msConflict.pas\"/>\n\t\t\t<DCCReference Include=\"msChoicePanel.pas\"/>\n\t\t\t<DCCReference Include=\"msSmash.pas\"/>\n\t\t\t<DCCReference Include=\"msAlgorithm.pas\"/>\n\t\t\t<DCCReference Include=\"msProfileForm.pas\">\n\t\t\t\t<Form>ProfileForm</Form>\n\t\t\t</DCCReference>\n\t\t\t<DCCReference Include=\"msProfilePanel.pas\"/>\n\t\t\t<DCCReference Include=\"msSmashForm.pas\">\n\t\t\t\t<Form>SmashForm</Form>\n\t\t\t</DCCReference>\n\t\t\t<DCCReference Include=\"msThreads.pas\"/>\n\t\t\t<DCCReference Include=\"msOptionsForm.pas\">\n\t\t\t\t<Form>OptionsForm</Form>\n\t\t\t</DCCReference>\n\t\t\t<DCCReference Include=\"msSplashForm.pas\">\n\t\t\t\t<Form>SplashForm</Form>\n\t\t\t</DCCReference>\n\t\t\t<DCCReference Include=\"msEditForm.pas\">\n\t\t\t\t<Form>EditForm</Form>\n\t\t\t</DCCReference>\n\t\t\t<DCCReference Include=\"msSettingsManager.pas\">\n\t\t\t\t<Form>SettingsManager</Form>\n\t\t\t</DCCReference>\n\t\t\t<DCCReference Include=\"msPluginSelectionForm.pas\">\n\t\t\t\t<Form>MiniPluginSelectionForm</Form>\n\t\t\t</DCCReference>\n\t\t\t<DCCReference Include=\"msConflictForm.pas\">\n\t\t\t\t<Form>ConflictForm</Form>\n\t\t\t</DCCReference>\n\t\t\t<DCCReference Include=\"msTagManager.pas\">\n\t\t\t\t<Form>TagManager</Form>\n\t\t\t</DCCReference>\n\t\t\t<DCCReference Include=\"msTagHelper.pas\">\n\t\t\t\t<Form>TagHelper</Form>\n\t\t\t</DCCReference>\n\t\t\t<None Include=\"ModelSupport_MatorSmash\\default.txvpck\"/>\n\t\t\t<BuildConfiguration Include=\"Debug\">\n\t\t\t\t<Key>Cfg_2</Key>\n\t\t\t\t<CfgParent>Base</CfgParent>\n\t\t\t</BuildConfiguration>\n\t\t\t<BuildConfiguration Include=\"DebugLite\">\n\t\t\t\t<Key>Cfg_4</Key>\n\t\t\t\t<CfgParent>Base</CfgParent>\n\t\t\t</BuildConfiguration>\n\t\t\t<BuildConfiguration Include=\"Base\">\n\t\t\t\t<Key>Base</Key>\n\t\t\t</BuildConfiguration>\n\t\t\t<BuildConfiguration Include=\"Release\">\n\t\t\t\t<Key>Cfg_1</Key>\n\t\t\t\t<CfgParent>Base</CfgParent>\n\t\t\t</BuildConfiguration>\n\t\t</ItemGroup>\n\t\t<Import Condition=\"Exists('$(BDS)\\Bin\\CodeGear.Delphi.Targets')\" Project=\"$(BDS)\\Bin\\CodeGear.Delphi.Targets\"/>\n\t\t<Import Condition=\"Exists('$(APPDATA)\\Embarcadero\\$(BDSAPPDATABASEDIR)\\$(PRODUCTVERSION)\\UserTools.proj')\" Project=\"$(APPDATA)\\Embarcadero\\$(BDSAPPDATABASEDIR)\\$(PRODUCTVERSION)\\UserTools.proj\"/>\n\t\t<ProjectExtensions>\n\t\t\t<Borland.Personality>Delphi.Personality.12</Borland.Personality>\n\t\t\t<Borland.ProjectType>VCLApplication</Borland.ProjectType>\n\t\t\t<BorlandProject>\n\t\t\t\t<Delphi.Personality>\n\t\t\t\t\t<Source>\n\t\t\t\t\t\t<Source Name=\"MainSource\">MatorSmash.dpr</Source>\n\t\t\t\t\t</Source>\n\t\t\t\t\t<VersionInfo>\n\t\t\t\t\t\t<VersionInfo Name=\"IncludeVerInfo\">True</VersionInfo>\n\t\t\t\t\t\t<VersionInfo Name=\"AutoIncBuild\">False</VersionInfo>\n\t\t\t\t\t\t<VersionInfo Name=\"MajorVer\">1</VersionInfo>\n\t\t\t\t\t\t<VersionInfo Name=\"MinorVer\">0</VersionInfo>\n\t\t\t\t\t\t<VersionInfo Name=\"Release\">1</VersionInfo>\n\t\t\t\t\t\t<VersionInfo Name=\"Build\">0</VersionInfo>\n\t\t\t\t\t\t<VersionInfo Name=\"Debug\">True</VersionInfo>\n\t\t\t\t\t\t<VersionInfo Name=\"PreRelease\">True</VersionInfo>\n\t\t\t\t\t\t<VersionInfo Name=\"Special\">False</VersionInfo>\n\t\t\t\t\t\t<VersionInfo Name=\"Private\">False</VersionInfo>\n\t\t\t\t\t\t<VersionInfo Name=\"DLL\">False</VersionInfo>\n\t\t\t\t\t\t<VersionInfo Name=\"Locale\">1033</VersionInfo>\n\t\t\t\t\t\t<VersionInfo Name=\"CodePage\">1252</VersionInfo>\n\t\t\t\t\t</VersionInfo>\n\t\t\t\t\t<VersionInfoKeys>\n\t\t\t\t\t\t<VersionInfoKeys Name=\"CompanyName\"/>\n\t\t\t\t\t\t<VersionInfoKeys Name=\"FileDescription\"/>\n\t\t\t\t\t\t<VersionInfoKeys Name=\"FileVersion\">1.0.1.0</VersionInfoKeys>\n\t\t\t\t\t\t<VersionInfoKeys Name=\"InternalName\"/>\n\t\t\t\t\t\t<VersionInfoKeys Name=\"LegalCopyright\"/>\n\t\t\t\t\t\t<VersionInfoKeys Name=\"LegalTrademarks\"/>\n\t\t\t\t\t\t<VersionInfoKeys Name=\"OriginalFilename\"/>\n\t\t\t\t\t\t<VersionInfoKeys Name=\"ProductName\">Mator Smash</VersionInfoKeys>\n\t\t\t\t\t\t<VersionInfoKeys Name=\"ProductVersion\">1.0</VersionInfoKeys>\n\t\t\t\t\t\t<VersionInfoKeys Name=\"Comments\">created by matortheeternal</VersionInfoKeys>\n\t\t\t\t\t</VersionInfoKeys>\n\t\t\t\t\t<Excluded_Packages>\n\t\t\t\t\t\t<Excluded_Packages Name=\"$(BDSBIN)\\bcboffice2k150.bpl\">Embarcadero C++Builder Office 2000 Servers Package</Excluded_Packages>\n\t\t\t\t\t\t<Excluded_Packages Name=\"$(BDSBIN)\\bcbofficexp150.bpl\">Embarcadero C++Builder Office XP Servers Package</Excluded_Packages>\n\t\t\t\t\t\t<Excluded_Packages Name=\"$(BDSBIN)\\dcloffice2k150.bpl\">Microsoft Office 2000 Sample Automation Server Wrapper Components</Excluded_Packages>\n\t\t\t\t\t\t<Excluded_Packages Name=\"$(BDSBIN)\\dclofficexp150.bpl\">Microsoft Office XP Sample Automation Server Wrapper Components</Excluded_Packages>\n\t\t\t\t\t</Excluded_Packages>\n\t\t\t\t\t<Parameters_Win32/>\n\t\t\t\t</Delphi.Personality>\n\t\t\t\t<Platforms>\n\t\t\t\t\t<Platform value=\"Win64\">False</Platform>\n\t\t\t\t\t<Platform value=\"Win32\">True</Platform>\n\t\t\t\t</Platforms>\n\t\t\t\t<ModelSupport>True</ModelSupport>\n\t\t\t</BorlandProject>\n\t\t\t<ProjectFileVersion>12</ProjectFileVersion>\n\t\t</ProjectExtensions>\n\t</Project>\n"
  },
  {
    "path": "frontend/MatorSmash.mes",
    "content": "[GeneralSettings]\nMesVersion=4\nHandleExceptions=0\nLinkInCode=1\nAppendMapFileToBinary=1\nNoOwnMadExceptSettings=0\nCheckFileCrc=1\nCheckForFrozenMainThread=0\nFreezeTimeout=60000\nReportLeaks=0\nWindowsLogo=0\nCrashOnBuffer=0\nCrashOnUnderrun=0\nAutomaticallySaveBugReport=1\nAutoSaveBugReportIfNotSent=0\nAutomaticallyMailBugReport=0\nAutoMailProgressBox=0\nCopyBugReportToClipboard=0\nSuspendAllRunningThreads=0\nShowPleaseWaitBox=0\nPleaseWaitIcon=plwait1\nAutomaticallyContinueApplication=1\nAutomaticallyRestartApplication=0\nAutomaticallyCloseApplication=0\nSendInBackground=0\nSendHelper=196608\nSend32Icon=send321\nUploadViaHttp=0\nHttpServer=\nHttpSsl=0\nHttpPort=0\nHttpAccount=\nHttpPassword=\nUploadToFogBugz=0\nUploadToBugZilla=0\nUploadToMantis=0\nBugTrackerAccount=\nBugTrackerPassword=\nBugTrackerProject=\nBugTrackerArea=\nBugTrackerAssignTo=\nMailAsSmtpServer=0\nMailAsSmtpClient=0\nSmtpServer=\nSmtpSsl=0\nSmtpTls=0\nSmtpPort=0\nSmtpAccount=\nSmtpPassword=\nMailViaMapi=0\nMailViaMailto=0\nMailAddress=\nBugReportFile=bugreport.txt\nAttachBugReport=0\nAttachBugReportFile=1\nDeleteBugReportFile=1\nBugReportSendAs=bugreport.txt\nBugReportZip=\nScreenShotDepth=0\nScreenShotAppOnly=0\nScreenShotSendAs=screenshot.png\nScreenShotZip=\nAdditionalAttachments=\nAppendBugReports=1\nBugReportFileSize=100000\nDontSaveDuplicateExceptions=1\nDontSaveDuplicateFreezings=1\nDuplicateExceptionDefinition=1\nDuplicateFreezeDefinition=2\nShowExceptionBox=1\nOkBtnText=&OK\nDetailsBtnText=&Details\nPleaseWaitTitle=Information\nPleaseWaitText=Please wait a moment...\nBugTrackerTitle=%25appname%25, %25exceptMsg%25\nBugTrackerDescr=error details: %0d%0a%25errorDetails%25\nMailSubject=bug report\nMailBody=please find the bug report attached\nSendBoxTitle=Sending bug report...\nPrepareAttachMsg=Preparing attachments...\nMxLookupMsg=Searching for mail server...\nConnectMsg=Connecting to server...\nSendMailMsg=Sending mail...\nFieldsMsg=Setting fields...\nSendAttachMsg=Sending attachments...\nSendFinalizeMsg=Finalizing...\nMailFailureMsg=Sorry, sending the bug report didn't work.\nVersionVariable=\n[ExceptionBox]\nShowButtonMailBugReport=0\nShowButtonSaveBugReport=0\nShowButtonPrintBugReport=0\nShowButtonShowBugReport=1\nShowButtonContinueApplication=1\nShowButtonRestartApplication=1\nShowButtonCloseApplication=1\nIconButtonSendBugReport=send1\nIconButtonSaveBugReport=save1\nIconButtonPrintBugReport=print1\nIconButtonShowBugReport=show1\nIconButtonContinueApplication=continue1\nIconButtonCantContinueApplication=cantContinue1\nIconButtonRestartApplication=restart1\nIconButtonCloseApplication=close1\nFocusedButton=4\nSendAssistant=SendAssistant\nSaveAssistant=SaveAssistant\nPrintAssistant=PrintAssistant\nAutomaticallyShowBugReport=0\nNoOwnerDrawButtons=0\nBigExceptionIcon=big1\nTitleBar=%25appname%25\nExceptionMessage=An error occurred in the application.\nFrozenMessage=The application seems to be frozen.\nBitFaultMsg=The file \"%25modname%25\" seems to be corrupt!\nMailBugReportText=send bug report\nSaveBugReportText=save bug report\nPrintBugReportText=print bug report\nShowBugReportText=show bug report\nContinueApplicationText=continue application\nRestartApplicationText=restart application\nCloseApplicationText=close application\n[BugReport]\nListThreads=1\nListModules=1\nListHardware=1\nShowCpuRegisters=1\nShowStackDump=1\nDisassembly=1\nHideUglyItems=0\nShowRelativeAddrs=1\nShowRelativeLines=1\nFormatDisassembly=0\nLimitDisassembly=5\nEnabledPlugins=modules|processes|hardware\n[Filters]\nFilter1ExceptionClasses=\nFilter1DontCreateBugReport=0\nFilter1DontCreateScreenshot=0\nFilter1DontSuspendThreads=0\nFilter1DontCallHandlers=0\nFilter1ShowBox=3\nFilter1Assis=\nFilter2ExceptionClasses=\nFilter2DontCreateBugReport=0\nFilter2DontCreateScreenshot=0\nFilter2DontSuspendThreads=0\nFilter2DontCallHandlers=0\nFilter2ShowBox=0\nFilter2Assis=\nGeneralDontCreateBugReport=0\nGeneralDontCreateScreenshot=0\nGeneralDontSuspendThreads=0\nGeneralDontCallHandlers=0\nGeneralShowBox=0\nGeneralAssis=\n[Assistants]\nAssistant1=SendAssistant|Send Assistant|ContactForm|DetailsForm|ScrShotForm\nAssistant2=SaveAssistant|Save Assistant|ContactForm|DetailsForm\nAssistant3=PrintAssistant|Print Assistant|ContactForm|DetailsForm\nForms1=TPF0%0eTMEContactForm%0bContactForm%07Message%0c%13%00%00%00Contact Information%08MinWidth%04%00%00%00%00%08OnAction%0c%1b%00%00%00madExcept.HandleContactForm%05Timer%04%00%00%00%00%00%09INVButton%0bContinueBtn%07Caption%0c%08%00%00%00Continue%07Enabled%09%0bNoOwnerDraw%08%07Visible%09%00%00%09INVButton%07SkipBtn%07Caption%0c%04%00%00%00Skip%07Enabled%08%0bNoOwnerDraw%08%07Visible%09%00%00%09INVButton%09CancelBtn%07Caption%0c%06%00%00%00Cancel%07Enabled%09%0bNoOwnerDraw%08%07Visible%09%00%00%08INVLabel%06Label1%07Caption%0c%0a%00%00%00your name:%07Enabled%09%07Spacing%04%00%00%00%00%00%00%07INVEdit%08NameEdit%07Colored%09%07Enabled%09%05Lines%04%01%00%00%00%08Optional%09%0aOutputName%0c%0c%00%00%00contact name%0aOutputType%07%09nvoHeader%07Spacing%04%00%00%00%00%04Text%0c%00%00%00%00%05Valid%09%00%00%08INVLabel%06Label2%07Caption%0c%0b%00%00%00your email:%07Enabled%09%07Spacing%04%00%00%00%00%00%00%07INVEdit%09EmailEdit%07Colored%09%07Enabled%09%05Lines%04%01%00%00%00%08Optional%08%0aOutputName%0c%0d%00%00%00contact email%0aOutputType%07%09nvoHeader%07Spacing%04%00%00%00%00%04Text%0c%00%00%00%00%05Valid%09%00%00%0bINVCheckBox%08MemCheck%07Caption%0c%0b%00%00%00remember me%07Checked%08%07Enabled%09%0aOutputName%0c%00%00%00%00%07Spacing%04%00%00%00%00%00%00%00\nForms2=TPF0%0eTMEDetailsForm%0bDetailsForm%07Message%0c%0d%00%00%00Error Details%08MinWidth%04%00%00%00%00%08OnAction%0c%00%00%00%00%05Timer%04%00%00%00%00%00%09INVButton%0bContinueBtn%07Caption%0c%08%00%00%00Continue%07Enabled%09%0bNoOwnerDraw%08%07Visible%09%00%00%09INVButton%07SkipBtn%07Caption%0c%04%00%00%00Skip%07Enabled%09%0bNoOwnerDraw%08%07Visible%09%00%00%09INVButton%09CancelBtn%07Caption%0c%06%00%00%00Cancel%07Enabled%09%0bNoOwnerDraw%08%07Visible%09%00%00%08INVLabel%06Label1%07Caption%0c,%00%00%00what were you doing when the error occurred?%07Enabled%09%07Spacing%04%00%00%00%00%00%00%07INVEdit%0bDetailsMemo%07Colored%09%07Enabled%09%05Lines%04%09%00%00%00%08Optional%08%0aOutputName%0c%0d%00%00%00error details%0aOutputType%07%0dnvoOwnSection%07Spacing%04%00%00%00%00%04Text%0c%00%00%00%00%05Valid%09%00%00%00\nForms3=TPF0%0eTMEScrShotForm%0bScrShotForm%0dActiveControl%07%0bContinueBtn%07Message%0c%18%00%00%00Screenshot Configuration%08MinWidth%04%00%00%00%00%08OnAction%0c%1e%00%00%00madExcept.HandleScreenshotForm%05Timer%04%fa%00%00%00%00%09INVButton%0bContinueBtn%07Caption%0c%08%00%00%00Continue%07Enabled%09%0bNoOwnerDraw%08%07Visible%09%00%00%09INVButton%07SkipBtn%07Caption%0c%04%00%00%00Skip%07Enabled%08%0bNoOwnerDraw%08%07Visible%09%00%00%09INVButton%09CancelBtn%07Caption%0c%06%00%00%00Cancel%07Enabled%09%0bNoOwnerDraw%08%07Visible%09%00%00%0bINVCheckBox%0bAttachCheck%07Caption%0c%25%00%00%00attach a screenshot to the bug report%07Checked%09%07Enabled%09%0aOutputName%0c%00%00%00%00%07Spacing%04%00%00%00%00%00%00%08INVImage%0aScrShotImg%06Border%09%09Clickable%09%07Enabled%09%04File%0c%00%00%00%00%06Height%04%00%00%00%00%07Spacing%04%00%00%00%00%05Width%04%00%00%00%00%00%00%08INVLabel%06Label1%07Caption%0c%15%00%00%00(click to edit image)%07Enabled%09%07Spacing%04%00%00%00%00%00%00%00\n"
  },
  {
    "path": "frontend/ModelSupport_MatorSmash/MatorSmash/default.txvpck",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<nodeSet version=\"1.0\">\n  <view uin=\"b4zfh5af0zf_v\">\n    <property name=\"$defaultDiagram\" value=\"true\" />\n    <property name=\"$metaclass\" value=\"Package Diagram\" />\n    <property name=\"$name\" value=\"default\" />\n  </view>\n</nodeSet>"
  },
  {
    "path": "frontend/ModelSupport_MatorSmash/default.txvpck",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<nodeSet version=\"1.0\">\n  <view uin=\"ea9vm1284dq_v\">\n    <property name=\"$defaultDiagram\" value=\"true\" />\n    <property name=\"$metaclass\" value=\"Package Diagram\" />\n    <property name=\"$name\" value=\"default\" />\n  </view>\n</nodeSet>"
  },
  {
    "path": "frontend/ModelSupport_MatorSmash/msEditForm/default.txvpck",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<nodeSet version=\"1.0\">\n  <view uin=\"njkyjunm3h_v\">\n    <property name=\"$defaultDiagram\" value=\"true\" />\n    <property name=\"$metaclass\" value=\"Package Diagram\" />\n    <property name=\"$name\" value=\"default\" />\n  </view>\n</nodeSet>"
  },
  {
    "path": "frontend/ModelSupport_MatorSmash/msFrontend/default.txvpck",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<nodeSet version=\"1.0\">\n  <view uin=\"n0j337jkpef_v\">\n    <property name=\"$defaultDiagram\" value=\"true\" />\n    <property name=\"$metaclass\" value=\"Package Diagram\" />\n    <property name=\"$name\" value=\"default\" />\n  </view>\n</nodeSet>"
  },
  {
    "path": "frontend/ModelSupport_MatorSmash/msOptionsForm/default.txvpck",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<nodeSet version=\"1.0\">\n  <view uin=\"z6ar60bu6om_v\">\n    <property name=\"$defaultDiagram\" value=\"true\" />\n    <property name=\"$metaclass\" value=\"Package Diagram\" />\n    <property name=\"$name\" value=\"default\" />\n  </view>\n</nodeSet>"
  },
  {
    "path": "frontend/ModelSupport_MatorSmash/msProfileForm/default.txvpck",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<nodeSet version=\"1.0\">\n  <view uin=\"y0bo0tytf3p_v\">\n    <property name=\"$defaultDiagram\" value=\"true\" />\n    <property name=\"$metaclass\" value=\"Package Diagram\" />\n    <property name=\"$name\" value=\"default\" />\n  </view>\n</nodeSet>"
  },
  {
    "path": "frontend/ModelSupport_MatorSmash/msProfilePanel/default.txvpck",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<nodeSet version=\"1.0\">\n  <view uin=\"ac7klwk840k_v\">\n    <property name=\"$defaultDiagram\" value=\"true\" />\n    <property name=\"$metaclass\" value=\"Package Diagram\" />\n    <property name=\"$name\" value=\"default\" />\n  </view>\n</nodeSet>"
  },
  {
    "path": "frontend/ModelSupport_MatorSmash/msSmashForm/default.txvpck",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<nodeSet version=\"1.0\">\n  <view uin=\"d40chv15btm_v\">\n    <property name=\"$defaultDiagram\" value=\"true\" />\n    <property name=\"$metaclass\" value=\"Package Diagram\" />\n    <property name=\"$name\" value=\"default\" />\n  </view>\n</nodeSet>"
  },
  {
    "path": "frontend/ModelSupport_MatorSmash/msSplashForm/default.txvpck",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<nodeSet version=\"1.0\">\n  <view uin=\"xigiykmxj3j_v\">\n    <property name=\"$defaultDiagram\" value=\"true\" />\n    <property name=\"$metaclass\" value=\"Package Diagram\" />\n    <property name=\"$name\" value=\"default\" />\n  </view>\n</nodeSet>"
  },
  {
    "path": "frontend/ModelSupport_MatorSmash/msThreads/default.txvpck",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<nodeSet version=\"1.0\">\n  <view uin=\"y6gq3u7hleh_v\">\n    <property name=\"$defaultDiagram\" value=\"true\" />\n    <property name=\"$metaclass\" value=\"Package Diagram\" />\n    <property name=\"$name\" value=\"default\" />\n  </view>\n</nodeSet>"
  },
  {
    "path": "frontend/lang/english.lang",
    "content": "{ TSmashForm }\n{ ## QuickBar ## }\nmsMain_QuickButton_Hint=Quick patch|Apply Smash.All to loaded plugins and #13#10generate a smashed patch.#13#10\nmsMain_NewButton_Hint=Create new smashed patch|Make a new empty smashed patch.\nmsMain_BuildButton_Hint=Build patches|\nmsMain_ManageButton_Hint=Manage smash settings|Click here to manage smash settings.\nmsMain_OptionsButton_Hint=Options|Change the options that control how the #13#10program runs.#13#10\n{ #### DYNAMIC #### }\nmsMain_NoPatches=There aren't any patches to build or rebuild.\nmsMain_BuildPatches_Loader=You can't build patches until the background #13#10loader is done.#13#10\nmsMain_BuildAllPatches=Builds all patches that are ready to be built or #13#10rebuilt.#13#10\n{ ## Main Panel ## }\n{ ## Details Panel ## }\nmsMain_DetailsLabel_Caption=Details\nmsMain_DetailsCopyToClipboardItem_Caption=Copy to clipboard\n{ ## Plugins Tab ## }\nmsMain_PluginsTabSheet_Caption=Plugins\nmsMain_PluginsListView_Column0=Index\nmsMain_PluginsListView_Column1=Filename\nmsMain_PluginsListView_Column2=Setting\nmsMain_PluginsListView_Column3=Patch\n{ #### DYNAMIC #### }\nmsMain_PluginDetails=Plugin Details\nmsMain_Filename=Filename\nmsMain_Hash=Hash\nmsMain_FileSize=File Size\nmsMain_DateModified=Date Modified\nmsMain_NumRecords=Number of records\nmsMain_NumOverrides=Number of overrides\nmsMain_Author=Author\nmsMain_Description=Description\nmsMain_Masters=Masters\nmsMain_ClearTags=Are you sure you want to clear tags from these plugins?\n{ ## Plugins Popup Menu ## }\nmsMain_NewPatchItem_Caption=<New Patch>\nmsMain_OpenPluginLocationItem_Caption=Open plugin location\nmsMain_AddToPatchItem_Caption=Add to patch\nmsMain_ManageTagsItem_Caption=Manage Tags\nmsMain_SmashSettingItem_Caption=Smash setting\n{ ## Patches Tab ## }\nmsMain_PatchesTabSheet_Caption=Patches\nmsMain_PatchesListView_Column0=Index\nmsMain_PatchesListView_Column1=Name\nmsMain_PatchesListView_Column2=Filename\nmsMain_PatchesListView_Column3=Size\nmsMain_PatchesListView_Column4=Date built\n{ #### DYNAMIC #### }\nmsMain_PatchDetails=Patch Details\nmsMain_Status=Status\nmsMain_PatchName=Patch name\nmsMain_PluginCount=Plugin count\nmsMain_DateBuilt=Date built\nmsMain_Plugins=Plugins\nmsMain_Fails=Fails\nmsMain_TooManyFails=Too many fails to display.\nmsMain_DeletePatches=Are you sure you want to delete these patches?\n{ ## Patches Popup Menu ## }\nmsMain_ToggleRebuildItem_Caption=Toggle rebuild status\nmsMain_OpenInExplorerItem_Caption=Open in explorer\n{ ## Plugins Submenu ## }\nmsMain_MoveItem_Caption=Move\nmsMain_UpItem_Caption=Up\nmsMain_DownItem_Caption=Down\nmsMain_ToTopItem_Caption=To top\nmsMain_ToBottomItem_Caption=To bottom\n{ #### DYNAMIC #### }\nmsMain_BuildPatch=Build patch\nmsMain_RebuildPatch=Rebuild patch\nmsMain_BuildPatches=Build patches\nmsMain_RebuildPatches=Rebuilds patches\n{ ## Log Tab ## }\nmsMain_LogTabSheet_Caption=Log\n{ #### DYNAMIC #### }\nmsMain_AppDetails=Application Details\nmsMain_Application=Application\nmsMain_Author=Author\nmsMain_Version=Version\nmsMain_DateBuilt=Date built\nmsMain_GameMode=Game mode\nmsMain_Language=Language\nmsMain_TimesRun=Times run\nmsMain_PatchesBuilt=Patches built\nmsMain_PluginsSmashed=Plugins smashed\nmsMain_SettingsSubmitted=Smash settings submitted\nmsMain_RecsSubmitted=Recommendations submitted\nmsMain_Website=Website\nmsMain_ApiCredits=API Credits\nmsMain_xEditVersion=xEdit Version\nmsMain_xEditCredits=xEdit Credits\nmsMain_Testers=Testers\nmsMain_Translators=Translators\nmsMain_LoadException=Exception Loading Plugins\nmsMain_PluginsNotLoaded=Due to an exception, not all of your plugins #13#10have been loaded.  You can still use the program. #13#10See the log tab for more info.#13#10\nmsMain_Enable=Enable\nmsMain_Disable=Disable\nmsMain_AutoScroll=Autoscroll\n{ ## Log Popup Menu ## }\nmsMain_FilterGroupItem_Caption=Filter group\nmsMain_FilterLabelItem_Caption=Filter label\nmsMain_CopyToClipboardItem_Caption=Copy to clipboard\nmsMain_SaveAndClearItem_Caption=Save and clear\nmsMain_ToggleAutoScrollItem_Caption=Disable auto scroll\n \n{ TOptionsForm }\nmpOpt_btnCancel_Caption=Cancel\nmpOpt_btnOK_Caption=OK\n{ ## General Tab ## }\nmpOpt_GeneralTabSheet_Caption=General\nmpOpt_gbLanguage_Caption=Language\nmpOpt_lblLanguage_Caption=Current languge\nmpOpt_gbStyle_Caption=Style\nmpOpt_kbSimpleDictionary_Caption=Simple dictionary view\nmpOpt_kbSimplePlugins_Caption=Simple plugins list\n{ ## Patching Tab ## }\nmpOpt_PatchingTabSheet_Caption=Patching\nmpOpt_lblDestinationDirectory_Caption=Patch destination directory\nmpOpt_gbDebug_Caption=Debug\nmpOpt_gbOther_Caption=Other Options\n{ ## Advanced Tab ## }\nmpOpt_AdvancedTabSheet_Caption=Advanced\nmpOpt_lblCurrentProfile_Caption=Current profile\nmpOpt_gbLogging_Caption=Logging\nmpOpt_lblClientColor_Caption=Client\nmpOpt_lblGeneralColor_Caption=General\nmpOpt_lblLoadColor_Caption=Load\nmpOpt_lblPluginColor_Caption=Plugin\nmpOpt_lblErrorColor_Caption=Errors\nmpOpt_lblTemplate_Caption=Template\nmpOpt_lblSample_Caption=Sample\n \n{ TSettingsManager }\n{ ## Settings ## }\nmsSet_gbFiltering_Caption=Filtering options\nmsSet_lvSettings_Column0=Name\nmsSet_lvSettings_Column1=Records\nmsSet_btnSave_Caption=Save\nmsSet_btnDiscard_Caption=Discard\n{ ## Settings Popup Menu ## }\nmsSet_NewSettingItem_Caption=New setting\nmsSet_CloneSettingItem_Caption=Clone setting\nmsSet_CombineSettingsItem_Caption=Combine settings\nmsSet_EditSettingItem_Caption=Edit setting\nmsSet_DeleteSettingItem_Caption=Delete setting\n{ ## Details ## }\nmsSet_lblName_Caption=Name\nmsSet_lblColor_Caption=Color\nmsSet_lblDescription_Caption=Description\nmsSet_lblTree_Caption=Tree\n{ ## Tree Popup Menu ## }\nmsSet_ToggleNodesItem_Caption=Toggle nodes\nmsSet_IgnoreDeletionsItem_Caption=Toggle ignore deletions\nmsSet_SingleEntityItem_Caption=Toggle treat as single entity\nmsSet_PruneNodesItem_Caption=Prune nodes\nmsSet_PreserveDeletionsItem_Caption=Toggle preserve deletions\n\n{ TTagManager }\nmsTagM_Caption=Manage Tags - %s\n{ ## General ## }\nmsTagM_lblDescription_Caption=Description\nmsTagM_btnAdd_Caption=Add Tags\nmsTagM_btnRemove_Caption=Remove Tags\nmsTagM_btnClear_Caption=Clear Tags\nmsTagM_btnReset_Caption=Reset Tags\nmsTagM_btnApply_Caption=Apply\nmsTagM_btnCancel_Caption=Cancel\nmsTagM_kbCombine_Caption=Apply combined setting\n\n{ TTagHelper }\nmsTagH_btnCancel_Caption=Cancel\nmsTagH_btnOK_Caption=OK\n{ #### DYNAMIC #### }\nmsTagH_AddTags=Add Tags\nmsTagH_RemoveTags=Remove Tags\nmsTagH_PromptAdd=Check the tags you want to add\nmsTagH_PromptRemove=Check the tags you want to remove\n\n{ TProgressForm }\n{ #### DYNAMIC #### }\nmsProg_Closing=Closing\nmsProg_Smashing=Smashing Patches\nmsProg_DoneBuilding=Done smashing patches\nmsProg_BuildingTree=Building tree"
  },
  {
    "path": "frontend/msAlgorithm.pas",
    "content": "unit msAlgorithm;\n\ninterface\n\nuses\n  SysUtils, Classes,\n  // superobject\n  superobject,\n  // mte units\n  mteHelpers, mteTracker, mteBase,\n  // ms units\n  msCore, msConfiguration,\n  // xEdit components\n  wbInterface, wbImplementation;\n\n  procedure CopyLinkedElement(srcCont, dstCont: IwbContainerElementRef;\n    eLink: string; obj: ISuperObject; dstRec: IwbMainRecord);\n  function rcore(src, mst, dst: IwbElement; dstrec: IwbMainRecord;\n    obj: ISuperObject; bSingle, bDeletions, bOverride: boolean): boolean;\n\nimplementation\n\nvar\n  firstLink: string;\n  bLinkProcessed: boolean;\n\n{ \n  ElementByKey: \n  Gets an element from a container, @e, matching a specified @key.\n  If @bUseSortKey is true uses SortKey, else uses GetAllValues.\n}\nfunction ElementByKey(e: IwbElement; key: string; bUseSortKey: boolean): IwbElement;\nvar\n  i: Integer;\n  c: IwbContainerElementRef;\n  element: IwbElement;\n  eKey: string;\nbegin\n  if not Supports(e, IwbContainerElementRef, c) then \n    exit;\n  \n  // loop through children elements\n  for i := 0 to Pred(c.ElementCount) do begin\n    element := c.Elements[i];\n    // get sort key if bUseSortKey, else get values key\n    if bUseSortKey then\n      eKey := element.SortKey[false]\n    else\n      eKey := GetAllValues(element);\n    // if keys match result is current element\n    if eKey = key then begin\n      Result := element;\n      break;\n    end;\n  end;\nend;\n\n{\n  HandleElementLife:\n  Called by rcore.  Handles the creation/deletion of elements in the\n  destination patch record @dstRec.\n}\nfunction HandleElementLife(srcCont, dstCont, mstCont: IwbContainerElementRef;\n  dstRec: IwbMainRecord; obj: ISuperObject; bSingle, bDeletions, bOverride: boolean): boolean;\nvar\n  i: Integer;\n  element: IwbElement;\n  eObj: ISuperObject;\n  process, bInDestination, bInMaster: boolean;\n  eLink: String;\nbegin\n  Result := false;\n\n  // handle element creation\n  for i := 0 to Pred(srcCont.ElementCount) do begin\n    element := srcCont.Elements[i];\n\n    // if the element isn't in the destination record\n    // and wasn't in the master record, copy it to the destination\n    // if it isn't in the destination but is in the master it means\n    // that it was deleted and shouldn't be copied.\n    bInDestination := Assigned(dstCont.ElementByName[element.Name]);\n    bInMaster := Assigned(mstCont.ElementByName[element.Name]);\n    if (not bInDestination) and (bOverride or not bInMaster) then begin\n      Result := true;\n      if bSingle then \n        exit;\n\n      // skip according to setting\n      eObj := GetElementObj(obj, element.Name);\n      process := Assigned(eObj) and (eObj.I['p'] = 1);\n      if not process then begin\n        if settings.debugSkips then\n          Tracker.Write('      Skipping element creation at '+element.Path);\n        continue;\n      end;\n\n      // copy element\n      try\n        if settings.debugChanges then\n          Tracker.Write('      Created element at '+element.Path);\n        wbCopyElementToRecord(element, dstRec, false, true);\n\n        // if another element is linked to the element, copy it\n        eLink := eObj.S['lf'];\n        if (eLink <> '') then begin\n          firstLink := eLink;\n          bLinkProcessed := false;\n          CopyLinkedElement(srcCont, dstCont, eLink, obj, dstRec);\n        end;\n      except\n        on x: Exception do\n          Tracker.Write('        HandleElementLife: Failed to copy '+element.Path+', '+x.Message);\n      end;\n    end;\n  end;\n\n  // handle element deletion\n  if bDeletions then begin\n    for i := Pred(dstCont.ElementCount) downto 0 do begin\n      element := dstCont.Elements[i];\n      if Assigned(mstCont.ElementByName[element.Name]) and \n      not Assigned(srcCont.ElementByName[element.Name]) then begin\n        Result := true;\n        if bSingle then\n          exit;\n\n        // skip according to setting\n        eObj := GetElementObj(obj, element.Name);\n        process := Assigned(eObj) and (eObj.I['p'] = 1);\n        if not process then begin\n          if settings.debugSkips then\n            Tracker.Write('      Skipping element deletion at '+element.Path);\n          continue;\n        end;\n\n        // remove element\n        if settings.debugChanges then\n          Tracker.Write('      Deleted element at '+element.Path);\n        dstCont.RemoveElement(element);\n\n        // if another element is linked to the element, copy it\n        eLink := eObj.S['lf'];\n        if (eLink <> '') then begin\n          firstLink := eLink;\n          bLinkProcessed := false;\n          CopyLinkedElement(srcCont, dstCont, eLink, obj, dstRec);\n        end;\n      end;\n    end;\n  end;\nend;\n\n// GetMasterElement: Gets the first instance of an element (the master)\nfunction GetMasterElement(src, se: IwbElement; dstRec: IwbMainRecord): IwbElement;\nconst\n  debugGetMaster = false;\nvar\n  i: integer;\n  path, key: string;\n  mstRec, ovr: IwbMainRecord;\n  mst: IwbElement;\n  bSorted: boolean;\nbegin\n  Result := nil;\n  mstRec := dstRec.MasterOrSelf;\n  path := IndexedPath(src);\n  bSorted := IsSorted(src);\n  \n  // if sorted, use SortKey, else use GetAllValues\n  if bSorted then \n    key := se.SortKey[false]\n  else\n    key := GetAllValues(se);\n    \n  // debug message\n  if debugGetMaster then \n    Tracker.Write('      Called GetMasterElement at path '+path+' looking for key '+key);\n    \n  // loop from override 0 to the second to last override\n  // last override is in our patch, we don't want to process that one\n  for i := 0 to mstRec.OverrideCount - 2 do begin\n    ovr := mstRec.Overrides[i];\n    mst := ElementByIndexedPath(mstRec, path);\n    Result := ElementByKey(mst, key, bSorted);\n    \n    // break if we found a subrecord matching the sortkey\n    if Result <> nil then\n      break;\n  end;\nend;\n\n{\n  BuildKeyList:\n  Creates a list of element keys for elements in @container in a stringlist @sl.\n  Uses SortKey if @bUseSortKeys is true, else uses GetAllValues.\n}\nprocedure BuildKeyList(container: IwbContainerElementRef; var sl: TStringList;\n  bUseSortKeys: boolean);\nvar\n  i, n: integer;\n  childElement: IwbElement;\n  key, adjustedKey: string;\nbegin\n  // loop through children elements\n  for i := 0 to Pred(container.ElementCount) do begin\n    childElement := container.Elements[i];\n\n    // use sort if bUseSortKeys is true, else use GetAllValues\n    if bUseSortKeys then\n      key := childElement.SortKey[false]\n    else\n      key := GetAllValues(childElement);\n\n    // find a non-colliding key\n    n := 0;\n    adjustedKey := key;\n    while (sl.IndexOf(adjustedKey) > -1) do begin\n      Inc(n);\n      adjustedKey := key + IntToStr(n);\n    end;\n\n    // add adjusted key to stringlist\n    sl.Add(adjustedKey);\n  end;\nend;\n\n{\n  MergeArray:\n  Merges a sorted or unsorted arrray element by comparing element\n  keys.  Compares a source array @src, against a master array @mst and\n  a destination array @dst.  Returns true if any changes are made.\n  Exits before making any changes if @bSingle is true.  Preserves\n  deletions if @bDeletions if true.  Tracks @dstRec and @obj for\n  calling rcore on element containers in sorted arrays.\n}\nfunction MergeArray(src, mst, dst: IwbElement; dstrec: IwbMainRecord;\n  obj: ISuperObject; bSingle, bDeletions, bOverride: boolean): boolean;\nvar\n  i, s_ndx, m_ndx, d_ndx: integer;\n  se, de: IwbElement;\n  slMst, slDst, slSrc: TStringList;\n  srcCont, dstCont, mstCont, seCont: IwbContainerElementRef;\n  bSorted: boolean;\nbegin\n  Result := false;\n\n  // exit if input array elements can't be treated as a containers\n  if not Supports(src, IwbContainerElementRef, srcCont) then\n    exit;\n  if not Supports(mst, IwbContainerElementRef, mstCont) then\n    exit;\n  if not Supports(dst, IwbContainerElementRef, dstCont) then\n    exit;\n\n  // determine if we're handling a sorted array\n  bSorted := IsSorted(src);\n\n  // Build lists of element keys in each array for easy comparison\n  slSrc := TStringList.Create;\n  slMst := TStringList.Create;\n  slDst := TStringList.Create;\n  try\n    BuildKeyList(srcCont, slSrc, bSorted);\n    BuildKeyList(mstCont, slMst, bSorted);\n    BuildKeyList(dstCont, slDst, bSorted);\n\n    // ELEMENT DELETION:\n    // Remove elements that are in master and destination, but\n    // missing from source\n    if bDeletions then\n      for i := 0 to Pred(slMst.Count) do begin\n        s_ndx := slSrc.IndexOf(slMst[i]);\n\n        // element from master isn't in source\n        if (s_ndx = -1) then begin\n          Result := true;\n          // if we're in a treat as single, exit without removing anything\n          if bSingle then exit;\n          // if element is present in destination, remove it\n          d_ndx := slDst.IndexOf(slMst[i]);\n          if (d_ndx = -1) then continue;\n          if settings.debugArrays then\n            Tracker.Write('        > Removing element at '+dst.Path+' with key: '+slMst[i]);\n          dstCont.RemoveElement(d_ndx);\n          slDst.Delete(d_ndx);\n        end;\n      end;\n\n    // ELEMENT ADDITION:\n    // Copy array elements in source that aren't in master\n    // or destination\n    for i := 0 to Pred(slSrc.Count) do begin\n      d_ndx := slDst.IndexOf(slSrc[i]);\n      m_ndx := slMst.IndexOf(slSrc[i]);\n      se := srcCont.Elements[i];\n\n\n      if (d_ndx = -1) and ((m_ndx = -1) or bOverride) then begin\n        Result := true;\n        // if we're in a treat as single, exit without adding anything\n        if bSingle then exit;\n        // add element to destination\n        if settings.debugArrays then\n          Tracker.Write('        > Adding element at '+dst.Path+' with key: '+slSrc[i]);\n        de := dstCont.Assign(dstCont.ElementCount, se, false);\n        if bSorted then\n          slDst.Insert(dstCont.IndexOf(de), slSrc[i])\n        else\n          slDst.Add(slSrc[i]);\n      end\n\n      // Special handling for sorted arrays\n      // Traverses elements that may have been modified without their sortkey changing\n      else if bSorted and (d_ndx > -1) and Supports(se, IwbContainerElementRef, seCont)\n      and (seCont.ElementCount > 0) then begin\n        if settings.debugArrays then begin\n          Tracker.Write('        > Traversing element '+se.Path+' with key: '+slSrc[i]);\n          Tracker.Write('        > Source Element: '+GetAllValues(se));\n          Tracker.Write('        > Destination Element: '+GetAllValues(dstCont.Elements[d_ndx]));\n        end;\n        // traverse element\n        try\n          Result := rcore(se, GetMasterElement(src, se, dstrec), dstCont.Elements[d_ndx],\n            dstrec, GetElementObj(obj, se.Name), bSingle, bDeletions, bOverride);\n          if Result and bSingle then\n            exit;\n        except on x : Exception do begin\n            Tracker.Write('      rcore: Exception at '+se.Path+': '+x.Message);\n          end;\n        end;\n      end;\n    end;\n  finally\n    // free lists\n    slMst.Free;\n    slSrc.Free;\n    slDst.Free;\n  end;\nend;\n\n{ \n  CopyElementValue:\n  Copies the edit value of @se to @de.\n}\nprocedure CopyElementValue(se, me, de: IwbElement);\nbegin\n  if not de.IsEditable then begin\n    if settings.debugChanges then begin\n      Tracker.Write('      Unable to copy element value on '+se.path);\n      Tracker.Write('      Element is not editable');\n    end;\n    exit;\n  end;\n\n  if Assigned(me) and settings.debugChanges then begin\n    if (not settings.debugTraversal) then\n      Tracker.Write('      '+se.Path);\n    Tracker.Write('      > Found differing values: '+se.EditValue+', '+me.EditValue);\n  end;\n\n  // try to copy element value to destination element from source element\n  try\n    de.EditValue := se.EditValue;\n  except on x : Exception do\n    Tracker.Write('      CopyElementValue: Exception '+x.Message);\n  end;\nend;\n\n{\n  CopyLinkedElement:\n  Copies the linked element named eLink, and then copies any elements it is\n  linked to.\n}\nprocedure CopyLinkedElement(srcCont, dstCont: IwbContainerElementRef;\n  eLink: string; obj: ISuperObject; dstRec: IwbMainRecord);\nvar\n  cObj: ISuperObject;\n  le, de: IwbElement;\n  cLink: string;\nbegin\n  // exit if we reached the first link in a chain\n  if (eLink = firstLink) then begin\n    if bLinkProcessed then\n      exit;\n    bLinkProcessed := true;\n  end;\n\n  // else try to copy the linked element\n  try\n    cObj := GetElementObj(obj, eLink);\n    le := srcCont.ElementByName[eLink];\n    de := dstCont.ElementByName[eLink];\n    if Assigned(le) then begin\n      if settings.debugLinks then\n        Tracker.Write('      Copying linked element '+le.Path);\n      if Assigned(de) then\n        de.Assign(Low(Integer), le, false)\n      else\n        dstCont.AddIfMissing(le, true, true, '', '', '');\n      // follow chain\n      cLink := cObj.S['lf'];\n      if cLink <> '' then\n        CopyLinkedElement(srcCont, dstCont, cLink, obj, dstRec);\n    end;\n  except\n    on x: Exception do\n      Tracker.Write('        CopyLinkedElement: Failed to copy '+eLink+', '+x.Message);\n  end;\nend;\n\n{\n  HandleElement:\n  Wrapper function around the logic for recursing into child \n  elements (rcore), handling an array, or copying element values.\n}\nfunction HandleElement(se, me, de: IwbElement; dstRec: IwbMainRecord;\n  obj: ISuperObject; bSingle, bDeletions, bOverride: boolean): boolean;\nvar\n  srcType, dstType: TSmashType;\n  container: IwbContainerElementRef;\n  bCanAdd, bIsContainer: boolean;\n  seVal, meVal: string;\nbegin\n  Result := false;\n\n  // deftype and elementtype\n  srcType := GetSmashType(se);\n  dstType := GetSmashType(de);\n\n  // other type information\n  bIsContainer := Supports(se, IwbContainerElementRef, container)\n    and (container.ElementCount > 0);\n  bCanAdd := se.CanAssign(High(Integer), nil, True)\n    and not (esNotSuitableToAddTo in se.ElementStates);\n\n  // exit if srcType <> dstType, returning true\n  if srcType <> dstType then begin\n    if settings.debugSkips then begin\n      Tracker.Write('      Source and destination types don''t match');\n      Tracker.Write('      '+stToString(srcType)+' != '+stToString(dstType));\n      Tracker.Write('      Skipping '+se.Path);\n    end;\n    Result := True;\n    exit;\n  end;\n\n  // exit if master element not assigned and not array\n  if not Assigned(me) then begin\n    if bCanAdd and (srcType in stArrays) then\n      me := de\n    else begin\n      if settings.debugSkips then begin\n        Tracker.Write('      Master element not found!');\n        Tracker.Write('      Skipping '+se.Path);\n      end;\n      exit;\n    end;\n  end;\n\n  // debug messages\n  if settings.debugTraversal then\n    Tracker.Write('      '+se.Path);\n  if settings.debugTypes then begin\n    Tracker.Write('      bCanAdd: '+BoolToStr(bCanAdd, true));\n    Tracker.Write('      SmashType: '+stToString(srcType));\n  end;\n\n  // merge array\n  if bCanAdd and (srcType in stArrays) then begin\n    if settings.debugTraversal then\n      Tracker.Write('         Merging array');\n    try\n      Result := MergeArray(se, me, de, dstrec, obj, bSingle, bDeletions, bOverride);\n    except on x : Exception do\n      Tracker.Write('        MergeArray: Exception at '+se.Path+': '+x.Message);\n    end;\n  end\n  // else recurse deeper\n  else if bIsContainer and (srcType <> stInteger) then begin\n    if settings.debugTraversal then\n      Tracker.Write('        Recursing deeper');\n    try\n      Result := rcore(se, me, de, dstrec, obj, bSingle, bDeletions, bOverride);\n    except on x : Exception do\n      Tracker.Write('      rcore: Exception at '+se.Path+': '+x.Message);\n    end;\n  end\n  // else copy element value\n  else if (srcType in stValues) then begin\n    seVal := se.EditValue;\n    meVal := me.EditValue;\n    if (seVal <> meVal) then begin\n      if not bSingle then\n        CopyElementValue(se, me, de);\n      Result := true;\n    end\n    else if settings.debugSkips then begin\n      Tracker.Write(Format('         Skipping, \"%s\" = \"%s\"', [seVal, meVal]));\n    end;\n  end\n  else if settings.debugSkips then begin\n    Tracker.Write(Format('         Skipping, %s is not a value type',\n      [stToString(srcType)]));\n  end;\nend;\n\n{\n  rcore:\n  Recursively copy overridden elements.  Recursively traverses elements,\n  comparing between a source element (from an override record) @src, a \n  master element @mst, and a destination element @dst.  Tracks the \n  destination patch record for element copying through @dstRec.  Uses a \n  json tree @obj to determine user settings for traversal.  Uses @bSingle \n  to determine when we're in a \"single entity\" as specified by the user, \n  and @bDeletions to determine when it's ok to delete removed elements \n  from the destination patch record.\n  \n  - Uses HandleElementLife to resolve element creation/deletion.\n  - Uses HandleElement to handle arrays, recurse deeper, or copy element\n    values\n}\nfunction rcore(src, mst, dst: IwbElement; dstRec: IwbMainRecord;\n  obj: ISuperObject; bSingle, bDeletions, bOverride: boolean): boolean;\nvar\n  i: integer;\n  srcCont, dstCont, mstCont: IwbContainerElementRef;\n  se, me, de: IwbElement;\n  process, eSingle, eDeletions, eOverride: boolean;\n  eObj: ISuperObject;\n  eLink: string;\nbegin\n  Result := false;\n\n  // prepare containers\n  if not Supports(src, IwbContainerElementRef, srcCont) then begin\n    if settings.debugSkips then begin\n      Tracker.Write('      Source element not a container.');\n      Tracker.Write('      Skipping '+src.Path);\n    end;\n    exit;\n  end;\n  if not Supports(dst, IwbContainerElementRef, dstCont) then begin\n    if settings.debugSkips then begin\n      Tracker.Write('      Destination element not a container.');\n      Tracker.Write('      Skipping '+src.Path);\n    end;\n    exit;\n  end;\n  if not Supports(mst, IwbContainerElementRef, mstCont) then begin\n    if settings.debugSkips then begin\n      Tracker.Write('      Master element not a container.');\n      Tracker.Write('      Skipping '+src.Path);\n    end;\n    exit;\n  end;\n\n  // copy elements from source to destination if missing AND\n  // delete elements missing from source if found in master and destination\n  Result := HandleElementLife(srcCont, dstCont, mstCont, dstRec, obj, bSingle, bDeletions, bOverride);\n  if bSingle and Result then begin\n    if settings.debugSingle then\n      Tracker.Write('      Single entity change found at '+src.Path);\n    exit;\n  end;\n\n  // loop through subelements\n  for i := 0 to Pred(srcCont.ElementCount) do begin\n    // assign source, destination, master elements\n    se := srcCont.Elements[i];\n    de := dstCont.ElementByName[se.Name];\n    me := mstCont.ElementByName[se.Name];\n\n    // skip if destination element not assigned\n    if not Assigned(de) then begin\n      if settings.debugSkips then begin\n        Tracker.Write('      Destination element not found!');\n        Tracker.Write('      Skipping '+se.Path);\n      end;\n      continue;\n    end;\n\n    // skip according to setting\n    eObj := GetElementObj(obj, se.Name);\n    process := Assigned(eObj) and (eObj.I['p'] = 1);\n    if not process then begin\n      if settings.debugSkips then\n        Tracker.Write('      Skipping '+se.Path);\n      continue;\n    end;\n\n    // set element treat as single entity / ignore deletions booleans\n    eSingle := bSingle or (eObj.I['s'] = 1);\n    eDeletions := bDeletions or (eObj.I['d'] = 1);\n    eOverride := bOverride or (eObj.I['o'] = 1);\n\n    // handle element\n    Result := HandleElement(se, me, de, dstRec, eObj, eSingle, eDeletions, eOverride);\n\n    // if we're in a single entity and an element is changed, break\n    // we don't need to handle anything anymore\n    if bSingle and Result then begin\n      if settings.debugSingle then\n        Tracker.Write('      Single entity change found at '+se.Path);\n      break;\n    end;\n\n    // if the element we're processing has the single entity flag set\n    // and we're not currently in a single entity, copy entire element\n    if eSingle and (not bSingle) and Result then try\n      if settings.debugSingle then\n        Tracker.Write(Format('      Copying single entity %s', [se.path]));\n      de.Assign(Low(Integer), se, false);\n    except\n      on x: Exception do\n        Tracker.Write('        rcore: Failed to copy '+se.Path+', '+x.Message);\n    end;\n\n    // if another element is linked to the element being processed\n    // and the element being processed has been modified, copy the linked\n    // element\n    eLink := eObj.S['lf'];\n    if Result and (eLink <> '') then begin\n      firstLink := eLink;\n      bLinkProcessed := false;\n      CopyLinkedElement(srcCont, dstCont, eLink, obj, dstRec);\n    end;\n  end;\nend;\n\nend.\n"
  },
  {
    "path": "frontend/msChoicePanel.pas",
    "content": "unit msChoicePanel;\n\ninterface\n\nuses\n  SysUtils, Classes, Controls, Dialogs, Graphics, Buttons, StdCtrls, ExtCtrls,\n  ImgList, Types,\n  // mte components\n  mteHelpers,\n  // mp components\n  msCore;\n\ntype\n  TSenderCallback = procedure(Sender: TObject) of object;\n  TChoicePanel = class(TPanel)\n  public\n    Selected: boolean;\n    constructor Create(AOwner: TComponent); override;\n    destructor Destroy; override;\n    procedure ToggleSelect(Sender: TObject);\n    procedure SettingChanged(Sender: TObject);\n    procedure Deselect;\n    procedure Select;\n    procedure SetTop(top: Integer);\n    procedure SetWidth(width: Integer);\n    function GetSetting: TSmashSetting;\n    function GetLabel: string;\n    procedure SetSelectCallback(callback: TNotifyEvent);\n    procedure SetLabel(sig: string);\n    procedure AddChoice(choice: TSmashSetting);\n  private\n    lstChoices: TList;\n    ColorUnselected: Integer;\n    ColorSelected: Integer;\n    lblSig: TLabel;\n    cbChoices: TComboBox;\n    SelectCallback: TNotifyEvent;\n  end;\n\nimplementation\n\n\n{******************************************************************************}\n{ TChoicePanel\n  A GUI component for interacting with a profile.\n}\n{******************************************************************************}\n\nconstructor TChoicePanel.Create(AOwner: TComponent);\nbegin\n  // set up panel\n  inherited Create(AOwner);\n  Parent := AOwner as TWinControl;\n  Width := (AOwner as TWinControl).ClientWidth;\n  Height := 36;\n  Left := 0;\n  Top := 0;\n  ParentBackground := false;\n  ParentColor := false;\n  ParentDoubleBuffered := false;\n  Cursor := crHandPoint;\n  Anchors := [akLeft, akTop, akRight];\n  Visible := true;\n\n  // set local variables\n  Selected := false;\n  ColorUnselected := Color;\n  ColorSelected := $f0ece4;\n  lstChoices := TList.Create;\n\n  // create components\n  lblSig := TLabel.Create(self);\n  cbChoices := TComboBox.Create(self);\n\n  // set up lblSig\n  lblSig.Parent := self;\n  lblSig.Top := 10;\n  lblSig.Left := 16;\n  lblSig.Caption := 'SIGN';\n  lblSig.Cursor := crHandPoint;\n  lblSig.Align := alCustom;\n  lblSig.Anchors := [akLeft, akTop];\n\n  // set up cbGame\n  cbChoices.Parent := self;\n  cbChoices.Top := 8;\n  cbChoices.Left := 75;\n  cbChoices.Width := Width - cbChoices.Left - 6;\n  cbChoices.Style := csDropDownList;\n  cbChoices.Items.Text := '';\n  cbChoices.Items.Add('Patch');\n  cbChoices.ItemIndex := 0;\n  cbChoices.Align := alCustom;\n  cbChoices.Anchors := [akLeft, akTop, akRight];\n\n  // set event handlers\n  self.OnClick := ToggleSelect;\n  lblSig.OnClick := ToggleSelect;\n  cbChoices.OnChange := SettingChanged;\nend;\n\ndestructor TChoicePanel.Destroy;\nbegin\n  lblSig.Free;\n  cbChoices.Free;\n  lstChoices.Free;\n  inherited;\nend;\n\n{ EVENT HANDLING }\nprocedure TChoicePanel.SettingChanged(Sender: TObject);\nbegin\n  if Assigned(SelectCallback) then SelectCallback(self);\nend;\n\nprocedure TChoicePanel.ToggleSelect(Sender: TObject);\nbegin\n  if Cursor = crHandPoint then begin\n    if Selected then Deselect else Select;\n    if Assigned(SelectCallback) then SelectCallback(self);\n  end;\nend;\n\nprocedure TChoicePanel.Select;\nbegin\n  Selected := true;\n  Color := ColorSelected;\n  Repaint;\nend;\n\nprocedure TChoicePanel.Deselect;\nbegin\n  Selected := false;\n  Color := ColorUnselected;\n  Repaint;\nend;\n\nprocedure TChoicePanel.SetTop(top: Integer);\nbegin\n  self.top := top;\nend;\n\nprocedure TChoicePanel.SetWidth(width: Integer);\nbegin\n  self.width := width;\nend;\n\nfunction TChoicePanel.GetSetting: TSmashSetting;\nbegin\n  Result := nil;\n  if cbChoices.ItemIndex = 0 then\n    exit;\n  Result := TSmashSetting(lstChoices[cbChoices.ItemIndex - 1]);\nend;\n\nfunction TChoicePanel.GetLabel: string;\nbegin\n  Result := lblSig.Caption;\nend;\n\nprocedure TChoicePanel.SetSelectCallback(callback: TNotifyEvent);\nbegin\n  SelectCallback := callback;\nend;\n\nprocedure TChoicePanel.SetLabel(sig: string);\nbegin\n  lblSig.Caption := sig;\nend;\n\nprocedure TChoicePanel.AddChoice(choice: TSmashSetting);\nbegin\n  lstChoices.Add(choice);\n  cbChoices.Items.Add(choice.name);\n  cbChoices.ItemIndex := 0;\nend;\n\nend.\n"
  },
  {
    "path": "frontend/msConfiguration.pas",
    "content": "unit msConfiguration;\n\ninterface\n\nuses\n  Classes, wbInterface,\n  // mte units\n  mteHelpers, RttiIni;\n\ntype\n  TGameMode = Record\n    longName: string;\n    gameName: string;\n    gameMode: TwbGameMode;\n    regName: string;\n    appName: string;\n    exeName: string;\n    appIDs: string;\n    bsaOptMode: string;\n  end;\n  TSettings = class(TObject)\n  public\n    [IniSection('General')]\n    profile: string;\n    newProfile: boolean;\n    gameMode: integer;\n    gamePath: string;\n    language: string;\n    simpleDictionaryView: boolean;\n    simplePluginsView: boolean;\n    simpleSplash: boolean;\n    [IniSection('Advanced')]\n    generalMessageColor: Int64;\n    clientMessageColor: Int64;\n    loadMessageColor: Int64;\n    patchMessageColor: Int64;\n    pluginMessageColor: Int64;\n    errorMessageColor: Int64;\n    logMessageTemplate: string;\n    preserveTempPath: boolean;\n    allowTagging: boolean;\n    smashSound: boolean;\n    [IniSection('Patching')]\n    patchDirectory: string;\n    debugPatchStatus: boolean;\n    debugMasters: boolean;\n    debugArrays: boolean;\n    debugSkips: boolean;\n    debugTraversal: boolean;\n    debugTypes: boolean;\n    debugChanges: boolean;\n    debugSingle: boolean;\n    debugLinks: boolean;\n    buildRefs: boolean;\n    preserveITPOs: boolean;\n    constructor Create; virtual;\n  end;\n  TStatistics = class(TObject)\n  public\n    [IniSection('Statistics')]\n    timesRun: integer;\n    patchesBuilt: integer;\n    pluginsPatched: integer;\n    settingsSubmitted: integer;\n    recsSubmitted: integer;\n    constructor Create; virtual;\n  end;\n  TProfile = class(TObject)\n  public\n    name: string;\n    gameMode: Integer;\n    gamePath: string;\n    constructor Create(name: string); virtual;\n    procedure Clone(p: TProfile);\n    procedure Delete;\n    procedure Rename(name: string);\n  end;\n  TProgramStatus = class(TObject)\n  public\n    bInitException, bLoadException, bChangeProfile, bForceTerminate,\n    bLoaderDone, bInstallUpdate, bUpdatePatchStatus, bClose: boolean;\n    GameMode: TGameMode;\n    Version: String;\n    constructor Create; virtual;\n  end;\n\n  procedure DeleteTempPath;\n  procedure LoadLanguage;\n  function GetLanguageString(name: string): string;\n  procedure SaveProfile(var p: TProfile);\n  procedure LoadSettings; overload;\n  function LoadSettings(path: string): TSettings; overload;\n  procedure SaveSettings; overload;\n  procedure SaveSettings(var s: TSettings; path: string); overload;\n  procedure LoadStatistics;\n  procedure SaveStatistics;\n\nvar\n  settings: TSettings;\n  CurrentProfile: TProfile;\n  statistics, sessionStatistics: TStatistics;\n  language, PathList: TStringList;\n  ProgramStatus: TProgramStatus;\n\nconst\n  // IMPORTANT CONSTANTS\n  bTranslationDump = false;\n\n  // GAME MODES\n  GameArray: array[1..6] of TGameMode = (\n    ( longName: 'Skyrim'; gameName: 'Skyrim'; gameMode: gmTES5;\n      regName: 'Skyrim'; appName: 'TES5'; exeName: 'TESV.exe'; appIDs: '72850';\n      bsaOptMode: 'sk'; ),\n    ( longName: 'Oblivion'; gameName: 'Oblivion'; gameMode: gmTES4;\n      regName: 'Oblivion'; appName: 'TES4'; exeName: 'Oblivion.exe';\n      appIDs: '22330,900883'; bsaOptMode: 'ob'; ),\n    ( longName: 'Fallout New Vegas'; gameName: 'FalloutNV'; gameMode: gmFNV;\n      regName: 'FalloutNV'; appName: 'FNV'; exeName: 'FalloutNV.exe';\n      appIDs: '22380,2028016'; bsaOptMode: 'fo'; ),\n    ( longName: 'Fallout 3'; gameName: 'Fallout3'; gameMode: gmFO3;\n      regName: 'Fallout3'; appName: 'FO3'; exeName: 'Fallout3.exe';\n      appIDs: '22300,22370'; bsaOptMode: 'fo'; ),\n    ( longName: 'Fallout 4'; gameName: 'Fallout4'; gameMode: gmFO4;\n      regName: 'Fallout4'; appName: 'FO4'; exeName: 'Fallout4.exe';\n      appIDs: '377160'; bsaOptMode: ''; ),\n    ( longName: 'Skyrim Special Edition'; gameName: 'Skyrim'; gameMode: gmSSE;\n      regName: 'Skyrim Special Edition'; appName: 'SSE';\n      exeName: 'SkyrimSE.exe'; appIDs: '489830'; bsaOptMode: ''; )\n  );\n\nimplementation\n\nuses\n  Graphics, SysUtils, Dialogs, ShellAPI, Windows, Registry;\n\n{ TSettings }\nconstructor TSettings.Create;\nbegin\n  // default settings\n  newProfile := true;\n  language := 'English';\n  simpleDictionaryView := false;\n  simplePluginsView := false;\n  patchDirectory := wbDataPath;\n  generalMessageColor := clGreen;\n  loadMessageColor := clPurple;\n  clientMessageColor := clBlue;\n  patchMessageColor := $000080FF;\n  pluginMessageColor := $00484848;\n  errorMessageColor := clRed;\n  logMessageTemplate := '[{{AppTime}}] ({{Group}}) {{Label}}: {{Text}}';\nend;\n\n{ TStatistics constructor }\nconstructor TStatistics.Create;\nbegin\n  timesRun := 0;\n  patchesBuilt := 0;\n  pluginsPatched := 0;\n  settingsSubmitted := 0;\n  recsSubmitted := 0;\nend;\n\n{ TProfile }\nconstructor TProfile.Create(name: string);\nbegin\n  self.name := name;\nend;\n\nprocedure TProfile.Clone(p: TProfile);\nbegin\n  name := p.name;\n  gameMode := p.gameMode;\n  gamePath := p.gamePath;\nend;\n\nprocedure TProfile.Delete;\nvar\n  path: string;\nbegin\n  path := PathList.Values['ProgramPath'] + 'profiles\\' + name;\n  if DirectoryExists(path) then\n    DeleteToRecycleBin(path, false);\nend;\n\nprocedure TProfile.Rename(name: string);\nvar\n  oldProfilePath, newProfilePath: string;\nbegin\n  // rename old profile folder if necessary\n  oldProfilePath := PathList.Values['ProgramPath'] + 'profiles\\' + self.name;\n  newProfilePath := PathList.Values['ProgramPath'] + 'profiles\\' + name;\n  if DirectoryExists(oldProfilePath) then\n    RenameFile(oldProfilePath, newProfilePath);\n\n  // then change name in the object\n  self.name := name;\nend;\n\n{ TProgramStatus }\nconstructor TProgramStatus.Create;\nbegin\n  bInitException  := false;\n  bLoadException := false;\n  bChangeProfile := false;\n  bForceTerminate := false;\n  bUpdatePatchStatus := false;\n  bClose := false;\n  Version := GetVersionMem;\nend;\n\n{ CONFIGURATION HELPERS }\n\nprocedure DeleteTempPath;\nbegin\n  DeleteDirectory(PathList.Values['TempPath']);\nend;\n\nprocedure LoadLanguage;\nconst\n  langFile = 'http://raw.githubusercontent.com/matortheeternal/smash/master/frontend/lang/english.lang';\n  directions = 'Your english.lang file is missing.  Please download it from GitHub.  ' +\n    'After you click OK, a webpage with the file will be opened.  Right-click the ' +\n    'page and choose \"Save page as\", then save it as english.lang in the \"lang\\\" ' +\n    'folder where you have MatorSmash.exe installed.';\n  accessMessage = 'It looks like Smash doesn''t have permission to read files ' +\n    'from disk.  Try running the program as administrator or disabling your antivirus.';\nvar\n  filename: string;\nbegin\n  filename := Format('lang\\%s.lang', [settings.language]);\n  language := TStringList.Create;\n  if (not FileExists(filename)) then begin\n    if settings.language <> 'english' then begin\n      settings.language := 'english';\n      LoadLanguage;\n    end\n    else if not FileExists('MatorSmash.exe') then\n      MessageDlg(accessMessage, mtConfirmation, [mbOk], 0)\n    else begin\n      MessageDlg(directions, mtConfirmation, [mbOk], 0);\n      ForceDirectories(PathList.Values['ProgramPath'] + 'lang\\');\n      ShellExecute(0, 'open', PChar(langFile), '', '', SW_SHOWNORMAL);\n    end;\n  end\n  else\n    language.LoadFromFile(filename);\nend;\n\nfunction GetLanguageString(name: string): string;\nbegin\n  if language.Values[name] <> '' then\n    Result := StringReplace(language.Values[name], '#13#10', #13#10, [rfReplaceAll])\n  else\n    Result := name;\nend;\n\nprocedure SaveProfile(var p: TProfile);\nvar\n  path: string;\n  pSettings: TSettings;\nbegin\n  // get profile path\n  path := PathList.Values['ProgramPath'] + 'profiles\\' + p.name + '\\settings.ini';\n  ForceDirectories(ExtractFilePath(path));\n\n  // load settings if they exist, else create them\n  if FileExists(path) then\n    pSettings := LoadSettings(path)\n  else begin\n    pSettings := TSettings.Create;\n    pSettings.patchDirectory := p.gamePath + 'Data\\';\n  end;\n\n  // save profile details to settings\n  pSettings.profile := p.name;\n  pSettings.gameMode := p.gameMode;\n  pSettings.gamePath := p.gamePath;\n  SaveSettings(pSettings, path);\nend;\n\nprocedure SaveSettings;\nbegin\n  // user saving settings from options form\n  settings.newProfile := false;\n  TRttiIni.Save(PathList.Values['ProfilePath'] + 'settings.ini', settings);\nend;\n\nprocedure SaveSettings(var s: TSettings; path: string);\nbegin\n  TRttiIni.Save(path, s);\nend;\n\nprocedure LoadSettings;\nbegin\n  settings := TSettings.Create;\n  TRttiIni.Load(PathList.Values['ProfilePath'] + 'settings.ini', settings);\nend;\n\nfunction LoadSettings(path: string): TSettings;\nbegin\n  Result := TSettings.Create;\n  TRttiIni.Load(path, Result);\nend;\n\nprocedure SaveStatistics;\nbegin\n  // move session statistics to general statistics\n  Inc(statistics.timesRun, sessionStatistics.timesRun);\n  Inc(statistics.patchesBuilt, sessionStatistics.patchesBuilt);\n  Inc(statistics.pluginsPatched, sessionStatistics.pluginsPatched);\n  Inc(statistics.settingsSubmitted, sessionStatistics.settingsSubmitted);\n  Inc(statistics.recsSubmitted, sessionStatistics.recsSubmitted);\n  // zero out session statistics\n  sessionStatistics.timesRun := 0;\n  sessionStatistics.patchesBuilt := 0;\n  sessionStatistics.settingsSubmitted := 0;\n  sessionStatistics.recsSubmitted := 0;\n  // save to file\n  TRttiIni.Save('statistics.ini', statistics);\nend;\n\nprocedure LoadStatistics;\nbegin\n  statistics := TStatistics.Create;\n  sessionStatistics := TStatistics.Create;\n  TRttiIni.Load('statistics.ini', statistics);\nend;\n\ninitialization\nbegin\n  ProgramStatus := TProgramStatus.Create;\n  PathList := TStringList.Create;\nend;\n\nfinalization\nbegin\n  ProgramStatus.Free;\n  PathList.Free;\nend;\n\nend.\n"
  },
  {
    "path": "frontend/msConflict.pas",
    "content": "unit msConflict;\n\ninterface\n\nuses\n  Classes, SysUtils,\n  // mte units\n  mteBase,\n  // ms units\n  msCore,\n  // xEdit units\n  wbInterface, wbImplementation, wbHelpers;\n\ntype\n  // States used in InitNode to indicate states a node shall initially have.\n  TVirtualNodeInitState = (\n    ivsDisabled,\n    ivsExpanded,\n    ivsHasChildren,\n    ivsMultiline,\n    ivsSelected,\n    ivsFiltered,\n    ivsReInit{>>>},\n    ivsHidden{<<<}\n  );\n  TVirtualNodeInitStates = set of TVirtualNodeInitState;\n\n  // navnode flags\n  TNavNodeFlag = (\n    nnfInjected,\n    nnfNotReachable,\n    nnfReferencesInjected\n  );\n\n  TNavNodeFlags = set of TNavNodeFlag;\n\n  // navnode data\n  PNavNodeData = ^TNavNodeData;\n  TNavNodeData = record\n    Element      : IwbElement;\n    Container    : IwbContainer;\n    ConflictAll  : TConflictAll;\n    ConflictThis : TConflictThis;\n    Flags        : TNavNodeFlags;\n  end;\n\n  // node flags\n  TViewNodeFlag = (\n    vnfDontShow,\n    vnfIgnore\n  );\n  TViewNodeFlags = set of TViewNodeFlag;\n\n  // node data\n  PViewNodeData = ^TViewNodeData;\n  TViewNodeData = record\n    Element: IwbElement;\n    Container: IwbContainerElementRef;\n    ConflictAll: TConflictAll;\n    ConflictThis: TConflictThis;\n    ViewNodeFlags: TViewNodeFlags;\n  end;\n\n  // collections of node datas\n  TViewNodeDatas = array[Word] of TViewNodeData;\n  PViewNodeDatas = ^TViewNodeDatas;\n\n  TDynViewNodeDatas = array of TViewNodeData;\n\n  // exposed methods\n  procedure ConflictLevelForMainRecord(const aMainRecord: IwbMainRecord;\n    out aConflictAll: TConflictAll; out aConflictThis: TConflictThis);\n  function ConflictLevelForChildNodeDatas(const aNodeDatas: TDynViewNodeDatas;\n    aSiblingCompare, aInjected: Boolean): TConflictAll;\n  function ConflictLevelForNodeDatas(const aNodeDatas: PViewNodeDatas;\n    aNodeCount: Integer; aSiblingCompare, aInjected: Boolean): TConflictAll;\n  function ConflictAllForElements(e1, e2: IwbElement; aSiblingCompare,\n    aInjected: Boolean): TConflictAll;\n  function ConflictThisForMainRecord(aMainRecord: IwbMainRecord): TConflictThis;\n  function ConflictAllForMainRecord(aMainRecord: IwbMainRecord): TConflictAll;\n  function IsITPO(rec: IwbMainRecord): Boolean;\n  function IsITM(rec: IwbMainRecord): Boolean;\n\nimplementation\n\nprocedure AppendToNodeDatas(var NodeDatas: TDynViewNodeDatas; e: IwbElement);\nvar\n  Container: IwbContainerElementRef;\nbegin\n  SetLength(NodeDatas, Succ(Length(NodeDatas)));\n  NodeDatas[Pred(Length(NodeDatas))].Element := e;\n  if Supports(e, IwbContainerElementRef, Container) and (Container.ElementCount > 0) then\n    NodeDatas[Pred(Length(NodeDatas))].Container := Container;\nend;\n\nfunction ConflictAllForElements(e1, e2: IwbElement; aSiblingCompare,\n  aInjected: Boolean): TConflictAll;\nvar\n  NodeDatas: TDynViewNodeDatas;\nbegin\n  // prepare node datas\n  AppendToNodeDatas(NodeDatas, e1);\n  AppendToNodeDatas(NodeDatas, e2);\n\n  // compute the conflict level\n  Result := caUnknown;\n  if Length(NodeDatas) > 0 then\n    if Assigned(NodeDatas[0].Container) then\n      Result := ConflictLevelForChildNodeDatas(NodeDatas, aSiblingCompare, aInjected)\n    else\n      Result := ConflictLevelForNodeDatas(@NodeDatas[0], Length(NodeDatas), aSiblingCompare, aInjected);\nend;\n\nfunction NodeDatasForMainRecord(const aMainRecord: IwbMainRecord): TDynViewNodeDatas;\nvar\n  Master        : IwbMainRecord;\n  Rec           : IwbMainRecord;\n  i, j          : Integer;\n  Records       : TStringList;\n  AnyHidden     : Boolean;\n  IsNonOverride : Boolean;\n  EditorID      : string;\n  FormID        : Cardinal;\n  LoadOrder     : Integer;\n  Group         : IwbGroupRecord;\n  Signature     : TwbSignature;\n  plugin        : TPlugin;\n  aFile         : IwbFile;\nbegin\n  Assert(wbLoaderDone);\n  IsNonOverride := False;\n  AnyHidden := False;\n\n  if aMainRecord.Signature = 'GMST' then begin\n    IsNonOverride := True;\n    EditorID := aMainRecord.EditorID;\n    SetLength(Result, PluginsList.Count);\n    Master := nil;\n    for i := 0 to Pred(PluginsList.Count) do begin\n      plugin := TPlugin(PluginsList[i]);\n      aFile := plugin._File;\n      Group := aFile.GroupBySignature['GMST'];\n      if Assigned(Group) then begin\n        Rec := Group.MainRecordByEditorID[EditorID];\n        if Assigned(Rec) then begin\n          if not Assigned(Master) then\n            Master := Rec;\n          Result[i].Element := Rec;\n        end;\n      end;\n    end;\n\n  end else if (aMainRecord.Signature = 'NAVI') (* or (aMainRecord.Signature = 'TES4') *) then begin\n    IsNonOverride := True;\n    Signature := aMainRecord.Signature;\n    FormID := aMainRecord.FormID;\n    LoadOrder := aMainRecord.GetFile.LoadOrder;\n    SetLength(Result, 0);\n    Master := nil;\n    for i := 0 to Pred(PluginsList.Count) do begin\n      plugin := TPlugin(PluginsList[i]);\n      aFile := plugin._File;\n      if aFile.LoadOrder = LoadOrder then begin\n        Group := aFile.GroupBySignature[Signature];\n        if Assigned(Group) then begin\n          Rec := Group.MainRecordByFormID[FormID];\n          if Assigned(Rec) then begin\n            j := Length(Result);\n            SetLength(Result, j+1);\n            if not Assigned(Master) then\n              Master := Rec;\n            Result[j].Element := Rec;\n          end;\n        end;\n      end;\n    end;\n\n  end else if (aMainRecord.Signature = 'TES4') then begin\n    IsNonOverride := True;\n    Signature := aMainRecord.Signature;\n    LoadOrder := aMainRecord.GetFile.LoadOrder;\n    SetLength(Result, 0);\n    Master := nil;\n    for i := 0 to Pred(PluginsList.Count) do begin\n      plugin := TPlugin(PluginsList[i]);\n      aFile := plugin._File;\n      if aFile.LoadOrder = LoadOrder then begin\n        // header of .dat file, show only itself\n        if SameText(ExtractFileExt(aMainRecord.GetFile.FileName), '.dat') and not SameText(ExtractFileExt(aFile.FileName), '.dat') then\n          Continue;\n        // skip .dat file header by default\n        if not SameText(ExtractFileExt(aMainRecord.GetFile.FileName), '.dat') and SameText(ExtractFileExt(aFile.FileName), '.dat') then\n          Continue;\n        Rec := aFile.Elements[0] as IwbMainRecord;\n        if Assigned(Rec) then begin\n          j := Length(Result);\n          SetLength(Result, j+1);\n          if not Assigned(Master) then\n            Master := Rec;\n          Result[j].Element := Rec;\n        end;\n      end;\n    end;\n\n  end else begin\n    Master := aMainRecord.MasterOrSelf;\n\n    SetLength(Result, Succ(Master.OverrideCount));\n\n    AnyHidden := Master.IsHidden;\n    if not AnyHidden then\n      for i := 0 to Pred(Master.OverrideCount) do begin\n        AnyHidden := Master.Overrides[i].IsHidden;\n        if AnyHidden then\n          Break;\n      end;\n  end;\n\n  if (Length(Result) > 1) and ({ModGroupsEnabled or }AnyHidden) or IsNonOverride then begin\n\n    Records := TStringList.Create;\n    try\n      if IsNonOverride then begin\n        for i := Low(Result) to High(Result) do\n          if Supports(Result[i].Element, IwbMainRecord, Rec) then\n             Records.AddObject(Rec._File.FileName, Pointer(Rec));\n        Result := nil;\n      end else begin\n        Records.AddObject(Master._File.FileName, Pointer(Master));\n        for i := 0 to Pred(Master.OverrideCount) do begin\n          Rec := Master.Overrides[i];\n          Records.AddObject(Rec._File.FileName, Pointer(Rec));\n        end;\n      end;\n\n      {f ModGroupsEnabled then repeat\n        MadeChanges := False;\n        sl := TStringList.Create;\n        try\n          for i := 0 to Pred(ModGroups.Count) do begin\n            sl.Assign(TStrings(ModGroups.Objects[i]));\n            for j := Pred(sl.Count) downto 0 do begin\n              k := Records.IndexOf(sl[j]);\n              if K > 0 then // >, not >=, never hide the original master\n                sl.Objects[j] := TObject(k)\n              else\n                sl.Delete(j);\n            end;\n            if sl.Count > 1 then begin\n              k := Integer(sl.Objects[0]);\n              j := 1;\n              if k = 0 then begin\n                while (j < sl.Count) and (Integer(sl.Objects[j]) = k + 1) do begin\n                  Records.Objects[Integer(sl.Objects[Pred(j)])] := nil;\n                  Inc(k);\n                  Inc(j);\n                end;\n                Inc(j);\n              end;\n              while (j < sl.Count) do begin\n                Records.Objects[Integer(sl.Objects[Pred(j)])] := nil;\n                Inc(j);\n              end;\n              for j := Pred(Records.Count) downto 0 do\n                if Records.Objects[j] = nil then begin\n                  Records.Delete(j);\n                  MadeChanges := True;\n                end;\n            end;\n            if Records.Count < 2 then\n              Break;\n          end;\n        finally\n          sl.Free;\n        end;\n      until not MadeChanges;}\n\n      i := 0;\n      while (i < Records.Count) and (Records.Count > 1) do\n        if IwbElement(Pointer(Records.Objects[i])).IsHidden then\n          Records.Delete(i)\n        else\n          Inc(i);\n\n      SetLength(Result, Records.Count);\n      for i := 0 to Pred(Records.Count) do\n        with Result[i] do begin\n          Rec := IwbMainRecord(Pointer(Records.Objects[i]));\n          if i = 0 then\n            Master := Rec;\n\n          Container := Rec as IwbContainerElementRef;\n          Element := Container;\n          if (Container.ElementCount = 0) or (Rec.Signature <> Master.Signature) then\n            Container := nil;\n        end;\n\n    finally\n      FreeAndNil(Records);\n    end;\n\n    Exit;\n  end;\n\n  Result[0].Element := Master;\n  Result[0].Container := Master as IwbContainerElementRef;\n  if Master.ElementCount < 1 then\n    Result[0].Container := nil;\n\n  for i := 0 to Pred(Master.OverrideCount) do\n    with Result[Succ(i)] do begin\n      Container := Master.Overrides[i] as IwbContainerElementRef;\n      Element := Container;\n      if (Container.ElementCount = 0) or (Master.Overrides[i].Signature <> Master.Signature) then\n        Container := nil;\n    end;\nend;\n\nprocedure ConflictLevelForMainRecord(const aMainRecord: IwbMainRecord;\n  out aConflictAll: TConflictAll; out aConflictThis: TConflictThis);\n\n  procedure Fix(const aMainRecord: IwbMainRecord);\n  begin\n    with aMainRecord do begin\n      ConflictAll := aConflictAll;\n      if ConflictThis = ctUnknown then begin\n        ConflictThis := ctHiddenByModGroup;\n      end;\n    end;\n  end;\n\nvar\n  NodeDatas                   : TDynViewNodeDatas;\n  i                           : Integer;\n  Master                      : IwbMainRecord;\n  KeepAliveRoot               : IwbKeepAliveRoot;\nbegin\n  KeepAliveRoot := wbCreateKeepAliveRoot;\n\n  aConflictAll := aMainRecord.ConflictAll;\n  aConflictThis := aMainRecord.ConflictThis;\n\n  if aConflictAll > caUnknown then\n    Exit;\n\n  Master := aMainRecord.MasterOrSelf;\n  if (Master.OverrideCount = 0) and not wbTranslationMode and not (Master.Signature = 'GMST') then begin\n    aConflictAll := caOnlyOne;\n    aConflictThis := ctOnlyOne;\n    aMainRecord.ConflictAll := aConflictAll;\n    aMainRecord.ConflictThis := aConflictThis;\n  end else begin\n    NodeDatas := NodeDatasForMainRecord(aMainRecord);\n    if Length(NodeDatas) = 1 then begin\n      aConflictAll := caOnlyOne;\n      NodeDatas[0].ConflictAll := caOnlyOne;\n      NodeDatas[0].ConflictThis := ctOnlyOne;\n    {end else if wbQuickShowConflicts and (Length(NodeDatas) = 2) then begin\n      aConflictAll := caOverride;\n      NodeDatas[0].ConflictAll := caOverride;\n      NodeDatas[1].ConflictAll := caOverride;\n      NodeDatas[0].ConflictThis := ctMaster;\n      NodeDatas[1].ConflictThis := ctOverride;}\n    end else\n      aConflictAll := ConflictLevelForChildNodeDatas(NodeDatas, False, (aMainRecord.MasterOrSelf.IsInjected and not (aMainRecord.Signature = 'GMST')) );\n\n    for i := Low(NodeDatas) to High(NodeDatas) do\n      with NodeDatas[i] do\n        if Assigned(Element) then\n          with (Element as IwbMainRecord) do begin\n            ConflictAll := aConflictAll;\n            ConflictThis := NodeDatas[i].ConflictThis;\n          end;\n\n    Fix(Master);\n    for i := 0 to Pred(Master.OverrideCount) do\n      Fix(Master.Overrides[i]);\n\n    aConflictThis := aMainRecord.ConflictThis;\n  end;\nend;\n\nprocedure InitChilds(const aNodeDatas: PViewNodeDatas; aNodeCount: Integer;\n  var aChildCount: Cardinal);\nvar\n  NodeData                    : PNavNodeData;\n  Container                   : IwbContainer;\n  FirstContainer              : IwbContainer;\n  SortableContainer           : IwbSortableContainer;\n  Element                     : IwbElement;\n  i, j, k                     : Integer;\n  SortedCount                 : Integer;\n  NonSortedCount              : Integer;\n  SortedKeys                  : array of TnxFastStringListCS;\n  Sortables                   : array of IwbSortableContainer;\n  SortKey                     : string;\n  LastSortKey                 : string;\n  DupCounter                  : Integer;\nbegin\n  SortedCount := 0;\n  NonSortedCount := 0;\n  FirstContainer := nil;\n  for i := 0 to Pred(aNodeCount) do begin\n    NodeData := @aNodeDatas[i];\n    Container := NodeData.Container;\n    if not Assigned(FirstContainer) then\n      FirstContainer := Container;\n    if Assigned(Container) then\n      if Supports(Container, IwbSortableContainer, SortableContainer) and SortableContainer.Sorted then\n        Inc(SortedCount)\n      else\n        Inc(NonSortedCount);\n  end;\n\n  if (NonSortedCount > 0) and (SortedCount > 0) then begin\n    if Assigned(FirstContainer) then\n      ;//PostAddMessage('Warning: Comparing sorted and unsorted entry for \"' + FirstContainer.Path + '\" in \"'+FirstContainer.ContainingMainRecord.Name+'\"');\n    SortedCount := 0;\n  end;\n\n  if SortedCount > 0 then begin\n//    Assert(NonSortedCount = 0);\n\n    SetLength(SortedKeys, Succ(aNodeCount));\n    for i := Low(SortedKeys) to High(SortedKeys) do begin\n      SortedKeys[i] := TnxFastStringListCS.Create;\n      SortedKeys[i].Sorted := True;\n      SortedKeys[i].Duplicates := dupError;\n    end;\n\n    try\n      SortedKeys[aNodeCount].Duplicates := dupIgnore;\n\n      SetLength(Sortables, aNodeCount);\n\n      for i := 0 to Pred(aNodeCount) do\n        if Supports(aNodeDatas[i].Container, IwbSortableContainer, Sortables[i]) then begin\n          SortableContainer := Sortables[i];\n          DupCounter := 0;\n          LastSortKey := '';\n          for j := 0 to Pred(SortableContainer.ElementCount) do begin\n            Element := SortableContainer.Elements[j];\n            SortKey := Element.SortKey[False];\n            if SameStr(LastSortKey, SortKey) then\n              Inc(DupCounter)\n            else begin\n              DupCounter := 0;\n              LastSortKey := SortKey;\n            end;\n\n            SortKey := SortKey + '<' + IntToHex64(DupCounter, 4) + '>';\n\n            SortedKeys[i].AddObject(SortKey, Pointer(Element));\n            SortedKeys[aNodeCount].Add(SortKey);\n          end;\n        end;\n\n      aChildCount := SortedKeys[aNodeCount].Count;\n\n      for j := 0 to Pred(aChildCount) do begin\n        SortKey := SortedKeys[aNodeCount].Strings[j];\n        for i := 0 to Pred(aNodeCount) do\n          if SortedKeys[i].Find(SortKey, k) then\n            IwbElement(Pointer(SortedKeys[i].Objects[k])).SortOrder := j;\n      end;\n\n    finally\n\n      for i := Low(SortedKeys) to High(SortedKeys) do\n        FreeAndNil(SortedKeys[i]);\n\n    end;\n\n  end\n  else\n    for i := 0 to Pred(aNodeCount) do begin\n      NodeData := @aNodeDatas[i];\n      Container := NodeData.Container;\n\n      if Assigned(Container) then begin\n        case Container.ElementType of\n          etMainRecord, etSubRecordStruct: begin\n              aChildCount := (Container.Def as IwbRecordDef).MemberCount;\n              Inc(aChildCount, Container.AdditionalElementCount);\n              if Cardinal(Container.ElementCount) > aChildCount then begin\n                //PostAddMessage('Error: Container.ElementCount {'+IntToStr(Container.ElementCount)+'} > aChildCount {'+IntToStr(aChildCount)+'} for ' + Container.Path + ' in ' + Container.ContainingMainRecord.Name);\n                //for j := 0 to Pred(Container.ElementCount) do\n                //PostAddMessage('  #'+IntToStr(j)+': ' + Container.Elements[j].Name);\n                //Assert(Cardinal(Container.ElementCount) <= aChildCount);\n              end;\n            end;\n          etSubRecordArray, etArray, etStruct, etSubRecord, etValue, etUnion, etStructChapter:\n            if aChildCount < Cardinal(Container.ElementCount) then\n              aChildCount := Container.ElementCount;\n        end;\n      end;\n    end;\nend;\n\nprocedure InitNodes(const aNodeDatas: PViewNodeDatas;\n  const aParentDatas: PViewNodeDatas;\n  aNodeCount: Integer;\n  aIndex: Cardinal;\n  var aInitialStates: TVirtualNodeInitStates);\nvar\n  NodeData                    : PViewNodeData;\n  ParentData                  : PViewNodeData;\n  Container                   : IwbContainerElementRef;\n  SortableContainer           : IwbSortableContainer;\n  i                           : Integer;\nbegin\n  for i := 0 to Pred(aNodeCount) do begin\n    NodeData := @aNodeDatas[i];\n    ParentData := @aParentDatas[i];\n\n    Container := ParentData.Container;\n    if Assigned(Container) then begin\n      if Supports(Container, IwbSortableContainer, SortableContainer) and SortableContainer.Sorted then\n        NodeData.Element := Container.ElementBySortOrder[aIndex]\n      else\n        case Container.ElementType of\n          etMainRecord, etSubRecordStruct:\n            NodeData.Element := Container.ElementBySortOrder[aIndex];\n          etSubRecordArray, etArray, etStruct, etSubRecord, etValue, etUnion, etStructChapter:\n            if aIndex < Cardinal(Container.ElementCount) then\n              NodeData.Element := Container.Elements[aIndex];\n        end;\n    end;\n    if Assigned(NodeData.Element) and NodeData.Element.DontShow then begin\n      NodeData.Element := nil;\n      Include(NodeData.ViewNodeFlags, vnfDontShow);\n    end;\n  end;\n\n  aInitialStates := [ivsDisabled];\n  for i := 0 to Pred(aNodeCount) do\n    with aNodeDatas[i] do begin\n      if Assigned(Element) then\n        Exclude(aInitialStates, ivsDisabled)\n      else\n        if Assigned(aParentDatas) and ((vnfIgnore in aParentDatas[i].ViewNodeFlags) or (Assigned(aParentDatas[i].Element) and (aParentDatas[i].Element.ConflictPriority = cpIgnore))) then\n          Include(ViewNodeFlags, vnfIgnore);\n\n      if not Assigned(Container) then\n        if Supports(Element, IwbContainerElementRef, Container) then begin\n          //          if Container.ElementCount = 0 then\n          //            Container := nil;\n        end;\n\n      if Assigned(Container) then\n        if Container.ElementCount > 0 then\n          Include(aInitialStates, ivsHasChildren);\n    end;\nend;\n\nfunction ConflictLevelForChildNodeDatas(const aNodeDatas: TDynViewNodeDatas;\n  aSiblingCompare, aInjected: Boolean): TConflictAll;\nvar\n  ChildCount                  : Cardinal;\n  i, j                        : Integer;\n  NodeDatas                   : TDynViewNodeDatas;\n  InitialStates               : TVirtualNodeInitStates;\n  ConflictAll                 : TConflictAll;\n  ConflictThis                : TConflictThis;\n  Element                     : IwbElement;\nbegin\n  case Length(aNodeDatas) of\n    0: Result := caUnknown;\n    1: begin\n      Result := caOnlyOne;\n      aNodeDatas[0].ConflictThis := ctOnlyOne;\n    end;\n  else\n    Result := caNoConflict;\n  end;\n\n  if wbTranslationMode then begin\n    if Result < caOnlyOne then\n      Exit;\n  end\n  else begin\n    if Result < caNoConflict then\n      Exit;\n  end;\n\n  ChildCount := 0;\n  InitChilds(@aNodeDatas[0], Length(aNodeDatas), ChildCount);\n  if ChildCount > 0 then\n    for i := 0 to Pred(ChildCount) do begin\n      NodeDatas := nil;\n      SetLength(NodeDatas, Length(aNodeDatas));\n      InitialStates := [];\n      InitNodes(@NodeDatas[0], @aNodeDatas[0], Length(aNodeDatas), i, InitialStates);\n      if not (ivsDisabled in InitialStates) then begin\n\n        if ivsHasChildren in InitialStates then\n          ConflictAll := ConflictLevelForChildNodeDatas(NodeDatas, aSiblingCompare, aInjected)\n        else\n          ConflictAll := ConflictLevelForNodeDatas(@NodeDatas[0], Length(NodeDatas), aSiblingCompare, aInjected);\n\n        if ConflictAll > Result then\n          Result := ConflictAll;\n\n        for j := Low(aNodeDatas) to High(aNodeDatas) do\n          if NodeDatas[j].ConflictThis > aNodeDatas[j].ConflictThis then\n            aNodeDatas[j].ConflictThis := NodeDatas[j].ConflictThis;\n\n      end\n      else begin\n\n        ConflictThis := ctNotDefined;\n\n        for j := Low(aNodeDatas) to High(aNodeDatas) do begin\n          Element := aNodeDatas[j].Container;\n          if Assigned(Element) then\n            Break;\n        end;\n\n        if Assigned(Element) and (Element.ElementType in [etMainRecord, etSubRecordStruct]) then begin\n          j := (Element as IwbContainer).AdditionalElementCount;\n          if i >= j then\n            with (Element.Def as IwbRecordDef).Members[i - j] do\n              if (wbTranslationMode and (ConflictPriority[nil] <> cpTranslate)) or\n                (wbTranslationMode and (ConflictPriority[nil] = cpIgnore)) then\n                ConflictThis := ctIgnored;\n        end;\n\n        for j := Low(aNodeDatas) to High(aNodeDatas) do\n          if ConflictThis > aNodeDatas[j].ConflictThis then\n            aNodeDatas[j].ConflictThis := ConflictThis;\n      end;\n    end;\nend;\n\nfunction ConflictLevelForNodeDatas(const aNodeDatas: PViewNodeDatas;\n  aNodeCount: Integer; aSiblingCompare, aInjected: Boolean): TConflictAll;\nvar\n  Element                : IwbElement;\n  CompareElement         : IwbElement;\n  i, j                   : Integer;\n  UniqueValues           : TnxFastStringListCS;\n\n  MasterPosition         : Integer;\n  FirstElement           : IwbElement;\n  FirstElementNotIgnored : IwbElement;\n  LastElement            : IwbElement;\n  SameAsLast             : Boolean;\n  SameAsFirst            : Boolean;\n  OverallConflictThis    : TConflictThis;\n  Priority               : TwbConflictPriority;\n  ThisPriority           : TwbConflictPriority;\n  FoundAny               : Boolean;\nbegin\n//  if aSiblingCompare then\n//    Priority := cpBenign\n//  else\n//    Priority := cpNormal;\n//  IgnoreConflicts := False;\n  FoundAny := False;\n  MasterPosition := 0;\n  OverallConflictThis := ctUnknown;\n  case aNodeCount of\n    0: Result := caUnknown;\n    1: begin\n        Element := aNodeDatas[0].Element;\n        if Assigned(Element) then begin\n          if Element.ConflictPriority = cpIgnore then\n            aNodeDatas[0].ConflictThis := ctIgnored\n          else\n            aNodeDatas[0].ConflictThis := ctOnlyOne;\n        end else\n          aNodeDatas[0].ConflictThis := ctNotDefined;\n        Result := caOnlyOne;\n      end\n  else\n    LastElement := aNodeDatas[Pred(aNodeCount)].Element;\n    FirstElement := aNodeDatas[0].Element;\n\n    UniqueValues := TnxFastStringListCS.Create;\n    UniqueValues.Sorted := True;\n    UniqueValues.Duplicates := dupIgnore;\n    Priority := cpNormal;\n    try\n      for i := 0 to Pred(aNodeCount) do begin\n        Element := aNodeDatas[i].Element;\n        if Assigned(Element) then begin\n          FoundAny := True;\n          Priority := Element.ConflictPriority;\n          if Priority = cpNormalIgnoreEmpty then begin\n            FirstElement := Element;\n            MasterPosition := i;\n            for j := Pred(aNodeCount) downto i do begin\n              LastElement := aNodeDatas[j].Element;\n              if Assigned(LastElement) then\n                Break;\n            end;\n          end;\n          if Element.ConflictPriorityCanChange then begin\n            for j := Succ(i) to Pred(aNodeCount) do begin\n              Element := aNodeDatas[j].Element;\n              if Assigned(Element) then begin\n                ThisPriority := Element.ConflictPriority;\n                if ThisPriority > Priority then\n                  Priority := ThisPriority;\n              end;\n            end;\n          end;\n          Break;\n        end;\n      end;\n\n      if aSiblingCompare then\n        if Priority > cpBenign then\n          Priority := cpBenign;\n      if aInjected and (Priority >= cpNormal) then\n        Priority := cpCritical;\n\n      if (Priority > cpIgnore) and (not Assigned(FirstElement) or (FirstElement.ConflictPriority = cpIgnore)) then\n        FirstElementNotIgnored := nil\n      else\n        FirstElementNotIgnored := FirstElement;\n\n      for i := 0 to Pred(aNodeCount) do begin\n        Element := aNodeDatas[i].Element;\n        if Assigned(Element) then begin\n          ThisPriority := Element.ConflictPriority;\n          if ThisPriority <> cpIgnore then\n            UniqueValues.Add(Element.SortKey[True]);\n        end else begin\n          ThisPriority := Priority;\n          if not (vnfIgnore in aNodeDatas[i].ViewNodeFlags) then\n            if Priority <> cpNormalIgnoreEmpty then\n              UniqueValues.Add('');\n        end;\n\n        if (ThisPriority = cpNormalIgnoreEmpty) and not Assigned(Element) then\n          aNodeDatas[i].ConflictThis := ctIgnored\n        else if ThisPriority = cpIgnore then\n          aNodeDatas[i].ConflictThis := ctIgnored\n        else if aSiblingCompare then\n          aNodeDatas[i].ConflictThis := ctOnlyOne\n        else if i = MasterPosition then begin\n\n          if Assigned(Element) then\n            aNodeDatas[i].ConflictThis := ctMaster\n          else\n            aNodeDatas[i].ConflictThis := ctUnknown;\n\n        end else begin\n          SameAsLast := (i = Pred(aNodeCount)) or not (\n            (Assigned(Element) <> Assigned(LastElement)) or\n            (Assigned(Element) and not SameStr(Element.SortKey[True], LastElement.SortKey[True]))\n            );\n\n          SameAsFirst := not (\n            (Assigned(Element) <> Assigned(FirstElementNotIgnored)) or\n            (Assigned(Element) and not SameStr(Element.SortKey[True], FirstElementNotIgnored.SortKey[True]))\n            );\n\n          if not SameAsFirst and\n             (ThisPriority = cpBenignIfAdded) and\n             SameAsLast and  // We are not overriden later\n             not Assigned(FirstElementNotIgnored) then begin // The master did not have that element\n            ThisPriority := cpBenign;\n            Priority := cpBenign;\n            SameAsFirst := True;\n          end;\n\n          if SameAsFirst then\n            aNodeDatas[i].ConflictThis := ctIdenticalToMaster\n          else if SameAsLast then\n            aNodeDatas[i].ConflictThis := ctConflictWins\n          else\n            aNodeDatas[i].ConflictThis := ctConflictLoses;\n        end;\n\n        if (ThisPriority = cpBenign) and (aNodeDatas[i].ConflictThis > ctConflictBenign) then\n          aNodeDatas[i].ConflictThis := ctConflictBenign;\n\n        if aNodeDatas[i].ConflictThis > OverallConflictThis then\n          OverallConflictThis := aNodeDatas[i].ConflictThis;\n      end;\n\n      case UniqueValues.Count of\n        0: Result := caNoConflict;\n        1: Result := caNoConflict;\n        2: begin\n            Element := aNodeDatas[0].Element;\n            CompareElement := aNodeDatas[Pred(aNodeCount)].Element;\n            if (Assigned(Element) <> Assigned(CompareElement)) or\n              (Assigned(Element) and not SameStr(Element.SortKey[True], CompareElement.SortKey[True])) then\n              Result := caOverride\n            else if (UniqueValues.IndexOf('') >= 0) and Assigned(CompareElement) and (CompareElement.SortKey[True] <> '') then\n              Result := caOverride\n            else\n              Result := caConflict;\n          end\n      else\n        Result := caConflict;\n      end;\n\n      if aSiblingCompare and (Result > caConflictBenign) then\n        Result := caConflictBenign;\n\n      if not FoundAny then\n        for i := 0 to Pred(aNodeCount) do\n          aNodeDatas[i].ConflictThis := ctNotDefined;\n\n      if Result > caNoConflict then\n        case Priority of\n          cpBenign: Result := caConflictBenign;\n          cpCritical: begin\n              if UniqueValues.Find('', i) then\n                UniqueValues.Delete(i);\n              if UniqueValues.Count > 1 then\n                Result := caConflictCritical;\n            end;\n        end;\n\n      if Priority > cpBenign then\n        if OverallConflictThis > ctOverride then\n          with aNodeDatas[Pred(aNodeCount)] do\n            if ConflictThis < ctOverride then\n              if ConflictThis = ctIdenticalToMaster then\n                ConflictThis := ctIdenticalToMasterWinsConflict\n              else\n                ConflictThis := ctConflictWins;\n\n      if Result in [caNoConflict, caOverride, caConflict] then\n        for i := 0 to Pred(aNodeCount) do begin\n          case aNodeDatas[i].ConflictThis of\n            ctIdenticalToMaster: case Result of\n                caNoConflict: ;\n                caOverride, caConflict: if i = Pred(aNodeCount) then\n                  aNodeDatas[i].ConflictThis := ctIdenticalToMasterWinsConflict\n              end;\n            ctConflictWins: case Result of\n              caNoConflict: aNodeDatas[i].ConflictThis := ctIdenticalToMaster;\n              caOverride: aNodeDatas[i].ConflictThis := ctOverride;\n              caConflict: ;\n            end;\n          end;\n        end;\n\n      if Result < caConflict then\n        for i := 0 to Pred(aNodeCount) do\n          if aNodeDatas[i].ConflictThis >= ctIdenticalToMasterWinsConflict then begin\n            Result := caConflict;\n            Break;\n          end;\n\n    finally\n      FreeAndNil(UniqueValues);\n    end;\n  end;\nend;\n\nfunction ConflictThisForMainRecord(aMainRecord: IwbMainRecord): TConflictThis;\nvar\n  ct: TConflictThis;\n  ca: TConflictAll;\nbegin\n  ConflictLevelForMainRecord(aMainRecord, ca, ct);\n  Result := ct;\nend;\n\nfunction ConflictAllForMainRecord(aMainRecord: IwbMainRecord): TConflictAll;\nvar\n  ct: TConflictThis;\n  ca: TConflictAll;\nbegin\n  ConflictLevelForMainRecord(aMainRecord, ca, ct);\n  Result := ca;\nend;\n\nfunction IsITPO(rec: IwbMainRecord): Boolean;\nvar\n  mRec, prevOvr, ovr: IwbMainRecord;\n  i: Integer;\nbegin\n  // get previous override\n  mRec := rec.MasterOrSelf;\n  prevovr := mRec;\n  for i := 0 to Pred(mRec.OverrideCount) do begin\n    ovr := mRec.Overrides[i];\n    if ovr.Equals(rec) then\n      Break;\n    prevovr := ovr;\n  end;\n\n  Result := ConflictAllForElements(prevovr, rec, False, False) <= caNoConflict;\nend;\n\nfunction IsITM(rec: IwbMainRecord): Boolean;\nconst\n  ITMConflictArray: set of TConflictThis = [\n    ctIdenticalToMaster,\n    ctIdenticalToMasterWinsConflict\n  ];\nbegin\n  Result := ConflictThisForMainRecord(rec) in ITMConflictArray;\nend;\n\nend.\n"
  },
  {
    "path": "frontend/msConflictForm.dfm",
    "content": "object ConflictForm: TConflictForm\n  Left = 0\n  Top = 0\n  Caption = 'Combine smash settings'\n  ClientHeight = 377\n  ClientWidth = 709\n  Color = clBtnFace\n  Font.Charset = DEFAULT_CHARSET\n  Font.Color = clWindowText\n  Font.Height = -11\n  Font.Name = 'Tahoma'\n  Font.Style = []\n  OldCreateOrder = False\n  OnClose = FormClose\n  OnCreate = FormCreate\n  OnShow = FormShow\n  PixelsPerInch = 96\n  TextHeight = 13\n  object btnOK: TButton\n    Left = 545\n    Top = 344\n    Width = 75\n    Height = 25\n    Align = alCustom\n    Anchors = [akRight, akBottom]\n    Caption = 'OK'\n    TabOrder = 0\n    OnClick = btnOKClick\n  end\n  object btnCancel: TButton\n    Left = 626\n    Top = 344\n    Width = 75\n    Height = 25\n    Align = alCustom\n    Anchors = [akRight, akBottom]\n    Caption = 'Cancel'\n    ModalResult = 2\n    TabOrder = 1\n  end\n  object tvRecords: TTreeView\n    Left = 301\n    Top = 8\n    Width = 400\n    Height = 330\n    Align = alCustom\n    Anchors = [akTop, akRight, akBottom]\n    DoubleBuffered = True\n    Indent = 19\n    MultiSelect = True\n    ParentDoubleBuffered = False\n    ReadOnly = True\n    StateImages = StateImages\n    TabOrder = 2\n    OnCustomDrawItem = tvRecordsCustomDrawItem\n    OnMouseMove = tvRecordsMouseMove\n  end\n  object sbChoices: TScrollBox\n    Left = 8\n    Top = 8\n    Width = 287\n    Height = 330\n    Align = alCustom\n    Anchors = [akLeft, akTop, akRight, akBottom]\n    TabOrder = 3\n  end\n  object FlagIcons: TImageList\n    Left = 408\n    Top = 24\n    Bitmap = {\n      494C010103000800540010001000FFFFFFFFFF10FFFFFFFFFFFFFFFF424D3600\n      0000000000003600000028000000400000001000000001002000000000000010\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000D7D7F8FF7373E6FF3434DBFF2121BEFF2121BEFF2D2DDAFF6B6BE4FFD2D2\n      F7FF000000000000000000000000000000000000000000000000000000000000\n      0000E4F1E779D7D6B8CCD4BF91F3D2B683FED2B581FED1BD8FF3D5D3B5CCE3F0\n      E6790000000000000000000000000000000000000000D1D1D12E4F4F4FB01B1B\n      1BE42B2B2BD48282827DF7F7F708000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000F8F8FDFF7373\n      E6FF2020B5FF2020B5FF3434DBFF5B5BE2FF5B5BE2FF3D3DDCFF2020B5FF2020\n      B5FF6464E3FFF8F8FDFF00000000000000000000000000000000F2F8F33CD9D8\n      BACBDCAB6CFEE1974BFFE18F3DFFE18A37FFDF8835FFDD8A39FFD99044FFD4A3\n      64FED4D4B6CBF1F7F23C0000000000000000D1D1D12E0C0C0CF3000000FF0000\n      00FF000000FF000000FF3B3B3BC4F2F2F20D0000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      00000000000000000000000000000000000000000000F8F8FDFF4242DDFF2020\n      B5FF5353E0FFD7D7F8FF00000000000000000000000000000000E2E2F9FF5B5B\n      E2FF2020B5FF3D3DDCFFEFEFFCFF0000000000000000F2F8F33CDBCDA5DEE3A1\n      58FFE69240FFE58F3AFFE48D39FFE28B37FFE08A36FFDF8834FFDD8733FFDB87\n      35FFD7944CFFD3C49DDEF1F7F23C000000004E4E4EB1000000FF4D4D4DB2D7D7\n      D728B2B2B24D1A1A1AE5000000FF3A3A3AC5F2F2F20D00000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      000000000000000000000000000000000000000000007373E6FF2020B5FF8282\n      E9FF000000000000000000000000FEFEFE03FDFDFE0700000000000000000000\n      00009292EBFF2020B5FF6464E3FF0000000000000000DBDABCCBE6A35AFFE994\n      41FFE8923EFFE7903CFFE58E3AFFE38D38FFE28B37FFE08935FFDF8834FFDD86\n      32FFDC8633FFD6944BFFD4D3B5CB000000001B1B1BE4000000FFD7D7D7280000\n      000000000000D9D9D9261B1B1BE4000000FF3A3A3AC5F2F2F20D000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      000000000000000000000000000000000000D7D7F8FF2020B5FF5353E0FF0000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000006464E3FF2020B5FFC8C8F5FFE6F3E879E3B273FEEC9846FFEB95\n      41FFEA933FFFE8913DFFEAA560FFF9F7F5FFF8F0E8FFE18B37FFE08935FFDE88\n      33FFDD8632FFDA8735FFD3A263FEE3F0E6792B2B2BD4000000FFB3B3B34C0000\n      00000000000000000000D9D9D926BABABA45EFEFEF10F3F3F30C000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000007A7AE7FF2020B5FFD2D2F7FF0000\n      00000000000000000000FEFEFE0D0000000000000000F4F4FC28000000000000\n      000000000000E2E2F9FF2020B5FF6B6BE4FFDDDBBDCCEBA256FFEE9844FFED96\n      42FFEB9440FFE9933FFFEBA562FFF9F7F5FFF8F0E8FFE38C38FFE18A36FFE089\n      35FFDE8733FFDD8632FFD88F43FFD4D3B5CC8383837C000000FF1A1A1AE5D9D9\n      D9260000000000000000C3C3C33C424242BD131313EC262626D97F7F7F80F7F7\n      F708000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000003434DBFF3434DBFF000000000000\n      0000B9B9F2FFB9B9F2FFB9B9F2FFB9B9F2FFB9B9F2FFB9B9F2FFB9B9F2FFB9B9\n      F2FFEFEFFCFF000000004242DDFF2525D6FFDDC89AF3F09D4BFFF09945FFEE97\n      43FFED9642FFEB9440FFECA663FFF9F7F5FFF8F0E9FFE48D39FFE28C38FFE18A\n      36FFDF8934FFDE8733FFDB8937FFD1BC8DF3F7F7F7083B3B3BC4000000FF1B1B\n      1BE4D9D9D926E3E3E31C060606F9000000FF000000FF000000FF000000FF3B3B\n      3BC4F2F2F20D0000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000002323C6FF5353E0FF000000000000\n      00002121BEFF2020B5FF2020B5FF2020B5FF2020B5FF2020B5FF2020B5FF2020\n      B5FFC8C8F5FF000000006464E3FF2121BEFFDFC38FFEF39C49FFF19A46FFEF99\n      44FFEE9743FFEC9541FFEEA864FFF9F7F5FFF8F0E9FFE68F3BFFE48D39FFE28B\n      37FFE18A36FFDF8834FFDD8734FFD0B480FE00000000F2F2F20D3A3A3AC50000\n      00FF1B1B1BE4CECECE31444444BB7171718EE1E1E11EB7B7B7481A1A1AE50000\n      00FF3A3A3AC5F2F2F20D00000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000002323C6FF5353E0FF000000000000\n      00002020B5FF2020B5FF2020B5FF2020B5FF2020B5FF2020B5FF2020B5FF2020\n      B5FFC8C8F5FF000000006464E3FF2121BEFFE0C390FEF49D4AFFF29B47FFF19A\n      46FFEF9844FFEE9743FFEFA965FFF9F7F5FFF8F0E9FFE7903CFFE58E3AFFE48D\n      39FFE28B37FFE08A35FFDF8835FFD1B581FE0000000000000000F2F2F20D3A3A\n      3AC5000000FF1A1A1AE5B8B8B847E1E1E11E7171718E444444BBCECECE311B1B\n      1BE4000000FF3A3A3AC5F2F2F20D000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000003D3DDCFF2D2DDAFF000000000000\n      0000F8F8FDFFF8F8FDFFEFEFFCFFEFEFFCFFEFEFFCFFEFEFFCFFEFEFFCFFF8F8\n      FDFFF8F8FDFF000000003D3DDCFF2525D6FFDFCA9CF3F3A14FFFF39D48FFF29B\n      47FFF09A45FFEF9844FFF0B172FFF9F7F5FFF8F0E9FFE8913DFFE7903CFFE58E\n      3AFFE38C38FFE28B37FFDF8C3BFFD2BE90F3000000000000000000000000F2F2\n      F20D3B3B3BC4000000FF000000FF000000FF000000FF060606F9E3E3E31CD9D9\n      D9261B1B1BE4000000FF3B3B3BC4F7F7F7080000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000007373E6FF2020B5FFD2D2F7FF0000\n      0000000000000000000000000000F1F1FA0FFAFAFD05F1F1FC32000000000000\n      000000000000E2E2F9FF2020B5FF6B6BE4FFDFDDBFCCF1A85BFFF49E4AFFF39C\n      48FFF29B47FFF5CBA3FFF9F7F5FFF9F7F5FFF8F0E9FFEA933FFFE8913DFFE68F\n      3BFFE58E3AFFE38C38FFDE9548FFD7D5B7CC0000000000000000000000000000\n      0000F7F7F7087F7F7F80262626D9131313EC424242BDC3C3C33C000000000000\n      0000D9D9D9261A1A1AE5000000FF8383837C0000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      000000000000000000000000000000000000D7D7F8FF2020B5FF5353E0FF0000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000006464E3FF2020B5FFC8C8F5FFE7F3E979E9B879FEF4A14FFFF49D\n      49FFF39C48FFF19B46FFF19F51FFF6DEC6FFF8F1E9FFEB9440FFE9933EFFE891\n      3DFFE68F3BFFE3903DFFDAA96AFEE4F1E7790000000000000000000000000000\n      00000000000000000000F3F3F30CEFEFEF10BABABA45D9D9D926000000000000\n      000000000000B3B3B34C000000FF2C2C2CD30000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      000000000000000000000000000000000000000000007A7AE7FF2020B5FF8282\n      E9FF000000000000000000000000000000000000000000000000000000000000\n      00008B8BEAFF2020B5FF6464E3FF0000000000000000DFDEC0CBEFAD64FFF4A0\n      4CFFF49D49FFF39C48FFF19A46FFF09945FFEE9743FFEC9641FFEB9440FFE992\n      3EFFE7913EFFE19E55FFD8D7B9CB000000000000000000000000000000000000\n      00000000000000000000F2F2F20D3A3A3AC5000000FF1B1B1BE4D9D9D9260000\n      000000000000D7D7D728000000FF1B1B1BE40000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      00000000000000000000000000000000000000000000F8F8FDFF4242DDFF2020\n      B5FF5353E0FFD7D7F8FF00000000000000000000000000000000D7D7F8FF5B5B\n      E2FF2020B5FF4242DDFFEFEFFCFF0000000000000000F3F9F43CE1D2ABDEEFAD\n      63FFF4A04EFFF49D49FFF29B47FFF19A46FFEF9944FFEE9743FFEC9541FFE996\n      43FFE3A158FFD9CAA3DEF2F8F33C000000000000000000000000000000000000\n      0000000000000000000000000000F2F2F20D3A3A3AC5000000FF1A1A1AE5B3B3\n      B34CD7D7D7284E4E4EB1000000FF4F4F4FB00000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000F8F8FDFF7373\n      E6FF2020B5FF2020B5FF3434DBFF6464E3FF5B5BE2FF3D3DDCFF2020B5FF2020\n      B5FF6B6BE4FFEFEFFCFF00000000000000000000000000000000F3F9F43CDFDD\n      C0CBE8B778FEF0A75AFFF2A04EFFF29B48FFF19A47FFEE9B49FFE9A053FFE0B0\n      71FEDAD9BCCBF2F8F33C00000000000000000000000000000000000000000000\n      000000000000000000000000000000000000F2F2F20D3B3B3BC4000000FF0000\n      00FF000000FF000000FF0C0C0CF3D2D2D22D0000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000D7D7F8FF7373E6FF2D2DDAFF2121BEFF2121BEFF2D2DDAFF6B6BE4FFD2D2\n      F7FF000000000000000000000000000000000000000000000000000000000000\n      0000E6F3E979DFDCBFCCDEC99BF3DFC28EFEDEC18EFEDCC799F3DCDABCCCE5F2\n      E879000000000000000000000000000000000000000000000000000000000000\n      00000000000000000000000000000000000000000000F7F7F7088282827D2B2B\n      2BD41C1C1CE34F4F4FB0D2D2D22D000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      000000000000000000000000000000000000424D3E000000000000003E000000\n      2800000040000000100000000100010000000000800000000000000000000000\n      000000000000000000000000FFFFFF00F00FF00F81FF0000C003C00300FF0000\n      83C18001007F00008E718001183F00001FF800001C3F00001DB800000C0F0000\n      3004000000070000300400008003000030040000C001000030040000E0000000\n      1E380000F03000001FF80000FC3800008FF18001FC18000083C18001FE000000\n      C003C003FF000000F00FF00FFF81000000000000000000000000000000000000\n      000000000000}\n  end\n  object StateImages: TImageList\n    Height = 17\n    Width = 17\n    Left = 336\n    Top = 24\n    Bitmap = {\n      494C010104000800500011001100FFFFFFFFFF10FFFFFFFFFFFFFFFF424D3600\n      0000000000003600000028000000440000002200000001002000000000002024\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\n      FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\n      FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\n      FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\n      FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\n      FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\n      FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\n      FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\n      FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\n      FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\n      FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\n      FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\n      FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\n      FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\n      FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\n      FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\n      FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\n      FFFFFFFFFFFFFFFFFFFF8F8F8EFF8F8F8EFF8F8F8EFF8F8F8EFF8F8F8EFF8F8F\n      8EFF8F8F8EFF8F8F8EFF8F8F8EFF8F8F8EFF8F8F8EFF8F8F8EFF8F8F8EFFFFFF\n      FFFFFFFFFFFFFFFFFFFFFFFFFFFF8F8F8EFF8F8F8EFF8F8F8EFF8F8F8EFF8F8F\n      8EFF8F8F8EFF8F8F8EFF8F8F8EFF8F8F8EFF8F8F8EFF8F8F8EFF8F8F8EFF8F8F\n      8EFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8F8F8EFF8F8F8EFF8F8F8EFF8F8F\n      8EFF8F8F8EFF8F8F8EFF8F8F8EFF8F8F8EFF8F8F8EFF8F8F8EFF8F8F8EFF8F8F\n      8EFF8F8F8EFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8F8F8EFF8F8F8EFF8F8F\n      8EFF8F8F8EFF8F8F8EFF8F8F8EFF8F8F8EFF8F8F8EFF8F8F8EFF8F8F8EFF8F8F\n      8EFF8F8F8EFF8F8F8EFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8F8F8EFFF4F4\n      F4FFF4F4F4FFF4F4F4FFF5F5F5FFF9F9F9FFF8F8F8FFF5F5F5FFF4F4F4FFF4F4\n      F4FFF4F4F4FFF4F4F4FF8F8F8EFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8F8F\n      8EFFF4F4F4FFF4F4F4FFF4F4F4FFF5F5F5FFF9F9F9FFF8F8F8FFF5F5F5FFF4F4\n      F4FFF4F4F4FFF4F4F4FFF4F4F4FF8F8F8EFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\n      FFFF8F8F8EFFF4F4F4FFF4F4F4FFF4F4F4FFF4F4F4FFF4F4F4FFF4F4F4FFF4F4\n      F4FFF4F4F4FFF4F4F4FFF4F4F4FFF4F4F4FF8F8F8EFFFFFFFFFFFFFFFFFFFFFF\n      FFFFFFFFFFFF8F8F8EFFF4F4F4FFF4F4F4FFF4F4F4FFF4F4F4FFF4F4F4FFF4F4\n      F4FFF4F4F4FFF4F4F4FFF4F4F4FFF4F4F4FFF4F4F4FF8F8F8EFFFFFFFFFFFFFF\n      FFFFFFFFFFFFFFFFFFFF8F8F8EFFF4F4F4FFCCCBCAFFDBDADAFFE9E2DFFFBA99\n      8CFFBD9D90FFF6F3F2FFEDEDECFFECEBEBFFEAE9E9FFF4F4F4FF8F8F8EFFFFFF\n      FFFFFFFFFFFFFFFFFFFFFFFFFFFF8F8F8EFFF4F4F4FFCCCBCAFFDBDADAFFE9E2\n      DFFFBA998CFFBD9D90FFF6F3F2FFEDEDECFFECEBEBFFEAE9E9FFF4F4F4FF8F8F\n      8EFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8F8F8EFFF4F4F4FFCCCBCAFFD5D4\n      D4FFDCDBDBFFE1E1E0FFE7E7E6FFEBEBEAFFECECEBFFECEBEBFFEAE9E9FFF4F4\n      F4FF8F8F8EFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8F8F8EFFF4F4F4FF714E\n      21FF6A491FFF61441DFF593E1AFF553B19FF553B19FF553A19FF553A19FF553B\n      19FFF4F4F4FF8F8F8EFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8F8F8EFFF4F4\n      F4FFCAC8C6FFF0ECEAFFBB998BFF975F4AFF98614CFFD1B9B0FFF9F9F9FFF6F6\n      F6FFE6E6E6FFF4F4F4FF8F8F8EFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8F8F\n      8EFFF4F4F4FFCAC8C6FFF0ECEAFFBB998BFF975F4AFF98614CFFD1B9B0FFF9F9\n      F9FFF6F6F6FFE6E6E6FFF4F4F4FF8F8F8EFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\n      FFFF8F8F8EFFF4F4F4FFC6C4C2FFE9E9E9FFEDEDEDFFF0F0F0FFF4F4F4FFF6F6\n      F6FFF6F6F6FFF6F6F6FFE6E6E6FFF4F4F4FF8F8F8EFFFFFFFFFFFFFFFFFFFFFF\n      FFFFFFFFFFFF8F8F8EFFF4F4F4FF755123FFB89255FFAE864CFFA47A44FF996E\n      3BFF936532FF8F5F2CFF8C5925FF553B19FFF4F4F4FF8F8F8EFFFFFFFFFFFFFF\n      FFFFFFFFFFFFFFFFFFFF8F8F8EFFF4F4F4FFD1CFCDFFE9E1DEFF955D48FF965F\n      49FF97604BFFA47361FFFAF9F8FFF4F4F4FFE2E2E1FFF4F4F4FF8F8F8EFFFFFF\n      FFFFFFFFFFFFFFFFFFFFFFFFFFFF8F8F8EFFF4F4F4FFD1CFCDFFE9E1DEFF955D\n      48FF965F49FF97604BFFA47361FFFAF9F8FFF4F4F4FFE2E2E1FFF4F4F4FF8F8F\n      8EFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8F8F8EFFF4F4F4FFC2BFBCFFE5E4\n      E3FFE9E9E9FFEDEDEDFFF2F2F2FFF4F4F4FFF5F5F5FFF4F4F4FFE2E2E1FFF4F4\n      F4FF8F8F8EFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8F8F8EFFF4F4F4FF7B55\n      24FFC29D5DFFB38927FFAA8124FFA07822FF966F1FFF8F691EFF8F602CFF553B\n      19FFF4F4F4FF8F8F8EFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8F8F8EFFF4F4\n      F4FFE1E0DEFFAA7F6EFF945C47FFE2D4CFFFA77867FF97604BFFD5BFB7FFF6F6\n      F6FFDEDDDCFFF4F4F4FF8F8F8EFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8F8F\n      8EFFF4F4F4FFE1E0DEFFAA7F6EFF945C47FFE2D4CFFFA77867FF97604BFFD5BF\n      B7FFF6F6F6FFDEDDDCFFF4F4F4FF8F8F8EFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\n      FFFF8F8F8EFFF4F4F4FFBFBBB8FFE1DFDDFFE5E5E4FFEAEAEAFFEFEFEFFFF2F2\n      F2FFF2F2F2FFF2F2F2FFDEDDDCFFF4F4F4FF8F8F8EFFFFFFFFFFFFFFFFFFFFFF\n      FFFFFFFFFFFF8F8F8EFFF4F4F4FF815A26FFCBA966FFBF942AFFB88E28FFB087\n      26FFA77F24FF9F7722FF9A6B34FF5C401BFFF4F4F4FF8F8F8EFFFFFFFFFFFFFF\n      FFFFFFFFFFFFFFFFFFFF8F8F8EFFF4F4F4FFCDC9C5FFDDCFC9FFC8AEA3FFEEEE\n      EDFFD5C1BAFF965E49FFA57664FFF8F8F8FFD6D5D5FFF4F4F4FF8F8F8EFFFFFF\n      FFFFFFFFFFFFFFFFFFFFFFFFFFFF8F8F8EFFF4F4F4FFCDC9C5FFDDCFC9FFC8AE\n      A3FFEEEEEDFFD5C1BAFF965E49FFA57664FFF8F8F8FFD6D5D5FFF4F4F4FF8F8F\n      8EFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8F8F8EFFF4F4F4FFBCB7B2FFDCD8\n      D5FFDFDCDAFFE3E1E0FFE8E8E8FFECECECFFEDEDEDFFEDEDEDFFD6D5D4FFF4F4\n      F4FF8F8F8EFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8F8F8EFFF4F4F4FF855D\n      27FFD4B36DFFC99E2CFFC4992BFFBE932AFFB78D28FFAE8525FFA6793EFF6546\n      1EFFF4F4F4FF8F8F8EFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8F8F8EFFF4F4\n      F4FFB9B3AEFFDDD9D5FFE5E2DFFFDCD8D5FFF4F3F2FFA1715EFF945C47FFD6C3\n      BCFFDCDCDBFFF4F4F4FF8F8F8EFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8F8F\n      8EFFF4F4F4FFB9B3AEFFDDD9D5FFE5E2DFFFDCD8D5FFF4F3F2FFA1715EFF945C\n      47FFD6C3BCFFDCDCDBFFF4F4F4FF8F8F8EFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\n      FFFF8F8F8EFFF4F4F4FFB9B3AEFFD7D1CDFFD9D4D0FFDBD7D4FFDFDDDBFFE3E2\n      E1FFE6E6E5FFE8E8E8FFCDCDCCFFF4F4F4FF8F8F8EFFFFFFFFFFFFFFFFFFFFFF\n      FFFFFFFFFFFF8F8F8EFFF4F4F4FF895F28FFDABB74FFD1A42EFFCEA22DFFC99D\n      2CFFC2972BFFBB9129FFB18647FF6E4C20FFF4F4F4FF8F8F8EFFFFFFFFFFFFFF\n      FFFFFFFFFFFFFFFFFFFF8F8F8EFFF4F4F4FFB9B3AEFFD5CFCBFFD5CFCBFFD6D1\n      CDFFE6E2E0FFCFB8AFFF925A45FFA57765FFE8E7E7FFF4F4F4FF8F8F8EFFFFFF\n      FFFFFFFFFFFFFFFFFFFFFFFFFFFF8F8F8EFFF4F4F4FFB9B3AEFFD5CFCBFFD5CF\n      CBFFD6D1CDFFE6E2E0FFCFB8AFFF925A45FFA57765FFE8E7E7FFF4F4F4FF8F8F\n      8EFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8F8F8EFFF4F4F4FFB9B3AEFFD5CF\n      CBFFD5CFCBFFD6D1CDFFDAD5D2FFDEDBD8FFE1DFDDFFE4E3E2FFC8C7C6FFF4F4\n      F4FF8F8F8EFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8F8F8EFFF4F4F4FF8B61\n      29FFE0C27BFFD5A82FFFD3A62FFFD0A42EFFCB9F2DFFC5992BFFBB9250FF7652\n      23FFF4F4F4FF8F8F8EFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8F8F8EFFF4F4\n      F4FFB9B3AEFFD5CFCBFFD5CFCBFFD5CFCBFFD6D0CCFFF1EEEDFF9D6A57FF925A\n      44FFD0BFB9FFF6F6F6FF8F8F8EFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8F8F\n      8EFFF4F4F4FFB9B3AEFFD5CFCBFFD5CFCBFFD5CFCBFFD6D0CCFFF1EEEDFF9D6A\n      57FF925A44FFD0BFB9FFF6F6F6FF8F8F8EFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\n      FFFF8F8F8EFFF4F4F4FFB9B3AEFFD5CFCBFFD5CFCBFFD5CFCBFFD5CFCBFFD8D3\n      D0FFDCD8D5FFDFDDDBFFC5C3C1FFF4F4F4FF8F8F8EFFFFFFFFFFFFFFFFFFFFFF\n      FFFFFFFFFFFF8F8F8EFFF4F4F4FF8D6229FFE4C87FFFE1C37BFFDDBE75FFD9B7\n      6EFFD3AF68FFCCA760FFC49D59FF7C5624FFF4F4F4FF8F8F8EFFFFFFFFFFFFFF\n      FFFFFFFFFFFFFFFFFFFF8F8F8EFFF4F4F4FFB9B3AEFFB9B3AEFFB9B3AEFFB9B3\n      AEFFB9B3AEFFD0CCC9FFC0A79DFFAB8677FFE4DFDCFFF5F5F5FF8F8F8EFFFFFF\n      FFFFFFFFFFFFFFFFFFFFFFFFFFFF8F8F8EFFF4F4F4FFB9B3AEFFB9B3AEFFB9B3\n      AEFFB9B3AEFFB9B3AEFFD0CCC9FFC0A79DFFAB8677FFE4DFDCFFF5F5F5FF8F8F\n      8EFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8F8F8EFFF4F4F4FFB9B3AEFFB9B3\n      AEFFB9B3AEFFB9B3AEFFB9B3AEFFB9B3AEFFBAB4AFFFBDB9B4FFC1BEBBFFF4F4\n      F4FF8F8F8EFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8F8F8EFFF4F4F4FF8D62\n      29FF8E622AFF8E622AFF8D622AFF8C6129FF8A6028FF875E28FF845B27FF8059\n      26FFF4F4F4FF8F8F8EFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8F8F8EFFF4F4\n      F4FFF4F4F4FFF4F4F4FFF4F4F4FFF4F4F4FFF4F4F4FFF4F4F4FFF8F8F8FFF9F9\n      F9FFF6F6F6FFF4F4F4FF8F8F8EFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8F8F\n      8EFFF4F4F4FFF4F4F4FFF4F4F4FFF4F4F4FFF4F4F4FFF4F4F4FFF4F4F4FFF8F8\n      F8FFF9F9F9FFF6F6F6FFF4F4F4FF8F8F8EFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\n      FFFF8F8F8EFFF4F4F4FFF4F4F4FFF4F4F4FFF4F4F4FFF4F4F4FFF4F4F4FFF4F4\n      F4FFF4F4F4FFF4F4F4FFF4F4F4FFF4F4F4FF8F8F8EFFFFFFFFFFFFFFFFFFFFFF\n      FFFFFFFFFFFF8F8F8EFFF4F4F4FFF4F4F4FFF4F4F4FFF4F4F4FFF4F4F4FFF4F4\n      F4FFF4F4F4FFF4F4F4FFF4F4F4FFF4F4F4FFF4F4F4FF8F8F8EFFFFFFFFFFFFFF\n      FFFFFFFFFFFFFFFFFFFF8F8F8EFF8F8F8EFF8F8F8EFF8F8F8EFF8F8F8EFF8F8F\n      8EFF8F8F8EFF8F8F8EFF8F8F8EFF8F8F8EFF8F8F8EFF8F8F8EFF8F8F8EFFFFFF\n      FFFFFFFFFFFFFFFFFFFFFFFFFFFF8F8F8EFF8F8F8EFF8F8F8EFF8F8F8EFF8F8F\n      8EFF8F8F8EFF8F8F8EFF8F8F8EFF8F8F8EFF8F8F8EFF8F8F8EFF8F8F8EFF8F8F\n      8EFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8F8F8EFF8F8F8EFF8F8F8EFF8F8F\n      8EFF8F8F8EFF8F8F8EFF8F8F8EFF8F8F8EFF8F8F8EFF8F8F8EFF8F8F8EFF8F8F\n      8EFF8F8F8EFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8F8F8EFF8F8F8EFF8F8F\n      8EFF8F8F8EFF8F8F8EFF8F8F8EFF8F8F8EFF8F8F8EFF8F8F8EFF8F8F8EFF8F8F\n      8EFF8F8F8EFF8F8F8EFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\n      FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\n      FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\n      FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\n      FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\n      FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\n      FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\n      FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\n      FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\n      FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\n      FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\n      FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\n      FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\n      FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\n      FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\n      FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\n      FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\n      FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF424D3E000000000000003E000000\n      2800000044000000220000000100010000000000980100000000000000000000\n      000000000000000000000000FFFFFF0000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      000000000000000000000000000000000000000000000000000000000000}\n  end\nend\n"
  },
  {
    "path": "frontend/msConflictForm.pas",
    "content": "unit msConflictForm;\n\ninterface\n\nuses\n  Windows, Types, Messages, SysUtils, Variants, Classes, Graphics, Controls,\n  Forms, Dialogs, StdCtrls, ComCtrls, ImgList,\n  // superobject\n  superobject,\n  // mte units\n  mteHelpers, mteBase,\n  // ms units\n  msCore, msChoicePanel;\n\ntype\n  TConflictForm = class(TForm)\n    btnOK: TButton;\n    btnCancel: TButton;\n    tvRecords: TTreeView;\n    sbChoices: TScrollBox;\n    FlagIcons: TImageList;\n    StateImages: TImageList;\n    procedure DrawFlag(Canvas: TCanvas; var x, y: Integer; id: Integer);\n    procedure tvRecordsCustomDrawItem(Sender: TCustomTreeView;\n      Node: TTreeNode; State: TCustomDrawState; var DefaultDraw: Boolean);\n    procedure PopulateTree(sig: string; aSetting: TSmashSetting);\n    procedure ChoiceSelected(Sender: TObject);\n    procedure CreateChoicePanel(sig: string; var lst: TList);\n    procedure FormShow(Sender: TObject);\n    procedure FormCreate(Sender: TObject);\n    procedure btnOKClick(Sender: TObject);\n    procedure FormClose(Sender: TObject; var Action: TCloseAction);\n    procedure tvRecordsMouseMove(Sender: TObject; Shift: TShiftState; X,\n      Y: Integer);\n  private\n    { Private declarations }\n    lastHint: string;\n  public\n    // slConflicts is a stringlist of record signatures\n    // each signature has a TSmashSetting associated with it\n    // in slConflicts.Objects\n    // slConflicts may have duplicate signatures with different\n    // TSmashSetting objects\n    slConflicts: TStringList;\n  end;\n\nvar\n  ConflictForm: TConflictForm;\n  ChoicePanels, SelectedPanels: TList;\n\nimplementation\n\n{$R *.dfm}\n\nprocedure TConflictForm.DrawFlag(Canvas: TCanvas; var x, y: Integer; id: Integer);\nvar\n  icon: TIcon;\nbegin\n  if x < 30 then\n    exit;\n  icon := TIcon.Create;\n  FlagIcons.GetIcon(id, icon);\n  Canvas.Draw(x, y, icon);\n  Inc(x, 18);\n  icon.Free;\nend;\n\nprocedure TConflictForm.tvRecordsCustomDrawItem(Sender: TCustomTreeView;\n  Node: TTreeNode; State: TCustomDrawState; var DefaultDraw: Boolean);\nvar\n  e: TElementData;\n  R: TRect;\n  x, y: Integer;\nbegin\n  if Assigned(node.Data) then begin\n    e := TElementData(node.Data);\n    R := Node.DisplayRect(true);\n    x := R.Right + 6;\n    y := R.Top;\n\n    if e.preserveDeletions then\n      DrawFlag(Sender.Canvas, x, y, 0);\n    if e.singleEntity then\n      DrawFlag(Sender.Canvas, x, y, 1);\n    if (e.linkTo <> '') or (e.linkFrom <> '') then\n      DrawFlag(Sender.Canvas, x, y, 2);\n  end;\nend;\n\nprocedure TConflictForm.tvRecordsMouseMove(Sender: TObject; Shift: TShiftState;\n  X, Y: Integer);\nvar\n  node: TTreeNode;\n  e: TElementData;\n  sHint: string;\nbegin\n  // hide hint and exit if shift is down\n  if (ssShift in Shift) then begin\n    Application.HideHint;\n    exit;\n  end;\n\n  // draw hint if on a node with the link parameter\n  node := tvRecords.GetNodeAt(X, Y);\n  if not Assigned(node) then\n    exit;\n  e := TElementData(node.Data);\n  if not Assigned(e) then\n    exit;\n\n  // get hint\n  sHint := node.Text + #13#10'Type: '+stToString(e.smashType);\n  if e.linkTo <> '' then\n    sHint := sHint + #13#10'Linked to: '+e.linkTo;\n  if e.linkFrom <> '' then\n    sHint := sHint + #13#10'Linked from: '+e.linkFrom;\n\n  // display hint if it isn't the last hint we displayed\n  if sHint <> lastHint then begin\n    tvRecords.Hint := sHint;\n    Application.ActivateHint(Mouse.CursorPos);\n    lastHint := sHint;\n  end;\nend;\n\nprocedure TConflictForm.PopulateTree(sig: string; aSetting: TSmashSetting);\nvar\n  rootNode: TTreeNode;\n  item: ISuperObject;\nbegin\n  rootNode := tvRecords.Items[0];\n  for item in aSetting.tree['records'] do\n    if Copy(item.S['n'], 1, 4) = sig then begin\n      LoadElement(tvRecords, rootNode, item, false);\n      break;\n    end;\nend;\n\nprocedure TConflictForm.btnOKClick(Sender: TObject);\nvar\n  i: Integer;\n  aChoicePanel: TChoicePanel;\n  aSetting: TSmashSetting;\nbegin\n  // get user selection from choice panels, add it to slConflicts\n  // to be handled later\n  for i := 0 to Pred(ChoicePanels.Count) do begin\n    aChoicePanel := TChoicePanel(ChoicePanels[i]);\n    aSetting := aChoicePanel.GetSetting;\n    if Assigned(aSetting) then begin\n      DeleteMatchingItems(aChoicePanel.GetLabel, slConflicts);\n      slConflicts.AddObject(aChoicePanel.GetLabel, TObject(aSetting));\n    end;\n  end;\n\n  // close form with ModalResult = mrOK\n  ModalResult := mrOK;\nend;\n\nprocedure TConflictForm.ChoiceSelected(Sender: TObject);\nvar\n  i: Integer;\n  sig: string;\n  aChoicePanel: TChoicePanel;\n  aSetting: TSmashSetting;\nbegin\n  tvRecords.Items.Clear;\n  tvRecords.Items.Add(nil, 'Records');\n\n  // populate tree view with selected record nodes\n  for i := 0 to Pred(ChoicePanels.Count) do begin\n    aChoicePanel := TChoicePanel(ChoicePanels[i]);\n    if not aChoicePanel.Selected then\n      continue;\n    sig := aChoicePanel.GetLabel;\n    aSetting := aChoicePanel.GetSetting;\n    if Assigned(aSetting) then\n      PopulateTree(sig, aSetting);\n  end;\nend;\n\nprocedure TConflictForm.CreateChoicePanel(sig: string; var lst: TList);\nvar\n  aChoicePanel: TChoicePanel;\n  i: Integer;\nbegin\n  aChoicePanel := TChoicePanel.Create(sbChoices);\n  aChoicePanel.SetLabel(sig);\n  aChoicePanel.SetSelectCallback(ChoiceSelected);\n  aChoicePanel.SetTop(36 * ChoicePanels.Count);\n  for i := 0 to Pred(lst.Count) do\n    aChoicePanel.AddChoice(lst[i]);\n  ChoicePanels.Add(aChoicePanel);\nend;\n\nprocedure TConflictForm.FormClose(Sender: TObject; var Action: TCloseAction);\nbegin\n  FreeList(ChoicePanels);\nend;\n\nprocedure TConflictForm.FormCreate(Sender: TObject);\nbegin\n  ChoicePanels := TList.Create;\nend;\n\nprocedure TConflictForm.FormShow(Sender: TObject);\nvar\n  i, index: Integer;\n  aSetting: TSmashSetting;\n  sl: TStringList;\n  lst: TList;\nbegin\n  // construct a new stringlist that has each unique record signature\n  // paired with a list of all the settings that have that record signature\n  // (retrieved from slConflicts)\n  sl := TStringList.Create;\n  try\n    for i := 0 to Pred(slConflicts.Count) do begin\n      aSetting := TSmashSetting(slConflicts.Objects[i]);\n      index := sl.IndexOf(slConflicts[i]);\n      if index = -1 then\n        index := sl.AddObject(slConflicts[i], TObject(TList.Create));\n      lst := TList(sl.Objects[index]);\n      lst.Add(aSetting);\n    end;\n\n    // create choice panels\n    for i := 0 to Pred(sl.Count) do begin\n      lst := TList(sl.Objects[i]);\n      if lst.Count > 1 then\n        CreateChoicePanel(sl[i], lst);\n    end;\n  finally\n    // free memory\n    sl.Free;\n  end;\nend;\n\nend.\n"
  },
  {
    "path": "frontend/msCore.pas",
    "content": "unit msCore;\n\ninterface\n\nuses\n  Classes, Menus, ComCtrls, RegularExpressions,\n  // third party libraries\n  superobject,\n  // mte units\n  mteBase;\n\ntype\n  // SMASH CLASSES\n  TElementData = class(TObject)\n  public\n    priority: byte;\n    process: boolean;\n    preserveDeletions: boolean;\n    overrideDeletions: boolean;\n    forceValue: boolean;\n    singleEntity: boolean;\n    smashType: TSmashType;\n    linkTo: string;\n    linkFrom: string;\n    constructor Create; overload;\n    constructor Create(priority: byte; process, preserveDeletions,\n      overrideDeletions, singleEntity, forceValue: boolean;\n      smashType: TSmashType; linkTo, linkFrom: string); overload;\n  end;\n  TSmashSetting = class(TObject)\n  public\n    name: string;\n    hash: string;\n    description: string;\n    records: string;\n    tree: ISuperObject;\n    color: Int64;\n    bVirtual: boolean;\n    constructor Create;\n    destructor Destroy; override;\n    constructor Clone(s: TSmashSetting);\n    function GetRecordDef(sig: string): ISuperObject;\n    procedure LoadDump(dump: ISuperObject);\n    function Dump: ISuperObject;\n    procedure UpdateHash;\n    procedure UpdateRecords;\n    procedure Save;\n    procedure Delete;\n    procedure Rename(newName: string);\n    function MatchesHash(hash: string): boolean;\n    function GetTags: String;\n    function GetCombinedTags: String;\n  end;\n  {TRecommendation = class(TObject)\n  public\n    game: string;\n    username: string;\n    filename: string;\n    hash: string;\n    setting: string;\n    settingHash: string;\n    recordCount: integer;\n    rating: integer;\n    smashVersion: string;\n    notes: string;\n    dateSubmitted: TDateTime;\n    procedure SetNotes(notes: string);\n    function GetNotes: string;\n    procedure Save(const filename: string);\n  end; }\n  // SMASH CORE CLASSES\n  TPatchStatusID = ( psUnknown, psNoPlugins, psDirInvalid, psUnloaded,\n    psErrors, psFailed, psUpToDate, psUpToDateForced, psBuildReady,\n    psRebuildReady, psRebuildReadyForced );\n  TPatchStatus  = Record\n    id: TPatchStatusID;\n    color: integer;\n    desc: string[64];\n  end;\n  TPlugin = class(TBasePlugin)\n  public\n    setting: string;\n    smashSetting: TSmashSetting;\n    patch: string;\n    constructor Create; override;\n    procedure GetMsData;\n    procedure GetDataPath;\n    function GetFormIndex: Integer;\n    function IsInPatch: boolean;\n    procedure LoadInfoDump(obj: ISuperObject);\n    function InfoDump: ISuperObject;\n    function HasTags: Boolean;\n    procedure ApplySettingTags;\n    procedure SetSmashSetting(aSetting: TSmashSetting);\n    procedure LoadTags(sSettingName: String; var sl: TStringList;\n      var sTagGroup: String);\n    procedure GetSettingTag;\n    procedure WriteDescription;\n    procedure Save;\n  end;\n  TPatch = class(TObject)\n  public\n    name: string;\n    filename: string;\n    dateBuilt: TDateTime;\n    dataPath: string;\n    status: TPatchStatusID;\n    plugin: TPlugin;\n    plugins: TStringList;\n    hashes: TStringList;\n    smashSettings: TStringList;\n    masters: TStringList;\n    fails: TStringList;\n    constructor Create; virtual;\n    destructor Destroy; override;\n    function Dump: ISuperObject;\n    procedure LoadDump(obj: ISuperObject);\n    function GetTimeCost: integer;\n    procedure UpdateHashes;\n    procedure UpdateSettings;\n    procedure GetStatus;\n    procedure UpdateDataPath;\n    procedure GetLoadOrders;\n    procedure SortPlugins;\n    procedure Remove(plugin: TPlugin); overload;\n    procedure Remove(pluginFilename: string); overload;\n    function PluginsModified: boolean;\n    function FilesExist: boolean;\n    function GetStatusColor: integer;\n  end;\n  TSettingHelpers = class\n    class function SettingByName(name: String): TSmashSetting;\n    class function SettingByHash(hash: String): TSmashSetting;\n    class function GetSmashSetting(setting: string): TSmashSetting;\n  end;\n  TPatchHelpers = class\n    class function CreateNewPatch(var patches: TList): TPatch;\n    class function GetPatchForPlugin(filename: string): string;\n    class procedure AssignPatchesToPlugins;\n    class function PatchByName(var patches: TList; name: string): TPatch;\n    class function PatchByFilename(var patches: TList; filename: string): TPatch;\n  end;\n\n  // Loading/Saving Functions\n  procedure RenameSavedPlugins;\n  procedure SavePatches;\n  procedure LoadPatches;\n  procedure SaveSmashSettings;\n  procedure LoadSmashSettings;\n  procedure SavePluginInfo;\n  procedure LoadPluginInfo;\n  procedure LoadSettingTags;\n  // Helper Functions\n  procedure HandleCanceled(msg: string);\n\n  procedure UpdatePluginData;\n  function CreateNewPlugin(sFilename: string): TPlugin;\n  function PluginLoadOrder(sFilename: string): Integer;\n  function PluginByFilename(sFilename: string): TPlugin;\n  procedure PopulateAddList(var AddItem: TMenuItem; Event: TNotifyEvent);\n  procedure AddAllRecords(currentSetting: TSmashSetting; var tv: TTreeView);\n  procedure RemoveSettingFromPlugins(aSetting: TSmashSetting);\n  function GetTagString(var slTags: TStringList): String;\n  // Tree Helper Functions\n  procedure BuildTreeFromPlugins(var tv: TTreeView; var sl: TStringList;\n    tree: ISuperObject);\n  procedure SetChildren(node: TTreeNode; state: Integer);\n  procedure UpdateParent(node: TTreeNode);\n  procedure CheckBoxManager(node: TTreeNode);\n  procedure LoadElement(var tv: TTreeView; node: TTreeNode; obj: ISuperObject;\n    bWithinSingle: boolean);\n  procedure LoadTree(var tv: TTreeView; aSetting: TSmashSetting);\n  function GetRecordObject(tree: ISuperObject; sig: string): ISuperObject;\n  function GetChild(obj: ISuperObject; name: string): ISuperObject;\n  procedure MergeChildren(srcObj, dstObj: ISuperObject);\n  function CreateCombinedSetting(var sl: TStringList; name: string;\n    bVirtual: boolean = false): TSmashSetting;\n  function CombineSettingTrees(var lst: TList; var slSettings: TStringList): boolean;\n  // Tag Helper Functions\n  function ClearTags(sDescription: String): String;\n  procedure GetMissingTags(var slPresent, slMissing: TStringList);\n  procedure ExtractTags(var match: TMatch; var sl: TStringList;\n    var sTagGroup: String);\n  procedure ParseTags(description: string; var sl: TStringList);\n\n\nconst\n  // IMPORTANT CONSTANTS\n  ProgramTesters = ' ';\n  ProgramTranslators = ' ';\n  xEditVersion = '3.1.1';\n\n  // CHECKBOX STATES\n  csUnknown = 0;\n  csChecked = 1;\n  csUnChecked = 2;\n  csPartiallyChecked = 3;\n\n  // SMASH TYPE ARRAYS\n  stArrays = [ stUnsortedArray, stUnsortedStructArray,\n    stSortedArray, stSortedStructArray ];\n  stValues = [ stString, stFloat, stInteger, stByteArray ];\n\n  // PATCH STATUSES\n  StatusArray: array[0..10] of TPatchStatus = (\n    ( id: psUnknown; color: $808080; desc: 'Unknown'; ),\n    ( id: psNoPlugins; color: $0000FF; desc: 'Need two or more plugins to patch'; ),\n    ( id: psDirInvalid; color: $0000FF; desc: 'Directories invalid'; ),\n    ( id: psUnloaded; color: $0000FF; desc: 'Plugins not loaded'; ),\n    ( id: psErrors; color: $0000FF; desc: 'Errors in plugins'; ),\n    ( id: psFailed; color: $0000FF; desc: 'Patch failed'; ),\n    ( id: psUpToDate; color: $900000; desc: 'Up to date'; ),\n    ( id: psUpToDateForced; color: $900000; desc: 'Up to date [Forced]'; ),\n    ( id: psBuildReady; color: $009000; desc: 'Ready to be built'; ),\n    ( id: psRebuildReady; color: $009000; desc: 'Ready to be rebuilt'; ),\n    ( id: psRebuildReadyForced; color: $009000; desc: 'Ready to be rebuilt [Forced]'; )\n  );\n  // STATUS TYPES\n  ErrorStatuses = [psUnknown, psNoPlugins, psDirInvalid, psUnloaded, psErrors];\n  UpToDateStatuses = [psUpToDate, psUpToDateForced];\n  BuildStatuses = [psBuildReady, psRebuildReady, psRebuildReadyForced, psFailed];\n  RebuildStatuses = [psRebuildReady, psRebuildReadyForced, psFailed];\n  ForcedStatuses = [psUpToDateForced, psRebuildReadyForced];\n  ResolveStatuses = [psNoPlugins, psDirInvalid, psUnloaded, psErrors];\n  FailedStatuses = [psFailed];\n\nvar\n  PatchesList, SmashSettings, pluginsToHandle, patchesToBuild: TList;\n  ActiveMods, SavedPluginPaths: TStringList;\n  ActiveModProfile, xEditLogGroup, xEditLogLabel, DictionaryFilename: string;\n\nimplementation\n\nuses\n  Windows, SysUtils, Dialogs, Graphics,\n  // mte units\n  mteLogger, mteTracker, mteHelpers, mteLogging, RttiJson, CRC32,\n  // mp units\n  msConfiguration,\n  // xEdit units\n  wbInterface, wbImplementation;\n\n{ TPlugin Constructor }\nconstructor TPlugin.Create;\nbegin\n  patch := ' ';\n  inherited;\nend;\n\n{ Fetches data associated with a plugin. }\nprocedure TPlugin.GetMsData;\nbegin\n  hasData := true;\n\n  // get data path and hash\n  GetDataPath;\n  GetHash;\n\n   // get numOverrides if not blacklisted\n  if (numRecords < 10000) then\n    numOverrides := CountOverrides(_File);\n\n  // call get data method\n  GetData(PluginsList);\nend;\n\nprocedure TPlugin.GetDataPath;\nbegin\n  dataPath := wbDataPath;\nend;\n\nfunction TPlugin.GetFormIndex: Integer;\nvar\n  Container, MasterFiles: IwbContainer;\nbegin\n  Result := 0;\n  Container := self._File as IwbContainer;\n  Container := Container.Elements[0] as IwbContainer;\n  if Container.ElementExists['Master Files'] then begin\n    MasterFiles := Container.ElementByPath['Master Files'] as IwbContainer;\n    Result := MasterFiles.ElementCount;\n  end;\nend;\n\nfunction TPlugin.IsInPatch: boolean;\nbegin\n  Result := patch <> ' ';\nend;\n\nfunction TPlugin.InfoDump: ISuperObject;\nvar\n  obj: ISuperObject;\nbegin\n  obj := SO;\n\n  // filename, hash, errors\n  obj.S['filename'] := filename;\n  obj.S['hash'] := hash;\n  obj.S['setting'] := setting;\n\n  Result := obj;\nend;\n\nprocedure TPlugin.LoadInfoDump(obj: ISuperObject);\nvar\n  aSetting: TSmashSetting;\nbegin\n  aSetting := TSettingHelpers.SettingByName(obj.AsObject.S['setting']);\n  SetSmashSetting(aSetting);\nend;\n\nprocedure TPlugin.SetSmashSetting(aSetting: TSmashSetting);\nbegin\n  if not Assigned(aSetting) then begin\n    setting := 'Skip';\n    smashSetting := TSettingHelpers.SettingByName(setting);\n  end\n  else begin\n    setting := aSetting.name;\n    smashSetting := aSetting;\n    Logger.Write('PLUGIN', 'Settings', 'Using '+setting+' for '+filename);\n  end;\nend;\n\nfunction TPlugin.HasTags: Boolean;\nvar\n  regex: TRegex;\n  match: TMatch;\nbegin\n  regex := TRegEx.Create('{{([a-zA-Z]{1,10}:){0,1}([^}]*)}}');\n  match := regex.Match(description.Text);\n  Result := match.Success;\nend;\n\nprocedure TPlugin.ApplySettingTags;\nvar\n  sTags: String;\nbegin\n  description.Text := ClearTags(description.Text);\n  sTags := smashSetting.GetTags;\n\n  // write tags to the description\n  description.Add(' ');\n  description.Add(sTags);\n  description.Text := Trim(description.Text);\n  WriteDescription;\nend;\n\nprocedure TPlugin.LoadTags(sSettingName: String; var sl: TStringList;\n  var sTagGroup: String);\nvar\n  slRecords: TStringList;\n  aSetting: TSmashSetting;\n  settingsToCombine: TList;\n  i: Integer;\nbegin\n  // if only one setting present, use it\n  if sl.Count = 1 then begin\n    aSetting := TSettingHelpers.GetSmashSetting(sl[0]);\n    SetSmashSetting(aSetting);\n  end\n  // else make a combined setting\n  else begin\n    settingsToCombine := TList.Create;\n\n    // loop through found settings\n    for i := Pred(sl.Count) downto 0 do begin\n      aSetting := TSettingHelpers.GetSmashSetting(sl[i]);\n      if not Assigned(aSetting) then begin\n        sl.Delete(i);\n        continue;\n      end;\n      settingsToCombine.Add(aSetting);\n    end;\n\n    // if settingsToCombine has 0 settings, set to skip setting\n    if settingsToCombine.Count = 0 then\n      SetSmashSetting(nil)\n    // if settingToCombine has only 1 setting, use that setting\n    else if settingsToCombine.Count = 1 then\n      SetSmashSetting(settingsToCombine[0])\n    // else build a combined setting\n    else begin\n      Logger.Write('PLUGIN', 'Settings', 'Building combined setting');\n      slRecords := TStringList.Create;\n      CombineSettingTrees(settingsToCombine, slRecords);\n      if sTagGroup <> '' then\n        sSettingName := sTagGroup + '.' + sSettingName;\n      aSetting := CreateCombinedSetting(slRecords, sSettingName, true);\n      SetSmashSetting(aSetting);\n    end;\n  end;\nend;\n\nprocedure TPlugin.GetSettingTag;\nvar\n  regex: TRegEx;\n  match: TMatch;\n  sTagGroup: String;\n  sl: TStringList;\nbegin\n  // get setting tags from description\n  regex := TRegEx.Create('{{([a-zA-Z]{1,10}:){0,1}([^}]*)}}');\n  match := regex.Match(description.Text);\n  sl := TStringList.Create;\n\n  // set to skip setting if no tag is found\n  if not match.Success then begin\n    Logger.Write('PLUGIN', 'Tags', 'No tags found for '+filename);\n    setting := 'Skip';\n    smashSetting := TSettingHelpers.SettingByName(setting);\n  end\n  // else parse settings from tag\n  else begin\n    Logger.Write('PLUGIN', 'Tags', 'Found tag '+match.Value+' for '+filename);\n    ExtractTags(match, sl, sTagGroup);\n    LoadTags(match.Groups.Item[2].Value, sl, sTagGroup);\n  end;\n\n  // free memory\n  sl.Free;\nend;\n\nprocedure TPlugin.WriteDescription;\nvar\n  Container: IwbContainer;\nbegin\n  Container := _File as IwbContainer;\n  Container := Container.Elements[0] as IwbContainer;\n  Container.SetElementEditValue('SNAM - Description', description.Text);\nend;\n\nprocedure TPlugin.Save;\nvar\n  path: string;\n  FileStream: TFileStream;\nbegin\n  // save plugin\n  path := dataPath + filename + '.save';\n  Tracker.Write(' ');\n  Tracker.Write('Saving: ' + path);\n  Logger.Write('PLUGIN', 'Save', path);\n  FileStream := nil;\n  try\n    FileStream := TFileStream.Create(path, fmCreate);\n    _File.WriteToStream(FileStream, False);\n    if SavedPluginPaths.IndexOf(path) = -1 then\n      SavedPluginPaths.Add(dataPath + filename);\n  except\n    on x: Exception do\n      Tracker.Write('Failed to save: '+x.Message);\n  end;\n  TryToFree(FileStream);\nend;\n\n{ TPatch Constructor }\nconstructor TPatch.Create;\nbegin\n  name := 'NewPatch';\n  filename := 'NewPatch.esp';\n  status := psUnknown;\n  dateBuilt := 0;\n  plugins := TStringList.Create;\n  hashes := TStringList.Create;\n  smashSettings := TStringList.Create;\n  masters := TStringList.Create;\n  fails := TStringList.Create;\nend;\n\ndestructor TPatch.Destroy;\nbegin\n  plugins.Free;\n  hashes.Free;\n  smashSettings.Free;\n  masters.Free;\n  fails.Free;\n  inherited;\nend;\n\n\n{ Produces a dump of the patch. }\nfunction TPatch.Dump: ISuperObject;\nvar\n  obj: ISuperObject;\n  i: integer;\nbegin\n  obj := SO;\n\n  // normal attributes\n  obj.S['name'] := name;\n  obj.S['filename'] := filename;\n  obj.S['dateBuilt'] := DateTimeToStr(dateBuilt);\n\n  // plugins, pluginHashes, pluginSettings, masters\n  obj.O['plugins'] := SA([]);\n  for i := 0 to Pred(plugins.Count) do\n    obj.A['plugins'].S[i] := plugins[i];\n  obj.O['pluginHashes'] := SA([]);\n  for i := 0 to Pred(hashes.Count) do\n    obj.A['pluginHashes'].S[i] := hashes[i];\n  obj.O['pluginSettings'] := SA([]);\n  for i := 0 to Pred(smashSettings.Count) do\n    obj.A['pluginSettings'].S[i] := smashSettings[i];\n  obj.O['masters'] := SA([]);\n  for i := 0 to Pred(masters.Count) do\n    obj.A['masters'].S[i] := masters[i];\n\n  // files, log, ignored dependencies\n  obj.O['fails'] := SA([]);\n  for i := 0 to Pred(fails.Count) do\n    obj.A['fails'].S[i] := fails[i];\n\n  Result := obj;\nend;\n\n{ Loads a dump of a patch. }\nprocedure TPatch.LoadDump(obj: ISuperObject);\nvar\n  item: ISuperObject;\nbegin\n  // load object attributes\n  name := obj.AsObject.S['name'];\n  filename := obj.AsObject.S['filename'];\n\n  // try loading dateBuilt and parsing to DateTime\n  try\n    dateBuilt := StrToDateTime(obj.AsObject.S['dateBuilt']);\n  except on Exception do\n    dateBuilt := 0; // on exception set to never built\n  end;\n\n  // load array attributes\n  for item in obj['plugins'] do\n    plugins.Add(item.AsString);\n  for item in obj['pluginHashes'] do\n    hashes.Add(item.AsString);\n  try\n    for item in obj['pluginSettings'] do\n      smashSettings.Add(item.AsString);\n  except\n    on x: Exception do\n      // nothing\n  end;\n  for item in obj['masters'] do\n    masters.Add(item.AsString);\n  for item in obj['fails'] do\n    fails.Add(item.AsString);\nend;\n\nfunction TPatch.GetTimeCost: integer;\nvar\n  i: Integer;\n  plugin: TPlugin;\nbegin\n  Result := 10000;\n  for i := 0 to Pred(plugins.Count) do begin\n    plugin := PluginByFilename(plugins[i]);\n    if Assigned(plugin) then\n      Inc(Result, plugin._File.RecordCount);\n  end;\nend;\n\n// Checks to see if the plugins in a patch have been modified since it was last\n// patchd.\nfunction TPatch.PluginsModified: boolean;\nvar\n  plugin: TPlugin;\n  i: integer;\nbegin\n  Result := false;\n  // true if number of hashes not equal to number of plugins\n  if (plugins.Count <> hashes.Count)\n  or (plugins.Count <> smashSettings.Count) then begin\n    Logger.Write('PATCH', 'Status', name + ' -> Plugin count changed');\n    Result := true;\n    exit;\n  end;\n  // true if any plugin hash doesn't match\n  for i := 0 to Pred(plugins.count) do begin\n    plugin := PluginByFilename(plugins[i]);\n    if Assigned(plugin) then begin\n      if plugin.hash <> hashes[i] then begin\n        Logger.Write('PATCH', 'Status', name + ' -> '+plugin.filename + ' hash changed.');\n        Result := true;\n      end;\n    end;\n  end;\n  // true if any plugin setting doesn't match\n  for i := 0 to Pred(plugins.count) do begin\n    plugin := PluginByFilename(plugins[i]);\n    if Assigned(plugin) then begin\n      if plugin.setting <> smashSettings[i] then begin\n        Logger.Write('PATCH', 'Status', name + ' -> '+plugin.filename + ' smash setting changed.');\n        Result := true;\n      end;\n    end;\n  end;\nend;\n\n// Checks if the files associated with a patch exist\nfunction TPatch.FilesExist: boolean;\nbegin\n  Result := FileExists(dataPath + filename);\nend;\n\nprocedure TPatch.UpdateDataPath;\nbegin\n  dataPath := settings.patchDirectory;\n  if not SameText(dataPath, wbDataPath) then\n    dataPath := dataPath + name + '\\';\nend;\n\nprocedure TPatch.GetStatus;\nvar\n  i: Integer;\n  plugin: TPlugin;\nbegin\n  Logger.Write('PATCH', 'Status', name + ' -> Getting status');\n  status := psUnknown;\n\n  // don't patch if there aren't two or more plugins to patch\n  if (plugins.Count < 2) then begin\n    Logger.Write('PATCH', 'Status', name + ' -> Need two or more plugins to patch');\n    status := psNoPlugins;\n    exit;\n  end;\n\n  // don't patch if mod destination directory is blank\n  if (settings.patchDirectory = '') then begin\n    Logger.Write('PATCH', 'Status', name + ' -> Patch directory blank');\n    status := psDirInvalid;\n    exit;\n  end;\n\n  // update the patch's data path\n  UpdateDataPath;\n\n  // loop through plugins\n  for i := 0 to Pred(plugins.Count) do begin\n    plugin := PluginByFilename(plugins[i]);\n\n    // see if plugin is loaded\n    if not Assigned(plugin) then begin\n      Logger.Write('PATCH', 'Status', name + ' -> Plugin '+plugins[i]+' is missing');\n      if status = psUnknown then status := psUnloaded;\n      continue;\n    end;\n  end;\n\n  // check plugins were modified or files were deleted before\n  // giving patch the up to date status\n  if (not PluginsModified) and FilesExist and (status = psUnknown) then begin\n    Logger.Write('PATCH', 'Status', name + ' -> Up to date');\n    status := psUpToDate;\n  end;\n\n  // status green, ready to go\n  if status = psUnknown then begin\n    Logger.Write('PATCH', 'Status', name + ' -> Ready to be patchd');\n    if dateBuilt = 0 then\n      status := psBuildReady\n    else\n      status := psRebuildReady;\n  end;\nend;\n\nfunction TPatch.GetStatusColor: integer;\nbegin\n  Result := StatusArray[Ord(status)].color;\nend;\n\n// Update the hashes list for the plugins in the patch\nprocedure TPatch.UpdateHashes;\nvar\n  i: Integer;\n  aPlugin: TPlugin;\nbegin\n  hashes.Clear;\n  for i := 0 to Pred(plugins.Count) do begin\n    aPlugin := PluginByFilename(plugins[i]);\n    if Assigned(aPlugin) then\n      hashes.Add(aPlugin.hash);\n  end;\nend;\n\n// Update the settings list for the plugins in the patch\nprocedure TPatch.UpdateSettings;\nvar\n  i: Integer;\n  aPlugin: TPlugin;\nbegin\n  smashSettings.Clear;\n  for i := 0 to Pred(plugins.Count) do begin\n    aPlugin := PluginByFilename(plugins[i]);\n    if Assigned(aPlugin) then\n      smashSettings.Add(aPlugin.setting);\n  end;\nend;\n\n// Get load order for plugins in patch that don't have it\nprocedure TPatch.GetLoadOrders;\nvar\n  i: integer;\nbegin\n  for i := 0 to Pred(plugins.Count) do\n    if not Assigned(plugins.Objects[i]) then\n      plugins.Objects[i] := TObject(PluginLoadOrder(plugins[i]));\nend;\n\n// Sort plugins by load order position\nprocedure TPatch.SortPlugins;\nbegin\n  GetLoadOrders;\n  plugins.CustomSort(LoadOrderCompare);\nend;\n\nprocedure TPatch.Remove(plugin: TPlugin);\nvar\n  index: Integer;\nbegin\n  // clear plugin's patch property, if it's the name of this patch\n  if plugin.patch = name then\n    plugin.patch := ' ';\n  // remove plugin from patch, if present\n  index := plugins.IndexOf(plugin.filename);\n  if index > -1 then\n    plugins.Delete(index);\nend;\n\nprocedure TPatch.Remove(pluginFilename: string);\nvar\n  index: Integer;\nbegin\n  index := plugins.IndexOf(pluginFilename);\n  // remove plugin from patch, if present\n  if index > -1 then\n    plugins.Delete(index);\nend;\n\n{ TSettingHelpers }\n\n{ Gets a smash setting matching the given name. }\nclass function TSettingHelpers.SettingByName(name: string): TSmashSetting;\nvar\n  i: integer;\n  aSetting: TSmashSetting;\nbegin\n  Result := nil;\n  for i := 0 to Pred(SmashSettings.Count) do begin\n    aSetting := TSmashSetting(SmashSettings[i]);\n    if aSetting.name = name then begin\n      Result := aSetting;\n      exit;\n    end;\n  end;\nend;\n\n{ Gets a smash setting matching the given hash. }\nclass function TSettingHelpers.SettingByHash(hash: string): TSmashSetting;\nvar\n  i: integer;\n  aSetting: TSmashSetting;\nbegin\n  Result := nil;\n  for i := 0 to Pred(SmashSettings.Count) do begin\n    aSetting := TSmashSetting(SmashSettings[i]);\n    if aSetting.MatchesHash(hash) then begin\n      Result := aSetting;\n      exit;\n    end;\n  end;\nend;\n\n{ Gets a smash setting matching a name or hash }\nclass function TSettingHelpers.GetSmashSetting(setting: string): TSmashSetting;\nvar\n  sl: TStringList;\n  smashSetting: TSmashSetting;\nbegin\n  // default result\n  Result := nil;\n\n  // parse setting name and hash\n  if Pos('|', setting) > 0 then begin\n    sl := TStringList.Create;\n    try\n      sl.Delimiter := '|';\n      sl.StrictDelimiter := true;\n      sl.DelimitedText := setting;\n\n      // if we have a setting name, use it to get a smash setting\n      if Length(sl[0]) > 0 then begin\n        smashSetting := SettingByName(sl[0]);\n        // and return it if the hash matches\n        if Assigned(smashSetting) and smashSetting.MatchesHash(sl[1]) then\n          Result := smashSetting;\n      end\n      // else just get the setting from the hash\n      else\n        Result := SettingByHash(sl[1]);\n    finally\n      sl.Free;\n    end;\n  end\n  // else just return SettingByName\n  else\n    Result := SettingByName(setting);\nend;\n\n{ TPatchHelpers }\n\nclass function TPatchHelpers.GetPatchForPlugin(filename: string): string;\nvar\n  i: Integer;\n  patch: TPatch;\nbegin\n  Result := ' ';\n  for i := 0 to Pred(PatchesList.Count) do begin\n    patch := TPatch(PatchesList[i]);\n    if patch.plugins.IndexOf(filename) > -1 then begin\n      Result := patch.name;\n      break;\n    end;\n  end;\nend;\n\nclass procedure TPatchHelpers.AssignPatchesToPlugins;\nvar\n  i, j: Integer;\n  patch: TPatch;\n  plugin: TPlugin;\nbegin\n  for i := 0 to Pred(PatchesList.Count) do begin\n    patch := TPatch(PatchesList[i]);\n    for j := 0 to Pred(patch.plugins.Count) do begin\n      plugin := PluginByFilename(patch.plugins[j]);\n      if Assigned(plugin) then\n        plugin.patch := patch.name;\n    end;\n  end;\nend;\n\n{ Gets a patch matching the given name. }\nclass function TPatchHelpers.PatchByName(var patches: TList; name: string): TPatch;\nvar\n  i: integer;\n  patch: TPatch;\nbegin\n  Result := nil;\n  for i := 0 to Pred(patches.Count) do begin\n    patch := TPatch(patches[i]);\n    if patch.name = name then begin\n      Result := patch;\n      exit;\n    end;\n  end;\nend;\n\n\n{ Gets a patch matching the given filename. }\nclass function TPatchHelpers.PatchByFilename(var patches: TList; filename: string): TPatch;\nvar\n  i: integer;\n  patch: TPatch;\nbegin\n  Result := nil;\n  for i := 0 to Pred(patches.Count) do begin\n    patch := TPatch(patches[i]);\n    if patch.filename = filename then begin\n      Result := patch;\n      exit;\n    end;\n  end;\nend;\n\n{ Create a new patch with non-conflicting name and filename }\nclass function TPatchHelpers.CreateNewPatch(var patches: TList): TPatch;\nvar\n  i: Integer;\n  patch: TPatch;\n  name: string;\nbegin\n  patch := TPatch.Create;\n\n  // deal with conflicting patch names\n  i := 0;\n  name := patch.name;\n  while Assigned(PatchByName(patches, name)) do begin\n    Inc(i);\n    name := 'NewPatch' + IntToStr(i);\n  end;\n  patch.name := name;\n\n  // deal with conflicting patch filenames\n  i := 0;\n  name := patch.filename;\n  while Assigned(PatchByFilename(patches, name)) do begin\n    Inc(i);\n    name := 'NewPatch' + IntToStr(i) + '.esp';\n  end;\n  patch.filename := name;\n\n  Result := patch;\nend;\n\n{ TElementData }\n\nconstructor TElementData.Create;\nbegin\n  self.priority := 0;\n  self.smashType := TSmashType(0);\n  self.linkTo := '';\n  self.linkFrom := '';\nend;\n\nconstructor TElementData.Create(priority: Byte; process, preserveDeletions,\n  overrideDeletions, singleEntity, forceValue: Boolean; smashType: TSmashType;\n  linkTo, linkFrom: string);\nbegin\n  self.priority := priority;\n  self.process := process;\n  self.preserveDeletions := preserveDeletions;\n  self.overrideDeletions := overrideDeletions;\n  self.singleEntity := singleEntity;\n  self.forceValue := forceValue;\n  self.smashType := smashType;\n  self.linkTo := linkTo;\n  self.linkFrom := linkFrom;\nend;\n\n{ TSmashSetting }\nfunction GetUniqueSettingName(base: string): string;\nvar\n  i: Integer;\nbegin\n  Result := base;\n  i := 1;\n  while Assigned(TSettingHelpers.SettingByName(Result)) do begin\n    Inc(i);\n    Result := base + IntToStr(i);\n  end;\nend;\n\nconstructor TSmashSetting.Create;\nbegin\n  name := GetUniqueSettingName('NewSetting');\n  hash := '$00000000';\n  color := clBlack;\n  description := '';\n  records := '';\n  tree := SO;\n  tree.O['records'] := SA([]);\nend;\n\ndestructor TSmashSetting.Destroy;\nbegin\n  name := '';\n  hash := '';\n  color := 0;\n  description := '';\n  records := '';\n  if Assigned(tree) then tree._Release;\n  tree := nil;\nend;\n\nconstructor TSmashSetting.Clone(s: TSmashSetting);\nbegin\n  name := GetUniqueSettingName(s.name + '-Clone');\n  hash := '$00000000';\n  color := s.color;\n  records := s.records;\n  description := s.description;\n  tree := s.tree.Clone;\nend;\n\nfunction TSmashSetting.GetRecordDef(sig: string): ISuperObject;\nbegin\n  Result := nil;\n  if not Assigned(tree) then\n    exit;\n  Result := GetRecordObj(tree, sig);\nend;\n\nprocedure TSmashSetting.LoadDump(dump: ISuperObject);\nbegin\n  name := dump.S['name'];\n  color := dump.I['color'];\n  hash := dump.S['hash'];\n  description := dump.S['description'];\n  records := dump.S['records'];\n  tree := dump.O['tree'];\nend;\n\nfunction TSmashSetting.Dump: ISuperObject;\nvar\n  obj: ISuperObject;\nbegin\n  obj := SO;\n\n  // tree\n  obj.O['tree'] := tree;\n  // normal attributes\n  obj.S['records'] := records;\n  obj.S['description'] := description;\n  obj.I['color'] := color;\n  obj.S['hash'] := hash;\n  obj.S['name'] := name;\n\n  Result := obj;\nend;\n\nprocedure TSmashSetting.UpdateHash;\nbegin\n  hash := StrCRC32(tree.AsJSon);\nend;\n\nprocedure TSmashSetting.UpdateRecords;\nvar\n  item: ISuperObject;\n  sl: TStringList;\nbegin\n  // prepare comma delimited stringlist\n  sl := TStringList.Create;\n  sl.Delimiter := ',';\n  sl.StrictDelimiter := true;\n\n  try\n    // loop through records and add their signatures\n    // to the stringlist if they are set to be processed\n    for item in tree['records'] do begin\n      if item.I['p'] = 1 then\n        sl.Add(Copy(item.S['n'], 1, 4));\n    end;\n\n    // assign records the delimited signatures\n    records := sl.DelimitedText;\n  finally\n    // free memory\n    sl.Free;\n  end;\nend;\n\nprocedure TSmashSetting.Save;\nvar\n  path: string;\nbegin\n  UpdateHash;\n  path := Format('%s\\settings\\%s\\%s.json',\n    [PathList.Values['ProgramPath'], ProgramStatus.GameMode.gameName, name]);\n  ForceDirectories(ExtractFilePath(path));\n  Dump.SaveTo(path);\nend;\n\nprocedure TSmashSetting.Delete;\nvar\n  path: string;\nbegin\n  path := Format('%s\\settings\\%s\\%s.json',\n    [PathList.Values['ProgramPath'], ProgramStatus.GameMode.gameName, name]);\n  if FileExists(path) then\n    DeleteToRecycleBin(path, false);\nend;\n\nprocedure TSmashSetting.Rename(newName: string);\nvar\n  oldPath, newPath: string;\nbegin\n  oldPath := Format('%s\\settings\\%s\\%s.json',\n    [PathList.Values['ProgramPath'], ProgramStatus.GameMode.gameName, name]);\n  newPath := Format('%s\\settings\\%s\\%s.json',\n    [PathList.Values['ProgramPath'], ProgramStatus.GameMode.gameName, newName]);\n  if FileExists(oldpath) then\n    RenameFile(oldpath, newpath);\n  name := newName;\nend;\n\nfunction TSmashSetting.MatchesHash(hash: string): boolean;\nbegin\n  // result is true if hash is blank\n  if hash = '' then begin\n    Result := true;\n    exit;\n  end;\n\n  // else result is true if the input hash matches setting's hash\n  // starting at the first hexadecimal digit\n  Result := Pos(hash, self.hash) = 2;\nend;\n\nfunction TSmashSetting.GetTags: String;\nvar\n  index: Integer;\nbegin\n  if Pos('Combined setting:', description) = 1 then\n      Result := GetCombinedTags\n  // else handle a normal setting\n  else begin\n    index := Pos('.', name);\n    if (index > 0) and (index < 11) then\n      Result := Format('{{%s}}', [StringReplace(name, '.', ':', [])])\n    else\n      Result := Format('{{%s}}', [name]);\n  end;\nend;\n\nfunction TSmashSetting.GetCombinedTags: String;\nvar\n  sl, slTags: TStringList;\nbegin\n  Result := '';\n  sl := TStringList.Create;\n  slTags := TStringList.Create;\n  try\n    sl.Text := description;\n    // parse tags from description\n    slTags.CommaText := sl[1];\n\n    // return tag string\n    Result := GetTagString(slTags);\n  finally\n    sl.Free;\n    slTags.Free;\n  end;\nend;\n\nprocedure SavePatches;\nvar\n  i: Integer;\n  patch: TPatch;\n  json: ISuperObject;\n  filename: string;\nbegin\n  // initialize json\n  json := SO;\n  json.O['patches'] := SA([]);\n\n  // loop through patches\n  Tracker.Write(' ');\n  Tracker.Write('Dumping patches to JSON');\n  for i := 0 to Pred(PatchesList.Count) do begin\n    Tracker.UpdateProgress(1);\n    patch := TPatch(PatchesList[i]);\n    Tracker.Write('  Dumping '+patch.name);\n    json.A['patches'].Add(patch.Dump);\n  end;\n\n  // save and finalize\n  filename := PathList.Values['ProfilePath'] + 'Patches.json';\n  Tracker.Write(' ');\n  Tracker.Write('Saving to ' + filename);\n  Tracker.UpdateProgress(1);\n  json.SaveTo(filename);\n  json := nil;\nend;\n\nprocedure LoadPatches;\nconst\n  debug = false;\nvar\n  patch: TPatch;\n  obj, patchItem: ISuperObject;\n  sl: TStringList;\n  filename: string;\nbegin\n  // don't load file if it doesn't exist\n  filename := PathList.Values['ProfilePath'] + 'Patches.json';\n  if not FileExists(filename) then\n    exit;\n  // load file into SuperObject to parse it\n  sl := TStringList.Create;\n  sl.LoadFromFile(filename);\n  obj := SO(PChar(sl.Text));\n\n  // loop through patches\n  for patchItem in obj['patches'] do begin\n    patch := TPatch.Create;\n    try\n      patch.LoadDump(patchItem);\n      PatchesList.Add(patch);\n    except\n      on x: Exception do begin\n        Logger.Write('LOAD', 'Patch', 'Failed to load patch '+patch.name);\n        Logger.Write('LOAD', 'Patch', x.Message);\n      end;\n    end;\n  end;\n\n  // finalize\n  obj := nil;\n  sl.Free;\nend;\n\nfunction IndexOfDump(a: TSuperArray; plugin: TPlugin): Integer;\nvar\n  i: Integer;\n  obj: ISuperObject;\nbegin\n  Result := -1;\n  for i := 0 to Pred(a.Length) do begin\n    obj := a.O[i];\n    if (obj.S['filename'] = plugin.filename)\n    and (obj.S['hash'] = plugin.hash) then begin\n      Result := i;\n      exit;\n    end;\n  end;\nend;\n\nprocedure SaveSmashSettings;\nvar\n  aSetting: TSmashSetting;\n  i: Integer;\nbegin\n  Tracker.Write('Saving smash settings');\n  for i := 0 to Pred(SmashSettings.Count) do begin\n    aSetting := TSmashSetting(SmashSettings[i]);\n    if aSetting.bVirtual then\n      continue;\n    Tracker.Write('  Saving '+aSetting.name);\n    aSetting.Save;\n  end;\n  Tracker.Write(' ');\nend;\n\nprocedure CreateSkipSetting;\nvar\n  skipSetting: TSmashSetting;\n  index: Integer;\nbegin\n  index := SmashSettings.Add(TSmashSetting.Create);\n  skipSetting := SmashSettings[index];\n  skipSetting.name := 'Skip';\n  skipSetting.color := clGray;\n  skipSetting.description := 'Special setting.  Any plugin with this setting '+\n    'will be excluded from patch creation.';\n  skipSetting.tree := SO();\n  skipSetting.tree.O['records'] := SA([]);\nend;\n\nprocedure LoadSmashSettings;\nvar\n  info: TSearchRec;\n  obj: ISuperObject;\n  sl: TStringList;\n  aSetting: TSmashSetting;\n  path: String;\nbegin\n  path := Format('%ssettings\\%s\\', [PathList.Values['ProgramPath'], ProgramStatus.GameMode.gameName]);\n  ForceDirectories(path);\n\n  // load setting files from settings path\n  if FindFirst(path + '*.json', faAnyFile, info) <> 0 then\n    exit;\n  repeat\n    sl := TStringList.Create;\n    try\n      sl.LoadFromFile(path + info.Name);\n      aSetting := TSmashSetting.Create;\n      obj := SO(PChar(sl.Text));\n      if Assigned(obj) then begin\n        aSetting.LoadDump(obj);\n        if aSetting.name <> '' then\n          SmashSettings.Add(aSetting);\n      end;\n      sl.Free;\n      obj := nil;\n    except\n      on x: Exception do begin\n        if Assigned(sl) then sl.Free;\n        obj := nil;\n        Logger.Write('ERROR', 'Load', 'Failed to load smash setting '+info.Name);\n      end;\n    end;\n  until FindNext(info) <> 0;\n\n  // create skip setting if it isn't assigned\n  if TSettingHelpers.SettingByName('Skip') = nil then\n    CreateSkipSetting;\nend;\n\nprocedure SavePluginInfo;\nvar\n  i, index: Integer;\n  plugin: TPlugin;\n  obj: ISuperObject;\n  filename: string;\n  sl: TStringList;\nbegin\n  // don't load file if it doesn't exist\n  filename := PathList.Values['ProfilePath'] + 'PluginInfo.json';\n  if FileExists(filename) then begin\n    // load file text into SuperObject to parse it\n    sl := TStringList.Create;\n    sl.LoadFromFile(filename);\n    obj := SO(PChar(sl.Text));\n    sl.Free;\n  end\n  else begin\n    // initialize new json object\n    obj := SO;\n    obj.O['plugins'] := SA([]);\n  end;\n\n  // loop through plugins\n  Tracker.Write('Dumping plugin errors to JSON');\n  for i := 0 to Pred(PluginsList.Count) do try\n    plugin := PluginsList[i];\n    Tracker.UpdateProgress(1);\n    if not Assigned(plugin.smashSetting) then\n      continue;\n  \tindex := IndexOfDump(obj.A['plugins'], plugin);\n    if plugin.smashSetting.bVirtual or (plugin.setting = 'Skip') then begin\n\t    if index <> -1 then\n\t      obj.A['plugins'].Delete(index);\n\t    continue;\n    end;\n    Tracker.Write('  Dumping '+plugin.filename);\n    if index = -1 then\n      obj.A['plugins'].Add(plugin.InfoDump)\n    else\n      obj.A['plugins'].O[index] := plugin.InfoDump;\n  except\n    on x: Exception do\n      Tracker.Write('  Exception '+x.Message);\n  end;\n\n  // save and finalize\n  Tracker.Write(' ');\n  filename := PathList.Values['ProfilePath'] + 'PluginInfo.json';\n  Tracker.Write('Saving to '+filename);\n  Tracker.UpdateProgress(1);\n  obj.SaveTo(filename);\n  obj := nil;\nend;\n\nprocedure LoadPluginInfo;\nvar\n  plugin: TPlugin;\n  obj, pluginItem: ISuperObject;\n  sl: TStringList;\n  filename, hash: string;\nbegin\n  // don't load file if it doesn't exist\n  filename := PathList.Values['ProfilePath'] + 'PluginInfo.json';\n  if not FileExists(filename) then\n    exit;\n  // load file into SuperObject to parse it\n  sl := TStringList.Create;\n  sl.LoadFromFile(filename);\n  obj := SO(PChar(sl.Text));\n\n  // loop through patches\n  filename := '';\n  for pluginItem in obj['plugins'] do begin\n    filename := pluginItem.AsObject.S['filename'];\n    hash := pluginItem.AsObject.S['hash'];\n    plugin := PluginByFileName(filename);\n    if not Assigned(plugin) then\n      continue;\n    if (plugin.hash = hash) and (plugin.filename = filename) then\n      plugin.LoadInfoDump(pluginItem);\n  end;\n\n  // finalize\n  obj := nil;\n  sl.Free;\nend;\n\nprocedure LoadSettingTags;\nvar\n  i: Integer;\n  plugin: TPlugin;\nbegin\n  // loop through loaded plugins\n  for i := 0 to Pred(PluginsList.Count) do begin\n    plugin := TPlugin(PluginsList[i]);\n    if plugin.setting <> '' then\n      continue;\n    plugin.GetSettingTag;\n  end;\nend;\n\nprocedure HandleCanceled(msg: string);\nbegin\n  if Tracker.Cancel then\n    raise Exception.Create(msg);\nend;\n\nprocedure RenameSavedPlugins;\nvar\n  i: Integer;\n  oldFileName, newFileName, bakFileName: string;\nbegin\n  // tracker message\n  Tracker.Write(' ');\n  Tracker.Write('Renaming saved plugins');\n\n  for i := Pred(SavedPluginPaths.Count) downto 0 do try\n    oldFileName := SavedPluginPaths[i];\n    newFileName := oldFileName + '.save';\n    bakFileName := oldFileName + '.bak';\n    Tracker.Write(Format('    Renaming %s to %s', [ExtractFileName(newFileName), ExtractFileName(oldFileName)]));\n    if FileExists(bakFileName) then\n      DeleteFile(bakFileName);\n    RenameFile(oldFileName, bakFileName);\n    RenameFile(newFileName, oldFileName);\n  except\n    on x: Exception do\n      Tracker.Write('      Failed to rename ' + newFileName);\n  end;\nend;\n\nprocedure UpdatePluginData;\nvar\n  i: Integer;\n  plugin: TPlugin;\nbegin\n  for i := 0 to Pred(PluginsList.Count) do begin\n    plugin := TPlugin(PluginsList[i]);\n    plugin.UpdateData;\n  end;\nend;\n\nfunction CreateNewPlugin(sFilename: string): TPlugin;\nbegin\n  Result := TPlugin(TPluginHelpers.CreateNewBasePlugin(PluginsList, sFilename));\nend;\n\nfunction PluginLoadOrder(sFilename: string): Integer;\nbegin\n  Result := TPluginHelpers.BasePluginLoadOrder(PluginsList, sFilename);\nend;\n\nfunction PluginByFilename(sFilename: string): TPlugin;\nbegin\n  Result := TPlugin(TPluginHelpers.BasePluginByFilename(PluginsList, sFilename));\nend;\n\nfunction DefDisplayName(var def: TwbRecordDefEntry): String;\nvar\n  sig: String;\nbegin\n  sig := String(def.rdeSignature);\n  Result := def.rdeDef.Name;\n  if (Result <> sig) then\n    Result := sig + ' - ' + Result;\nend;\n\nprocedure PopulateAddList(var AddItem: TMenuItem; Event: TNotifyEvent);\nvar\n  i: Integer;\n  recordDef: TwbRecordDefEntry;\n  item: TMenuItem;\nbegin\n  for i := Low(wbRecordDefs) to High(wbRecordDefs) do begin\n    recordDef := wbRecordDefs[i];\n    item := TMenuItem.Create(AddItem);\n    item.Caption := DefDisplayName(recordDef);\n    item.OnClick := Event;\n    AddItem.Add(item);\n  end;\nend;\n\nprocedure AddAllRecords(currentSetting: TSmashSetting; var tv: TTreeView);\nvar\n  i: Integer;\n  recordDef: TwbRecordDefEntry;\n  groupName: String;\n  recObj: ISuperObject;\nbegin\n  for i := Low(wbRecordDefs) to High(wbRecordDefs) do begin\n    recordDef := wbRecordDefs[i];\n    groupName := DefDisplayName(recordDef);\n    recObj := GetRecordObj(currentSetting.tree, groupName);\n    if Assigned(recObj) then continue;\n    if not BuildRecordDef(groupName, recObj) then continue;\n    currentSetting.tree.A['records'].Add(recObj);\n    LoadElement(tv, tv.Items[0], recObj, false);\n  end;\nend;\n\nprocedure RemoveSettingFromPlugins(aSetting: TSmashSetting);\nvar\n  i: Integer;\n  plugin: TPlugin;\nbegin\n  for i := 0 to Pred(PluginsList.Count) do begin\n    plugin := TPlugin(PluginsList[i]);\n    if plugin.setting = aSetting.name then begin\n      plugin.setting := 'Skip';\n      plugin.smashSetting := TSettingHelpers.SettingByName('Skip');\n    end;\n  end;\nend;\n\nfunction GetTagString(var slTags: TStringList): String;\nvar\n  i, index: Integer;\n  tag, sTagGroup, sGroup: String;\nbegin\n  for i := 0 to Pred(slTags.Count) do begin\n    tag := slTags[i];\n    index := Pos('.', tag);\n    sTagGroup := Copy(tag, 1, index - 1);\n    if (index > 0) and (index < 11) and (SameText(sGroup, sTagGroup) or (i = 0)) then\n      sGroup := sTagGroup\n    else\n      sGroup := '';\n  end;\n\n  // generate the string of tags\n  if sGroup <> '' then begin\n    Result := StringReplace(slTags.CommaText, sGroup + '.', '', [rfReplaceAll, rfIgnoreCase]);\n    Result := Format('{{%s:%s}}', [UpperCase(sGroup), Result])\n  end\n  else\n    Result := Format('{{%s}}', [slTags.CommaText]);\nend;\n\n\n{******************************************************************************}\n{ Tree Helper Functions\n  - BuildTreeFromPlugins\n  - SetChildren\n  - UpdateParent\n  - CheckBoxManager\n  - LoadElement\n}\n{******************************************************************************}\n\nprocedure BuildTreeFromPlugins(var tv: TTreeView; var sl: TStringList;\n  tree: ISuperObject);\nvar\n  i, j: Integer;\n  plugin: TPlugin;\n  rec: IwbMainRecord;\n  RecordDef: PwbRecordDef;\n  def: TwbRecordDefEntry;\n  sName, sSignature: string;\n  slRecordSignatures: TStringList;\n  recObj: ISuperObject;\nbegin\n  slRecordSignatures := TStringList.Create;\n  slRecordSignatures.Sorted := true;\n  slRecordSignatures.Duplicates := dupIgnore;\n  try\n    // loop through plugins\n    for i := 0 to Pred(sl.Count) do begin\n      plugin := PluginByFileName(sl[i]);\n      if not Assigned(plugin) then\n        continue;\n      if not plugin._File.IsEditable then\n        continue;\n      // loop through records\n      for j := 0 to Pred(plugin._File.RecordCount) do begin\n        rec := plugin._File.Records[j];\n        // skip non-override records\n        if rec.IsMaster then\n          continue;\n        sSignature := rec.Signature;\n\n        // skip record signatures we've already seen\n        if (slRecordSignatures.IndexOf(sSignature) > -1) then\n          continue;\n        slRecordSignatures.Add(sSignature);\n        // skip records that aren't defined\n        if not wbFindRecordDef(AnsiString(sSignature), RecordDef) then\n          continue;\n\n        // get record def object if it exists\n        sName := sSignature + ' - ' + RecordDef.Name;\n        recObj := GetRecordObj(tree, sName);\n\n        // build record def if it doesn't exist\n        if not Assigned(recObj) then begin\n          def := GetRecordDef(rec.Signature);\n          if not BuildRecordDef(sName, def.rdeDef, recObj) then\n            continue;\n          tree.A['records'].Add(recObj);\n          LoadElement(tv, tv.Items[0], recObj, false);\n        end;\n      end;\n    end;\n  finally\n    tv.Repaint;\n    slRecordSignatures.Free;\n  end;\nend;\n\n{\n  SetChildren\n  Sets the StateIndex attribute of all the children of @node\n  to @state.  Uses recursion.\n}\nprocedure SetChildren(node: TTreeNode; state: Integer);\nvar\n  tmp: TTreeNode;\n  e: TElementData;\nbegin\n  // exit if we don't have a node to work with\n  if not Assigned(node) then exit;\n\n  // loop through children setting StateIndex to state\n  // if child has children, recurse into that child\n  tmp := node.getFirstChild;\n  while Assigned(tmp) do begin\n    tmp.StateIndex := state;\n    e := TElementData(tmp.Data);\n    e.process := state <> csUnChecked;\n    e.singleEntity := false;\n    if tmp.HasChildren then\n      SetChildren(tmp, state);\n    tmp := tmp.getNextSibling;\n  end;\nend;\n\n{\n  UpdateParent\n  Calculates and sets the StateIndex attribute for @node based\n  on the StateIndex values of its children.  Uses recursion to\n  update parents of the parent that was updated.\n}\nprocedure UpdateParent(node: TTreeNode);\nvar\n  tmp: TTreeNode;\n  state: Integer;\n  e: TElementData;\nbegin\n  // exit if we don't have a node to work with\n  // or if not is set to be treated as a single entity\n  if not Assigned(node) then exit;\n  e := TElementData(node.Data);\n  if not Assigned(e) then exit;\n  if e.singleEntity then exit;\n\n  // parent state is checked if all siblings are checked\n  state := csChecked;\n  tmp := node.getFirstChild;\n  while Assigned(tmp) do begin\n    if tmp.StateIndex <> csChecked then begin\n      state := csPartiallyChecked;\n      break;\n    end;\n    tmp := tmp.getNextSibling;\n  end;\n\n  // parent state is unchecked if all siblings are unchecked\n  if state = csPartiallyChecked then begin\n    state := csUnChecked;\n    tmp := node.getFirstChild;\n    while Assigned(tmp) do begin\n      if tmp.StateIndex <> csUnChecked then begin\n        state := csPartiallyChecked;\n        break;\n      end;\n      tmp := tmp.getNextSibling;\n    end;\n  end;\n\n  // set state, recurse to next parent\n  node.StateIndex := state;\n  e.process := state <> csUnChecked;\n  tmp := node.Parent;\n  UpdateParent(tmp);\nend;\n\n{\n  CheckBoxManager\n  Manages checkboxes in the TTreeView.  Changes the StateIndex\n  of the checkbox associated with @node.  Uses SetChildren and\n  UpdateParent.  Called by tvClick and tvKeyDown.\n}\nprocedure CheckBoxManager(node: TTreeNode);\nvar\n  e: TElementData;\nbegin\n  // exit if we don't have a node to work with\n  if not Assigned(node) then exit;\n\n  // if unchecked or partially checked, set to checked and\n  // set all children to checked, update parents\n  if (node.StateIndex = csUnChecked)\n  or (node.StateIndex = csPartiallyChecked) then begin\n    node.StateIndex := csChecked;\n    e := TElementData(node.Data);\n    e.process := true;\n    e.singleEntity := false;\n    UpdateParent(node.Parent);\n    SetChildren(node, csChecked);\n  end\n  // if checked, set to unchecked and set all children to\n  // unchecked, update parents\n  else if node.StateIndex = csChecked then begin\n    node.StateIndex := csUnChecked;\n    e := TElementData(node.Data);\n    e.process := false;\n    e.singleEntity := false;\n    UpdateParent(node.Parent);\n    SetChildren(node, csUnChecked);\n  end;\nend;\n\nprocedure LoadElement(var tv: TTreeView; node: TTreeNode; obj: ISuperObject;\n  bWithinSingle: boolean);\nvar\n  item: ISuperObject;\n  child, nextChild: TTreeNode;\n  bProcess, bPreserveDeletions, bOverrideDeletions, bIsSingle,\n  bForceValue: boolean;\n  priority: Integer;\n  oSmashType: TSmashType;\n  sName, sLinkTo, sLinkFrom: string;\n  e: TElementData;\nbegin\n  if not Assigned(obj) then\n    exit;\n\n  // load data from json\n  sName := obj.S['n'];\n  priority := obj.I['r'];\n  bProcess := obj.I['p'] = 1;\n  bPreserveDeletions := obj.I['d'] = 1;\n  bOverrideDeletions := obj.I['o'] = 1;\n  bIsSingle := obj.I['s'] = 1;\n  bForceValue := obj.I['f'] = 1;\n  bWithinSingle := bWithinSingle or bIsSingle;\n  oSmashType := TSmashType(obj.I['t']);\n  sLinkTo := obj.S['lt'];\n  sLinkFrom := obj.S['lf'];\n\n  // create child\n  e := TElementData.Create(priority, bProcess, bPreserveDeletions,\n    bOverrideDeletions, bIsSingle, bForceValue, oSmashType, sLinkTo, sLinkFrom);\n  // nodes insert in sorted order for record nodes\n  if (node.Level = 0) and node.hasChildren then begin\n    child := node.getFirstChild;\n    while (AnsiCompareText(child.Text, sName) < 0) do begin\n      nextChild := child.getNextSibling;\n      if not Assigned(nextChild) then\n        break;\n      child := nextChild;\n    end;\n    child := tv.Items.InsertObject(child, sName, e);\n  end\n  // else just add them in the order they were found\n  else\n    child := tv.Items.AddChildObject(node, sName, e);\n\n  // set check state\n  if bIsSingle then\n    child.StateIndex := csPartiallyChecked\n  else if bProcess then\n    child.StateIndex := csChecked\n  else\n    child.StateIndex := csUnChecked;\n\n  // recurse into children\n  if Assigned(obj.O['c']) then try\n    for item in obj['c'] do\n      LoadElement(tv, child, item, bWithinSingle);\n    if not bWithinSingle then\n      UpdateParent(child);\n  except\n    on x : Exception do\n      // nothing\n  end;\nend;\n\nprocedure LoadTree(var tv: TTreeView; aSetting: TSmashSetting);\nvar\n  obj, item: ISuperObject;\n  rootNode: TTreeNode;\n  e: TElementData;\nbegin\n  e := TElementData.Create;\n  rootNode := tv.Items.AddObject(nil, 'Records', e);\n  obj := aSetting.tree;\n  if not Assigned(obj) then\n    exit;\n  if not Assigned(obj['records']) then\n    exit;\n\n  for item in obj['records'] do\n    LoadElement(tv, rootNode, item, false);\nend;\n\nfunction GetRecordObject(tree: ISuperObject; sig: string): ISuperObject;\nvar\n  item: ISuperObject;\nbegin\n  Result := nil;\n  for item in tree['records'] do begin\n    if Copy(item.S['n'], 1, 4) = sig then begin\n      Result := item;\n      break;\n    end;\n  end;\nend;\n\nfunction GetChild(obj: ISuperObject; name: string): ISuperObject;\nvar\n  child: ISuperObject;\nbegin\n  Result := nil;\n  for child in obj['c'] do begin\n    if child.S['n'] = name then begin\n      Result := child;\n      exit;\n    end;\n  end;\nend;\n\nprocedure MergeChildren(srcObj, dstObj: ISuperObject);\nvar\n  srcChild, dstChild: ISuperObject;\nbegin\n  for srcChild in srcObj['c'] do begin\n    dstChild := GetChild(dstObj, srcChild.S['n']);\n    if not Assigned(dstChild) then\n      dstObj.A['c'].Add(srcChild.Clone)\n    else begin\n      // merge force value\n      if srcChild.I['f'] = 1 then\n        dstChild.I['f'] := 1;\n      // merge treat as single\n      if srcChild.I['s'] = 1 then\n        dstChild.I['s'] := 1;\n      // merge preserve deletions\n      if srcChild.I['d'] = 1 then\n        dstChild.I['d'] := 1;\n      // merge override deletions\n      if srcChild.I['o'] = 1 then\n        dstChild.I['o'] := 1;\n      // merge process\n      if srcChild.I['p'] = 1 then\n        dstChild.I['p'] := 1;\n      // merge links\n      if srcChild.S['lt'] <> '' then\n        dstChild.S['lt'] := srcChild.S['lt'];\n      if srcChild.S['lf'] <> '' then\n        dstChild.S['lf'] := srcChild.S['lf'];\n      // recurse into children if present\n      if Assigned(srcChild.A['c']) then begin\n        if Assigned(dstChild.A['c']) then\n          MergeChildren(srcChild, dstChild)\n        else\n          dstChild.O['c'] := srcChild.O['c'].Clone;\n      end;\n    end;\n  end;\nend;\n\nfunction CreateCombinedSetting(var sl: TStringList; name: string;\n  bVirtual: boolean = false): TSmashSetting;\nvar\n  i, index: Integer;\n  newSetting, aSetting: TSmashSetting;\n  recordObj, existingRecordObj: ISuperObject;\nbegin\n  newSetting := TSmashSetting.Create;\n  newSetting.tree := SO;\n  newSetting.tree.O['records'] := SA([]);\n\n  for i := 0 to Pred(sl.Count) do begin\n    aSetting := TSmashSetting(sl.Objects[i]);\n    recordObj := GetRecordObject(aSetting.tree, sl[i]);\n    existingRecordObj := GetRecordObject(newSetting.tree, sl[i]);\n    // if record object matching record signature already exists\n    // merge the record objects\n    if Assigned(existingRecordObj) then\n      MergeChildren(recordObj, existingRecordObj)\n    // else just add it to the tree\n    else\n      newSetting.tree.A['records'].Add(recordObj.Clone);\n  end;\n  newSetting.UpdateRecords;\n\n  // set other attributes\n  newSetting.UpdateHash;\n  newSetting.bVirtual := bVirtual;\n  newSetting.description := 'Combined setting:'#13#10 + name;\n  index := Pos('.', name);\n  if (index > 0) and (index < 11) then\n    newSetting.name := Format('%sCombined-%s', [Copy(name, 1, index), newSetting.hash])\n  else\n    newSetting.name := 'Combined-'+newSetting.hash;\n\n  // add new setting to SmashSettings list\n  aSetting := TSettingHelpers.SettingByName(newSetting.name);\n  if not Assigned(aSetting) then begin\n    SmashSettings.Add(newSetting);\n    Result := newSetting;\n  end\n  else begin\n    newSetting.Free;\n    Result := aSetting;\n  end;\nend;\n\nfunction CombineSettingTrees(var lst: TList; var slSettings: TStringList): boolean;\nvar\n  setting: TSmashSetting;\n  sl: TStringList;\n  i, j: Integer;\nbegin\n  sl := TStringList.Create;\n  Result := false;\n  for i := 0 to Pred(lst.Count) do begin\n    setting := TSmashSetting(lst[i]);\n    sl.CommaText := setting.records;\n    for j := 0 to Pred(sl.Count) do begin\n      if slSettings.IndexOf(sl[j]) > -1 then\n        Result := true;\n      slSettings.AddObject(sl[j], TObject(setting));\n    end;\n  end;\n\n  // free memory\n  sl.Free;\nend;\n\n\n{******************************************************************************}\n{ Tag Helper Functions\n  - ClearTags\n  - GetMissingTags\n  - ExtractTags\n  - GetTags\n}\n{******************************************************************************}\n\nfunction ClearTags(sDescription: String): String;\nvar\n  regex: TRegex;\n  match: TMatch;\nbegin\n  // find tags\n  regex := TRegex.Create('{{([^}]*)}}');\n  match := regex.Match(sDescription);\n\n  // delete tags\n  while match.Success do begin\n    sDescription := StringReplace(sDescription, match.Value, '', []);\n    match := match.NextMatch;\n  end;\n\n  // set description to the memo\n  Result := Trim(sDescription);\nend;\n\nprocedure GetMissingTags(var slPresent, slMissing: TStringList);\nvar\n  i: Integer;\n  aSetting: TSmashSetting;\nbegin\n  for i := 0 to Pred(SmashSettings.Count) do begin\n    aSetting := TSmashSetting(SmashSettings[i]);\n    if slPresent.IndexOf(aSetting.name) = -1 then\n      slMissing.Add(aSetting.name);\n  end;\nend;\n\nprocedure ExtractTags(var match: TMatch; var sl: TStringList;\n  var sTagGroup: String);\nvar\n  i: Integer;\nbegin\n  sTagGroup := '';\n\n  // split tag on commas\n  sl.Delimiter := ',';\n  sl.StrictDelimiter := true;\n  sl.DelimitedText := match.Groups.Item[2].Value;\n\n  // trim leading or trailing whitespace from tags\n  for i := 0 to Pred(sl.Count) do\n    sl[i] := Trim(sl[i]);\n\n  // if tags are presented under a group, append the group name\n  // and a . to the beginning of each setting name in the tag\n  if match.Groups.Item[1].Value <> '' then begin\n    sTagGroup := TitleCase(match.Groups.Item[1].Value);\n    SetLength(sTagGroup, Length(sTagGroup) - 1);\n    Logger.Write('PLUGIN', 'Tags', 'Parsing as ' + sTagGroup + ' tags');\n    for i := 0 to Pred(sl.Count) do\n      sl[i] := Format('%s.%s', [sTagGroup, sl[i]]);\n  end;\nend;\n\nprocedure ParseTags(description: string; var sl: TStringList);\nvar\n  regex: TRegEx;\n  match: TMatch;\n  sTagGroup: String;\nbegin\n  // get setting tags from description\n  regex := TRegEx.Create('{{([a-zA-Z]{1,10}:){0,1}([^}]*)}}');\n  match := regex.Match(description);\n\n  // if match found, put the tags into the stringlist\n  if match.success then\n    ExtractTags(match, sl, sTagGroup);\nend;\n\ninitialization\nbegin\n  PatchesList := TList.Create;\n  SmashSettings := TList.Create;\n  SavedPluginPaths := TStringList.Create;\nend;\n\nfinalization\nbegin\n  FreeList(PatchesList);\n  FreeList(SmashSettings);\n  SavedPluginPaths.Free;\nend;\n\nend.\n"
  },
  {
    "path": "frontend/msEditForm.dfm",
    "content": "object EditForm: TEditForm\n  Left = 0\n  Top = 0\n  ActiveControl = edName\n  Caption = 'Edit patch'\n  ClientHeight = 151\n  ClientWidth = 333\n  Color = clBtnFace\n  Font.Charset = DEFAULT_CHARSET\n  Font.Color = clWindowText\n  Font.Height = -11\n  Font.Name = 'Tahoma'\n  Font.Style = []\n  OldCreateOrder = False\n  Position = poScreenCenter\n  OnShow = FormShow\n  PixelsPerInch = 96\n  TextHeight = 13\n  object PageControl: TPageControl\n    Left = 8\n    Top = 8\n    Width = 317\n    Height = 104\n    ActivePage = EditTabSheet\n    Align = alCustom\n    Anchors = [akLeft, akTop, akRight, akBottom]\n    TabOrder = 0\n    TabWidth = 60\n    object EditTabSheet: TTabSheet\n      Caption = 'Edit'\n      object lblName: TLabel\n        Left = 12\n        Top = 13\n        Width = 27\n        Height = 13\n        Caption = 'Name'\n      end\n      object lblFilename: TLabel\n        Left = 12\n        Top = 40\n        Width = 42\n        Height = 13\n        Caption = 'Filename'\n      end\n      object edName: TEdit\n        Left = 102\n        Top = 10\n        Width = 202\n        Height = 21\n        Margins.Right = 8\n        Align = alCustom\n        Anchors = [akLeft, akTop, akRight]\n        TabOrder = 0\n        OnChange = edNameChange\n        OnKeyDown = edKeyDown\n      end\n      object edFilename: TEdit\n        Left = 102\n        Top = 37\n        Width = 202\n        Height = 21\n        Margins.Right = 8\n        Align = alCustom\n        Anchors = [akLeft, akTop, akRight]\n        TabOrder = 1\n        OnChange = edFilenameChange\n        OnEnter = edFilenameEnter\n        OnKeyDown = edKeyDown\n      end\n    end\n  end\n  object btnOK: TButton\n    Left = 250\n    Top = 118\n    Width = 75\n    Height = 25\n    Align = alCustom\n    Anchors = [akRight, akBottom]\n    Caption = 'OK'\n    TabOrder = 1\n    OnClick = btnOKClick\n  end\nend\n"
  },
  {
    "path": "frontend/msEditForm.pas",
    "content": "unit msEditForm;\n\ninterface\n\nuses\n  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,\n  Dialogs, StdCtrls, ComCtrls,\n  // mte units\n  mteHelpers,\n  // mator smash units\n  msCore, msConfiguration;\n\ntype\n  TEditForm = class(TForm)\n    PageControl: TPageControl;\n    EditTabSheet: TTabSheet;\n    btnOK: TButton;\n    lblName: TLabel;\n    lblFilename: TLabel;\n    edName: TEdit;\n    edFilename: TEdit;\n    procedure FormShow(Sender: TObject);\n    function NameValid: boolean;\n    function ESPFilenameValid: boolean;\n    procedure edFilenameChange(Sender: TObject);\n    procedure edFilenameEnter(Sender: TObject);\n    procedure edNameChange(Sender: TObject);\n    procedure edKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);\n    procedure btnOKClick(Sender: TObject);\n  private\n    { Private declarations }\n  public\n    { Public declarations }\n    patch: TPatch;\n  end;\n\nvar\n  EditForm: TEditForm;\n\nimplementation\n\n{$R *.dfm}\n\nprocedure TEditForm.btnOKClick(Sender: TObject);\nbegin\n  patch.name := edName.Text;\n  patch.filename := edFilename.Text;\n  ModalResult := mrOK;\nend;\n\nfunction TEditForm.NameValid: boolean;\nvar\n  aPatch: TPatch;\n  i: integer;\nbegin\n  Result := false;\n\n  // return false if illegal characters present\n  if not FileNameValid(edName.Text) then\n    exit;\n\n  // return false if edName is blank\n  if Trim(edName.Text) = '' then\n    exit;\n\n  // return false if patch with specified name already exists\n  for i := 0 to Pred(PatchesList.Count) do begin\n    aPatch := TPatch(PatchesList[i]);\n    if (aPatch.name = edName.Text) and (aPatch <> patch) then\n      exit;\n  end;\n\n  // all tests passed, return true\n  Result := true;\nend;\n\nfunction TEditForm.ESPFilenameValid: boolean;\nvar\n  aPatch: TPatch;\n  plugin: TPlugin;\n  loadOrder, highLoadOrder, i: integer;\n  sFilename: string;\nbegin\n  Result := false;\n\n  // return false if illegal characters present\n  if not FileNameValid(edFilename.Text) then\n    exit;\n\n  // return false if filename doesn't end in .esp\n  if not StrEndsWith(edFilename.Text, '.esp') then\n    exit;\n\n  // return false if specified filename corresponds to a\n  // plugin that is in patch\n  if patch.plugins.IndexOf(edFilename.Text) > -1 then\n    exit;\n\n  // check if there's a load order error patching into the specified file\n  plugin := PluginByFilename(edFilename.Text);\n  loadOrder := PluginLoadOrder(edFilename.Text);\n  highLoadOrder := MaxInt;\n  if patch.plugins.Count > 0 then begin\n    sFilename := patch.plugins[patch.plugins.Count -1];\n    highLoadOrder := PluginLoadOrder(sFilename);\n  end;\n\n  // return false if there's a load order error\n  if Assigned(plugin) and (loadOrder > highLoadOrder) then\n    exit;\n\n  // return false if patch exists\n  for i := 0 to Pred(PatchesList.Count) do begin\n    aPatch := TPatch(PatchesList[i]);\n    if (aPatch.filename = edFileName.Text) and (aPatch <> patch) then\n      exit;\n  end;\n\n  // all tests passed, return true\n  Result := true;\nend;\n\nprocedure TEditForm.edFilenameChange(Sender: TObject);\nvar\n  valid: boolean;\nbegin\n  // if invalid disable btnOk, show hint, and make font color red\n  valid := ESPFilenameValid;\n  btnOk.Enabled := valid and NameValid;\n  edFilename.ShowHint := valid;\n  if valid then\n    edFilename.Font.Color := clWindowText\n  else\n    edFilename.Font.Color := $0000ff;\nend;\n\nprocedure TEditForm.edFilenameEnter(Sender: TObject);\nbegin\n  // change selection to not include the .esp\n  if (edFilename.SelLength = Length(edFilename.Text))\n  and StrEndsWith(edFilename.Text, '.esp') then\n    edFilename.SelLength := edFilename.SelLength - 4;\nend;\n\nprocedure TEditForm.edNameChange(Sender: TObject);\nvar\n  valid, exists: boolean;\nbegin\n  valid := NameValid;\n  exists := DirectoryExists(settings.patchDirectory + edName.Text)\n    and (edName.Text <> patch.name);\n\n  // if invalid show hint and make font color red\n  btnOk.Enabled := valid and ESPFilenameValid;\n  edName.ShowHint := (not valid) or exists;\n  if (not valid) or exists then\n    edName.Font.Color := $0000ff\n  else\n    edName.Font.Color := clWindowText;\nend;\n\n{ Save patch by pressing enter in edName or edFilename }\nprocedure TEditForm.edKeyDown(Sender: TObject; var Key: Word;\n  Shift: TShiftState);\nbegin\n  if (HiWord(GetKeyState(vk_Return)) <> 0) and btnOk.Enabled then begin\n    btnOkClick(nil);\n    ModalResult := mrOk;\n  end;\nend;\n\nprocedure TEditForm.FormShow(Sender: TObject);\nbegin\n  edName.Text := patch.name;\n  edFilename.Text := patch.filename;\nend;\n\nend.\n"
  },
  {
    "path": "frontend/msLoader.pas",
    "content": "unit msLoader;\n\ninterface\n\nuses\n  Classes,\n  // mte units\n  mteHelpers, mteBase,\n  // mp units\n  msConfiguration;\n\n  { Initialization Methods }\n  function InitBase: boolean;\n  function GamePathValid(path: string; id: integer): boolean;\n  procedure SetGame(id: integer);\n  function GetGameID(name: string): integer;\n  function GetLanguageFileSuffix: String;\n  function GetGamePath(mode: TGameMode): string;\n  procedure LoadDefinitions;\n  procedure LoadBSAs;\n  { Load order functions }\n  procedure RemoveCommentsAndEmpty(var sl: TStringList);\n  procedure RemoveMissingFiles(var sl: TStringList);\n  procedure RemoveSmashedPatches(var sl: TStringList);\n  procedure FixLoadOrder(var sl: TStringList; const filename: String; var index: Integer);\n  procedure AddBaseMasters(var sl: TStringList);\n  procedure AddMissingFiles(var sl: TStringList);\n  function PluginListCompare(List: TStringList; Index1, Index2: Integer): Integer;\n  procedure LoadPluginsList(const sLoadPath: String; var sl: TStringList; noDelete: Boolean = False);\n  procedure LoadLoadOrder(const sLoadPath: String; var slLoadOrder: TStringList);\n  procedure PrepareLoadOrder(var slLoadOrder, slPlugins: TStringList);\n\nvar\n  slPlugins, slLanguageMap: TStringList;\n  UpdateCallback: TCallback;\n\nimplementation\n\nuses\n  SysUtils, StrUtils, IniFiles, ShlObj, Controls,\n  // mte units\n  mteTracker, mteLogger, mteLogging, mtePluginSelectionForm,\n  // mp units\n  msCore,\n  // mp forms\n  // xEdit units\n  wbHelpers, wbInterface, wbImplementation, wbBSA,\n  wbDefinitionsFNV, wbDefinitionsFO3, wbDefinitionsTES3, wbDefinitionsTES4,\n  wbDefinitionsTES5, wbDefinitionsFO4;\n\n\n{******************************************************************************}\n{ Initialization Methods\n  Methods that are used for initialization.\n\n  List of methods:\n  - GamePathValid\n  - SetGame\n  - GetGameID\n  - GetGamePath\n  - LoadDataPath\n  - LoadDefinitions\n  - InitPapyrus\n}\n{******************************************************************************}\n\nfunction InitBase: boolean;\nvar\n  slLoadOrder: TStringList;\n  psForm: TPluginSelectionForm;\nbegin\n  Result := false;\n\n  // INITIALIZE VARIABLES\n  LogPath := PathList.Values['ProgramPath'] + 'logs\\';\n  PathList.Values['TempPath'] := PathList.Values['ProgramPath'] + 'temp\\';\n  PathList.Values['ProfilePath'] := PathList.Values['ProgramPath'] +\n    'profiles\\'+ CurrentProfile.name + '\\';\n  ForceDirectories(PathList.Values['TempPath']);\n  ForceDirectories(LogPath);\n  ForceDirectories(PathList.Values['ProfilePath']);\n\n  // SET GAME VARS\n  SetGame(CurrentProfile.gameMode);\n  wbVWDInTemporary := wbGameMode in [gmSSE, gmTES5, gmFO3, gmFNV];\n  wbVWDAsQuestChildren := wbGameMode = gmFO4;\n  wbArchiveExtension := IfThen(wbGameMode = gmFO4, '.ba2', '.bsa');\n  wbLoadBSAs := wbGameMode in [gmFO4, gmSSE, gmTES5, gmTES4];\n  Logger.Write('GENERAL', 'Game', 'Using '+wbGameName);\n  Logger.Write('GENERAL', 'Path', 'Using '+wbDataPath);\n  Logger.Write('GENERAL', 'GameIni', 'Using '+wbTheGameIniFileName);\n\n  // INITIALIZE SETTINGS FOR GAME\n  LoadSettings;\n  LoadLanguage;\n\n  // INITIALIZE XEDIT\n  wbDisplayLoadOrderFormID := True;\n  wbSortSubRecords := True;\n  wbDisplayShorterNames := True;\n  wbHideUnused := True;\n  wbHideIgnored := False;\n  wbFlagsAsArray := True;\n  wbRequireLoadOrder := True;\n  wbLanguage := GetLanguageFileSuffix;\n  wbEditAllowed := True;\n  wbContainerHandler := wbCreateContainerHandler;\n  wbContainerHandler._AddRef;\n\n  // INITIALIZE DEFINITIONS\n  Logger.Write('GENERAL', 'Definitions', 'Using '+wbAppName+'Edit Definitions');\n  LoadDefinitions;\n\n  // LOAD SMASH SETTINGS\n  Tracker.Write('Loading smash settings');\n  LoadSmashSettings;\n\n  // LOAD PATCHES\n  Tracker.Write('Loading patches');\n  LoadPatches;\n\n  // PREPARE LOAD ORDER\n  slLoadOrder := TStringList.Create;\n  slLoadOrder.CaseSensitive := False;\n  slPlugins := TStringList.Create;\n  PrepareLoadOrder(slLoadOrder, slPlugins);\n\n  // DISPLAY PLUGIN SELECTION FORM\n  THeaderHelpers.LoadPluginHeaders(slLoadOrder);\n  psForm := TPluginSelectionForm.Create(nil);\n  psForm.slCheckedPlugins := slPlugins;\n  psForm.slAllPlugins := slLoadOrder;\n  psForm.sColumns := 'Plugin,Patch';\n  psForm.GetPluginInfo := TPatchHelpers.GetPatchForPlugin;\n  psForm.GetPluginMasters := THeaderHelpers.GetPluginMasters;\n  psForm.GetPluginDependencies := THeaderHelpers.GetPluginDependencies;\n  if psForm.ShowModal = mrCancel then\n    exit;\n  slPlugins.Text := psForm.slCheckedPlugins.Text;\n  psForm.Free;\n  wbFileForceClosed;\n  FreeList(HeaderList);\n\n  // ALL DONE\n  Result := true;\nend;\n\r\n{ Check if game paths are valid }\nfunction GamePathValid(path: string; id: integer): boolean;\nbegin\n  Result := FileExists(path + GameArray[id].exeName)\n    and DirectoryExists(path + 'Data');\nend;\n\n{ Sets the game mode in the TES5Edit API }\nprocedure SetGame(id: integer);\nvar\r\n  sMyDocumentsPath: string;\n  sIniPath: string;\nbegin\n  ProgramStatus.GameMode := GameArray[id];\n  wbGameName := ProgramStatus.GameMode.gameName;\n  wbGameName2 := ProgramStatus.GameMode.regName;\n  wbGameMode := ProgramStatus.GameMode.gameMode;\n  wbAppName := ProgramStatus.GameMode.appName;\n  wbDataPath := CurrentProfile.gamePath + 'Data\\';\n\n  // set general paths\n  PathList.Values['DataPath'] := wbDataPath;\n  PathList.Values['GamePath'] := UpDirectory(wbDataPath);\n\n  // find game ini inside the user's documents folder.\n  sMyDocumentsPath := GetCSIDLShellFolder(CSIDL_PERSONAL);\n  if sMyDocumentsPath <> '' then begin\n    sIniPath := sMyDocumentsPath + 'My Games\\' + wbGameName2 + '\\';\n    if wbGameMode in [gmFO3, gmFNV] then\n      wbTheGameIniFileName := sIniPath + 'Fallout.ini'\n    else\n      wbTheGameIniFileName := sIniPath + wbGameName + '.ini';\n  end;\nend;\n\n{ Get the game ID associated with a game long name }\nfunction GetGameID(name: string): integer;\nvar\n  i: integer;\nbegin\n  Result := 0;\n  for i := Low(GameArray) to High(GameArray) do\n    if GameArray[i].longName = name then begin\n      Result := i;\n      exit;\n    end;\nend;\n\n{ Gets language file suffix }\nfunction GetLanguageFileSuffix: String;\nbegin\n  Result := settings.language;\r\n  if (wbGameMode = gmFO4) and (slLanguageMap.IndexOfName(Result) > -1) then\r\n    Result := slLanguageMap.Values[Result];\r\nend;\n\n{ Gets the path of a game from registry key or app path }\nfunction GetGamePath(mode: TGameMode): string;\nconst\n  sBethRegKey     = '\\SOFTWARE\\Bethesda Softworks\\';\n  sBethRegKey64   = '\\SOFTWARE\\Wow6432Node\\Bethesda Softworks\\';\n  sSteamRegKey    = '\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\'+\n    'Steam App ';\n  sSteamRegKey64  = '\\SOFTWARE\\Wow6432Node\\Microsoft\\Windows\\CurrentVersion\\'+\n    'Uninstall\\Steam App ';\nvar\n  i: Integer;\n  regName: string;\n  keys, appIDs: TStringList;\nbegin\n  Result := '';\n\n  // initialize variables\n  regName := mode.regName;\n  keys := TStringList.Create;\n  appIDs := TStringList.Create;\n  appIDs.CommaText := mode.appIDs;\n\n  // add keys to check\n  keys.Add(sBethRegKey + regName + '\\Installed Path');\n  keys.Add(sBethRegKey64 + regName + '\\Installed Path');\n  for i := 0 to Pred(appIDs.Count) do begin\n    keys.Add(sSteamRegKey + appIDs[i] + '\\InstallLocation');\n    keys.Add(sSteamRegKey64 + appIDs[i] + '\\InstallLocation');\n  end;\n\n  // try to find path from registry\n  Result := TryRegistryKeys(keys);\n\n  // free memory\n  keys.Free;\n  appIDs.Free;\n\n  // set result\n  if Result <> '' then\n    Result := IncludeTrailingPathDelimiter(Result);\nend;\n\n{ Loads definitions based on wbGameMode }\nprocedure LoadDefinitions;\nbegin\n  case wbGameMode of\n    gmTES5: DefineTES5;\n    gmFNV: DefineFNV;\n    gmTES4: DefineTES4;\n    gmFO3: DefineFO3;\n    gmFO4: DefineFO4;\n    gmSSE: DefineTES5;\n  end;\nend;\n\nprocedure LoadBSAFile(sFileName: String);\nvar\n  sFileExt: String;\nbegin\n  sFileExt := ExtractFileExt(sFileName);\r\n  Logger.Write('LOAD', 'Resources', 'Loading resources from ' + sFileName);\r\n  if sFileExt = '.bsa' then\r\n    wbContainerHandler.AddBSA(wbDataPath + sFileName)\r\n  else if sFileExt = '.ba2' then\r\n    wbContainerHandler.AddBA2(wbDataPath + sFileName);\r\nend;\n\n{ Loads all of the BSAs specified in the game ini and by plugins }\nprocedure LoadBSAs;\nvar\r\n  slBSAFileNames: TStringList;\n  slErrors: TStringList;\n  i: Integer;\n  modIndex: Integer;\n  plugin: TPlugin;\n  bIsTES5: Boolean;\nbegin\n  slBSAFileNames := TStringList.Create;\r\n  try\n\r    slErrors:= TStringList.Create;\n    try\n      FindBSAs(wbTheGameIniFileName, wbDataPath, slBSAFileNames, slErrors);\r\n      for i := 0 to slBSAFileNames.Count - 1 do\r\n        LoadBSAFile(slBSAFileNames[i]);\r\n      for i := 0 to slErrors.Count - 1 do\r\n        Logger.Write('ERROR', 'Load', slErrors[i] + ' was not found');\r\n\r\n      for modIndex := 0 to PluginsList.Count - 1 do begin\r\n        slBSAFileNames.Clear;\r\n        slErrors.Clear;\r\n        plugin := TPlugin(PluginsList[modIndex]);\r\n        bIsTES5 := wbGameMode in [gmTES5, gmSSE];\r\n\r\n        HasBSAs(ChangeFileExt(plugin.filename, ''), wbDataPath, bIsTES5,\r\n          bIsTES5, slBSAFileNames, slErrors);\r\n        for i := 0 to slBSAFileNames.Count - 1 do\r\n          LoadBSAFile(slBSAFileNames[i]);\r\n        for i := 0 to slErrors.Count - 1 do\r\n          Logger.Write('ERROR', 'Load', slErrors[i] + ' was not found');\r\n      end;\r\n    finally\r\n      slErrors.Free;\r\n    end;\n  finally\r\n    slBSAFileNames.Free;\r\n  end;\nend;\n\n\n{******************************************************************************}\n{ Load order functions\n  Set of functions for building a working load order.\n\n  List of functions:\n  - RemoveCommentsAndEmpty\n  - RemoveMissingFiles\n  - AddMissingFiles\n  - PluginListCompare\n{******************************************************************************}\n\n{ Remove comments and empty lines from a stringlist }\r\nprocedure RemoveCommentsAndEmpty(var sl: TStringList);\r\nvar\r\n  i, j, k: integer;\r\n  s: string;\r\nbegin\r\n  for i := Pred(sl.Count) downto 0 do begin\r\n    s := Trim(sl.Strings[i]);\r\n    j := Pos('#', s);\r\n    k := Pos('*', s);\r\n    if j > 0 then\r\n      System.Delete(s, j, High(Integer));\r\n    if s = '' then\r\n      sl.Delete(i);\r\n    if k = 1 then\r\n      sl[i] := Copy(s, 2, Length(s));\r\n  end;\r\nend;\n\n{ Remove nonexistent files from stringlist }\nprocedure RemoveMissingFiles(var sl: TStringList);\nvar\n  i: integer;\nbegin\n  for i := Pred(sl.Count) downto 0 do\n    if not FileExists(wbDataPath + sl.Strings[i]) then\n      sl.Delete(i);\nend;\n\n{ Remove smashed patch plugins from stringlist }\nprocedure RemoveSmashedPatches(var sl: TStringList);\nvar\n  i: integer;\nbegin\n  for i := Pred(sl.Count) downto 0 do\n    if Assigned(TPatchHelpers.PatchByFilename(PatchesList, sl[i])) then\n      sl.Delete(i);\nend;\n\r\n{ Forces a plugin to load at a specific position }\r\nprocedure FixLoadOrder(var sl: TStringList; const filename: String; var index: Integer);\r\nvar\r\n  oldIndex: Integer;\r\nbegin\r\n  oldIndex := sl.IndexOf(filename);\r\n  if (oldIndex > -1) then begin\r\n    if oldIndex <> index then begin\r\n      sl.Delete(oldIndex);\r\n      sl.Insert(index, filename);\r\n    end;\r\n  end\r\n  else if FileExists(wbDataPath + filename) then\r\n    sl.Insert(index, filename)\r\n  else\r\n    exit;\r\n  Inc(index);\r\nend;\r\n\nprocedure AddBaseMasters(var sl: TStringList);\r\nvar\r\n  index: Integer;\r\nbegin\r\n  index := 0;\r\n  FixLoadOrder(sl, wbGameName + '.esm', index);\r\n  if (wbGameMode = gmTES5) then\r\n    FixLoadOrder(sl, 'Update.esm', index)\r\n  else if (wbGameMode = gmSSE) then begin\r\n    FixLoadOrder(sl, 'Update.esm', index);\r\n    FixLoadOrder(sl, 'Dawnguard.esm', index);\r\n    FixLoadOrder(sl, 'HearthFires.esm', index);\r\n    FixLoadOrder(sl, 'Dragonborn.esm', index);\r\n  end\r\n  else if (wbGameMode = gmFO4) then begin\r\n    FixLoadOrder(sl, 'DLCRobot.esm', index);\r\n    FixLoadOrder(sl, 'DLCworkshop01.esm', index);\r\n    FixLoadOrder(sl, 'DLCCoast.esm', index);\r\n    FixLoadOrder(sl, 'DLCworkshop02.esm', index);\r\n    FixLoadOrder(sl, 'DLCworkshop03.esm', index);\r\n    FixLoadOrder(sl, 'DLCNukaWorld.esm', index);\r\n    FixLoadOrder(sl, 'DLCUltraHighResolution.esm', index);\r\n  end;\r\nend;\n\nfunction GetPluginDate(const aFileName: string): Cardinal;\nconst\n  DateOmitYears = 60;\r\n  DatePrecision = 100000;\r\nvar\r\n  F: TSearchRec;\r\nbegin\r\n  // Try to fit a meaningful modified date of a file into 32 bits integer value\r\n  // For relative load order sorting only\r\n  // Oblivion GOG version has dates from 1969 year and FileAge() doesn't support them\r\n  if FindFirst(aFileName, faAnyFile, F) = 0 then begin\r\n    Result := Round((F.TimeStamp - 364 * DateOmitYears) * DatePrecision);\r\n    FindClose(F);\r\n  end else\r\n    Result := 0;\nend;\n\n{ Compare function for sorting load order by date modified/esms }\nfunction PluginListCompare(List: TStringList; Index1, Index2: Integer): Integer;\nvar\n  IsESM1, IsESM2: Boolean;\n  FileSK1, FileSK2: Integer;\nbegin\n  IsESM1 := IsFileESM(List[Index1]);\n  IsESM2 := IsFileESM(List[Index2]);\n\n  if IsESM1 = IsESM2 then begin\n    FileSK1 := Cardinal(List.Objects[Index1]);\n    FileSK2 := Cardinal(List.Objects[Index2]);\n\n    if FileSK1 < FileSK2 then\n      Result := -1\n    else if FileSK1 > FileSK2 then\n      Result := 1\n    else\n      Result := 0;\n\n  end else if IsESM1 then\n    Result := -1\n  else\n    Result := 1;\nend;\n\n{ Add missing *.esp, *.esl, and *.esm files to list }\nprocedure AddMissingFiles(var sl: TStringList);\nvar\n  F: TSearchRec;\n  i, j: integer;\n  slNew: TStringList;\n  fileSortKey: Cardinal;\nbegin\n  slNew := TStringList.Create;\n  try\n    // search for missing plugins and masters\n    if FindFirst(wbDataPath + '*.*', faAnyFile, F) = 0 then try\n      repeat\n        if not (IsFileESM(F.Name) or IsFileESP(F.Name) or IsFileESL(F.Name)) then\n          continue;\n        if sl.IndexOf(F.Name) = -1 then begin\n          fileSortKey := GetPluginDate(wbDataPath + F.Name);\n          slNew.AddObject(F.Name, TObject(fileSortKey));\n        end;\n      until FindNext(F) <> 0;\n    finally\n      FindClose(F);\n    end;\n\n    // sort the list\n    slNew.CustomSort(PluginListCompare);\n\n    // The for loop won't initialize j if sl.count = 0, we must force it\n    // to -1 so inserting will happen at index 0\n    if sl.Count = 0 then\n      j := -1\n    else\n      // find position of last master\n      for j := Pred(sl.Count) downto 0 do\n        if IsFileESM(sl[j]) then\n          Break;\n\n    // add esm masters after the last master, add esp plugins at the end\n    Inc(j);\n    for i := 0 to Pred(slNew.Count) do begin\n      if IsFileESM(slNew[i]) then begin\n        sl.InsertObject(j, slNew[i], slNew.Objects[i]);\n        Inc(j);\n      end else\n        sl.AddObject(slNew[i], slNew.Objects[i]);\n    end;\n  finally\n    slNew.Free;\n  end;\nend;\n\nprocedure ProcessAsterisks(var sl: TStringList; index: Integer; noDelete: Boolean);\r\nvar\r\n  s: String;\r\nbegin\r\n  s := sl[index];\r\n  if s[1] <> '*' then begin\r\n    if not noDelete then sl.Delete(index);\r\n  end\r\n  else\r\n    sl[index] := Copy(s, 2, Length(s));\r\nend;\r\n\r\nprocedure ProcessPluginsFormat(var sl: TStringList; noDelete: Boolean);\r\nvar\r\n  i: Integer;\r\nbegin\r\n  for i := Pred(sl.Count) downto 0 do\r\n    ProcessAsterisks(sl, i, noDelete);\r\nend;\n\r\nprocedure LoadPluginsList(const sLoadPath: String; var sl: TStringList; noDelete: Boolean = False);\r\nvar\r\n  sPath: String;\r\nbegin\r\n  sPath := sLoadPath + 'plugins.txt';\r\n  if FileExists(sPath) then begin\r\n    sl.LoadFromFile(sPath);\r\n    if (wbGameMode = gmSSE) or (wbGameMode = gmFO4) then\r\n      ProcessPluginsFormat(sl, noDelete);\r\n  end\r\n  else\r\n    AddMissingFiles(sl);\r\n\r\n  // remove comments and missing files\r\n  AddBaseMasters(sl);\r\n  RemoveCommentsAndEmpty(sl);\r\n  RemoveMissingFiles(sl);\r\n  if noDelete then AddMissingFiles(sl);\r\n  RemoveSmashedPatches(sl);\r\nend;\n\r\nprocedure LoadLoadOrder(const sLoadPath: String; var slLoadOrder: TStringList);\r\nvar\r\n  sPath: String;\r\nbegin\r\n  sPath := sLoadPath + 'loadorder.txt';\r\n  if (wbGameMode <> gmSSE) and (wbGameMode <> gmFO4)\r\n  and FileExists(sPath) then begin\r\n    slLoadOrder.LoadFromFile(sPath);\r\n\r\n    // remove comments and add/remove files\r\n    AddBaseMasters(slLoadOrder);\r\n    RemoveCommentsAndEmpty(slLoadOrder);\r\n    RemoveMissingFiles(slLoadOrder);\r\n    AddMissingFiles(slLoadOrder);\r\n    RemoveSmashedPatches(slLoadOrder);\r\n  end\r\n  else\r\n    LoadPluginsList(sLoadPath, slLoadOrder, True);\r\nend;\n\nprocedure PrepareLoadOrder(var slLoadOrder, slPlugins: TStringList);\nvar\n  sLoadPath: String;\nbegin\n  sLoadPath := GetCSIDLShellFolder(CSIDL_LOCAL_APPDATA) + wbGameName2 +'\\';\r\n  LoadPluginsList(sLoadPath, slPlugins);\r\n  LoadLoadOrder(sLoadPath, slLoadOrder);\n\rend;\n\n{ Log Initialization }\nprocedure InitLog;\nbegin\n  // INITIALIZE GROUP FILTERS\n  GroupFilters.Add(TFilter.Create('GENERAL', true));\n  GroupFilters.Add(TFilter.Create('LOAD', true));\n  GroupFilters.Add(TFilter.Create('CLIENT', true));\n  GroupFilters.Add(TFilter.Create('MERGE', true));\n  GroupFilters.Add(TFilter.Create('PLUGIN', true));\n  GroupFilters.Add(TFilter.Create('ERROR', true));\n  // INITIALIZE LABEL FILTERS\n  LabelFilters.Add(TFilter.Create('GENERAL', 'Game', true));\n  LabelFilters.Add(TFilter.Create('GENERAL', 'Status', true));\n  LabelFilters.Add(TFilter.Create('GENERAL', 'Path', true));\n  LabelFilters.Add(TFilter.Create('GENERAL', 'Definitions', true));\n  LabelFilters.Add(TFilter.Create('GENERAL', 'Dictionary', true));\n  LabelFilters.Add(TFilter.Create('GENERAL', 'Load Order', true));\n  LabelFilters.Add(TFilter.Create('GENERAL', 'Log', true));\n  LabelFilters.Add(TFilter.Create('LOAD', 'Order', false));\n  LabelFilters.Add(TFilter.Create('LOAD', 'Plugins', false));\n  LabelFilters.Add(TFilter.Create('LOAD', 'Background', true));\n  LabelFilters.Add(TFilter.Create('CLIENT', 'Connect', true));\n  LabelFilters.Add(TFilter.Create('CLIENT', 'Login', true));\n  LabelFilters.Add(TFilter.Create('CLIENT', 'Response', true));\n  LabelFilters.Add(TFilter.Create('CLIENT', 'Update', true));\n  LabelFilters.Add(TFilter.Create('CLIENT', 'Report', true));\n  LabelFilters.Add(TFilter.Create('PATCH', 'Status', false));\n  LabelFilters.Add(TFilter.Create('PATCH', 'Create', true));\n  LabelFilters.Add(TFilter.Create('PATCH', 'Edit', true));\n  LabelFilters.Add(TFilter.Create('PATCH', 'Check', true));\n  LabelFilters.Add(TFilter.Create('PATCH', 'Clean', true));\n  LabelFilters.Add(TFilter.Create('PATCH', 'Delete', true));\n  LabelFilters.Add(TFilter.Create('PATCH', 'Build', true));\n  LabelFilters.Add(TFilter.Create('PATCH', 'Report', true));\n  LabelFilters.Add(TFilter.Create('PLUGIN', 'Report', true));\n  LabelFilters.Add(TFilter.Create('PLUGIN', 'Check', true));\nend;\n\ninitialization\n  slLanguageMap := TStringList.Create;\r\n  slLanguageMap.Text :=\r\n    'English=en'#13 +\r\n    'French=fr'#13 +\r\n    'German=de'#13 +\r\n    'Italian=it'#13 +\r\n    'Spanish=es'#13 +\r\n    'Russian=ru'#13 +\r\n    'Polish=pl'#13 +\r\n    'Japanese=ja'#13 +\r\n    'Portugese=pt'#13 +\r\n    'Chinese=zh';\n\nfinalization\n  slLanguageMap.Free;\n\nend.\n"
  },
  {
    "path": "frontend/msOptionsForm.dfm",
    "content": "object OptionsForm: TOptionsForm\n  Left = 0\n  Top = 0\n  Caption = 'Settings'\n  ClientHeight = 447\n  ClientWidth = 584\n  Color = clBtnFace\n  Constraints.MaxHeight = 485\n  Constraints.MaxWidth = 600\n  Constraints.MinHeight = 485\n  Constraints.MinWidth = 600\n  Font.Charset = DEFAULT_CHARSET\n  Font.Color = clWindowText\n  Font.Height = -11\n  Font.Name = 'Tahoma'\n  Font.Style = []\n  OldCreateOrder = False\n  Position = poScreenCenter\n  OnCreate = FormCreate\n  PixelsPerInch = 96\n  TextHeight = 13\n  object SettingsPageControl: TPageControl\n    Left = 8\n    Top = 8\n    Width = 568\n    Height = 401\n    ActivePage = GeneralTabSheet\n    Align = alCustom\n    Anchors = [akLeft, akTop, akRight, akBottom]\n    TabOrder = 0\n    TabWidth = 80\n    object GeneralTabSheet: TTabSheet\n      Caption = 'General'\n      object gbStyle: TGroupBox\n        Left = 6\n        Top = 69\n        Width = 548\n        Height = 71\n        Margins.Left = 6\n        Margins.Top = 6\n        Margins.Right = 6\n        Margins.Bottom = 6\n        Align = alCustom\n        Caption = 'Style'\n        TabOrder = 0\n        object kbSimpleDictionary: TCheckBox\n          Left = 12\n          Top = 20\n          Width = 205\n          Height = 17\n          Align = alCustom\n          Caption = 'Simple dictionary view'\n          TabOrder = 0\n        end\n        object kbSimplePlugins: TCheckBox\n          Left = 12\n          Top = 43\n          Width = 205\n          Height = 17\n          Align = alCustom\n          Caption = 'Simple plugins list'\n          TabOrder = 1\n        end\n      end\n      object gbLanguage: TGroupBox\n        Left = 6\n        Top = 6\n        Width = 548\n        Height = 51\n        Margins.Left = 6\n        Margins.Top = 6\n        Margins.Right = 6\n        Margins.Bottom = 6\n        Align = alCustom\n        Caption = 'Language'\n        TabOrder = 1\n        object lblLanguage: TLabel\n          Left = 12\n          Top = 20\n          Width = 78\n          Height = 13\n          Margins.Left = 6\n          Margins.Top = 6\n          Margins.Right = 6\n          Margins.Bottom = 6\n          Align = alCustom\n          Caption = 'Current languge'\n        end\n        object cbLanguage: TComboBox\n          Left = 265\n          Top = 17\n          Width = 274\n          Height = 21\n          Margins.Left = 6\n          Margins.Top = 6\n          Margins.Right = 6\n          Margins.Bottom = 6\n          Align = alCustom\n          Style = csDropDownList\n          Anchors = [akTop, akRight]\n          TabOrder = 0\n        end\n      end\n    end\n    object PatchingTabSheet: TTabSheet\n      Caption = 'Patching'\n      ImageIndex = 1\n      ExplicitLeft = 0\n      ExplicitTop = 28\n      object gbGeneral: TGroupBox\n        Left = 3\n        Top = 3\n        Width = 554\n        Height = 54\n        Caption = 'General'\n        TabOrder = 0\n        object lblDestinationDirectory: TLabel\n          Left = 12\n          Top = 20\n          Width = 129\n          Height = 13\n          Caption = 'Patch destination directory'\n        end\n        object btnBrowsePatchDirectory: TSpeedButton\n          Left = 519\n          Top = 17\n          Width = 23\n          Height = 22\n          Hint = 'Browse'\n          Margins.Right = 6\n          ParentShowHint = False\n          ShowHint = True\n          OnClick = btnBrowsePatchDirectoryClick\n        end\n        object edPatchDirectory: TEdit\n          Left = 168\n          Top = 17\n          Width = 345\n          Height = 21\n          TabOrder = 0\n        end\n      end\n      object gbDebug: TGroupBox\n        Left = 3\n        Top = 63\n        Width = 554\n        Height = 146\n        Caption = 'Debug'\n        TabOrder = 1\n        object kbDebugPatchStatus: TCheckBox\n          Left = 12\n          Top = 24\n          Width = 200\n          Height = 17\n          Align = alCustom\n          Caption = 'Debug patch status'\n          TabOrder = 0\n        end\n        object kbDebugMasters: TCheckBox\n          Left = 12\n          Top = 47\n          Width = 200\n          Height = 17\n          Align = alCustom\n          Caption = 'Debug masters'\n          TabOrder = 1\n        end\n        object kbDebugArrays: TCheckBox\n          Left = 12\n          Top = 70\n          Width = 200\n          Height = 17\n          Align = alCustom\n          Caption = 'Debug arrays'\n          TabOrder = 2\n        end\n        object kbDebugSkips: TCheckBox\n          Left = 12\n          Top = 93\n          Width = 200\n          Height = 17\n          Align = alCustom\n          Caption = 'Debug skips'\n          TabOrder = 3\n        end\n        object kbDebugTraversal: TCheckBox\n          Left = 12\n          Top = 116\n          Width = 200\n          Height = 17\n          Align = alCustom\n          Caption = 'Debug traversal'\n          TabOrder = 4\n        end\n        object kbDebugTypes: TCheckBox\n          Left = 273\n          Top = 24\n          Width = 200\n          Height = 17\n          Align = alCustom\n          Caption = 'Debug types'\n          TabOrder = 5\n        end\n        object kbDebugChanges: TCheckBox\n          Left = 272\n          Top = 47\n          Width = 200\n          Height = 17\n          Align = alCustom\n          Caption = 'Debug changes'\n          TabOrder = 6\n        end\n        object kbDebugSingle: TCheckBox\n          Left = 272\n          Top = 72\n          Width = 200\n          Height = 17\n          Align = alCustom\n          Caption = 'Debug treat as single'\n          TabOrder = 7\n        end\n        object kbDebugLinks: TCheckBox\n          Left = 272\n          Top = 95\n          Width = 200\n          Height = 17\n          Align = alCustom\n          Caption = 'Debug links'\n          TabOrder = 8\n        end\n      end\n      object gbOther: TGroupBox\n        Left = 3\n        Top = 215\n        Width = 554\n        Height = 58\n        Caption = 'Other Options'\n        TabOrder = 2\n        object kbBuildRefs: TCheckBox\n          Left = 12\n          Top = 22\n          Width = 201\n          Height = 17\n          Align = alCustom\n          Caption = 'Build references'\n          TabOrder = 0\n        end\n        object kbPreserveITPOs: TCheckBox\n          Left = 273\n          Top = 22\n          Width = 201\n          Height = 17\n          Align = alCustom\n          Caption = 'Preserve ITPOs'\n          TabOrder = 1\n        end\n      end\n    end\n    object AdvancedTabSheet: TTabSheet\n      Caption = 'Advanced'\n      ImageIndex = 2\n      object gbLogging: TGroupBox\n        Left = 6\n        Top = 72\n        Width = 548\n        Height = 190\n        Margins.Left = 6\n        Margins.Top = 6\n        Margins.Right = 6\n        Margins.Bottom = 6\n        Align = alCustom\n        Anchors = [akLeft, akTop, akRight]\n        Caption = 'Logging'\n        TabOrder = 0\n        object lblClientColor: TLabel\n          Left = 12\n          Top = 20\n          Width = 27\n          Height = 13\n          Caption = 'Client'\n        end\n        object lblGeneralColor: TLabel\n          Left = 12\n          Top = 48\n          Width = 37\n          Height = 13\n          Margins.Left = 12\n          Margins.Top = 11\n          Caption = 'General'\n        end\n        object lblLoadColor: TLabel\n          Left = 12\n          Top = 76\n          Width = 23\n          Height = 13\n          Margins.Left = 12\n          Margins.Top = 11\n          Caption = 'Load'\n        end\n        object lblPatchColor: TLabel\n          Left = 274\n          Top = 20\n          Width = 27\n          Height = 13\n          Align = alCustom\n          Anchors = [akTop, akRight]\n          Caption = 'Patch'\n        end\n        object lblPluginColor: TLabel\n          Left = 274\n          Top = 48\n          Width = 28\n          Height = 13\n          Margins.Top = 11\n          Align = alCustom\n          Anchors = [akTop, akRight]\n          Caption = 'Plugin'\n        end\n        object lblErrorColor: TLabel\n          Left = 274\n          Top = 76\n          Width = 29\n          Height = 13\n          Margins.Top = 11\n          Align = alCustom\n          Anchors = [akTop, akRight]\n          Caption = 'Errors'\n        end\n        object lblSample: TLabel\n          Left = 12\n          Top = 155\n          Width = 34\n          Height = 13\n          Margins.Left = 12\n          Margins.Top = 6\n          Margins.Right = 6\n          Margins.Bottom = 6\n          Caption = 'Sample'\n        end\n        object lblSampleValue: TLabel\n          Left = 88\n          Top = 155\n          Width = 232\n          Height = 13\n          Margins.Left = 6\n          Margins.Top = 6\n          Margins.Right = 6\n          Margins.Bottom = 6\n          Caption = '[12:34] (GENERAL) Test: This is a test message.'\n          Font.Charset = DEFAULT_CHARSET\n          Font.Color = clGreen\n          Font.Height = -11\n          Font.Name = 'Tahoma'\n          Font.Style = []\n          ParentFont = False\n        end\n        object lblTemplate: TLabel\n          Left = 12\n          Top = 109\n          Width = 44\n          Height = 13\n          Margins.Left = 12\n          Margins.Top = 6\n          Margins.Right = 6\n          Margins.Bottom = 6\n          Caption = 'Template'\n        end\n        object cbClientColor: TColorBox\n          Left = 88\n          Top = 17\n          Width = 145\n          Height = 22\n          Selected = clBlue\n          Style = [cbStandardColors, cbExtendedColors, cbSystemColors, cbCustomColor, cbPrettyNames, cbCustomColors]\n          TabOrder = 0\n        end\n        object cbGeneralColor: TColorBox\n          Left = 88\n          Top = 45\n          Width = 145\n          Height = 22\n          Selected = clGreen\n          Style = [cbStandardColors, cbExtendedColors, cbSystemColors, cbCustomColor, cbPrettyNames, cbCustomColors]\n          TabOrder = 1\n        end\n        object cbLoadColor: TColorBox\n          Left = 88\n          Top = 73\n          Width = 145\n          Height = 22\n          Selected = clPurple\n          Style = [cbStandardColors, cbExtendedColors, cbSystemColors, cbCustomColor, cbPrettyNames, cbCustomColors]\n          TabOrder = 2\n        end\n        object cbPatchColor: TColorBox\n          Left = 392\n          Top = 17\n          Width = 145\n          Height = 22\n          Align = alCustom\n          Selected = 33023\n          Style = [cbStandardColors, cbExtendedColors, cbSystemColors, cbCustomColor, cbPrettyNames, cbCustomColors]\n          Anchors = [akTop, akRight]\n          TabOrder = 3\n        end\n        object cbPluginColor: TColorBox\n          Left = 392\n          Top = 45\n          Width = 145\n          Height = 22\n          Align = alCustom\n          Style = [cbStandardColors, cbExtendedColors, cbSystemColors, cbCustomColor, cbPrettyNames, cbCustomColors]\n          Anchors = [akTop, akRight]\n          TabOrder = 4\n        end\n        object cbErrorColor: TColorBox\n          Left = 392\n          Top = 73\n          Width = 145\n          Height = 22\n          Align = alCustom\n          Selected = clRed\n          Style = [cbStandardColors, cbExtendedColors, cbSystemColors, cbCustomColor, cbPrettyNames, cbCustomColors]\n          Anchors = [akTop, akRight]\n          TabOrder = 5\n        end\n        object meTemplate: TMemo\n          Left = 88\n          Top = 109\n          Width = 449\n          Height = 37\n          Align = alCustom\n          Anchors = [akLeft, akTop, akRight]\n          Lines.Strings = (\n            '[{{Time}}] ({{Group}}) {{Label}}: {{Text}}')\n          ScrollBars = ssVertical\n          TabOrder = 6\n          OnChange = meTemplateChange\n        end\n      end\n      object gbSmashProfile: TGroupBox\n        Left = 6\n        Top = 6\n        Width = 548\n        Height = 54\n        Margins.Left = 6\n        Margins.Top = 6\n        Margins.Right = 6\n        Margins.Bottom = 6\n        Align = alCustom\n        Anchors = [akLeft, akTop, akRight]\n        Caption = 'Smash Profile'\n        TabOrder = 1\n        object lblCurrentProfile: TLabel\n          Left = 12\n          Top = 24\n          Width = 70\n          Height = 13\n          Caption = 'Current profile'\n        end\n        object lblCurrentProfileName: TLabel\n          Left = 151\n          Top = 24\n          Width = 89\n          Height = 13\n          Margins.Left = 6\n          Margins.Top = 6\n          Margins.Right = 6\n          Margins.Bottom = 6\n          Caption = '<PROFILE NAME>'\n          Font.Charset = DEFAULT_CHARSET\n          Font.Color = clGreen\n          Font.Height = -11\n          Font.Name = 'Tahoma'\n          Font.Style = []\n          ParentFont = False\n        end\n        object btnChangeSmashProfile: TButton\n          Left = 392\n          Top = 18\n          Width = 150\n          Height = 25\n          Caption = 'Switch smash profiles'\n          TabOrder = 0\n          OnClick = btnChangeSmashProfileClick\n        end\n      end\n    end\n  end\n  object btnCancel: TButton\n    Left = 501\n    Top = 415\n    Width = 75\n    Height = 25\n    Align = alCustom\n    Anchors = [akRight, akBottom]\n    Caption = 'Cancel'\n    ModalResult = 2\n    TabOrder = 1\n  end\n  object btnOK: TButton\n    Left = 420\n    Top = 415\n    Width = 75\n    Height = 25\n    Align = alCustom\n    Anchors = [akRight, akBottom]\n    Caption = 'OK'\n    ModalResult = 1\n    TabOrder = 2\n    OnClick = btnOKClick\n  end\n  object IconList: TImageList\n    Left = 16\n    Top = 400\n    Bitmap = {\n      494C0101010008007C0110001000FFFFFFFFFF10FFFFFFFFFFFFFFFF424D3600\n      0000000000003600000028000000400000001000000001002000000000000010\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      00000000000000000000000000000000000075848FFF66808FFF607987FF576E\n      7BFF4E626FFF445661FF394852FF2E3A43FF252E35FF1B2229FF14191EFF0E12\n      16FF0E1318FF0000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      000000000000000000000000000000000000778792FF89A1ABFF6AB2D4FF008F\n      CDFF008FCDFF008FCDFF048CC7FF0888BEFF0F82B4FF157CA9FF1B779FFF1F72\n      96FF214A5BFEBDC2C44A00000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000007A8A95FF7EBED3FF8AA4AEFF7EDC\n      FFFF5FCFFFFF55CBFFFF4CC4FAFF41BCF5FF37B3F0FF2EAAEBFF24A0E5FF138C\n      D4FF236780FF5E686CB400000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000007D8E98FF79D2ECFF8BA4ADFF89C2\n      CEFF71D8FFFF65D3FFFF5CCEFFFF51C9FEFF49C1FAFF3FB9F5FF34B0EEFF29A8\n      E9FF1085CDFF224B5BFFDADDDF27000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      00000000000000000000000000000000000080919CFF81D7EFFF7DC5E0FF8CA6\n      B0FF80DDFEFF68D3FFFF67D4FFFF62D1FFFF58CDFFFF4EC7FCFF46BEF7FF3BB6\n      F2FF31ACECFF256981FF7A95A190000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      00000000000000000000000000000000000083959FFF89DCF1FF8CE2FFFF8DA8\n      B1FF8CBAC7FF74D8FFFF67D4FFFF67D4FFFF67D4FFFF5FD0FFFF54CDFFFF4BC5\n      FCFF41BBF7FF2EA2DBFF516674F1E1E4E62B0000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      000000000000000000000000000000000000869AA3FF92E1F2FF98E8FDFF80C4\n      DEFF8EA7B0FF81DEFDFF84E0FFFF84E0FFFF84E0FFFF84E0FFFF81DFFFFF7BDD\n      FFFF74D8FFFF6BD6FFFF56A9D1FF8E9BA3A20000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      000000000000000000000000000000000000889CA5FF9AE6F3FF9FEBFBFF98E8\n      FEFF8BACB9FF8BACB9FF8AAAB7FF88A6B3FF86A3AFFF839FAAFF819AA6FF7F95\n      A1FF7C919DFF7A8E99FF798B95FF778893FF0000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000008BA0A8FFA0EAF6FFA6EEF9FF9FEB\n      FBFF98E8FEFF7ADAFFFF67D4FFFF67D4FFFF67D4FFFF67D4FFFF67D4FFFF67D4\n      FFFF778893FF0000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000008EA2ABFFA7EEF6FFABF0F7FFA6EE\n      F9FF9FEBFBFF98E8FDFF71D4FBFF899EA7FF8699A3FF82949FFF7E909AFF7A8C\n      97FF778893FF0000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000008FA4ACFFA0D2DAFFABF0F7FFABF0\n      F7FFA6EEF9FF9FEBFBFF8DA1AAFFC0D0D6820000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      000000000000000000000000000000000000D8DFE2578FA4ACFF8FA4ACFF8FA4\n      ACFF8FA4ACFF8FA4ACFFBDCFD68D000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      000000000000000000000000000000000000424D3E000000000000003E000000\n      2800000040000000100000000100010000000000800000000000000000000000\n      000000000000000000000000FFFFFF00FFFF000000000000FFFF000000000000\n      0007000000000000000300000000000000030000000000000001000000000000\n      0001000000000000000000000000000000000000000000000000000000000000\n      0007000000000000000700000000000000FF00000000000001FF000000000000\n      FFFF000000000000FFFF00000000000000000000000000000000000000000000\n      000000000000}\n  end\nend\n"
  },
  {
    "path": "frontend/msOptionsForm.pas",
    "content": "unit msOptionsForm;\n\ninterface\n\nuses\n  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,\n  Dialogs, ComCtrls, StdCtrls, Buttons, ImgList, FileCtrl, ExtCtrls, Types,\n  // mte units\n  mteHelpers, RttiTranslation,\n  // mp units\n  msConfiguration;\n\ntype\n  TOptionsForm = class(TForm)\n    [FormPrefix('mpOpt')]\n      SettingsPageControl: TPageControl;\n      btnCancel: TButton;\n      btnOK: TButton;\n      IconList: TImageList;\n      [FormSection('General Tab')]\n        GeneralTabSheet: TTabSheet;\n        gbLanguage: TGroupBox;\n        lblLanguage: TLabel;\n        gbStyle: TGroupBox;\n        kbSimpleDictionary: TCheckBox;\n        kbSimplePlugins: TCheckBox;\n        [FormSection('DontTranslate')]\n          cbLanguage: TComboBox;\n      [FormSection('Patching Tab')]\n        PatchingTabSheet: TTabSheet;\n        gbGeneral: TGroupBox;\n        edPatchDirectory: TEdit;\n        lblDestinationDirectory: TLabel;\n        btnBrowsePatchDirectory: TSpeedButton;\n        gbDebug: TGroupBox;\n        kbDebugPatchStatus: TCheckBox;\n        kbDebugMasters: TCheckBox;\n        kbDebugArrays: TCheckBox;\n        kbDebugSkips: TCheckBox;\n        kbDebugTraversal: TCheckBox;\n        kbDebugTypes: TCheckBox;\n        kbDebugChanges: TCheckBox;\n        kbDebugSingle: TCheckBox;\n        kbDebugLinks: TCheckBox;\n        gbOther: TGroupBox;\n        kbBuildRefs: TCheckBox;\n        kbPreserveITPOs: TCheckBox;\n      [FormSection('Advanced Tab')]\n        AdvancedTabSheet: TTabSheet;\n        lblCurrentProfile: TLabel;\n        gbLogging: TGroupBox;\n        lblClientColor: TLabel;\n        cbClientColor: TColorBox;\n        lblGeneralColor: TLabel;\n        cbGeneralColor: TColorBox;\n        lblLoadColor: TLabel;\n        cbLoadColor: TColorBox;\n        lblPluginColor: TLabel;\n        cbPluginColor: TColorBox;\n        lblErrorColor: TLabel;\n        cbErrorColor: TColorBox;\n        lblTemplate: TLabel;\n        meTemplate: TMemo;\n        lblSample: TLabel;\n        [FormSection('DontTranslate')]\n          lblCurrentProfileName: TLabel;\n          lblSampleValue: TLabel;\n\n    procedure FormCreate(Sender: TObject);\n    procedure LoadLanguageOptions;\n    procedure btnOKClick(Sender: TObject);\n    procedure btnBrowsePatchDirectoryClick(Sender: TObject);\n    procedure meTemplateChange(Sender: TObject);\n    procedure appendBackslashOnExit(Sender: TObject);\n    procedure btnChangeSmashProfileClick(Sender: TObject);\n  private\n    { Private declarations }\n  public\n    { Public declarations }\n  end;\n\nvar\n  OptionsForm: TOptionsForm;\n  slSampleLogMessage: TStringList;\n\nimplementation\n\n{$R *.dfm}\n\nprocedure TOptionsForm.btnBrowsePatchDirectoryClick(Sender: TObject);\nbegin\n  BrowseForFolder(edPatchDirectory, PathList.Values['ProgramPath']);\nend;\n\nprocedure TOptionsForm.btnOKClick(Sender: TObject);\nbegin\n  // check if we need to update patch status afterwards\n  ProgramStatus.bUpdatePatchStatus := settings.patchDirectory <> edPatchDirectory.Text;\n\n  // General > Language\n  settings.language := cbLanguage.Text;\n  // General > Style\n  settings.simpleDictionaryView := kbSimpleDictionary.Checked;\n  settings.simplePluginsView := kbSimplePlugins.Checked;\n\n  // Patching > General\n  settings.patchDirectory := edPatchDirectory.Text;\n  // Patching > Debug\n  settings.debugPatchStatus := kbDebugPatchStatus.Checked;\n  settings.debugMasters := kbDebugMasters.Checked;\n  settings.debugArrays := kbDebugArrays.Checked;\n  settings.debugSkips := kbDebugSkips.Checked;\n  settings.debugTraversal := kbDebugTraversal.Checked;\n  settings.debugTypes := kbDebugTypes.Checked;\n  settings.debugChanges := kbDebugChanges.Checked;\n  settings.debugSingle := kbDebugSingle.Checked;\n  settings.debugLinks := kbDebugLinks.Checked;\n  settings.buildRefs := kbBuildRefs.Checked;\n  settings.preserveITPOs := kbPreserveITPOs.Checked;\n\n  // Advanced > Logging\n  settings.clientMessageColor := cbClientColor.Selected ;\n  settings.generalMessageColor := cbGeneralColor.Selected;\n  settings.loadMessageColor := cbLoadColor.Selected;\n  //settings.patchMessageColor := cbPatchColor.Selected;\n  settings.pluginMessageColor := cbPluginColor.Selected;\n  settings.errorMessageColor := cbErrorColor.Selected;\n  settings.logMessageTemplate := meTemplate.Lines.Text;\n\n  SaveSettings;\nend;\n\nprocedure TOptionsForm.btnChangeSmashProfileClick(Sender: TObject);\nbegin\n  ProgramStatus.bChangeProfile := true;\n  btnOKClick(nil);\n  Close;\nend;\n\nprocedure TOptionsForm.appendBackslashOnExit(Sender: TObject);\nvar\n  ed: TEdit;\nbegin\n  // add trailing backslash if length > 0 and it is missing\n  ed := TEdit(Sender);\n  if Length(ed.Text) > 0 then\n    ed.Text := AppendIfMissing(ed.Text, '\\');\nend;\n\nprocedure TOptionsForm.LoadLanguageOptions;\nvar\n  info: TSearchRec;\n  sLang: string;\nbegin\n  cbLanguage.Items.Add('English');\n  cbLanguage.ItemIndex := 0;\n  if not DirectoryExists('lang') then\n    exit;\n  if FindFirst('lang\\*.lang', faAnyFile, info) <> 0 then\n    exit;\n  repeat\n    sLang := TitleCase(ChangeFileExt(info.Name, ''));\n    if sLang <> 'English' then\n      cbLanguage.Items.Add(sLang);\n  until FindNext(info) <> 0;\n  FindClose(info);\nend;\n\nprocedure TOptionsForm.FormCreate(Sender: TObject);\nvar\n  index: Integer;\nbegin\n  // do translation dump?\n  if bTranslationDump then\n    TRttiTranslation.Save('lang\\english.lang', self);\n\n  // load translation\n  TRttiTranslation.Load(language, self);\n\n  // prepare sample log message\n  slSampleLogMessage := TStringList.Create;\n  slSampleLogMessage.Values['Time'] := '12:34:56';\n  slSampleLogMessage.Values['AppTime'] := '00:01:52';\n  slSampleLogMessage.Values['Group'] := 'GENERAL';\n  slSampleLogMessage.Values['Label'] := 'Test';\n  slSampleLogMessage.Values['Text'] := 'This is a test message.';\n\n  // General > Language\n  LoadLanguageOptions;\n  index := cbLanguage.Items.IndexOf(settings.language);\n  if index > -1 then\n    cbLanguage.ItemIndex := index;\n  // General > Style\n  kbSimpleDictionary.Checked := settings.simpleDictionaryView;\n  kbSimplePlugins.Checked := settings.simplePluginsView;\n\n  // Patching > General\n  edPatchDirectory.Text := settings.patchDirectory;\n  // Patching > Debug\n  kbDebugPatchStatus.Checked := settings.debugPatchStatus;\n  kbDebugMasters.Checked := settings.debugMasters;\n  kbDebugArrays.Checked := settings.debugArrays;\n  kbDebugSkips.Checked := settings.debugSkips;\n  kbDebugTraversal.Checked := settings.debugTraversal;\n  kbDebugTypes.Checked := settings.debugTypes;\n  kbDebugChanges.Checked := settings.debugChanges;\n  kbDebugSingle.Checked := settings.debugSingle;\n  kbDebugLinks.Checked := settings.debugLinks;\n  kbBuildRefs.Checked := settings.buildRefs;\n  kbPreserveITPOs.Checked := settings.preserveITPOs;\n\n  // Advanced > Profile\n  lblCurrentProfileName.Caption := settings.profile;\n  // Advanced > Logging\n  cbClientColor.Selected := TColor(settings.clientMessageColor);\n  cbGeneralColor.Selected := TColor(settings.generalMessageColor);\n  cbLoadColor.Selected := TColor(settings.loadMessageColor);\n  //cbPatchColor.Selected := TColor(settings.patchMessageColor);\n  cbPluginColor.Selected := TColor(settings.pluginMessageColor);\n  cbErrorColor.Selected := TColor(settings.errorMessageColor);\n  meTemplate.Lines.Text := settings.logMessageTemplate;\n\n  // set up browse buttons\n  btnBrowsePatchDirectory.Flat := true;\n  IconList.GetBitmap(0, btnBrowsePatchDirectory.Glyph);\nend;\n\nprocedure TOptionsForm.meTemplateChange(Sender: TObject);\nvar\n  template: string;\nbegin\n  template := meTemplate.Lines.Text;\n  lblSampleValue.Caption := ApplyTemplate(template, slSampleLogMessage);\nend;\n\nend.\n"
  },
  {
    "path": "frontend/msPluginSelectionForm.dfm",
    "content": "object MiniPluginSelectionForm: TMiniPluginSelectionForm\n  Left = 0\n  Top = 0\n  Caption = 'Plugin selection'\n  ClientHeight = 424\n  ClientWidth = 334\n  Color = clBtnFace\n  Constraints.MaxHeight = 1500\n  Constraints.MaxWidth = 700\n  Constraints.MinHeight = 400\n  Constraints.MinWidth = 350\n  Font.Charset = DEFAULT_CHARSET\n  Font.Color = clWindowText\n  Font.Height = -11\n  Font.Name = 'Tahoma'\n  Font.Style = []\n  OldCreateOrder = False\n  Position = poScreenCenter\n  OnShow = FormShow\n  PixelsPerInch = 96\n  TextHeight = 13\n  object lblPrompt: TLabel\n    Left = 8\n    Top = 8\n    Width = 311\n    Height = 26\n    Align = alCustom\n    Anchors = [akLeft, akTop, akRight]\n    Caption = \n      'Select the plugins you want to base the setting tree off of.  Th' +\n      'is  should be the plugins you plan to use this setting with. '\n    WordWrap = True\n  end\n  object CheckListBox: TCheckListBox\n    Left = 8\n    Top = 45\n    Width = 318\n    Height = 335\n    Margins.Top = 8\n    Margins.Bottom = 8\n    Align = alCustom\n    Anchors = [akLeft, akTop, akRight, akBottom]\n    ItemHeight = 13\n    PopupMenu = CheckListPopupMenu\n    TabOrder = 0\n    OnClick = CheckListBoxClick\n    OnKeyUp = CheckListBoxKeyUp\n  end\n  object btnOK: TButton\n    Left = 170\n    Top = 391\n    Width = 75\n    Height = 25\n    Align = alCustom\n    Anchors = [akRight, akBottom]\n    Caption = 'OK'\n    TabOrder = 1\n    OnClick = btnOKClick\n  end\n  object btnCancel: TButton\n    Left = 251\n    Top = 391\n    Width = 75\n    Height = 25\n    Align = alCustom\n    Anchors = [akRight, akBottom]\n    Caption = 'Cancel'\n    ModalResult = 2\n    TabOrder = 2\n  end\n  object CheckListPopupMenu: TPopupMenu\n    Left = 64\n    Top = 64\n    object SelectAllItem: TMenuItem\n      Caption = 'Select all'\n      OnClick = SelectAllItemClick\n    end\n    object SelectNoneItem: TMenuItem\n      Caption = 'Select none'\n      OnClick = SelectNoneItemClick\n    end\n    object InvertSelectionItem: TMenuItem\n      Caption = 'Invert selection'\n      OnClick = InvertSelectionItemClick\n    end\n  end\nend\n"
  },
  {
    "path": "frontend/msPluginSelectionForm.pas",
    "content": "unit msPluginSelectionForm;\n\ninterface\n\nuses\n  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,\n  Dialogs, StdCtrls, CheckLst, Menus, ComCtrls;\n\ntype\n  TMiniPluginSelectionForm = class(TForm)\n    CheckListBox: TCheckListBox;\n    btnOK: TButton;\n    lblPrompt: TLabel;\n    btnCancel: TButton;\n    CheckListPopupMenu: TPopupMenu;\n    SelectAllItem: TMenuItem;\n    SelectNoneItem: TMenuItem;\n    InvertSelectionItem: TMenuItem;\n    procedure FormShow(Sender: TObject);\n    procedure CheckListBoxClick(Sender: TObject);\n    procedure btnOKClick(Sender: TObject);\n    procedure CheckListBoxKeyUp(Sender: TObject; var Key: Word;\n      Shift: TShiftState);\n    procedure SelectAllItemClick(Sender: TObject);\n    procedure SelectNoneItemClick(Sender: TObject);\n    procedure InvertSelectionItemClick(Sender: TObject);\n  private\n    { Private declarations }\n  public\n    { Public declarations }\n    pluginsList: TStringList;\n    selectionList: TStringList;\n  end;\n\nvar\n  MiniPluginSelectionForm: TMiniPluginSelectionForm;\n\nimplementation\n\n{$R *.dfm}\n\nprocedure TMiniPluginSelectionForm.btnOKClick(Sender: TObject);\nvar\n  i: Integer;\nbegin\n  selectionList.Clear;\n  for i := 0 to Pred(CheckListBox.Items.Count) do begin\n    if CheckListBox.Checked[i] then\n      selectionList.Add(CheckListBox.Items[i]);\n  end;\n  if selectionList.Count > 0 then\n    ModalResult := mrOK;\nend;\n\nprocedure TMiniPluginSelectionForm.CheckListBoxClick(Sender: TObject);\nvar\n  i: Integer;\nbegin\n  btnOK.Enabled := false;\n  for i := 0 to Pred(CheckListBox.Items.Count) do begin\n    if CheckListBox.Checked[i] then begin\n      btnOK.Enabled := true;\n      break;\n    end;\n  end;\nend;\n\nprocedure TMiniPluginSelectionForm.CheckListBoxKeyUp(Sender: TObject; var Key: Word;\n  Shift: TShiftState);\nbegin\n  CheckListBoxClick(nil);\nend;\n\nprocedure TMiniPluginSelectionForm.FormShow(Sender: TObject);\nvar\n  i, index: Integer;\nbegin\n  CheckListBox.Items.Text := pluginsList.Text;\n  for i := 0 to Pred(selectionList.Count) do begin\n    index := pluginsList.IndexOf(selectionList[i]);\n    if index > -1 then\n      CheckListBox.Checked[index] := true;\n  end;\n\n  // reset OK button enabled state\n  CheckListBoxClick(nil);\nend;\n\nprocedure TMiniPluginSelectionForm.InvertSelectionItemClick(Sender: TObject);\nvar\n  i: Integer;\nbegin\n  for i := 0 to Pred(CheckListBox.GetCount) do\n    CheckListBox.Checked[i] := not CheckListBox.Checked[i];\n\n  // reset OK button enabled state\n  CheckListBoxClick(nil);\nend;\n\nprocedure TMiniPluginSelectionForm.SelectAllItemClick(Sender: TObject);\nbegin\n  CheckListBox.CheckAll(cbChecked);\n\n  // reset OK button enabled state\n  CheckListBoxClick(nil);\nend;\n\nprocedure TMiniPluginSelectionForm.SelectNoneItemClick(Sender: TObject);\nbegin\n  CheckListBox.CheckAll(cbUnChecked);\n\n  // reset OK button enabled state\n  CheckListBoxClick(nil);\nend;\n\nend.\n"
  },
  {
    "path": "frontend/msPriorityForm.dfm",
    "content": "object PriorityForm: TPriorityForm\n  Left = 0\n  Top = 0\n  Caption = 'Change node priority'\n  ClientHeight = 134\n  ClientWidth = 300\n  Color = clBtnFace\n  Constraints.MaxHeight = 172\n  Constraints.MaxWidth = 316\n  Constraints.MinHeight = 172\n  Constraints.MinWidth = 316\n  Font.Charset = DEFAULT_CHARSET\n  Font.Color = clWindowText\n  Font.Height = -11\n  Font.Name = 'Tahoma'\n  Font.Style = []\n  OldCreateOrder = False\n  Position = poScreenCenter\n  PixelsPerInch = 96\n  TextHeight = 13\n  object lblPriority: TLabel\n    Left = 24\n    Top = 67\n    Width = 34\n    Height = 13\n    Caption = 'Priority'\n  end\n  object lblPrompt: TLabel\n    Left = 8\n    Top = 8\n    Width = 284\n    Height = 39\n    Caption = \n      'Change a node'#39's priority to adjust how it conflict resolves with' +\n      ' other nodes.  Values from higher priority nodes will be favored' +\n      ' over values from lower priority nodes.'\n    WordWrap = True\n  end\n  object btnCancel: TButton\n    Left = 217\n    Top = 101\n    Width = 75\n    Height = 25\n    Caption = 'Cancel'\n    ModalResult = 2\n    TabOrder = 0\n  end\n  object btnOK: TButton\n    Left = 136\n    Top = 101\n    Width = 75\n    Height = 25\n    Caption = 'OK'\n    TabOrder = 1\n    OnClick = btnOKClick\n  end\n  object edPriority: TEdit\n    Left = 88\n    Top = 64\n    Width = 121\n    Height = 21\n    NumbersOnly = True\n    TabOrder = 2\n    Text = '0'\n  end\nend\n"
  },
  {
    "path": "frontend/msPriorityForm.pas",
    "content": "unit msPriorityForm;\n\ninterface\n\nuses\n  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,\n  Dialogs, StdCtrls;\n\ntype\n  TPriorityForm = class(TForm)\n    lblPriority: TLabel;\n    lblPrompt: TLabel;\n    btnCancel: TButton;\n    btnOK: TButton;\n    edPriority: TEdit;\n    procedure btnOKClick(Sender: TObject);\n  private\n    { Private declarations }\n  public\n    { Public declarations }\n    priority: Byte;\n  end;\n\nvar\n  PriorityForm: TPriorityForm;\n\nimplementation\n\n{$R *.dfm}\n\nprocedure TPriorityForm.btnOKClick(Sender: TObject);\nbegin\n  priority := StrToInt(edPriority.Text) mod 255;\n  ModalResult := mrOK;\nend;\n\nend.\n"
  },
  {
    "path": "frontend/msProfileForm.dfm",
    "content": "object ProfileForm: TProfileForm\n  Left = 0\n  Top = 0\n  Caption = 'Select Profile'\n  ClientHeight = 467\n  ClientWidth = 475\n  Color = clBtnFace\n  Constraints.MaxWidth = 491\n  Constraints.MinHeight = 250\n  Constraints.MinWidth = 491\n  Font.Charset = DEFAULT_CHARSET\n  Font.Color = clWindowText\n  Font.Height = -11\n  Font.Name = 'Tahoma'\n  Font.Style = []\n  OldCreateOrder = False\n  Position = poScreenCenter\n  OnClose = FormClose\n  OnCreate = FormCreate\n  PixelsPerInch = 96\n  TextHeight = 13\n  object btnOk: TButton\n    Left = 311\n    Top = 434\n    Width = 75\n    Height = 25\n    Align = alCustom\n    Anchors = [akRight, akBottom]\n    Caption = 'OK'\n    Enabled = False\n    ModalResult = 1\n    TabOrder = 0\n  end\n  object btnCancel: TButton\n    Left = 392\n    Top = 434\n    Width = 75\n    Height = 25\n    Align = alCustom\n    Anchors = [akRight, akBottom]\n    Caption = 'Cancel'\n    ModalResult = 2\n    TabOrder = 1\n  end\n  object ScrollBox: TScrollBox\n    Left = 8\n    Top = 8\n    Width = 459\n    Height = 420\n    HorzScrollBar.Visible = False\n    VertScrollBar.Tracking = True\n    Align = alCustom\n    Anchors = [akLeft, akTop, akRight, akBottom]\n    Color = clBtnFace\n    ParentColor = False\n    PopupMenu = ProfilePopupMenu\n    TabOrder = 2\n    object PaddingLabel: TLabel\n      Left = 3\n      Top = 100\n      Width = 3\n      Height = 13\n    end\n    object NewProfilePanel: TPanel\n      Left = 0\n      Top = 0\n      Width = 431\n      Height = 100\n      Cursor = crHandPoint\n      Margins.Left = 0\n      Margins.Top = 0\n      Margins.Right = 0\n      Margins.Bottom = 0\n      Align = alCustom\n      Anchors = [akLeft, akTop, akRight]\n      DoubleBuffered = False\n      ParentBackground = False\n      ParentDoubleBuffered = False\n      TabOrder = 0\n      OnClick = NewProfilePanelClick\n      OnMouseMove = NewProfilePanelMouseMove\n      object NewProfileImage: TImage\n        Left = 2\n        Top = 2\n        Width = 96\n        Height = 96\n        Cursor = crHandPoint\n        Picture.Data = {\n          0954506E67496D61676589504E470D0A1A0A0000000D49484452000000600000\n          00600806000000E298773800000006624B474400FF00FF00FFA0BDA793000000\n          097048597300000B1300000B1301009A9C180000000774494D4507DF09170328\n          04B714DDE70000164A4944415478DAED5C7B6C96D7797FCEF90C18DB9870BF24\n          A13469CB754BD769092529104203E4D2402E840C02445DBB4CCAA6459A347DD9\n          A6558B97495BD6A228DDD6269DB6496DD2AEE9B4A9524AD5E68FFDB1A81A0182\n          0DBE703536181BDB800DBE7E7ECFCEF539CF39EFFB994C4DB0FF781F64FCBD97\n          EFFBCEFBFC9EE7F75CCE39663049E485D3025EBF83D153CCFE7C1C226E703C61\n          F2713DE0AF25AF09017FC4182CBCEF6FE6F3CA857B66D44C9B0D5A49428F4F5E\n          9207DC9C92430E07CDC22761F4C0DC3F564A92C1FEEE5FB5BFF787BFE01595A5\n          A43454824902C2A40040C9FC2FBE3C6FD1D2D5BFDCBEF5EED533675633218C86\n          C6E4FFEA77628F85BC90A863FDDA9CD7AFF58FC0E3C4DEABCE4BFD43D3E13363\n          270EBFFFB5333FFFE31FC953C3FAA3270108930680459BBEF7E2F3FBB6BEBA78\n          CE3476A6FD0A6BBF340A4962D4AA9469356C3466152BF037A02A137D4EB94C22\n          CF337D41140AA272C95C76FCBF3FE83BFA6F0F2D0503C020E4007859B6EDAD57\n          9E7F6E6BB1ABB3077E76B05FABC6508F271D1C6C403337780A7B6DE69D73456F\n          53233BF2E603B7C9C3EBF2477E89F6820995C902005BB6FD0775BFBFEFA1978E\n          347440FDD961A828301D0198FE4FFD561141900810713FB56504CEBE965E31E3\n          D373E17273131C7E73E31DF26C9FFCB92A7F4A13FEE0133D002B7CD9F6EFD77D\n          6DDFC3C50F25000DAD2350C1ADAA99A119C6EC502D20E675C69330130BD4BB15\n          35317B5BED1D73A0B7A9590270FF9DE001189DE8079F4400BC55F77B7BB7148F\n          345C84C6732350E06674698B171E0401E113301B2490BBCC45E5011A806609C0\n          1B390059C2974B0A7A6EEFD6E25109409302A0608787164F82423C7A771DFC75\n          C13C42D2172405E5008C277CF9E36FD5EDDBB3A578B4FE2234B72B0F307598E2\n          7DF4036AF1E3289DB9DFF6664549B53206F4280A7A63430E40864800DEAEDBF3\n          ECE66243830260540340E91E95EF141F518D671C611FCCBD5F476198B1740EF4\n          B44800BE9B0390251A80672500C7EA3BA0F97C09B80AC261411B8E38B67A9B2A\n          51C59B9020F4B102E0B2A4A043390099A201D8B5FBC1E271E9012D174AC60304\n          7810480C104ED9CC58B7FA8D292BB917C385BCA7460270A52507A09C48007E58\n          F78C04A0517AC0890EEB0138426C0B5944048E3EA61ACC7CC0274A9A823E9D7B\n          C078A201D8B94B0170014E5E1C935990551F92BBB368A10F1930AC0F1CD580F5\n          9AE001993951F32909404B0B1CFACEFA1C800CE1CB9FFC51DD8E6736159BA407\n          9CEA940038F37754A2284740443731D5B8B7D8CCC93A85FA99B174760EC038A2\n          017872E7A66273C30538DD99486366965E5C80B59482ED09A3644A35CEDAB322\n          768D02A03907A09C68009E9000B44800CE740A1D039C8AB5255B40683A4A5B0D\n          CEEA950801BE16602668D77CCA7AC03FADCB01C810BE4202B05D027042C680D3\n          5D42C700E6321F20D98E7D8340BA891FC72B9DF96E1C54E7008C2B1A80C79E7E\n          4002D001ADDDCA03406BD7E4F3427B80C96880F0BC7B04DBAEA6B46453566627\n          741405F5369F90007C29072043F88AA7FEBDEED1A736164F3548007A7442635B\n          093ED066D10D553EB57A16A4A4D6037200CA8A06E01109C0690B80CE8230E3B1\n          2D662C0C5C916694EC688891B6840BDAAE66A85E927BC078A201784802704652\n          505B2F90201C7496B1D6723CEF8AB1A0131D28DF80A582706F8B04E01FEFCB01\n          C81009C08FEBB63EB5A178B6FE22B45DB60516C49443E88664459AE7D10D2C08\n          C275518D0B552F99253DE0640E4019D1006C7E7243B1557A40FB158E561E0C16\n          B31BAF78A4297D83D03582B037E38C9A3C512501B89C03505634005F7EC20070\n          E12A971464D34E1107D928C04674636FB65E611F5100F1807B730032842F9700\n          6C9200B42900FA98AE8483F4329A13765531B769267A06104A22996AF5ED1280\n          1609C03FE40064095FB1E39DBA8D8F6F28B6CB4A587B80CE6E44D47063E071C1\n          D69C8F172E122318AE852D60BAA6A0531280B5390019C2574A00363CBEBED87E\n          B4033AFA0B50E03EAF77BC8E198E9B980740AE17F1399A35410EC08D84AF7CFA\n          9DBA75DBD6172FC82CE8E235A9404EB21CCBFFD87A402B077D805C1FCC029319\n          357954A529E8341CFAF6177300324402F093BAFB24001DD2033A070C05218358\n          AB776B7D82202B3CF7BBBC55C706E6294A49D56DB7E4008C237C8504E0DEC7D6\n          172FCA207C69A0A0832BA6985AB1BEFB861E2100F37C7D2FC66A5F21BB385C7D\n          DB2CE85114940390297CC5CE9FD4ADFD8A04E0E845E81EB4561D29DF9D334D39\n          F39A5BBA7131028B366C619BC05CA500501EF0FA9AC907C0CBF201FF22DDD7BD\n          A9E0A82C68CD63F717BBA407740FCA428CBB600B80B35B8E7232AC9EC6098C0F\n          C23FC4F4DB6F911E9002E0662ECECDDC24C25E3821E0F5CF325874EF2B0B60FA\n          825D336AA6CF658E495DB94FFBF2014610B8BA9F444FDF872939F31D4BD73453\n          8BFA7961EAFADF79F4DEB597640CE81E3285186011C6C0CD407A1D6729DF57BF\n          CC7397FE8C4A15032400FDEDC75EAFA8BC65944FA91C912827F1768F68097674\n          6D7C9B0C7510CAD868928CF677BF7FF23F77BFC7A7549592D101BD4944DF2A95\n          3F7FFEED2B7EB1FDE1BB57CFACAD66B8E1C16E86A01B24127DCE3C7C623744E8\n          F3EE7E7AEC364C08BFA1427DA33966E4338D82A74E9F26DA7F7596F50E39BA71\n          E0BAF5A07E9E17E32EA990DD34A5EB8A7AC30198B6A816A6CC9A26872858608B\n          9152195564A450B21E23D4B13DC9C9C77116BD573E6CCF890B639DC70F3EDFFC\n          CEDEB7C06E12D197176FFAE73F79FEB9AD7FBB68F61438DD76959DBF34824A07\n          AB38F7C26D88C0CD11B842CADF4FDFE340710311899F36349FC582E71818E3A0\n          361031176C496F9911570BAC9EB6A3093D9956865F3F84AB59620B4530FD051B\n          6ED0DB9C8233DE86EF65E4BD143445A750511085C5B5ECFCC1E6C143DF5E73AB\n          056050DFB662FBDBAF7C7DDFE66257572F1CF8DF7E92EA65D04A160B9120E806\n          9B7E9FEF68621F9FDA1BF3CD3586964E331F4829DF5093B0ED686772FE339CAB\n          382562F30E4745565530169CF34CC4BC356175475E6392409492C554F296A98B\n          6A456FD3197670FF6FE32611AD9165DBD4E6882D2F1D39DE899B234CB0A39B22\n          4835EABE5F10F707D226A6132310B693692BD94D35E21423A5998076FC9274D7\n          03C2E529602A650CD2C436CC1CB22FD8BC07D91A01C71DD215CB50BAEF3261F4\n          42E0D21E9161ACF2EEA90B6AA1A7E92C1CDCFF05B749E48ABA852FDBF6FDBAAF\n          EFDD5A3C7CAC138E9F1B9601910117644908B8948EF0AFA607A754AA7C922A06\n          E36381E5864596B7AAF2B44366C41CDF471911A51C4F2744B1C22CDEF20313FE\n          3E62F53E98D20789362304C0645E0A1D407EF7D485B5D07D5C03E032310FC057\n          F76E291E3DD605C7CED9DD29EE0BD52FEE791B1729A8C10B6E4132F7B8E58182\n          FB192A35B98E3C6FD773224829E58F473BEE7BCDD8822C07A7C842E5A3228842\n          0409A52230D1B09D4DCFE13CB3C35EFDE3E5339E20E3241F35457A4077632B1C\n          FCD66F85002C9714F4DC9ECDC50F2505359D1B9514E4D61BB3D48798EDBA21F5\n          18C5724F29A8D334EF9BECD67A0B71294317E568C77235373CCE04B9DFC50CA2\n          3805E2984A0A129B95099FC539A521B1069133B25EA47352143A6F26CEA83BB7\n          DCCC63ABD7BCE0EEF040080DC08CF200EC9500D44B0F686A531E60AD5E789E0D\n          CA7C4203B83836E07DE2DA00BEAAC595CD2A33F093B886D769864369C7F22EF7\n          0FAEFE4F081B27B29C1A931A2E29C527C466ACB53A4043BA090374261D31EA01\n          01226190766B58A3DB1C186A7E5B81A300E8C90240ED50DCBB7B73B141C600B5\n          39C2206876A6BB20E603BFB0C0586B247387DEC2A2A09BC1FB1CC24C8606E060\n          ED0FF97CA768FDE3AC3A71F7F8C08B0AA7ED5317F8698A48A826503EDD9513BC\n          3FD430A619E31668DE1314055D3BD90A87F66700B067F78312802E68393F6A56\n          2627CAE589329C6251F924880AB27CC4D371D4CFF1994A2AE3092C9F2C35616A\n          97BB80911101A363103A358EC95190072B48674910C6EF20995190A6DAEC08BD\n          8E7A030523008FD0129E8ABB0E462A140027CE49003E9F0660D7AE2F171B1500\n          6E734480B8B7EA30ADE3E935F90C03853DCDC14D11BAEC0951C2CAD5BBB6DED1\n          224F0F9712181E71EB81986344C085BAD16BAC2B481CA5C193D251502BD8317B\n          85B2105CF76431A5A2E7048454DE23E4431524056900BE1501A036C83DF3BB0A\n          804E90D5B2D9204753611B78017C7B98A1399BEF1789E5753013E9DCCE687120\n          AB16B0BF13D603DAD24BD2D2E54F4992782971F743C62A694A2F0034E3F17428\n          D0FBF05A5435D3C4C0A7B7590A8E159FED25D45053FD252B857933A0FF446B1A\n          80650A80673669004E76247687A2370848A5A476E0998137B4302C5D0815D1E0\n          3A3C9AC0D0B06D5740A810CEDC83FA58C3A872C977D0EB22837E18B16ACAF329\n          6B8F0232557A66A61400169C8D1C437AC07C09408BF4806FDE9506E0E99D9B8A\n          4DC7BBE05487DD9D1277A4842DC618557476C19595EFAB19AAC4A6B64AA123A3\n          0206861293F7738E318633EEDB0BB1A2624B8E826DB074253AEF3E80B91E354D\n          5FDDF803A5471E10784FAC74E1F5E413D750E4737209405F16008A82F4E60819\n          034E775A0AF2898C573E005287AA9413869749C125F47C2EB85603F7D9894A11\n          8747A4C54BAB57AF39F30F867CCDDD0390DA21A55088BC216DF999E759567A9C\n          6DF154F1E9EB54E931E164A4AA606299A2A0ABCD0A80DF4C03A037473800087F\n          62F0650C4B79B743C55592E982CB17652E7E5C1F94417554E8FCDDA5838E86B8\n          CBF1319D24E9628642813304F5FFA57CEF4629BA89F93D1D0FFC58528A2FEB19\n          A1F0B935D02701F8200B80C7D5E688864E38DD95780082B4D3538FAB0BC26A97\n          6423181B4CFA78EDFA989E4760DC2B383B805A6504D73DE7FBAC26A4A0F16827\n          7C6F081A10C5FB401CBD97C6117CC8806D6E48478E829806A00D3EF8FBDF8801\n          78BB6EDB8E8DC513D203CE5EB20090CCC737C27DA0A281D7D2B85FC723FF8DCA\n          54666038915C9F780B4B2995281DC1737D169BF94414E529ABBCE56351C6FD78\n          C7B57AC2EFE355CB594A471EA0C0108FA1C0B0393570B5E95C36005F91009C94\n          00B45EB2595090F9388578EBC5F5F92E5010EBBD36380683C3495AD1C4B26320\n          7C800DCF395A0BB220EEDB17A1F29DA2984E8999A3CE98D6A86E18F128AAB71B\n          C58432DE104844475C02704501F0EAEA34008FEC509B233AF5F6205707D0CCC7\n          59A7C3C47FBE1D8404A924E9A6EF5A49B70A629AA074A007C31D85510578EBD6\n          5739472BE419208E1B9CB92F1A694A9A05BC53B44B77D1E2036B0F535A37D672\n          0ACFCA8294075C2E07C0C34FDD5F3CA33CA047902CC80C4A3D3CB61C38E08E15\n          BD89C2763715DD0C0C26F621387A10AD6059A0386F3A2E0883FE4C0E411D81D9\n          11C9D799A78614A7A3B752CBF77DF4C09B52E929FDCCB4F2BDC1A567CDE83C9B\n          FF1551D0EC6AE86D2C03C0430A00E901E77AC1FCB124D2F3711404A4DD4C5B0E\n          57A4D5974ABE6DE02D91BC17C0A7988C8211A6783E3B22C038160B2C399D0561\n          E196493BA425117B41AA728E0335F592280047055750B845C225003D8D3208FF\n          DDAA0000B66CFBDB2F6FD9B1F1CF5A8F7589B69EC4EA290C5C8673216819ABF6\n          41DFF512B60E3CE5D88171FA404E814409E41C1ED3BF1141BD80280A15693DC3\n          6741F1E746B443A9251A8B319674A0A5B182B24CDC778AA9284541D262D9EC2A\n          D6D3700E0EBEBA2A9892648B37BCF6C8E7EF5BFB1F33972E295CBC3CEAFA9429\n          22237F1D40AF5CE897C156F780822C23724B4C2B43B70D021DFE2F6B85F357A5\n          527986122920A44F4FF37CB4DC34EDF0AAA9C06B2B032BA5CDB954B68403231E\n          00D171A41F967A41CD9FC170FF10F47CF8E17BF56F6CFAAA523EB84979F95379\n          C783FB77D62C5AB6BF30BDAA96616B80051F2FC837A84A56E09785C1C9BD265D\n          F5189DF4E74B9D57ADFE8CE83BD4C15881D9C04B3C2A553358C5A9B1BA40CC9D\n          F243E529100B0B6B61B0A3538851F71431674769641C5059965623FA81EC5B94\n          24B2201AEA6E3BD0FAF36FFC75DFB9FF392D4F5D06BB2C85F18ACA8AA4343455\n          BE563F55F677E6E77D52F299C7DE7C71C1234FBCD077E422F00A1E29DE2A3A08\n          CE165EFCC34ED423D2E963C502D5086B8343FBEF5A65BF7204CC7AB19B252E30\n          A8EF557FB37400DCC22CABEC8255FC54FBFAA602B0FCE91FBF34E7818D2FF61F\n          ED0456E0A1A563EDE0159D5276EA1E119C379D48DD0A56000C81599773B3D786\n          8E590046EC6B11728C11FB07236F2E002B77FFF4E559EBD6FEA906A0A2607379\n          37B113F2BD57366D7BFB8C2AAEBAF5DCACF280660DC067C158E0442CCED553D8\n          E4F8E62A791CE1AB9E7DB7EE962FDD53ECAFEFD2EB92C27AC1D5130C8189F3FE\n          4CCA2273BB6A36AAAF39980C993CCBD32781F095BBDFAD9BB57E4DF19AF6009E\n          997E0282C1D0473909C8B488E36401960EC2F36B2D0077E50064085F293D60D6\n          3A09407D1C0300698556C540BC218BA662F0540CB8DA9403504EF8CA3D8A82D6\n          1407EA6D0C204156DF402C9A93022F53E9B4CAB614A466A3AE2A0FF8660E4096\n          F0551680EB3206B08AB80E081B7BCC36864C0E4D6A90282BE2C483F8BC1AE301\n          3900992201F8990EC2030D5D7A8D9F563A516E9C6A066D6C17780B1C6B2A6C71\n          D8CF28CC33AD60321D9803404403304B02705D01608330AD846907352BF03AC0\n          C2C20DB091A7A603F564480E40A6200003C7BA4C3B965048565B22557C953DCF\n          F43248A626C41B5B7300CA08023028011059851827FDA028F341CE0FCEBBDE90\n          C01870A531980ECC0120A20198BD4E0220292889EB0016CE0D640767C804C379\n          8F9A10CF01282F7CD55E0980F6804B200A2C9DD1706C92A782331E737F9DAE86\n          D0E7E6CE9000B4E6009411F4802109405261127D8E8A05927A523A722D0788E2\n          433A2D5513E2977300CA8A06608E05602C4541C4BA8965D39683B987643EC40B\n          74E12C29E8F2F11C8072C2575B0F183E7E094AA4158120901413832D673EE046\n          DEC083CCC82C09E9CD01282B1280031280BB43005C47131B701E009A7A62B54B\n          9B740898BD36B75A0210AC48C8012082008C2800D42E4167E9A4F8CA6C374485\n          186DD261E1A6E2460EC0B8A20198E33CA0A210F572209803707F575ABF91877D\n          A1206B024A41D5D093035056108091C66E187593F2658A2FCE19C4D52E8B73FF\n          206DB56B727200CA8A0660AEF2000B80EFED40300993CE8EDC8C18F186A82DA1\n          B1C80118571000E50123156E81AD2FC8E2EA17F70D972BBEC8D21AB53B476541\n          DDC75A7300CA8806609EF2802609806D2B079C1ED704484D8C1467F41EF219E0\n          00501EB02A0720433400F3D71B0A1A2EF0A0FFE394AE8F303D85749794C40C4A\n          473A835214744C2F0BCC01C8100DC00209C0500C008B2826A3E00AD695A66286\n          054065410D3900E584AF92002CDA2001901434C4A807D0869B9D922C57F10694\n          E5E287C801F808C257ED3D50B758794073370C02F7696546038E171C32E0AB62\n          20F5415009E7007C14E1AB2D0083390013221A805B25050D347D8C00D8E58A39\n          001F611C2B9F7DF7AF96DC7FCF9F0F9CBA22064605730AF76D689F0971521FA4\n          0A2E7ACD774B059F5BCD2E1D3DABEA00B7394201509AF0079FE80158E1773EFA\n          2F9B177CE19EFFAABC7561C5D0F592EE396003144860D5770359F1403AA378CE\n          CF1D68CCE47F43D786A0F7F0A103F5DFDBFC0760D6E6AB05BA3773716EA64C16\n          00D438A67DEE897FDD5DB5E073AFF1E9D3A79BF49368157FF9269BDF432BA2F3\n          8055B012912430D4DDFEDED9037FF98DFEB6F771730494DBCC75931F7C3208E3\n          53AA2A92D1814F6A93885B1AAE381F3747400E406A2C9FD42691CCCD1113FDC0\n          EEA12793B8F1F0E8F8D715A7EC243A9E70F93FC75BE04FE910CD930000000049\n          454E44AE426082}\n        OnClick = NewProfileImageClick\n      end\n      object NewProfileLabel: TLabel\n        Left = 167\n        Top = 37\n        Width = 219\n        Height = 25\n        Cursor = crHandPoint\n        Caption = '< Create New Profile >'\n        Font.Charset = DEFAULT_CHARSET\n        Font.Color = clWindowText\n        Font.Height = -21\n        Font.Name = 'Tahoma'\n        Font.Style = []\n        ParentFont = False\n        OnClick = NewProfileLabelClick\n      end\n    end\n  end\n  object GameIcons: TImageList\n    Height = 96\n    Width = 96\n    Left = 24\n    Top = 416\n    Bitmap = {\n      494C0101060008004C0060006000FFFFFFFFFF10FFFFFFFFFFFFFFFF424D3600\n      000000000000360000002800000080010000C000000001002000000000000080\n      0400000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      00000000000000000000F3FAF81AD5F6F851B9F3F783A4F0F7A993EFF6C983ED\n      F6E479EBF6F774EEFAFB74EEFBFB74EEFBFB74EEFBFB96D8CBFBFF943BFBFD9A\n      45F4FCA052E3FCAC66C9FDB87EA9FDC89A84FDDBBE55FEF2E71E000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000F9F9F9066362\n      62A8131111FF131111FE262321F9858169FA0E0D0FFA171515FA1B1919F61D1B\n      1BF48D8C8C7B0000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000F3FAF91BC6F4\n      F66D9DEFF6B777EBF5FA71EEFBFF72EEFCFF72EEFBFF72EEFBFF72EEFBFF72EE\n      FBFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF6FF0FFFFBCBF96FFFF95\n      3BFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFC953EFDFCB0\n      6EBEFDCEA575FEEFE32400000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000DBDADA271614\n      14FC141112FF141112FF181612FF8F8058FF0B0A09FF141113FF141212FF1411\n      12FF2E2C2CE2F2F1F10E00000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000F2FBFB19BAF3F68385EDF5E272EEFBFF72EE\n      FCFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF72EE\n      FBFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF6EF1FFFFE3A6\n      60FFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD96\n      3EFFFD963EFFFD963EFFFC9E4DEBFDC3928EFEEDDF2900000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      00000000000000000000000000000000000000000000000000006F6E6E9C1512\n      13FF151213FF141112FF312B1CFF776337FF332D1CFF121012FF151213FF1512\n      13FF151213FFA2A1A16500000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      000000000000FDDDC150FCAC68C7DFA967FF6DF1FFFF72EEFBFF72EEFBFF72EE\n      FBFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF72EE\n      FBFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF7AE9\n      F1FFFB9740FFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD96\n      3EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFCA356DDFDD3AF690000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      00000000000000000000000000000000000000000000EAEAEA16151213FF1512\n      13FF161214FF151213FF403522FF6C5629FF413419FF111012FF151213FF1512\n      13FF151213FF2E2C2CE300000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      000000000000000000000000000000000000000000000000000000000000FDD0\n      AA6FFC9B49F0FD963EFFFD963EFFFF9236FF7FE6E9FF72EEFBFF72EEFBFF72EE\n      FBFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF72EE\n      FBFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF72EE\n      FBFF98D6C8FFFF9338FFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD96\n      3EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD96\n      3EFFFDC5958BFEFBF80800000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      00000000000000000000000000000000000000000000656364A7151213FF1512\n      13FF161314FF151712FF5F4F2CFF74592FFF2E2001FF1A160CFF131313FF1313\n      13FF151213FF151213FFA5A4A561000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      00000000000000000000000000000000000000000000FDD2AD6BFC9944F7FD96\n      3EFFFD963EFFFD963EFFFD963EFFFE963DFFBAC199FF71EFFCFF72EEFBFF72EE\n      FBFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF72EE\n      FBFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF72EE\n      FBFF6FF0FFFFC2BC8EFFFE953CFFFD963EFFFD963EFFFD963EFFFD963EFFFD96\n      3EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD96\n      3EFFFD963EFFFD963EFFFDC5958BFEFDFD020000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      000000000000000000000000000000000000DDDDDD24262324EC151213FF1512\n      13FF131212FF332C18FF745E2CFF584115FF382903FF2B2613FF151514FF1414\n      14FF151213FF151213FF353233DCFDFDFD020000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000FDE2CB44FC9F4DE9FD963EFFFD963EFFFD96\n      3EFFFD963EFFFD963EFFFD963EFFFD963EFFF39C4BFF6DF1FFFF72EEFBFF72EE\n      FBFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF72EE\n      FBFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF72EE\n      FBFF72EEFBFF6EF0FFFFE8A35BFFFD963EFFFD963EFFFD963EFFFD963EFFFD96\n      3EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD96\n      3EFFFD963EFFFD963EFFFD963EFFFD9740FCFDD3AF6800000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      00000000000000000000000000000000000088868782161314FF161314FF1613\n      14FF131610FF6C5726FF644C1EFF422E05FF463409FF3A2A15FF1D1917FF1414\n      14FF161314FF161314FF1E1B1CF6B6B5B64F0000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      000000000000FEFAF60BFCB273B7FD963EFFFD963EFFFD963EFFFD963EFFFD96\n      3EFFFD963EFFFD963EFFFD963EFFFD963EFFFF9338FF94D9CEFF72EEFBFF72EE\n      FBFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF72EE\n      FBFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF72EE\n      FBFF72EEFBFF72EEFBFF7DE7ECFFFD963EFFFD963EFFFD963EFFFD963EFFFD96\n      3EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD96\n      3EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFDA459D9FEF0E4230000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000F1F1F10F383637D9161314FF161314FF1412\n      16FF382B0EFF463106FF412E09FF473209FF634D19FF4B3815FF564E40FF1110\n      11FF161314FF161314FF161314FF636162AAFAFAFA0500000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000FEDCC052FD963EFEFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD96\n      3EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFD0B37CFF6FF0FFFF72EE\n      FBFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF72EE\n      FBFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF72EE\n      FBFF72EEFBFF72EEFBFF72EEFCFF9DD3C1FFFF9338FFFD963EFFFD963EFFFD96\n      3EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD96\n      3EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFDCB\n      9F7D000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000B3B2B253161314FF161314FF161314FF1713\n      0FFF47320EFF382C07FF181411FF15120CFF292313FF41321EFF807155FF7B7A\n      7CFF0E0B0CFF161314FF161314FF161314FFE1E1E12000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      000000000000000000000000000000000000000000000000000000000000FDB9\n      80A6FD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD96\n      3EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFF943AFF74EDF9FF72EE\n      FBFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF72EE\n      FBFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF72EE\n      FBFF72EEFBFF72EEFBFF72EEFBFF6EF1FFFFC8B886FFFE953DFFFD963EFFFD96\n      3EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD96\n      3EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD96\n      3EFFFDA862CFFEF9F50C00000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      00000000000000000000000000002D2B2BE5161314FF161314FF131113FF3629\n      13FF3F2D0BFF171314FF131415FF141414FF141414FF0C0C0FFF938D8AFF615E\n      5FFF100D0EFF161314FF161314FF161314FF7876779300000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      00000000000000000000000000000000000000000000FEF7F013FDA255E0FD96\n      3EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD96\n      3EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFF953BFFA9CBB0FF72EE\n      FBFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF72EE\n      FBFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF72EE\n      FBFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF6FF0FFFFECA156FFFD963EFFFD96\n      3EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD96\n      3EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD96\n      3EFFFD963EFFFD9842F9FEEAD832000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      00000000000000000000ACABAC5A161314FF161314FF151213FF181412FF4230\n      13FF231F17FF18191AFF141414FF141414FF161314FF100E0EFF171515FF110D\n      0FFF171415FF161314FF161314FF161314FF161314FFECECEC14000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      000000000000000000000000000000000000FEEBDB2FFD9741FBFD963EFFFD96\n      3EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD96\n      3EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFE5A65FFF6DF1\n      FFFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF72EE\n      FBFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF72EE\n      FBFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF80E5E7FFFE953CFFFD96\n      3EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD96\n      3EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD96\n      3EFFFD963EFFFD963EFFFD963EFFFDD9B95B0000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      00000000000000000000393737D8161314FF161314FF141214FF2A210DFF513C\n      12FF2B2A26FF161515FF161314FF161314FF161314FF131111FF141112FF1512\n      13FF141212FF161414FF161314FF161314FF161314FF6A6969A2000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000FDE1C847FD963EFFFD963EFFFD963EFFFD96\n      3EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD96\n      3EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFF9236FF83E3\n      E3FF72EEFBFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF75F4FFFF78FAFFFF72EF\n      FCFF6EE6F2FF74F1FEFF78FAFFFF75F5FFFF72EFFCFF72EEFBFF72EEFBFF72EE\n      FBFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF71EEFCFFA3CFB9FFFF93\n      38FFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD96\n      3EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD96\n      3EFFFD963EFFFD963EFFFD963EFFFD963EFFFDCBA07C00000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      000000000000B3B2B2531C191AF8161314FF161314FF121111FF2C2312FF644C\n      14FF1F1A0EFF151616FF161415FF161314FF161314FF131011FF131211FF1512\n      13FF121010FF151213FF161414FF171415FF151213FF272426EEE5E4E41D0000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      00000000000000000000FEDCBF54FD963EFFFD963EFFFD963EFFFD963EFFFD96\n      3EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD96\n      3EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963DFFBFBE\n      93FF71EFFDFF72EEFBFF73F0FEFF6FE8F4FF41888FFF1E3E41FF060D0EFF0000\n      00FF000000FF000000FF081010FF1D3C3FFF3A787FFF5FC7D1FF77F9FFFF72EF\n      FCFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF6EF1FFFFCEB4\n      7FFFFE963DFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD96\n      3EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD96\n      3EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFDC4938D000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000F9F9F906636162AA151414FF151515FF171513FF151513FF181514FF5640\n      10FF543E0FFF23211DFF222120FF282524FF171614FF151311FF12110FFF1614\n      12FF151412FF12100FFF171614FF2B2B29FF232222FF28241FFE9D978F760000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      000000000000FEDCC052FD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD96\n      3EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD96\n      3EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFF79A\n      46FF6DF1FFFF75F4FFFF367278FF000000FF000000FF000000FF000000FF0000\n      00FF090A0CFF020303FF000000FF000000FF000000FF000000FF0C1A1BFF448D\n      95FF75F4FFFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF71EF\n      FDFFF09F51FFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD96\n      3EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD96\n      3EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFDC4948C0000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000E7E6E71A161314FE161415FF221C12FF221B0CFF131411FF141312FF251B\n      10FF5B410AFF6F5C3CFF6B6B6AFF484644FF1E1D1BFF13120FFF100F0DFF1413\n      11FF171615FF141311FF131110FF231D15FF2E2715FF322610FF45413FCFF2F2\n      F20E000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000FDE3CC42FD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD96\n      3EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD96\n      3EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFF93\n      39FF99D2C2FF13282AFF000000FF000000FF000000FF161A1DFF7D94A6FFBDDF\n      FBFFCAEDFFFFC3E5FFFFB5D5F0FF8DA7BCFF556572FF101315FF000000FF0000\n      00FF070E0FFF52AAB3FF75F5FFFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF72EE\n      FBFF84E3E2FFFF943AFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD96\n      3EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD96\n      3EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFDCB\n      A17B000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      00006C6B6BA1171515FF161515FF261D11FF29210AFF101310FF141412FF0F0F\n      10FF2D220CFF72571FFF989288FF1D1B18FF1E1D1CFF0E0F0DFF0E0C0AFF1312\n      10FF241B0FFF181814FF2D2212FF2E2311FF181510FF131213FF171515FFC2C2\n      C242000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      000000000000000000000000000000000000000000000000000000000000FEEE\n      E028FD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD96\n      3EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD96\n      3EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFF9B\n      40FF361E0AFF000000FF000000FF000000FF000000FF000000FF000000FF0000\n      00FF121718FF46545EFFA7C5DEFFB8D8F4FFB9D9F6FFC1E2FFFF8BA5B9FF242B\n      30FF000000FF000000FF2A575CFF75F3FFFF72EEFBFF72EEFBFF72EEFBFF72EE\n      FBFF71EFFCFFA9CCB1FFFF9439FFFD963EFFFD963EFFFD963EFFFD963EFFFD96\n      3EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD96\n      3EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD96\n      3EFFFDDABB590000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      000000000000000000000000000000000000000000000000000000000000E7E7\n      E71A171515FF171515FF171515FF1C170FFF2A210CFF0E0F0DFF11110FFF100F\n      0DFF101112FF48370DFF6A531FFF282722FF0D0D0DFF0A0B08FF090705FF0E0D\n      0BFF16120BFF211E10FF32240BFF171514FF141214FF121010FF171515FF3E3D\n      3CD4000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000FEF9F50CFD99\n      44F7FD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD96\n      3EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD96\n      3EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFE973EFF985A\n      25FF000000FF000000FF000000FF272C2DFF6E7B82FF96AEC2FFB1D1ECFFC0E2\n      FEFFC1E3FFFFBCDDF9FFB6D6F2FFB8D8F4FFB8D8F4FFB8D8F4FFB8D8F4FFC0E1\n      FEFF7E95A8FF030404FF000000FF183235FF74F1FEFF72EEFBFF72EEFBFF72EE\n      FBFF72EEFBFF6DF1FFFFD3B177FFFD963DFFFD963EFFFD963EFFFD963EFFFD96\n      3EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD96\n      3EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD96\n      3EFFFD963EFFFEEADA3000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000006766\n      66A6171515FF171515FF161414FF2A2111FF2A200BFF10110FFF10100DFF1513\n      11FF131013FF342711FF6F540DFF1C190BFF0B0B09FF10100EFF0F0E0CFF0E0C\n      0AFF0B0B0CFF241C11FF42320AFF1A1B15FF161513FF110F0DFF151412FF1816\n      15FFBBBBBB4A0000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000FDA65CD6FD96\n      3EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD96\n      3EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD96\n      3EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFF9C40FFB46B2CFF0D07\n      02FF030201FF646E74FFC4D8E7FFDFF4FFFFD7ECFEFFD7ECFDFFCFE7FBFFBCDB\n      F6FFB7D8F4FFB8D8F4FFB8D8F4FFB8D8F4FFB8D8F4FFB8D8F4FFB8D8F4FFB8D8\n      F4FFB8D8F4FFAFCEE8FF15191CFF000000FF1F4043FF76F6FFFF72EEFBFF72EE\n      FBFF72EEFBFF72EEFBFF72EEFBFFF39D4CFFFD963EFFFD963EFFFD963EFFFD96\n      3EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD96\n      3EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD96\n      3EFFFD963EFFFD9944F7FEFAF60B000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000DFDEDE232523\n      23EF171515FF181616FF131412FF604913FF2E2408FF151212FF121210FF1615\n      13FF242225FF3C2B0DFF735512FF16140DFF121310FF161614FF151412FF1110\n      0EFF151412FF151413FF403112FF212426FF191614FF13120FFF161513FF1816\n      15FF434141CE0000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      00000000000000000000000000000000000000000000FDC18F93FD963EFFFD96\n      3EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD96\n      3EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD96\n      3EFFFD963EFFFD963EFFFD963EFFFF9A40FFC2742FFF211308FF000000FF717B\n      81FFD9EEFEFFD8EDFFFFD6EBFDFFD6EBFDFFD6EBFDFFD6EBFDFFD6EBFDFFD7EC\n      FDFFCAE4FAFFB8D8F4FFB8D8F4FFB8D8F4FFB8D8F4FFB8D8F4FFB8D8F4FFB8D8\n      F4FFB8D8F4FFB8D8F4FFB5D5F0FF0E1113FF000000FF428991FF73EFFCFF72EE\n      FBFF72EEFBFF72EEFBFF72EEFBFF88E0DDFFFF9439FFFD963EFFFD963EFFFD96\n      3EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD96\n      3EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD96\n      3EFFFD963EFFFD963EFFFDAA64CC000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      00000000000000000000000000000000000000000000000000008E8D8D7C1816\n      16FE181616FF161517FF342B11FF725514FF3B2B0EFF140F10FF11100FFF1D1B\n      1AFF221E15FF664A11FF5D4B1BFF151613FF161715FF161715FF151311FF0D0B\n      09FF161412FF131313FF554319FF262421FF332714FF151514FF161715FF1617\n      15FF1E1D1EF6C2C2C24200000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      000000000000000000000000000000000000FEE5D03DFD963EFFFD963EFFFD96\n      3EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD96\n      3EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD96\n      3EFFFD963EFFFD963EFFFC963EFF543214FF000000FF43484BFFD0E4F4FFD7EC\n      FFFFD6EBFDFFD6EBFDFFD6EBFDFFD6EBFDFFD6EBFDFFD6EBFDFFD6EBFDFFD6EB\n      FDFFD6EBFDFFD3EAFDFFBCDBF5FFB8D8F4FFB8D8F4FFB8D8F4FFB8D8F4FFBBDC\n      F8FFBDDEFAFFC1E3FFFFBADAF7FF98B3CAFF000000FF000000FF70EBF7FF72EE\n      FBFF72EEFBFF72EEFBFF72EEFBFF70EFFDFFAFC8A9FFFF943AFFFD963EFFFD96\n      3EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD96\n      3EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD96\n      3EFFFD963EFFFD963EFFFD963EFFFDCCA2790000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      00000000000000000000000000000000000000000000F1F1F10F3E3C3CD51816\n      16FF181616FF161615FF52380CFF7E6624FF32230AFF120E0EFF0D0A0BFF1313\n      12FF3D2E09FF81661DFF3E351BFF151816FF161816FF171816FF0D0B09FF0C0B\n      09FF141311FF141415FF493814FF232018FF3B2A11FF141414FF161715FF1617\n      16FF161616FF73737399FBFBFB04000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      000000000000000000000000000000000000FD9A47F3FD963EFFFD963EFFFD96\n      3EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD96\n      3EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD96\n      3EFFFE973EFFDA8236FF110A04FF000000FF8D99A2FFDDF3FFFFD6EBFDFFD6EB\n      FDFFD6EBFDFFD6EBFDFFD6EBFDFFD6EBFDFFD6EBFDFFD6EBFDFFD6EBFDFFD6EB\n      FDFFD6EBFDFFD6EBFDFFD6EBFDFFBFDDF6FFB8D8F4FFB8D8F4FFB8D8F4FF96B2\n      C8FF000000FF0C0E10FF485661FFA4C2DAFF313941FF000000FF3E8188FF72EF\n      FCFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF6DF1FFFFD9AE70FFFD963EFFFD96\n      3EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD96\n      3EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD96\n      3EFFFD963EFFFD963EFFFD963EFFFD963EFFFEF1E62000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      00000000000000000000000000000000000000000000B9B8B84D181616FF1816\n      16FF181616FF2A2012FF5E410CFF826823FF150F06FF0C0A0BFF0E0C0DFF251E\n      0FFF71561CFF684F10FF181A15FF181B18FF181917FF171715FF0F0E0CFF0D0B\n      09FF12110EFF121415FF4D3E11FF1C1D18FF382C0CFF191616FF151715FF1617\n      16FF161616FF242424EFE6E6E61B000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000FDBE889CFD963EFFFD963EFFFD963EFFFD96\n      3EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD96\n      3EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFF97\n      3EFFC1722FFF000000FF050504FFB6C7D4FFD7ECFFFFD6EBFDFFD6EBFDFFD6EB\n      FDFFD6EBFDFFD6EBFDFFD6EBFDFFD6EBFDFFD6EBFDFFD6EBFDFFD6EBFDFFD6EB\n      FDFFD6EBFDFFD6EBFDFFD6EBFDFFD7ECFDFFC0DEF7FFB8D8F4FFB8D8F4FFB8D8\n      F4FFB8D8F4FF485560FF000000FF000000FF111416FF000000FF152B2EFF76F7\n      FFFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF74EDF8FFF69B48FFFD96\n      3EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD96\n      3EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD96\n      3EFFFD963EFFFD963EFFFD963EFFFD963EFFFCA65DD500000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000032302FE2181616FF1816\n      17FF181716FF38290EFF6D510AFF6C561DFF0C0B0EFF19171AFF151616FF2C1F\n      0AFF846B29FF634A0BFF2C2821FF2C2F2DFF1B1C1AFF161614FF0F0F0DFF0604\n      02FF100E0CFF111013FF654E15FF595242FF543F0DFF48330DFF1C1A16FF1717\n      16FF171616FF161616FF8C8C8C7D000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      00000000000000000000FEEDDF29FD963EFFFD963EFFFD963EFFFD963EFFFD96\n      3EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD96\n      3EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFE973EFFBD70\n      2FFF000000FF060605FFC2D4E1FFD6EBFDFFD6EBFDFFD6EBFDFFD6EBFDFFD6EB\n      FDFFD6EBFDFFD6EBFDFFD6EBFDFFD6EBFDFFD6EBFDFFD6EBFDFFD6EBFDFFD6EB\n      FDFFD6EBFDFFD6EBFDFFD6EBFDFFD6EBFDFFD7ECFDFFBDDCF6FFB8D8F4FFB8D8\n      F4FFB8D8F4FFBCDDFAFF8DA7BCFF050607FF000000FF000000FF000000FF76F6\n      FFFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF8CDDD7FFFF93\n      38FFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD96\n      3EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD96\n      3EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFDD6B462000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      000000000000000000000000000000000000AAAAA95C1D1A16FF181616FF1918\n      16FF171715FF3A2C10FF6F4F0DFF594312FF121418FF1A171AFF181618FF251B\n      10FF806B1AFFA78D2AFF765F1AFF1C1D18FF171514FF161311FF131210FF0E0D\n      0BFF0D0C0AFF100F12FF634910FF755B14FF76570EFF70550DFF362C11FF1717\n      16FF191816FF171716FF161616FF000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      00000000000000000000FDA862CFFD963EFFFD963EFFFD963EFFFD963EFFFD96\n      3EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD96\n      3EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFD37D34FF0000\n      00FF000000FFBACBD8FFD6EBFDFFD6EBFDFFD6EBFDFFD6EBFDFFD6EBFDFFD6EB\n      FDFFD6EBFDFFD6EBFDFFD6EBFDFFD6EBFDFFD6EBFDFFD6EBFDFFD6EBFDFFD6EB\n      FDFFD6EBFDFFD6EBFDFFD6EBFDFFD6EBFDFFD6EBFDFFD5EBFDFFB8D8F4FFB8D8\n      F4FFB8D8F4FFB8D8F4FFB8D8F4FFB0D0EAFF1A2023FF000000FF000000FF62CD\n      D8FF72EEFBFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF70EFFEFFB4C4\n      A1FFFF943AFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD96\n      3EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD96\n      3EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD9842F9000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      000000000000000000000000000000000000363635DB282015FF171516FF1717\n      16FF2E2612FF543E10FF72540EFF594313FF121417FF1A1819FF191717FF1515\n      19FF563E11FFB2952DFFB29224FF453A12FF171716FF161513FF171614FF1313\n      11FF11110FFF0F0F10FF3C2808FF70540AFF84651CFF73530BFF4D3C11FF1817\n      12FF191816FF171816FF161716FF838383870000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      000000000000FDE0C749FD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD96\n      3EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD96\n      3EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFF5913CFF090502FF0000\n      00FF99A6B0FFD7ECFEFFD6EBFDFFD6EBFDFFD6EBFDFFD6EBFDFFD6EBFDFFD6EB\n      FDFFD6EBFDFFD6EBFDFFD6EBFDFFD6EBFDFFD6EBFDFFD6EBFDFFD6EBFDFFD6EB\n      FDFFD6EBFDFFD6EBFDFFD6EBFDFFD6EBFDFFD6EBFDFFD6EBFDFFCDE6FBFFB7D7\n      F4FFB8D8F4FFB8D8F4FFB8D8F4FFB8D8F4FFBBDCF8FF2B3339FF000000FF0103\n      03FF60C8D3FF72EFFCFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF6DF1\n      FFFFDEAA69FFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD96\n      3EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD96\n      3EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFDC799850000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000B7B7B74E201F23F8342810FF151616FF231D\n      12FF5B3F09FF957826FF7E6210FF664D14FF171715FF1A1917FF1A1717FF1614\n      15FF353227FF7E5F12FFAA8C21FF83701FFF14151AFF1C1C1BFF121311FF1819\n      17FF141513FF0D0F11FF44300AFF6B4D08FF8D6F24FF6C4D0BFF5F4710FF1818\n      12FF151613FF1A1A17FF151817FF2B2D2CE7F0F0F01000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      000000000000FCA256DEFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD96\n      3EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD96\n      3EFFFD963EFFFD963EFFFD963EFFFD963EFFFF9B40FF3D240FFF000000FF565D\n      61FFDBF1FFFFD6EBFDFFD6EBFDFFD6EBFDFFD6EBFDFFD6EBFDFFD7ECFEFFD1E4\n      F5FF8A969FFF828E97FFB4C5D2FFD7EDFFFFD6EBFDFFD6EBFDFFD6EBFDFFD6EB\n      FDFFD6EBFDFFD6EBFDFFD6EBFDFFD6EBFDFFD6EBFDFFD6EBFDFFD7ECFDFFBFDE\n      F6FFB8D8F4FFB8D8F4FFB8D8F4FFB8D8F4FFB8D8F4FFBDDEFBFF2E373DFF0000\n      00FF000000FF5DC2CDFF72EFFCFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF72EE\n      FBFF77EBF5FFF89944FFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD96\n      3EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD96\n      3EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFEFC\n      FB05000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      00000000000000000000F8F8F807626262AA2B2D30FF3B2B0DFF171715FF342A\n      09FF6C4F10FF9E811EFF977C17FF977F26FF231A10FF181817FF181819FF1312\n      13FF2E2B2CFF433614FFA2831BFFA18219FF757360FF414341FF393A37FF1011\n      0FFF171715FF121315FF5E440DFF70540DFF8E6F1DFF745610FF64470BFF2F23\n      13FF171411FF241D14FF161817FF191919FCA3A3A36500000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000FDE0C748FD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD96\n      3EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD96\n      3EFFFD963EFFFD963EFFFD963EFFFE963EFFA46128FF000000FF0E0E0EFFD9EE\n      FFFFD6EBFDFFD6EBFDFFD6EBFDFFD6EBFDFFD6EBFDFFD9EEFFFF7E8991FF0000\n      00FF000000FF000000FF000000FFCEE2F0FFD6EBFDFFD6EBFDFFD6EBFDFFD6EB\n      FDFFD6EBFDFFD6EBFDFFD6EBFDFFD6EBFDFFD6EBFDFFD6EBFDFFD6EBFDFFD2E9\n      FCFFB7D7F4FFB8D8F4FFB8D8F4FFB8D8F4FFB8D8F4FFB8D8F4FFBCDDFAFF232A\n      2FFF000000FF000000FF5FC7D2FF72EEFBFF72EEFBFF72EEFBFF72EEFBFF72EE\n      FBFF72EEFBFF91DAD1FFFF9338FFFD963EFFFD963EFFFD963EFFFD963EFFFD96\n      3EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD96\n      3EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFDC8\n      9A84000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      00000000000000000000E1E1E0212A2C2CF927221EFF352912FF111314FF4D33\n      0BFF745410FF9D7F1EFFAD921DFFA08736FF2A200BFF141213FF161518FF1514\n      17FF171316FF343531FF806A26FF9F8518FFC8B675FFBFC1BEFF585A58FF0F10\n      0EFF1A1C19FF1C1A1AFF6D4E10FF71520EFFA48A23FF7C5B12FF694C0CFF4232\n      09FF2B2826FF221B12FF171717FF181717FF504E4EC2F4F4F40C000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000FDA963CDFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD96\n      3EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD96\n      3EFFFD963EFFFD963EFFFD963EFFFF973EFF070402FF000000FF97A5AFFFD6EB\n      FDFFD6EBFDFFD6EBFDFFD6EBFDFFD6EBFDFFD6EBFDFFD7EBFDFF9EACB7FF9FAD\n      B9FF95A3AEFF838F98FF8B97A1FFDAF0FFFFD6EBFDFFD6EBFDFFD6EBFDFFD6EB\n      FDFFD6EBFDFFD6EBFDFFD6EBFDFFD6EBFDFFD6EBFDFFD6EBFDFFD6EBFDFFD7EB\n      FDFFC0DEF7FFB8D8F4FFB8D8F4FFB8D8F4FFB8D8F4FFB8D8F4FFB8D8F4FFB7D7\n      F3FF101416FF000001FF020303FF68DAE5FF72EEFBFF72EEFBFF72EEFBFF72EE\n      FBFF72EEFBFF6FF0FEFFBAC199FFFF953BFFFD963EFFFD963EFFFD963EFFFD96\n      3EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD96\n      3EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD97\n      41FB000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000077757498302719FF322711FF141113FF211C10FF5137\n      05FF8F7226FF9C7D17FFB1931EFFB09936FF4B360FFF1E1A12FF141317FF1918\n      1BFF141114FF1F1C20FF413919FFAC9421FFA08523FFD8D1A5FF3B3D3AFF1414\n      13FF151415FF29271DFF876214FF7E5F10FFB9A231FF8C6E19FF74560EFF5D43\n      0BFF3F2C06FF1F1D16FF171717FF181717FF191717FFCCCCCC38000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      000000000000000000000000000000000000000000000000000000000000FEEE\n      E127FD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD96\n      3EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD96\n      3EFFFD963EFFFD963EFFFE973EFF824D20FF000000FF252728FFDFF5FFFFD6EB\n      FDFFD6EBFDFFD6EBFDFFD6EBFDFFD6EBFDFFD6EBFDFFD6EBFDFFDCF2FFFFD7EB\n      FBFFA4B3BFFF87939CFF8A97A0FFABBBC7FFDAEFFFFFDCF1FFFFD6EBFDFFD6EB\n      FDFFD6EBFDFFD6EBFDFFD6EBFDFFD6EBFDFFD6EBFDFFD6EBFDFFD6EBFDFFD6EB\n      FDFFCEE7FBFFB7D7F4FFB8D8F4FFB8D8F4FFB8D8F4FFB8D8F4FFB8D8F4FFB8D8\n      F4FFA5C2DCFF000000FF000000FF0C191BFF75F5FFFF76F7FFFF74F1FFFF72EE\n      FBFF72EEFBFF72EEFBFF6EF1FFFFE2A863FFFD963EFFFD963EFFFD963EFFFD96\n      3EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD96\n      3EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD96\n      3EFFFDD6B4620000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      000000000000E9EAEA17191717FF2D2211FF39332DFF161316FF2A1F0DFF5F42\n      0AFF9D7F20FFA0841AFFA78B1CFFA38D34FF211E19FF1E1A1BFF141416FF1B1A\n      1DFF151115FF181518FF111112FF8A7721FFAB9326FFB29637FF534622FF0E0E\n      10FF131111FF141415FF614711FF80600CFF967923FF9C831BFF7E5D14FF7B59\n      0FFF593F08FF1C1A14FF171717FF181717FF191717FF595858B7000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      000000000000000000000000000000000000000000000000000000000000FDBE\n      899BFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD96\n      3EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD96\n      3EFFFD963EFFFD963EFFFF993FFF050301FF000000FF9BA9B4FFD6EBFDFFD6EB\n      FDFFD6EBFDFFD6EBFDFFD6EBFDFFD6EBFDFFDFF5FFFF9CAAB4FF393D3FFF0000\n      00FF000000FF000000FF000000FF000000FF000000FF3B3F41FF91A0ABFFDDF3\n      FFFFD7ECFEFFD6EBFDFFD6EBFDFFD6EBFDFFD6EBFDFFD6EBFDFFDCF1FFFFD6EB\n      FDFFD8ECFEFFB9D9F5FFB8D8F4FFB8D8F4FFB8D8F4FFB8D8F4FFB8D8F4FFB8D8\n      F4FFB9D9F5FF798FA1FF000000FF000000FF0D1B1DFF13282BFF2B595EFF5FC7\n      D1FF75F3FFFF72EEFBFF72EEFBFF79EAF2FFFA9842FFFD963EFFFD963EFFFD96\n      3EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD96\n      3EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD96\n      3EFFFDA65DD60000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000007272729A181717FF261E13FF2C261DFF171716FF3F3111FF9479\n      1BFF9F8319FF876814FF9B811DFF7B611EFF222020FF1D1A1DFF181719FF1717\n      17FF181617FF131012FF131315FF3D361FFFC2A62EFFBBA13EFF967921FF0809\n      0DFF141212FF1A1819FF2D291AFF5D4814FF71530FFFA2842BFF876815FF7D62\n      14FF785B12FF231D13FF181818FF181818FF191717FF191717FFD7D6D62C0000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      000000000000000000000000000000000000000000000000000000000000FD96\n      3EFEFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD96\n      3EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD96\n      3EFFFD963EFFFD963EFFA16028FF000000FF121313FFE0F5FFFFD6EBFDFFDAEF\n      FFFFD6EBFDFFD6EBFDFFDCF2FFFFA5B4BEFF1D1F1FFF000000FF1D1D1CFF5958\n      57FF7A7A79FF8C8B8BFF8E8D8DFF81807EFF5F5E5DFF1C1B1AFF000000FF0708\n      08FF717C84FFD7EDFDFFD7ECFEFFD6EBFDFFD6EBFDFFCCE1F1FF616C73FFD7ED\n      FFFFD6EBFDFFC5E1F8FFB8D8F4FFB8D8F4FFB8D8F4FFB8D8F4FFB8D8F4FFB8D8\n      F4FFB8D8F4FFBEE0FDFF44515BFF2B3339FF1C2326FF000000FF000000FF0000\n      00FF2F6268FF75F5FFFF72EEFBFF72EEFBFF96D7CAFFFF9337FFFD963EFFFD96\n      3EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD96\n      3EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD96\n      3EFFFD963EFFFEF1E52100000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000E4E4E41D232323F1171717FF201D13FF5D4610FF131414FF68561FFFAB8E\n      20FFA28721FF715009FF846513FF382B10FF110E10FF161315FF191819FF1818\n      18FF191718FF0F0C0DFF110F0FFF0F0D0EFFB99C36FFB49B2FFF7D6417FF0809\n      0DFF151314FF161414FF141213FF0F1217FF382E14FF927323FF907321FF8D6E\n      19FFB09628FF544014FF191818FF181717FF191717FF191717FF595757B80000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000FDDFC44CFD96\n      3EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD96\n      3EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD96\n      3EFFFD963EFFFF9B40FF36200DFF000000FF6F7980FFD7ECFEFFD7EDFFFF6F79\n      7FFFDAF0FFFFD5EAFAFF454B4EFF000000FF5E5D5CFFD5D4D3FFFFFFFFFFFFFF\n      FFFFFEFEFEFFFDFDFDFFFDFDFDFFFEFEFEFFFFFFFFFFFFFFFFFFD8D8D7FF6B6C\n      6CFF010202FF000000FF76838BFFDCF2FFFFD6EBFDFFD4E9FAFF131616FFDFF5\n      FFFFD6EBFDFFCEE7FBFFB7D7F4FFB8D8F4FFB8D8F4FFB8D8F4FFB8D8F4FFB8D8\n      F4FFB8D8F4FFB8D8F4FFBCDDFAFFBDDEFBFFC0E1FEFFB3D3EEFF53626EFF0000\n      00FF000000FF254C50FF76F6FFFF72EEFBFF6FF0FFFFC0BD91FFFF953CFFFD96\n      3EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD96\n      3EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD96\n      3EFFFD963EFFFDC7998600000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      00008D8D8D7D181818FF181818FF141616FF56400FFF6A5215FF8E731EFF9C7F\n      18FFA28824FF76540DFF5F4812FF08050AFF131013FF120F12FF151415FF1818\n      18FF1A1818FF131111FF110D0DFF060A0CFF88701DFFB19329FF514015FF1313\n      15FF161414FF141112FF181516FF1A1918FF191615FF33290DFF947423FFB293\n      30FFA98E1BFF8E7424FF1F1A14FF181818FF1A1818FF1A1818FF262424F0D6D6\n      D62D000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000FDB87DAAFD96\n      3EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD96\n      3EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD96\n      3EFFFD963EFFF3903CFF000000FF000000FFC1D3E2FFD6EBFDFFD1E5F4FF0000\n      00FF666F74FF1A1A1AFF848381FFF7F7F6FFFFFFFFFFFDFDFDFFFDFDFDFFFDFD\n      FDFFFEFEFEFFFEFEFEFFFDFDFDFFFDFDFDFFFDFDFDFFFDFDFDFFFDFDFDFFFFFF\n      FFFFFFFFFFFFA1A3A3FF252626FF070A0BFF9FAFBBFFABBCC9FF000000FFCBDF\n      EFFFD6EBFDFFD6EBFDFFB7D7F4FFB8D8F4FFB8D8F4FFB8D8F4FFB8D8F4FFB8D8\n      F4FFB8D8F4FFB8D8F4FFB8D8F4FFB8D8F4FFB8D8F4FFB8D8F4FFBBDCF8FF839B\n      AFFF000000FF000000FF459098FF72EFFCFF72EEFBFF6EF1FFFFE7A55DFFFD96\n      3EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD96\n      3EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD96\n      3EFFFD963EFFFDA052E400000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      000000000000000000000000000000000000000000000000000000000000F0F0\n      F010434343CE181818FF181818FF121718FF4E3811FF856612FFA88F27FFB39A\n      27FF947716FF624912FF131214FF100D0FFF090608FF120F12FF171617FF1717\n      17FF1B1919FF161314FF121011FF272221FFB9A237FFA58B26FF413622FF1817\n      19FF1A1818FF191717FF161314FF161314FF151214FF191815FF655419FFB99C\n      2FFFB79C29FFAE8F2CFF3F3115FF171718FF1A1818FF1A1818FF191717FF7E7C\n      7C8F000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000FC9741FBFD96\n      3EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD96\n      3EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD96\n      3EFFFD963EFFA56228FF000000FF191A1AFFE0F6FFFFD9EFFFFF575E63FF0000\n      00FF959493FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEEEDFFC1C0BFFF9D9C\n      9AFF838281FF807E7DFF939191FFB5B3B3FFE3E2E1FFFFFFFFFFFFFFFFFFFEFE\n      FEFFFDFDFDFFFDFDFDFFFFFFFFFFCCCDCEFF2E2E2EFF000000FF000000FF8796\n      A0FFD6EBFDFFD7ECFDFFBCDBF6FFB8D8F4FFB8D8F4FFB8D8F4FFB8D8F4FFB8D8\n      F4FFB8D8F4FFB8D8F4FFB8D8F4FFB8D8F4FFB8D8F4FFB8D8F4FFB8D8F4FFBBDC\n      F8FF546370FF000000FF020505FF74F2FFFF72EEFBFF72EEFBFF7CE8EEFFFD96\n      3FFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD96\n      3EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD96\n      3EFFFD963EFFFD963EFFFEF3EA1B000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      000000000000000000000000000000000000000000000000000000000000B8B8\n      B84D171717FF181818FF181818FF181817FF594110FFAD9021FFA4891DFFB69B\n      2EFF967D1AFF261E17FF18171AFF171317FF110E11FF100D10FF1A191AFF191A\n      19FF1A1818FF211F1FFF1F1E21FF8D8665FFAF992CFF997E22FF1A1911FF1313\n      14FF292626FF292727FF181616FF151213FF161414FF191717FF2F2A17FFAC91\n      22FFBCA133FFC2A633FF63561CFF151616FF1A1918FF1A1818FF1A1818FF3230\n      31E3EDEDED130000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      00000000000000000000000000000000000000000000FEEAD931FD963EFFFD96\n      3EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD96\n      3EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD96\n      3EFFFF983FFF5F3817FF000000FF596166FFD8EDFFFFC8DBE9FF000000FF0000\n      00FFFEFDFCFFD0CFCEFF838281FF3A3836FF151414FF303437FF5C656AFF7C88\n      90FF8D9BA4FF838F96FF656E74FF393E41FF040505FF000000FF393736FF8281\n      81FFCECECFFFFFFFFFFFFFFFFFFFFEFEFEFFDCDDDEFF000000FF000000FF4A52\n      58FFDAEFFFFFD6EBFDFFC3E0F8FFB8D8F4FFB8D8F4FFB8D8F4FFB8D8F4FFB8D8\n      F4FFB8D8F4FFB8D8F4FFB8D8F4FFB8D8F4FFB8D8F4FFB8D8F4FFB8D8F4FFB8D8\n      F4FFB4D4EFFF000000FF000000FF4DA1AAFF72EEFBFF72EEFBFF72EEFCFF9BD4\n      C3FFFF9338FFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD96\n      3EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD96\n      3EFFFD963EFFFD963EFFFDD2AC6C000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000002F2F\n      2FE4171717FF181818FF171617FF302616FF896E16FFB79C28FFA78B18FFB398\n      2CFF826B1EFF18171FFF1C181BFF1A171AFF141114FF120E11FF191919FF1818\n      18FF2C2B2BFF4A4848FF979A9FFF9C863BFFBDA434FF7E681DFF12100EFF1111\n      11FF1A1819FF1B1819FF161414FF151313FF1A1718FF1C1919FF0E1013FF8E78\n      22FFB89F29FFBDA431FFBCA539FF13100FFF1A1917FF1A1818FF1A1818FF1917\n      18FFA6A5A6620000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      00000000000000000000000000000000000000000000FDCBA17BFE963DFFFF92\n      36FFFF9337FFFF9337FFFF9337FFFF9337FFFF9337FFFF9337FFFF9337FFFF93\n      37FFFF9337FFFF9337FFFF9337FFFF9337FFFF9337FFFF9337FFFF9337FFFF93\n      37FFFF9839FF241509FF000000FF8F9CA6FFD6EBFDFFC9DCEAFF000000FF0101\n      01FF000000FF40474BFF8A979FFFC7D9E7FFE1F7FFFFDBF1FFFFD7ECFFFFD6EB\n      FDFFD6EBFDFFD6EBFDFFD7ECFEFFDBF0FFFFE1F7FFFFCCDFEEFF95A3ACFF5960\n      66FF101314FF000000FF535454FF737474FF0E0F0FFF010101FF000000FF9BAC\n      B7FFD6EBFDFFD6EBFDFFC8E3F9FFB8D8F4FFB8D8F4FFB8D8F4FFB8D8F4FFB8D8\n      F4FFB8D8F4FFB8D8F4FFB8D8F4FFB8D8F4FFB8D8F4FFB8D8F4FFB8D8F4FFB8D8\n      F4FFC0E1FEFF1D2226FF000000FF31676CFF73F0FDFF72EEFBFF72EEFBFF6FF0\n      FFFFC6B989FFFE953CFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD96\n      3EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD96\n      3EFFFD963EFFFD963EFFFCB375B5000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000B4B4B4521818\n      18FF181818FF181818FF151515FF4C390EFFBA9F32FFB09422FFB29925FFBA9F\n      2EFF6A581AFF2F2E33FF1B181AFF1A171AFF1A1619FF151115FF181719FF1616\n      16FF373534FF4B4A48FFD6D6CDFFBDA947FFBBA031FF7A6723FF141514FF1414\n      14FF131111FF191717FF2A2828FF171415FF1A1818FF1B1819FF0C0C10FF937E\n      23FFBAA02BFFB89C2BFFC1A32FFF50481DFF1A1718FF191819FF1A181AFF1A17\n      1AFF262326F00000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      00000000000000000000000000000000000000000000FDB06EBEF89A46FF8BDF\n      DAFF88E1DFFF88E1DFFF88E1DFFF88E1DFFF88E1DFFF88E1DFFF88E1DFFF88E1\n      DFFF88E1DFFF88E1DFFF88E1DFFF88E1DFFF88E1DFFF88E1DFFF88E1DFFF88E1\n      DFFF8DE8E6FF000000FF000000FFBCCFDEFFD6EBFDFFD7ECFEFF9FAFBBFF0000\n      00FF9BABB5FFDAEFFFFFD6EBFDFFD6EBFDFFD6EBFDFFD6EBFDFFD6EBFDFFD6EB\n      FDFFD6EBFDFFD6EBFDFFD6EBFDFFD6EBFDFFD6EBFDFFD6EBFDFFD6EBFDFFD8ED\n      FFFFE0F6FFFFC9DEEDFF6A757CFF000000FF000000FF040505FFAEC0CCFFD8ED\n      FFFFD6EBFDFFD6EBFDFFCDE6FAFFB7D8F4FFB8D8F4FFB8D8F4FFB8D8F4FFB8D8\n      F4FFB8D8F4FFB8D8F4FFB8D8F4FFB8D8F4FFB8D8F4FFB8D8F4FFB8D8F4FFB8D8\n      F4FFBEE0FDFF262D32FF000000FF2A585CFF74F1FFFF72EEFBFF72EEFBFF72EE\n      FBFF6FF0FFFFEBA258FFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD96\n      3EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD96\n      3EFFFD963EFFFD963EFFFC9843F6000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      00000000000000000000000000000000000000000000000000003E3E3ED41818\n      18FF181818FF181818FF131314FF594B15FFB59C28FFC0A53EFFAF9627FFBAA0\n      2BFF574912FF211F23FF1A171AFF1A171AFF1B171AFF171216FF0E0D0EFF1212\n      12FF31302EFF7C7A78FFDED19BFFB69B30FFC7B044FF675D2DFF161616FF1717\n      17FF100E0EFF363435FF201E1EFF121010FF141212FF131212FF171410FFA793\n      25FFBB9E2CFFB99F2EFFBCA02CFFB19829FF554B1DFF1A171AFF1A171AFF1A17\n      1AFF19171AFF9F9FA06900000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      00000000000000000000000000000000000000000000FC9844F7FD963EFFE4A6\n      60FF6FF0FFFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF72EE\n      FBFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF72EE\n      FBFF6ADCE8FF000000FF000000FFDBF1FFFFD6EBFDFFD6EBFDFFD8EDFFFF909F\n      A8FF97A7B3FFD6EBFDFFD6EBFDFFD6EBFDFFD6EBFDFFD6EBFDFFD6EBFDFFD6EB\n      FDFFD6EBFDFFD6EBFDFFD6EBFDFFD6EBFDFFD6EBFDFFD6EBFDFFD6EBFDFFD6EB\n      FDFFD6EBFDFFD6EBFDFFD7EDFDFF000000FF181B1CFFC8DCEBFFD6EBFDFFD6EB\n      FDFFD6EBFDFFD6EBFDFFD1E8FCFFB7D7F4FFB8D8F4FFB8D8F4FFB8D8F4FFB8D8\n      F4FFB8D8F4FFB8D8F4FFB8D8F4FFB8D8F4FFB8D8F4FFB8D8F4FFB8D8F4FFB8D8\n      F4FFC0E1FEFF030405FF000000FF39787EFF72EFFCFF72EEFBFF72EEFBFF72EE\n      FBFF72EEFBFF7FE6E9FFFE953DFFFD963EFFFD963EFFFD963EFFFD963EFFFD96\n      3EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD96\n      3EFFFD963EFFFD963EFFFD963EFFFEF5EE150000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      00000000000000000000000000000000000000000000B8B8B84D1E1E1EF71818\n      18FF181818FF181818FF171718FF584A18FFC2A746FFD5BD6BFFBFA448FFC2A6\n      37FF64530FFF141218FF1A171AFF1A171AFF1A171AFF1F1B1DFF090709FF1314\n      13FF141414FF6E6A69FF867127FFC5AF52FFB8AA50FF544E39FF171616FF1916\n      17FF1C1A1AFF444343FF5B5959FF353233FF1B1919FF1A1819FF2B2715FFB4A2\n      49FFB4982CFFBFA133FFB49826FFC0A32FFF9E841FFF241F19FF1A171AFF1918\n      1AFF18181AFF363538DDFEFEFE01000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      000000000000000000000000000000000000FEF7F111FD963EFFFD963EFFFE95\n      3DFFD0B37CFF6EF1FFFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF72EE\n      FBFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF72EE\n      FBFF5DC2CDFF000000FF0D0F10FFE2F7FFFFD6EBFDFFD6EBFDFFD6EBFDFFD7EC\n      FFFFDAEFFFFFD6EBFDFFD6EBFDFFD6EBFDFFD6EBFDFFD6EBFDFFD6EBFDFFD7EC\n      FEFFE0F6FFFFDCF2FFFFD6EBFDFFD6EBFDFFD6EBFDFFD6EBFDFFD6EBFDFFD6EB\n      FDFFD6EBFDFFD6EBFDFF8B9AA4FF33383BFFD7EDFEFFD6EBFDFFD6EBFDFFD6EB\n      FDFFD6EBFDFFD6EBFDFFD4EAFDFFB7D7F4FFB8D8F4FFB8D8F4FFB8D8F4FFB8D8\n      F4FFB8D8F4FFB8D8F4FFB8D8F4FFB8D8F4FFB8D8F4FFB8D8F4FFB8D8F4FFB8D8\n      F5FF778D9FFF000000FF000000FF63CED9FF72EEFBFF72EEFBFF72EEFBFF72EE\n      FBFF72EEFBFF71EEFCFFA1D1BCFFFF9338FFFD963EFFFD963EFFFD963EFFFD96\n      3EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD96\n      3EFFFD963EFFFD963EFFFD963EFFFDDFC54B0000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      000000000000000000000000000000000000FAFAFA05696969A4171717FF1818\n      18FF181818FF181818FF161617FF635724FFC7BB64FFD4C277FFC7BA6AFFC5B7\n      66FFB7A866FF181518FF19161AFF1A171AFF1C191DFF282528FF1E1D1DFF1313\n      13FF181818FF323331FF958953FFE1D69AFFD3C181FF38352AFF191717FF1917\n      17FF252323FF6A6767FFC0BEB7FFA29F9FFF4F4D4CFF181717FF3E3B25FFB8A4\n      51FFE1D59AFFC3B057FFBEAD54FFC8B350FFC1A632FF483E1AFF151719FF1918\n      1AFF18181AFF1D1C1FF9AEAEAF58000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      000000000000000000000000000000000000FDE4CE40FD963EFFFD963EFFFD96\n      3EFFFF943AFFB8C29DFF6FF0FFFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF72EE\n      FBFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF72EE\n      FBFF55B1BAFF000000FF232729FFDEF4FFFFD6EBFDFFD6EBFDFFD6EBFDFFD6EB\n      FDFFD6EBFDFFD6EBFDFFD6EBFDFFD6EBFDFFD6EBFDFFD6EBFDFFD6EBFDFFA1B2\n      BEFF161919FF2F3537FFD6ECFDFFD6EBFDFFD6EBFDFFD6EBFDFFD6EBFDFFD6EB\n      FDFFD6EBFDFFD6EBFDFFC0D3E3FFDCF1FFFFD6EBFDFFD6EBFDFFD6EBFDFFD6EB\n      FDFFD6EBFDFFD6EBFDFFD6EBFDFFB6D7F4FFB8D8F4FFB8D8F4FFB8D8F4FFB8D8\n      F4FFB8D8F4FFB8D8F4FFB8D8F4FFBBDCF9FFBADBF7FFB8D8F4FFB8D8F4FF9DB8\n      D0FF000000FF000000FF47959DFF74F3FFFF72EEFBFF72EEFBFF72EEFBFF72EE\n      FBFF72EEFBFF72EEFBFF6EF0FFFFCCB682FFFE953DFFFD963EFFFD963EFFFD96\n      3EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD96\n      3EFFFD963EFFFD963EFFFD963EFFFDCCA27A0000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      000000000000000000000000000000000000E0E0E0221C1C1CF9181818FF1818\n      18FF161616FF090B0DFF1E1E1BFFB2AA79FFE9DDAFFFE5DCACFFE4DFB8FFF1EE\n      D3FFE7DFC2FF4B4947FF191617FF171516FF3D3B3BFF777677FF2E2E2CFF1013\n      10FF282A26FF1C1F20FFCCCAB8FFFAF8F1FFD4CA9FFF33312AFF282526FF1816\n      16FF282526FF343334FFFFFFE2FFFDFBEAFFAAAB9EFF0B090BFF313028FF9B94\n      70FFF1EDD6FFEAE5C5FFEBE1C3FFDFD699FFDCC87EFF908945FF101115FF1719\n      19FF161918FF171718FF606060AEF8F8F8070000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      000000000000000000000000000000000000FDD2AE6AFD963EFFFD963EFFFD96\n      3EFFFD963EFFFF9338FF9FD2BEFF71EFFCFF72EEFBFF72EEFBFF72EEFBFF72EE\n      FBFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF72EE\n      FBFF51AAB3FF000000FF2F3537FFDDF2FFFFD6EBFDFFD6EBFDFFD6EBFDFFD6EB\n      FDFFD6EBFDFFD6EBFDFFD6EBFDFFD6EBFDFFD6EBFDFFD6EBFDFFDAEFFFFF090A\n      0BFF000000FF292E30FFDCF2FFFFD6EBFDFFD6EBFDFFD6EBFDFFD6EBFDFFD6EB\n      FDFFD6EBFDFFD6EBFDFFD6EBFDFFD6EBFDFFD6EBFDFFD6EBFDFFD6EBFDFFD6EB\n      FDFFD6EBFDFFD6EBFDFFD8ECFEFFB7D8F4FFB8D8F4FFB8D8F4FFB8D8F4FFB8D8\n      F4FFB8D8F4FFB8D8F4FFB9D9F5FF677B8AFF778C9EFFB8D8F4FFBADAF6FF88A1\n      B5FF99B5CCFF000000FF29555AFF75F4FFFF72EEFBFF72EEFBFF72EEFBFF72EE\n      FBFF72EEFBFF72EEFBFF72EEFBFF70EFFDFFEFA052FFFD963EFFFD963EFFFD96\n      3EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD96\n      3EFFFD963EFFFD963EFFFD963EFFFDBC85A00000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      00000000000000000000000000000000000078787894171717FF181818FF1717\n      18FF312D26FF9F9875FFCAC39AFFEAE0BDFFE1DDB3FFDDD19BFFE5E0B5FFF8F3\n      E0FFE9E8D1FF77736AFF141214FF323130FF1D1A1EFF8A8162FF0C0D0BFF1418\n      15FF18161CFF92855AFFE0D2A0FFE8E4B3FFDDD4A8FF4F4E4AFF262323FF1513\n      13FF151313FF0E090AFF757263FF999480FFEEECCDFF3B3935FF1C191CFFB3B4\n      A4FFEEEDD1FFEBE9C8FFDBCC91FFE3DCB8FF7C8375FF606D5AFF0E1311FF1619\n      18FF161918FF171818FF171717FFE2E2E21F0000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      000000000000000000000000000000000000FDC4958CFD963EFFFD963EFFFD96\n      3EFFFD963EFFFD963EFFFF943AFF8BDFD9FF72EEFBFF72EEFBFF72EEFBFF72EE\n      FBFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF72EE\n      FBFF52ABB4FF000000FF33393BFFDCF2FFFFD6EBFDFFD6EBFDFFD6EBFDFFD6EB\n      FDFFD6EBFDFFD6EBFDFFD6EBFDFFD6EBFDFFD6EBFDFFD8EDFFFF67737AFF0000\n      00FF000000FFC0D4E2FFD6EBFDFFD6EBFDFFD6EBFDFFD6EBFDFFD6EBFDFFD6EB\n      FDFFD6EBFDFFD6EBFDFFD6EBFDFFD6EBFDFFD6EBFDFFD6EBFDFFD6EBFDFFD6EB\n      FDFFD6EBFDFFD6EBFDFFD7ECFDFFB8D8F5FFB8D8F4FFB8D8F4FFB8D8F4FFB8D8\n      F4FFB8D8F4FFB8D8F4FFB4D4EEFF040506FF859DB1FFBBDBF8FFB5D5F1FFB9D9\n      F5FF677A89FF000000FF000000FF5DC2CDFF72EEFBFF72EEFBFF72EEFBFF72EE\n      FBFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF83E4E4FFFF943BFFFD963EFFFD96\n      3EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD96\n      3EFFFD963EFFFD963EFFFD963EFFFCAF6CC00000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000F0F0F010171717FF171717FF181818FF1718\n      18FF292D20FF5F6541FFD0BE72FFD4C06FFFC8B353FFD7C876FFCFC170FFD5C9\n      76FFE9DEB3FFABA074FF555048FF3D3C35FF3A382EFF887331FF0D110FFF0F14\n      15FF655721FFA88E3CFFD3C576FFDAC96CFFCCBF65FF9B9358FF17140FFF1515\n      13FF141310FF2B2929FF141315FF0C0D0EFFB0AA8AFFAAA47CFF1A1816FFD1C6\n      9CFFD7CA88FFD2C071FFC7BB58FFBBAF6DFF707E72FF757E70FF0D1110FF171A\n      19FF161918FF171818FF181717FF6B6A6AA30000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      000000000000000000000000000000000000FDB980A6FD963EFFFD963EFFFD96\n      3EFFFD963EFFFD963EFFFD963EFFFA9842FF7CE8EDFF72EEFBFF72EEFBFF72EE\n      FBFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF72EE\n      FBFF57B4BEFF000000FF313639FFDCF2FFFFD6EBFDFFD6EBFDFFD6EBFDFFD6EB\n      FDFFD6EBFDFFD6EBFDFFD6EBFDFFD6EBFDFFD6EBFDFFC7DBEBFF000000FF0000\n      00FF667278FFD8EDFFFFD6EBFDFFD6EBFDFFD6EBFDFFD6EBFDFFD6EBFDFFD6EB\n      FDFFD6EBFDFFD6EBFDFFD6EBFDFFD6EBFDFFD6EBFDFFD6EBFDFFD6EBFDFFD6EB\n      FDFFD6EBFDFFD6EBFDFFD8ECFDFFB8D9F5FFB8D8F4FFB8D8F4FFB8D8F4FFB8D8\n      F4FFB8D8F4FFBFE0FDFF181D20FF44515BFFBFE1FEFF637584FF7F96A8FFB4D4\n      EEFF0C0F11FF4E5D68FF000000FF1B383BFF76F6FFFF72EEFBFF72EEFBFF72EE\n      FBFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF71EFFCFFA6CDB4FFFF9439FFFD96\n      3EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD96\n      3EFFFD963EFFFD963EFFFD963EFFFDA559D90000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      00000000000000000000000000006F6F6F9E171717FF181818FF181818FF181A\n      18FF344337FF324736FF686B3FFFAC9E4FFFCFBD5FFFCEBD59FFD2C062FFD0BD\n      64FFD5C063FFD4C060FFB4A054FF947F37FF8B731FFF9E8937FF131714FF181D\n      20FF665D29FFAC9035FFC8B258FFD4BD60FFC7B856FFC6B557FF3F391FFF1518\n      17FF1F1D1AFF151415FF171619FF1D1D24FF130F0CFF937C2AFF6D643FFFC7B2\n      4AFFCBB455FFD5BF60FFB2A155FF6A7048FF576657FF282C29FF161918FF1619\n      18FF161A18FF171817FF181717FF191717FFE7E7E71A00000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      000000000000000000000000000000000000FCB171BAFD963EFFFD963EFFFD96\n      3EFFFD963EFFFD963EFFFD963EFFFD963EFFEF9F51FF73EEFAFF72EEFBFF72EE\n      FBFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF72EE\n      FBFF60C9D4FF000000FF262B2CFFDEF3FFFFD6EBFDFFD6EBFDFFD6EBFDFFD6EB\n      FDFFD6EBFDFFD6EBFDFFD6EBFDFFD6EBFDFFD6EBFDFF909EA9FF000000FF0000\n      00FF8D9BA4FFD6EBFDFFD6EBFDFFD6EBFDFFD6EBFDFFD6EBFDFFD6EBFDFFD6EB\n      FDFFD6EBFDFFD6EBFDFFD6EBFDFFD6EBFDFFD6EBFDFFD6EBFDFFD6EBFDFFD6EB\n      FDFFD6EBFDFFD6EBFDFFD8ECFDFFB9D8F5FFB8D8F4FFB8D8F4FFB8D8F4FFB8D8\n      F4FFB8D8F4FFB8D8F4FFADCBE5FFBDDEFAFF9DBAD1FF090B0DFFC2E5FFFF424F\n      58FF6D8090FF161A1EFF000000FF000000FF62CBD6FF72EEFBFF72EEFBFF72EE\n      FBFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF6EF1FFFFD1B279FFFE96\n      3DFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD96\n      3EFFFD963EFFFD963EFFFD963EFFFD9D4CEC0000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      00000000000000000000E2E2E21F2A2A2AEA171717FF181718FF181818FF292D\n      29FF849184FF809081FF40523FFF404A37FF5E6C4FFF74703EFF98822CFFBFA9\n      45FFC7B34DFFCEB955FFC8B34EFFBAA640FFC0AB45FFCBB854FF9F8E4FFF3836\n      25FFB8A548FFC3AB48FFCAB74FFFCAB751FFBEAB46FFCCB756FFBEAA4BFF3D36\n      22FF24252BFF2D2C1DFFAD9E4EFF857A3EFFA39642FFC6AE49FFBEA847FFC9B2\n      52FFB9A545FF79763FFF36432CFF4C5B4AFF2F3831FF151917FF161A17FF161A\n      17FF161A17FF181A17FF181816FF191717FF676666A800000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      000000000000000000000000000000000000FCAB65CAFD963EFFFD963EFFFD96\n      3EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFDFAA68FF6EF0FFFF72EE\n      FBFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF72EE\n      FBFF6DE4F0FF000000FF121415FFE1F7FFFFD6EBFDFFD6EBFDFFD6EBFDFFD6EB\n      FDFFD6EBFDFFD6EBFDFFD6EBFDFFD6EBFDFFD6EBFDFFDAF0FFFF32383BFF0000\n      00FF141718FFDBF1FFFFD6EBFDFFD6EBFDFFD6EBFDFFD6EBFDFFD6EBFDFFD6EB\n      FDFFD6EBFDFFD6EBFDFFD6EBFDFFD6EBFDFFD6EBFDFFD6EBFDFFD6EBFDFFD6EB\n      FDFFD6EBFDFFD6EBFDFFD7ECFEFFB8D8F4FFB8D8F4FFB8D8F4FFB8D8F4FFB8D8\n      F4FFB8D8F4FFB8D8F4FFBBDBF8FF95B0C6FF000000FF8EA7BDFF96B0C7FF0000\n      00FF90AABFFF21292CFF000000FF000000FF2B595EFF74F2FFFF72EEFBFF72EE\n      FBFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF72EEFCFFF29D\n      4EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD96\n      3EFFFD963EFFFD963EFFFD963EFFFD9742F80000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      000000000000000000008F8F8F7A171717FF171717FF171717FF161716FF4B50\n      4DFFA3B0A4FF5D6D5FFF6C7C6EFFA8B8AAFFA5B5A7FF90A195FF676129FF957C\n      23FFC3AF49FFC5B24BFFCCB755FFC9B550FFBEAB42FFC3B048FFD0BA5EFFCFBE\n      5DFFBDA844FFCCB653FFBBA441FFC7AF4AFFC0AA46FFC6B24CFFCEBB64FFC1AF\n      49FF81733AFFC7B44BFFC3AC45FFBFA940FFC9B34EFFCCB451FFC6B04BFFBBA6\n      41FF918439FF303D2FFF414F41FF606E60FF565F56FF1A1E1BFF1A201BFF1A20\n      1BFF171A17FF181917FF181916FF191717FF272525EFE0E0E022000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      000000000000000000000000000000000000FDA75FD3FD963EFFFD963EFFFD96\n      3EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFF953CFFC9B786FF6EF1\n      FFFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF72EE\n      FBFF77F8FFFF010202FF000000FFDEF4FFFFD6EBFDFFD6EBFDFFD6EBFDFFD6EB\n      FDFFD6EBFDFFD6EBFDFFD6EBFDFFD6EBFDFFD6EBFDFFD6EBFDFFD9EFFFFF2328\n      2AFF000000FF69747BFFD8EEFFFFD6EBFDFFD6EBFDFFD6EBFDFFD6EBFDFFD6EB\n      FDFFD6EBFDFFD6EBFDFFD6EBFDFFD6EBFDFFDBF0FFFFDCF1FFFFD6EBFDFFD6EB\n      FDFFD6EBFDFFD6EBFDFFD6EBFDFFB7D7F3FFB8D8F4FFB8D8F4FFB8D8F4FFB8D8\n      F4FFB8D8F4FFBADAF6FF6C8091FF000000FF74899AFFBEE0FCFF0C0E10FF7A90\n      A2FF252D31FF738899FF000201FF000000FF000000FF73F0FDFF72EEFBFF72EE\n      FBFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF86E1\n      DFFFFF9439FFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD96\n      3EFFFD963EFFFD963EFFFD963EFFFD9741FB0000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      000000000000F3F3F30D3E3E3ED3171717FF171717FF161716FF1C1F1DFF171F\n      1BFF19231AFF0D1A0FFF4E5A4FFF303C32FF889489FF92A093FF374422FF655D\n      21FFC6AF4AFFC0AF4AFFBEAC48FFCDBC56FFC3B34BFFC3B14EFFC4B34EFFD6C5\n      6FFFC2B04FFFC9B552FFBCA744FFC5B14AFFC6B24DFFC5B14CFFD2BD64FFCAB3\n      4FFFCEB94EFFB9A440FFBBA440FFCCB853FFC9B354FFBFA842FFBCA13CFFBAA3\n      42FF645D28FF334237FF94A192FF9DAA9DFF637063FF5E6B5EFF7F8A7DFF878D\n      87FF222321FF1B1A18FF1A1816FF191717FF191717FE9090907A000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      000000000000000000000000000000000000FCA65AD8FD963EFFFD963EFFFD96\n      3EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFF9439FFB1C7\n      A6FF70F0FEFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF72EE\n      FBFF76F6FFFF162E31FF000000FFC3D7E6FFD6EBFDFFD6EBFDFFD6EBFDFFD6EB\n      FDFFD6EBFDFFD6EBFDFFD8EDFFFFD6EBFDFFD6EBFDFFD6EBFDFFD6EBFDFFD3E8\n      FAFF131617FF000000FFC1D5E3FFD6EBFDFFD6EBFDFFD6EBFDFFD6EBFDFFD6EB\n      FDFFD6EBFDFFD6EBFDFFD6EBFDFFDDF2FFFF464D51FF393F42FFD9EEFFFFD6EB\n      FDFFD6EBFDFFD6EBFDFFD4EAFCFFB7D7F4FFB8D8F4FFB8D8F4FFB8D8F4FFB8D8\n      F4FFB8D8F4FFB9DAF6FF7C93A5FF9BB6CDFFC1E2FFFF3C4750FF262D33FF98B4\n      CAFF353F47FF657786FF2B6E71FF000000FF000000FF499AA2FF72EEFBFF72EE\n      FBFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF71EF\n      FDFFACCAACFFFF943AFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD96\n      3EFFFD963EFFFD963EFFFD963EFFFD9741FB0000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      000000000000BBBBBB4A161616FF171717FF171717FF151515FF373D37FF545F\n      56FF323D33FF233124FF38453BFF657368FF27362AFF38493BFF6A806FFF6176\n      66FF5A6231FFBEAA48FFC7BA5AFFBEAD48FFD0BF62FFC7B855FFBFAF48FFCABB\n      5BFFCABB5CFFBEAB48FFBDAC4AFFC0AE52FFC6B553FFB4A141FFB7A043FFB097\n      3DFFCAB557FFC4AE4CFFCEB652FFC3B147FFCCB94DFFA9953EFF5C5A36FF404D\n      38FF42513FFF596858FF82917FFF515E51FF394639FF4E5B4FFF96A193FF98A0\n      96FF2D302CFF1A1816FF1A1917FF191717FF191717FF413F3FD2F1F1F10F0000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      000000000000000000000000000000000000FDA55BD7FD963EFFFD963EFFFD96\n      3EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFF93\n      38FF99D6C6FF71EEFCFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF72EE\n      FBFF73F0FDFF32676DFF000000FF96A6B1FFD6EBFDFFD6EBFDFFD6EBFDFFD6EB\n      FDFFD6EBFDFFCFE3F4FF5B656BFFBED1E0FFD6EBFDFFD6EBFDFFD6EBFDFFD6EB\n      FDFFC6DAE9FF020303FF303639FFDEF4FFFFD6EBFDFFD6EBFDFFD6EBFDFFD6EB\n      FDFFD6EBFDFFD6EBFDFFD6EBFDFFADBECAFF000000FF000000FF748088FFD7EC\n      FEFFD6EBFDFFD6EBFDFFD1E8FCFFB7D7F4FFB8D8F4FFB8D8F4FFB8D8F4FFB8D8\n      F4FFB8D8F4FFB8D8F4FFB8D8F4FFBFE0FDFF4F5E6AFF060607FFB7D8F4FF0F12\n      15FFA9C7E0FF2A2F35FF42ABAFFF1E4D4FFF000000FF1E3D41FF75F5FFFF72EE\n      FBFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF72EE\n      FBFF6DF1FFFFD6AF73FFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD96\n      3EFFFD963EFFFD963EFFFD963EFFFD9741FB0000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      000000000000373737DA161616FF171717FF161616FF151515FF242922FF828F\n      84FF849085FF677669FF819187FF34443BFF3B4E43FF3F5546FF263B2CFF7D92\n      82FF485B4CFF656326FF9C8E40FFC4B765FFC2B454FFC8BA5FFFCDBE64FFBBAE\n      4AFFC6B758FFBEAE4AFFB7A845FFCABC5DFF8D7E31FF414B33FF2C3E32FF2935\n      2EFF83763CFFC1B34BFFD1C36CFFC3AD48FF988332FF3B3922FF556A5CFF6F80\n      70FF475645FF677565FF4E5C4CFF515F51FF334033FF243025FF8B9A88FF98A4\n      98FF353B34FF202420FF181715FF191717FF191717FF181616FFBEBEBE470000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      000000000000000000000000000000000000FDA860D1FD963EFFFD963EFFFD96\n      3EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD96\n      3EFFFF953CFF86E1E0FF72EEFBFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF72EE\n      FBFF72EEFBFF52AAB3FF000000FF616B72FFD8EDFFFFD6EBFDFFD6EBFDFFD6EB\n      FDFFD9EEFFFF555E63FF000000FF101314FFDEF3FFFFD6EBFDFFD6EBFDFFD6EB\n      FDFFD6EBFDFF9EAFBAFF000000FF9FAFBBFFD6EBFDFFD6EBFDFFD6EBFDFFD6EB\n      FDFFD6EBFDFFD6EBFDFFD6EBFDFF87959EFF000000FF000000FF2D3134FFDDF3\n      FFFFD6EBFDFFD6EBFDFFCDE5FAFFB7D8F4FFB8D8F4FFB8D8F4FFB8D8F4FFB8D8\n      F4FFB8D8F4FFB8D8F4FFB4D3EFFF2D363CFF050607FFACCAE4FF52616DFF4856\n      60FFB1D0EAFF000302FF54DBE0FF3D9DA1FF000000FF000000FF72EEFAFF72EE\n      FBFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF72EE\n      FBFF72EEFBFF74EDF9FFF59B4AFFFD963EFFFD963EFFFD963EFFFD963EFFFD96\n      3EFFFD963EFFFD963EFFFD963EFFFD9841FA0000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000B5B5B550161616FF161616FF171717FF151515FF1A1D1BFF39443AFF5663\n      58FF758278FF829288FF6F7F76FF90A59BFF98AFA5FFA5BBB1FF7F9289FF2237\n      2BFF556A5EFF758880FF6A7D79FF616C4CFFB1A85BFFC6BD5BFFCEC06BFFC7BC\n      5DFFBCB14DFFC4B955FFB0A43FFFC7BC5DFFB7AC58FF849272FF5C7A6BFF7F8A\n      5EFFD4C672FFC1B567FF8A7F3FFF5B5424FF455141FF3B493CFF4C5C4CFF8595\n      84FF444F44FF313B2CFF394738FF637164FF636F62FF576457FF617161FFBDC8\n      BFFF545D55FF7A827AFF1B1D1CFF181717FF181717FF181616FF383636DB0000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      000000000000000000000000000000000000FCAC68C6FD963EFFFD963EFFFD96\n      3EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD96\n      3EFFFD963EFFF79A46FF79E9F1FF72EEFBFF72EEFBFF72EEFBFF72EEFBFF72EE\n      FBFF72EEFBFF72EFFBFF000000FF212627FFDFF5FFFFD6EBFDFFD6EBFDFFD6EB\n      FDFFDFF4FFFF202526FF000000FF000000FFA7B8C5FFD6EBFDFFD6EBFDFFD6EB\n      FDFFD6EBFDFFDCF2FFFF474F53FF222729FFDFF5FFFFD6EBFDFFD6EBFDFFD6EB\n      FDFFD6EBFDFFD6EBFDFFD6EBFDFF95A3AEFF000000FF000000FF171919FFE0F6\n      FFFFD6EBFDFFD6EBFDFFC9E2F9FFB8D8F4FFB8D8F4FFB8D8F4FFB8D8F4FFB8D8\n      F4FFB8D8F4FFB8D8F4FF697C8CFF2A3238FFB1D1ECFF7B92A4FF040506FFBDDE\n      FAFF45515BFF2C7174FF51D3D8FF54D9DEFF000000FF000000FF50A8B1FF72EE\n      FBFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF72EE\n      FBFF72EEFBFF72EEFBFF8BDED9FFFF9438FFFD963EFFFD963EFFFD963EFFFD96\n      3EFFFD963EFFFD963EFFFD963EFFFD9A44F50000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      00003E3E3ED3161616FF171717FF171717FF141515FF191F1BFF6D7B71FF6B7C\n      71FF707F75FF364D3FFF395143FF5E776BFF9FB8ACFF3C5647FF546A64FF677C\n      7AFF5E726EFFC7D9D4FFD0DED9FF9FB2A8FF8C8942FFC6BE62FFCCC471FFC0B6\n      5BFFC2BA58FFBDB751FFB2A943FFCDC676FFC2B358FFC6B85CFF949A74FFC7BB\n      5BFFC9BE5BFF706D39FF38493FFF4E6257FF3D5144FF485A4CFF6E7E70FF5361\n      55FF656D4FFF626841FF49502FFF98A597FFBBC6BCFF8D9A8DFF879788FFAAB6\n      ABFF919E93FF5F6D63FF151816FF171717FF171717FF181717FF181616FFB6B5\n      B550000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      000000000000000000000000000000000000FCB375B5FD963EFFFD963EFFFD96\n      3EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD96\n      3EFFFD963EFFFD963EFFEBA258FF71EFFCFF72EEFBFF72EEFBFF72EEFBFF72EE\n      FBFF72EEFBFF75F4FFFF1F4245FF000000FFC9DEEDFFD6EBFDFFD6EBFDFFD6EB\n      FDFFDEF4FFFF222729FF000000FF000000FF83919AFFD6EBFDFFD6EBFDFFD6EB\n      FDFFD6EBFDFFD6EBFDFFCEE3F3FF000000FFA8BAC6FFD6EBFDFFD6EBFDFFD6EB\n      FDFFD6EBFDFFD6EBFDFFD6EBFDFFCEE3F3FF000000FF000000FF2F3437FFDDF2\n      FFFFD6EBFDFFD6EBFDFFC4E0F8FFB8D8F4FFB8D8F4FFB8D8F4FFB8D8F4FFB8D8\n      F4FFB8D8F4FFB8D8F4FFBCDCF9FFBEDFFCFF90AAC0FF000000FF9BB7CEFF91AC\n      C2FF000706FF53D6DBFF51D2D7FF53D7DCFF173C3DFF000000FF31686EFF73F0\n      FDFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF72EE\n      FBFF72EEFBFF72EEFBFF70EFFDFFB2C6A4FFFF943AFFFD963EFFFD963EFFFD96\n      3EFFFD963EFFFD963EFFFD963EFFFD9F4FE80000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      000000000000000000000000000000000000000000000000000000000000B7B7\n      B74E1D1D1DF7161616FF161616FF171917FF1D211FFF87928DFFC3D1CBFF9DAF\n      A6FF364C3EFF5C8E77FF538E7AFF3B8063FF31664EFF335540FF5E7870FFB1CA\n      C5FFA6BEBCFF59746EFF708A82FFC5D4D1FF838850FFBFBA5BFFCBC672FFBEB9\n      58FFC0BC58FFC1BC5AFFB1AD47FFCEC87AFFC2B856FFC7BD5FFFC7BD58FFBCB3\n      51FFCABA5FFF757442FF586F64FF93A797FF798E77FF93A895FFC5D4C9FF97A2\n      8FFF43483CFF142220FF212C26FF484C2FFF1C2418FF213129FF54655BFF2E3E\n      33FF2A3C31FF1C2A26FF191C1BFF171717FF171717FF181617FF181616FF3E3D\n      3DD4000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      000000000000000000000000000000000000FDBC85A0FD963EFFFD963EFFFD96\n      3EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD96\n      3EFFFD963EFFFD963EFFFE963DFFD9AD70FF6EF1FFFF72EEFBFF72EEFBFF72EE\n      FBFF72EEFBFF72EEFBFF4FA4ADFF000000FF79858DFFD6EBFEFFD6EBFDFFD6EB\n      FDFFD9EEFFFF505A5EFF000000FF000000FF8D9DA7FFD6EBFDFFD6EBFDFFD6EB\n      FDFFD6EBFDFFD6EBFDFFD7ECFFFF6E7A81FF3F464AFFDBF0FFFFD6EBFDFFD6EB\n      FDFFD6EBFDFFD6EBFDFFD6EBFDFFD9EEFFFF6E7980FF000000FF97A6B1FFD6EB\n      FDFFD6EBFDFFD7ECFDFFC0DDF6FFB8D8F4FFB8D8F4FFB8D8F4FFB8D8F4FFB8D8\n      F4FFB8D8F4FFB8D8F4FFB9DAF6FF90AAC0FF000000FF7E95A8FFACCBE4FF0200\n      00FF42ACB0FF51D2D7FF51D2D7FF51D2D7FF2D7577FF000000FF193336FF76F6\n      FFFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF72EE\n      FBFF72EEFBFF72EEFBFF72EEFBFF6DF1FFFFDCAB6BFFFD963EFFFD963EFFFD96\n      3EFFFD963EFFFD963EFFFD963EFFFCA75ED30000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000F9F9F9066969\n      69A4161616FF161616FF161616FF181E18FF334036FF728278FF455A4EFF334B\n      3FFF284130FF617A77FF4490A8FF2AB1DEFF2FA0C2FF497164FF679C96FF5EB7\n      C1FF8FB0AAFFA5BDB7FF94B1A8FF638177FF497359FF848D42FFC8C267FFC8C0\n      6EFFC1BE5DFFC4C15FFFBAB651FFCCC76FFFCBC168FFC2BC5FFFBAB451FFC1B8\n      5DFFC6BF65FF4A532CFF6F8C7AFF506440FF5A6841FF73825CFF819170FF7781\n      5DFF444C47FF1B2D3DFF3B4C4CFF32412EFF3A4B44FF263530FF16251EFF2432\n      29FF2C3C32FF38443CFF2A352EFF151916FF181718FF181616FF181616FF1F1D\n      1DF7BFBFBF460000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      000000000000000000000000000000000000FDC89B83FD963EFFFD963EFFFD96\n      3EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD96\n      3EFFFD963EFFFD963EFFFD963EFFFF953BFFC2BC8FFF6EF0FFFF72EEFBFF72EE\n      FBFF72EEFBFF72EEFBFF76F5FFFF040909FF1B1F21FFE0F6FFFFD6EBFDFFD6EB\n      FDFFD6EBFDFFBACDDBFF000000FF000000FFCFE3F4FFD6EBFDFFD6EBFDFFD6EB\n      FDFFD6EBFDFFD6EBFDFFD6EBFDFFD9EEFFFF85949DFFD9EFFFFFD6EBFDFFD6EB\n      FDFFD6EBFDFFD6EBFDFFD6EBFDFFD6EBFDFFDAEFFFFFDAF0FFFFD8EDFFFFD6EB\n      FDFFD6EBFDFFD7ECFDFFBBDAF5FFB8D8F4FFB8D8F4FFB8D8F4FFB8D8F4FFB8D8\n      F4FFB8D8F4FFB9D9F5FF829AADFF000000FF6F8393FFABC9E3FF070506FF368B\n      8EFF52D4D9FF51D2D7FF51D2D7FF51D2D7FF41A6ABFF000000FF04090AFF77F9\n      FFFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF72EE\n      FBFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF76ECF6FFF79A46FFFD963EFFFD96\n      3EFFFD963EFFFD963EFFFD963EFFFCB273B70000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000E9E9E9171A1A\n      1AFA161616FF161616FF121212FF343E31FF374837FF304333FF364D3BFF3553\n      41FF415A49FF6C7F70FF6D9B96FF51C7EAFF4CA4B7FF78967FFF5C7E74FF3C56\n      58FF333C39FF839C91FF8EABA0FF87A69AFF5E7662FF28351CFF9FA249FFD4CE\n      7DFFC3C062FFC6C262FFBEBC58FFC4C063FFC8C06CFFB8B252FFC6BE63FFC9C3\n      6DFF7A8B48FF536F5AFF688359FF637948FF9AA688FF3D4233FF3F4635FF2528\n      21FF495037FF545A4CFF838D72FF26392DFF394F41FF214C2BFF2B5534FF2D4A\n      32FF2E4432FF273E29FF2E4C33FF243928FF171515FF181717FF181616FF1816\n      16FF6E6D6D9FFAFAFA0500000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      000000000000000000000000000000000000FDD7B65FFD963EFFFD963EFFFD96\n      3EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD96\n      3EFFFD963EFFFD963EFFFD963EFFFD963EFFFF9338FFA9CBB1FF70EFFDFF72EE\n      FBFF72EEFBFF72EEFBFF73EFFDFF39787EFF000000FFA9BAC7FFD6EBFDFFD6EB\n      FDFFD6EBFDFFD7ECFEFFB9CCDAFFB9CCDBFFD6EBFDFFD6EBFDFFD6EBFDFFD6EB\n      FDFFD6EBFDFFD6EBFDFFD6EBFDFFD6EBFDFFD6EBFDFFD6EBFDFFD6EBFDFFD6EB\n      FDFFD6EBFDFFD6EBFDFFD6EBFDFFD6EBFDFFD6EBFDFFD6EBFDFFD6EBFDFFD6EB\n      FDFFD6EBFDFFD6EBFDFFB7D7F4FFB8D8F4FFB8D8F4FFB8D8F4FFB8D8F4FFB8D8\n      F4FFB8D8F4FFB9D9F5FF91ABC1FF97B1C8FF90A9BFFF000000FF348589FF52D6\n      DBFF51D2D7FF51D2D7FF51D2D7FF51D2D7FF4FCED3FF000000FF000000FF72EE\n      FBFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF72EE\n      FBFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF8FDCD4FFFF9338FFFD96\n      3EFFFD963EFFFD963EFFFD963EFFFDC08D960000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      00000000000000000000000000000000000000000000000000007B7B7B8F1616\n      16FF161616FF161616FF1B1B1AFF6A725EFF505D42FF425239FF25341AFF3C4C\n      33FF4C6348FF567152FF3E5C3CFF3F623EFF668962FF222A20FF313A2DFF1514\n      14FF21231EFF57774DFF71966FFF516559FF39443DFF4E5B4BFF718E4FFFBEBC\n      65FFCACB74FFB8B85AFFB9B958FFC4C167FFC4C267FFC1BD5EFFD6CD7DFF6C6D\n      3CFF5B6F50FF49583BFF363A2DFF768070FF0C0D0DFF141413FF1C1F18FF0F10\n      0FFF4A5239FF22251BFF60674AFF24352EFF2B5C34FF284A31FF29482FFF2947\n      2FFF223A28FF243929FF203625FF263D2CFF181717FF181616FF181616FF1816\n      16FF242222F1E4E4E41D00000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      000000000000000000000000000000000000FDE8D635FD963EFFFD963EFFFD96\n      3EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD96\n      3EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFF9438FF93DACFFF72EE\n      FBFF72EEFBFF72EEFBFF72EEFBFF5DC2CCFF000000FF393F43FFDDF2FFFFD6EB\n      FDFFD6EBFDFFD6EBFDFFD6EBFDFFD6EBFDFFD6EBFDFFD6EBFDFFD6EBFDFFD6EB\n      FDFFD6EBFDFFD6EBFDFFD6EBFDFFD6EBFDFFD6EBFDFFD6EBFDFFD6EBFDFFD6EB\n      FDFFD6EBFDFFD6EBFDFFD6EBFDFFD6EBFDFFD6EBFDFFD6EBFDFFD6EBFDFFD6EB\n      FDFFD6EBFDFFCAE0F1FF8EA7BCFFB8D8F4FFB8D8F4FFB8D8F4FFB8D8F4FFB8D8\n      F4FFB8D8F4FFB8D8F4FFBCDDF9FF576774FF000000FF3C9A9EFF52D5DAFF51D2\n      D7FF51D2D7FF51D2D7FF51D2D7FF51D2D7FF56DDE2FF020404FF000000FF68D8\n      E4FF72EEFBFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF72EE\n      FBFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF70EFFEFFB8C29CFFFF95\n      3BFFFD963EFFFD963EFFFD963EFFFDD0AA6F0000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000646464A81515\n      15FF161616FF161616FF181817FF31352AFF2F3724FF2F3A21FF212D15FF2330\n      16FF2B3C24FF425837FF4D623AFF41582FFF52663CFF171A19FF2C3E26FF1717\n      17FF1E1F1BFF3C4D32FF3B4D2FFF182216FF1A1E17FF395035FF4A623FFFACB4\n      66FFC0C072FFB0B056FFC2C26AFFD0CE7AFFB7B75AFFCECC70FF939053FF1E23\n      1CFF4D594BFF2A2D29FF1E2120FF4F564FFF1E1F1DFF1B1B1BFF141513FF1717\n      16FF3A402EFF151713FF1A1D12FF313E2EFF32452EFF2F4830FF23412CFF2443\n      2AFF1B291EFF151415FF1D2920FF213629FF171615FF181616FF181616FF1715\n      15FF181616FFCFCFCF3400000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      000000000000000000000000000000000000FEFDFB04FD963EFFFD963EFFFD96\n      3EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD96\n      3EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFF82E4\n      E6FF72EEFBFF72EEFBFF76F6FFFF183436FF000000FF000000FFB4C7D4FFD6EB\n      FDFFD6EBFDFFD6EBFDFFD6EBFDFFD6EBFDFFD6EBFDFFD6EBFDFFD6EBFDFFD6EB\n      FDFFD6EBFDFFD6EBFDFFD6EBFDFFD6EBFDFFD6EBFDFFD6EBFDFFD6EBFDFFD6EB\n      FDFFD6EBFDFFD6EBFDFFD6EBFDFFD6EBFDFFD6EBFDFFD6EBFDFFD6EBFDFFDDF3\n      FFFF96A5AFFF000000FF6E8192FFB8D8F4FFB8D8F4FFB8D8F4FFB8D8F4FFB8D8\n      F4FFB8D8F4FFB8D8F4FF74899BFF000000FF0E2324FF4BC1C5FF51D2D7FF51D2\n      D7FF51D2D7FF51D2D7FF51D2D7FF51D2D7FF55DCE1FF091818FF000000FF60C9\n      D3FF72EEFBFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF72EE\n      FBFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF6EF1FFFFE0A8\n      66FFFD963EFFFD963EFFFD963EFFFEE5D03C0000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000C5C5C53F1515\n      15FF161616FF161616FF151515FF1B1B1CFF282D2CFF3C4C30FF354426FF2643\n      2CFF244935FF295038FF234530FF2B482DFF384F31FF1C1C19FF293425FF1717\n      16FF1A1A1AFF202220FF1A1B1AFF1A1A1AFF1C1D1BFF252720FF4D6B3FFF9397\n      51FF658156FF51795FFFA1A862FFC0BD6DFFCDC979FFA8AB61FF24241BFF252A\n      23FF1C1F1BFF1B1B1BFF191A1AFF34382DFF1C1E1AFF181818FF151415FF1919\n      19FF1B1C1AFF121212FF11170FFF162012FF232D18FF28301AFF295032FF3051\n      38FF2B4934FF171514FF243426FF1C1E1AFF181616FF181616FF181616FF1715\n      15FF403F3FD1F0F0F01000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      00000000000000000000000000000000000000000000FD9E4DEAFD963EFFFD96\n      3EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD96\n      3EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFF49C\n      4AFF76EBF5FF72EEFBFF5CC0CAFF000000FF4FA5ADFF010101FF32373BFFDEF4\n      FFFFD6EBFDFFD6EBFDFFD6EBFDFFD6EBFDFFD6EBFDFFD6EBFDFFD6EBFDFFD6EB\n      FDFFD6EBFDFFD6EBFDFFD6EBFDFFD6EBFDFFD6EBFDFFD6EBFDFFD6EBFDFFD6EB\n      FDFFD6EBFDFFD6EBFDFFD6EBFDFFD6EBFDFFD6EBFDFFDAF0FFFFC8DCEBFF4249\n      4DFF000000FF040505FFB8D8F5FFB8D8F4FFB8D8F4FFB8D8F4FFB8D8F4FFB8D8\n      F4FFB8D8F4FFB8D8F4FFBCDDFAFF8DA6BBFF0F1315FF000000FF3FA4A8FF51D3\n      D8FF51D2D7FF51D2D7FF51D2D7FF51D2D7FF54DAE0FF0E2323FF000000FF5DC3\n      CDFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF72EE\n      FBFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF78EB\n      F3FFFA9843FFFD963EFFFD963EFFFEFBF9070000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000F2F2F20E4343\n      43CC161616FF161616FF161616FF151515FF1F2323FF131D10FF1B2515FF1B2E\n      20FF2A4632FF3B5C3EFF366143FF2F5240FF131E1BFF191A17FF282D25FF1C1B\n      1CFF191919FF191819FF191919FF191919FF181817FF222A1CFF465A36FF999A\n      50FFA0B877FFADC497FFC3C776FFC4C573FFB9BA6EFF373825FF171717FF1C1E\n      1DFF181817FF191919FF191919FF1B1C19FF1C1D1AFF181818FF181818FF1919\n      19FF181818FF121313FF223125FF253524FF262E1AFF1A1E0EFF0C1004FF1115\n      09FF0F1207FF191716FF1B1E1AFF191817FF181616FF181616FF181616FF1715\n      15FE999898700000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      00000000000000000000000000000000000000000000FCB87CACFD963EFFFD96\n      3EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD96\n      3EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD96\n      3EFFE6A55DFF71F3FFFF2A565BFF070E0EFF78FAFFFF42898FFF000000FF9DAD\n      B8FFD6EBFDFFC2D6E5FFB2C4D2FFA9BBC8FFA2B4BFFFA6B7C3FFDAF0FFFFD6EB\n      FDFFD6EBFDFFD6EBFDFFD6EBFDFFD6EBFDFFD6EBFDFFD6EBFDFFD6EBFDFFD6EB\n      FDFFD6EBFDFFD6EBFDFFD6EBFDFFD6EBFDFFDAEFFFFF484F53FF000000FF0000\n      00FF000000FF849BAEFFB8D8F4FFB8D8F4FFB8D8F4FFB8D8F4FFB8D8F4FFB8D8\n      F4FFB8D8F4FFB8D8F4FFB8D8F4FFB8D8F4FFB9D9F5FF191E21FF000000FF42AA\n      AEFF51D2D7FF51D2D7FF51D2D7FF51D2D7FF54DBE0FF0C1E1FFF000000FF5ACA\n      D9FF6CF2FFFF6CF2FFFF6CF2FFFF6CF2FFFF6CF2FFFF6CF2FFFF6CF2FFFF6CF2\n      FFFF6CF2FFFF6CF2FFFF6CF2FFFF6CF2FFFF6CF2FFFF6CF2FFFF6CF2FFFF6CF2\n      FFFF8EDDD5FFFF943AFFFC9F50E6000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000009797\n      9771161616FD161616FF161616FF161616FF181A18FF293223FF262F22FF1622\n      12FF182314FF1A2614FF2A3820FF243527FF1C2225FF15181AFF191919FF1919\n      1AFF191919FF181818FF181818FF181818FF191918FF242B23FF272A17FFA3B3\n      56FFBEC474FFC7D078FFC4CA7BFFC6CD7DFF40422AFF111015FF181818FF1817\n      18FF181818FF181818FF181818FF181817FF1B1B1AFF191919FF181818FF1818\n      18FF181718FF171B1AFF35483BFF404A37FF2A301EFF101408FF0F1106FF2122\n      14FF363822FF181614FF181616FF181616FF181616FF181616FF181616FF2826\n      26ECE5E5E51C0000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      00000000000000000000000000000000000000000000FDD4B067FD963EFFFD96\n      3EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD96\n      3EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD96\n      3EFFFE953DFFD8BC83FF041013FF2C5B5EFF73F1FFFF76F6FFFF0E1D1EFF0F11\n      12FFDBF0FFFFABBCC9FF212527FF000000FF000000FF000000FF9FAFBCFFD6EB\n      FDFFD6EBFDFFD6EBFDFFD6EBFDFFD6EBFDFFD6EBFDFFD6EBFDFFD6EBFDFFD6EB\n      FDFFD6EBFDFFD6EBFDFFD6EBFDFFD6EBFDFFDBF1FFFF41474CFF000000FF0000\n      00FF687279FFBCDDFAFFB8D8F4FFB8D8F4FFB8D8F4FFB8D8F4FFB8D8F4FFB8D8\n      F4FFB8D8F4FFB8D8F4FFB8D8F4FFB8D8F4FFB8D8F4FF9FB9D0FF000000FF0409\n      08FF53D5DAFF51D2D7FF51D2D7FF51D2D7FF55DDE3FF060B0BFF000000FFDB8D\n      44FFF39C4CFFF39C4CFFF39C4CFFF39C4CFFF39C4CFFF39C4CFFF39C4CFFF39C\n      4CFFF39C4CFFF39C4CFFF39C4CFFF39C4CFFF39C4CFFF39C4CFFF39C4CFFF39C\n      4CFFF29D4EFFFB9740FFFDBB83A2000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      000000000000000000000000000000000000000000000000000000000000EBEB\n      EB15262626EC161616FF161616FF161616FF171915FF2A3526FF273324FF1A26\n      16FF212D1EFF192514FF21311CFF243F38FF161D21FF1A1D20FF191918FF1919\n      19FF1A1A1AFF191B1BFF191B1BFF191B1BFF191B1BFF18191AFF64733DFF8DA5\n      3CFF91A64AFF90A33BFFD5D98FFF4C5034FF131516FF181A19FF161918FF1619\n      18FF161918FF161918FF161918FF161918FF161918FF161918FF181818FF1818\n      18FF171717FF1B221EFF203025FF293221FF1F2416FF101409FF101309FF2424\n      15FF32331FFF171515FF161616FF181616FF181616FF181616FF171515FF706E\n      6E9D000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      00000000000000000000000000000000000000000000FEF3E91CFD963EFFFD96\n      3EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD96\n      3EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD96\n      3EFFFD963EFFFF983EFF000000FF377379FF73EFFCFF72EEFBFF5FC6CFFF0000\n      00FF5C656CFFDDF3FFFFDFF4FFFF9EAFBAFF1D2122FF000000FFA6B7C4FFD6EB\n      FDFFD6EBFDFFD6EBFDFFD6EBFDFFD6EBFDFFD6EBFDFFD6EBFDFFD6EBFDFFD6EB\n      FDFFD6EBFDFFD6EBFDFFD6EBFDFFD6EBFDFFD6EBFDFFD8EDFFFF272B2DFF5A63\n      68FFD6EFFFFFB7D7F4FFB8D8F4FFB8D8F4FFB8D8F4FFB8D8F4FFB8D8F4FFB8D8\n      F4FFB8D8F4FFB8D8F4FFB8D8F4FFB8D8F4FFB8D8F4FFC2E4FFFF080809FF0000\n      00FF399092FF51D2D7FF51D2D7FF51D2D7FF52D1D6FF000000FF000000FFFF99\n      3FFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD96\n      3EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD96\n      3EFFFD963EFFFD963EFFFDDABC57000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      000076767695161616FF161616FF161616FF161516FF1E231CFF405040FF2939\n      29FF172414FF131F11FF415F43FF3E5F45FF1C2A2BFF141A1DFF191918FF1919\n      19FF1A1A1AFF191C1CFF1A1C1CFF1A1C1CFF1B1D1DFF141619FF8B9C63FFB4C6\n      7AFFB2C276FFC4D088FF7D874EFF1E1F1CFF191B1AFF181A1AFF181A1AFF181A\n      1AFF161918FF161918FF161918FF161918FF161918FF161918FF181818FF1717\n      17FF161616FF27342DFF3F5D4DFF435240FF293121FF12160BFF18190BFF2827\n      16FF1F2315FF161714FF161616FF181616FF181616FF171515FF171515FFF3F3\n      F30D000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000FD9F4EE9FD96\n      3EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD96\n      3EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD96\n      3EFFFD963EFFFF9A40FF000000FF2D5C60FF73F1FEFF72EEFBFF70E9F5FF142A\n      2CFF000000FF495155FF8897A0FFDBF0FFFFDFF5FFFFA4B6C2FFD9EEFFFFD6EB\n      FDFFD6EBFDFFD6EBFDFFD6EBFDFFD6EBFDFFD6EBFDFFD6EBFDFFD6EBFDFFD6EB\n      FDFFD6EBFDFFD6EBFDFFD6EBFDFFD6EBFDFFD6EBFDFFD6EBFDFFDEF4FFFFDAF0\n      FFFFC6E1F8FFB8D8F4FFB8D8F4FFB8D8F4FFB8D8F4FFB8D8F4FFB8D8F4FFB8D8\n      F4FFB8D8F4FFB8D8F4FFB8D8F4FFB8D8F4FFB8D8F4FFC0E1FEFF000000FF0000\n      00FF398E91FF51D2D7FF51D2D7FF51D2D7FF3E9C9EFF000000FF29180AFFFF9C\n      40FFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD96\n      3EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD96\n      3EFFFD963EFFFD963EFFFEFBF808000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000F4F4F40B151515FF161616FF161616FF161616FF1A1C19FF314032FF3348\n      34FF223122FF1F2C18FF315030FF426940FF406048FF26362FFF161817FF191B\n      1BFF191C1CFF181C1CFF1A1D1CFF1B1E1DFF1B1E1EFF17191EFF879569FFC6D7\n      8FFFCCD79AFFC8D49AFF5D6349FF191C1AFF1A1C1CFF1A1C1CFF1A1C1CFF191B\n      1BFF171A19FF161918FF161918FF151918FF1C1F1EFF171918FF181717FF1817\n      16FF212120FF2F4136FF74937FFF66795CFF414D37FF2A341BFF444C2CFF383C\n      20FF475245FF111111FF171616FF181616FF181616FF171515FF777676950000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000FDC29091FD96\n      3EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD96\n      3EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD96\n      3EFFFD963EFFFF9D41FF190F06FF080E0EFF78FAFFFF5EC5CEFF000000FF2F60\n      65FF3F848AFF2C5D61FF000100FF090A0AFF9BACB7FFD9EFFFFFD6EBFDFFD6EB\n      FDFFD6EBFDFFD6EBFDFFD6EBFDFFD6EBFDFFD6EBFDFFD6EBFDFFD6EBFDFFD6EB\n      FDFFD6EBFDFFD6EBFDFFD6EBFDFFD6EBFDFFD6EBFDFFD6EBFDFFD6EBFDFFD7EC\n      FDFFBDDBF5FFB8D8F4FFB8D8F4FFB8D8F4FFB9D9F5FFB8D8F4FFB8D8F4FFB8D8\n      F4FFB8D8F4FFB8D8F4FFB8D8F4FFB8D8F4FFB8D8F4FF7F93A4FF000000FF0000\n      00FF4CC1C5FF51D2D7FF51D2D7FF52D5DBFF1F4B4CFF000000FF8B5223FFFE97\n      3EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD96\n      3EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD96\n      3EFFFD963EFFFDAB63CC00000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      00000000000088888881151515FF161616FF161616FF151515FF1F2821FF273A\n      28FF253624FF20351DFF508250FF3C643DFF466E51FF243D25FF171A18FF1A1C\n      1CFF181D1CFF191F1CFF1A1D1CFF1B1E1DFF1A1E1FFF1B1D21FF485334FFCBDE\n      8FFFCCD89FFFCAD6A3FF5B624CFF1A1D1BFF1C1E1DFF1A1E1DFF1A1C1CFF1A1C\n      1CFF191B1BFF181A1AFF161918FF161918FF242827FF1A1B1BFF1E1E1EFF1B1A\n      19FF1F1F1FFF566C47FF799769FF6F8566FF293A1BFF506335FF59653DFF454D\n      2FFF3E463DFF151315FF161616FF181616FF181616FF191717FDE0E0E0210000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000FEEAD931FD96\n      3EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD96\n      3EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD96\n      3EFFFD963EFFFF973FFF6F421BFF000000FF0E1A19FF000000FF64D1DBFF73F1\n      FEFF72EEFBFF73F1FEFF74F3FFFF356E73FF000000FF8F9FA9FFD8EDFFFFD6EB\n      FDFFD6EBFDFFD6EBFDFFD6EBFDFFD6EBFDFFD6EBFDFFD6EBFDFFD6EBFDFFD6EB\n      FDFFD6EBFDFFD6EBFDFFD6EBFDFFD6EBFDFFD6EBFDFFD6EBFDFFD6EBFDFFD4EA\n      FDFFB7D7F3FFB8D8F4FFBBDCF9FF92AABFFF5A6875FF647381FF92A9BEFFBEDF\n      FBFFC0E1FEFFBCDDFAFFBBDBF8FFBDDFFCFF9BB4CAFF030303FF000000FF142F\n      2FFF53D9DEFF51D2D7FF51D2D7FF51D0D4FF000000FF000000FFFA943DFFFD96\n      3EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD96\n      3EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD96\n      3EFFFD963EFFFDD2AD6B00000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      000000000000E7E7E71A1D1D1DF7161616FF161616FF161616FF101512FF4557\n      4AFF152311FF416543FF6DA574FF5D965CFF2E5431FF1E3221FF1D231FFF191D\n      1FFF181E1FFF171E1DFF374839FF191C1BFF191F23FF1A1F23FF262828FFAAB9\n      87FFC3D799FFD0E0B0FF76845CFF21251FFF1C1C1CFF1A1F1EFF1A1E1DFF1B1E\n      1DFF181D1CFF181C1BFF181A1AFF151615FF25332EFF3E3F3DFF2E2E2CFF1C1B\n      19FF272826FFBCC7C1FFABBFACFF556C48FF77905BFF778E5CFF728258FF414C\n      2EFF1A1F19FF171617FF161616FF171515FF171515FF686767A5F9F9F9060000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      000000000000000000000000000000000000000000000000000000000000FC9D\n      4DEAFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD96\n      3EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD96\n      3EFFFD963EFFFD963EFFEC8C3AFF000000FF000000FF489399FF72EFFCFF72EE\n      FBFF72EEFBFF72EEFBFF72EEFBFF75F4FFFF3E8186FF000000FFA4B5C1FFD7EC\n      FEFFD6EBFDFFD6EBFDFFD6EBFDFFD6EBFDFFD6EBFDFFD6EBFDFFD6EBFDFFD6EB\n      FDFFD6EBFDFFD6EBFDFFD6EBFDFFD6EBFDFFD6EBFDFFD6EBFDFFD6EBFDFFC9E3\n      F9FFB8D8F4FFBADAF7FF728494FF000000FF122B2BFF286566FF0E2928FF0000\n      00FF1C1F21FF343B42FF434D56FF31393EFF000000FF000000FF010202FF4BBF\n      C3FF51D2D7FF51D2D7FF51D3D8FF2C6C6EFF000000FF70431CFFFF983FFFFD96\n      3EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD96\n      3EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD96\n      3EFFFD963EFFFEFAF70A00000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      000000000000FCFCFC036F6F6F9C161616FF161616FF161616FF131515FF232D\n      22FF355431FF669970FF6CAC6AFF64A267FF538B53FF213B28FF1E2926FF181D\n      1EFF1C1F1EFF2C4232FF4D7654FF151B1BFF192022FF191F23FF1F2224FF525F\n      3FFFBFD0A2FFCADE9FFFA7B48EFF9BA780FF535945FF19201AFF14191CFF191F\n      1FFF181C1EFF181C1CFF181A1AFF121312FF6B7B77FF72827BFF2C2E2CFF1815\n      15FF21251EFF8DA883FF516F3FFF354A27FF748E58FF96AB81FF4E6347FF343E\n      2EFF161916FF161616FF171616FF171515FF1D1B1BF8B6B5B550000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      000000000000000000000000000000000000000000000000000000000000FDCB\n      9F7DFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD96\n      3EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD96\n      3EFFFD963EFFFD963EFFFF973EFF844E21FF070E0FFF77F8FFFF72EEFBFF72EE\n      FBFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF75F6FFFF31666AFF000000FFB5C7\n      D4FFD6EBFDFFD6EBFDFFD6EBFDFFD6EBFDFFD6EBFDFFD6EBFDFFD6EBFDFFD8ED\n      FFFFD7ECFEFFD6EBFDFFD6EBFDFFD6EBFDFFD6EBFDFFD6EBFDFFD7ECFDFFBDDB\n      F6FFBADAF7FF89A2B7FF000000FF0F2324FF54D8DDFF51D3D8FF53D9DEFF50CA\n      CEFF30797BFF132C2CFF000000FF000000FF020101FF1D4546FF4CC3C7FF51D2\n      D7FF51D2D7FF51D2D7FF52D2D6FF020202FF000000FFF7933DFFFD963EFFFD96\n      3EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD96\n      3EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD96\n      3EFFFDB273B70000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      00000000000000000000C5C5C53F202020F3151515FF161616FF161616FF181B\n      18FF426D43FF77B87DFF6EAD78FF417353FF467646FF294831FF172C20FF1E35\n      29FF24372DFF2D5039FF202B26FF182020FF1A2023FF1A2023FF1B2122FF1C22\n      21FF252C2AFF96A292FFDFEDCFFFCEE0C0FFC9D6CBFFA5B891FF404F35FF0F15\n      18FF1A1F1FFF191D1DFF171B1BFF18191AFF1A191AFF7C9A8CFF95B5A5FF6F8D\n      75FF618159FF55724DFF587343FF2F4025FF51663EFF566B41FF526E61FF252C\n      29FF151616FF171616FF171515FF171515FF343232DF00000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      000000000000000000000000000000000000000000000000000000000000FEF9\n      F50CFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD96\n      3EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD96\n      3EFFFD963EFFFD963EFFFF9A40FF462911FF366C70FF73F0FDFF72EEFBFF72EE\n      FBFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF76F6FFFF285457FF0000\n      00FFBCCFDEFFD6EBFDFFD6EBFDFFD6EBFDFFD6EBFDFFD8EDFEFF84929BFF5A65\n      6BFF6E7A82FFACBECAFFDFF6FFFFD6EBFEFFD6EBFDFFD6EBFDFFD1E8FCFFBFE1\n      FEFF697E8DFF000000FF030505FF4EC8CDFF51D2D7FF51D2D7FF51D2D7FF51D2\n      D7FF51D2D7FF53D9DEFF55D9DEFF52D1D6FF55DCE1FF52D6DBFF51D2D7FF51D2\n      D7FF51D2D7FF52D6DBFF255A5CFF000000FF8D5423FFFE973EFFFD963EFFFD96\n      3EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD96\n      3EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD96\n      3EFFFDE4CE400000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      00000000000000000000000000003E3E3ED2151515FF161616FF161616FF1616\n      16FF42594BFF77B784FF71AC81FF2B5238FF3C5C4AFF396145FF203A28FF3F63\n      4EFF2A4033FF1B2522FF191F22FF1A2022FF1B2123FF1C2024FF1C2125FF1C21\n      25FF1D2226FF141A1EFF2C342FFF8C9885FFCED9D2FFD6E0D8FFE0EECFFF8493\n      79FF181D1DFF191D1EFF181C1DFF181C1CFF191B1DFF18191BFF6E8A7AFF5F87\n      65FF345432FF35533DFF9DB09CFF394C35FF43573BFF414F30FF546B5FFF1415\n      15FF161616FF171616FF171515FF171515FFACABAB5B00000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000FDB87DAAFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD96\n      3EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD96\n      3EFFFD963EFFFD963EFFFF983FFF000000FF52A7AFFF72EEFBFF72EEFBFF72EE\n      FBFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF76F6FFFF2751\n      54FF010000FFB0C2CEFFDFF5FFFFDFF6FFFF91A0AAFF0A0B0BFF060F10FF2348\n      4BFF000000FF000000FF151718FF79878FFFADBFCCFFACBECAFF70828EFF161B\n      1EFF000000FF000000FF40A5A9FF51D2D7FF51D2D7FF51D2D7FF51D2D7FF51D2\n      D7FF51D2D7FF51D2D7FF51D2D7FF51D2D7FF51D2D7FF51D2D7FF51D2D7FF51D2\n      D7FF51D2D7FF45AEB2FF000000FF261609FFFF9B40FFFD963EFFFD963EFFFD96\n      3EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD96\n      3EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFDA0\n      52E3000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000C6C6C63E151515FF161616FF161616FF1716\n      17FF28362BFF6FB180FF49774DFF2E4936FF2C4D34FF4B7C5BFF2C503BFF3357\n      45FF1C2725FF1A1F24FF1B2025FF1B2024FF1C2125FF1D2226FF1D2326FF1E23\n      26FF1E2227FF1E2327FF1B2025FF0F1419FF1D2424FF55615CFFA6B0A9FFE3F0\n      DBFF939A8FFF1D2121FF181D1CFF181B1BFF18191BFF18181AFF212725FF273D\n      29FF273C23FF365451FF2B4834FF557560FF577665FF3F5343FF28312CFF1513\n      13FF181616FF171515FF171515FF2F2D2DE40000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000FEEFE324FD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD96\n      3EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD96\n      3EFFFD963EFFFD963EFFD47E34FF000000FF60C6CFFF72EEFBFF72EEFBFF72EE\n      FBFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF76F6\n      FFFF367176FF000000FF222527FF040405FF000000FF38747AFF75F4FFFF75F3\n      FFFF70E9F5FF336A6EFF000000FF000000FF000000FF000000FF000000FF0000\n      00FF000000FF307C7FFF52D5DAFF51D2D7FF51D2D7FF51D2D7FF51D2D7FF51D2\n      D7FF51D2D7FF51D2D7FF51D2D7FF51D2D7FF51D2D7FF51D2D7FF51D2D7FF51D2\n      D7FF4FCBCFFF050B0BFF000000FFE48738FFFD963EFFFD963EFFFD963EFFFD96\n      3EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD96\n      3EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFDD7\n      B75E000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000004A4A4AC5151515FF161616FF1717\n      17FF121213FF4C7A56FF284730FF2B4533FF518565FF70BA80FF3A725BFF3861\n      55FF1A1C1EFF1C2025FF1D2226FF1E2326FF1E2326FF1E2427FF1E2326FF1E23\n      27FF1E2427FF1E2427FF1D2226FF1C2125FF1B2024FF181D22FF1B2224FF8C95\n      81FFDDECC0FF3C413EFF171C1CFF181B1CFF1A191BFF1A191BFF151416FF2937\n      2AFF1A2B1EFF7FA294FF729A89FF6F9890FF375349FF4A635CFF101311FF1715\n      16FF171515FF171515FF171515FFB0B0B0560000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      000000000000FCB273B8FD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD96\n      3EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD96\n      3EFFFD963EFFFD963EFFC67531FF000000FF61C7D0FF72EEFBFF72EEFBFF72EE\n      FBFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF72EE\n      FBFF74F2FFFF69DBE6FF41878DFF3E8287FF6BE0EBFF73F0FEFF72EEFBFF72EE\n      FBFF72EEFBFF73F1FEFF6FE8F3FF2F6165FF000000FF000000FF000000FF0000\n      00FF2C7275FF53D8DDFF51D2D7FF51D2D7FF51D2D7FF51D2D7FF51D2D7FF51D2\n      D7FF51D2D7FF51D2D7FF51D2D7FF51D2D7FF51D2D7FF51D2D7FF52D4D9FF49B9\n      BDFF081211FF000000FFBE712FFFFE963EFFFD963EFFFD963EFFFD963EFFFD96\n      3EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD96\n      3EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFC9C4AED0000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      000000000000000000000000000000000000C4C4C440151515FF171717FF1717\n      17FF161618FF2B362AFF21412AFF2B4E39FF79C397FF60AA86FF3A7457FF3968\n      59FF191A1CFF1F2225FF1E2427FF1E2427FF1F2528FF1E2427FF242A2CFF1D25\n      25FF1D2325FF1D2325FF1E2426FF1E2425FF1C2223FF1A2122FF1C2223FF2328\n      2AFFD5D9D5FF9AA095FF12161AFF191C1EFF191A1CFF18191BFF131517FF3C4D\n      3DFF606E66FFB4D5D8FF527F7EFF385A53FF45635CFF22322EFF161515FF1615\n      15FF171515FF171515FF373636DBF0F0F0100000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      000000000000FEF0E422FD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD96\n      3EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD96\n      3EFFFD963EFFFD963EFFDF8536FF000000FF52A7AFFF72EEFBFF72EEFBFF72EF\n      FCFF73EFFBFF52A9B0FF4A959DFF5BBEC7FF76F7FFFF72EEFBFF72EEFBFF72EE\n      FBFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF72EE\n      FBFF72EEFBFF72EEFBFF72EEFBFF74F2FFFF68D9E3FF2C5C60FF23484BFF3FA4\n      A8FF52D6DBFF51D2D7FF51D2D7FF51D2D7FF51D2D7FF51D2D7FF51D2D7FF51D2\n      D7FF51D2D7FF51D2D7FF51D2D7FF51D2D7FF51D2D7FF51D2D7FF3C9598FF0000\n      00FF010100FFBF712FFFFF973FFFFD963EFFFD963EFFFD963EFFFD963EFFFD96\n      3EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD96\n      3EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFDD9BA5A0000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      000000000000000000000000000000000000F4F4F40B484848C8171717FF1818\n      18FF181918FF171616FF2D4D39FF21402AFF6CAC88FF305D3FFF326446FF2C57\n      44FF1C2526FF1D2226FF1E2427FF1E2527FF1D2427FF2C3431FF98A591FF141B\n      1CFF1E2627FF1E2526FF1E2426FF1E2426FF1D2324FF1C2223FF1B2122FF2228\n      28FFA4AB9EFFABB2A2FF111417FF191C1EFF191A1CFF18191BFF28282BFF5967\n      5DFF8CB0AFFF5F908DFF2F4B44FF425D55FF4E7068FF181919FF161515FF1715\n      15FF171515FF161414FF86858584FEFEFE010000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      00000000000000000000FDBA82A4FD963EFFFD963EFFFD963EFFFD963EFFFD96\n      3EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD96\n      3EFFFD963EFFFD963EFFFF9C40FF080502FF316164FF73F1FEFF73F1FEFF50A2\n      A9FF010000FF000000FF000000FF000000FF0B1819FF5DC2CCFF73F0FDFF72EE\n      FBFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF72EE\n      FBFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF74F1FEFF76F4FFFF56D7\n      DDFF51D2D7FF51D2D7FF51D2D7FF51D2D7FF51D2D7FF51D2D7FF51D2D7FF51D2\n      D7FF51D2D7FF51D2D7FF51D2D7FF51D2D7FF51D2D7FF51CFD3FF000000FF7042\n      1CFFF6923CFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD96\n      3EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD96\n      3EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFCA357DC000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      000000000000000000000000000000000000000000009B9B9B6D191919FD1818\n      18FF181818FF1A1A1BFF1C291FFF2F5039FF294A33FF274535FF305C43FF3569\n      53FF293A34FF1B2225FF1D2528FF1D2528FF171E23FF707E6DFFC4DCB3FF2C38\n      30FF1C2626FF1D2627FF1E2526FF1E2426FF1D2426FF1D2325FF1C2223FF2429\n      2AFFA3B38AFF8C9B75FF13161AFF181B1DFF191A1CFF17181AFF424143FFA1B5\n      B9FF679A96FF4B7A71FF28453DFF45655BFF30463FFF161414FF171515FF1715\n      15FF171515FF232121F0D7D7D72B000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      00000000000000000000FEFAF70AFD963EFFFD963EFFFD963EFFFD963EFFFD96\n      3EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD96\n      3EFFFD963EFFFD963EFFFF973FFF73441CFF000000FF6EE5EFFF65CFD8FF0000\n      00FF0B0703FF975A25FFD07C33FFBC6F2EFF4D2E13FF000000FF55B2BBFF73F0\n      FDFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF72EE\n      FBFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF60DE\n      E7FF51D2D7FF51D2D7FF51D2D7FF51D2D7FF51D2D7FF51D2D7FF51D2D7FF51D2\n      D7FF51D2D7FF51D2D7FF51D2D7FF51D2D7FF53D7DCFF1F4E50FF5D3716FFFF9B\n      40FFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD96\n      3EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD96\n      3EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFEE9D734000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      00000000000000000000000000000000000000000000EBEBEB152D2D2DE71818\n      18FF191818FF191B1BFF171E1CFF29523BFF223B2CFF274231FF264C38FF366B\n      52FF2A5348FF1A1F23FF1D2528FF1D2528FF171E24FF6D7E65FFCBE7AEFF7686\n      72FF1E2627FF1D2627FF1D2626FF1E2526FF1E2426FF1C2324FF1A1F24FF4A54\n      4BFFE2F3D3FF434943FF171B1DFF181B1DFF191A1CFF161719FF3E4F4FFFA8CD\n      CEFF5E9C9AFF4F817BFF32524CFF364F46FF1B1E1CFF171515FF171515FF1715\n      15FF171515FF575656B700000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000FDD3AF68FD963EFFFD963EFFFD963EFFFD96\n      3EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD96\n      3EFFFD963EFFFD963EFFFD963EFFFB953EFF0E0803FF1B3435FF469095FF0000\n      00FFC47430FFFD963EFFFD963EFFFD963EFFFF9B40FF895628FF000000FF52AB\n      B3FF74F1FFFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF72EE\n      FBFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF64E2\n      ECFF51D2D7FF51D2D7FF51D2D7FF51D2D7FF51D2D7FF51D2D7FF51D2D7FF51D2\n      D7FF51D2D7FF51D2D7FF51D2D7FF51D2D7FF43A9ACFF000000FFFA943DFFFD96\n      3EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD96\n      3EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD96\n      3EFFFD963EFFFD963EFFFD963EFFFD963EFFFDB980A600000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      00000000000000000000000000000000000000000000000000008181818B1717\n      17FF181818FF1A1B1BFF171C1BFF406A57FF3D7B50FF4E8071FF2C5A43FF2C63\n      48FF42705DFF172021FF1D2528FF1D2528FF1D2529FF21292DFFABC5A8FFCEE8\n      DFFF7B8D90FF263A3BFF121618FF181B1EFF15191BFF292E30FF6B7373FFDBE6\n      E1FF626C62FF19201FFF1A1E20FF191C1EFF191A1CFF161719FF3F6462FF6199\n      98FF5E9C99FF38625BFF53867FFF3F6057FF120E0EFF171515FF171515FF1614\n      14FF161314FFDFDFDF2200000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      000000000000000000000000000000000000FDA961CFFD963EFFFD963EFFFD96\n      3EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD96\n      3EFFFD963EFFFD963EFFFD963EFFFD963EFFE18537FF050200FF070B0BFF0000\n      00FFB86D2DFFFD963EFFFD963EFFFD963EFFFD963EFFFF9A3FFF6B4B29FF0000\n      00FF469299FF75F5FFFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF72EE\n      FBFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF64E3\n      ECFF51D2D7FF51D2D7FF51D2D7FF51D2D7FF51D2D7FF51D2D7FF51D2D7FF51D2\n      D7FF51D2D7FF51D2D7FF51D2D7FF4FCCD0FF02090AFF8C5323FFFE973EFFFD96\n      3EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD96\n      3EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD96\n      3EFFFD963EFFFD963EFFFD963EFFFD9944F6FEFDFC0300000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000FDFDFD021717\n      17FF191818FF191A1AFF171B1AFF1B2722FF55A667FF58AE90FF3C8359FF5CA9\n      80FF489164FF283935FF1B2427FF1D2528FF1E272CFF1D262AFF587E83FF9DE9\n      EFFFD9F2F7FFC5DFE6FF8EBAC2FF6D9FA9FF82B5BCFF9BCDCDFF5F7C6EFF2C34\n      35FF1A2023FF1A1E20FF1B1C20FF1A1C1EFF191A1CFF1A1C1CFF355E45FF2D6B\n      54FF255043FF48807AFF426961FF171B1BFF161213FF161314FF161314FF1613\n      14FF605E5FAD0000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      000000000000000000000000000000000000FEF6EF14FD963EFFFD963EFFFD96\n      3EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD96\n      3EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFED8C3AFF2B190BFF0000\n      00FF402610FFFF9B40FFFD963EFFFD963EFFFD963EFFFD963EFFFF9B41FF4638\n      23FF000000FF2E5F63FF75F5FFFF72EEFBFF72EEFBFF72EEFBFF76F7FFFF65D2\n      DCFF448E95FF65D1DCFF72EFFCFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF60DF\n      E7FF51D2D7FF51D2D7FF51D2D7FF51D2D7FF51D2D7FF51D2D7FF51D2D7FF51D2\n      D7FF51D2D7FF52D4D9FF4CC3C6FF0A1515FF130B05FFFF9A40FFFD963EFFFD96\n      3EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD96\n      3EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD96\n      3EFFFD963EFFFD963EFFFD963EFFFDE3CD410000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000008F8F\n      8F7B191818FF191A1AFF171A1AFF161718FF2F5A3DFF55A36CFF53A46FFF67C1\n      87FF6EC08EFF294B3CFF1E2427FF1F2629FF1F292FFF232F36FF83A0A3FFD2F7\n      F9FFDEF0F6FFE4F1F8FFBEE4E2FF7BD2C4FF5BA896FF182324FF191D21FF1B20\n      24FF1B1F23FF1A1D21FF1B1C20FF1A1C1FFF191A1CFF1B1F1DFF5D7F5CFF6289\n      68FF23503DFF3D6A62FF2C443DFF141011FF161314FF161314FF161314FF1613\n      14FFD8D8D82A0000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      00000000000000000000000000000000000000000000FDDABD56FD963EFFFD96\n      3EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD96\n      3EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFF9B40FF9B5C\n      26FF0C0703FFC77631FFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFF9C\n      45FF40544CFF000000FF0A1415FF438B91FF52A9B2FF40858CFF162E2FFF0000\n      00FF000000FF000000FF5EC5CFFF72EEFBFF72EEFBFF72EEFBFF73EFFCFF57D7\n      DEFF51D2D7FF51D2D7FF51D2D7FF51D2D7FF51D2D7FF51D2D7FF52D6DBFF54D9\n      DFFF44ACAFFF275F60FF000000FF000000FFC47430FFFD963EFFFD963EFFFD96\n      3EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD96\n      3EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD96\n      3EFFFD963EFFFD963EFFFDC18E94000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      000000000000000000000000000000000000000000000000000000000000E8E8\n      E819262626EF1A1A1AFF181A1AFF191B1CFF1B1D1EFF72BE9DFF7AC89CFF7DBD\n      A3FFD0F2F5FF4E7163FF1D2226FF1E2629FF232E34FF2B3A42FF577176FFDBFC\n      FFFFE7F3FAFFDFEDF4FFE0EBF4FFCEEEF3FF687C7BFF121418FF1B2224FF1D20\n      23FF1C1F21FF1B1D20FF1B1C1FFF1A1C1EFF191A1CFF262C29FFC7DCC5FFA9C7\n      92FF356642FF325B50FF151A18FF151314FF161314FF161314FF161314FF5755\n      56B7F7F7F7080000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000FDBD869EFD96\n      3EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD96\n      3EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFE96\n      3EFFFF9C41FFFA943DFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD96\n      3EFFF8A04FFF62BDC4FF295459FF0E1E20FF070E0FFF070F10FF060B0CFF0000\n      00FF000000FF000000FF040707FF6EE6F2FF72EEFBFF72EEFBFF6FECF8FF4FD1\n      D6FF51D2D7FF51D2D7FF51D2D7FF51D2D7FF54DBE0FF3EA1A5FF1C4749FF0000\n      00FF000000FF000000FF010001FFA36128FFFF983FFFFD963EFFFD963EFFFD96\n      3EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD96\n      3EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD96\n      3EFFFD963EFFFCA65DD400000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      000000000000000000000000000000000000000000000000000000000000FDFD\n      FD027474749A1A1A1AFF1A1A1AFF1A1C1BFF19191CFF516D62FFA1D7BEFF82C3\n      98FFBAEBBFFF7B997FFF1D2727FF1B2628FF243036FF2E3F47FF344D59FFACC0\n      C6FFF6FAFFFFF3F7FCFFF1F6FCFFF2F7FBFFF0F2F2FFB1B2B3FF1C2021FF1B1D\n      20FF1C1E20FF1B1D1FFF1B1D1FFF1A1C1EFF17171BFF505849FFD4EAACFF90B1\n      6EFF769A5DFF617561FF131415FF151414FF161314FF161314FF1A1718FAA9A8\n      A85E000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      000000000000000000000000000000000000000000000000000000000000FCA8\n      60D0FD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD96\n      3EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD96\n      3EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD96\n      3EFFFD963EFFE8A45BFF72F3FFFF77F8FFFF77F9FFFF77F9FFFF77FAFFFF76F6\n      FFFF62CDD8FF265054FF000000FF183234FF76F7FFFF73EFFCFF5EDDE4FF51D2\n      D7FF51D2D7FF51D2D7FF51D3D8FF44AFB4FF091818FF000000FF070E10FF1F41\n      45FF3C7275FFC16E29FFFF9A40FFFE973EFFFD963EFFFD963EFFFD963EFFFD96\n      3EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD96\n      3EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD96\n      3EFFFD9A46F4FEFBF70900000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000C9C9C93B232424F3191A1AFF191B1CFF1A1D1CFF2E2E31FFB9DCBFFF7AC3\n      8BFFBCE6BBFFABBDC0FF242D2FFF192326FF202B30FF2A3841FF2A3F49FF7180\n      86FFF0F4F8FFEDF0F3FFA0A3A5FF7C7F83FF7E8084FF9A9A9DFFCECED0FF4244\n      44FF191B1DFF1B1D1FFF1A1C1EFF191A1CFF131119FF8B9D67FFC4D88FFF91A7\n      79FF91AE66FF485034FF131212FF151414FF161314FF161314FF302D2EE2F3F2\n      F30D000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      000000000000000000000000000000000000000000000000000000000000FEFC\n      FB05FD9E4DEAFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD96\n      3EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD96\n      3EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD96\n      3EFFFD963EFFFE963DFFD5AF74FF6DF1FFFF72EEFBFF72EEFBFF72EEFBFF72EE\n      FBFF72EEFBFF76F7FFFF29565BFF000000FF336B70FF6FEFFBFF50D1D6FF51D2\n      D7FF51D2D7FF52D6DBFF3C9B9EFF000000FF152B2DFF66D5E1FF77F9FFFF75F4\n      FFFF6FF2FFFFD6AF74FFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD96\n      3EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD96\n      3EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD96\n      3EFFFEF0E5220000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000004F5050C2181A1AFF191B1BFF1A1B1CFF1B1F20FF799574FFB2E2\n      ADFFB8E2B8FFE2EFF7FF2E3539FF1B2326FF1B2529FF232E34FF253238FF5C64\n      6AFFECF1F4FFA8ABAEFF0D0F13FF181B1FFF171A1EFF12161AFF0D0E13FF4E4F\n      52FF212224FF1A1D1EFF191A1CFF19191CFF0D0C10FFDDEABCFFE2E1CDFFC6C6\n      B0FFB6B699FF141411FF141414FF151414FF161314FF161314FF8F8E8E7A0000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000FEF6F013FD9A45F5FD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD96\n      3EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD96\n      3EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD96\n      3EFFFD963EFFFD963EFFFF943BFFBEBF94FF6EF0FFFF72EEFBFF72EEFBFF72EE\n      FBFF72EEFBFF72EEFBFF75F5FFFF1E3E41FF000000FF2F7679FF54DADFFF52D5\n      DAFF53D7DCFF266264FF000000FF1A3639FF74F1FEFF72EEFBFF72EEFBFF72EE\n      FBFF72EEFBFF87E1E0FFFF9337FFFD963EFFFD963EFFFD963EFFFD963EFFFD96\n      3EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD96\n      3EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFEE7\n      D437000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      000000000000C7C8C73D161A1AFF181A1AFF181A1CFF18191CFF404F43FFA4D6\n      9AFFE2F1E4FFFBFEFFFF525559FF1D2124FF1E2226FF1E2428FF1C2529FF5961\n      64FFF1F5F9FF2D3034FF1C1F23FF1E2125FF1E2125FF1C1F23FF1C1D22FF1A1B\n      1FFF1C1D21FF191A1EFF18191BFF141517FF494C49FFFAF7E5FFE7E1C9FFD7D3\n      BBFF5E5A51FF110E0FFF161314FF161314FF161314FF1D1A1BF7000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      000000000000FEF3EA1BFD9843F8FD963EFFFD963EFFFD963EFFFD963EFFFD96\n      3EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD96\n      3EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD96\n      3EFFFD963EFFFD963EFFFD963EFFFF9338FFA5CEB6FF70EFFDFF72EEFBFF72EE\n      FBFF72EEFBFF72EEFBFF72EEFBFF75F4FFFF244A4EFF000000FF163839FF1F50\n      52FF020606FF000000FF30656BFF75F5FFFF72EEFBFF72EEFBFF72EEFBFF72EE\n      FBFF72EEFBFF6EF0FFFFD5B075FFFD963EFFFD963EFFFD963EFFFD963EFFFD96\n      3EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD96\n      3EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFEE2CC430000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      000000000000000000004B4E4EC4181A1AFF181A1CFF191A1EFF0F0F12FFC1CB\n      BDFFF5F7F7FFF2F3F7FFA0A2A4FF17191DFF1E2226FF1E2226FF1B2024FF6A6D\n      71FFDADCE0FF101217FF1E2125FF1E2024FF1D2024FF1A1D21FF1C1C20FF1A1C\n      20FF1A1B1FFF191A1EFF18191BFF0E1012FF9A9791FFF0E5D1FFEBE0C8FFD0CB\n      BAFF040000FF161414FF161314FF161314FF161314FF908F8F79000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      00000000000000000000FEF4EB1AFD9A45F5FD963EFFFD963EFFFD963EFFFD96\n      3EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD96\n      3EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD96\n      3EFFFD963EFFFD963EFFFD963EFFFD963EFFFF9439FF90DBD2FF72EEFBFF72EE\n      FBFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF76F6FFFF4DA1AAFF183033FF0B17\n      18FF2B5A5FFF61C9D4FF74F3FFFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF72EE\n      FBFF72EEFBFF72EEFBFF85E2E1FFFF9337FFFD963EFFFD963EFFFD963EFFFD96\n      3EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD96\n      3EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFDE3CC42000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      00000000000000000000C6C7C73E181919FF191A1AFF191A1BFF141616FF4E4F\n      50FFFDFDFEFFEFEEEFFFEDEEEFFF0D1113FF1D2024FF1E2125FF1C1F23FF6B6E\n      72FF96989BFF171A1FFF1C1F24FF1C2024FF1C1E21FF1A1D1FFF1A1C1FFF1A1C\n      1EFF191A1DFF181A1CFF18191BFF0F1012FFD3CEC1FFEFE7D2FFF2E8D1FF5754\n      4BFF141311FF161313FF161314FF161314FF272425ECEEEEEE12000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000FEF7F112FD9E4DEAFD963EFFFD963EFFFD96\n      3EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD96\n      3EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD96\n      3EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFC973FFF80E6E9FF72EE\n      FBFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF76F6FFFF77F9\n      FFFF74F1FEFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF72EE\n      FBFF72EEFBFF72EEFBFF6EF0FFFFD4B177FFFD963EFFFD963EFFFD963EFFFD96\n      3EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD96\n      3EFFFD963EFFFD963EFFFD963EFFFD963EFFFEE9D83300000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      00000000000000000000F4F4F40C4A4E4DC5171A1AFF161918FF181A1AFF0F11\n      11FFC8C9C7FFFDFBF9FFFAF8F8FF3A3B3BFF171B1EFF1B1F21FF1B1F21FF292D\n      2FFF898C8DFF131719FF1A1E20FF1A1E20FF1B1D1FFF1B1D1FFF191A1CFF191A\n      1CFF18191BFF16181AFF151719FF403F3EFFDBD6C4FFECE5D1FFD0CBBDFF2623\n      20FF161412FF161413FF161314FF161314FF7A797990FEFEFE01000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      000000000000000000000000000000000000FEFCFA05FCA961CFFD963EFFFD96\n      3EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD96\n      3EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD96\n      3EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFF39D4DFF75ED\n      F8FF72EEFBFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF72EE\n      FBFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF72EE\n      FBFF72EEFBFF72EEFBFF72EEFBFF85E2E2FFFF9337FFFD963EFFFD963EFFFD96\n      3EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD96\n      3EFFFD963EFFFD963EFFFD9D4AEEFEF3E91C0000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000A1A3A266161A19FD161918FF181A1AFF1719\n      1AFF4D4D4CFFFAF8F6FFF8F4F3FF959595FF111416FF1C1E20FF1C1E20FF1A1C\n      1EFF323436FF181A1CFF1B1D1FFF1B1D1FFF1B1D1FFF1A1C1EFF191A1CFF181A\n      1CFF16181AFF16181AFF161619FF64635EFFE4DFCBFFE9DEC8FF7A7567FF1411\n      10FF161313FF161213FF161214FF201D1EF3C6C5C53E00000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000FDBE889CFD96\n      3EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD96\n      3EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD96\n      3EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFE4A6\n      61FF6FF0FFFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF72EE\n      FBFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF72EE\n      FBFF72EEFBFF72EEFBFF72EEFBFF6FF0FFFFD3B178FFFD963EFFFD963EFFFD96\n      3EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD96\n      3EFFFD963EFFFDAC67C8FEFCFA05000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000EEEEEE122C2E2DE7161918FF181A1AFF181A\n      1AFF202321FFC5C4C2FFF8F6F4FFD7D7D6FF0D0F10FF1B1C1EFF1A1C1EFF1A1C\n      1EFF191B1DFF1B1D1FFF1B1D1FFF1B1D1FFF1A1B1DFF181A1CFF191A1CFF1718\n      1AFF15181AFF161818FF171717FF93948EFFF9F8EAFFE3E0D5FF322F2DFF1512\n      12FF151213FF151213FF151213FF4B4849C40000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      000000000000000000000000000000000000000000000000000000000000FDDB\n      BE54FD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD96\n      3EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD96\n      3EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFE95\n      3CFFCFB47DFF6DF1FFFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF72EE\n      FBFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF72EE\n      FBFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF84E3E4FFFF9337FFFD963EFFFD96\n      3EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD96\n      3EFFFDC99C810000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      00000000000000000000000000000000000083838387171817FF141918FF1419\n      18FF121716FF727471FFEBE9E3FFE1DFDBFF454545FF18191BFF101214FF1D21\n      22FF181A1CFF181A1CFF181A1CFF181A1CFF18191BFF17191BFF16181AFF1719\n      1BFF131617FF111616FF222420FFCBCDC3FFFCFCEFFFACACA3FF0A0907FF1613\n      13FF151213FF151213FF151213FFCECDCD350000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000FEF7F112FDA963CDFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD96\n      3EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD96\n      3EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD96\n      3EFFFF943AFFB7C39EFF6FF0FFFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF72EE\n      FBFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF72EE\n      FBFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF6FF0FFFFD2B279FFFD963EFFFD96\n      3EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD9E4DEAFEEA\n      DA30000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      00000000000000000000000000000000000000000000171717FD151716FF1418\n      17FF141818FF272929FFDAD6D4FFEEEBE6FF888786FF1C1D1DFF848687FF2023\n      25FF151819FF16181AFF16181AFF16181AFF18191BFF17181AFF16181AFF1C1D\n      1EFF636361FF2A2927FF484642FFFFFEEEFFFEFFF0FF242320FF141210FF1613\n      13FF151213FF151213FF413F40CE000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      00000000000000000000FDD4B166FD963EFFFD963EFFFD963EFFFD963EFFFD96\n      3EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD96\n      3EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD96\n      3EFFFD963EFFFF9338FF9ED2BFFF71EFFCFF72EEFBFF72EEFBFF72EEFBFF72EE\n      FBFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF72EE\n      FBFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF83E3E4FFFF9337FFFD96\n      3EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFDC4948C000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000093939376151515FF1617\n      16FF151818FF0A0D0CFF8D8C8AFFECEBE3FFDEDDD6FFDBDAD5FF656866FF090F\n      0EFF141918FF161918FF161918FF161919FF181818FF171717FF171616FF1414\n      14FF4B4A47FFC6C1B1FFD6CCB8FFF5EAD2FFA4A39DFF090809FF141413FF1313\n      13FF131313FF121212FFC5C5C53E000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000FEFBF808FDBC85A0FD963EFFFD963EFFFD96\n      3EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD96\n      3EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD96\n      3EFFFD963EFFFD963EFFFF943AFF8BDFDAFF72EEFBFF72EEFBFF72EEFBFF72EE\n      FBFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF72EE\n      FBFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF6FF0FFFFD0B27BFFFD96\n      3EFFFD963EFFFD963EFFFD963EFFFDAE6BC2FEF2E81D00000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      00000000000000000000000000000000000000000000E7E7E719272727EA1414\n      14FF151515FF151515FF141313FFFDFAF4FFEEECE1FFAFAEA6FF0E110FFF1218\n      16FF141817FF161817FF161817FF161817FF161616FF161616FF151515FF1515\n      15FF0C0C0EFF8C8780FFF7F2E1FFF0E7CDFF312F2DFF131313FF131313FF1212\n      12FF111111FF494949C3F2F2F20D000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      00000000000000000000000000000000000000000000FEF1E71FFCB475B5FD96\n      3EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD96\n      3EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD96\n      3EFFFD963EFFFD963EFFFD963EFFFA9842FF7CE8EEFF72EEFBFF72EEFBFF72EE\n      FBFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF72EE\n      FBFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF82E4E5FFFF93\n      37FFFD963EFFFCA75FD2FEE6D13B000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      00000000000000000000000000000000000000000000FCFCFC03777777931414\n      14FF141414FF151515FF101010FF7B7875FFFCF7EBFF757470FF111211FF1516\n      16FF161616FF161616FF161616FF161616FF151515FF141414FF141414FF1414\n      14FF0F0D10FF595855FFF6ECD0FFA39B87FF1A1819FF131313FF111111FF1111\n      11FF111111FE9494947200000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      000000000000000000000000000000000000000000000000000000000000FEF0\n      E521FDB980A6FD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD96\n      3EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD96\n      3EFFFD963EFFFD963EFFFD963EFFFD963EFFEF9F52FF72EEFBFF72EEFBFF72EE\n      FBFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF72EE\n      FBFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF6FF0FFFFD9C4\n      9AC5FEE6D13B0000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000CACACA391C1C\n      1CF5131313FF141414FF141414FF292626FFF5F3EBFF4E4D49FF121213FF1515\n      14FF151414FF141414FF141414FF151515FF141414FF141414FF121212FF1212\n      12FF0E0D10FF44423DFFEEE8C8FF5D5B56FF101010FF121212FF111111FF1111\n      11FF1F1F1FEFECECEC1400000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      000000000000FEFBF709FDCDA378FDA050E6FD963EFFFD963EFFFD963EFFFD96\n      3EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD96\n      3EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFDEAA69FF6EF1FFFF72EE\n      FBFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF72EE\n      FBFF72EEFBFF72EEFBFF72EEFBFF71EEFCFF76ECF7FCAFF1F697EFFAF9220000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000004A4A\n      4AC1121212FF131313FF131313FF151514FFABAAA2FF62625DFF101010FF1313\n      13FF131313FF131313FF131313FF131313FF131313FF131313FF111111FF1111\n      11FF0D0D0FFF44443FFFE7DDC0FF111113FF111111FF111111FF111111FF1111\n      11FF7E7E7E8A0000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      000000000000000000000000000000000000FEECDC2DFDC4948CFCA152E4FD96\n      3EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD96\n      3EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFF953CFFC8B787FF6EF1\n      FFFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF72EEFBFF72EE\n      FCFF71EEFCFF78EBF6F9A6F0F6A7DAF7F7480000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      000000000000000000000000000000000000000000000000000000000000C8C8\n      C83A101010FF101010FF101010FF0F0E0EFF474644FF20201EFF121212FF1212\n      12FF121212FF121212FF121212FF121212FF111111FF101010FF101010FF1010\n      10FF0F0F0FFF201F1EFF6A695EFF09090AFF101010FF101010FF101010FF1010\n      10FFF3F3F30C0000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      000000000000000000000000000000000000000000000000000000000000FEF5\n      ED17FDD6B462FDBA7FA7FCA052E4FD963EFFFD963EFFFD963EFFFD963EFFFD96\n      3EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFD963EFFFF9439FFAFC8\n      A8FF70F0FEFF72EEFBFF72EEFCFF72EEFCFF72EEFBFF79EBF5F69BEFF6BBBFF4\n      F778E9F8F82E0000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      00003F3F3FC3040404FF040404FF040404FF000000FF020202FF040404FF0404\n      04FF040404FF040404FF040404FF040404FF040404FF040404FF040404FF0404\n      04FF040404FF030302FF000000FF050505FF040404FF040404FF040404FF7979\n      7989000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000FEFEFE01FEEBDB2EFDDABA59FDCB9F7DFDBF\n      8B99FCB578B1FCAB66C9FDA75ED4FCA55CD7FCA55CD7FCA75DD5FCAA63CCFFB1\n      6FB5B3EAE7A2B5F3F68AC8F4F769DFF7F83FF9FBF90F00000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000D2D2D22D000000FF000000FF000000FF000000FF000000FF000000FF0000\n      00FF000000FF000000FF000000FF000000FF000000FF000000FF010101FE0606\n      06F9050505FA050505FA050505FA050505FA070707F80B0B0BF4191919E6E3E3\n      E31C000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      000000000000000000000000000000000000000000000000000000000000A2A2\n      A25D000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000\n      00FF101010EFE0E0E01F00000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      000000000000FCFCFC03F6F6F609F3F3F30CF2F2F20DF3F3F30CF7F7F708FDFD\n      FD02000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000002222\n      22DD000000FF000000FF000000FF000000FF1D1D1DFF000000FF000000FF0000\n      00FF030303FC7575758A00000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      000000000000000000000000000000000000F2F2F20EF7F7F708FEFEFE010000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000F3F3F30CB7B7\n      B748888888776464649B4B4B4BB43D3D3DC2393939C63F3F3FC04F4F4FB06969\n      69968C8C8C73B8B8B847F2F2F20D000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000A0A0A05F0606\n      06F9010101FE000000FF000000FF121212FFBBBBBBFF000000FF000000FF0000\n      00FF000000FF2B2B2BD4E1E1E11E000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      000000000000000000000000000000000000A8A9A95E434445C19393926FE5E5\n      E51AFDFDFD020000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      000000000000000000000000000000000000EFEFEF1066666699171717E80A0A\n      0AF5000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000\n      00FF010101FE0B0B0BF4161616E95E5E5EA1DEDEDE2100000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      00000000000000000000000000000000000000000000F6F6F609474747B80000\n      00FF000000FF000000FF000000FF8A8A8AFFEEEEEEFF383838FF000000FF0000\n      00FF000000FF000000FFA1A1A15E000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      000000000000000000000000000000000000BDBCBC43282F35FF14171BFF3737\n      37CCC5C5C53AF8F8F80700000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      00000000000000000000F5F5F50A8F8F8F70000000FF000000FF010101FE0101\n      01FE000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000\n      00FF000000FF010101FE010101FE000000FF000000FF6161619EE2E2E21D0000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      00000000000000000000000000000000000000000000BEBEBE410E0E0EF10000\n      00FF000000FF000000FF0E0E0EFFE4E4E4FFF4F4F4FF959595FF000000FF0000\n      00FF010101FE000000FF3A3A3AC5F3F3F30C0000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      000000000000000000000000000000000000EBEBEB143D3F42D23F474FFF1E23\n      26FF212121DF9A9A9968F2F2F20D000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      000000000000DCDCDC23454545BA000000FF000000FF010101FE000000FF0000\n      00FF273239FF435662FF556B7BFF5C7585FF5B7485FF546B7AFF465965FF313F\n      48FF181E22FF000000FF000000FF000000FF000000FF000000FF0F0F0FF08585\n      857AF9F9F9060000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      000000000000000000000000000000000000FBFBFB0466666699000000FF0101\n      01FE000000FF000000FF707070FFF0F0F0FFF6F6F6FFCFCFCFFF212121FF0000\n      00FF000000FF000000FF000000FFC1C1C13E0000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      000000000000000000000000000000000000FDFDFD02ACADAD55262D31F9464E\n      57FF1E2329FF06060BF97676768EECECEC130000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000D1D1D12E1E1E1EE1000000FF000000FF010101FE000101FF3A4A54FF9FCA\n      E6FFAFDFFDFFB4E6FFFFB7E8FFFFB5E6FFFFB2E3FFFFB1E1FFFFADDDFBFFA9D7\n      F5FFA3CFECFF98C1DCFF617C8DFF12171BFF000000FF010101FE000000FF0101\n      01FE444444BBF7F7F70800000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      000000000000000000000000000000000000E1E1E11E050505FA000000FF0000\n      00FF000000FF101010FFBCBCBCFFF6F6F6FFF5F5F5FFF7F7F7FF5C5C5CFF0000\n      00FF000000FF010101FE000000FF333333CC0000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      00000000000000000000000000000000000000000000F2F2F20D7A7B7C8D232A\n      30FB414A54FF181D30FF040410FF5B5B5BAAD7D7D728FBFBFB04000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000FEFEFE01FAFAFA05F5F5F50AF0F0F00FEEEEEE11EEEEEE11F4F4F40BFDFD\n      FD02000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      000000000000000000000000000000000000000000000000000000000000EFEF\n      EF10373737C8000000FF000000FF000000FF000000FF030405FF1A2126FF0B0E\n      11FF101418FF212A31FF40525EFF678495FF9CC7E2FFB0E0FFFFB0E0FFFFB0E0\n      FFFFAFDFFEFFB0E0FFFFB3E4FFFFBAEDFFFF799AAFFF1E262CFF030405FF0101\n      01FE000000FF333333CCF5F5F50A000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000006D6D6D92000000FF010101FE0000\n      00FF000000FF464646FFF1F1F1FFF5F5F5FFF4F4F4FFFAFAFAFFB5B5B5FF0909\n      09FF000000FF000000FF000000FF000000FFBFBFBF4000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000E3E3E31C4D50\n      51C12D373DFF313941FE0E1128FE010311FF393D4FCAC0BFC041FCFCFC030000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000FEFEFE01F4F4F40BECECEC13E4E4E41BD6D6D629C0C0C03FACACAC539E9E\n      9E618F8F8F707C7C7C836363639C535353AC4A4A4AB54B4B4BB46262629D9191\n      916ED3D3D32C0000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000007272\n      728D000000FF010101FE000000FF000000FF000000FF000000FF000000FF282D\n      2FFF4F575DFF66757EFF698393FF69889CFF86ABC3FFAEDEFDFFB0E0FFFFB0E0\n      FFFFB0E0FFFFB0E0FFFFAFDFFEFFAFDFFEFFB4E5FFFFAFDEFDFF7392A6FF2029\n      2FFF010101FE000000FF373737C8EAEAEA150000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000F3F3F30C000000FF000000FF000000FF0000\n      00FF060606FF9B9B9BFFFCFCFCFFF5F5F5FFF5F5F5FFF5F5F5FFFFFFFFFF2A2A\n      2AFF000000FF000000FF000000FF000000FF3B3B3BC400000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000FEFEFE01C1C1\n      C13E2E3337F74B545EFF3A4149FE090D1CFF040F42FF191B1CEBC0C0C03FFCFC\n      FC03000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000FAFAFA05F1F1F10EE8E8E817D8D8D827BEBEBE41A2A2A25D8C8C8C737878\n      78875F5F5FA0444444BB333333CC272727D81E1E1EE1151515EA0D0D0DF20909\n      09F6050505FA030303FC010101FE000000FF000000FF000000FF010101FE0606\n      06F9202020DF8383837CF3F3F30C000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000D4D4D42B0000\n      00FF000000FF010101FE000000FF000000FF0C0D0EFF707E86FFBACFDEFFC9E1\n      F0FFD2EAFAFFD7F0FFFFD5F0FFFFCAEBFFFFB4E2FFFFAFDFFFFFB0E0FFFFB0E0\n      FFFFB0E0FFFFB0E0FFFFB0E0FFFFB0E0FFFFAFDFFEFFB0E0FFFFB1E2FFFFA2CE\n      EBFF3D4E59FF010101FE000000FF515151AEF9F9F90600000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      000000000000000000000000000067676798000000FF010101FE000000FF0000\n      00FF222222FFF6F6F6FFF3F3F3FFE8E8E8FFFCFCFCFFF8F8F8FFFCFCFCFFA3A3\n      A3FF000000FF000000FF000000FF010101FE080808F7C0C0C03F000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000FEFEFE01F9F9F906EEEEEE11F3F3F30CFDFD\n      FD02000000000000000000000000000000000000000000000000000000000000\n      000000000000000000000000000000000000000000000000000000000000F9F9\n      F90687888880353B44FF414A57FF12162FFF080F30FE03032BFF2A2A2EDEADAD\n      AC53F6F6F6090000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      00000000000000000000000000000000000000000000F7F7F708EFEFEF10E9E9\n      E916DFDFDF20D8D8D827CECECE31B8B8B8479D9D9D62888888777474748B5A5A\n      5AA53C3C3CC3262626D9181818E70E0E0EF1050505FA000000FF000000FF0000\n      00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0101\n      01FF020202FE030404FF050606FF080909FF0A0D0DFF0A0B0CFF050606FE0101\n      01FE000000FF010101FE6363639CEDEDED120000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      00000000000000000000000000000000000000000000000000004C4C4CB30000\n      00FF000000FF010101FF181B1DFF7A8891FFDAF3FFFFDAF4FFFFD6EFFFFFD5EE\n      FEFFD6EFFFFFD6EFFFFFD5EEFFFFD6EFFFFFD6EFFFFFC4E8FFFFB2E0FFFFB0E0\n      FFFFAFDFFFFFB0E0FFFFB0E0FFFFB0E0FFFFB0E0FFFFB0E0FFFFB0E0FFFFB0E0\n      FFFFB3E3FFFF35444EFF010101FE000000FF9999996600000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      00000000000000000000E2E2E21D141414EB000000FF000000FF000000FF0000\n      00FF919191FFEFEFEFFF686868FF3C3C3CFF646464FFD3D3D3FFFFFFFFFFF8F8\n      F8FF1B1B1BFF000000FF000000FF000000FF010101FE5D5D5DA2000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      00000000000000000000FCFCFC03D4D4D42B7C7C7B854C4C4CB5636466A7B1B1\n      B151FCFCFC030000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000E0E0E01F5C5F62C43E4859FF2D3541FE242A2DFF0F1110FE060609FF1717\n      23EDB1B1B250FCFCFC0300000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000F5F5F50AABABAB546161619E474747B83A3A\n      3AC5292929D61C1C1CE3121212ED080808F7000000FF000000FF000000FF0000\n      00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0101\n      01FE040405FF080A0AFF0E1010FF161B1CFF202728FF2B3233FF343D3EFF3D47\n      49FF465456FF4F6061FF5A6B6DFF627576FF66797BFF66797AFF58686AFE2F38\n      38FE040606FE000000FF010101FE78787887FCFCFC0300000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      00000000000000000000000000000000000000000000DEDEDE21101010EF0101\n      01FE1A1D20FF75838CFFCAE1F0FFDFF9FFFFD6EFFFFFD5EEFEFFD6EFFFFFD6EF\n      FFFFD6EFFFFFD6EFFFFFD6EFFFFFD5EEFFFFD6EFFFFFD7EFFFFFD2EDFFFFC1E6\n      FFFFB0E0FFFFAFDFFFFFB0E0FFFFAFDFFEFFB2E3FFFFB9EBFFFFB9ECFFFFB8EA\n      FFFFB6E8FFFFB1E2FFFF273239FE000000FF000000FFD8D8D827000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      000000000000000000007B7B7B84030303FC010101FE000000FF000000FF0E0E\n      0EFFFAFAFAFFA4A4A4FF000000FF000000FF000000FF141414FF878787FFFDFD\n      FDFF949494FF000000FF000000FF000000FF000000FF1E1E1EE1D1D1D12E0000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      000000000000F9F9F9069F9F9F65171717EA15181BFD2A3137FF262D33FC9799\n      996DFDFDFD020000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000FBFBFB04A5A5A55E4D5660F74D5762FE2F3840FF0C0D10FF03031FFF0303\n      0FFF19191BEABBBBBC4500000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      00000000000000000000E2E2E21D6161619E0E0E0EF1010101FE000000FF0000\n      00FF000000FF000000FF000000FF000000FF000000FF000000FF010101FF0405\n      05FF080909FF0F1112FF1A1F1FFF272E2FFF313B3CFF3E494AFF475558FF5769\n      6BFF65787AFF6C8082FF758A8DFF799093FF80989AFF88A0A2FF869FA1FF849C\n      9FFF88A0A3FF89A2A5FF89A3A5FF8BA4A7FF8AA3A6FF87A0A3FF839D9FFF819A\n      9BFF586768FE070808FF000000FF0A0A0AF5ADADAD5200000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      000000000000000000000000000000000000AEAEAE51171717E8010101FE434B\n      50FEC5DDEBFFD7F0FFFFD6EFFFFFD5EEFEFFD6EFFFFFD6EFFFFFD6EFFFFFD6EF\n      FFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD5EEFFFFD6EFFFFFD5EE\n      FFFFD0EDFFFFB6E2FFFFAEDFFFFFB1E1FFFF89AFC7FF2D3A42FF28343BFF3F51\n      5CFF6B899CFFA7D4F3FF9CC7E2FF010101FE000000FF393939C6000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      000000000000E3E3E31C303030CF000000FF000000FF000000FF000000FF8C8C\n      8CFFEEEEEEFF3E3E3EFF000000FF000000FF000000FF000000FF000000FF2323\n      23FFBCBCBCFF141414FF000000FF000000FF010101FE000000FF88888877FEFE\n      FE01000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000F9F9F906A6A6A75C060606FA16191DFF525A6AFE67707AFF585B5FD1E1E1\n      E11EFEFEFE010000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      000000000000EFEFEF105E6062B657626EFF3F4954FE1E272EFF0F1317FF0809\n      14FE030303FF383837CEE4E4E41BFEFEFE010000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      000000000000CCCCCC33424242BD000000FF000000FF020202FE090C0CFF0D0F\n      10FF141717FF1C2222FF283131FF343E3FFF3E4A4BFF4A575AFF5B6B6DFF687C\n      7EFF708789FF768C90FF7C9597FF839DA0FF8BA4A7FF8BA5A8FF87A1A4FF8AA4\n      A6FF89A3A5FF88A2A4FF8CA5A8FF90A9ABFF8AA3A6FF849FA2FF88A2A5FF8CA5\n      A8FF8CA5A8FF87A0A3FF869FA2FF87A1A4FF86A0A3FF8BA5A7FF8FA7A9FF8CA6\n      A8FF89A3A6FF455254FF010101FE000000FF3A3A3AC5EBEBEB14000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      00000000000000000000EBEBEB144E4E4EB1000000FF0A0B0CFF85959FFEE1FC\n      FFFFD6EEFFFFD5EEFEFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EF\n      FFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD5EE\n      FFFFD6EFFFFFD6EFFFFFBFE6FFFFB1E1FFFF99C3DEFF2E3B43FF0A0D0FFF0000\n      00FF000000FF000000FF252E36FF161C20FF010101FE0B0B0BF4BDBDBD420000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      000000000000A3A3A35C000000FF000000FF000000FF000000FF000000FFDDDD\n      DDFFE4E4E4FF0B0B0BFF000000FF000000FF000000FF000000FF000000FF0000\n      00FF080808FF373737FF000000FF000000FF010101FE000000FF202020DFF0F0\n      F00F000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      000000000000000000000000000000000000000000000000000000000000FEFE\n      FE01C4C4C43C252525DE00011AFF37475DFE5C6683FF525A66FEA7A7A75CFDFD\n      FD02000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      00000000000000000000C3C3C33C3D444BF4535F6AFF313C44FE1B252EFF0D12\n      25FF070702FE07060EFB8586877DF5F5F50A0000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000C3C3C33C2F2F2FD0000000FF000000FF0B0D0DFE465353FF6F8284FF7489\n      8CFF7B9192FF7D9596FF7F999CFF849EA1FF839DA1FF859FA2FF8CA6A8FF8DA6\n      A8FF88A2A6FF87A0A3FF88A2A5FF8AA3A6FF8BA4A7FF8BA5A7FF8EA7A9FF8CA5\n      A8FF8CA5A7FF8FA7AAFF8AA4A6FF88A1A4FF8AA3A5FF89A2A5FF8AA3A6FF8DA6\n      A8FF8EA7A9FF8DA6A8FF8CA5A8FF8BA5A7FF8AA3A7FF8AA3A7FF88A1A4FF86A0\n      A2FF89A2A4FF7A9092FF1E2424FF010101FE080808F798989867FEFEFE010000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      000000000000BFBFBF40252525DA000000FF272C2FFEACC1CDFFDBF4FFFFD5EE\n      FEFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EF\n      FFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EF\n      FFFFD6EFFFFFD6EFFFFFD6EFFFFFC7E9FEFFB3E2FFFFB7E9FFFF94BDD7FF576F\n      7FFF13191DFF000000FF000000FF000000FF000000FF000000FF68686897FCFC\n      FC03000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000F8F8F8073E3E3EC1000000FF010101FE000000FF000000FF000000FF9C9C\n      9CFFF7F7F7FF777777FF000000FF000000FF000000FF000000FF000000FF0000\n      00FF000000FF000000FF000000FF000000FF000000FF010101FE000000FF9D9D\n      9D62000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      000000000000000000000000000000000000000000000000000000000000E3E3\n      E31C40403FC600062FFF212B51FF4A526CFF464D5DFD8C8D8F7BF5F5F50A0000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      00000000000000000000F5F5F50A6E6F719F434B55FF283038FE1D262DFF0C0F\n      1EFF040C40FE03094CFF181819EDADADAD53FBFBFB0400000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      000000000000000000000000000000000000000000000000000000000000CACA\n      CA352E2E2ED1000000FF000000FF141818FE5E7173FF8EA6A8FF96ADAFFF91AA\n      ABFF7F989BFF839D9FFF8CA5A7FF8FA8AAFF90A8AAFF8BA5A7FF8CA6A8FF8AA3\n      A5FF88A1A4FF89A2A5FF8BA3A7FF87A0A3FF829C9FFF819B9FFF839DA0FF88A2\n      A5FF87A1A3FF809B9EFF819B9EFF87A0A3FF8CA6A8FF8DA6A8FF86A0A3FF839D\n      9FFF89A2A5FF8BA4A7FF869FA2FF859FA2FF8DA6A8FF8CA6A8FF88A1A4FF829D\n      A0FF87A1A3FF87A0A3FF536364FF040505FE000000FF303030CFDDDDDD220000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      00009C9C9C63070707F8000000FF464D53FFCDE5F4FFD7F1FFFFD6EFFFFFD6EF\n      FFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EF\n      FFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EF\n      FFFFD6EFFFFFD5EEFFFFD6EFFFFFD6EFFFFFD0ECFEFFB4E1FFFFB0E0FFFFB0E0\n      FFFFA3CFECFF546C7BFF000000FF000000FF000000FF000000FF1C1C1CE3F3F3\n      F30C000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000C6C6C639000000FF000000FF000000FF000000FF000000FF000000FF0707\n      07FFDFDFDFFFE9E9E9FF393939FF000000FF000000FF000000FF000000FF0000\n      00FF000000FF000000FF000000FF000000FF000000FF010101FE000000FF1515\n      15EA000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      00000000000000000000000000000000000000000000FEFEFE01E5E5E51A6464\n      659F05061DFF0C1949FE5F6771FE737C83FE6C6F72AFE7E7E718000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      00000000000000000000FEFEFE01B7B7B74A393F45F5353B44FF353F49FF1D27\n      55FF0A1C4BFF080811FE050414FF181818EEB9B9B947FDFDFD02000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000CFCFCF302E2E\n      2ED1000000FF010101FE15191AFF677A7CFF849EA1FF768E91FF556769FF3139\n      3AFF222829FF475455FF849D9FFF86A0A2FF8EA7A9FF8CA5A7FF859FA2FF87A1\n      A4FF89A2A4FF839DA0FF86A1A3FF8BA4A6FF8CA5A7FF8CA6A8FF8AA3A5FF89A2\n      A4FF8DA6A8FF8DA5A8FF8BA5A7FF8AA3A6FF89A3A5FF859FA2FF86A0A2FF88A2\n      A5FF829DA0FF839DA1FF859FA2FF89A2A4FF89A2A5FF87A0A4FF89A2A5FF86A0\n      A3FF829C9FFF839D9FFF799193FF202727FF000000FF000000FF8181817E0000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      000000000000000000000000000000000000000000000000000000000000A0A0\n      A05F020202FD010101FE495257FFD4EDFDFFD5EEFEFFD5EEFEFFD6EFFFFFD6EF\n      FFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EF\n      FFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EF\n      FFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD1ECFFFFB5E2FFFFAFDF\n      FEFFAFDFFEFFB5E7FFFF98C1DCFF242E34FF010101FF010101FE000000FF4545\n      45BAECECEC130000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      00003C3C3CC3000000FF000000FF000000FF000000FF030303FF000000FF0000\n      00FF262626FFF9F9F9FFC3C3C3FF101010FF000000FF000000FF000000FF0000\n      00FF000000FF000000FF040404FF000000FF000000FF000000FF010101FE0000\n      00FF9E9E9E610000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      00000000000000000000000000000000000000000000E7E7E71862625FA00505\n      25FF0B0C1DFE4F575DFE858E96FF666C72EEBABABA45FDFDFD02000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000DDDDDD224B5054D0424D5DFF27356DFF474F\n      5DFF383D42FF13171BFF101214FE080808FF2C2C3CD9D8D8D827FEFEFE010000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      00000000000000000000000000000000000000000000C4C4C43B2F2F2FD00000\n      00FF000000FF1C2122FE6C8182FF859EA0FF506062FF151919FF010101FF0000\n      00FF000000FF242B2CFF829A9DFF87A1A4FF839EA0FF89A2A4FF8AA3A5FF89A2\n      A5FF8FA8AAFF8FA8A9FF89A3A5FF88A1A4FF8EA8AAFF8CA6A8FF8BA4A6FF8AA3\n      A5FF86A0A2FF88A2A4FF88A1A5FF849EA1FF819A9EFF839DA0FF88A1A3FF8CA5\n      A7FF8BA4A7FF89A2A5FF89A2A5FF88A1A4FF8BA4A6FF8BA3A6FF8BA4A6FF90A8\n      A9FF8FA7A9FF87A1A3FF859FA2FF5E7274FF070908FE000000FF131313ECC8C8\n      C837000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000ADADAD520808\n      08F7000000FF383F43FFCDE6F5FFD7F0FFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EF\n      FFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EF\n      FFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EF\n      FFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD5EEFFFFD6EFFFFFD2EDFFFFB7E3\n      FFFFAEDFFFFFAFDFFEFFB2E3FFFFADDDFBFF607B8CFF030405FE010101FE0000\n      00FF161616E9ACACAC5300000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      000000000000000000000000000000000000000000000000000000000000C7C7\n      C738000000FF010101FE000000FF000000FF080808FF565656FF000000FF0000\n      00FF000000FF686868FFFFFFFFFF8A8A8AFF000000FF000000FF000000FF0000\n      00FF000000FF000000FF444444FF1C1C1CFF000000FF000000FF000000FF0000\n      00FF222222DD0000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      000000000000000000000000000000000000F1F1F10E7C7C7D87040418FF0304\n      2CFF656D72FE818B95FE616973FF6B6C6DACF4F4F40B00000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000F1F1F10E62646AA72B343FFF464E5FFF6068\n      74FF5B646FFF11151BFF101416FF0A0B10FE060610FD7575758DF6F6F6090000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      000000000000000000000000000000000000CDCDCD322E2E2ED1010101FE0000\n      00FF1A1F1FFE73898BFF849C9FFE394344FF060707FF000000FF000000FF0000\n      00FF040404FF556565FF8CA5A7FF8EA6A9FF89A2A5FF88A3A6FF8DA7A9FF8FA8\n      AAFF8EA7A9FF8AA3A6FF849EA0FF849EA1FF87A0A3FF88A2A5FF8BA4A7FF8AA3\n      A5FF87A0A4FF87A1A3FF8AA3A6FF8CA5A8FF8BA4A7FF89A2A5FF849FA1FF839D\n      A0FF869FA2FF88A2A4FF8DA7A9FF8BA4A7FF8BA4A6FF89A3A6FF87A0A3FF8DA5\n      A7FF91A8AAFF8DA6A8FF8BA5A8FF89A2A5FF3A4546FF000000FF000000FF5555\n      55AAF7F7F7080000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      00000000000000000000000000000000000000000000C8C8C837020202FD0000\n      00FF1F2326FED0E9F8FFD7F0FFFFD5EEFEFFD6EFFFFFD6EFFFFFD6EFFFFFD6EF\n      FFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EF\n      FFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EF\n      FFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD5EEFFFFD6EFFFFFD2ED\n      FFFFB6E2FFFFAFDFFFFFAFDFFEFFB0E0FFFFB0E0FFFF90B7D0FF141A1EFF0101\n      01FE000000FF030303FC7E7E7E81000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000003B3B\n      3BC4000000FF010101FE000000FF000000FF343434FFA7A7A7FF000000FF0000\n      00FF000000FF161616FFC4C4C4FFFDFDFDFF191919FF000000FF000000FF0000\n      00FF000000FF000000FF505050FF969696FF000000FF000000FF000000FF0101\n      01FE060606F9A4A4A45B00000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      00000000000000000000FEFEFE01EAEAEA157E7E7F84030304FF03063EFF0A10\n      51FE777F84FE98A1AAFF50555BF4CACACA350000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000F8F8F8078586878123272DFB444B55FF4952\n      5BFF3D464FFF0B0D11FF0A0A10FF07070CFF040403FF2F2F2FD4DDDDDE220000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000C8C8C8372B2B2BD4000000FF010101FE181D\n      1DFE6E8285FF859C9EFF353D3EFF000000FF000000FF000000FF000000FF0203\n      03FF3C4848FF829B9EFF86A0A3FF849FA1FF88A2A5FF87A0A3FF88A1A4FF89A2\n      A5FF87A1A4FF86A0A2FF88A1A4FF88A1A4FF839DA0FF829D9FFF86A0A3FF89A2\n      A4FF8BA4A6FF8CA5A7FF8DA6A8FF8AA4A7FF8EA8AAFF8DA7A9FF89A3A6FF8AA3\n      A6FF849EA1FF849EA1FF86A0A3FF87A0A3FF849DA0FF849EA1FF86A0A3FF859E\n      A1FF87A0A3FF8AA3A5FF88A2A4FF8BA4A7FF758A8CFF131717FF000000FF0C0C\n      0CF3A5A5A55AFEFEFE0100000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      000000000000000000000000000000000000E7E7E718141414EB010101FE0D0F\n      10FFBFD5E3FFD6EFFFFFD5EEFEFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EF\n      FFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EF\n      FFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EF\n      FFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EF\n      FFFFCFECFFFFB3E1FFFFAFDFFFFFB0E0FFFFAFDFFEFFB1E1FFFFA0CDE8FF222B\n      31FF010101FE010101FE000000FF515151AEF6F6F60900000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000BFBFBF400C0C\n      0CF3010101FE000000FF000000FF000000FFADADADFFA7A7A7FF000000FF0000\n      00FF000000FF161616FFC0C0C0FFFFFFFFFF060606FF000000FF000000FF0000\n      00FF000000FF000000FF474747FFF1F1F1FF1B1B1BFF000000FF000000FF0000\n      00FF000000FF4A4A4AB5F9F9F906000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      00000000000000000000ECECEC136F6F6F94050503FF020230FF04105FFE2A33\n      51FF515B78FF5C6670FF7D7E8091F7F7F7080000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000FDFDFD029F9F9F662C3438F83C444EFE434B\n      55FF414A53FF182025FF0C0F11FF04040EFF03030CFF13131CF3B5B5B64AFEFE\n      FE01000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      00000000000000000000C5C5C53A303030CF000000FF010101FE181D1DFE6D81\n      83FF88A1A3FE3E4A4CFF000000FF000000FF000000FF000000FF080A0AFF4855\n      56FF829B9EFF86A0A3FF86A0A3FF87A1A4FF849FA1FF859EA1FF859FA2FF86A0\n      A2FF89A3A5FF8CA6A7FF90A8AAFF92A9ACFF8DA6A8FF88A1A4FF87A1A3FF89A3\n      A5FF8BA4A6FF8DA6A9FF8BA5A7FF88A3A5FF839DA1FF89A2A5FF8BA4A7FF8BA4\n      A7FF8EA7A9FF8CA5A7FF86A0A2FF87A1A3FF8AA3A6FF8AA3A5FF8BA5A8FF8BA5\n      A7FF8AA3A6FF8AA3A6FF87A1A3FF849EA0FF809B9DFF435051FF020203FE0000\n      00FF414141BEECECEC1300000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000FCFCFC035A5A5AA5000000FF010202FE8393\n      9CFFD7F0FFFFD5EEFEFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EF\n      FFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EF\n      FFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EF\n      FFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD5EE\n      FFFFD7EFFFFFCBEAFFFFAFE0FFFFAFDFFFFFB0E0FFFFAFDFFEFFB2E3FFFFABD9\n      F7FF465864FF000000FF010101FE000000FF3F3F3FC0E8E8E817000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000595959A60000\n      00FF000000FF000000FF000000FF262626FFFFFFFFFFA0A0A0FF000000FF0000\n      00FF000000FF474747FFF4F4F4FFC5C5C5FF000000FF000000FF000000FF0000\n      00FF000000FF000000FF474747FFEEEEEEFF9E9E9EFF000000FF000000FF0000\n      00FF000000FF101010EFC0C0C03F000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      000000000000F9F9F9068E8E8E74040402FE02021AFF333842FE292E47FF5D64\n      78FF545D6FFF656A71E8C8C9C938FEFEFE010000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000FEFEFE01CBCBCB342E3439EF394049FE4951\n      5BFF454D56FF1B2227FF050608FF030303FF030311FF040406FF555556B1EDED\n      ED12000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      000000000000CECECE31323232CD010101FE010101FE191E1EFE6B8081FF8DA6\n      A8FE7C9193FF111414FF000000FF000000FF020302FF212829FF65787AFF859E\n      A1FF8CA5A8FF8FA8AAFF8BA4A6FF88A2A5FF8AA3A5FF8AA3A5FF87A0A3FF829C\n      9FFF809A9EFF86A0A3FF8CA4A6FF8DA6A8FF8EA8AAFF8AA3A6FF859FA3FF869F\n      A3FF849EA1FF86A0A2FF87A0A3FF859EA1FF859EA1FF87A1A4FF8BA5A7FF8BA4\n      A7FF8CA5A8FF8BA4A6FF88A2A5FF89A3A6FF88A2A4FF86A0A3FF869FA2FF8AA3\n      A6FF8AA3A6FF89A2A5FF8BA4A7FF8DA5A7FF87A0A3FF778E90FF1C2121FF0000\n      00FF020202FD9595956A00000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000B9B9B946000000FF000000FF3C4348FFDAF3\n      FFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD5EE\n      FEFFD6EFFFFFD8F2FFFFDBF4FFFFDAF4FFFFD6EFFFFFD5EEFEFFD6EFFFFFD6EF\n      FFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EF\n      FFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EF\n      FFFFD5EFFFFFD6EFFFFFC8EAFFFFAEDFFFFFAFDFFFFFB0E0FFFFAFDFFEFFB0E0\n      FFFFACDBFAFF556D7CFF000000FF000000FF000000FF181818E7E2E2E21D0000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      00000000000000000000000000000000000000000000D0D0D02F1B1B1BE40000\n      00FF000000FF000000FF000000FFABABABFFF9F9F9FFA0A0A0FF000000FF0000\n      00FF050505FFA2A2A2FFFFFFFFFF717171FF000000FF000000FF000000FF0000\n      00FF000000FF000000FF474747FFEBEBEBFFE9E9E9FF1F1F1FFF000000FF0000\n      00FF010101FE000000FF6F6F6F90FCFCFC030000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000FCFCFC03B4B4B34D0A0A0FFA020209FF070823FE394A75FF6C798BFF7C87\n      91FE333941FE7B7E8199F2F2F20D000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      000000000000000000000000000000000000F2F2F20D5F6161AF323B42FF444E\n      57FE525B66FF363E46FF14171FFF05061AFF040304FF030303FF040405FF9393\n      9370FBFBFB040000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000D6D6D6293A3A3AC5000000FF000000FF131617FF697C7CFF8EA6A9FE8CA5\n      A7FF80979AFF353E40FF1B2022FF30393AFF5C6C6EFF80989AFF839DA0FF819C\n      9FFF849FA1FF87A1A3FF89A2A5FF89A2A5FF8BA5A7FF8CA5A8FF8BA5A8FF8AA3\n      A6FF839DA1FF839DA0FF849EA0FF829C9FFF87A1A4FF8CA5A8FF88A0A3FF88A1\n      A3FF8AA3A6FF86A0A3FF86A1A3FF8CA5A8FF90A9AAFF8BA4A6FF85A0A2FF87A2\n      A4FF8AA3A6FF8AA4A6FF8CA5A7FF8BA4A6FF8BA4A6FF88A2A3FF87A1A4FF8AA3\n      A6FF87A1A4FF839C9FFF89A2A5FF8DA7A9FF8DA6A8FF8DA6A9FF576668FF0201\n      01FE000000FF272727D8DADADA25000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000101010EF000000FF040505FED0E9F8FFD7F0\n      FFFFD5EEFEFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD5EEFEFFD6EFFFFFD6EF\n      FFFFC0D6E5FF8C9CA6FF69757EFF707D86FFBDD4E2FFD6EFFFFFD6EFFFFFD6EF\n      FFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EF\n      FFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EF\n      FFFFD6EFFFFFD5EEFFFFD5EEFFFFBEE5FFFFAFDFFFFFB0E0FFFFB0E0FFFFB0E0\n      FFFFB0E0FFFFB7E8FFFF495D69FF000000FF010101FE000000FF131313ECB8B8\n      B8479898986798989867C8C8C837ECECEC13FEFEFE0100000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      000000000000000000000000000000000000FCFCFC038383837C000000FF0000\n      00FF000000FF000000FF2E2E2EFFE9E9E9FFF6F6F6FFA0A0A0FF000000FF0000\n      00FF2C2C2CFFF9F9F9FFFFFFFFFF232323FF000000FF000000FF000000FF0000\n      00FF000000FF000000FF474747FFEBEBEBFFF3F3F3FF868686FF000000FF0000\n      00FF000000FF000000FF090909F6E6E6E6190000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      000000000000000000000000000000000000000000000000000000000000F9F9\n      F906B0B0B04F2F2F35D802021CFF02021EFE232834FF8F99A2FF828B95FE6F7C\n      88FF5F676FEAC8C8C837FEFEFE01000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      00000000000000000000000000000000000000000000A2A2A15F292F35FF424C\n      55FF424A53FF454E59FF191F32FF060C55FF060704FF050505FE030302FF2223\n      2EE1D0D0D030FEFEFE0100000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      000000000000000000000000000000000000000000000000000000000000D9D9\n      D9263D3D3DC2000000FF010101FE131818FE627476FF88A2A5FF859FA2FF849E\n      A1FF89A2A5FF849C9EFF809799FF869EA1FF87A2A4FF8CA5A8FF90A7A9FF8FA7\n      A9FF8BA4A6FF88A1A4FF8EA7A9FF8BA3A7FF86A0A2FF869FA2FF8CA5A7FF8EA8\n      A9FF8CA5A8FF8AA3A5FF8CA5A7FF8AA3A6FF88A1A4FF89A3A5FF8AA3A6FF8BA4\n      A6FF8AA3A6FF87A0A2FF829DA0FF85A0A2FF8CA5A7FF8CA5A7FF8BA4A6FF859F\n      A2FF849FA1FF849FA1FF87A2A4FF8BA4A5FF8CA5A7FF8FA8AAFF8BA4A7FF89A2\n      A4FF859FA2FF88A1A4FF849EA1FF89A2A5FF91AAACFF90A8ABFF8AA2A4FF2D34\n      35FF000000FF000000FF6565659AFAFAFA050000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000079797986000000FF010101FE82919BFFDBF4FFFFD5EE\n      FEFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD5EEFEFFD6EFFFFFDEF8FFFF7E8C\n      96FF0E0F10FF000000FF000000FF000000FF282D30FFDFF9FFFFD6EFFFFFD6EF\n      FFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EF\n      FFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EF\n      FFFFD6EFFFFFD6EFFFFFD6EFFFFFD2EDFFFFB4E1FFFFAFDFFFFFB0E0FFFFB0E0\n      FFFFAFDFFEFFB0E0FFFFB6E7FFFF4D6270FF000000FF010101FE000000FF0000\n      00FF000000FF000000FF000000FF1F1F1FE076767689E4E4E41B000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      000000000000000000000000000000000000F3F3F30C191919E6000000FF0101\n      01FE000000FF000000FF939393FFF4F4F4FFF6F6F6FFA0A0A0FF000000FF0000\n      00FF757575FFFFFFFFFFDEDEDEFF0D0D0DFF000000FF000000FF000000FF0000\n      00FF000000FF000000FF474747FFEBEBEBFFF5F5F5FFCBCBCBFF1F1F1FFF0000\n      00FF000000FF000000FF000000FF787878870000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000FBFBFB04A7A7\n      A75A161615EE040405FF040406FE252A2FFF6D7781FF838D97FF75808AFE6973\n      7DFF85868684F9F9F90600000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      00000000000000000000000000000000000000000000DFDFDF203B3F43E64851\n      5BFF404851FE384049FF323B3EFF101952FF061C81FF0A0807FF07070CFE0505\n      0AFD7A7A7989F6F6F60900000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000E5E5E51A4747\n      47B8020202FD000000FF131617FE687B7DFE8AA4A6FF87A1A3FF89A2A5FF8CA6\n      A8FF8EA7A9FF8DA7A9FF8BA4A7FF89A2A5FF89A2A4FF88A1A4FF869FA2FF849E\n      A0FF819C9FFF839DA0FF89A2A5FF8CA5A7FF8CA5A7FF8BA4A6FF829D9FFF849E\n      A1FF8EA8A9FF8FA7A9FF8BA4A6FF87A0A3FF809C9EFF839DA0FF89A2A5FF87A1\n      A4FF809B9EFF7C9699FF829C9EFF869FA2FF849DA0FF8BA4A7FF8EA7AAFF87A1\n      A4FF859EA1FF89A2A4FF8DA6A8FF8FA8AAFF8AA3A5FF8AA3A6FF8BA4A6FF8AA2\n      A6FF8CA5A8FF8FA8AAFF8DA7A9FF8BA5A7FF8EA6A9FF8FA8AAFF8CA4A7FF667B\n      7DFF0D1010FE000000FF141414EBBBBBBB440000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      000000000000E4E4E41B181818E7000000FF262A2DFFC7DFEEFFD6EFFFFFD6EF\n      FFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD4ECFCFF434B50FF0000\n      00FF000000FF000000FF050607FF101213FF84939DFFD9F3FFFFD6EFFFFFD6EF\n      FFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EF\n      FFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EF\n      FFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFCBEAFFFFADDFFFFFB0E0FFFFB0E0\n      FFFFB0E0FFFFAFDFFEFFB0E0FFFFABDAF8FF42545FFF000000FF080A0CFF141A\n      1DFF000001FF010101FE000000FF000000FF000000FF191919E6CBCBCB340000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000009494946B000000FF010101FE0000\n      00FF000000FF232323FFCFCFCFFFF5F5F5FFF6F6F6FFA0A0A0FF000000FF0000\n      00FF535353FFFFFFFFFFFFFFFFFF464646FF000000FF000000FF000000FF0000\n      00FF000000FF000000FF474747FFEBEBEBFFF5F5F5FFF8F8F8FF595959FF0000\n      00FF000000FF000000FF000000FF000000FFFBFBFB0400000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      00000000000000000000000000000000000000000000FEFEFE01C9C9C9361313\n      14F2030303FF040403FE0E1012FF536068FF7B888FFF717D89FF727E87FF5D60\n      62C7E7E7E7180000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      00000000000000000000000000000000000000000000F9F9F9067A7A7C8E3439\n      40FF404952FF3B444DFF424C53FF0C0E42FF0E1011FF0A0C1AFF05070DFF0509\n      17FF313A52D3E1E0E01F00000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      00000000000000000000000000000000000000000000E8E8E8174C4C4CB30000\n      00FF000000FF0F1212FE627375FE8CA5A7FF89A2A4FF869FA2FF8AA3A5FF85A0\n      A3FF839D9FFF849EA1FF89A3A5FF8DA7A9FF8BA3A6FF829C9FFF809B9EFF849D\n      A0FF88A2A4FF89A2A5FF88A1A4FF88A1A3FF87A1A3FF89A2A6FF8EA7A8FF8CA5\n      A7FF8AA3A5FF8CA5A8FF8AA3A6FF8AA2A5FF88A1A4FF8BA4A6FF8FA8A9FF8EA6\n      A8FF88A0A2FF869EA0FF89A2A5FF88A1A4FF89A2A4FF859EA1FF87A1A3FF8DA6\n      A8FF8AA3A7FF8AA3A6FF8DA6A8FF8EA7A9FF89A2A4FF849EA0FF89A2A5FF89A2\n      A5FF8BA5A8FF8AA4A6FF89A2A4FF86A0A2FF839DA0FF849EA0FF859FA2FF849D\n      A0FF3D4849FF010101FE000000FF525252ADF0F0F00F00000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000008E8E8E71020202FD000000FF738089FFD7F0FFFFD6EFFFFFD6EF\n      FFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFCBE3F2FF9BAEB9FFB3C8\n      D6FFD1E9F9FFE2FCFFFFE3FDFFFFE0FAFFFFD6EFFFFFD2EBFBFFD5EEFEFFD8F1\n      FFFFD7F0FFFFD6F0FFFFD6EFFFFFD5EEFEFFD6EFFFFFD6EFFFFFD6EFFFFFD6EF\n      FFFFD6EFFFFFD6EFFFFFD5EEFEFFD6EFFFFFD4EDFCFFD6EFFFFFD5EEFEFFD6EF\n      FFFFD6EFFFFFD6EFFFFFD6EFFFFFD5EEFFFFD7EFFFFFBDE5FFFFAEDFFFFFAFDF\n      FFFFB0E0FFFFB0E0FFFFB0E0FFFFB0E0FFFFA9D7F5FFAAD9F6FFB9ECFFFFB8EA\n      FFFFBAEDFFFF94BCD6FF3F505BFF0B0E0FFF010101FE000000FF000000FFBFBF\n      BF40000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000FEFEFE01151515EA000000FF000000FF0000\n      00FF000000FF656565FFFAFAFAFFF5F5F5FFF6F6F6FFA0A0A0FF000000FF0000\n      00FF0A0A0AFFCBCBCBFFFBFBFBFFE5E5E5FF111111FF000000FF000000FF0000\n      00FF000000FF000000FF474747FFEBEBEBFFF4F4F4FFFAFAFAFFBFBFBFFF0909\n      09FF000000FF000000FF010101FE000000FF7575758A00000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      00000000000000000000000000000000000000000000EBEBEB1449494ABC0202\n      02FF070708FE0A0C0DFF191E22FF414950FF555C64FF6C767EFF50585FEFBCBC\n      BC44FEFEFE010000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000C0C0C0412D31\n      37EF2B3239FF363D47FF252E3EFF082189FF0C0F42FF07155BFF0A163FFF0808\n      0BFF1A1A1CEDC7C7C73900000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      000000000000000000000000000000000000E0E0E01F505050AF000000FF0000\n      00FF121516FE5E7273FE88A2A4FF869FA3FE849FA1FF87A0A3FF859FA2FF87A1\n      A3FF859EA1FF859EA1FF87A1A3FF87A0A3FF88A1A4FF8CA5A8FF90A9ABFF8DA6\n      A9FF8CA5A7FF8BA4A6FF89A2A5FF8EA6A9FF8BA4A6FF859FA2FF849EA1FF849D\n      A0FF849FA1FF89A1A4FF86A0A2FF86A0A3FF8AA4A7FF8AA3A5FF8AA4A6FF7990\n      93FF799092FF8EA7A8FF8DA6A8FF89A3A5FF87A0A3FF849EA1FF87A1A4FF8CA5\n      A7FF8BA5A7FF86A0A2FF829D9FFF829C9FFF819C9EFF859FA1FF869FA3FF89A2\n      A5FF88A0A4FF86A0A3FF87A0A3FF839DA0FF809A9EFF829DA0FF869FA2FF89A2\n      A5FF73888BFF141717FF000000FF0C0C0CF3A8A8A85700000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000F3F3F30C373737C8000000FF0E0F10FFBCD2E0FFD6F0FFFFD6EFFFFFD6EF\n      FFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD5EEFEFFD6EFFFFFDAF3FFFFDEF8\n      FFFFDAF3FFFFAABDCAFF7B8A93FF5D686FFF515B61FF535C63FF5E6970FF7381\n      89FF90A1ACFFB3C8D5FFDAF3FFFFDFF9FFFFD9F3FFFFD6EFFFFFD6EFFFFFD6EF\n      FFFFD6EFFFFFD6EFFFFFD6EFFFFFD2EAFBFF616C73FFD9F2FFFFD6EFFFFFD6EF\n      FFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD2EDFFFFB3E1FFFFAFDF\n      FFFFB0E0FFFFB0E0FFFFB0E0FFFFAFDFFEFFB0E1FFFFB1E1FFFFAFDFFEFFAFDF\n      FEFFAFDFFEFFB2E3FFFFB8EAFFFF8EB5CFFF2C3840FF010101FE000000FF0B0B\n      0BF4C7C7C7380000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      00000000000000000000000000009090906F000000FF010101FE000000FF0000\n      00FF080808FFCACACAFFF9F9F9FFF4F4F4FFF6F6F6FFA0A0A0FF000000FF0000\n      00FF000000FF565656FFF2F2F2FFFAFAFAFFAAAAAAFF000000FF000000FF0000\n      00FF000000FF000000FF474747FFEBEBEBFFF5F5F5FFF5F5F5FFFEFEFEFF3D3D\n      3DFF000000FF000000FF000000FF000000FF171717E8EDEDED12000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      000000000000000000000000000000000000FBFBFB04A1A1A2610B0A0BF60F11\n      13FF0E1013FF0B0B0FFF5B646CFF7B8A93FF82919AFE6B7981FE7F82849FEFEF\n      EF10000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000DEDEDE213C3D\n      40CF13181EFF1C2328FF2B3538FF0A1254FF1A263FFF101114FF06123CFF070B\n      25FF0A0910FFA5A6A75AFDFDFD02000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000E9E9E916525252AD040404FB000000FF0E10\n      10FE65797AFE8AA5A6FF8BA4A6FE89A2A5FF86A0A3FF8AA3A6FF8AA3A6FF869F\n      A2FF849EA0FF87A0A3FF859FA2FF839DA0FF869FA2FF89A2A5FF859FA1FF87A1\n      A3FF8BA4A7FF8DA7A9FF89A2A5FF88A1A4FF8EA7A9FF8EA7A9FF89A2A4FF89A2\n      A5FF88A1A4FF87A1A3FF89A3A6FF8BA4A7FF8DA5A8FF93ACADFF7E9293FF6174\n      75FF859EA1FF8BA4A7FF8EA8A9FF92ABACFF90A9ABFF8BA4A7FF859EA1FF829C\n      9FFF88A2A5FF8FA9ABFF8DA5A7FF859FA1FF819C9FFF819B9FFF86A0A3FF88A1\n      A4FF87A1A3FF8AA3A6FF8CA5A7FF8CA5A7FF87A1A4FF839EA0FF87A0A3FF8BA4\n      A7FF8DA6A9FF4B5859FF000000FF000000FF2D2D2DD2E7E7E718000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000D4D4D42B000000FF000000FF454D52FFDFF9FFFFD6EFFFFFD6EFFFFFD6EF\n      FFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD5EEFEFFD6EFFFFFE1FBFFFF92A2\n      ADFF262A2DFF0B0D0EFF010101FF000000FF000000FF000000FF000000FF0000\n      00FF060607FF0E0F10FF191C1DFF566067FFA8BDC9FFDDF7FFFFD9F3FFFFD6EF\n      FFFFD5EEFEFFD6EFFFFFD6EFFFFFDEF8FFFF080809FFABBFCCFFD7F0FFFFD6EF\n      FFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD5EEFFFFD6EFFFFFC3E7FFFFB0E0\n      FFFFB0E0FFFFB0E0FFFFB0E0FFFFB0E0FFFFB0E0FFFFB0E0FFFFB0E0FFFFB0E0\n      FFFFB0E0FFFFAFDFFEFFAFDFFEFFB1E1FFFFA2CFEBFF2B373EFF010101FE0000\n      00FF3B3B3BC4F3F3F30C00000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      00000000000000000000FEFEFE011D1D1DE2000000FF000000FF000000FF0000\n      00FF484848FFFFFFFFFFF5F5F5FFF5F5F5FFF6F6F6FFA0A0A0FF000000FF0000\n      00FF000000FF080808FFB2B2B2FFF6F6F6FFEDEDEDFF595959FF000000FF0000\n      00FF000000FF000000FF474747FFEBEBEBFFF5F5F5FFF4F4F4FFF9F9F9FFC2C2\n      C2FF000000FF000000FF000000FF010101FE040404FB8585857A000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      000000000000000000000000000000000000F2F2F20D595958AA030314FF1519\n      1CFF161A21FF191E23FF7B8790FF556874FF85939CFF6A7176E9C6C6C639FDFD\n      FD02000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000E9E9E9164849\n      49BC13171DFF232C33FF363D46FF373E42FF101627FF10151BFF090705FF0908\n      10FE0D0D0CFF7777778EFBFBFB04000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      00000000000000000000E8E8E8175F5F5FA0000000FF000000FF0B0E0EFE5667\n      69FE859FA0FF88A2A4FF869FA2FF849EA1FF88A2A4FF859FA2FF89A2A5FF8AA3\n      A6FF89A2A5FF87A1A4FF89A1A4FF89A2A5FF86A0A3FF859EA1FF86A0A3FF8CA5\n      A7FF8DA7A8FF8CA5A8FF89A2A5FF859FA1FF86A0A2FF869FA2FF88A1A3FF8EA7\n      A9FF91A9ABFF8AA3A6FF859FA2FF849EA0FF839DA0FF6C8284FF505F61FF88A1\n      A4FF87A1A4FF88A2A4FF89A3A5FF89A3A6FF8AA3A6FF8AA4A7FF89A2A4FF8AA3\n      A5FF8BA4A6FF8BA3A6FF8EA6A8FF8CA5A7FF8DA6A8FF8EA7A8FF8CA5A7FF859F\n      A1FF849EA1FF87A0A3FF8AA3A5FF91A9AAFF91AAACFF8EA6A8FF8CA5A6FF8BA4\n      A6FF86A0A3FF789194FF222929FE000000FF000000FF7D7D7D82000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      00007171718E000000FF010101FEA2B5C0FFDAF3FFFFD6EFFFFFD6EFFFFFD6EF\n      FFFFD6EFFFFFD6EFFFFFD5EEFEFFD6EFFFFFD6EFFFFFB7CCDAFF31373BFF0000\n      00FF000000FF020202FF0C0C0CFF131313FF191919FF1F1F1FFF2A2A2AFF2727\n      27FF1B1B1BFF131313FF090909FF000000FF000000FF191C1EFF7F8E97FFC1D8\n      E6FFD1E9F9FFD8F1FFFFD6EFFFFFDFF9FFFF2A2F31FF66737AFFD6EFFFFFD5EE\n      FEFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD1EDFFFFB3E1\n      FFFFAFDFFFFFB0E0FFFFB0E0FFFFB0E0FFFFB0E0FFFFB0E0FFFFB0E0FFFFB0E0\n      FFFFB0E0FFFFB0E0FFFFB0E0FFFFB0E0FFFFB1E1FFFF86ABC3FF080A0CFF0101\n      01FE000000FFBCBCBC4300000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000099999966070707F8010101FE000000FF000000FF0000\n      00FFCCCCCCFFF8F8F8FFF5F5F5FFF5F5F5FFF6F6F6FFA0A0A0FF000000FF0000\n      00FF000000FF000000FF3F3F3FFFE9E9E9FFF6F6F6FFC7C7C7FF191919FF0000\n      00FF000000FF000000FF474747FFEBEBEBFFF5F5F5FFF5F5F5FFF4F4F4FFFFFF\n      FFFF363636FF000000FF000000FF000000FF000000FF383838C7ECECEC130000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      000000000000000000000000000000000000E0E0E01F363635CD030857FF0D10\n      35FF1B2125FF646E76FF6D7984FF4C5D68FE70808CFF7576779DF7F7F7080000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000EAEAEA155153\n      56B8181D25FF1E262EFF2F3840FF434D57FF262C36FF090B24FF090B1CFF090D\n      23FF0A1434FF6566689FFAFAFA05000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      000000000000ECECEC136060609F020202FD000000FF070909FF546365FE8CA5\n      A6FF90A9A9FE8FA8AAFF89A2A5FF89A1A4FF8AA3A6FF87A0A4FF87A1A3FF8BA4\n      A7FF8DA6A8FF8CA4A7FF8AA3A6FF8CA5A7FF8CA5A7FF8AA3A6FF89A2A5FF88A1\n      A4FF87A1A3FF8AA3A5FF8DA6A8FF8DA6A9FF8BA4A6FF8CA5A8FF8DA6A8FF8DA6\n      A8FF89A3A5FF88A2A4FF8BA4A7FF8CA6A9FF728789FF3F4B4CFF758C8EFF849F\n      A1FF87A0A3FF89A3A6FF8AA3A6FF88A2A4FF859FA2FF87A1A4FF8AA2A6FF89A2\n      A5FF88A2A4FF849FA2FF849EA1FF88A1A5FF90A8ABFF8EA7A9FF89A3A6FF8CA5\n      A8FF8CA5A7FF89A3A6FF87A0A4FF819DA0FF86A0A3FF8FA7A9FF8CA6A8FF839E\n      A0FF859EA2FF89A3A5FF627476FF08090AFE000000FF1B1B1BE4C8C8C8370000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000101010EF000000FF0F1112FFDEF8FFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EF\n      FFFFD6EFFFFFD5EEFEFFD9F3FFFFD2EAFAFF6D7A82FF090A0BFF000000FF2323\n      23FF656565FF969696FFBFBFBFFFE1E1E1FFFAFAFAFFFFFFFFFFFFFFFFFFFFFF\n      FFFFFFFFFFFFDEDEDEFFB3B3B3FF868686FF575757FF212121FF000000FF0002\n      03FF475055FF8C9CA7FFD1E9F9FFDDF6FFFF2F3539FF1E2224FFCAE2F1FFD5EE\n      FEFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD5EEFFFFD7EFFFFFC0E6\n      FFFFAFDFFFFFB0E0FFFFB0E0FFFFB0E0FFFFB0E0FFFFB0E0FFFFB0E0FFFFB0E0\n      FFFFB0E0FFFFB0E0FFFFB0E0FFFFB0E0FFFFB0E0FFFFB7E9FFFF324048FF0101\n      01FE000000FF3F3F3FC000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      000000000000F4F4F40B404040BF000000FF000000FF000000FF000000FF4444\n      44FFFFFFFFFFF4F4F4FFF5F5F5FFF5F5F5FFF6F6F6FFA0A0A0FF000000FF0000\n      00FF000000FF000000FF000000FF9B9B9BFFFAFAFAFFFAFAFAFF787878FF0101\n      01FF000000FF000000FF474747FFEBEBEBFFF5F5F5FFF5F5F5FFF5F5F5FFF6F6\n      F6FFB9B9B9FF000000FF000000FF000000FF000000FF050505FAAEAEAE510000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      000000000000000000000000000000000000BCBCBB44191824EC03086BFF0505\n      25FF2E356FFF586670FF667580FF5E6D79FF565F64F4C8C8C837000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000E4E4E41B4244\n      48C9181D27FF1E2630FF293038FF353D45FF343C44FF101318FF0C0D12FF0405\n      09FF04060DFF6666679FF8F8F807000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000EFEFEF106565659A050505FA000000FF080A09FE536466FE8CA5A8FF8FA8\n      A9FE8AA4A5FF849EA1FF85A0A3FF89A2A5FF88A1A4FF88A1A4FF859FA2FF89A3\n      A5FF8EA7A9FF8CA5A8FF89A1A4FF88A1A4FF88A1A3FF86A0A2FF8CA5A7FF8CA5\n      A7FF859FA2FF819C9FFF849FA1FF87A1A4FF89A2A5FF8BA4A7FF8CA5A7FF859E\n      A2FF829C9FFF86A0A3FF8BA5A8FF74898BFF252D2EFF687B7DFF86A0A2FF8BA4\n      A6FF91A8AAFF8FA7A8FF8CA6A8FF89A2A4FF89A2A4FF89A3A4FF8DA6A8FF8DA6\n      A8FF859FA2FF88A1A4FF89A2A5FF89A3A6FF87A2A4FF85A0A3FF89A3A6FF8FA9\n      ABFF8EA8AAFF8DA7A9FF8AA3A6FF859FA2FF86A0A2FF88A1A4FF859FA2FF8AA2\n      A5FF8BA4A6FF8CA6A8FF859DA0FF333D3EFF010101FE020202FD6161619EF5F5\n      F50A000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      000000000000000000000000000000000000000000000000000000000000D0D0\n      D02F000000FF010101FE5E6970FFDBF5FFFFD5EEFEFFD5EEFEFFD7F1FFFFD5EE\n      FEFFD5EEFEFFD7F1FFFFBED4E3FF272C2FFF000000FF0B0B0AFFA5A5A5FFEEEE\n      EEFFFCFCFCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEFFFEFE\n      FEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8F8F8FFECECECFFD8D8D8FF8787\n      87FF292929FF000000FF15181AFF191D1FFF010101FF000000FF91A2ADFFD8F1\n      FFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD5EFFFFFD6EFFFFFD5EF\n      FFFFAFDFFFFFAFDFFFFFB0E0FFFFB0E0FFFFB0E0FFFFB0E0FFFFB0E0FFFFB0E0\n      FFFFB0E0FFFFB0E0FFFFB0E0FFFFB0E0FFFFAFDFFEFFB4E5FFFF7B9CB2FF0000\n      00FF000000FF000000FF00000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      000000000000B8B8B847080808F7000000FF000000FF000000FF000000FFC5C5\n      C5FFF6F6F6FFF5F5F5FFF5F5F5FFF5F5F5FFF6F6F6FFA0A0A0FF000000FF0000\n      00FF000000FF000000FF000000FF0B0B0BFFE9E9E9FFF8F8F8FFEDEDEDFF2929\n      29FF000000FF000000FF484848FFEBEBEBFFF5F5F5FFF5F5F5FFF5F5F5FFF4F4\n      F4FFEDEDEDFF3A3A3AFF000000FF000000FF010101FE000000FF515151AEF9F9\n      F906000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000F3F3F30C616161A3040403FF030332FE0304\n      37FF11144BFF535F6BFF566774FE63717FFF626466B1F2F2F20D000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000E0E0E01F3B3C\n      41CF171D25FF1B202AFF242D35FF2D373EFF232C34FF0E1011FF0E0E0EFF0606\n      06FF040404FF505051B6F1F1F10E000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      000000000000000000000000000000000000000000000000000000000000F4F4\n      F40B7272728D040404FB000000FF070808FE4D5B5CFF8BA3A5FF86A0A3FF839D\n      A0FF819B9EFF809B9EFF88A1A4FF90A9AAFF90A9ABFF8DA6A8FF8EA7A9FF8AA4\n      A6FF87A0A3FF8BA5A7FF8CA5A8FF88A2A4FF859FA2FF88A1A4FF869FA3FF829C\n      9FFF768E90FF627779FF5D7072FF73898BFF8AA3A6FF8DA6A9FF8EA7A9FF8EA7\n      A9FF8BA4A7FF87A0A3FF6B8184FF1E2323FF4A5859FF8FA9ACFF8CA5A8FF8EA8\n      A9FF8EA7A9FF89A2A4FF829C9EFF859FA2FF8AA3A6FF88A1A4FF88A1A4FF89A2\n      A5FF849FA1FF839DA0FF7F9799FF6A7E80FF546466FF4A585AFF475557FF5564\n      66FF677C7EFF7C9497FF89A2A4FF8DA6A9FF8AA3A6FF8BA3A7FF8BA4A6FF8FA8\n      AAFF91A9AAFF8DA6A8FF8DA6A8FF6C7F81FF0E1011FF000000FF101010EFB7B7\n      B748000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000008383\n      837C000000FF000000FFA6BAC6FFD7F0FFFFD6EFFFFFD9F2FFFF9FB2BEFFD8F1\n      FFFFD8F1FFFFB3C8D6FF15181AFF090808FF535353FFF1F1F1FFFFFFFFFFFEFE\n      FEFFFFFFFFFFFEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\n      FFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEFFFFFFFFFFFEFEFEFFFFFFFFFFFFFF\n      FFFFFFFFFFFFF2F2F2FF737373FF050505FF000000FF000000FF24282BFFDEF8\n      FFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD5EFFFFFD6EF\n      FFFFC2E6FFFFAEDFFFFFAFDFFFFFB0E0FFFFB0E0FFFFB0E0FFFFB0E0FFFFB0E0\n      FFFFB0E0FFFFB0E0FFFFB0E0FFFFB0E0FFFFB0E0FFFFB1E2FFFFA0CCE9FF0000\n      00FF010101FE000000FFDDDDDD22000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000F8F8F8076060609F000000FF000000FF000000FF000000FF484848FFEBEB\n      EBFFF4F4F4FFF5F5F5FFF4F4F4FFF6F6F6FFFFFFFFFFA0A0A0FF000000FF0000\n      00FF000000FF000000FF000000FF000000FF848484FFFEFEFEFFFCFCFCFFA7A7\n      A7FF000000FF000000FF3F3F3FFFF5F5F5FFFAFAFAFFF4F4F4FFF4F4F4FFF5F5\n      F5FFF5F5F5FF9B9B9BFF000000FF000000FF000000FF000000FF000000FFD8D8\n      D827000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000C4C4C43C060606FF040317FF060618FE0405\n      55FF171A28FF1C212DFF3D4A55FF3E454BFF96979871FCFCFC03000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000DFDFDF20373A\n      3BD111171BFF181E25FF2A333BFF2F363EFF1D2227FF0E1216FF0F1012FF0E0F\n      12FF0E0F11FF212224EAE1E1E11E000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000F0F0F00F6E6E\n      6E91020202FD000000FF070808FE4A5759FF88A1A3FF8FA7AAFF8BA5A7FF88A2\n      A4FF8CA5A7FF8DA6A8FF8AA3A6FF8BA3A6FF8BA4A6FF8CA6A8FF8DA5A8FF87A1\n      A3FF839EA0FF849DA0FF87A1A3FF8AA3A6FF8CA5A8FF8DA7A8FF6D8183FF3A46\n      48FF191E1FFF080909FF040404FF2B3234FF829B9EFF86A0A2FF849EA0FF859F\n      A2FF8AA4A6FF6F8487FF1F2425FF414C4EFF89A2A5FF88A1A4FF859FA2FF86A0\n      A2FF89A3A6FF8BA4A6FF89A3A5FF87A0A3FF87A0A3FF87A1A4FF86A0A3FF8BA5\n      A8FF7B9192FF414C4EFF141717FF010101FF000000FF000000FF000000FF0000\n      00FF020203FF161B1BFF424E4FFF788D8FFF8BA5A9FF89A3A5FF8DA5A8FF8AA3\n      A5FF87A1A4FF8AA3A7FF8DA7A9FF87A1A4FF404D4EFF000000FF000000FF4040\n      40BFF0F0F00F0000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000003E3E\n      3EC1000000FF0C0E0FFFC4DBE9FFD5EEFEFFD8F1FFFFBFD6E4FF070708FFD4ED\n      FDFF99ABB7FF08090AFF4A4949FFC4C4C4FFFFFFFFFFFFFFFFFFFEFEFEFFFFFF\n      FFFFFFFFFFFFFFFFFFFFFFFFFFFFF4F4F4FFE1E1E1FFD9D9D9FFD8D8D8FFDDDD\n      DDFFE7E7E7FFF5F5F5FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\n      FFFFFEFEFEFFFFFFFFFFFFFFFFFF1B1B1BFF000000FF000000FF000000FFDCF6\n      FFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EF\n      FFFFD1EDFFFFB1E0FFFFAFDFFFFFB0E0FFFFB0E0FFFFB0E0FFFFB0E0FFFFB0E0\n      FFFFB0E0FFFFB0E0FFFFB0E0FFFFB0E0FFFFB0E0FFFFB1E1FFFFA2CFECFF0000\n      00FF010101FE000000FFDDDDDD22000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000E1E1E11E000000FF000000FF000000FF000000FF000000FFA2A2A2FFF5F5\n      F5FFF4F4F4FFF5F5F5FFF6F6F6FFB9B9B9FF191919FF000000FF000000FF0000\n      00FF000000FF000000FF000000FF000000FF515151FFFFFFFFFFF6F6F6FFF2F2\n      F2FF000000FF000000FF000000FF000000FF6E6E6EFFEFEFEFFFF6F6F6FFF5F5\n      F5FFF5F5F5FFD6D6D6FF2B2B2BFF000000FF000000FF010101FE000000FF5252\n      52AD000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      00000000000000000000FAFAFA057879798D010103FF05060FFE0C0D08FF0304\n      44FF0B0E5CFF070F8DFF0C115FFF22283DF4C2C3C34000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000E2E2E21D3C3D\n      41CF14191FFF191F27FF262E36FF2D3338FF2E3D59FF24292FFF0D0F12FF1013\n      19FF101218FF0E0F13FFC9C9C936000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      00000000000000000000000000000000000000000000F7F7F708797979860A0A\n      0AF5000000FF030304FE485656FF819A9CFF819C9FFF839DA0FF87A0A3FF88A2\n      A4FF8BA5A7FF8DA6A9FF8CA6A8FF8CA5A7FF88A2A4FF88A1A4FF87A1A4FF85A0\n      A2FF87A0A3FF8DA7A8FF8EA7A9FF8AA4A6FF859FA3FF4C5C5DFF0F1212FF0101\n      01FF000000FF000000FF000000FF384244FF89A2A5FF88A2A5FF849EA1FF839E\n      A0FF738A8DFF1A2020FF272E2FFF829B9DFF90A9AAFF8EA7A9FF87A0A3FF86A1\n      A4FF87A1A4FF8AA2A4FF8AA3A5FF859EA1FF849EA1FF89A2A5FF87A2A4FF5D70\n      72FF0D1010FF000000FF000000FF000000FF000000FF000000FF000000FF0000\n      00FF000000FF000000FF000000FF0E1212FF596A6CFF8AA4A7FF89A2A5FF8BA3\n      A6FF8BA5A7FF8CA5A7FF8AA4A7FF8BA5A7FF7C9394FF191E1EFE000000FF0000\n      00FF8D8D8D720000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000001D1D\n      1DE2000000FF2F3438FFCAE2F1FFD5EEFEFFDFF9FFFF5C676EFF000000FF1619\n      1CFF0E1010FFB0B0B0FFFAFAFAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\n      FFFFBEBEBEFF6C6C6CFF232222FF100F0FFF0C0B0BFF0A0909FF0A0A09FF0D0C\n      0CFF10100FFF151515FF1A1A1AFF363636FF636363FF959595FFC6C6C6FFF9F9\n      F9FFFFFFFFFFFFFFFFFF818181FF030303FF000000FF000000FF50595FFFDCF6\n      FFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD5EE\n      FFFFD4EEFFFFBCE4FFFFAFDFFFFFB0E0FFFFB0E0FFFFB0E0FFFFB0E0FFFFB0E0\n      FFFFB0E0FFFFB0E0FFFFB0E0FFFFB0E0FFFFB0E0FFFFB3E4FFFF81A5BCFF0000\n      00FF000000FF000000FF00000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      00006262629D000000FF010101FE000000FF000000FF2F2F2FFFDDDDDDFFF5F5\n      F5FFF5F5F5FFF6F6F6FF9A9A9AFF000000FF000000FF000000FF000000FF0000\n      00FF000000FF000000FF000000FF000000FF616161FFFFFFFFFFF5F5F5FFFFFF\n      FFFF000000FF000000FF000000FF000000FF000000FF4D4D4DFFE9E9E9FFF5F5\n      F5FFF5F5F5FFFDFDFDFF6F6F6FFF010101FF000000FF000000FF000000FF0000\n      00FFDDDDDD220000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      000000000000FEFEFE01DBDBDB242A2929DD020202FF0A0A0BFF0E0F13FF1C21\n      22FF3C4144FF1F2450FF161E5BFF474A49D3DBDBDB2400000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000EDEDED125457\n      57B1141A1DFF13181EFF141C23FF263037FF212C42FF262D33FF111418FF0C0C\n      0CFF0E0F10FF101115FFC2C2C23D000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      000000000000000000000000000000000000FBFBFB048B8B8B74070707F80000\n      00FF050606FE404C4DFF859EA0FF8AA3A5FF88A2A4FF89A3A5FF8CA5A7FF88A2\n      A5FF839DA0FF859FA2FF87A0A3FF88A1A4FF88A2A5FF86A0A3FF859FA2FF8CA5\n      A7FF8FA8A9FF8AA4A7FF86A0A3FF799293FF394445FF000000FF000000FF0000\n      00FF000000FF000000FF242A2BFF7D9395FF8CA5A8FF859FA2FF859FA2FF8097\n      9AFF1E2424FF090C0CFF6E8284FF89A3A6FF859FA1FF859FA2FF8CA6A9FF90A9\n      AAFF859DA1FF829C9FFF8BA4A7FF8DA7A9FF86A1A4FF869FA2FF5C6D6EFF0406\n      06FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000\n      00FF000000FF000000FF000000FF000000FF010101FF495859FF829A9EFF8CA6\n      A8FF8BA5A8FF87A0A3FF859FA3FF8EA7A9FF94ACAEFF5B6B6DFF030505FE0000\n      00FF242424DBD1D1D12E00000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000E5E5E51A1515\n      15EA000000FF4C565BFFD1EAF9FFD6EFFFFFD0E8F7FF131618FF000000FF4848\n      48FFF7F7F7FFFFFFFFFFFFFFFFFFF9F9F9FFE9E9E9FFB7B6B6FF535454FF080A\n      0AFF0A0C0EFF343A3EFF69757DFF8898A2FF93A4AFFF92A3ADFF8898A2FF7887\n      8FFF647079FF4D565BFF32383CFF181B1DFF101214FF080A0BFF000102FF0000\n      00FF080807FF000000FF000000FF000000FF000000FF3F464BFFD2EAFAFFD5EE\n      FEFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EF\n      FFFFD6EFFFFFC6E9FFFFB0E0FFFFB0E0FFFFB0E0FFFFB0E0FFFFB0E0FFFFB0E0\n      FFFFB0E0FFFFB0E0FFFFB0E0FFFFB0E0FFFFB0E0FFFFB6E8FFFF3D4E58FF0101\n      01FE000000FF444444BB00000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      000000000000000000000000000000000000000000000000000000000000E1E1\n      E11E000000FF000000FF000000FF000000FF030303FF7A7A7AFFFCFCFCFFF4F4\n      F4FFF5F5F5FFAFAFAFFF0C0C0CFF000000FF000000FF000000FF000000FF0000\n      00FF000000FF000000FF000000FF000000FF8F8F8FFFFDFDFDFFF6F6F6FFEBEB\n      EBFF000000FF000000FF000000FF000000FF000000FF000000FF5D5D5DFFF4F4\n      F4FFF4F4F4FFF8F8F8FFD5D5D5FF0B0B0BFF000000FF000000FF010101FE0000\n      00FF4F4F4FB00000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      000000000000FBFBFB049797976C060606FA040404FE070708FF080809FF272C\n      32FF474D55FF383D48FF181C2FFF4D4E58BAEAEAEA1500000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000F1F1F10E5E5F\n      60A813191EFF1B2229FF151B29FF303844FF2D3643FF2F383FFF1F262EFF1519\n      1EFF0F1013FF0E1015FFB5B5B54A000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000FCFCFC039191916E0B0B0BF4000000FF0101\n      01FE3A4547FF829A9CFF8CA6A8FF8AA3A5FF8BA4A7FF87A1A3FF88A2A4FF8CA5\n      A7FF8AA3A6FF87A1A3FF849EA1FF849FA2FF8BA5A7FF8CA5A8FF89A2A5FF87A0\n      A3FF88A1A4FF859FA2FF819A9CFF3C4748FF010101FF000000FF000000FF0000\n      00FF000000FF2B3334FF7E9495FF92ABACFF87A0A3FF86A1A3FF839B9EFF2F38\n      39FF000000FF536163FF8EA7AAFF88A1A4FF8BA4A7FF8BA4A6FF8AA3A6FF89A2\n      A5FF86A0A3FF88A2A5FF8BA4A6FF859FA2FF88A3A5FF6D8284FF0A0C0CFF0000\n      00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000\n      00FF000000FF000000FF000000FF000000FF000000FF000000FF495858FF89A3\n      A7FF8BA4A7FF8DA6A8FF8DA5A7FF89A2A4FF86A0A2FF80999BFF2C3435FF0101\n      01FE020202FD6E6E6E91FAFAFA05000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000CECECE311010\n      10EF000000FF67737AFFD7F0FFFFD7F1FFFF90A0ABFF050606FF080808FFBCBC\n      BCFFFFFFFFFFEEEEEEFF9F9F9EFF504F4EFF1E1E1FFF31393DFF6D7B84FFA4B8\n      C4FFD1EAFAFFE1FBFFFFDEF7FFFFDCF5FFFFDBF4FFFFDBF4FFFFDBF5FFFFDDF6\n      FFFFDEF8FFFFDFFAFFFFE1FCFFFFE0FAFFFFCEE6F5FFB9CFDDFFA3B6C3FF8D9D\n      A8FF586269FF000000FF000000FF000000FF32383CFFC7DEEDFFD7F0FFFFD6EF\n      FFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EF\n      FFFFD6EFFFFFD0ECFFFFB2E0FFFFB0E0FFFFB0E0FFFFB0E0FFFFB0E0FFFFB0E0\n      FFFFB0E0FFFFB0E0FFFFB0E0FFFFB0E0FFFFB1E1FFFF8DB3CCFF07090BFF0000\n      00FF050505FAC8C8C83700000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000005C5C\n      5CA3000000FF010101FE000000FF000000FF0C0C0CFFDEDEDEFFF7F7F7FFF5F5\n      F5FFE1E1E1FF151515FF000000FF000000FF000000FF000000FF000000FF0000\n      00FF000000FF000000FF000000FF000000FFC4C4C4FFF9F9F9FFF9F9F9FFC9C9\n      C9FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF8E8E\n      8EFFF9F9F9FFF5F5F5FFFFFFFFFF555555FF000000FF000000FF000000FF0000\n      00FF101010EFD6D6D62900000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      000000000000EAEAEA15525252B2040404FF050505FF090A0BFF0E0E11FF0B0F\n      14FF141831FF333944FF343B46FF696B6DA1F2F2F20D00000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000F2F2F20D5E60\n      62A8151A1FFF131B29FF181C20FF181E34FF373C43FF464E59FF232B34FF1B1F\n      28FF141A20FF0F1319FF8C8C8C78FEFEFE010000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      00000000000000000000FDFDFD029595956A101010EF000000FF010101FE3C47\n      48FE80999CFF8BA4A7FF8CA6A8FF8DA6A8FF8EA7A8FF8EA6A9FF8BA5A7FF86A1\n      A3FF85A0A2FF8AA3A6FF88A2A5FF839DA0FF829C9FFF89A2A5FF8DA7A9FF8AA3\n      A7FF8BA4A7FF90A9ABFF6E8284FF0A0D0DFF000000FF000000FF000000FF0A0C\n      0CFF495758FF799294FF849DA0FF8AA4A6FF8FA8AAFF8FA8AAFF2D3536FF0000\n      00FF374042FF849EA0FF849EA1FF87A1A4FF89A3A5FF8AA4A7FF8EA7AAFF8CA5\n      A7FF8BA4A7FF8DA6A8FF89A2A5FF8AA4A6FF879FA1FF161B1BFF000000FF0000\n      00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000\n      00FF000000FF040606FF313B3CFF0F1213FF000000FF000000FF010101FF5667\n      69FF89A4A6FF8AA2A5FF88A1A4FF849EA1FF87A1A3FF8DA7A8FF6B7D7FFF0C0E\n      0EFE000000FF161616E9C4C4C43B000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000B6B6B6490A0A\n      0AF5020202FF7F8E97FFD8F1FFFFD3ECFCFF576168FF000000FF010101FF4A4A\n      4AFF5D5D5DFF0C0B0AFF1A1C1EFF7A8891FFC0D7E5FFCEE6F6FFD7F0FFFFD7F0\n      FFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EF\n      FFFFD6EFFFFFD6EFFFFFD5EEFEFFD6EFFFFFD6EFFFFFD6EFFFFFD7F0FFFFD8F1\n      FFFFDBF4FFFF2D3235FF000000FF272C2FFFCFE7F7FFD7F0FFFFD5EEFEFFD6EF\n      FFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EF\n      FFFFD6EFFFFFD7EFFFFFB7E3FFFFAFDFFFFFB0E0FFFFB0E0FFFFAFDFFEFFB0E0\n      FFFFB3E4FFFFAFDFFEFFAFDFFEFFB0E0FFFFA8D5F3FF2F3B44FF000000FF0000\n      00FF000000FFC9C9C93600000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000DEDEDE210D0D\n      0DF2010101FE000000FF000000FF000000FF636363FFFFFFFFFFF4F4F4FFF9F9\n      F9FF888888FF000000FF000000FF000000FF000000FF000000FF000000FF0000\n      00FF000000FF000000FF000000FF000000FFFBFBFBFFF5F5F5FFFBFBFBFFA8A8\n      A8FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0A0A\n      0AFFFFFFFFFFF5F5F5FFF7F7F7FFDDDDDDFF000000FF000000FF000000FF0000\n      00FF020202FD6D6D6D9200000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      000000000000BEBEBE42121212F2040404FF080807FF111315FF11161BFF353D\n      46FF2E333BFF373C46FF272C34FE6F707198F5F5F50A00000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000F0F0F00F5E5F\n      61A9161A20FF0D143BFF13182EFF080A15FF181F2BFF252B33FF13171DFF0F10\n      13FF101317FF0D0E0FFF555556B1F7F7F7080000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      000000000000FEFEFE01A9A9A956111111EE000000FF020303FE384242FF849C\n      9EFF8BA4A6FF88A1A4FF87A1A4FF8CA5A7FF8CA4A6FF859EA1FF819B9EFF839D\n      A0FF88A1A3FF8BA4A6FF8EA7A8FF8BA4A6FF86A0A2FF87A0A2FF8AA3A5FF8AA3\n      A5FF859EA1FF859EA1FF697F80FF171A1AFF0B0D0EFF191E1EFF3A4546FF7187\n      89FF8EA8AAFF8CA6A8FF849FA2FF839EA0FF859DA0FF384243FF000000FF1F25\n      25FF7E9598FF87A0A3FF8AA3A5FF8BA4A6FF819C9FFF839DA0FF88A0A3FF86A0\n      A2FF8BA3A6FF8CA4A6FF87A0A2FF8AA4A7FF414C4FFF000000FF000000FF090A\n      0AFF0D1011FF000000FF000000FF000000FF000000FF000000FF000000FF0000\n      00FF000000FF101313FF7B9395FF738A8CFF222A2BFF000000FF000000FF0C0F\n      0FFF6C8286FF819C9FFF809A9EFF839DA0FF86A0A2FF8AA3A6FF859FA1FF3640\n      42FF000000FF000000FF4D4D4DB2F3F3F30C0000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000A2A2A25D0505\n      05FA070708FF94A5B0FFD7F0FFFFD5EEFEFF68757DFF000000FF000000FF0000\n      00FF1F2426FF92A3ADFFDDF7FFFFDAF3FFFFD5EEFEFFD5EEFEFFD6EFFFFFD6EF\n      FFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EF\n      FFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EF\n      FFFFE0FAFFFF0E1010FF202427FFCAE1F0FFD5EEFEFFD5EEFEFFD6EFFFFFD6EF\n      FFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EF\n      FFFFD6EFFFFFD7EFFFFFC4E8FFFFAFDFFFFFB0E0FFFFB0E0FFFFB0E0FFFFA9D6\n      F4FF648091FFACDBF9FFB0E0FFFFB0E0FFFFA6D4F1FF313F47FF0C0F11FF0101\n      01FE000000FF030303FCE8E8E817000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      00000000000000000000000000000000000000000000000000007575758A0303\n      03FC000000FF000000FF000000FF000000FFDFDFDFFFF7F7F7FFF5F5F5FFFAFA\n      FAFF767676FF000000FF000000FF000000FF000000FF000000FF000000FF0000\n      00FF000000FF000000FF000000FF4C4C4CFFFCFCFCFFF4F4F4FFFEFEFEFF8888\n      88FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000\n      00FFFFFFFFFFF5F5F5FFF4F4F4FFFFFFFFFF545454FF000000FF000000FF0000\n      00FF000000FF272727D8DDDDDD22000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000FAFAFA057575748E030303FF080707FE080909FF0B0C0DFF181C21FF3239\n      42FF464D57FF282F39FF252C34FE77797B94F6F6F60900000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000F0F0F00F5B5C\n      5DAC11172AFF14171DFF131625FF0D153FFF101844FF0E1230FF0D0E1EFF0C0D\n      1DFF090904FF08080CFF323237D3E3E3E31C0000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      000000000000A4A4A45B181818E7000000FF010101FE323C3CFF7E9597FF8CA6\n      A8FF8BA5A7FF8AA3A5FF87A1A3FF859FA1FF869FA3FF88A2A5FF88A2A5FF89A2\n      A5FF8AA2A6FF89A3A6FF8FA7A9FF91A9ABFF8FA7A9FF89A2A5FF859FA1FF8AA3\n      A6FF8CA5A6FF8DA5A7FF8EA5A7FF778C8EFF6C8082FF788F92FF849EA0FF87A1\n      A3FF89A2A5FF8DA7A8FF91A9ABFF8BA4A6FF3C4749FF000000FF060707FF5C6E\n      70FF849FA1FF88A2A5FF89A3A5FF89A2A5FF8BA5A7FF8FA8AAFF8AA3A6FF859F\n      A1FF839DA0FF819C9FFF849FA2FF758B8DFF0C0F0FFF000000FF0C0E0EFF6071\n      73FF6C8082FF111516FF000000FF000000FF000000FF000000FF000000FF0000\n      00FF000000FF1C2223FF849EA0FF8AA3A6FF748B8EFF1E2425FF000000FF0000\n      00FF343E3FFF829B9EFF87A0A3FF8DA6A9FF8EA7A9FF89A3A5FF89A2A5FF7389\n      8CFF141818FE000000FF050505FA979797680000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      00000000000000000000000000000000000000000000000000009494946B0202\n      02FD0A0B0CFFA3B6C2FFD7F0FFFFD6EFFFFFC8E0EEFF505A60FF000000FF0F10\n      11FFC7DEEDFFDBF5FFFFD6EFFFFFD5EEFEFFD6EFFFFFD6EFFFFFD6EFFFFFD6EF\n      FFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EF\n      FFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD7F0\n      FFFFCDE6F5FF090A0AFFB3C9D6FFD7F1FFFFD5EEFEFFD6EFFFFFD6EFFFFFD6EF\n      FFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EF\n      FFFFD6EFFFFFD6EFFFFFD1EDFFFFADDFFFFFB0E0FFFFB0E0FFFFB1E1FFFF80A4\n      BAFF000000FF7FA2B9FFB3E4FFFFB5E7FFFFB0E1FFFFB2E3FFFF7B9CB2FF0000\n      00FF010101FE000000FF353535CAF9F9F9060000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      00000000000000000000000000000000000000000000E0E0E01F2A2A2AD50000\n      00FF000000FF000000FF000000FF626262FFFDFDFDFFF4F4F4FFF5F5F5FFF7F7\n      F7FFA9A9A9FF000000FF000000FF000000FF000000FF000000FF000000FF0000\n      00FF000000FF000000FF000000FFB6B6B6FFF7F7F7FFF5F5F5FFFFFFFFFF7171\n      71FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF3636\n      36FFFDFDFDFFF5F5F5FFF5F5F5FFF5F5F5FFCECECEFF000000FF000000FF0000\n      00FF000000FF000000FF9A9A9A65000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000EBEBEB14333334D2050505FF080808FE0A0A0BFF080807FF080808FF1214\n      18FF3C424CFF343B44FF1F262DFD7E7F8189F9F9F90600000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000EDEDED125354\n      54B411182DFF0C1132FF111428FF060B4CFF0C0F2FFF0A1051FF0D0D17FF0A0C\n      2AFF040F59FF06071EFF0F0F19F3B0B0B053FDFDFD0200000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000B0B0B04F181818E7000000FF000000FF30393AFE81999AFF8DA6A9FF89A3\n      A6FF86A0A3FF859EA1FF88A1A4FF8AA3A6FF89A3A6FF89A1A4FF89A2A5FF8BA4\n      A7FF8BA4A7FF8DA6A8FF8CA5A8FF8AA3A6FF89A3A5FF8AA3A6FF8AA4A6FF8EA8\n      AAFF8EA7AAFF8EA5A8FF8FA8AAFF8EA7A9FF8DA6A8FF89A2A5FF87A0A3FF88A1\n      A4FF8AA2A5FF8BA4A7FF89A4A6FF475556FF010101FF000000FF3D4949FF88A2\n      A5FF89A1A4FF89A2A5FF89A2A4FF86A0A3FF87A0A3FF88A2A4FF89A2A5FF8CA5\n      A8FF8CA5A8FF88A1A4FF859FA2FF4A5859FF010202FF010202FF465254FF8EA6\n      A8FF8FA7A9FF4F5F60FF020303FF000000FF000000FF000000FF000000FF0000\n      00FF000000FF434F50FF8DA6A9FF8DA6A8FF8CA4A8FF697E80FF0E1111FF0000\n      00FF050606FF758C8EFF8EA8AAFF8FA8A9FF8BA5A7FF87A1A3FF8BA4A7FF90A9\n      ABFF546364FF030303FF000000FF262626D9D9D9D92600000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      00000000000000000000000000000000000000000000000000008D8D8D720101\n      01FE0C0E0FFFACC0CDFFD7F0FFFFD5EEFEFFD7F0FFFFD2EBFBFF808E98FF0303\n      03FFC0D7E5FFD5EEFEFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EF\n      FFFFD6EFFFFFD6EFFFFFD5EEFEFFD6EFFFFFD6EFFFFFD5EEFEFFD6EFFFFFD6EF\n      FFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EF\n      FFFFD3ECFCFFC1D8E6FFD7F0FFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EF\n      FFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EF\n      FFFFD6EFFFFFD6EFFFFFD7EFFFFFB3E1FFFFAFDFFFFFAFDFFEFFAFDFFEFF4D63\n      71FF000000FFA7D4F1FFB8EBFFFF627D8EFFAEDDFBFFBAEDFFFF3A4954FF1014\n      17FF000000FF010101FE020202FD9191916E0000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      00000000000000000000000000000000000000000000A1A1A15E000000FF0000\n      00FF000000FF000000FF000000FFD8D8D8FFF5F5F5FFF5F5F5FFF5F5F5FFF5F5\n      F5FFDEDEDEFF000000FF000000FF000000FF000000FF1D1D1DFF1D1D1DFF0000\n      00FF000000FF000000FF313131FFE8E8E8FFF5F5F5FFF5F5F5FFFFFFFFFF6C6C\n      6CFF000000FF000000FF323232FF060606FF000000FF000000FF000000FF7373\n      73FFFAFAFAFFF5F5F5FFF5F5F5FFF4F4F4FFEDEDEDFF535353FF000000FF0000\n      00FF010101FE000000FF313131CEF4F4F40B0000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000CECECE310E0E0EF9050505FF0A0A0AFF0E0F13FF0F0F10FF111317FF3E43\n      4DFF2F343EFF272D35FF242B31F994949571FAFAFA0500000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000F0F0F00F5D5E\n      61AB12171DFF14171BFF121619FF121515FF0A0C25FF0A0D2FFF0C0C0FFF0707\n      10FF060627FF09090AFF0A0A0CFF606060A3F5F5F50A00000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      000000000000000000000000000000000000000000000000000000000000BFBF\n      BF40252525DA000000FF010101FE2B3234FF799093FF8BA4A6FF8AA4A6FF88A1\n      A4FF87A1A3FF8CA5A8FF8BA5A7FF8AA4A6FF88A1A3FF87A1A4FF8BA4A7FF8EA8\n      AAFF8CA5A7FF87A0A4FF849DA1FF86A0A3FF8CA5A7FF8EA6A8FF8EA7A9FF88A1\n      A4FF86A0A3FF85A0A2FF829DA1FF859FA2FF88A2A5FF88A3A6FF8CA6A9FF8BA5\n      A7FF82999CFF6E8486FF303A3BFF000001FF000000FF23292AFF8AA4A7FF8BA4\n      A7FF8AA3A6FF8BA4A6FF8FA7A9FF8DA6A8FF89A2A5FF839DA0FF829C9FFF88A1\n      A4FF8DA5A7FF8EA7A9FF879FA1FF282F30FF000000FF111515FF788F92FF89A2\n      A4FF8CA5A7FF819A9CFF1C2122FF000000FF000000FF000000FF000000FF0000\n      00FF020203FF687C7DFF8EA8AAFF8EA7A9FF8DA6A9FF8DA7A9FF526264FF0000\n      00FF000000FF3E494AFF8FA9ABFF8BA4A7FF849EA0FF819B9FFF87A0A3FF8AA3\n      A6FF82999BFF283030FF010101FE030303FC7D7D7D82F9F9F906000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      00000000000000000000000000000000000000000000000000008B8B8B740000\n      00FF0E0F10FFB1C6D3FFD7F0FFFFD6EFFFFFD6EFFFFFD5EEFEFFD9F2FFFF91A2\n      ADFFC5DBEAFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EF\n      FFFFD6EFFFFFD6EFFFFFD2EAFAFFBDD4E2FFBBD1DFFFC9E0EFFFD6F0FFFFD6EF\n      FFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EF\n      FFFFD5EEFEFFD6EFFFFFD5EEFEFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EF\n      FFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EF\n      FFFFD6EFFFFFD6EFFFFFD7EFFFFFBEE5FFFFAEDFFFFFB1E1FFFF88ADC5FF0000\n      00FF516675FFB6E8FFFF8CB3CBFF000101FFB3E3FFFF9CC7E3FF050708FF6E8D\n      A1FF20282EFF000000FF000000FF1D1D1DE2E7E7E71800000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      000000000000000000000000000000000000F3F3F30C373737C8000000FF0101\n      01FE000000FF000000FF5C5C5CFFEEEEEEFFF4F4F4FFF5F5F5FFF5F5F5FFF5F5\n      F5FFE6E6E6FF1C1C1CFF000000FF000000FF000000FF545454FF444444FF0000\n      00FF000000FF010101FFA7A7A7FFF5F5F5FFF5F5F5FFF5F5F5FFFEFEFEFF8787\n      87FF000000FF0C0C0CFF868686FF0D0D0DFF000000FF000000FF000000FFAAAA\n      AAFFF7F7F7FFF5F5F5FFF5F5F5FFF5F5F5FFF6F6F6FFAAAAAAFF010101FF0000\n      00FF000000FF000000FF000000FFBDBDBD420000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      00009D9D9D66050505FF030202FF0E1014FF0E1221FF21272BFF2E333AFF2D33\n      3BFF2E363EFF2A3039FF23282FF89C9C9D69FCFCFC0300000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000F0F0F00F5A5B\n      5DAC0E1013FF101116FF111419FF181D25FF161B20FF0D1018FF0B0C17FF0809\n      15FF0D0D0DFF0C0C0EFF12151AFF525353B5ECECEC1300000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000C5C5C53A2323\n      23DC000000FF000000FF242A2CFF7A8F91FF8AA4A7FF829C9EFF829C9FFF849E\n      A1FF849FA1FF86A0A3FF88A2A4FF8AA4A6FF8BA4A7FF8CA5A7FF8EA7AAFF8FA9\n      ABFF8CA6A8FF859FA2FF839DA1FF839EA1FF85A0A4FF89A5A7FF8AA6A9FF8FAA\n      ADFF8EABADFF93AFB2FF93AFB3FF8AA4A7FF81989BFF74888AFF607172FF3F4A\n      4CFF1B2021FF060707FF000000FF000000FF040505FF6D8183FF8BA3A6FF8AA3\n      A5FF89A2A5FF87A0A3FF8AA3A6FF8DA6A8FF8BA5A7FF8CA5A7FF8DA6A8FF89A2\n      A4FF87A0A3FF89A3A5FF7D9497FF0D100FFF000000FF323D3EFF86A0A4FF7F9A\n      9EFF849EA1FF8FA8ABFF6A7D7FFF0B0E0EFF000000FF000000FF000000FF0000\n      00FF101515FF81999CFF89A2A5FF859EA2FF869FA2FF8DA7A8FF839B9DFF191D\n      1EFF000000FF040505FF71888AFF859FA2FF849EA1FF8BA5A7FF8DA6A9FF89A2\n      A5FF8AA4A6FF627576FF080A0AFF000000FF1B1B1BE4C4C4C43B000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      00000000000000000000000000000000000000000000000000008F8F8F700101\n      01FE0E1011FFB3C8D5FFD6F0FFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFDBF4\n      FFFFD7F0FFFFD5EEFEFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EF\n      FFFFD5EEFEFFDDF7FFFF68747BFF000000FF000000FF485056FFE0FAFFFFD6EF\n      FFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EF\n      FFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EF\n      FFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EF\n      FFFFD6EFFFFFD6EFFFFFD6EFFFFFC8E8FFFFAEDFFFFFB2E2FFFF7DA0B6FF495D\n      6AFFABDAF8FFAEDDFCFF3C4D58FF34434CFFB7E9FFFF617B8CFF050708FFA1CD\n      EAFF090C0DFF000000FF010101FE000000FF6A6A6A9500000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      000000000000000000000000000000000000BCBCBC43000000FF000000FF0000\n      00FF000000FF060606FFAFAFAFFFF6F6F6FFF5F5F5FFF5F5F5FFF5F5F5FFF5F5\n      F5FFEAEAEAFF3E3E3EFF000000FF000000FF070707FFA8A8A8FF424242FF0000\n      00FF000000FF686868FFF0F0F0FFF5F5F5FFF5F5F5FFF5F5F5FFF9F9F9FFC2C2\n      C2FF000000FF0D0D0DFFBFBFBFFF2B2B2BFF000000FF000000FF000000FFD4D4\n      D4FFF5F5F5FFF5F5F5FFF5F5F5FFF5F5F5FFF5F5F5FFE3E3E3FF383838FF0000\n      00FF000000FF010101FE000000FF333333CC0000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      000000000000000000000000000000000000000000000000000000000000FCFC\n      FC035E5E5FA6030303FF0B0B0DFE11151BFF313841FF525B66FF78838FFF373B\n      43FF1D242AFF1F282FFF1A2026FA98999971FCFCFC0300000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000F1F1F10E6061\n      62A6101519FF14181EFF191D25FF1A1F28FF1C2029FF191D25FF13161BFF0B0B\n      0CFF0D0E10FF111418FF11161AFF454749C3E6E6E61900000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      00000000000000000000000000000000000000000000EEEEEE11434343BC0000\n      00FF000000FF212829FE728A8CFF89A3A5FF8FA8AAFF90A9ABFF8DA7A9FF8CA7\n      A9FF90A9ACFF8BA5A8FF8FA9ACFF90AAADFF91ABAEFF92ADAFFF91ACAFFF91AC\n      AFFF8FABAEFF95B0B1FF99B4B7FF96B1B4FF8DA8ABFF859C9DFF798D8EFF6679\n      7AFF4F5F61FF3B4747FF2E3637FF1D2323FF111414FF080A0AFF010202FF0000\n      00FF000000FF000000FF000000FF000000FF111415FF789093FF86A0A2FF8BA4\n      A7FF8AA3A5FF839EA0FF7E999CFF839EA0FF89A2A5FF87A0A3FF859EA1FF87A0\n      A3FF88A1A3FF86A1A2FF687C7EFF010101FF000000FF5E7275FF88A2A5FF8AA3\n      A5FF8BA4A7FF89A2A5FF8BA6A8FF4F5C5DFF000000FF000000FF000000FF0000\n      00FF313B3CFF91AAACFF8CA5A7FF8AA3A5FF8BA4A6FF88A2A5FF89A3A6FF5767\n      69FF000000FF000000FF455254FF89A4A7FF85A0A2FF88A1A5FF8AA3A6FF8BA5\n      A7FF87A0A3FF859EA1FF353E3FFF000000FF000000FF515151AEFAFAFA050000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000999999660303\n      03FC0D0F10FFB0C5D2FFD7F0FFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EF\n      FFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EF\n      FFFFD7F1FFFFC6DDECFF000000FF000000FF000000FF8A99A3FFDBF5FFFFD6EF\n      FFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EF\n      FFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EF\n      FFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EF\n      FFFFD6EFFFFFD6EFFFFFD6EFFFFFD0ECFFFFADDFFFFFAFDFFEFFAFDFFEFFADDC\n      FBFFB2E3FFFF87ACC4FF000000FF8DB3CCFFA8D5F3FF1F282DFF4B606DFF7B9D\n      B2FF1E262CFF090B0DFF010101FE000000FF000000FFCFCFCF30000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000002E2E2ED1000000FF010101FE0000\n      00FF000000FF3D3D3DFFE9E9E9FFF5F5F5FFF5F5F5FFF5F5F5FFF5F5F5FFF5F5\n      F5FFEDEDEDFF575757FF000000FF000000FF4F4F4FFFE4E4E4FF2D2D2DFF0000\n      00FF7D7D7DFFE9E9E9FFF7F7F7FFF4F4F4FFF5F5F5FFF5F5F5FFF5F5F5FFF8F8\n      F8FF4E4E4EFF000000FFB5B5B5FFB3B3B3FF000000FF000000FF000000FFE3E3\n      E3FFF4F4F4FFF5F5F5FFF5F5F5FFF5F5F5FFF5F5F5FFFCFCFCFF848484FF0404\n      04FF000000FF000000FF010101FE000000FFBABABA4500000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      000000000000000000000000000000000000000000000000000000000000F4F4\n      F40B5E5E5FAB040407FF090A21FF11151EFF3E4659FF19276CFF071767FF424A\n      67FF23282DFF22292FFF2F353EF99798996DFCFCFC0300000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000EBEBEB145151\n      58B50C0C11FF0E0E12FF11151CFF1A1F27FF1C222BFF151920FF0E1012FF0606\n      06FF0E1013FF0F1218FF111419FF343739D5DFDFDF2100000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      00000000000000000000000000000000000000000000AAAAAA550C0C0CF30000\n      00FF242A2CFF7B9396FF8BA7ABFF8BA7A9FF8EA8ABFF93ADB0FF95AFB2FF95B0\n      B3FF98B4B6FF9CB7BAFF97B3B6FF93B1B4FF9BB8BAFFA5C1C4FFA0BDC0FF9EBC\n      BFFF9CB8BCFF8EA8ABFF6F8384FF566667FF364142FF202728FF191E1FFF181C\n      1DFF1C2020FF1E2424FF1F2627FF252B2DFF2D3637FF343F40FF374243FF313A\n      3BFF2B3435FF1B2021FF0C0F10FF010101FF040606FF697E80FF8AA4A7FF8CA7\n      A9FF8CA5A7FF89A1A4FF88A0A4FF88A1A4FF86A0A2FF849EA1FF859FA1FF87A0\n      A3FF87A1A4FF8AA3A5FF536365FF000000FF000000FF778C8EFF8FA8AAFF92AA\n      ACFF92A9ABFF8BA4A5FF86A0A3FF7F9799FF212727FF000000FF000000FF0101\n      01FF607274FF85A0A3FF88A1A4FF8DA6A8FF8BA4A6FF869FA2FF86A0A3FF7187\n      8AFF0A0D0DFF000000FF1A1F1FFF8AA4A6FF8FA9AAFF89A2A5FF829C9FFF839D\n      A0FF869FA2FF86A1A4FF6E8488FF131617FE000000FF000000FF9C9C9C630000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000A8A8A8570707\n      07F80C0D0EFFA9BDCAFFD7F0FFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EF\n      FFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EF\n      FFFFDEF8FFFF5D686FFF000000FF000000FF16191AFFE0FBFFFFD5EEFEFFD6EF\n      FFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EF\n      FFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EF\n      FFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EF\n      FFFFD6EFFFFFD6EFFFFFD6EFFFFFD2EDFFFFB2E0FFFFAFDFFFFFB0E0FFFFB1E2\n      FFFF93BAD5FF000000FF3C4D57FFADDCFBFF81A5BCFF000000FF9CC7E3FF3543\n      4DFF536A79FF0F1316FF020708FF000000FF000000FF2E2E2ED1000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000B8B8B847000000FF000000FF000000FF0000\n      00FF050505FF8E8E8EFFFBFBFBFFF5F5F5FFF5F5F5FFF5F5F5FFF5F5F5FFF5F5\n      F5FFEEEEEEFF5E5E5EFF000000FF373737FFEFEFEFFFD0D0D0FF676767FFC9C9\n      C9FFF2F2F2FFF5F5F5FFF4F4F4FFF5F5F5FFF5F5F5FFF5F5F5FFF4F4F4FFF5F5\n      F5FFE8E8E8FF6E6E6EFFA3A3A3FFF6F6F6FF999999FF000000FF010101FFE3E3\n      E3FFF5F5F5FFF5F5F5FFF5F5F5FFF5F5F5FFF4F4F4FFF6F6F6FFE9E9E9FF1010\n      10FF000000FF000000FF010101FE000000FF323232CD00000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      000000000000000000000000000000000000000000000000000000000000E7E7\n      E7182E2E2ED6030305FF04062CFF090C38FF040B53FF101226FF272F39FF1117\n      49FF222749FF32393DFF1C2138F79F9F9F65FCFCFC0300000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000DEDEDD223234\n      3CD505061FFF101314FF111319FF111420FF161B21FF0F1114FF0B0C0DFF0E0F\n      12FF111418FF0F1115FF0E1013FF353739D4DCDCDC2300000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      000000000000000000000000000000000000F6F6F6096F6F6F92020202FD090C\n      0CFE718688FFA7C3C5FFA3C0C3FFA0BFC1FFA2C0C2FFA0BFC2FFA0BFC2FFA2C0\n      C4FFA3C3C6FFACCBCEFFB3D2D5FFB3D2D5FFAFD0D3FFAECFD3FFB0D2D5FFB1D3\n      D6FFB0D1D5FFB1D1D3FFACCCCEFFA8C9CBFFACCCCFFFABCBCFFFABCCD0FFB6D5\n      D7FFBAD8DBFFB7D7DBFFB4D7DAFFB5D9DDFFBCE0E4FFC5EBEDFFC9EDF1FFC7EA\n      EEFFBEE2E5FFAACACEFF8CA7A9FF3F4A4BFF000000FF2B3334FF88A2A5FF85A0\n      A2FF89A3A6FF90A9AAFF8CA6A8FF8AA3A6FF8BA4A6FF8BA4A7FF8EA7AAFF8EA7\n      A9FF8AA4A6FF8EA8AAFF434F51FF000000FF07090AFF7D9496FF8EA7AAFF87A1\n      A3FF809B9FFF839DA0FF89A1A4FF89A3A5FF5F7173FF080A0AFF000000FF1013\n      13FF7D9496FF869FA2FF7F9A9DFF7F9A9DFF829CA0FF869FA3FF88A1A4FF8098\n      9AFF283132FF000000FF0A0C0DFF799093FF86A0A3FF859FA1FF87A0A2FF88A2\n      A4FF89A2A4FF87A1A3FF86A0A3FF515F60FF020202FE000000FF2C2C2CD3DADA\n      DA25000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000BBBBBB440C0C\n      0CF3090A0BFF9EB1BDFFD7F0FFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EF\n      FFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EF\n      FFFFC7DEEDFF131618FF000000FF000000FF8D9DA8FFD9F2FFFFD5EEFEFFD6EF\n      FFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EF\n      FFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EF\n      FFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EF\n      FFFFD6EFFFFFD6EFFFFFD6EFFFFFD3EEFFFFB6E2FFFFAFDFFFFFB0E0FFFF84A8\n      C0FF090B0DFF0E1215FF94BDD7FFB6E7FFFF192025FF2D3942FFA1CDE9FF080A\n      0BFF82A5BCFF0D0E10FF225E61FF040C0CFF010101FE070707F8B0B0B04F0000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000303030CF000000FF000000FF000000FF0000\n      00FF161616FFEEEEEEFFF6F6F6FFF5F5F5FFF5F5F5FFF5F5F5FFF5F5F5FFF5F5\n      F5FFECECECFF565656FF6D6D6DFFF6F6F6FFF4F4F4FFF6F6F6FFFBFBFBFFF6F6\n      F6FFF4F4F4FFF5F5F5FFF5F5F5FFF5F5F5FFF5F5F5FFF5F5F5FFF5F5F5FFF5F5\n      F5FFF5F5F5FFFAFAFAFFF8F8F8FFF4F4F4FFF7F7F7FFBBBBBBFF1A1A1AFFE0E0\n      E0FFF5F5F5FFF5F5F5FFF5F5F5FFF5F5F5FFF5F5F5FFF4F4F4FFFFFFFFFF7272\n      72FF000000FF000000FF000000FF010101FE0A0A0AF5B7B7B748000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000FEFEFE01CECE\n      CD32141414EE030313FF020335FF0C0E19FF0D1018FF161A21FF1A1F2BFF2229\n      34FF14182DFF0D1165FF151A40F4AEADAB55FDFDFD0200000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      00000000000000000000000000000000000000000000FDFDFD02FDFDFD02FEFE\n      FE01000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000D1D1D12F2626\n      28E4060611FF10131BFF141821FF121628FF1F232BFF171B22FF0F1015FF0F0F\n      14FF11151AFF14181EFF11151BFF323538D7DDDDDD2300000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      000000000000000000000000000000000000F0F0F00F575757A9000000FF0E11\n      11FF88A3A6FFB6D8DBFFBCDEE1FFBEDFE3FFB5D7DBFFADD1D6FFB2D5D9FFB3D5\n      DAFFB4D8DCFFBADDE1FFBADFE3FFC0E4E8FFC0E5E8FFB8DDE2FFBDE2E5FFC5E8\n      ECFFC5E9EDFFC2E7EBFFC3E8ECFFC1E6EBFFC1E7EAFFC2E7EBFFC4E9EDFFC1E7\n      EAFFBFE5E9FFC8ECEFFFD1F4F6FFCBEEF1FFC6EBEEFFC6EBEEFFCBEFF2FFCDF2\n      F4FFC7ECF0FFC6EAEEFFCDF1F4FFB5D4D6FF2B3333FF000000FF657879FF8DA7\n      AAFF8AA3A5FF8CA5A8FF8BA4A6FF87A0A3FF87A1A4FF8AA4A7FF8BA4A6FF89A2\n      A5FF8DA6A8FF8FAAACFF364041FF000000FF1A1E1FFF849C9FFF8AA3A5FF89A3\n      A5FF89A2A4FF8CA5A7FF8EA8AAFF8CA5A8FF8BA4A6FF222829FF000000FF1F25\n      25FF80989BFF8AA3A6FF87A1A3FF87A0A3FF8AA2A5FF8CA5A7FF8DA7A9FF88A2\n      A4FF435051FF010101FF050606FF637677FF8DA6A8FF8FA8AAFF93AAACFF92AA\n      ABFF8AA4A7FF849EA1FF89A2A5FF80999BFF262D2EFF000000FF040404FB6F6F\n      6F90F9F9F9060000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000D1D1D12E1111\n      11EE050606FF8D9EA8FFD7F0FFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EF\n      FFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD8F1\n      FFFF819099FF020202FF000000FF1C1F22FFC5DCEBFFD6EFFFFFD6EFFFFFD6EF\n      FFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EF\n      FFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EF\n      FFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EF\n      FFFFD6EFFFFFD6EFFFFFD6EFFFFFD4EEFFFFBAE4FFFFAFDFFFFFAAD9F7FF3240\n      4AFF090C0EFF98C1DCFFB9ECFFFF5E7989FF000000FF7697ACFF587181FF1920\n      25FF9EC9E5FF0A080AFF359598FF1F585AFF000000FF000000FF515151AEF7F7\n      F708000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      00000000000000000000B9B9B946080808F7010101FE000000FF000000FF0000\n      00FF828282FFFFFFFFFFF4F4F4FFF5F5F5FFF5F5F5FFF5F5F5FFF5F5F5FFF5F5\n      F5FFF2F2F2FFE8E8E8FFFFFFFFFFF5F5F5FFF5F5F5FFF5F5F5FFF5F5F5FFF5F5\n      F5FFF5F5F5FFF5F5F5FFF5F5F5FFF5F5F5FFF5F5F5FFF5F5F5FFF5F5F5FFF5F5\n      F5FFF5F5F5FFF5F5F5FFF5F5F5FFF5F5F5FFF5F5F5FFFBFBFBFFF7F7F7FFECEC\n      ECFFF5F5F5FFF5F5F5FFF5F5F5FFF5F5F5FFF5F5F5FFF5F5F5FFF6F6F6FFEBEB\n      EBFF040404FF000000FF000000FF000000FF000000FF5A5A5AA5000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000FDFDFD02A8A8\n      A85A0B0B0BF5090A0FFF111515FF13191DFF181E24FF24282FFF242D34FF1520\n      3CFF0B0D3DFF0E112FFF171A25F6A9A9A85CFDFDFD0200000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000F9F9F906D1D1D12E7979798A5C5C5CA9B5B5\n      B54BEDEDED12FDFDFD0200000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000C0C0C0401818\n      19F0080806FF050522FF0A1040FF1C202FFF20272FFF151C22FF101218FF1014\n      16FF111419FF101417FF14161EFF3B3C40D0E0E0E01F00000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      000000000000000000000000000000000000F2F2F20D5D5D5DA2010101FE090B\n      0CFF829A9DFFBBE1E5FFC2E6E9FFC2E7EBFFC3E8ECFFC6E9ECFFC1E6EAFFCAED\n      F1FFCAEDEFFFBFE5E9FFB8DFE3FFBEE3E8FFC3E7EBFFCCEFF2FFD0F2F6FFC9ED\n      F0FFC9EDF0FFCBEFF3FFCEF2F5FFCCF0F3FFC5E9ECFFC6EAEEFFC8EDF0FFBFE4\n      E9FFBCE2E7FFC6EAEDFFCAEEF1FFCFF1F4FFC9EDF1FFC1E6EAFFBCE2E6FFBAE0\n      E4FFBDE2E6FFC1E7EAFFC2E7EBFFC1E6EAFF89A4A6FF101313FF222829FF829A\n      9DFF89A3A5FF8CA5A8FF8CA6A8FF87A0A3FF849EA0FF859FA2FF86A0A3FF87A0\n      A3FF89A2A5FF88A2A5FF2C3636FF000000FF1B2021FF889FA2FF89A2A6FF8BA4\n      A7FF8FA8AAFF8EA7A9FF8AA3A6FF8DA6A8FF748A8CFF0D0F10FF232929FF191D\n      1EFF58696BFF86A1A3FF8CA6A8FF90A9AAFF90A8A9FF89A2A4FF7F989BFF768C\n      8EFF343E40FF000101FF020303FF58686AFF90A9ABFF8DA7A9FF8CA6A7FF8BA4\n      A6FF8CA5A7FF8DA6A8FF8BA4A5FF859FA1FF607274FF0B0C0CFF000000FF1717\n      17E8C4C4C43B0000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000E8E8E8171616\n      16E9010101FE77858FFFD8F1FFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EF\n      FFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD1E9\n      F9FF4B5459FF000000FF000000FF1E2224FFC6DDECFFD6EFFFFFD5EEFEFFD6EF\n      FFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EF\n      FFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD5EE\n      FEFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EF\n      FFFFD6EFFFFFD6EFFFFFD6EFFFFFD5EEFFFFBDE5FFFFAFDFFFFFB0E0FFFF9DC8\n      E4FFADDDFCFFB1E2FFFF91B9D2FF07090AFF20292FFFABD9F8FF0C0F11FF6782\n      94FF8BB1C9FF050002FF43BEC3FF3BA7ABFF030A0BFF000000FF000000FFD9D9\n      D926000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      000000000000FDFDFD02565656A9000000FF000000FF000000FF000000FF0909\n      09FFF0F0F0FFF6F6F6FFF5F5F5FFF5F5F5FFF5F5F5FFF5F5F5FFF5F5F5FFF5F5\n      F5FFF5F5F5FFF6F6F6FFF5F5F5FFF4F4F4FFF5F5F5FFF5F5F5FFF5F5F5FFF5F5\n      F5FFF5F5F5FFF5F5F5FFF5F5F5FFF5F5F5FFF5F5F5FFF5F5F5FFF5F5F5FFF5F5\n      F5FFF5F5F5FFF5F5F5FFF5F5F5FFF5F5F5FFF5F5F5FFF4F4F4FFF5F5F5FFF5F5\n      F5FFF4F4F4FFF5F5F5FFF5F5F5FFF5F5F5FFF5F5F5FFF5F5F5FFF4F4F4FFFCFC\n      FCFF727272FF000000FF000000FF000000FF000000FF171717E8CECECE310000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000F7F7F7087A7A\n      7A8907070DFC0E1114FF10151AFF151B20FF1D2429FF20262BFF181E3BFF111B\n      49FF121721FF1A2025FF1A1E23F6A7A7A85CFEFEFE0100000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      00000000000000000000F8F8F8079B9A9B68282828DB040404FF020201FF1011\n      14F4565656ADCCCCCB34FDFDFD02000000000000000000000000000000000000\n      00000000000000000000000000000000000000000000FEFEFE01A4A4A45C0E0E\n      10FF101114FF0E1011FF080817FF101132FF2A2F3FFF24282FFF151920FF171B\n      23FF151920FF14181DFF101317FF484A4BC1E8E8E81700000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      000000000000000000000000000000000000F9F9F9067E7E7E81040404FB0203\n      03FE5D6F71FFBFE2E6FFC4E8EDFFC6EBEEFFCCF0F3FFCBEEF1FFC9EDF1FFC8EC\n      EFFFC1E6EAFFBDE3E7FFC5EAEDFFC3E8EBFFC0E5E9FFC8ECEFFFC7EBEFFFC2E7\n      EBFFC5E9EDFFC6EAEEFFC3E8ECFFC4E9ECFFCBEEF2FFCAEEF1FFC4E9EDFFC4E8\n      EBFFC1E6EAFFC0E5E8FFC3E8ECFFC4E9EDFFCBEFF1FFCAEEF1FFC8EDF0FFC3E9\n      ECFFC7EBEFFFCBEFF2FFC4E8ECFFC1E7EBFFC5EAEDFF687B7DFF020302FF4A58\n      5AFF859EA1FF829C9FFF859EA1FF89A3A5FF8BA4A6FF8AA3A5FF87A1A3FF87A1\n      A4FF869FA2FF8DA6A9FF2D3535FF000000FF1E2425FF8AA3A5FF8BA5A8FF87A1\n      A4FF8BA4A7FF89A3A5FF849EA1FF849FA2FF4E5F60FF141818FF89A1A3FF687B\n      7DFF171B1CFF74898BFF687A7CFF4F5D5EFF3A4647FF313B3CFF212828FF0E10\n      10FF010101FF000000FF010101FF445153FF8AA3A5FF89A3A5FF849EA1FF839E\n      A1FF8AA3A5FF8DA6A8FF8BA4A6FF8AA3A5FF8AA3A5FF3D4748FF000000FF0000\n      00FF4E4E4EB1F8F8F80700000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000001B1B\n      1BE4010101FE5F6A71FFD5EEFEFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EF\n      FFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD5ED\n      FDFF6F7C84FF000000FF000000FF000000FF69757DFFE0FAFFFFD5EEFEFFD6EF\n      FFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EF\n      FFFFD6EFFFFFD6EFFFFFD6EFFFFFD5EEFEFFD9F2FFFFC8E0EEFFDCF6FFFFD6EF\n      FFFFD5EEFEFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EF\n      FFFFD6EFFFFFD6EFFFFFD6EFFFFFD5EEFFFFC0E6FFFFAFDFFFFFAFDFFEFFB1E2\n      FFFFB2E2FFFFA5D2EFFF232D33FF020303FF95BED9FF6C8A9DFF07090AFFAFDF\n      FEFF688496FF050A0AFF4FDDE2FF4EDBE0FF15393BFF010101FE000000FF5D5D\n      5DA2000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      000000000000CCCCCC33181818E7000000FF000000FF000000FF000000FF8282\n      82FFFAFAFAFFF4F4F4FFF5F5F5FFF5F5F5FFF5F5F5FFF5F5F5FFF5F5F5FFF5F5\n      F5FFF5F5F5FFF5F5F5FFF5F5F5FFF5F5F5FFF5F5F5FFF5F5F5FFF5F5F5FFF5F5\n      F5FFF5F5F5FFF5F5F5FFF5F5F5FFF5F5F5FFF5F5F5FFF5F5F5FFF5F5F5FFF5F5\n      F5FFF5F5F5FFF5F5F5FFF5F5F5FFF5F5F5FFF5F5F5FFF5F5F5FFF5F5F5FFF5F5\n      F5FFF5F5F5FFF5F5F5FFF5F5F5FFF5F5F5FFF5F5F5FFF5F5F5FFF5F5F5FFF5F5\n      F5FFDEDEDEFF060606FF000000FF000000FF000000FF000000FF8282827DFCFC\n      FC03000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000E8E8E8174546\n      48C104040CFF101316FF141920FF242A31FF1E272DFF283037FF363D45FF262B\n      30FF182022FF181E23FF161A1EF4B0B0B051FEFEFE0100000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      000000000000FCFCFC03ACACAC57111211F0060606FF030308FF040411FE0303\n      08FF030302FF393938D0C2C2C23EFDFDFD020000000000000000000000000000\n      00000000000000000000000000000000000000000000FCFCFC03919191700E0E\n      10FF0F0F13FF101217FF15181AFF07092FFF272D57FF31363BFF1D242BFF1C22\n      28FF161A20FF12161CFF11141AFF646466A0F3F3F30C00000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      00000000000000000000000000000000000000000000B7B7B748101010EF0000\n      00FF232929FFB0D0D3FFBEE3E8FFBEE3E8FFC1E6EAFFC4E9EDFFC6EAEEFFC6E9\n      ECFFC5E9ECFFC7EBEEFFC8ECEFFFC6ECF0FFCAEFF3FFC7ECEFFFBEE4E8FFC0E5\n      E9FFC6EAEEFFC6EBEEFFBFE4E9FFBDE2E7FFC3E8ECFFC4E9ECFFBFE4E9FFC3E8\n      ECFFCAEEF1FFC3E8EBFFC7EBEFFF9DBABCFF647577FF708183FF99B2B5FFB9DD\n      E1FFC3E9EDFFC6EAEDFFCAEEF1FFC6EBEEFFCBEFF3FFC4E7EAFF3F4B4CFF0A0C\n      0CFF748B8DFF869FA2FF8AA3A5FF8DA6A9FF8CA6A8FF8FA7A9FF8EA7A9FF8BA4\n      A8FF87A1A4FF88A2A5FF2F3739FF000000FF22292AFF8AA3A6FF88A2A5FF88A2\n      A5FF8FA8ABFF90AAACFF8DA6AAFF85A0A3FF374142FF242A2BFF92ACAEFF839A\n      9CFF0F1111FF0C0F0FFF070809FF020202FF000000FF000000FF000000FF0000\n      00FF000000FF000000FF000000FF394445FF829B9EFF839DA0FF829C9FFF859F\n      A2FF89A3A5FF88A0A4FF8AA2A5FF8EA7AAFF90A8ABFF7F9596FF151819FE0000\n      00FF0A0A0AF5C0C0C03F00000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000003C3C\n      3CC3000000FF444C51FFCFE7F7FFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EF\n      FFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EF\n      FFFFD4EDFDFF75828BFF000000FF000000FF000000FF798790FFDFF9FFFFD5EE\n      FEFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EF\n      FFFFD6EFFFFFD6EFFFFFD6EFFFFFD9F2FFFF8B9CA5FF09090AFF3A4146FFDAF4\n      FFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EF\n      FFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFC3E7FFFFAFDFFFFFAFDFFEFFB0E1\n      FFFFACDBF9FF1E262BFF000000FF7C9EB3FFA9D8F5FF161D20FF597283FFAFDF\n      FEFF38444EFF1B4C4EFF4EDADFFF4DD7DCFF3FAEB3FF000000FF000000FF0000\n      00FFEFEFEF100000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000FCFCFC037B7B7B84000000FF010101FE000000FF000000FF0E0E0EFFE4E4\n      E4FFF4F4F4FFF5F5F5FFF5F5F5FFF5F5F5FFF5F5F5FFF5F5F5FFF5F5F5FFF5F5\n      F5FFF5F5F5FFF5F5F5FFF5F5F5FFF5F5F5FFF5F5F5FFF5F5F5FFF5F5F5FFF5F5\n      F5FFF5F5F5FFF5F5F5FFF5F5F5FFF5F5F5FFF5F5F5FFF5F5F5FFF5F5F5FFF5F5\n      F5FFF5F5F5FFF5F5F5FFF5F5F5FFF5F5F5FFF5F5F5FFF5F5F5FFF5F5F5FFF5F5\n      F5FFF5F5F5FFF5F5F5FFF5F5F5FFF5F5F5FFF5F5F5FFF5F5F5FFF5F5F5FFF5F5\n      F5FFEFEFEFFF666666FF000000FF000000FF000000FF000000FF1D1D1DE2EDED\n      ED12000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000DBDBDB242F30\n      3BD60E1015FF12161BFF14171EFF12161DFF12171DFF1A212AFF1D212EFF191D\n      38FF0F1342FF0F1320FF15171FF5AAAAAA58FDFDFD0200000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      000000000000EDEDED12545454B1060606FF030305FF04040FFF03030CFF0404\n      05FF040406FE020216FF1F1F1EE7C5C5C53BFBFBFB0400000000000000000000\n      00000000000000000000000000000000000000000000FCFCFC0379797A8C0D10\n      15FF101115FE101218FF131421FF090A36FF0B0C27FF1F2328FF272D34FF1E22\n      2BFF141820FF111219FF0F1217FA83838483F6F6F60900000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      00000000000000000000000000000000000000000000F0F0F00F444444BB0000\n      00FF000000FF5A6A6BFEBCE0E3FFC0E6EAFFC2E6ECFFC6EAEDFFC7EBEEFFC1E5\n      E9FFB7D7DAFFAECBCDFFB3D2D5FFBEE2E6FFC4E9EBFFBBE1E6FFBAE0E5FFBFE4\n      E8FFBCE2E6FFC0E4E9FFC9EEF2FFCCEFF2FFCAEEF0FFC6EAEEFFC5EAEEFFCCF0\n      F3FFCAEEF2FFCBF0F3FF96B0B3FF101314FF020101FF0E0E0EFF2A2A2BFF646E\n      6EFFADC9CBFFC9EEF1FFC9EEF1FFC7EBEEFFC0E5E9FFC2E8ECFFA7C7CBFF2329\n      2AFF3C4848FF8DA7A9FF859FA2FF859FA2FF87A0A4FF86A0A3FF8AA3A5FF8DA6\n      A8FF8EA7A9FF8EA7AAFF3E4C4DFF000000FF1E2324FF7B9496FF7B9294FF6A7E\n      80FF5B6C6DFF3D4A4BFF202628FF151616FF010202FF050606FF5F7274FF5364\n      65FF050606FF000000FF000000FF000000FF000000FF000000FF000000FF0000\n      00FF000000FF000000FF000000FF384344FF869FA2FF8AA4A6FF8AA3A5FF8AA3\n      A6FF8CA4A8FF8AA5A6FF8BA5A7FF8DA5A9FF86A0A3FF8CA5A8FF4A5758FF0000\n      00FF000000FF7A7A7A8500000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000007272\n      728D000000FF272B2EFFC8E0EFFFD5EEFEFFD6EFFFFFD6EFFFFFD6EFFFFFD6EF\n      FFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EF\n      FFFFD5EEFEFFDEF8FFFF8B9CA5FF040404FF000000FF070808FFA4B8C4FFD6EF\n      FFFFD5EEFEFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EF\n      FFFFD6EFFFFFD6EFFFFFD6EFFFFFDFFAFFFF0F1113FF000000FF000000FF555F\n      65FFDDF7FFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EF\n      FFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFC4E8FFFFB0DFFFFFB0E0FFFFB6E8\n      FFFF222B31FF000000FF5B7584FFB3E5FFFF5F798AFF010101FFA2CDEAFF9CC6\n      E1FF040102FF399FA3FF4CD5DAFF4BD3D8FF4FDFE4FF0F2A2BFF000000FF0000\n      00FF8484847B0000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000EBEBEB14171717E8000000FF000000FF000000FF000000FF707070FFF0F0\n      F0FFF4F4F4FFF5F5F5FFF5F5F5FFF5F5F5FFF5F5F5FFF5F5F5FFF5F5F5FFF5F5\n      F5FFF5F5F5FFF5F5F5FFF5F5F5FFF5F5F5FFF5F5F5FFF5F5F5FFF5F5F5FFF5F5\n      F5FFF5F5F5FFF5F5F5FFF5F5F5FFF5F5F5FFF5F5F5FFF5F5F5FFF5F5F5FFF5F5\n      F5FFF5F5F5FFF5F5F5FFF5F5F5FFF5F5F5FFF5F5F5FFF5F5F5FFF5F5F5FFF5F5\n      F5FFF5F5F5FFF5F5F5FFF5F5F5FFF5F5F5FFF5F5F5FFF5F5F5FFF5F5F5FFF5F5\n      F5FFF6F6F6FFB7B7B7FF0B0B0BFF000000FF000000FF010101FE000000FF9696\n      9669000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000C6C6C6391E1E\n      20EA0C0C0EFF0B0C0FFF0D0F15FF141825FF161B26FF181D35FF171B3CFF171A\n      26FF0E0F1CFF090913FF101215FA90919273FCFCFC0300000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000FEFEFE01BBBBBB441C1C1CEC0B0B0BFF030308FF05052BFF050517FF0303\n      1DFF03030FFF04040BFE050504FF3B3A3ACDDBDBDB2400000000000000000000\n      00000000000000000000000000000000000000000000FCFCFC03797A7A8A1012\n      18FF101419FF10131BFF0B0D24FF131618FF0D0F1FFF1B1F29FF32373EFF262C\n      32FF0A1138FF070816FF0A0B10FF5A5B5CABEFEFEF1000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000BBBBBB440F0F\n      0FF0000000FF030404FE5D6F6FFFC1E5E9FFC3E7EBFFC8ECF0FFC9EDF0FF768B\n      8DFF333939FF303232FF464B4CFF6D797BFFA5BFC1FFC4E9EEFFC7ECF0FFC6EB\n      EFFFC5EBEDFFC3E7EBFFC1E5E9FFC6E9EDFFC6EAEDFFC7EBEEFFC4E9EDFFBDE4\n      E8FFC3E8ECFFC9EDF0FF4B585AFF000000FF000000FF040404FF0F0F0FFF2827\n      27FF545859FFA4BEC0FFC4E9ECFFC0E5E9FFC7EBEDFFC9EBEFFFCCEFF2FF8CA6\n      A8FF101213FF5B6B6CFF8FA9ACFF86A0A3FF849FA2FF86A0A2FF859EA1FF849E\n      A1FF87A0A4FF8BA4A7FF4F5F61FF000000FF020303FF141718FF111414FF0304\n      05FF000000FF000000FF000000FF000000FF000000FF000000FF070808FF1418\n      18FF0F1213FF000000FF000000FF000000FF000000FF000000FF000000FF0000\n      00FF000000FF000000FF000000FF3C4647FF8BA3A6FF8BA4A6FF88A1A4FF849F\n      A1FF839DA0FF87A1A4FF88A1A4FF88A1A4FF8BA4A6FF869FA2FF64787AFF0607\n      07FE000000FF575757A8FAFAFA05000000000000000000000000000000000000\n      000000000000000000000000000000000000000000000000000000000000B2B2\n      B24D000000FF030404FEC1D7E6FFD5EEFEFFD6EFFFFFD6EFFFFFD6EFFFFFD6EF\n      FFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EF\n      FFFFD6EFFFFFD5EEFEFFD9F2FFFF99ABB6FF0E1011FF000000FF1D2123FFC1D8\n      E7FFD6EFFFFFD5EEFEFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EF\n      FFFFD6EFFFFFD6EFFFFFD7F0FFFFD2ECFBFF000000FF000000FF000000FF0B0C\n      0DFFB7CCDAFFD6F0FFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EF\n      FFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFC6E8FFFFB0E0FFFFB0E0FFFFAEDE\n      FDFF3C4C56FF637E90FFB6E8FFFF8BB0C9FF000000FF546B79FFB6E8FFFF4D60\n      6EFF051B1BFF48C8CDFF4BD3D8FF4CD4D9FF4CD6DBFF379A9EFF000000FF0000\n      00FF292929D60000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      00008B8B8B74000000FF010101FE000000FF000000FF121212FFBFBFBFFFF6F6\n      F6FFF5F5F5FFF5F5F5FFF5F5F5FFF5F5F5FFF5F5F5FFF5F5F5FFF5F5F5FFF5F5\n      F5FFF5F5F5FFF5F5F5FFF5F5F5FFF5F5F5FFF5F5F5FFF5F5F5FFF5F5F5FFF5F5\n      F5FFF5F5F5FFF5F5F5FFF5F5F5FFF5F5F5FFF5F5F5FFF5F5F5FFF5F5F5FFF5F5\n      F5FFF5F5F5FFF5F5F5FFF5F5F5FFF5F5F5FFF5F5F5FFF5F5F5FFF5F5F5FFF5F5\n      F5FFF5F5F5FFF5F5F5FFF5F5F5FFF5F5F5FFF5F5F5FFF5F5F5FFF5F5F5FFF5F5\n      F5FFF5F5F5FFEEEEEEFF434343FF000000FF000000FF000000FF000000FF1212\n      12ED000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000A2A2A25F0D0D\n      0FFF0A0B14FF0B0B0FFF0E1012FF10151AFF15181FFF191D25FF1C2129FF1416\n      1CFF111519FF111317FF0E1012FB8B8C8D79FAFAFA0500000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000E7E7E7183F4043C5050513FF080805FF04031EFF08091BFF0D0D0EFF0607\n      24FF090A36FF09080FFF0A0A0DFF0E121FFF9D9E9F64FDFDFD02000000000000\n      00000000000000000000000000000000000000000000FAFAFA05818282801013\n      16FF0F1217FF101217FF0C0E13FF13161BFF131825FF11154AFF34384AFF0E15\n      63FF101522FF131419FF0F1216FF36383BD3E0E0E02000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000FEFEFE018484\n      847B030303FC000000FF0C0F0FFF8DA7A9FFC5EAEEFFBFE5E9FFA2C0C4FF191E\n      1EFF030303FF0B0B0BFF171717FF2B2B2BFF4C4E4EFF94A9ACFFC6EBF0FFC4E9\n      ECFFC5EAEEFFC2E7EBFFC0E5E9FFC4E9ECFFC2E7EAFFC3E8EBFFC4E9EDFFC3E7\n      EBFFC9ECF0FFC5E9EDFF3E494BFF000000FF000000FF010101FF050505FF1818\n      18FF373737FF646A6BFFB6D6D9FFC5EAEDFFC5E9EDFFC6E9ECFFC9ECEEFFC7EA\n      EEFF66797BFF111415FF72888AFF89A2A5FF869FA2FF869FA2FF87A0A3FF869F\n      A2FF829DA0FF849FA2FF637577FF000000FF000000FF000000FF000000FF0000\n      00FF000000FF000000FF000000FF000000FF000000FF000303FF617375FF7D94\n      96FF718587FF090C0BFF000000FF000000FF000000FF000000FF000000FF0000\n      00FF000000FF000000FF010101FF445253FF87A1A4FF8CA5A7FF8CA5A7FF8AA3\n      A5FF89A3A6FF8BA4A7FF8AA4A7FF849EA1FF849EA0FF8BA4A7FF708385FF080A\n      0AFF000000FF515151AEF8F8F807000000000000000000000000000000000000\n      000000000000000000000000000000000000000000000000000000000000FAFA\n      FA05000000FF010101FE97A9B4FFD8F1FFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EF\n      FFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EF\n      FFFFD6EFFFFFD6EFFFFFD6EFFFFFD7F0FFFFBBD1DEFF0E1011FF000000FF292E\n      31FFDEF8FFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EF\n      FFFFD6EFFFFFD6EFFFFFD6EFFFFFD7F0FFFF000000FF000000FF000000FF0303\n      03FF83929BFFD8F1FFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EF\n      FFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFC6E9FFFFB0E0FFFFAFDFFEFFB0E0\n      FFFFA9D8F5FFB1E1FFFFA0CCE8FF161C20FF101417FFA9D7F5FF90B8D1FF0000\n      00FF2B787BFF4CD4D9FF4CD4D9FF4CD4D9FF4BD3D8FF46C5CAFF0B1F20FF0101\n      01FE101010EFD1D1D12E00000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000080808F7000000FF010101FE000000FF000000FF4A4A4AFFF3F3F3FFF5F5\n      F5FFF5F5F5FFF5F5F5FFF5F5F5FFF5F5F5FFF5F5F5FFF5F5F5FFF5F5F5FFF5F5\n      F5FFF5F5F5FFF5F5F5FFF5F5F5FFF5F5F5FFF5F5F5FFF5F5F5FFF5F5F5FFF5F5\n      F5FFF5F5F5FFF5F5F5FFF5F5F5FFF5F5F5FFF5F5F5FFF5F5F5FFF5F5F5FFF5F5\n      F5FFF5F5F5FFF5F5F5FFF5F5F5FFF5F5F5FFF5F5F5FFF5F5F5FFF5F5F5FFF5F5\n      F5FFF5F5F5FFF5F5F5FFF5F5F5FFF5F5F5FFF5F5F5FFF5F5F5FFF5F5F5FFF5F5\n      F5FFF5F5F5FFFBFBFBFF989898FF060606FF000000FF000000FF010101FE0000\n      00FF9393936C0000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      00000000000000000000000000000000000000000000FAFAFA057E7E7E840E0E\n      12FF0E0E10FF0B0B0BFF0E0E11FF0F0F16FF11161AFF181D24FF1B1F28FF191E\n      26FF12161BFF0E1018FF111418FB898A8A7BFAFAFA0500000000000000000000\n      000000000000000000000000000000000000000000000000000000000000FBFB\n      FB048080818408080CFF07071FFE060526FF060F46FF141511FF090B4AFF0B0C\n      27FF0F0F07FF060634FF03030DFE070814FF5E5E61A8F6F6F609000000000000\n      00000000000000000000000000000000000000000000F8F8F8075C5D5EAA0E11\n      17FF13161DFE11151AFF111318FF171922FF1F232EFF101335FF191D28FF2B2F\n      33FF1C1F29FF12161CFF12141BFF323336D8DADADA2600000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      000000000000000000000000000000000000000000000000000000000000F0F0\n      F00F585858A7020202FD000000FF3C4647FEB6D7DBFFC3E8ECFF8DA7A9FF0809\n      09FF000000FF020202FF060606FF101010FF282727FF464647FFA2BBBDFFCDF2\n      F4FFC9EDF0FFC7EBEEFFC9EDF0FFC3E9EDFFC1E5E9FFC3E7EBFFC9EDF0FFCBEF\n      F1FFC4E8ECFFC6ECF0FF6D8183FF000000FF000000FF000000FF020202FF0B0B\n      0BFF252525FF434343FF91A4A5FFCAEFF2FFC1E6EBFFC0E5E9FFC1E7EAFFC3E8\n      ECFFBDE1E6FF495657FF3B4547FF8CA5A8FF8AA5A8FF8EA7A9FF8CA5A8FF8BA4\n      A7FF8AA4A6FF89A2A5FF798F91FF060808FF000000FF000000FF000000FF0000\n      00FF000000FF000000FF000000FF000000FF000000FF1A1F20FF839EA0FF859F\n      A2FF849FA2FF4D5D5FFF020202FF000000FF000000FF000000FF000000FF0000\n      00FF000000FF000000FF020202FF526164FF849FA1FF859FA1FF8CA5A7FF8CA5\n      A7FF89A2A5FF89A2A5FF8AA3A6FF89A2A4FF89A2A5FF8EA7A9FF59696AFF0001\n      01FF000000FF67676798FEFEFE01000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      00002C2C2CD3000000FF4F575EFFDDF6FFFFD5EEFEFFD6EFFFFFD6EFFFFFD6EF\n      FFFFD6EFFFFFD6EFFFFFD5EEFEFFD7F0FFFFC9E0EFFFC5DCEBFFD5EEFEFFD5EE\n      FEFFD6EFFFFFD6EFFFFFD6EFFFFFD5EEFEFFD7F0FFFFC4DAE9FF1D2123FF0000\n      00FF566067FFDBF5FFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EF\n      FFFFD6EFFFFFD6EFFFFFD5EEFEFFE0FBFFFF131516FF000000FF000000FF0000\n      00FF69757DFFD7F1FFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EF\n      FFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFC7E9FFFFB0E0FFFFB0E0FFFFAFDF\n      FEFFB0E0FFFFABDAF8FF3C4D57FF000000FF7EA0B6FFB0E0FEFF181F22FF0D23\n      24FF4BD2D7FF4CD4D9FF4CD4D9FF4CD4D9FF4CD4D9FF4BD1D6FF1F5658FF0000\n      00FF040404FB9B9B9B6400000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000008383\n      837C000000FF010101FE000000FF000000FF080808FFA7A7A7FFFBFBFBFFF4F4\n      F4FFF5F5F5FFF5F5F5FFF5F5F5FFF5F5F5FFF5F5F5FFF4F4F4FFF5F5F5FFF6F6\n      F6FFF6F6F6FFF6F6F6FFF5F5F5FFF5F5F5FFF4F4F4FFF5F5F5FFF5F5F5FFF4F4\n      F4FFF5F5F5FFF4F4F4FFF5F5F5FFF5F5F5FFF5F5F5FFF5F5F5FFF4F4F4FFF5F5\n      F5FFF4F4F4FFF5F5F5FFF5F5F5FFF5F5F5FFF5F5F5FFF5F5F5FFF6F6F6FFF6F6\n      F6FFF6F6F6FFF5F5F5FFF5F5F5FFF4F4F4FFF5F5F5FFF5F5F5FFF5F5F5FFF5F5\n      F5FFF5F5F5FFF5F5F5FFF5F5F5FF1C1C1CFF000000FF000000FF000000FF0000\n      00FF1D1D1DE20000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      00000000000000000000000000000000000000000000EEEEEE11434444C40809\n      09FF0C0C0CFF0C0C0DFF0E1013FF111418FF11172FFF181C27FF171D35FF1418\n      22FF090B31FF070820FF0A0A0EFD7E7E7F86F9F9F90600000000000000000000\n      000000000000000000000000000000000000000000000000000000000000E9E9\n      E916262525E106061FFF090926FF0F1014FF0D1339FF121F63FF081176FF0F0E\n      0AFF0B0C13FF0A0B1CFF0E0D0AFF0D1013FF323437D9E8E8E817000000000000\n      00000000000000000000000000000000000000000000F2F2F20D4D4E4FBB1012\n      17FF111319FF14171EFF13151BFF1B1E25FF1F2332FF0E0F28FF2F323AFF292C\n      35FF14171DFF14161DFF0F1218FF303037DADADADA2600000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000D2D2D22D252525DA000000FF040505FE6B8082FFCFF3F6FFA6C2C4FF1013\n      13FF000000FF000000FF000000FF060606FF161616FF333333FF666D6EFFB7D8\n      DBFFC2E8EBFFC6EBEEFFC8ECEFFFC8EDF1FFC6EBEEFFC8ECEFFFC9EDF1FFC4E9\n      ECFFC5E9EDFFC1E7EBFFA3C3C6FF1D2122FF000000FF000000FF000000FF0505\n      05FF191919FF3A3939FF70797AFFC1E5E9FFC7ECEFFFCBEFF2FFCAEDF0FFCAEE\n      F1FFC6EBEFFFA2C2C5FF3A4546FF81999BFF93AFB2FF8BA6A8FF8CA5A7FF8BA4\n      A7FF8BA4A6FF8EA7A9FF859DA0FF1B2021FF000000FF000000FF000000FF0000\n      00FF000000FF000000FF000000FF000000FF000000FF3C484AFF88A3A5FF849E\n      A1FF849EA1FF7D9698FF252C2CFF000000FF000000FF000000FF000000FF0000\n      00FF000000FF000000FF030404FF58696AFF89A2A5FF87A1A4FF87A0A3FF8EA7\n      A9FF8AA3A6FF86A0A3FF88A1A4FF89A1A4FF8CA5A8FF819A9CFF22292AFE0000\n      00FF000000FFA1A1A15E00000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      00008585857A000000FF060606FED9F3FFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EF\n      FFFFD6EFFFFFD6EFFFFFD7F1FFFFC2D8E7FF24292BFF16181AFF8D9EA8FFDBF5\n      FFFFD5EEFEFFD6EFFFFFD6EFFFFFD6EFFFFFD5EEFEFFD8F1FFFFB6CBD9FF1618\n      1AFF020202FF97A8B4FFD7F0FFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EF\n      FFFFD6EFFFFFD6EFFFFFD6EFFFFFDAF4FFFF6B7880FF000000FF000000FF0000\n      00FF66737AFFD7F0FFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EF\n      FFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFC7E9FFFFB0E0FFFFB0E0FFFFAFDF\n      FEFFB6E8FFFF576F7EFF000000FF526977FFB7EAFFFF475A66FF010505FF3FB2\n      B6FF4DD8DDFF4BD3D8FF4CD4D9FF4CD4D9FF4CD4D9FF4CD6DBFF31888BFF0104\n      04FF000000FF6A6A6A95FEFEFE01000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000F6F6F6091A1A\n      1AE5000000FF000000FF000000FF000000FF282828FFFBFBFBFFF5F5F5FFF5F5\n      F5FFF5F5F5FFF5F5F5FFF5F5F5FFF5F5F5FFF4F4F4FFF8F8F8FFEBEBEBFFC3C3\n      C3FFB7B7B7FFBABABAFFCDCDCDFFF4F4F4FFF4F4F4FFF4F4F4FFF6F6F6FFF5F5\n      F5FFF6F6F6FFF4F4F4FFF5F5F5FFF5F5F5FFF5F5F5FFF5F5F5FFF4F4F4FFF6F6\n      F6FFF5F5F5FFF5F5F5FFF5F5F5FFF4F4F4FFF5F5F5FFDFDFDFFFBDBDBDFFB8B8\n      B8FFB9B9B9FFD9D9D9FFF8F8F8FFF5F5F5FFF5F5F5FFF5F5F5FFF5F5F5FFF5F5\n      F5FFF5F5F5FFF4F4F4FFFFFFFFFF8F8F8FFF000000FF000000FF000000FF0101\n      01FE060606F99D9D9D6200000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      00000000000000000000000000000000000000000000D7D7D7280D0E10FD0506\n      06FF070708FE0C0C0BFF0F1011FF101216FF0F1529FF101432FF111537FF161D\n      30FF060616FF0A0B0CFF101215FD7777788BF8F8F80700000000000000000000\n      0000000000000000000000000000000000000000000000000000FEFEFE01D7D7\n      D728232527EA0D0F1BFF04076BFF0B0C29FF171E24FF0A1E96FF0B134EFF1B1E\n      23FF10152AFF060F5CFF080930FF090C23FF121421F8D2D2D22D000000000000\n      00000000000000000000000000000000000000000000E9E9E9163C3C3ECF0E11\n      17FF171B22FF14181FFF11151BFF1F252DFF0C0D18FF11141AFF272A31FF252A\n      30FF16191CFF10121DFF090A14FF393C3FCFDFDFDF2000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      000000000000A0A0A05F080808F7000000FF121515FE9DBABCFFC2E7EBFF3D48\n      4BFF000000FF000000FF000000FF010101FF0D0D0DFF292929FF4E4F4FFF99B3\n      B5FFBADFE4FFC1E6EAFFC6EBEEFFC6EAECFFC4E9EDFFC2E7EBFFC0E5E9FFC4E9\n      EDFFC7ECF0FFC3E7EBFFC3E8EBFF859A9DFF0A0B0BFF000000FF000000FF0303\n      03FF151515FF353434FF697273FFC1E4E7FFC8ECF0FFC6EBEEFFC8ECEFFFCCEF\n      F2FFC7EBEEFFC7ECEFFF89A3A6FF617274FFA0BEC1FF97B2B4FF8EA8ABFF8CA5\n      A7FF8DA6A8FF8AA3A6FF849DA0FF394445FF000000FF000000FF000000FF0000\n      00FF000000FF000000FF000000FF000000FF000000FF607374FF8FA8ABFF8CA5\n      A7FF849EA0FF859FA2FF657779FF080A0AFF000000FF000000FF000000FF0000\n      00FF000000FF000000FF090A0BFF728889FF839EA1FF87A0A3FF88A1A4FF87A0\n      A3FF8CA6A8FF8DA6A8FF8CA5A8FF859FA1FF7D979BFF404D4EFF010101FE0000\n      00FF313131CEECECEC1300000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000D9D9D926000000FF000000FF97A9B4FFDAF4FFFFD6EFFFFFD6EFFFFFD6EF\n      FFFFD6EFFFFFD6EFFFFFDEF8FFFF636F76FF000000FF000000FF000000FFC2D9\n      E8FFD8F1FFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD9F3FFFFADC2\n      CFFF000000FF2E3337FFCCE4F3FFD5EEFEFFD6EFFFFFD6EFFFFFD6EFFFFFD6EF\n      FFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFBFD5E4FF0F1113FF000000FF0202\n      03FF81909AFFD8F1FFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EF\n      FFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFC6E9FFFFB0E0FFFFB0E0FFFFB5E6\n      FFFF6C8A9DFF000000FF384852FFB0E0FFFF678395FF000000FF349295FF4DD7\n      DCFF4BD3D8FF4CD4D9FF4CD4D9FF4CD4D9FF4CD4D9FF4CD4D9FF40B3B7FF050E\n      0FFF000000FF404040BFF4F4F40B000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      00000000000000000000000000000000000000000000000000008B8B8B740404\n      04FB010101FE000000FF000000FF000000FFA9A9A9FFFCFCFCFFF4F4F4FFF5F5\n      F5FFF5F5F5FFF5F5F5FFF5F5F5FFF5F5F5FFF5F5F5FFD8D8D8FF515151FF1818\n      18FF0C0C0CFF0F0F0FFF1D1D1DFF898989FFF9F9F9FFF8F8F8FFE2E2E2FFF5F5\n      F5FFCCCCCCFFF8F8F8FFF5F5F5FFF5F5F5FFF5F5F5FFF4F4F4FFFFFFFFFF8A8A\n      8AFFFFFFFFFFEBEBEBFFECECECFFF5F5F5FFD8D8D8FF292929FF121212FF0D0D\n      0DFF0E0E0EFF2B2B2BFFABABABFFF3F3F3FFF5F5F5FFF5F5F5FFF5F5F5FFF5F5\n      F5FFF5F5F5FFF5F5F5FFF5F5F5FFF4F4F4FF191919FF000000FF000000FF0000\n      00FF000000FF434343BCF2F2F20D000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      00000000000000000000000000000000000000000000D1D1D12E101217FF0707\n      07FF060608FF090A18FF090B1AFF0F1018FF0D101BFF0E1420FF080A48FF1315\n      19FF14171CFF14191FFF111519FB8585857FF9F9F90600000000000000000000\n      0000000000000000000000000000000000000000000000000000FEFEFE01CECD\n      CD321F2226ED12151BFF141616FF0A0A2AFF040439FF242833FF131E60FF262D\n      49FF11163FFF141515FF101313FF14171CFE14181DFFB0B0AF53000000000000\n      00000000000000000000000000000000000000000000D6D6D629101114FA0F10\n      16FF151722FF141620FF171B25FF1A1E2BFF161921FF2B3039FF161B3FFF1115\n      34FF0D1035FF0F111BFF1A1F26FF45464BC8E5E5E51A00000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      000000000000F6F6F6095C5C5CA3000000FF000000FF374243FFB6D9DDFF9AB7\n      BBFF141718FF000000FF000000FF010101FF080808FF212121FF474848FF95AA\n      ACFFC4E8EBFFC1E6EBFFC0E5E9FFC2E7EBFFC4E9EDFFC6EBEEFFCBEFF2FFCEF2\n      F4FFCEF2F5FFCBEFF2FFC9EDF0FFC3E9ECFF748A8DFF151818FF020202FF0303\n      03FF131313FF373737FF899A9CFFC9EDF0FFC8ECEEFFC8ECEFFFC9ECF0FFC5E9\n      ECFFC5EAEDFFCBEEF2FFC2E6E9FF809799FFA1BEC0FFA1BFC2FF93AEB1FF8FA9\n      ABFF8CA6A8FF8FA8A9FF8DA6A9FF617274FF040505FF000000FF000000FF0000\n      00FF000000FF000000FF000000FF000000FF0E1111FF718889FF87A1A3FF89A2\n      A4FF8AA3A5FF8BA4A5FF8CA4A7FF384343FF000000FF000000FF000000FF0000\n      00FF000000FF000000FF161A1AFF8DA5A6FF8BA4A7FF8DA6A8FF8BA4A6FF849E\n      A1FF87A1A2FF85A0A2FF86A0A2FF869FA2FF536364FF070808FE000000FF0808\n      08F7A4A4A45B0000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000F0F0F00F303030CF000000FF3B4146FFDFF9FFFFD6EFFFFFD6EFFFFFD6EF\n      FFFFD6EFFFFFD6EFFFFFE1FBFFFF3D4448FF000000FF000000FF000000FF505A\n      60FFDFF9FFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD5EEFEFFDBF5\n      FFFF83929CFF000000FF83939DFFDAF3FFFFD5EEFEFFD6EFFFFFD6EFFFFFD6EF\n      FFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD7F0FFFF90A1ABFF181B1CFF2A30\n      33FFC9E0EFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EF\n      FFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFC5E8FFFFB0E0FFFFB0E0FFFFB2E3\n      FFFF90B7D0FF597181FFADDCFBFF708FA2FF000000FF215D5EFF4BD2D7FF4BD3\n      D8FF4CD4D9FF4CD4D9FF4CD4D9FF4CD4D9FF4CD4D9FF4CD4D9FF4DD8DDFF091A\n      1AFF000000FF1A1A1AE5EBEBEB14000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      00000000000000000000000000000000000000000000000000007171718E0202\n      02FD000000FF000000FF000000FF000000FFE4E4E4FFF7F7F7FFF5F5F5FFF5F5\n      F5FFF5F5F5FFF5F5F5FFF5F5F5FFF5F5F5FFEFEFEFFF6B6B6BFF000000FF0000\n      00FF000000FF000000FF000000FF787878FFFBFBFBFFCFCFCFFFB2B2B2FFF0F0\n      F0FF797979FFFEFEFEFFF5F5F5FFF5F5F5FFF4F4F4FFF7F7F7FFE2E2E2FF0E0E\n      0EFF9E9E9EFFCFCFCFFFB9B9B9FFF5F5F5FFE0E0E0FF000000FF000000FF0000\n      00FF000000FF000000FF111111FFE5E5E5FFF4F4F4FFF5F5F5FFF5F5F5FFF5F5\n      F5FFF5F5F5FFF5F5F5FFF4F4F4FFFEFEFEFF434343FF000000FF000000FF0000\n      00FF000000FF333333CCE7E7E718000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      00000000000000000000000000000000000000000000DCDCDC23242629E9090A\n      0BFF0A0C10FF0D0D18FF0A0B34FF0B0E26FF0A0C16FF080C2EFF141817FF1B21\n      26FF191E23FF141817FF121617FB8687877EFAFAFA0500000000000000000000\n      000000000000000000000000000000000000000000000000000000000000CDCD\n      CD3223262CEE171C24FE1C2129FF191E22FF10151DFF060953FF2A3371FF0517\n      84FF213477FF303346FF353A47FF3B414BFF282C34FFC7C7C738000000000000\n      00000000000000000000000000000000000000000000B2B2B14E0D0F12FF0C0E\n      14FF0A0E23FF0D1021FF0F132BFF0D1139FF262A38FF1F243EFF161823FF171B\n      22FF181C20FF171A21FF131720FF65666BA6F0F0F00F00000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      00000000000000000000D7D7D7282B2B2BD4000000FF060707FE728789FFC5EA\n      EEFF94AEB1FF202626FF000000FF000000FF060606FF1C1C1CFF48494AFFA4BC\n      BFFFCCEFF3FFCEF1F4FFC8ECEFFFC6EBEEFFC5EAEDFFC0E5E9FFC1E5E9FFC4E8\n      EDFFC4E9ECFFC7EBEEFFC4E9EDFFC0E6EAFFC5EBEFFF9FBCBFFF5F7173FF3B46\n      47FF455051FF7C8F90FFC3E4E7FFC9EDF0FFC4E9ECFFBFE4E8FFC3E8ECFFC5EA\n      EEFFC6EBEEFFC1E6EBFFC5EAEEFFBEE0E4FFA6C2C5FFB1D1D4FF9FBDBFFF91AB\n      AFFF8AA4A6FF88A2A4FF8AA3A6FF859C9FFF181D1DFF000000FF000000FF0000\n      00FF000000FF000000FF000000FF000000FF242C2DFF81999CFF88A2A4FF88A1\n      A4FF8DA7A9FF90A9AAFF91A9ABFF7F9799FF191E1EFF000000FF000000FF0000\n      00FF000000FF000000FF3C4849FF90AAACFF8BA4A7FF869FA2FF86A0A3FF8AA4\n      A7FF89A2A4FF8CA4A7FF89A2A5FF607275FF0D0F10FE000000FF050505FA7171\n      718EF4F4F40B0000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000007F7F7F80000000FF0C0E0FFFB7CDDBFFD7F0FFFFD6EFFFFFD6EF\n      FFFFD6EFFFFFD6EFFFFFE0FAFFFF474F54FF000000FF000000FF000000FF1619\n      1AFFD5EEFEFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD5EE\n      FEFFD4EDFCFF485156FF030303FFC4DBEAFFD7F1FFFFD6EFFFFFD6EFFFFFD6EF\n      FFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD5EEFEFFDCF6FFFFCCE4F3FFD4ED\n      FDFFD8F1FFFFD5EEFEFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EF\n      FFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFC3E7FFFFAFDFFFFFB0E0FFFFAFDF\n      FEFFB2E2FFFFB8EAFFFF5F798AFF000000FF194648FF49CDD2FF4CD4D9FF4CD4\n      D9FF4CD4D9FF4CD4D9FF4CD4D9FF4CD4D9FF4CD4D9FF4BD3D8FF4FDFE4FF1845\n      46FF000000FF000000FFE1E1E11E000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000D6D6D6291010\n      10EF000000FF000000FF000000FF000000FF606060FFFFFFFFFFF5F5F5FFF5F5\n      F5FFF5F5F5FFF5F5F5FFF5F5F5FFF5F5F5FFEBEBEBFF484848FF000000FF0000\n      00FF000000FF000000FF191919FFE3E3E3FFE2E2E2FF656565FF9B9B9BFF2A2A\n      2AFFC1C1C1FFF9F9F9FFF5F5F5FFF5F5F5FFF5F5F5FFF8F8F8FF686868FF0101\n      01FF070707FF999999FF4F4F4FFFC0C0C0FFEDEDEDFF717171FF000000FF0000\n      00FF000000FF000000FF000000FFDCDCDCFFF5F5F5FFF5F5F5FFF5F5F5FFF5F5\n      F5FFF5F5F5FFF4F4F4FFF8F8F8FFD6D6D6FF000000FF000000FF000000FF0101\n      01FE020202FD7777778800000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      00000000000000000000000000000000000000000000E8E8E81726292CE7141A\n      1EFF11141AFF0C0D13FF10131DFF1A1F26FF181F22FF0D101DFF232A34FF1B22\n      3BFF0A0B34FF05054AFF080832FB7E7E7F87F5F5F50A00000000000000000000\n      000000000000000000000000000000000000000000000000000000000000DCDC\n      DC232C2E32E21A1D26FF1B1F27FF1A1F27FF282E35FF2C326DFF4E5B7FFF3A3F\n      51FF08143FFF001675FF616983FE818892FF585A5FCEECECEC13000000000000\n      00000000000000000000000000000000000000000000828282840B0C11FF0F0F\n      15FF0E1316FF111419FF0E1125FF0B0F37FF22272CFF232836FF32353EFF2A2F\n      37FF292D36FF262C31FF191D25FF68696C9FF4F4F40B00000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      00000000000000000000FDFDFD029595956A080808F7000000FF1A2020FFA0BF\n      C2FFC2E7EBFF98B6BAFF445354FF141718FF0B0C0CFF2A2D2DFF839495FFC6E8\n      EBFFC0E5E9FFBCE2E5FFC4E9ECFFCFF2F4FFCFF3F6FFCDF1F4FFC2E7EBFFBFE5\n      E9FFC1E6EBFFC0E5E9FFCCF0F3FFCAEEF3FFCCF0F3FFCAEFF1FFC0E4E8FFB3D6\n      D9FFB5D7DBFFC0E3E7FFC3E8ECFFBCE2E7FFC2E8ECFFC4E8ECFFC1E7EAFFC8EC\n      EFFFCDF0F3FFCEF1F4FFD1F4F6FFCAEEF1FFBDE0E4FFB6D9DDFFAACACEFF95B3\n      B7FF88A3A7FF849FA3FF8CA5A7FF8FA8AAFF566668FF000000FF000000FF0000\n      00FF000000FF000000FF000000FF000000FF394546FF839DA0FF87A0A4FF89A3\n      A6FF8AA3A6FF89A2A5FF89A2A5FF8BA6A8FF607274FF030404FF000000FF0000\n      00FF000000FF010202FF6F8588FF87A2A4FF8CA6A8FF8AA4A7FF8DA6A9FF8EA8\n      AAFF86A0A3FF8AA3A6FF6C8083FF141818FE000000FF000000FF585858A7EDED\n      ED12000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      000000000000D0D0D02F0F0F0FF0010101FE717E87FFD7F0FFFFD6EFFFFFD6EF\n      FFFFD6EFFFFFD6EFFFFFDCF6FFFF7A8891FF000000FF000000FF000000FF1113\n      14FFBED5E3FFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EF\n      FFFFD6EFFFFFC2D9E8FF131617FF78878FFFDDF6FFFFD6EFFFFFD6EFFFFFD6EF\n      FFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD5EEFEFFD5EEFEFFD6EFFFFFD6EF\n      FFFFD5EEFEFFD6EFFFFFD6EFFFFFD6EFFFFFD5EEFEFFD7F0FFFFD8F1FFFFD5EE\n      FEFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFC1E7FFFFAFDFFFFFB0E0FFFFB0E0\n      FFFFB4E5FFFF556D7BFF000000FF010506FF42BABEFF4FDCE1FF4CD4D9FF4CD4\n      D9FF4CD4D9FF4CD4D9FF4CD4D9FF4CD4D9FF4CD4D9FF4CD4D9FF4EDBE0FF2975\n      77FF010101FE000000FFBFBFBF40000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000005151\n      51AE000000FF010101FE000000FF000000FF0E0E0EFFDCDCDCFFF7F7F7FFF4F4\n      F4FFF5F5F5FFF5F5F5FFF5F5F5FFF5F5F5FFF1F1F1FF797979FF000000FF0000\n      00FF010101FF2C2C2CFF9E9E9EFFA3A3A3FF2E2E2EFF000000FF000000FF2C2C\n      2CFFFFFFFFFFF4F4F4FFF5F5F5FFF4F4F4FFF7F7F7FF959595FF090909FF0000\n      00FF000000FF000000FF040404FF000000FF7C7C7CFFB6B6B6FF545454FF0606\n      06FF000000FF000000FF121212FFE5E5E5FFF4F4F4FFF5F5F5FFF5F5F5FFF5F5\n      F5FFF5F5F5FFF5F5F5FFFFFFFFFF505050FF000000FF000000FF000000FF0000\n      00FF111111EEDFDFDF2000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      00000000000000000000000000000000000000000000EEEEEE114D4E4FC0171C\n      24FF171C24FF141820FF161A24FF1F272EFF15192DFF12152BFF050948FF0405\n      3CFF0A0B11FF070719FF040518FF38393FCFDADADA2500000000000000000000\n      000000000000000000000000000000000000000000000000000000000000EBEB\n      EB143D3E41CE191F27FF20252DFF4A5059FF646E86FF6979A5FF8F969FFF7881\n      8CFF6E7581FF757A7EFF2D365BFF384059FF9797986DFCFCFC03000000000000\n      000000000000000000000000000000000000FBFBFB047E7E7E850C0D0FFF1012\n      17FF11141AFF12161BFF0D1016FF060A45FF08104FFF363941FF383C45FF262B\n      33FF171C32FF0D144AFF1B1E24FE6C6D709DF3F3F30C00000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000EDEDED124C4C4CB3000000FF000000FF4855\n      56FEBBDFE2FFC3E8ECFFC5E9ECFFA9CACCFF94B0B3FFAAC7C9FFC9ECEDFFCFF2\n      F5FFC9EEF2FFC3E8ECFFC0E5E9FFC6EBEDFFD0F3F5FFCAEDF0FFC4E9ECFFC6EA\n      EDFFC6EBEEFFCAEEF1FFC5EAEDFFC2E7EAFFC6EAEDFFC8EDF0FFCCF0F4FFCDF1\n      F4FFCDF1F3FFC8ECEFFFC7EBEFFFCCEFF1FFC8ECF0FFC9EDF1FFC6EBEEFFC4E8\n      ECFFCBEEF1FFCDF1F3FFC3E8ECFFC2E6EAFFBFE4E9FFC4E9ECFFC0E1E4FFA9C7\n      CAFF97B3B6FF90AAACFF88A2A5FF849FA1FF87A1A3FF212728FF000000FF0000\n      00FF000000FF000000FF000000FF020303FF546364FF8BA5A7FF8AA3A5FF8CA6\n      A8FF86A0A3FF849EA0FF839DA0FF86A0A3FF88A1A4FF374344FF000000FF0000\n      00FF000000FF323B3CFF92ACAEFF88A2A4FF86A0A2FF88A2A4FF8CA5A8FF89A2\n      A5FF89A1A4FF778D90FF1E2323FF000000FF000000FF3E3E3EC1E8E8E8170000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      00000000000000000000484848B7000000FF272B2EFEC8DFEEFFD6EFFFFFD6EF\n      FFFFD6EFFFFFD6EFFFFFD7F0FFFFD2EAF9FF000000FF000000FF000000FF1113\n      14FFC1D7E6FFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EF\n      FFFFD5EEFEFFD6EFFFFFDCF5FFFFD7F0FFFFD5EEFEFFD6EFFFFFD6EFFFFFD6EF\n      FFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EF\n      FFFFD6EFFFFFD6EFFFFFD5EEFEFFD6EFFFFFD5EEFEFFA5B7C4FFAABFCBFFD6F0\n      FFFFD6EFFFFFD6EFFFFFD6EFFFFFD5EEFFFFBFE5FFFFAFDFFFFFB0E0FFFFB0E0\n      FFFFB5E7FFFF3B4C56FF050708FF000000FF000000FF276F71FF47C7CCFF4CD5\n      DAFF4BD3D8FF4BD3D8FF4CD4D9FF4CD4D9FF4CD4D9FF4CD4D9FF4DD8DDFF3698\n      9CFF000000FF000000FF9A9A9A65000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      000000000000000000000000000000000000000000000000000000000000DFDF\n      DF20000000FF000000FF000000FF000000FF020202FF747474FFFCFCFCFFF5F5\n      F5FFF5F5F5FFF5F5F5FFF5F5F5FFF5F5F5FFF6F6F6FFA8A8A8FF000000FF0000\n      00FF010101FF262626FF2B2B2BFF000000FF000000FF000000FF000000FFABAB\n      ABFFF7F7F7FFF5F5F5FFF4F4F4FFFFFFFFFF9B9B9BFF080808FF000000FF0000\n      00FF000000FF000000FF000000FF000000FF000000FF191919FF343434FF0707\n      07FF000000FF000000FF515151FFECECECFFF5F5F5FFF5F5F5FFF5F5F5FFF5F5\n      F5FFF4F4F4FFF8F8F8FFCCCCCCFF0B0B0BFF000000FF000000FF010101FE0000\n      00FF5F5F5FA00000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      00000000000000000000000000000000000000000000F5F5F50A505152BC1518\n      1FFF141721FF0E1123FF0F1240FF151935FF171B28FF1E2227FF151718FF0A0B\n      3CFF191D23FF14171CFF101316FF0E1013FFA2A2A25FFEFEFE01000000000000\n      000000000000000000000000000000000000000000000000000000000000F5F5\n      F50A4D4E51C5252932FF383B46FF596484FF567EB6FFCACFD4FF959DA8FF9097\n      A3FF99A2AEFF747D8BFF4A505AFF4D5159EEC9C9CA3800000000000000000000\n      000000000000000000000000000000000000F6F6F609525354B70D0F12FF1012\n      18FF101419FF0F1215FF12161AFF14181AFF11131FFF282A38FF3A3C45FF1418\n      2CFF141730FF11173AFF161825FF656669A4F4F4F40B00000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      000000000000000000000000000000000000D0D0D02F1D1D1DE2000000FF0304\n      04FE7C9193FFCBEFF2FFC9EEF0FFCBF0F3FFC7ECF0FFC5EAEDFFC5E9EDFFCDF1\n      F2FFCEF1F4FFC7ECEFFFC3E8EBFFC3E8ECFFC6EBEFFFC4E8EDFFC7EBEFFFC8EC\n      F0FFC4E8ECFFC1E5E9FFC0E5E9FFC3E9EDFFC3E8ECFFC8ECF0FFCAEEF1FFC4E9\n      EDFFBFE4E8FFC1E6E9FFC0E5E9FFC5E9EDFFC5E9ECFFC3E7EBFFC1E6E9FFC0E5\n      E8FFBFE5E9FFC0E5EAFFC0E6EAFFC4E8ECFFC7EAEDFFC7EBEEFFBEE3E7FFB1D3\n      D6FF9FBEC1FF93AEB0FF89A3A5FF859FA1FF89A2A4FF6B8082FF080909FF0000\n      00FF000000FF000000FF000000FF08090AFF6E8284FF91AAABFF8EA7A9FF89A2\n      A5FF89A3A6FF8CA5A7FF89A2A4FF89A3A5FF859DA1FF354142FF000101FF0000\n      00FF050606FF708486FF8CA5A7FF8AA2A5FF859FA2FF88A1A4FF8BA4A6FF89A3\n      A5FF7A9294FF2D3638FF010101FE000000FF2D2D2DD2CBCBCB34000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      00000000000000000000E0E0E01F000000FF000000FF8D9EA8FFD9F3FFFFD5EE\n      FEFFD6EFFFFFD6EFFFFFD5EEFEFFDBF5FFFF7C8A94FF000000FF000000FF2226\n      29FFDAF4FFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EF\n      FFFFD6EFFFFFD5EEFEFFD6EFFFFFD6EFFFFFD5EEFEFFD6EFFFFFD6EFFFFFD6EF\n      FFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EF\n      FFFFD6EFFFFFD6EFFFFFD6EFFFFFD8F2FFFF6D7A82FF000000FF8A9AA4FFD7F1\n      FFFFD6EFFFFFD6EFFFFFD6EFFFFFD4EEFFFFBCE4FFFFAFDFFFFFB0E0FFFFB0E0\n      FFFFAFDFFEFFB2E3FFFF88AEC6FF506674FF050607FF000000FF102E2FFF3DAA\n      AEFF4EDBE1FF4BD3D8FF4CD4D9FF4CD4D9FF4CD4D9FF4CD4D9FF4DD7DCFF3FAF\n      B3FF000000FF000000FF8181817E000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000565656A9000000FF010101FE000000FF000000FF2D2D2DFFD8D8D8FFF5F5\n      F5FFF5F5F5FFF5F5F5FFF5F5F5FFF5F5F5FFF5F5F5FFC8C8C8FF1D1D1DFF0000\n      00FF000000FF000000FF000000FF000000FF000000FF000000FF040404FFE1E1\n      E1FFF5F5F5FFF4F4F4FFFDFDFDFFABABABFF010101FF000000FF000000FF0000\n      00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000\n      00FF000000FF000000FF8A8A8AFFF4F4F4FFF5F5F5FFF5F5F5FFF5F5F5FFF5F5\n      F5FFF5F5F5FFFDFDFDFF656565FF000000FF000000FF000000FF000000FF0000\n      00FFEBEBEB140000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      00000000000000000000000000000000000000000000F9F9F9066F6F7099181B\n      23FF191E24FE10151FFF0A1256FF1A1D2BFF131614FF161B27FF0B0F51FF0C0C\n      27FF151924FF13161CFF0F1114FF060607FF5F6060A8F6F6F609000000000000\n      000000000000000000000000000000000000000000000000000000000000FDFD\n      FD027A7A7B8D3E414BFF848A96FE939DABFF6A7588FF75839CFF7A8494FF94A1\n      B3FFACB4BEFFA8B1BCFE959EA9FF7C7F84B4EBEBEB1400000000000000000000\n      000000000000000000000000000000000000EBEBEB14343637D4101217FF1216\n      1DFF0F1116FF0F1114FF111519FF14191CFF0D1033FF282C53FF2D323FFF262B\n      37FF2B2F36FF222831FF13171CFF6E707297F7F7F70800000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      000000000000000000000000000000000000000000009595956A030303FC0000\n      00FF1D2223FF9BBABEFFBEE3E8FFC7ECF0FFCBF0F2FFC3E9EDFFC0E5E9FFC0E6\n      E9FFC5EAECFFC9EDF1FFCEF1F4FFC3E8ECFFBFE5E9FFC6EAEEFFC8ECEFFFC7EC\n      EFFFC4E8ECFFBEE3E7FFC0E5E9FFC3E7EBFFC5E9EDFFC4E9EDFFC1E6EAFFBEE3\n      E7FFBCE1E6FFC3E7ECFFC6EBEEFFC4E9ECFFCDF1F4FFCFF3F6FFC2E8ECFFBBE1\n      E5FFB8DEE4FFBFE5E9FFCCF0F3FFCEF1F4FFCCEFF3FFCEF2F5FFC8ECEFFFC2E4\n      E8FFABCBCFFF93B0B3FF87A2A5FF869FA2FF86A0A2FF859EA0FF495658FF0101\n      01FF000000FF000000FF000000FF0C0E0EFF7D9395FF8EA8AAFF8DA6A9FF88A2\n      A4FF89A2A5FF8DA6A8FF93ACAEFF809597FF374243FF020303FF000000FF0000\n      00FF3E4A4AFF89A2A4FF86A1A3FF859EA2FF8BA4A7FF8CA5A8FF87A1A4FF859F\n      A1FF3D4747FF020202FE000000FF141414EBB3B3B34CFEFEFE01000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      00000000000000000000000000007474748B000000FF0D0E0FFEDBF4FFFFD6EF\n      FFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD1E9F9FF717E87FF2A2E31FFAFC4\n      D1FFD9F2FFFFD5EEFEFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EF\n      FFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EF\n      FFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EF\n      FFFFD5EEFEFFD5EEFEFFD7F0FFFF5F6A71FF010202FF0C0D0EFFAEC2CFFFD7F0\n      FFFFD6EFFFFFD6EFFFFFD6EFFFFFD3EEFFFFB8E3FFFFAFDFFFFFB0E0FFFFB0E0\n      FFFFAFDFFEFFB0E0FFFFB1E1FFFFAFDFFDFF92B9D3FF171D21FF000000FF0612\n      13FF389EA2FF4CD5DAFF4CD4D9FF4CD4D9FF4CD4D9FF4CD4D9FF4CD6DBFF43BB\n      BFFF000000FF000000FF7474748B000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000DCDCDC23000000FF000000FF000000FF000000FF000000FF9B9B9BFFF5F5\n      F5FFF4F4F4FFF5F5F5FFF5F5F5FFF5F5F5FFF5F5F5FFE5E5E5FF393939FF0000\n      00FF000000FF000000FF000000FF000000FF000000FF000000FF1C1C1CFFE6E6\n      E6FFF5F5F5FFF7F7F7FFDADADAFF0C0C0CFF000000FF000000FF000000FF0000\n      00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000\n      00FF000000FF060606FFB2B2B2FFF6F6F6FFF5F5F5FFF5F5F5FFF5F5F5FFF5F5\n      F5FFF5F5F5FFD1D1D1FF252525FF000000FF000000FF010101FE000000FF5D5D\n      5DA2000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      00000000000000000000000000000000000000000000FCFCFC038A8A8B770F11\n      14FF09091CFF090E4EFF151C2DFF15192BFF04065DFF021083FF151936FF2126\n      2CFF0F1427FF161C23FF111419FF0E0F12FF232426E6E5E5E51A000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000C7C7C738525963FFC2CAD1FFC1C9CFFE98A1AFFF22306EFF303F87FFB7BE\n      C1FEB0B8C0FFA1AAB5FF75797ED7CCCCCC33FDFDFD0200000000000000000000\n      000000000000000000000000000000000000DBDBDB24242428E70E1114FF0F12\n      15FF0E1017FF0E1115FF0F1115FF0D1017FF0C0C1EFF181A1BFF292E34FF2E34\n      3CFF252931FF222A31FF1F242CFA8A8B8C7BFAFAFA0500000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      00000000000000000000000000000000000000000000EEEEEE114E4E4EB10101\n      01FE010101FE4E5C5DFFC5E8EAFFD2F4F7FFCDF1F4FFC8ECF0FFC8EDF0FFBFE5\n      E8FFBFE4E8FFCDF0F3FFCEF2F5FFC8EDEFFFBEE3E7FFC2E6EAFFCAEEF2FFCAEE\n      F2FFC9EDF0FFC1E6EAFFBFE5E9FFC1E6EAFFBCE2E7FFBAE0E4FFBDE3E7FFC1E6\n      EAFFC6EBEEFFC7ECEFFFC0E6EAFFC3E8EBFFCAEFF1FFD1F4F6FFD3F5F8FFD1F4\n      F7FFC9EEF1FFC5EAEDFFC5E9EDFFC5EBEEFFC8ECF0FFC5E9EDFFC9EDF1FFCDF0\n      F3FFBFE0E3FFA3C1C5FF92ACB0FF8DA7AAFF8DA6A9FF8BA4A6FF8DA6A7FF3740\n      42FF000000FF000000FF000000FF010101FF262D2EFF57696AFF73898CFF778C\n      8EFF778C8EFF708688FF465456FF0D1011FF000000FF000000FF000000FF1E24\n      25FF7F989AFF87A2A4FF8BA3A6FF89A3A5FF8CA6A8FF8EA7A9FF88A1A3FF4D5B\n      5DFF010101FE000000FF0C0C0CF39393936C0000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000EEEEEE11191919E6000000FF5D686FFFDCF6\n      FFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFDAF4FFFFDEF9FFFFD7F0\n      FFFFD5EEFEFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EF\n      FFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EF\n      FFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD5EEFEFFD6EF\n      FFFFD7F0FFFFCBE3F2FF4C555BFF000000FF000000FF2C3135FFDEF8FFFFD6EF\n      FFFFD6EFFFFFD6EFFFFFD5EFFFFFD3EDFFFFB4E1FFFFAFDFFFFFB0E0FFFFB0E0\n      FFFFB0E0FFFFB0E0FFFFB0E0FFFFAFDFFEFFB1E2FFFF8AAFC8FF090C0EFF0000\n      00FF071616FF44BEC2FF4CD4D9FF4CD4D9FF4CD4D9FF4CD4D9FF4CD6DBFF41B7\n      BBFF000000FF000000FF7575758A000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000F9F9F906535353AC000000FF010101FE000000FF000000FF393939FFEBEB\n      EBFFF4F4F4FFF5F5F5FFF5F5F5FFF5F5F5FFF5F5F5FFFDFDFDFF5C5C5CFF0000\n      00FF000000FF000000FF000000FF000000FF000000FF000000FF181818FFE6E6\n      E6FFF4F4F4FFFCFCFCFF898989FF040404FF000000FF000000FF000000FF0000\n      00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000\n      00FF000000FF252525FFD0D0D0FFF5F5F5FFF5F5F5FFF5F5F5FFF5F5F5FFF5F5\n      F5FFF4F4F4FF909090FF000000FF000000FF000000FF000000FF000000FFD8D8\n      D827000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      00000000000000000000000000000000000000000000FDFDFD029494956D1114\n      19FF111619FF14171AFF12182FFF21283CFF202432FF1B1C2CFF33383EFF2325\n      33FF111421FF0E1021FF0F111AFF0E0F14FF0F1013FBC3C3C33C000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000F5F5F50A888A8D9899A1A8FFB8C0CAFF909AA6FE3D4975FE5C6986FEB4BC\n      C3FF9DA5AEFF767B7FCBC4C4C43BFDFDFD020000000000000000000000000000\n      0000000000000000000000000000FEFEFE01C0C0C041191A1EF10F1011FF0909\n      0DFF070716FF070810FF08090FFF0A0B19FF292E43FF32406BFF283A78FF2932\n      47FF22292FFF21272EFF1E242AF89C9C9D69FDFDFD0200000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000BEBEBE411818\n      18E7000000FF0B0D0DFE869FA2FFC8EDF1FFC7EAEEFFC4E9EBFFC4E9EDFFC6EB\n      EFFFC8ECEFFFCBEFF2FFCAEDF1FFC7EBEFFFC3E8ECFFC1E6EAFFC1E6EAFFC4E8\n      ECFFC5E9EDFFC9EDF0FFCCF0F2FFCDF0F4FFC9ECF0FFC9EDEFFFC6EAEDFFC7EC\n      EFFFCAEEF1FFC2E7EAFFC2E6EAFFC0E5E9FFB9DFE3FFC0E4E9FFC9EDF1FFCCF0\n      F3FFCBEFF2FFC7EBEFFFC1E7EBFFC2E7EBFFC6EAEEFFC1E5EAFFBFE5E9FFC3E7\n      ECFFC5E8EBFFB7D6D8FFA1BDBFFF90ABADFF8CA6A9FF8AA3A6FF8AA4A6FF89A1\n      A4FF414D4EFF020303FF000000FF000000FF000000FF000000FF080A09FF0B0D\n      0DFF0B0D0DFF070909FF000000FF000000FF000000FF000000FF212728FF7A91\n      93FF8DA7A9FF8BA4A7FF8BA4A6FF88A2A5FF89A2A5FF86A0A2FF5A6B6DFF0C0E\n      0FFE000000FF040404FB7F7F7F80F9F9F9060000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000009292926D040404FB060607FFA6BA\n      C6FFD7F1FFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EF\n      FFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EF\n      FFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EF\n      FFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD5EEFEFFD6EF\n      FFFF8C9CA6FF1F2224FF000000FF000000FF000000FFABBFCCFFDAF3FFFFD5EE\n      FEFFD6EFFFFFD6EFFFFFD6EEFFFFD1EDFFFFAFDFFFFFAFDFFFFFB0E0FFFFB0E0\n      FFFFB0E0FFFFB0E0FFFFB0E0FFFFB0E0FFFFAFDFFEFFB9EBFFFF3C4D57FF0000\n      00FF000000FF226062FF4DD9DEFF4CD4D9FF4CD4D9FF4CD4D9FF4DD7DDFF3BA4\n      A8FF000000FF000000FF8C8C8C73000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      000000000000B2B2B24D070707F8000000FF000000FF000000FF000000FFB8B8\n      B8FFF7F7F7FFF5F5F5FFF5F5F5FFF5F5F5FFF4F4F4FFFCFCFCFF939393FF0606\n      06FF000000FF000000FF000000FF010101FF000000FF000000FF000000FFDDDD\n      DDFFF5F5F5FFFBFBFBFF9E9E9EFF010101FF000000FF000000FF000000FF0000\n      00FF000000FF000000FF000000FF000000FF060606FF000000FF000000FF0000\n      00FF000000FF414141FFEFEFEFFFF5F5F5FFF5F5F5FFF5F5F5FFF5F5F5FFF4F4\n      F4FFECECECFF2A2A2AFF000000FF000000FF010101FE000000FF595959A6FAFA\n      FA05000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      00000000000000000000000000000000000000000000FDFDFD0299999A691418\n      1EFF15191DFF111426FF1A2029FF2F3237FF363C42FF1F2359FF07158AFF1619\n      23FF1E2229FF161922FF0F1115FF0F0F11FF090A0DFF8F8F8F76000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000FEFEFE01EAEAEA159B9C9D7463686DE68E95A0FFA8B3C2FFA4ADB7FF7983\n      8BFF727579C0D1D1D12EFCFCFC03000000000000000000000000000000000000\n      0000000000000000000000000000FBFBFB049F9F9F660F1012F708080EFE0303\n      17FF05050BFF060619FF040421FF0C0E19FF161A25FF121627FF06166BFF0A0D\n      2CFF0F1322FF13151DFE1E1F26F2BDBDBD44FEFEFE0100000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000008484\n      847B000000FF000000FF22292AFEA5C5C9FFC2E7EBFFC0E5E9FFC5EAEEFFCCF0\n      F2FFCCF0F3FFC7ECEFFFC3E7EBFFBDE2E7FFC2E7EBFFCCEFF3FFC4E8ECFFBDE2\n      E6FFC0E5E9FFC9ECF0FFC2E7EBFFBDE2E6FFC8ECEFFFCAEEF0FFC6EBEEFFC5E9\n      ECFFC5EAEDFFC6EBEEFFC9EDF0FFCAEEF1FFC5EAEDFFC0E5E9FFC3E7EBFFC7EC\n      EFFFC6EAEEFFC0E5E9FFBEE4E8FFC1E6EAFFC6EBEFFFC6EAEEFFC0E6E9FFBDE2\n      E7FFC0E5E9FFB9DBDFFFAAC8CBFF9BB6B8FF91A9ABFF89A2A5FF859FA1FF86A0\n      A3FF829A9DFF5A6B6DFF0A0B0CFF000000FF000000FF000000FF000000FF0000\n      00FF000000FF000000FF000000FF000000FF000000FF333D3EFF7B9295FF869F\n      A2FF839EA0FF839DA0FF859FA2FF869FA3FF849FA2FF64777AFF111516FF0101\n      01FE020202FD5E5E5EA1EFEFEF10000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      000000000000000000000000000000000000E0E0E01F141414EB000000FF3C43\n      48FFCFE7F6FFD5EEFEFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EF\n      FFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EF\n      FFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EF\n      FFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFDAF4FFFF707D\n      85FF000000FF000000FF000000FF000000FF606B73FFDBF4FFFFD6EFFFFFD6EF\n      FFFFD6EFFFFFD6EFFFFFD6EFFFFFCBEAFFFFAEDFFFFFAFE0FFFFB0E0FFFFB0E0\n      FFFFB0E0FFFFB0E0FFFFB0E0FFFFB0E0FFFFAFDFFEFFB4E5FFFF7595AAFF0000\n      00FF000000FF0C2223FF4FDDE2FF4CD4D9FF4CD4D9FF4CD4D9FF4EDADFFF2D7F\n      83FF010101FE000000FFBCBCBC43000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      000000000000EFEFEF103B3B3BC4000000FF000000FF000000FF000000FF2F2F\n      2FFFFFFFFFFFF4F4F4FFF5F5F5FFF5F5F5FFF5F5F5FFF8F8F8FFCFCFCFFF0D0D\n      0DFF000000FF000000FF080808FF6D6D6DFF000000FF000000FF000000FF7878\n      78FFFCFCFCFFF5F5F5FFF8F8F8FF565656FF000000FF000000FF000000FF0000\n      00FF000000FF000000FF000000FF000000FF1A1A1AFF5C5C5CFF000000FF0000\n      00FF010101FF6A6A6AFFFDFDFDFFF5F5F5FFF5F5F5FFF5F5F5FFF5F5F5FFF7F7\n      F7FFA9A9A9FF000000FF000000FF000000FF000000FF040404FBB3B3B34C0000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      00000000000000000000000000000000000000000000FEFEFE01A7A7A8591116\n      19FF0E132DFF0E0F21FF111734FF11164BFF1A1F3FFF23283CFF232832FF4146\n      50FF171C23FF191E25FF0F1115FF0F0F0FFF0A0A0BFF6B6B6B9FF8F8F8070000\n      0000000000000000000000000000000000000000000000000000000000000000\n      00000000000000000000FBFBFB04D9D9D92687888987808284C07C7D7D95AFAF\n      AF50EEEEEE11FEFEFE0100000000000000000000000000000000000000000000\n      0000000000000000000000000000EDEDED125D5D5DA70A0A0AFE0C0C0DFF0D0E\n      0EFF0E0F11FF111517FF1C2124FF434752FF454B57FF30353DFF2A2E31FF252A\n      2FFF21292EFF1B1F27FF303235DEE3E3E31C0000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      000000000000000000000000000000000000000000000000000000000000ECEC\n      EC133B3B3BC4000000FF000000FF49595AFFB8DDE1FFBEE4E8FFC4E9ECFFC6EB\n      EEFFC6EAEEFFBEE3E7FFBBE1E5FFC2E7EAFFBDE2E7FFB9DFE3FFBEE4E9FFBDE2\n      E7FFC1E6EAFFC8EDEFFFC9ECF0FFC5E9EDFFC2E7ECFFC3E8EBFFC7EBEFFFCCF0\n      F4FFCAEFF2FFD0F3F6FFCCEFF3FFC6EBEDFFCCEFF3FFC6EBEFFFC3E7EBFFC2E7\n      EAFFC7EBEEFFC7ECEFFFC5EAEDFFC2E6EAFFC4E8ECFFCAEEF2FFC8ECF0FFC4E8\n      ECFFBBE1E6FFB7DBDFFFABCCD0FF97B4B7FF8DA8AAFF92AAACFF90A9ABFF8CA5\n      A7FF8BA5A7FF8EA8AAFF819799FF3F4A4CFF121616FF060808FF030303FF0101\n      02FF020202FF030404FF080909FF1E2324FF5B6C6EFF87A1A4FF839EA1FF88A1\n      A3FF8AA3A6FF87A1A4FF879FA2FF8AA3A6FF7A9092FF1F2626FE000000FF0000\n      00FF404040BFE0E0E01F00000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000009C9C9C63040404FB000000FF0000\n      00FF8798A2FFDAF3FFFFD5EEFEFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EF\n      FFFFD6EFFFFFD5EEFEFFD6EFFFFFD5EEFEFFD6EFFFFFD6EFFFFFD6EFFFFFD6EF\n      FFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EF\n      FFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFBBD1\n      DFFF101213FF000000FF000000FF212427FFCBE3F2FFD5EEFEFFD6EFFFFFD6EF\n      FFFFD6EFFFFFD6EFFFFFD6EFFFFFC2E7FFFFAEDFFFFFB0E0FFFFB0E0FFFFB0E0\n      FFFFB0E0FFFFB0E0FFFFB0E0FFFFB0E0FFFFAFDFFEFFB4E5FFFF7798ADFF0000\n      00FF000000FF0C2323FF4FDDE2FF4CD4D9FF4CD4D9FF4BD3D8FF4FDEE3FF1A49\n      4AFF000000FF060606F9E8E8E817000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      000000000000000000008E8E8E71050505FA010101FE000000FF000000FF0000\n      00FFBABABAFFFAFAFAFFF4F4F4FFF5F5F5FFF5F5F5FFF5F5F5FFFFFFFFFF2222\n      22FF050505FF0F0F0FFFAAAAAAFF666666FF000000FF000000FF000000FF0000\n      00FFC3C3C3FFF7F7F7FFF5F5F5FFFFFFFFFF9E9E9EFF1F1F1FFF040404FF0000\n      00FF000000FF000000FF000000FF000000FF101010FFC7C7C7FF383838FF0606\n      06FF0E0E0EFFAEAEAEFFFAFAFAFFF5F5F5FFF5F5F5FFF5F5F5FFF5F5F5FFFBFB\n      FBFF242424FF000000FF000000FF000000FF000000FF3D3D3DC2EDEDED120000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000B9B9B9471518\n      1FF80C0E17FF0B0F34FF12163BFF202B4CFF2E353EFF3A4049FF3D434BFF4A51\n      5DFF171D22FF191E25FF12161BFF0F1012FF0C0C0DFF333334D6E5E5E51A0000\n      0000000000000000000000000000000000000000000000000000000000000000\n      000000000000000000000000000000000000FEFEFE01FAFAFA05FCFCFC030000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000C8C8C83819191AEE0C0E10FF0F1217FF0F13\n      18FF12161BFF161B23FF2C3239FF4C5460FF494E5BFF3D424CFF3B3E48FF252A\n      31FF191B22FF191C23FF4E4F51BCF3F3F30C0000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000BFBFBF401B1B1BE4000000FF0A0D0DFF89A1A4FFCBF0F3FFC9EDF0FFC5EA\n      EDFFC5EAEEFFC3E8ECFFC3E8ECFFC8ECEEFFCDF1F4FFCAEEF1FFCAEEF1FFC6EB\n      EEFFC4E9EDFFC6EBEFFFCDF1F4FFCEF1F4FFC7EBEEFFC5E9ECFFC4E8ECFFC4E8\n      ECFFC4E9EDFFC7EBEEFFCCEFF2FFCEF1F4FFCBEFF2FFC3E8EDFFC0E4E9FFC1E5\n      E9FFC5E9EDFFC9EDEFFFCEF3F4FFCCEFF1FFC6EBEEFFC5EAEEFFC6EBEEFFC7EC\n      F0FFC8ECF0FFC8ECEFFFB9DBDFFFA3C2C6FF91AEB1FF8DA6A8FF8CA4A6FF8CA4\n      A6FF88A1A3FF849EA0FF87A1A3FF8BA5A7FF7E9698FF65797BFF546465FF505E\n      5FFF576667FF5C6E70FF728688FF87A0A2FF8DA8ABFF8AA3A6FF8BA4A7FF8AA3\n      A5FF88A1A4FF88A2A4FF89A3A5FF7F9698FF2D3636FF000000FF000000FF3030\n      30CFD7D7D7280000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000F9F9F906575757A8000000FF2D6166FF0000\n      00FF030304FFB2C7D4FFDBF4FFFFD5EEFEFFD5EEFEFFD6EFFFFFD8F1FFFFDBF4\n      FFFFDEF8FFFFE0FBFFFFE2FCFFFFDCF6FFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EF\n      FFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EF\n      FFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD5EEFEFFD7F0\n      FFFFA5B8C4FF181B1DFF060707FF9BAEB9FFD7F0FFFFD6EFFFFFD6EFFFFFD6EF\n      FFFFD6EFFFFFD5EEFFFFD7EFFFFFB8E3FFFFAFDFFFFFB0E0FFFFB0E0FFFFB0E0\n      FFFFB0E0FFFFB0E0FFFFB0E0FFFFB0E0FFFFAFDFFEFFB9ECFFFF475B67FF0000\n      00FF000000FF163F40FF4EDBE0FF4CD4D9FF4CD4D9FF4CD4D9FF4CD5DAFF0919\n      1AFF000000FF3B3B3BC4F2F2F20D000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      00000000000000000000F2F2F20D1A1A1AE5000000FF000000FF000000FF0000\n      00FF393939FFFCFCFCFFF5F5F5FFF5F5F5FFF5F5F5FFF4F4F4FFF9F9F9FFC5C5\n      C5FF909090FFD4D4D4FFD6D6D6FF1D1D1DFF000000FF000000FF000000FF0000\n      00FF0B0B0BFF959595FFDFDFDFFFFCFCFCFFFFFFFFFFF3F3F3FF959595FF3B3B\n      3BFF000000FF000000FF000000FF000000FF050505FF838383FFEDEDEDFF9E9E\n      9EFF979797FFF7F7F7FFF5F5F5FFF5F5F5FFF5F5F5FFF4F4F4FFFCFCFCFFADAD\n      ADFF000000FF000000FF000000FF010101FE040404FB8C8C8C73000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000C8C8C8381D1F\n      32EB10131EFF181D24FF262C32FF383E48FF434954FF454D57FF3C404AFF555E\n      6BFF232930FF15181EFF101318FF0E0E10FF0D0D0DFF131313F2B5B5B54DFDFD\n      FD02000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      00000000000000000000FDFDFD02909090730E0F10FF0E0E0FFF0F1014FF1015\n      18FF181E23FF1C2527FF232B2DFF41474CFF43494FFF3F444EFF393D45FF262B\n      31FF20272CFF1A1F27FF6C6C6E9CFBFBFB040000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000F9F9F9067B7B7B84030303FC010101FE2E3637FFB5D4D6FFC8ECF0FFBCE1\n      E6FFC1E6EAFFCCF0F3FFD0F3F5FFCFF2F5FFCEF1F4FFCAEEF2FFC1E6EAFFC1E6\n      E9FFC7EAEEFFC6EAEEFFBEE4E8FFC5EAEEFFC8EDF0FFC2E6EAFFC7EBEEFFC2E8\n      EBFFBBE1E6FFBFE5E9FFBEE2E6FFC1E6EAFFC2E7EBFFC5EAEDFFC5E9EDFFBBE1\n      E5FFBAE0E5FFC2E7EBFFC9EEF1FFCDF1F4FFC6E9EDFFBEE3E6FFC1E6EAFFC5E9\n      EEFFC8ECF0FFC7ECEFFFC7E9ECFFB2D3D6FF98B6B9FF8EA9ACFF8CA5A7FF88A1\n      A4FF89A3A5FF8AA4A6FF86A0A3FF88A1A5FF8CA5A7FF8CA4A6FF839DA0FF819B\n      9EFF8CA5A7FF8DA7AAFF8BA5A7FF88A1A4FF85A0A3FF89A2A5FF8CA4A7FF8BA4\n      A6FF8FA8AAFF93ABACFF8CA3A5FF3F4A4BFF020303FE000000FF1C1C1CE3C0C0\n      C03F000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000EBEBEB141A1A1AE5040809FF72F2FFFF2957\n      5CFF000000FF202326FFCBE2F2FFD6EFFFFFD6EFFFFFDAF4FFFFBCD3E1FF92A3\n      AEFF67747CFF3F464BFF1E2123FF7E8D96FFD5EEFEFFD6EFFFFFD6EFFFFFD6EF\n      FFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EF\n      FFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EF\n      FFFFD7F0FFFFC5DBEAFFC0D7E5FFD5EEFEFFD6EFFFFFD6EFFFFFD6EFFFFFD6EF\n      FFFFD6EFFFFFD6EFFFFFD6EFFFFFAEDFFFFFAFDFFFFFB0E0FFFFB0E0FFFFB0E0\n      FFFFB0E0FFFFB0E0FFFFB0E0FFFFB0E0FFFFB0E1FFFF9FCBE6FF101518FF0000\n      00FF000000FF2C7D81FF4DD7DCFF4CD4D9FF4CD4D9FF4CD5DAFF3CAAAEFF040C\n      0CFF000000FF7878788700000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      00000000000000000000000000008383837C000000FF010101FE000000FF0000\n      00FF070707FFB4B4B4FFFAFAFAFFF4F4F4FFF5F5F5FFF5F5F5FFF4F4F4FFF8F8\n      F8FFFDFDFDFFCACACAFF232323FF000000FF000000FF000000FF000000FF0000\n      00FF000000FF000000FF303030FF656565FFA9A9A9FFF0F0F0FFFFFFFFFFE5E5\n      E5FF858585FF000000FF000000FF000000FF000000FF040404FF848484FFFEFE\n      FEFFFBFBFBFFF5F5F5FFF4F4F4FFF5F5F5FFF5F5F5FFF5F5F5FFFAFAFAFF2B2B\n      2BFF000000FF000000FF000000FF000000FF151515EAF3F3F30C000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000D3D3D32D2628\n      30E415191FFF1B2128FF22292FFF252B32FF343B42FF404750FF3E444DFF4F58\n      64FF333942FF161920FF121519FF0E0E0FFF050505FF040404FF575757ACF0F0\n      F00F000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      00000000000000000000F4F4F40B565657B30B0C0DFF0D0D0DFE0E1115FF1114\n      1EFF121731FF0E1140FF0C1759FF1D2C6BFF2C3761FF383E46FF343A42FF242B\n      31FF1C2128FE13161DFF90908F74000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      000000000000E1E1E11E333333CC000000FF000000FF5D6E6FFFC8EDF0FFC8ED\n      F0FFBEE4E8FFBCE2E6FFC0E6EAFFC5EBEEFFC4E8ECFFC3E8ECFFC8ECEFFFCBEF\n      F2FFC4E8EDFFBFE4E8FFBDE2E7FFBEE5E9FFC5EBEEFFC7ECF0FFC3E9EDFFC3E9\n      ECFFC4E8EDFFC0E5E9FFBFE5EAFFB8DEE3FFBDE2E7FFC8ECF0FFCCF0F4FFCDF1\n      F4FFC6EBEFFFC8ECEFFFC6EBEEFFC5EAEDFFC1E6EAFFBDE2E7FFC3E8ECFFC9EE\n      F0FFC8ECF0FFBFE4E9FFC0E5E8FFBFE2E5FFACCDD0FF95B2B5FF8CA6A8FF8DA6\n      A8FF8EA7A9FF8CA5A7FF8CA6A8FF8DA7AAFF8FA8AAFF90A9ACFF8CA5A7FF85A0\n      A3FF85A0A3FF8DA6A8FF8AA4A6FF89A2A5FF8BA3A6FF8EA6A9FF8BA4A7FF87A1\n      A5FF88A1A4FF89A1A4FF506060FF030404FE000000FF121212EDA4A4A45BFEFE\n      FE01000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000D2D2D22D000000FF275357FF75F7FFFF66D8\n      E4FF0E1D1FFF000000FF566067FFD3EBFBFFCFE7F6FF4A5359FF020202FF0000\n      00FF000000FF000000FF000000FF2C3134FFCAE1F0FFD6EFFFFFD6EFFFFFD6EF\n      FFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EF\n      FFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EF\n      FFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EF\n      FFFFD6EFFFFFD7F0FFFFCDECFFFFB0E1FFFFB1E2FFFFB1E1FFFFB1E1FFFFB0E1\n      FFFFB0E1FFFFB0E1FFFFB1E1FFFFB1E2FFFFA7D4F2FF40515DFF000000FF0000\n      00FF03090AFF45C1C5FF4BD3D8FF4CD4D9FF4CD4D9FF4CD5DAFF2A787BFF0101\n      01FE0B0B0BF4BABABA4500000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000FCFCFC03050505FA000000FF000000FF0000\n      00FF000000FF535353FFF6F6F6FFF5F5F5FFF5F5F5FFF5F5F5FFF5F5F5FFF5F5\n      F5FFDFDFDFFF171717FF000000FF000000FF000000FF000000FF000000FF0000\n      00FF000000FF000000FF000000FF000000FF080808FF1A1A1AFF8A8A8AFFF8F8\n      F8FFF1F1F1FF818181FF000000FF000000FF000000FF000000FF000000FF8888\n      88FFF9F9F9FFF5F5F5FFF5F5F5FFF5F5F5FFF4F4F4FFFBFBFBFFA7A7A7FF0808\n      08FF000000FF000000FF010101FE000000FF7B7B7B8400000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000E2E2E21D4144\n      45C914191EFF161D21FF1C252BFF252F33FF272E34FF282F35FF2F363CFF4048\n      51FF343B44FF0F1315FF0C0D0FFF0A090AFF040404FF040404FF242424E0D1D1\n      D12E000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      00000000000000000000D2D2D22D232323E7050505FF080808FF0E0F11FF1317\n      1BFF1A1E21FF222A2BFF464E51FF4C5259FF3D4552FF303748FF282F3AFF1F26\n      2EFF20262DFF13171CFFBFBFBF40000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      00000000000000000000AEAEAE510E0E0EF1000000FF0A0C0CFE8FAAACFFCBF0\n      F3FFC4E8ECFFC5EAEDFFC3E8EBFFC2E7EBFFC7ECEFFFCCEFF2FFCFF1F5FFCBF0\n      F3FFC2E7EBFFBEE3E8FFC3E8ECFFC5E9ECFFC6EBEEFFC9EEF0FFC4E9EDFFC9ED\n      F0FFD0F4F7FFCBEFF2FFC9EDF0FFC9EDF1FFC6EBEFFFC9EDF0FFC5EAEDFFC3E8\n      ECFFC8EDF0FFC4E9ECFFBCE3E7FFBDE2E7FFC0E5E9FFC3E8EBFFC1E6EAFFC4E9\n      ECFFC5E9ECFFC0E5EAFFC1E6EAFFC8ECEFFFBEE0E2FFA2C0C3FF8EA9ACFF849E\n      A1FF819B9EFF829C9FFF87A0A3FF8DA6A8FF8BA5A8FF89A3A6FF8CA6A7FF8EA8\n      A9FF859FA2FF839DA0FF8AA3A5FF8DA7A8FF8CA5A8FF8EA7A9FF8AA3A6FF8AA3\n      A6FF89A3A6FF566769FF090B0BFE000000FF030303FC88888877FEFEFE010000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      000000000000000000000000000098989867000000FF428B93FE73F3FFFF74F6\n      FFFF5ABFC9FF030708FF000000FF77858EFFE0FAFFFFDAF3FFFFAFC4D1FF7380\n      89FF373D41FF000000FF000000FF222729FFC8DFEEFFD6EFFFFFD6EFFFFFD6EF\n      FFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EF\n      FFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EF\n      FFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD5EE\n      FEFFDAF4FFFFB3C7D5FF758C9BFF607A8BFF698597FF7B9CB2FF8AAFC8FF91B9\n      D2FF90B8D1FF8CB2CAFF85A9C0FF6F8EA2FF303D46FF000000FF000000FF0000\n      00FF276F71FF4BD2D7FF4BD3D8FF4CD4D9FF4BD3D8FF49CDD2FF174042FF0000\n      00FF232323DCFDFDFD0200000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      00000000000000000000000000000000000088888877000000FF000000FF0000\n      00FF000000FF191919FFC4C4C4FFF5F5F5FFF5F5F5FFF5F5F5FFF5F5F5FFFAFA\n      FAFF7B7B7BFF000000FF000000FF000000FF000000FF000000FF000000FF0000\n      00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF3E3E\n      3EFFF1F1F1FFDFDFDFFF323232FF000000FF000000FF000000FF000000FF0303\n      03FFFFFFFFFFF5F5F5FFF5F5F5FFF5F5F5FFF5F5F5FFF3F3F3FF4A4A4AFF0000\n      00FF000000FF000000FF000000FF040404FBFBFBFB0400000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000F0F0F00F5F5E\n      60A70F1317FF0F1319FF161B20FF192026FF20282EFF272F34FF353D44FF444D\n      59FF343A45FF101417FF0C0C0DFF040404FF040404FF030303FF060607FF9F9F\n      9F62FEFEFE010000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      000000000000FCFCFC03757576900A0A0BFF0C0C0CFF0D0F10FF0E0F12FF1317\n      1CFF1B2329FF303940FF565F6CFF5C6674FF4D5460FF494F5AFF2D353AFF242D\n      33FF181F25FF333536DCE1E1E11E000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      00000000000000000000FCFCFC037B7B7B84000000FF000000FF293133FFB0D1\n      D4FFC9EDF1FFBFE5EAFFBCE3E7FFBFE4E9FFC9EDF0FFCDF1F4FFC5E9ECFFC4E8\n      EBFFD0F2F5FFD0F3F5FFCCF0F2FFCAEDF1FFC3E8ECFFBEE3E8FFBEE3E7FFC2E6\n      EAFFC7EBEEFFC4E9EDFFBFE5E9FFC3E8EBFFC6EAEEFFCDF1F4FFC8ECF0FFC6EC\n      EFFFC8EDF0FFC1E6EAFFBDE2E6FFBDE3E7FFC4E9ECFFCBEEF2FFC9EDF1FFC4E9\n      ECFFC4E9ECFFC9EDF1FFC8ECF0FFC5EAEDFFBBDEE1FFB0CFD2FFA0BBBDFF8CA7\n      AAFF88A1A4FF89A2A5FF89A2A6FF89A2A5FF8AA3A5FF86A0A3FF839DA0FF8BA4\n      A7FF92AAABFF8DA6A8FF8CA6A8FF8BA4A6FF89A2A5FF849EA1FF839DA0FF869F\n      A2FF66797BFF0F1212FF000000FF010101FE7272728DF8F8F807000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      000000000000000000000000000079797986000000FF499CA4FF72F2FFFF70EE\n      FBFF72F2FFFF53B1BBFF000000FF000000FF7B8A93FFE3FDFFFFDAF3FFFFD7F0\n      FFFFCCE4F4FFBDD2E1FF6D7982FF7B8992FFD2EBFBFFD6EFFFFFD6EFFFFFD6EF\n      FFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EF\n      FFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EF\n      FFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD5EEFEFFDCF6\n      FFFF77858DFF090A0AFF000000FF040A0BFF040909FF020000FF070507FF0A0B\n      0DFF0B0E10FF0A0D0EFF080A0CFF030304FF000000FF000000FF000000FF266C\n      6FFF4CD4D9FF4CD4D9FF4CD4D9FF4CD4D9FF4CD4D8FF44BEC3FF010303FE0000\n      00FF8B8B8B740000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      000000000000000000000000000000000000EBEBEB14101010EF000000FF0101\n      01FE000000FF000000FF7A7A7AFFF2F2F2FFF4F4F4FFF5F5F5FFF5F5F5FFF9F9\n      F9FF7D7D7DFF000000FF000000FF000000FF000000FF000000FF010101FF1F1F\n      1FFF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000\n      00FF666666FFFFFFFFFF696969FF000000FF000000FF000000FF000000FF0101\n      01FFFFFFFFFFF5F5F5FFF5F5F5FFF5F5F5FFF6F6F6FFBEBEBEFF121212FF0000\n      00FF000000FF010101FE000000FF7F7F7F800000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000F8F8F8077173\n      749613181DFF20252CFF262F34FF252E33FF30373CFF343941FF3A4048FF4349\n      53FF464E59FF181D23FF0B0A0CFF050505FF040404FF060606FF040405FF6868\n      689BF1F1F10E0000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      000000000000E3E3E31C29292AE00C0C0CFF0A0B0BFF0F1115FF13181EFF151B\n      21FF252C32FF363D44FF4B535EFF4F5865FF4B535FFF3D444CFF2A3138FF1A1F\n      25FF13171DFF444546C6F1F1F10E000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000E4E4E41B343434CB000000FF040404FE5F72\n      74FFC6E9ECFFCCF0F2FFCBEEF0FFC2E7EBFFBFE4E8FFC1E5EAFFBEE3E7FFC4E9\n      EDFFCDF1F4FFC8ECEFFFC1E7EAFFC4E9EDFFC6EBEFFFC4E7EBFFCAEEF0FFC7EB\n      EEFFC4E8EBFFC9ECEFFFCBEEF0FFC4E8EDFFBDE3E7FFBBE0E5FFBFE5E9FFC1E6\n      EAFFC3E8EBFFC8EBEFFFCCEFF3FFC8ECEFFFC9EDF0FFCAEDF1FFCAEEEFFFC2E6\n      EAFFC3E7EBFFC5EAEDFFC4E9EDFFBDE2E7FFB5DADFFF9EBEC0FFA0BFC1FF92AC\n      AFFF8EA7AAFF8DA6A8FF859FA2FF819B9FFF839EA0FF86A0A3FF88A2A4FF869F\n      A2FF87A1A3FF86A0A3FF839DA0FF7F9A9DFF7F9A9DFF7F999CFF86A0A2FF7186\n      89FF1B2021FE000000FF020202FD4F4F4FB0E9E9E91600000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      00000000000000000000000000007B7B7B84000000FF3D838AFF73F3FFFF71EF\n      FCFF70EEFBFF71EFFCFF367379FF000000FF030404FF636F76FF8797A1FFB7CD\n      DAFFC9E1F0FFD6EFFFFFDBF5FFFFDAF3FFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EF\n      FFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EF\n      FFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EF\n      FFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD5EEFEFFDAF3FFFFABBF\n      CBFF000000FF000000FF2B797BFF51E3E8FF50E0E5FF47C5CBFF318A8DFF1B4B\n      4DFF091C1CFF061212FF050E0EFF050E0FFF071314FF133435FF3DADB1FF4EDB\n      E0FF4BD3D8FF4CD3D8FF4CD4D9FF4BD3D8FF4EDADFFF225F61FE000000FF0303\n      03FC000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      000000000000000000000000000000000000FCFCFC037A7A7A85000000FF0101\n      01FE000000FF000000FF131313FFE7E7E7FFF4F4F4FFF5F5F5FFF5F5F5FFF6F6\n      F6FFC3C3C3FF000000FF000000FF000000FF000000FF000000FF5F5F5FFF9E9E\n      9EFF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000\n      00FF121212FFFFFFFFFF838383FF040404FF000000FF000000FF000000FF4949\n      49FFFCFCFCFFF5F5F5FFF5F5F5FFF4F4F4FFF0F0F0FF707070FF000000FF0000\n      00FF000000FF000000FF0F0F0FF0E6E6E6190000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000FBFBFB049F9F\n      9F6723292CF831383FFE3B414AFF3E424CFF383F47FF383E46FF33393FFF2E35\n      3CFF373E47FF101317FF080707FF030303FF040404FF050505FE030303FF1919\n      19EDA1A1A161FCFCFC0300000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000FCFCFC03A4A4A45E141314F40B0B0CFF0F1012FF12161BFF14181EFF1A20\n      25FF1B2026FF3D434DFF525965FF434954FF434A55FF3F4753FF31363EFF1C23\n      33FE11141FFF6667689FF8F8F807000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000FEFEFE01A4A4A45B0E0E0EF1000000FF1317\n      17FE9CB9BBFFC4EAEDFFC4E9EDFFC7EBEFFFBFE5E9FFBDE3E7FFC8EDF0FFCDF1\n      F4FFC4E9ECFFC4E7EBFFC4E8ECFFC2E6EAFFC0E5E9FFC3E8EBFFC4E9ECFFC4E9\n      ECFFC0E5EAFFC6EAEDFFD0F3F5FFD0F3F6FFC8ECEFFFC0E5EAFFC6EBEEFFC8ED\n      F0FFC3E7EBFFC4E9EDFFC8ECEFFFCCF0F3FFC8ECF0FFBFE5E9FFBFE4E9FFC3E8\n      EBFFC3E9ECFFC6EBEFFFC9EEF1FFC7ECEFFFC8EEF0FF88A2A6FF91AEB0FF9AB6\n      B9FF8DA7A9FF839DA0FF849FA2FF859FA2FF849EA1FF859EA1FF8BA4A6FF89A2\n      A5FF87A1A3FF86A1A2FF869FA2FF8AA4A6FF8CA5A7FF8EA8A9FF7E9495FF252C\n      2CFE010101FE000000FF383838C7D7D7D7280000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      00000000000000000000000000009E9E9E61000000FF1F4246FE76FAFFFF70EE\n      FBFF72F1FEFF65D6E2FF21474BFF000000FF020606FF000202FF000000FF0000\n      00FF282B2EFF6A777FFFC1D7E5FFDCF5FFFFD5EEFEFFD6EFFFFFD6EFFFFFD6EF\n      FFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EF\n      FFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EF\n      FFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD7F0FFFFCAE2F1FF2226\n      28FF000000FF1D4649FF4BD2D7FF4BD3D8FF4BD3D8FF4CD5DAFF4ED9DEFF4FDE\n      E3FF4EDBE1FF45C2C6FF40B2B6FF40B3B7FF47C8CDFF4FDEE3FF4DD7DCFF4BD3\n      D8FF4CD4D9FF4CD4D9FF4BD3D8FF4CD6DBFF45C1C6FF010101FE000000FF8D8D\n      8D72000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      00000000000000000000000000000000000000000000C6C6C639151515EA0000\n      00FF000000FF000000FF000000FF868686FFF9F9F9FFF4F4F4FFF5F5F5FFF5F5\n      F5FFE4E4E4FF0F0F0FFF000000FF000000FF000000FF000000FFA7A7A7FFF7F7\n      F7FF151515FF000000FF000000FF000000FF000000FF000000FF000000FF0000\n      00FF303030FFFFFFFFFF6C6C6CFF010101FF000000FF000000FF000000FF9696\n      96FFF8F8F8FFF5F5F5FFF5F5F5FFF4F4F4FFE4E4E4FF080808FF000000FF0000\n      00FF010101FE000000FF6F6F6F90FBFBFB040000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000FEFEFE01C4C4\n      C43C1B1F22F0181F24FF242A32FF353C44FF343B42FF32383FFF33363FFF3038\n      3EFF21272CFF0E0F11FF070707FF060606FF060606FF050505FF040404FE0404\n      05FF1B1B1BE9B8B8B84AFCFCFC03000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000ECECEC13515154B50E1013FF0A0A0DFE060616FF0E1119FF151A21FF2A31\n      38FF444953FF616A76FF5B636FFF424952FF4A4F5BFF0F1242FF0E0F23FF1A1D\n      29FE1A1D24FF8686877FFCFCFC03000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      000000000000000000000000000000000000F8F8F80766666699000000FF0101\n      01FE394344FFBFE1E3FFCFF3F5FFCDF1F4FFCFF2F5FFCDEFF2FFC8ECF0FFC6EA\n      EEFFC6EAEFFFC7ECEFFFCCF0F3FFC9EEF2FFC5E9EDFFC7ECEFFFCEF1F4FFCEF2\n      F5FFCDF0F4FFC9EDF0FFC4EAEDFFC9EEF1FFCEF2F4FFC9EDF1FFBFE4E8FFBFE4\n      E8FFC1E6EAFFC1E6EAFFB9DDE1FFACCBCEFFADCCCFFFC4E7EAFFC5EAEEFFCBEF\n      F2FFC7EBEFFFC4E9EDFFC8ECEFFFCAEEF1FFC6EAEEFFA6C4C7FF67797AFF9DB8\n      BBFF8CA7AAFF89A3A5FF8AA3A6FF88A0A3FF85A0A2FF87A1A4FF8BA4A7FF89A2\n      A5FF89A2A4FF8AA3A6FF8BA5A8FF8BA5A7FF8FA7A9FF859C9DFF323B3CFF0101\n      01FE000000FF262626D9C9C9C936000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000DBDBDB24000000FF000000FF68DBE8FF73F4\n      FFFF6DE8F4FF0B1617FF122629FF56B6C0FF66D8E4FF66D8E4FF61CDD8FF3C7E\n      86FF060F11FF000000FF1B1E20FFADC1CEFFD8F1FFFFD5EEFEFFD6EFFFFFD6EF\n      FFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EF\n      FFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EF\n      FFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD5EEFEFFD5EEFDFF576167FF0000\n      00FF040A0BFF57BAC5FF68E9F4FF4BD3D7FF4BD3D8FF4CD4D9FF4CD4D9FF4BD3\n      D8FF4CD4D9FF4CD4D9FF4CD4D9FF4CD4D9FF4CD4D9FF4CD4D9FF4BD3D8FF4CD4\n      D9FF4CD4D9FF4CD4D9FF4CD4D9FF4FDDE3FF163D3FFF000000FF232323DCEBEB\n      EB14000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      00000000000000000000000000000000000000000000FEFEFE01515151AE0000\n      00FF000000FF000000FF000000FF0E0E0EFFF5F5F5FFF5F5F5FFF5F5F5FFF5F5\n      F5FFECECECFF4D4D4DFF000000FF000000FF000000FF000000FFA4A4A4FFF6F6\n      F6FFD1D1D1FF0C0C0CFF000000FF000000FF000000FF000000FF000000FF0808\n      08FFC9C9C9FFF1F1F1FF404040FF000000FF000000FF000000FF000000FFDADA\n      DAFFF5F5F5FFF5F5F5FFF4F4F4FFFAFAFAFF7A7A7AFF000000FF000000FF0000\n      00FF000000FF0E0E0EF1C2C2C23D000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      000000000000000000000000000000000000000000000000000000000000E9E9\n      E916343638D511141AFF161B1FFF21252BFF2B3337FF2A3036FF2E333AFF373F\n      47FF454C58FF2C333BFF0D0E10FF090909FF050505FF040405FF030309FF0303\n      07FE040404FF3F3F40C7E0E0E01F000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000D4D4D52C2C2C2FE10E0E0FFF0E0F10FF060608FF050409FF090B0DFF181E\n      23FF545B67FF515A65FF363E48FF444B56FF2D343DFF2F343AFF353740FF3335\n      3CFF1B1C22FDB3B3B44DFEFEFE01000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      00000000000000000000000000000000000000000000DDDDDD22232323DC0000\n      00FF000000FF657778FFC0E5E8FFC1E6EAFFC2E6EAFFC0E5E9FFBEE3E7FFB4D6\n      DAFFA7C5C8FFAECBCEFFC0E0E3FFC7EBEEFFCCF0F3FFC9EEF1FFC1E6EAFFC4E9\n      EDFFC5E9EDFFBDE2E7FFBADFE4FFBEE3E8FFC3E8ECFFC5EAEEFFC8EDF0FFC8EC\n      EFFFC7ECEFFFABCBCEFF455254FF151717FF262A2AFF586162FF98AFB2FFBFE2\n      E6FFC8EDF0FFC3E7EBFFBDE2E6FFC2E7EBFFC6EBEEFFBBDFE2FF465455FF7288\n      8AFF92ADB0FF92ABADFF8EA8AAFF86A0A3FF89A3A6FF8BA4A6FF8AA3A5FF86A0\n      A2FF859FA1FF8BA4A7FF8BA5A8FF8BA5A8FF869EA0FF424F50FF030404FE0000\n      00FF151515EAB2B2B24D00000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000F0F0F00F323232CD000000FF14292CFF61CD\n      D8FF173235FF102426FF6DE6F2FF72F1FEFF70EEFBFF70EEFBFF71EFFCFF73F4\n      FFFF72F1FEFF2F646AFF000102FF0B0C0DFFA6BAC7FFD7F0FFFFD6EFFFFFD5EE\n      FEFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD5EEFEFFD5EE\n      FEFFD6EFFFFFD7F0FFFFD7F0FFFFD7F0FFFFD6EFFFFFD6EFFFFFD5EEFEFFD6EF\n      FFFFD6EFFFFFD6EFFFFFD6EFFFFFD7F1FFFFD1E9F9FF6E7B84FF000000FF0000\n      00FF2D5E63FF76FBFFFF71EFFCFF68E9F4FF4CD4D9FF4BD3D8FF4CD4D9FF4CD4\n      D9FF4CD4D9FF4CD4D9FF4CD4D9FF4CD4D9FF4CD4D9FF4CD4D9FF4CD4D9FF4CD4\n      D9FF4CD4D9FF4BD3D8FF4CD5DAFF339194FF020606FE020202FD9292926D0000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000B5B5B54A0707\n      07F8010101FE000000FF000000FF000000FF868686FFFFFFFFFFF4F4F4FFF5F5\n      F5FFF3F3F3FF848484FF000000FF000000FF000000FF000000FF2F2F2FFFE6E6\n      E6FFF7F7F7FFBFBFBFFF3A3A3AFF111111FF0D0D0DFF1E1E1EFF494949FFC7C7\n      C7FFFFFFFFFF979797FF070707FF000000FF000000FF000000FF252525FFE8E8\n      E8FFF4F4F4FFF5F5F5FFF6F6F6FFEBEBEBFF070707FF000000FF000000FF0000\n      00FF000000FF4C4C4CB3F8F8F807000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      000000000000000000000000000000000000000000000000000000000000F8F8\n      F8076D6D6E9A10161AFF292E35FF3E444DFF3B4048FF3C424CFF444A55FF4148\n      52FF444B56FF31373FFF121418FF0D0E0EFF09090CFF050512FF03030BFF0404\n      0FFF040406FF060607FFA0A0A061FEFEFE010000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      000000000000000000000000000000000000000000000000000000000000FEFE\n      FE01ADADAD541C1D20F60B0B0DFF0C0C0CFF060618FF0A0B0BFF15181CFF2429\n      30FF676F7CFF6A737FFF5D6574FF5E6674FF404552FF3E4655FF2D323DFF3236\n      3DFF3E4044D5DADADA2500000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000A5A5A55A0C0C\n      0CF3000000FF131818FF94B1B4FFC5E9EDFFC0E4EAFFC8EDF1FFA4C0C2FF3E46\n      48FF2E3030FF3F4243FF5F6667FF8FA3A5FFC0E1E4FFCAEDF1FFC3E8EBFFC1E7\n      EBFFBCE3E6FFBEE3E7FFC0E5E9FFBFE4E8FFBFE4E8FFC2E7EBFFCAEFF2FFCEF2\n      F4FFC8EDEFFF556566FF000000FF000000FF050505FF121212FF343434FF7584\n      86FFB7D9DDFFC5EBEEFFC7ECEFFFC5EAEDFFCDF0F3FFC9ECEFFF6B8082FF1C22\n      22FF80979AFF8DA8ABFF8EA6A9FF8EA7A9FF88A2A4FF87A1A4FF89A2A5FF8CA5\n      A7FF89A3A5FF88A1A3FF89A2A4FF869EA1FF4E5C5EFF050606FE000000FF0D0D\n      0DF29191916EFCFCFC0300000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000008B8B8B74020202FD010101FE0000\n      00FF000000FF5EC6D2FF73F4FFFF70EEFBFF71EFFCFF71EFFCFF71EFFCFF70EE\n      FBFF71EFFCFF76FAFFFF47969EFF030B0CFF020101FF7D8C94FFD9F2FFFFD6EF\n      FFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFD6EFFFFFDEF8\n      FFFFC2D8E7FF9FB2BEFF96A8B3FFA3B6C2FFC0D7E5FFDEF8FFFFDDF6FFFFD9F2\n      FFFFD9F2FFFFDBF5FFFFDEF8FFFFA8BCC9FF41494EFF000000FF000000FF0D1C\n      1EFF70EDFAFF71EFFDFF70EEFBFF71EFFCFF5FE2EBFF4CD4D9FF4CD4D9FF4CD4\n      D9FF4CD4D9FF4CD4D9FF4CD4D9FF4CD4D9FF4CD4D9FF4CD4D9FF4CD4D9FF4CD4\n      D9FF4BD3D8FF4DD9DEFF40B4B9FF091B1BFE000000FF454545BAFAFAFA050000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000003535\n      35CA000000FF000000FF000000FF000000FF1B1B1BFFEBEBEBFFF6F6F6FFF5F5\n      F5FFF6F6F6FFAEAEAEFF040404FF000000FF000000FF000000FF000000FFCECE\n      CEFFF6F6F6FFF9F9F9FFE2E2E2FFBDBDBDFFB9B9B9FFCFCFCFFFFEFEFEFFF8F8\n      F8FF7F7F7FFF111111FF000000FF000000FF000000FF000000FF5D5D5DFFEEEE\n      EEFFF5F5F5FFF4F4F4FFFFFFFFFF747474FF000000FF000000FF000000FF0101\n      01FE070707F8A2A2A25D00000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000909090751F272CFF2F353EFE3F4650FF424B58FF404A57FF394049FF444F\n      59FF363D46FF3E444EFF191E23FF0C0D0FFF0A0A0AFF04040EFF040316FF0404\n      12FF080808FE050504FF5C5D5DA7F4F4F40B0000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      000000000000000000000000000000000000000000000000000000000000EBEB\n      EB14414142C60C0D0FFF05050AFF050506FF040424FF050746FF12141EFF3D42\n      49FF89909DFF848B98FF6E7582FF535866FF4C5161FF2B303EFF2C3341FF252A\n      30FE6B6D6E9DF2F2F20D00000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000F2F2F20D5F5F\n      5FA0010101FE010101FE3E4A4BFFB5D7DBFFC4EAEEFFC4E8ECFF465354FF0101\n      01FF0A0A0AFF161616FF252525FF3D3E3EFF6D7879FFBEE1E3FFD1F5F8FFCBEE\n      F0FFCAEDEFFFCDF0F4FFD3F6F9FFD7F7F9FFD1F5F6FFC5E9EDFFBCE2E6FFBEE4\n      E8FFC3E8EBFF303839FF000000FF000000FF010101FF070707FF191919FF3A3B\n      3BFF808F90FFC4E8EBFFCCF0F3FFCBEFF4FFC7EBEEFFC9EDF2FFB3D2D5FF161A\n      1AFF323C3CFF88A2A4FF8AA4A6FF8AA2A6FF8AA3A6FF8DA6A8FF8DA7A9FF8CA5\n      A7FF8DA6A9FF8BA4A6FF87A0A2FF576768FF0B0D0DFE000000FF000000FF7E7E\n      7E81F7F7F7080000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      000000000000000000000000000000000000F6F6F6091C1C1CE3000000FF0101\n      01FE265156FF74F7FFFF70EEFBFF71EFFCFF71EFFCFF71EFFCFF71EFFCFF71EF\n      FCFF70EEFBFF70EEFBFF71F0FDFF55B4BEFF030607FF020202FF5D686FFFD7F0\n      FFFFD5EEFEFFD5EEFEFFD6EFFFFFD6EFFFFFD5EEFEFFD5EEFEFFD7F0FFFF6772\n      7AFF121416FF080708FF070708FF0A0C0CFF111314FF2B2F32FF798791FFAFC3\n      CFFFB3C8D5FF8C9CA7FF353B3FFF08090AFF000000FF000000FF000000FF57B6\n      C1FF72F1FEFF70EEFBFF71EFFCFF71EFFCFF70EEFBFF51D7DEFF4BD3D8FF4CD4\n      D9FF4CD4D9FF4CD4D9FF4CD4D9FF4CD4D9FF4CD4D9FF4CD4D9FF4CD4D9FF4BD3\n      D8FF4DD8DDFF3DACAFFF040E0EFE000000FF191919E6F8F8F807000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      000000000000000000000000000000000000000000000000000000000000B2B2\n      B24D000000FF010101FE000000FF000000FF040404FF8A8A8AFFFDFDFDFFF4F4\n      F4FFF5F5F5FFCDCDCDFF222222FF000000FF000000FF000000FF000000FFDADA\n      DAFFF5F5F5FFF4F4F4FFF5F5F5FFF6F6F6FFF2F2F2FFB1B1B1FF666666FF1616\n      16FF040404FF000000FF000000FF000000FF000000FF000000FF969696FFF5F5\n      F5FFF5F5F5FFF6F6F6FFE7E7E7FF141414FF000000FF000000FF000000FF0000\n      00FF1E1E1EE10000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000DFDFDF202C3033E6293135FF3A3F4AFF3C444FFF434C5AFF444F5AFF4A53\n      5FFF474F5DFF424957FF2D3239FF0E0F14FF0C0D18FF0C0C16FF080A33FF0B0B\n      15FF080809FF030302FF191919EFC5C5C53A0000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000FDFDFD029A9A\n      9A680C0C0FFF0E0F10FE0F0E12FF0E1012FF0C0C14FF080916FF070726FF0D11\n      30FF252D46FF677183FF8B95A2FF9FA8B5FF808996FF323844FF2F323BFE2F35\n      3AF79F9F9F64FCFCFC0300000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      000000000000000000000000000000000000000000000000000000000000D1D1\n      D12E212121DE000000FF040505FE758C8DFFCBEDF0FFB8DADEFF252C2DFF0000\n      00FF010101FF040404FF0D0D0DFF202020FF3A3939FF788586FFC2E6E9FFC5EA\n      EEFFC3E8ECFFC7ECEFFFCCF0F2FFCBEEF2FFC5EAEDFFC9EDF1FFC5E9EDFFC6EA\n      EEFFC8EBEEFF434F50FF000000FF000000FF000000FF010101FF0C0C0CFF2929\n      29FF4E4F50FFB0CACDFFC7ECF1FFC3E8EBFFC5E9EDFFC5EAEEFFC9F0F4FF697D\n      7EFF000000FF526163FF88A2A5FF8BA4A8FF8EA7A9FF86A0A2FF839DA0FF89A1\n      A3FF88A0A3FF87A0A3FF677A7CFF111314FE000000FF020202FD6262629DF9F9\n      F906000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      00000000000000000000000000000000000000000000D4D4D42B070707F80000\n      00FF57BAC4FF71F0FDFF71EFFCFF71EFFCFF71EFFCFF71EFFCFF71EFFCFF71EF\n      FCFF71EFFCFF71EFFCFF70EEFBFF73F5FFFF61CEDAFF0C1A1BFF000000FF464E\n      53FFCAE2F1FFD7F0FFFFD6EFFFFFD6EFFFFFD7F0FFFFCAE2F1FF444C51FF0000\n      00FF0E1D1FFF265256FF142C2EFF070F0FFF000000FF000000FF000000FF0000\n      00FF000000FF000000FF000000FF000000FF000000FF000000FF2B5B61FF6EEA\n      F7FF70EEFBFF71EFFCFF71EFFCFF70EEFBFF71EFFCFF66E7F2FF4BD3D7FF4BD3\n      D8FF4CD4D9FF4CD4D9FF4CD4D9FF4CD4D9FF4CD4D9FF4CD4D9FF4CD4D9FF4CD4\n      D9FF45C2C6FE040D0EFE000000FF272727D8E7E7E71800000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000292929D6000000FF010101FE000000FF000000FF3C3C3CFFE9E9E9FFF5F5\n      F5FFF5F5F5FFEAEAEAFF404040FF000000FF000000FF000000FF000000FF5555\n      55FFFAFAFAFFF5F5F5FFF4F4F4FFF5F5F5FFF0F0F0FF717171FF000000FF0000\n      00FF000000FF000000FF000000FF000000FF000000FF0F0F0FFFBBBBBBFFF6F6\n      F6FFF5F5F5FFFCFCFCFF838383FF040404FF000000FF000000FF000000FF0000\n      00FF9A9A9A650000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000F9F9F9068586867C1A1E24FF282B33FF272933FF2F323BFF31343CFF3537\n      41FF3D3F4CFF3F414CFF2F333AFF0F100FFF080818FF030319FF040405FF0707\n      09FF040410FF05050CFE030306FF4F4F50B5E6E6E61900000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000E6E6E6193A3B\n      3CCF0E0F13FF0F1014FE0F1014FF101214FF11121BFF101331FF171C2DFF545D\n      64FF374358FF1B3677FF636C7AFF6F7989FF6D7886FF383F4AFF242831FE2729\n      2FF0C5C5C53AFEFEFE0100000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      00008E8E8E71020202FD000000FF181D1DFEA5C2C5FFCCEFF2FF3B4647FF0000\n      00FF000000FF000000FF030303FF101010FF2C2C2CFF505252FF9AB2B6FFBCE1\n      E5FFC3E8EDFFC7EBEFFFC2E7EAFFBBE1E5FFBAE0E4FFC1E5EAFFC4E9EDFFC4E9\n      ECFFC3E9EDFF839C9EFF040505FF000000FF000000FF000000FF060606FF1F1F\n      1FFF3F3E3EFF839193FFC5E9EDFFC4E8ECFFC3E7EBFFC5EAEEFFC7EBEFFFC4E7\n      E9FF161A1AFF131717FF7B9192FF8EA8AAFF87A1A3FF859FA2FF859FA2FF8AA4\n      A7FF8AA4A7FF6F8385FF1E2324FE010101FE000000FF4D4D4DB2E1E1E11E0000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      00000000000000000000000000000000000000000000000000007575758A0811\n      12FF68DBE7FF70EEFBFF71EFFCFF71EFFCFF71EFFCFF71EFFCFF71EFFCFF71EF\n      FCFF71EFFCFF71EFFCFF71EFFCFF70EEFBFF72F3FFFF69DFEAFF2A585DFF0000\n      00FF1D2023FF8C9DA7FFC7DEEDFFBBD1DFFF808E98FF1C1F21FF000000FF2D60\n      66FF6DE8F5FF76FBFFFF74F7FFFF5DC4CFFF3C8087FF1F4346FF020506FF0000\n      00FF000000FF000000FF000000FF000000FF000000FF142A2DFF67DAE6FF71F0\n      FDFF71EFFCFF71EFFCFF71EFFCFF71EFFCFF70EEFBFF72F0FDFF55D9E1FF4BD3\n      D8FF4CD4D9FF4CD4D9FF4CD4D9FF4CD4D9FF4CD4D9FF4CD4D9FF4CD4D9FF4CD3\n      D8FF276D6FFE000000FF7373738CEAEAEA150000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000B4B4B44B000000FF000000FF000000FF000000FF070707FFACACACFFF5F5\n      F5FFF5F5F5FFFEFEFEFF656565FF000000FF000000FF000000FF000000FF0000\n      00FFB4B4B4FFFAFAFAFFF9F9F9FFF5F5F5FFF4F4F4FFFBFBFBFFA4A4A4FF3535\n      35FF000000FF000000FF000000FF000000FF000000FF2F2F2FFFDBDBDBFFF5F5\n      F5FFF5F5F5FFE3E3E3FF333333FF000000FF000000FF000000FF000000FF1616\n      16E9000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      000000000000B7B7B849181C21FB14161EFF0F1215FF171A1FFF20242AFF3135\n      3CFF2A2D33FF212332FF0F1025FF080826FF040427FF040400FF050518FF0404\n      0EFF030318FF060607FE0C0C0DFF0B0B0AF98A8A897BF4F4F40B000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      00000000000000000000000000000000000000000000FBFBFB04A0A0A0620F0F\n      13F6070813FF080917FF080911FF060616FF0B0E28FF1E2125FF1B2047FF8388\n      94FF797E8BFF43465BFF313042FF545665FF686D7BFF7B8391FF666E7DFF3C3C\n      42D9EBEBEB140000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000F4F4F40B5A5A5AA5000000FF000000FF3A4748FFB6DBDEFF849D9FFF0000\n      00FF000000FF000000FF010101FF090909FF222222FF454545FF7E8C8DFFBFE3\n      E6FFC4EAEEFFC4E8ECFFC0E6EAFFC2E7EAFFCAEEF2FFD1F3F7FFD1F4F7FFCAED\n      F0FFBFE4E9FFB7DADDFF465353FF000000FF000000FF000000FF030303FF1919\n      19FF3A3939FF6F7878FFC5E9ECFFC8ECF0FFC1E6EBFFC5EAEDFFC7ECEFFFCCF0\n      F4FF6D8081FF000000FF2F3838FF849D9FFF8BA4A6FF8BA3A6FF8BA5A7FF88A2\n      A5FF728889FF202627FF010101FE000000FF363636C9D9D9D926000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      00000000000000000000000000000000000000000000000000002D2D2DD21731\n      33FF6AE1EDFF71EFFCFF71EFFCFF71EFFCFF71EFFCFF71EFFCFF71EFFCFF71EF\n      FCFF71EFFCFF71EFFCFF71EFFCFF71EFFCFF70EEFBFF71EFFCFF70ECF9FF4DA3\n      ACFF010202FF020000FF121415FF101213FF010000FF000000FF4898A1FF70ED\n      FAFF71EFFCFF70EEFBFF71EFFCFF71F0FDFF71F0FDFF6CE5F2FF66D8E4FF3D81\n      88FF081112FF000000FF000000FF000000FF162F32FF6AE0ECFF72F1FEFF70EE\n      FBFF71EFFCFF71EFFCFF71EFFCFF71EFFCFF70EFFBFF71EFFCFF67E7F2FF49D2\n      D6FF4CD4D9FF4CD4D9FF4CD4D9FF4CD4D9FF4CD4D9FF4CD4D9FF4BD3D8FF47C6\n      CBFE0B1F20FF555555AA00000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000F5F5F50A333333CC000000FF010101FE000000FF000000FF575757FFEFEF\n      EFFFF4F4F4FFFBFBFBFF9C9C9CFF070707FF000000FF000000FF000000FF0000\n      00FF3B3B3BFFFFFFFFFFC8C8C8FF515151FF484848FF4F4F4FFF717171FF8E8E\n      8EFF696969FF000000FF000000FF000000FF000000FF505050FFF8F8F8FFF5F5\n      F5FFF5F5F5FFA7A7A7FF020202FF000000FF000000FF010101FE000000FF9D9D\n      9D62000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      000000000000D0D0D0302C2D30E11B1D25FF353640FF3E414CFF30343CFF1E21\n      32FF1B2136FF1F2131FF171B27FF0A0A2EFF040437FF040437FF03031DFF0303\n      06FF070712FF0A0A25FF060609FF070714FF0D0D1FF8A3A3A35EF9F9F9060000\n      0000000000000000000000000000000000000000000000000000000000000000\n      00000000000000000000000000000000000000000000E5E5E51A4C4C4CB80909\n      09FF0A0A09FF0C0D0EFF0D0E0FFF111418FF131517FF090D3EFF15194DFF686F\n      7CFF818A97FF6C7483FF444B5AFF212631FF23272FFE4D5563FF515B69FF8F90\n      9177FDFDFD020000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      000000000000D2D2D22D212121DE000000FF070808FE788E90FFCAECEFFF4B58\n      58FF000000FF000000FF010101FF070707FF1E1E1EFF414141FF767F81FFC1E4\n      E8FFC8ECEFFFC7EBEFFFC9ECF1FFC6EBEFFFC3E7EBFFC0E5E9FFC5EAEDFFCBEE\n      F1FFC6EAEDFFC9ECF0FFB0CFD2FF2E3637FF020202FF000000FF030303FF1515\n      15FF353434FF7C898BFFC5EAEEFFCBF0F3FFD1F4F7FFCDF1F3FFC6EBEEFFBFE5\n      E9FFB3D5D8FF202627FF000000FF4D5C5DFF94ACAEFF94ABADFF8DA6A8FF798F\n      91FF293132FF000000FF000000FF282828D7C9C9C93600000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000FF1E40\n      44FF6CE4F1FF71EFFCFF71EFFCFF71EFFCFF71EFFCFF71EFFCFF71EFFCFF71EF\n      FCFF71EFFCFF71EFFCFF71EFFCFF71EFFCFF71EFFCFF71EFFCFF70EEFBFF72F2\n      FFFF6EE9F6FF397980FF152E31FF0D1B1DFF204549FF63D2DDFF73F4FFFF70EE\n      FBFF71EFFCFF71EFFCFF71EFFCFF71EFFCFF71EFFCFF70EEFBFF70EEFBFF73F4\n      FFFF74F5FFFF50A9B3FF31676EFF47979EFF72F2FFFF70EEFBFF70EEFBFF71EF\n      FCFF71EFFCFF71EFFCFF71EFFCFF71EFFCFF71EFFCFF70EEFBFF6EECF9FF4FD6\n      DCFF4BD3D8FF4CD4D9FF4CD4D9FF4CD4D9FF4CD4D9FF4BD3D8FF4CD6DBFF3594\n      98FF000000FFDFDFDF2000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000009A9A9A65000000FF000000FF000000FF000000FF000000FFD2D2\n      D2FFF5F5F5FFF7F7F7FFDADADAFF0E0E0EFF000000FF000000FF000000FF0000\n      00FF4A4A4AFFFFFFFFFF707070FF000000FF000000FF000000FF000000FF0505\n      05FF6B6B6BFF0A0A0AFF000000FF000000FF030303FF818181FFFDFDFDFFF4F4\n      F4FFECECECFF484848FF000000FF000000FF000000FF000000FF1F1F1FE0EEEE\n      EE11000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      000000000000D8D8D828303235DC181B22FF22282EFF2A2F36FF2B2F38FF1E25\n      51FF282D4DFF323745FF25283DFF0A0A25FF040428FF05050BFF05051EFF0404\n      29FF06061DFF050525FF03030AFF030309FE020204FF202020EAADADAB55FCFC\n      FC03000000000000000000000000000000000000000000000000000000000000\n      000000000000000000000000000000000000FBFBFB049696966C070707FC0405\n      08FF050405FF070809FF070705FF0E0E10FF111211FF050623FF59627DFF767F\n      8CFF828B97FF7B8290FF5E6677FF4C5571FF2A2E39FF14161DFF5D5D60AEEEEE\n      EE11000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      000000000000FCFCFC0389898976070707F8000000FF242A2BFFA9C8CBFFAFD1\n      D5FF445153FF030304FF000000FF050505FF1B1B1BFF414040FF7F8E90FFC2E5\n      E8FFC7EBEDFFC7EBEFFFC5EAEDFFC3E8ECFFC3E8ECFFBEE3E7FFC2E7EAFFC8EC\n      F0FFCAEEF2FFCBEEF1FFC6EBF0FFAFD0D4FF5E7173FF222929FF0E1011FF1E20\n      20FF545D5EFFAFCDD1FFCAEEF1FFC6EBEEFFC8EBEEFFC5E9ECFFC3E9ECFFC4EA\n      EEFFC4E8EBFF697C7DFF010101FF0D1010FF667A7CFF8BA6A8FF7E9598FF333E\n      3EFF010101FE000000FF242424DBBDBDBD420000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      00000000000000000000000000000000000000000000EFEFEF10000000FF1F42\n      46FE6CE5F1FF71EFFCFF71EFFCFF71EFFCFF71EFFCFF71EFFCFF71EFFCFF71EF\n      FCFF71EFFCFF71EFFCFF71EFFCFF71EFFCFF71EFFCFF71EFFCFF71EFFCFF70EE\n      FBFF71F0FDFF75F7FFFF77FCFFFF76FAFFFF76FBFFFF72F1FEFF70EEFBFF71EF\n      FCFF71EFFCFF71EFFCFF71EFFCFF71EFFCFF71EFFCFF71EFFCFF71EFFCFF70EE\n      FBFF71EFFCFF73F4FFFF75F8FFFF74F5FFFF71EFFCFF71EFFCFF71EFFCFF71EF\n      FCFF71EFFCFF71EFFCFF71EFFCFF71EFFCFF71EFFCFF71EFFCFF6FEDFAFF56DB\n      E2FF4BD3D8FF4CD4D9FF4CD4D9FF4CD4D9FF4CD4D9FF4CD4D9FF4EDBE1FF0B1F\n      1FFF4B4B4BB4F7F7F70800000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      000000000000DCDCDC23292929D6000000FF000000FF000000FF000000FF5D5D\n      5DFFFBFBFBFFF5F5F5FFFFFFFFFF242424FF000000FF000000FF000000FF0000\n      00FF7E7E7EFFE7E7E7FF313131FF000000FF000000FF000000FF000000FF0000\n      00FF1F1F1FFF000000FF000000FF000000FF0B0B0BFFBEBEBEFFF9F9F9FFF6F6\n      F6FFCBCBCBFF000000FF000000FF000000FF000000FF000000FF8282827DFCFC\n      FC03000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      000000000000D5D5D52A313233D70F1012FF13161BFF17191DFF191F34FF2F33\n      3EFF3D3F49FF3E414AFF343840FF0F1111FF040438FF030300FF040403FF0404\n      01FF04054DFF04030AFF040407FF030307FF030303FE06060CFF26274CE0C8C8\n      C639FDFDFD020000000000000000000000000000000000000000000000000000\n      000000000000000000000000000000000000D9D9D9261F1F1FE9060609FF0404\n      0AFE060606FF05060CFF080926FF090A1DFF0B103CFF040B3EFF30477DFF5661\n      79FF767F93FF505979FF1E2139FF11122CFF161A24FF323337D9CBCBCB34FEFE\n      FE01000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      00000000000000000000ECECEC13444444BB000000FF010101FE475759FFBBE1\n      E4FFB3D6DAFF697D80FF272D2EFF0F1011FF252727FF636E6FFFB3D2D5FFCCF0\n      F4FFCDF2F4FFC5EAEEFFBDE2E7FFC6EBEEFFCDF0F4FFC5EBEEFFBFE4E8FFBDE3\n      E7FFC0E5E9FFC0E4E9FFBFE5E9FFBAE0E5FFB6DBDFFFAACBCFFF94AEB1FF94AF\n      B3FFADCDD1FFC4E9EDFFC4E9EDFFC2E6E9FFC4E8ECFFC4E9ECFFC4E8ECFFC7EC\n      F0FFC5EAEEFFA8C6C9FF101313FF000000FF1B2122FF57686AFF283031FF0101\n      01FE000000FF121212EDA5A5A55AFCFCFC030000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      00000000000000000000000000000000000000000000EDEDED12000000FF1936\n      39FF6BE2EEFF71EFFCFF71EFFCFF71EFFCFF71EFFCFF71EFFCFF71EFFCFF71EF\n      FCFF71EFFCFF71F0FDFF71EFFCFF70EEFBFF71EFFCFF71EFFCFF71EFFCFF71EF\n      FCFF71EFFCFF71EFFCFF70EEFBFF71EFFCFF70EFFCFF71EEFBFF71EFFCFF71EF\n      FCFF71EFFCFF71EFFCFF71EFFCFF71EFFCFF71EFFCFF71EFFCFF71EFFCFF71EF\n      FCFF71EFFCFF71EFFCFF71EFFCFF71EFFCFF71EFFCFF71EFFCFF71EFFCFF71EF\n      FCFF71EFFCFF71EFFCFF71EFFCFF71EFFCFF71EFFCFF71EFFCFF70EEFBFF5CDF\n      E8FF4BD3D8FF4CD4D9FF4CD4D9FF4CD4D9FF4BD3D8FF4EDBE1FF2E7F82FF0404\n      04FB9A9A9A650000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      000000000000000000006F6F6F90020202FD000000FF000000FF000000FF0000\n      00FFD9D9D9FFF8F8F8FFFFFFFFFF6C6C6CFF000000FF000000FF000000FF0000\n      00FFA2A2A2FFB1B1B1FF010101FF000000FF000000FF000000FF000000FF0000\n      00FF000000FF000000FF000000FF000000FF131313FFEEEEEEFFF6F6F6FFFDFD\n      FDFF4A4A4AFF000000FF000000FF000000FF000000FF181818E7CFCFCF300000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      000000000000B8B8B848131314F90E0F11FF0E0E11FF0F0F17FF181A20FF2124\n      2AFF2E3036FF32353EFF41434BFF252726FF040764FF05061EFF040409FF0303\n      0BFF040323FF030311FF040403FF070708FF070706FF04041AFE08080CFF4C4C\n      4DB8EBEBEB140000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000F8F8F80777777890050505FF050505FE0303\n      03FF060606FF0A0A0BFF0C0D0DFF101114FF252944FF686E82FF797F8BFF3C45\n      6AFF2B326BFF343C5FFF0D1E7BFF202A3EFF141622FD72727595F3F3F30C0000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000C4C4C43B151515EA000000FF030303FF829A\n      9CFFCCF1F5FFC9EEF2FFB8DADDFF9BB8BBFF9AB8BBFFBADCDFFFCFF3F5FFC6EA\n      EEFFC0E5E9FFBAE0E5FFBDE3E7FFC5EAEDFFC2E7EBFFC6EBEFFFC0E6EAFFBAE0\n      E5FFC7EAEEFFCBF0F2FFCCF0F2FFCBEFF1FFCCEEF1FFCBEEF2FFC4E9EDFFC0E5\n      E9FFBBE1E6FFBBE0E5FFBFE4E8FFC0E5E9FFC0E5E9FFC4E9EDFFC7EBEEFFC4E8\n      EBFFC2E6EBFFC8EDF1FF596A6CFF000000FF000000FF000000FF000000FF0000\n      00FF131313EC9B9B9B64FEFEFE01000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000FF0C19\n      1BFF68DCE8FF70EEFBFF71EFFCFF71EFFCFF71EFFCFF71F0FDFF6DE7F4FF66D7\n      E3FF5DC4CFFF59BCC7FF64D3DFFF6AE1EDFF71EFFCFF71EFFCFF70EEFBFF71EF\n      FCFF71EFFCFF71EFFCFF71EFFCFF71EFFCFF71EFFCFF71EFFCFF71EFFCFF71EF\n      FCFF71EFFCFF71EFFCFF71EFFCFF71EFFCFF71EFFCFF71EFFCFF71EFFCFF71EF\n      FCFF71EFFCFF71EFFCFF71EFFCFF71EFFCFF71EFFCFF71EFFCFF71EFFCFF71EF\n      FCFF71EFFCFF71EFFCFF71EFFCFF71EFFCFF71EFFCFF71EFFCFF71EFFCFF60E3\n      ECFF4CD4D9FF4CD4D9FF4CD4D9FF4BD3D8FF4CD4D9FF44BEC3FF050F0FFF1818\n      18E7EAEAEA150000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      00000000000000000000DCDCDC23090909F6010101FE000000FF000000FF0000\n      00FF515151FFFFFFFFFFFAFAFAFFB7B7B7FF000000FF000000FF000000FF0000\n      00FF858585FF999999FF000000FF000000FF000000FF000000FF000000FF0000\n      00FF000000FF000000FF000000FF000000FF3E3E3EFFFFFFFFFFF8F8F8FFCBCB\n      CBFF000000FF000000FF000000FF000000FF000000FF5A5A5AA5000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000F8F8F8077B7B7B880E0E14FF0B0C1AFF0A0C22FF0D0D11FF10111AFF1517\n      1DFF1C1F24FF1F2226FF303239FF1E1F33FF060616FF04051AFF040532FF0303\n      08FF030302FF030327FF050520FF06060FFF06060AFF04040DFF03030AFF1A19\n      1BECBAB9BA460000000000000000000000000000000000000000000000000000\n      00000000000000000000FDFDFD02C3C3C23D18181CEC030302FF030305FF0505\n      05FF090A0BFF0E1114FF101218FF242831FF7A808BFF9FA9B2FF7C8591FF707A\n      84FF97A1A8FF6B727DFF282E44FF0C1A67FF171B31F991919275FAFAFA050000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      00000000000000000000000000000000000089898976010101FE000000FF272E\n      2EFFA4C2C5FFC4EAEFFFBEE4EAFFC1E7ECFFCAEEF2FFC8EDF1FFC3E8ECFFC3E8\n      ECFFC3E8ECFFC7EBEFFFC8EDF0FFC1E5E9FFC0E5E9FFCAEEF1FFCDF0F4FFCFF2\n      F6FFCEF2F5FFCBEFF2FFCDF1F4FFD0F3F6FFCDF1F4FFCAEEF1FFC5E9ECFFC4EA\n      EDFFC4E9EEFFC2E7EBFFBEE4E8FFBCE2E7FFC2E8ECFFC4E9EDFFCBF0F4FFCCF1\n      F3FFCBEFF2FFCFF5F8FF869FA1FF000000FF000000FF010101FE000000FF0E0E\n      0EF19F9F9F600000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000292929D60000\n      00FF5CC3CEFF71F0FDFF71EFFCFF70EEFBFF72F1FEFF5BC1CBFF254F53FF050A\n      0BFF000000FF000000FF000000FF152D30FF3D8088FE6EE9F6FF73F3FFFF70EE\n      FBFF71EFFCFF71EFFCFF71EFFCFF71EFFCFF71EFFCFF71EFFCFF71EFFCFF71EF\n      FCFF71EFFCFF71EFFCFF71EFFCFF71EFFCFF71EFFCFF71EFFCFF71EFFCFF71EF\n      FCFF71EFFCFF71EFFCFF71EFFCFF71EFFCFF71EFFCFF71EFFCFF71EFFCFF71EF\n      FCFF71EFFCFF71EFFCFF71EFFCFF71EFFCFF71EFFCFF71EFFCFF71EFFCFF63E5\n      EFFF4CD4D9FF4CD4D9FF4BD3D8FF4CD5DAFF4AD0D5FF163E40FE000000FF6565\n      659A000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000575757A8000000FF000000FF000000FF0000\n      00FF0E0E0EFFCCCCCCFFF9F9F9FFF8F8F8FF000000FF000000FF000000FF0000\n      00FF1B1B1BFF898989FF000000FF000000FF000000FF000000FF000000FF0000\n      00FF000000FF000000FF000000FF000000FF838383FFFEFEFEFFFFFFFFFF4444\n      44FF000000FF000000FF000000FF010101FE0A0A0AF5B7B7B748000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000CDCDCD32212122E90A0A0FFF080819FE0B0B0FFF0D0D10FF0F1217FF1213\n      18FF12142CFF13162AFF161827FF15182FFF0E0F14FF070709FF040521FF0404\n      06FF07070AFF04051EFF030309FF030305FF030304FF030307FF030303FF0303\n      03FF3C3C3BC8CACACA35F7F7F708FEFEFE010000000000000000000000000000\n      0000FEFEFE01F6F6F609C3C3C33C434345C004040BFE04040FFE030305FF0606\n      05FF070707FF0A0B0DFF0F1114FF101115FF4E565DFF8895A1FF9AA6AEFF8895\n      9FFF6D7B88FF5E6875FF5C6774FF2B3240FF13191FFC74747491F4F4F40B0000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      000000000000000000000000000000000000E9E9E9163F3F3FC0000000FF0101\n      01FE242A2AFF75898AFFAFCED1FFC7E8EBFFC9EDF0FFC8ECF0FFCAEEF1FFCEF2\n      F5FFD5F8F9FFD3F5F7FFCEF2F5FFCCF0F3FFD2F3F6FFCEF0F3FFCBEFF1FFC9EC\n      EEFFBFE2E6FFBCE0E3FFBBDFE3FFB5DADEFFBCDEE2FFC3E5E8FFC0E3E6FFC0E2\n      E5FFBCDEE1FFB7D7DAFFAFD0D3FFA9C7CAFF9EBCBFFF97B5B8FF99B6B9FF9FBE\n      C1FFA2C3C7FF88A3A6FF202526FF000000FF010101FE000000FF090909F69090\n      906FF9F9F9060000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000979797680000\n      00FF2A5B60FE75F8FFFF70EEFBFF71F0FDFF5DC6D1FF060E0FFE010101FE0000\n      00FF0E0E0EF13E3E3EC1333333CC000000FF000000FF142B2EFE63D2DDFF72F1\n      FFFF70EEFBFF71EFFCFF71EFFCFF71EFFCFF71EFFCFF71EFFCFF71EFFCFF71EF\n      FCFF71EFFCFF71EFFCFF71EFFCFF71EFFCFF71EFFCFF71EFFCFF71EFFCFF71EF\n      FCFF71EFFCFF71EFFCFF71EFFCFF71EFFCFF71EFFCFF71EFFCFF71EFFCFF71EF\n      FCFF71EFFCFF71EFFCFF71EFFCFF71EFFCFF71EFFCFF71EFFCFF71EFFCFF65E6\n      F1FF4DD4DAFF4BD3D8FF4DD8DDFF4BD2D7FF133335FF000000FF000000FFF2F2\n      F20D000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000E0E0E01F000000FF000000FF000000FF0000\n      00FF010101FF6D6D6DFFFCFCFCFFFCFCFCFF464646FF000000FF000000FF0000\n      00FF000000FF161616FF131313FF000000FF000000FF000000FF000000FF0000\n      00FF000000FF000000FF000000FF000000FFCDCDCDFFFCFCFCFFC6C6C6FF0A0A\n      0AFF000000FF000000FF010101FE000000FF2E2E2ED100000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000FEFEFE01E5E5\n      E51A434343C2070707FF0B0B0CFE0A0B10FF0F0F0FFF0F1012FF111213FF0D0E\n      23FF0C0D2AFF0F1014FF0F1015FF0E101CFF11121CFF080816FF030957FF0305\n      23FF030417FF030432FF040302FF040403FF040404FF040435FF030309FF0303\n      02FE08080BFF272727DE616262A4A2A2A25ECECECE31E3E3E31CE2E2E21DD2D2\n      D22DAFAFAF50646464A0101010F4040408FF030314FF03030AFF04040DFF0404\n      04FF040404FF111418FF1B1F26FF49515CFF9AA5B1FF9AA6B1FF85919CFF7984\n      91FF5B6776FF555E6BFF434853FF282F37FF13161DFF2B2E30DFC7C7C739FEFE\n      FE01000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      00000000000000000000000000000000000000000000BFBFBF40202020DF0000\n      00FF000000FF000000FF121514FE2A3233FF3A4748FF4C5B5DFF556566FF5666\n      68FF546364FF4E5C5EFF4A585AFF485656FF424E4FFF3C4849FF394345FF353F\n      40FF313A3BFF2C3536FF273031FF272D2EFF252B2CFF212828FF1F2324FF1A20\n      21FF191D1EFF151819FF111413FF0D1010FE0A0C0BFF070808FF040404FF0506\n      06FF060808FF000000FF000000FF000000FF000000FF050505FA68686897F9F9\n      F906000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000EDEDED121717\n      17E8000000FF60CAD5FF72F3FFFF75F7FFFF0E1F21FE000000FF0B0B0BF4A7A7\n      A758000000000000000000000000F6F6F609585858A7050505FA050B0CFF55B6\n      BFFE70EDFAFF71F0FDFF70EEFBFF71EFFCFF71EFFCFF71EFFCFF71EFFCFF71EF\n      FCFF71EFFCFF71EFFCFF70EEFBFF71EFFCFF71F0FDFF71EFFCFF71EFFCFF71EF\n      FCFF71EFFCFF71EFFCFF71EFFCFF71EFFCFF71EFFCFF71EFFCFF71EFFCFF71EF\n      FCFF71EFFCFF71EFFCFF71EFFCFF71EFFCFF71EFFCFF71EFFCFF71EFFCFF67E9\n      F4FF4DD3D8FF46C4C8FF328D90FF030A0BFE000000FF000000FF898989760000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      000000000000000000000000000000000000585858A7000000FF010101FE0000\n      00FF000000FF252525FFD5D5D5FFF9F9F9FF909090FF000000FF000000FF1010\n      10FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000\n      00FF010101FF090909FF000000FF101010FFFFFFFFFFF8F8F8FF616161FF0000\n      00FF000000FF000000FF010101FE000000FFBABABA4500000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000ECECEC137272\n      7292080808FC070707FE0D0D0BFF07071BFF0E0E0BFF0F0F11FF0F1011FF0C0F\n      22FF121214FF111215FF101115FF1C1E21FF0E0F36FF06064EFF040328FF0304\n      19FF030358FF030441FF040413FF040405FF040405FF040405FF040300FF0304\n      0AFE050720FE030205FF020200FF05081CFF201F1CE3424244C239393BC92525\n      25DF0A0A0AFA030303FF030304FF03030AFE040419FE030313FF040405FF0606\n      06FF0B0C0EFF272D35FF49515EFF6B737EFF96A2ACFF6D7987FF657281FF4F59\n      66FF3F4652FF313640FF20262DFF1A2025FF11141AFF12161AFF4A4B4DBDE3E3\n      E31C000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000BBBBBB444242\n      42BD090909F6000000FF000000FF000000FF000000FF000000FF000000FF0000\n      00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000\n      00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000\n      00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000\n      00FF000000FF000000FF050505FA151515EA414141BE9292926DF1F1F10E0000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000FEFEFE018383\n      837C000000FF122628FE68DDE9FF64D4DFFF000000FF010101FEC2C2C23D0000\n      00000000000000000000000000000000000000000000A0A0A05F121212ED0000\n      00FF336D73FE6ADFECFF73F4FFFF70EEFBFF71EFFCFF71EFFCFF71EFFCFF71EF\n      FCFF71EFFCFF71EFFCFF74F5FFFF71EFFCFF5DC6D1FF6BE3EFFF73F3FFFF70EE\n      FBFF71EFFCFF71EFFCFF71EFFCFF71EFFCFF71EFFCFF71EFFCFF71EFFCFF71EF\n      FCFF71EFFCFF71EFFCFF71EFFCFF71EFFCFF70EEFBFF72F1FEFF75F7FFFF53B9\n      C2FF225C5FFF091B1CFE000000FF000000FF000000FF6161619EF9F9F9060000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      000000000000000000000000000000000000D6D6D629000000FF000000FF0000\n      00FF000000FF000000FF959595FFF5F5F5FFD0D0D0FF000000FF252525FF4E4E\n      4EFF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000\n      00FF0C0C0CFF5F5F5FFF000000FF5C5C5CFFFCFCFCFFD0D0D0FF202020FF0000\n      00FF000000FF000000FF000000FF303030CF0000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      00000000000000000000000000000000000000000000F3F3F30C8484847D0707\n      08FD0A0A0AFF0B0B0AFE0C0C0FFF0A0A11FF090912FF0E0F10FF0E0E0FFF0B0C\n      15FF0E0F0FFF101217FF131519FF22252CFF3B3C3FFF0A0B35FF0D0E33FF0100\n      1EFF090A14FF030304FF020219FF030316FF030315FF04031AFF03094AFF0307\n      85FF040419FF04040CFF030305FE040954FF040530FF030312FF030304FF0303\n      03FF030303FF040404FF030303FF030404FF030306FF050505FF060707FF0E10\n      12FF475159FF808A95FF909BA4FFA7B1B7FF798491FF555C6BFF323B43FF3135\n      3DFF353A40FF252D31FF262B33FF14181EFF16171FFE15181EFF0C0D10FF696B\n      759CF4F4F40B0000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      000000000000000000000000000000000000000000000000000000000000EDED\n      ED12ADADAD525E5E5EA12A2A2AD50E0E0EF1050505FA010101FE010101FE0101\n      01FE010101FE020202FD020202FD030303FC040404FB050505FA080808F70A0A\n      0AF50C0C0CF30F0F0FF0131313EC161616E91B1B1BE4212121DE272727D82E2E\n      2ED1353535CA3A3A3AC53E3E3EC1414141BE474747B84B4B4BB4515151AE5757\n      57A86464649B7E7E7E81B5B5B54AD6D6D629EDEDED12FDFDFD02000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      000000000000000000000000000000000000000000000000000000000000FDFD\n      FD023F3F3FC0000000FF1A393CFE5BC1CBFF000000FF0F0F0FF0EBEBEB140000\n      0000000000000000000000000000000000000000000000000000CCCCCC330D0D\n      0DF2000000FF0F2122FE56B8C1FF76FAFFFF71EFFCFF70EEFBFF71EFFCFF70EE\n      FBFF71F0FDFF74F5FFFF4FA9B2FF102325FF070F10FF0C1A1CFF54B4BEFF73F5\n      FFFF70EEFBFF71EFFCFF71EFFCFF71EFFCFF71EFFCFF71EFFCFF71EFFCFF71EF\n      FCFF71EFFCFF71EFFCFF71EFFCFF71EFFCFF74F6FFFF67DAE6FF244C51FF0409\n      09FE000000FF000000FF000000FF4F4F4FB0CFCFCF30FAFAFA05000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      000000000000000000000000000000000000F8F8F807575757A8000000FF0101\n      01FE000000FF000000FF2F2F2FFFEAEAEAFFEFEFEFFF8F8F8FFFCFCFCFFF3333\n      33FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000\n      00FF0C0C0CFFB2B2B2FF878787FFDEDEDEFFF4F4F4FF8A8A8AFF000000FF0000\n      00FF000000FF010101FE000000FFBDBDBD420000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      000000000000000000000000000000000000EFEFEF107F7F808509090AFF0707\n      09FF07070AFE0D0D14FF0B0C21FF0E0E0FFF090A33FF0D0E15FF0A0A2AFF0E0F\n      10FF0D0F1FFF14161EFF292F3DFF646B72FF444F91FF5A6790FF414C8CFF4B64\n      7EFF53596EFF5A626CFF20232CFF08092FFF060606FF040403FF040527FF0606\n      16FF040407FF030317FF030640FF030637FF03030DFF030300FF030303FF0303\n      03FF050505FF040505FF040404FF030302FF040505FF0C0E10FF1D252AFF3942\n      4BFF737D87FF7E8993FF929BA3FFBEC7CEFFA8B2B8FF7D858DFF75808AFF525B\n      64FF484D56FF4F545EFF3C3F48FF31373DFF1D2228FF131727FF0A0D3FFE1011\n      1BF8A0A0A062F9F9F90600000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      000000000000FCFCFC03ECECEC13D0D0D02FBDBDBD42B3B3B34CB0B0B04FB1B1\n      B14EB1B1B14EB3B3B34CB5B5B54AB9B9B946BBBBBB44BEBEBE41C3C3C33CC6C6\n      C639CACACA35D0D0D02FD4D4D42BD9D9D926DFDFDF20E5E5E51AEBEBEB14F1F1\n      F10EF6F6F609F8F8F807F9F9F906FAFAFA05FBFBFB04FCFCFC03FCFCFC03FDFD\n      FD02FEFEFE010000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      000000000000494949B6010101FE0A1718FF010101FE000000FFACACAC530000\n      000000000000000000000000000000000000000000000000000000000000E3E3\n      E31C1E1E1EE1000000FF000000FF244E52FE5EC6D1FF6AE1EDFF6BE4F0FF69DF\n      EBFF5BC1CCFF214548FF000000FF000000FF000000FF000000FF000000FF4BA0\n      A9FF72F1FEFF71EFFCFF71EFFCFF71EFFCFF71EFFCFF71EFFCFF71EFFCFF71EF\n      FCFF71EFFCFF70EEFBFF71EFFCFF6FEBF8FF418A92FE000000FF010101FE1010\n      10EF2F2F2FD08F8F8F70F2F2F20D000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      00000000000000000000000000000000000000000000B5B5B54A030303FC0000\n      00FF000000FF000000FF000000FFB5B5B5FFF7F7F7FFFEFEFEFF9A9A9AFF0505\n      05FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000\n      00FF000000FF484848FFF1F1F1FFF6F6F6FFE6E6E6FF272727FF000000FF0000\n      00FF010101FE000000FF313131CEF4F4F40B0000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000F7F7F7088D8E8F760F1117FB0F1117FF1416\n      23FE1B1D29FF212352FF1D224CFF2A2C42FF181B49FF0C1458FF1A1C23FF1D20\n      29FF191D3FFF4D546BFF788199FFAEB6BCFFA7B1B4FF939EA5FF99A2A4FF536A\n      8DFF546485FF606B76FF515863FF2C324FFF272E4BFF222729FF0C0E23FF0B0D\n      38FF141632FF12151DFF151715FF161819FF0A0D10FF0B0E11FF2F3338FF5159\n      5EFF51585FFF5C646BFF50575EFF4C5258FF576068FF4E555FFF5D656DFF8A95\n      9FFFADB6BEFFB9C1C8FFCAD1D5FFC6CDD1FFAAB2B8FF9AA5A9FF7C878EFF6B72\n      7CFF565D64FF676F78FF5F666EFF4C5158FF202630FF101626FF101413FE0F0F\n      11FF2C2C2DD8B2B2B24EFCFCFC03000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      000000000000000000009494946B1C1C1CE3000000FF000000FF121212EDECEC\n      EC13000000000000000000000000000000000000000000000000000000000000\n      0000F2F2F20D7070708F080808F7000000FF000000FF162F31FF1C3C3FFF1021\n      23FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0001\n      01FF47979FFF72F1FEFF70EEFBFF71EFFCFF71EFFCFF71EFFCFF71EFFCFF71EF\n      FCFF71EEFBFF70EEFBFF75F9FFFF346F75FE000000FF1F1F1FE08C8C8C73D7D7\n      D728000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      00000000000000000000000000000000000000000000EFEFEF103E3E3EC10000\n      00FF000000FF000000FF000000FF2E2E2EFFFAFAFAFFE5E5E5FF343434FF0000\n      00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000\n      00FF000000FF020202FFAEAEAEFFF9F9F9FFA5A5A5FF000000FF000000FF0000\n      00FF000000FF000000FF96969669FEFEFE010000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000BBBBBC4A202229FB363A44FF5B626CFE848A\n      93FF898F9AFF8D919CFF444C6AFF404652FF252C57FF22272DFF262A2BFF242C\n      63FF7C8293FFBFC5CAFFA0AAB1FFB1BAC2FFAEB8C0FF99A4ABFF546786FF1726\n      69FF394574FF585E65FF484E4DFF111B62FF14205FFF2A3353FF112069FF6268\n      74FF737B83FF646E78FF525B65FF4F565EFF6D747CFF929CA4FFA9B2B9FFB9C3\n      C8FFA3ADB4FFB5BEC6FFA7B1B9FFB8C1C8FFBCC4C9FFB9C1C7FFBDC6CCFFBEC6\n      CCFFC2CCD0FFCAD2D6FFCBD4D7FFC5CCD2FFBCC6CAFFBBC6C9FFB2BCC0FF8F99\n      A0FF5D646DFF373F46FF2D3238FF1E2328FF141926FF1A1F29FF15181DFF0808\n      09FF0B0B0FFF171717F09C9C9C67F8F8F8070000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000EFEFEF109292926D0A0A0AF5000000FF3A3A\n      3AC5000000000000000000000000000000000000000000000000000000000000\n      000000000000FCFCFC03E7E7E7189393936C464646B9222222DD2D2D2DD25353\n      53AC7B7B7B849D9D9D62B6B6B649BDBDBD42A8A8A8575C5C5CA3000000FF0000\n      00FF010202FE51ACB4FF73F4FFFF70EEFBFF71EFFCFF71EFFCFF71EFFCFF71EF\n      FCFF70EEFBFF77FBFFFF3A7B82FF000000FF141414EBD8D8D827000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      00000000000000000000000000000000000000000000000000008F8F8F700505\n      05FA010101FE000000FF000000FF000000FFB0B0B0FFE1E1E1FF303030FF0000\n      00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000\n      00FF000000FF000000FFA1A1A1FFFDFDFDFF1D1D1DFF000000FF000000FF0000\n      00FF000000FF262626D9DCDCDC23000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000F2F2F20D9FA0A16A676B73E07E8590FB777E\n      8BFF717987FF69707DFE555C69FF3C424EFF2D3243FF3A4068FF1E2474FFB9C1\n      BCFFC3CBCEFFA8B1B8FFAEB7BDFFABB5BCFF9CA7AFFF7D8994FF757E89FF6672\n      79FF2E385EFF384264FF233055FF2C3775FF666F75FF878F98FF9CA4A9FF929B\n      A5FF969FA7FF939BA4FFCCD2D6FFC4CCD1FFB1BAC1FFA9B2BAFFABB4BCFFC7CD\n      D1FFCED6DAFFC8D1D6FFCBD4D8FFC6D1D4FFBDC6CCFFBFC7CDFFB4BFC6FFC9D2\n      D6FFD4DADCFFD5DDDFFFD2D8DBFFCED5D9FFD1D8DBFFCBD3D6FFB6C0C5FFC3CB\n      D0FFBAC4CAFFBEC8CCFF7F8A8FFF475156FF1D202EFF151619FF111113FF0504\n      05FF0C0C0CFE0E0F11FF121215F7A0A0A062F6F6F60900000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      00000000000000000000000000000000000000000000FDFDFD02A3A3A35C6161\n      619ED3D3D32C0000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000D4D4D42B1515\n      15EA000000FF000000FF53AFB9FF71F0FDFF71EFFCFF70EEFBFF70EEFBFF71EF\n      FCFF71EFFCFF4A9DA5FE020404FF060606F9A0A0A05F00000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000F9F9F9061616\n      16E9000000FF000000FF000000FF000000FF2B2B2BFFEAEAEAFF313131FF0000\n      00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000\n      00FF000000FF000000FFB3B3B3FFA0A0A0FF000000FF000000FF000000FF0000\n      00FF010101FE6969699600000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      000000000000000000000000000000000000FAFAFA05D6D6D6298E8F90807173\n      78CD636A71FE636B76FF5F6571FF606671FE454B56FE596073FF869092FFD9DF\n      E2FFC0C9CEFFCDD3DAFFB3BDC3FFA2ACB4FF89949BFF7B8792FE5F6E85FF5564\n      7EFF6E788CFF79848FFF929DA3FFA7B0B4FFAFB9C1FF9EAAB2FFA5AFB6FFBEC7\n      CDFFC2C9CEFFD1D7DBFFC4CBD0FFB9C0C8FFC2C9CDFEBEC7CCFFBDC5CBFFBCC7\n      CCFFBBC5CCFFBCC6CDFFBDC8CCFFB9C3CAFFB0B8C1FFB6BEC6FFB7C1C8FFC0CA\n      CFFFCBD4D9FFCCD3D9FFBEC5CAFFC0C6CBFFC9D0D4FFD1D8DCFFC4CDD1FFADB6\n      BDFFAEB8BEFFACB5BCFFB0BAC1FFA6B1BAFFB6BEC4FE8B96A1FF6F7782FF3C42\n      48FF0B0B0EFF020100FF0A0A0AFF212122E6CECECE3300000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      000000000000000000000000000000000000000000000000000000000000E2E2\n      E21D3B3B3BC4000000FF010202FE3C8087FF71F0FDFF74F6FFFF75F9FFFF6DE7\n      F4FF38787EFE030707FF000000FF8484847B0000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000008383\n      837C000000FF010101FE000000FF000000FF090909FF8D8D8DFF2D2D2DFF0000\n      00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000\n      00FF000000FF000000FFA6A6A6FF232323FF000000FF000000FF000000FF0000\n      00FF0E0E0EF1CECECE3100000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      00000000000000000000000000000000000000000000FEFEFE01F8F8F807DDDE\n      DE22A0A1A16453575AD7474E55FF545A63FF8E969CFFB2B8BBFF7F8589FF8B91\n      95FF8D959AFF696F74FF62686EFF73797FFF879096FF909BA2FF9CA7B0FF939C\n      A4FFA6AFB3FF868C90FF787D7FF666696CDD75787BEF808588FE83898BFB9BA1\n      A4FFBBBFC1FFC1C9CDFFBFC9CCFFC1C9CDFFC2CACDFFBDC4C7FF93999DFF636A\n      6DED7B7F83F48A9194FF777E81F5616567E17F868DFF9DA6AAFF899196FFA4AC\n      B1FFA9B1B6FFA7B0B4FFACB4BAFFCBD1D4FFC3C8CDFFBAC0C5FFCBD2D7FFDDE2\n      E5FFD0D7DAFFC3C9CEFFB1B7BCFFC1CACEFFC4C9CDFFB4BABFFF90979BFF7277\n      7CFF555C61FF505961FF1F2224FF555555ACECECEC1300000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000F5F5F50A575757A8000000FF000101FF152C2FFE47979EFF3B7E85FF0E1F\n      20FF000000FF000000FF9A9A9A65000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      000000000000000000000000000000000000000000000000000000000000FCFC\n      FC030B0B0BF4000000FF000000FF000000FF000000FF161616FF0C0C0CFF0000\n      00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000\n      00FF000000FF000000FF212121FF020202FF000000FF000000FF010101FE0000\n      00FF4A4A4AB50000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000FCFCFC03E5E5E51AA7A8A75E8B8B8A7E9292926D9A9A9A65B8B8B847BABA\n      BA45B5B5B54AC2C2C23DBFBFBF40B2B2B24D9A9A9A65858485968080819C8383\n      839097979768C2C2C23DD7D7D728DFDFDF20DCDCDC23D2D2D22DC8C8C837B7B7\n      B7489393936C838383838080808C808080888484847B8C8C8C73BABABA45D2D2\n      D22DD4D4D42BD1D1D12ED6D6D629D9D9D926C2C2C23DABABAB54B6B6B649ADAD\n      AD52A4A4A45B9E9E9E61868686797F808091868787A67B7B7B9B7E7F7FA28485\n      86AD8282839F808181889090906F89898A868585857A90908F71B7B7B748C7C7\n      C738C4C4C43BB0B0B04FB9B9B948E9E9E916FDFDFD0200000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      00000000000000000000A0A0A05F181818E7050505FA000000FF000000FF0808\n      08F7202020DFB1B1B14E00000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      00008B8B8B74000000FF010101FE000000FF000000FF000000FF000000FF0000\n      00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000\n      00FF000000FF000000FF000000FF000000FF000000FF000000FF010101FE0000\n      00FFD5D5D52A0000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      00000000000000000000000000000000000000000000FEFEFE01FBFBFB04FDFD\n      FD02000000000000000000000000000000000000000000000000000000000000\n      00000000000000000000FDFDFD02FDFDFD02FEFEFE0100000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000FDFDFD02FBFBFB04FAFAFA05F9F9F906F9F9\n      F906FBFBFB04FDFDFD02FEFEFE0100000000FEFEFE0100000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000EEEEEE11A2A2A25D7F7F7F808484847BABAB\n      AB54F5F5F50A0000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000ECECEC13191919E6000000FF000000FF000000FF000000FF000000FF0000\n      00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000\n      00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF5050\n      50AF000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      000000000000000000000000000000000000424D3E000000000000003E000000\n      2800000080010000C00000000100010000000000002400000000000000000000\n      000000000000000000000000FFFFFF00FFFFFFFFFC00003FFFFFFFFFFFFFFFFF\n      FFC007FFFFFFFFFF000000000000000000000000000000000000000000000000\n      FFFFFFFFC0000003FFFFFFFFFFFFFFFFFFC003FFFFFFFFFF0000000000000000\n      00000000000000000000000000000000FFFFFFFE000000007FFFFFFFFFFFFFFF\n      FFC003FFFFFFFFFF000000000000000000000000000000000000000000000000\n      FFFFFFF8000000001FFFFFFFFFFFFFFFFF8003FFFFFFFFFF0000000000000000\n      00000000000000000000000000000000FFFFFFE00000000003FFFFFFFFFFFFFF\n      FF8001FFFFFFFFFF000000000000000000000000000000000000000000000000\n      FFFFFF800000000000FFFFFFFFFFFFFFFF0000FFFFFFFFFF0000000000000000\n      00000000000000000000000000000000FFFFFE0000000000007FFFFFFFFFFFFF\n      FF0000FFFFFFFFFF000000000000000000000000000000000000000000000000\n      FFFFF80000000000001FFFFFFFFFFFFFFE00007FFFFFFFFF0000000000000000\n      00000000000000000000000000000000FFFFF00000000000000FFFFFFFFFFFFF\n      FE00007FFFFFFFFF000000000000000000000000000000000000000000000000\n      FFFFE000000000000003FFFFFFFFFFFFFE00007FFFFFFFFF0000000000000000\n      00000000000000000000000000000000FFFF8000000000000001FFFFFFFFFFFF\n      FC00003FFFFFFFFF000000000000000000000000000000000000000000000000\n      FFFF0000000000000000FFFFFFFFFFFFFC00003FFFFFFFFF0000000000000000\n      00000000000000000000000000000000FFFE00000000000000007FFFFFFFFFFF\n      F800001FFFFFFFFF000000000000000000000000000000000000000000000000\n      FFFC00000000000000003FFFFFFFFFFFF000001FFFFFFFFF0000000000000000\n      00000000000000000000000000000000FFF800000000000000001FFFFFFFFFFF\n      F000000FFFFFFFFF000000000000000000000000000000000000000000000000\n      FFF000000000000000000FFFFFFFFFFFF000000FFFFFFFFF0000000000000000\n      00000000000000000000000000000000FFE0000000000000000007FFFFFFFFFF\n      E000000FFFFFFFFF000000000000000000000000000000000000000000000000\n      FFC0000000000000000003FFFFFFFFFFE0000007FFFFFFFF0000000000000000\n      00000000000000000000000000000000FFC0000000000000000001FFFFFFFFFF\n      C0000007FFFFFFFF000000000000000000000000000000000000000000000000\n      FF80000000000000000001FFFFFFFFFFC0000003FFFFFFFF0000000000000000\n      00000000000000000000000000000000FF00000000000000000000FFFFFFFFFF\n      80000001FFFFFFFF000000000000000000000000000000000000000000000000\n      FF000000000000000000007FFFFFFFFF80000001FFFFFFFF0000000000000000\n      00000000000000000000000000000000FE000000000000000000007FFFFFFFFF\n      80000001FFFFFFFF000000000000000000000000000000000000000000000000\n      FC000000000000000000003FFFFFFFFF00000001FFFFFFFF0000000000000000\n      00000000000000000000000000000000FC000000000000000000003FFFFFFFFF\n      00000000FFFFFFFF000000000000000000000000000000000000000000000000\n      F8000000000000000000001FFFFFFFFE000000007FFFFFFF0000000000000000\n      00000000000000000000000000000000F8000000000000000000000FFFFFFFFC\n      000000007FFFFFFF000000000000000000000000000000000000000000000000\n      F0000000000000000000000FFFFFFFFC000000003FFFFFFF0000000000000000\n      00000000000000000000000000000000F0000000000000000000000FFFFFFFFC\n      000000003FFFFFFF000000000000000000000000000000000000000000000000\n      E00000000000000000000007FFFFFFF8000000003FFFFFFF0000000000000000\n      00000000000000000000000000000000E00000000000000000000007FFFFFFF8\n      000000001FFFFFFF000000000000000000000000000000000000000000000000\n      E00000000000000000000003FFFFFFF0000000001FFFFFFF0000000000000000\n      00000000000000000000000000000000C00000000000000000000003FFFFFFF0\n      000000000FFFFFFF000000000000000000000000000000000000000000000000\n      C00000000000000000000003FFFFFFE0000000000FFFFFFF0000000000000000\n      00000000000000000000000000000000C00000000000000000000001FFFFFFE0\n      0000000007FFFFFF000000000000000000000000000000000000000000000000\n      800000000000000000000001FFFFFFE00000000007FFFFFF0000000000000000\n      00000000000000000000000000000000800000000000000000000001FFFFFFC0\n      0000000007FFFFFF000000000000000000000000000000000000000000000000\n      800000000000000000000001FFFFFFC00000000003FFFFFF0000000000000000\n      00000000000000000000000000000000800000000000000000000000FFFFFF80\n      0000000001FFFFFF000000000000000000000000000000000000000000000000\n      000000000000000000000000FFFFFF000000000001FFFFFF0000000000000000\n      00000000000000000000000000000000000000000000000000000000FFFFFF00\n      0000000000FFFFFF000000000000000000000000000000000000000000000000\n      000000000000000000000000FFFFFF000000000000FFFFFF0000000000000000\n      00000000000000000000000000000000000000000000000000000000FFFFFE00\n      0000000000FFFFFF000000000000000000000000000000000000000000000000\n      000000000000000000000000FFFFFE0000000000007FFFFF0000000000000000\n      00000000000000000000000000000000000000000000000000000000FFFFFC00\n      00000000007FFFFF000000000000000000000000000000000000000000000000\n      000000000000000000000000FFFFFC0000000000003FFFFF0000000000000000\n      00000000000000000000000000000000000000000000000000000000FFFFF800\n      00000000003FFFFF000000000000000000000000000000000000000000000000\n      000000000000000000000000FFFFF80000000000001FFFFF0000000000000000\n      00000000000000000000000000000000000000000000000000000000FFFFF800\n      00000000001FFFFF000000000000000000000000000000000000000000000000\n      000000000000000000000000FFFFF00000000000001FFFFF0000000000000000\n      00000000000000000000000000000000000000000000000000000000FFFFF000\n      00000000000FFFFF000000000000000000000000000000000000000000000000\n      000000000000000000000000FFFFE00000000000000FFFFF0000000000000000\n      00000000000000000000000000000000000000000000000000000000FFFFC000\n      000000000007FFFF000000000000000000000000000000000000000000000000\n      000000000000000000000000FFFFC000000000000003FFFF0000000000000000\n      00000000000000000000000000000000000000000000000000000000FFFFC000\n      000000000003FFFF000000000000000000000000000000000000000000000000\n      000000000000000000000000FFFFC000000000000003FFFF0000000000000000\n      00000000000000000000000000000000000000000000000000000000FFFFC000\n      000000000003FFFF000000000000000000000000000000000000000000000000\n      800000000000000000000000FFFFC000000000000007FFFF0000000000000000\n      00000000000000000000000000000000800000000000000000000001FFFFE000\n      000000000007FFFF000000000000000000000000000000000000000000000000\n      800000000000000000000001FFFFE00000000000000FFFFF0000000000000000\n      00000000000000000000000000000000800000000000000000000001FFFFF000\n      00000000000FFFFF000000000000000000000000000000000000000000000000\n      C00000000000000000000001FFFFF00000000000001FFFFF0000000000000000\n      00000000000000000000000000000000C00000000000000000000003FFFFF800\n      00000000001FFFFF000000000000000000000000000000000000000000000000\n      C00000000000000000000003FFFFF80000000000001FFFFF0000000000000000\n      00000000000000000000000000000000E00000000000000000000003FFFFF800\n      00000000003FFFFF000000000000000000000000000000000000000000000000\n      E00000000000000000000007FFFFFC0000000000007FFFFF0000000000000000\n      00000000000000000000000000000000E00000000000000000000007FFFFFE00\n      00000000007FFFFF000000000000000000000000000000000000000000000000\n      F0000000000000000000000FFFFFFE000000000000FFFFFF0000000000000000\n      00000000000000000000000000000000F0000000000000000000000FFFFFFF00\n      0000000000FFFFFF000000000000000000000000000000000000000000000000\n      F8000000000000000000001FFFFFFF000000000000FFFFFF0000000000000000\n      00000000000000000000000000000000F8000000000000000000001FFFFFFF00\n      0000000000FFFFFF000000000000000000000000000000000000000000000000\n      FC000000000000000000003FFFFFFF800000000001FFFFFF0000000000000000\n      00000000000000000000000000000000FC000000000000000000003FFFFFFF80\n      0000000003FFFFFF000000000000000000000000000000000000000000000000\n      FE000000000000000000007FFFFFFFC00000000003FFFFFF0000000000000000\n      00000000000000000000000000000000FF000000000000000000007FFFFFFFC0\n      0000000007FFFFFF000000000000000000000000000000000000000000000000\n      FF00000000000000000000FFFFFFFFE00000000007FFFFFF0000000000000000\n      00000000000000000000000000000000FF80000000000000000001FFFFFFFFE0\n      0000000007FFFFFF000000000000000000000000000000000000000000000000\n      FFC0000000000000000003FFFFFFFFE0000000000FFFFFFF0000000000000000\n      00000000000000000000000000000000FFE0000000000000000003FFFFFFFFF0\n      000000000FFFFFFF000000000000000000000000000000000000000000000000\n      FFE0000000000000000007FFFFFFFFF8000000001FFFFFFF0000000000000000\n      00000000000000000000000000000000FFF000000000000000000FFFFFFFFFF8\n      000000003FFFFFFF000000000000000000000000000000000000000000000000\n      FFF800000000000000001FFFFFFFFFFC000000003FFFFFFF0000000000000000\n      00000000000000000000000000000000FFFC00000000000000003FFFFFFFFFFC\n      000000003FFFFFFF000000000000000000000000000000000000000000000000\n      FFFE00000000000000007FFFFFFFFFFC000000003FFFFFFF0000000000000000\n      00000000000000000000000000000000FFFF0000000000000000FFFFFFFFFFFE\n      000000007FFFFFFF000000000000000000000000000000000000000000000000\n      FFFFC000000000000001FFFFFFFFFFFE00000000FFFFFFFF0000000000000000\n      00000000000000000000000000000000FFFFE000000000000007FFFFFFFFFFFF\n      00000000FFFFFFFF000000000000000000000000000000000000000000000000\n      FFFFF00000000000000FFFFFFFFFFFFF80000001FFFFFFFF0000000000000000\n      00000000000000000000000000000000FFFFFC0000000000003FFFFFFFFFFFFF\n      80000001FFFFFFFF000000000000000000000000000000000000000000000000\n      FFFFFE0000000000007FFFFFFFFFFFFF80000001FFFFFFFF0000000000000000\n      00000000000000000000000000000000FFFFFF800000000001FFFFFFFFFFFFFF\n      80000003FFFFFFFF000000000000000000000000000000000000000000000000\n      FFFFFFE00000000007FFFFFFFFFFFFFFC0000003FFFFFFFF0000000000000000\n      00000000000000000000000000000000FFFFFFF8000000001FFFFFFFFFFFFFFF\n      E0000007FFFFFFFF000000000000000000000000000000000000000000000000\n      FFFFFFFF00000000FFFFFFFFFFFFFFFFE0000007FFFFFFFF0000000000000000\n      00000000000000000000000000000000FFFFFFFFE0000007FFFFFFFFFFFFFFFF\n      F000000FFFFFFFFF000000000000000000000000000000000000000000000000\n      FFFFFFFFFE00007FFFFFFFFFFFFFFFFFF000000FFFFFFFFF0000000000000000\n      00000000000000000000000000000000FFFFFFFFFFE003FFFFFFFFFFFFFFFFFF\n      FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF80FFFFFFFFFFFFF\n      FFFFFFFFFFE003FFFFFFFFFFFFFFFFFFFFFFFF1FFFFFFFFFFFFFFFFFFFFFFFFF\n      FFFFFFFFFFFFFFFFC001FFFFFFFFFFFFFFFFFFFFFFC001FFFFFFFFFFFFFFFFFF\n      FFFFFF07FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00007FFFFFFFFFFF\n      FFFFFFFFFF8001FFFFFFFFFFFFFFFFFFFFFFFF03FFFFFFFFFFFFFFFFFFFFFFFF\n      FFFFFFFFFFFFFFFC00001FFFFFFFFFFFFFFFFFFFFF8000FFFFFFFFFFFFFFFFFF\n      FFFFFF01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8000007FFFFFFFFFF\n      FFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFF\n      FFFFFFFFFFFFFFF0000003FFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFF\n      FFFFFF803FFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFE0000001FFFFFFFFFF\n      FFFFFFFFFF00007FFFFFFFFFFFFFFFFFFFFFFFC01FFFFFFFFFFFFFFFFFFFF000\n      07FFFFFFFFFFFFE0000000FFFFFFFFFFFFFFFFFFFE00007FFFFFFFFFFFFFFFFF\n      FFFFFFC00FFFFFFFFFFFFFFFFFF0000001FFFFFFFFFFFFC00000007FFFFFFFFF\n      FFFFFFFFFE00003FFFFFFFFFFFFFFFFFFE0FFFE007FFFFFFFFFFFFFF80000000\n      00FFFFFFFFFFFFC00000007FFFFFFFFFFFFFFFFFFC00003FFFFFFFFFFFFFFFFF\n      FC07FFF003FFFFFFFFFFFFFE00000000007FFFFFFFFFFF800000003FFFFFFFFF\n      FFFFFFFFFC00001FFFFFFFFFFFFFFFFFF807FFF003FFFFFFFFFFFFFC00000000\n      007FFFFFFFFFFF000000003FFFFFFFFFFFFFFFFFF800000FFFFFFFFFFFFFFFFF\n      F007FFF800FFFFFFFFFFFFF800000000003FFFFFFFFFFC000000001FFFFFFFFF\n      FFFFFFFFF800000FFFFFFFFFFFFFFFFFE00FFFFC00FFFFFFFFFFFFF000000000\n      001FFFFFFFFFF8000000000FFFFFFFFFFFFFFFFFF000000FFFFFFFFFFFFFFFFF\n      E01FFFFC007FFFFFFFFFFFE000000000001FFFFFFFFFF0000000000FFFFFFFFF\n      FFFFFFFFF000000FFFFFFFFFFFFFFFFF803FFFFC003FFFFFFFFFFFC000000000\n      001FFFFFFFFFE00000000007FFFFFFFFFFFFFFFFF0000007FFFFFFFFFFFFFFFF\n      803FFFFE001FFFFFFFFFFF8000000000000FFFFFFFFFC00000000003FFFFFFFF\n      FFFFFFFFE0000007FFFFFFFFFFFFFFFF007FFFFE001FFFFFFFFFFF0000000000\n      0007FFFFFFFF800000000001FFFFFFFFFFFFFFFFE0000003FFFFFFFFFFFFFFFC\n      00FFFFFE001FFFFFFFFFFE00000000000003FFFFFFFF0000000000007FFFFFFF\n      FFFFFFFFC0000001FFFFFFFFFFFFFFFC00FFFFFE000FFFFFFFFFFC0000000000\n      0003FFFFFFFE0000000000003FFFFFFFFFFFFFFFC0000001FFFFFFFFFFFFFFF8\n      00FFFFFE000FFFFFFFFFF800000000000003FFFFFFFE0000000000001FFFFFFF\n      FFFFFFFF80000000FFFFFFFFFFFFFFF001FFFFFF0007FFFFFFFFF00000000000\n      0001FFFFFFFE000000000000007FFFFFFFFFFFFF00000000FFFFFFFFFFFFFFE0\n      01FFFFFF8003FFFFFFFFE000000000000000FFFFFFFC000000000000003FFFFF\n      FFFFFFFF00000000FFFFFFFFFFFFFFC003FFFFFF8003FFFFFFFFC00000000000\n      0000FFFFFFF8000000000000001FFFFFFFFFFFFF000000007FFFFFFFFFFFFF80\n      07FFFFFF8003FFFFFFFF80000000000000007FFFFFF8000000000000000FFFFF\n      FFFFFFFE000000007FFFFFFFFFFFFF8007FFFFFFC003FFFFFFFF000000000000\n      00007FFFFFF00000000000000007FFFFFFFFFFFE000000003FFFFFFFFFFFFF00\n      0FFFFFFFC001FFFFFFFE00000000000000003FFFFFF00000000000000003FFFF\n      FFFFFFFC000000003FFFFFFFFFFFFF000FFFFFFFC001FFFFFFFC000000000000\n      00003FFFFFF00000000000000003FFFFFFFFFFFC000000001FFFFFFFFFFFFF00\n      1FFFFFFFC001FFFFFFF800000000000000001FFFFFF00000000000000003FFFF\n      FFFFFFF8000000001FFFFFFFFFFFFF003FFFFFFFC001FFFFFFF0000000000000\n      00000FFFFFE00000000000000003FFFFFFFFFFF8000000000FFFFFFFFFFFFE00\n      3FFFFFFFC001FFFFFFE000000000000000000FFFFFE00000000000000001FFFF\n      FFFFFFF0000000000FFFFFFFFFFFFE003FFFFFFFC001FFFFFFC0000000000000\n      000007FFFFE00000000000000001FFFFFFFFFFF0000000000FFFFFFFFFFFFC00\n      7FFFFFFFC001FFFFFF80000000000000000007FFFFE00000000000000003FFFF\n      FFFFFFF00000000007FFFFFFFFFFF8007FFFFFFFC001FFFFFF00000000000000\n      000003FFFFC00000000000000003FFFFFFFFFFE00000000007FFFFFFFFFFF800\n      7FFFFFFFC001FFFFFE00000000000000000001FFFFC00000000000000003FFFF\n      FFFFFFE00000000003FFFFFFFFFFF8007FFFFFFFC000FFFFFC00000000000000\n      000001FFFFC00000000000000003FFFFFFFFFFC00000000003FFFFFFFFFFF800\n      7FFFFFFFC000FFFFF800000000000000000000FFFFC00000000000000001FFFF\n      FFFFFFC00000000001FFFFFFFFFFF0007FFFFFFFC000FFFFF800000000000000\n      000000FFFFC00000000000000000FFFFFFFFFF800000000001FFFFFFFFFFF000\n      7FFFFFFFC0007FFFF0000000000000000000007FFFC00000000000000000FFFF\n      FFFFFF800000000000FFFFFFFFFFF0007FFFFFFFC0007FFFE000000000000000\n      0000003FFFC000000000000000007FFFFFFFFF000000000000FFFFFFFFFFF000\n      7FFFFFFFC0007FFFC0000000000000000000003FFFC000000000000000007FFF\n      FFFFFF000000000000FFFFFFFFFFE0007FFFFFFFC0007FFF8000000000000000\n      0000001FFFC000000000000000003FFFFFFFFF0000000000007FFFFFFFFFE000\n      7FFFFFFFC0007FFF80000000000000000000001FFFC000000000000000003FFF\n      FFFFFE0000000000007FFFFFFFFFE0007FFFFFFFC0007FFF0000000000000000\n      0000000FFFC000000000000000001FFFFFFFFE0000000000003FFFFFFFFFC000\n      7FFF8FFFC0007FFF000000000000000000000007FFC000000000000000000FFF\n      FFFFFC0000000000003FFFFFFFFFC0007FFE03FFC0007FFF0000000000000000\n      00000007FFC000000000000000000FFFFFFFF80000000000001FFFFFFFFFC000\n      7FFC01FF80007FFF000000000000000000000003FFE000000000000000000FFF\n      FFFFF80000000000000FFFFFFFFFC0007FF800FF80007FFF8000000000000000\n      00000003FFE0000000000000000007FFFFFFF00000000000000FFFFFFFFFC000\n      7FF8007F80007FFF800000000000000000000003FFE0000000000000000007FF\n      FFFFF00000000000000FFFFFFFFFC0007FF0007F80007FFFC000000000000000\n      00000001FFE0000000000000000007FFFFFFF00000000000000FFFFFFFFFC000\n      7FF0003F80007FFFC00000000000000000000001FFE0000000000000000003FF\n      FFFFF000000000000007FFFFFFFF80007FE0003F80007FFFE000000000000000\n      00000001FFF0000000000000000003FFFFFFE000000000000007FFFFFFFF8000\n      7FE0003F80007FFFF00000000000000000000003FFF0000000000000000001FF\n      FFFFC000000000000003FFFFFFFF80007FC0003F80007FFFF800000000000000\n      00000003FFF0000000000000000001FFFFFFC000000000000001FFFFFFFF8000\n      7FC0003F80007FFFF80000000000000000000007FFF0000000000000000001FF\n      FFFFC000000000000001FFFFFFFF80007FE0003F80007FFFFC00000000000000\n      00000007FFF8000000000000000001FFFFFFC000000000000003FFFFFFFF8000\n      7FE0003F80007FFFFC000000000000000000000FFFF8000000000000000001FF\n      FFFFE000000000000003FFFFFFFF80007FE0003F00007FFFFE00000000000000\n      0000001FFFFC000000000000000001FFFFFFE000000000000007FFFFFFFF8000\n      3FE0007F00007FFFFF000000000000000000003FFFFC000000000000000001FF\n      FFFFF000000000000007FFFFFFFF80003FE0007F00007FFFFF80000000000000\n      0000003FFFFE000000000000000001FFFFFFF00000000000000FFFFFFFFF8000\n      3FF0007F00007FFFFF80000000000000000000FFFFFE000000000000000001FF\n      FFFFF00000000000000FFFFFFFFF80003FF000FE00007FFFFFC0000000000000\n      000000FFFFFF000000000000000001FFFFFFF80000000000000FFFFFFFFF8000\n      3FF001FE00007FFFFFE0000000000000000001FFFFFF000000000000000001FF\n      FFFFF80000000000001FFFFFFFFF80001FFC03FE0000FFFFFFE0000000000000\n      000003FFFFFF000000000000000001FFFFFFFC0000000000001FFFFFFFFFC000\n      1FFF1FFE0000FFFFFFF0000000000000000007FFFFFE000000000000000001FF\n      FFFFFC0000000000003FFFFFFFFFC0000FFFFFFC0000FFFFFFF0000000000000\n      00000FFFFFFE000000000000000003FFFFFFFE0000000000003FFFFFFFFFC000\n      0FFFFFFC0001FFFFFFF800000000000000000FFFFFFE000000000000000003FF\n      FFFFFE0000000000007FFFFFFFFFC0000FFFFFFC0001FFFFFFFC000000000000\n      00001FFFFFFE000000000000000003FFFFFFFF0000000000007FFFFFFFFFC000\n      07FFFFF80001FFFFFFFC00000000000000003FFFFFFE000000000000000007FF\n      FFFFFF000000000000FFFFFFFFFFC00007FFFFF80001FFFFFFFE000000000000\n      00007FFFFFFE00000000000000000FFFFFFFFF000000000000FFFFFFFFFFC000\n      03FFFFF00001FFFFFFFE0000000000000000FFFFFFFE00000000000000000FFF\n      FFFFFF800000000000FFFFFFFFFFC00001FFFFF00001FFFFFFFF000000000000\n      0001FFFFFFFE00000000000000000FFFFFFFFF800000000001FFFFFFFFFFE000\n      01FFFFF00001FFFFFFFF8000000000000003FFFFFFFE00000000000000001FFF\n      FFFFFFC00000000001FFFFFFFFFFE00000FFFFE00003FFFFFFFFC00000000000\n      0003FFFFFFFF00000000000000001FFFFFFFFFE00000000003FFFFFFFFFFF000\n      00FFFFE00003FFFFFFFFC000000000000007FFFFFFFF00000000000000003FFF\n      FFFFFFE00000000007FFFFFFFFFFF00000FFFFC00003FFFFFFFFE00000000000\n      000FFFFFFFFF80000000000000007FFFFFFFFFF00000000007FFFFFFFFFFF000\n      007FFFC00003FFFFFFFFF00000000000001FFFFFFFFFC000000000000000FFFF\n      FFFFFFF0000000000FFFFFFFFFFFF800003FFF800007FFFFFFFFF00000000000\n      003FFFFFFFFFC000000000000003FFFFFFFFFFF0000000000FFFFFFFFFFFF800\n      001FFF800007FFFFFFFFF80000000000007FFFFFFFFFC000000000000003FFFF\n      FFFFFFF8000000000FFFFFFFFFFFF800000FFF00000FFFFFFFFFF80000000000\n      00FFFFFFFFFF8000000000000003FFFFFFFFFFF8000000000FFFFFFFFFFFF800\n      0007FF00000FFFFFFFFFFC000000000000FFFFFFFFFF8000000000000007FFFF\n      FFFFFFFC000000001FFFFFFFFFFFF8000007FE00001FFFFFFFFFFE0000000000\n      01FFFFFFFFFFC000000000000007FFFFFFFFFFFC000000003FFFFFFFFFFFF000\n      0007FC00001FFFFFFFFFFF000000000007FFFFFFFFFFC00000000000000FFFFF\n      FFFFFFFE000000003FFFFFFFFFFFF0000000F000001FFFFFFFFFFF0000000000\n      07FFFFFFFFFFC00000000000000FFFFFFFFFFFFE000000007FFFFFFFFFFFC000\n      00000000000FFFFFFFFFFF80000000000FFFFFFFFFFFC00E00000000001FFFFF\n      FFFFFFFF000000007FFFFFFFFFFFC00000000000000FFFFFFFFFFFC000000000\n      1FFFFFFFFFFFC01F80000000001FFFFFFFFFFFFF00000000FFFFFFFFFFFF8000\n      000000000007FFFFFFFFFFE0000000003FFFFFFFFFFFE01FC0000000003FFFFF\n      FFFFFFFF00000000FFFFFFFFFFFF0000000000000003FFFFFFFFFFF800000007\n      FFFFFFFFFFFFF81FE000000001FFFFFFFFFFFFFF80000000FFFFFFFFFFFE0000\n      000000000001FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC0FF00000000FFFFFFF\n      FFFFFFFF80000000FFFFFFFFFFFE0000000000000000FFFFFFFFFFFFFFFFFFFF\n      FFFFFFFFFFFFFE0FF80000003FFFFFFFFFFFFFFFC0000001FFFFFFFFFFFE0000\n      0000000000007FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF87FFFFC0007FFFFFFF\n      FFFFFFFFC0000003FFFFFFFFFFFF00000000000000007FFFFFFFFFFFFFFFFFFF\n      FFFFFFFFFFFFFFFFFFFFE000FFFFFFFFFFFFFFFFE0000003FFFFFFFFFFFF8000\n      0000000000007FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF001FFFFFFFF\n      FFFFFFFFE0000007FFFFFFFFFFFFF0000000000000007FFFFFFFFFFFFFFFFFFF\n      FFFFFFFFFFFFFFFFFFFFFC03FFFFFFFFFFFFFFFFF0000007FFFFFFFFFFFFFFFF\n      8FFC7FFE017FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE07FFFFFFFF\n      FFFFFFFFF000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\n      FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000000000000000000000000000\n      000000000000}\n  end\n  object ProfilePopupMenu: TPopupMenu\n    OnPopup = ProfilePopupMenuPopup\n    Left = 48\n    Top = 136\n    object NewProfileItem: TMenuItem\n      Caption = 'New profile'\n      OnClick = NewProfileItemClick\n    end\n    object DeleteProfileItem: TMenuItem\n      Caption = 'Delete profile'\n      OnClick = DeleteProfileItemClick\n    end\n  end\n  object GeneralIcons: TImageList\n    Left = 96\n    Top = 416\n    Bitmap = {\n      494C0101020008004C0010001000FFFFFFFFFF10FFFFFFFFFFFFFFFF424D3600\n      0000000000003600000028000000400000001000000001002000000000000010\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      00000000000000000000000000000000000075848FFF66808FFF607987FF576E\n      7BFF4E626FFF445661FF394852FF2E3A43FF252E35FF1B2229FF14191EFF0E12\n      16FF0E1318FF000000000000000000000000000000000000000000000000C4C4\n      E3FF2313C2FF7663D6FF00000000000000000000000000000000000000007663\n      D6FF2313C2FFC4C4E3FF00000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      000000000000000000000000000000000000778792FF89A1ABFF6AB2D4FF008F\n      CDFF008FCDFF008FCDFF048CC7FF0888BEFF0F82B4FF157CA9FF1B779FFF1F72\n      96FF214A5BFEBDC2C44A00000000000000000000000000000000C4C4E3FF2313\n      C2FF3631EEFF2313C2FF7663D6FF0000000000000000000000007663D6FF2313\n      C2FF3631EEFF2313C2FFC4C4E3FF000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000007A8A95FF7EBED3FF8AA4AEFF7EDC\n      FFFF5FCFFFFF55CBFFFF4CC4FAFF41BCF5FF37B3F0FF2EAAEBFF24A0E5FF138C\n      D4FF236780FF5E686CB4000000000000000000000000000000009D9CDAFF2313\n      C2FF4A3DECFF4A3DECFF2313C2FF7663D6FF9D9CDAFF7663D6FF2313C2FF4A3D\n      ECFF4A3DECFF2313C2FF9D9CDAFF000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000007D8E98FF79D2ECFF8BA4ADFF89C2\n      CEFF71D8FFFF65D3FFFF5CCEFFFF51C9FEFF49C1FAFF3FB9F5FF34B0EEFF29A8\n      E9FF1085CDFF224B5BFFDADDDF27000000000000000000000000000000007663\n      D6FF2313C2FF4A3DECFF4A3DECFF3737D8FF2313C2FF3737D8FF4A3DECFF4A3D\n      ECFF2313C2FF7663D6FF00000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      00000000000000000000000000000000000080919CFF81D7EFFF7DC5E0FF8CA6\n      B0FF80DDFEFF68D3FFFF67D4FFFF62D1FFFF58CDFFFF4EC7FCFF46BEF7FF3BB6\n      F2FF31ACECFF256981FF7A95A190000000000000000000000000000000000000\n      00007663D6FF2C26C4FF4A3DECFF4A3DECFF4A3DECFF4A3DECFF4A3DECFF2C26\n      C4FF7663D6FF0000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      00000000000000000000000000000000000083959FFF89DCF1FF8CE2FFFF8DA8\n      B1FF8CBAC7FF74D8FFFF67D4FFFF67D4FFFF67D4FFFF5FD0FFFF54CDFFFF4BC5\n      FCFF41BBF7FF2EA2DBFF516674F1E1E4E62B0000000000000000000000000000\n      0000000000002C26C4FF3631EEFF4F4EECFF4F4EECFF4F4EECFF3631EEFF2C26\n      C4FF000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      000000000000000000000000000000000000869AA3FF92E1F2FF98E8FDFF80C4\n      DEFF8EA7B0FF81DEFDFF84E0FFFF84E0FFFF84E0FFFF84E0FFFF81DFFFFF7BDD\n      FFFF74D8FFFF6BD6FFFF56A9D1FF8E9BA3A20000000000000000000000000000\n      0000000000003737D8FF3737D8FF655BF1FF655BF1FF655BF1FF3631EEFF3738\n      BBFF000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      000000000000000000000000000000000000889CA5FF9AE6F3FF9FEBFBFF98E8\n      FEFF8BACB9FF8BACB9FF8AAAB7FF88A6B3FF86A3AFFF839FAAFF819AA6FF7F95\n      A1FF7C919DFF7A8E99FF798B95FF778893FF0000000000000000000000000000\n      00007663D6FF3738BBFF655BF1FF655BF1FF655BF1FF655BF1FF655BF1FF3D47\n      C8FF7663D6FF0000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000008BA0A8FFA0EAF6FFA6EEF9FF9FEB\n      FBFF98E8FEFF7ADAFFFF67D4FFFF67D4FFFF67D4FFFF67D4FFFF67D4FFFF67D4\n      FFFF778893FF0000000000000000000000000000000000000000000000007F86\n      DAFF3D47C8FF7774F3FF7774F3FF5B61E0FF3D47C8FF5B61E0FF7774F3FF7774\n      F3FF3D47C8FF7F86DAFF00000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000008EA2ABFFA7EEF6FFABF0F7FFA6EE\n      F9FF9FEBFBFF98E8FDFF71D4FBFF899EA7FF8699A3FF82949FFF7E909AFF7A8C\n      97FF778893FF00000000000000000000000000000000000000009D9CDAFF4656\n      C8FF8586F0FF8586F0FF4656C8FF5B64CEFF9D9CDAFF5B64CEFF4656C8FF8586\n      F0FF8586F0FF4656C8FF9D9CDAFF000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000008FA4ACFFA0D2DAFFABF0F7FFABF0\n      F7FFA6EEF9FF9FEBFBFF8DA1AAFFC0D0D6820000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000C4C4E3FF4656\n      C8FF4F4EECFF4656C8FF7F86DAFF0000000000000000000000007F86DAFF4656\n      C8FF4F4EECFF4656C8FFC4C4E3FF000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      000000000000000000000000000000000000D8DFE2578FA4ACFF8FA4ACFF8FA4\n      ACFF8FA4ACFF8FA4ACFFBDCFD68D000000000000000000000000000000000000\n      000000000000000000000000000000000000000000000000000000000000C4C4\n      E3FF4656C8FF7F86DAFF00000000000000000000000000000000000000007F86\n      DAFF4656C8FFC4C4E3FF00000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      000000000000000000000000000000000000424D3E000000000000003E000000\n      2800000040000000100000000100010000000000800000000000000000000000\n      000000000000000000000000FFFFFF00FFFFFFFF00000000FFFFFFFF00000000\n      0007E3E3000000000003C1C1000000000003C001000000000001E00300000000\n      0001F007000000000000F80F000000000000F80F000000000000F00700000000\n      0007E003000000000007C0010000000000FFC1C10000000001FFE3E300000000\n      FFFFFFFF00000000FFFFFFFF0000000000000000000000000000000000000000\n      000000000000}\n  end\nend\n"
  },
  {
    "path": "frontend/msProfileForm.pas",
    "content": "unit msProfileForm;\n\ninterface\n\nuses\n  Windows, Messages, SysUtils, Classes, Controls, Forms, StdCtrls, Graphics,\n  ImgList, Menus, Dialogs, ExtCtrls, pngimage,\n  // mte components\n  RttiIni, mteHelpers,\n  // mp components\n  msConfiguration, msLoader, msProfilePanel;\n\ntype\n  TProfileForm = class(TForm)\n    btnOk: TButton;\n    btnCancel: TButton;\n    GameIcons: TImageList;\n    ProfilePopupMenu: TPopupMenu;\n    NewProfileItem: TMenuItem;\n    DeleteProfileItem: TMenuItem;\n    GeneralIcons: TImageList;\n    ScrollBox: TScrollBox;\n    NewProfilePanel: TPanel;\n    NewProfileImage: TImage;\n    NewProfileLabel: TLabel;\n    PaddingLabel: TLabel;\n    procedure FormCreate(Sender: TObject);\n    procedure FormClose(Sender: TObject; var Action: TCloseAction);\n    procedure FormDestroy(Sender: TObject);\n    procedure RealignPanels;\n    function CreateNewProfile(name: string): TProfilePanel;\n    procedure NewProfileItemClick(Sender: TObject);\n    procedure LoadProfiles;\n    function ProfileExists(gameMode: Integer): Boolean;\n    procedure CreateDefaultProfiles;\n    procedure ProfilePopupMenuPopup(Sender: TObject);\n    procedure SelectionChanged(Sender: TObject);\n    procedure DeleteClicked(Sender: TObject);\n    procedure DeleteProfileItemClick(Sender: TObject);\n    function ProfileNameTaken(name: string): boolean;\n    procedure NewProfileImageClick(Sender: TObject);\n    procedure NewProfilePanelClick(Sender: TObject);\n    procedure NewProfileLabelClick(Sender: TObject);\n    procedure NewProfilePanelMouseMove(Sender: TObject; Shift: TShiftState; X,\n      Y: Integer);\n  private\n    FOldWndProc: TWndMethod;\n    FMouseInPanel: Boolean;\n    procedure PanelWndProc(var Message: TMessage);\n  public\n    ProfilePanels: TList;\n  end;\n\nvar\n  ProfileForm: TProfileForm;\n  SelectCallback, DeleteCallback: TNotifyEvent;\n  MouseOverProfile: TProfilePanel;\n  ProgramPath: String;\n\nimplementation\n\n{$R *.dfm}\n\nprocedure TProfileForm.DeleteProfileItemClick(Sender: TObject);\nvar\n  bApproved: boolean;\n  aProfile: TProfile;\nbegin\n  // get user verification\n  aProfile := MouseOverProfile.GetProfile;\n  bApproved := MessageDlg('Are you sure you want to delete '+\n    aProfile.name + '?', mtConfirmation, mbOKCancel, 0) = mrOk;\n\n  if not (bApproved and Assigned(MouseOverProfile)) then exit;\n  ProfilePanels.Delete(ProfilePanels.IndexOf(MouseOverProfile));\n  aProfile.Delete;\n  MouseOverProfile.Free;\n  RealignPanels;\nend;\n\nprocedure TProfileForm.RealignPanels;\nvar\n  i, vPos, pCount: Integer;\n  p: TProfilePanel;\nbegin\n  // just some aliases\n  vPos := ScrollBox.VertScrollBar.ScrollPos;\n  pCount := ProfilePanels.Count;\n\n  // adjust tops\n  NewProfilePanel.Top := 100 * pCount - vPos;\n  for i := Pred(pCount) downto 0 do begin\n    p := TProfilePanel(ProfilePanels[i]);\n    p.SetTop(100 * i - vPos);\n  end;\n  PaddingLabel.Top := 100 * (pCount + 1) - vPos - PaddingLabel.Height;\n\n  // adjust widths\n  NewProfilePanel.Width := ScrollBox.ClientWidth;\n  for i := Pred(pCount) downto 0 do begin\n    p := TProfilePanel(ProfilePanels[i]);\n    p.SetWidth(ScrollBox.ClientWidth);\n  end;\nend;\n\nprocedure TProfileForm.FormClose(Sender: TObject; var Action: TCloseAction);\nvar\n  i: Integer;\n  p: TProfilePanel;\n  aProfile: TProfile;\nbegin\n  // save all profiles\n  for i := 0 to Pred(ProfilePanels.Count) do begin\n    p := TProfilePanel(ProfilePanels[i]);\n    aProfile := p.GetProfile;\n    try\n      SaveProfile(aProfile);\n    except\n      on Exception do\n        // nothing to do\n    end;\n  end;\n\n  // set profile if user clicked OK\n  if ModalResult = mrOK then begin\n    for i := 0 to Pred(ProfilePanels.Count) do begin\n      p := TProfilePanel(ProfilePanels[i]);\n      if p.Selected then begin\n        CurrentProfile := TProfile.Create('');\n        CurrentProfile.Clone(p.GetProfile);\n        break;\n      end;\n    end;\n  end;\n\n  // free memory\n  FreeList(ProfilePanels);\nend;\n\nprocedure TProfileForm.FormCreate(Sender: TObject);\nbegin\n  ProgramPath := ExtractFilePath(ParamStr(0));\n  ProfilePanels := TList.Create;\n  SelectCallback := SelectionChanged;\n  DeleteCallback := DeleteClicked;\n  LoadProfiles;\n  CreateDefaultProfiles;\n  FOldWndProc := NewProfilePanel.WindowProc;\n  NewProfilePanel.WindowProc := PanelWndProc;\nend;\n\nprocedure TProfileForm.FormDestroy(Sender: TObject);\nbegin\n  NewProfilePanel.WindowProc:= FOldWndProc;\nend;\n\nprocedure TProfileForm.LoadProfiles;\nvar\n  path, settingsPath: string;\n  info: TSearchRec;\n  p: TProfilePanel;\n  aSettings: TSettings;\nbegin\n  path := ProgramPath + 'profiles\\';\n  if not DirectoryExists(path) then\n    exit;\n\n  if FindFirst(path + '*', faAnyFile or faDirectory, info) <> 0 then\n    exit;\n  // add found profiles\n  repeat\n    if IsDotFile(info.Name) then\n      continue;\n    settingsPath := path + info.Name + '\\settings.ini';\n    if not FileExists(settingsPath) then\n      continue;\n    aSettings := TSettings.Create;\n    TRttiIni.Load(settingsPath, aSettings);\n    if aSettings.profile <> '' then begin\n      p := CreateNewProfile(aSettings.profile);\n      p.SetGame(aSettings.gameMode);\n      p.SetPath(aSettings.gamePath);\n    end;\n    aSettings.Free;\n  until FindNext(info) <> 0;\nend;\n\nfunction TProfileForm.ProfileExists(gameMode: Integer): Boolean;\nvar\n  i: Integer;\n  profile: TProfile;\nbegin\n  Result := False;\n  for i := 0 to Pred(ProfilePanels.Count) do begin\n    profile := TProfilePanel(ProfilePanels[i]).GetProfile;\n    if profile.gameMode = gameMode then begin\n      Result := True;\n      break;\n    end;\n  end;\nend;\n\nprocedure TProfileForm.CreateDefaultProfiles;\nvar\n  i: Integer;\n  path, name: string;\n  p: TProfilePanel;\nbegin\n  for i := Low(GameArray) to High(GameArray) do begin\n    if ProfileExists(i) then continue;\n    path := GetGamePath(GameArray[i]);\n    name := GameArray[i].appName;\n    if path <> '' then begin\n      p := CreateNewProfile(name);\n      p.SetGame(i);\n      p.SetPath(path);\n    end;\n  end;\nend;\n\nfunction TProfileForm.CreateNewProfile(name: string): TProfilePanel;\nbegin\n  Result := TProfilePanel.ICreate(ScrollBox, GameIcons, GeneralIcons, name);\n  Result.SetSelectCallback(SelectCallback);\n  Result.SetDeleteCallback(DeleteCallback);\n  ProfilePanels.Add(Result);\n  RealignPanels;\nend;\n\nprocedure TProfileForm.NewProfileItemClick(Sender: TObject);\nvar\n  name: string;\n  i: Integer;\nbegin\n  // find profile name\n  name := 'NewProfile';\n  i := 1;\n  while ProfileNameTaken(name + IntToStr(i)) do\n    Inc(i);\n\n  // create a new profile\n  name := name + IntToStr(i);\n  CreateNewProfile(name);\nend;\n\nprocedure TProfileForm.NewProfileImageClick(Sender: TObject);\nbegin\n  NewProfileItemClick(nil);\nend;\n\nprocedure TProfileForm.NewProfileLabelClick(Sender: TObject);\nbegin\n  NewProfileItemClick(nil);\nend;\n\nprocedure TProfileForm.NewProfilePanelClick(Sender: TObject);\nbegin\n  NewProfileItemClick(nil);\nend;\n\nfunction TProfileForm.ProfileNameTaken(name: string): boolean;\nvar\n  i: Integer;\n  pName: string;\nbegin\n  Result := false;\n  for i := 0 to Pred(ProfilePanels.Count) do begin\n    pName := TProfilePanel(ProfilePanels[i]).GetProfile.name;\n    if SameText(pName, name) then begin\n      Result := true;\n      break;\n    end;\n  end;\nend;\n\nprocedure TProfileForm.ProfilePopupMenuPopup(Sender: TObject);\nvar\n  pt: TPoint;\n  index: Integer;\nbegin\n  // get profile user is moused over\n  pt := ScrollBox.ScreenToClient(Mouse.CursorPos);\n  Index := pt.Y div 100;\n  if Index < ProfilePanels.Count then\n    MouseOverProfile := TProfilePanel(ProfilePanels[index])\n  else\n    MouseOverProfile := nil;\n\n  // can only delete profile if mouse over a profile\n  ProfilePopupMenu.Items[1].Enabled := Assigned(MouseOverProfile);\nend;\n\nprocedure TProfileForm.SelectionChanged(Sender: TObject);\nvar\n  i: Integer;\n  p: TProfilePanel;\n  bSelected: boolean;\nbegin\n  // deselect all panels except the sender\n  for i := 0 to Pred(ProfilePanels.Count) do begin\n    p := TProfilePanel(ProfilePanels[i]);\n    if p <> TProfilePanel(Sender) then\n      p.Deselect\n  end;\n\n  // enable and focus ok button if profile panel is selected\n  bSelected := TProfilePanel(Sender).Selected;\n  btnOk.Enabled := bSelected;\n  if bSelected then self.FocusControl(btnOk)\n  else self.FocusControl(btnCancel);\nend;\n\nprocedure TProfileForm.DeleteClicked(Sender: TObject);\nbegin\n  MouseOverProfile := TProfilePanel(Sender);\n  DeleteProfileItemClick(nil);\nend;\n\nprocedure TProfileForm.NewProfilePanelMouseMove(Sender: TObject; Shift: TShiftState; X,\n  Y: Integer);\nvar\n  mEvnt: TTrackMouseEvent;\nbegin\n  if not FMouseInPanel then begin\n    mEvnt.cbSize := SizeOf(mEvnt);\n    mEvnt.dwFlags := TME_LEAVE;\n    mEvnt.hwndTrack := NewProfilePanel.Handle;\n    TrackMouseEvent(mEvnt);\n    NewProfilePanel.Color:= $f0e8d8;\n    FMouseInPanel:= True;\n  end;\nend;\n\nprocedure TProfileForm.PanelWndProc(var Message: TMessage);\nbegin\n  if Message.Msg = WM_MOUSELEAVE then begin\n    NewProfilePanel.Color:= clBtnFace;\n    FMouseInPanel:= False;\n  end;\n  FOldWndProc(Message);\nend;\n\nend.\n"
  },
  {
    "path": "frontend/msProfilePanel.pas",
    "content": "unit msProfilePanel;\n\ninterface\n\nuses\n  SysUtils, Classes, Controls, Dialogs, Graphics, Buttons, StdCtrls, ExtCtrls,\n  ImgList, Types,\n  // mte components\n  mteHelpers,\n  // mp components\n  msConfiguration, msLoader;\n\ntype\n  TProfilePanel = class(TPanel)\n  public\n    Selected: boolean;\n    Valid: boolean;\n    constructor ICreate(AOwner: TComponent; GameIcons, GeneralIcons: TImageList;\n      name: string);\n    destructor Destroy; override;\n    procedure ToggleSelect(Sender: TObject);\n    procedure Deselect;\n    procedure Select;\n    procedure SetTop(top: Integer);\n    procedure SetWidth(width: Integer);\n    function GetProfile: TProfile;\n    procedure SetSelectCallback(callback: TNotifyEvent);\n    procedure SetDeleteCallback(callback: TNotifyEvent);\n    procedure SetGame(i: integer);\n    procedure SetPath(path: string);\n  private\n    aProfile: TProfile;\n    ColorInvalid: Integer;\n    ColorValid: Integer;\n    ColorSelected: Integer;\n    GameImage: TImage;\n    lblName: TLabel;\n    lblGame: TLabel;\n    lblPath: TLabel;\n    edName: TEdit;\n    cbGame: TComboBox;\n    edPath: TEdit;\n    btnBrowse: TSpeedButton;\n    btnDelete: TSpeedButton;\n    GameIcons: TImageList;\n    SelectCallback: TNotifyEvent;\n    DeleteCallback: TNotifyEvent;\n    procedure Browse(Sender: TObject);\n    procedure Delete(Sender: TObject);\n    procedure NameChanged(Sender: TObject);\n    procedure GameChanged(Sender: TObject);\n    procedure PathChanged(Sender: TObject);\n  end;\n\nimplementation\n\n\n{******************************************************************************}\n{ TProfilePanel\n  A GUI component for interacting with a profile.\n}\n{******************************************************************************}\n\nconstructor TProfilePanel.ICreate(AOwner: TComponent; GameIcons: TImageList;\n  GeneralIcons: TImageList; name: string);\nconst\n  GameItems = 'The Elder Scrolls V: Skyrim'#13#10 +\n              'The Elder Scrolls IV: Oblivion'#13#10 +\n              'Fallout: New Vegas'#13#10 +\n              'Fallout 3'#13#10 +\n              'Fallout 4'#13#10 +\n              'Skyrim: Special Edition';\nbegin\n  // set up panel\n  inherited Create(AOwner);\n  Parent := AOwner as TWinControl;\n  Width := (AOwner as TWinControl).ClientWidth;\n  Height := 100;\n  Left := 0;\n  Top := 0;\n  ParentBackground := false;\n  ParentColor := false;\n  ParentDoubleBuffered := false;\n  Cursor := crDefault;\n  Anchors := [akLeft, akTop, akRight];\n  Visible := true;\n\n  // set local variables\n  aProfile := TProfile.Create(name);\n  self.GameIcons := GameIcons;\n  Selected := false;\n  ColorInvalid := $d8d8f0;\n  ColorValid := $d8f0d8;\n  ColorSelected := $f0e8d8;\n\n  // create components\n  GameImage := TImage.Create(self);\n  lblName := TLabel.Create(self);\n  lblGame := TLabel.Create(self);\n  lblPath := TLabel.Create(self);\n  edName := TEdit.Create(self);\n  cbGame := TComboBox.Create(self);\n  edPath := TEdit.Create(self);\n  btnDelete := TSpeedButton.Create(self);\n  btnBrowse := TSpeedButton.Create(self);\n\n  // set up GameImage\n  GameImage.Parent := self;\n  GameImage.Top := 2;\n  GameImage.Left := 2;\n  GameImage.Height := 96;\n  GameImage.Width := 96;\n  GameImage.Cursor := crDefault;\n  GameImage.Transparent := true;\n  GameImage.Align := alCustom;\n  GameImage.Anchors := [akLeft, akTop, akBottom];\n\n  // set up lblName\n  lblName.Parent := self;\n  lblName.Top := 11;\n  lblName.Left := 112;\n  lblName.Caption := 'Name';\n  lblName.Align := alCustom;\n  lblName.Anchors := [akLeft, akTop];\n\n  // set up lblGame\n  lblGame.Parent := self;\n  lblGame.Top := 38;\n  lblGame.Left := 112;\n  lblGame.Caption := 'Game';\n  lblGame.Align := alCustom;\n  lblGame.Anchors := [akLeft, akTop];\n\n  // set up lblPath\n  lblPath.Parent := self;\n  lblPath.Top := 65;\n  lblPath.Left := 112;\n  lblPath.Caption := 'Path';\n  lblPath.Align := alCustom;\n  lblPath.Anchors := [akLeft, akTop];\n\n  // set up edName\n  edName.Parent := self;\n  edName.Top := 8;\n  edName.Left := 177;\n  edName.Width := 227;\n  edName.Text := name;\n  edName.Align := alCustom;\n  edName.Anchors := [akLeft, akTop];\n\n  // set up cbGame\n  cbGame.Parent := self;\n  cbGame.Top := 35;\n  cbGame.Left := 177;\n  cbGame.Width := 227;\n  cbGame.Style := csDropDownList;\n  cbGame.Items.Text := GameItems;\n  cbGame.ItemIndex := 0;\n  cbGame.Align := alCustom;\n  cbGame.Anchors := [akLeft, akTop];\n\n  // set up edPath\n  edPath.Parent := self;\n  edPath.Top := 62;\n  edPath.Left := 177;\n  edPath.Width := 227;\n  edPath.Align := alCustom;\n  edPath.Anchors := [akLeft, akTop];\n\n  // set up btnBrowse\n  btnBrowse.Parent := self;\n  btnBrowse.Top := 61;\n  btnBrowse.Left := 410;\n  btnBrowse.Width := 22;\n  btnBrowse.Height := 23;\n  btnBrowse.Flat := true;\n  btnBrowse.Transparent := true;\n  GeneralIcons.GetBitmap(0, btnBrowse.Glyph);\n  btnBrowse.Align := alCustom;\n  btnBrowse.Anchors := [akLeft, akTop];\n\n  // set up btnDelete\n  btnDelete.Parent := self;\n  btnDelete.Top := 4;\n  btnDelete.Left := 410;\n  btnDelete.Width := 22;\n  btnDelete.Height := 23;\n  btnDelete.Flat := true;\n  btnDelete.Transparent := true;\n  GeneralIcons.GetBitmap(1, btnDelete.Glyph);\n  btnDelete.Align := alCustom;\n  btnDelete.Anchors := [akLeft, akTop];\n\n  // set event handlers\n  self.OnClick := ToggleSelect;\n  GameImage.OnClick := ToggleSelect;\n  lblName.OnClick := ToggleSelect;\n  lblGame.OnClick := ToggleSelect;\n  lblPath.OnClick := ToggleSelect;\n  btnBrowse.OnClick := Browse;\n  btnDelete.OnClick := Delete;\n  edName.OnChange := NameChanged;\n  edPath.OnChange := PathChanged;\n  cbGame.OnChange := GameChanged;\n\n  // call initial events\n  GameChanged(nil);\n  PathChanged(nil);\nend;\n\ndestructor TProfilePanel.Destroy;\nbegin\n  aProfile.Free;\n  GameImage.Free;\n  lblName.Free;\n  lblGame.Free;\n  lblPath.Free;\n  edName.Free;\n  cbGame.Free;\n  edPath.Free;\n  btnDelete.Free;\n  btnBrowse.Free;\n  inherited;\nend;\n\n{ EVENT HANDLING }\nprocedure TProfilePanel.ToggleSelect(Sender: TObject);\nbegin\n  if Cursor = crHandPoint then begin\n    if Selected then Deselect else Select;\n    if Assigned(SelectCallback) then SelectCallback(self);\n  end;\nend;\n\nprocedure TProfilePanel.Select;\nbegin\n  Selected := true;\n  Color := ColorSelected;\n  Repaint;\nend;\n\nprocedure TProfilePanel.Deselect;\nbegin\n  Selected := false;\n  Color := ColorValid;\n  Repaint;\nend;\n\nprocedure TProfilePanel.Browse(Sender: TObject);\nbegin\n  // have user browse for folder\n  BrowseForFolder(edPath, '');\n\n  // then update in profile\n  aProfile.gamePath := edPath.Text;\nend;\n\nprocedure TProfilePanel.Delete(Sender: TObject);\nbegin\n  if Assigned(DeleteCallback) then DeleteCallback(self);\nend;\n\nprocedure TProfilePanel.NameChanged(Sender: TObject);\nbegin\n  if FileNameValid(edName.Text) and\n  (not DirectoryExists(PathList.Values['ProgramPath'] + 'profiles\\' + edName.Text)) then\n    aProfile.Rename(edName.Text);\nend;\n\nprocedure TProfilePanel.GameChanged(Sender: TObject);\nbegin\n  // set in profile\n  aProfile.gamemode := cbGame.ItemIndex + 1;\n\n  // clear the GameImage, then set it to the image of the\n  // game the user selected\n  GameImage.Canvas.Brush.Color := clBlack;\n  GameImage.Canvas.Rectangle(0, 0, 96, 96);\n  GameIcons.GetBitmap(cbGame.ItemIndex, GameImage.Picture.Bitmap);\n  GameImage.Repaint;\nend;\n\nprocedure TProfilePanel.PathChanged(Sender: TObject);\nbegin\n  // set in profile\n  aProfile.gamePath := AppendIfMissing(edPath.Text, '\\');\n\n  // reflect validity in the GUI\n  if GamePathValid(aProfile.gamePath, aProfile.gameMode) then begin\n    Valid := true;\n    Cursor := crHandPoint;\n    GameImage.Cursor := crHandPoint;\n    Color := ColorValid;\n  end\n  else begin\n    Valid := false;\n    Cursor := crDefault;\n    GameImage.Cursor := crDefault;\n    Color := ColorInvalid;\n  end;\n\n  // repaint to update GUI\n  Repaint;\nend;\n\nprocedure TProfilePanel.SetTop(top: Integer);\nbegin\n  self.top := top;\nend;\n\nprocedure TProfilePanel.SetWidth(width: Integer);\nbegin\n  self.width := width;\nend;\n\nfunction TProfilePanel.GetProfile: TProfile;\nbegin\n  Result := aProfile;\nend;\n\nprocedure TProfilePanel.SetSelectCallback(callback: TNotifyEvent);\nbegin\n  SelectCallback := callback;\nend;\n\nprocedure TProfilePanel.SetDeleteCallback(callback: TNotifyEvent);\nbegin\n  DeleteCallback := callback;\nend;\n\nprocedure TProfilePanel.SetGame(i: Integer);\nbegin\n  cbGame.ItemIndex := i - 1;\n  GameChanged(nil);\nend;\n\nprocedure TProfilePanel.SetPath(path: string);\nbegin\n  edPath.Text := path;\n  PathChanged(nil);\nend;\n\nend.\n"
  },
  {
    "path": "frontend/msSettingsManager.dfm",
    "content": "object SettingsManager: TSettingsManager\n  Left = 0\n  Top = 0\n  Caption = 'Settings Manager'\n  ClientHeight = 582\n  ClientWidth = 1024\n  Color = clBtnFace\n  Constraints.MinHeight = 520\n  Constraints.MinWidth = 960\n  DoubleBuffered = True\n  Font.Charset = DEFAULT_CHARSET\n  Font.Color = clWindowText\n  Font.Height = -11\n  Font.Name = 'Tahoma'\n  Font.Style = []\n  KeyPreview = True\n  OldCreateOrder = False\n  Position = poScreenCenter\n  OnCreate = FormCreate\n  OnDestroy = FormDestroy\n  OnKeyDown = FormKeyDown\n  OnShow = FormShow\n  PixelsPerInch = 96\n  TextHeight = 13\n  object Splitter: TSplitter\n    Left = 650\n    Top = 0\n    Height = 582\n    Beveled = True\n    Color = clSilver\n    ParentColor = False\n    OnMoved = SplitterMoved\n    ExplicitLeft = 857\n    ExplicitHeight = 682\n  end\n  object pnlEntries: TPanel\n    Left = 0\n    Top = 0\n    Width = 650\n    Height = 582\n    Align = alLeft\n    Caption = 'pnlEntries'\n    Constraints.MinWidth = 650\n    TabOrder = 0\n    object lvSettings: TListView\n      Left = 2\n      Top = 1\n      Width = 642\n      Height = 573\n      Align = alCustom\n      Anchors = [akLeft, akTop, akRight, akBottom]\n      Columns = <\n        item\n          Caption = 'Name'\n          Width = 238\n        end\n        item\n          AutoSize = True\n          Caption = 'Records'\n        end>\n      DoubleBuffered = True\n      MultiSelect = True\n      OwnerDraw = True\n      GroupView = True\n      ReadOnly = True\n      RowSelect = True\n      ParentDoubleBuffered = False\n      PopupMenu = SettingsPopupMenu\n      SortType = stData\n      TabOrder = 0\n      TabStop = False\n      ViewStyle = vsReport\n      OnChange = lvSettingsChange\n      OnClick = lvSettingsClick\n      OnDrawItem = lvSettingsDrawItem\n    end\n  end\n  object pnlDetails: TPanel\n    Left = 653\n    Top = 0\n    Width = 371\n    Height = 582\n    Hint = 'The search clears any previous selections, be aware of that!'\n    Align = alClient\n    Constraints.MinWidth = 300\n    ParentShowHint = False\n    ShowHint = True\n    TabOrder = 1\n    object lblName: TLabel\n      Left = 8\n      Top = 12\n      Width = 27\n      Height = 13\n      Margins.Left = 8\n      Margins.Top = 8\n      Align = alCustom\n      Caption = 'Name'\n    end\n    object lblDescription: TLabel\n      Left = 8\n      Top = 93\n      Width = 53\n      Height = 13\n      Margins.Left = 8\n      Margins.Top = 8\n      Align = alCustom\n      Caption = 'Description'\n    end\n    object lblTree: TLabel\n      Left = 8\n      Top = 234\n      Width = 22\n      Height = 13\n      Margins.Left = 8\n      Align = alCustom\n      Caption = 'Tree'\n    end\n    object lblColor: TLabel\n      Left = 8\n      Top = 39\n      Width = 25\n      Height = 13\n      Margins.Left = 8\n      Margins.Top = 8\n      Align = alCustom\n      Caption = 'Color'\n    end\n    object lblHash: TLabel\n      Left = 8\n      Top = 63\n      Width = 24\n      Height = 13\n      Margins.Left = 8\n      Margins.Top = 8\n      Align = alCustom\n      Caption = 'Hash'\n    end\n    object tvRecords: TTreeView\n      Left = 8\n      Top = 261\n      Width = 354\n      Height = 282\n      Margins.Left = 8\n      Align = alCustom\n      Anchors = [akLeft, akTop, akRight, akBottom]\n      DoubleBuffered = True\n      Enabled = False\n      Indent = 19\n      MultiSelect = True\n      MultiSelectStyle = [msControlSelect, msShiftSelect, msVisibleOnly]\n      ParentDoubleBuffered = False\n      ParentShowHint = False\n      PopupMenu = TreePopupMenu\n      ReadOnly = True\n      ShowHint = True\n      StateImages = StateImages\n      TabOrder = 0\n      OnCollapsing = tvRecordsCollapsing\n      OnCustomDrawItem = tvRecordsCustomDrawItem\n      OnKeyDown = tvRecordsKeyDown\n      OnKeyPress = tvRecordsKeyPress\n      OnMouseDown = tvRecordsMouseDown\n      OnMouseMove = tvRecordsMouseMove\n    end\n    object edName: TEdit\n      Left = 152\n      Top = 9\n      Width = 210\n      Height = 21\n      Margins.Left = 8\n      Margins.Right = 8\n      Align = alCustom\n      Anchors = [akLeft, akTop, akRight]\n      Enabled = False\n      TabOrder = 1\n      OnChange = edNameChange\n    end\n    object meDescription: TMemo\n      Left = 8\n      Top = 112\n      Width = 354\n      Height = 100\n      Margins.Left = 8\n      Margins.Right = 8\n      Align = alCustom\n      Anchors = [akLeft, akTop, akRight]\n      Enabled = False\n      TabOrder = 2\n    end\n    object btnSave: TButton\n      Left = 207\n      Top = 549\n      Width = 75\n      Height = 25\n      Align = alCustom\n      Anchors = [akRight, akBottom]\n      Caption = 'Save'\n      Enabled = False\n      TabOrder = 3\n      OnClick = btnSaveClick\n    end\n    object btnDiscard: TButton\n      Left = 288\n      Top = 549\n      Width = 75\n      Height = 25\n      Align = alCustom\n      Anchors = [akRight, akBottom]\n      Caption = 'Discard'\n      Enabled = False\n      TabOrder = 4\n      OnClick = btnDiscardClick\n    end\n    object cbColor: TColorBox\n      Left = 152\n      Top = 36\n      Width = 210\n      Height = 22\n      Margins.Right = 8\n      Align = alCustom\n      Anchors = [akLeft, akTop, akRight, akBottom]\n      Enabled = False\n      TabOrder = 5\n    end\n    object edHash: TEdit\n      Left = 152\n      Top = 63\n      Width = 210\n      Height = 21\n      Margins.Left = 8\n      Margins.Right = 8\n      Align = alCustom\n      Anchors = [akLeft, akTop, akRight]\n      Enabled = False\n      ReadOnly = True\n      TabOrder = 6\n      Text = '$00000000'\n      OnChange = edNameChange\n    end\n    object edSearch: TEdit\n      Left = 152\n      Top = 234\n      Width = 209\n      Height = 21\n      Align = alCustom\n      Anchors = [akLeft, akTop, akRight]\n      TabOrder = 7\n      Text = 'Search...'\n      OnClick = edSearchClick\n      OnKeyPress = edSearchKeyPress\n    end\n  end\n  object SettingsPopupMenu: TPopupMenu\n    OnPopup = SettingsPopupMenuPopup\n    Left = 56\n    Top = 40\n    object NewSettingItem: TMenuItem\n      Caption = 'New setting'\n      OnClick = NewSettingItemClick\n    end\n    object DeleteSettingItem: TMenuItem\n      Caption = 'Delete setting'\n      OnClick = DeleteSettingItemClick\n    end\n    object CloneSettingItem: TMenuItem\n      Caption = 'Clone setting'\n      OnClick = CloneSettingItemClick\n    end\n    object CombineSettingsItem: TMenuItem\n      Caption = 'Combine settings'\n      OnClick = CombineSettingsItemClick\n    end\n  end\n  object TreePopupMenu: TPopupMenu\n    OnPopup = TreePopupMenuPopup\n    Left = 672\n    Top = 504\n    object BuildItem: TMenuItem\n      Caption = 'Build'\n      object AddItem: TMenuItem\n        Caption = 'Add'\n      end\n      object AddAllRecordsItem: TMenuItem\n        Caption = 'Add all records'\n        OnClick = AddAllRecordsItemClick\n      end\n      object BuildFromPluginsItem: TMenuItem\n        Caption = 'Build from plugins'\n        OnClick = BuildFromPluginsItemClick\n      end\n    end\n    object AutosetItem: TMenuItem\n      Caption = 'Autoset attributes'\n      OnClick = AutosetItemClick\n    end\n    object SelectSimilarNodesItem: TMenuItem\n      Caption = 'Select similar nodes'\n      OnClick = SelectSimilarNodesItemClick\n    end\n    object ToggleItem: TMenuItem\n      Caption = 'Toggle'\n      object ToggleNodesItem: TMenuItem\n        Caption = 'Toggle nodes'\n        OnClick = ToggleNodesItemClick\n      end\n      object PreserveDeletionsItem: TMenuItem\n        Caption = 'Toggle preserve deletions'\n        OnClick = PreserveDeletionsItemClick\n      end\n      object OverrideDeletionsItem: TMenuItem\n        Caption = 'Toggle override deletions'\n        OnClick = OverrideDeletionsItemClick\n      end\n      object SingleEntityItem: TMenuItem\n        Caption = 'Toggle treat as single entity'\n        OnClick = SingleEntityItemClick\n      end\n      object ForceValueItem: TMenuItem\n        Caption = 'Toggle force values'\n        OnClick = ForceValueItemClick\n      end\n    end\n    object LinkItem: TMenuItem\n      Caption = 'Link'\n      object ChainNodesItem: TMenuItem\n        Caption = 'Chain nodes'\n        OnClick = ChainNodesItemClick\n      end\n      object LinkNodeToItem: TMenuItem\n        Caption = 'Link node to'\n      end\n      object UnlinkNodeItem: TMenuItem\n        Caption = 'Unlink nodes'\n        OnClick = UnlinkNodeItemClick\n      end\n    end\n    object PruneItem: TMenuItem\n      Caption = 'Prune'\n      object AutoPruneItem: TMenuItem\n        Caption = 'Auto-prune nodes'\n        OnClick = AutoPruneItemClick\n      end\n      object PruneNodesItem: TMenuItem\n        Caption = 'Prune nodes'\n        OnClick = PruneNodesItemClick\n      end\n    end\n  end\n  object StateImages: TImageList\n    Height = 17\n    Width = 17\n    Left = 752\n    Top = 504\n    Bitmap = {\n      494C010104000800000111001100FFFFFFFFFF10FFFFFFFFFFFFFFFF424D3600\n      0000000000003600000028000000440000002200000001002000000000002024\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\n      FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\n      FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\n      FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\n      FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\n      FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\n      FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\n      FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\n      FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\n      FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\n      FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\n      FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\n      FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\n      FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\n      FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\n      FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\n      FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\n      FFFFFFFFFFFFFFFFFFFF8F8F8EFF8F8F8EFF8F8F8EFF8F8F8EFF8F8F8EFF8F8F\n      8EFF8F8F8EFF8F8F8EFF8F8F8EFF8F8F8EFF8F8F8EFF8F8F8EFF8F8F8EFFFFFF\n      FFFFFFFFFFFFFFFFFFFFFFFFFFFF8F8F8EFF8F8F8EFF8F8F8EFF8F8F8EFF8F8F\n      8EFF8F8F8EFF8F8F8EFF8F8F8EFF8F8F8EFF8F8F8EFF8F8F8EFF8F8F8EFF8F8F\n      8EFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8F8F8EFF8F8F8EFF8F8F8EFF8F8F\n      8EFF8F8F8EFF8F8F8EFF8F8F8EFF8F8F8EFF8F8F8EFF8F8F8EFF8F8F8EFF8F8F\n      8EFF8F8F8EFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8F8F8EFF8F8F8EFF8F8F\n      8EFF8F8F8EFF8F8F8EFF8F8F8EFF8F8F8EFF8F8F8EFF8F8F8EFF8F8F8EFF8F8F\n      8EFF8F8F8EFF8F8F8EFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8F8F8EFFF4F4\n      F4FFF4F4F4FFF4F4F4FFF5F5F5FFF9F9F9FFF8F8F8FFF5F5F5FFF4F4F4FFF4F4\n      F4FFF4F4F4FFF4F4F4FF8F8F8EFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8F8F\n      8EFFF4F4F4FFF4F4F4FFF4F4F4FFF5F5F5FFF9F9F9FFF8F8F8FFF5F5F5FFF4F4\n      F4FFF4F4F4FFF4F4F4FFF4F4F4FF8F8F8EFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\n      FFFF8F8F8EFFF4F4F4FFF4F4F4FFF4F4F4FFF4F4F4FFF4F4F4FFF4F4F4FFF4F4\n      F4FFF4F4F4FFF4F4F4FFF4F4F4FFF4F4F4FF8F8F8EFFFFFFFFFFFFFFFFFFFFFF\n      FFFFFFFFFFFF8F8F8EFFF4F4F4FFF4F4F4FFF4F4F4FFF4F4F4FFF4F4F4FFF4F4\n      F4FFF4F4F4FFF4F4F4FFF4F4F4FFF4F4F4FFF4F4F4FF8F8F8EFFFFFFFFFFFFFF\n      FFFFFFFFFFFFFFFFFFFF8F8F8EFFF4F4F4FFCCCBCAFFDBDADAFFE9E2DFFFBA99\n      8CFFBD9D90FFF6F3F2FFEDEDECFFECEBEBFFEAE9E9FFF4F4F4FF8F8F8EFFFFFF\n      FFFFFFFFFFFFFFFFFFFFFFFFFFFF8F8F8EFFF4F4F4FFCCCBCAFFDBDADAFFE9E2\n      DFFFBA998CFFBD9D90FFF6F3F2FFEDEDECFFECEBEBFFEAE9E9FFF4F4F4FF8F8F\n      8EFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8F8F8EFFF4F4F4FFCCCBCAFFD5D4\n      D4FFDCDBDBFFE1E1E0FFE7E7E6FFEBEBEAFFECECEBFFECEBEBFFEAE9E9FFF4F4\n      F4FF8F8F8EFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8F8F8EFFF4F4F4FF714E\n      21FF6A491FFF61441DFF593E1AFF553B19FF553B19FF553A19FF553A19FF553B\n      19FFF4F4F4FF8F8F8EFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8F8F8EFFF4F4\n      F4FFCAC8C6FFF0ECEAFFBB998BFF975F4AFF98614CFFD1B9B0FFF9F9F9FFF6F6\n      F6FFE6E6E6FFF4F4F4FF8F8F8EFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8F8F\n      8EFFF4F4F4FFCAC8C6FFF0ECEAFFBB998BFF975F4AFF98614CFFD1B9B0FFF9F9\n      F9FFF6F6F6FFE6E6E6FFF4F4F4FF8F8F8EFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\n      FFFF8F8F8EFFF4F4F4FFC6C4C2FFE9E9E9FFEDEDEDFFF0F0F0FFF4F4F4FFF6F6\n      F6FFF6F6F6FFF6F6F6FFE6E6E6FFF4F4F4FF8F8F8EFFFFFFFFFFFFFFFFFFFFFF\n      FFFFFFFFFFFF8F8F8EFFF4F4F4FF755123FFB89255FFAE864CFFA47A44FF996E\n      3BFF936532FF8F5F2CFF8C5925FF553B19FFF4F4F4FF8F8F8EFFFFFFFFFFFFFF\n      FFFFFFFFFFFFFFFFFFFF8F8F8EFFF4F4F4FFD1CFCDFFE9E1DEFF955D48FF965F\n      49FF97604BFFA47361FFFAF9F8FFF4F4F4FFE2E2E1FFF4F4F4FF8F8F8EFFFFFF\n      FFFFFFFFFFFFFFFFFFFFFFFFFFFF8F8F8EFFF4F4F4FFD1CFCDFFE9E1DEFF955D\n      48FF965F49FF97604BFFA47361FFFAF9F8FFF4F4F4FFE2E2E1FFF4F4F4FF8F8F\n      8EFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8F8F8EFFF4F4F4FFC2BFBCFFE5E4\n      E3FFE9E9E9FFEDEDEDFFF2F2F2FFF4F4F4FFF5F5F5FFF4F4F4FFE2E2E1FFF4F4\n      F4FF8F8F8EFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8F8F8EFFF4F4F4FF7B55\n      24FFC29D5DFFB38927FFAA8124FFA07822FF966F1FFF8F691EFF8F602CFF553B\n      19FFF4F4F4FF8F8F8EFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8F8F8EFFF4F4\n      F4FFE1E0DEFFAA7F6EFF945C47FFE2D4CFFFA77867FF97604BFFD5BFB7FFF6F6\n      F6FFDEDDDCFFF4F4F4FF8F8F8EFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8F8F\n      8EFFF4F4F4FFE1E0DEFFAA7F6EFF945C47FFE2D4CFFFA77867FF97604BFFD5BF\n      B7FFF6F6F6FFDEDDDCFFF4F4F4FF8F8F8EFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\n      FFFF8F8F8EFFF4F4F4FFBFBBB8FFE1DFDDFFE5E5E4FFEAEAEAFFEFEFEFFFF2F2\n      F2FFF2F2F2FFF2F2F2FFDEDDDCFFF4F4F4FF8F8F8EFFFFFFFFFFFFFFFFFFFFFF\n      FFFFFFFFFFFF8F8F8EFFF4F4F4FF815A26FFCBA966FFBF942AFFB88E28FFB087\n      26FFA77F24FF9F7722FF9A6B34FF5C401BFFF4F4F4FF8F8F8EFFFFFFFFFFFFFF\n      FFFFFFFFFFFFFFFFFFFF8F8F8EFFF4F4F4FFCDC9C5FFDDCFC9FFC8AEA3FFEEEE\n      EDFFD5C1BAFF965E49FFA57664FFF8F8F8FFD6D5D5FFF4F4F4FF8F8F8EFFFFFF\n      FFFFFFFFFFFFFFFFFFFFFFFFFFFF8F8F8EFFF4F4F4FFCDC9C5FFDDCFC9FFC8AE\n      A3FFEEEEEDFFD5C1BAFF965E49FFA57664FFF8F8F8FFD6D5D5FFF4F4F4FF8F8F\n      8EFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8F8F8EFFF4F4F4FFBCB7B2FFDCD8\n      D5FFDFDCDAFFE3E1E0FFE8E8E8FFECECECFFEDEDEDFFEDEDEDFFD6D5D4FFF4F4\n      F4FF8F8F8EFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8F8F8EFFF4F4F4FF855D\n      27FFD4B36DFFC99E2CFFC4992BFFBE932AFFB78D28FFAE8525FFA6793EFF6546\n      1EFFF4F4F4FF8F8F8EFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8F8F8EFFF4F4\n      F4FFB9B3AEFFDDD9D5FFE5E2DFFFDCD8D5FFF4F3F2FFA1715EFF945C47FFD6C3\n      BCFFDCDCDBFFF4F4F4FF8F8F8EFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8F8F\n      8EFFF4F4F4FFB9B3AEFFDDD9D5FFE5E2DFFFDCD8D5FFF4F3F2FFA1715EFF945C\n      47FFD6C3BCFFDCDCDBFFF4F4F4FF8F8F8EFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\n      FFFF8F8F8EFFF4F4F4FFB9B3AEFFD7D1CDFFD9D4D0FFDBD7D4FFDFDDDBFFE3E2\n      E1FFE6E6E5FFE8E8E8FFCDCDCCFFF4F4F4FF8F8F8EFFFFFFFFFFFFFFFFFFFFFF\n      FFFFFFFFFFFF8F8F8EFFF4F4F4FF895F28FFDABB74FFD1A42EFFCEA22DFFC99D\n      2CFFC2972BFFBB9129FFB18647FF6E4C20FFF4F4F4FF8F8F8EFFFFFFFFFFFFFF\n      FFFFFFFFFFFFFFFFFFFF8F8F8EFFF4F4F4FFB9B3AEFFD5CFCBFFD5CFCBFFD6D1\n      CDFFE6E2E0FFCFB8AFFF925A45FFA57765FFE8E7E7FFF4F4F4FF8F8F8EFFFFFF\n      FFFFFFFFFFFFFFFFFFFFFFFFFFFF8F8F8EFFF4F4F4FFB9B3AEFFD5CFCBFFD5CF\n      CBFFD6D1CDFFE6E2E0FFCFB8AFFF925A45FFA57765FFE8E7E7FFF4F4F4FF8F8F\n      8EFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8F8F8EFFF4F4F4FFB9B3AEFFD5CF\n      CBFFD5CFCBFFD6D1CDFFDAD5D2FFDEDBD8FFE1DFDDFFE4E3E2FFC8C7C6FFF4F4\n      F4FF8F8F8EFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8F8F8EFFF4F4F4FF8B61\n      29FFE0C27BFFD5A82FFFD3A62FFFD0A42EFFCB9F2DFFC5992BFFBB9250FF7652\n      23FFF4F4F4FF8F8F8EFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8F8F8EFFF4F4\n      F4FFB9B3AEFFD5CFCBFFD5CFCBFFD5CFCBFFD6D0CCFFF1EEEDFF9D6A57FF925A\n      44FFD0BFB9FFF6F6F6FF8F8F8EFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8F8F\n      8EFFF4F4F4FFB9B3AEFFD5CFCBFFD5CFCBFFD5CFCBFFD6D0CCFFF1EEEDFF9D6A\n      57FF925A44FFD0BFB9FFF6F6F6FF8F8F8EFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\n      FFFF8F8F8EFFF4F4F4FFB9B3AEFFD5CFCBFFD5CFCBFFD5CFCBFFD5CFCBFFD8D3\n      D0FFDCD8D5FFDFDDDBFFC5C3C1FFF4F4F4FF8F8F8EFFFFFFFFFFFFFFFFFFFFFF\n      FFFFFFFFFFFF8F8F8EFFF4F4F4FF8D6229FFE4C87FFFE1C37BFFDDBE75FFD9B7\n      6EFFD3AF68FFCCA760FFC49D59FF7C5624FFF4F4F4FF8F8F8EFFFFFFFFFFFFFF\n      FFFFFFFFFFFFFFFFFFFF8F8F8EFFF4F4F4FFB9B3AEFFB9B3AEFFB9B3AEFFB9B3\n      AEFFB9B3AEFFD0CCC9FFC0A79DFFAB8677FFE4DFDCFFF5F5F5FF8F8F8EFFFFFF\n      FFFFFFFFFFFFFFFFFFFFFFFFFFFF8F8F8EFFF4F4F4FFB9B3AEFFB9B3AEFFB9B3\n      AEFFB9B3AEFFB9B3AEFFD0CCC9FFC0A79DFFAB8677FFE4DFDCFFF5F5F5FF8F8F\n      8EFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8F8F8EFFF4F4F4FFB9B3AEFFB9B3\n      AEFFB9B3AEFFB9B3AEFFB9B3AEFFB9B3AEFFBAB4AFFFBDB9B4FFC1BEBBFFF4F4\n      F4FF8F8F8EFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8F8F8EFFF4F4F4FF8D62\n      29FF8E622AFF8E622AFF8D622AFF8C6129FF8A6028FF875E28FF845B27FF8059\n      26FFF4F4F4FF8F8F8EFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8F8F8EFFF4F4\n      F4FFF4F4F4FFF4F4F4FFF4F4F4FFF4F4F4FFF4F4F4FFF4F4F4FFF8F8F8FFF9F9\n      F9FFF6F6F6FFF4F4F4FF8F8F8EFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8F8F\n      8EFFF4F4F4FFF4F4F4FFF4F4F4FFF4F4F4FFF4F4F4FFF4F4F4FFF4F4F4FFF8F8\n      F8FFF9F9F9FFF6F6F6FFF4F4F4FF8F8F8EFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\n      FFFF8F8F8EFFF4F4F4FFF4F4F4FFF4F4F4FFF4F4F4FFF4F4F4FFF4F4F4FFF4F4\n      F4FFF4F4F4FFF4F4F4FFF4F4F4FFF4F4F4FF8F8F8EFFFFFFFFFFFFFFFFFFFFFF\n      FFFFFFFFFFFF8F8F8EFFF4F4F4FFF4F4F4FFF4F4F4FFF4F4F4FFF4F4F4FFF4F4\n      F4FFF4F4F4FFF4F4F4FFF4F4F4FFF4F4F4FFF4F4F4FF8F8F8EFFFFFFFFFFFFFF\n      FFFFFFFFFFFFFFFFFFFF8F8F8EFF8F8F8EFF8F8F8EFF8F8F8EFF8F8F8EFF8F8F\n      8EFF8F8F8EFF8F8F8EFF8F8F8EFF8F8F8EFF8F8F8EFF8F8F8EFF8F8F8EFFFFFF\n      FFFFFFFFFFFFFFFFFFFFFFFFFFFF8F8F8EFF8F8F8EFF8F8F8EFF8F8F8EFF8F8F\n      8EFF8F8F8EFF8F8F8EFF8F8F8EFF8F8F8EFF8F8F8EFF8F8F8EFF8F8F8EFF8F8F\n      8EFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8F8F8EFF8F8F8EFF8F8F8EFF8F8F\n      8EFF8F8F8EFF8F8F8EFF8F8F8EFF8F8F8EFF8F8F8EFF8F8F8EFF8F8F8EFF8F8F\n      8EFF8F8F8EFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8F8F8EFF8F8F8EFF8F8F\n      8EFF8F8F8EFF8F8F8EFF8F8F8EFF8F8F8EFF8F8F8EFF8F8F8EFF8F8F8EFF8F8F\n      8EFF8F8F8EFF8F8F8EFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\n      FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\n      FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\n      FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\n      FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\n      FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\n      FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\n      FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\n      FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\n      FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\n      FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\n      FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\n      FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\n      FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\n      FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\n      FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\n      FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\n      FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF424D3E000000000000003E000000\n      2800000044000000220000000100010000000000980100000000000000000000\n      000000000000000000000000FFFFFF0000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      000000000000000000000000000000000000000000000000000000000000}\n  end\n  object FlagIcons: TImageList\n    Left = 824\n    Top = 504\n    Bitmap = {\n      494C0101050008004C0110001000FFFFFFFFFF10FFFFFFFFFFFFFFFF424D3600\n      0000000000003600000028000000400000002000000001002000000000000020\n      00000000000000000000000000000000000000000000D1D1D12E4F4F4FB01B1B\n      1BE42B2B2BD48282827DF7F7F708000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      000000000000000000000000000000000000D1D1D12E0C0C0CF3000000FF0000\n      00FF000000FF000000FF3B3B3BC4F2F2F20D0000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000004E4E4EB1000000FF4D4D4DB2D7D7\n      D728B2B2B24D1A1A1AE5000000FF3A3A3AC5F2F2F20D00000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000001B1B1BE4000000FFD7D7D7280000\n      000000000000D9D9D9261B1B1BE4000000FF3A3A3AC5F2F2F20D000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000002B2B2BD4000000FFB3B3B34C0000\n      00000000000000000000D9D9D926BABABA45EFEFEF10F3F3F30C000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000008383837C000000FF1A1A1AE5D9D9\n      D9260000000000000000C3C3C33C424242BD131313EC262626D97F7F7F80F7F7\n      F708000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      000000000000000000000000000000000000F7F7F7083B3B3BC4000000FF1B1B\n      1BE4D9D9D926E3E3E31C060606F9000000FF000000FF000000FF000000FF3B3B\n      3BC4F2F2F20D0000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      00000000000000000000000000000000000000000000F2F2F20D3A3A3AC50000\n      00FF1B1B1BE4CECECE31444444BB7171718EE1E1E11EB7B7B7481A1A1AE50000\n      00FF3A3A3AC5F2F2F20D00000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000F2F2F20D3A3A\n      3AC5000000FF1A1A1AE5B8B8B847E1E1E11E7171718E444444BBCECECE311B1B\n      1BE4000000FF3A3A3AC5F2F2F20D000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      000000000000000000000000000000000000000000000000000000000000F2F2\n      F20D3B3B3BC4000000FF000000FF000000FF000000FF060606F9E3E3E31CD9D9\n      D9261B1B1BE4000000FF3B3B3BC4F7F7F7080000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000F7F7F7087F7F7F80262626D9131313EC424242BDC3C3C33C000000000000\n      0000D9D9D9261A1A1AE5000000FF8383837C0000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      00000000000000000000F3F3F30CEFEFEF10BABABA45D9D9D926000000000000\n      000000000000B3B3B34C000000FF2C2C2CD30000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      00000000000000000000F2F2F20D3A3A3AC5000000FF1B1B1BE4D9D9D9260000\n      000000000000D7D7D728000000FF1B1B1BE40000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000F2F2F20D3A3A3AC5000000FF1A1A1AE5B3B3\n      B34CD7D7D7284E4E4EB1000000FF4F4F4FB00000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      000000000000000000000000000000000000F2F2F20D3B3B3BC4000000FF0000\n      00FF000000FF000000FF0C0C0CF3D2D2D22D0000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      00000000000000000000000000000000000000000000F7F7F7088282827D2B2B\n      2BD41C1C1CE34F4F4FB0D2D2D22D000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000D7D7F8FF7373E6FF3434DBFF2121BEFF2121BEFF2D2DDAFF6B6BE4FFD2D2\n      F7FF000000000000000000000000000000000000000000000000000000000000\n      0000A0AE9D666A9161AA31881DFF31881DFF31881DFF31881DFF6A9161AAA0AE\n      9D66000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000E4F1E779D7D6B8CCD4BF91F3D2B683FED2B581FED1BD8FF3D5D3B5CCE3F0\n      E679000000000000000000000000000000000000000000000000F8F8FDFF7373\n      E6FF2020B5FF2020B5FF3434DBFF5B5BE2FF5B5BE2FF3D3DDCFF2020B5FF2020\n      B5FF6464E3FFF8F8FDFF00000000000000000000000000000000EEEEEE115189\n      45CC31881DFF31881DFF31881DFF31881DFF31881DFF31881DFF31881DFF3188\n      1DFF518945CCEEEEEE110000000000000000000000000000000000000000232D\n      3A00232D3A00232D3A0000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000F2F8F33CD9D8\n      BACBDCAB6CFEE1974BFFE18F3DFFE18A37FFDF8835FFDD8A39FFD99044FFD4A3\n      64FED4D4B6CBF1F7F23C000000000000000000000000F8F8FDFF4242DDFF2020\n      B5FF5353E0FFD7D7F8FF00000000000000000000000000000000E2E2F9FF5B5B\n      E2FF2020B5FF3D3DDCFFEFEFFCFF0000000000000000EEEEEE113B8629EE3188\n      1DFF31881DFF31881DFF31881DFF31881DFF31881DFF31881DFF31881DFF3188\n      1DFF31881DFF3B8629EEEEEEEE1100000000000000000000000000000000232D\n      3A00232D3A00232D3A0000000000000000000000000000000000000000000000\n      00000000000000000000000000000000000000000000F2F8F33CDBCDA5DEE3A1\n      58FFE69240FFE58F3AFFE48D39FFE28B37FFE08A36FFDF8834FFDD8733FFDB87\n      35FFD7944CFFD3C49DDEF1F7F23C00000000000000007373E6FF2020B5FF8282\n      E9FF000000000000000000000000FEFEFE03FDFDFE0700000000000000000000\n      00009292EBFF2020B5FF6464E3FF0000000000000000518945CC31881DFF3188\n      1DFF31881DFF31881DFF31881DFF31881DFF31881DFF31881DFF31881DFF3188\n      1DFF31881DFF31881DFF518945CC00000000000000000000000000000000232D\n      3A00232D3A00232D3A0000000000000000000000000000000000000000000000\n      00000000000000000000000000000000000000000000DBDABCCBE6A35AFFE994\n      41FFE8923EFFE7903CFFE58E3AFFE38D38FFE28B37FFE08935FFDF8834FFDD86\n      32FFDC8633FFD6944BFFD4D3B5CB00000000D7D7F8FF2020B5FF5353E0FF0000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000006464E3FF2020B5FFC8C8F5FFA0AE9D6631881DFF31881DFF3188\n      1DFF31881DFF31881DFF31881DFFFFFFFFFFFFFFFFFF31881DFF31881DFF3188\n      1DFF31881DFF31881DFF31881DFFA0AE9D66000000000000000000000000232D\n      3A00232D3A00232D3A0000000000000000000000000000000000000000000000\n      000000000000000000000000000000000000E6F3E879E3B273FEEC9846FFEB95\n      41FFEA933FFFE8913DFFEAA560FFF9F7F5FFF8F0E8FFE18B37FFE08935FFDE88\n      33FFDD8632FFDA8735FFD3A263FEE3F0E6797A7AE7FF2020B5FFD2D2F7FF0000\n      00000000000000000000FEFEFE0D0000000000000000F4F4FC28000000000000\n      000000000000E2E2F9FF2020B5FF6B6BE4FF5D8C52BB31881DFF31881DFF3188\n      1DFF31881DFF31881DFF31881DFFFFFFFFFFFFFFFFFF31881DFF31881DFF3188\n      1DFF31881DFF31881DFF31881DFF5D8C52BB000000000000000000000000232D\n      3A00232D3A00232D3A0000000000000000000000000000000000000000000000\n      000000000000000000000000000000000000DDDBBDCCEBA256FFEE9844FFED96\n      42FFEB9440FFE9933FFFEBA562FFF9F7F5FFF8F0E8FFE38C38FFE18A36FFE089\n      35FFDE8733FFDD8632FFD88F43FFD4D3B5CC3434DBFF3434DBFF000000000000\n      0000B9B9F2FFB9B9F2FFB9B9F2FFB9B9F2FFB9B9F2FFB9B9F2FFB9B9F2FFB9B9\n      F2FFEFEFFCFF000000004242DDFF2525D6FF31881DFF31881DFF31881DFF3188\n      1DFF31881DFF31881DFF31881DFFFFFFFFFFFFFFFFFF31881DFF31881DFF3188\n      1DFF31881DFF31881DFF31881DFF31881DFF000000000000000000000000232D\n      3A00232D3A00232D3A0000000000000000000000000000000000000000000000\n      000000000000000000000000000000000000DDC89AF3F09D4BFFF09945FFEE97\n      43FFED9642FFEB9440FFECA663FFF9F7F5FFF8F0E9FFE48D39FFE28C38FFE18A\n      36FFDF8934FFDE8733FFDB8937FFD1BC8DF32323C6FF5353E0FF000000000000\n      00002121BEFF2020B5FF2020B5FF2020B5FF2020B5FF2020B5FF2020B5FF2020\n      B5FFC8C8F5FF000000006464E3FF2121BEFF31881DFF31881DFF31881DFF3188\n      1DFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\n      FFFF31881DFF31881DFF31881DFF31881DFF000000000000000000000000232D\n      3A00232D3A00232D3A00232D3A00232D3A00232D3A00232D3A00232D3A000000\n      000000000000000000000000000000000000DFC38FFEF39C49FFF19A46FFEF99\n      44FFEE9743FFEC9541FFEEA864FFF9F7F5FFF8F0E9FFE68F3BFFE48D39FFE28B\n      37FFE18A36FFDF8834FFDD8734FFD0B480FE2323C6FF5353E0FF000000000000\n      00002020B5FF2020B5FF2020B5FF2020B5FF2020B5FF2020B5FF2020B5FF2020\n      B5FFC8C8F5FF000000006464E3FF2121BEFF31881DFF31881DFF31881DFF3188\n      1DFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\n      FFFF31881DFF31881DFF31881DFF31881DFF000000000000000000000000232D\n      3A00232D3A00232D3A00232D3A00232D3A00232D3A00232D3A00232D3A000000\n      000000000000000000000000000000000000E0C390FEF49D4AFFF29B47FFF19A\n      46FFEF9844FFEE9743FFEFA965FFF9F7F5FFF8F0E9FFE7903CFFE58E3AFFE48D\n      39FFE28B37FFE08A35FFDF8835FFD1B581FE3D3DDCFF2D2DDAFF000000000000\n      0000F8F8FDFFF8F8FDFFEFEFFCFFEFEFFCFFEFEFFCFFEFEFFCFFEFEFFCFFF8F8\n      FDFFF8F8FDFF000000003D3DDCFF2525D6FF31881DFF31881DFF31881DFF3188\n      1DFF31881DFF31881DFF31881DFFFFFFFFFFFFFFFFFF31881DFF31881DFF3188\n      1DFF31881DFF31881DFF31881DFF31881DFF000000000000000000000000232D\n      3A00232D3A00232D3A0000000000000000000000000000000000000000000000\n      000000000000000000000000000000000000DFCA9CF3F3A14FFFF39D48FFF29B\n      47FFF09A45FFEF9844FFF0B172FFF9F7F5FFF8F0E9FFE8913DFFE7903CFFE58E\n      3AFFE38C38FFE28B37FFDF8C3BFFD2BE90F37373E6FF2020B5FFD2D2F7FF0000\n      0000000000000000000000000000F1F1FA0FFAFAFD05F1F1FC32000000000000\n      000000000000E2E2F9FF2020B5FF6B6BE4FF5D8C52BB31881DFF31881DFF3188\n      1DFF31881DFF31881DFF31881DFFFFFFFFFFFFFFFFFF31881DFF31881DFF3188\n      1DFF31881DFF31881DFF31881DFF5D8C52BB000000000000000000000000232D\n      3A00232D3A00232D3A0000000000000000000000000000000000000000000000\n      000000000000000000000000000000000000DFDDBFCCF1A85BFFF49E4AFFF39C\n      48FFF29B47FFF5CBA3FFF9F7F5FFF9F7F5FFF8F0E9FFEA933FFFE8913DFFE68F\n      3BFFE58E3AFFE38C38FFDE9548FFD7D5B7CCD7D7F8FF2020B5FF5353E0FF0000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000006464E3FF2020B5FFC8C8F5FFA0AE9D6631881DFF31881DFF3188\n      1DFF31881DFF31881DFF31881DFFFFFFFFFFFFFFFFFF31881DFF31881DFF3188\n      1DFF31881DFF31881DFF31881DFFA0AE9D66000000000000000000000000232D\n      3A00232D3A00232D3A0000000000000000000000000000000000000000000000\n      000000000000000000000000000000000000E7F3E979E9B879FEF4A14FFFF49D\n      49FFF39C48FFF19B46FFF19F51FFF6DEC6FFF8F1E9FFEB9440FFE9933EFFE891\n      3DFFE68F3BFFE3903DFFDAA96AFEE4F1E779000000007A7AE7FF2020B5FF8282\n      E9FF000000000000000000000000000000000000000000000000000000000000\n      00008B8BEAFF2020B5FF6464E3FF0000000000000000518945CC31881DFF3188\n      1DFF31881DFF31881DFF31881DFF31881DFF31881DFF31881DFF31881DFF3188\n      1DFF31881DFF31881DFF518945CC00000000000000000000000000000000232D\n      3A00232D3A00232D3A00232D3A00232D3A00232D3A00232D3A00232D3A00232D\n      3A000000000000000000000000000000000000000000DFDEC0CBEFAD64FFF4A0\n      4CFFF49D49FFF39C48FFF19A46FFF09945FFEE9743FFEC9641FFEB9440FFE992\n      3EFFE7913EFFE19E55FFD8D7B9CB0000000000000000F8F8FDFF4242DDFF2020\n      B5FF5353E0FFD7D7F8FF00000000000000000000000000000000D7D7F8FF5B5B\n      E2FF2020B5FF4242DDFFEFEFFCFF0000000000000000EEEEEE113B8629EE3188\n      1DFF31881DFF31881DFF31881DFF31881DFF31881DFF31881DFF31881DFF3188\n      1DFF31881DFF3B8629EEEEEEEE1100000000000000000000000000000000232D\n      3A00232D3A00232D3A00232D3A00232D3A00232D3A00232D3A00232D3A00232D\n      3A000000000000000000000000000000000000000000F3F9F43CE1D2ABDEEFAD\n      63FFF4A04EFFF49D49FFF29B47FFF19A46FFEF9944FFEE9743FFEC9541FFE996\n      43FFE3A158FFD9CAA3DEF2F8F33C000000000000000000000000F8F8FDFF7373\n      E6FF2020B5FF2020B5FF3434DBFF6464E3FF5B5BE2FF3D3DDCFF2020B5FF2020\n      B5FF6B6BE4FFEFEFFCFF00000000000000000000000000000000EEEEEE115189\n      45CC31881DFF31881DFF31881DFF31881DFF31881DFF31881DFF31881DFF3188\n      1DFF518945CCEEEEEE1100000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000F3F9F43CDFDD\n      C0CBE8B778FEF0A75AFFF2A04EFFF29B48FFF19A47FFEE9B49FFE9A053FFE0B0\n      71FEDAD9BCCBF2F8F33C00000000000000000000000000000000000000000000\n      0000D7D7F8FF7373E6FF2D2DDAFF2121BEFF2121BEFF2D2DDAFF6B6BE4FFD2D2\n      F7FF000000000000000000000000000000000000000000000000000000000000\n      0000A0AE9D666A9161AA31881DFF31881DFF31881DFF31881DFF6A9161AAA0AE\n      9D66000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000E6F3E979DFDCBFCCDEC99BF3DFC28EFEDEC18EFEDCC799F3DCDABCCCE5F2\n      E87900000000000000000000000000000000424D3E000000000000003E000000\n      2800000040000000200000000100010000000000000100000000000000000000\n      000000000000000000000000FFFFFF0081FF00000000000000FF000000000000\n      007F000000000000183F0000000000001C3F0000000000000C0F000000000000\n      00070000000000008003000000000000C001000000000000E000000000000000\n      F030000000000000FC38000000000000FC18000000000000FE00000000000000\n      FF00000000000000FF81000000000000F00FF00FFFFFF00FC003C003E3FFC003\n      83C18001E3FF80018E718001E3FF80011FF80000E3FF00001DB80000E3FF0000\n      30040000E3FF000030040000E01F000030040000E01F000030040000E3FF0000\n      1E380000E3FF00001FF80000E3FF00008FF18001E00F800183C18001E00F8001\n      C003C003FFFFC003F00FF00FFFFFF00F00000000000000000000000000000000\n      000000000000}\n  end\nend\n"
  },
  {
    "path": "frontend/msSettingsManager.pas",
    "content": "unit msSettingsManager;\n\ninterface\n\nuses\n  Windows, Types, Messages, SysUtils, Variants, Classes, Graphics, Controls,\n  Forms, Dialogs, StdCtrls, ExtCtrls, ComCtrls, Grids, ValEdit, CommCtrl, Menus,\n  ImgList, StrUtils,\n  // superobject\n  superobject,\n  // mte units\n  mteHelpers, mteLogger, mteProgressForm, mteBase, RttiTranslation,\n  // ms units\n  msCore, msConfiguration, msPluginSelectionForm, msConflictForm, msThreads;\n\ntype\n  TSettingsManager = class(TForm)\n    [FormPrefix('msSet')]\n      Splitter: TSplitter;\n      [FormSection('Settings')]\n        pnlEntries: TPanel;\n        lvSettings: TListView;\n        [FormSection('Settings Popup Menu')]\n          SettingsPopupMenu: TPopupMenu;\n          NewSettingItem: TMenuItem;\n          DeleteSettingItem: TMenuItem;\n          CloneSettingItem: TMenuItem;\n          CombineSettingsItem: TMenuItem;\n      [FormSection('Details')]\n        pnlDetails: TPanel;\n        lblName: TLabel;\n        edName: TEdit;\n        lblColor: TLabel;\n        cbColor: TColorBox;\n        lblHash: TLabel;\n        edHash: TEdit;\n        lblDescription: TLabel;\n        meDescription: TMemo;\n        btnSave: TButton;\n        btnDiscard: TButton;\n        [FormSection('Tree')]\n          lblTree: TLabel;\n          edSearch: TEdit;\n          tvRecords: TTreeView;\n          StateImages: TImageList;\n          FlagIcons: TImageList;\n          [FormSection('TreePopupMenu')]\n            TreePopupMenu: TPopupMenu;\n            LinkItem: TMenuItem;\n            PruneItem: TMenuItem;\n            BuildItem: TMenuItem;\n            ToggleItem: TMenuItem;\n            AddItem: TMenuItem;\n            AddAllRecordsItem: TMenuItem;\n            BuildFromPluginsItem: TMenuItem;\n            AutosetItem: TMenuItem;\n            SelectSimilarNodesItem: TMenuItem;\n            ToggleNodesItem: TMenuItem;\n            PreserveDeletionsItem: TMenuItem;\n            OverrideDeletionsItem: TMenuItem;\n            SingleEntityItem: TMenuItem;\n            ForceValueItem: TMenuItem;\n            ChainNodesItem: TMenuItem;\n            LinkNodeToItem: TMenuItem;\n            UnlinkNodeItem: TMenuItem;\n            AutoPruneItem: TMenuItem;\n            PruneNodesItem: TMenuItem;\n\n    // TREE METHODS\n    procedure DrawFlag(Canvas: TCanvas; var x, y: Integer; id: Integer);\n    procedure tvRecordsCustomDrawItem(Sender: TCustomTreeView;\n      Node: TTreeNode; State: TCustomDrawState; var DefaultDraw: Boolean);\n    procedure tvRecordsKeyDown(Sender: TObject; var Key: Word;\n      Shift: TShiftState);\n    procedure tvRecordsMouseDown(Sender: TObject; Button: TMouseButton;\n      Shift: TShiftState; X, Y: Integer);\n    procedure tvRecordsCollapsing(Sender: TObject; Node: TTreeNode;\n      var AllowCollapse: Boolean);\n    procedure tvRecordsKeyPress(Sender: TObject; var Key: Char);\n    procedure tvRecordsMouseMove(Sender: TObject; Shift: TShiftState; X,\n      Y: Integer);\n    procedure LinkNodeItemClick(Sender: TObject);\n    procedure TreePopupMenuPopup(Sender: TObject);\n    procedure AddItemClick(Sender: TObject);\n    procedure AddAllRecordsItemClick(Sender: TObject);\n    procedure BuildFromPluginsItemClick(Sender: TObject);\n    procedure SelectSimilarNodesItemClick(Sender: TObject);\n    procedure ToggleNodesItemClick(Sender: TObject);\n    procedure PreserveDeletionsItemClick(Sender: TObject);\n    procedure OverrideDeletionsItemClick(Sender: TObject);\n    procedure SingleEntityItemClick(Sender: TObject);\n    procedure ForceValueItemClick(Sender: TObject);\n    procedure PruneNodesItemClick(Sender: TObject);\n    procedure UnlinkNodeItemClick(Sender: TObject);\n    procedure LinkNodes(node1, node2: TTreeNode);\n    procedure ChainNodesItemClick(Sender: TObject);\n    function DumpElement(node: TTreeNode): ISuperObject;\n    procedure DumpTree;\n    procedure DeleteNodes(var aList: TList);\n    procedure DeleteChildren(node: TTreeNode);\n    function CanPruneRecords: boolean;\n    procedure AutoPrune;\n    procedure AutoPruneItemClick(Sender: TObject);\n    procedure Autoset(parentNode: TTreeNode);\n    procedure AutosetItemClick(Sender: TObject);\n    // SETTINGS MANAGER EVENTS\n    function GetGroup(name: string; var group: TListGroup): Boolean;\n    procedure AddSettingItem(aSetting: TSmashSetting; bSelect: Boolean = true);\n    procedure FormCreate(Sender: TObject);\n    procedure FormShow(Sender: TObject);\n    procedure SelectSetting(index: Integer);\n    procedure lvSettingsChange(Sender: TObject; Item: TListItem;\n      Change: TItemChange);\n    procedure lvSettingsDrawItem(Sender: TCustomListView; Item: TListItem;\n      Rect: TRect; State: TOwnerDrawState);\n    procedure SplitterMoved(Sender: TObject);\n    procedure NewSettingItemClick(Sender: TObject);\n    procedure DeleteSettingItemClick(Sender: TObject);\n    procedure CloneSettingItemClick(Sender: TObject);\n    procedure CombineSettingsItemClick(Sender: TObject);\n    procedure SettingsPopupMenuPopup(Sender: TObject);\n    procedure btnSaveClick(Sender: TObject);\n    procedure btnDiscardClick(Sender: TObject);\n    procedure edNameChange(Sender: TObject);\n    procedure edSearchClick(Sender: TObject);\n    procedure edSearchKeyPress(Sender: TObject; var Key: Char);\n    procedure NextSearchResult();\n    procedure ResetSearch();\n    procedure FormDestroy(Sender: TObject);\n    procedure lvSettingsClick(Sender: TObject);\n    procedure FormKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);\n  private\n    { Private declarations }\n    lastHint: string;\n    bSearchActive: Boolean;\n    slSearchResults: TStringList;\n  public\n    { Public declarations }\n    FilterFilename: string;\n  end;\n\nconst\n  collapseHitTestDelay = 0.1 * seconds;\n\nvar\n  SettingsManager: TSettingsManager;\n  NewSettings: TList;\n  currentSetting: TSmashSetting;\n  currentSettingItem: TListItem;\n  pForm: TProgressForm;\n  LastCollapseTime: TDateTime;\n  SearchIndex: Integer = -1;\n\nimplementation\n\n{$R *.dfm}\n\nprocedure TSettingsManager.edSearchClick(Sender: TObject);\nbegin\n  // On search field click set bSearchActive to false\n  if (bSearchActive) and (MessageDlg('Start new search?', mtConfirmation, [mbyes, mbno], 0) = mrYes) then\n    bSearchActive := False;\n  // Empties the search field when clicked and a search is active\n  if not bSearchActive then\n    edSearch.Text := '';\nend;\n\nprocedure TSettingsManager.edSearchKeyPress(Sender: TObject; var Key: Char);\nvar\n  i: Integer;\n  node: TTreeNode;\nbegin\n  // Exit if no records are available\n  if tvRecords.Items.Count = 0 then\n    exit;\n  // Exit function if input is not \"Enter\"\n  if Key <> #13 then\n    exit;\n  // Tell the user to enter search term\n  if (edSearch.Text = 'Search...') or (edSearch.Text = '') then begin\n    ShowMessage('Please enter a search term!');\n    exit;\n  end;\n  // Do a search when bSearchActive is false\n  if not bSearchActive then begin\n    // Clear old results\n    slSearchResults.Clear;\n    for i := 0 to Pred(tvRecords.Items.Count) do begin\n      node := tvRecords.Items[i];\n      // Check if search-string is contained in node-text\n      if ContainsText(node.Text, edSearch.Text) then\n        slSearchResults.AddObject(node.Text,TObject(node));\n    end;\n    bSearchActive := True;\n    // Show result\n    NextSearchResult;\n    Key := #0;\n  end;\nend;\n\nprocedure TSettingsManager.NextSearchResult();\nvar\n  node: TTreeNode;\nbegin\n  // Notify the user of an unsuccessful search and reset search\n  if slSearchResults.Count = 0 then begin\n    ShowMessage('No results could be found!');\n    ResetSearch;\n    exit;\n  end;\n\n  // Exit the function if there is no search active\n  if not bSearchActive then\n    exit;\n\n  // Increase the SearchIndex\n  Searchindex := Searchindex + 1;\n  // Display the amount of results and the current position in the search field\n  edSearch.Text := ('Result: ' + InttoStr(Searchindex+1) + ' / ' + InttoStr(slSearchResults.Count+1));\n  // Go back to the beginning if end is reached\n  if Searchindex > Pred(slSearchResults.Count) then begin\n    Searchindex := 0;\n  end;\n  // select the node and set focus\n  node := TTreeNode(slSearchResults.Objects[Searchindex]);\n  tvRecords.SetFocus;\n  node.Selected := true;\n  node.Focused := true;\nend;\n\nprocedure TSettingsManager.ResetSearch();\nbegin\n  bSearchActive := False;\n  edSearch.Text := 'Search...';\nend;\n\n{ Tree methods }\nprocedure TSettingsManager.DrawFlag(Canvas: TCanvas; var x, y: Integer; id: Integer);\nvar\n  icon: TIcon;\nbegin\n  icon := TIcon.Create;\n  FlagIcons.GetIcon(id, icon);\n  Canvas.Draw(x, y, icon);\n  Inc(x, 18);\n  icon.Free;\nend;\n\nprocedure TSettingsManager.tvRecordsCollapsing(Sender: TObject; Node: TTreeNode;\n  var AllowCollapse: Boolean);\nbegin\n  LastCollapseTime := Now;\nend;\n\nprocedure TSettingsManager.tvRecordsCustomDrawItem(Sender: TCustomTreeView;\n  Node: TTreeNode; State: TCustomDrawState; var DefaultDraw: Boolean);\nvar\n  e: TElementData;\n  R: TRect;\n  x, y: Integer;\nbegin\n  if Assigned(node.Data) then begin\n    e := TElementData(node.Data);\n    R := Node.DisplayRect(true);\n    x := R.Right + 6;\n    y := R.Top;\n\n    // this fixes a bug with drawing flags when expanding a node\n    if x < 20 then\n      exit;\n\n    // draw flags\n    if e.preserveDeletions then\n      DrawFlag(Sender.Canvas, x, y, 0);\n    if e.overrideDeletions then\n      DrawFlag(Sender.Canvas, x, y, 1);\n    if e.forceValue then\n      DrawFlag(Sender.Canvas, x, y, 2);\n    if e.singleEntity then\n      DrawFlag(Sender.Canvas, x, y, 3);\n    if (e.linkTo <> '') or (e.linkFrom <> '') then\n      DrawFlag(Sender.Canvas, x, y, 4);\n  end;\nend;\n\nprocedure TSettingsManager.tvRecordsKeyDown(Sender: TObject; var Key: Word;\n  Shift: TShiftState);\nvar\n  i: Integer;\nbegin\n  if (Key = VK_SPACE) then begin\n    for i := 0 to Pred(tvRecords.SelectionCount) do\n      CheckboxManager(tvRecords.Selections[i]);\n    // repaint tree view in case a single entity flag was unset\n    tvRecords.Repaint;\n  end;\nend;\n\nprocedure TSettingsManager.tvRecordsKeyPress(Sender: TObject; var Key: Char);\nbegin\n  if Key = #13 then\n    NextSearchResult;\n    Key := #0;\n\n  if Key = ' ' then\n    Key := #0;\nend;\n\nprocedure TSettingsManager.tvRecordsMouseDown(Sender: TObject; Button: TMouseButton;\n  Shift: TShiftState; X, Y: Integer);\nvar\n  HT: THitTests;\n  node: TTreeNode;\nbegin\n  // this allows right clicking to be used to select nodes\n  if Button = mbRight then begin\n    node := tvRecords.GetNodeAt(X, Y);\n    if Assigned(node) and not node.Selected then begin\n      tvRecords.ClearSelection(false);\n      tvRecords.Select(node);\n    end;\n  end;\n\n  // this prevents a bug that happens when collapsing a node\n  // would cause the control to scroll up, putting the user's mouse\n  // above a checkbox\n  // the tree view collapse is triggered prior to this mouse down\n  // event, so the hacky solutin I came up with is to use a delay\n  // to exit this event if we collapsed a node within the last 0.1\n  // seconds\n  if Now - LastCollapseTime < collapseHitTestDelay then\n    exit;\n  HT := tvRecords.GetHitTestInfoAt(X, Y);\n  if (HT - [htOnStateIcon] <> HT) then\n    CheckBoxManager(tvRecords.Selected);\n  // repaint tree view in case a single entity flag was unset\n  tvRecords.Repaint;\nend;\n\nprocedure TSettingsManager.tvRecordsMouseMove(Sender: TObject;\n  Shift: TShiftState; X, Y: Integer);\nvar\n  node: TTreeNode;\n  e: TElementData;\n  sHint: string;\nbegin\n  // hide hint and exit if shift is down\n  if (ssShift in Shift) then begin\n    Application.HideHint;\n    exit;\n  end;\n\n  // draw hint if on a node\n  node := tvRecords.GetNodeAt(X, Y);\n  if not Assigned(node) then\n    exit;\n  e := TElementData(node.Data);\n  if not Assigned(e) then\n    exit;\n\n  // get hint\n  sHint := node.Text + #13#10'Type: '+stToString(e.smashType);\n  if e.singleEntity then\n    sHint := sHint + #13#10'Treated as a single entity';\n  if e.forceValue then\n    sHint := sHint + #13#10'Forcing values';\n  if e.preserveDeletions then\n    sHint := sHint + #13#10'Preserving deletions';\n  if e.linkTo <> '' then\n    sHint := sHint + #13#10'Linked to: '+e.linkTo;\n  if e.linkFrom <> '' then\n    sHint := sHint + #13#10'Linked from: '+e.linkFrom;\n\n  // display hint if it isn't the last hint we displayed\n  if sHint <> lastHint then begin\n    tvRecords.Hint := sHint;\n    Application.ActivateHint(Mouse.CursorPos);\n    lastHint := sHint;\n  end;\nend;\n\nfunction GetSiblingNode(node: TTreeNode; text: string): TTreeNode;\nvar\n  aNode: TTreeNode;\nbegin\n  Result := nil;\n  aNode := node.Parent.getFirstChild;\n  while Assigned(aNode) do begin\n    if aNode.Text = text then begin\n      Result := aNode;\n      exit;\n    end;\n    aNode := aNode.getNextSibling;\n  end;\nend;\n\nprocedure UnlinkNode(node: TTreeNode; bTo, bFrom: boolean);\nvar\n  linkedNode: TTreeNode;\n  e, le: TElementData;\nbegin\n  e := TElementData(node.Data);\n  if bTo and (e.linkTo <> '') then begin\n    linkedNode := GetSiblingNode(node, e.linkTo);\n    if Assigned(linkedNode) then begin\n      le := TElementData(linkedNode.Data);\n      le.linkFrom := '';\n    end;\n    e.linkTo := '';\n  end;\n  if bFrom and (e.linkFrom <> '') then begin\n    linkedNode := GetSiblingNode(node, e.linkFrom);\n    if Assigned(linkedNode) then begin\n      le := TElementData(linkedNode.Data);\n      le.linkTo := '';\n    end;\n    e.linkFrom := '';\n  end;\nend;\n\nprocedure TSettingsManager.UnlinkNodeItemClick(Sender: TObject);\nvar\n  i: Integer;\n  node: TTreeNode;\nbegin\n  // unset link element data attribute for each selected node\n  for i := 0 to Pred(tvRecords.SelectionCount) do begin\n    node := tvRecords.Selections[i];\n    UnlinkNode(node, true, true);\n  end;\n\n  // update gui\n  tvRecords.Repaint;\nend;\n\nprocedure TSettingsManager.LinkNodes(node1, node2: TTreeNode);\nvar\n  e: TElementData;\nbegin\n  // exit if nodes have different level\n  if node1.Level <> node2.Level then\n    exit;\n\n  // unlink nodes as necessary\n  UnlinkNode(node1, true, false);\n  UnlinkNode(node2, false, true);\n\n  // link nodes\n  e := TElementData(node1.Data);\n  e.linkTo := node2.Text;\n  e := TElementData(node2.Data);\n  e.linkFrom := node1.Text;\nend;\n\nprocedure TSettingsManager.ChainNodesItemClick(Sender: TObject);\nvar\n  i: Integer;\n  prevNode, node: TTreeNode;\nbegin\n  node := tvRecords.Selections[0];\n  for i := 1 to Pred(tvRecords.SelectionCount) do begin\n    prevNode := node;\n    node := tvRecords.Selections[i];\n    LinkNodes(prevNode, node);\n  end;\n  // link last node to first node\n  prevNode := node;\n  node := tvRecords.Selections[0];\n  LinkNodes(prevNode, node);\n\n  // repaint\n  tvRecords.Repaint;\nend;\n\nprocedure TSettingsManager.LinkNodeItemClick(Sender: TObject);\nvar\n  item: TMenuItem;\n  targetNodeText: string;\n  node, targetNode: TTreeNode;\nbegin\n  // get the target node to link to from the menu item clicked\n  node := tvRecords.Selections[0];\n  item := TMenuItem(Sender);\n  targetNodeText := StringReplace(item.Caption, '&', '', [rfReplaceAll]);\n  targetNode := GetSiblingNode(node, targetNodeText);\n  if not Assigned(targetNode) then\n    exit;\n\n  // link the nodes\n  LinkNodes(node, targetNode);\n\n  // update gui\n  tvRecords.Repaint;\nend;\n\nprocedure TSettingsManager.TreePopupMenuPopup(Sender: TObject);\nvar\n  bHasSelection, bTreeSelected, bHasMultiSelection, bSubrecordSelected,\n  bHasChildren, bRecordsSelected, bSomeUnChecked, bIsContainer: boolean;\n  i: Integer;\n  node: TTreeNode;\n  MenuItem: TMenuItem;\nbegin\n  // clear link node submenu\n  LinkNodeToItem.Clear;\n\n  // get selection booleans\n  bHasSelection := tvRecords.SelectionCount > 0;\n  bTreeSelected := (tvRecords.SelectionCount = 1)\n    and (tvRecords.Selections[0].Level = 0);\n  bHasMultiSelection := tvRecords.SelectionCount > 1;\n  bSubrecordSelected := (tvRecords.SelectionCount = 1)\n    and (tvRecords.Selections[0].Level > 1);\n\n  // get multiselection booleans\n  bHasChildren := false;\n  bRecordsSelected := true;\n  bSomeUnChecked := false;\n  for i := 0 to Pred(tvRecords.SelectionCount) do begin\n    bHasChildren := bHasChildren or tvRecords.Selections[i].HasChildren;\n    bRecordsSelected := bRecordsSelected and (tvRecords.Selections[i].Level = 1);\n    bSomeUnChecked := bSomeUnChecked or (tvRecords.Selections[i].StateIndex = csUnChecked);\n  end;\n\n  // enable/disable menu items\n  bIsContainer := bHasSelection and bHasChildren and not bTreeSelected;\n  AddItem.Visible := bTreeSelected;\n  ToggleNodesItem.Enabled := bHasSelection;\n  PreserveDeletionsItem.Enabled := bIsContainer;\n  OverrideDeletionsItem.Enabled := bIsContainer;\n  SingleEntityItem.Enabled := bIsContainer and not bRecordsSelected;\n  ForceValueItem.Enabled := bHasSelection and bRecordsSelected;\n  AutoPruneItem.Enabled := CanPruneRecords;\n  PruneNodesItem.Enabled := bHasSelection and bRecordsSelected and bSomeUnChecked;\n  UnlinkNodeItem.Enabled := bHasSelection and not bTreeSelected;\n  ChainNodesItem.Enabled := bHasMultiSelection and not bTreeSelected;\n  LinkNodeToItem.Enabled := bSubrecordSelected and not bTreeSelected;\n\n  // build LinkNodeToItem submenu\n  if bSubrecordSelected then begin\n    node := tvRecords.Selected.Parent.getFirstChild;\n    while Assigned(node) do begin\n      if node = tvRecords.Selections[0] then begin\n        node := node.getNextSibling;\n        continue;\n      end;\n      MenuItem := TMenuItem.Create(LinkNodeToItem);\n      MenuItem.Caption := node.Text;\n      MenuItem.OnClick := LinkNodeItemClick;\n      LinkNodeToItem.Add(MenuItem);\n      node := node.getNextSibling;\n    end;\n  end;\nend;\n\nprocedure TSettingsManager.AddItemClick(Sender: TObject);\nvar\n  item: TMenuItem;\n  groupName: string;\n  recObj: ISuperObject;\nbegin\n  item := (Sender as TMenuItem);\n  groupName := StringReplace(item.Caption, '&', '', [rfReplaceAll]);\n  recObj := GetRecordObj(currentSetting.tree, groupName);\n\n  // build record def if it isn't already present\n  if not Assigned(recObj) then begin\n    if not BuildRecordDef(groupName, recObj) then\n      exit;\n    currentSetting.tree.A['records'].Add(recObj);\n    LoadElement(tvRecords, tvRecords.Items[0], recObj, false);\n  end;\n\n  // update gui\n  tvRecords.Repaint;\nend;\n\nprocedure TSettingsManager.AddAllRecordsItemClick(Sender: TObject);\nbegin\n  AddAllRecords(currentSetting, tvRecords);\n  tvRecords.Repaint;\nend;\n\nprocedure TSettingsManager.BuildFromPluginsItemClick(Sender: TObject);\nvar\n  slPlugins, slSelection: TStringList;\n  i, mr: Integer;\n  plugin: TPlugin;\n  selectionForm: TMiniPluginSelectionForm;\nbegin\n  // build list of plugin filenames\n  slPlugins := TStringList.Create;\n  slSelection := TStringList.Create;\n  for i := 0 to Pred(PluginsList.Count) do begin\n    plugin := TPlugin(PluginsList[i]);\n    slPlugins.Add(plugin.filename);\n  end;\n\n  // prompt user for plugin selectcion\n  selectionForm := TMiniPluginSelectionForm.Create(self);\n  selectionForm.pluginsList := slPlugins;\n  selectionForm.selectionList := slSelection;\n  mr := selectionForm.ShowModal;\n  if mr = mrOK then\n    BuildTreeFromPlugins(tvRecords, slSelection, currentSetting.tree);\n\n  // free memory\n  selectionForm.Free;\n  slPlugins.Free;\n  slSelection.Free;\nend;\n\nprocedure TSettingsManager.SelectSimilarNodesItemClick(Sender: TObject);\nvar\n  i, index: Integer;\n  node: TTreeNode;\n  reqSmashType, currentSmashType: TSmashtype;\n  slSelection: TStringList;\nbegin\n  // Create StringList\n  slSelection := TStringList.Create;\n  try\n    // Add \"Text\" and \"SmashType\" of selected nodes to StringList\n    // Note: \"SmashType\" has to be converted to be used in a StringList\n    for i := 0 to Pred(tvRecords.SelectionCount) do begin\n      node := tvRecords.Selections[i];\n      reqSmashType := TElementData(node.Data).smashType;\n      // \"SmashType\" converted into TObject\n      slSelection.AddObject(node.Text, TObject(reqSmashType));\n    end;\n    // Go through all nodes and check if their \"Text\" is in StringList\n    for i := 0 to Pred(tvRecords.Items.Count) do begin\n      node := tvRecords.Items[i];\n      currentSmashType := TElementData(node.Data).smashType;\n      index := slSelection.IndexOf(node.Text);\n      // If a \"Text\" is found, get associated \"SmashType\" from StringList\n      if (index > -1) then begin\n        // Convert \"SmashType\" back to TSmashType\n        reqSmashType := TSmashType(slSelection.Objects[index]);\n          // Check if node's and saved \"SmashType\" match and if node is selected\n          if (currentSmashType = reqSmashType) and not node.Selected then\n            tvRecords.Select(node, [ssCtrl]);\n      end;\n    end;\n  finally\n    // Finally free the StringList\n    slSelection.Free;\n  end;\nend;\n\nprocedure TSettingsManager.ToggleNodesItemClick(Sender: TObject);\nvar\n  i: Integer;\nbegin\n  for i := 0 to Pred(tvRecords.SelectionCount) do\n    CheckboxManager(tvRecords.Selections[i]);\nend;\n\nprocedure TSettingsManager.PreserveDeletionsItemClick(Sender: TObject);\nvar\n  i: Integer;\n  node: TTreeNode;\n  e: TElementData;\nbegin\n  for i := 0 to Pred(tvRecords.SelectionCount) do begin\n    node := tvRecords.Selections[i];\n    if not node.hasChildren then\n      continue;\n    e := TElementData(node.Data);\n    e.preserveDeletions := not e.preserveDeletions;\n  end;\n  tvRecords.Repaint;\nend;\n\nprocedure TSettingsManager.OverrideDeletionsItemClick(Sender: TObject);\nvar\n  i: Integer;\n  node: TTreeNode;\n  e: TElementData;\nbegin\n  for i := 0 to Pred(tvRecords.SelectionCount) do begin\n    node := tvRecords.Selections[i];\n    if not node.hasChildren then\n      continue;\n    e := TElementData(node.Data);\n    e.overrideDeletions := not e.overrideDeletions;\n  end;\n  tvRecords.Repaint;\nend;\n\nprocedure TSettingsManager.SingleEntityItemClick(Sender: TObject);\nvar\n  i, expectedLevel: Integer;\n  node: TTreeNode;\n  e: TElementData;\nbegin\n  expectedLevel := 0;\n  for i := 0 to Pred(tvRecords.SelectionCount) do begin\n    node := tvRecords.Selections[i];\n    if expectedLevel = 0 then\n      expectedLevel := node.Level;\n    if not node.hasChildren then\n      continue;\n    if expectedLevel <> node.Level then\n      continue;\n    e := TElementData(node.Data);\n    e.singleEntity := not e.singleEntity;\n    if e.singleEntity then\n      node.StateIndex := csPartiallyChecked\n    else begin\n      SetChildren(node, csChecked);\n      node.StateIndex := csChecked;\n    end;\n    UpdateParent(node.Parent);\n  end;\n  tvRecords.Repaint;\nend;\n\nprocedure TSettingsManager.ForceValueItemClick(Sender: TObject);\nvar\n  i: Integer;\n  node: TTreeNode;\n  e: TElementData;\nbegin\n  for i := 0 to Pred(tvRecords.SelectionCount) do begin\n    node := tvRecords.Selections[i];\n    e := TElementData(node.Data);\n    e.forceValue := not e.forceValue;\n  end;\n  tvRecords.Repaint;\nend;\n\nprocedure TSettingsManager.AutoPruneItemClick(Sender: TObject);\nbegin\n  AutoPrune;\nend;\n\nprocedure TSettingsManager.Autoset(parentNode: TTreeNode);\nconst\n  disabledElements: array[0..2] of string = (\n    'Record Header',\n    'Unused',\n    'Unknown'\n  );\n  disabledRecords: array[0..5] of string = (\n    'DOBJ',\n    'LCTN',\n    'IDLE',\n    'NAVM',\n    'NAVI',\n    'RACE'\n  );\nvar\n  i: Integer;\n  node, nextNode: TTreeNode;\n  e: TElementData;\n  bParentIsRoot, bParentIsRecord: boolean;\nbegin\n  // get parent booleans\n  bParentIsRoot := parentNode.Level = 0;\n  bParentIsRecord := parentNode.Level = 1;\n\n  // loop through children\n  node := parentNode.getFirstChild;\n  while Assigned(node) do begin\n    node.StateIndex := csChecked;\n    e := TElementData(node.Data);\n\n    if Assigned(e) then begin\n      // if parent is root, preserve deletions\n      if bParentIsRoot then\n        e.preserveDeletions := true;\n\n      // if parent is record, perform case statement on type\n      if bParentIsRecord then begin\n        case Ord(e.smashType) of\n          Ord(stStruct): begin\n            e.singleEntity := true;\n            node.StateIndex := csPartiallyChecked;\n          end;\n          Ord(stUnsortedStructArray): begin\n            e.singleEntity := true;\n            e.preserveDeletions := true;\n            node.StateIndex := csPartiallyChecked;\n          end;\n          Ord(stSortedArray),\n          Ord(stSortedStructArray):\n            e.preserveDeletions := true;\n          Ord(stByteArray):\n            node.StateIndex := csUnChecked;\n        end;\n      end;\n    end;\n\n    // if we're not on the root, disable elements that match\n    // a string in the disableElements array\n    if not bParentIsRoot then begin\n      for i := Low(disabledElements) to High(disabledElements) do\n        if Pos(disabledElements[i], node.Text) > 0 then begin\n          node.StateIndex := csUnChecked;\n          e.singleEntity := false;\n          e.preserveDeletions := false;\n        end;\n    end\n    // else disable records that match a string in the\n    // disabledRecords array\n    else begin\n      for i := Low(disabledRecords) to High(disabledRecords) do\n        if Pos(disabledRecords[i], node.Text) = 1 then begin\n          node.StateIndex := csUnChecked;\n          e.singleEntity := false;\n          e.preserveDeletions := false;\n        end;\n    end;\n\n    // disable count elements\n    if bParentIsRecord then begin\n      nextNode := node.getNextSibling;\n      if Assigned(nextNode)\n      and (TElementData(nextNode.Data).smashType in stArrays)\n      and (Pos('Count', node.Text) > 0) then\n        node.StateIndex := csUnChecked;\n    end;\n\n    // recurse\n    if (node.HasChildren) and (node.StateIndex <> csUnChecked) then\n      Autoset(node);\n\n    // go to next sibling\n    node := node.getNextSibling;\n  end;\n\n  // update parent node\n  UpdateParent(parentNode);\n\n  // repaint\n  tvRecords.Repaint;\nend;\n\nprocedure TSettingsManager.AutosetItemClick(Sender: TObject);\nconst\n  msg = 'This will change all nodes in this setting, are you sure you want to continue?';\nvar\n  mr: Integer;\nbegin\n  // confirm with the user that this is what they\n  // really want to do\n  mr := MessageDlg(msg, mtConfirmation, [mbYes, mbNo], 0);\n  if mr = mrYes then begin\n    Enabled := false;\n    Autoset(tvRecords.Items[0]);\n    Enabled := true;\n  end;\nend;\n\nprocedure TSettingsManager.PruneNodesItemClick(Sender: TObject);\nvar\n  i: Integer;\n  node: TTreeNode;\n  nodesToPrune: TList;\nbegin\n  nodesToPrune := TList.Create;\n  for i := 0 to Pred(tvRecords.SelectionCount) do begin\n    node := tvRecords.Selections[i];\n    if (node.Level = 1) and (node.StateIndex = csUnChecked) then\n      nodesToPrune.Add(node);\n  end;\n  DeleteNodes(nodesToPrune);\n  nodesToPrune.Free;\n  UpdateParent(tvRecords.Items[0].getFirstChild);\nend;\n\nfunction TSettingsManager.DumpElement(node: TTreeNode): ISuperObject;\nvar\n  obj: ISuperObject;\n  child: TTreeNode;\n  e: TElementData;\n  i: Integer;\nbegin\n  obj := SO;\n  // get name\n  obj.S['n'] := node.Text;\n  // get data properties\n  e := TElementData(node.Data);\n  if (e.priority > 0) then\n    obj.I['r'] := e.priority;\n  if (node.StateIndex <> csUnChecked) then\n    obj.I['p'] := 1;\n  if (e.preserveDeletions) then\n    obj.I['d'] := 1;\n  if (e.overrideDeletions) then\n    obj.I['o'] := 1;\n  if (e.singleEntity) then\n    obj.I['s'] := 1;\n  if (e.forceValue) then\n    obj.I['f'] := 1;\n  if (e.smashType <> stUnknown) then\n    obj.I['t'] := Ord(e.smashType);\n  if (e.linkTo <> '') then\n    obj.S['lt'] := e.linkTo;\n  if (e.linkFrom <> '') then\n    obj.S['lf'] := e.linkFrom;\n\n  // exit if no children to dump\n  if node.hasChildren then begin\n    // dump subrecords (children)\n    obj.O['c'] := SA([]);\n    child := node.getFirstChild;\n    i := 0;\n    while Assigned(child) do begin\n      obj.A['c'].O[i] := DumpElement(child);\n      child := child.getNextSibling;\n      Inc(i);\n    end;\n  end;\n\n  Result := obj;\nend;\n\nprocedure TSettingsManager.DumpTree;\nvar\n  i: Integer;\n  obj: ISuperObject;\n  node, rootNode: TTreeNode;\nbegin\n  obj := SO;\n  obj.O['records'] := SA([]);\n  rootNode := tvRecords.Items[0];\n\n  // loop through records\n  node := rootNode.getFirstChild;\n  i := 0;\n  while Assigned(node) do begin\n    obj.A['records'].O[i] := DumpElement(node);\n    Inc(i);\n    node := node.getNextSibling;\n  end;\n\n  currentSetting.tree := obj;\n  currentSetting.UpdateRecords;\nend;\n\nprocedure TSettingsManager.edNameChange(Sender: TObject);\nbegin\n  if Assigned(currentSetting) then\n    btnSave.Enabled := (currentSetting.name = edName.Text) or\n      not Assigned(TSettingHelpers.SettingByName(edName.Text));\nend;\n\nprocedure TSettingsManager.DeleteNodes(var aList: TList);\nvar\n  i: Integer;\n  node: TTreeNode;\nbegin\n  // delete nodes in reverse order\n   for i := Pred(aList.Count) downto 0 do begin\n    node := TTreeNode(aList[i]);\n    if node.HasChildren then\n      DeleteChildren(node);\n    tvRecords.Items.Delete(node);\n  end;\nend;\n\nprocedure TSettingsManager.DeleteChildren(node: TTreeNode);\nvar\n  nodesToDelete: TList;\n  child: TTreeNode;\nbegin\n  nodesToDelete := TList.Create;\n  child := node.getFirstChild;\n  // get nodes to prune\n  while Assigned(child) do begin\n    nodesToDelete.Add(child);\n    child := child.getNextSibling;\n  end;\n  // delete nodes\n  DeleteNodes(nodesToDelete);\n  nodesToDelete.Free;\nend;\n\nprocedure TSettingsManager.AutoPrune;\nvar\n  mr: Integer;\n  nodesToPrune: TList;\n  node: TTreeNode;\nbegin\n  mr := MessageDlg('Your setting tree has records that can be pruned.  '+\n    'Would you like to prune them?', mtConfirmation, [mbYes, mbNo], 0);\n  if mr = mrYes then begin\n    nodesToPrune := TList.Create;\n    node := tvRecords.Items[0].getFirstChild;\n    // get nodes to prune\n    while Assigned(node) do begin\n      if node.StateIndex = csUnChecked then\n        nodesToPrune.Add(node);\n      node := node.getNextSibling;\n    end;\n    // prune nodes\n    DeleteNodes(nodesToPrune);\n    nodesToPrune.Free;\n  end;\nend;\n\nfunction TSettingsManager.CanPruneRecords: boolean;\nvar\n  node: TTreeNode;\nbegin\n  Result := false;\n  node := tvRecords.Items[0].getFirstChild;\n  while Assigned(node) do begin\n    if node.StateIndex = csUnChecked then begin\n      Result := true;\n      break;\n    end;\n    node := node.getNextSibling;\n  end;\nend;\n\n\n{******************************************************************************}\n{ Settings Manager Events }\n{******************************************************************************}\n\nfunction TSettingsManager.GetGroup(name: string; var group: TListGroup): Boolean;\nvar\n  i: Integer;\nbegin\n  Result := false;\n\n  // get the group\n  for i := 0 to Pred(lvSettings.Groups.Count) do begin\n    group := lvSettings.Groups[i];\n    if SameText(group.Header, name) then begin\n      Result := true;\n      break;\n    end;\n  end;\nend;\n\nprocedure TSettingsManager.AddSettingItem(aSetting: TSmashSetting;\n  bSelect: Boolean = true);\nvar\n  index: Integer;\n  item: TListItem;\n  sGroupName: string;\n  group: TListGroup;\nbegin\n  // add item to list view\n  item := lvSettings.Items.Add;\n  item.Caption := aSetting.name;\n  item.SubItems.Add(aSetting.records);\n\n  // get group\n  sGroupName := 'Ungrouped';\n  index := Pos('.', aSetting.name);\n  if index > 0 then\n    sGroupName := Copy(aSetting.name, 1, index - 1);\n  if not GetGroup(sGroupName, group) then begin\n    group := lvSettings.Groups.Add;\n    group.Header := sGroupName;\n    group.State := [lgsCollapsible];\n  end;\n\n  // assign group\n  item.GroupID := group.ID;\n\n  // set selected item to the new setting\n  if bSelect then\n    SelectSetting(item.Index);\nend;\n\nprocedure TSettingsManager.FormCreate(Sender: TObject);\nvar\n  i: Integer;\n  aSetting: TSmashSetting;\nbegin\n  // do a translation dump?\n  if bTranslationDump then\n    TRttiTranslation.Save('lang\\english.lang', self);\n\n  // load translation\n  TRttiTranslation.Load(language, self);\n\n  // initialize list view, SmashSettings list\n  NewSettings := TList.Create;\n  lvSettings.OwnerDraw := not settings.simpleDictionaryView;\n  lvSettings.Items.Count := SmashSettings.Count;\n\n  // prepare groups and load items\n  for i := 0 to Pred(SmashSettings.Count) do begin\n    aSetting := TSmashSetting(SmashSettings[i]);\n    AddSettingItem(aSetting, false);\n  end;\n\n  // Create the StringList for the Search\n  slSearchResults := TStringList.Create;\nend;\n\nprocedure TSettingsManager.FormDestroy(Sender: TObject);\nbegin\n  // Free the Search StringList\n  slSearchResults.Free;\nend;\n\nprocedure TSettingsManager.FormKeyDown(Sender: TObject; var Key: Word;\n  Shift: TShiftState);\nbegin\n  if (Key = 70) and (Shift = [ssCtrl]) then\n    edSearch.SetFocus;\nend;\n\nprocedure TSettingsManager.FormShow(Sender: TObject);\nconst\n  TVS_NOTOOLTIPS = $0080;\nbegin\n  // disable tool tips on tree view\n  SetWindowLong(tvRecords.Handle, GWL_STYLE,\n    GetWindowLong(tvRecords.Handle, GWL_STYLE) or TVS_NOTOOLTIPS);\n\n  // build AddItem submenu\n  PopulateAddList(AddItem, AddItemClick);\n\n  // force lvSettings to autosize columns\n  lvSettings.Width := lvSettings.Width - 1;\n  lvSettings.Width := lvSettings.Width + 1;\nend;\n\n// selects the setting specified by @index\nprocedure TSettingsManager.SelectSetting(index: Integer);\nbegin\n  lvSettings.ClearSelection;\n  lvSettings.Selected := lvSettings.Items[index];\n  lvSettingsChange(nil, nil, TItemChange(nil));\nend;\n\n// update setting data whenever user changes their selection\nprocedure TSettingsManager.lvSettingsChange(Sender: TObject; Item: TListItem;\n  Change: TItemChange);\nbegin\n  tvRecords.Items.Clear;\n  if (lvSettings.ItemIndex = -1) then begin\n    currentSetting := nil;\n    edName.Text := '';\n    edName.Enabled := false;\n    cbColor.Selected := clBlack;\n    cbColor.Enabled := false;\n    edHash.Text := '$00000000';\n    meDescription.Text := '';\n    meDescription.Enabled := false;\n    tvRecords.Enabled := false;\n    btnSave.Enabled := false;\n    btnDiscard.Enabled := false;\n    exit;\n  end;\n\n  // set current setting values\n  edName.Enabled := true;\n  cbColor.Enabled := true;\n  meDescription.Enabled := true;\n  tvRecords.Enabled := true;\n  btnSave.Enabled := true;\n  btnDiscard.Enabled := true;\n  currentSetting := TSmashSetting(SmashSettings[lvSettings.ItemIndex]);\n  currentSettingItem := lvSettings.Items[lvSettings.ItemIndex];\n  edName.Text := currentSetting.name;\n  edHash.Text := '$' + currentSetting.hash;\n  cbColor.Selected := TColor(currentSetting.color);\n  meDescription.Lines.Text := currentSetting.description;\n\n  // load tree if assigned\n  if Assigned(currentSetting.tree) then\n    LoadTree(tvRecords, currentSetting);\nend;\n\nprocedure TSettingsManager.lvSettingsClick(Sender: TObject);\nbegin\n  if bSearchActive then\n    ResetSearch;\nend;\n\nprocedure TSettingsManager.btnDiscardClick(Sender: TObject);\nbegin\n  // reload the setting\n  lvSettingsChange(nil, nil, TItemChange(nil));\nend;\n\nprocedure TSettingsManager.btnSaveClick(Sender: TObject);\nvar\n  index: Integer;\n  group: TListGroup;\nbegin\n  // adjust the current setting's attributes\n  currentSetting.Rename(edName.Text);\n  currentSetting.color := cbColor.Selected;\n  currentSetting.description := meDescription.Lines.Text;\n\n  // prompt user to auto-prune the tree if it's a new setting and\n  // we can prune records,\n  // then dump the records tree\n  index := NewSettings.IndexOf(currentSetting);\n  if (index > -1) then begin\n    if CanPruneRecords then\n      AutoPrune;\n    NewSettings.Delete(index);\n  end;\n  DumpTree;\n\n  // save the setting to disk\n  currentSetting.Save;\n\n  // update edHash\n  edHash.Text := currentSetting.hash;\n\n  // adjust the current setting in the list view\n  GetGroup(currentSetting.name, group);\n  currentSettingItem.GroupID := group.ID;\n  currentSettingItem.Caption := currentSetting.name;\n  currentSettingItem.SubItems[0] := currentSetting.records;\n\n  // repaint list view\n  lvSettings.Repaint;\nend;\n\nprocedure TSettingsManager.lvSettingsDrawItem(Sender: TCustomListView;\n  Item: TListItem; Rect: TRect; State: TOwnerDrawState);\nvar\n  i, x, y: integer;\n  lv: TListView;\n  aSetting: TSmashSetting;\nbegin\n  lv := TListView(Sender);\n\n  // get color\n  aSetting := TSmashSetting(SmashSettings[Item.Index]);\n  lv.Canvas.Font.Color := aSetting.color;\n  lv.Canvas.Font.Style := [fsBold];\n  lv.Canvas.Refresh;\n\n  // draw selected rect\n  if Item.Selected then begin\n    lv.Canvas.Brush.Color := $FFEEDD;\n    lv.Canvas.FillRect(Rect);\n  end;\n\n  // draw item\n  x := Rect.Left;\n  y := (Rect.Bottom - Rect.Top - lv.Canvas.TextHeight('Hg')) div 2 + Rect.Top;\n  lv.Canvas.TextOut(x, y, ' '+Item.Caption);\n\n  // draw subitems\n  for i := 0 to Item.SubItems.Count - 1 do begin\n    Inc(x, ListView_GetColumnWidth(lv.Handle, lv.Columns[i].Index));\n    lv.Canvas.TextOut(x, y, ' '+Item.SubItems[i]);\n  end;\nend;\n\n{******************************************************************************}\n{ SettingPopupMenu methods\n  Methods for dealing with the popup menu for the settings list view.\n  - NewSettingItemClick\n  - EditSettingItemClick\n  - DeleteSettingItemClick\n}\n{******************************************************************************}\n\nprocedure TSettingsManager.SettingsPopupMenuPopup(Sender: TObject);\nvar\n  bHasSelection, bHasMultiSelection: boolean;\nbegin\n  bHasSelection := Assigned(lvSettings.Selected);\n  bHasMultiSelection := lvSettings.SelCount > 1;\n  DeleteSettingItem.Enabled := bHasSelection;\n  CloneSettingItem.Enabled := bHasSelection;\n  CombineSettingsItem.Enabled := bHasMultiSelection;\nend;\n\nprocedure TSettingsManager.NewSettingItemClick(Sender: TObject);\nvar\n  newSetting: TSmashSetting;\nbegin\n  // create new setting\n  newSetting := TSmashSetting.Create;\n  NewSettings.Add(newSetting);\n  SmashSettings.Add(newSetting);\n  AddSettingItem(newSetting);\nend;\n\nprocedure TSettingsManager.DeleteSettingItemClick(Sender: TObject);\nvar\n  i, index: Integer;\n  setting: TSmashSetting;\nbegin\n  for i := Pred(lvSettings.Items.Count) downto 0 do begin\n    if not lvSettings.Items[i].Selected then\n      continue;\n    lvSettings.Items.Delete(i);\n    setting := TSmashSetting(SmashSettings[i]);\n    RemoveSettingFromPlugins(setting);\n    SmashSettings.Delete(i);\n    index := NewSettings.IndexOf(setting);\n    if index > -1 then\n      NewSettings.Delete(index);\n    setting.Delete;\n    setting.Free;\n  end;\n  lvSettings.Repaint;\n  lvSettingsChange(nil, nil, TItemChange(nil));\nend;\n\nprocedure TSettingsManager.CloneSettingItemClick(Sender: TObject);\nvar\n  setting, clonedSetting: TSmashSetting;\nbegin\n  clonedSetting := TSmashSetting.Create;\n  setting := TSmashSetting(SmashSettings[lvSettings.Selected.Index]);\n  clonedSetting.Clone(setting);\n  SmashSettings.Add(clonedSetting);\n  // add setting to list view\n  AddSettingItem(clonedSetting);\nend;\n\nprocedure TSettingsManager.CombineSettingsItemClick(Sender: TObject);\nvar\n  i: Integer;\n  ListItem: TListItem;\n  settingsToCombine: TList;\n  setting: TSmashSetting;\n  sl, slRecords: TStringList;\n  cForm: TConflictForm;\nbegin\n  // create lists\n  settingsToCombine := TList.Create;\n  slRecords := TStringList.Create;\n  sl := TStringList.Create;\n  sl.StrictDelimiter := true;\n  sl.Delimiter := ',';\n\n  try\n    // add selected settings to the settingsToCombine list\n    for i := 0 to Pred(lvSettings.Items.Count) do begin\n      ListItem := lvSettings.Items[i];\n      if not ListItem.Selected then\n        continue;\n      setting := TSmashSetting(SmashSettings[i]);\n      settingsToCombine.Add(setting);\n      sl.Add(setting.name);\n    end;\n\n    // build a list of the record objects in the settings\n    // if conflicts found, have user resolve them\n    if CombineSettingTrees(settingsToCombine, slRecords) then begin\n      cForm := TConflictForm.Create(self);\n      cForm.slConflicts := slRecords;\n      if cForm.ShowModal = mrOK then\n        CreateCombinedSetting(slRecords, sl.DelimitedText);\n    end\n    // else just create the combined setting\n    else begin\n      CreateCombinedSetting(slRecords, sl.DelimitedText);\n    end;\n  finally\n    // update lvSettings if we created a new setting\n    if SmashSettings.Count > lvSettings.Items.Count then begin\n      setting := TSmashSetting(SmashSettings[Pred(SmashSettings.Count)]);\n      AddSettingItem(setting);\n    end;\n\n    // free memory\n    settingsToCombine.Free;\n    slRecords.Free;\n    sl.Free;\n  end;\nend;\n\n// repaint when splitter is moved\nprocedure TSettingsManager.SplitterMoved(Sender: TObject);\nbegin\n  Repaint;\nend;\n\nend.\n"
  },
  {
    "path": "frontend/msSmash.pas",
    "content": "unit msSmash;\n\ninterface\n\nuses\n  Windows, SysUtils, Classes, ShellAPI, Controls, Dialogs,\n  // superobject\n  superobject,\n  // mte units\n  mteHelpers, mteLogger, mteTracker, mteBase,\n  // ms units\n  msCore, msConfiguration, msConflict, msAlgorithm,\n  // xEdit units\n  wbInterface, wbImplementation;\n\n  procedure BuildPatch(var patch: TPatch);\n  procedure RebuildPatch(var patch: TPatch);\n\nimplementation\n\nprocedure BuildPluginsList(var patch: TPatch; var lst: TList);\nvar\n  i: Integer;\n  plugin: TPlugin;\nbegin\n  for i := 0 to Pred(patch.plugins.Count) do begin\n    plugin := PluginByFileName(patch.plugins[i]);\n    if not Assigned(plugin) then\n      raise Exception.Create('Couldn''t find plugin '+patch.plugins[i]);\n    lst.Add(plugin);\n  end;\nend;\n\nprocedure SetPatchAttributes(var patch: TPatch);\nvar\n  patchFile: IwbFile;\n  fileHeader: IwbContainer;\nbegin\n  patchFile := patch.plugin._File;\n  fileHeader := patchFile.Elements[0] as IwbContainer;\n  // set author\n  fileHeader.ElementEditValues['CNAM'] := 'Mator Smash v' + ProgramStatus.Version;\n  // set description\n  fileHeader.ElementEditValues['SNAM'] := 'Smashed patch:'#13#10 + patch.plugins.Text;\nend;\n\nfunction GetPatchFile(var patch: TPatch; var lst: TList): IwbFile;\nvar\n  plugin: TPlugin;\n  bUsedExistingFile: boolean;\n  patchFile: IwbFile;\n  i: Integer;\nbegin\n  // get plugin if it exists\n  // else create it\n  plugin := PluginByFilename(patch.filename);\n  patch.plugin := nil;\n  if Assigned(plugin) then begin\n    bUsedExistingFile := true;\n    patch.plugin := plugin;\n  end\n  else begin\n    bUsedExistingFile := false;\n    patch.plugin := CreateNewPlugin(patch.filename);\n  end;\n\n  // don't patch if patchFile not assigned\n  if not Assigned(patch.plugin) then \n    raise Exception.Create('Couldn''t assign patch file');\n\n  // don't patch if patchFile is at an invalid load order position relative\n  // to the plugins being patched\n  if bUsedExistingFile then begin\n    for i := 0 to Pred(lst.Count) do begin\n      plugin := TPlugin(lst[i]);\n      if PluginsList.IndexOf(plugin) > PluginsList.IndexOf(patch.plugin) then\n        raise Exception.Create(Format('%s is at a lower load order position than %s',\n          [plugin.filename, patch.filename]));\n    end;\n\n    // clean up the patch file\n    patchFile := patch.plugin._File;\n    for i := Pred(patchFile.RecordCount) downto 0 do\n      patchFile.Records[i].Remove;\n  end;\n\n  // set result\n  Result := patch.plugin._File;\n  Tracker.Write(' ');\n  Tracker.Write('Patch is using plugin: '+patch.plugin.filename);\nend;\n\nprocedure AddRequiredMasters(var patch: TPatch; var lst: TList);\nvar\n  slMasters: TStringList;\n  i: Integer;\n  plugin: TPlugin;\nbegin\n  slMasters := TStringList.Create;\n  try\n    Tracker.Write('Adding masters...');\n    for i := 0 to Pred(lst.Count) do begin\n      plugin := TPlugin(lst[i]);\n      GetMasters(plugin._File, slMasters);\n      slMasters.AddObject(plugin.filename, patch.plugins.Objects[i]);\n    end;\n    try\n      slMasters.CustomSort(LoadOrderCompare);\n      AddMasters(patch.plugin._File, slMasters);\n      if settings.debugMasters then begin\n        Tracker.Write('Masters added:');\n        Tracker.Write(slMasters.Text);\n        slMasters.Clear;\n        GetMasters(patch.plugin._File, slMasters);\n        Tracker.Write('Actual masters:');\n        Tracker.Write(slMasters.Text);\n      end;\n    except\n      on x: Exception do begin\n        Tracker.Write('Critical exception adding masters!');\n        Tracker.Write(x.Message);\n        raise x;\n      end;\n    end;\n  finally\n    slMasters.Free;\n    if Tracker.Cancel then\n      raise Exception.Create('User cancelled smashing.');\n    Tracker.Write('Done adding masters');\n  end;\nend;\n\nprocedure BuildOverridesList(var patch: TPatch; var lst: TList;\n  var records: TInterfaceList);\nvar\n  i, j, recCount: Integer;\n  plugin: TPlugin;\n  aSetting: TSmashSetting;\n  aFile: IwbFile;\n  rec: IwbMainRecord;\n  recObj: ISuperObject;\nbegin\n  Tracker.Write(' ');\n  Tracker.Write('Processing files');\n  for i := 0 to Pred(lst.Count) do begin\n    if Tracker.Cancel then break;\n    plugin := TPlugin(lst[i]);\n\n    // get file and setting for later use\n    aFile := plugin._File;\n    aSetting := plugin.smashSetting;\n\n    // loop through file records\n    Tracker.Write('Processing '+plugin.filename);\n    recCount := Pred(aFile.RecordCount);\n    for j := 0 to recCount do begin\n      if Tracker.Cancel then break;\n      rec := aFile.Records[j];\n      if j mod 500 = 499 then\n        Tracker.UpdateProgress(500);\n\n      try\n        // skip non-override records\n        if rec.IsMaster then\n          continue;\n        rec := rec.Master;\n\n        if OverrideCountInFiles(rec, patch.plugins) < 2 then\n          continue;\n\n        // skip records according to smash setting\n        recObj := aSetting.GetRecordDef(rec.Signature);\n        if not Assigned(recObj) then\n          continue;\n        if (recObj.I['p'] <> 1) then\n          continue;\n        // skip non-conflicting records\n        if ConflictAllForMainRecord(rec) < caConflict then\n          continue;\n\n        // add record to overrides list\n        if records.IndexOf(rec) = -1 then\n          records.Add(rec);\n      except\n        on x: Exception do begin\n          Tracker.Write('  Error processing ' + rec.Name + ', ' + x.Message);\n          continue;\n        end;\n      end;\n    end;\n    \n    // update progress bar for file\n    Tracker.UpdateProgress(recCount mod 500);\n  end;\nend;\n\nprocedure UpdateCounts(var rec: IwbMainRecord);\nvar\n  container, arrayContainer: IwbContainerElementRef;\n  i: Integer;\n  element, nextElement: IwbElement;\nbegin\n  // if reocrd is not editable, exit\n  if not rec.IsEditable then\n    exit;\n\n  // if record can't be treated as a container, exit\n  if not Supports(rec, IwbContainerElementRef, container) then\n    exit;\n\n  // loop through top-level elements\n  for i := 0 to container.ElementCount - 2 do begin\n    element := container.Elements[i];\n    nextElement := container.Elements[i + 1];\n    if not Supports(nextElement, IwbContainerElementRef, arrayContainer) then\n      continue;\n\n    // if next element is an array element and current element has the\n    // word count in its name update the count to be the number of elements\n    // in the array\n    if (GetSmashType(nextElement) in stArrays)\n    and (Pos('Count', element.Name) > 0) then try\n      element.NativeValue := arrayContainer.ElementCount;\n    except\n      on x: Exception do\n        Tracker.Write('    Exception updating count at '+element.Path);\n    end;\n  end;\nend;\n\nfunction HasPartialFormFlag(rec: IwbMainRecord): Boolean;\nbegin\n  Result := ((rec.Signature = 'QUST') or (rec.Signature = 'LCTN')) and\n    (rec.Flags._Flags and $00004000 <> 0);\nend;\n\nprocedure SmashRecords(var patch: TPatch; var records: TInterfaceList);\nvar\n  i, j: Integer;\n  incProgress, currentProgress: Real;\n  rec, mst, ovr, patchRec: IwbMainRecord;\n  f, patchFile, forceFile: IwbFile;\n  plugin: TPlugin;\n  aSetting: TSmashSetting;\n  recObj: ISuperObject;\n  e, eCopy: IwbElement;\n  bDeletions, bOverride, bForce: boolean;\nbegin\n  Tracker.Write(' ');\n  Tracker.Write('Smashing records');\n  patchFile := patch.plugin._File;\n\n  // loop through records to smash\n  currentProgress := Tracker.GetProgress;\n  incProgress := (Tracker.GetMaxProgress - Tracker.GetProgress) / records.Count;\n  for i := 0 to Pred(records.Count) do begin\n    if Tracker.Cancel then break;\n    if not Supports(records[i], IwbMainRecord, rec) then\n      exit;\n    Tracker.StatusMessage(Format('Smashing records (%d/%d)',\n      [i + 1, records.Count]));\n    currentProgress := currentProgress + incProgress;\n    Tracker.SetProgress(Round(currentProgress));\n\n    // loop through record's overrides\n    patchRec := nil;\n    forceFile := nil;\n    for j := 0 to Pred(rec.OverrideCount) do begin\n      if Tracker.Cancel then break;\n      ovr := rec.Overrides[j];\n      f := ovr._File;\n      // skip overrides that are in plugins we aren't patching\n      if patch.plugins.IndexOf(f.FileName) = -1 then\n        continue;\n      plugin := PluginByFileName(f.FileName);\n      if not Assigned(plugin) then\n        continue;\n      // skip ctIdenticalToMaster overrides\n      if (ConflictThisForMainRecord(ovr) = ctIdenticalToMaster) then\n        continue;\n\n      // skip plugins that have the skip setting\n      if plugin.setting = 'Skip' then\n        continue;\n\n      // skip overrides according to smash setting\n      aSetting := plugin.smashSetting;\n      recObj := aSetting.GetRecordDef(ovr.Signature);\n      if not Assigned(recObj) then\n        continue;\n      if (recObj.I['p'] <> 1) then\n        continue;\n      bForce := recObj.I['f'] = 1;\n      if bForce then begin\n        if Assigned(patchRec) then begin\n          patchRec.Remove;\n          patchRec := nil;\n        end;\n        forceFile := f;\n      end;\n\n      // copy record to smashed patch if it hasn't been copied yet\n      if not Assigned(patchRec) then try\n        if bForce then\n          e := ovr\n        else\n          e := WinningOverrideInFiles(rec, patch.plugins);\n        Tracker.Write(Format('  [%d] Copying record %s', [i + 1, e.Name]));\n        eCopy := wbCopyElementToFile(e, patchFile, false, true, '', '' ,'');\n        patchRec := eCopy as IwbMainRecord;\n        if bForce then continue;\n      except\n        on x: Exception do begin\n          Tracker.Write('      Exception copying record '+ovr.Name+' : '+x.Message);\n          patch.fails.Add('Exception copying record '+ovr.Name+' : '+x.Message);\n          continue;\n        end;\n      end;\n\n      // skip if we're forcing and plugin doesn't require forceFile\n      if Assigned(forceFile) and not bForce\n      and (plugin.masters.IndexOf(forceFile.FileName) = -1) then\n        continue;\n\n      // finally, recursively copy overridden elements\n      try\n        bDeletions := recObj.I['d'] = 1;\n        if (wbGameMode = gmFO4) and HasPartialFormFlag(ovr) then\n          bDeletions := False;\n        bOverride := recObj.I['o'] = 1;\n        if bForce then\n          mst := e as IwbMainRecord\n        else\n          mst := WinningOverrideInFiles(rec, plugin.masters);\n        Tracker.Write(Format('    Smashing override from: %s, master: %s',\n          [f.FileName, mst._File.FileName]));\n        rcore(IwbElement(ovr), IwbElement(mst), IwbElement(patchRec), patchRec,\n          recObj, false, bDeletions, bOverride);\n      except\n        on x: Exception do begin\n          Tracker.Write('      Exception smashing record: '+ovr.Name+' : '+x.Message);\n          patch.fails.Add('Exception smashing record: '+ovr.Name+' : '+x.Message);\n        end;\n      end;\n\n      // update any count elements on the record\n      UpdateCounts(patchRec);\n    end;\n  end;\nend;\n\nfunction IsChildGroup(group: IwbGroupRecord): Boolean;\nbegin\n  Result := group.GroupType in [1,6,7];\nend;\n\nfunction NativeContainer(element: IwbElement): IwbContainer;\nvar\n  group: IwbGroupRecord;\nbegin\n  if Supports(element, IwbGroupRecord, group) and IsChildGroup(group) then\n    Result := group.ChildrenOf as IwbContainer\n  else\n    Result := element.Container;\n  if not Assigned(Result) then\n    raise Exception.Create('Could not find container for ' + element.Name);\nend;\n\nprocedure RemoveEmptyContainers(aContainer: IwbContainer);\nvar\n  container, nextContainer: IwbContainer;\n  rec: IwbMainRecord;\n  bITM, bITPO: Boolean;\nbegin\n  container := aContainer;\n  // traverse up container until we find an IwbMainRecord\n  while Assigned(container) and \n  not Supports(container, IwbMainRecord, rec) do begin\n    // break if container still has elements in it\n    if container.ElementCount > 0 then\n      exit;\n\n    // else remove it and traverse up to next container\n    nextContainer := NativeContainer(container);\n    container.Remove;\n    container := nextContainer;\n  end;\n\n  // exit if record is not ITM or ITPO\n  bITM := IsITM(rec);\n  bITPO := IsITPO(rec);\n  if not (bITM or bITPO) then\n    exit;\n\n  // else remove MainRecord and recurse\n  if bITM then\n    Tracker.Write('    Removing ITM: ' + rec.Name)\n  else\n    Tracker.Write('    Removing ITPO: ' + rec.Name);\n  nextContainer := rec.Container;\n  rec.Remove;\n  RemoveEmptyContainers(nextContainer);\nend;\n\nprocedure RemoveITPOs(aFile: IwbFile);\nvar\n  i, CountITPO: Integer;\n  e, m: IwbMainRecord;\n  container: IwbContainer;\n  ITPOs: TDynMainRecords;\nbegin\n  Tracker.Write(' ');\n  Tracker.Write('Removing ITPO records from patch');\n  CountITPO := 0;\n\n  // loop through file's records\n  for i := Pred(aFile.RecordCount) downto 0 do begin\n    if Tracker.Cancel then break;\n    e := aFile.Records[i];\n    m := e.MasterOrSelf;\n\n    // skip master records\n    if e.IsMaster then\n      continue;\n\n    // skip records that have elements in child group (WRLD, CELL, DIAL)\n    if Assigned(e.ChildGroup) and (e.ChildGroup.ElementCount > 0) then\n      continue;\n\n    // remove record if no conflicts\n    if IsITPO(e) then begin\n      Tracker.Write('    Removing ITPO: ' + e.Name);\n\n      // add ITPO to list of records to remove\n      SetLength(ITPOs, CountITPO + 1);\n      ITPOs[CountITPO] := e;\n      Inc(CountITPO);\n    end;\n  end;\n\n  // remove the records\n  for i := Pred(Length(ITPOs)) downto 0 do begin\n    e := ITPOs[i];\n    container := e.Container;\n    e.Remove;\n    try\n      RemoveEmptyContainers(container);\n    except\n      on x: Exception do\n        Tracker.Write('      Exception removing empty containers: '+x.Message);\n    end;\n  end;\n\n  // finalization message\n  Tracker.Write(Format('    Removed %d ITPO records', [CountITPO]));\nend;\n\nprocedure CleanPatch(var patch: TPatch);\nvar\n  patchFile: IwbFile;\nbegin\n  patchFile := patch.plugin._File;\n\n  // remove ITPOs\n  try\n    if not settings.preserveITPOs then\n      RemoveITPOs(patchFile);\n  except\n    on x: Exception do\n      Tracker.Write('    Exception removing ITPOs: '+x.Message);\n  end;\nend;\n\nprocedure SavePatchFiles(var patch: TPatch);\nvar\n  patchFilePrefix, patchPath: string;\nbegin\n  // update patch plugin hashes and settings\n  patch.UpdateHashes;\n  patch.UpdateSettings;\n\n  // get path to save file at\n  patchPath := patch.dataPath + 'smash\\';\n  ForceDirectories(patchPath);\n\n  // save patch plugin\n  patch.plugin.dataPath := patch.dataPath;\n  patch.plugin.Save;\n\n  // save files, fails, plugins\n  patchFilePrefix := patchPath + ChangeFileExt(patch.filename, '');\n  patch.fails.SaveToFile(patchFilePrefix+'_fails.txt');\n  patch.plugins.SaveToFile(patchFilePrefix+'_plugins.txt');\nend;\n\nprocedure BuildPatch(var patch: TPatch);\nvar\n  patchFile: IwbFile;\n  pluginsToPatch: TList;\n  recordsList: TInterfaceList;\n  time: TDateTime;\n  msg: string;\nbegin\n  // initialize\n  Tracker.Write('Building patch: '+patch.name);\n  time := Now;\n  patch.fails.Clear;\n  pluginsToPatch := TList.Create;\n  msg := 'User cancelled smashing patches.';\n\n  try\n    // build list of plugins to patch\n    BuildPluginsList(patch, pluginsToPatch);\n    HandleCanceled(msg);\n    \n    // identify or create patch file\n    patchFile := GetPatchFile(patch, pluginsToPatch);\n    SetPatchAttributes(patch);\n\n    // add masters to patch file\n    AddRequiredMasters(patch, pluginsToPatch);\n    HandleCanceled(msg);\n\n    // build list of overrides\n    recordsList := TInterfaceList.Create;\n    BuildOverridesList(patch, pluginsToPatch, recordsList);\n    HandleCanceled(msg);\n\n    // stop smashing if no records to smash\n    if recordsList.Count = 0 then\n      raise Exception.create('No records to patch!');\n\n    // smash records\n    SmashRecords(patch, recordsList);\n    HandleCanceled(msg);\n\n    // clean patch (ITPOs)\n    CleanPatch(patch);\n\n    // save patch and associated files\n    SavePatchFiles(patch);\n\n    // update statistics\n    if patch.status = psBuildReady then\n      Inc(sessionStatistics.pluginsPatched, patch.plugins.Count);\n    Inc(sessionStatistics.patchesBuilt);\n\n    // finalization messages\n    time := (Now - time) * 86400;\n    patch.dateBuilt := Now;\n    patch.status := psUpToDate;\n    Tracker.Write(Format('Done smashing %s (%.3f)', [patch.name, Real(time)]));\n  except\n    on x: Exception do begin\n      patch.status := psFailed;\n      Tracker.Write(Format('Failed to patch %s, %s', [patch.name, x.Message]));\n    end;\n  end;\n\n  // clean up\n  TryToFree(pluginsToPatch);\n  TryToFree(recordsList);\nend;\n\nprocedure RebuildPatch(var patch: TPatch);\nbegin\n  BuildPatch(patch);\nend;\n\nend.\n"
  },
  {
    "path": "frontend/msSmashForm.dfm",
    "content": "object SmashForm: TSmashForm\n  Left = 0\n  Top = 0\n  Caption = 'Mator Smash'\n  ClientHeight = 682\n  ClientWidth = 1264\n  Color = clBtnFace\n  Font.Charset = DEFAULT_CHARSET\n  Font.Color = clWindowText\n  Font.Height = -11\n  Font.Name = 'Tahoma'\n  Font.Style = []\n  OldCreateOrder = False\n  Position = poScreenCenter\n  OnCloseQuery = FormCloseQuery\n  OnCreate = FormCreate\n  OnDestroy = FormDestroy\n  OnShow = FormShow\n  PixelsPerInch = 96\n  TextHeight = 13\n  object Splitter: TSplitter\n    Left = 670\n    Top = 45\n    Height = 615\n    Beveled = True\n    Color = clSilver\n    ParentColor = False\n    ExplicitLeft = 637\n    ExplicitHeight = 637\n  end\n  object QuickBar: TPanel\n    Left = 0\n    Top = 0\n    Width = 1264\n    Height = 45\n    Align = alTop\n    TabOrder = 0\n    object NewButton: TSpeedButton\n      Left = 52\n      Top = 2\n      Width = 48\n      Height = 40\n      CustomHint = bhNew\n      NumGlyphs = 2\n      ParentShowHint = False\n      ShowHint = True\n      OnClick = NewButtonClick\n    end\n    object BuildButton: TSpeedButton\n      Left = 102\n      Top = 2\n      Width = 48\n      Height = 40\n      CustomHint = bhBuild\n      NumGlyphs = 2\n      ParentShowHint = False\n      ShowHint = True\n      OnClick = BuildButtonClick\n    end\n    object OptionsButton: TSpeedButton\n      Left = 202\n      Top = 2\n      Width = 48\n      Height = 40\n      CustomHint = bhOptions\n      NumGlyphs = 2\n      ParentShowHint = False\n      ShowHint = True\n      OnClick = OptionsButtonClick\n    end\n    object ManageButton: TSpeedButton\n      Left = 152\n      Top = 2\n      Width = 48\n      Height = 40\n      CustomHint = bhManage\n      NumGlyphs = 2\n      ParentShowHint = False\n      ShowHint = True\n      OnClick = ManageButtonClick\n    end\n    object QuickButton: TSpeedButton\n      Left = 2\n      Top = 2\n      Width = 48\n      Height = 40\n      CustomHint = bhQuick\n      NumGlyphs = 2\n      ParentShowHint = False\n      ShowHint = True\n      OnClick = QuickButtonClick\n    end\n  end\n  object MainPanel: TPanel\n    Left = 0\n    Top = 45\n    Width = 670\n    Height = 615\n    Align = alLeft\n    BevelOuter = bvNone\n    Caption = 'MainPanel'\n    Constraints.MinWidth = 200\n    TabOrder = 1\n    object PageControl: TPageControl\n      Left = 3\n      Top = 7\n      Width = 664\n      Height = 605\n      ActivePage = PluginsTabSheet\n      Align = alCustom\n      Anchors = [akLeft, akTop, akRight, akBottom]\n      TabOrder = 0\n      OnChange = PageControlChange\n      object PluginsTabSheet: TTabSheet\n        Margins.Left = 4\n        Margins.Top = 4\n        Margins.Right = 4\n        Margins.Bottom = 4\n        Caption = 'Plugins'\n        object PluginsListView: TListView\n          Left = 3\n          Top = 3\n          Width = 650\n          Height = 571\n          Align = alCustom\n          Anchors = [akLeft, akTop, akRight, akBottom]\n          Columns = <\n            item\n              Caption = 'Index'\n              Width = 45\n            end\n            item\n              AutoSize = True\n              Caption = 'Filename'\n            end\n            item\n              Caption = 'Setting'\n              Tag = 300\n              Width = 161\n            end\n            item\n              Caption = 'Patch'\n              Width = 150\n            end>\n          ColumnClick = False\n          DoubleBuffered = True\n          MultiSelect = True\n          OwnerData = True\n          OwnerDraw = True\n          ReadOnly = True\n          RowSelect = True\n          ParentDoubleBuffered = False\n          ParentShowHint = False\n          PopupMenu = PluginsPopupMenu\n          ShowHint = True\n          TabOrder = 0\n          ViewStyle = vsReport\n          OnChange = PluginsListViewChange\n          OnData = PluginsListViewData\n          OnDrawItem = PluginsListViewDrawItem\n        end\n      end\n      object PatchesTabSheet: TTabSheet\n        Caption = 'Patches'\n        ImageIndex = 1\n        ExplicitLeft = 0\n        ExplicitTop = 0\n        ExplicitWidth = 0\n        ExplicitHeight = 0\n        object PatchesListView: TListView\n          Left = 3\n          Top = 3\n          Width = 650\n          Height = 571\n          Align = alCustom\n          Anchors = [akLeft, akTop, akRight, akBottom]\n          Columns = <\n            item\n              Caption = 'Index'\n            end\n            item\n              AutoSize = True\n              Caption = 'Name'\n            end\n            item\n              Caption = 'Filename'\n              Width = 175\n            end\n            item\n              Caption = 'Size'\n            end\n            item\n              Caption = 'Date built'\n              Width = 150\n            end>\n          ColumnClick = False\n          DoubleBuffered = True\n          MultiSelect = True\n          OwnerData = True\n          OwnerDraw = True\n          ReadOnly = True\n          RowSelect = True\n          ParentDoubleBuffered = False\n          ParentShowHint = False\n          PopupMenu = PatchesPopupMenu\n          ShowHint = False\n          TabOrder = 0\n          ViewStyle = vsReport\n          OnChange = PatchesListViewChange\n          OnData = PatchesListViewData\n          OnDblClick = PatchesListViewDblClick\n          OnDrawItem = PatchesListViewDrawItem\n          OnKeyDown = PatchesListViewKeyDown\n        end\n      end\n      object LogTabSheet: TTabSheet\n        Caption = 'Log'\n        ImageIndex = 2\n        ExplicitLeft = 0\n        ExplicitTop = 0\n        ExplicitWidth = 0\n        ExplicitHeight = 0\n        object LogListView: TListView\n          Left = 3\n          Top = 3\n          Width = 650\n          Height = 571\n          Align = alCustom\n          Anchors = [akLeft, akTop, akRight, akBottom]\n          Columns = <\n            item\n              Caption = 'Time'\n              Width = 80\n            end\n            item\n              Caption = 'AppTime'\n              Width = 80\n            end\n            item\n              Caption = 'Group'\n              Width = 80\n            end\n            item\n              Caption = 'Label'\n              Width = 80\n            end\n            item\n              AutoSize = True\n              Caption = 'Text'\n            end>\n          ColumnClick = False\n          DoubleBuffered = True\n          MultiSelect = True\n          OwnerData = True\n          OwnerDraw = True\n          ReadOnly = True\n          RowSelect = True\n          ParentDoubleBuffered = False\n          PopupMenu = LogPopupMenu\n          ShowColumnHeaders = False\n          TabOrder = 0\n          ViewStyle = vsReport\n          OnData = LogListViewData\n          OnDrawItem = LogListViewDrawItem\n        end\n      end\n    end\n  end\n  object DetailsPanel: TPanel\n    Left = 673\n    Top = 45\n    Width = 591\n    Height = 615\n    Align = alClient\n    BevelOuter = bvNone\n    Constraints.MinWidth = 200\n    TabOrder = 2\n    object DetailsLabel: TLabel\n      Left = 6\n      Top = 10\n      Width = 32\n      Height = 13\n      Caption = 'Details'\n    end\n    object DetailsGrid: TStringGrid\n      Left = 3\n      Top = 27\n      Width = 581\n      Height = 584\n      Align = alCustom\n      Anchors = [akLeft, akTop, akRight, akBottom]\n      ColCount = 2\n      DefaultColWidth = 150\n      DefaultRowHeight = 22\n      DoubleBuffered = True\n      RowCount = 1\n      FixedRows = 0\n      ParentDoubleBuffered = False\n      PopupMenu = DetailsPopupMenu\n      ScrollBars = ssVertical\n      TabOrder = 0\n      OnDrawCell = DetailsGridDrawCell\n      OnMouseMove = DetailsGridMouseMove\n      OnMouseUp = DetailsGridMouseUp\n    end\n  end\n  object StatusPanel: TPanel\n    Left = 0\n    Top = 660\n    Width = 1264\n    Height = 22\n    Align = alBottom\n    BevelOuter = bvLowered\n    TabOrder = 3\n    object StatusPanelMessage: TPanel\n      Left = 3\n      Top = 0\n      Width = 951\n      Height = 22\n      Margins.Top = 0\n      Margins.Bottom = 0\n      Align = alCustom\n      Alignment = taLeftJustify\n      Anchors = [akLeft, akTop, akRight, akBottom]\n      BevelEdges = [beRight]\n      BevelKind = bkFlat\n      BevelOuter = bvNone\n      Caption = 'Welcome to Mator Smash!'\n      Ctl3D = True\n      ParentCtl3D = False\n      TabOrder = 0\n    end\n    object StatusPanelMerges: TPanel\n      Left = 960\n      Top = 0\n      Width = 30\n      Height = 22\n      Margins.Top = 0\n      Margins.Bottom = 0\n      Align = alCustom\n      Anchors = [akTop, akRight, akBottom]\n      BevelEdges = [beRight]\n      BevelKind = bkFlat\n      BevelOuter = bvNone\n      Ctl3D = True\n      ParentCtl3D = False\n      TabOrder = 1\n      object ImageBuild: TImage\n        Left = 4\n        Top = 4\n        Width = 16\n        Height = 16\n        Picture.Data = {\n          055449636F6E0000010001001010000001002000680400001600000028000000\n          1000000020000000010020000000000000000000000000000000000000000000\n          000000000B0C0C000808080000000000020203000B0911000D0912000D091200\n          0D0912000D0912000D0912000E0A14000F0C1714121222A20D0C16BE0200004F\n          000000000B0C0C00080808000000000000000000050103000D0309000C030800\n          0C0308000C0308000B0207000E030700162043B9194C96FF1D4A92FF151E3BF1\n          020000590B0C0C00080808000000000000000000060205000E050C000D050B00\n          0D050B000D050B000C0205000C091C6D2E5EA1FD4E98DFFF156DDEFF1556BEFF\n          0D0F1EBE0B0C0C000808080000000000000000000B070D001A0F1F00170E1C00\n          170E1C00170D1A00150A1712163369E55CA2E3FFB6DFFDFFBEDFFFFF4B73B9FE\n          0506177F0B0C0C000808080000000000000000000302030012091500160A1A00\n          150A190014061200100E2A813976BDFF97D0FDFFDDFCFFFFB4BECFFF25222EAB\n          000000000B0C0C00080808000000000000000000000000000C050E0014071600\n          13071500110210191E3F76EC7ABEF7FFC7F3FFFF95B9D8FF1A223ABB00000000\n          000000000B0C0C0008080800000000000000000000000000060309000F040D00\n          0E0105000E1C41BE5298DBFFADE7FFFF72A8D7FF12203EC30000000200000000\n          00000000090A0A000505051B000000480000000C00000000060308000E000200\n          0C0C24982A6FB8FE9BE1FFFF7CB5E3FF081C3ECC000000080000000000000000\n          000000000405052E494847E34F4F4EFC0404049C01000000070001000F0D2497\n          2466AFFE7ECDFFFF9FDBFEFF24436EEF0000002A020000000000010000000000\n          00000000535252D7D6CFCDFFB8B4B2FF3B3C3CF8000000610A0F21971F67B4FE\n          6AC2FFFFA8E6FFFF4D7CACFE00000D7600000000000000000000000000000000\n          00000000797676ECD7D2D3FFCBC9CAFF8E8F8EFF44413FFB6E6F75FE5395C9FF\n          80D3FFFF76B2E0FF0C1735C40000000000000000000000000000000000000000\n          000000002828283A434343CB888888FDACACABFFAAA9A7FFBEB7B1FFB6B0AAFF\n          729DBDFF254468EA000000210000000000000000000000000000000000000000\n          00000000262626001D1D1D00313131ADA4A3A0FFCCCAC7FFC5C1BFFFCDC6C3FF\n          7A7270FF090809A3000000000000000000000004000000140000000C00000000\n          0000000027272700262626002222222A676665F1D1CFCDFFE6E3E1FFB3B1B0FF\n          6F6E6CFF444443F92D2E2EE4333333DB494949E83A3A3AE50606064804040400\n          05050500272727002727270026262600232323465D5D5CE7C2C0BDFFD6D3D1FF\n          ACA9A9FFA8A7A6FFAFADACFFBBB9B8FF999998FE393939B80303030C05050500\n          06060600272727002727270028282800252526002020201937363698737170E5\n          999595F99F9B9AFC8F8B8AF6686565D929292871010101000505050006060600\n          06060600FFF30000FFE10000FFE00000FFC10000FF810000FF830000FF070000\n          FE0F00008C1F0000083F0000003F0000807F0000C07F0000E0070000F0070000\n          F81F0000}\n      end\n    end\n    object StatusPanelLanguage: TPanel\n      Left = 996\n      Top = 0\n      Width = 130\n      Height = 22\n      Margins.Top = 0\n      Margins.Bottom = 0\n      Align = alCustom\n      Anchors = [akTop, akRight, akBottom]\n      BevelEdges = [beRight]\n      BevelKind = bkFlat\n      BevelOuter = bvNone\n      Caption = 'Language'\n      Ctl3D = True\n      ParentCtl3D = False\n      TabOrder = 2\n    end\n    object StatusPanelVersion: TPanel\n      Left = 1132\n      Top = 0\n      Width = 130\n      Height = 22\n      Margins.Top = 0\n      Margins.Bottom = 0\n      Align = alCustom\n      Anchors = [akTop, akRight, akBottom]\n      BevelEdges = []\n      BevelKind = bkFlat\n      BevelOuter = bvNone\n      Caption = 'v0.00.00.000'\n      Ctl3D = True\n      ParentCtl3D = False\n      TabOrder = 3\n    end\n  end\n  object XPManifest: TXPManifest\n    Left = 1120\n    Top = 8\n  end\n  object PluginsPopupMenu: TPopupMenu\n    OnPopup = PluginsPopupMenuPopup\n    Left = 56\n    Top = 112\n    object AddToPatchItem: TMenuItem\n      Caption = 'Add to patch'\n      object NewPatchItem: TMenuItem\n        Caption = '<New Patch>'\n        OnClick = AddToNewPatchClick\n      end\n    end\n    object SmashSettingItem: TMenuItem\n      Caption = 'Smash setting'\n    end\n    object TagsItem: TMenuItem\n      Caption = 'Tags'\n      object ManageTagsItem: TMenuItem\n        Caption = 'Manage tags'\n        OnClick = ManageTagsItemClick\n      end\n      object ApplySettingTagsItem: TMenuItem\n        Caption = 'Apply setting tags'\n        OnClick = ApplySettingTagsItemClick\n      end\n      object ClearTagsItem: TMenuItem\n        Caption = 'Clear tags'\n        OnClick = ClearTagsItemClick\n      end\n    end\n    object RemoveFromPatchItem: TMenuItem\n      Caption = 'Remove from patch'\n      OnClick = RemoveFromPatchItemClick\n    end\n    object OpenPluginLocationItem: TMenuItem\n      Caption = 'Open plugin location'\n      OnClick = OpenPluginLocationItemClick\n    end\n  end\n  object PatchesPopupMenu: TPopupMenu\n    OnPopup = PatchesPopupMenuPopup\n    Left = 160\n    Top = 112\n    object CreateNewPatchItem: TMenuItem\n      Caption = 'Create new patch'\n      OnClick = NewButtonClick\n    end\n    object EditPatchItem: TMenuItem\n      Caption = 'Edit patch'\n      OnClick = EditPatchItemClick\n    end\n    object RemoveUnloadedPluginsItem: TMenuItem\n      Caption = 'Remove unloaded plugins'\n      OnClick = RemoveUnloadedPluginsItemClick\n    end\n    object DeletePatchItem: TMenuItem\n      Caption = 'Delete patch'\n      OnClick = DeletePatchItemClick\n    end\n    object MoveItem: TMenuItem\n      Caption = 'Move'\n      object UpItem: TMenuItem\n        Caption = 'Up'\n        OnClick = UpItemClick\n      end\n      object DownItem: TMenuItem\n        Caption = 'Down'\n        OnClick = DownItemClick\n      end\n      object ToTopItem: TMenuItem\n        Caption = 'To top'\n        OnClick = ToTopItemClick\n      end\n      object ToBottomItem: TMenuItem\n        Caption = 'To bottom'\n        OnClick = ToBottomItemClick\n      end\n    end\n    object BuildPatchItem: TMenuItem\n      Caption = 'Build patch'\n      OnClick = BuildPatchItemClick\n    end\n    object ToggleRebuildItem: TMenuItem\n      Caption = 'Toggle rebuild status'\n      OnClick = ToggleRebuildItemClick\n    end\n    object OpenInExplorerItem: TMenuItem\n      Caption = 'Open in explorer'\n      OnClick = OpenInExplorerItemClick\n    end\n  end\n  object IconList: TImageList\n    Height = 32\n    Width = 64\n    Left = 1048\n    Top = 8\n    Bitmap = {\n      494C010105001400CC0240002000FFFFFFFFFF10FFFFFFFFFFFFFFFF424D3600\n      0000000000003600000028000000000100004000000001002000000000000000\n      0100000000000000000000000000000000000000000000000000000000000000\n      000000000000000000000000000000000000000000000000000000000000E2E2\n      E21D8F8F8F705F5F5FA03F3F3FC0303030CF303030CF3F3F3FC05F5F5FA08F8F\n      8F70E2E2E21D0000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      000000000000000000000000000000000000000000000000000000000000E5E5\n      E51D9E9E9E70747474A0595959C04C4C4CCF4C4C4CCF595959C0747474A09E9E\n      9E70E5E5E51D0000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000009898\n      9867050504FF332E27FF473F36FF50473DFF50473DFF473F36FF332E27FF0505\n      04FF989898670000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      000000000000000000000000000000000000000000000000000000000000A6A6\n      A667272727FF4A4A4AFF595959FF606060FF606060FF595959FF4A4A4AFF2727\n      27FFA6A6A6670000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000A4A4A45B5C5C5CA3F9F9F906000000009898\n      9867161411FF918171FF918171FF918171FF918171FF918171FF918171FF1614\n      11FF9898986700000000F9F9F9065C5C5CA3A4A4A45B00000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000B0B0B05B727272A3F9F9F90600000000A6A6\n      A667343434FF929292FF929292FF929292FF929292FF929292FF929292FF3434\n      34FFA6A6A66700000000F9F9F906727272A3B0B0B05B00000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      000000000000F4F4F40B575757A8040303FF0C0B09FF4B4B4BB4F9F9F9069393\n      936C171412FF948575FF948575FF948575FF948575FF948575FF948575FF1714\n      12FF9393936CF9F9F9064B4B4BB40C0B09FF040303FF575757A8F4F4F40B0000\n      0000000000000000000000000000000000000000000000000000000000000000\n      000000000000F5F5F50B6E6E6EA8262626FF2D2D2DFF636363B4F9F9F906A1A1\n      A16C343434FF969696FF969696FF969696FF969696FF969696FF969696FF3434\n      34FFA1A1A16CF9F9F906636363B42D2D2DFF262626FF6E6E6EA8F5F5F50B0000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000ECECEC13343434CB151311FF7C7064FF817567FF0F0E0CFF252525DA0404\n      04FB23201CFF98897AFF98897AFF98897AFF98897AFF98897AFF98897AFF2320\n      1CFF040404FB252525DA0F0E0CFF817567FF7C7064FF151311FF343434CBECEC\n      EC13000000000000000000000000000000000000000000000000000000000000\n      0000EEEEEE134F4F4FCB343434FF848484FF878787FF2F2F2FFF424242DA2626\n      26FB3F3F3FFF999999FF999999FF999999FF999999FF999999FF999999FF3F3F\n      3FFF262626FB424242DA2F2F2FFF878787FF848484FF343434FF4F4F4FCBEEEE\n      EE13000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      000000000000000000000000000000000000000000000000000000000000F4F4\n      F40B343434CB1D1A18FF8F8274FF9B8D7EFF9B8D7EFF84786BFF342F2AFF7369\n      5EFF9B8D7EFFA49789FFAB9F93FFAEA296FFACA094FFA79B8EFFA09385FF9A8C\n      7EFF73695EFF342F2AFF84786BFF9B8D7EFF9B8D7EFF8F8274FF1D1A18FF3434\n      34CBF4F4F40B000000000000000000000000000000000000000000000000F5F5\n      F50B4F4F4FCB3A3A3AFF939393FF9D9D9DFF9D9D9DFF8B8B8BFF4C4C4CFF7E7E\n      7EFF9D9D9DFFA5A5A5FFACACACFFAFAFAFFFADADADFFA9A9A9FFA2A2A2FF9C9C\n      9CFF7E7E7EFF4C4C4CFF8B8B8BFF9D9D9DFF9D9D9DFF939393FF3A3A3AFF4F4F\n      4FCBF5F5F50B0000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000005757\n      57A8161412FF928578FF9E9182FF9E9182FF9E9182FF9E9182FFA19486FFB6AC\n      A1FFC9C1B8FFCBC2BBFFC7BEB6FFC2BAB1FFBFB6ADFFBBB2A8FFB8AEA3FFB2A7\n      9BFFA79A8DFF9F9183FF9E9182FF9E9182FF9E9182FF9E9182FF928578FF1614\n      12FF575757A80000000000000000000000000000000000000000000000006E6E\n      6EA8343434FF969696FF9F9F9FFF9F9F9FFF9F9F9FFF9F9F9FFFA3A3A3FFB7B7\n      B7FFCACACAFFCBCBCBFFC7C7C7FFC4C4C4FFC0C0C0FFBDBDBDFFB9B9B9FFB3B3\n      B3FFA8A8A8FFA0A0A0FF9F9F9FFF9F9F9FFF9F9F9FFF9F9F9FFF969696FF3434\n      34FF6E6E6EA80000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000A4A4A45B0404\n      03FF847A6EFFA29587FFA29587FFA29587FFA29587FFAFA498FFCFC9C2FFD2CC\n      C4FFCEC7C0FFCBC2BBFFC7BEB6FFC2BAB1FFBFB6ADFFBBB2A8FFB8AEA3FFB4AA\n      9EFFB1A69AFFACA094FFA39789FFA29587FFA29587FFA29587FFA29587FF847A\n      6EFF040403FFA4A4A45B00000000000000000000000000000000B0B0B05B2727\n      27FF8B8B8BFFA4A4A4FFA4A4A4FFA4A4A4FFA4A4A4FFB1B1B1FFD0D0D0FFD2D2\n      D2FFCFCFCFFFCBCBCBFFC7C7C7FFC4C4C4FFC0C0C0FFBDBDBDFFB9B9B9FFB5B5\n      B5FFB2B2B2FFADADADFFA4A4A4FFA4A4A4FFA4A4A4FFA4A4A4FFA4A4A4FF8B8B\n      8BFF272727FFB0B0B05B00000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      00000000000000000000000000000000000000000000000000005C5C5CA30D0C\n      0BFF8C8176FFA5988BFFA5988BFFA5988BFFB8AEA4FFD8D3CDFFD6D0CAFFD2CC\n      C4FFCEC7C0FFCBC2BBFFC7BEB6FFC2BAB1FFBFB6ADFFBBB2A8FFB8AEA3FFB4AA\n      9EFFB1A69AFFADA296FFA99D91FFA5998BFFA5988BFFA5988BFFA5988BFF8C81\n      76FF0D0C0BFF5C5C5CA300000000000000000000000000000000727272A32D2D\n      2DFF929292FFA6A6A6FFA6A6A6FFA6A6A6FFB9B9B9FFD9D9D9FFD6D6D6FFD2D2\n      D2FFCFCFCFFFCBCBCBFFC7C7C7FFC4C4C4FFC0C0C0FFBDBDBDFFB9B9B9FFB5B5\n      B5FFB2B2B2FFAFAFAFFFABABABFFA6A6A6FFA6A6A6FFA6A6A6FFA6A6A6FF9292\n      92FF2D2D2DFF727272A300000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000F9F9F9064B4B\n      4BB4110F0EFF8F847AFFA89C90FFB6ACA1FFDCD7D2FFD9D4CEFFD6D0CAFFD2CC\n      C4FFCEC7C0FFCBC2BBFFC7BEB6FFC2BAB1FFBFB6ADFFBBB2A8FFB8AEA3FFB4AA\n      9EFFB1A69AFFADA296FFA99D91FFA6998CFFA79A8DFFA89C90FF8F847AFF110F\n      0EFF4B4B4BB4F9F9F90600000000000000000000000000000000F9F9F9066363\n      63B4303030FF959595FFAAAAAAFFB7B7B7FFDDDDDDFFDADADAFFD6D6D6FFD2D2\n      D2FFCFCFCFFFCBCBCBFFC7C7C7FFC4C4C4FFC0C0C0FFBDBDBDFFB9B9B9FFB5B5\n      B5FFB2B2B2FFAFAFAFFFABABABFFA7A7A7FFA8A8A8FFAAAAAAFF959595FF3030\n      30FF636363B4F9F9F90600000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      000000000000000000000000000000000000000000000000000000000000F9F9\n      F906252525DA393631FFAEA397FFDAD5D0FFDDD8D3FFD9D4CEFFD6D0CAFFD2CC\n      C4FFCEC7C0FFC8BFB7FFBBB1A7FFB4AA9FFFB3A89DFFB5AA9FFFB7ACA2FFB4AA\n      9EFFB1A69AFFADA296FFA99D91FFA6998CFFA39689FFAB9F93FF393631FF2525\n      25DAF9F9F906000000000000000000000000000000000000000000000000F9F9\n      F906424242DA515151FFB0B0B0FFDBDBDBFFDDDDDDFFDADADAFFD6D6D6FFD2D2\n      D2FFCFCFCFFFC8C8C8FFBCBCBCFFB6B6B6FFB4B4B4FFB6B6B6FFB7B7B7FFB5B5\n      B5FFB2B2B2FFAFAFAFFFABABABFFA7A7A7FFA4A4A4FFACACACFF515151FF4242\n      42DAF9F9F9060000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      000000000000000000000000000000000000E2E2E21D98989867989898679393\n      936C040404FB827A71FFC8C0B8FFE0DCD8FFDDD8D3FFD9D4CEFFD6D0CAFFD2CC\n      C4FFC1B9AFFFAFA498FF7D756DFF554F4AFF554F4AFF7D756DFFAEA397FFB2A7\n      9CFFB1A69AFFADA296FFA99D91FFA6998CFFA29587FFA79B8EFF827A71FF0404\n      04FB9393936C9898986798989867E2E2E21DE5E5E51DA6A6A667A6A6A667A1A1\n      A16C262626FB8C8C8CFFC9C9C9FFE1E1E1FFDDDDDDFFDADADAFFD6D6D6FFD2D2\n      D2FFC2C2C2FFB1B1B1FF888888FF676767FF676767FF888888FFB0B0B0FFB3B3\n      B3FFB2B2B2FFAFAFAFFFABABABFFA7A7A7FFA4A4A4FFA9A9A9FF8C8C8CFF2626\n      26FBA1A1A16CA6A6A667A6A6A667E5E5E51D0000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000008F8F8F70070606FF1C1A18FF1C1A\n      18FF292724FFB2A79CFFDEDAD5FFE0DCD8FFDDD8D3FFD9D4CEFFD6D0CAFFC5BD\n      B4FFA2988EFF282623FF070707F8404040BF404040BF070707F8282623FFA298\n      8EFFB1A69BFFADA296FFA99D91FFA6998CFFA29587FFA19485FFB1A79BFF2927\n      24FF1C1A18FF1C1A18FF070606FF8F8F8F709E9E9E70282828FF3A3A3AFF3A3A\n      3AFF454545FFB3B3B3FFDFDFDFFFE1E1E1FFDDDDDDFFDADADAFFD6D6D6FFC6C6\n      C6FFA6A6A6FF444444FF292929F85A5A5ABF5A5A5ABF292929F8444444FFA6A6\n      A6FFB2B2B2FFAFAFAFFFABABABFFA7A7A7FFA4A4A4FFA2A2A2FFB2B2B2FF4545\n      45FF3A3A3AFF3A3A3AFF282828FF9E9E9E700000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000005F5F5FA0423E3AFFB6ABA1FFB6AB\n      A1FFB6ABA1FFBFB6ACFFE4E0DDFFE0DCD8FFDDD8D3FFD9D4CEFFD2CCC6FFB6AC\n      A1FF292724FF343434CBE3E3E31C0000000000000000E3E3E31C343434CB2927\n      24FFB4AA9FFFAEA297FFA99D91FFA6998CFFA29587FF9F9183FFB1A69AFFB6AB\n      A1FFB6ABA1FFB6ABA1FF423E3AFF5F5F5FA0747474A0595959FFB7B7B7FFB7B7\n      B7FFB7B7B7FFC0C0C0FFE4E4E4FFE1E1E1FFDDDDDDFFDADADAFFD3D3D3FFB7B7\n      B7FF454545FF4F4F4FCBE6E6E61C0000000000000000E6E6E61C4F4F4FCB4545\n      45FFB6B6B6FFAFAFAFFFABABABFFA7A7A7FFA4A4A4FFA0A0A0FFB2B2B2FFB7B7\n      B7FFB7B7B7FFB7B7B7FF595959FF747474A00000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000003F3F3FC05C5752FFB9AFA5FFB9AF\n      A5FFB9AFA5FFCAC3BBFFE4E0DDFFE0DCD8FFDDD8D3FFD9D4CEFFC9C2BAFF857E\n      76FF070707F8E3E3E31C00000000000000000000000000000000E3E3E31C0707\n      07F8857E76FFB2A79CFFA99D91FFA6998CFFA29587FF9F9183FFAEA296FFB9AF\n      A5FFB9AFA5FFB9AFA5FF5C5752FF3F3F3FC0595959C06E6E6EFFBABABAFFBABA\n      BAFFBABABAFFCBCBCBFFE4E4E4FFE1E1E1FFDDDDDDFFDADADAFFCACACAFF9090\n      90FF292929F8E6E6E61C00000000000000000000000000000000E6E6E61C2929\n      29F8909090FFB3B3B3FFABABABFFA7A7A7FFA4A4A4FFA0A0A0FFAFAFAFFFBABA\n      BAFFBABABAFFBABABAFF6E6E6EFF595959C00000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      000000000000000000000000000000000000303030CF69645FFFBCB3A9FFBCB3\n      A9FFBCB3A9FFD1CAC4FFE4E0DDFFE0DCD8FFDDD8D3FFD9D4CEFFC6BEB6FF5C57\n      53FF404040BF0000000000000000000000000000000000000000000000004040\n      40BF5C5753FFB6ACA2FFA99D91FFA6998CFFA29587FF9F9183FFADA195FFBCB3\n      A9FFBCB3A9FFBCB3A9FF69645FFF303030CF4C4C4CCF797979FFBDBDBDFFBDBD\n      BDFFBDBDBDFFD1D1D1FFE4E4E4FFE1E1E1FFDDDDDDFFDADADAFFC7C7C7FF6E6E\n      6EFF5A5A5ABF0000000000000000000000000000000000000000000000005A5A\n      5ABF6E6E6EFFB7B7B7FFABABABFFA7A7A7FFA4A4A4FFA0A0A0FFAEAEAEFFBDBD\n      BDFFBDBDBDFFBDBDBDFF797979FF4C4C4CCF0000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      000000000000000000000000000000000000303030CF6C6762FFC0B7AEFFC0B7\n      AEFFC0B7AEFFD2CCC6FFE4E0DDFFE0DCD8FFDDD8D3FFD9D4CEFFC8C0B8FF5E59\n      55FF404040BF0000000000000000000000000000000000000000000000004040\n      40BF5E5955FFB8AFA4FFA99D91FFA6998CFFA29587FF9F9183FFAEA397FFC0B7\n      AEFFC0B7AEFFC0B7AEFF6B6661FF303030CF4C4C4CCF7C7C7CFFC1C1C1FFC1C1\n      C1FFC1C1C1FFD3D3D3FFE4E4E4FFE1E1E1FFDDDDDDFFDADADAFFC9C9C9FF7070\n      70FF5A5A5ABF0000000000000000000000000000000000000000000000005A5A\n      5ABF707070FFB9B9B9FFABABABFFA7A7A7FFA4A4A4FFA0A0A0FFB0B0B0FFC1C1\n      C1FFC1C1C1FFC1C1C1FF7B7B7BFF4C4C4CCF0000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000003F3F3FC0615D59FFC3BBB2FFC3BB\n      B2FFC3BBB2FFD1CAC4FFE4E0DDFFE0DCD8FFDDD8D3FFD9D4CEFFCEC7BFFF8C86\n      80FF070707F8E3E3E31C00000000000000000000000000000000E3E3E31C0707\n      07F88C8680FFB6ACA2FFA99D91FFA6998CFFA29587FF9F9183FFB4AA9EFFC3BB\n      B2FFC3BBB2FFC3BBB2FF615D59FF3F3F3FC0595959C0737373FFC4C4C4FFC4C4\n      C4FFC4C4C4FFD1D1D1FFE4E4E4FFE1E1E1FFDDDDDDFFDADADAFFCFCFCFFF9797\n      97FF292929F8E6E6E61C00000000000000000000000000000000E6E6E61C2929\n      29F8979797FFB7B7B7FFABABABFFA7A7A7FFA4A4A4FFA0A0A0FFB5B5B5FFC4C4\n      C4FFC4C4C4FFC4C4C4FF737373FF595959C00000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000005F5F5FA0484542FFC7BFB7FFC7BF\n      B7FFC7BFB7FFCDC6BEFFE4E0DDFFE0DCD8FFDDD8D3FFD9D4CEFFD4CEC8FFC6BE\n      B6FF2D2B2AFF343434CBE3E3E31C0000000000000000E3E3E31C343434CB2D2B\n      2AFFC5BCB4FFAFA499FFA99D91FFA6998CFFA29587FF9F9183FFBFB5ACFFC7BF\n      B7FFC7BFB7FFC7BFB7FF484542FF5F5F5FA0747474A05F5F5FFFC8C8C8FFC8C8\n      C8FFC8C8C8FFCECECEFFE4E4E4FFE1E1E1FFDDDDDDFFDADADAFFD5D5D5FFC7C7\n      C7FF484848FF4F4F4FCBE6E6E61C0000000000000000E6E6E61C4F4F4FCB4848\n      48FFC5C5C5FFB1B1B1FFABABABFFA7A7A7FFA4A4A4FFA0A0A0FFBFBFBFFFC8C8\n      C8FFC8C8C8FFC8C8C8FF5F5F5FFF747474A00000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000008F8F8F70080707FF1F1E1CFF1F1E\n      1CFF2E2C2BFFCAC2BAFFE1DDD9FFE0DCD8FFDDD8D3FFD9D4CEFFD6D0CAFFCFC8\n      C0FFB9B1AAFF2E2C2BFF070707F8404040BF404040BF070707F82E2C2BFFB9B1\n      AAFFBBB1A7FFADA296FFA99D91FFA6998CFFA29587FFA49789FFC9C1B9FF2E2C\n      2BFF1F1E1CFF1F1E1CFF080707FF8F8F8F709E9E9E70292929FF3D3D3DFF3D3D\n      3DFF494949FFCACACAFFE2E2E2FFE1E1E1FFDDDDDDFFDADADAFFD6D6D6FFD0D0\n      D0FFBCBCBCFF494949FF292929F85A5A5ABF5A5A5ABF292929F8494949FFBCBC\n      BCFFBCBCBCFFAFAFAFFFABABABFFA7A7A7FFA4A4A4FFA5A5A5FFCACACAFF4949\n      49FF3D3D3DFF3D3D3DFF292929FF9E9E9E700000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      000000000000000000000000000000000000E2E2E21D98989867989898679393\n      936C040404FB99948EFFD8D3CDFFE0DCD8FFDDD8D3FFD9D4CEFFD6D0CAFFD2CC\n      C4FFCEC7BFFFCDC6BEFF95908AFF65625EFF65625EFF95908AFFCCC5BDFFBFB5\n      ACFFB1A69AFFADA296FFA99D91FFA6998CFFA29587FFB8AEA3FF99948EFF0404\n      04FB9393936C9898986798989867E2E2E21DE5E5E51DA6A6A667A6A6A667A1A1\n      A16C262626FBA3A3A3FFD9D9D9FFE1E1E1FFDDDDDDFFDADADAFFD6D6D6FFD2D2\n      D2FFCFCFCFFFCECECEFF9F9F9FFF787878FF787878FF9F9F9FFFCDCDCDFFBFBF\n      BFFFB2B2B2FFAFAFAFFFABABABFFA7A7A7FFA4A4A4FFB9B9B9FFA3A3A3FF2626\n      26FBA1A1A16CA6A6A667A6A6A667E5E5E51D0000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      000000000000000000000000000000000000000000000000000000000000F9F9\n      F906252525DA464441FFD2CCC4FFDFDAD5FFDDD8D3FFD9D4CEFFD6D0CAFFD2CC\n      C4FFCEC7C0FFCBC3BCFFCBC4BCFFCBC4BCFFCAC3BAFFC5BDB4FFBAB1A6FFB4AA\n      9EFFB1A69AFFADA296FFA99D91FFA6998CFFA89B8EFFCFC8C0FF464441FF2525\n      25DAF9F9F906000000000000000000000000000000000000000000000000F9F9\n      F906424242DA5E5E5EFFD2D2D2FFDFDFDFFFDDDDDDFFDADADAFFD6D6D6FFD2D2\n      D2FFCFCFCFFFCBCBCBFFCCCCCCFFCCCCCCFFCACACAFFC6C6C6FFBBBBBBFFB5B5\n      B5FFB2B2B2FFAFAFAFFFABABABFFA7A7A7FFA9A9A9FFD0D0D0FF5E5E5EFF4242\n      42DAF9F9F9060000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000F9F9F9064B4B\n      4BB4151514FFB5B0AAFFD5CFC9FFD8D2CCFFDDD8D3FFD9D4CEFFD6D0CAFFD2CC\n      C4FFCEC7C0FFCBC2BBFFC7BEB6FFC2BAB1FFBFB6ADFFBBB2A8FFB8AEA3FFB4AA\n      9EFFB1A69AFFADA296FFA99D91FFA69A8DFFC8C1B8FFD5CFC9FFB5B0AAFF1515\n      14FF4B4B4BB4F9F9F90600000000000000000000000000000000F9F9F9066363\n      63B4353535FFBBBBBBFFD6D6D6FFD8D8D8FFDDDDDDFFDADADAFFD6D6D6FFD2D2\n      D2FFCFCFCFFFCBCBCBFFC7C7C7FFC4C4C4FFC0C0C0FFBDBDBDFFB9B9B9FFB5B5\n      B5FFB2B2B2FFAFAFAFFFABABABFFA8A8A8FFC9C9C9FFD6D6D6FFBBBBBBFF3535\n      35FF636363B4F9F9F90600000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      00000000000000000000000000000000000000000000000000005C5C5CA31111\n      11FFB8B3AEFFD8D3CDFFD8D3CDFFD8D3CDFFDAD4CFFFD9D4CEFFD6D0CAFFD2CC\n      C4FFCEC7C0FFCBC2BBFFC7BEB6FFC2BAB1FFBFB6ADFFBBB2A8FFB8AEA3FFB4AA\n      9EFFB1A69AFFADA296FFAA9E92FFC7BFB6FFD8D3CDFFD8D3CDFFD8D3CDFFB8B3\n      AEFF111111FF5C5C5CA300000000000000000000000000000000727272A33232\n      32FFBDBDBDFFD9D9D9FFD9D9D9FFD9D9D9FFDADADAFFDADADAFFD6D6D6FFD2D2\n      D2FFCFCFCFFFCBCBCBFFC7C7C7FFC4C4C4FFC0C0C0FFBDBDBDFFB9B9B9FFB5B5\n      B5FFB2B2B2FFAFAFAFFFABABABFFC8C8C8FFD9D9D9FFD9D9D9FFD9D9D9FFBDBD\n      BDFF323232FF727272A300000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000A4A4A45B0606\n      06FFB3AFABFFDBD6D1FFDBD6D1FFDBD6D1FFDBD6D1FFDBD6D1FFD6D0CAFFD2CC\n      C4FFCEC7C0FFCBC2BBFFC7BEB6FFC2BAB1FFBFB6ADFFBBB2A8FFB8AEA3FFB4AA\n      9EFFB1A69AFFB2A89CFFCFC8C1FFDBD6D1FFDBD6D1FFDBD6D1FFDBD6D1FFB3AF\n      ABFF060606FFA4A4A45B00000000000000000000000000000000B0B0B05B2828\n      28FFBABABAFFDCDCDCFFDCDCDCFFDCDCDCFFDCDCDCFFDCDCDCFFD6D6D6FFD2D2\n      D2FFCFCFCFFFCBCBCBFFC7C7C7FFC4C4C4FFC0C0C0FFBDBDBDFFB9B9B9FFB5B5\n      B5FFB2B2B2FFB3B3B3FFD0D0D0FFDCDCDCFFDCDCDCFFDCDCDCFFDCDCDCFFBABA\n      BAFF282828FFB0B0B05B00000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000005757\n      57A81E1E1DFFCDC9C4FFDFDAD6FFDFDAD6FFDFDAD6FFDFDAD6FFDEDAD5FFD9D3\n      CDFFD0CAC2FFCBC2BBFFC7BEB6FFC2BAB1FFBFB6ADFFBBB2A8FFB8AEA3FFB9AF\n      A5FFC9C1B9FFDCD8D3FFDFDAD6FFDFDAD6FFDFDAD6FFDFDAD6FFCDC9C4FF1E1E\n      1DFF575757A80000000000000000000000000000000000000000000000006E6E\n      6EA83D3D3DFFD0D0D0FFDFDFDFFFDFDFDFFFDFDFDFFFDFDFDFFFDFDFDFFFD9D9\n      D9FFD0D0D0FFCBCBCBFFC7C7C7FFC4C4C4FFC0C0C0FFBDBDBDFFB9B9B9FFBABA\n      BAFFCACACAFFDDDDDDFFDFDFDFFFDFDFDFFFDFDFDFFFDFDFDFFFD0D0D0FF3D3D\n      3DFF6E6E6EA80000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      000000000000000000000000000000000000000000000000000000000000F4F4\n      F40B343434CB2A2A29FFD0CCC8FFE2DEDAFFE2DEDAFFC0BCB9FF4B4A49FFA8A5\n      A2FFE1DDD9FFDED9D4FFD8D2CDFFD3CDC7FFD2CBC5FFD4CEC7FFDAD5D0FFE1DD\n      D9FFA8A5A2FF4B4A49FFC0BCB9FFE2DEDAFFE2DEDAFFD0CCC8FF2A2929FF3434\n      34CBF4F4F40B000000000000000000000000000000000000000000000000F5F5\n      F50B4F4F4FCB474747FFD3D3D3FFE3E3E3FFE3E3E3FFC5C5C5FF636363FFB1B1\n      B1FFE2E2E2FFDEDEDEFFD8D8D8FFD4D4D4FFD2D2D2FFD5D5D5FFDBDBDBFFE2E2\n      E2FFB1B1B1FF636363FFC5C5C5FFE3E3E3FFE3E3E3FFD3D3D3FF464646FF4F4F\n      4FCBF5F5F50B0000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000ECECEC13343434CB1F1F1EFFBBB9B6FFC3C0BDFF171616FF252525DA0404\n      04FB353433FFE5E2DEFFE5E2DEFFE5E2DEFFE5E2DEFFE5E2DEFFE5E2DEFF3534\n      33FF040404FB252525DA171616FFC3C0BDFFBBB9B6FF1F1F1EFF343434CBECEC\n      EC13000000000000000000000000000000000000000000000000000000000000\n      0000EEEEEE134F4F4FCB3E3E3EFFC3C3C3FFC9C9C9FF363636FF424242DA2626\n      26FB505050FFE6E6E6FFE6E6E6FFE6E6E6FFE6E6E6FFE6E6E6FFE6E6E6FF5050\n      50FF262626FB424242DA363636FFC9C9C9FFC3C3C3FF3E3E3EFF4F4F4FCBEEEE\n      EE13000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      000000000000F4F4F40B575757A8060606FF131212FF4B4B4BB4F9F9F9069393\n      936C242323FFE9E6E3FFE9E6E3FFE9E6E3FFE9E6E3FFE9E6E3FFE9E6E3FF2423\n      23FF9393936CF9F9F9064B4B4BB4131212FF060606FF575757A8F4F4F40B0000\n      0000000000000000000000000000000000000000000000000000000000000000\n      000000000000F5F5F50B6E6E6EA8282828FF333333FF636363B4F9F9F906A1A1\n      A16C414141FFE9E9E9FFE9E9E9FFE9E9E9FFE9E9E9FFE9E9E9FFE9E9E9FF4141\n      41FFA1A1A16CF9F9F906636363B4333333FF282828FF6E6E6EA8F5F5F50B0000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000A4A4A45B5C5C5CA3F9F9F906000000009898\n      9867242424FFECEAE7FFECEAE7FFECEAE7FFECEAE7FFECEAE7FFECEAE7FF2424\n      24FF9898986700000000F9F9F9065C5C5CA3A4A4A45B00000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000B0B0B05B727272A3F9F9F90600000000A6A6\n      A667424242FFEDEDEDFFEDEDEDFFEDEDEDFFEDEDEDFFEDEDEDFFEDEDEDFF4242\n      42FFA6A6A66700000000F9F9F906727272A3B0B0B05B00000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000009898\n      9867090909FF565555FF777675FF868583FF868583FF777675FF565555FF0909\n      09FF989898670000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      000000000000000000000000000000000000000000000000000000000000A6A6\n      A6672B2B2BFF6C6C6CFF898989FF969696FF969696FF898989FF6C6C6CFF2B2B\n      2BFFA6A6A6670000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      000000000000000000000000000000000000000000000000000000000000E2E2\n      E21D8F8F8F705F5F5FA03F3F3FC0303030CF303030CF3F3F3FC05F5F5FA08F8F\n      8F70E2E2E21D0000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      000000000000000000000000000000000000000000000000000000000000E5E5\n      E51D9E9E9E70747474A0595959C04C4C4CCF4C4C4CCF595959C0747474A09E9E\n      9E70E5E5E51D0000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      000000000000FDFDFD00DAE6D600C9DBC400CBDBC500DDE8DA00000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      000000000000FDFDFD00DEDEDE00CFCFCF00D0D0D000E1E1E100000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      00000000000000000000000000000000000000000000E3E3E31CC5C5C53ACBCB\n      CB34E8E8E817FEFEFE0100000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      00000000000000000000000000000000000000000000E3E3E31CC5C5C53ACBCB\n      CB34E8E8E817FEFEFE0100000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      00000000000000000000000000000000000000000000FEFEFD00D0E0CB0093B7\n      8700578F4600397B23003C7E27003E7F29003E7F29003C7D27003A7C25005E94\n      4D009DBD9300D6E4D20000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      00000000000000000000000000000000000000000000FDFDFD00D5D5D5009F9F\n      9F006A6A6A004F4F4F0052525200545454005454540052525200505050007070\n      7000A8A8A800DBDBDB0000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000DEDEF324A3A3\n      DF668787D5858484D4888484D4888484D4888484D4888484D4888484D4888484\n      D4889C9CDC6DDADAF22800000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000E3E3E324B1B1\n      B166999999859797978897979788979797889797978897979788979797889797\n      9788ABABAB6DDFDFDF2800000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      000000000000000000000000000000000000BABABC4857576DC043435CD45350\n      5DB989898976CFCFCF30FBFBFB04000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      000000000000000000000000000000000000BABABA485A5A5AC0474747D45353\n      53B989898976CFCFCF30FBFBFB04000000000000000000000000000000000000\n      0000FFFEFE01E1D2C73FE9DED62FFFFEFE010000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000FEFEFE01FDFDFD02FDFDFD02FEFEFE010000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000FEFEFE01D1D1D13FDDDDDD2FFEFEFE010000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000FEFEFE01FDFDFD02FDFDFD02FEFEFE010000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      000000000000000000000000000000000000D9E5D600548E4200478533004684\n      3200468432004684320046843200468432004684320046843200468432004684\n      320046843200488534005F944E00E7EFE4000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      000000000000000000000000000000000000DDDDDD00686868005C5C5C005B5B\n      5B005B5B5B005B5B5B005B5B5B005B5B5B005B5B5B005B5B5B005B5B5B005B5B\n      5B005B5B5B005C5C5C0071717100E9E9E9000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      00000000000000000000000000000000000000000000000000006767DFAC2424\n      DDFA2828DFFF2828DFFF2828DFFF2828DFFF2828DFFF2828DFFF2828DFFF2828\n      DFFF2828DFFF5353E1C300000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000838383AC4E4E\n      4EFA4E4E4EFF4E4E4EFF4E4E4EFF4E4E4EFF4E4E4EFF4E4E4EFF4E4E4EFF4E4E\n      4EFF4E4E4EFF747474C300000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000CBC9CC373D4878E526508EFF255293FF2A45\n      83FF353656E66A6A6A96CBCBCB34FDFDFD020000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000CACACA374E4E4EE54D4D4DFF4F4F4FFF4848\n      48FF3C3C3CE66A6A6A96CBCBCB34FDFDFD02000000000000000000000000C6A8\n      947C9E6947DCA5714BF2A6734EEDA8795AC2FCFBFA0600000000000000000000\n      0000000000000000000000000000FBFBFB04F6F6F609F2F2F20DEFEFEF10ECEC\n      EC13EAEAEA15E9E9E916E9E9E916EAEAEA15ECECEC13EFEFEF10F2F2F20DF6F6\n      F609FBFBFB04000000000000000000000000000000000000000000000000A6A6\n      A67C666666DC6C6C6CF26E6E6EED767676C2FAFAFA0600000000000000000000\n      0000000000000000000000000000FBFBFB04F6F6F609F2F2F20DEFEFEF10ECEC\n      EC13EAEAEA15E9E9E916E9E9E916EAEAEA15ECECEC13EFEFEF10F2F2F20DF6F6\n      F609FBFBFB040000000000000000000000000000000000000000000000000000\n      00000000000000000000FCFDFC0086AE79003D7E270045843100468432004684\n      3200468432004684320046843200468432004684320046843200468432004684\n      320046843200468432004583310041812C0096B98B0000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      00000000000000000000FCFCFC0093939300525252005A5A5A005B5B5B005B5B\n      5B005B5B5B005B5B5B005B5B5B005B5B5B005B5B5B005B5B5B005B5B5B005B5B\n      5B005B5B5B005B5B5B005A5A5A0056565600A2A2A20000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      00000000000000000000000000000000000000000000000000002F2FE0F0DDDD\n      FAFF9B9BF0FF9090EFFF9090EFFF9090EFFF9090EFFF9090EFFF9090EFFF9090\n      EFFFE1E1FAFF2828DFFF00000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000565656F0E4E4\n      E4FFADADADFFA6A6A6FFA6A6A6FFA6A6A6FFA6A6A6FFA6A6A6FFA6A6A6FFA6A6\n      A6FFE8E8E8FF4E4E4EFF00000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      00000000000000000000F5F5F50A5D5F81C10C52A8FF1357A6FF1B58A6FF175D\n      B2FF2251A1FF353555E98181817EE4E4E41B0000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      00000000000000000000F5F5F50A646464C14D4D4DFF505050FF535353FF5757\n      57FF515151FF3B3B3BE98181817EE4E4E41B0000000000000000C2A08A86A672\n      4BF1B0794EFF8D5A32FF8F5B33FFAA754DFBB68F74A000000000000000000000\n      000000000000FEFEFE01F8F8F807F2F2F20DEDEDED12E7E7E718E2E2E21DDDDD\n      DD22D9D9D926D6D6D629D6D6D629D9D9D926D5D5D52CE2E2E21DE7E7E718EDED\n      ED12F2F2F20DF7F7F708FDFDFD020000000000000000000000009E9E9E866D6D\n      6DF1747474FF555555FF565656FF707070FB8C8C8CA000000000000000000000\n      000000000000FEFEFE01F8F8F807F2F2F20DEDEDED12E7E7E718E2E2E21DDDDD\n      DD22D9D9D926D6D6D629D6D6D629D9D9D926D5D5D52CE2E2E21DE7E7E718EDED\n      ED12F2F2F20DF7F7F708FDFDFD02000000000000000000000000000000000000\n      000000000000F0F5EE00508A3D00458331004684320046843200468432004684\n      3200468432004684320046843200468432004684320046843200468432004684\n      32004684320046843200468432004684320045833100699B5900F9FBF9000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      000000000000F1F1F100636363005A5A5A005B5B5B005B5B5B005B5B5B005B5B\n      5B005B5B5B005B5B5B005B5B5B005B5B5B005B5B5B005B5B5B005B5B5B005B5B\n      5B005B5B5B005B5B5B005B5B5B005B5B5B005A5A5A007A7A7A00FAFAFA000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      00000000000000000000000000000000000000000000000000002F2FE0F09B9B\n      F0FF3737E2FF2929E0FF2929E0FF2929E0FF2929E0FF2929E0FF2929E0FF2929\n      E0FF9494EFFF2828DFFF00000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000565656F0AFAF\n      AFFF5A5A5AFF4F4F4FFF4F4F4FFF4F4F4FFF4F4F4FFF4F4F4FFF4F4F4FFF4F4F\n      4FFFA7A7A7FF4E4E4EFF00000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000094919F79144594FF418CD4FF3B82CCFF0854B9FF115D\n      C2FF0E65D2FF224DA1FF4E4C5ABFC9C9C9360000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000095959579464646FF7B7B7BFF747474FF515151FF5959\n      59FF5F5F5FFF505050FF4F4F4FBFC9C9C93600000000F1ECE61BA16E49E7AD73\n      47FFA46534FF8B552CFF774926FFA16A3FFFA26F4AE9ECE2DA29000000000000\n      000000000000FEFEFE01F8F8F807F3F3F30CEEEEEE11E8E8E817E4E4E41BDFDF\n      DF20DBDBDB24D8D8D827ACAAAA676E6E6BDF7F7F7AEC6F6F6AD2BFBFBE4EEDED\n      ED12F3F3F30CF8F8F807FEFEFE010000000000000000EBEBEB1B6A6A6AE76E6E\n      6EFF5F5F5FFF505050FF454545FF656565FF6B6B6BE9E1E1E129000000000000\n      000000000000FEFEFE01F8F8F807F3F3F30CEEEEEE11E8E8E817E4E4E41BDFDF\n      DF20DBDBDB24D8D8D827AAAAAA676D6D6DDF7E7E7EEC6E6E6ED2BFBFBF4EEDED\n      ED12F3F3F30CF8F8F807FEFEFE01000000000000000000000000000000000000\n      0000F4F8F300578F450045843100468432004684320046843200468432004684\n      31003E7E29003E7F29003E7F29003E7F29003E7F29003E7F2900468432004684\n      3200468432004684320046843200468432004684320043822F0064985400F9FB\n      F900000000000000000000000000000000000000000000000000000000000000\n      0000F5F5F5006A6A6A005A5A5A005B5B5B005B5B5B005B5B5B005B5B5B005A5A\n      5A005353530054545400545454005454540054545400545454005B5B5B005B5B\n      5B005B5B5B005B5B5B005B5B5B005B5B5B005B5B5B005858580076767600FAFA\n      FA00000000000000000000000000000000000000000000000000000000000000\n      00000000000000000000000000000000000000000000000000002F2FE0F09E9E\n      F1FF3B3BE2FF2F2FE0FF2F2FE0FF2F2FE0FF2F2FE0FF2F2FE0FF2F2FE0FF2F2F\n      E0FF9696EFFF2828DFFF00000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000565656F0B0B0\n      B0FF5D5D5DFF535353FF535353FF535353FF535353FF535353FF535353FF5353\n      53FFA9A9A9FF4E4E4EFF00000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      000000000000DBDBDC243C4A80E41667BFFF7CB3E4FF92C5EEFF448DDFFF035E\n      D7FF005EE2FF0B65E4FF444864D2CDCDCD320000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      000000000000DBDBDB24505050E45D5D5DFF9C9C9CFFABABABFF7F7F7FFF5C5C\n      5CFF5F5F5FFF646464FF4C4C4CD2CDCDCD3200000000C2A28D84AB774FFDA465\n      34FFA46534FFA16333FF7A4B27FF7F4F28FFAD794EFFA2714ED0FCFBFA060000\n      0000000000000000000000000000FDFDFD02F9F9F906F5F5F50AF1F1F10EEEEE\n      EE11EDEDED12B4B4B35E898985F0C3C8C6FFA9AFADFFC8CDCBFF6F6F6AD2F9F9\n      F906FDFDFD0200000000000000000000000000000000A0A0A084727272FD5F5F\n      5FFF5F5F5FFF5D5D5DFF474747FF4A4A4AFF747474FF6D6D6DD0FAFAFA060000\n      0000000000000000000000000000FDFDFD02F9F9F906F5F5F50AF1F1F10EEEEE\n      EE11EDEDED12B4B4B45E888888F0C7C7C7FFAEAEAEFFCCCCCCFF6E6E6ED2F9F9\n      F906FDFDFD02000000000000000000000000000000000000000000000000FDFD\n      FC00639752004684320046843200468432004684320046843200468432004B88\n      3700C0D5BA00CADBC400CADBC400CADBC400CADBC400CBDCC5005F954E004583\n      30004684320046843200468432004684320046843200468432004684320085AD\n      780000000000000000000000000000000000000000000000000000000000FCFC\n      FC00747474005B5B5B005B5B5B005B5B5B005B5B5B005B5B5B005B5B5B005F5F\n      5F00C7C7C700CFCFCF00CFCFCF00CFCFCF00CFCFCF00D0D0D000717171005959\n      59005B5B5B005B5B5B005B5B5B005B5B5B005B5B5B005B5B5B005B5B5B009292\n      9200000000000000000000000000000000000000000000000000000000000000\n      00000000000000000000000000000000000000000000000000002F2FE0F0A0A0\n      F1FF4242E3FF3434E1FF3434E1FF3434E1FF3434E1FF3434E1FF3434E1FF3434\n      E1FF9999F0FF2828DFFF00000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000565656F0B1B1\n      B1FF606060FF565656FF565656FF565656FF565656FF565656FF565656FF5656\n      56FFAAAAAAFF4E4E4EFF00000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000007A788D9D0B4DA2FF579FDFFF8FC1ECFFA3D0F4FFC9E7FCFFB4D4\n      FAFF5DA6FFFF2F67C6FF6D6B7CA1EFEFEF100000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000007C7C7C9D494949FF8A8A8AFFA9A9A9FFB5B5B5FFC9C9C9FFBDBD\n      BDFF979797FF666666FF6F6F6FA1EFEFEF1000000000A2714FCEAF784DFFA465\n      34FFA46534FFA46534FF935A2EFF764926FF8C5931FFAA754DFAA97D5FBAFEFE\n      FD02000000000000000000000000000000000000000000000000000000000000\n      0000C7C5C54B868682EEC1C7C5FF9EA3A1FFA3A7A5FFA8ADABFF80807DEBF2F2\n      F21000000000000000000000000000000000000000006D6D6DCE737373FF5F5F\n      5FFF5F5F5FFF5F5F5FFF555555FF454545FF545454FF707070FA7A7A7ABAFDFD\n      FD02000000000000000000000000000000000000000000000000000000000000\n      0000C5C5C54B858585EEC6C6C6FFA2A2A2FFA6A6A6FFACACACFF7F7F7FEBF2F2\n      F210000000000000000000000000000000000000000000000000000000009EBE\n      930044822F004684320046843200468432004684320046843200468432004684\n      320062965100FDFDFD00F7F9F600F7F8F600F7F8F600F7F9F600EDF2EB005D94\n      4B00468432004684320046843200468432004684320046843200468432004181\n      2C00B0CAA900000000000000000000000000000000000000000000000000A8A8\n      A800585858005B5B5B005B5B5B005B5B5B005B5B5B005B5B5B005B5B5B005B5B\n      5B0073737300FDFDFD00F7F7F700F7F7F700F7F7F700F7F7F700EEEEEE006F6F\n      6F005B5B5B005B5B5B005B5B5B005B5B5B005B5B5B005B5B5B005B5B5B005656\n      5600B9B9B9000000000000000000000000000000000000000000000000000000\n      00000000000000000000000000000000000000000000000000002F2FE0F0A0A0\n      F1FF4747E4FF3B3BE2FF3B3BE2FF3B3BE2FF3B3BE2FF3B3BE2FF3B3BE2FF3B3B\n      E2FF9B9BF0FF2828DFFF00000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000565656F0B2B2\n      B2FF646464FF5A5A5AFF5A5A5AFF5A5A5AFF5A5A5AFF5A5A5AFF5A5A5AFF5A5A\n      5AFFACACACFF4E4E4EFF00000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000D2D1D331253F7EF42A7FCEFF84BDEBFF98CAF2FFAFD8F8FFD9EEFEFFFFFF\n      FFFFCDD4E0FF585774D2D2D2D32D000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000D1D1D131444444F46E6E6EFFA3A3A3FFB0B0B0FFBCBCBCFFD0D0D0FFE1E1\n      E1FFBDBDBDFF5B5B5BD2D2D2D22D0000000000000000C3A38C85A7724CF5AD75\n      49FFA46535FFA46534FFA46534FF89542BFF764926FF956137FFA8754DF7B38B\n      6EA700000000000000000000000000000000000000000000000000000000CACA\n      C846838380ECC0C5C3FFA9B0ADFFAFB5B2FF9CA19FFFBEC3C1FF797975CA0000\n      00000000000000000000000000000000000000000000A0A0A0856D6D6DF57070\n      70FF5F5F5FFF5F5F5FFF5F5F5FFF4F4F4FFF454545FF5C5C5CFF707070F78787\n      87A700000000000000000000000000000000000000000000000000000000C9C9\n      C946828282ECC4C4C4FFAFAFAFFFB4B4B4FFA0A0A0FFC2C2C2FF787878CA0000\n      0000000000000000000000000000000000000000000000000000E2ECDF003D7E\n      2800468432004684320046843200468432004684320046843200468432004684\n      320043822F0062965100EFF4EE00F6F8F500F6F8F500F6F8F500F6F8F500EFF4\n      EE00639751004584310046843200468432004684320046843200468432004684\n      32004B883800F3F7F20000000000000000000000000000000000E5E5E5005353\n      53005B5B5B005B5B5B005B5B5B005B5B5B005B5B5B005B5B5B005B5B5B005B5B\n      5B005858580073737300F1F1F100F6F6F600F6F6F600F6F6F600F6F6F600F1F1\n      F100747474005A5A5A005B5B5B005B5B5B005B5B5B005B5B5B005B5B5B005B5B\n      5B0060606000F4F4F40000000000000000000000000000000000000000000000\n      00000000000000000000000000000000000000000000000000002F2FE0F0A4A4\n      F1FF4C4CE5FF4242E3FF4242E3FF4242E3FF4242E3FF4242E3FF4242E3FF4242\n      E3FF9E9EF1FF2828DFFF00000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000565656F0B4B4\n      B4FF686868FF5E5E5EFF5E5E5EFF5E5E5EFF5E5E5EFF5E5E5EFF5E5E5EFF5E5E\n      5EFFAEAEAEFF4E4E4EFF00000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      00007777909E125CB2FF69AFE8FF93C6F1FFA5D3F7FFC5E4FDFFF1FEFFFFC2DA\n      ECFF4B5279E9BCBCBE4300000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      00007C7C7C9E555555FF979797FFACACACFFB8B8B8FFC8C8C8FFDDDDDDFFBFBF\n      BFFF555555E9BCBCBC4300000000000000000000000000000000C2A08A869F6B\n      47E9AE794FFFA66939FFA46534FFA36534FF835029FF774926FF99643BFFA674\n      4DF4BC9981920000000000000000000000000000000000000000CECDCC417F7F\n      7CEBC2C8C5FFA1A7A4FFA7ADABFFA6ACAAFFC2C8C5FF898A85ECDBD9D92F0000\n      00000000000000000000000000000000000000000000000000009E9E9E866868\n      68E9747474FF636363FF5F5F5FFF5F5F5FFF4B4B4BFF454545FF5F5F5FFF6F6F\n      6FF4969696920000000000000000000000000000000000000000CCCCCC417E7E\n      7EEBC7C7C7FFA6A6A6FFACACACFFABABABFFC7C7C7FF898989ECD9D9D92F0000\n      00000000000000000000000000000000000000000000000000008CB380004684\n      3200468432004684320046843200468432004684320046843200468432004684\n      3200468432004684320062965100FBFBFA00F6F8F500F6F8F500F6F8F500F6F8\n      F500ECF2EA00508B3E0046843200468432004684320046843200468432004684\n      320045833100B2CCAA0000000000000000000000000000000000999999005B5B\n      5B005B5B5B005B5B5B005B5B5B005B5B5B005B5B5B005B5B5B005B5B5B005B5B\n      5B005B5B5B005B5B5B0073737300FAFAFA00F6F6F600F6F6F600F6F6F600F6F6\n      F600EEEEEE00646464005B5B5B005B5B5B005B5B5B005B5B5B005B5B5B005B5B\n      5B005A5A5A00BBBBBB0000000000000000000000000000000000000000000000\n      00000000000000000000000000000000000000000000000000002F2FE0F0A5A5\n      F2FF5151E6FF4747E4FF4747E4FF4747E4FF4747E4FF4747E4FF4747E4FF4747\n      E4FFA0A0F1FF2828DFFF00000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000565656F0B5B5\n      B5FF6C6C6CFF626262FF626262FF626262FF626262FF626262FF626262FF6262\n      62FFB0B0B0FF4E4E4EFF00000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      000000000000000000000000000000000000000000000000000000000000D3D3\n      D32D2E4683EC4194DDFF8BC3F0FF9BCEF5FFB7DDFCFFE9FAFFFFB3DCF4FF4452\n      85F8A4A3AA5D0000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      000000000000000000000000000000000000000000000000000000000000D3D3\n      D32D4B4B4BEC808080FFA9A9A9FFB2B2B2FFC1C1C1FFD9D9D9FFBDBDBDFF5353\n      53F8A6A6A65D000000000000000000000000000000000000000000000000EADF\n      D92BA16F4DD4AB7751F6AA6F42FFA46534FFA16333FF804F29FF774926FF9965\n      3DFFA7724EF0C7A9947A000000000000000000000000D1D1CF3C7C7C76EBC3C8\n      C6FFA1A7A5FFAEB5B2FFA0A7A4FFBBC1BEFF91918FEEC1C0BE54000000000000\n      000000000000000000000000000000000000000000000000000000000000DFDF\n      DF2B6B6B6BD4737373F66A6A6AFF5F5F5FFF5D5D5DFF4A4A4AFF454545FF6060\n      60FF6F6F6FF0A7A7A77A000000000000000000000000D0D0D03C7B7B7BEBC7C7\n      C7FFA6A6A6FFB4B4B4FFA6A6A6FFC0C0C0FF909090EEBFBFBF54000000000000\n      0000000000000000000000000000000000000000000000000000498636004684\n      3200468432004684320046843200468432004684320046843200468432004684\n      3200468432004684320043822F006A9C5B00F8F9F700F6F8F500F6F8F500F6F8\n      F500F7F9F700ECF1E9005F954E00468432004684320046843200468432004684\n      3200468432004C883A00000000000000000000000000000000005E5E5E005B5B\n      5B005B5B5B005B5B5B005B5B5B005B5B5B005B5B5B005B5B5B005B5B5B005B5B\n      5B005B5B5B005B5B5B00585858007B7B7B00F8F8F800F6F6F600F6F6F600F6F6\n      F600F8F8F800EDEDED00717171005B5B5B005B5B5B005B5B5B005B5B5B005B5B\n      5B005B5B5B0061616100000000000000000000000000DADAF2289C9CDC6D8484\n      D4888484D4888484D4888484D4888484D4888484D4888484D4882727DFF7A9A9\n      F2FF5858E7FF4E4EE5FF4E4EE5FF4E4EE5FF4E4EE5FF4E4EE5FF4E4EE5FF4E4E\n      E5FFA7A7F2FF2828DFFF8484D4888484D4888484D4888484D4888484D4888484\n      D4888484D4889C9CDC6DDADAF2280000000000000000DFDFDF28ABABAB6D9797\n      9788979797889797978897979788979797889797978897979788515151F7B6B6\n      B6FF707070FF676767FF676767FF676767FF676767FF676767FF676767FF6767\n      67FFB3B3B3FF4E4E4EFF97979788979797889797978897979788979797889797\n      978897979788ABABAB6DDFDFDF28000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000007171\n      8AA32069B8FF78BCF2FF94CAF4FFADD8FBFFDCF3FFFFA7D8F8FF415B8FFA9592\n      9D71FEFEFE010000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000007676\n      76A35F5F5FFFA2A2A2FFAFAFAFFFBCBCBCFFD3D3D3FFB9B9B9FF595959FA9595\n      9571FEFEFE010000000000000000000000000000000000000000000000000000\n      0000FEFDFC03BA967D96A8744FF1AA7042FFA46534FFA16333FF804F29FF7749\n      26FF9C683FFFA26E48EDDFD0C64200000000D3D3D138787874EAC3C8C5FFA1A8\n      A5FFAEB4B1FFA1A7A4FFBAC0BEFF999A95F0B4B4B26500000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000FCFCFC0393939396707070F16A6A6AFF5F5F5FFF5D5D5DFF4A4A4AFF4545\n      45FF636363FF6A6A6AEDCFCFCF4200000000D3D3D338777777EAC7C7C7FFA7A7\n      A7FFB3B3B3FFA6A6A6FFBFBFBFFF999999F0B4B4B46500000000000000000000\n      00000000000000000000000000000000000000000000BDD3B6003F7F2A004684\n      3200468432004684320046843200468432004684320046843200468432004684\n      32004684320046843200468432004483300065995500F5F7F400F6F8F500F6F8\n      F500F6F8F500F6F8F500EAF0E800508B3D004584310046843200468432004684\n      3200468432003F7F2A00CFDFCA000000000000000000C4C4C400545454005B5B\n      5B005B5B5B005B5B5B005B5B5B005B5B5B005B5B5B005B5B5B005B5B5B005B5B\n      5B005B5B5B005B5B5B005B5B5B005959590077777700F5F5F500F6F6F600F6F6\n      F600F6F6F600F6F6F600ECECEC00646464005A5A5A005B5B5B005B5B5B005B5B\n      5B005B5B5B0054545400D4D4D40000000000000000005353E1C32828DFFF2828\n      DFFF2828DFFF2828DFFF2828DFFF2828DFFF2828DFFF2828DFFF2828DFFF9696\n      EFFF5E5EE7FF5757E6FF5757E6FF5757E6FF5757E6FF5757E6FF5757E6FF5757\n      E6FF9696EFFF2828DFFF2828DFFF2828DFFF2828DFFF2828DFFF2828DFFF2828\n      DFFF2828DFFF2828DFFF5353E1C30000000000000000747474C34E4E4EFF4E4E\n      4EFF4E4E4EFF4E4E4EFF4E4E4EFF4E4E4EFF4E4E4EFF4E4E4EFF4E4E4EFFA4A4\n      A4FF727272FF6C6C6CFF6C6C6CFF6C6C6CFF6C6C6CFF6C6C6CFF6C6C6CFF6C6C\n      6CFFA3A3A3FF4E4E4EFF4E4E4EFF4E4E4EFF4E4E4EFF4E4E4EFF4E4E4EFF4E4E\n      4EFF4E4E4EFF4E4E4EFF747474C3000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000B5B4B94F1D45\n      8AFE53A5E8FF90C8F6FFA3D4FAFFD0EEFFFF92D1F9FF385B96FF8A879480F9F9\n      F906000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000B5B5B54F4646\n      46FE8D8D8DFFAEAEAEFFB8B8B8FFCFCFCFFFB2B2B2FF575757FF8B8B8B80F9F9\n      F906000000000000000000000000000000000000000000000000000000000000\n      00000000000000000000BB987E94A7754FF2AA6F41FFA46534FFA16333FF8350\n      29FF8C562CFFAF784EFF9F6D48D8D6D6D434757471E9C3C8C6FFA2A8A5FFADB4\n      B1FFA1A7A4FFB8BEBBFFA0A19EF2A9A9A5770000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000095959594707070F2696969FF5F5F5FFF5D5D5DFF4B4B\n      4BFF515151FF737373FF696969D8D5D5D534737373E9C7C7C7FFA7A7A7FFB3B3\n      B3FFA6A6A6FFBDBDBDFFA1A1A1F2A8A8A8770000000000000000000000000000\n      0000000000000000000000000000000000000000000072A16300448330004684\n      3200468432004483300044833000448330004483300044833000448330004483\n      30004483300044833000448330004583300043822F006D9E5D00FEFDFD00F6F8\n      F500F6F8F500F6F8F500F7F9F700E7EEE400548D410046843200468432004684\n      3200468432004483300095B88900000000000000000082828200595959005B5B\n      5B005B5B5B005959590059595900595959005959590059595900595959005959\n      590059595900595959005959590059595900585858007D7D7D00FDFDFD00F6F6\n      F600F6F6F600F6F6F600F8F8F800E9E9E900676767005B5B5B005B5B5B005B5B\n      5B005B5B5B0059595900A0A0A00000000000000000002828DFFFE8E8FBFFACAC\n      F3FFACACF3FFACACF3FFACACF3FFACACF3FFACACF3FFACACF3FF9B9BF0FF7676\n      EBFF6161E8FF5E5EE7FF5E5EE7FF5E5EE7FF5E5EE7FF5E5EE7FF5E5EE7FF5E5E\n      E7FF7373EAFF9B9BF0FFACACF3FFACACF3FFACACF3FFACACF3FFACACF3FFACAC\n      F3FFACACF3FFE8E8FBFF2828DFFF00000000000000004E4E4EFFECECECFFB7B7\n      B7FFB7B7B7FFB7B7B7FFB7B7B7FFB7B7B7FFB7B7B7FFB7B7B7FFA8A8A8FF8686\n      86FF737373FF717171FF717171FF717171FF717171FF717171FF717171FF7171\n      71FF838383FFA6A6A6FFB7B7B7FFB7B7B7FFB7B7B7FFB7B7B7FFB7B7B7FFB7B7\n      B7FFB7B7B7FFECECECFF4E4E4EFF000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      00000000000000000000000000000000000000000000DFDFDF21444D79D82983\n      D3FF83C3F6FF9BCFF9FFC4E9FFFF74C4FAFF28579AFF83808C88F8F8F8070000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      00000000000000000000000000000000000000000000DFDFDF21535353D87171\n      71FFA9A9A9FFB4B4B4FFC9C9C9FFA5A5A5FF535353FF83838388F8F8F8070000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000B8947B99A8744EF3A96E40FFA46534FFA465\n      34FFA46534FFAE764AFF986541E671716DE8C3C8C6FFA2A8A6FFADB4B1FFA1A8\n      A5FFB7BDBAFFA7A9A6F49D9B998A000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      000000000000000000000000000091919199707070F3686868FF5F5F5FFF5F5F\n      5FFF5F5F5FFF717171FF626262E6717171E8C7C7C7FFA7A7A7FFB3B3B3FFA7A7\n      A7FFBCBCBCFFA8A8A8F49B9B9B8A000000000000000000000000000000000000\n      000000000000000000000000000000000000000000004E8A3B00468432004684\n      3200518B3E0089B07C0085AE780085AE780085AE780085AE780085AE780085AE\n      780085AE780085AE780085AE780085AE780085AE780081AB7300AAC6A100F8F9\n      F700F6F8F500F6F8F500F6F8F500F7F8F600E7EEE500548E4200468432004684\n      3200468432004684320075A367000000000000000000626262005B5B5B005B5B\n      5B00646464009696960093939300939393009393930093939300939393009393\n      930093939300939393009393930093939300939393008F8F8F00B3B3B300F8F8\n      F800F6F6F600F6F6F600F6F6F600F7F7F700E9E9E900686868005B5B5B005B5B\n      5B005B5B5B005B5B5B008585850000000000000000002828DFFFB0B0F3FF6666\n      E9FF6666E9FF6666E9FF6666E9FF6666E9FF6666E9FF6666E9FF6666E9FF6666\n      E9FF6666E9FF6666E9FF6666E9FF6666E9FF6666E9FF6666E9FF6666E9FF6666\n      E9FF6666E9FF6666E9FF6666E9FF6666E9FF6666E9FF6666E9FF6666E9FF6666\n      E9FF6666E9FFB0B0F3FF2828DFFF00000000000000004E4E4EFFBABABAFF7676\n      76FF767676FF767676FF767676FF767676FF767676FF767676FF767676FF7676\n      76FF767676FF767676FF767676FF767676FF767676FF767676FF767676FF7676\n      76FF767676FF767676FF767676FF767676FF767676FF767676FF767676FF7676\n      76FF767676FFBABABAFF4E4E4EFF000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      000000000000000000000000000000000000F7F7F7086E6C83AA105EB1FF64B6\n      F4FF92CCF8FFBFE5FFFF67BDF8FF164C95FF807E8B8DF6F6F609000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      000000000000000000000000000000000000F7F7F708717171AA555555FF9B9B\n      9BFFB0B0B0FFC7C7C7FF9F9F9FFF484848FF8181818DF6F6F609000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      000000000000000000000000000000000000B992799CA9754FF3AF784CFFC49B\n      7CFFAA7042FFA9754FFF835C3FFEABAFACFFA3AAA7FFACB3B0FFA2A8A5FFB4BB\n      B8FFACAFACF7908E8B9D00000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000009090909C717171F3737373FF9797\n      97FF6A6A6AFF717171FF595959FEAEAEAEFFA9A9A9FFB2B2B2FFA7A7A7FFBABA\n      BAFFAEAEAEF78E8E8E9D00000000000000000000000000000000000000000000\n      000000000000000000000000000000000000F4F8F3004E893B00468432004684\n      32006598540000000000F7F9F600F7F9F600F7F9F600F7F9F600F7F9F600F7F9\n      F600F7F9F600F7F9F600F7F9F600F7F9F600F7F9F600F7F9F600F7F8F600F6F8\n      F500F6F8F500F6F8F500F6F8F500F6F8F500F7F8F600E4ECE100488635004684\n      320046843200468432006A9B5A00FEFFFE00F5F5F500626262005B5B5B005B5B\n      5B007676760000000000F7F7F700F7F7F700F7F7F700F7F7F700F7F7F700F7F7\n      F700F7F7F700F7F7F700F7F7F700F7F7F700F7F7F700F7F7F700F7F7F700F6F6\n      F600F6F6F600F6F6F600F6F6F600F6F6F600F7F7F700E6E6E6005D5D5D005B5B\n      5B005B5B5B005B5B5B007A7A7A00FEFEFE00000000002828DFFFB5B5F4FF6D6D\n      EAFF6D6DEAFF6D6DEAFF6D6DEAFF6D6DEAFF6D6DEAFF6D6DEAFF6D6DEAFF6D6D\n      EAFF6D6DEAFF6D6DEAFF6D6DEAFF6D6DEAFF6D6DEAFF6D6DEAFF6D6DEAFF6D6D\n      EAFF6D6DEAFF6D6DEAFF6D6DEAFF6D6DEAFF6D6DEAFF6D6DEAFF6D6DEAFF6D6D\n      EAFF6D6DEAFFB5B5F4FF2828DFFF00000000000000004E4E4EFFBDBDBDFF7B7B\n      7BFF7B7B7BFF7B7B7BFF7B7B7BFF7B7B7BFF7B7B7BFF7B7B7BFF7B7B7BFF7B7B\n      7BFF7B7B7BFF7B7B7BFF7B7B7BFF7B7B7BFF7B7B7BFF7B7B7BFF7B7B7BFF7B7B\n      7BFF7B7B7BFF7B7B7BFF7B7B7BFF7B7B7BFF7B7B7BFF7B7B7BFF7B7B7BFF7B7B\n      7BFF7B7B7BFFBDBDBDFF4E4E4EFF000000000000000000000000000000000000\n      000000000000FBFBFB04EBEBEB14F1F1F10E0000000000000000000000000000\n      0000000000000000000000000000FBFBFB0487829088154C99FF339BEDFF8AC8\n      F9FFABDAFEFFA0DCFFFF185CA9FF726E7D9AF3F3F30C00000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      000000000000FBFBFB04EBEBEB14F1F1F10E0000000000000000000000000000\n      0000000000000000000000000000FBFBFB0486868688494949FF838383FFADAD\n      ADFFBDBDBDFFBBBBBBFF545454FF7272729AF3F3F30C00000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      00000000000000000000000000000000000000000000C2A48D83A26F4BE7B88A\n      69FF9C6942FA9E7659FFE0E3E1FF797975FF989E9AFFA2A8A6FFB3BAB7FFB2B4\n      B2F9868682AD0000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      00000000000000000000000000000000000000000000A1A1A1836C6C6CE78686\n      86FF656565FA737373FFE2E2E2FF787878FF9D9D9DFFA7A7A7FFB9B9B9FFB3B3\n      B3F9858585AD0000000000000000000000000000000000000000000000000000\n      000000000000000000000000000000000000F0F5EE004D883900468432004684\n      320065985300FFFEFF00F6F8F500F6F8F500F6F8F500F6F8F500F6F8F500F6F8\n      F500F6F8F500F6F8F500F6F8F500F6F8F500F6F8F500F6F8F500F6F8F500F6F8\n      F500F6F8F500F6F8F500F6F8F500F6F8F500F6F8F500F8F9F700E5EDE300558E\n      4300468432004684320064985300FEFEFE00F1F1F100606060005B5B5B005B5B\n      5B0075757500FEFEFE00F6F6F600F6F6F600F6F6F600F6F6F600F6F6F600F6F6\n      F600F6F6F600F6F6F600F6F6F600F6F6F600F6F6F600F6F6F600F6F6F600F6F6\n      F600F6F6F600F6F6F600F6F6F600F6F6F600F6F6F600F8F8F800E8E8E8006868\n      68005B5B5B005B5B5B0075757500FEFEFE00000000002828DFFFB9B9F4FF7878\n      EBFF7878EBFF7878EBFF7878EBFF7878EBFF7878EBFF7878EBFF7878EBFF7878\n      EBFF7878EBFF7878EBFF7878EBFF7878EBFF7878EBFF7878EBFF7878EBFF7878\n      EBFF7878EBFF7878EBFF7878EBFF7878EBFF7878EBFF7878EBFF7878EBFF7878\n      EBFF7878EBFFB9B9F4FF2828DFFF00000000000000004E4E4EFFBFBFBFFF8181\n      81FF818181FF818181FF818181FF818181FF818181FF818181FF818181FF8181\n      81FF818181FF818181FF818181FF818181FF818181FF818181FF818181FF8181\n      81FF818181FF818181FF818181FF818181FF818181FF818181FF818181FF8181\n      81FF818181FFBFBFBFFF4E4E4EFF000000000000000000000000000000000000\n      0000ECECEC139898986D707072979D9D9D62E3E3E31C00000000000000000000\n      000000000000000000000000000095939C751D4487FB218DE5FF7CC2F8FF98D1\n      FCFFC1EBFFFF398ED6FF41496DD2D8D8D8270000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000ECECEC139797976D707070979D9D9D62E3E3E31C00000000000000000000\n      000000000000000000000000000095959575444444FB767676FFA7A7A7FFB4B4\n      B4FFC9C9C9FF7A7A7AFF4E4E4ED2D8D8D8270000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000F2EBE61CBCA3\n      917F6F6458E96D6D68FFC8CCC8FFDFE3E1FF777873FF9EA39FFFB7BAB7FB7F7F\n      7ABAFDFDFD020000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000EAEAEA1CA1A1\n      A17F626262E96C6C6CFFCBCBCBFFE2E2E2FF777777FFA2A2A2FFB9B9B9FB7E7E\n      7EBAFDFDFD020000000000000000000000000000000000000000000000000000\n      000000000000000000000000000000000000F0F5EF004D883A00468432004684\n      320065985300FFFEFF00F6F8F500F6F8F500F6F8F500F6F8F500F6F8F500F6F8\n      F500F6F8F500F6F8F500F6F8F500F6F8F500F6F8F500F6F8F500F6F8F500F6F8\n      F500F6F8F500F6F8F500F6F8F500F6F8F500F6F8F500F7F9F600D2E1CD004382\n      2F00468432004684320065985500FEFFFE00F2F2F200616161005B5B5B005B5B\n      5B0075757500FEFEFE00F6F6F600F6F6F600F6F6F600F6F6F600F6F6F600F6F6\n      F600F6F6F600F6F6F600F6F6F600F6F6F600F6F6F600F6F6F600F6F6F600F6F6\n      F600F6F6F600F6F6F600F6F6F600F6F6F600F6F6F600F7F7F700D7D7D7005858\n      58005B5B5B005B5B5B0076767600FEFEFE00000000002828DFFFBCBCF5FF7F7F\n      ECFF7F7FECFF7F7FECFF8686EDFF8D8DEEFF9090EFFF9696EFFF9B9BF0FF9E9E\n      F1FFA0A0F1FFA2A2F1FFA4A4F1FFA7A7F2FFA4A4F1FFA2A2F1FFA0A0F1FF9E9E\n      F1FF9B9BF0FF9696EFFF9090EFFF8D8DEEFF8686EDFF7F7FECFF7F7FECFF7F7F\n      ECFF7F7FECFFBCBCF5FF2828DFFF00000000000000004E4E4EFFC2C2C2FF8686\n      86FF868686FF868686FF8C8C8CFF919191FF979797FF9B9B9BFF9F9F9FFFA3A3\n      A3FFA6A6A6FFA8A8A8FFA9A9A9FFAAAAAAFFA9A9A9FFA8A8A8FFA6A6A6FFA3A3\n      A3FF9F9F9FFF9B9B9BFF979797FF919191FF8C8C8CFF868686FF868686FF8686\n      86FF868686FFC2C2C2FF4E4E4EFF00000000000000000000000000000000E9E9\n      E916707070AB686665FE605F5EFF494949CE9C9C9C63F0F0F00F000000000000\n      000000000000FBFBFB049D98A06C24437FF81B84DCFF6EBCF8FF8CCBFBFFB6E3\n      FFFF78C4F8FF20437FF8A4A2A75F000000000000000000000000000000000000\n      000000000000000000000000000000000000000000000000000000000000E9E9\n      E9166C6C6CAB5A5A5AFE545454FF464646CE9C9C9C63F0F0F00F000000000000\n      000000000000FBFBFB049B9B9B6C454545F86F6F6FFFA1A1A1FFAFAFAFFFC3C3\n      C3FFA6A6A6FF444444F8A4A4A45F000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      00000000000000000000FDFDFD03FDFDFD030000000000000000E4E4E3226868\n      64E3C3C7C5FFA4AAA7FF656661FFCBCFCDFFDEE2E0FF787874FF6D6C68CFFBFB\n      FB05000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      00000000000000000000FDFDFD03FDFDFD030000000000000000E3E3E3226767\n      67E3C6C6C6FFA9A9A9FF656565FFCECECEFFE1E1E1FF777777FF6C6C6CCFFBFB\n      FB05000000000000000000000000000000000000000000000000000000000000\n      000000000000000000000000000000000000F7F9F6004E893B00468432004684\n      32006699550000000000FFFEFF00FFFEFF00FFFEFF00FFFEFF00FFFEFF00FFFE\n      FF00FFFEFF00FFFEFF00FFFEFF00FFFEFF00FFFEFF00FFFEFF00FDFCFC00F6F8\n      F500F6F8F500F6F8F500F6F8F500F6F8F500F9FAF900C9DAC300468432004684\n      320046843200468432006D9E5D00FFFFFE00F7F7F700626262005B5B5B005B5B\n      5B007777770000000000FEFEFE00FEFEFE00FEFEFE00FEFEFE00FEFEFE00FEFE\n      FE00FEFEFE00FEFEFE00FEFEFE00FEFEFE00FEFEFE00FEFEFE00FCFCFC00F6F6\n      F600F6F6F600F6F6F600F6F6F600F6F6F600F9F9F900CECECE005B5B5B005B5B\n      5B005B5B5B005B5B5B007D7D7D00FEFEFE00000000002828DFFFC5C5F6FF9696\n      EFFF9D9DF0FFA5A5F2FFABABF2FFABABF2FFABABF2FFABABF2FFABABF2FFABAB\n      F2FFABABF2FFABABF2FFABABF2FFABABF2FFABABF2FFABABF2FFABABF2FFABAB\n      F2FFABABF2FFABABF2FFABABF2FFABABF2FFABABF2FFA5A5F2FF9D9DF0FF9696\n      EFFF8D8DEEFFC1C1F6FF2828DFFF00000000000000004E4E4EFFC8C8C8FF9999\n      99FFA1A1A1FFA8A8A8FFAEAEAEFFAEAEAEFFAEAEAEFFAEAEAEFFAEAEAEFFAEAE\n      AEFFAEAEAEFFAEAEAEFFAEAEAEFFAEAEAEFFAEAEAEFFAEAEAEFFAEAEAEFFAEAE\n      AEFFAEAEAEFFAEAEAEFFAEAEAEFFAEAEAEFFAEAEAEFFA8A8A8FFA1A1A1FF9999\n      99FF919191FFC5C5C5FF4E4E4EFF000000000000000000000000F9F9F9067777\n      77A28F8B8AFFC3BEBAFFA5A19EFF5A5959FF525252B6BDBDBD42FDFDFD020000\n      0000FDFDFD02918F9979244380F81D84DCFF67B8F7FF85C8FAFFA2D8FFFFA7E0\n      FFFF2265AFFF706D7C9BF4F4F40B000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000F9F9F9067373\n      73A27C7C7CFFA8A8A8FF8E8E8EFF4F4F4FFF515151B6BDBDBD42FDFDFD020000\n      0000FDFDFD0292929279454545F8707070FF9D9D9DFFABABABFFBABABAFFBEBE\n      BEFF5B5B5BFF7171719BF4F4F40B000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000DCDBD92D8A8886A26A6A65E27D7D7AE2777773CC9999968A666563E2C2C6\n      C4FFA6ACAAFFAAB1AEFFA0A7A4FF666762FFCFD2D0FFDDE1DEFF7C7C78E7E1E1\n      E025000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000DADADA2D888888A2696969E27C7C7CE2767676CC9898988A646464E2C5C5\n      C5FFABABABFFB0B0B0FFA6A6A6FF666666FFD1D1D1FFE0E0E0FF7B7B7BE7E1E1\n      E125000000000000000000000000000000000000000000000000000000000000\n      00000000000000000000000000000000000000000000538D4100468432004684\n      32004B8838006598540063975300639753006397530063975300639753006397\n      5300639753006397530063975300639753006397530061965000A3C29900F8F9\n      F700F6F8F500F6F8F500F6F8F500F7F8F600D1E0CC003E7F2A00468432004684\n      320046843200468432007CA86E000000000000000000676767005B5B5B005B5B\n      5B00606060007676760075757500757575007575750075757500757575007575\n      7500757575007575750075757500757575007575750073737300ADADAD00F8F8\n      F800F6F6F600F6F6F600F6F6F600F7F7F700D6D6D600545454005B5B5B005B5B\n      5B005B5B5B005B5B5B008B8B8B0000000000000000002828DFFFD5D5F8FFB0B0\n      F3FFB0B0F3FFB0B0F3FFB0B0F3FFB0B0F3FFB0B0F3FFB0B0F3FFB0B0F3FFB0B0\n      F3FFB0B0F3FFB0B0F3FFB0B0F3FFB0B0F3FFB0B0F3FFB0B0F3FFB0B0F3FFB0B0\n      F3FFB0B0F3FFB0B0F3FFB0B0F3FFB0B0F3FFB0B0F3FFB0B0F3FFB0B0F3FFB0B0\n      F3FFB0B0F3FFCFCFF8FF2828DFFF00000000000000004E4E4EFFD7D7D7FFB2B2\n      B2FFB2B2B2FFB2B2B2FFB2B2B2FFB2B2B2FFB2B2B2FFB2B2B2FFB2B2B2FFB2B2\n      B2FFB2B2B2FFB2B2B2FFB2B2B2FFB2B2B2FFB2B2B2FFB2B2B2FFB2B2B2FFB2B2\n      B2FFB2B2B2FFB2B2B2FFB2B2B2FFB2B2B2FFB2B2B2FFB2B2B2FFB2B2B2FFB2B2\n      B2FFAFAFAFFFD3D3D3FF4E4E4EFF000000000000000000000000B1B1B1557571\n      71FFE2DCDAFFCCC5C3FFB1ABA8FF979695FF484848F17575758AD8D8D827FCFC\n      FC039D9BA36C1E4488FD1C84DCFF5EB4F6FF7BC3FAFF8FCEFFFFB9E7FFFF469A\n      DEFF3A426DDBD0D0D02F00000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000B0B0B0556565\n      65FFC3C3C3FFB0B0B0FF989898FF848484FF414141F17575758AD8D8D827FCFC\n      FC039D9D9D6C454545FD707070FF999999FFA7A7A7FFB2B2B2FFC6C6C6FF8484\n      84FF484848DBD0D0D02F00000000000000000000000000000000000000000000\n      000000000000000000000000000000000000000000000000000000000000C8C8\n      C747757572EBBDC0BEFFC7CCCAFFC2C8C5FFC7CCCAFFB9BCB9FFC3C7C5FFAAB0\n      AEFFA9B0ADFFA4AAA7FFAEB5B2FFBCBFBCFF5A5954F7D1D5D2FEDCE0DDFF7C7C\n      76E6E3E3E2230000000000000000000000000000000000000000000000000000\n      000000000000000000000000000000000000000000000000000000000000C8C8\n      C847747474EBBFBFBFFFCBCBCBFFC7C7C7FFCBCBCBFFBBBBBBFFC6C6C6FFAFAF\n      AFFFAFAFAFFFA9A9A9FFB4B4B4FFBEBEBEFF585858F7D4D4D4FEDFDFDFFF7B7B\n      7BE6E2E2E2230000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000085AF790043822E004684\n      3200468432004583310045833100458331004583310045833100458331004583\n      31004583310045833100458331004583310042822E0096B98B00F7F9F600F6F8\n      F500F6F8F500F6F8F500F9FAF800D7E4D3004A87370046843200468432004684\n      32004684320043822E00A5C39B00000000000000000094949400585858005B5B\n      5B005B5B5B005A5A5A005A5A5A005A5A5A005A5A5A005A5A5A005A5A5A005A5A\n      5A005A5A5A005A5A5A005A5A5A005A5A5A0058585800A2A2A200F7F7F700F6F6\n      F600F6F6F600F6F6F600F9F9F900DBDBDB005F5F5F005B5B5B005B5B5B005B5B\n      5B005B5B5B0058585800AFAFAF0000000000000000002828DFFFD8D8F9FFB5B5\n      F4FFB5B5F4FFB5B5F4FFB5B5F4FFB5B5F4FFB5B5F4FFB5B5F4FFB5B5F4FFB5B5\n      F4FFB5B5F4FFB5B5F4FFB5B5F4FFB5B5F4FFB5B5F4FFB5B5F4FFB5B5F4FFB5B5\n      F4FFB5B5F4FFB5B5F4FFB5B5F4FFB5B5F4FFB5B5F4FFB5B5F4FFB5B5F4FFB5B5\n      F4FFB5B5F4FFD8D8F9FF2828DFFF00000000000000004E4E4EFFDADADAFFB5B5\n      B5FFB5B5B5FFB5B5B5FFB5B5B5FFB5B5B5FFB5B5B5FFB5B5B5FFB5B5B5FFB5B5\n      B5FFB5B5B5FFB5B5B5FFB5B5B5FFB5B5B5FFB5B5B5FFB5B5B5FFB5B5B5FFB5B5\n      B5FFB5B5B5FFB5B5B5FFB5B5B5FFB5B5B5FFB5B5B5FFB5B5B5FFB5B5B5FFB5B5\n      B5FFB5B5B5FFDADADAFF4E4E4EFF0000000000000000000000006D6A6AC7DFD9\n      D9FFF0EAEAFFC3BCBCFFB7B6B6FFB7B8B7FF7E7E7DFF424242DC7A7A7A858583\n      82894E4D66F41671BDFF43AAFBFF78C1FAFF86CAFEFFAEDEFFFF7DC8FBFF2045\n      82F99F9CA0660000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000656565C7C1C1\n      C1FFD0D0D0FFA8A8A8FFA1A1A1FFA2A2A2FF6F6F6FFF3F3F3FDC7A7A7A858282\n      82894D4D4DF45F5F5FFF909090FFA6A6A6FFAEAEAEFFC0C0C0FFAAAAAAFF4444\n      44F99D9D9D660000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000E3E3E2237979\n      77E7C7CCCAFFB7BEBBFFB6BDBAFFB6BDBAFFB6BDBAFFB7BEBBFFB8BFBCFFA9AF\n      ACFF9EA4A1FFACB3B0FFC3C8C5FF73736EDCE5E5E51F767570D1D4D8D5FEDBDF\n      DCFF7A7A75E5E4E4E32100000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000E2E2E2237878\n      78E7CBCBCBFFBDBDBDFFBCBCBCFFBCBCBCFFBCBCBCFFBDBDBDFFBEBEBEFFAEAE\n      AEFFA3A3A3FFB2B2B2FFC7C7C7FF727272DCE5E5E51F747474D1D7D7D7FEDEDE\n      DEFF7A7A7AE5E4E4E42100000000000000000000000000000000000000000000\n      00000000000000000000000000000000000000000000D9E6D5003D7E28004684\n      3200468432004684320046843200468432004684320046843200468432004684\n      3200468432004684320046843200448330008AB17E00FDFCFC00F6F8F500F6F8\n      F500F6F8F500F7F9F700D0E0CC0040802B004684320046843200468432004684\n      3200468432003B7D2700E5EEE3000000000000000000DDDDDD00535353005B5B\n      5B005B5B5B005B5B5B005B5B5B005B5B5B005B5B5B005B5B5B005B5B5B005B5B\n      5B005B5B5B005B5B5B005B5B5B005959590097979700FCFCFC00F6F6F600F6F6\n      F600F6F6F600F8F8F800D6D6D600555555005B5B5B005B5B5B005B5B5B005B5B\n      5B005B5B5B0052525200E8E8E80000000000000000002828DFFFDCDCF9FFBCBC\n      F5FFBCBCF5FFBCBCF5FFBCBCF5FFBCBCF5FFBCBCF5FFBCBCF5FFBCBCF5FFBCBC\n      F5FFBCBCF5FFBCBCF5FFBCBCF5FFBCBCF5FFBCBCF5FFBCBCF5FFBCBCF5FFBCBC\n      F5FFBCBCF5FFBCBCF5FFBCBCF5FFBCBCF5FFBCBCF5FFBCBCF5FFBCBCF5FFBCBC\n      F5FFBCBCF5FFDCDCF9FF2828DFFF00000000000000004E4E4EFFDCDCDCFFB9B9\n      B9FFB9B9B9FFB9B9B9FFB9B9B9FFB9B9B9FFB9B9B9FFB9B9B9FFB9B9B9FFB9B9\n      B9FFB9B9B9FFB9B9B9FFB9B9B9FFB9B9B9FFB9B9B9FFB9B9B9FFB9B9B9FFB9B9\n      B9FFB9B9B9FFB9B9B9FFB9B9B9FFB9B9B9FFB9B9B9FFB9B9B9FFB9B9B9FFB9B9\n      B9FFB9B9B9FFDCDCDCFF4E4E4EFF0000000000000000000000007C7A7AA6B2AF\n      AFFFEBE5E4FFC3C1C0FFC5C6C6FFB5B5B5FFA1A09FFF6C6C6CFF454546F25D5C\n      5CFBA39D97FF7A848AFF2381C9FF68C3FFFFA5DBFFFFA6E1FFFF2670BAFF6260\n      74ABEDEDED120000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000777777A69B9B\n      9BFFCCCCCCFFAAAAAAFFAFAFAFFFA0A0A0FF8D8D8DFF5F5F5FFF3F3F3FF25151\n      51FB8B8B8BFF747474FF6C6C6CFFA3A3A3FFBCBCBCFFBEBEBEFF636363FF6565\n      65ABEDEDED120000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000787872BBC4C8\n      C6FFB7BEBBFFC6CBC9FFCACFCDFFC8CDCBFFC7CCCAFFB7BEBBFFB6BDBAFFB6BD\n      BAFFB6BDBAFFC5C9C7FF757570E0E9E9E81C00000000F3F3F30F757370D6D5D9\n      D6FFD9DEDBFF797976E4C5C5C348DCDBD92DF5F5F50B00000000000000000000\n      0000000000000000000000000000000000000000000000000000777777BBC7C7\n      C7FFBDBDBDFFCACACAFFCECECEFFCCCCCCFFCBCBCBFFBDBDBDFFBCBCBCFFBCBC\n      BCFFBCBCBCFFC8C8C8FF757575E0E8E8E81C00000000F3F3F30F727272D6D8D8\n      D8FFDDDDDDFF787878E4C5C5C548DADADA2DF5F5F50B00000000000000000000\n      00000000000000000000000000000000000000000000000000005B9249004684\n      3200468432004684320046843200468432004684320046843200468432004684\n      3200468432004684320043822F0085AE7800F5F7F400F6F8F500F6F8F500F6F8\n      F500F7F9F600E0EADD0048853400468432004684320046843200468432004684\n      32004684310067995600000000000000000000000000000000006D6D6D005B5B\n      5B005B5B5B005B5B5B005B5B5B005B5B5B005B5B5B005B5B5B005B5B5B005B5B\n      5B005B5B5B005B5B5B005858580093939300F5F5F500F6F6F600F6F6F600F6F6\n      F600F7F7F700E3E3E3005C5C5C005B5B5B005B5B5B005B5B5B005B5B5B005B5B\n      5B005A5A5A00777777000000000000000000000000002828DFFFF2F2FDFFD1D1\n      F8FFD1D1F8FFD1D1F8FFD1D1F8FFD1D1F8FFD1D1F8FFD1D1F8FFCACAF7FFCACA\n      F7FFC3C3F6FFC3C3F6FFC3C3F6FFC3C3F6FFC3C3F6FFC3C3F6FFC3C3F6FFC3C3\n      F6FFCACAF7FFC7C7F6FFD1D1F8FFD1D1F8FFD1D1F8FFD1D1F8FFD1D1F8FFD1D1\n      F8FFD1D1F8FFF2F2FDFF2828DFFF00000000000000004E4E4EFFF3F3F3FFCFCF\n      CFFFCFCFCFFFCFCFCFFFCFCFCFFFCFCFCFFFCFCFCFFFCFCFCFFFC5C5C5FFC7C7\n      C7FFBDBDBDFFBDBDBDFFBDBDBDFFBDBDBDFFBDBDBDFFBDBDBDFFBDBDBDFFBDBD\n      BDFFC5C5C5FFC3C3C3FFCFCFCFFFCFCFCFFFCFCFCFFFCFCFCFFFCFCFCFFFCFCF\n      CFFFCFCFCFFFF3F3F3FF4E4E4EFF000000000000000000000000F8F8F8088080\n      809A706D6DFF989898FFBEBEBEFFB4B4B4FFA4A4A4FF969595FF90908FFFA4A2\n      9EFFB2AFAAFFB9AFA8FF8A898AFF3283BFFF88D6FFFF4DA1E3FF35416CE9C3C3\n      C33C000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000F7F7F7087D7D\n      7D9A616161FF868686FFA8A8A8FF9F9F9FFF919191FF848484FF7F7F7FFF8E8E\n      8EFF9A9A9AFF9B9B9BFF7A7A7AFF6E6E6EFFB2B2B2FF898989FF454545E9C3C3\n      C33C000000000000000000000000000000000000000000000000000000000000\n      000000000000000000000000000000000000000000000000000071716CD5CBD0\n      CEFFC5C9C7FF787974E874746FCE7B7A77B8787874E7C7CCCAFFB7BEBBFFB6BD\n      BAFFC1C7C4FF848481EAE1E1E126000000000000000000000000F0F0EE137675\n      71DAD7DBD9FFD9DDDBFFB6B8B6F7A8AAA7F1757571D0FDFDFD03000000000000\n      0000000000000000000000000000000000000000000000000000707070D5CFCF\n      CFFFC8C8C8FF787878E8737373CE7A7A7AB8787878E7CBCBCBFFBDBDBDFFBCBC\n      BCFFC6C6C6FF848484EAE1E1E126000000000000000000000000EFEFEF137474\n      74DADADADAFFDCDCDCFFB7B7B7F7A9A9A9F1757575D0FDFDFD03000000000000\n      0000000000000000000000000000000000000000000000000000A3C29A004583\n      3100468432004684320046843200468432004684320046843200468432004684\n      320046843200448330008CB27F00FCFCFC00F6F8F500F6F8F500F6F8F500F8F9\n      F700D6E3D2004886340046843200468432004684320046843200468432004684\n      320046843200CDDDC80000000000000000000000000000000000AEAEAE005A5A\n      5A005B5B5B005B5B5B005B5B5B005B5B5B005B5B5B005B5B5B005B5B5B005B5B\n      5B005B5B5B005959590098989800FCFCFC00F6F6F600F6F6F600F6F6F600F8F8\n      F800DADADA005D5D5D005B5B5B005B5B5B005B5B5B005B5B5B005B5B5B005B5B\n      5B005B5B5B00D2D2D2000000000000000000000000007E7EEC962828DFFF2828\n      DFFF2828DFFF2828DFFF2828DFFF2828DFFF2828DFFF2828DFFF2828DFFFCFCF\n      F8FFC8C8F7FFC7C7F6FFC7C7F6FFC7C7F6FFC7C7F6FFC7C7F6FFC7C7F6FFC7C7\n      F6FFDADAF9FF2828DFFF2828DFFF2828DFFF2828DFFF2828DFFF2828DFFF2828\n      DFFF2828DFFF2828DFFF7E7EEC960000000000000000969696964E4E4EFF4E4E\n      4EFF4E4E4EFF4E4E4EFF4E4E4EFF4E4E4EFF4E4E4EFF4E4E4EFF4E4E4EFFD1D1\n      D1FFC3C3C3FFC0C0C0FFC0C0C0FFC0C0C0FFC0C0C0FFC0C0C0FFC0C0C0FFC0C0\n      C0FFD7D7D7FF4E4E4EFF4E4E4EFF4E4E4EFF4E4E4EFF4E4E4EFF4E4E4EFF4E4E\n      4EFF4E4E4EFF4E4E4EFF9696969600000000000000000000000000000000F9F9\n      F906B8B8B855757575A8656565FEB2B2B2FFA2A2A2FF9F9E9BFFAEACA8FFB5B1\n      AFFFB6B2AFFFB9B5B3FFC4BAB4FF9E9895FF4183B4FF284D89FB96959675FCFC\n      FC03000000000000000000000000000000000000000000000000000000000000\n      000000000000000000000000000000000000000000000000000000000000F9F9\n      F906B6B6B655727272A8595959FE9D9D9DFF8F8F8FFF8B8B8BFF979797FF9D9D\n      9DFF9D9D9DFFA1A1A1FFA5A5A5FF878787FF6E6E6EFF4B4B4BFB95959575FCFC\n      FC03000000000000000000000000000000000000000000000000000000000000\n      00000000000000000000000000000000000000000000FDFDFD02787873E5CACE\n      CCFF706F6BE1DFDFDF270000000000000000D7D7D63271706BE5C5CAC8FFB6BD\n      BAFFBFC5C3FF81827FE7FDFDFD0300000000000000000000000000000000ECEC\n      EB1781817EE7DBE1DEFFD0D8D4FFD4DBD7FFC1C4C1FB97959394000000000000\n      00000000000000000000000000000000000000000000FDFDFD02777777E5CDCD\n      CDFF6E6E6EE1DFDFDF270000000000000000D7D7D7326F6F6FE5C9C9C9FFBCBC\n      BCFFC4C4C4FF818181E7FDFDFD0300000000000000000000000000000000ECEC\n      EC17818181E7E0E0E0FFD7D7D7FFDADADAFFC3C3C3FB95959594000000000000\n      0000000000000000000000000000000000000000000000000000F9FBF9004583\n      3100468432004684320046843200468432004684320046843200468432004684\n      32004483300076A36700F7F9F700F6F8F500F6F8F500F6F8F500F6F8F500E2EB\n      DF0043822F004684320046843200468432004684320046843200468432004684\n      320059904700FBFCFB0000000000000000000000000000000000FAFAFA005A5A\n      5A005B5B5B005B5B5B005B5B5B005B5B5B005B5B5B005B5B5B005B5B5B005B5B\n      5B005959590085858500F8F8F800F6F6F600F6F6F600F6F6F600F6F6F600E5E5\n      E500585858005B5B5B005B5B5B005B5B5B005B5B5B005B5B5B005B5B5B005B5B\n      5B006B6B6B00FBFBFB0000000000000000000000000000000000000000000000\n      00000000000000000000000000000000000000000000000000002F2FE0F0D8D8\n      F9FFCFCFF8FFCCCCF7FFCCCCF7FFCCCCF7FFCCCCF7FFCCCCF7FFCCCCF7FFCCCC\n      F7FFE6E6FBFF2828DFFF00000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000565656F0DBDB\n      DBFFC6C6C6FFC3C3C3FFC3C3C3FFC3C3C3FFC3C3C3FFC3C3C3FFC3C3C3FFC3C3\n      C3FFE1E1E1FF4E4E4EFF00000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      00000000000000000000909090856F6F6FFFABABA7FFB6B4B0FFBAB8B5FFBCB8\n      B5FFBEBAB8FFC0BCBAFFC7C2C0FFC3BBB8FF76706FFF706E70A8F0F0F00F0000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      000000000000000000008E8E8E85626262FF969696FF9E9E9EFFA3A3A3FFA3A3\n      A3FFA5A5A5FFA7A7A7FFACACACFFA7A7A7FF656565FF6C6C6CA8F0F0F00F0000\n      0000000000000000000000000000000000000000000000000000000000000000\n      00000000000000000000000000000000000000000000FEFEFE0180807BAE6B6B\n      66DAE9E9E81C00000000000000000000000000000000AFADAB69AFB2AFFFB6BD\n      BAFFBDC4C1FF8F908DECEAEAE81B000000000000000000000000000000000000\n      0000878783DCD9E0DDFFCFD7D3FFCFD7D3FFD8DEDBFF9E9F9CF0CFCECD400000\n      00000000000000000000000000000000000000000000FEFEFE017F7F7FAE6A6A\n      6ADAE8E8E81C00000000000000000000000000000000ADADAD69B1B1B1FFBCBC\n      BCFFC3C3C3FF8F8F8FECE9E9E91B000000000000000000000000000000000000\n      0000868686DCDFDFDFFFD6D6D6FFD6D6D6FFDDDDDDFF9E9E9EF0CDCDCD400000\n      000000000000000000000000000000000000000000000000000000000000D1E0\n      CD00448330004684320046843200468432004684320046843200468432004583\n      310089B07C00FBFCFB00F9FAF800F9FAF800F9FAF800FAFBFA00E2EBDF004F8A\n      3D00468432004684320046843200468432004684320046843200468432004180\n      2D00E5EEE200000000000000000000000000000000000000000000000000D6D6\n      D600595959005B5B5B005B5B5B005B5B5B005B5B5B005B5B5B005B5B5B005A5A\n      5A0096969600FBFBFB00F9F9F900F9F9F900F9F9F900FAFAFA00E5E5E5006363\n      63005B5B5B005B5B5B005B5B5B005B5B5B005B5B5B005B5B5B005B5B5B005656\n      5600E8E8E8000000000000000000000000000000000000000000000000000000\n      00000000000000000000000000000000000000000000000000002F2FE0F0D8D8\n      F9FFD3D3F8FFD1D1F8FFD1D1F8FFD1D1F8FFD1D1F8FFD1D1F8FFD1D1F8FFD1D1\n      F8FFE6E6FBFF2828DFFF00000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000565656F0DBDB\n      DBFFC9C9C9FFC6C6C6FFC6C6C6FFC6C6C6FFC6C6C6FFC6C6C6FFC6C6C6FFC6C6\n      C6FFE2E2E2FF4E4E4EFF00000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      00000000000000000000F1F1F1115F5F5FCFAFAEAAFFC5C3C1FFC1C0BDFFC4C1\n      BEFFC6C2C0FFC9C4C2FFC9C3C1FF928F8EFF555555F97E7E7D82DDDDDD22FAFA\n      FA05FEFEFE0100000000000000000000000000000000FCFCFC03FBFBFB040000\n      0000000000000000000000000000000000000000000000000000000000000000\n      00000000000000000000F0F0F011595959CF999999FFACACACFFA9A9A9FFAAAA\n      AAFFACACACFFAEAEAEFFADADADFF7F7F7FFF4C4C4CF97D7D7D82DDDDDD22FAFA\n      FA05FEFEFE0100000000000000000000000000000000FCFCFC03FBFBFB040000\n      0000000000000000000000000000000000000000000000000000FEFEFE01F3F3\n      F30F0000000000000000000000000000000000000000A1A19E80B6B9B6FFB6BD\n      BAFFC0C6C4FF90928FEFD9D9D72F000000000000000000000000000000000000\n      0000767671D5D6DAD7FFD2D9D6FFCFD7D3FFCFD7D3FFDADFDDFF7D7D78E3F2F1\n      F111000000000000000000000000000000000000000000000000FEFEFE01F3F3\n      F30F0000000000000000000000000000000000000000A0A0A080B8B8B8FFBCBC\n      BCFFC5C5C5FF919191EFD9D9D92F000000000000000000000000000000000000\n      0000757575D5D9D9D9FFD8D8D8FFD6D6D6FFD6D6D6FFDEDEDEFF7C7C7CE3F1F1\n      F111000000000000000000000000000000000000000000000000000000000000\n      00008AB17E0042812E0046843200468432004684320046843200468432004A87\n      3700B4CEAD00B1CBA800B1CBA900B1CBA900B1CBA900B2CBAA00468432004684\n      320046843200468432004684320046843200468432004684320043822F00AFC9\n      A600000000000000000000000000000000000000000000000000000000000000\n      000097979700575757005B5B5B005B5B5B005B5B5B005B5B5B005B5B5B005F5F\n      5F00BDBDBD00B9B9B900BABABA00BABABA00BABABA00BABABA005B5B5B005B5B\n      5B005B5B5B005B5B5B005B5B5B005B5B5B005B5B5B005B5B5B0058585800B7B7\n      B700000000000000000000000000000000000000000000000000000000000000\n      00000000000000000000000000000000000000000000000000002F2FE0F0DCDC\n      F9FFD6D6F9FFD5D5F8FFD5D5F8FFD5D5F8FFD5D5F8FFD5D5F8FFD5D5F8FFD5D5\n      F8FFEAEAFBFF2828DFFF00000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000565656F0DCDC\n      DCFFCCCCCCFFC9C9C9FFC9C9C9FFC9C9C9FFC9C9C9FFC9C9C9FFC9C9C9FFC9C9\n      C9FFE4E4E4FF4E4E4EFF00000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      000000000000000000000000000082828296918F8CFFD3D1CFFFCAC8C6FFCBC9\n      C7FFCECBC9FFD3CFCDFFA9A6A4FF7E7E7EFF636363FD49494ACD707070919999\n      9966ADADAD52B5B5B54AB5B5B54AB1B1B14EA5A5A55B99999968B9B9B946F2F2\n      F20D000000000000000000000000000000000000000000000000000000000000\n      00000000000000000000000000007F7F7F967E7E7EFFB9B9B9FFB1B1B1FFB2B2\n      B2FFB3B3B3FFB8B8B8FF939393FF6F6F6FFF585858FD464646CD707070919999\n      9966ADADAD52B5B5B54AB5B5B54AB1B1B14EA5A5A55B98989868B9B9B946F2F2\n      F20D000000000000000000000000000000000000000000000000000000000000\n      000000000000000000000000000000000000F0F0EE13696864D7C5CAC7FFB6BD\n      BAFFC9CECCFF676661DCFEFEFE01000000000000000000000000000000000000\n      0000EAEAE81B70706BD8CDD0CEFED4DBD7FFCFD7D3FFD1D8D4FFD2D5D3FE7D7B\n      78B7000000000000000000000000000000000000000000000000000000000000\n      000000000000000000000000000000000000EFEFEF13686868D7C9C9C9FFBCBC\n      BCFFCDCDCDFF656565DCFEFEFE01000000000000000000000000000000000000\n      0000E9E9E91B6F6F6FD8CFCFCFFEDADADAFFD6D6D6FFD7D7D7FFD4D4D4FE7A7A\n      7AB7000000000000000000000000000000000000000000000000000000000000\n      0000000000008AB17F0045833100468432004684320046843200468432004684\n      3200448330004483300044833000448330004483300044833000468432004684\n      3200468432004684320046843200468432004684320040802B00A2C199000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      000000000000989898005A5A5A005B5B5B005B5B5B005B5B5B005B5B5B005B5B\n      5B005959590059595900595959005959590059595900595959005B5B5B005B5B\n      5B005B5B5B005B5B5B005B5B5B005B5B5B005B5B5B0055555500ADADAD000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      00000000000000000000000000000000000000000000000000002F2FE0F0DDDD\n      FAFFDCDCF9FFDCDCF9FFDCDCF9FFDCDCF9FFDCDCF9FFDCDCF9FFDCDCF9FFDCDC\n      F9FFEBEBFCFF2828DFFF00000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000565656F0DDDD\n      DDFFCFCFCFFFCCCCCCFFCCCCCCFFCCCCCCFFCCCCCCFFCCCCCCFFCCCCCCFFCCCC\n      CCFFE5E5E5FF4E4E4EFF00000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000DEDEDE265B5B5AD4A2A19DFFDDDCD9FFD6D4\n      D2FFD6D3D1FFD6D3D1FF908F8DFF808080FF8A8A8AFF707070FE5C5C5CF75353\n      53EC565656E4585858E05C5C5CE1626262E66F6F6FEF616161F98B8B8B80F3F3\n      F30C000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000DEDEDE26555555D48D8D8DFFC1C1C1FFBBBB\n      BBFFBABABAFFBABABAFF7E7E7EFF717171FF7A7A7AFF636363FE525252F74C4C\n      4CEC4E4E4EE4515151E0555555E1595959E6646464EF575757F989898980F3F3\n      F30C000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000EBEBEB196A6866DBBEC3C0FFBCC2C0FFC6CB\n      C9FF9FA39FFAA8A7A37600000000000000000000000000000000000000000000\n      000000000000F6F5F50C777773C5C1C4C1FAD8DFDBFFD8DDDAFF7E7E79E4D8D8\n      D633000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000EBEBEB19686868DBC2C2C2FFC1C1C1FFCACA\n      CAFFA2A2A2FAA6A6A67600000000000000000000000000000000000000000000\n      000000000000F5F5F50C767676C5C3C3C3FADEDEDEFFDCDCDCFF7D7D7DE4D7D7\n      D733000000000000000000000000000000000000000000000000000000000000\n      000000000000000000008BB17E0042812E004684320046843200468432004684\n      3200468432004684320046843200468432004684320046843200468432004684\n      32004684320046843200468432004684320043822F00A2C19800000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000097979700575757005B5B5B005B5B5B005B5B5B005B5B\n      5B005B5B5B005B5B5B005B5B5B005B5B5B005B5B5B005B5B5B005B5B5B005B5B\n      5B005B5B5B005B5B5B005B5B5B005B5B5B0058585800ACACAC00000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      00000000000000000000000000000000000000000000000000002F2FE0F0DDDD\n      FAFFDFDFFAFFDDDDFAFFDDDDFAFFDDDDFAFFDDDDFAFFDDDDFAFFDDDDFAFFDDDD\n      FAFFEDEDFCFF2828DFFF00000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000565656F0DEDE\n      DEFFD1D1D1FFCECECEFFCECECEFFCECECEFFCECECEFFCECECEFFCECECEFFCECE\n      CEFFE6E6E6FF4E4E4EFF00000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      000000000000000000000000000000000000E2E2E2225B5B5BCD959490FFDFDC\n      DBFFE3E1E0FFE0DDDBFFAAA6A5FF7B7B7BFF8A8A88FF8F8F8EFF969694FF999A\n      99FF9E9E9DFFA6A5A5FFB2B2B1FFC3C3C2FFA6A6A6FF808080C3D5D5D52C0000\n      0000000000000000000000000000000000000000000000000000000000000000\n      000000000000000000000000000000000000E1E1E122565656CD828282FFC3C3\n      C3FFC7C7C7FFC3C3C3FF949494FF6D6D6DFF797979FF7E7E7EFF848484FF8787\n      87FF8C8C8CFF929292FF9D9D9DFFACACACFF939393FF787878C3D5D5D52C0000\n      0000000000000000000000000000000000000000000000000000000000000000\n      00000000000000000000EEECEC1662615CE2C7CAC8FFCBD0CEFFCCD0CEFF8D8E\n      8AF07E7E7BAFF9F9F80800000000000000000000000000000000000000000000\n      00000000000000000000FDFDFD03878783A8A4A5A3F6747471DFE4E4E3210000\n      0000000000000000000000000000000000000000000000000000000000000000\n      00000000000000000000EDEDED16606060E2C9C9C9FFCFCFCFFFCFCFCFFF8D8D\n      8DF07D7D7DAFF8F8F80800000000000000000000000000000000000000000000\n      00000000000000000000FDFDFD03868686A8A5A5A5F6737373DFE4E4E4210000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000C5D8C00043822E0046843200468432004684\n      3200468432004684320046843200468432004684320046843200468432004684\n      32004684320046843200468432004B873800DFEADC0000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000CCCCCC00585858005B5B5B005B5B5B005B5B\n      5B005B5B5B005B5B5B005B5B5B005B5B5B005B5B5B005B5B5B005B5B5B005B5B\n      5B005B5B5B005B5B5B005B5B5B005F5F5F00E3E3E30000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      00000000000000000000000000000000000000000000000000002F2FE0F0DDDD\n      FAFFE1E1FAFFE1E1FAFFE1E1FAFFE1E1FAFFE1E1FAFFE1E1FAFFE1E1FAFFE1E1\n      FAFFEFEFFCFF2828DFFF00000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000565656F0DFDF\n      DFFFD3D3D3FFD0D0D0FFD0D0D0FFD0D0D0FFD0D0D0FFD0D0D0FFD0D0D0FFD0D0\n      D0FFE8E8E8FF4E4E4EFF00000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      00000000000000000000000000000000000000000000EEEEEE13787878A26B6A\n      68FFC6C2C0FFEDEAE9FFECE9E7FFBFBCBAFF9E9B9BFF979494FF9B9A99FFA4A3\n      A2FFACAAA9FFB8B6B4FFBDBCBAFF8A8988FF7B7B7BA3EBEBEB14000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      00000000000000000000000000000000000000000000EEEEEE13757575A25E5E\n      5EFFACACACFFD0D0D0FFCECECEFFA6A6A6FF8A8A8AFF848484FF888888FF9090\n      90FF969696FFA1A1A1FFA6A6A6FF797979FF787878A3EBEBEB14000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      00000000000000000000FEFEFE01898884A4787872E170706AD9686662D3BDBD\n      BB58000000000000000000000000000000000000000000000000000000000000\n      000000000000000000000000000000000000B4B2B064EFEFEF14000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      00000000000000000000FEFEFE01878787A4777777E16F6F6FD9656565D3BCBC\n      BC58000000000000000000000000000000000000000000000000000000000000\n      000000000000000000000000000000000000B2B2B264EFEFEF14000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      000000000000000000000000000000000000F3F6F100A2C19800538C40003E7F\n      290044822F004684320046843200468432004684320046843200468432004382\n      2E003C7E27005B924A00ADC8A400F9FBF9000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      000000000000000000000000000000000000F3F3F300ACACAC00666666005454\n      5400585858005B5B5B005B5B5B005B5B5B005B5B5B005B5B5B005B5B5B005858\n      5800525252006E6E6E00B6B6B600FAFAFA000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      00000000000000000000000000000000000000000000000000003030E0EDE3E3\n      FAFFE4E4FBFFE4E4FBFFE4E4FBFFE4E4FBFFE4E4FBFFE4E4FBFFE4E4FBFFE4E4\n      FBFFEFEFFCFF2828DFFF00000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000585858EDE0E0\n      E0FFD5D5D5FFD2D2D2FFD2D2D2FFD2D2D2FFD2D2D2FFD2D2D2FFD2D2D2FFD2D2\n      D2FFE8E8E8FF4E4E4EFF00000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      000000000000000000000000000000000000000000000000000000000000B7B7\n      B754696969C17A7876F8B0ADACFFD4D0CFFFDED9D7FFDAD4D3FFD5CECDFFC9C1\n      C0FFB6ADADFFA19B9AFF858282E197979780F2F2F20D00000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      000000000000000000000000000000000000000000000000000000000000B6B6\n      B654636363C16B6B6BF89A9A9AFFB9B9B9FFC1C1C1FFBDBDBDFFB8B8B8FFACAC\n      ACFF9B9B9BFF8B8B8BFF787878E194949480F2F2F20D00000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      000000000000000000000000000000000000000000000000000000000000C9DA\n      C2007AA76C00548D4200518B3E004F8A3C004F8A3C00518B3F00568F440084AC\n      7700D6E3D1000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      000000000000000000000000000000000000000000000000000000000000CECE\n      CE00898989006767670064646400636363006363630065656500696969009191\n      9100DADADA000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      00000000000000000000000000000000000000000000000000003A3AE2E5E8E8\n      FBFFF2F2FDFFF1F1FCFFF1F1FCFFF1F1FCFFF1F1FCFFF1F1FCFFF1F1FCFFF1F1\n      FCFFF9F9FEFF2828DFFF00000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      00000000000000000000000000000000000000000000000000005F5F5FE5EEEE\n      EEFFEBEBEBFFE9E9E9FFE9E9E9FFE9E9E9FFE9E9E9FFE9E9E9FFE9E9E9FFE9E9\n      E9FFF9F9F9FF4E4E4EFF00000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000F8F8F807C7C8C74293939187727272BB706E6EDD727070EA757474E37D7C\n      7CC49090909CB1B1B160E2E2E21E000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000F8F8F807C6C6C6428F8F8F876D6D6DBB666666DD666666EA696969E37474\n      74C48A8A8A9CAEAEAE60E1E1E11E000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      00000000000000000000F4F8F300EFF4EE00EFF5EE00F5F8F400000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      00000000000000000000F5F5F500F1F1F100F1F1F100F6F6F600000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      00000000000000000000000000000000000000000000000000009797EF783D3D\n      E2E12828DFFF2828DFFF2828DFFF2828DFFF2828DFFF2828DFFF2828DFFF2828\n      DFFF2828DFFF7E7EEC9600000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000AAAAAA786161\n      61E14E4E4EFF4E4E4EFF4E4E4EFF4E4E4EFF4E4E4EFF4E4E4EFF4E4E4EFF4E4E\n      4EFF4E4E4EFF9696969600000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      000000000000000000000000000000000000424D3E000000000000003E000000\n      2800000000010000400000000100010000000000000800000000000000000000\n      000000000000000000000000FFFFFF00FFE007FFFFE007FF0000000000000000\n      00000000000000000000000000000000FFE007FFFFE007FF0000000000000000\n      00000000000000000000000000000000FE20047FFE20047F0000000000000000\n      00000000000000000000000000000000F800001FF800001F0000000000000000\n      00000000000000000000000000000000F000000FF000000F0000000000000000\n      00000000000000000000000000000000E0000007E00000070000000000000000\n      00000000000000000000000000000000E0000007E00000070000000000000000\n      00000000000000000000000000000000C0000003C00000030000000000000000\n      00000000000000000000000000000000C0000003C00000030000000000000000\n      00000000000000000000000000000000C0000003C00000030000000000000000\n      00000000000000000000000000000000E0000007E00000070000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000018000000180000000000000000000\n      000000000000000000000000000000000003C0000003C0000000000000000000\n      000000000000000000000000000000000007E0000007E0000000000000000000\n      000000000000000000000000000000000007E0000007E0000000000000000000\n      000000000000000000000000000000000003C0000003C0000000000000000000\n      0000000000000000000000000000000000018000000180000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      00000000000000000000000000000000E0000007E00000070000000000000000\n      00000000000000000000000000000000C0000003C00000030000000000000000\n      00000000000000000000000000000000C0000003C00000030000000000000000\n      00000000000000000000000000000000C0000003C00000030000000000000000\n      00000000000000000000000000000000E0000007E00000070000000000000000\n      00000000000000000000000000000000E0000007E00000070000000000000000\n      00000000000000000000000000000000F000000FF000000F0000000000000000\n      00000000000000000000000000000000F800001FF800001F0000000000000000\n      00000000000000000000000000000000FE20047FFE20047F0000000000000000\n      00000000000000000000000000000000FFE007FFFFE007FF0000000000000000\n      00000000000000000000000000000000FFE007FFFFE007FF0000000000000000\n      00000000000000000000000000000000FFF83FFFFFF83FFFFFFFFFFFFFFFFFFF\n      FFFFFF83FFFFFF83FFFFFFFFFFFFFFFFFF8003FFFF8003FFFFC003FFFFC003FF\n      FFFFFF01FFFFFF01F0FFF0FFF0FFF0FFFF0000FFFF0000FFFFC003FFFFC003FF\n      FFFFFE00FFFFFE00E07E0007E07E0007FC00007FFC00007FFFC003FFFFC003FF\n      FFFFFC00FFFFFC00C0780001C0780001F800001FF800001FFFC003FFFFC003FF\n      FFFFFC00FFFFFC008038000180380001F000000FF000000FFFC003FFFFC003FF\n      FFFFF800FFFFF800801E0007801E0007E000000FE000000FFFC003FFFFC003FF\n      FFFFF800FFFFF800800FF00F800FF00FE0000007E0000007FFC003FFFFC003FF\n      FFFFF001FFFFF001800FE01F800FE01FC0000003C0000003FFC003FFFFC003FF\n      FFFFF003FFFFF003C007C01FC007C01FC0000003C0000003FFC003FFFFC003FF\n      FFFFE007FFFFE007E003803FE003803FC0000003C00000038000000180000001\n      FFFFE007FFFFE007F001007FF001007F80000001800000018000000180000001\n      FFFFC00FFFFFC00FFC0000FFFC0000FF80000001800000018000000180000001\n      FFFF801FFFFF801FFE0001FFFE0001FF80000001800000018000000180000001\n      FFFF003FFFFF003FFF0003FFFF0003FF04000000040000008000000180000001\n      F8FE007FF8FE007FFF8007FFFF8007FF00000000000000008000000180000001\n      F07E00FFF07E00FFFFC007FFFFC007FF00000000000000008000000180000001\n      E03801FFE03801FFFCC00FFFFCC00FFF04000000040000008000000180000001\n      C01001FFC01001FFF0000FFFF0000FFF80000001800000018000000180000001\n      C00003FFC00003FFE00007FFE00007FF80000001800000018000000180000001\n      C00007FFC00007FFC00003FFC00003FF80000001800000018000000180000001\n      C00007FFC00007FFC000807FC000807FC0000003C00000038000000180000001\n      C0000FFFC0000FFFC001C03FC001C03FC0000003C00000038000000180000001\n      E0000FFFE0000FFF8301E03F8301E03FC0000003C0000003FFC003FFFFC003FF\n      FC001FFFFC001FFF8781F01F8781F01FE0000007E0000007FFC003FFFFC003FF\n      FC00079FFC00079FCF81F00FCF81F00FF000000FF000000FFFC003FFFFC003FF\n      FE00000FFE00000FFF01F00FFF01F00FF800001FF800001FFFC003FFFFC003FF\n      FE00000FFE00000FFE03F80FFE03F80FFC00003FFC00003FFFC003FFFFC003FF\n      FF00001FFF00001FFC03FC1FFC03FC1FFE00007FFE00007FFFC003FFFFC003FF\n      FF80003FFF80003FFC0FFF3FFC0FFF3FFF0000FFFF0000FFFFC003FFFFC003FF\n      FFE0007FFFE0007FFFFFFFFFFFFFFFFFFFE007FFFFE007FFFFC003FFFFC003FF\n      FFF001FFFFF001FFFFFFFFFFFFFFFFFFFFFC3FFFFFFC3FFFFFC003FFFFC003FF\n      FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000000000000000000000000000\n      000000000000}\n  end\n  object TaskTimer: TTimer\n    Enabled = False\n    OnTimer = OnTaskTimer\n    Left = 984\n    Top = 8\n  end\n  object LogPopupMenu: TPopupMenu\n    OnPopup = LogPopupMenuPopup\n    Left = 264\n    Top = 112\n    object FilterGroupItem: TMenuItem\n      Caption = 'Filter group'\n      object TMenuItem\n      end\n    end\n    object FilterLabelItem: TMenuItem\n      Caption = 'Filter label'\n      object TMenuItem\n      end\n    end\n    object CopyToClipboardItem: TMenuItem\n      Caption = 'Copy to clipboard'\n      OnClick = CopyToClipboardItemClick\n    end\n    object ToggleAutoScrollItem: TMenuItem\n      Caption = 'Disable auto scroll'\n      OnClick = ToggleAutoScrollItemClick\n    end\n    object SaveAndClearItem: TMenuItem\n      Caption = 'Save and clear'\n      OnClick = SaveAndClearItemClick\n    end\n  end\n  object DetailsPopupMenu: TPopupMenu\n    Left = 720\n    Top = 104\n    object DetailsCopyToClipboardItem: TMenuItem\n      Caption = 'Copy to clipboard'\n      OnClick = DetailsCopyToClipboardItemClick\n    end\n  end\n  object bhBuild: TBalloonHint\n    Style = bhsStandard\n    Left = 128\n    Top = 24\n  end\n  object bhNew: TBalloonHint\n    Style = bhsStandard\n    Left = 80\n    Top = 24\n  end\n  object bhOptions: TBalloonHint\n    Style = bhsStandard\n    Left = 232\n    Top = 24\n  end\n  object bhLoadException: TBalloonHint\n    HideAfter = 12000\n    Left = 112\n    Top = 168\n  end\n  object bhManage: TBalloonHint\n    Style = bhsStandard\n    Left = 176\n    Top = 24\n  end\n  object bhQuick: TBalloonHint\n    Style = bhsStandard\n    Left = 32\n    Top = 24\n  end\nend\n"
  },
  {
    "path": "frontend/msSmashForm.pas",
    "content": "unit msSmashForm;\n\ninterface\n\nuses\n  // delphi units\n  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,\n  Buttons, ExtCtrls, ComCtrls, XPMan, StdCtrls, ImgList, CommCtrl, Menus, Grids,\n  ValEdit, ShellAPI, StrUtils, Clipbrd,\n  // indy units\n  IdBaseComponent, IdComponent, IdTCPConnection, IdTCPClient,\n  // third party libraries\n  superobject, W7Taskbar,\n  // mte components\n  mteHelpers, mteTracker, mteLogger, mteLogging, mteProgressForm,\n  mteBase, mteTaskHandler, RttiTranslation,\n  // ms units\n  msCore, msConfiguration, msLoader, msThreads, msOptionsForm,\n  msEditForm, msSettingsManager, msTagManager, msSplashForm,\n  // tes5edit units\n  wbBSA, wbHelpers, wbInterface, wbImplementation;\n\ntype\n  TSmashForm = class(TForm)\n    [FormPrefix('msMain')]\n      XPManifest: TXPManifest;\n      IconList: TImageList;\n      TaskTimer: TTimer;\n      [FormSection('QuickBar')]\n        QuickBar: TPanel;\n        QuickButton: TSpeedButton;\n        NewButton: TSpeedButton;\n        BuildButton: TSpeedButton;\n        ManageButton: TSpeedButton;\n        OptionsButton: TSpeedButton;\n        bhQuick: TBalloonHint;\n        bhNew: TBalloonHint;\n        bhBuild: TBalloonHint;\n        bhManage: TBalloonHint;\n        bhOptions: TBalloonHint;\n      [FormSection('Main Panel')]\n        MainPanel: TPanel;\n        Splitter: TSplitter;\n        PageControl: TPageControl;\n        DetailsPanel: TPanel;\n        [FormSection('Details Panel')]\n          DetailsLabel: TLabel;\n          DetailsGrid: TStringGrid;\n          DetailsPopupMenu: TPopupMenu;\n          DetailsCopyToClipboardItem: TMenuItem;\n        [FormSection('Plugins Tab')]\n          PluginsTabSheet: TTabSheet;\n          PluginsListView: TListView;\n          [FormSection('Plugins Popup Menu')]\n            PluginsPopupMenu: TPopupMenu;\n            AddToPatchItem: TMenuItem;\n            RemoveFromPatchItem: TMenuItem;\n            TagsItem: TMenuItem;\n            ManageTagsItem: TMenuItem;\n            ApplySettingTagsItem: TMenuItem;\n            ClearTagsItem: TMenuItem;\n            OpenPluginLocationItem: TMenuItem;\n            SmashSettingItem: TMenuItem;\n        [FormSection('Patches Tab')]\n          PatchesTabSheet: TTabSheet;\n          PatchesListView: TListView;\n          [FormSection('Patches Popup Menu')]\n            PatchesPopupMenu: TPopupMenu;\n            ToggleRebuildItem: TMenuItem;\n            OpenInExplorerItem: TMenuItem;\n            BuildPatchItem: TMenuItem;\n            EditPatchItem: TMenuItem;\n            RemoveUnloadedPluginsItem: TMenuItem;\n            DeletePatchItem: TMenuItem;\n            [FormSection('Move Submenu')]\n              MoveItem: TMenuItem;\n              UpItem: TMenuItem;\n              DownItem: TMenuItem;\n              ToTopItem: TMenuItem;\n              ToBottomItem: TMenuItem;\n        [FormSection('Log Tab')]\n          LogTabSheet: TTabSheet;\n          LogListView: TListView;\n          [FormSection('Log Popup Menu')]\n            LogPopupMenu: TPopupMenu;\n            FilterGroupItem: TMenuItem;\n            FilterLabelItem: TMenuItem;\n            CopyToClipboardItem: TMenuItem;\n            SaveAndClearItem: TMenuItem;\n            ToggleAutoScrollItem: TMenuItem;\n      [FormSection('Status Bar')]\n        StatusPanel: TPanel;\n        StatusPanelMessage: TPanel;\n        StatusPanelLanguage: TPanel;\n        StatusPanelVersion: TPanel;\n        ImageBuild: TImage;\n        bhLoadException: TBalloonHint;\n\n    // SMASH FORM EVENTS\n    procedure UpdateLog;\n    procedure LogMessage(const group, &label, text: string);\n    procedure ToggleFormState(bEnabled: boolean);\n    procedure FormCreate(Sender: TObject);\n    procedure InitDone;\n    procedure FormShow(Sender: TObject);\n    procedure LoaderStatus(s: string);\n    procedure LoaderDone;\n    procedure FormDestroy(Sender: TObject);\n    procedure FormCloseQuery(Sender: TObject; var CanClose: Boolean);\n    procedure SaveDone;\n    procedure ProgressDone;\n    function ShouldDisplay(bh: TBalloonHint): boolean;\n    procedure DisableHints;\n    procedure HideHints;\n    procedure DisplayHints;\n    procedure RefreshGUI;\n    procedure OnTaskTimer(Sender: TObject);\n    procedure UpdateStatusBar;\n    procedure UpdateListViews;\n    // DETAILS EDITOR EVENTS\n    procedure AddDetailsItem(name, value: string);\n    procedure AddDetailsList(name: string; sl: TStringList);\n    procedure PageControlChange(Sender: TObject);\n    procedure UpdateApplicationDetails;\n    procedure DetailsCopyToClipboardItemClick(Sender: TObject);\n    procedure DetailsPanelResize(Sender: TObject);\n    procedure DetailsGridMouseMove(Sender: TObject; Shift: TShiftState;\n      X, Y: Integer);\n    procedure DetailsGridMouseUp(Sender: TObject; Button: TMouseButton;\n      Shift: TShiftState; X, Y: Integer);\n    procedure DetailsGridDrawCell(Sender: TObject; ACol, ARow: Integer;\n      Rect: TRect; State: TGridDrawState);\n    // PLUGINS LIST VIEW EVENTS\n    procedure UpdatePluginDetails;\n    procedure AddPluginToPatch(var plugin: TPlugin; var patch: TPatch; i: Integer);\n    procedure AddPluginsToPatch(var patch: TPatch);\n    procedure ChangePatchSetting(aSetting: TSmashSetting);\n    procedure PluginsListViewChange(Sender: TObject; Item: TListItem;\n      Change: TItemChange);\n    procedure PluginsListViewData(Sender: TObject; Item: TListItem);\n    procedure PluginsListViewDrawItem(Sender: TCustomListView; Item: TListItem;\n      Rect: TRect; State: TOwnerDrawState);\n    // PLUGINS POPUP MENU EVENTS\n    procedure PluginsPopupMenuPopup(Sender: TObject);\n    procedure UpdatePluginsPopupMenu;\n    procedure AddToNewPatchClick(Sender: TObject);\n    procedure AddToPatchClick(Sender: TObject);\n    procedure ChangeSettingClick(Sender: TObject);\n    procedure RemoveFromPatchItemClick(Sender: TObject);\n    procedure OpenPluginLocationItemClick(Sender: TObject);\n    procedure ManageTagsItemClick(Sender: TObject);\n    procedure ClearTagsItemClick(Sender: TObject);\n    procedure ApplySettingTagsItemClick(Sender: TObject);\n    // SMASH LIST VIEW EVENTS\n    procedure UpdatePatchDetails;\n    procedure UpdatePatches;\n    function NewPatch: TPatch;\n    procedure PatchesListViewChange(Sender: TObject; Item: TListItem;\n      Change: TItemChange);\n    procedure PatchesListViewData(Sender: TObject; Item: TListItem);\n    procedure PatchesListViewDrawItem(Sender: TCustomListView; Item: TListItem;\n      Rect: TRect; State: TOwnerDrawState);\n    procedure PatchesListViewDblClick(Sender: TObject);\n    procedure PatchesListViewKeyDown(Sender: TObject; var Key: Word;\n      Shift: TShiftState);\n    // PATCHES POPUP MENU EVENTS\n    procedure PatchesPopupMenuPopup(Sender: TObject);\n    procedure EditPatchItemClick(Sender: TObject);\n    procedure BuildPatchItemClick(Sender: TObject);\n    procedure RemovePluginsItemClick(Sender: TObject);\n    procedure RemoveUnloadedPlugins(patch: TPatch);\n    procedure RemoveUnloadedPluginsItemClick(Sender: TObject);\n    procedure DeletePatchItemClick(Sender: TObject);\n    procedure OpenInExplorerItemClick(Sender: TObject);\n    procedure ToggleRebuildItemClick(Sender: TObject);\n    procedure UpItemClick(Sender: TObject);\n    procedure DownItemClick(Sender: TObject);\n    procedure ToTopItemClick(Sender: TObject);\n    procedure ToBottomItemClick(Sender: TObject);\n    // LOG LIST VIEW EVENTS\n    procedure LogListViewData(Sender: TObject; Item: TListItem);\n    procedure LogListViewDrawItem(Sender: TCustomListView; Item: TListItem; Rect: TRect; State: TOwnerDrawState);\n    // LOG POPUP MENU EVENTS\n    procedure LogPopupMenuPopup(Sender: TObject);\n    procedure ToggleGroupFilter(Sender: TObject);\n    procedure ToggleLabelFilter(Sender: TObject);\n    procedure CopyToClipboardItemClick(Sender: TObject);\n    procedure SaveAndClearItemClick(Sender: TObject);\n    // QUICKBAR EVENTS\n    procedure UpdateQuickbar;\n    function GetSmashedPatch: TPatch;\n    procedure StartPatching;\n    procedure QuickButtonClick(Sender: TObject);\n    procedure NewButtonClick(Sender: TObject);\n    procedure BuildButtonClick(Sender: TObject);\n    procedure ManageButtonClick(Sender: TObject);\n    procedure OptionsButtonClick(Sender: TObject);\n    procedure ToggleAutoScrollItemClick(Sender: TObject);\n  protected\n    procedure WMSize(var AMessage: TMessage); message WM_SIZE;\n    procedure WMMove(var AMessage: TMessage); message WM_MOVE;\n    procedure WMActivateApp(var AMessage: TMessage); message WM_ACTIVATEAPP;\n  private\n    { Private declarations }\n    slDetails: TStringList;\n  public\n    { Public declarations }\n  end;\n\nconst\n  MessageDelay = (0.1 / 86400.0);\n\nvar\n  splash: TSplashForm;\n  SmashForm: TSmashForm;\n  LastHint: string;\n  LastURLTime, LastMessageTime, FormDisplayTime: double;\n  bPatchesToBuild, bPatchesToCheck, bAutoScroll, bCreated, bClosing: boolean;\n  pForm: TProgressForm;\n  TaskHandler: TTaskHandler;\n\nimplementation\n\n{$R *.dfm}\n\n\n{******************************************************************************}\n{ Patch Form Events\n  Events for the Patch Form.\n  - UpdateLog\n  - LogMessage\n  - ProgressMessage\n  - FormCreate\n  - FormShow\n  - LoaderDone\n  - FormClose\n}\n{******************************************************************************}\n\nprocedure TSmashForm.UpdateLog;\nvar\n  bLogActive: boolean;\nbegin\n  LogListView.Items.Count := Log.Count;\n  bLogActive := PageControl.ActivePage = LogTabSheet;\n  // autoscroll if active\n  if bAutoScroll and bLogActive then begin\n    //LogListView.ClearSelection;\n    //LogListView.Items[Pred(LogListView.Items.Count)].MakeVisible(false);\n    SendMessage(LogListView.Handle, WM_VSCROLL, SB_LINEDOWN, 0);\n  end;\n  // correct width if active\n  if bLogActive then\n    ListView_CorrectWidth(LogListView);\nend;\n\n{ Prints a message to the log }\nprocedure TSmashForm.LogMessage(const group, &label, text: string);\nvar\n  msg: TLogMessage;\nbegin\n  msg := TLogMessage.Create(\n    FormatDateTime('hh:nn:ss', Now),\n    FormatDateTime('hh:nn:ss', Now - AppStartTime),\n    group, &label, text);\n  BaseLog.Add(msg);\n\n  // if message is enabled, add to log\n  if MessageEnabled(msg) then begin\n    Log.Add(msg);\n    // if patch form is created, update log list view\n    if bCreated then\n      UpdateLog;\n  end;\nend;\n\nprocedure ProgressMessage(const s: string);\nbegin\n  if s = '' then\n    exit;\n  Logger.Write(xEditLogGroup, xEditLogLabel, s);\nend;\n\nprocedure InitLog;\nbegin\n  BaseLog := TList.Create;\n  Log := TList.Create;\n  LabelFilters := TList.Create;\n  GroupFilters := TList.Create;\n  // INITIALIZE GROUP FILTERS\n  GroupFilters.Add(TFilter.Create('GENERAL', true));\n  GroupFilters.Add(TFilter.Create('LOAD', true));\n  GroupFilters.Add(TFilter.Create('CLIENT', true));\n  GroupFilters.Add(TFilter.Create('PATCH', true));\n  GroupFilters.Add(TFilter.Create('PLUGIN', true));\n  GroupFilters.Add(TFilter.Create('ERROR', true));\n  // INITIALIZE LABEL FILTERS\n  LabelFilters.Add(TFilter.Create('GENERAL', 'Game', true));\n  LabelFilters.Add(TFilter.Create('GENERAL', 'Status', true));\n  LabelFilters.Add(TFilter.Create('GENERAL', 'Path', true));\n  LabelFilters.Add(TFilter.Create('GENERAL', 'Definitions', true));\n  LabelFilters.Add(TFilter.Create('GENERAL', 'Dictionary', true));\n  LabelFilters.Add(TFilter.Create('GENERAL', 'Load Order', true));\n  LabelFilters.Add(TFilter.Create('GENERAL', 'Log', true));\n  LabelFilters.Add(TFilter.Create('LOAD', 'Order', false));\n  LabelFilters.Add(TFilter.Create('LOAD', 'Plugins', false));\n  LabelFilters.Add(TFilter.Create('LOAD', 'Background', true));\n  LabelFilters.Add(TFilter.Create('CLIENT', 'Connect', true));\n  LabelFilters.Add(TFilter.Create('CLIENT', 'Login', true));\n  LabelFilters.Add(TFilter.Create('CLIENT', 'Response', true));\n  LabelFilters.Add(TFilter.Create('CLIENT', 'Update', true));\n  LabelFilters.Add(TFilter.Create('CLIENT', 'Report', true));\n  LabelFilters.Add(TFilter.Create('PATCH', 'Status', false));\n  LabelFilters.Add(TFilter.Create('PATCH', 'Create', true));\n  LabelFilters.Add(TFilter.Create('PATCH', 'Edit', true));\n  LabelFilters.Add(TFilter.Create('PATCH', 'Check', true));\n  LabelFilters.Add(TFilter.Create('PATCH', 'Clean', true));\n  LabelFilters.Add(TFilter.Create('PATCH', 'Delete', true));\n  LabelFilters.Add(TFilter.Create('PATCH', 'Build', true));\n  LabelFilters.Add(TFilter.Create('PATCH', 'Report', true));\n  LabelFilters.Add(TFilter.Create('PLUGIN', 'Report', true));\n  LabelFilters.Add(TFilter.Create('PLUGIN', 'Check', true));\n  LabelFilters.Add(TFilter.Create('PLUGIN', 'Tags', false));\n  LabelFilters.Add(TFilter.Create('PLUGIN', 'Settings', true));\nend;\n\n{ Initialize form, initialize TES5Edit API, and load plugins }\nprocedure TSmashForm.FormCreate(Sender: TObject);\nbegin\n  // INITIALIAZE BASE\n  bCreated := false;\n  AppStartTime := Now;\n  InitLog;\n  Logger.OnLogEvent := LogMessage;\n  //bAutoScroll := true;\n  InitializeTaskbarAPI;\n  SetTaskbarProgressState(tbpsIndeterminate);\n  xEditLogGroup := 'LOAD';\n  xEditLogLabel := 'Plugins';\n  wbProgressCallback := ProgressMessage;\n  StatusCallback := LoaderStatus;\n\n  if not InitBase then begin\n    ProgramStatus.bClose := true;\n    exit;\n  end;\n\n  // CREATE SPLASH\n  splash := TSplashForm.Create(nil);\n  try\n    InitCallback := InitDone;\n    TInitThread.Create;\n    splash.ShowModal;\n  finally\n    splash.Free;\n  end;\n\n  // do translation dump?\n  if bTranslationDump then\n    TRttiTranslation.Save('lang\\english.lang', self);\n\n  // load language\n  TRttiTranslation.Load(language, self);\n\n  // finalize\n  bCreated := true;\nend;\n\nprocedure TSmashForm.FormDestroy(Sender: TObject);\nbegin\n  // free lists\n  FreeList(GroupFilters);\n  FreeList(LabelFilters);\n\n  // free other items\n  TryToFree(TaskHandler);\n  TryToFree(slDetails);\nend;\n\nprocedure TSmashForm.ToggleFormState(bEnabled: boolean);\nbegin\n  // show/hide hints\n  if bEnabled then\n    DisplayHints\n  else\n    HideHints;\n\n  // disable/enable form\n  Enabled := bEnabled;\nend;\n\nprocedure TSmashForm.WMSize(var AMessage: TMessage);\nbegin\n  if bCreated and (Now - LastMessageTime > MessageDelay) then begin\n    LastMessageTime := Now;\n    if (AMessage.WParam <> SIZE_MINIMIZED) then\n      DisplayHints;\n  end;\n  inherited;\nend;\n\nprocedure TSmashForm.WMMove(var AMessage: TMessage);\nbegin\n  if bCreated and (Now - LastMessageTime > MessageDelay) then begin\n    LastMessageTime := Now;\n    if (AMessage.WParam <> SIZE_MINIMIZED) then\n      DisplayHints;\n  end;\n  inherited;\nend;\n\nprocedure TSmashForm.WMActivateApp(var AMessage: TMessage);\nbegin\n  if bCreated and (Now - LastMessageTime > MessageDelay) then begin\n    LastMessageTime := Now;\n    if AMessage.WParam = 1 then\n      DisplayHints\n    else\n      HideHints;\n  end;\n  inherited;\nend;\n\nprocedure TSmashForm.InitDone;\nbegin\n  splash.ModalResult := mrOk;\nend;\n\n// Force PluginsListView to autosize columns\nprocedure TSmashForm.FormShow(Sender: TObject);\nbegin\n  // CLOSE IF PLUGIN SELECTION CANCELED\n  if ProgramStatus.bClose then begin\n    bClosing := true;\n    Close;\n    exit;\n  end;\n\n  // DISABLE GUI IF INITIALIZATION EXCEPTION\n  if ProgramStatus.bInitException then begin\n    StatusPanelMessage.Caption := 'The application failed to initialize';\n    Logger.Write('ERROR', 'Load', 'There was an exception initializing the application');\n    Logger.Write('ERROR', 'Load', 'Review your log messages to resolve the issue');\n    Logger.Write('ERROR', 'Load', 'You can also change the program''s settings, if necessary');\n    PluginsTabSheet.Enabled := false;\n    PluginsTabSheet.TabVisible := false;\n    PatchesTabSheet.Enabled := false;\n    PatchesTabSheet.TabVisible := false;\n    PageControl.ActivePage := LogTabSheet;\n  end;\n\n  // QUICKBAR\n  QuickButton.Flat := true;\n  NewButton.Flat := true;\n  BuildButton.Flat := true;\n  ManageButton.Flat := true;\n  OptionsButton.Flat := true;\n  IconList.GetBitmap(0, QuickButton.Glyph);\n  IconList.GetBitmap(1, NewButton.Glyph);\n  IconList.GetBitmap(2, BuildButton.Glyph);\n  IconList.GetBitmap(3, ManageButton.Glyph);\n  IconList.GetBitmap(4, OptionsButton.Glyph);\n\n  // STATUSBAR VALUES\n  StatusPanelLanguage.Caption := settings.language;\n  StatusPanelVersion.Caption := 'v' + ProgramStatus.Version;\n\n  // UPDATE GUI\n  slDetails := TStringList.Create;\n  PluginsListView.OwnerDraw := not settings.simplePluginsView;\n  PluginsListView.Items.Count := PluginsList.Count;\n  UpdateLog;\n  UpdatePatches;\n  UpdatePluginsPopupMenu;\n  UpdateStatusBar;\n  UpdateQuickBar;\n\n  if not ProgramStatus.bInitException then begin\n    // START BACKGROUND LOADER\n    LoaderCallback := LoaderDone;\n    SetTaskbarProgressState(tbpsIndeterminate);\n    if settings.buildRefs then\n      TLoaderThread.Create;\n\n    // CORRECT LIST VIEW WIDTHS\n    ListView_CorrectWidth(PatchesListView);\n    ListView_CorrectWidth(PluginsListView);\n\n    // LOAD AND DISPLAY HINTS\n    bhLoadException.Title := GetLanguageString('msMain_LoadException');\n    bhLoadException.Description := GetLanguageString('msMain_PluginsNotLoaded');\n    DisplayHints;\n\n    // initialize task handler\n    TaskHandler := TTaskHandler.Create;\n    bLogTasks := false;\n    TaskHandler.AddTask(TTask.Create('Disable Hints', 12.0 * seconds, DisableHints));\n    TaskHandler.AddTask(TTask.Create('Refresh GUI', 3.0 * seconds, RefreshGUI));\n    TaskTimer.Enabled := true;\n  end;\n\n  // ACTIVATE WINDOW\n  FormDisplayTime := Now;\n  ForceForeground(Handle);\n  if ProgramStatus.bInitException then\n    PageControlChange(PageControl);\n  if not settings.buildRefs then\n    LoaderDone;\nend;\n\nprocedure TSmashForm.LoaderStatus(s: string);\nbegin\n  StatusPanelMessage.Caption := s;\nend;\n\nprocedure TSmashForm.LoaderDone;\nbegin\n  wbLoaderDone := true;\n  SetTaskbarProgressState(tbpsNone);\n  xEditLogGroup := 'GENERAL';\n  xEditLogLabel := 'xEdit';\n  FlashWindow(Application.Handle, True);\n  UpdateQuickbar;\nend;\n\nprocedure TSmashForm.FormCloseQuery(Sender: TObject; var CanClose: Boolean);\nbegin\n  CanClose := ProgramStatus.bClose;\n  if not bClosing then begin\n    bClosing := true;\n    Enabled := false;\n\n    // show progress form\n    pForm := TProgressForm.Create(Self);\n    pForm.pfLogPath := LogPath + 'save\\';\n    pForm.PopupParent := Self;\n    pForm.Caption := GetLanguageString('msProg_Closing');\n    pForm.SetMaxProgress(PluginsList.Count + PatchesList.Count + 2);\n    pForm.Show;\n\n    // start save thread\n    TaskTimer.Enabled := false;\n    SaveCallback := SaveDone;\n    TSaveThread.Create;\n  end;\nend;\n\nprocedure TSmashForm.SaveDone;\nbegin\n  // clean up pForm, close form\n  pForm.SetProgress(pForm.ProgressBar.Max);\n  pForm.SaveLog;\n  pForm.Free;\n\n  // restart program if update applied\n  if ProgramStatus.bInstallUpdate then\n    ShellExecute(Application.Handle, 'runas', PChar(ParamStr(0)), '', '', SW_SHOWNORMAL);\n  // restart program if user wants patch profile change\n  if ProgramStatus.bChangeProfile then\n    ShellExecute(Application.Handle, 'runas', PChar(ParamStr(0)), '', '', SW_SHOWNORMAL);\n\n  // allow close and close\n  SaveLog(BaseLog);\n  ProgramStatus.bClose := true;\n  Close;\nend;\n\nprocedure TSmashForm.ProgressDone;\nbegin\n  xEditLogGroup := 'GENERAL';\n  pForm.SaveLog;\n  pForm.Visible := false;\n  FlashWindow(Application.Handle, True);\n  pForm.ShowModal;\n  pForm.Free;\n  Enabled := true;\n  ShowWindow(Application.Handle, SW_RESTORE);\n  SetForegroundWindow(Application.Handle);\n\n  // free lists\n  if Assigned(timeCosts) then timeCosts.Free;\n  if Assigned(pluginsToHandle) then pluginsToHandle.Free;\n  if Assigned(patchesToBuild) then patchesToBuild.Free;\n\n  // update patches and gui\n  UpdateListViews;\n  UpdatePatches;\n  UpdateQuickbar;\n  UpdatePluginsPopupMenu;\nend;\n\nfunction TSmashForm.ShouldDisplay(bh: TBalloonHint): boolean;\nbegin\n  Result := (Now - FormDisplayTime) * 86400 < (bh.HideAfter / 1000);\nend;\n\nprocedure TSmashForm.DisableHints;\nbegin\n  HideHints;\n  TaskHandler.RemoveTask('Disable Hints');\nend;\n\nprocedure TSmashForm.HideHints;\nbegin\n  bhLoadException.HideHint;\nend;\n\nprocedure TSmashForm.DisplayHints;\nvar\n  pt: TPoint;\nbegin\n  if ProgramStatus.bLoadException and ShouldDisplay(bhLoadException) then begin\n    pt.X := 126;\n    pt.Y := 16;\n    pt := MainPanel.ClientToScreen(pt);\n    bhLoadException.ShowHint(pt);\n  end;\nend;\n\nprocedure TSmashForm.RefreshGUI;\nbegin\n  if not bClosing then UpdateStatusBar;\nend;\n\nprocedure TSmashForm.OnTaskTimer(Sender: TObject);\nbegin\n  if not bClosing then\n    TaskHandler.ExecTasks;\nend;\n\nprocedure TSmashForm.UpdateStatusBar;\nbegin\n  ImageBuild.Visible := wbLoaderDone and bPatchesToBuild;\n  StatusPanelLanguage.Caption := settings.language;\nend;\n\nprocedure TSmashForm.UpdateListViews;\nbegin\n  if PageControl.ActivePage = PluginsTabSheet then begin\n    UpdatePluginDetails;\n    PluginsListView.Repaint;\n  end;\n  if PageControl.ActivePage = PatchesTabSheet then begin\n    UpdatePatchDetails;\n    PatchesListView.Repaint;\n  end;\n  if PageControl.ActivePage = LogTabSheet then\n    LogListView.Repaint;\nend;\n\n{******************************************************************************}\n{ Details Editor Events\n  Methods for helping with the DetailsGrid control.  Methods include:\n  - AddDetailsItem\n  - AddDetailsList\n  - PageControlChange\n  - UpdateApplicationDetails\n}\n{******************************************************************************}\n\n{\n   Adds a ListItem to DetailsView with @name and @value\n}\nprocedure TSmashForm.AddDetailsItem(name, value: string);\nbegin\n  slDetails.Add(name + '=' + value);\nend;\n\n{\n  Add one or more ListItem to DetailsView with @name and the values\n  in @sl\n}\nprocedure TSmashForm.AddDetailsList(name: string; sl: TStringList);\nvar\n  i: integer;\nbegin\n  if sl.Count > 0 then begin\n    for i := 0 to Pred(sl.Count) do\n      slDetails.Add(Format('%s[%d]=%s', [name, i, sl[i]]));\n  end\n  else\n    slDetails.Add(name + '= ');\nend;\n\n{\n  Switch details view when page control is changed\n}\nprocedure TSmashForm.PageControlChange(Sender: TObject);\nvar\n  ndx: integer;\nbegin\n  ndx := TPageControl(Sender).ActivePageIndex;\n  case ndx of\n    0: begin\n      UpdatePluginDetails;\n      ListView_CorrectWidth(PluginsListView);\n    end;\n    1: begin\n      UpdatePatchDetails;\n      ListView_CorrectWidth(PatchesListView);\n    end;\n    2: begin\n      UpdateApplicationDetails;\n      ListView_CorrectWidth(LogListView);\n    end;\n  end;\nend;\n\nprocedure TSmashForm.UpdateApplicationDetails;\nbegin\n  // prepare list view for application information\n  slDetails.Clear;\n  DetailsLabel.Caption := GetLanguageString('msMain_AppDetails');\n\n  // add details items\n  AddDetailsItem(GetLanguageString('msMain_Application'), 'Mator Smash');\n  AddDetailsItem(GetLanguageString('msMain_Author'), 'matortheeternal');\n  AddDetailsItem(GetLanguageString('msMain_Version'), ProgramStatus.Version);\n  AddDetailsItem(GetLanguageString('msMain_DateBuilt'), DateTimeToStr(GetLastModified(ParamStr(0))));\n  AddDetailsItem(' ', ' ');\n  AddDetailsItem(GetLanguageString('msMain_GameMode'), wbGameName);\n  AddDetailsItem(GetLanguageString('msMain_Language'), settings.language);\n  AddDetailsItem(' ', ' ');\n  AddDetailsItem(GetLanguageString('msMain_TimesRun'), IntToStr(statistics.timesRun + sessionStatistics.timesRun));\n  AddDetailsItem(GetLanguageString('msMain_PatchesBuilt'), IntToStr(statistics.patchesBuilt + sessionStatistics.patchesBuilt));\n  AddDetailsItem(GetLanguageString('msMain_PluginsSmashed'), IntToStr(statistics.pluginsPatched + sessionStatistics.pluginsPatched));\n  AddDetailsItem(GetLanguageString('msMain_SettingsSubmitted'), IntToStr(statistics.settingsSubmitted + sessionStatistics.settingsSubmitted));\n  AddDetailsItem(GetLanguageString('msMain_RecsSubmitted'), IntToStr(statistics.recsSubmitted + sessionStatistics.recsSubmitted));\n  AddDetailsItem(' ', ' ');\n  AddDetailsItem(GetLanguageString('msMain_Website'), '-');\n  AddDetailsItem(GetLanguageString('msMain_ApiCredits'), 'superobject, TurboPower Abbrevia, xEdit');\n  AddDetailsItem(GetLanguageString('msMain_xEditVersion'), xEditVersion);\n  AddDetailsItem(GetLanguageString('msMain_xEditCredits'), 'zilav, hlp, Sharlikran, ElminsterAU');\n  AddDetailsItem(GetLanguageString('msMain_Testers'), ProgramTesters);\n  AddDetailsItem(GetLanguageString('msMain_Translators'), ProgramTranslators);\n\n  // update gui\n  StringGrid_CorrectWidth(DetailsGrid);\n  DetailsGrid.RowCount := slDetails.Count;\n  DetailsGrid.Repaint;\nend;\n\nprocedure TSmashForm.DetailsCopyToClipboardItemClick(Sender: TObject);\nvar\n  i: Integer;\n  name, value, previousName, previousValue: string;\n  sl: TStringList;\nbegin\n  sl := TStringList.Create;\n\n  // build stringlist of formatted name value pairs with special formatting for\n  // empty names and empty values\n  name := ' ';\n  value := ' ';\n  for i := 0 to Pred(slDetails.Count) do begin\n    previousName := name;\n    name := slDetails.Names[i];\n    previousValue := value;\n    value := slDetails.ValueFromIndex[i];\n    if (name <> ' ') then\n      sl.Add(Format('%s: %s', [name, value]))\n    else if (value <> ' ') then begin\n      if (previousName <> ' ') then begin\n        sl[sl.Count - 1] := previousName + ':';\n        sl.Add('- '+previousValue);\n      end;\n      sl.Add('- '+value);\n    end\n    else\n      sl.Add(' ');\n  end;\n\n  // copy to clipboard\n  Clipboard.AsText := sl.Text;\n  sl.Free;\nend;\n\n{ Resize StringGrid columns when parent panel changes size }\nprocedure TSmashForm.DetailsPanelResize(Sender: TObject);\nbegin\n  StringGrid_CorrectWidth(DetailsGrid);\nend;\n\n{ Make cursor pointer if mouse is over a URL }\nprocedure TSmashForm.DetailsGridMouseMove(Sender: TObject; Shift: TShiftState;\n  X, Y: Integer);\nvar\n  ACol, ARow: integer;\n  value: string;\nbegin\n  // don't change cursor if in help mode\n  if Screen.Cursor = crHelp then\n    exit;\n\n  DetailsGrid.MouseToCell(X, Y, ACol, ARow);\n  // use default cursor on cells in column 0, or at an invalid cell\n  if (ACol = 0) or (ARow > Pred(slDetails.Count)) then begin\n    Screen.Cursor := crDefault;\n    exit;\n  end;\n\n  // test if cell is a url\n  value := slDetails.ValueFromIndex[ARow];\n  if IsURL(value) then\n    Screen.Cursor := crHandPoint\n  else\n    Screen.Cursor := crDefault;\nend;\n\n{ Handle user clicking URL }\nprocedure TSmashForm.DetailsGridMouseUp(Sender: TObject; Button: TMouseButton;\n  Shift: TShiftState; X, Y: Integer);\nvar\n  ACol, ARow: integer;\n  value: string;\nbegin\n  // only process left clicks\n  if Button <> mbLeft then\n    exit;\n\n  DetailsGrid.MouseToCell(X, Y, ACol, ARow);\n  // skip clicks on cells in column 0\n  if ACol = 0 then\n    exit;\n\n  try\n    value := slDetails.ValueFromIndex[ARow];\n    if IsURL(value) and ((Now - LastURLTime) * 86400 > 1.0) then begin\n      ShellExecute(0, 'open', PChar(value), '', '', SW_SHOWNORMAL);\n      LastURLTime := Now;\n    end;\n  except\n    // invalid cell\n  end;\nend;\n\n{ Handle drawing of a cell }\nprocedure TSmashForm.DetailsGridDrawCell(Sender: TObject; ACol, ARow: Integer;\n  Rect: TRect; State: TGridDrawState);\nvar\n  sText, sNextVal, sNextName: string;\n  iHalfBottom, iPadding: Integer;\nbegin\n  // initialize stuff\n  sText := ' ';\n  iPadding := (Rect.Bottom - Rect.Top) - DetailsGrid.Canvas.TextHeight('Hg');\n  iHalfBottom := Rect.Top + (Rect.Bottom - Rect.Top) div 2;\n  DetailsGrid.Font.Style := [];\n  DetailsGrid.Font.Color := clBlack;\n\n  // draw name\n  if ACol = 0 then begin\n    DetailsGrid.Canvas.Brush.Color := TColor($00f6f4f3);\n    DetailsGrid.Canvas.Rectangle(Rect);\n    DetailsGrid.Canvas.Brush.Color := clWindow;\n    DetailsGrid.Canvas.Rectangle(Rect.Left, Rect.Top, Rect.Right, iHalfBottom);\n\n    if Assigned(slDetails) and (slDetails.Count > ARow) then\n      sText := slDetails.Names[ARow];\n    // handle lists\n    sText := RemoveFromEnd(sText, '[0]');\n    if StrEndsWith(sText, ']') then\n      exit;\n\n    DetailsGrid.Canvas.Brush.Style := bsClear;\n    DetailsGrid.Canvas.TextOut(Rect.Left + 4, Rect.Top + (iPadding div 2), sText);\n  end\n  // draw value\n  else if ACol = 1 then begin\n    DetailsGrid.Canvas.Brush.Color := clWindow;\n    DetailsGrid.Canvas.Rectangle(Rect);\n\n    if Assigned(slDetails) and (slDetails.Count > ARow) then\n      sText := slDetails.ValueFromIndex[ARow];\n    // handle special drawing of urls and master files\n    if (Pred(slDetails.Count) > ARow) then begin\n      sNextVal := slDetails.ValueFromIndex[ARow + 1];\n      sNextName := slDetails.Names[ARow + 1];\n      // urls blue and underlined\n      if IsURL(sNextVal) then begin\n        DetailsGrid.Font.Style := [fsUnderline];\n        DetailsGrid.Font.Color := clBlue;\n      end\n      // esps and esms red if not loaded\n      else if Pos('Plugins[', sNextName) = 1 then begin\n        if not Assigned(PluginByFileName(sNextVal)) then\n          DetailsGrid.Font.Color := clRed;\n      end;\n    end;\n\n    // draw text\n    DetailsGrid.Canvas.Brush.Style := bsClear;\n    DetailsGrid.Canvas.TextOut(Rect.Left + 4, Rect.Top + (iPadding div 2), sText);\n  end;\nend;\n\n{******************************************************************************}\n{ PluginsListView Events\n  Events involving the PluginsListView control.  Events include:\n  - UpdatePluginDetails\n  - PluginsListViewChange\n  - PluginsListViewData\n  - FlagNotSafe\n  - DrawFlag\n  - DrawPluginFlags\n  - PluginsListViewDrawItem\n  - PluginsListViewMouseMove\n}\n{******************************************************************************}\n\nprocedure TSmashForm.UpdatePluginDetails;\nvar\n  plugin: TPlugin;\n  index: integer;\nbegin\n  // don't do anything if no item selected\n  if not Assigned(PluginsListView.Selected) then\n    exit;\n\n  // prepare list view for plugin information\n  slDetails.Clear;\n  DetailsLabel.Caption := GetLanguageString('msMain_PluginDetails');\n\n  // get plugin information\n  index := PluginsListView.ItemIndex;\n  plugin := TPlugin(PluginsList[index]);\n  if not plugin.hasData then plugin.GetData(PluginsList);\n\n  // add details items\n  AddDetailsItem(GetLanguageString('msMain_Filename'), plugin.filename);\n  AddDetailsItem(GetLanguageString('msMain_Hash'), '$' + plugin.hash);\n  AddDetailsItem(GetLanguageString('msMain_FileSize'), FormatByteSize(plugin.fileSize));\n  AddDetailsItem(GetLanguageString('msMain_DateModified'), plugin.dateModified);\n  AddDetailsItem(GetLanguageString('msMain_NumRecords'), IntToStr(plugin.numRecords));\n  AddDetailsItem(GetLanguageString('msMain_NumOverrides'), IntToStr(plugin.numOverrides));\n  AddDetailsItem(GetLanguageString('msMain_Author'), plugin.author);\n  AddDetailsList(GetLanguageString('msMain_Description'), plugin.description);\n  AddDetailsList(GetLanguageString('msMain_Masters'), plugin.masters);\n\n  // update gui\n  StringGrid_CorrectWidth(DetailsGrid);\n  DetailsGrid.RowCount := slDetails.Count;\n  DetailsGrid.Repaint;\nend;\n\nprocedure TSmashForm.ChangePatchSetting(aSetting: TSmashSetting);\nvar\n  i: Integer;\n  ListItem: TListItem;\n  plugin: TPlugin;\nbegin\n  // loop through plugins list, adding selected plugins to patch\n  for i := 0 to Pred(PluginsListView.Items.Count) do begin\n    ListItem := PluginsListView.Items[i];\n    if not ListItem.Selected then\n      continue;\n    plugin := TPlugin(PluginsList[i]);\n    plugin.setting := aSetting.name;\n    plugin.smashSetting := aSetting;\n  end;\n\n  // update and repaint\n  UpdatePatches;\n  UpdateListViews;\n  UpdateQuickbar;\n  UpdateStatusBar;\nend;\n\nprocedure TSmashForm.AddPluginToPatch(var plugin: TPlugin; var patch: TPatch; i: Integer);\nbegin\n  Logger.Write('PLUGIN', 'Patch', 'Added '+plugin.filename+' to patch '+patch.name);\n  if not plugin.hasData then\n    plugin.GetData(PluginsList);\n  if plugin.patch = patch.name then\n    exit;\n  patch.plugins.AddObject(plugin.filename, TObject(i));\n  plugin.patch := patch.name;\nend;\n\nprocedure TSmashForm.AddPluginsToPatch(var patch: TPatch);\nvar\n  i: integer;\n  ListItem: TListItem;\n  plugin: TPlugin;\nbegin\n  // loop through plugins list, adding selected plugins to patch\n  for i := 0 to Pred(PluginsListView.Items.Count) do begin\n    ListItem := PluginsListView.Items[i];\n    if not ListItem.Selected then\n      continue;\n    plugin := TPlugin(PluginsList[i]);\n    if plugin.patch <> ' ' then\n      continue;\n    AddPluginToPatch(plugin, patch, i);\n  end;\n\n  // update and repaint\n  UpdatePatches;\n  UpdateListViews;\n  UpdateQuickbar;\n  UpdateStatusBar;\nend;\n\nprocedure TSmashForm.PluginsListViewChange(Sender: TObject; Item: TListItem;\n  Change: TItemChange);\nbegin\n  UpdatePluginDetails;\nend;\n\nprocedure TSmashForm.PluginsListViewData(Sender: TObject; Item: TListItem);\nvar\n  plugin: TPlugin;\nbegin\n  if Item.Index > Pred(PluginsList.Count) then\n    exit;\n  plugin := TPlugin(PluginsList[Item.Index]);\n  Item.Caption := IntToHex(Item.Index, 2);\n  Item.SubItems.Add(plugin.filename);\n  Item.SubItems.Add(plugin.setting);\n  Item.SubItems.Add(plugin.patch);\n  if Assigned(plugin.smashSetting) then\n    PluginsListView.Canvas.Font.Color := plugin.smashSetting.color\n  else\n    PluginsListView.Canvas.Font.Color := clGray;\n  PluginsListView.Canvas.Font.Style := PluginsListView.Canvas.Font.Style + [fsBold];\nend;\n\nprocedure TSmashForm.PluginsListViewDrawItem(Sender: TCustomListView;\n  Item: TListItem; Rect: TRect; State: TOwnerDrawState);\nvar\n  i, x, y: integer;\n  ListView: TListView;\n  R: TRect;\nbegin\n  ListView := TListView(Sender);\n  if Item.Selected then begin\n    ListView.Canvas.Brush.Color := $FFEEDD;\n    ListView.Canvas.FillRect(Rect);\n  end;\n\n  R := Rect;\n  R.Right := R.Left + ListView.Columns[0].Width - 3;\n  x := Rect.Left + 3;\n  y := (Rect.Bottom - Rect.Top - ListView.Canvas.TextHeight('Hg')) div 2 + Rect.Top;\n  ListView.Canvas.TextRect(R, x, y, Item.Caption);\n  for i := 0 to Item.SubItems.Count - 1 do begin\n    R.Left := R.Right + 3;\n    // fixes drawing bug\n    R.Right := R.Left + ListView_GetColumnWidth(ListView.Handle, ListView.Columns[i + 1].Index);\n    x := R.Left;\n    ListView.Canvas.TextRect(R, x, y, Item.SubItems[i]);\n  end;\nend;\n\n{******************************************************************************}\n{ Plugins Popup Menu methods\n  Methods for dealing with the popup menu for the PluginsListView.\n  - PluginsPopupMenuPopup\n  - UpdatePluginsPopupMenu\n  - AddToPatchClick\n  - AddToNewPatchClick\n  - CheckForErrorsClick\n  - RemoveFromPatchClick\n}\n{******************************************************************************}\n\nprocedure TSmashForm.PluginsPopupMenuPopup(Sender: TObject);\nvar\n  i: integer;\n  bPluginInPatch, bHasSelection, bAllPluginsInPatch, bAllHaveTags: boolean;\n  ListItem: TListItem;\n  plugin: TPlugin;\nbegin\n  // initialize selection booleans\n  bHasSelection := false;\n  bPluginInPatch := false;\n  bAllPluginsInPatch := true;\n  bAllHaveTags := true;\n\n  // loop through selection\n  for i := 0 to Pred(PluginsListView.Items.Count) do begin\n    ListItem := PluginsListView.Items[i];\n    if not ListItem.Selected then\n      continue;\n\n    plugin := PluginsList[i];\n    bHasSelection := true;\n    bAllHaveTags := bAllHaveTags and plugin.HasTags;\n    bPluginInPatch := bPluginInPatch or plugin.IsInPatch;\n    bAllPluginsInPatch := bAllPluginsInPatch and plugin.IsInPatch;\n  end;\n\n  // disable/enable menu items\n  AddToPatchItem.Enabled := bHasSelection and not bPluginInPatch;\n  SmashSettingItem.Enabled := bHasSelection;\n  OpenPluginLocationItem.Enabled := bHasSelection;\n  RemoveFromPatchItem.Enabled := bHasSelection and bAllPluginsInPatch;\n  TagsItem.Enabled := bHasSelection and settings.allowTagging;\n  ClearTagsItem.Enabled := bHasSelection and bAllHaveTags;\nend;\n\nprocedure TSmashForm.UpdatePluginsPopupMenu;\nvar\n  i, index: Integer;\n  patch: TPatch;\n  aSetting: TSmashSetting;\n  MenuItem, GroupItem: TMenuItem;\n  sGroup: String;\nbegin\n  // clear submenus\n  AddToPatchItem.Clear;\n  SmashSettingItem.Clear;\n\n  // add <New Patch> option to Plugins popup menu\n  MenuItem := TMenuItem.Create(AddToPatchItem);\n  MenuItem.Caption := GetLanguageString('msMain_NewPatchItem_Caption');\n  MenuItem.OnClick := AddToNewPatchClick;\n  AddToPatchItem.Add(MenuItem);\n\n  // add patches to submenu\n  for i := 0 to Pred(PatchesList.Count) do begin\n    patch := TPatch(PatchesList[i]);\n    MenuItem := TMenuItem.Create(AddToPatchItem);\n    MenuItem.Caption := patch.name;\n    MenuItem.OnClick := AddToPatchClick;\n    AddToPatchItem.Add(MenuItem);\n  end;\n\n  // add smash settings to submenu\n  for i := 0 to Pred(SmashSettings.Count) do begin\n    aSetting := TSmashSetting(SmashSettings[i]);\n\n    // parse setting group\n    sGroup := 'Ungrouped';\n    index := Pos('.', aSetting.name);\n    if (index > 0) and (index < 11) then\n      sGroup := Copy(aSetting.name, 1, index - 1);\n\n    // get group menu item or create it if missing\n    GroupItem := SmashSettingItem.Find(sGroup);\n    if not Assigned(GroupItem) then begin\n      GroupItem := TMenuItem.Create(SmashSettingItem);\n      GroupItem.Caption := sGroup;\n      SmashSettingItem.Add(GroupItem);\n    end;\n\n    // create MenuItem\n    MenuItem := TMenuItem.Create(GroupItem);\n    MenuItem.Caption := aSetting.name;\n    MenuItem.OnClick := ChangeSettingClick;\n    GroupItem.Add(MenuItem);\n  end;\nend;\n\nprocedure TSmashForm.AddToPatchClick(Sender: TObject);\nvar\n  MenuItem: TMenuItem;\n  patch: TPatch;\n  name: String;\nbegin\n  MenuItem := TMenuItem(Sender);\n  name := StripHotkey(MenuItem.Caption);\n  patch := TPatchHelpers.PatchByName(PatchesList, name);\n  if Assigned(patch) then\n    AddPluginsToPatch(patch)\n  else begin\n    ToggleFormState(false);\n    ShowMessage('Error: Could not find patch '+name);\n    ToggleFormState(true);\n  end;\n\nend;\n\nprocedure TSmashForm.ChangeSettingClick(Sender: TObject);\nvar\n  MenuItem: TMenuItem;\n  aSetting: TSmashSetting;\n  name: String;\nbegin\n  MenuItem := TMenuItem(Sender);\n  name := StripHotkey(MenuItem.Caption);\n  aSetting := TSettingHelpers.SettingByName(name);\n  if Assigned(aSetting) then\n    ChangePatchSetting(aSetting)\n  else begin\n    ToggleFormState(false);\n    ShowMessage('Error: Could not find setting '+name);\n    ToggleFormState(true);\n  end;\nend;\n\nprocedure TSmashForm.AddToNewPatchClick(Sender: TObject);\nvar\n  patch: TPatch;\nbegin\n  patch := NewPatch;\n  if Assigned(patch) then\n    AddPluginsToPatch(patch);\nend;\n\nprocedure TSmashForm.ManageTagsItemClick(Sender: TObject);\nvar\n  i: integer;\n  ListItem: TListItem;\n  tmForm: TTagManager;\n  plugin: TPlugin;\nbegin\n  for i := 0 to Pred(PluginsListView.Items.Count) do begin\n    // only process selected list items\n    ListItem := PluginsListView.Items[i];\n    if not ListItem.Selected then\n      continue;\n\n    // create a tag manager instance for the plugin\n    plugin := TPlugin(PluginsList[i]);\n    tmForm := TTagManager.Create(self);\n    try\n      tmForm.plugin := plugin;\n      tmForm.ShowModal;\n    finally\n      tmForm.Free;\n    end;\n  end;\n\n  // update\n  UpdatePatches;\n  UpdateListViews;\n  UpdateQuickbar;\n  UpdateStatusBar;\nend;\n\nprocedure TSmashForm.ApplySettingTagsItemClick(Sender: TObject);\nvar\n  i: integer;\n  ListItem: TListItem;\n  plugin: TPlugin;\nbegin\n  for i := 0 to Pred(PluginsListView.Items.Count) do begin\n    // only process selected list items\n    ListItem := PluginsListView.Items[i];\n    if not ListItem.Selected then\n      continue;\n\n    // create a tag manager instance for the plugin\n    plugin := TPlugin(PluginsList[i]);\n    plugin.ApplySettingTags;\n    plugin.Save;\n  end;\n\n  // update\n  UpdatePatches;\n  UpdateListViews;\n  UpdateQuickbar;\n  UpdateStatusBar;\nend;\n\nprocedure TSmashForm.ClearTagsItemClick(Sender: TObject);\nvar\n  i: integer;\n  ListItem: TListItem;\n  pluginNames: String;\n  plugin: TPlugin;\n  pluginsToClear: TList;\n  bApproved: Boolean;\n  frmDialog: TForm;\nbegin\n  // initialize variables\n  bApproved := false;\n  pluginsToClear := TList.Create;\n  pluginNames := '';\n\n  // use a try-finally to make certain the list is freed\n  try\n    // add selected list items to the list\n    for i := 0 to Pred(PluginsListView.Items.Count) do begin\n      ListItem := PluginsListView.Items[i];\n      if ListItem.Selected then begin\n        plugin := TPlugin(PluginsList[i]);\n        pluginsToClear.Add(plugin);\n        pluginNames := pluginNames + #13#10'    - ' + plugin.filename;\n      end;\n    end;\n\n    // prompt user if a plugin was selected\n    if pluginsToClear.Count > 0 then begin\n      frmDialog := CreateMessageDialog(GetLanguageString('msMain_ClearTags') +\n        pluginNames, mtConfirmation, mbOKCancel, mbOk);\n      frmDialog.PopupParent := self;\n      ToggleFormState(false);\n      bApproved := frmDialog.ShowModal = mrOk;\n      ToggleFormState(true);\n    end;\n\n    // exit if user didn't approve clearing tags\n    if not bApproved then\n      exit;\n\n    // clear tags on plugins in the list\n    for i := 0 to Pred(pluginsToClear.Count) do begin\n      plugin := TPlugin(pluginsToClear[i]);\n      Logger.Write('PLUGIN', 'Tags', 'Clearing tags on '+plugin.filename);\n      plugin.description.Text := ClearTags(plugin.description.Text);\n      plugin.GetSettingTag;\n      plugin.WriteDescription;\n      // plugin.Save;\n    end;\n\n    // update\n    UpdatePatches;\n    UpdateListViews;\n    UpdateQuickbar;\n    UpdateStatusBar;\n  finally\n    pluginsToClear.Free;\n  end;\nend;\n\n{ Remove from Patch }\nprocedure TSmashForm.RemoveFromPatchItemClick(Sender: TObject);\nvar\n  i: integer;\n  ListItem: TListItem;\n  pluginName, patchName: string;\n  patch: TPatch;\n  plugin: TPlugin;\nbegin\n  for i := 0 to Pred(PluginsListView.Items.Count) do begin\n    // only process selected list items\n    ListItem := PluginsListView.Items[i];\n    if not ListItem.Selected then\n      continue;\n\n    // get plugin associated with patch item and remove it from patch\n    plugin := TPlugin(PluginsList[i]);\n    pluginName := plugin.filename;\n    patchName := plugin.patch;\n    if patchName <> ' ' then begin\n      patch := TPatchHelpers.PatchByName(PatchesList, patchName);\n      if Assigned(patch) then\n        patch.plugins.Delete(patch.plugins.IndexOf(pluginName));\n    end;\n    plugin.patch := ' ';\n  end;\n\n  // update\n  UpdatePatches;\n  UpdateListViews;\n  UpdateQuickbar;\n  UpdateStatusBar;\nend;\n\nprocedure TSmashForm.OpenPluginLocationItemClick(Sender: TObject);\nvar\n  i: integer;\n  listItem: TListItem;\n  plugin: TPlugin;\nbegin\n  for i := 0 to Pred(PluginsListView.Items.Count) do begin\n    // only process selected list items\n    ListItem := PluginsListView.Items[i];\n    if not ListItem.Selected then\n      continue;\n\n    // open plugin location in explorer if it exists\n    plugin := TPlugin(PluginsList[i]);\n    if DirectoryExists(plugin.dataPath) then\n      ShellExecute(0, 'open', PChar(plugin.dataPath), '', '', SW_SHOWNORMAL);\n  end;\nend;\n\n{******************************************************************************}\n{ Patch List View Events\n  Events involving the PatchesListView control.  Events include:\n  - UpdatePatchDetails\n  - UpdatePatches\n  - PatchesListViewChange\n  - PatchesListViewData\n  - PatchesListViewDrawItem\n  - SavePatchEdit\n}\n{******************************************************************************}\n\nprocedure TSmashForm.UpdatePatchDetails;\nvar\n  patchItem: TListItem;\n  patch: TPatch;\nbegin\n  // don't do anything if no item selected\n  patchItem := PatchesListView.Selected;\n  if not Assigned(patchItem) then\n    exit;\n\n  // prepare list view for patch information\n  slDetails.Clear;\n  DetailsLabel.Caption := GetLanguageString('msMain_PatchDetails');\n\n  // get patch information\n  patch := PatchesList[PatchesListView.ItemIndex];\n  AddDetailsItem(GetLanguageString('msMain_Status'), StatusArray[Ord(patch.status)].desc);\n  AddDetailsItem(GetLanguageString('msMain_PatchName'), patch.name);\n  AddDetailsItem(GetLanguageString('msMain_Filename'), patch.filename);\n  AddDetailsItem(GetLanguageString('msMain_PluginCount'), IntToStr(patch.plugins.Count));\n  AddDetailsItem(GetLanguageString('msMain_DateBuilt'), DateBuiltString(patch.dateBuilt));\n  AddDetailsList(GetLanguageString('msMain_Plugins'), patch.plugins);\n  AddDetailsItem(' ', ' ');\n  if patch.fails.Count < 250 then\n    AddDetailsList(GetLanguageString('msMain_Fails'), patch.fails)\n  else\n    AddDetailsItem(GetLanguageString('msMain_Fails'), GetLanguageString('msMain_TooManyFails'));\n\n  // update gui\n  StringGrid_CorrectWidth(DetailsGrid);\n  DetailsGrid.RowCount := slDetails.Count;\n  DetailsGrid.Repaint;\nend;\n\nprocedure TSmashForm.UpdatePatches;\nvar\n  i: integer;\n  patch: TPatch;\nbegin\n  // update patch count\n  PatchesListView.Items.Count := PatchesList.Count;\n\n  for i := 0 to Pred(PatchesList.Count) do begin\n    patch := TPatch(PatchesList[i]);\n    // sort plugins in patch\n    patch.SortPlugins;\n    // get status of each patch\n    if not ((patch.status in ForcedStatuses)\n    or (patch.status in FailedStatuses)) then\n      patch.GetStatus;\n  end;\nend;\n\nfunction TSmashForm.NewPatch: TPatch;\nvar\n  patch: TPatch;\n  EditPatch: TEditForm;\nbegin\n  Result := nil;\n  patch := TPatchHelpers.CreateNewPatch(PatchesList);\n\n  // edit patch immediately after its creation\n  EditPatch := TEditForm.Create(Self);\n  EditPatch.patch := patch;\n  if EditPatch.ShowModal = mrOk then begin\n    patch := EditPatch.patch;\n    LogMessage('PATCH', 'New', 'Created new patch '+patch.name);\n    // add patch to list and update views\n    PatchesList.Add(patch);\n    UpdatePatches;\n    PatchesListView.Repaint;\n    UpdatePluginsPopupMenu;\n    // set result\n    Result := patch;\n  end;\n\n  // add and update patch\n  EditPatch.Free;\nend;\n\nprocedure TSmashForm.PatchesListViewChange(Sender: TObject; Item: TListItem;\n  Change: TItemChange);\nbegin\n  UpdatePatchDetails;\nend;\n\nprocedure TSmashForm.PatchesListViewData(Sender: TObject; Item: TListItem);\nvar\n  patch: TPatch;\nbegin\n  if Item.Index > Pred(PatchesList.Count) then\n    exit;\n  patch := TPatch(PatchesList[Item.Index]);\n  Item.Caption := IntToHex(Item.Index, 2);\n  Item.SubItems.Add(patch.name);\n  Item.SubItems.Add(patch.filename);\n  Item.SubItems.Add(IntToStr(patch.plugins.count));\n  Item.SubItems.Add(DateBuiltString(patch.dateBuilt));\n  PatchesListView.Canvas.Font.Color := StatusArray[Ord(patch.status)].color;\n  PatchesListView.Canvas.Font.Style := PatchesListView.Canvas.Font.Style + [fsBold];\nend;\n\nprocedure TSmashForm.PatchesListViewDrawItem(Sender: TCustomListView;\n  Item: TListItem; Rect: TRect; State: TOwnerDrawState);\nvar\n  i, x, y: integer;\n  ListView: TListView;\n  R: TRect;\nbegin\n  ListView := TListView(Sender);\n  if Item.Selected then begin\n    ListView.Canvas.Brush.Color := $FFEEDD;\n    ListView.Canvas.FillRect(Rect);\n  end;\n\n  R := Rect;\n  R.Right := R.Left + ListView.Columns[0].Width - 3;\n  x := Rect.Left + 3;\n  y := (Rect.Bottom - Rect.Top - ListView.Canvas.TextHeight('Hg')) div 2 + Rect.Top;\n  ListView.Canvas.TextRect(R, x, y, Item.Caption);\n  for i := 0 to Item.SubItems.Count - 1 do begin\n    R.Left := R.Right + 3;\n    // fixes drawing error\n    R.Right := R.Left + ListView_GetColumnWidth(ListView.Handle, ListView.Columns[i + 1].Index);\n    x := R.Left;\n    ListView.Canvas.TextRect(R, x, y, Item.SubItems[i]);\n  end;\nend;\n\n\n{******************************************************************************}\n{ LogListView methods\n}\n{******************************************************************************}\n\nprocedure TSmashForm.LogListViewData(Sender: TObject; Item: TListItem);\nvar\n  msg: TLogMessage;\nbegin\n  if (Item.Index > Pred(Log.Count)) then\n    exit;\n  msg := TLogMessage(Log[Item.Index]);\n  Item.Caption := msg.time;\n  Item.SubItems.Add(msg.appTime);\n  Item.SubItems.Add(msg.group);\n  Item.SubItems.Add(msg.&label);\n  Item.SubItems.Add(msg.text);\n\n  // handle coloring\n  if (msg.group = 'GENERAL') then\n    LogListView.Canvas.Font.Color := settings.generalMessageColor\n  else if (msg.group = 'LOAD') then\n    LogListView.Canvas.Font.Color := settings.loadMessageColor\n  else if (msg.group = 'CLIENT') then\n    LogListView.Canvas.Font.Color := settings.clientMessageColor\n  else if (msg.group = 'PATCH') then\n    LogListView.Canvas.Font.Color := settings.patchMessageColor\n  else if (msg.group = 'PLUGIN') then\n    LogListView.Canvas.Font.Color := settings.pluginMessageColor\n  else if (msg.group = 'ERROR') then\n    LogListView.Canvas.Font.Color := settings.errorMessageColor;\nend;\n\nprocedure TSmashForm.LogListViewDrawItem(Sender: TCustomListView;\n  Item: TListItem; Rect: TRect; State: TOwnerDrawState);\nvar\n  i, x, y: integer;\n  ListView: TListView;\n  R: TRect;\n  msg: string;\n  map: TStringList;\nbegin\n  ListView := TListView(Sender);\n  if Item.Selected then begin\n    ListView.Canvas.Brush.Color := $FFEEDD;\n    ListView.Canvas.FillRect(Rect);\n  end;\n\n  // prepare map\n  map := TStringList.Create;\n  map.Values[ListView.Columns[0].Caption] := Item.Caption;\n  for i := 0 to Pred(Item.SubItems.Count) do\n    map.Values[ListView.Columns[i + 1].Caption] := Item.SubItems[i];\n\n  // prepare text rect\n  R := Rect;\n  R.Right := R.Left + ListView.Width - 3;\n  x := Rect.Left + 3;\n  y := (Rect.Bottom - Rect.Top - ListView.Canvas.TextHeight('Hg')) div 2 + Rect.Top;\n\n  // draw message\n  msg := ApplyTemplate(settings.logMessageTemplate, map);\n  ListView.Canvas.TextRect(R, x, y, msg);\n\n  // clean up\n  map.Free;\nend;\n\n\n{******************************************************************************}\n{ Log Popup Menu events\n  - LogPopupMenuPopup\n  - FilterInitItemClick\n  - FilterSqlItemClick\n  - FilterServerItemClick\n  - FilterDataItemClick\n  - FilterErrorItemClick\n  - CopyToClipboardItemClick\n  - SaveAndClearItemClick\n}\n{******************************************************************************}\n\nfunction EnableStr(var b: boolean): string;\nbegin\n  Result := IfThen(not b, GetLanguageString('msMain_Enable'), GetLanguageString('msMain_Disable'));\nend;\n\nprocedure TSmashForm.LogPopupMenuPopup(Sender: TObject);\nvar\n  i: Integer;\n  item: TMenuItem;\n  filter: TFilter;\nbegin\n  // rebuild group filter items\n  FilterGroupItem.Clear;\n  for i := 0 to Pred(GroupFilters.Count) do begin\n    filter := TFilter(GroupFilters[i]);\n    item := TMenuItem.Create(FilterGroupItem);\n    item.Caption := EnableStr(filter.enabled) + ' ' + filter.group;\n    item.OnClick := ToggleGroupFilter;\n    FilterGroupItem.Add(item);\n  end;\n\n  // rebuild label filter items\n  FilterLabelItem.Clear;\n  for i := 0 to Pred(LabelFilters.Count) do begin\n    filter := TFilter(LabelFilters[i]);\n    item := TMenuItem.Create(FilterLabelItem);\n    item.Caption := Format('%s %s, %s', [EnableStr(filter.enabled), filter.group, filter.&label]);\n    item.OnClick := ToggleLabelFilter;\n    FilterLabelItem.Add(item);\n  end;\n\n  // toggle copy to clipboard item based on whether or not log items are selected\n  CopyToClipboardItem.Enabled := Assigned(LogListView.Selected);\n\n  // rename toggle auto scroll item based on whether or not auto scroll is enabled\n  ToggleAutoScrollItem.Caption := Format('%s %s', [EnableStr(bAutoScroll), GetLanguageString('msMain_AutoScroll')]);\nend;\n\n// toggles a group filter for the LogListView\nprocedure TSmashForm.ToggleGroupFilter(Sender: TObject);\nvar\n  index: integer;\n  filter: TFilter;\nbegin\n  index := FilterGroupItem.IndexOf(TMenuItem(Sender));\n  filter := GroupFilters[index];\n  filter.enabled := not filter.enabled;\n  LogListView.Items.Count := 0;\n  RebuildLog;\n  LogListView.Items.Count := Log.Count;\n  ListView_CorrectWidth(LogListView);\nend;\n\n// toggles a label filter for the LogListView\nprocedure TSmashForm.ToggleLabelFilter(Sender: TObject);\nvar\n  index: integer;\n  filter: TFilter;\nbegin\n  index := FilterLabelItem.IndexOf(TMenuItem(Sender));\n  filter := LabelFilters[index];\n  filter.enabled := not filter.enabled;\n  LogListView.Items.Count := 0;\n  RebuildLog;\n  LogListView.Items.Count := Log.Count;\n  ListView_CorrectWidth(LogListView);\nend;\n\n// toggles auto scroll for the LogListView\nprocedure TSmashForm.ToggleAutoScrollItemClick(Sender: TObject);\nbegin\n  bAutoScroll := not bAutoScroll;\nend;\n\nprocedure TSmashForm.CopyToClipboardItemClick(Sender: TObject);\nvar\n  i: Integer;\n  sl: TStringList;\n  msg: TLogMessage;\nbegin\n  sl := TStringList.Create;\n\n  // put selected messages in stringlist\n  for i := 0 to Pred(Log.Count) do begin\n    if not LogListView.Items[i].Selected then\n      continue;\n\n    msg := TLogMessage(Log[i]);\n    sl.Add(Format('[%s] (%s) %s: %s', [msg.time, msg.group, msg.&label, msg.text]));\n  end;\n\n  // put stringlist in clipboard, then free\n  Clipboard.AsText := sl.Text;\n  sl.Free;\nend;\n\nprocedure TSmashForm.SaveAndClearItemClick(Sender: TObject);\nbegin\n  SaveLog(BaseLog);\n  LogListView.Items.Count := 0;\n  BaseLog.Clear;\n  Log.Clear;\n  LogMessage('GENERAL', 'Log', 'Saved and cleared log.');\nend;\n\n\n{******************************************************************************}\n{ PatchesPopupMenu methods\n  Methods for dealing with the popup menu for the PatchesListView.\n  - PatchesPopupMenuPopup\n  - EditPatchItemClick\n  - CheckPluginsForErrorsItemClick\n  - DeletePatchItemClick\n  - RebuildPatchItemClick\n  - ReportOnPatchItemClick\n  - OpenInExplorerItemClick\n  - ForceRebuildItemClick\n  - IgnoreRebuildItemClick\n  - PatchesListViewDblClick\n  - PatchesListViewKeyDown\n}\n{******************************************************************************}\n\nprocedure TSmashForm.PatchesPopupMenuPopup(Sender: TObject);\nvar\n  bNeverBuilt, bHasBuildStatus, bHasUpToDateStatus, bHasSelection,\n  bIsNotTop, bIsNotBottom: boolean;\n  patch: TPatch;\n  i, patchesSelected: Integer;\n  sBuild, sRebuild: string;\nbegin\n  bNeverBuilt := false;\n  bHasBuildStatus := false;\n  bHasUpToDateStatus := false;\n  bIsNotTop := true;\n  bIsNotBottom := true;\n  patchesSelected := 0;\n\n  // loop through list view to find selection\n  for i := 0 to Pred(PatchesListView.Items.Count) do begin\n    if not PatchesListView.Items[i].Selected then\n      continue;\n    patch := TPatch(PatchesList[i]);\n    Inc(patchesSelected);\n    // update booleans\n    if i = 0 then bIsNotTop := false;\n    if i = Pred(PatchesList.Count) then bIsNotBottom := false;\n    bNeverBuilt := bNeverBuilt or (patch.dateBuilt = 0);\n    bHasBuildStatus := bHasBuildStatus or (patch.status in BuildStatuses);\n    bHasUpToDateStatus := bHasUpToDateStatus or (patch.status in UpToDateStatuses);\n  end;\n\n  bHasSelection := (patchesSelected > 0);\n  // change enabled state of PatchesPopupMenu items based on booleans\n  EditPatchItem.Enabled := bHasSelection;\n  DeletePatchItem.Enabled := bHasSelection;\n  BuildPatchItem.Enabled := bHasSelection and bHasBuildStatus and wbLoaderDone;\n  ToggleRebuildItem.Enabled := bHasSelection and not bNeverBuilt and\n    (bHasUpToDateStatus or bHasBuildStatus);\n  OpenInExplorerItem.Enabled := bHasSelection;\n  // move submenu\n  MoveItem.Enabled := bHasSelection;\n  UpItem.Enabled := bHasSelection and bIsNotTop;\n  DownItem.Enabled := bHasSelection and bIsNotBottom;\n  ToTopItem.Enabled := bHasSelection and bIsNotTop;\n  ToBottomItem.Enabled := bHasSelection and bIsNotBottom;\n\n  // one or multiple patchs?\n  if (patchesSelected = 1) then begin\n    sBuild := 'msMain_BuildPatch';\n    sRebuild := 'msMain_RebuildPatch';\n  end\n  else begin\n    sBuild := 'msMain_BuildPatches';\n    sRebuild := 'msMain_RebuildPatches';\n  end;\n  // handle build patchs menu item\n  if bNeverBuilt then\n    BuildPatchItem.Caption := GetLanguageString(sBuild)\n  else if bHasBuildStatus then\n    BuildPatchItem.Caption := GetLanguageString(sRebuild)\n  else begin\n    BuildPatchItem.Enabled := false;\n    BuildPatchItem.Caption := GetLanguageString(sRebuild);\n  end;\nend;\n\nprocedure TSmashForm.EditPatchItemClick(Sender: TObject);\nvar\n  EditPatch: TEditForm;\n  i, j: integer;\n  plugin: TPlugin;\n  patch: TPatch;\nbegin\n  // loop through patches\n  for i := 0 to Pred(PatchesListView.Items.Count) do begin\n    if not PatchesListView.Items[i].Selected then\n      continue;\n    patch := TPatch(PatchesList[i]);\n    Logger.Write('PATCH', 'Edit', 'Editing '+patch.name);\n    // create EditForm\n    EditPatch := TEditForm.Create(Self);\n    EditPatch.patch := patch;\n    if EditPatch.ShowModal = mrOk then begin\n      patch := EditPatch.patch;\n      // update plugin.patch properties\n      for j := 0 to Pred(patch.plugins.Count) do begin\n        plugin := PluginByFilename(patch.plugins[j]);\n        if Assigned(plugin) then\n          plugin.patch := patch.name;\n      end;\n    end;\n\n    // free and repaint\n    EditPatch.Free;\n    PatchesListView.Repaint;\n  end;\n\n  // update patch details and popup menu\n  UpdatePatchDetails;\n  UpdatePluginsPopupMenu;\nend;\n\nprocedure TSmashForm.UpItemClick(Sender: TObject);\nvar\n  i, max: Integer;\nbegin\n  max := Pred(PatchesListView.Items.Count);\n  // if patch at index 0 is selected, exit\n  // we can't move it up!\n  if PatchesListView.Items[0].Selected then\n    exit;\n\n  // loop through patches\n  for i := 0 to max do begin\n    if not PatchesListView.Items[i].Selected then\n      continue;\n    PatchesList.Move(i, i - 1);\n    PatchesListView.Items[i].Selected := false;\n    PatchesListView.Items[i - 1].Selected := true;\n  end;\n\n  // update gui\n  UpdateListViews;\nend;\n\nprocedure TSmashForm.DownItemClick(Sender: TObject);\nvar\n  i, max: Integer;\nbegin\n  max := Pred(PatchesListView.Items.Count);\n  // if patch at max index is selected, exit\n  // we can't move it down!\n  if PatchesListView.Items[max].Selected then\n    exit;\n\n  // loop through patches in reverse so we don't move the same patch\n  // multiple times\n  for i := max downto 0 do begin\n    if not PatchesListView.Items[i].Selected then\n      continue;\n    PatchesList.Move(i, i + 1);\n    PatchesListView.Items[i].Selected := false;\n    PatchesListView.Items[i + 1].Selected := true;\n  end;\n\n  // update gui\n  UpdateListViews;\nend;\n\nprocedure TSmashForm.ToTopItemClick(Sender: TObject);\nvar\n  i, max, iIndex: Integer;\n  tempList: TList;\nbegin\n  max := Pred(PatchesListView.Items.Count);\n  // if patch at index 0 is selected, exit\n  // we can't move it up!\n  if PatchesListView.Items[0].Selected then\n    exit;\n\n  // create tempList\n  tempList := TList.Create;\n\n  // loop through patches to build new list\n  iIndex := 0;\n  for i := 0 to max do begin\n    if not PatchesListView.Items[i].Selected then begin\n      tempList.Add(PatchesList[i]);\n    end\n    else begin\n      tempList.Insert(iIndex, PatchesList[i]);\n      Inc(iIndex);\n    end;\n  end;\n\n  // set PatchesList to tempList\n  PatchesList.Clear;\n  for i := 0 to max do PatchesList.Add(tempList[i]);\n  tempList.Free;\n\n  // update selection\n  for i := 0 to max do\n    PatchesListView.Items[i].Selected := i < iIndex;\n\n  // update gui\n  UpdateListViews;\nend;\n\nprocedure TSmashForm.ToBottomItemClick(Sender: TObject);\nvar\n  i, max, iIndex: Integer;\n  tempList: TList;\nbegin\n  max := Pred(PatchesListView.Items.Count);\n  // if patch at max index is selected, exit\n  // we can't move it down!\n  if PatchesListView.Items[max].Selected then\n    exit;\n\n  // create tempList\n  tempList := TList.Create;\n\n  // loop through patches to build new list\n  iIndex := 0;\n  for i := 0 to max do begin\n    if not PatchesListView.Items[i].Selected then begin\n      tempList.Insert(iIndex, PatchesList[i]);\n      Inc(iIndex);\n    end\n    else begin\n      tempList.Add(PatchesList[i]);\n    end;\n  end;\n\n  // set PatchesList to tempList\n  PatchesList.Clear;\n  for i := 0 to max do PatchesList.Add(tempList[i]);\n  tempList.Free;\n\n  // update selection\n  for i := 0 to max do\n    PatchesListView.Items[i].Selected := i >= iIndex;\n\n  // update gui\n  UpdateListViews;\nend;\n\n{ Remove unloaded plugins and plugins with errors }\nprocedure TSmashForm.RemovePluginsItemClick(Sender: TObject);\nvar\n  i, j: integer;\n  plugin: TPlugin;\n  patch: TPatch;\nbegin\n  // loop through patches\n  for i := 0 to Pred(PatchesListView.Items.Count) do begin\n    if not PatchesListView.Items[i].Selected then\n      continue;\n    patch := TPatch(PatchesList[i]);\n    Logger.Write('PATCH', 'Plugins', 'Removing plugins from '+patch.name);\n    // remove plugins that aren't loaded or have errors\n    for j := Pred(patch.plugins.Count) downto 0 do begin\n      plugin := PluginByFilename(patch.plugins[j]);\n      if not Assigned(plugin) then begin\n        Logger.Write('PATCH', 'Plugins', 'Removing '+patch.plugins[j]+', plugin not loaded');\n        patch.plugins.Delete(j);\n        continue;\n      end;\n    end;\n  end;\n\n  // update\n  UpdatePatches;\n  UpdateListViews;\nend;\n\nprocedure TSmashform.RemoveUnloadedPlugins(patch: TPatch);\nvar\n  i: integer;\n  plugin: TPlugin;\nbegin\n  Logger.Write('PATCH', 'Plugins', 'Removing unloaded plugins from '+patch.name);\n  for i := Pred(patch.plugins.Count) downto 0 do begin\n    plugin := PluginByFilename(patch.plugins[i]);\n    if not Assigned(plugin) then begin\n      Logger.Write('PATCH', 'Plugins', 'Removing '+patch.plugins[i]+', plugin not loaded');\n      patch.plugins.Delete(i);\n    end;\n  end;\nend;\n\nprocedure TSmashForm.RemoveUnloadedPluginsItemClick(Sender: TObject);\nvar\n  i: integer;\n  patch: TPatch;\nbegin\n  // loop through patches\n  for i := 0 to Pred(PatchesListView.Items.Count) do begin\n    if not PatchesListView.Items[i].Selected then\n      continue;\n    patch := TPatch(PatchesList[i]);\n    RemoveUnloadedPlugins(patch);\n  end;\n\n  // update\n  UpdatePatches;\n  UpdateListViews;\n  UpdateQuickbar;\nend;\n\nprocedure TSmashForm.DeletePatchItemClick(Sender: TObject);\nvar\n  i, j: Integer;\n  plugin: TPlugin;\n  patch: TPatch;\n  patchNames: string;\n  bApproved: boolean;\n  patchesToDelete: TList;\n  frmDialog: TForm;\nbegin\n  // see how many patches the user selected\n  bApproved := false;\n  patchesToDelete := TList.Create;\n  patchNames := '';\n  for i := 0 to Pred(PatchesListView.Items.Count) do\n    if PatchesListView.Items[i].Selected then begin\n      patch := TPatch(PatchesList[i]);\n      patchesToDelete.Add(patch);\n      PatchesListView.Items[i].Selected := false;\n      patchNames := patchNames + #13#10'    - ' + patch.name;\n    end;\n\n  // show multi-patch prompt if multiple patches selected\n  if patchesToDelete.Count > 0 then begin\n    frmDialog := CreateMessageDialog(GetLanguageString('msMain_DeletePatches') +\n      patchNames, mtConfirmation, mbOKCancel, mbOk);\n    frmDialog.PopupParent := self;\n    ToggleFormState(false);\n    bApproved := frmDialog.ShowModal = mrOk;\n    ToggleFormState(true);\n  end;\n\n  // exit if user didn't approve deletion\n  if not bApproved then\n    Exit;\n\n  // clear details grid\n  slDetails.Clear;\n\n  // loop through patches\n  for i := Pred(patchesToDelete.Count) downto 0 do begin\n    patch := TPatch(patchesToDelete[i]);\n    Logger.Write('PATCH', 'Delete', 'Deleting patch '+patch.name);\n    PatchesListView.Items.Count := PatchesListView.Items.Count - 1;\n\n    // remove patch from plugin patch properties\n    for j := 0 to Pred(PluginsList.Count) do begin\n      plugin := TPlugin(PluginsList[j]);\n      if plugin.patch = patch.name then\n        plugin.patch := ' ';\n    end;\n\n    // delete patch\n    patchesToDelete.Delete(i);\n    PatchesList.Delete(PatchesList.IndexOf(patch));\n    patch.Free;\n  end;\n\n  // update patches\n  UpdatePluginsPopupMenu;\n  UpdateListViews;\n  UpdateQuickbar;\n  UpdateStatusBar;\nend;\n\nprocedure TSmashForm.BuildPatchItemClick(Sender: TObject);\nvar\n  timeCost, i: Integer;\n  patch: TPatch;\nbegin\n  timeCosts := TStringList.Create;\n  patchesToBuild := TList.Create;\n\n  // get timecosts\n  for i := 0 to Pred(PatchesListView.Items.Count) do begin\n    if not PatchesListView.Items[i].Selected then\n      continue;\n    patch := TPatch(PatchesList[i]);\n    if not (patch.status in BuildStatuses) then\n      continue;\n\n    // else calculate time cost and build patch\n    Logger.Write('PATCH', 'Build', 'Building '+patch.name);\n    timeCost := patch.GetTimeCost * 2;\n    timeCosts.Add(IntToStr(timeCost));\n    patchesToBuild.Add(patch);\n  end;\n\n  // free and exit if no patches to check for errors\n  if patchesToBuild.Count = 0 then begin\n    timeCosts.Free;\n    patchesToBuild.Free;\n    exit;\n  end;\n\n  // Show progress form\n  self.Enabled := false;\n  xEditLogGroup := 'PATCH';\n  pForm := TProgressForm.Create(Self);\n  pForm.pfLogPath := LogPath + 'patch\\';\n  pForm.PopupParent := Self;\n  pForm.Caption := GetLanguageString('msProg_Smashing');\n  pForm.SetMaxProgress(IntegerListSum(timeCosts, Pred(timeCosts.Count)));\n  pForm.Show;\n\n  // start patch thread\n  PatchCallback := ProgressDone;\n  TPatchThread.Create;\nend;\n\nprocedure TSmashForm.OpenInExplorerItemClick(Sender: TObject);\nvar\n  i: Integer;\n  path: string;\n  patch: TPatch;\nbegin\n  // loop through patches\n  for i := 0 to Pred(PatchesListView.Items.Count) do begin\n    if not PatchesListView.Items[i].Selected then\n      continue;\n    patch := TPatch(PatchesList[i]);\n\n    // open in explorer\n    path := patch.dataPath;\n    ForceDirectories(path);\n    ShellExecute(0, 'open', PChar(path), '', '', SW_SHOWNORMAL);\n  end;\nend;\n\nprocedure TSmashForm.ToggleRebuildItemClick(Sender: TObject);\nvar\n  i: Integer;\n  patch: TPatch;\nbegin\n  // loop through patches\n  for i := 0 to Pred(PatchesListView.Items.Count) do begin\n    if not PatchesListView.Items[i].Selected then\n      continue;\n    patch := TPatch(PatchesList[i]);\n    Logger.Write('PATCH', 'Status', 'Toggled rebuild status on '+patch.name);\n    // if forced up to date, set to Ready to be rebuilt\n    if patch.status = psUpToDateForced then\n      patch.status := psRebuildReady\n    // if normal up to date, set to Ready to rebuilt [forced]\n    else if patch.status = psUpToDate then\n      patch.Status := psRebuildReadyForced\n    // if force rebuild, set to Up to date\n    else if patch.status = psRebuildReadyForced then\n      patch.status := psUpToDate\n    // if normal rebuild, set to Up to date [Forced]\n    else if patch.status = psRebuildReady then\n      patch.Status := psUpToDateForced;\n  end;\n\n  // update\n  UpdatePatches;\n  UpdateListViews;\n  UpdateQuickBar;\nend;\n\n{ Double click to edit patch }\nprocedure TSmashForm.PatchesListViewDblClick(Sender: TObject);\nbegin\n  EditPatchItemClick(nil);\nend;\n\n{ Shortcut to delete patches using the delete key }\nprocedure TSmashForm.PatchesListViewKeyDown(Sender: TObject; var Key: Word;\n  Shift: TShiftState);\nbegin\n  if HiWord(GetKeyState(vk_Delete)) <> 0 then\n    DeletePatchItemClick(nil);\nend;\n\n{******************************************************************************}\n{ QuickBar Button Events\n  Events involving buttons on the QuickBar.  Events include:\n  - CreatePatchButtonClick\n  - RebuildButtonClick\n  - ReportButtonClick\n  - OptionsButtonClick\n  - DictionaryButtonClick\n  - UpdateButtonClick\n  - HelpButtonClick\n}\n{******************************************************************************}\n\nprocedure TSmashForm.UpdateQuickbar;\nvar\n  i: Integer;\n  patch: TPatch;\n  sTitle: string;\nbegin\n  // DISABLE ALL BUTTONS IF INITIALIZATION EXCEPTION\n  if ProgramStatus.bInitException then begin\n    QuickButton.Enabled := false;\n    NewButton.Enabled := false;\n    BuildButton.Enabled := false;\n    ManageButton.Enabled := false;\n    OptionsButton.Enabled := true;\n    exit;\n  end;\n\n  // BUILD BUTTON\n  bPatchesToBuild := false;\n  bPatchesToCheck := false;\n  for i := 0 to Pred(PatchesList.Count) do begin\n    patch := TPatch(PatchesList[i]);\n    if (patch.status in BuildStatuses) then\n      bPatchesToBuild := true;\n  end;\n\n  // enable build button if there are patches to build\n  BuildButton.Enabled := bPatchesToBuild and wbLoaderDone;\n  // swap hints\n  sTitle := GetLanguageString('msMain_BuildButton_Hint');\n  if not wbLoaderDone then\n    BuildButton.Hint := sTitle + GetLanguageString('msMain_BuildPatches_Loader')\n  else if not bPatchesToBuild then\n    BuildButton.Hint := sTitle + GetLanguageString('msMain_NoPatches')\n  else if bPatchesToCheck then\n    BuildButton.Hint := sTitle + GetLanguageString('msMain_CheckPatches')\n  else\n    BuildButton.Hint := sTitle + GetLanguageString('msMain_BuildAllPatches');\nend;\n\nfunction TSmashForm.GetSmashedPatch: TPatch;\nbegin\n  Result :=  TPatchHelpers.PatchByName(PatchesList, 'Smashed Patch');\n  if Assigned(Result) then\n    RemoveUnloadedPlugins(Result)\n  else begin\n    Result := TPatchHelpers.CreateNewPatch(PatchesList);\n    Result.name := 'Smashed Patch';\n    Result.filename := 'Smashed Patch.esp';\n    PatchesList.Add(Result);\n  end;\nend;\n\nprocedure TSmashForm.StartPatching;\nbegin\n  // make and show progress form\n  self.Enabled := false;\n  xEditLogGroup := 'PATCH';\n  pForm := TProgressForm.Create(Self);\n  pForm.pfLogPath := LogPath + 'patch\\';\n  pForm.bDetailsVisible := false;\n  pForm.PopupParent := Self;\n  pForm.Caption := GetLanguageString('msProg_Smashing');\n  pForm.SetMaxProgress(IntegerListSum(timeCosts, Pred(timeCosts.Count)));\n  pForm.Show;\n\n  // start patch thread\n  PatchCallback := ProgressDone;\n  TPatchThread.Create;\nend;\n\nprocedure TSmashForm.QuickButtonClick(Sender: TObject);\nvar\n  smashAll: TSmashSetting;\n  smashedPatch: TPatch;\n  i: Integer;\n  plugin: TPlugin;\nbegin\n  // STEP 1: find Smash.All setting\n  smashAll := TSettingHelpers.SettingByName('Smash.All');\n\n  // STEP 2: if Smash.All setting not found, exit\n  if not Assigned(smashAll) then exit;\n\n  // STEP 3: find and clear or create smashed patch\n  smashedPatch := GetSmashedPatch;\n\n  // STEP 5: apply Smash.All to all loaded plugins except game ESM\n  // STEP 6: add all loaded plugins except game ESM to smashed patch\n  for i := 0 to Pred(PluginsList.Count) do begin\n    plugin := TPlugin(PluginsList[i]);\n    if SameText(plugin.filename, wbGameName + '.esm') then\n      continue;\n    if Pos('Smash.', plugin.setting) <> 1 then\n      plugin.SetSmashSetting(smashAll);\n    AddPluginToPatch(plugin, smashedPatch, i);\n  end;\n\n  // update application state\n  UpdatePatches;\n  UpdateListViews;\n  UpdateQuickbar;\n  UpdateStatusBar;\n\n  // check/fix smashed patch status\n  if smashedPatch.status = psUpToDate then\n    smashedPatch.status := psRebuildReadyForced;\n  if not (smashedPatch.status in BuildStatuses) then\n    exit;\n\n  // STEP 7: build smashed patch\n  Logger.Write('PATCH', 'Build', 'Building '+smashedPatch.name);\n  patchesToBuild := TList.Create;\n  timeCosts := TStringList.Create;\n  patchesToBuild.Add(smashedPatch);\n  timeCosts.Add(IntToStr(smashedPatch.GetTimeCost));\n  StartPatching;\nend;\n\nprocedure TSmashForm.NewButtonClick(Sender: TObject);\nbegin\n  NewPatch;\nend;\n\nprocedure TSmashForm.BuildButtonClick(Sender: TObject);\nvar\n  i, timeCost: Integer;\n  patch: TPatch;\nbegin\n  // exit if the loader isn't done\n  if not wbLoaderDone then begin\n    Logger.Write('ERROR', 'Patch', 'Loader not done, can''t patch yet!');\n    exit;\n  end;\n\n  // exit if there are no patches\n  if PatchesList.Count = 0 then begin\n    Logger.Write('ERROR', 'Patch', 'There are no patches!');\n    exit;\n  end;\n\n  // calculate time costs, prepare patches\n  timeCosts := TStringList.Create;\n  patchesToBuild := TList.Create;\n  for i := 0 to Pred(PatchesList.Count) do begin\n    patch := TPatch(PatchesList[i]);\n    if not (patch.status in BuildStatuses) then\n      continue;\n    Logger.Write('PATCH', 'Build', 'Building '+patch.name);\n    timeCost := patch.GetTimeCost;\n    patchesToBuild.Add(patch);\n    timeCosts.Add(IntToStr(timeCost));\n  end;\n\n  // exit if no patches to build\n  if timeCosts.Count = 0 then begin\n    Logger.Write('ERROR', 'Patch', 'No patches to build!');\n    timeCosts.Free;\n    patchesToBuild.Free;\n    exit;\n  end;\n\n  // make and show progress form\n  StartPatching;\nend;\n\n{ Edit smash settings }\nprocedure TSmashForm.ManageButtonClick(Sender: TObject);\nvar\n  smForm: TSettingsManager;\nbegin\n  smForm := TSettingsManager.Create(self);\n  smForm.ShowModal;\n  smForm.Free;\n\n  // update\n  UpdatePluginsPopupMenu;\n  UpdatePatches;\n  UpdateListViews;\n  UpdateQuickbar;\n  UpdateStatusBar;\nend;\n\n{ Options }\nprocedure TSmashForm.OptionsButtonClick(Sender: TObject);\nvar\n  OptionsForm: TOptionsForm;\n  prevLanguage: string;\nbegin\n  prevLanguage := settings.language;\n  // Create and show options form\n  OptionsForm := TOptionsForm.Create(Self);\n  OptionsForm.ShowModal;\n  OptionsForm.Free;\n\n  // update owner draw if changed\n  PluginsListView.OwnerDraw := not settings.simplePluginsView;\n\n  // rebuild log because some messages may have been enabled/disabled\n  RebuildLog;\n\n  // if user changed language, update language displayed\n  if settings.language <> prevLanguage then begin\n    LoadLanguage;\n    TRttiTranslation.Load(language, self);\n  end;\n\n  // update gui\n  UpdatePatches;\n  UpdateListViews;\n  UpdateQuickBar;\n  UpdateStatusBar;\n\n  // if user selected to change game mode, close application\n  if ProgramStatus.bChangeProfile then\n    Close;\nend;\n\nend.\n"
  },
  {
    "path": "frontend/msSplashForm.dfm",
    "content": "object SplashForm: TSplashForm\n  Left = 0\n  Top = 0\n  BorderIcons = []\n  BorderStyle = bsSingle\n  Caption = 'Mator Smash'\n  ClientHeight = 300\n  ClientWidth = 600\n  Color = clBtnFace\n  TransparentColorValue = clWindow\n  Font.Charset = DEFAULT_CHARSET\n  Font.Color = clBlack\n  Font.Height = -11\n  Font.Name = 'Tahoma'\n  Font.Style = []\n  GlassFrame.Enabled = True\n  GlassFrame.SheetOfGlass = True\n  OldCreateOrder = False\n  Position = poScreenCenter\n  OnCreate = FormCreate\n  PixelsPerInch = 96\n  TextHeight = 13\n  object imgSplash: TImage\n    Left = 0\n    Top = 0\n    Width = 600\n    Height = 300\n    Picture.Data = {\n      0954506E67496D61676589504E470D0A1A0A0000000D49484452000002580000\n      01520802000000A1773670000000097048597300000EC400000EC401952B0E1B\n      0000000774494D4507DF0A1216092FFDA4DA3D0000FFFF4944415478DA7CBC07\n      9C5D57792FBADAAEA74F2F9AA62E4BB62C5BEE4DB8601B83E9840448203790F2\n      CB4D7909099740CA0B2FEF92040381000910724320A10730C536EE96AB6CB948\n      569DD16846D3674E3FBBAC7ABFB58FECC7CBBBEFCE4F1E8D8FCEECB3F65ADFF7\n      2FDFFAD6C613A3B950E65DC3DA446C18CEB4DA49D1A5341CD6419B2D4CDC5E78\n      CF5FBC918785021B7FE61F7EF4BDBF7B30257D6749FE44A7B554AF2B62142648\n      615F13C618A7284913A33542C82024047C430A21429036C8C0FF6164FF333840\n      9AC33FF9148982AB90224DC2F4B6DE812D61D8CF577BA368DFEE2B9E6DADBED0\n      6AC4AA32BBB4B091248262A54DF7D769F6175C122E8EB24B62837EEE8B74DF07\n      A3800F241413820D0C4BDB91C0AF51027F08C3149BECD70CBC87B8AE6B8C9152\n      6A6342C5538304258A328CA9671043063E5F52C38D329462CC7C3740B22CF89A\n      83DA9B4BEE046213B4EC09E20FA7EFF9F835FD577664E030354063AA88768867\n      6442184C8E87754E9246D28CBFF1E183B33F210D9F9CCEB766D6F28970B15F87\n      81DBF93376AA60C48EE3C077957D99EC7631228CB2BA6A516676F9C37B69D189\n      E6872F951FFA875F33BD31F69C8597D32FFECE7F242F87C7FAD9CC46ED6CB5A5\n      357608C6462B6C2F6B301618C3D5877C7F7BFFE076966E49DDF1ADC5DBEFFA45\n      7A61C574B48B50C75FF5195AFCD1FC437FF9705115965B67E631598BC94C4CE6\n      0C6A514589743576B1132232E5E9711255503A38B8E9F6778ECF4FBFB46B64B4\n      520E8C2B5347609FC0FC53EA60C60C71612EA356F3EE7F6BD66688871A738D95\n      15A7B78906A488096E484A53E26ADA41BC89A212423D79AF3964E21167D0A724\n      189E7DDB5FDEDCB37F8CCBD4950DC4584A2AB0181473091F6317DC906EA84140\n      C0EDC28A1A8D8554EDB64E39D606F38E34867A0EF55D985798698C094C38A32E\n      E7228ED3E75F3AB27FFF657E8F5D770CAB0FC3C60E0408222E218E368E21107D\n      046166D788BA367C605D6C604390C1FFC270608221FA88D2140681498A751F4C\n      3EC212961E3E0F91B6FD25E3210A7FC5067ECB14115188D68DD4D854082E2123\n      106A20DAC64820E3DBF740A29914A114316CEF526781DE8D6102835159C0C305\n      E1838CFD5CF88147F6FDAAA94493180E516F243112C29A19980A25CE9D3A565D\n      5FDD7DE965D473A552D4F1E2947B61005900B78DB5549C2391521B38DAC4AEF6\n      620841B78310531AB3EAE11A5A8983716E064528F290C4C2AB6135C47595E88E\n      2B8A11721491A57679F970E35C45EFFDD33B134FE67800975EF89BA3877EF862\n      0BE0C329001694425EEA59D975F17027CA3FF978ADCA9D73F1C692E1D3296BD2\n      22CC86921C6E49C24F5AC14230E6424608CE15BC625F8374C552499D7DD96537\n      0856D7663A257639B219B7C98D2C162146B8D2FDBDF97D83035B1231D0EA4C8E\n      84E5AD4167A0FEBA0FDC521972EBC13A2E4C3BD5FE473F964E7F7B362C88651A\n      AEA99E4EEBE448980CBA2328F2774C96AEBE2B70FBFA61AD4DE8631F0660338C\n      6A6A5F814FC5CAD86580A0384D6B5B7EFAA917FA23B17733456993ABF242153F\n      7AF04CD4CC99247DE36DBBFB7A164DECBF34D37C79235AE9141AEBD8373AF485\n      EB3986E93BEED83AB1654E9379E60C27ADD0CF169A421ABA42A1C410662C0613\n      02608A0473F3A2EDFCE8EE97D7AB95F68A68B6D98A22B3C63DDD501B9D98CBB6\n      17602728281C3854C9B4A1B816307318268AA12C768D862881498279B3A06BC1\n      9DD298F9BA13391C700A4190694219F3FA82FC783EDCE4CA926E8EF5D09B0E5C\n      72F091A766669AB8585830C191B87DBA1535530489D1E716B6549CA99CE88FD3\n      5DE56D774C68265A7E508E056754629E042690C68B29CC9CF41DE7A9134B2FA3\n      BC9B2FE678CB71CC0B4BF38BF9F0ACCA9F5E4E56DA9182F4A61AC661B31E7930\n      1EC6120B6E123990BB984056AA0CDD61FD5D06E9EE12A9A32895C6DD5C92BB8A\n      FD03D81D1AABFEC65F5CDB7BE9AEEDDB3E87378F965C0EA0473B4C36549A77C8\n      45BEBF53E21E21D86074C707AFD879C7F6A65185FAE8573EFA85930FAD24B46F\n      16872FD7AB0D91509701D99954390A4083A60CA54902F0020381314809E98632\n      ACC972B4CB56C4A2BCA381208D455C5586687168B3BF60B6F68C0D32B7275EBA\n      A892EBEF1BFBC1F1132BB97C33CD9D595EA8F3543278237C18B137FF0ACFFDFF\n      1061F7B3CE7F1A651688E1CD598E007664E901E44800D232A8045C81DC726CEE\n      4376C16F393CE1804014429A3A88798478766E95402A35905F8452D7A36E227C\n      86DB05DCDCD5931F56C130AB60537FCD2FECB8FEFDDB7965853314B01E003A65\n      80CF3C8400892452C0AA4009AA35DFFEE70FFE6CF990570FD849DC98A97A89A4\n      D86D53005F1B8C304C60441BDB16CB33D2EF2639C02C73DCA682E040BB82A18B\n      5081256777BDB6F8FEFFFE365D8C8008CF1D8D3EF3FE6F3867065FE8D3B3D5C6\n      7CBD0DC80FB181B0B25103C16330F00D366AC0F5B654FA77387CABF0C6B6155F\n      F7895F24179571C7C0EA2461CDA778E581B3F7FDF97DB44A5BB2BAE1F86BB199\n      4ECC598D9B1406A68008A92121C213AEDACCD23249B76EDB7EFB2F6D79F1A987\n      770C0FF7E47DE54A13628E387320691C3B0A500F860AC1EFFF4675E1251E1231\n      D75A3D83C2255950463AB403294768E092C443314DCAA9F094591BF7D0B033E8\n      005D6C597DF3FF7573B8BD47CAD4534DC45C41CAC0100C7345FC0CFF8DD51119\n      F87405858D1398BF3851ED480B4165A2316281870103B4E5CC8C0D6D404156C3\n      8FE716971CD71BDEDC6F89D06A28176000B4130405C004A0BFB154078163C518\n      2C85A5A12CBA2C055ABD04539C6120B08EA1360889403AC0A016ADB4C965249A\n      66BFEB2B9ED01090129602325910604AF82DCD6C70EB941009F201180D1B9669\n      20715EE0018DC0D580A1E17A1214099512341BB5F80557B56FB1F765795A2708\n      FE5822EC10F8C1860055DCD8CF81200632A8AE9F3C766462EB8E7CA9083146FC\n      504A8E999508709FA07235E7580A0C3C039F1931E3C0EC199ADACCE3ADB87EBC\n      E3A714F5B48351E2701777A8A035A4FA84AE53153BA21021081451EC54160F37\n      4F7BD1151FB953F73981CC25EDD68BFFEDB1D5176A1D4D003CE0CE067A50FF70\n      737C5B51A4A5C71FDF58EBD073BCB1AC93E99454491E26488346C8D85EEA0C51\n      409D6863D52106220406544882E0115D16ECD29E4D7F42BA3AF25511AC6C8C58\n      790259592CB8BBFB7BB71B3AA194231B3BAF186D159BF92DE8EDBFF686762009\n      3EE752CC1687BFF9E107970E35692EBF24DBA04A705B4D56467C24CA9E7FCB17\n      CAF9C1019839E33940840A3E027432CE52D84E77168EB05E64895507961F4F17\n      0E3EBF6B20C8016AA426D6E1634F2ED656031DF38B7607BBB703CFB346DB7DFC\n      E86235296D34D284D7E1B699DBAF052FE7D66FB9B16FC7CE52A2DB3076172B87\n      84102A3007D4D502B81066DA73EDADC132FA21A8AD170E9F3E7D6A536FB178DF\n      7DCFEB70702E7197119B595BDB88DACCC361BE0490CD00929228494151081827\n      030E41704D006E4BE68C6140456B663213638803F88825B710EA394253296481\n      BA3B7A7A8689ECA3919B560F5CBB6F6424F8C1F70E6D74825611CFA86826F256\n      EA700771C9D19395DCD65C7E5824638EFFE62D418F0F00EBC145084AA9548E01\n      1A07E16CAC34A5CEE3A7164ECAC075BD4117980CCDB4375E96EA2C2ECC6EA885\n      6A8B23A9201D35722C2704D28A9E38CB75E4808205884716EAE08EC03600867A\n      0E801093DCE6CA964ABAD5ADE452B46D4FFA818F5D97DB3EBE65F33FE2CDC33D\n      4C30583FEE9A18A57D81B7C70D367391D7F53DAF1DBBF38F6EE4FD29CBBBF33F\n      919FFD937FA24DBFA62B6790FB72633DD60294284498E69229421DC61DC83B1B\n      8B282342083FA93346A219DF58B8E91AB08C7B327411288070EDCBA53B07DC01\n      185CA24750ED0D97EF9A5F6FFDE4C4F27ABE7731D2732B8B2D017A157745302C\n      8BF579FF5B223C6F3E33336A69D0BE011617A63853E41951DB64228056369DBA\n      4468D3C64A65ECA9540280519869C07A1C5006760404A580D907B90270481D08\n      BCB64425576EF2D349CF99F08665331EDF8D7EF5CFAF0BB6C06C6BE482BB96D4\n      0A2717221690CE313ED22ED7DC25C1A9FBE6FEFD630FB7D64B55DF3919351762\n      1A4B9821EE382EB503A6D98C9D27EA2CF3BB446E531A5127D689EFA85D616597\n      CCD3F4DC35EFDEF4F60FBF56172404F3F2C9CE277FF96BDED94D877BD333B5D6\n      7C3382E0661679853533F67A4C6544D8CFDCA94AEF2E924E297FD38ED21D77BD\n      93EC2EE0083B92A661131C3E7FB17EFF5FDE174D831FEFD40C594BF5742C4F4B\n      55CF160F1C8D4B58CE980966B6B8B2485A975DB36FDF6BFA9E7DECC18B27A78A\n      8193E214E7001DACAF06F2061423410864034AF3F03D9DE30FADBB98CE775A27\n      0C9EE51E64B6EBC49E9D7C168A78306065678063BFADD77A715A31BD2EC3953D\n      AD5BFFE42A36E603B679BA0DE9A84805169512AE337B8533A8CBA60C022C2342\n      5868485CB00EED4EDAE9B800EB0EA3393F8B476CB1558045348EE35BA563611E\n      C88F211F56DE0685FDD9D21EC00104829B7DA7D60E5A4105D7766CEC596EB3CC\n      674B11C64A514B84D6C0D1F305073B084B72E0EDE0C58CA460B0148C8DE46DE2\n      BAC6F21AD112860FBF1883A7B0590386129095D870B5E16E5416093A0B770A41\n      6BB31D4294A7D6F498AECE3CCF01F87C3E80DA4C90EC18D9D20A8C297C00E231\n      0748736DEA82AAD68B33331BEBEB3BF7EC76021F78C48A44902CA0B6B388C382\n      1BC1ED3B91554F46274ADB6150442250A78BDC75BC48AFF54F5650C211AC348A\n      902C0905DE3065407890744414E2CAF28BEDA3A279E51FDFC126434F061B736B\n      CFFDB787C98AB3012E1C0C8CA1E323605196C7B6968DE97BFCE0CA4A032DAB74\n      4925A762BD8A434B84D95A82C7D799D4C776AA6D72805C11200740BF2A2484E8\n      0AD9AE05EC4EC52B44787E72949D4102360A28C375F06431B72B5F18C7284C9B\n      855E75D92D3BCFB45EBAE18EAB761ED8041840F329729CA547D0F7FFEC39B328\n      712E5E4E138C4B39242A3ECDA3DEEBFFCE1F1E1D862101549B80608F2512BC14\n      0583D6754D3050659345A21A330BECF96F3E34E15506F2857652C561E189A76A\n      8D8D1E0770519DBAE986ED0E16498CE617F5F169B19EA473ED731D1C68351E52\n      C292D98A135FBC67ECA24BFA7A46DB52AFA9D47369099B5083BCF63A9A360C5C\n      08870685109A7E11D7ABED877FE65D78E1E8C183479E7FAE8DF2634B4A4E775A\n      338D66930BDF63A1E3BAB6E0042A31069D0ADE19E64A886C322D7D1BD7A1BE1F\n      40FA4865438A8112B36E84438CD3D0078814510A44B8290886B01960BC8CD2A2\n      6BEE7CF3E58BB39D7BEF7F9E17BC5ACE9989C27335BCDED8F09C64BC124E857D\n      A35A0C90C61B37E537F7F50131D90511A96F099868F880CC9AAE29F3E899A5C5\n      D4CD31676B6FC1256855C58FAE6F9C65C5D9263AB7D68A0D2C8D763279AF902B\n      6C7C7066B5E179E487FC731CE6853E50A1E220B269E0BB10C80E72B6163B93A0\n      AE9A62DF75FE7B3F7A1919EA99DAF62F78CBD0A063700A41E480B830239EBF83\n      84C349B354DC78DBEF1DD872E72E4E1A6EC979FCAEEAD73FF7C300F5ACA1E2C9\n      549E6E5705C84B6A81C6704D14D10CA70079A0B73324B210939528326D4415EA\n      5A2F8B54D6E1604B84608E38F21CCFDD52D1DB73A4D7C9055174C548FEF28BA6\n      EE7EFAC52355B68CF3D3095F5C5B8D80A06C450877B3DB169E5E09EBEE7DFF7F\n      89D08253569FA05D69960108B5B042BAA962553DA5DD72A87581408494D87701\n      FE2901A8CD6192ADF5362171FCACB62841DB398EB0B3E95A054A4585C95D053A\n      2C7519979113BFE1D7775CF68EB2642DAECAAEEB132705AD4A9D40B34818E5EB\n      32D2A09A85AB077EF4170F3CF19DE9D82D2D613CDD48EBD8440AC410784DFB95\n      A1AABD25ADCE2BDC4C509CFF824170AD736EBA2B97DB96E6995EBEE9D7275FFB\n      1B979B1CA0B6B73E5DFFD47BFEDD9FDF7CB83F9E0647D8E818ECB8049680C3F5\n      88B1051070BAE0398008B7F4F4EF26E9B8F24777946EFBC43BC805791C114FF9\n      328CB959F7D6F1137F756FF5702369F33AD735AE66787A5A8A356CC7C0809011\n      2A1A34E5D02957F878FDC0EDFB2FB866E0D0A30FED1C1C2DFB2E4C12A73C2B8D\n      02D3407861C81FAE94EF79271EAE3FF79373211E5895EA85B8732A552AF49568\n      16B0EE47C1A0C6FDA0B05D8F6387B304C8D4EBB8200F7AAF94AFFDC8357408C4\n      88622805BB66708FCD1B705D26130D56829B2E00669C90A17657064571D46E92\n      38717D9FE543AD25B84F6B1E81516C0C418613EBE5AC1EA2CAC9A80C6C165020\n      D83EFB1DDEE59AF35ED04A7E20606C9CAC92943125C6D94A753558B7C0042F51\n      1BB454644591CC255822CCEC96E543ABE84810182EAC4CB3554D100D10AB102C\n      24FB68FB39526A467DABE96005690C4C4474415B84175D1F48B2EB5A4830AF48\n      C2CC988271B42E53A55AB795888C4CEC9521DA8DF199ABA20482013CDF4BCF3F\n      57EEA96C1A9FA00EF86F8023984F9C8D1B1921B448485664E620E8E254E93461\n      263461726215C54687AC5E5D19991A41B2293140A321103C3A2260D179902200\n      289E4F4B2B2FF3E39DE6E5FFC7EBDC6D3E4DE9D2D195E7FEF4A05375DA0873E3\n      61A12EBCA0A2E899DEC1D0F3879F7C627171DD54115BE29D63A9584670416505\n      30EA428BDD32B0363A9332F007B819B2CCD8BF14E4327CCFD68E74EDE0F9F479\n      E50BEC39FC7B9AF973B09745876C2D855BC2FC20067313EDBE7870FBE5433F7A\n      E4C93FFCF855DEC4681AD7B513E4FC1D87BE78E4B14F3F334A06D6D05A95820E\n      A4155C2CE1D2D59FC84F6E19577104008E73AEC9FB300926ABB6536D23123C0B\n      A49C40AE9B2A1092C77FF8123A47B7F40D3A7E3DD1FA85A3E8ECAC3F31DE77FC\n      D823575EBA79FB44256E2D51D37FF8700B38F0647BA58673ADB857C5ED817CBD\n      A010EDE03DDB7BF75F57EC9F6CC6919089CA79FD405BD84D94DB06AB6EA84B69\n      5E28E9E7AD9EBFEFC7D82B36766FDDFD4F9F7B20059789DDB398BCDC8A96DA4D\n      C8DE821B1080230E18CCE00B64509426DDD9CBF64F20675DCFF320446DCD19A1\n      9CAD8858C5611C5B2C05C7231289B92E61B2ADB7D4ABC5908369DC1A1FEDB9F6\n      DA6DCF3CF9F4C933A8E50FACBBE85C9CCCADC4B18C072B6CAA5CDEA44DAFA9DF\n      D61BEC9B18533CB24556AE7CECA7B6206B021085C43B1AC50797C06B857DCC9D\n      2C873E366B32797875E58C579E6EA833AB8D1449D7370EA0778A5250BFC42A3B\n      08114AEDDDD8ECC7C80DFC6E9D4F72018630177A58630F3993FEEA1656320D75\n      DD1BFADFF2FB5B75B977EA82AFE3ED83C3104EA996D224B9104FB8B929E9E5DA\n      2BFB0FE4DEF47BD7F83BCA90EC88A58FFC79FD87DF7C20D5E5AA537AB1519F8B\n      1B86210F23800D887F2B06198A89A4F667D3D5653A2BE864760C02C3FAED4CA0\n      657468F118315B5127FD456F67AF3FCA4891A7DB7CF3BA4BB73514FFF6B3A756\n      D270C3E49F6D77366AB5C4D67AD1F982A8C6AFEEFF9D977919F6FCA7E2A8BDBE\n      CD87AE3A3C4F8AB674967D5955CF6CCDD4E68610DDDD38307A5D2D8FAD4DD0D9\n      AD2018BA8F8907130C3809269B80CF831B071065AE2BFA5DB5CDA5A3C89551F3\n      92D74EBCF9F776CBFEB3B02A54962980178500D2802B92B525882E5E924ABB25\n      46D607FFF17DDF5E7C99D78BCEB4347335193B22D560F7EDB25922CC1C61B72E\n      8A50775B23D3C4F6159D6870AE5EC16DEEC9BB9B13C8E58D5FFEABCB76BE692C\n      C1D463003A0B7FFFABDF71CF6C7961309EA935CE343A12CC879D0405EBE0C0AC\n      C02DC00C4A18BCBBB5B7EF422CC67430B0A378FBDFBE15889024C84BF3A91B27\n      78B598B2239F7B78F6C12516E7D6D6EA4DADCE297152264B1AA5D4B39B085A96\n      90D94A9D09477A74E9E6B7EE1FBDA074E4A9A7F68C4EE428663EEBA8C8CB3318\n      337318CC1E0E80DBB4E7BBEB27F913DF3D992E97635238A13BA7056FD8BA74BB\n      A0F804CD6DF38B81E634A72178E338A5889BAAE3FA4EE57A7CE347AF2265505C\n      8A1A011C824CC95669896059C5AC6B0A4D06E216BC61DE9420192C229E269D8E\n      6EB6BD5C087C0C3E01740F4C2B4F12C7F34033423C20302756278143F44986A6\n      8838D6D8C1F76CDEC04CC30F19296644A86D88195B0565D6A358AC062DC3B22D\n      F1CC1F5AF9E66A4028882D98749B2AC6FA425B688294001EF357D75607470791\n      041106865EDA418324A2C27E9A840FCA2BE5C2CA27A201BACA09B02DC0F21069\n      01A027D298398053C2C9C2DB526B46E7F616C0F700ADDAFF9748464A76A48AB4\n      8A61CDB4E4441950015944E0A8BADE68B77A7A7B5D3F07696933D3528CDDDE32\n      924332839584EF1D820B31647412F93ACF0BD1B3E74051A415BC31BDB8697433\n      CAB513DA729ACCCE8A0491C8A860898E354EC334BF76DA9C5A6B5DFA3BB77917\n      B898E3734F2C1FFBEB17C42A8FECD645116B71F9FE817AFB48AEECF7F56D79FA\n      A9B373CBA665F20B49FB789ACC6347C2159903AA05682EDBFD345D8B87B3D166\n      DBE7B000E4E776D36DEE405E4BEB65347EF50B42C5EE325A816B174ED92DD3A1\n      9237952F4C79FE08E244AFBEE55D375593A59A5A78EB1F5F2782B6E43DD42BA0\n      583D71D7F3D35FAB865E7E23DC88352D93A22F934BFFB2B26BEF4E5D5F87ABE2\n      C0C13D65000BAB47C052779519B694284989E994AC556BCF36971EAF6FEDED77\n      FD0DA9F5DCB9DE470E2EEEBF72C7B1971FCA7B43375DBDC5358B7123595E715E\n      5E50A7DB7CA6014BD5C3752AE552AF170C93813270704FFDA2ABFDAD5B07A2CE\n      AA2D65525F694203988A4E8A236C1523ACADE37B959933F2B1278FBCFB3D6F7D\n      E9B1633FFECECBA9D3B7E8955FE6EDB97615245DDE098D546922148300569CF3\n      6E6D0C0606DA0B500858D0755D9C293C5B81605469983CDD2DAAC12A0012C6A0\n      2C311A2EE6C7C26010A10AE8B846EDCAAB725B4673071F6C4EAFE4453F5E40D5\n      85863FBF2EFD406C1F0EC6992946E975797ADDE6B11C4914E80401581944109F\n      0E385CF8B4DC63EB8D831B358FE6861D7F24E716295DE7D163D5F53341F96443\n      4E2F573943BE9B154652C4216019B87146323DABA5BD8B42A14019E35ADA2A9A\n      92E07D03CFA78815309B74E63793224B9DD7BD6FDB35EFED1541CFE60BFE1DEF\n      1C1C514052109F22AAB87A9B5FD8C4FD3C5A7DEB6FEEBCF82DE3B2EC51B72492\n      EADDBF3DF7F8E34712AF6F56D1139DE686E61A0BC7C0BA33C021083C486AC027\n      0C86B92BDB88DDE29259BCDAC9B57ACDD61DBBC54C0DB4821DA09A7E8F4E55E8\n      E6625842AC8F37DEB0B3E7C289BEFB4E2DFE74B693A87043E1838D4EB3D591DD\n      EDBE2EE5E9EE5FE79B6FBAFC4731F97F19C26CB3C456186926FD882D9F598251\n      B2FB069259AF2ED34829606C148C74468DF675C0240DEB636537B1318DED1C53\n      22014E21440CF1895B7073439EE8676A98D01E830746D49DBFB17BE84A9AE01A\n      E0A68B03E0096B201C70A15C308EA9AF4508F0076E7DE9C1CEBF7DE8B1F67AB0\n      9017A70C596A12039A4E274A7890A0D4566891CE38DBA2B3AD29DB99CB4A5E56\n      F27760A165AEE86EEC2E90F138EF3AB50F7CE6FAC95B7BDAA9E7B3527376E9CB\n      BFF5FDD63343A746E44CAB3D5D6FB5B985467085AE0B716A67C512A192030E9B\n      ACF45E8CE588F60776946EFDDBB7B00B0292104F94A52738590993F8DCF75F3C\n      F895E79C66256DA729C62B9A9F48A359A95BDAB30D52589595DAE2781398FBE1\n      EA6DEFDA5718098F3F73E8AA1DE033216700BFB4EB037348F02E20958CEB6866\n      5C0FFECA3FFADD53679E5606F7CFABF602D12B1C942DCF997802799B59C921C9\n      E085C5A19191971E396AA16FDD56390A37D01B3F7C09E9E5B67DC39A260F9B22\n      101A07F79119E6CC0EE157C2C4AA07ABFF0DE430434AF24E8C5AB1930F80956C\n      C122AB27DAE23EB345255B71035999F55621E25AA0B43A1F064F4C561A45E070\n      41A0587DC54CB6570786CFC6A5CEFEC9D61A94B56510D8B61C26B1DDF6031ECD\n      192A00A88D0DFAD806B20E2171C136311A9C3CB9D06ED52FBD622F88E138020C\n      E0610E90A643508C815051A0856FCB547677126478706E6EE5E0A38FCBA47AD3\n      2D070607FA01FC0D00BB915656673553D4F59DC86E4F8ACCABDA4D75931A4019\n      037F3A48C5C8709382E66240BB76EFD25A47F054CA9283ED0FA29992B0E807F9\n      62C5A3DDE4104DAC2BDC51286AFB6931AA248FCF05C37ED4A7579F9A9B284F9A\n      09D9766B4135444C00F3520184602145EBC8D561ED2C79F9F4FAFEDFBC33D8EF\n      01549DFDD1DCD97F3C9356D30E4421CAF94CEFBFBC6765E3B09FCB4D4CED7EEE\n      D0CCA933BCA57B56D3E8B888660D4D6015990332412402160306ABB35293DD73\n      B195BB6C6B0CC96E9F4C77733DABF28957CBA4964111CA321BDE4EB212301076\n      0262250C9DA19C7F41501C156919B52636177EF583BFFEE92FFDF3C577901BDE\n      B5477316C3F487529C8A9FF9EBB9B30F22EC57AA7A3574A51F99893FC4076EBC\n      DA3456B0B6DD7CA45CC2E5BC04050251627785882D875395B2BC6712B5BE61CE\n      90999F2D4EE62AD42C12E66DD4C77EF6F0C9C9ED65835A332FB76FBA72D7705F\n      DC69ACA4893E36C74FADD1E975D3447EEC98164E61218648BE9F131A37CA03E2\n      B2FDA35353D4F75A14D49506CD6D675E3A4DC312C27CA38A8E9B4F90FAC1F7CE\n      5CB26F72C7B6D2D73FF7D889D33DF55CEF59D638DDEAD412EC38303E704B3EE8\n      1598329053C6763330982B70068C5A0A042CF21DD701F5048C032E32ABC8D9DD\n      6F69CB1A30A7B112114F40878D86F98930DF8BBC025E2EB1F435976C936DF2E4\n      732B0D37BFEEC56B989C5DA78D584C0E93C950143AF402C36FD9323216AA5446\n      8484BE0C1211915032FBE9C57B17AB4FD61B399A1B626428F406FCB02ED34757\n      96CFE68BA7DA6A66AD114346019280048024863163DB40C52074791A7738AC7A\n      7F1F90324B786283396BD7CC5A68F000F576E5D6C751E020EFEDBF77C9AED7D3\n      D8EDDFBEE79B78CFD0A6D424048251C4FD8EDCEEE447A5DF5B89DFF5C77BCB97\n      21532C3B78B0B634F7ADF71D3E75AED629F49F8CF92C7C164091E630551EA4B7\n      20DCE20DE6D4E637CAAA799874FB6524975929D3D84AA9AD34667169751A5004\n      63170EE436BBBCCF0D49CC2F1F64BF70C9A092E9D70E2F3F59F500E0963AEDA7\n      3BAADD894DD7E2BD5AE530E815C03B4F84CC56B16C02C00BB633447777CB4DE6\n      47B30A0AB1AD4F4E66F9BA8CF2EA4642574802019EAF4B52DB24A3EDC608F020\n      0499F55F161E3D978381E09C199247AC922BED66A24875855107356F7DF3D8E5\n      6FE991418DD39050603FF0312E7640C081228D99D55C0EC70EF141DF060F7DFA\n      B9A7FE7539E1A569969C347435252EE813B039B67D28CB5BA584B20EC22E2EEA\n      96F66CD5CAD6C0A916D8A7B298672BBBF362B49D2F14D3F77DEAF24D3717DA51\n      CE65251627DFFED0FD2F7F4B9C1D44B3517C7CA3DE4C2D4078A1E37A607988C9\n      441DE8E15E4627CA958B7532827295CDB9DBFEE66DC1DE0211C8498B9C88C45D\n      298A66F3C58D07EF7A50CC072C31A9321B4A9C1611C440CD04C23652CAA24CB7\n      136F0CEBB0B072DB2FEFED9FE879FEB1272FDFB28B718988341E5548B8A023EC\n      86351837E014BB69EBE58A2F3DBC7CE49E0E16038B496319CB756552244B944F\n      527F54E71569EE78C3A6894DA30F7CF911E6E5CD3A4C260DAF2737FFE9E5B4B7\n      8D15CFF6E5800873B62F938A40751B4448B7AE9311A12DF2E84CB8DACE4188C0\n      94A39883D0B5FC6085A3CCB08A80FF67800AC876819AAE11C481554F38E311E2\n      D8AE615B0E85D1DB1FECC694155E59478CEDC2023CF62C6F51BB6E804A3030DB\n      A502A2C8026101510E0863AD244AB2B6A702FC0C0E07F0EE91879EDEB173626C\n      DB908AC5CFEE7D09E0F9FAD76CF18A467620DACBD6E03A4DEC240679CB0BE6C8\n      F31B5FF9F2F75E3C72F8231FB9E31DBFF45664918B5BBEA6C8CAB66EAB6216EC\n      D98FC0477694F627C3914980053149785A074567B80016A4B6E7DBEA345047C0\n      85700B32F304E78B63C6268175BCB69E235B88171347D0A8E325A57A8F7A6A91\n      6D76D201BD78CFF4241DD3173BF5B05A5C2B68A74194EFC81054B0E42DDBF583\n      BDCEAA7BF8A9854B7FF1D6E2AD7D48A6D3DF38B3F0AF4B3A1231D5090F3C262E\n      B93CDF8CA6857676ECDA7BE4C553478EB46233B696B68E8BD61943DB407D8E23\n      607EB9B40C9FD546A5DD20B17D03386B1A00630168D3CDEBF3EDDF5A77B3D9F6\n      9766559F6E6D48DAF9B1151EA3C10C4136E9E162719B17EEA2DE80898C587BE7\n      BBDFC8F79A27EEBEFFEDBF7E5DF10296F816467C87252FD0EF7FE444F31821F9\n      0D435B5E75A4F281E5D7BFF946D45E4628E5E05283BCD35F524E5613B79B55D6\n      1F23AA9BE0715C6CEA0DB4884FDE333BA8F33DC03EDAB4A3E1279E9B8B546DC7\n      AECD4F3D7CE6C29D43BBB797198469BCB1B4D13A394F561AC533F5A81EE03925\n      5BDC2922334AC500C04B64F2B9E89AAB86F6EC06C1BD41AC2E0B142CBD2715EB\n      007D3110E7A0DF0BFCD003BDADF8F4CDBF3072F4C1F51F7C03D794B31C54E7B8\n      7FB689B85B073451D1A0716A00995CA4902B94657B4AD46E108041D0DC2E4F00\n      9C0384C73CDBEF01F3990A08772C2D667262AA69DB7148A0D1A6B03418964782\n      69B7E18F79A5EBF60F9E3C3B73741647F99E35DA5C55ECECB2C8FB665B1FED91\n      FE505CBF79B4677F9F1F9BB666B9200DB04AA40F2A0D70A674CF42E3703B0A99\n      5FD2B2D76763F9524BA44FAE2ECFF9F9338999ADB6DBB61345FB5696DA31295B\n      CECF5A23B3FD7150A6611052D7E14290AC59520A01690EDC3415162F2CB647B5\n      753DEFF8E0E52307347746B6EEFE3ABE68788CE3046C0E48B531078D6B32A89D\n      A131F99E3FBB4A4FD682DE71A6C7A69F7EF1EEDF7D7A99A373CC3F9D8A4591A4\n      40BD220584702401A9CFC154DA5A24F240A3DA2ABDEA6A530847BBFB8A2D51D9\n      F652AE60CAEC6E86D002E1FE726E5FC51D27DA95B8CF676FDADDBFA797CF37E2\n      6FBC509F917D5591CCB6AA473A8673715EE9FE6F89D01643A4DD8CF16DA753B6\n      3F69F13F7B27B662D071DD00440DE9EEDE647CACD4AB5B08DD2A6AF7756ACB99\n      B6B5D4762864F21E2C247219B27CA64178E515EDCD972E5569DE0575D9DCB937\n      F7A6F76E0D06D680A10C2A669E81DB86430CE6030B9652D0DFCA4D43835D8ACF\n      B1AF7DF49EA517E1D5BE13697C54E92A62392C20A225A8DD57B60265667C6D1E\n      5B9368256F4684804C2A358EABFB8A646977490EB7F38323EC039FBB32778949\n      45D97016B8F4F14F1FFEDE5F1DED0C14CF7271BCD16C091C718E332B16321728\n      42DADE475D2178BC54BA58A763B4E8F599DB3FFEB6BEEB47818469E40BA212B6\n      9A230DBA669EFBD233CBCFC6E95A236A0B30A3F32A3995A46B2817615FE3B46C\n      D29D243741901F2EDEF4AE3D9591FCF143CF5F343A15DAFD362308C08F72EDDE\n      AC0161A05D92956921F29DB559F4C05767713C089261298D16B96C229527F176\n      BF30620072EB7BDEBD6972D3D0FD9F7E5C4A27887A6131BDABF08D7F7A993BD0\n      34320691406D3DC8B54DB00C3999C13BBFAE992F54DDAEAAAC65C2927F662150\n      92D589B3ED665039C676E176ABF7D426914D26DBAB84703EEBA6EABEEE5AAAB1\n      45D1EE36614690B6400A960281EAB22D33CAB1B847ED05092A6A05CE1E2C5DD3\n      5A1059C44C086E18F590B586C8C83CE86CC8F7F5F5C6638F1CBAFD8E9B8240AC\n      576B9FFFCCF7EE7CFD9D7B2FEBE76283C145741EE417F5DA9D56F5473F7AEA2B\n      5F3C343FDB6AB5D42DB7EEFAE4A7DF9A2B54EC698A4C6DDA6031EA95A630DCAD\n      8E1A5B57A0A8DB5666BB5D800BE36C8BB1A364078914D890D82D55BB819E6D47\n      67078CBA9B9CDD0BD909B3449855F8548AB9D7A1605C63A793DFA8E86756CC14\n      D6E3B8F1B3A5F25A485F33D80C57F2AB81F49A94FB182C3ACC8E48904C242C7D\n      523AFCC0B9AD575D32F0DE1D2A6D9CFAA799E64FE24EB31E811C3365D74D2EBB\n      326827F38D26DABDF7E2B9B9B34F1E5CE66A5B95B74E8AFAB4664D2563E67018\n      AF322E386A0B294A902E4BDB72A775FEC4EEBD74456D57E9763768BA4AF7FC66\n      A1DD4F855B62D4FE811F758AD3049BD0619BFDF26E371C07099CAC968BFE1B3E\n      7541F531B4BABA7CD31F5C0C08251A0A74BBEFE5E6EF693D74D753F17A2BEF95\n      D06A5FEF07966F7DC3B5862F60D5D6C44BB14B4A795674ECCE06402060AA9D7D\n      7084160B5D9992AA3A79EF2C9F8EF74C8C2AD130A4F7A513CD432F9E3870E0BA\n      E32F9E49C9DA0D575F1C260627F5248DCECCA727E7F17C249668344FE9725456\n      82F6858D21628644BF886B43BDFAC0D5C3BB763025562DFAB29C0067E4DA3824\n      1E216E62F268E9E8DE479FBEFFE6B780ABDBF2B5CFAD9E3B17C7815CC29553B1\n      A892358D42D5DE64E882CB6C671F20234028041328425B18D1B61BA527B42689\n      612DB497221449D58A53984A172C2D780330DEC4D6FA9080E475FA8BBD9B0B0B\n      61AB30A8729B07E2EDBBFA0F1F5D3C32AF516FAECAD46AA4D737DA93E59EA130\n      28C5D56B0BEE2DE3BDC64B3AC60912370731E6B425C3D524B87FBE792C058189\n      60D27A1C676BA5B7D66A1D8F9A8B5E3097E8A5B6AC0A90B13006AC39B00AE421\n      02999FF33C0F242D06EEC38CB0AC59535B8D9B55381CD09E528D61E782201E50\n      CAC9E9B77DE88A41307BFED6F15D5FC6FB8687532C206572586F76D924C2659D\n      6EDB57B8FD772F32E371501CA59D4DF77FF5A7CFFEFDA946989B61EE917AA306\n      A1E6D24ED48210F400E28D75A6CAB6B0D9BE82EE36A06D96C922D2D628409203\n      9E1B6CF9D9D62490E638F0BC2D83DE362A4799235BF10DBB276EDE16A064E368\n      9DDE7DB4B920826529A63B8D53F5343B16F6EAB1889FDB1844FF0F1D765B606C\n      0B3881D9B185529BD5AF901C4409CC820B5F8C6408A8BBADD5DDE19DEF9DB155\n      54DC4D1B660B1BD6057631D3767C6AF020867AF0FB3A27740591A162E59224F6\n      3DC8FA95B77D60F7AE2B3C60073FD7630B9910F7F0467BF2C25666B98758027E\n      CF4F7382F8FED243F51FFCF5A3ED5AB16AC293B1396D709DEA9C017563120522\n      4C827705A9959D96C888303BF5D83DFF416CBD4B742472454FC5DDD85DD4C351\n      38384A7EF99397F4ED073952318A792199F9CED217FFF0C118E517889949552D\n      552DCE6311C3FD876E002393D63D890A369B8AE54BB118C739944B5FFF7FBF73\n      F0D67190072C7621A323B64AE4AADF21A77F7C76F6FE05548D57E7EA42782B3C\n      9D51FC2C670D1C0ACA7B51BA93065B0873FCD5ABDEBC757C67FFEC91639B4BBD\n      9E32CC23B10607C6DCAC5F05C40FC9799D240E83C0F1898EF28F7CF7ECF26944\n      FDC23A4FCE71BD92763C27DDEA16C65159E61A97FED7A9ED7B267FF467F7AF2D\n      24E564288D44F9DAE0863FBBC219AA2A1531309B8E3D8C016250674DDFE7AB82\n      D635E36EF374762053E16CB70E671DA4D9AE2FE936619E5F7AFB7AE6EDECFB98\n      E9D2092A6417CB3A3F33DACBA427ED76CD58C56721185B674DBBDBD70180412A\n      22D7F544923FF2C2ECD0687E6CC2D386135DCEAEECC22A02F629C01456A02C07\n      4B7DECE8F4E1E74EFCC23BDF013EFD91871E79F9C8DCFBFECBAF61DC666E8C74\n      6449D8EFBDEF3F1EFFFBCF7EE7E927E7D2D408832A95E0339FFFD09D6F9B5471\n      6C5B9F8082454A198524CB8C30E92604D110E7F62023C98E37A2AC0D07618E88\n      30AA23451B740E503492D99FAC3B3EA389EE8923DC4D2ADB82605BF850B7DA08\n      F08C53B0651D4E3BE146451C5A9653C69962FCF15AE7D966FFEB76B68A1BB9A6\n      AFBC1A8E7C948262D0940B10BF11EB04A477E691666E70D3A6DFBE384D565FFA\n      E451F394DB8AEA1C64A22A074172E5F5B946E7DCD28ADC7BC9DE5663F9A9C7D6\n      D6D7065B283DA31AD392D4C00F3127D1F6C8728841E6839C91DC1E8DCC24AACC\n      F6856DCAA24C798BEE1E61B771E6E7CB3FB63DD8522FED760CC3A45913E4DA59\n      DB1496B7BAB9CDBED34712D9D998B8A9F8BEB7BFF7DFBFFDEDC28EE8CEDFBC45\n      1391706E0294738A47BFF2D2239F9B099B432EC7EEEB97DEFA8B0750AE619275\n      CC82543ACA63615F681CB838A0906F3BDB90140E2C10F75DA99BF1B947974FDF\n      B774FD9EDDD4AC602F5858CDFDC7F79FBDEEFA6B34AF1F3C7AF4B6DBF76F721C\n      BDD6809B5A6BF0974EB7CEC564365D5F72F462DABF58F734AB0D797C4A578AAE\n      E7A94E7F981CB866F4826D1EE70B0E73B5721DB7A04842DC16F1810843DDDCF1\n      CDEF3CB2F51274D58D37DCF7BD9987EF9EA3EEE039A966693A933605EE31BC42\n      D01AE96EA8236B9D21456C13B5C63EA3058FF4FB6E08624BA64594AFF2B44AC8\n      6227AEF3D4A14EE8F91A241EB23D4AA9E08097857C796BDE94941CA381DF695E\n      B26F7064BCF4E3075E6A8ADE34A4EBB8516F525F577A3C5AA6ED7DC4DC3A562A\n      94495BA15CE2414A70D68C7DB6D4711F9CA9CF23C601F15452266457DFC87A6D\n      6D498B0DDF3F17C9358E57B86A6849B34E1E905CDAEE66D0D0F502E6DAAA8E3D\n      A990F56F339A45820024F75D0F1CE1B8413B5C5416516E94BFE38FAE2AEEA028\n      D835BEFB0B78DFC83047C09CB242C956C799242A87EA57DDB1F5AA776FE703B1\n      17F69BE5BEAFFEF7EFACDC5F5B0BFC93AE73BA93345301F92F6D4735586B6AFD\n      350613651B036C1525B36FDD1A7DB73E0B73F44A2B735796837EA75B077B47BD\n      64CAD561A2464BC5D7ED1B1D736B4D8D1F3A2B0F9EAA6F18671EE1D39158A8D6\n      6DA1DA1E8F3D5FD9F84F6D605D2EC4AF1C1CA4191CDA4D1F93758A66C7BBBA8E\n      D09E37052A009B9FEDFDE26C0B8EBE6234B3CA89FDA8AC6B9349092E57658DEB\n      5967294CB6AD7218CFA80AC240DEA3F9E26EC553D5D87175F1965F1C744B0D8C\n      7214F9C8E5868216CF6B6A0FAEC0D01397BA128CBF93D03808870FFD8F938FFE\n      CB915817CE19369DD005E4C4847B5A7A80345A726B6A6D91566724DD6D7E736C\n      1FA9DDD6C356F9CB04602D29569CE60505331CF9FD23FA7D9FBCACE79A5CD2A4\n      9E9F239E387BEFC6FFF8D0C3F18ABFE4D15985169A9D58EB48DB550BA8CF88A3\n      6DCD5C14B4992816F762BE99E4B01BBFFE63EF1EBE634AE114462DB1EAE8658F\n      B67C49EB2F452F7EF7C5419A7FE1A193BA1D823C9FE19D93295ED17EEACA3E9C\n      6C47EE361AB8CEDA45378F5D74EDD4E9E75F180E0A15C853046825890B214A6D\n      01D17315C56B1BEBA11B967B0BD8EB3DF5F0CAB38F4102F7D653B56AF0994E9D\n      B2740B2B8CC8A22C6E5CFBA1A9CD576D7FF253CF1F3B7836ACF6634E833DE6C6\n      FFF3DA704B5BE8C8B6ABD3C01E767BB547B37B90DDEAC80CD86D3FCBF902023E\n      7F64E1FCCB5654A0EC790C962049D6E7D2F579D6536ABBA15CC82216774F4A00\n      7E6687301C5B1ACDAAA3D9895D78AF8F400903E6B13C606F2A3BBE57DC5875BE\n      F4856FDE7060DF55374E195133BA88ECA620B0B34024B67556048BCB40F03CFA\n      F0B30E2D5E79C5F5605DFEE44F3E7ACDB5D72A232EBF72F7A6910A73D0FCECCA\n      57BFF4C3CFDE751FF8CBFEBE711033F5D6F29D6FBFFAAE4F7EB0545EE9BA1F64\n      B2CE05DB30F2EA7E5897D9BB1BE54EC68DBAAB0E90ED8916B6462A3A482758C7\n      582446717B0D73BEE315BF325D192F5AA59F99E4CC6C930825AE3491206DBF51\n      8C9F5B439B883341C8B164F5E1D5A1CBA6F826C1529490752FCD53E149939248\n      526EDA411BA2B6FE246D74D89E8FBE26F59AD31F3FC29F71EBF13A7770C2CB81\n      1F5F7DC06FA56B3333E9BEFD7BB4D978F6F1B57367073A389997B5B3D25991A2\n      462807FDA159CE96A3652C93B606BF09A0CD98AD7CDB9D2BC063F34A2E773B48\n      6DD3B5A54AD295B93065CC2EB5AB34521C7832B595550703C7157D6F2CC88F39\n      6432C78A480669F9B51FDCBE6937FBEE177EF0FA77DC34764B9F24CD3455C453\n      A4E61CF952EDE4B7AAB843F8DE995FFEED37A2C29A414D99C22C8600147E9F47\n      4A9EDD9382F85476835662668B3AB449D2884FD3E7BE3DBBB377A4925F97246D\n      B647EFBB77A1B7B774E19EDC8F0E1EDBBC6DE2AA5D1E5D8B51C7EFA462AE2A8F\n      CF9B9966BBEA264B3A3C59759679540EE56637F48C1974DDBC16C3617AEDE543\n      DB3633A3EBD81EE70E14E64E101B92E05CD1719D871F9C5FAAE33BDF7545ADBA\n      F8CDCF9E6CAF4FD658EBACB371ACEE6D8822F64C48B23D20637503F8415B39F3\n      733CE1058A2D6331351038266AE5C03E7B5EDD0DCE44E9B976142913F83E02E2\n      8C3BB6DC42ED232100BC260BA5F1222B763A83D4276AE935077662E3FFEC67A7\n      4D3E58D3B50EF6755AF129E9F1F566DEBA69B8303E944BA50CB81BC0925090C9\n      CE744D3D7CA6BEC6722D9E860C5510DD39345CDD586D505DA7743D318B895E10\n      664549633B4D209D24E015E033D8308FD09052D0C8B62A07E04B332726EDC334\n      324F61B65133857245D3D874297AF3EF5DCE7A10CA5D34B1F773F892D161FBDC\n      0825FA18DEE6B8E324CDFBEBB7BE67DFD4CDA3A2C2F3F9FED6A9E02B7FF6BDE4\n      889977C9CB0C2F7019735B4F01B969CBC9D2969DEC5E0356CCD8AA323A7F9AD8\n      70CEAD4563346BDF92E70B2F5991B3CF732FE8AB8CEAB41F2779C50F5CB4E3B2\n      4D8E4E966AB4EF1B4FAD9C6A9996CB8EB7C4C97ADCE24977ABD3AA3C84F57F6E\n      0E7D9508B3B3E2E8BC24660C2C20CB0A9BB612F6AAF90BC3B0DB29DA85BCEECF\n      2CFBAEB33D4C982CD77A6B10AA202352B880F58A8482DB05F4538A87464EF8DE\n      A4E30DFB7EBF6AB9C5F61B7E65D7C08E86A12963832AE6340F961EB47A1933B0\n      A61C036FB92E96AE7D860026BCD5F383BB9E5A7A26114E78528B1329AE6B5761\n      C9807EA815D0C2229A45AC6E31C79E79CD5634EB06B2CDD8F0E614FEA193ABB8\n      9D5D45329A867D43FCBF7CE28AF2D5816811E2B9209D375ED4FFF8473F9547FD\n      E59C3BABF1F446B329055877B8A24B1C87BAD861205141826D2A16F661B995E6\n      3C4FDEF6D1B70FBE69A7400D07A114EE44D75C27A242B375EF9E2FDEB3253F74\n      ECC1B9CE9CED84382B9BA7243D239C98A95E166D9578172BB84E7BE7B52397DD\n      3271E8D18787BDFCE4D040C463E45390052C93417E2E9F4891C4BCDD680F0EF5\n      7BE5DE8DE9CE63F79C4669A51DA35569CE8A8EA27C332B0CA421EEAB5DF7E1B1\n      B11BA6E67EDCBCE70B0F94EAA39E0A555FE3A63FBBA67409CC51C2740E804640\n      EAD923845687D90E424B73E74F9DDB3E7B82CE1F25B46D9AAF365965988F75B7\n      B9B4BBAF963D8D283BAB6E3BEE2024427B42C7F24AD6236A4F233819053A9616\n      2C166781661B8AED6173A35DD04D9E47A3043FFFF4FA173FF79DFFFABBEFDA7F\n      75C5A0861139834A00D41AA7104712E09B4362D2D9B9C60FBE77DFEDB7DDD953\n      197AECD1A78E1E7DF9C65B0E1C7AEEA13FF8E3F7761A9D7B7FF0C2173E75F7B3\n      47A7C77BC37CC9CDE57ACE9D5B0709FAAD1FFEF5F5376DE79D69429DACC7CF26\n      9E5492521B27AF7650A3F3FBA49E6D0CED76979DBF79E07E3050407E6D241A48\n      B7AD51579944E83E91C7D68ABB9731D9A1556B2A09CBE691B570021492081AF9\n      51B17668D91F666C14B1BADF7EAC265D54B9B857AB4642EA4E9427124089D398\n      614E3A008046ABE78AA78FB72EFDE80131ACCEFCD5D1D613B8AD6BF6111CBCC7\n      715A571E7030E3875FAC5D7CC9CE30D77CE1C9FAF4F1724AF8825A9F13FE529A\n      AE1322684011F3602D144F0C6FD9C2AB257A5B8C5288DB5DD2EE3E08CECE53A8\n      574E109E57935D04C854B2675B6A05DCB8CCFA3F30975A1ADC9BCF8F05CE1478\n      2086A71ABDEADA63BFFA9137AF3E1EFDE4C78FBCEDC3370D5FE4A248344CE4E5\n      343DAE1EFEEB938B877BE9A633BFF45BB793D186D4EB7031AA439926B4609CC1\n      0272A8449EDDD7D0890521C789F5060357BDEA9FFA492DD7D09BFA3B915C576A\n      D74B2FA0E5C5B3B7BF6EE48967D4E2EAF2EB6E2B1461999A4C71B4D6C22F9D22\n      7355BC665A1B549D49BD39AE231917A92E103C1C04E3418136AA43B9E4A60393\n      93E33E322D10B876370590C7C5C0694E61697D75FC07DF3F77F5EDA3BB2E727E\n      FCF585170EE68497CEEBD513CDF26CC75385A480DDCC3DF394A79008B942094C\n      A011DC15E9708E8D7864204017EFDAFAC2938F4B16D4B1BBA6BD997ADC711C61\n      9598149D0E049FE3F9202BA254145C365EAC8C38B40FC78C57CBAEBA7ADFA5EB\n      8B1BC766E622D76D33AFD6E661D053F1586F5CBDA2D7B978AC0F6C87AB98A339\n      2883D4758FACC707E7EA75BF5C8B79D973FA10DE393454AFADA52EAAA6BC29D0\n      626ACE2832AF1504806B1F73042E56A7361334B06029C8E55D8F663534DB6B61\n      6B6CE71FA71230B205F331D95B721BFBDF5CBCEADDDBEC667A78F1E47E4B8443\n      B6594E8A2146B6B9EE26160F0ED55FFF1B57E676E6799E178A7D0B4FC4FFFAB1\n      07F1626EDE2787355F003B68DBE4906D0EB3BB901667ECC15FA25D611B24B2E2\n      93D59190EFD23E0FC9B635DB673F48D56D25F5FC60AA4CA688338EFD926AED1A\n      09AFDB3A34E4B522142D8ADE6F3DBAB480BD65479DA8A5A757DA69D6F782FFD7\n      65D19FE7425B3CCC4E48234B5B04BB36C6B3C4B632C99A5529841F065D1C2499\n      43EC928D93FD9C1590EC0731CA404764A964B7999875898EDD5C8777589F8EB6\n      E582294AFB8195C8C6150706AF7F7DAFF156ECEE032B82F2334E6ACFFE938038\n      9EFD5498063F4CA5F290719CBE630FD7EEFEFC8BACD617617644778E4B9D6A90\n      5B1C398995B660A0B223F3CA741BC48DDDD2CD7C2ACBDAFAED8222613BF9A2B0\n      E4A43B423C2AFC524FEBFD775DD77F850B5CA3605DBD843687BEF2A11FAD7EAF\n      B35C70E7997BA6DE5EED74B86DB133A0105C6068CF818409241FCEE5F711B19D\n      E403965EF3BBAFDFF29E2BA4534328019907F645A986035655F53EF4CFF7E8B9\n      5A4F676AFAE12529D132894E1B728ABB0D22FADC782A953B6DEF5F3279E9F081\n      5FDAFDDC03F781D7DC313919F1C80476AFEE7CCF89E3728D5DD75B5F5E7783A0\n      D4578A9AFAF17B4FB54061E9E29A14B332497132E9F6F4265E6E2ABEE62343BD\n      9714D213951F7EE23E79DC0B554915366EFCD09595EB5C4EC18B16011539B5DD\n      4C8EA6CA3E32203B3CDA3D59937544995759F19597B2033876CBEB3C66668DA6\n      D9A65AF6E43E42BBBE8991DC2B8506482827A3C9AC53C66447EC2D2FDAB75152\n      96B295EDC7055201D3FB8F3DF2DC57BFFCD823F71FFBA77FFE9BAB6E2809B542\n      50414B977AC6EEC1E03CF5CAB56A73667AE31F3EF7ED8DB5164CCCC2E2FA9933\n      A73FF9A93F9F9E99DBB56747FF20FDCC5D5FBAFF47A790E8EF2BE60BBD0DCCAA\n      5AB9F3F3F17BDEF7BA8F7FF2B7305DB104665BC332CDA9B3C69B0CE2CF2BBCF3\n      E60E06FF0A119AEED37368F62BC81E47D12DA46A483530681E99E597ED0D53F6\n      A2BA9B6EDD7D356DB9D6820AE60C6C8907F29AD3C497F9E543E78A3D813B4608\n      0FE4F3E9C2CB7393578FA73DB1310DDA0C6CC3AC2B9C348F12DA72E70D1385E3\n      632F3EBE36F5FB97063BFD131F79A6F104E67E9C5070147D84D6F65FAB7B06CB\n      4F3EB932BEB97F6C4C4F1F91CF3FE3C5BAB3411AF3B1339726AB9809EADB9D20\n      05EBA422CC239098247B2A408A34D78228D0BE38EB4BE8EE0E7659B05B1AED16\n      8132E900A04DEDE332C00329619B7DC19E7B61C74E0FEE77F1AE5C38EAB0DD9A\n      2D3A736F78FFCEEBDEFAFAFFF8F47796EBF577FFC1EDB9E14E83B73C9F065C2C\n      DEDB7AE01F1A8DEAECF56FDABDE7759B38D9404084A987C10B903AEDF749A990\n      821AB74193207B6AC94F7044599B2FA9EAD39ACF34370FCB4EBACE9CDD67A783\n      A32F3C73D3CDFDCB67071E7FE6E80DB7F58E0CBB7CBD638FD0C6DECC229B5E52\n      73CDC6BA11ABD4994FF1B924AD89A488F468E04DE6C23EAD8B2A9A1C74AEBB72\n      73A99C50B763CFD129E3FA2102FF5A58A6EC827FFFEAE9A109F69A378E9D391E\n      FDE06B4B1B555343E96CEA9F4E58CB070D0FEE18CCB44839771C2F5F2C3BD4F3\n      01CF92CEA0678688EC67FC377FE55D67AA47BFF5ED2782306C1BC85677B69DD6\n      4091E0AC5866452101944BB9359415E68F876C30E0BD9095F5F6544F78D59EED\n      475E9E39B5D2427DBD1B691471F042C5BC68ECCAA9EBC6077B49A665C1B9817B\n      66CEF32BCD27573B35B7D488449FE70D20BCA5AF37EAD468CEDD68B7EA915C16\n      6486B2D35AB78CF130784CDB3C15530CD91B109267B044B6E59A760FDA28C128\n      40BDEDF6085CBA8D7486E24DE55CE3D6DF1C9C3C90D3C227B97D53577E1EEF1D\n      EC234E48951871E956E68D79D1D864FB8EDFBA928DBB919F14C3DC897B56FEE3\n      B3479CB5BE69A69ED1C9AAB04F83A2B6E1C148FB200F2B3835B55D449E3D60E9\n      758910B01B74167061F7A003CE8CB7EDF552BA50E9D95E4EB721D6D3290C05E2\n      F6CB47B7BA6D47ACA705EFF09CBAFF706B29AC9C409D73757E76B595583D9E29\n      FB570E0EEA9FDF2C44AFEE1EDAC76B741F3E633BC06D474CB63D6E2B14F6B03C\n      CB1E2263FBA9EC316ABB97609B1BEC2FD97E53D43D5F9F6D6012FB7C4691F561\n      C3F2D85D239D1586E0BA2E52032EDA990F3629556AA5C5ADF937BF6B2AEC3BE9\n      B8D2AE884B2551C8F504B10FF7A4D4B72E92A41DEA09AA807A3C3570EF978F3E\n      7977BDC4C7AAEDCECB6E72C2966673013866B709CBA5631059D2B6C0819EE8EA\n      F1ACA4C36CB1EE7CABA282B1D9EE835C898A6D011991AE5F587BFFDF5E377A75\n      DE8027F789F612966C7AF8EF9E7FF6E3C7CE159D737EB822CC62BD0A702101C8\n      896BE7207095911E4F4672B98B30BF80E4B168EE7DEF0DFB7FFF76936B1A1325\n      BCAD4DAC7403C8DC477D67EE3FF2C8BFDDF3CE6B3FF0D8179F6C373B2BAC7D54\n      9A691D54C1D3877C2A4E76E122C4D0D8DE81EBDEBBF7C4A3F7F3EAC6EEA9CD12\n      989D59DC825560C0E9AE679F49661F93651637D6FB467A73F9CAE107CF9E3CB8\n      5EA4836B42CEE1B4A53AE36E6F2972FB2F3457FD693FDE9214E2BD2B3F5C7DEC\n      9F9F7363AF85E7F7FECAF885BF7A21CCA72B4AC809524B85862A0AAFD8DDBC57\n      3608336223D9FFD967BDBCFA943F83BB8F8BC25D27685F54DD2A62F6BC18921D\n      AE83D046B9AC5BC4AE7FD6ED49B3A7A9757B641C20C2EC317FF0CF3D5CB6A895\n      494127497239FF4B5FFCF637BF7AE8B927563FF1993FFE955FDB67C81A567920\n      11600504D7343DCF3D79E6BBDFFDE9A143F34F3C7A46511AF3165C68EF85939F\n      FDFC47BFF8A57FDB58C7870E1DAAAE3643CF0F3D9CF7ADCACD79B995D566A142\n      BFFDC3BFDBB52F9FA44BD9136B0840AE639F024314C835963D3430DBD1B67C96\n      9D0554D8B575D1ACCF12DE664CB7E507A208D4731B999A51555B0297DD1E51AB\n      1AB3521ECA7657BBED66D25E9659A190781B7E121829B913BB26B7F0D4424F29\n      703701917864A9FFDCBD878BDB7CB29751DE719A21B1FBEC09890A60DDE3C2BC\n      6051F1E8E4C1BB677B7F7DDB961B364D7FF4F9EA1388E7E284682106355ABDF8\n      0A39B16DE2D9676BD8ED5C7461A1BDDCF7D803623D598EDCE45CE2CFA5D1A236\n      6DE550E3780AE8054528E95099C0C04065710017FB14D5576571970BBB0FCAE8\n      9E01B0BB1BDD62294C87C22ADBDE0537EC0AE5DA664B3FF63C604597B72F025F\n      88F05627EF24BAB877E917FE765B31B7F7BE8F1D63C3D14D7FD82774ECB73653\n      E4A23679E9DF4E3FF5ADA3E144FA9AF75E50992A1AE1B89147254FCD9AC88BDC\n      D84802B0A8944704B688100A1FF4714DAF8BF4985B7B6179CBA817755610DD56\n      5BE979F2E00397EEC37DEEFE9FDE7778684F70F15513C9FAAADB428EC8AD34D0\n      91738DE98D4ECD3875E49E8BD5F1849F88DB412CC67C72617F7100CB8AD29E8C\n      B66D2E5E79E5484F2FA0493B0C7BEC9391BD06CA77BC70CB23F7AE74A2E6CD6F\n      DCE6578AFFF2F9678E3CA3905F9E339D19E32EC9C04791E4DC1E2FE582DA53F4\n      79404215758A586D29FABDA65D94C96BAFBEF8E6DFB9F3EB9FFDD7679F98F182\n      C10D19CEC640CC6A8377ECC3076DCB814E12213952AC5462F158C1F413DA8383\n      016AFC68F9A2F1E14DC3534F9F3C77AAB921F27E2C505EFAA189C6BDCE4D6383\n      534E008B94687B4444207278B5F6742DD9A0A556620698334CC8444F59C48DB0\n      B7506D37D76A9D35E39D22E4A856EB52040685D9B30B3A0C12D1B8F6C83C0E90\n      EDF6713DE63106633259851F0619B8643BAD0FB6B7944BF537FEC150697722D3\n      B293DF3775CD17F0256383BE741C94F4FB6A2BF6C71C357C317FCDEF5E40FB60\n      09CB546CBAFFF3878E7C7365B18867859CE1A4639FD4216D873FB5FDDB4C58A7\n      024E46D82614EAC2CD6022A82BAD3B9354713FCDB6DB58D0024B0616C4C3DB0B\n      B9B1C0EB4B486FD4B86A7FB86373319796B50C37FCF8B153B3C74EA76D929F63\n      E8B9AA335B83ABD58CD1E87FFD855F3D5D681FC9614BB5B627DAEEA8656510CB\n      7E94AAEC442D2C70973203DF0A88763B02240C82C0C95EB74798B3B679F8DDEC\n      C082073704C628B159567078CE9751E8ADFB24DAEC0F0CC6DE580E8CC1F28DEF\n      2C4E6EFB9F7CBD07B85D577926BCEAAEA79F7B6EEF55BDD82AB625D9C215830D\n      849E84244098B40990CC4FCA240C102613480833C00C6993022484E200066CDC\n      5B6CC996255B5DBABABABA57B7B7D3CFD97DEFB566AD7DAE4C9EF9F3FF57B69E\n      FB48BAE79CBDF75ADFF77EEB7BBFF74D72E8C8C96E60629545B48A351198158E\n      4C445448E3D61E232E6C8805E64C773CFAE5C9EA225A62EC1241D7A52C799460\n      8A1291103B9E802E3E6E0D496C120125311849AD0F117DA5642A8CA774230EB5\n      3A2086B2B1578D46ED9CCAFD77FCC1CE6D1F686BB2868037444E1F27E6E6A21F\n      7FE8C9CA9A13727301800B1E5813753C7689E7AADC008AB8358E08CE6D5AEF7E\n      B8D69BC8EA7E63FF0337EFFEFD77BB6D0E0455D5ABB3A0E98AC24B444ECF2D95\n      8BC77EFB897BDFF6AEE32F2ECDBE762DCDE8723DBC04C834F74C8D0D857C9B9A\n      3408EB19EFBDF3E3C699674FE159B47374D42315660418AA3454C2486A4F513D\n      E5BA9E4ED9D20A245AA36F98D4E68C177F52771BC866561390AA15752492AA58\n      9EC3D15B3EB51BF6D5FD9AAF9ADDDFFDDC71EFE95C21EA053B96EEF8E33E30EA\n      2A282F0038173B2FD1165A10696E4B7D2CAE85D0A6D6D0E6ACE91B542BB13C28\n      03E2790532CF853123543C2429FFE172ECCBB3D5783A82781949FA15FF98CBA3\n      512CE708E52815A4AA54D9937A5452D004F10413A80988659EA6B85D248DCFFC\n      C9979E7CEACAD4F9A5DB6FE9F9C6373F9EEDD41C90D3DD9ED74E4CBD7CFEDAC9\n      8B93CFBC7062EDFA6A1405060BDB18E8EB6E3FBFBEFEE18F7F70FBC89EFFF207\n      7F54AE543A0D2D4D685B2A59AC882896AA84A8EC389655BEED4D438F3CFCE786\n      BA28DE1BD8DD5C0D02E88548CEC86B2A91C418D92513D99C8ADF449547A48A3C\n      8C1910AD9EA14CFEF21055A5527A14CB1930711F5CBB4160396E3DCB235E9954\n      99947064F13722E30B0CD63A068E140B795283542C4014AAA5572FAB49138EE4\n      9B242804343CB954BFDE68DB73CB7A6AAA5D5399D3B4800B2D25E1A71D60850A\n      4F1693579FB81076695BDEFDC0E96F9D744EDA0CFB6E64E05ABF07967BEF5C1F\n      BFA9F7FACB5173AD3C719432039FF889539C12E027B8CEADC5666EC5D3EAA2E4\n      C0351157A2400B23C347A2D27622E0C95669885A72842DBCCCE2F16551DF482D\n      85782C12DCE0C7C9D64214B24D4166394D2A0F7CE269FD16B9D4D0D4CEAEAE5B\n      9BB4DD6C2267F94DEFDE7DEB4777D69DA99FFCAF976EDFFF40F73D8545E594C6\n      D44CBD03DAD1337F5C3E7F6EF2E623BD47DED91EEAEB1426B9C598DF600AF1D3\n      59AD900A438BCA315091B09578A0CC1259D25BD22E1E3F3F3690212CE09E8E41\n      E6E9674F6452FD7B6EEAFED763178BC5D4DBEFDE9E423328E2C5AA2730F1DA12\n      B87C852D733C43CB6B913259F467C45E09795233DB72E9CE04EF45DE6044332E\n      1C1FCEDD7257A71F4CA655AE221C5287D0828F93F5263CF5CAC9C3F70E27B798\n      2F1E2BFDE06B9514EFAD83D549DF5DC39D02F50684D43CC7713D4315114451A5\n      42B31C106FD7E8A00ADB9C6A3B40EFFCE78299D8FA8DCFBFD478D1EE30DAAE44\n      F66C642E3BA4062D0FFBCCD541C45D5A52004544D74D5380EB4E04BA80AA5A56\n      426D1EBAB92FB29BE7CFACF82459E3C4D5B404300B5678A053DFD38F312B4942\n      22D65C923E35599E6F2AEB9095F14602A9FD30D3A1090C67F716D26600AFCE2C\n      2EA8EA826A2C34FCB2ED3534EC1AF1D16C53C437F1584546F7096406C209ACE8\n      1C51C6B458C85B60395D215BB81470280CD8EFFAF51D5A9F081A2A30778C1FFE\n      3A3C38DC431C40995330D85625D94BA3893B945B7F75C4D1EA49A5DD5A4B7FFF\n      0BCF975EE48B1930EB07B33EB6A588861C608A6479226EB63CAE0B0997EE1021\n      C4A12789CB628789DF41A8B0908672B6B8620781024D0DF4A9642291E95268AA\n      E98E25A24307B2A984A35AA600D773A1F5ECE4F4EA06AA337D51C5AF95F8F58A\n      03A1FDEF24C2CD72F0DF244229B2130F12CB732DD954931241449452281E1793\n      FB41B603A5E29C26BE69D405108E0C5D575515C5DCFE9858B6493D904CFFC895\n      E52B410C8B07AAD1D04ED26A4F1A16027D0066745E1E1BD76F7B504FA42337AC\n      529A442809459545AA38A64B026CCA2446A5069D28826566E4C9CB4F3B2FFCE3\n      2C130819B0CB102EC85BC4F4002AA2E21508228A7C5F0A23C80804E066DF3F16\n      CE40D21EA135FF2FF5D539529A504FD28DEDD41B77721A0F8FFC6AEFED1F1389\n      27203E228A88F666D34D3DF1FF3C7FF69919CA334BC0BB4AE88C2BC7DCB0DB90\n      E2F144C114A821C8D3DC3E5CE93333A6DFDC7264F4F0A73E100CA228D8D0AC52\n      C89C50930AF7549E9BB0A92FBCC050CE7773E79F99A49652B4F915C866908FB1\n      3FC4E8569252B95B18CADCF7FB99F5CB45EBAC3BDAD116E9A54080342625AE19\n      F3E2F91343244255948551667E65AABD0072B99DAF3F539CB95C16D1B528DD04\n      500A6B6AE86746C37BFFF3566D2064A11628CAF2C9C6B1CF4F164A2396B972CB\n      27FB3BDF9169FA7E927641296709816630666D9A9BC8AA08C116DFE38DE57143\n      7C814B226F14CFD571A914C3E2F3E2D8CE21CE1498C54D07222BF25096E1C410\n      55AD78B85C8EA811790CA76BA1234A2E0185122C28894C2A13274C453EB53DF4\n      91DFFCE4D933F585994A5E775F3FF34D92C2C75E9D7AE8EF1F3E76ECDCEC72EB\n      0852801A53D42229EE1FDD39D1D3D5FFE4B913BFFA3B1F3DFECCC9E71F7D3A6B\n      9AED998CD848A1B84D3CF2A0B8CF414352F2AC5B6FEB7FECB1AF98C61A9403C8\n      1D9E1730E939200775586089F5AA88C526002A94C31E023AC9D13BB9195BE2A8\n      E2F756C30FFABEA78A742ED942611438585742F76AAC56ECCB5A49948061CC32\n      8B6E28F4C096C8BDB855360E65BF4DBA3A30AD72FC826618CA44570D399910B1\n      E570E1D9736D8571E5361AD62ABAD42415918D4ADA2C94C5BA1A14D64ECD4FCE\n      CEDFF1C0FD17CFCF39AFD98EEBD41DAA3AFD9C540AB7AE8CED6DAF4E2B731796\n      B6DD9EA6797EE554387D1CDA285A06F5F96666C1D5CAD8F568138B8FE89320D2\n      04C80FB1CB782069A08086A0C51FBA71B01B1F03BC314D817E1A3988F8B33708\n      A5AD9E486BD6A235B6A4695AA1A3E3266E0F13236505B4DFFBD93FBFB97D9F7A\n      F15B93574FD4DFFA5B6F6A765CC7A1A1DB694A1B8D67DABFF6954744587BF023\n      1385095A2B078A8F74EAB8E2019A69B54B27D423AE1960A9344BE5A2B4A38DC0\n      5D22974F5D4ED3B0AFA310391401E3E5572E62D079F3BECE99F9F22B2F576E3F\n      38B0A5CF06B655F7A8E34756855EBAEC4FDBD19C622F0760BA1A5EF75DE88BB5\n      AB983AEDCCA83D3818C146678448583B70A863DB8E048AAA20120F5700BE1C32\n      9321578F3F7F6AE78181F63DFAE206FEA7AF2E05CBF9506D4E85F55947F3086A\n      064143E003C907638A94E9911C311592765D1B50406FE4647DAFF04EFF177EEF\n      FD2B97977EF099571A73C93261454AD76C72AD56AC00D730DA9080936C8D0590\n      A8AAA69B4A04F21CF72A38059C34698A7576F4E04D56C37DEDDCB4CB951A5635\n      6CB447B43DAADCB9BDBD3DE10781E741BDE82927A6D63722BD4CD006A8985019\n      A0D934F079D4182864FA8CF4ECDCDA34677384967C5471FD0A64962EF5814D5B\n      C4D150F2FD812F702BE5722728F277A0884F265E81073A25A3A12696F0C056FE\n      E08747457E63A29E4DEE1A3FFC4DB8BFAF5309A08182EE141A434636AA1F7C7B\n      E7CDBFD4D7206513154AD3F05B5F78014DE5A60C6FDE0BAF07221162E97C1227\n      42A9EF13C8A5C4C446C4482442193E5A224852534D52F0C42E0C5C28424700EC\n      B6249F48A406782AC5837454BBFFA6C189211285EBA8191946FFB935EF854B73\n      3ED0571AEE22D5CF34826BC53ADC546AFBFFA908374FB8641B1CC5847708E3C2\n      4E1ECFBE010FC18D168A48840AA58EED454128BF5714DCE295C96D13C5B25722\n      52621679A8259785F4508A1838796C8F1A4A17D70A0425B5C6A123A3433B3DAC\n      36FDB04E1413A18400DC5077000945F4E448931F4DD2EC31A70E446A58EB78FC\n      6B9333271A009933BE3FC9D03A52C56E15A5BB88C7A28617B7CB0FA41782F815\n      C6AA0DB14701884FB7796C85D09AEF0A445E75412A49CA5B60630B6BA3CCDFFD\n      AEF4DBFF608FD8853850B00A5D713D7AC785AF5FF9D17F7F456FE6379075857A\n      9396EAFA2AE54D829D4882E0A411C10CC17BC2C650269F8A1CB34F7BE0BF7D58\n      3DD01944EB6AA318328B6951C43C85455857DDEF559F78F2B16D437B4F3D761D\n      D6331B4D7F06DA53BC2162E0304A6D23D9047072DDCA7D7FD2C657D42B8FCC8E\n      75E846D6B6E4A976563A3D7049698D806259B6B8BC7426B7512A558A1B3B76ED\n      BF7A76F5F2EB2500F21B962DA5FA3C44FC20BF03DCF53B634A2FF4DD244B466A\n      0026BF796DFA1B55E2260B6F350E7E768F97B788A3E12829B13F1418B0E5F980\n      DE981C6DF1276F24C2CDF142B92964632990C38768335BCACE2978636A5ECAD1\n      4A5D3122966F241F1F3081C097C88C6D22E4313956E49F5C387B7561F5CA3D6F\n      BE5F3C2020F290AA4E5E5EF8C50F7FF6FA2CB1AB107AB507EEDFBF512B9EBC38\n      DBACCB8FA02AC0541451C16A7AC6751A1D0974F7C103A54AF3F1D74F760C77D6\n      966A1D40CBE97AFFC860C56ECE2D2F3861C020F502B056AF8925B16757C7534F\n      FF553A17B0A0CA5162EEFAF2430F3DF2D6B7DEBF6DFB30600D394F8288D41685\n      D80F5C6288C8EE29508FF3180C642F5494162196825F58926842A99B234709E4\n      40EFBCE48E721B720F714921971B4EE4C4289E53974561DCFAC72109A4ECB507\n      A08E52D64B17A8AAA9E31DF5A84E20D42263F9A52BCA9C9FBDB74FC06ADC74C4\n      6EF098EB92509E263799820B8DE5E895474EDF79E4AE95A0B4F6F286530B9B3E\n      5682AE0834CCD185AD87B3C46B3B776C69746747662058B96EBFF684F879A542\n      CAD7EDD48C4F5680EF5087CB4904918C955811476ABF21F90EC88341AC5EB5C9\n      C86B09AA89E0EA8BE81ACFE36E2645B63928F5C664C5665B556AD2E25657DE4C\n      2477A62AC34EB6D76B77F5E2FE5FD7EFFEE521DECC3CF377AF6DD9D13BF0E681\n      6AB328EE8719ADE060FBB96F2F3FFF9DE347EEEDDEF3C044CD16E02332585D6C\n      59DBD078C1D353E211F6F8A2D4005C7C621005ACE2871B68FED2925FA98EF4F5\n      32392D9778FDF44C7115DF7A5B47C8F5C79F5C1CEDD50EDD6472A7D1F434CB0A\n      61A0CCCD45A7171B7304AE233EE344534D87B902FAD08805490515281ED18D21\n      45A1CD62670EDD7E78B4B3938BB7D174F1E0322232613571EAD8623A9B1AB99D\n      90F6ECB7BFBA34F91CE6842FA0F212C77560946CF1C044025340184899752EEE\n      2650B15AD09421058D1198749A511B7EF7A7B68E1FCD4D7E6FE59B5F9872DD6C\n      44DC66E8CE7B700E204B1E3AFB4C0A18214513F14CE7365519E94A446D4A2327\n      B65BD3EFEFE83878D3F6AB53932BF31B559212D59ACA783672F7F7A6B717141C\n      3A02452C3BF4E4ECDA2A076B5158649189F57ED54C330F03AB3F97DADAD6B1BA\n      BC71B15E5B56D47A448B0DB70C225BA78128FB028A622D2F88625A49C455A228\n      4C4A736129FB29968174C61BF4B842E1DEDBB247DFDF03126B5C20DAD4CE8923\n      FF0C6F1DEA51BCC81489D02443484987D5BB7E617CFC1D19DFB0A19BDC9804DF\n      FBD231782D379574E73C361F274224C3B52B09321C132629650191EA1D808910\n      2BCA97406581C08081406B52FD417C34D316608EDA7D4936AE9A037E5E07CDE1\n      8EE0815BC729A8B2B08A7C8728BD27AFF31357D7B842966ACD152D7FBA529FDE\n      A8C07F6F5EE28D832EB0292B1553C764FE8BAD56E2D3514CD1E63CD48D19EBD6\n      4B1122A2BA21B93B7E4029556477450EEAC5D3F38CC56AC7F1B9AEB83091A9C4\n      C2E6BE84DB610FE4DB15735055027B79C79EB603B70C23754D333D240567B0D4\n      7D17B843F144444532112A92C748A5965BA49631ECAC4D75FDF0EFCE9457C5A5\n      A2D9C0BFE2443590900618A12B0390A819A5C6B7884CB247253532811C8FFBE9\n      E5C7A4D9D84C83F91CFA513A4DEAE3A4B90566B0EF8DDFAB7DE0B3B787026641\n      9180A14D194C24BDABF05FFEF058F9558FE9E032AA4CBA7AC54922E862B522C9\n      61206F842049FC7D8C0D65B26D307469FDC1FFFAE1F6B76C0DA222B54A11AB85\n      54C4479F8A672B20D685EE1FFEDD97B7768E5E79C9F28A85861FCD46C5734ED1\n      41B88F66B7C174967B993670E7E713A6DB77EA5B17C7DA40BEDDAB3B3AD5BB19\n      6C22541105B288A66E10558A76B69054B0B1BA524F650C1180CE1E5FD1F0D8C2\n      7AC9F62D2AAA48C7EFDC47EEFA83092F6D21B723547DA094F586F2DA9766AE3D\n      6AF31CBCE78F6ECDDF570879802371BD3894B33C81D8C8376E17846F0C02FC5B\n      66B16C30AB9B0911FA3241885427A7ED35C40DC96890DAF5BE08AA5190410A8A\n      BB649898B9E5F9F56CAE5D51449A944C78819B8B6BF58BE7A71E79ECD574A6F3\n      631FFFA8917008F14E9F9E7EFFCFFFF1C65AD26D32103850CEE889E4A3E9095F\n      EC51852B05D314401E107D756DB123AB1FBDE5E0ECC2CA85F96B75D7CD607D44\n      4B6F1F19C6B9F4A3C75EF0892CC9928954AD6AD59B960BF8CE1D9D4F3FF3F5AC\n      00AAB5FADF7FEDB1BFF9EB6FFDEEEFFEDC2F7DF067C2B08C90F43E435C8B4D23\n      C475DA3829009405FC2E810DC5E2F661180117029140422AB2A3C501D2823084\n      AAD8C14C894A3CB4A2B00AA4BF9627F927B2ED41E2BEA1B470949AE6E235B014\n      1309C4EB429886C9E095AB9E1F26B77607C413F75F0E72AFF8E5C72E902EBD70\n      704B50AF53295168399A1DBA513230A200332771FE07D7B614B6D4DAADC513E2\n      5F8B7A9E509CF35C8764970EDCDFA618E6D429DFD4D203BBC26275F5E4E3C42A\n      1AB652BDEE6A577DB4C0833A0E189593FAB0E52C26F0B604FA520CC153BC9642\n      3D8FD9419B13CCA13C927F43805B760D99E42FBC3131FC069546060C425AE142\n      408A7EAD36A1E58683BC2E00427EF29D7FBC73EB7DDB56FFB578FC1F5E7EE023\n      6F8BB65B0E5B4D5742A6E878BEE7D8DF9EBF3E35F9F68FDCA314B0DD28EA8114\n      5E0913A1976A6AB914853D01B5E49195842411B0225E65D545BBB6582BA45202\n      79686AF2CAC5D295CBCDC3870A8A9E7AE1C552E415EFBDA35343A11F265C1740\n      C76F36E80BE736261D5E33F03C63176A5EBDD250759589470551C14CF76AB41B\n      BAFD0469963DD2973E787B1FD5370CD28434EFD13235F0D573B45C057BEFA7E9\n      DDE6E947F9A37F254A296D89AD547478B5A908D425D03354A81CC096B4468178\n      A8B8794906B798FA28816D2CF01AE88EDFEC7ED36FF600CB7DE521EB877F3F03\n      9AA2EC696E606516A6577C37E22E168F1C051A226AA8458E221E8869066DAAD3\n      89603E5288EB8DF6E5766F1D5CBE327D795D94BB0A403401E92081B7F52413E2\n      E580B21A26CE2C17E7037B3170EB4C57A8DE895126F20C11084C7A73776FE486\n      AF2F2FAD4AFB417DBDE66C44811D9B7E08682290404C29617E14724922D3B044\n      7B22438B0227402032153ACA434DC1B7BF7960D75B529CCE73921415E1C4916F\n      C13B4606B0E709F8D1AB2BFD58CD2BD6FD1FD9D5790764864BFCECCA79F6D097\n      5E820BD92B097FDE6773011608462658E049551B690323AD985C18C838C4892D\n      CDA47C83F9AAD8401C58024CCA196435F49CBC198EA4D000435DCD642ED53C7A\n      A87D34AF068EC5023BA9F1866B3CFE7AB318681E74E62BF545D276A666CF16CB\n      10FC7F26C21BADA05848538A0EB686F5255DACE5C1D1FA41A933197B91B56020\n      96C27606946AB84CE44025E69DE34D0F399944C5657902154B9550450948E809\n      E8E5991A1FE4FA1E9ACE86352D593A74F74857B7C181835597AA9EC85B4449C4\n      82540ED515883539D88F4324C7CF48A0AC2B70EBD987F92B4F2C35C3A048DCAB\n      B6B312113B4A48A343EE0A5421E9881CC9E134294F12ABFE7119DDC10DB1C4D8\n      8990B5F8ADE2C67AA191C4CE16CD1B07AA1644ED3BE17FFCEFF7F3F62AF00206\n      3498566C2C9E69DF73FFE3F5E37F719E1273913833E2B1D744A2665CAFB940A0\n      E8BC19E10C0D0E22D2A92B5D08F8A071DF1FBEB7E77DFB025624769945D5883A\n      2280C8FB183AB03EF6E2DFFE6D3BCF36E7B353AF3700A633CDD569E66D30D446\n      CC71463AC43AD3C9A1FF867AF3FB5FF9C6E9ACB7323E916251C6E219A08A32B4\n      1A9B3C4842CADABA6368349FCB576BC1DCF2EC962DE357CFAC78F5C2F29A572A\n      9752D8085DBF7D9F76E7A7C66CB1999D3EF9389255A47AE07AFEB5BF597CEDF1\n      8B134707EFFDF43B782F73C5E350138115001C7BF2C5837471748B69C0E00D96\n      D51B9C2AC9A6968417393B15A0968610D72037B924FB86D22C502AA20D844103\n      51D95FAF94C9430F3D274AD8F7FDFC7D0CAF20540D02E0D4124F3E7272A39AFE\n      EA5F7CE367DEF98EDFFE4FEF6EEF525F78EEB5F7BEEF8F8A25552C2A183814A8\n      F26832A900DE107751075A474265227B40A558591FECCA1ED87BF3990B93C8C0\n      B5F595829E1B4816C627465EBA72E9B56BD33865789E9B36138EE5559A4E08C1\n      C4B6AED75F7DBCBA31FDF9CF7DF96FBEFE6A2AE1FFE847FF73FFAD8391BB2A8A\n      40CFF5083108D021D5C45A2CCE4E9F7DED74B3A476F475740EF5640A494DFC0D\n      905D5AE089E0293DE79001C40E6734307CCA4351C414235611B83B3659117998\n      40D92B944D17515901CC5A70D2474C44CCA4A3B2B38B8B0B0BFD4776413572FD\n      A68FA0EA50746E75F5D46CEEC0B03ED2C1EA0D029D80D74240B88583C04BC2FC\n      E213157B8E2776E7EBD71AF505AF1130A46AD2221197F7DE6BA4FA94A529B33C\n      1BEDB84509D4D5F32F698B97B0879D4586AFFAEC7A1494E59868DCF9652D1955\n      24D919D2F38C472460374EC159AC52DF22CBB45A83E086259374A00DA39864DB\n      12638B1B85B1B05C3C6221497762CB7512349C527A237F18E745B9DCF3367ACF\n      1F8EE68CE4B1FF7AC66D44777DEE904DAE2AEB091704095F5B7F35FCEE9FBEB4\n      77DFF86D0F74D7FD15E4259548E09F12372069EB0266C2C396547D10A5B50F05\n      C80B4A35AF042B737E2195014C80575C5AC3674F57F6EE32DA0A6DAF9E69CE5E\n      9B7ECB3D138622B0542AF2A157167B473B71B17E72D9291B648179576CB4516D\n      7822B92AF2FC8B42A5D3547A49304A687B206E6873DFA1CEB1AD5A8A6C4428CB\n      F43564848BD3ED33B3E18107B4DCBEB03C95FF87CFCC113B5BE41BABDC3AD390\n      BEE402E908E88262674B49F850B4A6ED40C71D358C21CEBB2848D753E923F6DB\n      7E774BE7A8CA59E1C9BF3CF5CCD72FA7A37C1DBA2B2A28A1F46ADD73C27A2309\n      8C40331D4D247EF9D8094B523AA8D06E16B40166B070A2B77DE778F7CB67CE4F\n      AF9770260F43331FF09B737877AF2996F17A609C5C2ACF85CE06086AA11A315C\n      40F271A48857D0C0DECECE0C56CE2C2FCEB94E4453568467ABF59A7882728A31\n      54156912E485912FE76A65BF3FF6AC9692C1A278133837A1D271E8692A79D35B\n      86C7EE520238C35082A4F76CB9E32178A8AF4BE5410E05039AD105503EE5BC59\n      24C243D045750D76CF1FF7BEFF172F9362F6BCE6CC7B6CC1C79EECA04402214A\n      62B5547913E936F4A492ADCC3EAE5847819F083C15421742114B7CA87A8E95D7\n      518F8EFB08E863A8238063C3D1A1836D8AE720A6F8AE974A90D5067EF495D574\n      DF96B5F2DCD58DF274989D6C848BD5EAA6BBDCFF9D02618B25DECA85F1B103BF\n      61342177483C2D845B2CEA587307B5FA1D3CE661EA9A8E63F9161A4F51C0B82B\n      17736DE42CA2B87F1E0A3DF19A58A3B2C9D134742FA7C17E961C0E14235CDFB9\n      4FDF7D5B4710D5742D13F13A11011A09309210409AA100AB12E6C8552FB54565\n      454C5281BDD0F9E3BF5CABAD1A0D3598891A971A0D076921530931456C117135\n      161F93B3FEE26A02197EE2D35179001DDE38B989E53363DF0E8EA82DB20E6263\n      3A1F959E260499CD0FFDD19B7A8F42EE5B0CE6B90E7C5C035A7FF5C5CAF73EF5\n      4C6D96D8842CE3E09A8DD60264112740AE8E5309A66628DE0759874E7A218AA2\n      FAADBF76EF96FF7024325C6495202B8752E224C2222F3381F33AAF3FF19A75DE\n      6EA7134F3D7A42545165CFBBC6E0BC0F4C0CC7603420307564EEFACFF68E9BEF\n      BDF2F0E5CAF9537BB776A9665B2D404C0B15685110EB8152D57168BDE8747665\n      43185C9A9AE9E8E851997AF59C78BDFCF252C9002472237327BEF353A33C5F54\n      2A794E0D9E702D584AA4FAD94CEA85BF7EF1CA6B7347DEF5A69D3FB7C76FAB2B\n      B221A6FAD022B24868391FB14D2D50FE462244AD71718EAB2CD21897B2D7F200\n      0D051047F1DCAB9CBA8A6D9FA124D4479D7EB8A6E8E2EEEBAB8BFA37FEE1956F\n      FDF3E3EF7CDF5DBFF2D13BDB3A5C22B7C0F037FFFAF1E945F4F4B3275F7FFDF4\n      C73EF6B6DFFFFD8F9C39337BF49E8F51812E48402391BE898C7B582A1162AE89\n      E49356986441A9BAE7BBDB077B867BFAA76796A4B2AD5DEF4976B675B4DB983D\n      FCC24B249B6E8AAD0158219D162BA16435EB8D60DF915D7FF49F7FEB9B7FF357\n      DF7DF855B1260E1F1AF9F6B7FFACBB43ECBEA654AB5104FCA2A1CF56E74BD727\n      CB3FF8D693C79E3DD19EA27A92E6F27A4721D9D556C8A7B30A971D03A889CF64\n      0FEEEE1FDA3B90CAA5A06B72684356895899B306944D815882474E1105F29014\n      8752BD37D6F6742569991A0D142D34CF1F3F3671F72D4A0AF86E132039DFA044\n      BAFFC8D4A25BEA3DB283EB0C785524FD2E92BEC77964AB22429E67A79F5BC1E9\n      ACE96BCD95C0E2812BEE15508067F7EF0E070FA7CA2BC96BAFD4C77628D99168\n      714A3BFD5CD3F2C13A64B3A17F5D64903016579573CF2D7B5E1C71E487B1F324\n      8F770A8B0515C0A687676BEC586265B63956E2FA5E6B8EE28D04B929351C8788\n      28625216180003E0ADF9EC98E1F70094E59D6EA27ED7EFE5F73E908FA6CDEF7D\n      F1B9036FD93178674E00D6660DA7B50DB6049FFF9BD2CCC9EBEFFA85F1EC3069\n      583A0E4395AD13A2F06C6750405C0D04A094F38ED2F4D5B28B6BBCA114A75147\n      B68DC05210D86E33F7CAB1F56DA36870B87D76099F397765F7CEDE8E36A9210B\n      5C1AD6AB94C3C5A2766CCA9A63DE1208E70275B1DE5873AC8888B79212406D49\n      6D204187B136C40DCDAD7576B17D073B463B9D10A590B982F4A0B43674F67CFD\n      E6FB8C8E838EDBECFECEE7E6AB53A26E7117DCF205A6114D9325A01C9E9182FC\n      1E043E218D208C1CB713A101918A143C1EF6ADA54FBEE7934776DFB525F0AE8B\n      9DF2F857265F7F380ABDD0D3AB759299B7D455AFB9920812819EB491417883F8\n      4506284AF4503C0CED1115A34ABD3D65ECDCD1474870FAD2E4AA85B1D26984A8\n      0F5B776CCB9920AA78FA89B9F24C105409A87961CD72DA54636BCA4CD2B05D83\n      5BD3A92C218B8DDA956AC566223CA7E61B4ED1F17DCC1DE450A2C6D50EF7A4F6\n      AE34B696CC119908251D9C729654E818B234851C79F3E0C451E2A379461238B5\n      67EB9DDF8747FA7B35EEB4A17048313A10CCB579F7FEF2CEF6DB88175615D67D\n      E5A9FA4FBEF63AAEA5CF29F6BC172D86246484CAF385402461399B104857E630\n      161513A1DC01D28042F57D0541878086A805814243AB430DC712C9F688665D6B\n      7B8771CB2D7A47C683B60810BAEBF80A5596EAECD8B54AFBF08EF317CE2D349C\n      19983C5F0E172BD5960FDFBF97085BF0AF65C622328E3C2B9134B7F8F0536C76\n      91555AF2F39BD6F37145485BF94F5104EA13B05D3AA7C7DEEF5C8E242329FF10\n      AB7588F8E54B9B1E8D40450D9D9C66772BA487A7DA7C9437AA070E99435B3437\n      6822D21E44553DC1E4008B487EE2B648839D989E20D0956C76890FA8D04462FA\n      58F4C23FD728EE58E0B5CBBE332729BDA2C2936EEC02C8887C80B81EA7F240B2\n      7BB854748B62E2A8642DB0168095E77DF168238EC17743DCEF614D1D09ED416C\n      DA8DC67DFF61E2E8AFE59861033828D037312A16E94EB9EA239F7FFECCC35512\n      A62AD89E656CC65356048207AE0E4552270945BD19853D69750892B059DBFEBE\n      7DFB3F71BF48ADDC2AA36883534B1450584EA4BA2106E1057AE91B17C73B271E\n      7FFC39E60AB89B3F5F73269D40C1C138F587A982AD7CE72FAEBCE9BD3F639DAF\n      5C7EFC5FC73362D99A8E0A3C225661A47051CA8611229866E626ABAA1EF48D65\n      5736AC5A3518EDED3F7F729A05BD8B73156E07918B945174C7A77BF5BEBA52CD\n      07AAD499976D0BACA87A06DBE957BF73F6E16FBD7AD35BC7EFFF8DA3A62E6EA5\n      168837C152E3389693E4B1F24BEC8EBBA9A027355862EFA43A006A142AD25909\n      8BADE202E48A7418B3ABA51E2CE42A064A10E89034B06A4BFB2438F0FA29E7D7\n      7EE54B274FAF6C9DD03FF9C95F79FB8377983ADD5859FDC3CF3E72F9F2D26BA7\n      CEF030FC8FBFF1969BF61EFDE0473EC9B09934455071401021532FB90231CB16\n      A1F808A61C73E61EA2911F1C1CE9EFCD772EAF56A4677CBDD49FEB1ED8B7F7E1\n      E3CFCF6D54C4BB867ED8661A0A0875535B6ED444AECBB465D428AAAE34F24975\n      B9113EF8F65DFFF8F5CFA69341E8F97EA4D5CAEED599B9E3C75E79E6B1178AF3\n      4DEEA43A33DD1D5A5D21E2E9D838F0A858CE52F355B123D7539C9BEFDA7DF8C1\n      43E3378F49B9D678C00388DDC86A2CAC31017A444920D7673CD02ACDA1E2237A\n      B9DDB9488458949C368E9AF0EC8F1E1BBA657BA22785802BE2B19C4EA42A9E46\n      579FF9D74C773E7B60A409AA525EA219C69E0FB614A3B693979F2DAE5F6226D7\n      031B314A1AA4AA8A8DD644B9616FCB9B338E0BA75E2C6732DAC8FE5CB51A1C7F\n      74A3524956A0BB10B973AEBB211EB3947B259E344890AC2651DE07F1C8231189\n      A6E5CD0461CBA131567A6CD9146EBAF5B652E31B83F66F64440997E373511131\n      241B288A14130D91F6111D74E88D4E96D77C65E21E78E71FE4D5C1CCC56FAE9F\n      F9FEF4CFFEEE83D6D01CAAE423724D3CEDC6A9C2F73EFFFCCE6DE681FB47AA91\n      4B18367C17062C4868618FAE24318681ACB4A50AAB659517B1935CB90832462E\n      91ACB2B0E935F32F3EBFBA65800E8E266BAEFECAABF36281EDBFB997057512A9\n      D0F622DB0E59EED8E5DA998D6A8928ABD0BC542ECD3464212EEE43C2D04C5DC9\n      2232A4EAC322B108181C962746D247F7A5A0A172BA405460B963C75F5DDCF3A6\n      64FFA1204A0C1DFF5AE5CC8FD79B56B816D6261549710748E522B78B125BAC29\n      2427551D44C2284C86D1804A73184D38692B3B73F483DB8FBCFF005417312937\n      57520F7DEEEAF249A6845E352AAF92E44CDDB866849A48396168506073560C60\n      289053104EE8B89FB9DD0A4A29725AFAF09EFE200C8F9D9A64A48DD05406B9A3\n      497F6B678A71F2FA4273AAC19AAA5A776B65CB6AD333DBD2492DB23B12784B3A\n      9141A829A040B3B154B67D9AAC217DCDF2ABAE55074D14EB0047B2A70D3C0E23\n      010DE3F36FA982117191E74D856E21AEAAE03BEE1F1CBF83FA640E286998DCB3\n      4D24C2A3C3834A586D07E1A89212F844CF56DFF55BB7A6B6BA8CB8281A3CFBD0\n      E233DF9D247EF20CB6E6BC688349E6882811A47E1B8E6DBD2439269207B45260\n      18331249D75797231CDA14D49922105A32AC8E26C21135D309B34A7363DF4EED\n      E8E12CF29A6E892142032F5269E1D4B5E5CB356B7CF76DCF3C715C8088AB089E\n      5F0F36AC9043EFFF3D42DF628DB474A062A96C20FDD8E203D0966E1AA19BAAF3\n      E28BC45F28EE90D3588258D47D040295521C7706E589664B4132AE09C5D67165\n      AB4EBC9E22F28FCEBD513D1CA534CF4C03F1A17E7E60BF89D522A228E005443D\n      ACBA7246510EFA894C18CA69432C8A360F2B9E1480C229B79178FABBD3F56B79\n      8725A683EA34C0AB91880B8EA801039F8B0045750530550447CE3D2E5B833066\n      EDB158B3A4E5E3D80AE7B1D35028AE55B3F45551667461632B0A46A0618666DF\n      FEE867FF7C22481679348802263EA1A3F71A0AAF9D077FF99B8FC3653D44C112\n      892EF864C6136046446AC91AD508DA4BE1404E9BA0BA80B27D778FDEF6C7EF8E\n      B21174EB285C8B6059DE068139A3BAA5D7F49991135F39D19FCECFCDCC2E4D39\n      3C6ABB1EF24B9E805FE1B829DE15E37A3E75EFEA831F7B8757B6AE3D7AA627D4\n      D399A0492D0F1B1A54156663CA1C110E388D9CF4EAF26CDF7892E899C9CB0B85\n      549E3BCAFC9C532979DE4614347563AB7AC7A7F3E6801B95D261D21748460522\n      5EAB9EEE331D1AD1E0EB8F5E3FFDF2C9EE31EDE63B76B78F0D47386C918B65B7\n      3776D393A848B240613C90127BEC49117DF12B8CB54711C09423D56EBA4DC716\n      E1922225265568A69196BD445562122F121588A9A8FDDF7BE8CCEF7DE22FAFCF\n      D7337AE23DEFBAEDD77FE3DEBDB70EFEE9E79FF9EE777F5C2DD737564B14839E\n      AE81C96BABE2054C15F617D2AB8B4B5837EA20726B6EC862935FECCA0E9DCFD3\n      181E191EC9AA899A88E88D46542F1DB8F9D66A42FDF6334F3643EE7A4CC54A9B\n      46B5C83793C67AB3B96A8BEC8992BAD9A6EBAB6B258B834F7CE2677FE777DEDF\n      AC2F5DBB3AF7C4E3A72E5DDA98BA3AB7BA52CE24947C4233B1010390417E2681\n      721A20BE9754D2A1088F18D9A871E481036FFFF0DBB5BE3C97DA4FB22C9633D1\n      B232F658509345217091D87732C5C40647125ECA8E0193A452C937A101157973\n      F9D869B32393DADAEE0B942D5EA966352932412E7A6D79F5F8D9B6FD6368A2E0\n      D6EB4911AA1DBBA50F1E01B27E912DFED0A3CC8C18F644D6A535455154DB50B2\n      FEF87D86910917CF5657E7AD7D77DFE4B2B5B32FD596AFE52A616303F98BBEB7\n      E244354E3C4E4210A765910670E88B84C3C4F3D7624D55BE290410F742A4D576\n      2C90133BB2C5127AF1D18094968EADD85B94999649450B31B3F80702D848B26C\n      9F961C4BF8FD90B785092557BFEF33831D77415E6C7FF60BD7DA3AB27B3F9011\n      91CF611584FC84DDFDFAD7662E3C33F5F6F7DFA2F6D65CCF4B8419CC3C1BD640\n      5B5ECBE922A7C4632746E0D4BDE632F5330BE719F4958ECE8060C7B333AF9FB0\n      BAD261FFA05822F4ECB97A69C33DFAA60995948107149FBAD58A4A3353ABE089\n      B3330D355D42898B767DD2766D0E445857B1948314C1B74BD1C774D047822C63\n      0688EE3D58E89E30115E5435BD6275BF72767EEB416DF830E26D5D179E824F7F\n      F5B2DF4496E29F17DB4AAE5045E0555136C130F45864135C47E2918709425261\n      90D7D5DD0EF70DB6E3FEC25B3FBE5BCB36A2C041882E9C0FBEFDE9D37431C359\n      7915FAF36EC7852810774FA53EC54A18D150AADFC9A7958DF00081DDD433801F\n      066434CF6FDBB37B63BD76F2FC558F9A22661750706454C03C7069B9FEFAA2EF\n      9B5937A895DC465ECD8C1B22F6066935DAD196357D2FD4500DA24B73CB9550B1\n      9464D5831B56A3495D112223269D914379D423699381C0F110C59286F2A9A735\n      632BF5C51DBBFBC1B1BEFD0289CD12230F127B76DEFB30BC636848E3956E188E\n      82645601E901EF1D1FDDAF0F34982868FC8133DF5E79FE075779A09CA5EEA2CB\n      36B8C180A2C8A9BB402043A91523CFECC5360AA46C8C2856488042C47DB9401D\n      0A5CA0E9807481C6B06A75733DCB33EDA9E0C891D44087032DC83DCD0DEB44BA\n      C3F5FCE4D58B5E5B7274E2C08FFEE5C40687D3AA7D66A55173089324B5FF5B4E\n      26AE8EE2138FF83B5911C68787B19FA01462135B8B121A93C4E4F78AAAB48A48\n      12C55D4519226539161B5C4BBD2C187332D1E6D035904D3FA90B40059648C360\n      9B02262035C5156AE181DB3A47FAC44D2E8BCCE7F1BC2CFB145716DEAD4E2366\n      A2DE946F401CAA46AEC34CB367FAF5E895A7E682AAD8CF608687D7A15A16DB36\n      B21439F222FB7E5C54F45CC031B127E53BC7ED0B099AFC886D2A63C29F2AEA88\n      8C200A174B5B1088248F12E324D886928695C80D373EF4C5513C6C797EBB29C2\n      2D5F65A97EAEB884F73CF58593C7FFFEB4C6CD22469310CE0491D4780FA43E80\n      C0217B30EDCD91ADC8301A5EDFD1C1DBFEE43D4107004E83842B0C9564C69004\n      A86A452B6637764E7E63128A6F9976EAA9598ABA6782E6155F4A30F611D64FA1\n      E6A5E9B6DA3B3E7A1876E2CBDF3F975812B881DAA4E8A2B4CA931AB411956604\n      4CEA95B557CBB5627D7E64DB70B9545F9FABEFDC7AF08563279D66189552A0D9\n      C67AAC3B3F5D486D817E2519190D807D113A09C8709D3549454B7550BBAF7EAD\n      BE327B89168CFE9DDB80E64B7B3A74E32C348E8202D320E9AC1B9BF58848EF07\n      445463520B2320C902E0E9575EBCF6CD7F7A6261B1EA072C165DC09A6666336D\n      89943C6611753D259A2FF00849A85AC7B7BFFDF495CB4BB23B05EDE1A1F4877F\n      E19E5DB73CF8A9CF7C6A7979452CD246D50B036E716E26526D996467C2C0E259\n      2FAE27DA076717667C293DC154552458E6F92C158207B76DD3316D723C3F33DD\n      D9963A7CCF9B7FF4F2CBC7CE5D644415F85245C888FC0CE77D5D1DC5A65593B2\n      A686408D56B566B90D48D081FDDBDBDAF4E5E5858585F2FA86137260EAAAA661\n      910871E4664C85870296D2A4CA13284C2BAA2C4720AAB3FABDEFB9FDDD1F7A4B\n      B63FE5B9620727093419DF88A1B434A4E64C5C4153FC87902DCB3F5914C69E0D\n      A2E2620DA060795C82891301D5C1EEA5E5A8B4913E34D2D05DAD6E532BB40448\n      4361A29CB09E9AAC54CB5D077744290CA883ED0676A5187D1D5B6A35B7FA1DA7\n      BC2CD20DF582C0260DA4609365DDD0EEBF050DDF44AC75FBD5E7964677EEEA19\n      E733E76BE75F123F1AAE077E11B079CF5BF1798329416C982CBD78A12FB0B26C\n      0647466C9C18853105465A82E396107F4B1920760D91221A50BCB11CA9E2B1BC\n      54AC1520B53EFE0D8954BC00E60D8BEBED347B73421906564E9E7E393BEECFBE\n      E97726601216CF93E7FEF1C5077FE69EC4F6B980253DE6A9A143D6067FF0A7A7\n      75ECDEFDCE8E085ACC35A81C942C62DA46F2096AC473593E719BD5C82B692037\n      773EB02B4C445F44AAA19BB9783A4A127F6454F6672F5D09A7AF340E1F1A6ECB\n      3603D75359326A34C4B2DD68EAC7A6CA73355E42C664E85EF1C275D7C728A492\n      F685294A2710EA35DC2125E808D56CA44F74F203F7E44D7D8570D385C3AF5EBC\n      3AB0958DDC6580BEAE6B2F298F7DF122ABE10AA85D0466B5D60402C1E909F131\n      B9277674E06254C758A43B812B0D1E6574F5162F006AA27D0F7EFF2777A6FA6D\n      DF134F56BC21B9F6D4CA135F3CE32D69A1AEAF07F6B530B9EA175D53D41146D0\n      14EBC657447823F28824CD41B716B5897DC5718135C60AB9AD8303F3AB0B9756\n      8A21C919011B4FB36D03C9E9A5B5AB65A5ECEB81C0E3CC4E617D9818024B2475\n      3E914BA598EF81C0A6A86847332567C5853E32CBB6DDD4FC20E24E10F9322949\n      EEB77CCA2052E524A91C8712415A14E03B743966BEE7506EFC08F4D565AEA440\n      72F7EEFB7E048F0C0C68B03C00A3AD3097D240DB96E82DBF7E13ED2A33ECC366\n      DF2B5F9B3FF1C402C7CAEBCC5AF26009E800A844604BC98E91E299526A5B2C2D\n      39882BAB430E5CC890A81823CC5DE9BC8B33808EA9611FB0F3222163E5A6BDDD\n      3B6F5275560255B1690C8F6F28129577FEE8D89981C33BCC44CF0FBF756E1D91\n      AB6AE9EC7AAD618B04176C76C0FF6D1AE49B8361ADB13F8C908AE4F055AB5844\n      0468AA26AABDD824114A6AA8A2C40912686CF3982CD61A8031D005342E2A63B5\n      7216BFA600D3586A29CB535656A0601BC66392E9EB667AE8FE43BDA656465CA0\n      21E2416935870412C1B135B09CBDE6884A6B49485D9188596812D875EC27A5B9\n      CBF590E94B8E7F2DE44B40AD4BB2A80FC2A63CF894665A04322D96F8F7631345\n      D9DF92E3A59275485A3A60B119455C17CA6EA2E2A96B012049A00FA068BB92CC\n      BB3A32577FEED363036F4A5B1E348909598325330E7735B5E05E817FFDDBFF1C\n      CC6B2E4ACD2177360A566DEA07062621519AE38CF665F14E6CE61AA0F360C7E1\n      2FBCD7EFA1D07748B8C4D89A9C92933C9DB20876C9CAC0F2534B8BAF5E1CC98C\n      BEF8C3498D7688F43EED3B75977620DAAB4193D3406FBEED13FBB28793D79E9C\n      2A3DB7BC6B208DD3AE8353245415607312888C238DC2C50706C6D2CA9C9187BD\n      BDDD7357CA2AC9ADD78A0BF3ABB8DAEB6FA4C342F5D07F4A771C4C065692880F\n      AB35238208CF481550518C889C8832303039172B44176818D18AD4DE91260B60\n      D384413C5B69160F3C112C309136F45205DE43584734F7FCB3975E7C76F6D11F\n      5FB830B91AC9297B7972CAA4228BAA1293A15529C9122B842AC870A388A89A62\n      085869FBAEA52279DA1B06EC963B6E9A5B989E5F5C4BAA9AD70CC45AB459200A\n      CBF67486B8EEF6B1E1EBF3AB21C92F541645D8001271FB32A1709473D97B76EF\n      520999AE56AF5F9F79EB5BEEC585C2DF7FEF87B5BA1DC298F8C5830CE023F95C\n      219D6E389E258015A6A566BD5CAF690A4092A10714350909B57D3B91D6D78A95\n      AE8E4C24EA1C47D456209B5403CFD3B4AC8A5921A9875218127BC0DE77E7AE8F\n      FDC187735D4A002CCC351A25042A86B42ADB0272114BBF77062C1E89A2B0298B\n      42EECB517486A4300D73A4D840EC58DF145BCEC5C6B2577DF964F6F62D4E17C1\n      96A5DBDC91A5585D11396005578E5D025E943D7A7319AEEAC8D36A72B3955123\n      07F2CD6782A9933502939E13DACC610A3048D675FD54AFBDF79E04A2DE99974A\n      7653BDF5BEFE7AD13FF35C63A3E236195E8BA285C0BDEE0765A67A488F6D4444\n      96F690345E240CE9201617DE2C0741DC5FB871F2B9793A2AADA9D80DB37AD472\n      5E949EA941E0077E8B41132B600085F836482690B25DE543C4EB31CC14A766D6\n      79CF67EE300F3ABED7987C7425BAD6BBEBE7D7696E8B5D137871230147A77F04\n      7EF2F547DEFDBE5DF94E971112701B4BAE0B094D5D4B60C510153E739A75C02C\n      0D6656A7D9DA5C7DCBD602528A9197B8764985BE35322672BBBBBE669E3E5DDA\n      B5A3B3ABD3165586025291E5B2669DE1DC99F9E0D5ABC53234E610BF1AF0E94A\n      2D942A9B3C61AA9466C4A5B429CE98090640AA0B65B3BCB1F70E323610A89116\n      A84367A6AE750C3487EF4EC3A1AED50BD9473E7726DC001B7EE9324B349D806B\n      A64254148654A204EE4251CCF24A103251D404BEA9D1BB20157BC0E80FDEF7A9\n      9BDBF7B8BE5432E8029469DCBDF6BDD91F7C652EB4F390AE9460DB4CD35A5505\n      C00191E59862A162EC4150F7E548693BD13A1594A45147149ABE3BDE911A1DED\n      BEBAB631BDD8D071C60C2ABBC732018F2ECF376B2C55B19ABEC2D3541D465A5A\n      43BACAC6326646149491400738D21233457BB6E2853069076C85379AAEDFF03D\n      17CA26BE64AC480562A688471A86520B0AA15C32BD4DAA3747E37BF49D6F36B9\n      B91288A095D8B9FB2D8FC0DB074714B03A04D80ED29EA0616E27BBE7C3DBD5CE\n      AA0817DCEA7DF1ABD74E3DBB1250708E05CB1E2F030372459E46004FD49C2256\n      C4FE72026EC6804ADA47FBADF9E40843579AA484ED006F51956112A65853A7CE\n      7DF76FEBE84058A0DAA61232C5F3570C25595E2FFCF8D5D76F7DCF6D0BF3F563\n      4F963670E22259BD58AC59762CA60DE2B34278A325C8E14F2543E4E483C841D2\n      6D43B2C582086351B18ADC4759FC380951E428BA649462F14D72B38D14133CE1\n      A63F999498447294B0851DE52D54B4D00B01F34D1CF62A789C183D00A53477C7\n      FEF6429FF8E93A8949394CD1248F007B7CD3F957EA70C9E02BAE9E8A2CE6A96A\n      CFF21C38FEA3926DC1260FE7058489C006C222FF3081E17C81BAC427669E7495\n      50E08D535F91A265451AC90B909B3306B6517CC213D30150ECF424D0BA40C54A\n      3BE4E39AD62F89F08B777D60E8D02F4E84B1C482EC9450105011F431F113CFFE\n      D58967FF6E5687851277E6993D6B2BD520019408D2C678A4F4E5C12E9CEA6D2A\n      E91DC9A35F7A9F3F94849147FC391EAEF2D8AF0E09304A70C24B362E34CEFCCB\n      C90963C795E3F3F586B816FFBAE7562D9002891E534D2A0EB0945B7F7560E8E7\n      F3952BAB97FFE9DCB8994D77681E55448212157004C240C45C8E58A8EA6AB6D9\n      ACCFAF4C0D8F0E7157BD74F9DAE8CE89A9C96558EA5AB9E407E9F5FDBF911DBE\n      AB10843A412AD32DCF740130B5208BE442F745ACE252F6C5003C6BFBC4D0EB60\n      931AD33A25A7BE1F4AF6118BA7C808959A798A54C3AD96E123DF3FF5279F7D78\n      BD28C70A0D2A3EB7A80499E5342CD9CD52314A84D0F25DC750142E10B1089744\n      5279A146ECA627DE21A92B4414C93EB3C288C430219F4E193435BFBA48750176\n      B989C9685B7BC6505C9F5D9D2B195DA9ABF34B8818486A108ABB49DBC3E8FD37\n      EF8DB87FE2FA759178DFFFDEF7FEF0D553CFBCFC9A0225E35C64A42422836DE9\n      DE7CD673AC90E3E56AA3E64735D7F6409820A84B25635B77D5BC60A9542C3536\n      A4AC395511539CBAF486EBEDCE59CD5533A1462EE9CAE75502EC6695287EB6D3\n      F8932F7D72604B3B518320B022D787A2B0A206577D18D756502E5E3968CF4451\n      283B850E888B4228F38DC49F51E460917922DF3715E8E144892D3EF94266678F\n      BEA38B393695D91E2A8115508A3C4CCE6EACBF744DEBEE4AEE1FB48312B55D69\n      E0A8301A28DE4C70E9271B4A901199D365C812A043A05511BDD4E6C461921D84\n      A52570EE95C5F1BD031D3DD96B674B675F5D12F7B8E4B365E85FF39D554E1B5C\n      8B6D872349E78964F51FA11B5623B16C6ADCE210F120E437E6E563997DCC62A7\n      72794C8A361D49D98D2FD862984BD229F7B8A3C282128505BDDE67E251DC3620\n      4083B37AF0835B0EFC668F0BCE464BE9EFFFD9FC03BFDC9D1D190AA3B2139595\n      280596BABEFBC5A77A92FAE1BBFAB856B25D11C6552A561255904674034BDAAD\n      EF022934A0D6D6F1F5CBC52D5B7AB0B221B2CFC274DAB7ACB111115C9BB6953B\n      F5EA725F4F7A6C084722897003D83EABD7159A9D29D3A7CECCAF31A5A2E9D723\n      74493C7F29B0208720A5257DE82748306428A3D4EC57F3393FE818A9DE732897\n      C2A2D2CF4D2D6DB4755AFD4745222C5416BA1EFBB353CD59AFECD957A3643508\n      3C2A597F28F0339AE4503821AB315E0DA50A04F31D4AF0DD54C9A3A45170EEFB\n      C4D6C1BBF5D85F3619A0C09453375DAFFEDDD4D3DFBE940AB5861B6E20733A00\n      B3760D293C451291CD3D18D9D01340D300661B8239D5ED61B04DA10966F715CC\n      9EDECEB397668248942F24ADF1FEBECED7CF5EF1D554354255667768E6A89248\n      88388FDDE18CD101038C0317463ED1361C70AD68351C91F4B415EE6E34AD0DCB\n      F5A48BA746246E8E54CE4C8A551197E3591A5DD327B82212D5C07678CBDBF381\n      B9EA89BA2E73D39EB73D0A8F0C8E52B63482A25DA44B277E611FBAEB835BD4F6\n      2A5601AFF53DF5E52B178E973D859D63E1AA48845C26421AF8F28689808C2994\n      71399EA417C13B9007A5504EE48A70AD0472CEDEEB4670BB9E6BF7C3ACBA3132\n      E11F3E322A7B349647432D889065AFA594C2CA62E2E98BE78EFEE291E32FBD76\n      F58C52C46D67F8DAC572D9119B11B5CAA0B80C7CE3FF38114A2F4AB839282F25\n      7363BA174502D24BEE10937E4690482F3CD49AA8250232B548D22DE165C064F6\n      8CE70E658F10C7BC6C29148F422C2B5C85791D381AD4D55E64A618EB2DF083B7\n      B501BD1C49151B4DBAADD390A3104A87D358B794B45CA010A6008B901B887FD1\n      7BE2C5D5D953A22C5557A2EAAC03E603D0A43C1201DA53653397388C785E003D\n      5FD2F2A41C4E8BC9165F61140BB4C6A68890DFF812EF1E08101F511A370D0D0E\n      870D3A44BD24AF8DECCABDED6307CDC16A24D93719A6BA88E442E0D0A4B6FE9A\n      F7B7BFFF7C386F8ABDBFC2BCAB3E5994B05A7C787F8CE3EE2CDB8B52838E698E\n      D0BBFED7CF796352DC840673205C8C051222C8D79A2C91C00CAC83935FBBD867\n      0FDAF3D5CB57AF5B7A66C9F336EAB6C2CD0E2391312DA3982BDC0F0EFD9761EE\n      D6CEFFEF73C93532383A60010702DF10172DED3D110C49A5EC8B122B9B37AF5E\n      B96E18A9A1A1EEC9AB974832D7A827A3D58478F67565E5D0AF0EF4DFDF1906A2\n      9E4B00D50B55972395C00C94C6A1186866144B8302A061A6CBA1929F8E4960D0\n      F25492521370D387373E0A7BE965FF7F7EF96BCF3DB918C8329E2693A9B6F684\n      CFEB965BAB37991C888B44A86A7592A4BD3DC572225D1E359098521A49834F10\n      F9A60A4C1D004FDC5EDB91DC02D0DFDB572CD58BCD6A22A189BF19CEE74D0492\n      E9F485E9D98E91EEAB0BEBE58AADC90313811A7101F077EDDEEE03F7C5AB5307\n      F6EFDBBF6BCF97BFF3D0EC5A154205336E4238946BEB2EA43DBF2E6E7DC367B3\n      2B452B9416130249A4003A3C3432B06DEBC5B999335397B48C596D362936EC9A\n      8F813AD43B603537342D64CCA1504F1A66B3562FE413AAE67FECE31F3A74F7A1\n      DAC6DADCDC4CA9BC313F7F399160FBF6EFDC7EE470B4396920179ABC6CE60329\n      152D12A12D7321F063397B9585361600404421536701569B7CF1C4698CBCCE83\n      DBA06CA7068182D42673A37280BD8463B0D3F5A917A63A47C672DBDB43A3E604\n      95244A8882D366D6FCA3AE3B1B415FA0BC4C290C1DECA78846B99B9B08060F0A\n      0C8E2E9DD8A8D97CFF9D5B9AB5D2C92756DC62C60E69898AA56BCD476823420E\n      8BED4058DCA491B57CD012928B1DAC5978C3C434BC61387AC3AD3736F1453FDD\n      53F18FB07F732E2ABF3CCC922C45604835ABC73446037D285495A8991947EFFE\n      C39B12BB3600538FFDCB52B4846E7FF70EDE5E6D7836B7FDB43678EE9BD75EFE\n      C9D45BEEDF91EF92FEEF28D415A5216A5E91B1A906A44A83EC4E4B1415D9DAD4\n      85F581BE0E2D598A42B4782DD3A8D5B68F2580404B41F6C42BB3299DDEB4B7D3\n      87CD0812E4315CB740A49582D4331716A71BC0A6C6220797CAE565D7914409CE\n      B022A30F45A443A02895F6A94A0FD3D554FDC13BF2FD6DAE83F4D995467B3BEB\n      3A9C86C3ED56B5E3F9FF7172F5B4D508C8454752579BAAEAC8B0295229D463FD\n      208B49330B11D958E889307A8B82FA83ACA9570EFE7AF7AE5F186304789E8F04\n      B21161B71E30967EF2ABAFCC3C1691282C8770D60DE759B8C102CE056C4C8681\n      27E75B909CB516312885F80062794D238ED3AEC0F18E4C6767EAB58B97EB2125\n      30D9154B6CAF3B4D01F12AA1DFA5E85BB44C82221635C7B2469F0AE56005E58C\n      280E36961BD1E2A2D8266A59C31B5663C5F12C11CD154515283814A57098A262\n      6149DE86B8ADBA6A8C319D33B730E8DEF28E3C4B6D044803E93D37FDCC4FE01D\n      C3130A5A1E03E1565650B0DF7FBB7EE787264072152B1056071EFFCAE4E51355\n      1BFB97205FF24095E990ABAA80F5C817CB2F9227EE28D62894805BA217E9E16E\n      73E98B21A7A74DE2F46B781C15B216EBCCADDFF360B2B30B780D0359E2AFA12D\n      8A6BE82540C7F42438B5347DD72F1F7CFCF16767CF191BB0E334AF5E2C957C5F\n      5CAED7B25A8D0B38148FBFB25683504A83A24D61085996C667A4A234545B02C4\n      71CD2805A663F8272DFE083299B4858A0F57238262A3B5587049BC8A42286FD1\n      CF1071054E84A2F80D066934A26A192E4D2BF66DCB6C19F3235A74298D221109\n      54861D188F58C9B01B734E25273F5EE710B9E20F03BBFD99C7E6DCC5F60085F3\n      51E99A0D5718F64D91A219F2F340840DDCE0C4168592CF684C5D962950EE5249\n      E6967D7B9F85B15E0A7C63102A44BE478061A51569C9E48A6CDC9F40C36AA547\n      E5BA4EDEF1F15B076EB3A4AE5DD8C6759B4439462DA6DA38187BE1AB2B27BF79\n      41098222E49390CE44BC16F922F18F41DE990E77C3E4A89D5207F87D7FF98BDE\n      448E47BE1A5C87E1B26C363351ED2FFBF2306329112427BF53D6AEEA9A659FBB\n      74B5AE76ACB370BD528C1CA56064B2E94647697463E4CAD12F0CF5F4D2CAC36B\n      8B4F1647C6B6B2840D795DA7C095270694866465C5B5DD8D6DDBBB375648A5E8\n      0F4DE890D65E39B792346EB2E6195BB3D6DDB91DEFEBDEF69EE110DA5C31A59C\n      9684336A64A8AE1250246AF5360E75F908B84DA4D07C62D35A5D9AE8C216BC91\n      2A6AB1A29E406CE5B5E5471F7DF98B7FB67EFECA9C0E70269DD054A46902F184\n      9613881DCD4465148A20E48865105001E7108C68AC542DD6790865D38DC5A2D5\n      524949A42B9DF2A496D64CC46950DCA888BA52D3324B1B4588614621E9281AEA\n      6CA71A2D362A1EF448B270F6F2355D8ABD525FFC033FF8D983BB974A4B972A1B\n      1FF9C02FAD5F5FFCDF3F7AB24124DB4A8D483B56760CF48A2454F52A1661B3EB\n      755188524A74853AF6FFE1EA3DA3243BAE33C18878F1FC4B579959DE7555B5F7\n      DD68784B10044582A0445214ADC8114569B5D248943B3A33DA5D8923696734A3\n      196966CE4A3F2869E4471297144990201C0D3C1A40A31B68DF5DDE57A577CF85\n      DB1BD9E0FC581C9CD364A1AB2ADF8BB8F77E5FC4BDDF17CF1432EFDF7F2CC4F8\n      C5B7DFA9739E521C0BAD06A2989A182E798E53AFD582C04BD3C8CBD9512776A8\n      E55A6AEF9EF23D771EAF6EEDAC2EECDEBCB1962FE51EFFD87DF7BE67CF815363\n      DCCCDD72998000E95F95C9FE76634A4452FB34F5FB07B55221706500D321823D\n      699931430E763A2B5BEB6FBD71E0FE3BB0039B1EFE36CF741C99AEA766851337\n      680D779FAEB4CFAE7BC7069D879D9EDC29B57200CC9AF91DFCC6D0FCB38B3821\n      1E99DC8C19D07D58633751C6506FF6612F9741CD0574F65CE3D823E3B9626FE3\n      AC77FDE56ECAAC068DD74D763349D713D4E2C2B0B5187A92D810CD16EADCF21D\n      B975342A6F09EAF5072DB419DC8FDC66600D39E77D256E9D077EF4C5FE04957C\n      B79FB42FA390B50DC8F28A333949B3B34A4C5A6A3C9BEDB6D6EEFBD4D8997F3D\n      1D9B0DD4B1BEFB1BE1D1C7D5ECFBFD76C86D898D4E98AE8DFFE31FBD313268BD\n      F7E121138A6E6A736B1BD11C8004F8A4C09709817AE5F28453E95F797B63A834\n      902B75E177AEDCC8D62BD523FBF39682B4563EF7C6128F7BA74F4E4A2762D8B0\n      04BCEB246AF3D81D7A61B1F6D66637C6CEAE4037A3CE52378AA0089AB07C007C\n      4DCCFD0CA7D32E1FB7D9A4CC439EBDEB00BBE7242259FFDA52AB9CA7E3F796F1\n      A111D62BBFF85F5F5D78B116A3F2D54442AAAD51A3A10574538F00BCD6E02156\n      4628756E958C399679DCC44744DE659BA7BE387EF257EF498DBA9EB3804A0994\n      151291C17B3706BFF11B37C2ED2AD4FDB5A8BB22AD65A8DCA23FB79D6A2B6565\n      26D84C2CC0B369308DBA45CFB6953D8469396D9C3E5268E1E8EC62A7D32B0FF9\n      058F3677A2ED3585EA4C8C60FBA03750F05CC6DA33596B5F6062D642142A8C19\n      123732B21B6BED6AA3577148488C8A2EC33255DAFACD11C2112C4B4D0B102481\n      30118EEDEC93816188DC58EBCCE305ABDC8EB12D8223673EFA14FEC0F40165EE\n      ECC1E428CF186477EA3DD9F77CF60E946912BF87EAA5EFFF97D5F9B3C996519B\n      47EEB66075ADE6406DA6DD6E63AD547FCBA85BF1BE4B3841D4142C45B8C10533\n      6840F8984A0FB9DE08175912EE3FE4BCE7037BC3DE3AE52689430E083FF2B384\n      216E3D7BBEBEEBFB1FF9E907FEF12FFFE1EA257B9B14AFA695EBB52E07F4ADD2\n      FFA592F5AE5423BA65AFAADD510DEDB8D41FFF2334A72F8C55E4E8117EC74496\n      9550A05C6A4058847BA18FCCA0979566CD61C4D4255B0B30EB3641A49886893A\n      DFD9BABD89A4C4E8924626F1C75274C0C7A3B683052E0CA19367DCC102D37D9D\n      C004FB5DFA0488BBB2B40FB5A6ED0985E2A7156E5C20949C24815DD8BE822F3C\n      D76DA6A465246B696F8DCB26B5C2BE6E95FE2E41848A80CA5850F63867022548\n      635BD4F710167DB9C73EBC45FD3F75E5D7069AC012B554880589891B4080DBFB\n      72728EE33DB848CDEEBD9F2E9FF9581EB6001239E175754D20196EEB8BE6CAC5\n      CE37BF7CAEF78E494C342FABD799BB85FD6ADC9D31F18CCDCFE0605AB9725AFD\n      F857BE984E67A0325BB2C1E522924D43DB3633F8813D7BDD88EDD613ACFB56D3\n      1FA42F3D7F21E8CD84227735DCAC87EDB21D94F3E440A7BCE56CEEFDC2E8898F\n      EE479BE19B5F3937828BE569B74BEA16415EFF8442114F84C5CDEDDDFC84E365\n      9DC51BCB39C71D9B9A585ADB64A915569CFABADAEAECECBB3F7FE6F3FBD26204\n      A546E9E30378660F9BBE56F0B61C5B0E4A6C03F380B822CC93C8134A6B88E896\n      25A1DB8089EDB52B5DDB2C361AF8DCB9857FFEA7275F7C71BE121A9E6B3ABA97\n      8AE8DB04AC9F0C23F88946C2719ACA5468631F62F444BFDD422BD76A351AE1EA\n      FB474021525A462F82F5377C2F4321B0E364AE54F625D969B77A96510DC33886\n      046D0E01BB76338385DC2EE96D6D6DCE4D1DBD72F166236E329BA686998BD39F\n      B8FDD8A585EB6A70F8A73FF7D3FFF0D77FF3D2E545E458284E071D63CFE090E3\n      98A110ED90D55B612B4C18418E47511A054ADD7D78E6C0E8C82B576EDEDC6E53\n      BFD4AD75E1C576646B60B050CED8B8D6A5D85C8B427BA444C26D292CC07E4160\n      667D64638E639974A3C280FF4BBFF6B9F73E769F55F2A22436E90ED286AE96BE\n      BF355D9600F534FB05056A5E5B62E0A95D3D15CCCD7E7F3807040C0405A28039\n      AE1DAAAD6FFD70AA34A86E9F0CAD164DA234B4332A559D5D28FFD2CA5B753F7E\n      7173F7E2DAE0C1616B26802D46E0BF8AA66CECB9F2CC35BCDC72D1501DC3F610\n      9E5236E32860B3F70E0E4C93A81E9D7F637760BC3C77DC89EACDCB3F0C57AF50\n      62D15D555DE6648179DBFA1A53AF9DA5304BDB4A8BEC699F293DE4ACA917AC9B\n      D64E80E8E61ACD10404B063C89E4E847531658B31DE35D43E6FEE5A2CE24BA22\n      2ADB6494D85CF9ED1ECF98C96C2E99C17C06953C69DA63EDC77FEB74F1A8803C\n      77F1BBC3EFBCF2E4677EFEEE78809A54B1ED8A29475EFCCEE6CD1FCE7FF47DA7\n      FDD15E84DB7EE81A8E6222151C6BD7582DA7D2E57A5E337FED423797C90F8D41\n      228D3617ACEDCDE6C963632AA9536CCF2F749716DBA74E1CCD0611355B482610\n      F2715D59C29F6FA74FCFEFF0C4D954E615992EA6BA6FC544B66E7FB7F4BD0AD4\n      889CEB0DFACEA1341C219992B1FEE0C3A393D3130B5757827C38FEFE71345748\n      B875EEEB17DFFAFB8D4C7C6427AA5F34D3150387B1263540A00C85A88445268C\n      73DD696DF0D441C7ADF08898B2C2E6ED3F3B71E7AFDFC6511DF22FA4BEA81765\n      1D57724E22FAEAB36FBDF6478B380A2CA3B0DD034C9B2E4ADCB1F39238864C29\n      EB118DECB5CA0EC569C9F2A6EC4C49C80199647078FCC01E16B12B375784EBB7\n      09EE411E8ED0360B2D9BECB5BCC399ACD76B16289F1CCC230C495A2F23AC81E1\n      F851C296365B2B1DDB70494CF84ED46B497D8E026B99B72DDF248E4521CA9BB1\n      1653DD87644E15DD62F3AE8F17EC8926422E728FDCF6F127F1E31373DCAE4D1B\n      F404CF50BA3DF93014C27BA4D7C47E5B56B2CFFDC7D595B7D48E59BD2E835D95\n      3475FB00B198B60462FD5E94BEB4BB6206E93B9E1147A421C26D6C434ECA9268\n      96C83985C7082E04F103EF9D9E9C75D3A44E9822512BE19E60850C0B93487CFB\n      9D5AFEF6DBEE7BF0C09FFFD19FDF5CF0B669F16AB475B31E42A65322E9B77EFD\n      FF6627F495B6BEDFEFDBCF6BAF1A420ABA25028580F10D6A51E5D0148A928573\n      C2C0C28A32C4CA2659E9B69D54CF0EEA4E1F24B56D07868DA395810DA62CA93B\n      5E128A13AB33980413093AE89B65C705D230328B0F9E343C9A90C4A6D2E428D1\n      F62DA8ADA4AB6FE90D699090E2486A751D97E93E502B6E5B975EA8D76FB87524\n      1A245D4BA20A46A1EDB6E19BB9BED5E07D82472105C06388346110B4BA6B43F5\n      6FB9A4BECBD4D650DA5992E91B58A43F783F5475BF38E1D26314284B63D6E7FB\n      953716672CAB7BE041FCBE5F3CEC0491EE70B57B06C0395A82E04D9D8E1939CF\n      FFD9C65B7FBBED1AD696DA5931FDCB6DD244F690EAEC77D1EDCA9DC04E34297E\n      F2CF7F8E4FE700E698A8C3D5A212DB86AE41B0F07E9DAE38CC12CF9185EF2FCC\n      9C997AE1D9B3686188C9A14B6CAB1A374AA65BCEDBB349BE25EA43F7BAF7FECA\n      5D38636C3EB378F38977EE3C7128713BD24A00D459803453C32623CBCBBBD215\n      93FBF28DDDCDD6361B1D9DB37DBCB8B484E2C185AB511B20EB5EFAF02FDF168F\n      35ACD45201E4E1D4942E8180B711A7BE418AC00652923AC2C222A360FD743F3D\n      BD65DA085842A4F28DD72F9E3BBBF0DA6B8B17DFE92CAFEB46606C9152A96000\n      2E8D933465FDDCA7DB25123D2B496045528867600F5C0F6C133D5F419964C081\n      6C824BBE6703CC74EC04E1CD662BE23C708CA15C41345BB3A3E3B06495B0B7D4\n      A8E9911F89F2C4C8D9D681D9290BAB959DADD9D9C3F5EDD69BF397605F12D773\n      C3F081437BAF2D5C3FF9E0234363A37FFF4FFFB8D1021465945C52B29DF152A9\n      D26CF4A4EA46BCD7E6296CF52080641AD5EBA7268A0F9D38B553DB79EEC26566\n      D832350DC3A9F59A86E2771C39D8AB578DC05EDDDE1ECE0FB6776ACA4FA5B42D\n      EA17E191098B7A4D48118EADFEE88F7FE7C18F3C2092DDBE243F90AA96D0F09A\n      C65A9EC682AA6199B636600252A8AF09816969C93813F7F439233158DF8D155E\n      71625B01B393A7DFEEAE6D0E7FE2FE0EDDF558CF48BD340E298F0C06A95FC6CC\n      323BF6EEF76FF2EB95C1C921E7D8B0284B16555D67A8F27A77EBB96D2BF6800A\n      D775FF39CA00D430E2D2017FEF1D3929C3AD9BACDEE07327B37EC0EBABE4D5A7\n      6A69D78C4DB6A5C4F588AC135A955CF740A402A0780ACF019F0DD60DEA8DD25D\n      318012F54D2E56B75AC521B30307ECA25BFD34BAE6E903A4FE3FB74E5FFA5FBC\n      359BAFDB9E34FC927E2F11F0BF27B26C0EF329E195CC6C6AD64F7CB0F4F067F6\n      8B6033EA1D7BFD1FBF5B70D4C99F3CD253CC6A0292B05B55FB9B7FF2D6AC3F70\n      DBFB4862ADBA8DFDC481CA1709200024635013D1A6221D24F217DFECBA566E7A\n      D610AAB7B34CD7571AA78F4F2351A1C4585BE76FBF5D3D7AF8F868995363476A\n      19583FAE233B86A7369F9EDF6AD4D50E76AE1B683EE9369BA94B33B096D214B6\n      3EAB84B0B71C62DE69B171E115F1D6B1D303878F1DDA5E58C90C86238F0CA3A9\n      0CB7DC85E7579FFFD39B5EF55003375F559D05DD3E0B05D5D44D2052628E5241\n      184B03821D17B7697A10358EA8FD4ED2BDED5F8DDCF36B2761DB403869832140\n      AFDC5009B35D87F1E8C29FACFEF05FAE16F0742FEAD62C71A993AE612BEAEB7B\n      B97AAA3D5418A0960D30C4476AC2F5F2A918A1282BD382A9F68D8F85697C696D\n      8DF9B97A8C7B09AEA8180AFB7E373896CBE7A36EA0E291C1BCA147F46E498AE9\n      F9750C50AE95DEDC4161D20308034CA321653D8A2396665C28827AD632110290\n      25ACF72C14425E70BCF6C98F05C5FD890141641D3EF5C9EFE20F8DCF32B33A63\n      5A2754D6362AC0081FF8CC9DDCADE2A02B7633CFFEE1E2FADBA4E674AE316B57\n      F126859C4068AAB56BFA3B4C5BF462ADCFD8BF4F97C4467128516CE5E0CB4560\n      81B62C87E9A4E78D8EF0F77F782F351B2AD5673828EC72E14AE9DBBDA45D67DF\n      B8B87EF7E73EB1673AFFDFBFFCA79B3BC55DA770A9B77BB3D2C6D445B081FA67\n      86B7405C5FFC5E9B6853A3EFCF47F4F083D462A728230C0B19C0FF84AD0B8B67\n      4089D1C3E71E355D85E16B1029D25256BFB734265A6512AAA0A57576A5968BE3\n      82422E354C661A12476569CC2863C6748A966B5AE9DC097762165E679B32CF26\n      6E0CCB096513D284042202BF966323EADBAC008E84AA281CA7387FA977FEC52D\n      9B0D6E2BBECBE2CD386A188839410F6860AAB18CB64544C2329403081CB0B602\n      1E690A48CA9C690C4BCDBE773AD17289A21F9EA4DFA3A38938144753574DC001\n      AA3D62B039E48C49BFE42A67B0F6B15F3C357298482F8A010AA91C911965B1D0\n      ACFAC1F0F2F7D0D7BFFC9AD5F15ABCBEE3A2ABA1B31A7A83B4BEDF336E53DE28\n      B6BB23C94F7EE5E7F1DC80161AC3C08A1605DBA25CDBA9A1D46D391BAE70F08B\n      D69BFFF2FA6DEF39F5E6CB976AAF1B4C96AFF2EA4EDCC812ABEC9BC366218078\n      CC354FFFFCD1FCBD05D444AFFF3F2F0D47D9C1A9200C1A3EF067080420F3D26D\n      34D56EAB3135EB3B365A5F88939EB1FFE8C4C6FACDB49B5BBA9EB6C2D0CACA87\n      BF741B3ED9B4BB1672DDBEAAA8F9AE9C9199C324AF8F40516A0A47491B5B5D2D\n      9CADFAFEAAFAAA56AB0737ABBDC5A5EAEE26AB55F185B757E2D878FBE6EA8D6B\n      DB296381E72A64B3542B288449CC0184BC3B73A8019DC96EB56261CBCB588117\n      B228E9B57DA5863C3F302CCBF39B095BA9563C8C0B99AC619188C5A3859243EC\n      1A4BE777B670AC818397F1E746478E906081D583C2403633F0E4F77FD035941B\n      7846141F181FADEC6C7FFE0B9F7FE3FC3B4FBDF83AEB4FBC4D943259443296B3\n      D3AC71D394CA6CB7A3081E2F9749716C46F127EF7F0075A3B7166E34795AEF86\n      D8B47B50945271FB8123A8D26C276158B462168D866A5279F36EA2223C902DB5\n      9A1D008B116F7A79F56F7FF7973EFEB90FB2645B888EED00BF8B0C52427AF28A\n      A73CB66DAD30A92729FAD18675D948A488754F8ABD6E700AA01236202369EC24\n      8222AF6B59375AE7BFF7D2B1C7EFC22358A51543069D30845DEA45294D7857C4\n      342846171BD1538B7433CCEC1F714E0D267920E36B5E6572F55B3C598990479A\n      922642DA94C3E7C1057EEA03436EAECDEA990B2FAD4ECE8D8CCCDA5CA89B6FC7\n      57CF86423A4DD25B576831251B69CC2D28AB14C20819293C8378D79159CB4569\n      734543435ED9BF6FA75CEB5E74A9D68FB965C10D29C1A2E6ADAB419DBED02D71\n      19D13F5CD5461C14702DD29D4539AD078266089EA490BD537B24FAF86FDD973F\n      D04D4DABF5227AE5C9171EFEE231913172BCA4E22D1CE4BFFF978DADD76A1FFA\n      30F5C736BBDB876CA7A9ED64A4169BC4C4246648684F71FFC2D9AE62F6A1E381\n      92ADDDB5606569F7E4B149AA5AD490BB557AF6D58DD9997D735394922A4077D3\n      C844F5D408694A73CF2F6E2FAEB7778D60C9C28B71B4D5E8419E2390F1B4914D\n      AA2DF2B0E552F3B4ABC6B83D62B6CAC3C91DB7DFDEAB5706467A430F95D19E9C\n      74BCDD0BF527FFC379BA7960D3ACBE85E20DF87EA0C1024748244AF4BB450DF8\n      BF598C03D768B0F62C6E1D56731E0B8F7CA2F0C86FDEAE9C1868430C01A8DBF1\n      0C99A47A7A9712B4E47DED8F5F5A7AA5039152499315692EF2749B770D5AF088\n      4FC9AE52C01F462C7DCCDECBD9E6A041C6091DB3896CD5CBC5CCC4D4C4EAC676\n      AD1DF7905509D38E8D63164EBBC1DE4CB6287920E2E1013FEF5B5A47A1DFE101\n      A9D4F1FC141B4BB5DED64E4B015241662B4D7B22E9B2A8DFC1A1CF0F75273F56\n      9E630E23ABACF2BED39D7B884EDE66C04E16EEA1539FFC1E7E7C7C8F30ABD3D4\n      3A86F236D99D7A20FBE067CEA45E156722D2287CEF3F2DAF9C174D3BBC92D08A\n      640D536BD2D304E9C2D12F7EB4BF8D1840B27EB716255A2436C690F1E8B811CF\n      D26458E282430F1F75EE7AA04051173E9DBE8388002D1A8C4349B12A3BE29B97\n      173EF25B5F3450F2A75FFE9B56B7B84EFDAB61FD66ADABB55D905650127DF540\n      DC9F7612FAE00BF565423576079407FB3A36B8ABF9A86E180592A6BD7F52CBA1\n      2A08F80031B35D8742480491368A171AE8C2C68108015267F75B7154DF2099EA\n      B1547D7F6F095C86EA6219A3CA0F9031344E8EDC997582160F13C2ECFE2C5A0A\n      E08BEA3B3D579BC050AD2383E1E769FDB3C8F68CB8E39F7BA5BBB9AA95B23790\n      AC2431FCDBC184512B963885BC8BB4F2A3E84FCF3BC870B4781A517AE4420257\n      81428774E1267DD6A811AA6E76EDD36F2091503499A44C9704A6782F1072CA72\n      A0668FB9AE12D5071E9FB9FB3363DCB819F9E52C2EE144A08033DAC64E5E554B\n      5FFBBF5F59F9612B30832DD45C26FECD56E0E39D0301C020775859BD09FE913F\n      FBA23157D285104A965A6110204CF70A62E074CE3649887FAD74E55BE7E68ECD\n      BEF3FAF5DDD71493833765733BE93802173C3367047B9C8CE86D161FF60FFCC2\n      011AA0E8E5E4F2DF5E3A716C7FE26F98AE3E0CF66CA7D7EBF9CEF0F2CA4EBE28\n      8A25BFB96BAD2FB767F61691D1A9EF0AD62B5EBAB808E4EF8E9F3B987B2C327B\n      B04A9E722C5859830280F18451E0348389A4DA995C8FF4201269CF3C4DA48916\n      54D2BA69803A3D64067ACC8463DE4BA422405D373777DF3A77E3896FBDF0CAAB\n      ABFDB66A5B232B9DA880E90166445AC8A02F5A2B39720D5ACC1502CB8AD3B0DE\n      6E6253950A858CE90E3AB9F6766DB7DD1686CA0D956ADD168F93F1FCE07879A4\n      D6EE5E5E5F69A3C4B7CDDB46A6EE2E8C5D16B5959DD583878EBC7E6DF9E6C6BA\n      E7E81B6CDFF18783CC677EFCB1AF7EEBC9B7963724E4398B0CB82E663CE9C5DA\n      9F2B9749B8ACB77A0A369C0391AF8E4D4FCF0E94AF5DBFB1D46E03B68B6D5545\n      0924AD9313537969ED74DB743057DBDDCEC47C2297755CEF6A14A7ED76D6F254\n      AC92247233F2677FE5C3BFF01B9FE0B49D023432E029B90581C48B3CEDDE527D\n      D78C5A68656A6DC4A165EAB4CE2CD25B4E327AD3E4A691F623C8ECC51EEC0A61\n      7531E5C1CD97CEE3A43777FF81D8DAE57A5A92C8760FA5B10974388E59A200F1\n      77AEB6E21757CCD596379E2767A6D1F4961317775E30B75FA90538578F786C31\n      C02486A2A9C90EBE2F33B42F5511BDFCBD1D8A33FBEE2CF67003B3F2D9A72B8D\n      352DA256411CB0D336651BDD4EC2B304E5080E39042FE98365AD28A467E6B5FE\n      63FF6445B733E83AA912AB7FB6720BF2F48F936ECDD46B5ED83F0EEEE34EC1B1\n      696912CC4CD349B8B6CF1EF5F85E37DD23490967B911DEF19363A73F3258CF2D\n      15778FBFF12F1732FBF0DC5DB3AA0EFBAC6AE69DDDEBA527FEF3CBC7A7CCDB1E\n      1CE84ADF1035AD23DC6F2BD1F2568060AD4871EBD29B51BB264EDE59020253DB\n      2840213C7E64CC441D8C925E14BCF2D2C6F0F0C4BE69D3B15B9AEC192EEB0AD5\n      821C937B67AB7171B5B6819C55855779BA9B8A1EA32907962E6C0A150C9E9BBA\n      D4D967CB3D863F66776DA379EAC4091727F9D1C6D8C3C368A628296A5E6F7FE3\n      DF9DA76B4756ADD5AB586E1B54A514B37E479B01584E484C2C626510CA58462F\n      ED0C92FA21B937E0D1CCE3D687FECDDD24A78F00533DBFAEFD540D046F32D56D\n      1AC8D97EA1FBF75F7E2697E4BB5DD5B49DEB497595470919340CD7203B48B431\n      9FB0894A39E0333EEA792526663C376B08C9C3E1C172295B5C9C5F6AC682077E\n      4BF156D8CD283CE4FA238E9D531CF0E66811D888D6D9177AB32AD3B69145DB22\n      DDDE8D7BB19B72331140249346D2ABC4511BE090E35A1441A9F54D2387DD21E5\n      F9665A3C901E7CD0135E9804FB4F7FF205FCF1E939665426A87904E52D5599BC\n      2F78F0D327D3A046B289D11B7AF5BFAD5C7DB9DBA2F195C8D851AC69E9892223\n      D5699B19FA52FA1623E4FA90453B5F201A0B6C85899107126AF149148D393EA5\n      DD07DF3FB6672E31582C622B6182265AFF4CCFD9C5C585C5F8C5EAF2677FFF97\n      D7AE2EFEDD7FFA4627292E627A3DEC2ED67B08D037D15A4A5C17805BBDD1F896\n      6AA8D997D5A67A004A03832E4A008B78C286CC07244D2014A46EC192E5423A64\n      58A57616367C27A87139C0B8680BD102CEA87B0390F3AE86A730B19EA5823A14\n      6231840A45B33DE39803A9EB227EF0643077DC8ED21A5036994012D3A3C10C52\n      82DE72B66E283481234B81FA026BA8ED65BD95CBF15BAF41C51EECA43BCB9255\n      198F000061124128725840DD87C74C00A91A81427C78BA010EF79BA04D80178C\n      4BD63785127D7138D9BFF7577DC4AAF41D964AA4C90C8EA05671662468C4B567\n      3C738AD8198E27F6999FF8B7475571BE6DE573284F606367E0C7A5C22F986E7E\n      FE99CD7FF977670BE14444926B3C5C650152CD19C7388ABC22E48C03EEE37FF2\n      0539954590BC3477DBE2F1264EDADAC020F13BE6160A65666B6CFEA9B787C606\n      972EAC6DBC923239B48C7B5B71172732706999E48689E1E1381A6DDEF35BB7F9\n      739256DCB7FF7AD90BE9F80412A4DE1F6680A08D5D331701CE6C5547278711CE\n      6CADB7A48C26A673954A4DB1F2B50BB5CEB6D8FFF8F0F4177DDBD6FAD0D2F1B9\n      971A342128AB5029B55D60CB40DD90EC5FD3F6FDA2557F04540F01E856171B72\n      4DB31EF6A2348E81F3E917D98A5414C96A357EF1A5CB4F3CF14AB58EE2144BED\n      3BD1EF25D613695A6B51F7C4089D2E8125DA0807A695C9F892AA4826B0DF5C64\n      8C589992E5AF351B2991CDB0ED65826E9290444C5AF989B1C917B71656E27A20\n      F111B778787422CA9A576E5E983D72A8269D975E7DC3A53CD29143DE77C71DC7\n      C786FFE66BDFDE49841B383E92191FE23269367B9649F3F9CC6EBD992A5580FF\n      84CD91C2C0F8F0E8FAC6C64EA7D566128A7F8FF27A124D1672C78B633578A4A2\n      B755AB8C306B847849C6786377B313AB8C0BA9863BC4B04DFA852FFEF8BFF9F2\n      E7B9B5430C662017EB5B25A5DD4552AAAF57A9D25A2110CC14E2E0568FECADDB\n      7886F42CAF8AD08A9512FDFA91BEDFE734B285600233C0E32BF5ED6FFEE0E0BD\n      27BAC7FC388A4BD812B56AAC47D1909B10550B996347D461EFECE2E716D026C3\n      23A3D6192F18F7E2AAB8F154D5DB1A53290EAD4A93353C73A8CB9381C3FCF823\n      45866BAD6BC6F5D76A07EE1FF2464D0894CA82B8FCFC6EDA09606BAE8AFA8E9D\n      5C87F525C34C3B0AA4290636D49F17D3565B90C8B97E08A3DF8FADE9A076234E\n      AD5BF2433AD4B561BDBCA5DBA4D1931EF652EF4EEBA608D8B28005A78430E2A4\n      927A34DDEB2507149EC145132B67B6FDE12FDD450F6D3A9D60E342F8EA2B57DE\n      FFB107DC62A27A75A9EFA04B3FF8B357765F151FFAF04362E41D9A865806FAE8\n      09C53A5DE80BD9D024D6C265B2BE14DE765751E14A6373706961EBC4B1095385\n      18F752917BED955DDBF00EEDF7033FD22D7E525F47A535C834C1768FBFBCB83D\n      1FA91D65AC71BECE6555E024E6AE817340BAA46209543A3AE1A8FD6E6E9C860E\n      EAEE99981CCCE3C1A9C6C47BC7D4745E50C1B6D8777EFF5272656FD3597F9BC7\n      EBF08604140B23C500AE781843A6335DCB73349315A9884B0E30C2BD79C5461F\n      451FFEEDFB6841B7806BF00FC54077532BC9536D2A6E2476A7F0DA5F5CBCF0FF\n      2EBB69B9A3D812AF2C0B544541AC5F729B08A0F105DD0B4F7814F5F28E3520C4\n      A845075D3B63C0C656A303252873EBDB3BCC3213D368F6429602ACF446B3F922\n      56F001C6F34EDEC3BA2B539B8B116C18FA5AC943A9F01A7504E85470C0CBA41A\n      415E0AB524B70D455E5FAB006BB6A833248D2CC1F640EFF0C38E339976FC3DA7\n      3EF52AFEE4CC0CC3F5316A1CC2795BD4F7DCEDDFFBD9633C5F974E64B3890B5F\n      D938F7DC4E8FF07762BC23D396A9453A69AABBB29816A2E046DFF286EBE17A28\n      86B0D680BB4DC98D41A2F6D96812A39C850727C4031F1C0D823A6F774D99ED26\n      CC4A7D2E228142B737FED685DA82D7FAA97FFFBFCDFFF0F257FFF8D9569C5DC0\n      F84AB7079040CB820275D5E7157D11E07EAEEABBC8E9C10908584BDBD51A8AC8\n      50E9C32C5F9A2EB2A42520A58F5AC5119C0EB9DD61DB1A94030AF19ADC66A4D4\n      65AC2A789B12A119A3BE02227A44405143CF14425C3022A7657EC08E606DB2DC\n      CE07C9A93BF399619D4C4DF8E1A9D6D3967AC42205E20859587F22936BBD7EEC\n      C0A6F01C811276F1B5D6DA4A91D9C56ABA7A9DF5AA89D0A38ED44A13809BFAB3\n      4608C506D1535A02BE15BB5AF740FBDFD0BE401C54C118A2544F5350AD04D5EF\n      26D52777FAD8478F0BC7CAE4DAFC38842DC852C3A7723647F721675C64A9517B\n      DFCF8D1DF860A6093B12651C9A621A4B6EAB5C59D889D5F3BEF3FBE7E79F0042\n      965F55ED8530960E1DC1FC30F1720215EF1E7BE80F3F9B966C14739324885645\n      BC83E29A41A0CEF93D5A25897477CA979F78B35C2A265BE2FAB3D554965751B4\n      D2EB449DC4368D396BB8E88A8C8B5BAA72E04363077F6ACCB071E51CBAFCCF97\n      8E8D97B303495700F9A0B04286E4C0F216AE6C96C6C70746B38D7A6B6DB13233\n      37CC507B7333A1D1F4D6953A1EEE1DFFD793F943033CE18637C09C189B099539\n      244BCCB120FE2C6EEA79067D606AF55DE8B4D74DFF8E87E8291D643DF59D175E\n      FAE1F9F9F99DDA6E025031040C11AB5A0B85897674B55D3F4A045070AD4163DC\n      5273ED0F964321E0C8C104228869AB1F7DC30FBC703008B2909324248634C864\n      8481DB712FE2699AA4B95C4E8669D4E8ECDD77300CE84BD7DF81B49593E6897D\n      33137E7661FD863739EA8FCE3CFFFD972D9456A3D0F0B39FFDF0873BCBF34FFC\n      E0D5C2D8B8BEECDDDD713CAF1B4551C2DC8C6F00666FF60A1E29994ED90C4A41\n      7EBBD36E20BE5DAF677C3F76A9D61CE9C4B7CDED6DF79A5ED1EFB65A3EB26C62\n      F7103ABFBA160A7D54E1F85A5D1772A8E3D85FFAD59F397366AA5C5258A6896E\n      B9778320989C187361EB69534E96C6DD7E8335ED57068AFA33A40838823EBF90\n      09AE9A29A3498C081316D39D43901D0D59CFD07C4FA6DF78C5364CFAD849EDAA\n      A6520190374D69C82C4D2E1860BF8E880214180BC9D6938BE62A0E0B99C21D6E\n      6E9FB5FA66547DC12970BF2DD76233C5A4A4554BBDE689474BF644C30CB3179E\n      D9145E72E4CEC3DCE859C8B8FE6A63F91CF0B66C03D7D750635DF93B3CDF8814\n      3038484BA9FECC7DEF29E07622D12390FA9C00B605D0309DBC127DC5D9B7F5EC\n      BB32E90651532B6A306D3E24F4B83DD28900A88DA97784AEAD524B8D5BF0F7C7\n      2C79CCA0079453B2ADD8DBBDE763A70FFD84859C65DE09BEF395CDD1C181DB7F\n      AAC4C2AAE2039615D7AFB6BEF6EFB7EE3AF2DE3DF79D27AC87645ECF27921EE4\n      4FA45C62746DDBD85ACE5EBB583F73E78061D52A6BA585F9CD93C7262C1561A3\n      C765E6DC9B8D6E83DD7966CCB13BB6EB329E02654A6BCA8CFD44993F5CDEBE58\n      87AA6BADA66C818B0DAE0C6A6729B5303C072302DE879933D9ACED4D1871C150\n      E520375C963347D3A987C7D4A8C73C413BE4B93F9CDF7E6188B8DBE779BC44CD\n      185B4A778DA561DCC3A9D20AA69E0FA42B4A3A511CCD14D9413E972762F021F6\n      D1DF798896A806F5A602946D6A4F3E78737A80B381DABEB4D225FB99DF7F65F7\n      BCB68E6C1A7C89C915C8260A4A2C7680AD6AB90BC8EE661A87A6929EA10A1497\n      092E233200E50AF8F7F010A4FAF5D57502100AA19676ECA639D71FB4EC01168F\n      F974B4601B462C485F711C1805801E4B7A41BE1789C66EDC6DC13608BA925479\n      D2A3AA2313F8C7D57B9A529B0E1352A6BE229DD9BB54FEB86A0463A73FFD06FE\n      E4D40447F511D33840066CDE9ABDC3BFEFF34778A9C168CFE39397FF6EFBEC53\n      EB09A1EF446853842D0B00B1D6A880E74831A4126EF47DF238A4353DBB870197\n      00700BB03588BAFB4D63DA2E2259B9F3D1E291BB5DD822428F7FB811E738F485\n      EC0A7865C9C197CFEE36A7E2C77FEFD38B4F5EFDEA7F7EB11E9A8B545E68C66B\n      4D466DD3D43A6480EE342314FDB109D2AF8444C33AE085DA7D574B7D6A420699\n      CBB2B0A9A702A931E90407A831E770172500F7B45BBD104D6E5459B2C5799352\n      695A581A50C24C6DEDA2ED14FB8E339A4FEC135EC14565C3CA18687838BEEDDE\n      814475D298F64F8B186C33A9BD4739D428A2AB1846261614F5252C49D6A2DBF3\n      BB97CEB505DE5711B42AB7E645D44A859E33342CA98FEF4D8084B0B45D02285B\n      B3515318960E4E09CBC9A5C05A9B46AB9D020C88FA8A3DA87F70DA3FB7D1E5D2\n      00EAA401AE96D5309415737D9F38E2F103D23C48F224A98EDD2E3EFEAB0F2623\n      0B489509944AD1A276815B99C889327666F95B8D6FFFFE39AB37105A6423E9D6\n      291A10E941D3F3859A7874DFDDBFF799348321A7DB3441465B255519ED18A48E\n      45A69D6EC1D3677BC3F3CF5CF4A967B5820B4F2CA5B2B88EC46AB7D3EAC6F084\n      B3A4502E9A806A6D8C9D3179FF6F9E56132DDCF32FFCD54D6F4BEDDB5F48680D\n      B22D83C22C7A0E938D4D3356D6F03E9398ECC6A5AAEFE5C6F6669696373DB1BF\n      BD186E6D2F1FF9F4BEE1C7065AB89BF307B92594C5A866B105695309D452EAE9\n      087815DA058540E5F2FA5B4550ED04A905092055445DAF5E71966E84FFFC4FCF\n      BC746E2349E366A715E9A141A13B91353485BF092004F92E85641945B048C401\n      38126B87D2C2600982A7DBEB46CDB6A7F0F8C0C080EF035C89196BF20E5468E2\n      5A26AC54AD35942D2ED52A4DA4EE3C757C7D6DFDCAFAB6E1E3FD63638F95F7AC\n      57B7EA396B6876FFF79EFC018B7A95981586073EF3D18F3DFFE4776F2EAF9DBC\n      FDB6CAC6E676ADE2F89966AD059B3B33586CB69A58A4138EB3C7CD16DDEC4EBB\n      B9CB590DD0B46D519ED4B0E2CDE8917D474D05C8425B061E280CC69DF0B59DF5\n      2BDD2EEAA11CA2C24E8965C0D3948746A2301C2AE559BBE2C39B91A9655896E3\n      50CB02AAE8FAC9DE7D7B3EFAB1C74EDF7D9CE8939D446B2EBD6B6084FB26285A\n      AA8A911EE6A1C99ABA61DCD2222E3841DC9431946C151BE75637CE5E1EBBFF41\n      32D9EEA45DD3B4CD2E372151681DD74497D6388A424E6591ACE2DAD3D7D31DBB\n      E936C7EF1B7682C1B7BFB5E8773286852A6937E1E6805B8A7BD5F11374F201C8\n      2AAC72035FB8B87AFCD4F1DC5044AC8E6CFB6F3CDBD9BE2989EBEFE2F63C67D7\n      9B4664661315319D91349F33B53B22D2B6C3FAD6A66F5F0821A70C0303864F6F\n      F5C5FCC88C9050AA2772B57E05FC2B455FB81190AEC599B635850790FA0E8726\n      CC2819EE0142F609319B05BCDFCA8E0FFEE46F4DD223DB611487E7F7BFF48D97\n      EFF94871E840266E03D2838C38F0F47F5FEDDC440F7EC0CC6562C53DED9A495B\n      18B294CC2AD2B26C55DB2C5D7A630718A1E536B796F2CB4BDBA74F4E1BBC0B65\n      3295EEC5B7C3CA46FBA1FB0F29550D7299948788A5A2898C0EC033FFE5EDFA5B\n      9BAD26B7D6E2F406566B7A42C4215A7DAC6752D325808D896527138A4C997298\n      D2BC952917E3A3B7AB3DEF9B544366EA2546177FFFBFACAC3E95CFE55A5008AF\n      125293506A35620754E060C32616BCB7149201EBA63C3DE04573F19E2C6285FB\n      A34FFCDE23EE5806454CC0AF0120C1E1D5270C6B71A5C48A3063811858FEEEEE\n      B3FFF5E56C54EAB4E34DC46F22BE2251443C07591E8EA0A600E834B5A500B083\n      30B08C11834E6B812A5786DD7CC6191D2CF3766767B78AB24135E12D6D924846\n      3CBF84E4A88DF7943DDBD62E9B294F1CD3849D1C6BE4CB1DD7C2CADCDD895B2D\n      2248D04E45444487C751A25D6361CF1A012D0A56C6791EB5A64EF3B107ECC6C0\n      F8A94FBF867F7A0FBCAB6689A059355030D2F1E3C6FD5F38120DEC4A9A7A786E\n      FE9F375FFEE60257DE4581375858D76E9DA6A1EDAA002CF5C5AAA5EEB865BA08\n      EA96E558C6360AF24A4CD9BD39EA166496FAB50FFDAB71BF54635DD80B411C86\n      DAF63B2C28D54C448D34F73DF5C25AF9FDE5877EE5D12BDFB8FC9D3F7EB31E1B\n      D731BBD8116B0DDD23EBE9A1759A2429E37AEC4F37EC4A796B02D6D0223A8042\n      8DFEC43944F02D1B605816D777ED3D013D18A7C75C9FA1666EAE4805ED2DB61B\n      185544BA2179157E82E9E88E6AA16CA0759ADDA68E6DC2A250621C9634EF058E\n      C0C59C3873A7579C88819DAB24D0D6A63881342B840BA5D7602125A6D63BD7E3\n      C71C00769A32D54557DF5CAD6D9BA93552116857B45614E06F7D040A20C2316C\n      031BB0801DC1DA4A44FD11377D68C3FA032196BEDA8D6163E8A94C432A432B5C\n      F5954645BF79E1D6101B1122A6880108D2EEF6B6D093CDF190AD0E1372183925\n      8BB5C8F6A77EED43E38F2C44710930AD6725B053047645CE011AE455724FFDC1\n      D91BCFD51C77B09674374C9697C9914C316D35F77FE4D49DFFD74FC5AE228930\n      498ACC9E8C5B325CA7781331BF9BD630302139B2FAD24DD594A574E48D6F5C65\n      BCB0A6C45A1CB62288733A2470D65165DFC9007950BD933F3D3BF1C92213ADDE\n      797AE5AB37C607722363C0BA9A0A0F48D6F6088EAAC59D4632301B3BB9B85373\n      D756BAD38706198A2B4B49869797DF5819383278E0B7F7C7433D53233F0A488A\n      0A9F0099B41C0501255D7D3C4239E690B32CA91C3DAF651A3B3BEB7E0041E118\n      56A1D3A06BF3DDEB971B2FBC70FE89E7D65AAD5AC2637D34C4B57F16020C03D0\n      0A369540793FE35B6EB7D30D814CDBFAE410600E104FDF748084852CA9769AB0\n      0883F9CC6090293A5E8747CD56A7DDEDC162397A7E115E9279637B7B3893BFEB\n      F8C9B7AE5DBAB15ED9333BFAA9E27853A4EF24ADFD278E5D79E3EDE5D59D5A14\n      8D4F941F7ECF7BBEF59D677CDF3971E4E0EB2FBF99120A5C30ED85806BAC814C\n      B3591B0DFCBD7E76CCF27B2CB9D9A8340C7DB296753C8B25F07B0FCCCC16FD4C\n      B7D138BA7F2F6440C82867176FBEB1BB9B1A860F958150AFA8E0CB491C0F950B\n      59287B4285F5AE6B38AEEBD53AB59E88153C23B50E1E291C3D7EF0FD3F76CF1D\n      F71E83140C410C1C98E83173C08FDA28438B354A8D7A314D086048D6552216B6\n      A95D3B75318921FB0298BBFCF517CABC38F4A99128893D661B71FFBA31AC0BDE\n      D1C88E4361B2A30EF2A59B6CB59BDFDB6C6F43C859D3C7C676B7B66AAB5CA685\n      AE144C2481F4324AD9A5C6FE4707F94003A9810B2FB4D2303C75575938BB8E9D\n      AD2E9BAF3DBD1DD5062293AC1BDD1B9DB4865C003CFA0017C0AA5416C28E6681\n      5A120910285447266FF56143727C57B2F15D4B5E883F0DE2951E20BCD52FD3BF\n      17858CC9FB7AE30681B710330C65D1B198BF87DA471D36229A79C7112CF763BF\n      9C4CBD7FB2495A85DEC4F7FFFA4512A8073F7A1B623B929A529676DE499EF98B\n      97EE3971626A965383721429A321A58D554EA1B669ABCA6A76E95AEFD8C9C0F2\n      DB9BF39995D5DD13C7276C9448D99028D8DEB22E5E58387D6C4F26A73C9FA65A\n      B04D880E800140F0D65BF5F0FC46BB96E02D81AE2B341FA7B12250574CC46CCB\n      0ACC8CEED9A3BD5189F6186A8C5A3962978BE9C97B8DE90787D18829F38244F8\n      077FB2BCF674DE761AEF307651C92DA1E7FD0C8A6DCBC0A98035855C1D1A32ED\n      7B1FDFEEC553BDF10CE2C38FA00FFD1FF7FBA381D68FB7FB53DE123880D07DA6\n      B051AC50CBA94887769D67FFE899A527EB7E52EE50B544F83BBDB4852DA0C2C0\n      0481E5006DD0633A88473C36102F613249EC49C709009EA6BDE15C76249BEDB6\n      5BEB8DA6CC64EA52B53BF180ED8DB9AE1336274BDEE000008244F2D4A17A709B\n      693FA1D83013CFF398B2EA75D56CA8243652A10F343A8C75B515295156EAA6C9\n      983DE248941FDF9D7AD0AD8F4DDDF6F917F1CFCC8C4BDC1A348D19A39895C9F8\n      4172DFCFEE4F86ABF0ED2EDA33FFF58D97BEB1A0440085709D450D7D77601A1C\n      3E3E8EF511B1A07D3B5BDEBF0586BAC2891E259FA0688FDD1B46407DAD93F796\n      CE3CAA24DD165DCF666E1A77F4D05E58E2A28A69D4D99878E6E5D5E99F9AB8EF\n      67EEBAF19D956FFD87B3F584DCB4E4C58E5AAAC400EA7D40F9507C522D90D317\n      09C19CF75D34FB5E735A6E5B8B671B10A450CB84A9CDB92C150C17F2337E7A86\n      5A5321AC3F9A7BF4E0C5D7AED82BD6360E77241442510740D8771BC05C3848F9\n      B6A99913C4501C7BD43E6118819D87701A1C4EEE78D0277437895DCC0B18000D\n      8914EC10EE429A30710FE2432B3D01DB73AD146014F537E6DBF3976AF063BA86\n      5B5162A5DD6A6A4D5CA5C778213EB5D20DEC6714427A4040EC889EF0D732E990\n      C7445FF1916864DA1F13E95F79217DD7A1D5B7B55FA88E5EA960F744549F9752\n      602ECA84C41762E62179C4320E2336683046F8D1FB8E3FFAEBAD849653A88194\n      F77DD9DD08129F273CEE5DFCDBC517BFB264F4F280D66FA8B0EC9069D3456978\n      F8E3B79FFC8D0F471EA2A9A4FABE2D154907856B065E9689AD7028E3D412B9CD\n      375692F57498CCBDFDF577A2D85B97629DB37AAC2D96ECA43114E4CA9657A60E\n      8F136F0E3FF09B47D46485F0F25BFF6301DDE89C3A3A14C90DA9FD6AB1086353\n      8C2EAED5E84073629FAD58E6EAA526F59D3D078A8BD7E7699495F3507DD9DCEF\n      EE0DEEB00C91021C10DA47DCC3DC42D445668E23B77F431D13E92B8C12261C2B\n      8863F1CE85ABE7CE5EE934B04932D7AFAF5DBFB1DDEAB0EDEDB89AD85A6C448B\n      72CB5B221F96895D084D60DA09872AE8590E876410D0244DC250F79302E52C66\n      F3BEED1A40737CB7D9AEB73ACD6CE08C0C97F76406639656AA8D4AA5DA8C6323\n      E30DE40BAD76B3D26EEEDD33776272EFF33F7CBE93733F5E1A7406CBAF553747\n      A787E0B7BC71FEE64EBD3E33593A76FAF66F3CF7FC830FDDC39AD5375E3AEFFA\n      05C0B7BDA417F881EEA6C1686EA034E8799C27F395CD9EAD051B85C005D7EFEE\n      5487F2D9A191C16EDA3BB46726C769C2C5936FBF79B9D586D2356807AACB7CC7\n      E5A4957452C8264305ABE0A0A9918934A2D57ADAE1A2ADC2ED5EA31E333F5BFA\n      85CF3FF2131F7B6C7C326FD83D6C41A90D11D1D6465A055E0BCDE83352C69901\n      AC4B74A991902E54E434A5297688D905F80FB0D0E84026BB596D7EF56CE92393\n      F97D33AAD1D16D84498815B0C2444FA202476236E93222995031BE1957CFF2ED\n      4BB23CE45B83ECE64A45A663496A72D1CD12D3838CE5B626EFCA3A47584254EB\n      867FE1C54B773F74203FC953DA91A93F7F969FFF7EDBF5277649BCC63B6B51B2\n      0DBF46FB6E537DAAABE7AE741B8C0E2203255A68A63F8CD4EF3BBEA54DD17727\n      7D578948F4A708E52DC7CA7E9DD46E16483762E8DE1B885D923065C8D82D23FB\n      60C067CC68847866581C7DE8ED0F7CE9933D6FC764EB7C2378E61B0B0F3F7232\n      33536348247882D6D9F37FF57DA77BE49E078184B4901549542324903C40A447\n      4D5159F596AE87478E078EDFDB5AF657962A274E4D50A8753856D8AF54E8D997\n      AF1CDE373D3A9A71B2DAF41B3181631343314DE87C88DE5AAAD612731B1B37A4\n      BCD8E802C7D28D7C069420EA601F0174377A65AE0E4074DB764139E54179EA3E\n      7BFCCE8C1AB7D24CECD0E0F53F5BBFF175C448FB5AC2AE22B403C9443FBF9E02\n      4B93D8016A6DD91DC5A2A817607A4F9E4D47D301627B3EEC3DFA5B775B456DF2\n      AC685FC640DCD2ABE4F02786CD453DA0462EC59D73BBDFFD8317C2CBB6610CAC\n      C86899A00DE00A185B02E9AE0A43EB11EA714F960283CF6B6D4351C4642AF00B\n      4A3A221D2F1702C7B9B1B824A12262A315A6C0530BD4F2251B70D050C11E28D8\n      FA43A4A16D7B09B611EC4F2B350343413A37B33BEB9DA841640850D6E92A0017\n      5128D3888581690C39C38134BCCCD6C43D7E7AF8D091CF7E077F617A18E049D9\n      B1F6D001603493FBF17D5FDC978CEE702C3D35BBFEF4EE0FBE7A45C6D92BDA82\n      35AC69E33D4B8FA36B2B4FADD9AEDDDFFB474B5AE30CB8A761B8099FC262DA8E\n      07605D2CF4D8270E0EEFAFA6BD6D15E5096C74DE1650AF93622AEA98B2C6D2D0\n      F317B66EFBE513FB7F6C7AEDD9EAD7BEFCC26E57DE70F0E51E5EAA464831CF14\n      581B2AC994EB36AF1F4905EA13D1BE7016EACBC8E87E2793706E45314719E4EF\n      2B0DEECDF37D3C196374F04071F0F6D197BFFBE65063744D353679B2A90DB9B5\n      998C1E8384EA2985676B6753CE533B15653B73D42216F580E5CF1D2287CFD871\n      BCA3359059A02B178EF475147721EB9B24D47D2C10E05258B6C5F44561F6EDB3\n      EBEDBA192367B3D7DAE2ACC9516269EBE754F69BD3F4AD37A4029D1EB4BCBFF6\n      913561E3293D9509604C3F9B9615ED9B31E9997AAC675AB538865605EFDB0BEB\n      636195E81E22805D800D4984644FBB0388398A8E9AE998A96CEA5941E6F15F49\n      C6EF3814BA896E4CE53626416A91D4EF7AD8A8BD869EF883B7F9BA6BC8E82A8F\n      4BAE3166DA14A7F7FFE207C63E7F5FCF482020A07C2B00D56982E3552CAFA3D8\n      D0F3CA5164707BFB9D9DCA85FA81E0F8D5A7AFB73B649DB1752176E224458683\n      5B01F607ED42D97532F0A4A2BDEF83993D5F9C649E1297FC6B7F716E7F294B86\n      63EDE8901A549A82D9D56658EBAECF1CCA1383B6EAFEE64E7BFFD1529CECB476\n      B0BD39B278652DFFF9A1C39FDAABCC0E50130EDB1DD97D637920E545417CC8DA\n      005F15CF602AFBC45B9F5D639459BA52F9E77FF8C1534FBEDED50775C55AB3D7\n      8B445B3BACE9CB208D340C2DE34A09724CC3A5D43608E0218B1A3C4D7DA98DFE\n      5A61B709093F7008542326B28655B2FCAC65A62CDAED5470609E18982A168B8C\n      A356B777796375A3559F1C1ACA9876B5D36EB65B8F9CB9AF94297CFDA5E7DF3F\n      5AF64BA5159144BCB567CF9EB36FDFBC787DF1CCC1092B53B8B8BAF3898FFFC4\n      F7BEFDF5A5A56AC1F6C338696136323C980DD3A3D9F278B118DBF2F5A56B6D11\n      D9A6AD8D9C609B0A6C736364B4D48BEBE3E343C520D7EBB257AFDE98EF767AC0\n      23102D6B7164DDFFA25852CA1607026F286FE5F266ADD9BA786D473341D84AAE\n      6E050923E6FB85BC9D7A817DE8C8F4DD771FBDEB9E13834303B68D837C1641F4\n      264D442151C53C8D2C23C3756D496CCA55B7821DCE708F70463522C500E96D66\n      AC3FF1B2B1BC32FA130FB031A205D5C2180369308C9EC032115A1E14DE41DCB2\n      8850C2536B7EFA62BA757EC72AD99514DE7456C619CE63D79236B2184933337C\n      E2818C087A66CBBFF8FC86EFE5E7CE04CC5FC7C4978DE1379EDDDA58C4291DA8\n      A9F68EAC2DA57607C82F1441DD2A639AFD4B75AD20A54D3EF50544FF2EA52F84\n      D5AF7EB86F4CD19F4692B7BCBF6F199FF64796A12E9A92245A53014216A8A1C1\n      38605966F9D89E70C42C4DA69533C08A78F2E2E3BFF458F6583761973C7EE0E5\n      AFEDBAAA7DEAD18124502A98B43BECEAB7CF5F7BD17AE88159CF4D94D560A26E\n      1A79211CCD5D0CB9BBE62C5C6B9C3C5DA276178AE2C2E2EEA9D31386681A58E9\n      D6C7D43FFBD295F1F2F8DCDE41EA773940F014D9D261B590F54813056F5CDB59\n      EFC98A612F30B918890E7081FE29AFBE29E2DAF120B5A23223873CBCD731F3C8\n      2E0D90C377D2B97BB2687F8EB95DCBC95EF88BF5F37FDD24B6B110B3EB026F2B\n      432B25282E750BB174B5571B6E017009A380A113F9DE6C32EDA0F4C867461FFE\n      F5DB912F3037953E0ED3C2697D7D2F017F1A698A5CB3CD22C9C33C0D769F987F\n      E23FBE45BB7B2213CFC71BBB9874B9A308406CD2E3694F26004D3CC0277A9094\n      9B58164D73949893F09AB0F26C3238908395DA6C345A90210D330E1950AF82E3\n      D82A2D38640240B7A344DC766C27352C24990544CF615A67C377811B37D693D6\n      862028E096DD96BDAE08F5D122A62EC9960CC731B7864F66B20FDC7DF0B3FF13\n      FFDCCC1052ED92634D5AA57C2C27F7ABBBBEB0271ED9615866D44CE5A5CE33FF\n      F33CEA16AE0ABC927477A1E41113F217A4E944F799EBA44C741B2D96FA9851AB\n      ED94899A16E93420779296F6181FFCE43E3FD8E6BD180A49AA559753957023CE\n      4AD9152AAD2C955FB9B1F39EFFF3FED1DB0B1BCFB5BEFEBBDFDFEEF0EBB67139\n      34D66A91D2CD38A99E0A44FD4E12C87312F6785F2E8910E396EEB6C67150223C\n      3DD567C640CE07CDCCB181C1692B9D32B9257A87CEECE33E9A3FB7EA3572DB84\n      C1536C2316E97A6A69A71E284A0C90AAB23C0B223ECBF1989D3B6251887F2BD3\n      3B7D5FBE301C416E5589236313D8BF925A504809470A1BAB9E96A5D00A9029D1\n      038BD9CA86BA787E3B915E43F00617DB691C2A22B42615543EF8E63EC2D4134A\n      50868D04293DCEA8A703354AE640520D7D5693DE0ACD7E371414425D17D52D4F\n      BDBE9680D68F12FDAE65640B288418E2A3A76DD549398D4E66F08C4D02D327D8\n      BEFD317CC7670F75EC35C3323D5446D8E776927A5D404BE962EE9BBF7BB67949\n      B8822CC8346BA251C755B2F3D1DFFB9CFBF8911025C0086D6D2C4BB50A4EBC22\n      F9DB04529D60529BAF58BB576A0BDF5B3E9D3DB3F4DA7ABBAD36195F4EE3B528\n      D2EAE3AA1D90EC50A69C314909A1022C78B17AD76F9F52474D3B2E6DFDC55BF5\n      0B2B532727A911195008CD6C2F82D740D6D73747C733B972C052677DAD3938E6\n      50A7B753114E6B70F3EA466384BDE7371F51631D64498903A5E722A4A64C4649\n      120768B3010049041250381000D34026E5DDC4503E9385EF7DF395FFF1D7CF5C\n      B9DE68B78D30C21D802BACDF2E81495FB900E92902580DC93C8B948BD9817CD6\n      B18C52DDD006B686DAEA36B7A21E774C45CDA81B67093D383A01A851B69A2A8E\n      604F17DC6072645ABA764B8AAD66F5E6D2E2E4E0A0CDD1C6CE56ECDB1FFBF4E7\n      562EDF5C7EFDD5E3A74FC387DB696ECD1C3EB0B85DB9FACEE58373338B6B9B23\n      33FB0E1FDCFF577FFE9700A732D86F27DDC4C153634313113AE11773D9EC9B3B\n      4BF3713DF0BC9232691C01F24931192E4EE40BAE97B1C2B86D38EE9B17AF8588\n      26CA6ED4DB63D97CC1A442845C2493B921DBCD04B96C4AD1FCD6DA3B8BCB3B21\n      B3B2454C49D4ABC36EF63082526D7A9E41A028B61066816B964A0307F6EF3F78\n      60EFA9D3C7C727CAE35343C8D477E25AF34831647216D7288D506737256DEC21\n      92A6C09E9056282461A36DFCF153E9815CE613C7ABB86275233F22445A4297C0\n      040BC06C29EBB5AD44749C8C1F6373CDEB3ED75DB9D1307C1EA788435AD0071D\n      A1492110ADD4DB9D7BA0144C4536EB849B43E7CF564E3F34448AEB4239A62C35\n      D63BAF3CB3958473296275BE7E23B6EB71D4D2FD63908E4C8229D62D664A83F6\n      BE5D8D16A142DA7191FCC8D6BB7FA0D72734FA6607F5853BFAAD6852C65A734A\n      1ADA054D8F2B033F4C918875EBA92A513463A17DCA9E2459E1B1838FCA7B7E26\n      2F540B4733CD79E3856F3FF3BE0F1F70A60A69C670A4D1BE923CF79757F68E95\n      8F1C9F60683D152DA232483990D2A16C55D6CC1B97B7EEB87B0A917665D55A5E\n      6B9C3C354E658D40CCA540EEB26FBC723DC0A54347268D4037C928C8F3C88A1B\n      EDA4AD903178E146E5F26EBB4A9D754ED61354C728357583AC9E9F067C0295DC\n      4E4B9CCE91789FA5060CB738E01CBEDDDEFB401ECD3991DDB69DECD57FAABCF2\n      95D5E2C0D872C42F4510C502F2A7569DEBCFD2D8507B19EF60694B34889C2977\n      7396ED31587CE6E767EFF9D22965A54439BAB11D71C2FBEA3C944B80F911C0D4\n      8EF04994A4166BBBB173F6BF5DBEF0CDD433FDF570BE02E5360E9A2AA1761001\n      2BE211148A1C1436F8DC0082D238A0649C5A33A69D47DCA1A89CF586070AB556\n      7BBB5A65FA24D4D0C24112B9C0AC0D3E51704773A60FD90AF08CA5071A89A915\n      C252D2858DEAD93E15416B4BEE6C74A1EE62CB6488757B51171E4F98A39EE78A\n      AA3BEE141FBEEBAE5FFF2AFEDF678730EA1474212C17523C3A95DEF533E36CBA\n      1609951393CDB7D8D37FF726EE166F08BC14B6A18428025BDE043A921A12320A\n      603B0D060C7D798838302635662507909A30F23D5E3FFCB07DFF63C3326A99B1\n      ADF411326C5AA57B6DBA16061EA5D0EA35EFECD2F67B7FE7C191D3F9CD67EA5F\n      FB9DEFEF86F886675D0EC94A152813BCEB5BB3CD4437CBF425716FF9A7E89BC1\n      BEE076DF998248EC1A2AA406946F09CCFA845F9A50AA984BDAB2FAD18FBF77ED\n      D2E6F2C51D43B99B1C2DA7ED5DA824B7C800300C803F49A207F00317713688AC\n      319AD96BD8C8EE94F6C4271F1894AA4590A50029E9634AAA3B86E12369A1A8AC\n      61248C6BC8A85B19018526854B6FD677ABB0C8E64E1A37106E323D7AAC127869\n      382238965051F5C1833E11E85FC5245A92CD90FD99085DE6FB66C2A9E0E2D6B1\n      1D50A63E90D5974FBC3F557FCB7C4341BE87DA8A4D6D7781203E62037092E975\n      E3A3193A4D659152DF760A93C6635FDA67CDEEC0F7D9A48C0C57DA4962412137\n      9C4EF9D53FBF74E53BBBB4935F576D7877658B2823FAD41F7E913C34151ADC84\n      65D2F3960E9186912EF3E49C6EB9875CA515926873A173F3BB4BC09637CFEFF4\n      42B42BD4521A2DF53A912209BC17EA65B10D44A444CD926E476F8C3F3EB4FFF3\n      FB2514BFEBFF1F4F6F1A6DE9759607EEF19BCF78CF9D87BA43CD2A55A94A2A95\n      465BB66CE3916634100289437A258B4E62C001BA21B40349562F92D064EEAC86\n      054E3A6E020E84366063CB9235597395AA4A55AAF9CEF3B967FEE66F0FFDEE53\n      22F21F5925DD7BCEF7EDFD3ECFB3F7FB3E8F78E1DF7E6B69F6E8DC34F03FD58B\n      B5EDDA9CF09DB556BFDF3B7966019652E7A01786EDF913731B7B032439E9E677\n      EEB49EF9D94FEA67EC82772807E1E81A06A60382AAC8B46DC032847F6011C755\n      A988FA7D0036AB5C42CCD629E2FEE4F6EDEE6FFD9FFFF5D5D76F6F6D0FF6D214\n      0D0752B549FC50C30C02ED32BBE4DBF743312C8B32461F6036F75DE6D9519135\n      BB9D5698B4D254D936F5ED12216727670EDB1E6D76F6D481D3075DE021D7B726\n      461287AE6FAEB1242F09DCC3F2B9FDF6E967CF7CFCD4853FF9D33FA7423CF5F0\n      A377B6D68299F150A6FBBBCD23F3475EFFDE5B1FFBD8B33B3BFB7FF2ADE74746\n      FC2C2CE22CB75D3657293D58AECDB9E5EE60F0DECE3A0EDC09AFE4874980756D\n      BC9C60E4D6A76C9BC5B4E8A36CBFD7DF58DEAA078DF64E676A720ACB1CC85198\n      76ABD5EA6C794AD93CC4E4D6CEC19BB7EF0E0813C0F0CCE44081F2DC36054E41\n      AD912C6014CFCE4C2860E851DF44DE67198049B5569A9E193B72F4D0C4646D7E\n      61666AA426B2D01FE1C7CFCD976B364ADBCA1139546D15033F81BD2DA176562A\n      F673CBEF3CFFF5239F7DA4FCF05C2B6DE35456A080C5004089141137EDA74080\n      55089A203E68E88ADA9ADAFBD6467BFBC0768241682B0D3C1036724DE152AC77\n      671E2ACD3F0208BBA1A2C3AF3F7F70F45CA33CD166D41932F0E8FDB7BBF72E56\n      88A886456B5DA1BD2CDD43AAA510A80CD3F56938E83007521B2F6436CCF62CEE\n      2BC2FBBE6A1FA4BB91FB06027AB88CEE8717C64E6EE5B6258CBBAA6612CA4AAA\n      74989BA1C80AD3C7BCE038B516A8458A8989C7EF7CFF9766010D4831A653F5F2\n      375F9CAC1E3AF6A193215F762B35B43FFECAEFBF25F6D3673EF22071760A1D8B\n      CCA166002702A8DE5BC3ABF7762F3CBEA8557F670DAF6F0E4E3F346EE916319E\n      7F9E22F49DD7EFEAB072F6E1236E631FDB20F5CAAC5069D40B0F0A4B36967792\n      D757769B967B50F0AD5437B18E6D28C582169243A5425404B812E143AA7FD4CE\n      C72DD0FEC1C9F3FE91672A684E47A5D4F12AEBDF1C7CFBB72E05D6EC468EAE24\n      F9EDDC3016871166295DE4656D69460F24BCBB6296579682ADA57C4965E1F99F\n      3DF2F8171F2E50CC906B5C94A06E49337FAA2954674D73AF50FBC89185B1F619\n      D8482617D97FF9D5D7D40E6898742F17CB11DDC342DA2593F9AD4D83E0D01CC6\n      34399ABEDA3CAB6372C8B62738AD73E65159B2F0C4E858B3D9DA3E6809DB8D11\n      07582B594E95E17147CDD6ECB132BCA150030960C6638438B0F581BA0963FF4C\n      2DACDD5EAB68AEF7458C5DDB4B8A7427E1512AC65D36820B5462F2C1F9CFFF87\n      17F1CF2E8E21D4AFDA7CC19DAC65B83ADABDF0D3E3EC81148A7709CDF7AFEBE7\n      BEF2A6EA56D7B07D2FEA6ECB44626EC1EF44343166CCC34C20B3C08CC51AC8C5\n      8CA369D67D00D3293DA982F889BFEE2C9CCA7507B3A8A454A468960D80457012\n      026B8052EEDC794F5F6F0D3EF42B4F8D9FAB1D3CDFFDDA3FFAD6EE00DDF69D6B\n      0084FB036C2E698BFBF5DFCCFAE9FB2E482651DACC100EAF27870DDF5CB29285\n      420EF251A44B95E00CAD2E2017F92D76A4F8C24FFEC4ABBFFB527315B836D988\n      C86AD66F99467966C60187CA0204B539F5701848C3395E9EB7CA0BD815F6CEFC\n      99FCD8C36581407021AA04BC652A3D09DF1045A6E72CAD99080E000BD3A91ADA\n      18B5D7F1CD7733C246FA34DFC8C28D9EC86143DA194D81C40308A09E96B9D250\n      F719B16406D5C88C700B00617304294DB032802202E50868FB01166A1390614C\n      B7CDA99FB9B5916650CABC64D3196E196F59E3AD90C33BD1764992A38E3DA393\n      095E541D2BD6FC537F77ECC8A7AD5CF6392E61C78362900DFD331D545E7B6EE3\n      DBBF7DD51A9CDC555B0E9325240F2D8C3CFB4FFF863CE94696720A3D9C2CB7A8\n      B649B692256FD8821B2034074832DE92ABCFED4CB627B6DEDD061601E8B489F2\n      7BD1208662413C3B4B4A793112D446CA5ED58C150DCA87BD0BFFE021BCD4B748\n      E5CEEFBFD77F337AF0A467557437250229075B4094EFDDD9593A3E5BA9EB3CEE\n      ADAD6C2C9E3C1369B297AE4F58C1E64B45FDE1D9F1BF7F24AB74B00E28F37300\n      2D5DB274C574081A826486FE90843250CAFBE295E75FEF77E26EABBFB7D7212C\n      40BC76E9DACA1BEFDC3EE8CBC4D8AC9B55048BC766CC1C4A4B6171665BE67EC5\n      FC13A4D22C1DB751BD54F210ABF9A54A50EDC7C9EE20EC1705E6D4E1C4A3F8C4\n      EC944F6935DC990C497D5F08455A234EBFCC5C89EC660F88ED8A55BC2B3A4550\n      FEC4C73EBECBAB7FFE95FFFCE8E46C7566760B2599B9D2D595D2F47BEFBCFBA3\n      9FF9D46B6F5E7AE7FAAD02EA5F9A81AA3A5AAB369438BD340FAFFDCEF23DD729\n      8FF0A02A098FC3B9B1AA9271A66511D445236812D52BB2E57B2B53A551BB9F99\n      8E705D4440EB48512EF9E3F5462C5846C5B5B58D8BCBDB39F304B712110B91BB\n      961970326DD6A83017D466765EDA36290776A5E40D6F3C4007F170100E933BCD\n      BCAFE7711B3B254F9E3937FB0F7FF5EF4E9D5A4CE20362012BEA70D5C2220232\n      16533FF2EB23517FF7DBAFC9F5D6DC879F2826791FB54A3A67ED36313681F07B\n      407B2369B2DA3349D28370509713CE567DF7F9B5FD5D9910AE4962E2C9441DCB\n      8090988E27473E429DDA5E914EDD7A0FF67CBE74DCA136FC8C085BBDACE75DFB\n      0E6DBEEF20CC77ADC1AE10DB486D1645D704A159CA14A5A121A592C02841D302\n      1666EC033948EF3B359A2396FB391564786F7CBFD8E09ED775C28A0F328616C6\n      3D80A24C5999196AEA3B44CE73E7A8B68EDABC544CB213773EFC372726672A58\n      E5509B7637D8EDD7F72E7C64894E6DE0FA28E9CE6F3CB772EDF91BE7CECF8DCD\n      9AF9E13CB12DCB916A00CB6D73B9E8B59393A7C680246FAD8AD5D5FE9973130E\n      6DEAC291DA9744DDBCBCDDD9B2CE3F7AC21BDF07854C558D1402C9A8BB979141\n      D08EECE76F2E372DAF95B176C13644DEE68564052F9403D58FF2CCD1FE001D65\n      F1293FAF63C7F7DDE38F944F3C5B4387645C11B65F4EDFB2FEF25FBCD13E7037\n      057E3BCDAE17B9061D4A894595A3E418711463DB3A87BF26897FBABCB3541C96\n      8901C247BF782EC73116D6FD1C576AE2D9B51A5EA61055C67450888E31D2B114\n      CE12D21DBDF47FDFB9F6C7B7AD8C000DB89DE61B0477E00D111BA8589EC6A0B6\n      8DBF3DA158684B2A17A93A414B41300B4A51265A444BD35325DBBBB7BE09383A\n      A0768E6DF83D2336ABCA68DA97B3A31E67A2C039942B73366B99D3486A6B62EB\n      4885CCB53C5A1D6CAAEE4AAA42C402BD990507493242B349501A8C6FD6F9CF7D\n      F37DFCF71603E084556A1D2E976A4ABA7EF8C88F4F078F8898A415BA14BE4F5F\n      FC9D37D4416DD5CFD606E956A20B6213061A18D428103B6D5A59F0D0A3019699\n      648EA4D3567789AA8A2E5516E8335FA8DB956DD67778144814E6241711750B46\n      12941BA6E6BDF77AB7ADE9D3BFFC74E9C1A0FF4EF207BFFAEDED5DB5E6D8D762\n      71A7D935178F202487D12A436430CBD50C47007F606C982B685A492D3A74F971\n      B153905A912CD6F549141C4DEB1DBE76EC67A61F3A7DF6AD7FF2B6ECF19DA0D5\n      EA5556F24E8F1B0A48CD052F22CC0C5F40F5307EA148020A2EDAA559349197EE\n      2D3C2E0E1D712DE4247DD82B20FD4086D95830A13369D27A3C946973D96B49CC\n      10CEBC3B97C3CE0E47B6DF46FDD5B0BD1DE6C80A606BE334A184498A13357C62\n      D8A4C49AF61F6D0CC5A5997132F61699C97334F11AF035815E170AFE05E3353A\n      143064E824608AF8301DC05C6298011A651A8F04503FA4B9CEE76D679138D30C\n      7974E0C14648468F7C4A3EF5B7E6306B13C74336373D3856496AC7E264F78DD5\n      3FFFF2C55AF3C9F5D26A2D26A0798F7DDF91F3BFFAC3AAA10D59D5D2363CC729\n      A885F235D67DDB9C0444A939D96624DE172B7FB936B237BA79B99D653C267C4B\n      C47B0268BFCEB4338853A174D9B3A64A6486DA5EAEA99B3EF2B78FD63FEDA75C\n      D39BC1957FF7EE7C55D526B5E64EB72B61EF96CBA5D6C6BEC5E9C8A28D593F5A\n      CD5136669F185B0BAFCDC94AFC3EDF47BD13FFF03179926505B6AC0A7012AD6C\n      0BD7307533243033EE595088180F5484DF7AE9F2C6ADFDB8A957565AEFDC5CBB\n      B9D73E4872457D78681E4F3177409D5B8E53E65C8661D8EB8370A87825E45899\n      AD3DA2EC5E143BEE2CF62BC6C43E67A3762508CAB03DA9BB2F92F4607749B353\n      338752106A9D7BF3C85E082D1A926689EF7A1949E229ED8592DD4069CB966D99\n      B1B171D729BDBF7A6B5B45D3A71FEA0FE20950AB9CDFDDDD6B35F73EF7F4875F\n      FDEE9B779BDDD5688080262074666C7234D7E38DDADEA077B0D33C5D9F1A37B4\n      A93F510D0E797E7F79CDAF54F747FC83527EC08AB55B6B8D3838DA980766BD1F\n      1E00BA45B02D2AEE48AD02047233B56EADDEDCE9F404E2B6ED7593AC25536339\n      62B334CA601DE6A830169C85AAD9663428C38539E3A408344BE09731B26CCD3C\n      A0F1323316B1DDDD9FFEDB9FFBA99FF981EAA4ADADC2B218968214091603A4FB\n      85EE0BAE629117A08DBBB8FDB557655E8C3EFB603EC98B689F2603E0E8A6B9AE\n      90441292499CE6E6240C7E46A2BCBCC6F6F9CDEFDEEB6F4B8FD68AE283290807\n      01FBEA1F7ABA549A07A6A13BABA2B3D93B7AE630720A2869CC4E8082EEDE11EF\n      7F570EF682D45207526C6BBC12CB032C239A1746CD39A09F41FE33E3160BDFCC\n      8C4B1AB31CA5869D33E64440DE371E35B04887B783E668B4EBA54EE63919A750\n      DC696AAEDD8CE2C0A05FA82EEA5A2F527634702AA241BCB5731F1B39F599F9CC\n      5A3692A8B7F8E69FDC3A7DD41FB9C0D2468392D9F4BD1B6FFCDE46AD649D3B3F\n      A6C8A080476EBB89EC5996B5762BC459B0303F4249B6B116AEACED9F7B78C135\n      E9CE08D62B60F7E69D68F36E7CEEFC4269BAAD788A74850C4FE192839CAECB54\n      D59E5BD9DCCA59B7E0EB85BA23921E960EA3368815CD2C6EA72CB512BAE414A0\n      081BD2A9FBCED90BDEFC4703759877BDCC67B6B3D578EEDFBDB979C5DF66E9DB\n      517835CC63E4B89CBAC6D01703CF1152E4B04234ABF0CAC3CEF652318D8BC185\n      5F387DE6EF9E116A60493EF438A1C4D81618DD0D129A250CD9456675304D516A\n      910C7E1210C3F87BFFEC0DF11EC97D720F479B836005BE2437231446AC9B0E41\n      50DD188A3DA3C61C94897894CB19DFAE61C055EE137EECD04C1477D7F6DA0365\n      C7C82A242C15E44B39EEB0F1808CD600FF7A40EBB0E708D3EAAB19C7DC2339CF\n      8CF52A81FAE6152DB1BBBC4F223BA7B55E0230AD4B8CC6446D55DC5FFCD67BF8\n      1F2C5126C72AC49EB6B331AE7D1F3FFCC3872A17D2010B4B6836BDC3DEFE836B\n      627DF4A6BBB53D50DB913500FECEA020A726C9DDE4D3DCB7F63317B580098D18\n      CF3AE9BC2FE1FFCC9E2D3FF9E36342AF5B11E3A90772D1D4AC8CB3189154E704\n      09EDBDF3C2A6B0BCA77FF923EE493EB821FFE8D75FDC5C55DBCCBADCEBDFE90D\n      10089D34FB2BC36D6CA2C484A2CC58E58228547FE53E06B8E688BC5F0BFCC23B\n      C2F4523D398AFCF94E351BDD7FE6FF7838EEA6D7FFD9AA9557972BCB61677C45\n      B4FBA0F80925F27E7E99399AA4E66AA2703999B3DC79DB9B51F3D9D8BDA31FA5\n      6363F05E894A79AECC501A36D3F7C6F64C004649C612604CA176724282BD357A\n      F76A040420464517C71B71BB0B3FD38CD8DB52C496E955A3A6877C78C24AA805\n      DF2A93C3433D6C7A7FCD48A034D038BC6D45B936FEC6A6817BA8B687798B262A\n      CEB888619CE3C2A49F989840F8779C02395A6715D43FC6E9111A8C71EE954100\n      40212CD5CFC79FFCE229A7DAD58E999BD4B0AF59299196E3A3F06EF3DBBF7AC9\n      B97AEA4663E5685403BD3EF9F98527BEF439E9B1089E09293C33B8E3C50E6CFC\n      75FFE04A4CA437C8604923D7EEED26F7BE7167AC35BD7E25CC323BD5782FEDF7\n      80ED6AC515DFC9D4AE86D29BCD58EAB05D99C435CEA291B3C5B1BF734C349093\n      4D6E7DABD37EE9ADC38BBEEBB3240CDA29AA8C5B59ABD5DE3E183D5E774714D9\n      713A6BC83E53EBAB9D910347C7F6DD9DD5E9CF1C697CEE48EA2A93B5897D4C39\n      946BA402E30E621B59EC620BAA1C963C8DF5D6ADBD5B6FADBCF1F2B5AB779BEF\n      ACB59B001196078FBB62470E71FA5264547984068574340D980BACE840A65B3A\n      1AAB78473D7F3729AACC1FB16C4BC43649A7993D872A416524ABF2A0088FF5F3\n      B1420D38AEF3B420A014500D5416B35296B13CB40166EDEA9E06C993028CECA2\n      22DFC73B63C1AB2322996DF008BB090E461BD7B6EF59161F2D57DE78EBD25E2F\n      CA1235E5FA80D547E6E6AACC1A743ABB3B5B8B95FAE3D58972F3609CAA995A99\n      2315853DBB566F5BCE7AD15D35429F9D44953AFC62603645D40CA376E074A746\n      DA4AF75A832B7BED6ED20FEA654679D28FE35CF68158964ACD5607DE231F9ED1\n      4B862683928DAD4198B4B2589891240042E3998B040F4035B876220711CE7EE3\n      577EE8AFFD8DCF0F7BDB434CB32C4D3C3B303307B0CE4557890EE72196BD03A6\n      C7B4ABDF6F6D3DFF3D7F71B4FED4D144863C4D9548418FBAC0A712D065C61A5B\n      A6E9F0F88398401B2099ABE9FA8B6DBD5B91C88BED3016031F977391D61F0866\n      1E0D88DF927BC9C6D5C1FCF153A9DBB77CF8A480617D6E591B57F0FB6F4409FC\n      3788EC66782B23EB69AF4BA39CC35BF5092EC1B7A443771166AE70CC1D83193D\n      3203E06478EEF2818FF17D89388C65137D8B5A66CAED7ED00D40B71CCE109B02\n      0B7BAE248B43365B089C515272B2EEFC51F6E8CF1C8E46EF9A23CFEEECE66B07\n      A8B7B7F4B1A3E95C593916DBB97BF977F3D65AEBD9674ED941AF5089C05C0009\n      61626739B58AC6E46819A1646B3BDCDCDE3B7BFA08D719369D0B263564F34EB6\n      79A775FAE1A9DA5C281D2818255250A0D40A58C72DE09DD5EF6E1DDCEBA89EB0\n      EE68F95EDE8B941AB1CB3E1043E0AB50483C450B67D612B3B0B0B537E93B171E\n      B7A73E11E8234EC7CA02D837BDB1E77FE77B5B2F349ADEE0461EDDECEBAE7091\n      4D6C0741B18AA3048A93E7824000EA5D7EC26B1E4E46023B7DE6D73FB4F0E34B\n      59D60E0CC80029E54472D3C74854C66C3BD4C8C923B70BCCCA8BAA38837DB1CF\n      5171EF2B2BABFFEF5E9EF33594EC76AD7BB848A0B4A8E1592621540833346A06\n      565C8ACD646A85C635174D5336C12BCCEC5C323F5DDB3F6835FB00B77E07368C\n      1401F5465DBBCCF2F19AAA95C38273653363C36D8C9B30B559C164015501E7A0\n      866D8A3BBBAD64D9E977534E46F284A4452A3CDC1E19F9F96F5CC43FB768133D\n      52E57CCACEA7B8677171F45967E6A356646B005A71A0AE7CEDF6DEC5C6AEBBBF\n      1BE3CD84B731BCA8DC7029C481F89B730E637BC229285B8247120DE56FA90A4C\n      2F7CF02353A73E5ECAF5A6052B34B1A1EC1744E2DCA2B126892A1820817FE9BB\n      1B39F73FFC4BCF38C769745B0110AEDECA9AAEFF5E9CDD19844671996E51D30B\n      68D49B311735F847877FFD8F60696A72B1F3B0E494B4732AB08F968B05614FC6\n      6EE361EB13FFFCD9D7BEFEF2EA7F6C56ADF17BF672B353DF927D60A7C00E2D33\n      CE60E4978D313707AEC065E9BCE34F537B868E91B99D939FF0B8D5C303E0819E\n      31D297C238706A20D0C69A1F83B41741AADACC1722F76F821CDC26965D8E94DC\n      CFD3AD6C10E37C7802C41416B66B4CBC52A031A6D3D858031B1404F8028D6894\n      9D61A6C354600376CA9C311B573933CC642E39F07D4B1D3330A287B489DC37DA\n      198E8E9BC82513F85A25F112C52779A5A2C4EC21BF54675B5763BED0FD812F3D\n      1CCC27DA5266F00EB08378C06FB98750A778FECB97D3E7A736A777E7065E2AFA\n      87BF70E6ECDFFF0CD48C183E10C95D137B609BB00DB9E676AEC61250B1C0458A\n      383BD8186C7D7B63EC606AFB561A2650DB515BA4A1498E42322ADA52761801B4\n      0EB458F4EB93A45C929970D7CFFDD452ED137340D5C2A6FDDEBF7AEE70AD3232\n      616721ED74F2A06E957C7EE3DDDB8DE989C67405E568677DDF9DF17CDFCBB673\n      BF52BF71F5B63DEB1DFB3B8F89592EA46D235F58B8A0DCCE7D9A0293C88B3A7C\n      EEC202DD665C7A5C1329D2D3B7DFBAF38D3F7FF5CFBF7BED9D9528A266E28260\n      514D1595590454C2A60DB73CE197C74AD538023A29BA22A21A8DD901A07FD344\n      079213DA3B9BF2632999D45639B052BB4865BF4A8B0AD22E37DDB86B2E494A6E\n      058470181178B80A5B119050443C5BB7064488C48E457FB6D3187FA994BE5FE7\n      89EDC68374647272737767BC5ADDDED8B8B2B17AD0191C76C7C72DDB35BEDE15\n      814496742A51EFD985F92396EBECB4C62465799E397956C1DC0676E8F7088F7D\n      0F449D1F87BE543D280202D8375EF7D09B25F2569C6FB6932DDE670EC8D1D220\n      4A1AB59195BB6B5629E8665132885CA94A463FDB6EA33A82FCD576EB20C9923C\n      5379715F1939043BF0790237816FC0C53FFE5F7FFEAFFDFCA749123918C4670A\n      8A4B07D6C0C4441BB75E2E128E43AD07B98EAC7C3B03AD9EB9E4CACEFA9B17A7\n      3F74D439DC509D7D414442F2522848480CEDD44227B012CDFC8F8A805AC30EA8\n      E697A3E56FEFB0BC145331A0A9431D01A050CE1EFC54D91BEFA8BE7BE3A5B831\n      353572222EE83ECE6D55D85EA95CF4E8DAB5DED5CB830201A9621D24B7D3783B\n      CB7B263B0A1B9AAC30A81A1B33330E0995E97ED2D2F094BF18869B0E47BF8619\n      8568E8B208CFD356E68E69E81C06347998DB464C6F1D140059F8329F6368CEB3\n      27B80EA45F6B144FFD8323646A13F8B58A3DD26197BE7EF1D45317F8239EF007\n      4128EFFD7171E93B573FF6F4D9DA84CC54CF14301B673A5FBFDBADE0A989B1B2\n      42F1FA6A74D0EB9C7EE010CE136AF82EE89860EB6EBE71B775FAA1A9DA7C2CED\n      1C2802C94DAE004B11B9398873FFD58DCECDA609F75A23E4268A3B99F04C2F00\n      E5261F552B4FB3C299C1F9024EC6895B75F9D947DD639F1B55F3AAC7B200114B\n      CD7CEFAB6F6E7CCDEBF9E906D66B11EA155017A1B864C0CB0169A525A90D85DA\n      18B53C8E9B87B391F106FDE4BFF854FDE3F524EB7BC25CAC0ACA19F0842110C2\n      96E4B082682C4D94A1E10FD47883C4C6107C03FDD93FFA8BF476A917D32639D8\n      C678204964CCEF88E97419B66C48D3BD4180DE5945E1174985CA59DF9FB2031F\n      5EC5A073F2C821C4F4CACE4E4ABD4EA2CDDDA252759B96EDA2E28AA951CE7D2B\n      93B1E3B261C21642163C2B2A188818E13B265DCA74A924A5DD9583FE9EE42AE0\n      0A473A6F96EA5FFACE25FCA523252D7C732169C9434E9DCA74FC7476FA872707\n      6E613BBE95ABEBFF7DF5F60B35E5C89D54AD667A5BC403040494E2A1E1768EA5\n      307E469699DDA1C50C21A3881CF23921CD0B9F5B9C39C3306993B8602913C6A9\n      C97819811CA5A008296820EF9D97369453FAD02F7ED43E8CA27BF2BFFFE31757\n      6EE6BBCCBDADE4DD24DBEBF5BDA1D3F4D0650C9E2BE19C0B13D56DFEBA1F273D\n      CC234796464050CB849E09ACE31E9E93362CD6E39F9E3AF7B34F7CED37BFAA5F\n      B203565FB3B7B606E5DD621072232BCDF1B6B1C3C13EB7801D8B3C09185A7082\n      71CD471D36F9085E788A89E2804480D88E313B2D24C9A0D2134029A3E3A036C1\n      2ED05D45F27EC75A7B5FC82C488A0C96F956941F8824A7A939D8CCEC44A40084\n      1A8A96B98A6699500948696EC1CFC8813501995068D8136A8627CCC23245C220\n      9DB9FB3283CCEA7EF886B1121E468FEA0FDABDE5B0C9C62E4009E9AC8EA2A38C\n      1EA3415989F9C5D2C2D1D16B6FEDF5D1EE0FFEDCF9D1A72DCC42D820C24C3C1A\n      B708C57356F0977FF366FFEBB5DDB1BD7A53092B3DFF8BDFB7F0138F19BB3164\n      339A73C03CCD608516C5AAD5793757CC49CCFD14B69DFE7AD27BA919ECD697AF\n      B463E97415C8A92425802C2C1DA43D95241CC5A09E2519F5CA13D899060D8F3A\n      638FD2635F3CAFCADD98EADDAF769A6FAD3C786A860AD5EF26A9882727465A3B\n      3D58B16387A633DA1FA47BA08DC746169A3BDD60ACB4FF7E3B0FE3433F73863F\n      5D4F52EAE08A7464C8A427472C04043D35114D40698807A428C951BB190EB6C3\n      A4295E79E5F273DFBB7EF1E6462B54458E911594F3CC4369465062D6806D17B0\n      03E1118AB9B1DAB415589D0C0F54D9B749400A198E497DC16D9CA3CE24946492\n      A940EF7B34B65889F020974054B72C8682B21B46DDA8B3E1B136E23E944D1C57\n      037FBC701BB92EACB0BC97CB44DFB3AD6B557F63A41295FC182B29B31AB7B697\n      D7AFDC596EC6E8D8E107741E4FA46231A2633E0F7C359947C73429539EBA7E93\n      E10391367C7BA4177A69AE2A4E6C0CC7B55F0066AACCF673CADD4C06850E7576\n      55A6EF5B7CD7B5DE89F605C08D24E591B1D58DADCA48FDA0DB0A93A406EC1884\n      BDE5AAC0850A31D8EBACF57BA1B9A986A2077B02FEA302E4B2070ACA4609C97E\n      EC079EFC975FFE15674A9A61891CA86F6E7C347C07382AA780BE39CA23C38A41\n      8491CC16F7A4CC23EC04BADCFECE45B1BE39F9CC03D938CAF27E4952D58D4C1F\n      26ACEF6C606E24243146DE056C819C12071FB8FB7FB91E2FEB02E89A4D615530\n      528EF3C1FC8574F631AE12EFDEEBB01AD5898FB9A1B86E8B11528CE65AD8F0FE\n      42FAC62BFBEB2B05A58DB0C85A4A6E446A57A01E4905BC60CC8025C057A380E1\n      94DDEF87318313D89C84DEBF841F9691A1D7FAD0333976CCEC3D93261F5B5221\n      B11C5E2D5283D75A060608F5ACEDCC55623B1EE75EFAF84F9646CFB2DC02B69A\n      3A92BFF5476B5EF9F0D2FF3442A79B5658EBBE895EFDC3374F4E2DCD9DF05274\n      6019877F0DBCE5CECDBD3167726A34807778FB560815E4E489719426D8C42203\n      7A97B6EEA51B773A67CE4E0310160E10D312D450C941AA620C40183A6FEF8537\n      B6A37661AF607457170759420AED61EE1AF749046496276C4E8B234C4E790114\n      A1071EF6CEFCE0B49E89FB24F691C3DD994BDFBC78E7B74918E4FB4020329A68\n      07D8107C12690C9431282A49B35C149896CEA1DE92AC8D4D589FF8CD4F584F78\n      48E5A6F1CEF8DB33A6D8D0F9C3041D99DB1D141ABA01A58941C58B786E2C2CB1\n      C5AEFC974BEFFEABED5A3ED32B2FEFA44533252D4C2366178569C107FE0F3F46\n      68339E1A08E4246985D029C799F49CB2C57896825039B4307A103597F7DA051E\n      95BA92447D9B24F51202A1315671471A1ED231368517F09B21DB428E5D986A2A\n      2C8A2C2C08A7A965AB1E5A7BAF29DBB4CA8254C83DB7F60B2F5EC6BF74B82634\n      B3B1AA23B9E8D72A1CFB53D1991F5942E349CEBA1527D87CB578E7CF8415DA7B\n      99B893276B32EA6131CC0702DD804C370BB2A4B498141E4B966C3CC92A35A2DD\n      F2CE473E7FB4B66829D92751CC042EA46546010B4133C2539C139D28F7E2CBEB\n      D8AB3DF5A567F96291ADC93FF9F2F33BB7D936B6AFC4837542773A3D470DDD1F\n      A889C13533627931BC8FC4438D64581C679C3320584C384E8DCB073D7C8ADBB3\n      DA4DF1DEA77FE1E991C717FF9F7FF87BD5E571A4D81E6F2F6741B3E887469511\n      8B0EEFDF342AD946F5E82CA971B2E005A3F03468EFCCE7A6461E8845D676B252\n      363017B9B03C8071E3C25018D847C667567998245AE7071B64F32EAC02A79376\n      5A45B197B28802191A0C2DD9E1351B5B2CF3F90DE0D1382FA234D3CC920CD633\n      01D56BD4A13947353E99E68602DFD782E65C3437B3F406F1865FF67EA79BFEAB\n      8046733C2A342F4CC388A8E3F801C759D2F6089653B3FCECE3472EBEBEB2B6BE\n      F9F44F9D3CFD53E3C8ED69ED2962AE45B001427807DE6BBF7567FFAB56B7D2AA\n      858A8EA2277EEDFBEBCF3E989BA84633610194C8E82A8E55B12ABBEFC22A6269\n      6AB43077BBB7C3FE8B4DB6E6EEACA409F13B126DE5837E96D8C6D3B29AA23852\n      F015E16B58F06CEB044F11CF15A268B49EF8E299E0A3419F6FF3CB33AFFCFB57\n      17CAFED1A5E95EBFBDBBBD3F3136EE59DEF6727B746E41D422C1F7B3BDFEE4C8\n      89DDB407ECB231185BBFBEE57DB231F9D30F80BCF56545F822061A664C0ACBED\n      5EAF58CFEB23A3C4F6F7773B6F5DBCF9E62BD76FBDB779F3767BA0516C5A6318\n      CD14ACA526773C8010917DE028A3A84358AED260C41AE3EC240A1672B78AEC51\n      6C4FD41D2ABA54C4A37E5067A4A4239AF7A5E7EE56ABD7E3CC2BE892706768DC\n      057A4F6C2A8B6531782E0BDF6A87E5FA48E05932CBE64869D1A9942AD651B555\n      2F148E592F256BB6B5B53076D74709F057EAEEACEEBD77E34EB53E5673AA7EAB\n      B9901527A9FD80E77A38E536144B1D296BCDF1DF24D9B5F6CEC35EEDB3BA3AA1\n      8B5E2347C84C7C29E516A9C305A32241D82809938992EB0489D8D21BA5DA5A1A\n      DF1CF4767390F3C1EAEE6E69A4323EDAA012C7A9E8153AB59DF5E6413B6EF613\n      E3646923E6502B2545A281559A4C4285E447BEEFC2BFFAAD9F9F9B1DCFB2356E\n      32508C7FA134CDDB6C18783BEC414505E1B02113A9010A5788F167CADA184DB4\n      EDDED7BE27591A7CFF490180DEC9813E0207F78CDB47CF347402A3860AA20A20\n      8BA061ECC82A6E64DB2FEE01BF8F306BC90EA39E86DA3CBA7FFAC76614579DDB\n      C1CA8DEDD3CF567367DD2E3C266AA67D9A6A2A9DFD5DF6E6732BC5A02CB4D54D\n      F3A6A2AB49BE8F93D8B80933AA80002A8A448E5C8D86F479E8D7783F80820CA7\n      920C04DEF733542862B971AB3039E74850D3623C1C3324CAF4698B8A16F35C1F\n      729C31675075172B63CC5DBCF7D0678E694B4478DBD3B8FFDED8FB5706177E72\n      862DB4493E81B7E9EB5FBD9A2C17E79F3D8CFDA6576078C4C2B53677BA23B45A\n      F1B524E4BDAB91EDA2C38B659C9B96DD14DE8755DA5ECE366EB7CF9C9BAD1ECA\n      8403A5CF876A0BE86292326EF6D281FD7E4B5CDF0A9BB9753B2BEEE8A2996736\n      E615CBE3669E2017AEB2326B5EA3530E9EF06D8CB2C593FE851F3D440E037901\n      1A6953B771E5EDABB7FE77D4E7E99E2CF6A136732B1EFAF060E4E5F0E4CCDC50\n      A1B28C2167C98A17707D6CCEFED03FF928798851F85F62DC0DCD52904320840A\n      0DA219988E023C6648DBC21EE47460672E9656CA7A4EE4BFF0CB9792D725AEB6\n      3AB95C1F14AB0A75810B01F53607619984878BB5C79CB2B4BC4C95286F587CC4\n      013A884A405692787AA6541DA35BADFE5EDBCEE03DE8A2C85B1E07C8E31EA7D3\n      93D5911ACEF303C5403432C00666FA92CCB537E5DA643A5AC47C9AC2C783E0E0\n      4E37DD0D09B5F7BDD12F7EFB32FEE5A5915C660CD351CB39E4D935509B2C3BF9\n      B143D31F26A9BB6CE37A786FE2B9FF7A23B837D641C51D355856697F98106482\n      CB4D4C19809A23000C5556E1D9A295CF7AD396C80F1D8B9EFAC1195EC15916B3\n      7CC04CB0BA2724C066668EC70D10A24839EFBEB24EBDFA535FFA045E00E4D27F\n      FAE5E7EFBE990C82C6A5A8BF8CF07E1859C3F445D044F7D397CC61B2499C3696\n      486696DD04549BE825407FCAF8B82F8FB1F42CAED6351193CD9FFE173F9A2AF2\n      87BFFC27D583316053FBA27B4BBB912E622C8676E1D4B80120ED526A9B11D46C\n      DCB517BCD28886EABF76E1870E978E8432EFF32410A1B96F9545815313A4A48C\n      9457A6DF513A940A91E89D6579B045A34C85386E29DD2E9C8CB3B4E8689D58DA\n      0192330C431CC6C1806632EE21A08B99A0AC3040A8CC688639E404881D1A3498\n      14382486778285FAAB96EEA1ABCEFDDE6E3CDCB06AE88D521817102825F9042D\n      4EDACE61EDD449313BCF1F7DE6F8BB97EEDDBEB4BFF891C98FFED21154ED006C\n      2BA3E373C05BED4BE494BEF7DB77B77E47E25A6647213F449EFE8DCFFB178ECA\n      C242193581362A26D24216017A5D84D76914912237890C5639B91E0E5E6CAB65\n      B2BB95262CD8177A2B0DDBD1C0363EE101B164AE636186222D8E658DE371EAD7\n      7979275D3FF4C9EA852F9D4BBC65373DB2F1C7FBABDF78F7E9C74F0C74FB603B\n      6EB88D20E06BAB9B4EA911CC82BEEB7656DBE3E5B9BC5AB40E7616FCD36B97D7\n      9A0BF989FFF982373B8B330A6B1D7620E6D302797BEDBE7ABB75E5D2B53BB7B7\n      6FAF1CDCDDEEB60724570E94E7FD38C18EA59288A75905B170D4168C6521C83E\n      616A1E239C6187B1CA68C9D1B078FC05C56BDC996FB5162BFE38CE2BB095B805\n      8C20F7CCED2D454E13DB179B4D9AE68F95C70FB12C5719D4E2C2E6A1EBED49B2\n      1BCB3D8936D328CFB2C35EA9246552646DDE9DAAD78E707FA6AF6C44AFFAFAAD\n      E9D2665023D25FBEB9D14D7A0F4D4F4E6CB5CEB5C2699F3A55520F4337135B65\n      E70D912DB7121522AF52727C7A7AB47E1CDE47116656369A95D76CFBEB9D8DDE\n      C1C1674B23C76181BAACC7AC2CA565C1AAF0A6B23CE6C1AAABAFA16C57A3B5EE\n      40943DA75EE32618D6BED16C6EE6453F55592C77F34DD14725E2FA4EB99F4603\n      1563AE3937F34D0F3D30F795FFFCAF0F3F3091E52DC67A86892A282F0E27663E\n      01569FC23243B9401991992D2537D7243D22FB89DA8BADA29439D686DEFCE60B\n      C1E191EAC3F3321D2080400960098223D185E60987959C15712E0B973B80A4A8\n      8DD7BFB5C956EBBAF07B7E91A2C28D5DC5C2A54F95BC6338DDB7AFBDB672EAC9\n      795469B1A4B0092F58619CFDB4AF0A7BFD7AFFE61B9D3CF415F10E54B625D22D\n      21BA9A99A03C80336CF272B07686394C46B79870A961CB0C36D1AD1FC4DA0CFB\n      47813C45148892E2E61E910C5D8E0DED34FBCED2BA8E8A05A6E71D6E0ADDD2A1\n      A3671A57565E78FAB30F7AD328F37751AEFDCEC9B75FB83373DE9B385F96BCC6\n      12B1FDADFE6B7F78FDC2478E8DCCA54E94E9CC8A28DDDA6B8FD9A55A097E8F7D\n      F1ED7EBD618F8F635614B02A93028889BF7577A808CF1DAACE67CA8592EE8398\n      CE49CEA06CDD1CE45DB636A0EFAE75B713BA5CA065AA5BC2F4D278D80C756A2D\n      0A10E8D23A4CAD076C320E6A9514E531F5E1CF2F961F05993C0070624E7077FD\n      DE8D5FB1F7D27617D1A6422D5D0C4CBC118804574BCA91B449E6085166FE8493\n      CE90F2D4F1E0FCAF7D889CC4C6AE3C1B1A79801A0104D3C3740C038466E89B0A\n      363C550E139E024D21204D713FB0BCE885E83BBFF11CED99EAB7958B1B45B16F\n      729381EF284684B1010091899897530F4421B07586CA9C8C78BC4EED32065CEE\n      4E4CF352ADB1B6099F98188BD1AC67DAEE3183DA36526353138EE524391E10D7\n      044CF361C4101DBEC9021B5FE982F578E139B246B3A0BBBADFEA84ED60FAEFFD\n      E915FCBF2D8E434D419A969033C1D229CFC2D2AB2DB98FFCB487C7EF26518574\n      8F7FE74F5F29BD752CB4B2BBAA753B4B0F909D836AD0C6C03F477E8CE11515AE\n      8A472C7CD24FC7ED3952648F7DDC39FE8C9D64315294AB5017992C02A52DD830\n      38913425B03A63655F7A7985078D277FE1937A3EE49973E9DF5E79E98F96FBBC\n      7A398D6E89A2051BAD10F74DE2EFE767DE9F9DC07F35123B3C22345103143B2E\n      B1E76AE204CD1E41A3B614EE93C90FFEA34FDF796DFDE57F7DB59C3584198E6E\n      5F35914943319A65F01F9BFED7E155AD8514ECA469C79D73BD8A19D7B9F7F0E7\n      16ABC70B73F3D57370EE98442410A309E860662204E17DC1369214AA68D494EB\n      B7435554FA59D1C3795BE9AE043DC5FB5157E7916F71339DA1CDF730579CCCCE\n      EF67F01A47029C0EAF090B7C5FFF99BB0834D47F26026EE8C7AD3F8861D2C363\n      1B622C6ACD9635F719667EC20CE9EB5C532847B3B63E4AADE3CC2FC9E8D883E5\n      879E3874E3E6F2CD57069553D5CF7CF9946834A104106E231337A66091E7CC7D\n      F33FACB7BE02DA36B570BF7ABE7CFED77F544F9791086C05AC193E664C010819\n      D57A2F4BEE58DD7DAD12A5017D4AC995B8782D14AB686D7B30C0663C6AA748A3\n      2C0F00CB4365F95654F452694EFB391553256F943A25EDC7229533D1C77EE1BC\n      FB709E0AEDACCCDCF837DF6B04796D3138D8964507CDCCF883B8DDEE648D4323\n      D6886AAEF64C2AEEB868EEB6A6CA479ADB8315B97FE287CE078F1C461C1E912C\n      06C2A3D3289841CA8EDF5EFED3DFFB9337DEB8B31BD126F1FAD4228E15450332\n      34620EE3240D53973942465D0EE40CD9B07509057873299EF64B711C45FDE8B0\n      CF4ED8F6A172F068053D2A4B0D808580E665DB4E940F0FDA651D8CFA1A2BBF02\n      5F169E4BE038E5B4EF64830C0427B64B3971258B30DFF4AC5827957CE098E474\n      FE8E62BD242EDBD4CBD3B38DF1224937C64AEF97EC5CF8DDAB1B44488717277D\n      F788E6B699FE4ABD24B1987F29172FC711714AC7A97D4CE54B3E7780C8C683AC\n      4C8B548D6FFB1BC4F98ED3CA7D71810787523307618E16B2CCCCDA521B388215\n      E73D078512F506496CB1DD80772BCE5E96EE747AFB18AFC5F0540ADBD8D0F746\n      831191A18324098BC4F445583428FB08C9119FFFAD9FFA911FF9C2E726176724\n      EA82E084656921BEBBB212EDEC3B8668CBCA4CD51D2D99352BA439F324315040\n      660DB2680BFE948232B8DDEDBF75AB766C9A1C09E2ACED01B91324028E180B0B\n      088D3646D15812AB20F05AB338EF5F4DFBDF8E47F5C23E4DDBAA5B4E7D33C87B\n      BC7DF4D32322466B573A76DD195B0276135153EBF3586AAE03CBE4CAFAEFBF7E\n      B07C39C3A811E27C5F0E36527D50381160BA694C30195B5E6ED414A6401F712E\n      0AD39E4A4180D1E1B98BBADF3D474C7B4C4AC4B07C125A98B63E391CCB37C68E\n      A05D1A58CC133DCB5040C76A73F1F98FCDBD7DF1F5273F72CE5F8CE2D2012A6C\n      7F3076EFE2EA4EDC7BEA0B9FCAAC98162DB232FD97FFF28D99C3B5C507881BC5\n      24F77A1AAF6E6F1F199BF03DDCEEA737AE8BA523A34129C4A9B018C89D9C5077\n      F5CE6067253C7D6EAE3E07156DD87C078A82806CA3C58DAE6A5B3B03FAF64A7B\n      3524BB9677238B3712731D53E2B6034008358A02B2F0456A9DE078D2D6A00999\n      1B3FF9C347EA1FAD08D59605B503F760B07FF917E966A755107F5F8B7B838303\n      5803B6AFA49B26C2E2BAEED1404A5FB3133EAD203A75AAF4F0AF3D4D8F5210B5\n      1680800DF29A7073340A5C2C1F5AD2E1020AA371764D114ACD151D68F6C25862\n      A93C7273FADE7F7CFBCE1FF539F65A1CBD0FAB51980064BBC81D66D601146720\n      9CB6C0AEC2B699755116C6A3AE33E17815845D14F976363B3B094A627B7790A4\n      F0FE38C6161052051F42C5E375363D5B2E581F3919F34CD2829948838A6D3161\n      2CD1A06836B1B06D5C65DA85CFDB6C0DEEE6EEFFF2D51BF8CBC766051A80ACB5\n      041F77F24987F96822C5FD477F8C8E5D08C3D8F1D08317DFBC947D6D2AA5E116\n      EBDE88E57AC64C171E4D88A2511AC4C6EC2A75647F84D8A783A48C4619C51FFF\n      7C65F274A824910943A203E54816A0644121C42082704C0A4A63C9DF7D65C5F6\n      1B4FFCFCA792B9B64FFCBB5FB9FBCDDFBDD62982750B5F0EA3EDB4B83FF33A4C\n      0E33A3F4F79BBBEECFD4AB0F0C5886269C92B9053E368E1FB48B87C498D6D1D4\n      8F3BCFFCC2C7DFFBFDF7AEFCFEBA834A0392B57BD1BB068B50A665268CF72E50\n      3A7377A7944350151B6BDA19CBAE01AD2EDFBDF0834783C554A431EB7BA47073\n      D8AD50D9A14A082687B7EC186010DE57E8AC5C1BA45D52089A506B2789F645D6\n      932237731F18DEAC67E95402671E2A5A7863960B2B04CA282C0EA85819E83902\n      AF0399A47481CD910D1430CE1526A91CB6090D831E01028782D2DC16E261F686\n      D9D3E67418B497319F835FB4E0D9C7083F42DC40F58F9DF68F3F321E86FD4B7F\n      D1EF3AD98FFCE6E3CE2214700E02941A6A6CD2244975EAD5DFBED5FA4F192081\n      B29B277FE2E8DCDF7C2C2ABB1E1D95319029551429D4437327895A49B2E6F496\n      F33C62162579202E17DB7FB626F7D841287A986F2505903B90F8154CCAD836BA\n      C134D4470399780EABD96C82D9E3AC0A68BF5F341FFCFCC2919F9C6B7BDB65F5\n      00FA83CDF75EFAF6E9278F473D6FEB4E7372D686C7D56BA6A589B2044EA8AABD\n      DDDDC63CEB3605E6BEE7F82B77D70F3DFEA0F7C9A3A25160EE346FB757BFB7BC\n      601F9207FA8517DEB97B77A7953BBBDA59CE8BAD410F1BE714EC18D7412BC32C\n      02959A666359B26704BD83251B208160C321E1666876A454B5C983B6F308E627\n      7CBF5CCB8FEF390C979F2FF52FF1C1396C3F1D31A788E31AE96115E674355697\n      9AED2D95FDE4830F9DEC27762A4929100AFE26CE401DD5EABAC41D9CCA6CD04D\n      4552583E7257E3E8BBD166DD733FED8E3508DE19A1FB52D96B69B81D0E26AAD9\n      4CF57A73BB51E8C758304268AB907DE069DC032913F064A94650BF1994ABE120\n      5316E0726A274EACD99E453A166DE6723048792F5CB2AD724037A8BA9EEB1EA6\n      C7CD92F60F65DC1DE411969B6576C316170F7652D7EE4AD9ECF72DC2F328B5C6\n      2781ADAEB45ABBF14073E429345FAA56CAE5448A348D7AEDDEF9678E7DEEAF7F\n      7F6FD01F8411D4E8ADDBAB83D59D64757DC1775C9C8F4ED71EFAF0234B174E8D\n      1E9E6395528EBBDC84FD8652EC0DF4BA46494DD4A257D73BEFDF9A786A89CD90\n      AC48751790463B40737B21B64C162C2B1C9280CE8F439AD6E3D1EDFFB6A3EF38\n      DAF53BB267172E434E6F7463E9B38D4A63E4EE5BDBDD243AFBD4022ADAB073A5\n      8970918C9AD9209DE74C8C5D7EB173EFFD145670428DC5F3F27ED652246242BB\n      C6AFB82A89B1D8362CD3C4899BA65762BABC4CDF19FEA0FFDD5CC310286E8C0E\n      3B66000887ADFDC380466D9CDD47B058A06AD6C215B9543DBEFAD4F72FBCF6E2\n      F5B30F9DAC3DAA42B2AA44B994D8D97EF4F2CB9BCFFEF4F7AB433D25379DD603\n      6FFDCECDB07F70FEB186678267CADD146D37F70F4F35A02AEF37A36B57C3D367\n      677D3F368E53D2340A50EEACDD19ACDE6C3D7CE1486389C480E5C8650033C88C\n      6339BBAABF1C7563EFCDD5F6724A570AB286F4DD4117BE4ECD76B994362796A1\n      16644CA263544F7235DD28592C3EFA647DF2B3B3293930ED02546047DDF867D6\n      A58BB7291D692371BBB7D30175E7D406B1CACC4130D4C63C506AAA547B84609A\n      E7279E9D3AF5CB4FA655A0989E05C28F9AB65F2E2C539F4CFA8431D156CA3333\n      6128324F9A90CC7850665666629A11EB0F2E86DFFB8D15D4B237E3FEBE67ED4B\n      3988C28AC5013133699A6508A23EE5558B519447B9B91DAA5167D2F31A8C54A8\n      76B0A856ADE91973E1BDB1D593BAAA851F1643F739550496AAD55863CE475EAA\n      ED9C591229287B4C3390AFC069B053F4187194B23805DE690364B7BDA98FFCD2\n      37F1978FCE49DC3797578A351C5C6774848C0A9D8C9D6A3DF24323A8EC623C71\n      F7F6CAE6FF650B1E6D26075BD2DF10DE00C508F7A8B6E2AC12135BD3BE25060D\n      1A3CE48625326E07ECA39F0FC64F746406B0E32AA896C643ACA41527D2245D19\n      206416108ECB2FDFB2BDF1C77FFE93E15CA76CF3ED3F3BF8FA6F5DECC4DE1A91\n      D7D37435CC336DD6E67D454887DE6A4551DCBF1DBCAF0887878550AD5983B8A7\n      C6F131941CCFEADA8BCEFEE2FC033F76EED23FBF74FBBF1E60EE765034188877\n      007F95E180820E6D4B814E68E336E9125DD3648EB119C7A9598E68DC7BEC078F\n      93C95025090B5D6060E63C16D8A7017566D23B518E44C111C84167F55A92C726\n      112AE57CB59B7654D1CADAA0785C56732CA06E5166E6E22D5914499C18F34273\n      A82C1378BD8CE788244AE5DA38229A7BE7617A2C6666E0DFF4C860D3C43C6C1C\n      45E6287A88846838B629B509A25680C640FC9409059B77F9716C1DA15E09F58F\n      9FF30E3F54957978F11BE9DA60F0895F3A3BFD615B9122373F5A19C77710A2D6\n      D8777EF3BDF84F518D3B5175E3B12F5E687C6261C09C92336B5CE49810B26018\n      C83890A85E1CAF3BBD1B00DCC6EE262D27AF46EB7FBE6A857E2BDA07DB3E0000\n      FFFF49444154174D73D69F6DE4C0EB588D310BA518FE0EDBC014429D2A138BA5\n      AB44CF39A5115D360DB073D1133F77BE776AE0652576595FFE83FF363F39E9B9\n      B3DB7B3D6627634E29879FE80B3E6931540FF7F64A355490D183AC3D335ADBBB\n      B4E34F4D96FFC619B95448E4DA69F5EA73EFBCFABBCFA315D12F46BA1A352DEB\n      DAA0DF94288A0B4F5B35CBE38E95101D993154D3FC8EE3FE4152A41972B52F19\n      4F50512162C6257325E7C1C0FD905D3E235939CE6929ED8BD28B82FEBBDECA9B\n      FDEEB9BAF31363F3E7316D643DDF5179C95B8F50224A5B79DBE1784A92B35699\n      8B3CAC0EA7C0BB45A08CC96FC631E304C8562D2FF0F640D7C75EB3E3BDA2FF68\n      8AA70EC2DC92BB8D4A1379C21FBD99657F71F99DB2CB3FD6987928C33CE943F9\n      B1141D651E3017E0E1094F54D94D0BEA44765DDB326E5DF7F05FEEED24A9E577\n      8DD59373C89B2C5BF59CBC9FE6FF796DA5235835A58B2A7E78A47EAE3159866F\n      5A24CD34DDD1AA35527A3FEC6C77BB35BF94F5FBE54AA9472B1BE6703A1A6850\n      00FC50A352632EA0F77E3704E02964B6DFD9010828C15746C8E6A8512D79A01A\n      8BAC46D568CD7FE0DCE2939F797AFACCD1D2C2A46094F01E2C7764DC877B05DA\n      4AD4969D65EE6ED17DF3769EF41A1F3A295C9487805818D62397C02F139D4B5C\n      F838C339CF222B2C15E5E48D62FBF9A6AFAAA902E5661165B5EDCDD127AC4367\n      97366EB53737F7CE3FB14879DF2C7D6415D4DC0FF0CC32A34EDADDBEA92EBED2\n      CFA24023DACF93B6D05B911A70BB2D535682A2930DAD994C27DA70706228F386\n      D3E0E6065F7FD09246756A8E443593268A5867D898220EEF08812A18205CB4E8\n      BC8DCBF142E9F4FB1FFFF193AFFEC5F2C2F4A1431FC731DFD0AAE4165436E3B7\n      5F6F1F79FA23C1B901529BAE7C60F7DBF1E5972F3D767E2AA021A5E5CDEDB0DB\n      EB2ECE8EF8B6B5B2DEDA5A970F9E031E1EA214E102032B26CCDEDD4897AFEF3F\n      786E617489E636C86D879AF0E1980048EEA9F06E34889C3756DAB753BA9AA075\n      4AD6F35410ED23E268E9BB36940FA6F40CA547391B67722AB0A61A1C8D0C4EFE\n      D4F9BCD4D72C67CC9C7E36FF70ECD56F5C5271A59517F7B2FD3607A40DC29C98\n      6E01D37499BA4531EE054F1187A2F4F827A71FFCA547D372C855896A5BD0D478\n      AB491B0DE9B5C934A6052B5CE378418A613A28B0AC50E99416AE828F67C7565C\n      7AEFDFDC78FF8F96915BDEC77825EA27B2009EAB445E0037C266B41E5E54C363\n      3E5351514499F614AD713662A38A663EB1EA55DC98D4CC135B3B51BB03FBC28B\n      8B1C48CB08733C252D9257C7EDF214D3A54C39A9C28509EBA3C0BB8C9F173786\n      59E675C33F73385284F74B731FFDD20B0084B34A8766612852B29D2AE56316C0\n      AA54EEDEE33F74A876CA4194B67BD97BFF36CC925E2F4DF765792563073A1438\n      02299115E5D81866F6411C8DB2EA591E9779C31DB19EF97C6964695F26186525\n      2D07CA0CD306C8B02F207E1A0149A0765AF02B2FDD0882C947BEF8E9DEC2816F\n      89F06DFEF57FFC6AA7ED6CA2E2FD34BDD9052032E877BF3BF47F08C10F8070F8\n      858616CAA60D658E571F1A638765B4202AD68CF8F03F7970F4DCE4F77EF5ADDD\n      6F15C2E3BBAA1B0FC8459AB10CEA34830D9D9B9487829BF407EC12D440688EF2\n      59D7AB02439B597EE287CF6495039DE6F6C01131D01C2301496AA1DC00A1D000\n      84994FCA3B77D5C60D51C01FDA207DAD7BAD4479568AA3FE60200B17BEAFE3E6\n      C4B229734012A671025B977186B9D58F63D8633946E970826278104A0AB3D994\n      E99A191AC701F2837295C3694234F4EE19FE2992E47EA8BA19AD340DC75A3A48\n      1EB2D909E62D22AB620D4E9E0F664FD854A6D75FC1EFDED97BF0470F5DF8C211\n      C9BB85091FA7F6D0BA354FEBDFFAA76F93577D1047F8E4E0C95FFB1099A7392A\n      FBEE828652ABB3613B92F16CA47A90F43768F72A942EC0622BAA77BEB1BBF597\n      DB8135DAD76A7B10AEB493F55CA79C00104A6BE028A74ECA8002A14A7B424645\n      66D3620E7E2EAD55B1DBA7BBA7FEDA03951F3793786E5A5AFB83EF58BB6A6AEA\n      F86ED8DD696E1D2DCD5B03BC9F6F578ED438A9242D338D549A3C79A7756771A2\n      965D8FF6937CFEEF9C468F95F214B6F01892BC7565EBB9FFF09DE5AB49C8E88E\n      C6F7E2EC005E47418DFF4F92F78B3882AAC21137FE5A50101D244460052A364E\n      270DB7341958876C7512E71F2F558EC62A709C0E50C23CFDE3A8F3DF9270973B\n      5AB05E9820AA9E284FFE4830B68806D81A8C5682D1DC5183F825277A31DAFFCC\n      F8FC79600F234E67C429C112D81CEC84D91D84ABB5DA51D83F1C704C31D7A59E\n      A5781175774AEDD896DE2589FED360FFADB8B0A3F8E1D2E8E71B938745E1049A\n      592990189F5A05AC33CA6929209C83D2844D8B60B5464A44FAABEDDDDFEFB50A\n      CBFEB1CAD84F809C0DC23D2EDE0DD9BFBFBA763996E7AB8D0FF9959365E94845\n      5CDCE7799664D59479A8B4C5E90D249A454E61BD891C18E1DD4ED885958999CF\n      79B5E20DB2A897C6793C1CA3AE8EF54DBA7A6A6B728A83DA0779041F8F58F042\n      27AA1FFFBEA74E3D7E62EEECA22821C10D97335A5BA785B94F639600F21A8678\n      B388976B5984F6E28D4B2B501BA7CF9E886B290DA58E1360E4288D58021BC083\n      A21BE358F2CC5696D5A9DCFBFFEED155732D9B638AB53D205D3AD77FE073A7DA\n      07D1AD2B9BE7CE2F7A8D18188D56F0BC0A8D539A395085B099B3ABDF7E47DC7D\n      57EBD45138696583FD8CEE0BB7A984B46033198F3DE3DC6B2C49CDF192567FD5\n      35A3EE5B8398E262196F60F8ED4C1841A352949BA1294D4D4A2852A31C1F75D9\n      AC4D834EA374EED6A7BFF0F01B7FB15166D5933F504FC82DE308AA3989D9F275\n      9197EAC73F5DCBD11613E3D97AFDD5DF7BE1D47CA35ACFECA0BA72AB03856366\n      B6EC5ADE8DAB1BC00A8E9E9942BA8F3FE8C853B0FD3BFBE8EEB59DC3C7A7C60E\n      735482B26063540863376BD950826FF6B3D07D7DADF37E8CD653B28DC96A1EA7\n      5A045A9731763D1718B695E78B9675C4B5C66CD6B0D599F9EA5AF3DA033F7CC1\n      79A85ED003467342ADF0D2E4CB5F792DDF2B0D245A539D1D22FAD2890B62824F\n      B1B0B5A80A3DE5F8C73425767AE2B393677EF1D1CC0D39AA52644B1C9BEE3BE9\n      9827673C6775CA0A3BE7C6A99419F34D06EC195413E0A5C03291CAB6405724D7\n      F6DFF8CDABADAD22C474372F7A5A2466C4DA8CE358D81E268BE2BA85CB4C53C7\n      96C44389F490A8C19F15A4649C9DFA6353FF3F4FEF016DD7715D09DE4A37BFFC\n      DECF191FF8200082044990600283288992AC60A92DCB6ADB6AB9ED716CCB961C\n      24BBBBEDB667B9C76ECF2CAFD6F2B4C7331EB79CE5A064258A12299262264190\n      C8F8007E0E2FA79BAB6EDD39F520CDA248710120F0DEBD5567EF5D75CEDED1F8\n      9C15C46C7B2FDB6FC61AD3418C5A1C39207151CA4C919F64EE0CCBDC3821A104\n      2C463A7C5A25824106A4C948794A03180733BCFCC2A3BFF62CFA8FCB135425F9\n      09AEE4A29963C6A46E96958D79347618DFF28E121D53A5F9DCDF071BE76E98B8\n      D48EACAB41BC9B85C0A63509ABDD802DC50122785C63EE49CC4DEA5AE3F4911F\n      2D96E60008810AE434D01F2A65C8541A4626481D05EA09022024179EBE542C4E\n      1EFFA5F70C0F7632DC43D7AA5FFDEDEF3537B336D12E87F1F96E30B47472B35F\n      94F39B1784FFBFDDA83ACD50C10C5299EBE26C81E66F2FEB47B4743A33CD63E4\n      D1DFBBCD9DB09FF9F557BADF23411EEDA5FDC023E718A7216798A48C0482834E\n      B088BA4F25A91843DA41DD9CB19499149DBF7AFF474E46F63E8A53363413D558\n      A16C80686C65C0E49533458C64ECC8DA8DB7FA8D4D2A2519645E5F435B432E75\n      2A69301C0E9074E0892A972200EF54D937C117D1D48727BA658571021F00F46E\n      4A2990DE20E1412A85F2B901DDA27A6794F48375CA53555690EA4EBAE91695DD\n      3CCFC90CE53A8E46C3C132B533B960E947993B9B92823138FE40AE7600A8B258\n      BFE07CEFB5EDCA71FBFDBF759F28B504F07964E8CA678D067BCE77FED7579D4B\n      C541B0BFF0A363B7FDE22D43C337E89C4EE7339A5757892813CAF91B567937E9\n      6C22EF3AA16A7291F40AF57F5CEFBFE05976B523A3FAD0DFEEC65B0277516A4A\n      1EDA711E5BD3A4602350FC693FE25D1E4A43966DBC489C59CD617A0C9078F433\n      7707937D03A3F8F566EF9BD727C7177ADCBBBABABD9C5B2C636BBB7BA3B854D5\n      4D33F64328D213CBB76C0ED71D82CAC3F28D9D9DE98F1FB54F4F88106151D49C\n      9C88586775F0C53FFEFC2BAFAD0106F5B4FC562077BBDE28B22A8E41D168A3A4\n      AC51D65CC4F25A12E94C996FC10FE6081D97E2A14AF1877385FB043584D8A818\n      6FDAC9B75FBC5ECAA1A3870F19F03A80A7726BB5C55FD8DA8727FFEE837377B3\n      78910EF3B92CB78B2E2D57FE68FDF2619CFB78752A67A26E9938892C74D2B56E\n      F08DA09BB7DDF7E27C68B0B3246C67C903E5B9699D75F42E46C2DA4F5BC8FE36\n      0FD6BBDE6298DE355699E75A41131D3348D57C966ACC0175DA65C6C56127E874\n      6E4BAD25DB6E15E45B443EB3C65FBBB6A119C6630FDEF650911DD9A91733EB1B\n      52FCDEC54B83883C56A83EB43263156591009550D78603C2FB9EAF35234BBA6D\n      6C5E43722FCB3AA9ECD9F46AB7DEEC0C605FAE4CCF323F09E38017D9FAB0EBFB\n      B2401CD729B407BD7CCE9829179C380D456CE75834684F14ACFBEE3C72F29E63\n      D50363F3771FD2C772BEB219160642460C953CCA28D6A11AAAD6DC411A5FA1C1\n      35D86BA8A56F7FE76ADE35DCD313207479AF0FB480C6B11E618D2B2B50954B87\n      55AFAC492BDED9FEDE13EBCC3781F00861289F14677BE5476613462F3EBF73F8\n      D05C612988F91045254481887B4696F7E336546A83DA49AB72FEB960E76A6812\n      3C4806FDCCD8F27157439DC44F8C51FFA76A4953D35F233E3DEA1C55BE15048D\n      7CD835E5F31B6309EF5EC59CC444E956E53BA702D4E0A7E4984E561C7D8611D6\n      754AF76F3CF693B79DFDE62EEFD2933F321FE38B1914978432CDE8EC6497361A\n      77BEFF2EB3E2F971A40793AFFD3F6727913E710B506FB67EBEEF50AB3CA96364\n      BEF5D2F56231377BB80C1B88A8B61E50A28AEF073D7AE5DCF6FC526D6CD9A025\n      5D201D29F91C0352987DE49FEFF081F5C266F7822F7762BAC3B3AB7E9F230945\n      AC6CA8ABD0BD541613BE8CD192658CE5734516DFB35CD8DD5B4D17ABB7FDF829\n      91DBC35994A556B26F3DF3E76706574D621537447783079E34FD04F134424414\n      A95E13649A99799961275A79DFF89D9FBA33027D9055E093C393578C5D75158C\n      5C33511A831E4C28301B4E0D85A33250E1C6AA9E08A499910F2403E444E3C2FF\n      B176FEA9353737B1D78F770590D798ABFB3C80403D5393D4C2CAD2021E395B53\n      030A628EE2B19C0DB5A5E61412BF6EE77A73070A969B6FF4D21B1BCD98131DE5\n      841F0320E50DD36082984975C1312B5A66834EE1AAA755F5D6C0EB87979848A9\n      4CBD9896606A0EDDC5C73EF31CFA8F076A861A47482391688C998C4CB1DC34CE\n      5B480664EFE8E39333A7725ADEDF7B81BDFCAFE74CBF1A097B3D0DD644DC8980\n      54318965026A53033C1425C64EA9830CDD9CD44E7FA4529A6AC26FAA45D66854\n      5C75128DA672220C3A48180932E3045F7CFA7CC19D3CFAF38F87B787A1DC7777\n      279FFCBD37AEBED68A2DFD5AC4CF0D925D865554A01049A2A2A5755D57A163A3\n      2C5E85AD697A334F07806A91154FB8EC1841A50C1B77A2B7FFC129C7309EFDE4\n      8BED97713F2776B36134A497746EC5CA6A39212A4B10E005602F53BE4BD16446\n      0E9BF6B46D817CD3972E3EF0D17B13B39EC5827996F0D483C32A2717D4BDC953\n      A402D580F8B5F2372E76C3410E5EDF7ED46EA5BC97E25437D2D40FFD01D058A9\n      6E4FE1BDF224061E9AD9860E54E007A2907A7112A9A3163581EA85A127559716\n      BE69373A323D94EA3854A9DD914054CD9E239B4C6562A080903028F4C06EE097\n      BB589BD3D931A330996445C7BBFDA1627E268095B8BB957FE67B3B599EFFDBDF\n      79101D0D63A665D822323090DE3A9FBDF04767731BA5AC3CBCE337EF341F4581\n      1814D0B214F3C88412AA2625474E549C266DD1DCC8927DA0DBCA637DCFDCFCDC\n      B5F42A7C855C23059C8A3A11DD96A491C6593CEC2169633A6E5A0EC817A92B0B\n      7C9974C5C0B0E8B46EAE58AE9509500F277FFB24BA37F5A597EB16F73FF76A91\n      2B53AFF58D7E0ED99365B7D36A198EADD754AC477F2F2CCFD4023DE8B7860BCE\n      C18DED35EBE1B1B11FBD27EC46F16654B04A68FAA0A639BD8BD7BFF8675F78E6\n      3B978659A58DEC06887D0442019EBCDFF7633F520C84A8D414EA8E362E1B775B\n      DD6621D2DEBF34F6DEE2C41D5E5AE3D9A0607E3BD87F6263D75A9EFCB9D2E289\n      664723C3B462644382A3FC2B06FB7C54878DF2B8348FBA289A928B03B467E65F\n      E1E8B58B57DFBDB4727BD98DE9005ED7A496BBB8DD794E0641ECFDA4359967DA\n      5364F0E47EFDAEC2E26353CB9A1B66A85BF055E7AB202E0909EE78A84CE39C72\n      32198AE12826C14A6367B7113EBBBEDAACA28589C269E9CCA5C6F73A1B7FBAB5\n      FFB2863E3031F189C387E79296E481C6CB573AF667376F3C13EDFCDAC2F2C731\n      8D6BE1FFB9B6B652B6EE2E4E560692A628D38D486AC3286D87698B9AAB9C5F90\n      FCADA07FB5DF45182F2DCC062D8F8A2C57CC5DD8DDE84A6D76769C806468749C\n      BCC5B3D0B51853A66A82C6E13BEFBB7377F5DC4C35F7918FBCFFC0B103F9E569\n      CDD4B41C2CFB482DE18C22D5F22CB8323EA2BA3AEC6870B911456DA72351536E\n      9E7DCBAAE9E387A7B314E40BC7893438919C4B0DF615AC3B1227216506F1ACF5\n      7FB9906E1181ED806B65AD1691EDA9F71AF6726DF5856E2D6F556F8D221490C1\n      989A6C22032A0B3C0D4D789C7ECFD08AE16EE1CC939B83BAA4A6D513492391FB\n      211FA4B24D14D42959308A1FB9E9D9AF0E5C547EFD480D8E26EDD55AC9545C9E\n      BA9E00BAA946BD95AE50AE1E6936A933D0589318A4796EF65DAD931F9CBCF89D\n      D6E6F9C1231F3E820ABB0C184C088A384DFCF4D5339BCBA7DE3EBE920DB51DC6\n      F3EB7FD330EB72FEC1428777EAE7FCF1DCB835064FCAB876667B61A1608F210E\n      B4400915D0D742C0DEF68D4B6F6CCD1F181F3F6890A2CE01BCB338C589C0A6E3\n      13FFCD8EE8B297367BE77DB91FEBDBA1B8110F894E968BE52A23431E9F0DC3B9\n      343B4AB4094C0A8542D10A4F2D38380E2F7883DB3F76AA704B08855026F92419\n      9EF9BB9DEDA7635BAFEE64BDCD28F033278C450CD293C176D68BB11C23FA38CE\n      73A7BFF443A5539FBC23D23D6B048412078A4F80224486EAA4579A24561EDC20\n      03325DAA5B391F8F6CEB34A2F2C6A58F0C35B7D9E97D5D7EE3CFBF5390353F34\n      7712581FC3489984EB5453FE32F0DD99D4F2CAFC071680A6C86B268B865335DD\n      A942DE21DC1F6C2F2D574A35E530D4EA0DD7AFB7493281191DFABE0E10E09826\n      4E0A2E2A8DE96615746196E02881C209C2505D10AA9E8D2CE3A05B11313DE7C0\n      63BFF50CFA9D9509956BACC2E5136EA8E8AEF1AC3A4F2A050C90D5B00FA03BDE\n      3F6DCEEDA4F58367BFB6D97A03CA89B5990DAFA569D337D4311DF1A0AE89CCC2\n      912810F920B641AA1873E9E91F1DCF8FD5659CA0D802E8558E41AA9F5E50805B\n      F843521314612ACCF34F9E61A472DBCFBE3D399D797267BCBBF4C69FEE3EFFE5\n      F38945AE87E9A558BB9AC64481687AB37754E54E2867644DFBC1309D92860A13\n      8315AB76AB4E8F61ECA234F7B0F1C8EFDE6D87D9339F7C7170CE6CBAD196E8FB\n      7DB6AA27F914EB0803F35439CA6966121DB01C80703CC3474C77C6B118A5C6C2\n      C5077FE224371BA9CFF5404D328934803F0E477616A93B7EA1E67F457059AB6F\n      845A5AE5D8DC0DBA7BB13754DEA1A3CCB8248C543E9FC9EC6A900C121E817C53\n      F262E49AAA960EA589F21ACD1235A72D47B7C4B0EED4D59C923284DE043FA88C\n      EA4C4625C6E0F4FB93C09267A9D29ACA08436880D06A89D019428EEAF9F124AB\n      1482138F14F54AC791CECEBEFDF20B9D81F03FF49B77E61FD242CC2575A916C2\n      FADD7CDA7BF54F2F97F60AE62DDA7DBF73AA7B741F1E72991FD6B4435277E1A3\n      296EAE0958E8C4DFCF9AEBA91882BA37A08CAC6AD73EB79A6B56BD9436E42012\n      32946E9D5A7B6918879DE150D750CCF404136260A7840D9AA60311489DD46CB6\n      EC58340825CE1DFED9E9DAFB9D961E4C44339D2F5F4DCE5D1BAFCE0F87AC3ED8\n      9B9C3294074357CB1DC21A108F1D41731199C8EDEC07D3F67C6BE33ABBBB52FD\n      E84389A6FB2FACBFF1774FCD1DB87DFAF85DB4500C3BC93FFEFD379E78F95C5F\n      B3434CFBBE0F92A1ED077D955C0E64C7528B050DDD8C2AAF3E0BE5B4F46D05EB\n      A3D59907511E7783CE44F189B0F1C2956B8FDD716AC5EE03E39BC9100BB94F80\n      DD32ACFCD2F42D9A5E6BF5AD409F732AF95261686ED4EA34CD2DFE5FADAD7634\n      FC85A50313D9A06DA77A5A1E5E1FAEA5DE9EECDC539A9CF3C3D5A2F16DCF0B77\n      F93B6A07A68A985678A18429611C38B76668861ECAA1A6A6DDA0A4608B5AE166\n      DCA8CB272E5DDCCD060F9C3C340FD435966FEC0F9EDBEEB74C776E6EECDF1F9D\n      2D77AE5680EC76EDEB41E1AFFAFDCFEF5CFCD881859F2DD4269261CB8ED69037\n      2174E51BE3715069B08A86294F41180B7AA95E5F75AC9779B40EC547D3E97C6D\n      736327D54D5ACA5DB8B1E6323257AB245CEEB715A89B36BCCB90E47199146A18\n      AFE4DC9A91D905F2BFFCA75F9A397D321C36002EA865E330540B13ABF6715D65\n      F701CD548B9301C0518D9318C78DA47ED532B478BD3D7CBDE11C60D69C034824\n      62ACB25C548B7242D5E19295A80BDDC04285C18BFBCD97A334B102C40B7E3595\n      2DF6D070F6A195E6399EF9BDCAED51A267AC3FC540B1B1469614544F0481FDE5\n      D30C2858A5F926BFF0D2200EAC84254DDE6FC7593F227BF866EA849227224B47\n      B615A3E8A591D1E8F7A727401132D530CDA46AC719B9A3A6541DCB10151FCA01\n      08E941431F539107B5E50FB58FBDCBDA7D237DE3BBFBA7DEB5589C0EB3804910\n      747A9D217EF942E8561E993F65F6ED559A1ABD7F12E1B9C1D23BCBBBF15EB48A\n      E78AD3B2900C3D6DE77CE3E0720EE59593A3291D0E0A4AD98F71119A17CE6C1E\n      38343576C8D2F2584D27A896CC8413231799C333F5B44D5F024518688DC4A847\n      B209DCCAA06308E5793248C5EB4C3F9A91BBE1C582A065AC54E0F7CEB31231DF\n      DCEF9313D6F1F7953523CD92F1B858AF7F135DF8BB3A0AF42189B7C2A09750A0\n      4DB1211253F5B89BA198349D236C3260ADB977BBF77FF27690B796AC11AC4B1A\n      AA2E19E164584FA9BA732132CED445848D24908E04243F5507763A576E353D1B\n      AA98E7A736D2B767BFFB275F6D9E69DB74A62ED815AF1368892E95695B4248A8\n      CABAE648AC2B9F198935581E9A29E898654D17ED8AC1825EAB5C60F3078A462E\n      4D52BEBB167ABBE5C090BD2C06202B125A415819B75B9959266C9C6A55143010\n      9DBC90981A518E8CA996EAEA9A098070F9B1CF3C897EEFC81403C12F89BAF562\n      1150B3B22C2D92EA9809EF3CE8D0C6ADEF9C1EBF2D0160ADBFC4DFFAF29E4E4A\n      9B72B821642324A1C8841E730AA59AA14858843F480B1621EE4CFAC0BF1973C7\n      EBCA7E32B190CA045138A2A51C5814D47B8D031002B532CE7FEB327CDAE33F73\n      1F7ED4F064A79ACCDDF8D7DE937FF6A296E6AF85834B32BBAC528C46E145B08B\n      53A99ABA984AF85307A4CA8B65E47BA426EEFC5BCCDAAD08DFAA030EC513EF29\n      DFFB1B278C56F0D4A75E0A2EB96D57ACF16EAF2BD659064A85294B33C5F19463\n      0D6849AA1121A7327CCC72676CC3A4182F5E3AFDD153C26AA9EC34904F310345\n      0AE887133B8E6039AACE3392D0F61B41BF075B281F68FA5E30DC8F86C30C7E3F\n      A642E8B574100CBD04D0AF14ABB6A5948E86912956F2151026862703850FE030\n      95911A82D00461B1D4A244A56DC067D446839A524D3B8DF2A7460476B463D577\n      17A935F25C03A199181A1937F5192D3DC49C9AA0B54A7AEB230E29EDBB49A1DE\n      B65E7DA1D70DBDF77EEAAEE26359A4F5B15100A26E84E6EA97F72FFED58D4237\n      977B37BDF353F70E6ABB24D39D6429D397536481EEA100D3F0C670AC0DD6B5EE\n      2A113A2703028BE8ACDCF8ABEBE568AA19260D1104F0F198E311B7C54358E8A2\n      9FF39241C4BC484D23EB1564982A7B916283E5099AC099A9DC03AC991FB10E7C\n      6C317085919592D7BBFDAFBF3E9B5B94445FDBB9502BBB4652D8DBEF8FAF98C4\n      C1690B1E69CF9A2CB77AC24479BFB1DB2A24C73EF59341DEB21B59F71F5FFAEA\n      3F7F9BDBE350459D7C59CB55BEFDC65B979AFD81C461321A1B07F486FA050F5E\n      65AC41811C3A52CD858352B97FAAFCC1E2D8DD033ED509B562E57B2EFADCFA85\n      BBA767DF5F5E38145F6BB084DB7659E45241F66DC1F5C15C123A410A64BC492C\n      8396DC21DE762E2DA5F956643D3F39FE9517CFFEBBA9C9BB67AD3E1B225E929B\n      623DE86F93C181B1C943A976B95B7F8B996FED0447CDF1B7D5F279E6CB3C43B9\n      3CAAB87E5E0A1DE70228FC3163B283430C54618B7752F72D9CDE685DBFAB681E\n      B1CD1D3FF9DADADEE4D1D3244CA7BCDD5BE6EDD40A815FF375F2E620FB8BFAB9\n      034BE59F294EAD84BC6F67D2764D2FCDF3F862EA7550B6589C2C4860D581AA45\n      C3B42EB20B0C5D027141741EA62F0EEA31A643A6AFB79B868667C76AA013F6DA\n      1D1FB618A5A98C4D17D92536810A8773851385E2C6B5373FF08B1F7EFB677EB6\n      A3F553354D288C84E7333554A4C2C62DA80704CAA746B99AC7E32243B6A276A2\n      45D2CD60B06643C938D369F4B727560A346771D5016F621192340021A569B6F2\n      AB10002666BC93EC7FA3293B8E6F64B99E4BD3417C5B6FE13DC703900FCDEDCA\n      71451A8C61053E63C27A584DB8E024D680C962D11F8DB2CD5E78AA7FFDBCEFD8\n      5637E90C32D4E8895DC2A0680942B86A641FC9BC9B119F23573339EA4B1B99CE\n      644C53CE53AA8353CB54C6A5B261831D8B60014F517240D76B998C4969E1875B\n      47DE6985EBB957BFB179F4FEE9CA629246C05B99D01A8445F51D238C8F2E3D92\n      F3CCAB581AC113C6FEF7B6564E97DABCD5BCC297A766359777F7D060972F1D83\n      0D038F5C27524F7DE0BD19876717BA97DED85E383451BBC5D480364835DD09B0\n      C3117352367C6B8FEFEAAFAF87973DB92F643DCB86864D11D27D80FFA1AFEB7D\n      BB7004D37BF2AE93A6611A150BFCD48259A5D67A375DA5FB0FFCC421BD2A9419\n      7D25E66F59AFFEDF6BC99A11516D4774EB01573BC842A1A18E9C8C38192B9AF7\n      64733EA92F3C9EBBF713B7459667A42E436EA6ABE344453C46A783F0EAA0C26B\n      581F0D0840214BD4F07FA63C7A60DF0BECA3D8D3B9EA75C74975EB9F2FBFF957\n      E7493ADE44782F0A3B114F54004FCAD4E026538DF7E9C81A121EBECE31ACA358\n      2B5136E11AF38522D44D24BC8347CAC571CD8B7B32301BABE6AEEF25B6E5F304\n      7351D2D038437924889E1835A2CF5A693153A91C812219115658680289D38CA1\n      79E0EDFFF149F4FB47414BA8C1B89827499AB28CE68959947842D7CB66C6495F\n      AF923BDFF6203A7E56EED1D7FF667DD8A8F82CBF1B761ABEDF48C850B70555E3\n      2D44C0B64277E8053765959ABCFFFD3977AE9D4AE0010EE5EA7A2CCD68225533\n      2B8D544088477C8ECCD5EF783CD06EFFB915E7FEBCCA4546B4B3D5FDDA7F7A89\n      5D9BDFA1CDB3A479B55F6CC4BE3A01E6C8E6AAEB91D334620A1DD4A4243C76D8\n      8A04B9383A464A2734B262616E74163E327FEF2F9F243B83A73FFD9CF796D337\n      0DA8E5BB837697E43894448C8A1929088D6BA289F9801126E95266DE6639B316\n      36B3482CDF78F8C3EF48CD3A8FB6403CA220A70EEE137527DA8F43810327C9E1\n      9DDADEF97E225180484F43AD24EDC57124D4AC2B5391BAD407391204AA72AAE8\n      5DD898CACCC9B62CC3B04426832882F7AE62349832AE05013948D300337516AA\n      780A494763F500FB1216FEE8A474445D11FC3F051C15058135CE86990C8B99BD\n      C0F4052D58628693D9E549F39607192A6D16E2CA70E8BEF4F46ED3F37FE8B71E\n      293C14896C93100B65E5B43E71E6B3E73A2F347299E1FC01BDFD91E34932A480\n      53C6ACD4F331A0964849E4230AF20E45BDF33279D36ECF46C5164076FC2DDEFA\n      62DDC99C2EEC3D5F6B08E5036F22430B79C2BC1C2A35068321CB128A86C3814C\n      3305EA1AA9985685E3314C73068385C6EEEADFF51FDEA14FA26661A8F72DFFEF\n      370A0D6155796B6B3B17D6D058EDCDC195A542BE62157B32C45154748A50C703\n      25EDD87EABB5F2B1F7C427A7815C3A2DB4FECD97BFF82FCFDA5B0E2853D0085D\n      CB7DCD1BBCDE6D7B84865EA48991135196D91A550C04488F410F826C4AD33C8A\n      4E8E55979BFE9255BCE1B02F6DAF5518F9D8DCE48AF4B9FACCDAA82F2993948C\n      D8CBF76340D4E9045452D5AE844B09EE98DE1E8F86C1D85AD7BCD2DD7DF7C9E9\n      15DE2E0BB61DB0B5307B6B6F47AB960EDF5ACD773AD737BA7F598F8746EE1313\n      95877CD8AD56EC56592ECA8A7D51CCD972DA813D14B5F53064432FC6F2829D3B\n      5357A0962F704F0E8E97169662C729D176D22A519BEBA6B7DFEB85E4AD28796E\n      7373A15A7B68BC7A280F3AA297A9A46F0B36467D103F2FC3D52058320B8F4FCF\n      8E457D4D190065436EEF0EB54D217672722DEB9D0F027889EBCD60DC8102630D\n      92682B1A4484C282A394697158B5C99863B879B620F0A241A78FCF7CF88F3FE5\n      CE9665C67555A9D44923CD84AA809A72A51C05960379E5EA325D193FA8084FD5\n      481AF5D2B0A9252D3FD8E7E702ADDFAA1E2B098322EE907EACC9C8B380636A76\n      C499C6C2444B8364F0CD5D71D9ED1BAEEB937CE6FBD3F1D4076E8FBABBC35673\n      FCF0546A0FB2C80372858895614FAA6E558302AD802D8C07C830FCBA7BE3F9B0\n      7B4590CCEC89A89FA51B5CD683416060AE33D891AA19462A8FE604EA970A1180\n      6DA72676796A28B3DFD138856A571FB5926AA3F1F1822627095D34AC316AE689\n      3FF5437CF96D8574C37EF54B6B87EE9A2D1E8722D065B10DC41188762CCDFD66\n      3673BAAA17BC3434C2D5F2E56F9EBD6D2EDFAA377A315DBE65D24CF9E5EF7986\n      3351BBB38D123F4BF3B1726141462A1310D4C3C29537EA53876B951384188929\n      1C902C29208C20D410C1FA7EEF0A5BBD6CAF0DC486B6BB6B8AAE2CD889E1CA78\n      837B71A13ADB4F72325A2A974BA6A9F141D91ADEB15CACD966109B6FEEB4661E\n      5C587AB7CBD965AC1FA05C9CF9AB8DDD6F5A52E61AE6FE8EE8EFC5B40E2A19B3\n      3277F4A4675687F7680B326B1D7BE7CCF15FB835CA6FA3949B78522355A986F5\n      38BC3820FABA32C832B4EC6663E60FAC7B46A6CE6A345AF09BB139224E6479C0\n      BF13BDFCBB9786BE3BB4E370C8F7FAC686A503E31C8B8676423D6AFA8666A76A\n      224B8DB869F03CA42EB41ACB4F5A79371336898BB5ECC0B1AA603D9034839D74\n      7F2709C35CAAE5FC24CAB4A864C8B9BC5D20B065FDD414A446ADAACD4C01EC2C\n      3480E900A9484C62C7CEF2DB4011FED1F1F98447A9720C55E2032A9709C5516A\n      6542270A06C6BE40839523CB73EF5549423B2FB55FFB76D730E71AC97027E86D\n      47A803859BC14AB440BF1894DF6638394D2F55D37BDF93CF2F76B8007A980399\n      833550604066848A7AE050A2749F015377D69EF5FBEDF8F8BF3FE43CE06ACC96\n      00AA81F6E41FBFBEFEAD3874D0C5ACB11AE477405A293327C310CA0413702061\n      99BA4F5049A048AA201999A3C9315AB883B0159D46AC39FF63B3F7FCC2EDB41E\n      7DF7379F0FCED96D03AF67FDA6EFB7B01D6375B09843B4A23AC7B26696F40982\n      FD302BD951C35A70A94533B978ED911F7BBBB0EA22DC199DA2BA48A8AC0DC919\n      14B0440210BA62C3DD39D703DE1B62DACD801BCB01073211C3DB37998E29C865\n      80C66418033FD0611924710C3F6D9BA6AE1B5CE183020E20CA4C678CD2388E3D\n      9E461843FD50650361D50333727542CA158DA85426E53E336AF6565EE796BA72\n      C5C06BE30A62331A5EA268CE30615FCD2FE7E7EFA0D2DACF897C14E45E7FAEB1\n      371CBCFD37EE2F3F2463BE070FD2308AFE56E5C5FFFC92D84C27170B47FFE430\n      2B8B44C40C80D09A9534176B0424AF0E22980271F293F625C45759584D6D1FC7\n      B4F1CFCDF0D900A85557886680778308D8BBAB3BBA46826CA87313BE38D07235\n      B7E0873D156A97F679E298E694E94E6156C24029D2D6D8E6DB7FFEB47DFF74DB\n      6C1580917EB5517FEEC2E2C172D8EA6A5DC3181FBF166EE68498AC4EF631F73A\n      CD996299C35A8C79C1CA6FEFEDCDFEF003F1C32B61E017421B73F3C64BE79FF8\n      EC53BDFD1E61A5AB1D7FD7342EF4877BFD6014B603E0454CDD70894E856449C8\n      6AD6C1901C122E5A706D37397CA57562FCE867F7CFEDE9DEA7E70F9F48C9AE9D\n      113D2640CA94F38C3A3C9084AA26338975A2AB8333D57C0D888CB561B26FFAF0\n      0B9AEBE16BC4FDD260F3B189F19FB20A653510E5E0EBC985EEE0B7F96AEBA0F1\n      D3D32B2783C2572FEF5E36F101872F6A9E27493FB3A50722DB8F613B16A65C9A\n      CB136C0643534672A2F8C4EECE7ADBBB6F7A7A2E6A1EAC999315A838F65B8D9D\n      85F9B9A34DC9B6A30D913C93E32F6F6FAE60F791B9C5B203C25BA83DAE816AA1\n      9CA7E786BCD30ECF127E39ED7DF4D6630F40F5F1EA9D3472229766D53752F4BD\n      A8BB11798382114459C74B34E674C3B0150E3C007BF8A2506D559A816138482F\n      9A73822F99CE6CCEFEE8A77F7AF97DF734C356295FC02A9465749E083B528DD3\n      DF6CC11CFD3B481A6DF4232A4A1336769AC50362F1B4B39D443DB3D3DB3F7BC3\n      36DDC2D1C92CE9A1815ADAB123618D9ABE6AA10F640422287E79B8F76C27E579\n      3BB090F4FA13EDA5F71D1652AEBDBABAB8B2602E6B43DC3424EC284BA54929BF\n      2535CAADCE5714AA49CBA8FAD7F199AFAEA77E5150DA83AA25B27A38EC93CC1B\n      5D67E9D820AAAB1E648FCAA09723F318A24E5AA8547102D9CDD8DE9B26BF0AF1\n      B3242FB319DD3860DA258D964CFFF0479CB13B71B69B7BE1F317668E8DCFDF0F\n      38DE05112263758F936AEEFA7658B973AC3C07FC24A6CDA98B5FBC30CE58B3B5\n      EBD6AAB5C962D2F12EBF525F3E7CAB31D7062690498BE34C4F0853CD8140058A\n      175FDF9B3B365EBB9D662C618991291D0F759A3A4C4BAED7F757C995EBF6B62F\n      9B5AE75ADC69A47611E5AB710432CC9A984B501C34D61DAC556C581D68CC09EE\n      3B9C7765405975D3D7B668FB818F1FC5A5BDC472758DF65F174FFDF74B05B930\n      90F17638D8E4C9760A128D14856BF1305F90C701F77178CBDB266EFDF995B8B8\n      03955CD7263292CB1868D99B8396A04CB25184810240D5D77733366814FD9A29\n      6417F050D3541D4C1206B5A370E5B3572EBFB8AF31AB1FC21F8AB635D06A7141\n      C646A685888494D988DACAC88FDF4C9D83975CC0664D77276DCB213133860B87\n      4AF949E02731F1F59D9D786F575056EA07A11051C9D1C75C96836D9C265C46C2\n      0895E5F478257391CF62DD45693CD09185AAC74F7FF21BE8F70F8D8F3CA4957B\n      59A206D7E15F99A9D13C63799A158DCC42406FF0D2070A138BB9A0CD5FF9CA7E\n      B49B9716BD11763693B4C1556C39D140F61187F1A33ACB13A35012F7BCB3505D\n      0942EE91CCCE624195CF2C5479654DA76C7603A6E6434D6BFB0559DFF66FFDA9\n      03B987ECD48097EB10649CFB87AB4FFFD92584DC35DEB92EF4ADC86F21E54488\n      22C432ED6622AD7A38F0773A3222D350CE488E60F34E622E1B2CD23B8B3F3E7D\n      E7CF1CA50DF1D4AF3D1F5DB0DB2C03E6DBF6E37D66C79932672B22525676A3A8\n      21823ED2F48C8E73BC4C8D7987C227202B6B8F7EF431E13464B8874200424739\n      230010C544A5E9CAD80ADDC155AD7B5D798EF545D68CE20058A36E00A3F43D4F\n      803482BD89692F54F9C6881115FA14277110508218D3A13644F0A415DCA86742\n      543F104E6496A84E994C59376ADAF7FB41534D19B7AB7E4D9428552947664F59\n      8232A162B541CBF29A4A0A6573CC99C0D8A2836377D4AA4BF0DBF6199010E1BC\n      F94273BBE73FFAEB276B8FB224E8126612A8082F662FFFE1AADFF7EFFB89A313\n      BFBC9C2675D09C54CE207332A386724216986619052D3F6CF0E62A11BB4498A9\n      2549D7DAF8DC1ABDACFCC15B116F06A80B541CC81A50C7143E766460DBB65D85\n      EEAA3F5D1B44D16EECAFF6EBC860E3767E42C393C42C117D07ADDDF363B74EFD\n      9BE37D6B876905FC5270ED2B2FAF2C4EE0281EEE44D6D8780F4115EF4E4DCF80\n      4AE8EEEFD67279C3CDF57AC3925958BF7C75FEFD0FA4EF3E9E4119EB021BCA41\n      5958FBF2D5AFFDED9776D63B03EA6E6478B50F5F8EF3381D440970D542DE9DCC\n      57AAA68DF88013996F7BA74BD3D3D3D59DFE7ED20BD38CAEB6363E7AF7F14707\n      9C05F1DE443185E24AB045B0CE94225053A76A9E5257068B4405D90A1D495DD2\n      3E55A92AA1877BFCD966F76BBD5EB0DB7BEFD8E4E1995CAE52417D63B7113C93\n      B69F1E6EDCBE17FCDB8327BEA727AF22FF1D63E34722BF9186BB94D18E60C360\n      A00532670D048D3A41D9D0F28B534F6D6D5EA90FEE3C78EC1431DE679B256D70\n      A3A67DB3BB034FF31D8BC74977E8737C1D6BAF34D7AD28FAE82D07E7B1344CE4\n      C3D6561D96167CD6204EFAA2842FB45F2BD2BF959BC76DFB9395A5A218EC040D\n      DAE0453476D6A45FF2EA37FAFD6CA2624B7BE0674921FFDACE7A2BF090B2C752\n      17D433A6EB024BD3391FB3EE0CF854CEBEF3C4918FFCFEAF6A554D98C8C49872\n      75957DB3E944792E9394A8D13C78295C1BF9297DDF1F1E81384C30EC1F166B5A\n      1475EAC4BF417792ADD71B1347AAB412C81096BCC9694A83847958B3F421902A\n      6AB14DB2FBC416DAD1D9309FD0B855DAACDE57AE4ECFBDF285D727DDE2C1F71D\n      E8D69A20D58DBE0AF904A584552E9CBA6803869A6611011516B9BB6FA14B2F0D\n      192E0449D81250B2FC6696B6A58C32A9C34B5687BACACB498E4E5C46B1720036\n      A3286C35C0ACFC3AD0A8C346D59E1444999CB3AC03A69317B896EF9FFCE919B6\n      E0D166FE857F385F3C5038FC5035113D5D501E014905F6EFAE6D75DD23F33347\n      2CA0A1563076F58B7B728FEB4638BE5C0588ED6C0F86757FE5F84A60B4B49185\n      0640B9CE35049523A3C2CFDFB8D89E3C5C2A1CC11A4D9834548F81A52548CBA7\n      A0FBBAF51BECDAA6536F734F74D793C1566A30668D4951CE743B5FED9B3C0AEA\n      8137747061D22CCDBAD189F9ACAA0704153A59F1427F67E1E1EAE2E9C9216B30\n      CACCA8F2F25F5E6CBE9C3AD9E4BE1F5C15BD1BC2F732C021C74AE2924D8E1A2A\n      CA6AF1DED2895F5ECAC6F6B04A3CAA0167D474A2A94E0BD56C84D5AD2BBD39DB\n      26470DB9A3A1CC510352AAFCB284E0A9BA16D6280F101A0F9F1D3CF3672F91B6\n      11317D43261B61E8F314E8B7A96B02749CC6407D9952393D53952E0932191E01\n      99768AD38E53D6252383DA349B5C2C093930A5E6F7EDDDADA8DD0D09757C3FB6\n      1D83616152656E61A86AE4AB6C5844A7966B598187B8EB5A2A5288976E7DE4D7\n      BF83FEF8C8AC6A27D5A0EA8D6487B234D0B948692ACB2A6784950077A2C4381A\n      DEF3A13B048EDEFCDAF5F61BF0C54A0D9AAC89612309A0B4A86619AE9558768B\n      C1CACCB49DE0CE47F3D32770C83B12BE02D780CF809CE15260A931A192FC22EA\n      279435CFD2DD6BDEF19F3A987B9BCD99C5321B33EA5F8A3FFFBB4FF91B1A50C3\n      55915C4FFC6D35666066B19A54516B858DF2A694FB235637D90857DDEC08C3C7\n      357D56635A3E3CF96B47E63F38A6ED64DFFAC433E2B2D535D01AEF3786D18E6E\n      A9B02F999608AB216252D415C110905F6395942C223A090C0167F6E19D477EF2\n      6DA95B4FA306F581B2EB598A01CE476F90A559428756FD6C10B474814827E68D\n      30883121A60980D7EF76E1556315FE67045C0609E059A2FC50111651980AAE26\n      40300A782C47FD3211176A9451C59F2901A30CFBB411BB56A91437AF2C942D7E\n      A674A1D28BA95A0E32468150A95DB623F814130B863143F3AE96542BDE895355\n      AB80630E6C414D18BEF17C7DBD3D38FDC9BB271ED681164171D18879FD73D72F\n      7FAE2DF3E9DBFFCB5DF89E3C923D0D281A3B80584D3516332B494D159083FA59\n      7B23EB6C2119A8219DD4E457F08DBFBC56EAE7412BB5056F79C427A607CB2B8E\n      553C3556A2C0D04D06DB99A70EB5004F7A38BBD26BF492C090684CC3736EBE62\n      D8A1DC9F7F64FE965F3C15BA3B94E5D81A3BFB774FCD5A769998EDBDA1592C63\n      03797BF5CAD48428D14EA7A16BA854AB75FAC3823486FB4DFB9E65FAC1534319\n      E5A58D9D522FE0B9BDDCF62B97FEE97F7EE5D25E770F9B7BA14ABB838AA86656\n      6926D2147B311359B190E56A13E31ABA37430724BD92CABFDF5D033EFC89A583\n      1FB07249AF1399D429E535771CAB43F7543384A4428C8A214807D88F2A85D4A0\n      09D502CC4B694D86404B39275124D095CDF8C9F36B3B5EFBD6C313EB8D0DBF58\n      1CD3ABEF32A690E93CF7D4933553970F1CFCD685B31F9ABCE511C3C2A43F2092\n      F11C8DB4844400A7A96952CC86FD6E501AFB6E27FCC6C5B55BE70FBD472F1FDB\n      6AE3BCF6ADE9F89F56AFFCD4E489E53DF1A6D5399327F5C1F0C810FDE4EDC7AB\n      2608D08ECA740085431C8C8D28153E1732708D0BAD574DF9F952BFBFB5FFCB95\n      956385521B0571DFD34374838A9745AF4DE4456F389B9FC968E1A5EDAD6BD120\n      3355DF9E85B48A6E4D183914C7F664B1A1790F6A9A6EE08FFFDACF9FF8F0DB84\n      954659ACA7999A1E1C39B5007DCEB00A71D5D5D1BE32D7072054A7FB37275F95\n      86068014A0056D53F90F8BF659DBCBDA671AA908C757DCC48882303233D38853\n      58DA9A612504D85E640646E3895D72064A506D608896B53673EF5879666AFDF5\n      BD68CF9B3939A39FD043DA3633CC2293A482A8A041C9353DC90CAA6B326E9850\n      6F7AD5B7BEDD6EAF6B8E5E0879BCED7BDB32696B2A805AA83B1620D46A1C4B6D\n      B491490754EF301B252DA29191C74DBB63F505E09B0857CA59D35A301D37D16A\n      95C6E99F3BC22B0DBD5D38F3B5556BDC58393DCD4557D9ADA81E047818E67E63\n      E857AA87EFA9A5648B46C5F52FF56F3CB7BD74C099BFB518046CF3E2A068D3C9\n      03964722353E28940D0A151A8EA1D2E961CFDA59EF4D1C2CB9CB998A179386EA\n      1A743127593EE1C99AB77D8D6C6F395E37E3C9B06568E785EC495EA6D2965AE8\n      7189626C02A3A1055C9C66B93933393E874AEAA21B25B8B41979BB72F7D11F7E\n      80DC3A805F4A89E35FCFBEF2074FD782E538B356B3C12A1FD6950F956101DBB6\n      F4139A07246DEC28BDEF5767C8420FAB81FA62A6DC6B88EAC5C6BA328E54E626\n      E40786E66A2C13DD8C0780259272B550A0F882CE048EC00110881C3AAFFFD18B\n      FC759E5AB9EB59BF1D278D9EEC67821909CD529ED92AED30E5B6CE00D3521515\n      9952894AD49AB1ED9A8E4DE239F9F4C0D1292B2F44B88FD3C9618FACDFD8CD52\n      432446AC225D438AA5ABBB256ABB3465286A41CD051672A864D7B4286E588E33\n      740F3CF2E967D1676F5D4C441CF1048FCE008094484C130D41B575099964FAAC\n      6ED9619A9476A74F4E1F7A60BE7175E3F2D7F7447F6240F0B6D6DC4B924668F8\n      191465015AF0162009B6C9E8E0F8BDF6F27D8540B6546B67A2FC09D5553A2044\n      8AA82024B638F16228A617ECF58BBD3BFFDDE1FCE36E022A2A203A20882C7EF3\n      0F9FBBFCD53D8B55D6A4773509000E078AA6322694A39A52E254515024945335\n      CD70CDD196497C8298F3A49895BC53BF79CBC4BB0AA8613CF94BDFE5978D8189\n      3684B7DF8DD74C43A84BF2D4CDB46AA6D938F3258FE0BF477A25A38BBA3D6560\n      2BCBACE5ED873FF6B028ECCBA845038C3C5D9D6FC3A351E7AA1464A86CE3FDB3\n      5E1AE5E30C7793A413C7911A4C026107AC182A901C46518A18D6AD289161E433\n      95EEC6887A02895A231447321D721EDD3C3FC2C03A4646DE1867781403AA8D62\n      98464E326A5212B62251FED02A3E58D9804A8E87A0510CE996A436678A694C6A\n      24A76BDE811579F8365BE1A774180D91B4CEBCA0E2B71EF9E47D9507492C03A6\n      5924745FF96FAF349F938BEF9C39FAABE3BD3CB6341F0B83B947355A92A9071A\n      566805A0C22CDDCD9A97919A8940B103B4AD1C3C9FEE7F61BB228B018ABB42B6\n      877820694CE15B01C8A6B0328728861DEA60E612A6582261C23436071DA95C66\n      23168BAAAEBB3A6867EE1E73EFFE2F8F65A56D7578E2972F7FF15563BBB790AF\n      B63B4344F492E50C9A5DBBE8A271CB0FFBA1EF5527274061BB31891B5D7AFB9C\n      F363A7039C5829707FB6E725BD57F76F3C7F71F3CD9DABBBFDEB315A1B84835E\n      CC03352E1453454E8165EB9A366152A0EB0FB9B98F5A3544F5AFA2E8B9F5F59F\n      5F3EFCA3B68B878D386FD8F99C93693A2BA62AAE9D0BC653A65AB9558EAB22A6\n      407574AA14BCEA905357718344E4B5680E519BD849EDE27EFA8533AF4E148DC5\n      BC5BF7FA837E6F25C8F274BC5329BDBC79E981A583F56B5BCFAF6DBCE381A3A7\n      58581E0C12A31813CBD438E543A2EC8462452178F98936FEDF36576B0BE50F99\n      E5E5903EEF35CEEAA139F0DF979BAF0D934E3ED92BE9B542F1DE5CADAA2509F5\n      352B55F3E29941A433ECF2FDD6B013C52D219D4E7C8326E7A6F59D66F358681F\n      300ABE897D28A8AA2359F6781893EC0DD18BA05CE4AABB425EEFB79238722D32\n      67DB344C0A56DE023DC0036AD0C5A83D7774F967FEF03395A3D391F21D93C013\n      9824DFB769012024326119E34A24A211102A4DA5CE1BD59591BAFC4E8105AAAB\n      6DD5373654048BB6C3C6B92DB7EAEAF3284A0756642A1FE73840D844CCF2D140\n      A7CC7BBA2B9FF2ACA8DC3092BAB677FCD4B235976BB65AE980B6B6DA471E3B12\n      CD3487B4950B8A40F4C8C82F2AC284C36E242ADF55C520A666B0937BFD5B8DA4\n      E1E6A9D610623B159B71D4D3846A600792A4860AD5CDFE28A557C50825203DBE\n      3F6A8F7E10083A0AC6CEA48BD0ACE9CCEA660E807062EFDE8FAFC8725FEFE52F\n      7EE73A29E8871E9CE3BC4B406F4071021449739D8EBF4BE96D8F1CCCD80E4EEC\n      9DAF8797BEB97AD75D938539B9BF8FF7AFA6CB4B4577623084C7C2F591751455\n      868D1C9EADD3DA4DEB7B839923D5FCB21ACAD00005A04A147401BBCA17DA5AB8\n      F656B2B769C531F5707231EE9F4BA2886A391155818C82848C7BFD48E472A531\n      5A982574C610470FB896190091A6961B23E3FCC69A55CE1FFBF8B45970135BFD\n      F0EB7F7DBEFE9D806613FB28BE9E0CD7A2644075A6A56396F1800C2C39969BCF\n      1EFA54CD5C19625946D2CD4C9EE9046BA58C9A48752001C461EDFBB60464741E\n      A0FE92F0A4E568224C8E2C40609547598B8696596EFFCDE6DEDFEE44426F1861\n      374EF606A4A96A6964C8241566AC6129626507CD54B2A1B21691C8D1E8A29B9F\n      34689EC6191ACC2E5767975C9EAECB642C4B9C4EB3B7BFD5CB4431CD8C613280\n      A2A7676E85E62B3AE8090FB896662421F12BB3F6D8940D85CB2B2E3CFCE9A7D1\n      678F2DC2070C7938727806E99FAA6B2ACA54D2124F6BBA3167E4CAA07EF59DD8\n      25C7DEB1589B4ECFFCEBB9C1F5292E9CA6D680F5B4E141F9838F1E9AC83E8CF0\n      ACEBE0AC7DF836EBD8C3133E6D64F0EE4269401552B7E6F03830E30447262743\n      CEB4C625FBCAEB9DFB3E762CFF43796E1B22A28011CC295EFAC2FAD3FFFB1BB9\n      B85A47C9C5C4BB9426FBCAD4C1A4001ADAC8C249DD39482D01660172531BB7D9\n      21DDBB9DB933B8A255BC7BFFF391CAA31669E79FFAA5EFC6E7F140D736D3A0D1\n      89AE9A500F15903832AB685A8140E911D1C86DADA0B105CB99B1982D33736EF7\n      918FDF2F8ABB3C6AEB3ED53C50FC008429127A1A293B27D124AD8BA057ABDD30\n      6A78FE10B88AF20F517B0F584892897E04920C249BADC6D734D55DC1B01A2607\n      2AC405EC57D48FA27E1287D9C8502923894C6F264C648A61ABFFA53737618638\n      4F01B9112118905485FA028802E7F5E0A79CCCAEA6DAA285C7355C326C847BC7\n      EF36E79668E40B03573169535978F9C5BD8DAEFFF8AF3CE4DC9F0ED3469E4ECA\n      F3E8A9FFF6623A70EEFD0FC70BEF0983D4D2339FA2A2340F7362594026635805\n      05A946BAD664F3228E229439037BABD89FEA7F2D683DD92A19F981E60F32D4EC\n      653EEC760798531279B143739E9DFABEA7A29281630A4DA7BA3282C3C476ECC0\n      1B6622CE5906A55A2536FC4A70C7A7EF2A9C6459D841FA54FBA59DEE3397970B\n      939D613F0C9229AB9C78516A627DDC48B264D0EB9627C77B5164868806B13C32\n      6E7EE8DEC4D02CE5C90F9BC62575F2C63F7EE7857F797EB7C7D7B179A51FA429\n      E343917031CCA0A8509BE9A91F9768696C227D8CEA0FD389CB49F89DE1E629A7\n      F853F64C5E243BA4A5E55959776502D276A8AE1725EC6935E89DA9E402143360\n      AACAB099A94E3B66657A52D2F4A1A277DE24A1F339C72C4603F6AD6FBF186CED\n      3D7E68C5B198AF797597B757FD73A5D2A594BF4DE65748F1BFBEF45CE560E557\n      0F4ECFD51B91E986BAC507FD5804507A63A0B02069D2892FECF4FEDFEE8DD971\n      FCCE423E10F29A9B633DFE7EB75666DCCDB323A0DAE28816685024432D712C3B\n      4BB1AD3BC950EEECF4B77AF1BE2FDA61D236791C45B1818626AC2B6C7ADC8E51\n      A46B3D4BA5A014435C5036C1EC5AAE73BDEDFB664ECB972FAFDF2816EC02C99C\n      98171D07E7EC6630704576205729C9FAFD1F78C7477EE7136991C429C86C353F\n      AD0CC940728CD26D339C09AAFE0168814777842A4F6CE465360A99CE8414CA34\n      49D9AF499A0659B2933636C46AAFB3D3CB1D2A9825AE872AC78243B9E3CA6933\n      4643285BE2155F7CBD83016B5CDC4BFDE5A549E7167B27DBA856966E7C637BA2\n      502CBDCB69E437CDD0B58546542A2CE254A4CA4888D2940A396016A769A579C6\n      3CFF74DB1D88C0301B88AEFBC15E1A0E650C1540CD2A2BC718A282B3D529934A\n      D553FD12A3B837E502A2C679D59684B550A464DAB467A991E3746C69E7B60F2D\n      18E309E9BA17BFBD9AE5C92D0F2E4BD1C7899A0A06383371B9D719DE48A23BDE\n      7332D340B2D8BB4FF637BFBB71F75DD399E3ADAD2728185B58B039BDCE6DAA71\n      53E579609A25B19102852CECAE058D5677F1C46471D98C88CAF566BACEAA6E9A\n      00F407724D00106E6FD19E465645FF4216DDF03C78B74B84AE142B2CD336E256\n      AB27F26E655A370F9AB886E2A5B98AE166CC8E651A20CD90327F6DADAEDDA3DD\n      F5E8ED7135882D8177E8B3FFFDACD8A8A4C86AF0D66AD8DB06504A5145D7EF26\n      7E215D72A6C423BF5EB16F1942F5D360F799DEE822BD96110B36BC6A4C6337C7\n      DB6EC69E67238AA41680AAB2F05A405264CA1E051851D78E2321C7DED0D7FFC7\n      6AF3861F985A87F3DD58DF5323A55C6572204016AD1FC01A4F74AC4C6211E8A4\n      0C81CA5D708B63048DDB0093BDF298BD72BCAAD99B5150C099CD8364E77A3B68\n      41B17539E1B126420F99D2A8D9BA4962E048B9A29DA816E4D6D47C293F99EF16\n      261FFACCB7D09F1E59569EDF800EEAB20A962EBC41C02B2D569D199A8B4895D9\n      15D399348350A0CA217AE4EDEEDE8D9D734FF01C9FEF259D06469707A82EBC54\n      8F08B10F0B3AEDE8393DA8D49293EF5ED28ABD942538513DB12369C33535A84D\n      69A46724F4A4EFED8C5D7AAD73FCDD0BB50FD644C9105C47D2335C1A5E37BEFC\n      5BCF4697529FB11B925FD1C47A9C80CE1FFDE7CAFE2105B6414689D18906E47C\n      DC20872DEF18CB4FA372561D3CFC0727720F50D2CC3FF32BCF0567B86FB06D19\n      35BAE1251D3E0D941B69C9ACA4A1829AA64D634D0D583A1A0196B1E858391004\n      937BA77FFCF674B293F84DC3D3718446D3FC485376EAC444C5EE6AD0BE0A75DA\n      0D65D608825E021F42457E409D542DB8140FA1022552DDB469CC465A29E70027\n      A2B0C984A0A6DEF3BD408A012C6CC3F085EC47AAF48689728E27B079B18A7E50\n      E08C47043723F0269446C48A9302C18EE009100188EA0ABCE4E667A81A9A7174\n      4DB7BB27EE2FBB85040903A516A62D26C75F7E1956C5E0839F7C877E4F30203B\n      45E3E8CE5F6CBDF6F7579CF9C2FDBF7ED43CDEC9926A9A74091BCFE0ED592EC9\n      FA0CFE4C5ED450E235CFB070D3D068CC9DD8D9C9EF4DD5FFB6E5BDE999840A3B\n      EB2469A3CD536232C7E228F287315673B609D1095287F12196996558163165A4\n      46B654D3974E5CD784D736EE3975A3B9F88B4B73EF1C97BC8DF3E3E195B0F995\n      B7A6512E20B25B6FCDE66778CFF719CF4D3B1A927EBF6F978BEA7EA93E0491E6\n      DE7B107DF09E484BA03C20EA04C4B07A06BEE1EDBFB8FEB97FF8DA4BED5ED3CE\n      6DEEF7F830A1198B473D8B20E5A230165A6E49F44E2F8D95CBC5AD37AE3F3E39\n      FD58B9540D42AADB898C025B19A1A57E36301B5C50C5AEB9692187019BCB9248\n      E73C97C54C9DF300F2EB31EA54E34956CE0514767D6EA66896DD2C91175EBEEC\n      6FED1F9B1FB36B2470B50EE8FBABBD979DC25F3476A8177DF8B6DB5064DB31BE\n      251D4E33D11A7AA9204992744CD2B1DD3425BDE170175BCF6F6F5768F2AE31C3\n      4D06C69DB75FF4925A23784F759CDAC0DBE2DC56D72422A9A05E45C756CE8C4D\n      11925E2F0631BD36F0D731DA1600FAB04642BF60FA1AA8619C4B2953ADEC02B3\n      14E4FF400255B2723E2BC4CCAF78DB5C3BD7EA47C0EA41E81854E7C178211F61\n      79A55F8F8976D82D1E446EC9EEFEF0AFFCCCFD3FFD612FEADA8621C290315DCD\n      FD6450B9B5EF9F80619402ED5131B642DD148EFC3B7E1032ADB45A365AC80A34\n      458CA99F76D7D1E67EFB5A83D9767E1C2020845A1FC52AE181028E00E7D44D7D\n      07797F775DB4B4A8E0F4C3E4C0ECB8718C5CA3E70EDC76CAFB6EB2FDDCEAF4DB\n      4AF6BD66042F2CE006B19411BD01CC33C28905BB2001CA68F70C6492FEFCB567\n      7B83979AA1EE7624DB0AF91E0FBA328889423F654FAD387BAA82B1091AE5816B\n      DFF7D91E65848EBAB8951EC91132A59B002DC5944E1C6DDCFE8145E1F4CC61E9\n      CD6F9E4325F3E8E9C3B1DF6469A8C2F924D371917BD955BF79EBE3770BD164B4\n      D078B6BDF9D4A5BBEE381A63EFDAD5CE4465A95CE4A9B1EF2B1F723B834A0044\n      5FC02A634652DABCD6EF86FDC53BA6727306A870AE212094A46089A0CFDA89B6\n      4D2EBED2BFBE957408BD18F6D6B4149ECFBCE9DEEAE60A7EE4F50757989708B3\n      68171773CEB29D15D2687AB296B2C8B0231599C035C798EA0DC8455ABFFDC145\n      F776D6B29A26327BCFC667FFBA554AC60C235C8FEBE702AD1110008205AB5345\n      878D4AF4C02FE52BA740F35B5966486BA8DA2FE5780A2F8DA574142C908D9211\n      D4B9A86293EA822753137A6ABA46896BA95AA810D78624802552DC2BB5FEE75A\n      E785A624E62E4F6EF074B50F8428B340D0E998948B11D4DDC180C3B220EA602D\n      1BB523D4289DB6CC31860C2DCAB9F4C0AD656BBA1D0446CCA54D2CBF1E35AF85\n      DC5769C03196431FB88C91B79841B88D7CF850E333D34132680F76A75666F9E2\n      C1D3BFF555F42787E601D2639082502E541BB4A6DCC33380AC91DD356006C679\n      CB5D02A4CFCCD4EC1E79A75159C8BFFAF5DDC1798364768366D762B1CBC30027\n      5CC74B213D50C8955944F5DE3D8F1F2C2CF104F7350E85138050357FA8052529\n      89754DF3054B87F5EAF9573A07EF1D9B7E6F552E1484B4287C50969068E2B5FF\n      71E1C23F5DD3B2C27A1A5F49D335CEFB1A919A1A1B540380AAF946B9660322B0\n      144D1BC64173702B73A750154D7AA7FFEB6DC649A4B7F22FFCC60BBD1782D871\n      7645D4E80D2EC0EAD290AF5CAAB53226056D94D509EB8EA72CCD664DFB50A130\n      A61BB4BC7FFF8F1FCBE63A49D03106188030E25C69BB98E098325EAC9FEB0D36\n      826162085D6F43150B558B9889A9AE220ED56F98A8E32096F8CA34B062E93978\n      A5EAC238A304504DEB45A12FD3811009A36186FA2006308E450CAF6B847923FE\n      3C6A3A1E312B05FDE928507B44A74193180A63E3A466B019A64F310BA42DC1C3\n      A965B4744B4EF93782E696F059DA59507BF5B57A47CAB7FFEC7DF45410D32DA7\n      3D7FFE4F76AFBFB23FF3EEDA6D3F3DA7E5F6A918976988CCC9D459E1A689D296\n      A9BA90721A0F82D619CAF731D2E32CA7D31EB956DDFBEBED6C1796229463DE8A\n      C400CAA4B295A6294983304E3D364C07CCC4A66EF04C864220F8ACD480456F60\n      22A208B678C955063B135E7EDF6E577F62FCE0070EA4B8231C17D5C9F53F7FF6\n      00ABC4A656DFDA3B503B28FA7E2BF3CA8B2592C9A0DDCA95AAF0B4BDB53A4E45\n      EEE1A3D9074F063271628A683EA44CDB16AFFEF537E255AF3B40DFBEB1712DC3\n      CD9087BD6434A4A9F992C71827207491B12CC9E1DB16AE772E3DCE8D4FEA0B93\n      0CB7414D60C43CBC87D16E16A581DF40C910EB5D6C0DB821135CCA8C126CE8A4\n      C7919741F1A7088A88898D8E012F0E78359923A5292797B23851D3418C0FC289\n      83C5FC0268699F79967F6EEF494C3F170FE264F870CE9CF09C596B166A7528BB\n      C4A4B94C591FDF48F8BA072A5FFBFF987A0F60CB92B34C30FDF1D73EEFCAFBAE\n      5275B5F72DB5A49607212184194130046207378819D8DD89985D860566779960\n      2016CD32C20C6218564220346AF916ED5B5D6DABCBFBF7EAF97BDFF5C7E7C9CC\n      B399B79A882955AB3AA2DFAB77EE3927FFEFFB32FFFFFB46426DDB60F75CE3D3\n      F3D3F7229192F21C26E76EAD1E72EC8776EFC9D65B9D61A4A6A8312176B047A9\n      05BD2482B7B6C32B9B3BCBA3C110C394A0BED4928A4C0A7299C89BB92C53DC14\n      ACE1FB9E4F0298C16428B4BAF52C95884ACEB40E492DF7CCDA663713F3CDC90A\n      042E2C5399AE64C391267D357F1FF517386ACE64BFF0DBFFEB9EC7EFC9786221\n      020B2D4F5081C6C945E6B0706CCAA265A0B1B1D1D55C20F3226B2014065A4CF0\n      B81C473EFCD3FC3A2924D714790893EDF8D272EF4A7B71CF5C399573C8955E65\n      454261A1918C330FC74CFDEDD5D1F524F56A592A76ED6EB27DD94A7D657ADF7E\n      A735B9FABDAB80658B8FEDC967B93906261894B9349ED518725BBFBA1CC6058B\n      50A945F44CBC9C2D7FA537CCC020B7B95D5B8F473B2AEE151137AB4D5758625A\n      514081880CF473C7FF945038B66193E3D4F8528900EA12EC2C596E55D0A9933B\n      A73EBE3F675D6B10BCF6D4DB64CA39F1F8913CD4AC46578B5C2F081BD4F39EDC\n      84F18127EE32275256D07E697DF5E96B77DFF55038E8AE77BABB16672D3B5138\n      8AB41484161DEF254BC589A20E9FBA767153D86AE964D39963237D61BE5569D4\n      25C372D4A71B69BCACDE7C63B0B299250A6E44C948239289956575E3CE676EFB\n      1A28132E2C42661CBAC74633169E9B6920A6CB71CCB0E639D07126328EF4ADD5\n      0F77EE8307C47C51B809ED56DFFAFC8A3C83F7D7DC8E1CBD1DE16B1DAEDF97C9\n      E9B456EC566C70EA336CCFFB02006C406C610D74E921AA21A1AB9786310F43CC\n      2408980DD2F16F35DE1FBD1D10605C0F4569066E345BD2322FD4E068E793E17F\n      5FDFF9DA32E5F516451755B69E97BCC092E78A0F53130F629835302105D48442\n      CB9294AA8AC89C06428BB840040CCEEE71A64EC85CD1ACE058429AB0FECD386E\n      1748BF67080D4C25625AE6232826A0AECDD276D9FCE2ECCE6023C2DC39F5C093\n      FFEE1BF03FEC9DD73F28D3B55BDF7DAC0BB90991378654140362FA48F507B15C\n      F76041265820E1C0D9179EF8E0C1783D79F3AB6BB65CEC01B109D3D528EFCA32\n      F68ADDB9B3645B4DC63D9A9D7C6CD7CC09D0CBD72CEC91822269CCA595C4C67A\n      BBB0B5F28354F47726CE9EEE2C1EAAECFDE8143EB5A859AC0D8BA21CEA67D77F\n      2EF987DFFD16099B3B005C4DF9B2505B4215188FCFACF58D34737966A34A95B6\n      420B84ED65833B586D0A04F63EFEF06F1F47274B3B9CB8F45BAF2F7F638B5BF5\n      4D990EA2E139C41200C271D05F8050C3E44EC0F1B88F805C4E2074C0F5165C9F\n      FA9DFB3F73801E888A74E88404662217E6141E66A5A5B5EC20587DB3530EC1A8\n      302AB89DE7C34258CCD64048C68D4DB90622C72288F090DB26D38300A51F8979\n      6128B3C2340D8B22924A7F57A8CC566BCC0B05B1867661FA7C8551E226234D3F\n      36A308C7B9C4E5580EC2DBBD6D943A9AB9509E2DF86C12E139AFA661883AFD77\n      DD37EB350C392FF41BA1E529EAF3A156846B21510FFFCC5D8D2734687593D3E4\n      07FF7125CACB87FED51D130F6A99DAC7A20134B9F017A5B3AF2044C91D1B4024\n      6C90F4A2DE79A206B07414A93885C85E2C36FF61DB33569859AA5427E691C104\n      8B522234346A240FB1B1663457481123A11423933C688CE87DC735B9E56539EB\n      B924E733B1D70E06E4A3DE9D3F7D9F7246B1530679E3EA7FFCDE020F609D6DAE\n      6DEEADEE1549BEADFAF55D4D1BC36CA7E3380176FDE8E67691A595F71E571FBF\n      3742B99F332D86136A557875E59BAF3EF5875F12857F75945DE1C57A94171CD8\n      C445C84A8DB566360823CDF3ABA8EE33D094A37F7DE7E22321A9162073410279\n      21D95A2857B9968745EECF9F696F9D8DE36D0073210281761376A85699B6A8CA\n      53A5BF143A601CB3D5AA8A014E1B7169CE542DE0626B024CC45951698A3B67AD\n      BDBE37E0E4D25BEBCFD583BFDD5CFB28F57FCCF7AF668397F46A2EE89CAB514C\n      109E36A4A3892C2C46BED6F5CDD9B8D7BFB3E91F99C4966F6D40E7BB17AEAA22\n      7AEFBEF95D92F457D20C33B48F59F54A8DDA560AD77BE1D956E752BBB7998B84\n      1106B0278C63B4F259AF5FBC12F56E08739AC9348FD6FFB34AAD2117B0990B24\n      B6AEEAA90DA199E3B7835BFDD1F55EEFF0DCFC142261BB1D62D9F5495FA4735A\n      4CD8CE64490EDF37F1EB7FF0EF65C3D53086F978500C4341C67BA2C6AEBA3451\n      030A14C631B03483D563FC1B076B0AD32600C71C0FCAB1215429CC6EBA11DA25\n      EA8BE58BED17CE56BD8677743E063B4C695AAE79276699A56927062E7D6A79EB\n      B5AEA49340143307AB6857B4167466F6CF33502F6E24CBCF5E5DDA35CFDE5B07\n      590E510C09D715849415D35262B2A41341CCB5B8164559DE7DB67AF9DC2D5934\n      4ADCD818856D39DA4AFB892E90FAE14132D6839944A25AB812AA779C668C5E34\n      3CB630A68EC24368C9F3972CAF2A7070AC7DCF27F716A4677583979F3AEF2DD9\n      1A08F9B0AF355249D238CFECB2D15F4976ECF4D807EF1360A097FFF6F3CBABDF\n      BB79EF8927D757578595CE2F5A008CCC7907F0F48F611201632F9C12C59C6CEA\n      DC5B2BD62CDD7DD704AAC3A12E9A9355BF59CFB9C877FAEEAD51EB9278FB6CD8\n      1B986DB6C204D87B424ACD46312B3DDF6214859A4611AE159A0F35998313142C\n      4D7BBEA7C1361D3F0B60BA323571C095D6CEC59977ED6A3C792276D799AED417\n      83737F7EB932D0B223B81E791D8543BEE5B8D914DC2DC160DFC7C0F11F9E31C1\n      88FAAFF63223D4CA9A4236A0267B49C1DB6179BAE091DB263E6367AC716AC2B8\n      335799AE197DA3B3DB2EED1A07E439BEF9DFAEC36E6D45CA37796FA3D0C5D6D7\n      60A4E4108A42EB08ACEB92FE6CA65746F12CB33071316A323AEFFB4D0C2B08BA\n      9562E911073B342E92222DAAB8966FF1F6D51DA83FBDE50FF33CD6C2CB481936\n      6F699150C0229B9B6F921AD90C3B5BFEEC4FFF9737E11F1E5A307B7E666C45AB\n      718DE8C074F5985D2C4A980658CD5B0576EC03D2AE21145830219DDDF756F71F\n      9879FDBB37A2F5BA16B711C96F0DD34D0EFB2E9F55955904A6A9AC30B5E778F5\n      C0C34E6EED801C5361697A589A3E15A30895D09F2C214844E9DC9957DAFAD9EC\n      FFF04CE5894319A696991A0801F164CBFBFAFFF1D4E82D286CEF46648070998B\n      D0B424E97F4C23B3D2E51B6B22875849E695DA6FA747AD4A4DB0E0B07CF4774E\n      AA3B4A279D6AFDD1A5B7BE7831C3133B653E4AFBE74A1696606046214C73DC04\n      46BE693ED53A4C8B4DD900702FD177CAC156EFBECFECF54F68004C9C2106B928\n      446182E053E9A64EBE69DD3AD3F3A417216BC08B5BA361025025A8BB9842CEA5\n      892C97C82240962855755DBC899045AE1F61ADD2D034BA1BC62930477CDD34EB\n      A669660C138CAD36D4FC5ADF7B29C6298BFA45C21812333F014C068CE94536A6\n      67C6854F43AC0FACAA52B30E9AB2EC0A653CDF99DB4B0EDE310188D63FA6FB57\n      63320349DA9B7EFD95D5D4491FFBC5FBBD53422F97E52FAEBDF1F79B33F7EE7E\n      F873476473477F699132E43AB8B24BD105639A0B0616D47456CAFE4632BAC94C\n      EF8E5EFB36DEC69B5FBA595C2899B1AC4F35911CE526BEAB34BE904C2BA130D3\n      B78B555C2D0FA53155223846AA97A7C33CD3BAC5716DD3315B14F3AE3B459DE9\n      985E07ABEA09E7FE5FFC80B4FA915F54CA89D69F9C76B7B83313EC6C7726CB26\n      A4743B6BFB73D5C0A2A2D7D7ABDDAA37F9663F198DDCC78FA14FDE975265A5FA\n      F939B9EDBAA20A37E36FFDE1FF77FEF4D5B06037A37C231791301DFD428050C8\n      9EE0619A68C1EE13EF30F39F6C54EE0FD47EC61BC2D8D67700DA2CD28D240BED\n      EAB62A9FED779687C355CD029D31AFD56554825DB6BF14D45CC814D7929941CC\n      E68A785857294C2A49C1308A594905F3123F94A58393FB51F1EEC5F99E8B2F5E\n      E97D93A9677B9B9F25933FEF05BD7DEE9FE63BEBDBE90F1FB863828E0888ABC0\n      A9DB734D15732ACFC76AF9AD4BEFD9B7182CB8373DEBD96BDBDBAB9D07679B0F\n      4F04E95A7B25A5C40B4E4ED94E738A17E5E556E7D5ADF6DB51D2C1FAC9E12981\n      2A121716BEA1E20D99DEEA49E396AB97F1780AD244C7D9B8CC332CE004217B3C\n      7BCF6C759CD268DB8EB7DE1F6C0EFB0DCF9BC3164C8B21832D566A2A315996F3\n      A89CF59D077EE29E9FF9AD7FA35F65E34F2D4D8365894B89C775CEC0A2993AD0\n      64BCA0DC4CF3298385665FD458079AE1FA774CCDCC4882D96DCC016726FF5C8B\n      C418766E94D7AF6E5FD99CD87F18D672A836B53E973220A9CC8CB799CB5ED85A\n      7F669B8059088AC9636ED2EC8F26C4DCC97D51B8E3C37AFFFBED742DAE3D31E7\n      4E698AD6D60211080BCBAA117144ABB218404F5F2842210231E8DC71F9B94BC9\n      9625123F11B0C5A34D6EECA11245B4D2309D745A0CC3CC911575DB7666BC16C9\n      78A3CFF4812A7D5968C1721798A381901E6EDFF7893D25EBDA3BD557BF7BA97E\n      B8BEFF9EB97C1853810A9A08C05DD0DC3A3FEAF8F9898FDDAF982E25B0F5E2DA\n      F2B7D6EEDEFFEE95B5E5E61EEAD66225469A280A680C0A6C65CE69044AB12EC6\n      D1F49937AFD70FF97BEE9BCA68AE1A8E3D532516CD4645D90A9DD5B47D26B974\n      292DB8019E14FA3D4EBBD13057515075AB0E05795EEA958B736A8E492813A061\n      9593153955D772DE38888F8D5D33CD151CBB368A3A3BA33438B267F1470E66E4\n      A616B21BDFEB5EFAC615D10DB075B057169BF9755BAA59BC085134F9507EFF3F\n      3B54C218D80878A66B1F025F4B989202E37F654AB431FCBAED41319EADD76BE8\n      B68FEB78E6547323058488D17870C56CF8AEC873FFEF9B64ABB959E0B3C5E05A\n      186A8E013145625841D8278142BA62EBBA8799D937D6DF2E09862E82D3AE3B8B\n      E98456A470B4F090579B66890C0B5E3AD0B339D9B9DA2ABAC8654D01D540643B\n      49A1903749990D848D789A74F6DCB19805F61BDDFCE7FFDB05F8C7C777E9226F\n      7C314D7CBAA530280A336BC7CC4741991099466242CCDC0C2D7D051984AC1E9D\n      7C6446AFB0579E592F23572B9DCD2859CEE43692155059F0D01C963E282777E3\n      934FD658334C43C1A48D4AAEF9A290FA5611CD096C33E5A375ECAEF36F0E787F\n      FBE00716EA1F3E029A3514C650C6DC61844E9EFD8BD7CF7FF196E61A5B915C56\n      E86A2E7634BDA50C8D4F5F0DAF40A549375670499507BCE218AB68D1EA1DE28F\n      FDEEDDC551E80F2BD15FADFEE03FBF5DE0F92EE2DD68EDB2F2FB4AF5014EB53E\n      13AA0E60808DFAD2B4486BF6298435D55ED03CC7494EFDE442ED6E2D82527B08\n      40C275A1CFCDD668E9E57E7C036E5D8C02E0B50BD9CBF86A14460ABA4E2520B6\n      6D280ECF405612D3A35805AC815D3AEE6E91AA6C34A67BC3789415B12A35D56D\n      C749374922298CBBAF998A84C644CE9CD2C2B1D53D300672E615321DBC1A1ECD\n      AE09187BB69A68506BD1B5A728ABEB8591F42B4D79F4CE89A031FE02D3A7A215\n      A6BEE7C56867E2E2E975D8148FFC2FF7F185A1D5F6DEF8DD1F6C6D8BFB7FF9E1\n      E68312B048C4269D9604155AD905CA690DB4050AA92E9C71CC7B3745DCB28985\n      4ADF58E5BDC4AFFEC3CDE97C2647514EF23CC289B486CC1C27DBC8CE78DE4B63\n      507A848280501F107DA19A91874057F73C4933470B418B94D23842CEBBDE5EE5\n      DE942BFC11E7CEFFE963056E4795AC26AB83BFBE08AF0FDC297F3088DCD475EA\n      D5F66843EB048B40986546994D4CA7DBC37818068F1DC11FBF37B7A01D1A53AE\n      C2F380B4EDD2DD7AEEE25FFECE9FAA980C38DA29D1CA703448B59A479D30EE6B\n      324F08E4E2BEF9853D02DEE354EF61E8A0066B1196C1748FB3EBED7687C15EB5\n      F1F28D8DAF663B686C50AAC6BB3B7AA133008DE7B12A5D805C0DA79AC75B7829\n      57AE8F2748AD5930BD86865AE5388E52D64E9C6A117298D12525AA0E0EBBE252\n      853E977616A1F59B870FF871FF4A603FBFBCFDF0F4F4076AD8038358008AEB20\n      8CE2A9DAF7E3FCCD8B571F39704062753649D687E95C863F343D3701E495EECE\n      E53C9FB6BD9F98998BEACE0FDAEB2FB63A9B9C867625157C41C913C66B81BF45\n      B25779D22ECA7064C7669E9D980674E3F00B8CD7BCC621B7CA72352DF85D0776\n      719256131A61B095479D68B050AF5538484729AFFA6D257BDDEEA166E58E6685\n      8483477EE5FD9FFEA55FE0FAF59366134F4B0A65120EC0D83FD738C2E85FC6C5\n      9568B561C28DE0B85B70DC2F63A67ECC64219463D4345AAB34792E39A418E705\n      4A5A70706BF5F45B30238B27772BB89317D256955266A9CAB5E8A0E786EBDF5C\n      F3B259A9F1ED00195576FC634DB4541915BD1A0CE096BBFADC55EAD3D98776C3\n      CA8083082AADDC7DAD1F10D3F533539C4193C2A95765568A89E886B8F4DD5B56\n      3CA9C9705764ED326BF1A29F83DC7C320384A24C306C1AE76733C46DFA8509B8\n      3D526F6A4580D01CB366895515C83E3ABAFBE30B9075F1BAFBF68B2B73A766EB\n      7B71194B563A390E05493D51DFB920FB8DFCE087EE94B4AFF161F8FAE8E297AE\n      EEAAED972499D9EF013A042A29A1CD415DD73493F75E941C4504D8622BB87E6D\n      6BFACEDAFC5DB5B08C9DDD3378CAD177BA6867702D661BD9D66BF1FA0D694396\n      42B14CECB77A512F1A4E3874B15A6B6AE4D68491A20AC46E093C626B4565113E\n      51150B530E415A71234531A285790EC8214C0E7692D6A0587AE270F3513FB306\n      96A85CF8E6F295EFB4DC649E63B2A9B66086E660D334331E1EBDE7E78EE33A2F\n      355D61866200FD3E605B195F48098903C663E9E6D518C77C94EFFC3106C3F14C\n      E938504E486E8C5C74FD666DFAFAE75FC9AFB06E64AD2175238D0AA6AF1AE222\n      B6F42391D0F8299B315EE242C24A40A9391FD3E5708259F3D89AD3AB11C68DBB\n      E8FC5E5B8048289AA7B242EDA25784370A1051C7A3A1CA36BABC9F10CFB29A16\n      0E740D1583EA04F3F74F6FF88D0FFFFBEFC3CFBF6B49EAF76EDCADA44C7E88D9\n      0A0752AB1AA5158A30B1B1C61C74DA52814727A03F092A40EED48F15FB1F39F0\n      8367AFA7CB16CD59378F568A6239D55CC39DF7E102510DC2EC7A72F871565D12\n      3287960642904B2DFB1531B64B25F55456F234470BCBD765FBEA95E34FEEAAFD\n      D0113CD744C30C8A94FB887AC1E8B5F095FFF3ECF6663F2CAC35C02E647C2DD7\n      AFABBE0D86E016633732829005F15EA50EF8A506C24A89ECFDE123BF73AF388A\n      83815D7C273EFD1F5E0DF9D48014DD70F972E9F765D9C33481A4E4DCD35848B1\n      A53FB596A179364DC961CB9D03C471C5BB7E62AA719F5E44FA9528CD70B27E68\n      25A41CBAB937D46FF64DE928AB5588A1285A5AA79AAE5EAA5F6A8F11CE93A44C\n      35D9D5E27D927993BAD0C164BCEDCC08733BC35873B07E2E7284DB49124B156A\n      DA614059CA719F3640E3DC5D43470D7B22868D98F423AD144DFCD3F8557234C9\n      D08CDEA94C3387EA6B149D03C7EB0BFBED12A60A982C66A32035D12BD1CEBA77\n      F3F466F58075C76F1CE633C27949BDF67FBD51BB73CFC1CF9DC8EC6B448882EB\n      35EBE26A5D735C50D40DCCEA7B43A518B545F73AE411439E6635696B6BF4373D\n      7EB19C623321EA0A4BC8D80B0BDAB3F2B414545A8571D6CE941667B8F420AA18\n      F37DD32F319E76311192A3384A4D291401237395DA61E074E9567ABF77E49F7F\n      985BFDD01B35A41FFFDD757EB61DCC0461C251488246B53BDCAE041A8BB5F4E0\n      C32C0D66E6E2D630E90D279EB8137FE4CE0C2B2F25B074B96367D8B60B6671F7\n      A53FFEEAF35F7A3A1EC9C40D6E2471A750A980DBBD5157CB7A04E6A173DFDE45\n      BAB1F1D8E4DC4964EFCEB300F041C02E42B9DCE719F2DE4CA267069BAB846996\n      86C70456E87FF41B06B0958B3A00A79AE4F02EAFD610C8CD505BB677C0A81DD4\n      E0A46F59198E462CCD2CD1093501D034659226B18BE31CD314A041109CDDDE7A\n      F7C4E4632589217DB5C86BD9E05F2C5516613644B42C5C5BE04B81FD85D6EA6A\n      273E39B970B3BDBDEDA33D8DE6C14E3CABE92DA43725F77D76C4724FD8CE32E8\n      BF325CBF0531C4334D515B9062D6EE36A74239590E6C676B87C43DB81DE16BBD\n      E8A650DB5C50207C73FA5F4686F659F6784761EF42530B887D6D41F62CBCDEBE\n      298058AA54A87E8CD45A0D938D3002183C7074DF1E0B909DAD477FED239FFEE5\n      5FE04299217A44CCD83C2A0D83337EBDA5C066F79E4AFDFE1AA87D67DA604C58\n      0D9898AD5163C006C7D0A2BF40174C936DCC64A06B80149C77C2CB6F6467CECF\n      1F3A92371CC173CF1C7FF0D4F4B5B9785D6E7CF94AA557179605670A341D050F\n      CF0D835C5F45905100BCCED9ADFCAD68E2812A3B80B524D56C4E2F03BDA4D478\n      121EE57CDCD7CAF40A1ED8FDC668F6E6775BFD0B192DABC3B2E800B925643B96\n      69A1A5B22ECC1A0853459BB7BBFC4D83EBD8907B6C1456625456099D65F61CA6\n      15CDE6EF48EEF9D80CB4BAF93572ED8DF6C1C7F6A8DA90A488C26A02FAC08A59\n      56E95DC0D952B1F8C4B1820E0961D19BE28DBF383343ABBB0E57ADA6A6069ACF\n      A75AE314A0662C3B35B800AD5B47143A836BB0DD4A961E9EAA1DC426667AF78C\n      D02AB7106A3D716F15C5FAE0E69B49BCE94C30A7958F5EE2F9F38350887CAFE3\n      EEB1AA0BD4C22A1906AA9A10DA971563ACA49C8AB2ED6466C2A51415E6B9949A\n      62EAA292001FD341056096342E0F07F31F3FE0DE5D4A3A52DB74ED1BADCDA7DB\n      04357B0CF7E26C525A3693F94CE7B19F3EEA2D6A45930933A4A2E90136D9E314\n      61220076C621F3F49DC6516596FFED6475D376325E5366DE9E17FA7D4845A6A9\n      87CB2756FEF65AFBC5611157D7B95A5769A7C83569F04B901579AC173F316EE7\n      44734CA9D51E61BA6223A17176C2B276537F4610574BE9BDC981E31E66B92CD9\n      28CE0852411924CB60B49A7B146630ED8664BD2551C0A66CBB026023C099683B\n      BB0372F2C4BDBFF175F89F4FED965A9D161AA9CD705086A0B14133914366E359\n      BFDB637F11C0545FBFC48B95990555736492D4D78E7D74CF60506EBF2240970E\n      E4F05699AF8CEC0C9A76F7050AA6B097A8F5BD0F81A3F74FE862C924C3A5C9DF\n      342CA234B9268E4859291338D3DE66D74EBF79E4B1F9E94F1D5733554BFF4CD3\n      3555941674FACDD3BFF7E6E5D39785AC6C21F75C9A2EE7792CC73E05B73BB221\n      A204DB10ED52C57EA73CCE9A7504E8BEE143BF7DAF3C4683D897AFA333BFF5FD\n      8DB6175139CA37CE17764FCA01B153CC445E38A2A822E4506CAC238B6C8ED0A3\n      AE3F07B185C5D11FAB4F3E0C65165B7D50A626B683EBB59D99ADD1EE5991AE6B\n      194AB6B81829D9112A35062F9068494E10A19A37E484695DA61A90CD5A81A2FA\n      FB73DFABC4091FC43C83B49B168342F4F2AC2034CE332D35B3829B8E35831AE8\n      9DE0ECF276F341894C6FAC7E71C56D5F60FD2535C266195DB0EC49EC1669E437\n      E581934D2B30BE0940D1925A1C6AC257F8C05DB90236CF740E3D3637FDD989D4\n      CFFB7FDE5EFFF2C6A9CF3E4A7FD42BF8B21A15D46B2494D9D526B5A641EE995C\n      2B26202DB2EE5A3958213223CAA5DCEB5DBD3AF8AFC31A9F71B11BCAB6E92ECF\n      1BFDACECB12C511C99C814986B36AD68663206B9932BC71C3C6AD5A0B50EF16C\n      6F100D07459288D8A268BEDE3CA48543304AEF768FFCCCFB792D1B59DD06A8A9\n      AFDFEABFB23C31DFD4A528DFE1412D18C51DDF61B4E22A91B74683CAC242B233\n      8A7AC38527EF051F3891CBC2D7524759DC6619F1901930AAAA33DB5FF8D7BF3F\n      DC8CB78B72B928D6D26C7B94271CE815CB013882E8FD274F95172F3CE2787B3C\n      7F06D85349B14386DFB187CBB88E06B567DBD7DFAC6462E413AD6D4C979B197D\n      35B1E5259A02E03DB3C1BF78FF9DA7F653CB1EA21907B4E5B95BEA1F5F1BB557\n      4A0A498ED248B60A35C02E561A7742CF75DD3ED9D9F15C3B2E7D5CBD31E47694\n      3CE4F982B0F3FA6FEEDCFCD985E064CD45AC9AF70B2F23AF58E22FD256398247\n      58F3D99D75BEBF760725F786224CC58DA011497A18D26034D0E4A42D5A3D9CE6\n      C104E2C1D1D4BF1F89237711F7492696CA3AAF800B505DE7A75BD16BADD17712\n      FE8F834116A554D3ABA22C997E4ED841361069D50114CA4F913DE7487476D49E\n      9DF427212318B7A2B4ABA935C01CABF980ED26621790F7FCC27B7FE6373E97E6\n      5C5704E32A8FC6417E72DCE0A54B9A19B585664B1CC4E3C8ECDBB622E3BC14BD\n      DC812891699F31FD5E6AEC1CA851D7850988FC28C2C45138936B67C50B4F131C\n      88FD4721E216EF290B1B6E25301AD89B7F7536D80E941BA4415CD92BDCF7CC67\n      D320ED27BAD04307E62148BED6E3F351EDCE3A6A32331F687A2B589A0AA23FB1\n      3261A282BBAAF487F55BC168C65EA9BCF2A5B77DD8CC316BC97C5BC8AD50461C\n      8E4DA3B3422539698EC3D0C65152C0D8D442A341CC7FAF32B2E8980D642F07F6\n      E1F0EE1F9AD640185D44EB17C3234F1EE4F6264CB504F792B287BC02476EEB6D\n      484EE2E9870FE7B283210BDF1467FFFAE2DEC6E4D2098DA49A34D0B28CCDA92E\n      A9092DB5D3C2C124945D06FDCD73591497C73F74002E269A68C1F9A63002B7E0\n      5707C19AECDC685D3B13C1E1C434725787DBDF1E0DCF63EC5874578917B03343\n      AD528571B598C96AAC5BD6986B6CF77C0E61383D197855568CB7A92D82B5101E\n      E2A6E50F3C3E64A13F2A1AE7E8F6F1CF2CC1D95ED59E02372BFD2F5DB9716620\n      BD850DA1EFBD2424EF051B8FFEE491A9A3B4C4B960188D7D0835508D8150AA31\n      101AAA3426C163F987DEE97430CD32723C5B51A242930C2120C792A02858FFFA\n      4AEBB9014D9B1B51D1226035EA5808D7A0D5CFD3817EB530301B6619D7D8E523\n      466D2D490A5D609A96BD849CE91C567C1A375AC7EFA93875FDC16C6E06D6629F\n      54D14EA57F7544782600CFCBFACA9618E1B4499C3A618109F4DB21B3B4FAE8FD\n      F7FCE6D7E17FBA63B718E7DB8E2D859171F53226976677DF5C30C1B7ED72AC3C\n      D33FAE5A73661D112496FE48938787C74E55AF3FCFBB376752D6DF022BBDA876\n      4DF99A3AEC2664175CA232A333371FFEC4616E6CB133986D59C0D654AFD06C4D\n      F3835C0922B58C95B173FEC5AB733333FB3E74043C369D560B2D427DC5409E95\n      35EFEACB2B677FEF1577ADD153F64520AF9562990F873895185AAA46B96B41E8\n      32DE84ED5D3478102F4D694C3FD8BDE7B71EAC1DF3405EE45BFCE9FFEDEBF8EA\n      24281BABE9CEDB301FEA2AA7215FBFABA6DB4658D8546B1B230FA0DD16DB43D1\n      2C635ED698F858BAF7E3208F5A2C7445346EC533D66C198A697C06A4CB505F7C\n      1790912A37A288381593E89E498C2073196350C5A32623138E636B90638945C9\n      8457EB6D0D06110F111E31BA99E4DB03AD04F4D328E53875B0D0EFA4398F97D4\n      E4C843138C516AF50C30D602787C2A6A56A9D4327D0635677D3A6D211B0A2187\n      7B8E4D4CEDD6A43D1A5B365800138E0A49B857AA8DD72A2BB792133FBF587B7F\n      A456E05BBFBDDE986EEEF9CD2099DE74FB4BB86826D56E5A39D5643E28E392E5\n      51A1156855155DD1BE544B33A32B5561A5935B5FBED2784DAC3F2AC849A7FCD6\n      D6FC65FDFACDAEC1ED120CF2020D61B5286D2C0A0193B4A4E376692D3BF4BA40\n      6118EACA5A09020C411C26D0348E01DB71E791CD59888FD343FFF2F1B8D91F5A\n      5AAFD6C073ABDB2F5EAACFED629A26AE77C87463900E1DA8E84C032682F7437B\n      AA3E48C2300E77FFD0E3FCFE43E6082FC18059A9455D311959D2D5AB3B65DFFF\n      FD2FBEF4DF5FCF066C1358AFF1F84AA74D15F124AED76B20E93F72F08075E3E6\n      FD95697BDFCCF5D6E6C1B2E2DBEE53C9CA55927B09B9BADEBD614196D312901C\n      F092E9826DE2609AA07E7760FFD27BD8BB3F26E2A532DFFDC3B5EACFEDD4CEA3\n      E842FED2D39BDFBEF4FD57E30BA3F9C9B476649466D9CEB51A6C7B6E1E8F263D\n      02B9A3976166B175B776AB3798CDD2239E560CEA427FF3C852F52E3A6DF721F5\n      71272A2E59F46D3BDEB9B472FFDCDCA57830E5061F620BA0DD5A990EAFCAE151\n      569DEC0761E9ADD634436EE9B7771A352792F8CEF9E1234F38D5FBEA7CBE16DB\n      7A5DA46E34509D8C5FDFB7FAFAFAE99BE95737D2A7B733A1F1731C53A40913A7\n      4A3F91F9123FB4B0A72ABA17BBA383F5FA71E6AF0F46AF88AC0521A15617883E\n      2FF6D3E0FE069BC4BDA39F78EC27FEEDBF1A605DE9B0576262A6618D31B7413A\n      3876E23458A1FF3FFFA73CA3DB3AC08C51DF1EFF298DBA56E3698A1299786E69\n      4C244C57A006E8848D46C96B6FF76E5C5938B6A06CC079C62C0B18FF5D598EAC\n      EB7FBB5CBFE254B1BDE1751AEF9F0BEEF352DA2943A48B8096A8390CC599247B\n      11CC9C380CEE97395EA38A62A5A949A97233F30D956948D34C49C24C612DFD9C\n      F517475BCFC775303928B216401B05ECC4B15409445A36A31C3A26FCAD343BBE\n      BA428CCF089131362EA58FF02EBFB260394EA6A6EFE81DFCD0B4B4C4ADD3890C\n      E181879B1CF6F211D2C21539A3328170347DF362443F0A771F3A08471C30DC7A\n      63EBFADF5D3E75E8B8B504D27280336CDC2FB0A0855608CDACD44CB127E284E5\n      B317DF6A55179B7BDEBBD09F18548F2E4AEA994CF58847176FD44664E5ADCD5B\n      AFB62A7071907937527129EC0C455477AD39475779AA84899D83A40C98AB926C\n      DAAD4ED99E872585A95F85CD0957DF34A9098ABEF9040155C91147D5BEC0FD72\n      34315A77AC7ABCEB47E6F32594BA1476F9E0AB5BC5B3A897370B8962FD6E3937\n      4FDD5F3FF0C811E5C422C8A9F10CB200B500CB011E956042D72CB3B3358E1347\n      E6B010DE8ECC03E3B942707B9F14987473D3CEA4060C566E7D7B78F5EFD6CC4E\n      7259AC14A295A5E6544812FDB2C9B2D07590993D6A284D62720999E66FA6C1AC\n      A1E014A6F3956A409C4C868B8FC0E661C04586733CDE0F9016F48737E262ADA8\n      E0C9418CB77A7157F4805B8518EF6664A6485DD7CBEE38F1E0E7FF1EFED1E1F9\n      77D2DE35169A734F63EA7CFB5CEAF69EAED99193425F0FC1BE8D481DC959C787\n      2A856EF7D8BB66B321B97976A490136139E4E8729E6469B46055E768502542B2\n      CDC30F4D2CDCD12C449FE489394B17544B225C9886319358A03941565979ABAD\n      19C4D2BB172BEF9E11736EAA619F306C4C6A152C6AAFFCDB67D6FEB1E7064B57\n      C2C1B2CCAF69E1ACAFC8A402DBA2C48EA455806A786BBF5DB917CD36398866B7\n      EEFCB5638BEFDB034456B4E06BBFFF7C781A97AAB25E74DE067290F1BEE69FFA\n      1168A18D804B4D50755968D880F314EFB7E8AC4583BC597B323CF62957573432\n      C422A638A34068D4494862856F817C55CB3ED12FAD4E967595D08A4A24C201C4\n      A2946B72078A320D9B94CE5602CD90321A19FFF792EE6C6AD88021A22B51D82F\n      41274A10D1AAD8744E999BAC9FB1995BD1B7FA76B7B07110D00C8558CCEC2E4A\n      AE5F58DB662E660D6E375D6BD66779D29A9CA54B8726906B4C99A012089B33CF\n      1C940A9794C2ED97ACADD1E8AE5FDDE51C11CB5FDFB8FE0F9DC77FFEFDF4E1EE\n      285FF7F942095D30034BFB0E0DB5663453E6B7CFB4A39D353AEA3A6591170963\n      BE3C273AFFB00E7786533F7E1CDEE1673F584B9E8E7058150E0C654F401C293F\n      E39632A602595EE2A29063230EE53A2E2F7891E71ADAA9BE9A52F3219473AE5F\n      F1D992152C0227C8D15F797732311CD97C4A03E14B5BAD67CF0793332C837CBB\n      EBCC4D0ED3D0521C4F35CCE84398D8F54A77D44B8158FAD8E3C5A97D4A942CA5\n      80D0CC66B69814C6CFC02A23D53DBFFC95DFFFB3B52BEDB5049D4BF8F541A8B2\n      62D1758FEDD9FDE6CEFA870A7F4AF26EA0FFDA60762B3FB803F61D38F072D47A\n      2BEBEF407AB63BD832F59C8BDB311FC418BF32A989A6FBE452F5977FC8BBFB43\n      58EEF2D5FE9F82E4132174EBE202D8F8D260FD3BFDCB9DE7FE6AFBB9B3D6A031\n      3F0BDDE968D82BC34BD9A8EE4EF9FAB36AF82958EE4E9E6B6F71DE5F9AAA6A66\n      7579BBFFAEA9E0CE6C8A96C1693A58C3A156A873C8DDD858EF68CABE545F6F8F\n      F6BBF5FD7A91C79D8155B80D9FF6CA69419D3422B63BA8575ABC7FEF94F8A9F7\n      CE2E3E38171DB80B4D3E0AE9244037ACC10BFCFA69779DB69FDDBEF2067FA685\n      FFB2DDBD894DF3879DF2BD80CD58CE5CA5E232AAA9FC41954CB1CAB45BE981EC\n      A5C1E64521FBC238CAADF77BDC76774F4E1D04F151A758383AFFC9FFF997AA77\n      9FC8CBCC305B5D4891E1FB701CD351181308337F0075791B07358CFD646E7BB3\n      FC13101A9CBC3D136BDCAB8DB78D09F328C6F5AD803C912B2BADD3A727E69B56\n      C38E64A2E9A9415AFD3BF537BEB6C6CE40AF2CFB53E1DC8F1E2D161241426384\n      2C1D13080C33BA656D7E7B9D6136F5C4A29A4B0B1E11C010B6352494C63FC7B4\n      62E75AE0C1B41028A081EA58579FDA18DC84C87206A45C8FD5F6284EC5501AC7\n      7B8F8F7DC24CBD566351380E7C53E31C131FA379DB5BB06C3F07CD0792438F4F\n      4A195D7BB5EFB0EAAE933E171DA46A9948A9DDD3D2B9E84EDC7A3BF33E65CF1D\n      DC03C30C30D27A7573ED9B2B771D3A216AA3B81C32C18C1D151298EBEAEEE7A6\n      113B2B11CB76EC4BAFDF3AF5E4BBC81D4A2D50677E36338DD824BBBA01D7B83D\n      F0CE3E7FBE7D295479752725D7F3EC661E722427293D50A9D7B47C2150AB000D\n      E82E7148517A90E8CB6EBAD4B701A559A055AD6D7A0DF4AA4218215E05DE2647\n      8A90192D115596DC5C0E6B0716973EE48AC588264DB05D5BFDD6F7DA671A5A52\n      EBB29B83753AD3BDF73377CB7AA45F6A8CF48372A0116D72DC62CB4C3280D9D9\n      42634019DFB831FCBD13230BC64E591A83B524329D3311517EF492BAF1E55BB8\n      434614DF10FCF2A097E825832DD36B5F9A5C648AA067D92502A33C05261006EA\n      42535370D10D665DCFD57802A38913E59E7B2B0588F40793FA6103ECB38AD851\n      C31B911C5A594A4789E8CA487F3F2274C9A3F340572F34DC7BF0037FF91DF8F9\n      A34B98105DB0F42FD3B14FD0EDF13593FC838C298052C6E22DB331E62A804E8D\n      301FE7554B545C97BAE0E0BBA6AE5EBE12EDD479361116BD1B72A31FD2AA333D\n      69C9092AB0E4CD5DF0D8E335E8463803B430A7E731F4B10973C84DA316145455\n      B72E8B566BB0F4E0947DA75539BEC4996DE6F1C651E6D499D8FACADAD3FFF70B\n      1531170AB1A2C2CBA2D8CA51A460EE9429146E61374BA7C13A076DE764D99C94\n      A417AC1FFEE9A53B7EF204B0441939D73F7FF6D657DBA50C5A60F8AA2C865C8C\n      4A9243333C4B4B6553ACCB7491253E4053401EF2DD39D7AAE74D7A5FFBD43F33\n      59A072A0CA98A29C68202C6581423678438A2DA3CD87A5DB4E929E7EB2CC4A86\n      E9845FF77D47637D120FDCB2683236E1583EA52330F02BBE8A449E98D2DD5770\n      6530DA48D254416AD91AEF8A4298DE608C0B73CA2CC75D06C6BC5633116E12EC\n      A999E5E55CFF5173ED9AE54F4AC726C80209B67B47EE9CAACE38719E1B008486\n      AF28CDA2358B2536AA78ABDF0BE36074F7E70E16A3E14B7F70AED15C3AF1D9FD\n      E9C4BA9D53985555D5C533FA4AF7E4562E28B5F29216894AB7D34EC74E4BE3D3\n      E9967464B5BEBACE4E4BB97B38FDFE636089800446FFB83D78A5EFE16A4E45A4\n      649C5929F79431130889E5A569CE35182AE1D8B6E338A6EB592B7FC3A5B0FE2C\n      456E5CFC16344DB712710C1CFD95F766D3616CF14651295F6EB59E39EB37A6AD\n      1CA45B1D7F7E3AE2092E323ADD304719B1A66F7667D82F2AF6EC471E1207174B\n      0169CE4A4273DBB6C5442158C9AA5C97AA2C3FFD177FF3B5BFF8F2DA88DC48E9\n      B57E2A727EA0EA1E99695C4CC487516DBF435FDB38B7EBE0EEC3B8369DE04CF3\n      255CBE9CF55F29F999CE208E948740AC2BB54641AAEB30058585147FFF02FDDC\n      C7A7DFF7B10570682F9F7E6F24EFAE46FBB07BAD0CFFABD8FC3AEDC8B5E78BCF\n      7D69F9E90D7290344EDA484DC9151ECB75B96F56CB0C0DAC7E62D5DFDCD8442C\n      3DB838D3DD19686DB234B918A4F6E676FB6CB621CD9C0A385E9D692E4C5FDABC\n      547761949717BA1C3BF540667B17DCC041AC9DCC001A3025D1D49BDD6E66F77F\n      EEC9CA8F7D72891E9C93077F3C273F92F28A45D73DF8A26A3F27DF7A61F08DDE\n      DA79EF6BDBEACFAEDEEC4AB0E4D0BD7EF5C4D4FC14B6592A70126329F7C5A37D\n      F5B991121B93E4C5A47D332F5747A97EE5B7632D91E0FEC5A57D62F44000AB32\n      39F5E31FB9E7177E1C54DD7143E538197AEC33A1FF35375974C032EDA9D9D867\n      F236FE8D21D01856AB71C69FFE36613A050D407238565B99E24416C6054F4BB1\n      A8D77FE1071AE6DD3D1321E3B4288CB4D1775F363ADFEA88573257E4F288A87F\n      E2501284CC810432AE495F9A505520EE8D5E6B772EB4668F2D38770789354442\n      5768D78C346A79C1E1F87C41975E896020F3D4425E72AE7CFB7B5AF7DAFAC76F\n      C67C3BCAE23289B9BE7E5F1ADBC5B10454C6806DDC0F62540CC1B042C90CB326\n      017113E93E91DE75DF7C918D2EBCB135BD343FBB4B2BFF10E3992CD77477CB66\n      56DAAAF72E12EF335E7DA1A9D709C6F6D6CB6B9DE7368F1F3ECE9D5E5A8EA8D9\n      93820528B064B6D43F310F7525808DE16AB9DDE99EF8D841B927769626A45F17\n      445A651A9D590B06539B6792332F9C4169301C812EB42F26C3A4625306DC309F\n      57D82BCA6AA50A354544914D5C0B510F531B82AA4318E49A54D90E684CF8D425\n      A6E554DF446515A82301B32BF366A42B4B6DB57873BDCB0E8CF67D78D638CE0F\n      F5EDED24A76B376F0CE18EE31632A96FEFF9F48C7702673245C42F89AD298B09\n      2B852E2285692DC2C606CB0C4383775298E03B0EA4E0B683AB86310D84C64192\n      E548B8E86DE7EA17AFBB233B77DC4B59FC666BA3A3F98DED1AEB3BCE09820E33\n      D18869929B3944D33FCA48595610D640386359BEC20CA6602A3CF6F80CAE844A\n      83A8AE88B99926229C0E6E65FD5B5CC536D7976BE3A130E7D50DA4E688648EBD\n      3D3DFBA92F3F6F80901062AA951266530E21F393C6CECE63E7F0715AA5549AF0\n      9034F152E492A01AE4934EE91515FDC5FB1FA412B62FFFA090830564A7B7D48D\n      EDA1C741AD1664B3444D93A640BD838FE0E97D44A6804A73441083001BAFA59C\n      2B133762C1CA60C37DFDB5AB07EE99A91D27CD070FC989AAC9612C53CA90A167\n      A3E937FF9F37AE7CE51A731AEB205C4BF9666ADDD2DCD0D6C091BBD209801BA8\n      F621C73E012BB3D08BDDCEDE1F993AFED9BB333F64215BFFAB8D1B5F5C81C25B\n      953B6F41D44F8B914664CCF412D6A2938292315A8AC22D4143F2FDBEB3E43BF5\n      AC561C5ABFE7A734518E55A860A26F3236D8A40A38B05A2FC765CFD5201F96DE\n      761C0DF45AC5AC48F2C0F18C6380C9B12EA63CAB499039BFD2373010B6EBC43B\n      115676AE68272F6F0CC38D51A49F1DB1ACC24C66680D25B49E2C0D0D31EDC526\n      7A57FF01613EE6D49A8F58A5AA12D470DD9AA606FA6F4502E0D1FC016B76AF93\n      C3D4A0A86966D4AC3CCFCD4031655E2555B5F3CF9E3FF2FEF9A947FDAD17B72E\n      7F6DE79E4F3F98DFB745BCB41A4D68150D161A9C091A4D4555555056CB11EC6F\n      64DD1B8C97B8D47F6DA25F8CC1E970F4ED6EB06925F7AD2DBDFFC1DC4EF5FBEB\n      F79CEE3756D54D65F9DE108A28B6B2D8D55857D2482F75B3E74C8C29629AA566\n      770B48642C72D438D3CD64215B9635AB7FAC1CA447CB93BFF63E3E9725ACA8F2\n      40FD60ABF5DC856ADD98AA8DD65BC1C27452E4846774B6A151BE084397B25E32\n      044BCDE6FB1F5253F552525C582561DC72ACA25A4A3FC59EA4C89671FBA597FF\n      E6DFFDC15A175C4BDC0BED280DA37DD395F9A617EF80876667277BDD7D8CEE5A\n      9A6E8BB4A5928D4E27A7F42605E71158EB64B223369242E9C542B5CE26A0107A\n      7D1FAEDB1F3950FFF18797F62FDAA41A8CCA89EDD0767782A4D143CE8DF9E136\n      DE2E5FB8A5BEF0F27267407C2D72EA7858D17795F829DD4B731A0AE835DF48C3\n      2B83E191667DBF06EC8817C8EB94F072F7E6822B3F58A91FA9386FF47BDF6CA5\n      CEC4E4D166A599F50987ADDC796518AFA9E181A6F390E3ECCA19B4E9599F5FDB\n      E6BD6E74670DFED28F2EBDFB93B3F0C812987E1F484E023C0D580FB65ECAB6DE\n      2C76DE5AF94F672FDC204F2BBB9B8213D239160476D56E15E9C54E7BC8D383A5\n      F3C1C903CD615722D6A76AD5126F44FDEB0A5E2DF25B59DC2DB8C276855A0F04\n      ECF109EF242EFB33FEBDBFF293BB1EBE5B536462DC854D078482EF2842CDC9F5\n      0D33DB8AB773330DA11B0719C1B155D9EDD9097352A4C65D13391C6775C74030\n      93FEA74A83A2597EF6E2E8F4EBCDC373F114D60C8508A1DFE7A09CD8F9CE207D\n      7EE481D87EC8F23EB810D985EF38FAFB8DA14C9CE24CB36A8BF661F7D9D53206\n      138F4CA7BB782994AB498C67E9759B8D8409992339E5E3C3C992E3B290F1D4F5\n      EFF5BBCB5A97E201CFBB85E8CB629068A246C79E98E35426D38E87A9D91C1D03\n      BB14554A662D6B12523F87E803E1BDEFDA9B7477CE9D5DDE7B7CCFE4AC3907E3\n      BCA66B7029D72025830D0F6D34BD9FADB149AB08130BF99B2FAC0E5F6D1DD9B7\n      8FBB5151EA0FA8C14099DA0B6C3BCD0BC6BB0256D2B98D0B11DAE334DFE3B15D\n      C25D589466C03751AD6EB91CA1D5DA9B4F6D767BFA42D9462F6BCBF26611C349\n      CFF31C374C67A4495AAD552A52F08A1A5A8EA7C50D85582B304D1734A773B0A8\n      54A8E311E632A96F0A34830F50F8888854F5985DD302D136E5395CDEDC7276FB\n      73279D81DA2424A8648DEDE561F7753E959806F4DA4760E50122CC19826D260E\n      342135AD204C1313D343301685D0A40860D358356E96B98D84E3E3638805871C\n      6BAC81760EA58B2E786F7DE13C1BB1DCF6AEF2EC5C7B33D2CBDBD81C5926B649\n      8B7282645E146966224F4CF681399BF4309EC46C8E3953D4AA2011A2CEE147A7\n      6AFB4449539839658C459C39CC8EDA6AEB628C470C17788890C91CD62AA848A6\n      A9460E6FAB39F9CFBF761AFE895184F8B60A44D8B42F9A2D407368651E2ABCAD\n      0E95EC6A76CF538F63CDA42C87CF38B092F994307B69E7E0A9DAA5D39DE856C5\n      63AC03B75743B29D12C7970B3659625369B8BD7452EEBBABAA2B0B34C5127060\n      2CF59896D244CBC28146D62C6C3CFBCCF9C939FFE84353C1030B6AB1AE05A850\n      8903458E4ADB9BC6A7CBAFFFE6D7C2BE35A27014275B39B900D13611B614AEAE\n      91D8AAA9643F2D8F117F91540B16CE3E5139F1ABA746134392DBD1DF0D2FFED1\n      3952B89B387CBB24ED30D5D498538D3A1A98CD783FD34F1141266455647B1CB6\n      18B8B3A2992DAC9DFCB1A9DA12E0718A620C132D6E336386DD77D65F18D1A45A\n      B2B297D33ECF0652731BFD5FCBC0F5F33C2F54E63BB48E81FEED1ADFC5C29DB6\n      5CCF0EDB91284C3F4D4FC0EBDD519F8B7C3C67A381C19C1A4BAD3FD8D85A16AB\n      420B7B331C52981D4EC48DA7BFAA103C61D94D6655A9D5D0CA0D0EFC49B1E758\n      BD74B2DCF877300C3545D22587677A75792C684CB436A65E79E3EBEFFBEC83DE\n      4470E64F5F43BC7EE2B37775262FB8183AC924AC4C88BA9665D8EE7B26249DC0\n      4A2C606BB5E86D32E298644A2A681AECFCCD7A722EA17A613CB1B5F8C0BD09D4\n      22226EB089F2E5E1F0991D9252EE7B21B7B23ED24A2F61230BBBFA0D755C47BF\n      3ADDDE401AE0135AB039AED6DE388E469CF320F0660A3694FDE488BCF3D79F2C\n      E634D6093FF7D4ABEDD633E7EBB5295D127BEBDBC1CC442638CE73676E32B74A\n      0D84BE824311B377EDF7DF7DB7A2142807959ED0658A39843B00D7A4B2B5C0B6\n      2CD579F9E557BEF095B3E7B79F6B673713948579B56903BF9C6FA91FDD7D6429\n      1CED9DA9F5E29DB5A85B345D77B61126716B140F0A5D133402D97FBCB5B399B6\n      F5DB3A0DF0E15AE39E5D8BEF39B4EB90AFF40DCBF390E9FA1DE97A5AB68DFF41\n      CAE348EABA87EA1737FA3B79599D99940C76A2E88DE55B1723BEE6C30782EA92\n      AA44AA7C4EF3D22A7D706AB139824329AE8BF2F2CED6B199E0171F3CF0414AAA\n      C3EC3C2F9EEA0E9EB9D802FE647DB1095BEB7B6499D5BCAFF73AA361FAA9A583\n      FB40B996749FCAA2E5983BC2BE13969FBC7FE1FEF74C556BB89257BB3D25E79B\n      6C8A34D370B6C4607363E7F9CD8DA1B3829C2A721BFD50A5C311545D00AFD6AD\n      3370C45AA38F56F71CB53575D275498682BF968DBE97876B9E9D41301A6AA151\n      D4AAB57B6AEC2E1F7EA2367989C6F77CEEA70FBEEFC1C224A96BFA68FA46CD54\n      A0390954441AAB6DC0B8813DF53F60A109FE2BC16D7324D30CADBFAE34C10863\n      43B3982A5B484B333E2672FD9136DBADAF7E2B98F5D0A11A280C10725878A2DE\n      FA46277976E8B949ED833E7D7C2652C2A71545B5A800B81792984B0B1081E2E7\n      DBFDB787132727ED077CC104880BE27BA56B67230EB2148094C5A6126B299B67\n      3163CDCD37B35B2FA630B215E203283663D4CFF583E5528902186B0BB38D314E\n      042DC79901FA73D51D7BC6B62700F6F2127D6070F78923D1566F65756DEF1DD3\n      6E9069F6944B2DDD39E0DBB9B2366EC84AB9D8F8D9295881324A9970D7FFF166\n      7AB1BF77F74261C5BA249A7E24B3F7A6F933256996E12429A9D39BBF7EA635F7\n      C43C79047B4B1E0D3C4DC60D8D5CC98AEBE9FA0B835B2F7051F16E8DE2BE402B\n      FDE17611E5B696E4CA11C56EDBDFE554A6FC0AE67C89A64E50D38099E57996A6\n      A0E0D335BFE9598CC82C1FD51A81A51FB4C8B8A75C5093454F2B1901AB145699\n      E8594CE65D7C7D63C0E6C5D2D106B5825C93DEBCDC794BF04B558B62706867E1\n      43CDB4A9E92F347313A56582221C81C7F4A81C5B8228136A8CE16DBA34FE55DE\n      E6F5E3E3E452185F2289235AFAC505EBF49F9EC3433AC4784588D5FE4863904D\n      3C8C4CFB79AA725D475C6AF9D4925CA54A4426CC423158D6009E67DE82634FA0\n      3229E38593EEC2BDA474A292331C5A22E184E23C413B5712B8811DCE3A0A0C05\n      1AE9CA5FE675AAB0C5B62A8D5F7FFA2DF88563BB6E678621334C6FCEAB848642\n      73D4684E0ADFC9A45472443C1768903589DDA0E4F315BBA9EC0A7362B479F0DE\n      4902C995D3EB561EC410B638DFE032036082B0398D9422A94DCBFD7755ED49A5\n      8B3F84BADC23208DDF88C96E8D868EFE6CB2F2F6999D6CC84F3D38E7BDCBC2F7\n      EE896D334D4E351D346D36BC92CCDCF8F3EBCFFFFD15ACF1378A5A4A9C2BC17A\n      0135A5615019270884F6E2FC18F3E669B52CF3E63DECCE7F735F6FA163810A78\n      BABCF87BA7E59074497A46A25694B405484CDC1EA4B064E37D7FD32AC78B2610\n      4B1699F3ED99BC0AE63A477E6472F228C9A2014A084DCDF669C94BD0F16EBD30\n      B08BBAE65751698F8ABC2F8CD128CFB514A15A036962AAA12C28C58C63796656\n      47793354AFA36490E9759D296B54B2E5413452202D34E990E66E60909A486548\n      A96599A12F6EF64AB5B8D3379E9282E71A082799356D59139A23114AB5920E86\n      B307DD604A23AB197CD10FD0B46E8D239C32987B93C49B9DD9FAAE7F953D73FF\n      0FDF056E80B7BF75F9C887EE72EF069CEDB0929630C093D385E71610BB19E324\n      47A0403B6D3C1C99CBA256A652478BA17370F3AF571C5CC9A6B8F77058DDB390\n      229E11AED75CB51F44DF5857CB5238B5A8B45064924437E110096A1C4CA8160C\n      344953631C11459ACDD5AB15CFB1789E99B0464AE7248B50181D2D8FFDCBF716\n      53698E0AAF08D499EEC677DF6A7A139ADCF45A6D6FAAC94581F3C29A6D640E28\n      C25155947D99BA8F1D771E3C257385A4079197637DA596264582384432D3E949\n      45EFB5372EFED95367CF6D7D7F985FE364B43D023E6993F4E3C2FDD5D93B16CA\n      E292DDBB36583BE14D1C72EBC441D206AA50F12025397322F8952A5B6DAD346C\n      BCA4EC03959929D7ADA202ABC188240981BE621569C3920CAA853B2A3561E698\n      6E21B9A1B8446E5C4846A1976BEAED3E3D1CFC49D86E48363FBDEBEACE6A22BB\n      87666A73B95D8EB25E15BE381C36A1FD5B274FBD8F15306DE5CC8671E9B0FA33\n      DDF82F5BBD8B399FC6F25055713BBD168B7E4BBE7BFF21AB88AF6FAFB7A0A745\n      B7323B04F4A4454E0468168B59E64C78B67F782AF144D91B7A2325D7449EA338\n      4669526A12DD855948C7B9938AAE96F212C9B6324D92F1A78D479E4F2489D26C\n      99C0A73ADBDD7AA5371C8D7A19B0B474708FB8E0D199CA47DCEA5A133DFEBFFF\n      52E3C401610E980035073DA641549733E3696646E78DB1E9B8E0C97772786EDB\n      AABDF32F46148ECF8A34046A4D66C204326A4CEB686ED2C763BB0886E1E0DBCF\n      2239F4EF98CDE5687CBD80097FE7AB2DFE62E44DF3CA8FD6C0513749351FAF97\n      555692526EF6585E6668644AEE15387AB6A331B9FA6883EEB575AD60960FEBB5\n      ACE0208A5512BA857E709131FF07FA2D55A24FAE7F378F2EEB9A166B486E6581\n      2643C3AC65B01A0185C7FD8FA5B10A37E1C242D345507734B3650DBD8424A64F\n      6CDD71C7A9C1FACE30EC2E1CAB6230C8A023A1C764488BBC90CD2BE7B6666666\n      2B3FB1042B40C5B9153AABDFBDC65746BBF6CC143836B782A3F1CF00E67D2EF5\n      628E71E9849BC1C67AFFF08777D37B2CB958251E222402DD5C5E21C3D78737BE\n      B3225BB5755ADE02A0CD652F32B9E7858D7A49D7C6400BE9594867A85303E044\n      4090E326426AD6A84B9326DDB38D9A631C44F282C75E60D9BEAD974E6CE9EA96\n      20D39360155AA0104EA1605C1734776727DB6EC7933393B333D5D1EE551F5BD9\n      80AD9F937213533CDCFB911975426945EF681AA29FBFA30A37B7A45B9A7B66F6\n      09C03BC62008DC6E247E6790F09DC91A20B48681A9EC39A4222F3867FECB4516\n      BBED9C6F946027D35C04404D734A94832232C7C0AA62DB3E76C01808074A845A\n      D603A581708E79D3942D5A44E2A2B2A8F6BFBB22AA435C222B76418E221EC3FF\n      9FA9F780B62CB9AEC32ADFFCF27B3FFFDFBFD3343A4C0E1CCC0C060302182482\n      2412339896694990442E4AA2B424D91497685BB424DAA268DAB24D9322089206\n      184000440E33180C2677989EE9FCBBFBE7F0F27D37D6ADAAEBAAD7432E63CDC2\n      EADFEBF70B754F9DBD77D5396763BBD847F185988C48CA9C2147DDD44C12F0B1\n      D40A62CB097EFDBB97E0EF9F5E016F75C998992DE6505F4D1D12CC2D3744C458\n      690851648231C35D78CECD14D2B9AA3B4B59033B5ABAF88BF0C8BDADF52B37C3\n      5B9AE3CD0DCBB00F8B830970A8D7A17CCE42B8C8164F04ED9394D38C6B2AC34C\n      8B8E99D2A817C9F899714570EFC0BA797E74EA44C73F1939EF3AAA961633A163\n      22C766D058260B26F767BFF06B5F2AD72DFDB1465671259CEC0A7B2C11A13AF5\n      4D1C488F90FC8465CFD38A0349F3143EFDDF3F3C3ED6D718E7BEE05CF8B7CFC9\n      2E9A40F186847B49BAABC9AFA68F5A910260567ADABAAEF74745E4875CB65CF1\n      E7B99FDABB777DA0B1F8763FD3101A23AC11208988B2F375B2FD6262A9DAA488\n      26258A344C61A4159FDEF84952C4694A99CE676503C145DF2120279A5FCDD124\n      8EF248670F27CCE050E2035E8E72999B8BBF82985AF432C935106A4E48891952\n      549AE2D1121610258253846D003AB63367DBFAA95B7ACFE0F1CC213A73DC9530\n      932536B33B4C8996E944D4C10EBDB27A58CB5175E30F4BFCAEC1E13347CEFDC1\n      05BFD639F6C9B72564DD2EA9166C85DE0EADA6406ECA554D3F74AD6826FB6AB0\n      CB382C4B2FD7744F493B74C2CFAD8D2E460BF7DFD5A53DEBC4B87E7821D79FD4\n      5C96AA9AAAC8B351FEC29827BE7E1D4DAD74FEDB9071361166074064AC8985A9\n      47D6B104A733E36A9EAB5FB834A373E4AC62999D4D4E97A77EF5BD4565922361\n      80F0D264F36B679BD48C2638D8DDADCCB675E099EAB67690D85A42E4412EFB20\n      A97FF0517CF228341DAF2EA0951C326AA08CA51039C885790268313877E9D2EF\n      FDD5B54BDD2F8D920BA92C7A99C654E082FFD45A7DC46F8974F806E8928AFD10\n      6ECC0C841990414C3315A04C63D968A833567338EE0742F96111047E4C34ED2D\n      B0668201E296266E0C99323B4C781A21E087A03521D14CF069B0FFFC85FD9F98\n      3F7E88B20C874DDFEF51E7D3E3EEADCDFE55286E5BD9E34BAD07811B6E8CD392\n      A316BC7D103DB9B4F08BC1FC6218162E3A086873ACEC11B86E8BD75C34199B67\n      71BD5A3EBFF7FA09821E718256D0D02CEAC04C6347F5EE2438D6E173B413C60F\n      F4F2A630730BC174BE7F487084619CF15DE90166644694EAA76477850ED9B8D0\n      2926CFDA1CD57446580A768ED43F7EA3BF319CEC31709B476ED0DE1F1457D289\n      A64B07A348EF8C8AEF1F65E2878F2F9C0178BC52FDE0FFF0AB70A5658A61729D\n      33C994464E676CEB445802339A458B21F896738A497EE88EDFED5BCEF5778A65\n      A6C43B9FFAF76AFE05A6A3F3353AAB9416AEE69B2FBC9ADDBCDA3CBD909189B1\n      B4D6F194B3C15F1EC89713EF04F43E5651B3301D13A73A833AAEC1E28350F647\n      90C5290195A8917EF320BE3964C769F0CE4E2627845471ADAA737419A7AA17D3\n      1C21390082291814746C413239E7AD7D352C135EBA6C27B68705EA27DB99FE90\n      A6DF9C98865EA1E9F274409DB9B528024A1A14CF691011D87F6AEBD0890736AE\n      6E9BF1632B50A844EA9C6E0AED43475644AF7DF9D28DC38FB59DF71DCD690E12\n      EE0CBC9B5F7C130CE29523B3A99A20FDABC6A1757A735698AE943C4E2DD058BF\n      1D27343FF59153EC849FD7B0513D6242F768FCCDE4DA97AECB4D8955FDF522BC\n      8ECAAD540C4631B35DA71EC442E3C5A45264C73C7FD5F25682CA924CA465A5C6\n      501C85492AB8DEF72E16C2D74FCE5C824ABFE2D8BEC5EA9A22C458EB49E008B7\n      28985E488214D3ACBC28C4C156D15D1F2F35668287FB81D7123E19C4E9FE6B19\n      BE2916EF0F2AEF65A9A7696A00B4680BB8B9A6073E34FD14531739634F3FE512\n      A60D0C4D51E6ADAB63D35C2ACD5C5A41260CB8F85270F90F2F07A13312E5ED42\n      EC16223653B574E643459144C6185D31842D8D17422F158C298AF49F949640A4\n      A5819FB055DFA5ACC4B5E4F4FB178A56AF5499C37D98D911CF04115664A5AF8B\n      E4064741B51BA98344838E699B8FA5D8B6FCFFF8CA0DF84777AF4E2B79A63CAD\n      2CA7331F0C4999D6B79A6352230C31F2959BC8586F60E3B129A5EFC01987CDA3\n      AA251C50E1FE613E3757B9F1F28D6CB81A8A51828B83844D723057876DC0DD0C\n      D45AF691C7DAA29E28993A720C4DDD0C111A8F4B571431B07351B4DF7876DCA9\n      D88B0F4B727FC0EEBDA7A0AAD0CA4D2A9BA104152A6FBEF1BF5DDAF8EC36638D\n      018EF7C3C1568AD721138CA022B5105C45F9519B2CB24A15D8D55578FA5FDD97\n      3C18CB92F9E7AD73BFF9ACDC82B9446B106FC5F14656980E0AFD609499864ECC\n      FC52E022E8E6F1B2C316036F4538828D0F3FEE2FBDBF91A33E1C973AB1F134A6\n      C21DBEA1765E4B1CD2D41C342AE1A4C873FD3C2DDBA2769216C3F1443FEC96EF\n      B7089A712CA4126281A045C2D158701D79DE202EBB793906749C17D9D481DE75\n      3D9D33529ECA5214456EEC29B08509CE95993E5048133175CB9AF5BC3AC61573\n      5D5FD076BE72A2893DCE554C892B8DBF9B86C4486F794EB93B5F63F3B5AD372E\n      75FFAA3CF653AB659ABFFA954B8F7DF4A9F29E1480A195554BDB054B41517179\n      8621B0AC7C8C92A40C0F54D8A53410C88B31F4B98F5F496F7FE5220ED0D2930F\n      EC5EB94DEF2D5A2B33653131FD825007BE256F67C3677B60CFB3412597698A51\n      5F82BC405AD026A9F1ACB71D47EB42C98519E22F0545A5F1A262A61FB6217064\n      45F17DF4D83F7A4FE10E0AA41C555197275B5F39DB807E6039077BBB41BB6E4A\n      88746A6FB8990B212F689C8EED72F647DF592C7774CE84852B59C0A16D411B40\n      5B94844022915EB9383B77F9E2EF7EFE8D0BBB5F1FF117A33CEB47A7307BE2D0\n      EABFE0B45F857D94489ECD21DF16183A9436AD221B7A1630D3D26D1A4265ED3B\n      E3B4A08232A109600E505CA5E6A5238004A33AA9522012C25DE56F1381249D93\n      ED1778F2CFAEBCFEBEFB577F315851FBFBDB3EB8BEB5E7B9D5E18C7F085706AE\n      FDE52B17E28DFEA3879741733E75409D0F17D2F8B8EB2F2AD934885019DB4696\n      7831EC02716BD20B503D229D3FDAB832B334F33E0FDC8765E9D82F8CE4F544D4\n      EA6C81A0448DCE6D6D372DEBB19996AF046602202BC9DC7DE9DF48E495F1E8AB\n      61D751BCD4294A2753C7D14CF8A1EAEC7CDD6A04E03EE62E44FAA586E759FED1\n      62763D8E5F23D9F7D5B0BB973FBA74E6D5DBB7AFB324446A128AB97AED6E177D\n      6C65161651EB897B9FFE8D5F4998B02885F24E839839E712D8CCD8D6198E98CA\n      98A29C66F669D125342809DFC2C269279E98AA0109B528338E53E616C9684735\n      3D8DC29A1DE7F995AB83EF3F37BFD22EE634BB922E222025C3CF6E95E727DEDB\n      2BD647EA5C8DF33E6573F370CEA5FA7D52210743C8BB91457C55C9BFD78F5FE8\n      E2AAAA3D3D0BDA28CB905D6FA8BA891F340445181211226109616774C4B0C6D8\n      851B5F184E6E6AC24542C5F6F52ECEC763959BF2088AD574040AD39A0253629C\n      654A8FA016251DCD8732D079CF6EFBC803575FBFBE70C80BAA63C488269082E6\n      D2C9F1A806D7DA3BA39DE58F06F0EEA3192D6414F97BC1FA5FBF49F2BCB51214\n      2AD55B194A53CB2B8D398306A6A4CC1D2CE6D7D66F3A27D9EA87EF412B554ED3\n      94642EAE10BD1F7FFFE2FEB908499B637845F2D7D37833E78920CC72B9A947CB\n      1D991EB1ADFB9ACD59803A36ABF0107B81A02496F260146659E15A2E85D0D7CC\n      91691E922252BAAE556D8F7CDA120265B09076699ADB80F1D1914861DB8C4FDF\n      BF3AE23DBCB0386E2C1F299761540D471B72F45C6497E9A10FB5E8296F1CC7D5\n      8A0B40C409A1A6D4F3ADA2CBA949FDF446F82D14C4536F2663C5A4C31969A9AF\n      F3821D93D22157EBBB7F70AD11BA0562B74579234DB6E3C93057D3C325A88972\n      AEB8CE841EA496B989863D91C7D0345E7B0A689EB0E855966C16B0B22083D31F\n      388C0F45051EB19C91BC9A97E5440CED1CE33537BC9469000C73D2D30960CABF\n      2229769DCAFFF2E215F899BB0F4D47BE4D4DC3C09DE93753E90A8066F45C9862\n      3FCD0D6A820E8B486BB4A9555346B1A859F62CA835A0A76816BBBD879F38B17F\n      F3C6CE8D402B80846761E9DD1E24F53A6E623E075D5CC2CEA95AE304A16C4CF2\n      7E095D535AA40451FAF763C926AEB570EB2C18EF0C4E3D1E64CB71FD917BE062\n      2B278996A72E248916EAC42517F0F3FFDD33D99E950219A9E856945D2BE98468\n      1084B6E28B6571D8062B4EB52E1DA723CEFC8BBBC153A540D8BBE15FF8F7CF46\n      6FA498071B406C4ED2DBBC18609CEBDD6726792A33BD05424FFF57E48B0C2DD4\n      FC15C11C269BA7E1EA27DA29392051C962248A14A5CEFED962F72C7758435291\n      2214A6A657DBCCD2264C4B0E4DBBA2386D07411BE396659C7FB444A954691CC6\n      E6401CFBC344EE676228602F8A25205A9D79AEA73460662980B2C8B39C7366DB\n      C621B950D331338828D5749D966D571070752C91B47E027516DB111F20A4CC54\n      07BD2DB04EDA0567A13747593B00D8BDF8CA1BF8223DF9C1475E79E6BB5EBB71\n      F2630FE46C130B8EB502AC55CB19AFB0B0D2624AE359B85DF4C77A01B5E62DB1\n      9D222CA055D9AEEC7EF6DAA87F30F3F45C6369AEF7D75BF0FD7673A602F23033\n      55035A1D95602CC237797E4E54622F2AB3112EB31CC73930F301F49E134AE706\n      8A58922495C0D35F8E4E5BD46D067DD7A97030C0E3E4617BF5BF7982DB039D29\n      2D582F6FA6DB7FF35A2DA7811774F777DD46D5DC3069FC6B06DC272AD51C3A2A\n      E76BB50FBD23AFFB4C78487A05D1ABE7626095D8231916364B708AD5509DBBFC\n      FDDFFD8B73AFEDBC10E297E334EB859F5A58FEB9B9C38777B7AFB2A8678936AB\n      2CD2FA189357F17887C68B08DEABF791E03270F692D18B7DB03D96636169943C\n      52852735C78A4533B335E127958021AEBF2E40C9C56056F423E5572E3AF45B6F\n      BEF9AE432B4F1F5F188C6E5E1B0CAEED68463AB7918CA52FFE7EE7D011AF111E\n      74C3B0BF0EC15706DDDC634FCDB51E506A2920D2E210E3403575CECD65287B11\n      4DE1760C5F188783B23C51693C1004F3D8345171CB7E2D0F6386E6ABD517BB6B\n      6F5CEFB73D9D6E586A59334B758FE6BC543733F2E2567CB91FA65AE442D738D3\n      6A0D5DF76B8D4A6D983EA0F0C37576A4AE8910EE4027E378C8150BA992E4F578\n      7CA1A29EDDDD2A58DD6AB6D6F6371220FA69E1D8D61355EF23CD7A1F4FEEFBF8\n      07DEF52B3F9F8382A0A93FF6B4BF603A5B0D16D81C7E1173085AFCED6D5039BD\n      255453279569F9E8B494B4BCE3C2A3A63E0BE662EBCEB81153740A346C6B9130\n      D8DFFEE297676D59DEBF98C56317EA64630FFEECA6BC32F1DF3BE3BCB79A0C07\n      7C00C9CA3C5E086C0D939A8AA411EC6FA4B64D08416FA6F137F65552580FDAFE\n      039D480345D5C7B38C400A22CA7B7B3049A8D6224599C304E1DC2E9BE317E59B\n      5FEB3255292D7690E593BC3C9061AEB38329D23795B1FA4311730D066C86B59C\n      6ADB560D419ACAE50FC56E6DE9CAF51BC7EF5F00A8670A370B1D8651E24ADA6B\n      452F296BC1F27F9CD0C5230593621C7AEBDEF617AF58B870668C71002B2C65DC\n      038CE79A19F208425FCC4FD6BD8DECC6EA4F1DF11F5ACD7C1283BEADB9D74E6D\n      F2171B6B9F3BC7E46CC841AF1C6D2A79319A6CE702FA75CDD4D238D59BEDA8EB\n      DC5FA91E65168B4636105517F98DFA20C922215205E3AC489342C33943B011F8\n      0E29154F3CCF7603EEBAA60181E342202D103096D8A22C475AF56B49E9CA1118\n      AC8F6A070237A875970DEE42C077A2AB71EF95CDA5D333DEDB9D3D6BD00EEA38\n      55805133970EA392682CD46B7667A80230C53AD38A9329B2E898D0A94BA29209\n      24388B28B0E95AEBE0336B6453AF9F7540AC9E19BC95EE0C26499A63AD4E49C9\n      4B9DB1A8AF132D245A8D851A65CC002E6949150032EF07F384361C9817DD234F\n      CE35EEA385D3071C91A2A6E961947769AEFCFD6678ADD8DF1E09158C723CE179\n      01794A61D7ABFDF6F36FC2CFDCB37AA7D3B17CEB20DF9CEE8B3B05EF72DA5968\n      581BF433A5053367E66E1C14B166841EB5ABC299632EA142235673C99E9D05B7\n      2EE77954A6318C4B7B2BC993329DADE03962BB8AE9353DFA7023688E991C1725\n      D54B41F41B0A2A8C08322718D97EEDEAD9CDE5E3BE7D58D8A79AFEC3A7A46BCC\n      025949335040E337D35CFB83CBE7FFEB1B01AE4F50BECE93EBB1D82B694EA90F\n      F84259AE58E09013B4948BFDF4EE7F7AC6F98095C2C2DBADBCF97FBEBCFBAD83\n      1AEF6C8964372F6E09B15F8218A2424E27E54FD98B8761B5940B14AD342ACB1A\n      0A14AC1D2F577F4A7FDC2D5F7FEDD0A014CB83DE6B60EF6201B57A0469A66345\n      681D02A84E0B423F67ACC16B1C4EAAD49A61A469E91D9E92C0182FE451A6CC78\n      347B24C041260E923C3553E28C7832F3B43106C6C8CB9CC2A8E919BA2923D541\n      85A9DE2515CB0928AA326C43C190ACB668ED847E2B1D4325266678AD093A42B4\n      16E4CEB0B2EC52DB93B1FFADAFBC7C62EE50CB9DB976FDF5D39F78182E295E8C\n      549438AD59D4E948AAF73131F5C151910ED77066C64F6986AE5722475AAD57A2\n      67A3F5AFAED54EFB4B1F5BE85F3FB0BE04F34FBACD8A07B2382586E6D9A28005\n      C887F6E05B07EE2604AE3BD0C4362E95E5E9CF1E4EA230CA0C53F57C4699D6CB\n      224D2C2DAA80004556A978F59276D13079C839FA4B8FE7D6582F9E5B56CA2EDE\n      FFC22BC158F95E70D0DB73EB01D1328173D2F28167E571C235A69E39C29E7A20\n      371D663ED44088B560A8204938F61D4E3324339B57411EBD72FECBBFF39997CF\n      F72FF4F16B49C444F46F974FFE746E87A01B1BD757E8D220719C4B59B4964F7C\n      8F1DAB548E601A98FA7A78ABBBFB191BF642702B82B77BC31A510F39EEBB9AF3\n      87ECA09472908C75C4E82D1FF2FCCB3AD70CCD6DFCAE9FBCA359FBA7F3772549\n      F7FF185EFBDE30E5632F0B3AEB300BFBFB1F762A8FCFCD3CE007CB1264B0BCE1\n      63D1F05A9968F4BB364C33C295EBB1A05D2BDD496F378BBBADDCDE2EEC376A6E\n      2293BB748203F8222FF7527066B6D3A9178D3AE15D799EB1B5C0DDE8F717AC16\n      99A8B58DB5811ABDB1175D0320B3883147A50C468EEDAB5A1A1E360F82817CF2\n      FE99D97707CEBC9DEBE74C2595B91B0B06273C2D5037113740F63DA7FCA3DDAD\n      60AE25FB432EE50841CF71DF6E5B1FEED4D7D5C1CFFFFAAF9DFC91A74159286E\n      8C06D51403B198DEAC2043FC4DDF349AA2DD94504F19B599C5369D0C79E780F4\n      4EEF848E5B39150512EB6C66C6F798C66250187351A8E2FED7BF0577376A6F3F\n      9A96A9E6C13061FB7F7209ECE6D50FAFD207EC78B7C752A75CAA8339DF66AE4E\n      BC691E59DDAD4CEF630AAC83523E9FA4D786692399796219B4DC0C15D66C806C\n      BFCC6931DE2D7A999D7358641ABCA529762DAD5EE3D5CF6EC34180098C603948\n      D0AE48529EE75AA6693DA2799F2C4D716721F4FB555DD6762CAF148122477E84\n      F6C389D671ABA73A291896A9709957C034D1C46550DF79B17BF81DC7D3A795D7\n      382251C227A17FC5E97EF9BA5301A899964252EE0253CA6F142130C5E9713B5D\n      EEBE1C4E4EF3C37FEF046C556244B82FED583A5FE3D7FEF0FCA49F23D99864E5\n      0E0EB7D2643D49268869E29CA85273F16A210E0174B7E76B511820A5D5698973\n      BF52EB8EC7132E0B44C34C26DCDCEA6A5156B569DD654C6F79253248DBB3CCA9\n      72A565ABB1444096942E231C89546B04A253BC9D876374DE114134A1B173B4E1\n      DC65114B6517F36C90B5DF5D1F2D0C1070FCB482299F761322404CB14C39F501\n      357F505343AB29C498EBC369C33254547F7BA981105AE456EBF69FDCCC6FA589\n      C29B0518035218232BAD31453E1D22A31989E76814D4909FA585205A3F509467\n      A9A6127689DB8EB3C0EC36D34975503FC10EBD6736F706260A339B6092172188\n      0B7B584D37D4D61B3DCE6D2EBDA1B1469FA40CF7AACDDF79E92AFCD37BEE1C8D\n      9A8E4173B061EADCCD1D8F343DF6E5D4824B99021E698AD585312D32F36E8C31\n      5449AA94B66D0D429A076859345E3D534FE27CFDCA00F146C4E9AEE04399DA4C\n      752CAD0B031D5441BB387AC671FD547F13CD17CC28249E2B44CD35B131B9ABDC\n      787DA809E591FBAA62396ABCE3B49A69E887A1CC7BE905E40807688DFCCD3FFF\n      73F7209800DCC3EAD678B22BC018EA5C542E02B260AB15CB99918E62F1DDBF7C\n      AAF6B1062F5316D5363E7FE5CA1F5F994F9777B3E1AE54D779B12564681CC8E1\n      B451D26C5E1B8006541D581E6A540E036C71DC38060FFD642D6EEC6920047D2E\n      8A9CA47EFF35BCF3BAA6F03A838429B1CD732666C234D51F5F8149966459DEF2\n      BC05D77261A6E0C49F71A972F8C4B8737385260A0E64B91BC699993F6686B1A8\n      69CBBCD6E25A7F1BFF47AC5384B946D3C8C88C5502AB516A4359717191878E83\n      8F9C98C3B3616E9A4D6D210B63D385B1C2658207D565FD307440CE0D2E25AF3E\n      77FDE10756FBB77BED933395C71B311E82989B0A96F986AA3574B4EB900249A2\n      B5204FB6B44883E6CA0B48CCB106DC3DEFFAE72EEA1CB5FC81657A04EF3DBB5E\n      7FD1CF7E91542D0D8459C6CC9A59496E2804AA8D5E1A8AB391835BB11992AB62\n      0533CD2FA429AD4F79519889E258B34E0D6886D869E203A563B306B47A64923F\n      1E1CF9F947726BA21FBE257CE387FB972FF9439D6EDCBDE15ED0A8522D8334FF\n      6855814DF22849046FBCFD1EFAE049630E09FC526B78E43114E890E434700DB9\n      4E4D41FECD8D9DE72F7CE92B2FBC783DBCDC55AF87238D8FFF72E9D07F8B9A09\n      1D14AA689B734474D502D7ACB221D8BDACE6797820C73EC63A2A0F78FAC57212\n      1EE4BDC23A1FA55D8CC7E3B0E5B936292B5403A5D81EAA7D80FBC8E2F15067DE\n      590A3FB5BCF4A9A5D9BA2A3EDFEFFF7E37BC3C2933CEC7229536801CBABC5C5D\n      B44F55E9879DCE63A44661C16DA2094B391A001E95B685E616E356D51996EE38\n      DD8B36CB4CFF7B910A8DCA6CBB10DF29F2AFC4C9605CFCF243277FF668D3CBBA\n      FB43F5DCD5F0FF9D8CCFA3E48946F583658B4A6BDD472FEFEFDD1EC4FD124D48\n      563A80C56876C63F5CAA39219847679AC1A34EED04D6998D6325FD10E639E9DB\n      566B2FBE2A7961059B83F10BA8F8928AAE8D269E4D74A249F3A25E6B9F2CC57D\n      0DD699F37EF97FFCF5CA99A3A6BD520AD3128FA499B12BA67887A605113A8F90\n      E951E7349F4C270496D301DC7F8B82D31FA746B7C652D4983428938B85096180\n      72617223CCC5850BFDF3AF364FCD950DDBE4D17D75FB73173C415B3F7C57BE58\n      0EAE6C2CD6178B39473628736A00B394C7566F4F8B04444A9C60B946C36736B2\n      3CAEDE53091E5DE020C2B5060EEAB9191734E67B291A0C9898E8CC9398A3DB22\n      286AF139EBFA37773439C8101A16785788284B3458C1E9BD0911A585A899D686\n      41E0B296451C255A96BBF82E7663EFC6E29959AF890B9E698DE1F8AE567858BA\n      FD6BA3AC28973E784F7A125AD662A60ECA38666749F8AD8D4A1B14F589E2D2CA\n      FDD2344E955320043982D549F5E6C5DBF3BF70377DBAA5F331031E67145F1FEF\n      FCEE4B789D0E81D3EDA625747689D81C0DFA5926A915E742A702CFF76DAE035B\n      1CB3EC45467C630421B12D2CDB8D922C15201130967898E91D09196354163A55\n      D41D22629D17822050ED79E0D564CA0501CC4119D29A5A1357B7AE68A963014A\n      2E369AFBFD5BD8D8EF32EB309C7DB02943B4FDCAADEA69DFBA9B6484D2DCF254\n      0C5C0ACC30AC69893004A6EC414B43D38C37356F36D724D30E05132FD44CB7B1\n      63821C7CBB79E3D3D7500FC78A5E1DC55BA338CD1585BED4145FC786B92836A7\n      5F6529E324334556949A095E1A7A94F1BA69BACEB2E53421B6510C67C7273E7C\n      8437522D22359A58D0B870C9B85003CD2041F8663A3C1025A84D0AD94B472141\n      FB7EF5775EBE06FFF4DE4346954F673C4F8FF6D19D617010E9B4A25FC014F79B\n      AA266AECE575E6D54A06431B731B2A6E3B7985D2395AF124C76E4A66F1C2B275\n      FDE23EEF3753ADC4F27880B2884F3A813383DD4A69733E3C7C3A98398A940564\n      2E6D2DBDE5444007820A2813A6C179C7D978333E79A62657B6D5E956E5F4BD38\n      605C68118230659211927B57FECB0B57FEF41A569D01453B3C1AE672CCCB212E\n      17009BA76AD5B5E694CB5134F7F1C6F19F3F625C428AFAF0A5DE2BBFFDFCCCC1\n      E2044C76647935CB6F1BB65B2A33524E03A1B9EAA0523681AA896CB95E799B6D\n      55858767A2959F0C9CB7493C1268A43532A769A5F70A5E3F1B61E6C76A322C98\n      5E31AA853DD22B4234928599FE166CB6E2CF3AFAE750922858F4CB31CB06DC74\n      4E4938126508C0A828C38CA72937268708D9B60D2D9A6B75A9FF62EAE4561AE7\n      0360C972C60B1C9DB334CF653AF784CD4E75E1E8AC64FB3A71488C84F145A546\n      A0790969E6560B01EC81B871EE6B6B0BCDE3251B73315A7AC7A1A2A97137B7B0\n      AD11A5A89094DAB4A04E5280D1482531A09322351B5CC37AC40FFC2208BF17ED\n      9EDF597AC7A2FB680324E5F89903F72A2C7E01B8D02B73915153EF8013A9738E\n      828EDA2E0FBEDBA5073E2D1DFD341309CCC411C210B5B902519AA5C6254E05BE\n      E3E85C0285C58CF4AC4AD66791F343ABF51F3D9E93B17EBC4CF8AA4FF73EFF52\n      6D0C3D42B747FB8D998629E3C933ABDDC094F0348B91AA3FF9203EBE6C1AD080\n      ABB02FB1CF4C970AE5D4B78A09E4E3ECECF9DE37CEDEBAB2FFDC7EFAD23E5F1B\n      F26B939E06E41F6B55FFD9EA7D2BDBB75256361D477F89A11489EF3A9A8668C0\n      261927BC6A3B9A8924A5BAEC91D17AAF2BC09AE35E8AF28DC14438ECF678DFF3\n      8966FD99446C66AE9797F7EEEEAC2C37DFBEB0F813F5F652115F0AFB7F329C3C\n      9FB0DBBBBD4595DEDFAC79F39D6F8E86DE78F433EF7D074CFAA3F5DDC30A3F68\n      DBBEA69C954A948635A8ECFA6CB8B0C81E7D1BB87D802FDC1AF6377231C1E3A4\n      91D25D095E75D156ABEEAE1C7D6EEDCDEB576FFDEA8347DEB738737DFDCAB32F\n      4DB61BF3B768A886BD93045BC06FAF1EEB67C9767F481A756866FCF5876072D4\n      F696207489EC2CB617ED6021C33E282363FCC5FD091789391AA223B443C8A8A4\n      7D095E2BF2EF66C9C55E976B9C33CE5F56DDF28FD569DD49EFB1C87D3FF844E7\n      6D871EF8818783434BA50D629542866951326363766710C7DF4EC8BD73283A9D\n      2E33BD2C940608A72533D3BFD151529A711B4430C149A939A0391A35D3CD4CAF\n      7302376E6FBFF2BCDF719C434DAD2BADAD72F3AB97EBCD86FFE4D281EC0EAFEF\n      DD75E484AC295181C06B122FE0456A8D86657480A4FEE7B61C38832FDF22FB4A\n      B493C67BEAB0A5BF640B363A59809C2C55BD54EC6C503E018AC6A58662680B6A\n      0F3A6B7F7E23DBC1396109565B39D1A43635260DD0140195C0453AC2CC8D9983\n      419D2157890673AC133CF606CB8FB46599910C698990385A8651BF6B6FBC7163\n      E1DD77C147E6452360A03529B708E7F2DB71F1E2A8B68463BF0B3870F2408B0F\n      9D56F59ED1EB61679D83FD6EBC248EFFE40FE42B241161350EE0A875E3F73F6F\n      877ACBCCBEF6E216F31B7B19EF4B6B77DC9DF0CCA616D6204D7522520EC37E59\n      B631AC63D4AAD81803DF2D7D37E8760709073A0147806E6AE2AB593E63165401\n      50BEE9B7E25ED5AF3B961403A7A6EAF375ADC18A2246A67A82140C6B6AA2FFCF\n      232C27D5703B99AC4DEAB89682B19CCF971F5A9EF4BA5B37B74EBEEBFEB09596\n      24F1B546B09919B166BC74A67781046A7639BD739BDAD6EB383127E33A250858\n      6A0924B9136920D48A70FD8FAFBB033B416C2D2E36E2BC9FF13883F9F48C019B\n      EA3D536467941A400A226E068C5097326CCA95CB866F2F53BB03DD0A4D41B377\n      E4832B6A81642027D0D8B011E37B4EB9CEE19A7E5CC63B374399FBA9CEC62AED\n      43B9ED547EE7A52BF0F30FDFA5D1AED01037751006D32A7C13B653EB1F038958\n      E76A246C2512A553AF19ACAB7C92570949F507D6F2FA546D354842EC44A1074E\n      3F528DF6E4ADF3B2449DFD6CB2910F6298BA18AEFAB520853E65C2E9CE9DA1AD\n      A5461AA63A750134C9A5CE3E6D002780C445BC70E9FBF1F1439677667F7B46CC\n      3EF28ECA4C1DE8DCA35781389C61977AE88AFC8BBFF75F2BFCE89E54BB289E24\n      4934E11B365E282D0D84C7026F017819189327D5A3BFF2009ED15AA4A2AEF2E7\n      FECD379BB76662A81521BC6A26D4883E90A999DF620EAD09A28E540D5856F278\n      A916DC65B30EA80FE0EDE59FF2179FAC899DC88AB57A4DA9E884AFB1B59746FA\n      D743311E645A17A5BE6BD57D47E5995E46EADACCA24D8B0565468B110EA4D522\n      72609B19C6081725EE25598410B7EC5073000E5CCBD1E922CEB362AAC4CD8581\n      A964C5E624A32834C96833D70345C5D60B1F5A015A39324FEB4C4B4A6EA6ADEA\n      F8A895C2E12A759AA9B5AC144E4B501FDF22B75EEC1D9D3BB913DD3AF4D88273\n      0484B28B10F39B6DE0405EA731B1D538730F623B4EF4A3166484E18CCAED1484\n      D4C9E001B9FEFB9796968F56DE17A4CD89BD5F1B7FABE70DA4FA19C5806F5A1C\n      B1FE2E12256628BAE41265F6CEB30378D56EE25A3FDECEA0B95196A58E60C43C\n      5F6F82384DBAC3BEEFB17AC5A35868ED4EB1AA08AB4BE2F99FB9BB7CE76C8606\n      1A3A2D59D53A6BEB8BAFB4636A23BC33DC6DCDB6745E4BF3D4ED3429B378CE73\n      0B05EF7C08CCB74B34F563A615802B5459A5D41AC7A160185F3B77F17FFFE3E5\n      03B237B63F7BBBFFC258DE9E645BF91860F000427FFFC403BFB0358C2D35F655\n      0AF87CC65C5C59A7F1B37CBD56B1EEF1EA6D4DF415F2A9FBAC0B612A63DBFDE2\n      F54BC3542DFA0B1BDBFB03CFEE291947B94D88C8E3854EF31FB4DDC7ECF946A2\n      C24076BDF2E5CB379FDF1EBC5177E7665AFFB87EE8913DFE4CFFE01F86D73EB5\n      B4FCA92377C324BDB1587925DE3E15258726E2663451015CC6B831B3BA796869\n      E967DFBBFBEA6BDE77CE7B6B9BA61755E75BEE0D6A56BCE49CAE36E83E7FB522\n      7EE26FBEF836CFF9778F3F5125BB2FEFD4B737814A47FBDEE83C4C6F6FF57F20\n      983B3DD348EA60278D3B113AE9D40F2A93BBB9BD52F1BA794FA7A07A0A750468\n      E09F8844A70505532B1AF951BA6E2FA28CEEF4E38B697CBDEA5F81F8F5ADADC2\n      F8C4E91C6D69F133D3C46E357F22CC68A70A9BFECAB1C38FBFE7C9BBDFF59868\n      B849C94921CD1CFDE96C3FE33C0FDEB2DE995EB84873E302D5FF1F08A748A94C\n      F2A79AE116962CA8F1BE31F9CDA0A1CA3527863B9B7BE75EA19EAA1C9BD3AA82\n      DE12DBDFB9D1599AB31E9DDDE8DE2C0FF295D5E38A8D64C3529516F52B5996B8\n      690C065B20CB8C0D0CF7875FDBB56F687EBC8D1E2B9A671690EA94AD593E6F7C\n      B17194CB5B377116950AE7A5DE0E38A036DB54C9CBE2C6F747C00EC630DA2B82\n      284F8C05B3E9892C6D63188E6B41056995AE8A2A81FA4F01C1597DB0F8589B1E\n      2DA466C0DC050EEA5A999DFAFEEBC5607FABF50FDF9E2F6A09316B297FA4B61C\n      A0A2CF1FE08B79ED101D595B96A2561A68165E985336A391BD8DD99737CE9FF8\n      8DC7AA6F9B4B40163A51472DC5BFF9D2F8EA5EF0D0ECB9672F2F0E8F6CE7F926\n      91FD3E3E88860288A6EBB5A9C3A358A802598431D0F6ECA645ABBEA5785AB535\n      105686BD61A8E56DC9E2926C0E27A9190185E6EAF5C58AC734CB34B310A2866B\n      B9D84516282B21AA724C6A42B0D22A5232A20E834261950DDB5663B252DE04D1\n      B56D33FFB596E37BD2C36766765EEC76968F8BBB335EED06A1ADB59A01427A47\n      14CAA9BC9A1AF59A7A993B33484D2820A18190954464568835CFBFD5DAFBCCAD\n      C6D84B147D234C2F8793DDA298683960A6C097041AFB29535BA8E912265C1853\n      76330C5F985A49FD4B150BAD607BC96E5769C6E6BBB34FCDA0653F8269C54320\n      892027B4ACA828174921DE7036AE74E3313573F9303800C5B65BF94F1A083F77\n      FF2AE7059CE29DB863B0695C81D49DD1DBD36E598DE22835079498992B5E654A\n      C130D002D5E066095B9E53D729596710895A4707B595D9172FACAB48E742EB20\n      B5D77232527CA90E6670D1B1FC32053EB5EFBA1F3975A9A15A920380322DD3CD\n      52910994B5F5EB4E9864A7EE777440662D41DE7BDA52F3C612DBD7E05A292D07\n      64C9777EF32BC95F88197BF53A5ADF07F16028F61965B975C85747DD7496D68A\n      CC7696C943FFFC21F09088ECCC1BFBE77EFD39FC6D11E1858CAFEF92F0520EC6\n      454566322162E850AD4AAB12B4415E073C00F890861C300F41547934BFEB132B\n      40C3F968CC90646329AF79E79E494AD80132BB5D8EA04215E6552DCFCCB62B13\n      07C300D380B0AAC30A147167E22CD072878A114A0A95709C4B2410D6D1C1CDE6\n      979EEB722E782634311C8B6C6C266E7BA6982A995435EA3AA40AA94F7C1D0211\n      1AB54ED0FA31928048658DBA8ECC6292B34C1268F93E6982A436D28FA89A1EDB\n      FBFAB8D845122BF5BEC1E24AB574634DCDAC4A13353A1C08E65018E560770432\n      6554A726215C7F20674C0E5277349BAE669F1B0FBB07FE8F75F2C392C456B55F\n      DD7EF6527B44C29FEE54326E158695155AD899CB647754022DFC8AB3DBF2DBAA\n      921F193A2AD181116665CA6D629506F7286634CF92A9E3A2B419B16D0BE0B231\n      4AD6DBFB0BBFF1945AAC38A59583D88608F482FE9FBFECEBD857F9A83BF2E767\n      8DE78648AD4E53D3CA284AC47CADFE830F25359F71BDE5ABB97253A609591D15\n      C02DD2F28D575EFFC657362F6F3E841702AEBED8DFFB8F97762F1D202599261B\n      C77CF0FE9367EE4DED6312C1EE9EB21499695CA1E225D127E3F0C7ACF6494CC3\n      86CEEBE56C4C344864B6DF5768978B0BD1F085A8BB5912597A93A191BB33967C\n      BAEA7EA2AD034DCA705263AEA619E76EF69EEFEAE868C6C9F62757F0BB1BAD73\n      63EBCFFAD173935BFFF789D5150706333E9E28D077B654F50B717873FFF6C71D\n      EF4124C032BBB510748E3FE8EFEFF183EDEE3887A3B4AA347D9994ED9A3DD7E1\n      9A8F434442F0D5D7B7FEE5A59B4F3FFED06FB65436186D0DF763A51941FD5A46\n      3E77B03F81F9473BED1F9AADD12A7EB9DFEDE9FCE6A10597DE85D112C65D5C7E\n      75345CCBE18960E6942A57B0D09FDC93759CD8D7D2D1752EDF10D97E196BE0BB\n      05C8F7FA23CDCD5AD2D4FF0D209F59704FB598A6DA2EA5C766838E18CDD8F689\n      A77EF0F0C7DF07571720C7566E0398283B4F09768A69F7FC140EFFF646F06FCB\n      EF8C62BCE3C203E4D4FB0F0B3EAD26C5E68A0C46AA1094348086A8F8FCC1856F\n      936D891E3EC53CE43DD33BFBEAB3733FFEF05CA529AF8CF1F25C51CF284800A4\n      797BA1F0AA4C0A960D8D8B44D147C18448969C1D152FEF3B5D44E617D97BE727\n      ED8D72B605FDD5B2889DA82C6EDDC2F10173351094B8D0CC3441D0EEAF8137BF\n      D2AB8CDB764A6ED9A33483DD4C273A1F1482305E5851D546ABD0B3D21CB94CD3\n      DFCA58C187F8EC0375E16F453660455D635BA1A222777BAF65871E3CADDE4B7A\n      9DC42A8F056307E02E9C1CDCFAE21B41DFEAB4DD42F4F5A298834DAD74425515\n      1E8528BE22464769E7574F080F5B232D76ACF8BB6F6C7CEED2DB0E3F796B7D7B\n      7873D8CE1AE3707CC0C473423E934F3C62FD80740F5B95C49806A76D15D6A868\n      741680B403ADB640A21A2394B3D1444419C905B9C2E3EFA1F14699CD16F47EDA\n      9E47BE2BD152A5818B3D9DB89A95AC12C8C99858DE12AB2ABB36CC8A5D634F60\n      3145E6B374DEB12EEA9DA4E9EDCE06E85FA7D5A252A569FD14630BE2DAE6C543\n      0FDD45DB4A3A07A6130D103386BBF0B460CF8146E818E10469C02A3D5315474B\n      730A05BD52C3691961AD3C651B5CA5B73FBF51F6DD092A6FE5E9B59D389556E1\n      9532CF1CE4C4922B665C5A415E38841270A747DFF8A441AE457DC940D969C2D5\n      365D8CAD7AE9068F79D6934838599114C48C09CAB01690251E4DC662171D5C2A\n      F8BA0B126F9CE53D067A73EDDFFAF6CBF04FEF5E32BE7798628CD574D0C9D4E5\n      08DD719F90A6A1CD347D9B8646212C64A6CF8A421AB769689CD3F5C7AA305687\n      A8AA1913A2CA5B5B397D6CAB17F736C65804FB31DE50646BD2ABB262D1A50D62\n      64B30E8AA696D5C7347CE04CF4088305C7D3654A29F6F3B479F1F5F595A3F5D6\n      421A577AEE13A79DB9930529002D905E5C9B62A4865FDD7DE57FBA580E2B6150\n      7479381ECB9BA8A09CAE78E5618FCFD22A2C5CDA910F7DEA0C78B733B6C26ADC\n      B8FDBB6FEE7DEE368147F2F26043F5DFE4653FB1A5E95F1523A6B5B55D51A00E\n      F29ACA6A90ADFA6885CE5294790FE66FFBC882508322E390A7B696DA372BE7BE\n      3E52B20501DF61DC4C312EA95E046CDA8152ADF73D889B965DF56D0E2350E356\n      07973B840FC1242B72A945212DB4AE2F4BFD1397DCB6ECE9185A63E815F27454\n      145C6896833C522E54AC0629592E6DEA262A636DD839EEA2208A644C40CDD3BF\n      06928CA4C8A2B6EBD26619BA438D67D6E6CCB5AFEE0C86E1E9779E70DF999949\n      C85A12DB250C2CE4B918DB1AA2CA7002D3D454316B44429AD6025153B1886AAA\n      95BE14AE9F5F3BF4F00A3BCDC64E6EE18ABD4B0F9E5B6BE441FA31CFE3053133\n      DFA04E609A34E9FC1C69B6AE45FE7E997E2D2E76FCCC821335B5DC29CCA540A6\n      D98119B58C08C166B8B9D27210BA9EAD85821F46F9DDA4FEAFDEC9034D7280C0\n      39D5A972831CFCF5D99AC64E9985BD71B0305F1897D2D459688BACD0D29FDDB5\n      1C3C712F775C9211545605F5956DB08BF2526C5DBEF1CD6FF6CE5F9CC3D53AB7\n      DD10F0D2792153FFF9B537BF77302C8CFD183B7668FE23FB38F3D468F3E63BEE\n      BFE7EAE8E0D278600BF8CEE52373E6685DD4FB63DBB3272D17AA54512FA3FE8D\n      2879BEB773A5C84625298566C8A55709169CF221289E0EEA9E56FB8ED25B4D6C\n      C53737C2B35E75B3569DE1831F99C1F373CD4F5FEB7DEEFCEDC30BED5F5AB296\n      6CCD406C9601BDA81B61FEDB572E86CBFE03C1CC0F8BDA925E90197C10E44DE6\n      E407114F248832AC724600B62CDCEE88468070996E753792E2B7CE9DB7ABF6FF\n      7AD71956619A8E6806250A3C4CD973BDE80BD76F367CEB8797DA4FAD747AE5E4\n      26C838711A395F2E8A59E390554C8875332ABE7F7DCDF2D463CBCBC7A497F58B\n      CD617A7534BA6EA16D4B318F75D3FC064757FA91A1E2B0CC353996C5A98EFFD4\n      C985A7899D8FD283AC2F5AAA6E393E7416DEFDE8B14F7EC86F2CA35847AAD4E8\n      234D111778AB52F00E049AC932A0FCBBC922D36A0463AE828D5BA50142A44C31\n      0A500825A63FBF7034C584C9C5F0EA0BF19B5DEF91D3B4EE3A5FB876E5E0F6C2\n      8FFF80EA85F876E49D3C96573995130C58DE99959536D358C58745AF10791FD9\n      135AB2EC8D28FDFE8EDBA3A0E23A4FB6D3E3B99C695AC10A178913976A7B5B0D\n      770935D539FA8360C9B53AE107C195AFF7D506B153BA41FB1167BD0C16880255\n      300A00150E2A16895D2B31D5C18C796091D6BB95BDE001140B4B8E55A4BF5593\n      CF0E6EC479D39979FA6DA59FA35A7D62EB5CA0583E29FA93DB5F7CA5031A558F\n      7030501828CE64AE318CA30CE290AEEDED9FF8E4C7D9BDC141E59A276CF65DF2\n      CAFFF5C5A3F7B574A877FF26235965688D53207643F46221CF450356C893AEAF\n      577344C0A156F52492333CADB38ACA84062F3F009E2335CD1DA56594A13051BB\n      857C331F279A9E66790E544E71033B773716EFE113CF75A0CEA735EC541AB70F\n      86194C1796ABE604A7E4A08C317301A82A1A62E3EF5C6050EBDE28BAD7263EA2\n      AE93B54ED626B437B247C71E5B953402542A8109F43538987A5B9D0B68864D79\n      092A253561C58CE31F006C5A3D9A2BA45FB0092F7B9B9FDF123B653F8B7774C2\n      15EEB86403309964B1D6D4A67901192AAA31D4B71C2DDA0A64EA1CA47EAB84DB\n      8054A6C5F2F335B894D98144F8946C7DB85538B9E05A324AA4E572414189B33C\n      163B60FFCD6C7C1538A2992BB021E2DD46EDB79E3B0FFFF2E1A3D3DBEBE9A9FE\n      B4F3514D4F48A7516CDE484EBB400ACD5F8AC2668C219CEBFF2933BC3633BE5F\n      A50BC162A5DEB2182B14203B7377CD20D7BE75791765B5DDB0DCA7E8D6E840C3\n      F19C5EEC525499D5A09AE046CDC5F2D0D18A86CE2C4F4D636E8930B6202C2064\n      972E8CCAD2BDEF916A6ADF90AB33FE838FA455FD488C4F498173CB83E586FDEA\n      BF7969EF82C62F6792679358BC594E74E69B77D161B76C33DF03BEC4E3FB7EE6\n      A8FD732B23AB1B8859F0E5F1F3BFF3ED4A7755B9935BC5E07A51EE4566185088\n      F221023AC7550109705E55BC8DADE315B70D3CA026C11971FAA78E88729FE739\n      4A735B03F65EEDF2376311D7F2225C133136036D6DD3F70705450503CAC7B86E\n      3BBE4D6239B666883D87D3EBB9087161BADF712A8071A74548F3E19C733CAD2A\n      06526F48999B3232AAB3579215350B2DD7AC3A544CC144FF9E5B748E372B3338\n      2F87C0D49B3326359D2C329632DFD10F45D9694A3317CC74BF9BDF7A75D75BA5\n      A73F78182CF58B48533807362DD6B6041034C745375559426C4DA7A65EF71C52\n      608DFC03066AEED9DACDE7AFC3BBC4CAE30DA9D2426F77E2E36D397AB557551D\n      F181C2E642F32F094DEFD374429295EAD0B4A49339E2BBD9F0B214004D5BC334\n      1F98D61E03C495B97060C6525A696DE75AB45E714D8BF278ECBD67D1FEC70F66\n      2865021584E342A14BC5F6572FB6AA3E954532089DD91903842263734D9EA549\n      21AA3F70069C5805D863DC29919F5117535F1320D41BED7DE3CF77CE5E3B5268\n      08CC232EB5D26FA44E86F09F2683FF706DED5A64065BDA54FD62B0B2A6FA3507\n      EA805A8B475EBB33B793FEF8CA6931DC6D7AE088D22C4D0D2D85ABD0855E9CE3\n      57C7E1F3C978D7A2DBE34427CC7A10548BEC0CA34FCCB7DA806BEDCE7C7B308C\n      37B6C657737516A8B8141F9EA97C70CE19B56AFFE47B6FBEB035F991A3477E32\n      3BB07DE796A071CE4CAD5C1DBF1EED5D1B0DAAD03B09DBC7905D7772D5882BC0\n      4A0660B340B1225AAC0B103B44752CBB4DDD23F5062DE4EB7CF27B7BD70F2F2F\n      FE6B6B46D4F4D6E3CA4C440544D29BFDF20F6E0F9E8FA38FAECCFF6CDD4E68F7\n      25D00B27F51356F5985FD3816D8908C7594EDC35A86E8C86735E958EE52D2D2B\n      CB5227D7AD0ADE55938A6B6B41DA47DEE62022661C99296DD251FB94E7FEDC3D\n      777D148532B387817D56ED65225F6435D1B4EFFAA51F9D7BE229A00263250122\n      5364AED0DF01E1B4856C2A0AEF540BC2BFC3428D7BC67A1C496E2C0D01360EBA\n      302E35C1D67083B4CE3E2B36CEF75E59AF3E709ACC36ACBF3CD7738BDA07EEEF\n      5FBAD688283BB61CB9FA1B259AEBF3CE2C0C6689DEC9A22B4359447D04270CA2\n      E2B6E87FFB76D0B374C8D20703EBB176D1AAD995F90C70969468D0CBF637A0CA\n      90205387D7C28C8CCE67D6BF33E8BD3AAE15FE263E1871AF97EAFC6D2EF775D2\n      A39AC163D1B2D00C0D7C09523A6E9EACB59F8C752287C487729C912EC335B23D\n      BB7773D4FAC461759F4D65934435518500EFE29112BB65F71B2F74824651E6CA\n      D18CB240B9870B0BCA380FA3C90EE9CD5B6FFBE4FB919FE68D10AFA9B5DF7AB5\n      E3B51AF7B017BFFED2DCFA6952B4DFC49B37B3BDB5097A1378992C66019AB3E9\n      463EDA2B9293BEFF8156FB0802BE22398F6153B96DD249582E409A9124055986\n      2684451845619C66F9061317F9904878DA9B7B1CF36AA5C69321B38B99439D49\n      996D7777358199A92F2C763A088CB8ECBA01C9A07E6D5E5A9C69FA9E58BDB52C\n      D91658C35C203A27FD03B8593DEE078B354EBA9A9C1154D5D9C3A0846904E6D3\n      BE092CA7F7C3881A39854D378D663250B20888009DB56F7C6ECB499D02A92E87\n      DB09BE9D645D31CA98D6084CE4DC52A50B70855855CF8BF22C543C45A569C4E1\n      8503AD2AA13376D976D53152AF029C2E0C673FB220AB5C698634EDDAA705D53A\n      958B420D54BC06765F8B48EC6AACD95362B352F98D67CEC23FBF6F15BC15A1E6\n      F4D6A4E5E994D1B7E61D2853F73A9D92C344317533999646034AB5284C389F4E\n      E9E62D66B72DDB851A0173AB2E3A871AB7AEEEA43D3F96EE864C76C4244A0B1B\n      E22A454D1BD7806DE96FE70C5756FDD9A59942448824A064582F341C409CF1C9\n      DCD537A363A7FCFAC241CF4ADD271E25471754915BA61177C23C0546EE8D4F6F\n      5EFCEC869B9B36916E9E5C15519E670D0B2E7956DB38D67A3CEA1FFDF0C2CCBF\n      B837F4F76DD1B6AEB8DFF99FFFACF6CA2CAACA0D196E08B41DA908C811E67169\n      76840F8C1F6F158A59E21CB79D8EFE3672C296F27B7EFA28A8F6B324255A2464\n      02F582EBDFE1C5A09215830DA059B7B410ABFB816321A4125AF20AD240E832AC\n      C6C5C05D706807F31B054AA85650B116A0B9716932CE41453E6D4D991A6009C9\n      3373A2042D271144ABC22AC3F30EAC21335D7BA4D16CDEA9ACB8500B1F250CE4\n      026ECEDE5D2C5C695519D41C41C40EAB881DE7D237373166777D6811AF445A2A\n      1439B32B33A455CFB47E9019093330307E5ECAD6385A629DBC3847D3297EECA0\n      BEF3E5BE64C5EC07AAAA11A289A4661A7E5976E1E0E549BD582ADF3B30FEE3C2\n      6435C9A651A0711F522D6E2D69AB1B6CEFC5319C08046C21CA38E7C628DA7509\n      B1A42AD234716DC2CC58576933E3DA926451F5478F939F3896408DA2A4B00453\n      447D6F7FFB992BAD4E0D15851AE7B4D348646E6BC86DB85AD0C404CEBCEBD16C\n      562FA8CD544D616F4210D3723C27F18BAF46DFF81289ACEA04A271A49732E2B0\n      A23F7D9C6E54ABBFB5BEF7C79B3D9EABA6E487E7E6DC246DD6DC8BBB5BF32796\n      0E6EEFDDDF5CBE97936399589C7195C7AB45B1CA69DC507658163078214F9E49\n      A3F55C24369DB82501F13B2CFF13F5F9861658BEC8A4EF7493613FFE9EC8CFEA\n      672FE5215E7C7CB979D215FDDAC2BFBEB0FBF99B9B772F07FF01BA11B3FFCBE6\n      E6852C8B019A59AD9F9AA936C32C0EF39B496C31B242E04A8355477C50785F8F\n      F8E5B848F52EB4B54A16F3397C4F09DF5D6BCFADAE7CA5B7F19F77F73EF4D0E1\n      7F57F5532F6659814A3B87DCE1B9CEFF5FCD834FEF0EEE76AD7FB2DAD60FFC32\n      0BFBA3F9B81B422EDB013C14205FE74733FB45BF8FF5F2D6E6EBD96407035CAF\n      A7C362A0F211E2B9C810A4BBBD64A237A1694F3575F05551FE83F9857F34BB38\n      276E8C6830AE34739F6EF4F60494769DB69FBCE7D8CF7EB2A82DBA0587452C19\n      40775C6CDF02C229BD2EE59D396CD31FCD31931946F37740A8BF29344008400C\n      CDA8794F07783678850DAE0C5EDDF40F1FA18B8DFEE7BFD77EE0A458F20EAE5C\n      6BD7E759238849C14A4E8092B5260E96A04E46B0572645DEEF524D4FB152FBE5\n      DED737ABFB7ADF8DB32365EB3DA740A78EEA0D0D7C3891288ED2EE2D158D6D65\n      9A42211045A137C4CCCE4BD1E6337BB345750FF7BB59B5CB89A1AF24D3301928\n      BFE16097890EB22BC2F852CFBC6F8ECDAF4B58D5BF41616CE75AD62DDF7C65BF\n      72DF6AFBE999ACAEC5FAAC9537A8CA957B0546AEB8CCC3EFBDDA9CAD0C440A2C\n      1DEE451E431F35EC382FE2F4EAC6F8F04F7F403E08B19F380773EBBFF73219F7\n      96DE7E7AF4D2D6F6B9411E6AF6DBBC36E617F3CD8B19DFC4D5A66B9DC0C44B92\n      C84612A1FB2CF7F15AC517A919A0679770B51CDBE1C2B09AF3B2D47F97D2512C\n      37443E2688A4E5A1DAEC6E16BFD4DF425AE00A7CBC097DE6C224B534D8CE91E6\n      82AB3FD1EE763CEA16B3EDCEC26200DD01B4075204BCE4A6DB1670CFF6416CEF\n      5F1922CD4B10663555D4A289379E3F7384CCED179AD6729769C9823961625A97\n      6F4D0DEB8599384DB0164CA675855B9AFEE4F6080317BD106C7F6940B996A4F6\n      28273787F25A34DC4F0739A3B90E0F2EF4BFF730AD60CBB1689AE71A0843CDB1\n      4B4521D23AC42BF1A2A5132F386EB7EA088E5BDD851F9A458B64DAE3504025F1\n      745A9BE63BE544A25D7BE7C57EB253D0D24A98BD11D47EED9BAFC2BF7AF0E85B\n      2A707A9C8F10D140580831B5947B8BC2DD39359D6A97D2943A4FBB94520D8C42\n      6B70A6A58DA364D3B69A9EC78444F6E4F099E6FE66AFBF81A0D5B9990CD7F3E1\n      80EB98D54C1ED571D904B8ED793A19525B1E5AEDCC2CD8B9D8259A6FC14A5E76\n      89155B68E5F285848BE1BD0F3727EE3EBBFFA47BDF8958700D3596DEC8E6288D\n      ED7F3F7EE1DFBFDCDCAB09C23665B427E4301BE9C59AAF54DA169D439695C4FE\n      7DECF86F3C94AC6AD5E1DBFDDAF7FF9FBFAE7CC6292BE53E28B638D84E445765\n      7D626CBB588A8C618705AAB89C27F68AA2ED80389A4BD6F9E91F5B8547E264D8\n      7372067536EDB15BDF2EF21D1793EC3664719C4BA13CC7712CE862E9615181B8\n      E1385AE9A530B266EDB2AEE49A00914E4720D1FB472105A92228157AF7109D23\n      FE3FAEDE03C8B2E4BA0E4CFBFC7BDFD72FDBD5AEDACD748F37F0437810A02452\n      E4D282945614E5B9322B51A2A895960A29184B29C40DADA80821965A0A028D68\n      9610810106C080C00098194C8FEB9969DF5DD5E5EB7BF76CBE349BF91B5CADB6\n      BAA33AA2EA77D57FEFDDBCE79CCC7BCF35BEAEF301145A3651DB9DA5A66FA5E6\n      59356392CF4A91D096ED1DAF705F6B65E9204B944C99835E885D02224B062547\n      B95560A73CB6F3F5EDFD83E1C6BB4F349F0E52B1072D407C8F54EBD0894CEB69\n      12A3E9D8D8F9488B49C2B5EAB0538813AD72C3FE4AF75B83513CD9F8C83AAFCF\n      941914AA3353466C594EBDCEB727EDFC14FAD0A11993289199126CCD27EC6ACD\n      A8102F53425C356B1E7C6D0FEC2428B725A2195089943A9628B6F40B599146BE\n      ED397A357002F4C2288B40D53FFD98FC504B4331C9B816782E0AE4F3BBBD176F\n      5516AA3C4DED02E185FA94CD7C63BA426788E5F5B0FDFEA7647D91A42E123581\n      ACC4A7AE5E52770F6FFEFE1FDBDB77158FDEDEED12E45CB01B419C16C5A8A280\n      5DD6BF81A2BF7BEB9D6BF1B45A8A292517A41B7A641724D556D31EB33A7559E7\n      F0CF9D3BBF00182B7A176B8D739A3BBB45A88551523C3F9B7E6D3070DA6B4E18\n      F678AF62C57FA6D2FC988A2A424BA8641CFB47C9F89AC85E9C4E9965BDABBDF6\n      28914FD4A08FD2BEB3F4EB57D367FBC3BD64FBCF5AB5F5D367AF51F1CAB877AF\n      736425791B8063AEBDB4B13E2D1234995458B1E0D35AD07AED68FCB5D124C11E\n      10BCD9B0954C5611F8F8B98B6D6175F73BD78F7637117CFFF995BFB314C0AA94\n      69414BD7522204B98DFDEF1CE1AF4C547FD6FBE1B34B0F79C225F0666E6F695C\n      F2AA76E7E814CA9B8E12A5CA5870796FF8FC68B05BF398E63FF70E8FAD1E9BA4\n      2C466A7FD2D30C844B904190CF353C96E4E1C0F95FCF9CFE689C7277FC4EBDF1\n      D2685285B4E5F933310B2250D9587EF87FFE1B7CED4CA819559E315F51735E33\n      B76CBCDF2601FF7B2054DFEBADF853202CCDF1967176D49F53A25738D37CA9C8\n      27AFBAE96EFAE6AE152EC108EFDDB871FCA9C7F322EDEF6DB64FAD138B140210\n      079911BB6658EF3193EE9C012859B9D7B558062C260672F0954ED4C1C88DF79C\n      EEF27B1E754E2DABB6CF6D0F6702F19C8D0EF3DE915F025C9AF6A9342F6C509F\n      DE02DBCFED3666FE98643D56E9E55A064D393536240B3AF20297D23CE028D478\n      709E859F0A4AD4A38CE85F2E4019E46D75B5D8B5CA637FF971DE2620770008B1\n      4E6B3399576EDA59C49FDB19DFBA553BE6E76A3E9018C91294EE94FA7973FFCE\n      E678DD3FF7D7BE7F5A19D6323CFDEDD1E67357CF7F622D1F0FBA5F12B2E30E82\n      D1ED78324A5B23575E1F1D16A4817CB12805E94F6958092CF7C94A6DC3478CCF\n      54512E57ACCA5967171C2E8876D68D49EE62E51D65E5D5647CA748B224BBB87C\n      1A2B7CF3A8A341C4362366B35610F80A785A9AD5F2E68AE64B44F2A8DFCB079D\n      5154F11774F8D7CD481A535B48A8C4803AC4A1442432D98ED940E90C807C3CA2\n      DDF69996FB78AA80954CB8164B88148E635A664C35BB32F67B26B3189E624398\n      A03232F679DE8800AFFCAADD7D3E333D12018967D6D6A8EC6226889CE6FC681A\n      9BF8A1C43163EF819958814CC54A264D89A783A94F6D2D631629AD38701506BE\n      2866B5DEDA9F59B1CEB8468CAA126B355712C5E763A439B33BEEF0CA747A6706\n      33C449B417367EFE6B97E11F3C7A5CE7625323336F7B44E62412B3B2342D4066\n      FCE1BCB342CDBF0F8D05CBBC8615991A67C64D75AC96359C135EEAB5510B3C27\n      D77778B0BEE10209766FA780B60F8A782B1BEF6B89005D0A601D8A050B2FDAC4\n      8C4E2E511095A7CF5A5E5494826B06A1C102D002016FD4433BF726671F587156\n      066A29F41EDD285BC6D1DB87909AAD75C43BE4EAAFBC8CBE95E96CBD45E28C79\n      87E9A116BEEDA8D1F6AD6585DA9CCC2ABD33BF78C9FA50538392C51AD79EFF36\n      FAE733BDD06690ECE6BC53967B3CED99267862179828045C1C20B908C8096155\n      2BAAA2A102971B9F5CF0DE43D369C7CE2D5C14728C8F5E04E91DAA49F30EF4F3\n      42649A9798DA655873618D801082909AF965DC17EEA2C7FCB2BC9DA2D85871E6\n      9A5E6A690389348A9059B63D27CE6AEEE6AA392DB6A82D78A96953A4E5B51218\n      A7991C34366A74D1C98D5515211003C9919D23FDFB6D47FA6466270C662DB1A8\n      6E586F7DF34678BE72ECFBDAC08935D6601D177547EA8C086C2A6CD11F2A9D76\n      B16902143A10115434414EC104C52FC0D1DDA9F55ED7BF64E114202DD2001368\n      E45A341F83FE1B593B3F4BDFB7AD4C59A07E0B186A1AAD1FB066C0F9DC8D9850\n      8D4C831707EC8DBE97574A42A65003E1BC04D958174BD7B57486D3F1A9112C08\n      2CD3B472228CFEE2D3D979840527A9A68FD8E536FBE29DC95B3BD15A3D1DCF42\n      EEA0766D564C43AE548075BEF11E3AE53F78815B0D9B55210B19A21A102B044E\n      BEF2C2F697BE9EE7D3EDFDECAB836C33874FA1FA0F576BCB60DCC819E95BD783\n      C5BF7EEFDAB7F2899569F5EAB89AF902206D4A2CDA16B6C74554F72B758BECDE\n      FB985BFD487BD966396A7879C16F67E99B367A4B82DE84451C2C51F6C46AF058\n      C55F893593A4A349BE3DC22F3993AF94072DAFF534AA9FE0EC5C3B6C875CB3A0\n      1D54FD8DD7BA3B6E7D023A6F77C7AE65AF2E5681A76477B26CA6C807CF0E3619\n      057F7669F5A3B4E60AD125EC75C99EBFB7EB47C19A570D338DFB36AE6A6A16DC\n      1A0CF73A1D7FCC2FFAB5A5206C12F1B1157FED5895B18C14D4D69800922910E3\n      2C7A6BBFF8C2D1D6E283B59F5D3F71AAC76E59D3E7F60F3A983EDA5C7E94CB3A\n      CB8F3078613CFDFA7E5F2C1DDBEC0F5B7E233F1C7935EB40A0FD8439AED51B77\n      C5BC215087572960208B1F6935FFEE89D573D3A39BB595CFEEDE7D19A40B15EF\n      89A071963A36C9F215EB99FFE517C8FA49D7542EC49A2B5A82A2EF992BDF9F4D\n      6F864CCFDBB2BE37CBFEBEEBCC7F0342302F96318584C9FC9CC0132CE1E95B6E\n      BE535EEFF1993DC559EC17A7D64E26F78E725A54CE2D81DCEC77C29A5FD8FA1F\n      87E055530FE50FA548C0F6C0D28BD449C5508EBED8AD0E093C85B787D7DB272F\n      860FAECB1354856D949BA1CB2A1B4EEFDDF693926AE4C7302D730C22D8F737BF\n      70D7DBC599638F58D0CFE1444C4A92E8B5B88C5B6DCBF1894EA8A5E5E6CDF751\n      F978AA591C2D33C50BCB5B185F97DDBDECEC5FFE003B5B661A26E2BA4735A867\n      9AFB25DEA186D6FE67BFA35520691B9320927B99BE614E162416DA0A6EF747AB\n      7FE562FA3869B065F987C3B77EFF1BC79F5A6EB4DD2BBF7F1D6D5525720EE8E4\n      4E961DA5568148D3D6B941DD100701861BD5A5A986E959BCE13B2BBEE62DDC29\n      D5D9D06B9FAD0C4017424FED4CADDC9D0ABA1567079C0D91DA1A7635D189AAAD\n      59A225296F468D0798A804A866367054B5C52BCB82418EA16F617BDC198F8E0A\n      BD94DB4B41FDB85E33D834D4110D2F05A02CF41D3853076F0DACACE97895140C\n      BD06F43E90C15A2D8B136861890A0BEB1F8591D66C9AFD40AE8899D1869413E3\n      41205AA6B83EEC53EE8C7F5F765F94339215B42862EF602462E3C9A59721D81B\n      4ECC79F2FCAF31032BCD5E3621C6A9D145B8026905530FE1D0588EA065EC3865\n      9A45C3C58F2FBA0FF885BE6142AF336CAAB30A531E2801737BAED856A36BDDA2\n      67CAECBB95959FFBF24BF00B4F9EBE7F3AA8AFB060A5216C18DFEFFA9817409B\n      D835E007A89C5B4918673C29B8295E35C7011813C91864ACEADA55CFAB8350F1\n      41B5C59ACD70E7EE38C98319A4072ABD391D4CA103380D956C50B64CF8A2B762\n      69585483467BB27E2A84B450FAF652DB54D6EAD814786F4B2302397E49A180D3\n      3375FCD8C9B16BBBDC7504CA3D4194DDFDBF6EEEFDFBB7B52CBF8B125E0487C5\n      D12C17CD706121A4CB421E936E5FED2FFEDCFACACF5C28CD296DB87FE366F23F\n      6902A3259C3760702F4F77547A000A8DAD06BFF51DB28125795BA00768B5D6D4\n      EF13F1346B3FE5AFFE60958331D4D99D1538A3A357D1E82DFD4CB30318254CAF\n      FE926B56EE5B4D9F84A068EA046BE6CB7054C1EE9257041C6C329C6080482ED4\n      28CDB2D20CF22D85865F3A2FBB356068264E304009F1A8741474915EDE88E1A9\n      DDC8A213AE7240218898DB51110A2C8713DF34C41744159E612CD1ACB1F3DC76\n      C6D8B18F2ED30D99CD66155A030D54BA44388494024D733589359B13C8F85C61\n      33E39968358A5D27BB95EE5DDE593AB3E83E8146605803CBA0B0389C62C23462\n      17FD627CB76816A7F1BB7724B294C64003841A96158B4B2735B64966C71C85E2\n      06CFFEE42060AD6CEE0438CC8DF39B6B79D84065E959C886A50E46CB51252CAD\n      A7572B9F7E62DA2E282BED52CAD0D6E0D9FF9DD7D5CEA87ABC391D4D83D2211A\n      08CB695428AD163B75D8FEC8D3A8B958B0008B1A2A43413418898A8D3ABFFF47\n      D3E75F99C9F2EA61F6FC00BC3410AC33FBA1B60683C6D9F14894F4F348FDD2F6\n      C1AD94D9B957D07CDE2AABE6B542CA5778115A6BCBAD5B475BEF3AD1FA21AF71\n      699C6E04D1C045296377787A23B25E8DB378569E97F6C7975B673D018B01C2EE\n      2873F687E232CB362707D5C5E671373A3E4D2F848E1F20E228C7863DE47DF6AD\n      83776660B1E2EA5C7867DAD3A9F7825F5BC82D069DBB32DB117114B80F08F450\n      4C97ABEDEBB4FC2FDDAD9B49727AA1F100708F016B8ACBBB24DB8E6785D9CBAA\n      9EB06AABDC0D180C40FCD4B23ABDD4E030D7310133A145F89125225E3DB83DFD\n      BC9C7CCB1EFCC34B8F3CD363A3BA265295EF0CFA63CE3666F2BC53FFE6ACFF1C\n      28B6671C6590F895DE64DAF06A3BBDEDC3D09B082B8484B16101CD383ECE29A1\n      F68A487EE9C1739FB055B5E8FE1A3AF9FC95D7F3850AA8F38BD8FEB8D30E553A\n      3A463EFC4B7F3F3A710A44A440B952582FCF3F9DB8336F96B83F8FF07E11FD9F\n      5A8BCC8150DE77A085802BD392A5A332015A23A940CA8CA7579C7853EC65ECE6\n      6CAA33C303D525B736FDEE35FB5C9B9FAE6891E689503682CCCD6D4EB05A92C2\n      D3F914C8986E4F509A9751AC8622F9BD4E9850F8AE60F3CE9545BA1E3D7D3E3D\n      AFECCABAE9E7257AC5CDE2CD9BEE68667A3F28CACA0200DB4E2BBB5FDAE16FC4\n      DC5F9865745CC281986AA9AB574B9B56DAC8A999B3DB58ADE4AB1F0E8BD5AE3D\n      AD2BBB24806677CABDC37CFD879F81E75DA017AB0CA9BF60C828CCF545E907E4\n      EDC69B9FFDD2DA42C398C902E1E511973827B390445BDF1E341E7B24F84B2BA9\n      D5755FA9DCFA67DFAE2EA1A54F2C6CBDB2977E1D05A2D275665BAAD89F5A3BBD\n      D8AD7A275D3F92E23579A875CB31AB5D30C04571A6E254314BCBC452EA81566B\n      F94465A84616216A3BB6583092F46677980915351AFBF9ECFAA8A3BC805AC168\n      927951E5FDCA23280E108E3CA7B2C02BAB5ABF690E9E0391DA82A63DBBB39BB0\n      220FD6DDC576D5F7A5A24549454672EA80C08AE2CDE2F0CAAC4AB5C0911815F2\n      FD71E5D452A9693FE5FAC122213468999E0AE3A105CDA479E3CF87A664148836\n      C868E1F69CCC3AFA5C9EDD08BB743A867139F33A133EC685E6D014FB895E39FA\n      1E1A533E787F76A3980F70AABAEEA2262080D4C57C2EB0E9C5408B961B21C6FC\n      71ED7D0DEF895A46A7589AEF1815C90D2B2B30F3472EEC91F8EAC1ECDE0497B5\n      71E5D4CF3CFB02FCE2E3A78C1180547CEE6DA93FF1B9F7DDF73E80340DFC1096\n      C62657980D7D332B44284490658EA88D478034632C312F23DF5BA2752213CF4B\n      1797BC4E77369CD05486872ABE95F5BA252A73C758C391C91292C7FDF5C8693B\n      582B8783E515727C4373FC11D7624539D8CBF57D9BF66A37AE772E3C5C6B2CD2\n      4975147E7023693608AF3B82964EA11C52BC307AE59F7CC54B2B33A46246FB6A\n      3229A486E3864F96A506422D8BFACEC7C2337FFF3D85976B21934FA7C92F6E6F\n      5EDDC7AC56407B2F4F6EB3E99E349D6FAE198E06134B3F38BE8CE843EE425449\n      1A3AE34F85BD21CEFC785346B1984A559416B747AF89EEE59494AA27BCA90642\n      0932200397ACD4DC1A14750C09D72C5D802A76967CE696785BC8A932071110CF\n      8A5203A734B32FCC8012036240B31BACD765A9BF0D61CD919E5436F1353E337F\n      D63A4349A3E48CB1C291C82E21D360E439843A8A81943BB85456285B876F76BA\n      9B7BA79F3AE15F702670684BEA393559D7FCCB631A71CB02CDA6B8E080B8A556\n      F8662F47426163B4303B2847DFD8A267C8E253D5540D6DAB560A47942945B905\n      286484F5F2C96EEAE363DE131D816CAE239A58480B3C0CF2716A25661CAB0624\n      451C779FCE9E3B208348D8CE0C81CE6CC67216B9BE633B9A1668E88C6C68E2D5\n      16339E443F70DEFFE4996990D805273A1345361AC0C3CFBEEC8F736F351C0E66\n      15189146A81561247081587AB6D5F8D0938246B0884A5995A56B3B510A53DF06\n      933FF8FCE88FBE8994FFF9EEE0BB5AE983957BA3AC3BDAFFF9874EFF0C422E60\n      BF56F47FE5DE60CAFC6A6A8F1D33B81C9B1A46B363A2A337B22D97AB06414FAC\n      B536D2EC07975783FD0E21210FADAB38F96ADC1948FC70B0F618701F089103C7\n      3A3BCCB87555047FBC37B8921E7E7261FD7C0E1C47ADACF90B2A773816583369\n      3523F0F9FDF12B7BB18B9D8B79D9AD826D592CC516CEC14E9D7651B154809645\n      A72C0BA0BBE8B7F684B8CCA71D5C365C7A3C5655860F6C708B16A4949784730E\n      068E16E95CE512F830F9C8B9A0BD762C4631D5773231A7CD63A2EA0599EC665F\n      21E2335B5B7FF3B1E33FEED772D183853B76C2031BDDDEDCA620E810EFF337AE\n      B757370E0F0F84E774F2BC9FE51960133359C1A54273559671A60305401F8AE4\n      2301F98767D61ED36C374FDEA7E5CA1B373FBA7A5A3AA3E682DBC8444D32B068\n      7FECEFFD8DEAD34F98C1638AE9D5814C35D59F02A1395086F70F05E746A3F7FD\n      47E76398E0DC63C48C6F328AD0BC1C19209426FCF332BDE22577791F0CBF7EC3\n      5E08C2F79E02DDF1F4F65EEDD193E3AAB24AEAE1BA08ACC2C92D49086F091530\n      AFAFE0CCDD8DC12CC96A0919CAF273079EB2C4275B5B6FBEBEB0E5563EFCE8E4\n      69EC792788BE8F149A0E997B77AC4E8FEA8C863193660FCC66D1F05BA3C9378F\n      727C8C65325568208B4231C701154257A817951A1C46F431BBF1948D9C23CA8E\n      69986731DE7FB3B7F8E1A7DD675A03300BF3BAC53D1059319498E78EE8317F09\n      BFB9DD7FEE85D6526DE66438CF3DE6EA44A7A1A1BBD32DC2C6E91FFD70726CEA\n      779C97FFC5736E277BE85D2713ABB8FEC2A1B515B582E8AE185C17607B6CF506\n      4954B3CE444143F157D3FD6C562E825ABDB96851793EA22B58F527DD89981E3B\n      B6545FA9C465EAE579E75EDF81758DCA9D713E98A59062BB127607FD6C5AB8D5\n      C6DB93E111961F096B0ECA03A94244A93D5D38E1440B3ED65FCABA652E1CB05C\n      A45EAF37E88E26F50A595FF3FD054D7A66B1FEA4F92B76EDC4ED5D1BC8231149\n      1F1770F060E7D8A535B080188A8D7DA5497302D2B9B31AB1042660EE399CD3D4\n      2D9B3A1D94CE1876D4DE7F4E686F694F8D7A4A8353352EF1C42E9324E5054EB9\n      48353AE9F044606EBFA5B42C74096CB85E1B5B2D811ACA3411C7B8A0C235C328\n      746EA4A3E8E986F7BE56660DB1E6744A4B8E79AF85523165C1C44643586C0D46\n      D7FB701CA4D50B3FF9A517E0B38F6F6872AC7F8134F61E5487252B8D3CD1E161\n      53736E359F5FCF852189668A8A197DA19152C733A6392BF5375CCB32163A455E\n      AB440B34F2A570F07461D19DB0A23FC459E91F94F126EBED15FABF56CD511C1C\n      E9C85DA68D5AE007580B0566D1C9C973B8D68299E6A156A4F50B30C63A4B77AE\n      6B5223CE3CBC32F677C9A3AEFBE039AE5AB670059EC080A003FBA5FFED5BC9B7\n      862DAB79248A014807855656A415D8AB165E347670B9B8C81FFCA50F156BACD4\n      2901E0FC3F4D2E7FEEC530694BE0F541796DDADF337B805427F882C304490B81\n      658B9EB75A95205E80D0CE08AB8E2FFC641B9D106296AB4C2F2C7B768DEFBF34\n      F4326BA22A939C0FA44C94A4165CF0689BC09686097D87308755E22C7AA99620\n      5B0CCE4C79B8306395F82C6379698631AAB9F98666473631AA5B3F008A50DB83\n      B860C4F227AAB45661FD1406F69425A52C03401C6695C4812EB4048AA59B9654\n      73F856B14936DFBAB3FA703D3A6F335A408E09A676DD1721802562D35C8B7DAD\n      CA88F17454C0D11928CB397750138C6B575FDA6E4E79F3130DBE9C23BD4CBC56\n      0AB3AC18453A740B1D725EBE3B191F312F5AF71FDA9758C32AB15D1B59A61552\n      26191A17145AB1E6D84455C6E1E4D92ED87319C1B1A6263AA472AEA99FC64DC7\n      77229B84483F7B9158E59896CB9F7E923ED998C19967DAACA5BE05B80FF73FF7\n      DDBAFE494D3298A40BDE92F2709C8D43E88C54EABFFF417CE98C925A30D738A8\n      9B916F7A6D1957FAD9C16FFD1EFFFA9B442DFEDBDED65BDBBD47E989DED0FADD\n      CEDE4ACBFDF58D93EFE5EC33C3835F1C0F8789D7C8C0984C1D6E0829334D20C6\n      0353D95A59CB332BADA5EEE8478E9F6EB399838A47F3F6514D3D97ECECB8E064\n      75F5C4A178DC8B6A0D8D9DA388E87C04BEDC17FF6E67F7FBDBAD4BA1DF2EB2E5\n      C530A87131EED549039028274C787C735CBCF0CE4166858BCACB5419CF9B2F73\n      C97B1E909A1D4C4AFD2AE65A99E41E31DE1BAF65ACEBA19315DA4C26812431B2\n      0B405BC06BA62C28992D4BCB4776D3AFD7BD45DF796532DB53C95AD3BD685556\n      4584E3B40E55779ABE595A5FBDBBFBD84AFD936BED46B9D71738E0AE56FEDF86\n      D9372693163D7EEFEAC135908A5395C1C191CE2A77D344F8F3BA16415D445491\n      1B43193714196FC9F46FAFB73FDDAA68422504AD88E1C9BBF1CF05AB0F0572DF\n      4FEED122C472C1B13EF857FEC2DA8F7F8A114919431A0028BBEFA5F5FF01C2FB\n      AD14F7B110FCA92234908844690AE0B440D30F02E974C701F295CCCA4C2BC23B\n      E598DCFCA36FAF3F7436BA7862F8D615127AD1E995441594FA16A9481B339213\n      A04959032847E75301A6EE5EACD2595C4D9CAE92BFB5EB789EFC891347AFBEE9\n      7C7D52FFC8A3A30FD9BE77DA2AB5A05080967C6F93EEEF03CE4DB5BF51AC8CA8\n      307FADE83EB79795C7405EC6A5184A338D37F06168CB48C8A64DE2606ABFBF56\n      7BC02649075827C420DDBABAD77AF77B2BEF3F23A3693A8D1D55234E8B1B0F39\n      C8E5C8A303699F94DFB88ADEBC562EE018E795992958CB6864C7D1CDEFBE79FE\n      EF7C327B38B40A807F3FF9CEE7BEF4E0FB56740E2D34085ECEF994BBBE3C48C4\n      9B137A93AB51395A0C6BA791DFB6E421E57BFB83A6D3744347A4BD272BD163D5\n      6A9CF53B64DC38D908A24A91164E290F8731458D2C268793EC5AEF28A760B15E\n      C3E3B4AD2FA856FBE3FD3B3749FE84BE2ED73AE157966DCDE7B38AA6FD1A0803\n      5C8A49AE3934AC22126AA210F7CA716FE0DBB8BD64BB8BA0F08A187327A8E3C2\n      141B0CDF3EA463C72F1AB7DCEB0BE7AACD27164B3A2D94B2209EDBB070A09306\n      7539C05072ADA110D504290282408FA7778BD11F316FBC727B7670544E3CBB9D\n      4838A4F99069B6AF630F0C649E609D524A2D1B6AB6EB095527A466D196EB5420\n      0E94D6F2A6CA1A9421E572C157A51ABB976AD1C796337F48B94E7D54CE270123\n      09A7B40C638CA72A3F8A27EF74C081CB828B3FF1A56FC22F3F7E4A9A893FE6A0\n      D0744A5003E14551F0B2B41D47032132EE235C002CC4FCA7999D2E6966A89B5D\n      31B389AA430503E8521CF86E2051156BDD31AB344D0B636F02B2CCE964E90EEF\n      6FA7B956B1985026C7156137206D0420825ED3AA503574C3CE99079690E922B5\n      189C943C8BFCE574026FBE7DEFF4C31BFE2936AADD6BBFEF51EEAFCD8DCD673A\n      8B11BCBCF9473B77FEDDE5E371F3C8CAC7821D31364B78C3B157032D88B42443\n      5934B9F0779EE4CF848C642120E9778A97FFD557ABBD3652C1109677D3E9362B\n      627DFDC6FB50A5484B1DD0A0F0248CDA55BEA29F7FE9CD48E7EC8F349C877091\n      C52A814EE9E6BB7CFFE5A13F7073190CB91848305666C47C95AA4502577CDBC7\n      6623597348AB6DA734E5B70B92CF1D1E9548199F66655EE838708DD9B7BEB91A\n      A2CC96B76911D539B96661CDFCCD7E4A0882532EAE671A3D75CE26201418739B\n      1BBD2128C7938C4E2071C362EDDE0B073480AB1F6C8CAC4391812A696117813A\n      6608A32451B34C961060D7D8E4810299D2D3B2841EE4B5BB2FEE58857BF29135\n      16F573E3CFBB0C2D18E37199656166934C2F4D27B99B4C07A8D15A41E7EF49E8\n      171C7BA1AF79A50E15C80A30CAE695573AD26795A436FCCA186D5925841351CE\n      EB0120E765A124B650DD771A6664AF3A22055BF24FFDDC7BCB7558E433DFC833\n      53488677E5EE1FBEBA426CE115BD69BA543F29519926232071B918D63FFC44D1\n      AC9AF650D010A802ED48A4A565C3F2CEB5777EF3B7A34E12F3D5DFBBF94E87C5\n      1B56F5705BFE5637EF7AEAAFB72BBFDA5CFD52AFFF37279DA34CAC64AA07B379\n      BB379A8F42305B76C278D9012DC61F56EE076CF7B483D74FB6CFF7C95B6A781D\n      4FED30D2E17B3E5A888CADECB4698B45A77A6F087FFDE6EE9781FDEF833671B3\n      5ADBAADAFAD64C1D2C4A1094B422ADD276CB3C072FDFEADD982507CE922B6905\n      C842A50C1A7E902BC0CC163AF2111AF029836C4990CB09DBB2C1BA2BDA905789\n      454BA755BA9598458165D5483B7256AA961D296C839C595F3E9ABE7178546445\n      9B90C7EB4B0FFBB50597CDCAE27064DD3E94B761FCF0471FFE687CD8517C650C\n      DCA9BCD9B47E636FE7708B9D5ABEF49BDBDFC9972A9AA24E4669E9B984334D85\n      5D485256E61A9D6CA2A1629D049F3CBEFA833E7D9C19A7CA03DBBB78F3F53341\n      F46395D5A7D23C77D9AB640C7CB06CD3873FF2E1F7FCC2DF928EC25A6929D7B4\n      887D0F08E7F8F7BD4A51F9DF442198CF614286FC99334283914419531AB367C8\n      988575322BDE46C3EB72426F7FFB8DB5271F8A10DDBE7A79F55D0F2A9D65B45A\n      756AC2764DF1BC2A852686B086049574CC61EA1C4D553A990589DF47C57FBA45\n      AA36FDF499FED54DFCC79DC67B2E8C3EECD2702310D090644B80C37B68E79E99\n      7E864D9AD3AB132317DEB476FFE86E91ACA052C48CCFE6F81DB848A72557078F\n      9C4617ABE107560B127B040D06A47B6D7BEDC1F3E1C79E9A0630D22F4EC6D2A6\n      CA5BCAC6D04525B2C7828E48BE3CF9FAEBF6DE2E8E642C99A339433EA9D48E75\n      6E155A9F557FEAF4D81DFB77BDDBBFF2D262A3E69DE0793C229DFAFEEB2CCF19\n      8EF8D10CBDDA85D751D153838AF44EC0CA5A434B4A7BEBB0A710765D1095E34B\n      D07A4F6B59E259D2CC83E3A1CD6D61EAC3C9E1AC2879D03D623B59B1CD336EC3\n      A52010BDA1CD34E508AE6493230F5DC8F3D5A8DA1468A35EAF05C87632BF6103\n      4B33801C9A6902A6B54E2F616306947893237DF3CAFA31485AC514177EA3A121\n      DF2D95EC15F9A6F0D28583725F56B2E31F3CC6C3143888E7A5438904660F4F10\n      5A1ABF19666333D04301D76C3DB8CEF0AD3CFFBA7286B57B935E1F09C6AD6196\n      1EC8E908A22AF44C49BB2AF68B692C4448EC26A44B802E601240D8885CC7C17A\n      2187217441964C5D4BC20AC9B56AA167A3C60F9ECCA211D58A50FF31E57D5ACC\n      C11955514E512EF3513C79BB0BEFB9393EF713CFBE009F7BEC94C959846A19CB\n      CC3924B26C3352354B5333B6DE8CE635353225A45A260A9D3774F6C63A48D47C\n      340535358179A161C4CC9725A04ADD25CB7259E286A0F49DFE8C97DC1A67E53E\n      9BDD8BA7A59641D48E450E0BEA4BB65A054D1C35542DA205C6DD95D5CAC2725D\n      5909D06C9862AAB304A0B7AE1F4855B9F0EE8559ED96FDE0BA7DEA2243C2C289\n      D970F657876FA6AFFE932F2FDC73520FCC14E84A314959155B7597341C52D1AB\n      0C4CDB3FBD11FCC563A597FACC290FCAB77EF52570195AB23200F9A128EFC469\n      5FDF7963224C35DC60A4349F58C3C1E93A5D06A822FC828E973E48AB1FB09252\n      0B18CB63361B8883CB23BAA5432318297524415F484D9D2228961DBCE25A1587\n      282A94D6326D47BF7CDE3E014CD130425A68C74519A725D30C89BA6613DFE482\n      9252ACE3C4324DA3540BF3991807275C7FDD2A69667C8DCD34019D60A4A00221\n      622B3B77C60CC455DCEE5D4DD8942F3FD8E2ED38B733286D1B7AB4E12999E49C\n      A06C62698497A4D47182B0714D2F66C68C5145BBD70ED25172E1DC45B1AE4524\n      539AA9057E61E59894F9B8B075ACE62926CEF8769C4FED7663999FBD2D956F3A\n      37ABA119D5A655152F597F0AB9A55C4DE7674E1A8EBFCDE13546F423969C1585\n      85A8009241FDD7CC7FABE9DFEFE0439FFB4F9D5BFC898B4590E22CA59A2F8252\n      8719BB1E77BF76ED58141662344ECB85F6695ECC8A741C436C8CB61F3BC7B49E\n      5421069A9707CAF18DDB78C107CF3F7FF7B9AF80946D1E5AD621286BCE3BECE8\n      BBB746AF4CF084968F94E0B7DEFFF82B63F6F377AF4F14D9986577E17D6B683C\n      3FB1E2A62E645EDAA125493BF09620FF48A3F118741703FF10E5339E79895C0A\n      1A9B6967E8241B0DEF09E23780FF4686FEF1EB57AF2FAEFDA66D9DADD1C8037A\n      519B7932A6C5C71D9AE619D6D4C21C7B7733F0E2F5DB7798CF39A160EE406D6C\n      A1548E944550981702C9BB381E94EC3CAA6F15F21D94F9889FAC362A9A9017AA\n      962617017F78216A3403CF773D4B5FF14C8AD8A2A40F6B59810B287778D219C5\n      4D292F2EF94D2CE2CDF488B77EF1DE3B070F2FFC63EA56387AD0D3F794C504BE\n      92E4FFE1CD9BB368418595B7766E43074D341320A46A2CF01535552B78AA7930\n      281E93F0A74E3F70A2DE103BF79E722318059FDBBDF91555EC264980E9279B0B\n      67909D627E840756052D9D38FD63FFF017C8994565B28DA3C9CF9F6E8DFEF740\n      38EFAB37FDC9F3DDD1797F353085930608F17C7A7962C650941622BCCCDEB092\n      BBE2501CEC1FB62F9DA357B6877CD87CFFB994150EAE61BF5E124C44098596C9\n      1E401E2EA1C271A9D34A7FA8B251E616C1111EFEE72BFE5A447F68BD77F3C87B\n      7E1C9E5F9C3E13C085F39149C2408B04D8DD81BB9B9AE5EBE466EAA7F8442F3D\n      B21B6DFFDE66398EB0B28C19303153726C051CC2001D88DAECF8472FC9BAAD1F\n      5C7C6F67670CDB971E587CEF451DFD360D2DD350942B5A6422542CB45082E854\n      2A46EFE1779E7FB6E2AA1563B249BB0E09740EEDB1DD83F1FACFFE006D242816\n      5BFFE7E5C9ADE9D90B2BC8D58B251CDC48BA5B9A32EBBCE16E67ECC5D16857F3\n      7813B88A987D1EEE608B436363BF5EC11B04ACA4EA74A505EC849C10EE32115A\n      1EF72121DEEDAD4E3CB546C2D9926A62219865AB816F5B28CEE2342DA6006840\n      5D09C315BF96DEDB5EF1703D20C4918D65CFAD40CD9835EFC0A00066F432E624\n      2572311D78A25049B1172D81DAF146A2497A80B27452B782745B0CEF6475104D\n      ADA97FC10ACE7AD220A430AC1399B24D61DC5D4CC7A9860DA841D6D17A5E73A3\n      B0FBDDAC7849A19EDB17E5D0B376873A0114876CD2D519183A114053070D6599\n      8BD2074413E16396BFA0AF0D4AC7365D0E1AAD1B4DD2F065EF705E44C8A75495\n      E064D8FEE1536963EC08731664F6004C71164A097033A9C35014657A635CBCA9\n      26C5F19FFEF2CBF0CB0F1FE75262CD406D6ACA1FCD682C680A4A343AEAA7A61F\n      044152071CB10A96975AAB2280B1B1795386EF9B28275AFCEAC0124CFF1339CE\n      12265199601B15A13FCCB5A48693A43CCAD99E566B50C7B93DD5F75473309ED5\n      083FE6569648D4A4C4C51C82FCD4D956B49071D427C64D555FB59C6562F74AB9\n      7A2AA83D94CDDAC47FE4715681448D2DE402DAC8F7C42BBFF275F862EC86D519\n      8747653E2BB594B22BBE1506A816F31A84D6F7372A7FEF74EA8EA32191A133FE\n      CD83C3CFEEC2DC99227954B2AD34DF2F75E01666A4DFDCD70EF3E41809CED6BD\n      55802BCA874E0ECF74D77EA05A780C8F5D0D412215A3AB317B4D3AD09B40BC5B\n      8A3D56660608D5AA433410565D0234AB0D80BBE87287959B4225668C8832CC08\n      26054F73599859409631A411A512850E4D8F168E664BBC22A9C59C49F39C451A\n      CAEC05484ACC6962CE65AE8C018FA3E1B2A88C1CE21677E16477D63E5F45CBA5\n      005CF3791D0E2A32699D9448CB052D426C729F809B026429B0257D98D9BDAD6E\n      7767E7D423679C88A68D824A423D475A3A27992AA4629671637FA7858DDFB9D1\n      01096D55D7E4837705F7915EED75038466B40ACB8AFE44A7220DAC844CAC229A\n      BC61952F0D6CDB2934BA9B5D7DCBF806584067599AF3508044E6875578EAA73E\n      253E50136AE067669D68BA46243AFCF63D7175B4560DD2783FE5A4B1B8914F7B\n      229DF28585E8E34FAA768333CD8DF4EAF401F0997E528E8D0F7B87BFFB5F7BD7\n      DE8E8B14F6BCE3E9EADB65F9BFEF5DF9F67EEC0AF0E852F5536DEB83CB4B5F3C\n      18FDF2AD9D2927C798D8C3CA1C4F19209C6767E37E096AC8518233045A0BDEC5\n      ACF8E1FADAC98AD7D538084DAB6CE0B80793A3C593CD33AD70619685C0BFCAE8\n      DF7BF1F295B5D5CF2E3B8F63D0E4E50842EE7881E997C2534F274EEEF15C4A27\n      B5AA47BD71773A9BE46C166B4A4093420EB148A0A005AF23BB8FC5359203373C\n      C9837B797E4D18ABB9965DF789FE29E512EB7DAC46DF530F2BC6BED5D64F3051\n      1924CC330D519625CC709ADB4ADDD4DADBB2DBA4D880A97794DCCABC5FDC3DF8\n      76CDFEB97A7D695C9CAF7AA72A7693F104B9FF66F3DEE78E86CBC78E1D6EEF0D\n      802C7D57E76DC7D4BE95546ABE15CE407ED1867FFFE4CAC3C8B9A7E0B3D7AE3D\n      DA5E3BBEB2FCFCC18DC66AEBC5A3C126530B0AFC48FDE46ACEFB76B713CEACB0\n      FAA99FF8E9133FF931E631CD250D45BA8F84FF7F209CCF38FDDE4921F81E102A\n      6341A4CC1032FDF51498B1BDBE824536BDEC8BDDE2FA20D1F0B25C9F7EF35AED\n      545B9D0913206D58B79CD63C9FE6662481E5030DE9A5E9BEE090F1410FF22120\n      DCDEE4DDFF7A75E1D2AAF8606B70E3A8F2A6C21558BE3792271E0E4A3329CADC\n      CEDE2EDCDFCC592EA0E30A9DC0065AF7E14EF3E00FEEB123FD1A3F4E4A88B963\n      534FEB2E8D7CD6BDFAD39EFFF871C5ACDD1B7B90B1DA33EF0D1E3A97D05C803C\n      2408943ABCF4B598E209E4594C4BCCD2182483E7AEBCFDCEB7564FB7C2C4B47E\n      4E2CA746C2FDD7DF71DEBBE17EF4BC1BC3F2D9CDCD3FBCBC7A69CD6AE95555D2\n      6469EBA5435EA0B8101908EE65F93BC9A057DAB970B855264EA6554065222C9D\n      A07CFCBED5C60316C98F26A1DFD440583BC5ECB6623355F4A11F34766F762723\n      BC0BACCB5932165A0E141796165C9F98374FFD0917D77B875389CF3496C264BC\n      EAAA9000CF23B5366E2CD9E604579484E8BF94332AAD18A9201E0333E52E36D5\n      0E76CDADAC55CB20CFD1446B759ABBFBB7062B07ED3210A3DA64E9E956E927FA\n      8EF2444B0C8F6906E894D83213F87049588E90C781CD4112EE3D1F176F4830B6\n      26D4D9257073D423361C17D9BEE6DD02054248DB2A957ECBCC53A84EED1AB122\n      0BBB44F904F8FA3D1154AD82F631FB60071719B3CB91A323ED78B4F83F9C4E16\n      46A6C3AAD45028E6D6A7982188E302D3795CEEF2F8C5E4A8BBF0335FBA0CBFF6\n      F86960AC2F858E476C990E479D044B2EEE8F1546A6A5C4941726666B540B45E3\n      90A9BFAC332D987B88C0B95F8499D66BAA5B65C50B5A48D44D2B0F2EA2EA50A3\n      382BE3987752D5E1C9481A839F090C33052B36C6D37885E0135ED8C06EA4AF0B\n      4B378A4F9C877630D5ABC3428DD22E5180C797A359BC77FC23CE74D942171E74\n      376ABC380850A8053160C1E6675EDDFADD6B21A9E7C03E1259CAB9CB88E75B5E\n      052CE6A82DE8E49162F95F3E5CD659B42F470BB8F64275E757DF48873AACD57E\n      9A1D7078379F253ADE4CB3B8861C2D9F674BD83B5F0B4E53B7AE578F5374C2B7\n      CEFED8026C5964E4DA990334ADD8E4C9B75294C1C4B277843240C835008B559B\n      AE7834B2A1D4FC3180FE92AF9F7D7EC718A7204A74D69FE4F36E0B9DC769C04B\n      33F8D18C6BD67065139FCC7CA2A9ED52A2C5623BAF9D2A4150143A6C84266950\n      427D4F520028620EA5D6ACDE115338F94EB1BE7E1A5D4886602B2A6B165C2E1A\n      3CAE8F1C86FD817E944C20338E54CA099D97CA30D6B0E5DA7873DCBF717B7D63\n      D95D77A51CB24695014123E9B83A0545207559364EF1D442156BE21DBCBDA589\n      68BB72423DB6CB72DB721BA411999E6984401E17E358AF108E329B6AE6559B5C\n      8DF26FECFBAE6B7C453507CA188325AC0505E09142156497AA3C685BEB7FED27\n      26A753287A51CA4D2BB3ABD939BEFE85B7A243B052F566FD4DAE93EBE2463A38\n      54F1C87BE461F47D97128AEDD226B4A264A889A0C49411E01C8CF63EF3DBBBD7\n      AEF835EFF881334A9ABFBB3FFD0FFDBDDDB2FC54BDFDF3ABF5A7689CA1E21BD0\n      FB67AFDDBB16E773F3F83237932BC8FDF65E9D4D2DA96110716429AC961C7CDE\n      A5EF3EBFF1D15E72A08A6B6C2C1B41AD50ABFBC933EBEBC42F45A4350CDEEDCB\n      5FB972EDC5D5D66F34C08315EC4A962BCD7A2A4EC13C2E3985D3B0281CCD433D\n      5CF8145B8764D840AED52DB5003CE2695FB1CD64766B304D852BEC4AA7CCECD0\n      5E96EACD2CBE55E4A79D3AD65ADEC60DCA1F28463F797EBD11C20462223D4FE0\n      18CC32AD3A800B710E92912DADA9AC5D4D9C1D1DBBC5E0619A9E71ACADDCFD83\n      99FFD95B774E7AF9838BEDC562FC24814F84915D5BF81A21BF7CE59DD7A72930\n      7BF28470E82967E82748E804AB395965D9AFFFEC7AF567BD1C4CFBAF541B9FB9\n      7A57279C8F9F3F4B5D7167B023FCD5573B1355888FC0DA93252EC2C15665C05C\n      EFECD3EFF9D8BFFCDBA915DBA506670F188C338509DF2B1CBD6FAA767F77745E\n      5C67469A2243EE34993276A4C09AFB30270A08C16DCD4893C9E540ECF45FDAAA\n      6C1C9FA0347B6D6FEDA133BC2D520A295D2620A2A67A5DCB25AC68685CBB5809\n      505102568CBA048C759A976FCD7A5FB9B5F2DE0DF68437B8D56FED540A3E824F\n      FAE0817779E9FC9D78080CF6C0EE9D42E728E8BA8C97AC875D1B77177A9F3F98\n      DC19607F29CB74166204435BFABE9464A5EF7E22002BDEDE3B1334A42BCF7C00\n      5CAA2B8259100A94037EA0AF5CB155286A8C0C73BB631197A661A993CB7F79D6\n      29FB7683A41470665564BDF7CE41B1EAAFFED4C5C24F9DFDE0D6AFBDBC3AF1D0\n      0332C107B5706970131EBC9259B9D387C93BD9682CDC2CF78608777426D6784C\n      18B7E089313D5EA97B303D23E28B96951418D4961CA7682FCFBC8532CDD06C80\n      EDA87E74ED7034B5AE49FC1D9E1DE653321E3D76EA24CEE3A03BDDF09AD3BAF7\n      B6C3AEDE18AE60FF4284CF545003E076BD819C61A5ADB58F19332960A1B00B41\n      8B98075474BB075A6534A2F5620836EF6D554F57162E566272A460E9233F1997\n      FEF36E6AF3713BAE5CF2FC25FD8C19551E42410A4AEEA59ABE591263E664C091\n      4E821D86FAE1E61706C55B1AF32A07025DE56C371F7B0E98A57947AF49CE5BB6\n      5D09AA8899F13D01B11C63B60634AF732858F29D633A25491DCAB3D693EDFE3D\n      DAEF745D35B31857C72AAB9FBE90B4479A139302315442E34D86724C695E200B\n      6A7DE90E6CF92ADCBBEDFFF817BE0DBFF2E486C909D0589A3226EE371402335E\n      984C6709C69A0BB9854EC8C2D4940A0D86829BD341329FD84BA8A66205D7516D\n      6636E9E4B80061C3D5040A7B5AB9601D9B3C133045742F4D8FD27CA464A27426\n      E266230EA182E75889253F386E87ABC4AE6BB1A992A51361B4A425730CAC4C03\n      05F1828C93AB97772E9D7BC05B67E05C8E1F39A9FC5566663DCC1CE214AFB22F\n      FCEA574FBF63A96AD4817C8AD1745284542C38628D853E0B930DBEFE8F4EC34B\n      8A173AE588FA4E63F3DFBCC0DE9EE5AC9690DA68363E8887DBCA9A98F2FE990E\n      F901464BA5B8E82E6C84AA6EE7F5A28189AAFD39965DEAD9690D8F2B31EA8009\n      8B9FD54F5B70E0C5D21942D1E753BDBC35255BF79C8A0F329C810AA92EB9B617\n      8B3B6236829AC19B994F5996EB38F0EB851044305B533900B234AD605E770982\n      6637666CCF820B2EAE4B9D128C8701D5C1207DE9E9C4515863A6659470C3596B\n      70655C0B42E74137767784AD9F6ED5C33E088B0C0E78065C9DB3B572D72AAF1C\n      035C80D033732D844CAF89A3CB45B8E82E7DD849D10C95EDC2D9A78EED855189\n      284444966531EEBB12614DBF58B87F7D9FCF92955A153DACA30BE27A0D3722CD\n      6E1C6A954529E31C0EFA7A75733324BE91DE988CBFD06F064D427102CBA9647A\n      1979C0ECAF983632227A6A643F737AF92F7C98FB63128F9165E7BC24D8A67BD3\n      DDE7BFEB688DEF86D9D148F3047779B9ECF4FA50F89F7AAF776CADE08E0F1B66\n      034FE755E24CA9431171B7B6F63EF33BD3AD816B5716FBC58BBCF66FAEDDBEDC\n      DDFB50C3FAEBCBAB0F02AB4A6881C5ED40FDF3D7EF7DBE9715B45D2F3BD93C37\n      0BA073B141436C2CCA80E979526E50AA0FB4A28B0D782A5A6B6DDFA8BA953717\n      4E7D79EFEE59D8F9F489F692E5FAB603927CB3CBFEEDBDDE171A2BBFD34ACE37\n      ABAE0E456C8DB1CD5CE3C603F9D836F3166C21A9BE688C6538D1628B952453A6\n      EB0F49850F86C32BDBDDBDCC1EB9D15E3A2D2D5A0B176FE5F88DA3BD95D0AA62\n      792288BC243EEECB8F3E7E72C9D7CBA2D0241A016A0CE72C63B1C834F84A93D0\n      7D6499A610095F93F1CB59DFB6BD53B5E5BBBDC3DF7A75FBB26BBFAFB6FA140D\n      572DE189C107EAC186E5FF6167F05777777B91A146D554326974B180616E956D\n      95FD62DBF94BD573969657E9A804EEFF2DAD5F3EBCFB031B6BBF2AED3DD4D9E5\n      F5E7F3E23BF9CE31DF7B1255576AF6B81C9A1EA7773FFEB17FFDB78C4D4BE93B\n      DF3394B93FEB5BC2FBB3DDFEDF6299EF7550E82F6B38728429141B9BAA031019\n      E094130E2D7D5916BB51DC7A6E6F343B7EE1E9EE1B6FFB328DDEF548AC03AAB6\n      E0A12AD64FCE8C8198575CEB5B2B68091427B19B166074245186F5E3B8BAD77D\n      F9D699A71EE575BBBF79B75E698D6FEDB64E1E4F7EE049AD8A4ACB2E74669B76\n      C9AD376192E4B806B1479303243390575FFA93ED632F850EB2B966A15EE6A382\n      48D18940F4FE13CDB34BC3CB6F0D4BB1F6A3DF3739E387C21C4E22E940A0F9B1\n      0D106114649A9E9BE45BEA370785EA7DF75AFFC567CF9D3D5F26B3A96343153A\n      FB7CD8D95FFBABCFC4C7889BB566FFFA05B0B5479FA2CCD2D1AA717D6170653A\n      B83A82B431D6CA7612EFAA6C48B2324F90FED128C82C8C8BF152CA97A3BAA044\n      2FC6AAEF2C116F1D58C7AB283C21E5A29A256CBA3B5CF7EB57EEC038F7FA69EF\n      168BAF15CEE11445B6F2227654A418378FFBD545046F4DEE52269F39B971C985\n      617CB8D2F412AD171716802BA764842A5AE3140E74082F01690E3A5AFDC60B2B\n      0C2FE15E1CECDD488ED5FDE689888314688146878397053A700871E3E393D6D3\n      559DBC5CE22AAB507206039FE32C0639844E089A88C49C33D059DEFB5ACAEEA5\n      42A2ED5C5C9D4E76D884595E093DAE535E365D72DD453BF434F945F391791A77\n      8CDBB566EF452BF2D642BFA6BF68C7957735E9C4DA7DFBB65B7A66E250931CFB\n      F32DF440C2658E4B8AB416941A0C6D475373D300AF34E7A2000E3AF15BBBE067\n      FFC51DF8E5274E6978BB0F847C3E465527506E0EB38919D336FF98BFC034BC19\n      F735309FA16BC643993A530D8AA569B7980F5E84B82A79C5A29E853C235E0017\n      52A359819D6EC1BA39D3DA7C26586106586085B5022B81E4756CAD5177D5F296\n      5D87C82CA8AAE631CFAD498E6282B13085DC60D271BA7767973EB0305BDCB22F\n      6CD0950799A39164EAA8100D9ADFFD3F9E0DBF9816BED3557C2C15334392D3A6\n      A38EC37A450493A578F517CED98F514EF4DB115E5C3BF88F6FF43FBFE588E531\n      F6FB79DC998EF71518012A4AADDCC1049741513E6035CF44B06EB326AF13C8C3\n      8F17F0E918A4A1358D12D4C109C8FFC4611D21809F94D610F26E392B4B1670B4\n      EEBB351F2A57C02AAD2D6B1418A94D994CB42427A6CF841585C4306C24498685\n      5658FA022D2DC1235038481903224DD5178177CA020E4766134FE6A4648ABBD0\n      7791C34152A242AB85831B1D55C0F50B6BCA8E4B9CE51890D0D70B0465DC5400\n      13AD4B8493626039D04D018E31D7EAB9D9DFEEF46F76AA601947A4F9B4272B66\n      747311CC6CD7B583809B4D6E33BD251B0D3C0989AAC809E9DE1B68B253AB84EC\n      8C693CB61A2D5575750C502D51F417D242763B9666E21051554BAF8FA75F1C84\n      6E156228259FCD1BA97C64D790D688728AB281939DFBCB9FCC9F5E13EAD01539\n      30D39A84051D70637FF7C52BCBB596C5D1E4B0E7552BB8593DB8BB553D7FCAFD\n      C8D3929A998C36AEABF9D91E444E8C2C4CA07BEBD6ADCFFC8ED84BAAFA6DED25\n      DF9CC15FDEBBFB969C7DBABAF0F35EB301186C78302B81E7FCF6E0E057AE760E\n      5050D2194C283513994509CA79D002640173A70BB4E2541E89E89233FB07E07C\n      86277B54FDF1C13096F047CFADBDC73127BC231B4E0F475656F92F9DC1EF5583\n      FF78CE3F85AD0AD3E1EC949ADF284D0F19D0E282F059C143A7CAB97EC63ACC8D\n      CF6201F583810C60B40000FFFF49444154204059A67A17E36B3BFD37F7A61327\n      1821392E7229ED7B0ADE1D7596283841F1BAB44E22F2D84AF5D1F52ACE872E75\n      40A9C19403930318A2B6E63499E4CA774A53F3E8645C596ED499A437462351A9\n      6A0A7CF5DA9D7F0A8B63D27DA2D9BEE0DBFEF0E0C3CDE8012F7807D8FFE8E6EE\n      73D3A16D4BBB504A9A596F6363A559FEF92AF9A7C7CF2C4F4B402D2B4D5089FF\n      24A8FD8BCEF61296BF50699C71271DB2F81FFAC33F169D3341F4DEBE7C6C6D65\n      BB1CA64A5C7CCFA31FFCB59FCF3CA51871E7DBCEEA7BF3E7E4FD8D50F8DF558D\n      DEDF2BCD94E60AC8C6706C68898CE6D3EDE3DC5495635ADC1A7CEB3FCB46A3B5\n      7CE1E0F26BADB64F365698CE397ED3211130E96A7EE0033477A450AF2A20182D\n      82C94C658304A45EC2BB2FDF9CF62667DEF32413A27BE7DAE2D9B37BAF5D3BDE\n      5A8F7FE4DD6EC124B14B00ED594F6EBD49727D23AB183AB2EC0092A169E3ED2F\n      6E59B7A3A68E89922B8F52900A35B01F6EFA1F7864FBFAAD4EB7F3E88F7F429E\n      A91BF35ECCE7A5563A719984A7993C337205EAB43865A9A39764C2777FFB59AB\n      7FB775BC996133C98D8E83CDEBF7363EF1A0FDD1752D24F84BD3D77EFD4B174E\n      B4F12A93320120446A61F8C6747473CA50E588930E0737927E0FC6C60043D909\n      740B026B65BE90F14654D1709EA5B315D76942D250A05D576B0F06AA26B3299F\n      EE8C8F2D2C5CB9C3C6533229926D51BC99838379073241592ACB946B8C7356BD\n      90F32E2DD1C546EBD18AE7C79D56D5D2FCA552AF3B552B45036665C6FC51A386\n      61717E3AA6B3FE64EDB4A5161877A37CA02F6EDFB6D0F2D97541324C072469EF\n      7CF7D0CABCDCCFDA4F35508B0154124D5700A381C5A12C91A4668890CDC1D4B4\n      A86FD5779E8BCB1E2F10DACDC5ADD1A4C7D39C380CBBC2462A9D2ED8CEA21785\n      1A4F308CD384152C742C5472DF2135CF5AA0B84D087672EF218F14D69D376E34\n      400BF16A978C1EF8F115FA882C41AE732114C86C89414A7886CC005A33905D83\n      5D3C2C6E75E88FFC83D7E1D7DE75768E6273BB07733EA8D14D2B39FD61B64031\n      21F7FB098DCB9A3440A8691846A49452AB3D392FBCD3FFB9E4A5D19100855005\n      84543D33C2124A338D2C2DC598C951C987AC9C089DFC34F0239D020BB33E2482\n      D2536091B8A7FCA88549609ABC92F69A5B5F714B922064294BABA18E47CFBDF6\n      FCC1C9079DF0C24CACAF901317654D68F964B11A94EDDBBFFDD5FCDF1F94AE97\n      40DC4DD2D26857DEF4E8A2F22B9C8EFDFED2FF78AAFEC985A99F59C67A15A1D7\n      D39BFFEA35AF1B8EA13580B09BC4FD32EF4B95321B1250E29156321768FD4C44\n      1A8E68AA484B39FBE93878068A12E3C42FC0580B0DF9863BBC36433288993501\n      7204D2A4C87D45DA94D45C69050454507D252871176CA37C4ACDF99ED2F02452\n      0D776E3D2F392C530215B45C7D27ACF9E150699CF78A7023B017F4ED94C69716\n      81319F480F11ADB153EC20473388D1BE5EE3A395730BB42194CCB4D8849E93F9\n      A554851D6BB4F4251139CD5D4DA73C7B4A8766A2E1E4587A058E3A3DBF158556\n      D465D3FA258F56733E2BD36A190401715D667C8B1CCEB2746814A1052A620087\n      07539F52CFB5E2533ACA3DAFA51524C636C2A6361EC938E347870EE60584E4FF\n      21EC3DC324CDAE32C16B3F1F3ED2DBF2D5E5BBABBD915A6A879118248411CCC0\n      620666805DCCC0206606333CB0C3B3CB32830637A2F148C208249090412DD34E\n      5DEDBB4C97AFCAACF491193E3E7BEDDE9BDDDA65777F6C3DF95465656644647C\n      DFB9E77DDF7BCF39AFACA497FBF15349404B06F2A95243590C08F088213A6551\n      E45B241507CA8B3FFEBEBC26B96CF9501A8D6E42CCD174F0D2A5E2EAC6786D4C\n      A445DA1D46539389CC5BC970FF230F81837345A628AE435A378083ECF9A4CB8C\n      7C3777F2CAC54BBFFF517F2D6FE266695DFC2D1BFCF2F2B50E751F61CE4FCC2C\n      EC8F4C7E2C4242CD025A0BFC8FB7B6FFE8D56B2B0EC5DC037628BEC973E67698\n      F56DB7F3B86B4099841CEF51C5379D9CFD2F6BE5D723F965925D8B478751F93D\n      F5C96994FA557C636B27C361CF093E73F172B06FDF8F4F953CCD659E488180F2\n      1CA3E04522694E4A768FD0B58364B4B910B166B6A4C3F030265D1CD8C18981DF\n      C9D4C58DE1B5CE70472685E5F5E8A6622D964C027CEF64ED6469FA605819A7C2\n      77336812B17966694FF1AC85B6B65522C49051EB5FC21C627532E3856F141C8A\n      DAC4DD56A85484A356FC13F1D276C107597EFF4CF3705C3C562D9F28BBB153FE\n      F3B5E4FFB876A96B10470A1F580BE99EC38F45DE7F99DBFF2887439165148E25\n      392DD0B96AF3CFD3E4D59B973F70E7A91F1A2E9FF76A7F5AA8CB0E3D302AEEEB\n      1787F6CF9F1D6C335D1CBFFFE8BB3FFC73BCAC01DBF526076F8D5803E0FF0B84\n      6F99305920CCB57624A41A8F0C5E621EDAB23E34CA7C134DCAB9F562E7EC3F34\n      4E9F4C466474FDE6E489191D218D424DC73409EC4EB679881584AE9D34054C56\n      6102B168A7CD7152383ADAC8573EFFAC1EAB2C3C701F5BDFE92C5D99BCFFD4D5\n      AFBC72A8B4987DFBFD365AB10319C0693B5D3F4F59E6E49149F585DEE49E2AB5\n      1A373F7673D4F5A61CD737812730737338CF4BF7CE0C936CAD934C7FC383E57B\n      E64DB6205D938C0B681B922200FDDD893C12698921E1128AC068442ECF5E4B3E\n      F3CCF824CECB45ECA8C6A8397A35EE57C0C2CFDD3708FB955B959BBF7DA6B3B9\n      72FCD1C3204B9148CD12447973FBE56E728B27305CE56807E2AB2323C386D69E\n      47931DEBE6800E5077D6F18CA2482972393BEC7863401BC916D5D9813BC694C9\n      AF43A77BB35F9D2EDF584D773A5068770BEA17E3E155C1433722C3A1E13D3981\n      90539AC3DB6BC4A7514DE123E5B026860E615EE8964A416522046E365403073B\n      0E37CB34E6D654DBDF58EA4D2FD6D174061ADC4355DD0B6E5DD9C8155BDC5F0F\n      9C4485D57825E99E1D365403CF2AFF5E985546D4245643003D3B8A1618600908\n      CB75A1E300F9EC82B7F2C511E0619FA24B3BBD41CA95837B5AF734B2623B8D9B\n      D4AD50175B3B2499096EC8A6239567847325AAB8A80AE4B4E3639AD1E3746C6E\n      F6CA7367E976E4F05ACB691FF8AEA9F23D8ED0467278D03C9B79CFE6C61B5167\n      F7D9CC6234D91CE7A96EA58D77FFC053F0CBF71FB6F3BDAC8D30DDF55D32B16B\n      955CCED8DB5346EDE851BE3B70065BCB012B040D9A10697B06B4F5D503766E33\n      A6C4B61E6AE561548D420F1BF26ACDDB522E52A1BB39331FB194852DF744B99D\n      B820AD4935348B5BD530DD13D54CF26F1223AF595856F579DFAD62231891A1DA\n      C156142EF6D7C2CDB5CB07EE6D889950EE9FF3F7D634D194855079A373CB9BBF\n      70B15F18DC8872097BF990435EF1C2867226284D540B9FA67B7EE29EC15CEAE7\n      3E77D2D2B0BCF9E1CBF95707427AEB1076B518E4C34E6EA03A308405A3CE0838\n      8749ED50E4D57CD9007E48343A34A83F1A28476B13AE32C30546CB7EE7D521CA\n      43C6DCBE1003C4FA3CF3913B4670855AA720EDEBDA42897B5D7D0B653DCC6CDB\n      B032F96C989B3B10D8F63A9113DBAFE2134C1C95508832AA5925AB1FA86A8F9B\n      2C45F1EEB9AC63EB51B804818C9CCC4BDBD970D02FCD56834913C3038073C356\n      1CAF22B42A6026606AF47F5894112817D58D5809AFEAD30E66AF90E44AAAA274\n      FADD77F1D5C1ADF6DADC3D656A60BA887A957EA952218E1D138B1015795E0C7B\n      86AB5311E911EDAD0F4C82F75DD43F24C252D51D1BE726963D07DA99A5800F62\n      BEB5E162216CF55625BB3C183CC32A3A20B60ED100211B61458953D1C487E0BA\n      684F7DE0EEEAB73F28D440E981411F43AC30C03A669DAF9DAB8E00A1C1B0D7D5\n      5257A7E7765AEBF0E04CF3DEDB4118086610BAA9B16D6EB46CCB2A091F985FE1\n      EA9BE7FFFB1F55D7F884AC82BE7AD21FFDE66BD7247783983FBA30F93DD31327\n      4CE8523EF048DFE04CA5FEC2F59B5F5A4FAE0CE337B500818976C7CB80AF7317\n      A802EB217524E7A780FAE97B8FBF677370B6DAF89B6CBB57F4EFEAAAF7D4F6EC\n      9DABE58336EAE38BAEF31BDD8B530DEFA7FC6393025DD5BDAB74D4CAB224E619\n      86CC13250AF63AD5C8809DB9F4D0A96A24790F81A4E413C294ED0295B69351D3\n      A09BA2F561BC1AB7DB3CCD35E9459E88F0A1A9C9FDCDA92A0E0C30F4D3CE088E\n      7A3A6925452AEC906D614B9020E3C3B05ADE1B36A613B1E83B914AA918112369\n      7C64E82B4E0C4D287562F67C5BFD61EBC62B209DAB04EF2A8DDFC9D8BB67CA50\n      A81759E9432F5F7CD31EB3E1AA36D42E1FD3EC270E1FFC3EAFDC18C63D69B706\n      A23C338967CD299F61F8634B57FD3B0E3E99F49FF6F1DF18DE276B77F7B2DB3D\n      06662B3738E37972E0C1C30FFDD62F32D77132A8710E1078BB2EE66D1BDE7FAE\n      08DFFE06D4B99D050229A7B658D4297C60128A6BD000054C76CF7CB20256F0D1\n      C35B17367CA8AAC7C7725038B08EC924773C8E33471BD54DADBF9D415E8B82B6\n      6783F64DC00F2020FE8D7EEBB933E1A97DE5A347D337AE66ACD7B8F3E0952FBF\n      7E88EE111FB8CFDA3C61820A0D926EB179D1C00F295C04490CDA8652464BD5D5\n      8FAF88A1F65C3F626611B36185D51E3912C3516B6D65EFFB9EA0C7E6131FE151\n      EA492CDD0459F79D9282AE75585466451B9E4B32E819400C0B7DE5C93F1AE3B2\n      310B329A65DAF5969DE26652FDFEFBE307652A8BF12FC0E58F3C3F7E778DEF01\n      A4E51801221CAD5A41EB6B6DDDA6231C6C48B29EF3F522EDC90422936CE1B682\n      1CE06341753AF42EB7D7FB2E1CC7EE9DD8DFE36227E4A0323A7CAA69674C27A5\n      F5AB9DEA94D7E9C8B5F514EAF2B6045F8BDB1740E1BB95BD380AB0BC39DC3241\n      88523CC5772AA5F12A70F6FA41030BAD63BF441C2C9A0DBF3E17A63035CAC2B5\n      DD0F4219328EE9CE2A836ED83846D558C7B6DBB0591D7BCB37AE1459F7D0C23E\n      3586B2385137347B436A2A4B8F60F70E6C3D0604064805D847867852260D0F11\n      698954872FAACDAF260A96D790D84CAD251BF59D9578B49E668EEF9A172D13CF\n      B06A61024DF3420BCF750DCD2C433C598D4C9A6B2060923C17437A0CCF3D7878\n      E5CC65768194D8F84EB833F3BE46ED1D752D8686376A232B1032398B0ABB9D00\n      859005335120B993C0F93BDEFF09F8C5BB0F14057F0BF3F4EE9E06DC55824612\n      0ABBC56FE1D344BB59349EE7218C99E076BA0C441611212A6C95CDEEF1A07DB8\n      6D2A34E1E93AF69CD5EE5E58135A382A4462D043D93ADCC21A1C821150B1E2D2\n      E02B5404985042D35EB8E047E3108EBB864E0ECB934E63B10E032E704202C321\n      8483AA975E5EAD37AA5377D7E2BDC0BF6D2F3044C1A8AC3CC529DDF8D0B9D59B\n      3B1EAF62EA1A0E3402A2EC54222E6702E4A22CADE78BFFE91DC3A389ED6D8459\n      E48CE9AFC4AFFCCA9766C54C9BD24D472469DAEBB32D4E63205C351A84DE1E10\n      1DF0828A272B00D629069383E623653265429D71C670EE989CD8FF5A260684AA\n      72CC640FE43B2C23C869FA4E0D09DFDC3A5755E623D428D41A1E6D1B7E61AE89\n      4450C6391F1A4A4A0C7160B6C80C0776EC25327A8EE59E74E69CEA62856973B5\n      72DB316167161BFE41CC1DA18AA62BC9A035681C180B9A6152F43DDF64834C79\n      E6E204469B0A9076E906C0AA3E9AC0C36A67FA668D8CE1846EBDD6934BB4562E\n      C5D5ADB1538793A56CA3BDBAF7C13231973A698EC6BB61B9647BDDED86356569\n      2292C49310B300F4D1A0156B2C82100F4ED2667D02D51B962B3846721B7E06C5\n      30E69BEB0EE41C43AA2AC9C57EE71936C6029CE4069013A3AE0D7D3392D78E4D\n      D08350CCFCF4B7F023659D9BE74F95016E64A043F46F6E8C2E2CCD908A21459D\n      611FFB7E0D87ADCECED8BF78402D4E22EB61E6225DD33A02881AB16FFECB908F\n      319057CE9FFDF01F8E6D8AAA2A33963FCBC16FBD76E995A1917751251DFDE8A1\n      C51F986B9655B644E1AB6B1BF7D5A70E03E732149700FE6A7F78E6E6EA4ACC0D\n      C2723B6B1D0061960BC650BF3FF27F6A7A6E7FBCF35771F6142E9A55F721451F\n      ADCC4D856EA73718C2EA5F6F2D5FAEF6BEEBB6DB1E39CFDF2063FFD4BDFA026A\n      F3B13272FC5BDB5BBD941F9C8E1654C0D686018E2413A1D0B5B21107A3D95A79\n      32AA7B46CBD969D485E7970AEE3044062AD96623E54509D06B9B6B7877B48221\n      757D5E249A0D80E8497B9E9649103A55CF09F3B843609E43507783398D8FF8CE\n      C37B674E2FD63D140339A8F9548F32C625754B830BF423FDCD67AA703D1D9CA8\n      4EDCA5D4B74EFB93BAB8044AFFE1DCEA97FA0970A26AC66337FE815AED6716F7\n      348BA1D1C5864839B65138B6076FA8749D797F97C79F92F147034FCC4EFEF6B9\n      CB3BD4FDE0DCFC8359CC893A07781F8CEEFE17EFBCFB3FFFAC49DCE148401AEF\n      DAF0BE057B6F374B582084FFBC7DC2C44E615DCB8CB873338E9557784849E116\n      D6E566756BF98D4F1D3ADD641AB55F5D193B30ABA6A1D159AEAC623426EDF15E\n      4AB561380E5021B02E3BB921DD46AAC864A50079C03DF6CA72FFD2B9E637DF87\n      9D60E7F5EBB5C52AD95B5DFDD2F979BE203F700F56B93279C368F6614F6F5C96\n      22B65DDEC408D111052EBEE0AFFE43CB4D44B930E098B7C79299771E5795C69B\n      57AEED79E2F6CAD18AB2068A56021244B48CCD859630346B73777A78818D3020\n      C4B09212C3C9DF3F1BBFF8C2D8F149E1AC6219C0747CEDF5F5FAA9BDE5EFDCD7\n      2A6F54E3B1D11FAEF8B7FAE131B543DAA56C9123AB4093EBC000A1934631F437\n      355949F22ECBBBD990B80412AF0D60CAD48CC21381B394767B26CD717082E363\n      D5C80D990CDBC76F9F28F99E48CA372EB5A6A67D9EB8D7AEB6808C061CBCC1D2\n      E78ABEE4E08EA05906E046DAF3C79B28D119ED436EA495378BDC06E4B588443E\n      80F9A05E028B87274009669C11830FCC454E62D2503A70B6BB6AEECE0938B505\n      5C81D29AABCB9C0DB7AEDE4A37E8DCF1716FCCD3033578AEC3B798DAC3C71F6B\n      8CC2D8901F87938038D68A592790B88912BEAEAF7DA9DB7FD5607CB8AAF936E7\n      143A8EE7DE1A0D3646834A601DEE90C69215B6DACA271CEAC0C853C6EB008D45\n      7E85803A81E673CEE2F09433F1C4E2F61BB77A5F52D1A8BEE16F4C7D607CF6F1\n      39C07B401AD9662839B4455A8CD881A3D6ED9E13CBD03C191C3AF4D89F5A2094\n      72D77AC27ECFC09AB98F943AAEC9F7B6C86EB7D17EB7D35E1B243618C9779D7B\n      A5B54CB0C5E2B62347DBE995767FD5646D65EBA2774DC96C19B57D3E6422CC24\n      75909BC52C646A50D74A2AC40C26286667D2236D50B38E9D45BF3C6B70DE810E\n      4A9D8A6CCED78369C8E800AB0A77B6912746EBD5F6123FF2AEF16C4F571DDCE3\n      8EED715C55F09ECBFDED0FB7D69EBD5A1E94A526EBB8D796BC84EA91924D27AD\n      1BE91180A91F3D913C6284802A3140DD10F6FD73BFF26CE525ADBD683960A34C\n      A56DBE218A0E1444A251098DE5649F17353C58827CCC77A4D79B78A81A1DA34C\n      272AD3A4301A4DA45F93835516E906E76080C40ECF0B8D2A2E19778067AE38D6\n      DE8CEBCD41B0E3F6D6ADD73541CA4E7507A41B4B9B274462208E6A9752838A46\n      5465CA64F4FD755A730DC8E428C9C9C8300A30A081AA988BD2ED6C8B5E1605A5\n      60C1609ED16FD2B62859AB3423C71C935C382C382A8C3E479C2A0E6580CAE954\n      F7FC7A7FB33B3F7B5856BDB6B83A796031B934C8F9A87E870FA822836AB620BC\n      C0B353B014021217A3581599AF281651B26CEB5DAC6CAC7ADD13646272161AB5\n      4E909D16270D782895646C731D9B30C6D0D1D5D185CEF01939254B282B868417\n      5096B58DA6D401239E8CBFE336E77B1F346B3EE2DC37FC98AA1C6B67C8B65E7A\n      93F6F3B1A0AA33DE19C54158E2C3DC9B1A73BEE16E163AB820CA0911A8505DB1\n      DDEFF6D8DB61D8B3759F572EBEF1DB7FD0DC017E4141DC8583DA9FADB57F6D6B\n      6D442AF3A874D724F88EBDEE43AE7769277E55168F8C354FAE6F7767714EEB49\n      11747AE295F6E02F77365EC286F119A245150A7C96FE586DEC27AB635E31FC54\n      A0CFBAA836189D76C95DE36313885E63F0CF069D0B5BCBBFFAF083139BFD4B3B\n      C96FC6E06C7B39F15065763C8B33430B0ECDCD4D4F4CB4B7B76FDD58352B0842\n      3707AA0BB8A11C650C2AC8A5929A18B02A9171A87CC3256D9F4A4863131D69A1\n      F25498EBBA2BA842E24F4D4D4C8DD7B41404D25E3BC7D0F7FC30DEDEF65806AB\n      958EABB747FD516BA30EF8F1C9D2779F3EF640E8D3D10EF224355A6BC8C4A0F2\n      EA40FFC5C6EA97D376AD5479A231F68129749CA49DC2FB8D9BC3DF6975047582\n      4C2E46F2370E1D7E97629AA876CCC748498B7404520290C3DC65E27F89BABF7F\n      F5C6CFCC46EF6E2EBED86FFDC2FACD8931F24B53C71B5BF10BAADF9E02DFFBEF\n      7E78F17DDFD4C3A8C438B5677D7AD76EC2F2E5DDC132BB40F8D6A6E8D7B1B0C0\n      CC3177CD04B16F82D600A1F5104C481E4A6FE7C59705BA3E75775D5C5867DB22\n      B87D4FE6E44E58C26619AB92B97EC2243325B03021E0DB1D6760C41D372B26CF\n      975D07397D9A7CF90D297BE5476E6FADEEB0CDC1DC1D0B79896F7CF1D25EBE97\n      7FCFFD54E60A0343F4DDC100AC5F977CC03C2AB01D87E6B348BC04369FEA8582\n      34443E243BF13D6393F79D7CE973CFED7BECE1F0E1831A8F42C68159144153C2\n      C0CD13119098BA01C3B6C8C7AC0B9362113637DEB9B573E377FEECC0447978D8\n      83C56629A96757C1903A63DF7B2499EF79C033E1B5F9D7E726E7CAD05B4F79E1\n      E8590E33930B3A178AAD577A8EA88D34DD90BA8B5057C8ED61C7C0AEE3477DA1\n      87392FE572C6A12DD61F46AE27E061E8ED2D877E5004D1E0E4C94658F6D2245C\n      BED11EAB528FD52F5E5A05DAC919BCCAC10B2CC114DE1136F39DE1B522A98C37\n      232ECE06B94A98F96B0E9009A867AA61C3C735C8CB386F4CFAA5F9C0C8716B50\n      64F72399895E99BB4BABF1E4D189CA612E8311815562F73986BC23AF9E890329\n      E78E4E8080931877CE0C925E4A8FE2CA7DA1F2B45390DD9D7CA6458EECFE8801\n      98E6A54FAF65371CC5A31E064BBD9EF91AF2DC2E4B3B8361CD90E83002C4CD53\n      EB312A1DB33474486859E12621638157A63002B2643BFDB877048EBF777CB83C\n      6CFD1D2B771BDDCA96FF58B0E79B0F003534F024AC6DA409CD1C2AD7502E5B76\n      63849C52DA68F0F2D103EFFA63DB3E616D25881DB997B3C20E3841D62FDE040A\n      C476CF5370AB4B24D41893DD7A19699D380C9F1756199A075ABFA9DD6D52DB56\n      219575D97DBBA1566645612B6B90752C2F144839CF0A237DA0701C85911D6BAA\n      AD070A022082649AF87BA8374D60CDD3D0C9C3093F5AC0BA3440699956535D31\n      776B6CE9C5E1F49CEBDFA1E4F17177E190A666B5F629C6DDBF03B7FEFCF9DA66\n      0900BA1A24B792C46795A9D0A9F9A320CF254013FFD321FFBB1B436754CD4AAC\n      2860A9029E496FFDAF2FA021EA35FC212371A7D816A316D44C94936064F8D882\n      6B283C2D6336E93B0A8C1A7784B5FB43467A3A8584518973F07AB87DA953160D\n      CD2C1B6F29162BE06130E5D3C8F02EA3C59B30DAE7AAA1D7B91943615591592E\n      D0F1FB0608AD8B6062BD17A04BEC046C219D044FA2D262D5A82BEB1B4F928C8C\n      90C0B5621217A524E9B446AB95C86B4C4C315028A3F6CB305131663884154326\n      0A6B2505A908542ED260A0EAB2BC7CDBE88D769CF7CAFB50B83033ECF3D6F6DA\n      DEA347E317AFA112744E38D2957E5A12730E76F0EE2018DB3B9B0F8D2AB65E97\n      4894FA6F6EF86E54D02298F4DBB7B9136333D00B6DA394E470F76458158CADAF\n      21F3922649C3FAE0FC4EFAD9B441AB421910B0AE99BE89778846508C9A64FA83\n      0FE3DB277234748C161CC4B8E42554F9DBE9E8E93702C7279572BEDD8F97771C\n      3F18B864FED187D49E7143A1080CB91368547655151A9D4C00B39AC07381A237\n      6FBCFABB4F86EB2C1C819924CDDB7415943ED98BFF7EBBBB2606A71BF45B66C8\n      43E3E3176F767865ECE4B837136F71437D4114309F90A0E390CF26FD4F6E6D3D\n      BF35687BE60D799511FBD9E9C5EF77FD730DFDD9B8BB9DB0135DF9F878F9E09E\n      6AEAB87FBBD6FBD8B5E51F7EE0C4070772A533FCE5A2FBD19DD440D65CADB6BF\n      3971DBE4CC74581A2F5724326FDBEDF2E2F9B3677BAC600E311F33130D98C522\n      368437A0BE3DBC34B7DC43813D56444506C5D5F52D5FA34373B39572CDF37CAC\n      CDF5043587946C6814E692F7BA8357CE5DD832503E3935E31BC5EE6C4BB90DC0\n      40F0EDD646B7BB5313D907F6CDFFAB2387E74DAA2AFA392E128FA81BCE3F6E6E\n      7F94B5521C9D10F8FB6EABDE4D7B61EEFFC52AFBD0FA7A8B9A8B8B3E343BFE9D\n      7BA726FBADD08BFA035B06C550CA212B09572772D3759F96E0D36B2DDF19FEFC\n      6D7757D2F82FF38D2FC4D951AF7C5255BA4E2C4F4FFCD8AFFF7C657E36E78972\n      95C75DF8F56340FD1612DA39BB5F9F35F3F56219863965D844B170995173AE75\n      D6292495CE56B2F3CA6B8DBBC2CC598BCFDC9818DF030E4E58BBB7524D6807EC\n      CEEC836F0D2755BB9616C8D00A6BE9897196A815238AE4C5C1F20B6F4C9C9A2D\n      ED9FD878ED1A892AF5E3E3520CB6BE7079C13D927CF09EC0242568F31A1E76C1\n      E692E243ED516ED6A78980344CBF92A4CF263E0223B8553DD6F46EDB7F69E946\n      E5C49EE9476ECF026A67FBCA42795820AF90959251EF08A4D4B69445E657C8AD\n      3B8B417AB8D35FF9CBBFAB1683D2B49F4459C023B503975EBB35FBBE77A827CA\n      7DDA9A49E7E38FDE6A9D7D73FA8E9AC9B28E70CC0ACA8B24D2B5D6D964ED6C4C\n      61B5C7D596E4DB66F920B433EA9A9C6D60242F54A650D50B4F8ED50A96F6A52A\n      D2C2CFE544A55437F4BD1C1FBB2D74229DE7DEE6FA889A678193972EAF700558\n      0C9672F286624C67079C92D6CE92B57D57331A7C89A7254A0C22EEF5C2852034\n      B01601B510FA1E1B62376F1EAC69F33DEBE063F80636A259147875AD174E95E6\n      4E07BC3C508E6FEE308519117EBCEE775FD848747FE18119BFE2C7AFE4C9EB22\n      754663DF58259376841426E62A3362CBA824346A2C1E7FED53D7F30D17C8728E\n      494FB19D2C1E6A21A464A361D9D07C3FE484DA9D4C25336DAB452BD4A921A741\n      683370230F539E854A441EF58F80DA136EDA531B1F679556AD1DB5DC87FD7DDF\n      7A14C081AD19B1A6704008BB958D8C20B26588BB736EA5A74BB7ED7BC72E10DA\n      78056F0DE5B7640DEEBA2F199A0CADB704328868D113690390BB8788B61605EE\n      FE70CE4CA6B25F114A825D04A5C03656D8FD156B37BBDB25B7CBD69852B99499\n      3029D3022624CEEEDC63F3308BCBE6A18E5063D8DBE304D3044F44C4C4140961\n      79AFE34C676E8681AF79D5FC98CB56F1AD376F1D7E620FBAC3C387F7328306D8\n      DCEF347DB1FAE67F7D6A6229244E7015F57634A249D07074B392F989815E3CFB\n      C183DE7735E3A8130D03459D2191D561ADF7DF5FE93DB7C549B9AFBD61910F45\n      BA21C04E1170DA73733C49C2B9925775590D197A0EC345507FAC0ACA033614C4\n      7AC926FED2C4E66B1BEE2074A59B70B1A355CFC019414D0735ECF034CECBBC7A\n      281499D75D8D51A23C846C811BF5F382EC4E97CCCD0DB6B3AD91CE408A2ABCB6\n      BF62DE66AE84EF05394F4DC81A0AE0A68DA2C3FA790B3544B9E218B852126B5F\n      298F716494210CECADB5E3CCB04B6CEFBAD1756E312A06C157F674BA6BE1ED6E\n      74CAE45235BAC5E35E31B77082BFB62ACB05BC5BE77E5E634D3053D20470C6EC\n      90D44466FDD8087A1F79BA2D76AEECD41BE3A9977BD39EB86736704B00BB92D8\n      F116E6CD596FC2A2C85696B1B6C636216AF4CE6EE37FC870581AEA9C4A697202\n      35145DC8A166EEA347ABDF711F331A57E5DC70883C570EC6253F3F73195DDEF2\n      AAE5D4C37AADEFAE2599EFA0FB8F06F71C5546DD83409392249E8211E1816D8A\n      4556052BEC5343B9E2F6F93FF9F3F52F9EAFECA805855939A876A8CC6A7FC907\n      9F1FDDB82700EFAC862602963687778533559AA5D5D1BE5E89D9523F13853943\n      A040FE40BB9FBCB5F2DF373B2D078C51FFDFCFED7FB8DFFBAD26BFBAD5DD5B99\n      7AE7887CB30F9A73EE7325FFBF3D7BF1C199F91F196F8095D54F32F99F3A6D14\n      D67156BCFBC4E9DBA7661CC9C2807A9E4154437502DAAC6CF1F41F9FFEEAFAE6\n      F6373CF0C054AD2C8B1C985CE944C8A7C0B3D5D78EF21CBBF20A8DC5D32FBC1E\n      46FE9D779ECA32932DA83D86174CF3C27ABE4866292346E7AF5C5F6F771E78E0\n      814648F5486CDFDC340858603761B29DA7673BCBA3E1CE37572A3F73E4E86DB5\n      A8AB3AC28B2B979D1772FEE76474E6C6CE5DA4F1BE83A5FBCBF10C0FCE64E57F\n      73E5EA59994CA2E8AF171716A6489474DD11361448BB066E126D272A504792A1\n      8617307C2ECE3FB6B5F2A113C73F50C88017AF8C55FE646787205DE29D3BBFE7\n      89F7FDE2CF1864412257AEB61D0D6F994DBC5532F3F64499B7FAEBF5D74B6580\n      C2125AE58B14D612486AC8952E3014D98D4D9874FD43A8B3F55AE7DCAD83A7EF\n      51751F19D20F3D660791202A002EA8ED63B6D6F2C256B32B136B26AB75FA706D\n      A220E27397967BED85274E38DDCEF0FA4E70FB6DC36A514D8BF6E72E8E4D9E8C\n      BFEDAE30CFA034AFCDB3ED75D4DF24C2AA719BC090536C8ACE67369A57FD0CB6\n      F2D3D3D5230BF1E5A5F0D062F0DE3B64A4516EEE0ACD2D67D2545381CC8A0969\n      921B4E1B1B30838E9B533B2C318DB73FF14974E95CF3CEB9D84F4CAAF3D61657\n      2F5D8453DEECB73FD4991E211FD52E04DD275F77CB855C6494077E12F26A9F0B\n      11E4531BE79395F309C4954196B78AA20D754FA891C9062C352BC653B830D81F\n      B8FB5DA744C828CDEDC8490D3C3FACF9A486BB478F07E1A42DEBDB5E1B32ED4C\n      473397AFAD7663A632A7C5C89B2CEFE6239F83DC0B9654D1A4EEDDA5F13371BF\n      48FB75A217FDE8D0E43428B84EB23D41A92A4DE61C95E66869C670652E9C1615\n      4D57950C776F77E26EDA5B3C5D751758EE218989B59E50D6EC8F9EF76F5CBD22\n      AA6CE1E462908F6FFDE346DECFC86D6AE2FE8AF219571924DA235E02FB253821\n      D6AAAF7DEE463CF49428C599CC5CBDC14683BC285137B4FB963C812865D2706E\n      DBA98E8DB443BE84136E58C5864F2ADF01910B0C6CBB18048765ED1B2890FEF2\n      5FC4FECD30AD0CD103CEDE6F3B05C8D06094041861834609C0256882C50A3A69\n      BD26800FA2238B0F3C099FBDFFB059948C31A9DE72D1B4FBA08EEBED323A5B5C\n      6E0F01776D536C49B4893B0B8770D787426579C14C4244D681155AE70A6DCB82\n      0C462AC50CD6EEF24006645A6486A87108126ED5A5814BDB89A877A75B41BD3B\n      66D06857DD20DE0CF5C6119A0CA88B72C7D195C530D8530420E7C8E1E5107879\n      209CEB2FACD25A30F3C4343A36A66AE30642114DF98DF28DDF3AE3BDC41C1ADE\n      72921D4950E29431AF9759D5846CAEC2FB4B933F741B9F68EB9C186DCD097239\n      2A5EEE6C7CE49CD7AB6F17A287B354EA959EDCC181D27DC5511D078BA1D3F078\n      99C09286D1A46EBC7702D6062C3659DEA89C7E79B0D83DB75DAC88B20C5921BB\n      76E8A8DD11AE12D0805688CB8A08F77B4CD374ABD03D166054184A809C3CB72E\n      1F98080782B21798BC9CA02498F24A8B51516299CE410149AE3CE052508A3792\n      DE7060BEE54E11CE12642B083DE164C03A0BDA3D68E4DADCE32ADFF6277B05F1\n      1CB10E7B6FF69DF52A6BF6A2071D364BBC81C7AE8EB27834B9E701F66C0B5485\n      7E304DA3611DCFE92A35F9C5FA41DAB151B218A6E6A6B8D0532DB6737DA7313E\n      31F4E2EAA1863AB9E8504F69C2B1EDE6B399031095A40608CD3FD63E078E8D2E\n      749D4FC7CCF5524F11268C32A1BE21FC3C8BC8D80F3EAEEE9E86799F0E7AA262\n      C8BF817B551268E30B671A92A26A293624763DA19D1CEC9BC1EFB93F192FC34C\n      1A2EA40CD701865F454A7BC89E4A2B3BCADE900A5B4253B45E38F3B5DFFD3B79\n      3D161A1FA8E2F96D1E14F595AA3F20BD69A3ED83F2B3799EF5E2EF28CFF8C560\n      BBA226E25A6ECB6FD3947708CF1B22F04569BD52F9D5A5CB7FDE1A18B8FAE983\n      874E77B73E518A96D6372B287CDC0DBF39D4CE64F047A3F4B337B73E74C7A9BB\n      37575707F99339FE38E363157F42B877CD2C4E4CD748D3683BD688AA01350F30\n      0882C228DAD8DEF9D2D75E7CE8D8F1662530FAB8569F71CB4D183A6ECD310B29\n      1F319DE614F1341E7DFE0B5FA934FCC71E7F6721A8091169382C54460971EB62\n      835D8A3DC7FDCCA73FCF33FDAFFFE71F9B3A34450A79E3B9979FFEFBCFB79636\n      0DF674B27C18924BFDE5B5E55B77B9E897DFF9E061057DBE4AB3C6352D3E3A6C\n      7DEAB5F5BB6A730F4F3AEF9A2635012F92FA7F7CF3CA53ED0E81C15FCD368FEF\n      A995473D9A528DCB1A9AD41C9B5CCFA08B859DEF7E0DC8E765FCBB297C67C17E\n      7DEF42797DB5B3B8EF0F86C36D3DF0E4E6B7FCF8F7DEF3633F222C66DB54B0BB\n      9C35F8677F2078CB92F72D4508DFB664523635155694608C0CDB4E29512A49B6\n      6E2C55C783D06DB72FBD08DDA076FCB0CD3983B000916CB8DA152ED738730D68\n      296258788C7777910D96666C39F37ACDAD6CF08FE7F9E258FDCEF9E199572BA4\n      CAEFD8D723C3F176DE79EA72E3C0E9D137DE1E6629B6343D4B5BB7BCB8038A21\n      F53D6D7E77E60DAE0DDBFF74ABB6EEA2DBB477E2E4FAA03DB1B719DD7B18D4CA\n      DA3A5670EEAA8C528F47D44ECDCE346A7AAC0045AC28C8102D3B15D02D86CF9F\n      D97CE633070ED451136576720FF65E9C3CB775FED40FDF2FF795796020D31FFD\n      C35AF773B7F69C6A64E56D38A09EA8C6D55621418D2DAC5FC8AE9F1B2A10A679\n      3114A2C50B230DA51D713FAC06C1FEEA4426F595EE76496591E74A267D40EBA5\n      6A18547CA9CBA077E894EFCDD99F1F6C65C5309A1AAF5DB8B2DCEB63C42B1D21\n      AE8978C3DADFB8DB015A96FD314EF6A77EE2988BCF6A5447524686742A54714A\n      872A137B68C8463BDA4B660E446105F5834D87578C02701C570BF7C6D27A6D3E\n      18BFCB2BCA23E97B86ADB9C4C8EADCBB55173DB6747D8DB864CF81DBF8B56CFD\n      B52D14A8DA7D9E7B04163CF5718821E978DB4D3121CF86E79E5E1DC970543883\n      A468F338768D3A5075E83643A305D5363318A38C4C02B607C1363C04BB068475\n      E250BBB1A8C7CB7E64804624D15155FDC64873D8FA871C5CC0CCCFE19D64FE3B\n      4EE92085B6D610DAE9B6B290D0DD3564321825AC2185F67574F46D20B4FB9F56\n      8CDA39966AF7B0D01079886CFBE05B3B10F65150EF4E5FB31EF672F75FF33DF3\n      3BDAD9A48EA3EC0445616B6CAC9B89D1A1DA36EAEE4E9E31AF99E599353C2738\n      66ACD0D68DC8BCDAEE39BA2DCFB0BCD1684F80CB90D6301D27642A7442CD1CCD\n      A371A77E94447ECAB0C37C0382A3D087A4EBBCFCD2B585070E8CDD3F0E0F8D0B\n      A4881FC2C26FFD8FCBC34F2D1B706901D6958EC8804B8A5A04C6B1AF8464F3D9\n      E11F7DA7BA6D9849E6A20AE618905C0FC1CDDF7C3938EBE7126CE0B810EED600\n      6CD9F38C7C248D0A75F6BA64320255975600F6A2BCF1E8185E28783142420D74\n      5A2D668BA564E77CBF5CF858E044E38E34812F4A18D411768CF62EF1608FA150\n      BEE8C96275186293BE0A8DFC2C35774611875BA0738291484424EAFBEA4ED331\n      AB6BC807BEA225554109DDBEBA6A545075EF189920B18C0D6D3054D4FAD7D8E1\n      658645BBE66A4BCA6920B0A3139E21CF5566DDBF9AB83D7FECD8D8506CB1032A\n      0FE12C9B8DAF76B362BBB9FFD4F04B2DBF5AD2F7CBB4B25D0D67948FB5DD3D37\n      4F03D5C0406D614F039C40AD67C5664A6A95A13368DC390B0E2C60E04965FBD0\n      A9E1F146D163AC8671B272D38E0C43E62AD792B32DF854667BA20364BD4F1933\n      FC98F9941D9C98FAFEC70765E6B1D8B5FBA86C8858457BC50B17F3A5AD52A35E\n      98271B30BDDC31723978D7DDEAD4BEA1471CED525B835C319C57EB70D70DD108\n      4261E71532D7B6519021CCD2D7FFE8F35FFBE857B772780FCE4E46554F95FD61\n      1EEA0456C819E2FCFD66FB50507ABF1706FD3E88AA43D7E808CC7501754A24A3\n      46C04B17D526CF61FAE1372FACF0E25FDE76E0F0DAD2E77B24C560BE5EBFDB15\n      279B68CD41BFF2ECC5F92347BFDFE4A1CB17FB49FD8F07E0D9B95A3FDF5EC8DD\n      BB26E7EB73D5E6A9A95AB33C11D483DA389E6C204A2A0277B73A1FF9F8DF1C3F\n      B2EF9E7B4E8DCF4C07B50914358551F550DA46768DCD9A3468D35AB9F5E4EFFD\n      B14BE58FFCDB1F288D2F02EDDA4D16649419B687A2B64E80C3247EF2B7FEC7FA\n      958D9FFBA55F8CF64E59F333115F7FF5D517BFF0E52BAF5D70842B633620E2F3\n      9D8B5756B61E76E12F9C78F0DDA53C8538A6F0F9A5D5A7970746291C41EC5D63\n      7EE8D335BFF237EB9BBF77F1E60EA23F42F4F71DDB7F542A964AE1054683462C\n      356A3F83D48E18D6E8962C2E8AD15F0433D56B177FF2C8E15A499FE7E8CBD73B\n      6EC548F4CDEFFCE91F3AFDDDDF01CA8ED619526F37CCFFBFFEBC7D46F87520B4\n      9F729391B07900E176D2A85076E80A6FB56FB537F61C1E27EB6F6EBCF2FCD4A3\n      0F14150F6798B5BDA03A9B5790A205E5929ABB0F5D450A05467673427B4C2828\n      571CCCDBCFBCD45FEEEFFFC6770FB2EDF4DAF5A94347E45864048ED74E96BEF8\n      E69E130F250F1FF6D20C00911503B9B55C4A06C0B0B2D09129F1E252FBA94BDD\n      0B3B8B8D7972ACBCB1DEF28E2F54DF7B3A2F39EE0019B226A9C89CC2D398C8C0\n      DC3B6642A9701DD7C8CB518A18F1023F26E2858B9DAF7C31DA43D08CC989A96B\n      D6B3D0EDA7737AB43CF6FEFD79C368664C46DE8D3F3AE375DDC9831569645641\n      8008DA4ECF24EBB17C6AF31CBB7A61084925E77CA4D89A01402396ED89140792\n      EF89EA938DC9B57E8F8B9111B64551444C8E2367A2D46820BFE6B1B1831A2C70\n      E5E9C210F3D5686CC13B7F6DA5B341A968ECE4836510AF24704706B768BEA2DB\n      8BA8B2D8F7EF9D2553F34D9EECB4D7D60DE934F79D40675F69FC50A989D22C2D\n      5A6353686A36ECD518B5EE8F52414640A5754B186D37F7AE465AB9054A861B07\n      C884B39B3A46DDEE48B982DACBDDA0E68E4FCF0E5FEFEF5CEF807DC5D4130DE0\n      085F8586BD6C945627F3B9F42BF0EA99AD110DBBD21D71B931DC1E61E9E3A02A\n      49D9A322202383208CC3B4B0D3B95DCF0D3C9F509C715230DF815180CB1494ED\n      20E7C23D21EA8F35B514C9F362F4422EA044C7D0EC779D32E442DB8EE1DD41BF\n      5602DA517816E504B72CCA5CA9E8E8C27D7F009FBFCF02E1EE763E78ABA15083\n      5D33693B4746604C217CFBBF1608773D984C12B7E78818F3B7DBE8B179062329\n      AD3414B96D2044C4F6869BF8B753AD74C672EBEF4069CC590E90DDB0666F9D2A\n      DB794BB6A319206292B1B01374C63C67260C6A5086BCF0223D712CF4C6CC6F2B\n      19C212F3302C28C637DF18705839F8D8023CED70DFD5BEC90B22F9D8D6F29FBE\n      1E70B700EE304523C180CB6B2E6C6A9F10352AB78F7FDFBBD4E33235EA5DF9C4\n      00B2939BF7DDFAC4ADD1275A255DE94039104E2F815D91E7927500A680EEA760\n      26C4A1EF56ED26F8A07667899E8E001CAA3C1D69119964DEA5ADD7DB6E0F46DA\n      CB84DB2E640675E0D8A909480A15727FD151631E4C607275DB906B8DCD950B58\n      4E0530C2863B54BBC840C080CE798DFD8D4225462821023CEA93111CDD689B4B\n      5EDE5B4753DE30EB1B5A12184DC699B6E3BB6D0502D00E9591C923AA3C8AC31D\n      5B84B95DEA9DB56617D3FB67F8FC70E7DA76695F1384B0342C27D7BBB1D31BDF\n      3BBBFDF47AB3B9286EA745A5530A4BC00F392CCC5D200CEA3E2BEC560FF268D8\n      BEB05662816113C33AABDF3905E6F76148A54296421868B2A392911825E9F24D\n      2A53873A380F8767568A5744807D090CAB52D8D6D81683317FE65F3EE69F5E2C\n      C400EB8C181990F5B41FD0ADB4FBF917AB51598C957992CBE5763164E513B779\n      0FDD99FA2E70FDDD2AA09088B25519C8E3C800883D15879240EE1A5E65EE95EB\n      62746574FEA3CF7EE9534FB7064BF7EF3D38BF23F673185131F4C08B61E9AFCE\n      5EF8E0ED27EEEA0DCA06E04B95BE974069789B1DBA8395CA0DCFF3025750214A\n      9FD8DAFA44EFD6E347F6DFB5BEF9C7196DFADE41C0EFF1C4E2FEF1E710FD95CF\n      BEFAC1874E7C5B8984D76E6DC8F1DFDFEAF51F39353B3775FE2BCF1FA84E3CFE\n      8E7BF61F9BA10D577A7E65F1406D7E01630703D05DDDF9C8AFFFCECC94F7DEF7\n      7F43EDC03EAD8C520CB93D32372CD5E0B90300F70D79DF5EFFBDDFFC0813D94F\n      FDECBF2B37F7D889D4D4BE69B1FB5991E7818F572E9DFDEB3FFE58DACD7FEA43\n      BF5C9A9FCFC5C0CE05C0BA686D5D39F3FA9B5F7CA9756DBDA3E43F2DBD7965B0\n      91F5D5015FFFC13D27B20A9825AACADDD75BC5D9D6E020C67751546F943A08BC\n      1127BF78EEC6EB95D26277F0CBFBE7BFA554112C158406869D0AC3662451C416\n      4A39B4A5587B38FAFB6A75FBCA95DB0F2E4EEE9FFFCCD94B2B3DB6D8AC0568F0\n      F8B73FF6FEFFF81366AD7194174886C243FF77DBFC3F9BBEFDFF044243931416\n      9C106084BD6DCD2A40AFD35D5973A6EB51436D3DFDD986CCE1BD470B17F08D82\n      E88968E2608E99A49903351176BEA34D30C8641BC5052C7481C176B031587AF6\n      1939DBDC7FF2EEF66BAF3B1351B47F562789216DC36E7FEDF59523A7DE9D1DAF\n      39998604A6D9365A5B0EF20170555B8B8057E90D78E3AF9E6956C71B771C5FB9\n      7905ED2BCF7DF0B161401361745F99885DB70C6DD6987548B7DDEDC216B8C3A2\n      E0811EBA59157AE0A937B63FFD4FE585D03D1CF674170B5D538DF85CA73DECEF\n      F9F6778EA60A5E9315E9E1ABF2DAC79F9F9C593492D145239C32CD51D7B57AA0\n      9154365FCE962E26D06FA69CB579BAC68B3E874C1A5E22121E8F536FA63C5608\n      E5FAB4AF5892C50D9E9DAA56EBC0AD7951BD44497D0816042FA3ACCFDDEB7E69\n      9FB3B6D9D9BE0668DED8C8BABD32BE369037137213A71DDC3F144ECC0CC3C7BC\n      6272BEE11216F787BD425D6E6F675ACE45D579B75CB7B390068076F7ED6D7853\n      752A0BD7E5398815A37AD4DC5C192D3C34E31EE830AF8F8D5830284733EABAC3\n      D5A1DF29397D7765F57AB559ADE8B9B5E76EF6706FEC9DB5897D0D9E168E4FBA\n      CDED463AB7FDC9AC757E9085D18E723A051FC87827E9F9B8D4A081918D05857D\n      C98C8EB2938A3DBF54B1D3B2F22C0B11054551F249C94181664D48A85704F7E2\n      DA83D31A64F20AD8F952DF0EE03BA0A7BFFBB89E001C98AC0CB01D7944766B98\n      8575093699D6E297AFC3DBE6EF354078FFA1B726CBD82D4D0B88CAB6C6DB9D77\n      CDAD67A6DE2D8501D81074BB6BAA6CA7BDD28810F3614DEDB9B09B1F46FCD91F\n      352F11DB748C1CA191D86DAD05F60810D8EA09A50C101610718D989DB369BD12\n      DF3A45B768A8EDAB3B08D77C7736F2A731AE2B69B4443847BCC532329A01727B\n      DC1965808C483E73E1F99DF93B26EA8F7960CF6CA24D40C5E073ECECEF3D53CA\n      68A86BC321DA8171EEE50DEC3705757CDE77B64F7CD33DFC07ED4E860950471A\n      9894B9C1941B70E5C937DC250A70B52D613BCDA5D05DC6371D6B25B91F8869CF\n      503DA70AA0C7FB683F6E3E360B7CA306E3D8E03EA37E51EA5D1C89E5A42203C6\n      68975B9B6DCF85354C30E7CAC0F2341433AE217DECE6400E0CED7480B97766DD\n      996B490A841852B2C04570B0EACD51CD72575724D7FD418F8F722CC0D8E29868\n      E891EC034123C3438BDD4E75C7F075695295B23C253480CDF500FBD6B1BC7536\n      53233A75640CCE8251B1952EF1B1C5691D0927F187975AAC2E1B33959D9737C6\n      17F6A48780AA881035400098CE11814621AB6EC1530E09A28AB42F6F8DFB5359\n      36640BA474E72418DB8B4CCE30B789584B55AC842DD84B92FCD6B263B78B1C38\n      A0BDAF5E4FAFC2B213C922B7F3FD29EA23C1EF5858F8E16F496981790A55AC41\n      8A2127394DBE7651AF77A2664D841E1816ADEBABCEF464E31DF7A299692120F6\n      C2826BD7AD4111585F14E868E43892EFB23943CA42202DDF4E61D194E3E2C58D\n      8FFDCCAFFE5567AB16D41F4AF0E9C01B11BEEE389756B79A1E7A62667AB63F24\n      48F5A91D5B5D666545BDDC247ADB178592108E515F6DC9A746C5877BB7EEBBF3\n      E8E96B1B7F816A13203B25BBEF996DFAA5F17FCCF47FFBDA4B3FF0F091EF305A\n      6DA9F71276FFB688E71F7DE7F13D07FFEA537F8F11F8FEF77ED3DD47E665096D\n      1258D97BDBC4F41E429D8C6772C83FFE1B7FE689CDF7BCFFB1E66D87010E01AD\n      DAD12BB645961B22ABAD3947CA77DA7FF23B7FD2E9777EF4E77FBE3CB90F70A8\n      4DBE87CCAE2C6527DA03F376AE5F78F2777F7F30E03FFBEF7F69EAC06DDCB2D0\n      98F21C9925DE1D6DBC7EF9B967CF9C79E3CD0B2F5F2C85F55EC57D75FDC6E350\n      3CF2D0A1C5FEEADD95C99DDC7FF6EAAD71884E574A33A5201BF5BABEFB6B57D7\n      FFA0976017FC2F41E3DFCE4C96506E56A4C3354332A7D267DA29504A9D1E8071\n      7B782620CFF737379C20F42BAF2FAFB893FE5CADB24FC05387677FFC0F7E0DD4\n      88C08A193A2FC8FF2F10EE16D1982CC4045012380E75311B16AB37FBC378E2F8\n      81D1D6A5C1C517660F4CAB890A2B64FFD6B0317B1C07E326F968CC916BB31091\n      26AF1905256C204AC1544E759B7EF5CD95D56B73EF7B44F4D3F4D272F9E4DE6E\n      0D045C84DC59BBB1510CC5BEA3F7E413D4F03942B0EC6FC2AD252C06192904F1\n      A35EA9F54F4B7C359DDD373FD859614767C7DF7B8FAC87588685224357041006\n      A90795CB1C1B8FC4564D5365544956406AA7D40DCEBCD4FEE233537527385C66\n      C8A4079967388CCBA3A796F53BBCE683B7A7A5222F6595BC84BFD8DF7EE966ED\n      E478E29910D626CB030273EB91202BACD479215B3E9F02B73160D9264BB621EC\n      16E6C2D11D362AA8AA3A0E8F0DBD944DB7C421F023770117EF5A180FAD411E2D\n      975C815AD1BC618F643464E83A26FBBCBC509D0B1919953692785076DEEC6797\n      066C83C021C8E6BD4A3D83B56414456861B21E98571965CBA3BE725583E219E0\n      4E86156A3438E8CC4C479393914F11C02C4323030E153475E3EC209CADCE3E1C\n      717F1D6817D3886166B29347DC74AD1F265E6FB93BD81CCDD6F78DD6D9E6E60E\n      6E8203EF5C04A54C6311975B1576A0F569D6BB92A610B595B3C37986F3547129\n      0DDF279EA1FB1A0D25E3C0A600AA0C8A214B84954442F90896031A403041D024\n      36FCB21F3D12D64E4E2A1AAB4DD4FADC8EEC61EF001AFFEE236A1A1526339A85\n      C4CC4AF2B5CA913DFD93D61CDAFCAD03101D99BBF7231608771B274C52B5C6A9\n      BB5BA3B63BDE2C44B53B47D4A86FB8DB6F6FFEB29BA80635D1AE28308253EC76\n      11DAEDD2DD3E4213213ADDED5774843DC2B26E85760E86C147435EF23CD39A41\n      6C9E4E5894B58609DA565C989F43F6B5A9C794F0099E099CBD86F8601CC23C0B\n      46D1C9793A9187C41043A7F063190ECA7AFFE68BBAA7D60F7C67939EDC9FD259\n      E80EFC572AAF7DF80B783DAB170DCEFC4D3A6CE3FE24AD4D198AEAC53DDC3A7A\n      DFB1E17F68784347E50971324B44994F44B5FB9767479FDD71C554CFC5ED2286\n      896A29B04C0C5A8B7D793CE311A7143530AAC1249D6493DFB007F85D93D313E1\n      28A97C512F966472B95D295C9EE2048786A611ACAB66A9991BEAE74E538A45AF\n      8422B492253B1DEC3942FA44558C1CE034E5620004A71587EE33F9B8204280ED\n      28E9982BCEC2AA1FD523E62703BFAFB00EE3529846D03251213C0590DDC01418\n      31D750EAB4A64377CDEFBC3A302BA3727A42D67BC24DD2B646EBA3C6FE491541\n      983ADDCBCB64D2AD541BDDB3ADFAB1B1DEDEB6531D0B06FB41B5C33423466827\n      42B61365B532C946C5F0EACE6C75314DFBE458D539DD04A5452340EDA924B526\n      65B6DC00192998B2D55B8E3572C3BA0D77BE72556D46402247DA51A7799E6653\n      51FDC7BE0D1C6A8CE4C8113911B1F9B2829973B63B78F9BA5F3652DC2746816C\n      0E86ACA8BDFB1EB4774E93100B0A8867821F5AD25D120466262201F5CDA2305C\n      C08036883417CCC953AADC11597FEAFC277EF57FFB62BF7C3956F36A74B7437A\n      4C5FC448B6BAFFF5C4D1FB72C51CD02D4B73C1CD1ADAD38D30F4078E7485619C\n      BC53290C9D6BE695D761F93F6E5E5E3CB4EFE8B995813E169687D3C1EAFDE570\n      C639FC721EFCEA99CF7FDBBB16BF058FA52BC517757CD6570FDFF7E8F8D8F457\n      5E7D65B5B3F59EC71E7CF0D47E3F2403EC54F61DAFCCEE959263C7EDACB59FFC\n      EDBF20F9D67BBEF5B1C593C7B4DF206E5DDB6AEF02683BC9C74E9EE643B6B3F3\n      D74FFEE5D2F2859FFC0F3F555B3861F2A279CBD6F05D9B28C2986973BBB3FEE6\n      2FFDD22F6910FDD4CFFDA7897D7B0B9D0B62282DB3836AE261A7D7DE5EDF7EE6\n      E35FB8F08557C7EB735DA1B7B2ECFCADB3DF7E6A66CFE8C60142F72F9E3C7B63\n      7BD8DFBE636E72119AF01FF0B2FF37A9F38B2F5DBF5177BF2DD5BFB06F7E2A14\n      2E17410687547642E133594BB03417D8093ABDC132539F8F8ABFEB0D06034040\n      31BFD75D888285B65A2C910FFEE2BF5EF8EE6FE5C2EEF81AC5BFDB7BBCDB2BF1\n      7F55896AF5B621EFD70F09E5AE7F09108261D72093DE594B3697A3F9794CC1F2\n      D9AFDAC18947E784EFEC5CBC159266B47804BA63B664148A82A41C33B302A861\n      E0267359BF69A175566CBE39F8C22BCD83FBC8893DEB67CFD62BD3E14CB34DAD\n      E0ABF6F4FA4B3782DAE4D85DA73505D25A0F28BDBE4CDA2BDACF12973BD2E367\n      D3ED57BAE3F5F9E1C67265AA49FFCD314D27312F61E4B2088C605E968432A3C1\n      5DB3C63D6EB02F05CE40AA72CF07A033249F7E313B7BD63B55710F1991BCE10A\n      A900D16930BC98E4D745E507C360623C2F93BCD62F6FB9E99FF5FC0CA353C500\n      EF38A39A14BEA63CC8C1C029225D4ABEC657CFA50257863CDF96C5BA54B99DA9\n      410648F47106394F0D1D0CA303A03A6C0DAA357F0EC5F74ED272190F10A8D5AB\n      2ADD684C3BB81E64058E97D2623608BCB0F7CA36EA06EB89DC20EA6A962C17B0\n      E784FD38A9685D52FACD7A05E7FD3102BD58F9D8487AB3D88A3159ECD3CE0C8D\n      CA2E0A03E691A23C1B2F4CEF630A24740449BF2CFDCE92B395A9838F4C0533B1\n      E205C401F091F6A9E12B2C6F8B761CEDD4F8AA376CF534F6581BE5714E0EF0F9\n      87EB793154612F2A0E2CFD238B97592E81C1DEEDBC48719C0131CC21862442A0\n      AC5D602EB659068614E705834639DBF21496E70141F552580170DAA5D3880ADC\n      0DBFA952393006BC54F4F5E66736558B46079CC6771E90F32481991D2D63D8BE\n      8E6C0BA36DE4357C7AB7D041DB6299B97B3E029F7BE0083422D13A98DBDA2DA3\n      E60AA173EBC763EE3AB583B424DF9D10B15BB1ACAC2234FCC7FA5210F315940B\n      83176A37A86D9463BB5F673DEEB51DDBED3243D62C72DAAD592347F3A2B04D88\n      10E5BB655B42D86C2A891D6640B8A8201A4AEBC957F29D66108CF9514D432276\n      CAA76838EF1A09E5798149112ACCB5C7649B779FED4F9FB89FFEAB834BFBB6C7\n      8C60BA1E5CFEAF2FF00BB281A2CC5A231531D52502A7092D437325BBB3872706\n      BF315DCA8DFE4C844E3CC3EE899BB9805C179BBF7EA5BE3AD6F5F40E4AC476DE\n      1378138B1DA93C01F7978219973530AB395E868BF147E7D5DE34612D2088CCEB\n      088D683B67AF08A75BD79E3FD24592700251E8D8FA1A8979360EC18CC9890666\n      5C7693978A90E374E48F0AAD1A70C24911C7B17FC805734E9E0FE3AD814A40B9\n      5C23554FD0C20D0CE2D839E8761EA941573B72881364AB0A0DF366C8DAE54951\n      4472DADDF2D6DEB8213C307E68C29F701919709D905BF5221FE9031A3541B051\n      8B5F8EC37DD180B4D26E317F686FBA90A2BAEBA64D3BBFD0DE51878DE251C648\n      01CBDC4976E2FE6034539F60F188DEB1D0B96BAA2142006DF387AD5213765EA6\n      7095CCBAFAD62DCF3AFDBA781DF2CFDD8C77A0F44C9AE001031B5AE16FBE6BE1\n      7B1E61591B2B0E91CE89C62CC5468E3CF522CA553033A13930F7B3BDBE8D6F3F\n      183D7C9A49E2E71E44511A968C00756C2D852BDF9A54A2760F9F20240A5ACD84\n      510C729FB87875F495FFFD23CF7DF572BB05CFE1FC6CD27632EBE068EED08335\n      E737668F1EE5C37E33D19236BBA5ACBCAE514948D7A7AEEDFBA38688B9D52CAF\n      3AE81C2DFDF6F5EDF1FD8BE5D18D1B6FA4C7F74EDF5981C7425978A55799FFD1\n      A75F7ADF3D879A15FFCD766F13901EC077BEFBF17D8DC9372E9F7FE3EAC5C79F\n      78F4FE3B6E370441FA5E65FFDECACC9CA1E78634B054FCE1EFFF617BE9E2B7FE\n      9F3CBD07B46D57561DB8E3C9E7E6775F8E3F27FD2FD557AE1212525155504525\n      5780A21A30C66043DB18B703668CEE368341F76863D334C6B919DD0D8DC10497\n      8B52259554AAA41C7ECE2FE79BEF3D39EC7D7AEDFB45FF21BDA1FF74DF7DF79C\n      B3D79A73EEBDD65C9FFAD899871E2C2C879B15A16289FDF57022908661DC6D7F\n      F31B5FEBF6FA9FFEDCE74A93736310E1E8FF2FBE9412D8D2E6BDBB7FEFEFFED2\n      03671EF8957FFC6BF5C5A3E3762455914D80AC7AA3E1D6561E255FF9F25FBDF5\n      D22B53462D4CD2BD38BCD60A8F7B870F1D5F5CDFBBF58B1FB838B7B63F3CC8B2\n      89F9890AB5C27564D035567FFED2FA3FF5074789F1CF4E1DFD519CB801886C13\n      82978BA050A33235024152508AC84BA3FC6EE2FDA9885E4F3DCED1472B6CD1AC\n      A7096B66F1C7BEF0DC83FFE21FB4515A0F1375C054DC6FA9578EE6B9AA55575B\n      8AE3E6C9B1A50C51557212C7341298BB1E160549C39B371B96C16627C2EE7EFB\n      D69B33C76B854B78AA75D7FACECA49BD564D7302D14C0448B23C233ECB639A32\n      5450C193C88C64E465DF7C6B3F3A38FDEC53F9FEEED6F6EACAC3E7A4F2A3A411\n      C0798B765FBA665F3C1F5E3C61E5484B639265F1E12E8EBB7971A857DCF46ED1\n      FEF2EE2CAD1F9AA3C1223EFD89A73DB76A884253E7D134E526A62E445C08845E\n      C74484E591409CC70E5287DD7787D99F7ECD1BAC573EB0C4171BA2D391693FD6\n      4132B8257F72EBD56BE50AAD7E76616024D8E42E992297B3CDAFBCD25871E914\n      C589C623BB404942235D68218D0046BC2B64E7ED40A7B59E4CF792A83B8C6255\n      7FC63353622A6BCCD505AC65268DE6FE76B74282D972747472D2D64A87C96E7D\n      594BC2B86935AB735624BABD35436FF60DB7BA71294F0FF830497648BC1678DD\n      580CDDD23D00584CEA240F784AD504456E084E98EE2721A3B844D004C6733A9F\n      52E37428C47CC531669669B5847281B25216098F1E940F6FC6B38FD79DF72365\n      5692DB9CCBC24EA238B72C371D86C95E5B8F71DE95EDBBD2F4E6C203C8DEFEF2\n      736539D70DEDD0EC2C6C7F294687A8C7BC6D5DAE856CE81322010D72104926A5\n      655D9552467952D6B4AA56CA530CC4AC9DF824230D62D68CAC64FB33F0A9A24A\n      0C99F427E8D4F4548AFB454A7BCF778BDB881C23533F77A69802EDA79A1A94C7\n      83B83F094555BC2021C6C7731671CE2C9FFBB7F83B0F1FD718312143A94EFB71\n      193E307644834C9DA0A0717B3CBC499A89F76A4AC7278AA0FFEE37D783524C95\n      C7CCB8489A28778871518D1C7B96AAFD8344A19D1A260D311026B19A728F810F\n      4B49B1805FA10E5EC9B87607D531AD716E80E4A0C85213A7F406D14AD8A747C2\n      C671177E84E99022913463548E7549BD37D37860D57FF162FFC9C214D2ED340E\n      FFFDB5F637F6CA052461B49FE51EC536CBA7E086220E2F9D5DA90CFE8FE55A0E\n      047290915C170E04A6AF47AEA892FF7778F0A7BBC830BB3846921F0EE31D91B4\n      0A55E0BE6CEB735AD8D04485996111D51E2EF3F324247D9212913610EA1BA358\n      5CA2D99655E8862F82345595E0A646CAA8C8A80C001F970BA423141AC9BDDCF5\n      CD420BFB20F21875E2AA1650AD2AD9697D50747C3FAAEA65DD34A8863296C2EF\n      E68C275ECA302B401F004F515ECD88710252A7284C88E69CA515E22477D2C1EA\n      8056B4D2F1BA5E37406A248597C954DCE2CC65723189EDB87CD8482EE5CEF1FA\n      7E743B4FC4C2A9E3E97C862A8C87363633A04758D2C40FFC3885EBAAE6C660BB\n      9324B96D9832CF4A4F9F1F3D30ED844086F4FBAE00CAEE18AB7185B9DF915B6B\n      008839B3D17691FDD52A1A6901531B985A4646CDEAD4DFF9647EACAAC5439034\n      C2A4519698C35178EF6E7C77D3A9D6428AEBDC4E0E461E95A5E71E930B3314A4\n      5F6A0ADDC97487AA62192AFFFAC47A3CD1512D67D5AB4AF5224BE1D76805DDFC\n      F36F7DE977FFE0DA3EDC9219B9D478E7DE65E20164BAFB839D9F3D75FC17586D\n      517807561B585DDD77B0E5C142F629CB282A1150995A982007A70649EE51FB3F\n      6E0DF5E949E3E0968526266CE7E1AABE808743537BB370BFFCE29B9F7FFF058E\n      D3D70F5B1B98E372ED879EFBD19A5BDA3CD8FDDAB75F78EE479E7BF8810B33D3\n      D3C2D626CF9CC225275327F4F8F5EFBFF61FFFC31FD468FE535FFCFC233FFCC3\n      A338D96975AEDEB8FDF63BEF64715C2FBB678E1D7FFF138F8C06ED5FFB67FF34\n      CD8A5FFAFBBF7AF6ECD9DD83C36B37AE43C8ACAC1C99999A86CBAF972B6FBDFA\n      C63FF87BBF0C7FFDE55FF9D523172E6A0C37CBAEEB18898C7488B8DE30180DFE\n      FC4BFF550EC26577E2DEEAFAF5DDED3B9B61BC7DE3D4034B32E97D7ABEF11CD2\n      466BF18094CB4DAEE35DD0529E36796DB3FF63BB5B5359F1F78F2FFF94416A61\n      E8A9361FE28810C8468475C81D7A8E39E5DFCCF046B7F586C3FF2A19AD948C4F\n      5BD6B2E16E8EE25CC4471E5EFECCEFFDD3A45976FC00083450368AEE0361016F\n      928F9B7BD4F1F25F03A184E55384AAB22214CCA581D7090FDA334BCBA808DA37\n      DE51FE1193A860B97F6740D8A475E228358D2C0154B5940F1585E70E0426C5B1\n      1A3E21599C9B41BEBF137EF54D7A7EAE3A3FD3BB7A1DB2A6B3320131AE8EA981\n      A36DC7BD5757EBCF7EA073BC697B40AF20EFFBB2DF8D83AE062CAB15B65EDE12\n      BBB4308CCAC545E7E9E3C204913685D5DE35E431CAA443A48D888980CD2603AA\n      818CC879C1694AE48DB776BFF23DBDDD6D3C7B829C71837E571B2807AD84E786\n      67D35D7BEFD66AFD42CD7CA2123A19771CAD5F4E7FD0DD7DFBCAD2C3D3911E01\n      96F2C092244C19C005173461C81E5C27BB6F0C7554ED23B9138752F2344CFBC3\n      4E69C68D92B84E9D134797DFD95F5FEF42FEE5739A776612C472C9926E800FAC\n      2370C95A16F0C5F3650F1FC677AA31B937BB7474F306EEAD6671263A66B11D47\n      DBFD414B33D6250400AB15422F7CE57C9601DD2AB8E904690C0167605141859A\n      2B67EA758DDB8C69346BCEB3C9A66A9F4ACD8898980FDD836B23DFF0973F3A8F\n      A6002BC619DF8E33B5D7A1E34486ED361A80E4B6467771F70636D3AA20A17B3A\n      A9BF8F048D88EE37F7FF5B260E508F8F56B564D5D7BC08325D4AA9005ECE0833\n      8A284D42A0659325A7CC6DD09C3E12AD78A4617D128352CA2A257FCAD21A4925\n      7772FCB962A254CD742F0D71F2ED387A27E027F5E6DF3A87267365FDA12A3795\n      07889A2EA80A35552B291A0321764E1F39FB6FF1B71F5AB40DCDD128C86FB503\n      0C222F959154038423A10E82E0B1A7697ABF79B0181B0C8CED21D45F21563930\n      A33C93639DA78E02F24CCD7465AC5086A520E86836B6EA16AA42B44885AAB501\n      7C8E95231F559459027E2B62EC503241F9BCEB5AAACA2486987128AD50B3C4F3\n      CC3D9C79A002792B578ECB141B22B7469A6D92B67BF3CDADD91F7DB0FAA34B3E\n      1BBAD944FC97BBB7FED3BB75514E49D192680400C4C504433544F338A8344DFF\n      7717A70D23CF3B52E7F0A08B5466E6D0809C7BD9D9FA17EF181D9C72DA831F14\n      62330A5B39658536ABE15923993241AA1B7111A38568EA0365E96612347CEE22\n      09482AC9AA36BA9E126A877924946B886AAB37010FB90C6CE91C6340B2716AA6\n      1B39EF51CAC5800D042115543724E8BE51D208204E2A76CD61A5D448423CA434\n      D7B856482D8E0076984E240160537E74062821CA03F8DFF0180D6089DB59E7D6\n      A151362BE76A6945392E6A980321C964E2DD10A5F9926CC64911691D37BE9556\n      8ECE6C1F5EA1269B3973044DD3DC027DC655C5863287CA332F0A9304C0C51146\n      7FF5A064BA9117E189B2F3F4F970DE357DAA4E91991AE6479547AC52F1497F57\n      6CAF6AB0108C12C07CF8FC6A29B321FB643287255DFEE0E3D6679E0DD1D0083C\n      2CA3DC24D2F3F19D8DCEDB975C6A68D37578F4AE2782561F5D3C411E7F400A66\n      472642566A3A92599A6000FD6AA5C1A251BDD79092D4B67B9001DF34E10363DD\n      08EE6EFED7FFF5F76F7FFBED2D327933D5461C392C36A9D5EE85AE3FF8B5D3E7\n      3E183343841DD3235AD1C0D67800A21F1A05E2548B88519404A1AE058C257C37\n      127F11E3A9C523F4EAD5195CD52D7676426B16A3B669BE4ECAFFEDA5577FE6E2\n      293B4C6F20F4F55EABB2B0F4B90F7D32B7ED3F7FFECBAF5F79E76FFEECCF3CF6\n      E0FB1617E64178AE760F575BAD9BB7EE7CF7A5EF5FBF741322E3A9F367965796\n      B865BD75EDDAE59BB755B4E4EF555682EE9B99AC38AEBDBABA0BDF334DE5261A\n      67F77B0E9061F024C96C433F7FF61CACA64BEFBC9D4A443901C60ECC7469767A\n      71760673747C71E1871E7AA85AAB3EFFCDAF3D7EF28145ADB27E77F5EAEABDF5\n      0DEFADADCBD30BE547661A477BBB9F3F7EBCD88C86FB99E550A31126C06370A5\n      BD9F3ED53AC043FF6716267F65A636E7C531022D54C04DCB3124012065E39E62\n      CADEE4DACEDEFEBD8AFB67077BE7CAD59F6BD4E71DF4C6A8BBED4546DDFAD9FF\n      FD9FCC3D7B5102C9CA252B888A7F8579F0E09018CFE0A59073C6694215E52920\n      4C103622D5053BDCDFBA6D4E2C554AA5BCB5B677E5D5A90716F5860C0F76B6AF\n      F847CFFD109DADA1F1A800100904642102AA3AA244AAFE1DE534AAE6FBF42FBF\n      EDDFD998FDE8336277F7706D75FEC90B8999E545CC21D7A7C4BBB2877AB2F4F4\n      FBBDBA61FA48DA7916EC8BDE01857BEBD1C18B37F95EBC99FA95A71F9CF99127\n      A406392AD3B4A95C029EC1EAE3CA1021E7B830400440B0242C143AB2F647C5B7\n      2E6D7EEFABDCD4671E3D85CF54C272927587A4EB6391989AC1DAA67873380C87\n      F673B3FAA296D969AE31ED408F5EEB8EB6F7672E4E4434A4B1ADC5468EE38C26\n      05C8109A706CC5778D8D1F7479EAF8941EA4C928118EE16628818428F29CFBB9\n      E4F2ADE1CE8E6FD5EDCAF18A7868CAE107B85934A93DCC6AEDEACCF4D65E77E1\n      6229B7BBF24EB3D5BB71EAFC859D35B17375880AA3C7D17A345AEBF60F0AB205\n      28CFF99C634F2BAB1DB81932482536CC304DF24268E3C99FD38C2D68FAACEAF7\n      8194D6B55C736ADE712724F008BBE2706178BBC9ADDBDBA79F3B577EC44A684F\n      5961EA02286BA6F6F674D98FBD9D435B5AC4B3F7DF1A65873AE09198E8CF3DEA\n      882389DCABEC7F55A4BBC433E255146CC73C48A828401C65CAA7AEE08E42ACD4\n      B2F4AAA9F30C47B180CCEC894C2BC8AC66CC3A909CF29AC1CC58C7D3887E0257\n      2041958B3828B4B78DFEF7DBE8186FFEAD33A8AE06F2405252B94321202364EC\n      BBADF645DF53842B677E1FFFE0E1658B138B631D019D65F02AB8232928428106\n      11D078A40E0EC7937BC7E530E329630AF5986A1C1C7719C2358F1D20D5A921BC\n      759226808E201F922C238C2933529569956FA99A082EE1F55904E1AE4A7054B9\n      754A54536C956B4D46E72025709A03FD13C2C0D451EECE22C787CDD37A69C50A\n      0B806AE021B97462C8611A6DDCBD7E906BDAA94FFD48BAE431A1C9EFF6AFFEF6\n      EBD369C32F644B4A2F4354CB1B46D1544325326E72FF37ABCB739379D696A625\n      8B1A071CE69D0445B637177F6530FAD24D4D3A6DA20F51BC97E48731491354D7\n      E4B4994F5B7A099B88C991BBBFF054C598D2B3308F254040ACC788779CDE658F\n      67765EE409807ECE0C06B720CEB51480C65AA2850B89D7120745BEABEA80958F\n      2DA16A3B1E8443293697F5A2847456950990F47EAE4790E8801F8236051ACD29\n      53CE9F4265C60C240953D33B30A86369079B89B7E5998E563E6A159362243D42\n      741D8255A6FE688806A5F292EA3864DC8CF6F2703B6C2E2C6FAE5E7216DDFAD9\n      0554350AA61E18E82A0A123F4C8B7E982519D6D470F568B3572F35F737B7EAEF\n      7F50BB783CB4A499D8888EBBF9D5F02DD085F0C4B362B42F76EE609A63B332BA\n      1A24DFDA85BBE162DD4FB2D1D9D9C92F7E18CF5451968A3C2C74080C41B7F7BB\n      3F788BEC75DDC9A6744DCDD4BDB56DDCAC3BCF3CD4AE38A6B09DC841D44E4C0B\n      C1152A8A0440381EEB03BF0CABB36445C84C3D111950792AE86BFFF79F7EFDDF\n      FDA119E2B8BCF8C79B833BED96A5175AC54ABCE467A767FEB6632C265940A866\n      DBAE480C895AD44E8B012789CB351F9B5D6E9BAC98CE7D5924CF8FFCAF0CB223\n      330BC5E57BCF9913E6943B5796359AB4CA8DE723F9C6BBD77E72694EEF8587F3\n      0BFFE7BD9BB3C78FFF9D8F7DF6C5B5CDAF7EFB5BFDC47FE2B1C71EBDF0601284\n      AFBCFDE6375E7F7DB735B88F734C09239012221ACF69B91F39701B8199AAFF50\n      930A94D7347C5B5745D32A4C287ECF9A5A95ADA9ED1C35318629D229354494D3\n      84CC851A7488D4D88C711713FCA969C42E19F0F07FFD177EF1426DBEBBB7FFEA\n      DBEF6CACF7BEB37703E1E8C78F2DD50F563F72E1E464A4A537FAC0CAEC399654\n      20DD18C3FDF423ADC141BFF799D9C6AF2F4CAE0C418218E35B1DE7B0DE0A1DC8\n      2230DA089232D5F65BAD2B8EFEE783EE79ADFE3F2E2DD7C9E12BA8FFFACEC0D6\n      CB1FFEBB9F7AF8EF7DDA370D0A4B5E8DB554C721EAE2C6FA4F9DACC0E5147F0D\n      8458CD978F8AF11C93FE5A1C75F5F9939AC4E1A56F63E6EBCB0D6CC4AD4BD734\n      7EAA7AEA51C922AC4E14F5B40001CFA98C49EE09190B43871462E619DADFDE79\n      E53BFACA6C737E71F78DD74BF592FBBE6311447F91DA0547BD6CFF8D3BD58593\n      F6A993A9C598EAE20F86F14E30DA9EC9DDFCBBADE4D59DC2A68313C6CCC7DF2F\n      6A3535A5D7B2B5C056928102F96359061F9932AE2BF70F4841AC28B677BB5F79\n      995D5E2FF44E0538DC83F3A222D51C98AE87BAA1C853CE4CBACF862FAF398BCD\n      E8FD13A68B989502D6E16DE2BFD1C359543DEBC62CA6AAF201163224CAB45033\n      D4639DD868CFD9FC6E2BEFD1981BDD027482C6B9158AF830EC8084B05226807F\n      1A7247F59BE2A61937793691B947CC454B17A1B67BF4E462BBB5E7CE0973AAC8\n      0E1B87BBAB8B478F07237AE7AD039CBA40B177B2607D34DA4DF2ED24CD299D99\n      68AE44FE004214E38000F3D46275C1F0BC7213C9094AE7315BE2E694EE948C0E\n      42AE3BA94D1E81E08CD5BC3E1B6531B9F9FDB659AE1FFFE47436D31B1FF95285\n      2545CA8841622DDAEE2603BF42CBE9266A5D0E48A607B4D73869588F15A253DA\n      FC6A9AECB1C42CB670DCCAF930543BAE0901E1A519D8B6D440ABD8D469097029\n      CF935C7A90B199CEA49835D992CDA66C6A5009B0ED9E738D0FC212C95327CD52\n      4DBFE4F65ED84127B4E6CF9D2D1A7991AAC24D40190584888F7DD2D4C3042C94\n      C4565BA367FF357EFDD16593018F26AA519F29D84C548F9B9E223E8CB24194A9\n      DDCBE27E4BC57D5BA3FB7F147C65CA3746B55B884224E3E1850470145485EA91\n      6590FF2426B90A080C6F99AA5A402AC7078D39E4DF5C08D5285A2823454EA62C\n      6B029326030821AA953FCF4065EB1C163E5083C09A89261F722396716E8B22D1\n      4A38A6092997BC91B8F1E2EDA73EFED9E243366211BA1CDFF88D571BED524071\n      BB40C3186024AF18799352B350A817FC2A3A7EF19CC87B09C06D61ABD9A9A81F\n      15A1C1A6C9BA36FCC337D3EBA9A92DEDE07E27270711EA7B894D8B26A08CA555\n      89651978C8B7262EBAEE11374D13D5D99DE42CC63C347A573DDCE12058A30244\n      956E325B16BE34D4C83D6391E76E41218046D85FF359042B88403C6ABA9690C0\n      9CA1CE91528AD3D807CDC3A5A3A6D9A97BAA4E66C7B707EE008829A10136A640\n      08496A912A4BD868DDEBEE7895995AF58C9B59FDF143D0929CA899B038EFEDB7\n      4D7DCA9E57FBED3AAD1F6C1C14824D3B33BBAB77AA0FD5AC53134877E189E65C\n      B5FD7178A84124DB43124BA41BBD7EC087A22C9D8DF6C1E2A79F2B8E4CC10233\n      505D01A61A3401D99731906B0560CA963CBC53909CF2CAC1EB6DFCDAD0868C31\n      CC434D777FE1C7D3278E6849C6E32CD6646866D52C0EBFF7FAE0D28DC9D2046D\n      36600565BD7EA8A3D2931764B391809095AE264B18DB82293B6696291F07C4C6\n      3B6D6AB74115344B8DA926A03C77100F6E6FFF97DFFC9DED376E5E5C59E15AFD\n      97DFBAB91A610422DA2CCA08FDD6DCE24F7210D491A7D71DCFAE97DD8E16F6FB\n      C2D67196F6F489D2ED38DE8DE2F3D38DE9220AA8F672D77FA7359A6D4C47ADE1\n      4F6426AAF32957DA38DF9898F937B7574D827FCC291D6EED6FCD2D3F7FB07FE4\n      C8911F7BE4F17FF3C2F76E6EAD778211E42A573792D1A81F81A242440D31CD39\n      D5957F0568B842B2F1CE8A527A6AAED9F8D86FBC5583EF177C70AC4C7909DCDC\n      4C752BA9EA33AACC9B001BF17D7108200299DF8417A8B91E4CE1AAA6D825E44F\n      25BE54DD960552453C73EEFCAF7EFA27C4C87FEBF2E5DDF5F6E561ABB5BFF6DC\n      5463454F4FCC57CE95EADAAA570C85D6E0AC0EF48AFA23F4C98DE19DF6C1C7E7\n      9BBF3ED73CD90F0AC953550A170B8002E02F098811E96B9A88C5DAA8FB9A81BE\n      0BCFA613FDC6D289F7B3C19A1DFE497FD445D663178EFDD46FFEF79D937306CE\n      7589813BAB8A38F5C4902AA15317707F48EF18E3B172DB4680B25E9E79BB7A4D\n      C35669B476373EB83E79A45A54CCFEDDD5707F3477E1C3F9C40CCA02AA3C4520\n      232120532C87D59424A997BA9628B25210156FBE7DB076ABF2A9A7F9F58DCEEE\n      D6CCD30F17868CF210D2999E61B9EEED5F599BFDC053B431A15AC22013A7799C\n      B765DA316FB6DB7F7A3D0B79FDA317F8234D3C554DA853305310E94425657901\n      382AD5A391CAE4BB609C69A988AEDDDDFBD6CBC6E1A1EE79F65375FDF8BCE762\n      C76274E817074314C1AA85946B8E36C283CB5BC71F39DB5F668EC8B99B263823\n      3BBCF746AB52D3B493662C7C9A5824D5243C67581D194958A451CB18D477BE77\n      E86DC519B687940D0B1C02291F750143F25C38529F74EA21451B29A4E7BCCAC9\n      B483A6187742C3355C60D58BC74A85ECFB597BF2E814C9CCBDDBBB957ABD549F\n      B8F6DA667408F065B571BA19007F0E07EA941D32395FCC825453B3E43CD0DD86\n      25145AA806000DA12A01AD8916A8316DB84DDE3668336551792E39B25C01A553\n      D4E0F5E6C1DBD9FECDD1ECD3D5E98FD447D9C042B6A4A954870F90F22A68987B\n      7BBB2888DDAC1ADEC87B6B11F019B8CDA56772034FDEFCCA286D19A98E3A24EF\n      E57410A7C3BCEFA1282974D525982356A841AD1A703F800E0AB1AF97EC1AC9A2\n      8696CC733C058982659193CE3E33AB3D98A338F1B41064077FCB3AF8C6967EC6\n      0120448D4C6D452AFE39368B5140A8149C229E8AA8D9D83EBD7CE65FE3371E5B\n      B428AD1A0CB22783B0A248552503AAE47810E6835884480D8F2D448AC6CE81AA\n      83F0FE905E755EA81687AA5DC8B2308AB172986199EAAC5763E6C6166B6A2E85\n      9AC1ABE63A8140230A05C725AAAA3D231340373394EB1A9D2F95A60885D5676B\n      54D7589EA732C9D47C226EDA05936EB7F12045555891F0742457A592996C0205\n      B6EEFDD5ED079A0F163F7F349D8CF56DB9F93FBDA35DC789A9750B320C01E884\n      6D44D38C9488EB8579F485F6C90F3D9D523F25003208E4A69EC7A05253A2B158\n      CBDFE9F6FE62ABBC37DB73B35E5E7472DA0960ED65258E666CBD41A8A3CB8875\n      AC13A47A7E22267E01191A1035818CA5797783F8566A1023C2092091C5CA2919\n      1133A3293296F4D4056E2178A10DEF0D711719B404A2D913BE3645CA479C448F\n      2388CD5C58969A529F2B8B73A628B40CA94C346E08017458D9EF23E6C17A30FC\n      B9833B1BDE81BF78FC283BA9F7AD4DC1622776ED6202583CE4AE74140CF6BAD5\n      A5055CF3016C6958DEDADE7026EBCEC0181E761BCF34D151E0722E3CE9CCF625\n      32D578E5201287035D45246DEF75CABC06DC16CF4EE9CFBE2FAB5AC48F086D12\n      92150C1833BC46E3CAA7302E069BA8B78E14DB291FBEB8615D171A155E90590F\n      5E707EE6C37E8D5861A2BCEB5DB8BB1959BB1B7DFF3533CEDCDA24B21CE187A3\n      60547AFC343EB150C0DAC16541DC8CDA549AB85045CB4C45A4AA2656BBFA635B\n      2335F34463419E9498810EBC57FEF0CF5EFA7FFE722AA31F3A754163FC17DFBD\n      F2CDF58146D4689CB396FEFB2BCB4F86073E1AC4F6AC9135762CF982587FAA6D\n      4D4ECE779DFC2BBB97BC4C3C519DBA50317155DBC7F6D54B073C41B4E1AE11F1\n      B94E82AB74D6068EA07D8F1AFFF6FAAD8766A69F75CC7776F72E57A6EE0CD2B9\n      46ADD92CFDC7AF7DDFCF6502549E3114035750735E7288338D41EC291D84A992\n      84EA641B290780716FAE3216046887A4C3D8FDDE5CE07B10359C33A19EFD986A\n      8EAB2B2182C6C62B3497B99442E3CA0A5FA12210AEB191B002158028999B5C0B\n      521FE9C408E5471F38FFC0B1139D7ECF3B08B6315ABDF5F6FB1CF3FCD1464906\n      1F6A4E1AED74ADE361475B29211B17C0003EBBEE5FDEDDFDF8C2D4AF4D4F9CF7\n      4026E090632962D50A9C6BC056138C469ACE92F086882FA17CDDB2AE6EEE7FAA\n      39FB6BF50A4DBB7F64C86F86C10395F23FFCE7FF28FDF0E30C797055341774DC\n      7B558CDB848B71ADA8C2C2625CAC50A090273C94D4573B5D56DDE0223878F77B\n      E50513D7B01E8BC377D727A64F93A513996D6360D885A6461BE32262524BD5E8\n      09101CBE097A382F1FB63ADF7AB95AB3C86327462FBDEDCED6C94347A5DF53D6\n      948E6626A4786B2B49A9F981F765BA69FA8530238A28F23D7CFB4EF7C5D782C3\n      B8FAD843EE871E8C2B905734208DA6DDF0F2BE4B27D494F21C9E1081A72A4922\n      39669DD1E14B6FF42EDD986E58391EB90D533B63FB3A250EB70D43EE76A2D6C0\n      8627937324DCDD2BDB61E01F7BE8E8504BED58A45618A3A43CAC0EAF0CD5509A\n      B934141148219A7149551D58919398A90EC7523471F84677743BCC7373A08693\n      E0BDFEA09F040193D56AA342ED7098B6417868098DF325D33D375B61034065C9\n      CD1A9D31703DAA34E8566B6B627E7AD2A187770220C88BC7E7D6AEB50E6FC1C3\n      B4F7F2F0204BF6C33831B4AE10DD404EF00C5B36DC1B3F8C35D356B54E72DC22\n      45D414C812245AC294F13309AA763347093587C756CA95091697435C3679BFBC\n      FEFDDDD8C84F7EEE783ADBD7534B3D7EC02C89355C21B99EF7DBBDADED0A76B5\n      3D63FFF290A44E1849ED89DEECD4B14BCF1F4ACF89901811D18D5020655F8EDA\n      B907B8C30BB3CA8D8AC12D55C09916021014D471A962367811D558308DB22632\n      521E8733F9F24797E5E4085E36D0028D54E91B66EB5B3BEC943DFD73E7102842\n      D0921030807F109F58A36AF4A5C0F7772A01089DD3CBA77E0FBFFED8A2CD68DD\n      D440CED222551310910CC22C475A9CB37E2A8700B498703CDEF557166BE33678\n      35A450052726CA891BA8563E36A7A1948E3B079152847996E6921B7AAE8AA769\n      A65696D28B913AF862E3AD2135922E486320A073257751D34B42562CCD2D5949\n      9AE6513C1EE3A8BB4535612DF76C62CCE2840BA9219BC1EAD37C272E1C8A6FC9\n      FCA6ACFED245EF6CE60E68FBB76EE2D7D2C430DB420E432998308C6086D31AAF\n      0FFDD47B66F3CC673E985880B12925E329A241C6120EBF267708EE8BEE9FECD9\n      3FA0F0A8FB69D4C7B4939161247542665DD6248943124163BE48AB8F4F04764F\n      26B99994945122A1F156ECBDE3DBC88C8B145296414AA0DE989DF288E88B4656\n      C9129A389633DC18A5DBB2242A12D8AC9D182B8C4CA14078AEEB2642F5B9584A\n      8400B626197CA15247847323A57900EB8F120BE974480697E256DE9D3932EDCE\n      DAB1D3F59C013C1F7358B245A5A069A189A0938811D356686A01A6BBB453DEE9\n      6F4F1C6D8677E322CC6B1F9A924BBCF02C9CE1C4F609B6E1D9C8384E3A0337D3\n      655A74D677CAE5A9FDEDF6D20F7F207F6039B7743D94992C731A639AC0C3CD01\n      CA25A32212BDBBD2DF61F02043B7F7FC5D731D239E0EAACEEC173E139E9C65A0\n      DFFCA0A045C8E1AAE4FE0BDF60FB3B8D89891431BD30B7F6778CB3F3CDC7CF27\n      19A84B9708BBD06B29B631D20BA5A20AAEFA78185C1AE06FA1C695C077407BE2\n      00E7A5040F5FBDF517FFF2F70F36B79E6AAC3C519DF30AFF8AE4BFF39D37BFEB\n      6520BC3E3537F72BB5EA839E221D7DA21D94AA6F2687F792F62F93A58D5AEDAB\n      7B37F682E18F9E3BF1B45973811A54B47B45F9F0DDCE29C137E4E0ED39F7F37E\n      5CAEDBA5222E4CF32F06C90BFB9D47EA9547EBD6CBBDD66B5A63773F9A71DDC8\n      4EDFB9DE0E911CC51ED2D4C4482E90AE696136B617246A4B4BD9BB2BEBC1F14E\n      E6F8601D808F012FCCD3F7CE083523533D217047F43C89EFF71C504641E1DDDF\n      78B93F1666BCC542F2FBE3AF41108288441C542190A3A048553B93CCB9C1F322\n      5BAE35AA613E53ABD5669A24A65B92DDB8F6CA494A1EBC78B43AEA7DB1DAA05E\n      F88D7E4F73CB3FAA9B3519F7CAFCF35BD19BF7363F3E37FB4F9AF553710ABCC5\n      535BAF194A4992934C15CD91C03031F66EA7F9B5C0F71BB5EFB4DA3811BF76F4\n      E8331CDF94E99FEDEDD835F7A7FFF1CF2DFDF4C7300E894277C1941FE818D08B\n      F7FC4655A99E6AA850F722E3902A6331C832AB66B022BEF11D490FC8C906AC79\n      717D2B6E93FA233F224C7DBC49CB546B3F002BB00B0E9F2982DB0A526DA44993\n      08BEB9B5FAE20BC71EBF1890D4BB766FF2A90BC2564DEEA0A83B543452237AF9\n      9675ECC4E0DC12E8E77A578A926A14E69BBDE84B2F1DDCB93EF3B1C78C1F7E60\n      40E1FE577161E985EA4F0548645A05D2552AC64C46973C0BD97EB7FBD2EB07D7\n      EE9C3CB22C5010B25EE9C1399179D231F5E9BA88BCAC1B88202379C642C447B5\n      8DEF5DE5353C7B615ECDA28B50688E1219554713DD2BDDCAF172DE1C8106E089\n      A9E64BD1F190CD1CA534026EE3A6F5E1A5917F3B12B1392CB4762EBA6130C892\n      C3C8B3DD5A95DBBD51B04B4160703D8C8E18F464DD69C8A2C99D9CE6684E1B92\n      D1FCE2F4C6F6A65EE6D37334DDB73B9DC3F913B5E161BEF176C8507D3B18B651\n      31C8F2A148F653001E3D33F2F7FA0204E240C1C7366228CF75521804EB59EA50\n      5276EC33052B9B46D5368518959DE4E8A989A494CA26D530D97879DBDBE72B1F\n      3EE13E132BCB5803E254557F72458C192C86C1F656D1F6AAA299DF110737D33C\n      28F307DBF3478EBFFBC22649DD200312577402C0C2B427BD014E20D118C4B424\n      76755AD60D1320AC88C6EEC6A6298CA643AB9A37838A06323DEE0F8FC6473F7E\n      5CDA20C713DF4CB070E81BFAE1B7F6F5D3A599BF750ED58135E5488D43528D36\n      6AB83716CAE252ED4B42689AD83EB772E677F10F1E5D7419AB6A4C8D9F2D32AA\n      63C6E9C80B8500A9670D73DCCD8A501D0BA93918109F4C6DD5B171D18DB87FE2\n      0F08C7B806D095C15B638862B5FEC31814202849C67513B4979AB69726683CD4\n      428DFC65209E2195B282915E3004123563D9471D6782604BA38E6B02410A469E\n      AE5394103DAD456C641F092BC758E884C4D6B41832A991B851E2E4E56862F7A5\n      EDCAA72FC8E72C3BE6C3FFED66F8C208D9A5B64449CABC7C6459E9B4A695B113\n      86227E72FFE8DF787F544B0A1271D0B854F9FD825A01899BEB91E066F2DDA0FF\n      671BA57E3325C223453BE3AD5039ED4E18D99C1157096422E93B69F5C96ABAE0\n      11E5226A1799A6EAE2FA85F78EC70306D7283358529AB44138C50608EA798D4E\n      B2808C34E5954C46D703CB73392C927A5C3AE706A6A7DA8325564DEC00EFA234\n      E61121505FA1069E69F0C432EA4BF8C0B90D01D6BB3120BDDC7AB8AC1DE561DA\n      212442264973AE656503DE4003FA2E3B5B892927E8A920C683525EC307FA567F\n      63F6DCDCFEA556B33EA53DD34C2B3EF26D1DDB01EF72E4680225C3A13F1CD652\n      AEBCE3763B85556A6762E5834F672B5389282C90CDAC8A50C0544131DC350B80\n      512371D2BF950EB71D6C16F7B2CE0BABA5913B042C7DF481D24F7E728472DB8F\n      79120A9B8052D6EE6C7A2FBCCCAC0CCDD63569249BDD4E89353EF6A4EE3ACC57\n      5B49C2ACA2C226C21254135C6D1D405E4F951BADC66351A8697B92274A45C5B0\n      D207E2DDDFFE8397BEF2B5FA64E343CD13139DB46BC74D0FBF46E56FED6DAE6F\n      0D7F7E6AE953E5DA841700A06ED4B46F253B2045002FDD20FECF83FEDEC8FBD9\n      F30FAE308CE3A143B3A1A65D8AF5DD9BFB3F6CD5AFECADDD7E70E56F6441CDD2\n      0D99760CF32FF746FB393D41D20716CA5FDE3DB8EECEAD6D0D46BDC3E6E9395D\n      36DEB973B39F84D4D06526003700AFEE0F6351851C637B4375223FF6B157C3AB\n      158B54A715F2BDBE3A342E1F51BA1338236324CD12B5C53246417514A1F8A5D0\n      342D859021EF7D87AA6266343E3256DBE752A120E082FAFFA6A3FFF8534FCF11\n      E3BBDF7EB132DBE46EFDF5F5BDACBB3FC7E5D2030B4764F60B66D549E3E7633F\n      4DF16779ADAEE5BD6AFACBEDE295AB6B1F999DFB954AE54412018E8D0C5AC400\n      8448CD5A404558A08818840FB6137E6D346895E8BB99BC72383AA1B12F2E4C9C\n      34DD0D2F7EB5BFF3C4173FF253FFE897C699912622862CA12ACBD5BE911C5BCC\n      17E37114C5B8970AAB1B43D42C1AC2AAFAC8F757BFEF1C415193CB5ECF7B67B5\n      31F32039FA3ED0A4CA9E8770354A4E401ACB5216735814B11AFB956A52CFD3E8\n      EAA5EEC1DAC26317FB576EDACD0A5F6E006BD463086D9A997A74732FBE7ED87C\n      F6E983A60148331DEA85E6E14178F8D557C2CB77661E5AD09F5B0E267901A933\n      AD615621F0284481C719121B90665435A78973EDB0D57AFEC5F0E070F9A1B3BE\n      378A37EE35CECFC64D085CC22A95C261AA25BA1D661D2F065A2D74EB1AEABEB5\n      DE385FC1272D55D81068A133002DE5B6AAA3BBBE7BDC1C945A5C9D829BEA0455\n      F9ECA86A094C335555E86B781BF5DF1DA0C0E9C5905764611AFD34390C43B7D2\n      D0113FEC1DAEC7412CAA2C8F4A456BA662CF6B93339A49B476F34C3545858B1D\n      83916EB06D9F3098D7DCDFDDAC4C514E2B9BEF46495FF3407561D20A8284A2BD\n      44DE6C7B9D3AB70156954186DAEB537E2AB99A106C4820E240F30B8A0BD335CF\n      9292CBD0846E582863C4AF4D99F5230DAFD2B667F27413DFFD7A545E6E2C7DD1\n      52A351351EA92145CAB193A96602960751777D1BF238DDD55A978BA435914C6F\n      2D1E59DA5F0BDBAD10F8EE28CD5AC304D25C378F472445860EB2DF25A45E7641\n      CF696ABF19504335DBB98535E9B0492B9D40C2CC8BBEE9993F54AD3CD910790F\n      A260C07C221CE36DF3E0C57DEDA43BF50BE7911DAA4EF571F32A51131E40B708\n      65752B72453301089D738B277F07FFE0F16587D08AAAB4871B901050471A4962\n      90A244164627129D1441A622AA1E4C30AAFE8C27DA6388CFB1B99A4C33004236\n      EEAAB86F4583EE9F0608D55008B211F49199E4791826623C9105DE242738005D\n      A8ACEA01AB624E8B39CB5E56C784D8A25233A861E9E16848B184952B93722242\n      732EAD9EC051C307D162A6965DB8859D266E6CE07AE7DD0E3D326B7F769227C8\n      FBD7F7FC6FF489596D4914A5244C3DCBCA2775A382AD208CD2C7D3E5CF9C4B1A\n      03ACE00BC1FD5193400B13527A816361B9B46B6C7CF5AAFB9201809760DC93FA\n      41A8877131E5E219D3AB026913C43372FD7D3A399F42DEA2B0148521B1721AF5\n      AE8EC47EA163081C9A4B96EA29D5720B80699E6B335AC243EE629CB2C1B548DB\n      B774C2B35A689FB5623BBA4F55382BB8F2B383B5070C232D9832B84B54FF0A7C\n      D858814D871DDE8A0A9FCF9EAAA313790BEF6804F10C92B01DE7AABC8D164299\n      BDA6A2BDE6CF4F9E88E7F729C7BCAFF96B516C64F66275FBEAD6CAC58BF4B41E\n      6B3D969768CE216730C83251160C06611835B12DD7874584E0EEA1A5D9A9C7DF\n      17978123232394B95107694750A8BCB691A1B6B7456FD8B9A621DF4ADDFC7BBB\n      DDD7F68DDCEA9D2CAF7CFE93D9CAFC10C94A2C59EC439211B11F7EE315F3DEBA\n      B6E08413AEB7E7E982B83FF460BC32214269871A73261288E4DCE2AA220CBE28\n      2355AE6638C3E5ABD1ABEA105A9D1D832AC09C68FE4B6FFFE56FFC4E34F4CE9C\n      387E56BAD630EB59E174CFDF9DA8FD5E18BEF9DD5BFFF3F49147B5F280A37D97\n      5CF1B7E0F24FE98D53C2FD667C6F90D98F4E1C3B9D4B9274434B00D3081CE76B\n      ABDB3CA64F58CDEBDB1BAD874E7EC23F740870387E0FD3970E02DDAA4EA5ED13\n      4BB52FDFD9B9A2CFBCBBDFD9EF1FCECED7A9CFEF750E121D12889AE608C4733C\n      13617C825008369E4B5B8C6BCA0AA1365418421A55877FCA6E21CBDD920B3A3C\n      1F5BFD964B6508AB344F9224354D33CD8146AA0378659BCF202FA9C9430A5ED5\n      461DC8E5F74A6F94BE82B015855E00EECA132BC73EFCD8E340B0B7D657DF59BB\n      1994CA234FA65E07A374FEE8C405D3F8B1247F6872E2CD210079FE23A5A94933\n      EC39DEFF32D05FB8BCF19195A33FABF15379ECC173E55875F1C7008534C31262\n      2321A643465B9976330E37C868D3765EDDF06AD438C7E2E526E7B5EA7E77046B\n      FA339FFBF8FB7FE5B319E464534F45AAB44EA11A6DD8D8A9EAAF9BEBC73708AE\n      9F65B98EF51025AB9BBA138A6622F028DED945012A2F3D981AD394B958A88E64\n      8234353E0BC7398B80ACE354B5F10992B3243CF8DE8BAC4EABF333C9BB6BFA03\n      8B78D28A85F262D3E0AEC5C5C60FAE9A4669F2C9C77A2604342DA58CE491FFEA\n      5BDB3F786DF6E173A50BF3A93922362CAC0695D308AB8267A40A28F5CCF4001A\n      122C41A0EA37D6875F7F7110B4163EF868301CEE5EBDB1786A81CF5A4936C8EA\n      4DD728610D787B42F6E2A2358C2C00618DBC9EA31B87A5274AD9115984160BAC\n      C81D4892DA7B15EF5EE09CB3BC529724C8CA0C55868F2801BDAB3473A64E9D62\n      825BB4FF7A170D9C28D7BB695A18C6304BF7463E366C9D1A61D0E964612BAC49\n      9299CEC836F4593EDF4873D7DA9F3965D9A56ABCEFCFCE4E1FECDFC22B56DD58\n      D8DB5A6746D49C5ADAB8EA85FB384CF15062BF902921FB825C6F0F2F4316C3DC\n      522758EA68458D4705199C6725CAE09F2C0E01E6CD8AB3444C1B9139C36A0013\n      2E02AEEB13F355E3849FCD1D9A79F3E0EBA8DD191CFDC28C7D067E54A40C0219\n      243D126AC3CF929278078762A7554FEA873F88C3AD66C0779DAA5548ABDB532D\n      37FD281BC4852F68378D7C9C27450E22A0EE58B661A4610A9C5855916AF009B1\n      959185AA3D65171594C0BB078DB8F9B145B48265E433243C4395AB5B37EAEDAF\n      6DCA153E098AD089A5E2192A8F02FB12EA684F821C244AFA17E3AAD1B30A085F\n      7FEA98599032212EB02F58626AF80A8040A6FA6073AD1B8AC3540C0BCC8A5CE3\n      9C00F2E563EB19E52443F3F1205FF80237655C3E83B331E91BFB49C0B2CD942A\n      CCD5CE10D3F471BD4C060941D7B4820110C67196A5980432857899B5AC45A64D\n      690CB412A6A2522FF9A341114765D34D13035E6A5445E52449A6FD444F8DCC72\n      480919A9B022EAD4C2EDB03740537FF33848CCE8FF5AEF7EA5C578A58B799416\n      71EC997A5137AC326671344A1FB3173FB794D60EE1C6B0D4848F91B09C828A55\n      4D5320984D4ACCF6FE36FD0F49D4852CAAC7D83E04D0F0F2B285679C046E3DCF\n      4804E87F5296DE6FCA2260A9A380B0C87986C3D570742BB4739748550B937149\n      18327399CD216BD62E8C94B82068F4C1F550DEC126D24423B61F70622356F63A\n      12A2072822BC912A1E54F3CDB09AF5244C01C0E6E6F56C130DEE7944F0C6D169\n      722CC9703F2D468C189C96D5786419A93E66E5016BC072F4BBFECAB1E349E980\n      16161B697B37769B8B539E21F777768F7FF8593A29323CA0D450FB53488DD62E\n      A2CC3B6C81E6AF4A23BEDD31B4F246124D3FF3A4766431013A27308D3261D540\n      E753912004A4192058E4F15E30BCCD44647B6EF6C256EB5A5BDA56E3733F6C5D\n      3C1BB996541E9290432307CBF4C69DE0D5B7AA26271683C4BFE7FB338F5DD08F\n      CE0759CE7919273AB7EB614E346AC1EA43EF190740E602324054173157C5DDB0\n      AC025E98008487E9CDDFF94F3FF8F6776BB6FD4873A9E117459605CC6B8CC22B\n      A5F2BF3CE8A5377BBF3D7D7456E27B13DA9BA8C74478C2283590130E939B93DE\n      39313707778B805CF672E551E36CB3ECEDDDFD1A2F37426DBDDD4A8ECD7D82FA\n      3AE426D378D38BAEF9A85EAAD4D3C3F909FBD52DEF0D5CFB66679738FCCCE49C\n      95F156E2BF72F7664C15D429AF987197D138DD0B65248AC6CDE3E3F1ECAEA573\n      858AEA15A552298A63C3B6A22084B0EA777B3393535EE05B8ED3EFF74BD5F2D0\n      1F41B07AC1B8F4828EC1A3B83FB5E13DB7CEF7FE4AC74A30C746810C84579696\n      3EF181A72D2FEAF73A9BFD7687711EA05BBBAB1B4977BE643D576B3C28C2A74F\n      2E1DEE74B677FC85D9A923D5A29475FEB868FCC93BB7CECF2D7F1E938789F098\n      EC43782B20845C5D28F71A84626C9A517BCB2AEF09B91776779AA5570EE26664\n      7D66E9E8DBFD37EE59C134AE2D2754D3B2C77EEE833FF6777FBE60521A14D204\n      05669026BA92ADE8BDA914633D08FF66CAD23B27FBADACDF237325C93DDEDF6E\n      6FAE958F9D42C6A44E260B560202A4A6BA15868AA822143C00294900A0202F02\n      7A743B1B2F3E3FFFE4C92E8AAD5B5DE79113C206188D242EDC8CD18DE1EAE55B\n      4B1F7A3A712C5668B0A032B8AE7B87DBDFF8727DA1E23E71AAA30B4BC0FAD411\n      9B44AC09345295E13250694E64F68156EA5946EF6C0EFEEADBC5B057FEE8C399\n      25DB6F5D6E56EAEC58CDB773341C85730B35646848558BE39D047586C20A40CE\n      042F87D65E643EE7F8CD1E0BEACCB7A2521FE3C45A2F8FD623E7823DAAF6F410\n      723AB071A03B9443D8438E8784CD789A49C3333BAFB6E5812E8433CA32C1693F\n      8A575BFD5014AE5331594A34B21318832CE69624449F668D1991B95ADB5D66F3\n      A7A67756EF1E5B39D63EE844D85B5A3AD16BEF0DBA7B2B274E76F6C5E12D3FF3\n      583FCE86790A5FFBDC5EF3931B2C7320F7A84334A9EC530802F8B111B6408B0A\n      65A8C23560CBA42493096312B465B518981AA1855DAA68930F26D94ADBB2A7E2\n      CBF6EAE5ADC547A7DD6735487C42D733A98C8529AC4EE6226AA942F6D5D58667\n      8FAEE0EE4D238D47B0B035B3E4277954E04122865931CA8A96EFA946E5223738\n      B135067C09235A366C0D9679166BA898D0CD69CB686AD822E948B6F9697DE283\n      0BA1137289A84C7DB57965BB6BD3875FBE8B8F6ACD9F7FA0B0957F73A1FC3E95\n      A767AE063C289F18A2BAEC81695BD83EBB78E25F292004455326B4A433503652\n      4B19274592925819180044B705EAE6428EB768886AFC17634B35AA3659B37C0C\n      7CAABF7E9C03D0F81B4859605212A78902C2F1D441A66B18983D646AD0834037\n      65166549986491446A087A21661C779E69B31AADE8CACEAEDE28890C90CB770D\n      4BB558F8F00EC439CAE442906920183483009464424FA86BA7213AB816D73F33\n      6F371AF2BFEDECFCC51A2DAA436E42F6CEE35067B8A499158645DC891EA92DFC\n      2448CB7DD06B2457C5D58060C0C775B51FC285303299A08AE47F526CBC76AB12\n      5B94B89D947622B59F53770A1727B69A508CA2D9ACFE816A6676B134A9B024B0\n      5B5C240769F772E00E1D8ED48878D5F7468081C6D14C569A2F632D29AA821BC6\n      E84E1A5D4E35C08929E93EE0FA2C5693B608D2013679969A7106A10ECB001918\n      5003FB0673E25D63EBCD7E8994668ED6F2A3DAA8BCEBFAC098B8480A61A97343\n      2483718522E8A5D2CECE7EA9AC5767CA19EAB2B49A75E5CEFAE6CAE9B39DD65E\n      50C6F34F5F205A067A5530C01AC80300A0591E27FE6ECBA526E9A5C3F52EA24E\n      5872A73FF274EADA70B5C04CB23C239A0B3C894860E68654E550220F56E36843\n      03C5BF4EBDAF6FB55BBEF5C8D1A9CFFFF80808B26E94332D222234487DD0CDBE\n      FA6DBFB55D3A318BBBD170A76D3C71565C5CE239D33233674EA2954D56251929\n      944B1F56559004674A4C50A01719302A13D9CA47457A06B681D1FDD7D7BFF66F\n      FEA025FCB3B3CBE76303F9719B46340B277DFA0D66FEA3B5DB1FAE2FFC7AE198\n      B177A5C10E13EF04E10D04ACC50091E6598306299B390AB3A15F844EA59AE5A4\n      17790193C498DCDD0F87A3EEF24AE324F139B383427BB3353CD49C82E5E7EAA4\n      81E4A543F95DADF2EFAFBF71F2F8CADFB8F02C4FC280933F7AF16BF70E3B68DC\n      E43A1E6B37DEC3047E841924AC304F8187DA3AAF38AEA559699C8834AF561BE3\n      53F614C460B552DDDD589B9A981CF9A153AD1C760E1B13CDCEA023091E458154\n      B37FC65531F7C7A28DFB2F947F8544EF19965165DAA48D3D1B74D3FAC4079E39\n      596A6CAFAFF581B258551EC42FEE5EDF883B7399FE85D9C5255B3E3457A17BFD\n      EB3BBDD15CE3C949FBC2FEF68BFADCBFBB7D875BE52F58CED31A81681C020D4B\n      0BB507091C836409C11132CC7C7060BB8789680FBAF7AAF4A6E5C4B7FDFFE1C4\n      5373F5E26BED4BB7875D8769869E345DF4C9FFEE27DEF7C5CF081B7E3C83C007\n      DEA436FEC683EBC71279DC5302F91F685F3C4C0F76AD929D56398EBAF9BDEB31\n      498DD3A7D3C42D9309818D9CAAD6115418148010F9B916C065B394E66A943846\n      ABF7DA6F7EBFF1DCF9B5FE6EBD872B27E705CF7C532444D47D465E5B3F0CFD89\n      4F7CD89749C953D3AE556DF6975EEED0CEE2074E01AAF99026EC0AEDC35BD691\n      5D53FA1B7E153332AA17C1BE6D9BE995EB075FFEA65BD2EC8B47B4D9DAC19BEF\n      1848564EAD44A30E295B89C34975CA86CC9A833449D05E54B4FAB91990C21EBC\n      10D981D49EA50367CF8EE68867054E8B9154BBED781BA979D11A957B4EAAD989\n      96A94377F8646ACEA052108C7A59E266EEE81D3F5A05226945795A101223D20A\n      B35186344B9516591CDFEE0C3B9E2FA9013264CE72E6686EF3B4688AA38F4F1F\n      1C5EB378AD6C2F1CDCBB3973729EC974FBEEEAE4E23CD12AB77FB0898786C0BA\n      57485802235E3A94C58DC463E3BE1DB5610D74580A4B0DD5207A2EA9AA324196\n      6D020FE579AF6E01F0B33AE98310D6721780A27AC42F3F84B466291F383B6FEF\n      3BD2767E1C22A99A8D1D3981CB31C302EA9C53A01759727890DEE99A0795BD77\n      13DC53E7E56AD420D387A91C6132CC852FF3813FD20C83216480202B20B823D5\n      5CA4C003604C946D365BB19B58038AC458DCE23B731F9C37CED83E4B4CC919CA\n      46A62F72BDBA39B3F3A55BDA09ABF9B72F146608F252DE6F4342CA3B1D721751\n      25D1CA30610C8467168FFF2BFCDA934B3A0021A0B6C99509922E3480A224C641\n      46254822AD876937CFA3444DE755356CAABFF6FED6A8719FFC8AFBBE6BE3FA37\n      80C47CEC676398A690CA1840D5856B3C563D19023E0DD7347865944084A35460\n      1FC991501961D672560C7392A02ABC2BCF4A15BD645BA3EE10EE05B7841881C8\n      B2B425CE56F2C24C41DD42E863AED442619282B0FE3B043FCA1A674E14DF6E6F\n      FEF1352AAB1EB7C33C2BA2D0A2BAABBBAE96CA682FBD589BF9E985B002744CA7\n      A9250D78CE8264853A23149215AE48135CCEC9B5D2F6F397F50DE4607728E013\n      B241240C8396A96828D355195482F2C39372FA102085E6264D552F4911A0E195\n      84EF982626A91E4B02100C0C261C4C85F539583F096916C4E4E90E89DE4D443F\n      36E6B07BB6ECA308814A0682CB55398004E5AC8C63007E3425C510CB7AE9C68D\n      7D5A38CBA7960B3B0AF59ED74C9B61998420B4F35CEDC85365E89A27ACD0530F\n      775A83D9E333991632E6D160A1BDDE4A336F66FEF8FEEA5AF9C945E3743DCF15\n      9F8E585FD74BD4AB103488865EDA0D4AB49C6D77C351E6A7A474EE6CE97DE763\n      AE1AC22810132434AA090CFA047169A4A92A1BCD87B79360D5301CF1CAE0F06B\n      1BA8D698F8E91FD2578E67064D93D4519B5E9819845CBDDAFBEAD79BF395A86C\n      0CF786D5DA84FEF4F95183D1405A45252B9CDC6982D43481D90067E2AAB41EB2\n      3B96AA1E4035D4ABF97852232C865CA331637BB8F63B7F78E78DB7F7F3E0A923\n      A797E1E20AD1AB1048028E6FFE513FFEADCB977EF1E1D33F9524A0493781BE18\n      662392A100260801AC15CC1B32B53DA2A97D479995CD304DAB71C205BB6D36BE\n      7A302C45BDCFCD99201288591EF6E5FA41B85B725BA4FBCC52C5DDEF7D7B3F7F\n      796AEA3F5FBBF6F4D9131F597C8C8AA0B438F3DAEEEA7F79E1053F4A29553EDE\n      F75D3601AD0CA6956AA59E3F04A26969A6CD8D8A5D8E43B80E01A10E01A23A6E\n      09AE96CB87DBDB8D4A3556A37670A7DF6BCC0010F6125892B8C884E80EFAE35A\n      4BA4A67F80F054BD35EA0BFEEB2214548C7DBC958A93E766E63EF6D09354A2F5\n      D65E9CD3DEFEE6F7DA1B99512C46FC27E68F4C95F1E92A9D0BB2B7F6FA776BCE\n      879BEEE39B6BD7C9CCBFEAB4B730FA42ADFC113535A5F0280325A80AFAB14849\n      9A10E4AB3D80C8E75A2FC107817F9B0F37A79D6B370F3E6A9EFEC70FBD3F4D3A\n      DFF1B65F6EDD660DFA8894CE64EDC7FFE12F4E3FF74446B3200E2B965B64F7FD\n      F1C60461AC68D51C079278FB1B408D9DC93A42BDE1E64D31EC3696E642B7A2B3\n      399ADA826688A9E67E2275AA769CFD54F395997BAA2705D1752CAE5F11776EF1\n      C78EDD69AFCFD9534ED3153409011A4851EA66AD172F378F9D481F581C115A8F\n      29457AEFD60DEF95EF4F3C7B164D100ECB4A376369D1ACC4680519A05AF8F8CE\n      CA8449AB13F96B375BAFBCDAD40BE703A77A0D9CAFEF4757EF4E9D5EA0D36506\n      C916D6CD5C4D2F5555B0165121337190C876172086674EF76551929AF64438D4\n      B7AD68458B9DC03D0040C2D79D6C5F6A178D9ED52A25A699F294C66AB9E77AAE\n      C4133C373C28A2525112B7C4F0AA6A2B5686632247CC08A9D58A523F4E6091E1\n      540C646695ED0269C3613EA16B53456C41DC4DE0A547CB49BEDED9F6CF1E7B76\n      EFCE2D3A994DD6AA9DF57DB885D5D9D9F5B70ED32D35DD7684F2ED7ED4857B52\n      E0ED3848453EDE86226AFA41A10EE3F098B1286854AD0B0C162C156D5DD6AABA\n      3D572A66F4C2C838842873FCA5474AC67937E36CF78D967E59639F9313276712\n      927303D4458C751B9675AAEB6A187C14F5AEEC963AF6FED59E5C378069794992\n      31AB93140165FD22F1440850E2E806CE61C1514A95DF5B8E24C09789350B17F5\n      326B38A421B91353C18260AEBFF0B105519799F26EE4206E7CD303C956D99CDE\n      FFF26D76CC98F8DBE79195085084638F2A0E3A90227558019F4915CB140A08AD\n      D30B27FF257EF5C9255360075357E70553A70DA649689692405D4B24690FB12E\n      8079A1C9FB9C4E0D72CA15BA32C601B4C73D5E899A2D21D5E443C69204C864C1\n      555537AC7F5577053430CED5D40A105F9C69CA6011B23687DC85438201698228\n      9CE4FAB26E34B16C381A539E4ED9DCF444BF3584946A57223CC045EC9239D33A\n      8E8991480D8546CCF5C2FAFF887A0F70CBB2B33A70E7136FBEEFDEFB62D5AB1C\n      BA3AAA5BDDAD6E05D44A080122088381218C8DB1C1603C0EE300FE00631BCCCC\n      980F0FC21E92E11B10C922B4004B6A49DDA883D4A1AABBBABA2BBCAA97C3CDE1\n      E4B3F73EF3EF5BC2F37D52A9D47A7AEFDD73F6FED75A7BFFFF5A4C0085448E15\n      5C2D4D160E8FBFE75DF8A5C1ADDF7AC5295A130A8F2441C1AC22AA65BF51E261\n      1E6EE8072B0B3F786A5C0E4B0128399AD92920294B601DAAD0D2A02B7CC981C5\n      20BD38FD8BCDE8B97EA570804E06D4EB018322ACEA914506353409ACC8BFD4A2\n      17E10D02E83902286811516245D7307A13BB0CC756A400C9B45DB068BC183657\n      1B08FED912EC3042877E7225097647F632295DA884261B0F0B6E9206CD202165\n      D298482500EF6E5AC1C3F2E8C651A467ED0B956201A5540632B43C54CE17E021\n      223701EC036AAD313C941404EC747300BCB37AFAF844CD7CAB4B87276EBE7173\n      F5F4024FACE920AC7EFC7CB4083C1F96A84CDC01500C67BAACD5E170D0B763E2\n      CFC8E8D6A1D75A1E67A8F6D863BCD35442A038A79CC7BC70CC45286C7ACCB493\n      25DAE269367853CB3D1B3B83BFDA4B5F9874DEFB2EF9898BB9A87989A9273150\n      706459FBA3BD2F7D4EA8EE42C59AEC0FF0CA4AF9F107545920BB487220FB3546\n      DAB9F280F25BC6FBC174C8A40C480E147561FCB4E61367E64CC1A5239A961563\n      5F7CF3B55FFDDD3B5B1B392E9E5839BD3C96B0000E507A14E19BCC7EEE7638D9\n      1FFDE0FDC72FE54775D023CA460E87B2A8526C723879A6CBC6512E4D9126DCB3\n      AC9953C425B610475E5FFD852AFFBBA3FE136DF1536438AA5413A732DB49B311\n      7BD3439BD5D947562B8B5BD34FED8E3FB3BEF2CC95B73F78FCC4B75CF8902392\n      D8635FD8B8F6A72FBE10E7F3D81628237328846A023C687165697FD8AD20E131\n      CBE29627BC2C4C617D839E6182037384FF43C9716414DA946166CDD224D1923B\n      40A3F26912C62A836FD61DF4CC9195E988A126C59098B117AC8D2310604AF237\n      E1B70537851436D587CE3F78E1C4A937EF6C5CDDDD0FA64713ACA1BE1D97F443\n      27CE9451F848CDBA20D80BBB835B96F3C18AFDF8E4607F5AFF3919BD82B36FAF\n      94BE41A2724103D30A6ECE348000E52C4D802B214E481EA559409C3B79BECB86\n      8352F6DA4194CE9C8F754EFDD0B9FB5A887DF1E0EDCFA46F3E01CFA162AF3EF5\n      CE0FFCE8F75BABAD1CA9B9D128BE7B98ABE9DC010083F2E1C564371CEC392B17\n      E0C189D9B5EEE6ABFEE2925DAE23F864E27888CA0E1B321DE7A88691C3A0C0E0\n      596207F0C478040AC32242156F5C611BB7D1BDAB3747DBC7564E8932BC6B2046\n      89499CDB1F8DDEDC5EB9EF9DAA628D7CE11321766787CFBD642DC48D4B17D262\n      488DB12749F30A2E1F57C207AD60CEDD11D114C87F2C5F383A78F60B7E59379F\n      388DCA78361CEC5FBB51AFFA0BCB4D90959252509D25B7552CD850DF73120B5D\n      E0FD54757B544C51E61EBDC87CEEFAF78F53B1C3C3759A9523679741E1BF5A42\n      7D411FE65DEBA09A7A16485B1699611A097F8DB9E650A28DB8293CBA29A6AF46\n      C5946B8D9224CA350DB17D1427F17C266D1ACB4A73A1ECA06838C863DA12A50E\n      C82F9A06F562F1C14AA51A6FBCB175E1D47B26A3D95E7AE5CCFA5A31C147D37E\n      ED58471EB2FE2BD3385433AC063937223607F2AC13959BE34346A8410022E061\n      509280FE51122A9C19A7C3CC45871C374A7665C92F56ECCCCFA54D7D00CCF649\n      D27CAA9CAF8AF195C4FB2CEF7EE468FD1D27B565525DE7C3A34063ED443089A4\n      93697A98A9B726C3DBA3EC75279D69EAD8BDB0E8A5A8275528B2713606615536\n      B33AA0FF04A2760C6ADBF408902A2D952929FBB26C6595942EE27A4CA7D6A3AC\n      F4849D7809324DECB6201900A12EACF24673FFCFDFA6A7ECF6DFBDDF9C264958\n      CF068F4018C23631A7EBF0588DF5A7328130DE85B533BF88AF7CDD593B2F3C20\n      5D6C1E9BC434AB9A71283283F5C06294F5959A643CC1B6999707E8323E5C9910\n      A6661BEB3463C06D66678D1781E90B3367A5994964352963F0E208005E0EECC0\n      56261ED1E43CC15F6C4A0135CD901EEC3AAD2732F238038C59A478C1E3654064\n      9C95EBA53C29E269C4DB6936CB79E853DFF6CF73D90C35881373B307DA116B58\n      FC82C53BF2500F4F3DF551F2F2F0CEFFFBB240F57EC14168032CD7A95DF75D8E\n      A324EA668F596BDF795F501ADAA663942B33BC8C8DE7373573FD325702A49D4C\n      C34A6EBF668FFEFBA07C8080114D30DB452C2C509B48C03249656491EA52473C\n      39CB5040324CCDD9B5220CCD6EABF8725193BE62512A0A898C582B5ACA5F292B\n      37735A44FB4A479CDEA1E3D7FBA2C9C5392B15C9DC148D8136054901644DE250\n      D3298322DEAD8C37801348EFB4D49D28C9734FD74D84943DF58D6F15496D1309\n      2DCC45B09761D3B0946EF45CAF8E4E38474E6F61C2F5A137DA1D2F3E70F2E8F6\n      4DD2692EBCEFDC544C2DD8F30946B6599A85C4228866A389A378B4D10D8EA2D6\n      C90B49B5EADD7729772C78BE3433F7C1802548E4C81868DA5A978021D17C3F8C\n      AF80E8B477F1E0335B296D2C7DE7370D973C8FD96C1421CF0984F225CAFEC7B3\n      F9C60D67D99B0C7ACC2E951EBB2F3C5E351A3EF773E4525162C8875A4BB98F14\n      BEABA4E68E5CD8B83C9A242F6146688A91C6DEB4702A3AED3EFDD9CFFCD7CF74\n      8FC6F737D9938E6DA7D52F26FCB9EEC1059DFD19715EB979E76FD98BDF71AEE1\n      A4C0B885C3AA0393D200345D1B573207DE51024514512743CC18C5BB11AD4A94\n      584783C6A70EA2CFCBCD1FBCB0F8BDD9EC48088C6A1B7DDCB5FDCDE9EEF915EF\n      9C2D8E8E92DFDEECBE75AAF3CC9B6FAD55EAEF5F7F4FA92C8FA6E3E7DF7AFD28\n      9A496DCCF04CD1478087BA6C1B8B8BF6F2527F3A8255DEAEB739A616005FA2AA\n      C64F1C3EA786070BFA86192E894D39653C963930C854A68AA0511C8EE2A955F2\n      66699CE7591804599694850F58D2CD036C46844D97D5BCBF14982110DDBB0EDC\n      BAE6BA0B2B4BBD83FD71945B50E01CF8A0BA9CA0F72DAF961CF244C5FE001757\n      B68F9E23E4C976F3A341703BB17E2DE9BF8CD37788F20791B76CA4BCCE4D9028\n      6CD64C9ACE057811CE08A867AA0244AEE9649FE539A53B41F695E13057E8DB96\n      D6FFC93DEF6D11FEC58D57AF26D78E554B4BEBED077FE0E38BEF7F9C7047A689\n      32ED83949AD0066AD836CD75164E0E0755B74D6A751D6DC6832B0A85E5C5E339\n      AC4B5251A85E508FE329D07690D346FC2AE395AC494C508A73738652601D6C5E\n      15A33D67C13BEC1F544E9D705C40B2424AD0D96470F30E4951E5C4695C2E6704\n      A480EE7DF9453299551E6D1BEB2592663AE58585ED76E42E28E65B11818A92DA\n      52E409BBB9F3F297FFB455F157EE3D0E12010109BEBE77188C6B0F1C07596C83\n      3EA62A41A2EEB4B2B61011280428D693E2604C0F22F868AAB0FB2FC40D5611F7\n      C5337BDF09DB7C6605E5718673FEB6607D665F7246EEC0CB2C9ED3944B5C302B\n      83FF9819E37B94480B48BEC70E2B93AB111E709EB0244F8ED24920FD28754749\n      1E726381D67116822CDD9F1ED61C76A154EB50374E93993BABDC4796CF7A8737\n      BB4DB142AB7C63E7CE6ABB51B2C4F6D15EA9B558C96B5B2FEE4C4754639E283D\n      90D6C6389E8A59AA556A482E375DCE4AF9966359224ED230498C8B3A66496A72\n      6EA0EC8392A952FB38676D9A7B96B9AA657EB8F20D15FAB01BDED2FE67EC1B8D\n      ED7BBEE1A25A8DA322B490CF954016CAE1DD134C158829916E4CE26B43EB7932\n      DC8F79A9310A64374CB7D2A8CF8B50E56E811AA61B051429CB6250862465C6A6\n      B346FC1A43F552DA62A811D996671DD50E5A1F58B0D60848190C8AD0248C5B91\n      9B68854A376A7B7F7ECBBAE835FFCE7DD28672CA4DC61FE07C6615A603D5D8CA\n      90B9D5111416E25D3C76FA17F0EBEF3B0B1CD983EA2A0A61DA4C55512F4C2ED9\n      4838210061D053D92CB2636AEEEE8C714C9281B8B36C508354CA0CBE2565E616\n      80506E6E1233C350D334B58001336B1ACC72A530D05FDBC94C9E486E8C66082A\n      53400E1C2B93CE99283506FE6FD136C52D829A366D50E4316D556C429CB037D5\n      1DF81E8A0C0DE32D5F74B215404569692346B5A59033B7E4184DB746C1E9777F\n      945E0BB6FEE015A66B03C2406BD2246B10046B4510A55516BEB738F6F51753A7\n      4B8962B96322379871BF23E6BC861A13097355A5A6D57E6DAF133C9DE6CF8F6A\n      859820B98979A8494BC76DCBCCF746DC6A5417C487F3140D98F1BEF661C32250\n      33876AF22AAECC7C4292C8C9418300BED1B2B457FDA289AC6651B8B9CA90E87B\n      83170E81E7D41F6A04D6147E35C7AACCEBA156BC403487F786C66CFFAD19E896\n      DAC912590CA262C872E1AA3A2882C40E1D0545054933A3894C5C2DA3C0BCF26E\n      26BB5179AD2997937DDC5B1DAF8CF6028F19DBCCC3E8D07D70D53BDD8E64689B\n      4C0F0039D09231B135E9A7B3A3BE57D84737F6DBD5E55E246B0F3DC0D78F9B93\n      066DDAE7F1BC4723B11201EC9CD8392A0962A1C9ADA97C43E884BC30E8BED85F\n      FA968FEB47CE02187BA99AC9DCAD80F60882B7AEC56FBED181CA1E07BD3C6CBF\n      FB51DCAA629B22A164D6A4A44109C7849B845AC41116C57CD8C77446CEA7AFA1\n      D2C9C235ED97A49BE9AA660D3BEABFF9EBBFF7C5DF7E8987F27D27E89ACD5F3B\n      B07F7B73B4F4E099EF5E59FAC5EEE4853FF9C2CFAE9DBEC847DA4AAD1084AFBB\n      67CB80A9FA149511CD1C5223A962734F7BC23358636C5261518F377EEFC0FEBD\n      1B379E6A35BEE77CAD31EBCEA00E749DB794FF175E12853B3FBE72BC364AFE32\n      50BF3B9EEDFBE28DDD5DC5B0D0354A22D8A2C0D10581CD6A3AEE4A76099B564F\n      D3051A4551BDD94863D07878A9B3647A3BB5C939F3E03566D278A7CF33AF91F1\n      0D3047868A4285D71665456EEE60C33C99E6092A5B53991A17D804F8CAC81C33\n      0ABA3D1B20FDB59E13D3880D74D75C1298910C264492A7D484C899195F3BCF12\n      D0D59E584CF4838D66B3513E9F851FB7FDDD71F06759FC507BF1DBD2FC664E3E\n      1D1F5ED6E9A276DE45AB4BF0CE4D2F19ACAF9CC16F44B1944C6776E024B077BB\n      28BF95470313FB50DA51EA2B7D50CD7AB5409F38FFC0379DB8D49EC84F065F5A\n      94F9F19ABBF6F1272FFCC0DFA2F00B2B1315610EBA52A2F282D9B0D3825E77C7\n      B3DB9EB5846814765F8CE5410D1E112D6BEA17049EA10780498A786EC9C60A9C\n      2923B719D11946A199A7042ECDD8F8E86D4F0F184EC787FBD6B9932E2C4B6333\n      002F070FAE6FD896EB1C5B437EB548151D4FB75E79BED92CD9F734292C63738B\n      03EACF425E2BB14071FA56CEA00A28168BC3A383DFF9B3C9C9E0F4439734D720\n      8AF1F674E785AB2BEFB894ADB89A04A6AFDFCC413A4E7921A892D2C431CD12A2\n      ABBB3DB10F7218E4131F7F79BC802BE88162E8ED97831A90CFA0120654FA9B36\n      D9CBEC336E5C8E580EDB90C6F0390B0B787981022894110DE7C5DCE3E385E056\n      4C873CD989814BF7513A4BDD28F58F66E150070E638B5673248B5B71CFB5D2B3\n      8ED3297C873B01E979A7C2130FB6E5240FBBC9C299D6C1CEB428D2A5E38DADDB\n      3BA870579AAB8737FBDD1B914DCAC0B466D83D9C12A846499A87E66351133AAC\n      35881EE394A68D534A61928F689A67B6E5609240B92CE9D20A71161D094FCD27\n      56A6C7AD0F7AAD8F2D81CC1E7E6A70D0ED5EF8C405FDB815E891234B42722432\n      130638D74CE690698CA6970FC55F8593ED14EAE824D4A324D94CE30382809E96\n      30A99BA64CD8FB340F61739810254D7595B8755AD4ED7089F216AA8EF130B92F\n      5D7CEFA271EF2289B103029093E5AC52187BCE37BCAD3FBDB9F0E4A2F77DE773\n      3CD19CC922750B07C58EE6A1F10B0014BA1B6D8EFD3910FE3C7EF5C993AE2ACA\n      16761D6C994B881CD5740A8038127640131C0D741EC456842D69DA64CCE03CE8\n      3A0EF861E6A4CCD51A9AD3776452E260374AD3103CBFB830D97573B7A87CDE03\n      9E80068FCD8138B32D7B7EEB9FC2BF158E53392A124BD0158B3748D1B0709D03\n      91C06EDD67CC1D1F0CF266E27A4EB20BF2A5289DB3C9099930738C00FA09DB85\n      416F20E1497E63BB77EADE27D9406CFEFE4B42D686440C40B0C6699DE08A5378\n      8C00D0271F559D278E25F61154212E414F5173178CE706880A6B9C1BEF0158D7\n      EECCC96AF235D6FFC39D5A2C52AA0E621CA6B64BD36619EAA78E25B541367D0C\n      6B3A2252715DCE920CB39CCEECC157A5D317A098229168CB61A058AD997DCCB3\n      561CD6CC15205721D8AC3C7BF5B0BB73B4F6F0C9C41D6B1497BC063054E2A809\n      E90A2ABC6C61F0DA5190C6F57B5AEE9AA38A4C4F42414D327D6AFABBE1010BCA\n      13C14163FB2915A68724C882B722223CFF8C48AC0098943FAD1F6EEDB4974FAB\n      FE24F465E3A9B37125E388D0D0446449E36AA23815C5FE201E05A0116707937A\n      E7C49DEEF0C4D7BD5F55EB66984399FA7A375D19781437475BCCD4579D67C186\n      4C76BC49BCFBF475CF3E56FB5FBE33B4338A01588DF335942EF7607AF8977F55\n      A90044C4FDA3FDCA8317F9BDA78111E1420071D0B4457505DEA0B9DE32FD100C\n      99FBD4B995E8DCBDDD947963D42060C199591B0622BBE46D6F7EEE673E79F0FC\n      DE2AD60FAC39776CFF17BEBC79EFA57B7FF0F107A783E087DE783178E1C6EF5F\n      7AB7DBBB36AB147C4A9C846F34C9AEA516A7B895616D630790DBB1012B2C6E85\n      2E75515A2AB2CB8EFD0FAF6FC611FB95330F3D84C6B7AC81E3BA7CDFFBAAB67E\n      6EF78DB38BF9CFAF9FF7BAE9AF8EA69FA6D6DBFB07B934D76631C8594305730B\n      08599ACDAFEA8A566D0133605FA9E338711056FC1270B83AF6166B0BF0170B9B\n      1602A0934962460B8C209CB75212E36581536A4E56E089807CE1A69BA448A0F0\n      D3629445E3686AA0713A337CA1E4DDE86ECF0D6BF0DD56353341017B1A889471\n      5202ADA4EAAC94CBBC0B5CD9449114CBAD85AA5225A4EF5D5B69EF6C7D78A11E\n      30F6B9EEE864B9FC21574C42F274DABF22533FC3E7A95731291F08A85CC3129C\n      A4B053808AC88C21994D6C7CC0D5519A266931E4F61D07DFE81FAE399565CF8F\n      A3D107D6CF7F57E9F4E7F05BFD8D1BED8A683E7AF1919FF8217B6DC9A4A6983B\n      6C052B7F667CB7341F76A7C1A4B6B046B09D47BB83EE57EB8B65219A05AB2BE2\n      22C03373AD60F2DCEEBAF368D86386343033D38422733F23CD24D7E8F0AD320F\n      493619F5BAA5FBCE99730E36BF60976AB2B1EDD66A7C71B1E06E9115B27B38D9\n      BFBDB0B89035729E9BDCC41C6A93F099D5C4BC9E66943BAEF1CD1CF56F3DF397\n      228AD7DE7F32B3711A4EFC9C8FBF7A3D8EE5D2E3F74B01226A8655563041CB0D\n      566A4676E64E4D77B066037D386007B1820AAEC5E4CB4153B9E8513AB2F74A41\n      5D84F6CC99C442370ECBE99D40AC5BB2A908E86449227847C85866201242954C\n      E077E520F9981537833B190DE9647B548C894D6A66924DA1512E8FC218F8689D\n      3AA1549B095479B96C8B256DAD546A091A94DAE9C9FB3BC422DBB76E55563B56\n      E6DCDCBE76F6819379373FB8D35FB9740AA06DE7D9432BF6FA2A9D112B9A896D\n      318AE224CE8B5403CD66665CA530CDE4C2CC81426595A969F6373D974A251CF1\n      1A2DB799D5F14160A06A6103495627C313DFB12E3AADBD2FEEC8A777BCF777AA\n      DF7B6E56F4FD8C31250AE0F53447F35928B3FC0B27DA3CCAFFA43FBB1A94496B\n      3449C758EF257157D1581750F47DA082854C95E90E6084C750FD68DEE07E9DE1\n      1A4FDB8C97193FD4070B1F5EF4EEF55334412C272463B901C2A8949A09BF2F8B\n      9DBFB87DEC5B4FD14F1C83656BFA7E586AC1678A6C0081BF01C27958342A61EF\n      C2B1533F8F5F79E2A45F00EF44B60DA5C86465A22649411D0DB81319CBEF51A1\n      82D48901384C809309C486ED47EF668E6194C15332065066BD526699F929999B\n      290BD3E5A718B780A8265249AD33A566716C1E84E06C9EC694194F7A924A39D3\n      A9A0A8456947E09A05FF220E2E9C86E7F995DE4E377047EDC54EB4930069B1D7\n      B9739E19BF1664ACA7B0699503710EE2BBD8B8315A5A3A6B91DAD61FBC6C2546\n      1176E1C565B84255CD551EBCE154C8EF94CBEF5C4D594F83802D5C737B89CC1E\n      C3DA84A8CDB3520D6873112A4AC5B0DEFFEFDDF8CAA0E279D3198E63809CAC5C\n      4ACB0A109328DF773F468817A23CA3D233263A24E3893F7E2D63BBC811384011\n      3C538780981ED82B9E7BBA5C34336941ADB3ADC4D1BB6AFFE5ADE66A872F6745\n      29E4852713AB70A0C2F66D65675BD6643758B85043EB12BE1605859759405803\n      E0C816A03F4D994D456C5358306E2A7C644931CD466F0ECBCBED625906D9B4CE\n      5BC12E1A0EB657D7CF1EDDDCF3CF76EC7777026B5C1635D297A0209292A9B964\n      AC8BA33E7C9CD9CEC4A5FE58D2F2F98BF6FA0965A6A285F1C72C4C279126F09E\n      2C1365621C86924CF5F278CF8FC2E0F2CEF04AFFD8377D42AF2FC72024F22866\n      5E895A62308B2FBF21760F28915BC31D7DBC71ECB10773610BAB5C1801CF0AD2\n      C0C49D0FC7991D06406862783529E613BD737C30BA50CFE39EA82C946B12DE82\n      67AF3CFD1FFECBE460D852C543672EFCE6D51BC9897BFEC183EF397E73F71629\n      7EE0D94F9FB44AFF6A61AD7CB03985B29681E8A3FB42F73DE6A4B40D820B6085\n      817CC3F52C5DA476CC68E1D89A15FF6DB4FF337BC36F3C73F267646D65DADF3B\n      53B127C9EB01FB5477F8D2E8E05F3E79E69B6D6B7314FEC7ADEE1BF6C25B3B7B\n      B0B48150741697A1B6EF1EECCDD3C7E081719DC99556C7414C46B1C3ED244D5D\n      D795855E607ECD2F63A3B2C85D8326D81AE653DEB5C12FE68DA6F3E15E743716\n      7B2EEF0C2B008DA854AAF2C974624E16D32C4F63A75A7EE37083DEDDCDF35145\n      056289981B3813CE90E52DBB74CFC933A3FEF0DAD16E4E80F0148F1C3B9BE5E1\n      E1E8E84367CF2C6EED3CDAA9E5BEF7E29D430FA9274FB4AB63F19769EF0D09AB\n      1BADF865A2321D67AD421C2B977D66DAE7617700F04CE2B8B07860D3FD241CC6\n      E958F06EC5DEE8F7AB123F7ECF85EDBD5B1DD085CB174B6DFBE5AB5F112E699F\n      3DF6E83FF801EFF17B22A27DE0D0719E739639164A02D43DB4FD3275CB80F593\n      C3D7993D76AB35AC17906815E68218CD8F8ED13C40DC74CA0210CE2D06FE7F20\n      943965840C0FDFAEF219C96693F1B074FF451AE600B3E6942988C71BDBFECA0A\n      6DB57205EC9E46FD43D08DEE4225250362263EE1E7D8A6AB9654715136A93850\n      73E278F8FC8BBD1B57CE7DFDE31A87110A6DDBD5370F0EAEDC3EF68EFB74CB95\n      725CC8501B972ECFAA2F69BB2A696899D1994C93093E1CA18340F14C2A2B782E\n      2CA7367BB73575F6DD4959246EE04C12AE1ADD72B431B58E7BAA91E30C8A0810\n      0DA051CC36330219A09029942080546AE5B578B750B1096318BD3E6E67ABD344\n      1D5AC904E1C3941D005CC6012CF1313C09DBAE736B15E125072859EA558B53F7\n      766847DEEADDAECCDCF6F2D937DE7ABED4B48E37EEDDBBB6CDD600C42AA397E3\n      F1B558B92426D66840B6E83449A06AE3697EB7D90BAB3C8382E870C188B9FF9A\n      8F02E05C00039436B22AC47789AEB9A865B17A2A6A8E73C0B7563ED659FCBA33\n      836050FDD9C33BEBF9897FF1BEC01A7971064B3C354EB173037A0010003513D6\n      14E59F9DECFED9EDD6AC9164F4A848FAA99CC62446146427140D582CB1248048\n      1613B9CE31CA2B0E6F525645A8CA7186C7AA23979E5AD31D58B5A17059968476\n      E1105C1F5B230195E40B62FF0B3BC7BEFF1CFDC6A68A5280DE5C8442531CBB05\n      4FD0DDAD63E41A7C2E0FBB170D10BEF6EE5325444A4657490A8B8F156C619E79\n      D9274EC8244E860084B13D310EBA003ED490CF627EA008DF0C1BE35043F53099\n      07D70B44CD0521312EF92640079E6A142505A5A93479868085E62B4D6E01C086\n      E98CE7C681112708687551CBE592C3CB0EA908F8A2D4AAC2EE6876770E07A4BB\n      726C490F009313DE21DE799EB9B1996384DD0F02C72E8041028E766F6BE06995\n      726BF34F2F97C246AF207BD830F512C99B25ED178C4FADFCEF456BF71DCBC9C0\n      5C1B140E9B1FBF4962FC5C4165514313356C311BC711496C2898AFA98D3FB9DE\n      CA2A3CB4B2A2D2CD61D5650D92708D725EE21F525E8B64D9AC481932869B9264\n      767CAD409BCAA72CD421B22D07F61719B045AB74A1AE3A266BDA045227859797\n      7ACFEED9C82BDFC793D201CBE16394254D9C82A5DBC1DEED41E7D48A759C457C\n      64A691536A030469994AC5984590CE405611636E04EF4C315B283FDE9F26F1B8\n      71AA539823EB1CA4DEE8B531AEF0925FDADADE3EF1A187B39334A6D312F5C958\n      6A9747967139C4C38C77276A968FB606C26B465E79F189F72A6E23C44133CF87\n      A04D4556C05B239132AA6D66159338DB349EC55BA3DDCFBF595DBFA7F2D4FBCD\n      9DB06DA56A3663763BC6EAEDDBA357BE521356BCB71BAF56BCA71E50B6F0ED06\n      6803D87BB6F1512BC39A2FBE361407F807E4930246CEFB1FC9DC9A99CEE7E44C\n      9B2443AE5923697AF5379F7EEEB73E9D059353172E6D6C05BD507FE07DEFBB47\n      2CB09E7AE6F6E55F7EE5F31FB8E7CC0773DC9E0663A48726924A1CC4B1767CA2\n      68091E8B8A5DD88C022F2279064A4F82A7EDD65FD3F0172FBF917AF4EF9FBFFF\n      9B67510D8A4BC59FF4833F60F8D7EE6CBDC7E13F7DFE44054F3FABE5FFB33DDD\n      291A6FEFEF6548B73BD58F3CFAD8EB37B7AEBEF5568CE41CD58C925D5E588437\n      88C2D4179656DA761DA88B25CB29DBC6B889409593A6CAC3EE302799D424712A\n      0367F35979E3503DEF8E146CCE2D0BF3650A0A149ECCA677BBDCA671C87CFBC6\n      E11D35372DBDDB276334A1695895773D5939E38D4603FEE1E8A817535955ECA9\n      330F8EF2F1D5BD1B1F3E75EA646F7CA1E913DFBF7EE7683CE9DFF7E0897BC7DE\n      6783DEEB99F1F76A346A411AE2245FD4D61265CB350F7E03102E59A85F47B345\n      EA95B8BB934737B3E9D402547336C6A383DEE4DB1FBAFF14289AC36D5A151F6F\n      ACBF19ED1FD170A9D678ECBBBEADFE5D1FECA9B0A94C376268C29930198C30CD\n      45B50A2B2B1AEEA6F95E6DC1CE12222A67505E3221CC800E26CB777E666E9E4B\n      6EFC264C3F235425038426F4145639E393A31B567E6401F1980CC5B9532CD6C8\n      E4DE68D49FF66FDEAE9E3E41173B2823342B86BD5DCAD272D9962C80E7A80B4E\n      AC1273EA543948D9D2487299DFBCD57FF64B6B97D68A15972441649996E9C94B\n      372A201C2FAD87C5647ED51529A87D5E5D5417135A6264CA126D4C4F508CF626\n      456F988BB85056F85C2A26C87B5F79EA1F38235F644EEC8609D0E89E1B6ECCFC\n      636559CF0161B09A37C5E5D8CA81C5E426BD0ADE36CA321470ED98A8D34958AE\n      540FBEB4DFD85DC8B262DF098714F5A57B3B8C6932A999F3143BE6BED0E21823\n      0D9A5002FF7F79EAFE657536EBF17EF5AAF04F1D9B0E777B77B64F9F797C340B\n      0EA7D78F9F5ED5637FE3B95D4FB919B60EB3E2C8043BA89CF3699A4ED3CC9CF9\n      410121C462266368EE1466B6642FEFCB1C7445A9223C60688E5D74985892EE82\n      ED0E71B7FC88BFF61DA7466BD3DAFF367D5DED9CFFB7DF4A57349EF68BCC18C9\n      4311A3C6FD83602D8A22569598BC45B67FFD4AF52AE5BCBCA38348D12C109272\n      ED02EE65B34C82B8764C6268A13240655976709D8886B22C4BF5D94EF3915AED\n      5253959290C59663C14F0110C0B832B07A1EF58AFF61ED3C73FBC48F9EA71F29\n      CB00349C9F5913A8293CF1A0BEDEE59026D9CB40B34B9D7B0C10BEFAEE935093\n      4AC204353005D255B3163C51584CD40DE68A50E741624F0B730E6378E8BCDFC6\n      E86713124BCD50053C26CC930C56A7E9AA30FF000AB4319A31DA4A9A53089D99\n      C56BFA2180E3810464C68803CF67B391197224CAA5785588A6851DAE7D01942D\n      112551AD2FF40FBA3D74B0BCB6EC24DEE4604A6A857FDE4E4B213C5766EA062E\n      6C8D84661CA93D7F3A4C1716DABBCFDCAC4C1B3D856FAB34C88A1A2F9A7E5641\n      8E9FD6937F3C5A5CEEC8620AFA0ADEAE49CE52853144A366E8854B7338273901\n      099DCD671E5964753FDB475F9195D892DC3D4C28FCC00A1F7333505047EF4BAB\n      C7EC5406CA38219BDE13E3ABB649A36B91673AEE520DEA1759091FB345BB725F\n      537522E3C79B5B6996D44869F67CA8BBA4F24E67E45D7770495397712136C9E0\n      ED03D224EEBDF033932253250A1CD964CF18D71900B85C48912B31E5F0BF602F\n      B2279C1131686D5EDBF64F15CD13B562EC620C346A387A63DA5A3F79B4BFC397\n      9CFABBCEC806C8FC8CC3C70202EC38C0AB6D78D9E340EC4ED241988568AA45FD\n      9EFBC4DA7AC13D63948E855931C61CFA6E5A00CB29084F46655747B7C9B83B7E\n      65331BC8958F7E24AA542829C1030418B780456C6EF59FFBEB16C2D1B09F9458\n      FD917B74A786400A60DB9043D1D0D467B484E7E652F3593863233D1FE7BD3B16\n      C78AAF053300B498B1266497AD74126D6D3CF79F3EB5FDB9B7D6CA4DDDA8BFB0\n      D5FDC0E31F68D9DEE76EBCF9ECCECEC1EE418944DF77F1FCE9FE44A43A70DDAD\n      3018507DA0F204D669CEA1986B8F74526C09DEC1F9258ADBD2DB6A2CFCD26CF3\n      8FAEEF7EA45AFDFB2BABA7E8D861C44A2B7F5DA85F1FF65EE9F67FFA814BDF26\n      F20C87BFAFD17FDD9E5C19299917AE218349AD52EA85599AA47747FC2C900FAE\n      CB99B06C4B2699673BF0EEAA8E2FD3BCE6F836E5E6CCF76B6964C6BC23498171\n      C14E344E31C6C2B728E61EE3461432CE01D5CC640414B61CC83F0E6566463819\n      0AB2B860786FBC1FA69971EE85DF06CA2632B94E0E6080D97BA6DB08F61C3697\n      F624A37241DB1F39F7D084445FD9B8FC5867F9CC3838532FD7ABB5839DDE667F\n      BF75EFEA53B3CAB3D3FE952C9AE8BCBE509BC521EC2D33F23A9E5C5A5DB28119\n      E7548EB267E8609597D6453DD0FA9A9A1C808221D684165777F79F6C74BEB772\n      4C4E8E5EAA0EBF3B6DF73BE2CDBC57C6EC9DDFFCD1F51FFFDBC32284B28F2D36\n      A5120F433FC8D0828B1D167481A50CEA0DD03150392A18B70A6CAE7A60E10000\n      12650344CD8F066233D6F53F81B0084D8E0094105D8C0EAFE7E38DCE42399E0C\n      F1E9755B52399F66C6FD59EFC6CDCAD993B4D3615021E3BCDBDBC222AB571CA9\n      2758F39CBA8553B17099197F44A0FBCACEE2CD673EEF90B07371458B047E2C28\n      97607B307E7D73EDF4C9E2C2D234EEC2BB344E9396CD2A9DC25D302603C504F6\n      7381CD9809DE0D8A7E37B526447BF1F34AED45B5F79527D5811B9444EE244E98\n      E0B43C74A6B7A6E5B5BAAEE6C607A12019BC7B13D560C64AE1ED935C0025CF49\n      606CBC22676F6FB8B4BC92DFCCD0654966B44BD301C1A3540CC2D4E5D94219D4\n      3EE9675C6662D5154D01EF29D149DA3A59668FE84965265EB367F570B1B2327C\n      F548D45DB66CEFDCBABDD45E14357FE74A9743D5C16ED70D0FC62C452A4664A6\n      D4288E3313B74E384102649169FCFA5AF4DEB808A5A41E714AC6D627670C2D62\n      EB94552D8324A179560FDA1F6FDBDF5AB57E51BFF8DA978FFFC8D777DE7D1CE5\n      5D94A55A17719E820E7381842273C0352D0DBDA8A9FF702FF9D4B6454A07A69F\n      92D199035F14D979A0A369063F8C0A33AB97F1027B1C953CBD40EDBA2C6B1E8F\n      DBFB2BEF6BB305513832A02123B6458489DDD1D6A434720B5FFF85BDFBFCD6F1\n      7F7412BFDF9563DBCAAAB93328A03E679582A666E26F7E6F37BF6077897B71ED\n      D42FE057DEB55E42B8649BA302C3D840B0358D750319723FE405CBC64885B13D\n      0618CB73F34824283A09AFCB640E99DC5D9315035B3188E777888216FFD3F962\n      9E50683A7ECC3C7F91E6C62727CBF35419BB2473DD05CA5299AB70C68A326767\n      2AE59221CC89CB49912796272ACDF6F0A83724BDD662D32B2AA3CD113CC6C6FD\n      95C09B144271D3C84AB589E8C8103C93C3FAC1F6A8DDEE745FDC2B8DAB6344AE\n      C7612449DBE3353B2A13A7499666FFE2B0CAEB501B55B9904871C53830112673\n      D39F42456E999222A006C534F7E274C64A946F785BBFB1D7081C49F534F54C54\n      86DD67F64CA44DF578563FE9A708D6CFDCCD1C135794F51E9DBC3CB06366CE73\n      9031764A450840587F475B2D0626A734B3421954B82D2FB3E47A5A7B27A0D81D\n      4B394C9698B4A7AF4C509AD51F2CA72B12B6A397D95032B5C8620B882E7733D3\n      7A272D0D4ADFCA7D8C3D783382F1EC3A1B76A70B0FFB8998FAD902658DC1CE75\n      148B4675716BFBFAE2BB4FB18B8D8840F111344F7491C6B0CE59D561D6EC60DB\n      DF9C4C7B13E2D413BFDE7CE811ED5630B28C0103D4A7393327F3204AA41259F8\n      196599DE2FC5DB78F360FBE58DF63BDFC5CEAD4B5888B9672A96501E148C97BE\n      AC0E77168B62904CEDC72F586B2B0C6AB9E72588581AB4603DB36A50ADB99EFB\n      0F997482BBCD8F64EEC0424DFACDBC9A19EBA93403A6143AACA266D34F3FFDCC\n      27FFB2BF5B744A8D60365EB9FFA1A2B5FEAB7FFC07CF1FED74790164E1137EF9\n      7BD696FD381AC8E23AA020425395A5D43A8AB3DC766669D06A54EC28B7915592\n      93C7AACE057FF135497EFACEF509927F6FE1F453F96CA99D624AEBD3CA7FE0EA\n      F3576F741AF59FB8EFD42372789444BF1BD3FFEBD6DE81E29756D68B5970ABB7\n      131965C7808D29133A897C6A2FB516B1F1F435A749405CB354964BA5344D9739\n      ACEBF9911331F92CB1CAE6B601866C93B9E4A677E7CD91C91B84FACEA03602FF\n      D7AA009DCCA1489A7C3833EB8D549426A02326E9781206DCF7C6D1AC3F9B09CB\n      9C1B6BE38F85E7C73DF3C1FBF974363CF8B6B23F7CE681C4D15F78F38507AA8D\n      D5C1F4EC42E3747B71B633787BBC9F9D697DCBCC7B359CBD9E875D95759A2089\n      F3DC16C6C874F7E091D3EB160120C4F6A4781E7781D8B678B9949103141FDA3A\n      036547F9AB7B7B6B19FADF574186E4CF7B87EF9AF264B57C393C82D7FAC0C79E\n      7AF027BE1FD6358F00358B10C4407F5AA15651B1B370904413CBA2B603D59C62\n      0640E817462843318C0D0F520229CF180798F04EA58DE0E6C8F81E46A60A2906\n      1F713AB83D3BB8B6B2D24C46030042ABE0505B8C97C7249EDCBCE59E3EAECA25\n      BB7081800F463B9867F5B293A57D33086B5732ABE229782F3C64DA0C8EDDB8B5\n      FFFACB8BF72D922A42C164665B256D1FBDF4368EE5C203E72736B0A9DCCB22A6\n      B5B47DD65CCE691DB8874306854AE725A4C03BD3A27F90B81328DAC90B2AD898\n      2CBCBB1C34666E5EE6999D88598AB272E00CAF0FABCB4D5283C2189A2E3F784C\n      12B8697E37EF9C0206314B1B9A3413BA74E7ADC35AA5531795F18BFB6EDF8D02\n      36B6C424913863024867191DCD86BBC32C4F9DBAE7343C552954057152CE6AEF\n      71C35A80EFF03DB9797AE921BC4576A35BED7B6A93DD14E5ACBA66C7DD78F825\n      E4E3C6D4E9ED067E2CF3512667480F63E3AE09AC8E6805A2D0052523B33C939C\n      0BE0E2A9C482309B12902E8CF20E128B489718AAFBE5500ED923F8D88F9D67B7\n      565FF8B5DF5978E2E153DFF1882ECD884E8B08785C04506069DB58B23B6AE01C\n      79F682FB5231FAD92FD3C89A95589E1476E04A22263C1EE6B3694E2739A626CD\n      5D96B85DB758C9C96AC4AA66A5800CD50351E73D2D44CC383E5494C278DE8B79\n      1E120B4A330B6AE567DDC1CDE1C20F778A27B81E94ECACAABC518E52F80B6076\n      3137003669E4A6AE39D8B90B844FAC97112E833A006E24917039AAEB98E8A28B\n      CBB1AD713C453A4CBD99696B93783EA0CF8C0DAB394CA4E6CA03E7C61591E673\n      636F6CDB20AD67B319AC5F61C265CC2049264D78AF9C4757C8BB1724001D5C28\n      60DF8899DCE5346EBBCE8A2D7C58FE76C10144B42416AD34162683E108F79BCB\n      0DA7288D37C6003795B32E3EA6231458D8E2005EF0C1DC4C0BEC8F1B3B57F757\n      3AABFD57BB02785841B795E1214D0B04486015B8EDAD4CFEF5A11B3650AAAC36\n      0FF2A1472B0838334F731E412DE569C9586371A09C884E3D8493C81A3A613BFC\n      8C1ABF7050F5DD59C818A9A4A427EC00F85A7C6FB474EF620E5F6FA6505922B5\n      EB54D47E31FC6A1F049BB1D6828F43BD0005B46335DED140C7329305998A5CA4\n      166CEC8D52FFF9AE7F0947C7BB9EA83AD3C6E8D668BC3F38767A811C63118F0B\n      6A0155B34C2F156C7C9E8154D0CAC434992E09336961CC7A6DAB48D9D6953BEB\n      A7CF2B37926565FA220377FFEDBDE5D32BD36148BD42DC5347EB9584300F39A0\n      B5F33C48A923784324321A1C8AB70EFB9390D4DAA5D317EC53671476745C7078\n      C31C44A0996B67DAD0F4CC4D78EE67B94AF041A9BFA15EBAAECACBF43D8FA7A0\n      84A0F8C047D2D22C8937AFA69B1B561E1E8D776B0F9E15A78F25C2B509FC5CE0\n      97405E4A84D614142045E709B4F3EBB1BBDD385007089B5B8F60736558CCC552\n      9C13DB8DEDC4DFD9D8FAA94FBEF56A783954924C1F595DEF9C7AD74FFDE99FBF\n      7670E7C9F555A1ECCFCD7A3FE9369FF0F8969EDE90723B5121C759902CF2C6F5\n      C9F4B0E3A679D28E95B6AC31266D22DFCF8B0BB5852F06F97FBE7973C5ADFDAF\n      8B27DE21878B0B8965D940BC7FA4620597EF7CE8C4B10F1DB757D4743765FFF6\n      46F7F7BAA39653FBF0BD0FBE79B0F9C2F60632A94B06B70A33C980AAC23DDEE8\n      D839F60807C2211CFB6832A4654F5BA294A2B2ED9A9C4E40975C9A7307CE3013\n      699E11369F9E9847C011A98C2A84D74A8CF831DDD7715A2BFBE12C30E7549C19\n      EBEDB93F7324C3A36E1764DD61BF1BA92C4645A25576174BE727CB646EBE969A\n      F635B25CF8DF78F1918362FAF9375FBEE4BBF74209D5FAD1F5D374A777797A78\n      E754E3FBA6CEF534BD56245BD178AD0404DFDA2DF26BA3DE5AA97CDCB127E3DE\n      B9B553A29BDEC9BA61DDCB357207A95F297531EC2D1A15FC2B83233BCCFEF5E9\n      87EF0FD31E1954B2041D6BBD363D4A5D76E2FD8F7EF0277F44BA8C25C61921E7\n      85849A8D8CA3F774D6B33D2E1C6BCE85E04F5B9B5B17A87CE69CD264F76AD345\n      65F2063000EEFCD809D6A401C218991909D36B94CDF6BAB7BFBAB6D20A864764\n      FDB82B1C73B198E52C2B665B5BB85AF28F9DD0938458F660B49F25FDC5A59606\n      4D950AED3632A7862326300FCDD57C3878E64B154F93FB9BA99AF8B364ECBBE5\n      837CF6F24D7F79915C5C497080F2D0CA12E3DA5CAEEA6A5B92322F3C2C811CE4\n      393656376C67ACFA3BA93D66ACC2DF760E5F36C7777A459214F11488718280ED\n      C6D6E8EDA157A9F016D0ED99B92782B560AC048D9C30A125665AD4866A9A9318\n      403AEF3BD36EDC596F0F6F6CCA2BAA161DDB0FF3C84232011E2F431EF5B2519E\n      505E34E1DBF81EAE15599390008F3A4F56BD130C4D937030AA3BCBD8AA1D1DDC\n      74CBF035B5CD3BDBED4EC321E5C3CB1379806AC2BBAD71AA8B00E3EDD1B8078A\n      D01C5B6807D6ADE372636C96CF4521BC02135306A8AB01C285F0AD4AAB600D9A\n      945D5D86529CE9A83D5DFFB177BAE74FBEFD4B7F840BFFEC0F7F74DA49A03C59\n      B0EF74042B9466B0B24116CA808F946BD76E78F1FFF172787D8A6A3EE8462B64\n      C2F27B320890EE2712E8BF329D9DB96758122959498581CE280D69B7FA7EDBBF\n      C7C4D46106944051E21258423831FFBD8171200E7FE30800A1F1CFCF8D5BFB4E\n      D4B29292B447406558E21A177073FF8C0C700270118F3A97D64EFE3C7EE3DD27\n      4A98F9B609420590140E55C65B5AE33EF503106C0608A3D899CD334429C2E6EE\n      08B8A6910C869801FDD2F3D9994C9AA3AD5C70591461181A431973B80CAAD18A\n      61079B0352038AA6B3609E4CA3058FA0A649E5987637D914B443695960133DCF\n      8B224BB0A0D5566BDC1F4EE9B8BDBA006A69726B0ADFC539C1D9E9221111539C\n      436D65803F4059991B94861B6327F366B74211FA5141BB66CCB1A852E4511057\n      796B796DF61387D6A039DA1D358EB9A402E86599E34C16491A60E08579D90C42\n      D289C9DBCB804802A48CA9F6E357F9E0995E3516798A41AF67F06AADB44892F8\n      6CBEFAC06A6E87B057091240A56067E3A19EBC3273C62ED612BE52303F46296E\n      F3DA23757ACC645DA34C980C709D91FD4AFF2BBDBC31AD3FC06191B0CD4AEF66\n      57B4F3E67920A3DAF4AD2366F240A03400422061A6BA0C834C051524A9656482\n      5C69A9DA702B907ADA5AEF68ECA43AB4ABEAF08D6E3958B24E59FDBD3BF5734B\n      E26453379C1003F9B1A04640CDCD807E50614758ED8D465FBDEC2DAD8E2DB7FD\n      D03B812953E682E8348E79B0C82CA84985303407856E62836286DF2B0239F876\n      76E7C8BEF4587CF66210ABBAE2D4B28A2289F777A6CF7FA9C34438E98EABC5C2\n      BB1E4885EDD5DA4A512EADB92588A778DD36C29A98523DEFD8BDEB4C6B96A72A\n      602BCCEFB0B1B9B5070E298BDC11169DE13F7C7AE3579E7971536E7AEAECBA7B\n      6CF1FC2FFFD5F597B7EF7CCBB9950745EBC641FA5FE25BFFAE73FC741EDCC826\n      6F14A80F7296F37C9632258616BB120F6063A3FEB8596FBE4AD2EA70F6CFEBD5\n      77AC9FF8E4E1DE1FED1C3D6AB5FEF6F2F163EAF0F4A259DBE3BEFA04D5176EF7\n      7FE0E4F1FB3AC6EBE07222FEE94BD75EC9D4C395C58F3CF0E09FDD78F5B5EEFE\n      FC44D4FCEA20DB5CCB76A9586BB6E159D56C3F8B922089467168E60F1872B86B\n      33E10BDB0024A615DF8F03D34086E66D74F0888D3FE9DCC09E980E7220148076\n      459EE78E65CB2432F734981A5B0046A22C4974465D3A198E6D61455138188F32\n      5204E60855DD75F29C0FA3983F41CB27142F49F75B2F3EDAF5E49F5E79FEA152\n      E93461FDF1E8BDC74F9E9BA92F8FF75F3ED7FCE1D0BE31996D503542F912E26E\n      5AECB9FCABB371B364350A340B66E78EAF47B77ABE571C719471EEE420148CFF\n      294D7462F92FE4E36E6FF023CBE7BF03FBE5788278DC5D702ECB09C8CADAC5E3\n      DFFEEFFF49D6F4193055280E383117DCB98A76FB9A0BAFE6C2E39E3F436B7EC9\n      6AD26C8CDBA019A781F292C39FC60A17B629905D73674C01E5BEA6088D028075\n      DCDFBFF1D26AAB341D0CD0E262B9D100E26DB2A3A48ABA3D5893D6C2A2415546\n      87E3C374D25DECC0520D696223DE504ECD442C9825A7D5C1D6F6B3CF9C7EE46C\n      B488A40C4A814C2A6572793F7A63ABF2F03D72CD07EEE8A4B17100A71C971AAA\n      D254D8159928701FB64A06220BAAF1CE400D76949851EAA11B6CE7A5ADC57BDB\n      D67957E7E6272604CA74EAE6D6E0E68433A7BC5A966422E773A41C5E38C87F25\n      94B14CCC84B1352292A65089E8B0D2BF33A99C7499930FBE3024576B8856FA38\n      34E3DE9AF6F5742447E5C2A990768444AA924A91B45C963AB362499D78B893D9\n      47D666651A8EABE717A6BBA3E0285E3CDDE88D8EC8D06BAD9CEC1EDD9EBE395D\n      999CD8ABA8DE6436D5786446BA55529895444D109060042B53BC4D87B9CC78CE\n      400B66B28840109550A551B0AA1302312849BA4CEA33326E7DDD9AF38FCE057F\n      F87AEF85DD533FF15DC15981E2A19F83BC880A159BCB30787136C94912B879BD\n      5B91BF71BDF7C55D2E2CDBB16520811F4BC6474916E4C804EE689D1300425A27\n      DCC5719913331F508B5A1FAC9095CC9C2001A912409504C61CB1CC60920D6FB8\n      7CF07B7B4EA55AFB87A7A78DBE1DD6445252F6081620CF1C6482B1D5D7EED6E1\n      836217BBF7ACADFF02BEF69E5365CA3C335B9519670F97C98ACA186243E64E01\n      B49280A069206242E15D9953584A401A5BF03B01024259848A03C43055590E2B\n      5C8F0DA5A573B73574D78514336AFE6E92591428D2BB8EA30615399FC9348BA2\n      326C09018F552D5256F3810F01BE111987CC629585D6B03748ACA87D7C0134E0\n      6C23D451C196917B89C56E4033269003D5553A923AB62D45B29DC51B99EC6222\n      BD108483CC41C4D738F5890A51D879603DFDEEBE356E6F5FD95A58769DE315C3\n      298C571B68AFD8F4DE296F3EB71B19031C135108CF2B350315E352EF2F87D64D\n      201324621AD8A86BDAF986E1B1F4F8C3A754395245400B3B31466B984724B81C\n      899E8B954EF2808A520EFBB94DABEFACB063269C43E79C58A00B2336ABF45F1F\n      8DC3DD534F9E8C7AD3E01A4A86B3A57795E92A8E9284988C66F8EA79CAB1A9CF\n      5A619919276EE33F61CF9AC0A0423F7767A5E0D6D85DE57881A1AC04D5222EBA\n      375EDCBCFF9EAF9F4437C77CB4F2C0495AAD148E1D71001F622716D64C195FC2\n      C4499CFE73D76930410B0BA8B35C3E7F092AB76795E6BE8EE6423863A65DCCDC\n      E3C21275482C63574778FBC6E4EDD7BDA51576E19DB96817856B3AA7F200C783\n      DE1B5F294DC7C56C36C9C2C5C7EF4F6AAEF47D78FC423BF02BE744C093B37099\n      E666B5CD93D88DF9F23CB5157F2DC39CD12237C7B2734F7E1AC1FB4371F9F6ED\n      3BBFFCE9B7BEB4B99FC965905D8B9DFFF6D5B79FBE71F0D19367DE9B903493CF\n      04D32F8AF8EFAE1FABEFEE1E8C835EBDBE0BDC0DE87EB9F495DE3EAB5647FB47\n      CCB6F793A0A9C9BE83CE4BF44B2BEB2BB5DACF0D0E7EFBF6EE93BC0640785C1E\n      DDB75A0EB36C6726BF47451FE9CEFEE5E9932B1EDAB3ED3F1AC4BFF0EA5B7D44\n      BFF9A147D7176ABFF5F9CF1C8174C5FC6E972714F0B2E3352BD595C5E5DEE1E1\n      6C32B5B900E4E366839AEEB20469732390248270509C734B7DDB757CD808E67C\n      466AA68D19B7D4B905EF9CE04CE666301CAA07286CA06704D0687A34ECC649CC\n      0B66B99666C5340CDC4AC91818723A9E4DA33432BBFB6EF7CCDF602108C219A3\n      AD9C7FECD8FDF18AFFC7979FBB5788D37EF9ADDDBD0FACAEBD1FB94FEF6D7CE6\n      4CFD1F276237CE0E61BD5BA41EE7AE243B367F9BE5C079670787366C43A7E4A5\n      D6825B6CF7477EA3912B099FC08A132F2791F02E73756D7BF35BAA4B3FDE58BD\n      309CB83CBDB2C8BEA42645AE17D616BFFBFFFE37F14A05E80F4912694BD07449\n      7F04EBD82DB7A9230A122358D7C89ADF46A7F3EAE4226D1914242122F0A10402\n      5668AED298493DC5192A22F884528B799AC76470E7D532C9F23891E58AB7D892\n      A6D022AC54321AA5D3A8D2592DBC9244791C0C83ED3B4BED0668271C8300AD23\n      BB1111D38A0108377CED451975DBEF3811B150E59963AE6A59F8C2CD6292951F\n      BB67E6A52C091D2065486BDB077AAE9DB28996CA8926236C625EB569FFDD3B42\n      FD5D64CE876CD6F576FEFAB6D72AD5DFD196B887130F049CD29153F0E1ED591E\n      91CE9976CE46B0D01170449D9B0C40ED6963F01213100254289A43D9E4B37AB8\n      13E6B5C45BA5D1D52C7C96E2D0C93830228E241BA324E15903D94E5E0A0AEB60\n      3C2CA964B9CA59598ED4E0F8432BE1D9A1BFD3D93DDCB4D76855B40637864E13\n      719B8E6FCB6667397567E32BFDE6EED2AC661D0C8C3342CCC4486AA0D5B94952\n      508C9A442625E7F699B0D033812C2A854A113068EA655E9DF24A2575BDD8CBF0\n      497B290BA7A24EF4272FB46F93BDDFFCEB951FFD8ED98355924EBC34332DD02A\n      C1292C6CA284E94E1C5BD3AAACE9CF8E767FE7552B20F57635C56930082D5C8D\n      9322967A92ABB1420914654A5AC4F1740A0B3F67917FC12E3F5691EE94CE7B5D\n      B06DCD033C04D429D3A1026A6D52D9FAE35BF573C7AADF737CE60F455CB2325B\n      F300C1EBCA9839CCC46A4EBE4D1B6B0140E85C9803E11327AA427836F047A03C\n      58F8DC0021ECC001B5A698D03CA26832E58324855D6F31D08EDC6120493435ED\n      9F7783D7580C40A88994C55162CCD68C78348F6EDE04605A5A18A50C38303C51\n      732C0EE42296F0BA43ACD23028715E732D5FE66D4E6A2ED44C0DF826A3D0726C\n      AFDE1876FBCACF5B6BF50878C24E814382DBDABE9F45EE8866DC2325C9CD4C82\n      B05DCC547E278F5FCBD5D44A40C5171614644FC8051BD40A19F2E1CA074EE5EF\n      19F3B4B3F5D5DB154754EF5D36D70F730B93BB1359007CD41CD098F47A693A78\n      CC04535E4C397527CFC6E197121F899C4B99330783F01D05ABC9DAC32775DD58\n      0230EDE4C0E9502E1212BC9EA05DCE0BC0FEB0A06E6192D048E5B1BB40082AC7\n      38905095E1D83E7AB33BD8DEBDF08EFBB34178F076D72DD1E663CDC29DC5A671\n      1C0B000B0908C8312388A77325EF6922109AB87105D974C28AF1CD5E4D8AF2E9\n      FAC40A69E1F8ACBCF5E6EB4C92E593F76FDFB95A7BA4E3AFD79130B35999F1C8\n      03B876B0320F59B32CDD184D5EDC6FAC75BA52B61E7E272A35726479C0BDA49E\n      4FE94B73525300F904D50F845DC46CCAA747E9575E8982E9C2534FE6A50E4B6A\n      8A97429C95E3517EEB4AD0BFEDE5D94EEF70FDC1FB68A723294DA0B4F312CF6D\n      4DBD54B80400590A73BA478D33CEFC248FCE5D28E9DD648579B3BC199E564037\n      A8C9A123BBBBD16FFED9AB7FBDBD3588CEF87AA9B1F0EBB746BF73E3FA074F74\n      9EA2F5FE6682D75B2F75DF3C40D5733E42B3D158D3D4AEC0AFDD1FF5C37AF9CB\n      7B07EBAD160FA3C3301C39C4494C0FD7DF5959FA67ED9654EA57A2E83FDDD8B8\n      C7297DCFF2DA7DE1F462A77C27093614FA8F38F9C62CFDB14EA75AB0ABC2FFC9\n      B76E3EDD1B54FDCA479E7CD7D1D1DE33AF5E8152991B4FB87900A152CD4A0D04\n      9F8D49D01B9C595C3DB774BC4A2C1FF65C942E546A5ACB02D86496F483C9C6E1\n      DEC6781FE00CB920149D5AAD69814A94C6DD51C0F74C1313F08BE19B4B909989\n      C07BA3FED1F04886F19A573D596A3CB87CAA51AA0CF2707F3ABA393E7C75FB76\n      F9F8522F9C0E470383827727A3EEEA428C1C8402C1A1C03C513FE15D3CF6992B\n      5F5E4EE38BCB2B5777773FD0687FC26B7EEAF65BBFDEC0FF8A97668C0FA58465\n      69A7994DF921A16F4441EE893C8D81F745D3FCF8D271474F7BDDC9F2F25A1CC7\n      6E495095F058878A6F337CFD68FFD152E59FAE9E7CB83B6ECBF4F575EFD3B29F\n      8DC3B5E5C5EFFC3FFF99FBF07933D2AE15B26432EAE9716A3517886861731D3C\n      2D4C1C87652E445168062BCDB8A36B9A0A68500016C2C35056C1726D98BC11CC\n      18AA30C1498AB931BA9A64C39B4977CF1CBE82DA5E6D213C1FE142D238F1DC39\n      6AB4D754A316B3DC2D54FFD5D75A504A2F547504DCBC89456D0A786231676BE7\n      E0852F761E5A554D9CE529F0FA02166D2F1ABEFA76A9B3C4D71B118DED28606A\n      DEEB50A95BB54E414CF1254AE52480CD6C1AE675210FF748779F10D3244F93EA\n      E0853D99EAF6A36BB2DC2D427B7EAF19C12B1E6FC5C151B67A715559E30C084B\n      CEB802DD0E8FC1377D374639518685341E9F0A102E3E88631C95D64B3CF5C62F\n      8583AB9312F6D03CFB391238E5C60D4FA7A41B4858448BBED302E2A426526776\n      C7CDDFABAB893B194483383971EEE4646F3F389C2DADAE47E1B8178E97564EA6\n      DBB3E0C61ECE5702254D063B2643F833CB7255CC2FB58CF1406EBA3ECD4D18E0\n      2F14A294C918674CD2B2744D66851B83A25960F62AAB3B20829278F8EF5B671A\n      F74D7FF3AFC4B73D55BC6B95E4130B38049DEF6B7353986648B18CE54EC4B045\n      EE587BFFF945B111F91DD75973F76EEDF23160512988A371968FB03B2B329BE8\n      45ECD51163561C54FA4BEF6EB3632223017778614E966D733669CECD4CCB89E9\n      24DC73DE7EFAF2EA53EFA87DFD5208023D179682629C98C93FD3A6691AB1EE5A\n      51986E6DF2FFB1F51ED09A5D5979E009F79C1BFFFCFF2FBF57394815A45256AB\n      D5916E846968A0A15960C0064CB2978D5963CF78ECB107B0595E06838119184C\n      B0C1188C8176B3A01DBA69E8AC56E852A924554EEFD5CBEFCFE1E673CE9DBD6F\n      A901AF6549AB54F5AAEAFD379CB3F7F79DBDF7F779D439B376E4A7E9D5E70EB5\n      009E42B2A531BC173B70540DF59B01C7D8234A7906A87C32E353749429800E7A\n      D27238405D0D20965B78AE0DB79F2A9A01F3CCCD102B98E64177059A4CC296CE\n      CB096CC6A224CB30BA59A8A81C6367526AD33C8903CE1ABE53257A1E2DA26117\n      A021A20A432FF0A51F0CFB43D620F5956A6F6B200EA49DF8BA9DDBE74958190B\n      2D7C52D5569ECBCC1141164CF25B4ABF04DF3CE8A268B09B8DC7553B6903C1CF\n      AD7E73B6F20D4BE6E1DC8AFDCDD7364944569F3A5D54A69A8500C19891103F53\n      924A60BC39AA2D2A0A59DB921A60C6D81224BEC6BB9F9CF8630F7BBCF02C5700\n      331C2E0ED69E3AA6DB49AE7A9692A6F0739A49C04B57547E97FADCC96802A9A5\n      C813BA422BEF00AA57E0BE868F80189A2B5958837BFDF1B5DE91CEF16C98DEDF\n      BF3BF770A37ABC915A13E2C24653B0EE082E424C9B048F9F815B07682C590C71\n      D292D6B2C8BAF3E69B878FADB86D6F64C6AE1F982939786B63F5A187FA3BB7B2\n      A0B6FCEC91BC4984E7153910068B329B02C58585A123F8A61B5F786395B606F0\n      C54EA7F5F03923037C570556EF4AF95F4D8C2A67FB2038A0ED842567E9DD2B83\n      8B571BA74F59E71E2A8C2D633B76FC5CEACA606FF2C54F563BE2C6CDABCDB5D5\n      B9279ECC60757835354D65D0444D15AB4269C0898DCDA2B87E71761E65BCD099\n      883D508F2E7B644A4663CAF135DB26A351F6877F76EF639F7D7DBD579B6F3DD7\n      69DF1EE43FFC85D7BC95CE8F34BCE6F6F860FE68B7EE7EE1C52F2C34966BD2DC\n      D59359BB73B0339A77FD1B07BB64AE99469A27595264B0D553C0A542BF8B57FF\n      B7E3C79EE213D8949F48ED9FB97933A879DFB5B4FC8E6178A8E15DCF927BDCF9\n      AFB3DD6F5DA97C2367D534F87411FCEDD75FBBC5CDF3E71EA909F9F295D7C771\n      8AAD9938EA900BEC8BD68D7A3D9F848126CF1E3F737E7ECD8F0CFCDCC480611D\n      26C4BC6D0BCE2ACD86E2A497CC3686DD5BBDBD2B5BF7B692514228870CEAFA5E\n      A5E23329B49152E268046C47691D8C06F7073BCB6EE39953E79E3F79B636D541\n      6CB218A9E5C4323B2A7CF1CED5EBC3FD09D3BD648A1615259AF8AAD5113C6B92\n      70E1E5C543C1FCC2B993AF5C7BCD1E8D8F1F5DDA3F983C57C8EF5D3DF43F7ADB\n      3F35EBFEE38A9F79952804E46CA3EF3485602C33AF7E65B03F4CA7F3ADF6DDF5\n      BDC595C3444D73035BB56EC55951C4DC23E16064537F4FD19DD9F842C5FBD1A3\n      C71F1D8C0E87E1FA52EDD36CB63119FA81F3753FF0D1C77EF0AF17E5806834D8\n      8947FD46738E54EA3AF74B3585298E70171E26423A4551CBC227C62F7B955340\n      A14C738632400ACF8F71A96440E86081022C175C1033E0E95EFFEED526C46380\n      ADC796B910165AA5E021F3F8F5DBCDFA823ABC32B3926AAEA75FB954332A7D1A\n      32B5E3E826E7CD9964D2E6FAE26BD1F5CBADE78FC60D42128560490801B9FDF6\n      AD85471F82140A6FC59ACE20D26554E48D8ED35AE4400174066859F1441A514A\n      D9986C7FCBDADDC6A322088C2A98BD3E1A6ECED69E3D9CAFF58A994B712E0202\n      AC89F74DF7EE64EDD472D14C2076938C73055F07BE584509399A60172A1105EA\n      A0A638473648BB3BC3C6CABC6CFBC97E347E694CB739D7B2C0B21B1D1426016C\n      4D8BD10C375ACB0B9A267467C3AA578921BEBC4B7516AC7C20366F85F38702CF\n      D1BDEB61ADB648DAB33B071B87E69E84B571E7C697C895051A3853C2FB593150\n      C53453118AA6947C8642E2CA70564D027643E9AB9869F84F2ADE485183111887\n      27F365DFAB1556CBB6ED51B4FD1DFAE1777EDDE8535F8A2F1C597CE1F1383A70\n      1D0138066709F259A187B9C9AC585A5E06E0C28FDAFD5F7EA3F8E28E58A0F5C7\n      3BFB77F6CCCDA206D7178F2679DE67F5B1C95D9A7674655104C0A1D323FD85E7\n      DBB482BAC7D4B700F88952B68F48787804C54B543DBD496F7CFED2B16F7D2E78\n      AA1D5B112D848007FB40C2D1583806CFCCFF9408DD336B87CB44D8F10257EA8C\n      407064D2C75E536084ACC76D74478E638B25990F1C4BE519C3284E1C0BC83FD0\n      732C6169E03B063E047B1B934C0FE1277969F9F4E083A8A570BC095D30200F26\n      99C2032F4BD0AC488B228448A27170A25DF11BCCB4514F42930AB32CAA6653BF\n      5A314C4CA753BB2D6A2B958D9B9BDE30A8E58DA416C9474D549F39DA718B20E7\n      B9B25349FCB83920B78AFCB3AC50B52D5BA78590B3593348AB107595AF4FB3FA\n      87AAA6617846BBD7FADD3BA3879F7DA4588D9535B4329F2A5FF130B3A7527BD6\n      AC639C3DD849B0110169782CE569AC077EEF3331BB299CCC682F875B0E127F6F\n      6967EDA9C3642E4BD501CF05292A39410F49759344D7285004740E4559CEC43A\n      4ADD677C33AF3009C2A3CF858B8A0264BC3918BFDA5D4B974CC2FAF676ED899A\n      A87B8597119114461186C57FC31381F41432AF9B111CFBB04818572D2FA967D7\n      E25C27D573EDDCC444A79627F7B7C67E52ADB46AFB7B976B672F38473A7990B2\n      007BF1607352E26B923187147916EF4E93BB7B0DE16DE595B5279FD0D53AE33E\n      DC2FD0762AE085660072B8420D22005D0A8F28A93BDA995CBE0888AEF5E473B9\n      5FB109CD61CFF82E10F8F8952FB9FB1BCACEBA51EFE8534FAB464B7B4D3B1304\n      ED742DED5615AB4A12508D67BC00DC1E5405693935580E9263DB5529CB8C6D94\n      90808914493C0DFFEBE7C3FFF8B9ABD374A9522C4BB61577FEFDCB77229E5D98\n      AFADA4CC0967DEA1E69795F9C49B1B67EBAD908577D359F3F8B95B3736E2643C\n      2A54B5D9E699D81EED25362C2DCB0FAD42A87F7AE891EFA8CB7A762F66CE17D3\n      F6BFBC7333AB938F763ACFF46675DFBFC3D87E66DF28F6BFEBCCC2D970A88BD6\n      BFDD4AFED5C67AD4749F3C757CEFCEC69DFD1EF656A36B8D28044ECD76E0D165\n      3A20E2C4FCE25AAD9D0EC6AEC501A94F6653CBB52DDF691953E372B9D1AE30D1\n      F6AAAD2AFCCA1E84D32B5BF76FF5F6B766E3FD783ACC62801BA26031CD018A38\n      8E53B14447784FAC9DB870EC14C0A67BDBF73787DD8899711CA5148F4F59E010\n      DF79E9CD37B6A37E56AA6F17E47F4A8454423E1176CE2A8C2F1F3EB4BFB7A9A2\n      D9DAE139A7F04EDCDFFD5B874F5C76C83FBA73E387EC8237DB565CCC3976E49A\n      FBD9ACC8651A895E202636E96DEE3022F70A92E433EAD83E71DBCC0A6AD202E6\n      3698DACABD1727FD78F694EBFDBD93C70FA7E3E530D44E70C5B63EABF6C73479\n      E4CCC9EFFDA97FAA4E2E45A33E3BD8633E7596E659E6E4994B6D80D053885EAC\n      0018AC191F172CA206C89347F118ABC06E523CE6CD0A6CAC2C9B6500D0910827\n      05A967B4029ACDD3DDD1FA359F08F42F3F3C276DDB523AC67670515CD99253A2\n      1F393EF68B4A18CBABB7CDA01B3DBF6C58D5CB1B166DE4D222341D7DF6738D64\n      C4CF779226A42163176ECC857CE9E646BC3FF7F459C8D65E1691E904F2754265\n      DA9EF79A8B2285259A6A1448CA44EE6A2528CFB3EE26DFD98228A9207852AFB8\n      A9362EEE2C5D5862E72634ADB314E0645C50A347D6CED57E67A5E61E9668389D\n      E2A15B61325823D802C7729CDC80406D04C4CBC28A00428EAFC796A8D1E356C6\n      C3EA0D77F4629A44284A92856694B0B145C745846A27761DF25647983995B976\n      406A2E3FB1D53AEAB0DCEFDF4D940E178ECC997D33EC8D9DA3D6C4642C0C163A\n      F5EEE84DFAE9F94490905A075931360438CF344ED1B281A1AA66564EF2108BCB\n      B29727E5049D76B5ACE5A88B412D5DB7AD7987036F6B0ADE08D58D139B173EF8\n      C141323DB0E213DFF49E0248B30406686B222D35A1700580C2539FF168E4641E\n      5BD4BFB511FDE135B64CDCA72A7A94655FC9E5C4813F13167ADBD426260F2CDD\n      C8BC255A4BAC7DEBE938B860E3B49B741207E599B816CC01DAA338F594C89DAC\n      9DBE91DDBF7AE3C877BE531C0F520861BC5492C6BA9E45DE9E5ACECB6D82C773\n      A8E7E79DC54478EB9D87EA6EE0DA242DA68C17B26AEB00CF508B811153E07B69\n      8ACE4A2E8005406D16047B217C6013D82FAC092BCDD561E75A3256263566A2AC\n      6914E3A47DD9F5673B5EE9DD8BEEA2B9D140091F48D06845E0416734A30ABE21\n      EF54DC86E03548EC7462D7D088219D66959A542A9FC5B9B76ABB55AF77A32F67\n      8E6B79A133AD9C97690D3D820001606BB553D6D32B1373974C3F6F4953EB8A70\n      9826552EDB9242EA8238EEBDC7B7DEC7688C039DC9DD6CFD4FD7CF3EF308BD50\n      E4CE80C52E3692D9CAC88467164F835C740112C4386AC22B94D328224A0E5E4F\n      9217757D82C93764B11F05C3B9FEF2938B6629CBF508B255513828A20BE06343\n      4EDE48016918AE53344D35EC04B59E76545B13DBC63D0ABB3E54D89619E6E1CB\n      3DF706B1943F5D1D579E85DC4F6540959E726C1F70729CC186550AE0D826859B\n      A132A561B0B02A86EEB1F8F260FEE44ABAA834C91D85C7D1BDED69B3793C196C\n      CB562ECE9DA6350FE832DC1AC3419100283D13C0F2144DD8CE57AE2F009BD9DB\n      8CCFBED03C75A2B0645158C074B17DCD2A721C783128C38EA6D9C0BD25507D7A\n      E562EFE635FFF85971E22C81AF329A03C8830DB37B7FF70B9F3E7EB8B3BB7EAD\n      FAC83167ED701134340BAC1490B28FE352D2D7CCB3884B4D59EC047458580C47\n      02E027B094615921B82328218106050AD80CE3832FBD3AF8FDFF115DDE8E1657\n      4EB1D8CCA23FE8DBAFAE4F3EDAAE756683F5542F7AD66AA5F8F551F8CB5DF5BE\n      C09B568A8368EA588DFB7B0721505F781E1130CB02F5023DD4247195F3818AF9\n      47C79F3E9D8C18DFB5B87725A9FDC4ED1B9305F79BABEDC7F66685676DD8C0C3\n      94559F7EFBF1D5EA7878D79EFBC94B9B9F18F784EF342A72DC9B68859ACF8471\n      549B238012A55F30BFE08F1C3B5DC409C133250DF96F6FD093813B9ACEE65796\n      9C38124AFB8555CBC985B9B5355939B770C4C3895D36E36440F23153C33C8E6C\n      221BC1349CD66C7FD16F0469116434EA8FB7F6F7D667FDABA3BD03A9779271C4\n      68779C546CC7E479AD1674BBDDC16C044C2A2D4F464BE5F2B2FE814E56C0EAB9\n      8D625299EF57B22C86287DEC50E788DBAA5EBFF5CDABC72673D5FFE7F2EB1F96\n      A4B1B26267BC0A9C8024B78B70A6D098F47E3C9BE2B40FD184EFE76AA0A6AA9C\n      96AD1456B351D71492A66ABA8DBB835998A68F5BE2EF9C3A7E544DEB6AB6A01B\n      07B6FB8762EFA61E1DF51B3FFC4FFE81FB0D8F0FBA3B1D085CF3416C332B92AC\n      70B0BC401314E7283C822DE709A54939442FF1048296F33390008B1C45BF5939\n      F7556A9328AD8050A82CE16CC292BDD9DEBA8E23C9DD1CEDE21B3C434F6C08D2\n      A23FEDDD5CB78F1DA24B73766EC4FEC1F0CA9BEE230B59634E92BA456AC49224\n      0D0FFEECD373358B3E5C9F019E4E81E1F0C491EE9FDEDDAFCC9A4F1E15B06081\n      0EC6112AE7694B3797ED3A902C4D8A4C0B6C81E7B905C88ED02CED6FB29D6D47\n      E902FDDDAB648BDCFBFC8DFA4A507DCC2DA887CA107A8612ADA1DBBB32911EAF\n      3D5CC9816402BF25794EA23C970E36604078CEF1141665E90CEC0D74243EB0C2\n      712A8F3B333A6AC59DD9CBE9F0666E5B82656216920921C374A64D2E2A7EA28B\n      BA6537B14551790B7ED1D9F33BA2D2AEAAB4E8ED749B95961DD4EEDFBBE1D5ED\n      A032777077BFB95A63AD9C7CC11B0F66692E878A8F5254B319677998E51CB6B8\n      B02378FED8CCAB329D219F82776209BBB01C9CABC209848623EBB4A8C8A22969\n      53932EDD3AFCDE73D3278FAEAF5F3BFD8DEFB73B9632A1812D42ED824C99EE71\n      9500136045380CB4CDDAE2E3DDD16F7D45CE53EB710705D0DED2E9BA760111AA\n      7CC77890982B5CD714EF10277147C17B043D894D551CE2B495026261CA223EF0\n      ED1C7662CE122F5E4D2E66DB83CD237FFD3C9B47B1421C9BC77940343520A5D7\n      29C1AE518C3414A5305C5A39B3BAF6AFE9FA732B9E0BAC594022D4762CEA8E25\n      81218964183248829A180DFF270744A0A114DC3677AA42025E89790AD4DE258E\n      996536E7090E7D9328060E17A39B1E13A82563F1288A381EB6615B60566AF5C0\n      820E5162CD58269739AD4B31571501401C0119E3A039EFC453279CC86A4DE731\n      BC17E99D1210308A7580404637D299355B3C39A7FC543BE5791F878D05F43713\n      DC4C6F15C3CBAE97FBA1DEEDA96EBBBA58CB6AC0A1278D61E79BABEAA1993CA8\n      87CD8C6FC983FFB471F8F832F9801BD701B6429200D6CA9801EA05D827418F78\n      539A7F03088D1D6C5516E3702F1AFDC96CAEBB4C5D3A110378F22648E79E69AA\n      95486111D701549B3A998010BFEB0E5E1BBBB94F4B41492BD5E46152BC439ABA\n      6509DF38DA861430CE531423B1D46BBDD9E70F026B717632AE3FEB9A5C491416\n      C92CEC862ACA762D081512C51D903941A8A085570D52D3BDBB29AAB5FA7C33CE\n      8702E856564CD7C71E2C45297BD9FEF2C9C5FC58CDC2062DC2988BDE1896C0E1\n      0D48CCB43EBE3B0AEF6DB4ADC466917ACF0F10F82CE950F8A0FC6D8DD8426273\n      93CA0ADFAE520DCF57D2D1ADD19B2F4D9268E1990FA8C6023171298BED38D378\n      EF337FD2AC18ECAC9E0EACF73DC9FD2AA5F089361E3B500F3E1D162167361EB1\n      C2B5506CEA27F0BBDC248014817F660ED002C5E00F6500B4538B692EFCBD69F2\n      AB7FB8FDB92F8E1D7BD55914B17539CDFEE0F69D67168F9FDF1D9B6434AAAA33\n      F59AADED7FB2B9FB1BA9FE1A53CD56BCCDD9EE6830959ED38F34107A7898B6C5\n      F22CB78404B466DBCE6F35A277D74FC3529ED9D32AA1DD54FEEB9DCDF596FBB5\n      AC7DEE209DFA7CB3C17607BDE757C873D5F9705A7CA2F07FFAEABDBB61C418B6\n      45C302056E09403EE7B0F2A4800F51854D69C50DDAF586673BD3499429787772\n      329935DBADD1603CBF303F9A0C1E08894B6D4ED4DBF309FDC0A94760412DD49B\n      52F2F9C585F9B9B68E13F71D67C87CEDD6A73EE70E33368CFB07FD3B83EE9D22\n      FE72776387ABDBFDBDA0DEE81F74857043D4135205044B1C59C4294648F8400A\n      21A63E30EC2D855C702CD1CA958FA61699E2A55E5D4E1E5DE89C72FDECDEFA63\n      AB871E5A5CDCBA75A3C1F5C2DA9A06B037C9874976DF31D720F0DA80D364B737\n      DE9D2676ABBDDF1DF4B197102DDC458182B18C27D2354BEDE6EE560424F694B0\n      7EE4A1C34F45B136C3635947D9C127AABD97A2EE9CAEBEE79BDEF7D4FFF591CC\n      2E6C53A14C45900133177D06A979706A44FFD259F1AB254EFA80D51A52566050\n      B5092728CA210A82DEE0826A94E43663A2872AEC8E0FB65B4C86B670978F2419\n      93686E13531EEDDEBECE159F3F763EE6962BC8CEEB1797E224397732AB341C56\n      A5C0AC27D1CE9FFFD9D291063D5DEB934923232225A164F67F1FC60B71E55CBD\n      90065E32A439D81789166E658DF91D52EA511BF44551F002E03903DC52E37DBD\n      B9EEA26D9034CCE389BDFDEA957C161D79EC7C520B25A5B909958C9DCC37B78A\n      497FDA3AD7CE58CC12C90564EE2849224FD7705849A48AC44AC3F245C528A664\n      1E8607FB5BEDF926AA0A38820CE9E873D3749F7B566D9665690EEF9EBBAE008A\n      37988E04AB07965FF523668FE5A17A91E58D4702DD8806B746625A6D9E5CDA9D\n      6D24B77A471A67A2783C1093DAB1C5A2A7062F77ED7140A407FC61AACC589351\n      AC6CE67361F7F219F02D00BCE8B7891620F002882E050151AE95B38AB42ACCB4\n      39E434E632321799D105617FDB63772FBF79EC6BDFE31CB5515A3C7761D7C732\n      263AB213846D804C47B61256DDF9E26CF41B5F842C567DA2AD85CE0F44EFADB0\n      3A7128FA0CF071813257151A06100B9BBAF6AE76BE961B82232448C7455068A9\n      7D9EF184530D40C59D9E88BE30DBAD8E8FFD8D234A2622AA02AD029E088B0DF2\n      24818C05F015F706C7C61A9615903C2A67D7D67E8E6EBE6BCDB13D47E2EC8DF1\n      325973187C746EA58388A19C059ED66719ED335B1B250B536522E040FEB31852\n      27806AEE14D3CC2AC5A06352448915C619170E1ADEE498EE60E1612BEE03FBE3\n      B2F742A1FA680EA14150E612AB2E8AA66DAA52A09D931C3757DCF140C176A9B9\n      5632EB15AEEF1F72D2416A762D03E4D2CF13912C9EE82495D0380AB6039ADFC2\n      C6B472ECB2BF1A4F2EDB226D8CCD8E92D33AADD5C85C5C44E454DAFA403D6B4E\n      49C85555B21D2BFA5C9F98A4F5B50BB3B90487F188C484AFF14209CF21B1713C\n      10C7E0415307DD5165684666FB63DDF6C182655BA19850607F9570F1E9B65E85\n      559B5BB1449B389942A017075EFFB5A90845995D61C3A6FCACC59F77F22A7720\n      AFF8B0AFB3629C285E4ECB5D99402214AA6ECE16C11348C850EC1A2899857117\n      27ABB411B6C3284F1348D7BCB0255CAF736DB817EED59F3D8ABF1E66B461452A\n      D9BCB4776AEEE428DE9187EBDEE2A25EB00996234B5D2B88220C968065290E78\n      6FE7D28DC5A03E99F59A678F93D5F740C65548CA184E2DA3BA281EFD01B3C908\n      0554C452C3231D5D7F311CEDDB0B9DEAC38F4D880DA8D72A52B89483B7AE93AD\n      3B9D656FE3C6EB0B8F3E6A9F3A04E412403DA0F682F8DCF219750CF23FF17622\n      2416B65061D79F41C57F600228B763699C0CC94881CD8A4CD1FEA7BE34FDCF9F\n      9A6C6C693F38162CEF27FABF6D6DDEEF261F5E3EDDD9DD9B99C8590CE6899E24\n      EAA7B7879F50E2A96AF3D2DEBD48AA4946FCAA1586A59819E7316C5841A4324D\n      45CE2CAEFE9BA65AD60D58BFA19B0248DF89ADDF8FA6EB1679C6B887F693B8EE\n      ECB4ACEE6CFC5DC7AAC7123188C8AFF5C39FDDD808A543B218C3362AF331087F\n      69A983EA96B506400E4B8B4BE3F1984B9124499AE78C5B10BA032CCD6A4FDABB\n      D9185696CE32C968857227D38F1C3AEA52BA3AB7E0E4E688D758226E3D21B593\n      878DE70CAEDC55FD69549875137D65B6774B4FEF8CFA49816A1590DE90DDA20A\n      B929BD014AC58FAF7A8B97A72D586085AF5968E86D60D303B6CC3161E259342C\n      6E3B2F1EA9B5CE373BDDAD7B6BADDA372E1F593D486EBB13783B387E91D1B1D2\n      1B3CBFEFA81E901574D1F6B7C793FB93E934573197890A21F801AB4182C6D286\n      CFEBAEBB3B4081AEE7FCE0EF1E5FBB10023599D6E30AABD42E37934BE1819E14\n      FEE1C637FDCC0FAD3E798EA05A6554B85CE42E296D534A458552C892FE651624\n      E5793CB61313CC95584246468853920F3227D6CCD30492BCC986B49800AE1E6F\n      DFB59319CB5D313FAFE6DB198405636C1199EE56BCD1F7578FC46D0827C46CEF\n      45AF5F729F7E3CAEB703D92253931EF476BEFCB9D5F387AC23FE34EDDB94DB8A\n      2571A23EDD17A76CFBA14003D356144382CAD3C2716A6BD46B950DCE6834C14D\n      5ACE8451D4448887F97DBC0CB4283510245AE1B58DED5BEBC7CE9FCD97F091F1\n      4225722AB8CDEFDB7BD7F6E64FB68B36864474D4C26F9801C363C019F13B971D\n      F740387380F92851D43BD8E796D5E8347395092A92EB5974313743C81E629C46\n      6E2A6BA23A23B3AE990869071AA90CF732EB84930D74ED14A59D7131ABF66F65\n      95359737CCF4DAD48BDD60516E8F77ECEA72B3E3755F9D9A7B90525824E99ED2\n      13C56731EC1FE158228CA6833C8F1C37804D6C0CA47E9C9D2DC18A41EB315A95\n      BCCA69CBA22DC121112E68B2BE385DFDC8E3D76EDD39F4FC1395A7E633C0BBA9\n      032125854468207E0366CB98D2FD22E47EA57E830F7EE57379389E7F6A392491\n      9BD5873743B299DAA918293A31C2E2A68A276D29ED14CDF7CF4D9B13C12101C3\n      672B0E0FC7D885C770EC12D845CD937B8BFD4FED9887FCE64716144D6C48A08C\n      2B60FA58F5C132B341698AB24101A36BFE9789F0E083C7E0C9C26FA5C58C05CA\n      6D784CFA26A1490F928642FD338509B18FDD495A1A13301E60015BA53C2736F3\n      1C578F13A6913FA74077139EC10344108A07CD104751F3094F47F17814DD2B38\n      C071D8D639162EB90D1F5613694BC455E02B102BFDDC99A7DDEE3828DA0D694F\n      475D3957779B72B8332AC60C7B3A03E057F1DC8976581B291B82A71090B1ECA2\n      006A20ECC91B93E49AC7D2763FDF17DEB896FB35B6BC2FBBB5F7B1CA19892238\n      68AB5C1F5C1D7B7B4CA7B3CA238D6C956454A1455F29DA84538E705F58C546F9\n      01883D5C3938D6266336A5FBFFBD2F6FFB425819835B96716DB4FC7447AFA640\n      026462C383CDAD0412A13D080617C77AC401EC414CD4B3909EE3D6BBFDA22E1C\n      A74A1C9CCC48FB2191802BA87D371A7D6657CDA4FB84EF3C6C348451E482381B\n      AA4B69666E49CB92650F333E3E884032E5BB97EFBA8B15FB742333CA5780AFAD\n      F58D3D9F576D20080CC0E6F118E8C9524B11530EA9294C75860B59B10AA7FBE5\n      D7ACC94C7A415E096AE7CF10FB1441595DC8B2185F51801E255D347C1AAB7A61\n      9A789A445BDD60F7DADDDE7EEBCCC3B5A3A753D4FDE64E3E55BBDB373EFBA587\n      CE9CDABB7711F2DDE213EF2C9A759CA80186A704A57EB9589C029D5951CC1507\n      BC294A6C3F60B70F3840490C10FCE7B09E2D03218C0EA39BFFF677F9576E4461\n      9E52F950D0FAB3DEDE6F5EB9F7C2A90BCF1CE4411C4EEA56A3E557A2C976417E\n      E6CEFE6712BE5C71EE0E7BDEF2DC56771F1E9B635B698C932639AC55071064FE\n      358EFD3DC7CE7F1DE9FBC64D4C92004EB5DCEBD3E2535138E0E6A142CE4D7452\n      77B7AD98DAF47B3AB213B99B33FEB3BDEEAFEEEF680E3787CD0319036C446CEC\n      F8C7690558C4582500CE6B036CA5D370824DD1857E300FC24C09410A1C8E0CB3\n      54489165397E034D443943D9C6CE13B7A9AD536EEB6C6B25366A1AC76D062C5E\n      8F0A7D79B6F7B9833B1317F11F6431B7E02AD7AC742B248542CF2EECFE2E3564\n      3479BB4D06F3138A1C3EF8B5C525A0D718B80B563E52561AC29D92DE3B1756F6\n      FABBB26A7D777BF5DDDBE6F54E1A87A8FB9BA374345957E11D13A6F0B9DCCAD2\n      2217727D3ADD9A8E01606468216A0C001761130E0B03360E7AF616DABCAB52FD\n      DF8F1E393D191385A69599ED242D7E67D6DF9CC54993BFE787BEF11DDFF52DCA\n      123941586E29973394597C9B05D2B230FC76122FFF47BF6A378C3902A9E15713\n      216642D862049639CD0A35219008AD2CEE6E98C146A0DABD246C3E71764A20EB\n      D91E99D0685FAD1F24DAF21E3A92EBD8A656F8E2978BB905EFD88942567866A7\n      D7EE7401C03D759C2F79C02C299A22596977947E79129CAF91359E1610E7208A\n      193C1F218E533F44DD46A903946B487F0CB54D729434296411EBDD0D3E1A50AC\n      1F02B20ECC406D5CBAB630B724CF7A244981D8E67252006E1F54775EDE69741A\n      DE4937A463A6CA5A8955F22C8D95A61216501C3283278CCDE3F66C184D879385\n      C5398876B98E78EAF2CB64EB624F543BD3249419090A774655E868B76201DC91\n      91B1A5CC8EE98AEBEF4F6EAD9C6E113FE8AF8FE2385F5C836F22F6AEAFD76B0D\n      29ADEEB8B7B87A240B49F7D28EB56B6CAFB567F428CD00DD47681D2B695A0CD2\n      6CEC42202BC58FB06ACB68C96D4A815C0036B4C6491372A164BEE0CD2CDF680F\n      E7DF7BB23789E71E5AAD7CF82C8A9F641E2F38F08482C42283A7A7585A0CF540\n      559CCE9ED3FB952FC45BBD952756672CF24433D94C66D7FB2EDC562A122315C5\n      7E1C4E52B2405AEF6D4F6A6360188E052F0A22AE0570B4B08DB2125821BA52F7\n      D6ABDB9FBAB5F0A187B3E76CE0106EE4C1D70DB0654454165A91C26EA2FFEB44\n      78C4429933D85B89A813A7EE122A554CA3EE549642A06946D29C764D69BACD68\n      CD621561414ECA9951B6F102271F4C798ACF2743D534EC9AC90D2C0AA0F7584A\n      D1A8C7AD9552E8610FE8DC96C00C4C8E076B8CBA01706311B7641440AC37969C\n      735410ED777BF3F6A297B05938F40F7580540DB6FBE803E414D51A84C1AC79AC\n      3EABF7950D08D3E170F1403F5CE5154EFF2B5DBED934E97C2FDBF7DC713DF304\n      EFEC777AF31FB264DBF0B43E6B74836861F3E26E43BA702FA9ABBD33CD9935E5\n      389780AE9E862428F855E0B82E221F64CF12509012A94C85BA4C075F9A38058A\n      1AB25C24CDE1D233F37A21C94C26331BB669CE33887DF6A40289507501B600BD\n      66268CE9192ADE57656DB81EAF10065EA29E015B67799A3A9B79FFF3DB7A68B5\n      DED12C0E87001984E4B49C2A2E432ABE338E3676A8BF0829842645B2DDEF8AD9\n      9113C7811C28196ADB8DD689D9D1AD438DBDC93DBBD3F017DB72A1AA821A3012\n      8EB26519E48434279E3F9F5CDD8C6FDD6956835112D79E7C5675565956C76F0D\n      EBA26C412E99A3801582F3310F7A47A7D3D9F64E231EEE4EA6CDC72ED85E35A3\n      6E2E2C3F3E187CE1CFF524648D7A7778EFF4B38F9BE62A1E82A2C52044E03211\n      329FA2D1A055EAD4C2D60126C94B27F7F2AC9C582501D00FB0BE922C37A99526\n      627F7CF3DFFCBABB31BCB13BB0BDFA138DF6EF6CDEFDCF9B931F7CE8DC737787\n      49348A0F2FD41D5A998E77BCE0A76E6CFDF7510CF82A65DC78DE6C8CA23ED8AD\n      8F185C58C0A459D291E4C73ACB3FE82F53DA13E8A39242B64F45E5E224FDD274\n      427DB94C58901A7840BD7474E8F0FCD7C8480FF89599FD2F36EF7ECA4404D006\n      44A842A4164E9E8902D7842E385AA11B54042DF23C905E9E450F44CE0C4AD361\n      5F9A299DAA3D8874148D29530617553ADAE8B25C4F515F0DC29F4358D3AB201D\n      284CD5F1B1AD96D1814EB7C331EA9097F1876646941D23B08DB3B2A25AAAF03C\n      28FF971AADD850F27616C493033CB22B80B302A482CFC5592000705C75F2E283\n      ED95309B4441F6DD0B6B5F7F9FBCE92438352B9C6192778B7C9FE63B453A86DC\n      63410EE6C3D96C20D8D4B5EEEE46990A317959704340FA2348EC100B334790CC\n      BCE078FFF0C4C995C9D0516CE0C86191AD54834116BD38DD8BDAF2CCB3E73EFC\n      7FFCBD68B1618AD445CB2AC1D015B2785B638F9007A7A30F6EF5ED669FBF6087\n      25562ADEFE03D87940CAA37693CD8095123223262ED420DB7A4B16AD7034644B\n      4DB17C3223AE4B263CDED3A3687CBFEFCF35C442CD0029EC75C757B69BE72EF0\n      B9369E485EBC3AB97FABF3DC493E6F9370889A2A944D76F7F5C5B871BEA61721\n      69139A708915BE5CF140360E535921B03529D60939EA1FB01440AA2036308EFE\n      8ED9DBE4B0EB1807F2E0686FFB951B3E091A4F36218D62494D461036645C19BD\n      9EE6936CEED1EAC4E972511511AC909C328892800701254981A7BB992119044F\n      40FA109077EF1FD45DAFB6D056F188405AEAD1FD2FF6C941C3A6954C8D21688C\n      C671068CB6213D69F89408E3462BF9C279E7E0EE76D36FB3550D69657A8D36FD\n      79B216F6C7FBEC8EDB593BD60B2FD2C99A7FBCE86F76E975D799B663A6C67A9A\n      50DD4D93C8488B35E3249B15E36946CBC206C37A0F2B8F21181A8ACA42573869\n      58B42978555A0D52ECD787D69976ADB59078AAF53DEF8824FE0B610F1221C453\n      0B5BF0729AD214228BABDB43BBFB9BAFE4B7BB4B6757721FA7364CD7F4DFD813\n      23E6D080154194C6C255A811BA5CD4DF5949EA1124151B9EAEA4A56B94AB51B8\n      286102804D875D357BAFDC3EF2379F9B3E846AED7E6C0367233C47B44D442288\n      931BF2C0E20637480E988040225CFD593A78E1088657C069B0AF6B94FB901425\n      8978D89D3910AA298B63035C76887B8BBA8CC27E753946E50CB69E47FC869D0E\n      2622022A05048D2586CDD22C49E16D8A82C91C3E0AA28E5210DF3385DE13C2B6\n      0D6CD72C1284D896E75BAC21D39A08F1A48CD995B5E6848E8783615BB6E900A5\n      959C955A3A49E3616C2C9DDB59B3DA4A4779F5587D52DFD34EEE64AE456D63E7\n      999D7BA9B3FFCA9EDB9FD77173928F02270C70C0D04ECFE69577E5CC06E2BF3C\n      AEDDABF78E6DBEB6595F747C29F677068B4F1F1D05039EAB4A1E14103D1936EF\n      51D8E0149536711452B1B24F3A1510FBF79B834FED924979D29BB1687EB0F4F4\n      929E4B520541413278D31CE03071A34AFFB589DE811B74D1B7288EE859EEBCBF\n      465A9E5576D0405E63449A2C4BA3D0DECA7B2FEE28D8BFEF5AC8E687A54D3402\n      2EF47C4033479EE7E8668526DB1A070CD8244BB7F692B32DDFF39D094041D253\n      66743D393E77360558E5F4AA4757A55F95738DC8164E8A50469334B181C47039\n      E68397AF771C3B51115D5BE347CFEAEA2A9F180B5B3B717C1EE0BE07094C0B08\n      A7B9E416ACB4C968BA7D37687AD6CDBBA34633387B8EC1A2622E4E19DE7D23BE\n      F4A56667FED6A0575B6BCF9D3D9B396D880F1C7B868105DA947A947965B6130F\n      9AA75000829459B0EC46852550CA6BAB02C59449CA39FAC1E6095BDFBDF973BF\n      CE36866FDD1F3895E6B3F3CD3F8BA28F6D6C7F74EED8B3B7B73535D19165006B\n      F5F168DBAFFFC4C6EE1F0DA6F59A3FD21A582064606971F430C3634BF8EE4540\n      D5B72D777EB832F7F82C1FD48AACD0C0F1018FEC19F962945D9E8C9A15594963\n      D814AE033B3A3B7974E1341BEEF4ADCF8EE54FDFBF794762B7A21FC3E3AF8512\n      CDE7A88EE10101C3363EFC7114A0C2286DB483EE630A2DBE8BE22F0FFA28F1A5\n      07993954098EB82B85B11F2B2CB4A4EA002081DFE4780E0FB0A3D4ED7DF00F12\n      74580D401E7124175992836614460891306D72B469B7CA29C6F2713E90F7C505\n      036B0B87E1B46A2FB7CFAF1EBB78F5EA701AB6A86C35DA039E9183DEFBDB4B56\n      A00FF8E03B9A6B1FD9166FDA090A26503E8610A6558FE40745366006186A4540\n      90D5EBD124AEDB772319F7BB4419C5FD04595BE23005D7AD01ECA4FADB83E6F7\n      1F5A0BA2413BF1EFD4F98109CF11DBB6F97F8BB676DDFCC4CACA87FFF1DFB7DF\n      F14852CC6A19F6441126ADB270FA20113E7860947E5511E0ABF5C2E2EDDFC08A\n      E2838222C16A21E078AEB31992946266700E2F9A6CBD6545B96F59B3701A9CBC\n      907B55ADC7824EE0B146B7B6A3DDFDF623A7B2C0D22C519FB9E5D6E7ADF32709\n      13F1E53B83BB3716DE718AB545114F908172D6DDDE26AF459DC73ABA83850A92\n      50018B068298ACC8E661222A10FC8A724CC2D2092C6F4889A8D48F8D3043B579\n      87A5D302760E953CB5476FED16FB49F3C21CAD0A65622EF39CCE84F6F47DFFE0\n      CDBDB9336EBA34D354BA916F61A7748EE7D999205AA0E610D00A9E6A9C6DC7FE\n      8BF1FE4C4DE295D5C39099533142A07C838DFE2CAF679DC489636B964FA94B6A\n      404EB44C6D58CC5930F6B3E6FBF30A6FF55E3AA85C70E8616D6EB9E97DE39CA7\n      B11BA56FB24049FFA8D9BA46FCA3B1EBBBE95B727A25867D9FD945549049944C\n      217688469899341D4D8A320392B7A7C7213940B646676D58279C352C5215AC6A\n      0BA0865DBF5F2C88C3A7CEEF66DD851F7C7754D31232BDE2C64E31FAA1989C62\n      11DA208F44DC98C8FEEF5DA2570E3A2717D24AA2002C8FACDE5BFB7C0C31DBB2\n      621F82B24151AF501EE795A79DAC1E5BCAC26340C742373DB44E88889D30E912\n      B3D47D694FCFA64BDFFEC864B1E0CAF69187C778B4AEB1CD3B12D4436F456C44\n      443515D8F3CCFA6A22FCBA230827B1972F950D8B07809AA40959D89B7904B505\n      66B18E133A01D088B304CC151A122103AC42B4AA107FDE4E0663672644E64222\n      8C74819C1A05E92027B00CA9332C2E04B2D826AA806E400C01401C57A4A8385E\n      8515352B173452F0AA3DD95A9B1FA593E964526315354A1AAD1A698AD95E54A4\n      A4F05528660DBBA9FB26385E9F34778011BA992FA8ADED1472A41FFADB2F75DD\n      695B47AE5269C541D9A638C81AEFF1CDB129200D8FCEF71BEBAD9D47365FBDE5\n      9FE0F57A6DFFF5DDC5C78F8E3A434BEB2074B1302EF1C4976A1B4F26B04F16A2\n      1AF6726BC8712911F1C2ECB37BC97A2E80142626591B2E3FB5ACDB599A4F01ED\n      A07F2844285AD8B13F786DA2B66820AA00E34D3293171CF9BE9AAAC1E6F7E1C9\n      EB22B584A3E2183294D8CD0E5EDA86F0B3F49E95B4DDA7C8FF507EACD491A21A\n      C2BA70013E90D28D2089F3B0DF0F1C210F2F6624C4422DA9DDBFDD6BDAB5CADC\n      C2F6EDABD5F34BA6CDFD4687BB6D5864B55C42464DE19384A94A6F74E9763045\n      D7C9B16BD5CE5FC82A8B69E156320CEE8AEB18CD334DC5A0B487B6D848C52D5B\n      CEAEBF05BB975559F895ABB5F38FE9A54310003CE690E9A0FBEA9FBA69AFE2B8\n      9B93C9F2BB9F3395A6A155341260086949E1128074B037CBA1A8D20E1AD6229E\n      8B9603A6A8B1560017420306A008190A1FE1A10EAACBD1DDFD5BBFFC3BB3D7EE\n      DDDB99595EF5B176F06A94FFD7DB9B1F3D72FCC2FD4D5BB8D3E57997AA466FB0\n      41BD9F1C8CFE7D774F329951F4C1B6B1ED9495AADD740A31CC2ABE46D83FB176\n      FA7C91320075D20E2D656779A09DFBD4FE6C18EF4C27A7EB9E134F2006796E75\n      AEEA34ABBC930F6F91D62FDFECFE5E6F7F2660897227B726CA49A4579884E819\n      EAE2A0806A5CDA502B20B99020FE22FB41F05C59EC34AA8D878E1E7DF4DCD9BD\n      59F2B3BFF0CBB5A6EF577C9567E1645A092A92F3517F28A56DD0CA1A5F77A474\n      86744EFD95C1F8BF9A4F79499D391312E9B506F69E03F555A59ADAA3674F9F3B\n      71EA8D2B57DEBC735B03F88E73DFB67FECFFFCDB3FF63D3FF8333FFF0BBFF9DB\n      FF894E92278F9D679ED8BE72F5A8EB581DEB20DBFDAE60ED3BFAEE8B9544602F\n      080B05DB8867138B612EA44061A84760F1C901C9AF0EF7DF2A5C1E85781648BD\n      14A3616C51ADCA33DE6545FEFEDCD117E66A61365C1C05D71B6662E7477AE14A\n      A7F59233BD1A769782C6F3DFFDAD47BEFF5B429A0405C1B23CDE06FF6A502DD3\n      61F1554D85074CB02483655110F321A20252BA39E2707259FA24B8518D0E3960\n      381DA5D11E59BF5A0138AA592A03EFD04A62E51907D0C3ADEE687CFB2E776570\n      F278DF9975EEA5DD2BEB9D271F214190DEBABFB37E7BE5B1E356CBCE9269210B\n      4758DDDBF7E8B5BCFDE4625E097358B2A9B0E1AE21783975D93A42988723851C\n      A7C63896D179A6D0C106389D4D5275F79A997409B043D7CF67841F9083976FCF\n      9F9C13C71B78E08D6836750A4106ADD1C53DBE429DD3269C4E1AA665B8D0050A\n      B9631B242C28048A9A60102D32A500280244EF6D1C2C3497590D326C3723A432\n      AAE52F67E97A11A2521C356313B0EA5845298ABF15B0589510F9D3DDB5E3CBEA\n      2E3A53D59FA9F14C4FDF98322FF08E57E3D928BCD55FAC2E871D37DCDA9F3B7C\n      888C67DD2BFB6C2061232780CB125457EBD1623737514E55A99042500D0E8B84\n      784E05FF1A8C9A5561D5805971C07C56C362136FC86AC5EAD1B37D1936FFEEFB\n      E26A2A63DBCA4861034CC6C309D82C569615221FD3A83EB3BBBF7F895EDE9A3B\n      DA8EEA093A29F4ADFEF521DC04DC3AD903EA574FAD749C4F6AE7FDE02916BB13\n      07E03AF0415F10015780AD6F04A82471ADE9CA9DCFBE357766AEF2C2B19995F0\n      DC75738A33395411946F1229F047A5BFDA7868D0010BC271700613E1E8EB0E95\n      4DD11A62BBDDB22C4F42244F473AE9871E159006627C00EE88289A118F52DF2D\n      044F5906498E447EEA2D09F8627A3F76525F172CA104B26094E9ACE011BC3E83\n      D68414476771DC10BD99B074822363362DAACCD4B8A9DA783E1EC3376B7B7EB3\n      DAEF0F714632CA007A34E6DB29CDB0CDB7D2E42DDECBF76A56D3F48BEAF1C6A4\n      B95778DA493C805EC0088963DC91BF7D714CC7152B6596529EE3F6D4C03EC33B\n      EF6EE4F6C8B2013599706ED0B9F7C8D66BB79C476973717EFF4FEF2E9C3F121E\n      4E7412D554B51040646722B750CCA2500F4E6E4AF92408FE282728E24AF2DAA4\n      FBEA182E43E7A6DBD93CF9EC31D3CE92228290CB55C994E1ED244E78258D6EAA\n      C0AA690B8DEFC479CBFD6B0B894305AD2229A0A9854398261B8FE4888C2EEEAB\n      AEE93C3DA79766181651010FA7CD1F8C6362815753CB7288E5F637B7A7D164ED\n      FC2108230A9E519AD169D5EC6B7FB9B977FF4DEFF08ABD58D31E71D70E271393\n      BBA16F2427324C523BA864DD7EF2E69D865D893497A7CFF143C7D30C98A6532A\n      4727B950B0D49DC2E288A16CB8684851E1C156B67BBFB3DC984CB6A603B57C12\n      C8753B62A20217F8D6AB07772F556B34EE0D6AF3CBECB9E742BBE6C41C3D2871\n      9D01D573D8832C484419C4CB01C8726A100F9C71F930433D1CAC212945792D0C\n      1EDA180B50FB6870E997FE63FF335746BB28BBF5C491F91777FA57FAC9B79C3E\n      7EE8EE2D0868F1E242918CDBA3D97DEDFC762DF8F1B75ED38944E3143C4FCA6B\n      A51AFD906519CF8E72F67F2F1FFE96C2095CBDEFC63552EDD194A7B9CF9CEB9A\n      7DB2DFA74ABFB7DD5C73D004AF60B645330938BA37FD535AFB9583E44F77B797\n      E75B8B55EFDAAD0DC0166156A47AC84A7D4C263C5B4782B150A12240A7E13DFD\n      8E678E1D3BBAB03077687969796E0E5080CFE5DACACAAB37AEFEED1FFDD16FF8\n      D087BEEF07BE2FCA9344658EEBC2FB8DC3C42AF931D1F495975FFEF19FFBC57E\n      983D7AE6E1A5F9059C54163C5719EC9968340580D2EBF7168F1C7AF3E6F57B77\n      3729F1B001CE24A71717BFE11B5FB8F0E4F9E3870E7782DAEFFDC17FF967BFF8\n      FF46C8A0C8630F3FFC477FFEDBCE4EFCFA975FFB934FFFF9C7FECB1F9F3F7E76\n      B1DABA7EE99539D7E52BCE6CB6FF9DFEF247C2FACBD5990891C7C3DBDBD359CF\n      A8FD223F40490AEAC0C652342CF23D127D3E66B36928D1E309F61B2CF444529D\n      A3A175715A917F75F2B19326DB95E1FCC0DF0DCCCCD79D717C64AE734B4EAF8D\n      F75CE11F7DE6C2D3FFF06F596B6D42746A328BDA1447234AD5750413C503A2FC\n      5706214B31573C002EA742DEF66B2E7FC00C8A9EBD083F08B694240427936B37\n      BF40A37DDD5E1AF6FACDD58EEA54C74404856D27A10A87DB6FDE3CD25AC9CEB7\n      E498F4AEDC198C27279F786ABAB5BD7B7FFDE8630FF3869DA87126B59FEBC9B5\n      BBBC1FD41E9FCF6857594C640ECF8C424658771A6BC46994B32AA8BE823AA3A8\n      FE040818654B6C15B17098EFDE333A228EC8664535F2F75EBA2D7CD17C62A560\n      C3428A384F1C6DACA4115D8BC7226C9D93229D903131414341DCCF01DC00CD92\n      78A66EB01E62800D13C8B45A127FB6398EFB79FB583BA90CF54854DC257DF320\n      DE8AF7EEC455D5B633194613E4498E25015F4639D7F6E47877E9A99ACDEADDCB\n      43EB90104726C5769E5FA90490750EEFA7F727C1CD39F30C536F72CF61CE091D\n      EE8FE337A43A8037AF6CE9AA8C6E46FD7DC17AA984C085658C721C0E0B20383F\n      0519823814D03D05601A580C20658D93993394B6EE74D6F8B116FDA1A7A22016\n      992DB0A29E69AB74DD035E9F4F15C746026FC87B1F7B2D7FF5C6E2434B5115FB\n      F0BC5963E3E5CD46BD6935CCECF5712D9E87783CCA26CE49D17C4E0081F46839\n      12ED62B301EA598B2C96B1E6ADE08A73E9CB97CEFDCD67CC393F85A55B542C3C\n      460BB1F48AE14502FE82B4FD762234B872601B93EAD9078970156E2981255D61\n      4E5B6007A692493F57E3D4C7BF55CCB242517B5CE45602F74C3D5F4974F1826F\n      6ACDAAB1774402C799DD983853B7A016A0F230CD814A2BB4C3141A831D479910\n      8365C25CA3ECE8033D2D8F1635123725055E08780AEEA4B6E8BA9ED3DD1C4114\n      234409C7AA765A93F160DC9D765A1DC820133DF0799043223CD298D5F70A17A8\n      A08B1BC5856BD1F681BBF74642429F2669800EC36EAF366D3CC3AAA704ECA69C\n      F3194BF3FA6CEEE6F9ADCBB7DC77C9E67C7BF4C9FBC1E1F9EC94364954511523\n      D29CC752F93844C7CA6636034902DE3F603E656988E895E246BEFFF9BE1305B0\n      3347477B871F5BD3D5242E429A97A535D8A7125EB708AF64E15555A1B55C6439\n      99D69EA989BF3617A3426CDD821C8BEAB310FF13331E8A584C2EEFAA5DD57A6A\n      4E2D3E4884584D43936E1C6315063B5D70925045F9C6C6D6CAB135BEE6446CE6\n      E5D21AD85B37BB95F9C57A91EF8FEF77DEFDD0841795D61ADA9C7B70E5A16549\n      F4ADE0BE1AC6BD2B371ADC524966AD9E94271E8F65CDD2B08ECB3284407F370B\n      4BFE166C39C21DAC4DC6D1EDEB6FAC1C6AB92C1DDDB94E8F9DAD553B3975940C\n      E4CE7D7DF94B444F49D31DEF6CB6CF5D288E9D9FB0AA0FEB1CEDF54A3880DA37\n      7681A7812523C4A61D3C91302853003FCBB144CA247A1901B3C10E396C7F661C\n      B06CC2D2F8E61F7CF2D2AFFF89D5D5ED6A656DA9F5E2BD9D9DA97A616D69F560\n      D773FD49BD4A92597396ED68F76315E79F5F7AAD4F7C5A1E5801C0F013082462\n      44D3C50AF991D6CA0F54E7DB793824D302187AEE8E981284438AF9F268F87A9E\n      D798F840A376D80624A352CBA2B2001ADFB8A37FCF923FB9B133B3BDB30B0D9D\n      8C8115BC7E637DAED6FABEBFF1ED97DF7CE5CAB59B49AC46D3F8C223C71E7FE4\n      C2F1B5B5F367CECE355B0CE73FD01E811A6CA240016D434769FA6BFFEEDF3D74\n      E6F4473EFAAD80616DC09205EE044F3A4A192EA5A2EC939FFDEC2FFDEAAF7DD7\n      77FFCD6FFBB66F0B1C5BA729B07492E5053E1416C571A255A5DDFA833FFEF8DF\n      FBB11FCF0BEBD133A7BEFB9B3EF4C1773CB37678BE3FE9C5A3A915EB4B576FFF\n      A39FFFC5DBFD116CBC7FF9CF7EE247FFF1B7DFFCF817772EDDBEBEBBFFF157BE\n      DC8BE343F585E9FA96D661FD50438DF6BFCEEF3C168908F6518E354CD4D9A245\n      97EA6D488410E38BA26A2C9459CA93DD7870C56BDF1C1C60C3442EB0B2824AD3\n      A53F94559CD5E4174E3D7E6836BD5957CD098EC7E92A9D26D3D576DD91C59B83\n      ED892B17D756DFFBFDDF69BFFB91A967090D19E781DD2B023E4C69D8A3856D88\n      0F14D8FF820763D3FA0369F31249958DEFB87ADE668F385B088FB088015831AB\n      75FF8BE9CE5BE2E89169BF6715A17BF2C88435F9B4B0ADD4C83CBCB1616F8C82\n      278E42A825B9B9F3F21B0D11B8F5DAFEDEF6CAC3C7F87C2DD44388589544EDBD\n      F89AB4969B8F958910822304F1143BC7B5D3B0EB87885D43E9F9D25F0E35D2E1\n      09B07230AD30A2C84932CA76EF15F914F99C116EEC46370EA6F7479D0B2DB590\n      1B22012E5B586AF593AD62AFDB5F7AB826F98460BB5D15B23A5729705FF1C0A4\n      DA30B40432199EA0E719921980F65B53AFED5A73C4CD03D8B4F9A89FF6757E9F\n      CF6E161553878B5080BC058F4B0D7627A3AA326EBEBF4217647A8786FDB1F704\n      AE4CFFDED2F060E83C6B0BC3CDC56227E81EF61E3E38B8EB9E8097E914D72BEA\n      06FA6067961311F7209EF4751A3199A658CD306FFB665AE51B810D0C3BD6F882\n      7B54BB9CB8D25A749D31EF721ACF7B73D1B257F93BEF4C8F3A3C07724A0A2BC3\n      9AB5B1506D5C0D811D7258FD7D36FCF8C5F4D56B0BA75B6913503AF7C2F6CEC5\n      9E5FF3ED63041221BDE730E98659E61D2F9ACF3B49302299B05845A1136D21D0\n      CE2C8F1CE0760BD62707BD74B6F4038FC5F386CD980589816B6970A2D8303408\n      E1060D1ECA00551EA6B0BF9208C72FAC412C8244E8366DD9B232C03799887A29\n      0F8D43A5566692AA54C9194D816903F9B3FDCC96CAD6B6A1226AE5DE695971E4\n      F82B3DD6931C0FD16892EB59AA90D25B8525CFD90000FFFF4944415436309954\n      EB1C5830ACDCE26DE590B2C86C5504AB9859CD36AEED4F0DD155D55AB481360E\n      B7229CD1F289AC79AE571D1D1C00939E9B5FCA7402905452990C54FD7073E677\n      0BD748ED6005C5C65149B26DF5AF199A793C09FD822490894FB3CE3B61FD4CE0\n      DA136EC5419E3BF1DC8D935B57EED43E58ABCCD592CF433695F49C67B2D0CB6D\n      2D211102ACAB004B40AD6D1CEB15CA686C89451D716D5B36DB95A3CF4EE91E8A\n      E298C7A2CE438B4A4C13862AB4000E28B626C16292D13515BD9EFB452515A996\n      61FB034BE4F9604C329F77302D7394F223714CC72311D3DEE5DD625F759E5ACC\n      E7666FEB26975513EC73E0680001EB0D7EDCDBD8821F174E1C99556649905566\n      9EBE69D2595E3D3C37DADD6C1DEAE42B34EFB45C7F8DC2BE2A86800A53600D05\n      0BB4DF7BE33E9B2455DF8E2CDAB8F07C66CF6B120094A3E108DF880FAB5401F6\n      8737A3917E4A969AD1FA7AC6A3D6D156B2B7C937B6F347DF51ADD5F292F8EACD\n      6BD9ED577C4F8EB23CCE670BCF3E5FF887525A93458CA34678D22E4B25659B42\n      4A4216585AEF6285A7648488EB55597E454824F0793C6840C39321A27266DBBB\n      7FF8A9CFFCFCEFB447EA48BBC31AB5CFDDB8037FEBF97A7369322182E58D2A49\n      237B96012CFE9C903FF5EAC52B5432C42E0AD696282C783973BEF5F5F5E68FD4\n      E71F2AF248A64313BB5CFA4A282E6015F5C3F0C583BD7EA55667E269DF5E9510\n      69540A4C1282BCD4955BF27703E7C7D7D79BF30B6B34FF968F7EC85E5BFEA5FF\n      EF573FF4CEE7BEE985F716BCD8D9DDEF1D8C7EF7131F7FFF7BDFFBCEA79E8E27\n      335F8870342E14E23D53023F568E91C2EDCCDCCAC7FEE88F035B7EE4C31FD688\n      0615EC0808EBAE70933891AE67847CE9F2A5D75F79E97BBFF33B8E1D3B922529\n      3C276572C659E9D28437261C07FECE2B6F5CFAA5DFF80F2F7CF377FCD0F7FD8D\n      5A61061B7787D31EE44C07251A8AFDC1EC9FFF87DFFECC9B774E2DAF7EFC377F\n      978BFB77FFFC92D99BAD0FC67FBE71FBE53BB70E2DAEC4BD51B7B7FDD8C3C79B\n      D3E959C7B7FAC3D3AE1758B6457898E543627688DE30E900EBC3C4CB888FBA51\n      3AB5CCCBDDE80D088E2EA41E0B8F9F01F7A578BE9D32FDA4EFFCFC91730BBDC1\n      F5162191D79C44564DBC49C6EDC079B25ABF39D8BA11D046107CED07BF26F8FE\n      6FDE6FFAF59CD8189BE85F4E4D940C10153729217FA914F71789B0AC0FE2D1E8\n      DBA31645D96DF5403B00E106B1F12C32BE325E7F8907AE63CBFECECDEACA8268\n      1C2E3287A29DE1D40A93D9F52D01BF3E7D8856DDF8DE5EEFF28D854A7B3299D6\n      8EAFF087972333E169EC4CE39D175F92F513ED0BF329ED199C2C915652E06996\n      D3149808EB58D32588585991A0734479B9A843084156476977534D0F08C96C8E\n      94810CF3E98B9BC98A721E6DF08CB931248E9078428DEC83CBBB9DB586BD9029\n      9660E906DD4A916B2253C66E7B9B713B4DD3A2007E91096673ED4E77C238CE9A\n      4B0D861A5739CB65B81DFA597570234CB7B85304693A2EAC3CA742C10EA74590\n      8BE231C3DEC9452CC797C6A44D2A2700409BD9CDD86A35FC05DF84D1FE8D41EB\n      68739A4EE2309E5B5885FB9DBEBA27F738DCDBC8E62353CC923C056654B610EA\n      B25E441FF8A55048234C14103F2C00DE3605A658CC33A1AA91CD3337B676DD6C\n      F51FBCDF7AFEB08A9115952E221A123D1AB699516E41C4B4C57E31FAA3AF246F\n      DC5E38D1C81B514A951F2F0CDE8AA9A52B4F38F9BD78FA6A4221CBA784CE25AD\n      F7DA45273629E756A03005614340C1F250E4229D9B7CEC56FDFC32FBB6635327\n      0EA69251948696B9C6214041006E4AD41A2D85CFFE5789709559225199DBF158\n      15C93990B1F8201329B381F2E7C534D391825FA59E71030EF91A821D505D4717\n      225D36DE1911046EF8CAA0D8661C331FCE33CD128D16EFE8BDCAD1C3038302E1\n      282F09EB098BBF8209C08A1E893DB80161037CB23BA2D2A440FEF4D82A74EA77\n      B8DDACC7D362D6ED39F3A2D9EE4CFB68C66B2880ADAC73781ED877E1186924F6\n      E6090D4F395FA7E31BC62A2A5CC5CC60D77FE5D9B67B0616F09027C240BA75F3\n      5C269D5B87F76EDC0B5E68072D27BB08603DB51F69EA6C06E0413919247227AE\n      14458A5A769AA3886B61143C783C1E372806D2B7A79F8921E90246E4CFAAC689\n      4E568C3391F00250804423779E5A809EAEEBF092F6F34A22135D8D5B5F7FC83C\n      C6074C37F81C36A2B8800F1499CED864688566F78D5DB2972F3DB596B7A70F26\n      8C71FA509745136CF673B0CC0B01AFDB5F3D74CC701D059174023E03547BEBC4\n      9147FBE33EABE5ADB36BDAE6ACD3C92CD4331580DB4C02D7CD1CAFE866BDCBF7\n      9B5E73301934CF9D116BA7725311C46528CA98A017B1CDE131D9389F86D3F3B0\n      C207B7EF5951543BB1F0FFD3F5A6C1961CE79558AEB557DDF5BD7BDFDEAFF70D\n      0D34BA416223C05D122942D4429923999664DA8E98989035E1B027E6A7FDC3CB\n      D8E11F0E4F84359EB0ACD1D89425D99A18D1144552DC40122080EE4603BD77BF\n      5EDE7ADFDD97DA2B332B9D791BF4BF09220844A3D1EFDEAACCEF9C93F97DE7A8\n      67D2B97DB39508F4FC2BDC30948833FBE3E98377E2D1FD65BF321EC6F0C88A73\n      E61942D751A994FD08AB5503A9D2C5730834F5109F9CFBEDC18FB27675AA8E9C\n      DF05C192CF3B27B573C13C99161A941539C1060CF9BBFFC3BFB8F3CD1F9EC2EE\n      F1C6E220A8FCE0E68DB6E35EB62BF5B8C878469B9EC24E3E4D62C3BD0F8D3FBE\n      76FD2F2951DAC0D5112AA0089099B07F505DF80F17964F118164A4AA54498C0C\n      0287299AE228B9D54D670FE2195958265C1E37E4028CA0AACD9E2BF5496D029F\n      38FF0B66FFDB74044BF1EB2F3CFBC66FBFF12899FEF0BBDFFB83377EA5EA6085\n      A4EAB31AC8FC9FFED59F3CF7DC73674E9DCAD254BDB8248EE17C5848556F8D5D\n      399B3797E37DCBFBBBEFFC60C1B4BFF8DAA7B22812FA8445B74B69CB965201B8\n      96C5F7EEDEBB73FFC66BAFBE7866E3284620963C73606E6AF3CD3AB670AA5638\n      C4AEFDE6F52BEFDDBAF1C6577EE3D4B1A379B78B9244ADF8B82C402AAAC25240\n      F8E76FFFF4AF7EF4F6175FF9D41F7EF56B7C767F389C2935BBD719DEED749EF4\n      875CEAF185EE70FF54109C4CF809C739B2B1DADE3B84485F4A27059B40B08FCA\n      1DA8FF41AD3D57CF8AA80AC272CC6785F37E3EDE4A33CE11C373BB68062D4032\n      C0BEB4D2FAA78D95C5D16CCB8713601D1D24B64B7FE66927B85F739B6311FE98\n      8415DF7EE5C499A57FFA0F7BABF58061538117864F0F3F9E3687E2B9C7DE7C7A\n      507ED42F039F02E11C173FEA087A7A3CAAFBBBE5477D35404914C5CF855A6FA4\n      2F467766FB0F5A9BC7A6835D9E8D1A8B6BD25BD79170E55849822CE3F9BBB7E1\n      5ADD5F6E40C34AEF3E49EEEFC388559E3D899E5D1966E30AE3749674AFBD47AA\n      271B171A89EC423D2664814C55312EAC06AD6C00ABA181701E7A05455C607DC6\n      41849E109ADF60323EEBE5FD1D2212A4EDE34C6D69712D7C983EAEBDBC12208B\n      0CB5C5605A070A99D277FAB6629DCF37623AA44C1130534A25340B3DACA7CD15\n      09D6E78EEAE9E79217DA818F3AC9AC986CC70BD526D80C1311F9F982E82AA297\n      52E8EF5D1DA28EE90358682F7417505B66C38568695CE938BF29E98249EE07BD\n      47FDE0596A2E02F898A40F85BF5913EB65F1806EE7D736578E47B715CA137353\n      E6BB0C5CB5C1284F9D74046156B851C443A2C09515424F8BE85415A4C7C991D0\n      06D436D117E6149588C836C36583539CBB31EE9945EB0F5F317EF914CB75CF73\n      09F53C9F6E7DA1EADD8739621411E3A018FFCDD5FCCE5EFB58B3704729CADDA2\n      1DDFE27132ABBDE2E21C4757D3B4071D1614EEA4FE290BAEE8E34B4C7C6EEA69\n      2B43A71BB00C036350ED7FFF7EFB73E7B24F5412C482C894041554384C8FA22A\n      CDA494A0FAC100FD3B14E1EC57D611A60C49B361AA3AA1C74719890F73BBA4EA\n      A30B0113A176194E415E81BE870930A712C5FA04519AE5514CCF958167A55742\n      FE483D15539B4FA87F5DB0382F9976CBD563E93A4BE817413B425BB52313E280\n      1A14291D9C96BA6195042DC54A796F6768480FE0B4BE6602B732D84ED874629D\n      20B54A75F0646CFB0E439922D1CB1BCB099DA99F8FD5EA578F96705BB198FB45\n      FAA8B44045554806677059D65EAC978B8504BA21105027525CD62D1A0F16BB8F\n      76FD5F69393E64776385AFCE332DC9525BAD6E4BE71C3991CF8D54E84850AAF8\n      04D767F54CDF03A0B2340B3A36C67F97A07D53D212BCC2AA471A7939652653DF\n      936486361A20B9E2F1C55D995D55C8E017569E5466AD37368BE750E699015A44\n      99008E9E772E8623381AD01CF6EFF5CA9D74F9D20AAB87BA8B501BF1A0A73794\n      EA6561A24165EBEEFD7A7DA1D95ACED84CBAC2CE9AFD833D66A296B39875C7F4\n      941F564963F938206688679CB14AE9E9CC1AED48C89F5CBDD3361B3ABBBBD6F4\n      4E9C4C886519BE3E1ED7327D2E02E7C584EA0B773DE6174FC6E3CEC1D27A0B3B\n      EA7BE7FB376EB42CCF38FF7C2E284939DCBB1B753E80E5CC83E67818562E7FBC\n      583AEE9AEB4AE0A6E68494AE2262481F6EEBBF74D6EE539D376F5FD128A8B110\n      E85652DD1EC1F4A5B5FAC68AA50985815C2261956EFEA39B3FF81FFFD7A2DBBB\n      D06CD680B15D5DFCF1B52B176AD5533420A96E7AB61C4895E2CFCA5901A6C4FE\n      F6EEFE7F31EB9B1C04C04D008B71F192EBFC93E6FAEBA6E25823B362FA2950E4\n      7A40011531CDDC5E943FCEA6B39235ABCBA620CBA6F4C550111959AB42C5AA47\n      D1C1C4FFE7D3EE5F4C7A2DDFFF47BFFEA5A5631BF7BBDDFD07F73FFFC2330BCD\n      6096A845E52A7EF997DFF9E6D1E3C7BCC0EF0F0783C9382BF2A7F935EDC5D672\n      A36DAB6AC1CAC030275EF5BBDFFBFB05C37DFDF20B6A0B443C55FBB13489D285\n      16A096C436321FDC7F78FDD1CDCB1FBFB4E454F4EDBFC8BB657CBFB74B14C0CF\n      8A6395C5E34BEBD576EBEEC1F6DD07772F3F7B6A7171C1E18A659721CF33AA94\n      3DAF975694E67FBF75E7AF7FF2A3AF7FF91FFCF2858FCFBA0F3A797A3018C7D3\n      7478308C92BC3B9D1CA413C337D64A7826156B94989EF9796044520FF6E65C8C\n      65F918B11D50C63A7E0BD9FA2852E4306758B8B23A06E24AEFF02113B1A54FEF\n      B0EE01243509BE7EEAC41B08D593B48BD143039D18660EC157968C593A7AC308\n      6C977C1F8D888B4F369ACFFD937F1C3E7B86E4DC504048E6E934BFE896D16397\n      F0171784F2A3A866F991E9CCD3E3D15F8C16EAFFA8FC45578D9E45579C2A8720\n      31EC5ABE9DDCFB99BB7A2CC764FAE0ADC5AA532E3FC39949C9AC844AB6BBE69D\n      BDC1E1FEE24ADB585D90593EB9723FBCBBBF7AE919F8F2E951781828209C849D\n      ABEF1A0BE71ACFD413A92802B2B9A51E8D12F9CCA8207F9DDA0BF33B4DAECD72\n      D51F41588984A968BFFE05A27B2259C40E9F906C2CD44AD47326906E93C78FEE\n      544E37EBAD9A9C69979FDC071693E28338DF4FFC578FE495114C13535A732B01\n      CE4AAEBD43C57CAC91C13253B548A9153D5251221EEF16BC5FBAE7951A4C6862\n      183CE8EF1D361ACB2C743A6F3EB226D051B293AB826E6111D9A142859EFD7262\n      5FF2415C0F6F872118B62F2E2AEA9EDD0C0131AC330B3C2F1EED7CD0A02B75BE\n      318E76C57AD6A8AD85EF14E2C1D0C07CC261C4AB31A393527F303DCF8C9E5212\n      6D2D434A6961ACC517522B1A5013AD64A4A867254C6BB9153A65FDEB97D097CE\n      692374FD3E73A2347F693382308B639C2B926F758BD1BFBD96DC395CDE68317B\n      90D1D8E68BF98D62D21B545FF569E0940FCBEEF5692D6F423FF75FA77239E142\n      C1B0AB1421224C8F96515542CCEC269B6EF7567FED39F68CCD39B072CAA9A20F\n      C2CD0D25024B2357B58D30F3DF0984F1178EE8F12413D31A559F90E92C2FA814\n      61206DDDDC224052A28423B5196AB8EA21F5F44710A73433552DA0E71D70A630\n      0D9CBF17C6770A8C0C55F21807092B33A6DEA05A458612374A75510CF4D6D18D\n      E5D2304D1F694F19F5D2190A95BCC78655ABBB591E4E06EA77FA4E2573965092\n      92E97E1950048EEB9CB6F1FD59B5560BE1342DD2D58D950C24D21408EB438412\n      9776660E6F86F2907865450F875752FF02C29B90FB405FCE2A99AA7324FCBC9A\n      F9B79CFE5EAFF9AB1B3428F9ED61FF60109C5F539FDA865CA937064C2FAE7233\n      669061A580981E2EE452935FED2561E746E2CCFE36118F947294F255563BB258\n      88890242B50968A6E72B0B92696FBBBBA2B8AA588CCFAC3C6C444BBF719C3F8F\n      8B8AE7899AD4F90FB2544F633896831E888BC18391D88D572EAE8A5AA8F8968E\n      2F9F4FDA49DD2F4314258EA37CD01FADAF6F2AB5A4D3E26949F7E44177D07EF6\n      786FEF71CD75CCA36B61E0DAD51A3669CA435554782E1CE228108D1E6F77B61E\n      B7EACBE3046D5C7A9D3955DD91AF74BF1084BA3C95C852DF55DBB0A8CA642818\n      8CF2D1EE13A7E5394B359045C5703CD9DBAFAF2FF1E575DDBEB5771876DE73CA\n      03A714D9309C61D4B8F82AAA9F03B45616536E46985590968304E8F0031DE1AC\n      B6F01C05E7E194504FD8CD7791352F77A9765B53A0966987065981427DACADEE\n      A33FFE56F7FBEF550373253015F2DD0E96AEBCF7CE27EA9506B459697858540C\n      0587DAEF218F794E9D2B71FCB58347342399DA0F223B6D90FF6879ED974DE215\n      9302A755BF6A15EA81EAC387084F48ECEE3279A3E8255976DC596900B76DA3A0\n      1C219AC7815D481BF6D3BBFEE2FFFCE8DE7767935F7BF5D5CBEB6BC8F7B7763A\n      66963C7F728D9505F61610AD8571F1BF7FFBFFCCF26C3C1E4F93E269A3E7D3D1\n      F68AEF78DA8843D1645A0F2AC071F676F61694083B7E54FB8B28ED5C75F32CB7\n      F4B1928E27CAA47C78B07BF7FEBD9AE7C9AC30D4AE636A211451CEC03CA6CF46\n      D8B5ECDA42CB6D564514BF72E6D4E6D1A37C125958679915EA4D0352CDE4741A\n      DD8C7BDFBDF6D6172EBEF2CAB173BDB0D74FA2699846E3300B8BB410FBE3E1CD\n      EED6F2D2E22AA54BB3F4747B8118E0778632346082CA94892928EF97F9235114\n      00BB6AA70A99CA34A7C2F00C77AABB08F645F9F7F1F06E1AA945A4392DC097AD\n      C67F76E2C4E97864F08C31FC41808F4E12B3845B1BB54ED8FB15CB69F8F6CFE0\n      28B159CB772FFDFEEFBBBFFC4B420FA33389E1FF7FD6A91B6544A94F923FD27F\n      F3565158C25FF8AD89F9AA51A0279F5E0D4A6D183717904F57549A922C119B0D\n      BE0F767E20BC16AE1F89EE7DDB4977F19197B8BB8A5097E3596205D5A888EE3D\n      29D3C43ED6A6CD4AD90D7B6FDD324CA7FEC98BB92B5016D2E1A4F7EE7BB27AA2\n      75B195C11EC4C8CC2928F45C4C4E02E8AD9BEE02D4A71A62DEB99317549139F5\n      7F4A266BB42AB0E297091977E168BF94AA8CE8FC657B5A11BBC32C99F8679BB9\n      ADFB252D7D3E98832E1EDF8F82F52A3A52A6A06F7042E63EAB4C0FE7E820265C\n      22C5C5B51561565A8E2580622489828F68AB50E5B37ED4C98D01E634EF1AE140\n      B6D75747B71E4FAF8D17F93A407681B8E261398A6DB598DC2478CD2E56211C06\n      E31B09A98AC6598B8FC2C9966856378BCDFD72600DB647ED95B55CAD8169B8B8\n      5EE7D934BC33063B26C9AB21C01192831CE582AB0F269E7ADD69631DA814E13C\n      1557E7E35A962AE4A41D4ABEA004725A4B8C214C2BBF77C1F9DD9798D0D199EA\n      7199FA2444E90682B32C8431F5A533CA077F7D2DBA37DED858E6B4A7D0D3E0B5\n      E28322ED4CAA2F57CA0545B7CDC3B767B4636337F75E23E898605CC96F0B58AA\n      54EA19166963C449F7FB07B8EEB6BF78A65CC7905394E3D4CC38126E666B514E\n      33A1AA3337951AFA7701E18692E2C8B58C86515AAA48972C96455F78C0924A09\n      F3322A74EFACA0B28E2B36848C8E08C9696196B6EBBCD45028A5EDBBDE9D4C3E\n      883072D4C2CE758A0750B247CF68601D4D9AA6B14590A9DDDDF4559B6558AA58\n      526DA80515FE9794798EEBB9F6643810B98252C35FD675B5BB330313BFBDE6E5\n      EB91629FE35BB3467D61207A8A132DAD2E33A44F8BD0FC308F436E4566EFC6C4\n      1A3BAEF05359D235E97CCC949569699A0A918991B34289C746ECC7E687C6A437\n      597CE338AA14FCC3EEE1E37EF5DCA6699704664ACC2999EB14358643ED4C2DA8\n      AA9D4FE728D43F085014C6CC1695FCEF797A9BEB2CE54FCBEA469389483B26E8\n      803F83428303852D20BBCBF32BC8631566C6D14ABCF4D567E0059C3A8E95B9DA\n      5F073125AE4892817E2FEFCF7AB70FC161B1F6C2111E8425E390CC5D1B109A77\n      289B2C159DBD6EADD572025F1B5C413D77DBBBBFBDB87422216838DA5A3ED686\n      0B4760A30D1C24CA544940A116820D40628AC16CE7C3DB6BAD058EB0BF7E8E3B\n      CB1974DCC0D25C557710414C5CF5ADA9C02597198496DAF5BB5D3E9D06A79653\n      9719692A1F1FA671E89CDD8C9C6A6566878FB6D2E28E2DFB7E4192D1205BA8D4\n      CE7E02DAE7F4C9909908105256D3DE790AEAF5C8A0927D74DE2CFA94CBC35FCC\n      D1ABB7E6E805A99E953601D72E01A048A5A78A6EB8FD6FDEDCFF93EF35064AF7\n      B75D99283A7C2D58FCF09D773F5BAD1B82C6542D1EB66EE926AC54E714EB39F7\n      0F19FFC7D1E0A033ED41E863F97BED235FB57D27ED4A186D542A8EC4917A3BD2\n      AC416B87F448E21F98E6DB45771A8E2F3BEB4BA5BB60A1051413940F081E0323\n      192657AAC1BF7EF2F826E39F7CF6D90B4BAB4A4F5EBF7177A3527DFED47A2459\n      4EBDC787D30F6EDCBBD5BFADDE48DDB2EB414029C9B2621E3F06923C0FD33807\n      4A62536DA00CA44914F7297413B78329412017156AABB5A26A5406F808C99147\n      02C3F68BD2A6868B71839A6DC30D945AE7BC1B4F27A548111AC561278E5D004E\n      D5974E5F387F64B16D0AAC14704AA5C9C09AE377BA87B7C283EF5FB9F6E9B367\n      BF70E9D5BBE35E328DD33861B922FD3C43707B3A7AD0D9B6203856F19A48562D\n      BC7174F53F7DACCA3F9AE6C924CF13CBDC26728B65312F1D4E3C25BB118F642A\n      48B94AAADE8097D5C56FC9E90F0F762CACCDC73997BFD9D8FCA395F5C5F0A010\n      19CAAD6BBE6CCD62BB04FBEB8D6E387CCDB6973CF3A6110DAC2CF0EC335FFCE2\n      C6577E1B580E2F72809F3AC5284084DA9F40B3271D48A8506FEEDE81B16E2F9F\n      3BCEA07960F647898BE5D35B44F41441E70DBC00E689DABCC5315F1CCADDEFA5\n      66D3699F07FB3F9ADEF9A1B3F41C3D7939C71D484256FA0843FB7032BB7B3FB3\n      41E3B9D33AC4E07EB7F3FEDD85234BD6857569723209C377AE276871E9636D66\n      8CB5B74A612A762F05CF9107DC3910C2B97DB33E0BCDB86E0051F5B09C0321CA\n      75285041A2A9EC6F4BA5D355ED94C22A9B6488B2EB77D029BFD8ACF1905599D0\n      7338A51BDECF449CD59EADA6EE00175C9F8E6243FBE7979A13EA6EA214C0C4CC\n      67DCA9A93D173392125548F768BC55D48FDA6CA3CB25377B6BC307B1B3086D9F\n      446F87F90D6A421729C40DCBA4BAAB2AB91872EF45C45F2D4AD6746EB5A2FD9D\n      CAC7725617EC81071ED8E8D5BEC34E749E3CC9EDE448EBB9C18753A3360E4EE6\n      93272C7CDBA9154B8288319BF58491E63CD310AD7DE5F4C43FD0069F54EAD14E\n      8B405BAD7293288D92067949F306B34722B4BF72BAF27B9FD00DA23AFF41D577\n      3D64CCE70ECC333445BEF4FB45FFAFDF4B1F4ED6373704EEE7F64C87055D2F8B\n      8369F5D586A8A798BBC9F522B9C125C8DC8F4BE7A2952BEA0C6D69718805D240\n      68C258F4BEBFD3F8F869E3E565EEE7EA97CA4411C45CF14E3BB100D779AEDAAA\n      4F9A73DFF6790FB25E720AA30CE89FD7A6DBD9178F4C4B819A81D9344A10DAA5\n      CC7B4C28AA2FE93CC4892B565AE4AAC2F20AF22CAA7E72E222329874C1254C7F\n      B586AA5EB55F2D7FBCD7BF35C670D92DA32C4B7349C605CC39B16C8749452312\n      47BB0F60858258C9106C9B4A75221412327642AB02979C66D651388A0B90A584\n      BB47177432C9DDD4378DFC130973336BEC26D78AE6E2D261B1E3564D3FF04A5B\n      686B3462E8F6265838B3E6F066CF9952C018AF67C1E540AE29DDAA477D2CDD88\n      2E199E96242DB185EE3651E199AF05C0DB673B79FFA7E3E69163C69ACCC1C0D4\n      43AA40271D316D0956E8CBF904A10895141735B51572736232C2AF5AC3776303\n      18E6A7D360A322F4B32938C9730CADDCD52D0D948FB7A2E81D6781B552B2DD7B\n      6E70FC2B1FC347EBC2A8E509B230473252E40EA352F643F8A4185FDD4B67F1D2\n      4BC785CF61AEC7840BC890EB089D7665173B3336898253ABA1ABCA5161737BB6\n      CF87FCE1C673A71FBEFB78B579CC3EDE4C568CD2095C198852244ADC40613060\n      64EEF0DE2E555486CD1A478FD1A553DC69EA7B07AED828513A1CC21CC0303596\n      8954622A52189586717FFB7065F304A83B11492BBC60D7EF294A239F3F82F912\n      8DBAFCF1FB84C53C11C433F63BB7AB278E7AEB9F94E0882E5338CAB59F724D7B\n      116BBC439A79E92C433CBF5C474F8DB4E0D3695C6AC3648E03262F885A936A43\n      095B559437AFECFDCB3F4FF7F688EBB59C85C6140CCAE2EA927BFF9D5BAFA2D5\n      145B63BF5C47F909B58E2D73CA52332D0037BAA5F37F15F91FEF6F75817CC335\n      FFE346730193297160289FA176C329263802301063F418F59A6AEB59CE8FCBD9\n      5E32F9B8533B278167EBE6C7A03090B015B2DDB6C0E38AF8F9C39D9D61F2F2D9\n      E7DA5E6BAF3FE88C7A17CF9E590C82ED647865B873EBC94310CA571D73C3B64E\n      BA4D078299C8B0679471025366FAFE411C8E92A2516DA459D19548AD404B2452\n      3D6740694EA156A81621C8D3B1CB4507CB5B359860B1099D1569015624EA7796\n      B209A88FB5CF905362339163C47FCA07939A3798943BD968D10F2EB456D6DBCB\n      8E691A9902BAACC3E36E3C9BEC1D2E571B479548E3940CA76999C548E09C29A0\n      B911F7DEDFDF5EC5F66937F0021318DA3EF1BFF75CA3A022958765D933D036CF\n      B68B3832B4396CA5D0C11A0A790AF5AAFCA4153939AE7E331BFD3C1CA972E823\n      5293E91F9E3CF1C512F85932A4C64418DB98A2223469CA2A6612D1162727379C\n      211DEE096906FEC6F30BCFFCEE97F263AFE2D4C398C554E763D8A55AF009C7BA\n      B7CE013192C30C1021035FAD965CED42ED52AFF58DA6C9F3C86F44D9FCA24587\n      D66B2F023D7CAB882E2F950E1A88E16E7F1C37CF3E2F15365F7FCB5644F67833\n      6FEB1955927B077ED954F4F2DE8EFCF0915C59282F1F8BD44E7EE71EF8C907E6\n      A935E3D5338A32EEBD7DAB3A2EAA9F68B320494ADF60BE5546201F08E83063DD\n      0C5A88EA194E28AB92244AF6C1522D5F6B9E2B104214E9359F53168F59F8C82A\n      279815294456E266B7A7719C365F3C5A665D4474D705B714C9E59D379353A72E\n      F2E3432986B470E623A3DA948B03C230536BC11B98E010E2B6350BC6B976E44F\n      6BAAACDD70C6E1D87AD61108BA69BB1C4507C95675B36624FEF0E7B3F27E5141\n      B558D8A1EC981490CC301BBEFF1967B270581FFBF8433211DBF03525E56AF94D\n      CBE830EF9259E2A4F3E1AC619E566BAE175E5B5A0F64EACC768CC9BDB4963901\n      331F59F778DE8AF25A58F214863A05501224758381F6B82C0D45A32D037BEA21\n      58981AD885722A23E7D3A72A5FFF8CC2246DADA738BAF6EED0BDEAA4A41363CA\n      096C3E32277FFE03113EAC9F6AEA665C551E4BC23E44F1C378E9B55AD19A2924\n      91A1C9DEA2E563404E70F52D0A5B517853FB272A7D557AA5E94DB6B6D1F6C4FF\n      F2C7E5513F82B1ABA48B2A2FBACB05950AAC758342F9F43841111B3A37C1D0CD\n      EC3AE6CB42DE8595F5FF06C66F6C28AA88EA1EF4D46FCFD593CF7B855295505F\n      002B84940220A1343BD40DDF16D6B64BA814A199982F06F66B4D61036BE28BEF\n      6E4F6E8E31AE9B324FB2AC9466C6D0AC046A2792BC7095DCB024345155A0401A\n      537D37C5A99E4E342632F1D73C5CB272AF704A37F112B65056ECFAEC61CC19AB\n      1EF7E82955E878FA24CD1F948B4BAB87B327D59667FAB692FCDADF8F98B9981F\n      FE76AAB3873D458F4B05D8275DE3B49D55E35C8F4762DD98A4DBF3D5EF2F0C2B\n      48EF180455AD1783D239901DDE7D73546F2D5BC7690ABAA6A44810BDF1B9C5B5\n      46D2DE6D12E5DA76897B3AA997C690E3FC261DBD1B07D2259F4BDD15AF54D55C\n      BB402ABDAE60C03198AAFC3CDC66B39F925ADE4CE96EFC09B6F25B97D0B2C789\n      2352C328F564B78E6F790A840FA2DED5031EA7CB2F6C960D9D074E45519A3033\n      29859E31C6FDADDDE0680BD50D7D89424C31CE07DBC3E074A348E2B813AD9E3D\n      2F975CB1E831645368C92CA184A7A95A8B16B83B9EF4078665DAB5BADD5E05B5\n      9592044C8F269758CFB5E8F603F5B758611ACB68C9409A3CDADA6AAF1E75AACD\n      82F0C2645E148B9BF7A58393F3CBAE5C90BD8362EF9E981D52DDD626BA93BDD5\n      4B97C8C20B12ACE98585C2CCC046F95411CEAD79F4CD0FFE286E1062F8D191D7\n      D36E4028D4522A99A9DB9F984650C5D7EEECDCF9E36FCC6EDEB372BE525F502F\n      0E4FE29092EB75A77F65EB0258E860241CF45C96AF6238ADDB639ED5A779591A\n      5D603FE6D67FD9DFBA56845F3BB2FE15C3409D43A3B21225B065C015B50949DE\n      91E4FE388D71D6924151E0031BDD0B7B9B96F532718E39760744EF4D0E497BB5\n      1F4A419D304357A2FE9571F7E4E6712B47DBFBFB674F9E5B5D5E3AE8ECDDE93E\n      D91E0F172179C65B7C09675EE0AB7DCB33453FED9183EF8D0EC2C0987AE4706F\n      70AAB457ACEAA32C02F170D5919B7EA5416D6490CC32182581631DAD54033D27\n      A6968F140C8E9231E1C29889C371B8C3590C8945BD719A0D41AE1851C371A081\n      1EF3B192509BDCDD8F679293D92C1907B6B7B1DEF69A1EC74591EF0F3A44711D\n      2C17961697140F9F2ACE0243A4EF7630A0777B9D07C34385B49F3C720A8523C9\n      A24FBEFAD2D7B73BA1677547B3A4280F0D743D9FF5B3CC290D8718BA89A928A4\n      89231BB68633DE68BF93A53FE877A76A2B401A08F1B9D6E2D75BADE7B204E4C9\n      00D29C3977A8643CB5655A718C71812779F1DC338B1CF59F4459D06AB596F199\n      375E059FFB6A26AAA6CEBCD4AB1D2B1C54C2D9AC08552614472A432433001D90\n      5260724962202C80DC791F19D72D94BA03FE69FA019C1FCBA99256725094A569\n      815919ED0E0E06D5CDD3069BC2CE0385E9639434CEAFEA79A494A48E7A3685A5\n      AADA6E777C77B776EA78B25AA5928BABF70EAF7DB878E19473E9D9CEDD2DF1C1\n      F6EAA737CB6A2E915308079685C523255633A72582150706B0D0BD7340B165F5\n      51358F33741B0F4C244975776B69CA642AC22720EFA9829928519852D1A5DDEB\n      8F5A173769BB2CCA589B020125B282FD1FF77CBBE27D5CD1F62965D6FC0E41C9\n      2E058886346596A7461F8343612C7BA93FD521B9892AA5AAE680E47E81332B38\n      E787A4E7C9C6E8D6181865F3588BEFA68377A6621F3858BD6A55C4594981FA12\n      F5975BC5B1282FC3DAA41ADF0C69955A67CD21E88AF72AB8356D2CB5D981DCDA\n      D93D76F668783885A2A89FF093493EBB0AE18E69133944B1006E5CD050082566\n      333D5A592A9A6613DDD26348DD704D30ACE20CDAD430B003CA9198599F3CD6F8\n      7DA51804D5FBA4D48D640ABE745B008EDD38916CE13E1AFDC58F141B74D77DA5\n      1905E5589AE226891E85ED5783645167FB78A496FD3C8B6EE57811D53E5B056D\n      9116A9EE5C765439B5A0F076DFBEE1D7FCFAAF5CCE9A802B882C141301DAE81F\n      CD23A1F5797A396FC5551F40F7FCCC9D024B3DDB056DE83CA38170FCC632744C\n      527775541C10322C8A7EE2404F8B495E6682A9FA9F33BD16D46A34A02AA576C2\n      92685DB63FBF098F999C3033F2F36F3ECC6FC6C034899E95D08979992089EE8C\n      D496A7041655DF91A53E38724C2BC90AF5CC28450A7172A3A42BF674326C2735\n      1CC16175626EDA681FB2DD92AD95B5972AD8D28794BD3B43C5875BCDA549DC75\n      9A0EF6A1BE23C40AB8A810C04026BF6D4EBA7D96C5B44ADA2FAC96CDAC70624E\n      54C5C58636FAD0790E3AE71D3ADD1B53AFB1EA5FAE31A707FABCF7A351DD6ED8\n      CF5A21D8B74A9372535112C2EC82E8EC3F531F46F39C28D547CD5CE99B5CEDBA\n      44C98AB726ADBC82BF949A8BA6F65950CB12338E116186A11D7C44F2984F7E06\n      EB7C3141FBFC0D63E1CBCFC11AC915A468FE9422436DFD8CE212F6C2F2F6A47F\n      BD0372DE7A76350F32ED6D2198A020D31DC9F5E8C38E8214E7E27224679E924E\n      A0DA7FB88F1DDCD8583BBC75AFB9B088CEAC8145B7543A9304BC2C5836B359A1\n      C46A3A8DD2EB7BDAF5DA772B6BC7A5DB8456854B9D0B3177BEE63AE34D622135\n      B9B64A8EB3B4FBE82171DDC6DAA66E47C11CAA67311CF07B8FF052657CB45649\n      ACE8C9632F9BF2A8AB4AD0349A2815B1FCFC8BC03D07E43290B90489369606D5\n      A7C11DF2A34ED1F928FDDC22123E758D9CB7010A2A95D0B69163A58AD3E7C02D\n      F178D4FFD3BF39FCD1BB6994ACF98D40150F878A245592FCBA4986F70F4E81C6\n      5820D3B78EE6F1320679C54E59EE865926E9A8A432B1FF1998FD45F7F1E5A6FF\n      DB8DE048C2ADB2112A1A8A8B9619D68CB223F0B530BEDD0497C3C0C9E89E5BEE\n      E7D3D3885E1264D5B5F2AAF9A3E1FE16C121B02CE972B4F8D3D1E36BB38360A1\n      1150A777D03B7FE23418C593EE4E2A3217A3E797964F230FB368E693619C99C3\n      C2A34EE21BFBD99854CDA9AAB88C7F6AF5A49D97EFCD3A17EAF6B3CBCBABF505\n      6A1A40ED35D3408C791455166BC0A7DA916DAF4B26AC6F7086A43715655AC6A2\n      1C8CA3E920EAE5F9C3E974A638AC40BD247A48F24482F37E5D95079FEABEA42B\n      87BB7B79BAE0D457AD4635A80DF2CC6E56FB59AC5EF24564C9A24C6C1271E1E9\n      590C7AB5BFBD33DC7E7D651345035A0375C95E6E2EFF7B4E354470E7E0B0E078\n      00C0B564BA6BEAB8C956461AB99E1B1B58C5A8825FEEE2777DF4B793E16ECC98\n      AD2D38D7B9F95FAF9DFA8C142E9C659247C29D16F63D52F4746A57B62E7901DD\n      EB4978F9C2E2321C3D1A86E6FAC691263FF9E229F43BFF09B3EA52DFDB28A134\n      42C3C3E8605871AB78A10E1C9BB98D248726504555201A03A40FC7800CE6FD19\n      5C87DC94856E26D54685942B3CD1C15E02F34C5517836665BE3F7AF4C46F1DB5\n      4C90ECDD22251BCD068D134BD872B2D2343D219350FB252289EEF793FB1DEF85\n      D3C396B9C060FAD68DC3ADEDE6B95346AD1EBEF961EDD575BC4C74B61AB21936\n      DC22812C4E5DAF084E78E50ACE15978FB478036C3EF46FCC5D601381626D8621\n      4DC05219EDF0B883B9AACAA50D4CB90F46577BC2000B9F5E8BF89EA37E57A20D\n      90E51E3E7CB4BDFC729D5B3A4A11E93E7FA6ED0C84A10871CE133484BCC314E7\n      CEDD485BB8A75621435613CE61857DC8CD65181D1FC5196B67A767B73BF60A36\n      EA26DF927B3FEF37FA865B561310312F55BBDD5D0D8C577067713F60F5CACD76\n      FE3832CEB1ECC8587417665BFB0B8B6DBA64F5BBDBC5A05C5938B3DDDD751759\n      B3554F1F96D30F0A3246A5D18CD838D3392C749A69032EFDE0157241A9478651\n      A90326100E50A1781B9D03E1804D8CD736171510D6C13C624667FB0A885589C0\n      0C465E168BACF5900EBFF17D038FCD255BC3A4A13885CD6FA1706BB6F84A2569\n      E78CF3C074CB7BF9E44A5A0A52FF441D9D2E32F59CB1294C25FA08EA984FDEBA\n      5DF9DCC9C60BA7622B03B6C4796188B95FB33E3B9F0FAA3EEDB382BA474B03A1\n      D4974C9268E342E45E585240D8FF72DBACB9EA2F6D13CC61DE8FF844113A1321\n      25B640C6943C519FA4B0D52B5AB04421EB6930E453F6A2B5FAABE77394EA4695\n      C499FC3F0FF19D54DA9AF98B5C2A551A2B26A2EA1B32904738E19EE0342F7255\n      3A2C132BE5E052C37592EEB47EA4D1617DCA49105A4214E008C60E89EFC78AF3\n      D53FD58ADB331B51D4273B1F6EFB4E25F06AB3F1D06959A5CF155895FA961C9B\n      3A972848DF65C359A7B479FD44C53BE673272AB4FD85B690D6CD9050D75F8271\n      59D87B0F0EEAC74EF927BCC83EB4133CFD6142121A7CCC1E935D9B99160F729C\n      1B859B1991A29FA61E9B02899121255F153F15AAAA93FC90EEFDA4B394D7C897\n      33146877301DC0A4F681169E98C25249BDF89E98FE4C36C952040FE8D79AFE2F\n      9D045699A98D2A0CCC73A95521239091EE58DE8EFA1F740928EBCFB415A750EF\n      45D10F4C31A17E361483ADEEDAC9CDA2CA62AAD909DD43FD4EDFBEB8EC1D8AB8\n      37F69F5B2B4FD6996519B026A7FA86416D3E4BCFB13BC3B73EB4A12D03692EB5\n      85DB3682354560B162058C964AE9EBBB0D4599D4B7AB182256127FB2B31D8553\n      A52F158951D4473315B51B0F76F8EEBE797471BCE4F9AADE1F0C5C9E8AE91E09\n      CC5EAFE72F2FD91BE7253D0AD102D0F38A8C236D31A1C8C77C6010CD27A6D1DC\n      6B147E9432079F1A73CAB94B63A9401F44DCA418C844FCE0AD9DBFFC567138E2\n      12B7AD7A45C0A9E2DA3CCF25BE695B078FBA6BA9A93489BD5A5F44E9BA2CABD4\n      9105177992481A4B2A38FA5B62FCCBEDAD3D167F6AC5FEACBDB89238408139CA\n      6C1AD50814CCEC25E59FB4E28BBB602168DCC131CF939789BFCEB963825650CD\n      A0F1BDF1E1BB2C1F142C15C11E4A77D2B1A25A811B4C8763806D33CE8E523FC0\n      B2EEC39315B7398B1F7A0BD7A3EE2C0C5FA1FE05C3F3EA6EB56A9FB05D12CF90\n      8D6B8B4124D22E4A8F2D9D709145B1A1682040D8E1408766B797E4520D346C20\n      5270F756DAD98F1C04B1D68078165351A2428002C4051FA73C1EE43C940752FE\n      0C863FDEDB35BD8A30B1549F67716596A6BA4B38CCD3593A531BD8A935D78F8C\n      B374320B3FD93EC20B91194A6AE0A6B46669F2D6E8D168D6FBEDF3E7E3C17E48\n      275FD8583A7F989D7EE6A4EC45DD9D4E06E9419EDF299247018D6DA39D1A2B89\n      525DBC076214980DE17E371CFD7438324D7DFA4488FCDDC595FF1CD68FA693A2\n      2E2682A72CE8156E5744F76D2C0CB11E4D7C6FF16A9A9E5DA22F58E9E330ED2F\n      D4CFB4F8E92375F737BF5EAEAEC72685A6EB16394C0B9015D9ADF7BA1FFCA07E\n      F9227EF937385E0EB4F54338E3535F47FD58DA50421B9A284A5B104494FC03D0\n      8486919549A1982B513F9048EE109A49713879B4E5F86DAB59DFBBFB5ED33764\n      3C558FDF5C598D002EC93450EF1744B123EB099EFCF886D76EF1538BAA9CFB51\n      31FEE0C1FEBD9DE3474F9A5B83FC7CD57AA6AAF05D028B6117E6B101A6B9E2B1\n      EE394B9E562496195D5C3E3D73D3845B0779622564752CB94E3655E58F0DD874\n      4764A1D41173C218E2F4663AEC8F973FB521FD8954C53C45283690B5D279F7FD\n      60D532562A8233ED0B8114F726A4B455A5CE250393B238CCFCD5A03043F56449\n      614BC82294B88AFBEE88C19DBDC58BADBCADBE13850F091B45C1E9A612AB9307\n      21FE317432BFC0B3D01A188252CBB03E6D8C4F0F40EE3447C7677787AC8C1B27\n      97C7EEB6F54143692CE79222C06C722DF1DB4B7145849DD991664B38C5F0F608\n      DF0E205F4FE5BEFAD392D29A4626D3833F50C723436211E852666A0A8C3DA08F\n      10541D744AA114A1F1FAD1853FF84C5E538A88696BD8A7079525524263E2260C\n      F08527F6F0CFBE63D289B162EBBC1DA5AC90C36EE3C9BD49EB652F5C2A1857E4\n      9AA0298EDE8BF37D5CBFD48417D3D48B75CCAA052D88C57BF9743FB1BE7ECE5D\n      08325B08C80DAE98F6D3609BF9BD4C39372D9ADB1B7384F588E57CC2691E51E7\n      626F0E849DAFB4DCBA433DDDA3AF2D463B33A390544F3A905CA0449BC11488A8\n      BA83CBAA523AC289EC9E955ABFD66E7C62238DA6981AE610F7BE71CF795428DA\n      29A15A8E98154A9BE8196A8290527E0656252B4154D7C39C33DBF568C554FBD6\n      563AA609FBE36E132D24D3C45CC666C5CCBA6C329A352F368DF35E614C0C6996\n      77C0E31B8FD64E6FA8CD30EB0C6A47AA893D0373F37AF5CD3C59C1A19D5ECDBB\n      C94EE564503BAF366C96CB085089E769A8187D34BB8695100B2BDB4F6EB52F3D\n      E7AD7821ED9A05CADE2CF801AFBDE28DAD2716771C56CBB18E92C88C99923046\n      E140A8D66AAA1E9A9D11BDE625E17D6BE7273B6DD8A45F8A156E95B99EA1D7E3\n      B50AE3444989AAEF28BE59CC7E2EABC662EE8EBD7FB8493ED6123A6AD022DC50\n      68ACA891DAB648C472AF4F1FB2C1875D4240E5B905401354CA01CA88ED5473BB\n      7FB743EA41EDD89212613CA005B4B3EBA306F5CB0B95F4DD2E34A8FFD953794D\n      61BC123115A5F138544CBA302115B7764827CA2C0A9BB6B9BA8E1B4773EE18AA\n      7CE8AC03136AA364C690E23966593ABE48B2787A78B8BBBCB641BD40FD0BED47\n      030B0CD364F7A1188FFCCD76D830C8CE132BC56C342E663BDE6A6D341855374E\n      A2E649898F00180019EBF4465855CF671E873077D67EDA9D25F1D3FE78DD26AA\n      4DEB9FDAA832DDCCCC81AA6A8694F483BB87FFFAFF9E3D7A944579CB6BE9A307\n      3D87905B4936A3F41AC583BB9D0D59B9361E676DF705D73A9F32DF7275774292\n      94059E0A7C88F31037FE269AFCABC327C4869FA92CBC44AB4B58DFF2329999D4\n      A88AA02A9C6FC05EBFAFB8D4A27A5AC6343CE757DA042E5BB4910297B85B447E\n      AB1C7F273C3C3A8603227A5CC739CDA679410CBB5A55EFED48A3698BA402B253\n      B05C0F93074E4B5469D327AFD71AC7A54C1524C86CC9B06D01814DD22A960DCB\n      F00C401AA23410D763A96A4DC5BCD865455F3D1EDB2FB5191DABF2B09E4C2B59\n      66280A39CD933819121952AC541C360C93D00632BD5CFD7C3672E1BDD9643FC5\n      5BE9F883AD9D8AA9B8A7B93B8B17373752017687FDA8C89F1E07A9477EBAB96C\n      1BB6621B79214605DF190FF766BD672E9C99F677CCD1E04B2BEDDF5A3E76D1A9\n      0E6B71BE3D8E0F6663096FB2EC5E99C69810880DDBE158E6695263B0CDD13783\n      E2FDC7831926AA7AAC97F04B4B2B5FACD436D35903A686077A420CB83BCB8361\n      3ED9A658583088066E7B759B8123E5F4930DFC90C80F1D78AE25CED58CC6177E\n      87BEFCCB0CC612A44641B3C488E399BCFF13B273ABFAE95F8A37CFCB070FDD41\n      579C3D95A8F7C3F40986AA584CF72AEAD109458E75DFA95ACF04739E409921A2\n      6A81850AA754420574B3BDFB845BD6FAE6934737037D89C48B49E89D3E9B1223\n      879D4AC121CEA7668E84B4F7D3DE8D07B5D31B622528A566C1B36B0FA3FB074B\n      218E4F55ED5756F420562E29AE49A076C490EB2EC9B3845C280961E49032340F\n      AB992F72ED5D99973A104311628844815024667B69382821B0D4CB9C89F821E3\n      3390E3F1F2854581D42E545C474994CAF0E161DE9FAE9CDF001E1465968B9030\n      B52F1CED6946CA722A93C338D808040D154B47D255655C3D81DC8EF534ED6DC8\n      0E44E5B21F56877462151F428B1AC633468427E6DBFEECADD8C686F0D22C2A0C\n      83D28B105DD09680AEA8C802EFDDE83564DB7C71820FD7F6B677617DB4D26E16\n      63301C0F168E6E8C0E0A11674BC79D7C944C6E32F2E8A8B407399C24054D8A6A\n      CA702E12ED7A85A94D91A92DA3B9DA9135AA305F62021D20C722B45E3F5EFF83\n      4F17D552FBF109ADE399361F409895232B4204551FE0E19FFD1DB1A6F69A2B15\n      10626E203BBF0927F7C6AD97837029565BC485061138BB914EAFA6F5E34DF239\n      3BAF8C95B4344C8A5271F0F707CB6B67C17FB0AC9D7A35CF173AE64DB759A977\n      83E791964FDD17E683D9F3DB3DF5B24A24B42726F4B0FBCCD2FA7F0B3BFF7EDB\n      A9EA2B1A8A5C3696B3DD698D9A50EAC189A234E25CD5F6DCB065DDB092325345\n      1632DC6FB2E5DF3F0F8FA82A34734815EFE0CEFF712338E022D027B0FA023B55\n      3F425538932B7954144A2624A6284C05AD9C0AE96E2C47492832EED42BD378E0\n      4BAD95982BED6553E9DDC1C3B173B21EBCE46534A40628A7A2B822FB7BFDCD8F\n      1D1D1FF6410A6B472B03D8559258B10F020D97077C8F471F847C81D72F2F8A7A\n      9EE3046B378E922A2454C082F5A0912831A526DFF61F0DDE5F7FED6356C599A2\n      810B71F1164BEF258BAFD526C1138BB95651CB51A1146A4163B5BAA976DF0619\n      2AD41F6370ED080F72C20FEC9DB71E2FD616E8E7536D7D58689EA97BBF0D9289\n      5C89104BA9DF1B7CF21E37B127DBA2FE4767C069B7D0C35054ED1EF5660AC835\n      1E65E3F2F1A1BB877B1F1E22837B971631C96892873A773D30B6E3B233712F1E\n      C9BD02153905767F94643BE1FAF193C28AC39DC43DB9414E55325098DC83D0CD\n      29E72C7491193DEE87F71E2FD76A13C0BCCD236471A3B45B4CAD2EAE562AD4D4\n      155205E8421F8D6AB94614344CFB76ABE6D4EB6A55AB0F47745D29D44B9BEE3D\n      90D9ACBAB698D9B8D8BAA2C3B52709C233A3026785B45A2768E32C406B528F0C\n      C67ABEB6ACCD97DCBCB71AA0A73E32701EB430B7CA9977C3CE81100A3D23A636\n      47A6D8D0641CFFE937931F5D1DC5B31C93556F11275CC88270E1E5C5C8205700\n      1CDCDE3F16ACFD78D2670DE753D87C26CA60C54B2DE02AF114C369490EEC92C4\n      E0BEEDFEF38327EFA5E99A1BBC54719EB1E102109041A5F638C72E552826FF02\n      1F0CCAE2B2B148A30459E565A77236D59E8E5EE0AB87F21336FC06EE7CBE5CDD\n      CD42B58CFCA0B1B5B553FA95DC322693A10FCA65079EAD39172DF3ACDA9C6A19\n      596AC1AB85AA5648A6A940A3CAAB556A5628B695AC670ECE49E969B486C3044C\n      FBC5EE60FAF6E0F06A148EA2DCD5D1CCC036C98556E5190E8F33B9C055693777\n      257A87B277B2D94134D156CE101C6DF92F9D683FE7394B692A26B1C076C7425B\n      B369A7178792BCDF1D3E4A622580F4051A670510BDA9827F40544124A60287A4\n      10BB882BF95C6568B15AE9E5C30BBEFB5F9DBCF4A2E17325E0F341B73B096762\n      5BC8B7417257C4CDD26CC7007846C795837876D66BD3DDF1BF402385E25159B6\n      4CE7B7FCF65748A55126C24C0250F8058B09DD03F634731ECB512675800A2B26\n      72637526C0C6B8FF4ADBBF63F3F78DF4FC8A75CC47ADD73FD7F8CCD7F4A292E3\n      7C30750AB52ED2CEDBDF96021EFFF5AFE5C92CFADE5F183B8FF9C73F6BBEFC05\n      ACE3A018B669C6CBB4440635140C1255C5A01EE5A3A5A439D3C69C8E8B5393E9\n      99EE61D9BD5F0E66D6B1677B830E487B8B81DBDF3954BC8DD4AB1CF445194319\n      AB07AD48B9238DC9CDC7691CB72E9DC85C80D5170A517CED6E7175BB6C07EEE5\n      D57243DFAB5025AB092AC150556A4C8F4BEB02B32C0147B490F32C6FED37A60D\n      2DB112AADA32498FC3F35CD51B313BC8C35ECE0B5F6632CEA75DAE887BE7C1DD\n      F5132B68B55116038852A67447EA4EDEDDF65BAEB5EA215B89CA29E2AA246885\n      A455D79827DD28385613460C134CCA603E6A9945602A89F4A266F27E1647E3C6\n      CBAE50CCEAA13FB91BFB17707264608E7CF843B3BC8B153153F58129FCF48B95\n      8F57D05AC15868E04A32E0BB0F0E4FAD1F495A2C9D96F07EEAB7093A02BAF7FA\n      6ED272D79BBBFDFB75E4556AAD4EBC6D7CA70568CC807ADC765A38515AA62253\n      CC565335B595656A404009AD527D5A4A942294E5B89C99AF9DA8FFFEA7F2AA9E\n      1BC27A145F5FF0526CC0948DAC996952F70336FAC677B19FD81B1EE40A9F728A\n      ECE2261A2B207CC54F9723C5DD4DE4EA8AD1C5831FF42CDF09BEBC1A350ED53B\n      777125EFCCEEFD6CFBB9AFFE267B21D787730AE9D0BCD37F6EDF27F424BB36A6\n      9D77EACDDD6911A073273FCD69B07A731E74CE2D6FFC77F0E00FDAD586A70754\n      B99576051B1435C3D21B0AC0422D8042A9C8C2521A54A907A6D4351A8A59F0FA\n      86FBD935518F533675613BFB791CFEBF8FFC69993925E7F3FE67AE2580A52FDB\n      15DEE58A14B32211825935CFAAFAA26062921A4DE7904D7C1928C49BB0BE7722\n      20C41A6D4D8045163E77AC68C66A1159180805726F3396170BCF2F1FDCDFAAB9\n      0BEEB235C6036C8292AB1564BA68A17775971FE68B97DA700DE55E0AF4542B9A\n      CF56E8761781756C9ABE232516BC6EEE990FD65EB9084D3B01639B20790D4DAE\n      0E9B973DB6364619368A2AD7B170AA6C6A8DA7B5FE3C050773A27E35078995BA\n      7CCBDAB9FA78E144137F5C3132A43B30D507D1EED2280549890B57AD9277D2F4\n      AE0213609EAF2EFEA373E512E6DA6793285EA85E88D03D9B02A443F8A863EEE2\n      BDEBBB769D38CFD5114A4CAE4A7235435EEFFA93A54AC55C25033BC2C4AD4EFD\n      FECDEDEA5ACB68BA617FC0835AEDF9B31C460A69D4C65020935A191369353486\n      3FDFF24C9892D85C6ADB2BA785B1C069A0E5B97A12F0A933941E4F9ACF6EA90D\n      52A477F764C5A04B0D4E54C53149493580F1486DD1F1EE5D848BCA52332EF2E2\n      E14F14ACE01C10572DB7594E3CAB751EB8C7015A527F762923DD0E231BE57C50\n      023E1DF09A63E1FC74146870D4F18E3ABD4FFD1DE6500167216792A4E13BEF0F\n      FEEC3B0B07E9342B40A38658E965C2D40EF79CB03C46C675A5750E8681D93888\n      79C5F78E17F10A63C4358943AD3821198C9931C2202FA2BE41AF40F31BDB9DC7\n      223B52359E6F908BD45E4E9D8C93DB28DB73CB93A9FDA69F6E1F76CEE0BA6910\n      04F8A740E5F91C2B765BAD7B2B25BD3BEDBEE987316B3CEE76B86961C3B97E78\n      A8FD0C8138E1D997AAFE59DF5EAF9A0D0379A0749524C98AD292B3A6C103CB75\n      2ADC71A7B6671A7E10635A004E615816F5FEC12C4E7F1CA6FFE6C1F67B7B8330\n      152D028ED86E8DD8B1949D24E4455103A0E6D8FADA2F02DB32B9057847297D80\n      17941C52EBC8E60B15FC99C5FA97DB474E9B0EE25164009DD19ECB38556B9F6D\n      8D467E7D613889B64793D4B77B79B2DF9F3CCA50FC34DD4EF114C5A40C7052A8\n      2A87D6576A1736975E0EEAB5528430C7BBF1613F3C44D6BB22BF56C43D9E2E7A\n      7E352B36BD6ABFD713819FB8CE8D87BB2667ED8B97AF6EDDFFFCC2FAAB02AEC8\n      DC25AC8A71850BA86D299DBD440E8171C38A59912B9498F14CAEB54CD3A83D7E\n      F2426BF1C097D7F0B8BD6CAE7AF4F8858B1BBFF5B572F9784FC8EEC3F79BBBEF\n      7B93CEE3C1A8FDCAA7DB274F4FAFBE133D7CB070E2C4FE6CDA3AF5327416B7EF\n      BD1754EDF6EA516936737DB99D134B953A46A0A29D6AD91982E5A563D3D4D493\n      787452766FC94ECF3AF142389D458777978E6E74F7876A1335D7D64AAA0AFE90\n      6A3B08A1876DA1243938B876C3AADB8D67369518A70A64C3627CED617CFFA0BE\n      DAB05F5ECD168D52B116C5DACA58DB55964DE01DE776557BCD09AE135FA5760A\n      9C3B02A8ADA1539B757F62C9292A249F6493FD241DFB79A6107DB43FA9B80B7C\n      7F301BCDDA97CF72DCC56E1216D0608DF2DE341A751A67D791D20CDAFBB9B471\n      C0D258DB8E8630DC9DD48ED65237314A93167E89A5C023912B5569C0D2A091D5\n      7B6FA74445FBA5230092E993F0B0F7A47DAE66B6A8B9EB4EBECFF2C70878A434\n      403149375E6A83CB09031D9A7A5CE0BDECB0FDC172F6D2D4A4BE79C7EF87BBD6\n      59E0F3D6E05A64AE406B8125DBACB6B01C2E4D9C6FA15E7F8691AF3479920BA6\n      67E4E60EB0588F75AACD6F228570C44585AAE19800AB1493327C0A84853E1A55\n      40A8951AD7328DAAE7382113971AF2CDFEF4DFFEB4BA691501570201C1C2C04E\n      71878CEE8E5B9F08583B44C202C02C04F73267F2B3693661AD2F2D8747C70A56\n      5DB6DEFBE0495F84E7BEFEAB7930A1DA97A39CCFA6EA0F36B720D2A786F3384B\n      A4E798A0DAE9DA29AED4A157DACB48E7AE3BE75736FF199CFED131AA87FD289F\n      C9B4C360041DAC0AA62864996BE70AF5A1B9A9571A0C90ABC47CB73E59FAB567\n      C9994A863AC851056B2DFD9B6EF8FD278EE26B064292E8597A29896D9ADADDBB\n      280C9920EE22AC5BBB6A266D56263B0735EAC5384E74AE712B19847445075F88\n      09EE1F460B2FADDBE7DD42917898E2828187F0E0CD7EA351A5C783837BF7DAF5\n      366990DC8D39609C4BCFF4F243D6B973B8D46CFA27AB85DABE8E52DED02C14D7\n      269A0358AA64E63A3F54296264A39F93E15A7FE1D23120AD5C868A57E23B7074\n      65523F61A39305CF0A55CFE6ED8E59F9D4DD503D54C80D060133D5FF5233F1C3\n      0ABF460EEF6C2FBCB6CC364666A9081A994B4EEDAF96E24C11067BE6A46FA5D1\n      16CB02E9BFBE56FFEA49519F5FA5EB03133D17A53DC289A29F7D79FF09D9A5BB\n      1FEC54D63DE78C1B9633DF0D08AAA513D9DDE9AD6C34A8310C6B304315EB7EE9\n      765278792D32676C3F368EACB81B6DDD10064D823C4C7092ECA9EDC7B742EB90\n      019B172D68B4574DEF98404DA11E8628C83C060968C31FA3D482D440329E751F\n      281D8CEB8EAC3A420FB753A0677CD47F90C26438DCBB6F352DB7DD9CF54760FF\n      4D9F2E177169FABC1063102CD385E724DD8470415FC1825007B3C8A65E86DAD1\n      08CF2D21E72632F3633A3DB4A3CD48E6E9018A3017043A4604BBCEDECEE15FFD\n      5D7AE551DA89AA56D3356DC57AB086404E4BC0F224A5742B478F065369FAFBDD\n      F85863719D274E3CF502CF750DB348518E0B61C68C6EA3FE949631AEFEA01B7F\n      6BD2E90171B44E5E0F1A2F0BDF4ED1552BBF5613453473B0338B92EE343C7EEC\n      18EA4F4E94F4C56A73554A2F8B1B8E416CA488E54F5C679A6421175151A8D5AC\n      7E9053A497169AC720ADEAAFA22822C62695145B109B4135AC5A916358C45412\n      D8A4C4559AA81B81BC8CC7D3D92C8C45F9FD8383BF1A0D7E1A31D3345FF01477\n      779B79A22841AC21CA9E029A42B48FD9B4CC61940BC5DC280A88B900E992ADE4\n      BE98C8244A6734CF372B8D1757975E0850229822E381699B3A104032519AA633\n      4EF33BA35EE2DA96E98E06D39F6297C56105D01AA5994C5D8F3CDF6AAD2A9EC1\n      0A573D050CD2C9783A9944539264F08E043FC3E5FB83DE62BDAECD3A0CD9CCB9\n      B91F561BED9F27D31FC6A33FB55EB87961E16F6EFEFC578DC6A7A8493D166761\n      5B5A1E36A16B8D87230A6D7DB88A63A65E080287C3D85F6EAFD45CFCE8C9856A\n      3BAEE277C1BE58A247EAB573D5C5E3AF3C6B6E9E96474EC92A0687B7D1BD875B\n      196E7EF2A56AB83BFEE6B761F34CF50B5F9EFEFCDB15A70DDA67E2DEFB3CDEEF\n      EE8FD62FBC4E1BEBB963A8756A114A39903A375EE14F019069E694415BD2100C\n      6EE4DD03EFE48BE92849766E36CF1DED8E0B312D969796CA9A919623231B90B2\n      90284B6969AADDB83BDCBD777BE1B9A3B415200115B112D04CBF7B9D3FEAF897\n      37D1C75622A520F3829690104715146037A1DB46280050274A418502BA8355FB\n      2249F0D41B51B765685718398BA7FB3C3DF4D5AFA66870AF535D5B5745FDE1FB\n      B7FF3FA6DE33D8B2EC3A0FDBE9E470E3BB2FBFD7EFBD4ED333DD33DD339800CC\n      201000854083044980840A94299954A9542A972CC992FFD855F61FFFF00FFF71\n      956455892591166DAB28069022001279800998DC39BF9C6EBEF7E4B3F73EDB6B\n      DF66599AEAEAEAE99977C3D96BAFF57D7BAFF57D4B9B9BCE0603080729194F3C\n      16F1C9EE6E2D0CE9529DB304EA19D5D6E79916698859BC37A96D36D320867203\n      9988E8DEFD0C978865966EC454BACF3FFE10389D517BB19DB17EEFE6C038313A\n      CF36C55C5E6EA3C177A35036B459D8B80CCEB8C62F906CAE4FB963555E6116C3\n      1F26B525D36C424AB22747137868CB67CF46C38938E93797E662A3988AB4D3E9\n      D00751F76E24E28681AD42F76C0157304AC125CA9136EC354CAA471C5D546287\n      EAC10629262A363F79B6F95FFFFF85502709AEF5D529C36A42061E61FC7B47D1\n      77DE695F0C633B6540D23037A853DE65FD7BA3C54F846831C725E35ADB1DB9B2\n      31FED974B8DB5FFAC24275250310601FAF3F7AEFFEFC97169D57E78A423AB076\n      B3A90E0DC5352E9935C9CC9238A9C84C064195BA934BB7856A17560599CA45DE\n      E5F5B5FF1597FFC3A592172675927E5676852B1C6D7C89AB02D89DF62236989E\n      1691C0107DEC1F9647E4457FF94B97499D726B5CA0C84F57E23FD8493FEC7AAE\n      55E86E148800C80FDAB9B804C4822AD3A49C672474AC9ACB2A958DA7954DA1D6\n      88A20CDCD664529210301FB691DA7FDCB3563BF39FD92CBC0C5E084B21475975\n      5D1EDD38D9BC7C3953835EF7686575A5B2612B8B4268F35C8BDA7B770F59C9D6\n      CF2F4151CDCC5442D552D412A66670909F4D48A8BC84C4CC1CED79FB1351BE44\n      EDB3735561542A073A4F76D0F8FDC86D33E7B2CD8B8981025C01994CB5FFA706\n      133ABE4D6076A505553075D2E6A4297EA606C7FDCE575622E7C8D64274545680\n      30002BD2D2282BAB72FB7EF6539E1D96A376BEF0EB5782CFAF4A7726E12D6687\n      2640B5A9A9A072C6A7D5DD1D7A603CBAB1BBF26CC75AC2B94BB9EF04792D7A30\n      89CBAC732EAC540F7B665ED5066F9DAECCADE20B6E8F0C9CD4F33796F4411CB3\n      741A60968979150F6822A2DB5D8784531699E7EADEC205A4E6150A956EFDCBB4\n      AF939EE517BA42490F2B8347C7E3FEC356FB22D68AB9A61EF8D3979D84434A53\n      393DDEEB1F3D686E2D9256303A3875C76F19E6129F0AAB267939323A1755E3D9\n      0A2F1155C3FA9C41778D53D59885DECC1B606637A10F28B466F26CF4B9D28F53\n      56FA5E450232772A7897F19FFF59FE273F89FBF10499EBCE7C27821F1023960B\n      25FD02E122EF1BE83435C7FDAC5FD1BF3CDCDBD838F38BA6DBE90ECCA66F06CC\n      4E125A42DEB5E3C23AF0E39191034ADDCFC9774F076FE559CAF0D3AEFB39B771\n      9EBA1383EE9BF2CDF4C01BF06079F166EFC812F49CEE431EAF5AE6AFBA0B4B59\n      9A9BE942DD3B33E1FD96D6C940BE9FE6B96758B6D2F3B48E4972C191EB54D4B5\n      8CD0564E66C714433EF60BC24A53AB2519B270D2884E27D1C9204B4592221E95\n      7F60DADFDADF7D9496679CDAA76BCB172975D4D0F24A0F60638E0A6164CA2EA9\n      5DDA0AB2B280FD26B89D0BAFAC426A65DA79564C0517840D8126AA72D9A1BFD1\n      F2571A1D2C35B0653630639B99CC80C76AD3BD74988962411AFC64F27DA080ED\n      A50561041C29DF1001205E6CC14F41AE4E84D94DCB93E9641AEDB26A5F889B9C\n      7FC48B3E258029D1B01F78EC7874BAD8595489BA7970E2ACAFFF4BF2F45FCD57\n      7FB8F7E1FA30F9BB73AB4D99ABBA367E9E292D2BCC3990988257FBFA8A31E396\n      71382A9A9DF6D69CA31EEE754848576A6F573B9310AF359AE74DA3D6A09D90B5\n      167C72E122DBBA4AEA5BB43597A084DEFEE9E04FFEBC73ED33E5D266EFE63B67\n      AE7DBC17A5B5E42EA6D183B73F38FBD9AF1F2784DBDED9ABCFEB6BB942289B40\n      D9C861932AD316B454B6828018DDC87B07DED64B7137CEF7AFCF3D7BA12F9DE8\n      C1FE4633CC37D72D31C1F13192908800DA62AD8A5F92FCF69D918CE75F389F2B\n      ADDF225D3F7830887F7C1709E17DFC6C75C91BF1D8290C573980820AC330C355\n      6A2C2B5A286DB842F521182E66DAC04F64E1B4563F835057513A3D54C52EEC52\n      32B686EFED7AAB8BCE8A77F0E15D392AD63F762E72269E15A0A1AA4C99EF9D4C\n      F7078B979F421ED04AC84FC09D0ABD692746B693781B0D6DCE5001D5D0473744\n      1AFA9EABC0B800C692112842474E723B411DE15D3248EA4DDE89459E84AF5908\n      C272CF3DF9EE9E3B716CD80866127CAA81AF1078DA4E663AA59DF332F9691C9C\n      6F8D167A3534977F50925A15AC1AE26ECE32377F061FC73BF37CC50B647CB3E8\n      EE10BBB291CC2BCD77E067818F008A5300FF989688AF5C5CCC1821B12500B8C8\n      FAD4B9C6DFF9F47F510819D7E2FAC0184544C79E22C5B777D21FDF684221F472\n      262A8680923BF95D3AB8375A7835240BBACE72484B0EB66573FC767972F770E3\n      8B1D7131A6659DDC6A1DF6871BFFFC4A54DFA1E3C0AE005BD299D18D6E4E7832\n      B6AC4FAAD54CA0444BC361AE27E400FB10AE57078A44808CA7B6CEFD6F38F967\n      5BB0CD015224BD9CA6FAC41409594AA9B5D6C89346436D040DCB5D547CD22E56\n      BE7ED9DCA8C97C5A8595D6A90646F5FBF7F0B1243527177A408D0158D61101A8\n      197128AA65E1BB8ED9A945F0A7DEA0E30699414665BFE3CE89014ECCD2D90C81\n      AB4687A73149D73E7FADEA981CC536D4CCA4420768F84697172504477FFB2E71\n      4963A9C14901D1AE662E65C9382913DE6EB5691D4B7D7550223DE30675C6D4FD\n      1A545FBD960041305071378F8BEC9DB4F5C525D13149AAEFEA2A19C953317A3F\n      A28AB45F9C2FD529831F146EC54A9D2C669C1F5083C1352D4C8D3431F3F6B451\n      FCB8488BA2FEA576447A8E30E04DE05969615269E634AF58E59D3626DF8B81A9\n      ECB67A1BBFF3B2FBB105208D4A11ADDCAD6D57F551973E1F1DEFA3877B6407DF\n      B9B973EED3EB34E478AE39662C189BF98D63A3E5962B9438855BB2B45F8D0EE2\n      C54B17A515A736778205B311689703D3A3CA81072170EE00367E771B9D64A5EF\n      96EB356F6B8199679470F5813DACBE9E082340E5B4E5839E9F70CA49968C8F82\n      00B3E616D23DCD88E8F952132043464A0B28DBF6C3D1E976E3D22AF2ACC976DF\n      2FDF45B80DF8C47033AD0B5C3B47E79E97AA4321F2813093528F0AAA70D61AF3\n      37238A68A698FA441D1920A212DA9041B34351E54C1A10580F1F3FF8BDFF47DE\n      DCE159D5682F06A5E1C7404821F7E665250D0062924F148F64303D88FBD4FC8F\n      E9F81827BFD99EFF44AAE7969C399FA453C60997765AB091218FCC7488924854\n      8F12F45681DF9926854C9F0EEC979ACDA750DD99543FF126BB93D1D46341A3DD\n      DD3EB62C7B617DB1FFF8F18B5EED9736CF56477BC0B2CF07F5964CB4E778E8CD\n      A03D30D34C3B0DFBE6D842C203A8640722B00A2B734EB5CF992462A634A9644E\n      CBC426D5388BBB51713C110323B83D9CFE9F453245F8AA137CCEACBF82E899D0\n      50A12075E618D448443E29D299D519AD04573C65152C8F8F589DDA9E5FCB6CFB\n      F164B23318F7F3B2B09C3164DD62F4711B3D1B2EB5B1C9A8517A6C6ACAD2357C\n      CF69B71BD2375259061137A6C5011BB6ED9A0B698BEB2660E41A230ED55EA629\n      4F7A71B117C93EEC697CE296B74CFE7E3A1924796B61B93F1AAE7B3E8457C464\n      B6D278F7EE8E1755AF2D3DF53BB5E5C74DFBDF3EFAF0E1C9C157B6965EE92C8C\n      BB7D0001ADCA59E2CCB7E9513218A372171277961A96F3B0E0763BB8E25BECC1\n      A1EBF86AB3F9283DAC055EC3750C35C13563C1CD9AC634B51B85BF197636ECB5\n      157BA553735D3699267132A4B8BDB282C29A35EE92C7378EDE789DAE6CCC7FF5\n      370FEEEF0C1EEF3EFBF15781399B2B67B8EF8A7CEABB5656159E50050A2591CE\n      F876DADBF1365F880669B9F341FBB9A72377A1FBC18D2DBB8A9FF998570C7176\n      A2F0B064253629E14A9394E168FFDECDE6994573A95550ED8318621B3F98643F\n      BC011CC7FEFCB9F13C2139AEE526E28243B2F5E60D67BD3228E41D808F5869D4\n      3693CFA54277EC73ADDE2B04ADA2243D30D25DED2E9485C99B07C852DE8B4BD9\n      707CF2E37B2BE7B7C4BAA38FE893A2744A3CCA4F3EDA77EB8DE6D965A985A551\n      2A879689D0C04E1E66DE7A1D2D14852AD9AC2D95A9507B7500212E4BA13B2B89\n      6D34CAED68F4B01B366AEED62282A8BB799021D9BC58379A6EF266BF7A47B0CA\n      E99B09DD08973EBD9CD4FB18AA7B04098BA9BBDEFEA383CE734DA3EE8BAECCBA\n      A761CD36DCA5E1C32E6B32B3A94693C1C25C580DC3DEEDA41C008633AA1C320E\n      13BA61BE04C243894929A47EF4A410128AEC0A18610A8CB0F1773E5536D0DF14\n      42CCB896C73398CA1373EA499CFCF1DDF29D47F5A7822C10A40010CE0976F23B\n      AC777FB8F089907480B713E488D8882DD592379DC35B3B673ED7A8560B9674F6\n      DFCA9B9716FC6FD406C65E3069594F4622B488879ADD0AEA412D2D4BA4EFA308\n      D3765904880A11A2D2A785026A058A29CA57CFBDF27B38FE27672C1644FD3C1B\n      E5AEA4361047494AA85F1492A3A0049B9232C1A4C58FE924FC85B5CE2F5EAC74\n      D6033EC54DE6E6DF7A50FCF9B62DEB65E8222DF6A2CFC6B499A43E3BD70AEA05\n      ECFA9505CCE5F0E4B4B5BC10E7D3A23F6E2C77E26926125E3FD3462E2947FCE8\n      7867F3B35BD6D38BBCC82A6D6B989B89535DE7C76F1E36CED5ECD0DBBE7D7F09\n      92FB1C9969DF4391C38092A7A3B8D56A52870196D76CD82033E11F4C7547996E\n      4E1288EB142F99899DC1E9881F560B5FDACCDDC2C84DAA8F14A272944DAEA7BC\n      2F565E3E239C2E503BA30C34C2038AA3BB1B4DD813A4D253CF052DB94582A1DF\n      FF51DF702DEF352F373240F2448A123E12320D611418322665DBFEE82FA7AEED\n      EE9E196CFEA357CCCDA61609865AA00780F59C67815D02E9F3E421DA3B5277CB\n      073BBD8DCFAED336E0144F39ADFC284AB60FE7CFAF4656CA3CD38AC9F8FA8EBD\n      D8616B4D8061BEEFABB916AC2087F526AE8D2C5115C850F8709CBD71D737DD62\n      39A82EAEA14693F1B3B04D912815C01CD3D48B0FAB52E6A60DE0331D1DEE7B9E\n      E334EB8A352B08526D214889B6365100CC6C5C8ADB37CB6CE05F39038023BD7F\n      6AA2F7B90C0C6A53166146536BDD59FA84500D880CF81F046C7F8299B4919641\n      7F322BA147092B0D5894062552BBEECCDA5667E8C24EE9FE69F9676F3CFCE97B\n      5199370D770DF928CF134074B0A52228AC2A665AC88095722AC3C3D3A867DAEF\n      20B92FE3ADAAF8A2556F0EB3F67C2D47892928F0F582A328134796EA07729246\n      69491F56F6EB71723D19019C3C1FDA9FA1ED4B99F36E201F5BC5ADFEE15CBD5D\n      0B1B8FEF3DDEAACFD98EB5D3DF7BA1DEFE9DF9B3E1699FBBE89CC16C605ABA31\n      1CC32EC096CA51A9076DF5B03A29A302888481CC9135B2A10016DA5D059899AD\n      8FAAE484570FC6D3FD021F33F7FD52FC68D48B05BF1A7A5FAE373F56B3565CDC\n      B1A8C385ACAAC22225D527F85A505449789B4A5FE443D552AE02B2A8A5262BD3\n      1D0125C0F6DD93FEC12051D4C9AA0CD3F469165C72432D155AE5A54F22AB7283\n      30741A2690EAD093850AB512F249AE9B31045586278DD164B437ED47A3A93C89\n      E2B2EA52524AE273F384B03B6274BF18B71A4D344E2183D71A359272F8D77786\n      471FC5D1B5B9CE7389FBF946D0EA9CF9C1F6E37F7F7A3B59665716DB5713FBCB\n      0B97D75010967CD83DDC57933BD5F05EC53B5CFBA5FC34396D2C34BEE4B68207\n      C75960A8ADB9FEFEEE0BEDE5D585664E4607814891B024AF31ECC992C884BA76\n      E2D4BDF5A7D4C2F2FCE54BDE5A4734BCE9D136BFFEA1DA3D193EDC3FFBA5AF9A\n      1F7F7978F38387DFFB4FCF5D389F2FACB22B2F567EDBCA0A54E4B95F050570FA\n      B912917078BBE86F9B5B2F44E34CEEBCDF78FA521900BFFC60393F4E5EF8BC95\n      75A9EC29322EAB4CEB580340941C6559F268273BED2FBE7C256E5A264F286493\n      D4C0D74FBAEFDF729E6ABBAF6C64506263601C14606F4E5CC759947E8B481BC8\n      1906DAA2D2997F30933AFB95B3835260185112EF59D343EE6240B0F93B7D9E64\n      E1A796B192C3BF7A04D8A4FE89CD9C0C4D5E084B2161E2C3ECDEEDED8D8B67BD\n      561D5250569D22A69C7138BD97BB0B015B07041A11A9805E02FDD73458DB87C6\n      5085AB0476A08034C7F6D8F09DA1B5EAF8CFD938E3F1F502487FEB52DD091792\n      EF1F678F4BE59A995FAD7E721D2D259C9E54104E4980A85B6ECBD18341E7DA02\n      D41EF1782A8E72E7C252518AE47E3CBF3E370C7655845BCDF57427E9DD3AB54B\n      D7559ED6B4D685B02AA510B0090831197381D659DA38E03F17C2DFFA5409194B\n      4292D04DFC5CDB57692FF6D48CDCB29AFCE147F8DE897F31C84281B3C2D6C2FF\n      4E7A970CEE4FE63F11AA8E64B9454C3EB6068ED166F7FCEDF7EF2EBFD6725782\n      6CDFDD7BD83BF7DB2FC8CD714CB41795A1CFA80D7D5BAB2FB5E46C7019D6026B\n      4B044598802C442B6DA732530ED7B213489C14F1A8F9F257FE0C67FF6C83617F\n      7C92F371E1112DEAAC84B6FA2E34D22D344790262BACA9E8E2E783E0AB4FE1F5\n      1A2D0A839191A81AA236F8BD9FFAEF0C14694D4C430B9DCA598304D33041216E\n      39166D05C2A1D16054B75C88F771345D6DB4B3313F29FAC186EF189E35754FFB\n      5DF729B7F9D222C02955F1CA1222CE8DBE11FD742A7644F3A57030ECE7837CE9\n      FCA26CE550D489248492422BBF31B7E94136E4B6B6D8861A849EA45D6376C8C7\n      A0FE4251330C61037139797860BBF5FAAB0B298D6D6E93025768C29334BA57C6\n      0F8B332F6C88B941C933A7A84BDD751A11E0CE32905A612783C89700270C070F\n      CC939F41459FA3175465033C308007142C27CA34B9054F0C9B46FC4E257FAA9D\n      77F9E7ACB9DFBD821A904D997CE2CE0E9B0EF813F60DE00FBB37D8DE6972238A\n      A539F789965EF2C2C33CECEF1CC39FE69742407ACCACF15E36DDDD6B5F5E4B03\n      C2ACD0F25AAA65E82B3765736572937011D5384B7F7C4F1D8E9C650F3DBD44D6\n      CE14B4C6F2670819101A2B2E80244BADF60FAC54EB37A6BDEDAC98D417572964\n      21E4403A067464432DE7A69252FB85556972F73A35B87D7145A585BA3350F607\n      B9F0B505118B3133B8F794B1F0B29001AB74AFB21EDB218A098842FB89570E22\n      BA574D1FB2CF26E8B57CB83E1017BA9F0C0AE4839F1F7DFBFBEAC668B83F315C\n      AFEDB8012F384F72A8E8889A2936394D24441EE012312ADDC3ACBA9124EF27D9\n      F2FAEAD2B877B9221E975EDDB2A860B9163DCE65910B7BC0EC2EAD46F91450DC\n      88A31B08BD5EC677D32915D533AE73B9357F621869554688EFF64EDACDB90676\n      7AFB27EEEA3C7769B6BDFDAA59FFFCEA26298B9AECCE79B586E34200F7F32833\n      98964783D295E61E33F2386616E054A0E6F605335C46AC222A536232C9FB8978\n      3CC846C23840E4A653FD7C749AA5E52F85DE2F2E2D5CB38D798D348585985700\n      4537726776CFA3B89E553514077EA12CD87E062F2C3D500DE49C4179AC385324\n      384EC58D93DE715666869563838AACE9985B8EDDC94A4314A43E53B5024EE206\n      713BE486EDD98E3EA2C59570AC2AAB703FAE86D37432247AC44A23D90963534A\n      32A5DE43CE607FD7F0993BEF4DBBDDA7EA2B629811DB3FA88A77BA87D2A52F75\n      E6CF67D6CB8EBADABABC93A0FFF1FE0F3F34E38FD7C2FFFDC55F5E9B92A9C876\n      4707513E9ED0F47131CC325233DA3B55F19DF1FEC75617FFA177C63EEC1E3584\n      B1DA1E5FDFDE70DCF39BED26A9064D56050D2C4DAD48230790B34DE0BA044FA9\n      5785F3AC16D8736EFBD2456F65A182C54B8BE9307197CFF547233CDC4E0E6F2E\n      AD2FFBAF7E41998B9878A8CA38CF728705C9380F97F3CAA8F76F8BEE6376F6DA\n      24CDD5EE87F58D73A2717EFCE046FBF446F6F1AFB26A484517C9518153884943\n      107DCBE2127A3818BDF161B0B1CC9F5E2668EC0032E48037ADE31F5F2F0F4F97\n      5F394BCED6B9E496F6248728429E11F0C606A95CA69DF8728492995D8621017E\n      C34B6A2F00C8C6D3287AEC8E27DCCF1580EC3B3C1F64EE0B2D00C5D93BD3F1DD\n      C1FC2F9E2F5A235C460CA8147128778EAFEF624CE7D716B05594665FA0D28D9A\n      E3EBB90DD17E81293546BAC3C7244FD42A98E410421C1BA5214B5E14A9A37CD2\n      25C0DB3BCBCDE0724D95E4E8BDBE9AE2D6D9B6631A27DF3D207D3B6BA4CD97C3\n      E07C4BB149614F8DBC1917C3A008A25B4926B2852B1D29E5600FB23A9E9F5F8D\n      F62648097F99ED4ECB859A637334BE394AF681A40554FB3E18A59E4AD6E22B5A\n      1D99180160334B4F9538AAFA9B42F8CD4F966DC87CB3420891ABD13135549219\n      130B38C8EFBF6F1F26FE793BF139CE4A47DFB83AC95D3A783459FC789D2FE446\n      EA318247CEA9E7F9F4A6F9F8C307673EB361D63ABDB7C674D568FEBD33058BAA\n      143213815C84354C61951604071429F55D2051C09CF4C270CD08850DC856EAA6\n      76787E31D0F5A448165FFBF5BFC4D93FDDE099910E2B1115C16C824C965A98AC\n      D4ADA705A3CA849D9B30A39E9BDF7C8E7FCC89A90C4AC5CB4C85EDE4CE34FFFD\n      37967765459BA7843A2477E00B42F0941942C26E79662B80A4D73D3995BE6504\n      5E79DC5D0E5A8543E29D8CAC5BF956E28F5C764773B0E0D736B11B41E1523853\n      2E02F491DE1A476F458DA25D9E8DF68E0EB6E6CEBBEBF58C1D318BCA58518BC9\n      4A9A9687A9100E7C0348E100D2993EC862DA14B6C0BA2D598B0021CB142E11EE\n      E1EDEDFAE68A7BA591E2A92B5D04B98D4415CF92077CF851BA71F50C5F1D9565\n      E4E64D09DF020F2914425E57CACA69423585C6B872E480F53EEC2F9D5F2F3A31\n      2CAC0B3441F19CC6B07C967091C50536BADF9F36EECE45F9A4F1DF9C21BFB981\n      81816B5105DD5589913E9D2C95674239DCBE6EEE9D8C3F1C7973EBD68B7EE24E\n      4C32C7EE2607DDDEDC33F310F1B3A6E1C660FBC8B12B6FAB2E01F0788B955B2F\n      DDC4443681E28F9DA10B2F9C5AEFEDC91F6CD76B3579B96E5C9A47F5E53CF599\n      7801D35D6A455AF846598A5965C15D3710FD9351EF4163C13783B94AFA840600\n      EC125659D2700BAA7DD698C032CA1EDD364282576A729CB18751E57E984B4F2A\n      F8E8B9428CCD7F4C359FAF9447B566297D52082106915EBC99F320D1D3C6529F\n      4D548C682D23580CACBB10ACEDBBF7F8B7FE437EE75E34A14DD19A17BEE31923\n      DC4724F7844ED23981AF66B07119A812A0F59407C30CBF391DFDF568B06407DF\n      AC2F84FD6E31E7947EB58EA933058E6924559C283F96C150A88448544632CF0E\n      1CF32DC7FA28C94E7BA706E30B9B1DA30A3A533D47F2B81C27A7E3A717D60FA9\n      BC333E59B2FD33ADD6E9F068B1905F9BBFB44AEF9B1545C02B999D63AB9BCBA3\n      54A676D02F0B270C46938161EAF392B0429FF617AF1197A2A2C7B387C9F43EA6\n      FDCA3169ED9E48BE9DEE18147DA9B6F4B717E79E69048D6C52D737B5380542C7\n      743205C669C8C29AE9CE416572387524F0318EAB9240A1A5628A7926A45FD92C\n      26CA0A6E15C9EB83A38930EAD5CA8957EC64DD39443FEE34CF306B5A4C4D9336\n      B40D62D527C5208DE228B90E299F03FC450E42EDB0BE82ED95821ABED587B0CA\n      8A05D8F59679DF16FF6A3CBEA4E87AE0DC1AEC35CEB5EB27F9B991231CFF0FA3\n      ED135B0512BD42FDADA0F1AC597CB279357617FEF18DEFF4ABE47FDE78E56BC6\n      726EE1EF0DEFDEA5C3C22EA52A8199AD8DFD08B9DF95A31FA4275F5D5CFCC76C\n      838E47B76B13B7DDC0BB93203056979C8D69456B96412C208EB269F5022BE2A5\n      5D8E2D34E502E114D5CBC40596E4340F6BCDE9566BFED5ABC1C58B16C0C7DE18\n      D5917AF8B39F7EF4C18B5FF82DABF35CF7C1E3478FDF597B66D33BF38C333911\n      CD334965354F6FC9D307D6D32F4FCA126D7F585BDDE4B5B3D9DE3D6FEF8DE2D5\n      BF6DB288E62788F71223D7F6C8C0C0119A5AA2964BFEF6FD3899D63E7B6D8A4E\n      EBC22C8A52D65BC6419AFCF5FB569D3A9FDC4CA10C72A0634126615528AF5F24\n      F0A9B4D068362B8444BB57CDEE0B016E522D60124D270FBC484A770275373CB2\n      D2BD889EF7ACD02EAFF3E39FDC6F7E72D9BD4ACB746CE55ACC4B091315FEF19D\n      FB41DD0B966015868216F6B8DD7B676A78A4F68C8349A4C7C121FD69612DC04E\n      D5CCCB46A2A23073605934A589E0457DBC16FDE0F8E4525C7FD16EE5E7D0EB6A\n      7B74BD75D9A96F37B3378B41D02DAFA46B579F6106205AC042D828721E4D59E1\n      E40F0BD84EEEB5DA484E8B5BD1B2BFC69BE468E7C18ABD329A0F507AD0AA79F8\n      900E3E88791FAA3163CC29F44832AF48AE3B5288E942099A1542BBAAA628365E\n      3BD7FCAD4FF13681EDCF6685906B7D45ED3893D19139CDFB7FF0BE3790DE9631\n      B5325A7047EBC138F13D3A7C3459FA44239F4FAC3C341024BA031B0ADC757CF4\n      F064EBB397A4B5D2FDEBDDC61716F0671369BA7636C7CD88696A4E84F6C1D547\n      2B9A91CF0A614935B3615C8FD34321D4679D8CA14A6627DDFC30B5E8854F7CF5\n      5B38FB274F4F7B391D91B0842A22A626CF6DDD941C629C28CD54A9A4FE801CFE\n      93FAB9679FD106CA552580D752D89CA8FB1FDE09DF1CBBC55CDF90795D060560\n      774BE82949ACE6CB702E3052F768F7B0B654D794BE1FD5365C887C719B1B2D3C\n      5EAF1C7B29D8A1F9603FF8FADC782365A9E7670D6589524DE841856EA2E9CD51\n      C3EEA4A63CC1C7CBD79A3448052F097209B1F474A09523A2A584B5A69C01CFD6\n      64243348AAB057E210880AAD606D646EE9832CFAC82577DCD1EF8EB1B1E0CAD2\n      92D35290D86C1ABD69B0CF7B6F1DB79ED95467B535A9211758C98193417AD5ED\n      AE525468C829A003C716C1E4E1703C4CD7AFADC4C12E9ECCBB1A7D649C687914\n      9E4666AD19F750FFC7DDC6918397C2F0EF3F9BBEC42B6A1A523717310E051CE8\n      945922BF9239DEBB6DDDD93B79FBA4F5DC65F5B9C563B3B718B5A77F71109826\n      7BD9EE8AA3865C61FB4E77776FE9C55612C699EB07ED4BD4080B15999562681E\n      D873619E3A834AFDD161D1EFF5AE45F62B579ACE27296AA6E6D4E558228B00D2\n      CE07D8A45201BF8230194EF76EAA4687B5CF5BB8C18090E0AC2296769697136D\n      D24B7DA598111DF7B7AFB7CFC222F9FCF881717C1BA07795F4A92394ED96AC65\n      B49E25F5A72B484B7A9E73D61FA09986ADA767B49C917657C294009FC900FF99\n      36FC1642393E7C247EFE7D75FBEDE97D343ED654D26B04402F211368B32B0AA0\n      D830CBC22812D853C07731D787FD8900803A7D5018FF26C91ECAF8B7E7DB5FCA\n      9925C2C434E6EA82C85E2A1308709AA903621C386E318BE404C84696908C6C97\n      E82D141F66F16B1736FD0C3FC812EE87A922B71F3F04C8FECCFA4A59E40F8E7B\n      81635C9EDFEC9D76FB8A5FADC933F579324DE175009D559E1517599615067323\n      A8E5CCE6B96CD8F5D3747FC90880CEA62E3951714D90D588A5CCFA361A3D984E\n      D738FD0781F36B2B2B8BDE2453190E42CED52C5D0074603633202F10934D991C\n      E4B1966F627EA15B799516EACFF380576DCC1AA6C539103D45993121D5EDB47F\n      3B490EF4CC0CA03EA75FF201E04037E8D8F59A697362DC8E46774472271A2251\n      20C1F4399E145A0B127E37CDF966B3A6D0F3C8FF38AAB9187FA8FADF1B3FFE54\n      DEE86FCCDFCB0E9FC1CE99B19AC01ED858FAE1CE76570AC97496DDF2C20BCABA\n      66F27F686C99F5D63FEB7D3894F87FBAF8AA5BC37F36BE63ED8C7E316F0E2C7E\n      CFC3669F1E5BD3479CFC71D43D41D1AF2C2EFCB7AAE148F1C82A964C37182407\n      81F22FCE5F8ECA00705308B019BE059DA98D54B3D1537D9A0E1C4837CE564213\n      872A33AB82326A359AECE2167EFE39F3FCB92344FA69BEDE9CAB4D93DD3FFDD6\n      7C929320343EF172F7F5EF345EFA8CBA724D9E7E808E6EB9CFBE721817E5DE8D\n      8D8DF3D25AA359367AF707DECB5FC05E9E14C7663176B5B9BDBEC401E82C502E\n      2AAEA2227AF75167F1A9F155C31EC7C04E944B4A5E8D6EECE7770E979FBF6A6C\n      D647680C28C8930C892A732F59C61C51819AB1C0990F175318F2520E01AC7161\n      5524834776F9885BFAD6C51D907CBFCF36C2744EB95DD1FBE37B4115F87FEB12\n      5FC92407A6264A028CCF327AE1F0C3A3F5AB0B49ABEFC12AF66BA30F86799A2F\n      BCB881FC44028D17100F16B1ACD9742E7C894294B93E5AD0DE888C566699F37C\n      ACF29F20FF9CE55E4305C9E447627AABDF3CDB193CCC83074B4E1DB15F9A96E7\n      806D87CACFADA91355A3D28CED232F7B3B6F6E76D826CEC763C0CCF5A57A3994\n      64DBAE6F365590C65E02515BDEE3E9FB4933092D494A3D060F45DCCCB0C84919\n      22015580122BE028AA22F2A9B5C6DFFF340F2BDD925931039BFA524070CB9438\n      9FA8DE64EFFFFDF69C1DFA8D86C05056AA120DECCACE6E99D3E36CE1D5A00C07\n      56E14224E4B5C2E0EDE2C734EE9F2CFE72238A878347C6DA377EA1BFBA0D0C63\n      AE9C53B0C534D5F81B49632D6F40C94CC84A3D99E87A726523314D586E198E75\n      A2D09D1D589FC9C2C5AB5FFC0E16FFE84A74382C0B60513E3C49B72C5CC0A166\n      951A86B65AACD4040F5AD796AC5FDF341A8D2A05380BA9AD70ED7AFC6EFFF0DF\n      7FB038F61C6665552E75A6A7494AD2766C75C83C5EA946AACF8FAC868D134BEB\n      F774ACD00C478F7B9597D355E25A0D72484EBB83F6A7CE18CF1A051B1B9C3111\n      0AACF2E8881C24D9CF113E727C879D88B177D60F36CCCA8A755FC84CFE4D2B39\n      4041A15AAF0780754599BEA5A6DA815821E0364C30C01D954970C50AEA38DD37\n      C7F5D339F90FB1287D5315968A3937721CB069EAEC64BDB74EE72E6DF0F34929\n      274E314FAAFC498F2796FA485BAAA4A0B1492CB3583CFDE0A832F9E295664147\n      C5C4730D0CA880EB39F54A8AC4731AE9BDAAF7D6C82E8CE6F38BC66F5DCB5613\n      9DC3B84F801791441FA154A6D04AC189BC7B8FDD3CD97E7072F6CBAFCA4D23B7\n      4BB3CF4EBEBFB37A66A55C4C739A86D57CF7BDAEEF39EE537E6CC6C2ABD55A1B\n      50DB6637B6FAC8445966897B06D4E63F7A4888F4BFBA2237962CF534C6ADD205\n      8488058016782BA0A1DA08921A5539DDBFA558112E6E29675914CC44909681F9\n      5A8090A88C106C5CECC25F41180EF66EB4CEAC55AECB8F1F1BC777B9BEEC838C\n      9C594158D0A674CEBA2B2F0814EA3B4FDD8903FF190AA1A53D28A5804CA13D28\n      142EF5AC08AC91B4CB51F6F0EEF0DDF7933B3B78148BAEE5A85ADD72B5B05E51\n      20253DC518E43F8B4E2D840AD892DA0A55FB5F136754C989146F9E4EBFD54D1A\n      4B4B9F75C9B584ABD28A02ABDD228DB8EBA478AC3A12A5B1C82400DA8AED18E2\n      4D231912D6E61D0B8577A72747E39DCF7EECD9602CBF1F9F6E0B00DE0E2CF1F6\n      F43416F999CE5C60DA83D15409B9B1B23C1E8DCC189220E9788116F525D5C1A4\n      874277CC3976DD619452C7EB0E466167CE1F89656AAC32E5E4B16798B9E5DCC5\n      EA5E3CA986D3174CEF2BE797AFD5DDD5224FF4F927A9225594A427D5C02645E8\n      F4B30993A2832DA790495E4C893EDB77A87592E6DB3C4B6D5A67C6F36670D5F6\n      9A3C47B2D4CD6FCC4C313915D5F549749A4EB96529CB99E67C906713247A5C9B\n      E67159D57DDBF77CCECB35624179E9F37C4A1047B89BC62758A602352AB4A49D\n      D0A48371DB7016ADFAB638F53CBC82583ECA78BBF3C1787C7738CA11321D6C94\n      6AC9B0CECE2F3D5D0C7F25B87461E9FCCFF293BDFDBD5FBBFCCA819AFCBB8FBE\n      F3F2E2F2F92182973D21083ECDF5067E30E5DF8BC62734FDDAEAE23F251D33CD\n      B67DD9765D74D4DFA559EBC2E28B257C53223D0BB02B6614694F1BEDC854E971\n      754298BED9D6BF74572C575529290070F87AA5E585FEDC5270FE29736B0B6FAC\n      4331DAD97EA0146C7763C9F0F77FF4BDC5973F6F5D7B7678F4AE353A0CB63E36\n      194CC64737D62F3F93B9EBAC4C4FDFFECBE6539F31E750297A241BD840DDF4E5\n      3D00346ED8333DC6428DDE7B502BECF4F3AB2C4A6C5E401A293036233C7CEB0E\n      6C44FFC5CD91995054B929206D96785B8E354F504D6B9FE242372702FCD6D384\n      99BE24D2F34849367A6CA5BBB1C115B36A3D1C3F38762FB4B396B226387BA317\n      ED8DDB57978C4B1E376202EF46694C2D3B72C7B7BAD441FE19C04B318EE9F461\n      7978FBE4FCB35BF81C11D5104BBDB998EE37D3AD9ADABD0357651A2B5969F5CD\n      129E97D23286276C78732F9CF3FDCB6D008CD3835EFA7034D75DC6BBF6D8EC99\n      5F40FED5262F4DDBABB41D7B95A5F92490417E83E32975364CB4549CEE76CD7E\n      BB39BF7238BCD58A6BF6592F62036659D62818BC3561C7A62F1DA465AA440908\n      46DF8F9AA61CFF9785907DF64CFD773ECD7D0148CFD20D0086D62A1340A66243\n      94F27177FB8FFF6AA5D1706AA15637C65CE0B12BDDF8264D86E5FCCB3E0F229A\n      9998C9DC2B6CD918FFA490836CEEF3CB8F763E6CAE5D6EBE7A215B1CA569DC04\n      444EF45886FACF96964F7C9E615575AF877AA27CACDDD52B6E106DBC72FF041D\n      9E12650CD4EA677EFB0778F4F575D81C0C3B95E9142550A5C2257A0D15F5D344\n      262CB55F0A5A5FD920F3ED1CAA258428E5DA6F370AF6FFF51BCE4D4EB1256CE1\n      AB12E7A5B4DC8959862BAE5977F941CA27D2AE69CD9AEE60505FAB4118C5F752\n      0544EC9982D7F3FA710D3D28B3F3AEF1D5B5C4CCBC6C56B420FC635E0D27E5CE\n      347D57D6D2564227B199AFBDB85ED5B292C45AD0481F7D9ADA1199012ED23A02\n      500A15440D9BE8B65CE5610D97CB0C57545A8EBE122D84C48FDF3A39BFF852F2\n      C50189610F42C98582E41429A569696CC7A7AF1F2E5CDA2C9FCE7314F9D33902\n      E40269950A4840B460801B0B73A4ED9CBA4BDBEFEC2F3F1F92A55C2482704F8B\n      5902C9AE34AB572C0ACBFAF80749BE43AB76D5FC5BABCE97AF1496BE43A6DAD7\n      49092B834861B9ADF485F1407D7818BF79DC37F2AD6F7C4CA284627FBA37CA0F\n      A69D67CE95C99EBE6B1DB3E33B87EBCF9C2D6B9C375D16B41971113301F31985\n      36A192162DF3BE7CEF60F0FD87EDAD79EF572E54619D141B888499C39DC2D0CE\n      B78C1792333D3E8A807CF7BB0F3A6BAB96BF8A708B4BADBDC0A921C9AC31444C\n      A020E5D8D3E13C3E181DDD6E6EAC57965D1E3EB24EEE240C5BC0E6CBC8F28202\n      D573F34CE3CC8B9CD62B5860F2443F14B080A198F6A3D1DA0EDAE5A2D2233BB8\n      24FDC3E9DB3F4EEFDDE7C7D3C9495E64B4A11A35CB562A9759EE73D3AECCCA00\n      E617C343A2C82C20238BDC0556A41D6A2D58F5E32CBB1ECBBFECC656ABF95FAD\n      759676F6025A4B2C5AABA1B9745A2BC99407B04A009553012FE1EC9BF85B93BD\n      DB694A55D86E2E4FF2118B8EBFF0CC533C91DF49BB3BD4981EC50C3EA6672532\n      CBE264A9D668B5DAC37EBF90E9D2FAB29B93224E7C89D7837A4858B77B3CC562\n      CAD428CFC769969A2C122231880FE0D135E62CB290A1ADE6CAE33CFDE9708F55\n      E26B41EB775BCB573CABA8A6852192D8988CA11A393B881C79F6CDDE51A92908\n      2FD2C933CDF92DE6ABB84C18314809002232DC5B3CBF9DC173B6CE88EA2AA32F\n      B61AF314A3516A4A83502BAAD021557BF9F8541465056CCA848A7882C4E36868\n      9B64DDB22FD8DEAAE3B23CB72B927A6614A526B18781F546747A5064C0F1BAE3\n      C9312FDB8DDAD3766BA3726E4D8FD67C33ACF271321173F3EF8E92BBE34CFBA5\n      29AE415289363C7F5199AE3BFEADFA4BAF7A9B4ECB9D0E4FE63A8B3F4C0EBFBD\n      FBE6A7DBADD5E33C37BC7D99D6A2E9775AD6E1B0BA9DF31D32FEC6C2FC3FB716\n      DDA8D8F64AC7B78BEE705B458B1B8BAF720B7238F70D6C403521C8D446844F66\n      6D34944752014564442BEEEA330683CB242D07B8CAB4427926800AE776C036CF\n      345FBA26969B68B5432DAB78EF231A06FED92B630BE50737BDB808162E1783D3\n      61FC60F1E2E502CD99383FFCF0DBB585ABFE8ACDF150A5430B16411B0269A324\n      28C0BC2AF584DCFDA3E4CE01FEC2F91A3001C87814012570A99FBDFB287BB4DF\n      7CED52D4D41FCF4B2483445F5F76ED25AAF58BE0C3F3995E04ABD0AC3D6D26AA\n      8BF8289B3EB2E25E62C9CC64ED3ECD6EEDBB973A794DD094C9874579A85D3C9B\n      D7168A0E52716A3396C20AC1CEEDA9A3BB872B6717490D6062540CADDEF5B4D3\n      6818976941BA86B4A4E6829008000330053C872155729917DAF058FBDA931208\n      3D36BCFBE8F48303FBC29CF56C806849E11D7F9E557B500CAA6C2D5FFCF299B8\n      CD036E284B506A00CB429056064EF63E673E225721051AD59BB61586A38DDDF2\n      BDCA99677687492A8CD24347FEE0DDB133B560F5A491675551499BA11AC503EE\n      3D2984782C27EC17B71ABFFD5AE172C0B54C2BAF315D8AA428E851887CF9F6EE\n      FE0F7EB2BADE24405D2A03104F456297FB931B8A67AAFDA2CDCD0C657A1423A7\n      8983C2D39F4CC238F0AEAEDE3EFCD9D62FBD666D3620CD6120CD0A289B3632D7\n      9DEA331547CD009FF4A8AB599302FA1B2F38A23901C353113D7C6C6605CDFCA3\n      FDDAD7FE97B770FF5757F4B09FB0EDB2826A16F9126A4B98313F55033A51AF2D\n      CCFDCAD35998233C47502CD0B0B280322CAA1F0E7ABFFF612B012EAD329B0794\n      E02467AE5D5E9235B52AB7D33E3D09163CDAB326FDC43E6B9A8199EF4A8887D6\n      A500B538C979F928C1C4F2BF7436B9A0B2427899C7CCAA02647F1CB143A7FF51\n      C40E4A1F9B3D3C6E9D6DBA5B6161C6C0C221E74232D0F2EE7A9446BB0861C289\n      56B0F4B03904482055A0D5605882A9A967FB909EB29B1E46A7BB9373CFBD985D\n      1D5AB15DA9825BA98302DED5E62DE2D1B8FFE3FDD58BEBC535053C2C18368891\n      2B64EBC62F55B042FB3272736AC136B95F1B1E25AD978DC43FB58BA651E154CF\n      0E4369324B234336F74EFCC99FC57C8CF127C3FA6F6C184F2D03F9D493740228\n      7F99413A1096090B6A242A3FC66F0F8EBF77E0BC32677EB1094FCFC9E64F6FEF\n      F86DC79D0FF241CF914EFF711F3E7FFD5C2782975F5E33BDA6BE61D40626B651\n      96B0E504A09DD174F0FDEB626FB2FCD96BE8724B990D229611B252530027442C\n      AE681E6565CD69A0F170727C1B9277B0B82E658BC850EB6AD3122B9713531FAE\n      CB297C543D0D0BD47ABC1775EFD7CFAC54869D1D3D744EEEA6C0F7146C506158\n      7E8E6AD8BF60AD5C9324AC90A50D962A8C009F4BCDD325212963D8365D4A68DA\n      4387BBD14F7F96DC79C426B29C8AD12873C366877954E463314C50D550BE1D93\n      98F2C4E576CC1BB991303636CA304F9A398E8939E112D6E176ACFE54A11F1D3D\n      FEDAFAC2972DCF1C41C8BA6D1B85465514318062036A28F6079533A56E01C984\n      92C32AFF93C3FB3F9283D2549FB3CCDF5A3D7F87F3FFD4DF7F44CDFE71EA56D4\n      608C5AB8943CCFCB86E99C5B5C8A8B4917A5CBC46C7B7EBD440004E633D16276\n      5226D261D43400883C3E3E1A19D56E34EDF9E25E82A60AD5256E586E96A7AB06\n      FECDCDCD5FF0DD559E5B458E1DE79408347076D2E2F182F3A37470F7B4C752B1\n      6EF8E716A0BA09CF32589CB91CB9DA3F244BB349514180F83DC3882D76DC3F2A\n      8AE962685F09DB17911B260A707565306991312E87551A43EED3B21E86043A6E\n      985559BABC58B5CC550B92389F785E61607BC243E6DE328A77D5A4819CF5CA9F\n      C8E2482BB21019655C49D36F5AFD6E998D8AC5DA0749F2615F6433D1779C27C8\n      41C242418C5E514BE973EA737BEED7C3A7963B1DCFB6ABD0F9BF47B7BFFDF8E7\n      5FABAF9E3F4E8F42F28139AEA5E9B70C3A395527053E40E35F9F6FFF0B6FB915\n      95BB56815C20C0FC818CE7169BAF26CC70110F341D541460B58E2DF83CFAA0EF\n      C91116D6B366B0CB65E556B0CEA6B45D55C849524CF42497C0B3235F484F422D\n      36365FBD4ACE6DAAF90E6ED54FF4B50C1627F79BD2B7BDF5E4F8718A7A739B4F\n      ABA28EADFCF0F6779BE1056715027E28CBB1AD37B83EE8D0C269DA674E001A41\n      A7D1BD1FBDD37879AB7D66499699414CA9CF5D4C6767D2FFD97BCDE7D6D5969F\n      CACC83AC939653A032E6A28117600900C36993600ADF4422A567D480A455E971\n      163F74329EBB6A4254A74BF8BD03EBA9791E40A5B4C677E240F8E3EDFBC18A69\n      7C6CBD12A5D649C405E38A885AEFF680166573D3156E94A7667A5BF99239CFB9\n      253B35746F36D193E950064D63A6ECAB35C42A6D4B09AF4CB4902F503CC103A0\n      534774FBFA365D71D79E3B83739E1F4DFBD78FCDC79E47EBEEAF86C7AF1C77A6\n      2D496734899710CE0EB7D42D32DE1B87171DEA53756444FD6978C92D8FF9703C\n      ECAC75A4A10FEF7D3C37FCF9B078C81D05B404E7DA158459CA27348142088B5A\n      E3B8C747E617CF37BFF9F1C2D3B2A954ABA653556976185B8F9A624E7CEB5EFF\n      DEF5C5731EAC8484F7352AED779B87FD0F7262188D6B2610119A3BD492299958\n      95DDFFD9B42DB64A968CCE44CBBFF454D5B260F3DA8429A1352E75A523B34238\n      2B801A5B6139D3BA7AF27480184A0BFE3C56C57E4FC5131B12F836DDBFE3FDCE\n      BFFD00F7BFB2AE9B9084E1001D33A182CB1CCD382A8E82975AC1972FA865BF28\n      052FDCC095393F64614876CDE37F7DA3F3088A3B4ADD3CA139E4401B7043BDC1\n      EB49B2175B99E32F7ADDE4A8C8CBE5B555C81DE96E924C33738B9873C48B6AF9\n      5ED4E7278B9F3C8B2ED552125B95874BAF6039A35DB437C61FD487EFC15247C8\n      99960EE95C5B23419ED3029988E2CAD0C50D1EA921B4DD8FD45DB15AD0C1234C\n      EBBE97D8E056652078A8363C09C184C983EE7B3DA31DD45F598B6BC320714A95\n      66660E7804F5217444FA683CFCC9C1FA85B5E205921B7930A86152560C950034\n      B45DB6A69E984A73649DFE7CDAECB4D1D934B327AEA8335C2415F01DC702F669\n      E48C39F8A693FD309EF069F877CF39BF7E2E07B83666A6A9E7160A526416E429\n      DB84D248A7D5E4A0FAEBE1F0ED41FB9B174780620BE6EF370E6EDD9D7B795DB0\n      DC8C151B92FD7B3B6B17D601B0C94E5D868B1572038B5510E0D8A55A3DBD84BC\n      888FD29DBF78BB59731B5F7CA16C7A8C76480950C084F8B773785E7D00AE39D7\n      E3A1C9F62D2507FE5AA78035902DA3720138E6A6D047F0C0AFB5F467A46F6888\n      A3554887DBE9E87170664552333F0046782FB70015640E10476C032334E69E26\n      8BCF4A1BB6902566623200EC219F583C2326D1084CE42A9A94776F8D6FDC4E1E\n      1EE309CA8785A3ACB930443CC9726169557809B038C6C4E4A42E4CA3D4A7615A\n      2D449FED1744E6A69EAFB362C0BE29BB9FB27F39E9DD30F3E78DEAF309B91CCC\n      DB12AF042E22798C0B61549550ADCCB126AC5FD1D8323B8657B31B6F86E25F1C\n      BEFB7EFFF8BFDF5AFBA5D8F8619E7C5B4C1EBADEF038C65262622426D7E249A9\n      80C75167C642BBE6D73D511CD791B9C0F17C562D556CC9B243D3847760089B86\n      0958AC72CD14C901CD1E17F9614572C8F3A55A40F2A576E3AC40CD4A25AC1A50\n      C925478369CF593DF4AD1F1EDD827A0C14730B9E7077DCA08E5222D7BABC59CD\n      606B5AB654999E41241DC7E2342E0EB3A26F59FB0EBE93F6459C6F51FFBC0125\n      CB75990AAB5277E3C2F20130991DE0B38478CC0726226DD81C00D8CB2ACBA1A0\n      EAD17645639BDE89BB000BCFD8B5464AD22449003D38F49496A9C7167A2E24E0\n      D8A3B7D2C17BA7710A355432A8D05CA4256C2C8A2C81CEB92B7D79F0593FFC8D\n      C52B97E9E22A701BBBF85138FE77AF7FF7571A97AE4C2550838F8269AF88DFB4\n      9DB28B8F87651F4D7F636DE1BFB3E717C7E5C8060AA2846BBD5374DB9DFA6762\n      2059B2D48510102DD585504379829FFCA347A1B55AC0EC444BCB6BE9AE3D208D\n      50EE21E14951E625CF52472F4891E99604A52C163EFB82F7ECF3E4F96785936F\n      EFDD5C59B9E054CDEEAD0F0D473436AF2004EB196FDFFFC1325B35D7A18A01B8\n      1AC12E82809B19F2E8E16B8925030298A89DB73EAA874EF0C27900AF36B2B0E1\n      4056B647E5F0F59FFB2DCBB8BA5ACAA909FB201771C00CBA60AA050CF81B8889\n      825822336AAB1B467199CAF8519EEF38A551DA2446C2DD4DABBDBE7F7931F50A\n      87F8DD8F7A35D634D2E969FFD1D2279E51A199270347715DD664884BFFF4A3BB\n      3ED4C12BCB83EEC4E852375655A330561D7D1F89592904506AC3B0A0FA03B156\n      5C774655A21259A9CD7614CB3385DDCC8D5C721C0EEEEF2B07B59E5BAB1AF960\n      FB54FD79D5DC9E33BE5E1B7F659F4EADC00E9506D92213A9C50C32228377C664\n      421A975AB9DF1F1D4661BFE99E3327C713AC4CB7E5C8194D402764F4518607A6\n      C91C59E9FE201B013D2D72D706980E85F0B8EC3BBFFC4CFB1B1FE796566A56BA\n      99139E8D14A28CDCFB8D517BFC6F6FA8F4B07E9102A063C22B595991C29B368E\n      DF1B3B353B7CCEC87061153EA3B8302790DCE3D7795D6C1C57DB9D5F5B65CFD4\n      0A47478DC1B51D82DE9C330E3813349E15436D5F59CD441E758FADD63890D215\n      44ED4D928313C7A538C2C3B7F3FE41E777FFF47DDCFBF29609D594E99148583B\n      2624A745B48AC80BCDA54F5F42755BA63107F6CBB1313BEEC2C8E9FEC5EDEC2F\n      F7578B79D826198BB917571DABB6B844859D3F1E0A3F751B56795C4D93117DAA\n      F2EA2EB96BAB1EE48042ACE546663ABBF55E7FE47CCCF35FAEC5666E08C3E636\n      BC3D008D34EECA0743FE3AB57B1DE41553FB385CA905E76AC288848131F00CDD\n      00A0B5C0148004C00F9A19E6DAE196DA904E91AC72A328DD0A4AA19530649490\n      E4E9A9DB7F6B38F7994BE5452DCCE61766456461958C1BC608A15842219CBC7B\n      BA7461A5BCAC4A967BE3100A97D00DD2106F906C4B65A596F0F207B47FFF68F5\n      EA8AEA544595CE9E465E70AFA29EA2538C73375E2C5FAF86B74ED553ACF30F9E\n      E757E76565981901DEA5C712F53841E968060B686552ED9E8EFFFC808C8CC6DF\n      BB14AFEF11EE58EFCBEEEE71FBCB170B11795D91ED245194749E5EA90285DAED\n      C26A01EA0476A95DDAB885B57C536CA479F2C1E9E8A39D9517CF56171A7963C1\n      41F334A7881925A1A63025D36D3E1436C5681A1DDCAEB74DDA5E14C63C96A16E\n      69A3F07D21CDD955656859BE2AD6649AB8DA69B8FFB08C76DDF565207CE5FE23\n      F3F46EAEF5094A3DFA40CCA8F2E9DC3967F599C26955A60351A6FBC58090718C\n      8AE32A9D54A787D5D1A1EC0DA607C3F1E1146A9DC1CD1A735C854CC1551A4D4C\n      DB29AC664663220726B715F162CCA78A592E507D45B25203740E60478B193333\n      8ED0BDD2FCBF46837B81BAD20E2F1F0F3FE1B4AD42F875A7C465C94568D60860\n      C3A2B2B831A9AA4347CFEE6E8830F017FF028DBE3DBCF7E5D6F2B5EDC91B6DF3\n      DFF5B63F802D9B31CC8B940988103DE39169197D2245D3648B61080FDB2F655B\n      50C0804DCBAA9B6C8EB2BA406D80DF52CE1AA385C38CB60298644E008859D447\n      CA1785C28253CC53C599B3AD8A4955AC28F646A3FDB3DB1FAD98F6AF5E58BB64\n      5B5AFA40C914004DA9679D66C3EE1C5EDFD52A12B29A72541929B2764EA77B51\n      BE4BD9638F3E16D9388E7C8E96C2FA82E52C0222C190FD948460A2C8C1468D3A\n      50FB12934E6D36CDB2D0B0EC52F95C41F89EF8E84304045B6D950E6C9D02DE45\n      08001A8985C7B3D3BCD6D8380ECDF7B2E99DC948DF3B72D9E6FC4A678DD6ADB7\n      1F3F8800C5432528F1A7DB18FB68A924DFAC5F7BCDDAE40E3E5AB1FED5CFBE97\n      66FC0BABE71626A3C7C9E19B56F25D959AB1D71D019D4CFFF699A57F64CF6DC4\n      32861D435012DA7F317934BFD2F94A59338C9C8754CD2E08A9359B3D25FA7A67\n      769E35AB4BB3C3AC0A093D23ABC74874EB974D2DA22D1E94965B5239D06528E5\n      4691C2CF6B4B5CD65C38BF89D7EDF1A63FFFDAA70152ECBCF74E7DAE196E3E85\n      A90F38AF7BFFBD7AE5999B35C1265C4C814AC90A2A16665A728B0B6DD1C36849\n      263BC7E8CE41F0E9CB69DB75044485A94C071732BFFD6072F468E1C5735AF945\n      6979ED22842ADC6472919026021AA1F50BB5F1A316549400A427E5F4BEAA0EAD\n      D2CB0D9DB492EB07A23B6DBFB805FCC143CEF0D688A5383CB7B2F7C19B61BB61\n      5F98E7D528D0FEBF44B27A455CD5ED4F1E3D6A3F7531850FDA9FC282F6A683F6\n      F945C88DB00FB3921BB665C2D303A2054F528A992EB29050210BFDB808671119\n      B0980672550E8ADDF76ED4173ADEE5BA72847C9D973F10FEB3BEF93577541BD4\n      69539F121B924F0A78313DABBDCFA66F24FEB2976E766969583F6FA80B2945DE\n      60AF1F766A3814158212E5C677C5E41EF7AB1A81BF50B9A52FEA50EA1890A86A\n      1C1D8961F0F5E71BBFF10AEC793A6B23D7545F165C947170BFB1D738F93F3EA8\n      B7043B9F0213B6648D0303C1C219D5F77FDEF516FCDA659A1178540D28A1A59B\n      A0098A7F20D9D4CA9ECDE77F6D55CD79507BB56E4E0640C0AFB425328028A29E\n      58DDE85F9A084AFC44E4513F1BD8EA462F53DB87324BA9E5AA7D347A2349D1D9\n      6FFCD14FF1F4972FE20AF643296720C67031D924F2A5BA716D11F99EC5F5DD63\n      41329302E06036AFABDBA3FDFFF8A6D3C76615E82B3933C7F3922E43C1B14787\n      853FC1F58E3B48BAF0A6C19257B965D12BF31D1EB403639D6891912E8D8E137A\n      26AC7F72A56A4649953B3234B518680AE9B4D8CDA2F7A7FCEEB86985C2701333\n      AF3FCDCC36E4F669653066D8FF1F4D6F0264D9715D8965BECC7CFBDF97DAABBA\n      BABA7A4503683440022040823B2990222929280D35638D6C8D368F35632B1CB6\n      4333316387631C61876D4D48E1912C69461A990C8D1652163710DC0102241B00\n      BB1B8DDEABBB6B5FFEFEFFDBF3BDCCF4CDDF720702BDD6AFFFF365DE73CECD7B\n      CF457AC0091C7E8D7C025908A217E5DABD19E00655B5B7873BC92DE4E4650032\n      E564028EDF0629B665FDA327BA33BB15E29BD9D453DA140A7E312CCC00253787\n      E33BC3D993F3625D807E62A1AB73FB6408D2C7484A9CC1D61896A3F9FE1B29B2\n      E3FA2396326DC991B0063A571E56A861C76E8F4862BD3313BF120E8D6EE91FAE\n      975E7C2CB1403BC0F906B59CC06916A48233AE2FF500C0A2145DEEED7C79A3B2\n      B658FBD41C6FF6556E8A4B13950AFBFDCB3C195BF782F1FD016D37ECC50A9B29\n      0BCB16AC0CBC5715125E5564444FF13026CE303E7CF9266059F3FDEB51592177\n      858906993A5C63641B12C38701A24581BA6EDF338A6E69A6AEAC1964CEEBCB3B\n      A5C7DB0099D08147DAFAD9A344C2D710DFC88AA2733B09364B2BCBB0D1E4F686\n      7174A728F4752C923936DD103BA15D9F3DFB6E556AC07144C3480D43D98FE424\n      E9474769D815C3BE11847CCCF9C440DCB3855DC1B06AB0E6896EEB0701E3D072\n      88FC808E74B355560E8B7B05FF6E1AACB9B32F2480ACC17E4D5AA9AAC438850F\n      A1EF54BD7762F43DA43EBF777775A1F2D9F6F2B98349492ADE74C62C0F27E367\n      D15C39A1375CF54D63B2DD1DE45902A8F588DFFC0C3E5132AAAF1B932C1C1CEF\n      A67F5E0DDE4CE2DB0A75063A861EAF94EA257B6730DCCD442699874164A4B008\n      ED9ABF54AECC595E1E85F0A62B0EAD2BBC88CD79C44A05AA51B32C0D33130ECF\n      B48D122513D890253BE05126F3A1CCC7DA67D2CDF544557650B237F6779F6CB5\n      3F5CAFAD8BD82711C883CC84306562645266711E8330F6192A98E271562DDCE9\n      D45133412C0C8B5ECCF70C010F6F47E5DB61D0D373B2290070C5B2E7CA95BA69\n      D6E1B1C7B1290AE5D289890EE24870BCE4B5FC0C5BC924748CDB34D947E92AAB\n      2EC6041E62CF42B12129904909EF407BA5DE358A2B9DCE3D644C2850C9DC44F2\n      59CCFED1E29976A3FAFBD75EFBA64824B0165139A3FA89858F551BCF9A8DC749\n      ED8C3BB3589B7D75B2FF3FFEE4ABEDD9995F6C9CE1FB87DF977B7F678E54E484\n      0970FCE01FAFCEFF8A5D5F0A41006444E141D5FACBF05E75AEF90B79D3667151\n      06324FD543D7D6A91AD4F64B3AB9450D5066BAF21DE9F21594E8CEA5A95996F6\n      92A496204C4E193F902603E4611822005A546485A567FD40CC5A6EF8CF5C304F\n      2C6C4E3A334F3C91575B4C2237CDD5F59B1C58D76A4DD9612142DD6D4DF44C1E\n      7D98406B62FD5BCA553C08D4D7DF363FF868B13E4B736A4646416DC930EDF6B6\n      5EF9DECAD92574A21E6390DD085510CECBB05FA8310BCA55C2F9D44617D3EE21\n      E04AE1BE483709EEC85487140B93A31FDDA0B9AA5F584E2A02744C7A639C1E4E\n      9ACF9E39DCBA9B6DF5DA4FAFA3B24E6EAB08E7568D33EA1314BF732F0B556DE5\n      F8E1FD3B6DD71A4C227BA6E4B635D6C69C33D7B6DCE91858430F0045523E4C0B\n      CA248941DBC7125BC050690E9B0ECE5F0F77DE3A307DD27E62A648F0E1B70EE5\n      A058FEF8BB83A7EF3B486B395D4C1201DD0550028A48F07DB27373AB72CCABD7\n      1A689FF4E3A3467B76D8EDC0B732AB6C5A1B60C92EE95E1DE0235A4525052490\n      026F9281AB6B792A5C1DE2A0F64BCFF89F7E97488684D05C3F5769F0585F66FA\n      DBA55BEEC11F5C9B5BB393E59EC841BF5480D4C2C2D9C3FAE68FF6FC39B7F6B8\n      1DCB9127EB86768451EA904DBE15C622763F6339CF956DB72D41F53A992D4C5C\n      7852A3C874F6CD74F2A92E97318C5C8F019EA6DCA7F3C1618B140FC646779B81\n      F022CDEC4A165FE749EDC4A7FEFC153CF9E431C18804651B87B5A51239E3E727\n      1DE714083233369434992995A950A802D769E00732F8FC55741D600960581838\n      ABCC78F66C29564577BF47895D2FF9E97E4AE0C77A6E9410DB76C61B63B682E9\n      124213E2A5ED83DD2DBA40EB4FAFAA59A73039CF1217B835085263840251BC26\n      FB9742B7940B2F1061B9546BD14743ECC9C808416B33664FB956AE20EE505300\n      5019585338836B4B6BD5E0ACC8ED31C126CB7D104E8584A7EA1D5E9B38E56AF5\n      E9765219E95692E9C4628300F726C528B30738BEDC0D3A99B752325711682E9C\n      809E543AFB211C23776388D5B6A29BE5DEE571E92CA1C752108D86F422773FA7\n      AC12943050B06A28072EFEB637BED615CFA8EA7FF9943CB60AE8CD8C22A319CA\n      878A9488A1A70B297B1CB17EA96BC47F7D6FEFCACECA2F3E831F29104D51618E\n      7FB85B9F9D5567CBF960686E06C39D817B7AD96857EC7A451A5477A02A13635B\n      CF55CC50EA20538DC8FEE8F0EB57CAA7D6FDC7EB8143295995459999BA5C9681\n      90C459C6E0190963D40FF66E961BC428D7743C375A9A2EC11B43D428DC8C4654\n      BA9AA4900C7418213ECB447C78239A3C681D3F8190C7376E91EE5DA06CA6A15D\n      D3409827B1ECA768F1E4A33CA783CD7D71D8F71261A59C8F20009238E5690687\n      C200616449B361551D61500E7B19E284CAF4C5BEC9596E27DA112F42C213B21C\n      93FB44FDC9FE6D9192CF9416D79895594505132743014EB44750E1EDE4E64B38\n      FF93DD8D30C97EAED5FAB9D6BC3D1EE366E9C0E607E9E8949AA909EB8BD1E11F\n      1FEEAEFAA58FCE1C1F19E37BBD07EFB78EBFD87EC2F4CB9BFD9DA4DFFBC26CF1\n      FDAB37F70C96306284E10B55EF62B5B51B47AF87C17E2C815A17868A7C510A65\n      CBF596AAF512A3C0160CC1ED229F41B42A54839855CB32B5F721896D93C70904\n      F33D1EA4AD6A3FE54977623BE6114D866178D25B188DE48F0AFE9F79EE472BF5\n      750885244ABC4C17CF15C2CC9941ED5014101B18F0239572A1EBCBBDC2CA1223\n      85C793EBBBAB28CB06880716EB2063A3E0D792F04E180F20586BB701B6EE379F\n      AA348FC19B492686590406100DE51AAE5F58043649056FA9B8134F96ABCD4A41\n      8A28D6724B4F3E413CCDD9B4D877148EBF24B29E764B24674BAB9D34D8CA8FDE\n      DFA8FC8EBD7411BB5F63C3FFBE7B77270766E9D5645CAFCC342961FDBD274F1D\n      7FCFCCC927BA5E09197F516CFCEF772F1FAFCF3FB778E6C1C19DBFE5BB833184\n      41D757E96FAC2D7FCEF41B610E728115B257B7FF4AECDB15FF7351D5375351A3\n      D4328127822884388EA6E343010889CE9FFD7DF18C2220210A9CA57AAA9A4505\n      D52E21B0C15C625B48276590769724292DE058A6496E24A91F0740CE44891D56\n      B1F7CC13C73FFBD9AC51814358CAC4E42737B1352AAFB7A41E7C9F023E2BAA1B\n      F12C0DB05C0321D5B2251BC5F86FAE92E7CEC8F32BB05E66C420DCE49EC1C6C3\n      EDAF7D6376B6449E3E0ED4A75A98855B808021AA451000A1ADA741E962F3E9BC\n      3111A7E37BA8D8B7C944701F01F076BA7C6FE823CB393D17F8103E09BD15C6FB\n      C3F2D36BDD74585C7AD03ABBAC962D9287A0E432788CCD16A342ED76FB37B74A\n      6E2B1B45F0DC0C8F4C50DC9AAF82FED26561B6451C6698ECE1B817FCD0E25E09\n      9EA6791C5B11C85003742AB04950BB7E5C310EEDF4DE5E27E91C7B663D38E477\n      BF76E789273E1EFDDC2633298275E7F0F11D95004B2A623A0636DDFFC9C8DDF3\n      EBCB33817520B74D62177EDD1D1E1DDA9E67987686A583DCF0F6247C7B5CCB6B\n      44D37D409B30AD38B06E6E941D5951EB9FBCE0BDF8840081800D4E3185709486\n      9988A83FA13F11479FBF3173BA12B70EA5C81DE169F30444AC497DFBC7BBFE8C\n      5D7E94E52234E12D214A71B5B82A469747645D9117253DEBDAA865483BB70A4A\n      80BC310085696D8C662153AB7F5D0A35759799EE27CDE10B38A6F9DD0911070E\n      9CEB416D7C295443CA8F9FF8D0EF7E1B8F7E6A3E965279CC3FE698EB56BE48ED\n      A536734A8261512509E62647CE98F44A4593D5B26FDC1FFEE5CD56DA18A12CAA\n      25F525CB6F94B2DCE81F4C804DBB2E1A0631A0BEDBB64157A48769FE40949B3E\n      39A1B22234875E67738466D5CCBBDBC642A97059068C50DF15915C1BD566F25A\n      3FFED6880C7C7FD5DF4937087217CEACABB95E4E408B16806E58EB3E3DE34432\n      6D1D2721F24F73BFD40035C3E0ECA5762EACDCCD2D5011DCCA7096935163EBED\n      FBADF79F7097752609428B2E84D2C381B4EF5D3ECEEC7D19BDD595C81ED861F3\n      B8E9F9B61216C7913E903AE74A633572BCF6F0B541DA895ACF57F25A604D5CD8\n      2E41B997655653794A46D89293B7A4BAE4242AF0FEF18CFF334F24AA6A278661\n      A6059CE01CE473456575B33062EB50B289FF001FFDEE8F84EFCEFFF3677BE5C3\n      32572AB0BBAF5F9FBD78AE68C962B7CF80FC27997BE104A943D4F521AE288AF5\n      A047E24300B4040A40471791B876EFE8D2ED99179ECA17486E7A365E93C89710\n      6273C4720759B9B6044645BC7B07A7FBFE42A5B06A58AE105585730D3AD18008\n      C4BDC21851E9E9BA230A11581886677131DE7B27CBF767978FC9CC9ADCBB6B8F\n      77A8E4324A4C58FA18A5DDB0DB8DA959C932DDFBA3B2BC88339EA7FA0A3DD741\n      1E7ED6E3EC1001802DC13BC8E15CEA8003E2D5288433ED39E42A63598A329E60\n      AADBECC74610245F9B1C6ED0FC23AD95F765DA439233C1B49D5B6E66E6803B5F\n      C5C91F6E6F2CADAC1D1B844F537CB15283101557C9CD68F0F5C3F8504510013F\n      7572F53CAECE680364F96331F956E7E8036BCF7ED239968EF7DF89B6BE81E546\n      5E5C1A0E3A59E014F9C7E6AB67407B61720DE13BA1188E934044D29776A29D29\n      7C832D54CA2DCF77E8D424B600C29A1A59E6FB2E08E94136C1EC3888C2687858\n      9DAB6DF43AA65BB2ECDA9D8383AEE04EC3D21DE123F5FEF6C23F9D6DB482D0CB\n      14708CAE999392E5E6869F2262526E91D8C483342C08AA21D34AA51E6D633971\n      00740CB8793E41FCC8C803A5AF26465C7489B18D8A2D860E27C9C6519F20B26A\n      969F2A374E52ECEA2E55405920F654FB42156AC3175C0A1719F3D831D23C41B9\n      B2994A38111880B2C7E4BD7177732CBA148D1DF45469F15F2CBF1025D9FFBAFD\n      CA417CF42F1BB39F5325D92EFDFE78FB8FB77B47BA05C889316A2AF1F1A505D3\n      E7A9C87ECE3AFED3495394C8BFE5F77FF7D6D55ABDB1ECD7EE8ADEC1280B5352\n      E1E17F73ECD8CF9B80A0284D123347FDBAF325D4B53DE71706A5929DCA3AA30E\n      403F9214C2A626CFD321DAC6F47E673A2C0E1EA1319D3A8A04D2065D70A2399C\n      62CBB2E0CF81A6074AC6105EB56F6151485ECE4919F4844DF2389C04831C541E\n      F5DDD553E50F3C557ADF29B351DD7CE77A89EF35CE2CE4720C080878C1A78EB8\n      A6F6821412F483BE24A4799CA02FBCAD1E3B469F5C07C2CD60D70373B2A41D07\n      BDAFBE0C02CCFCE0F921112DE141983140D2A22A514DA4CA429BEA4AA584F679\n      E4231E6E22BEC78CD420B362D43FD8DD2E2B8B16D45D9D899DC060A6F176B7D8\n      1FB9CF9F991809BAB40D8855B9B8949248BBAD150E6BAF189EA7824E74E376B1\n      97F945358A23F7B4BBB9736369FEB865038DE48645904940170225D08D28E8E1\n      F859A16D1900D623C2A3A190890687C2C69963610F1F84BDBB3B85AD668F1FBF\n      F9F29D53F6B9ECD753A40B782981D048184A24022AEC05A93B718FBCE8DBBCEC\n      97B3E3637BCF3B1CECB5E69B3C8A01CBAAED664A397C526B6C0F2FF5E53629D9\n      E51CC3C39EF0BA870CEA0649D74D6BBFFAFEF2C71E57E11869A731633ACB6E08\n      44CE3469FEDDDDE1771FCC9D9D49FC4320EFA01C08D32AC70AAA7B3F39A82D94\n      E8AA4E5562F89F659B8399C1B7FA4A15E5F7B1E25D395EB44D5421B2A48D344D\n      396544DA564CA3A07A985F3774F398691659A6E7E92023EB0E38C8900ECA69CF\n      C70EBF528C6F2666B9EA5E7CF4A9DFFE5BDCF9D812F285B966D917EAC37A414A\n      4E6B76055916978932013514432E300A3653E2970E77FEEC47E543D3111602A0\n      3C66E1B67EEC87F7BA1E29B5EAF5E1DE26A29E7BCA0DC9D8EE95B23B05F1B1BB\n      46182362820F778F64C998BB380F9A84F880194899865D1078BF9C927C8F4F5E\n      DEC0F7839963EBB03D8F7ABBF5739E7F0A228ECC3017546F4804DAD4D0CDDBDA\n      641CD04F7B0C6153D342F8D44C1A38712428735F8F26291233F5503DB91A1C84\n      83A59F3B99D3D8CD1CC0DC824E9D44E1278CB23875EEC4D995893DB7787B7277\n      EEB857AE803E01F0EBBB461D363016898490382E6DBEFAA0DCA08D674B318DDC\n      183E0F8B7D4EF21243801C29DA97FDEF84C911514F7AF3BF7E06ADCE1A7CEA2F\n      6A0404CE330B95B0F3485FAC73DAB16486BE7774FB3FFEE8D4A79FE71F6B0CBD\n      7E33B5D4BDBC7BF35EFB038FE74640F786FC76AF68D5ADC78F53C767CAD11447\n      272E70817D2E2D13A308A7E53C4BBFFD7A16E7D5F79E8FAA70806B0CAD70E248\n      0A7C008396455E96E7A03CE2C3DB3F6CB719AAC3339B256ADE109E76CD67B069\n      19CA6DAC607BF9DAAEC9CC6243970CB3AC18ECBEAD8C41737ED9E05EB6B3551C\n      DEA13B9DE068E8C3974400ADC03059C6591201ABD696033A276133645158154B\n      9926B64C20EA859245A2D320C00688AE5B06165FD1466E2A2914C71988144097\n      D87038F6BD21C2C374B74ABF38DC1F8DA34FCD1E3F03FA37CF61957387536106\n      D2FB661EFCC1EE76E095DFD35A7C2E4BCFF3C28AF9DCF2CC90A1BF88C516DAF9\n      945DFB448F184912E1C2CEE87EB3FE1F68A870E9B7579E215B777E22B7FF762F\n      B85C245BBEB73D386A19EA232BB5F9244B25D972FC7DE24F22DE191E8E60E7E7\n      9A5D2B90AA86D130419397DCAA8700D1D3647C78A46BC0EB5E5726B4EF9F68CF\n      07DDC3389BCCB41BD7770F7516CFD343584B367568FA2E9BFE7273A50D749852\n      69BA7B9358942BDD2402086C5A6E7767C76BFA03438E7956712B6650D04CFB34\n      47805826B05CA06EC6385371C9EDA769DDAFE6E35022A98DBD096C4B7727CADF\n      EEF78FF27CD5B23EBAB0B2902444260905B80676C2E03C6CD3105EA6CE1C12C1\n      69164A37D7EA794F01C13B22BD39EE771321B5231056A67A7165FDBF5D79FE24\n      AD7D7578EFF7EF7EA7AE26BF3DB7F21827BD6AF54F7B077FB575B061D490272C\n      919D376BE9F0C8F2E9878F2F7E3A6B9D4CFDC962FD2BA4F77B6FBE1AB9BE4827\n      A3CC480CAF914D7E676DED538655416A92C44CE27ED9790918B8C53E3B2C57ED\n      4C362C02B800CAD48437A08B44B551F0B4DB4B676D74EE765AFB473137F44D0F\n      83B3CFB5895FCAB383D1600261CE77608BF144DFAC54983D87AC92EB14651218\n      BA9C8666121FA4282051D3339E3FB1F0D10B4589987EEAB6DC424DA8A10583AE\n      82437A2CD9D406B7104412A0654926FFD3B5FCE4ACFBAE470AD3345322A915D2\n      C21559F6F2F793A45FF9C4BB270CD53237235CCF7D452E550D8C1BBAFC4B5FBB\n      6AA72FC9BB8AEFE2AC8761331595EEEE03BFECC69D09934E79AE965732A078EA\n      EA3E1B65F499B5C8C8E8C6B8FFF68399E7CE669518F0DD9665523D811A6D1EEE\n      B0F14176A767EC3922976C1DED1CDCAAD1B9CA4213E32C5329F118B11FFA123C\n      2C98D440A86BDF8043E4463686ED3C7138A86A27D7C5F4A2245C636C76EFDC62\n      6547756CB46DB9FFCC3619438C3E2CBA01C69BC7B9D21D68411995D21B7C786F\n      30B73A63147CD81FE4B99C692CECEFED969B0E6D209E6725D14EAFE5C36B8187\n      3C8822565E8C7CAD502AA9E895F2F2AFBEB7F4C2591486100F4155EBF9D5E31E\n      44633BF676FEEE12DD0FE7D6DA311980AE01AEA63302CCCD07E6C1D5C3D513F3\n      6201341A3C5C05EC3C7A130757E3C619973D8FC4496C3400FB6193970D505266\n      5ED80595B6EEA49F0E5E42D3CCA16E2B84C528344AA284A7FB47617F5CC7A5D4\n      48ED210B7E3C2C0645F9F422BB78FE915FFC0BDCF9C5F5C6595F1E4B7B7E64CD\n      2F95E75675FEDD2A086CBF54A08C22E6E4259BDD1F6F7EE1C7F89DB464557212\n      B5965DDCB2828287C3C427B6E3B0C3FD435F5AFE5205578C34C9265B2144FDF6\n      FA8C601C27B2DF1925246D9E9BF1562BA201CF8AE961C42447B0590D9B2A6FF8\n      BDC3C90FF75B0DDF6ED8DD8DB1EF96BCF791A87E64E7BEA01ABBE0B4307D0BAA\n      5D3900ED0A0A62677A65A028687AED684D733D0A0799A68EBB1CDBAEE890DB3F\n      BCBDF2EC9AF11810A7C84A741BBE203AC801106A0BD62447977BC646C1D64FDD\n      39B83CB3E2572A6E0ECCD09C58599980505331C6EDE1A5C9D1E6E1B1679A6C55\n      BB480178EB222588548599CAD05326FF711C5F49820AF67EFE78FDC553DAF641\n      7985BE16400697C88C212CABC24F68C45866EECB9D3FFA76EFA077E1373F192E\n      A68917377059BC31187526F50F9FE4F1917D100EAF75CA4F3C2AD6670C5DC10B\n      6F9B222AF5C463EC257AA69FC645BB1FEC7FF16BB38FACCAC767B8456DB980C5\n      5CAABD84E014998070999F984981FABBA3DEF5FAB29F5B65642E1BAAA53D8CD0\n      F48E48197A34AF1A2320560AA82D445888C065139ED7D6654AC795A513A88FE2\n      5B7793EDB7BD1BA32CC91DD30FC37C1209615869A298B27DE478866D19A64270\n      82B2DC2C014B61598479028F394300B9BAAE03E4BCA92D6F21EC021527B280BF\n      4841798F59E1A56629B46F53F9061F5746C631DCFAFCD1EDA305E3372A6B670F\n      D3B1C73D12C1374A0DEFCD22FF7783BDAFF5C2D395FA3F9B5D7C0E625718C3F7\n      9E6F9622E0F7056F8D049AF06D4772DFF48649E0D95F3542BB36F7CBCB17E2FB\n      B7AF8C37FE0AD3ABFDD1957104707CC6A51F2AF9AB4AEE64E9154008BFE14A3B\n      84186F0CEEEF6A0F712905D30EB1C224B452AB54ABE532637626B23002A14D6B\n      A5B4D3990449BBB970341C053C499948937CB95259B4ABC63878726E76CD314A\n      2A746391B8DEA6897FB4B9539E5BBEB1BDAD1C9A6731B00FCF61C3389A6DCFF3\n      4E00A2A65A295718BDB7BF43172BFB71542BCF0C0E278CFA719635CA259FE228\n      E82F34BD72D8F3582D34AC3726FD3B99F62BFDF8F2FC09AE5C91735A404C74B8\n      C1B47B4716133D06A6A40B4A4126E869A90748BD81E35BF1240F41B65BF0702A\n      1576DE2EB52D326F3A9FF04F9EAF1DFBE2E4C69FDF7DED85B2F919BB494D73DF\n      776FDD7EF0AFE1B84C46004419470BC879FED8729176EAB6FBE9850BE7C78653\n      615F9787FFE78DCB47A3788050C29C4A9EFCEB93EB3F4BCC8A508334C28A0C6D\n      F60A8EE0A87E32F21B562EAB105B0C6562E2EA44C3C329CEC0EBB1CED9129DE3\n      D3E9514E489E2A23A1103BEDEDC9B81B85405D8CACA8536BC12DD799ED80FA00\n      C60F62AED0063CCA0668138663E7C4CA46B1DD89F2CE784F04EC62FBFC2F7F58\n      3D79222B4618C7A648B5F703A1704E6147EA924F9CE73AF34A445AD0BFBD15AF\n      B7BD779D2D40B8C5585033320B5715F807970EB6EFCCFFD4B359C5D3E9FBE900\n      2A3DF51BD5099D81C32A20F268489245BC2BB31D13580D66F15E04C77BF1C4CA\n      C1EDCD1229FB4BED080FE031893B5DC7A0EC64739847B5D4E97D7FA37A6611AF\n      CAACE83BA8A69C35D598CD64DF9503B43BE437C3FE56B7BC6A1B3E05646A1F9B\n      25755B2443E560EADBD824C57406ED94484CEF548DE998F604A1D1984E429443\n      4037C6104194E716B64883AD3BB7BD5EDBDDAFE15FC27EBB8660DD4CA05E0AB6\n      7D96719219148E2A4EB431F55B87956EB3B40684DE19EE84E5EA0252498A0776\n      5DA71B1D51378E4AFD2B43DE150EB67CA97A36260457537158E2A55F7D5FF585\n      331A08A5E21E04EC844CBAC24ACCADD2ADBFFB56CB218DB946C6433D483DD76E\n      42D4AE0C0FB2A36B0767CE9C12F340F81256D8BC63ECBE3A007CA9BFDB97E772\n      B6E2CB9A9753650ADB487513A4B2B5AEC20F47C83E343BD63D857A3003F02719\n      24A23B42610A5AD6827D226AFC0E0FAFF7A8252B4F1D43AB274E7DF66F70F66F\n      CE190BE6C80FDDA5A63B3BAF98C795EEB1A63ADF805506ECD78325467F7465FB\n      877767ACB676E69B334A8B6ECE033E484DB3424D67BFB307B26FA6D1966E4C73\n      F360E3085077E1EC82CCE19D56870787810A661F5D446D8AEBA6B4292E00DC04\n      A68012C2E00EBE2D76BFF9C02CBCF6CAC2A0BF1B4C460BE7E6C92999B23E4801\n      69D8A053085354176A124069101B824941391C14580D3804BAA2DD84E0C5B034\n      859E0C0F08D4D8BDB43D52C9239F7CBC60037D295E800CA482E9442CBC01C043\n      23C9931FEED95D9F1D3F7E67FFCDD963A572D9CB0B9959891D5954DF5B2874E0\n      EFBCBC6F54D8C2879BB933D4731AF47A830EF453806324D8019DBC3CE1E342BC\n      CB6CFDC30BEAC4829EC022329048187B52A51C8E30073D618FECA15D18CE373A\n      6F7FE1E5858F9C6A7CF4B440516666AEE7673F1C2BC9CC272BE9781BDDE9C47B\n      B2F9BEE793790F14AC39AD812D7001420A0477041062310B78F4F59DCD97BE79\n      EC238FC76B361C0547AC4AD9D2CE3A328678A78415B861398827772EFBCDC4A8\n      D1DC9A31E81292FEC361DA9A25016F45C015235396912EAAE1A9A12C5C61A108\n      EF5DA6A2679767866FED8537EE5AC18E15CC6629AC0D20BB811CD7F2FC9C1766\n      6178B9617150D8859E0E8BF3D8B08190519181D4D3ED60D311E2448B1B61333D\n      F199174202F54F858AD394C998159504552664C324AFE3FCFEF5DD47ABC78633\n      EE770FAE3F26DD17CBCB9E0A9919F87A3C96771FE33F1EF63EDF1F372AF5A7F9\n      E493EDC6AA53F60A3ECB642D0E50662069EF53D6AB5514E7561C1F95F0170F1E\n      3C7EFAB18F374E1FBDF3769F06FF5B7AB8C5F116C06698FD546BFE8325D79EF4\n      EFE2FCB26B05C4F352CC583E62A377F6719E24BAC80CA16CDA9D6B11A344CD39\n      BF32E394B5578FD283A1310B336A704598A1E7418F93B0CCCC8A3440C2D70D52\n      E6B9418A3D1637B292512EBFBC75A7A75461E8AA77E259711657ABAEC995AF8C\n      E599F99DEDDD72BD2AB3B4EA96EF75F70754C5F0CF08443A055C596F7A2C5CCF\n      EC0561BD6A3603EE596E8AF0761607B0CF387ABED95A2766991840D480BE59C2\n      30854AB5E5879E98910B245D275268BF3BBC1FA79B1828A3696406D3D34259A3\n      6EB4B8CAC6BD26313E7BFCA94FAFBE5B79F6B776AFDDDFB8F6AE66B33925715E\n      967F63C6BDB1B175651CDC305028C802B6CB44AD9D3F65E5C9BBFAC53FA81DF3\n      EBE537D0F0F76FBFF35AA77B80481915FFD363A77F56B086B64DCF845063CA2E\n      9B0527C67391D5A639D655A3DA278AB8548760AA592EC8423D4647F715C20F82\n      5466332351C66E10EE26F1419618AE33D76ACD30ABA5B0132726CF7556131519\n      33726C23C21C8A1C205AA617571BDC25E6B8EBEC45C3D12439474EFCDAFBE4E9\n      8B69D2A32A627042617F0281D635CF42EB20D8C480A010F8D3DCFCF2DDF09139\n      EBE26943121620389AB12D1C50E3576FDCBDF4FAD2F317ADE32B585AB9F6F44A\n      A47667AE986C1620BD905C4FA153599E6CAB64DBC2B948F0783FF46B2E75D878\n      A75329CF929A17CB3E30DBC18DCD5AAD6AAD94C722AD083F7CBD6BD8D27DC211\n      18B8691997D60BBFAEA35D31C09391B133DCBD7483B9DECCC9539D5B0F2C5B55\n      8EB5240A33945A551F9BB49856DEEA04A95646C5C3764C88C628CED0642C9334\n      978473E22A4BE5A9740B919BF10F52FE96A03F63B59F5C90A5109B96AEDE3738\n      408035B608770B3ACABD18EDA2E0FB9CAD1DD6ECF9F028E7B1A8CE57A4954823\n      C112B426E8924A743B19DDCC9CB8E6A318142150132F48BBB5A2FA4F3F5C7AF6\n      040A223846097C329198A13617A36F786FBFF4F5D5F552A95496A9023D48540A\n      54199BE5EECE6470BB77EAE44931130B27A1436F72598C3782CA12AB3C618905\n      49179BB2EE734368D294E9E3A1A9079CC2A925C3B47D422B42F9D0B38FCBE4B0\n      27FB134FDB728A944EDCFE6A703909F73BB545659F6F87AD638F7EEE25ACFE7C\n      6D02FF7A71DE3FB118C9C8A1F01C999E2BE9E0C82E40399479E5EE0FDF99FDDD\n      5DDBB1805538CB2DB5523AC003DED99DC38E4DCBF73B815D6ECECD9695310165\n      7B786B0B58547D6D265643CFF500148B402C3FBA6A1C339306971684F1B2D0B9\n      BB54A9C8ACB262578CBFB4C377C4CC99F3A0C647DBBBEE09613F692ACC2D0022\n      A78078AB18687788DD1C693B3947CF58B70AC1523D674259BAD30830D5528674\n      9022A919316CD32DF79DEF5D5FF9F879EB3835F304111EF9B1979415C934E5E4\n      3483558FB2F8B55D2F9B67B333770E7F32BF56F121AE66227540BE19BAF113E1\n      E18F137EB958786A4D3E59087468E5105F32452D6BE085F5CC4C45F8CA58BCE1\n      D497EAC68B16F9F8A9DCAA0348E3A26FA9860AEDA29409AB607D8C4C32AE847E\n      60E4FFF6FAFE953BEBFFF2436895A0490A442CA379FFFBC3F9D935790E25BD7B\n      934B77AC62B6FEC20B7193D13436B157309303F302EE6A7A201C90637BF0445F\n      BF31BE7A7DFEA7CE4D96B1A9DB5C4E29D4C8F54A4486E1E4828D9C49B337E95F\n      7FB5098ADF076A3347F002046FA9B5340386A1BD914814D1DC931510D69C7288\n      FD9E002054FCEE9BE1DE0D5638FB6FEC543AA399AC7F8F9E726DDF661E253A0B\n      AD4D77A2D0C874E6128396A1BAE90FC85B2904464DB51FBFEE7391B0F574DDB2\n      69723D4398E84E2325088F49F2FFF76AC06ACB0882771BC47F50FEDB16FABDF8\n      FACFB4D6DE7744BF31B8B7BCBCF0A1613269C74DC36D446E0FDB7FDEEDFDC761\n      B771ECF4FA3C52F7AEBDC76D9C21660301BE18130B894CD584AF9BEA12C17CEB\n      25D2FB4FF1E8577FE1571EDB14BDCB57B78AA3BFF606DFE98D1E04E814AEFD83\n      A5B556D8A16E7117253798D5C516CD8B3ACBC351E7F53EB614AAB81E47B2CB63\n      4DB1B5D510F214764D562EFBCD5A9DEA9B14D812802739AC5C33B77C5C19481A\n      BB16452AEC1FF2921AE06212C56BADB5FB1BBB99763F44382FE8B4B66F44B441\n      A39DA3655DD080FAA671A2519D1C0EC6520D284E0923053173583EA01742E73B\n      84CE08080F0098E05CB705EBD602D04E8558B74ACFB517EB694E0A08747ABA84\n      1E828C70E2945A008686EA9AA21B070F06C3072A87F04F72642A23D67930A0BB\n      464525131B3FD39EFF40EAB72D4F5ACE29D23A5F5EEC323E96FDD6DE6E2DEEA4\n      4DB990D36BB6F363E67D7F3CFAEAC14E54D085BC3467F2A1DB7FEECCDA7F912D\n      BC075EC54EFFF464FB0FBFF3DA8F471DC7E0FFEAF1339F136C2615C334E2B99A\n      5076DD8180871E8B413D6556D904FC2BA83220E8380FFD65B4598A2E6ED04645\n      48DF7A61DDBC31E07C04ACC2724C89671C976631D5F6E5B9A43A3798EBA02F2D\n      C3318D7A1E0359CC882BB9DD48BC56C4B28A9BD4A4130125F960257B9254F227\n      F5A530B01D60B4DA170DA2A9F6E6D7269784C34F18085D929A7F773F78721E3F\n      BA6E6BBB41A4284B5C3D3A976EDCDFF8CEB7DB8F9F2D3F7A1EE9166620A45151\n      C482BB269C2FE6095DD6AE9278A08A7D0B1D9932EF3C18A0CC6C9F5BCDFBDD49\n      77D2585C0FA2BE59358085F7DEB9D75C6819B356AAE00C7AF2ADA273B435FB42\n      453922CF5C3A7B16E05C80D2D1A4A643865D75E7E0E0EE64FEC4853C1A0E063B\n      ADC59A51C65C25D83188E3E8CB4A0AEF47371EE914A18E8D7A97E866942848C6\n      914C0D27B3081C5D3A19D0D837E6EDFB73F1FFBB75786EB4F699E5B83E74AC1A\n      4A69C17401AD9555D5418AEB05B72634AAE21FCB7BE2B5F5F973688427834961\n      E695853AE7A109BB288D0971F36DD9BFA2ECFE9C2D7A41058EB6F22669346F55\n      7EEB43F4C2BC11A5004D1100888CECA8874ADC7899FCE85B5F3EF544AD62968D\n      1CB85C08D40C4D654FE72888EF4D8E2F1D17B3496877E97E257DD504064D4F65\n      95C71D888374A1259A258E15800251B0E561C39805D3C7944CCB8975D0D19D1A\n      D232ADA833480EFB3E572C06ED9E27EDD07B7BA5F7A6803DB578C146C79C9E3F\n      77E197BE87FB7FFD64C9ADD0854ADAB04C6C435C13D63022A995D72CA3A9EDFF\n      5EDF93FF7EA3E7C4C24D4A4D56A9B751828793917498C3EC496FE0376C552D72\n      854D519277A29CA56A2E771AAE29DCF830ED4F06CDC75B78598992F2BC06CD2C\n      6C945032285C7668F93301125FBE155D19D41E5B2FEAFCFE5B5B7534DB7EBA15\n      B7EFE73628B20A56CAB6884EE86B6F5C5D110B4F581954B7CE80FCD3F383941E\n      AD2EAB088D1C00C2C24CCA6921C3DE57EEAC7A67F0332792F60089C4C9296CFA\n      C8169E7491E2A8E816869D0FEDDEABB7671ACBA65FDBD8BCD95A6F79AED0842A\n      174119E23B2ADD609BDFD9F44FCC362F36911DC3198911A8D80C58BC2140ADAD\n      D12DB5F7EDB7891957DF3F6F7EF0ACB1BA024A90A1940052485317550992FA47\n      16ECF3C8854F625CDFDBF9C36FB4D76AD66F9CD4A3379272119798E51FBDF266\n      E5F41C9B2DB19B93FE959BF8C953F4EC716CDB44E8A10438877885801B3365EA\n      86594C4AE334FEE6F73AC1D1B14FBCB7F05D3807D8694863FA0BAE8BD7B42836\n      69BA75CD09B7D9027C6B1C1835622E325EB5940558A810070A85B22C72B69CA2\n      0E02574F8D560188042C4B727B3778E55BE6B57EB1E7935A2D6B805E5A320A65\n      14A0C3854CB2224C65C695F6769FDED00B7D3761A8696A7EEA6724E187EE4B25\n      86B6809AA6EEA713A0880EE72077322715AEC001C33814DE180F6CF31D9155B9\n      BDDF19FE7EBE93BF70EAE923F2D8ADECE46CB5A98E942F9507A1D57EA3A3FED5\n      FEFE3BE5F4D9E5D95F0B2B17C75E801334532CE44319E2541B598B7A612484DD\n      AC955E7AE7FA67CEBDFB85F513DBFDEDFD6E67B23BFC5F3C7E3518D290FF9C39\n      FB81D9D6281908C7DCCBB31B6672E4625BFA062F5F7DD0EB99878FD9E6139576\n      ACE4D5417F3F571AF1B1122C4786CE97567232EFB5AD86366905216169134350\n      2509D17E7ADA930FF664A68D3F0570C19B61D00B020E279950384F7A55D8D46A\n      FA219A15BA4D8021CD3FB5C594EEF17E5800086BA82C583D0D0BF0550F2D14B5\n      25999E71A0908BF480AFF9B2DFF07C7D5100EB2A35C46A054E7021D10439A382\n      EF2593C33849F478617849EDED861E3E21F802783226294DE48C41E767E6F6B3\n      BE17843F5B597E77B5016AB15AB15896968534C7513516BD399B867153181DCB\n      FC9FBB77FFEF482278738175617979C9C673F7777EE5D1A7EAAE65FBC55B8EFA\n      97AFBEDEEF45FFE6CCB98F9813257927F173409F3CCC7C5D7B578F48C90E4A65\n      E250E06382FB24F76033B23A7648A67DA132D3183824700C5624153E1D0D2835\n      FF62DA7D96A6A0114D1AEAB48FB60266B091B42FDB64186621CADD8AD9AECF38\n      AC9E1952950536120F74D65C557DF05878C2F2F852815200165B290A5209BED0\n      82F3348ED058A7EF33E6A0663A11D6CB2FF3C7CEDB8F3E8942587B91D9516187\n      8ECA483FBAF5E56FCEAEAF572F3CA29F7ACE0DD0DE59A65D0C9D194CE7B591A5\n      3CC0FC36161322DD7C92450F36AD47566C60EE373745DD45ABED2C4D2A114E76\n      F6FBE978E6ECF15C70538393B206EAC6F7DE3AF5CC05398752C44BE53564B6B9\n      8353953A5CCA615FF4BB7CE34096A9B5D4B4BEB245DA9E3CC5841C03570EAA1E\n      291397C77008C71097B9E658B959603D0755E70CE5244DFB63CA152D1E5AE44F\n      2DC74CB2BDBF17BCC11FF9D4453E2341FBBB962375AA43A6205438D2735B01D9\n      4D1EA27EFA3725D61E78332C890C314CCA4C18E55261E00CD09F15EC88A69794\n      718752339C505D3AA978909F610BBFF589A2AD67144A05DF5BD03841C538AC8F\n      ED3F2E0E6E5E9AFB683D4EB81DD998E61335F6916F85A5F183F148A0A5C79638\n      7900C83ABAC447E1BE72F2D5674E733FE55EE6AFB6E1AD0AA68D1080C11B8086\n      7024A8C0FABA4B9B262BC6853E2825154CD2CE261A0A5BB608042F3920478BE8\n      6D35EA0C06F3FB4B4FB98C551372EEF15FFD1A1E7DED89D2DCBC51D3D3597562\n      D800E2A3FB0B80DD3362A33B7CFFCFDE74EFA1E1D2A05E6E345A331CCED5D15E\n      A95C2DB9F5DEE1A1D7B0EC1A81B78333ABBBD9CF653633D7362B2529B2834EA7\n      C88BC5D38BC62C0ABC10576CC7AEA1846A971D952AD754C20F5FDD3FFCC13B8B\n      AB6D7F61B9FF76371C4473175A6C4E820A126523E0898320FCEB22325D034B41\n      EBC267267A022FFC02A430D153BF74C21495F328620EAC34E08FDDBD71F0E0CD\n      3B173FF60239DE800FAFED5F726094AE7210A85664A254F6688CF323B37FE5FE\n      ECD9474894DFDFB83B7F6AD6AE1A2AE7394931B3CDC8BDFFF53BE9517AF6C38F\n      A379D08781EE3000B18C6217A83497787CA2F7830DB1D9378F39A5174F92A78F\n      73CFC7FACA9F6B8325612A058C056131569E1B64662534B7FEECE5FCEE8313BF\n      F9A25A0E331632E502EAE09476DFBC5D7D74D10051FBE66E7FBF577BDFC56279\n      3637F415B29EB4A83D890D6E32ED640D9C9312EF60DC7DE9E50C678B1F7B5695\n      7D6438C8AA15CA228603914EEA9E2B3D6F34DCB9E6913EAD61E9DA19AE503C4F\n      540349AA406F0364A481C179520DA928B3ACAC032E8E0A6629E03893F183AF7F\n      71F2838D75FF09AFDC2AFC719A3A3AB80269CEE00B731967921722D76562DA01\n      643A6E776AF4AE6D6DE107AC0281688FA71656785AC7359D4AA80D1E40DE6A20\n      94A0788028264961052897ECA683BF33D89B5D590BBBC1E5CD07EDF5E513E5D9\n      8B9D7406F5F31A8870BB19DAD727E4B7F636DE2AA19924F964A3F1587D6536E6\n      2755BE9224631375A93EB54CB2B0E27D6772301CC7BFF6E4C7D7ADC6DDFDDBD7\n      260F86F9E4FF29BC1FEC6FCF58E49F2C68034AD8184734BFCD8307C0B44A25CC\n      D9D1985FEEF79FA7F8ECB125CB346F4FFA7779322A8CC99803B049C2752D82CE\n      FD22A64747C84AC9AB38AE6F5A7A1EA810A6C940251AD34E000D4A9A1CA88E94\n      E3389E04419A17BAC3573381E9852F990E8894EAE1F53ED246F253CB60DDF624\n      1F66060118E18F28C636D559116A1A2E210D426CD3B219E828C2A6344489426B\n      294280A5C4054F78CEA5389A2481EE5244D9B4BFD89086A33B7A749126336922\n      F358DFC9209619164600F9258F5E6CCF9DB34B7521EABDF173B4D2307058C1D8\n      25DE24210EB1B960518E2AF56FF2F8F7F636DF00F24B3D33E5368A3F71F6D479\n      C76D23F2D34E239D6D7EA177F4EFBEF7EDFFEAD98B9FE6E35A101F09A7C78D4C\n      650353668ACD25D60CCD7D8F3A0CD4AE2E31162E81D5645477CA480CB1CCB011\n      D5EDC148EA3E5C4A028B05948C0A11E562389980689B740E576BCDF3B30B7E21\n      991E005E241CC5B8A02EAE962A26AD48DB944E8E8D0C560F2FD5D907D6C6CB56\n      2559123843B08F8BD4365974D41DEFEE54E61BDE5225CB87C0601CCCFA877DFC\n      9DCBE5F73C458F1D078584B4F767C61DE188981DF4EF7DF9EBED33274B4F9DCF\n      00A7A31C68875EC8BC40DE82B28E113DEF7E2B496EEB8AF308776EDDF3EABEBF\n      34AF78D1BBBF596D3550C5532666B1ECBE75955501ECE6629EF8268353CB1276\n      EFBB3FA9AECC564F377256D8CE0A32F5D03AA06176AE40FDA27127B9BD152649\n      E9D471FBDEE8E8C146ED54C3A8018C1A29424ED3A59684036D10936852AB14D1\n      7DFFBAB21EB656CAF930444961F082E900A1B79D61B1388ABBAF4773CF1F27CB\n      564632C775F0D4250E7668015B278250A13D0C40211A6FB6F70F2EB7E6CA965B\n      4DBA23110EFC993AA76602F4C11466EE16D769F6E38CA838F32A12C35B99E047\n      BDD63FFF645E2634076A08473C67314889202A25E48F0EF8A8537ACA0BE31106\n      5E83A56031C9A91DD6861B41E191EA5A051B0372CFD9FF4990E060F191797BB5\n      14A3A1D134EDF99AB475BDE4F4DC6847A2E9819153E37A1B54408E52669962C2\n      93C32149731C17A0DA78CA81B6E67795785B8154E2EB41EB2C06E114B2472FFC\n      E63770F1E673C66CA3201E2B7046E39C489F97E0E814A58C46AAFB671BF1AB5D\n      CB67E27CB8505A890FB3240BDD86578CE364929855EA2EE936523BF3C73BE334\n      8CACD366D56DA1C81FEF77631635D62B7486A6249275CBAC54619B29383C38E7\n      043B70BCAE05F7BF76CB9E2B37CEF9F98368F466D15C6DDACF16A939B2503D67\n      3937630FB9DA4F16C209510F27CBC24FC64345A8E7D44FDDC5750709C5993901\n      E55F22E63DBCFFDD5D7AA2D6FAF042C12704849CC7382B40D014FA66AF965BC6\n      040D1AF0373F9944A371EBBD8FC75B9DCED5FB0BE797C92CC149D0F7C2663C9F\n      5D930FDEBAD780D779A2A9C818504D1466217362020064B6E9A4DF37A2BB7B25\n      C7244FCF1B1F3B552C374C60EA70C4741697C243057CC86CCE222332B3D4B4EA\n      6F24F7FFE4A5D967E7CA3F73AA50910296641B26B1E47EB1FFF6CED2BB4FEA89\n      B9DFBA2C4D67F6034FE7AD9A1E1F99EB3B026D1F64104E75A004B802A2E2DEDD\n      DB78F99BA599F2CC0B4FA9B28789A768854B060104B8B39E9C08417E1C0407D7\n      FD6641ED4CE9819A356ACC196C4EA512B839F5E195A242F19CA6282F79465382\n      94C47AB442269869F07CF3EDC95B9BB5D17C314149BE6F17257DDAB31CA78591\n      E5C01841376BF9023244E85F68BC83873135B6351EF6F43F34749842C7DFBB1F\n      692A2A8B8C6B04154092B55714077448B09D98F7A9FCE362E72E293E61AD550E\n      92BFCEB7ABEBABFF28F01679BF280BD72B2D44E6B508FDDAD68D37987AFFE28C\n      71D82F79F6C7EBF3CF04128853E8020615CCAEECBAD63BF9786B77E723E72EBE\n      77E571BF2FF677B7BE1D5D7DCD387C7532BB3D3C7C7EA5FDA9F26CF360029CEA\n      C045B754DCD11042A964EFECEDA435EBFF289D1A7AE4ADB4FFF2EEFDD0778344\n      F0145E5C6113690F38F1B0B2039E8E3E8C26315C667A96693388ECA66B9B44FB\n      BEEB1486CE4D8182B728A634E6D9703C8AB22CC9754731C833A98BAED0431CD4\n      79629084CAD44028212003FEC1EF1168269340F0746BE58A6BE96F8F0B614963\n      7A09A2171AF4A3D093965090A6419AA552264511F33CD7E3C3F43BD5EF73EAAB\n      012F0D340D626EAB526DD4AB098FF6BB5DF892BEEEA600B52B1BB63DEFBBF164\n      00A4F8D3B32B1F22757F34A62E49696EDBAC210B1724822213651C99FE2B71FA\n      EF8F36DF2A1278E835AC96E7ABB8DB7FFFFCC2E76A0BA754359959FA179B3F0C\n      45F77FF09B6746E9D0C09B4022A4DAC7D984E2A5CC9951A86CD312C394480551\n      C1457AAC39A3802B10CDE0437B06C15CE5D80915EBF3A46FC8FD3C7B301E74C2\n      099C8153F3F34D85566D67D171EC2C037EF0D0A380E3E9B589CD3073B0E30211\n      654CE524A36B2DEBBD27470D52CD9774999848756EA5E0A23BBEFEF20F839DCE\n      890BE7169F3BAB4AB07EFDDECEDDF807F7563EFC5EDC9E45B905CB96611179A8\n      04D2EDC1FEC1D75FAA5D5CB79E38139BC44DB0BE54E4639AF3C2399679EB2E4F\n      70F44E220E2875F38D83ACD3293F7586242A187686882F2F2EC309820016777A\n      9D9B77974F9D50259343F892FA82CF52F6D11B776197CD3F75BC60B9E1CE1BF6\n      6C6E01CDE12C53040ECF683FDFDC3EBAB9D33C7D92D5D8F0D61D23C86B2757B8\n      CE9D2676CDE54D4BE409705E0CAB4224042C357554D1B112C02F4ED3418062EE\n      5006645414B9EE5931CDE80A972B5EE96C3394BA0B96981A2881CFC3F6960170\n      7038DC09F50C74D818DEB82192B8D66AC223E0C1107627F65C881B8C4A05B167\n      DF0DBE17AB7EA84AF5A94089CC276B95FFFAC5CC122C833321722B61E9D888E2\n      5066A3BFB8B358ADC8FA24E43D823C966360079900CA3DD77B67622D316B09D3\n      891ABE150DF6E3F2BC3DF3C4B2F293188F59D3371B1565326DEBAAEB1EE5C3E9\n      5D1A1385E604102C7546260D93FD3D1A10C41DA27352A1A1FC7C600C6E1CDA3B\n      AEE596D8A3D25C9800F70DEDC72EFCDA4B586DFE546E2AC07E07B66541E084EA\n      3147BAC3CF1EFED5F5C14BFBBE6539276CB79945139EC367749B2407B018093F\n      A5CB06C4001278F10338DCB1B7C88CA6B0843FD9137194344EFAD69218E309AB\n      969D4A7BEA8806AC57A432644EDDDB35FBFFE1FBA9451BEF3B83833CFAD19E54\n      46F3BD4B79AD2F6C20D5262E0A671A52B44DEBC3D40FD110A85B82A765A27FBF\n      100084BA6506096C26BAAFA4147D73373EC8DA3FFFD4A07140F9A4242C6D6369\n      23AC7350B19FB5C67992D8F9ECD80FBF74851CABD327E7B30783C1A5CDF90B27\n      E49C606918D464796B6EFCF54E6088F9F7D545B907C8A03237CFA99E036523A0\n      DC94D3E21B9992895C30DC0F9E921756739BB910F8200251F8A4B6AEDD01E549\n      62A3288522B6A87BF007AFABCDCECA6F3C11AF72232196705227336113DD8FF6\n      6F1CAD5C38A9B2F1BD57AF2E9C3EED3C76065E4DEA849B9EFDA87B65FFDE5355\n      17FAE8E1C75737B65FFB6163B55D7EF29CB46D6CFA9856330042E24CDB49745A\n      4D1CED4D7A77EB4BA6E1895C2BE932554DA22708DA4817B6A48599174478699E\n      095B1A756DD3A4A75AEA59875C8E48BAC7EFF5B29B980D884ABA3406E65BA84C\n      4F91C67A1EB50642351D95230BA9A65EFB3AFD09510C94207CBBE95F4CEF2A8C\n      A931BCA14B99013B737D37034098237D1FE3447A8869C13184DB4E2EDEACE3AF\n      8CB6F361FEC173175FDBDB1867C52FB78F1F1F756A1E2D973D1A8B5B96F53B7B\n      1BDF9CC4EF69345EA8CC1583614DF153AEDDC636E00A9B14B4D17C0505570E1E\n      7C62EED4730B6BFEEC6C7C34EE5DBFFB03B2FF25EFF0E50D74CE903F7F7CE524\n      665622925C4425F3463239304848ECF138E8F6BB1F7C64ED7369EB1A49FE72EF\n      EEA6437A691E85A91654DAE47FEA51A17BE0A795B7629A66D4C1462F3AEC4B53\n      B72C1197B19AEBF9141E0CB1F43F9E4A3CA50A401BA5ED32B34270BD6C02D63E\n      4EB32CD75B53672E0D43275775A65497E7388C362B65CF623603E95468E70ED8\n      53C0C1892BA7CEC5499E055114C659A65F733AC10F1942F30D32B5E0CF1ECE73\n      60067619F519AD3B4ED3731DD850596601C02A1984931B1C1F8411C40A4F22AF\n      6ACE366B8F798D75CBB551361FF1A7020202F1C8CADB36AA71906F46D7621B51\n      F220C7D7EBA5CFEFDEDD0D43D73469C69F6CD75F3C7E6AEFF0EE4FC7F5F71C7B\n      F45BF3F8FF7AED2BFFDDEA23EFEE8D43CC77050B39DBC749ECA8666197455EB3\n      6813A42DB00147A6962EFAB389E9992E71EDD8A65D233BE2E17627EE1D7247E1\n      965FAAFA2E9002CC9069D38A6BDB6A5AFBA1BD9CF5E533D3BEC326D216DED8B0\n      650171D9F409351D8F0666C0CEB49D67CEA5AE69237DCBAABDA5B42F289647D1\n      D52F7C67EBF5BB079DDEC90F5E78FE17DEE3ACDA93DB6F1CBD7D79ED43EF5773\n      0B28F78828C1D19BB0AC04AF7A6BB3F3CAF76ACF3D82CE2C73845D69EB31BC79\n      97E699B4D763E7A4278678F886B28AB0270EDFBCBA7EE1743A53B2877C7F73C3\n      5E9D75EB151A719ACAED77DE218EB5707C199E18C4AE04E540F22D10601B83C1\n      EE64E95DEBFADAC09F33BCD91C545DC1755D2041C5708B4CFAF1E55DA3D4C81E\n      B3BD38ED7CF7AE5F9B2D9D6C01520BA094ED12B3094912446902145B09081680\n      78DA5A0C3E2D20EA302882D8D475B5C00664CEB9695A7C93C5665A7B62252531\n      7590C1E8F496445BFC68E91485DAD34003995DECA4A3DBBBF5BA4F2DE0B1796C\n      70C62C8B5B08F3C44EADC80B5F2BD4DD443017361DE848FBB919FFD73F9058CA\n      CA816AE5B13934C5988D8BD14ED07BFDCEF153A7D1E87E68744CB36CC54CD071\n      4C8A7267A17B69E89E63F671226FA0834BC3DCE22B178F91162ADC90DB9CF88E\n      5DAD236A4148543A53AEDBFFA79EE354E9CA919C681A8FE2FD1D36195AB85684\n      34D725B09165CCED5DED87FB87AD7086799E7F1144ECBE89FCC87E54A746E3BD\n      4FB05CE68029768945962E9DAD65F0A68ABFEB057FB9635AD43C498D4AE1C445\n      67DCF5CA552BAB649DCC6AE07C3E483D4E9352B283D361DE5EAD935ACE947974\n      7030C9B2B9E373FE3CCBBD20F7B0E5CF13512BD24CBA69C140B43A645C1A7EE5\n      2ED93C24E7CBC6ECAC79858EDE7E507A811A8F51C54D4CEDC80D4B0AD384209B\n      48430906B101C08000D3C3FABF290AEA4E0A5DF9A5C736828271B127DAC61BC9\n      CE5BB71BEF5AB22FCE86466081CA451C1113428F6D3108E14EC0222149A56ADD\n      2B76BFFAE6D2F32BE9BCC2BBBCFB6667E6E27ADE8A6C31C2760BBDC68757127A\n      A2547E9791E20320AF794874983721BA48A7F07AD70E4BDB6ED212F8A94AF5D9\n      3339A8666AA25CCF01138653180ED15DE309968099C0301C71F9E0F6E7BFBEFA\n      A967EC67FDAEDCAFE32A9566C2728B32B51777EFF4E64EACE6FD83FD07FB2BCF\n      5C54332D5D6CA9C7164E071A217D9F2301CA75613884D2A0F8C9ADF0C1666DB5\n      ED9C3F29A9A98887CD5A214CA23303D34C2468988DEB417C503D5E91151DC11D\n      E4535E52CA43B61B6B52C1EC828AADA3EEFE8DD9D38FABCA9C1EAB2BF9D4E991\n      291AF2E85EB6DDC30F1C7668F0FE21C9F460389C7194E62ACDE163499072C574\n      C2C954D4E83C9FD2B57F6A0A0E64EA99A5EF09A5D0CEB8DA6B572A6DE8A86FD0\n      0C5E4CA7B140AC96668CE1F9F50D7C40D0A05023C7FC9B3BB7F339F7F4FCF15B\n      6F5C7B6A76E6E3A6B966D09AEB82A8BF631BBF373AF8D3FB0347A10F18FE878F\n      AD65664C54F4D941EDAEAD8CC5F9EB3B9B37F6B72EAE9D7BCFD2A993ADD91CC7\n      97DF7E6324D597BADB5F9E0C07D8F8CFEBF31F352D3B8F12830ACA0289EEA7F1\n      B64D8372B5BBBDFD84657D646676A8C8A571FF95717F234CA6330574FE45BF63\n      7D4B671453FE0921574F1E2E7243F346A4AFFEF0DFF7332BEDFE87B40F10A225\n      CB3509282AD3F78152DA4277EE018CEA6134787A9FAFA666C0F05BA1516C5A2C\n      A9ADAE80E951A6FD23B40BA6EE8F9E527B9E25132EBB02026FC6739EEBAF9FD6\n      B6AA87A6D5FAF2609ABBD5A68B52027E2BF8AE8D8A5F766C871AA6EE314B2D85\n      7C3625F10A39A6752F11F77B87FD8457AB4EDDF5ABB1805593458CEDE25D738B\n      CF0A6B214356C904C2EBE6242F8C81EBDC0E839D281D942A5FDADDBE9245D274\n      1CCED7A9B900DFD4E7BF70FAC2934E9DCCCDFDE92BAFD851F44B6757EC83BD61\n      616F29B78B52203E36B29A326D315CA7D4833762A3844961528398D47127046F\n      4CFAB7C7DDD028CC5263C69F5DFBFF787A1320BBCEEB4CEC5FEE7EEF5BFBBDDE\n      D1DD001AFB420004375114B553B26CC992C78EC7E3B1C7BB3C49CDC495A4928C\n      CB93642AA9D4A46AC6992A4FA6E28CCB138F13C7E3C81A499629D1A228719140\n      82200162071A4BA3F7D7FDF6BBFFCBCD3917745024AA49A05FDFE5FCE77CDF59\n      BEE305FBB95B497353A6DC61591E17541B8E9D6915032176E198500F1E1FC3E8\n      67BABC7015AE3F332B0E09B8677483AEF7E47470E6096205B191149984604B85\n      CA7A43F5A83FBCB476F787B7DF7DE7DA808AB953D37FE7175F627AB4D97FFDE4\n      97BE24E7F6C729AF0817AC39E189A3327EF9F6DABB17DB9F7BBA589A02966618\n      35554014DB62280E7F54F245AA3659720D62F2830BF76A35BB79729E70335EDD\n      1CF5BA93A70EEFF1BC4A2D672BEEDCBAD13C7388D8864101ABF7651537874070\n      A11DB2F1EEDAE2D96535E390EA14B126105EA98CE6F07255D87FE08B1E7D10F7\n      3622F2B18A0B68ECF2A87BB73B7DE680D124513CB20034B501CFA410FBB034C8\n      E128E37E2229CB96524DB9D26977980F4716CA5B983A4DE110927E7D90F69AA7\n      F6EBAAC2ED7300636D5FA1F02AF08F5C8D47E06F7179114BECB8D9BBB2658703\n      BFE9252ECBB13E6818C249011A7BA81136BA418C7754069F414CA0B1F5CFECB7\n      7EF9D9C426107398060FBAC38AAE3F30F6DEDCE96EAF1E7AE234DDB8139A7B56\n      61DB297C771CD9C27F38397E37AA9E75C46C2A7E40460F23B6504C9F5F26663F\n      7580CC4A2BF05CBF563088D81C73A210E80D51F2219C45C55522A95083B4E88D\n      1DF03CC86DED5C65A6ED8975F9F0DA4ECDB79C3DD7A8FAC1595BF00DAE9CB175\n      F2C97FF80A1D6C7E29480196011F50392DC0D7988592EF0D37FFDD4A23745C40\n      CE07AD7CA4C4CE206856E1A10D3B63D777ED69AADD94C676B2AEC330ADEDAB56\n      5A2E8DF5706D343407134F34BD192F8EC7BC6EF15A4074CD9415F8FCD8DE834B\n      F5D2A6BE10DF7AE3E2C2936D7F3E101B4EFF8D6163CEE21F4BC6F581A99A06A9\n      6A278388C371CDBC09485FDA38E90A8EC764C8118BC7AEC264D8AAC170DDD4D8\n      4A2DEEF8ABF5F03B8F926AD6FECA62E48A40FBB9803834760CC40860161901AC\n      0670C8A072E2D1EB1B469CCE3E1D287BC85769F7AE6C9E9E4FAB7B361BD1D5A9\n      EE8FD74DA7593D535753834247C028C13224CD35A07BE5F15D6B7469332D4CFB\n      FC44F53307D9F4441172C059848B52E9D507374808A0B8143C0ABC047BD349FF\n      F8875DD29FFF8D8F2413828ACC421561784DB6439C74A737B8B737B3EFC068F5\n      7ECC8AE927CFAA8A0B4E0D683996FB50C0971765773966EF0CC2B2BDF89DEB66\n      1CB1C9AA75644962F8A952BB564800C3B80BC220D49022BEF6664CD3EAA156EC\n      E486C93D6930E110E6C5DC4ACD4A35F1B2371EDEFF8F6F84C7C7CFFDFC2F9289\n      3951181CFBC891BC502392C9837CBB47EE9BC6B64947233D4E1538DE342F12FC\n      47A539C1E6B2BF4D78E2F02A766D89B2E30FC066B905B39C70C56E036C008140\n      889D92587C906E22019F461AF5A7AD94E782AD1B6ACBB5AEAF6FB4A6E63B32FF\n      F69DBBC14C332FE8A2107F7F7AEE705E3438731CB6CEE41FEDAEFDABED30AA98\n      0BCA5E1AA5678F2ECE99EC17EED06BCB8D97B3EDCEE6D6179ACB2FEC3F553FB4\n      D8D95D373A1B8F861BDF25E177237D63737CCAA1BF3C7BF0449A4A390EC184BD\n      66278A6EE7F166E08C29AF67F2D393D3537BBDAF4F19AF5D5FD9A62EE16E1846\n      AEE38CB3A181AB6321C65918940A35ED55A86BF507830CD85D99802C1815A854\n      87E96094CCC45C0D668C9DB23B05B08CEF3BAEE594BA99E4F1CA980F55F249D9\n      FFC23E9C0046A450605E4AE1B8568E829C054972FC259085624F00B6A0969557\n      5D72D4C77D3465870D792C5A5D76DCE00F5D6CB56627EA0CABB9D8ED6F02632D\n      55372C1C7335E14A003FF4F3ECED6E673317F3844C631286ECABD54F3995B373\n      331422CA70704C3ABE39CC151C3A1F6EB8A7F5B652B7A3F8A62A7E1C8E1FE4CA\n      C6C1F3F1A15AED670E1E51245A20E285F6916BFDFC9FBFF3DD5F7FEED86786A1\n      1898EFFBCD2D92D0708F98DE3122F791A2C64DCFA285CD538B640EEF0143D3A2\n      5768C08F15EE2DB7676B752FD3A923B42394555637116D31860DDDB869DA5026\n      0FC1CFA378AE03566F72D7B4B9F4B3C4CD0DABE6A906F559B7D5F79F99090E1E\n      D3B43674C686623EC0EA61DEBB7A87EE60F7021DF33B371EBEFBFEB5475B1BF5\n      89EAB1E3CB27BF509BF9FC67E2806694368C00D8414C121F40CFDBD71EDCBA31\n      FB9517C454DD1D2BE2B5B81A2BB10D67D9B696A9AEE7F986497792EBABA3F5D1\n      F4A79E5456C46263776DB53DD128A626129D18E3545EBD6F780E3F3C0DA8D001\n      E4A9F3A49445A486B0FBD6EAF757168F2EC9E59AAEB799DD46695E78E719961D\n      A278BD18DEAF8CD8C6071BE6211ECC35DDB83ABEB4414C121C6E2BAC862ADAB4\n      4480A4D7C6B6BFA25C7185757C045EB83598B0340FF77A45047808FC0B405F41\n      C35A6FD0B317DBEE0CC499046CD1726A943865A55F143AD34939D74EBB059DCA\n      1F44D9E59589A9463461E27AFB0CDCB2372299E148C00BF190CB9785EC139BB9\n      4316B6FE93D3F6CF9C063A63E4BE49F588AD12B55B1D787B7FB136B4B6F61F5B\n      16DBABDA1D992933B20AC4B92420C635D3BCCB9DF3EDED7CB5780353F1CE59DB\n      DF57577C149B11C079370838801DC32ECA40A80D943C817F0B6A714037512AFB\n      3119094B021F06AF1F99AE60C4A57D7FE33AF03FDE98981ADEEDD5F7B5F87EAD\n      8D5D925B43EBD8D3FFE9F768BAF977796E1AB8437B2CAA02B8057F3BEEFED90D\n      3E067CC3FC059E47F9684BD69A152E8CEE5ED76E5BD60C76CF57F3BA5E63FDDD\n      9E7FD0B6670C9D12B94A0749AF75BA6E2EE9488DB95DB76A4D6D198F8B213AA0\n      09096B999FBF9F0FBFF3C03E68AAD3DCDF33C57B7A2CC2E6A7A6596BAC582C39\n      E785EF683727232380376BE39E3B0B17781AE4C34D2D70F005DCB86B295CE58B\n      B5296DEBEA6E3DFEC1CE78B757FFCCA23A01511D352315300F1B3B4C70A1844A\n      B919601D4170B5625C7D75E5C8B3CBC6C18141737A938DD68BDAC909ED0FB4CE\n      F8CBD6FAEE66FD8959EFB095B121DCB8211DCAF2980EE1F4F972667079606C66\n      5B4BC5D2A74F592767531CF70F4804C15023AAD72E020B120B432586E3E55CFE\n      D5EDDBDFB8F8C4AFBFA89E0B32955A096A3625C05675C32AEAE9DA5AF7E1FAFC\n      ECF2CE9D156B69BAF1C471696290A7D88C809F8883B2583002A286939072B01A\n      5FBCE931A227036F7911FC4361569855D70202A121B135102C2FCF2FBF0A74DC\n      5F9EC2A9185C388832CBCCACC1712DEEC7EBAFDEBDF7FDABE3FBBDB9AFCE9CFB\n      7BBFA42C8075B683CD141217AC807B118FE820CE6F4ABA0E103902C721211026\n      2970C122CD75A6280442ACC3976B30CBAD6EF03B163C1EB7C660D55031642614\n      0029CE5696E303BC408AE324322B542A891B5299B30E01AE0387C9F85EBE7B99\n      264F4E1E2EB6C2FF67E74E32E1FCB45DFBB8573B6A581E512EEE2260EF16E4F7\n      6EDF7D8BF303FB0F9C4C726F75FDFCDCC2E244EDEAF6EAC3DEE085E3273ED138\n      74B0313B92A3EE6063F5E1ED4EDDF9D3EED67736438307FFAC3571B8DEA88A4C\n      EA482B69683362E60D956C1BC44CE4A9A039639B7132FAA7E387B915EC446434\n      CAC17C98A5AB137E16460978312C42D870D18BB5C6F4DCD4A0D74BE2641CC3F9\n      13A2ACC961F1EFF1523D1437E01814952CDB884AB258262B29F9F08BC7BF1E57\n      F13E9C822AA7A1B1A88749374CFB3D2E80941F07271F2011A0FBB494E184B856\n      A8928F3B0074B0CD8187719864B8251631393C5ECE0E4C4F01995629EE55C7F3\n      4350A2C5668625B156E1E0560D09F8E44E3EFAF16E7771AAD5766A3953538EB3\n      BF1B4D0901CFE078BBF551D6A8E47B3D83A7B607FC248AB22D60E715F39665FF\n      E0C1E6BD2863AE4BF264A6EA3EA7ACB0B7FD2BCB075E9A3E76ABDEFA8D1F7EED\n      CC8CF9DFF84D77435FABB4EF90B037DC1EB9F60BA673481593D4AC622DB4885D\n      9206D688C92E4E0A3A138D5603702DB6E8A6D8A66CF08C0129E2052FCB224279\n      8086F3B225ED31FEB2CC1C9E0F33C0FFC251CCBD240BA461D67C3AA93D325A88\n      2A1F99B5DA0B85A80FFCD487F7372C929BAB64A347FB215C7692E4AE15EC6E8F\n      DE7EF3F2BD950D70AE875E3AF8A9DFF899DA999670224B0B01BCCF62DE38D56F\n      5DD9DB7E34F5A5E79366C51D662C9821B2AF652F25966D4E734086D91E8F471B\n      3FB834BD7F819E9CCC5C9ADFE8E6229C3CBA5F14C22C68BCB2DEDFDA9C3B7F5A\n      39A54AF63862811B8D872661B222BCB1DB79E5D1E4FCA43CDE90F596EDCFEB1C\n      252489C05139A93A71F74690ABC18DBD6CB43773EE08B12CB99376AEAFB6F6CF\n      D9B3819603EAD3A2E1246847063C394CB6C3D93779B97AA12052A08ADC384EBB\n      031546F0F671666568EEF6FBB4556F1C680A03F54951EE1BFC1C0A59E6D428F4\n      58CA84D8C568C01D37F58B77D7582ED5AC53A8C44D14719C117868425C88998E\n      8ABF4EC47A1E9060C718CFFC83A79D2F1C4FC05671BC448FF47DAAF72ABB95FE\n      BF7F90CC0D2766FD78B8E738C28E091395D81079C0F22B51A513B8670EADAE5C\n      2EAE8BFA6CE09DF7B85948F0682CE3BE61551C6A59B889881A8F8F4FD9DD6360\n      D54D0DB2DE880D95A32070B8B9694B6B2CF3DD8A9EEE5CCFD3FE78E1E854167A\n      83BB6BED63FB4473C48DA121DC917BE2C9DFFE2ED50F7F5D9090F11C6BD3E007\n      57CDEEFFB9421F8C8D83313DACB97092FBCAF11A8512516F14B41C3D99092777\n      F3BA7868C851EE2D72D5CCB0483234C2ADCC3F4C7106DA4A53AACCFA8C61D750\n      235A0FA52301BB59A1656F583B7F75D593B4FAD464DAE4F4FD30BCD9093E3E1D\n      1D85735B006D048C04C7DE127E617281BB560D65716562FEC944BF8B8E171010\n      7CBE760C54AE92E0F799916AF28E7AF0F6D5B94FED739E9B4B21D06BF0C95261\n      37B347212CEA11849D0AAF65466A2A3F7A75B7776FBCF8C5C3DD898755EA1717\n      C9687DD83ADF20563ADC48EDFF108E1769E3E3D3792584C357C41678436D8E00\n      6978C5845AB187377B8167872FB5DA270F14AE2F01369B96CAC73E782D6D2840\n      DE549581D0CCBCE9CAFB6BB7FFFC1577B2B5F4A533C52C46284B01E018655431\n      51B3E954FFFACDA8D7996F2D6CDC79D878EE947370010CD8065E57AE1E2E0744\n      4B465866470597A4F720BDB26280E39CAB790BF39AD8D4AE174650E42672D252\n      4CD5082371E53B74AA66CC3494A973A07A0E18D104DFE5E13B3B5BDF787FF3FA\n      465F28A3553FFB5F3E31F7DC5309E3DAAA8153B571F0083E3A64C50EEB0DF41D\n      291F167A10B39E0446A8CA284853015F636759493DB026A970ED25C18E56386F\n      8FAF1B9B48F157D9444ACB561A144394400321D6EA04DC6F4AEAA119667A0B75\n      1570A5C8EB4EF4F57463DA699F08F6BDB2797F6DDCFBB57D07CE88E230A3AE8F\n      1D142C49BBCAFE83B5CE1FC603C7F53FE1554E566A11D7EFC8B573C2F8CABE23\n      67178F9AA6636432BC756B908E2EDAEACF3A1B1F8C1391EA530B4BFF056519C1\n      5E5678F45C0B1BC88B640FB51814629AF0E3C1C4D8A6EF843BDF267A7D1C7742\n      090E68C2F59BF5209870D61EAD8F46B1407E0E3729E6EBCD16EE2426CD5A3D8D\n      D3288EFA511C67D9A8284439C984F18D633E1F7BF44B9E8C698C32C5898B154A\n      DA56B6BCA0C426A6461FEF4E2B0523F1FB8BC7F21865D351C13ED48E2AA9372F\n      A7E6791940392E6FB01CDBC10E1091C719AABA22012DF708B66AD5F9769B2144\n      4289AB722F2AB10AE24A12480EBFE31A654F83271A9BC6F77B9BEBA46804A8C0\n      EE1AA459E827AAD513B677AEB04E499FF35E5FEB91698D235CDEB5CBD5DFC47B\n      3F90E92A31A3CCC86260EF2AA7D94962BC7478F927DCCAF24087874FFCCF8F3E\n      E86D7CF04FE616E676E923A371CB48AF8F376F1BC5CF4DCE1D49E46C6136503C\n      4945A660012E93C1222B2EF52A30F36103F2B7E17613A690EC18A5E81AAACEB0\n      C7F963041A40040A06CF37B6A5412D9BD910E421108A2A3C3BAF62CD8C78AC4F\n      B2FA47F651AF55A8E6189C80E46CBD3BBE7CCF8B950E63ECF9A422C9635280CF\n      70AFBDFBF09D1F7FB0CDC8E2B1D6A77EF333273F77141E96E232467DE16CF09D\n      1FA3B2C167CE8415D34FB861B554BE5DAA4440E045E9433793C3F7568BFEB0FE\n      C272EE2B25CDF1EDED4ADDE28BAD44E6B56E3EBA72CB393A5F2C34782E0CA915\n      3A2965A32E9B0EAB9937F2E2EF775019E1A959519DB4AC79809B0C700F805DC6\n      A5DECBC7778AA8EB8DE8F0E283C6D1037ADA02D435BEB1D75FED1C78E6A80C52\n      0A9EDC7313DFCE4D16C458960653407D4A1CF001EF54AEED0303EC0DA34E97E6\n      D2B32D0E6730078370DC99005C9C6101DC700DEE0162029649A9E4C0C6C79A27\n      A3A14B6CDE70EFA67B371FFA6DC7B6207A0B0124082C50386691A7D53DF6A3E9\n      FEA5DD20AF749B6AEAD79EB15FD81F09F0489E49D330BFEFD1AC5851C9FFBB61\n      3D69447C60A80C8CD3958C0BB044B874AB737DA3295B95C6E2FD2B57C1DFCD9C\n      6BEA69AC71228846595A6DD75CE26023047B8C8A504E0EA2A0A9E228CA7769AE\n      7CE133B826CA625CCD9EFAF0DD6BE6CEEDB031E75716BCF42E1BEE75DAC766E2\n      6068D1B129FD5170E2C9AF7E978A9BBF441A61C4FB01ABF31B34FADAC3E1D5AE\n      BF64BBC732C16220FA9E98B66C6B6F73D3A9B1CA9C238D84D360BC268683C45B\n      70CC69206C2CDF537B7BC3D6F25CEDC0B86C08F049C3271597011D2334617D59\n      5576E6DBDDF9DEB7AFECDE5F39F2B199A25AA783CACEFBB7FD69EE3FD31AFAC2\n      D6D4D5407AC08F4A3CDF05AE10D75681B2A248070BE3B18010EE22E2C2661235\n      5A01F5C02B76D377FB3BAF5D9A3C3DE37E7E213685957303F0014DB9B489080A\n      06D025CF1C38036E2194D9E5ABDFBC363FBB583C67F7273A353193BF9EAA41B7\n      76DE22891E5C50C9C5ADD627E78C336EA40634B7EDA2CA7496921DE6D94E3813\n      FFA0170DC3EA9996F9734718C4641A281B02A6222CF114F64741A0CE2D916B14\n      073244BBFF477FD5D9BE7BF0CBCF160767EC89A64C064611123008BCA780E9FA\n      D63BEF93643C5399EA6CF69A9F3A5F4C4F884402DB65B8E9A49C9BC465DD6651\n      DAB08048B7772FBFF69001065B6A3B5353053C23B3024C9549135C205816783D\n      3A1CE56B3FB05B2DED5A89C3A8E3FBBC955EEDAD7FE35AFFD27677AD97F262F2\n      C4BE275E7CC6F97483D62DE1B99A550DE00C801A291C8004E7B07B83E26E46EE\n      29B51BB3013039A162E08265B38C9045D9298A1CA6449BB4FC5D96D09395A314\n      AC8C83D8B883C315E56C5CD92B52082994B2626A46452659889F47BABE759BA7\n      9D420D52F1FAFABA7D68A1625657AF5F7F7E71EE8B7E63FFDEC0F6189DF6AD0C\n      28A9F9C71BE37F39EE8F8938EF9B7E60F5B4FC98197C7661F9B99905CF31B6F7\n      36E4701875FB37E2E4F2E4E49F3C5819C6D1479DE08B734BC78A512E2CAD4C69\n      28CD73F03232633B7102FE739FE3D42DF7523EFA9BBC7B2562F099A330AD59FE\n      A16A73D2730B975C5B5BEBC409E03989B54262335AD77A6EAA6983E7D0D4B16C\n      88673BFD9EA07047D938CDA21C3962B956EF43B2F7789CB2EC63C1E7F3A13064\n      490E5919D58AC76BF83EDCA95D16FFCA19F302F319BA78CC228B9224A2203FF3\n      9DC0344C21B071069E6B2253F00EC00BE1BF185E9E9C9B9A69FA2E38281CB805\n      D80ED191141E6115493D5160209474ECE96A6E4020BCEEA877D6364F1D5886BF\n      C06C0A7EC94AC753C3F053ACFE597B26F28682F071568C000599F66A1EBD9FC5\n      576C76258CA288181926CF2257BC68360F3F79B87BF9E2E7F3DA4B1FFDFCAB2A\n      FA93BFF9CB5F9D6D3FEB4D3D1CE4DB15E7F5EEDA4597FEF6C4CCE98CD484AA72\n      E2B940F832DB312D6C41D2580AC19928EC43348C5AC1ABD80A67E2EAC6925BE3\n      629D1C9B4B0D5A98B6C2B54CF0AC067E6813C72096E9D0CCCBA40F1FDB28B43D\n      02D47EBE1E3C39538A7F551262F8892A6E3D4AEE6DB294D254B32C2732CEC0B2\n      71B2CE4FBB746F6DF8D6ADFB771FDEF3F7FBE7BFFCCC177FE573648EE519309C\n      F0FE5FBF39333BEF7DF2A988666E02C4A196923D8867866C86561ED2CDE928E8\n      7DED03E7E894F94C138E42726F34CED2F6FC44EA190E10F9776ED334F33E767A\n      64A46E0E5688E51FAA9585C984226A64EE38C8BEB7CDFC823F33A3AA33165B00\n      CC04F115ED0037B0F6D3E16D956F05D2CA7FDC9169E63F3D2BBDC28CDCD50BB7\n      B9A9E6CFCE837F30EA7515986191F9191A1DA6BA51749A60BF0DE0275626D6A3\n      34EB0F4594C011F0B10DD9A4BEAB3CF01EA96D9B06B8358020161338950C6E05\n      5876418659EC668A5AC1A0B2F7DE8A23D26AAB2A49849D3CC4B3449DF34C541E\n      1A0F8EF4BFBF4176F868C999FD472F5A2726A304D83920AB1195DB2C17E30B5B\n      F95BA3C6F395B0D83684D2A9B638EED62189055468F5E6CA543053D973EFDD7E\n      543D5EA99F71B59361B4D3D817A5B936AB105599427F8B4384541A4430922819\n      8E12961AB6E9C0BB4F3830C8C41A03C8AC4453DB9776C0F21BA75A190B8BABEE\n      30E9B44F4FC7D6D0D6C0428371F5D8935F7D8526777E8A069298DA582DC65FDF\n      C9DEEE3616AAE410FCC8385C1F3AB4E239EDDD47237F96FBD39E48FA16A9249B\n      D9284BED258B4F1632C9ADC818EE8DED496FE2D874C61E10655BC1826A022D4D\n      6CAC665819036EA483F1147D33EBBC7F3D7882D3456D87137B6FEEEA1A997C61\n      42BA391505B30C6A822D9A121381E0E7713935F601194C976920A35C7082FAEE\n      2E05D3709C0A194A6E56E96A7FE7FFBA216686733F7F2EF64B45CEA2DCCF5208\n      9C2590E5A2969A1599991BD32072F7DE59CD1EF5E75E3C23DABBDD4AD8C8978A\n      37803174FC733C5E19F1D7BCA1BF37FDDC62D1CE00D149E594F2E643660230F5\n      B39B2CBB1615755EFBF993E4988B8251465D17A6048C62139E6570B7E0EDB280\n      0F64381DD5B3D7B6B67EF0837D4F4FB2530D79E088F65A34DE368B3E158A7017\n      AC8D68E7C10F2F0585AE1835388BF54F9DCF3C8BA528F347CD12C7D3B2091005\n      E6C00102D691BCB322AF3FA40EE78766D8C404010F64D5C11573696199CAD426\n      84ACBDBD7EFA7EAB352724B7BD1ACDADBD3756565FBED97B7FB7908EAA385367\n      160E9E5DA84F5746F3D46DDB46BD9A0BB07D0F6702B999C111A05D6BD8E77752\n      7227D3DBA11E1922C5D220462D21758ECD9F10E2CA9C5E598128490F3CF1B2E2\n      553C1E9FA7BAF8F0574910CBF12485F96AA1FD314E4DECA2320755823DA89B17\n      AC71B2171EB6A6BFDF5D7B450CF655A6E3CEEEC1A9DAAF4C4C9FEA87B8CC62C2\n      0B28981CFD5A44FFC7CED63A1B1E6F3BB5501C0EE67EBF7EBC3EBF205CD24B36\n      FBF76F44E978777EF64F1F6C5CD80EF74472A635F5F946FD9CA223DEAD8AAAAD\n      DC1CA00DCF8996C09DFA1100686BDA770771F26ADC7DC7D3B7C6AC1F8F805F1F\n      AFB78EB24A93182322AE87BBD7C328B51ED33DACCE1D9AAA3A862993B4EE06BE\n      05764204EE07B32052A64A03394B532068F928C6BD1CEA31C72B63992A891FF6\n      3F944FC62873A365E7292FF789B272845E60FC2B89A52E2326C05F564ED3576C\n      B3D6A8E36A6EAD33A1934C0C8663C3B1C15AF1F3C0EB09787D64CA31E626DA01\n      787709C8B408004A4208834068A053C6065059BE35203C8615DACEB0517DE3FA\n      758AAB99B94B0BCFE36EC39CAFF92FF2DAB3A9ABE4907AFE6E7F0486DEAB7A97\n      557C274DAE77F63639DF18C51E3100D18F83E2E058140EAFBAEC978E9EFE787B\n      59DA95DFFF0F7F72A0E97D696939DAE9DD2EC8CBE3EE8522FBDD6AFB050A0798\n      D42CE6A0BE1A5C03874027C08AE141828F93D25705E55EEAF8E58E05ACD0320D\n      B6A238A79212810ADD1C1C369C3DF8FB0357D8850DC89839140CBC70981B3423\n      30D016AB3E336B1E6EA0CC9FE9A49ABBFD347DEF96EC440A18726A5BA1362388\n      8F58DB0993DC94969D591FAC5D7BF0A077637B3408D847BE74EEA77EF169FFB0\n      95AFDD5A7FFFD681675E94FBDA82482711D4B0637B6464CCCAEA036BAC8261E3\n      7A147F6F3DF8F491FE715AEBA9E1C57576B86DB57D076E686BB073E5DAE4A9C3\n      E64C35A1B981DA2FEAF1B01F93788E926A6627B5FC7B9B8527CCA7265565D122\n      07B0A0CC06BA94F903D2988F1F64C9FD006CE63ED9BEF570FAF8543EE5C02B77\n      847FF3F5D767665A9543B3A2EE02A363D833FCD87F500C198C3213075380C269\n      6CAB2B070D4761341A9B09005362553C5671A84DB596A5EE9C415C47309CC371\n      801BC243866053843150703651AC74D9834DA7EA01E6C8590260C3104D9C0B76\n      EED3E4E8E8DBDBF2AE144FCF4C7EF5237C165F06D899D61D3BEF91906DBE7283\n      AD15B5272108762BCCC96306F407F8A2193A6254DF5EDD6807D5F466A424F19F\n      AFCAB9984A81A0A8B0F0187062FA40500B70B6386F8B02B15C258038046E5A80\n      78CDC148000F01CC1B9956C8F3DAE896956CC7ED43369F67A324352EDA91D99F\n      38D91EB1A187D3A71808CFFFD677A9DAF8743C24816C76FEEA83F0DDBD76ADE5\n      ED678015BBF7476D7F4A98D16EB733E11EA6FB212A00D33212D4374C1B87AB51\n      6DE85A8EDA51E3CEB0B25009F6573165C3864EA55D54A7849DA664E8C0E11536\n      E56E911AF483E1EAB7AEEE7FE260F64421E558DDCDF61EF6E79F3D2417E07E12\n      4F628F93F0B432380358871B4339768432A65056025E230ED063EEC82C94EB8C\n      15847CC3274DB293DEFFD68FAC3D63DF570F1733B21FE98613103D26D4C49176\n      9C7F4F95ED12DF8B55EAA48EB3AEEFFDF0D2BE9307AC63CD9C6D8D1D524FE6C5\n      DB430EB0EB88F9E8FB7766DF9DD63F53F8537E2122CADC1C25ED04E309AE10ED\n      051BAFAF9B855F7D76C67E6951C095D87ECE5037C1C46E40C570BF1991E01A2B\n      B6A056E3810CFFE5CB6A5E563EB19F55893A7C26D486A78766D2018224E17C03\n      E895E6FD1FBCD7E2B6C52AB4D1B2CE2D8744DB8299D81C5C6680703D29C7A111\n      1C59E292E66CE30EBDB789027447E678A5C28807562C0B0742240000E0C05C64\n      E1A3D54D7D6BFFC1D3B6ACA90DBDF6E76FDC7BEB6618AA514616970E1D3DB2DC\n      5A6AA68D74EC24B5A9B639498A1AB6109ABC4232F8A46AC614314756D86377A3\n      E256A23686AA67880C586E0E51904AC018A20C848FCBF0E5C4062E7A47468819\n      3D9CF3C079B8722B4A512E5C2D270AE129E18A1869C4B89910A26A287808A188\n      D25DAE3B457E636323F53C363FFB9DAB37760B6552F664BBFE65AFF2AC16338E\n      63DB5695EA61227EE8B7FEEB7B7756E5F0B44FBEDA3EFABCBD7CC8236E63B637\n      EAEF0C1E2823BCB4B3F59D3C7D4392DE20FB98D3FCC9A99905AEF37CC483A296\n      D896B2335C7487ABA8C72A4B5951B7BD8AA21B227B9D846FE9C1AAAAAA7EEF68\n      BD7ACAAB1EE4AE19EB8126D748FCFAEEF6001BD508CBA96DD8C7F74F6D6F6D36\n      836AC5762D4A542E3CCB96521806CE8663EE53E1A808367C9112006895893C4C\n      E2384D22A01126CD153A2ACB33E14F0749916357144E3B037EB4192043EE007F\n      4476545806ABB838A7C039371C0B10C5200A31199BE7618624091B67308D8621\n      16BEB712F80B35B7CA6D57C836B3EB84FB4A191045CADE5478853901BFA61425\n      0B09DF2E84617A865DBD34DEBD95456797F64F02CAF70BED168B993C9319FB6D\n      BFD58F76751E2A0981F061DDFBAE1CBCDDDDE3DCCB29BFB9D3314D96E75A9BE0\n      87D4195AFDCA91B3091F0624FEF8E299572E5DBB35DAFECAD2FCF2DEE82229FE\n      D560E7662EFEBBDAC44B5EA591D3498301B32B6C9273383C387F4B6D13C7478A\n      B2F1982801DCDD0140EC301B9837B8036AE25D00F004D0015F6985C3C40439B9\n      B6F12978E058350782EEFA912DEDE59AFFC42C99B4518C1BA22C709FCDD1E8DD\n      BB64542861F3CC72426A26B8A75E17792601E7A9AC1B926A2F09ABEFDD1A5DDE\n      E96DC88D8F7C6AFFCFFECA8B69B41665C399173F967A16B8233BCA12DC9B211D\n      6130610FE8B056E57BDFBE6C8741F0F103E1942CAE75F8766A3D335B80E546A4\n      F3C64556F75A670F27F1D8F56C08A50AAE54682EB0F3170E5056155652CD5FDB\n      2C2AA9F964BBF0960C7518370BD97D546E83E085DBE737B3E81E4F7A8E6E0F6F\n      6FA6C3DED4897DB15358B6973FEC0EEFAC4D1D3B346A9995099703D5729816AA\n      2CAE50E485A651A6D8513B8B96E711E820114AF507E3F1C8742CAB562186A151\n      DF5883FB242E8AA966C83B70DA13453AA234D22A37CC666A8877EE17595ECC58\n      394FDCD4E17955F28C985BDA3FC0BF97F57EDCD39F3CD8FEEAD3BA6A18B995F2\n      58A9752FCD68D77EF8D7179D9CD58F90BCE8575855C6BEB495E65D3F76D46A2D\n      E9A2EE6BEFDECEECA145759E25C69E8D39369C19C7D201588B6DC045A3AA3429\n      FBCE912CE25E1E5323EB898B14E5D799C3248E1F141D7BE5E24E7BAEDD58A6A9\n      31C215706F51D94ABCC34144468194A6AA8E6B479E844028EF7E820F6AF93BC3\n      F5D73EB01DA379A8C5033DDEE80745CBB4FDDDC13DF0E0D5C959C0B8F02347BB\n      51328AE70FCC156E863BB346AABF3598586ABBC71A52EE019E53F559B31200BF\n      04C62BB0C289F2D641DE2077A39597DF6A36EDC6134BB1258D903FB87473FAD8\n      54FDE8FC30ED7936E3D8A9682A302CB821802EDC43E91CEC7E054AC9716E1995\n      9B011C69EADB7D60BD6ECD9101EFF2EDFFF8A3B52BAB477FEEF9CAB3ED88F470\n      B00471361C251B8C5433919939B34D138E8F28CC9E3BBABE1587FDA9170F0293\n      05D3A716E006777CA1530B6AA12B57BE77E5787C2AFFB5C885AB880862CB0CDC\n      5BCE00140D5D7A9BAE5F5EB38E4D4D7EF9F4B0AD2AB4866ABC8C38F093944601\n      55C3213243FB32202C55BADFBD927EFDCDC99F9810F39EB7FFA89A9C4D55E6C2\n      691FF5C0E36506059C68447AF3AD2B0D2BE024309697F5F2549866014E041A92\n      7D5807C22C290AF5A3AC8094717AF3127BB0232A66F0E4611E549872885B95DA\n      82788DEB3A1D6DC82CBCFFA0203BB5F6F1E18D78E3BBB7D75FBD9A0EC3B46E4E\n      9D3CB87CE0C06C50A3868E2A92EFAF032DE073059D75891930E094C025AC3AE0\n      3F6D85663A28EE8FE58D71BEDEE7DB96CC5299E414A58915020C85194FAA11D5\n      D2322282F3528FC7E871A4455374B365C1AB1C15409D27A9B0C54F4892145250\n      80D4800787CCD8E52C163221C5C5BCFFC341E7E0D2A164205FEBAC8221BC589D\n      F8FC44ED5C329A31B8E13A6DCB48F3FC35B7F1DFDEBA9D64E17FB56FF28BC6D2\n      E2D4B1FE2221A334DADE7DB8BDF6A86A5C73F95F5EBBBD958845CFF9D9E9A527\n      5118196EDF6E9A6625848B201190078844B91CD334B38A36F759CA6FABE48211\n      AEF0F0478F921396FD89C9D67E40CE596E185E57F39B32FD6177F3612E305D09\n      70D5F07CE0F322DF3733331EF4271B0D402B5A009F47C76E0210D3286166606F\n      307BCC051FAF1157C896B58468071CA89C2D41150C556C47E95E9C257198C315\n      71DEC4C9B9AA03CE0B9087467DE1728A160E008DB488B2349622D11202212E7B\n      0427CF48CBB63CE00AB99AAE54271B759F4AF8DB6651540CC7C4817A5E608A43\n      642ACF8A1C7754A366346D86D9C8352AC2B68579D5557FB5BB71B85D6F8D0544\n      C156D5F9A4AE9CCD4DAFE258998C45063F3177BC1B52FC98C947CDDADD7E7763\n      7D1B405C8CFD50B858329ED087C7D5A7F28A26DDCF9D39F0E2FE93FFF6D28DD7\n      06DBBF7A68F6E4DAE645C7FEE7D1786D987ED9317EF1E489C958199DDE846BBB\n      81C131EC16B62A90F0D934B534406886B79001CB2E2C97D80EAE30C6CA15D64F\n      F0697370CA3A37118899856BE1A6014E3DEC2332C08180A934957B6CC239D0D2\n      3ED535A5016EA75E76AF1BDFECD89151E45C65054D942BE1A73399E5F0F40B01\n      5C0D38C69E99BAE3C8BCBA3D78FBD18A72D4F3E70F1E3F3D3DFF89C3C5E999B4\n      182A4A1D80713E500F62693CAAB248ED4CAF7CFBC2DC9163DEA9C9381C742E3D\n      DC37BF902D8227F2D5C3DDB5EBB70EBC7036AF1A44E6B6654964FC80B10B8AF6\n      8887270F841D55F337378B7A6A3DD926E612D327705AD5DDD35418C2C50679D5\n      51F1A364F8C8759B744FAEBE7B636271CA5FF0D322F649A3FFC156344C664E2D\n      90166101EE21C03A0712C3722EC7300A03557BD4FFDF445AE26C0045321C2A99\n      1B6E0098CA20C442C55430713BE7565E50ECC22A2420156BC873A1866CD43482\n      E2CA4EBAD5B7E79C0CB84EEE989903942367433DBBE0BE65AE7D6DC5F8A9E3AD\n      DF3A4F3C8B470C35EAF4C3202AC823F3EECB3F6E37BDC6BE2CD51195159A36A8\n      2322BE8E3B763F08ECDD4A12F7123A9E3ABF902DA54A02DDB41128308615554C\n      0DC2635065B11D8E12E69DB8512A586410C2730DC7D54A0AAD7C51337AF5D1CA\n      68A7D7D9777696D4C1EF640CE337B7C1572C82771F55217C0A7F543F7AFEABAF\n      D0ECD2E7CC87AAFB9D9562A46A87AA69908A040295E55BF678AF5700A25CB206\n      8DF5A98DA5EE662731736FD1038759110160F8FE6ECF596E788B6EC22132096A\n      C759F5AC097691EFA00A95E9772DE5586EB0A206DFBA516483898FD64601B392\n      F9E1A53DB76506478CD4CC6D2C322B65C15987AF6C74A396D016970C2CDAB048\n      868BEE7829108CFDE04AD90CC79BCD8A195AEBDFF960F4DABDA3CF7E8CFFB423\n      930AB3536D74C0B28ADC718857C2492D0300E8404104D5BEBC4E77AFDE6C3D7F\n      481CC89322AD00AB82901D8BDD1FADED9B3AB1BBBEB9FEC1DAE9633FBDFDC91F\n      5632AB925668087C3C57D538E5DADFA9872F77C2715CFDF231FB278F8634AF44\n      154681A7835B8BCB02BE0FF65318398EF64A7F74677CE1DF7FF364BD35F37C94\n      CF4EB1B9739803A2315534CDB18AAB4C0587D5EC24FDB72FDB7E23CBCDDA13E7\n      E4622349F240324C620086837B462919E059A681C4802B9188DBEFF1477B79D5\n      F2CF1D2A1C87173EB17C858F0CF576A5AB2D80240FD78CB5BBDD07C5BB2FDF1F\n      AF534BB9CDA6DB6CDB0796A7A85550E0178ECD7042D9289A969CCB8A250FDC9D\n      AF3D1C38140EEA663B21CB87727590DD1CC56B7BC1AA03FE334F520E40167DB9\n      C4B6170C6EA536A62E6D927CD8FE8129D0521E85FE6D59AB1C2A04F78F1D371A\n      A54FA49D321E193BA218105440EC19C50F65A73B575959D9B2C7AA39B9FF95AD\n      5580A71FF11B5F5A9E3BBDFA68C130B3997A9DEBB6E4BFFF60FD7F95F2A7A7A7\n      7F573BADA9B9DE8953D6DEEEB5ADABE3B4AFBDD6BFFB60E5DDC05F4FC329917D\n      7961DF01456A391C384C5DDBA298CD95B0C8A68F961464A8CF2F0DD192CE68A8\n      AFFBF402DDBDBBD75BCDAC9F9A997F9AAA1A4D534BF6A91592E0912217C7BB37\n      A27E86D35646A96C944D375AB601FE386BD483FEDEEE64BBEE19C0DD150EF702\n      8DD3149312589E414CFE58E18551FEB8E1B3289DD1E35429FCB13068821DB542\n      2A78E1DCB06D6E1A39FC073C3D030F3EB049F499942739D82CD06992232B2F7C\n      C7A932DEA46CDE71DD5154136AC60D58263D92636B8FC942A5BA492C21A69A98\n      4DC53916049B26E6C7281DD30180D020352DE2DED4F1A5B4DFAAD71AA2A85A6C\n      BFE53C4FBCFD0970607DA3A6DA31F81919B90E30EBCB3B839749FF8651F4D2F1\n      84426E90828F45550F80E2C64230FD4FEACBBFA8B5BB30F1AF45F6BFBF73E1B7\n      97A78F8D367E44F81F8DC8FD5172B848BE78EAB0B1D39D12F2FCE282311AB60D\n      B3A295AB35B769E614C2C4ADA31C05062CDCB346110DAB001C8A9D639FA9816D\n      F38030282AD148ACCB4B2BB770BF89872DB3160D0040C793B975AC664CD694CB\n      485BA56ED80CA7863777D46A1E44266ABEE549AE3200C334295428805EE67924\n      65942BB39AC355A8ED5C5DDC0D6FAE8EC0A9CC2D7AE7FEEEF1937FFF9C0AD224\n      C900926715DA1800DA371347A014D9B5CD952B2B4B2F9D77A6FCEE7B2B795FCF\n      3C79ACF0BA7447AE5CFA607269BE7A6449D254519CA6053C4C112C22642C6163\n      91D9A91356D30BDB6422B5CE4E50BEC4D513383CE57624492DE16304CB3B2A7D\n      9467DB003A3D511BAE0CBADDF585B32D6CEF54551DB73A17EF06565A79612169\n      016A16B8F1052EAC1459806786A3381C421C116592A65C4053182267245769C8\n      DC6A96E24C0517400252E239B9E5E79827275CE6A9AF9C7E55C47968746CC086\n      DB8E7EB8A78D710C105AFB6E0231354DB9E8B5BC99F72676BFBE56F9958FF29F\n      DB0F80CF0326E10ED3FC4E302AC84DF6FE77DE3A7172DE09B6322AA46E5919DC\n      693A34565CBB92FEC8B26FB8C025ACB38179C2EA9B5BB6369DC491F0C44C0AE8\n      DBE060140CAE9E61C73AAE1D1224C7D5BDC810EB809D0A3216765FD3D4194EE9\n      3B53DBB736AB0755F56490990696B17706E24A25386E65B35946C20650F9CC1E\n      354E3CF50FFF86EABFFA78F8EACEEEFDD1FC91B6E5E42A116912DB81D9DBED55\n      1A2DA35D4B75E84996AC0F13513833137C82416C2E46B2B3B15D3B54F18FB999\n      8E2110789559D6AA1225531A129FD8194E798F99AE0B2FFDE6ADDECDAD994F1E\n      4DBCAEE7557B57867D3A9E3E0290172287C22160DB105C31D46B2C9754632B10\n      703AB073CB48201A38C524C9F82EF6EBA741566BC88653DDE3C99FDDDDB97067\n      EE2716ED976612125B31F826B32CB2A4C8C93C3362A8FED8341BC538A6344B2C\n      3D7AF53678C4B97327E199A6391C7D08BD54F4C7BB973767EDA7E04FD3E9A4F9\n      C5C650A7F58473D31C1411E07B6F6416AA9D3C4AD6DFBDD1D8576FFFFCB3F962\n      4DE3FA21ADBC3A382E271F129E46D8EFED03A5B255C2EF245BFFE66DDDED4CFD\n      DC4272D0B05B73E6C482A24E51E4F8EE742E44C63D13F55FF646BDF757DB60D3\n      F5BA7BFE04B8322C04E6C2F1822C430D245A0EA53D9E5228415034BCF3666D2D\n      24AC309E7F820054C0DC0C1869B5488163D880122A96BBFBEEB5E40FBF7F6963\n      BD9B4A3823879DEAB98525AB624BCFC8C0715AAE617252A1B95B88A9C2F53DD6\n      768A691B423F589C99FB66EEA06E0115F9A32EBDDC376E6572779067994C52B0\n      3AA3AC90A1B25A79C2CA1E7E2C81C1FF4C2C545F3170E1290563D5255BCCB149\n      A640B1D854F30C67E264EE39433A2AF4C509D1D5720198BD51FC41763FAA0447\n      47EEB5DECE3D0FB78490883D6DD6FEF3D999AAE84C35F54122686DFAFF36FD3F\n      BC70E5F3C1CC6F2E1CAF35AA74A6BE1DEE6CC53DB5AB3EB8BFF55EC05E33865B\n      9DBDE76CE3735663C10D88D22E8261462C7A20129231B094B181C3EB0E84042D\n      B0E1C97406B9BA978BBB35EB9D517710757FB6B9FF7848B1FC2B04D8C91D4BBC\n      CBE3D8F5363BA32B83F1D83174C1672022B66A5BE3FEE2E44CB6D3755DABDAAA\n      86A3DE8CEB37990D5ED666E0BC5114CFC0EA0C2D918132093E0A7838E51E555C\n      16A3186E36960CECBB14C8C0B576806A28B09E8C493097288F0DB808D3120215\n      6898C069E88AD4CD3C9928F286C3044030ABA232872BD776DC8CAB98EA7B5A77\n      45BCA3E29D7498246983F1436E6DD9AAB4726038C2B30D6D62C6CD4C2CD46885\n      1F6C5A3759F2A35167D2F01623C3C8D366D57F2AA83F5938ED4C5D6CCA6A86FB\n      65EE4C3A6FEFEEACAD0DEC5ABB639B773A1D96E50173C645820967575642FEDC\n      FE539393D9A98DBDAFEEFFEC059DFFDEB5BFFCDCF4DCA7B2EA6B72F75F8C76C2\n      D045D940534F64FA7327CF383A951BEB5FAACE9E2BDCC4531D2B5EE67E7D0067\n      808455941125F638C1893EDF6775DBE1BA028C36765893A6150994C54D09CB1B\n      5900A421B6696273D4E70154E133DE72EAEDAA59B7448DF30AA760F35925BAB5\n      EAEE09302F3888512E0B709192F02837C25C4AA0BC39C091569E922C36E14FB3\n      A2E70697E2ECD6FDCD6A2FF27DB1F80F9E3EF77B5F29802C6D8F8BC688EF35A4\n      5FDFAC77A788E2DFBCD7EF86AD2F1DA646347CEB4E656939DDE74581E63FBAD7\n      DBEB2E3F75BAA8D8699111291D8E3A60082309561178B9A325B5883DE4FD1F5E\n      AE2CD78A1373055FB4E422DC94E0618133C298BE85B324E22D39BE62B358F3AA\n      336CF55FBDEDB72AE6D3131DABD3CC73B2A96E5ED95A989EAF9D5A90730FA4AC\n      73D6B2F0DBBA08FACD466A59DACC00A299998F991B3682BB2FBB9351B40A751F\n      558ED44A63BBA9E56058C455A805E00E9B3143A46906AE94514B32D58FC3ED5D\n      9CCDA7E08510EE2AA992BA51B9ECAEBDBE3BFB8F7E2A79A1C673E9A75E6CF732\n      79BF3676E8B7B7376EDF0B9EB51DD31662E8C2D3CFDA198D92C68E3DAE15AF35\n      A33BE37461BDF9F11A097C03200AE6C8B194AD51314997F54E8A734558F3E465\n      6F5F51D25E66E0F88402E029486AE40E5BB193CB38BC6C9E50EA489291BC954E\n      0F6F8FC683707A799F5161B98AB92120A426F5C3CFFDD6AB54FE0F67D6EEAE78\n      10F4DAB380177A6BF79B4DBF3F1A2ACB0CDA354D81975A83F5311DE71327E614\n      F65270D9CFBAFD2D7B96B64EB6223906EA673B55125464D56145CC00B5E42AC7\n      4E66CB9376F4E666E7E2C6CC52CB9A17AA42FADBF9F0E6E8C099E9A2AD146780\n      DAB09EC24DCC0D606B132D70E00D35C5B0550CF31B55468706C9A8EB0BA6129F\n      CBC86A8AC5D137DEBFFEF685139F3E5279E9AC9223A98784D0724018E04F5E70\n      225C306FE6B767E438D1E3185EDBCECA4AB2D35FFAC859018C2913A60DBE511A\n      CC0CD77687573AD3C962E7EA76EBD909FD5422A4E9A31BA629006026DCC8E6A3\n      A9FEFBDBF7566E9DFFC54F14E7E7722C683A0AEED2AC80CF42A5F922225E25E3\n      56A675A52FC2AF5D8EDF5AD37535FD957D499BD98D69569F57040B8826C5E610\n      2D33CCFDC299D81D0EAE6DD506963AB8DF3CBD5CEE8FB3D24CDAB68D5BE3B155\n      9095FA010C85ADE12665165D7DCFD81D8C8DBCF5D1D3998583D1D40DB204E0A9\n      83DD37D42C6EECFCF85FFFC5C30FF61878B3283B3039FBC4FC5205021CD3110E\n      08791E200C8381F71AFBD4AE09DB75F9844D661DD9A4402C99F689004E820547\n      B131525746C6CDACE88C054466B028A1B06B51959226B8E5A50C84C5E30429C4\n      796C5DE0A5EC112BCA5C0E2D7553B442B9F40C0003C0B53C4E6C969B7D99DDF7\n      D5D8E4E928DD33F93B2C7AFFE1CEC9F9A52BDB9B77698693C4929DB0BDDF999B\n      DD978D66B85872CC5B8DDAEF5CBB6593893FFEE817A659BE867B31D3F5EFBF75\n      716F6BFAD0A90BFDD15FACDE360C72C8343F3B39B700412607B6C96CC77605AD\n      A802C770915843BCC754AD05FC83A17CA72C4846CCBB4976C9106F8E7617ABD6\n      4F7A8B0B51217D167101FCB997C6EBC3916106436AFD381F5E0D078042AB529A\n      553F2B74BBDE4C3BBD8353D3E3613F8AC7CB8BB376265B8EA792D4E046A15449\n      06051A35F67A63942B25125959B3010F84AD3438BF89932B9C634A84E25F3168\n      5E3E6E81E49141ECA0A230007D310941D2A14695501768612198E3A5CC898495\n      499ECA7C18F586C9789D61D5D0B6CD8AEFD56CABED78554DEA94044A7B1CC78F\n      B33C965258B91FAAB4EC65625160DFD6635209269D4A5D9209A567355D14455B\n      177DA6D3712A6AD5EF0D373F2832A335FDA81B5DED6C2BDB5512759F84CE0B0F\n      5E999CC89C3698951AFEE385835F3CF0C26B3CF95FAE7EF305BFFE42D1FC6EBC\n      F9BF85FD3C7311DB8968D27527DB0DB9B1F9923DF1D9FD87439E74C2CE416A1F\n      2A9C4AAD7257F503831F17CC48E2B45274ABDCA0B69716BCCAE2260009A30297\n      2BAD2C50639E7945A5DC2F586807EBB37041C23658CDF1AB8E5531559D8BBA45\n      3D9327BC7BEF91D357AE6014ABD45877C23C7F26589A6981EDB7120707B90958\n      01CE1C4AF09B0973D6F6C657EFDC8F81F736C9337FE7E9A77EE979D92AD262D3\n      1187B43B9DF1ADCA68AFF3CA753A3DD97A665FB1BA12DDDD099E7D424C386AAD\n      B77BE5FAE4C29CB334AD8D02E80B60238ECE0FA16D299080C93E8849B9C5AC11\n      EFBFFE7EE3484B1C9BD56CDE960B70FA154F8AB2F88EDB5BC176D4808C2F5B79\n      880B15555B5FDC1EDE7ED4FEDCF96EB35F2DC6B6743A6BE9FA95F573278FCA27\n      25D735B0F79CA516451173E018D26299E1E2A67305BE0DC288A5EC04A731D9E3\n      0B02D896972B5034921203970894EAF18A817F05D0A69504FA2F721B3859A6D2\n      ED1E4985A1D177A303905AD60CEB225F7BBBBFEF777E3A7CD6B3B2C2CD9CD8EC\n      A7F9837A97AB3FBF93E6929D2BED9B67B8463A6D0A238D825D6FD44CBEEB88CD\n      849F19B9E780EDB91C801D2BB52590B83ED6512BFBAE4939988EF3B5986BC243\n      5494529B0E20F75CA7C44CCCF06E561B4DA449EA1D37F2C5719C47CD6C7ABC12\n      81954EEC9B2A38209CD03020BE1A517DF985DF7C95EE7D615F3AB9DB5A6E8BB8\n      9986B4EAC93CDC4B15710F4C2734F463A97755181793FB1A021CA9E3F4C01F74\n      7B9327EAD5E36ECE8491C011B00A70A3754BC1173A85284B9CCAA0E08EE93837\n      F6B6BE798B04ADE9A75C56EB247DEBC15D3933D16E1C7609194644163EBC7CD3\n      202595A3E50257604CF0BB6570AC8BDBB9EB30DEB77341AD661AD81195ED512B\n      FEA36BE9FDADFA1767D9271B69268CB10B6705276D70E48502C45706043EE6F8\n      AEF2ADDEB057B103FE6030BAFCC0393513ECDF97A591598E7CA722B5B90D7148\n      DC1CB35D2B2DE8BECF1FCAEA3B188DA5C6F4BD49431AD10208BBB3FDBD07C6E1\n      FAF4AF3E23AB38C04FA9999BCAA5BE1200F29525C6B820D40657EF67DF7BE87C\n      7F358D87CE8B33E4282D02CBA94E916052E204973229407C012106C59BB5D0BD\n      71747B8F6D6BFFEC99E2F01C2A9738367671614444C1DD7276AC54582F230F4D\n      85B874830E76B79CA4F5E229695BA646640477644760D76EF7FAC6E57FFB4AF2\n      EEC65A3033478D5353B3134EC070D5B2257C5306A663910AD652781CD8610040\n      23345D57374C3E6BB31623158ED5162DB135AF507237C9AEC5FA5A646F0A3800\n      32CE80C4F3B2FF1327DF1EF7339681B01C09785C5287F38992D34C95D74C5142\n      4CC1E107D69117149042A6639C57320752C0DFECDBFCB574A7EF385E61DF5EDB\n      DA98F01EE5493ECA716BB0C5263DFACBED89CF8EE961E224FBAAFFE2C1ADF7FB\n      C53FFDEC2F7CA1591BCAAD37F61E0EBBFD45BBF2F2DD4717C2E1EDBABD3108CF\n      B1E0A71BF30BA62164886CCCE6E0749A824CE67C58D70ED06CC9CA16D7B2231B\n      8DC5C881A32AD6F3FD1F15E1D71E3D7AD2245F0816F71173AB41EE9B317CBB97\n      10DA4B4844879EF7418DFF60674D44798E9B3E09E038CB45E1AF73B34B83870F\n      DB130DBBE10E76760EB7A76CA12476FB959324F8A5B44AB55C88C360ADB8E510\n      C331844024D6A8B583B36C0657468E6330A43039A62E709F05846F6EE1D4BA45\n      0B389D3D258196BB58E5243A03249864DB49DE153A027FA0B2A6451BAEC5FC6A\n      C33427A859CF8B6AAE7CA52BA665E1442EE116174AC5698AC84A167921B1673E\n      97C471D764DCD199E7BAFB9CEA02B5DA52FA5A5844B92923BEBF96A77788BCE7\n      1A17FABD3B7B3D60A7D2B5710D6C2E3083438B9C3037D3FB2CE7974F9CFE3CF5\n      97ACE977E783FFE9C77FF12C733EC29B7FD65BF9B32CE7CA03771A1458D3EB19\n      627F61FC6733A7EA53B53FED5DDDBED7FDEF0F1F9FF3AAAFC7AB571E6DFDC24C\n      FB73ACA9687DCB88BB5E6FCE3671574AE0EF3688B28BA92270A5A11C36021FCF\n      3D5316E0AA0120E43EBC54C336002A5845C5A03EB32A465E87906945FDB8DE00\n      00FFFF494441547971DEDDECF018E227C534548E6DB9E0BEB16D2497141895C0\n      2E96D8F678228A4228A60CDC944285E1BF3D1C5CDDDE6EC24F5283A77EEB63F3\n      BFFA5C5EDBCED3039EB9E8665B6CF5EAA36BB7FCE79FAE4ED786DFFFD144B551\n      9CDF9FA9C27E79A54376A73F7A9E98125BFD25EAA35A65A580A21C63392C0367\n      078E9CC5CC21D97DF34AFBC454BE0CCE7AC19273787956063602F683AD0FCC14\n      2426836B46D4A5864E4CDB5ACF1EBD7CB5F0260E7CEEB472370A1D1A7472F7FA\n      70EFCED6C2470FF98B41C6BA56102411B750822F86C891F34A99338DED1C2846\n      8DB8A3C77A0FA54A1476C015E877CA2D2858592C6BDB280661684C52A03E7B16\n      C16BC0DD3A726F94F5C6A602AB367419088DAA23DF48B66FE50BBFF3E5F119CB\n      019094B9B9358CA2BBF535B1F17FBC3D7FF0607C34A2716ED8809E849978CAD4\n      A13DF686F5BD6FC5AE322B1FB38AF9181D89B2E9DF2E192EF7B594EDE79A9866\n      B93117F50535B6FD94D28EC861E1E7E48E350C761FEE884CCE0673A3DEB87EBC\n      9ED406799AF961BDBF3230EBBC3E352154A60105A0FAA61DD70E7EF4ABAFD29D\n      2FCC56969935ED74F6C04F4E18329151DF6A57E306D6208DAD6CB031682CCEAA\n      C9911DFBE15A12E6E3DAC98AB764E688256D9C726C52D2B650AE5CF8242D5845\n      843A72BD257247EC7EE3020B65EBE9257D20A63ABEFFC3CEF4C489E0A82BAC81\n      41CA6DF310C381B79BCA3430258A0BDB189700E92D97A3920C26D1397380E9A6\n      2EB18DAA759F6F7FE38ADCDA9C7FF1203DD7CAEC942B6D01E6C12627F01EE023\n      003900CDF44CDB2716EB8FB66D38A8FDBCF3FE8339BB653D339BE2B62D834B81\n      3A91B805CC17EFF5C4D54138CA9D1353B553B5ACD83331A664AEE48692B19316\n      4690BF32CA2EF6A67EFD63F9477176DECF0389A2EE0A351320EEDB06CEFA1421\n      83977E3B1B7EFD4EA3277B6E3F7869561E305DA7623A0DE2B524168C348EBD40\n      FCC3058E4A65111F67F1AD3DBD2983679F5607A6C08F99B64BCA3575A8658933\n      6345A9AA876946AC26246372E91D6337EA7BDAFFF469301527050B6412804764\n      6FBD7EEFBD6FBDDD7D304876E24665FA54AB75A05A052B4A0024D83E2EA6B151\n      85CDC61D26A6F082CCF71B24294C4B02536C19BC5A9006276D533AE516442072\n      2395DE8AA36BE3EA1A9119D84F867ADD65AE4297B58D72A7106033590E076843\n      3D16A1267F2B3783423B003051101A684CA6554E65AEE3BCD8320B082ED5986E\n      31FD9764F77E1C3F5DDFBFDA1DFE75BE13735289894FDD6D92183EF97B8B93BF\n      D5F3E70AFF1B8BFA0FAEDFF8C7FB3FFE9B4F7CA4A3EE85E95E7C7BF71B373E58\n      9FAB5BED7DDFB8737B43E4C420A7DD892FB4E767800BE62985174CD19536E01C\n      4B895D5318C46906409B967B8FB4B24CB433C9CC475A5F90A3CB3A3A4B9DA78B\n      DAB432C2BAB16DE6A3281C84E34C68D7AC6496B3E6F2F77BBBBB80B0F8879ADB\n      F0CB73BC45CBE7C3E1C1E9B931046022662AE0A625B8908AC0C563AC5C1D52EA\n      E6C1BB2C0B008FA54969991F23AA1490A6A644889B42B8E3A8960D1606E82661\n      34026C01069DD1413418D90944D548D011B86CA063E56B88C0591AAC541F2A8E\n      B72A0B7E60A6D2D6DA4DF3094166B83DCD9C3AF8108D79D9B1567DA9E0639561\n      0A863BE22C452D4D4297EF125923D6BC725C822A253305C0269A9A325334F3BD\n      75ADAEF47B97C6833B940E15B027520A25682353A7279BD554BEA962272C6603\n      F7A3C70F1D58DDF9A9FAF1DDE5F97F76F15B674DFB05BBF16F36AEBF42A8A37C\n      59641EAE9D603B245FA8D73F3B75E0CAFADDF7C4F8A989C95F5A3C7E696BE56F\n      F6D6F771FF77E7670E70EB47BC76E1D6B59766DD175D8B9BD58E1B843A9EC7CD\n      2D86085C8EB40198B26968CB515CDB32F2E1D11995C22B0C2BAC12E6932A9044\n      C7CE5CDB1171D81FA22E120A9233DCAC055C5B69962B8AA3B1B89301488F23FE\n      3FD2DE3448B2EC3A0FBBEB5B73CFAC7DEFEEEA7D9B9EC1CC608019AC04409004\n      2841A2291A324559B4251A222539BC842539B42B420A5BB615525896C2A44453\n      96284AA2450224400CC00166C54C637A7ADF97DAB32AF7CCB7DF77AFCF79D543\n      FED12FBBA7A3A7BBABAB2AF3BE7BCFF9BE73CFF9BE881B8E5AB816075688D663\n      CCEA5BCECD83CEE39D769204AC257FEC4FFDF1B93F3BABD4BCA44DA9F6C66FFD\n      CECE4177FD477F34D171F7871FCC9F3C45A7CBC9C188FE3FD7F80BF3E2182C64\n      AA6D9666096C06CBC2CA39E2C4436958829B1207273BD9D6EBEF2F3EB394AEB6\n      885C956AA9385409929F027762CCD7891ADFB3821D0A545CA08DCDE89DDEF856\n      525AA9B55EA9246EDF8C8593CFEF5DD9A5EDB0F5E519324DF5C87001473A16A8\n      B2065F2307064088EB286C9E3656D1FE8D4FD21C8A3C90436D071C00C6866426\n      D0F4A6F01BC5B90A543B8EA38208323D8EC37697A6041E4CD12D476CCB1D7FB7\n      3BDC7717FFD24F4E8E1947199188C499C4E3C7D55BA33BFFEC7B275E7A3E5A1A\n      7280D43805606482940E82AA7AC2F7BEDD9E996B953E56CA4B43026B2E9D0CA0\n      C2618FEBE1753AE66303698214A6378763CA48A98D80283861A329B2A8EED3AD\n      278F9A271AF03EB3495E3BD20AD881A452B6DD9D5B6D7F4DD49BF554A7000A8C\n      82EF21A2F2B157BEF61D3AFCDAA2EF35229D71C73065FAED416DB6E24C0BD81B\n      FD9D300E557DB66E3B3CF406E387A37CA4662E4C8BA37C9244E5BCCA9815F961\n      3EC59D7289A59264108F69EEDB1989ED763EFE7A3B7E9CD94773F759F880BDFF\n      7E0A1F683D3B9B9413B47CC61151A2A52636C96C130B38888079B9ADD0689148\n      9B5A9067B35C1227ADC30E87BF0BAF1F0CBEBBE17153FBDC9C3A0E789FF9A1AB\n      C73D5E85B0EC70A066905E6C9E4B6941F8A45CE5994E2219AA83EBF7FD5AABB2\n      7E44B1310A20C0B74A156C968C253228A7AF76FB9777CC949CF9DC7A56C5DE23\n      AAAD208D5DC44F63522259E0EEFE87ED9AAED77EEE23C31389E4BE1738F0CD00\n      73E2A1C1ABA6346563E2337B434F7EFD8EBD43D077A53E9CF9C4323D0D89C515\n      BC6AEC4A2E1C83FE6B29B63DA155789604032752839BED6C339BFEE427F263B3\n      388480045016D3D487625B85E8163A2B6101DF045DFDCE77EDB68E4B8EFB2317\n      5549CB202656858CEDCBBF7DF3D1D76F77EEECB925B75CF69F91F52917E89F06\n      9E1A42D0A79604D40647C1C5D11214E5918EB2EC32845A69E7C0DF7D092183D4\n      683A23521B8BD0C84223926EE6E1FD0930853C455288E31318B70BDF5DAC991C\n      FA2CA1056891080F711B45FAAA0FFD32F14A14AB7B8A65294D3293247AAC5587\n      418011E9441DD8F28A6FBE7FE7FE4A7576ECDADFEF6F02472965C6A676DFC2C6\n      A73FDEAA7C8DCD579DCADFCE1E6C97C83F3CF7A54B8A3FE85CBDBEF3B84EE66E\n      39FC970F505F3C82CD42AD865F6A3AA2D1ED5F14DE3CB05FCFAA1BBA6A784992\n      098F5D0D81AD3077C40E158D6ACD592AE5E19D9D35B6AD1B797C25E82E4B795E\n      345A198B51681C9DD277447A35E8461A7695086D6B9FEBEDC1602BCE50E8B278\n      48900E2C458E3567962BB5839DCDC65CCD76B91EF5E72CBF3441C028F1A217BB\n      DD003BA3DAA7E18702A5BAE8DB2358DFA42838831E1724A439042D6DB14C9B94\n      73485AFB510A5887E2D463B81B05D87E8B6109BBE0A5D658E1B0AC986057E85A\n      DD3D55AFD6D2AC94A6AE943E253526EA9CFB89AE325B689EE4649293808B48CA\n      002D9CC6BEA27E946B473EB2E20E514744E5A8F25C8D059A1A312E92CEA4DBAC\n      6E8EC71FF4BB0F09E9B8EE6E9AF58214DB86A9E249DA22F48F1E3F3E3F8CFFC6\n      609BC5B9073CB8C47EA23AF58B2B1F3DF0FCBFF9F637CE35CAE76DFF7F7F74F3\n      2D41DDACA4540898040D4C24B7A4849D1D5325737AC6ADFA8C5F4D0FBAA9F9CA\n      D1E35F69346F6CDDF9B7C3F844B9FADFCDCF2F8D26D7297973D0F948B9FC39D7\n      17593A99AD25558BD39843CE1715413C48180C4579B14492D85215F0CF65944A\n      2FB45C8B246910B14493041FAC52981610476429B6D4024E23901C752D8D0867\n      718A8DE078679FE0F686D7D9CBC27D416EEF1E0C0EC21936FDD2DFBAB4FC635F\n      D40E9CFE07EDF75E9B24F4E8473F33DC7E381AB7E7CF9F63CCEFBD7F9BEDF5EA\n      AF9CCC19EAF067D8410C4407686CE18E5B9CF6C3580EA988C38AECC78FDFFA60\n      F5F9B574AE4AE4114916B16B9447861619936638150D6F30DBE3E37B5A0C01E9\n      F0908DAE8FCBD14CBBBD535D35A5D3F500BE50EA5A7DD2797B3BAC8D973E7946\n      9780AA8738738263278AA374A99DB32A76CBB088622F94396C41A0853EE0A1C1\n      366CD7FC700C91E355DCA17126CA651C3A4A4789497278D693FD9E89528BE240\n      030AF66BB7F3ED9D844C2FFCF99F08175208942C21B13BC987BBD65BDB3B5FBF\n      BEF2B14BE9745FA42A450E01BC27858827F256F7CA6474FB60FEC2A27D42E67C\n      0C90019E5CAA143AAE605194B30FC77069B15E943C15AE2A3AC6982A3A0BED7E\n      65E79D3DBB6537CE5536B79ED444D39FAB8DCC5E4996F3FB7C7067547E917AAE\n      9764D84D0B901C187B503AF6C95F7A95C67F755967CD3836F532D97B70B7BA30\n      67A62D440C80C66189E7A455B7EA91DDE9ECF7E2BDF90BCDD2AC0B38DB629548\n      C5B441EC055F71B479E1C88D469A7313F85EE68CBFF366763B294D1F4F8E8FCA\n      6BC1E41A518F1BD5974A41F33A37D3AE6E6A162516CD24430F732972802636CE\n      4BE0E8212D8890CD13CF495DBF9411BA473BAF6D76EE6EAF3CBBECBED08ABD61\n      E859C8640255B24B46A5AC686104D0CC5D1BE76D248EC7F8F0BF5E36BE725799\n      BCFEC299A444659CC54E4E52EE51373507A993967B53C16F1C048F3AD5179AF2\n      C57AA2033BCF9971F11695E52A1F58D44DAE269BEF1ECC7DFC52E9D373A36A04\n      89CDD62E24010BC7C288B420998F8D9DB2C81A7E6B337FF5C974B9B26FB6D205\n      B1F8CA293545A90B51A8A2A58FD25CB4F012C669698086933C1EB949DEB9B13B\n      BA3739F2E52FE9B516D6BE331C70A685874441FD0B388485348A2673A34EFED6\n      77ED8E1E7A76EDF397D2AA71E0984C9CF7FEDDFBEF7FFD2E69C30BC98FD5BD13\n      732D9100E8E63A2763E07615CB68E0DEF06A6DE07FB0E2940B6591541A9993CC\n      B28528F9CC619227751E55E155440E4B054466D8F643A67623DE55388A0B794C\n      A96276222BAC180EAD267272383808A4075DF08AF1B90F270B213DE06C6202A7\n      8A47298D158D92BC0B81879884F1C759B4CD816A54AE3CDAB89386CEE2DCC67E\n      DB8E2960A41068A6E75A51F4D376FD8F1D39BD1D4E7EE3D1952F7CE58B5F9A5F\n      9EBE7E37EDECFFDB9D47BF390C8E7FE2B3EFDDBCF5C6A4E319370F8206B7CFAD\n      2ECE2429DFD95D70BD69AF045B6D4E300F02A507698DC3F3170AFB5E1576CD41\n      BAC5DBB1AC48A2B190BB16DB9390B5A355ED95C23CC953DB7560F50F58BA4D81\n      3EC838481F8F06DB5485161D69C9ABA5BD687230E8637B81C1B16F4F91C55269\n      69797EA7BF65A7E9B9DA74691259380945195A67121CFA4658CDF1321C7319DE\n      B81625649C214A29AA4E25B03E02521C0F00DB497B485857C35ED6ED208AC214\n      1842806D4A18145088A9085EC2B668AA9A8C9F9F9A59B22C1E84751C3D744B9C\n      3A463B78C15818EFA015A2C90AA5128A8AB7E1C415B310512335F4E8C0E7D273\n      7C23BC9CC009B1D3CC41B338E16B76DDA5D776B6BBB5F25DA2AFEFF7925C20E2\n      865442623F239F6A567F72797DA637F9A551AFDDDF5F99AA9F5D5EFA546AFDC4\n      D491DBC4FC4FEF7DE7FC6C7DC1D0FFF3D1BD2BB683BA169274D308323D8A734D\n      501A13E0011CAA9AE1898903611C215F9C3D22C2E0F2C12684E15FB870F62566\n      3FEA0FFFF9F6931A935F3B72F4133A9182F62C16547C0ECF5E1CA4DEACB26A9E\n      969514837560F1D4111ECB1CD87492055E25B34A8484223132353C4C2115209D\n      E63CA5A8410851022810C50B3CD8F54094933C0B5D78A0C4569080002AA98440\n      F43666A4C5FBF7B6816F2B6BEF137FF34F1FFFCA59123CDAFAFEB763BB7EECCC\n      8B836B57554D359EB9000166E38DCBADD3F3E5E546863EA63CCD951438C46252\n      C0D3F2309217CD1FF81BCE05DB4F363FB8BDF4D11349991B6BD5262B382FC942\n      78A5382D898A69583363D93E1B5D4DC89E721C7FEC74AEB72BD32B2C89F6AF5C\n      9EBB7426586EE8745CC9533DAE6CFFDEEDFA9146E9F30B93B4EF9B32CD536585\n      C03DB1631DF57A083628A3C14A71F5429E5A8816679914CE6A85BD0FCE44612C\n      F8C34448F182D044099A780CC66A1CC91C711C8E2B4EECED6F3F32B5B5C53FFB\n      85B015BB385D9E4662C207FDC16F7D20EF8F1BCF1D53953E5329DE7B4A5897C0\n      322EEF4C6DBCBE030167FEB959DD82B310E3E42D36A3E3250B66E342C9B17881\n      856423E297C3FE044D0B36C268458CF9F861900CD3C6D9D9D89F6C3E7AB8D25C\n      93556B2CBA0C0EFDFBD4EF56CD278758BFC0F0C32C3CB26EE81F7DF997BE4DF5\n      5F39D50B72BFD28CDBDB82C5D6620D4EB8E8656663E4CD56E3650FF686F528DE\n      89BA2B2F4CD1E9C4A099570DE05B5C4D9DA66B7B0DCA4A59318AC23360BB1527\n      2BEF7FE38A0B9F5E723B0D555B6FF24E32BE39AE9E3DA257F663B7E70533286D\n      6E019DB60DB6FD4060B098E562473EB0358FA61ECAC770EC012DD3C8DD7F78E7\n      C90F1E56D2C6898F5D346B49EAF62C514A8714A28EB2725C9088BB244CA59373\n      1B5E1080AF88C62449FC5866B7F6869DC1D4F3677599842C72122BF1032BB365\n      5A1A905D678639372BFBBFBCCD79DEFCD29C9E490114A2F11BF36524321664D6\n      D81D57C36F1CEC076AE5CF7C9C2E7338F7D2AF1466454C64190576274C604D5C\n      78346F74AFFCDFEFAECD2ED7ABAADBBEE39C59B4CE2D912697F539C25D1C37E2\n      569108152F62583ADAE728B2A80737F7B76EF4CEFED44FE9F92A322965B890D8\n      1A838669A410593FAC9E4024567AD0653FF81EEF84079EAE7CEE7952AA79A3F2\n      DD7FF9F6ABBFF94E3210156D1F2D974E352B65AAFA6A58A7150ADCC7B5276C62\n      B8B21C1C6CD390098983E5615BC7562E88492D5BE676257553C607654E5D20D4\n      70F0B2A4B0F770636AC6400970EC017E35E863807EBCC8598B3B4CE43045CE63\n      78EB911688A4B833846FA6B4844418650490B61661C6261919A76628D03120A4\n      FC364BAF07636E95C78ABCB6B731406D595A42DD001A0BBC3CAB69F379E57EE2\n      C58F5D0DBBE3479BFFE317FFC80C19EE6FDEDE198CEE37A7FFE9A307B7B63A2E\n      E16D213D25D0269E289744EB7E65AE5999B69DA9493EA74CD3E3401F50CD2B96\n      52A30E6C006F0F65A78C40C13E58676086800E9D2E2757F7B74DCB3DCDAACD84\n      0D4DA6CA368480284C26008EB80889E90AB26F00CE669B44C469829784BE7BEF\n      6037A0260833A1C842AD56AF973B7B5BA717169B39F593409262A6D068692836\n      B0630F290AA3144FB5E81BC55722544E2201085943C6427E6DC90133BD5C4F0C\n      4B2D6F2F5177061D9E64254DE165A405421694A32A2FFC5EA972669EF1EBE7CB\n      CD29CECA52DA28CD6F6CB47F06E48A32AF8AE85827287697632DCE42C799EC41\n      5594B0F986F57422389D52B29C11D7B260D359B9AE72896364997ABB2276987E\n      F3A07DAD37E816CEA28E119AA050D89A4D7F6EE5F473995589C2AF65D1DEDED6\n      D1F9E929C29FDB99FCEC99E7AFB6BCBF7BFD7BCF4EB766C7C93FDBDAB85B72FD\n      30859493A070F8A18517A3B8D10C45175D60CFC5E829C139889460CBDB6999FE\n      DCC58B6194FEB37BF77693EC2F2D9CF9AFA66793D1FDE18CB8BDDB99B1CAEBB5\n      EAACECA5DE4C586A1157DA2854AF03007D8C9571A43CEC7934B76B1E2B0319C6\n      DA1390BE28B3E04840FE63704430072268CB8C9302343413B4E780E79439612C\n      6295583C1278B5EC8E73C8A3BAEADF8E47EFEF6E66991CCC909FF885CFAF7F6C\n      F9F10FBFA33CFFD8D167FAD76E964EB5E4EAC2E8FDBBC3ED83F9574E1B97A151\n      067656170214796EE158943EAC9C106CAF2EDC42208FEC47DBF71F2F7EF4780C\n      419A2DBBEC084600E0F014F703DECDE3859897853B227A2F37FB3855AD1A9D07\n      BBC3F1E0E8A57383D7DF1BF7F5E2479EC9EA23F411CD1BE65EFEF0DD9BB593F5\n      D6A74F64B024406D730A7930457F422DB011C646DD60BCDF2D0861AE9F6ABC1F\n      CAE5E2E0963EAC8892A70A5145723C1CE2435336A527513A00B09D03E14531DB\n      AEFBE4BBF7E9CC91E59FFF5C508F3C62992C4EC8481E048F7FED7B53A955BD30\n      9FD9038217629E6679E08C5C5A17B72B8FDED828AD59AD67EB14B6150461A163\n      15095A8C851755DB621A12BF7D21BAA48B6EA3436345BCAA175933BB9BEEEFEC\n      2D3DB3485B766F7F67329C2C2FAF0000546E0000327E379F63A7C2E71F90ACE8\n      8E83E38E9AF84E5C3AFEF22F7E93A65F3B665C27CC92D1E460F6C4540227625C\n      1A3C6AD79724AF43D4AE86BB51D4EF565E9971CA2ED26780A81E091B8654E0F8\n      3704AD638D9DA5513CE251EC8BB5FDCB3707971F1C2B2DF644CF7FA6C527CEE4\n      F2B8B2ECD00B4001133B2A73EE25A864C8645EF873A3AD022F9AF898F6DD4C00\n      C2B45DAF620F92D1DDBDDEE5073DA3E79F3BD53C56D65E081B421A5B66852035\n      3719A0B4C2AFD05624B7FD5CDA1095541A430C7723153DDC1FF646B3E74FEB86\n      9765231B1E65E666DE814C6C6CB76E8411EB55DE71767F6DDF5F756B7F6CC690\n      1149E06BC639ABBA23204443ED45CE5675FF5FED88D30BB53FB39E39DA0E2AB9\n      9423803DDC0682058F2C131A6D0A6F0DB7FEC9F7CD84CE3E7F340B3748A7ED9D\n      5A31CF2CB3699B784DC23D14C4A0C80851FB03767C9EA97840B391C8F2D1FDC1\n      F6ADC1A92FFF113357D259D1224C0E4596292974AA9FAA5216FE7E597797BFFB\n      7B72146EE5E3A91FFB9C200B5BBF7EEFCD7FF97637028663CE79A50BD556A412\n      5D73991A8B98C85CE0BC361C7648E29228CF8912E353CF2BAE0A201868C76496\n      B413EE025676ECA0E6AA49D84CD000720291D2183744F9F2A4C87680D20A4698\n      9BC30BC2C27209E96021B15668A9A490365461E5849B37CB45AAB15D2D83004E\n      079005212C193A32F950670726DFB4E9ADF1683FCA4CB9767B7F2FC4928C412F\n      66C9528482793533A78D3CF9FCF36F3CB8F195E9F5BF76F165D97BF0FDF4F16F\n      DC7F38A1F57640DEEFEF7684B66989A71A2DCD913DC7F0AC4BC4AC57CBE72B53\n      CBC27293C9AC51AB8E373FC4B1B3093703A133419D9C3A38DF9F69C74E01E302\n      0A71AC83286C67C3B3BC0E29211474EC3194624BF338C6CAC384D3BD2C4A2D11\n      8DC6772B5E0DF807D005413B323FC892611CF7C3D86F362683E19CED2D57AAD9\n      683CE3730BD629C65E49CBE0303E10F0421F821FC61486EC148589E0054485CB\n      A8C42E0D03C1F7C0627D0EBC906EEDF77B79DEC6BE0E2A0A2D1F735896860875\n      3877A4B305C53E3B3B7F8C595E1C799CBBDC6239B1F01A9F15FA4424173C841D\n      86FA2D026B4A1952910D2B19E82404D02358C9F005251613EE131E61533FAD11\n      4B083964EA0742BFBEBBF1849A9EA27D88CCB66BE2C826B947CCCBD3B59F995D\n      AFEF1C346CF6E75DEBC9FDDB539295AAFE579CD99F76172F4BF5F73BD72F2DCC\n      D61E777FB5BFFFC0B74AB182638BE39885B771C6E8532AF2B458882536F394EF\n      4A2248C3CDCF55A71E1E048F4C30EFF0BF3773E653ACF6A63DF8D7C123D91DFD\n      B76BC74F47906980FF941E6791DB70CB3EB04B2B63A2446CCF90894C070EF5B4\n      5B8BADD40949865A8548698C46729C637D117682AD2890F514D81F65A94CA32C\n      074A62E12B4C980F1165D2C89835C131F44892C0C9C741FFAD09DDEB1C2CCED5\n      BEF0B35F882A9D49395D5B3F7F70F34EE3C28AB0F283EF5F29976AF2A513DA46\n      84C8CDA18D33E6423C2FE4D043EBB0CE08F8082FE57B373746C3D1EA474F1651\n      65C5626BE8ECC563143D3368FA8EE49F9613D54DB337CAC901CD4A4A4E75B6F6\n      BB1F7C70E653CFA524DB7CE3F154E2575E5E1CF93BD644885A25B997B4DFB83F\n      7561DAFEF8344B8D0801C0A4B11F33B4B671E9A1E16951DD290C378B2751D043\n      7A98110F7D0E8A426E91009F5A70E39F5365821836ECE4A0AB83C481E0CB28EB\n      961FBD7AD35E3F39FF275F09CA8983F24D61A646F249F8E4DFBCB3D4A859C74A\n      B98C2002D208A5D346A2E7645579D9E93F18555E288B239AC6F0393215A14A43\n      F41E285CF70E05267561878D521D464909481981601AA5D23862D7ED5E1990A6\n      2A3FE758DCEBDDEA318FD5966B582B14A43FE88DAE47ABB32F4C8E5CA30ABDE2\n      809248BC77F722FFD8C7211106FFF5BACB4ABDCE015FA27A8A38A11FDFCC6499\n      A96363CFE2D6C3CA70B7EF3D6B9313B605713191DACFE36666A61CDBAD621792\n      E3E6B196DACB46236A25C31F3C39F8E1C1F2FCF1406F93169BF256BB1F1CB052\n      52FFB81FC8BE93F8DC548D04ECEAE4C074502FA350DC93E87242CA65CE6C97D5\n      0940D3079DC193763C18545A6EF5997374D119D30DC9533B2F0361C4EB15AC67\n      14235A3C071E29ED063E18C98659EC12E10C75FFDAED34CF1A67D668C3572A95\n      1A35EA8929296B53688F26CDB01CE46624BFA3F67FB73FF3F139EB93321F8E85\n      71323B4874A914F13CEFC349A537AD87BFBDB7F653CF275F70614DDD64D100E3\n      F4E1C38017B384C49665DB1DA7F72BEFC63F7838736121596051A7CD7B41EDD2\n      51F29145330D11AF45092442882BFCB0C880164B4427A336CB8752586A27D9B8\n      3938FAE9CF9AA992C9152A9000CCC784C88B40C70BAF5774EAC568D9DB6397BF\n      4927E14610AC7CE2C79FBCD77FE3577E30D844E9B39353A58F48A7494420E9BE\n      CB01E603F2118CA93C8568E860E3289DD86CA4D312737DC50B292267040904B2\n      7AA23D626FC6E3CD6474A631D78C490C5BDA42E1A21230439E6545D70B1AEC1D\n      FE2C3A64CCA1AF42F19317A2D03C2F7C66F10EB1F8FB143D78B18296D1203143\n      4D23610F8104A769DF97B7D25147E911E5EF76DA51C94FC6313C4CC83AC875D0\n      B7016FCCAC44B784EB2FB4D283FDBFFFD2177FAC5ABDD1BE728B46BDA8F6FD2B\n      8FAF65831DA632889779D1B486537694B9F468B3BC4E1D7DD0654CAFB59AE7A4\n      3B370ED006D675F08253086371F42F09949D6A60BC5149A616BC49D4E6618C05\n      463514E711BC73923AF0D4B0C32C203A3058B2E9E7699FE927DD839B25FB4263\n      B1B43B0484185AA42F7447E7FB0056CADEC3FB5B1F595FE7411C4E26ABADB289\n      82AAED382A67515CE216451D201B1FF0A1FA5521AB069938A426E10A16C14A73\n      087D63482AC26CE46A9CA94E6714E83CA44C216A84A099D50CAB97CB90D7C7E1\n      C4A86CDE774EFAEE51C15BB9F255EE419403CC5B5CB633E0125C2AC71D0A33E4\n      24B1D8380907C301AC80056C360E2BC20686C025F76CA72C50E4054783801125\n      865AD6B86CFF707F6BA33DCE5A8D51D9BBB1BD1B27381A891E2F4A3DE3583F7D\n      ECD4729A7B79E6E9EC2F6AB5F564E3E4D27465A5B9B235F8CFACB59D28F9B5F1\n      83D5D32BBDEB8F7E6F34DA949603680918B9219642188C553059845A5554BEE8\n      87161C14601C0ECA469A9449354DED840D2EB6D2BF7CE6B9ADBB9D5F9F0C1F8C\n      FA7FE5F4B1AF44A449EDAB73CDB7B6EFBA6EF4A9E5C546128B92A55CC8879EA4\n      76C699B161F7E3A55FE2E1FD1CC60D788746C3E1C2C1FC58BB0665F052D73E20\n      E95E3C7EBF3308BB31B36A0183959E9C6B965E9AAEF9E14803107724AA1E8C46\n      0DD7FE60ACAE0E7AE1283F3BB5404F598B5F3DBF707CAE7FEDC6D473C7A264B4\n      FBCDCB478F9C0A3EB684DDEC38F97F885E0A190A733843AF8B24836F19088E08\n      CDEEF587C49273E71712ECF93B6AF3159A9AC344585CC0EB2247958D9964EA2D\n      2BDA21DA4D7923DA998CAEDE5AB9B068D64AE94678F0DDFBCE8CDBFAD88AD269\n      6A02CF9F8E3FE8EDBE776BE12347AC6797C32C16394402A561A7499FC61C086B\n      91A19FFE2848D721F3A387AD70E469E2FB501DE3E9C751282A8F22E0EC497F94\n      0D0307423A2CE97EF5EE77AF59C78FADFEEC27A332606F6ED4C84443713BDAFC\n      EDABCB47A7E9A2022298031085B0946721A4F27189BC9527E3D4F9A8934D454E\n      0CF9D4896562D2107608B6371C0E4D98427D1E3804C06A5BA824B385934D3287\n      3B2C12D1FBC9706BCC4FE5DE45E14E2AC18DD499B3F88AD1211171696F73230F\n      CCC2EAE9A0FA10A7D4B1A18F5998D9DDC85FC74438FE9BA7D5760C54B474DCD7\n      9619DC1DB9B9535AB343ABCFFA426D1967B542CFA30121304A61D9BA4C75CB92\n      E52A31566EA1FD05A404D2212C1183F6D6E6EB974F342E72DA78A4AF2DADCF06\n      6FC1F9F7D28B83687A52CE9A12721804030BFB06B44D525B62893EA38E7049A9\n      92C0E91EABE0DEBE7ED435A3B8BEB4E43F738236F254F73213D95C08E6992803\n      D8017009A53A31601A266DC3ED1C1646983407B867ACCC1A5CDF9CF486732F9D\n      150D1AA880A5B9D41C50221061C33608B5685A8B5D4D8328F89D83E86E3CFF85\n      35733C316378276EEE41D8711CC48A015556E7B5CEC14676EABFFC91E8C898A6\n      DCD173D85FE14424A1C436693629E78EFA467BEB57AE2CCE55F9593271827813\n      9027ABBE72D43C3FA54A10A96629E05154C728802EDA677148142ADC376A206D\n      69066CEF61327FF1395277745167C76EAAC30E19BCA8D4456D9461B91176DEB0\n      9DBFF33B6AA843559A64F5EF7CFDCA7023B26276F6C8E27ADDAB8481AB0D0030\n      749D95558E713B857D23B9E568D4F132BE852F5DE912F7B8550E614BDA56064C\n      59F044654FA2DEF5FB373EB17274C5A9C55CF484844468AB04599CB10B4F0994\n      C340894A8332C145A7F553EB0956643E1BCB14980951730DD26502F410A571C6\n      61121036A172CCC420078848F6AAF28DE1EE5E3768CDCCBE7BB07BA0215BB252\n      01D6035174A81955784D6215CE92E633BEFF3F7FF6C7AA2278B77BEBE6ADEDB8\n      5B7FD738BFC737529DCD666202C81EBEBF2CA35C649EAD50F95CA9313FD78AF3\n      B495AAD3315D9072928CD259AB9161868395703CCFD1DC8E14DAA7146D2C1624\n      7C95C1A768D7E67971FF20393E05051188878C8C549660DDC0EC58F9B5D1DE0F\n      083DD39A5D18668BA9F6251F5B64C364DB460FB40E32E3974A9DFD6EA55CF2B3\n      B4E5B90DDBB693C403F299E736821A1C622E3AF2F07A80E83CC12CC83001C21E\n      C8B0F3ACEF3BEF0D0EEEC69350E3E8290E54738EB6C044365474D6692C4F3521\n      4A8CC2106586B5024246550C8F12C087C98D745D4F383E6CFB4C4FC270902640\n      65B46F474475FB5D78630B535325D75DA56E2B846400BC38438F3C69EED9C183\n      B8B7CA2BEBB2B99944D758D416CA8F4B83497C7F3CD9CA6053A1455E2889ABF5\n      9F6CCCFE64636914F7C6B69AD1EC6F64EACE93CD6987F9929CD5E2674FBEB4F1\n      64F707D96EEBFCF1372F5FBB11267D6A03F5E545831084D9A719B008C5564135\n      9243132F7DD843423C8F6769EEAA724EFC80F44E56D20BB39537B7C71BA9F931\n      BBF5D7A7D766887ADF36FF70BC17B6F7FEF4D9F93F5A6F55D3085860E6DA9655\n      91BC82369C00072DBC2417581B818789739C3CD3164234954B8BD42B8FC7C33B\n      EDDDDDFE804BB1559A6908AFD69C3AC8A278347CDEAA7EBC524FC3F6DDF1C371\n      3258AAD49B5629D77AAA9BBECD27F70FC246C7ED39D1CA9FB9F8D9AFBE143FBE\n      EA5C5C3A18F627DF7BBC76F662FF2C7C7B48C354E28CCCA17C7A61DD59EC71AC\n      B214BDD5B92062906C7C70BFBC345B5FAD872AE6EE718B3E4D84682B84D78339\n      BABC190FCD19B3CB71F20865FAF212DB373B571FAE5C5C2673E87732B93FBEF9\n      BD2BCF3F77911C71494E3BD9BEE778EC36E9BC7EB7F5D963E4D92AA7C0F1F13E\n      1AAB42D227FC69DAFB834488A9B9B88FC15B0FF30759907D98139F5E6D229E88\n      139E997C1444DD21B06A4C849BEEDDB7EFF8E74F2EFC898F4DAC58A00DFA848F\n      87E91B9D8337B7165F5854D52ED7B043130B9872AA946F99368BDE1A7A55973F\n      2FC7F6A894B81C18991D03321519B265546147C88422E59AA99428345284B54C\n      08F6C113A777A7AD6F43784EFCE7855C62D6B6AF1F337BDD0BEAF0A52DB737B5\n      777FB33CEF7A736E442745D2A7B8F700803037F28EBDFC8BDFA23BFFFD4AD68D\n      E6661AD2B727ED711A25628EB80D21D37AE7836DB1204A97EAA9AF7942439DB8\n      D335A751CD60E17C47D8B64E391752C5FD6C34E05DB9F18DFB0BCB70FA5ABB37\n      F79B47D7DAFD2D279F4C9D99C99B09BC21875620781BDF66A8A882C228592E0C\n      2FD94E0350371DA89DF76FF7BB3D7BA6347B76D55F9F860C391E8C80614837B4\n      CB5E4ECA3AF105BE8309F62AA1131B0A5111EE181C54A7611ED038F479B9F3CE\n      8D49AA973E7251D4C524EE3A2ECBD354328766C0C61D08EFB806B94B652DDFCD\n      DBBF75D5036EFBE9055589646E1354048A586A698AEA5B74DFBBF51FAED48FAF\n      CE7EF9029A4D8B4A9E4B06FBD1A4D85BEA137B34C93ED8DFF9D59BD51DABB220\n      C8053201F2F040B996677F7E397D0E0E6166D30594EBC3F633BC0FA0C55035CE\n      14C40779DAB52D4992526F8F36568ED38A85C37998010B16689E1AB5E2EC0E36\n      A1605E24FD1D72F9F7C8A87EEF72FB7B5737B67783D9DC7F6E66A95E2E45F0C2\n      28A43BC033D476249BC465B4F21EA3F62E60B598DA104705D73C67C02A989D0A\n      2F61523234107AD2DEEDD0B4756429EF755AC1A8658B945B1173D1F8238F7316\n      50EDA1960396277401050F7B97C91F6441530845C914DE98292821D528EDAC95\n      82AC00D44A845CB67335C84940C97E6ABABEBC110FAE6CED4DD76A434277E231\n      2CAAA3B19D3882EC5F2442DCA9C2CF20E2E4E12FAE2CFCCC4B97443ECE06A36B\n      0F27FFF8FEC6EB4C47226D09B240AC014D870119A2338F05240000013CE55AC5\n      7A7166E97C68AFE60041235EB39A79D22436537A331DED8A5454FC962C4DE7B2\n      344C911D721AB23C764860714B17330F9099326592CC62229772886AF180B6D8\n      814D9E64A35FE974EAAEF3D2DCFCDA3899C9607349F8FB2EA1FD486BB774BB77\n      70BFDBB55CBE506A345CDF49E206232D2664147985A23C5AAAB1C243411F3A30\n      C19B474770C031A4E40F18BBD9EF4316DC48E2A468CF6585349E527995B20BD5\n      FAE952C905866A005A5BD8F6081CCE176315A13F13C45E0DE93E1EF606491878\n      8C351CA761B97561958969385ED57320D7C3B74ED3B88B750F3451024CD0182B\n      57D0276CB2958F679DFAB4F1132EEF92A44DF47BC37EEFA01F70D107969DA932\n      E501C98E38EC6B8DB5E7B5B7CB277BAE5A35CE5FCEC2FB4FB69FABD48E3BF242\n      6DEAF4F4FAEFBFFBF66E396D1E3FF2F5F7AE3E4A59006FC144688C880CBEF0E4\n      282A6F784352845B7437453B26E214934380458082C112454820F30AC72EA191\n      C36590FFA5B5135F741A6F05837FD27EB891A7FF7973EA97E69666832068F171\n      DD94745E4F99F0AAA95F8B09CEFD0A475787DEC8CA436994324EA4AC8450C7D9\n      75D877B7EEFDE0C9A3B5A5231F3F726E9695978E2E03FF2779341A766B76DD05\n      8430C08BEF87BD8D1F6C5E7BD2D99E6A4E9D3C7AF2D95E9096F34783C9E35DB3\n      9FE5AD15EBA5CF2E352F96EC8FAD6CDF7A98DF0D973FF9526776CF210E8A162A\n      54633A34D1C04E558D33F278EB05479E011460726FBC7967A375EAA8D3125196\n      4AFF04D34B5CE11D618A8910DB830996056D48EB84DE49837B285C44B81CB9B7\n      BE75F5D4C553F9BA1EA7FB156761F4CED6CEF5074B1F3D575E6CE4A6C3E13B85\n      F6F0D6F0C9ADDBA77FE41C5BAFA58176806603B4F31392FB8766DAC58FA23C7D\n      38565830C24357B0E2C9F00F0961D15D5AFC3F4F1240DA3448E2FD3E9C7D01CC\n      64C37FF0EE7DFFC2FAEC4F7F34E421AA61B2A138E8F57E6B237B90CC7C7A39F0\n      B79C4402FEC0517122009E440FB2E8EE60EA583D3F89C3207E5E2144243C96A8\n      7591A34DB8A6020DC4F07E152D48188EFD4B6A9990DABC36DAE8761FF41B7173\n      52194C5DAA31874DEEC676E2BB6B56D7DE29D19A78E00F1F0DEACFD507FE8E97\n      96716E0DE13B002F78004569F4CF7F8BDEFDD9C6F47CB9DA2887BB936490BB73\n      2E5DC8935192DE57A55AC5B924C26602B1817145CBB6A854855D32965025AD2D\n      4A426E2B97A991EE1F3CFAEEED7A67BE7176A1B37B05A89BABD6BA3B4FA63F46\n      74331070FC2108BBB16140213D2323830E83656ABC7C904FBAE36E679277A3F9\n      72C35F9E261766F5ACD953ED3C0B6A392F0F71AD72478C6C27D3B29431178BF8\n      496E01AC7171280BEBDAC03AD0BD9EC77AEBCDCB2A568B972E88F97A100D6C2C\n      442ABC864624614251F1902A07B01F45BE985DC9B65E7B6FEE7CC379763A873C\n      696C9545C6D656CA6377C44DD5BAE65F7DF5F2A9AF9C17E7A68DB298DB189BC0\n      05E01A69143764B175BB7DF01F3EC8EFA6555DF217ADC96C622067DF0B7CD7E5\n      5F5C0C2E9504B0CBC344480AD1774455C20095861714EFC771DBB605E733C1D0\n      732A53C22BEA8BD85C5ADCC715AE75820B54E0823F4820D14AB57782D7DFE95E\n      EDBEF5FAFDFB83940B6785B8EB6E75B3D7DE33A974BD1AB54B9EDB9FF4EB2A39\n      BDB8522F7900BD52AA81E396F2A2CAE7DBA12D8208C001FCCB0A7A9B4E9227C1\n      E4DFDFFC60EDE8B1CF2CAC3682036DC6486115403399B19800234C0F4B79C5F5\n      012A2CE745EF16BA2BA0F251714D68701E0B1F86423D6134844C1334249A10C8\n      58B2CF48273707F05C09B9DC398090EA4D4FBD75FF1E4446DB7682242D2802B3\n      8A615E78C6B0F7AB06C83C0B3DF16C12FDFD67CE9F3D31BFB7DFEEDDDC3D68AD\n      FC63AEBF7BFFFDF530FB52AB79E6F8C96B7B0FBF7E6FE77ED1C381754C896EA7\n      9E25CE4CF47953599B9EAA7BAE95A4E78249CBC6E2DF9EC8F63C3D4461ABAC4C\n      042C5A8B591E009C3820820696B0332D52BCBACB8A9B1C9B0B38B87D6D02F80C\n      450246C624FB5F7AFD7E307A7E69EA2463470CA9A2EB2FC9A51B196B274A1FE6\n      F19D647277309A6FB51CA5A61D67D5F7BC20F073E511834EA987D78478678C18\n      C729ECE7336380DF6DB2FCC664F87018F45136CA433B4102FF653E2555424E57\n      4BC7661A9ED6699C42DE1B336B1F92251A74922418F14457EDB22FBD1A47D903\n      C715CD92DF94B29E9396E135CD2C65D224810C1A19D50DC68F44DEA631E49B55\n      5939AEDC29065009F2ABA2960DBC36E0F25EAF7FEF60EFE61C76033C6C1FC4B0\n      1C129BE51B89FED2D4F417DDA959039C241C3BCC89D25F18EEE9917AA531BF9A\n      4CD69ACDE9E9A3EFBE7F9936A85998FD37D76FEFE78E1240C7635DB8A90803E8\n      BEF057CC89F8F09E501D564701A9A1D98C1551C3018643AA40C32A408DC68307\n      4574CB319F599C0DF6FAAF767A0387AF19F677D79E7929E73B267C9DF74333FA\n      E242EB58AA985F0EA6A653A0E359E8E5B11B9523874EA4899204D886C71D2DED\n      EFDCBEF6C1F0E0B94F7FF6E8C23167A8F2F668CE4AF646EDCEC1C672ADE908F7\n      6E67D23C7AD2E4F6CCCC7CECB23BED271BF71E64DB9D959A39DB842F2D5FDF1A\n      6D0EB3659B96E478F5274E1EFBF94F0EEEDF1C6F0F963EFFC951AB2F52E6607D\n      B6B847C0B6547A18CA81DCA14F8B46A3800C76C3A36EAF3DAA9F39463C5495E5\n      DE3A37FF914408D190C92CE50FE5E01184E0CCD77464EDFFF6ED85D523E933D6\n      8075EB5149B2A987AFBFEBEC9AF2F333A5B91A894699935AD21FBED5EEDDDF6E\n      BDB8527EEE042A874B2074DB5CCF222863E8F0F3B47BF40FB3207D3ABD873F24\n      F9839C7878C909BF85381042B84C92EE00C2880DCCED71E5EE1B57EDB32B2B7F\n      E26311EA4572A13B72A3BDFBAFEF95E266E913CD5179CB0B25BC2F25B4101EE9\n      58C18D408DE3FAF9B29E89229D70532EACC853469FBADB7034C390C06372AD08\n      7A5516CAC68A59DA4F3BE9E6EDED9633CF941CD676178F2FE513D1BEB3596955\n      9DA698F051D9AE04573231B0BD4BF6967F77763C8F85D9A29085588C3961F9D8\n      CB5FFB36EDFDE9B5FAB152120FC7EDC49B6E65B54408113E89B358CDBF389B37\n      86B14A8C2ECB06B59B35653BA818237D588A8915A54EEC00FF789C8F5F7DA2F6\n      E3D6FA521202BDDCF41C13DFCFA69656E5BACAEA3DA0DFD29451CCCAB50A581B\n      8874266C8B60AF9DF7C78A687BA6D53C32A316CA71554A15F06482EA0579866A\n      1B02E2B44F99453900AA18151179891A17F20376F7C37F409F7305C70AA26CEF\n      FAA3384E162E9D11754BC563E6BA45A7160AAE196C51549135ED4409758619CB\n      ECDE62F06AD8797867E10BF3621ECEA217A1597896675139A6417348F53479D5\n      DEBEF160FDAB2BE668D58433DA2A054ECFA2CA898050BA241EB6FFFD3BEED571\n      DEC9806895979B7185A972257CB85FAF48F923CBD1F9B2C962972E1A94823787\n      8EE2A818AC65515A1C25F10EA438C759CCCD3C632E6AE1A21D2F2442D827A8E5\n      C9F1F8E4B6B09238DD7EB2B97DFBF6E05E7FF2DAE0DAA327C0B229C04C424AAE\n      14406685A971B1665566A54F5DB931EC0CC693D5A945C776377B7B8D927DCCF1\n      6AD8F0567E371E7F6F73636E6AF6B3272E3413FA647237DD1A0CFCEAEFF4F655\n      48FEECB9176AC15EE68C25822507C2512462CA027815BCD8FF454144E9A72D70\n      A85F88B7D7586AC8D1AA574B6C3F48706A107E46A90A729D48D9A7BA2F29A4DB\n      87A391DFA8BF3101F21F9C995B7DBFBBB38DD782542A6C4D2BEAADC62ADA8460\n      257C83927DB0D89FF7FC7FBA7E6EA95AB95DCAFFDE1B6FBDDF8EBAA2C2F2F0AB\n      C7A6BEACDDB5C47FBF6CFEC6D6AD7792D44B3C91EBA1CC154D3ED268CC116B37\n      1D088BBFECCD5D0C5DE9F4E6A85F5104F69383D0CAEC27C1A6A536DC3423F99A\n      71CE44723E30996D17AC57651609449E1643BB19E7E83E0FC728258126A130BF\n      AAC5EEEEE359A94F4CFBEBB6B5AA582D05B62947D46E2BB2CDC91D997E67FF49\n      949029D73FD2A8CE0B594B93729EB9D83ECA04432D793CD2007819247062C3B2\n      51BACDCD0FCDE4FD68D20D144B794954462A46A3479ECF38EE71CF39EB8A4418\n      C87C41A4DA63BD13EB9D3C1325DEA0FA2823EBDC59F11A8EA2AB9C5B9C95B8B0\n      512208F0633E81A740C981C90F543EE262A0D4FE783CEB668BC65DE07E8B3A33\n      8035E1D4B96C120318B01E67E91B69BF47F902AF3FB6C53B3B8F801343480A45\n      0AF0F46C6E7D6DFAF81203B281B766F0EF373A7B7F75DC33C659CFE82587CCAF\n      2C38336B5BBFFFF6A546E356D3FA3F3636E2CCADEA6862C36A0B96D2C36BE7A2\n      63F4C3DA1B0E463254E32380A9B047121E84C0AD8189D0147CCAC2295BE5399C\n      733D01EA64A86D89CFF8DECFCF9D20E3C9AB61FF8D4EFB33CB4B3FB5E01F6313\n      0B30B453335E058EA6934623C7A385473446422CBE002AE5411073AB5C995F7C\n      34181E30FDF537BED79A3932A1F97B376E2C2F2EB62AE5BB0FEE3973D541AE4E\n      AF9E3AEEB65E9939BA4064B2B7FF8DCEEB79B471BA516BB0D94707E3FB071B4D\n      DB9B9DAB5EF8F997C6B5DD348BD73EF64A5C81F781D751B8B935D259D4B72D78\n      2D0AAD61C51B1DA71404869BDB2A61DEA95525820412A173CC966B34C6D2E861\n      22B4B0559B2A6233587FF2840F36341F2565257BF9E01B0F5BEB27D28B254000\n      A521900488CE49F4EF76B34A3AFDD2115587CCDA730884DE72F78D9D7E37997B\n      F9987BD6C9CD5844B9E2FEA1263C5A401785DBA2505ADCC51CDE1D1E36EC5179\n      D82A73D8315358AFE174631EC63CD5796FA8FB63093BFAA17FE78D6BCE99A595\n      9F791913A1E096DEE70F76767FF5DE54E524BF4407F54D7F685B390FED8C72D7\n      D97482EB136A13FF826DDC014024453CD86368070531854326D042331B1321C1\n      A4206027A8C3597C1E5B0FDF7FE2297F76F1CCD693DBCE49D2AA2CE4BBA2DD79\n      503EE2A33C0B6A22ABC1D560C63FC5E7075B530F163A8B383583B93DC7EA2A24\n      C2D23A26C2C9DF39E113166CF6730B0E6B5903D87F48C334122F657A792CFA9E\n      0D046DC64E67E02538A5E692C64E039587FB7999A45AFB7B0E3C83F1C660E999\n      C5B07C40DF172273F7FA7BF6BCD378BE11F8079604FC5BA27989508CD69C55C8\n      66B6B3B531268155F55A8B00581ADA1799D4C63629DE8EE64E6E9E4ED1A16C0C\n      1C62B439828D021B01CB39396C1A1710241A722611ECEECCB7BCBBD9C6CD1BDC\n      B2962F9E2255A1754434F604E768E329C8A186126C25B76CF749E6662399B436\n      AAC1AF3F8C1BC4FBF20CE5133B10916B67327723656524A919A1BCFD6F6C6723\n      B5FCC72F25D384E91A44086341428F5986CA5DE4EB573B3F7C349D97C69DB15D\n      96B449555DB86EAD7F7FB73C5BB23E73245B75288A76C227BBF4B0A07058E934\n      1C3D1B1881BD0A3CCAB62B5C56B00DB3F0E0C53DCFE94467C4AD94F3AADE1AED\n      5EB9F5F89DF7AFBCF5C14EA4FB13520AA5CFF9AA5F9B6772CE2F55966628FCD9\n      C686449E01E9B6A5F406834129780CA06998EAEF6CDEBF9127F6CC9223AA7944\n      3676B62DCBFCE4CB174FDB3479F0E07B43D63C3EFFABAFBD7A6C7DF6F3732BE7\n      0252A1D9884790B6DD8C499C04CE5391515409859DA94B09154A870C6D595062\n      0699A11139C3D9AC189E1C1C629E02F0C8D309445BE10F289CB6EC6118248DE9\n      CD71F7EAE3CDD66CB3EB57EE3FDE7298889919A944EBC3F9E243F140EC27C2AA\n      0941DF2055F65510FFE2F2CC5F9C9F230B47372CB7F7E4D1B73FB8FAAF47837A\n      D5F91F16677E247265684F5AE6DFC6EDFFF5417B0FF8A5B6D034BC98929F9A6A\n      2D4D2F3487D1C293DDE7CB3556137363BD64FBCA362151365A2A9BD8913DCFEC\n      07A3209C680B108DF44A8DB21253096B46C68F7211E7C0D64241FBC28C2D3A61\n      6688CE7CD9435AFEBDCEA32D2BBBD89CFA682ECF08CB4E20DD30582C40690769\n      BA27F93B9DDEEFC743517657BCD211CB5EA0AC1CA790386CF4A467C54C3D367B\n      09269C9C26926CD8E6918A7792F840653B69189BE2A36156A766B5565DAB3467\n      996C06A358C551C5BD41CD5B079D7E90AD576BE72C678989BA612DCA66192F29\n      60B0D20806007BACE35196C0FB5582C585912FE1B6E75784857AFD2E0D2AA999\n      CF780B9EB6CDB17DD43095D13DA62F77DAD6D2D241D5796DE75E776B84032746\n      241A302871ECE44789FD738D55875BA18C793C8EABF5AF0F835FDBDF30D5FA47\n      4BF597D3C97CAD99558FBDF5C6373FBDBAF88E33FEBF9E1C64BA544FD291CCD0\n      3A02B9B6FAB005E369774C91080BE720D4E9A3D830A59F4E90FD81ADF1534E72\n      C85DD0A8539409FDDCD2916A4D7CFFD19DCD50AD31FFEFAC9C8417507549E089\n      B16709697CDBD8AE35B0CA7692C2F1439F0CB4394656C68D9DA77C9FE63FD8D9\n      AC375A7BD7EFFD0E1D3E73FC64CBF27B4FB69F3F7D7AD2DD1F45E3914A076194\n      6397823D7BF4C8F233A7CF3CA2F7834737B63F98AB952BA5CAE39DBD6873705C\n      96D78FB7E2D3C4FEE4D2C2A72F4626B01044D978710E101708711A59D403C888\n      3B1D0E248DB001C0B0EEB5C755BF61AD4D293A29462C8FDA729E60AB72561034\n      BC2CC032A1964C28AAF7D97043CB4EEE07BCA7F67E777B66F999ECB99911BD5B\n      33B18865444B624BA6DFBAC66AC4F9D1B5AC0AAC68281C2789E8C13B6DB2912C\n      7EEE05BDA2FBA2E74C64EE401432028EB02C1B48B23AA662924A889B152B2DA3\n      69311F42BEC436077D7865885CF1B0E904A09F0E22368E5467C0618BB55B37BF\n      7FB9727679F18F3D9B5728529930A437B7F7FFCDB5A98553FC3419796D1F5879\n      9EA52E2C46995ECFD2C7315F74E999DC587D915846D5726E311A60A3CBA11221\n      CE0E02AB11944616965B4902E94A37B39B83FD7B5B331F5D4F190BAF75C48BAC\n      2C2BD94D14EEA24795E25159D7838D34EE46CDC5E9BC3A1EF9E372BF648A1A8F\n      4146623011968FBFF4B56FD1E81F9DD48F433DCAE47C89785C7645B237B1CF94\n      B3E393B1ECFBBA6ADB33AC52530B29F51B69EE4B742BEE513F811C23C6A5BDDF\n      BE33BAFEF8D88B673236190F7BD5BB8BC9689CCE67B5F3E5A41AA432F42B4E9E\n      688BD4299D269DF4FECD7B8A648BC7E79CD92AAB79D4938A6768280B98288980\n      F541EC13879373ACA823A2859B950B89932C45CFA566C545371569960274015C\n      AF06E1E6ABD75BAB73A523F3CC56C621A9C2F65CF9E1443AC1BE0B8CB419175E\n      6487324B2D56BB4506BF71D3FDC89CF95445ABA137A459C98D19D6CC09F6CC51\n      2B128FBF7DB735B558F9E49914E222711964018412816D4CAFDD0BFFF9DBD380\n      C30332E907A22CC5ACD075E35995FEED3D6FB16A7DE6680A144003A99A02CCCA\n      D8E106E24533165AAAE116C2390326A4C5398A3BA05B38E5D2B6D2144894CF3B\n      E4B57FF1AD6B6F5CDDDFDA2CC7BA3491C2999F595A9D2FCBC2A6474A0BBB2E60\n      1FA6A8869D2471A20C0588EC97CAF57A0D48414DB83C02969EEEC5F14616B583\n      D037CE51BBB65C2EA726FAEEAD77AA47675FDF519DF6C3C176E70B17D67EFCDC\n      49B2DB2E178E57A6780245B0C1967637D1014E4E185BA1FB48861D1D28EEAE50\n      988A588AF1C4A8D4A419564A0CB1321A6F49BD273C9DD0448D7F7F7F6FD09A9E\n      69563FB876A3E3D9B5F9A5F6EEC13018C3532DDE375ECEFE6140C4DB487C0502\n      AD4BA94AD37F70E9FC575B0B5B2C7BEDC1A3C5D2CCB568F48F1E5E3FDFA8FDB5\n      F2D2723F90D3B52ACFB728F9074FEEFE8B308A60612226591A50E370B692B9E7\n      CACD93F3D58AA7C8607226738EC316D1586E12943809E44449F14E149503DA56\n      D675F2C12082175DA2D6B45B6959251B9E8AC2C9C92457139207CCC47801AAF7\n      12FE9BD1DEDBD1F0F9E6DCA798BFC299A7F3121AC7AB98A5699E4FB87F2752BF\n      3ADAEE27C9B146E564A50169007DF1F2CCE24F6F7F21B970F4189396E13DA9DF\n      CB067B24779D72B73FDC5361E25012AA79C24F54EA4B00E3625DD6A481C2F2D1\n      A0E4BCA6E2EF0FBA00485E999A3B93EAA99C0176F6045243DFE400B77301C995\n      0642452855A98BBA3CB772C25308A838A60254C0E6AA2CE414C440023411B220\n      6F06BC2FE4EB357D5DC76C94DFD9DAD89FF6BA8A8D4743A958C64A9165AAF9F8\n      4FD5BD2F958F10C5E27C68E9E0A05AFFF5947CE7F10365E439C63EABA273ABC7\n      F767D6BFFFCEAB5F3D79F4B618FCEDDBDB2361571312D12CC37E39BC2723FFBF\n      7F703C3C7C8ED89AC4BB1632862F24A5BF3C776CB9246F8F7752939F5C5EE03C\n      941EF16C5BC98640B31485970D0C5BE8116E67BCAFD416C9DB3A1BB67B2F1C3D\n      736DF2D80AD5A9E9793A18D61D57081C7C8AB39C7B5E2FCD36C2F1AD5E7B2318\n      7CF5F49767A75B51D0BB71E3DDF6702FF5F85EBF37C54B47FD9AD2A34BFFE94B\n      AB7FEE93B1D7112A14C6023297A09E5B2AB398A100AD0DD497639B738C8C3D4E\n      B73F783437BF28E7AB391947C417E238E72D8A9F8442F678DA1078021B86770C\n      6FA1CB461B461C182F60C3ECF16F3F593EF252F6C2D240DFACE71D4BBBC00F48\n      5EB6EE0D36DFBC2C979CD98F1F4BACC864B00EE5BC4782F77ABDFBEDB59FFE44\n      BC66B251E0A349E284D9907E3CA16D02215B84091CBFDC13CA6126A534488503\n      ABC00E99603162A1D0B1C2C0F6CB27810C52D51D923094DD99DB6F5EAE5D589B\n      FDF1B3B9070FDAE2134DAEEDECFFE60F6756D7F94931B1BB2EE0409441A14E56\n      8F7FD0CFDAA973B29E1F8774DBB3639764CD0C071203AA27B01F212642504C98\n      549A380061B26EA673CF9A4E3748FFCACEF45C9D9C9F6EDF7AD8086BEC79CA33\n      B3FF666F6A663E5C089813F961EDE0DA4872595FF1622F482C650FD154B9E0BD\n      46A2228D1B558E7FF46BDFA4C3BFB51C6CC7D5A62F6A9445FEF051E82DE7EE79\n      19E190BB476B99F188E59EA4F5B1B17CC37C38E09919E55239AA3279B3BBF59D\n      77D72FCD667E20A3527C9DF56E4FEC453AFDF18AAA8EA8052FC009B2484962C7\n      DEE8668C17E5D35C9CCAFD568B6BCF0860FD46A1090E0706108E8792A2673B0E\n      0B141D759C5B00F894A335840A2D600B6900ADC21020ACD4842ED16EC9BEDD3F\n      F8EE0DB6D6983B77CA788C70D8511386E66548DB0BE99382D623C03410B41D23\n      620806C619FDCE7672FD60FE27CF86472392C6DE58C04307AEE766B4F013D7A6\n      A39FBCF3E0D8A73EC596CBB94DE163C4A98EE1DCE7B11FAB8DD7DE35EFEDAC34\n      E77B0FDB3467A56689CE1255A38E28F56FED788B35EB536BF18C94D461740A72\n      393B1C18C3AC8CD10FA8136712AD3C729C5A65286D2B4D96A125B4272034EBEB\n      076FFD83DFBCF3FAAD9050BBEE2D79E51796CE97C50CFCCB34D9D94AE3BB93C1\n      F57EAF1BA77194E95134E3F86434247998998CBBA632D33AB01B6BCDE9F3CDF9\n      356ACF4A96E9C960B05D2F79BC17F67626D9EA91FFEDC67B0FE72A9D83ADC55D\n      FAF367D74FD76AA872E0531A475E027089A682C76817935BCA544254578D1809\n      3976533A00C900D1983C56394F8D9589549189C9A3DC8C9580189BD0F4BA883E\n      48F325BBEE8EC26F74766E59E4C5B5E3C3870FDF52B128970C7C416C0DD279F1\n      EB87D21687934BC80831136B07364889247FE7D9F35F5DB89492F1BFBBF9E6BF\n      7AB07B0F289FA57EBEB5FC3349CB8A476CD1694E9443BDDF52A3BFF0E4FE4360\n      9AB0AB9000E540B35632BB4558EA27F6BCF3E9E6F2CC589D8CF97C08D908D02A\n      42251BD5E219772DE5C814E584203ACB763CDED041479A04288F84C515954C54\n      722E1549731DE45946D59855DEB5E36FEF3E99A7EE7926174AEEB17AD39F2471\n      16055C092A12E26E49FE9A8EEE6D6DF0541D9B6E4E3B8E97E7AECE1D5D284423\n      2B41897F062F99986D153EB1808EB324806D46E14B0459386579CBAE5F37DCCD\n      50D0C897100A13381F3B16FB66AF737D1CCCF8DE2B33D33349021FB508478D50\n      CBD83C2FA7B62EE633D0C4961DAA32E0183FCEE0A3D90E0A7E09C1EB467986D9\n      E858834DFCFE447B21EBCED65F9DA6BF7EEF5ABC171EAB4E29CEDFCEC3D170E4\n      321A1937B3E8B209FFC2D1A5675525CF79A2461ECF6F53FACB83C94EAF9B32FF\n      9214FF0921CB274FFC56AAF76EDFFEEBEB273B7AF2DF6C3E782BD7AE42BBEDA4\n      D071FEFF9C08595130783AF706395548A685AFC2D03210D37FA1B5F0C5D993DF\n      196FBCBE77EF474BCD9F6ACE4A57850ED05D69B9756263CA072007C41012218F\n      A96397EE06A31FEEEF2CAEAEEA9C6EEEEDBC323FA7D3CC33B4EAB90C1959063B\n      320E23AA80A108E997472ABB7EE7F66B69F2DCC2995796CE7B54BC73F79D9BDD\n      3B0347F582B4215BB3DA5E98E12FFDB9176B5F5A8A2CECEBE61A52B5A2286F96\n      1B9325969511E623E381BFCEA27E7FFBC6A3E593A7658D290660B226E4714E01\n      D224980A709C4E6B9A6982172B5C64C41C6022E40303E87D946EFEEEEDA5132F\n      67CFAD4FB2276ED8B635169FB9F17347843FDC08DEBC5B3936EBBF386F649801\n      CA17AED7D39DDFBF166464ED8B3F428F6AB3D76502DBF8B1431BFB5B0129310B\n      9687449A47E881998B4C70FE6122FC434688480E6271C4210AF527D968607766\n      EFBFF77EF3E2B1FA674E846C441CD71AE5F90F77F77FF7CADCFA51BE6E4DE410\n      659C194AD3585165F0D63E9DD0D2B946B63CA67C64A73E30427405E331876D42\n      B54E00AF96623B2534F48C3D998C99C39DB0B2FF5E07166EF69945A3B2EEB59D\n      4A73CA396D659374EBED8DD5D3A7C695816319BA4FB76FF51BB35395592BA47D\n      08E372EC1476A938C28E5D8FF4C344B8F35F347843D6E6AB2291DD8781049EF6\n      9CEC8BA163AF38E519CC6755C3ED05EC3E000A28053C8C88008B73F8EDB4FBCD\n      AB7E25774F92281FD93BCDE8DBAC3DBDBBF2CC823DE76932C87D03B8CF91F5B4\n      AD7A4F7AB099968ECFEBE59296118A483047C37E449DA943E11EBC3D84A5A6E8\n      E16350BF11F228434F2643335658D54346F87F597BD328CBB2AB3CF04C777E63\n      BC98232322E7A132B3B2C6AC524A3568000909B0C036B06C63830D46D80B5663\n      1BEC05C66EB7DD6E2FDC0683C16EDBED0170DBD818612484542551524935660D\n      AA21E739638E78F1E24DF7DDE94CBDF77D59422C2FAFE5A6A9953F322B2323EE\n      3BF79CBDBF6F9FBDBF8FE2BF51C6A74339889C30BEBEB3FED6CAECD47CEBB143\n      903D0B3DA281C8758A72E1783558D2C072E8057B7DF14A028236BA97F8BBDE9D\n      CF5C0BB83BF31D07E37A87A5D6CF5CE292822960070AC2EC888F6E0F37AE6D1E\n      FEEE8FA755E132E624D8CA3D14D629B4B87277E3D91766C23951D8DD9B1091C2\n      682A62B3844E394CBBDDABDBB5A549FEC1FD498BBAC849A608F3700C808E9B40\n      D11113A01DE71EA4793D3ECB5428D4BA377ED5198E327F20CEFFC2672F7EFA35\n      402DCC634F1C3B7EBC36A572BA29ED8DBDEDBB831B498255C85156445ED4A834\n      E69A130B9313805138518E2012F8A1D12FADF57B8391E201840948B30F1F3F58\n      813DA552C7775EBA7C63D33A973ADDBDC23EF160EBB160EA03C1A4371AE69ED4\n      214B8771DDC23F61900501B5C156E45263B111CBF7164803B0A56AAC8123E665\n      DF0C2D30E70C2D19E0BD36BBEDBB5B2A6F1A7A274BFECBF6C6E2BE85434EF5F9\n      BB77DE24D9C9E9D97945DFE86E77CAEFC6016863F243E9B86F2A909517146828\n      0AAF2C64461D37E9DF3BF7D09393CB8C7BD7ECF0777AEBBF76F18AD9337F7D7E\n      E993D64062C81BD5864EEA997B25727EAE7DF7D36B3B2873CD7856C50DB048A2\n      FB1A2D9EF7F3D1F00CE193CDFA013F3A24D9AC043C640A40318CA03602843A01\n      8B0DAF8ACB4CE6911884628B155B39AA52007A6FB210F6AE63786ED408AF41E5\n      3609F6EACED551574919595A859FE57A4B7E40B5CC9472B89B12B1CBED6A58D9\n      EC766F6FACD4427F6666C2A459437058E9C030BF545E2B2765B822BA63D35D97\n      F5E1A04956F72BC378E80AD6E0BC4250111B088D9028B12881C310F7AA94CF6E\n      6F7489BDBFD93A530D7D99C02BAB58C8D994C1E37ABA95A19E8C0328CC4294A3\n      76AC0F8E2347AC34472C1D7A299D014E4588A4E85755E52EF0FB5DC1DFB5E9CB\n      DDF6D541DA5C9CD3966FAF6E5DD19983DB918D083A69BFBFC27E74E9C0BE1124\n      0940B2B9E798AF4BFD8BEB9B43C8C7470E9EAC04DFBADD9E9B9AF90F3BEDE982\n      FCEFAD7DA237FA4592FDF2CEAD019238405978F90DDBC7DAFF8F39F0BD4488F6\n      CFE85E55FE1E28921110BF955BCC56C977EE5BD8DB4E9FDF6B2F46EE3F5C3CF1\n      E1B800D4DD89A8F03DEB23D6F6197AFA4A8762392667D60D06F5F0DDAD8DB8DD\n      3D3CBD0040A6458673D333324D91B552ACC969AB7018170045668B24751C0FFE\n      FB2A1B5DBBB0D68896970F9C6835A3A6C846BB9B5BBDE1FA301F144567B8D65C\n      92DFF1A98F46DF7ED4850D9D59ECFA3605B602B0340F200E335F3925A922C99D\n      8D9D3B77171E7E40389974B56435871F16B485573CF4BD44C834361569C11D49\n      ED0EE9AF12116389A69FAD7FE5C2C29187F499933991CE7087C94DC501690227\n      D20D199257BBBDB7571A0FCED3137EDFCB0128D24116E4DEF52F5CA8058B931F\n      5DE015E01E79E92DE1D8C0C11B5C59C5BB27DE516E07D29D23A3B261E11B5267\n      980855A9D20D1B98E5394B151926D95EC76F4FDD78F3ADC6E983934F9F4AF81E\n      0F3DD156C5AB1BDD972ECFDC7F982DF1848D7CC03F3827E6EB4DB27D7EBB1ED6\n      C3D355393360247565A86C24891136475539BC7AF124A0563172D8906926B5E7\n      C94A726DD05FEFB51E9AA7D3D4DEEC9BF5DC2EF8E17C35E90C465BC3E9438B99\n      9B00DB886F0FE3BD62EED0020BB2911D59877BB1474A8C4D34641C097034AB1F\n      3B0789B0F72307F841294237BBEDC4E970FEC9DAA839A0BC15D416D023A9E6B3\n      90153CA66CDA81F797B5F3905277CABBEBDDFD8D172AB2DF7AA43132EDB068EC\n      3CBF0BB970F4C1F585934B2475F08EB52E52A5E5B68D6F0E6BB5B0F670ABA8F5\n      320A906D16D21AF321EF0125423F6E6C1CA368E4514264F4B3332E5A5C698E8D\n      C628DBAAE1A90D300D54C742155A2144905F58EF5DBA151C9CAF9D39589ABF4A\n      80C12990450F87069061D1F1CD2E1BBF36BC83E32251A94F22FE4EBCFAEAFAEC\n      7D8BEE23B0601D9639BE0C0083682040BC3AE283DAA032BAB0DBD91BECFBF6A7\n      4735DFB7106E35CA9D08D7D94BDACFBC686FDC9A993B1C6FEE02A22C321DB402\n      6741D8490679B677A3D3383CCF3F7830AB6B144DB453A5086599054929AC85F2\n      E61077BD724C829667D941D12B8242F7BE12E9BBF1333FFDEBEB6BA3BE07B995\n      7CF7E291FAB0B853645F1F75AFEC6EBA756721AC1EAF3567099BE4C2A7F03E0B\n      14AD02E0E07ABA30387603B1CF09FA425CCC928B2A7BE1E6ED666D021E271EF4\n      9BFB67AFECAC17C3E4DB8E9D78A0B9B844FA65B73AE0E30202AECD33D7F3F0D6\n      0EF587C6D381D81BD603AE0CE45561B606AC01BC8117D8AC4BE0E449D6117C47\n      0057606298BF39EDBD34DC3C9EFBD3DEC4BF5EBBBE129033FBF66DB7FB5786BD\n      8AE72C0A6F7D102774CCD5B1220ACCDF94E2F6DF7455841409560A0898B5EC51\n      39FA990F9C796469699078CFBFF3D61D2FFBFDCE607D97FCC8A1C5EFE09D2027\n      4EEB50A5D886089E04955715F9A5B7DFBECC4422003663618648B52882072BF5\n      C37ECDD72347C925D73FE1042D14D9D2CA872FC269B69A15012460075DD63142\n      4BCCCE65191E0F7F397565735D0E6602AA2F8724375C3F4E4603AB3685CA6147\n      16A69EA7879B8D4978C523550811C38651C51EF147946E27BDAE02A0E60209F3\n      940D35A9181E96C62278DC4BB78E8CAA01454708A1A9CD4AAF0C5DA0463AB765\n      1D812BF46AA6D2133B929EEF0EDF887B0DEEBD7F727A994BA213209713A65283\n      A70E9075560B070822FC081C4AC1DE6A52CA929632DFF8070D30D377DC8A32F0\n      A9358A5A9A8AE6B1602F8BF485742F68CC6E6F77D7956A1BD9EB8D868E084AE9\n      47F4B3CED23F33D3FADED6642D8505013A860E8F6F72FE8B2BEBFD6C249BD5A9\n      3CFD76A34E9D3CF16F6FDDBEAFD9FAFBC1E4EC46F6B989C68FDF7C7505A024A4\n      75742B317F644638EEF4FF0346C8B02B9C58178E942F460DC7DD898BC0921F5B\n      3EFE432468AAEC9A1879CDCA1C71B2968A1456A00C36440367824DCE33748362\n      5776B72A41659FF18F88FA76AD6F0BEDD2F222121821407FF8294A931CF5D361\n      D1B23CC39B03415607F93B9D7435A341503D596D9E6D4C855936CC87B7EDF07A\n      7F6390740EB7264FFDC2279BF72FC96C8493E106D2754AB01C01F10CA1C54838\n      211C8037AF0EB261F3A1FBAC19595F4BB48F3AEC8869620B9418B5805C6C69E0\n      2CAC811D945BB343E2BB94A5C4A1742FD93AFFEEECA163FAD86974224FFA26BF\n      9E896D6A81142503F8A0F9A4F7423BBDB956FFC4B1DE82E2C35E15C2AAA2BC1F\n      76BE0C5F99CD7FD7834594FB199C41370724E84622F3714788A1E28392C202B9\n      70EF25C2B10F04125553AA80029C5714126192A7DD4EB03571F3EDB7BCE5997D\n      DFF2681AF45940DD35993EB736B87A67EAB14390B7329D3B40910A0880B5CEDB\n      3B83AB716B61B67ADAB7AD21913955516101F5C1E228ACDCC13B76446A80A56A\n      C74D129B447C815EF3DBEFAC8905123C38013BCFBF95F5EEACF90F4E85EEC4CE\n      AD95A8EA89A900753B477CE3D23A75BDD9C3538AC5D8758DC67EE1580EC0A229\n      37D0102FAD1F39F7579FA1D9CFDCE7D42590819DCD74F9ECBCDDDFEFD17C62F2\n      3EEB56F84460A37A9EC7DAEF397A4EA89839314A9A2533EDCFADE88B37171EF0\n      46F56D57369CABB5DD77768285C0792C371503E7CE77EA7A20061B6977A7BBFF\n      E47E31E3E830371EEAA530486361809AD6C0ED4839DA86E86EEC408BB3555608\n      E2398AA16D24E4A5202F476DE0A9599E09402E4E23AF26E7D7E2F576E3F43EF7\n      505DB2545057969E92CC81AF2D956DA51A33C272321D4B12106A24972663919E\n      D87BF652D291FB3E74D22C254AF548225C1B1020861CE84D2DF6F75A7B95D15B\n      9DA1D6331F79349F68D0425005D8D7B8D6D517B636BFF4B5C90A0958B373772B\n      A24196C9EA5C1D186152293870A35BDDE6F165FEC143595870ED3B640AF731A5\n      DF4884069B8319A67E6CC4E2986930BCE1D18EDDC42BE8C6EFDD7EEE9F7E6973\n      57B68BFEC373931F9C9D5DB97DEB52779B546B0727E7F7870D580CB7483DAB42\n      0189141D9D00D6E3852376A201DEF761312ADA9555310A599FA87E21617B6DF6\n      6027E1CC44DD1575AA9A56C3DEA9ECD8D429763D0910A392A92A2A1C90C405EC\n      C521F7FB789944007A7784F4E1E4403690680B83F3D74A67C06214CB8DD8F69C\n      5BC2AE98E2409F5C9FF69EEDAE84DBC58353FB5F95C3E7F7B6265AD519B7B1B2\n      BD0367C0077C6BB147C2A07A0C8A3D7E23B47D732EC4CA00442BE6014E3A61D2\n      9F7DEAF487168F98CCB9B1B6F1ECA5B79F4D8B75E2FDF9E5D9EFD6BD068A3C4C\n      1D48E30E572C637BD2FF959D8D7FA7FB23CAFC943BA4C850B098449A1CACD6A6\n      172B0FBACD135D75589205D7254C028C81DCE0115B234814726152AA203FB0C2\n      B885757263F1261A5BFD134647948CB8CD084E392BA5B77D9F7763C006D75DBD\n      CE182FF4BCEFCD507D94857E6AFB820F03EBA54941A301306966D7B2FE901A2F\n      0A7596570DC744880385E5A9C4EB009D1A607A2E760EC1CA3BAE91B2E2B9D8B8\n      82E11A5D29540EC999F4855D63C1D7DABDCDA4381C468F46FE34C18772A93BAD\n      2B2DEB515F15BE810DE151011F52A87200D48E35FBCA7694525C2F108E27B88B\n      DDBED8B418617F3CDDB1FA7A4DBC15D2AB2A7FE3F2ED89A8D1A8B75636366EAA\n      02CBA738F1462B52FF8DA5A58F86914E522902971048E1CFA9E29FAF6FD5543E\n      154E9FF4BDA7AB2C9BF0FFC9BB57BFEDC1C37F2D7597568B97E6E77E72EFE22B\n      DDBD8A1185469AF3FFE78EF0DEC4F77BEA97020FBB537E4A5DAA909BFD84FC9D\n      D3670F8FD237D2CD17F3DD4FCC2F7E92B7F6AAA30ABE6F9E8502A9212618D7AF\n      373706FDD7576E3697E78E0593F3315F8B7A0E6140D6007954C248C22BB8A76E\n      82C3414996708FC3F34F6479AE484C834BC3F4CBD7EF7447FAB183CB6767A7F6\n      D1C22BB25C93ABBBF18D4E7AFC874F9DF9E16FC9A6B0A61EC16ACB8245941429\n      9758D0ED7ADC0704FED2BBA4E1BB27978C49B4289481707E8C931662455C2AEC\n      D8340CE5C2C68990E82D9DAE0891E1B56F7BD87EF7F2F47DC7F5E251C566DD42\n      13793921777C7CEF328B684FD19976D0FDE27548E3531F3E6AA394A4314402AE\n      03DB1E6D7CE9323D3A39FFC4710BA495993C535150C7A084296F7C3729A593BB\n      C0A0C91F4A84A5340E9E5BA46E4941B222EB77FDCDDACAC50BBA5E3DF0D17379\n      63A84416ADF1E1E76E0DD6D7E69EDCAF1BA29012CE90A3425EF86BAFDE768615\n      6F2A8CEE77597DC891CE84196A166B17BBA44BB91F262102B9854B9C22F3D2B0\n      3F415FF3B757D6AB1F8E14E4C23DDF5C1FC5C966EDB179B61DEEAEAE37F647AA\n      06CCBFC677CCC6B5B5FAD2A43B2D0C1B31C300B20BED23272ACB235C2BC28251\n      F5F0B9BFFA05DAFD3F161B69ABB7B14B0F0BEF3E88765A34EA2AAA87B5291E4D\n      C0BF8DC948081BA84A0E870DE23AC0A52F5EDD7DF9F6C9C3D3796DD556B5DF59\n      D8F8AFDB7E406B9FA8F0964964CA2B1EC9DCDEF584277CF2EC51D3CA87BAE73A\n      15A11CD787039748E443D1D8EF114DB6C69D2406312FB6CD084E80FC97DDBB00\n      D6B582C8A9D1B7C6053089D756DBCF5F81D0D2387DC8EC0F0C4F848263552244\n      66CA3651948EA5656B2F72EBF2A794F2FEB608B27034CD6ECACB9F7F7EF9FE63\n      FE430BB9D3814C256305CB8C824E942679349CE84E6D86A37780BFEAC90F3F66\n      AB0DC8AA29013668A221CDBF7461F3EB6FCD1F6F7A4963B8BA4D53F4738E662A\n      64CEE816304236B8D56D1D3DC09F3A38F45357791E9B2919E17B1784046D80D0\n      F816FBE705964971060F029DA765EAD4017FD2AFFFA7377EEB9F3C63870E4F86\n      E78ECC3B452FE7DAAD560FD6A75A43D3882D9AC578BC70598AC65A026DA800D4\n      1799C0EAC558F713C866D5B8CAE53A02CE0DDB9439F02C31A417E08DD838979A\n      4877D5707A349D326D7D27C94615CF3759A12129E34D2D053AE3A25838514AB1\n      02071B4BF36A401A44E76AA4F5AEA07B0292A393E6ECDD2CFE7DD9792A9C7126\n      1B97E2EEC59B2B954A8DB526DFBC7B0B3EA68386ECE82283067602B1F537DF08\n      DAFFAE4086ED40A8F3EB145A4E11F90F3E74EAFB668EDB9DF4E2DAC6FA6CEB97\n      6F5C797B6BFBC7970F7E6F9654039A352BCB9DB4D7E4F58CAB1EFF7455FCB5B5\n      8B6DC2BD11A4371AA3E32AA956825AB33E950E267AE953E1E4B74C2FB68ACCCA\n      141285436D8046C544E21D084EF8A11E064E3560C6234AE390037532038C8DA5\n      D4623A24C012CCAE66A1D6B2483604BD5C149BA3E4D8FCF4BE243DC32B15EB75\n      394D59EEE7B124BE14EE1E55DB2AEB9822C72E0D34D5AD50A06BB803B0E988E8\n      0C189980CC5CC0EEF7855FE459846EB9800939064F6B5CE1CA519EC87C3BE237\n      DCE86BEBBBAAB00F45B5FB7DDA727347B02A8B26555833B0B564CE51191E2734\n      50C310AB11E5FE433CE9C06EA1B4E230013F395782B29C9910492AEFBB742312\n      EBC4BEB8B676D1251BA1073F2F28443CEAAF73E64144041CE49013DCF9A9A5C3\n      A7F302F512DC80293DE4E4B369FCEFF7BA07737B74E9F062919F483A6A3AFAF5\n      5B6B9F7CF4C4F70F54733DBBB47CF0D778FBD7DEBA54A0BB2CC3C1893F8E6699\n      7BC5D2125A79449466433CE4F6B156FDF1F9E9AB1B6BAFECF51E3E30FDA970E2\n      ECC640CF06104264C44751E97C0DC91018AD00DAE226DCC6D64C00F2EE664983\n      EA4C42EE0BDCA04853F842FC1102125191C38973580E278191404B9E023FF7B6\n      B4DD12EEAD7EB2D3DB8BFBEDA5807F68E9E01C9B5C4BD997B7BA8D46F74FFCDC\n      0F26EFF78776670A58602A49E8A24C4C5C10C71B38C02F0A73FEA2BF3CC9F6B7\n      2C2D321303300BFC5354D571AE12A1A3832F0FA70F51B99DB382E84D95DD769C\n      046DB836B2CD772F2E3C7646CD2E49358DF55FB39266574239905EC460DB3A79\n      AC0CDF08F7BE7063DFF28C7D6A6EC43AA171549A15CDC07B3B5E79F5E6C243F7\n      07675B5DB5D174439258ED39F0011D05C4C2D78E2E9CC2CB25EEA552F309BBE8\n      C6EE85E5E115902E939CE6328D07C196B771F9462EDC03DF722E6F0D733AA86D\n      45F167EEF477EECC7D6849D57D92E3F09DC8EAACA757DE5C9D8E96FB4E5A3FCD\n      ADDF0B6C08712DE5F8533D8DEE18C00AA54C80A358255247BBBECB2F91C10B7D\n      D5A4C1870315CA5A6F62EF8DF5FAA2470EB1C11B08CC1B2782D42F4235915C1D\n      F6DB7BF3F72FAB30C9640FBDB94855973601A88CA351929E30FF5E2254FFFC48\n      7CC1BA0E0F1E35BDC9A1539971EB4DDBF09CEA24CE507B24E799B424821310FA\n      049EF0ADADBB5F7879796992B54699ED44DE7C7C5EC59792F9C7E6060FED3990\n      6BFC59B34737AF6E724F4C3F7A98B8A3C2C9157319F3E08D0B2C592A045B066D\n      00CABBFB7B763EA5D82B3242D871182AA8287D28794C5288BDA11F41A870467C\n      EFF5EB4596CE9FBBCF4CBA806B04964F0DC36B64F25E7FF558C1AF9C77193B80\n      E3A5286061DEF7F6263796E21737F7B66F2D7DCB493DED4A53EAB140F087D02F\n      30E073D26C4FECCCECD47AAF6CD0C966EDB153D4C38E80D8518615CD3DD3FFEC\n      790B3F7789BBB749B2DDA539D6C9FDA980EFE7AA01C99676AFB4278F1D101F3C\n      36701200323E9F41CB9B524AA304E470548542E31087A1D07AD9200B0BC1DCB4\n      88B9906EE6BCF65B6FFDD6AF7CD1EDB27A3A3A77DF62C093AAE7D5846762D80C\n      004A145AE90ABC6CB7CCC1EF8388011601C0BAC21B373C3CD6BA35ACDE602BAA\n      762D75352E2E044960A939C764592A5B19C1AB00B96005B04709FE8CB727A83E\n      85456B74A5C16DC3203AF4C746F324C98B18A58A693FCBD7EAEEF3C55E104E4C\n      F79C82FAFFB1BFA6E4F050B531516D7EE5CEED35A3208863D226A5C922A03DCC\n      F2657DFB9BBBE6BF49C810201162023C6FC6755C0A4C85E1CDE4CF7FE0D4F7D6\n      E769E63D7BF5CA7FDBBBF3D9449AD0FBD1D9437F512A54E1A8786156EC54C9B4\n      F178C75E999AFAE9BB97BED21D121C408245290265E782EAFEC5038FF6D31D9E\n      06323DE7D51E13515D03D9D2A8FECF2C9A3FBB98F52B7949C1CA435E9A0CA3C2\n      139340A26C618173D298932E3119D13D4D539BC1176505BDC3C52B717BB65E79\n      B860A7881F7A15E53A453EF0489A1391339132DBB7B65DA4E86251C23D8F30F8\n      854AA0381EA733522A6859214CD9B08B8512F80393AA1403773C406A32C9072A\n      BD5521E733F34E7B30C3BD8F4D2F4D177B754F459E1BD9202CE0DB96A9CF48DF\n      7170748D972678088CA8A351672F643C0222881414EFE801952A6E84B2C021FB\n      3EBFE0DBD73ADB9686B599A5AF27FD6757AE671A874CA4E33A68828890F2C3AD\n      DA4FEFBFAFB5B1818512EEC201EBFAEEAFED6E7D7A38088DF6EBD5F9A2F89823\n      E6A69A5FB8B1F6038F3DF8D4762748D9D5C6CCD50AFDCF97DF78A6505AA0BCD6\n      1F5722C4620BBC45A139A418C246E85C234F371AB2282EC5C97E3FFA997D873F\n      98C9A6C9E21AF584F0016B844E16F08C9AC8091CEE9432271C1DDF50A3CF88A0\n      9C7837E3C972818B5706146CEEB3A5AC5269BE077C4C5299E1126287B3A39152\n      BDBBBDFEF6C69653F517E70F1419690FB2B9E1F0237FF33B5B9F3AD1753660EF\n      F93A2C0CBE789EE654331A0672676FE7FCDBF38F9C203311C6063352B2EA4068\n      679304CE0F72799CF033400DA98BFEF6C0C0ED8E2CEE30DA434B953B83BDEB6B\n      F3674F98C96945A71D5321764F1577597E7BC4A20A56187A893FB264A6F226DD\n      7CE1A2F7E864F591299E0D35B5BBA19D4A987A256F5FE9CC3CB1EC9E8D8AAC23\n      18D0660FFD6F310E301A0400FBB81A94DC9B8D27E949D9C53F1EB98773CAB001\n      485159901DBEF6FA8551428E7DC707D399BE66A3CADD20FEBD957EF7CEF407F7\n      B166A887868ACC1935DB17EFF0C28BFC7D7B69BBF98020EEC09581855CE8A33D\n      84ABD13D05A82B364CC2E161348F3CD2E1C957B7E566428FD2FA07A6D1C471D5\n      EE5C6DCFDDBF60A7B3DD17926AE4FB27C448C7513CB1F5CEFAD474532C350AD2\n      D576E402FCD3410187ACF4CD01B28057ED2CCC6AC71EFF2B9FA7F9DF3FB2B33B\n      9801DA31391C4E286761D1AF4D29AE59D5B32480734F044D434D06851F55E44A\n      7CED375FDCEF7AD5A3ACEFAEB9ACEADEAA6FBCB413B4A2C927277727B7ABCAE3\n      7125B91E1BE1358E4FA6AD51EE015605600BD894A3753CF398894AB7C732C472\n      72CFBDBBD4E02C271D58D95759CA8C615D000EA88BB92677AA6965F36BEFD83C\n      9DFFC8E9E1AC4E477B93AC6AFB05F1024E47EF0553FB9E90FD781611FF1F3099\n      52928D0FC351F3DDA9D5CFBD5B3FECD49E984B21D58B90E48595193C9DF180B0\n      7057D5B7A7776756FDC19B6DB6BC2F7AE8388A8A02D5087190D159EFAE7FE6C5\n      C5895A528D9D9B3CDBE97389BD1EDE74E02C71D9443D84D19DB8B16F8E3F7968\n      54B12277BC71B30C7607B071D71E2A54C339629811F11729E75401213B0C7867\n      3472BFF40B9FFDCA7F78A1967BA7E6A7165BDE944F26132D0669E1F34108A107\n      B5E90476FA619A8038C7B1F4859417AF42D93DE74A9CDD0728C8DD0C3634733C\n      6DC35C39067B1E460EC47EE149114A78C02E2B637D791B88BAF8C20056B4901D\n      4BD1506C638288E5F4F10E324F54616C07423FA3E9A8588BF8EFC8EDDB7BA34F\n      4C9EA8A4DECB45E799EEDA2CB3C05C6FF47A1B90F858D9AD8B852B8B326728A2\n      4585C4BA84FAC329707CB8CA71A97BEF4D70C737F2C881C9BD8DDD9F3A7EE22F\n      1E3A1533F34277FBF99DF6EF6DAD5F1BC47F6A6AF9C745F53E1DBB759A689B87\n      8C26AA6AFC2DE2FEEE28FDBFD66E5F83EFE4A17D395EC8690891DEFB9D8A737C\n      A6E2D8B323FBC1DC9B020E2E8A1C5B65300541D615008525BC1E54682F359271\n      4D39A653F4AC93188AE01DD1A145C9E64D4E776852C0DBCF9DDD20FC6ABA1B67\n      A34F34E78E176EA35249B3B422ACD5C31415E2515A3A23E8293F9438F763CBCA\n      B043B957220F8A92ACD81886FDABB066E584353C45A625F3B1AEEE2806103D2F\n      F42EC95E61F18B3B386278369A7F2CF4266C5C0B1844D0D0E02D0EE458B7845A\n      0EC1EE07F856B654F2C4495D6542CBAA1C3201DAC362BB2E8E22392868847EAF\n      7CC4D82DA62E436AF36BDB2BBB173ABB177D13FB02B88B34F0DD3D05599998EF\n      9D69FDE8F4FEFA4EDBB89C3A1EA4B3B540FCCBADD5CF0F06914727A6A64E56C2\n      8FD52299A45F7DF7E68F9F3BFBC0DABA2EF80D017B84BF99F6FEE1E66ADFF5E0\n      D8FCF12542F83C6839CCB0A6534A783B2450C0A43800883F3931FBE7824628F4\n      85BCB32B3B1F99DDB7189B894A308C8874ACCF1CE27BB1CF1DC226124A8D1E06\n      D497D93D7C04B499972B6871F01371912DBD9B10AED160487BAE190A405AC544\n      2ADD42637475AB5BDCFFCAA0FDE5F60A849EC3229A2F2A071F9B3FF713EF238F\n      3A9664B627FDEA445F1847E6410628C5C9B736372FDE587EDF19D2F460B32854\n      77AF3BF620259384493C42A51E284ACA233504545D10BB2DF35B8CF50509E5ED\n      78FBC6CABEF79D31130D4D5BC2D6A9CE35E95879D1A2E9169C6048D005BC402F\n      6FEEBD7873F5D2D5E34F9D728FD650283D19C27344F162FFAB5BBAD36D7E6056\n      1F439A1990AAA010605017033570B4CB9CC13D2308FA07A384E3D9275EBA16E2\n      EC94917CB7D83C7F6BB8AD8E7EF2C978A147785EB9118E9E5D1924EBAD0F4C93\n      8A6746867BCAD99D58BB78B9D99C71F85C6FB853392279251332B2D6D31EE003\n      ED480F6DDC782694A1434DEA131238C6853EBB9A3AA2B0C774E3C1293A74D26B\n      597B7D67E9FD8735EBF5DF50CDD9AA5D2C10C2AFF1EEEDEDB94333B6E1646608\n      A7D6B510EA5DC94BD3A652270055377898548F3CFEA3CFD0D54FCD7887DD70C9\n      876CE52C4C91992AADD7718615502C1334AB409ACADC3E0FE6DDF5DDCE9700F5\n      A6D3732D51DD25B558C755FBA627D7B3E889E9D1C2907B26DA6EAD5FBCEA4E85\n      93C7E64D04FFD060CC8697CBE1C8708A763421A551B988B2A400A6B41645AB29\n      5DDA5F71404A250127E846A69493D39110DE9488DD8DAFBC19D582C6C34B8330\n      46DD5E7846E139311105A15EF11EC5C00B5DFA9EAF4BC9DFCD373A31004B99AF\n      A9F62BD7173E7E502FE4992121ABD142E245926B9587E6B15E5EDF9AEACCAEBB\n      C93B7BE4D00176DF21D7BA0CC298CF1557E9EDB5C16B17676B7EE18CDC9B4EDE\n      190AC5923C8D162A6289650DC0A46EBE9A04934DFEE491510498D1F5580B1821\n      764594899060A7E858DD027B33CA4488BB088801561FA360F3FCEDDFFA5BFF4A\n      DF181C9FDB1FCA7CA62E6643B71AE77E2275CDDFE50A6BAA0469845B3AB96157\n      27A4454C63C06E201C000DC29B488E76265C8D8711B01D4601F7457D22BCA104\n      8A0881C2376820BFC1C6F36C5899475D6F74D036E57D04243D2C4BA369B71D91\n      C417DD34D5056D07CE2650CF21A400FA76D57CE6EEEA0C0F4ED71747C67C36BE\n      5364A8FE9C14A568246E3A84CED8A488A6B408745899070CF9C668F47BF1EC9E\n      D0FD3D360FDBE08035DFF9BE535F5BBFF6317FFE6FDCFF0158DA4F5F7EE36A2F\n      3F9F652FEC759EAECFFD7475E1B4EA044DCD320149252EEF720AE55E0C2A3F7B\n      E7F24B121EC1F3A42428CF849A1CBE3075461E0CA34FD6E79EE095892CC55B78\n      74A8C56BB8F21E199F0B3B38C75CAA9C7436584861B814105B51DF896670D4AC\n      BDE1990E9331107404AEC1555EBCB3B9FAD044EBE9DABE19F8B23C154279BAC8\n      05CF8DCE0DF6E043F61A4A95688DB68D907739F7182BE7949136A3945459CC47\n      6A5E4A72E55449660147FA04295CBFD02B22FDDDACBD32D4154BBF6DE6E0D122\n      6F0A59F579CD7801CAC8628F814784A74AA3827B47006FCF3C632B4084207C23\n      A82F0D1890E250915B149023B64F644AB98CAA9747F1735BAB1B79C167E62E75\n      771383BD434381EE98C05AEBC4FE85A57DDFE9565B49CA1C6CD04E0B73A7EAFF\n      F2C6EDAFA4A3638C9FDA77B8D58FEF9F0E01249EBF70EB271E7BF8C4CE363CD6\n      060900EAAFB8F41FDD5D7D1B5B46FFE8CD32FF7D2A8434E592D2E3103DA96860\n      4BC350C51E684C7EC7F264DED978AB9FAC90E27D75F667EBCB6712019451CD86\n      70849856C09DE3C8154254F02656E70E9C8D0C8D66D1A6AF24D4B0697177A063\n      1140380C13A51E8E5FB004B2AD515121852E461CE208737327B095B6E79FD783\n      AF6FADE771D2F0665B3C7BFA13C78EFED06364BFAB0101001B44F9DA22C880E4\n      D19DCB57F276BC0899AC023FA5D038A6D460E420B50D74ED427D72519AB960C9\n      805AC03992DACD0C18218B5DE3A6373AED95CDA5738F9A5AD58A096EEA00D988\n      AB94BEE1C66B191FA5220A53D7D369E68E9C986DFFD7777C529BF8D8A9A4DA0F\n      6CA22B242DDCB0D7C89EBF9B8F868D8F1C8867200E561C120219766881150F51\n      D36C40FF70221C5FB595B75265090E7EA0926298EDBDBAD5BD1E1FFA53EF1F2C\n      751995956B61FAFC6A62DACD875BCAC35A8AE3537ED3BF73F3EAFE53C7D23D77\n      341CD48FC0EE4C816D4088B22E9A9772E523A63785E0E83AC6752B6D938D776E\n      CEFB332A1DF2138A1F62EE60227D3DEBC9CEFC0766465B7DB92A1A87264CA5C7\n      4C757823EDB537164F2F683EF62F4C18A4A2CCB501BCAE3226E1F8042C7E98D4\n      8E3EFEA92FD0DBFFCBECE2B9994ED80F1BD3D1EC320985AC10ED722729CA71E6\n      4095773A4CEC1F7CF699FEABE79B670E98E98A27BB8E92B21F745ED96BB526D8\n      FBEAC35ADA48C5F0BC2ABCBCF550606664819AEA9110551471700C24414EB02F\n      14DBB9911F95422A63E202CF5A3242EC1AA5E59FB15F88E63423BE8AD83CB9D2\n      5FBF74A73255AD9F9C8AC314B09A8FC18AE6C684A86E0EA0BF181742C7A1746C\n      25424AE103740432F7E410685ADFF8FCA57AE0D7CEB686745B4475AE1C748E55\n      981110D16916E8C6567338BBC1F3B777F4F113F9B10321F7BC118EE54086D87C\n      F752D4EB063AA581B69789EC8E20ED0C47C3E6A109B6CCB28A62CA295673BF51\n      E31F3C117BD2CF03666BC0BE181A52C367877DCC3011E2D4082F7B06B91D8FAD\n      2B80E691C9BC7FF7777EE5C6675F6919B742E9FD730B4B9520C472A274383697\n      A685E4A8BDCC4A9FCA317946C08AC51A5ADE0AE10C1EAEA1E163917BC52DB642\n      E0FD1C0EF143E4C7916A08F3928B82D1DCC903C93D206FDA486B729CBC96F07B\n      F8650047E658FFB19951A9B9EBCAC4F58ADCDEE4EA8DA2DFE4C18134EA70F3AB\n      5BD7573999F48339B77961D0CEAD142E294C29036B34846009911CFDC44AF37A\n      A4A7686148CC7B44F01B5990FE41C1B4B40720DF6ACD5F39FBD0CFEFDE6A64F9\n      3F7AE42387DCD6A5DD95FFF6EEF3BFDDD157A878B23AFF93CDF074A0A46BA653\n      E26937156628932A716E06E1DFED6F7EBADFF5B200FE7EE89564548BCA74F0F4\n      E4A27BF90649B24742E7E9D2BD2F02BEE733E5A2CB04D6BF01D696D720AA2C14\n      23B68288A8506D17252B2CCDB1AB0A074D6F78104574D702C49758350DBD97DB\n      AB10D9BE6BF1F0E98CD551403277B2DC085EA0C424769CA69AC446A3A15201AB\n      820D410E43FD4048B6E8F7884344A50E33CE09A1922BE427C9F0FADA334E6AC8\n      9A5597E8F0F3835DD82D87DDEA879A338B32096C5173FC9A0D02343150706E39\n      BAEB71E3304C76006B080DF14E9E0217142864A74B396B8AAEE79654129B454E\n      2273696937125793F8C6EA36AB4E65CBF3AF257B17D7D6B2423A44241ED7B0F7\n      AC39C8E80F1D3DFE4056B4340AC50565E1F76A3DF8A5BBD7BE9A0C8F2BBB48C2\n      A34E74FAD8CC4AB7BDB5BEFDA38F9F5D8E3BC35E51D0AAE2F2AE6FFFFD5EFCD9\n      9DB6840FADE51F53222CFB6560A7113437C5BB3DB43A66AE70268160B86A6B58\n      0C1539383DFB73ADD67D43BEEC781BAC6BA79C00780EBCE2C081436585C33D9C\n      93F0144A4899B29517BE89809CA2392FB72B2A7ED152FD12EDD36D26AC28206C\n      E4C0BF0BCA06DC26CC400EAE421A4DB4ACD62F48F5FCC6FAAE2147FDEA344FEF\n      FF1367F6FFB9C79D057FA4530087B0E31C5910CEAE3CFFE26C65BA71EAB00DE0\n      14A738AF4B9B8C1E20A68E8910BB064579602007C33B0B282BA85D4FE43AB799\n      A7E8E0F2ED61AFB770F6AC0C9BCC99E416881E7C7857AB36936FA76C37272D3F\n      6B04BA67834D56E4F2025FFDDCEDB99347FC732D52EF6590797DE55A5FAC06DB\n      5FBD15B5FCE8ECD44E907A9556C3AB188923902AC968A5B4432A67B3BFE9D4DA\n      B11700E645ADF06E291F14E793EED77B0BDFF3F0E0F09016AA7A2B4ABF765BF1\n      41E564DD384A498B5E416F92D5CEDDC573277BB733D52F268E50532B8C76E115\n      328066D894152851A0090C953AE0617FDFE0ADCE70B4BD70F050E7FA5AE3E128\n      9EEA54F616F297A45D4CC57D32B9A8008D364E340CEBF364A27DA1ADFCFEEC71\n      E091DCA5AED2436C0297BEF54DE909404BE738E0FC415239F2F88F3C4BBBBF7C\n      D89DAFE4D33C5A9871BC3A09C2C4CD803945238026360B299C1DD754E3E75676\n      5E7E75BE66D921BF1B15A10EAABDA8FFD656DC8DE71F3FD09FB561A562DEDDE9\n      F4F2F9534B769E6676C7A90063F184AD52E2C1EEB41E247B45C65EA4F78CD8CA\n      204ECAF11AC6F0DECB404AA238F8C07182106F0B098F6F6DB6DFBD35B3B4109E\n      D9D7A33DC00C90BA00F98B20624055480E31CE49C712786CFC4E6CA982573655\n      A31531197B8B00C3B9D1BCFBFA2BCB8F1CF2278A1CCDD00264A49097149C6892\n      8B04E84F401A3B55397D3B4D2FB4DD47CE25470E406E094609DE572B7BEB4B5F\n      9D6145880FA1B337133BCC5D2AFAC341EBF80C5F66799411E59A0D651D27F8D0\n      C9B442B119D9D4A8334E8490E945590E6628A73E7EC4F1F5030EA953BFA8FCCE\n      CFFF97377EFB259198AA638E4CB68ED59A5380E6B3A4DC2106BD7D618B38DC45\n      CF55830015C10453CC96071F1B720476A3E2E6CCB0EB0DA7A04AAE88F00DBEA6\n      C4B9A8E92DB4022E041C7114845E6602EC3A84178E7D30A86AA560890D44778B\n      667DD8330261EC4E6876992D62BD1B7ABF3B58E98C8AA79BCB151E7DA17BE73C\n      1D007FAF2991E128862CCA821BEA07400CB5E8330E89C0B3A8A693415471CB1F\n      A2FF87899095E3139AD2EF67E46F9F3EFD4F8AD1F99BD7FEEEFBDEFF1DF5FBB3\n      78E76AB8FEAB5B3BFFF9623E9FE47FF34878D6A5006FA91AB67425C6189F4D64\n      7A4DB8FFC8F6FFC566DB0382A368CF87D397B9399925EC4CD43834DDA8CEF835\n      5E1CEBE68F8C9C1926B28613430CB2DA4BB5A74981DD4BA5100BDE54031AB5AE\n      02228B2D2B9099124A122C4ED1356ED35CED5ABAC3B5820572DD378BC1EBEDDE\n      47F72DFCE960BE9E0DD1A2ACB4D943F13B624716FEAD8D8D813C3ACC335BFA82\n      732C0B942564563AD45914520408E76BE2E2653E03B002AF4D307FCF11AF27BB\n      AF0FDADBD22CBAD1E393F3CB793A0D140EF6837523E37914BBEB34430179470A\n      59D6BB3D2C7351B4C31602B6206E07E4BEACBC8E2552C948B17E88A2CFC059D7\n      85BDE9937619326E76BAAFF436E37AB53D1A96880B771C2480871CF72FDF7772\n      7130A82AD3606E50E014E1DB15E79FDEB9F64A36DACFC8A9A5C347C2CAB24FBA\n      9BEDEEEACE0F9C7B78BABFA58636274161E2F5807C3EF37F756D75C0B0551641\n      EA380EBC6780FE474E84E3A1B67B3BC9701FB16696C1FFF0B122B1A4DD6F593E\n      F3133D9A0A9D38A38CC53561F6B76AAE0BC0126F8A73C16C1404F08960413C54\n      351B1BC7BB68E28EA5C9D2098920A884000A94459BBE47210BBA796ED152DD21\n      400B21C8E01B4B9B044F60D7A95DD4FAD5B53BF02227FDCA44853DFDA96F9DFC\n      9E5343B2CD0B09E900CE239C865B5F7DE5E0FD676C0B5B632011A26B279FA0F6\n      80D53582735539C1B673600D8066716B10015466232B36B9B14E21F72EBC0D48\n      AD79EA412966983BC3D0EBAE949654A9A49788DD826D4120A2409AA6DB44C5AA\n      D758F9CD9BD55DDBFAC87EFA80970081A671AA93804FE9AB72EDC58BF327E7C5\n      8946828E947ED89C50088F0BEE8CF3071D7BF38E2F32CAAE193236B52F4D1E75\n      A13BE1EB4EE7A59DD6270E268F189290CAED4AFAE2552520E3D488A70AA560CB\n      3BAFE8B6DE997EFFC1C10A911B49733FB5D34A2AB45F418D75ED4AED6B6F24B4\n      0504A984E7DFAD6FBDBE32737A268E7BE9209F3BB7300A7782DBF5F40D1D3DC6\n      D3E9EDF42560774EF3486099A2EDFAD6BB1BD111EA2C58127B40D0A5E9634B3D\n      894A1BAE72A7E9D2F28D05A3E8302642F5DBA7B25AC55B98168D0A0984F45129\n      D1C9518A09F2D788A481718A8DD4FC9BF389E74E9D9826DEDDBEBF9B9989E98D\n      FDA367AF9139C53E3CA527C260C526AFB7D9395A996DA03EBAF05139C343E707\n      4C7B0C5E9E87367C389B6D4A7A5D3AD198F25A08D91B9C5AD87D16877C9C8073\n      D87E8C277EFAE6E6EAF6C5A58797FDFDF52CED4288F089879915D59F716CC056\n      70FC3122D198046273E6B8784DC715C7D20DC8964E6056A7BF2B06517BE69116\n      85751161CE1D341590C03D0378E78533305606A4DEAEF2D6D53D79A5E73DF5AD\n      C3F919C28DAF522E058BC9CAEF7D69D6CD9D0951386AF872173083EF45FD6E67\n      E2C4345FA6795430E98A3DBE3B1CD69F3C6EF63578EC08DE24C21D8F0F628983\n      62A70A83D845CA05182BDCC20278D185CFBCFE1B7FF3DFD238309E7D7079EAE1\n      A8DA84B308D9C9480006464A7817801833AFC0CB2C5BDE5AF0D26F186F1CC744\n      BABC2E29CBAE586BC6BFC595823CEFA0D83AB6E067023BE099358102BE8D5E49\n      40800ABCEB06788BC3AB006F75561408EF682CD930B73915A9359B21DD1E6561\n      C2B3207A96EC3DBBB5BDE8889313F36B2A7D2B6EC31A577288F211C7E102A9A8\n      074FE76A6041652224C6C7DA0EC9F1F5A9F70C3FDFCB85F60FFD1EBB88E1DB09\n      E753B3D33F393DF1B5AAF8175F79E3DCA1233FF5D053BC7DE5CB3B579FD5D1B3\n      9B321E6CFFE59333DF2FA2433A5875E3D96198C322F1A411677BC2F9053BFA85\n      8D0EE0B0AA2423478D681115F6E34E0BAD297D3D3B13DD17F8F717EC508C5AF7\n      A4161611CBE009A5842488BEE406158E915C8FB186C1692E55E0249D2A670AE1\n      59B7991D4ABB6120114A9927B0DE3742F6DCCECE1116FDF8BE23F3DD3EC435E0\n      2381C2EF914374E474C4484C74624C52147AEC4457F613E3AF72144E725294AA\n      29416181C712470CB125C08583F46E1EFF7EB6BB529823247AA43E7FCA09EBE9\n      6E84ED588E4FAAB09119E4B5D2DAC5D18ED02E5A4F500E0723C272A829FB0ED5\n      188796960FE86A62951939B42669E29235A1123851F5C6AB3CFFCCB5AB40634F\n      4E1EBA2EE4CB1B3703D7CF8A4C130658F5A96AE3CFEE5F9E1AC53542A7AC57C9\n      4CEA7B2FFAE69FDDB9F686869C689726A7267BA38FCECE878EF7DAC58B7FE589\n      B3C7B7B65DE56F6A9AB07E22F8053BFB8FEF5E5FB329F60895D59A71221CCF05\n      FED1FE13B886D87E4F04CE4932830E6D12E10A8AB9BA967D6C66EEA3FBE68EAE\n      AB1766465FBD7BF92162BE7F76F9A0EF1BA6DCC031826540DC23CF713CEC5791\n      E538A940980E47D4C166CD329470A464F0D4808D84D43D3FF0F3CC2D5286B7E9\n      C24A0FC0267A6A00AB33238EBEBFA1712B6F6CAF3DD35E0FE70F2CF6E4030FCD\n      9CFA3B1F8657E84BC001107384DDD8DD7DF3EAC2071E35150FAF71486248CA45\n      8B9203D6D6F0AE1EF91F2F555C54A9151912AC64AF24451B8366AEDAEFBE549F\n      10EEA1FB155D606201D5394C8152DEC8DE36885EA7B44F4AB96EA24726A464E4\n      0EBEDC366FED3A33C27DB4498E2FE8D19EEB29650B9E849D77F6E44A7FFEC402\n      9FA703CFB8937386BA7E18E86C9B9371AB2806F5F19165A55E19DAFBE01B8417\n      6832BE5379776AF8CC2A7DDCA71FAD914444B72AF14B97351BD60E4D4026922A\n      53C6F15F34B2259D33CDC1AAD177B3E67EA15B399C4C9EC33E96D8340AF1C91F\n      1193311B9AC4DD3CDF710B3E7FF6C89D375FF3EA95C6FD13C691FA6D63EEC8DA\n      FB9C4EB0C55E0B83C52A991DA1B7F6ADFA683B094EAB51ADE7278D20AB583642\n      DEA0038D060CBAACB6108E29391C452523342F3E665B337A6242B90C1EA3A012\n      60A333022E16163E408861A32BD67EFBD2CCF59BECF4BEB44654B6596DF234AF\n      AA57A8BE3E6C3EEAE50FF964146DBFBA32315B731F2168A29A7BAEDBC4B29280\n      B8A731F8B3529601D80FB66F97D5D6D284CB7A80B3199C6157F81A21072C6C45\n      B911E1C2EDE5C377AE0F7777674FED730E5646BA2F240451785DE59517501601\n      9F4C62A91E1996531ADEE2C4204035CC04089DE077B9C1B8803523D34F6F7E6E\n      75F9DCA2B7C00C602580767EC0590AB412681C01A6220A0BA08E8AC40FBCAB3B\n      C5968A9EF8D8306A008BF32017C061E8647B2FBED4F00A1D42B0E4E973BBD416\n      5E33EC6DED4D1D98E107998C205854BD61B0BDB1593BBDEC9DDA2FF3DC6513C4\n      095146B61C21007067CA5C0E1CD1E8DCBA0CE7F19D7AFFADF5CFFC835FDDBAB0\n      4E44B8FFC85233192E0FB285663345450924F4A8EEC900722A8F1738DF0FE4D0\n      E114719FC6D9A212152B0E9F16C800D229C05EA8DF544ECC0854162E077F10E7\n      629661A58412D63F7512731C09A085AE26241AC1A29244CAA1D4A96143CDF614\n      4AF5EC59B9E6C8769E4FAB0A51E26A407FAF7B7B2FD7532883C7BB2A2F94A910\n      88F2D8A2515E363A10309C32E195C6E3B6ACC3C1F673042642ABEEE1784EC607\n      0B7D06CAC992728E06F872E0881F5E5CFCEB2E654B533FFBD6852FF6E5CF9C7B\n      FA4F4DFB57D76EFEE63BEB6F0FE99BB6F7E0F2E4FF3635FB7837D99C20610CFB\n      C853721426E99EE7FE8BA2F72BDB5D65EB414E24CB32212722FBEFDD3366B6D2\n      B383BCDF992BE421EA4E30E1006C8B3CEA8BBCAC7D2AA57D5376589BD21E8997\n      6D720C8105264289CDCEA50A9F1D68BECBE95D66B64D9E2431EC9E5EA3F272DC\n      6FEF0E7EE4D8A92763D35279D72B1CED0BBC204532917112230AD389C6566683\n      52F0848CE539603B97A58BD205C7968F80CB27B9000C7A331FBDD6D9BCA3ED9C\n      E73DC19A471A939534AF419CF24AA063E0AD5314CDC4322E9A2A302382520826\n      A00C158C6C39494FCA26658B134558A647E1055208E317807864D7E7A3D0BB3D\n      1ABE96F47AF313D2093637BAEBBDDE2EBCEF28CA62D5B7D225FADB5A537F6662\n      7A261E5604AF6A56532CAFF82F7AF6E76F5E79232FEA9E3D31BB782A779EACFA\n      03269FBB79F32F3EFEC813EDB69B92EBD651113C88DC2EAA7FB77DE7F5B48F87\n      A17486C34E3A8DAA7E1261D3587D7D6C4AF807AD54E40FE973933FF8DB721213\n      B87769768F3692141B0FE8D81EC5C5ADE454DDE0ECFE19E0E8EB2B7B172BC954\n      E0FDADF9E58FF66853177985F2BA4F3D9100A30B51D0C343B38808532B64A972\n      160B43A729FB18F0EE1AA7B498964CA99C07104CDDA2A0089B9025425AE7584F\n      C9CA63414DAE02EE0F69F66CBBFD76CF2E7953135575FA07CF9CFEA1739AF5D1\n      97D1E5EDD72E92AE9C7BDF3908FE0C1298411937CA1B94CE581B95E685A83EC0\n      C75A0858AEF52D03587537916D40E7DEC8EE5C7865F2C0849EDD0F47858B0578\n      AB5A25D886402B0C5D153734B9CD4C0F4BE180F94388C18E79BD6FBFDE253EDD\n      AA0C179F3C6602D83C895509C014A6EBBD2F5CAB74B2F089FDFA1089F3B4513F\n      20FD69375F2B6FB4AC29A707B1B10E7FC437542CC796C376E0C5F5BBADE477AF\n      26FB6CF5DBF7C3A2386BA2FFCA3563F3E6C106A90167542AF5F2AFB72B872B64\n      3E1ADE36763D6B1CF18BCA80F38848407D10E4803301E1C8809379692BB9A836\n      3656F69D9E8CAAADED77D6DDB9C83FC08516F11B7D47B2E0016F2FEB78D7A3CA\n      112773129E06D9F51CD62B38C24762E049C729DC52D69C62DD039B65F060C39F\n      8586931CA695A38FFDF033D4DCF8840D6B59AD2A1D6CE474D12464847DF83682\n      432B7C95BD7827FF8D3B8DE37D71A83A30A9365E45396C5B77DEEC19E14F3ED6\n      70A69DADD73B92BBB34F470ACD34B9E33ADC15886F61E560651D3C71184AC6F6\n      8F78FABC72EDB2CC51B9137840EB8004618F00C056A0CF13222E7AAF7E3DEBAE\n      788F345B33F326C9C76DFC22F0B1C91CEF17C7132CA5D1330A7373F4A1D60C05\n      39440A8781E70EBC78487FB9A3DD0C584EB5FFCECA667FEDF8A3A7880B611B32\n      A8E3B8704852F827C8556C80A79269CB338756D3AB1B59E2361FFFD644345DBC\n      85CC50E8686DB3B87185885801DEA62EF9E2A0CF77FDD9A0BB32989B9A12275C\n      19C6199B088ADADEEA56D4AA47E7EE4FDD9E250D973708F74B9B51546BB024B2\n      3894AC5C4FE724173A949BECD9FFF53FDD7EEE229FAF61A52F2916A43D39398B\n      ED3B06933D16D1C8D89A178B751A2D3080DEA1C1B9837423F73162972AA6C291\n      0003D02544DE1B7D2DF9314688D2E706A723B4C1DC09B14743B6948529BD4E20\n      2967D64969A1E0609A21E303697AB9929E3F34722F8FB75D7B7D34180EB2C589\n      85BC523DBFB771AB0FA70BB59B15960A35D6F0FEA7317DE934203047E3BA14F8\n      980CD32347F9691A31DD08D98F1C3AF413B18268F3EB35FA636F5D797CF6D82F\n      9D7D8CAF5F5E1BE99777E9AFAFDE889DF8EFDD77F8BB80D5F211A311B63C6526\n      C8F52DA6FEF568FB3FEE0C463A1224306438EBE71F3938FBEF7A531D61621748\n      30766757B1C7D22A8F5A5FA06E0644B95C8A4CCBF20EB6EC98C5DD55CEB9A2EE\n      BE86445860230D96A9E0C514EE864FEF08D9967927CF472842E85F33C5D706BB\n      C7ABB59F993A79BCD369D7FAC6547CE9B828724D24B57B4477991A96B60A468F\n      3DEACAD351CEBBE2C52E3665201AC08E604D0AC7BDCBE585ACDF57AA4E83936E\n      E521A9CB886C7DCF15381383473AD424804D56DE106B041EB6AEF5B83599951D\n      33F63DC65D0E7EA10D252D6B44401D338ACA61A6A07B55EF4E483B44AD8DE2AF\n      B63B1B34DBBF7828E915B777378DAAEFD04488E24FD4277FB032352747F0EA2A\n      8A4E6A31F4F9D76AEC176FDD7C3B2607DDFCD4FC91437BFA313F1F54C96FDE5A\n      FF73EF3FFBF1189621BB61EA03EE04904334FD6F3EFBC2D69D8BDD61EEE2BC30\n      60439FC227A089C149D3B24F12559EC6358C7B6DC7A4ACA6B37B3E14F7ACEDCB\n      2977FC5872EC9F6EBE516387D3001B9C950386AEC3AA51348C01FE9A295F7C72\n      6EFF77FBADA5781438CAB8B252751C476440DA7DE1320A47A9E7718761BD88A1\n      FA152B2B1863AD600010787F6571DA45E29CBB2D7D6C4B33329C4E2BA10C4A2E\n      8D4BBDA8570F50C66C8BE0A5D5BD7844ABDCD6979DEFFAC73FC01EA8247CAF1A\n      C7B79F3F3F39B75839791A621657A9D1F0436B84D709857DEB1B36D6C792A591\n      3141BF6B200C6444ED6D45761D0989D4742E5F689E59CE6A131E8744380314C0\n      C8A48CFD4D3C597A5BAB9BD4B6CBB60C91F2DC389CBF3DD42F6C44870F5CEC5E\n      3F343BE99DAC0185A5522435B7A0AA723D895FDC96ADA0F9E4A4249BDC992513\n      673CB35B6211BC6AD1B4B446C48B7F52E2EB7136C4926937E0CD8E933C776D90\n      66D31F3DC32AB96D27BD97EECA5C4F1EADD39A22CAC9B7C4EECAE599FB6678A5\n      99DDB6C5F6B07ECCD3D1906BAF003C17A203145302C28E1B92607766FD8B5B62\n      319B7E9F4B7BC1DAAB71E350B3B2DF9081D97E63BB3A55F78F43BCDD753B7E70\n      08C7599C7876EFF60AECCBCA7C136F38F48060AB5C852A8722A19663A32974D5\n      C46A849F578F3DFA979EA176EBCF1A1F68844F8807F104128323F19EDD845E9E\n      E5DE667AEDBF3E5FCFC4ECC30C7275965B11447AA4F4DA28DF056EE74CDE7F20\n      EF6CAEAEAD1D7DE2C17C4A190AF815A563A8C34B1F254C84D445A7595B0EFB8C\n      BD17F0860CABA1180A0A52FAD43B55949909423B22FEC8E9BE7D6967D499BD7F\n      BE3E17E00E2B70A81E3E94E3BA8CB17B5B1DA56490577074E5C346678DE30490\n      C3731C128153904A470885B7A2AE3310779F7BBB7572B632D7B03AC648E206A5\n      0F4E4ACBAA3141D91B81EEBD3C17364CAF6EAA22AC3FF6918437E193382874A3\n      B22B37C5D6AA15830217D571BF96EDDAED602E88579356A52AEEF3B32AF0A99A\n      4F9A83AD6EA6D4ECD38FE7952C1561486AAE8DEC9814E15AF839842CF4C3CB7C\n      E1B001FBCAFFFDF92FFE9B2FCBDC23136EB1B7F7C4C2D299EA640DDE53966064\n      64A4E00861029C0574BA5184801FC8A1494D29CBEA086C98C78127331EEFC191\n      7A322659F77A31699905991D93336C48841D592E6A56E040A2340046A5C4CBC1\n      91B27D8DBF12CB32C27764D603C69602A460EB327BB5D3CE9B11AD56B5669BEB\n      3BA5EE013EA242C11CC0F386FCCF5DF494E10B3B01B0D7555BAF04F84529B327\n      8C9A26FAF06CE32F1F3EF23DDDE1500D361766FFD56AFB959B9B7FFBDB3E7E3A\n      1BBD78E1C2A7B3E20BFD2EECDAEFACBB3F78FFE947BA1D029CD04216379096AF\n      0AF34B3BB77FBF9B4B12024D34B4F7679ACD9F9A3BBE3FEB64C44A07A7B8024A\n      5D8D361A994B8D5B36D72AEB64DACF740CF9858E0DA66CA9E0C5CAEE63841E80\n      A1EEE9E260236D3070D9B62DD6F2749DCB2EA08A8CEC79DE8B5977B097FCCCC1\n      FB3E42DC11ED08485892C307F460AB31DBB5B26B514A4D6179E45E47338288F2\n      5E32E7A47091B1D70A52CD89E67CD335AB3607045A73229FBB338E3B9B25197A\n      1040F2A04EAE6A14300F5A9C4138A7A536852847209DB2D65AB6FC9752BD18A7\n      CBCB837B032A64FC576B55D3CCB06C9E1800032EF5BC7744F6C5CEDD94886A6D\n      7245A96B9BDB699E75889F321D70F37D13F3DF15351A454C3C3321D901E5ED71\n      FB5C83FFB3BB772E0DD82C19F1C0395278DF5789AAF3AD7F79F7DA93F71FFD0B\n      5936DFCF76A289D554D56053A7B6578D5688FC5C67ED4B49A70DA0AD600E7153\n      74E953A46CE5C17B837216C2604037F71221FD8655136EE53129BC274D746F6A\n      CAFC7760EBDEBDA1C0D203691A72667AE1A9FDC77916EFEEDDADA4FD0F355B87\n      1975AA5C57DD887B78ABEB38431787C721B0E0482B7A3DE01D4E59C0A6D86141\n      E021D1811AB5F770F204D5E2EE25C27210A5D4BCB9970A5DCE578C685BD5636C\n      7D65B32E519AEBD09F7CE8919FFCB899B57EAFB7F2C597978E1E2E8ECF5AAEDC\n      1CD01784B81A110D4884E8FE3D961A41B91C6C872306259F081BB1E246CEBA3E\n      C0F73BC3EEADEB8D478F8C829ACB175D3A59E0954981DD35A646D129BB63D42A\n      31BBDC482268425320CF95DB45FF992BF513A76EF5EE56578AE98FCED82908EF\n      10A57D78CF1E84886BB2F3D69E3BED571EA87668DE983A4C03174E17F6321340\n      5880CE0D7637E222987BE606185FECC80FA258646F6EEC5C5B9D7BEA84B3BF62\n      D77A835756659C4D1C6FD1A6A2851BDFCC069DBBB3A7175825CAEF92D17AB771\n      38A42DD4819612CE092C01BA106556E141BC21EEBCDEDEF7C4B47B20B777E9FA\n      EB83D907E69C254376D2F5B7B6671667D962D8BEB61AE615F7084E1FEA15B6B3\n      B50DECD3A9BBA8DF4C126C255601B04C34C2429D9A924895EE138440D03E7A16\n      1361FF878C23015372E52BB4894CBD02E2044F3D196837FE8D77F6DEBD317DA6\n      59CC0DC39E2B86DCFA8E2998DECC46710E446E627ADFFA8D1BF3A79BF660902B\n      8DFD8C980879D91409FB0BF80B407C51D2C1F2302221C466198D7D8484BA1E84\n      748E2D4B5112052627D58EDA7DE9ADD466FB9E3C55D4A897F5015E31D7C3338B\n      BEC228506DCB1603948BC19B76D4EA2E61209C2688F0D65398F6A52B6591855A\n      A09EB35FED5C6EDBDBDD99A70E10931B9B418696A858CACB7A342A6B12EB21CA\n      C4E8A498F6D3CB6B9A346B8F3C9D3A35D87AAE2301940D2F5D8344E87869C173\n      0F78CA79B32B57C3F9C86CE61EE4CA9395AC9E70E20956CB12DDD9EAEF7BE401\n      B918150C0E79C5B55502E1B60C46967B12823077E1AC05C6BBFEF9373EFD0BFF\n      69736B94485B1FE5E7960F1CC71E191B5A698B6C7C09585AB7E14C18012C6002\n      C0A48263E30B5207EEE2941047BFE7B211071B1E11E89B80BE3752F88DC850DA\n      CA63479156AA28324CCB890932E3A704B8616274AC016991AEB1DD52992F17FC\n      D6A87F2DE93895569DB980DD9FDFDBF87A9102149EE41599E4319C8AB2008BD1\n      061E4FFD4F35C48F1D58D1700E9F0F55DCFCF27FE7C0D65DF86EE984B41F9FAC\n      FED881E327935E5A413392BBDEE4CFBD7DE981071FF9F333B3ABEFBEFB5B3AFD\n      7F7636E26EB240C85FFAC0833FB63BEC739CA33699DD96EAE50AFB95BB37AE26\n      9047AAB9CD8F87F4EFCD1DFCAE2CE8D6364410521F27CD6D29A76CCB2464B177\n      108BC334431F0DE978ACE44B3838C1CA31CDB11B1500A502A0831A07E28EEB43\n      6CDEB3E68A4D3758911666B7906B9E73B3483BEDC131C17EF0E4E9538581FD02\n      5129C0FB00AA18E9D9A2A7ED90C166E77AACFB896557142B80AD0A5F50607F35\n      AD15D42FACF5F8B650B19555E34EBAA192684B13E120069C2DEE691B14AA257C\n      5EE06E266E39EF81131E6523002A6D97D7F1A69403B1FABD6B9DD209B7545E82\n      4F3D1000D12DF1F062D1CD601BC88D90AE550564BFAB9B3B97D2115DDA0779E4\n      95DBB7E0DF5709F9D8CCCCF74ECE4FF47BB58AEB2835875C85BC55F5FFCFB595\n      67FBD9619145270FDE174C7C5FD7D618FFD77B37A7AAEECF4ECCB676763BD54A\n      3B5141CEF6F0661BA0A07FD78F3EBDB3FE3BED8D8E28D30C9E5C525E2897822A\n      65D9A774A3C3E116F20D4658A6195A9242FA5E2E34FF83448890AB74B4C33E32\n      0776B0393339EF3376BBBF314AF50F1C9EFED34E6B3E1D9940CB90052E50C2D0\n      84BE2239BB67DACEC7B68558F21CDB45E3600BEA565A0451A54B609908C71EC3\n      A5978A06562E381FABA9C289DC09EBEBB7560A6EAF53BD9599255115B4F7919F\n      FDF685EF3969FAEDBBCFBD76E0D8497D64D632A0445A9B50B03A610D4C08D858\n      5ECE2ED2327A23D017684ACB8722B9A19C21D0A6F4E256D6DE9A78FFE9D80D3C\n      BACFFD7F297B1368CBB2B33C6C4F679FE9CE6F1EEBBD7A3577F55C3D09A9D502\n      0D0861C460244300818060104EB0B29278D961D9C6E09078D9719689094B9824\n      205980C03212436BA4D5929AEE56CFDD55D555F5AAEACDD39D8733EE29FB3FF7\n      B524042B567A692D757775D5BBF79CBDFFFFFBFEE1FB501D2608C02BD4028A92\n      BD52040D953842AA4375A44D2CCA2C4E45BDEFF49EB85E722BD954597DEA1679\n      73A5F4C8B4D23289535AB25F6F14E6657245ED3FB73571E9B439CD63D6F1E72E\n      9038772C652B6A4A30F968C4F86240A1B1D805B7472AC19EAB5DBD971F7EE9D5\n      A9F30BEE7D8B6AEF20797A5777F3F29DD3B29639291B5D8EE37877EABE058BBA\n      B25D32D868D757389B77C0204B28892DC302BD7F6939544AF69F6A6AE52FBC63\n      21B5A4EF3A6B5F194C3C346BA633B59B366F742757A669C0DAD7767CBFC64E68\n      9BC6872FB62CD86D9C993000AAA4B067DA58E6E11B456322DC821BA8F1A27551\n      1ACD4A671EF8E9C7B18C7E56C39C1A8C0F430CB54441D30C845A52FF00F73FFA\n      1CB4DD2FCA23B733114F7A7108B13412D9A11C0E138BF8A23CA34CD6EFAB49DA\n      51BC01725F0EACAEC3E9834D3786C10F09A8A129C6588A7B095664883A11A5B9\n      A115A7C468085C84FB4E3B1DBC7C5567C3C9379DCF3D686139796C0A05E6C2F0\n      034E3EA83A009B2CA8B8D6C51A01007603701B188F6BB9AFCE321E192AC0BB23\n      F38CF2AE3C7DE5ECD48A739619916AA02DE34D8362471612A1FD676E60B50366\n      59A8F24697B7106D94EE7F2CA7150C2EC09008D36BB7E4C60DAF94E724B57706\n      BF800ED3CD6026743B20FAED9C2BA9C91CA282B191ACD4D91996A7E6DD7B4F14\n      F5D010D12A28FBD99703380404398CBD774E255BEF7CEC5FFCD6AB4F5D1B70E6\n      3BECEDB5E50B4E4886BD5AD5C52AA304E6D508F8C7C2E461EC420F3F140500B0\n      F0DDF149E17D6D60D90996DC60D21FF28B2C9AA541B18F89BFAE3100B571A038\n      509F16360FE6B9328AA4D48BB59342857494EB813603428E84B0C920CE442B8A\n      D246E9A5A3DDA75076CAABCEBAB50D993C3F6A827429548B583AF60F11BAE01F\n      6372FDEDD0C1428F62DCB2829302922E5CBB16498D5C8BBF933399F9D95AFDA7\n      164E18D1D6B3A5EA709498CAAFEFB586AB2B1F3E77C7F4959B9F6AB63EAA922F\n      6F6E941DFDAE93ABBF81F87E48A7738E8FB217EBFC7F8FF73F7F7034020330D6\n      C8925F9C5DFCD9FAD49CC8E3E9D81E514BA6A06452841710282F02AED4B02A0D\n      0812EAC685F83B945060B4B3708BD4A6D85051B062322E57E38E6341A1EE127C\n      9D646D0BBBA4BCC9D0EBF62C0876D86A75B47ADBE2C47F573F33331C619D716D\n      38CCDC209BD57AC68C084A3011B03503941A96D1A0C649C121051CCBE1BD09D0\n      2902C9409BB73D857CCA60D40D72867411B53C37C4C42DDA0CD0482A66C58A4C\n      01BE0EB818BE1E8B2B90829E14211B446BC68317E3186EB93C03174C833853DA\n      027D58C3B73F32729D2B71EFBA1607A1D7E5EECBEBEB87816B33D4B0973C58F2\n      3F74EAE2C9A39E43940871559BAA64DBCCFF3787BBBF1FC71332F6CE2C943B83\n      9FC96BF7AFAEFDE7787B67E3F6BFBEFBD27CAFD9F634163E1E926D1FB4BB5594\n      29B7D6E6D53F69EE7CB2BFDFF40C071D132358A1332591832D5E840A74D12183\n      94775CDFC0C7B2195F4F7DE61B3A1A7F3D1162344EF6E35FB3275F38A6AC482C\n      2D6844EF9EADFD4479F9443F2E5155F288E718EC135161F610B9506126302905\n      B34C60F8AE081D6FBEC2F304811D01054228E216A5AA8208A2B1144D41BE0B8B\n      770C965E5A0FBDBA6B99FDA8FB85E6CE564ED6DC99A97C347BA9F4E65FF9415D\n      4A0E9EBFB272E16E335B33BC0F2D685376C804C6651BBD81B9A3A247580CD783\n      E883A1B00BAC0EE9E8360DA425139D57B65812571FBC10DBF881E71D5C87D860\n      3FACB041C22534C73A31F67FB28355D790511EA03413D58CC7CF6D0C77FBB397\n      1E141F7DE1A8964DBC79D13B170ED30EE51C89848BCC429AE4F96C74A0A6DEB2\n      309ADACE1A676B963A8090698A60174C15D2B305F325C7C57C0A4C82E78CFB11\n      E97DFE55CF73C2474FE5BD6EFED52DDCCC83BB66F346EA8E4CFC5A9AEAA3FAA5\n      25FB626493B66F1CD6E75CF78467BFAD823151098BD1B961DC452D76EB73D7E7\n      EF5AA397BC38ED562FBBDD1BDDDAA3737852A5EBA3FEDE60E2CC028EB3FEB5C3\n      D2E2643E9184B9DB7BE5D09F9924330ECA6202F51E289AFBA9CD8034611629CB\n      62B8D0147B84F6538749781A126194FD949F39901D2D30B4AF306719CA331C57\n      B4DFFAE857E5F668F66C5DD7DB03C7E6D32014250B89D3C32E8D1B515FBB137E\n      DFED4D5DA8A960E0943DFBE8347799037636D045B57490B30289B1225217FCA4\n      981785190DC74B5D501F853BE93ABE0EC9ADB8F7B55707613AF3D0095CB1D458\n      306E017ECC1C3E3E5D84F231A731E373761CC18A6D5A10CF1712A4A52885ADAF\n      0CB3D4BE4991A98A9ED047AABD7B34B5B6AAFD26484ACA5C2A15F0A068314220\n      82BE0C19EFF91583252A18BDB28E9DC9D2FD8F0AA76E79038535769D5FBBA536\n      6FB87E949024703C7C191D0EB7BC09AF94FA4924E94AC817ECA789413D8D9465\n      CFB5C17BF2C1F3A8649F866F680DE1B2C5999A680FCCE929E535D9C5CF7CE44F\n      BFF07FFF79EC9662EE2C961B4B92CC46F95AB54A1D056B06B0D801F8046C8A2C\n      10502492E9CBB29DA526CD1DD7AF576B933E774B8E0989AA3ABA42B493E7284D\n      6DFC88DD607C21DF081250C719EF0159DC29054C85DAD8E78FB8CEA5CC742C74\n      4F6988D1988E104EA41E65626454CCA158FCEFFA077428A7BDC0B2E3DD6828C1\n      0FC6E218402205B9D32EA43793A06F73049E14E1A990DC76E01F80BBC3A9E099\n      489708FAAF66A67FA836758E8A98C731F35654163BFEAFDE38B83DB7F0CB97EE\n      5F7BE5FA33DB838FC4D1E3D16E4CF503D38D8FCD2C0E7DBA7028A27EFEF119F2\n      6B87EBED8171842378F6F66AE5D72757CF933C9EB3D428D2D25850ED407E8337\n      CE40410459280403A1E3A2963DB9F6B617BD19688450A81C40914B8E57B940B5\n      C3E6427B2263EC0C94EC38744FE703A19A1A943C0E3C6F24E8ED4EBB25D37984\n      7F6EF6E47B3C2F94994D662ED8249004A981D1436C220BD2A06B58E442AD8E55\n      5E34F6606C84242EEA737B9E4529B7B11B3B0E307D9C669C501BF1AAD83E291B\n      120B78E9802E9D637F97B2100C82B72A5A55787C41C65D9CB1C462D1D8310476\n      704571F4A1676DF1572A7811D22C450D8A5E54EEB22641B7A8B9924507C38C64\n      66FDDE85839D83ADCDE612423FBF72E61DA4ACD3415AC51EB65195EE22FEFFF4\n      07BFD7E9DA845E2E790F4D4C7E8F3F35530B2FE3FED3CFBEF0F7CFDF79B7AB75\n      D677539FA44E8BA5039CDA9B9A02022FC76EF98B9DBD4FF6772EDB0F95A24A51\n      B3480B7F2E0D9AAEE3C21B3E4EE66F50BD715D54BFC111F1B161ACFEA62CF88D\n      099BF1240760420EC36536863FD8F07EACB1762646A6665F627422D61799A7FC\n      7C5412CCC79281C01854B6A0FE04B6550A468B8A7E2B3042056D059B060C3CD8\n      62AC4A159BBCBA28BAD95F298AB805F4A704EF0DF1F56C40961A0162839DDE8E\n      4DFAB5AA71F387DFF7C89DDF7DF1E0E0B5D9F3CB72BEAC1DD8CE47BA4EF004C5\n      150342DBF6744A73AC49681320856E29B5586C4F8E367C1F662A0F5E5EAF56C3\n      F0F4424E2C5D9F769C3A744714946DA1414A3250C606BDB8A1D107F6E74728A3\n      0E0B5294BDBEB3F9C2C6A90B0F98E7F7DA478766D92B7FE7A299C26E2C991009\n      B3370585FDE9DE53FB92A5936F5AE855DD6AB50CE5044BA0B100B6438AB2A839\n      8EC2E3293CC6DC1E685373FCF466776B7FF22D67B1A3B3A76EC9ED24BC73DECC\n      49D6CBD317E38C0F2A0F2CC28E719F375F3F28D759B856B6405AC3706B21B228\n      ED41E7EAA63E7CE968FE2DCB8393314A4DE919D4DBE955DE3143EB247EB1938E\n      F2C69D8BE95637BBD90DCE4D10FBCC5A49EBDAE1E4C925D4603A8F2D6411DC1E\n      32ECE6368E026AE79672154B4AE858D92448C353D0231C651F0893922624F322\n      3F272865B9BDAA01434F6DB7FFE2B5F27CE82E59B09F0843136DCF050F1311DF\n      6EFB66A1B52BDC29C7B9CBD0D3965EA49E71893D49CCC1DC2163B46613A1C340\n      890886596073A9D8F806900574DFF125A91AE9081FDA78D5031C7DFCABBD6177\n      EE27BFA33F97053A83159D341F03B3A29E077F90C5E7E35C08619D166CA7F84A\n      C4F816EC804A3A2C7DD9DF291C1DE75CC58C5787A5D653EB95C519776D52EA43\n      D80132E0806BF307880916CB8645221C97208B0FA883C18BD7089F2A4322AC21\n      E83D82907B74F99ADFDE47A49BE0A1CF5CB2CDDB9D1DB7E4863818F6133615F8\n      273CCDFAA0DC927B4C34F60F0673F7DD25E7B90508183524AFC41496D93DC847\n      1C3913AF7CE2A9CFFCAF7F60867897A25A250C5A9D7B6717EF086A0D61A164AC\n      1C9BDE95C5FE1032B8BD87CC4B4DACF4F3751345F951CFA6236333878061AF81\n      4FF40CCC0F971683EA945B2A395C8A812E3C28D1B83D742C4A0105A83CCD4C5E\n      149A2D68EC80D3EC48CA8E520760F7699262C836CD75138951E858A21348F429\n      956CB6DB02044341115BC00D80E98E71ABE6B8FFFCED66C1B123151AD7EA0B81\n      2C505380212881CE31F2438DA91F985D5E8675F08334508E9998CBA31113BFBE\n      DFDFAC2FFC4FF7DF7BE6E6E64BFBF1E3BCFC47BBAFBF36682ED5F9EF2DAC2E90\n      A0DACAF7272B1FDA79E98B6942845715D8A5E92F9D5BFBFBBC464D677F099746\n      5019F40D9C4B9B786C3AF712E3099B905442209CD99B61BF63095CA8A05600C3\n      82A03459647B05931B5814A3A5E0BB81124223AD3B8CEE491BE7C8619E3ED73A\n      EAD46A3D1E5C3ED85714558DBE58AAFFF389C979A92D9AF3C16985DA8C3BB480\n      438B112445589680D1502D610201DAE7301468FF671146E268FBD31CB05482D9\n      477B1898C655CF075E20A565841EE7AAD0A401566D403E86C3143F1AEB22175B\n      A6C7F21264DCCA821B842566394631ECCB00179416864660F644893DA6BAA8F9\n      48103F09FCDD5CEC33DAB2FF26D5FFD169277BC3E999D9214A1786D1CF4D9F39\n      D1CF70687FAA281B6CBFF22785FADF366F6D0B7ED1F3DE5CABF3417779B23C37\n      33F1C28D5BE530F8E1732796DBAD7CA472A744A276645064CF00E7FD3C033198\n      72E3691DFFF6E6956BB03482C342C5612CC257487E8E8B9FF88DA9D7BF51672F\n      12A141FA6F0E977EE3BF02212A96832CA89A36E80796CF3E549AE8E6DDAF75B7\n      6643FEBDEECC9D292812F206B72C22AE060E881DD06219093834782812A78860\n      F6CCEB62E1161CA84D81CB6DE61BEFDF165A2B63768EC690DDBE849895BFB4BF\n      792D1EACD6A7EE9D5CDC3E3ABA9E8C10734FD482FBDF7AB2F6E6C9EA230BA6C4\n      348A8A75FD3A23531895612F1812A3282E312928188502858A083D4CD47E8854\n      D6965BAF5E5DB8F34C502B6B5CCE4D83FA756683242039C8A30834B108961C16\n      27D09EC24D49C110DBE603D61ADEFCEAB5532BF7C9C38EDC6A764992DC33B37C\n      CF12EBEC232A3BAE8586B891723E445B4F5D9DAB9EA46FAAE180EB1253B0679C\n      DB67319E522C3ACDA04BA581C61B1EB87DA2B8E1FEF5DECDAFBC387FDF197F92\n      272F6F0E6F0C1A1796E9298ABB83E4A951E627D50716B54970C29B570EC3925B\n      3A55312C81C28C050F20E563E91CEABF10E12EA93E5C692F0FFDD4A75FCCB224\n      F1DE396DA810CF740875FC3BA67A570F9D23E5DD5162F6386DEE47CDC1F48945\n      4B3FA44EECC382E922FBD42428790ACBF1A540304405F566079A9B90082F7DF0\n      3358263F454568D1B00825CE73077AB992B6A25B1F7D6A12B9FE056FC45A15E1\n      52C57B360CB89CB746EE814183DAE161347147CDB99F762B7D07B3B2F1C133D2\n      F14100CC816A57A1234A0C94AB91855420B386F0B1140AE4356F084A7F158650\n      D0CDF7FEF8CBC9ADD6DABBDF22EF6FF4C8BEEF681F86F4308525E0C2C38F14FA\n      DC662C6650C8471DEFE12A08A43234C466A09180D97CE6669A6995DABCE8959D\n      7D153D7FBB7EE95CE40F03D7721F68C58CA502C7A22C45AD1015CD335218411A\n      4682C1F3D708A9972FBD45976675AE4008590BB5B1A5B7D6116D099E836CDCA8\n      34D8DE73B9C33C3F1A6688E1CA6A4956226912967894CF775A49383DA72F4C80\n      C8BDAA2A5A9186739B8F20D1F0EE95EE1FFC93FF10EDA50723914939C9B24726\n      EA0F57E76A8990F1002C6271B11EA8A4B13C813AC4F1A4A5BB0E1F0AC139A8F4\n      64362073D2C3663F49777AFD83CE9028EA193A53699C595CBA40FB09D8B63884\n      519B3109881729920B92432F18E6ED84FDB395B2E05C88619E77913E709D438E\n      648E585F6602DDF6D50BB2E387A525123685F7F4FEED7D6C7F8D4003FE78EC06\n      5696DC62E45DBC31C5F06D66C237E217B64FD21ED59C494FA2FB28F9C1C9B977\n      4FCFCF58AA9245DA19757C15B80B0BDD66ECA4BF29E9B332F8E5FB1F387FB0F5\n      B9CDBD3FECE64F778E36B1989EABFE5BAFFA98BBD0CB92DF37ED7FDFDCDE4A70\n      09977C317C4FADF1332B8B77DA1812A6C34055B240011224A1137492DC3E8652\n      64F830B7F9208147CB6CDA8B541AC296A72A7209C8B016CEB5B0F2C62C2ACF41\n      2000C4E794E9517026EC12B2C17407E9612237B07AA2798026A6F75BA38E4EA9\n      6B7C8C7E6772F60EEE59C25B755D528CFE0D733144A8AB750C935D36B1C28986\n      A613C81D4024E71235882B85903E19A8BCECB8EE30ABF85ECEEDB960754B39B9\n      FDF3603894539B09251E7768080C5A905C05F6F14A2D9CE2BE14A37DE31B03DA\n      0B084BCA86F6E4601A23F0BBA8A4045B3E284568A112404D455331E585221136\n      304741789BA9AB69EF5A26E775894E4E3EA17647FDC39F7696DE8B2629117998\n      86499EC7F8CB93E57FB4BB7E39E3B3A958C1E97410BE7779E5FB264E3C7EFBE6\n      7F1A6CFDCC2397BEF3B0A70DDDF369A9B583339E80CE9FFD9078C88CFD30467B\n      87CCFDD8CE8D2F64FDC8585ACC0454B0B503AB9B050231F2B8CAF9F544772C9C\n      888E05A58E59DFDF920B0B7608FFCEB550DFA049CDBE636ECDC6BB978E36271C\n      FDBEB985479D8A1F0D1A815B62A4EC7883AAE48C41A70A17B24C1609316618D8\n      EBC2D0BA12189485A01D004C1EA64615E00C355EA73BAE8E8ED722ED0FB62C5E\n      F2D20B87C3CFAF5FAF4D4DCC57AA719CD89839030AB3870F7FF8BBD77EF43B40\n      35DFA223667F5383E1694242482D32B5C9177E9C0D80D4058B7A23894E183B1A\n      A1663957D16BFBDD2C9EBF740EFA13A2A4F8A4F4CB1649D86B0A8910E7E09A8D\n      6C16F42D96317857A043A963CF329A3C22C3F4D613AF9D9CBA332BCBE485751E\n      94AFABC1A94B2BA5B2D44E96952B71264DDC2EDBAFBE65465FED850FD6D8B995\n      AC425266CFA7FD4F8AF558A768D4CA02AAD82859A84A4722F35D9F75F4ADCF3D\n      57AF57EA67A6C5D65EE77267E2C4223D8550DC4BFEB297964CFD9E796D699772\n      0F5FDD0F192F9F6D1877A44026CB03206A53528CF69EDC9B0EA7C3B7549BA5DD\n      4ADA905F88984FD1DBCA2A4ED5932D5E2BBB77540F5FDA9BC84BF83CA5897B78\n      E3A6C379637ECADED4D48006192FB61C01C4AA626814F0B68699424087F6B641\n      8FF0D24F3E8E4DE783DA03FB3A90FEB21C568D4A09EA7EE672FBC5CD850BF369\n      A3EFBB9A8F1C9B9F47167A069ED8EE577AF56C374BFDAC76A96E96DC98098723\n      0F24339980C579CC68D11AB4019FC1A270219FC680A703BA26E03D64EFA6E31E\n      12E6686FE2306FFDD993ADAD83C93BCE4E3E768FAAE6202C8C73A1146781835D\n      00E464DC432F8AAB006C0B85BBE2C0EB719D4D8684F635190A2600C48BA2B0C5\n      3C2DDD747B40E23C5C2A67CE10135824013FA02475182E9AE885E0A7253A209E\n      0518474355CC1BBE700DE172E5BEB7AAEA9CC90D9446ED33DAD855DBEB883505\n      8B41A85957A3DB4D6E73816753AE96C3A4B136934FA43690B870CE1BFD91A23A\n      60F72E927248B4E56C15AACA16B5EBC0CF23F4E95FFEED9DCFDF3C443653E733\n      DA79687EE6D454B53C125CAB086509CA8892A1574AC1A0878CE2C227D6F327AA\n      B55A24984A267D7B3553A984F1BCC40D12AF14513796A8D71B25A338709C4B2E\n      B8B80A806908262BEC05CD1292E52C030B41FB244CA6EDEF6E4B1C4B150B1149\n      D522E8C0413605F281CD0ADEF510FD696BA323CDE9C9CAC9E0D4CBADEDF5612B\n      2F263C615BD1D1A830BA18AB3FE9FF5F891094D5191610F699FD6814A4AEBFB3\n      5EFA7BB3271EF1023719983C2D51E632D52AB124ACAF748FB4ABFF83249F49DC\n      FFF1C23D8FA8F8F9DEDEC706D117AE6FAE8FD2E9D9DAAFB9E103EEEC5535FA3F\n      06375F4B753484F37E6FADFA8FD6CE5CB27FD4A405DB9127646E3CD7759DC4E2\n      63D5D472643FF550043656F84C70E30B55D1C6F7BD04B6DAE00281DE1A052C81\n      C7B0C422DFCCD27D205396BCA654F733D567FC8890A612B786FDFE64F5C5666B\n      98335669BCD2DC023704077FB43E7D1FF738C165D76330546146B9EA2BD3D1AA\n      AB04F24017D34221FBBE33A2C761DBD5A861DF80259DF675D84B205410A9897A\n      6D9F59F023CF655EAC72EEBB26173E486A0A909A05D920656F18953611821D0B\n      44A5E28A14D5ABE26F314D95128ED3953222247540DED64D546283BCE5AF9AF8\n      487BC45429AE1912004BA7FBA3C18E8B0E1B8E1E7949245E4FFACFE94EA3EABF\n      2B9CBF983ABE0B73888B714E05793EF47E23DEFB784F73692ECCD42E9C58B8B4\n      D97C3F9DECAFAEFC0FD79E3A57F73F5C9DF386F92E8A269C81D37352E1E4967A\n      121439B0E75FCA5848CBD702E7B7DAD73FDDED24D00BE145F3361F17B2F01BE6\n      24C766DBF8B836CA8B0395FF3590F5ADB9F0580005C1D1B5600216712DFB40A2\n      51E2BFB070E6C1561A72A1CAA824F402F2ABAE9FD6ECB3618CD3A26102DAE506\n      26B160A5A2E07F1226F7C0D915DE17749BC753A37A5CBE35C72B1EE6F8532426\n      1F089C35E6AE66F2CB37AE6559BC5CA94D21D6701CEDC4CEE9D20FFF2FBF606A\n      0A7943FB4D299B063D57E4155F2385AD1DC049AC30C584AA015123840E86CEA0\n      DECB06CFDE420B93CED959575262139ADFC8FDD005DF5006AA5C2431855A9F41\n      3E569921473611421E250ACC4ED264E3F32F9FF456D3737CE74B975756EFDABF\n      7D1DD7C4E29BCE1A9F8CA2144A7A5C8941AF8E6AE2F9EDE65E6FEED17BD59999\n      21539008E39C079E2CBE3C0397CC42949C5940CCB5908EBDD5D8DB79E275D61E\n      CDDE359FF58E5AAFF567E616E9599DE61DF9C428E168EA81130A0D18E6EDD77B\n      24C6F50B13A63CCC6160C52F242C90E8C8FD670E66A717BC7BBD7E78584E1AC9\n      9787A842CDC33E8BB4F9CB269BAAA0D3ECE095A3053EA5CF1A76C8F6AEDF0CE6\n      C25AA36E5F5244621B584A05BACC29A4382E41E9D098F19217C04D7BF38F13A1\n      6EFF0319C4369FF0DC1EC52C6183CAFAF0E8779F2ECDD4F5592A64AB2C99C036\n      55EA5C2AC2FCE166D488E77A9B7BE15DCCB9C7974E99663E0E52134618071201\n      68A2E31999639593A2940CCB6FCC8CFDD961F39D650ECBFC90DC68E74F5EAE31\n      BE93F46A67972BF79E4A719F3B9AA4D0E6C29EEF48A84C158DE7F1BA10311226\n      B180C49171CD0F46DCB10C08B56967204962DF0A366EAC09476596F1A3ABB72A\n      272CC0B54728CE48E63A81CE74321A84815BD4B86D9200CF6265C0EC8680FE8B\n      4DE0CEE8C5EB48FBE54B6F55B5059B30301075A43777E4E635C7EB256400332A\n      D4CF6EC734C679091434C541525D9A120B46D39483F4A97D283C39C8C33B4FA1\n      F9AAA1DC9355E8F8908097E79EFFBDC79FF9ADC7875DB3614392CCEF9E9EBD6F\n      7AF9F0A0B99FF6736E922CB6A88ABADC0DFC4CA80CE36E96E549DE108E05DAD4\n      130DCF5D2E55E65C67C2712A1434D510EC0E82BD0FB1B7AB1058752DA4B7814F\n      9B61965A6E117820AAC972019D99CC224522332433BD65700F094B11A40598B9\n      B4B970E4329D5BB2887A3E7F31EBBDD4ECD87CB5589BB27F4E3F8EEC53B2C136\n      83F1A03742CD1BC98F7E6396FDFF930C166A51363407207F87528226197D57D0\n      F8C9B993A7729BAA3B84E5A5B0E428EEE4795AF70F036771D8A43EFD48863FB1\n      9BFFCAFD8F3E2A07AFF66EFE09355FDAEE7C6DA71D72FF5F2C4CCC37E6BFDADC\n      795247378749341265633E7066ED03D5A9D97C90556190A71699A1EFA6B934BD\n      CCA6C45D25FABEE31930D46D8B8857DC99D4AC2037D02609A1DC2B41715523C7\n      10365674855300E6F4B9D65931DFA2D501C37DCAE3D4EC12FCB468B7187571E9\n      EAF65134D5D8EC35858E4DD9F958A971C9F13CEEF896628060148AA1106DFA18\n      B52D25E72EC4F3DCF2702540680896FC7CE86A58FE5518CB3BCCFEF7D4E339A5\n      5BA34E89BB6759354E129F33FBE15DA97C10C3541E23B075089A1F0A146D6DA8\n      426EC13F0BD399A25D6CBF412C75C679DB7E006432CFED0C072DC746786E4F77\n      95B0529A9FF4CB75A943ADCAAEE372368C238062DAE6F4D2659C5CD3A9CBF80C\n      F71393F5557EAA317147AA67FB7DC3E966C97BF6A8F94B83A89367AE4756B0F3\n      4E4DDE3FBB5A5FBBF0C941F3A5F5E7FFEB0BE72EA5BE038389FB6EE666B9332A\n      268739E85858EEA385FD0A8EBFEBF28F0DF6FE73BBD593A6D09E1BAF93DBD7A4\n      A17880E0E009F48D51193E665DDF5A70F81BBCB040CEC0F40944430B502C99FE\n      8ECAFC8F87CBD3A328AAEB1189E662715A7B65E698BAA61473B73022845D25B0\n      4B4210DD9DF18811E85516DE4305D280A2E8B84D680A61BE374400C658DD32C7\n      F2CB9DFD5D992D2FACB563F9B5BDADF6B077C22B4F867598B127F13B7FEC4D8B\n      1FBCA47D0B8031F166B40A351E370873D0B58399D9A2E0CD84C4299643A35B29\n      1D56BAEAF0A92B530FDE95CC78BE7D7679457AB5DC773D61013FB7710D41E9BD\n      B8AFC6415A18DA53A84DF5088137456263DFEEE75F5ECE2BD943959B4F5C3971\n      FA92D7EBDCDE7A65F94D7790E91A0287DE84020634E0DB96F4BA5F18F5EB6CE9\n      ED0F9946600919CE0403690F298DF00CC05954B44C85F15D904455B854EA3C7B\n      107FEDFAF23DB39993345FE8CCD617E8451D931EFD8AE8E7E9F423A7B56E5B8E\n      34BA9DA67BF1F49D73666A94490B2F4B04142150B69F345F3E9C5D5B73567414\n      74C3B81A3F33340D62EEF6BC11565F6AB3C55A3C131D5E6EAF4DAD88D5945F47\n      9B376F4D9E9F0A43DF5EA8C4CD2511958C621BF01C1800E7B0415198AEA07169\n      D4BE219B08CFDEFF81BFC0BAFFDFA7CE917D679EA84A992096449F794D3FBB57\n      BF67E6A0D66C50C6076CC81943112834E76EBC8F9D8E9F8A56ED511E2FD88436\n      E1A635538EF270804D193350B105215B0A10C114E575B0DB2D3A17A0206A1894\n      FB1D17F43137DBDD97D6432FE453B58DC3DBA7EEBB03CD86891C1197A1547298\n      7C2230FA5648538F05C98A49BEC2B0AEB0F01BAF54008C529C904C9111821297\n      52C415B4C452171FE5DDE6BEBF36413CE967198820D3B06F217B329C9AA94377\n      DBBE4107E4F82598612A184AD7AEFDA8C9CBD755EE961F7C4C5717B4B0970836\n      17E4C65E76FB4A508D12D273C1C58DE16D9C1F24A861B3AEE27D8B1C5DE75C4D\n      B298295080D024C80E51522ED72E2C4B64BF51593A534E7575FB895B9FFDD5DF\n      6DED0EB7A1FA46CF54263049C251B2CCABB2E2F14A80A44D539633F34CE489C5\n      1FBE875CD7C64727439E433BA49F8C3228DA2914223C5F09A73875C158D1BE21\n      88A4AAF03EC23A241CFC94F68F5AFD7E6F7662A2E6729CE53895D806DDCC820D\n      202287CA3960798B096873A4B2A7E50E5107798A895B0EEBB9C35FDCDBDA8E46\n      03D0CD4663C672ECC6595CF8AF2F72BDB1E8FC6DB04150A1423EF07A8066B365\n      E7AD934B3F5C595EDD6F4EA0445A5A0B64C4E1928786E401EB7035A5E398E9DF\n      95EC0F5F3DFCD76F79EF9B70BADFBFF6FBC3EE9F6F775F8CF3925FF9F05C59D4\n      EAD73BFDE78F8EDA15B7D71FBCB35CFDF985D53332A9CE58A49D952477074A52\n      67271DB5A3B4A7CD9647F6F2748E95829148987227CABCD33F69512EA127400B\n      AF188AA012A6131C3ABE3990082DC4C98C4D84E010E6E08ED45D4D7B88DE0ED8\n      6B347D65FDF6E2F4CA4E2A2E8FBA89C82D5AF0E7ABBFEBD7EEC2D47338DC09B0\n      35B6C80A1D64798F9211E77DD89C02DB6903FB2A1ABC268805F0D8BEA9BAE397\n      ED635666E8923D1FBDB4BD89A5BA70F2F4B03F2A3B6ED571519ADA445842B88A\n      F0ACE37BF0136D78968283976B59BAE385DA62FE1EDE9AD06868018FE3B68C6E\n      229D06EED6E1E18ECB2C49B2DFAFC17D33189E2AD5571379CA0D616827802660\n      25B3FC21F3476C7D92AFABC48D208E3C2BDADB5ABC6D62F5BB4C3887651BF52D\n      84A292FFF4A0F554A7A7313A83C307EAFE02556F5BBA67B971F24FAF7FB59F1F\n      FCC8FC1DA7BB79D73BB271055B04991B95831B89423AF6F5C005E5E0C09486A5\n      EA9F0F3B9F3ADC7E5DA4B96F191948305598E300C1A6912515050534E392A8F9\n      5B2A115FF735F916DB4B825D171A7AF682A1956AF8AEF9B3E5486E8D0E3B2A59\n      71D0778593A715AE20542A3B960E72B798CF03A92D02BE1430B7EE1423301A72\n      1EA8D31716AF05EBB6140486758B06A139EEDBE0711ECC8D175373ADB37FADD3\n      37D5D9F2ECD2CEC14E92F64BAEB75C9E72D35496078FFDB7EF5E78E759A8B2D2\n      86321E7C4C943388DB607D607329843B66E98145AD7D6686988AFCE6E170AF3F\n      FDC0C5AC44B8B0B9BA2ADD8AE48E6B593648C85B0417E3A2A651146B72431385\n      FA54F4503E128E60DC6D7FF1C5A90E126F9D6BFEE54BF5C6BCBFBABAF557CF94\n      CBBCFEE05A5A4634C134D1C6B3B0A3E7DA477F6BF6FAD597272E9E9A3CBD6602\n      5F469126E33A9D66056D2EDE84067700CB990293052EBE26065F7CB53A2DF9A9\n      5AF3D9D6046DD00759ECF6F8D3E6A0DD5F78F4BC514DB075D9279DD7BB8B77CF\n      EBB9616672AE2A36E48309F26EDA7AFD60FA8EF34E234FFDC81BBAC317BA64C6\n      C3675D6FC0F3AFB6DCB589B6BFDBBE3E38BD7A41CEF7D94BFA60777FF69E69CC\n      C1663375721853CE08919621C3442FF80C23A960341736BE1C981A2DE5A5B3F7\n      FEC49F61D3FBA51CE8530E8F32C16AAF77F8F8B3538187A632539338B3A9CE1B\n      48EDFA998B1CD526B85DED1FF6DC25155C6223DFF859CD4125E3099036A49E25\n      84168D167B84C5240BBC3C1B4838E42B4429F140120CF42308BED53AFACC5313\n      F373A507EFE8745A3A1F4C9E5B30DC9E2C9C3B7E8A710D7B3ACE152B0629604E\n      063AD0E3F2FBB1B636C8C519B06D2DCA10C5DE021825C01221B199618AB674F3\n      EA4663B9212C8820C229ACD7B164BB9B07AE4B2667AAC5B1752C0805395B3522\n      A0AF062A23F6F065976F6709A95C7AABAE2F1A019515FBA5D4ADEDF8D66BE589\n      2CC13D8F10E550761844B746B4961A3A0C6465D093E5F333C0FA4C4A51B11B9B\n      368E0662EAEC82A93250E599BA906EF34FFE938FB65EDC6B3BEE2D2D1B193E69\n      19274F1E3A39778F7D81892039EC2141C116EC3B415A0DB9BCF0D8C08A69E162\n      9AE7F6886A2F4CB19B096969B36F4FA14860A287803E2E4C35D93C9638207041\n      38746D4100CAA2C914E71978DCD9E32670949A2C372DEDB550D676546A015D2E\n      32A1BB9CBC9C74AF75926AE82D3416F63ABDCD51A7EBD904A08EA34B110A9C6F\n      DA6856DF1C7EFE4B7410666A6110DCA61473BEC6DF3EBDFCB03BB118E9FA68D8\n      20794EE33834C8F503E587DAC45C240E9E22C832983FC4F88F5FDBFE576FFDA1\n      077ABDBDEEFAE748FED95EFEC451DB7ECB7F7C62BA5B6FBCBA7DB0314A3A4C57\n      B2EC975656DF45792D9451055A61E06F3D54F120DFE46A4365AFB49BF9B99557\n      B7B7EEAF9E70767AB2C4D0A4C786A309441AD3533FD0ED2397C2BE1811B8703E\n      065235F6E2C9B1490DF0428946548A4C0F6978C3A52F8AE1C0E3378F5ABBA9A5\n      72E5AD7647143EC7F37393BF5B9E58D316FBC1FA3C290C8F13835B42ED199595\n      CA7DD848B3418B599601BA1160832841725E8B19BFD4C8492071EC3BB73DFDF4\n      D64D7B16824AE57A34589E984A7BC3BAEF855ABB51BA56AA9D0DEB554BF7F35C\n      5BAAEFD8A86DAAD203470B3C56DA2ED43F181F6933406857E647961106DE8DDD\n      9D5E50EE97DD7E06A0B93E59636976AA933EE094B8272BD3C19CC1A538D31C4D\n      B6E4BE47070C0B83AFA7FDCB8E0EBCFA79515E9568C29754DA0C6B49A8FF718A\n      FFEDABD70E089ED1DE4205AFCC853F3175D723A35ABF4E3EDB7DE5FEF2D43D99\n      DBB544341D9412144450BBEF21D5A3852FB491196C35F152CA55B9F6A4137DE2\n      70F3E5CE10E67A1CB08EB67720A43C07D553309A50DF92F4BE8903BE7112F1B7\n      9C3E0B6A2C4865A0178B4E544B15EAEE24DD96D26BA1F3AEDAC2C34EB860135F\n      9ACC13CC7DC7F541D317734BCF8114C2C45E511B40C7F6804A4B7CEC6CA38B8E\n      20A00E335E28F86625712E4D609C23CE9F70F2AFEC1D913E9E28958E74DBA772\n      85058D5218C9E8E2EACA231F7E07BA179EB70145138B7253C6607F1E2B8E1487\n      4119364C5453A87E6073642E6F7DF9B9D995D3C1EABC251758BB9A54A5530219\n      00989EF7C0A58D8E8C02750604420ED250A14C44B31E4ADA2220D40F465F7AA9\n      BA3B4ADE7D527DFA39A756731FB86BEB4BCF97F6078DC72E749650DDC6DD5E2E\n      984E5D150A43D444FFF6F6D14173F58E3BD8C2BCF17D983C20AC70695485B247\n      814C2C044B865983268E536DD7F1E75FDBEBBCB8F8C85AFFC538B4A0E62DC1C8\n      6DB97F8576F69B2B8F5D34AC2B4CCEDAFED1AB9DD9B30D7422CDB04D845568A2\n      4921B6B3CEFAFEE4BD179D50E73C617DD37DB9595AAA392BAE69D3ECB96E707E\n      FA40DF18DE8ED6CEDEA51ACDFC6B4A0C93DA9D5505B3B25CA04413E1E60C5CB5\n      8994505C00293FFBDA8AEA3582F5091366E5B3F7FED89FE164F821C79E331F26\n      078376203E7D636FF376ED3C67BC5FB2843BD5CA095CE166B03445B37DEC76A6\n      07A3A6779FD14B963587B0F465B18B4D81A4621C1B9DC1DC1BCCB58BB577047A\n      4F30EE084A93369463AE144E6D0CDE181D3CF5F2FC6CDD3B3D9F7BCECEED8DD9\n      E5097F39D0609FEE19D0CA72A8540E78D5F2621019B65349B1165CD8F815A3E4\n      451DA9806412DEB4CD0260539F6B9E678479A8D1BBBC37E80D4EDC770AF12C53\n      D06A28DBC83F3207DB87D35355AFC20BEB23CF80F2884589A3C2C494834D8252\n      F2EA461CA1A234BA08827390D9A9DCD819DD78B93AA3EDD3E030D664E86052DC\n      4E116F21A7CF5123691B5377F9B22FD8889B1CE596CBCE770E85E4AA7ECF6C56\n      09FC7CE1958F3CFFDC1FBF7AA4BDD7A3A1B4B8A0172F19F5CEF36BE77D7BFF63\n      99E570F560DC96A834D22ECB9C621B536A0B928403E6BD0CC649516A114D1022\n      18EB802D1E950B02EB9BD0289290D7F3003216C805033D140A251993028B5CA4\n      22C94D2CF0282731F8DB95646653BBEC516909A8C520D4F75F67EA33BD9DAD4C\n      83DDB962B03B024B76C7CE05A6B06580F5EF6F841DFC86E487FE2F26424A01DC\n      50915D2A87EF5D5EBE1BBB8D514E8749804D3D608CD9C765BF9B8B8C45C57916\n      A403D759B28F53B9FF17EEFF616BFF1F3FF89E770C4CB379EB8FB2FEC7F79BCF\n      8D46131EF967F599EDB0F4974787786136DF39FCFECAC40F542B4B2C26010C2A\n      6AE48F226728D146921E107D24E4EB474D72D7B967366FDFD1581E6E1FB67D35\n      F4CCAC2233A3FCDE8B777FA87B803808DE0822C0499C1774D8D847418C4D8145\n      22D4A0C19DC6DC3DF0839B1ABDD26DBD9E0ED0DCF44B9BDB238B4661DBC51E77\n      7D6176E637AB8D65D0CDA642C04451968B589136D2FB18751D161B1C25A963A8\n      0ADD51964D8261B2CD28A0D55377B8C54993C8F5308F3D76430CD7E5E8D5F651\n      363521B5CC653A5BADFB513A23D0922277D7A62D9560164858E00628143B9A17\n      D31A1A16EC8B251A7B05326867AA23A33B9CA6E5F0F5ADADAF105D2F570F86C3\n      5E9EDC71EEBC6A75AB229B4EE28B88BE6D71B16EA4075A858A13B09517898A52\n      B1EDA13DC7232AB494A3A33A55123F165427043ED25916CEFCFAED1BBF17A742\n      D3D569F7CE13B5BBF6C54FD7EE9C3B31B713A6BADF5F566437DB57E920CC8C97\n      1BAEA945AF7D2D6426A9451D7E0073A460F56162A6B7ABD39FBCB5FFDC70BBC9\n      71D7822E97A25417B65E85AA1AFAEBB5886FCD85C7E239DFF4D758D7157E87C5\n      1D817DC40CC742DE5173DF3BBB76C6069D24B554B0E6B8D369B748848C79C6BE\n      38EC8221AEA1746C6E73DC969130647CAC5937EE0EAA6F68CA8C2B1FB074A355\n      638022466E84B4E97B19722FDFDA7E6177B7B23035414C29ED2F4C5502EC4CF4\n      79E50717EFFDC5EFF166D62C56824D751BCD6D56302E929E312EB867A1768E9B\n      398D7CA3E9E5CDED8DAD9537BFD9F80EB66CC7E2035ED7ACC4CDD8F23C30B0CD\n      3C423A90F6CA92981968C85BC6CDB20E4A5A2260C6F3932F3D5FDB68A77FF7AC\n      F993EB36C2F2EFBC78F4CC65E7F95EFD9E73E2AD9EA47BFE50283A93281E6A94\n      F2919FB2EEF33734F5CB674E3BA7D6A4C50530506BB19116363241DD8F6039D0\n      2A19D6754AD964BC4C9FDED8BEF6175377CEEA9B0E1B10E7EDD5917B183EE7DE\n      DADA3BF91DE77068EF4AC647B5D64BEDD20CE3E761C2D129122108876FC6ADF5\n      ADA9FB2EF27260F131EDE7CD97F627D766D9BC278F74FAEAA074E7DC5E7239DB\n      C94E9CBD5354F6875FC9AB8CB3354B89630BD409CA91CEA8E22039086AFA06B6\n      90844503122EA7C5F1A0B81464A52211A6E92FE248AA522ED1B07C93757EE759\n      5D55E84E5342B11751E9F2A4D8394C51C771DD7CDB06FC4AEE8FF85D3AAD5117\n      4D309D11DFDEFAB22153C8139A2B8BE80A5999C2E9853AF63EC2A9A020498673\n      9444F9A0DD47CFEF9431F5EE5B4021CB7A6967FF68FAE28299B447573836F0EB\n      32623EC8985944A48A2C88C6D670C542117D4361A9687E1482350A06D1734424\n      985769702CE25EE46D3C77B536D7A8AF3594850486C5125BBE9E74A2D17E737A\n      754EB10C2E05F1201722214D4C416EDE31CA81F9F16BDBD150952FBD5957972C\n      2203B10142CDC65E7CE5A5D27C9692B68B1DCBADBC7C4EEE5828DCE2C110211F\n      A7E5CE70503D3329BDC42102A5169F35D4D0DF69EF56EF5BAC9C5CDBF9CCCE53\n      FFE6E97ED3BD8CF2239BA1DAD149EE7FF73D1726E3A836485C46871C88075840\n      C07A254D9986E123C096DA25C451F62938894D6F22E58C849EAB5261E31E83E1\n      41D7615C5A52018629859192FD80CABE0A9B3C91CA729C49474A9443B1D59EBE\n      81C03DFB9D35DA661E4D2D2BD16D2312FBE553FB0369B3EC3C8BA3E706CDC4C6\n      1DE45A4611C262339417C438F13960617ABCA3753CBC57C4886FB695F8E66ECD\n      1BA3340C17D38D0E3A1F947E7C7AE54DD4F1467D1F610FF6492DEC41DC413ED4\n      1059CAECFFE5999B0E3CB6D8B470ABFADBF9D11FC9E6BF7CC7FB1EDE4C776FAD\n      3F5E359F1AF59ED8D89A0CE8AF4DAFBCD0ECBF5AF16ECAE48188FED2C4F2791A\n      FB332A967D4FF17E4CB6227D28CC0B21694736DDA06E948FA6269F3DD8A68647\n      3A1B55B912919FA1D302FDD0FD8F7E38DA85D5518B222D86E41655156F4015DB\n      06199289D620B065A632B35E612F13D311F450AB3FDDB9E92CCFA499DA3E68F5\n      A014C22AB978D389A5FF39A8CC29D80FD7796E215594C99E2247461D11B26B44\n      5FEB4EB7EF222E676BBD243ACBC29A8459C98CE5F699CC1967D9840DA8E2E0B6\n      876F38D957FB077BA5D2955BBB172EAEB68E0E83445CF4C21389B934B5388928\n      CB33CF48076C20E125C14E1BD1028407012F81CD0865474AEDE4EA90F3038E5F\n      D9DEFC3394CD691AC1F8309A2F57CB890AE6CB49B7F37DD8FBD1F27C4324F586\n      17087138A570A66BF6504AB69DA51BA9CA4C39F5BC6BE260CE57DFEB36EA4751\n      ECE1D211FDECE2C43FD8BF797D98B8323D3F5B7ADFDCEAF78BCA5A581A56B95B\n      2EF338133425694F44F128491888E32047EA14B4B7991CE692B17DDFC2523997\n      DA30D658AFCD3DDDD9F9A39D2B372DEF016546AA12D09E2E0681907A83F8FD8D\n      C59D6FE182C77F7916C614AA031E543C8D66621291F74E2C3DEA3598CAFB165E\n      E672296CCCA76D9733DF258147604C11901936CEB828658E27750AA521F4C69A\n      041A6B817EFD0717055B03CED6AADA718EAAE40527D9DBD85D9C984FE6A69FEE\n      F5B6379BB3984D9748C09205AF5C1D90FDE5E8A10FBDE7C2DBBFCB026F656136\n      58ECE4DCBE44C90AFF9854A896E10349724F9A832F3C556B4C84F75E045144D0\n      2709325E26A404C6CE3023C061418BC406EC116D9C4C401F159667729AB751DA\n      161ED6DC8D9E78A171FB487CE00EF427CDD6C6D6ECFB2F0EAE6DA82F8EEA6B67\n      C8F79663EF75CF3E2C31AF4D68D1E9C8EF5A5E2B77E29D67AFCDDD732739BB44\n      6A134C84F6B948A2A0D466D397A514590B531D8532C5A691CED3F5CEFE6B8FBB\n      934E79BF6ACF3D7F7B230ADB95D7DD9DABBBF3F79DC4D32AC33D2F9D1C3C1FD9\n      F451BE17A77444F22A269E3DC3E25672707D63E6DE0B6EA30216C8DDF4F0A59D\n      D9B3CB6CD6CF9B3AB9DCA9DE39BF3FBA9C1FC813A7EFCAFD83CED383A972152D\n      53892D15A654E50555050D2E52ECD10BC408FC4B536898EB4289DECF2D23FCD1\n      3FC36AF4A10CE671B5D345C9E76E6757D7CB67503269816335C85DA57ACA5826\n      5189392AC50D71ADDB615178CE096798E04CB92185C0E5221B823DA9BD88A31A\n      B6C4C505AF54504F5621D6A1050D164F6A95F1412E7707C3AB3BB993D7EF59D0\n      2C779193ED2742627E6A4A362CE7311ED8F5F890AD2988FCC3C88BC519204EC6\n      41B10DB463042CC7804EBD861578031B56148DB41E5A7069891383F43C355A3F\n      D06258395912156D81B06FAA1661662121376FD3FEA1B352EB7189DCA02C030A\n      A759E53067AC0BA5272877CB5B0783F6A07CEF7D4EF99451B5CC8756B0B7334A\n      9F7992CF1CA6B581A3CA4A67DC12F01689DB5958B257B3C7682DDA9141AD4227\n      9DD43E13CB7D48C7A793BB9B0752B3E9C6FD5FFC9D57AE5DD1BD587651B7A3D2\n      19AFF4771696E8CEAD03A44F4DCD9E12166112B09C2F84D1800683D038EC52DA\n      E4218B0959C0A4B85810B39919AC66B0858FF0E0D0D8CEEDD8E311620481C532\n      0BAC2CDAD6B98065EAC498488B048D046A1A7D84F590202FCE0EA8EE539A4832\n      74F9AB71772B8966BDF27C505BEFB55FECB7118395CFE85BC711FEF6BF7881D3\n      CD1BD89C154D042864B16296468000B6FDD5FB2BC1FBE7E61F13957AAB2F5C11\n      95A06460F94199DA74EE98C238443098CA3160079EB8B9C89C994FECF73A8DE0\n      E71E7870FE4AB47FADF96423FE9878FD89BD78BE1AFCD8F47494D3EB697CD46D\n      FEDCF4EA7B30E5A53899E1366A93163948F44D230FB4FAE3AAC9FA712F4AF606\n      91F64BAD28B377813AA424C46AADB2CAE982520F9E39FB7DFD4351585A12D885\n      2D2AF30466AF2DCCD0B901B3F9C209004BD424CEEB0EFB4AD6D9AFBABBFD51AB\n      D5F53C7B4C464327D4195E40A3EF5D9CFD87A55A95484BCF582E1DE57612B28D\n      F92173AFF45B875C0F5CBAD7E954BC4A14A0C351FB6C69A2D41CCC4F4D0C9C94\n      EAFC3EB731DDCD2B143CEBED1D28197A5D89DFCCFAD75BBDE9C946120F4F4E35\n      6A69BC96E187C3993552B2ACD3B1F7124CF1526923392878E391FD832CF9015D\n      0ADD17F988BA7B8AAEBBC117B2E8D9A46B3A322E54666124A3D8B8771B659926\n      DF35BFF45D197D4C9313152ABC645445B54C97C1EA9BF4993BE8A3EE614C5C2F\n      C259E09A39DF0925A81A97F6D1FE44F07F8AEE270E87112D8752BC7D2278BFC3\n      EEA60E9F59C8974FA6C4AB583EAD0619D1A0B09C0836E8B9AA9F0C0F649E78D8\n      CF8593145B9EC55ABA0DA728AA4C3F9EF53FD9D9BB368CEC7B893007446F6FDF\n      37D51FBE4D875F3A2EEBA3E345671B032E96A62E2D9CBCB6BFBE09D37BF2AD5E\n      FDAE88ADB87E95B0098DCA5AFB1CC32E834DA1BC58E72B522E2CB9D9BB938D19\n      60A16E638E37768B2559322688A6D09A8935A91B7F94ABAFB0D1E786879D94CD\n      CDCCD810366A75EB86367CB71E387386F8712C974BEFF8950F7A0FAFA6790C8A\n      46C67160002AD164A0F140E64310BF1248EFF577F63656EF3C4B024B0E89441E\n      A5558C4B187B68EC9C5828D4C1972C8AE250DFB720094AB791511DA4BB198E5C\n      C7193D75C35BEF347FEAE4DCA755F7CAAB8D0F9CEAECECB3C7FBA5A042DFB320\n      E6088A72F0F6B2F1570458AB5198BA244C9F3D186E6D4DBD6D8DAD2E69BD44F1\n      848145F3A418AA3689FDD002BBD095C90A013073E3E9AF5663341DD547FDA1F3\n      50236DC4BC3F549FEFF80B27F083A52EBB5A1593E6D9C6A097D41F92AAD61569\n      8870C5B318E766B2777D6FF29E357F9A4996AAC3A4FBC2CEE4F9D374B11677A2\n      E48AFDFBF983F68D6CE89E5879308F77DB1B376BF36534C16D6276A39C67D85E\n      EE088A89C64207C7A619532CC340871774BD990111379B08EF7AFF67B1ECFF7C\n      CE1298C4B819DFFEFD2FCF071E3B092C94F22010C4920418DBD7AE0A1CFFC8EB\n      5EEFA00609CFB9EE948D30547B3E816A856B099FF2ECEB48090B318CEDA20C14\n      63A8275D7BAD900B0ECFAAD5A7AD68FFEABAFD140BE7567019A7266299CE9A29\n      09CAFE99F9C88D1936AE4D842600E92BB0F3D2DAB21B4BC8B48B914D844560B4\n      CF17E7E389FDC21C8B146404B6F7B44C1C0A06D126F1B6BF766D7179862D07B9\n      6F01322182A782DA98D6BF7A39E0CA9BF1464C21EEFBDAA7904A65062A1FCA81\n      9402C21C78A73BD86F86172E3A5316735521EB13E9B7B3E1D34FF270874E152A\n      90B290F2CD9C7C4FC0B64A55A5C9C886199AD260615AFB2422A9C7120757545F\n      6E5DEDDC78313F7C5D773B72D798FD249FF76AAB8BD32F0F6ECBA8FBE395C57B\n      B0A7C70A2664AC1500DE10A4502D2C921FB41CD1D87F02C6B8297A63817DAC87\n      F9F5AB3E364629CC8F342DBC6190B060C6063A63526DD1749CE8A1402DAD5B58\n      47E0CA4E8644F6F258336744F106924FEF1D0E35F6FD20D3A89F25CCB1D9D4FE\n      D66F77577E2C15391E9E2B1A149668B3F12081FD3537438F5627FFDEE2CA2A22\n      FE68E45B4468D98EC96AD8A9196E5FB07048CA41B510F6F7A428410B4D6D556D\n      BE71BFFCB56B0F3DFCC85D67D6AAEBBDC12BDBCF4CE6FFAC7B6D2B96EFAEADFE\n      28AA3CE9B65F6CEEBCEFC4D2F70A6F568B78D6CD3C8F7770D6D5EB3ABD89D29E\n      111FD796FE9951AE778789743C873B248956B4FC3B5373EF5E5A9ACF635FC6C5\n      646758EC0E180A33CBE343A640843B172A1FCBCA80E2C7AB3577B2E366A4F47B\n      6AFF89BCB53C71E2D68DDB9B588C5C1B344B2855F359FA0F17973FE85B9C2E44\n      C9C458BAC21975F42EF3D64BDE176E5D35955256765FB9BD736A76A11B8D2222\n      E627278FD637EF3EB1D28ABAD5927FDAF1678EE2B5A05C2D792A4F6082C161FF\n      31EA7C3A3EBA3D5477D567CF609FD12420E99B79E96115064AE5BEF12CB38FF3\n      C4AF1732DBA056036D0462329326F6C9B8E46696BC2C9317B2D18685A6C9548A\n      53629318588659F20FE8DEA5E4E46479CD771E6D54EF8AB20B884D1127774DC2\n      A115E4397E22F17E371F0CB1614162491A894ED6FC992C3B0A4469231F7853BF\n      2A8E5EC8B24BA83E68DFBEF3DC89F7D467EFDD4AD9D25CEFEC8A9FFBE0C1CD2C\n      E3562008CC244D3A49F760D86D73C9EAA862FA791789C350F6CD10DC4B592362\n      FE55223E71B4FE646F28ECAB81124D2148AA8AA336362EF976FEB2B74717ECC0\n      83ABE2A5A80676A34E5726532EFEEED2F4DB9CDA545F24155D254EDDD88F6242\n      8F70DF72494C5C8840DA1C4F1ED940ED8139E1F1C51CA7C2C25BE77848C61496\n      1436E7274E254B729BF3820C1D66D91754F4F1687BAF129670701697A686A3A5\n      320B43141AC2B59EBBB4F2D03FFFA9D1899248B29A0E10B4E8A4917D37EBD87C\n      D3B7A050A2F60B372626ABA5D52528F8514F184E9D1AC6A10DB6103E4C51042D\n      782290546231FE5832D59EDAD46641AD5A926516A5AB97B6F52B5BAD1F595AFC\n      72D07EE9C5C6FB4FA4DDA1FECB0115583CE897EE9BB59FC151C58EBBF2211958\n      F0E17196B19DBFBA8C7C77EEA18BB9EB79EE2CC2A176499AF77DD0F6A4208F07\n      EB95B2182C32FBAFBC40F7FAD374A9BD77507F6446D5239CCBE8334DCB432A8F\n      CDF5BDCDD04C3AAF56F76FEECD3D1288992C8989A3B86F53D4567274ED60EAAE\n      53EE24963C374769E7F9DD890BA7E862A9B7DB569B83C953B39B7BAF525D5D5C\n      BDCF5E88C1DEDECC4A43D759A253CFE240986BA771613F6613B3FD48D0CAA585\n      B1249C1E65BF1AA56E563A73F7FB3E83E5F017323AF430975FDE6E3F75796ECE\n      177595126983ADCD3F38CFB5A419664EC8D106E9AC77CBAB703B711569CEB4CB\n      2D4D22F60D3A365549041C0B36BD614E15E48830948C6D10B4F1DD6699ED5EE7\n      EA462A93C53B5689CB651E492EECEFE8EF0EC28969BED448C21C83AC868BECEB\n      B7241BBCE92CDC6146D9B8E8DB5F2934D572E8CF14676FDC882EC2BEC5679196\n      997D0BAE1B225A6EDF6A756E1FADDD7D4E546D48827AAD6547B93D16BD74FBF2\n      8BB327268392491C84B9CF8D4BC014C212E60C1E0DD8F2609BF6587338BCBD41\n      574E054B0F1A3901F21F340F041D3DFB344DAF0773DA7E565847F331C83AEE13\n      D654649A27B4130D33AFEF87C1249AF363A7CF70CAED1DCA6A07CFA59FFE83D7\n      1D5DDD6BEE365D673D6361B592B63B796FF4C147DFF4A8C92AA3618A38F4DE59\n      A11E4790D412E4EF198CE08E05A00B466899B6C3409D00FAF3E35C38EE46A063\n      8BDF63558B632D3AA5C146365728070891A76A98EABE346DA3EDC58AA949739A\n      E93CB5B8CF3E44AC078EFB62AFF3F2609812708B8325025C8C847F3B8B1105E6\n      C645C97ADCB9019716FB891D4FE4F9D856EDFED0FDC9F90B971242551EBBB943\n      F584C2B55496EDDB20CC1EAADC2596689362565C21E12A98FA796EB1F491D6C6\n      4C33FFE01D0F4F2C2EAFDFDEEC6D6C3EC3FBFF6E78180DCC4F2CDD7777AA3EAB\n      6F973CF9E3D5B907879A387234558A2D7AEE9976A46F197153A63D2AFF53EF30\n      1AA114A111E616F510AC17B3FC479717DEBFB8B8140D2D354D490E869CF91488\n      B031631F33C6B9BD42609569E9A08421BEC4E20A021E5743C40E52759DD2D703\n      FAECFA8D52A97124C595A8071203DCB551FABCC2FF7471E5BD4E20751CD920A1\n      84C57947237D9DB1F592FBA92BAF9497E7BA49B4BED7BB7862E9A8DDB120A031\n      D1B0E464696AA6D96B2F9F58C4FBCDB3823D3A35BF606F533AAC84AEE2F42B26\n      FD573B5BDB256FD1341AFD7865A991A7BB3F509F796BC41D914621A552377218\n      105030A4CD24E68281112FC9A1EFB94FD5735E7ABDC20794E6FDEC53B7A2C4C2\n      79A2901C437818F286D12A6A4EAF36EE71F93B3BE687C974164853F30C2882C6\n      257BDC186D27FAE840F406942D2CAD0F0F3C3D7A647666E036D75A5CF5DCBF98\n      62BFB177350CEB6766575E7FF9E51F39B1FA6E8B1DF3A4DF68F8E555E91947CA\n      496F129643A84DCFC9147347EDFE6EA773ED70A75A0BA70322BA07C6C531652C\n      E17E07A35AF58BEEE0DFEFDDB896C882DA15B2ED2014C30B978AE4DB6484A070\n      4B8F2B15AE025E9841C441DFDF987F0C552B484754063AAB50A782490D9B2A67\n      30495C8C8F12B07A53E34D8C22A8D2E3B91C3316781B5F40700447C57E7D6128\n      626F60902636DE653D93A372557BF5EBEDE1E78E766E9649B55A3A3DCC57F29C\n      05C677FC936EA9DFDFBBF3BFF99E93BFF07D5DAAEB12DA34B1655896C0456DAA\n      E2CC979DC3667EEB70F1AE73AC907F038D5EE2178930B03CA2D07A5280A20BD7\n      D1C2F89BE410D62011221C633C94F991E21960ECF5CEE8A9ABDDBF3BB7F4DA54\n      F3AFFE6AE27BE694D2F157867CA4BA4BA3F977DF2344EE6469A1F8E4DB400C62\n      338E04578C26BDF1D4C6E4E999F074A871E8D7EFB039429A819F27C605ED6C06\n      E2FB85E23836C9FA7A6A337769757FFF70FADE0932678188504F66C34134F5F6\n      95C83F7450856F56F75EB83E77DF845E71876916E660B199F650F3A5ADD9B513\n      6CD951BEC447A2FDDC6EE3EC1A5DF23A5B87B8A91BCB93B7375FA9946727E6CF\n      F66F5C4DFB9DE9B5695341890D2D0ACC706D004C08A8E783E2122442A52908E4\n      81A18F06430642DDFC3811C63FAF68C49BF9CE27BE36A9B4BBCC324BD52CF871\n      14B347C22655E5A696817022D7F1683BA9DF51624BD8C0A63BB16980E880988A\n      7194F652030B98483BDC62132639949660A39D9844D2FD34BE76D0EFB467CECC\n      933A8345ECA27006DB953BEDC995553A574E5C45B14DA99E4D7B40F069A18F6F\n      93A9B4FF2600BF4C10954E8D8DE8088DD5CE61DA058942897364510C06C0433D\n      1374AE6CF36ABDB40A5D06CF81A544C61C9BE1F28DE1C6CD174FDCBB6A518D86\n      CD46CB687921582373934BAC980DC70A27F6480ED2C1F5EB7862AE74FA3184E6\n      720B8B78E611367AF935B3FF5A65221716AB655A7930C6EDF7BCEC56E4781CCF\n      A161D4A55D8B8E423EEDD3691BFB86CCAFE1CEC4A73EF24AEB263B8A464D151D\n      65F288BA57DABD151EFCD33BDFFCE0FFCBD87B46DB765D65822BECBCCF3EF9E6\n      F4720E7A8AB6244BCE3960CA2EDB6D032E188CA2A92AAA1905157A34A3A8D035\n      6050D035E81A5D0DDD403514D1808D8D0D18D99295ACE0A7F0DE939EEE4B37E7\n      734FD867E7957ACD7DAE8CF9A72B0D8DA777D30E6BCDF97D73CDF97D0C677C59\n      BF2847943305448D8EF94B0A55CAD893BFB3042AFB8F409D73843FDFAC881E28\n      2B8E44B50E52209CE9C17409E698E49AD329A083B9EC31D193AA2BD540098D29\n      864A64799E52B2AF98E155B1B27A5CBCD8DDBE95473A01834766E928FB1613A1\n      668FD0104201AA9796C950C1453094AEDF5E7EDE34BE3077FC02B52A83C4B04D\n      8D226DCE5A99AC4A287B831F97A9DF86C6691CE1DC100C114DA59C4C7A7F6993\n      3F59BEFAE3A7CE7F944C5AD5D997366E2E89CDEF5AD197EEEC1C42F58FCF9CDA\n      94EB5C646F6BB4CF0EC434C1B5C0D4E16090C55B486E30B495A16B59B1E5DACF\n      0ED692214A11664E50886C5CB01F3BB4F0F9C9C9B9B8970EF648BDA2170A2764\n      32620A2048E9268CCA6E4081048333259D01408D40413747A3C3BE396DFDFAFE\n      AD86D36C85C6E5DEFA3A21D1E8A4C80099F907A9F90BC78EBE333386384B5C11\n      141A8CDAAF08FE9D7E2F6B8E3DB7B9C2261B71946C6FEC07D5EA0E4F2596150D\n      85A382940D60ED7A8D7776DF3679E8A2693F208D5956F00ACF5DBA27CC5FBAB3\n      B83A3BB9B31D4F52A346F854C0DF69BAEF93D516C311A85668A0CB5CB28789A3\n      135A4CA8E6B92631AA1A6A15A4E39BDF0DD06371677D6F207BF9CD961FE75928\n      402E03A68E878C68A203A677A9E393339CFEF4F4A987721705BDA0E25B1AAD18\n      CCB560F2516632D2A16A68686CDF77C8F5D5C5A9F9C9F79872CAAE0E77A3A16B\n      7FDB2F7E73F38E5D19BB17B74F0EC2B78FD9CD249189D153F5EEA4A5B27CDE69\n      10D31D06AE19040D6606C85D35C5FF79F5B1EFF56EDDD308BE509B9CE24AAF46\n      137976A89339DA6839BF976DFD7FAB1B1924322A50391AA0ACB2D899BD95F5E9\n      E80862944E150C050AC111980BDFFA60A5F9C3B3A7AAAC5813DD25127D54EF5F\n      4A7CCD089168505A31B16320C3A6D28699F1B2EA52AA3B2AF226D12C6B35521D\n      B4AB9689B0345584F942956736B5D7A8F84BD1BBCE8BF378FA01736E9DA77FD4\n      BFBEAAA2E3563027887E060DBFAA1366953073CE7ECFFFFE8FD9A5C318536F98\n      1B92312352A267292665BE7CFDF57673AC363325F394B81E68EA618FD02A2442\n      648F180228369562EE46A9DBCDE0DA48E9A0A4EF38E4BCC3AC0C6C8156C2E8E9\n      6BE1C727A75766B6BFFDC4F8BB26956B77BFDB6D3363592D4D7DE86EC3778D2C\n      82D335CB47F1D0549EB48A0CF75DD5DE7FA91F0FF7171E988E742AA89D4869D5\n      D27FE099DEC8607322351D940C4C43A4B1B3DBFBDB179AFE4277185566A473CC\n      CD2C61BDE26EAD6ECF3C38CDDA4C5FACB1EFEEBCB8549DA99BA7DB891A5684C6\n      9B3835FCEE776E8CD71AF4EEB60C04D991BBCFAFB58F2FD043CE606D1B0FAC5A\n      B37967F5558D1283C65CEFEA1B9867B5A363CA2E729E5A42072152D60FD12811\n      52516A02810B4B3971A33447D47BDDCA829377E944D81B7EB1AA49EF95CDEDAF\n      BD343B55457328E51A94573004B4A1260B8ABB896D9888A73768D1E1CDBB2A64\n      5AFF60073B44D85CA744821AC862C24931D5E95326960ED39E9FE9F56564BED0\n      D43AE864E2B59DFDE5ADFAE1697BAA92AB4873144BE74B8AD241D4DB1F4E1D3D\n      82C702FD953ACE9B50B3B04061B6B42A9530991F6014C0FB04A3C11897C40281\n      7623C8F0EBC5AC749817919D1AC8F185618ACDE1FECDD5F6DD678B46C5C83563\n      35629D0488A8089C5DDD5FEBBC317FFF51D07184E56B2162C3E429B8AAE460FF\n      A1E370AE1321750B1EDDB921885F3DF93EE41E014D122BD319892D6FE68B2F55\n      AC1E691B586582181C46308D6C2D6511F6DBBEB49362C0D4D0618A55677CE431\n      6CB55EFA9BDD67BEB68D327F35EF6DDBCE6A2FC9FBE14CA5F6E1F3F71F8B0A73\n      F58D63734D4DFEC0D8A474E005FA57624D908606E55F8DED45293B0E0783A0EF\n      57163ECAB3427CA0E45426C283A6B5520E9F16601924CBE3569A091969DEC787\n      4CED0BD155A8A753A0E05CA28E93EB45BB55F0CB3D38EAAC1B5EC3F156A2EE1B\n      831E1858958D31296CEFE2AD041A8A4C58663AD67050F6829B20A06CA9D3D249\n      6A7DA1BDF04ED73344244BC9461D956AD020012D01C2A19E41EA4CAFA95C0303\n      696862C6AD210DEDD69363DE9F5F5EBCA73AFDCE76EDD8C4144BEC95F5D537BC\n      FDBFAC445FBBBAF385D6C90788FD426DE982F42F66CEAC5351BEA9DF4D2363BD\n      B8BFECCB358937FAE8C941F27AC3594FFA79CC618EC67135FF7BC471FEEDA9D3\n      6F8B229CEC23BDD30D5B32CB66156CDFD2984E51CDA5F472A039485FEA4708D8\n      0D0E2E0B90D2C085584BD35B47C77F776B69B79F9D1D5FB8BAB6B6C86301B01C\n      E5A507D2BB3CE73F9F3A7161B7885D35F48557A07D869E31F81FBD7E7B6C6A7E\n      254DEFC8849AC6B03318600D2B4B9569AEC18429736EBBBE99E6358CCE9E3A6A\n      F5F67EA432F530C321190A0B9B79F0CBFDDB5F2DD202B941266BAE9A9B70A67B\n      C38FD893978C86A177B963A61A9B1BFBB6E14065B77C173A1698B97ECC6E8AC9\n      2AA5D7A9BC4DD16A1C2D79C6EE6E6735CE184CFC5053EF2C4443D0A9C9356038\n      6E791F397EC862C5FFD21F388DAA0CACDCA73ACD3B12579053E4686B3FDC19C4\n      45105CE583A7A3DDCFB626EF761BED5ECC86C3B0567B81A22F6DACD7265AEFF4\n      8233DD6E83A23E3652E17DBBB7DD38B690C471D61F1C9F9EA9497AB635DFB61A\n      7950FBAE1AFCCEAB4FBC7E73E9D3F3739FF4DA13FD4168DB392666C2ACA0FAE5\n      6CF7DF6FAC86145541D40825E0CF4B4D0E72816F657DEADD9E9743A12E9890A3\n      88009FB43577776B93BEBFB1B31958E8C8E4D87B0B8F52AC61724DA126686053\n      4FDFB48D9103F62F8882730D29650A47D6EC6864F428D5C8F913FAAA2428C280\n      E13507E30A96B344D230A83EDFED3CBFB9451BE35387E6B1616CEE6E46E9D0B4\n      34ED25D3A6DF901A466094EF1FFDD0FDF7FCAB1FEFB70C3B4E3C6874ECE776E4\n      28CE973707BBBBC1F99336D5A1CA4280891DAE831CF1813F60701902EC0B1736\n      4A8420CBCE014A973E9450510B91EA26343229B256C3E4B9C5E883CDF1D5A9B5\n      C71E9F7E7412D583BD677727BDB15B1B2F56DE7E6CE2E83CCE0790D6EC0A4D86\n      B200C332E9491EE55ED1DC7EE10D67DCAE1C6FC541CDACCC3AA48AB9808145C8\n      B930F6C1F45E11DC4B92F0AF9FB5458B712EBC5EFD5C5D677BFB767DEDB55BD5\n      23F5C6C916D73B2F27FD57F6456634EE9A4983D0959CC44487A3F499653342DE\n      7B16729F395DB2F5CC5AFBF08C71CC8F36D655E855ABED3BCBAF4C1E9AF6BCF6\n      FE2BB73C8F38B3754553A60A13CCC8801817257787433621A16A5CDAAFC11CE1\n      A834AA1361A54C84FBC5179BA18AFEEA95FCE67AEBD458EA8458510B7BA5F14F\n      4452A64343625A1A0346D7091F88D625574E4A620508060DF456D1DBA2AD71A6\n      7022422A7A13A7A0B9EDBA05683F85AEA695C2BAB63EBC72DB1E6F58B32D0C0E\n      2C82A7CC32602E22EC853997630B73A81568200AFA6BAAD441003DC8B2470B86\n      F3EB5805E53174A24808F8068DDA67F41ECF11492041F254655410D7B6AABD6B\n      37F53756CE1EC93DD7C9A90E5B0C2603E30A31F2C757B7D5D6E47D7318832D0E\n      826057EAF5C30943AE598CDE23264385A3B3B48C576E8A5006C7DE831AE75296\n      1B760EE38BFD3C7AF5459A2CFB9336F2872CD189CBD6FB11E7B8D8B60C669855\n      5E50265223DD8FA5CADB4767B66ECA6F7F65B1B7ED7653B926F89230BA993AE4\n      388F8CCFE0DDFDA4BFF6B6E33317B06717925B07FE7CA89CCB05F9151021808E\n      55595A28C1E001C89E8E04BF0EDC5ED0DF1DD4A383095ED881C2C941104495A6\n      F524956CC8D38C871CED22D92568A0542AB8DE61116198917D6A3C9BF55E0841\n      E3D4839A9AC84ACE49CAE8AFD124087ABC950F4C46616124B151EA88EA67C317\n      5CE73363871F95764B134DB33047EDCB044EA64C308AA37AB1EADDEC72042774\n      14BC7834947613BCE1FBBF966CE8F0F92FA7EE9EA1A237E9AF76C36253B3EBE1\n      EFB2CEED4CFCD4D899F3FBFDCE4438CFE819668EB94168E1D8347C650EC241C7\n      466B397FBD9B7D65B87FA5EA7A091CAAB0924CB464FE99D9B99F989A39D4EF50\n      1C271A6F1B6E85578DA1D1696D9BF05EA1F3174C0AD9C83010645034B8CE47CE\n      405C7CBB417ABB71EA35FF667739B2351837EF0CFA854E959A5D2968A07B7FD5\n      FB8D63476776D32430071A0F70BC9BCB376A95FFFAD22B03D389A8B195C79AF3\n      43CE31084CFE10017A4C9A8E6AFC8A4135A68E0D772A202CFA9F5B731FEDA331\n      13C6A0286EFEBBFCCE9FA561AD3E35DCD86B8C0506CD4E38F645663E60D58F51\n      9B4621B849500384A84B3D688DF0F4DD0CF563762CC28923AC1D42BEEBE54FA4\n      3B9DC207FB2350114EB73B037DE519C2197825EB0D91B6091DF748FBC8F85F6D\n      177985A41EA6150F9E2EF671D05096196DEFCA4EBF9F176B6DE7AB3BCB2F27EC\n      67C7173E4D020D7265465448AF4E7ABFDDBB7EC4F7DF4F5A2B7177FD507B7BAB\n      FFF4EAAE79686A637F5BE3C947A7661A83E4EEE943E3C49FB627BCDAC40A12BF\n      F7CA735F5DBFFAAF8F9CFE4C526C12B967C31EF0B0F3B5A4F30B3B1BB18BBC14\n      6858E4C041A1AF43E95B5A9DE8FBCEBEA53F75E9160EA668A589B8423398BE77\n      7CE624F50D1E5B860E0DAA8AD438A16D4CA15462EA4458826513544334D9CA0F\n      C6340F4028E82D2040A6AA14E02E13A128D1A6192B5EE3A4D1054FF2AF07ECBF\n      679D8D6174B836E3586698F531292C57FF22EF30F55B69E2999C358D07FFE9E7\n      E67EE8A1DC4C080F0DDE57669A0DBADD976ECC4CCFCAC3E3A545142DD5513449\n      AFC295016A2D2DFDA418158604D15B170EB979A95806A2435883D250A27E8A07\n      E08FB0DCCD5FBA1DBDBFD55E1A5FF9DB6FCFBD734636AA3B4FADCFCC1D5F7CED\n      09FBC8F8A107EE52AC2375FA248121D202EE45BF094A4C4638CF6F17FD5B3B13\n      0FCC0C9A9CBAE38175146B16CD86C8B4404580086918B95E354A848FBF88D660\n      9A4FD587D50726725758FDF195E75EC3265D78DB4966EF1A06626F88FE623A7E\n      F76C3E1552298CC4CE6CA9AE0ED852147CE8786C2795D8597F66756C76CA3AE5\n      0D569754546DD4676EDF7E79EAF884E734F69FBB5169FBF6A4CF710CDAF53983\n      F936BDB0E16DC09F88669950C3863343015AD8C2D0999A38997F1C12E1AEFCFC\n      D8228FBEF4947E13F8989F88A84A6DD033B3495144B67E91054A91A72972789D\n      A3C2AE9EA36A52489DFF3C47D02122BEDE96C8D68C30A1A8023A7E9AC270A871\n      E636D808D99B83C1B3AF9854554FCFA406735C9741A1D2000552457AFB3DECDA\n      D5D94952AD0898FAA61496A539EAD893D400954C04520FB0BCD01026633078B4\n      21E542D82785824ED994147962FB0E0AC84EBEB7B4523D392D1B3EA52E91B680\n      80AB11414A1D94FED9CD15BE72E4FDE772110606B8AA2AF0762F3D7E75F0D7BF\n      936B22A5DFB52D682E3A9BC54AB772F85D68EC42562A2169646DE9FC72F38D7C\n      EBAA5391E64488729F274CFA439D88ECC1045FC94C4FB0AAC645860AD96073E0\n      7ACD971ECB3696077B51BA56382BCADD4C21A05E3A7972E7FAEBD568F77397CE\n      9D527610C6B663EA8481CA2111386326203208D61B0658E6C9D1882E3422C129\n      3D294D05BF5F141DC95B8CCCCB3894C2A5FE2BBF108592AC84682A5122911A29\n      7538DF51BC6BD048CAA828403A98EB104E986DBD61E77FBDB7B2A95F82659405\n      85517B1D58AE8D1A3EDFD20710216C40FEB5CAF61AAEC3B22BC4A7E70F7DD06E\n      36E3C800096215E4DC739C88A78E6154390E0ABD77ECD0B737B1481D37CD1031\n      3DCDE2139A5C1FAC2F2E753E75E66DEFF11A565A5C4FFB4B281EA8FC7A127D75\n      6FAB5A6F7CAA3D736CAF57AFC2CB3E629AB5021CAE7A86A1D70F8FF358CA15CE\n      9E4EB3DF1D6CAFB8A4950A0D67B809C5B4716A7CF4DCB90BCD00857B693EE865\n      500FB5896F53A76A3835D70EB01AC72888E2DA209E90C4CCB88E6B434A068EB9\n      4365ACE4AB9EB1BCBE3FA4DEA6892FEF6D4827D8CB126496C2ED1AAD60FE71D7\n      FB6F4716AA29CF3C38531461DE13C6F576EB3FBDF4DCEBFA899AB6D25820D3A1\n      9572C3F078AEBF646808BD0AAAFAB795A650A5520C3A3C55FDB01B7CBAF01EB0\n      7DB11F15F5F67F41DB7F3EE87534D612D0FE315B714ED60227EEDF53AD3FA49C\n      F6C6F684ED2354D39BA94F71CF239167EFF1AC03E3285078B0333944E2B219BF\n      C83B34A96B001909B9D5E9EE8629342B93F25F1D4C8546977C0CA17B0E1FFB17\n      2DDFC6791B174D51540C5705CD9EEF5B8D9613034D89777B43DB5C67C98FE56B\n      87F7D02F9D3E7346F3D261E6A4A88BF07240770DB419462B54AE54ADE7EEDC6E\n      CC1DED0FA2ACD73F3A3DD9DBD838D1ACDFD39E3057F73E7CE4C2C9E6216939AF\n      07C62FBEF0D7E765F8CF1D3F67B88F419EC032FD6F2683FF6D6DA9E761E8F6D0\n      B1D883C2A627C186FC2D7E98E57F19CC64E1D2A0199AC50D2E4F51F70333470F\n      05FA6D0F2A2C168A7B060D906A2B32A9F380529E4D61A44127020B0E2CF4CF29\n      DD47117A931782FC0CD43E4A937AF857E36BBD1DB90DB23CA0DC580D79C1D45A\n      BDB255A93EBFBEFBE46077BD61342C32CF64ADEC2B3B4283A99C69309805AA32\n      597FE4473F3CF9B10B03BF67B39E13277BAFBFA191EBF485F3CA05D52E902482\n      29D70A9C662AE8AB1FC98AE052695D9552D826B04338E787C36E9872CCC004CC\n      08131CEA4D8016B7D0EBEBC30FB65BB7C7561E7B7CE2A109A35EDD7B7673EAF0\n      89D55B2FC6529C7EDF23CCED0A1443FFBF02FF212C3DFDEC241D481C59616DEF\n      F29ED952C17D8DFD28092A175CEF302442285783B3241CE4C01165945E5FC95E\n      DC3422612D28E7FE26B775866EECBC782B5A8D8EBEEBAEA8B1AAACB4B23DD97F\n      AA57BBD014C712C1959D55537B682EF3FDE7B6263E7846B4100DF1E6F39BCDF1\n      8673D2EFACDD369246A33A7FE7CEAB13C775ACF7F69F5F0DA6036BA6A6542445\n      8E0A06672D2074804B622E3088D4CB7270029A65F45E038D5B65B1E0E4F94F7D\n      03F78ACFD4FE764F3C7ECD38E52733384F8BBA26B5FA253B16CB35BACDA5DEFE\n      2AB04C32788353E4542E5239A6AFD385B1421A61EC18A4813D291D9D81FDC2B3\n      AD149A85986B31DB71F778F78997D1A05F3F3541DA46CE13CBB081872980273A\n      9FF5BB7DA315B8132DBD1575DA2BFDE741E1B804D43A3E1B84389ADD29E56009\n      078188429F6329D96195AE4C1AE0C02197C845BFE2D5454DBCBA9EA9DC3E3FA7\n      59902BAD02E4E5A80B5AB5097265FABB8B2B62F9E40FDF978A501344D01635EC\n      91659F240C6C09A586E2A01E0E4239D19EB8BD65B72EA1B9FB0BCFC77CA8F901\n      D59B6E676B7FF179DFC8CC56DFB2ABAAC8841F2759EAC54DAA576CBF4F1B26A9\n      B94552B01DF5DA53EBCB579A719EAF17BBAFE7FE2D5E8F25C7C95075C379DFFB\n      E283E7CF633A1E32274F84CA90EB8027DC489D6E648C012518220EDC45F5EEA3\n      50F8C4E807752B0E1A64462ABFA5238C04B168E5330626134C7339A5F77591C9\n      98A13D29F7B018501C2A9982CC80DC251510F7325011D8ABB878696F77372AA0\n      62CC47B6A60C58E15B4F840EC83E6A2268801E9991E2C251E243EDF68782F159\n      C66C13347CAC42F826911A117B2D1E659A614406D9A0E265163D9FF61787693F\n      D1DBDA65C8DE32B3059BFDDAF4230F3A7E3FDF897B79C56A2DAABD17DCF06526\n      AEAFEC3D303F7F56E54704AA23AFE69B4DDB30B2842AACEF0B5412E24C47CBDB\n      35F72F64F25B5BAB5D2C4BDD4AA0030627152E9B08F9C028CAFA2FB44DA0C4D0\n      5C191D6670F4AB3FD5A468CA774E8E8D1F0E2A0D45AA985A98244992711E86E1\n      ADA0FEBAE28FAF6B943ABFB4B1B55AE448735B0187BB2087ABF8672BDEAFCECD\n      540A39B40DCE999B903DABF2DB49E77FEC6DF50D3F2B34FFA516933AA0A7967E\n      E28A1785F4CC8A4683C39440559670382BE78E941703FBC7CF9C3FDDCF0E0D98\n      5F6FFC06EDFFF6AD9B3DBD0DFDAA1A0E8E7B9E278A5AD39E88B28F54262F500D\n      37D3AE5DD9B3D42D992C25834E3F0CA3C44578A2D99C1B6BD52C9B13B1A1A275\n      D6AFA79E06C6E02795A4EB71B49E8818FA49E0090C7520B06C279747504567B4\n      F37EE51D2DFF42C33ADC746BA6A161B75F69DA7690F7B26CB38B874555D0CF7B\n      BDC76E2C3FD4A8FCFCF1BB8E169144439D63ADD0D8A937BF85C228F0D6FBC36F\n      EDADE744EF944180AC4CA7B7B976A3E2B0D76E7FFED499B73527E6BD7AD01A5F\n      22E81B9DADC517BEFE530B634764232F445264987ACF0AF16F576EDE866E31DB\n      12796A438554E7B3B7B83CBF3F738FDF6C6F560618DD8E13EBE1F1F94962ECB1\n      C1CD64EF53A45E6B35B1606522446302B7A901D551476741047EB7B04BA16E31\n      6A9CF93B698911682DAB6FA50BA0E482575238F48E881A20D42334E5062F0C35\n      39F1E5FD3BCFE51DD7B6A6121430EC578DAAE00BA6A7332E8339D082B8FC9E2F\n      3C7CEE271F298A6D74FD56B4B4D1BCFF623E51A59A98951A1B84F88478947A40\n      07A10E4AD59B02E5501AC5D4901C7A0680ADD2122FEBD00FDEDB31E9D93616AF\n      ADE2C58DE8C313EDEB8DD5279F9E7ADF216C5A9D6756264F9E5E5D7CB9BFD3BB\n      F0B1F767D34921F683D4471683F02C6D9D08158E859918DC4F6FE5BB2B2B0BEF\n      58E09E4C44DBF7CED1729A5B6F7BBDD9CC021B808A63B1DB4DBE79CBDA4BC55C\n      5E79703CC5CC0ADCECFA70E7F1D5A38F5E88CEEC33276AACCFE4CF256292D18B\n      9AAB3B34F6F3CA906EAB9DC7D79A17E7BC536332E19BCFAD4E4C8C1BA7839D3B\n      D7CDA8D10AE6EF2CBF3A75BAE50AB3F7E266E570D39CAAEA4C2F41469903DF17\n      80CB753CE4BC18A98F013A07E34F10E635A1BDD664FEC9739FFA3AE6DDCFE47F\n      784DDCD80CEEAFEF37B89D519F0964736E5B184ABCA0564F4955E3C3FE4D665A\n      9E7F9723DA4C70C3321D666A42A69764057904E9B4256CCDF0AD1C2A9C79CDD4\n      8040BEB0D27B61B1757CC2395A9532C4C034F486F7B9E49A5D9344757ABDCAFC\n      0488886B8E085A4626D4CBA032A8998527A98D8903CA8BD0965A28E8724830CC\n      D15050928504904B1521952BA69F5BC54BADBDE717278FCDB3F91A93DC65061C\n      911A14EA057A779BACF89D376EA4372F7CE621EE3368E6D1E19F58A5C9EF68EA\n      A750A5BCA9A640DC21B408E5AD354AA7D1F14778D042857EF19A72C1986B78FD\n      856867A935C19CC065451781B5B622A965C494EFEA744371DD355D27DFB2BEFB\n      FB8BABABF59DA4BF898777686339AFF69268B8BB798F1FFCCCA5FB27D27C335A\n      6D37ADD34CB5B039040127586C6A64E8484A41A8B25F5481622B58A41D983C8C\n      F673D928532AD99191C8135623F4032DA51528CB403BACC8509AF03893A1441D\n      253A520C888AF567C0E71EFD354FD7BB614A50BDE6DBA6B79FE4BB515694C281\n      B49CA0C7A5B1C45B2B8C42B364C1F4A6341D09758158A4F7D7821F9B3A7A58B3\n      3C15EBD7EBC15429E1B6AC247C3A75ECE6D8E3ACF76D34B81C75AF77F288003C\n      2F8DD52D5448FD533E3936FDEFBD0B93BB9B3D374930A8A82F89DD27FCF05B61\n      8499F98199A9E9B0336F7B4DB35E6785A32FD5411A8CE184D9CACC045A26EC29\n      94FD79D27BB61B4A038422C154A760B3C43C6AB8E38A4C786EDD30EB084D7841\n      C57763CC7A4592F6FB0CDA5EF08D7ED8112224BC9BF146C39AABD4E72DE794E9\n      1FA68EBB3FFC35BE49DB53AB83F84E77BFCBA00C800BE5026690CCA444B19F98\n      6CFDC776B339E0031BEB1F5824EAC934FE3D877D736DDF968E83ACC895704A95\n      827F26D8A0C0A88BC80DD80456AE4C389DA54A2F45919C996ECE17F90F8D4F3F\n      94999352FD7E85FD49A7133BD5BDBD9E91A756C28E1E1917457154FAF77A533B\n      83DE96235F43D952DCD91BB071441E30ECBBFDDAE12098F1DC0990A3CCC10351\n      6F0C229D1C6AA04C037E9B740DBCC3D9562FD91A648B69FE32E74B4815C2D414\n      00510F896113E5271ACEF9B6F9AEB1FAC3B5D618754CBF364CB3224CC87E18F4\n      A33FAE8FFDEA6B2FDD40EA9353933F3D373E2D3A34CEABA21567D6BE46A3546C\n      4B7599659D0C9459946F5FEEAE862D002DD5FDE81F9D3D7DBAC067C766BCE6F4\n      96ED5DC9D4D3DFF9832FCCFAC742BBE0AC30905738B7ACE0E7B66E3E99652682\n      599190E4709ACEE45BF43D399822C4D0CF8C4B77A7B25A065DD7D58A5DE43929\n      D4E9F9F11FCA6DBD1C5091691ED442A425D018A181411C0BFC27742284961024\n      4A154FF4F7122114D3607801447FE1A22428CF15D221262E8C84A92EA1AFF2E8\n      59D6DBB28D66AB9D266C27CB52A561ABD934A429D349DB19D3095FE737CF2AE2\n      8E3F412E7DFEC1131FBB7BF585A7EA958AFFC8BD7D195761E3820D33255ED948\n      E8C0294469E93272031E293C41850D545434F406592E6877055BF948C96E847B\n      AE8DD3576F183776931F9E6F5FB6D79E7D6EE6D31745CEBA4F2D4D9C3EB571F3\n      B5C1CD9D331F78677A5E23F4FD7AE8318F9BA274E91CF50441FC153826EB2FDC\n      AC56DDE0DEB94C51CB38468D403F99CC019D133B03775766E6344AC36F5CA7CB\n      BD7C226EBD772ED790AFA9AADBE6FA1FBF3E7DD7B1FC5195D04EABBB507C2F1F\n      D09DE03ECF00492D9FD77219A2F0E93D64E2F623A7F5CED87C7E7922A89B77CF\n      ECDC7CD54C1A2D6FEECEF22BB3E726AC4C8497F7BC5393B46DA922C47076017E\n      42E06A0C23BF3A283298212CD5A5E190A9EC36B4C09ADA649513E77EF8EB58BC\n      F0BEDDBFBC12E8B473CEEBD8A9CF1D9749BD35994D41ED6C98EB686A3A2EE576\n      7F29B6FD9A7F97CFDB85FE99A6E14A10D5C160746A952378D2C696A7A187124C\n      FAB6581FECFCF50B4DD7F72FCE08272179841C1222E54B1F92B20657BD62A73F\n      689E9E276D5FC1888053BAC84022C0423F734FEF3D4A7C585A3A144BBDD8538C\n      73104E18650698FDD51908743E88728915443B61B83B983E7D525A5C67610A2E\n      BD600E2228933225AA607FB874A7FFFAB11FBADF98D009A6D4EF13E5A418E565\n      6F51A91E8F60085DE3002A13BCBA920F0DE7D47B446356471943870D0E82136C\n      6F75EBDAE58AEA555B06B153FD86C01DC3202A4CD4D0187698E9066E73E2DA13\n      EB57BEB11D27C1729ADE10F906B53687388DF884C57FF4A173EE46B8F7C6FAF1\n      C3F5D393C682548ED0F8898CF4E34A6BE98344C8E1B2244808427B1151E518D3\n      68F3BDD9B88D47595081E316F46A967F968E2ADD8232C5321CA5BCCF645FAA1E\n      525D0565B144B28C318EE4EA58F04AAF73A50B0E240E07F13A0572E7603343CA\n      0D4EA179090FDE929E3644021B74326116522A3EA7F08F9E387F46293BEEEBC0\n      AF194FC5F20DAA5739AB571BEB8C7D67D8FD467FE78D24739133ED05E3AE57F3\n      1C47BF5BCE7396CF62F31FCE9EAEA7991F75321E0FACEA1E939BBC7BCD2AFE76\n      6BFB687BE241CB5E20D2378D0941E611F5F31C1A562BDED0716E6272352B9EE9\n      749E1F0E9672E608348D9C591BCFFA9579D75AA8B90B357F8C90B624D54CEF06\n      A0D1259783A6DDA8068E8DCC717A12F530594FD25BDD9E668A6B9D6E27892B88\n      5483E0C4C4DC9F36B7E48DE1DD53C79F5F5F5A2F12A9A851002491D03307424A\n      3F737CFE5F7B5EA59F62DF8F24BF1525CF18EAEB88BFB0D537334BFFAEAE665B\n      06AB47E81ECB39128C698CA7D3FBCB38793D0D35EAF28599132B037394645A8A\n      4791FF8F8F1D3F97318BA7CFCC55FFDBCD1BD753893D92EAD758F0E9BA6FE564\n      C21AEFF48637D2C1064F1B269AA9572F55BC771AC125B35257858B85E61C1E2F\n      2D308CF2688B0B6159D050834461CADC84837A8D4763626F12E3B5387D65307C\n      23CF6F0CFB3B294DA9816C537F8B5764A72DF6C8C2F4474E1EBDA73E8EF7BBBC\n      08150B65B4970D0EFD695EFC87F545EEA39F9CAEFE64A3322BCC38B5BCD8AEA6\n      452C87EBAED171EA5DA1012CDF2DD23D472DB2E1CBFB1D91A387AAE4F313A7DF\n      3775DCA836F75BED1787C9B37FF5875F9CAA1D2EECBECB39E5F57DB1E3B6FE55\n      B2F5077BDB06AAF89C8438D5E9005470DF1A27B410A8A61F9447A12718A6860D\n      4234B703A1494A1FAD4FBFB3B960159D3CCDF43AF4146A10D2C2B8C645DB307C\n      93581A4DD944EA88078D98074E88F24D704A4B0948548E2D21C0A590090719F4\n      B8B90CD552696273D156DF76F32F6D6CEEB1B4516B6BFCA35F826FDA1AB90654\n      55899A40641C1B2E26BE6F09191A4EF2F61F7EBB73EF54EDBE63B10F39CE8129\n      3DCDFF1C430749E00930665DA6607CA0AA014950FF9982C428D1EBA34C84504A\n      D21C28166C3FC63DCF4583E7AF7ACBDDFCB327EA4FB2A5E75E98FF91B78B34EB\n      3E7567F2E4D1DD95A5E1B5BDA30F5C4C1EB1733BAC779CD4675EA14342C1A88E\n      49AE296D65E8800CFA2FAB57568F3E7C8A37F4D369533AAB435262420C03611A\n      890B17ACDFB22796B3579665331A7BF734F3AC61236DF4DDEC1BDB8567041F6C\n      0DD056431ECA5FCF3B83B5C97BC614E706AE140ED3F755BC1245773A131FB824\n      3DB6F9FC8D0672BDB71FDD59BA6EA58DA63D79FBCEF7E62FCE1AC322BAD2F3CE\n      4D2B5F49313421D78108BA8635A41C3280523598BB2850CE17701246C19E4AFF\n      B551544E9CD78990FFDE3DCB2FBD367378CA59707AAC6771EA1B1637F56E9396\n      F48B3DA6B830EB9864D5DE72DFAD54FDBBEA45BB80B84F7C70CCB509D29B4753\n      70C33440AAC1614C99A68B867CFFD95707B7968EDC7B4AB674A6C93589633CE3\n      A6E160100D20D4255DDE8D92FAF979D5B075E430A42BB07EB87A87EA584E05AA\n      2023A0C8077931F0BCE1E0E60DCD0AA5A51B82A151309B51057862E1C029CCB5\n      C53BCD230B6E35006178137A674194532F46CA04618AA5F4CBDBFD62B5FA8EA3\n      E6AC1DF1D82536E5261AF57FE925527EAD86CA3031431C0DE1D0EE4AB897560E\n      3D48C64E72BD8CF47D12572F6DCAA26873BD77E3B245A389E9000CEC539D3019\n      6699CADC645FF18135D8202F3CB1D9EFD8C334BF95ABEBDCD8167C10A6768E1F\n      39B2E0E0FEE595B5B71D5EF8717FE21C8B733FEB115C9156A9A40AA71765D7A8\n      8EACC008C1AC92188665A1912D71A9A17460C8581243C14706D9B2EC02D0A41F\n      1221C8C1EB9BC95091AA61A1F6B9EC22D4C72A5432963C953C13FA5DE93BB537\n      2CFCECEEEE56065564503187F358567AAC1D80687D59E95B4B847A45B8A5307A\n      42E518429FA8CFBCBB36666934410A076B5C6C000452B425832D9BFE49BEF595\n      AD8D71BF7E37197F57FDF0E9C95924339186380E45916BCE5EE1469BEA88DC31\n      09D734A987D05A9EEC09BEC892E522BC50AFDF5DD09661D99E335D0C6B82E814\n      6538F63AE2CF8AF89B79FCECA0580B73DF30175CF73EC33E4FBD77B8A26D3975\n      53132E91D24CDFABA579A7DE20A6993B16C42B811CBD80B1C3F242EF1C971860\n      7DAE81237174EAD8467891A267D3F0E9787F53F23E8D9CAE3C12D407926FCBBC\n      93327CA0EBA1E3A21160FE2F4E1EF9A71635D2C2305D0D34AEF3EC55CBFA9BCD\n      BD97C3B40B8E42906D031BBDCDB17EC49BBFDB194FA33CAFD8DFB5E3FF67E5B5\n      5B29D7FB2AC7A6F03452CBDFCDADFF74F4C2854162E6C3A2ED2CD7AAFFC76B2F\n      BFE0997CAE79EDFA46CD420DECEACD1BB3622F2F5C1B9D68353E677A97DCC699\n      8C563486F3F5C2649A771A70D28122BDB84B17271DDA423B774ACB040ECA77A0\n      8FAAB10494B78885989109B269A2C5B4FF1759B454B0A5FD2CC90CBDE753BD4C\n      6C7EB6EE7F7EFEF0A39E77C8D7C96590C65B13B7EB97BDDA3F595E7C91263304\n      FDCBC3E39F1A3BE684308DA6E17D2C863D8506B43AA039172CEA47B18617AEFB\n      64D25B8A9379A9BE78E8FC596579F5201B6F2E86F19DE79EFAC953A76694D111\n      1D9BE6339A1F58D55F91C35F5ABE2D84E12ACD9819D29B927168B77D0B1F6E39\n      4000DD78301104DED42E36393414C90A4217AB63EFA8CDDA9D30B27BAD403F54\n      E4295541AA86509B50488706C40562636EE3DC00990F74A0A374B019F56A294D\n      ECD1E87802F0052B246F6454152A21451CE4AAC2ECD0089E76D46FE7BBCF1761\n      9D38B3CAB441C1CDA8606AF1A846C414B5260CCF301CCD177C94593EBBFB27DF\n      D7FCF885C8D2809ED97A55429F8463D080824148D97386461A94EA4D692998FF\n      85B54B39878841CA234C1D3F3325F633D4776CD979EA7BEDBD3CF9F431E79B83\n      B5975E9DFFD107799C75BF7B7BEAECA9DDEB8BF12BBB0BF79C293EDA888D6E63\n      DF29FCB2391215CC141C39A6D038013AF669EC2E3D7BABD16AD6CE8C0BB7A0F4\n      0C32AD9882898FC9217C319BE9474C5F1F6E3DF1B2E1F4C61E9A6093D5D80F6B\n      435BBC26571797173E7852D563AA6CB66FAF5D5D9C3E3DED003B261AAA133FE0\n      8B51F8D4CAE47B2E88C3D6D6B3D7EB85E9BFFDF8CEC69235AC34CDD68D3B970F\n      DDB360862C5F8CEC3353A99D519ED8A3BE79FD305201DDDE104EB1A6670A8C24\n      2938684960576639DCC10E12E12F9FDF0E576AA7A62C4F1545A81F95EB068C16\n      C2CA6CE4176BA531F7544E07ADEECABE1B54BC8BADBC9DC340AA8EDB3AAE3992\n      583AAD3AC874293672F0B5353D54E55736B79F7ED19D705B17E7941A82FD0C0C\n      1F80140B58D910644B97F455981595B3B3B2618A02D9CA1778A4EAA9C0670157\n      1494642B188CF60AA58AD170372E9BB140370ED08DCEFA8C43C6ABD3B5DEA03B\n      6C9C3F11C30FC730E984CA550963C2521A729086B5DFBF935432F77C939E6E0E\n      44ECE8F507DDA79A3D0BE83146907200302A185D329040F16A7FB76F54CFF953\n      7749C3D5E91452459E5399E9C7992EBDD25B596C58D86D56B99920DC27BC4024\n      20B4B1FF527CE52F76B7569C0E1637546F39161DD9D888F241D2E3095B702C54\n      141F3D7DE4E3870F9FEBE48D22193A61666318BE04B16670082EC72847D67DA0\n      5D8E356C354B35196087A319C2837E51B0C6E4C065CBA6603C92B410E5F130C9\n      A44A342344FD427610EA12BC2F44C88B4470565A6F6B7C911B7E4AF05691BFDE\n      D95DE52C87A28B85991A4D0389D1683C416F2DCE200F592948BD628DB61EAAD5\n      3ED15A988A120F834090622C705D5C48271783F1992F2FDDF8CE70F78185E39F\n      98BFEB7CE1D238DD186E7650A2B15D56E42008685B7ABD10964E578DAA53C974\n      0C976CABDFD927EECD34713C75C294E7A4DFE27EDD7203B2CFBCC6A6E9BC54C4\n      8F6DADBC3A1CEE09D442E8DE5AFBDD5373472D3A6514BE6455910630B0A19FB2\n      E81356687C6EE89B95A96019D5E8B3ACC54B9274E3AA5FD19496E4CC9506DC3B\n      D4244862183DCFD8B18D7EE06CA5E1AB4BE1AD5EEFAA8C07182504955EB25472\n      59B275EA22F96F4E1DFF69C55BD4EEE6AC8BC5ED22BFC2D01B5EF09D41EF76D8\n      B7F2E20C46EF9F9D7CCFF4F4429FE130340D53162A76BC2748FA7F6F2CDFE400\n      4D72962DF8D62F2C9CFBA141DE505168EB355615D8FFADC1FAEF90FE625AD452\n      DB91CE40E41AFFBB32BB189047C68287C7260FEDB06964DB1AD2E07450C1434B\n      EF1762806A815998542F109D8AC1F0D0910C9A4B9529895BE24786C1F4C597C8\n      8A72C904778CCC40776A5E27CAEE84D98BFBE153FBC3DB0A84A534BA0D8AE4ED\n      75F30B174F3FDC6878FD417B67FB8A32FF18D9BFBE7823C2E85E1F7D60EC588D\n      5B37BABBA12BA07B0999213707860E8E859B70AE3156C5DFC4B4976BAA2A5B4A\n      40A0C7D801274E8CF3E803478FBD77E1689B87AD616732CC9811FC8D6DFE87D7\n      AF5C0735C5D199063C6EF6962B163F58C784AE04844DD3C9596E2339496D1814\n      95C5872AF589F698C184A3848FB08FC59861B5106E601D17A09F987B342B27BD\n      0E7E1EFEC1DF00E71B8030CB9A0D678C269AB4214DA432ACE14081721C6173BB\n      56DB9E187B6C4D07915DE4800E88234DDFC01E8D1D33D7EC7096D6CCCC702A0D\n      53530494546AECDECF3D38F1B947851B490D2A3482978E65D630F64AB74203BF\n      29337EA00105FDAC509FD7B1B7A01224C32111F25296B99BD3BE45D9DE932F4C\n      6456FC9149F2F54EB8B432FEA9FBD3FEA0F7D2F2CCC5F3DBCF5D66D7C3B13387\n      C93F981C5A9D462FE00EB32091E8DF8C0B42C1A9B300A84C6D3B5CECE52BF1D8\n      5DF3C9E4AE2BEF96AE971165731DCBADB222995B3A11EE195B7FFB82956FB41E\n      9ECEE7AAD218D82991FBFEAD27AECD5E385A39EDC5B84F5163E73B77C66A15EF\n      7C35F314EED13C709D2D1E7FF5A67566CC7F74AEF3D2A2B55B046F3FB5DDDBB2\n      3A66CB6EDD587EE9D0A5055307B82546CF4F4624B6786230566A202A2393242B\n      5BFE4A6D6A986B111A17C852670958BDD230D83F5E26C29F994D66A479AA258A\n      D4928C52A1A8A54963610E3D4D4E57F4DF093A1B1B83F1EECA9E53F3BDF36359\n      13A6F51D5213868D2C416C098252C425181831B67C73ADE0CFDC8E37B6AA9726\n      691B7CD0C0684D832969E224E301653671521BEDAB4191FBA7A755DB419C982A\n      50D8843977706DD5C8BA2A719520AFB439D0893083D3DFB23FBF9C6983397A10\n      B5053684A5D54AAEDCAEB626D07890F89A96C21404E44B80DD19A40C536D27FB\n      F4BFBC44268871CCAB3E7C24A64C3F234FDA65A651A59424F41515D0735E58FA\n      2A31C76C6BB0DB91E4706D4ABF5D4D39600413644F44068577DE63D75E8D3636\n      9C9A6B4D604834522718CB40F5D7BFBE71FB2BB9418EBD38B8F59CD7DF0A35E3\n      9CBCB593C43C44FAE922F4D92377FD737FFAECFE665137762BA8CA425FF0C204\n      C788D28118182126B8343A21652FAD414AE5FB520CF2CD09FA7264704407F181\n      80A22A6778CB44A8097B2254A48A0CF7B8D8537817AB011660CD2A65AA58C8D2\n      61926CCF4C93B4A8F8FE1BFBDB6FA451EA18256AB44C0167CD0506336F80CF6F\n      49B80305C81ADE899B630000FFFF49444154EA4B71C514C29F9E39728EBAED82\n      37A06A5BE496CE8FA42E0CFD1C7FC7155FBE75EB8BA7EFFB78E3E8F85E1CC5DD\n      657B780BF77768D2C34A93AD814486E9C5A268A8ECDDD81D27F5D5CDC144DD8D\n      C3C1AE5DDBE46ACC2D168C7C01FB27D9E478417AF6DEE521FBB334FB1ACD7748\n      6239C623F5F627BCB17729F778ACDFE6403FE20DB9BFD91CABE57A59EB9764C1\n      0C288143035B08134A3150F886563C9D869B6E51E8F86A151A4E537054C941E7\n      5DFF4FD1C0AA9633A3DFC7BCB833FEEED764F1241DFEF9F6E24AD21709D4A54B\n      ED12BDC9F44E12FFEBE9E3FFACE06385D537C4862557F27CCDAA7C797FEFB174\n      A021C6516EFCA3C9C3EFF58320E9E5463EB40AFDAAEB5D3925EAEBCDFA2F87CB\n      5FE9EC6485C616E881B1899F9F3CF260AF1F7A9D7EC31EDBF202DAFC7F8BCEBF\n      D9BD1513B290D72972776D54A9E08F8FD73F5935CEC73BE3593A306710B899C8\n      348047AFC99D7E3BB494A1700476F4BAD1D15AFF7D21341B56C87272FDEA514E\n      50E8A89C704854509C07F33D9D27DA03185CCBAADE9315F9155E3CBF126EAEC6\n      11A2911523839FE1E82726A67EF4C87D4A3C3F34EB9755ED3FBF74ED5A9CE82C\n      55277848C9501D1C3B9703B0967EBB90418A1454F860393B34814F72473FBA02\n      5249824B58A51C159D29D02308BDA7EE9FF6BD5A307EC7A9FFF295571EE3716A\n      424B95061EC55BC5695014A50C7861795848F8818F9846BE7A8B09306176CDE3\n      274EFED4AE4A92C4161A5888C0307D8A6A424C5043432B8F82A227F78DC2D210\n      E2E06052FDBD44584E5208D0CDD71F5CA39904FB1C6C17F5B5C606BA5E119703\n      76636DEB54CF3F317BFA8936FE52BC418662B2306D4BBF9EAEEF7257F1315999\n      524D221DDAAA78329EEE6ECF1EAA9CFEF98FF18767A97E4AD0F6EA425BABBE1B\n      A1AFC92AAF01FE534A5095BA8BD22813212F132150108935FA4D944E84041261\n      472742528B1FADA26FECCA4E2FF8F85DC39DDDFEB5ADB9B3A7B69FB96CAC4A73\n      A66E7F7A320DE25A0F46E929B459EA7DA24100D3D0C9CD1C6840D150317787DF\n      59B75AA6B82F73F8255569E448E81CA8437E0E7D88A923088EBC9DC7BE4B3B77\n      DA0FCF25F39E8963C2102A9A6B4FDCA87B95FA0313835A57294F3D3FF4A2CCBE\n      AF168EA94A371878869739E69FDC5CF792994F5FCC6F6D26AF6FB51E3ABBA783\n      F91E6DB9134BAB2FCF9C9D36BB995C97F4C254AA314611911CF03C24C242D1BC\n      1C6241E55CBA7E1E820826802428095447D1C23B7EFE935FC7BB3F77B432C5ED\n      393EB473FDDE03E19832537E1149E18966BE952B56382DBD40C6BB373B55DF73\n      CEB5D198468C4C7952E34A93B40CE42333134EC6909DD3A84E27C5CBE9C677AE\n      D45AAA76DE2B82388342AFEB146065A470C11D0D4D345EA847377A862DECA335\n      D99CE0B84EC1B642336B0363701BE2461D18A1B0C03D119A6B8648DF2498CE3A\n      A5296CAE70A433609E4BCBA8F2BEECECAD8DCFCF184E4320073A2F75042F791B\n      1C014A860D11EDAD1ABF79CD99ACF69BCABB77CE1A7334C564384F1DE26AC692\n      405F08B735D5577E0E043A07F7032EFAAB3CCCABED07917B8253A5D3201C2560\n      A7205D33072782EEE26BE2E67AD5AB39E319ABDC40D84D16CF3EFDDFF73A5BD1\n      000F9786EA1525D70BD68FF820E230A328D58F4D4F7CE6D0A1D7766FA45EF1A1\n      DADCC9FD0235DC9EA9434FA94806DE8BA5ED309CD680752DB5F58336D4E80CB3\n      AC081F405B1D5BA031142A5AA529181A91E5B292AC2A5191A7B84871C2E89E82\n      B6CC3D2A06D0F203AED27D872E39E2998DDD6E264048C473E31CA6290C8D9279\n      29A1588AB7C14F7B73731F7CBC69BF8BBF7F4C391ACB2ABFC66281A820830D3F\n      D29AF887F6442BCDC01B0C6781A5AA98889833B7BAE758FF75A3FBF0F8A99FF5\n      C768BCF38AD1BDAEC38EA0A934B6395943C60D21BAB60E1B7D9E7475747A68E1\n      7CB0959E55C1AC30A3AC7FDBE8C70D3C67D9F7A7F6BC90A119BF6ACA5F6663B7\n      7617335ECC20E38375EF1FD46B97945BC3E00D332C65A65C4E4D81D3DA88531F\n      7456E0035182B2BF4096D65E6543212F4AD360551639473E73E51722F0872C3D\n      5915A0264DA16A16153C5FA5FC0FF6FB7F34C8D7852C44854B9D69D30AC6BF78\n      71FEB349D0486D66683AB8B71A982F0E064B06BE1285833DF585F6F18F617782\n      8485A55F8A8384CFC0282F342D169AE44E50FDAD1B4BDF8A32E5D20F555AFFAE\n      317D7E77538EB181ADF373EB0DA7F2E5DDE11F6EED6C3A82BA6C4E193F52215F\n      085A2774B09274E054128358B2078A0C0639D06427A569EC48B3BD744953A377\n      8B4BC991D2470F3CAEE13C89C2A9334C85A3B2C600FFE7225F382295435BA92A\n      F157FBC537BBE9EFF6F6BE2750567135D139CEC5A3274FFDFB22AA5BB413547E\n      7377E7FF5ADBEC063A91BA4666E97844342932B96D150E0245E072301D260FC8\n      C85014838EBE69E37C94D8884CF32CCA3DC62B06D159517FAF6C38D6856AE3C1\n      6367AFDEBEF9F8EA9DA1FE62BDEE8B3717217AB363468D00F3283D953747DE74\n      B4573FE0D9840FDA2B4BEC0903D71AB43F32B970CC6FBCE8AE4D46EAA4AA4C14\n      145A85956C1A749CD01A52B6093D7C301CA4530083D680B2211F7E8524A55957\n      79C442CBC678BD56E0A08291129DC21995250CCECD5D625EF1E81F76579F6183\n      C6ECD4BC5F439B9D38CD9105150A1B893A130D4DD0090DBC8AA348D332352B15\n      3C9A3F34F5C0CFFF4FE2FEA63594B25A83DE62AC9F2808C7300B7E8F03898F6B\n      A6AF919D015DAD50A2E5205909CD108C30532528D7A8B8CB4976FB5BCF9C6E2C\n      A46F9B527F79CDC8FBD6C72E6CDE5C153793B9C3A7BA2FBF4CBA3CB650FBE327\n      8D294A0728F176BCAC817000E61738B1870231195759E4C889A15B3CB7DBEFEC\n      8DBFFB5C36360D926FCA330F949B8B58E694B83AB9771FFF5E7AE3FACC3B16A2\n      E33AD04416B39CA23E7861476E158DF79E099B6F100D902EDBFCA65179D7D470\n      6ACB4C30D3A489BBD6B3E8F26BB7E7DE7D7E1CF1C12BAFD7DEF14058F4D97ED4\n      1A9BBD79EBCAA113937837123BD43E5F4B9D0867B99D9A9AC5489143ED5B7018\n      25848E10784BA14DDCCCB4231F4AE4EE90B971E61D7DDB07BF83F77FFE68FDB0\n      A526E38468E6E4F9CA46285366A681A1C9AA681F657164370C62B6C35B7DC776\n      DC732D344994E60B5025C726AD520C9DB5C2669A30290D608656F2ECF6F6B5A5\n      C9930DEF30E14E0AE39C42330C108F5612C42D74A0B5442DBD15128B998702D5\n      9E40B4A9F7AC466B60ECABF788B0386D28FDC335AE127A071714C708C7655BC8\n      C8D2A05038451A6F31621A5EBA9B856167ECD02C362A1AECC28C3C18C7C1C124\n      D65F0CB088F57757D0AFBF583D3EB96947953393F5432DE89F3515279AA46170\n      B3048B7A70DAB1391538E74639B6AED1FA20B1EDA366FDACB27D905B3EA8A6A6\n      88EB7855A0B8C76E6E6FBE76AB316554E728EF916B5FE9BDF1BC0813BC83F35B\n      61FA9A29B6F6E32C31869A3B17FC6CADF69EBB4EAEDC7EA91DC63F75E6DC9142\n      73BE2277384CE8B291AD0434CC946A693041A1D1031CBF52325259FBFE068624\n      C9CAA3410E86A56864935D0ECEF0B259C64EA448649EA0501A7B186F2335543C\n      2E322679AE34F0A7CC32C334FD6A3C0CB3342BFB42C5A8B20343DD30D05FB6E2\n      1DE4390C6203EA4DCCAB465146BED9830764B4FCC22A322996D306F9EC91E317\n      0AC3CD9900B313700C76B14E4506372BD78783AB69FAC8F1F3F7928A08BB4BDD\n      AD4816BB247BC38A372BF6B5E55DA6A8E3E9D82A6A35AF50694BA963C2B8AFBD\n      9031BE83338DA38EC5F96961E28AFF5D077F29DD7FB5B3AF06EC98EBBE4D53FD\n      C98943B61D606E223088C760AD55C67E98C8B460B603E13767BF7E00C597C1B1\n      BC853221801038D0D852C600DA8754D947537EE58196A4FEC7606E2011CBE37E\n      606C55EC1B61FEE246F8ED387C15A506450F70FC2B27EEBA3B2C7AB60C711ECA\n      78A0D09584DD688FFDD58DC513B5EA175A537785A8A5378FAD43585C28640BCB\n      E205736417313E36F7DB4B6BFFA3B74909FD27F3F39F71EC19965589132AEB45\n      93FCC5DEC65F0DF7D652B4E018EFF55A9F1C9F3E49648D1652A3581836B27410\n      CA08502B42A10F5B96EAB5A5EA5DD9238D0F5431470646EAC04E168DECD6A161\n      AA9C01287D5DE0CFC06F1C9FB114F457351ACD0A4D9D32AFF5DCFEF06B7BDB4F\n      85FD958299D432A5FD99C3E8D2FC7C8B56F73BFD9BDB7B1D26AB966972067AEA\n      B6E556ED71D79920A607E8A374DC2E315CE92F0ABDEE30ED467126C08765676F\n      EFC5ADF0DB6172DB92A8A210C3C1505635A62134B5D02E170CFC374D683F409A\n      20B19107C48147D2281B1E5815C2822D55A731038BDAEF5B389530A0943F2A25\n      01A5069C6DD374987C342F8ED5679B753FCD871597D6949CE268013B9EC6D5BE\n      AD615D68C234DD1BA0592F0A30BAD6C94632CE0ACEA1720378025B841AA581A1\n      301A2ED1B85EB6196BE9FC05624F1AD7A37DC37C6667E7F2A0BBED1A03D754FA\n      0181CC55E1913C209ABE2BBDBAF4866A1876C3B46DC1025305A6D97C70E1D0CF\n      7F229898CCB8B00D0FA9B2A7C280A1687430DC8FE941BE1F75CD0801FD6F147A\n      4629C762A829BA2AB6D3ACDF79F5FA4263363D55155F7FD572A9F58EC39B6B1B\n      FC7A387FE474FF754D5CEDAD6177FC43C7C9A461649A5E7689ACC344A5A9934C\n      425278E0B9CDB8C17D1E14CBF9DA956B53170FD927CFEA440805DB1CDEAF66CD\n      A928748875849B3CF75AEFD597671E399C9CC2A408F595B9A4995CEE4557B6C7\n      DE7D223FDA478E81BE27F69FDF997ADF49B690A3AC90A014ED19D7ADABCF5FAD\n      9F9A9D1B6FAFBF7879E6E1BB06FADB07BCD998BBAD13E1B9E97C63176F5BEEA5\n      566647382FACC2040F05A953009C0B72CD00C1744987305168A89153C44A9EC1\n      996046BF987EC74F3C86377E666AEA5C833506392D4CC3B725D40EA491087D17\n      994B12271E844ED530ED60703BA6CAAA5CA8C939021EE8A6CE08D4A01E412043\n      A36102C7D8D154FD567FE7894543CAB14B93AAA679564A9551FA6395837F7A89\n      5BA6A656A6A826B706D4E6E6A18A6A8D13670CDE1B2D099C02090746EB8804A5\n      4D38EC11ACB3204ECAE32F4AA926851902ECC8094C929AD1565FC334AFD542A6\n      AB53008C02EAF7A00AA05120C1CE90C1F7B797D5AF3C659D9B8E036935EDD6D9\n      B9AC82904F35B925E0D4087D554A8C4880A12F1BAE1A909D28C26191DB95F679\n      ECCD0A5576D8C161A22A64D73123948638B3C35B1B4BAFBD7CF1E88970913DF3\n      4757A3ACBAADE8D5580788FC0ECF630DA47785A693C2B0FD804C9BFC7492FEB3\n      7BDF7E1A114D9EA2A2673A4A237870262F0BFB2566075E8860E2DF04FFCBD207\n      74343548CA2806E77B1C44A04731ED60A4501DA83A41BD344722127986FBD2D8\n      A5785FC17C7D9C6731CB72CB2A0878F85A983C557136B63737E23019CD488CC0\n      F4DF794D1CA45E2A1D31C2DB548C6CE0CAA9D4BF5711D25B4DE3D02A971F0EDA\n      1F9E9B0BE2C412C22ABDA2242888114B077BC3B99DC6451C5F3A7C520ABC3DEC\n      EF0FBA7A035CCDBBDF12836507309C954A87FA961130968CD5C90453F707CDE3\n      9E97457BFAD3358EE79CD69058DF18EEFE69B77F5B1573B5E0C7EBED7BFCD6D9\n      C29853B860C3D8CA4560085538A012673082220331C76CC44C9183D838FA478E\n      A2A5546F361894B70CE65F6F726050DF1F09FBA0B23BB06494E5C4A612AE7E28\n      16B4C7B39C0AFDAAB6047A56F03FEFED7C6F105DC4E4678E5E7A7B6108BE39A4\n      8A9BD57E94AC59E849C4EE0CD2475B9397B2E1314A1BA49214726815B9856BB9\n      E5E4ACDF44A1CA3C1E3C9D935FDCB83AE9577E696AE1DEB49778B870A65E19AA\n      5F8D9697F7F73561BB7FC2FD7875EA11E61D651A3FB2D853B1262954FA423A08\n      A7B60377542E27F0CA2B95D9CB1EAA72F8EDA0DB4A8D10811CA11CF926AF1AC9\n      B92B72E0A22015E350EE1D79FB80B017589A7061B8CB96F5B54EE7CF3677AF65\n      9A8554E7ACC111623CDA6EDED79C98B4488DA240AFD42CD34B4D789AEC581565\n      38191A299DE0116D536FF67DC1D936D7997B98C49A425996B527F13345FEF5AC\n      FFB5E54E02EEF52E294663421C2C4A6DB0FB26196855811C2E5C33F4908CCEED\n      7EC0BFBEF4B72C6F3A076D0D351A3518759A8E1A3EE17B286CEA40A043CDE6E7\n      DA5004CBC37E60E2A6EB683CD7345DCD0276915856EC7A38581F445CAA451B34\n      987228322B71A0E8F4035512D8AA1ADEEBD46EEBA4A8F15C4DAA3A96535563CA\n      77A70D6FDAAAFB5E735DAA27F7775E4AC162A9AAA39B62B6250D134E6BFD424E\n      49B32568DD36357DA8DBA4A1B7932B263F7AF1F08F7D229B68A142B81A978334\n      1E1AF5CAE5162D88E170628207AB28AD1744B96281EA430FA20A411B84ED0E7B\n      DBC9CAFAC4F42156C3FDAF3F579D6EDB77CFED6C6C6437FB0BD347FA3796EA13\n      33EB77AE8F3F7A824E3B4430C462613584593175E0E089E220424FC0E959236B\n      4A8DDAC6AB8B0D2C2BF73E20EC0A367C19436B26F1692A32AA919970F0B595E5\n      A79F38F4E07C72D634E39451411CDF5932F71FBF593B55C70FF843A2EA3BDECA\n      63572A47C69BF72D301972AC318F6F0C1A5B2FDC2A86C9C2A5BB162F3F3B77DF\n      09C62211D1667D61F5D6D5F9BBA7F79797DDED8A77FF44610F1124425B47672C\n      74042C14544235A655541606E892981AD615143C952AAC9AAF98AB5BFE477FE9\n      49BCF9B35353175B45A0A325B7A8A3BF9168FC6531203D9161C8DAB03F745CD3\n      F28DF48EC85352BDBB261794324CB0B405B51D1D4B1D8DCE0B9BEB25E6E6ADFC\n      F93B9BDFBD367F769E9EF49919D96006AB518B8EBCF0C6348593A62606C814C1\n      F046CF74A54E84B2356EB8E352959615A46CE7511E371A0A5768E9F10C26389A\n      81812BBB5E6C3A116AC0AED7700EC2D4A6C58679B81B36A69A7A8FD86E9581BC\n      A8A113A1027B625E32429043EF6C2F59BFF66C76BAE5CD56F368D0BAFF041B33\n      731BBBB9D46892D954635D488A20EA598AB75126846662A6CCD3701006F5A346\n      E50C9C5C42F770A6B1803413916F9B2A827345E4EE7EEF6AF7B9ADF45535D8D0\n      5C3FBB9267D705DA50D95A37CA33027E07C818501D31F93D04FDC6A5074F49D2\n      3523E5613B8CF4FA4E414304722FE8A741F02A4921004B037A47E1D8AFF4BC25\n      D800860D7D69A86CFA1FED3939CA842053A0139A46CB60599F273AF3C9BEA0FB\n      54F560D08481430797A981F7A5EC6A9657A9F48DEADEA07F6B6FB32F788EBE5F\n      411A8D4EFCDD6C168888C2672524C2D1345669F544DF34DC1D5D07AAC9F190FD\n      DCA1F3E70D228BC80295585B872DCDB12DA24C601238748917A9A9FAC49614AF\n      859D9E26C481FB9DCDADA7E30CD4996CFBFF67EC4D802DBBAEEBB073CE3DE78E\n      6FFAF3D07FE8B91B8D460368824003202912242D99B24C91D460592957942851\n      E2D8719C722A7165B0934A3955492576AAE24A2A2E3996234783455123458A10\n      21700007104377A3E7F977FFFEF39BDF9DCE94BDCF7DBFD1A0E938BFC006FAF3\n      FDF7EFBBF79CBDD7DA67EFB5161A352021C36EAA7471A8159F23CD9F985BA9F7\n      3727746F2EF6DB567C4784FF74F3E18541FFB0603FD56C7E6A6EE12489782979\n      5186A1871305689B5262FB3BE1584FE01E5C4AC9C964EE0C3BAA0CE0A2BAA9FA\n      CBC898D4BA34007F0F1C39A14EDBC171A37162C07EE40A74407881C72E0BD3A2\n      492C01E001E72F3361012BDE30F437B71F7C79BBB7DC8C3EBB74E22FCAB465C3\n      CD4E5124D14DD2BBAB4711AF2F49719CB119A06DF050082F78A3F4D0F0CF2F55\n      A7050FB3688C82B7A2E4EFDE7CFBC5E5437FAFA81D36C5F9E5E8F7A5FEDDEB77\n      CF9BD101697F7961F1B3D37373BDFE940F5C5714C4C03B501CAA561E57D89F6B\n      1354B871C5764D5DAA776373848C534F450ADD9376DFB795B1592557EB3081EB\n      7B44380D1F2B45D73148289A0B80351E3A89C3EF2C0A116C04B5EF8CD497AEDF\n      5FF3EBFF569D1D0C83A7E717025278A268D483A2B3DD641EBC21DA2789308464\n      A8781A40C877D2F06349411C4547131537A306BF2F4D5340F201C3668B5DAFF1\n      F5ADC1EF6EF5BEDE199AB849720FDD4E292CD711098C93478475E899F7FDE8AB\n      7C6DE9BE5760B55A5D011F12320622C717AA695D1CA2C01F551A80F12A8F5E3A\n      F9D46E73B37F71ED1931F1447D3E61A2E0EC9E4CAFC8C1B777B7D6B52B324BEC\n      C843314FD81ADC734D9928780159BCAA22E00A31CE31069E256C5759DD62D4AF\n      A7CE2D2309C88262AB4173766A1152D39D618FABBC49AD6FD0340BDE5770D630\n      BC55D009EAD585D7A8031BCFA622BE2A48ADA1E7FE832F4C7CF6E33D200D9686\n      F01340A1356E4C08E225E781E40C239F72756D85FDB1C8BADDF9351B126C15E8\n      0C36EE673BDBB3274F9479F6F04F5E9B3B72307AEAE0E6DD9BE54EB6942CF4EE\n      3C98387DEACEF7BF35F7DC89F870CB7A3919699D34B45FF301C0969932B02054\n      5060EB465F1A31332F1FECB1772E472F9CA3CD491A4E1AB425F78025A53A1710\n      C594606B3BF7BFF6EAF2D9B9E26CC23BA501B2C8556338DB79FDB62A77A73FF3\n      54C66D6C93ED372E0DF786873FF9924A061A1B2D631417BBD4DD7EEDE2818FBE\n      7C7DE3DADCD18990DA515B4F4E1EDDBAFADEEC8B0BEB37AEB7F6266B2FCC49D1\n      2765290A81D60CE8295058695CEFA07338C5F364E098C5D007F4C493DD287DCF\n      EB99D54FFD833FA1DDFFEA70F3C9864AE096E610DA4BF89031C5A68D5CCB01EC\n      A6E6B09F41BE0B264C7E9BA54336716E4AAF6A8D76A5B1273CF837C0672DB80C\n      34E526B853DB7EFD42FAF0DEC1978E65F3B0D6B30478620E4CD2870400A1904A\n      C849403BA95726839B5D3FD17C35D193D3229AC19E3B08A7383BEF535AD37CC2\n      D0C873C236044BA378B46AB095D143A531488FC0B801E986B5F69D07592A0F1C\n      5D95AA10514B6A2CBA78B88510A63BA72608D47267E36EEBFF78B373A43E7978\n      AE73FFCEF49387F4F1A92C2489446FB99C63220C94F3BD44474558E4290E96B1\n      08D6D2A0B7197ACDA0FE0C114B9A630EF6F08408EEF11E6329DC6C8003DE1E7D\n      EF7FFEF3CD6F654091AF8E36CE1B7BC38677069DBDDCA6EDAC4622CF87583D3A\n      DD60BFFCECE967198BBBBDA9466D980E26E34630CA816AA6BEABBE310C5D04D6\n      107C50741E1CBB4F8CB77855ED50A884C32A2919D7D2A82B317C78DE80610A09\n      B74AA6A2AF7457410AA46D4A76891C5A6CFAA20092085B27E5DB65F7965693A6\n      09D871271B0E2CB6648F4F4D8C9B85228FD4F5612B794ED3A63A6621E30A1479\n      0C78BB5A1709CA1FB3B5FF6EF9E989417BE4A5C2133525D0FDC5335898214A7A\n      320F591DA80FAD6FF8FCEDD1CE66A43BC2FBCE839D2B6D99D466003247A6DB8A\n      2C1B1553ADE983CDD9E7253B0B9174D4B5ADE87A29DF54F28B77EF95717076AA\n      F9D3B5E64F2649ABD783305A84AC48BC019310EB28B609DB880908514A29AC8B\n      32B4B2D2743F0D50779F2B37EFCA25A3FA1C555264C2D59891228C47C5F62D05\n      C61EAC55519897688A6C039AA11CBAC2415A49D2DC26F1E57AF0CF1EDEFDDAD6\n      A8AFED4F35273E33756049D30E31DBC0CB47831A4EED9863C974AB57901AE90A\n      00D5105FA4AF47BED38A64A52613D35F547BBFBDBBFEB3078EFDE2A8D5F3F43F\n      B43BFF72341AF446CF47FEE7A6973FC5FCA3B28823B4E9E9036467CC29E7020C\n      D72A84484A79EE744658557574C7CFCC7524D3FDE27095FE2180BA995CF2A8F6\n      3B3639238E42BA804E6C920105A080320DCAE8E1E1ABC1EE1E08F20A2B28F1C4\n      D56EBA19849F8C43D3EDC137837A90C71495F4AD89205700C80B04301D809122\n      B36988D52957CC1FF341EA0ED50003CAB20CFD80732FCB20F8EE358A2CF05ABB\n      C6BFEA277F7C7FEB3B0FDB6B9959073E02090CB5DD736AB4EF148D4A82C67BBA\n      1A6ADFAFDC3B6B5ABB9F05B14CE955EE6290DF5D11C35142EA61EA2131A14D4F\n      1C989ABAB9BB716E66EED9C6322FE8ADC1DEF96CEF4ADE4BB1559E4C87742116\n      532288393F59E889D6047C0179B5952607AA5531B22FFCE4802BDDE86EF54769\n      7764F74A00A0B019ED90EB92EA52A5AEFB0152A808A3988B06B72C01A26B81D1\n      48A7248252E9091685EC742D4C3CDA107C35B2D3ACED9F3AFAC4BFF3B3F4A9C3\n      39501289EE0AAE0BA912BA61E3623FC79B40B5C2E930774080D05564B9DEF1CB\n      DEE0D64D69F2E9278E640F7AF77FF0C6CAC963E1C2C2BDAB17E2280AF2506DF6\n      273F74FAF26B5F5E3C79ACF5E44A110D833452518D88D8439F4500D8236A8B20\n      CD0040C01352CD49D11EA5AFFFC03F72325E59A5B519220505A4E8ABC2E43E45\n      8B6C6F77B8FEA75F9D3994D8732D6FE8B140652C8FF5E4F0EDEDBD4B570E7EE6\n      637A2E8260C9D776D75FBF79F88597CA1310F700C0FBD26FB476C4E0F77E10CE\n      2E6EFAA3682168B66AA37B9DD6ECC99D2B17A75E5CBC77EDEACC60B6F6C26C2E\n      7A342F60E5230E00F40168A7B2E0410DCD02780EC923156719CF229A742FB6C9\n      6E6DFAC9579EF86BFF171DFCF74792A335C8BD56A710436814DA06C741F4B474\n      A271F5742021E027D3457EC71FF6C4CC4767CBD542511ED20908D308481870C9\n      40736089D67BDDDCFDF60F1A5364F2D999B25594360F0B0E5880047EC1240A2D\n      1BAC01422264AA36BAD5F3634D96849A980EEA0B58C444D71B8FEA90B09AE133\n      C09C3D031C5CE311009220A0B31AB325DA1301592F708F87C9DA858B7EDC9C5F\n      5DC096581A3A856186A55152BA26010FA562987AB87E6BFE372E6E4D91A9932B\n      726BA3F0CAFA878FEBD93AC44AAE810042A4A63ECEE85B85BDAB9448AC8E6A0A\n      BCC24BFB0F49A192C633343EAE30E097F05CDD162E95EDC930F5D5C8BB25DFFD\n      87DF79F88EEE4A7BADD8BBA4C8F5823F1C0EDB1A0542028BBE6B8B46FECAE927\n      8F2F04D777AF7C746AFEB95D581F369BAEC97637F42094BB1A3F7C017646D309\n      CA7CCF99F45274EB76811B63B5225496144FDFF073625330C15B830739F02100\n      2D64D216860C833DAB7788855CBD4BED2E29B0F51108798EBDD4ED90BF237B6F\n      75FA43EC0EC5A2A87CBC29C6C54546C6840FFE238367A321DC205B37EEA84D8D\n      0F14C7AFA91C52E137FC470BCB7FA3B1140CF63A2C0B4594E401254209D88F79\n      C04D41CBDC960D1A181BEC84C9B7B3DEF764EF924AEF0CD2306CD4D3E274149C\n      690407EB7EC323D35EAB36644D3D028A73839AAF95E5971EEEEC4AF57273E2E7\n      67E73E598B5B65895D7991CF792707EE100A373163D14C107B409CF5983BFCF3\n      B1619A0E03D7FD5159CE7BE313D97142B0E451273C2E515760260825DD41ACAD\n      4CE64805AD5D0427DC4A95E14850E9F9CC8B68BFA833CFB06264712473984C7E\n      BDDFFF8D07EBDFCE4B40F17F756EEEE38D79366203331A660F6703B6ECB562B8\n      39BE0056583227BAAD21643021791E24B726C5ABDBD75A8CBEDC5C1E4AF6CFBA\n      9BBFBFBD57F7A2BF3CB9FC1F36C2F95A5C2BB28687C134658AD40260101E4A99\n      3B3EE12ED7D78E84B8416A875D30118E6374F51D5B8127B3DFF9E462B73B8776\n      140D2BC69847AA5343609500310B8F16B0146045EB212BE177D420060C732025\n      063E88F0463EAD73DFCFF0777B5180C57E3C1E64A5670B1F4715B16104CFDF43\n      3CA3B1A66284E339A14A4C02E84D5972875334E05D20DBA504C82958484DB055\n      90AFEC6CFDD6C6DDF76019699C8D93AE3B45D8CADA6DBF7D74BC92C79F738CE8\n      F085BA6A3150D52B1966DFE0B133458BC34AE4279295B985855B6BF76F8DBA6B\n      00887DD2F0D95322FC8848CED6EAABCDA0591741C26773FC98B850A4C42338EC\n      D1A315A9B5AED8A0AB1545B9F684F4C24CB37E8E26D90002B654F69064973A1B\n      EBB22C3CD8B2E5AE6A48D11001890057C05AC6F9261D46BE50BA61C8B465935C\n      C4823726EC5C2D5F085AF5E3ABABBFF2B3F6D0AC8290877B0F27D3D07F142F40\n      5BD472477350A6340AAB79EEA4DC94C42F246B8BFE4EF7CA9570AEE92DCFC8F3\n      3B0F77DE3BF8D4199EB25B17BFBF70FAD0F0611A776CEDC3A72E7EEDF7E7570E\n      CF3C736210ED267A8EF28878A81923CD5099015780C14A58254508A4D90F4732\n      BB78DDD064E2E429DB9A233280F598D21CE5C2202E59E10DCBDD3FFBB36442B3\n      17A73D15729D6B5E68E6B38766FDAB17569F7A469E9DED89EDE911DDF8E27B0B\n      CBC78B8FCF48B323E045A2DE281BF91BF7C9CD0D7B70623BC9960EAE0E2FDC6B\n      2E1D5FBB7171E5C5C39B976FD4CAA9DA73B305EFDAA26029F1012559A7AAE5AA\n      66A8310ACF08EBF94929FA48553BA47D67A7D99A0E4FBD74FCD3FF9C0EFFA743\n      D16A2293CC1603A6983FD95235789A8AF633087E4607E940CB7E397950C9DB71\n      7B9BCDBC32AF0F17D290C49B85608D07A70C6013F62EC15D165FEC3CB87173F2\n      4C3D3E2A6C58282999C66C89BB91E1503F16D9A8C036455D2FEE0E5850920302\n      4BA3F12C75FB14B56A4C4859C378D392F81C15D460FB68C78370B99652B91507\n      1B0BE20F3C15BBF6DEA5E6E24A63AA01A1AFC0B36A00A0DC9ACC83E7650C6302\n      AB885C6F6FDE99FE97EFEE25A6797259E8ECC6B5CBC73EFA21BD3C59FA00E631\n      A15B9437C3E15CE99742A30E8A85E74421A8463A6F67EDAD5A72CC4B4E9BA869\n      4D8EE1C3625E30241D7A0F123DCCFEE8EAF7FFE9C52C9BB95BEA1BE9E84AAA6F\n      E57A7720074526BC008215C4CD93B3CD234DC1DB0F3FFBE4E1E76DBC38C22E86\n      8EC030E85BE6CE9EAAF91FD83BCE8A5030BBAF2C8AD1C909C8288DC4DAD3DA69\n      01D871A7A89B1661C8BF35C9A5CAA5CCE2BEB5BB8C6C52B34D551F45444C259A\n      56723108FC1D6ABBAA78756FAF28325DD58F1EF5853AF5ECF71BEBE0B6FB0E4D\n      1A22F070106827714786148B65CE1D55B9721AABD17FF7E8E9CFD7A658BED7B7\n      C31A8B27550D5046C2450D90BEC921871A09904D7212EC2AFE03CE7E33DD7DB5\n      D805E6B41AF14FCF1C789E8A335ED03072500E67983F5FFA6BB5E0AB59FB77BB\n      BBDFEB173382FEDCEAD19F4C1AA7898975A605CF81BDE124EB2EEC7B88B840A1\n      2108B0EADCCB919A6A7415991D3A3972879A71260505AFAB6333FBA809E8D167\n      1755DB91C682041EB8D2AA40AA318E539708B1C356A28892A2D8768B9A7F050F\n      21D8C922F089C84B66C40E15B764F1DFE63BDFC87AD339F9BBCDA58FF0FA666D\n      04776D75AB9C899261C293D44E8EC86E9D75429FA195B8DEF5E49586F7E660AF\n      B537F8FCF4D1B6D0FF4BE7EED73BE90AA3FFDECCB11F4F6A87740F071571AE14\n      BB3258C0B1383066F355C771D5532C5D5795CB01AC62816CDC295B8D7DBB8242\n      C508C9FEA1618507AAFF8F54B299386CC77A4013A4176754E4909A50D8A24477\n      68021000BDAD2DDAEE58231FC6017C37318008B05429E0AF026D0F809E97D8E4\n      8996A8D8125272D4BE720397E35E4E77E508E6E06D95F381E11858FA58ECC776\n      223F4D2389632E9DC87F77307863ABFF8D07DD8B23D3C5B2BD8FC30FC42D43E9\n      72B0CB6A664C353931A8AC87BF0E82BD466119830358EEF09BA290120E96F2AA\n      29CA04015FF56AE8DA570CE135B375F2ECE4D4C7C2D68B2C3EC1FD165AFCC132\n      969CD912FD26F014D0D1595B35AC918A8593F1E9A7C59E79AC9D426E971EBE48\n      6874DE34CC1F09B64B48D7F306C48C8AF2DEB0BC5F16F765BA298B148225C3F3\n      C040889A310BC64EA96282DB5A5D844D7FC6278783BA17B3E99F7A7EEAF31F07\n      068D1297123BEB509C18537C69F13C491888C97862C26CC553613DF3A11523B3\n      7B7F70ED7AF3E8817C26A6DF5CDFF2D7979F7CCABB3BBA73FE8D951F3BB37665\n      635E35A2B3272EBEFA7BF3078ECE3C75BC17EF867405D63545F33456D0D4CA1E\n      973D4F49000E256E08C0FAB4DCEBA6D7B6269F79C6CE2C6322A45EE66500A6E0\n      9E79DCF75255BEF536257BF4F9296B039EA1BF6C9AE8200BFBBF7F87673CF9D9\n      A7BAD3ED2690CFDFB9ECF9F5E0332746C15E1D87D36313B4C8ED81FCF29BC9E2\n      F4ED69BB787845BF732F3974F0F2FD8B4F3C753CBDFCD092A8F6E13960849008\n      015A3AEB89D2EACCC39E18ECF612004B0A488D91D699A049FBE62EE0CFD6C1A9\n      7CEAC8994FFF211DFEA39570295161698AA147B9989954119E29B0DE480F602B\n      F9BAE0693B6B1C18B08DE9EE166F7E6CC61C453951DFB680D113942B4407649F\n      876537F57F73BD5B76EBE75A625159D9C772268F34CE75E2A193C221718A1633\n      1E2C845A796F04F0841CF0E9CC1CF567D163085551813B049437211196867332\n      80ACECA19D9071DD0DB4542512268B050148846A777B6B6363EAF0C9A0EEC3AA\n      2BA545A13E847670339451E838854BD3D7ED9D87F117BF6B222E666BF0CFE69D\n      5B3CF1A79F3B954D86140B06CAF3856B99B0D24B7D9920C9F2FA1A473E6ADCE4\n      69FBBE2993FACC732499C3E880472B1E33934AE6367E2886ED9DFFFD9B977FFF\n      EE1E9FB850963746F6562AEF0C477BFD0CAE53705C8D4C9740FB4E34EC5F3F71\n      EA33266A49350CF588433E534E1C00DE0D379976BE6170439910C06BB035C061\n      65F8366AD92329A690D484469339447F6A5CCE436E8882AC063067599A1D1BE6\n      DA74ACDD26668FA80227684CA924D0B43B32BD3D1C7871837BFEB7B25E99E64E\n      27EA7D2FA78A1602DA30AE83A14A0EA412B6C7FA157A75EBEAD50882B1FE0857\n      22E036C7F4C9303AA8756900E7A2524E9D06046EAD2613D634B89D68C5B3CDE6\n      A208166D50F68AB528F9A79D075FD959AF29F2F3F3739F9E9A6BF5D359EB03C4\n      18D9D4D4FD3B25FDDA68F45B3B9B436B3E3A3DF10BD3133FE6799390EE43D1F1\n      21002B4899915225845B477DAAD951005A189E3C6238223183CA1B8E02EE1F07\n      8E950AC66275F6511E1C1F906A8E4DB36E20D309ECEC1B8E03A2C491248B31DF\n      6ABF98280924C211D011582D0AB542714C2896AC3065CE60ED914661BF1B44FF\n      9BE97C717BFD749FFCAD8307E71B51AD6F0F0F3D12CADD389F49BD851EDF8C54\n      47D49B286C38B89F0CBFE5F51E66E65CEDA4E998DFE8AC7D89EE1EAFD5FF463C\n      FBB9D01774D88F6D5DF30407CA3DF8740A528F70E74A68BC0318969402D713AF\n      6CBAB0F7D89548C6A3DE15AAE2FB1F1D198D71D3A8FB66269533B4E353EE0CCF\n      3A47A15E50D6244D72E2C16746850B86F65E90FE0115F9B04561EF6A58E5D824\n      AC810F9392280944288617185848220C8CF0257347AF900835AB9E42C55671A0\n      C5569E4874DF977A9FCBE1D5138E6ABE3AA399B67954AA86120312BF45C9D746\n      E97736F66EECF4360AC86FDE38F1E1930618AC20397A15BF456F2BA7C01B60F1\n      0461108078F75DF49B4274E7951C87878853164475F68C9C69F82F4FCE3D1745\n      6798BF2C4D0D6E5440B39049C0C6C08C341F0579C5B299DB1AD59F3875E33EA6\n      DD3F48E00AFF0FE423A87DA958B5C030B2088F216DC2C12DADA428875C6F5176\n      5FDAB5917A30547BB91996DA96AAEE91C9800187F223D2E4FE0AF50F3793F999\n      B03FA967BFF0D2C42BE7465EC895EFE3110D247A4935A45D08A5E884E2A10278\n      55B841470ACB869AF6D28737E9CE4EFDE8724FC8F0ABB73AC7D9ECC143ECFCE6\n      C35B97667FFCECCD776FAC360F472BB3175FFBA3032B27278FAE66AD11854468\n      500417C09A44178B2E551D6083B8B6B0028D35DED2E8FE6BE71B4F9DF60F9FB2\n      32A27857E1C61710D7507AAC34F6E225953FA41F9A3010BC4B00FFD9A03E8A4C\n      9DFFE960E3C2C6E25F7BBAB738A81535F6DAFD8DEDBDC5BFF04C3A9907A382AB\n      896C6A86B60BFEA5EF9ADDDEFD6313CB4F9EF22EDCF60ECDBEB371F1D8E241BE\n      5628C16BCFCF17A26BCBC2078A8DB56269740EBF5AA24C1641C7992C83A8C973\n      9E6EE7DD9DFECC8184B5423279FAF4277F9B76FFF1623257977E0ECB378E6232\n      35A104DAC27BA32C7DD0218517F156D653A6B65E1B1E1C6C90F8F94973A22021\n      6765C2FDC80AF40A32D85212F6AF6F477F70BF9C30E1C726757DE841A8D5DCC0\n      D30152863A0B687CAD39E604C86C9008ED8352D2115B0AC9CC020B66DDE4B84B\n      8436A25ED3D056091984F4107A22E7A9DA12D124BC90680422A80FA87EF7C655\n      ADE5CCC967282C37B4ED03C81FB8738EC263520373F2F0E48DFAAAD7DDF1FEE0\n      0D0EE931B0C98945930F6FBE77F9F8473EA45767606788543A54685908173BE0\n      9008B1AC3640F70E120384D4D94E7BBB3D77E02C8D0F1180459ED7D569D3CECA\n      D2B05A9B3F78B0F63FFED9CE0FBAD72DF96EA96E64E2CE305B1B76D3144DA26B\n      46001E1D70BDE2D17F70FAD99FF6E2A0EC0F035570144EF580023B4B15E9551B\n      D13569084852C2AD5E777C851404A3B0719678187EB1F8E1722196C0D1F70F0F\n      C50BA325FCA972A56EFB615EAA81B1B06053D740ACF202789B6C25D7F3E19B3B\n      ED1D471952EE14179D28D47820D089F7603BA5E0A672BB0E04C9CBAAD59E01B4\n      813BAC51EF5C62FB1DC24F403C4D45A6097D8AD77C953214AE2423418639D935\n      64CF154E7D577D05E212D7C245429E4E5AC71BD3455CFFDD3BD76F75F6FE5230\n      F11FAF1E69ED6E037074DDACCC8BC93799FAC7BDDE958DED194A7F7175F5F353\n      D30B79A7C9B1535679A20C99F12102A742195F4E03A090D40D3253E048022E5E\n      01C5E208A320EEF996FA86E4AEF705D582C71E8EE352F4075549ACC0134657FD\n      743EA788439C582FEC2C55C2FF1441B50292A4AD926A547C370593B8F93C0ABB\n      1DB644906A9B09E0AB3AB632ECC557EAF13F94EBBFBBB7F1E2E481BF191F5D59\n      EF717838611A69035B05E853CA52AAFC26ECBD624F35F46E4DEC0593B74DEBD7\n      EFAE7F65F0E058D4FC4F178F7C2E14B1DCEC8B7C14383F4058D93817014B1EAB\n      5EDC608B1744BCCC27B98F36434D5875558771E5A9548D0F5647D05589C1113F\n      AD72477AB52B198CC745903FA354A5A3364EC61D650FAD753A15D8A4880EE418\n      D5112F15CCA2B89C87F6443ECB21A45B9C5DD328E0E9889F10212C662622E607\n      D89DA94D35C74811BBB85E25D7C5AAC687D08FBA3D81D128A770C4AD6B56C6F3\n      0B538659DEC8F022D324DEF4C5C361FE6050BCD16517D66EDE90450796193673\n      E211197316D102FB70F0465974214248A9DCD8390EF9592F40592C9E2259B068\n      EA0798A6D467A2E495D9839F11134F97BA950DFCB0D45E5E46B4F069E90BC543\n      0A0FDA40784BD9D8E9016FA5F7A8A6E2B2A0A99AAFD1401573AB8776A7D5082B\n      6C5CC8D16E60DA29F879AC602829E27C65349A528E086B53DA61DEAD5EEF4196\n      6F97C5D0391B46225E4C1A07A370CE53CB81495A263FD93AF4EFFF747EE800F0\n      F00878B7768360F08B6529AA66D9AAB65F39DA18C8FC234B3BEDFBD76255C62B\n      0BDD5187FFF1BBFA23071B73B3E4CD5B6591AA6757D72E5C3E7CE285C0A357BE\n      F1B5B963A72657166D0BD6C001371DE9C322A7E84AB4A769C709E6789EC29A11\n      3C6BE9FBA32FBFA19797279F39C76CC3426244C7A8D253A8131D42C63C7F39EF\n      AEF91F9EC16A010462A17BE15E621BFEBBE1EDD7CE2FFFA523FA20DC9D3ABF93\n      5F7DEBAD95B367C4A184E5038F4E95537365466ADFBEBAF58D37BB338D132FBF\n      5CDCBE2B0EB66E6D5CAE7BAD569A94DC365E5A92A243CA124797512501C07F41\n      95DBF178E625693E826CE5F593FB97D6825630BBDA3426CAE5D117FECA6FD1DE\n      3F998F2713D45185FC3331495A0D9CFEF4AC5FCACEF57BB4A7279A4B695F96F1\n      83A63AD9BF95F9CFB6F85354FBDAA73103D6EE6128C2C68ECCEF7CE781F8EE3D\n      BE1AB1E792D2EF4790848CC0AA1D00281CEB047CC831540004E5CAD335B64172\n      D3A5CB319D3EC0C3395BD52950D11D566683D0A91CA76E7B1E29703360E9C799\n      6A01D3C55DC64286D25DF7DF7D7372A2991C791208AF1B1986E714BABA584EF1\n      D005D28A335AE23ACD3AC51F7F3348512A257A6291066CFBC6ED68BA557FE2A0\n      84CF0BF912684DE84964AB25FA6F6276C8146ECF100B4C6AD46F3F1462B2367D\n      CAF059CB82BE9FB76C0B129702B27FF5FE3B7FEF0F83F5E0A2CCDE50C5B5CCBB\n      3DCCEFF5FBB0AD508348A27E6952A79F5D5EFA9BD34B47CB613F18E5C2C612E2\n      04C469961490DF4D2A70E320EAC2A2283042CEDCF09A1BC6755C041132407E8A\n      EDC0C678D5319EA218EA1595051262A96C2E35209F3521E0B9F500475B0BB0D2\n      0572481F41A14DDFF36EE6D9773A7B3B009C283639BB9674F36828D9BA2C08B1\n      0D821AD6D838112A419749D4DCC7DF3441503124A1689415076CA5E69D684E1F\n      6C4E3E5D04A8A516C80C303C0F0B1A6F8CEC5A5AF488ED66E966BFBD9D8E5294\n      7A96814681C81121F7198982F0E7570EFF5CBDB1900D803DE4460CBCF042BAF3\n      4F6E5DBF44E9F3A1F76FAFCC7C3A6E4E01A3F52CBAFA6AD53232F6601D920E27\n      2517A10AB1378E42BC153E1778E558AA44C7384869006D502A1410A1FF81A4E7\n      1A0B28F957BE388AFF54BD31FBF7C3566A5E38B262E0C2B125DB8619E232601D\n      D8332FB3441601CEA810C950AC06B61150125824CD2E6DD1DAA526FB1FE4CE5B\n      6BDDFF72E1DC2BD21449CFD262BA8D03CF9B4D7C0690BA4A2D8594B9F076A4BD\n      ABC49FA5C59FEC6D1D6A4EFC4A6BF167E3382A77733F0BC288A44447C42616DD\n      A40CEA30F878342A946025E47E9F28543FA275191B572336ACAAACBB36CDAA7D\n      12EB796CDC125331FEEA3F517E0A4F461DF1C5BE0F8F8E67723CEBE46CB1C6CA\n      31D6228B84B08A9AF054623D803886E3513B16B4D2B69A6453D47935409E0C04\n      0F020119917203E4011B59E9FB1265AE23EC71B932E4521AE58225C75C814545\n      A0640A2BDC58EB2A0B9EC9C039B067D4DF20337B26BFDADB7D737BF34A2FDB34\n      A62B21C3DB02192CFA7C1AF7AB288E5F60BD185304B61BB06AA812BD487DEA17\n      1984A1A5A0F94BB3ADE727970F7732BFC82D19E9A61DF202693796AD7CB44AC5\n      7167600C5995C4997D7FA67F7C165919A3B96F49E61819AC15E34EF171AF03B9\n      12053C710FF6BBB45E091B189EA4AF45A24D00D45368E92392C83D36E4FC8134\n      7786F94EAFC8FB78E7EAB13F3D192CC4F4409DD150359E3B32F5E97376798E4D\n      CE692F444B5CB4D5B0A156C83E5C47396AA950A7B8A607D6EBF7376FFA9E8926\n      5BA39DEDEE6B6FCD7FFAC35E1276DEBA3831BFD8637A7363EDF0B32F88A1BAF1\n      8D6FCE9D3ED9387C00A5F4F5015786F238C4431CC5DA3174CF407657CE28CE14\n      0AFE15D5FC6F9D7F20F8EC0B1FF5ED24E2F218A8B762D28E0001FB81BE78A9FF\n      E07AFD234B4C4B6C1D086949F7621D7B9BD337BFFA66E35834FBDC0197B7EA57\n      BEFECDC9A985B9670F6936347EC346D32663E1D668E76BDFEA6F768E7CE8C36D\n      3B8816C36CE781CA78DD9B9045D6F8E88A0A7AC84D733C5E2ECB14B563D09984\n      A171419A017CC3F1F875B5B7B137756C064090E9D71FACD57FFC3FFF1AEDFFFA\n      7C1447A82CE9B3606696C411AA50A286A8EA5EBE69B646D393ABD9D08E82F569\n      FA44FFFAC07BAA197F38CEE122A23A61B59285F0DE914FC9B6E9FFE903B976BF\n      79AA454F45251B044853E0914B37CE026035D0906C1836C3285E6222DCE569B6\n      C757EB9808A30554CA84E5EA1221E50DCB26725C6E1DEE54469D0A35422608C3\n      06D83F84749278D2DC7FF7074BAB4B64F1B8D6438D49045032BA17E0A021FC20\n      EE2CD7ADCC204764A3AFBC4EF6FACCC8E8C8AC986FC9C170F7DEFDD933A7BCA9\n      1A5A303A61333CD5C475ABF66BFC1827B0140A1B5EF577D63766174F93DA312D\n      A6B2400583820B0840C6DF2CDEF9FB5F4ADFDEBBA1D4F755762D233707F27EAF\n      8F8D70163B87238FFEC2A1E3AF4C364CBAB632CD8F4A3251D0C2133913009742\n      9C8987F0235DAF17F0534E39EA0FB88E05B418C4FC8672ADB0EB61B9E1FCAFB3\n      8F71A7D00AFF01565696169B9A21BB48932AB9E5F19E913D1CA5C19E0FED0C25\n      3CD8FB8A9644EC86C1F962F05E6777A45D5BADD64E84F8511328B5E3FE0944FA\n      904B629514AE90147233E78B0F359B1FAA3556AD5D0268E0B310A2A33B640914\n      EC6963433C79F24AA0248931A240B532869918B8BCF58694DC2CFB5B44DD4A01\n      3194D76C794FE69125273CEF895A6325AECD86936F3D587F75D4CE02F685B9C9\n      CF359AA7B915BECA08C48F30464DBFD27A32B4008A6023F96518CAC4F8786AE6\n      E2361E1030E908EE78BA63EC4A8EB1F6915879557B631F50CDD92F8DBA2A5725\n      C25E25886A44DA2D63D49C3190B2A4543283E5CA340A4D19253D0D39C8A95850\n      8EEA5600ED0186523DE2C3E9922774F64D2FFCD2E65ACD2B7F7C6A6A517AB823\n      20E4B1B2CBE48E0E2E05E5D5DE5E56987542EF154567582AAB5663FE4B470EFD\n      24E14798EE167D1AF2180745A22C32790C3B1E56ABF2815C40CA105C86423A87\n      20EE768BAF23371D489D21D0783870FFF1B2FDD95382024A848C83B6EB5E81CF\n      A66031E1C9A85B72AE5119BDECB0820FF916F73CDC49D82119F62328812E5206\n      E2468A238C91805059150BF10D600F7B38988A569F801E81E8733F093026E156\n      67D5287FC5508D4B84D5D043D56F025B2B426B3E9C970766CFD1208562375800\n      9BC6468504AA068B41A356789C61CB0ACFB9B7ABE4462ED7B2F26E26AFF7B37B\n      C37CBBD06DA5011743F4F0F174865583931ADB479DDC3E3713D4BE14B77E329C\n      7B319E6FCEDC6BC032EB0E22CEB1C95AE03C9E87E913A2834F9C081624D18CAB\n      712DF6830BE8FD7624FC1434C4490D5399B920CF1EBBDA03C7C5F6238213F8CE\n      80D9841C120ECA40E4190568AC22788E40443D61449072AF0F21AC9465CE76B3\n      F2BEEEB0297F2A602760BF00669D8ACD99E5E8C3A7826387497302D825C48CD0\n      509453E4AE0D0AD01230396CA41CE874BBB377AB365D0BC3A877F9FACEFD7B47\n      5FFAC8B0BFBD76E7EAA9A73E3CBCB1D60FE4FC13C7D880DD7DF58DE9E74ED68E\n      2F3B25E605407D254781694F4BA2B60969439C44348AAC3E2B75C982BA7F63ED\n      5E7B67FA858F276C1609450411C7D052A73EF383C05EBAD6BD7DA9F9B1153C5D\n      C79363CA552600B116ADEDEFDF68DFBF7BF2A75E285BC40FEAEBAF5F20237AE0\n      E533793C829FAD9129AFAC312FC8DFBEBCF3D537661696D2A353D104F1DAED11\n      5A392E14EB1BF58F1F36511F017D06818A00BBF5ACA4AA8A6D68BE86ED575DB6\n      7BEB7E637A2A9A8E4C59F46E67053FF9637FEBCBB4FFDB0B31FAFB701D077C6E\n      9A705F614FB48A3D925EBB23EFEC4DB4968AD26BD3F5057D38DDA2C5826E7D74\n      5A854321207DD64BAFA19989858515D7FFE34D69B767CF4CD35521ED108925BA\n      4102622EDC9A08350D10960047152E1176C3B4B7C50F36E90C30C203588583B5\n      669C8181D720AC991B88285DB849CE5F4A1004BE043782A721EA0A52A3DDF4C1\n      D5F3CBF0ECE78E1A14D194141348E4785489E23298C850DE41911CA8937CE37B\n      A3DBEBB1D67A328C4E2DC1761F5CBDD7AC3583678E03BE5604E5467984136786\n      0E0D1AAD240C0BECC0AF0086061E19F5D6AF7B7C229E3D67EB47944778771B52\n      6C5AAF4569B2F9ABDF7EF357BFBEADF805935ECD8A6B7DB6DE2D21BD26B61C86\n      8444DEA76DED139E78EEE9E5C8F64F2A0F3EDED0E705F370489023D9E2CA35F0\n      710F87DF58A51E6A5C290A9B5C3C5329646189033B53AA22A6C6214894D991AC\n      2CEC5091BE257D25874AEF7AB01E0CC001893F8DC64A70EB4B58BC5ADFEA0FB6\n      84481B8D3B9DBD9142B35A850397E4B15089272B7CEC80851B78819039414F4E\n      CF9C9A9E3C9484F39C4C5BD52C64539948BB83119436A4393A46025291405704\n      36B37B0104941C7735968173547D05503960368BC35D3FD829E5A62A6EE972AD\n      3017EE6EED317889AC595153F2E0F4EC2B2BF37F11C80F446458CE354427B134\n      11819BC6528176513E10578F13A0419101AE016C526A55A20184C5D913583FCE\n      714EA1421785E8EDEF17AF8C1D4F86ECB72C7E2090E9F1B7ABEE87313660AE79\n      92EE9FCBC257990F508101C23DA2338AE4DA50210D8E92794877E0028047F7E9\n      5E11257ED1AAA7D12D91FD497AE5C8C4C473A3E6F6B0F8AEEDA6692E3279DFB0\n      4BCC6C18DB27A443C8D0C3C3B315DFFED2B1039F30F4704EEA2C0220160618BA\n      4D504725705175485A1CB1E13EC210D45EC0C3648A05182C458C8D48F7074281\n      D1D8FD483D3E207C1F14607DCF9DF6B0CAC9D49412B5D9CD788A262702D5DB0C\n      1ED857077A880A14DA833289F4B17403CCB10642EE970C4572E1650ABB5B9810\n      A89258C93B024C65B12FC3004F0EB125DAB5C954877B6391CCCA37072FCA33CC\n      79E051A75E8697E83E1C6A29411E052402375D109C5214598AF415B13FB655C3\n      73D03CEC29B2874ED464BD2CEE763B9B83C1F7DAAA9B8FFAAE1010C501C322BB\n      2EE07D083935E57F6EE5D847CA68616BB835FD70162D4861C9700FDB00316B21\n      5685558493830C4D09153C26FBC81CFBF134588935D87D496EB8580729DD8340\n      4F08ED067E81AE5B48C91E3C40B82FF03724704671AC351A77DC2850221AA71E\n      7DC0764641A627818F3DB9466F18B5568C0CF792422F25E1F46454D4B49DAFC5\n      C7561AA74EB2A387C8C4A475A73D2543857D64A0D6758D924C6DDFDE1EACCD1C\n      9A03C8D4F9D6DBA369B63471FCC6951FA453FAE9436786AF5FB2C7A7FCE3F341\n      9BDFFF93EF4E7EF49477743EC0DEEF39CB4A6C72F2F0F48897DB446EA3A82AF6\n      DAC3EE80AB2BA9A889F58DEB776E4E9DFB44CB3FC048A005B66F924203A885B0\n      16DCBCD7BBF15EEDA503D8D6CF4BD89FCEAA0918B6B0B77A6B5FF9FEC14F3D5D\n      7CA8C58D672F767A37B6665E7E6A382973C881B6E5D9392DE2606B37FDBDD7F4\n      48F2E78EB2BA26A3C1302D5A73077B976E363F71C86B1518E8D0EDD25A5DE832\n      859B8D8D7CCAD973283BBA5CEE65EB8B479721B8C9F6B0BB3D9879F65327FFD2\n      FF43075F9C0F3D58BB814D223A3B8DE22EC24F6D590B98B9B596DFD8AAD51694\n      F677E9DA5CB69C0F9ABB6273F69373FE2CC3E0EAB54A6F02C85A5DA8EC9D8DF6\n      1F6CC54BB6756A824C6ACD528BC3B710387076033125EE6414E686685C026ED3\n      75364846ED87E2F0049D5AE2F1222422EC4A444DBC907A35CB5AC8084997D314\n      955CCC3811960C0806A0C4C0F75AD9C3ED9D9B57564E1DB353872D2D34901FEB\n      C46E70FB17633759B753004B41C2D1EF5D6ABFFDDE7454DBD3FDE4D9239299D6\n      6EB971FED2EC4B4FD393F30A4B4A805D0A9F4E186F07202F532DEC3EC29342CE\n      68ECE9BE2D367636FB8D95574CFD345C6B4D768CE9741B2D9EB71A6F76BFF6F7\n      7FEDD2C3DE759BDF48D36BBDE07E1FC79B66C8708F98628EBD387BE0BF5E38F3\n      B1F5AE9FD0221C8E6C91143480CC21E448286E9D02199EB9504C84E836AA5DA1\n      C9CD57E1311ECA71B893798AAC9D39A40F7B0AD851A66DE915A51928D223B4AD\n      24E4C2AD00EB0328E784B52E6C1CE09C0D4276B91C7CA7DFB9AD5CDF9B713D96\n      807395464179E34CDD505ACE0A3CC0C11CD010F1D4CCC2A717B26792C9E74CB4\n      DACE9222055493066A0844000082F5B14E8E7DAC8CE52312738933A95604518A\n      074F840AAF675308A249469812ED463C931B80BA70013529A3AC50C47FA06A37\n      6A077E6DB4FD9BBB6F2FCE07BFD25AFCC2283A09DBCE8EB6A603157A13C3ACA6\n      8A3C4454E1D1A0AE63CA82B44EF31A7628C6391E0A380E084FCC35228EE7C35C\n      3F860BA200C2722C07BA96C2FDE67AE63A293E980821AF79D51076A5A7365623\n      33985C51E3D9F5A4084FD0FE5015A95619B027897A7D3157310E31031DE5E87C\n      EB97C0A3294BF3ADD95A47F8AB1D74117F3D196E75F63E519BDFE6E61B934921\n      A797BA62140E7A3E4FA9582FB6A6944F87EC56B697CC9BE7853E727FF864722C\n      209344A6B5FA40C5C391A719074C29DCAC014A9E784E470D5DD3A92BDF3A953D\n      2A7C32A656D8ACE9D2FDB845B6129671841045535DFFACD331C20A39A4540F5B\n      2D0A601F80F215866E207F5E102919EA02E04CCA81BFC0C20A825C08E9438ECB\n      0D4EE6A1DC9207149D296CA1C3031195E670CF78E023D8C36E382455701FBD46\n      D30B024CE1AE05773CC2E26459ECF871E183D13CCFE126020551415406000F81\n      77C34E67E8D1AE14A24216E79EC855CE07D238175AF8CD0512C7A870A528A625\n      532361F2C0E6C2FB23FDCCF5F6DAF7B6EEDCCD7A8D7AFD4473FEA8DF48B4CECB\n      5E1299495DACE672D58A5885335E3465610BD9BE678690B5130199CA33A58F7B\n      06E2B4820B51C2B74E75A86ABCB2951C8193C2783F2D02300DB86751EDC5C72C\n      6A4ACF14020F1D210702726228DB18C03F84E3C932555EA478A27D2A51EA268B\n      78C6D1590088388469D8A5A5ED59D68B499D78136BA36CC32B467ECEE9E8602C\n      96E30070CA60AE159C3B537FF6A9E8E029D8DE991E2140C1DE0758D9B0030ABD\n      7DBB6F76EB2B133CD7C3EF5D3467E71ABDA98B6FBFD67879E94016E7DFBE5D3B\n      776478B8515BA76B5FFEDEF4A79F920727EB1009F534C021C5592E6288FE71BA\n      4DF24D4CF23CC8199057490A4C84ECFEFD8B372FCFBEF8E9C970457811C023EC\n      D1286D1EB082DAC683EDE1F50BC1F373705F0A3F075C11F77D1B0459A0E30D92\n      FDC1BBEA708DFEE46153AAFAC378F0BDCBB5E78F8F1601E916B488AC5D902C69\n      C1BDFEEA3747D7EF864F1FD3335C95A3CDCDCD434B2736CE5F9B79E5B098C145\n      88CAF1D81AA5D4A8076B0D1DFC009C43341BE4DBDF95FCA06ACEC5C0FC3AE7AF\n      C70B33C133CF1F7EF15FD0FC4B27852A588DAB8529D5ACFB58542A744232ABC2\n      1D99BD75A71E8861538BF555DB1CC13B0D1FA6D31F39C70E8A614DB34CC45E98\n      623522ECFDC19DFA9FF5DB2F6E2F3EBB68314A333C7B60D6756F535BB9435977\n      FECEF0ACD546F1D0446A63AF29027660951C3859A05EDEC87AB9CF1ACCCE5A0D\n      603A25B4C35580D9D42B35054AEE5B8DB2A8413221B220BB7A3DF35572FC7080\n      AE618FA686AA63358C845523798579F1BBDB37EF7EF7BD05AF56DB7E60E7A439\n      D5C893A87BAD5BDCEE1E3EF7AC5AAD675E1112C1D49E0C13D84DBE146189BDA8\n      5664CA1F315D7805D5DB59BF57348F1DC9A2BF48E43001B6C9681AE061C485FF\n      FB7B7FFA0FBEDACEC3B7EBE48D8D01E984F356ECD5462C357F7BF1C05F3F7264\n      42754741DA8BC8106DA7A24885214A4D41B2952858C334C04C84C0AE160CB951\n      B9AD25AA520BF262EC51F00C0720E9E32D41BA27818E5036B4BCAB544F031D34\n      D85AA7750FBB3833695329B41438FF1C0C75AC681AB18B227DBDB3BB97A32E07\n      A4BE11C43934FFF3EA0A7284E8309AC5CAE3455D92CFFBFC17A7E65E6A4C17AA\n      8751CBC376442416D53434D9C7C28C54531E25ED3B214EE06BDCFD49ABD1172C\n      2DA17C1D0E48A266198A8103736375E54703D637DEA526FF965FBCB776FB796F\n      E20B8D03F3A3CCAB99B286E77C185FB0D0685D487607C93E1AA4322E5C76638F\n      2A5174FF413F7606F8810C47F75FC2ECA38ED1F775E2EC78840E02ADAA5A94C7\n      EAA3159B72A29BD4C9FB545C4AB8CC018442E3E0A6040C051C0DDD539054614E\n      76229DD84381F32E820076A624F04C2AF33D9F47D434554A7CA08DBAF4A89F72\n      92181E0F491E2BC681EB88776AF13FEFDCFCC8C2C24FED7A89F5EE4C6A78CE0B\n      08A5438DA90D00B7E0A1CF8027B271FBE5B895D74565CE797533AA34CFC635DE\n      1FB622A2C67BECEFE39F7F5F610FA89E2C8BB24C0AA779341E4B775DA65A436E\n      739EA7E80688057C836A67927B35E92703AF570FDE9A343B9DF673A6364FF990\n      E661006B4876204D8920491A344161185FE129AB414D6EE2743271B61D9EF588\n      E1D861A479954FDE5773A824BA1F8920513461255ABAE9204D9CBB36766F6A4D\n      DDC40B5CED5869DCDA465BE713B59B82BEB1B9F98DADDD35C83E8BB3672617FF\n      829E7CEE61D1DAEBF745B6194955148D46924401B6B5406A7227AA8EF95B74B2\n      1B8FA8E0E0D00FD16B5DDD3CEB8E3FD9FE8DC40FF443DAB6FFEAC9F458FAE0D1\n      2B1F2799E47D250B029B901B9F56AD85826544F64DB631ECE4428B7ADCACC73E\n      5AA59328F0A75F3CC13EF3C2D681598F24ADA1878F59A445BED1EBDE896ABAD6\n      0AE9835D7AEDEEE0F9B3F5CEDEF6DEFDF8A9278B9DDEE0D6B5A5B347456B7AF0\n      EEC6F6F5070B9F7861549B9922CBA5BFCB6C84871C1640DE2EA35D060149A391\n      2B1EFADBC2004BE794DF2F6EDFBE7AE0B967FCD6A2D14DAB03ECE102560A711C\n      38D1CECED6E5EFCC9E9962416404D0448D7A9B0638A50D4BDB7EEDDD9DBDFCE4\n      E77EA210992F4DFBCD6B74BE3E7172954A413C085D6284AEACBED8E95DFEDDAF\n      1C9E98F163E1B71A77AEDF3874E464EFCA95F8A5D3E24844CA1D581ED2FAB4C8\n      A81C4180F46C2152580C47B6AF0D47C5ABABA7CEB2DE427A61D7869BC9B3BE8E\n      0F9DF8E8D7E8E8778EC2D3F61ABE9D9B34F53AAA6E1A59F8D2E39CAC8FFA3FB8\n      D5AA452564E1B5992CE8795C0EEF0F675F7E819D8A3A415153B1EF45B9C83D29\n      76BF74ADF5FD72F0627BE6A939EAA670B1ABC2694193F1B9B10379CC75B5DB9C\n      F8C0891BF9FA6E4CBCE0E011B2700C309C31A905C0416BCC4EA3149C9751DAC6\n      448863314AD300E82A04DB91197A61332CC3FCFA8D3224C9B1C39E0C1F65C1FD\n      C38F7133F8FB7FC573F52CFDF6C5F0CEBA6FD25DBE573FBB620211C9B0776DBD\n      3066F6DCE9744A141199E862BCD088B29D6B0D29013252AE0C95D8A36FE8C6BD\n      F54614D7A73F85BA8B5EA05464E224F082EEB71FFEDEDFF9B56BD777CE87F69B\n      BD6E5A025E2E4F12F30BA797BFB0746465D8E74537F373E037805D7D856A0B38\n      130834036B21B0ADD02E055BD960FB19CD7164CD54669FAE1B06590A22767758\n      CA25E1E82C8B23C225F306C6EE95BA0DF98FD89101D4A7254AF8BB1A1E2C533C\n      9BC6A115AE83A1F1376AE2DDA27DADB38B4A3392433428B5C9290E87C2DB3573\n      F57C527B6976E689245816DE92E735819CEA913BECA904BFA9ADC4BA1E6B0FA8\n      36AFB6A36AE73BA7506F7F4619D119766120B9C28450A2283615A5C907E580B1\n      5D5FDCCBF3ED349FAD4DAC26F529A2135B3642B87809ABD8F5623194906238EB\n      8E06C57886CA9C381616269D141D7B14320CF9D77E55E4AFFAD309508F41FC38\n      B6D26A9A9C98AAFF6F9C01DDBCDBFE68DD78E8D0FDE963B10F3D8C4DA1704CBA\n      C43319809F2E00625FA4A3915668348443DE0D315F7825A0F63CAD8F00DD0543\n      9F8711E7B9A42889424A090F0AADA821AF6ED4C36FA6BD52786783E4644E430A\n      6C1EB0D120F221A80715F7459758DF674238AC517DC0F1D1EEFB62A2E471BEFB\n      A3EE8D653F9408DFCF87EE1D5C4FA9F253B94F7EF0973077EFF0F458B9495783\n      9A0F0071986B507483BB3C26FE2E27E7FD7433EDBD24A60FA7A41FA951932679\n      4198D0400803DFAFC55470D46FC60284869FF4B0A7D4798DE2611AE398A7B103\n      93DA71BD94EEBB478CAF7B3CF208775AB926B26AD605791671B32EA8C8E19E35\n      BC4758504F4443CA77B9D8D0E6DEE6DEDE76B7371C0D6891CC4DACCC4DADB070\n      46D14617C819E2CD381211646BAAA445955A4C3E0CAD1E9C1B89B72F53BFBF58\n      DC02AAB4689D5F09AB5A8670949952F26FFA1A37EC568B72DCD6FB4817F77DAC\n      06EB0867558CB344416D03E0E0283BD22DD35E3E843B19D76A22C0993123ECCC\n      91A5F94F9D0DCF3D6992B02C64E0B174E36E7BE3FAF2992545D2CDAB371A23D3\n      387B66EFDDB7A37A141F3956AC6FE4B25F3FB9A001905FDE2D76468D674FE5B5\n      095F366D2099091132E318E51E231069806A56D39A80F732BC1B9CB1F5F2D68D\n      4B4B2F7C5834E6B5AE4382E3C87B7196C657C66EEF6D5CF8E6DC99695E4F34D0\n      397F9C0821E4F9C01ADFBDB7717767E5531F29A222A6DEE09DDB6D5E2E3E754C\n      D0D88A44F9313C0301F8AE9776DE7ECFDBEA41649B589EBF7FE7DEF2EAF1F6DA\n      ADDAD983E26883E41D5C8DF0DCCB9CCA02A05069523FA3BC3DB5F6DDBBB31F2E\n      C2D6A1D16DB57B637DF9448DCD6B931C3AF6B13FA1BDDF3A544B023611909909\n      1B2506CD104C4AB2300CD9AE1EBD732B025ADF20F47EB243761B7194DDE8B75E\n      7896BD38D909D346019C3F50C2B02ED9F8ADF3D3B7BCE1CBBD89E3ADFDD0E29C\n      F3E8383B5594C18C917B6901D5FA13E9FA1ECBCAFAE1E364E1B8F6EBD6E60625\n      21236627AC4D248344D87589B0C0491B8A064E94C98C145ED0F053DA7FEF126D\n      C5F59327B02F7E7FBB8FB74A2539B42F745445B08ECF662FDFC9FFFCCFC3D5E9\n      ADBD757FBAD15A99914489D40C6FEF904652FFF8998DDA70B623A8544C78961B\n      278863387A894BC0A645C4E06946A996D7EE25C75FB15393A31240EEA41FB470\n      B46A43BFF6F77FFDCB7FF09D9BF5D6ABBB1BA9291B0DF19F2D4D7CFED0914540\n      CF7B3DDFE74358B494F806D615D63C01C1960E6C7A122BC92E2952D7CF46B993\n      32818D8778DFC3D29F33CEC1F35FB8E51E908FD22167EB0DB5ED4AB5AB54DBDA\n      3E23230B8F51C75A0FB987827F0A824B5940720CFC9485D7F606F70CE9C67C2F\n      EF15A52A78032B4C10C3745E17EAE464FD13B5E66792DA591184BACC74A97D8E\n      6E1E2ADF37C4A0D529886594EC0B64D1477FA29BBBAD5A7C5DE4A9DA07D5BE6C\n      17754C110FB345611A702FA4BE1FB375DFA6BDF484989CCC0C244A39C1686263\n      B83B79E93457DDD91C8004D8030172416C87C70D482B8E431F4F841F04D13F14\n      E1F5F8300A7395EB06B2EFFB1B3F96002C3363F1CDFDC33352A9E8D831DBA85E\n      ED55D10F5616E6426C68425CE23A74DF579EB334C0914AB8FA0038BF163A8D2C\n      2B68AD8F8EB279E20538378E7DDAA1F180D30F895CCA05C09A575BF2EDDEF65F\n      6E1E7A028B33D6F3794DEADC1F167516A38C03D0620FED0A501A10BB72EC232D\n      15BA3F05F85846DBBF238F44741EEF9DF57E440EAC7A58C8FBE198A7522925A5\n      B4763C03E8B9DBE8467C510D10AD6E14644C166A92C147166C428AA0A0375AFC\n      55B95D2BC95F10F30DAD0676D010CC44BE72D399340C543D28432E807E29CBA5\n      332C7289D611553781BF4F921E19287DC046C9558058550572CDD1C4B9AFB899\n      5733B6AD36E36756581B9434B23E64EABCC4F313589BF7CAF42D3EBC1415DD7C\n      74A808CE86B32B704B25EECB38E08D24F2B18958BB4217AD569E6B5BA3D80240\n      1E95A248A5CF80EEAF0E26BAD91327E1F723EEF08FFA72F8723F5EFEE8448800\n      1DD09657B5EA23C8AC9A7C7910A1539D965B837EBBCC19F0C17A02D7329D0ECC\n      94F53E7AE4E8E77F22593E44CAF4C6D5EFD66BE5FCEA9419A5B7DEBC726062D1\n      3F32BDF9DEBB532B87231BB6AF5D699E5E5507EA382D7A754BC0E63F7AD8268D\n      3CA3611411ED63FD0073DE1EA15DF476C04203C1561CF48B9578511BFAF6B50B\n      4BE7CE412294BAE6113CA8B2CE1C180085DDDC5E7FE7754884FE444D7389B317\n      384F19E07CB936F2E168E79DDB532F9CE55358E61F5DBA7F6FFBC191E79F860F\n      A3839A0A1382D22DA89F54DE5BEFBC715E285D5B9C69EFB6E7E796B606DBB553\n      13F1D13993E71E42A20C9B8107230AC04A58D3B5E9F7F7E251E87F2AB4DBF18D\n      F3775B53D1ECC11AE4721DAD1EFAE41FD2EE6F1CAA4D27AC1590891609125962\n      9B79264754EA863F2B2FDC518361D0F0D88EFFD0EC4E474D7D350D9E38C43EB3\n      DA6F64511F089A6FA3C0DE2F777EFB7C6357941F1DD557922AE08DC9181E0F9A\n      B1969543D76E16AD541E67C174BEDD2FBB838983C7C9D2091B4D6244C1A9C180\n      DA3A907BC50A42AA44285D220CDC48589E33CBE3261FC8DD77DE09E6A6EB274E\n      C2A3791C72D9AAE4432B8856494921986DC78DF9CD8DF5AF7CA9D50802C5FB9B\n      3B134F1FEA4F911AE76C4B76DFBB250F4EB55E7E22C75E1E3CAB7491136511B0\n      EA8536B92A05D6C41ADEC58DFCCF2F77CEBCB8F0E3AF74057C9238F1629BA6C0\n      DADEFDCD57FFD1FFFAA5777BE2C2567BB96E7FFEDC137F65752EEC0C9ADA8F80\n      E18E4AEE070C154D25F6CD2158053CA798D6BEC68177A7C90FAC0092A057A9E6\n      BB56336C12D095340F4AE92A8731E0D250933253B65B943D657B440F09C918A4\n      192BB5AA4B823ABECC5939199696BA0C448FD35B727435CFD6868551BC4E1A83\n      6943864340E32FD69A3FDD9AF9B1A8B604049F650C4557F11662BFA6EFFB52D2\n      B14A6725D449EDA35D5A49D054FF2155E506870FD9564DE55818406B1A2C9FA2\n      D0237CC8DCF2B253F89D02BED3164014BC8879B5413E6148D4F055D3EB93113C\n      1341B9ADE08CF0E02F4E61801B579732FB24AD4AC0EC83B5A6477FFB009A7E3C\n      4BEECFD0EFE3A4C7638D75622C767FE558B65F8F2363C7A2AADE88E27DCC4D79\n      6273364470659D72176C6808BE6E5401B90164F64CD24051D875322429C4E4B6\n      F4FB9AD47D3A018F502AECE10F682879E6D14E319C2DA21D3FFE75B2C96BFECF\n      A5B5233DB53BE5A9484C65A5098A51C3C34AA88732BF0C274D995344ADFCACC9\n      7EC6265567E8E361FA8753DD231E427E749836A6722B1CCF5906107021CD0169\n      854D0A9F116996158C7B6E189ED9F1A16A66785C5A5264A3C8149CD486AC4EEB\n      5723FB876A6352843F534C4EEDA5C396EA2724819DE0BA608A80153EA3BE8845\n      80A9032D925115C12FB1654472563DAF4774F0D107608F25C2312573749462F2\n      33E39DAF8CAD52A37B6A12FD2581F0D344515E9042EA3EB5DBC60CB0FFDA1F64\n      B237CA0155D49B24A45E6249AC80D490A920AA71ECF7A91C1C1D32C37F43B27F\n      84BFF7452FB4DD17311F2742421EADA07F532264E347F6FF9908210B2A2081C4\n      D9D31886A22D387B8D9ACF2A106D2DD77AED8DB48710B2114CC315AA7CC0D4D4\n      93C7CF7DEE33F1C9A90B0FBF79F8C3D391CAC89D76EF6E7FF2C96773AFBBBBB7\n      39BF74886FF44777EE26E79E2C12EA9B60F4EE1D9E34C323474D9094A50E8310\n      95ECD02B0B1321D00AEC19C39E508CE7E87000710C22D696BD7BE5E281E79FE7\n      AD45656A28988A73A3106C480020787367FDAD3F9B3933154CD615852C5072EC\n      AF0E1CBC0638AFD75FBF3875E244EDC8043C80FCC1E0E195CB8BCF9D096BAD5C\n      C015D5454138453CC9D3ACFFED77E96E2F8AA3C2EA204876CD303C1AB79E582D\n      0B481839D1993BB38650D8B7C6EBDC198DDE7AB07AE8A83DA6079755BBD75F78\n      A6415437304D151F5AF9E4EFD0DEBF38545F6AE996CFEA75261209CF9AEBB41C\n      8E36760FCC9D28AEAD0F1F3C98684624E3DBBAD76475715BCBE906FF9993F901\n      2BBA1982F3A8692FF6F6FEF0520081F6133A9C7133582EDDD171BDC90DDA5489\n      905443D9A5018C2C266C5FF5B7F61A070E8995274932EDD49E95C3FF31C1D801\n      98ADEFCE08952B8D0AD40CB6D8B44E453D4C55F7F285687EDE5F3DEC0C3AC907\n      52E1BE74887DFF8B283E199ACED63BDF1E9DBF7064F6607E773D9DF0C32717B3\n      504FC0AFBDDBDEBEB33E73E2A8FCF8240B831C755A750D1E519123558DBDBEB1\n      89AEF3CD60EBFF7C8DBCB5BDB6B4F2C2DFFE65FDA1A3854E035B0935A9F3DFFA\n      C1DFF92F7EF5C22DD5B2C17F72EEF45F5D6AF2CE26DC877C38427205E1BC24F5\n      A04152891258566590E0AD1BCB72194357AE82D88F4F055060C39C34067123E4\n      54E2C9AF4D0A541B058C905AD697AA0F9B595B487E196112C7288874FEF49029\n      15D6EC2440AED4F33BF002A9B860B2EE5F96E9F736DB52C6C43443B63EEBD14F\n      2DCFFFCCD4C2330335374C896F7BA11A851EF77D0C700A6B923594E0C05852D9\n      BA9A2A2392C747A071C70AD7248E7D12CEEEC73D70ECA5AF2AD3F8C3840380ED\n      0F4C3E505EAE8574F11B2982CD8AFEC26C2B462250629F57C49D4B0EDA31FA41\n      E034FE5106FB112B75C77BD6D9BFB994F8D85CC4A362A0611F08223F94265DC1\n      C2D932EC9F318E4B18D8496BF773A4258F52AED95F4EE3D8472A31335B8D2628\n      C70E5D5F27E445277480B158790543B9A986E2B269466146AE93F01DAF5C8AC4\n      33E85B5C74EBD8B684A3B95CA4FDAEA4B5F3547CBDF7F0DCD1D5B35BBD03B9CD\n      5AA18CBC40E63E372A6468D405904008946CF25C354D70BC274E6895D0F1B1A6\n      BB2548983F70137E4446FC208670C5B7AA9452A91AB917D98078956823D64721\n      1F1625E4425175BFE0488976B78E16B0C6A5122ACFB86C87264CE9EAA09647F5\n      AF3646AFEDDCFA6CB2FC093231CA3AED200BE300329F7598CE54403914A5603A\n      F45143119874E97614F71E4DF5D00F5EF7A3448817853C953AA8E592A693DA76\n      C7D5EE9CD6B87448501B30F3B0BB9564995768112739F74603C9DAA63E148445\n      3B91BF1BF3B6D94E2887359F48136BD564ACE90369B5D8568E580E5335AE70C3\n      C624DCCD69126F7FC138008E2B73CCACFFCD75515A55D3FF7F30428B52316A5F\n      05084FE57C02EB0278224E1817810054BBD6D959DBD9D90EA94D926992CC97C9\n      DEA0D73A39BBFAA1F9B9E71B339F5A21C56EF7DD2BF1DC9277F45071F9FCC324\n      585A5C3637EE85F02EC7568CE05EC9BAEFDEF06796C59193254402A58417616B\n      2BB6538D08D905E08D636C5438297B00CD39730E79F4A159BF7D75EED9B3ACB9\n      4858D3E040B641E56F8F858693ADBDCD77FF7CEA74534C25DA42162818FC321D\n      A2C88FA7794E1FBE7AB13939577F6EB50824DB955B6FBD3773F689606626E5A1\n      07EB03A017E310D63863A30BD7F4F95BF5A405EFDAEE778D6FF9A178F2CC718D\n      3DF5A9674B1C16835C9B77F928B8F9C683D9A8D638D4CC55B6F57677E1E4829A\n      EBE8B45DD773A6F6C4CA27FF05EDFCDA72FDC8AC6AF9A25667B4860A5E3EACEA\n      BC7767637EF14471777BEFEAD59946DD637C4F0D82A1686C253B54463FF7043D\n      11DBD108CDE0798B7C7373F7F5DB9EE0B557286FEE8B75B16A85D3B1388A5B2A\n      660CE1D1ACD7024656A2B3B193B416C243A749631E1EAB46DD42586301612E11\n      5AD420738910B61A77A2623247E1F9381C8D7AD72E379656C8FC0A9A6ED0F70F\n      45AA0DADA91BD1D91717C66F8EFCB469FDF64EE78B7F34E77BC0D6FBC0476767\n      D4B1A99E9F4D15CCBBD1DBBEBA9E9C9BA83D73329D0C0BAA6A84F022334C8E3C\n      1D89067FE86DFDCE7BED57D766D2E67A9E4E7FEE95A5BFF5B3859F528DC2BACC\n      E67B7BDB7FF7BFF9D5DFF98DAB7FF3D35FF8A5A3F3F39B37BC2225AA3054E6B6\n      305A05D697DD22C26367AE3929995698C5726C59D51141211B37DA846B0B67D7\n      90045676A5B0CF2C3656FB524BC68684B68DEA48353024438971E499CA9D58E1\n      A6A704EF92461F3908CB236E86DCE680CCFC60BB94E747FD1B23B477F359EDE7\n      D8F0234B332F2413B325C4596C5E738A1E109A31B64AC49A16C7A40D7647386D\n      4807549C60B5AECAA16CFF448A521F4B17D4CD83992A0BBA067EEC5C725AC442\n      4A938ED2AC0B17C6422FE4F01151CFD5C8A00CA700745A321A46802A84287D91\n      41D01110F07D1F2D4B21B8A116C8FEB0037B14B82BFBF8C747011E653BFA4174\n      F428F4D371B674BA7D9548245EA9A30E78BA50927D0C45ECFBA57D27B353794F\n      3C2ABC8E67D45D472675DEB70CA921160C0DE0174012BD304BB2309249266444\n      73607E3782E80D355AA4F4E5129668D9ADB1A07036A5A5F287A31BF5D6EFB5FB\n      32559F3DBCDCEC6D260CB8630D826FEE9711CE6BD22244DF2524631E1DD75E2A\n      753136A66F0E7D32F34375E1315FA4F6B18230211FDC35FFDA6C69991ED343C7\n      808D2E4AEDEC30D9BEB458756758E967A694A837A428722F1EE45EDD26ED50BC\n      963FBCCDD20F4D2E9EEBFA44F6F2C46A1FFB4811F36A78E23C67368D2011E239\n      30CAA6BB793BCDC646128F1745DF4F8476FC0C9CD47485B7ABE310FCF495126F\n      650A51A570962A2FF0D2328594E6FFBF8CBD79B465E75527F64D67BCE7DEFBEE\n      1BEBBD9A47956A90549A6DC9B2658C3118D38CA13B045869422774D2BD92954E\n      AF26F92BABE974BAC9CA5A1D92954E8006DC0492B669C0C6605B0D18DBD8962D\n      A1C12595AA5473BD57AFDE78C7337E53F6FECEB9AF4A865E8D58585592AAEADE\n      73BE6FEFFDDBFBB77FBFD0D785F4146EB61783AAC80047F8395A180929CA5A8C\n      3BC01578147FF13C06A910B57F05EEF362990941A8624DF3182F0142D1BDE769\n      9B4448F6C607FFE1BFFEBD89704AF29A92B95C83147F7FB71F0A9989A2C42E75\n      CE6C10227D9129B993A55F5EDDDEF4C572E740B42D935694F111D7FD734F1C5C\n      786A79EEB18383E19DC5674E0E6603F6AD57F9A9933C8937DE7EF3F0CA1C9B9D\n      3590753627BB97EEF44E5E28F71F2D2D8BCA2CC09606D624507E1BB26BEC041B\n      66F02CB0862FAD2990CAC604BD936F6DACCD9E7BC4B6F651DED10A754190D227\n      4404A87063FBDEB7BF3C7BA6CDE7B14182EC3A5C3146D9F389A76312ECFEE9E5\n      96F6A3174E1761C936F29DAF7F7BFED1D3F4E87E2D5A9E749A67E8DB8E9E2966\n      7377E70B5F9FCD985D9ABBB7B316C18B3F3EDB7BF234F1903E8F0B34949772DB\n      93A5BCAAFAEFE4CB170EDAB9BCFFC6EE64233FF0E8FEB2B3C94926C66D925C38\n      FAC14FD2FEAF1E484E2F973D2F8CDBDCC6A84483934B95DDD9EACC1E921BC3FE\n      B7DFEA793E6D0769392603DE1974EF6693E4FB4EC64F2DE67212426C333DFBF9\n      9B5BAFAEB2B6E87E80B396A91783E8343E3A1841EEA334E274B9F0044396F187\n      9B432E5AED138F91EE7EC34383B431EDCC67E17640E49D706C4C1B5707213901\n      92A284FF8C45C1B8DFBFF4DACCE187E8F2715B96647A741E2886EF53AFEA3609\n      CF48DAF1C3BCD22F7D65F3AD6FEE3F7D205DED076322CE1FDA3DC0B9477B233F\n      7D774B5F7B873F72C47BF2985E6E39BD095C4CB1F7C6936BC3F19BBBF7BEB116\n      0C235FC5A32ABBB7D2F9E0FFF89F278F2D1BA77BCFF40EF126AFBDBEF1DFFD97\n      BF116E064F2F2F86D55040EC57A622957453FB009E74D0F659D4F28385D89BF5\n      754B8D3D358234DCCB84270DA97083BF14041E6E86FB52E8551B4A1E29A8855C\n      BB962AC5F858AB5DC082C60010447F79CADD7CCA482CCEF1FE1486A68256F02E\n      F2D22F4BE3B39D905F36FAB5D178B3AA124D3F10773EB8B0FF7BA37496F80088\n      8D55694491354BE90C840BD7452A2055075CE17EBFAD853F9A1E186B5C326AF4\n      80FFCB58E3E453FF3F7A8029A72CC56B5F27463C25C9789CA6691E56B82B826C\n      172A2ADCACA17E9B390B9312C5C48528153110EB5BB1C6350EDC0E68EC56D97D\n      E87F1FB191FB0231DF391EB3EF4906ACDE1D700A397508AD75A5B5769E65DAFD\n      C0221F804C23EC1EF5AF0E45666AE15BFB353649B0260E21D7C1F53D348AD451\n      E77701BF7CE2ABA8E25189969C107721226CF1E05A5ED2B43C13855DAF8083C7\n      D17E26F027653029BFB56FEED7D7D61FE3733FD4696BB3A102326F5A01256904\n      F58F816050C6CCF7FD9AA63F155163F520804EFFAA23E474A76D6A447CBF954D\n      F6D2E15F4E84DF91209B9F4EBBD075E3DB893C685556D6113585B3B982A707D5\n      EB98E8925B519904B9146C42CD4CE527B9D89AF17E35BF9672F293D1E9A3E924\n      C392879196085083D07DE040E410E470D6803D700B9017F359B3DB6AA68DDFE6\n      45DB8601DCAC85ECBD6232CD2575AFD62542373D74A20090718BD2896E9B4C57\n      A8C6073046B252D19D428F4B745A0CA95F3885D369E183DAB20437E9791CF93E\n      D65C15D41D0167587EBBA161BD8FE2CA9F3D01F3FBE1C8D8BF5667F481D6E87B\n      073D4DDBA1F9870C570FB9AA154D715E69DC1442BBCADF8D52D069004596AE67\n      FED736D62E1779B7B7D82176C19240159CE9D4E6BD8333C9E1E4D4074FDB19DB\n      6999DEF9C7F349BF3FB8B6707CB66823B799DCDE2E5747730F3F5BCD1CC835C4\n      9F3420317E060EB5CFC0E2B26B8A7264008D21AAB112F98F284115903BC39DDD\n      ED99871F35D13CA022381D3EBA1FC88A89D804747D7BE3D257E61E8EED6CC2B1\n      C8518E111E5AAB4681F179A0FEFC36BF3B8A3F7C3E9DB3FE50E75F79CBDFBF48\n      2E3CC4BDC4CB3D17024988701BA2A0DCFCCC97C96BD7E7CF3EB45D0EE3529313\n      4BADF79D247E5A56F802352BA1E6E1BBD5F657EE24F14A7C6EA16F37477F72AF\n      BB1877F6B7489211962AF84FC2274F3CFB493AFCE5839DF307271D16C609DA22\n      7A9E86734174BEB61D415E9462FCCEE5565A98C58EAA72F8FA71DEBB3B1C7A8F\n      2D2E7DE4CCC4CF505723EFE8CF5CDBBD74D7DF17B69F868F59C3765B87C6E6BE\n      D5C00CB9EE75D8C2F1352E0B1A2F9DC874502C9C7A8C2E1EB3ACAB1171549CB9\n      B903EEABE6980891848E6AD48CC06723924686C5C164AB7FE92F668E9CA14B27\n      48953F58EABA53C36AA3CEFA1FB8AB60D19F99F9B8CF7A7775ED0B7F34475418\n      4583BB3B9CF9C94387D295B6A4B64B42F6E6CDE1F61DB9D89A3D77942DCE8F6F\n      EDEC5EDC48DF1DA7774A39E290192C6047C9367975450E573E7AE187FFC14F86\n      0B3DC4AAE9BB22B84782F93FFB833BFFDF2F7E6EB436D69D76EA1A6508A3B4CA\n      F36230816F2C791CABBCEC7ADE015FEC27FA40C73FD88AF631EF40D89D95342E\n      95AF350A5B7AB44224A7182E8E79683C83A6F54C12B2359E8C2BF88D7C001595\n      6BCB610317E78DA4B4F06B8D27830DAF1CE93CD6144AAD2D42DE30D9B726FD54\n      91932DEFE3734B3F1ACF9F18C8A49DC1F1D21CA11F026E01EF44C11980F48B99\n      8A411D0615B3F04C59BB11D829230E4295E77BA4F13168FE729319276F883F34\n      8EEAC074653D1AAACA8E47793EC90163C7164B3A85D52DE391EFB521C6604E34\n      3263460B16303F227E0855034E4BEB1850738F9DD36CDD859B8A65E36BD67B5C\n      996658594747E72C4F1B6D4D42DC6E6F1D26B5A9A323CEBD240A32DB7AA7D085\n      CEB096776DF27EFD67DD9F36D366F5BBE18EDADABCC8456C5AD77A8EE584E7DF\n      D6DEB6F0BE14EEDA5B51787CE0C3E1E7E3D4BE3D1E77577A6799DEB73D327E34\n      F0452BAD98E27FDC0D3E75E7EEC77A475E2CF2309C8C239AD8B0630860C95238\n      FBDAD0F545EB9A8033DB384BDCA72CD5D5277EF5BA4C6982F59438E6584EF731\n      C77BF7C11FC48BF4813B659A32A2498ACCFD76BA42036874E0300E59E3E6038A\n      C21BA71A86DEC54EA92E9134906C1C7BDF66E5B7D6D7E67B2B9F68CFD2E14E1E\n      201B5F082782ED391721E4E040D5E5D940285FE0B6D55E3F874DEB9CFA5339A9\n      6B378AC3BF6B721F367177ED6B83DC86AEE2D2A033A945D90A214DDDB550B6E6\n      5AE1A2525598B2540A09D23AAB7C38FA7517C03D04053592274812F8A1C70214\n      3C5670F4339FD46C5407E6DC3890EE0D569BC92B6DCEEDFD87FC573EF67AA767\n      AF0BBA973ADD20804C1361AD848ECE29B43E774EBD4773D705767327A111B222\n      8AA55CB66657D3F2F3FD8DD7AB7162BCC32468792855D74133039287700327FB\n      C3D0BEB078F2F8A3A69C1C39DBF39E5DCA5B25C4C3F2EA5D9BD1CEF1274DB8A8\n      20FAB20AC55E91EC2E2BB30D88D06700FB9D7EAAACA849516508CE5AD022EFAE\n      6FE7F9DCD9C72AD1E3A2EBDE16E4285332D1B231BDB3BE75FD9B8BE79322F603\n      3489AA9055A7E089AA490BFE53CF7F6DA778F346FBC3E7C72BC813355F7F77A2\n      64F4C1276D904455085F4B7BF0CBB0678603FA37AEDDFBDC57BAB3B332107EA1\n      ECB15EFC81E336A848414A5DCA78D236A6BA9C0EAF6CCE9D3BCE5BE2DE951BEA\n      6AB1FCC41C4FA89599E5E34A083F7AFFA90BBF4E47BF7CB87DE148D985AB1571\n      2804B80FC70462B6DC1EE9BE0CFC767EF5865E5FF7F72DBBC65FDA52B3DB8394\n      AC448B1F7DBC5AA292E6F136CF7FEFDAF0C676FB78123F49501CD01DB23D6C4F\n      9D7459D38CE2AECCE2C8E6222C223C2E73D5BFBBB378E8143FF08841C5519FE1\n      223C2E9901963008115093C451433473168392B72D6BF9E9BDC1A557BA47CED1\n      C58708A0D5FBA7AADEA362662AB8EFCE0CB646525CDDF2502ACCD3DE5BB746BF\n      FD7BBD238B5BB450B72673BACB1F399EEE8757927779976CF5EFBDFCFA701BD0\n      62EBEEC6481621D14926BDC28AB454AC905145533EEA7325F7F93FFD0BFFF5E2\n      E3E72C20A7EC3AA177D07A7B2DDCFDC35BF24A3AB641214B539546490FF57755\n      5A66F06A57B7B6876999A66A3C916BBBA32DA9502C9893034BBD738B734FB467\n      1ED3E2E0309FC90A6B8AC2B732F67257F631E61715640C3DC8F31C1FAC9F5695\n      C27BC02AB4870180A8553D74C9F58014B61516425C9A94AF9BEA763EEE48F5F1\n      EEEC8FCC2E9C25AC6774E2FB4A17A5E00AD5C938FA3A41DAF254E92111DE7364\n      4D884B159AE4150DF27352A84288BA33B3B79D829AE075EB865B27F4AFEB162A\n      EE705450BB7A13C882E39CE1DE0367068E2D64751E856127C68DF0CAD7B95715\n      A897425B0C49843A08B0F4A1B5B7724DB3A27B03131C88D9FB5BCC9ABD17D7B8\n      66BCA9E3C303C8064536482D9CE22443ADEBDCBAD485D2D4ACDEE4B2DC4CC1A6\n      6D925EBD215067C2691AC47154F35F99468ACDE18FC6EE5DD4F47E9420F153BF\n      5254C5D22F7980CE2639920FFEC896AFC8DD9F3C70ECA9D5494909243CD39F90\n      B9E5CFE4C36F0E073F78F8F485F5CD599AA52DCE4518C143E51594E580EC631F\n      11BAEB15DB0746B6D359D534D4E26E1EFEC59D10C0746104E7A676BA61E1A832\n      7F9DC69D2B35F6D8B6B5C674334FD54616254AB261B906CF102E9885EAA982AC\n      4F9CB400DAC518D40B867FE4B7DF2DE557F29DE7E6170EA1C486F58CF30EF789\n      0DE183A01B1AFA7FC101F17D8BBD5F564F3C5D4FB6C982CD96826B19369BACB5\n      F370AD1D6B1B4D9726113A0FC2FBBD015C18B24EDD055DDD89B24DD18CE24A8E\n      0C04C525FC9546F55A241E092813EBF606B55120429F63EF16A7D5DAFA8D28BE\n      3B98B80A890C16CEDFB3BC35ED703E98F6F6D8ECEF79C6B45E9F78109AE385DC\n      FB8735A5CB2948A3063977DB95CEAF062F997B187874854666131CFD3CA812D5\n      5EF3E3CF6CAFBDBEB3CD8356E4F90B8AEF2B89F0BDACE3897179CCC6B7DA59CC\n      A25815474E758EFFC899E0915E30D3195FBD6D6717DA271F23B24D39D7A1A285\n      C421A897E56AC3981D1FAE7485CE4014955032C2150AFC324FBF7E3D0D829933\n      8F4BD2612C761AE759851934F13500CDB59DF5D7E71F69E54E6208AD94512528\n      40064E82EC63FFDBC3E1D7DF9A7DF15C79A42DB4B0AFDC4C4793CE0B4F547137\n      D02153024E45014516B701BCBBDD7CE78B7F5E6EECEE9B5B1AF487E448D07BF1\n      988E435106B9DC95AD413222E9CB7D15D0DE332B643DDFFEFC65B63C3BFB74CF\n      16635AC063DDA95A34883FF8D0B97F4577FFE5C1DE530FC959088382DB90A284\n      1EFC09252F6DBA396EB15679E76E76EB4698EC0FDB7CBC3B0855528C75CECCD2\n      0B8FD973F315DCEBF56AFC3B57F2DB83E44C1C3E06E15321BD78AF45431B2848\n      A68910CBB3864BE15B2F8617375EDD0CC25EF4F033263E6C4CE8DC8533D755C2\n      9533A80CA93BF328EF4A7338C192CF182F0926ABC3775EE91C3E4F171EB6E5C0\n      0D2FEE6741D74B994289E9E4BF2FE882B4399355E47777B2ECD32F659B37C283\n      F3D57AE1DF01FCEE916333DDD30BBB77B39DABEBEAF6D00E4C56D051654ACAFA\n      6898AD34B27759378A665AC93C95F1BE245F62473FF17CF7C9B3035D757CC034\n      9B9AE6E67646BE70A77539239947CC984084CFD1B107754970B852D8D02F2D57\n      2219B0D6D5CC5CCE8B9B94BF331CDCD95C1D0DF258914767C217160F9C8B3A07\n      7D218A94149304E2A1AE4A457779770CD9542BF4D7E0BC50BA36F7D6D691B78C\n      4B848C95797F20BC41105D2AF5ABFDED6D5DAD84FE4FCD2DFFA7F1FCA90CCAB7\n      A2DFB2C380B775E46C138CF14D19A2651A64041FD0A176222594B96D005CE640\n      29041FC5405089C6DD4B8DE2BE740F704FE76558EDE0BF85648A4B0371959A71\n      3F93504438C20502389A2BB4730E925698A00097CD89843F5DFB509089C80348\n      E6553898D4DCA9DBB870D07808D551C6AD6F38C3C11A10EC419C9A22419A1FD4\n      232D78F7280DAA1457AA514E4302052E86D581D63A3789BA75E87CF4F434EEB8\n      E451F3275DB3AD9E19B207429B1B48B9A25F370F00A3B3A175D318FF310BA074\n      F294F2B45FE12EBC9CCDD2C2FA9F9DF1FFD9DB573EB66FE9EFCF1E4BFABB95C9\n      46CA6E2FECFFADAB6FE7B1F723878F9EDAD85940C9484FC19DC00E942C026603\n      1679489E370F30C298CB8B76DA1DAD27A6CA09AB361F03F14DCDE775A3E7DAC1\n      9DD65B10EF19A4FEFB12A169FA72D3B99CBBC9EEA6510085659901B0867F1099\n      C2579009FC0A05C2288702C054A9A80039B0CC44AC33F0826F8C76EEA5DBCF1E\n      3B7EA414BD09649F4CB53D28BF4420681DFA51ABD5E3AEF7DB2886B3A98B329D\n      6ADFD9BDA59686253E4D274D227C20D3D85A6AAEDEB6D1B5293D8A4F5ABF340C\n      25FC0D76ADB98B4C65652BC9B24E9665A8638AF110CD938C7BEB807701C74065\n      12505C964493DA5A9A81B968E3B211AEDB369FB03E92DC9D0FBB1788FECA2CE8\n      58EE666F1C781F9DD70CD5FBBD2E9CCB69C062D6F98D20D308AB5EED08EE8E3E\n      CD9CE61C9E3BC926710E356C7B356EFDD6DAF52F0EB675D43A44DBCB58AA17C1\n      4C305FDA857E29A2561885FB235F9577E3B3C1FC538B8BCB3305449BA79FB087\n      4F7865E0335A055555469C4A4B86D66E733EE6A8FA0C8100AA8412B787D1D5DD\n      332C907F718DCE2EB54F9C95B4AB8D2790ED5E40E0D3412B54A1BE797BB87369\n      F6D120D726C45917044401550F6A92845088F0EE6DB5F595D7679F39454ECD42\n      BCF4DEBA3758DF997DEEA9B23B234C204ADC9B2CA02A54653429E110F6DF7C7B\n      F3AB6F3CD439B0391AD94366F1A30F9B4E9B679C88B4A27DBE5AAE7EF9D6CAFB\n      8ED393CC7E6B4B7F61937FEF51EF00A9C6235FFB968D4AA1C2D673271FF975BA\n      F62F96569E3BAFE684123C8004EE84E195C97DE66D5FBF2732DBD6A4B873938F\n      67BD056F52F4F918CE78B43B29BBA74F441F7A482E48BE369EFC9B77E9DA509C\n      0BFD47D164C25D9807BBE47522743442BC3E460A2C67D0314404D48FD5C660D2\n      CFE61E7FD1F4CE68190956A16225C246A398F49A44481497BC4984B39AB7C2F4\n      CEE8CA37DB871F23B3A7A91C10BAD71D63F76784D39AB18ED4B9170A9D0B61E1\n      CA4205436FAEDFFDDDCF2F50786AEDC95A26B6719577272AD52059BBBB694958\n      4A9AE5B84510FB7C36648BEDB01BF958C4B63CD30E9675A2932A9B93FE138792\n      F79FCAE0C82848F11241BB129B9F793B7875D4CE22536D595559786B0567A53B\n      4BBA82875CA98248F8092F3D2F0B04DCFC62548E73B395DB6F4FD257C6E31B1A\n      97B64E86C90BDDC5E7A2E46051C445069FF03681E4A7A40F9591CD501B8D6AB8\n      A9943B316E5AA223A1AAB4AC02F99621AF8CD26B83718FB20FCCCC7E6C66E603\n      223E00918794BA03BF5C6B59FAAD0566014C9606D0AD1BC40AE3F9803B707F84\n      A28532470851C5CEC0C6C52353E716378322D33D83865AE23A974EA1131F0385\n      575CDAC9A04CC790D704A4390897C8B2F124C492761289003DC271F38012CFF3\n      991F92008FA2746D388E54852684D85A7B631A0E30E2B89CD46462B779566F79\n      3BB784BA59E9FA00DA99CDA3D190765634B53A4A4D71E0353BA6B66475A4503C\n      29DC15F5B489F9749AEADCB8CA3CC09DA9F566EA9C5A771E1C3433F5D66ADD95\n      A46C0C184256ED12CD3927BE0FD5CC4C5E4AC6BF36D3FEE737EEDCEA0F7EF6C8\n      A9BF1927E1F6FAE64CF79B51E7536FBC726EAEF791C5D94365D593803F7C03A5\n      302DA573DE62BEDB2411BC7691A80365FDBF8CEE8190E69934F9C2C9EFD43345\n      3A9D3791262FD6D3C5BF94F8BEA35FBA6710D8B4A459D31FB68E910ADF57A1FA\n      0CFCFF1C7AA4D18A795C0B5FA1CD1E3C9D52E752AB246A1719DC0438EDFEE7D7\n      AF2EF4662FF8B3FB0A9D4019A4321A0B867BC2460BAE7D3867027911B8C3EB3A\n      DBBC1988367BEB0DAEAA4F02A95D14F79834763A0C9D7E976658E83AA80D0115\n      C288A80C91B8F387E3355579DA06DA32148D55D2B4C66936017448B13F26918A\n      822E0E5CE984920E612DE4F599B28395BDDBA181CF89CC9EBAF4C04FCC9DBFB6\n      63169B66A782900770E15FCE850E597E6755D280F7079ADE285D80BD31E7BB69\n      EADD1297A7A953986F342FD0938BE6591AD46B60DEF5D0FFCD8DD53FDDDCCD45\n      329BCCB574792E101F5E983FEA7BE9F668271BC4D402E68A0F90A5F35D1D2BFF\n      D489D6777D7832331749882CD5849782EF17A4B4D536B73B9CA7503CE88A2ACB\n      B115CB7263D07459B056FEE66DB1B83FDA7FC27A0BAA82D3557934870F5C9220\n      32ADEAF6ED7C7CA57B96031A17CA0D189980E20EBE5B8AF2E6A2330876BEF25A\n      F7F43E7E6EA5D0C67FB7BF736D6DE1B9A7646706701A2F5199350DB557568136\n      981437776E7DFA4FF60F2037F0F1427EF0E38F92A519592A343AD264FBCF2E66\n      E3FCD0779FA9F8F8DE1FBE7368A74BBE7FC9C8AC52DA876A9CE75067B2E8A9E3\n      8F7F92DEF9174B073EF0889AF77242232F061CA06CA9791504C1E0CE6EB93ED8\n      174493B55BD1EA6C3EAB755CD0EDB4AD3A83BED2ED99B98F9C338F4472635CFE\n      D695642DB58F7AEC31B4DD6D3AF8D30AE8BD8910DFAC14F8D2E006160C625FEC\n      8F8BCDDBF7BA0FBDCF3FFC7EAD5A1C82399D30C621C24020C544A81D170FD748\n      533803159BD32C8CD2DBE36BAF24871EB7BDD34CF5FF8A44B8D73999421666C3\n      9C550154CFAA94016385CC5F7A3D7AED7610B5D7EF6DEEDE1D15233D009433F2\n      20102BA799D08EE2AEE7CF066197909642DB51DCB24F780AE5BD9E3349A96654\n      F2E8A1E0A9657ACC9779061F8E041CB99117B3E2CFFBAD2D403AA312AE166AE6\n      9310BE7009B05095A6E244B6541557151C120092508F89AC2226863F731075DF\n      F4C52B56BED6DFDAEA0FCCF6F0B0D73ADBED1E9D9B5D8AE35E5E6D4F46F0F1B4\n      C750635A29C8249E1F4A88B90A220AC9A99D48F5B2B66FA73B7727D94381F8E1\n      DED2F7757AC7A10AB32A656A1C311289589AAEB659803B064AE06BF2D15C1799\n      889A429526D03714A22E231E9484CC195ED4A4043AE55A9A26FF3117FA8DDB01\n      10C4853FA33CEE15B91AF5B332331C758399E3EF291F004D4B78210F03141A97\n      70E23C865AC2D413229470D051BF1A8221DAD0391F05BCE766BAC8BE07FC6A59\n      B16669D5A9D8340D41DC3176167A8E02E3FAB47BD1453719AA69EBD52887B9AF\n      C09AFC80A0A11E4C36131EFCADACDB197793A67A4CE666D5889291A95F3B164D\n      DBA8C8E56F14B39C2E11A7A1D48144E57E25001EC291AEE0A3AF7ADDFFA75FFE\n      EADDD50321FDA7478F5CE8F7DFE9767E4FC4DF7CEB8D9F5A3EF478CB2482C52A\n      4C8CB0BE2EB13AC4A400400BF222C7756A5720387FA21AB14E4D77A70528FA61\n      4F49B6CEF0004D64D97DFD2E97CFDD76C55FFAEB2FE7C669846EBA2C757D80EE\n      3E6E911C9DEE24E0C2A205A90E3F11F3217B00EE40B7265C01D752713F50856C\n      C56DA8092F12FBEDABD74E2E2C1E69CFCC1A1B419C848B10B2CA471B1C2B50D4\n      09400F0649CFE515B735D7B4C6DDEC75AA65841D6BD45F6F84E2EE5334ED7BF5\n      CFAC7BD99AD61ADF18A58C13A3C74508402E858A2A2AB03D6A717FCB7A6951A6\n      051A3955C4399D62AE23BE25B1352DC2624B7D6BAA0859BF4C38716061EB219F\n      937E7172A30D9189D7BAED7B75C58394DDF73E61FBD74984EEBF3476CA0973FD\n      6A9453AA1BDE3513DA3881F8A0B27DF4EA2241A95910DCE6DEEFDE59FFB7EB5B\n      D77930EFB74F8CB327BAFED3678F7D2409535265B28042548B51B0A4D889CEC2\n      075F14271FD72C6610AB489EDA2AA03342A6D5F67553DC8D234D5B01F11382A6\n      696965C6A1203EFC5F4107D7FBC9A163BABB4CC58291B82EC66D6A982989EFEB\n      A8B87ECBE85BF1698D62B41211A5E69EB5C840CA511505924DB4FDD5D7C2C530\n      79FA6449897F637CEFD2CD7DCF3D63DA5DAE43240AFA10624DA8E02D991229F8\n      66FCD96F906FDEF4FCE86E373BF69147ED99DE844F02150777D9952FFEC9CA93\n      CBC999FDD59DFEF5AF5C3A7DFA8C3A5DB25D018FA824BB812D84EE90F0DC81A7\n      7E9D5EFFDF968E3EFFA89EF7336A03BF25B0752425944170EF2B3EBAB2DA92DA\n      0CB6C3CB8BBBC94EB05FD0BBFD5876B31DBA236DFCCCE1E47B0EAB7EAAFEF595\n      CEEA583EC6F985C03A76432DC130957634D34458B79A48E57A64504BC8205044\n      44920C6EAD4FBA47F73DFA716A7A8C00D09E503F44A4C04A488408FB1955A2E0\n      24859B51D9594582B8B83DBAFE5AFBD005D23D45F5605A0C367F06B57B8AFBCE\n      77CD8D9844EEDB84638B55671A3E451091B777367FED257E657560D29BB6EA97\n      2D9DC634C1BEF8B14E326700F4411988A578457CCD5042132E851720E8ABFC1E\n      6F69B8166265A9F5C251FA5834A80689091CC0AAEC9572FCEFEEB5D62B969AC2\n      A8D46652E56125713F516A897C2F2E2A817D24424AB48E86A23A878F19405C28\n      5194BD52246F27EF04E6AB3AFBD268F7CDF56D23A267DBAD7F987292B4003915\n      A87E857B0D8279847B130D689715215FEDEFBCBDB5F3DB6CBF95EB177AFCA797\n      66BF87C6B388422C8DD17B9449E5873E0902C8CE33AA5F795EE9F90AEA2B85E2\n      E21C0ADBC0EA98A800813D435B23122866EC74F98590C6CA6E4A6470AD1824D5\n      87850F79997BE853980EC7FD01A466F871883EF110D92045591902C699491814\n      2290021976889DFF6248B84FBCD0898903CA55B8BB8B7FA0471C61429B262834\n      1BFDCE58A466B0B8A654930851E60B77DB1102D656F26C1AD6DD7C4FBB50E9A0\n      2DEA31C3ABAD371FDCE8C834610777C5F6A0148A77A0D2014E045D92AD3B5614\n      81023A28D4EBDBDC2519F81301D722DF02DB6FCC09E691A4C2DF3615B4F474A8\n      6D280D2025A803A4EA7E6194FC37B7DF1ED3D13F39BEF0B72AF2177EF8C92059\n      7DEBCACF1F387ADA4B735FB7C55C1BFE18214B5E7A06A230D59E2D43EC853297\n      1B700433D5B961D33B57F3B5DDFA50FD0DDC256C5AA9B5842A69D6316B58FCDE\n      803CAD35F6D0605D2E342D5184387B3434970B1D65D83D1B2DF3BC0C25F1951B\n      D0E18AAC9376C14E37F14B74073521203DBBCBE7AE6C6CDEDCBC75E2F49183AD\n      76779476E05D708B9AD61E26419707D186054E2575BE88F5465D63CF329D88D6\n      D26BF845D130EA41613CE25AFA7B08AC117971BB10786094A395610A941A3E1B\n      9A4C41018E964E380FE8A64AA39FB92A4A54019684A3C9B923603951721308EE\n      79222E46707205948A3E77C6BB1A1FAE83B2F56220BE118CA4864C812B992E81\n      DC17F79BFE659A06D67B92259D62DDFBC910F772D1E41C4B619709DD5C900AF7\n      BD4C3332AC533281A4C15880B61955DEE2E166D8F9B5EDDD7F797575BDA4F314\n      65E30F1CEE7EBA37D33E72A06AC72A0EE316890E7BE6B145FFFC9395D9E79B36\n      512312A902DE5B39B1D96070F9B5FEADD7A9DE659DD09B5FEA1D391C2C245A8D\n      B92C710B626826832279E89CF47A95ED425E0D015AC9010070291252F8E9B5AB\n      BEB7EE9FAC888208AA1854754C68054F9195A4E0DAF727E1E637DEA4B15EF8C0\n      2325BCD21BE3CDCB3797DFFF344F6609FA80A318341CB5002F78398ACC0C0FE8\n      57AFCBDFFD9AA0DEED397AE8B993F6B1682719C77A7FF8F57CE39D57573EBE8F\n      745BFD2FDDBD7B6FF7EC271E4F835BAD9D05A964166D045511668BA47D76E9D9\n      5FA6939F9F8DFEE3F7F5176D44C3A884E007D7CC8898C92C8B724FDFDE36A36D\n      DD2AE5BA4CB7F385708117C518623A098355C5231EFCC4B3A61B6EFDDA97F66D\n      AAF2784B3D2D45C0040A10581E3005B887351D0D57C5A89A6A4CAD4F70E1AC2C\n      E1EDC76DA893E9BD147D0B9E7961D43D14EA19C81684F415A41EDD82F71DA0E4\n      3FFC24A46CC2F4B0E4B3156BB7C717CDCDAFB3A31F1AF49E9BC9EF56D80BD09E\n      531744CD1FC17115174AC542E3B21AFC14D936B84B5B51D30E4256FAE6E2C6B5\n      DFFDFAAD376E1486C91877997B855EA1E189A55952EB28D62B791AA95935A3CB\n      55FEEEA2C2770A221B7B3424DE6CE43FB1CC5E385C45433822840180F7E90D32\n      F9B3417993FAA394C802D9049544731E091F0247F6A446124E999C38F8C2E0CE\n      690E90575A5610559032C255A70232C258B335A95E5DBFF75221BFD026A75756\n      3ED13BF1C1015B198E391D43B2EDE783AA33B31DF5DE52FEEFAD6D5EADB288ED\n      FE74B7F777E2A3672B48199322943CC65113862E147340EF2D288D2A5AE0DF09\n      7A4E031A149EC702E46298A613C9EB4B5D52DE425B255508749EF3DC70028205\n      BC150815288D0D203357C340EC2FE03B9A353BBAABCC5C3F9C9D04A390EDFA70\n      4FB29099280E223F869487D717BD13D08218E551A04C097C4BF72A67DB30AD6A\n      C271FD436C3D023CE58EF1893BEF1CD3B6331E2A2D806EDC4FD1B65E08445501\n      1C8DD57590B3EFA0B4C2957CF8CCB6536213AC405F5FA38C0D357A3A4AEB8C6B\n      184B2C99681A42D5505080DC05836B270B69C75C40119428DA754BE5BEC9A186\n      18A11F70101A6400791ED4759239B76563E322E8E471D723FD44661C3233F57D\n      A486A891B0C20FBA457E85C8FF76E7DE4B03F95FACECFB7B3CBE9A24BF58153B\n      EF5EFF27278E3CA673CA82166D8514C054595A4F4084F3A046D11E0930C00AD7\n      84E68D9CAB75632AA76FD92409AB25AD7314A353B6D15486ADD6C9AB53446DE2\n      B887052D2376AFE071CFBF591AD758DCD60BF0F7DBA70D09D7C12CC74F2DA52E\n      AB0A6E364A5DE37B4581D9BAA5EC0A1482EF5CB48AEACAC1D95FD9DE985D973F\n      DD5E8AD4968D595B2546F1F13C2992D243334BA8960000649E6A1B91A4A127E1\n      11D092E16C0AF2243C6C643565A195C2B68BEF1017FA4ED66B8366C97D058886\n      3AA4DCA7720C1AA43A39CBEB24E3386B873B599A0A92227A6C06F03E32648BC0\n      8B465BE98EE72F96B61FD8716823C36625BC2196C750E3504FE14A438E2E4A34\n      8118E7A3CA5A030F9AF2E1C1F542EAA60C8D97EF77AC7852361541A27B449AFB\n      C2117B6F690AD6F70615B8CD12A31E9640D7781FAEBDF60B9D485E04C91FEE6E\n      FEAF6FBE7B35F6260071A5786629F99F3F71EE4969E2702E3D4ECA4749E7D173\n      B47D528908508757CD6B09F8775C78E3D6E0A6BEF4657DE54D7127D5B7C56E1E\n      4DBAD1814797836797CC41AB13B1B5B13D73E77474FAA06A634798EA00A94600\n      3B480A55424BD9FE2B6F2D2DCCD80538B523642E41F1E1E3043E944E44114B6A\n      FFDEAB6F439C597CDF858A97E25EB9F6EAD503CF3F67E61695416335B890AE0F\n      E0544E5BA21A8FC3E168F5737FDEB9B69BB58A95F73D632E1C2A7B9BF1C48E3F\n      7D852F24E1F72E54DBD9F0D3D7DAFBA3F0C333588D4AE7548061AC24D6E3D199\n      13E7FF35DDFD47F3BD1F7D727C3020D2242A361E97D86EC5B799DD1B0729CF6E\n      5DD77E995462BC5D84551079623BEB5B16CFF4795995E4C563C99963C3DF7939\n      BEB15B1C4AF8F3D48BB13A83D80D28C5100529C3196FD9DAD514B99C08D67C94\n      6EA7A544AE7A0B0A2AD157FDCD51F7FCD3E5FE73BA6AB50A4BFC9C086D542039\n      09E1A4AAC030A884278C8C4BDA95A29B8C2EEA9B5FE5475E1CF4DE3793AF6AC7\n      06709D573C5515EAB463F30CC08955AA9495D78E31382A1D7811DD4A6FBFF4AD\n      9B5F7B7BBC3A20CA2B7345A45A08E239CF5F48921822883323352E1D36FA6CAE\n      D6C6F9AEC08621D22B85CF131F896E331E7D78B6F58163641FFC921DC372DCBC\n      BBC5CA6F8C2757B53FCAA82C555911F470364E82CB3980A3E137BE7CE6880D1A\n      7D73355244D087821690996CE1515C7B8A585812DE1762D70B6E57D54B83E19F\n      ADAD95D63EB3B8F4446FF180E7CD1BE34FD2B215FD49BEFBFB1BEB7772BD1877\n      7EFC50F2BC58BA90B2783232B12D3AB80314A0F01E65BE501EFE1D1330C78A1E\n      2523D08190A1AB83CB4C763AE56A628AACAF996EAE1BFA6EA3840A00C900F974\n      A46066E49903630FE2C29ACCE2EDAA3B107D2F58EF42192393B2EC70D3F2A180\n      F2BC08E9A098D4E0493A0B62C21B7063F644C1EC7423C06D45BBF85E2BB4D53B\n      5BDAF5F56A66BCB2CE7ACC38EFE2FA94D53ADF6EA24885C6DF822334A4BB3EE2\n      12F8B1448732ACE043DCB962CED4071D1D9064840280CC0764C378A6AB01E4C0\n      3056E8BF4C664A93189B52BD2DE838F045B9DDF6E396165DDC62B14555F54303\n      5F9F0BDEB1A2E53E4BC68DCF455B2B6C2FA35E3813A69A7800F7D5A2D1DB49F0\n      F39B6B9F5E1DFFCCD2FCDF8F7B975AE13F5A5BB5A3F1FFF4D0C9F3722C88DFE2\n      49082885C3D7C3CA4E860A12A18F72132EBEBB2C4844D3A9C6DAA236CC70D194\n      2321ADD9F1743342AA1BC79066B7D0D4E452E6363D1A3599294DBFFE4913769D\n      9313DB832A54EF35215D70AFD7EDEA4EB28FDD45258B0AD03600169481704C2C\n      DC77C3638FD7496075A547865FE7F19F0FEECD07E2C3223E30292467638483C4\n      8B858EB0D528584145C54922596C85879212B4501C0A391EA02F9BDBD1400E1D\n      7ACDFF87293F7B0AC4F7B33EA93BA4A49680D0CE041BA93E029742148405AB73\n      5DE5444A802C0285A539EA2085C404944418625CB166D035D10B05898511D409\n      935A5413A234546899D2AC6F3EB0B2F21D6B2A0D22746BF87BFFD6D2A97E6993\n      08A72D36B7CC42DE2BCFFDC06FEB369C206523B515496FB83CE8D1883038ABB9\n      A53743FFB76EDCF9ECCDBB747E697D6BBCD2B51F5B097EFE7B3E462669F278E2\n      3FDF53070E52FF283791C154D5C1C7C6D381C766D20D79E96BBB5FFB32BB3E0C\n      B7929D3E5BCF33E94FE265B2F2ECE195F75DD8BA7B37EC9C693F76BC0A2A388A\n      9E0AA584430F787A42024327E38DBF78F3C08903AA5B427244755A9708E1B70F\n      301132C598C7A2CD57DF2655B1F8CC63CA577C2DBFFDF2E5432F7E50F7E615AE\n      34A07FB90B0E1C971003A8C20B3FCFFA7FF62679F94A15E4FB1E3D4F5E3C6BBA\n      3BE6DDF5BB9FBB7AE87DE7EC33C9E4E26DF9D2BDD9678FEB4794C8A03C293111\n      A250650E9FC00BCF9C3CFF9B74FD7FD8BFF4F147CDC96E918E005DD2C8230C0A\n      2CB4B4BF777D739EF6AA8D6D25D37661CAAC2A06E54CD2D91AF795F11654540C\n      27A343C9BE671FD3DFB8626E6EA53D117CC00BBB5E4D3A70DD0CED7CCE583350\n      AA7B2AF87E7DF752D1901D17587908C7677277A092A5E4C43355B4CFD39C4345\n      0C5843048808D16005AA8190D294D22CD72D1BF6E2D15BE6E6D7D8E1F70F7B4F\n      77CA351C26E125770B7BE85200BF5AB93E10DE7FB83AE8F362FD56C5FA6F5CBB\n      FA856F6EBF7E558D0017F0C9249DE5D1D178769E077114E51AD255CE6AB2B6B5\n      74DAFFC30FEC86DF508C6231CE98022415F9489B4AB8DA1F25CF1C8CCFCD197F\n      0889102E0D5BA3FAB56AF44EEE0D9111698ACA20DDA149844E8B0BFF971B1744\n      8CA970F90F1221E38A43CA2A91F052449C0725043E5E5464C845DFF7F2D27846\n      7C830EFF707BFB523A91942CB6DA8FB796CEF0F6E664E7B3933B17B57D24143F\n      B274F847FD76BBB2EDAA82C79675E9C42BA8D189B211C42EEE0CCD6BB31EA6A8\n      5B4C8284245C5AB2534F1FD700AC2DECACA86489FC761A49C7E5E54844674EED\n      DF3310A870F8B69990D9015D2BB2AD521F1EB5221DBF3D47DF10834E513D5CB1\n      43AD563B42AA5325B4F5A1AE16DC17D491FB0194C0CFDCD4C6352EEDB422AE79\n      704DA4A0D3A576ED5C75F0D3230346566809A46A4A8B719A1B75FE74CB5DBAF6\n      EC68C677251361063802552271E95B91A840353BD4ABC37911AE17965249826B\n      8DDAB7DB50C230EEF1168AD82B3D03B8C092A16FEF1255526FC5B31EDCA45CA2\n      3EAC8FE6A2383A846A06EA1234D1D250887B50D7482F84CFE0D12C0AE1DC24D8\n      8FF3E1E327453AECB5FEE9CEC66FDCDCFEF195C5FF2A9EB9CAC5CF5DBED4F5BC\n      7FFCD08973E530E4F00BDAB1010C542092355EE16BA865007DD606102E503A02\n      1A36864DBD87671C86833727D8144AF0665251EF45BA897D33F3430E1A9B0E9F\n      1A0848A7FA17F7FBA2048988B666CE4E050DDC3A09690063B36A02F7AEF6E880\n      5C08D01029A34815B6B88C635D9A31CEF81E9E21D99F7ACC069F4EB22F8CD77F\n      283EFC91093122ED8792E75E2012D209503497166548D1B71DE016C7045AB00A\n      AA5D88E98240D1C80A617DA89901DE4F679FDFA1B5781FFCD570C92910DB6916\n      74C7DB34C28F4E9DC66D4D584042900515DC1D855A15325359A651BB1E62BB73\n      CA1658CB131D52D4C1A86C69F528D038770F51E34542B4762AB402459A7096BF\n      A763D06C793E9008C9B44D5AABE7EC653EF7D41F503C68FC5EE80389B0E18A7D\n      C7DE67D368A5B68207A7382A6558B4441680C4D121D8CBA3F635C23EF5E6DB6B\n      C257713248D7A2BCFAC4A38FFCD087CFC547F2E4F9C3E5FC7E410F8932C6C615\n      92F02476EFE8BCB77E7BF4C6B7CC8D1BFE7A565C4FFB9BE5B8C01B43CC58FAE9\n      FCB1C5C59545F2B73ED43D7B5822B7CB173AB629098288A8098974B9BDB973ED\n      F2CAC3CB793410501A6A6C2348142B85C78DF30D2B846783DDD7AEE8B25878E6\n      BC06EC73275DFDDADB073EFADDBAD783ABE6E34576BAEA68B94D2A141ED6A816\n      72656DF4D9AFCB6A1C9C3AD4FDC4132449075FBD387A373DF4F167F5623EFECA\n      DBD1DB79F07D8FF597367A29DC4524B112B8E536574640223C71F637E8FA2F1C\n      9F7BE121EFA159056F9B1A250C2ADAE3BA95BF71A72F0ABF6B83EDEBD7174B38\n      6E7C3CCE620A2F9C8DD3AA478262673489C4FC89237A7BA836FBB960FEB3B4BD\n      2FC656A2AB571EDCA3719342C77BA0AE5180FF5A72C3B04F2C022F08E4A8DCB9\n      5BCE9D7A3F59395DD0808FD2183B7878B13DF8E85A58408414B2639AAA8845BD\n      28BDAC6E7D432C3F9ECD3F11566B0C2A4483074F39ED430FC9F18EC0C1B12D00\n      8FCE0B23BECBDEFAE2D7AE7EF15BEACEA0C54259C9221F2FB6E223DD5E0F3072\n      89CD1C692C606267BCD6F00F9ADD009708DDE8C229AA60A0F4D071141E5A8B56\n      333C7C78AEF7CC21BD2015031CADC4863097757A7144FB584F427C3565C56AB7\n      786CC5983D44E87661E134E9C26A01F1556360932E9670A93AC4F31583FC3716\n      FE8EB5E3B20420BA1DB03C0C2F8FD32F6E6DBF9A0D2125CDA0FBA01E78EA482C\n      FEF6F2C10F92CEA9B4C0F94DC0AA884E7C05E11F424B8C03060A6546E531893C\n      0B1ADAD2F37D56932F845B07AF735FBD884DA7E2A7902CE0202ADC15D250C220\n      DD40C1692E710CAE001446E81CA0AFFA64E696DCD76FDD99EF7DC66C5CDDBDF3\n      FEB98593C25BF4BD5EE841010775830E341248998FEE8435ADC08116DDDC7362\n      A7A0B046844DD93B8D190E981B670E084F12CB762BB5879ECAC6D58AF03F1AA9\n      7CC631419DB4969E0AA5B633AF74C20C113A2B928C93B16D24B29D9EACA5CA02\n      5C65B64CDBF13AB3934ACE10316770A83F88BC9B21B9A5F3B43F9A1B17E76716\n      97684B09318CC535BF5AD593D09833053F33224956963E2D628F73BF25E11017\n      BE29954FC63144443BA768807B289E57E6D96CFB93B6FC5FFEE29D0F9E58FABB\n      3CD961FECF5DBA3CE385FFF8C4D10B6A2044C8593B51F04B73F8AED2599441DD\n      E1BBEC63DD065B333FAB3785584310ADF5B6F9D481B0B9859C369D66DAD04FEA\n      EDA6D2B5DCEE932F6AD6614D3D732B6B3567886BBBB792FFC06B22CDC8B1F939\n      F22F71E04320CE289957507AE355C7551C274086044D2C372AE2B5210894D956\n      BBF5B9D1F07A7FF403078F9E2F264A0EB782A0ACC2251ACC87268B4D1E7B89B4\n      01BC21C1D3180E2D89358D0C458758DFB5CAE134510641BFF18DA2647A8EDE93\n      05A7EB1FEFFD774E5BAFAE77697DCD6B3D55C8ADF0052011A2662C60782B735B\n      16564A67CE84253572853D6EE72587170A4160E8C9CA871849A1C6D301D3BEAB\n      32359444C8EFB07B3284E4AFC85B7B88904C570CA7C96FAF41ED3ADB7B9CE9A9\n      9D16EABEBF575A722F1142B538096CA450E1D3B9D668F832D89F83F0CD421577\n      EF50F1FB6FBD69667BAA03D7636E77FDFA0FFCE0F1173E71A675F6948A178DE9\n      F955E298BA3B9AA5A8FEBA15A46F5E1CBE7D650EEE48AAB2BBC3B42FD7D67786\n      FD499BD04E44B2305FB9702CFAEF7F30EA25C88C473DC84414C805808286FA72\n      B0768BE4FD998351EEED7848C1C5AFA539B646390A4B3A4F3BED4322847FDC7B\n      EA9C82E07A6DB8FDCAD5C5EFFB6ED3E96ACB7CB7D684EF0837B85885CA9650A9\n      4CC24131F8D497ECED757266A5F3438F73DFEEBCF4AAB5D1EC471F356438FEDC\n      B75AA9EF7FEFB99DB9FEDCB6A96DA3A8A9A829B46B8D1E7FF85FD1C1FF7E8E9D\n      986D9F5B81EAA5D45561AB28E6A86F1E24A3BB43D95773F1CCCD8B170F0D2CED\n      78A92AAB41D56B2F8ED23484A831D280CEC29936F7E8B8BF4B48C81F379DC3B8\n      7041FD469D9F4EF53AA6531E47E78432A59E0DA36C9F40A661EC0BC5B6DFD96E\n      CD3E1C9E7D661CCED0A1EA40D4F54A8C9AB8EA833B69141E28129C7C1A75C2FC\n      86BAF52D3E77422F3FCEE536807F82A70E1321B6C2E06CC8D27A383C625EE0D3\n      58AF6D5DFCF5AF5C7AF97591430CF607E34927F4F7C7D18AEFB790DB06A74408\n      C3012E5751231756CB369AA6EBEE4EA570FC111CAB101B060269D35402D08999\n      D817779EDE6F1F8A4A918A71110C3C73836417077633659022A4825CC8B01269\n      1221445F5705E102609D08E196718810980899529009911F217289E5120BFA9A\n      EE6A351474187348A8618EDB44EB9DD617ABD167D76FEE78F0C9E5E3739D9F5C\n      3CF2F4B03AA5190F47DC43116C00479E07E520BAAEA3BBB6C0ED43E7FD84DF25\n      065883CA8E0D2073FC135BF32CB95B07ADEF9D64134F23275E595EF345882EBD\n      AA8AD1E9C264026D1A834175D9F0B971EC7BB39F0DC7FFEFEDD73FB1FFD08F05\n      50CBE5B6E7A1269041D56F010959F8C43118F74C9D9C8781257B55F3B49335A5\n      A962D7D6B1E24C4DD0301532111B31651C55068EC3EA4C7C5C89513336715D0C\n      BDA649BD0B16A868DB5313667087AC805887961D434E2B8F63FDA45103066E98\n      E9F25B32DF95D59CDFEE7911053028E52DA82C475B376D756E7EFE99EECA82A6\n      E389BF3D19AEC9FE5D39D2429E5A983F1FCF2F97AC8D0250B43450D6901694E4\n      51E5DB02BE6B0E8F59998592C4CCF3E290139946DE9738FFA557DF38F7F0D19F\n      0AA20D4DFEEEA57713E2FDF323479EB729E0541BCC008887BA5A5299E3E5170C\n      ABB1A9A6256ED939D598DA18C9A537E2B4BA6CAD823635986AC816EE81D78DFD\n      5A150F657F716DDDF98350B72AE908218EF4DD74F390F3E1CCBCEC5EAC65F441\n      F0411FC82D5296C213F0290186A03077853AD528838C19C5A51C8D6339CF2643\n      EC2DA40746DE2AEBFEE2E6BB6226FA9968DF4A3EBCD1359B855A9E78CBAD181D\n      3A380B4895585D72B5DB62D40B7B05D4CE348D00D613DF3000F458BAF00764E1\n      1A58785F7DD6D03D13CAF7A2C56635DFBA7F65EB1DFC5AC11BAF7D594F9DDD9E\n      BA6490A62B40E64C408139816F1FFBFB46907F6DC87884894AE578C874E063A3\n      C8404C20D8F2092C2EFD4DBD76A7542FDAFCD90FA6C6DA20E37E9A64D3566ACD\n      07237B8CD23A11EE89B1B1F720CB3D5D3748843E202D121811E29743622E54CB\n      3ED4291075599486E156E0BFB676F3D023676EDE98905EB1F878F53D3FFBC356\n      CF411122D13D1BA51C18DD311C8E5F107DEBCAFA2B17C331F1526DF322044850\n      E8494EB6B627E5E640A493513B3DFD532FC63FF971AA4AC1099A16D0380068A5\n      1443F36572F79DB77A7351B40021708B600644BE9BE18D2455855FD78BA4D879\n      F51DCFE79D27CE4888529776866FDFED7DDF7755ED04928527DD30B55186108E\n      31041FB4F0A44C7FFFABFED7AEAA338BD17FF2B4A7ECC6675F4E8E1DF49E3A44\n      36B7869F7F79E630FC78653B4AE7878E700B5F0E8B9A0C3730A2B3C74FFF0A55\n      FFE6997532DEFFEC591200EED2D2B90CC3A9028CA6FB45766FD88EBB93F12078\n      E5B6688B82E9F176D90DE68CAC5495B649526C971C8051D71B8C065CB7D85999\n      1CEF28316111D6E702F3A171BC74C7E072C9047E6AEA1E29DE30819758E04E43\n      E045E5CDF16457F41EFF50B67084957E0CB1242820117AE85884C4177468C0FC\n      161A2F0A8AD5EAF65F90D64270F082D1388B214861F6DCD0D9EA2A835B18F412\n      78B83427E377EEBEFC993FD55FBA33D6CA7A419E637FEE50A773BC3BC3C6C390\n      413200BC3B01882704F60C1B4F556BF7144BA8039A3814A8D793E1A721F2C398\n      EF55016581E05D21CECD8BA717327FE24FCA702CEC1D9D5D1AC9D5115E1059FB\n      D53589706F4648B16CC417A3DCB082BB0518F8E712698F28B362B30A0FAE170F\n      B4D92ACB54F0211704DBA86558D9B68DB73BED2F75EDAFBEF6EAC976F7278F3D\n      7266521E1EA7FB3D2FEBF52DE222785834864707A915406F04B9CC33B8075C0B\n      8532D542F68F53107388AA660535A4415A33BA9DA1107A7E6803F95208645AEA\n      02426855CEA5DA336233E0FDD2067DD919F55E5F897E876E5D7CEBDDBFFDD0B9\n      27299FD1A3768B12242741A9C303EC211A7874D4E77BCBC2754F4FBF4757CA25\n      4553EB9CA1DFA7DBEA732B14D85BC62C08D9B0DE78C01703250F1E12C2117158\n      D9F84740EAC0DEAB0F08BFC02DAF6D4F4CACDA167A003F9134C9B17734F6D816\n      3563A9221186410888FD8BC5BD4540B1D4EBB5925D462F0EFB6BFD41319A1C4C\n      5AE70F1DF2C3F8727FFBFA64B45D5039DE5DA6EC99DEEC63F34B506CACA9AA3F\n      93DCD8DCE4A3F4212F3C158733C478C8335211240928E4946E1700CD45E1D9D0\n      07C418DEF2E3DF7CF30D3DDBFBB17D331B1EF9B98BEF26CAFF27FB963FE12145\n      43C633B162900873AFCCD0FC137D06B427E9349E4E074FAC99DC3D20C1AAF554\n      12ADA18818A4F5BBA9A15B4044F40F7F57C2FDCCD150A78BF9EEAD60C3BC594D\n      C41EACE14D5A6DCCF69A25A526913402D370729503A48842EA251678D2AAC08E\n      88AD9079ECAC91E0932599674232999D1029BA5FF2D967576F9D8D7B1F4B6602\n      33DAF18B8D4A425D7BD25B98857B90A82082BF65057CC038F171DE6A4AC06C3E\n      D66AC24918991ABB3676B88D02CB7D043525C9D432027BD420D6D82EBA67E93E\n      58BD1F8336470A871E066F215C5AA115A95274BB2E151F1833603A0BF8999C23\n      718CD88E613EDC08E1487D1018024142F8984DC8AEC5CFD80319CB51B89AADC1\n      3D08B89708EBF5A08638566FB8D0FB42010F24423B4D846CFAE3FBBF1B96388E\n      FF03AF0E9E13AA73394D1288BD611815108EC298F5BA248E869688B025F74F96\n      3EB6A4970EC5E1232407A43429E0B89920E0A930697F98FB9F7BA9BF3E9E353D\n      363155550AA6E5242322367EE2E57478E7D668491FFDB98FC6179EB24541B892\n      B884058758112A3DA67956ADBDF3EEDCC92531A369B90991DCD14574DDDB8003\n      51BAAE7E5B065BDFBC18775AAD474F4A52F16FAF67B706ADEF79A148120E49BC\n      946E2DA5065688B3725B91882A95FADF7C37FC9D37766665F8779E0F2AB6F3C7\n      17E79F3B4B0E24D56BD78AD7AF745F7C981EF407D9A4E75C05706A06EF52E7B8\n      CE1F9E3D76FAFFA6F2DF7DE0D6BD5B475F7896006A428CCA725300B41396F890\n      FBAFAF4122895BADD19F5CF402E3055E3684F087FEC7D9B8DF0A66AA5D0C8D5E\n      8FA7454E729F9FA4D1E98E0C86D4D9F670126233043DA7D13FC7519CD18B1B1D\n      C0F1BD72CD05EACF23599E004C09F36070B9DF3AFE4475E0A1D05FE62524AD42\n      C35B74ED7B4B6BCD2A64DFC12FF4AAAD72F5350BEFF0F023C6FA167DDDD1CBDC\n      011B0893856885E32C8B69BCFDC6EA973FF907E98D9D99B20525DC7034EE50EF\n      917D07BB064A39CB20079529970A6013849E52101F62C35EA9C81A39676CB635\n      ABAA4D41AD4294F7F0C2107E4FCFF7BDC8330FB5BD0FEC9F8493202B824C2069\n      E4F248DD1C5269911689135A74738328AD9D5431753BE9DCD147DD46138EB699\n      727C2BDCC5D33257B11F184D4785EC6B3D4166BFA725ABA8DA2259C2837D4530\n      12DE67CCF61B9B5B3F76E8E1F7F30EC9FB0B6D7F16E7183B39EAD2F3002A2945\n      00155701CB040E0FB8D6916528151AF02CE4F5E68371329EF733915B02AEEF2B\n      DCC0D22BF1C32A5C304654885A07F0F94A9B435D1F8EB5184EB4A88409F6FFBE\n      B9F3F9ADCB3FBEFFF88FAA24B1995AF6E0E07B1255266414063C8AAD909ED65E\n      130E74ADFAC1F66681F74379C3777403663A1DA63AA167499CF32AAD9B5D2833\n      45EA1E83631E0180C513E7C4C444C9784E686E4C66CD9A2A4469E0B3EC50B30B\n      3993F91C1F4CAB6064A72C86B21A65D9D6CEF69519FEFCBEA3ED42DFDAD95CAD\n      B27B568F383D3C33FBB1B9E3F363F5E6D6ED57F5E086D5CB89776261F191DE62\n      6F98D1AD7156C83BB25855256D474BADE858121E162461F2F86E385F5078CC55\n      442BDCFEC14D0C54D237D8249E04C91FDC5D7DC5B37FF3C09C09C4DFBBF82E14\n      C9FFB037F713B1D7F2781EB67D80DA042AF03C632C2EA340D1C22F594D286C62\n      7FB3DB584B4BEBDA9F165548F9D45FAA9EF8EEAD4C583BED79DAFA09BAFF8EE1\n      4A80C7D1D7028376E30AC4E8D4F55E4C45136C9D4DEDFDE160DDA3ADD7DBDD28\n      0BFB4FCD78047E992C2AC88500B07041D4DD6034892E20ABAB344273D696B7EF\n      F7B7767F67EDE64F9C3CF791AD89EA557FDC1ADF4DC99364F9049CB7B66233A6\n      D213569120E894A8B34A3C48B01034045485DCD7AE4B46A7EDC77AB4C61AE060\n      1B9545B771489A350CBAA71547C894F2E35C7C1D6C0DD0205B72E79E82ABBA6E\n      35BACA543E569288228836ADBC3DEC1F9E9D4F0C9B99C83914EBD61572987450\n      56BE60240224EB298FA650F1D4061D88B9A7A603AE8CB05301843A43EB0710E1\n      834D512759BF2797F39ED6E81450B23D25D2BD7F88242A34A360CA3D101FB5EB\n      7007C8843405841EFA0CAAFE204E5A6DDBEDE8D98A9EB5FCC2F2801D6C87E758\n      9552BF6FB848A51F50E38F463B9756D54B5F8EBD1931E65EE541CD55AAC247B3\n      566F4468E2B7BCAAF29E5EB67FE361EE2D41490A0183602C23E36242621B68E9\n      AD0D766E6F76CE1F2CE22C2AB70147B8CBAFEB21B3A13C83EBAD695B855BDFFC\n      76D4EB248F9CD4A6B06FDC2D36B2D6479ECBE2040A6E01B5142338708637863F\n      A4A9C945DB4F491AAC0E5ABFF1EA7A76ADF59F7D303261FAEDD5CE7327598BCA\n      AF5CABD6D7A38F1FAB66793044CBECBA444384ACD1818786678E9DFCBFA8FAF3\n      17D7D756F73DF688E8B6319518542046075CAD221E141B3BE38DC1FCF2C1E2CD\n      9BBBAB3756E6E67429D2DD2AC2D3544A0DE02051932C0809AE7517BE5A52DD27\n      16281C8D28A7508CC35387732570CC8C1D16EDE4F1B8427E82035692616B1FD5\n      057D56C01D547EB15A14B23DFBC48B522C1885465B482DB228EFDA6819695BC0\n      EFE2FB811D176BDF36B2681D7BD8E825B7736D7D0F2A3325750197047225CFD9\n      E8F2C61FFFEA67762F6F26B4759B56E1A4DC67F8F9DEE2320FA1BAC3099325E8\n      26886A6100C10C9499A8B2D96CE25B46A6CA6DB5AC83A3DE3843042143EE51D4\n      DE34211C174FF82CDDEF271F399EB50B51E55E6ACD3DA56E64EAFA08CD7315AE\n      15A3F56E854D4FFC2D55339CC03219D1A176632D8AAC1E5C7183FF33455E447E\n      4B19BA9BE5630DEF1C39604ACA0C4A0B2E02E36BCFBF6CB32F6DADBD70F4D8F3\n      B4D3DEDCF121CF7479ECF3382B0B81A3141F021C9E4AE473439A875A1D302224\n      7112084066AE08760B07E48156173662186BB495B16B39F02407CC87321398B4\n      855291B215A7DB1E4B53C37758253AD742F2A9FE2ADBDAF981DED285F98E6726\n      33BD16DA82D58B5528D00EC5951721A0B74859A90B3B4AF78ADBBD152BD2C82C\n      370D3857F3E352B69692BA0D19D6B4B3EA6519EB24BC8DAB282CAE7D95243402\n      727569599FDA7B56EE40F92768E194937CCBD3ACBC5DA4EFD272187B82061049\n      791C5FDABA3BD172B637BBB1BDC9995758DEAF8A52E903B349E8791B1BFD1880\n      2DE129A92A22E766DB4F74718D6237CD5687031BB06E18EFA7C1A3D1EC821F96\n      A4EAEB3144CE38F69F2D920315EBC2674386008EC4B9A5055A66E910E277107E\n      4965FF677FFD67F62F3F9C74FFD9C6EE37566FFFCCF2D2CFF57A0B0081E28E44\n      35C6D242310CB744860192920BE2B4E518A7CDF3B27BD29AF50F089D2A71EF91\n      296B2246AD0953FB2A12FC0D70645CF3F4DDDD32AE1E02A88AF425E109140CC3\n      80835BAFB6D653A053B385A98BEC7BB8FEA6197DD5FE7F02973318567E456500\n      E4612108658CF42A64C14D98EA47454FDB8551703399FFF5E156DA9FFCECDCA1\n      997CE7664FDE8DC3DD9DFC61AF730E2E4590A51D8272B8D6AF7C9C1524509731\n      33F629115E44A00E567BDD4E470E720D86A91D47D3279FCA0B3C980BD9FDA14D\n      9DC1518716AA0D86053CFE1C4D9795AB134BA3729B9524E5DE24F03727E96531\n      B9D05E3E70375BB17EEAAB81AF43A37B68A3684880C3421BF9FD04E514847B5F\n      B59C5143EC75CC23D2D8F9D682B5D34458E7F2FAA936D8F141C795A91FCAFD15\n      7B7C6D282ABBC79D71EF00F2951369E270809CEE9A854BAF035600848A84F0BD\n      36D6EFA19C61F258193D3DA7E6574CF010E10B5A6DFB665B20D7A78DC63BEFDC\n      DE7EF9ADE8FA0EDC14AFF229EE15E05814AAE14AB0DC67F04D0591C947CE8C3F\n      7434221D62140530E7CA564DF25D9EC7D456AFDF8E594C4ECFCB78128FD78D70\n      6F0962A087C7035E620EDF43B17842365F7FA7B53CDF3A7900DE69FECA4D2AFD\n      E8B9272661EC618715A7CD50A5206F0A194B281A0B55752E4A3E91EDDF7E6D75\n      FD8DEE7FF44CCB26C32B6BDD0F9D84BA447DE1B2A185FCFE65E9EB99616859E1\n      A4690D51153AF79080B5CE1E3EFA7F50FDD6F76FBC757DE6C4A9687F2FE7250F\n      982DA1DEC41D5BF8A0AAD03B37B6E75A4BBE2AEEBCFCCD7D61E2B130ED97BCC2\n      F5B154028CECF2CAA83485325256B488AB997333ECA4AD82318334A962A405B2\n      4C091C7371E5BBCD271422434751EA95A84C6C9CC79490108E080B2762E37A7F\n      EEA167D9CAA942711FBE32F5B1B627859B7A63BBA1726B243E2BCBB5778AD17A\n      EFF809C3CE6384C6075F719F5516BF651B60FB8DE14BBFF4A9AD8BEB44F9908C\n      AEFBD99182BDD0DD778478A62890C806E743D7DEA606893B0C57EC0A11EC3114\n      EBE653332DA4B5CF6CCD50E032E002775B2981E3443DC057E5B217BEEF805966\n      B29CF8F0293755717D64AF8F69A61D6117535DBD3BE1666C756B141132F2FEC9\n      74C7C4897C2A6C00BA446CD15C7E54C90CF96B4C595D9062CCC54CE1C7ACF54E\n      285F2DB74EF7E6CF49AF5B15B12DE7E1FA0566E2A9992AD41E8304ED21178B42\n      293121520A285579EC0463328F649EE994C23476420DE381DAA6235A337C9D7C\n      131A3CE11E02A64DADE0E5498D3336CA46F012B7CAA848DE0AE92F55D79782E8\n      13D1D2F38078E8EEB86B131125055C28BF0CB0DCC0E705B195095CBAFB0E110D\n      17979B15ED5AA3C3052DAB8C43CFA6E6D9C21FCE496D6FC41AE7F17A59C2D93E\n      D17A5B1A3DBC21DEB2B454934A97480A65D2ADCBBFA547FD2A2F3C11F57A5EAB\n      DB576AECF39BDB5BEFDEBC836C69081391475A61B7AFAF55135449F77C92CBD9\n      20EED160371F0D43A1B902581C4BDA46EB794850059CE0EE62E7C8D19516A7C1\n      A0D07776E249D9D5346EB5A29559D38D629A2F64EA78411621364914A481679C\n      86B6E02452F01EF89B21FD85D55B3FB1B4F40C097E5F84BF7AF9CDE79766FEC1\n      CACAB9ED491CB7C61EA01F155A94F03568472814934EF9720FD33D80CC1869C4\n      CF28F6E0EBDD0680602E3632178B49E313D18027868585EBAE515783B943EF96\n      0591348F479DBB999F0ADCA2FB54ECBBD6DEDC93AD99724C6D1DEC75BD71E496\n      013C072A99B3C6D495544529A59CC958C5C504F2AC9651597848FBEDBCE3B77E\n      7BF376BB9DFC28993995CA3B71FA4762C42AF6BD2A990584B114010609B98FBB\n      09E85A815B091091A5EFC36D14F59AE394FB5A4F9D9BADFF07F616F66A8269B3\n      D4B2667DCFD2A97EBA75F37BC83F2E94D7D6BEA80C402A2B0B5DE424455E3844\n      34FE19B2B962FCE7BCC585CDCC7A366D518F99AE24C808F06C849584376A51D4\n      6E9AAE434C3F1E44C3A9F6F9B40B5227C25A0061CFAA1E757DEF37451B46127E\n      76FA9EDD8929F586EE257EDAFC894CA37717162448248630E753D3E265C47820\n      66E29610225D2EFDC713766645F907AD9EA7C8821BD8721C21332EB2B7FAE3AF\n      5F1A5FBC9198C48DA791F006401C7780D109078E26093D9457F7DE774CBE7044\n      F296717C7280FA00DA08AFC6BEB43BA31BFFF6AB67DEF782776636E777A3FC1E\n      EE4BC36976136B775600AA86906EC281DC7CEBDADCE9A37CA96B6535FAD6CDA8\n      B3143CF2300051A85F3DECF64B83979F395208FC490AAE640195AFD4ED3FBB79\n      E98D2F2D7FF4425CB5AAAD9DD6779F363B7DF3B9CBDE4AABFFDD339077667762\n      EB1758FC187471B236831BC9E2F3878FFE12ADAEFD8D9DD76F84ADB999C74FF6\n      C500F2AE28A4707AD5887E9818DE1CFA9B76E67077F8C6B7CDC67026EA408CC9\n      0729AE01C28DE1810F1172778C8306114E74111CE5AD67DBA53F4085AE324275\n      60964B1F09A25C076ED74FE1F7404777A82C9C4A1F9A10FA70A08DEFC37F98DF\n      1964B235FFC47795341436416D114C0EB92B8D3C9CA909F45E879B506C5C9B6C\n      5E5A3C7E84842F6893E29A113C0F86161D1C9268DF7CED57FEE0F21FBC3CEBCD\n      8E941E1A15CAF2FCDCBE87FC56301A636F8261F3D5B5105C5CA628E6865DDFC0\n      234DC387D4A5F75EB302BB886EBEC219935835635FDBF9E5F92CF0E59CF0CECF\n      C5A77AC372171089D831C5B5A1BD39A6A9428D4DE912A132CEFE4037F2D04EFD\n      84B895DADA2D8128A70857E1763744ECAC90695E15F0C5182B9D7AD9985469E8\n      45C8A9E2EF90B116EA39DADE37CA6462829658D2B8CCBDEB9BFF9FADF700B6EC\n      BAAEC44EBCF1A5FF7EEEC6EFDC8D0C104414863980A248310CE919CB1435A15C\n      234A768DCAB2E419554DD9E5B2C7AEB2C75556288F4AD2A84899435B928BA43C\n      A3A1280FD3104C2040100D800DA073FEF9C59BCE3DC17B9FFBDE6F5036C96211\n      44E3FFF7EE3D67EFBDF65E7BAD98A212171CF4D0FBFE55D4645443FC8803D9C2\n      334C328693D5366E25CF0D87E6222C8DFC2F222DCBBC9D9B4D94A80C3207280A\n      AD68E5153EECC4A9CD42C49D2BB1F8B3ABAFEA078FFFC3BCD5E55AD1412B2180\n      4A556E22D925618CE3B1105EBF01800031029709BCA1D041F675B33EE741446D\n      9AD10EF5E81A9B24F440C7470798CA5BA22363D4FA3118BC0B545BC508C621ED\n      4D6B3D36640FC09C9456849846B5C314CCC34B5DBE3BCDAED4D32BF964981776\n      0A892FDEAAB1BD7BDFBDF74D86A3D76E5D2B2146641C59DD4C8718A902A5398E\n      31E1ADC40ECD1F6B82FC2E175649E88C1275B1E2F43A8763EDB6851D4AF6D8E9\n      BB9F904BCBBB139E4D6E0E6F8F3BF9E9DEC263C1C2E142A51A82510A0F709F14\n      39BC5DC763676EF6DABFF1DA1BEF6EB53ED15DFD9615FFD3E5B3FD88FED6B123\n      1FCC6947F26142E1617514AEB496F05B2836480EB88F7E3AC7EE28BFCD4CB17C\n      EB4C34A58CDF1068C832D41E640237EB5D365B04B36D439F021BACE12574E6EA\n      6CB88328A540AAAB6CD63D673B367E26D7E89562FEC0297D631CDB4CD8F16309\n      AF42471BEFB55A4322D4BA4A725741514E65AB826B516AAA7A36CC68F2A5C87D\n      E1EA1BBF72E4C90F5C2B281FBC7C587E6FBCBFE4ECDFEA1F6A0DA64127540189\n      044ACB5401A643A4E073DCDA25DC0FE13040375AB37389BB26A9507A8005E901\n      34A477B2227D33E4320E6A3CAFCF81467044FB3A15574DF14A6A45AA928E33C5\n      79F483D45C1E6EDDB77AF8FE01ED8E2AB9948C4DD12648E3AD5086A38EA08A48\n      2051345D8B6681B3D982204CB003DAD13C1136F3C3991EC2EC26B03B05E301F9\n      87CEFFEC9B69326C365C608D4F87C3361ABC614F49919E9EC6299AC6604748D6\n      F091221E771211CAC189E1F26327F5C6514557B97282ECD62483C89F025ADA2A\n      EAEF9D1FBC7885668AD8962F33A1DAE4B82ACB8208A24B280CAD892D5CAC9327\n      8FBBC737B0EA150E825582DC3A891BC39CAAF33BE77EE78BA74EDFDFFDE85BED\n      0943A6E759E02DD118D4E6D8DE465E7F10C081709BD9E0CAF5E5B7DCAB422295\n      DBFBE1C5DEF1FB822387A79463D70DA7891572C4E0D26BE169501685B220B2D5\n      2ABA313DFBECBF3BF9967BC53428F76EB73F709FDA19D55FF949FBF4F2E09D6D\n      0077BD1D69D3DAB7B83C8BD64258953479E0E8B1DFA1D3AB1F36E776CDA85E78\n      EFE3C36022E0FFD77E906914D40EE80E38E25BCF5F3B7C347559B5F5FC4F96C2\n      3408C26252C0DFE722282A05056B547235CD591AD605D5CB55FF5DBDAA3386A7\n      009818359B65AE830A729F3009F298A5F625A480A789137EC0C3F83E2305310B\n      6E9AC39DCFDD6BE3D6F187C2B533842C199C9929D4ABC66DEE18A21245E92FF8\n      BDAEDABD3ABEF1E2CAC935127FC0D8090BE13668C81C914C441D7FE7737FF9CA\n      5F7C77A98A4D56EF155397041FE68B411A40B512195C14C2313EFC5C81A3715C\n      BCC01E945751118ECCEDEFEE8837362D0832531044DE81C49E83E7ED413E9706\n      B2764784277BED470E0DD59E743C19B0E2CAC05C9E90A9D23820B1DE24C2CF03\n      6BDD2442EFFA893C47D37468FCFFF6C81DCA5DB851015CB9A95228DCC845654D\n      45DD08D71C04D433234C39EA64106D8CAAD429889AF0046294AF0ECA10533BE4\n      E7B0111546AF54246B90104E7E105B8496D69B54683237A9694082F709F1F426\n      3FE347B71914AB0A14C010246B8A4A439D945131851037B03DD1FD912CFF68EF\n      EC6A6FE153FCD8D1C9982C309B9280D510874B789F510AB535471CE8A47FDD0A\n      8A196C88F08344D83CEAB9077923ECECFF0A9298F2FB7DBAF69BF218C901F909\n      AFC10C77C25B4A6093B5550619450AE8102A1EE350AA2E08B12F6AAACD3ADB36\n      E5085B284C067DA809DAED8531A7E7F6B65EBB7D1BBE658072E30A005709BF3B\n      106819030143B9C090A6DBC8898447575B45B8C43205456D684445C56BE7552E\n      636322A8548919C1715810478EAC1CDA9F6CDC98DCEB82A369FFAEC3E95214F5\n      501BA220B82E19DAACE2012FE1E318805AD9F5E5CE675E7DED7E117EE6F0C99F\n      28FAF9EDCB37F3E13F3975FA638A4580FE530AB570474119EB8A00C11DF3CBE3\n      BE43DC043E0CFD5E96AC710C6C24271D7216BDC280A787DA83E04966BDD0D95A\n      219FD935CEA5D6B01F611A70399F0EE2CFAFB1398AFF42068DF0C55F2071EBD4\n      79E3059F781AE5D58606724003F6DA14D67BD6229FC0A1D2BBE20554D31A4519\n      E0E258238C4A18CD45F09A0CFECD959B9B7BD35F7CF089878659E2CC0FBAF537\n      CCE629D17D6F9E2E1A52B51D8BF1FBE421832B02612D740E6241858A6C0D15D6\n      93909B1B3C9723A707B27C8C1EB04A9A443247AE736F278F1195D50D959119F4\n      1722A686029B780D5946425BB26CBF80BFB5DF59FCABFCCA353DF950FBC899ED\n      3A904CB784AC7528A0CAB45AABC8B22E97BA8B7BBA5E1E96CC8D4E1A97413797\n      41F79B5E7EDD95CEA5D31BF6AE9DB3F566ECB1C621716EAF71800BFFFF1221D1\n      CD3614C60154C9B0DC0BB74A11C6014F8449B9ED4AD20EE953B47DF464152F57\n      2E8DC834A8B7E11539D1B5B9A6AF5C533FB83ABD328218DD365DE6F9B7956016\n      F2A90CB1C49090040011157C4D749ED8E0A77BC40A12C04185AF8A4E4D8076D2\n      C295DFBC70F34FBEB5756BB8FCEE074EFEC70FB2E3F0D447784A43A1EA3AB090\n      0E350F6341C2F1855BF9FE70F5890772A2A371B5FDD2D5FE038F870B7D452135\n      0994B42565235AC70CA652C016C2D6DE55046E88BBF2C277D844ADBB8E76E3F8\n      7DF78C2E6E965F7F7DF5F19393C763B80EBD61E012642522CFCED6F055D0F52F\n      BEFFC8B1DFA6C5E607821B667475D47EF261DD87FBA2420790931A5DA24A04EA\n      A176063FBE45D456AFBDBAFBD2F9B8285B5050583199D492305D17DCC90EE94C\n      47194094487527E9A0F3B6901C82708989108E2724C23A2CD1484AC7F8CE207C\n      600494F07051FB80A17F826391B511AE92873684DF3AB4FBB95C3AF39495C71D\n      D2D56AB8263E11A6CA482A21FCD450B3BAC9CEE8DA7716D73B6EF16F5B9B5109\n      2F10D9CAD2B6AF7DF327FFEE0FBE2C264E54A49A4E8CCA0E1F5AFB689E66B118\n      1994638A147C5E54A42D24A45AC4B3E885EEA7970DB5A7719563BEA5EF8FA35F\n      E5F100A4B1BA410D8CA851E304FCC9AB48B0842577B55A4F9DD837FB80DD7A23\n      A1AE4FEB8B433B5516875B9E2DFBA64488C7DFD3EABC7D29698408705C8F740F\n      D41AA80D9D167A8AA12280A0515B53505A08D9869ACDD6F0AAFA92AF00DCA9F3\n      34926DC1025C10C486042A43C60DD9C4FF408AAD6407A95A0A3FD52438A8C5D2\n      955770EB9B59DD9CE3CD9B91A8F76DC02CA93113A9DA4A48FC6509212C2261A1\n      C54E49A62CD895EC2B7B6F648BFCEF1E3EF3AE1F8FF70E21F1BC05209B933CB6\n      26955061027C9524404B0754A0D698481D6773422E9D2742FA66312C6F778E83\n      55553742B1882A1A6AFF6CA4EAF1AA379727706D276240F52E757B9C141CAA54\n      E92DDB285CDA51E0AEBBE96BC3DBD746DA655669DD26D23179DB969BD22DDC75\n      988ECB6C6F1F6A832A209E03841D56087F021B9910538C40E204B23F490DB56B\n      E417C9CBC81AC08BF896182F206111169A7A9DEA43D41D4DD8A97EF8D0F2A1A3\n      3659CCD92188AAA6866C4BE3BA8800B3463160CA0ACAD8080D3EEAC9E57EFC5F\n      5ED98AF3EC53EB1B85EC3C9B8FAEEFEEFCCA91D34F8D4621CFAA14627D18D65C\n      71787A06430043E61B1AE2D6B58FE638B7F52343DE8441EAA77DA81944660329\n      31ABE366E68E9EBC31D3B56484DE0144DED6DDEF57343D11DB147F0D40691834\n      082ABDFC825760902845E4AD30AC572743BE2869EA7462E72F186FBDC6956989\n      529D165D55A08CCE9551069E283E980A3798A7702259BCE5E46F9F3F6742F90F\n      0E3FF0D8D0EC85D93783FCC6CECE3BD2430F062DEA32136B03759E17508C1C22\n      1CC3A1409B49C8CEF855074D483EEB97CE1A1E9C9183B5FBBF61C438EB4DE203\n      B15AA1FC07DE02BC291445009045A3F1100A52113B303487AFB4F0B55EF6F5C1\n      F9F72C1E7B70045FA48AD3282DA132B3D300DBD8F0A263438A16447911600BD7\n      2F347ADAB9A767DB8344E89A87D6D071DFAC153E9F171C9080C8FC9E5A3B1353\n      9D7DEC39DD6C262BE4A130AE0BA386398F517B87560124B410126194062A26C5\n      82948717DAEF8113B65AEAD8E12A4846D584E880647CF78D2BD94B57BB9B548C\n      58A5E02A071CB7D85811A1334D0051560A13E20A72214A76BA15BF6551AC89A8\n      2424242A94042A4C8A5B52C1BE3AFF7BFF76F7AF2F456661CB65D15BDA3FF38F\n      DE959C818F55170EBD68A0A6B495862A939160FFD54B70B616DE72BA225ADE1E\n      ED9FDFED3DF4844C3A7061FDBC5B6BA650261FFBE29E074491AF805521FC28A9\n      F2ED5B37BEFDD2C96849D171FCC147B79F7F6DFADCC5131F78B4BC2F28F3AC57\n      A590A27CB0C5251E4E4AC86F34BA770310A1DA7D97DC8F4797A76E63B573EAB0\n      290A29125422B0059C4C085C8CB5CC9EDB7CF9B9F5A523F9AD517DE37AAF1541\n      B99C97CC4EF348A2DF666C3B102EC666D0AD9776C5A678C2A46722694251B4B1\n      23124D5554405801408EDD2FA1BCEE15A066C87AB89C5D43ECA6113729542B90\n      3223F8A5135E9569111C8E561F174C3264164C04EE79F52C244AC8751C75ED79\n      391A5EFCE6429FD8955F302E63312F6B958ADEE0ECEDAFFEDE972757A6BAA2C3\n      7CCA5C79667971A3DDBE6FA72A506F17D7F9B8B3316463240E19153805250C0F\n      25605278D2388C9FCDD2B99DD1C79B617A73DB2CF7DD5194D74423146E782505\n      94A822249DD556FAF4C93DBA5F17D5D234D437F3FAF2C84EE1A21B665CC38BF1\n      369FE6CD89D0355A6BE8EB8EFC4DDCF1C6F82FCBCA66DAE694A14DBC3125F655\n      E1E54BF89E0EB7F1680F8E0F24C44ED08D655769C6DD3442B6508F0AF852B380\n      885A555444010033F45CC67BC8B171D6E869A1E09EDF61985BDE52D2F033E149\n      613BC84BBFE136B436980ED0382473F590E6B2F5429B7DE1EACBF7AEAE7D2A59\n      5FBE715BAC8406553B03174528B0C474185A5CD9E34CB09841B863A2C43EB817\n      012207240572B04E7CC06B47590F281DB4178FF5CDBD6641DEF7F7E1C8A1B37C\n      A398A92AE424EE6A59523A91622CC5AE35BB6505610AAA55B48F34D8390B11C4\n      D0676BFEEAE6F56B50AC73FC8D5CB34446F860FD73471D74FFFDEDDC7FCE79E3\n      DA86E11C19B4A36B201214D73A807451A3DF95EF4D2EA4C18349F77D61F76D46\n      DC4D5827093451900091E088BBB2DCD3F7A61506D328AA110741FA84CF94A8D1\n      ED50FCF676FDC6FEAD9F3F7D848BDED72F5D5EEF1FFE446BE9D4DE4D994CE098\n      A626352E988448DB0D6BDCD8848F59AA52D7E8C388E2D464E601C2BD945AED4C\n      59D72CC4C228E082FA5A5272D1AC3CCCED6D1B217A9CCFCF989533CFD046BCED\n      40DAA7D961F3AD478F638CEF8B6ABC4770AE4410064834E56CB6C9EE71A5EF9D\n      A2180EC6F79924AA638DFE9BF6358EA15A295255A242DD12EB09621C2DF4EC56\n      277ACE167FFEC38B8716D67F69FDE883FBFB0317BEE08A5B66FCD4E2E2095593\n      C464298D2C4FBC294F155AAF413DEFEBFB8280CCF9AECDBAA4A173598879E2F1\n      A8C98F47D881B717F26D1B128BACE0D778853A8772A90C97712052688CBC50F8\n      E434CC981916266FFFE008FF3ED90A6FECBE77ED2451AAEBF8DA0472BA1B2744\n      739718FCD6D32097500CC6B1DF704645432A049292665DE9E6C259DBD062D80C\n      127A83CBD95CE68EFAF681E49D6BECCFC9C1DF7DB3720D7E3707F5139B24F07C\n      A05CE72DF446A70A0AD3451C8C8411D7A9506B69FBAD779BBBF7955DB43A8849\n      CEECC866B5998474B7DC3F7BA1BC32E894BD605F84399DAE1581C257AE42AC93\n      62386A41E024B263759B9307DAE63821D1344A7A0E57013822368AABC86658BF\n      F0BB5FBAFE8DEB71D68F9D1CB1ADDEA3DD53FFE8F4FA23C72110158582B88F3C\n      6A05F50C0744982C2E93BB160A5BA5D706C5B64AEE7F94CB04EA4C4F6D428974\n      ECCE7A1F2AE56D4F425D6337C65534CADC78BAF3AD97D7007BB141FCDEC7F69F\n      7F7DF4CAF513CF3CA2EF09F2D1A4633B5AE69EBF0B853520C2DC18C9C37B8F1C\n      FF5D3A19BE2F2842B3A5B3ED7CF1F1A7A06E2D24DC3308ED0535458DAC5B09CF\n      6DF2FD37767707C797D68A572E5038C5FD16D44C7C7B1C423242AB059684E924\n      1F75C687C66C6A8E174B8F76ED8246FBC8D26217CF19DA0AB0DD0021248CBCC2\n      8CF178CB979C5E848132FC0F8A910A14BD9C54F574C49616DE26164F94750269\n      44F289A01382DF2036AE456A9A98C1E4F2B34C0DC4A99FD3A9343C681B615EDD\n      FD0F7FF46FAFBD7A4BB3741BF054963FD05D7E24ED2FD5C49643A3BD6D8B3F50\n      3EC479693EA420A1F0985F39C6016C1394DD7C824267BE3D5EC1B2198A38405C\n      B64CA22A8E383A0D43DC85E0C882E5B8FF8E7BA77A6227AE3DE5E56068AE0EC9\n      B482B80E3FD55BE62011061775D15D01550A89B72FF06EAF1CFFFFAAC65D7BC0\n      0CCA4D2A9B432A1381111C390610F9B898C800925F579084D8D8D671C01796BA\n      782F342A03E266B145BF1E234D63CD80814162C06A7CF2BC6F3C7204670673B5\n      AB3156C38FC2294E85ABC348241495D7B5B6A8F616A0C2589D31BD9F84537853\n      7B792B5DFEEA34FBEAD68DC737D6EFAF74ACF5D18DFE4ABD85CC4881E5041A4A\n      502CF268D81806E1EDC735BF66458D35DB0E78EF1BE75D88D79EC0608DAA702B\n      038B03AC0B20EFF989355A59C3F7836C222B4634441931E26468EABC568571E3\n      B81D28C8C296E525546613E2DE2826E7D4F47555EF20C421CBBD147ECE39C5CB\n      B2528D872A7A2F62C0F7AC795F883485396A973028FAF16936CBEA5E368113DF\n      4ED13813AEA1168E43528E7BA57D22221F5C5C7F2A5D5825A40D37926B1B1103\n      F5ABD110AC2100E592D668D184923CF804AC81DC8C06012442E591AABA1E447F\n      34CDBE7B73F3FD0FBFA5D2DBD77F72FD13A7EFBD2F9731A09FB41282F5740099\n      2247B90716685663A9CF4B8D132B28BED3120A24BAB7B8F89CABC7ED7899D223\n      A3E972A10C3C9C585618248542CF02F878B68576083A0982A422A2294850090D\n      B98570EC95ACEA842B4B5313247809EA3AB40A6A7F03010FCA0F8ADECCF0004A\n      B4397111CEED3509002C43C26549C4DB21F57D633F006F24AE9B7E8A5F61C674\n      884D2DE4FAE91A8A3A5B6B56C0B3C6468EF21028341C8ABEA14CBE3ADEF9DFAE\n      DCB8AFB3F1ABCBEB1B6CFF663D79099F6CF0B75ADDE34501A14476432B32A85A\n      EBB05B1934F3407337C86106E5402D6A8F421942CA18191E2DA83C7036E4CA60\n      46319A371B3D89C46B3558EA66D912BB4A66365074DE4A1ADBD00D4308B91A54\n      43AD41745EED4F49A2F4F958FCCED6EDA327CF7C82464737772B494DC4A3AA90\n      61080FBF6B9872257A2185A108392E3130643813E147E26CAEE78B0C103B5F15\n      9F05A6A6E139CF7433FEAFFF2F4BEE90BCC96CB43877669E2B52C0E1162A4648\n      191BD4F04441F0AE082291866915DBE161DD7E5B9F1C0902D5762CE4F0864B4D\n      06B9DBA9DC9EA5D7C7EAEA8E9D1AAB5855E0BA421C96A853124606F21F8E0871\n      FE474226DB325E6FD34328484D23C297129EC468E4512B48C535D4A217F4E667\n      7FB4FDDCE6B5FDE9C0AA8576CB646A29499EFC7B8F479FEC664BDB79A5BA7C5D\n      4C433B2A2683CDE4C8218186EDACBC71C9842BC9EABD121325F3A36E7C6EDEFC\n      8B1E94CDF8B50DBC955C055026EAE1B75FEA4F540D78F5D1BB377F7CB6DCDA3D\n      F6CE47EC5D5151E76963E7674B842CD8B39AF08090D6F1B58D7F49B3C907519F\n      7CCCB32BE3F4E809BBB6985305179943BD861BB0685C09C79CEEB3ABCFBDD8D7\n      AC55DAC9CE2E8DE1CB266677C20B000B2C77E8AA8A54A9F182712A6BEDF71EED\n      89634145CBB89DD8AC8032108D3605D312C231EE44607B8E98F9228F27BFA104\n      69881809CBEF00B5C1A786952BE9E27D243A0A7795898CF2716D2B4B3BC4F690\n      2B6286EEE60BC3DDABEC9EB78B850E443079397FFE0FBE72E5D9D7A11EDE31B6\n      2CD571913ED85E5C06F4A42078648CFC9482111660DCF7E4FC42A39DF1AA6B72\n      40B09EF51C660A0E7E9B11CB4CA81E1367F238AE9204B5DD6C0D0942014A580A\n      16DFFD60AEA67AB76E41229C0EED754884AAAE148A7A12E225C09000D2680561\n      DDAC11056216443938EB509214C52C26F0EA6A84E41A17A5FC828A315ACA890C\n      6595779CED30DD9174A103A8A661B2E0E88DCD396635AB9B76197C012170ACD6\n      48C6345A9EB38B85780FF2130017176A4481259AB83B56A37FB741DD230A9992\n      57A64DAA218E02E2DCBA1D16BC34CCCF6EDD3C76FCE8F1E5A5E2D6F523213BDD\n      961D632AE11DBABD8E360E1242E456BBE60379A99A86E5D8C83B368D58EBFD04\n      7D3482F30C18AB7275D5901D85B6F0C1941FA462DA02C45B5364586964810ECB\n      6AAF2C2AB427101738CDCB4AA6299348140FC228D76AABC8369DB95696676FDF\n      1E68ACC1B0FC42F4815DF0C65A6926E16DE78B5933394E4F94920C8A2D695D42\n      E0FB8831000238201132EF640E1186BEBBCF1F5C5A7BB2BB7AC6B0B5A28E6D55\n      0B350DEA2A866A18FE419AD424B5A2C21FE3CB3E2BBC2400BC195C2A815A36D0\n      566873354E3F974FFEFDE55B4F9FBEC755D78F85F2EE2239A9C23830B66D42C2\n      DA167E98AE90052543C26BA7CC44543C1C0506C2548A2738D8822396B677F776\n      E1F11710563BB10364AEAAC5B15AAE9C93E14022733CD03AB16631903160BB50\n      9401ED02608003482131D6A62A222322D1CA38CDA4459E37204BCDB988A42B90\n      8288F8450448C5D715A40BF42FA13E48C08F863CC66514797F28D1589F114F6C\n      C08B83AE58B6D1C0C1C1A4374A46556E654589FAD6257C41B4F1628BAE535AF9\n      4637FE4AB5FDE5B3179F5C58F9F46A7FC3DAD7ADFDC6787F25483F14F40FE785\n      6959DD832A9D4DC665D459A82C14ED589FD6DCD512AFB2F4AA2515F6C879ACE1\n      03A11C76ED3BF24D898B19EE4DFF326FF29DA266AEEE70A715AF1B3D77A2303E\n      39EDAA52E5056D8FF2BD5EFFF755F5FCF55BBF7EF7030F8CC79A1B40DF415946\n      0297A0138C7CD67B42B93009C2141EAB2D6D856C113E532A17BE38B53E113626\n      E48DACC19B12618364E9FC8CDA372F0EFA80D628211CF875129C08C2B10D70B0\n      269DA481A852413B611447861AB544A2477BC15BE2A1D85FB0278DAEE1D1E84C\n      93DD926C55F456A66F8CF5768E0C08CBD1BD86B3C842B2A13C8CD1B75B480789\n      503A9E8AB02FC395D0F6781DD6B21D143DD64AD31A996A1493960A76FEEFD747\n      7F71FE30593DB7B9F5FCCD0B244C96D355B95BDBF5E9BBFF9BA79377C4A87B38\n      911DB9565EB935AAA62B678EA1634365F2AD2DD13B4A3B87BD3F0AF5C5823B18\n      8E92D94AA5979F87884D8B9CD61171D5D90BE2CA36FC6AF9C089EBAFBCC4CAF2\n      F03B1F354BACD2795263F3B9B63913B1D342D4155C26121FBDEBD8EFD36AF861\n      87D4BAC4DCCCA6A5ED3E782F9C241453C76400984061300CE19374ECB9EB7BCF\n      BDBCD25D980E87769C777BBDBC2AEB7119D748682F7089202419875AAFA42373\n      98F71E5C676D5A26759938A9CAA4F46288516A78889434D650F6CD8C02817D1D\n      6CB4D45EF39647210F24A90B359EB2E4B85C79186A599F37E1E142D2E1CA483F\n      B61FD3E1C5CD4B2FD3F507568FDE63AF64AF7EE1BB6FFCE58B01EDECE87A0B55\n      3F82B72D1F3A2C645167635AB547AEB1ED69C82FCD4620C660E9FB249C35D332\n      AF77F0D3662894CE38A4F3CD24546C71BA886213250222231ADF519CCFF5C5F2\n      FB1FCEABBCB836EC66B22A26EEF698647E01CE9B5061C50C71476BDAAC92C3E9\n      B2DAAB4AE08237D186D606F7080D1B15650939082D4EB1C06AAE26DCC2C292D0\n      D60B9277856D05ACDB82AA0FB205865A2A9B513912130A00A832E0701EE71CF7\n      6645E3A0D9D254C65A70597B9769676BBF46E5D0EA1E374B6A87D018AD4A8D4D\n      B231E0205AF061DA7996F32F9D7BF1ED87EE7A64A57F76E7D6DAA195F770B6B8\n      B53B4A164C1B430EEA3D437496682EC1428929676662D8D4BFD4CEA4F61B4EBF\n      B702D6681F880CFBAA428D74CF421435EE42E55E8B0ABBBA0AE28F9812332E00\n      1B239D1D1BEB819808F29A569747C32B757D4D9713419334594DD3051E044C6C\n      4DAB57F687BB41A4386D4F7695439969E27D56396214B80A80892D7A3810EFC5\n      6C70828E9ABC33FA244478BC5610DE4AC019C2F62AF56410BFFFAEE31F4ADA01\n      EAC7A38A5480D4630C27D84EC1262097C40738E36D88F0AC5974678257651482\n      2B08C92E0C707468AE26E9E7CBFC8B172EBDEDF899933C3F9544D14E71427622\n      0B7524835F116A0FD7381AC67A82594E0B38FAC10DE66E218BD8CA28E80AB96E\n      6532B5578BE9D9C4BC6246CBDDF4B80DEE93AD6498C3E335328422264EDAA454\n      4429C8A88A2BD9096BD65AD3659F2A2861A50BDB531154761CA9410F4D1EBB15\n      4BA128C2158B2A9012CD94D07F19D080A8B038A521F5A2BED807464B5B000EB8\n      9C164256C2057C6CFACF8CB0ACC73F5EF6130E195E028440A1A2F01074AD32AB\n      B0D95DE82463814BF784D8EFB7FF6CF7E2972FDCFE3B6B1BBF14ADC4D5F82B62\n      F295DD9D67564F7D54045CED4E7AA91371CBE482A82A68A75EF26112225D23F4\n      FBE30D06F5B41166B04282F84AE85CA4E180A7D9FCCBCE44E5FC7F3589D0F302\n      AC6D08C9DACFF8E1F460CA825B5C4389908B3CCF26ADF66B61FB0F5FF9D1BDAD\n      958F6CACF7075B11263401E808E28A137E208BED600D7F1DA6217C7628851CDA\n      00F8C6F62C89316FCED3D87CCC97B5DE243A78C0DB6BE6E4E44D59B09913CFF6\n      690E3C99E10F62160C990070449A057F28535C1A4CD322BEBF953CD8278BBCB6\n      4AD63DAB4D31C8CBBD2C9C72BE5796570776A7E480430C9267BD4E0927120A09\n      A8A821A4006E173AE43662C142142D46A4836447A804652BC897C324845AA084\n      B410BA363D3BBDF4AFBE19DF221D974E6B7D65327A696BB312412B6D25A266CB\n      D907FFEB8FB51FE9917AEA46FAD6B5EDEECA526BB507F1281B56EA46B6B0F180\n      69B52D0027E48279D695B594CD81F15CADCE42E86239948238B6DA1995DF7D99\n      D73A7AF0F8C5F33F89193BF4F647F20E361DD2DA61B700B71F03C053F03AB4AA\n      4DB178DFC39FA5D5EE47709C43223AB2B7AE6DAD9D3AC39716D1DDD4E1BE2294\n      0EA80C16B1CAC94ECE27DF7AC18CA721A5D5E65E12C47528AABC0AA7367290D3\n      094F9350993C9F9818EE6A19DDD50DEF5D524B2E1305A1AA65A8C405401C1D22\n      65C34BAFE17CB8519BF0EF129B61D842871B175924BD8D04DF9DB805DA3D25E4\n      D1B0EEF3BA45F001472A26B5C8433A146EB477F1B568B81894F1F35F7AEED6D9\n      BDE9582816EC67A3B6D56F6D2F3C14A7892A0B574E00ED94319EB8597D414C23\n      0B8E732484838D778FAF31EC412274F329826F5DBA66D8DE8CD290432151C94F\n      60FB51435AD69CA8BE587AE6A16995951707FD3C5455AEB74724C36E27EA5EA2\n      00B1F5847EEDC3238E8C981FD620FF492124F2AB0BB86232C8AA8AC98ACBDCC2\n      5B43F5F066900149122EFB422CFB218FA1D40B00F3E1C0C636AA378D14192548\n      E795121321F31388466E644E999B094542EA113C42E11B830E5D501369272130\n      019846E72F8A94B91A79A394093D1EAAB8F5ADB1FEEECED67DC7EF3A11C8D1F6\n      CE423739D30E0E4D8A368BB258D629A036480288FEE1F260F39F23A5C533812C\n      F7108CDD893600D3BC7AA673000AA08A9C690B183B93B8C3C51254C7E6165D53\n      B2DA0EACDEA7649FBB9C0164C535502863201D4294878A625F55DBB5BA5E4E2F\n      8D87BB45D90CC521A1E5F0AE71139DC585560477C4A8D7F99598E1E087488D02\n      BE08D988E7D00218E4C64246ABA1D494A8B18421BCB46B9A3C12B7DEBFBCFCF4\n      C2C25D84AE030C27A86F62436C7F411CE7811FC5B866AECCBD34381626F0F1FD\n      9E0CBE190C8846399F08A546CDC38B71FC2779F1854B573E78E2CC7BDB61BCBB\n      D395AD1E117D6612A8B3F17AC2D142916048BB18E1840268996937B0C980467B\n      B6BA996F6E4E47ADD6722B5A4DDA296DEBBDF1F5EE4DB5332827EDAE5DEB2F46\n      E268562C55F5A4ACC65154B75A82D1D5A25EC9EA4B0BF5E1AC5E544EB47A55BB\n      E3EA7A9954899EE01E3C8D2A5C058304E2B0C160BCC633F22FE016A2720F40F6\n      1863242ED5D528DAC08DCC91A208158887E68D54BD464E1C69660AB8C38502E2\n      9EC2A56D845BD2D823CD5D551944CE61455B7558295728BBBBD6FEECEEB56F5F\n      D8FDF4EAE95F9041DE219F25C3AF9FBFF9E9B5B5F7C5294FE3A213CA62774157\n      8AA55022949CC01DF4D35C38FFD88B6F6147948E635A034AA31CB7BCF8ECF879\n      1EED9B54E858B30CE2AB64BFE9DBE8F735236AEC945B2F66E497BF1CDAF89800\n      62A6D5D3BA0E93C56FECE77FBE75FE230FDCFF3E5DC1532D5C240C8528350D34\n      2EC0E1A3C00240480EA09084AC46373EBCB0BC99D5BB59A93A33129FFB2E1DB4\n      AFBC7CCC0C15CE3C34DE24D8ED678273D952DEB449211743A0486D1094292129\n      4F824806E128AEF419B9FCB756D15E098A4BDED27BB929EA7250B0A98B725EDE\n      1CE53786B2805B812A2606AF0A86C73215110042C03B22408D9790D9B60C1763\n      B110A0D754A86C68792AB37E90C44E41E463BCBD934E3EF7F2E41B573A32A9AB\n      B213B4322ABF73EBFAB9D1DE34B4C73AAB6A6FEFD8D31B4F7FE6A9F4FE747AED\n      E2F6B43EF1C0FD35648C90EE5D1BB9DD68F9EE474CC49A75208CDB0DAB6ED64C\n      62F3F5558A453B84040821DC844539FAABEFF3DD71F7AD67DEB8F6463B8ED69F\n      7E68D2861C6912C51494700655465C59D380A989DD7FDDBDE7235FA26AFF9310\n      89D07AD1F2FD1BFB214B3AC74FE900259825A0120889BC56C8CB91A911E6EACE\n      ED677FB81AB769560DF706ED6E0FB7C3C7654B49381C652C630711BEA89044AD\n      444FB013ADF078C7C4B6C25D7592C2F9ACA08E824F10723CABDEEE8FF994D7A8\n      B860F92104E01AC03CF8AE010E4E5529F23A6D75CF88F008618BCA06BEF70288\n      AA103A23D968F0FA05F152FEC68F2F5F7E633836C924ECEC8EC6647FF8587FF1\n      89A595563625451642A65290579246C9C4EFB1CFFA83E82921BCBB389DE12476\n      A06E3B4F8407A5C79B7D3219AE9A85CDBE3F812FE509CAC5025BFCC043E37CAC\n      CF0F978B685A4DF4EE84A22B7D53F035EA3E9E9039970D633E6033F87785A21B\n      C4B7492BCB0685AA714ACD728049B8B60719C5C0FDEB181308DA4F02EC896293\n      CF4B69434A9DE9D0E39783A35BC75E14C4DB3BF83D337267DB8CDCC1BBDCBB63\n      4116AC305CDBB482A8E632E700E2D3CAA519811A07FEC1ABCE0D1683EF0C77AF\n      ED4D1E5ADF58EBB5AFDCBCB11AA66F6FB7FBD9C884814AC280642696508162F6\n      95283CEDBCB1F8ECC1CE290A0D498ECD2431B4171940CB1BA3503CD277FCBD69\n      02064C8612FF9506980A6866687406415304634A375D7D494DB6AA1277CBAD70\n      410C993021BCDDED96A1B86ECA6F5FB97C1B75833CDBA5B19EC75F17FB85763D\n      332A68D815D888C1E55CE399BB68EB1D26F09C0514025441C081C3DA12E4C1C5\n      D6CFAEAE3F1DB6376A9D1805E547CE4D138A984F945EB0D5F299E111EE416B0C\n      6D5EFE058EAB41296E8485A6E68067A1E0F13342A2EAD7C3E04FF2FC5F5FBAFE\n      F3274E7F9041950C98288A185FE5AEA533A8C0A11C86D21C37042C0F917A843D\n      1DA604E0CF8CE829D7DB9C9C93E2FB595956D40E070F2D25CB4BC9C96C6DB32A\n      5F27E5053B2E86837B93CEA96E3791625C97D7CA69C1C97DC1E28989A8E55658\n      473C5CD8A27CB71A1F0AEC69AA9698A54932062CAA39D4A40977B19D181E9634\n      2A195AA2715111977344C3009F23EA024A71C5508BCC503FF505F01045220054\n      C27DEBDFCE34DE7CEB19977BA0C6D2E81283336083A501BCC6699EE35F4ED482\n      480305250EB910467F91B9BF3CFFD2DF3F74E2E7C370109A3F2593E7AE6F7E74\n      E1C8BB5BAD3456289358550001AB00B531624D5385117E1C02C8672DCF08CF70\n      A71DDD9AA03E6BAC179BEE8E1F8ECC50979D135C7D9FD4EB2DCD7A94CD6E8F69\n      E0085A6EE1BE38FE9170646E5257E5E5A2E257170FFFB3D75F024CF0EB1B2B0F\n      4D2D372DC856815013A9022D11AF6147CBE2124004719868DF844035BBB9490A\n      614DFB6FB6A935137DBDA3BB4649A38333E335DCE158FBD8C99A0AB751C56B76\n      4820F4072CAEE3A068099AC87610D55CD5A782E8C95E7C22B610898B408DAC1B\n      D76A5C867087272EBF0615D4804C4C40B0869D09D4A1BE101F7482948A180E01\n      947B929711218B4900C5780AC8A57691413E75CC758BF10591F3691A2C655FB9\n      B5FFB99F2C0F432D746D33C8208446DB4CBCB873E3A5E1CD56D8EFD91E17E5DD\n      EF5C7DF86F9F3EBFF5D289A71F111B4BDA2878839B2FDE585ABD9FAF1FB1E26F\n      28E9B86662351319F04FC760C72513C695A2E24AE55F7B9E9CBFD97DF0E4C5DD\n      6BAD5E7BF5671E98A61564F5A8B485340032204291BA04FC536E93EBDF197FE2\n      57FF9AE6C35F881DC3F91304D7B1CEAF0E7AEB47CCDA12BC6E092537AD8DA8AD\n      C393E5E0B29476F75B2FB406559C24DB576EC60457CA8BBC8A4A1A3A91638F51\n      B78244E5D37D92B78F76923EDB23C385BB376818C28BD31205F925629586A037\n      B7B86633A128FF0E118822AF90CA1A671F36A8501199F14EDD5D2BD24591F413\n      97909DC29DBB36B870E3D6A59B3B9B7BD15E3D9C5450D3EC190E50A09A6427E3\n      D6A38B2BC7D3D44E512316DE2BC3BA74C654460B0CEEED5E913B805AC3DE8177\n      DEF9B4EECD88903602543F9D08D1CD3540DE2B47835003E50247F906592CF1FE\n      330FEC0DF7D91BC3C5A91C5413370124EAF7A8AC9F319806209146D550204644\n      5F3DBCF48A78362986CBD29051A54B2A330AFFDBD66CB6280D6549DFD5DD14EA\n      FE20099186A6E1DD0888B168ECD74C3271BD58F03AE05EB1813452CB77842289\n      970F9857A16981622D25C4597839CAB6D000DC66485EE051E6E03FB682046D5F\n      590BBF31186F55D553FDF6B16EE7AB675F5D585EFED0F2F23DA58154B4139BA0\n      455B28131E009E871848BCA09EF564D4C6E2A721EECC5A3DC8AE27DE7B496B40\n      020A774B002EA3C30D2ECBE364C9A05F1582B24C55136B4A47146EF7636B9879\n      ADB15D4E6ED5C5D5C9DE8DE9F4A26075ADA7E86BC510C7523984BF0E65891D57\n      7445875B6D2C0E6999EF8799A6E9C9676342C010B2A65E5A01EDEDF2B044D10C\n      ADD7B47E8425EF5E5F832C78B84D17024B8B49006F211080E846C2C5020D8E39\n      546716439A86FB88A41A7E2084E58B736F7907111F79A9F07215478D15F80CA1\n      C06E70FDBA909F2BF2CF5FBAF19163A73E46E89AAA6ACA3A69ABA3A64B807571\n      4F1C45BA15A441A8B951A050E5A4277912D1A236FB43EE2EBBD6451657290039\n      40E93BCFEFED6C46E18943A74FC7EC58CA62662F6EEE7EF7C6D690B387EEDA38\n      C648AB1F3F7BEBEAEBB7B323FDEEAFF49777C2D67383C11B7B9B4F2EF43ED15D\n      690D86BBCBE9F35C0D46D913A2FB561A2C94A58DB32A8C4734C90C09284B8416\n      28644EBCA3AA14C899D79240DD2C4CC3BFC4681060731A4D2E67FE0F33D76C1C\n      552290677AB6B3E37C62D1352A6D636F431B28B55B4602EA4AF8C2E589F83D35\n      FADEE4E67FBB71F2833BC30BDDF80F22F2F2A5EBFFF9B1934FD1124A181D8410\n      87343A7BB148E1532F39559801E7D3256FA886DB4B286EC40E2CA81AF6ACDFF6\n      9F6B07F8F3296CA3DB4A677A2D7855BCBC914FE1489CC59A068590F7A0F89D56\n      EDA9BA99F4FE54F22FBCF1E22F9E59FD38EDAC8D439C7BC85AD122A468458163\n      3B5C7674285C075944629043F698E71ECCFD24A8F11ED56EA66640DF6C7DC5E7\n      D2A9334BE4B9D0B9FF936C9638393B68B948F89491ACD310E2B5882319D1B297\n      77DFB926EE6F55266713C7723ED92F3B5389CAA0B5D0D7867BE76FD1A90B594C\n      9BA62D6AAA382F54C0C7BDA8C5824091508636A0554CD9720BE12084C1A02650\n      8E8496C40C8026E98785AD932D79FB0F9FE72F565DD22AEDD4891AAE969DB88A\n      B07D6A9FDBBA7633AF9378A52B2346F697EF13F7FFFCE9C31F7F649C94B8A378\n      69525CCEDB6F795CA7F11D436832AFA51BDC74474797033E700612A129B8C291\n      D773E7F40F5F6FDFB572AB1EC8D5EEF2E3F7E77145751902D80C5C625090C110\n      28056571AEBAF142FDF1DFF80A1D8F7EB18DBB49908579E4C2F18B5745D88D8E\n      1DB761883B0B983DA1BA51E86614F31AFEEBF6E4F2579E5D8B3BD2B1BD1B5B2D\n      1663DBAEC6C512789B79CC3AA8F0598ECC98AFF3EE99E551B1091179E9D82922\n      A38A15659849808EB84EE77D7499B7BA683425D9CCFED6870E6C1CE6321A87E9\n      12942095294719093B41B4CCEB287B6DF7E6B3E777CFDE16753AC5C556564CB6\n      4B089C446679B9D259488C5D1672354C025C5AC2D402C8958930ACF2D92FC019\n      B04F71DC1B987A29293B57BEA4F60E229C5722078970267E02A7B0928ADB0832\n      35768F792D03B8F661B1C8FB1F786067679B9E1BF686745F8D5164B946C59B66\n      25DCEB6BDB99DE87F56D16EF060B053141AB2088E4123E6C65E9B8D223654B86\n      BC7B9F515098069EF27A08C57A08B107D5E138C5A04C8CF6BD035C73C6292AE4\n      4151F299DDB607AFDC352E338D57834FF6D463C456692AF43BC5850489701025\n      73E1C701BC85124455668798A130FF26C8A66FEC3FB97E6665397DF1C639CBE5\n      BB8F1CDF980C799D97ED40B7651C8814B27980D6BE7845BD5F956D2CEDEF8C5A\n      99F5BF97371108DE187A4296804443CE2DBC291C34353462FC93B5221388F444\n      4F002AE34F9315E063F893686E20D16F14429EE043672E27E64651FCE0C68DED\n      0A725A40146ED74A782FB641F790F1B0836CC9D42FC7A122B19773448159E9FF\n      365224D1C32B222C689B3DB8CE0F745A1F58DF78D7C2D24942528D0B9C35AB50\n      8727148A51146180275CA30C13948880C7EB46A00045AD30367174DDF4960DB6\n      29F90D37C2CF9C94D406BE5AEDA4C0AEA07A4D467F52667F7AE9E607D68FFCDD\n      5EA7BBB317A52D69C9E188B56C29FD90260BA018B291F1F3197836359F502324\n      81727C44E9EBB5BEBD335A72721AF1ADBB8FFD684C7EF8EAD571B07568A8EEEF\n      86DD5E9AC5D1344C6FED8DC75BDBB676877AE93E24FDF5953DE7DE71BDBCDE92\n      2FEFDEFCC0C3F7BC838A433B1904F76769FDC2DED6BD61F4E9D58DBB2BD375EE\n      7B4792F1E6765C952792F61AC4D712D7CD6D08852D8AEF31E11D6C7158834A6C\n      8DFA8C76FE650B16A61152A82023FA5B66908789D75DF85184172BC25DFB18DE\n      BF56B903DC0F65824BACCB294D2AD1CF926F25ED7FB17D79D1AA7F922E6C4CCA\n      CB87373EBB777B73EFC62F9C3CFAA4128B868C3B258E78702DCA150095E197A2\n      B618AB71FC4F908327508C863B3953C340FE216FF6EB7D7F682E43E30F2BC745\n      7BE7AFCB4128C0D628F165ABA7D361E654704F70E3A08CB4DDB5E2FC5D47FFFB\n      57BED7EA069FE9AF3CB98F4C8369827E9F10EB1CF2A23956CCF0F60144751228\n      8B74C38EF1EECA7EB36226683E1371F5BFD9F85ACACF6B66AE9C3F95086711B3\n      11A86FB4D966069F486A82679A70134744B65D1A17ADB2F578DA7AB45BC78A54\n      4C4E65B197C3FDEB0EDAA8BA7C7B3CBDB24FC6566AC81368DF66FCA216F68B38\n      2E4454691BCA3EA8928340988857000F9752D9C6E939871018BB3AD42C0E6827\n      AF9228311DF55757A75F7CAD5D76344ACC968656503C88CA910A0D4A760117DE\n      BE75A5AEA2A8B30438894D3EF19B3F4B7E7E75BA947145F2EFDF5E6E1DD1678E\n      EA28807FA459AF646F36C76B884B4DEB180F1B9CB58CD790DE4B0189F5952BD5\n      B75F6AB5DB6356D487BA4B4F9C29A5A2E817497361A068D70E4AEF3C5551F1FD\n      E1CE8DCE07FE8B2FD23CFB4F63EC44D505EE2872B1AF0757F77B474FF17E17CF\n      B5ABA56723E31A78C0A6B64A6430FDEEABC5D94B6BDD95E9DEA0DECBE066D6E8\n      17CC7A3618270C10C2221CF92A1BD05D794FABF3E8E9D1F9376898B436EE42B2\n      5EE24A3282300238D3971C11F120C0B7CB911A0B076556DE505E703910F06883\n      5EB8C04674786EA7BA3419BDB65BDED6F5946B134E4B572857691351BD20C345\n      213B82E326ABC3EC044F1E891E16DE1D32169195610BD43EC59579EBC54970D9\n      CD7BEDBA195BB0694637AA0F3F65213D638D3633C24693B08C6A408509D44290\n      452084E26E1055CB72F99987B76EDFA4AF0EBA6336618A969A57B8DB306347FB\n      352A6C76615BD935133C5DA13C3F779E4C803533E436365180846D09E0CC1AE4\n      A9EA5A4AB6D269F724264C6CD0708B858440A510F4A942F300E9FB919877EAD9\n      961866C126E759EF613EDBC96D261F0E2D809BFF17250AD0E3169789C39AF3A9\n      81937BCD96B75276DBE52F0DAA9F93BDD3BDD5BFD8DBDAAC279F5A5FBDA7AA54\n      68B3968E22C36458B1560CB71E699D7E12C41A8D527767B57986C4BD622CE006\n      ADEB1C0A47850E1E0D62C59285A371B4A7D356553D069087DA37CE3725D8C0E8\n      6BA4BECAEB9BA6CED1B54320B0D024C1252DB96BC90B5B5B378B12011912D6B0\n      E068A498F1817A25636F5A3153334635206F748EC40D783770D08D4661A380FD\n      4749F8D4EAFA7B56D63670BE35CE009373C890580EA3C737A73620E8BFA32B5F\n      18A1E814EE9E208781CDF97D28B04E678B920CDFB4A959CDBD0127244278C870\n      47D15D1D0EC66B22F85C917DF1F2CDF7AC6F7C7CA1B7381AA450F4C9B0CF5407\n      A9850E8E4B018950D208DE8B0E4A4E223784BB5DD9A8A317A108CEDD24A7E545\n      5DFFF960F802E7277B773DD559B5FCD64FAEEF3DBB35D89624EACA87BADDC716\n      56B4E55FFED1CBB90820189C5ABD2BEDB6CE5DB894CB6AA39BFC4CDCBAAFDDBB\n      5E555FDBDCDCCFCA0FAD1CFDE8FA61B57D55A5E194D1DF99E61B83AD4FF69377\n      A471978AC286A568C1CD4A20D788C2E10085174C2468034B708F81C2BDF32EB7\n      F08C04E311BA58FB8D25FC4F29F069497F46B1F103305CDBB4E4901A95ADC750\n      181AA82CE0CD409CB041ED42B2F4231DFC2F175FDE586FFF5ABA7CF2CAF0CA5D\n      2BFF6CF3826BD17F7CE8F863835206662F501CE75738C8AF50BF0703642590BB\n      1478BD698BFE0BC2CDF5A27CC27073E729DB8862DB86D48A3FA4518D3EA092E2\n      56A4E73C19EA8D4D20A4E4A6EC57919998619EC13FB99BF6FFD8E65FB8F4DAAF\n      9CDAF874154725C95A510CE81DFB5B78027DDA558C530141AD1D619B1C07E08E\n      F399B84CD39B6DD48C0F46304D186207B2A2B3194763DE7240ABF112577466F0\n      89A65A700D655D0738930CD3CE3474F481A4F78E25D22B543EA5234EA7C2E480\n      A2B9B8ECB29D41BD3BB57B2AA85880FEE71241AFC4B201A941A8CD4679D4ADB5\n      42881DA3D012ED45B21F052920206F400CF9AA2DA19E66EB654C7BD58F8B9DCF\n      3EDFBB6E24FC08C99C422E61419456059450C232D7EADD52D9B76F5FD8246239\n      583B6465BCA19EF8ADB775DEBD56ECECE5578AE563F7A9D585AAA8521C3F51EF\n      C5CB0EFAC4737558AFA58BD8108AE20C75F9439B57D3CEA452DFFC51B03BD9B6\n      D3E88953ED073734C5B13AD4AD15AA1CC89C2988D8ED2D553EBB6FD387EEF9F4\n      1F5093FFB2DF9BA971CD1BBEAE22D9A5BDC045C93D272701151AF227F21971B5\n      B8CACB441A4993FD72F28D1F9BEB7BBD4E6FB239888CC850195FB4AD1C86D87C\n      886B28EE4CC5C6D35EB5F4964364AD35D8DB56C6F67A8B512B862245BB214551\n      A400E382F5DD01AC99FC82955F5D40D56FDC150678D19179505C55FBE7C67BE7\n      87D98D52A8B8CE21F743C484FC56479202046D85BD95D2F490B9A632807F162D\n      DB4288B15087E081B6319A5CD371A231D3A02801EE1EFBE910EE7EBAD990722E\n      4C6F0F24FBDFBCB1CA9ACB4367E2FAAE0AA16E0D230A1588D5520312D210010E\n      B517DEF3E0B5577FC25E1FAFE8784C4A78FB0205488C77046B6C3F7D2758E34E\n      2DEA410202AB14A26ADF2F44F618157072C6A5065C58E29FC20C19700AA82B0E\n      782C15D67F1C39EA506EE380D0CBA841193393716ADA728C9399120E278D9069\n      9301DC5CD9B05146A6A8012F14EA1C6874F640037B36D4905A6F3875A3236ED8\n      626B347C9B3C4D7BEEECE4F68D49F558B2FE5E89838029406CEC0098108A4FD9\n      29482C45EDF735BCE9EEBCB13C1B6934F68ECDB945BE044A3003B6C13EB9462D\n      72B86E80A04AA5F35229A4AA1A806F25D44A06D9EA993113C6A791BC5595576D\n      7E2ECB2E293511BAA84948C91280358762F208EC082950F005C0ADC7F4D66F75\n      93597D3DB3D26AACE94860BC081D04A3A0CE8E4BFBD44AFAF0E1E50FB71717AC\n      6B43A231D934ACCB38702C8C00FD23FB1015D1116BA0DD1AF18CE7C67B883522\n      0CDCD38B715AE837D6AD5F3DC5E70C884E7BA6A0AD0594420A823513B5A98BEA\n      42147DB6CCBE74E5D63B560F7F74B5BF381C2CB8A84F832EAF13A8CFB1A7478B\n      C069C92205DF4AE6A1436F8C2A63D8736BF5264CE4F5E505F2C79DF22F2E6FDE\n      2DFBDD6C3C1A4F16177B57163BDFBD7E637171B5866C5E4DBB00BC8268ACF999\n      7B1E0947EAF2951F0BE26E4A7E7A636585B9E2EA662DD22B6817CA3E75EABE77\n      545A4EF6AEC5F66B93D18F07FB3DBBF491B5E5F70BB562C6E3B6DC5A58BC35D5\n      ADBCBE2F64EBB897A14A11A0F399F1520CCD936E445D009F21DBCAF1508489EF\n      253B378CB0571129D4BE816F58FBB4D95650D9A08E5F61E100285743C4823042\n      AAC8AD8E21502CFF7155FED1E61B7FEFEE33BFB457B40CF97F1693DF3DFFFAB1\n      85D6270FDFF5DE8CDC0ACA292BFB491C42DDE209CF0EB52EB0B907B54484E206\n      24C726EE5C855BF80D57CF86F15E1E98FCC8BCE7C6D16D036E84F5B7AF11EFB4\n      8DF1334ABDFAA64545AA854C984AEC96559067326A7D3189FFE71B171E6C05BF\n      D65E3A3481571EB4303C1BFFDB384AD63A4FFD12344A03DCA6613875F458C7CE\n      3617E788B0D137B8B3EF3FA7AF3789702EFA786006E2D1B577666E8C4691841E\n      575CB4E308100ACD0FD3EE3347F80959E50339ACE8883A2558C5AB61662E9793\n      DDA11B433CE3910D190E08A8C11BCD903EEDCB73082D118B71BD2B80988B242E\n      D94FC26E84F08B29171000DD15C0C8381287B43BAF76BF7895BE3469D70C850B\n      71315BE05E20D6FB05532A423368B471BD60273F1C0E4B95AEF305CA27DD27A2\n      0FFEFA87C664142FF4E5EA618545B587EDBE7F8DCF6FDE5AF2EDE0A6ABDE0C0A\n      E1386548AE9368C017E755F9ED97C28BB70187F0A7CF440F1E3668726E9C20A5\n      D38996590058C4B42F8EEAEFEF070FFCECDA87FF476AB35F555443F52A017748\n      283705BB9595B787D1A963936ED4764216F0FFC3C5474D0C1DF152B8A4A6E4FC\n      E6D6D77EB8922C40369AEE8D45E9225C8882DC606311422E7392496ACA623B38\n      1EC5EF380E5F7DB4B989C32C11F6FB877530B522476369843AA88CAEADA201EE\n      76A32A253C6FCF516075E02EE4A3B35BF9C522DB65838A4D7830AA8C34E11289\n      172DEF4A93045ADB4AA9B4A34C50EB920386403E5A58D24021066B76995BCA42\n      093C68CFECCA9A2C8879074B27DE88111FB8FFFC0D5F843B0BAD738926E2F598\n      6ADC390F258B05603C5C7983BB27E2A3FDCE53A76FBFF432BF9277AB08703EF6\n      4D711BC13364BDA42F8E44508ECA4B2C2159C89A52415EE49E18EA6701A2ACF5\n      B8AC016A29AFCC0EE1A193849D3822440B2439420A47CB6174CEF2DB90D64B3D\n      36BAC9B39BECEDE8DC5C9CC293E46CA334DCA05A1FB0006EC249B6B2C2920E3E\n      54610860725AD19DB2D85F6E5F76459DA975921EA39DAF429D37B9F289B0FBAE\n      3A850FA9C2BC151A1D0693286E311B73B2E7654CB85F89B8F3E49AC186F5E986\n      FAF53263110B6A831913356B70C7006113946D709C2A55E00607F69D1445F108\n      D412E370F0B82150EFCBD0C85CBBED805E4ADD8FAAFDEFDFBC9C7B221FA63574\n      BF430DE01A5905DC53583CE90F17D610C971657045075027F5E695F0F70D729C\n      CFB4A327175AEF5C6EBD350D97290062A3E0CE609002BC2F63C3031461E6A564\n      85B4354409ECCC2287181BFA6466088505DDCCB8C39B3734FD5DE26916B83AAA\n      7D6B14AA931A0A345B31A5311196D3EC7ABBF3AF26E33FBF7EEB6756563FBEB6\n      BC321A2FDA7091C92E5561881F137E6A05801560045257A08484EC1FA43CF10A\n      3C555AC54AF6FFF7F1CDCFEF5F797BBFFF91F8C8AB64FA6536FCFAF9BCD01348\n      18EF5F5D4B9756BE35DCBE9E176452F66B756A710D7EECCD6CD03DB4AEB7F747\n      A35167A95D8AF0FA10924E78AFE04FA5C17AECF6B9796E6FF7D6A83E7578E397\n      F9EA5A12D5F9FE7E527F6B74FB9AB52717961FE3F1FD56AFE2C4CBE27A948890\n      813C8B557E04E05744B1AC45471E246CF3408661384EF07424350A84D4A88A87\n      CF2CB2525638AC4739234884AA12A566B545E2A7D2116DDF96CB9FDBDAFECEFE\n      D57FF8C0C9776F4DBAA2F51F62F1FB17CEF5FBEDDF5C3DBC5C4328A9ABD4E186\n      26F21BF0CC789B069C5A06C686D64D02DC92699A3BC862F21C27E7EF356533FF\n      26BF578136677385257805AC112F77DEE5043799BCD803C4802883BB190F9521\n      83ED84CAB32B1BFFEBFECEA5ED2BBF76FFE9478734C989CFC52E60287284B436\n      DF2B71CC0449D8D8526081CCFC49A5AC5199F13CBE199DF54032E64E227433D1\n      3B4C0F6C66E784A6E57C6ED88429178D59555C0AB610279D49306DBD7D257EFB\n      E182E66673120F0C57DC94D6ECEAE2D6A8DCC96D89920D815F8BF12337D40CC0\n      61428069157FB6E080F501059511AB12CA7B51DC4B652ABD46335A18A3424424\n      E4E2821EDF1E7EF5927DB6088A58913284FA5AA1A42742B212CD47A855A9E195\n      8137CA8B76FC93F1E895BD0909BA29658B1D7BFF7B4F1EF9D03DF22D6B958C44\n      0E0125F264122FA8DEF84C11368783640688F1D9F844683560534355A054F5FD\n      57C37337B23A734F9E481E3966B10D83747148769086F3102F62F0D28DEA9551\n      FB83BFB4F8C83FA576FCCB28034A391C41781395A461E5AA9B83DDBAE8DF7B2A\n      A631819005B9C28C49C8B5DF882138AB71EA87AFE7AF5E6BF516767706F11832\n      0D2F1891806104C40B9C18B49924E5240B26ADC756C37BFB756C8AD1787C63D8\n      D64972A805490CC9CCB8B55D0354B60281189702A230AF209EF6C97EB5FBF2EE\n      F8BB93D1E650D44969ED6E5D2989307D4D748FC95E0B62765D1A88E2B68E6AA9\n      A0C46964F9A15C8662DD13B491708168006A2F17125A066CE6152D1BB5CB99CB\n      EE8C32E61A3358FA371D8266CA53ACE9501C1C4AE74A94B142CB559CFB430D61\n      38EF1CEA894579F3CAB57E91464A4E5C89FB7076960899774DF48B2F1E175AFF\n      CB9033593BEFD2886B0A14D50D01186535B689AD772E6656B793A0154AA72B12\n      7987B8C0DB803726005ECD9E362CCDA65940899C9912349EDD3EEDD9D97899CD\n      4121766A34CA0AF31AB1A755B6AA2CA0B15C9BFD585ED0B94BD2E53A389107CF\n      9E8EBEF6BDEF3D7DF8D007237E42987DA755D26D452164058D768C51406A1B14\n      35F631F89D2DCC197C768DB521AAD11974A4AAAB9242F180AD704A6AAF14E144\n      5E54650DBF5AD7DE585E590DB175C8D94D57EEC5B410A2825AA16290A409844B\n      1E03487865B0F5E3E94ECE91AA8120A4F624AC99CD024E2703FCBD50563188B1\n      50F474B599A2EE5948C290A89CAAFCBE80FCDCFAE2C78E6FDC9BC840E5A52B2B\n      62621C008B9AE21B6D43E15163158E5E95B8CC8815518DD22E54E0781175D2D9\n      7C29DB4F36DDCC6611B3B2CFC2B8265AFB311896385068701413E78087A178AC\n      46D98D76FB0F87A3CF6FDE7E6265F9532B2B6BA3499B868B3CE8902A89BC1792\n      1FA9C321E6F0D6E196913CD2215DE88EAAA25507A356EF5FEE5CF8CAC56B9F5E\n      E97F9A2F6F0EC66F3C78E6B3B7AE7E636BF8787F49DCDEB95D8E76D3E4662C93\n      B87BEFF2CAF0F6B59DAD6D387D192587EE3BFE50915CCE772EECEF96500FF174\n      6D61A1274D35DC2A8D1B013AA8F947568F3E932C759DBE6DD479E9BEB57DF9D6\n      307B72B5F5B195BBEE0650A8ADED46A390E41A157BEE4B52E64504311433F427\n      840B8E97161720219D55F05604BCDF561C089920AAB170143011C21F0268A41A\n      653382F361EC8ED62287184BB2908ADC2C549DD7E2EE7F77FB279033FFE9C2C6\n      FD9B83DD85F6D70DFFCAE52BA78F24FF383CD62DD5B4AFF764D5D65034D04242\n      C0C7870CD532BA5E735261F6F3ED475F3412EFA7D65069FC1061D6C64719BB19\n      619F7B32A79D375290C8E3EB524C8481C5E117A711BCCA626F87EA7AAFB3FEF9\n      51F6AFB72E3E736CE5EFB70E1DDACCAAA0A1D5E2621314407E6319AEBE0E1208\n      F202E21EB618180E7EF1D7CD548C1BC58999DDCD4F25423233F7680CB8685371\n      A2430C5618D66B88A324BA4055C35AD632EEE984F19341F7999345BBA8265938\n      A0E110215ABD9B8D5EDF7503ED272690C502EAE138AAE3A3C4BF17A8C35560DE\n      88AD0390874C9147CC2D04F1621AA621CE63A5E1ADA0B425BCE5D6D212BCB2AD\n      BFFEB17A6E736DDC87589071C82795A0BAA80C20129137F30240E7F01DF4946A\n      1D4725672FEC6F9F2DCB4EB478C40819E54FFEE633CB1F7FA094AE6552382F4D\n      AF9D21C156FABD36F6E66732872916497450D5C33B903A8000F3C2EBC1CBD7AA\n      7242DF7A2C7AEC38001556940CDE5E40015BA800B09DC89F7B5D6F16FD8FFD83\n      FEF1DF8044F819AC58A08840FB22DC1D2392A94976E9FCA57B1E7CD8CA88D218\n      C74D32ABE1EEE26E91E1A1AC30C1999DAFFF50142EE691DE9DBA6125C23006E8\n      4B75D5924E99368F594046F9BE5864DD270F4F0EA1974BAAC5F0E66E5EEA76B7\n      9376BB7E015C7B4A8E296BF8A022B46D5AB6DC2EBFF1A3CB975ED8E4FBAB05DC\n      09F8B7AE62E6D65BED651EB7E02368AECA1ACE2BBA9C12DD2AAA29BA14611729\n      5254D6987070E7B5F159771EC9711CF536CD750871380368E671B4A9115DA372\n      439BFDC2FF4F22F4DC56FCF3072AEFA1AB0A4F99924873046411400497313180\n      1495E9DB9E1D9B52E078BC5993E05E3F80341B140D251B32131C3E6C12A21269\n      2339C73007B802628683E062D0625ECA489276004715FD7A19A0766C8A523B13\n      46C12C832C1986CC73D4F0F269A86992FA269D6DE69F3333EE86BEE1C7374808\n      301217362A03458529B5D743A67BC44D92602BCFFABD15244C67FA9F57AF7DD8\n      A4FFC9CA116727269D444CB170791C7535AB5A18475A7076BA629089D878D4DC\n      508F66463D4886F385ACA12814AD21B4214D14676BF035E05516068E4405DF8D\n      F092901C39AB48F1ADA4DC62EE52313C9F0F6E666A5793292753061F96441856\n      518C51A3DC755CDAC2F351FC345020EAC28D147C4818C1F08F51E9D78C153A7E\n      0521546C8BC43CB3B1FCC9131B8F30BB5466AE2EEA480E5BC930E4ED4C61116C\n      99445559A865E19340B480786A20C24AC72AE6E09304762EDEDCF8B963218F12\n      E5D6971D021709F1F1333C8535E60623FCE2225C55403DBCAE00B318359D5E8B\n      D33FC9B33FBC75F3E1D5C55FEDAFAD0D27810C3A32E83B950600831B15020BB0\n      02B5D7292EF5F58D2ADB720A87CFF49F2D26FFE2C6AB4F9F5AF8CD6ABDB7A9AF\n      1DEEFE5FDBB75FB972ED2D87564FAD9EDA61F2CF6EBEF1E268078D15194F0F2D\n      5D2D46A3BC6AF3109EDDB02C0F93603F746355779D0C08243FAD3A1C2BC302DE\n      175F0BA24FAE1F7DBAE6CFA7EEA5DDCDB3E30104BB4FDC7DFA7D616B6D3020B5\n      99B65BB71CBDB6B999D4E523C78E9C049C23B844B54224AA211A830A4060C1E9\n      A5F689775A3104E228204389D3C41A0222F767C122966F2EA3315ECF044E5101\n      47C64045D8D2B4939171D2FE7AC4FE8F1FBDF8CCE123EF72A20FE93CEA7C773A\n      FA3F772FFD672BA79E4CBB159996900839824108B225FABDD9D018E67B048E06\n      BE246CF454E94CDB138928C46BADCDACDFFD7B446D42C66553DF90C61AC27ADF\n      63AFB9063F2655046008A03D866A88D5342B18ED7E5FD9FFE1F64597BA7F7EF7\n      230FDD1C16B1800A4A181CB70914F96FBC410C8BB88871CB48FB3161B3E6341B\n      F979DA8BF7A6713F8D081BC6A447D9E816E9A5635963344B4518A0931C625986\n      4C5DCC1D61959AD142B6F1FE33C183ABD568576726282403443874E595BDF1A5\n      BDD8452CE4702921DD3512BBBEEEF604465428161CCD2851EA8409534852B505\n      EFC70807E1ACF8ED9992636FA707C13C8837BFFF03F2EFC7ED5204199D8C72D9\n      0ACB622C0257E1FA2E0A52B09AF972DDC01DA691307049043F5F4DBE3319E6A2\n      B5520429AF8F7FE4EE477FEB63A603F90CEDD21D2E22E363C1E53FEBE6FB9477\n      44F29A092E21259C5C289DAA500546DB572FEB17CE93AA0C1F3ECA1F3F5E4245\n      94E5011C28DC91508643D6973B3F3C1BD2A0F7BEBFD33FF45F5137FD0CBCD712\n      F707440C05755EB83694DD26BB7C2B75A1583F6CE356A0A22A9DD0AA96AEB137\n      210A35087979E1F6F007E756839E52F5DECD9D4ECD231E00A86011AD5C2DC348\n      B21022EBC44DDAF7F6E28717B33887A41551414641B99D95E514304EB282CC53\n      6573F8A20EFE51B2545D5257BE7B6DEBDC603A094ABE44CBA247D85A982EB128\n      C1CD2E8D4B06A837E97D99B1B50800B0C27E9509D158172766002772E390E3A7\n      71531EBE1ED400504D67987EE07807102ED12CD83A7B506A3552FD08B39B45A8\n      032784D9E3F68990354E9F98345B564DA9D490A72C3AFAD6316467387C50FF56\n      B108C5549ACCD244E6AAF057DAA7224F966BBC6471DE60BC735A0D20C9083F75\n      C2834844A1202AD79A0B74C4823BC3C842278E0386B64BE8E52751A89DE3123D\n      263C217C031D352031B961C307BB71C21BA0CDA93DD66BCBCD2C78E7A34ABFC8\n      6103F800655915B9DF93207CC2E830901355B7782A69B81F92B3C5EEEA76F1FE\n      63C716B35194101DEB30A525165F0915093C4A8D6098248E97C23BA87954E477\n      351B113DEFE5A4A16AF41605E8EEA67923360227B7B49008D1F49D70E5688E2B\n      8CB6A2A83AAEE01BC39962BCB076CFEA1DF1FFF2F5DEC1B666579DD84EDFFEC2\n      C9F7DCF8F27BDDEA28B5D4414212CA48622410A90083042E30533535530CCC60\n      0C35C9C30CF80FA772195761B9C62EDBE59A318CA74C8D84848484029240EA6E\n      B5D4AD0E2F75BF1C6E3EE98B3B79ADBDBF73BB5B80BB9A47EBBDFBEE3DE77C7B\n      AFB57E6BFDD6EFE7EE26ECD9FDEDE7F70E6A045742D8C86308F4BA6D702CC7C2\n      C691686D59FDD66D00F2DE0AA1864F51570F0AFAC1F5EE874EACBDB1978C71CB\n      1D503641014F2CFBA2A6AA53280E70BF52C1BFD8BCC6356AF845008403D084A3\n      27A86521B9091F36030A6FCB75FF096B3F82F5711F3E6364E3589C5B33DB2642\n      C028080BE1A494DACDF32B69F61FA3E8F76FBF7CAEDBF9ADFEF18DC3A94D6427\n      91ABBAEE47C64A44D2586C41BC8D6328F22987E2B4E6C55C27C979499FDCDBDE\n      4C7AEF5939DB9B348522974CF5872F3EB7727AF4DBA6FF2CD7CF3173FD203F9E\n      AEDB28FBA35B97BE562F20E80E79679CF5A344EEECDC9D51B82910F013543382\n      1310AA35ACF0789C02F22D32ED5628A9343E9A53BDDE4F9CBAF7ED0D4B67D39D\n      0EFB6AD47C199050453F385CFF709ADE53E71A5963900871F32C91B829E051A1\n      225EE4C1632C8A18C8240C40508CFA2BB8F71EC4BE9D5F9DE20C4EAF8257E200\n      7147BAC4C469165035603BA85792A9957FC2ABCFDCBAF98995073E3AB1A6337D\n      61CCFF74875D3CBCF2E1379C7C5F139DC401B75924045E0ABADB205CB0B183A8\n      EB34F356A3D42D117C88A9D6EFDE310F177D07235A364C011E79D1A7B0D1B02C\n      228937C7B49D8A161C4F0A5CF2A9907B45BD5289DDA4F75FDCBAFC4C3DFDA727\n      EFFD19CD2692667060BCA7253A08FB5D554C06709D534124D7B8FA14366C83D0\n      120DE2325E55DBBD6E46C8DABD398F90960E1B9E9BED9396E73E433E9591D704\n      60895B391CEDCA778D463F78B286DA72AED031033ED73921572B7D61227203E5\n      08C4D25A2BA819B158458160EF6182C28C3C12B147CCF83BC8B5EC4AB7D6E1A3\n      348AFDE085939C369534BDB515282E17DFBB78E5C927EF7BFE3E1DB9BC9C26B3\n      AA67E285291BA1702519574913AA13B8A2503D273A46DA58B370D23483EE3345\n      F1D4DEA4970C57A10019356FFFCD1F39FB636F216A81964E3C313610FC5B44F8\n      EAE684B718C3EA0A5F7BC921D9B0BA4C943426BA70B3F8F6793B5FA4F71F136F\n      3B97776C94978981446819CA5B26AE20579FFACE786BA5FFC447C7C7FE3975F9\n      AF42E057BE2D8142B53532B4200ED06939B9B1D3DD382E7B23E19246967E1E82\n      A1A651B5CD243274E666FEE7CF885B8B6EB7BFBFBF6FF6CB0E54170062982B62\n      6723DCBE9498A36A9556FDC74F360F0D0E44D9AF34E054FC9AC9BE9ECCE9AC91\n      44F4B7D66C1FEE46CF5CB52F7FE1EACEF373ABE2BAC2C58E95385D89B21E2A4F\n      E39E99370A4341B0400915FE7460DE857CA111D23BEFA2821EF5E8650C090125\n      4E3872A5053A4079DE31EEFC8956939EB47B81BED0F2FFCB1ED9BABD26178675\n      DB9653E3CF9F741A4299C15D257F742301294A08C0A12576B36AECBF60F06A54\n      5B053ABF41EFEF3C2E0E3AEF79DB601644313B94606199B68D6E0E351CCCC892\n      58C5721FEF5A7D264DC610948836386D402F037C18C10D030718DEE91947547E\n      0CE8CD3CE174083F95F49BDD3E2FE11812AF9272BE79E52D2F927972689B596D\n      8B5295F097A2082E6001474A22D52861D90B8B836FA6D57F6F470E4E7FA43BD2\n      57741937A8040E3F36D31CD24613A1BE4DD688C60FB29171A77CD1247121D4A0\n      32235ADBF84D2C2F8E8302950D7370930AC01E3CE7D182F305A47FB8CD717CC0\n      CD1D5BEC3272887D045A2A3BD166662D7CCDEE74B65D2D94F7B8771861694479\n      EDF7BFD0A1D78772AF1082350236AD3DFF0F324F4CD87B62F6F0D9D13B8F6DBE\n      B99BACD5A554254601C92B996874C6231DC35203901442240AC038E4B720AF14\n      7220D4ED75846342F83CA5B19921DA23BEA53400220DE69583DA851117F4DA90\n      5287EA0068A3E1B5361DAEF4426480B2CFA27E8AB925A297A2E87FBA7B4DC6F1\n      DFEB6F6CE63316D15194AC2A8B8930C29D3C814ABC1CA28743794F8202255505\n      A7EB566A4A4ACEEA6E34B38B5834B1D8DFDDDBA375EFE4FA63379B2FBAED0B93\n      BD87E8F8DE64F37B4DF9C787B74D36E0B53C7FB0FF5D9A9700DC88B0B1250BDB\n      45BC0675167ABB794989188E28B689004C47C8AA1D565DC0D30F6F6EBCF7C499\n      FE24BFB573F77BD5E4AA2DCEAC0C3EB87AFA712BFAD55CF2E6FC607865BA7730\n      393897741EED8F57894D553D8A3229A48EBC690E551635825264334125111399\n      088977C88B7AC22D14C82835B52F3D080B3BA6246F16107904599DB9B4E217C6\n      D9FF35BDD599D19FEB9E1AE5872A717749FA3FCE6F3A5BFDEAF0FE879BA6EE2A\n      9332890401644658AB3AC6C406C0BDEFFE11AF2DEC07F428E4EC15C9A917C046\n      14881A57B803D3440C300C927A8C4B896FDC0AEFB9A1B1D681079A5414C00194\n      4EACD28B78B45FAAFE6C9E77BAFFE4CEF69FE4C58FF63ABFB5B115577506DF52\n      6B810A457EAAEC0D3FF1D4C25D4E23BC9338230CA3C176AB3FD4054BE189F0BB\n      CB753A8A3BFD6EE9F41B289418E30079FA6E168B716B1A59E4CAEDDD674E7DE2\n      09D251CDCE1E81B8AB23AC736F2AF3D29EDECDE314C5DC49ED7737E1C1F8C482\n      18104D8FA877318C9CE4002EE08FEA4C252B7DB93E44697584213554F755D488\n      B561DC5B31AF6C6F7FF93976773EDE5E9DA9A2D1650F55CF501C44E337567E10\n      2318C403287089CAD0605094D4D4A649443271F6BBE5F4B962DACF7A63C6BAC7\n      928FFDF35F20EF38EE203628AB5D94451D548FB17ED8EF097D5EFA82A2C545EB\n      666E44ADACADEB0E7C3CC6BE72B3F9CE457138352B69FF071F2CC752344AD4C6\n      26A6E2266B3AF47A79EB85E7FA6F3DD33FFB8EADCDDFA176F1EBFEDC63911124\n      2FBD6FA1861BB298CCEB79BDB6750A303C69E54F2CC27102774F29EA7AF0C6AE\n      ECDDF9B327874D94C6C9CE74329863C46F38D3118A8543AD9CA1F3019DE9D974\n      436C7DF8513396E5FEBE1490E2F2141E68AEDD76DDEC5607935CF657A8EEEC3D\n      9F1FBE509279628C489CDBA21015136CC97A1F5240E9DE7A6AB90D1076E31C6E\n      8807C9B90845E731CDA07518F34C795CAC0B0419DF73F02D056C1D306797DAA1\n      4B2E656826124BC95F4B844B35233F3C5F4EAA3D1D92923615C1D189F067A09E\n      C9B28BADB10DB8144370AD821B92581A1D84D01DF223F1ED3450201B40D05023\n      55B3CA746CBFE6E9A5581D8AFC5CC4EF87FAD9D4351CCF58E08BF77372172A44\n      BFAE40961C802596052809C1CC42A88127D578193794CB34686AD8A0CB0312D6\n      2365E99ED8767A9F0B859C30649A54B4C10538429A4E72A1985EBBBBF7F8038F\n      BE7F761D1E248A682770CD309E21C049A4656143A365D5A28395F78880CF12A0\n      1AC4B5C4125154687D0B7503EAC8C151448FF70650DE545140CB245944D19E24\n      0768ADC4507252440BEAAEE6930BF9FC42A31AC9F7A8B9AB94692553C3F88DF9\n      798857C5E35E1D4DA1C2648418105737E15DC0FFC6D5C1868CB5BB7F3878707D\n      EB3F5D9D1FDFDA04E49AE0801F0B7B7C2A382A168145EAFDB4591516EE7D400A\n      6295962EA7324BA3734BFD950C2E3A47E423CFB86F1754C25E18FA5AF8638A1F\n      793B3BE5CA2F54955089F319E1B78D9D51F7C9BDEDB98C7F6EB4B651CF3266D7\n      49B2A618C41C0D5F8A3D700E2189C69405614A0FADFC74075BFDDE6C0B27C170\n      141B85010D15100DFF8E3DD0C43E126F3407F9F96A3AB1E4B41BC9267E3A33FF\n      A1BE7BFECEB628C8CBA853899B4D61E91315DABD9AA5C151ACF3D52113B8DB04\n      B1C774653CEA74F3BAA8CAEA781ABD73FDD8BBB3E159CD164DFE922C9F34FB97\n      775047FEFEF1CA07FA6B0F17B6972F2090DA4454F0CA7B69227856DB3E00C288\n      0683713CFDDCCB14C6D8C2D07E1D05A197C6B502DF59C5353483C513D65635CA\n      BC45C2F02B4DF9A9C9F5D1B1AD0F4E876FDC277707D3CBC3B5CFBD7C0D4EF54F\n      DC77CF60BE87332C9C95C5387C806A07255B754D51FA87A30937F7CB430417E6\n      906AE63BDC785EFC1605C703A10429D19C1C72391E2513B142E2734F1BC700B1\n      1A25D046DD0AB5E08AE47CA580CAE4F0EE228B7FBF247F7067FBA134FE17674F\n      3F9C370C120DC11D215C1073DEFDDBA75E22699C0128C6862BF3DBCCAE15B7A2\n      2498C1E32B64472E892D8AA55E3D23300E3C0B3B6A799D28CDAFD148870819A1\n      568598B10FDED77FD759B7738BCE8B8A49130DE855259E9BB0DB730558218583\n      AE3B4D048F165012DAC122811F196F50237184F30CBBD6107685586CB1DE70C8\n      1240FA8C485BB9D2463A59E97191D43726310E7BEE0000D50849444154F3676F\n      91CB457AE848A5555D63970E7DDC50F2C5B315AD0B0275FEE2C0B9952856264A\n      01CFC441F5091FCB76623EBB77654F887BD3D561513EF4138F1FFF473FAC362C\n      6D9476494A7B91C15A1E1798E098E808E11ADAD46B87024F2887119580146AD3\n      A195507667A77EE6FC70924F74B9FAFE37371B19BC18A8C8B550D38E5B5974D8\n      B7B60F77AE241F7930193E7466EDF7A85BFC5AD05DF0DB75CE0612AF17B674F0\n      DD6EEC0E56563BDDA1F3263EF0F4E11E22EAA96B948E4F8468C8E25B2F16DF3C\n      BFDE5F9D548B6CB7D69495A858C5B1EFC74806C193D16954DFB6D39593AB1B3F\n      F048B311EBBD9B6931A35D385625CA6B00789AC8E6FCFCCAD3DBDB37CABA8C5D\n      25A064383D5CEB619B538529170B333C6FE91E14C348207C0457DBD6E4C54F69\n      FC2279685B058634F54CD15638C627426F04D56EB9B51E182E5813799B82D7E4\n      BF23DA286DB3ED32117A7CD74AB7F8141B7955E2A0E71236837CEF912C13A10B\n      E6EF98C4B437398253D018BFB98A4A26F000725B4D8422137D5C0DF7FB9D2FD0\n      DD2C631F60D9AA6D76A22A8E64C7C2ED5B6E71B0561DC3CF39FC7E290E3AA877\n      60B6350AC6BBD0BD6BD06D96C40615A63D9B9BA39E5851BBBCDE53A268CC5470\n      C5791FA9CE761B9D7798C8B539B6FA872F3FFD031B277FB1D922D90E4EAB13C9\n      6228D82DAEA1405C46653DFF997ABA1DFC5F09052EEA0E422D0FFF1F0E8C410E\n      6F55C32944B54DB8509ACAD26E1B9C3947B911D84DA55361A704C5E5B08CC090\n      1E617642D7D6CE41D69B25E499C39B5FBFFECA367CB8121F9308EB608436AE7D\n      017058F1F66A81041C8225281CCEAA99C29FDC93900F6D8E7EFCCC7D6F487B3A\n      394CA02C2AEB0E6150A71B8D7E5758AF71BFFB8046EA1450882F5EE852BF6969\n      6CE3394741882BC832784DD4D62D20CC5C9D1F000786109E52FF27478930F405\n      E00BE0097388E8282420268E41229C52F76F0EF60E28FD85B5ADF572DA1174D5\n      8A75C37B38CBA8BD7A24B3E869059FA00FD847E7AB55AAB33C8A83D97A9B20FD\n      86D53CC3F4366C18AD4CE1F1793267CDB4DE8DF84538698DEEB0E4DF1EBE7C79\n      515FE6A491185C383A663410150BE4CA639605209C68F87C9B4C20199E22B9CA\n      ACA6EC5D67CF3EBEB299E6667F517E73FBEA3767D3BD94FC304D3F76E6FEFB1B\n      B73A2F363A9DCAD8FD544F325DD753D1D449D419C8F1B8E94769EE1D331D2024\n      E59A9A1B920AD9CBD03742E395811BAA707B41453A94BC36AB5D54D99DD84D29\n      397900D157FCFB68E77376FB13BD87DEB513DD968BE355F674663F79E78537AF\n      AC7D3C3ED6AFE7C5C0A179708DD47100E6915170B0258B20F37A3A2FF71D2314\n      E8C2F2CDD908E932F8E95609EFA0A6846B228B8A0916D7BC20792BB80284261A\n      A91235CA49A5E8DBE2CA08B20A1998DC4587079388FCBFC3F13F7DE185F588FC\n      C6F1E31F21296406ECB1C27BC2E48506CF02571C71894276E2E0EF45B9BFCE1E\n      1A62E70FB59831C2504E5FBFBF453D45DCB372B92799F90507896B8A1C921649\n      A5B22A8BE00D36E509B7FAB3EF736951EDDE4950953F66363B7CF62EBD38EDA3\n      C82B24330555791CFA44D46F61A1698C2052E8500F44DE429DF24E922EDE304A\n      D0FD04623AD549331545D4CBFAFD15FBCADECEB75E51AF2C7A5502E19C1625F1\n      7EAB2C68EA7992605B20064783B661A2B1C4A07E95579B18C2713FFDFAE4EE8B\n      F57C1877B7986846EA2DBFF113673EFAC6064E22EDEA9AC42C463C666B3F1C65\n      E8948D580499A21A1BCC96370D442678CC0D6F583EAF9EBDD89FD4FB93EDD17B\n      1F51C7BA70EFE043A8459D77C8709ED12F9C9FBB3CFBC89B48E7CCB9D5FF8ABA\n      FCD7C31E4DF87CC333E058982BF8353F9CCF0F176BC74ED49D0E8AB723D5D120\n      BF09C31560362CA94461A75FFA96BA74BB2F533A856A002B522A315AFB5E1C80\n      185641DD24E1BBEDADBFE95EFEA1C7695490C97EB9D89B93B9EBC19F2783E95A\n      F1A5BD57BE74A3CA23F81E3D196FF0EE104A180DB1D404976DEA428666A1DCB6\n      81F5182CC47C3B0A9F1AB2FFBD3C6EBB334BC2F10A9C6E836A0B58267ADF6ADB\n      66CBA0DCD096036146F8AA2AFD913EF5F727426FFDEEF520DA0143BBA8704471\n      B6ADE17548842CCCACFC81C0260B04CC5AE95A7B36A9374134B83433D74D6E15\n      2F4997F75F89CCF924BF6FD87F736EA929A7239E51D9ABE8226DB78B6CF850DA\n      2B12945B7C4FD4AF1EE631873B11F9001C2CA5705910C9081C805755ABFAB030\n      45755744D80BA6A2F026E2095C2A2DA6B1BC3A4EBE7EF5A547462B3F928E4FEF\n      2EF42636FED0823512A80E061523C0411AD0330F89107E08F68A2CC93493161E\n      BEA974A31B25FC229D82B3A0192D9DC8EDAE26155A01C0B7B2398EE87458B180\n      80754757B7EB6A56AB54745C96BD5CE6FBA6B9A6F2AB655D08AF26812221B829\n      814E1E0CFF267CB009520E281AD38B44A906106AA48BE3827FE0C4E823674FBC\n      7D6DB865959A1CDCEC76120235257A1BF130266568B7EDA51A91C11BC6AA8C2D\n      0F40A890C23CE6E8F7A8D7C3A29ECE19B0E0F279FBCD9D76699284756C6C961A\n      BFB219FEC45B31FBAD4D5741BD121D187757BB99A0FFE76276ADC87F79EBD426\n      2442C9570CDFB412471098365124CEE15E9747848CB42A7DBCB52FF7FBDFDC04\n      29145CB7C22612CE2E394ED0216A4BEC77519DC3A79A4038AF6A53D6C6739DDD\n      15086565F9ED79FEED9DD995461D125946BE9C7080DD6D02818799D2D77C0C75\n      B589178ED00964A3946F657D28E46E4D674ADB33DDCE13A7EF7D37AF47B9491B\n      51487947B86BD5749A4FEFEB74DF49BB6B853AB4C5AC930236CB78CDB1272D3A\n      592C18550CC9455196701C59F050DEF9154CEFFB60510B3E4662B59D464C156A\n      3C816C2C2EAFB0CFEF5F3BD6193DC0C7AB73339C2CE6ABE917E3EAE93BDB1F1C\n      9E7EAB621D5E1419C031915A89E81F5EB8941EA938DC11E7705421AC3628DAEC\n      19D69ED18697096A821867B2B691486E664E497FEDA11661D870C7BDAC8A1A99\n      CB1AA02D29B96EA4EA885CC6102F89FECAC6EA6FBEF8FCA151BFBCD2FB07FD2D\n      5BC307C720E30994D9B3917767C1E21D13A124A88416F43D48B095C7E447DBE6\n      7A6BC6EB230F6BB56F02B91481ACF60D42E47760CC463129DA8DE1AF0EA2A834\n      65F1BEF1C6136F2A673BAC2A2504B59A95B7F3E2E2A1DCD5A94C4B3FB7072C83\n      362EF8697B53282CA951AD1FBE1F5E2E2820229A42C21BF4176324BAA2888CA8\n      CA4CB9612CE34CDD2916DFB9C52E2F3A33462A5AD5DA55393E35B47D753C489B\n      FB2599A02879C43CAC98812B10E34A111ABE01244AE2F426774FCE760F953AD6\n      EB29BED87CCFFDEFFC871F33231A451D8385AEC00CA82B1B71FF7004EE792029\n      1FD28CF64D6EA48FA06821AB5DB5502FBCDCD3517EE30A7FEC0CB9771DAE615C\n      A1BB62D113FDA9B47FFA5C93BAF8236FA4C9A933AB8808FF21D640985A7D8389\n      856E9F69F7360D39B8BB2B21696F9D88B98869D023B7705E2153E2BA3FD27EA8\n      DD3DB8F5F96FACECC2839064D1E8BAA9A1AC88645CE3A7A0532862C980A18BD9\n      353DE93F72EFE8FD0F92012D6753471B281507159B3F7D78F153D7DD7599D804\n      C0FDC6A017352832817E3CA1B208D968F9DF9EEFE8ABECB08DE0438FF0C4644C\n      844B213EEADB10583D04AC07674CA082ACE76579AB9557DBEFAF4984AFDFA77F\n      AD6FD9EB1221BA2AB636667EA1A14D8421E0792C688F565EDAA8EA25D68817D5\n      6C2AF8A0B45759E3149553A8E6C22C6A593A97742EA6F67BF3EDFBC7AB8F44A9\n      6CE62A732C4DA28A243C2A22E3BDA358AB0447C3010E4B482E7C20F01A6A81C4\n      712F15851C1F1CE13516DDC01D2B20F22257A981C03DE5128731942C989E489B\n      55747D1A4F8FADFDC1C17953D5FFEDA9474EDDBA3BDF3402DB8CE82F48E1E062\n      31CB792CFD0AA32F3748D8B344ED2F013705872880B634F225B5B79DA350D3F0\n      32376E4E628544DF0557070C7E3A003F8BD45BC78B4635FDCE15575D54F92DAB\n      F71AB5ABEBEB10B371E88CF82A82176168E0E0E098D11B56591F40529DE02022\n      C6B127557A859077AD0D7FECE489F7AEAE9D709A56D3C62DA0FA3E9443F87B02\n      BF0A15EFB0B413411ABBA50C7B6A212EB591EFFB67590DB516015E672F622DB5\n      22C8E685EE285DB649BD0B4830206A394AEDE693C2E13547AD29A20C3F506E87\n      B01975FF9EA8E7EFDCFDCF4E9C39D62CBA115FB172D3F214E9864864C0B99540\n      F3092F62E31304F352094BD34C4F72B1C2B7CDB52FD19CD19132712C1B8ACF02\n      FB72947B2959486F319F2B0BE508BCB6B2E432AB5874A56C9E2A8B2F15B3A7AA\n      F2D0F399626420924A12953A31E75A373C42A93F784B4822ACFD5B272615E4BD\n      5BC73F3AD87A78066972FF90D38B8DB9A2CCF5C55452F7B6D58DC775726FC353\n      ED0A4085B1B252CB0207FC040E512621BA2682A752A00F4BCA28B2AFA0B2878A\n      0AA20944383F6AC7E6AFCD51EACAA287007AF92202CAB5FDFAEC56B6BAFADEBD\n      CE6192AFA02A5BF619973F77B0FBF32B671E6DF4A457E55D3E2E50FDA64E718A\n      867BD92D39C07A3F60949EF4DA2ED405E636A1B9C02107DAB221FBCE716FE7DD\n      204F9BA3B6828D14E773E100A456F0186D255599353229B3A83673A2BE33EAFD\n      CB6B2F7F7D3AFFF1D5EC9FF536D0E99321990DF75CD1FF132295E77E72128544\n      E8F53D6890E20DC4191666343EDEBD6665CBB72342B9ED13211A5CE2D5C64418\n      C90642780AE013B786A0D653BFF4C058A4F9DE5E8466D9C21C54B397EEC8031C\n      EE1BC0F93E3071286AD0BC190F3E2240F82E5E68209851E7529B61223786D1A8\n      C77813A55C79A77539EEC02751DE994F5EDA56AF4C87739914B45E14566B836A\n      8FC13706091C4883403E4470BDB22D838D901C252C5CD260D8D4110ED70178AB\n      B4734117DFDDB92D07C96090A6C3E82D3FFF039B3FF636F8080C9778315160C6\n      2A6483C0F94397037405C199AD42EC09771F0D4C94A675554CCA172FAFA7E3E6\n      C695C5A96EF6C8598875B2D48A36E54074F7B9FDFC8BBA43E4871F649D73A7D7\n      FE15B58B5FC519815746245EB0CE0FD234E22528978550557DFBEAF5F563F7F2\n      0C9108C1D3CB9944892C8122618DC3C74BD5D53BF3CF7F532C4862B9A95489BA\n      C102003B5C41F84C21644686902ED4BF15C066F1C4F1D187DFCAE22E5F14E4E6\n      76F59DCB2FFDC585E2AE8C8AEED824C764222C6484466448CD6BA9FFF6481490\n      861E9409857658DBF2A0087F5FA31A1C69A5DA5B5F80E0FBE519C9A889CF515D\n      C20B96BBA382BFC54C7F6322FCDB10A10771AC455C614AB71462234BD99610FA\n      48D828F7E890057D19F8F1B542AB4BEB8D6120E9533683BCBFB07069A7DDE4D3\n      D1EE84373FD93D76EFB45AA4753D84AA5610C35D1C794A41B83474E98AD18A46\n      9157CD633CB8B181EEBD24FB1AC8BE36AFF542B979856D4BC8958A27A42C72C8\n      15D2C454F41B14A5FC4ABE7D7B32FD95071F7DD3EDFDD5541F0E7133053F3A09\n      D52236949CD721F4A8B41D5C845D8904DE0B8AB4357E49C25BCBC3235C34B676\n      0AE35C8CEB780D849772C1EB1BB19D4AA4FDC435C1BD906EE7AE30BB9D7892C9\n      EB6571ABC8EF94EAEEEE94D42A32104190C2E55D74BD0D50AB51133A9558B343\n      CD094960E4C85B57C587CE1CFBC1F5F5B342A606B22EB611501B1C4E828CD137\n      C933CFBCE828BA4538E659C25E62240C9BC3097B9DA6C291BA5568857A181A05\n      2C18EEB89F61BB80056DE8B02F1F876B9BE8ED8E67B09CAC9C57DF2307B53B8C\n      E4A1359F4DA36FBC7CE9578E9D3945EA8CD3B193EB9AA510A8A4225E781B9E3F\n      AE1BF1E05FE637C2596BBEE31FB16F8D6322C4E083343F47320C1B5018421D03\n      39009945689989CD4DDCDC88450C8FA93F2191C1C265C6CC5ECAEE507265D1BC\n      30597C6B3A7F56D9190A6E65DC04D8924319864D2DAC45925A09A88DE150467A\n      F2C65EE76DAB6BDDD9E290B22BD5FC465DF7087DCB60ED07871B6F8832C8F857\n      BB7A5B2D36E7F50326EA4538BFA0ADE02E7C38904A791247543293380E5540C2\n      7DFAB37EA30D578394F0761D4880830F9A5645D387D33AD72A8E5F2A0EE0A3B8\n      7F914CBA265DD47D9B5CEAA57F56EEF7A97C7B946CB086448D6011ABA188EB29\n      5A4659E652513983C454AB63EAD7C19B0623B85F7884427992623718FE95A886\n      6FA194AB24AD13F4978C0D85AAC00951C0E5A10D12F61524F7455653A1FA5021\n      34AEBC9EC5BF7FB0FFBFDEBCFDC438F9DDFEC6262602F862FC2825AADD605333\n      C2BD42DC2241B0CA7D59D36E7239DF0927CB3E965B0A82D3302844ED4F0F0B01\n      B6281A429FEFEC73B89B3879B5DE3F6F706EADFCE913F26E450F00D2A3DE81B9\n      3D27D726684A49598DD70ED504D00A3B6DBCC208FC2B2011E27E37E38A68006D\n      741427C786740808DF257D3B55B918A49DF1106EA07A79AFB8B447F78C992A5A\n      43395593AA02FC5C7B4F39E705CAF175FA415510930EFF84905AA1E831DA3721\n      0EC5EE34065626D2B98C9FDEBF7D9B55D920DE88B3F587870FFEDAC7E233EB35\n      0E7BD1AED54956E32500788DE44E87D31FDC95C2D212F29855DC2AED6A532D26\n      CF5FDC1CAC56776F1D74F4EA130FE0FE918612B4AA07BCB34DEACF3E2BC619FF\n      D003B473F6F4EAEF509BFF2A6DB3A0F0726EE8F5E3F1850BDEA410E2A707077A\n      B7199CD8602BC3C6D31D8DF6F610283C675453E26A94E3B3F3978B2F7C378E13\n      A4DBEEE6B22116AB5117552EB6144E9E662E81524BD9EDB45A7FECC164F34C7D\n      FEC6B5275F20FB2524C7FD837ABDB7B6493BE9BC461A509695F0AE747364A017\n      E28B8F46EDDAF2D13FC40FFEA01EF10D38EAC872A4876C6076B4630E1F7714E1\n      414759314402AFEE7D2F91955F3BF349EDF55AA3DF3F23F48B9D505771ED5169\n      7078380A9A2C986A06024588959ED7E04D18B1FA6A2A43BC43212E12FB316645\n      C8B4A8925208175F94EACF8B6B8F3C78EFBB4D32DE3DB05D32E53AE2B1C87A73\n      DCA72461684482880C5DAA61B4134F0FEAF1A91F6110D4FAB55EE6A9C89B49DE\n      E41AE5E6D14191F30AF74BEA192F4A5D8F9BC474865F96F5F307B7FEFEDA43EF\n      9B42C17B408E475DD51431EE6CA0B13B3C7ED4A563B8A3E096EE546DD6402A1C\n      14804DADB47799640A0A666D66B5AEF1866899D4B809C7EB4617D41C46A62448\n      FB4A0C42F55DA65EAAE72F94B3EBCAEC560E8A7D9C8C5B21E1CC7BFE3D96EC48\n      DE0C3B44E831815A63B84C6F377BEAD478E5CD9B9B0F76E4C39DF834C45280DB\n      90F6051A0DC22DC964178917AEF495BEB764A7A1E6C7E692F6BD77E602C2420D\n      DFEF2B838E7A3A6DABDCBF691150A07FCA3634DA977B23ED84C74342CF37095B\n      2B7E03070A568D89106A1F881EFB8D5E24D9BE525F5EE97FF1FC0B7F77FDF819\n      0631DE8E69BA56932CF2785978114224B012AFE4ED97593DD73E5402A82BEFC3\n      A55F27655E5D1DAE35AE3B019A49F0455B9CD34AA6F1F4E28C1CEDF45864E115\n      78B53FC80050407234087480190F187B36E19F2FE75FBE73706507C0839801EE\n      833750E529407314D406A01A1B2413E9140DE36A380F9A3BC5E28ED66F5D5B7B\n      EBEAF81C8DD74B9ECF8BE7E9FC6BEAF638133F1E6F3D5AA770182BA1BD203091\n      0645DA7168CE303742ED9C243CEDC7492741253AEB203342E6A839FA16650A7B\n      3A53D774B448769B8A91C384478A7673CBB00F6516919334824B74A513FDDBFD\n      971FDC3AF6230B37AAA7DB1BB123A3E3793717539675F868483A5D25301320FD\n      A56AA03053BAD24E55706834E0867CA079D72019B3469E305AAEE1B492E2B81D\n      707902084FD3A2835347A79A48CDB21A8EC0B0E61DADF205257FA4CDBFBCFAF2\n      BA8CFE9BCDE3F7A1A2869194C7B87C4C390E899567A210D989098E1ED1708C7B\n      B1EF769DD9AFF25B6FD2DA76EABD8F222E7FF9000289D47A355FBF558F8D5E78\n      E6704771F207956D4F9C7CEF9BE60F1A77F1B05B4A42D2E9AD6973FD605C0A53\n      9635C3D601E60E4FA96E6413A1E134767D39F2A29882B221D2AC27D3B58EEC62\n      7EA5521C64FB71AF9FAD6D925C972F1FD8CB87EC76214B5617355A68E13A68CD\n      3494B4998728C4338F5CCB93704BF9E665696830FE604190F99DC826F0A46A22\n      93EE75D27CF3F0BA4AC53DBDD5C1489FFCB1371DFFF80FE72995B58B503711C3\n      6E6C704FAB1680044D178D493591B501FC867697B53155ECECE485F3C34EAFDC\n      DF9DD062E3F1071BD324510C8FB7E9D3F4AE9DFE87A77A6757E987EE67C9C953\n      E37F4DDDE2D77D6B94075D628FB8C2C81DCDDC1D2457C48572FFCA4D4052FDB5\n      75DB43AB79EEB868AC10118E663C2DD7D906C24AF3B96FDFB87C65D01D74F69B\n      74A61770A252692BF44D44550D47124592345B545505B1124ED2023E40A9145F\n      CC67A34E36603C417D2F48CA710DE7C3E854E393F6F440D2EE34B8657C5A4A96\n      B4C242709DE1D56AD4AD087FBEF440F02C1AF4DA846A42C8280A1BF14789F0D5\n      6C478297F4AB88F0A884A121E8BCC609D3D3515B916EBB147A78ADE7ADF79A6E\n      95C6FCF29C3F1C3E6861A8C5ED718BF81551360A8FCDA028CC695290BBEBBDAF\n      347713C1DED619AD3565CA548A119A432AAA23891636F0CA43E317A36158E838\n      22B57A5160EAF5D69CAF652954AC1AF2130034C88290EE8A0AA7268AC1B9221A\n      0056C5E75111B16615103ECF9EEEF2CF5EBFF8EEF5939FA0FD938B995D753369\n      577852A1C9942F5139F15D0A1F7C83FF8BA7B9874F10E0070A4B3A38A16822E0\n      7205E704F539AD2B892D84984B36A328B5AD20CB7968AE8D96E8DD43AA2CBEC6\n      ED5FCD0FBE7AFBF681369C763DEED2087744B0F0D1415863C4E88A712B9ADC33\n      E83E72EAF4E9F5D5F5B819B26885D10103C00779A6D1AEF11BCA0C939AF59E93\n      02F2494396DDF096FC495EA30B8E4D271C0FE8C8B41A4E4B6985574F820F4861\n      2628B0C5A69727D16F86B4BA75C145DC92D64D072B38DCC5F02D399426D1D850\n      8342B6516C6AC8AE213342BE3CEE7DE5E24B9F18ACDE1BD14CF0918B5795CBD0\n      EC4273DCA9C70E3A920E395C25E480603A5F165E08BE030B6C39A5F65B6910CC\n      D0512845D122282AA1E8C04110D3B4A1B6C62939811264D69D6B00B73A4A1ADE\n      2D05A0431711D4C3226EC6D8556DBEB67DF31BD7F7BF085113A25783B01AEA20\n      D4FA85BADB6B547B3F7AA9554323E9687E92C73F79E2DC6627BD72B87D757F72\n      77B20040FBC6D1DA0F8F4FBC01ED399A45849359696DA268822448EBB508E093\n      44DA63C451C64376A264D031A8AB8B3E67223878F8F715F9205AD7BA404E108F\n      6A43F24662E595DE01E0A8F499229A89F84B237379FFF68F8BD11B6A351DCB3A\n      EE8C50A47556B388F6C7D1788BA48328EBC93806C822B18707255BA95C332B16\n      2B7B57F349D1103A8FC8C42FA5AE2BB1599148AB052D490FEAF36245C48B9441\n      D90A61C7948712B2291915B2C7544D8DFE94A1BF7EF5E598B3DFD93CFE0E1E7B\n      E082B36DC885F0968546DB73CE5D9CC5905615BADDA134301E211401F779432C\n      0D3178881C4168342C4D40CCF5BB287EB88D99113E35ED7A129E9ECE87FC7033\n      B9E7A7DE579457DC2BB3CC0D9AA9BAFDF29D61C1B31C2909B5C0B25978F163F8\n      B94CE2BA88F00281B8042C792D9DED8964BD17F523B4E163064E9B3A213A834D\n      B270E5C5DDFCD23EBD5B24B96325A2310751C4550A0EB470B24A1D2AB47A0283\n      379E0B1C8CD6EEA6E57311A7B9E7082A89CE56B6E2B86B10E10446141DF9D46C\n      FB5A7EB835DA3839A4FCDEF8A17FF4B3E40DEBD85546E418B9E0F1E695E8210A\n      752A4B94B2121D74E0B32A4929286E0DCECF5FEAAD8DCBE9FEEEFEDD636F7E48\n      0C93B2A9E09C547D96DD68A69FFE4EEFCC9801224C4F2322F464193F1941C12E\n      2C5EC9512264ACE5130094D665796BBF233AD1B1CD2285E748A02843DF704084\n      B867828156DB461ED6DB5F7FAAB9B6773C19D9DD392D75891AC3C2D4D8880EEB\n      A85013991A8E0DC695D2893B33335BE841C4B7241922918442196FD011026A44\n      2335F6C302080B2E252EA81F91B65F4A8F5A43D89DC680205A43795F23FB269E\n      97F0F4610C377CD190CC38BF724319792DF25BCAB81EC5BEA3AC46968A9DAF02\n      0512AC7C978E154B1AC551527DAD0810F5344E7F145810FF82CA13F55C2C6DF5\n      48082DA0E498A8341B7D25997FE5F0CA4737CEBC8FF68C9B95A9E93B9610B148\n      78051903EB45D5D218BDDB9A6B398947CA00CBB44D68AD01162901E95321AF78\n      3A2D2BB4C6E1CAB0C2C289A1906DE22A9AA64D5FA9EEDCDCD81AFED1F4D616EB\n      FC92DCBCCFE62ECB650661235E3811253ED9E1729EF3EA97CE8F5B58EB0DE637\n      E6ACF7DD6B0096D7CE401CCD0DADD13C4A0874EF2BA9C98999733D87EF509084\n      4426923347177134A5747F516E2F8A9766FB1748BDC3132B136CF1A84AD8398E\n      C61C041FB699251B7174B6979D4CE5D961F7782F594BA38463485D29C8B2198D\n      4640152E3963564097742F6517FC4E43BBA0B5F424AD8C15690B171E76B7E083\n      D3A21D65B8D73CEEA53B3639B288C3D984B7970C8B13AC1D0CB6041AFC13FCFA\n      50B96337D26F1E614B1F63BE424DD746D143CDF6AC9D3BF29595DE572EBDF4F1\n      C1EA1B244F391D5A395634839F91586FAC2E9C5F6126DCFA4A1E9F3E06CD2025\n      E7675B9E67C15A822B562754F9F70B5506F3423B70A0236F93A150BB02DF01D2\n      4590C98EE93FD64C2A443F39EA1C988E215D48EE31B91D41403DF8CC15F69D5B\n      93670BBD4D3D5D9F941038D193DA043C2D03405723951EEAD3E8BD24AFD505E9\n      F033ABDD277A5B6F67EBE9ACB9AD67139A6775F3A088FBD89CE110B933C73B50\n      E919EF72830E91D80F12DCF593D8F592058406C1526D98D685C46929602F7801\n      73A81E7395CC6AC5B81664B4D09358A28877054013F2A19B0BF6929B6FEBD9DB\n      BB1BF7CC9CEECA1B993E55D70B786F715F0CD7F9602D5ADD10FD610E395D8824\n      4D96C591EB4D2E43957A7331BBBEBD33992F266551E8F278B7FBA0CC56E6F39E\n      A479541689896D14B90847102E8F2AD334D994A61925B1AA3FE7F8DFBB7C5931\n      F15B5B273E14C5508D3A0F0A539C3222652646F061933426095AC718EE6301CE\n      0A39B6F8BCAD28A39E51EEAB9AA3452F4F54864A05CB82D8C20345EE5DC9287C\n      987D29B5ADF77B46BFF9F889F73F5EBCF05CB2606C81C4C462BFEC96346A0CD4\n      46004001D6FA620F47A061BE227061C4EFE6C7CC2514D2061BC94236754A3A1B\n      83EEDA801A57DD38585CDA73771B72A021054AE46DD7BE418BC7194B3B29B212\n      C593DD321106CC1A28CE47E8C58F9584D7D2535E1507AA3444BEDC90082AAA48\n      6C537571763865ECDC281E1D8BB28FBEE59E9F7E4F25D194071E3645610A82C2\n      A7B87163630887908C7985CA8511A441EC2346BB87872FBFB272FA58914FF66E\n      5C3FF6C07D626358B2461675DD67E9F51A1261F7F40A0344989D39BDFAAF2011\n      FEE360698E8507612DEE6A05ED423040262F4B213E1DBA690D35145D1DEB3446\n      D9165CD563D8BEF73AC202F04DCCF82B3B075F788A2F9A7E6734BFBA4D21E1C9\n      0480022B9134819D994AD5AA33ABA1845894CECD2B96D0EED9DEB05FE799059C\n      C00A86DE9E5092A262B9494958B56D9B7CBEFB1C98ED61E534284358AB9557B1\n      225E7C9DB2D60028980185C50BF8DA54E26E7D1BC8FE5A22FC6B43C1BFFE47AF\n      FD2758CAB48E15A1814683C3514B11A64B1E8E67107AFD0AE707F2D8826990F8\n      8F1B7068C38BCBB9259B697AE944F6A91BE737A3F467D74F1F6FEA9CE74D0A39\n      033DA195A48D37756875BDBC415700295884F87A85FBD4E8E32167A52B9C6EFC\n      2BCA674555A8B2310DEE8CC11DE295730B670B623B26C1157A539BB5E11FDFBC\n      3635F5C78F3DF89E99598FAB7C542F6893C901A51DEC9A11DF3A44668F0AA7DB\n      F37328F72B8DA820AA8CACB0AEAE6A07B9106DC22D479D03C917BAF213515403\n      2DA8172515722F8B5F16FC45A59EDBDFBF395F3468D080063A58E63BD2776435\n      9127620201E8649A9CEBA6F7F7FBC752D187720F47840A610E2E8023BBBD6B64\n      8373426416441495040DC06101F71CC96FDE121D2FBFE6DE91A37D2A2CCC5697\n      6B398CB4F356F832B3DC6D3EAA65DA412FB1EED50310FADE48666C3DB3973D02\n      12CEE4D2ED038F04471108EAF59AFDD4C4A28A4B899B32744FDBB9A55F1D77BE\n      7AE9FC27066BF748967236347255931812934784028765FE477A29F0568498F3\n      D09730618934F4E75B022FFC89F10EB2C4B59C263F7EB2B46DA2604F18DF72DC\n      443EDE62E18F8A75481FC4FE3D327C0996D870039111D06C5D54F9A717879F3F\n      38B870309BD6BE25E03D4EBC13950F14CE3F02ECA10BAA9A15621FDF587BECCC\n      162D178765F1BDC362DF9523CB1F8B57DFDDEF49052745278C772CEB29DAC19F\n      6B392AE802F26FB881E23826595475699CC854E2F27F01153555423B11CAC0C6\n      DAA2A9FDFA6392AB5C90AC89B0C34178B730E35A5F1EBA4F8983536EF491FD34\n      8BD4E5F5EAD8143EC34853DE70693A59B2B5959E3866FA7D970E948357045928\n      112C91F6BAEAA410BAF8BC714573A39E3D3DBF71FEEA4B9B8BE2BDB27F0E22B6\n      680EA37A8349091F14378D2D0198DA1A4AC6348573572EBE1625FFE0CA8D1D42\n      7F75EBC44FC01BA9D1130E8E652A444AA9B404C00CC44C190B786F802550FEC6\n      576BA8E4C24222C427699614ADF6D7D0F781A785620EF87DA02A411B94345646\n      77E3C8E2945D9DF8C9F74EDD42BC70A3C77AE5DE7C7A5830C5646170F105E788\n      14894886E15347BD16543080A2CA2253D4B058A4A34C0C925AEA0A52FD563F5D\n      EF4390D74F6FEF5FBDEBEE2E56349AED5954C28792B780BC87D28E9635D8DE95\n      0CCD95DBC5C79635B6C41264090A1109BA08F9A7C8F0D415CE5E238FF618D25F\n      888B92EC5A597C6731591FC98D01B7F78D1EFBFB3F46EEDF328D86C21D02009C\n      8026864861219D73AC34BDB20CDC7949EAC8F0A6A43777A6D7AFAFDE77B66AE6\n      BB172E6F9E39159D5C2D232B8BB2ECB2CECD66F2E967BA2747FC430FB0CE69DF\n      1AC544E889B39EB4DBFA1DD3D008F20D198A0C3BEE70E1AF9AE46A7FD14B0774\n      BCA2635A433589566C063D8450B39214513DB0A97EFAF2ED2F3D3D5E5D4F79BA\n      B8782782888BEC7CA24A0D07B782A24CC5B5E58D29E00C27245D637D74DF6D2A\n      2898516D194B7528EA5045CBDA842C9D5DDB1CD5328A1182B4171CA79908075B\n      9F2472A4C4E0372391EC6E83491EC9E46B4444EDB2C9F9B726C2EFFB9DD7FF43\n      79D855780D1C0C5FBA74F74420188838414494F80886D3E30629E1D823257E87\n      08124BDD0CA6E2CEB8FBC9F1EEF54B37FED9E69B1FB66C922E4AD9A4D81695E8\n      60EC85DAAC374B747E63D0F715BDC9106A1CA32F3CAA33FBDF81F2B073A0E7F0\n      DDBB9DBDC34931AF8C26389C83236870B00E1760EECC025343B2B520F930FD5C\n      74F0CD0B377EF9E4990FD2E1AA293A2984613D4F898953A4D1F0D6FA17D93018\n      78F1C6624046AA098A9D37156ECEC8490DA52FF2063029A0DF4C25E8044528B0\n      9C020484F690F0DF697218F36F4D76BFB17F704DDB290D54010D297DC5918723\n      760F130F0C460F9E585B4B5D8FF101611DA815AC8BF19EC005627EFDCB195F6C\n      F80219BE03EE823134E6A61152E5F1E3C5BBED47683690A7C8ABFA4CB4758D68\n      330459FA57F914A95FAD0397CF9490E0BCDEAEB4FAF1CD727961390B248117B7\n      AC7DC382B4C1D781FF7AC97562BCDE02EAF86122A487CA612274E46B2BDDAF5E\n      BAF089C1EA7D92C7111F6122640025486CBCDCA3B72DE0DEA419273B81F9EC5F\n      350F3A5B816D1818F04169014A755CA1D3B84881E618C2B38182674F4887486C\n      87721C2F11D71C4E086A224B884EC455119B47F0D1899E4A7A8A274591C76E3B\n      15D71AF3CCCDC9376ECE9EA99AEB90387116C4128D9B4BDE4235764984BD86DA\n      8EAC3DC6E8A64CF6CCE436779D84BCABB7F6D8E0944807BCD963C52C3634234C\n      7A9A311AFE681763A30EC5CAE105C5B1843C03F8A4834E9BBCE9B12283380E58\n      8A243A18CB63A882FA0BC59B1A176BC83471830D01D1ABAC528B3B43762915BB\n      DB8B3789C16955A7B4313CF12D5624A436823450718C877CBC46079B241DC964\n      8389015CA6193FCC3A3D2C3EA03088186498C255D3C3BDEF3DFD8DE7BFF7CCC9\n      6EE7D1EECA3D2656ECB083BB70063E370980A866B9167DF878E7D367D2CEAF5D\n      BBF55C597FFCF8E62FC53DD128DFD642C9978CF30E7A05A2BB5822211142E4B6\n      DAFB1CF3208FE4F97D21116A6F3CEB960BC3AD9E035289829E1A3A4360535370\n      8CCFA451A91B3D74B2FBE8B95BD75E39BE9F985931D9DE2FEB46D248029CB2DE\n      B58D6339CC713D05AD3F1228B520C4E3049A0168A5FD98AD404561452FEE6CAD\n      C2D9CB77B6F7F777F905E5AA4662C9C275513AA41093C636E86E6D7CAF5233E1\n      E0E207156FACD542B3E42886869E8AFF4F409149A22D941E155739F66679A220\n      8FB25CA0165D8F240B11FF5579A06273A217A51BC9B11F7DCBC64FBDA7664436\n      0808AC74650C6741473E2C615474357A7B426A153AD68ADCDE99DCBC31BEFF6C\n      A3ABFD17CE8F8F6DCAD36BB9307155173DDABBAD269FFA4EF7F8507CE87EDA39\n      736A156784FFB9BFC22111860DE2B0F9EBFD29311B78B562946B45A31EBA5FD2\n      FD85CCBAECE46A2109699AA4F198D11B9B43968E5117C42D9EBA7CEBC9EF6D74\n      D6E29D5ABF720899741F6074696809A084F2B81B8938123C852B54EBA482AC0A\n      A9BA5234AC5CDAC0F1F45ACD81FA618F3631D9724648BD80B55F1C861F6C349C\n      5F3F354649DFB0E44EBCA77B808FA81F2B5C8A23E265FBD010F23724C2A3FFF9\n      FF0F07DB19E1B2DA0933C276FF3AE0577CA95E55D417EA6183109BA9008C1B1C\n      ADFA148D9514F674ABA6DF642FAD26BFF6CA777FE6A1D3BF34198E99BE398482\n      C10ED1F23B815F22A40EC34DC685C9A0110CA7174E30863D2EE2248922094101\n      8D2CFCEC8B4EF494A88AB2C974612A2BA214992BA163675C434CC15DCEA12863\n      4397BD22E91FDE7CFEDDF7DDFB9143FA383CF7AC810A05EAD4A893D65081E149\n      F7F46E8E34193F0643EE3EA02F5D695DD906F542EBBA50C8FF14AC925C31EFE7\n      E248C920CA63918236AB5072215F86BD68F537B76F3D3B3B2808C037E11A2D89\n      3BD78DCFAC644F6CAD3EDAED6C19BD4A48876BA30E20AD0B99502E35D4EB688E\n      4BBD899585401163D0442036157E8BD41BCB41E4C25AC8F33E247AA842B8A7B5\n      C0408F625BED336DB360E00CFB44D92AC810126840F4A8926DE95101FF05FF2C\n      DFFAC678D28E044D0BD43D69A9AD9C303FE20F43512EE76784D62B5187B51F43\n      00AD03309E347657033A775F1FF5BEF6F2855F18ACDE1373C00D432BD73597B4\n      86F7E0B7EB22DF97C60C80AA3281F0853E7F84452C947FAFE6C2C09F420A2C35\n      7EB705A56882727CB0015912A4E1973A99A0D1B0498C67B3E35A090A43413431\n      1C0940B226A246E1926957F028AF84A22419BFA8A23F9DCCFE9FEBAF3C3F2B2A\n      05F806806342892C913EA8E035A4510AD0A334048EA575D57AA23FB679FC4362\n      C466F597263798A8CEAE8CD6D37EAC2C606588F5B8E0017F5F93C4B6429A2E82\n      B76F86C48EA3B8CB4429F56CC800420D2DCB289B5364436518BF690E154AD164\n      A5D12870CD860BEC52DC8D1B0D09B4E2579BF220B36FAAF8A99D66364A907805\n      4937A1283A69BD7B9A84D8D989D636A2D5E3ACBF267BBD54F6E1A3538089B3A8\n      E87029A2782FEFE4BA19C45F9B5FFFD437BE18BF70FB27D3732BC79A21ADE3A0\n      E44E00E29BBC76034B3B557129C97EE3DAEDCFCDA61F3C3EFEC7F16AC72CC96C\n      164030ED712171479324924712B280C5CACB433BEF13EE2572914D0317DC1E19\n      F09260C6EB2B38BF4CEDC99E38B3F67AFEA900901A9F181C7FFF3BD4AD2BF9EE\n      E1CA616FBEB75B2D161CA934D63B26F9FACD3B572F9B58B85B0D471C1BEDA920\n      DD840E923221DDF59118F5D5CEDEE2F68E3B585493594F8FFDAA2F54AB8DF5BA\n      7728F3857D05DF3953A8A92B2DA023BC9EF4882DE1C93247C2E1AD160AAE2524\n      31E0375DD70C1529053A9D09CD6C8919842400F3E3FE79662E37FB1B83787D10\n      650FAF9EFCC51FA267B638817A061018CAC74840A5D897F70BE20445BC1AECE5\n      A81460D9CEEEE4EEEDD5732721821CBE747EB0B5294F8E4BAEA3A62EBAB477D7\n      CC3EFD6CBAD5153FE411212442BBF84DE24D54BDAB74B84D183A9061C245C020\n      8048A880008B792A32ACDA9FD479150FBB62DC83FC9F600313FF120E0BE0034F\n      903A93156CF74F9E5A7CEBF2B84AF5DCCE6775D1C05F4ED3EEA03B1A6759E4B4\n      7205C1058C72A1ABB92108A9714F0799A20A8F06442DACE995D7E6B42DCC424D\n      E9D6F215C5595AB502828814A51143A7D16251858BA2DEEB2B50AD22387A9196\n      2C24424F8ED5AFC2BE2315D716DAFDED893074B8499802BE66DB6C99058FF4A6\n      9720D25B471316CCCC107F68622AEDFD9E50CA4A3500A8219DB969AFFB27BBB7\n      AEE507FFC9436F7DAC82C49DEFC4332145EA248E6FB085AF045E39283F334F16\n      65019E44328EA44C1274789BCF1615947F0A61F781A30BEA2EDDBA351AACD286\n      A27CAD8810E6C3CBC0EB65174C4F5D73BC16D737FA9FBF74F95477E547568F3F\n      A88A4D5AA1DE742F538E43851E31456353536FB74B8F1030626D2807EB5CD5B9\n      360DF16B4DF8ED55CC4A09D013D90F280DE28C927CA19087E03A83B98C2F4DF6\n      FEEC60F72AA078FC2CCC0A25EFE877DFBFBAF6C64E76B69F66992B515752E3A6\n      006432BF3FE764A404C25FA877B238064C887AFD7E60DA7254222F13A2BDCA02\n      3A177A0641F02EF373EF30C70CEE02410480B52A0AE1D91BC75AA16EC81CA969\n      456883C672FBB8492BECE7A7E6819BCB5ADCE7ECABF5D35259262442DCFAF75F\n      879A8806974FB5F1C343A8451A522936D56EB7B17342FE72A5F78DCB173E3E58\n      BD37E609244227D71A16C3A38A1A2F958B8252F05C7CACA4414EA1353EE6BE3B\n      C1486B70EE9DB910195B6C0B33AF9682AA8C1E17FAE549E721852727E2E76334\n      65C6F3F4830F1ED63D0EF00E9ABCC377AC711E484C26A3BA49B4829CA9A1B2E1\n      511365970F9BAFDCDAFFEADEE4DB4539432772806A73217DE18A9390C84BB5C2\n      C9252BCA9E6250FF42249D0F8578EF60782CC9E051723489739C2EBD857C0D4B\n      DB453F169B0AD7D73AF1BAA12308331D4A3A0C57D8182D248065C8DEE8AE0400\n      56E0FA32A1CAD10A4E0AA9399CBEB863535BEA8358EF9362B56427E66237C54C\n      83DD722FD60BAF34C648676BAEE6299BF6A25926DCB07B5F7D62DB9562DC1F0C\n      07755E0FC76BD9680C4109379E46FDBB567FE9CB5F7DE62FBFFDA1BE7D60909C\n      CE2447D5419C929710DCE7E54AAD763A83DFD939F83F76EE3CB8D5FDDDECC450\n      2FEB5E282EAD8344DE210EDE481AE1C536BE28334BF5ED50395311AA19D69E52\n      D662C2B053819C26CE94C08574811F195B48A74EF6C68FDF9BF5A2F98557C461\n      55DD895C91A32A402AF2BAE0B8AEE0D59871F51EBB65B833E15C2DFC228EE432\n      4B64377631DAF2C161ABE779B93FE585492D7A77933AF60E6A95F074756FFD83\n      A70CF10472569A0865CD8DB2B15DA2C0201F11C2A2DFAD0FBA762E24C2481B74\n      2922100750C90D7261050541AC25B54943144D279DCED3D52E4FCDB944C893F1\n      F0471F5FFFF03B759442A98BCBAC42450846AD67A7A213461D99DABF8C549B72\n      FB6E5D4C875B1B5635934B97BA1B6BF2C4B81696352526C25D527CEA19B9DEE1\n      3F741FC73DC27F4D4DFEDB5E4033481AB8B6951BB820CCCB325B549D6B62442E\n      AC6C382EF4DAE9FE819D95E3D1C80C1312730E35A101A08B0A590094F60D3630\n      0677E9E2D3DFBAFEE44B94A489C886D938EEAFD8B42369ACF2C36631270B4A6B\n      28D335BCEC0AAA0C745B605C359808E194C2214798AAB0DDE7FDBE79C8B85E7C\n      8F86598B57B4C217A4BD0B28A321110ADF4BF2F8D16BF1C0DFC59527890AA858\n      ADB0A37D03D20E19C96BC4641CF96B88F0D5D6286D57FB09F136739E14EF5763\n      896F94A16D39947010FD7100688C309E2D8BA7C00B8259245840E50A8020A611\n      04A71C8F96E9BAE89B43FEEF5EBEF8CB6BF73CDA1D46ACACA31CA29E44173D38\n      2191F23CCD184D614905E9C9AB04432CA59003B3512CBAD291453EB93CDBD9AF\n      EAA4A4663F7F6E85C5925F7C65FFC4E618AA75DE38299881148504362C37F74D\n      79D7568FC7EB9FA9772E6FEF7CFCF89B9EA8EC7A54AF8F38AD4B97C55512C36B\n      4F2DE2835C06617C78CEC63720E141D9C5BCAC2B1C077A1D4C09B8A582E21F6E\n      9F80FBD0488F7D91C512273E24C7B723F1AD7AF18D9D1BD7EB0602D0E97EFCE0\n      78F4D878F468B77B4EA913D8BD2D75ECCA9842918E90DBC093ECA26993ABA14E\n      8B0585C8C595F6EB0310CE78053714B0114764EAF564D14B4DA07A02EE1A5682\n      A0C82A32275D6C5092D070D6F29C96D58B6BDB352EC0C1F06BEC654D03392B34\n      775AD25E18F8DB9666EA2C6B51A37BCDE470A935DA8E89FD008FD9F06F408448\n      E6C55F1A5AE08CD0ED683BA7E4A995FE5F5C3CFF33AB5B6FE0BC4FE80A114328\n      B1F1FE41B823B8B426FC6607DECB96E5DA9A88211F86D160B0415B8B73F8BDC8\n      BF5F8E16CE98B871961F2469A983FC84E374CF0B9050AA7280ECDAE1437291D7\n      2420C1D9382C5522BBC7341CE0377281150AD96959159D057CFBE18C76BED1B8\n      3FD9B9FBECC1C1DEACB8248CF56AD6B1C5D5CF1A6D881185243A2A224932A871\n      9B1FDEBAFFE7936E329D10A56584510CD27D179DBC517617EB18E4F6601122A9\n      56A259703B6AE849137592C8640C509FE45054470C17FB88F2A82676D8674EE6\n      8E9555CEE0D645E9426626863C50D32AAAD1E4CB26196F6C858C66D489C4D765\n      B00F3C1002CEC95D51DFE9924B6A76A598FC48F6F09FDF7C295EEDBFFBF403E6\n      CADD8DB3C79B336333C8EE5939995611ED0EB77BE91F3FFFEDFD3FFAD420A9DF\n      7AF2F823F180E5E54C2A2D5C7F37EFE5F6CE60F4C9AAFA9F5FBE3458EDFC0FFD\n      CD1512553E0E51A4583619717D467A0034258EBB202F080465DE3BCD7715A937\n      660AEAF9AE65A407CD761A2494238DAAB00A89C4A8835699C66E7593B79CE9DF\n      7BFCC60B2FADCCB598A8728F5355B9A664128919A8F1A69173659968B041EABC\n      F01B2D622BA2085E8AC0A612624774922F6AD2286CA556DAD6808D9924C80742\n      357E9CFC1B6530BC311EE11E282E9922B78DD3CA9A8E0D5A83A1AD18B4968EDC\n      B9DBD6287AE8F8EA10C5B2D1C50E4545BC968D40FDBA0435A7984B7BCFDAC58E\n      999DED27FD4D91BDEDD4899FFFA81AF6ADC18A1E6D0DA4C5AD7483680DC0B362\n      46FB85AD4CE9C58D5BF074BB5BEBB6AE272F5DE8AC8EE233AB4D0478AB2ABBAC\n      BB43AACF7C978E63F9C1FB5876F6ECEAEF525BFC9360234A83E76CA870E9B2E1\n      E7CD36E0B72AAF5C213511F86E0CF694E74D71FD6E767C936EF6AD6EA026A955\n      91A0A22469A2D48A6E2A06CDCE62FBD98B90DE331ED9CAAA85650BC20B460F66\n      BC500EC20D8EBB954122057CE8DACB4141AC0F330C8678CE0F302B8184EFACB1\n      B1A68D40717081CA95A441B3379BA2704E6B0B1176DB83F8345E302F1484CC04\n      94044377B96004F1FD49CEAFEB1CFD63E8EB6684AFFB628FA8C27F95D8A5C341\n      119E2CE36738D8E667F0522B5DC71197B87B843A788D9FEFC575246A5A3A33E3\n      9A3B3380E7579A46A407851E93DE27D5CE53F5E17FB7FED0996A5166458E9D49\n      9A89D847A6069E36447C0C41061B8F7071BA0099E178273D32BC57EA8199EE5D\n      9FBEF4F5C5F55772F3C4FA63E24EF57977F38151B7DB983C67BDCEBA5CCC643D\n      2946F1AD4CCEA6E586EC7F6F7F7BFFD4CA908E6E7CF7A9F76E6EBC7D3C3EDED8\n      7547FBC831A9ABA8B289D78B870C47B24620DF1EA3254EE822A8070F67F9A268\n      2C8DBC2E4D84D1CC5B3D4089A76955F2AAF2DA580A5B989911F1BE105FDCBDF9\n      E78BD942D0B767E27DA3E49D83953792640BE79E8DE9D169A46A5C0FA1B185B8\n      29E0E2C1C52A85DF406ADB7D5EBC300C86E9EBE17CA85EC21AD6D16375E4E839\n      06EE0B6BE7CB4765CD72CDF3FBC6BFDABCE69BBCBA421AE6526D0D8568DC83AC\n      D0293E5AEE712DAB39CC84BCEBA467386116449868D06F16D55FA0AA996B7360\n      DC2DABA69CBE38E87EF1C2A50F1E3FFD084D4F16F506731131688787A28AD44B\n      0312D4BCF7DB8ED80F602D50F59342D420F52271EDB2A35F6B6E3C3EF4ABD334\n      D8DDB9402E7D55BA12AD709B76701EA8CE4B6D55B2AC125CAB11A9BC7490E716\n      79A468F14D50E49E5892D76A329DDDBAB3F37BA477653A3D682A1D447828AE30\n      F9212DF213191A95519976EEA1EA894EE7078E9F1C55B5CB6791B5DD28D6B546\n      1521F4D54618AD503645E3F1C25E35F6A9224878DC25CCA611ED24AC93465122\n      50E148D89CE791C50D103669E804CAD0B881B70609B1B4718D0DE45AB81A058A\n      E28AA3F0232E2E6232E02862297A33D9F9C66CF26CC2B6B3F8C9F3E7DF7DF2D8\n      E5ED3B80D73EF6E0A3D3AF7FEBFEAD113D9BCCF5C147DEF0C67B065B66752517\n      E9B0964F6FCFFFDD0B4F5EB8F0BDBF7BFCE407924C745853ECC71340269DDB83\n      E1974CF1BF3CFBC2C5EEDABF19CBCD349D555CD83446A9EC3266E5AA7323C018\n      718CDB51C4A4B84A25FC6784526E1001396EF932AF7E85AD3FAF2F0007C097D8\n      847A9585C42BA3028268163D3B78C77DF2FE53D32B77D89D8ADE29C9C208D5C0\n      078AACCCF679220FC527541E1E34F5EEC98DC4B2400AFCD9E895A691D91C5600\n      89D77DB528A809F55835430A4F9456655C9791C8702C8B74CD126D056C2A0C95\n      246F309F93D7901B5F433C0C3B8521A286993D6E12A23CB7BF307EAC88D409CF\n      871738FBBECBA2678B291B91335B697FCD9CFCB9F7CAC71EAEA14807E0076564\n      17FF725249C0088E5590074D54175199D6757EF9669C25C9A94D5B5493EFBDD4\n      1D66F2CC6A91B8B834E58067DBD4FCD98B554775FFCEC3343BFD86D1EF519BFF\n      76B0ED691533DACDE130893E4A84484C40F681F3A0CCE24B87BB309B2FDCDE7C\n      3818EAB574214C4743148CD02B944BE56827CA78D960F99A57646FAA6EED9903\n      CD6794CD0151160E8A8E52D952BB52DB0A89E40E92A806F05D63AB1CB5DB5072\n      092A506971A28BC430E4B5B9462007000A22F8E0342062C88E803EBC8B77DBA7\n      4209EAB68F859A2D0C65F359841E849AB56312475E0D916DA7CF1EF5B6FE0665\n      99575BDEE1AF8720CB116A0B13112B156781E40A6577DA0018C2D1E082B80A8A\n      4D7C37F06413284359EDA242418E309E671BE7D6E6769FF3EBE3E40F2EBF78EE\n      DCD95FEC6E6C4016E93645556CB06E862B9070924BC08F6869E9B7CB73F8C858\n      9C59E41F476BC749B671B83F7FEEC677A7E98C2B76EBFCC1DE70757A627CFCDA\n      4132720388447552C73DA7CA95AA6A62FE62A29F7FF9E65B374F7DE3D6F5E26D\n      F73517F78EE58B9F3B71F2616DD671C198D53135D241A52E71B28E9B4600B129\n      3AE36061C868543566BAA817798541CECFC9292AE2C3C9704553F7B2DEA2A976\n      45BD279A1E93E38923C9F04B2BE4FF9E5FBB7E65FE2E463FB07EFA6D1B831359\n      3470AC8776F056C13B8AA062084E1A28EF80E2BF0C4BE5C82EA72318CA311EB6\n      7B2C6D83BCDDEDA3AD66FFEBF94D4725CC5137DBBEBED74D8F0CE55FDFFFD6FA\n      756723440D7B44875AB2C02D5DA6DB57D3E951CDDB66464C9B7E35DA78400989\n      50A35D1EF2A7355D687B60C92DDDCC397D76D0F9C2C5CBEF1D6FBE2DE91FAB9A\n      35673AE83187EF4D60224495BC6036D9E63CB6EC5EF8EBCBC591351D0B128FB8\n      30E8039E5D922C96A651AF1AFCF89953CB7925CB9CFF7D55E0F2D79625145C97\n      E952F110D97254340E6A5A92E7F38B3BF1CB8BC5372777FFAACC6F52143B00CC\n      C934CB50D50E778610FB48D22DC9A988BDE7DCE9F777460F1690BAF6275C4D63\n      A2D1DA2081621895EF0D8D8D89B12EC6F38521125BB7689D0AC942C0C991ACD7\n      15FD5E14A791278F788E5609D705EA34D738C0B916B05252239B02305089EF15\n      134713D31A85A3EDD8C544C697CBC5454E2EAEA69FCF77A6DDF4A5EFDD88FBB4\n      5B0170A4E3F5F1F0E6DE1BB3A1B86F757B76F3BF7CF007EFDD2D16A7BBD1E9F1\n      A649E7E9E66133FBDFBEFE85AFBC78E1571EB8FFA76AD9AF9A9B99AA78BD4AE4\n      0DD3FF17CF5FFC8F9DF493BDEC3E99EA8264B20BB18A48C3F47CDDBA35C5BA91\n      549D08E24538C13680402F7042BD2FA0EF26047E3A824580EC0D3300CA1216D9\n      C266697A68F222B35B6F3E1B3F74AE994E762F5C1505277B75820EA1B85466FD\n      C48EB47B0BB49D8933BEB460E438945B122F5A15A4608668829A1EF52B4226D1\n      16596F99744A651A95D7E1862A5C02313E7DE16B155679BF067A746C8E944996\n      C302BB3C4EE150FA5915F2487D00F69EC75E1D85A36C3F630B265F6816B34E75\n      ACCF47AB2C7ECFB9933FFD7778327425711D5A9B69CA62D4E4C0E2B021DCE67A\n      1AA78CE7F9E1956BFDF1588C7AB6AC0F5EBAD81BF7E2532B8A6A80B9F980F777\n      B9FAECF3BA6BB28FBE9176CE9C59F95D6A8ADF0E3789045353D7068C3090A561\n      7129D48FC613FF999FA4585B426A61D1FCD2CD5EE9E253C75C2F820231AFFB3C\n      CA0065D746C591688A69842ACCDA2D2AB253C2E321DB8D9B38B750AED66A5EE8\n      1CA7DCAE8444086572E35483E67CC6BB7BC339864408251C324BB0048F50A4CB\n      55F8C173F40FC22F44471BA96C1D0CE6DB96175D864484FFD81D451B2C262083\n      06DB001294425F33D7F1068F2C04D3BF25111EFDB7BF7138039636F2581A37B4\n      DA63EC4F52701D34A8F28B4814CE3E942180E3B125C9711B1E7E7F91B29AD0DE\n      9C929D666F6DF8BFDBED9D9BB77FFBDC43C78A02CADAFDA466B18C4CA491E49D\n      D4A6F65ABD9C54485181EF01C0A9E1E230ED2427EF258D28A793BFBCF0CD67AE\n      5D7FD33DE774213F75F9FCE8E137FCECAC77536E67C6442ABBDBEDC0CF3FB350\n      506B7D355A3C73E3EE07B6CEFEC5CD6BDF3A26DF72CBFCECFD0FBCB328EE5DCC\n      56FB7296D04957B8244E09ED1B2C40518C42902E6ABC03F88D8A52EF1E2C146A\n      C1C4C1F61417E5B0290127D1242CBE924FEB41D7567655A687F9B418F7BEAD66\n      9FB9768BA6FC87368E7F24EEBDD9D135AFC4E3E05C260C2A1D05453A96FD4E3A\n      8EBBFF8C965058481CE267DA2FE7B1D63924E82484EE507BD9B025CEFEC681EE\n      D1D4E9D5FF6D96AC613C2C7EBA11B4D1BFEFEFFA4478245A17CC52E96BC0639B\n      830D79F565049D3FD752035CE005F808847B1328DA42C2F20FB64AD19E064200\n      2994DBB7F6B6515346BEDBCF3E7BF995C7A3F43DE3CD33CAAC39D2E72EE2FE06\n      722F16EF3D833C22F4077899085B3D21CC16CC97FC3468C1634B81B469AFDD70\n      0C6F8A073CC7DA9BC0DD522ACE4B4030FA7D8B43AD6D0AD664181983777A60D4\n      A16DA3FF08B48F999AD9C161B4B3585CD7E622215F3F38FCABFDC31B84C0F524\n      490A77813595431176007638441C33F24837FAA1CD13F776BA09E4C919CA5145\n      9E0F14A509BC0B9421246E4174893A5A0091596A448FA74C41FC04BCDB08897D\n      F734126B4937EEC4F8A00006354DA99B422B08D571C3658EE01B0020D4D0CEA8\n      055A60A37869C35CCD5DC6D2BDBCFCFCF695ECF1879FBC72F3CEFED4A5E43B82\n      ACCD494E08E4E69447DDD2D503D9A1E6BF7EECFDFF1F65EF016E4976D7079E50\n      A7E24DEFBED82FBFEE9E0E93734B23314A4848489665839025BC800DF8C36093\n      6CF8583E63AF65EF7A31BBC6BB66C1EB4F1804B2C064590109C18C66A491349A\n      9ED43D339D737AF1E6CA27ECF99FAABAEFF54832DE9ED64CF753F77DF756D5F9\n      C75F70BEFE125B73EF78E31D075285FD5535812E8BF0AFCE5CFBD217BEF61D53\n      93EF5C5C0EF281AD767C2E76F2F93F8E9D8FEE5CFC6994BD6B7E3F1DE6FAEC86\n      226160B5AE5B40D994FA9CD9A84E958D7D18B281EF2354BBA69227C62C9D1B6D\n      59B3ED0686BDB93D9C037898921C1423BB76EEDFB5D8BEF7A05ABFD53B778D87\n      C065F391A7C21CBAC50A4551FA821598FA22174228010A8EA0266A953E9AAA10\n      1531961112B40E8CB78FFE6F002FCC07B64E87E087D5C6BA01C8817501E671D2\n      CC83604C31C6CCEF1DA8A05DF8D8B74D84D5DB944591665916F85229EB1AE167\n      51BF51C7AB539E58F356FFEE7B9C3B0FC561E6D9BA504ECD68066CCA41BDDF41\n      B11882AA7AAF97F7FADEF414D6212A4EB6CF9E6F4DB69CF9A62E4064C6874DDA\n      DAA1F9674FE62C0FDE77176E1D9C9FF92816A39F33A824AB82CF1564B862AA53\n      E0B00DF0DB4051300517010E990AD2BE4C858702F1F55383B3D71AF71DA6772F\n      64EEACCAE03348C1CB7D0E4E2C9C5B3A6FF533BC1EF19B111A70D417BA734F07\n      311F266A94A92827FA894F7595C641CB869BF123189F42B1E1E6B880676220FE\n      C27C4387030768B4C6E829930CD666A4223F96456D9108C1FE557F3C87621B14\n      AA709527D51E7788F1808D54AC0B89D1EB63EA9EEA98943E22BA2BAD0B2A329D\n      8A694615D05A2C30346189024F20FD196C007B739AA40CB6569E502C964A87BC\n      3EB36EA691AE56518FBBCEC456B3F97FBEF6D5F7B4DBFFACB968A5A1FE6C231A\n      DB9683329C077EE4EBD7948100515ADDFA47CC5E17743E8BD33AA3870E73D5C0\n      03FEE26B2F929AFBD2B98B97E2D89A69E2EEF0D1C6BE033DE76263DB57C2E6FE\n      49875C8EBBC7F2A065D77EB37F6EC3B7DFD25CFAF285F32FFBF9CFD86B8FED9B\n      59D9BE75A78B3C5BE9939FD47D7DFC5C7DCC416B4F573C28B2A49FE82C680D63\n      BEBD3314C262D4D3F91F58DE667DCB29B8C6E9277AA493613DD84EE32677DC91\n      1AB482FF1A5F7C29E9DEAD9CBFD7DE7FACD16462C8541C301BAEB76B0997C658\n      874604E667B9F074A520A109024B4B38A2B0A647B864F855ADCC9E7D5CD51192\n      3136E95B105D76EF66D511AAF174B4EADBF0DE3FAD8A22BAE44198954D4594BF\n      4DD848EC6641AC4A838AA20A46722C32AB000B62BCFEA070330027182942D843\n      11471D216F88ACAF3BC256FDB367CFEFCFF9772EAC1C10640EA91606BA08683E\n      5160CBE8FC67442BCB44583CED66D2656A40662891300529D9A5A4C85AC56722\n      06EB5BB994140D46C536AAEA80B1DB22AE6CA7F0F892C2340E190350838C9000\n      1297C6621315DE5FD8E0FC75DB17EBFCCB47288A50475A2786F133C3DE57A3FE\n      39CE238048C0F2D6533A35C2E7D2DD5FCE65C3C50F4C4EBED99F79C06AB413CE\n      B87EEE13CB1239069D2249C00D63C4745F07BC5196F31AD267296328D7E79B1B\n      B9419D206791E5347C5F3F583A3EA31CD48EF5FBCC94359256A4AF044B75F10C\n      FE5CC9B6A71F66359992EDBAF59A1327A3F4E8E4E289B3A7A766E6F7295FFFE5\n      9D00BFAA0683EEF0E2707895CA6B9C6F263235B21CC79656D0952B0FCE4D3CFE\n      E091AD5B57FFCEEC01B9D2267EAD96D59EB87CF56327BFDA24F2EFEF5B3E38E8\n      D6148A79F00D12FCE2F50B87D3C10FDCF3E8C4B6AEFA790CC2D0C4D3B194E775\n      A2F467A701E09A9A298C8263D01B377672A41009623AECF2D2ED0460FD208366\n      9E275D7638B61BEB4E6D3668DDB31AF370FD9533B39CE158DF0796A5FA6C3158\n      D0CB021D553DDA65F6294155D880C0799E9ADF902A5719380E4246F1439582B0\n      4AD960C09D752DBE59F35F3875FE81A5A549530253EE80C00B8E4182567AC6B6\n      A432DED99DB2A162BF2EF726421871412244452294630113332485E8825D65C5\n      9EF34C7C2B74C5D1767DBAC58277DDED7DCF9B534F87970CAC7D758C55CC824C\n      10C3AE8C29958DC2CD4D3B93EEEC2CB0D1E3B87BEADCD4CCB4BDAF99EACFA09B\n      B23AAA7728F9CC2B61D6F7DF772F99BB7B7ADF2FE944F8B304E4755881D442C5\n      9E1D97C101179614E0D908C90D14A54055C6BC75451DECC7CF5D1C7EFAD9E1C5\n      75B47FDFD4FBDFD478E02E204D25FA0D31E0C7329520D096D189D4CD11D5A5D9\n      5698F622B2C5695FEA442806311EE6729822DD142619E09973D00B85F25200EE\n      5C5F28079C3B61D403AB49093206F0807070AE930632030237945618CDE27E83\n      182794EC046239F5984E84AF134EAB340EF03835EE2E486E0F8CAFEB36CA8936\n      AC7E192D67AA30E8CC2CC8DE4C1F6CFDF0A632D3EFAD16C4163E4FDC758537C2\n      E18D9DCE4647277FF08071758510E90CCA3618EE31E75667F8C0FCEC23ED89FD\n      8D5AC3162D8A6712B42FD3C950B7FF1185C42A90AD7ABE3C2DF11F5DECBF6F7E\n      6A61AE3D39B7BF99D587D7B7FEF81B4F9F917CF5FE473FF7FC57EB53CEDB9B53\n      0774C19137AFB6BB2EDCB1DA536AF4CA60E37DCDE529ABF9AB374F86FB670F84\n      ECFCF5AB9DFD339FCC171BAE6A8BD1B4CD61536E21C9806B5298EE21CBCE2D16\n      29E4C779371C0E923C17D49236538EE24A609A5A48B7AB393CCFB0E5BD6A5BAD\n      8CD642B9CDE8A5BAF3DCF5AB28936F5E5A7CB3EBDC8D05CDFAC6A9D9C97D9AE8\n      FE0174D999916DA36098A0409EBF00771B022B36ACA092E58277E737BBCC2459\n      DEA8DBDAB5D7253FA4F624C26F51DC7CAB9247967FC7DC5BD07D1CF791A5B164\n      A9AA56B006D56D2FA4AA5D61C9295450659AF91248B080DF163CDEB0E213E04B\n      DD91EA06CF0644BD3CD5FCCC99F37361FCAE950307105E50A8A5504041970BB0\n      5F009D004A222473563EA98294014515CA6F94A0DD11B132DD5A859D313000A5\n      C68EE70538AEA8192BAD5D42C66B557805189E958A13E6F3B0D2590A4CDA4D46\n      849FA2A84D40A6D9A0CA93000A6747105BDFE0484589EA627636CA5E89E2E7FA\n      C393617843C848F77196AF3FBEAEE485D0C561D6147C15E1FB1AB38BF5C66C2B\n      6829D9C0320029B2C4E61C5082D24A240A89CA28A04D1C257CFD5D0C8B5F1A54\n      49206158C56C590FEC5A00945A9D36F82011BD94A63ADE7B09B6603D6FA55C87\n      581D257548719C4B76F6F51B178E2CADDE4D9A933DAE1B4DFDFC539B51DBDA70\n      A408BCEE283E978627A3D18B37D72F61719300B7E651BFFDE0E4BEE7AF9FFF9D\n      BBA66B2BF738B5B9090AD481673A3BFFF92B5FD7F1E1FDFB0E7DA7C08DED1BA7\n      6AF6BFEE0C4E24FD1FDC7FFFB1BEB2D238F6416D099A31CEE7255F20CAAA89D8\n      E50C7CB3EC8C82F389A1D5C3A2CC88CD58A804CA809C1A2D4B1F503CC08E1311\n      65B76BC8B73A9DCDBA224ECCAD0C96B0023458741F97E2BD0AC8A50089B9D145\n      2E34E512A0B60A249C2AF5B251B53D2F86F995822ED1093675E8C674EB934F3E\n      73ECD0EAFDF5BAFE8E12C6DFBA7A0D8D88448D16B954958A22D5B92B4FE8DE44\n      58E0AEF726C2DD7EC318D7C13E4967C7C07B898F2E9168B9E11D74085EF19B3F\n      F40E79CFB2B10584AD19F08A925C3189F348F73C3219746EDC0898EBCD4CE956\n      7B341A0D5E39373BBBCF9AAFC581B263356CC87A8F922F9E0DB7D76BEF7B082D\n      DDDF5AF8052C863F05E61B60D94C40344E15666063356708F5C66CA5E4F6E8AC\n      06B0277D171423673BEB9F7852BDBA1EB4DAA3F9867D6405DF37D5BEEB20A83B\n      524B988A53149366C96DFDBE39923B83A41F918D9C74653E88E520C783140D52\n      19A628C9700AD2B92A037E1C30CDE1D88992FC0BCD7B5E5C61AB4884B959E216\n      8466C3A451552204389C454AFA842E2C7C1B1221DECD7F7BE3E938C98D3111DF\n      AE172C7E1039264680A48205B0509A1194321DCBB971580078736A79EB043D7B\n      E1DA5FED24578518F0B8E6DA73B5F684E7E96A71095B938A2636BA8C93CE305C\n      96DEE53C3C47C2762E7C21E73DE7FE66FB0EAB36EFF9759F790C814D610D9F4D\n      B63E73EAFA3A99F9D03D871E9E5FA9D1261EAACDF3174E6DAF7F7A67FD344213\n      0E7943CD5FD3B72E4C2C676EDDEDD20C145B9FC8FA17B2DE07560E8E6E84BFD5\n      BDBAB33435D98FEBBDE19DF7DFFFAFB7842EC26D96D503621B230CB0EF719982\n      8CC824D535331984FA360D439EE7167C6209C07A468163A1529B2496EEE175D9\n      02A63F3B44E551D69C9A7B2EEEFFC5C6E5A3FBD6BE87CE7C472C2CAB1B4E2599\n      AB7CE233E486AE2E8EB8ABDB4005FAF40C54260C0AC0CC3C71795A617A5A1087\n      C702A17BEFC8DE9E1E8FF7BE52DDD602AADBD22725E4B6CC87BF75262CB424D0\n      58449B90B2ACADAA22E3FF55E8C88C0FF69E8C5BAA69A8C28F10467AC09790CA\n      24C2E2D714BC3848CCD58E54370524C2E313F5CF9DBD301927EF5CDB7F87C4CB\n      984C497DB9900D9C51031FA0AA808F19603D364C5859EA6F01C51E12A152E58E\n      10581184179FAFCC94003356BB1D21AE382060C36858A2E5665D16026E0525B1\n      40BDC367E1A4FA6C856F29C8E4986C0CE1D261CC483BC18E08E651168823E8CC\n      E9A658F7642461C3DCBA82E9D792F089DEE6C9B8DF09495F9F7233397609630A\n      A7C02FE1BA47F4A955C764C9B2F6FBCD45C759B4D9B4E54C49E46620880DFA2D\n      CCCA747831A621B6CEA646B14BD2CC01B94EAEBFB3CB503D70DB9E6F251C8DB8\n      4EB5B90045387D483B2477381ED84487EDA98CB998BD48FA518DDE2382F98188\n      1C91A1BC9D1247BF6517DB167325892CBCEDB2AB5972228DBE940FBFB1BD95A4\n      74C2AA6D65E2638F4CD4C4B4CBED373CB2D2A4431EAA5389FB6BC74F5EB9B1FE\n      0FD60EBEDD433B34F9F420FA5FD7AF7EB0BDFA4374CA0FBB3D9208C7C600A493\n      0B0AAFEAABECABBE0B77A906C36ED8B308B01C01208F11418370AF2F9365D21F\n      543A16496080C238A3B9676AA2514439581EC2283C952EF58CFE347689D83D0A\n      15A2CB3C1EB4A07B15AE48B4EAFBAB5D43A926288D1853F1701BDB6FD01CD517\n      7FAB6E7FEEF42B4DC77FDBECFC4C9CEA3E25B6F4239E32507A0ECCF4A34C78E3\n      8EF09B13A179FE60D06F50E886105FEEF44BC07581F1029800A5EB9675261BB0\n      9A75B8E54ED4143F3AE1BCF35EFF91A3BAB2D1A5B30D221520AE67030E29E449\n      B473F3DAC4E23C0D3CE09176FA9D9367A65716D98C97372C5D808F021EF43179\n      E25CF7F2D589EF7E181F3E36B1F873588E7E128A4962DCB272A86289F1EB2AAE\n      04B4E3E5D849571940A2A4E00990E54DDFB93A1C7DFCCBE4E486D4D547BD565B\n      99B7E6A6C2BB88BF34694D4E2ACF01ED658062C335E7220747657DB4A24C7443\n      B4256557F041AAFA99EA266898CA414432015AF829A8C0035B53819B042D3D77\n      9559D882E32EC9112BF6B7E04667549961816FB6238896C800B3AE81034CF5C7\n      B2883E194688447DEBFA7F4F60FCEB1221B4CCA21C49B14C378028A1FADE725D\n      9C061C7CEEC2A0763DB08EF7B65FBC7EB9DF83E5D704B3671AEDA5C6D46A3039\n      ED353225129E06CC69580EA51628917169C5B283127D6CE2FE707D7BFDFA7027\n      5429AB795B8398D4D974BBAD4F751687377736E284BEEFE023F72ECC1F9C5BE9\n      21AB2792979E7ED251E442E07FEC85AFBFF3C0E25BB92D06C3B4DDE64ED08B76\n      986E3B90FB546FBDCBF2B7EC5F39FFEAF5CFC7836E2DF0E3E8DD5EFB1D2BFBDF\n      D5E961265D577A2EB56D687E442161033A59A03132E8F27000C36DD8A9583837\n      7B3A90E8D5815D57223A00C36402A55926321120796BB5FDD9DECDCDF5C1E3F5\n      F977CC2C2D25FD763EA46E163748EA325DF6A64C7F1B301F6046251A44BFCC33\n      A69F0FB8B1C4804B8CA3B2FE2E8EC0AA92A3D87BFB4A30A3AA92A442F8B66611\n      9506F3E3C456143118FF354F40F5E2E3E7A0488A9582A85295A3082A2001C557\n      54C9A32FE5338A305314C6D26CD740A50C99498A8905425A8A0AC008A1AE42EB\n      4AF495F86ADDFDF4A5CB1371FADE83079633B186E93E42BD8CEB5867C145A6E0\n      A009A0843199031E69522CBD2146AA72FF578C3701325DCABDE13D334F647449\n      2A95F1F2A2A0A23E2765D1510A55149ABD45C70D625FB404FFE0628B535E29B3\n      104795BD06C23960DC32DDCAD3C22C52DA39B239D5854F465864B14DC1B7D2F8\n      E2D6F0E56EF7996EFF428E1278218A5C0F392ECA74744974C0B011D74D5B80AD\n      A63E3E1E3D18D877DBCE51EA2E210FC7F94888C465DC615C870809B4B71467AE\n      EE4B81E5A65C0696BA356A3789DDD02927136192C652C0AA0559BA8BDA767048\n      48531F8C58656D6FDBCE7C85BD51E811EC615497BA62C7AE229E305B2A50AA51\n      C475B1B2AFC5D9D32AF96477FD786FC8ACFAE119A7B5D3797763EAFB1FBDAF3D\n      578B508207EEFA36FAC3F3A7BF7EEBE29156FBADABCBED3AFF99F5EBCDD35BFF\n      64E98E054707BCAE954987FAFAC834199BA6B6F22CC1583D77BD3CC42C8F4442\n      EA0E4C9830B8E0A14AAC032608E0C20EFC63A66C4070339C59A00AD388A52565\n      4C516C4307C38CFC9A048E79A5CA5EC1A7CBE11629C41F8B98599A8E8D1FEFC2\n      2CACA47416030C730A02996EB17A2793B576ED85F51B17B6BBEF5E3D7024CD74\n      F4EBD9BA6A4E7DD8C9FAB038DC03402BA609D5C352E55A5401CD8ABC2BF1DE2A\n      B30AC5450612CC7162E29ECFE20D2BD937EDAD30EEBA39BD77BEFE7D6F8D0F4E\n      EBC6BE96A546F59A663CF27431F5CA19EE59E88EB9A1E433CA8BCFDFE85EBB36\n      FBD051DA62D0507334B4E35AC2C8F39B1BC75F6ABEF1A8F7A6774122CCFA3FC6\n      2CD7306B593153346F5B55EFC7F4E0FA4AA6DC6838201527A8E68A61BAF9075F\n      F19FBEE60C64D66EDAD353B9459D8989EC9065CF37D8F2B46879DC86D1074835\n      73106003D30DFD721117BD91EA2039C028E47828742254BD840F22354A4C22E4\n      32C9818B0D1AF3FAD6EBBE1D196F5990E4A002DC85649C51CAA4D9D1EB9BCAB9\n      2EA12C330BAA3435C035BE1C4A6107F84618F4B7E45E4CC4B7D58CF936597057\n      6E4694F00D9AE6BA8C8D9892367104B1521AA5E4E5ED9DF30C9DE1694CD01DED\n      B907160E1EA6722A17AD988209AC1BC0D0D8652925943980384D61AE005AF432\n      635124E338647830E15D73F25B32BBB0B37D2B0A7B494E73D4CCF0BE66EBF054\n      FB2D9E17F88D91E50C3CE7C2D5F35FFEE2E7FA2A0FE766AEEEAC1F9B691DC955\n      3EE0AA397B5C0C9C8DEE6C73BAEB044FDDB8880274EF81C5174E5C7A395123DF\n      9DE0F14FCFAF7DB7AA37D55077CB0D0FB960BDAB0F9B9531065EA5BA81E772D4\n      4FA27E2A737D2803FDF8E64480DF97B11924309B0205CC2CE3BA44D5492EB170\n      97862FF6B6CE0CA2C76796BFBFB93AB9B32E1A71D2103E2113C243D4DFA99181\n      837CA94B0705CAF7C4326AA586B666C4F0B841F90AA3A8A95F9C09B2F7508D67\n      94D56EAFFC3A51E5CC12DF96C28C856FB5BDC37B73633900204A7D9BF208A3B1\n      8603A9FC4C5441A8AFA206A9BE3DAA80C4A6B095A561A1E91ACD0F4A0A7ABF71\n      8784D193C0FA79E5998AF5E3AFF0A6147D2CBF5A73FFDBA5CB7E9C7CF781FD2B\n      5C1EC4D682BE5E59E6EBABA47F42072EC13205CE6835BD20458D5FB84F4BC395\n      307BFD023E6D644849A1FB60B261B1562446F2568DD5C16935232DB1B1267D1A\n      C95E51495CEAAF33552E6865A91D41CA9459CCDC64E1150A406E98C718DEA4BE\n      F62986D5576ED64DBA720F04F1C15B4B848475197D3509BF3A18BC92E45706E9\n      B0970FC3C4540B043C964D6993EBD406E33B28866731BECF6F3CC86A0F375AB3\n      52B13CD3B5197619D46782634E7547123008525CE6B6FE459607083798EB5AB0\n      65CFB82E38254AC88E8B068CF282310ACA0C88B87602A453D9E4B256C0439822\n      290F2C0FE51258052ECDF3A8855D27A59D7AEDAFEAF8E337CE9DD81C5CB37536\n      4E3E323FF5A1F9834D4F4DAFD6D6EC9AB545AE30E7BF6CDCF8CB17CFD141F72E\n      37FDC3A929727DFB7B1757F62FD6158ADB215F946E43E119E6D849AC6FA28549\n      7380B927F22656967E2A52987E53E3BA47CCFA85900CFC19405343DF083F2F24\n      06E12EE8D6D2CBE07EE614250CE74645CF9837EBF394997B4CAA80573EE763B8\n      19AEB6EC7B0BCD127A5F1167CBCA0FA18978F8727DF24C6F78340846427DE9EA\n      F5B7DD75E703E1C0E1C996C7F483ADFB500CB34CB1B766ADCE4549DA55C5B4B1\n      1CAAE16264629C2977F9D9B872BB43006E036B1A4EBC33323B937727A783054B\n      EE6F59C8CADC63879CBFF3E6EEBC4F47DDB6B43264592EC1DD41F4F2E96079A6\n      77B01D5964BE8F93972F8FC25EFBB123C201B8A5642C26B1A78BF0D77AB7BEF2\n      7CEDD072E3DD7FABBDEF6770DAF921DBAD81C635240DBB4C84E6692FC2BF01AA\n      A310CB40827647EC60324AF19367B7FEF41BCDD0B27412D0C17DA231A4A866FB\n      6ACEC6B375BAD6E60B3E6E5AAE07DA5048E82B04CC4918E747B9ECC5A8A3E400\n      C958621DB27B19D61D613FE1C3584530209509F827528E48C67530D6958E6120\n      83BA15E1F036A230C1BEC375A9120B7D99B23CB70A0911329E6D9ABD2BD47F65\n      22047236967BA2E4FF9F4C783B8342199219841C2FD39F0C9203F53A0A5F8AC2\n      5B89AECDD84C6D6A61627EBA365BF35A3A8631AA8F954439D8FF71D03706B514\n      7D4774C4B78DE891BED0A10B62D1C036D6353FB544CD89606690D7A8C3A92E36\n      509C666EAE6A16F52DE1C82DDD296D882C1F46E18BA7CF776F7D3CBE7252C4EF\n      9C597818C60D09462E15B58F67DB2BD7FB879656CF12F4C4C5338BD3AD9999C6\n      D74F5FDB148CD8EEBD35EBE797F6BF6523EDDABCE6AA9AFEDE34855AC1AE49BB\n      110B1226F968344C873116C8B1EC2E0A8C16AD2E4678A2233285299D076B0314\n      A5F9C8B1BB2D671DF32FA73767AFA51F995CD9EFFB94C6353B77A8103AAC58CC\n      53201E9ED83046B68CEF060760005C55DDF9C100BC802383AF05E490E2E04A80\n      71A93169B01C51EE1EB3F214EFD5C22EFE18DECB69D87327F726C23D2FF2FA24\n      582AAC8D0F27C2C51454EE050294BA7FE513478A37537655A5C650B1FB374AD6\n      A5DA8319AB02FB92A7C01EEA29BC85650FC9AFD7833FBD78C18E9377AFADAC0A\n      7498B0659D08D3CCA314803036016E1758CFE3C2C2D5301F54817A282F41D1C6\n      91721E8C2BBB14335D2B0361910E3129BC370A584F018D29D74965D758887717\n      C0311315AD22BB579D6511614B9527648A15A833894031313A964C82BE2EF431\n      8698ABBFA394709C1D983550B0C84AF5CB5861E0DEA06A3B49A872AEDDD8BE12\n      46D7B8EC73328CF820E71D9A75691EA532E52436F6A258E6071DF68EE9D9377A\n      F59924F661DDAA12AE0F56DD03CB667066D2B94B27095D43DB5CB81805AEEDDB\n      1618D5E5B92E5DF5FB03F48CA1C3E8749812E5EB6433089DA6DFA3B995E73360\n      E0BA6959BEC56D3FA68162828AD0CE29D3CD22189875293BDDB4BF70F3E22775\n      80F14073EB9EFAE47732FAE183734D4F92E939E5B413D47A61B3FF9F9F7AF2CA\n      CEC649BF9EF7469360D928A88F0FBAB507EB93872C7759F065873A2C0D089A8C\n      651FABD821E0022F323770C0638F23864DFC000430C8A0738A0D9F9073F0A6D0\n      6522E8E3880A2468A8A3707774F9680965B4E3C7CFC0D88207ED464954990354\n      516E0FEDC1187A19A48CA925F144AFFFECC2FC976EDC7858D907160EFCF6ABAF\n      3C76EF91C7069D7A9A745CA6DB4037D737C0473AFBEE4984A59A0CAE06366A5C\n      C4AADB12A12AF5718BC7D4589799790A9536CCFBDC0B9E7ABA77ABDEAC2DB974\n      39C02D95D296E3BCE77EF637EEC175E4409FE6E39C8FCE9D15A3A87974ADD722\n      9239ED4E9E1D3F9F59DC7BC3FE04E77E2E758309937A6CA3EBE9AD279E73EB8D\n      F6DFF8F0BE959FD589F0072D062659987A405E57459D09FF05AE60811E12FA53\n      822024B7756077864FBF92FFF1F3AD0ECA846EEC5D17045271125835456910A0\n      491FAF34C5A28774C1D3B4886F295B2ADB024A9A4E05A942C304ED48D9136294\n      A91EE7BD540D32FD451566284C55022052DD17EA0E8E66B9FE6CA105E1074CBD\n      05F0E86D4962C913CF1EC5B117A9B6E5666906A1A13CE10455E672CA44D12211\n      2A28A0A4113837B7077F8B5C38D69751DF841AFDE644A83BBAA11DB20C7B9923\n      B9DB61F666E0C6813B3FB36F11D702236A02CD9FCD864464920B5D906211A761\n      DA1F7869E643E1C96129E7829726ACFC5960F933C4F6F4EF09B013784D7F14D0\n      21C7C8F390BEB030050677EE18739CEA3011EDBC7AC6BEDCB9DA0EFE3D5B7FE6\n      EA957FBA74E48141DAB5C2D8664928FEBD251EDA1ADDB3B2F2D564F0CCB59B77\n      CDCD12465E585F1F096B89D00FAD2CBF9F584777A2C4F3DC06267E2259029B21\n      1C64993B18C930CD139E9B0E0BE89BDB96C7C0055781C61BD1252B287FE8B883\n      335D09E041605FB6F2D7E29D59ABF516D67C3CC56D190EEB59E45317DB9E7E9C\n      1948AF21C30F32B52A2CFF04087D151D8E196A9B0589815B824F8D8E46FA0F80\n      A01342BB9BBD62BCF3BA412832027F7BEF5755FEEEFD33456EDB0B8FBA3D23EE\n      6A26E0BD1A51A6A9C26A1711BA3BF91145A15B0ACD2A630E274B81BD526BDFF4\n      9146BE0C4814AAB4D5030D01ACABA858A09E445B580D08FA46BDF62717CE9138\n      7EE7EAF29A904788BB9F58419C7916B40C0AD48480E16C7CC5CB4926C2E57329\n      5189B52B1784B850934063767CF9E856BF31E393C2C0BA689C4BEA6DE5AF6CD8\n      B8B8D04F2D9163941697B020F2170E64454B3D2E30B0F1751A561354A3705AB4\n      33B2505A00DD9114ACF0A8A33F883EDD99F0C1E31EEBD0A2B3574CC94E96EFA4\n      7294B338B7D294C4288CF0B013CBAB213F1DA66779B6A12007E8EB71C871DFD4\n      6A1F0BEACB0AD99C87BA2349942F75D6B0746E4B9470618D26B10E5A54F9BA5B\n      30165423D82C82322D548B19DCA26D0FEBC8361BC1BCE69C0F50933B45BD635D\n      ACA3C0CF9C1AB80E531032663C63C2B2542BA7CDDCEA33BA51234F0E87BF7DF5\n      EA0B0C1EE71F3EB8F6FDB3FBE6717F76BE4E9D093F58418DA97349F6D246F8EA\n      CE7594886BD7AE5DE86D6F0C876916EA2CE7223487D0C244A35D23F7CD37EF71\n      EA0B23E40A20D201EEC006C35458F3003FD4D2EF1D36B946C0016A01A62F0298\n      34DB20EB8922D01B508E004F891C2452817E06897017FC34168440635AEC38E7\n      C96A913EA6D118CA6CC5CB29380F18B77AA3E307963F75EEE2EA4EF8E8C38FFD\n      FAB35F7FE4D0E2DF267222CE7A9E9322EE4315A21BDD187D73222CF374C1BAC1\n      E37D4229CC65E60C253BB804C589B2E2A4B002248C5EAFDB9FDABA1A32B6DFF2\n      D61C34DBD625436ED5D9FEF73EA2FEE6BD4336F2B8CBAE6DF637AEBB8B6D7B7E\n      32D66580ED38DB49FCE23959B7ED0796339AB95CE6D8622AA1C4D2476EE3A997\n      59A426DFF1C1D57B7F1167BDFF09448D984FEC1A301301C0434B2D62C02F11A3\n      852128C503A29F03669DDE1C7CF685ECE59B4D5217A97E871ED2B9C9A27196FA\n      BE0FE2C835074D7B78D6C533369D747153D751360A402ACC0CAA304A72D4D7E9\n      50C160A897C99D28EBC4A21FE18843228C53C888092442A2339CC847604DA86C\n      30382F099E9963DDC0E9288C673247976FBAD9E2B62A12E1F89C9BEB394E84C0\n      9DD0719616C408552A697D33EFACDC88A86FCA917BD930A2181DE188802E0338\n      E410C7F5DBAC3183FD969416668E79912C8BBA3BB7AE47832E49722B4A2D0E14\n      A7904794600F9E76291D92F93A5048961960B9ED63EAD6A4EB80E764AEF33631\n      6C15D998F06B6D1C257918020E8937699C847C304CC39E629FE96DFFB7787BC9\n      A33F36B13ADF4D7A0D6B1BACC1C83F97C9DBFAA3C30BD39FEE5C7FA9932F32DF\n      26D62519EA40F630B27FE98E3B573BDB0D2C9AACAE0229028E7CAC2C3B1DCAFE\n      0ECF12B068E12050A9402C54D7A836034F5413DCE12BCA882319817369D310CB\n      6D1E6DA2F447F365D620291BAC211124B96CD53703B0BFF6748B005610A08594\n      EAC74882135E4E0011051DA14946E09466444888CEB81C642B752791D1DD7B80\n      D06EFEC37BBAC0B180C537B57E95344A95F0C66B926F5A06DFFE5BA1C67EDAC5\n      7729FFE2B8D12CDD454AD686B1B420E5B72C668B55162CBE027807500D2CCF3F\n      313C3C9EC954E0BEC29B580D893ADE68FCE9F9B3288EDEBEB6BA98E547897D07\n      B59B2977CD4CDDA02780B1516C2ACA1168D91182BF66B9C6A464FCD18855804A\n      C79CA2825058F28B5499CB4ADA142A004178DC4D92AAD1BC4D7D62FCEF92B882\n      49D91A57E7C690E1F56D0538A92A52695927E897B3E0FF00614B66E5DDCCCA43\n      9D1E331CA4441FF00CF42D51A01FBB5864298F108E94CAC248E57962D121B6B6\n      727583E3ABD4FE467F7032EE75643E49C911EA3C5E9BBA676EC6B78533C8BC18\n      143D33D334E9776643230A735BDD52050ABBD88A2D9C2135A4323732E84AA0A1\n      4BB7E25140BDC0727B59BA1D8D9616166DB9B9716B6BB539DBA67EC47362D129\n      62B17EA85B73CB75C830F108CB1CCA13F6FB4EF8FFDC384B1C5B67A276E0BFCB\n      4A7F6E6DC60F6AD1C17B5214B4A89706351DEC74A4D8E9445B29D91AE59BC3C1\n      88A82BE1CEF9C1F633175FDD19A68B143D546B7EA4B9EF8176DB463A98412AB7\n      5D23DF6B81A2050037406100FA3C3829AC906B03A8A52EA333334B7104489FEB\n      472F33F64125B7B9A2DE5641ACAC57F6D6797B8698A8D249960558DA3CC9258B\n      A8958997A6A7FFFCC2D5E1A5EB0FBDFB5DBFFFE20BC71ACE8FB61ACD14EDB8FA\n      028701207466241EA1F1D271ACBD80C7696FB7792D579295C382795E2C84C6C0\n      6CE017EADE8A28CE2CD4A93B9FEA6FBD92644B5670D4B66B405A416B39AAFBB4\n      F18FBF337DDB2AE945E8F8E94C67C70796B98DED4C31DB5737BBDB27CFD457E6\n      D8DDF33AA9B0304998E3E7316CEDA5DFFDDA197665D8BCEBAD87DFF3AB38DAFE\n      30D58D097528AB616C1B3E251DABAC15D310C979CC844B2CEBE668F499E3FCD5\n      75399234B36BB4314A79A6E39A8EEA6962376AC8D1BFC4D4676CC2C1131E99F2\n      51CB1535866A0EB82963C33F14394CBB5390025023243B51DE8D85FE18612E47\n      098E521166BAE3413AF3A560511752C572ECC5006E56464D66E0B357A31DFDC6\n      0E9156BBAF7B671C39DC9837E3CA231EB4E76E4F8450351789B0E8FC5ECF9A2F\n      6E80A9EF89BC2D30DE96052BD4A869145CE1B912C42D2682A0AD5B9E3C5494B9\n      239975469D9DED1BC9CE2D140E5DD0E6D7BD2CA844A73689404590E94F043693\n      04C704668135DDD3AA3487BD27D3DD24185A3969EEE923A12B5116031695BA16\n      134CC5484C8CEA548A11E6B79AF444ADFEF1B3676EF4BA3F7164FF31801C65B7\n      EA8D244C830CFD42DA7F9FCAD7DACE1FAE6F5FD12126757D656DEB6F6CA51FF6\n      DBFF6C62B11EF53A4DB4227DE42A9D053346869918F4F32C01BF4E2EB244B7B1\n      9472CBE6BA8C4209C49862E227CCCE471F390BA7167473569AD5399A0E1A47FA\n      7D67A6BEC1929AE3349115892C6B790951BA29F4A13614B97E526C5D70D93A26\n      E68621AE9F08304E424480D60A0C7F1038DBE8325F1F57915925071EE8BDE335\n      ED6E015B1636C6E8A15C6A8C472CA69C957BB92FDF0E0CF5DF4F84632E144168\n      0C135506B95F50EC4811594A85355454BED5AEA54C8AA818605589D0A0BD5422\n      F000914D0C5AA3C7EB8D3FBB7006C7D1E307D6F685C9516C1D61EE04579E0E80\n      1464378DA79820C5B2AF64462B84C7234D5992FF2AA944AAE34771A1A82C99F5\n      8542BD098F0506AEE826CBCB824B705F893235026C4599012C6E548DADCC9FA4\n      B75FB38A7564A80D6622AA0CBB022055D850F74541B504AB14231397652217C0\n      A0702537C3268F89247672EE64BA60229CD091103CC53246511A81AB2D83815F\n      48C88EEBBFD8ED9C18F6CF0DC3EB60F54EEE989C7AD794B3CC26EA23409E5B0E\n      E346FD92552253FA02F88AB8A0DA286200DF228E14A870085DFBB9AFC9E1D706\n      B71E593C7A60E83C71E9B5AB0FCDFFC468E9BF6EBDAC73E3DBFC592B09079E68\n      617220D42710EDE4F18C57C769DE43E2A83DF79CBDF3E9F0FA676F0D4F725B04\n      C10362F0D17B561F741DDB6E37279669C389DA2337052E73EAB4246D4429684D\n      DA352749F848A0B3E1E8D4A07BE2D557AF9D3C15A16C7FC3FDCEC3773CD86AEF\n      E35910EB1620C1BA12B541BB0956BB5C1925481D4118454AE84E95182C963006\n      5B66B147CCB43165302F659C8E6B20B4670A627E4BC645DE38059A475516E400\n      52148EC638CCC8E7EADCC02F7B932F6FEF7CFED5F34BEFFE8EE7AF5E7DA7CA7F\n      A4D670A5AD13A1A5B66B394AC812C2BDD727C2719E2DE883BB6917176C7D352E\n      975429CC6CCC81E01B7303E172683E0ABCA7F3F4F31BDBBED75CB6E88C2717EA\n      F6214C797FDBFD8E95D9BFF796A421D1F173EEEA6474F78C3E29B5912076905D\n      BAD179F5C2DC2347E2B5893C1FD423197BAE1F0DC166CC9F489EBFAC8E5FAF35\n      8FDCFB63BF8F07373EE0FA758960486731F0C992C50A1EC9B282806506EF35C9\n      4C66AB274E0D3EFF9CE87114219FB67415D219C5D475C1F2C6D5E152290FCC42\n      29232089DBF0703B902D4FD61CE5C39C5DF712368CB63948C70846734C80DAC3\n      D190EB142886BA174CA1291C81692FD06D325DB789884A3B157E8C28587A21DD\n      FB6F3279BC7BB3516BDEC7A6FC5BBA9A6343D7D85390AA7807CF5118B50156C7\n      B18AD1A804198CDD36F0F51DE1AE0185A9EE0B678942CF1F950A96129894C510\n      0F182135A7EEB4A7517326726A436475C2783418F4AFDF40DD6E90678C43A803\n      75006F22C3B48FF22D9CEDE03CCC384B7507AD3CE627064F1B283A816C6C253C\n      D0D72998E26E0B368591EE391708AB0D244893623060EE38F990E4CDD84116ED\n      79F8CB83CE571CFBC9CDED2587FEA3B5A599CEE6592C2FF8ED19EED66F45FF5C\n      F43FE0A1C53AFDC4D5ADED003B6950E7AC57534CF57F71EDC80F747880D2732D\n      7554D740FA12D956274E377BA324A7C4F1C16E258D61226439BA4FD515549D77\n      80B162018805A214A219D225160A819F292662B1969323B811EE1FD983AC8E1B\n      DBBED59D6430958A129732701232D0438475BD1E0B5044B033B02487EAC5D127\n      5B18F94D0CEA63C086116057ADAF34B778117CC9B8354165E385AB95A1195FEE\n      01349588D1EA9FF142A4D0D02EB66A7B0A20B5E77C8EBF5AB2E385AC7036B8FA\n      767B2838A2E236CA3D3DABA9170C88D4786F19B285498085F5052E12A1822DB1\n      2EF6489508D5F3B5FAA72E9EC371F8A6036B33A3E8B0A2773AFE9C248E8EDA16\n      B89B4BB06E37D500A9BAB1A22228EA7D2C2B3FC2326D53CB2AB782C828C05497\n      A55813162F623E48A9FBA870D5F1A231C910573C4DCCC70025D32B1479D5BCBA\n      ACE22CB498996C1807506444521403D92D50DC350438187DA7267C27C4A909BB\n      3902AD2AE15BA14AA36810F84E6E4087BAF531DB30C6B1A772CB4E339AA72A8F\n      8588854CB33C57CC8BBC895398FD457FF864AFBB13870F26F1B1A9F6FDD3F32D\n      98392540E631904B6966ED4C59AE24BADEA202C4A76DF314741DA87874357A6A\n      8AFCBB53A78ECD4F7FD03DFC47974E7E6CB1FFB5ECFDFFBB7FFEFCCEC57FDA58\n      594CF31364BBD50AF6F7B0876C643BD3096C6DD6679CC5EB913365BDD6B67EE5\n      CAFA135B29C3FA7B8EDEBE7FFA83B6F35DA1CFA4DF5BA4FD83D11459CEED1669\n      4C12EA4384A7A92BF3662F47918748D0B3693E3F757AFDC6AF9FF9CA13674FB0\n      6BD1633EFEBEC3871F086AB3796CCB4497C3996D78D2A0F3A0BB2E86B16F0105\n      47A5C05D965E8E58067D9F306079501DB1646E613B2F1FDBF17E7D8F8A04A99A\n      B2DDBC64E4C454B917283816A21C1CE82FF4D2240BA6D6F3FCDF1D3FA18EDDB9\n      D9EB7F50E6FFB03EA16BEC4D1F3B7CAB99AB08AF28D22DCE43590956048CF176\n      7F0FDA0DEDED08CD3B24E3534C0AFE3DB016742F9C478CBCA8C8272F5C19351A\n      730E3D4AD54146A728996A07FD6C7DFAED879363338B31B18F1D4EA6215C3B23\n      5D473BD1D9CBE1958D9937DDDD99D395FC702267B16FFBC301A8CF3726B29337\n      932FE99039FF965FFC3CEE7CF19ED6D18389E7EB3ECEB1EAE078AC3359A1638F\n      64022A2F940A3020706E84D11F7F83BEB4E9644EA274A3E2EBDAC6CA20968312\n      33D50D231636FC07D916F86C7AD4AABBA4E6E817A68103A8445AAAFB086E8288\n      4E1306238AD25CD7843211224AF908181424933C4E719CDB190E6D0091D999EE\n      20005CCF897B3EEEF5797A87D5588B49061C558A8070521C7990481360750D80\n      7F4114F36D5843D0C264878C63DDEB59F3D582101638D9B4B4B7891DC9843A62\n      C2B59C440C24C9F41DD39F21E732B37DE97944F7E8534B58BAACD3BFD93FFFE9\n      CD67AF38A91DDBDE7A7EF7CC4A776BC39E695EA7E9F329BF3AE87549BE814721\n      E7347368E6253A8DB8969D0F66399F643A3A48E983B94C9D5BD3822DF8CDA966\n      2BB0693B95CB115E009B1CA10F37ECF074F795939B727076B9F97BB7AEBC7A73\n      670D91F7EE5B78831BE88FFBC5BC73A5CD1E5041FDCCB57FE1660F35D6E828BD\n      126D7499C8904E36765DE66FAA3B3FBABAEFAE41ECE784D4266A0D192BB293CB\n      BE4E4FB1B2111D39A8A73FA512BA0507328FD4C9108F5C306FD3095066B9AE40\n      1D5A8B731CE91ED7520EE5FBA8D84FE48292038F218F5936D3C550A14162FCF0\n      C0E6A0C0FC53A355C90DC4976253E1AA720FA5CA3D96393FE68BF00A181E2E52\n      1D66D84C52903604312485990EB266971FBA057611911243B9DB389232C7C1E1\n      E4AA6AEEF608D414051FDE9368A51A2BCB14655121E552B18C45C9DC9010E465\n      B5EE90C6FD01154C3F43A62A40A7A0B004805BD3189A1E89E8275966FA1F9220\n      ACC34657E523A9CE34833FBC722189E3636B2B33196AA6E93DF5D67DC86E2769\n      6EF3C88531B267B95C726901C10BB6EE46905A19C60B8CD14174A400E09AAD0E\n      32A6D6E691374E54E5F4161B9F16301F329F5401FBA0D0EE32C7C2CCAB8D549B\n      516D2BF445153097F734801570A9BCB6645C55EEF151472542B0EC8477D5CF4D\n      EB68C6C4A4087925DC579557B820A219DF4764C6C83AC0C0AC40E21CB2AD417F\n      5A29BC325CCB308C4EA7A3FF40D4D9FE4EADE9BCADB5F036D15A4B7022463D27\n      9736F124668900DB6EDDFD657EDFCD67E2AC95892B4DB1E1A0E981A51FE74FCA\n      5B7FB5B1FDB70EDCC9A8F3FF9E7AF1C7BDA5A71F58B8F1D2C99F4A2617EEBEE3\n      B73AAF3E829DF7AA89A7B3FECD49F743B9B3B6B57D7C851DBB2272DFEB79F6F5\n      86F35B17CF7E7634881C622774C509BE6375F17E5BDE9B2547200D337BBA467D\n      8BD4DA89ED84D39EB27133B68334C81D77E408CE455D059E0CCEF5FB7F70EBC2\n      EF3FFBEC569C3C7660E11FCCB1B7E61D9D1E761A736E9835465BAAC5B631B185\n      9FA1CC85A88C12D826222FA33AD9EB6C9150A0E6D9461B4C58460EC208BE1708\n      E371C14654E1C7098F2B473A8DA18C8A11531E174DB07AC123B009A5766A2C08\n      C1B72579A67B709F7F814C8A7F71FCEA976BD36B81F38361FF27970E22946E7B\n      B97EA95A0E2EC18089267BEB4555C2B664694E575229B821159A310FC5A55A57\n      C95528A4AFCDC32A2D9EE8D4231BADB4768559FF72E3C4CBF5FC509E3D96646B\n      F566CD691FAC4F37F8C0A33BD6DD96F3937F335DF325CF19A19C512B91979F7C\n      7EAE39E5DFB994348995652C9389837D30BFCB2CCF153B9DCD275F71C285EFFA\n      A92FE0C1A7EF47CDBA333F4BDA6DC4C01DBA187B988E9AC1D3A80B4EC7B16275\n      EB534FA55FBDD0DA52016970EA8C626181840A3CBBC689D0043602386FECE85B\n      8F752EC4BE098B90052DC4E0E482929605EE4E703E74064D850268A87EBAA5FE\n      B530735160D627324F5212E7FA620D6D580D36231EE82F62B28D554F37B0399D\n      CA8897E5AC467B303D7508AA0A7D2329832CB0FA940CD91E187E836A5E35D1F9\n      EFFF80C0A77C01024E308D15B4E1F2A03E0A2D9A773CEB7C1622954D059313D3\n      77B4BD037D57DCEC76062F9DDD44834F77CE04D27D5BEDE857AE5C3A7BEFE489\n      CD8BCDA1CC926C455953AE978BCC7758CBF2943371224B9EDEBAAEBB9DF72F2E\n      BFB5D6AA71BEC375E947028163DDB9E6D2E7A8A6FB614BDE542362E325162C4A\n      3721F28C9B757DE6E5B52F9D3FB933CFBA98892B83C7EBFB8E3527BC7E2F65D6\n      9F743736A7DCC71AF3F2D5D3FF818943CE940EACB74408B58DD11D7679F6A3CB\n      0B3FD89A6C6F6D79AE576F4D0FF36E4F5FF8441F082B252462A0DF84407649A6\n      C4C4470928862083AFEA760DF00EA003AD7B43E27214E462DAA6D335BBEEEB74\n      9111A653A045F52D062E60E16D5491D98A2155C53D4755B82C9A365C38DF9AB2\n      B418D914434EE3728D64A9B2060526E4E6C21CC938F0A982308A4BBF115C05F4\n      4A3250ED458AEEC18A8FB94DBB44F871959423512ECCCA6EB16020E392263846\n      C1A04AA6B36234526391598AF516490019F75E5CBE49983B72706095BA08CC51\n      8CC880EA125A0C257F35F0FEE4CA25DD883FB2BA3219E5F52C3DECD71E71EAD3\n      B910348B1D50BEB2A94EFD8216003BC31C34DAA3B810CEC6C624157E1A269172\n      6C5956E025C7B0A813CDD8136C246429A59A9689B2E008E202CD5EE265709908\n      7522BF3D09569DA2DA9316E10AD0C25B70578C07305EB262708C5135659980AA\n      CEB2C40A16B0DB0254545C58690C86A980850516A0479D26B96E2D75E59C0BC3\n      BBC63425F6B6D35CEF6D9F1C765F4DB64483DD39397BCC9D9CD81CE03CE73547\n      87661671375703CF778570A4C82CDEF5604A5C8B75EC66676AF43F9E3E21276B\n      8BCBCBE7CF5D6E84C9C6E26CB8B5F5E684DCF7F0835FDBBAB4BC1D7D70FF9D9F\n      BD796103E7FF70E6C0E4C6C69959745756DFC963DFF227707085928F0D2EFDD1\n      F696EE66752A9815D61A236BBEAF6BE7070367CDF166FC20D405ADEFB5905AC8\n      C56C6B5A35267A1E95818E556AD26E7063BD18AADAE9ADAD2FBCFCFC532F1E6F\n      F9EADD0726BE776E657628623B4C7CD02109642D74F5FB8707511F40DB00A8F2\n      A25C832B04BB356A544700922D0BEFB062025ED15CCD55060493B93FBAC63089\n      50C5543A42D5329511A4E31D5544F721302CB5008EF4BB726E7978E1D052FB57\n      CF5EFD8D8D4180F0FF3C37F18F9616B12EE32CE408E171CCC10158EDEAD08F59\n      83A6C82DB60CA49AE8184E5C35D729881C05998700AA4E16930C96E9C8A8DBA9\n      C9B4BE6E051FBD75FA8B79F700B51F88A3BB1A8DC5DAC48245675B6287DE9CFC\n      C823CDF73E169221760825FAC3A4CE6674EDF9533387F6DB87E7535BA024D1D5\n      724A81798929CD45CE521E3D77A97F85BDF7A7FF128B67DFD7BB7ABDB1B04FED\n      6BC74D27A8D7B0EE3810388C13EAE8365EB701C4F7C9572E9FFCD32F4EECC866\n      C294B22575129D08736C6780C202316C6A5674A09A05BB7030AAD4315DF785B6\n      853D4A5C5BFF54E6FF024205CC1781AB8AC0ABBD7070D53547A6F4231EE92C08\n      CB1315EBA227259CA70A6ADD7A2CFC340B6DB1ED5B68489A43BBC7D0756734C9\n      938339EB192151B322294E34987B81BB994D6C5FFFCF12C8D8E819BDA2BF2611\n      C221CEA5AC83D3993DD0DD36891B5389B258760A89D7926872C23EB270C0F38F\n      763BFD4486972F9FBE7CF132599EBF42E8E9572F1D6CAF7EF9E6853375D18DD3\n      7B6BB53BFDD6E3F5C634C55614B539D1F7746362EA376EBCF6646FEB10633FBF\n      76E4A10CD33CED617D38A98758CFC30942BA03ABE9A4C8D00537DEB052FDD9F7\n      E7BEF2BD2F66B79EDADA52A97545DFA3097474B679B798384A1BD6689825A19C\n      68FFD1AD1B373C726C7975E3F997BF60215DB0E864A67F3A9CEA0B14BAAA9565\n      1F5D3DFC9E04F9246713757D9DAFE0482737FDE7A4658D5C2B52C24A39D3A9D1\n      281F62B3E41952DCCC99E2C65CDDD625AF1872DD0A8A1985D7B0BDC058E052E1\n      A3CCC7BA68297DD42A3D30494AEC5281432B534E213C888CB94C31AC2C3A72D3\n      0418A15993D3A43111C46592C2A0230D8A4AC4FC5D6EE94E1AE853FA6FFAB961\n      BF95A79C14AAE8BBE48A6A14432C324E7BB880B1182424BA6D3A803299E33DBA\n      A62611C26C8AEC369ABBE56E29B456CC1AE1709B642E8AFAD7584815DB175C41\n      49C11991C81CA512453A115AB4A3C45089D702F78F2F5D4059F2E0F24A2BCEBC\n      2C5965EC0DB5F6125CA03C353825CBB2CCFE1B956C7E6C20EEA4703C32F9CED4\n      D3C6ED0241F16376A726CD115C663413684A3F2520A9509C14A37F50F72A84E5\n      7029375A0C4E48D99DEFB6808656B16BEB719B00E198C2541110D178653486DD\n      EEE925F74290C8DE7552B18B05AE88015001CA5A1F62A8214050475F3B6E5620\n      3A6EA4A057CDB8AF2BF16ECD7EC149BF916FED0C7B7793E6FDB8364DED218F42\n      9179847ACADAB2F1848E2B4497D7F03D3C589F5A51C213D7FFB3FECD3F8A766A\n      93CD7D5BE24A3E8A1D7DFD543D938BAB734DDF95AF5DFEEEA3F7BE1CEE9CB97E\n      EB87F7DFB192645D163B3A32FA5E1066331D3E3931F39C95FDC1E8D613DB9B9B\n      5CC7331B8A429BE48ADFC5C41CC20B6E4DB7163A00DE3FD98C5F39FDDEFB1F38\n      5F27A7BAB73E70E4E87C94A85690FBB419EC8B134779569FCA9736FB9F7CE299\n      E357CEBE77FFF4870F1D382A12371D859229DBC528023B62830472CC314B815C\n      0372C6FAA6EA025A00075197C9A69C29C5D248E1E42C77EB13595439BA4A3012\n      E4F0171DAEDC0C714A1228828DF221923AB3D473F5CBEDA9A57367DEB8BCF43B\n      1BEBBF726B338FF25F589AFEF1A55947E429B5BC5CBA52C4CCDE2D0DAB7BA92A\n      A25191EE0A41A38A915B72790A8EAE7936CD1D2795139E9545B66E9B6B93B137\n      608D7FBB75FD77366EACF9AD372A7CD842876AB57DB64A9D5B4BEF3D127CE4CD\n      A4A5C34094109D96747EC2EC959BFD6BEBF5478F66B301C838891C405ABA8DCE\n      39617694453EB1D3D7D66FBC30F8C0CF7E09ABAB7F575CD9C8B6FBF6F2BE6CA5\n      9DDBB44E743747392C636DB097D65151D70EFFE9B973DF38D9D45190EB6B6C73\n      6CF34CE9DED3E5506B80150F293003D4E8E881730C8C776DA218C8EF60D7B65C\n      07C38812A49BA46524845111F38020883295C689FE374974472808B841422264\n      69C6723BD7BDBE8E7B32C968CA294B3B1839135F89D77B0DF98844F7F4D516F3\n      0BAB1252A82C026F4B17470239C4F15D6C99121CD0F8FF031D2124C2BE54B3F0\n      90591DFDF672DE92CCDECEBAB74679ADB56F7EAED96C4D61B5FF539BAF354E5F\n      0892E15F8AF5EDE9D9BA35F7C5175EB85ACF58983F9AE2FB5A4B47571756739C\n      C41D9285BAAE6F597EC7F1BF80B35FB974BAABD047EACD5F9C5D9B8942EE11E9\n      D83ACB8CF23C84D1A360FA4E59B6702D7D5CA52EC742B092519E774685AF0CBA\n      1D4BB761FD89802D5B7E3DB74671B49345B58956A4ECBFBC71FD3A110FDC73F4\n      E2CB275ECA25E32AD7A1DF76EC18E0BF09491F9EB0FFD5DCD107BA9935E1F428\n      0FD777AEB79CC904609C11C5B12921A4044F4858D340128542C5E22A52963072\n      3FD0D063285BEA44CC33BADF0FA62C7DED0510926B8EB1D20666374C3660518E\n      8D38479966CCC0BF90FD31BC501DC70A4535D39FE9245710B18BC9232F9878A6\n      6D2900A7D4F01348B95600CB75612163ADA55CCE55E1FAA90A469F2A165CE37E\n      D0D8E82151B095C67BFB2253C19E8BEEED5273505F2C85A78CEE0DA115D80422\n      F2F89C17AADBAA14622AF9FE05D0AEDCB09B608D2AD68569708C6115C819E68A\n      8C30E961B4ADE0BE9FA905900893F8E19595469231914ECBEC4DF599033AA0EA\n      E6C7A89453CB1295588442A5480CF01908B01A0A95E0824768F25E36B6552A48\n      9ABB34325CD8BC9AC59391E52D71EB0560BE400B1AB551B4F7D3957F518D794A\n      A85A40557B54FD64A871FEC395EA0D31F620B2281AF61057CA856525596E1E0C\n      3C46189A8B8F21ED5763B6D22D2E97443FDB3A23A60A1628E6411971C1B0AD63\n      466EBB59B3B189F273B7AE4C05C1BC13B849268D89CA08D883D4CB7168A184AA\n      8918B90ADF744562DB766E9FC2FCD76E9DDFC8C56A46AFBBF0E9B24C97C2FAB1\n      CEF7050EEEA60FAF2CB7DAAD2FBD78E2F1D9A9C7266616F2F4F9243C5A9F6AC5\n      695D57FBA14E646EB7D5FCCB9DF5E35BDB674476C667C0004CB0CE1052A7AD44\n      D641ACDEBD6F757678F2DCB17DD39DA589574E9DFDB5636FBF3BCC9ECA6FDEBD\n      34AF62B6556B2E2D34025D9CB299A198FDD8E7BFF05F4E7FE5C0C1C99FDB77F0\n      1DBA4760E17A2DAFA7FA81D7B789A68CE60840C366F3AC8B695DF242A307E6C3\n      04073129C0F4D5992AC7D4C524A094F296A5D02778404246040B3D9D6533AC0A\n      E355DDCDFB880619FAB7737EFCC40BEFBCFBAE675DF1D1B36775C2F999B9E97F\n      325FAFE53CA201E09A75E8B26CF94D8910552288A852652A4AE36A1331A67E9B\n      3902359C1C64C08C0488ED09280CB1662233A7F19BE1F037CE5E9E20F53751E7\n      D19AB78878ABC9EDFBDC033FF236B9564F46436AE9BCA8944B6B09A5CF9E0355\n      90470F8654D472882DA90D4F936E0601ED4789A3707AA173F9B99DF7FFE32FE1\n      64EB83F6508ECEDF8AD2CC999B7667A71DDFC78EEE95510EA53275B8DDB97C8D\n      FDEA2BD1F6D0678E7E7739A6B016048D39097C70C02981D24191DAA12B33B830\n      48EEB66E01614AA67B413030B799624457B58281843E20B4E1B628F0F9E58227\n      1901A92E4E13091ADC2927798A44A67B6E0634583EB2E3A938ABEDA04EB3FE29\n      9ADCE874BFDB9BD99FEB4632C4B861B22029C483CC425F771242A732DB770823\n      6084F63F9808917E7AFB996A2BC45CD1F794EE8D9A571CB291844DEEEEAF2D34\n      67A684DD9461E33FF54FF03F7FFAFEF985DFF376FEBCB73D330C54364A1AF8ED\n      B3B50FAB993B6B33DC564EA77F556436C51371CA5DFBF444F357AE9DFBFCA8D7\n      44E81727E67FCC9F0D70B6E5E499AE2A74F9E598E978A67826063C1FE82C2671\n      9D135759A142234699EFA78E775677E9DDAD49A49C54F5903C95F6AEE7D1F2EA\n      1DBD6EF4DCCD9B7D860E1D3E70EED4E93312B02AA9D055A2C39097F3D043E90F\n      1F58F8FBDECCCC20ED3BAAC36396A43B6EE0EB4215046405085C113C70A5EE11\n      6C68CAD0C802938476A8B61AB544700E1667B99D250B165D64648EE186436D17\n      F09F59E1276F622A32B2261297A22770D65445FE56A5CE59C132106372BA044D\n      07905B9395419E522945A9852D49CAC99882524B944A14C55401F072906C4C04\n      1EE3E0C60001599CB30AF79B61B9E77C12AC6E6B042BCB3E70911D9F5C5CE2EE\n      48C57F32401859A05F4AC27C35052D664DE51770B50D312283869A0CFB1369A4\n      94A97E1C33AC1321DE41725B0091E07CC3FFB30B26112EAD0659A6DBDD5A12BF\n      A9D1BE9BD56C9D98016C0CC57231FA34F1A4A42E540DAEE9AACBBE1BCE802E6A\n      31AA2C8DC148C74000CB65A028C43CF42BA496474A019202D8830BECBC34854B\n      71248CE15C655D7D7BE62B8FDB581004EF591E8EF18A948C592C7B14084AA053\n      897E2DB3221A035C8B3EB480064B52B59890BA756C1216D7F599BEA3B94CF30C\n      C91E1522E441EE04C21339DDD1A96E32E88B8886490B3024B8CFD480E6AE8471\n      4B9F9198A2A90839425DAC8991872723A7AFD8C73B37BED6EF4C4A77689111D2\n      D1CD35B68809D8AB20346FFBEF7AE0A1174FBFD84FF9F7DD71F40DEBA34F38BD\n      C751EB00C7BC8193B0BB9F3B36B2B3C9896E8A2E8EC227D2AD17B27E2D163BD2\n      D62F311069AA03912E4C256FA6C863944F046267F4FDC1F49B16173E71F5C44F\n      3FF450D36DFCFAC9E3DFF5E83DDF353B496262D59762DBFBEC8533FFF7979EB0\n      F2EC27EE3AF09686535331D1C909CCBE49C6007B060F03AC2560DA59031D6070\n      98D25FA79C95D4185932178A9A4C95FB80021723CDF8C0ECF2E14F82C2A9BED6\n      C23CDE12EBDE5BF89C3652FC8939EF85A75EBEF7C8C1D162FDDFBCF0F2FA80FE\n      C864E39757275A09EF383030726444B06390611257876597BF210B219B12952A\n      AAC7633C8D81C28B14AB18F3268D35A9A35B7DD7E28170F348B9C16773F56B2F\n      9E9191F546AFF6486037F968F5A185C33FF3EE742A49933EA82FC98CB55C1AD8\n      6C6BB4FDEC2B53FBD7F2BB17629ED5A0213022AE308DD1193BA71E635CF2EBA3\n      9BA7D2B77FE4CF70B4FD3EB0FE18A9F0D276BA9DD426A6DD8559B26F4AB824D2\n      6F3957B5013FFDB927F67D4AC84C588E4E2C0EF0ACF5B1CA0C25003A4723D68D\n      2B0019CC5471E1894D8D5217B68C4E21CC4B8DAF9A6549468CE956D5BE817C9A\n      12999118CD743B28509CAB24275C27081E1216A420A6DEB5E3C53EAF77AD936D\n      FA6FF24B8FC8E99FD86ADB72786A5F363972F48B5945ED696A7FC059105DDE58\n      2C7040744F472130CBA27BE866DFC416AC7E04791A62600CB12C5124DFB1AD2B\n      59E6E060D19BAA3BF5E6DC5AB72F6E5ED9FABAB5FDDA979F999A997BDA4B9FBE\n      75F3517FFA1D4EFDE119F7401DCFE9C39A03F6570CA35E1ED839AA61B9CEF053\n      16F93F2E9EBB68F13969FDF2EA1DEF4F89CFC4BA95D98AF920BC95EB6792197D\n      5D7DF14744C651AC7B41FD348C28A02AC00A1CA9EB34D3459227601FBB49E589\n      DEF695C1E08EFD0707483D73F58A74E8E17D0B57CF5F3C8B6D585D8396949703\n      923EB997895F3A7AD7A17E9CE779D7F89B39522499030918613B81EF1F33A4EB\n      650EDA0A66DC267131F3DFF66BFDB84F6DEC633123F811D75FA6B401B07E99B9\n      287380E6844B398382AA842B074159AA8EC992FF6D184E85FFD96E4FA08C9299\n      B16383DF5320EE2B5D96A6FA85CDEABC64A2EB744B41ED152B43BA000513B3A5\n      A6559FA6C64CE1CA76BDC2C198819EDA9BFBC604B8F249A840A0B6AC8C9AAA67\n      648F0C4DF57D94CEDCA592B12C44FA0B565EB1EB2F02BB2AE5FEA449D112BCBF\n      15A81C19FC472CC980A02E529B320F95B8D26C7CF6E27994250F2CACBA694248\n      EE67D131AFF58053F74152192CAE014B4E81572D6519578A444F8B6E704CB134\n      43CE94B9804420A458134965ECC689AA581286D3A77F61312C4B5D005C74B315\n      D1A1D8BA17697C4CBB2E2796A5EE4435681B7781A4ECB1D5EBD6B345C35739A1\n      C9AADF46E3A1D91EF1205CD24441CB8A00C3DCEC3FAB600D080B33476512CE33\n      00AFA588F5614F318E740746728E22A5D3056C2CA1EAE2208A9B5B6610257428\n      2111A531ECC040F13DB44524333FD72D5BF0743AFABDF56B3B2E6EC7FEC04A52\n      625B99E3906C4442C5901FD347E6167A7274BAD3FDAEB9A51FCA6BFF8B3AFFBD\n      DED283DC19B238F2F3A9444E65C4B141DA38206E6291EB3C4C457A11B776FA3B\n      5D1C5F50FCB2E49B61A2CB7EEE0511B414F9AC1293ADE07CB7FF7D93EDC9A9F6\n      6F9F3EFFFD6F79F8BD7E3BBE75EB8DEF7ACC4E071374EA2FAE0D7FE9B9A7AE6D\n      5FF9C9B5E50FB5F7CDC115805E44C8543F84FA44C4A04587807D2B70218CAEAF\n      5E421955A57A505175C872345AF867998C636C80252E8851D8ECF6A9C19D714A\n      11A732D5AD764E9BA9F5E262F03BCFBE6A4D4E1C393CFF9BC75F796188BFB7ED\n      FCC7FD9313A3BC1B4C8F5CE909FD2FB0261CD3E7F7B0350A34E29E47688CA91A\n      3B59C3301F9E6D64B82258270ADB2214B4C575F1C2A46E3B6B5F4FE8FFF59513\n      C39CDD59634768FAF8A3470E7DCF31FAAEFDBD9D73EC5A47F994B98C78D809FC\n      E4DAADCDB317971FBD2F9F6FF25CE75102DB4E07529ACE0FE0E06781D41FEA89\n      E14DF7FEB7FF26969DF744B9BECBAE3D20D9F9ED683B62AD6670F8009A6F757C\n      309BAF9DD9BEF09B7FD678750234F97C8F529AA71918360207DCB892411E3300\n      2430682706B7578C437051649AAD05C10C4C01C169DBA2605D402B941A34EE92\n      73D380E89B9B4992EA075977843A1102633B55C8E890C90C712FC19CD84FAAE1\n      9F77D73FBCEFCE375F4811496F4EAA7A68084AD4987899A91098E4E998A9BB41\n      1F12A1111A95B85809A1DB42DBEE4CB4BA497E2687AE0E2EFAB8A87E839C53C3\n      6C2BBAA7B6EC365B687AA6E12F5DB870EB4B174FD61C7C72B0F3E737AFF53059\n      B1ECBFBD76E031C73944B82F0692A6E0A827E96810E749D3CF40F4FB6AD3FFDD\n      CECEEF6D6C7490B897D9FFDBDDF73E166516CEFB32AB63D7CEB39C6420675DAC\n      707445AFAB75D0D4018421C835BA6E4707CD7494A85C3027D3D911D34DC9CF6F\n      6EDE1C0DEE583D7099A65FBE711DB9D6AADB0AD7B76F22AAFF926D88C529B31D\n      14FDC0ECEC0FBA8D208976405C81B9665C0A798C416F94F13C065173DD7EE14C\n      973D167594554BF0C052B7A6D8A9CBD7DBBEBB685BCB041FB099FE459D5161A9\n      0466F404043D806984845540FB4B587F392B346C21047BE4C2E705D47960AD8C\n      41BC1BC871A0850B752357C6621DE6871294489099202218146779862D208629\n      5190E18C099051B68647CC182F14071C576289642C93566CCA505907C94A84BA\n      4827255AB550DA340F805BB031C6B21C4576AB9E912AD1021EA10474800CD52E\n      4BBFE805F7047493C5C1350C58E606374B75C9132AD5C7A8A354478908C91B13\n      ADCF9C3F6B2375746A4E27425DCFFB79F4B0537FC49F70E284C2E368F88036CD\n      8DBB78A17441A02028AC32E06AE858AF8BCE54C184C5086F92924C4D0A4B44FD\n      A72DFDA77545ACFF8A4D987E05A643435198CB92752949C1AFA8726125BA88CB\n      596FC53A2B3264759A8A5F1132EEE7763BC5B1D257D14412C3B418D3738B1284\n      18C1ADD79D4970A22F2C108834559961A6A192DA042B953DD860FD1402F92655\n      3C15592EFAA9BE88288759BD6D21171BD3755BE58902ED069D43470EE24C78C6\n      0F3CD4E1C2A9AD23F6BBDDAB4FCBC1E4C08F499271EAA19A44718C1369819875\n      1B0158B3CBD59DB4F6E3B3FBFF65F7C4E3B9FFA1D5BB6EC45B5D121D095AFB22\n      1D04619ADEC6966EFB7485A9EF50441BD2D13D48D253F25C869FC992CF5CBDBC\n      6D33C9EA3C0F114B21CF67F63EA11B3D6B03A3FB1AAD87DD76FFFAA51FFDDEB7\n      1F9BB251283ADEB2AE703FF1B94F3F75E9CC07EED9FFF353FBDD38127260054A\n      A491452D5D3759C20A6258810F1DC92DB86039C1D58AD7D851164F08B8BC40CF\n      008F832800CFD450A7FFBFB6DE0440D3B32A137DD76FFDD7DAABABAAF7A497EC\n      3B4BD8110119641405F52282BBE2B871959971667067B87A9DAB730725A020E8\n      1D71608C8048804012208124A4B374964EAFD5D5555DFBBF7EEBBBDC73DEEFAF\n      4A82C636C6A4BBAAFEEF7BDF739E73CE739EC7D19E01DD21B9039E72C9517FA7\n      C415342585F63A4DFA5F9E38DD09821FBFE1EA4F7EEDC17FCEF51B66C28F1E6C\n      4DF6CD7A389E84B659F6F171EE74D20979E12B7E7E9C75F4E9E71FA76A880120\n      8F7B4E8846501E785032E55213497D6225D35A84CB74EC43F73DF644AF17D8C1\n      9B6F9D7BFBBBDE14DFB6A76CE7DA64DEE96EA152D60A20E8C541B8F5CCE9BC18\n      CEBEEC263483D590F31C751B129046AB2B2805A19883BBC6534ECAB97DC7FE90\n      16EBDF87430B055958DAA12E2E6E952B9DA03926AE3FD299AC05362CEF3C51FC\n      7F5F57662FDC40CFF390E1991610291165B9355BDC74769342B875B861C0D03B\n      AD6ADC387D0AE6FA39D8118303293CB41CD098F947DA72D5A85F1997A50CCAC7\n      B042D9B4A47989A0072D99D0910C3E4934B443E99D6CB0BB9E79E27030F1E278\n      B651A0F941920EFC1109063D811D53C3994A31CD3C9708B92DAB66DA73780423\n      04794179B8DBBCC6139F44F0EC945FB00B757922EFCC65E645D154DA9AC8A6F7\n      85A9BFB8BCF2C9E513B717B57BFDEC2F9E7DEA587BFC9DCD3D377133169A96A0\n      7156FA280A6986B9E90F21C3D7BD142A73F658CBFFA3E5F35F4B325E966FABB5\n      DFB37FFFE112977A1353B691169FA70C8D7D15662214D311684A2A133CD13644\n      FB61B16ACA359592A2EC7AC18A212B503586E2FCCACA627F70FCC0BE678AFE83\n      97B7087A250714F2AFDBE5C2461CF54A41E6A9F98DFD57BC64981A9D77EA4101\n      0561E966BB10238CC9ACEE402A04000667B0405900C885BAB00059367CF3686F\n      A525C2F9C03FC2C551C6F6481A72A303F464C9B0CB8D7C448F1A09E848544BE4\n      2301CB5DB204A9388EA8A286C65CC6596B4104E766D4B229192B8883558EF08D\n      1C06E5466DB8678F4A892A477B01E9C832C83746FF36A67CAE25BA0DA5AA70F9\n      CA95A59401CE42FEBDB66C34BAABB81D5841BA6AD5857D1706AA3D41439FCB79\n      78709DAEBADDD194A13BF1DB8C968E475D3DEE9452C90E1FBD6A43EE0A133E07\n      AC9C312FA41C67175E19C3F3D498C4D21EA5808A36B5CE28B9D4A8FFD399538D\n      303CD818135942591197F9712B5FDC9C8A208AF29D35795CC5C5CA193E1E7E42\n      67A38A31C4DD34CCEB82091F6E1AB7D996D33BE6D58B803F025901031B942C70\n      C64A53950B899730D7FC6495C2D568D3C2C1C6DDDEA65B77DAD5232515B99391\n      DDBD975171886DADAAE07B7E3540CD882E6347C46E67B8B7DB41DDF9D3D458F3\n      5D1193DAE7F570762C0A1060992A8ABB4A11FB07C8DFB3CEA00E3DC04B53967A\n      ABCC0604758B21A4338D69071E8DA19905788F9F9D5BA8F750C3A550420F29BC\n      1D99C8E82BA6F7898D8BFD9C43F03539E52406445A92D4ADE8C1ED302C4232FB\n      94F55E3736F199F2E2F55DF1FD87AFDB94C9D94B675F33B1F768E10368B51EF5\n      08161C2D2AEB99691299F01EF5871EF15607E2E17AEDC39B17EEED0F27EBCDB6\n      31FD413F8364A7E007F74C8C64887DCC8F995CDD5E7DE7F143BF7AF38D0F2F9D\n      51B30B6F6C5D4197D67FEDDC037F7BEEE9FF38B5EF87A7F7ED29D3815AB735B4\n      BA037C1428DFCF51353FF5019E56D8133D3E1D10ABACC1AA511D769A85DB2374\n      8B9D3447A15F08E4CA699BE346128A5800F4863845B5B2B2A738A98DD593AD5F\n      BAB07CC6D8F7DD76EB3FDEF3F09D4ABD6636B8E3406336314BFE385CFEB1A26F\n      7157E5859AA5CFA3533D8FB7462B3161E684FB88EB69542C2F38DE908871F5C0\n      258EB4560A8FD60A2C9C4C106F16B5FFF74B0F7CE6ECE557BC7AFA577EF20DC7\n      5FB2BF6C16B6A63D00A58B03D5E9A5210D261AB2B0DB8F3C51DB3721AE9A4F14\n      3C0C273C0DE74448F47C81BB88EC048D0702B2A1383CBFF09F68DAF99120C3F2\n      0E371C7C493707E5A9CBC3B51E9D9F6B1EBB1A9EF3A50F7D61EA64A73FB71F82\n      32DA30E54A669A2545A95489447B44FC5CE179858B93E322343643AB90517138\n      511E08C5729C0BB9C4FEA57585A3193D22142A732C04ED38758640F2739B85DA\n      E168A840E1878644DFECB3BEEF7FCB2B1E7EFAF45BE7AF9AEEDB21831F5BB21C\n      6A0544C7B8762290BB5F2542E4497954443EFC70AA9A59EAD1ACFEF9AFE7F92D\n      AF6AFC816ABC527A791648F948691E4B7A2F9E6A1D83C4D13A984D1FC9D63696\n      174FFFFD99A7F676BDC766A2CF5C7AE6FBF71CF8512F5C20BD7AC462EA8B0242\n      114AFDF5866947418DE4B35E2A1AF5AF70F5FEC5B38B5CD687E96FCD1DF88146\n      348D1EC470C98A2094E8D988B2FD98B1B56BDF43EEF7391B000C101E545CDDB4\n      582B00E4223CD894C1A3DDCE79934773E3E756D6CE75FB371CDBBFD4EB9FB8B4\n      89D30C1B31E395BC83EE54C835941052BFA7D17EC7ECDC7C1F779813DF471E85\n      561E021539D04557E8CC1A1FBE15F13288980589A8D70FE913B6737EE3F2E1DA\n      C415326C51722814F33E09217C70A27D387EBEA5122F952BE22C4747AC5D594E\n      B22B59E2E611B8418052C7D82655AE6A73925180D79CCC3642073CA14A01F4B1\n      50C83A653DF827E76CE0DA0B58FA94E8623812DB73991E9E1BEE99C231303B4B\n      BCCAEC2A21B8BE8BA9E888680786D4105E952CA6A238F2E70A1AB3035315233B\n      6B10CF69CC5641DFECEABAE11264D5DEE72314E574318C46A758CC970AA50098\n      735AAD7AA73B6D55A890D04E3BA1A44BEC36D4854625D69C0FC3AF5C3CDF6AB6\n      F6D6EA22CD98CDC2223B5E8A974CCCD65C36D11094ACF58994E8446D3200B744\n      95AED6F6280F21FD01782F01EC6A0E88DF17F99487F30B02EF14939B82C3CF59\n      59A07F85B49822206DFA4CF4EB29AA5A1A171C2B65C56AB4C82A0D1A52F9952B\n      5AF57AAA29E0A8675AA9D230D7BA7E6E60B8CB47AA4E03A3E679156155A1577C\n      D77FA539F3C27FDEA9F8B0B9CB9CF770C5C4D5D54465A4AA88F3AC1025DA1C23\n      9F1BDCCA876304F5B7227949D3D49470A60BF4EFD8F65448D0FFB62434D4566A\n      D5F774CF2B425C48D4DDC0BB50F34EAC2C7D44F50075E90143A552FCE8194EA6\n      DD749B055CA304A0DA23F9A23007FAFAA513FB6B7B5A0F9F7CEC7B1AE3B74CCC\n      D0A2F019F17020AD22CF6F66641C426EB141FD84787EDE111B7EEBD35EF2E1CB\n      67AE9B3BFC3A7F2AE92D9FA2C3D3DB8333FDA28752C3AA6EC830E0452CAF26E4\n      57AFB8E1D1279F98BFED9A771CB962BAB097B9F8F7DFBEEFA1C71EFFA5E3477F\n      A8363936D81A7A59CF834B8FFE0795A546A490228AFB1578CF5C8932526FB1BB\n      6BF4BC62A438E09109699115502051C025428942C0991685274592D35349D99D\n      9E79E5C6F6CF6D6D7D697BEBE76FB8F6C45317EFCE8AEF9B941F3AD01A2BEDF9\n      A01D1235960D067E4DD0E7C8322F24588D026F055F1C91AE720D231504432A89\n      E357721FED634B7893F0991AC6F39997F3211C784009C1F889CB834786EBB77E\n      EF35B7BF68BFACE73D9E859241AA030CCE2E77378AC1F8150BC30BABF9A9B363\n      2FB93A9D8290A4C2D21975A003111A73689C5939F515950B1E93E8D8C2F46FD2\n      A2FF732CCB50F810E22E296AF8D2C96069F5E2F98D2B67AFB617F4D6671F09B6\n      49B26F567A9ECE0B2F3751665592C339CB1C090CBE9550A442CB1AEFC3A8FDC8\n      B8A878034EFC1EC711908F19320C511D06C5641D7F90B88122FCCEBC2C317E68\n      2C0A6D5192129D9BE0BBF83914551A82622D65199717000E666626F121E52DEA\n      4E9D885925D2403B975E6C7E4122C4DE38926514954C441E14D7AA1A5FEE48BE\n      EE46B7EF9AFD542C8394E9D0FA4C15AA19DCB3D25D1966FFE6EA85B1FE3098B9\n      6D3071E8E4E9FB579F795CAF05776C2FAAE929789A3F323D7F73DE596851B823\n      F0C64AEBAB3030653118F4D6B8AEE154DF0E9BF54F773BFFE3F2F296E78F0FB3\n      DFDBB7F775357F1C0058C94B5564359C92FA26C08937455327EE6893AAEA5641\n      AEA2EC729AF50A2CE4122E37BDE0DECB17CF97834357EEBFB0B4766ABB77E0D0\n      6C96E66797B7127892AC46A84FE8A66346630FE44A4D7F72FED0B55284A680AA\n      A82835A0642CD0B519123DB02AF710247027830D980512E236D567746F31DF3A\n      D0681F22F1F1A48C3D3E3B1686ACD43A0903B4B0C07D6E546376C192A1EDFAF3\n      640CDDEB18497152E344175C0B045B01057C34381A0AC333C14933FA89B9BA84\n      B9F2D20539642D31CFB2C4AA1215997168AA42D1C912F86F90297D4342457C85\n      63426FA4AAB9EBAD46ABA5A59DA2B46A899A52EE8EB52A1BF61D885C55B13BFB\n      88DA6723730937D6C2B5A48AEAE2CE4945F0C1936B468AFEAEF93A62DFECAE05\n      570B90A4F25ADD194D3A7E1029094929858F8189D0A8AEC6AEC0F920FAF2A5C5\n      280E0E8D4F46000455DA2CF2AB497063732270ADFEB228B0E2817B85BB0368D2\n      8B55912340C8AA59CA705537C7B0AD3A5ADF9B2780E9E197B4D4AB9298351E02\n      0164428DC7B5D9F638608BB1A2076741C28574D45AFC98D512E6C8B8D7D8E7D5\n      6E666733A29A41D0519F79248B55F5284718DF2121B623F946769C5F0CD9DD16\n      7DC13EC6086D8C1AB0238511E5CE49452AAEF6FA475865670966B4A86A504E8C\n      E1BAA2EBD57378592A2C480D3DBD44A2C8208302DC18653B924045603C591032\n      2C73E67100E67003A136C4DC0975A31FA479FEF3D9C5CDEDBCC070249C3E95AE\n      98B4F081502857509C55181D9B40EA726FAD71DBFEC38F3D7D628ED8575D7395\n      E87622ADC7B98C33DBF4022DB997C929019865BB80289F07FD847C6B8C7EA47F\n      9E9AE076D23E34562BA412093DD95BFD66776345F10191691CEB1AF793C14B83\n      F6F6FAD2B5C7AF7AD7EB6FBB2AED4F90E9551AFEF6439FBDFB3B4FFFECC1B99F\n      69EF63F9A013E1C6043A8F3A07C22644494B31113235AA3676440D8C5BA4A92E\n      2833238188044E14859AAB44221CC44A780A8845732D8B58F8C38CDFDBE93FD8\n      F2FF60E8FF5239BCE3F2C55BA7DB9D813A352C7E6CCCFFB37DE33121E7C27A4D\n      976379B21DD67C77F49F2FE7E65EEB48F0DEB217621E4EAB061E71A349267155\n      96782874850C754F92C8A0511B09CD7464C7453C3EC69AB36C6AACF406D402E8\n      876C147A4E54D7069ED84C7B9DADDAC4E4F97B1F6885F1D8CB8E6FD6531F3061\n      5A2023058D794A236D05DA1C7101E2904F6B572D4CBF8FDADEAFA11526EEA726\n      3C4BEB38FAC094D8BFD8B3277BECC4F6C6D39BADB15951AB53383059E9E7D64F\n      01C1E6252A9D63DE8233C50B2495AB4A0DC0C13FE668324800AC04B0281ACFA1\n      BFA8234317889231613938C92A68F99CE41DA4B412B7EC4BA3E01AC7436C6CC2\n      2F3CAC949541E4F745D92D1EAB954FCAEE8B49FDBAA57C6BDC67238B1C7870CC\n      F325CA3342C0F1B9C4440827C27927ED36C0FE05FA7C6EB44B682E743B17F0E9\n      96276B9F7FEA5CCDB2B75E7BC8EBE5E1C44B37E2F6FDE7EEBEF8C423B7D01B7E\n      C09C66BDDE5BC7E75E25E555524D45F00DCA94B082C890F874507607C38E67A3\n      52D1C0BFE07B1FBF70F11F927C2039A4AC3FD8B7E7D5AD382A4998A21B64A796\n      94C6F83A184AC8E0AC5622DF1C575C218A091F32C5BA52EBD8C044BFB16D62B6\n      FDF8AE95B34B7972D3D1C32B17571FDFEE7A936310E42FAF6FA670A464801798\n      0E6881C537A0D7EF0BA377EED9DF243A6746A6B8870B992F83405ED835898B11\n      703672621281A57A587A9005EF1FAE0C687ED3F8EC026E28E9973019075E23F2\n      103912253D51328BC187613B4E10C8E244A00805DFDDD8AD84745DDBD0890ABA\n      71380AFF9438FA45EE482594869E0A28511458414B035849013A3705FC3DA041\n      A8E4003045C096CBC1A56230AC01D2B046A0315150D858D9861175CAE7E1DE57\n      3BBBA3CDB491BAF488B8B8B3B38DA873E4A245858BE328C68264623AF280727F\n      A2DC9929E25585BFAAEA65A41DEC3CDC2DA9E09B63FD58F7692A508589D35463\n      4B27D4891D515BFD7B566D1896CE2B67486C9508BBC6F4AD015CF9ACEFDF75E9\n      229CFA6BF6EF6FC31FC986E3A5BE5ED6AF903E412880967ADCED5020B801B402\n      590DB0020E5321372B2D6816886D692E99EC72D15F2FD413B968077E33F442D4\n      5D82DF04D7DA006C91146D431A528E8731D4E0AFE896807103E97B4E52AB5AE0\n      23CE2A863D4F8F77A430506DF23B324EC503786EACE7629C61F6B98BC5767981\n      A3F4697744EA9EA74947767C835DC464A3F66C95EE5075BADA60ACE83B6E7F66\n      3452A2D54A080A1F22BCE0989DB05BE2949BA946AD5151699DBB614B9E43896E\n      CB9C2E8902CDBD2D5D8CEC122FF724E20A1D67D26ED9BC5932599A24B09FAF87\n      779E7AFA59ED300FDA49E240B6EADF32EB218B44945041CF0FBD0D0EA953BC72\n      F6E0C6D2D9ED2C79FD8D472787799675E7EBF52B37ED5CC6B79AF062C4B80FD7\n      5C53F8BE24E811FD08EFDD2DF2CF5F589E68345F3D377F652FBFA68CD35AF608\n      CD1E18906F6CACAE42E58E9FC8D40090EB72A6D97EEDC2CCCB03FED69B5F2652\n      F9AC1DFEE677BE74EEF10BBFBCFFC0CBC6A6A549C7888AF23C176A2829D39C1B\n      E956D9B493A4607634A6876AC2BD3CB7A7EB8A6C56AD1B790C20620147046297\n      D4812CF103662C898C503AFA7C92DC91AD7F31DAFF3B01F97F164F7BA4CC3487\n      9BFAE335F9DFF64DC5942CFA6164CB6691F4C2BAF75DE2F8BB2ACDBB13413672\n      3571B44A67A582FE2A0C87E790B5420F958E7CA45552345956AC11C9A9596FBE\n      4927B511CEEEA9241C82A6C8512F974AEA8534144EF48BD3829467D79EFC9F9F\n      DD77DB0DADEFBF65E8F5206AD6348A2FB9FB4FDDB603807E6C43098C46928647\n      E6A6FE23B5DBEF856A3867055C464FC303284A03C7C197344ACF76D892DAF8CE\n      92EC9A71D6CA8B4221A5D3B044D9CC1404391C70A3BC14B540210BA65C07F069\n      20D0E05A3D9C289CEE50A83A946255347196A0682302851B147474C4976195EE\n      011B31C9508F180B0508BF055339C985F32C8752056A46833CC10E1BC8DA67B3\n      A5FE187B3D6F5E7F29DD8A83CA190D19658248C034B8540C1988E28C50C20974\n      DE492F3458FA9783DCDD7F5F2BF2C4F71E6FB63FF3F0896BDAF10F1E3DCCF326\n      AD5D970A7E66F391AF9CF866A9E73F202ED716D7DF77E0C04D813C588F82AC80\n      F79006E8D9111581E9996EBF285169232F6AC159EE7DE4F4997FC2E503313DE8\n      7FF8C0DE57C471AA3424F62661B9DFCBB9A2A5D899C3F06A8B00375E84D7D5E6\n      7251F6014D5299E8728B163D197EF1E29945A36F3974606D65EB915E37091A11\n      C085B49B8A91F5063EE342C2559E13E45D3333AF9611C4CE1E637E62634353DF\n      746D4E33D3F1658835BDC14418CA21A3BD429DD958B3A1B86A6A7AAE974F40B4\n      6D05570B1452445633837F40F1761441870BC4475A958EC04935633B587DA421\n      5F71EA9D4BAD0B8125B6ADE20400ACCD05474239F2FA0CCF6D000F0E0A210A49\n      5A26211B08DAE16C55DBEDADED222FFB833E3CCB46A3DEA8D703210381FBCE4C\n      A337B72424CE14613B5B0008FE78B5AA5F85E91D970814C8206EE9023E85D329\n      C6AE253C74512D63547B8F8CE9B218B53F5D3B8E8DE832F897363BFEF428443D\n      E2EDE84A4DF479811FF308777524DE0256B1678CBB8EF09C734212488494758D\n      EE193B203637E624215F59BBDC2FCB5B8E1C1A87538C8950DD128ECD19782A79\n      2171902ED1761E573971AB9290002A636351C9D395B28520434EFA9E2D43CF00\n      ACF651A1521A172E708712EE2C3A82C10F2650E046399722330BEF82E368DDF5\n      D2D037D8544A3E7457A3C7318346BE1623A652C54DDD21E63AC2B8CB4B8A5592\n      DE3B19AECA682351851D213B3AD234DF0991A3AD44FB3CD20D1D29A01247601A\n      098ABB92B5E2B0BAC75D695ABAC92B14C500CBA046169AA1B50BAEDF03E00614\n      82C41847D842861F1DF85B0CEE760AFF7933E68BB650899A14CD5A1493B2E083\n      04E05919C2816CFDCD60EDB3BDD50E36D320E686B4CC3C34A606F4E735085AAA\n      0D22313ED45B105D843818B4F2325F19F45EBF307773D83EB77A66DFDED91B7A\n      62A167B6EA2C369037F27618FBB86727E1149E559D6F49FDD7CB1BC9F8D8AD73\n      B3731757AEA3FEAC0FC1A0BEC4C28BA6FFC0D2D947FAF95078435A6A09C92D6A\n      64C52B6BECBFBEF52D53998AA3F1937AF0970F3EF0F5C79E79CFF5D7BDDC6FCE\n      A43D01179A6650FB24507158CFD31EE05C5EB5EE8DD32C410B70E462C20576C2\n      AF1A87CC0AEA5AC06880C0538DF5861445E04145E8ABBE1ED44BC05D63FF40F5\n      6F2E9FFC726DEFDFCD4EFED9E9A713F483C5B6DB8FC4F4FFDA3F33A6E9060F24\n      49635D245E9DB95597DD66DBEE06C5486BC851B1700A5F598609DC2980D2854A\n      8E626492F1C847794EF87F05F183504C10B66F9CCDED83FAC2D08D9C678CC5A2\n      04842C0A9AC001E6D4833F55D438E4C2228E6A7DD1FBD897B7EF7AB07DC3C1C6\n      BB5F65F6C726EF0A14F7289535501639C50B847BDCB1B98988887FE5FCD47FA0\n      66EBD771A28709AA84CCA16CE136BAE0EBC73D487BA55FBBCCEC131BF4B1B57C\n      98400843CD971E443FA87B701E013F5E3054B2C015C5C40390AE7581EC3EB859\n      4996431C97510CC969677F7EA47C016007BD97E1F4579646EE1AA0587E356B71\n      8910822333397CBF0EF545E9D5E1354100014C935A25C61E1C0EBE33D83AB67F\n      FECA2459282D144E948DB67051BA4EE0823FDAF904C48B03836D7EAC5925DDB5\n      23A1FF320BEE4E743D43FCA2DB8FEB0F04639FFED603AFDC37F686FDFB04D92F\n      5AD7D32C5D59FDCE874FDCFB8F9607E3EDDAD9F36F1DAFDF32D96E06718B052D\n      C02A79477B34A5FE70C8B31E266522D3A1C756C2FA1DA7CFDF0908A2CEDBEBDD\n      FFB5EFC0ABBDF0325189A8355092B85BF838F969E0A365431FDB8D5E0EA51B14\n      40744995AB4A651420071990B2C3F3C4F85FB878E63C67D7EFDBB3B1963C3628\n      523F0AF33C223D256CA248CC498711A8ED00505C13C7EFB9E28A23DBDD9E2E86\n      6158D3BE4CB2BE57260098733D400D2128E6505D0230D2394FDF976CC10B7C45\n      38BDBF6F22A6C3C0EE6D34A64C82126AF0507DDFBD29233DA49655CA9B5A403E\n      C311BB2C79A552BB331C77260D5015690830DA946EB8C3D8D8B6090A53063C09\n      78CE59592A96695FA1EE7B4119DCE965AE9EEDACDE9DA60FD6C89E38383ABE67\n      5AF90B24982978A3AF6B8515A892A920B263F74B92CC096C60D711BE17F60865\n      5AE4D5C2BEA9DAB02E27B77306004CE25A8FA92439059E0A546582DC80430A82\n      BC661F0F53A5F3A577B22BA9CA14A4FAB8438BD211963C576FDAE7E800ACAA95\n      46DC1A5B9A1181147E1E788055222C241F10BAA5CBAE32A9AB084F287D4F77AB\n      AFF58B8E1F6E96D6CFF2A942DD1434A73426C2DCC78CE06B0270A186BB708A38\n      3144B8D9B2D47580C80552E7D1331235EF3DA73BB0EAF840C82173A9C8106C7A\n      55E66AB8FAEE32845D6A7A4874D458440847C335AEB5659CCC4755BC19DC15D9\n      E50D593332BEC6B624232343ECAA395A6007938D66844EE082552AADEE77EE7E\n      899D5C689EBB79EC390329BD4334722FC8388D62BC17C6AD51569C03C7D4750B\n      00D8A32690FC32C953384BF0292977FC08645E57171F5E0577A69FA56ED4866A\n      DB642B2617197CAAF091583F39D83A9247D7C9769767039189BCB8A633F3A583\n      637F7EF9E4936B97E1D291208ACADC331A17B60B6F9A200567C3E78E86495097\n      12C2520439D2DCC2EADFDB9C7FE2F2E9030767AFA6F16C62FA019DF5867E9671\n      08F6B20EA9A5990CE1857D93D33BB786A74B3677707AB8FEECC16678ED963CEE\n      CF09C03D7E67B9A6BE90969FBBB8D94D1400F0BE0932BF9C8886775C7DCD6BF7\n      EE2DFCFA58A7F69019FEF613F7DAB3CB7F70F8BAC3A8C9B94549026738659E07\n      1955051D1FB770E181691CB79342E9C6D858D46CB17A8D489F16453648D23411\n      5B0392F5881A38790AC973CF2FAC8A69CFF4C70CDC95A93B3DFAEEB30F7D427B\n      0F1DBDFA2F4E3ED1CFE0AEC656656F99083F7870663EA35D5C12CF0293155E6B\n      B4EDB25B72ECCA3BEDA82B1847E64602A79B3A20D29498080190FAB5C8FA0CE2\n      3D148556B0787C825C19D9199E794DA901E66DC33B23269269407C9178458836\n      5ECCFA4A353C1D46FD762D3AD75979DFC7F79D4F2E8D69FF1D2F9E7DF3AD70D5\n      203519F8E15044C744D6993672149284BA0112218DAE9A9F7A1FB5FD5F85E056\n      70A3859686CB3280D0A664DFD08CAA96C7E7E15224E972EFAE27C872DED890A2\n      4355AE5335F4201F0DD13AB3CC71F82F88E645DE116C4CF32453A75AD1F941FF\n      FA921DC8331AC24F1B58CD87B2C8B96E16D2B3B470485B5746545537C4ED1EE2\n      E410900A8EBA0B51A22BCF806642E704150F82366400C5BF528FFE2A593F38DC\n      FC3519F0542E3567C7F20E1A9162F84207182CC3242E6BB150F050C2755128C8\n      4747938AE76D86ED52FBAAEB69DC5CBF2FFD7DDDCE30AC7FB6D9FCD437EEFF99\n      BDB3AF9FBFB2D3DC4F6BE3CDB573174E3DF2E9D4FEFEA5F4ED87F7D9B3ABD712\n      F3BA7DA21DA58AF9D286B22835A7DD522689B605DAA834339278FAE264F4E133\n      A73F970ECB1ADFD3517FB3EFC84BA9DF176926B23A843023010541CEEB84E82A\n      1666344AE0B3B1AEC82E58B652788AD9C40C376574B6D38B9AF65C197CE3C252\n      C2CD81430B97D7D7D7FB436445C0E9C22887B0AE44F2AE5221690FF5CFB6F77F\n      4FB34DF5B6B54560456EBDBE08526ABA7A5806A43ED06914D921DC15F95450DC\n      9F2EEFF5FCDBC3318EB61FD931165D21EB26901E4F2A795CC62BCE80A386085C\n      4FADE66F8ECBC00A9BC6A9F58DE8465EC2483030B5CC40766268B46A20E77520\n      F9716C3E239D202B9A80C7134913A6FDD6B3E3B53BC3E2CB6478AAB3156D1637\n      F8D33747F17E9E05BE2F01F143F157002E4AF127F0FC6D413602B6E293659BAD\n      517BA6D61AF47B493A4CB3B4DF1D428AAA53947D6A28D650A645C44CD06C45D1\n      3C391BC78D804B5F19DFB08830A8866B44C45CC4168B5A08F7D8F9420D1DDC8E\n      703562B57DACB14DC79CB675A5980328DAD6ACB392B12329095E299F55798FD1\n      5142702C76F4CA51381C2539854ADC24CC0C00EF293ACCCD455D2EC7EC2B0338\n      3266361F1C9EDD832B6F69BA57D07921EADA07F4AD2007EAB459D27100CC809E\n      09FEF2990D71A704D7E59D0E8C2BD19074EB066C23AAECCE2203327D4CA5F462\n      AD7A8ECE367289AB24C26DB5143C5A09B523E0682AC94267B56B9D7C4C25E3E3\n      50BDADF6EF47EAAE908BDD42B5C53DBD8AA2EB20AACF723792F228F3147C39A3\n      2BA3849D162C2EAE553FC36852C89C1043A5CAF73CE46A71DB0CBF28FC1F945F\n      27D5DE15431C5FF9C68C8870D6A57947D3C5BD2AA87E54A9B8E50A975331C6F8\n      43CDFAE566E4DDEBF51F2ABB351DBE48CC8DF77828FC6ED9895871211C7E7C6B\n      EBBEAE2A8DA43C3000908B829528B96190E45F02C61FBA6D4500ACF0BA33AE27\n      2CBB76DFFEA7D62FDCB06FEECD76829FBD7461825D3B4EE3BE9DCC1A110934CF\n      1A2C6F0F8B41187CC86C7D34DDDA33B577AE93B74272D560F8BA785AF7922216\n      B1E7B7B4FF2D95BEFFF2D99394856523C015DFE4F689C66BA70F1D9F3A74D335\n      7BA2DEC67736977FEBC1870A1ABEFFE0D15B36168D9FAF9A302C6BCD00C24587\n      B3C82F4DCE505E0A0AD960E66871F0886AFB6DA1485A6C49C8253AEBAEB49E7E\n      A09B01B2CCC34E129493051D2FC3D4231B8D6E52CF78AFD5FC7C18BEF7C463C7\n      83B1F91BAEB9F7E16FADA7C33E8FE08AFD4443FEE181D9A649BB4168348D9429\n      5DA9C1D007A3D2A2B0744718089113AAECBB4D413812D229AF206B04FDF9B82F\n      68C045C3CB7D93475AD5B937D568CD8DF326C0B31C8F858EAC8A50F6520C0DB6\n      8DC62D852A27237E1F3052EE4BDD68D6366BE547EEEEDF7BA64DA24DB2991EA5\n      0BBFFE7D7AA1960AC0F9CC1F747C88915250471AC5438AC8D7A7C1B1D9A9DF80\n      44F8EB04DDBFA07AD7F013714884E8043F5434B76543B219009D6827FF9D8B5B\n      8F2FC6EB52F6A84AF342E5241D8854B38CEA12E5CBF07F8B2CB3B41E0490B5BE\n      B3BDA5B8770597D33A2302EEBF4F155300D03854ECF0E9B9D385A223B1FE1D1F\n      41E6A635C8CC530A4A08E4C5E3B83C87425349CC13B514C2BC7F6FE0FDCDD6E9\n      D74F4DBEB56B00F72FB66A5359E1DC8C2B188A8910C7568020478910C9B2D869\n      41ADD191F315DD31AB7C218914A3C6507873C3C1308CFF21083FF9B56FFFFCB1\n      D9D7ED395CC407646D8A2C3F737AE5E45DA5F8EFA7FB0717E2DA4AFF4D8DF61B\n      A6685DF4520ACF388E5509A9701DEDA400CC0ADC11C06E5AD96FD5FEE8ECA93B\n      756A037A55DF7CE8E055371A5AD04CB3023010F7225BC2D3D149809B535E4665\n      2E20E077687A51914D1D427E4B68BAC4F8E32BAB63D3C1920EBFBEB494313637\n      3BD11DF6D63A59412A5E259246A130C01E8E80DA83DC1C36FFDDE4916359D627\n      DBDD10CA360FD25191E123C0F716403232714E3B8DE86B66FBDCEAE59BE4F88D\n      ED096EB31A2927899DA9C563D2AFA55AD777F8F3ACEA6F54EC057C61A65A97A8\n      2667281A8B7AF670E4BDD452404CD4A490E60A38462CE51482CA648FD635C989\n      EE44C15A3D5E8E820B463FDBDFBAB0B191A603486007EAB58546BD1D458D52C5\n      8344417927509C7A83914DC9D7B859EE0D20F5439652DB43B8E921614DC01194\n      D7040BE013E2B59263CDA60C3CDCA740CA2D730520A488A82872A44D3AA2B2AD\n      E4C930FE1AADE090A1A00C137C5E896A75B0629572D75D821A14C59B1481DC09\n      791422A1A429311583D1ED29904A9A6544E7A8EC8A88138B42A22132BE90C952\n      608BD22682F6147C4B74E1BC64CCA2AFBFDA1F74F3E2C689E6441C0F87459DB0\n      BDDCCE1356D7A8CFABB1D95FB472334682004A3E8E733F89C6F558DE556C78C7\n      7375FC545E79E27EB78E92D3F818D9EA56BF1DC9839559805B1871468286EEEC\n      8138519C9D86E60EF953DB8AA2B323DF5D99785AD7A8842F20B0092B5D9F1870\n      6CE15232005F0F770AD0C31AF31F3E4FC01AE868A1DC8220443B0FEEBD6B351B\n      A72A525921BA66B275F61AD598D6ED6195F84D2A15128214713C8DD832A695C8\n      6DE560B1CBDBAABA5018989190ACB1FF26A1EC877393AB5E59F69549845C31EA\n      F1AD750855C726F6B606A49594033F2F7C7359F0BFBCB0F88082EBE5C7251A47\n      17F0000BB4D3844223267420F0470D4A242697DC34959D6B342E67BDC393CDB7\n      350F0E4F9EDAD8D7B82D26AD94B65523341E409A80408229322FF84248FFE4E2\n      E90DCA6F9C989A0AD8116DE70B3A69C4B4EF27C53008FC31397176507EF0D2D3\n      777B80A0F8749AD5399D9F1A7FE5F8DE9FB8FDA6B912B21DFDF2C6E93BEEBAF7\n      96D9A91FDD3B37B9B50C019C88094D078C6C6B1A025AF5942E4BDB6F4FB5AE7D\n      B9A8CD69DF167EA7AE4CB06EC8CA46A9BA6B64B1D92371D14B86ABBC8CCC202A\n      99CED12680923EEDD7BC2FD6C8079E3D3D6FFCF163579E3C7B7A3B19F6FDBA50\n      E5BB1BFEEF1E9C6DA9ACEB07F0AA42A5D4CEBCCBECECDD3E474B6498021D8076\n      931F89A2C41C6D6AE07D30282258248D4F0A5FEB1A0B661AE19E715A87022087\n      1C2311FB6022C4F28E0DD19A5843C1E61351F04823D9D01372622AFFE2B327FF\n      EAAB635D3EED459EC82FF9EB7BDFF1A2E8CD3796D29AB2A03A133EA778DAD548\n      61020D1E438689F0372111BE17C97AB860A039E448E5C14FAD658A4B78A445CD\n      843B722959EEF51F3C652E401D6D49A6549A29781A998150503AF2285C035A16\n      C830D6A6AFD4939BDDA9F69EBD0CCEF760C821037B710A18022B428A09833979\n      8D4A6F64342EDF19B0546BD190B9B4424F6012A72557F03FF070F3548B253176\n      6F6FEB62E7D2BF3D727CEFB636E94047F01691A3C147C6BA686B0C7102C0BB08\n      3011C207D34E53C3ADAB905D4D60B223F8F402FA8CB509977BD2C1208A3E2DFD\n      BFFCD2C3BF72CBC26BA60E186FA1DE9CED5D3AF9ADC5474E04639F3CB575966E\n      CC0CED7B160EFDF094DFB6BD2D03EF3A6A4044CDD46A61071A723117254F3CEB\n      43152EE41F9D3BFDF71E82CB5764EC83FB8E1D5425F3A1162C6909F8D3837810\n      C14D93049319264501AF6BD30E564A78F30DF85450193F43CD7D8B8B07172637\n      68F8F5C5C582D0289679A906257C40D41D11680C8E63528DB8BF685BFAC37B0F\n      BF498E875B6B2A80BB0DF010DD8EE13647806FB51950741C1C50FB00E97F3B59\n      7D516BE18D64C2EB758C574C52BB4F7A8D460007B8D92B933151B99CD2D186BC\n      934A137CD4E0D24E48C9F1724B5D26B8A1446566598E9D40482D8D82F15C7738\n      76C59B4338897ED2A89DB6EA11959E28FACF7437E02B5D59AF1FF3FD2BBC20C6\n      A45468B4539659A6B7B20C8AD9356BCEE7E98AD65B0AE97C2193B35E34C9E418\n      15D33C38824C0F78E7F00D0C5C0AF88E99D5902AB78AE1801603663A795A2251\n      662249065959389E0E94E1D8C547FDEEB228E0BC19A7E425C91E2D91B3CA99E7\n      09DC7DE53460BCC64493F249168C33AF85037AE197DB9558B0AE66F1D4152815\n      65AE92AB76E70A42A5D0A8EE8CEA981C19B3F06B809A5B2AD7645098654ECEF0\n      E26BFD4167387CCD81BD50BCF40B3D26FCBD54EFB5B4A9D16187C329A27A2CB7\n      63C447BE38B67751C6AE5A22AC5E8C53F3778AE523C3C2DD445869BCECB83D54\n      1C263BDA2C43F9B0111CC4A5C35182DBB1371E19E418A862477C36B7DD375236\n      DF51DFB16C67C95E3B6984AAD7692A022880418DE4149C6C729AC1C5963CA6A8\n      D3E888B54EC58CBBC784DDCB510FD60A86D297E86184E02E77A60A882D0C0928\n      8E87711E49915056BA0124F6B4256A9160DB9B5762794E48055794CDAE892560\n      226DB580AC8C2B84B4EF715350AFA3D3DC3E13937B7A2B706BF786E3D7E86646\n      521F91117FDCA39F585D7C66305496156EADD1B33624064010C0EA044B70E477\n      39CB281269DC4E8332714292771EB8AEF7CCE9E4F0F8AB886917A26EA2580B09\n      D1880D83B2143C3ADB68FDF9F2D9CF6F6E5E71707246DBC3CD317579E3A6DAD4\n      2188D0653F0CF8A12C9CB5CDCFD1FEEF0C4F3F94E79E76FBF1C65C25C57B5E7A\n      EB5BF6DD38A164575DFAD8E9073FF6C0D95FB8F59AB7147A32B19B2C2ABDC4B7\n      1D6B9A4C17904086456EAF3816DEFCDAC46F87A610C965D5D91EACF4972E5C5A\n      EBAC3F396566697098AA232CF7B733DAC761FBB6601B417B693BCF3CF378BDFC\n      F8C573596A82F1C9F5612FCDF2CCAF89A278772BFCDDFD334D9576FD10CE44B0\n      93082B76683517A4958E26A205284EF000E091758910797CBE0F29904342A82A\n      16404375CEDBBE37DD201375228CB6998183808BA901811C8E965303C0530AE2\n      8817E76AC80222FDB870628B5FFFD097CF7DF1E481FAC47CE84DD932B583C175\n      AD43BFF85A7EB066CB2192443DE6E7156E73D7819686F93C8444F8EFA9EDFEBA\n      A50EA66139EB04AC90BE932382F6DA70F5D09190E62C2FCCB32B83C757CCA5A1\n      97D3B2D763494187054D6D911AA3F0D3E18FED10632FCD015C3582F6988573D1\n      1F420D58F8AD3E26F2542A8B11863B11ADCABBCD8E58EA23DB175BD10FA02E84\n      8A0730626B580E216F1B3D91F5CE07C1472D7BF8D9733F353BBB506B9CCCCB23\n      BE7FF5F67AC76BE00CC0996E550BD3A81C0E7F476519A91C6D0A45C077BAA264\n      24B4B8E341B9A31A55F54D874CEE49FABD5AFD7FFBFE5FDEF5E02FDF76E03593\n      FB099B698E2F6CAF3EF9E5A7BE795FC6BEB1EA9DF42E4503F25353B3EF9E6BCE\n      9B04FE94F1EA7E9EDB426F28D253F8117D25D62313970652DE5F6FAE7E28DD4C\n      897E4B7DFC37E60F8CA5834892891C1069BE5943B3C626AEB75AA94BC8E0032B\n      7AAC582D3ADBC42FF898CACB2E4D1EA7EA4BCB2BC7E6A6FA32F8E6F945549882\n      4C86910FB28DE7A45C949332C36750B7E5CD7EFC837B0F8D95A8D90987C85736\n      2176832B43E0107100197D66B37AFD6B7CEB9E334BAFAEB5BF6F727FB1BD2985\n      9A137441F0B140441E171A059F87E1281156EC172750E88C26B024741A4DDA69\n      7E418A298C2E4D02D8DF30A99CF185B53C01A4CAE1035F0EE9409267E2C68961\n      FFE995F3DBBDC17C1CDD3A317790066DC6726EB73CB321EC76A97AFDC1CA20BD\n      90170526291C62D5A53713D566E346CB97015A7AC1D5A01A8D5F98187A49098F\n      5EE72896A3377B502AE6F0E3F486059AD7619D4302490E7B5E2DAE85810F473C\n      6034967E88F3340CB802A104D67050B518888E8E4123777934706D5D0D0C4F03\n      6941D649D061D9847274A833E81899DA19EE8EC84A5514C07A084007EA86437D\n      5370566222347DABFA56679A763275D9A3A778FED5ADAD288C6F6AD6B32C592F\n      CC4CBD395FA407051B47E74F54CC8DB91D2F48DB601BC9F3511B8450774FEC28\n      F5BA5EA7931C6795D4DB77558476571BC0353B7736D573BBE3D431927AAAFE99\n      579B2FC46920184770B38E1F6BABC9BEFB6D8C5775DBAEED92803217852EF167\n      82A4E5558AA0048BBF5C12547C742D1205D098A09D5B8CCF0E6A0F0BAF1253B7\n      B101AA5F219F100A2CD45BB618080BDC86C28F289CB5A5ABBEB14C84FAAC1498\n      20BDB26AD13A268644C42B9088E116D4ACDE91A1458651E5BB4170C9107F5E5D\n      9248D6D6D6BAEB5A6DB7A26FAF5F7A76ABF3A27D572EB0580E0B38D942F88B59\n      FAC98DC5AF990420862C842065E1A4187C42329C6462830BDBB29C07B87C6252\n      6900D4BE65DF957A63736B32789B081A38C1F51B4644AC241E1CF3A2C5EA4356\n      FF5CD6FFD3CB4FDBF9766373787461EFC6A9F3AF1F5B381AC72D283755D6D426\n      26105582C743F65F174F7E0370930C20E97A79F23D87E77FEAFA57BF2C6836E9\n      C6D371FF8FEF3FB1F4E4DA1F5D75D381C1A0F4D910E03753B46C37732D58BA4D\n      93C6F53715476FD8E2DE043C8C53A71E3B7FF6CEEDC5BB2FAC9469B9C46CCAD8\n      7E8FFCE8F4F46BC2F65C61659AE49EBF529F7A60653391653126EEB970EAC1BE\n      D19E971337EFF76391E43F3D16BF7FEF3426C220840810A8B2949C8CF64AA9DD\n      A50D57E3638E6BFCB84AE0F48E4C80A43BE17B2C94C4E3900E29DCCF907AED50\n      4CD648CBB71EEA1F384F5394AA6450C89BC005B70C7D4551DB8032A4F540DE8A\n      015D961BDB9FF8D03FAD3CBA7E306E1E6CC905419B945D0EB3D977DFDA7AF3A1\n      BC5C25425A2F1669C64762C73839352CD84984DBBF5AA53FD7A444D325D4F8B2\n      6E1CE235886DB93E97916448B68BFCC4D2F0D4AA9F9872B30B45A3ED16809154\n      060719F9DB56153E80B48877933254754AFD3E1B667A634C04ACF088E6A12E00\n      1AA790CF399323D92737BA70984E88914F815B9A42DE79C638A0F4466636C258\n      16C57CAF7BBA19BFFDF4199DD3BFBAFA9AD54B2BF7B6E39705D1EB2F2E2F3626\n      B0B94B59D5A883CB809D238631436245081F423B212E4E763C717638E1C6EE58\n      AA8D28F26EDA3C9B26DD7AFC99D0FBD85D0FFEFC0DFBDF307B250966A3D6647F\n      EDD96F3EFDD0C74F2D9D89F7792DBD7A61E995ADE67B0ECF1E2DE1908685088D\n      CE54516EE5B68FE2552CD072B14DDBDDAC5D049FA2E507509981FED4D12347B2\n      CE71210E6B394E586A504246A0889601BCEA978815B6185FA7D946D11BF88DA1\n      AE9559D623C347B8BEEBD2E563F35379587BF0D97358F919DC61C12B4D45257A\n      CE779CC6A74BF5A31333AF69CF6E0F2FF366542BA8DFCBB7855DA96308A90FB8\n      16C15A24BFD45F3AB9B97575BDFEE6706ED2D08E1C36A53D4AC4249CCED00616\n      BD3AA9CF7338026EACEB5A601596272E5BC0D1E1D810559578BA12A91139A0A2\n      4A6D9DA6825C16655E0F86C2F6A9592FB38BABAB4F156A4BB23092FB67C6AF8C\n      5B631DE56DE554864F66BD87D2AD8B0AB54E9AF83E3D5DAF8FC7B5A95AD4B4A4\n      9E638DEB6799505A01A812644D2597B33E3230498CFBB20C75E9E0DBE645590B\n      C2561C35843FE6454D2E214749C216548F73494BA8D08B0039D8106E15D4EB9E\n      53ADE4A553A835366DC30F6FB18E31D643791AC74E744AA9D80AC5260F86DC0E\n      F1352E9459E536225C231FB72C2DDDD90970152114FBA344883F210ED8E0720D\n      2011129B29B29EE56BBE789224F76D6ECED4DB37D7E34E3EB8A84C5386D786FE\n      74D69FB17E9B844D291B9C8C29DB423E831598CA918F3FFAE178E50A8C4C748E\n      89A2FAE62F4884A34EE68EB423D911C2E21A3D0E49658CE50C719D1A19FE852B\n      03A3B51162AA7E122E1AE29242C53E72B00B4B37F764B0200E9D3A02C011ED68\n      43704C0A8BE6A080FD71F05F949554FAA2CCFBB68C2C9B10D118957EA678692A\n      3D2AEB04F921174ADC517106423B16881569D939078CFEA295F61B0AED302776\n      85D200B822871A25A8D72503891BCBB86F82DF1F8A000F9981AC80DF50D21020\n      09F3564949837A90D2AC9B9E26D977F2F5AF9FEFDD7E78DF7C63D21FE6931B03\n      9FF16F46E623BDE5277BA94542040666809FA146EA81AA98AF0E7E00722A1DC3\n      C72BC84D639311A1CBB27C4F7326E8A711F7A7B85FD319F5D13EA39ECB3132F1\n      08A7EF5D7CF0E9313631E447F72E246717DFBCE7C8D87030E3FB6D7C896924D9\n      82163109BEE1B3DF3EFBC413052473A9683E29A2DBDA33EFBCEAC89BAF9CDDEA\n      AF9E0FE3DFBFE37F5DDD9A7BFBFEB9C326E90FB7951F701B7A2CC8D3C44EF9B5\n      1BAF31937B65E9659DCDFB9F3AF19907BF75B697B46623AFE9EF27531732FBE0\n      FAF2603878DBECCC4F4FEF6F77364A9FAF05CDBBCE5CBC20F399437BD69E3DF3\n      896E9A62231A8702DAAFC92C7FCF44FB3FCCB61B2AE90421FC071F2A426FE439\n      58D13E9EF31EC15ADE6D6EC0574080C2554028C4BCD0E3814F7C88051E0921E0\n      081A317FA2CE2011A2301A7110132E0D2428DCA540E693C9B04B8034679E41B4\n      ACCD3C7BB673FA81475F3C33F5975F78F8D48995A3516B7FDDCED7BC290A9F7D\n      18DE3EBEF07FBE64303350858975640138559EA5A65ADB0A79E012A1D9FE655B\n      1581709628EA9249B48186BCCDCBA04E6CEC16F08894294D75797AA3FBE879B1\n      96D2CD21EB15A45F02BE2D53654AEB242D549419A8C9D3C23454AB53E8F36CB3\n      29D4151A1E91D793BC56AA56A17B1E12053D77BFCC887087D90FF04165CA49AB\n      4E0EE00EF8B7394422D3F7635614B379FF992878D71367AE3C7EE487026FE9D1\n      93FCF055575172FDE6DA5AD840E7598C03CEBB15DD3AD101031766A122E4463B\n      C751FA3C9ACC2E55948C24C176D4212D19707F7E38ECC6E1FFF4F9C7BE72E267\n      AF9CFDC123379AE62C8F1AE5A5D34F3C7BF2631796BE1E4CBC6961DFA34F3D3E\n      29CA5FBEEEE0B5BD4494E150048528933CDF4E4B9472E2B8E1BC5433E39DBC66\n      C3BF15E59FAE5E9C14B5D72F4C89CD33FF6672FEE63E4465D2F56D3D153EA183\n      086DADA0A62CB8B72EBD359B6C95FDBE5FBF9C7BA8042A8B0749F1C5A5CB57EC\n      192751F3B1331770071DD7BB2B6CCFABCD018CD21869ED8B6AE1DB660F1CC900\n      A70D73080A5A9485DDF4C9C087FB6FC2C23B2FD8B7B2CE3DDBAB2F0FE257B6F6\n      007229D5609C91235E3823B9E7E1D81887AAA8734544E9D3D1F6AB0B97463BD5\n      69C799D1C81E85736651630899DA523324412BD44F5989CCB9367D8AF717D3AE\n      52B6663D9194E3A53838374F43EF726FAB6BF55A9AF77293589121EB5D37255F\n      08BDBDDCAB330FB5C3F2C2B35A3A1D75DCEF6104A25186ABF95E9E972A47D30B\n      1F1E9D1F720C80481AAC41FCB314D28F0761172A53C8E56E1D45684D76D6B79D\n      B49BAA383ED566BDBBC1F89F525BC2A794188BA9D3B8319588BCF350D3D51E08\n      9CDCA11F004A441D1364EAD31247F9B4C0D6341DAD2D56B595418EAB70C41185\n      4F0B499829A303A3014C6E66E54AC84FE4BDFB373A876BF597B66A6B797252EB\n      1A2442C10FB2728E7A93B6D662B2CEEC78A96B1A679D0C13A1C51E3AF2EBA068\n      1576B4CE4E391F6DBAEB7F5553DEEEBAEA8E12A144F170639FE73365DCAE8B71\n      D526D9E1C2E278D30D82AB5543E55C440BE751039FBA44696BEC4CA0E03E56AA\n      6E2D93B3A1641DAE0748F9134DC3B1CD8B6314BA16D875536CABA166A466F98C\n      0DF6582F2CF10FE18A14C356AA5F6A85AE3A5078B10A9470B772A6DDEBC0AC83\n      9D5278A7C4AD6D08D7A3771D54E75482494A30110AF48AF6B8E3BEE2CE0F8AEC\n      389E8E8022C6A21E52EA714D85CC59A820AA157D4E3EDBBD74FF7A7F6EFFBE5B\n      59F35067C875B1510F4F58FBC5B5E547079DBE70D370B428554EC0933814E258\n      C404C336C1150933C3C3462D5EE7E52F8F2FD8B58D5610EDAB351AC3BEEF9B5C\n      40A8B407CA899530FEC5C507EE11BA41BD8566C3F47A6F3C7CDC3B776921AE4F\n      346A6D6A26F36C06C27E5ED0DAD883C6FED9C533F7904122583DF57D52BC62EF\n      DC7F7EDD4BAFCEB381127FD74F3EFAD5AFFEF8FE7D6F83FC324C0AE95B933C5A\n      AB9DDED8BEE5FA1BDA870E13D96CE4E41B4F3FF4A7F7DF4572F18B0B076EA9D7\n      33994643CB8AF6DDB6FC3B7D8975377FA1397FAD5699B06BB2FEE9A5C5FB587A\n      EDB143CD27573ED0EFA0FE35AE8B1378575EAE7F7D76F2BD13B546996EF90145\n      D00F31CAD5371825460BA16E851C0755B61298852CE8E146B9C6D51F2E439FC6\n      48014581B0484022243EDE5E1E71E33913267CA84806A7EED4BB8451C28DC532\n      3188ADD7E815F5DFFFC0C72F3CF0D41FFCDB57DDB334B8E78167E6BDFAFE069F\n      6DCA591A3613A5DA8343BFF512F3AAF1022AEC3C2A58E6B4CD70EA86114186CC\n      BF6A76EA7D90087FC988AA8D02E703576D24F2D9A14A0DCB30A20C9E364EBB89\n      3F405388D5E1E0B173EACC06DF28F876660648A95139FAE8E2DA1F8AEB1B2FCB\n      99969B41EDC4FA2A2B939BA627BC3437C6C7240EF105F96DD23EA727E14439DC\n      76A1331DD5AEE5662AA3468A5C30A7056BA0D25246161709FDF05367F7BFEAB5\n      9DD5B3D1A90B6F983B3E863DF3AE44252EEC5671279DC3DCB218223F8F414508\n      B580D3F4A24EE3AB92C077C2FBA335A75DF9C46A258E7499B77790F482E0D3A1\n      F8E8D74EFCC054FCEE17BFD6B6A701649A73A7CE5EB870E770F0575BDD5F397A\n      EBC9A57369B2FC0BC7F6DED2CFA33CEA726FE897DD6CD8C7D32288134F852F2B\n      ACE9C5FEDFA2E2F61A3C8643A67CC7A13D6FAA4D4E6F24DC427D6B628522DF59\n      60A0620E4A9331B122F986C9FB6AB0EE45CF26D6E445ADE17DBB48BEB0BCB6A7\n      1187CDE6B9E5B5A2127030AA62665432C9524248CE5A9CFDFCE4C2E176B3DEEB\n      C40CAA16B6AD49CAA182742BD85CAE337A5F7FF31BDB1BB786F1EDD37BC62D2F\n      CC70DCDAABA8BFC0250ABA60274F699FA50145AE6FE6558612CE8E025321245C\n      F8841AFB0106B360456C2F4AC07B79E8AF487349173916896435E97659D1ACB7\n      27833A1C855E4D36131D6D67795A6C0E875B507EB46BB41687BE57E7B2C66854\n      96F5A404CCC4F10B97CCBD5907D4A81288E5351478AE3D06B7C4231CEE4EBDC8\n      A0A4C6B20F5EAF429A3CAECF18E2441BDCACAB62C750A1AB891114676E07DE54\n      978B8E960EAB2E5F4D8D9A047624A7622A36388AEEE0661E4A07C0F7EA738E89\n      10DDDBDD46043A94A1E603FAC8BA6CE714E9717903C5A3F14B72A872DD180FA9\n      A4430D0F8F6CE7E56ACDBFBFBFFEF056FFE593D3B779F2924EBFDCE9B46BAD63\n      BABC26E6F35E306BEB6D2BEBD436E0C9546ADF489581BB0A279C238A8522D18E\n      047E391D7970389EB425FFFA5FBBA97047F265A75AB41547A63206194996E36F\n      93051BCD158D75171DE96785CB85B9B51954C678454DEAC9D2652489924302B2\n      424F12C040DB45164A7F326E8488FDB0615E6A5C5EDBA24547A5F05262CB67BD\n      78827A7161785E7A3803C5FA5332E2A3DC209E5B4C731C15DE71711233198EEB\n      A4533FD35452B6C304AF3A5F804F1CC286DC2C256A2FE255F7B596B8C48DB5AA\n      132192D8D3C3EA7928B1E9562B693D21677CFB3935F8C74BCB578FCDBEB13915\n      6FAD6B299246FB9924B97FE3F223DDEE12B67301E8964CBB44E8787FDCC106DC\n      E3914C943AB0C4F7FD2C10EF9E5C60EB9B535170A4D59AE8270129F298C586CF\n      6D72559FF8EDDEB31F815B6EC534876796DF72F48AF8F4F2B5F144CDF3E76430\n      D7192E48EA3305907A10D6EFD6C97F5B39F3A02E27B448A81F08FB7BAFB9E95D\n      7BA63C153E363BF7275FFD62F1E4133FBBE7C0354AF8F9A0F48ABFAB07DF21FA\n      C76E7DCD0D6476C0BCBB2E3FF6A92F7EEE58D0FEA18563570E07ADC1329C5C00\n      07A26CF783D65333D1C98D73FB95BA062EA2F59EE6E293C9DA3FA75B2FBBF2D0\n      C1531BEFEFF7D04D0F62383C6D1940987ADFDE99F7D4BCBACAB7C2103E7E604A\n      052FC1A0466865AE4BAB7488CB00F8AF11200ADC8E6050CFC5820502CA4140C3\n      26848A50DA807180773E87530D119B0782B9150B77E8CA4A969DE15BE638F785\n      225106DA9BFAD8A7EEFBC33FFEA763CDF08FDF78CB968E3F75DF439BA93A38D6\n      D8E793F9209A448E5177FF4F1E1F7FD7F1211936585CE821A7954491EB6B8860\n      2711767FD13A8D0DB8EE706A73AB8354A8F582D59A76B205E70EC01E03A814E4\n      12EAC86E963EB5989FBCE4AD412254AA57DA1C8D7C4C5290D2EA4227A498EB03\n      44640F34F9A3FDAD9B0BEF7A3FD8643994B0ED4440B0DDF675A085A7A8DE118D\n      B76EC4E436278493BDD9112680824421633D830755A0AEFC5648174D71F7998B\n      E2E65BEF3DF5C4AB44F076AFA5B3BCDB0827B21CFBFD58BA383526E296C2DCED\n      105100C8A2A42E5018BB43CA19499E3F2F0B3E1721B6843C38488632BCAB59BB\n      E3BE6FDF1CD29F7BED9BFDE6746859F2F49367D7D6BE60CA3B2E2EBE349A2819\n      8BCACECF1D9EBD6DA864E675A5DF17C556D24F01AD720F2547289B18925ECD3E\n      33CEFFFECCD2DD5BC33420D74AF17B078F5ED783EAB10C18EE0B1A11A06C001A\n      B61AF86309974B50299A42537D418A877B59DAEFEFDD33F148967CE5D22A9C9F\n      A81E6FF7D35C550CF76A04C25C2EA43E6431951D9D1EFFCF644F5683A0369490\n      4D18D497F07BFCC6C0428E3BD3B07725ABE7D7BB33A2FD33E3131BBE2A5472BD\n      D7B8DAE9EB979E862716E232862D7C368828A4EB06A275A2474AD4CE4A028E76\n      819284B843AA502B1BD18740CDB68B4C3FC5D215CFB6C3FA0153AB77F37A49C7\n      8917427D6CB3C71B2A93CC4F4DAD6435226338FFC44444C38F0DF72C172C45CA\n      15D40790D255E627082F911F41B0D034AECE43695363B85252971495B5EAAA81\n      CCB21D285351FE2B8C4347D3BAAAFED796EC78C1D05D1B05475E1E7925E0DF03\n      35A280A2381AEA1857AC2EA7916430FB32E3D4FD91508F32D680573111A26412\n      442C54FF71BA4B6838017F2548D6B7C249A30040423152AC6058866D74D22BD5\n      7A23BA77EBD2A97EF6968503AF6B344FEBE4134B177C1EBFAC1EEF33BDBD51B4\n      4737C6B4173328078B18BEB240460F0B180BD0F5C31978D06AA037626F3A311B\n      C5BF6B5596ED98E13C971DDD3860C7A371472ED93EDF1AA9329274A335D735C5\n      FC88CBEA23E60A6E13006CC8D0A54D4309B721FCBE2E074E10068D4501D549DA\n      0DF9655A0C89C9CA222B0A8892335ED3CB8C2F2424BA7E405779B1A5F3B43F18\n      D3FCB0DF9815112D2196CB16170DC88BE83A89752B4026F4D8A423C5560425B4\n      92F60370ED911115C88CBC3F5C5277CF863A6B1A9C0DF99E363E7AA30A8C0758\n      DC42DD59CFF1F7C28F3184635FD85609B1387AB2577C8E9B7F5C3B7DD3C4F85B\n      E209B1DD1D22FF3C28897FCFD6FAFFDE58BB04E98EA5D5B2A8DBA6ACA6AA959A\n      0B0E2D3C6CBE2AEB796F9C9C690E923DBEB8667C6C76908779AE1B1EFCE40B1D\n      2E83F627FDC1EF5C38D9D162425B2FA273FB676A6756DE30B9DF23A85CB1AFB4\n      D728B83BAAC40DC66048C5E786C91F6F5F1A14E976D06639FDC9E393FFFEF623\n      63F5E96DDDB8BCBDFD892F7CA629821F6E4E5DBBB97DA616FDC1E5C53DAFBAE5\n      676FB87DFCA9CE5D17CEFDD5A57BAE90FEBFE357CC6DE84EB3AF5837EEE7FD46\n      AB06771D8D7D583FD209405FEBA703F170597C2556FFBCBCF8A27DF3473BE907\n      37BBB85A0A5854DB42C88665BF7560E1DDC2D64DB91906F01442EB12212E43B8\n      A68473564097768C4CCE475356146E815CAF484222A4013C71CF865811125702\n      E25A85C798FB8536A9C4F5E299338BC2EEBB24021BA425C483B07DE7971FF9DD\n      3FF9C2F21639D0083E70DBA1C3F5B94F3EF2C897B63BFB5A93C7ADDD13891A21\n      0D564EBF64ECAADF7C653909604269B475336CA492085F39A0FE7197087BBF60\n      1C579C690A07A0202AEEB3F3F79FF6A7E6276F3C52A83C60A1A571260B498C97\n      64D9D397CAC797E572CAB74C3940574C9DE47A9052D71CCBB36CCE04A9B277DA\n      EE65C9DEC0C7E757B7CAB6DFE5B29E40142B8602A552444946D7AFDAABC5B927\n      857F8DC1AB9AE9BBEE1B840D65781220D9C4CBE4A6173ECD06F76C2EA67B8F3D\n      F0F033EF3A72F855B60F78328BA627CB6D97FB50479DBBED275485463B0F2242\n      497CE68496E8CE24B012A6D86DFABCD034CDDA2DDF3FD01D1622B8AFDDFAF307\n      BE75452C7FE2556F98AE4DB500093C79F2E18DE57B7DF9F7E7CEAD25C9B817DE\n      1A05EF3DBC70756FA0739984F18026DBC97088DA87A8A30D3F5473688775F268\n      DDFCF5A9B3DF49E195AAB7EFDDFB53B5D6D4D2DA542DB6451E7961669038E7C4\n      1F908ED1E7F22225439503983DE3F1AF757A836EE7EAF93DA78CFAE78B972C2E\n      4603688698270A5CF0C2852927DF85C36841CA31615F7EECF0AFAFC7EB7EAEB8\n      D23A57C2DB5256167C22F7D784F95B7BE9DEAC7BA31C7FA77F3C56E7BB35D2E4\n      F4E6CC3B96101AB26E03AE206B203B02003ECD3D8C35D884AAAC74AB71083A8F\n      D0725850ED56D6DC441B1EFC79DEBFC88B61EC8DD178A60C85A170401A528699\n      C62A8DB84CC0E1BEE1663AD40E02B74871CF332E755C96E8222D009B03524269\n      0CCC3262E07CCB71650CBE9A6769886D0AA770CA9C0A24D3CEBC29A0AC329A19\n      F9308D66C1B45AF718D94428510983DAAA054A779A9C48B3D80DFD84649C55CA\n      96DC8E542D2B06BF711652A3251B6B3C85DBDE0A0DC270928EE511C56892A38E\n      1A5C255BB8E5F40E6E2E994A3C0935B295A9F4DF32630A657BA5D9A8F95FDD5E\n      B990163F3677E00D71E3ACD41F5DB90431FF564AAFAEA9B9289853F5B60A4280\n      0B36F54D5940B9E43111321EE0E45139B30C5C4E76844E1C6FB85456F2EFAA08\n      D9BF62C089794D8D2687B4724BDE21C958F25C7D556D3518E7D4E378A9F0382A\n      5B198D8F9B613F48E1FAEF268DBA446FE96C882A0A4830EF58DDE5F888A4DBB3\n      8434B96DF30B3A51CA2CD4C71A04923949ACEA7B360DF856D61F7406754A179A\n      AD1AD4B96916C0BB16A865E45316103A26BC49C8907919E2FA4A95110DEAF9A3\n      DE5CB535489D74258AFFB391B691D3A471148948A55091F0500824EDD3000913\n      A573EF53D5BA6501002790743599B17B9EF2E3BF18EF7FF6D9136F64C10F36F7\n      D03283A240FAAD93B9BDE3E2B993514DE7EB54DB1D01235AB90AE3DE06B69B20\n      C5A3F90FFC7AD1D4543B4D0FFBE2FAC9F1F9A1AAC38BAFC17F2AF7E51E37DE83\n      F3ADF79EF8E6392D27E18306349A8A26973ADFBF70B050692ED4611A5C5FF079\n      D46D56BA506DBFF664107F70F3E2DDDBCBEB518B0DBD9B65FF3FBDE3E557EC9D\n      5FD88AA3A1F7C9A7BFFDF1A7BFF58B137BDFD4A5FFC3DA7FDC5AF9A51F78F3CB\n      09BDEFECE9FFFEE8B76E9D1EFBE9D6CCCCB6018892932413ACAC37753F680E87\n      46DA0E207D9AF92ADFE4C1A981BD98E8E5D8FFDCE553FBE6E68F29FAE7AB2B1A\n      F7D290E751303EC9BDDF3A7CE0FFD0596CD56618C1A38B4C597ACEEDA42A072B\n      8B214721C02207BB370220087225A5E4B1C41E69E8D14018C88E2E116213CD87\n      87003912FFD97536D0400FBB1CD87C2970C0CF6B4A91A1B60F3D7DF1FDFFF757\n      4F5CE89BA03DE5D90F5E3FFBDAD6C2A7CE3E73C7E6FA4434757DA1A742158772\n      06C0CB6471FB7FF9DEF8F699ACBFCE3DE1C6D0162B42C4B350111EDB33FDBEFF\n      1F1CAF12FB8DB29B6E0000000049454E44AE426082}\n  end\n  object lblTitle: TLabel\n    Left = 24\n    Top = 140\n    Width = 153\n    Height = 41\n    AutoSize = False\n    Caption = 'Mator Smash'\n    Color = clWhite\n    Font.Charset = DEFAULT_CHARSET\n    Font.Color = clBlack\n    Font.Height = -24\n    Font.Name = 'Tahoma'\n    Font.Style = []\n    ParentColor = False\n    ParentFont = False\n  end\n  object lblAuthor: TLabel\n    Left = 24\n    Top = 168\n    Width = 93\n    Height = 13\n    Caption = 'by matortheeternal'\n    Color = clWhite\n    Font.Charset = DEFAULT_CHARSET\n    Font.Color = clBlack\n    Font.Height = -11\n    Font.Name = 'Tahoma'\n    Font.Style = []\n    ParentColor = False\n    ParentFont = False\n  end\n  object lblProgress: TLabel\n    Left = 24\n    Top = 200\n    Width = 481\n    Height = 31\n    AutoSize = False\n    Caption = '  Loading...'\n    Color = clWhite\n    Font.Charset = DEFAULT_CHARSET\n    Font.Color = clBlack\n    Font.Height = -11\n    Font.Name = 'Tahoma'\n    Font.Style = []\n    GlowSize = 1\n    ParentColor = False\n    ParentFont = False\n    Layout = tlCenter\n  end\n  object lblVersion: TLabel\n    Left = 174\n    Top = 155\n    Width = 35\n    Height = 11\n    Caption = 'v0.0.0.1'\n    Color = clWhite\n    Font.Charset = DEFAULT_CHARSET\n    Font.Color = clBlack\n    Font.Height = -9\n    Font.Name = 'Tahoma'\n    Font.Style = []\n    ParentColor = False\n    ParentFont = False\n  end\nend\n"
  },
  {
    "path": "frontend/msSplashForm.pas",
    "content": "unit msSplashForm;\n\ninterface\n\nuses\n  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,\n  Dialogs, StdCtrls, ComCtrls, ExtCtrls, pngimage,\n  // mte units\n  mteTracker, mteHelpers,\n  // smash units\n  msConfiguration;\n\ntype\n  TSplashForm = class(TForm)\n    lblTitle: TLabel;\n    imgSplash: TImage;\n    lblAuthor: TLabel;\n    lblProgress: TLabel;\n    lblVersion: TLabel;\n    procedure ProgressMessage(const s: string);\n    procedure FormCreate(Sender: TObject);\n  private\n    { Private declarations }\n  public\n    { Public declarations }\n  end;\n\nvar\n  SplashForm: TSplashForm;\n\nimplementation\n\n{$R *.dfm}\n\nprocedure TSplashForm.ProgressMessage(const s: string);\nbegin\n  lblProgress.Caption := '  '+s;\n  Application.ProcessMessages;\nend;\n\nprocedure TSplashForm.FormCreate(Sender: TObject);\nbegin\n  Tracker.OnLogEvent := ProgressMessage;\n  lblVersion.Caption := 'v'+GetVersionMem;\n\n  if settings.simpleSplash then\n    lblProgress.GlowSize := 0;\nend;\n\nend.\n"
  },
  {
    "path": "frontend/msTagHelper.dfm",
    "content": "object TagHelper: TTagHelper\n  Left = 0\n  Top = 0\n  Caption = 'Tag Helper'\n  ClientHeight = 412\n  ClientWidth = 334\n  Color = clBtnFace\n  Font.Charset = DEFAULT_CHARSET\n  Font.Color = clWindowText\n  Font.Height = -11\n  Font.Name = 'Tahoma'\n  Font.Style = []\n  OldCreateOrder = False\n  Position = poMainFormCenter\n  OnClose = FormClose\n  OnCreate = FormCreate\n  OnShow = FormShow\n  PixelsPerInch = 96\n  TextHeight = 13\n  object lblPrompt: TLabel\n    Left = 8\n    Top = 8\n    Width = 185\n    Height = 13\n    Caption = 'Check the tags you want to {ACTION}'\n  end\n  object CheckList: TCheckListBox\n    Left = 8\n    Top = 27\n    Width = 318\n    Height = 346\n    Align = alCustom\n    Anchors = [akLeft, akTop, akRight, akBottom]\n    ItemHeight = 13\n    Sorted = True\n    TabOrder = 0\n  end\n  object btnCancel: TButton\n    Left = 251\n    Top = 379\n    Width = 75\n    Height = 25\n    Align = alCustom\n    Anchors = [akRight, akBottom]\n    Caption = 'Cancel'\n    ModalResult = 2\n    TabOrder = 1\n  end\n  object btnOK: TButton\n    Left = 170\n    Top = 379\n    Width = 75\n    Height = 25\n    Align = alCustom\n    Anchors = [akRight, akBottom]\n    Caption = 'OK'\n    ModalResult = 1\n    TabOrder = 2\n  end\nend\n"
  },
  {
    "path": "frontend/msTagHelper.pas",
    "content": "unit msTagHelper;\n\ninterface\n\nuses\n  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,\n  Dialogs, StdCtrls, CheckLst,\n  // mte units\n  RttiTranslation,\n  // smash units\n  msConfiguration;\n\ntype\n  TTagHelper = class(TForm)\n    CheckList: TCheckListBox;\n    lblPrompt: TLabel;\n    btnCancel: TButton;\n    btnOK: TButton;\n    procedure FormShow(Sender: TObject);\n    procedure FormClose(Sender: TObject; var Action: TCloseAction);\n    procedure FormCreate(Sender: TObject);\n  private\n    { Private declarations }\n  public\n    { Public declarations }\n    slTags: TStringList;\n    iMode: Integer;\n  end;\n\nvar\n  TagHelper: TTagHelper;\n\nimplementation\n\n{$R *.dfm}\n\nprocedure TTagHelper.FormClose(Sender: TObject; var Action: TCloseAction);\nvar\n  i: Integer;\nbegin\n  slTags.Clear;\n  if ModalResult = mrOK then\n    for i := 0 to Pred(CheckList.Items.Count) do begin\n      if CheckList.Checked[i] then\n        slTags.Add(CheckList.Items[i]);\n    end;\nend;\n\nprocedure TTagHelper.FormCreate(Sender: TObject);\nbegin\n  // do a translation dump?\n  if bTranslationDump then\n    TRttiTranslation.Save('lang\\english.lang', self);\n\n  // load translation\n  TRttiTranslation.Load(language, self);\nend;\n\nprocedure TTagHelper.FormShow(Sender: TObject);\nbegin\n  // update lblPrompt\n  case iMode of\n    -1: begin\n      Caption := GetLanguageString('msTagH_RemoveTags');\n      lblPrompt.Caption := GetLanguageString('msTagH_PromptRemove');\n    end;\n    1: begin\n      Caption := GetLanguageString('msTagH_AddTags');\n      lblPrompt.Caption := GetLanguageString('msTagH_PromptAdd');\n    end;\n  end;\n\n  // populate checklist\n  CheckList.Items.Text := slTags.Text;\nend;\n\nend.\n"
  },
  {
    "path": "frontend/msTagManager.dfm",
    "content": "object TagManager: TTagManager\n  Left = 0\n  Top = 0\n  Caption = 'Manage Tags'\n  ClientHeight = 312\n  ClientWidth = 434\n  Color = clBtnFace\n  Font.Charset = DEFAULT_CHARSET\n  Font.Color = clWindowText\n  Font.Height = -11\n  Font.Name = 'Tahoma'\n  Font.Style = []\n  OldCreateOrder = False\n  Position = poMainFormCenter\n  OnClose = FormClose\n  OnCreate = FormCreate\n  OnShow = FormShow\n  PixelsPerInch = 96\n  TextHeight = 13\n  object Panel: TPanel\n    Left = 0\n    Top = 0\n    Width = 434\n    Height = 273\n    Align = alTop\n    Anchors = [akLeft, akTop, akRight, akBottom]\n    TabOrder = 0\n    object lblDescription: TLabel\n      Left = 8\n      Top = 8\n      Width = 53\n      Height = 13\n      Align = alCustom\n      Caption = 'Description'\n    end\n    object meDescription: TMemo\n      Left = 8\n      Top = 27\n      Width = 321\n      Height = 238\n      Align = alCustom\n      Anchors = [akLeft, akTop, akRight, akBottom]\n      TabOrder = 0\n    end\n    object btnClear: TButton\n      Left = 335\n      Top = 87\n      Width = 90\n      Height = 25\n      Align = alCustom\n      Anchors = [akTop, akRight]\n      Caption = 'Clear Tags'\n      TabOrder = 1\n      OnClick = btnClearClick\n    end\n    object btnRemove: TButton\n      Left = 335\n      Top = 56\n      Width = 90\n      Height = 25\n      Align = alCustom\n      Anchors = [akTop, akRight]\n      Caption = 'Remove Tags'\n      TabOrder = 2\n      OnClick = btnRemoveClick\n    end\n    object btnAdd: TButton\n      Left = 335\n      Top = 25\n      Width = 90\n      Height = 25\n      Align = alCustom\n      Anchors = [akTop, akRight]\n      Caption = 'Add Tags'\n      TabOrder = 3\n      OnClick = btnAddClick\n    end\n    object btnReset: TButton\n      Left = 335\n      Top = 118\n      Width = 90\n      Height = 25\n      Align = alCustom\n      Anchors = [akTop, akRight]\n      Caption = 'Reset Tags'\n      TabOrder = 4\n      OnClick = btnResetClick\n    end\n  end\n  object btnCancel: TButton\n    Left = 346\n    Top = 279\n    Width = 80\n    Height = 25\n    Align = alCustom\n    Anchors = [akRight, akBottom]\n    Caption = 'Cancel'\n    ModalResult = 2\n    TabOrder = 1\n  end\n  object btnApply: TButton\n    Left = 260\n    Top = 279\n    Width = 80\n    Height = 25\n    Align = alCustom\n    Anchors = [akRight, akBottom]\n    Caption = 'Apply'\n    ModalResult = 1\n    TabOrder = 2\n  end\n  object kbCombine: TCheckBox\n    Left = 8\n    Top = 283\n    Width = 201\n    Height = 17\n    Align = alCustom\n    Anchors = [akLeft, akBottom]\n    Caption = 'Apply combined setting'\n    Checked = True\n    State = cbChecked\n    TabOrder = 3\n  end\nend\n"
  },
  {
    "path": "frontend/msTagManager.pas",
    "content": "unit msTagManager;\n\ninterface\n\nuses\n  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,\n  Dialogs, ExtCtrls, StdCtrls, RegularExpressions,\n  // mte units\n  RttiTranslation,\n  // smash units\n  msCore, msConfiguration, msTagHelper;\n\ntype\n  TTagManager = class(TForm)\n    Panel: TPanel;\n    lblDescription: TLabel;\n    meDescription: TMemo;\n    btnClear: TButton;\n    btnRemove: TButton;\n    btnAdd: TButton;\n    btnCancel: TButton;\n    btnApply: TButton;\n    btnReset: TButton;\n    kbCombine: TCheckBox;\n    procedure btnAddClick(Sender: TObject);\n    procedure btnRemoveClick(Sender: TObject);\n    procedure btnClearClick(Sender: TObject);\n    procedure btnResetClick(Sender: TObject);\n    procedure FormShow(Sender: TObject);\n    procedure FormClose(Sender: TObject; var Action: TCloseAction);\n    procedure FormCreate(Sender: TObject);\n    procedure ReadTags;\n    procedure WriteTags;\n    procedure AddTags(var slTagsToAdd: TStringList);\n    procedure RemoveTags(var slTagsToRemove: TStringList);\n  private\n    { Private declarations }\n  public\n    { Public declarations }\n    plugin: TPlugin;\n  end;\n\nvar\n  TagManager: TTagManager;\n\nimplementation\n\nvar\n  slTags: TStringList;\n\n{$R *.dfm}\n\nprocedure TTagManager.btnAddClick(Sender: TObject);\nvar\n  thForm: TTagHelper;\nbegin\n  thForm := TTagHelper.Create(self);\n  try\n    thForm.iMode := 1;\n    thForm.slTags := TStringList.Create;\n    GetMissingTags(slTags, thForm.slTags);\n    if thForm.ShowModal = mrOK then\n      AddTags(thForm.slTags);\n  finally\n    ReadTags;\n    thForm.Free;\n  end;\nend;\n\nprocedure TTagManager.btnRemoveClick(Sender: TObject);\nvar\n  thForm: TTagHelper;\nbegin\n  thForm := TTagHelper.Create(self);\n  try\n    thForm.iMode := -1;\n    thForm.slTags := TStringList.Create;\n    thForm.slTags.Text := slTags.Text;\n    if thForm.ShowModal = mrOK then\n      RemoveTags(thForm.slTags);\n  finally\n    ReadTags;\n    thForm.Free;\n  end;\nend;\n\nprocedure TTagManager.btnClearClick(Sender: TObject);\nbegin\n  meDescription.Lines.Text := ClearTags(meDescription.Lines.Text);\n  ReadTags;\nend;\n\nprocedure TTagManager.btnResetClick(Sender: TObject);\nbegin\n  meDescription.Lines.Text := plugin.description.Text;\n  ReadTags;\nend;\n\nprocedure TTagManager.FormShow(Sender: TObject);\nbegin\n  // create tags stringlist\n  slTags := TStringList.Create;\n\n  // update description and tags\n  meDescription.Lines.Text := plugin.description.Text;\n  ReadTags;\n\n  // update the form's caption\n  Caption := Format(GetLanguageString('msTagM_Caption'), [plugin.filename]);\nend;\n\nprocedure TTagManager.FormClose(Sender: TObject; var Action: TCloseAction);\nbegin\n  if ModalResult = mrOK then begin\n    plugin.description.Text := meDescription.Lines.Text;\n    if kbCombine.Checked then\n      plugin.GetSettingTag;\n    plugin.WriteDescription;\n    plugin.Save;\n  end;\n\n  // free memory\n  slTags.Free;\nend;\n\nprocedure TTagManager.FormCreate(Sender: TObject);\nbegin\n  // do a translation dump?\n  if bTranslationDump then\n    TRttiTranslation.Save('lang\\english.lang', self);\n\n  // load translation\n  TRttiTranslation.Load(language, self);\nend;\n\nprocedure TTagManager.ReadTags;\nvar\n  bHasTags: Boolean;\nbegin\n  slTags.Clear;\n  ParseTags(meDescription.Lines.Text, slTags);\n  bHasTags := slTags.Count > 0;\n  btnClear.Enabled := bHasTags;\n  btnRemove.Enabled := bHasTags;\nend;\n\nprocedure TTagManager.WriteTags;\nvar\n  sTags: String;\nbegin\n  // clear tags\n  meDescription.Lines.Text := ClearTags(meDescription.Lines.Text);\n\n  // if no tags to write, exit\n  if slTags.Count = 0 then\n    exit;\n\n  // see if all of the tags belong to the same group\n  sTags := GetTagString(slTags);\n\n  // write the tags to the description\n  meDescription.Lines.Add(' ');\n  meDescription.Lines.Add(sTags);\n  meDescription.Lines.Text := Trim(meDescription.Lines.Text);\nend;\n\nprocedure TTagManager.AddTags(var slTagsToAdd: TStringList);\nvar\n  tag: string;\nbegin\n  // add the tags to slTags\n  for tag in slTagsToAdd do\n    slTags.Add(tag);\n\n  // write tags to the description\n  WriteTags;\nend;\n\nprocedure TTagManager.RemoveTags(var slTagsToRemove: TStringList);\nvar\n  tag: string;\nbegin\n  // remove the tags from slTags\n  for tag in slTagsToRemove do\n    slTags.Delete(slTags.IndexOf(tag));\n\n  // write tags to the description\n  WriteTags;\nend;\n\nend.\n"
  },
  {
    "path": "frontend/msThreads.pas",
    "content": "unit msThreads;\n\ninterface\n\nuses\n  Classes, SysUtils, StrUtils, shlObj, Dialogs, ComCtrls,\n  Windows, MMSystem,\n  // superobject\n  superobject,\n  // mte units\n  mteHelpers, mteLogger, mteLogging, mteTracker, mteBase,\n  // ms units\n  msCore, msConfiguration, msLoader, msSmash,\n  // xedit units\n  wbBSA, wbInterface, wbImplementation;\n\n\ntype\n  // THREADS AND CALLBACKS\n  TCallback = procedure of object;\n  TStatusCallback = procedure(s: string) of object;\n  TInitThread = class(TThread)\n  protected\n    procedure Execute; override;\n  end;\n  TLoaderThread = class(TThread)\n  protected\n    procedure Execute; override;\n  end;\n  TPatchThread = class(TThread)\n  protected\n    procedure Execute; override;\n  end;\n  TSaveThread = class(TThread)\n  protected\n    procedure Execute; override;\n  end;\n\nvar\n  InitCallback, LoaderCallback, ErrorCheckCallback, ErrorFixCallback,\n  PatchCallback, SaveCallback: TCallback;\n  StatusCallback: TStatusCallback;\n\nimplementation\n\n\n{******************************************************************************}\n{ THREAD METHODS\n  These are threads that the program will run for various large jobs which need\n  to be decoupled from general program operation and the GUI.\n\n  List of methods:\n  - TInitThread.Execute\n  - LoaderProgress\n  - TLoaderThread.Execute\n  - TErrorCheckThread.Execute\n  - TPatchThread.Execute\n  - TSaveThread.Execute\n}\n{******************************************************************************}\n\n{ TInitThread }\nprocedure TInitThread.Execute;\nvar\n  i: integer;\n  plugin: TPlugin;\n  aFile: IwbFile;\nbegin\n  try\n    // PRINT LOAD ORDER TO LOG\n    for i := 0 to Pred(slPlugins.Count) do\n      Logger.Write('LOAD', 'Order', '['+IntToHex(i, 2)+'] '+slPlugins[i]);\n\n    // LOAD RESOURCES\n    Tracker.Write('Loading Resources');\n    wbContainerHandler.AddFolder(wbDataPath);\n    LoadBSAs;\n\n    // LOAD PLUGINS\n    for i := 0 to Pred(slPlugins.Count) do begin\n      Tracker.Write('Loading '+slPlugins[i]);\n      try\n        plugin := TPlugin.Create;\n        plugin.filename := slPlugins[i];\n        plugin._File := wbFile(wbDataPath + slPlugins[i], i, '', False, False);\n        plugin._File._AddRef;\n        plugin.GetMsData;\n        PluginsList.Add(Pointer(plugin));\n      except\n        on x: Exception do begin\n          Logger.Write('ERROR', 'Load', 'Exception loading '+slPlugins[i]);\n          Logger.Write('ERROR', 'Load', x.Message);\n          ProgramStatus.bLoadException := true;\n        end;\n      end;\n\n      // load hardcoded dat\n      if i = 0 then try\n        aFile := wbFile(wbProgramPath + wbGameName + wbHardcodedDat, 0);\n        aFile._AddRef;\n      except\n        on x: Exception do begin\n          Logger.Write('ERROR', 'Load', 'Exception loading '+wbGameName+wbHardcodedDat);\n          Logger.Write('ERROR', 'Load', 'Please download and install this dat file!');\n          raise x;\n        end;\n      end;\n    end;\n\n    // LOAD PLUGIN INFORMATION\n    Tracker.Write('Loading plugin information');\n    TPatchHelpers.AssignPatchesToPlugins;\n    LoadPluginInfo;\n    LoadSettingTags;\n\n    // CLEAN UP\n    slPlugins.Free;\n  except\n    on x: Exception do begin\n      if Assigned(slPlugins) then\n        slPlugins.Free;\n      ProgramStatus.bInitException := true;\n      Logger.Write('ERROR', 'Load', x.Message);\n    end;\n  end;\n\n  if Assigned(InitCallback) then\n    Synchronize(nil, InitCallback);\nend;\n\n{ TLoaderThread }\nprocedure LoaderProgress(const s: string);\nbegin\n  if s <> '' then\n    Logger.Write('LOAD', 'Background', s);\n  if ProgramStatus.bForceTerminate then\n    Abort;\nend;\n\nprocedure TLoaderThread.Execute;\nvar\n  i: Integer;\n  f: IwbFile;\n  plugin: TPlugin;\nbegin\n  FreeOnTerminate := true;\n  StatusCallback(Format('%s (%d/%d)',\n    [GetLanguageString('msMain_LoaderInProgress'), 1, PluginsList.Count]));\n  try\n    for i := 0 to Pred(PluginsList.Count) do begin\n      StatusCallback(Format('%s (%d/%d)',\n        [GetLanguageString('msMain_LoaderInProgress'), i + 1, PluginsList.Count]));\n      plugin := TPlugin(PluginsList[i]);\n      f := plugin._File;\n      if SameText(plugin.filename, wbGameName + '.esm') then\n        continue;\n      LoaderProgress('[' + plugin.filename + '] Building reference info.');\n      f.BuildRef;\n      if ProgramStatus.bForceTerminate then begin\n        LoaderProgress('Aborted.');\n        break;\n      end;\n    end;\n  except\n    on E: Exception do begin\n      LoaderProgress('Fatal: <' + e.ClassName + ': ' + e.Message + '>');\n      wbLoaderError := true;\n      ProgramStatus.bInitException := true;\n    end;\n  end;\n  LoaderProgress('finished');\n  StatusCallback(GetLanguageString('msMain_LoaderFinished'));\n  if Assigned(LoaderCallback) then\n    Synchronize(nil, LoaderCallback);\nend;\n\n{ TPatchThread }\nprocedure PlaySmashSound;\nvar\n  HResource: TResourceHandle;\n  HResData: THandle;\n  PWav: Pointer;\nbegin\n  HResource := FindResource(HInstance, PChar('SMASH'), 'WAV');\n  if HResource = 0 then exit;\n  HResData := LoadResource(HInstance, HResource);\n  if HResData = 0 then exit;\n  PWav := LockResource(HResData);\n  if not Assigned(PWav) then exit;\n  sndPlaySound(nil, SND_NODEFAULT);\n  sndPlaySound(PWav, SND_ASYNC or SND_MEMORY);\nend;\n\nprocedure TPatchThread.Execute;\nvar\n  i: integer;\n  patch: TPatch;\nbegin\n  FreeOnTerminate := true;\n  // build patches\n  for i := 0 to Pred(patchesToBuild.Count) do begin\n    if Tracker.Cancel then break;\n    patch := TPatch(patchesToBuild[i]);\n    StatusCallback(Format('%s \"%s\" (%d/%d)',\n      [GetLanguageString('msProg_Smashing'), patch.name, i + 1, patchesToBuild.Count]));\n    try\n      if (patch.status in RebuildStatuses) then\n        RebuildPatch(patch)\n      else\n        BuildPatch(patch);\n    except\n      on x : Exception do begin\n        patch.status := psFailed;\n        Tracker.Write('Exception: ' + x.Message);\n      end;\n    end;\n\n    Tracker.Write(' '#13#10);\n    Tracker.SetProgress(IntegerListSum(timeCosts, i));\n\n    if Tracker.Cancel then\n      Tracker.Write('Smashing canceled.');\n  end;\n\n  // say thread is done if it wasn't cancelled\n  if not Tracker.Cancel then begin\n    Tracker.Write('All done!');\n    try\n      if settings.smashSound then PlaySmashSound;\n    except\n      on x: Exception do\n        Tracker.Write('Failed to play Smash sound.');\n    end;\n  end;\n\n  // clean up, fire callback\n  StatusCallback(GetLanguageString('msProg_DoneBuilding'));\n  Tracker.Cancel := false;\n  if Assigned(PatchCallback) then\n    Synchronize(nil, PatchCallback);\nend;\n\n{ TSaveThread }\nprocedure TSaveThread.Execute;\nbegin\n  FreeOnTerminate := true;\n\n  // save ESPs only if it's safe to do so\n  if not ProgramStatus.bInitException then begin\n    // Save plugin errors\n    try\n      SavePluginInfo;\n    except\n      on x: Exception do\n        Tracker.Write('Exception saving plugin errors '+x.Message);\n    end;\n    Tracker.SetProgress(PluginsList.Count + 1);\n\n    // save patches\n    SavePatches;\n\n    // force close files\n    wbFileForceClosed;\n\n    // rename saved plugins\n    RenameSavedPlugins;\n  end;\n\n  // save statistics and settings\n  SaveStatistics;\n  SaveSettings;\n\n  // delete temppath\n  if not settings.preserveTempPath then\n    DeleteTempPath;\n\n  // print final messages\n  Tracker.Write(' ');\n  Tracker.Write('All done');\n\n  // unbind events\n  Logger.OnLogEvent := nil;\n  Tracker.OnLogEvent := nil;\n  Tracker.OnStatusEvent := nil;\n\n  if Assigned(SaveCallback) then\n    Synchronize(nil, SaveCallback);\nend;\n\nend.\n"
  },
  {
    "path": "frontend/settings/Fallout3/Smash.All.json",
    "content": "{\"records\":\"ACHR,ACTI,ADDN,ALCH,AMMO,ANIO,ARMA,ARMO,ASPC,AVIF,BOOK,BPTD,CAMS,CELL,CLAS,CLMT,COBJ,CONT,CPTH,CREA,CSTY,DEBR,DIAL,DOOR,ECZN,EFSH,ENCH,EXPL,EYES,FACT,FLST,FURN,GLOB,GMST,GRAS,HAIR,HDPT,IDLM,IMAD,IMGS,INFO,INGR,IPCT,IPDS,KEYM,LAND,LGTM,LIGH,LSCR,LTEX,LVLC,LVLI,LVLN,MESG,MGEF,MICN,MISC,MSTT,MUSC,NOTE,NPC_,PACK,PBEA,PERK,PGRE,PMIS,PROJ,PWAT,QUST,RACE,RADS,REFR,REGN,RGDL,SCOL,SCPT,SOUN,SPEL,STAT,TACT,TERM,TREE,TXST,VTYP,WATR,WEAP,WRLD,WTHR,ACRE\",\"description\":\"Smashes all the things.  Produced using autoset attributes on all record prototypes produced by v1.0.0.\\r\\n\\r\\nLast updated 4\\/30\\/2018.\",\"tree\":{\"records\":[{\"t\":1,\"p\":1,\"n\":\"ACHR - Placed NPC\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":3,\"p\":1,\"n\":\"NAME - Base\"},{\"t\":3,\"p\":1,\"n\":\"XEZN - Encounter Zone\"},{\"t\":11,\"n\":\"XRGD - Ragdoll Data\"},{\"t\":11,\"n\":\"XRGB - Ragdoll Biped Data\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Patrol Data\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"XPRD - Idle Time\"},{\"p\":1,\"n\":\"XPPA - Patrol Script Marker\"},{\"t\":3,\"p\":1,\"n\":\"INAM - Idle\"},{\"t\":6,\"p\":1,\"n\":\"Embedded Script\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"SCHR - Basic Script Data\",\"c\":[{\"t\":11,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"RefCount\"},{\"t\":3,\"p\":1,\"n\":\"CompiledSize\"},{\"t\":3,\"p\":1,\"n\":\"VariableCount\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"}]},{\"t\":11,\"p\":1,\"n\":\"SCDA - Compiled Embedded Script\"},{\"t\":2,\"p\":1,\"n\":\"SCTX - Embedded Script Source\"},{\"t\":10,\"p\":1,\"n\":\"Local Variables\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Local Variable\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"SLSD - Local Variable Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Index\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"}]},{\"t\":2,\"p\":1,\"n\":\"SCVR - Name\"}]}]},{\"t\":8,\"p\":1,\"n\":\"References\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"SCRO - Global Reference\"},{\"t\":3,\"p\":1,\"n\":\"SCRV - Local Variable\"}]}]},{\"t\":3,\"p\":1,\"n\":\"TNAM - Topic\"}]},{\"t\":3,\"p\":1,\"n\":\"XLCM - Level Modifier\"},{\"t\":3,\"p\":1,\"n\":\"XMRC - Merchant Container\"},{\"t\":3,\"p\":1,\"n\":\"XCNT - Count\"},{\"t\":5,\"p\":1,\"n\":\"XRDS - Radius\"},{\"t\":5,\"p\":1,\"n\":\"XHLP - Health\"},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Linked Decals\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"XDCR - Decal\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":11,\"n\":\"Unknown\"}]}]},{\"t\":3,\"p\":1,\"n\":\"XLKR - Linked Reference\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"XCLP - Linked Reference Color\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Link Start Color\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Link End Color\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Activate Parents\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"XAPD - Flags\"},{\"t\":8,\"p\":1,\"n\":\"Activate Parent Refs\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"XAPR - Activate Parent Ref\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":5,\"p\":1,\"n\":\"Delay\"}]}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"XESP - Enable Parent\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":3,\"p\":1,\"n\":\"XEMI - Emittance\"},{\"t\":3,\"p\":1,\"n\":\"XMBR - MultiBound Reference\"},{\"p\":1,\"n\":\"XIBS - Ignored By Sandbox\"},{\"t\":5,\"p\":1,\"n\":\"XSCL - Scale\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DATA - Position\\/Rotation\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Position\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"X\"},{\"t\":5,\"p\":1,\"n\":\"Y\"},{\"t\":5,\"p\":1,\"n\":\"Z\"}]},{\"t\":6,\"p\":1,\"n\":\"Rotation\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"X\"},{\"t\":5,\"p\":1,\"n\":\"Y\"},{\"t\":5,\"p\":1,\"n\":\"Z\"}]}]}]},{\"t\":1,\"p\":1,\"n\":\"ACTI - Activator\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"X1\"},{\"t\":3,\"p\":1,\"n\":\"Y1\"},{\"t\":3,\"p\":1,\"n\":\"Z1\"},{\"t\":3,\"p\":1,\"n\":\"X2\"},{\"t\":3,\"p\":1,\"n\":\"Y2\"},{\"t\":3,\"p\":1,\"n\":\"Z2\"}]},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"},{\"t\":11,\"n\":\"MODB - Unknown\"},{\"t\":11,\"p\":1,\"n\":\"MODT - Texture Files Hashes\"},{\"t\":7,\"p\":1,\"n\":\"MODS - Alternate Textures\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"3D Name\"},{\"t\":3,\"p\":1,\"n\":\"New Texture\"},{\"t\":3,\"p\":1,\"n\":\"3D Index\"}]}]},{\"t\":3,\"p\":1,\"n\":\"MODD - FaceGen Model Flags\"}]},{\"t\":3,\"p\":1,\"n\":\"SCRI - Script\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Destructable\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"DEST - Header\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Health\"},{\"t\":3,\"p\":1,\"n\":\"Count\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":8,\"p\":1,\"n\":\"Stages\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Stage\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"DSTD - Destruction Stage Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Health %\"},{\"t\":3,\"p\":1,\"n\":\"Index\"},{\"t\":3,\"p\":1,\"n\":\"Damage Stage\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":3,\"p\":1,\"n\":\"Self Damage per Second\"},{\"t\":3,\"p\":1,\"n\":\"Explosion\"},{\"t\":3,\"p\":1,\"n\":\"Debris\"},{\"t\":3,\"p\":1,\"n\":\"Debris Count\"}]},{\"t\":6,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"DMDL - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"DMDT - Texture Files Hashes\"}]},{\"p\":1,\"n\":\"DSTF - End Marker\"}]}]}]},{\"t\":3,\"p\":1,\"n\":\"SNAM - Sound - Looping\"},{\"t\":3,\"p\":1,\"n\":\"VNAM - Sound - Activation\"},{\"t\":3,\"p\":1,\"n\":\"RNAM - Radio Station\"},{\"t\":3,\"p\":1,\"n\":\"WNAM - Water Type\"}]},{\"t\":1,\"p\":1,\"n\":\"ADDN - Addon Node\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"X1\"},{\"t\":3,\"p\":1,\"n\":\"Y1\"},{\"t\":3,\"p\":1,\"n\":\"Z1\"},{\"t\":3,\"p\":1,\"n\":\"X2\"},{\"t\":3,\"p\":1,\"n\":\"Y2\"},{\"t\":3,\"p\":1,\"n\":\"Z2\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"},{\"t\":11,\"n\":\"MODB - Unknown\"},{\"t\":11,\"p\":1,\"n\":\"MODT - Texture Files Hashes\"},{\"t\":7,\"p\":1,\"n\":\"MODS - Alternate Textures\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"3D Name\"},{\"t\":3,\"p\":1,\"n\":\"New Texture\"},{\"t\":3,\"p\":1,\"n\":\"3D Index\"}]}]},{\"t\":3,\"p\":1,\"n\":\"MODD - FaceGen Model Flags\"}]},{\"t\":3,\"p\":1,\"n\":\"DATA - Node Index\"},{\"t\":3,\"p\":1,\"n\":\"SNAM - Sound\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DNAM - Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Master Particle System Cap\"},{\"t\":11,\"n\":\"Unknown\"}]}]},{\"t\":1,\"p\":1,\"n\":\"ALCH - Ingestible\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"X1\"},{\"t\":3,\"p\":1,\"n\":\"Y1\"},{\"t\":3,\"p\":1,\"n\":\"Z1\"},{\"t\":3,\"p\":1,\"n\":\"X2\"},{\"t\":3,\"p\":1,\"n\":\"Y2\"},{\"t\":3,\"p\":1,\"n\":\"Z2\"}]},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"},{\"t\":11,\"n\":\"MODB - Unknown\"},{\"t\":11,\"p\":1,\"n\":\"MODT - Texture Files Hashes\"},{\"t\":7,\"p\":1,\"n\":\"MODS - Alternate Textures\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"3D Name\"},{\"t\":3,\"p\":1,\"n\":\"New Texture\"},{\"t\":3,\"p\":1,\"n\":\"3D Index\"}]}]},{\"t\":3,\"p\":1,\"n\":\"MODD - FaceGen Model Flags\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Icon\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"ICON - Large Icon filename\"},{\"t\":2,\"p\":1,\"n\":\"MICO - Small Icon filename\"}]},{\"t\":3,\"p\":1,\"n\":\"SCRI - Script\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Destructable\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"DEST - Header\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Health\"},{\"t\":3,\"p\":1,\"n\":\"Count\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":8,\"p\":1,\"n\":\"Stages\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Stage\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"DSTD - Destruction Stage Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Health %\"},{\"t\":3,\"p\":1,\"n\":\"Index\"},{\"t\":3,\"p\":1,\"n\":\"Damage Stage\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":3,\"p\":1,\"n\":\"Self Damage per Second\"},{\"t\":3,\"p\":1,\"n\":\"Explosion\"},{\"t\":3,\"p\":1,\"n\":\"Debris\"},{\"t\":3,\"p\":1,\"n\":\"Debris Count\"}]},{\"t\":6,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"DMDL - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"DMDT - Texture Files Hashes\"}]},{\"p\":1,\"n\":\"DSTF - End Marker\"}]}]}]},{\"t\":3,\"p\":1,\"n\":\"YNAM - Sound - Pick Up\"},{\"t\":3,\"p\":1,\"n\":\"ZNAM - Sound - Drop\"},{\"t\":3,\"p\":1,\"n\":\"ETYP - Equiptment Type\"},{\"t\":5,\"p\":1,\"n\":\"DATA - Weight\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"ENIT - Effect Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Value\"},{\"t\":3,\"p\":1,\"n\":\"Flags?\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Withdrawal Effect\"},{\"t\":5,\"p\":1,\"n\":\"Addiction Chance\"},{\"t\":3,\"p\":1,\"n\":\"Sound - Consume\"}]},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Effects\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Effect\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"EFID - Base Effect\"},{\"t\":6,\"p\":1,\"n\":\"EFIT - \",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Magnitude\"},{\"t\":3,\"p\":1,\"n\":\"Area\"},{\"t\":3,\"p\":1,\"n\":\"Duration\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Actor Value\"}]},{\"t\":8,\"p\":1,\"n\":\"Conditions\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"CTDA - Condition\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":5,\"p\":1,\"n\":\"Comparison Value - Float\"},{\"t\":3,\"p\":1,\"n\":\"Comparison Value - Global\"},{\"t\":3,\"p\":1,\"n\":\"Function\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":11,\"p\":1,\"n\":\"None\"},{\"t\":3,\"p\":1,\"n\":\"Integer\"},{\"t\":3,\"p\":1,\"n\":\"Variable Name (INVALID)\"},{\"t\":3,\"p\":1,\"n\":\"Sex\"},{\"t\":3,\"p\":1,\"n\":\"Actor Value\"},{\"t\":3,\"p\":1,\"n\":\"Crime Type\"},{\"t\":3,\"p\":1,\"n\":\"Axis\"},{\"t\":3,\"p\":1,\"n\":\"Quest Stage (INVALID)\"},{\"t\":3,\"p\":1,\"n\":\"Misc Stat\"},{\"t\":3,\"p\":1,\"n\":\"Alignment\"},{\"t\":3,\"p\":1,\"n\":\"Equip Type\"},{\"t\":3,\"p\":1,\"n\":\"Form Type\"},{\"t\":3,\"p\":1,\"n\":\"Critical Stage\"},{\"t\":3,\"p\":1,\"n\":\"Object Reference\"},{\"t\":3,\"p\":1,\"n\":\"Inventory Object\"},{\"t\":3,\"p\":1,\"n\":\"Actor\"},{\"t\":3,\"p\":1,\"n\":\"Voice Type\"},{\"t\":3,\"p\":1,\"n\":\"Idle\"},{\"t\":3,\"p\":1,\"n\":\"Form List\"},{\"t\":3,\"p\":1,\"n\":\"Note\"},{\"t\":3,\"p\":1,\"n\":\"Quest\"},{\"t\":3,\"p\":1,\"n\":\"Faction\"},{\"t\":3,\"p\":1,\"n\":\"Weapon\"},{\"t\":3,\"p\":1,\"n\":\"Cell\"},{\"t\":3,\"p\":1,\"n\":\"Class\"},{\"t\":3,\"p\":1,\"n\":\"Race\"},{\"t\":3,\"p\":1,\"n\":\"Actor Base\"},{\"t\":3,\"p\":1,\"n\":\"Global\"},{\"t\":3,\"p\":1,\"n\":\"Weather\"},{\"t\":3,\"p\":1,\"n\":\"Package\"},{\"t\":3,\"p\":1,\"n\":\"Encounter Zone\"},{\"t\":3,\"p\":1,\"n\":\"Perk\"},{\"t\":3,\"p\":1,\"n\":\"Owner\"},{\"t\":3,\"p\":1,\"n\":\"Furniture\"},{\"t\":3,\"p\":1,\"n\":\"Effect Item\"},{\"t\":3,\"p\":1,\"n\":\"Base Effect\"},{\"t\":3,\"p\":1,\"n\":\"Worldspace\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Function\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Param (INVALID)\"},{\"t\":3,\"p\":1,\"n\":\"Creature Type\"},{\"t\":3,\"p\":1,\"n\":\"Menu Mode\"},{\"t\":3,\"p\":1,\"n\":\"Player Action\"},{\"t\":3,\"p\":1,\"n\":\"Body Location\"},{\"t\":3,\"p\":1,\"n\":\"Referenceable Object\"},{\"t\":3,\"p\":1,\"n\":\"Variable Name\"},{\"t\":3,\"p\":1,\"n\":\"Quest Stage\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Function (INVALID)\"},{\"t\":3,\"p\":1,\"n\":\"Weapon List\"},{\"t\":3,\"p\":1,\"n\":\"Target\"},{\"t\":3,\"p\":1,\"n\":\"Target List\"},{\"t\":3,\"p\":1,\"n\":\"Target Part\"},{\"t\":3,\"p\":1,\"n\":\"VATS Action\"},{\"t\":3,\"p\":1,\"n\":\"Critical Effect\"},{\"t\":3,\"p\":1,\"n\":\"Critical Effect List\"},{\"t\":3,\"p\":1,\"n\":\"Weapon Type\"},{\"t\":3,\"p\":1,\"n\":\"Run On\"},{\"t\":3,\"p\":1,\"n\":\"Reference\"}]}]}]}]}]},{\"t\":1,\"p\":1,\"n\":\"AMMO - Ammunition\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"X1\"},{\"t\":3,\"p\":1,\"n\":\"Y1\"},{\"t\":3,\"p\":1,\"n\":\"Z1\"},{\"t\":3,\"p\":1,\"n\":\"X2\"},{\"t\":3,\"p\":1,\"n\":\"Y2\"},{\"t\":3,\"p\":1,\"n\":\"Z2\"}]},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"},{\"t\":11,\"n\":\"MODB - Unknown\"},{\"t\":11,\"p\":1,\"n\":\"MODT - Texture Files Hashes\"},{\"t\":7,\"p\":1,\"n\":\"MODS - Alternate Textures\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"3D Name\"},{\"t\":3,\"p\":1,\"n\":\"New Texture\"},{\"t\":3,\"p\":1,\"n\":\"3D Index\"}]}]},{\"t\":3,\"p\":1,\"n\":\"MODD - FaceGen Model Flags\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Icon\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"ICON - Large Icon filename\"},{\"t\":2,\"p\":1,\"n\":\"MICO - Small Icon filename\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Destructable\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"DEST - Header\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Health\"},{\"t\":3,\"p\":1,\"n\":\"Count\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":8,\"p\":1,\"n\":\"Stages\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Stage\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"DSTD - Destruction Stage Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Health %\"},{\"t\":3,\"p\":1,\"n\":\"Index\"},{\"t\":3,\"p\":1,\"n\":\"Damage Stage\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":3,\"p\":1,\"n\":\"Self Damage per Second\"},{\"t\":3,\"p\":1,\"n\":\"Explosion\"},{\"t\":3,\"p\":1,\"n\":\"Debris\"},{\"t\":3,\"p\":1,\"n\":\"Debris Count\"}]},{\"t\":6,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"DMDL - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"DMDT - Texture Files Hashes\"}]},{\"p\":1,\"n\":\"DSTF - End Marker\"}]}]}]},{\"t\":3,\"p\":1,\"n\":\"YNAM - Sound - Pick Up\"},{\"t\":3,\"p\":1,\"n\":\"ZNAM - Sound - Drop\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DATA - Data\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Speed\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Value\"},{\"t\":3,\"p\":1,\"n\":\"Clip Rounds\"}]},{\"t\":2,\"p\":1,\"n\":\"ONAM - Short Name\"}]},{\"t\":1,\"p\":1,\"n\":\"ANIO - Animated Object\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"},{\"t\":11,\"n\":\"MODB - Unknown\"},{\"t\":11,\"p\":1,\"n\":\"MODT - Texture Files Hashes\"},{\"t\":7,\"p\":1,\"n\":\"MODS - Alternate Textures\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"3D Name\"},{\"t\":3,\"p\":1,\"n\":\"New Texture\"},{\"t\":3,\"p\":1,\"n\":\"3D Index\"}]}]},{\"t\":3,\"p\":1,\"n\":\"MODD - FaceGen Model Flags\"}]},{\"t\":3,\"p\":1,\"n\":\"DATA - Animation\"}]},{\"t\":1,\"p\":1,\"n\":\"ARMA - Armor Addon\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"X1\"},{\"t\":3,\"p\":1,\"n\":\"Y1\"},{\"t\":3,\"p\":1,\"n\":\"Z1\"},{\"t\":3,\"p\":1,\"n\":\"X2\"},{\"t\":3,\"p\":1,\"n\":\"Y2\"},{\"t\":3,\"p\":1,\"n\":\"Z2\"}]},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"BMDT - Biped Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Biped Flags\"},{\"t\":3,\"p\":1,\"n\":\"General Flags\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Male biped model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"MODT - Texture Files Hashes\"},{\"t\":7,\"p\":1,\"n\":\"MODS - Alternate Textures\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"3D Name\"},{\"t\":3,\"p\":1,\"n\":\"New Texture\"},{\"t\":3,\"p\":1,\"n\":\"3D Index\"}]}]},{\"t\":3,\"p\":1,\"n\":\"MODD - FaceGen Model Flags\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Male world model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MOD2 - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"MO2T - Texture Files Hashes\"},{\"t\":7,\"p\":1,\"n\":\"MO2S - Alternate Textures\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"3D Name\"},{\"t\":3,\"p\":1,\"n\":\"New Texture\"},{\"t\":3,\"p\":1,\"n\":\"3D Index\"}]}]}]},{\"t\":2,\"p\":1,\"n\":\"ICON - Male icon filename\"},{\"t\":2,\"p\":1,\"n\":\"MICO - Male mico filename\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Female biped model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MOD3 - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"MO3T - Texture Files Hashes\"},{\"t\":7,\"p\":1,\"n\":\"MO3S - Alternate Textures\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"3D Name\"},{\"t\":3,\"p\":1,\"n\":\"New Texture\"},{\"t\":3,\"p\":1,\"n\":\"3D Index\"}]}]},{\"t\":3,\"p\":1,\"n\":\"MOSD - FaceGen Model Flags\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Female world model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MOD4 - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"MO4T - Texture Files Hashes\"},{\"t\":7,\"p\":1,\"n\":\"MO4S - Alternate Textures\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"3D Name\"},{\"t\":3,\"p\":1,\"n\":\"New Texture\"},{\"t\":3,\"p\":1,\"n\":\"3D Index\"}]}]}]},{\"t\":2,\"p\":1,\"n\":\"ICO2 - Female icon filename\"},{\"t\":2,\"p\":1,\"n\":\"MIC2 - Female mico filename\"},{\"t\":3,\"p\":1,\"n\":\"ETYP - Equiptment Type\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DATA - Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Value\"},{\"t\":3,\"p\":1,\"n\":\"Max Condition\"},{\"t\":5,\"p\":1,\"n\":\"Weight\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DNAM - \",\"c\":[{\"t\":3,\"p\":1,\"n\":\"AR\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"}]}]},{\"t\":1,\"p\":1,\"n\":\"ARMO - Armor\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"X1\"},{\"t\":3,\"p\":1,\"n\":\"Y1\"},{\"t\":3,\"p\":1,\"n\":\"Z1\"},{\"t\":3,\"p\":1,\"n\":\"X2\"},{\"t\":3,\"p\":1,\"n\":\"Y2\"},{\"t\":3,\"p\":1,\"n\":\"Z2\"}]},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":3,\"p\":1,\"n\":\"SCRI - Script\"},{\"t\":3,\"p\":1,\"n\":\"EITM - Object Effect\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"BMDT - Biped Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Biped Flags\"},{\"t\":3,\"p\":1,\"n\":\"General Flags\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Male biped model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"MODT - Texture Files Hashes\"},{\"t\":7,\"p\":1,\"n\":\"MODS - Alternate Textures\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"3D Name\"},{\"t\":3,\"p\":1,\"n\":\"New Texture\"},{\"t\":3,\"p\":1,\"n\":\"3D Index\"}]}]},{\"t\":3,\"p\":1,\"n\":\"MODD - FaceGen Model Flags\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Male world model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MOD2 - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"MO2T - Texture Files Hashes\"},{\"t\":7,\"p\":1,\"n\":\"MO2S - Alternate Textures\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"3D Name\"},{\"t\":3,\"p\":1,\"n\":\"New Texture\"},{\"t\":3,\"p\":1,\"n\":\"3D Index\"}]}]}]},{\"t\":2,\"p\":1,\"n\":\"ICON - Male icon filename\"},{\"t\":2,\"p\":1,\"n\":\"MICO - Male mico filename\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Female biped model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MOD3 - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"MO3T - Texture Files Hashes\"},{\"t\":7,\"p\":1,\"n\":\"MO3S - Alternate Textures\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"3D Name\"},{\"t\":3,\"p\":1,\"n\":\"New Texture\"},{\"t\":3,\"p\":1,\"n\":\"3D Index\"}]}]},{\"t\":3,\"p\":1,\"n\":\"MOSD - FaceGen Model Flags\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Female world model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MOD4 - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"MO4T - Texture Files Hashes\"},{\"t\":7,\"p\":1,\"n\":\"MO4S - Alternate Textures\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"3D Name\"},{\"t\":3,\"p\":1,\"n\":\"New Texture\"},{\"t\":3,\"p\":1,\"n\":\"3D Index\"}]}]}]},{\"t\":2,\"p\":1,\"n\":\"ICO2 - Female icon filename\"},{\"t\":2,\"p\":1,\"n\":\"MIC2 - Female mico filename\"},{\"t\":2,\"p\":1,\"n\":\"BMCT - Ragdoll Constraint Template\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Destructable\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"DEST - Header\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Health\"},{\"t\":3,\"p\":1,\"n\":\"Count\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":8,\"p\":1,\"n\":\"Stages\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Stage\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"DSTD - Destruction Stage Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Health %\"},{\"t\":3,\"p\":1,\"n\":\"Index\"},{\"t\":3,\"p\":1,\"n\":\"Damage Stage\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":3,\"p\":1,\"n\":\"Self Damage per Second\"},{\"t\":3,\"p\":1,\"n\":\"Explosion\"},{\"t\":3,\"p\":1,\"n\":\"Debris\"},{\"t\":3,\"p\":1,\"n\":\"Debris Count\"}]},{\"t\":6,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"DMDL - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"DMDT - Texture Files Hashes\"}]},{\"p\":1,\"n\":\"DSTF - End Marker\"}]}]}]},{\"t\":3,\"p\":1,\"n\":\"REPL - Repair List\"},{\"t\":3,\"p\":1,\"n\":\"BIPL - Biped Model List\"},{\"t\":3,\"p\":1,\"n\":\"ETYP - Equiptment Type\"},{\"t\":3,\"p\":1,\"n\":\"YNAM - Sound - Pick Up\"},{\"t\":3,\"p\":1,\"n\":\"ZNAM - Sound - Drop\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DATA - Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Value\"},{\"t\":3,\"p\":1,\"n\":\"Max Condition\"},{\"t\":5,\"p\":1,\"n\":\"Weight\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DNAM - \",\"c\":[{\"t\":3,\"p\":1,\"n\":\"AR\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"}]}]},{\"t\":1,\"p\":1,\"n\":\"ASPC - Acoustic Space\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"X1\"},{\"t\":3,\"p\":1,\"n\":\"Y1\"},{\"t\":3,\"p\":1,\"n\":\"Z1\"},{\"t\":3,\"p\":1,\"n\":\"X2\"},{\"t\":3,\"p\":1,\"n\":\"Y2\"},{\"t\":3,\"p\":1,\"n\":\"Z2\"}]},{\"t\":3,\"p\":1,\"n\":\"SNAM - Sound - Looping\"},{\"t\":3,\"p\":1,\"n\":\"RDAT - Use Sound from Region (Interiors Only)\"},{\"t\":3,\"p\":1,\"n\":\"ANAM - Environment Type\"}]},{\"t\":1,\"p\":1,\"n\":\"AVIF - ActorValue Information\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":2,\"p\":1,\"n\":\"DESC - Description\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Icon\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"ICON - Large Icon filename\"},{\"t\":2,\"p\":1,\"n\":\"MICO - Small Icon filename\"}]},{\"t\":2,\"p\":1,\"n\":\"ANAM - Short Name\"}]},{\"t\":1,\"p\":1,\"n\":\"BOOK - Book\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"X1\"},{\"t\":3,\"p\":1,\"n\":\"Y1\"},{\"t\":3,\"p\":1,\"n\":\"Z1\"},{\"t\":3,\"p\":1,\"n\":\"X2\"},{\"t\":3,\"p\":1,\"n\":\"Y2\"},{\"t\":3,\"p\":1,\"n\":\"Z2\"}]},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"},{\"t\":11,\"n\":\"MODB - Unknown\"},{\"t\":11,\"p\":1,\"n\":\"MODT - Texture Files Hashes\"},{\"t\":7,\"p\":1,\"n\":\"MODS - Alternate Textures\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"3D Name\"},{\"t\":3,\"p\":1,\"n\":\"New Texture\"},{\"t\":3,\"p\":1,\"n\":\"3D Index\"}]}]},{\"t\":3,\"p\":1,\"n\":\"MODD - FaceGen Model Flags\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Icon\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"ICON - Large Icon filename\"},{\"t\":2,\"p\":1,\"n\":\"MICO - Small Icon filename\"}]},{\"t\":3,\"p\":1,\"n\":\"SCRI - Script\"},{\"t\":2,\"p\":1,\"n\":\"DESC - Description\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Destructable\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"DEST - Header\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Health\"},{\"t\":3,\"p\":1,\"n\":\"Count\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":8,\"p\":1,\"n\":\"Stages\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Stage\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"DSTD - Destruction Stage Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Health %\"},{\"t\":3,\"p\":1,\"n\":\"Index\"},{\"t\":3,\"p\":1,\"n\":\"Damage Stage\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":3,\"p\":1,\"n\":\"Self Damage per Second\"},{\"t\":3,\"p\":1,\"n\":\"Explosion\"},{\"t\":3,\"p\":1,\"n\":\"Debris\"},{\"t\":3,\"p\":1,\"n\":\"Debris Count\"}]},{\"t\":6,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"DMDL - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"DMDT - Texture Files Hashes\"}]},{\"p\":1,\"n\":\"DSTF - End Marker\"}]}]}]},{\"t\":3,\"p\":1,\"n\":\"YNAM - Sound - Pick Up\"},{\"t\":3,\"p\":1,\"n\":\"ZNAM - Sound - Drop\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DATA - Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":3,\"p\":1,\"n\":\"Skill\"},{\"t\":3,\"p\":1,\"n\":\"Value\"},{\"t\":5,\"p\":1,\"n\":\"Weight\"}]}]},{\"t\":1,\"p\":1,\"n\":\"BPTD - Body Part Data\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"},{\"t\":11,\"n\":\"MODB - Unknown\"},{\"t\":11,\"p\":1,\"n\":\"MODT - Texture Files Hashes\"},{\"t\":7,\"p\":1,\"n\":\"MODS - Alternate Textures\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"3D Name\"},{\"t\":3,\"p\":1,\"n\":\"New Texture\"},{\"t\":3,\"p\":1,\"n\":\"3D Index\"}]}]},{\"t\":3,\"p\":1,\"n\":\"MODD - FaceGen Model Flags\"}]},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Body Parts\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Body Part\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"BPTN - Part Name\"},{\"t\":2,\"p\":1,\"n\":\"BPNN - Part Node\"},{\"t\":2,\"p\":1,\"n\":\"BPNT - VATS Target\"},{\"t\":2,\"p\":1,\"n\":\"BPNI - IK Data - Start Node\"},{\"t\":6,\"p\":1,\"n\":\"BPND - \",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Damage Mult\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":3,\"p\":1,\"n\":\"Part Type\"},{\"t\":3,\"p\":1,\"n\":\"Health Percent\"},{\"t\":3,\"p\":1,\"n\":\"Actor Value\"},{\"t\":3,\"p\":1,\"n\":\"To Hit Chance\"},{\"t\":3,\"p\":1,\"n\":\"Explodable - Explosion Chance %\"},{\"t\":3,\"p\":1,\"n\":\"Explodable - Debris Count\"},{\"t\":3,\"p\":1,\"n\":\"Explodable - Debris\"},{\"t\":3,\"p\":1,\"n\":\"Explodable - Explosion\"},{\"t\":5,\"p\":1,\"n\":\"Tracking Max Angle\"},{\"t\":5,\"p\":1,\"n\":\"Explodable - Debris Scale\"},{\"t\":3,\"p\":1,\"n\":\"Severable - Debris Count\"},{\"t\":3,\"p\":1,\"n\":\"Severable - Debris\"},{\"t\":3,\"p\":1,\"n\":\"Severable - Explosion\"},{\"t\":5,\"p\":1,\"n\":\"Severable - Debris Scale\"},{\"t\":6,\"p\":1,\"n\":\"Gore Effects Positioning\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Translate\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"X\"},{\"t\":5,\"p\":1,\"n\":\"Y\"},{\"t\":5,\"p\":1,\"n\":\"Z\"}]},{\"t\":6,\"p\":1,\"n\":\"Rotation\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"X\"},{\"t\":5,\"p\":1,\"n\":\"Y\"},{\"t\":5,\"p\":1,\"n\":\"Z\"}]}]},{\"t\":3,\"p\":1,\"n\":\"Severable - Impact DataSet\"},{\"t\":3,\"p\":1,\"n\":\"Explodable - Impact DataSet\"},{\"t\":3,\"p\":1,\"n\":\"Severable - Decal Count\"},{\"t\":3,\"p\":1,\"n\":\"Explodable - Decal Count\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":5,\"p\":1,\"n\":\"Limb Replacement Scale\"}]},{\"t\":2,\"p\":1,\"n\":\"NAM1 - Limb Replacement Model\"},{\"t\":2,\"p\":1,\"n\":\"NAM4 - Gore Effects - Target Bone\"},{\"t\":11,\"p\":1,\"n\":\"NAM5 - Texture Files Hashes\"}]}]},{\"t\":3,\"p\":1,\"n\":\"RAGA - Ragdoll\"}]},{\"t\":1,\"p\":1,\"n\":\"CAMS - Camera Shot\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"},{\"t\":11,\"n\":\"MODB - Unknown\"},{\"t\":11,\"p\":1,\"n\":\"MODT - Texture Files Hashes\"},{\"t\":7,\"p\":1,\"n\":\"MODS - Alternate Textures\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"3D Name\"},{\"t\":3,\"p\":1,\"n\":\"New Texture\"},{\"t\":3,\"p\":1,\"n\":\"3D Index\"}]}]},{\"t\":3,\"p\":1,\"n\":\"MODD - FaceGen Model Flags\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DATA - Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Action\"},{\"t\":3,\"p\":1,\"n\":\"Location\"},{\"t\":3,\"p\":1,\"n\":\"Target\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":6,\"p\":1,\"n\":\"Time Multipliers\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Player\"},{\"t\":5,\"p\":1,\"n\":\"Target\"},{\"t\":5,\"p\":1,\"n\":\"Global\"}]},{\"t\":5,\"p\":1,\"n\":\"Max Time\"},{\"t\":5,\"p\":1,\"n\":\"Min Time\"},{\"t\":5,\"p\":1,\"n\":\"Target % Between Actors\"}]},{\"t\":3,\"p\":1,\"n\":\"MNAM - Image Space Modifier\"}]},{\"t\":1,\"p\":1,\"n\":\"CELL - Cell\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":3,\"p\":1,\"n\":\"DATA - Flags\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"XCLC - Grid\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"X\"},{\"t\":3,\"p\":1,\"n\":\"Y\"},{\"t\":3,\"p\":1,\"n\":\"Force Hide Land\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"XCLL - Lighting\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Ambient Color\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Directional Color\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Fog Color\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":5,\"p\":1,\"n\":\"Fog Near\"},{\"t\":5,\"p\":1,\"n\":\"Fog Far\"},{\"t\":3,\"p\":1,\"n\":\"Directional Rotation XY\"},{\"t\":3,\"p\":1,\"n\":\"Directional Rotation Z\"},{\"t\":5,\"p\":1,\"n\":\"Directional Fade\"},{\"t\":5,\"p\":1,\"n\":\"Fog Clip Dist\"},{\"t\":5,\"p\":1,\"n\":\"Fog Power\"}]},{\"t\":7,\"n\":\"IMPF - Footstep Materials\",\"c\":[{\"t\":2,\"n\":\"Unknown\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Light Template\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"LTMP - Template\"},{\"t\":3,\"p\":1,\"n\":\"LNAM - Inherit\"}]},{\"t\":5,\"p\":1,\"n\":\"XCLW - Water Height\"},{\"t\":2,\"p\":1,\"n\":\"XNAM - Water Noise Texture\"},{\"t\":7,\"p\":1,\"n\":\"XCLR - Regions\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Region\"}]},{\"t\":3,\"p\":1,\"n\":\"XCIM - Image Space\"},{\"t\":11,\"n\":\"XCET - Unknown\"},{\"t\":3,\"p\":1,\"n\":\"XEZN - Encounter Zone\"},{\"t\":3,\"p\":1,\"n\":\"XCCM - Climate\"},{\"t\":3,\"p\":1,\"n\":\"XCWT - Water\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Ownership\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"XOWN - Owner\"},{\"t\":3,\"p\":1,\"n\":\"XRNK - Faction rank\"}]},{\"t\":3,\"p\":1,\"n\":\"XCAS - Acoustic Space\"},{\"t\":11,\"n\":\"XCMT - Unused\"},{\"t\":3,\"p\":1,\"n\":\"XCMO - Music Type\"}]},{\"t\":1,\"p\":1,\"n\":\"CLAS - Class\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":2,\"p\":1,\"n\":\"DESC - Description\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Icon\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"ICON - Large Icon filename\"},{\"t\":2,\"p\":1,\"n\":\"MICO - Small Icon filename\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DATA - \",\"c\":[{\"t\":7,\"p\":1,\"n\":\"Tag Skills\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Tag Skill\"}]},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":3,\"p\":1,\"n\":\"Buys\\/Sells and Services\"},{\"t\":3,\"p\":1,\"n\":\"Teaches\"},{\"t\":3,\"p\":1,\"n\":\"Maximum training level\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":7,\"p\":1,\"n\":\"ATTR - Attributes\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Attribute\"}]}]},{\"t\":1,\"p\":1,\"n\":\"CLMT - Climate\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":7,\"p\":1,\"n\":\"WLST - Weather Types\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Weather Type\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Weather\"},{\"t\":3,\"p\":1,\"n\":\"Chance\"},{\"t\":3,\"p\":1,\"n\":\"Global\"}]}]},{\"t\":2,\"p\":1,\"n\":\"FNAM - Sun Texture\"},{\"t\":2,\"p\":1,\"n\":\"GNAM - Sun Glare Texture\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"},{\"t\":11,\"n\":\"MODB - Unknown\"},{\"t\":11,\"p\":1,\"n\":\"MODT - Texture Files Hashes\"},{\"t\":7,\"p\":1,\"n\":\"MODS - Alternate Textures\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"3D Name\"},{\"t\":3,\"p\":1,\"n\":\"New Texture\"},{\"t\":3,\"p\":1,\"n\":\"3D Index\"}]}]},{\"t\":3,\"p\":1,\"n\":\"MODD - FaceGen Model Flags\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"TNAM - Timing\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Sunrise\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Begin\"},{\"t\":3,\"p\":1,\"n\":\"End\"}]},{\"t\":6,\"p\":1,\"n\":\"Sunset\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Begin\"},{\"t\":3,\"p\":1,\"n\":\"End\"}]},{\"t\":3,\"p\":1,\"n\":\"Volatility\"},{\"t\":3,\"p\":1,\"n\":\"Moons \\/ Phase Length\"}]}]},{\"t\":1,\"p\":1,\"n\":\"COBJ - Constructible Object\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"X1\"},{\"t\":3,\"p\":1,\"n\":\"Y1\"},{\"t\":3,\"p\":1,\"n\":\"Z1\"},{\"t\":3,\"p\":1,\"n\":\"X2\"},{\"t\":3,\"p\":1,\"n\":\"Y2\"},{\"t\":3,\"p\":1,\"n\":\"Z2\"}]},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"},{\"t\":11,\"n\":\"MODB - Unknown\"},{\"t\":11,\"p\":1,\"n\":\"MODT - Texture Files Hashes\"},{\"t\":7,\"p\":1,\"n\":\"MODS - Alternate Textures\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"3D Name\"},{\"t\":3,\"p\":1,\"n\":\"New Texture\"},{\"t\":3,\"p\":1,\"n\":\"3D Index\"}]}]},{\"t\":3,\"p\":1,\"n\":\"MODD - FaceGen Model Flags\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Icon\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"ICON - Large Icon filename\"},{\"t\":2,\"p\":1,\"n\":\"MICO - Small Icon filename\"}]},{\"t\":3,\"p\":1,\"n\":\"SCRI - Script\"},{\"t\":3,\"p\":1,\"n\":\"YNAM - Sound - Pick Up\"},{\"t\":3,\"p\":1,\"n\":\"ZNAM - Sound - Drop\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DATA - \",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Value\"},{\"t\":5,\"p\":1,\"n\":\"Weight\"}]}]},{\"t\":1,\"p\":1,\"n\":\"CONT - Container\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"X1\"},{\"t\":3,\"p\":1,\"n\":\"Y1\"},{\"t\":3,\"p\":1,\"n\":\"Z1\"},{\"t\":3,\"p\":1,\"n\":\"X2\"},{\"t\":3,\"p\":1,\"n\":\"Y2\"},{\"t\":3,\"p\":1,\"n\":\"Z2\"}]},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"},{\"t\":11,\"n\":\"MODB - Unknown\"},{\"t\":11,\"p\":1,\"n\":\"MODT - Texture Files Hashes\"},{\"t\":7,\"p\":1,\"n\":\"MODS - Alternate Textures\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"3D Name\"},{\"t\":3,\"p\":1,\"n\":\"New Texture\"},{\"t\":3,\"p\":1,\"n\":\"3D Index\"}]}]},{\"t\":3,\"p\":1,\"n\":\"MODD - FaceGen Model Flags\"}]},{\"t\":3,\"p\":1,\"n\":\"SCRI - Script\"},{\"t\":10,\"p\":1,\"n\":\"Items\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Item\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"CNTO - Item\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Item\"},{\"t\":3,\"p\":1,\"n\":\"Count\"}]},{\"t\":6,\"p\":1,\"n\":\"COED - Extra Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Owner\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Global Variable\"},{\"t\":3,\"p\":1,\"n\":\"Required Rank\"},{\"t\":5,\"p\":1,\"n\":\"Item Condition\"}]}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Destructable\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"DEST - Header\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Health\"},{\"t\":3,\"p\":1,\"n\":\"Count\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":8,\"p\":1,\"n\":\"Stages\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Stage\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"DSTD - Destruction Stage Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Health %\"},{\"t\":3,\"p\":1,\"n\":\"Index\"},{\"t\":3,\"p\":1,\"n\":\"Damage Stage\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":3,\"p\":1,\"n\":\"Self Damage per Second\"},{\"t\":3,\"p\":1,\"n\":\"Explosion\"},{\"t\":3,\"p\":1,\"n\":\"Debris\"},{\"t\":3,\"p\":1,\"n\":\"Debris Count\"}]},{\"t\":6,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"DMDL - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"DMDT - Texture Files Hashes\"}]},{\"p\":1,\"n\":\"DSTF - End Marker\"}]}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DATA - \",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":5,\"p\":1,\"n\":\"Weight\"}]},{\"t\":3,\"p\":1,\"n\":\"SNAM - Sound - Open\"},{\"t\":3,\"p\":1,\"n\":\"QNAM - Sound - Close\"}]},{\"t\":1,\"p\":1,\"n\":\"CPTH - Camera Path\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Conditions\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"CTDA - Condition\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":5,\"p\":1,\"n\":\"Comparison Value - Float\"},{\"t\":3,\"p\":1,\"n\":\"Comparison Value - Global\"},{\"t\":3,\"p\":1,\"n\":\"Function\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":11,\"p\":1,\"n\":\"None\"},{\"t\":3,\"p\":1,\"n\":\"Integer\"},{\"t\":3,\"p\":1,\"n\":\"Variable Name (INVALID)\"},{\"t\":3,\"p\":1,\"n\":\"Sex\"},{\"t\":3,\"p\":1,\"n\":\"Actor Value\"},{\"t\":3,\"p\":1,\"n\":\"Crime Type\"},{\"t\":3,\"p\":1,\"n\":\"Axis\"},{\"t\":3,\"p\":1,\"n\":\"Quest Stage (INVALID)\"},{\"t\":3,\"p\":1,\"n\":\"Misc Stat\"},{\"t\":3,\"p\":1,\"n\":\"Alignment\"},{\"t\":3,\"p\":1,\"n\":\"Equip Type\"},{\"t\":3,\"p\":1,\"n\":\"Form Type\"},{\"t\":3,\"p\":1,\"n\":\"Critical Stage\"},{\"t\":3,\"p\":1,\"n\":\"Object Reference\"},{\"t\":3,\"p\":1,\"n\":\"Inventory Object\"},{\"t\":3,\"p\":1,\"n\":\"Actor\"},{\"t\":3,\"p\":1,\"n\":\"Voice Type\"},{\"t\":3,\"p\":1,\"n\":\"Idle\"},{\"t\":3,\"p\":1,\"n\":\"Form List\"},{\"t\":3,\"p\":1,\"n\":\"Note\"},{\"t\":3,\"p\":1,\"n\":\"Quest\"},{\"t\":3,\"p\":1,\"n\":\"Faction\"},{\"t\":3,\"p\":1,\"n\":\"Weapon\"},{\"t\":3,\"p\":1,\"n\":\"Cell\"},{\"t\":3,\"p\":1,\"n\":\"Class\"},{\"t\":3,\"p\":1,\"n\":\"Race\"},{\"t\":3,\"p\":1,\"n\":\"Actor Base\"},{\"t\":3,\"p\":1,\"n\":\"Global\"},{\"t\":3,\"p\":1,\"n\":\"Weather\"},{\"t\":3,\"p\":1,\"n\":\"Package\"},{\"t\":3,\"p\":1,\"n\":\"Encounter Zone\"},{\"t\":3,\"p\":1,\"n\":\"Perk\"},{\"t\":3,\"p\":1,\"n\":\"Owner\"},{\"t\":3,\"p\":1,\"n\":\"Furniture\"},{\"t\":3,\"p\":1,\"n\":\"Effect Item\"},{\"t\":3,\"p\":1,\"n\":\"Base Effect\"},{\"t\":3,\"p\":1,\"n\":\"Worldspace\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Function\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Param (INVALID)\"},{\"t\":3,\"p\":1,\"n\":\"Creature Type\"},{\"t\":3,\"p\":1,\"n\":\"Menu Mode\"},{\"t\":3,\"p\":1,\"n\":\"Player Action\"},{\"t\":3,\"p\":1,\"n\":\"Body Location\"},{\"t\":3,\"p\":1,\"n\":\"Referenceable Object\"},{\"t\":3,\"p\":1,\"n\":\"Variable Name\"},{\"t\":3,\"p\":1,\"n\":\"Quest Stage\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Function (INVALID)\"},{\"t\":3,\"p\":1,\"n\":\"Weapon List\"},{\"t\":3,\"p\":1,\"n\":\"Target\"},{\"t\":3,\"p\":1,\"n\":\"Target List\"},{\"t\":3,\"p\":1,\"n\":\"Target Part\"},{\"t\":3,\"p\":1,\"n\":\"VATS Action\"},{\"t\":3,\"p\":1,\"n\":\"Critical Effect\"},{\"t\":3,\"p\":1,\"n\":\"Critical Effect List\"},{\"t\":3,\"p\":1,\"n\":\"Weapon Type\"},{\"t\":3,\"p\":1,\"n\":\"Run On\"},{\"t\":3,\"p\":1,\"n\":\"Reference\"}]}]},{\"t\":7,\"p\":1,\"n\":\"ANAM - Related Camera Paths\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Related Camera Path\"}]},{\"t\":3,\"p\":1,\"n\":\"DATA - Camera Zoom\"},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Camera Shots\",\"d\":1,\"c\":[{\"t\":3,\"p\":1,\"n\":\"SNAM - Camera Shot\"}]}]},{\"t\":1,\"p\":1,\"n\":\"CREA - Creature\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"X1\"},{\"t\":3,\"p\":1,\"n\":\"Y1\"},{\"t\":3,\"p\":1,\"n\":\"Z1\"},{\"t\":3,\"p\":1,\"n\":\"X2\"},{\"t\":3,\"p\":1,\"n\":\"Y2\"},{\"t\":3,\"p\":1,\"n\":\"Z2\"}]},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"},{\"t\":11,\"n\":\"MODB - Unknown\"},{\"t\":11,\"p\":1,\"n\":\"MODT - Texture Files Hashes\"},{\"t\":7,\"p\":1,\"n\":\"MODS - Alternate Textures\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"3D Name\"},{\"t\":3,\"p\":1,\"n\":\"New Texture\"},{\"t\":3,\"p\":1,\"n\":\"3D Index\"}]}]},{\"t\":3,\"p\":1,\"n\":\"MODD - FaceGen Model Flags\"}]},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Actor Effects\",\"d\":1,\"c\":[{\"t\":3,\"p\":1,\"n\":\"SPLO - Actor Effect\"}]},{\"t\":3,\"p\":1,\"n\":\"EITM - Unarmed Attack Effect\"},{\"t\":3,\"p\":1,\"n\":\"EAMT - Unarmed Attack Animation\"},{\"t\":7,\"p\":1,\"n\":\"NIFZ - Model List\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"Model\"}]},{\"t\":11,\"n\":\"NIFT - Texture Files Hashes\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"ACBS - Configuration\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":3,\"p\":1,\"n\":\"Fatigue\"},{\"t\":3,\"p\":1,\"n\":\"Barter gold\"},{\"t\":3,\"p\":1,\"n\":\"Level\"},{\"t\":3,\"p\":1,\"n\":\"Level Mult\"},{\"t\":3,\"p\":1,\"n\":\"Calc min\"},{\"t\":3,\"p\":1,\"n\":\"Calc max\"},{\"t\":3,\"p\":1,\"n\":\"Speed Multiplier\"},{\"t\":5,\"p\":1,\"n\":\"Karma (Alignment)\"},{\"t\":3,\"p\":1,\"n\":\"Disposition Base\"},{\"t\":3,\"p\":1,\"n\":\"Template Flags\"}]},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Factions\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"SNAM - Faction\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Faction\"},{\"t\":3,\"p\":1,\"n\":\"Rank\"},{\"t\":11,\"n\":\"Unused\"}]}]},{\"t\":3,\"p\":1,\"n\":\"INAM - Death item\"},{\"t\":3,\"p\":1,\"n\":\"VTCK - Voice\"},{\"t\":3,\"p\":1,\"n\":\"TPLT - Template\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Destructable\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"DEST - Header\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Health\"},{\"t\":3,\"p\":1,\"n\":\"Count\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":8,\"p\":1,\"n\":\"Stages\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Stage\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"DSTD - Destruction Stage Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Health %\"},{\"t\":3,\"p\":1,\"n\":\"Index\"},{\"t\":3,\"p\":1,\"n\":\"Damage Stage\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":3,\"p\":1,\"n\":\"Self Damage per Second\"},{\"t\":3,\"p\":1,\"n\":\"Explosion\"},{\"t\":3,\"p\":1,\"n\":\"Debris\"},{\"t\":3,\"p\":1,\"n\":\"Debris Count\"}]},{\"t\":6,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"DMDL - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"DMDT - Texture Files Hashes\"}]},{\"p\":1,\"n\":\"DSTF - End Marker\"}]}]}]},{\"t\":3,\"p\":1,\"n\":\"SCRI - Script\"},{\"t\":10,\"p\":1,\"n\":\"Items\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Item\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"CNTO - Item\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Item\"},{\"t\":3,\"p\":1,\"n\":\"Count\"}]},{\"t\":6,\"p\":1,\"n\":\"COED - Extra Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Owner\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Global Variable\"},{\"t\":3,\"p\":1,\"n\":\"Required Rank\"},{\"t\":5,\"p\":1,\"n\":\"Item Condition\"}]}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"AIDT - AI Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Aggression\"},{\"t\":3,\"p\":1,\"n\":\"Confidence\"},{\"t\":3,\"p\":1,\"n\":\"Energy Level\"},{\"t\":3,\"p\":1,\"n\":\"Responsibility\"},{\"t\":3,\"p\":1,\"n\":\"Mood\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Buys\\/Sells and Services\"},{\"t\":3,\"p\":1,\"n\":\"Teaches\"},{\"t\":3,\"p\":1,\"n\":\"Maximum training level\"},{\"t\":3,\"p\":1,\"n\":\"Assistance\"},{\"t\":3,\"p\":1,\"n\":\"Aggro Radius Behavior\"},{\"t\":3,\"p\":1,\"n\":\"Aggro Radius\"}]},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Packages\",\"d\":1,\"c\":[{\"t\":3,\"p\":1,\"n\":\"PKID - Package\"}]},{\"t\":7,\"p\":1,\"n\":\"KFFZ - Animations\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"Animation\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DATA - \",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Combat Skill\"},{\"t\":3,\"p\":1,\"n\":\"Magic Skill\"},{\"t\":3,\"p\":1,\"n\":\"Stealth Skill\"},{\"t\":3,\"p\":1,\"n\":\"Health\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Damage\"},{\"t\":7,\"p\":1,\"n\":\"Attributes\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Attribute\"}]}]},{\"t\":3,\"p\":1,\"n\":\"RNAM - Attack reach\"},{\"t\":3,\"p\":1,\"n\":\"ZNAM - Combat Style\"},{\"t\":3,\"p\":1,\"n\":\"PNAM - Body Part Data\"},{\"t\":5,\"p\":1,\"n\":\"TNAM - Turning Speed\"},{\"t\":5,\"p\":1,\"n\":\"BNAM - Base Scale\"},{\"t\":5,\"p\":1,\"n\":\"WNAM - Foot Weight\"},{\"t\":3,\"p\":1,\"n\":\"NAM4 - Impact Material Type\"},{\"t\":3,\"p\":1,\"n\":\"NAM5 - Sound Level\"},{\"t\":3,\"p\":1,\"n\":\"CSCR - Inherits Sounds from\"},{\"t\":10,\"p\":1,\"n\":\"Sound Types\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Sound Type\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"CSDT - Type\"},{\"t\":10,\"p\":1,\"n\":\"Sounds\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Sound\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"CSDI - Sound\"},{\"t\":3,\"p\":1,\"n\":\"CSDC - Sound Chance\"}]}]}]}]},{\"t\":3,\"p\":1,\"n\":\"CNAM - Impact Dataset\"},{\"t\":3,\"p\":1,\"n\":\"LNAM - Melee Weapon List\"}]},{\"t\":1,\"p\":1,\"n\":\"CSTY - Combat Style\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"CSTD - Advanced - Standard\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Maneuver Decision - Dodge % Chance\"},{\"t\":3,\"p\":1,\"n\":\"Maneuver Decision - Left\\/Right % Chance\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":5,\"p\":1,\"n\":\"Maneuver Decision - Dodge L\\/R Timer (min)\"},{\"t\":5,\"p\":1,\"n\":\"Maneuver Decision - Dodge L\\/R Timer (max)\"},{\"t\":5,\"p\":1,\"n\":\"Maneuver Decision - Dodge Forward Timer (min)\"},{\"t\":5,\"p\":1,\"n\":\"Maneuver Decision - Dodge Forward Timer (max)\"},{\"t\":5,\"p\":1,\"n\":\"Maneuver Decision - Dodge Back Timer Min\"},{\"t\":5,\"p\":1,\"n\":\"Maneuver Decision - Dodge Back Timer Max\"},{\"t\":5,\"p\":1,\"n\":\"Maneuver Decision - Idle Timer min\"},{\"t\":5,\"p\":1,\"n\":\"Maneuver Decision - Idle Timer max\"},{\"t\":3,\"p\":1,\"n\":\"Melee Decision - Block % Chance\"},{\"t\":3,\"p\":1,\"n\":\"Melee Decision - Attack % Chance\"},{\"t\":5,\"p\":1,\"n\":\"Melee Decision - Recoil\\/Stagger Bonus to Attack\"},{\"t\":5,\"p\":1,\"n\":\"Melee Decision - Unconscious Bonus to Attack\"},{\"t\":5,\"p\":1,\"n\":\"Melee Decision - Hand-To-Hand Bonus to Attack\"},{\"t\":3,\"p\":1,\"n\":\"Melee Decision - Power Attacks - Power Attack % Chance\"},{\"t\":5,\"p\":1,\"n\":\"Melee Decision - Power Attacks - Recoil\\/Stagger Bonus to Power\"},{\"t\":5,\"p\":1,\"n\":\"Melee Decision - Power Attacks - Unconscious Bonus to Power Attack\"},{\"t\":3,\"p\":1,\"n\":\"Melee Decision - Power Attacks - Normal\"},{\"t\":3,\"p\":1,\"n\":\"Melee Decision - Power Attacks - Forward\"},{\"t\":3,\"p\":1,\"n\":\"Melee Decision - Power Attacks - Back\"},{\"t\":3,\"p\":1,\"n\":\"Melee Decision - Power Attacks - Left\"},{\"t\":3,\"p\":1,\"n\":\"Melee Decision - Power Attacks - Right\"},{\"t\":5,\"p\":1,\"n\":\"Melee Decision - Hold Timer (min)\"},{\"t\":5,\"p\":1,\"n\":\"Melee Decision - Hold Timer (max)\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":3,\"p\":1,\"n\":\"Maneuver Decision - Acrobatic Dodge % Chance\"},{\"t\":3,\"p\":1,\"n\":\"Melee Decision - Power Attacks - Rushing Attack % Chance\"},{\"t\":5,\"p\":1,\"n\":\"Melee Decision - Power Attacks - Rushing Attack Distance Mult\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"CSAD - Advanced - Advanced\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Dodge Fatigue Mod Mult\"},{\"t\":5,\"p\":1,\"n\":\"Dodge Fatigue Mod Base\"},{\"t\":5,\"p\":1,\"n\":\"Encumb. Speed Mod Base\"},{\"t\":5,\"p\":1,\"n\":\"Encumb. Speed Mod Mult\"},{\"t\":5,\"p\":1,\"n\":\"Dodge While Under Attack Mult\"},{\"t\":5,\"p\":1,\"n\":\"Dodge Not Under Attack Mult\"},{\"t\":5,\"p\":1,\"n\":\"Dodge Back While Under Attack Mult\"},{\"t\":5,\"p\":1,\"n\":\"Dodge Back Not Under Attack Mult\"},{\"t\":5,\"p\":1,\"n\":\"Dodge Forward While Attacking Mult\"},{\"t\":5,\"p\":1,\"n\":\"Dodge Forward Not Attacking Mult\"},{\"t\":5,\"p\":1,\"n\":\"Block Skill Modifier Mult\"},{\"t\":5,\"p\":1,\"n\":\"Block Skill Modifier Base\"},{\"t\":5,\"p\":1,\"n\":\"Block While Under Attack Mult\"},{\"t\":5,\"p\":1,\"n\":\"Block Not Under Attack Mult\"},{\"t\":5,\"p\":1,\"n\":\"Attack Skill Modifier Mult\"},{\"t\":5,\"p\":1,\"n\":\"Attack Skill Modifier Base\"},{\"t\":5,\"p\":1,\"n\":\"Attack While Under Attack Mult\"},{\"t\":5,\"p\":1,\"n\":\"Attack Not Under Attack Mult\"},{\"t\":5,\"p\":1,\"n\":\"Attack During Block Mult\"},{\"t\":5,\"p\":1,\"n\":\"Power Att. Fatigue Mod Base\"},{\"t\":5,\"p\":1,\"n\":\"Power Att. Fatigue Mod Mult\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"CSSD - Simple\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Cover Search Radius\"},{\"t\":5,\"p\":1,\"n\":\"Take Cover Chance\"},{\"t\":5,\"p\":1,\"n\":\"Wait Timer (min)\"},{\"t\":5,\"p\":1,\"n\":\"Wait Timer (max)\"},{\"t\":5,\"p\":1,\"n\":\"Wait to Fire Timer (min)\"},{\"t\":5,\"p\":1,\"n\":\"Wait to Fire Timer (max)\"},{\"t\":5,\"p\":1,\"n\":\"Fire Timer (min)\"},{\"t\":5,\"p\":1,\"n\":\"Fire Timer (max)\"},{\"t\":5,\"p\":1,\"n\":\"Ranged Weapon Range Mult (min)\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Weapon Restrictions\"},{\"t\":5,\"p\":1,\"n\":\"Ranged Weapon Range Mult (max)\"},{\"t\":5,\"p\":1,\"n\":\"Max Targeting FOV\"},{\"t\":5,\"p\":1,\"n\":\"Combat Radius\"},{\"t\":5,\"p\":1,\"n\":\"Semi-Auto Firing Delay Mult (min)\"},{\"t\":5,\"p\":1,\"n\":\"Semi-Auto Firing Delay Mult (max)\"}]}]},{\"t\":1,\"p\":1,\"n\":\"DEBR - Debris\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Models\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"DATA - Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Percentage\"},{\"t\":2,\"p\":1,\"n\":\"Model Filename\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"}]},{\"t\":11,\"p\":1,\"n\":\"MODT - Texture Files Hashes\"}]}]}]},{\"t\":1,\"p\":1,\"n\":\"DIAL - Dialog Topic\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Quests\",\"d\":1,\"c\":[{\"t\":3,\"p\":1,\"n\":\"QSTI - Quest\"}]},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Quests?\",\"d\":1,\"c\":[{\"t\":3,\"p\":1,\"n\":\"QSTR - Quest?\"}]},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":5,\"p\":1,\"n\":\"PNAM - Priority\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DATA - \",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"}]}]},{\"t\":1,\"p\":1,\"n\":\"DOOR - Door\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"X1\"},{\"t\":3,\"p\":1,\"n\":\"Y1\"},{\"t\":3,\"p\":1,\"n\":\"Z1\"},{\"t\":3,\"p\":1,\"n\":\"X2\"},{\"t\":3,\"p\":1,\"n\":\"Y2\"},{\"t\":3,\"p\":1,\"n\":\"Z2\"}]},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"},{\"t\":11,\"n\":\"MODB - Unknown\"},{\"t\":11,\"p\":1,\"n\":\"MODT - Texture Files Hashes\"},{\"t\":7,\"p\":1,\"n\":\"MODS - Alternate Textures\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"3D Name\"},{\"t\":3,\"p\":1,\"n\":\"New Texture\"},{\"t\":3,\"p\":1,\"n\":\"3D Index\"}]}]},{\"t\":3,\"p\":1,\"n\":\"MODD - FaceGen Model Flags\"}]},{\"t\":3,\"p\":1,\"n\":\"SCRI - Script\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Destructable\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"DEST - Header\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Health\"},{\"t\":3,\"p\":1,\"n\":\"Count\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":8,\"p\":1,\"n\":\"Stages\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Stage\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"DSTD - Destruction Stage Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Health %\"},{\"t\":3,\"p\":1,\"n\":\"Index\"},{\"t\":3,\"p\":1,\"n\":\"Damage Stage\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":3,\"p\":1,\"n\":\"Self Damage per Second\"},{\"t\":3,\"p\":1,\"n\":\"Explosion\"},{\"t\":3,\"p\":1,\"n\":\"Debris\"},{\"t\":3,\"p\":1,\"n\":\"Debris Count\"}]},{\"t\":6,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"DMDL - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"DMDT - Texture Files Hashes\"}]},{\"p\":1,\"n\":\"DSTF - End Marker\"}]}]}]},{\"t\":3,\"p\":1,\"n\":\"SNAM - Sound - Open\"},{\"t\":3,\"p\":1,\"n\":\"ANAM - Sound - Close\"},{\"t\":3,\"p\":1,\"n\":\"BNAM - Sound - Looping\"},{\"t\":3,\"p\":1,\"n\":\"FNAM - Flags\"}]},{\"t\":1,\"p\":1,\"n\":\"ECZN - Encounter Zone\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DATA - \",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Owner\"},{\"t\":3,\"p\":1,\"n\":\"Rank\"},{\"t\":3,\"p\":1,\"n\":\"Minimum Level\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"}]}]},{\"t\":1,\"p\":1,\"n\":\"EFSH - Effect Shader\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"p\":1,\"n\":\"ICON - Fill Texture\"},{\"t\":2,\"p\":1,\"n\":\"ICO2 - Particle Shader Texture\"},{\"t\":2,\"p\":1,\"n\":\"NAM7 - Holes Texture\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DATA - \",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Membrane Shader - Source Blend Mode\"},{\"t\":3,\"p\":1,\"n\":\"Membrane Shader - Blend Operation\"},{\"t\":3,\"p\":1,\"n\":\"Membrane Shader - Z Test Function\"},{\"t\":6,\"p\":1,\"n\":\"Fill\\/Texture Effect - Color\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":5,\"p\":1,\"n\":\"Fill\\/Texture Effect - Alpha Fade In Time\"},{\"t\":5,\"p\":1,\"n\":\"Fill\\/Texture Effect - Full Alpha Time\"},{\"t\":5,\"p\":1,\"n\":\"Fill\\/Texture Effect - Alpha Fade Out Time\"},{\"t\":5,\"p\":1,\"n\":\"Fill\\/Texture Effect - Presistent Alpha Ratio\"},{\"t\":5,\"p\":1,\"n\":\"Fill\\/Texture Effect - Alpha Pulse Amplitude\"},{\"t\":5,\"p\":1,\"n\":\"Fill\\/Texture Effect - Alpha Pulse Frequency\"},{\"t\":5,\"p\":1,\"n\":\"Fill\\/Texture Effect - Texture Animation Speed (U)\"},{\"t\":5,\"p\":1,\"n\":\"Fill\\/Texture Effect - Texture Animation Speed (V)\"},{\"t\":5,\"p\":1,\"n\":\"Edge Effect - Fall Off\"},{\"t\":6,\"p\":1,\"n\":\"Edge Effect - Color\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":5,\"p\":1,\"n\":\"Edge Effect - Alpha Fade In Time\"},{\"t\":5,\"p\":1,\"n\":\"Edge Effect - Full Alpha Time\"},{\"t\":5,\"p\":1,\"n\":\"Edge Effect - Alpha Fade Out Time\"},{\"t\":5,\"p\":1,\"n\":\"Edge Effect - Persistent Alpha Ratio\"},{\"t\":5,\"p\":1,\"n\":\"Edge Effect - Alpha Pulse Amplitude\"},{\"t\":5,\"p\":1,\"n\":\"Edge Effect - Alpha Pusle Frequence\"},{\"t\":5,\"p\":1,\"n\":\"Fill\\/Texture Effect - Full Alpha Ratio\"},{\"t\":5,\"p\":1,\"n\":\"Edge Effect - Full Alpha Ratio\"},{\"t\":3,\"p\":1,\"n\":\"Membrane Shader - Dest Blend Mode\"},{\"t\":3,\"p\":1,\"n\":\"Particle Shader - Source Blend Mode\"},{\"t\":3,\"p\":1,\"n\":\"Particle Shader - Blend Operation\"},{\"t\":3,\"p\":1,\"n\":\"Particle Shader - Z Test Function\"},{\"t\":3,\"p\":1,\"n\":\"Particle Shader - Dest Blend Mode\"},{\"t\":5,\"p\":1,\"n\":\"Particle Shader - Particle Birth Ramp Up Time\"},{\"t\":5,\"p\":1,\"n\":\"Particle Shader - Full Particle Birth Time\"},{\"t\":5,\"p\":1,\"n\":\"Particle Shader - Particle Birth Ramp Down Time\"},{\"t\":5,\"p\":1,\"n\":\"Particle Shader - Full Particle Birth Ratio\"},{\"t\":5,\"p\":1,\"n\":\"Particle Shader - Persistant Particle Birth Ratio\"},{\"t\":5,\"p\":1,\"n\":\"Particle Shader - Particle Lifetime\"},{\"t\":5,\"p\":1,\"n\":\"Particle Shader - Particle Lifetime +\\/-\"},{\"t\":5,\"p\":1,\"n\":\"Particle Shader - Initial Speed Along Normal\"},{\"t\":5,\"p\":1,\"n\":\"Particle Shader - Acceleration Along Normal\"},{\"t\":5,\"p\":1,\"n\":\"Particle Shader - Initial Velocity #1\"},{\"t\":5,\"p\":1,\"n\":\"Particle Shader - Initial Velocity #2\"},{\"t\":5,\"p\":1,\"n\":\"Particle Shader - Initial Velocity #3\"},{\"t\":5,\"p\":1,\"n\":\"Particle Shader - Acceleration #1\"},{\"t\":5,\"p\":1,\"n\":\"Particle Shader - Acceleration #2\"},{\"t\":5,\"p\":1,\"n\":\"Particle Shader - Acceleration #3\"},{\"t\":5,\"p\":1,\"n\":\"Particle Shader - Scale Key 1\"},{\"t\":5,\"p\":1,\"n\":\"Particle Shader - Scale Key 2\"},{\"t\":5,\"p\":1,\"n\":\"Particle Shader - Scale Key 1 Time\"},{\"t\":5,\"p\":1,\"n\":\"Particle Shader - Scale Key 2 Time\"},{\"t\":6,\"p\":1,\"n\":\"Color Key 1 - Color\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Color Key 2 - Color\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Color Key 3 - Color\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":5,\"p\":1,\"n\":\"Color Key 1 - Color Alpha\"},{\"t\":5,\"p\":1,\"n\":\"Color Key 2 - Color Alpha\"},{\"t\":5,\"p\":1,\"n\":\"Color Key 3 - Color Alpha\"},{\"t\":5,\"p\":1,\"n\":\"Color Key 1 - Color Key Time\"},{\"t\":5,\"p\":1,\"n\":\"Color Key 2 - Color Key Time\"},{\"t\":5,\"p\":1,\"n\":\"Color Key 3 - Color Key Time\"},{\"t\":5,\"p\":1,\"n\":\"Particle Shader - Initial Speed Along Normal +\\/-\"},{\"t\":5,\"p\":1,\"n\":\"Particle Shader - Initial Rotation (deg)\"},{\"t\":5,\"p\":1,\"n\":\"Particle Shader - Initial Rotation (deg) +\\/-\"},{\"t\":5,\"p\":1,\"n\":\"Particle Shader - Rotation Speed (deg\\/sec)\"},{\"t\":5,\"p\":1,\"n\":\"Particle Shader - Rotation Speed (deg\\/sec) +\\/-\"},{\"t\":3,\"p\":1,\"n\":\"Addon Models\"},{\"t\":5,\"p\":1,\"n\":\"Holes - Start Time\"},{\"t\":5,\"p\":1,\"n\":\"Holes - End Time\"},{\"t\":5,\"p\":1,\"n\":\"Holes - Start Val\"},{\"t\":5,\"p\":1,\"n\":\"Holes - End Val\"},{\"t\":5,\"p\":1,\"n\":\"Edge Width (alpha units)\"},{\"t\":6,\"p\":1,\"n\":\"Edge Color\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":5,\"p\":1,\"n\":\"Explosion Wind Speed\"},{\"t\":3,\"p\":1,\"n\":\"Texture Count U\"},{\"t\":3,\"p\":1,\"n\":\"Texture Count V\"},{\"t\":5,\"p\":1,\"n\":\"Addon Models - Fade In Time\"},{\"t\":5,\"p\":1,\"n\":\"Addon Models - Fade Out Time\"},{\"t\":5,\"p\":1,\"n\":\"Addon Models - Scale Start\"},{\"t\":5,\"p\":1,\"n\":\"Addon Models - Scale End\"},{\"t\":5,\"p\":1,\"n\":\"Addon Models - Scale In Time\"},{\"t\":5,\"p\":1,\"n\":\"Addon Models - Scale Out Time\"}]}]},{\"t\":1,\"p\":1,\"n\":\"ENCH - Object Effect\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"ENIT - Effect Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"}]},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Effects\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Effect\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"EFID - Base Effect\"},{\"t\":6,\"p\":1,\"n\":\"EFIT - \",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Magnitude\"},{\"t\":3,\"p\":1,\"n\":\"Area\"},{\"t\":3,\"p\":1,\"n\":\"Duration\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Actor Value\"}]},{\"t\":8,\"p\":1,\"n\":\"Conditions\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"CTDA - Condition\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":5,\"p\":1,\"n\":\"Comparison Value - Float\"},{\"t\":3,\"p\":1,\"n\":\"Comparison Value - Global\"},{\"t\":3,\"p\":1,\"n\":\"Function\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":11,\"p\":1,\"n\":\"None\"},{\"t\":3,\"p\":1,\"n\":\"Integer\"},{\"t\":3,\"p\":1,\"n\":\"Variable Name (INVALID)\"},{\"t\":3,\"p\":1,\"n\":\"Sex\"},{\"t\":3,\"p\":1,\"n\":\"Actor Value\"},{\"t\":3,\"p\":1,\"n\":\"Crime Type\"},{\"t\":3,\"p\":1,\"n\":\"Axis\"},{\"t\":3,\"p\":1,\"n\":\"Quest Stage (INVALID)\"},{\"t\":3,\"p\":1,\"n\":\"Misc Stat\"},{\"t\":3,\"p\":1,\"n\":\"Alignment\"},{\"t\":3,\"p\":1,\"n\":\"Equip Type\"},{\"t\":3,\"p\":1,\"n\":\"Form Type\"},{\"t\":3,\"p\":1,\"n\":\"Critical Stage\"},{\"t\":3,\"p\":1,\"n\":\"Object Reference\"},{\"t\":3,\"p\":1,\"n\":\"Inventory Object\"},{\"t\":3,\"p\":1,\"n\":\"Actor\"},{\"t\":3,\"p\":1,\"n\":\"Voice Type\"},{\"t\":3,\"p\":1,\"n\":\"Idle\"},{\"t\":3,\"p\":1,\"n\":\"Form List\"},{\"t\":3,\"p\":1,\"n\":\"Note\"},{\"t\":3,\"p\":1,\"n\":\"Quest\"},{\"t\":3,\"p\":1,\"n\":\"Faction\"},{\"t\":3,\"p\":1,\"n\":\"Weapon\"},{\"t\":3,\"p\":1,\"n\":\"Cell\"},{\"t\":3,\"p\":1,\"n\":\"Class\"},{\"t\":3,\"p\":1,\"n\":\"Race\"},{\"t\":3,\"p\":1,\"n\":\"Actor Base\"},{\"t\":3,\"p\":1,\"n\":\"Global\"},{\"t\":3,\"p\":1,\"n\":\"Weather\"},{\"t\":3,\"p\":1,\"n\":\"Package\"},{\"t\":3,\"p\":1,\"n\":\"Encounter Zone\"},{\"t\":3,\"p\":1,\"n\":\"Perk\"},{\"t\":3,\"p\":1,\"n\":\"Owner\"},{\"t\":3,\"p\":1,\"n\":\"Furniture\"},{\"t\":3,\"p\":1,\"n\":\"Effect Item\"},{\"t\":3,\"p\":1,\"n\":\"Base Effect\"},{\"t\":3,\"p\":1,\"n\":\"Worldspace\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Function\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Param (INVALID)\"},{\"t\":3,\"p\":1,\"n\":\"Creature Type\"},{\"t\":3,\"p\":1,\"n\":\"Menu Mode\"},{\"t\":3,\"p\":1,\"n\":\"Player Action\"},{\"t\":3,\"p\":1,\"n\":\"Body Location\"},{\"t\":3,\"p\":1,\"n\":\"Referenceable Object\"},{\"t\":3,\"p\":1,\"n\":\"Variable Name\"},{\"t\":3,\"p\":1,\"n\":\"Quest Stage\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Function (INVALID)\"},{\"t\":3,\"p\":1,\"n\":\"Weapon List\"},{\"t\":3,\"p\":1,\"n\":\"Target\"},{\"t\":3,\"p\":1,\"n\":\"Target List\"},{\"t\":3,\"p\":1,\"n\":\"Target Part\"},{\"t\":3,\"p\":1,\"n\":\"VATS Action\"},{\"t\":3,\"p\":1,\"n\":\"Critical Effect\"},{\"t\":3,\"p\":1,\"n\":\"Critical Effect List\"},{\"t\":3,\"p\":1,\"n\":\"Weapon Type\"},{\"t\":3,\"p\":1,\"n\":\"Run On\"},{\"t\":3,\"p\":1,\"n\":\"Reference\"}]}]}]}]}]},{\"t\":1,\"p\":1,\"n\":\"EXPL - Explosion\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"X1\"},{\"t\":3,\"p\":1,\"n\":\"Y1\"},{\"t\":3,\"p\":1,\"n\":\"Z1\"},{\"t\":3,\"p\":1,\"n\":\"X2\"},{\"t\":3,\"p\":1,\"n\":\"Y2\"},{\"t\":3,\"p\":1,\"n\":\"Z2\"}]},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"},{\"t\":11,\"n\":\"MODB - Unknown\"},{\"t\":11,\"p\":1,\"n\":\"MODT - Texture Files Hashes\"},{\"t\":7,\"p\":1,\"n\":\"MODS - Alternate Textures\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"3D Name\"},{\"t\":3,\"p\":1,\"n\":\"New Texture\"},{\"t\":3,\"p\":1,\"n\":\"3D Index\"}]}]},{\"t\":3,\"p\":1,\"n\":\"MODD - FaceGen Model Flags\"}]},{\"t\":3,\"p\":1,\"n\":\"EITM - Object Effect\"},{\"t\":3,\"p\":1,\"n\":\"MNAM - Image Space Modifier\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DATA - Data\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Force\"},{\"t\":5,\"p\":1,\"n\":\"Damage\"},{\"t\":5,\"p\":1,\"n\":\"Radius\"},{\"t\":3,\"p\":1,\"n\":\"Light\"},{\"t\":3,\"p\":1,\"n\":\"Sound 1\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":5,\"p\":1,\"n\":\"IS Radius\"},{\"t\":3,\"p\":1,\"n\":\"Impact DataSet\"},{\"t\":3,\"p\":1,\"n\":\"Sound 2\"},{\"t\":6,\"p\":1,\"n\":\"Radiation\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Level\"},{\"t\":5,\"p\":1,\"n\":\"Dissipation Time\"},{\"t\":5,\"p\":1,\"n\":\"Radius\"}]},{\"t\":3,\"p\":1,\"n\":\"Sound Level\"}]},{\"t\":3,\"p\":1,\"n\":\"INAM - Placed Impact Object\"}]},{\"t\":1,\"p\":1,\"n\":\"EYES - Eyes\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":2,\"p\":1,\"n\":\"ICON - Texture\"},{\"t\":3,\"p\":1,\"n\":\"DATA - Flags\"}]},{\"t\":1,\"p\":1,\"n\":\"FACT - Faction\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Relations\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"XNAM - Relation\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Faction\"},{\"t\":3,\"p\":1,\"n\":\"Modifier\"},{\"t\":3,\"p\":1,\"n\":\"Group Combat Reaction\"}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DATA - \",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Flags 1\"},{\"t\":3,\"p\":1,\"n\":\"Flags 2\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":5,\"n\":\"CNAM - Unused\"},{\"t\":10,\"p\":1,\"n\":\"Ranks\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Rank\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"RNAM - Rank#\"},{\"t\":2,\"p\":1,\"n\":\"MNAM - Male\"},{\"t\":2,\"p\":1,\"n\":\"FNAM - Female\"},{\"t\":2,\"n\":\"INAM - Insignia (Unused)\"}]}]}]},{\"t\":1,\"p\":1,\"n\":\"FLST - FormID List\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"FormIDs\",\"d\":1,\"c\":[{\"t\":3,\"p\":1,\"n\":\"LNAM - FormID\"}]}]},{\"t\":1,\"p\":1,\"n\":\"FURN - Furniture\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"X1\"},{\"t\":3,\"p\":1,\"n\":\"Y1\"},{\"t\":3,\"p\":1,\"n\":\"Z1\"},{\"t\":3,\"p\":1,\"n\":\"X2\"},{\"t\":3,\"p\":1,\"n\":\"Y2\"},{\"t\":3,\"p\":1,\"n\":\"Z2\"}]},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"},{\"t\":11,\"n\":\"MODB - Unknown\"},{\"t\":11,\"p\":1,\"n\":\"MODT - Texture Files Hashes\"},{\"t\":7,\"p\":1,\"n\":\"MODS - Alternate Textures\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"3D Name\"},{\"t\":3,\"p\":1,\"n\":\"New Texture\"},{\"t\":3,\"p\":1,\"n\":\"3D Index\"}]}]},{\"t\":3,\"p\":1,\"n\":\"MODD - FaceGen Model Flags\"}]},{\"t\":3,\"p\":1,\"n\":\"SCRI - Script\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Destructable\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"DEST - Header\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Health\"},{\"t\":3,\"p\":1,\"n\":\"Count\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":8,\"p\":1,\"n\":\"Stages\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Stage\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"DSTD - Destruction Stage Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Health %\"},{\"t\":3,\"p\":1,\"n\":\"Index\"},{\"t\":3,\"p\":1,\"n\":\"Damage Stage\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":3,\"p\":1,\"n\":\"Self Damage per Second\"},{\"t\":3,\"p\":1,\"n\":\"Explosion\"},{\"t\":3,\"p\":1,\"n\":\"Debris\"},{\"t\":3,\"p\":1,\"n\":\"Debris Count\"}]},{\"t\":6,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"DMDL - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"DMDT - Texture Files Hashes\"}]},{\"p\":1,\"n\":\"DSTF - End Marker\"}]}]}]},{\"t\":11,\"n\":\"MNAM - Marker Flags\"}]},{\"t\":1,\"p\":1,\"n\":\"GLOB - Global\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":3,\"p\":1,\"n\":\"FNAM - Type\"},{\"t\":5,\"p\":1,\"n\":\"FLTV - Value\"}]},{\"t\":1,\"p\":1,\"n\":\"GMST - Game Setting\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"p\":1,\"n\":\"\"}]},{\"t\":1,\"p\":1,\"n\":\"GRAS - Grass\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"X1\"},{\"t\":3,\"p\":1,\"n\":\"Y1\"},{\"t\":3,\"p\":1,\"n\":\"Z1\"},{\"t\":3,\"p\":1,\"n\":\"X2\"},{\"t\":3,\"p\":1,\"n\":\"Y2\"},{\"t\":3,\"p\":1,\"n\":\"Z2\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"},{\"t\":11,\"n\":\"MODB - Unknown\"},{\"t\":11,\"p\":1,\"n\":\"MODT - Texture Files Hashes\"},{\"t\":7,\"p\":1,\"n\":\"MODS - Alternate Textures\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"3D Name\"},{\"t\":3,\"p\":1,\"n\":\"New Texture\"},{\"t\":3,\"p\":1,\"n\":\"3D Index\"}]}]},{\"t\":3,\"p\":1,\"n\":\"MODD - FaceGen Model Flags\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DATA - \",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Density\"},{\"t\":3,\"p\":1,\"n\":\"Min Slope\"},{\"t\":3,\"p\":1,\"n\":\"Max Slope\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Unit from water amount\"},{\"t\":3,\"p\":1,\"n\":\"Unit from water type\"},{\"t\":5,\"p\":1,\"n\":\"Position Range\"},{\"t\":5,\"p\":1,\"n\":\"Height Range\"},{\"t\":5,\"p\":1,\"n\":\"Color Range\"},{\"t\":5,\"p\":1,\"n\":\"Wave Period\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"}]}]},{\"t\":1,\"p\":1,\"n\":\"HAIR - Hair\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"},{\"t\":11,\"n\":\"MODB - Unknown\"},{\"t\":11,\"p\":1,\"n\":\"MODT - Texture Files Hashes\"},{\"t\":7,\"p\":1,\"n\":\"MODS - Alternate Textures\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"3D Name\"},{\"t\":3,\"p\":1,\"n\":\"New Texture\"},{\"t\":3,\"p\":1,\"n\":\"3D Index\"}]}]},{\"t\":3,\"p\":1,\"n\":\"MODD - FaceGen Model Flags\"}]},{\"t\":2,\"p\":1,\"n\":\"ICON - Texture\"},{\"t\":3,\"p\":1,\"n\":\"DATA - Flags\"}]},{\"t\":1,\"p\":1,\"n\":\"HDPT - Head Part\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"},{\"t\":11,\"n\":\"MODB - Unknown\"},{\"t\":11,\"p\":1,\"n\":\"MODT - Texture Files Hashes\"},{\"t\":7,\"p\":1,\"n\":\"MODS - Alternate Textures\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"3D Name\"},{\"t\":3,\"p\":1,\"n\":\"New Texture\"},{\"t\":3,\"p\":1,\"n\":\"3D Index\"}]}]},{\"t\":3,\"p\":1,\"n\":\"MODD - FaceGen Model Flags\"}]},{\"t\":3,\"p\":1,\"n\":\"DATA - Flags\"},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Extra Parts\",\"d\":1,\"c\":[{\"t\":3,\"p\":1,\"n\":\"HNAM - Part\"}]}]},{\"t\":1,\"p\":1,\"n\":\"IDLM - Idle Marker\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"X1\"},{\"t\":3,\"p\":1,\"n\":\"Y1\"},{\"t\":3,\"p\":1,\"n\":\"Z1\"},{\"t\":3,\"p\":1,\"n\":\"X2\"},{\"t\":3,\"p\":1,\"n\":\"Y2\"},{\"t\":3,\"p\":1,\"n\":\"Z2\"}]},{\"t\":3,\"p\":1,\"n\":\"IDLF - Flags\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"IDLC - \",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Animation Count\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":5,\"p\":1,\"n\":\"IDLT - Idle Timer Setting\"},{\"t\":7,\"p\":1,\"n\":\"IDLA - Animations\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Animation\"}]}]},{\"t\":1,\"p\":1,\"n\":\"IMAD - Image Space Adapter\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DNAM - Data Count\",\"c\":[{\"t\":3,\"n\":\"Flags\"},{\"t\":5,\"n\":\"Duration\"},{\"t\":6,\"n\":\"HDR\",\"c\":[{\"t\":3,\"n\":\"Eye Adapt Speed Mult\"},{\"t\":3,\"n\":\"Eye Adapt Speed Add\"},{\"t\":3,\"n\":\"Bloom Blur Radius Mult\"},{\"t\":3,\"n\":\"Bloom Blur Radius Add\"},{\"t\":3,\"n\":\"Bloom Threshold Mult\"},{\"t\":3,\"n\":\"Bloom Threshold Add\"},{\"t\":3,\"n\":\"Bloom Scale Mult\"},{\"t\":3,\"n\":\"Bloom Scale Add\"},{\"t\":3,\"n\":\"Target Lum Min Mult\"},{\"t\":3,\"n\":\"Target Lum Min Add\"},{\"t\":3,\"n\":\"Target Lum Max Mult\"},{\"t\":3,\"n\":\"Target Lum Max Add\"},{\"t\":3,\"n\":\"Sunlight Scale Mult\"},{\"t\":3,\"n\":\"Sunlight Scale Add\"},{\"t\":3,\"n\":\"Sky Scale Mult\"},{\"t\":3,\"n\":\"Sky Scale Add\"}]},{\"t\":3,\"n\":\"Unknown08 Mult\"},{\"t\":3,\"n\":\"Unknown48 Add\"},{\"t\":3,\"n\":\"Unknown09 Mult\"},{\"t\":3,\"n\":\"Unknown49 Add\"},{\"t\":3,\"n\":\"Unknown0A Mult\"},{\"t\":3,\"n\":\"Unknown4A Add\"},{\"t\":3,\"n\":\"Unknown0B Mult\"},{\"t\":3,\"n\":\"Unknown4B Add\"},{\"t\":3,\"n\":\"Unknown0C Mult\"},{\"t\":3,\"n\":\"Unknown4C Add\"},{\"t\":3,\"n\":\"Unknown0D Mult\"},{\"t\":3,\"n\":\"Unknown4D Add\"},{\"t\":3,\"n\":\"Unknown0E Mult\"},{\"t\":3,\"n\":\"Unknown4E Add\"},{\"t\":3,\"n\":\"Unknown0F Mult\"},{\"t\":3,\"n\":\"Unknown4F Add\"},{\"t\":3,\"n\":\"Unknown10 Mult\"},{\"t\":3,\"n\":\"Unknown50 Add\"},{\"t\":6,\"n\":\"Cinematic\",\"c\":[{\"t\":3,\"n\":\"Saturation Mult\"},{\"t\":3,\"n\":\"Saturation Add\"},{\"t\":3,\"n\":\"Brightness Mult\"},{\"t\":3,\"n\":\"Brightness Add\"},{\"t\":3,\"n\":\"Contrast Mult\"},{\"t\":3,\"n\":\"Contrast Add\"}]},{\"t\":3,\"n\":\"Unknown14 Mult\"},{\"t\":3,\"n\":\"Unknown54 Add\"},{\"t\":3,\"n\":\"Tint Color\"},{\"t\":3,\"n\":\"Blur Radius\"},{\"t\":3,\"n\":\"Double Vision Strength\"},{\"t\":3,\"n\":\"Radial Blur Strength\"},{\"t\":3,\"n\":\"Radial Blur Ramp Up\"},{\"t\":3,\"n\":\"Radial Blur Start\"},{\"t\":3,\"n\":\"Radial Blur Flags\"},{\"t\":5,\"n\":\"Radial Blur Center X\"},{\"t\":5,\"n\":\"Radial Blur Center Y\"},{\"t\":3,\"n\":\"DoF Strength\"},{\"t\":3,\"n\":\"DoF Distance\"},{\"t\":3,\"n\":\"DoF Range\"},{\"t\":3,\"n\":\"DoF Flags\"},{\"t\":3,\"n\":\"Radial Blur Ramp Down\"},{\"t\":3,\"n\":\"Radial Blur Down Start\"},{\"t\":3,\"n\":\"Fade Color\"},{\"t\":3,\"n\":\"Motion Blur Strength\"}]},{\"t\":7,\"p\":1,\"n\":\"BNAM - Blur Radius\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Data\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Time\"},{\"t\":5,\"p\":1,\"n\":\"Value\"}]}]},{\"t\":7,\"p\":1,\"n\":\"VNAM - Double Vision Strength\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Data\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Time\"},{\"t\":5,\"p\":1,\"n\":\"Value\"}]}]},{\"t\":7,\"p\":1,\"n\":\"TNAM - Tint Color\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Data\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Time\"},{\"t\":5,\"p\":1,\"n\":\"Red\"},{\"t\":5,\"p\":1,\"n\":\"Green\"},{\"t\":5,\"p\":1,\"n\":\"Blue\"},{\"t\":5,\"p\":1,\"n\":\"Alpha\"}]}]},{\"t\":7,\"p\":1,\"n\":\"NAM3 - Fade Color\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Data\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Time\"},{\"t\":5,\"p\":1,\"n\":\"Red\"},{\"t\":5,\"p\":1,\"n\":\"Green\"},{\"t\":5,\"p\":1,\"n\":\"Blue\"},{\"t\":5,\"p\":1,\"n\":\"Alpha\"}]}]},{\"t\":7,\"p\":1,\"n\":\"RNAM - Radial Blur Strength\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Data\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Time\"},{\"t\":5,\"p\":1,\"n\":\"Value\"}]}]},{\"t\":7,\"p\":1,\"n\":\"SNAM - Radial Blur Ramp Up\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Data\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Time\"},{\"t\":5,\"p\":1,\"n\":\"Value\"}]}]},{\"t\":7,\"p\":1,\"n\":\"UNAM - Radial Blur Start\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Data\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Time\"},{\"t\":5,\"p\":1,\"n\":\"Value\"}]}]},{\"t\":7,\"p\":1,\"n\":\"NAM1 - Radial Blur Ramp Down\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Data\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Time\"},{\"t\":5,\"p\":1,\"n\":\"Value\"}]}]},{\"t\":7,\"p\":1,\"n\":\"NAM2 - Radial Blur Down Start\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Data\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Time\"},{\"t\":5,\"p\":1,\"n\":\"Value\"}]}]},{\"t\":7,\"p\":1,\"n\":\"WNAM - DoF Strength\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Data\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Time\"},{\"t\":5,\"p\":1,\"n\":\"Value\"}]}]},{\"t\":7,\"p\":1,\"n\":\"XNAM - DoF Distance\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Data\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Time\"},{\"t\":5,\"p\":1,\"n\":\"Value\"}]}]},{\"t\":7,\"p\":1,\"n\":\"YNAM - DoF Range\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Data\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Time\"},{\"t\":5,\"p\":1,\"n\":\"Value\"}]}]},{\"t\":7,\"p\":1,\"n\":\"NAM4 - Motion Blur Strength\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Data\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Time\"},{\"t\":5,\"p\":1,\"n\":\"Value\"}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"HDR\",\"c\":[{\"t\":7,\"p\":1,\"n\":\"aIAD - Eye Adapt Speed Mult\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Data\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Time\"},{\"t\":5,\"p\":1,\"n\":\"Value\"}]}]},{\"t\":7,\"p\":1,\"n\":\"@IAD - Eye Adapt Speed Add\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Data\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Time\"},{\"t\":5,\"p\":1,\"n\":\"Value\"}]}]},{\"t\":7,\"p\":1,\"n\":\"bIAD - Bloom Blur Radius Mult\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Data\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Time\"},{\"t\":5,\"p\":1,\"n\":\"Value\"}]}]},{\"t\":7,\"p\":1,\"n\":\"AIAD - Bloom Blur Radius Add\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Data\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Time\"},{\"t\":5,\"p\":1,\"n\":\"Value\"}]}]},{\"t\":7,\"p\":1,\"n\":\"cIAD - Bloom Threshold Mult\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Data\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Time\"},{\"t\":5,\"p\":1,\"n\":\"Value\"}]}]},{\"t\":7,\"p\":1,\"n\":\"BIAD - Bloom Threshold Add\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Data\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Time\"},{\"t\":5,\"p\":1,\"n\":\"Value\"}]}]},{\"t\":7,\"p\":1,\"n\":\"dIAD - Bloom Scale Mult\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Data\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Time\"},{\"t\":5,\"p\":1,\"n\":\"Value\"}]}]},{\"t\":7,\"p\":1,\"n\":\"CIAD - Bloom Scale Add\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Data\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Time\"},{\"t\":5,\"p\":1,\"n\":\"Value\"}]}]},{\"t\":7,\"p\":1,\"n\":\"eIAD - Target Lum Min Mult\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Data\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Time\"},{\"t\":5,\"p\":1,\"n\":\"Value\"}]}]},{\"t\":7,\"p\":1,\"n\":\"DIAD - Target Lum Min Add\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Data\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Time\"},{\"t\":5,\"p\":1,\"n\":\"Value\"}]}]},{\"t\":7,\"p\":1,\"n\":\"fIAD - Target Lum Max Mult\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Data\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Time\"},{\"t\":5,\"p\":1,\"n\":\"Value\"}]}]},{\"t\":7,\"p\":1,\"n\":\"EIAD - Target Lum Max Add\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Data\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Time\"},{\"t\":5,\"p\":1,\"n\":\"Value\"}]}]},{\"t\":7,\"p\":1,\"n\":\"gIAD - Sunlight Scale Mult\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Data\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Time\"},{\"t\":5,\"p\":1,\"n\":\"Value\"}]}]},{\"t\":7,\"p\":1,\"n\":\"FIAD - Sunlight Scale Add\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Data\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Time\"},{\"t\":5,\"p\":1,\"n\":\"Value\"}]}]},{\"t\":7,\"p\":1,\"n\":\"hIAD - Sky Scale Mult\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Data\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Time\"},{\"t\":5,\"p\":1,\"n\":\"Value\"}]}]},{\"t\":7,\"p\":1,\"n\":\"GIAD - Sky Scale Add\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Data\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Time\"},{\"t\":5,\"p\":1,\"n\":\"Value\"}]}]}]},{\"t\":11,\"n\":\"iIAD - Unknown\"},{\"t\":11,\"n\":\"HIAD - Unknown\"},{\"t\":11,\"n\":\"jIAD - Unknown\"},{\"t\":11,\"n\":\"IIAD - Unknown\"},{\"t\":11,\"n\":\"kIAD - Unknown\"},{\"t\":11,\"n\":\"JIAD - Unknown\"},{\"t\":11,\"n\":\"lIAD - Unknown\"},{\"t\":11,\"n\":\"KIAD - Unknown\"},{\"t\":11,\"n\":\"mIAD - Unknown\"},{\"t\":11,\"n\":\"LIAD - Unknown\"},{\"t\":11,\"n\":\"nIAD - Unknown\"},{\"t\":11,\"n\":\"MIAD - Unknown\"},{\"t\":11,\"n\":\"oIAD - Unknown\"},{\"t\":11,\"n\":\"NIAD - Unknown\"},{\"t\":11,\"n\":\"pIAD - Unknown\"},{\"t\":11,\"n\":\"OIAD - Unknown\"},{\"t\":11,\"n\":\"qIAD - Unknown\"},{\"t\":11,\"n\":\"PIAD - Unknown\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Cinematic\",\"c\":[{\"t\":7,\"p\":1,\"n\":\"rIAD - Saturation Mult\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Data\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Time\"},{\"t\":5,\"p\":1,\"n\":\"Value\"}]}]},{\"t\":7,\"p\":1,\"n\":\"QIAD - Saturation Add\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Data\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Time\"},{\"t\":5,\"p\":1,\"n\":\"Value\"}]}]},{\"t\":7,\"p\":1,\"n\":\"sIAD - Brightness Mult\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Data\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Time\"},{\"t\":5,\"p\":1,\"n\":\"Value\"}]}]},{\"t\":7,\"p\":1,\"n\":\"RIAD - Brightness Add\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Data\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Time\"},{\"t\":5,\"p\":1,\"n\":\"Value\"}]}]},{\"t\":7,\"p\":1,\"n\":\"tIAD - Contrast Mult\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Data\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Time\"},{\"t\":5,\"p\":1,\"n\":\"Value\"}]}]},{\"t\":7,\"p\":1,\"n\":\"SIAD - Contrast Add\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Data\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Time\"},{\"t\":5,\"p\":1,\"n\":\"Value\"}]}]}]},{\"t\":11,\"n\":\"uIAD - Unknown\"},{\"t\":11,\"n\":\"TIAD - Unknown\"}]},{\"t\":1,\"p\":1,\"n\":\"IMGS - Image Space\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DNAM - \",\"c\":[{\"t\":6,\"p\":1,\"n\":\"HDR\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Eye Adapt Speed\"},{\"t\":5,\"p\":1,\"n\":\"Blur Radius\"},{\"t\":5,\"p\":1,\"n\":\"Blur Passes\"},{\"t\":5,\"p\":1,\"n\":\"Emissive Mult\"},{\"t\":5,\"p\":1,\"n\":\"Target LUM\"},{\"t\":5,\"p\":1,\"n\":\"Upper LUM Clamp\"},{\"t\":5,\"p\":1,\"n\":\"Bright Scale\"},{\"t\":5,\"p\":1,\"n\":\"Bright Clamp\"},{\"t\":5,\"p\":1,\"n\":\"LUM Ramp No Tex\"},{\"t\":5,\"p\":1,\"n\":\"LUM Ramp Min\"},{\"t\":5,\"p\":1,\"n\":\"LUM Ramp Max\"},{\"t\":5,\"p\":1,\"n\":\"Sunlight Dimmer\"},{\"t\":5,\"p\":1,\"n\":\"Grass Dimmer\"},{\"t\":5,\"p\":1,\"n\":\"Tree Dimmer\"},{\"t\":5,\"p\":1,\"n\":\"Skin Dimmer\"}]},{\"t\":6,\"p\":1,\"n\":\"Bloom\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Blur Radius\"},{\"t\":5,\"p\":1,\"n\":\"Alpha Mult Interior\"},{\"t\":5,\"p\":1,\"n\":\"Alpha Mult Exterior\"}]},{\"t\":6,\"p\":1,\"n\":\"Get Hit\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Blur Radius\"},{\"t\":5,\"p\":1,\"n\":\"Blur Damping Constant\"},{\"t\":5,\"p\":1,\"n\":\"Damping Constant\"}]},{\"t\":6,\"p\":1,\"n\":\"Night Eye\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Tint Color\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Red\"},{\"t\":5,\"p\":1,\"n\":\"Green\"},{\"t\":5,\"p\":1,\"n\":\"Blue\"}]},{\"t\":5,\"p\":1,\"n\":\"Brightness\"}]},{\"t\":6,\"p\":1,\"n\":\"Cinematic\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Saturation\"},{\"t\":6,\"p\":1,\"n\":\"Contrast\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Avg Lum Value\"},{\"t\":5,\"p\":1,\"n\":\"Value\"}]},{\"t\":5,\"p\":1,\"n\":\"Cinematic - Brightness - Value\"},{\"t\":6,\"p\":1,\"n\":\"Tint\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Color\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Red\"},{\"t\":5,\"p\":1,\"n\":\"Green\"},{\"t\":5,\"p\":1,\"n\":\"Blue\"}]},{\"t\":5,\"p\":1,\"n\":\"Value\"}]}]},{\"t\":11,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"}]}]},{\"t\":1,\"p\":1,\"n\":\"INFO - Dialog response\",\"d\":1,\"c\":[{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DATA - \",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Next Speaker\"},{\"t\":3,\"p\":1,\"n\":\"Flags 1\"},{\"t\":3,\"p\":1,\"n\":\"Flags 2\"}]},{\"t\":3,\"p\":1,\"n\":\"QSTI - Quest\"},{\"t\":3,\"p\":1,\"n\":\"TPIC - Topic\"},{\"t\":3,\"p\":1,\"n\":\"PNAM - Previous INFO\"},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Add Topics\",\"d\":1,\"c\":[{\"t\":3,\"p\":1,\"n\":\"NAME - Topic\"}]},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Responses\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Response\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"TRDT - Response Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Emotion Type\"},{\"t\":3,\"p\":1,\"n\":\"Emotion Value\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Response number\"},{\"t\":3,\"p\":1,\"n\":\"Sound\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"}]},{\"t\":2,\"p\":1,\"n\":\"NAM1 - Response Text\"},{\"t\":2,\"p\":1,\"n\":\"NAM2 - Script Notes\"},{\"t\":2,\"p\":1,\"n\":\"NAM3 - Edits\"},{\"t\":3,\"p\":1,\"n\":\"SNAM - Speaker Animation\"},{\"t\":3,\"p\":1,\"n\":\"LNAM - Listener Animation\"}]}]},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Conditions\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"CTDA - Condition\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":5,\"p\":1,\"n\":\"Comparison Value - Float\"},{\"t\":3,\"p\":1,\"n\":\"Comparison Value - Global\"},{\"t\":3,\"p\":1,\"n\":\"Function\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":11,\"p\":1,\"n\":\"None\"},{\"t\":3,\"p\":1,\"n\":\"Integer\"},{\"t\":3,\"p\":1,\"n\":\"Variable Name (INVALID)\"},{\"t\":3,\"p\":1,\"n\":\"Sex\"},{\"t\":3,\"p\":1,\"n\":\"Actor Value\"},{\"t\":3,\"p\":1,\"n\":\"Crime Type\"},{\"t\":3,\"p\":1,\"n\":\"Axis\"},{\"t\":3,\"p\":1,\"n\":\"Quest Stage (INVALID)\"},{\"t\":3,\"p\":1,\"n\":\"Misc Stat\"},{\"t\":3,\"p\":1,\"n\":\"Alignment\"},{\"t\":3,\"p\":1,\"n\":\"Equip Type\"},{\"t\":3,\"p\":1,\"n\":\"Form Type\"},{\"t\":3,\"p\":1,\"n\":\"Critical Stage\"},{\"t\":3,\"p\":1,\"n\":\"Object Reference\"},{\"t\":3,\"p\":1,\"n\":\"Inventory Object\"},{\"t\":3,\"p\":1,\"n\":\"Actor\"},{\"t\":3,\"p\":1,\"n\":\"Voice Type\"},{\"t\":3,\"p\":1,\"n\":\"Idle\"},{\"t\":3,\"p\":1,\"n\":\"Form List\"},{\"t\":3,\"p\":1,\"n\":\"Note\"},{\"t\":3,\"p\":1,\"n\":\"Quest\"},{\"t\":3,\"p\":1,\"n\":\"Faction\"},{\"t\":3,\"p\":1,\"n\":\"Weapon\"},{\"t\":3,\"p\":1,\"n\":\"Cell\"},{\"t\":3,\"p\":1,\"n\":\"Class\"},{\"t\":3,\"p\":1,\"n\":\"Race\"},{\"t\":3,\"p\":1,\"n\":\"Actor Base\"},{\"t\":3,\"p\":1,\"n\":\"Global\"},{\"t\":3,\"p\":1,\"n\":\"Weather\"},{\"t\":3,\"p\":1,\"n\":\"Package\"},{\"t\":3,\"p\":1,\"n\":\"Encounter Zone\"},{\"t\":3,\"p\":1,\"n\":\"Perk\"},{\"t\":3,\"p\":1,\"n\":\"Owner\"},{\"t\":3,\"p\":1,\"n\":\"Furniture\"},{\"t\":3,\"p\":1,\"n\":\"Effect Item\"},{\"t\":3,\"p\":1,\"n\":\"Base Effect\"},{\"t\":3,\"p\":1,\"n\":\"Worldspace\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Function\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Param (INVALID)\"},{\"t\":3,\"p\":1,\"n\":\"Creature Type\"},{\"t\":3,\"p\":1,\"n\":\"Menu Mode\"},{\"t\":3,\"p\":1,\"n\":\"Player Action\"},{\"t\":3,\"p\":1,\"n\":\"Body Location\"},{\"t\":3,\"p\":1,\"n\":\"Referenceable Object\"},{\"t\":3,\"p\":1,\"n\":\"Variable Name\"},{\"t\":3,\"p\":1,\"n\":\"Quest Stage\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Function (INVALID)\"},{\"t\":3,\"p\":1,\"n\":\"Weapon List\"},{\"t\":3,\"p\":1,\"n\":\"Target\"},{\"t\":3,\"p\":1,\"n\":\"Target List\"},{\"t\":3,\"p\":1,\"n\":\"Target Part\"},{\"t\":3,\"p\":1,\"n\":\"VATS Action\"},{\"t\":3,\"p\":1,\"n\":\"Critical Effect\"},{\"t\":3,\"p\":1,\"n\":\"Critical Effect List\"},{\"t\":3,\"p\":1,\"n\":\"Weapon Type\"},{\"t\":3,\"p\":1,\"n\":\"Run On\"},{\"t\":3,\"p\":1,\"n\":\"Reference\"}]}]},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Choices\",\"d\":1,\"c\":[{\"t\":3,\"p\":1,\"n\":\"TCLT - Choice\"}]},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Link From\",\"d\":1,\"c\":[{\"t\":3,\"p\":1,\"n\":\"TCLF - Topic\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Script (Begin)\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Embedded Script\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"SCHR - Basic Script Data\",\"c\":[{\"t\":11,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"RefCount\"},{\"t\":3,\"p\":1,\"n\":\"CompiledSize\"},{\"t\":3,\"p\":1,\"n\":\"VariableCount\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"}]},{\"t\":11,\"p\":1,\"n\":\"SCDA - Compiled Embedded Script\"},{\"t\":2,\"p\":1,\"n\":\"SCTX - Embedded Script Source\"},{\"t\":10,\"p\":1,\"n\":\"Local Variables\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Local Variable\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"SLSD - Local Variable Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Index\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"}]},{\"t\":2,\"p\":1,\"n\":\"SCVR - Name\"}]}]},{\"t\":8,\"p\":1,\"n\":\"References\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"SCRO - Global Reference\"},{\"t\":3,\"p\":1,\"n\":\"SCRV - Local Variable\"}]}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Script (End)\",\"c\":[{\"p\":1,\"n\":\"NEXT - Marker\"},{\"t\":6,\"p\":1,\"n\":\"Embedded Script\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"SCHR - Basic Script Data\",\"c\":[{\"t\":11,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"RefCount\"},{\"t\":3,\"p\":1,\"n\":\"CompiledSize\"},{\"t\":3,\"p\":1,\"n\":\"VariableCount\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"}]},{\"t\":11,\"p\":1,\"n\":\"SCDA - Compiled Embedded Script\"},{\"t\":2,\"p\":1,\"n\":\"SCTX - Embedded Script Source\"},{\"t\":10,\"p\":1,\"n\":\"Local Variables\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Local Variable\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"SLSD - Local Variable Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Index\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"}]},{\"t\":2,\"p\":1,\"n\":\"SCVR - Name\"}]}]},{\"t\":8,\"p\":1,\"n\":\"References\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"SCRO - Global Reference\"},{\"t\":3,\"p\":1,\"n\":\"SCRV - Local Variable\"}]}]}]},{\"t\":3,\"n\":\"SNDD - Unused\"},{\"t\":2,\"p\":1,\"n\":\"RNAM - Prompt\"},{\"t\":3,\"p\":1,\"n\":\"ANAM - Speaker\"},{\"t\":3,\"p\":1,\"n\":\"KNAM - ActorValue\\/Perk\"},{\"t\":3,\"p\":1,\"n\":\"DNAM - Speech Challenge\"}]},{\"t\":1,\"p\":1,\"n\":\"INGR - Ingredient\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"X1\"},{\"t\":3,\"p\":1,\"n\":\"Y1\"},{\"t\":3,\"p\":1,\"n\":\"Z1\"},{\"t\":3,\"p\":1,\"n\":\"X2\"},{\"t\":3,\"p\":1,\"n\":\"Y2\"},{\"t\":3,\"p\":1,\"n\":\"Z2\"}]},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"},{\"t\":11,\"n\":\"MODB - Unknown\"},{\"t\":11,\"p\":1,\"n\":\"MODT - Texture Files Hashes\"},{\"t\":7,\"p\":1,\"n\":\"MODS - Alternate Textures\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"3D Name\"},{\"t\":3,\"p\":1,\"n\":\"New Texture\"},{\"t\":3,\"p\":1,\"n\":\"3D Index\"}]}]},{\"t\":3,\"p\":1,\"n\":\"MODD - FaceGen Model Flags\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Icon\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"ICON - Large Icon filename\"},{\"t\":2,\"p\":1,\"n\":\"MICO - Small Icon filename\"}]},{\"t\":3,\"p\":1,\"n\":\"SCRI - Script\"},{\"t\":3,\"p\":1,\"n\":\"ETYP - Equiptment Type\"},{\"t\":5,\"p\":1,\"n\":\"DATA - Weight\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"ENIT - Effect Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Value\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Effects\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Effect\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"EFID - Base Effect\"},{\"t\":6,\"p\":1,\"n\":\"EFIT - \",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Magnitude\"},{\"t\":3,\"p\":1,\"n\":\"Area\"},{\"t\":3,\"p\":1,\"n\":\"Duration\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Actor Value\"}]},{\"t\":8,\"p\":1,\"n\":\"Conditions\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"CTDA - Condition\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":5,\"p\":1,\"n\":\"Comparison Value - Float\"},{\"t\":3,\"p\":1,\"n\":\"Comparison Value - Global\"},{\"t\":3,\"p\":1,\"n\":\"Function\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":11,\"p\":1,\"n\":\"None\"},{\"t\":3,\"p\":1,\"n\":\"Integer\"},{\"t\":3,\"p\":1,\"n\":\"Variable Name (INVALID)\"},{\"t\":3,\"p\":1,\"n\":\"Sex\"},{\"t\":3,\"p\":1,\"n\":\"Actor Value\"},{\"t\":3,\"p\":1,\"n\":\"Crime Type\"},{\"t\":3,\"p\":1,\"n\":\"Axis\"},{\"t\":3,\"p\":1,\"n\":\"Quest Stage (INVALID)\"},{\"t\":3,\"p\":1,\"n\":\"Misc Stat\"},{\"t\":3,\"p\":1,\"n\":\"Alignment\"},{\"t\":3,\"p\":1,\"n\":\"Equip Type\"},{\"t\":3,\"p\":1,\"n\":\"Form Type\"},{\"t\":3,\"p\":1,\"n\":\"Critical Stage\"},{\"t\":3,\"p\":1,\"n\":\"Object Reference\"},{\"t\":3,\"p\":1,\"n\":\"Inventory Object\"},{\"t\":3,\"p\":1,\"n\":\"Actor\"},{\"t\":3,\"p\":1,\"n\":\"Voice Type\"},{\"t\":3,\"p\":1,\"n\":\"Idle\"},{\"t\":3,\"p\":1,\"n\":\"Form List\"},{\"t\":3,\"p\":1,\"n\":\"Note\"},{\"t\":3,\"p\":1,\"n\":\"Quest\"},{\"t\":3,\"p\":1,\"n\":\"Faction\"},{\"t\":3,\"p\":1,\"n\":\"Weapon\"},{\"t\":3,\"p\":1,\"n\":\"Cell\"},{\"t\":3,\"p\":1,\"n\":\"Class\"},{\"t\":3,\"p\":1,\"n\":\"Race\"},{\"t\":3,\"p\":1,\"n\":\"Actor Base\"},{\"t\":3,\"p\":1,\"n\":\"Global\"},{\"t\":3,\"p\":1,\"n\":\"Weather\"},{\"t\":3,\"p\":1,\"n\":\"Package\"},{\"t\":3,\"p\":1,\"n\":\"Encounter Zone\"},{\"t\":3,\"p\":1,\"n\":\"Perk\"},{\"t\":3,\"p\":1,\"n\":\"Owner\"},{\"t\":3,\"p\":1,\"n\":\"Furniture\"},{\"t\":3,\"p\":1,\"n\":\"Effect Item\"},{\"t\":3,\"p\":1,\"n\":\"Base Effect\"},{\"t\":3,\"p\":1,\"n\":\"Worldspace\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Function\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Param (INVALID)\"},{\"t\":3,\"p\":1,\"n\":\"Creature Type\"},{\"t\":3,\"p\":1,\"n\":\"Menu Mode\"},{\"t\":3,\"p\":1,\"n\":\"Player Action\"},{\"t\":3,\"p\":1,\"n\":\"Body Location\"},{\"t\":3,\"p\":1,\"n\":\"Referenceable Object\"},{\"t\":3,\"p\":1,\"n\":\"Variable Name\"},{\"t\":3,\"p\":1,\"n\":\"Quest Stage\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Function (INVALID)\"},{\"t\":3,\"p\":1,\"n\":\"Weapon List\"},{\"t\":3,\"p\":1,\"n\":\"Target\"},{\"t\":3,\"p\":1,\"n\":\"Target List\"},{\"t\":3,\"p\":1,\"n\":\"Target Part\"},{\"t\":3,\"p\":1,\"n\":\"VATS Action\"},{\"t\":3,\"p\":1,\"n\":\"Critical Effect\"},{\"t\":3,\"p\":1,\"n\":\"Critical Effect List\"},{\"t\":3,\"p\":1,\"n\":\"Weapon Type\"},{\"t\":3,\"p\":1,\"n\":\"Run On\"},{\"t\":3,\"p\":1,\"n\":\"Reference\"}]}]}]}]}]},{\"t\":1,\"p\":1,\"n\":\"IPCT - Impact\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"},{\"t\":11,\"n\":\"MODB - Unknown\"},{\"t\":11,\"p\":1,\"n\":\"MODT - Texture Files Hashes\"},{\"t\":7,\"p\":1,\"n\":\"MODS - Alternate Textures\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"3D Name\"},{\"t\":3,\"p\":1,\"n\":\"New Texture\"},{\"t\":3,\"p\":1,\"n\":\"3D Index\"}]}]},{\"t\":3,\"p\":1,\"n\":\"MODD - FaceGen Model Flags\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DATA - \",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Effect - Duration\"},{\"t\":3,\"p\":1,\"n\":\"Effect - Orientation\"},{\"t\":5,\"p\":1,\"n\":\"Angle Threshold\"},{\"t\":5,\"p\":1,\"n\":\"Placement Radius\"},{\"t\":3,\"p\":1,\"n\":\"Sound Level\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DODT - Decal Data\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Min Width\"},{\"t\":5,\"p\":1,\"n\":\"Max Width\"},{\"t\":5,\"p\":1,\"n\":\"Min Height\"},{\"t\":5,\"p\":1,\"n\":\"Max Height\"},{\"t\":5,\"p\":1,\"n\":\"Depth\"},{\"t\":5,\"p\":1,\"n\":\"Shininess\"},{\"t\":6,\"p\":1,\"n\":\"Parallax\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Scale\"},{\"t\":3,\"p\":1,\"n\":\"Passes\"}]},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":6,\"p\":1,\"n\":\"Color\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]}]},{\"t\":3,\"p\":1,\"n\":\"DNAM - Texture Set\"},{\"t\":3,\"p\":1,\"n\":\"SNAM - Sound 1\"},{\"t\":3,\"p\":1,\"n\":\"NAM1 - Sound 2\"}]},{\"t\":1,\"p\":1,\"n\":\"IPDS - Impact DataSet\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DATA - Impacts\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Stone\"},{\"t\":3,\"p\":1,\"n\":\"Dirt\"},{\"t\":3,\"p\":1,\"n\":\"Grass\"},{\"t\":3,\"p\":1,\"n\":\"Glass\"},{\"t\":3,\"p\":1,\"n\":\"Metal\"},{\"t\":3,\"p\":1,\"n\":\"Wood\"},{\"t\":3,\"p\":1,\"n\":\"Organic\"},{\"t\":3,\"p\":1,\"n\":\"Cloth\"},{\"t\":3,\"p\":1,\"n\":\"Water\"},{\"t\":3,\"p\":1,\"n\":\"Hollow Metal\"},{\"t\":3,\"p\":1,\"n\":\"Organic Bug\"},{\"t\":3,\"p\":1,\"n\":\"Organic Glow\"}]}]},{\"t\":1,\"p\":1,\"n\":\"KEYM - Key\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"X1\"},{\"t\":3,\"p\":1,\"n\":\"Y1\"},{\"t\":3,\"p\":1,\"n\":\"Z1\"},{\"t\":3,\"p\":1,\"n\":\"X2\"},{\"t\":3,\"p\":1,\"n\":\"Y2\"},{\"t\":3,\"p\":1,\"n\":\"Z2\"}]},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"},{\"t\":11,\"n\":\"MODB - Unknown\"},{\"t\":11,\"p\":1,\"n\":\"MODT - Texture Files Hashes\"},{\"t\":7,\"p\":1,\"n\":\"MODS - Alternate Textures\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"3D Name\"},{\"t\":3,\"p\":1,\"n\":\"New Texture\"},{\"t\":3,\"p\":1,\"n\":\"3D Index\"}]}]},{\"t\":3,\"p\":1,\"n\":\"MODD - FaceGen Model Flags\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Icon\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"ICON - Large Icon filename\"},{\"t\":2,\"p\":1,\"n\":\"MICO - Small Icon filename\"}]},{\"t\":3,\"p\":1,\"n\":\"SCRI - Script\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Destructable\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"DEST - Header\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Health\"},{\"t\":3,\"p\":1,\"n\":\"Count\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":8,\"p\":1,\"n\":\"Stages\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Stage\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"DSTD - Destruction Stage Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Health %\"},{\"t\":3,\"p\":1,\"n\":\"Index\"},{\"t\":3,\"p\":1,\"n\":\"Damage Stage\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":3,\"p\":1,\"n\":\"Self Damage per Second\"},{\"t\":3,\"p\":1,\"n\":\"Explosion\"},{\"t\":3,\"p\":1,\"n\":\"Debris\"},{\"t\":3,\"p\":1,\"n\":\"Debris Count\"}]},{\"t\":6,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"DMDL - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"DMDT - Texture Files Hashes\"}]},{\"p\":1,\"n\":\"DSTF - End Marker\"}]}]}]},{\"t\":3,\"p\":1,\"n\":\"YNAM - Sound - Pick Up\"},{\"t\":3,\"p\":1,\"n\":\"ZNAM - Sound - Drop\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DATA - \",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Value\"},{\"t\":5,\"p\":1,\"n\":\"Weight\"}]}]},{\"t\":1,\"p\":1,\"n\":\"LAND - Landscape\",\"d\":1,\"c\":[{\"t\":11,\"n\":\"DATA - Unknown\"},{\"t\":11,\"n\":\"VNML - Vertex Normals\"},{\"t\":11,\"n\":\"VHGT - Vertext Height Map\"},{\"t\":11,\"n\":\"VCLR - Vertex Colours\"},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Layers\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Base Layer\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"BTXT - Base Layer Header\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Texture\"},{\"t\":3,\"p\":1,\"n\":\"Quadrant\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Layer\"}]}]},{\"t\":6,\"p\":1,\"n\":\"Alpha Layer\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"ATXT - Alpha Layer Header\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Texture\"},{\"t\":3,\"p\":1,\"n\":\"Quadrant\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Layer\"}]},{\"t\":11,\"p\":1,\"n\":\"VTXT - Alpha Layer Data\"}]}]},{\"t\":7,\"p\":1,\"n\":\"VTEX - Textures\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Texture\"}]}]},{\"t\":1,\"p\":1,\"n\":\"LGTM - Lighting Template\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DATA - Lighting\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Ambient Color\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Directional Color\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Fog Color\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":5,\"p\":1,\"n\":\"Fog Near\"},{\"t\":5,\"p\":1,\"n\":\"Fog Far\"},{\"t\":3,\"p\":1,\"n\":\"Directional Rotation XY\"},{\"t\":3,\"p\":1,\"n\":\"Directional Rotation Z\"},{\"t\":5,\"p\":1,\"n\":\"Directional Fade\"},{\"t\":5,\"p\":1,\"n\":\"Fog Clip Dist\"},{\"t\":5,\"p\":1,\"n\":\"Fog Power\"}]}]},{\"t\":1,\"p\":1,\"n\":\"LIGH - Light\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"X1\"},{\"t\":3,\"p\":1,\"n\":\"Y1\"},{\"t\":3,\"p\":1,\"n\":\"Z1\"},{\"t\":3,\"p\":1,\"n\":\"X2\"},{\"t\":3,\"p\":1,\"n\":\"Y2\"},{\"t\":3,\"p\":1,\"n\":\"Z2\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"},{\"t\":11,\"n\":\"MODB - Unknown\"},{\"t\":11,\"p\":1,\"n\":\"MODT - Texture Files Hashes\"},{\"t\":7,\"p\":1,\"n\":\"MODS - Alternate Textures\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"3D Name\"},{\"t\":3,\"p\":1,\"n\":\"New Texture\"},{\"t\":3,\"p\":1,\"n\":\"3D Index\"}]}]},{\"t\":3,\"p\":1,\"n\":\"MODD - FaceGen Model Flags\"}]},{\"t\":3,\"p\":1,\"n\":\"SCRI - Script\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Destructable\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"DEST - Header\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Health\"},{\"t\":3,\"p\":1,\"n\":\"Count\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":8,\"p\":1,\"n\":\"Stages\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Stage\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"DSTD - Destruction Stage Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Health %\"},{\"t\":3,\"p\":1,\"n\":\"Index\"},{\"t\":3,\"p\":1,\"n\":\"Damage Stage\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":3,\"p\":1,\"n\":\"Self Damage per Second\"},{\"t\":3,\"p\":1,\"n\":\"Explosion\"},{\"t\":3,\"p\":1,\"n\":\"Debris\"},{\"t\":3,\"p\":1,\"n\":\"Debris Count\"}]},{\"t\":6,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"DMDL - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"DMDT - Texture Files Hashes\"}]},{\"p\":1,\"n\":\"DSTF - End Marker\"}]}]}]},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Icon\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"ICON - Large Icon filename\"},{\"t\":2,\"p\":1,\"n\":\"MICO - Small Icon filename\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DATA - \",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Time\"},{\"t\":3,\"p\":1,\"n\":\"Radius\"},{\"t\":6,\"p\":1,\"n\":\"Color\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":3,\"n\":\"Unused\"}]},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":5,\"p\":1,\"n\":\"Falloff Exponent\"},{\"t\":5,\"p\":1,\"n\":\"FOV\"},{\"t\":3,\"p\":1,\"n\":\"Value\"},{\"t\":5,\"p\":1,\"n\":\"Weight\"}]},{\"t\":5,\"p\":1,\"n\":\"FNAM - Fade value\"},{\"t\":3,\"p\":1,\"n\":\"SNAM - Sound\"}]},{\"t\":1,\"p\":1,\"n\":\"LSCR - Load Screen\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Icon\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"ICON - Large Icon filename\"},{\"t\":2,\"p\":1,\"n\":\"MICO - Small Icon filename\"}]},{\"t\":2,\"p\":1,\"n\":\"DESC - Description\"},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Locations\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"LNAM - Location\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Cell\"},{\"t\":11,\"n\":\"Unused\"}]}]}]},{\"t\":1,\"p\":1,\"n\":\"LTEX - Landscape Texture\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Icon\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"ICON - Large Icon filename\"},{\"t\":2,\"p\":1,\"n\":\"MICO - Small Icon filename\"}]},{\"t\":3,\"p\":1,\"n\":\"TNAM - Texture\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"HNAM - Havok Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Material Type\"},{\"t\":3,\"p\":1,\"n\":\"Friction\"},{\"t\":3,\"p\":1,\"n\":\"Restitution\"}]},{\"t\":3,\"p\":1,\"n\":\"SNAM - Texture Specular Exponent\"},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Grasses\",\"d\":1,\"c\":[{\"t\":3,\"p\":1,\"n\":\"GNAM - Grass\"}]}]},{\"t\":1,\"p\":1,\"n\":\"LVLC - Leveled Creature\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"X1\"},{\"t\":3,\"p\":1,\"n\":\"Y1\"},{\"t\":3,\"p\":1,\"n\":\"Z1\"},{\"t\":3,\"p\":1,\"n\":\"X2\"},{\"t\":3,\"p\":1,\"n\":\"Y2\"},{\"t\":3,\"p\":1,\"n\":\"Z2\"}]},{\"t\":3,\"p\":1,\"n\":\"LVLD - Chance none\"},{\"t\":3,\"p\":1,\"n\":\"LVLF - Flags\"},{\"t\":10,\"p\":1,\"n\":\"Leveled List Entries\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Leveled List Entry\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"LVLO - Base Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Level\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":3,\"p\":1,\"n\":\"Count\"}]},{\"t\":6,\"p\":1,\"n\":\"COED - Extra Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Owner\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Global Variable\"},{\"t\":3,\"p\":1,\"n\":\"Required Rank\"},{\"t\":5,\"p\":1,\"n\":\"Item Condition\"}]}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"},{\"t\":11,\"n\":\"MODB - Unknown\"},{\"t\":11,\"p\":1,\"n\":\"MODT - Texture Files Hashes\"},{\"t\":7,\"p\":1,\"n\":\"MODS - Alternate Textures\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"3D Name\"},{\"t\":3,\"p\":1,\"n\":\"New Texture\"},{\"t\":3,\"p\":1,\"n\":\"3D Index\"}]}]},{\"t\":3,\"p\":1,\"n\":\"MODD - FaceGen Model Flags\"}]}]},{\"t\":1,\"p\":1,\"n\":\"LVLI - Leveled Item\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"X1\"},{\"t\":3,\"p\":1,\"n\":\"Y1\"},{\"t\":3,\"p\":1,\"n\":\"Z1\"},{\"t\":3,\"p\":1,\"n\":\"X2\"},{\"t\":3,\"p\":1,\"n\":\"Y2\"},{\"t\":3,\"p\":1,\"n\":\"Z2\"}]},{\"t\":3,\"p\":1,\"n\":\"LVLD - Chance none\"},{\"t\":3,\"p\":1,\"n\":\"LVLF - Flags\"},{\"t\":3,\"p\":1,\"n\":\"LVLG - Global\"},{\"t\":10,\"p\":1,\"n\":\"Leveled List Entries\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Leveled List Entry\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"LVLO - Base Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Level\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":3,\"p\":1,\"n\":\"Count\"}]},{\"t\":6,\"p\":1,\"n\":\"COED - Extra Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Owner\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Global Variable\"},{\"t\":3,\"p\":1,\"n\":\"Required Rank\"},{\"t\":5,\"p\":1,\"n\":\"Item Condition\"}]}]}]}]},{\"t\":1,\"p\":1,\"n\":\"LVLN - Leveled NPC\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"X1\"},{\"t\":3,\"p\":1,\"n\":\"Y1\"},{\"t\":3,\"p\":1,\"n\":\"Z1\"},{\"t\":3,\"p\":1,\"n\":\"X2\"},{\"t\":3,\"p\":1,\"n\":\"Y2\"},{\"t\":3,\"p\":1,\"n\":\"Z2\"}]},{\"t\":3,\"p\":1,\"n\":\"LVLD - Chance none\"},{\"t\":3,\"p\":1,\"n\":\"LVLF - Flags\"},{\"t\":10,\"p\":1,\"n\":\"Leveled List Entries\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Leveled List Entry\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"LVLO - Base Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Level\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":3,\"p\":1,\"n\":\"Count\"}]},{\"t\":6,\"p\":1,\"n\":\"COED - Extra Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Owner\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Global Variable\"},{\"t\":3,\"p\":1,\"n\":\"Required Rank\"},{\"t\":5,\"p\":1,\"n\":\"Item Condition\"}]}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"},{\"t\":11,\"n\":\"MODB - Unknown\"},{\"t\":11,\"p\":1,\"n\":\"MODT - Texture Files Hashes\"},{\"t\":7,\"p\":1,\"n\":\"MODS - Alternate Textures\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"3D Name\"},{\"t\":3,\"p\":1,\"n\":\"New Texture\"},{\"t\":3,\"p\":1,\"n\":\"3D Index\"}]}]},{\"t\":3,\"p\":1,\"n\":\"MODD - FaceGen Model Flags\"}]}]},{\"t\":1,\"p\":1,\"n\":\"MESG - Message\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"p\":1,\"n\":\"DESC - Description\"},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":3,\"p\":1,\"n\":\"INAM - Icon\"},{\"t\":11,\"n\":\"NAM0 - Unused\"},{\"t\":11,\"n\":\"NAM1 - Unused\"},{\"t\":11,\"n\":\"NAM2 - Unused\"},{\"t\":11,\"n\":\"NAM3 - Unused\"},{\"t\":11,\"n\":\"NAM4 - Unused\"},{\"t\":11,\"n\":\"NAM5 - Unused\"},{\"t\":11,\"n\":\"NAM6 - Unused\"},{\"t\":11,\"n\":\"NAM7 - Unused\"},{\"t\":11,\"n\":\"NAM8 - Unused\"},{\"t\":11,\"n\":\"NAM9 - Unused\"},{\"t\":3,\"p\":1,\"n\":\"DNAM - Flags\"},{\"t\":3,\"p\":1,\"n\":\"TNAM - Display Time\"},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Menu Buttons\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Menu Button\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"ITXT - Button Text\"},{\"t\":8,\"p\":1,\"n\":\"Conditions\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"CTDA - Condition\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":5,\"p\":1,\"n\":\"Comparison Value - Float\"},{\"t\":3,\"p\":1,\"n\":\"Comparison Value - Global\"},{\"t\":3,\"p\":1,\"n\":\"Function\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":11,\"p\":1,\"n\":\"None\"},{\"t\":3,\"p\":1,\"n\":\"Integer\"},{\"t\":3,\"p\":1,\"n\":\"Variable Name (INVALID)\"},{\"t\":3,\"p\":1,\"n\":\"Sex\"},{\"t\":3,\"p\":1,\"n\":\"Actor Value\"},{\"t\":3,\"p\":1,\"n\":\"Crime Type\"},{\"t\":3,\"p\":1,\"n\":\"Axis\"},{\"t\":3,\"p\":1,\"n\":\"Quest Stage (INVALID)\"},{\"t\":3,\"p\":1,\"n\":\"Misc Stat\"},{\"t\":3,\"p\":1,\"n\":\"Alignment\"},{\"t\":3,\"p\":1,\"n\":\"Equip Type\"},{\"t\":3,\"p\":1,\"n\":\"Form Type\"},{\"t\":3,\"p\":1,\"n\":\"Critical Stage\"},{\"t\":3,\"p\":1,\"n\":\"Object Reference\"},{\"t\":3,\"p\":1,\"n\":\"Inventory Object\"},{\"t\":3,\"p\":1,\"n\":\"Actor\"},{\"t\":3,\"p\":1,\"n\":\"Voice Type\"},{\"t\":3,\"p\":1,\"n\":\"Idle\"},{\"t\":3,\"p\":1,\"n\":\"Form List\"},{\"t\":3,\"p\":1,\"n\":\"Note\"},{\"t\":3,\"p\":1,\"n\":\"Quest\"},{\"t\":3,\"p\":1,\"n\":\"Faction\"},{\"t\":3,\"p\":1,\"n\":\"Weapon\"},{\"t\":3,\"p\":1,\"n\":\"Cell\"},{\"t\":3,\"p\":1,\"n\":\"Class\"},{\"t\":3,\"p\":1,\"n\":\"Race\"},{\"t\":3,\"p\":1,\"n\":\"Actor Base\"},{\"t\":3,\"p\":1,\"n\":\"Global\"},{\"t\":3,\"p\":1,\"n\":\"Weather\"},{\"t\":3,\"p\":1,\"n\":\"Package\"},{\"t\":3,\"p\":1,\"n\":\"Encounter Zone\"},{\"t\":3,\"p\":1,\"n\":\"Perk\"},{\"t\":3,\"p\":1,\"n\":\"Owner\"},{\"t\":3,\"p\":1,\"n\":\"Furniture\"},{\"t\":3,\"p\":1,\"n\":\"Effect Item\"},{\"t\":3,\"p\":1,\"n\":\"Base Effect\"},{\"t\":3,\"p\":1,\"n\":\"Worldspace\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Function\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Param (INVALID)\"},{\"t\":3,\"p\":1,\"n\":\"Creature Type\"},{\"t\":3,\"p\":1,\"n\":\"Menu Mode\"},{\"t\":3,\"p\":1,\"n\":\"Player Action\"},{\"t\":3,\"p\":1,\"n\":\"Body Location\"},{\"t\":3,\"p\":1,\"n\":\"Referenceable Object\"},{\"t\":3,\"p\":1,\"n\":\"Variable Name\"},{\"t\":3,\"p\":1,\"n\":\"Quest Stage\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Function (INVALID)\"},{\"t\":3,\"p\":1,\"n\":\"Weapon List\"},{\"t\":3,\"p\":1,\"n\":\"Target\"},{\"t\":3,\"p\":1,\"n\":\"Target List\"},{\"t\":3,\"p\":1,\"n\":\"Target Part\"},{\"t\":3,\"p\":1,\"n\":\"VATS Action\"},{\"t\":3,\"p\":1,\"n\":\"Critical Effect\"},{\"t\":3,\"p\":1,\"n\":\"Critical Effect List\"},{\"t\":3,\"p\":1,\"n\":\"Weapon Type\"},{\"t\":3,\"p\":1,\"n\":\"Run On\"},{\"t\":3,\"p\":1,\"n\":\"Reference\"}]}]}]}]}]},{\"t\":1,\"p\":1,\"n\":\"MGEF - Base Effect\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":2,\"p\":1,\"n\":\"DESC - Description\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Icon\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"ICON - Large Icon filename\"},{\"t\":2,\"p\":1,\"n\":\"MICO - Small Icon filename\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"},{\"t\":11,\"n\":\"MODB - Unknown\"},{\"t\":11,\"p\":1,\"n\":\"MODT - Texture Files Hashes\"},{\"t\":7,\"p\":1,\"n\":\"MODS - Alternate Textures\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"3D Name\"},{\"t\":3,\"p\":1,\"n\":\"New Texture\"},{\"t\":3,\"p\":1,\"n\":\"3D Index\"}]}]},{\"t\":3,\"p\":1,\"n\":\"MODD - FaceGen Model Flags\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DATA - Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":5,\"n\":\"Base cost (Unused)\"},{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Assoc. Item\"},{\"t\":3,\"p\":1,\"n\":\"Assoc. Script\"},{\"t\":3,\"p\":1,\"n\":\"Assoc. Creature\"},{\"t\":3,\"n\":\"Magic School (Unused)\"},{\"t\":3,\"p\":1,\"n\":\"Resistance Type\"},{\"t\":3,\"p\":1,\"n\":\"Counter effect count\"},{\"t\":3,\"p\":1,\"n\":\"Light\"},{\"t\":5,\"p\":1,\"n\":\"Projectile speed\"},{\"t\":3,\"p\":1,\"n\":\"Effect Shader\"},{\"t\":3,\"p\":1,\"n\":\"Object Display Shader\"},{\"t\":3,\"p\":1,\"n\":\"Effect sound\"},{\"t\":3,\"p\":1,\"n\":\"Bolt sound\"},{\"t\":3,\"p\":1,\"n\":\"Hit sound\"},{\"t\":3,\"p\":1,\"n\":\"Area sound\"},{\"t\":5,\"n\":\"Constant Effect enchantment factor  (Unused)\"},{\"t\":5,\"n\":\"Constant Effect barter factor (Unused)\"},{\"t\":3,\"p\":1,\"n\":\"Archtype\"},{\"t\":3,\"p\":1,\"n\":\"Actor Value\"}]},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Counter Effects\",\"d\":1,\"c\":[{\"t\":3,\"p\":1,\"n\":\"ESCE - Effect\"}]}]},{\"t\":1,\"p\":1,\"n\":\"MICN - Menu Icon\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Icon\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"ICON - Large Icon filename\"},{\"t\":2,\"p\":1,\"n\":\"MICO - Small Icon filename\"}]}]},{\"t\":1,\"p\":1,\"n\":\"MISC - Misc. Item\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"X1\"},{\"t\":3,\"p\":1,\"n\":\"Y1\"},{\"t\":3,\"p\":1,\"n\":\"Z1\"},{\"t\":3,\"p\":1,\"n\":\"X2\"},{\"t\":3,\"p\":1,\"n\":\"Y2\"},{\"t\":3,\"p\":1,\"n\":\"Z2\"}]},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"},{\"t\":11,\"n\":\"MODB - Unknown\"},{\"t\":11,\"p\":1,\"n\":\"MODT - Texture Files Hashes\"},{\"t\":7,\"p\":1,\"n\":\"MODS - Alternate Textures\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"3D Name\"},{\"t\":3,\"p\":1,\"n\":\"New Texture\"},{\"t\":3,\"p\":1,\"n\":\"3D Index\"}]}]},{\"t\":3,\"p\":1,\"n\":\"MODD - FaceGen Model Flags\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Icon\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"ICON - Large Icon filename\"},{\"t\":2,\"p\":1,\"n\":\"MICO - Small Icon filename\"}]},{\"t\":3,\"p\":1,\"n\":\"SCRI - Script\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Destructable\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"DEST - Header\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Health\"},{\"t\":3,\"p\":1,\"n\":\"Count\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":8,\"p\":1,\"n\":\"Stages\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Stage\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"DSTD - Destruction Stage Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Health %\"},{\"t\":3,\"p\":1,\"n\":\"Index\"},{\"t\":3,\"p\":1,\"n\":\"Damage Stage\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":3,\"p\":1,\"n\":\"Self Damage per Second\"},{\"t\":3,\"p\":1,\"n\":\"Explosion\"},{\"t\":3,\"p\":1,\"n\":\"Debris\"},{\"t\":3,\"p\":1,\"n\":\"Debris Count\"}]},{\"t\":6,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"DMDL - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"DMDT - Texture Files Hashes\"}]},{\"p\":1,\"n\":\"DSTF - End Marker\"}]}]}]},{\"t\":3,\"p\":1,\"n\":\"YNAM - Sound - Pick Up\"},{\"t\":3,\"p\":1,\"n\":\"ZNAM - Sound - Drop\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DATA - \",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Value\"},{\"t\":5,\"p\":1,\"n\":\"Weight\"}]}]},{\"t\":1,\"p\":1,\"n\":\"MSTT - Moveable Static\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"X1\"},{\"t\":3,\"p\":1,\"n\":\"Y1\"},{\"t\":3,\"p\":1,\"n\":\"Z1\"},{\"t\":3,\"p\":1,\"n\":\"X2\"},{\"t\":3,\"p\":1,\"n\":\"Y2\"},{\"t\":3,\"p\":1,\"n\":\"Z2\"}]},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"},{\"t\":11,\"n\":\"MODB - Unknown\"},{\"t\":11,\"p\":1,\"n\":\"MODT - Texture Files Hashes\"},{\"t\":7,\"p\":1,\"n\":\"MODS - Alternate Textures\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"3D Name\"},{\"t\":3,\"p\":1,\"n\":\"New Texture\"},{\"t\":3,\"p\":1,\"n\":\"3D Index\"}]}]},{\"t\":3,\"p\":1,\"n\":\"MODD - FaceGen Model Flags\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Destructable\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"DEST - Header\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Health\"},{\"t\":3,\"p\":1,\"n\":\"Count\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":8,\"p\":1,\"n\":\"Stages\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Stage\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"DSTD - Destruction Stage Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Health %\"},{\"t\":3,\"p\":1,\"n\":\"Index\"},{\"t\":3,\"p\":1,\"n\":\"Damage Stage\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":3,\"p\":1,\"n\":\"Self Damage per Second\"},{\"t\":3,\"p\":1,\"n\":\"Explosion\"},{\"t\":3,\"p\":1,\"n\":\"Debris\"},{\"t\":3,\"p\":1,\"n\":\"Debris Count\"}]},{\"t\":6,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"DMDL - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"DMDT - Texture Files Hashes\"}]},{\"p\":1,\"n\":\"DSTF - End Marker\"}]}]}]},{\"t\":11,\"n\":\"DATA - Unknown\"},{\"t\":3,\"p\":1,\"n\":\"SNAM - Sound\"}]},{\"t\":1,\"p\":1,\"n\":\"MUSC - Music Type\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"p\":1,\"n\":\"FNAM - Filename\"}]},{\"t\":1,\"p\":1,\"n\":\"NOTE - Note\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"X1\"},{\"t\":3,\"p\":1,\"n\":\"Y1\"},{\"t\":3,\"p\":1,\"n\":\"Z1\"},{\"t\":3,\"p\":1,\"n\":\"X2\"},{\"t\":3,\"p\":1,\"n\":\"Y2\"},{\"t\":3,\"p\":1,\"n\":\"Z2\"}]},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"},{\"t\":11,\"n\":\"MODB - Unknown\"},{\"t\":11,\"p\":1,\"n\":\"MODT - Texture Files Hashes\"},{\"t\":7,\"p\":1,\"n\":\"MODS - Alternate Textures\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"3D Name\"},{\"t\":3,\"p\":1,\"n\":\"New Texture\"},{\"t\":3,\"p\":1,\"n\":\"3D Index\"}]}]},{\"t\":3,\"p\":1,\"n\":\"MODD - FaceGen Model Flags\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Icon\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"ICON - Large Icon filename\"},{\"t\":2,\"p\":1,\"n\":\"MICO - Small Icon filename\"}]},{\"t\":3,\"p\":1,\"n\":\"YNAM - Sound - Pick Up\"},{\"t\":3,\"p\":1,\"n\":\"ZNAM - Sound - Drop\"},{\"t\":3,\"p\":1,\"n\":\"DATA - Type\"},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Quests\",\"d\":1,\"c\":[{\"t\":3,\"p\":1,\"n\":\"ONAM - Quest\"}]},{\"t\":2,\"p\":1,\"n\":\"XNAM - Texture\"},{\"t\":2,\"p\":1,\"n\":\"Text\"},{\"t\":3,\"p\":1,\"n\":\"Topic\"},{\"t\":3,\"p\":1,\"n\":\"Sound\"},{\"t\":3,\"p\":1,\"n\":\"NPC\"}]},{\"t\":1,\"p\":1,\"n\":\"NPC_ - Non-Player Character\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"X1\"},{\"t\":3,\"p\":1,\"n\":\"Y1\"},{\"t\":3,\"p\":1,\"n\":\"Z1\"},{\"t\":3,\"p\":1,\"n\":\"X2\"},{\"t\":3,\"p\":1,\"n\":\"Y2\"},{\"t\":3,\"p\":1,\"n\":\"Z2\"}]},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"},{\"t\":11,\"n\":\"MODB - Unknown\"},{\"t\":11,\"p\":1,\"n\":\"MODT - Texture Files Hashes\"},{\"t\":7,\"p\":1,\"n\":\"MODS - Alternate Textures\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"3D Name\"},{\"t\":3,\"p\":1,\"n\":\"New Texture\"},{\"t\":3,\"p\":1,\"n\":\"3D Index\"}]}]},{\"t\":3,\"p\":1,\"n\":\"MODD - FaceGen Model Flags\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"ACBS - Configuration\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":3,\"p\":1,\"n\":\"Fatigue\"},{\"t\":3,\"p\":1,\"n\":\"Barter gold\"},{\"t\":3,\"p\":1,\"n\":\"Level\"},{\"t\":3,\"p\":1,\"n\":\"Level Mult\"},{\"t\":3,\"p\":1,\"n\":\"Calc min\"},{\"t\":3,\"p\":1,\"n\":\"Calc max\"},{\"t\":3,\"p\":1,\"n\":\"Speed Multiplier\"},{\"t\":5,\"p\":1,\"n\":\"Karma (Alignment)\"},{\"t\":3,\"p\":1,\"n\":\"Disposition Base\"},{\"t\":3,\"p\":1,\"n\":\"Template Flags\"}]},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Factions\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"SNAM - Faction\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Faction\"},{\"t\":3,\"p\":1,\"n\":\"Rank\"},{\"t\":11,\"n\":\"Unused\"}]}]},{\"t\":3,\"p\":1,\"n\":\"INAM - Death item\"},{\"t\":3,\"p\":1,\"n\":\"VTCK - Voice\"},{\"t\":3,\"p\":1,\"n\":\"TPLT - Template\"},{\"t\":3,\"p\":1,\"n\":\"RNAM - Race\"},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Actor Effects\",\"d\":1,\"c\":[{\"t\":3,\"p\":1,\"n\":\"SPLO - Actor Effect\"}]},{\"t\":3,\"p\":1,\"n\":\"EITM - Unarmed Attack Effect\"},{\"t\":3,\"p\":1,\"n\":\"EAMT - Unarmed Attack Animation\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Destructable\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"DEST - Header\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Health\"},{\"t\":3,\"p\":1,\"n\":\"Count\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":8,\"p\":1,\"n\":\"Stages\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Stage\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"DSTD - Destruction Stage Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Health %\"},{\"t\":3,\"p\":1,\"n\":\"Index\"},{\"t\":3,\"p\":1,\"n\":\"Damage Stage\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":3,\"p\":1,\"n\":\"Self Damage per Second\"},{\"t\":3,\"p\":1,\"n\":\"Explosion\"},{\"t\":3,\"p\":1,\"n\":\"Debris\"},{\"t\":3,\"p\":1,\"n\":\"Debris Count\"}]},{\"t\":6,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"DMDL - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"DMDT - Texture Files Hashes\"}]},{\"p\":1,\"n\":\"DSTF - End Marker\"}]}]}]},{\"t\":3,\"p\":1,\"n\":\"SCRI - Script\"},{\"t\":10,\"p\":1,\"n\":\"Items\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Item\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"CNTO - Item\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Item\"},{\"t\":3,\"p\":1,\"n\":\"Count\"}]},{\"t\":6,\"p\":1,\"n\":\"COED - Extra Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Owner\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Global Variable\"},{\"t\":3,\"p\":1,\"n\":\"Required Rank\"},{\"t\":5,\"p\":1,\"n\":\"Item Condition\"}]}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"AIDT - AI Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Aggression\"},{\"t\":3,\"p\":1,\"n\":\"Confidence\"},{\"t\":3,\"p\":1,\"n\":\"Energy Level\"},{\"t\":3,\"p\":1,\"n\":\"Responsibility\"},{\"t\":3,\"p\":1,\"n\":\"Mood\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Buys\\/Sells and Services\"},{\"t\":3,\"p\":1,\"n\":\"Teaches\"},{\"t\":3,\"p\":1,\"n\":\"Maximum training level\"},{\"t\":3,\"p\":1,\"n\":\"Assistance\"},{\"t\":3,\"p\":1,\"n\":\"Aggro Radius Behavior\"},{\"t\":3,\"p\":1,\"n\":\"Aggro Radius\"}]},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Packages\",\"d\":1,\"c\":[{\"t\":3,\"p\":1,\"n\":\"PKID - Package\"}]},{\"t\":7,\"p\":1,\"n\":\"KFFZ - Animations\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"Animation\"}]},{\"t\":3,\"p\":1,\"n\":\"CNAM - Class\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DATA - \",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Base Health\"},{\"t\":7,\"p\":1,\"n\":\"Attributes\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Attribute\"}]},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DNAM - \",\"c\":[{\"t\":7,\"p\":1,\"n\":\"Skill Values\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Skill\"}]},{\"t\":7,\"p\":1,\"n\":\"Skill Offsets\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Skill\"}]}]},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Head Parts\",\"d\":1,\"c\":[{\"t\":3,\"p\":1,\"n\":\"PNAM - Head Part\"}]},{\"t\":3,\"p\":1,\"n\":\"HNAM - Hair\"},{\"t\":5,\"p\":1,\"n\":\"LNAM - Hair length\"},{\"t\":3,\"p\":1,\"n\":\"ENAM - Eyes\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"HCLR - Hair color\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":3,\"p\":1,\"n\":\"ZNAM - Combat Style\"},{\"t\":3,\"p\":1,\"n\":\"NAM4 - Impact Material Type\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"FaceGen Data\",\"c\":[{\"t\":11,\"p\":1,\"n\":\"FGGS - FaceGen Geometry-Symmetric\"},{\"t\":11,\"p\":1,\"n\":\"FGGA - FaceGen Geometry-Asymmetric\"},{\"t\":11,\"p\":1,\"n\":\"FGTS - FaceGen Texture-Symmetric\"}]},{\"t\":3,\"n\":\"NAM5 - Unknown\"},{\"t\":5,\"p\":1,\"n\":\"NAM6 - Height\"},{\"t\":5,\"p\":1,\"n\":\"NAM7 - Weight\"}]},{\"t\":1,\"p\":1,\"n\":\"PACK - Package\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"PKDT - General\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"General Flags\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Fallout Behavior Flags\"},{\"p\":1,\"n\":\"Type Specific Flags (missing)\"},{\"t\":3,\"p\":1,\"n\":\"Type Specific Flags - Find\"},{\"t\":3,\"p\":1,\"n\":\"Type Specific Flags - Follow\"},{\"t\":3,\"p\":1,\"n\":\"Type Specific Flags - Escort\"},{\"t\":3,\"p\":1,\"n\":\"Type Specific Flags - Eat\"},{\"t\":3,\"p\":1,\"n\":\"Type Specific Flags - Sleep\"},{\"t\":3,\"p\":1,\"n\":\"Type Specific Flags - Wander\"},{\"t\":3,\"p\":1,\"n\":\"Type Specific Flags - Travel\"},{\"t\":3,\"p\":1,\"n\":\"Type Specific Flags - Accompany\"},{\"t\":3,\"p\":1,\"n\":\"Type Specific Flags - Use Item At\"},{\"t\":3,\"p\":1,\"n\":\"Type Specific Flags - Ambush\"},{\"t\":3,\"p\":1,\"n\":\"Type Specific Flags - Flee Not Combat\"},{\"t\":3,\"p\":1,\"n\":\"Type Specific Flags - ?\"},{\"t\":3,\"p\":1,\"n\":\"Type Specific Flags - Sandbox\"},{\"t\":3,\"p\":1,\"n\":\"Type Specific Flags - Patrol\"},{\"t\":3,\"p\":1,\"n\":\"Type Specific Flags - Guard\"},{\"t\":3,\"p\":1,\"n\":\"Type Specific Flags - Dialogue\"},{\"t\":3,\"p\":1,\"n\":\"Type Specific Flags - Use Weapon\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Locations\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"PLDT - Location 1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":3,\"p\":1,\"n\":\"Cell\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Object ID\"},{\"t\":3,\"p\":1,\"n\":\"Object Type\"},{\"t\":3,\"p\":1,\"n\":\"Radius\"}]},{\"t\":6,\"p\":1,\"n\":\"PLD2 - Location 2\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":3,\"p\":1,\"n\":\"Cell\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Object ID\"},{\"t\":3,\"p\":1,\"n\":\"Object Type\"},{\"t\":3,\"p\":1,\"n\":\"Radius\"}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"PSDT - Schedule\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Month\"},{\"t\":3,\"p\":1,\"n\":\"Day of week\"},{\"t\":3,\"p\":1,\"n\":\"Date\"},{\"t\":3,\"p\":1,\"n\":\"Time\"},{\"t\":3,\"p\":1,\"n\":\"Duration\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"PTDT - Target 1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":3,\"p\":1,\"n\":\"Object ID\"},{\"t\":3,\"p\":1,\"n\":\"Object Type\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Count \\/ Distance\"},{\"t\":5,\"n\":\"Unknown\"}]},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Conditions\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"CTDA - Condition\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":5,\"p\":1,\"n\":\"Comparison Value - Float\"},{\"t\":3,\"p\":1,\"n\":\"Comparison Value - Global\"},{\"t\":3,\"p\":1,\"n\":\"Function\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":11,\"p\":1,\"n\":\"None\"},{\"t\":3,\"p\":1,\"n\":\"Integer\"},{\"t\":3,\"p\":1,\"n\":\"Variable Name (INVALID)\"},{\"t\":3,\"p\":1,\"n\":\"Sex\"},{\"t\":3,\"p\":1,\"n\":\"Actor Value\"},{\"t\":3,\"p\":1,\"n\":\"Crime Type\"},{\"t\":3,\"p\":1,\"n\":\"Axis\"},{\"t\":3,\"p\":1,\"n\":\"Quest Stage (INVALID)\"},{\"t\":3,\"p\":1,\"n\":\"Misc Stat\"},{\"t\":3,\"p\":1,\"n\":\"Alignment\"},{\"t\":3,\"p\":1,\"n\":\"Equip Type\"},{\"t\":3,\"p\":1,\"n\":\"Form Type\"},{\"t\":3,\"p\":1,\"n\":\"Critical Stage\"},{\"t\":3,\"p\":1,\"n\":\"Object Reference\"},{\"t\":3,\"p\":1,\"n\":\"Inventory Object\"},{\"t\":3,\"p\":1,\"n\":\"Actor\"},{\"t\":3,\"p\":1,\"n\":\"Voice Type\"},{\"t\":3,\"p\":1,\"n\":\"Idle\"},{\"t\":3,\"p\":1,\"n\":\"Form List\"},{\"t\":3,\"p\":1,\"n\":\"Note\"},{\"t\":3,\"p\":1,\"n\":\"Quest\"},{\"t\":3,\"p\":1,\"n\":\"Faction\"},{\"t\":3,\"p\":1,\"n\":\"Weapon\"},{\"t\":3,\"p\":1,\"n\":\"Cell\"},{\"t\":3,\"p\":1,\"n\":\"Class\"},{\"t\":3,\"p\":1,\"n\":\"Race\"},{\"t\":3,\"p\":1,\"n\":\"Actor Base\"},{\"t\":3,\"p\":1,\"n\":\"Global\"},{\"t\":3,\"p\":1,\"n\":\"Weather\"},{\"t\":3,\"p\":1,\"n\":\"Package\"},{\"t\":3,\"p\":1,\"n\":\"Encounter Zone\"},{\"t\":3,\"p\":1,\"n\":\"Perk\"},{\"t\":3,\"p\":1,\"n\":\"Owner\"},{\"t\":3,\"p\":1,\"n\":\"Furniture\"},{\"t\":3,\"p\":1,\"n\":\"Effect Item\"},{\"t\":3,\"p\":1,\"n\":\"Base Effect\"},{\"t\":3,\"p\":1,\"n\":\"Worldspace\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Function\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Param (INVALID)\"},{\"t\":3,\"p\":1,\"n\":\"Creature Type\"},{\"t\":3,\"p\":1,\"n\":\"Menu Mode\"},{\"t\":3,\"p\":1,\"n\":\"Player Action\"},{\"t\":3,\"p\":1,\"n\":\"Body Location\"},{\"t\":3,\"p\":1,\"n\":\"Referenceable Object\"},{\"t\":3,\"p\":1,\"n\":\"Variable Name\"},{\"t\":3,\"p\":1,\"n\":\"Quest Stage\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Function (INVALID)\"},{\"t\":3,\"p\":1,\"n\":\"Weapon List\"},{\"t\":3,\"p\":1,\"n\":\"Target\"},{\"t\":3,\"p\":1,\"n\":\"Target List\"},{\"t\":3,\"p\":1,\"n\":\"Target Part\"},{\"t\":3,\"p\":1,\"n\":\"VATS Action\"},{\"t\":3,\"p\":1,\"n\":\"Critical Effect\"},{\"t\":3,\"p\":1,\"n\":\"Critical Effect List\"},{\"t\":3,\"p\":1,\"n\":\"Weapon Type\"},{\"t\":3,\"p\":1,\"n\":\"Run On\"},{\"t\":3,\"p\":1,\"n\":\"Reference\"}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Idle Animations\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"IDLF - Flags\"},{\"t\":6,\"p\":1,\"n\":\"IDLC - \",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Animation Count\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":5,\"p\":1,\"n\":\"IDLT - Idle Timer Setting\"},{\"t\":7,\"p\":1,\"n\":\"IDLA - Animations\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Animation\"}]},{\"t\":11,\"n\":\"IDLB - Unused\"}]},{\"t\":3,\"p\":1,\"n\":\"CNAM - Combat Style\"},{\"p\":1,\"n\":\"PKED - Eat Marker\"},{\"t\":3,\"p\":1,\"n\":\"PKE2 - Escort Distance\"},{\"t\":5,\"p\":1,\"n\":\"PKFD - Follow - Start Location - Trigger Radius\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"PKPT - Patrol Flags\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Repeatable\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"PKW3 - Use Weapon Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":3,\"p\":1,\"n\":\"Fire Rate\"},{\"t\":3,\"p\":1,\"n\":\"Fire Count\"},{\"t\":3,\"p\":1,\"n\":\"Number of Bursts\"},{\"t\":6,\"p\":1,\"n\":\"Shoots Per Volleys\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Min\"},{\"t\":3,\"p\":1,\"n\":\"Max\"}]},{\"t\":6,\"p\":1,\"n\":\"Pause Between Volleys\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Min\"},{\"t\":5,\"p\":1,\"n\":\"Max\"}]},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"PTD2 - Target 2\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":3,\"p\":1,\"n\":\"Object ID\"},{\"t\":3,\"p\":1,\"n\":\"Object Type\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Count \\/ Distance\"},{\"t\":5,\"n\":\"Unknown\"}]},{\"p\":1,\"n\":\"PUID - Use Item Marker\"},{\"p\":1,\"n\":\"PKAM - Ambush Marker\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"PKDD - Dialogue Data\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"FOV\"},{\"t\":3,\"p\":1,\"n\":\"Topic\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Dialogue Type\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"PLD2 - Location 2 (again??)\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":3,\"p\":1,\"n\":\"Cell\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Object ID\"},{\"t\":3,\"p\":1,\"n\":\"Object Type\"},{\"t\":3,\"p\":1,\"n\":\"Radius\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"OnBegin\",\"c\":[{\"p\":1,\"n\":\"POBA - OnBegin Marker\"},{\"t\":3,\"p\":1,\"n\":\"INAM - Idle\"},{\"t\":6,\"p\":1,\"n\":\"Embedded Script\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"SCHR - Basic Script Data\",\"c\":[{\"t\":11,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"RefCount\"},{\"t\":3,\"p\":1,\"n\":\"CompiledSize\"},{\"t\":3,\"p\":1,\"n\":\"VariableCount\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"}]},{\"t\":11,\"p\":1,\"n\":\"SCDA - Compiled Embedded Script\"},{\"t\":2,\"p\":1,\"n\":\"SCTX - Embedded Script Source\"},{\"t\":10,\"p\":1,\"n\":\"Local Variables\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Local Variable\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"SLSD - Local Variable Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Index\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"}]},{\"t\":2,\"p\":1,\"n\":\"SCVR - Name\"}]}]},{\"t\":8,\"p\":1,\"n\":\"References\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"SCRO - Global Reference\"},{\"t\":3,\"p\":1,\"n\":\"SCRV - Local Variable\"}]}]},{\"t\":3,\"p\":1,\"n\":\"TNAM - Topic\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"OnEnd\",\"c\":[{\"p\":1,\"n\":\"POEA - OnEnd Marker\"},{\"t\":3,\"p\":1,\"n\":\"INAM - Idle\"},{\"t\":6,\"p\":1,\"n\":\"Embedded Script\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"SCHR - Basic Script Data\",\"c\":[{\"t\":11,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"RefCount\"},{\"t\":3,\"p\":1,\"n\":\"CompiledSize\"},{\"t\":3,\"p\":1,\"n\":\"VariableCount\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"}]},{\"t\":11,\"p\":1,\"n\":\"SCDA - Compiled Embedded Script\"},{\"t\":2,\"p\":1,\"n\":\"SCTX - Embedded Script Source\"},{\"t\":10,\"p\":1,\"n\":\"Local Variables\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Local Variable\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"SLSD - Local Variable Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Index\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"}]},{\"t\":2,\"p\":1,\"n\":\"SCVR - Name\"}]}]},{\"t\":8,\"p\":1,\"n\":\"References\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"SCRO - Global Reference\"},{\"t\":3,\"p\":1,\"n\":\"SCRV - Local Variable\"}]}]},{\"t\":3,\"p\":1,\"n\":\"TNAM - Topic\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"OnChange\",\"c\":[{\"p\":1,\"n\":\"POCA - OnChange Marker\"},{\"t\":3,\"p\":1,\"n\":\"INAM - Idle\"},{\"t\":6,\"p\":1,\"n\":\"Embedded Script\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"SCHR - Basic Script Data\",\"c\":[{\"t\":11,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"RefCount\"},{\"t\":3,\"p\":1,\"n\":\"CompiledSize\"},{\"t\":3,\"p\":1,\"n\":\"VariableCount\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"}]},{\"t\":11,\"p\":1,\"n\":\"SCDA - Compiled Embedded Script\"},{\"t\":2,\"p\":1,\"n\":\"SCTX - Embedded Script Source\"},{\"t\":10,\"p\":1,\"n\":\"Local Variables\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Local Variable\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"SLSD - Local Variable Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Index\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"}]},{\"t\":2,\"p\":1,\"n\":\"SCVR - Name\"}]}]},{\"t\":8,\"p\":1,\"n\":\"References\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"SCRO - Global Reference\"},{\"t\":3,\"p\":1,\"n\":\"SCRV - Local Variable\"}]}]},{\"t\":3,\"p\":1,\"n\":\"TNAM - Topic\"}]}]},{\"t\":1,\"p\":1,\"n\":\"PBEA - Placed Beam\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":3,\"p\":1,\"n\":\"NAME - Base\"},{\"t\":3,\"p\":1,\"n\":\"XEZN - Encounter Zone\"},{\"t\":11,\"n\":\"XRGD - Ragdoll Data\"},{\"t\":11,\"n\":\"XRGB - Ragdoll Biped Data\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Patrol Data\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"XPRD - Idle Time\"},{\"p\":1,\"n\":\"XPPA - Patrol Script Marker\"},{\"t\":3,\"p\":1,\"n\":\"INAM - Idle\"},{\"t\":6,\"p\":1,\"n\":\"Embedded Script\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"SCHR - Basic Script Data\",\"c\":[{\"t\":11,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"RefCount\"},{\"t\":3,\"p\":1,\"n\":\"CompiledSize\"},{\"t\":3,\"p\":1,\"n\":\"VariableCount\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"}]},{\"t\":11,\"p\":1,\"n\":\"SCDA - Compiled Embedded Script\"},{\"t\":2,\"p\":1,\"n\":\"SCTX - Embedded Script Source\"},{\"t\":10,\"p\":1,\"n\":\"Local Variables\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Local Variable\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"SLSD - Local Variable Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Index\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"}]},{\"t\":2,\"p\":1,\"n\":\"SCVR - Name\"}]}]},{\"t\":8,\"p\":1,\"n\":\"References\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"SCRO - Global Reference\"},{\"t\":3,\"p\":1,\"n\":\"SCRV - Local Variable\"}]}]},{\"t\":3,\"p\":1,\"n\":\"TNAM - Topic\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Ownership\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"XOWN - Owner\"},{\"t\":3,\"p\":1,\"n\":\"XRNK - Faction rank\"}]},{\"t\":3,\"p\":1,\"n\":\"XCNT - Count\"},{\"t\":5,\"p\":1,\"n\":\"XRDS - Radius\"},{\"t\":5,\"p\":1,\"n\":\"XHLP - Health\"},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Reflected\\/Refracted By\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"XPWR - Water\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":3,\"p\":1,\"n\":\"Type\"}]}]},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Linked Decals\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"XDCR - Decal\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":11,\"n\":\"Unknown\"}]}]},{\"t\":3,\"p\":1,\"n\":\"XLKR - Linked Reference\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"XCLP - Linked Reference Color\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Link Start Color\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Link End Color\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Activate Parents\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"XAPD - Flags\"},{\"t\":8,\"p\":1,\"n\":\"Activate Parent Refs\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"XAPR - Activate Parent Ref\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":5,\"p\":1,\"n\":\"Delay\"}]}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"XESP - Enable Parent\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":3,\"p\":1,\"n\":\"XEMI - Emittance\"},{\"t\":3,\"p\":1,\"n\":\"XMBR - MultiBound Reference\"},{\"p\":1,\"n\":\"XIBS - Ignored By Sandbox\"},{\"t\":5,\"p\":1,\"n\":\"XSCL - Scale\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DATA - Position\\/Rotation\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Position\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"X\"},{\"t\":5,\"p\":1,\"n\":\"Y\"},{\"t\":5,\"p\":1,\"n\":\"Z\"}]},{\"t\":6,\"p\":1,\"n\":\"Rotation\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"X\"},{\"t\":5,\"p\":1,\"n\":\"Y\"},{\"t\":5,\"p\":1,\"n\":\"Z\"}]}]}]},{\"t\":1,\"p\":1,\"n\":\"PERK - Perk\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":2,\"p\":1,\"n\":\"DESC - Description\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Icon\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"ICON - Large Icon filename\"},{\"t\":2,\"p\":1,\"n\":\"MICO - Small Icon filename\"}]},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Conditions\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"CTDA - Condition\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":5,\"p\":1,\"n\":\"Comparison Value - Float\"},{\"t\":3,\"p\":1,\"n\":\"Comparison Value - Global\"},{\"t\":3,\"p\":1,\"n\":\"Function\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":11,\"p\":1,\"n\":\"None\"},{\"t\":3,\"p\":1,\"n\":\"Integer\"},{\"t\":3,\"p\":1,\"n\":\"Variable Name (INVALID)\"},{\"t\":3,\"p\":1,\"n\":\"Sex\"},{\"t\":3,\"p\":1,\"n\":\"Actor Value\"},{\"t\":3,\"p\":1,\"n\":\"Crime Type\"},{\"t\":3,\"p\":1,\"n\":\"Axis\"},{\"t\":3,\"p\":1,\"n\":\"Quest Stage (INVALID)\"},{\"t\":3,\"p\":1,\"n\":\"Misc Stat\"},{\"t\":3,\"p\":1,\"n\":\"Alignment\"},{\"t\":3,\"p\":1,\"n\":\"Equip Type\"},{\"t\":3,\"p\":1,\"n\":\"Form Type\"},{\"t\":3,\"p\":1,\"n\":\"Critical Stage\"},{\"t\":3,\"p\":1,\"n\":\"Object Reference\"},{\"t\":3,\"p\":1,\"n\":\"Inventory Object\"},{\"t\":3,\"p\":1,\"n\":\"Actor\"},{\"t\":3,\"p\":1,\"n\":\"Voice Type\"},{\"t\":3,\"p\":1,\"n\":\"Idle\"},{\"t\":3,\"p\":1,\"n\":\"Form List\"},{\"t\":3,\"p\":1,\"n\":\"Note\"},{\"t\":3,\"p\":1,\"n\":\"Quest\"},{\"t\":3,\"p\":1,\"n\":\"Faction\"},{\"t\":3,\"p\":1,\"n\":\"Weapon\"},{\"t\":3,\"p\":1,\"n\":\"Cell\"},{\"t\":3,\"p\":1,\"n\":\"Class\"},{\"t\":3,\"p\":1,\"n\":\"Race\"},{\"t\":3,\"p\":1,\"n\":\"Actor Base\"},{\"t\":3,\"p\":1,\"n\":\"Global\"},{\"t\":3,\"p\":1,\"n\":\"Weather\"},{\"t\":3,\"p\":1,\"n\":\"Package\"},{\"t\":3,\"p\":1,\"n\":\"Encounter Zone\"},{\"t\":3,\"p\":1,\"n\":\"Perk\"},{\"t\":3,\"p\":1,\"n\":\"Owner\"},{\"t\":3,\"p\":1,\"n\":\"Furniture\"},{\"t\":3,\"p\":1,\"n\":\"Effect Item\"},{\"t\":3,\"p\":1,\"n\":\"Base Effect\"},{\"t\":3,\"p\":1,\"n\":\"Worldspace\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Function\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Param (INVALID)\"},{\"t\":3,\"p\":1,\"n\":\"Creature Type\"},{\"t\":3,\"p\":1,\"n\":\"Menu Mode\"},{\"t\":3,\"p\":1,\"n\":\"Player Action\"},{\"t\":3,\"p\":1,\"n\":\"Body Location\"},{\"t\":3,\"p\":1,\"n\":\"Referenceable Object\"},{\"t\":3,\"p\":1,\"n\":\"Variable Name\"},{\"t\":3,\"p\":1,\"n\":\"Quest Stage\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Function (INVALID)\"},{\"t\":3,\"p\":1,\"n\":\"Weapon List\"},{\"t\":3,\"p\":1,\"n\":\"Target\"},{\"t\":3,\"p\":1,\"n\":\"Target List\"},{\"t\":3,\"p\":1,\"n\":\"Target Part\"},{\"t\":3,\"p\":1,\"n\":\"VATS Action\"},{\"t\":3,\"p\":1,\"n\":\"Critical Effect\"},{\"t\":3,\"p\":1,\"n\":\"Critical Effect List\"},{\"t\":3,\"p\":1,\"n\":\"Weapon Type\"},{\"t\":3,\"p\":1,\"n\":\"Run On\"},{\"t\":3,\"p\":1,\"n\":\"Reference\"}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DATA - Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Trait\"},{\"t\":3,\"p\":1,\"n\":\"Min Level\"},{\"t\":3,\"p\":1,\"n\":\"Ranks\"},{\"t\":3,\"p\":1,\"n\":\"Playable\"},{\"t\":3,\"p\":1,\"n\":\"Hidden\"}]},{\"t\":10,\"p\":1,\"n\":\"Effects\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Effect\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"PRKE - Header\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Rank\"},{\"t\":3,\"p\":1,\"n\":\"Priority\"}]},{\"t\":6,\"p\":1,\"n\":\"Quest + Stage\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Quest\"},{\"t\":3,\"p\":1,\"n\":\"Quest Stage\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":3,\"p\":1,\"n\":\"Ability\"},{\"t\":6,\"p\":1,\"n\":\"Entry Point\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Entry Point\"},{\"t\":3,\"p\":1,\"n\":\"Function\"},{\"t\":3,\"p\":1,\"n\":\"Perk Condition Tab Count\"}]},{\"t\":10,\"p\":1,\"n\":\"Perk Conditions\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Perk Condition\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"PRKC - Run On\"},{\"t\":8,\"p\":1,\"n\":\"Conditions\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"CTDA - Condition\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":5,\"p\":1,\"n\":\"Comparison Value - Float\"},{\"t\":3,\"p\":1,\"n\":\"Comparison Value - Global\"},{\"t\":3,\"p\":1,\"n\":\"Function\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":11,\"p\":1,\"n\":\"None\"},{\"t\":3,\"p\":1,\"n\":\"Integer\"},{\"t\":3,\"p\":1,\"n\":\"Variable Name (INVALID)\"},{\"t\":3,\"p\":1,\"n\":\"Sex\"},{\"t\":3,\"p\":1,\"n\":\"Actor Value\"},{\"t\":3,\"p\":1,\"n\":\"Crime Type\"},{\"t\":3,\"p\":1,\"n\":\"Axis\"},{\"t\":3,\"p\":1,\"n\":\"Quest Stage (INVALID)\"},{\"t\":3,\"p\":1,\"n\":\"Misc Stat\"},{\"t\":3,\"p\":1,\"n\":\"Alignment\"},{\"t\":3,\"p\":1,\"n\":\"Equip Type\"},{\"t\":3,\"p\":1,\"n\":\"Form Type\"},{\"t\":3,\"p\":1,\"n\":\"Critical Stage\"},{\"t\":3,\"p\":1,\"n\":\"Object Reference\"},{\"t\":3,\"p\":1,\"n\":\"Inventory Object\"},{\"t\":3,\"p\":1,\"n\":\"Actor\"},{\"t\":3,\"p\":1,\"n\":\"Voice Type\"},{\"t\":3,\"p\":1,\"n\":\"Idle\"},{\"t\":3,\"p\":1,\"n\":\"Form List\"},{\"t\":3,\"p\":1,\"n\":\"Note\"},{\"t\":3,\"p\":1,\"n\":\"Quest\"},{\"t\":3,\"p\":1,\"n\":\"Faction\"},{\"t\":3,\"p\":1,\"n\":\"Weapon\"},{\"t\":3,\"p\":1,\"n\":\"Cell\"},{\"t\":3,\"p\":1,\"n\":\"Class\"},{\"t\":3,\"p\":1,\"n\":\"Race\"},{\"t\":3,\"p\":1,\"n\":\"Actor Base\"},{\"t\":3,\"p\":1,\"n\":\"Global\"},{\"t\":3,\"p\":1,\"n\":\"Weather\"},{\"t\":3,\"p\":1,\"n\":\"Package\"},{\"t\":3,\"p\":1,\"n\":\"Encounter Zone\"},{\"t\":3,\"p\":1,\"n\":\"Perk\"},{\"t\":3,\"p\":1,\"n\":\"Owner\"},{\"t\":3,\"p\":1,\"n\":\"Furniture\"},{\"t\":3,\"p\":1,\"n\":\"Effect Item\"},{\"t\":3,\"p\":1,\"n\":\"Base Effect\"},{\"t\":3,\"p\":1,\"n\":\"Worldspace\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Function\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Param (INVALID)\"},{\"t\":3,\"p\":1,\"n\":\"Creature Type\"},{\"t\":3,\"p\":1,\"n\":\"Menu Mode\"},{\"t\":3,\"p\":1,\"n\":\"Player Action\"},{\"t\":3,\"p\":1,\"n\":\"Body Location\"},{\"t\":3,\"p\":1,\"n\":\"Referenceable Object\"},{\"t\":3,\"p\":1,\"n\":\"Variable Name\"},{\"t\":3,\"p\":1,\"n\":\"Quest Stage\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Function (INVALID)\"},{\"t\":3,\"p\":1,\"n\":\"Weapon List\"},{\"t\":3,\"p\":1,\"n\":\"Target\"},{\"t\":3,\"p\":1,\"n\":\"Target List\"},{\"t\":3,\"p\":1,\"n\":\"Target Part\"},{\"t\":3,\"p\":1,\"n\":\"VATS Action\"},{\"t\":3,\"p\":1,\"n\":\"Critical Effect\"},{\"t\":3,\"p\":1,\"n\":\"Critical Effect List\"},{\"t\":3,\"p\":1,\"n\":\"Weapon Type\"},{\"t\":3,\"p\":1,\"n\":\"Run On\"},{\"t\":3,\"p\":1,\"n\":\"Reference\"}]}]}]}]},{\"t\":6,\"p\":1,\"n\":\"Entry Point Function Parameters\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"EPFT - Type\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":6,\"p\":1,\"n\":\"Float, Float\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Float 1\"},{\"t\":5,\"p\":1,\"n\":\"Float 2\"}]},{\"t\":3,\"p\":1,\"n\":\"Leveled Item\"},{\"p\":1,\"n\":\"None (Script)\"},{\"t\":6,\"p\":1,\"n\":\"Actor Value, Float\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Actor Value\"},{\"t\":5,\"p\":1,\"n\":\"Float\"}]},{\"t\":2,\"p\":1,\"n\":\"EPF2 - Button Label\"},{\"t\":3,\"p\":1,\"n\":\"EPF3 - Script Flags\"},{\"t\":6,\"p\":1,\"n\":\"Embedded Script\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"SCHR - Basic Script Data\",\"c\":[{\"t\":11,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"RefCount\"},{\"t\":3,\"p\":1,\"n\":\"CompiledSize\"},{\"t\":3,\"p\":1,\"n\":\"VariableCount\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"}]},{\"t\":11,\"p\":1,\"n\":\"SCDA - Compiled Embedded Script\"},{\"t\":2,\"p\":1,\"n\":\"SCTX - Embedded Script Source\"},{\"t\":10,\"p\":1,\"n\":\"Local Variables\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Local Variable\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"SLSD - Local Variable Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Index\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"}]},{\"t\":2,\"p\":1,\"n\":\"SCVR - Name\"}]}]},{\"t\":8,\"p\":1,\"n\":\"References\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"SCRO - Global Reference\"},{\"t\":3,\"p\":1,\"n\":\"SCRV - Local Variable\"}]}]}]},{\"p\":1,\"n\":\"PRKF - End Marker\"}]}]}]},{\"t\":1,\"p\":1,\"n\":\"PGRE - Placed Grenade\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":3,\"p\":1,\"n\":\"NAME - Base\"},{\"t\":3,\"p\":1,\"n\":\"XEZN - Encounter Zone\"},{\"t\":11,\"n\":\"XRGD - Ragdoll Data\"},{\"t\":11,\"n\":\"XRGB - Ragdoll Biped Data\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Patrol Data\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"XPRD - Idle Time\"},{\"p\":1,\"n\":\"XPPA - Patrol Script Marker\"},{\"t\":3,\"p\":1,\"n\":\"INAM - Idle\"},{\"t\":6,\"p\":1,\"n\":\"Embedded Script\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"SCHR - Basic Script Data\",\"c\":[{\"t\":11,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"RefCount\"},{\"t\":3,\"p\":1,\"n\":\"CompiledSize\"},{\"t\":3,\"p\":1,\"n\":\"VariableCount\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"}]},{\"t\":11,\"p\":1,\"n\":\"SCDA - Compiled Embedded Script\"},{\"t\":2,\"p\":1,\"n\":\"SCTX - Embedded Script Source\"},{\"t\":10,\"p\":1,\"n\":\"Local Variables\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Local Variable\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"SLSD - Local Variable Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Index\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"}]},{\"t\":2,\"p\":1,\"n\":\"SCVR - Name\"}]}]},{\"t\":8,\"p\":1,\"n\":\"References\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"SCRO - Global Reference\"},{\"t\":3,\"p\":1,\"n\":\"SCRV - Local Variable\"}]}]},{\"t\":3,\"p\":1,\"n\":\"TNAM - Topic\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Ownership\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"XOWN - Owner\"},{\"t\":3,\"p\":1,\"n\":\"XRNK - Faction rank\"}]},{\"t\":3,\"p\":1,\"n\":\"XCNT - Count\"},{\"t\":5,\"p\":1,\"n\":\"XRDS - Radius\"},{\"t\":5,\"p\":1,\"n\":\"XHLP - Health\"},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Reflected\\/Refracted By\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"XPWR - Water\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":3,\"p\":1,\"n\":\"Type\"}]}]},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Linked Decals\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"XDCR - Decal\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":11,\"n\":\"Unknown\"}]}]},{\"t\":3,\"p\":1,\"n\":\"XLKR - Linked Reference\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"XCLP - Linked Reference Color\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Link Start Color\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Link End Color\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Activate Parents\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"XAPD - Flags\"},{\"t\":8,\"p\":1,\"n\":\"Activate Parent Refs\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"XAPR - Activate Parent Ref\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":5,\"p\":1,\"n\":\"Delay\"}]}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"XESP - Enable Parent\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":3,\"p\":1,\"n\":\"XEMI - Emittance\"},{\"t\":3,\"p\":1,\"n\":\"XMBR - MultiBound Reference\"},{\"p\":1,\"n\":\"XIBS - Ignored By Sandbox\"},{\"t\":5,\"p\":1,\"n\":\"XSCL - Scale\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DATA - Position\\/Rotation\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Position\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"X\"},{\"t\":5,\"p\":1,\"n\":\"Y\"},{\"t\":5,\"p\":1,\"n\":\"Z\"}]},{\"t\":6,\"p\":1,\"n\":\"Rotation\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"X\"},{\"t\":5,\"p\":1,\"n\":\"Y\"},{\"t\":5,\"p\":1,\"n\":\"Z\"}]}]}]},{\"t\":1,\"p\":1,\"n\":\"PMIS - Placed Missile\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":3,\"p\":1,\"n\":\"NAME - Base\"},{\"t\":3,\"p\":1,\"n\":\"XEZN - Encounter Zone\"},{\"t\":11,\"n\":\"XRGD - Ragdoll Data\"},{\"t\":11,\"n\":\"XRGB - Ragdoll Biped Data\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Patrol Data\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"XPRD - Idle Time\"},{\"p\":1,\"n\":\"XPPA - Patrol Script Marker\"},{\"t\":3,\"p\":1,\"n\":\"INAM - Idle\"},{\"t\":6,\"p\":1,\"n\":\"Embedded Script\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"SCHR - Basic Script Data\",\"c\":[{\"t\":11,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"RefCount\"},{\"t\":3,\"p\":1,\"n\":\"CompiledSize\"},{\"t\":3,\"p\":1,\"n\":\"VariableCount\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"}]},{\"t\":11,\"p\":1,\"n\":\"SCDA - Compiled Embedded Script\"},{\"t\":2,\"p\":1,\"n\":\"SCTX - Embedded Script Source\"},{\"t\":10,\"p\":1,\"n\":\"Local Variables\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Local Variable\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"SLSD - Local Variable Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Index\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"}]},{\"t\":2,\"p\":1,\"n\":\"SCVR - Name\"}]}]},{\"t\":8,\"p\":1,\"n\":\"References\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"SCRO - Global Reference\"},{\"t\":3,\"p\":1,\"n\":\"SCRV - Local Variable\"}]}]},{\"t\":3,\"p\":1,\"n\":\"TNAM - Topic\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Ownership\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"XOWN - Owner\"},{\"t\":3,\"p\":1,\"n\":\"XRNK - Faction rank\"}]},{\"t\":3,\"p\":1,\"n\":\"XCNT - Count\"},{\"t\":5,\"p\":1,\"n\":\"XRDS - Radius\"},{\"t\":5,\"p\":1,\"n\":\"XHLP - Health\"},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Reflected\\/Refracted By\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"XPWR - Water\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":3,\"p\":1,\"n\":\"Type\"}]}]},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Linked Decals\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"XDCR - Decal\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":11,\"n\":\"Unknown\"}]}]},{\"t\":3,\"p\":1,\"n\":\"XLKR - Linked Reference\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"XCLP - Linked Reference Color\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Link Start Color\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Link End Color\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Activate Parents\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"XAPD - Flags\"},{\"t\":8,\"p\":1,\"n\":\"Activate Parent Refs\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"XAPR - Activate Parent Ref\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":5,\"p\":1,\"n\":\"Delay\"}]}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"XESP - Enable Parent\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":3,\"p\":1,\"n\":\"XEMI - Emittance\"},{\"t\":3,\"p\":1,\"n\":\"XMBR - MultiBound Reference\"},{\"p\":1,\"n\":\"XIBS - Ignored By Sandbox\"},{\"t\":5,\"p\":1,\"n\":\"XSCL - Scale\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DATA - Position\\/Rotation\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Position\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"X\"},{\"t\":5,\"p\":1,\"n\":\"Y\"},{\"t\":5,\"p\":1,\"n\":\"Z\"}]},{\"t\":6,\"p\":1,\"n\":\"Rotation\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"X\"},{\"t\":5,\"p\":1,\"n\":\"Y\"},{\"t\":5,\"p\":1,\"n\":\"Z\"}]}]}]},{\"t\":1,\"p\":1,\"n\":\"PROJ - Projectile\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"X1\"},{\"t\":3,\"p\":1,\"n\":\"Y1\"},{\"t\":3,\"p\":1,\"n\":\"Z1\"},{\"t\":3,\"p\":1,\"n\":\"X2\"},{\"t\":3,\"p\":1,\"n\":\"Y2\"},{\"t\":3,\"p\":1,\"n\":\"Z2\"}]},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"},{\"t\":11,\"n\":\"MODB - Unknown\"},{\"t\":11,\"p\":1,\"n\":\"MODT - Texture Files Hashes\"},{\"t\":7,\"p\":1,\"n\":\"MODS - Alternate Textures\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"3D Name\"},{\"t\":3,\"p\":1,\"n\":\"New Texture\"},{\"t\":3,\"p\":1,\"n\":\"3D Index\"}]}]},{\"t\":3,\"p\":1,\"n\":\"MODD - FaceGen Model Flags\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Destructable\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"DEST - Header\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Health\"},{\"t\":3,\"p\":1,\"n\":\"Count\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":8,\"p\":1,\"n\":\"Stages\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Stage\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"DSTD - Destruction Stage Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Health %\"},{\"t\":3,\"p\":1,\"n\":\"Index\"},{\"t\":3,\"p\":1,\"n\":\"Damage Stage\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":3,\"p\":1,\"n\":\"Self Damage per Second\"},{\"t\":3,\"p\":1,\"n\":\"Explosion\"},{\"t\":3,\"p\":1,\"n\":\"Debris\"},{\"t\":3,\"p\":1,\"n\":\"Debris Count\"}]},{\"t\":6,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"DMDL - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"DMDT - Texture Files Hashes\"}]},{\"p\":1,\"n\":\"DSTF - End Marker\"}]}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DATA - Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":5,\"p\":1,\"n\":\"Gravity\"},{\"t\":5,\"p\":1,\"n\":\"Speed\"},{\"t\":5,\"p\":1,\"n\":\"Range\"},{\"t\":3,\"p\":1,\"n\":\"Light\"},{\"t\":3,\"p\":1,\"n\":\"Muzzle Flash - Light\"},{\"t\":5,\"p\":1,\"n\":\"Tracer Chance\"},{\"t\":5,\"p\":1,\"n\":\"Explosion - Alt. Trigger - Proximity\"},{\"t\":5,\"p\":1,\"n\":\"Explosion - Alt. Trigger - Timer\"},{\"t\":3,\"p\":1,\"n\":\"Explosion\"},{\"t\":3,\"p\":1,\"n\":\"Sound\"},{\"t\":5,\"p\":1,\"n\":\"Muzzle Flash - Duration\"},{\"t\":5,\"p\":1,\"n\":\"Fade Duration\"},{\"t\":5,\"p\":1,\"n\":\"Impact Force\"},{\"t\":3,\"p\":1,\"n\":\"Sound - Countdown\"},{\"t\":3,\"p\":1,\"n\":\"Sound - Disable\"},{\"t\":3,\"p\":1,\"n\":\"Default Weapon Source\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Muzzle Flash Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"NAM1 - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"NAM2 - Texture Files Hashes\"}]},{\"t\":3,\"p\":1,\"n\":\"VNAM - Sound Level\"}]},{\"t\":1,\"p\":1,\"n\":\"PWAT - Placeable Water\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"X1\"},{\"t\":3,\"p\":1,\"n\":\"Y1\"},{\"t\":3,\"p\":1,\"n\":\"Z1\"},{\"t\":3,\"p\":1,\"n\":\"X2\"},{\"t\":3,\"p\":1,\"n\":\"Y2\"},{\"t\":3,\"p\":1,\"n\":\"Z2\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"},{\"t\":11,\"n\":\"MODB - Unknown\"},{\"t\":11,\"p\":1,\"n\":\"MODT - Texture Files Hashes\"},{\"t\":7,\"p\":1,\"n\":\"MODS - Alternate Textures\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"3D Name\"},{\"t\":3,\"p\":1,\"n\":\"New Texture\"},{\"t\":3,\"p\":1,\"n\":\"3D Index\"}]}]},{\"t\":3,\"p\":1,\"n\":\"MODD - FaceGen Model Flags\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DNAM - \",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":3,\"p\":1,\"n\":\"Water\"}]}]},{\"t\":1,\"p\":1,\"n\":\"QUST - Quest\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":3,\"p\":1,\"n\":\"SCRI - Script\"},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Icon\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"ICON - Large Icon filename\"},{\"t\":2,\"p\":1,\"n\":\"MICO - Small Icon filename\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DATA - General\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":3,\"p\":1,\"n\":\"Priority\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":5,\"p\":1,\"n\":\"Quest Delay\"}]},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Conditions\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"CTDA - Condition\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":5,\"p\":1,\"n\":\"Comparison Value - Float\"},{\"t\":3,\"p\":1,\"n\":\"Comparison Value - Global\"},{\"t\":3,\"p\":1,\"n\":\"Function\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":11,\"p\":1,\"n\":\"None\"},{\"t\":3,\"p\":1,\"n\":\"Integer\"},{\"t\":3,\"p\":1,\"n\":\"Variable Name (INVALID)\"},{\"t\":3,\"p\":1,\"n\":\"Sex\"},{\"t\":3,\"p\":1,\"n\":\"Actor Value\"},{\"t\":3,\"p\":1,\"n\":\"Crime Type\"},{\"t\":3,\"p\":1,\"n\":\"Axis\"},{\"t\":3,\"p\":1,\"n\":\"Quest Stage (INVALID)\"},{\"t\":3,\"p\":1,\"n\":\"Misc Stat\"},{\"t\":3,\"p\":1,\"n\":\"Alignment\"},{\"t\":3,\"p\":1,\"n\":\"Equip Type\"},{\"t\":3,\"p\":1,\"n\":\"Form Type\"},{\"t\":3,\"p\":1,\"n\":\"Critical Stage\"},{\"t\":3,\"p\":1,\"n\":\"Object Reference\"},{\"t\":3,\"p\":1,\"n\":\"Inventory Object\"},{\"t\":3,\"p\":1,\"n\":\"Actor\"},{\"t\":3,\"p\":1,\"n\":\"Voice Type\"},{\"t\":3,\"p\":1,\"n\":\"Idle\"},{\"t\":3,\"p\":1,\"n\":\"Form List\"},{\"t\":3,\"p\":1,\"n\":\"Note\"},{\"t\":3,\"p\":1,\"n\":\"Quest\"},{\"t\":3,\"p\":1,\"n\":\"Faction\"},{\"t\":3,\"p\":1,\"n\":\"Weapon\"},{\"t\":3,\"p\":1,\"n\":\"Cell\"},{\"t\":3,\"p\":1,\"n\":\"Class\"},{\"t\":3,\"p\":1,\"n\":\"Race\"},{\"t\":3,\"p\":1,\"n\":\"Actor Base\"},{\"t\":3,\"p\":1,\"n\":\"Global\"},{\"t\":3,\"p\":1,\"n\":\"Weather\"},{\"t\":3,\"p\":1,\"n\":\"Package\"},{\"t\":3,\"p\":1,\"n\":\"Encounter Zone\"},{\"t\":3,\"p\":1,\"n\":\"Perk\"},{\"t\":3,\"p\":1,\"n\":\"Owner\"},{\"t\":3,\"p\":1,\"n\":\"Furniture\"},{\"t\":3,\"p\":1,\"n\":\"Effect Item\"},{\"t\":3,\"p\":1,\"n\":\"Base Effect\"},{\"t\":3,\"p\":1,\"n\":\"Worldspace\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Function\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Param (INVALID)\"},{\"t\":3,\"p\":1,\"n\":\"Creature Type\"},{\"t\":3,\"p\":1,\"n\":\"Menu Mode\"},{\"t\":3,\"p\":1,\"n\":\"Player Action\"},{\"t\":3,\"p\":1,\"n\":\"Body Location\"},{\"t\":3,\"p\":1,\"n\":\"Referenceable Object\"},{\"t\":3,\"p\":1,\"n\":\"Variable Name\"},{\"t\":3,\"p\":1,\"n\":\"Quest Stage\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Function (INVALID)\"},{\"t\":3,\"p\":1,\"n\":\"Weapon List\"},{\"t\":3,\"p\":1,\"n\":\"Target\"},{\"t\":3,\"p\":1,\"n\":\"Target List\"},{\"t\":3,\"p\":1,\"n\":\"Target Part\"},{\"t\":3,\"p\":1,\"n\":\"VATS Action\"},{\"t\":3,\"p\":1,\"n\":\"Critical Effect\"},{\"t\":3,\"p\":1,\"n\":\"Critical Effect List\"},{\"t\":3,\"p\":1,\"n\":\"Weapon Type\"},{\"t\":3,\"p\":1,\"n\":\"Run On\"},{\"t\":3,\"p\":1,\"n\":\"Reference\"}]}]},{\"t\":10,\"p\":1,\"n\":\"Stages\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Stage\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"INDX - Stage Index\"},{\"t\":8,\"p\":1,\"n\":\"Log Entries\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Log Entry\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"QSDT - Stage Flags\"},{\"t\":8,\"p\":1,\"n\":\"Conditions\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"CTDA - Condition\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":5,\"p\":1,\"n\":\"Comparison Value - Float\"},{\"t\":3,\"p\":1,\"n\":\"Comparison Value - Global\"},{\"t\":3,\"p\":1,\"n\":\"Function\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":11,\"p\":1,\"n\":\"None\"},{\"t\":3,\"p\":1,\"n\":\"Integer\"},{\"t\":3,\"p\":1,\"n\":\"Variable Name (INVALID)\"},{\"t\":3,\"p\":1,\"n\":\"Sex\"},{\"t\":3,\"p\":1,\"n\":\"Actor Value\"},{\"t\":3,\"p\":1,\"n\":\"Crime Type\"},{\"t\":3,\"p\":1,\"n\":\"Axis\"},{\"t\":3,\"p\":1,\"n\":\"Quest Stage (INVALID)\"},{\"t\":3,\"p\":1,\"n\":\"Misc Stat\"},{\"t\":3,\"p\":1,\"n\":\"Alignment\"},{\"t\":3,\"p\":1,\"n\":\"Equip Type\"},{\"t\":3,\"p\":1,\"n\":\"Form Type\"},{\"t\":3,\"p\":1,\"n\":\"Critical Stage\"},{\"t\":3,\"p\":1,\"n\":\"Object Reference\"},{\"t\":3,\"p\":1,\"n\":\"Inventory Object\"},{\"t\":3,\"p\":1,\"n\":\"Actor\"},{\"t\":3,\"p\":1,\"n\":\"Voice Type\"},{\"t\":3,\"p\":1,\"n\":\"Idle\"},{\"t\":3,\"p\":1,\"n\":\"Form List\"},{\"t\":3,\"p\":1,\"n\":\"Note\"},{\"t\":3,\"p\":1,\"n\":\"Quest\"},{\"t\":3,\"p\":1,\"n\":\"Faction\"},{\"t\":3,\"p\":1,\"n\":\"Weapon\"},{\"t\":3,\"p\":1,\"n\":\"Cell\"},{\"t\":3,\"p\":1,\"n\":\"Class\"},{\"t\":3,\"p\":1,\"n\":\"Race\"},{\"t\":3,\"p\":1,\"n\":\"Actor Base\"},{\"t\":3,\"p\":1,\"n\":\"Global\"},{\"t\":3,\"p\":1,\"n\":\"Weather\"},{\"t\":3,\"p\":1,\"n\":\"Package\"},{\"t\":3,\"p\":1,\"n\":\"Encounter Zone\"},{\"t\":3,\"p\":1,\"n\":\"Perk\"},{\"t\":3,\"p\":1,\"n\":\"Owner\"},{\"t\":3,\"p\":1,\"n\":\"Furniture\"},{\"t\":3,\"p\":1,\"n\":\"Effect Item\"},{\"t\":3,\"p\":1,\"n\":\"Base Effect\"},{\"t\":3,\"p\":1,\"n\":\"Worldspace\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Function\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Param (INVALID)\"},{\"t\":3,\"p\":1,\"n\":\"Creature Type\"},{\"t\":3,\"p\":1,\"n\":\"Menu Mode\"},{\"t\":3,\"p\":1,\"n\":\"Player Action\"},{\"t\":3,\"p\":1,\"n\":\"Body Location\"},{\"t\":3,\"p\":1,\"n\":\"Referenceable Object\"},{\"t\":3,\"p\":1,\"n\":\"Variable Name\"},{\"t\":3,\"p\":1,\"n\":\"Quest Stage\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Function (INVALID)\"},{\"t\":3,\"p\":1,\"n\":\"Weapon List\"},{\"t\":3,\"p\":1,\"n\":\"Target\"},{\"t\":3,\"p\":1,\"n\":\"Target List\"},{\"t\":3,\"p\":1,\"n\":\"Target Part\"},{\"t\":3,\"p\":1,\"n\":\"VATS Action\"},{\"t\":3,\"p\":1,\"n\":\"Critical Effect\"},{\"t\":3,\"p\":1,\"n\":\"Critical Effect List\"},{\"t\":3,\"p\":1,\"n\":\"Weapon Type\"},{\"t\":3,\"p\":1,\"n\":\"Run On\"},{\"t\":3,\"p\":1,\"n\":\"Reference\"}]}]},{\"t\":2,\"p\":1,\"n\":\"CNAM - Log Entry\"},{\"t\":6,\"p\":1,\"n\":\"Embedded Script\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"SCHR - Basic Script Data\",\"c\":[{\"t\":11,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"RefCount\"},{\"t\":3,\"p\":1,\"n\":\"CompiledSize\"},{\"t\":3,\"p\":1,\"n\":\"VariableCount\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"}]},{\"t\":11,\"p\":1,\"n\":\"SCDA - Compiled Embedded Script\"},{\"t\":2,\"p\":1,\"n\":\"SCTX - Embedded Script Source\"},{\"t\":10,\"p\":1,\"n\":\"Local Variables\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Local Variable\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"SLSD - Local Variable Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Index\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"}]},{\"t\":2,\"p\":1,\"n\":\"SCVR - Name\"}]}]},{\"t\":8,\"p\":1,\"n\":\"References\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"SCRO - Global Reference\"},{\"t\":3,\"p\":1,\"n\":\"SCRV - Local Variable\"}]}]},{\"t\":3,\"p\":1,\"n\":\"NAM0 - Next Quest\"}]}]}]}]},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Objectives\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Objective\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"QOBJ - Objective Index\"},{\"t\":2,\"p\":1,\"n\":\"NNAM - Description\"},{\"t\":8,\"p\":1,\"n\":\"Targets\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Target\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"QSTA - Target\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Target\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":8,\"p\":1,\"n\":\"Conditions\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"CTDA - Condition\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":5,\"p\":1,\"n\":\"Comparison Value - Float\"},{\"t\":3,\"p\":1,\"n\":\"Comparison Value - Global\"},{\"t\":3,\"p\":1,\"n\":\"Function\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":11,\"p\":1,\"n\":\"None\"},{\"t\":3,\"p\":1,\"n\":\"Integer\"},{\"t\":3,\"p\":1,\"n\":\"Variable Name (INVALID)\"},{\"t\":3,\"p\":1,\"n\":\"Sex\"},{\"t\":3,\"p\":1,\"n\":\"Actor Value\"},{\"t\":3,\"p\":1,\"n\":\"Crime Type\"},{\"t\":3,\"p\":1,\"n\":\"Axis\"},{\"t\":3,\"p\":1,\"n\":\"Quest Stage (INVALID)\"},{\"t\":3,\"p\":1,\"n\":\"Misc Stat\"},{\"t\":3,\"p\":1,\"n\":\"Alignment\"},{\"t\":3,\"p\":1,\"n\":\"Equip Type\"},{\"t\":3,\"p\":1,\"n\":\"Form Type\"},{\"t\":3,\"p\":1,\"n\":\"Critical Stage\"},{\"t\":3,\"p\":1,\"n\":\"Object Reference\"},{\"t\":3,\"p\":1,\"n\":\"Inventory Object\"},{\"t\":3,\"p\":1,\"n\":\"Actor\"},{\"t\":3,\"p\":1,\"n\":\"Voice Type\"},{\"t\":3,\"p\":1,\"n\":\"Idle\"},{\"t\":3,\"p\":1,\"n\":\"Form List\"},{\"t\":3,\"p\":1,\"n\":\"Note\"},{\"t\":3,\"p\":1,\"n\":\"Quest\"},{\"t\":3,\"p\":1,\"n\":\"Faction\"},{\"t\":3,\"p\":1,\"n\":\"Weapon\"},{\"t\":3,\"p\":1,\"n\":\"Cell\"},{\"t\":3,\"p\":1,\"n\":\"Class\"},{\"t\":3,\"p\":1,\"n\":\"Race\"},{\"t\":3,\"p\":1,\"n\":\"Actor Base\"},{\"t\":3,\"p\":1,\"n\":\"Global\"},{\"t\":3,\"p\":1,\"n\":\"Weather\"},{\"t\":3,\"p\":1,\"n\":\"Package\"},{\"t\":3,\"p\":1,\"n\":\"Encounter Zone\"},{\"t\":3,\"p\":1,\"n\":\"Perk\"},{\"t\":3,\"p\":1,\"n\":\"Owner\"},{\"t\":3,\"p\":1,\"n\":\"Furniture\"},{\"t\":3,\"p\":1,\"n\":\"Effect Item\"},{\"t\":3,\"p\":1,\"n\":\"Base Effect\"},{\"t\":3,\"p\":1,\"n\":\"Worldspace\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Function\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Param (INVALID)\"},{\"t\":3,\"p\":1,\"n\":\"Creature Type\"},{\"t\":3,\"p\":1,\"n\":\"Menu Mode\"},{\"t\":3,\"p\":1,\"n\":\"Player Action\"},{\"t\":3,\"p\":1,\"n\":\"Body Location\"},{\"t\":3,\"p\":1,\"n\":\"Referenceable Object\"},{\"t\":3,\"p\":1,\"n\":\"Variable Name\"},{\"t\":3,\"p\":1,\"n\":\"Quest Stage\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Function (INVALID)\"},{\"t\":3,\"p\":1,\"n\":\"Weapon List\"},{\"t\":3,\"p\":1,\"n\":\"Target\"},{\"t\":3,\"p\":1,\"n\":\"Target List\"},{\"t\":3,\"p\":1,\"n\":\"Target Part\"},{\"t\":3,\"p\":1,\"n\":\"VATS Action\"},{\"t\":3,\"p\":1,\"n\":\"Critical Effect\"},{\"t\":3,\"p\":1,\"n\":\"Critical Effect List\"},{\"t\":3,\"p\":1,\"n\":\"Weapon Type\"},{\"t\":3,\"p\":1,\"n\":\"Run On\"},{\"t\":3,\"p\":1,\"n\":\"Reference\"}]}]}]}]}]}]}]},{\"t\":1,\"p\":1,\"n\":\"RACE - Race\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":2,\"p\":1,\"n\":\"DESC - Description\"},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Relations\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"XNAM - Relation\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Faction\"},{\"t\":3,\"p\":1,\"n\":\"Modifier\"},{\"t\":3,\"p\":1,\"n\":\"Group Combat Reaction\"}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DATA - \",\"c\":[{\"t\":7,\"p\":1,\"n\":\"Skill Boosts\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Skill Boost\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Skill\"},{\"t\":3,\"p\":1,\"n\":\"Boost\"}]}]},{\"t\":11,\"n\":\"Unused\"},{\"t\":5,\"p\":1,\"n\":\"Male Height\"},{\"t\":5,\"p\":1,\"n\":\"Female Height\"},{\"t\":5,\"p\":1,\"n\":\"Male Weight\"},{\"t\":5,\"p\":1,\"n\":\"Female Weight\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"}]},{\"t\":3,\"p\":1,\"n\":\"ONAM - Older\"},{\"t\":3,\"p\":1,\"n\":\"YNAM - Younger\"},{\"p\":1,\"n\":\"NAM2 - Unknown Marker\"},{\"t\":7,\"s\":1,\"p\":1,\"n\":\"VTCK - Voices\",\"d\":1,\"c\":[{\"t\":3,\"p\":1,\"n\":\"Voice\"}]},{\"t\":7,\"s\":1,\"p\":1,\"n\":\"DNAM - Default Hair Styles\",\"d\":1,\"c\":[{\"t\":3,\"p\":1,\"n\":\"Default Hair Style\"}]},{\"t\":7,\"s\":1,\"p\":1,\"n\":\"CNAM - Default Hair Colors\",\"d\":1,\"c\":[{\"t\":3,\"p\":1,\"n\":\"Default Hair Color\"}]},{\"t\":5,\"p\":1,\"n\":\"PNAM - FaceGen - Main clamp\"},{\"t\":5,\"p\":1,\"n\":\"UNAM - FaceGen - Face clamp\"},{\"t\":11,\"p\":1,\"n\":\"ATTR - Unused\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Head Data\",\"c\":[{\"p\":1,\"n\":\"NAM0 - Head Data Marker\"},{\"t\":6,\"p\":1,\"n\":\"Male Head Data\",\"c\":[{\"p\":1,\"n\":\"MNAM - Male Data Marker\"},{\"t\":10,\"p\":1,\"n\":\"Parts\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Part\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"INDX - Index\"},{\"t\":6,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"},{\"t\":11,\"n\":\"MODB - Unknown\"},{\"t\":11,\"p\":1,\"n\":\"MODT - Texture Files Hashes\"},{\"t\":7,\"p\":1,\"n\":\"MODS - Alternate Textures\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"3D Name\"},{\"t\":3,\"p\":1,\"n\":\"New Texture\"},{\"t\":3,\"p\":1,\"n\":\"3D Index\"}]}]},{\"t\":3,\"p\":1,\"n\":\"MODD - FaceGen Model Flags\"}]},{\"t\":6,\"p\":1,\"n\":\"Icon\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"ICON - Large Icon filename\"},{\"t\":2,\"p\":1,\"n\":\"MICO - Small Icon filename\"}]}]}]}]},{\"t\":6,\"p\":1,\"n\":\"Female Head Data\",\"c\":[{\"p\":1,\"n\":\"FNAM - Female Data Marker\"},{\"t\":10,\"p\":1,\"n\":\"Parts\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Part\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"INDX - Index\"},{\"t\":6,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"},{\"t\":11,\"n\":\"MODB - Unknown\"},{\"t\":11,\"p\":1,\"n\":\"MODT - Texture Files Hashes\"},{\"t\":7,\"p\":1,\"n\":\"MODS - Alternate Textures\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"3D Name\"},{\"t\":3,\"p\":1,\"n\":\"New Texture\"},{\"t\":3,\"p\":1,\"n\":\"3D Index\"}]}]},{\"t\":3,\"p\":1,\"n\":\"MODD - FaceGen Model Flags\"}]},{\"t\":6,\"p\":1,\"n\":\"Icon\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"ICON - Large Icon filename\"},{\"t\":2,\"p\":1,\"n\":\"MICO - Small Icon filename\"}]}]}]}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Body Data\",\"c\":[{\"p\":1,\"n\":\"NAM1 - Body Data Marker\"},{\"t\":6,\"p\":1,\"n\":\"Male Body Data\",\"c\":[{\"p\":1,\"n\":\"MNAM - Male Data Marker\"},{\"t\":10,\"p\":1,\"n\":\"Parts\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Part\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"INDX - Index\"},{\"t\":6,\"p\":1,\"n\":\"Icon\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"ICON - Large Icon filename\"},{\"t\":2,\"p\":1,\"n\":\"MICO - Small Icon filename\"}]},{\"t\":6,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"},{\"t\":11,\"n\":\"MODB - Unknown\"},{\"t\":11,\"p\":1,\"n\":\"MODT - Texture Files Hashes\"},{\"t\":7,\"p\":1,\"n\":\"MODS - Alternate Textures\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"3D Name\"},{\"t\":3,\"p\":1,\"n\":\"New Texture\"},{\"t\":3,\"p\":1,\"n\":\"3D Index\"}]}]},{\"t\":3,\"p\":1,\"n\":\"MODD - FaceGen Model Flags\"}]}]}]}]},{\"t\":6,\"p\":1,\"n\":\"Female Body Data\",\"c\":[{\"p\":1,\"n\":\"FNAM - Female Data Marker\"},{\"t\":10,\"p\":1,\"n\":\"Parts\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Part\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"INDX - Index\"},{\"t\":6,\"p\":1,\"n\":\"Icon\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"ICON - Large Icon filename\"},{\"t\":2,\"p\":1,\"n\":\"MICO - Small Icon filename\"}]},{\"t\":6,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"},{\"t\":11,\"n\":\"MODB - Unknown\"},{\"t\":11,\"p\":1,\"n\":\"MODT - Texture Files Hashes\"},{\"t\":7,\"p\":1,\"n\":\"MODS - Alternate Textures\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"3D Name\"},{\"t\":3,\"p\":1,\"n\":\"New Texture\"},{\"t\":3,\"p\":1,\"n\":\"3D Index\"}]}]},{\"t\":3,\"p\":1,\"n\":\"MODD - FaceGen Model Flags\"}]}]}]}]}]},{\"t\":7,\"s\":1,\"p\":1,\"n\":\"HNAM - Hairs\",\"d\":1,\"c\":[{\"t\":3,\"p\":1,\"n\":\"Hair\"}]},{\"t\":7,\"s\":1,\"p\":1,\"n\":\"ENAM - Eyes\",\"d\":1,\"c\":[{\"t\":3,\"p\":1,\"n\":\"Eye\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"FaceGen Data\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Male FaceGen Data\",\"c\":[{\"p\":1,\"n\":\"MNAM - Male Data Marker\"},{\"t\":6,\"p\":1,\"n\":\"FaceGen Data\",\"c\":[{\"t\":11,\"p\":1,\"n\":\"FGGS - FaceGen Geometry-Symmetric\"},{\"t\":11,\"p\":1,\"n\":\"FGGA - FaceGen Geometry-Asymmetric\"},{\"t\":11,\"p\":1,\"n\":\"FGTS - FaceGen Texture-Symmetric\"}]},{\"t\":11,\"n\":\"SNAM - Unknown\"}]},{\"t\":6,\"p\":1,\"n\":\"Female FaceGen Data\",\"c\":[{\"p\":1,\"n\":\"FNAM - Female Data Marker\"},{\"t\":6,\"p\":1,\"n\":\"FaceGen Data\",\"c\":[{\"t\":11,\"p\":1,\"n\":\"FGGS - FaceGen Geometry-Symmetric\"},{\"t\":11,\"p\":1,\"n\":\"FGGA - FaceGen Geometry-Asymmetric\"},{\"t\":11,\"p\":1,\"n\":\"FGTS - FaceGen Texture-Symmetric\"}]},{\"t\":11,\"n\":\"SNAM - Unknown\"}]}]}]},{\"t\":1,\"p\":1,\"n\":\"RADS - Radiation Stage\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DATA - \",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Trigger Threshold\"},{\"t\":3,\"p\":1,\"n\":\"Actor Effect\"}]}]},{\"t\":1,\"p\":1,\"n\":\"REFR - Placed Object\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":11,\"n\":\"RCLR - Unused\"},{\"t\":3,\"p\":1,\"n\":\"NAME - Base\"},{\"t\":3,\"p\":1,\"n\":\"XEZN - Encounter Zone\"},{\"t\":11,\"n\":\"XRGD - Ragdoll Data\"},{\"t\":11,\"n\":\"XRGB - Ragdoll Biped Data\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"XPRM - Primitive\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Bounds\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"X\"},{\"t\":5,\"p\":1,\"n\":\"Y\"},{\"t\":5,\"p\":1,\"n\":\"Z\"}]},{\"t\":6,\"p\":1,\"n\":\"Color\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Red\"},{\"t\":5,\"p\":1,\"n\":\"Green\"},{\"t\":5,\"p\":1,\"n\":\"Blue\"}]},{\"t\":5,\"n\":\"Unknown\"},{\"t\":3,\"p\":1,\"n\":\"Type\"}]},{\"t\":3,\"p\":1,\"n\":\"XTRI - Collision Layer\"},{\"p\":1,\"n\":\"XMBP - MultiBound Primitive Marker\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"XMBO - Bound Half Extents\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"X\"},{\"t\":5,\"p\":1,\"n\":\"Y\"},{\"t\":5,\"p\":1,\"n\":\"Z\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"XTEL - Teleport Destination\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Door\"},{\"t\":6,\"p\":1,\"n\":\"Position\\/Rotation\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Position\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"X\"},{\"t\":5,\"p\":1,\"n\":\"Y\"},{\"t\":5,\"p\":1,\"n\":\"Z\"}]},{\"t\":6,\"p\":1,\"n\":\"Rotation\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"X\"},{\"t\":5,\"p\":1,\"n\":\"Y\"},{\"t\":5,\"p\":1,\"n\":\"Z\"}]}]},{\"t\":3,\"p\":1,\"n\":\"Flags\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Map Marker\",\"c\":[{\"p\":1,\"n\":\"XMRK - Map Marker Data\"},{\"t\":3,\"p\":1,\"n\":\"FNAM - Flags\"},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":6,\"p\":1,\"n\":\"TNAM - \",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":11,\"n\":\"Unused\"}]}]},{\"t\":3,\"p\":1,\"n\":\"XSRF - Special Rendering Flags\"},{\"t\":11,\"n\":\"XSRD - Special Rendering Data\"},{\"t\":3,\"p\":1,\"n\":\"XTRG - Target\"},{\"t\":3,\"p\":1,\"n\":\"XLCM - Level Modifier\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Patrol Data\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"XPRD - Idle Time\"},{\"p\":1,\"n\":\"XPPA - Patrol Script Marker\"},{\"t\":3,\"p\":1,\"n\":\"INAM - Idle\"},{\"t\":6,\"p\":1,\"n\":\"Embedded Script\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"SCHR - Basic Script Data\",\"c\":[{\"t\":11,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"RefCount\"},{\"t\":3,\"p\":1,\"n\":\"CompiledSize\"},{\"t\":3,\"p\":1,\"n\":\"VariableCount\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"}]},{\"t\":11,\"p\":1,\"n\":\"SCDA - Compiled Embedded Script\"},{\"t\":2,\"p\":1,\"n\":\"SCTX - Embedded Script Source\"},{\"t\":10,\"p\":1,\"n\":\"Local Variables\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Local Variable\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"SLSD - Local Variable Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Index\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"}]},{\"t\":2,\"p\":1,\"n\":\"SCVR - Name\"}]}]},{\"t\":8,\"p\":1,\"n\":\"References\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"SCRO - Global Reference\"},{\"t\":3,\"p\":1,\"n\":\"SCRV - Local Variable\"}]}]},{\"t\":3,\"p\":1,\"n\":\"TNAM - Topic\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"XRDO - Radio Data\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Range Radius\"},{\"t\":3,\"p\":1,\"n\":\"Broadcast Range Type\"},{\"t\":5,\"p\":1,\"n\":\"Static Percentage\"},{\"t\":3,\"p\":1,\"n\":\"Position Reference\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Ownership\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"XOWN - Owner\"},{\"t\":3,\"p\":1,\"n\":\"XRNK - Faction rank\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"XLOC - Lock Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Level\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Key\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":3,\"p\":1,\"n\":\"XCNT - Count\"},{\"t\":5,\"p\":1,\"n\":\"XRDS - Radius\"},{\"t\":5,\"p\":1,\"n\":\"XHLP - Health\"},{\"t\":5,\"p\":1,\"n\":\"XRAD - Radiation\"},{\"t\":5,\"p\":1,\"n\":\"XCHG - Charge\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Ammo\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"XAMT - Type\"},{\"t\":3,\"p\":1,\"n\":\"XAMC - Count\"}]},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Reflected\\/Refracted By\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"XPWR - Water\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":3,\"p\":1,\"n\":\"Type\"}]}]},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Lit Water\",\"d\":1,\"c\":[{\"t\":3,\"p\":1,\"n\":\"XLTW - Water\"}]},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Linked Decals\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"XDCR - Decal\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":11,\"n\":\"Unknown\"}]}]},{\"t\":3,\"p\":1,\"n\":\"XLKR - Linked Reference\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"XCLP - Linked Reference Color\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Link Start Color\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Link End Color\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Activate Parents\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"XAPD - Flags\"},{\"t\":8,\"p\":1,\"n\":\"Activate Parent Refs\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"XAPR - Activate Parent Ref\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":5,\"p\":1,\"n\":\"Delay\"}]}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"XESP - Enable Parent\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":3,\"p\":1,\"n\":\"XEMI - Emittance\"},{\"t\":3,\"p\":1,\"n\":\"XMBR - MultiBound Reference\"},{\"t\":3,\"p\":1,\"n\":\"XACT - Action Flag\"},{\"p\":1,\"n\":\"ONAM - Open by Default\"},{\"p\":1,\"n\":\"XIBS - Ignored By Sandbox\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"XNDP - Navigation Door Link\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Navigation Mesh\"},{\"t\":3,\"p\":1,\"n\":\"Teleport Marker Triangle\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":7,\"p\":1,\"n\":\"XPOD - Portal Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Room\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"XPTL - Portal Data\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Size\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Width\"},{\"t\":5,\"p\":1,\"n\":\"Height\"}]},{\"t\":6,\"p\":1,\"n\":\"Position\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"X\"},{\"t\":5,\"p\":1,\"n\":\"Y\"},{\"t\":5,\"p\":1,\"n\":\"Z\"}]},{\"t\":6,\"p\":1,\"n\":\"Rotation (Quaternion?)\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"q1\"},{\"t\":5,\"p\":1,\"n\":\"q2\"},{\"t\":5,\"p\":1,\"n\":\"q3\"},{\"t\":5,\"p\":1,\"n\":\"q4\"}]}]},{\"t\":3,\"p\":1,\"n\":\"XSED - SpeedTree Seed\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Room Data\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"XRMR - Header\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Linked Rooms Count\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":8,\"p\":1,\"n\":\"Linked Rooms\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"XLRM - Linked Room\"}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"XOCP - Occlusion Plane Data\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Size\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Width\"},{\"t\":5,\"p\":1,\"n\":\"Height\"}]},{\"t\":6,\"p\":1,\"n\":\"Position\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"X\"},{\"t\":5,\"p\":1,\"n\":\"Y\"},{\"t\":5,\"p\":1,\"n\":\"Z\"}]},{\"t\":6,\"p\":1,\"n\":\"Rotation (Quaternion?)\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"q1\"},{\"t\":5,\"p\":1,\"n\":\"q2\"},{\"t\":5,\"p\":1,\"n\":\"q3\"},{\"t\":5,\"p\":1,\"n\":\"q4\"}]}]},{\"t\":7,\"p\":1,\"n\":\"XORD - Linked Occlusion Planes\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Plane\"}]},{\"t\":7,\"n\":\"XLOD - Distant LOD Data\",\"c\":[{\"t\":5,\"n\":\"Unknown\"}]},{\"t\":5,\"p\":1,\"n\":\"XSCL - Scale\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DATA - Position\\/Rotation\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Position\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"X\"},{\"t\":5,\"p\":1,\"n\":\"Y\"},{\"t\":5,\"p\":1,\"n\":\"Z\"}]},{\"t\":6,\"p\":1,\"n\":\"Rotation\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"X\"},{\"t\":5,\"p\":1,\"n\":\"Y\"},{\"t\":5,\"p\":1,\"n\":\"Z\"}]}]}]},{\"t\":1,\"p\":1,\"n\":\"REGN - Region\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Icon\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"ICON - Large Icon filename\"},{\"t\":2,\"p\":1,\"n\":\"MICO - Small Icon filename\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"RCLR - Map Color\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":3,\"p\":1,\"n\":\"WNAM - Worldspace\"},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Region Areas\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Region Area\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"RPLI - Edge Fall-off\"},{\"t\":7,\"p\":1,\"n\":\"RPLD - Region Point List Data\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Point\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"X\"},{\"t\":5,\"p\":1,\"n\":\"Y\"}]}]}]}]},{\"t\":10,\"p\":1,\"n\":\"Region Data Entries\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Region Data Entry\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"RDAT - Data Header\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":3,\"p\":1,\"n\":\"Priority\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":7,\"p\":1,\"n\":\"RDOT - Objects\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Object\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Object\"},{\"t\":3,\"p\":1,\"n\":\"Parent Index\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":5,\"p\":1,\"n\":\"Density\"},{\"t\":3,\"p\":1,\"n\":\"Clustering\"},{\"t\":3,\"p\":1,\"n\":\"Min Slope\"},{\"t\":3,\"p\":1,\"n\":\"Max Slope\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":3,\"p\":1,\"n\":\"Radius wrt Parent\"},{\"t\":3,\"p\":1,\"n\":\"Radius\"},{\"t\":5,\"p\":1,\"n\":\"Min Height\"},{\"t\":5,\"p\":1,\"n\":\"Max Height\"},{\"t\":5,\"p\":1,\"n\":\"Sink\"},{\"t\":5,\"p\":1,\"n\":\"Sink Variance\"},{\"t\":5,\"p\":1,\"n\":\"Size Variance\"},{\"t\":6,\"p\":1,\"n\":\"Angle Variance\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"X\"},{\"t\":3,\"p\":1,\"n\":\"Y\"},{\"t\":3,\"p\":1,\"n\":\"Z\"}]},{\"t\":11,\"n\":\"Unknown\"}]}]},{\"t\":2,\"p\":1,\"n\":\"RDMP - Map Name\"},{\"t\":7,\"p\":1,\"n\":\"RDGS - Grasses\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Grass\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Grass\"},{\"t\":11,\"n\":\"Unknown\"}]}]},{\"t\":3,\"p\":1,\"n\":\"RDMD - Music Type\"},{\"t\":3,\"p\":1,\"n\":\"RDMO - Music\"},{\"t\":7,\"p\":1,\"n\":\"RDSD - Sounds\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Sound\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Sound\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":3,\"p\":1,\"n\":\"Chance\"}]}]},{\"t\":7,\"p\":1,\"n\":\"RDWT - Weather Types\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Weather Type\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Weather\"},{\"t\":3,\"p\":1,\"n\":\"Chance\"},{\"t\":3,\"p\":1,\"n\":\"Global\"}]}]}]}]}]},{\"t\":1,\"p\":1,\"n\":\"RGDL - Ragdoll\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":3,\"p\":1,\"n\":\"NVER - Version\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DATA - General Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Dynamic Bone Count\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":6,\"p\":1,\"n\":\"Enabled\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Feedback\"},{\"t\":3,\"p\":1,\"n\":\"Foot IK (broken, don't use)\"},{\"t\":3,\"p\":1,\"n\":\"Look IK (broken, don't use)\"},{\"t\":3,\"p\":1,\"n\":\"Grab IK (broken, don't use)\"},{\"t\":3,\"p\":1,\"n\":\"Pose Matching\"}]}]},{\"t\":3,\"p\":1,\"n\":\"XNAM - Actor Base\"},{\"t\":3,\"p\":1,\"n\":\"TNAM - Body Part Data\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"RAFD - Feedback Data\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Dynamic\\/Keyframe Blend Amount\"},{\"t\":5,\"p\":1,\"n\":\"Hierarchy Gain\"},{\"t\":5,\"p\":1,\"n\":\"Position Gain\"},{\"t\":5,\"p\":1,\"n\":\"Velocity Gain\"},{\"t\":5,\"p\":1,\"n\":\"Acceleration Gain\"},{\"t\":5,\"p\":1,\"n\":\"Snap Gain\"},{\"t\":5,\"p\":1,\"n\":\"Velocity Damping\"},{\"t\":6,\"p\":1,\"n\":\"Snap Max Settings\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Linear Velocity\"},{\"t\":5,\"p\":1,\"n\":\"Angular Velocity\"},{\"t\":5,\"p\":1,\"n\":\"Linear Distance\"},{\"t\":5,\"p\":1,\"n\":\"Angular Distance\"}]},{\"t\":6,\"p\":1,\"n\":\"Position Max Velocity\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Linear\"},{\"t\":5,\"p\":1,\"n\":\"Angular\"}]}]},{\"t\":7,\"p\":1,\"n\":\"RAFB - Feedback Dynamic Bones\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Bone\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"RAPS - Pose Matching Data\",\"c\":[{\"t\":7,\"p\":1,\"n\":\"Match Bones\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Bone\"}]},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":5,\"p\":1,\"n\":\"Motors Strength\"},{\"t\":5,\"p\":1,\"n\":\"Pose Activation Delay Time\"},{\"t\":5,\"p\":1,\"n\":\"Match Error Allowance\"},{\"t\":5,\"p\":1,\"n\":\"Displacement To Disable\"}]},{\"t\":2,\"p\":1,\"n\":\"ANAM - Death Pose\"}]},{\"t\":1,\"p\":1,\"n\":\"SCOL - Static Collection\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"X1\"},{\"t\":3,\"p\":1,\"n\":\"Y1\"},{\"t\":3,\"p\":1,\"n\":\"Z1\"},{\"t\":3,\"p\":1,\"n\":\"X2\"},{\"t\":3,\"p\":1,\"n\":\"Y2\"},{\"t\":3,\"p\":1,\"n\":\"Z2\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"},{\"t\":11,\"n\":\"MODB - Unknown\"},{\"t\":11,\"p\":1,\"n\":\"MODT - Texture Files Hashes\"},{\"t\":7,\"p\":1,\"n\":\"MODS - Alternate Textures\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"3D Name\"},{\"t\":3,\"p\":1,\"n\":\"New Texture\"},{\"t\":3,\"p\":1,\"n\":\"3D Index\"}]}]},{\"t\":3,\"p\":1,\"n\":\"MODD - FaceGen Model Flags\"}]},{\"t\":10,\"p\":1,\"n\":\"Parts\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Part\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"ONAM - Static\"},{\"t\":7,\"p\":1,\"n\":\"DATA - Placements\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Placement\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Position\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"X\"},{\"t\":5,\"p\":1,\"n\":\"Y\"},{\"t\":5,\"p\":1,\"n\":\"Z\"}]},{\"t\":6,\"p\":1,\"n\":\"Rotation\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"X\"},{\"t\":5,\"p\":1,\"n\":\"Y\"},{\"t\":5,\"p\":1,\"n\":\"Z\"}]},{\"t\":5,\"p\":1,\"n\":\"Scale\"}]}]}]}]}]},{\"t\":1,\"p\":1,\"n\":\"SCPT - Script\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"SCHR - Basic Script Data\",\"c\":[{\"t\":11,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"RefCount\"},{\"t\":3,\"p\":1,\"n\":\"CompiledSize\"},{\"t\":3,\"p\":1,\"n\":\"VariableCount\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"}]},{\"t\":11,\"n\":\"SCDA - Compiled Script\"},{\"t\":2,\"p\":1,\"n\":\"SCTX - Script Source\"},{\"t\":10,\"p\":1,\"n\":\"Local Variables\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Local Variable\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"SLSD - Local Variable Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Index\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"}]},{\"t\":2,\"p\":1,\"n\":\"SCVR - Name\"}]}]},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"References\",\"d\":1,\"c\":[{\"t\":3,\"p\":1,\"n\":\"SCRO - Global Reference\"},{\"t\":3,\"p\":1,\"n\":\"SCRV - Local Variable\"}]}]},{\"t\":1,\"p\":1,\"n\":\"SOUN - Sound\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"X1\"},{\"t\":3,\"p\":1,\"n\":\"Y1\"},{\"t\":3,\"p\":1,\"n\":\"Z1\"},{\"t\":3,\"p\":1,\"n\":\"X2\"},{\"t\":3,\"p\":1,\"n\":\"Y2\"},{\"t\":3,\"p\":1,\"n\":\"Z2\"}]},{\"t\":2,\"p\":1,\"n\":\"FNAM - Sound Filename\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"SNDD - Sound Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Minimum Attentuation Distance\"},{\"t\":3,\"p\":1,\"n\":\"Maximum Attentuation Distance\"},{\"t\":3,\"p\":1,\"n\":\"Frequency Adjustment %\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":3,\"p\":1,\"n\":\"Static attentuation cdB\"},{\"t\":3,\"p\":1,\"n\":\"Stop time \"},{\"t\":3,\"p\":1,\"n\":\"Start time \"},{\"t\":7,\"p\":1,\"n\":\"Attenuation Curve\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Point\"}]},{\"t\":3,\"p\":1,\"n\":\"Reverb Attenuation Control\"},{\"t\":3,\"p\":1,\"n\":\"Priority\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"SNDX - Sound Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Minimum attentuation distance\"},{\"t\":3,\"p\":1,\"n\":\"Maximum attentuation distance\"},{\"t\":3,\"p\":1,\"n\":\"Frequency adjustment %\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":3,\"p\":1,\"n\":\"Static attentuation cdB\"},{\"t\":3,\"p\":1,\"n\":\"Stop time \"},{\"t\":3,\"p\":1,\"n\":\"Start time \"}]},{\"t\":7,\"p\":1,\"n\":\"ANAM - Attenuation Curve\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Point\"}]},{\"t\":3,\"p\":1,\"n\":\"GNAM - Reverb Attenuation Control\"},{\"t\":3,\"p\":1,\"n\":\"HNAM - Priority\"}]},{\"t\":1,\"p\":1,\"n\":\"SPEL - Actor Effect\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"SPIT - \",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"n\":\"Cost (Unused)\"},{\"t\":3,\"n\":\"Level (Unused)\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Effects\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Effect\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"EFID - Base Effect\"},{\"t\":6,\"p\":1,\"n\":\"EFIT - \",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Magnitude\"},{\"t\":3,\"p\":1,\"n\":\"Area\"},{\"t\":3,\"p\":1,\"n\":\"Duration\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Actor Value\"}]},{\"t\":8,\"p\":1,\"n\":\"Conditions\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"CTDA - Condition\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":5,\"p\":1,\"n\":\"Comparison Value - Float\"},{\"t\":3,\"p\":1,\"n\":\"Comparison Value - Global\"},{\"t\":3,\"p\":1,\"n\":\"Function\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":11,\"p\":1,\"n\":\"None\"},{\"t\":3,\"p\":1,\"n\":\"Integer\"},{\"t\":3,\"p\":1,\"n\":\"Variable Name (INVALID)\"},{\"t\":3,\"p\":1,\"n\":\"Sex\"},{\"t\":3,\"p\":1,\"n\":\"Actor Value\"},{\"t\":3,\"p\":1,\"n\":\"Crime Type\"},{\"t\":3,\"p\":1,\"n\":\"Axis\"},{\"t\":3,\"p\":1,\"n\":\"Quest Stage (INVALID)\"},{\"t\":3,\"p\":1,\"n\":\"Misc Stat\"},{\"t\":3,\"p\":1,\"n\":\"Alignment\"},{\"t\":3,\"p\":1,\"n\":\"Equip Type\"},{\"t\":3,\"p\":1,\"n\":\"Form Type\"},{\"t\":3,\"p\":1,\"n\":\"Critical Stage\"},{\"t\":3,\"p\":1,\"n\":\"Object Reference\"},{\"t\":3,\"p\":1,\"n\":\"Inventory Object\"},{\"t\":3,\"p\":1,\"n\":\"Actor\"},{\"t\":3,\"p\":1,\"n\":\"Voice Type\"},{\"t\":3,\"p\":1,\"n\":\"Idle\"},{\"t\":3,\"p\":1,\"n\":\"Form List\"},{\"t\":3,\"p\":1,\"n\":\"Note\"},{\"t\":3,\"p\":1,\"n\":\"Quest\"},{\"t\":3,\"p\":1,\"n\":\"Faction\"},{\"t\":3,\"p\":1,\"n\":\"Weapon\"},{\"t\":3,\"p\":1,\"n\":\"Cell\"},{\"t\":3,\"p\":1,\"n\":\"Class\"},{\"t\":3,\"p\":1,\"n\":\"Race\"},{\"t\":3,\"p\":1,\"n\":\"Actor Base\"},{\"t\":3,\"p\":1,\"n\":\"Global\"},{\"t\":3,\"p\":1,\"n\":\"Weather\"},{\"t\":3,\"p\":1,\"n\":\"Package\"},{\"t\":3,\"p\":1,\"n\":\"Encounter Zone\"},{\"t\":3,\"p\":1,\"n\":\"Perk\"},{\"t\":3,\"p\":1,\"n\":\"Owner\"},{\"t\":3,\"p\":1,\"n\":\"Furniture\"},{\"t\":3,\"p\":1,\"n\":\"Effect Item\"},{\"t\":3,\"p\":1,\"n\":\"Base Effect\"},{\"t\":3,\"p\":1,\"n\":\"Worldspace\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Function\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Param (INVALID)\"},{\"t\":3,\"p\":1,\"n\":\"Creature Type\"},{\"t\":3,\"p\":1,\"n\":\"Menu Mode\"},{\"t\":3,\"p\":1,\"n\":\"Player Action\"},{\"t\":3,\"p\":1,\"n\":\"Body Location\"},{\"t\":3,\"p\":1,\"n\":\"Referenceable Object\"},{\"t\":3,\"p\":1,\"n\":\"Variable Name\"},{\"t\":3,\"p\":1,\"n\":\"Quest Stage\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Function (INVALID)\"},{\"t\":3,\"p\":1,\"n\":\"Weapon List\"},{\"t\":3,\"p\":1,\"n\":\"Target\"},{\"t\":3,\"p\":1,\"n\":\"Target List\"},{\"t\":3,\"p\":1,\"n\":\"Target Part\"},{\"t\":3,\"p\":1,\"n\":\"VATS Action\"},{\"t\":3,\"p\":1,\"n\":\"Critical Effect\"},{\"t\":3,\"p\":1,\"n\":\"Critical Effect List\"},{\"t\":3,\"p\":1,\"n\":\"Weapon Type\"},{\"t\":3,\"p\":1,\"n\":\"Run On\"},{\"t\":3,\"p\":1,\"n\":\"Reference\"}]}]}]}]}]},{\"t\":1,\"p\":1,\"n\":\"STAT - Static\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"X1\"},{\"t\":3,\"p\":1,\"n\":\"Y1\"},{\"t\":3,\"p\":1,\"n\":\"Z1\"},{\"t\":3,\"p\":1,\"n\":\"X2\"},{\"t\":3,\"p\":1,\"n\":\"Y2\"},{\"t\":3,\"p\":1,\"n\":\"Z2\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"},{\"t\":11,\"n\":\"MODB - Unknown\"},{\"t\":11,\"p\":1,\"n\":\"MODT - Texture Files Hashes\"},{\"t\":7,\"p\":1,\"n\":\"MODS - Alternate Textures\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"3D Name\"},{\"t\":3,\"p\":1,\"n\":\"New Texture\"},{\"t\":3,\"p\":1,\"n\":\"3D Index\"}]}]},{\"t\":3,\"p\":1,\"n\":\"MODD - FaceGen Model Flags\"}]}]},{\"t\":1,\"p\":1,\"n\":\"TACT - Talking Activator\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"X1\"},{\"t\":3,\"p\":1,\"n\":\"Y1\"},{\"t\":3,\"p\":1,\"n\":\"Z1\"},{\"t\":3,\"p\":1,\"n\":\"X2\"},{\"t\":3,\"p\":1,\"n\":\"Y2\"},{\"t\":3,\"p\":1,\"n\":\"Z2\"}]},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"},{\"t\":11,\"n\":\"MODB - Unknown\"},{\"t\":11,\"p\":1,\"n\":\"MODT - Texture Files Hashes\"},{\"t\":7,\"p\":1,\"n\":\"MODS - Alternate Textures\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"3D Name\"},{\"t\":3,\"p\":1,\"n\":\"New Texture\"},{\"t\":3,\"p\":1,\"n\":\"3D Index\"}]}]},{\"t\":3,\"p\":1,\"n\":\"MODD - FaceGen Model Flags\"}]},{\"t\":3,\"p\":1,\"n\":\"SCRI - Script\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Destructable\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"DEST - Header\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Health\"},{\"t\":3,\"p\":1,\"n\":\"Count\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":8,\"p\":1,\"n\":\"Stages\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Stage\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"DSTD - Destruction Stage Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Health %\"},{\"t\":3,\"p\":1,\"n\":\"Index\"},{\"t\":3,\"p\":1,\"n\":\"Damage Stage\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":3,\"p\":1,\"n\":\"Self Damage per Second\"},{\"t\":3,\"p\":1,\"n\":\"Explosion\"},{\"t\":3,\"p\":1,\"n\":\"Debris\"},{\"t\":3,\"p\":1,\"n\":\"Debris Count\"}]},{\"t\":6,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"DMDL - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"DMDT - Texture Files Hashes\"}]},{\"p\":1,\"n\":\"DSTF - End Marker\"}]}]}]},{\"t\":3,\"p\":1,\"n\":\"SNAM - Sound\"},{\"t\":3,\"p\":1,\"n\":\"VNAM - Voice Type\"}]},{\"t\":1,\"p\":1,\"n\":\"TERM - Terminal\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"X1\"},{\"t\":3,\"p\":1,\"n\":\"Y1\"},{\"t\":3,\"p\":1,\"n\":\"Z1\"},{\"t\":3,\"p\":1,\"n\":\"X2\"},{\"t\":3,\"p\":1,\"n\":\"Y2\"},{\"t\":3,\"p\":1,\"n\":\"Z2\"}]},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"},{\"t\":11,\"n\":\"MODB - Unknown\"},{\"t\":11,\"p\":1,\"n\":\"MODT - Texture Files Hashes\"},{\"t\":7,\"p\":1,\"n\":\"MODS - Alternate Textures\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"3D Name\"},{\"t\":3,\"p\":1,\"n\":\"New Texture\"},{\"t\":3,\"p\":1,\"n\":\"3D Index\"}]}]},{\"t\":3,\"p\":1,\"n\":\"MODD - FaceGen Model Flags\"}]},{\"t\":3,\"p\":1,\"n\":\"SCRI - Script\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Destructable\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"DEST - Header\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Health\"},{\"t\":3,\"p\":1,\"n\":\"Count\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":8,\"p\":1,\"n\":\"Stages\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Stage\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"DSTD - Destruction Stage Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Health %\"},{\"t\":3,\"p\":1,\"n\":\"Index\"},{\"t\":3,\"p\":1,\"n\":\"Damage Stage\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":3,\"p\":1,\"n\":\"Self Damage per Second\"},{\"t\":3,\"p\":1,\"n\":\"Explosion\"},{\"t\":3,\"p\":1,\"n\":\"Debris\"},{\"t\":3,\"p\":1,\"n\":\"Debris Count\"}]},{\"t\":6,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"DMDL - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"DMDT - Texture Files Hashes\"}]},{\"p\":1,\"n\":\"DSTF - End Marker\"}]}]}]},{\"t\":2,\"p\":1,\"n\":\"DESC - Description\"},{\"t\":3,\"p\":1,\"n\":\"SNAM - Sound - Looping\"},{\"t\":3,\"p\":1,\"n\":\"PNAM - Password Note\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DNAM - \",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Base Hacking Difficulty\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":3,\"p\":1,\"n\":\"ServerType\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Menu Items\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Menu Item\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"ITXT - Item Text\"},{\"t\":2,\"p\":1,\"n\":\"RNAM - Result Text\"},{\"t\":3,\"p\":1,\"n\":\"ANAM - Flags\"},{\"t\":3,\"p\":1,\"n\":\"INAM - Display Note\"},{\"t\":3,\"p\":1,\"n\":\"TNAM - Sub Menu\"},{\"t\":6,\"p\":1,\"n\":\"Embedded Script\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"SCHR - Basic Script Data\",\"c\":[{\"t\":11,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"RefCount\"},{\"t\":3,\"p\":1,\"n\":\"CompiledSize\"},{\"t\":3,\"p\":1,\"n\":\"VariableCount\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"}]},{\"t\":11,\"p\":1,\"n\":\"SCDA - Compiled Embedded Script\"},{\"t\":2,\"p\":1,\"n\":\"SCTX - Embedded Script Source\"},{\"t\":10,\"p\":1,\"n\":\"Local Variables\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Local Variable\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"SLSD - Local Variable Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Index\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"}]},{\"t\":2,\"p\":1,\"n\":\"SCVR - Name\"}]}]},{\"t\":8,\"p\":1,\"n\":\"References\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"SCRO - Global Reference\"},{\"t\":3,\"p\":1,\"n\":\"SCRV - Local Variable\"}]}]},{\"t\":8,\"p\":1,\"n\":\"Conditions\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"CTDA - Condition\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":5,\"p\":1,\"n\":\"Comparison Value - Float\"},{\"t\":3,\"p\":1,\"n\":\"Comparison Value - Global\"},{\"t\":3,\"p\":1,\"n\":\"Function\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":11,\"p\":1,\"n\":\"None\"},{\"t\":3,\"p\":1,\"n\":\"Integer\"},{\"t\":3,\"p\":1,\"n\":\"Variable Name (INVALID)\"},{\"t\":3,\"p\":1,\"n\":\"Sex\"},{\"t\":3,\"p\":1,\"n\":\"Actor Value\"},{\"t\":3,\"p\":1,\"n\":\"Crime Type\"},{\"t\":3,\"p\":1,\"n\":\"Axis\"},{\"t\":3,\"p\":1,\"n\":\"Quest Stage (INVALID)\"},{\"t\":3,\"p\":1,\"n\":\"Misc Stat\"},{\"t\":3,\"p\":1,\"n\":\"Alignment\"},{\"t\":3,\"p\":1,\"n\":\"Equip Type\"},{\"t\":3,\"p\":1,\"n\":\"Form Type\"},{\"t\":3,\"p\":1,\"n\":\"Critical Stage\"},{\"t\":3,\"p\":1,\"n\":\"Object Reference\"},{\"t\":3,\"p\":1,\"n\":\"Inventory Object\"},{\"t\":3,\"p\":1,\"n\":\"Actor\"},{\"t\":3,\"p\":1,\"n\":\"Voice Type\"},{\"t\":3,\"p\":1,\"n\":\"Idle\"},{\"t\":3,\"p\":1,\"n\":\"Form List\"},{\"t\":3,\"p\":1,\"n\":\"Note\"},{\"t\":3,\"p\":1,\"n\":\"Quest\"},{\"t\":3,\"p\":1,\"n\":\"Faction\"},{\"t\":3,\"p\":1,\"n\":\"Weapon\"},{\"t\":3,\"p\":1,\"n\":\"Cell\"},{\"t\":3,\"p\":1,\"n\":\"Class\"},{\"t\":3,\"p\":1,\"n\":\"Race\"},{\"t\":3,\"p\":1,\"n\":\"Actor Base\"},{\"t\":3,\"p\":1,\"n\":\"Global\"},{\"t\":3,\"p\":1,\"n\":\"Weather\"},{\"t\":3,\"p\":1,\"n\":\"Package\"},{\"t\":3,\"p\":1,\"n\":\"Encounter Zone\"},{\"t\":3,\"p\":1,\"n\":\"Perk\"},{\"t\":3,\"p\":1,\"n\":\"Owner\"},{\"t\":3,\"p\":1,\"n\":\"Furniture\"},{\"t\":3,\"p\":1,\"n\":\"Effect Item\"},{\"t\":3,\"p\":1,\"n\":\"Base Effect\"},{\"t\":3,\"p\":1,\"n\":\"Worldspace\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Function\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Param (INVALID)\"},{\"t\":3,\"p\":1,\"n\":\"Creature Type\"},{\"t\":3,\"p\":1,\"n\":\"Menu Mode\"},{\"t\":3,\"p\":1,\"n\":\"Player Action\"},{\"t\":3,\"p\":1,\"n\":\"Body Location\"},{\"t\":3,\"p\":1,\"n\":\"Referenceable Object\"},{\"t\":3,\"p\":1,\"n\":\"Variable Name\"},{\"t\":3,\"p\":1,\"n\":\"Quest Stage\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Function (INVALID)\"},{\"t\":3,\"p\":1,\"n\":\"Weapon List\"},{\"t\":3,\"p\":1,\"n\":\"Target\"},{\"t\":3,\"p\":1,\"n\":\"Target List\"},{\"t\":3,\"p\":1,\"n\":\"Target Part\"},{\"t\":3,\"p\":1,\"n\":\"VATS Action\"},{\"t\":3,\"p\":1,\"n\":\"Critical Effect\"},{\"t\":3,\"p\":1,\"n\":\"Critical Effect List\"},{\"t\":3,\"p\":1,\"n\":\"Weapon Type\"},{\"t\":3,\"p\":1,\"n\":\"Run On\"},{\"t\":3,\"p\":1,\"n\":\"Reference\"}]}]}]}]}]},{\"t\":1,\"p\":1,\"n\":\"TREE - Tree\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"X1\"},{\"t\":3,\"p\":1,\"n\":\"Y1\"},{\"t\":3,\"p\":1,\"n\":\"Z1\"},{\"t\":3,\"p\":1,\"n\":\"X2\"},{\"t\":3,\"p\":1,\"n\":\"Y2\"},{\"t\":3,\"p\":1,\"n\":\"Z2\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"},{\"t\":11,\"n\":\"MODB - Unknown\"},{\"t\":11,\"p\":1,\"n\":\"MODT - Texture Files Hashes\"},{\"t\":7,\"p\":1,\"n\":\"MODS - Alternate Textures\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"3D Name\"},{\"t\":3,\"p\":1,\"n\":\"New Texture\"},{\"t\":3,\"p\":1,\"n\":\"3D Index\"}]}]},{\"t\":3,\"p\":1,\"n\":\"MODD - FaceGen Model Flags\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Icon\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"ICON - Large Icon filename\"},{\"t\":2,\"p\":1,\"n\":\"MICO - Small Icon filename\"}]},{\"t\":7,\"p\":1,\"n\":\"SNAM - SpeedTree Seeds\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"SpeedTree Seed\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"CNAM - Tree Data\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Leaf Curvature\"},{\"t\":5,\"p\":1,\"n\":\"Minimum Leaf Angle\"},{\"t\":5,\"p\":1,\"n\":\"Maximum Leaf Angle\"},{\"t\":5,\"p\":1,\"n\":\"Branch Dimming Value\"},{\"t\":5,\"p\":1,\"n\":\"Leaf Dimming Value\"},{\"t\":3,\"p\":1,\"n\":\"Shadow Radius\"},{\"t\":5,\"p\":1,\"n\":\"Rock Speed\"},{\"t\":5,\"p\":1,\"n\":\"Rustle Speed\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"BNAM - Billboard Dimensions\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Width\"},{\"t\":5,\"p\":1,\"n\":\"Height\"}]}]},{\"t\":1,\"p\":1,\"n\":\"TXST - Texture Set\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"X1\"},{\"t\":3,\"p\":1,\"n\":\"Y1\"},{\"t\":3,\"p\":1,\"n\":\"Z1\"},{\"t\":3,\"p\":1,\"n\":\"X2\"},{\"t\":3,\"p\":1,\"n\":\"Y2\"},{\"t\":3,\"p\":1,\"n\":\"Z2\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Textures (RGB\\/A)\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"TX00 - Base Image \\/ Transparency\"},{\"t\":2,\"p\":1,\"n\":\"TX01 - Normal Map \\/ Specular\"},{\"t\":2,\"p\":1,\"n\":\"TX02 - Environment Map Mask \\/ ?\"},{\"t\":2,\"n\":\"TX03 - Glow Map \\/ Unused\"},{\"t\":2,\"n\":\"TX04 - Parallax Map \\/ Unused\"},{\"t\":2,\"n\":\"TX05 - Environment Map \\/ Unused\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DODT - Decal Data\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Min Width\"},{\"t\":5,\"p\":1,\"n\":\"Max Width\"},{\"t\":5,\"p\":1,\"n\":\"Min Height\"},{\"t\":5,\"p\":1,\"n\":\"Max Height\"},{\"t\":5,\"p\":1,\"n\":\"Depth\"},{\"t\":5,\"p\":1,\"n\":\"Shininess\"},{\"t\":6,\"p\":1,\"n\":\"Parallax\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Scale\"},{\"t\":3,\"p\":1,\"n\":\"Passes\"}]},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":6,\"p\":1,\"n\":\"Color\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]}]},{\"t\":3,\"p\":1,\"n\":\"DNAM - Flags\"}]},{\"t\":1,\"p\":1,\"n\":\"VTYP - Voice Type\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":3,\"p\":1,\"n\":\"DNAM - Flags\"}]},{\"t\":1,\"p\":1,\"n\":\"WATR - Water\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":2,\"p\":1,\"n\":\"NNAM - Noise Map\"},{\"t\":3,\"p\":1,\"n\":\"ANAM - Opacity\"},{\"t\":3,\"p\":1,\"n\":\"FNAM - Flags\"},{\"t\":2,\"p\":1,\"n\":\"MNAM - Material ID\"},{\"t\":3,\"p\":1,\"n\":\"SNAM - Sound\"},{\"t\":3,\"p\":1,\"n\":\"XNAM - Actor Effect\"},{\"t\":3,\"p\":1,\"n\":\"DATA - Damage\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DNAM - Visual Data\",\"c\":[{\"t\":5,\"n\":\"Unknown\"},{\"t\":5,\"p\":1,\"n\":\"Water Properties - Sun Power\"},{\"t\":5,\"p\":1,\"n\":\"Water Properties - Reflectivity Amount\"},{\"t\":5,\"p\":1,\"n\":\"Water Properties - Fresnel Amount\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":5,\"p\":1,\"n\":\"Fog Properties - Above Water - Fog Distance - Near Plane\"},{\"t\":5,\"p\":1,\"n\":\"Fog Properties - Above Water - Fog Distance - Far Plane\"},{\"t\":6,\"p\":1,\"n\":\"Shallow Color\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Deep Color\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Reflection Color\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":5,\"p\":1,\"n\":\"Rain Simulator - Force\"},{\"t\":5,\"p\":1,\"n\":\"Rain Simulator - Velocity\"},{\"t\":5,\"p\":1,\"n\":\"Rain Simulator - Falloff\"},{\"t\":5,\"p\":1,\"n\":\"Rain Simulator - Dampner\"},{\"t\":5,\"p\":1,\"n\":\"Displacement Simulator - Starting Size\"},{\"t\":5,\"p\":1,\"n\":\"Displacement Simulator - Force\"},{\"t\":5,\"p\":1,\"n\":\"Displacement Simulator - Velocity\"},{\"t\":5,\"p\":1,\"n\":\"Displacement Simulator - Falloff\"},{\"t\":5,\"p\":1,\"n\":\"Displacement Simulator - Dampner\"},{\"t\":5,\"p\":1,\"n\":\"Rain Simulator - Starting Size\"},{\"t\":5,\"p\":1,\"n\":\"Noise Properties - Normals - Noise Scale\"},{\"t\":5,\"p\":1,\"n\":\"Noise Properties - Noise Layer One - Wind Direction\"},{\"t\":5,\"p\":1,\"n\":\"Noise Properties - Noise Layer Two - Wind Direction\"},{\"t\":5,\"p\":1,\"n\":\"Noise Properties - Noise Layer Three - Wind Direction\"},{\"t\":5,\"p\":1,\"n\":\"Noise Properties - Noise Layer One - Wind Speed\"},{\"t\":5,\"p\":1,\"n\":\"Noise Properties - Noise Layer Two - Wind Speed\"},{\"t\":5,\"p\":1,\"n\":\"Noise Properties - Noise Layer Three - Wind Speed\"},{\"t\":5,\"p\":1,\"n\":\"Noise Properties - Normals - Depth Falloff Start\"},{\"t\":5,\"p\":1,\"n\":\"Noise Properties - Normals - Depth Falloff End\"},{\"t\":5,\"p\":1,\"n\":\"Fog Properties - Above Water - Fog Amount\"},{\"t\":5,\"p\":1,\"n\":\"Noise Properties - Normals - UV Scale\"},{\"t\":5,\"p\":1,\"n\":\"Fog Properties - Under Water - Fog Amount\"},{\"t\":5,\"p\":1,\"n\":\"Fog Properties - Under Water - Fog Distance - Near Plane\"},{\"t\":5,\"p\":1,\"n\":\"Fog Properties - Under Water - Fog Distance - Far Plane\"},{\"t\":5,\"p\":1,\"n\":\"Water Properties - Distortion Amount\"},{\"t\":5,\"p\":1,\"n\":\"Water Properties - Shininess\"},{\"t\":5,\"p\":1,\"n\":\"Water Properties - Reflection HDR Multiplier\"},{\"t\":5,\"p\":1,\"n\":\"Water Properties - Light Radius\"},{\"t\":5,\"p\":1,\"n\":\"Water Properties - Light Brightness\"},{\"t\":5,\"p\":1,\"n\":\"Noise Properties - Noise Layer One - UV Scale\"},{\"t\":5,\"p\":1,\"n\":\"Noise Properties - Noise Layer Two - UV Scale\"},{\"t\":5,\"p\":1,\"n\":\"Noise Properties - Noise Layer Three - UV Scale\"},{\"t\":5,\"p\":1,\"n\":\"Noise Properties - Noise Layer One - Amplitude Scale\"},{\"t\":5,\"p\":1,\"n\":\"Noise Properties - Noise Layer Two - Amplitude Scale\"},{\"t\":5,\"p\":1,\"n\":\"Noise Properties - Noise Layer Three - Amplitude Scale\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DATA - Visual Data\",\"c\":[{\"t\":5,\"n\":\"Unknown\"},{\"t\":5,\"p\":1,\"n\":\"Water Properties - Sun Power\"},{\"t\":5,\"p\":1,\"n\":\"Water Properties - Reflectivity Amount\"},{\"t\":5,\"p\":1,\"n\":\"Water Properties - Fresnel Amount\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":5,\"p\":1,\"n\":\"Fog Properties - Above Water - Fog Distance - Near Plane\"},{\"t\":5,\"p\":1,\"n\":\"Fog Properties - Above Water - Fog Distance - Far Plane\"},{\"t\":6,\"p\":1,\"n\":\"Shallow Color\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Deep Color\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Reflection Color\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":5,\"p\":1,\"n\":\"Rain Simulator - Force\"},{\"t\":5,\"p\":1,\"n\":\"Rain Simulator - Velocity\"},{\"t\":5,\"p\":1,\"n\":\"Rain Simulator - Falloff\"},{\"t\":5,\"p\":1,\"n\":\"Rain Simulator - Dampner\"},{\"t\":5,\"p\":1,\"n\":\"Displacement Simulator - Starting Size\"},{\"t\":5,\"p\":1,\"n\":\"Displacement Simulator - Force\"},{\"t\":5,\"p\":1,\"n\":\"Displacement Simulator - Velocity\"},{\"t\":5,\"p\":1,\"n\":\"Displacement Simulator - Falloff\"},{\"t\":5,\"p\":1,\"n\":\"Displacement Simulator - Dampner\"},{\"t\":5,\"p\":1,\"n\":\"Rain Simulator - Starting Size\"},{\"t\":5,\"p\":1,\"n\":\"Noise Properties - Normals - Noise Scale\"},{\"t\":5,\"p\":1,\"n\":\"Noise Properties - Noise Layer One - Wind Direction\"},{\"t\":5,\"p\":1,\"n\":\"Noise Properties - Noise Layer Two - Wind Direction\"},{\"t\":5,\"p\":1,\"n\":\"Noise Properties - Noise Layer Three - Wind Direction\"},{\"t\":5,\"p\":1,\"n\":\"Noise Properties - Noise Layer One - Wind Speed\"},{\"t\":5,\"p\":1,\"n\":\"Noise Properties - Noise Layer Two - Wind Speed\"},{\"t\":5,\"p\":1,\"n\":\"Noise Properties - Noise Layer Three - Wind Speed\"},{\"t\":5,\"p\":1,\"n\":\"Noise Properties - Normals - Depth Falloff Start\"},{\"t\":5,\"p\":1,\"n\":\"Noise Properties - Normals - Depth Falloff End\"},{\"t\":5,\"p\":1,\"n\":\"Fog Properties - Above Water - Fog Amount\"},{\"t\":5,\"p\":1,\"n\":\"Noise Properties - Normals - UV Scale\"},{\"t\":5,\"p\":1,\"n\":\"Fog Properties - Under Water - Fog Amount\"},{\"t\":5,\"p\":1,\"n\":\"Fog Properties - Under Water - Fog Distance - Near Plane\"},{\"t\":5,\"p\":1,\"n\":\"Fog Properties - Under Water - Fog Distance - Far Plane\"},{\"t\":5,\"p\":1,\"n\":\"Water Properties - Distortion Amount\"},{\"t\":5,\"p\":1,\"n\":\"Water Properties - Shininess\"},{\"t\":5,\"p\":1,\"n\":\"Water Properties - Reflection HDR Multiplier\"},{\"t\":5,\"p\":1,\"n\":\"Water Properties - Light Radius\"},{\"t\":5,\"p\":1,\"n\":\"Water Properties - Light Brightness\"},{\"t\":5,\"p\":1,\"n\":\"Noise Properties - Noise Layer One - UV Scale\"},{\"t\":5,\"p\":1,\"n\":\"Noise Properties - Noise Layer Two - UV Scale\"},{\"t\":5,\"p\":1,\"n\":\"Noise Properties - Noise Layer Three - UV Scale\"},{\"p\":1,\"n\":\"Noise Properties - Noise Layer One - Amplitude Scale\"},{\"p\":1,\"n\":\"Noise Properties - Noise Layer Two - Amplitude Scale\"},{\"p\":1,\"n\":\"Noise Properties - Noise Layer Three - Amplitude Scale\"},{\"t\":3,\"p\":1,\"n\":\"Damage (Old Format)\"}]},{\"t\":6,\"n\":\"GNAM - Related Waters (Unused)\",\"c\":[{\"t\":3,\"n\":\"Daytime\"},{\"t\":3,\"n\":\"Nighttime\"},{\"t\":3,\"n\":\"Underwater\"}]}]},{\"t\":1,\"p\":1,\"n\":\"WEAP - Weapon\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"X1\"},{\"t\":3,\"p\":1,\"n\":\"Y1\"},{\"t\":3,\"p\":1,\"n\":\"Z1\"},{\"t\":3,\"p\":1,\"n\":\"X2\"},{\"t\":3,\"p\":1,\"n\":\"Y2\"},{\"t\":3,\"p\":1,\"n\":\"Z2\"}]},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"},{\"t\":11,\"n\":\"MODB - Unknown\"},{\"t\":11,\"p\":1,\"n\":\"MODT - Texture Files Hashes\"},{\"t\":7,\"p\":1,\"n\":\"MODS - Alternate Textures\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"3D Name\"},{\"t\":3,\"p\":1,\"n\":\"New Texture\"},{\"t\":3,\"p\":1,\"n\":\"3D Index\"}]}]},{\"t\":3,\"p\":1,\"n\":\"MODD - FaceGen Model Flags\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Icon\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"ICON - Large Icon filename\"},{\"t\":2,\"p\":1,\"n\":\"MICO - Small Icon filename\"}]},{\"t\":3,\"p\":1,\"n\":\"SCRI - Script\"},{\"t\":3,\"p\":1,\"n\":\"EITM - Object Effect\"},{\"t\":3,\"p\":1,\"n\":\"EAMT - Enchantment Charge Amount\"},{\"t\":3,\"p\":1,\"n\":\"NAM0 - Ammo\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Destructable\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"DEST - Header\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Health\"},{\"t\":3,\"p\":1,\"n\":\"Count\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":8,\"p\":1,\"n\":\"Stages\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Stage\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"DSTD - Destruction Stage Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Health %\"},{\"t\":3,\"p\":1,\"n\":\"Index\"},{\"t\":3,\"p\":1,\"n\":\"Damage Stage\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":3,\"p\":1,\"n\":\"Self Damage per Second\"},{\"t\":3,\"p\":1,\"n\":\"Explosion\"},{\"t\":3,\"p\":1,\"n\":\"Debris\"},{\"t\":3,\"p\":1,\"n\":\"Debris Count\"}]},{\"t\":6,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"DMDL - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"DMDT - Texture Files Hashes\"}]},{\"p\":1,\"n\":\"DSTF - End Marker\"}]}]}]},{\"t\":3,\"p\":1,\"n\":\"REPL - Repair List\"},{\"t\":3,\"p\":1,\"n\":\"ETYP - Equiptment Type\"},{\"t\":3,\"p\":1,\"n\":\"BIPL - Biped Model List\"},{\"t\":3,\"p\":1,\"n\":\"YNAM - Sound - Pick Up\"},{\"t\":3,\"p\":1,\"n\":\"ZNAM - Sound - Drop\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Shell Casing Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MOD2 - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"MO2T - Texture Files Hashes\"},{\"t\":7,\"p\":1,\"n\":\"MO2S - Alternate Textures\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"3D Name\"},{\"t\":3,\"p\":1,\"n\":\"New Texture\"},{\"t\":3,\"p\":1,\"n\":\"3D Index\"}]}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Scope Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MOD3 - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"MO3T - Texture Files Hashes\"},{\"t\":7,\"p\":1,\"n\":\"MO3S - Alternate Textures\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"3D Name\"},{\"t\":3,\"p\":1,\"n\":\"New Texture\"},{\"t\":3,\"p\":1,\"n\":\"3D Index\"}]}]}]},{\"t\":3,\"p\":1,\"n\":\"EFSD - Scope Effect\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"World Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MOD4 - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"MO4T - Texture Files Hashes\"},{\"t\":7,\"p\":1,\"n\":\"MO4S - Alternate Textures\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"3D Name\"},{\"t\":3,\"p\":1,\"n\":\"New Texture\"},{\"t\":3,\"p\":1,\"n\":\"3D Index\"}]}]}]},{\"t\":2,\"p\":1,\"n\":\"NNAM - Embedded Weapon Node\"},{\"t\":3,\"p\":1,\"n\":\"INAM - Impact DataSet\"},{\"t\":3,\"p\":1,\"n\":\"WNAM - 1st Person Model\"},{\"t\":3,\"p\":1,\"n\":\"SNAM - Sound - Gun - Shoot 3D\"},{\"t\":3,\"p\":1,\"n\":\"XNAM - Sound - Gun - Shoot 2D\"},{\"t\":3,\"p\":1,\"n\":\"NAM7 - Sound - Gun - Shoot 3D Looping\"},{\"t\":3,\"p\":1,\"n\":\"TNAM - Sound - Melee - Swing \\/ Gun - No Ammo\"},{\"t\":3,\"p\":1,\"n\":\"NAM6 - Sound - Block\"},{\"t\":3,\"p\":1,\"n\":\"UNAM - Sound - Idle\"},{\"t\":3,\"p\":1,\"n\":\"NAM9 - Sound - Equip\"},{\"t\":3,\"p\":1,\"n\":\"NAM8 - Sound - Unequip\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DATA - \",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Value\"},{\"t\":3,\"p\":1,\"n\":\"Health\"},{\"t\":5,\"p\":1,\"n\":\"Weight\"},{\"t\":3,\"p\":1,\"n\":\"Base Damage\"},{\"t\":3,\"p\":1,\"n\":\"Clip Size\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DNAM - \",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Animation Type\"},{\"t\":5,\"p\":1,\"n\":\"Animation Multiplier\"},{\"t\":5,\"p\":1,\"n\":\"Reach\"},{\"t\":3,\"p\":1,\"n\":\"Flags 1\"},{\"t\":3,\"p\":1,\"n\":\"Grip Animation\"},{\"t\":3,\"p\":1,\"n\":\"Ammo Use\"},{\"t\":3,\"p\":1,\"n\":\"Reload Animation\"},{\"t\":5,\"p\":1,\"n\":\"Min Spread\"},{\"t\":5,\"p\":1,\"n\":\"Spread\"},{\"t\":5,\"n\":\"Unknown\"},{\"t\":5,\"p\":1,\"n\":\"Sight FOV\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Projectile\"},{\"t\":3,\"p\":1,\"n\":\"Base VATS To-Hit Chance\"},{\"t\":3,\"p\":1,\"n\":\"Attack Animation\"},{\"t\":3,\"p\":1,\"n\":\"Projectile Count\"},{\"t\":3,\"p\":1,\"n\":\"Embedded Weapon - Actor Value\"},{\"t\":5,\"p\":1,\"n\":\"Min Range\"},{\"t\":5,\"p\":1,\"n\":\"Max Range\"},{\"t\":3,\"p\":1,\"n\":\"On Hit\"},{\"t\":3,\"p\":1,\"n\":\"Flags 2\"},{\"t\":5,\"p\":1,\"n\":\"Animation Attack Multiplier\"},{\"t\":5,\"p\":1,\"n\":\"Fire Rate\"},{\"t\":5,\"p\":1,\"n\":\"Override - Action Points\"},{\"t\":5,\"p\":1,\"n\":\"Rumble - Left Motor Strength\"},{\"t\":5,\"p\":1,\"n\":\"Rumble - Right Motor Strength\"},{\"t\":5,\"p\":1,\"n\":\"Rumble - Duration\"},{\"t\":5,\"p\":1,\"n\":\"Override - Damage to Weapon Mult\"},{\"t\":5,\"p\":1,\"n\":\"Attack Shots\\/Sec\"},{\"t\":5,\"p\":1,\"n\":\"Reload Time\"},{\"t\":5,\"p\":1,\"n\":\"Jam Time\"},{\"t\":5,\"p\":1,\"n\":\"Aim Arc\"},{\"t\":3,\"p\":1,\"n\":\"Skill\"},{\"t\":3,\"p\":1,\"n\":\"Rumble - Pattern\"},{\"t\":5,\"p\":1,\"n\":\"Rumble - Wavelength\"},{\"t\":5,\"p\":1,\"n\":\"Limb Dmg Mult\"},{\"t\":3,\"p\":1,\"n\":\"Resist Type\"},{\"t\":5,\"p\":1,\"n\":\"Sight Usage\"},{\"t\":5,\"p\":1,\"n\":\"Semi-Automatic Fire Delay Min\"},{\"t\":5,\"p\":1,\"n\":\"Semi-Automatic Fire Delay Max\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"CRDT - Critical Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Critical Damage\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":5,\"p\":1,\"n\":\"Crit % Mult\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":3,\"p\":1,\"n\":\"Effect\"}]},{\"t\":3,\"p\":1,\"n\":\"VNAM - Sound Level\"}]},{\"t\":1,\"p\":1,\"n\":\"WRLD - Worldspace\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":3,\"p\":1,\"n\":\"XEZN - Encounter Zone\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Parent\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"WNAM - Worldspace\"},{\"t\":6,\"p\":1,\"n\":\"PNAM - \",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unknown\"}]}]},{\"t\":3,\"p\":1,\"n\":\"CNAM - Climate\"},{\"t\":3,\"p\":1,\"n\":\"NAM2 - Water\"},{\"t\":3,\"p\":1,\"n\":\"NAM3 - LOD Water Type\"},{\"t\":5,\"p\":1,\"n\":\"NAM4 - LOD Water Height\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DNAM - Land Data\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Default Land Height\"},{\"t\":5,\"p\":1,\"n\":\"Default Water Height\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Icon\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"ICON - Large Icon filename\"},{\"t\":2,\"p\":1,\"n\":\"MICO - Small Icon filename\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"MNAM - Map Data\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Usable Dimensions\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"X\"},{\"t\":3,\"p\":1,\"n\":\"Y\"}]},{\"t\":6,\"p\":1,\"n\":\"Cell Coordinates\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"NW Cell\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"X\"},{\"t\":3,\"p\":1,\"n\":\"Y\"}]},{\"t\":6,\"p\":1,\"n\":\"SE Cell\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"X\"},{\"t\":3,\"p\":1,\"n\":\"Y\"}]}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"ONAM - World Map Offset Data\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"World Map Scale\"},{\"t\":5,\"p\":1,\"n\":\"Cell X Offset\"},{\"t\":5,\"p\":1,\"n\":\"Cell Y Offset\"}]},{\"t\":3,\"p\":1,\"n\":\"INAM - Image Space\"},{\"t\":3,\"p\":1,\"n\":\"DATA - Flags\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Object Bounds\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"NAM0 - Min\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"X\"},{\"t\":5,\"p\":1,\"n\":\"Y\"}]},{\"t\":6,\"p\":1,\"n\":\"NAM9 - Max\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"X\"},{\"t\":5,\"p\":1,\"n\":\"Y\"}]}]},{\"t\":3,\"p\":1,\"n\":\"ZNAM - Music\"},{\"t\":2,\"p\":1,\"n\":\"NNAM - Canopy Shadow\"},{\"t\":2,\"p\":1,\"n\":\"XNAM - Water Noise Texture\"},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Swapped Impacts\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"IMPS - Swapped Impact\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Material Type\"},{\"t\":3,\"p\":1,\"n\":\"Old\"},{\"t\":3,\"p\":1,\"n\":\"New\"}]}]},{\"t\":7,\"n\":\"IMPF - Footstep Materials\",\"c\":[{\"t\":2,\"n\":\"Unknown\"}]},{\"t\":11,\"n\":\"OFST - Offset Data\"}]},{\"t\":1,\"p\":1,\"n\":\"WTHR - Weather\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":3,\"p\":1,\"n\":\"aIAD - Sunrise Image Space Modifier\"},{\"t\":3,\"p\":1,\"n\":\"bIAD - Day Image Space Modifier\"},{\"t\":3,\"p\":1,\"n\":\"cIAD - Sunset Image Space Modifier\"},{\"t\":3,\"p\":1,\"n\":\"dIAD - Night Image Space Modifier\"},{\"t\":2,\"p\":1,\"n\":\"DNAM - Cloud Textures - Layer 0\"},{\"t\":2,\"p\":1,\"n\":\"CNAM - Cloud Textures - Layer 1\"},{\"t\":2,\"p\":1,\"n\":\"ANAM - Cloud Textures - Layer 2\"},{\"t\":2,\"p\":1,\"n\":\"BNAM - Cloud Textures - Layer 3\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"},{\"t\":11,\"n\":\"MODB - Unknown\"},{\"t\":11,\"p\":1,\"n\":\"MODT - Texture Files Hashes\"},{\"t\":7,\"p\":1,\"n\":\"MODS - Alternate Textures\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"3D Name\"},{\"t\":3,\"p\":1,\"n\":\"New Texture\"},{\"t\":3,\"p\":1,\"n\":\"3D Index\"}]}]},{\"t\":3,\"p\":1,\"n\":\"MODD - FaceGen Model Flags\"}]},{\"t\":11,\"n\":\"LNAM - Unknown\"},{\"t\":7,\"p\":1,\"n\":\"ONAM - Cloud Speed\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Layer\"}]},{\"t\":7,\"p\":1,\"n\":\"PNAM - Cloud Layer Colors\",\"c\":[{\"t\":7,\"p\":1,\"n\":\"Layer\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Color\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]}]}]},{\"t\":7,\"p\":1,\"n\":\"NAM0 - Colors by Types\\/Times\",\"c\":[{\"t\":7,\"p\":1,\"n\":\"Type\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Time\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"FNAM - Fog Distance\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Day - Near\"},{\"t\":5,\"p\":1,\"n\":\"Day - Far\"},{\"t\":5,\"p\":1,\"n\":\"Night - Near\"},{\"t\":5,\"p\":1,\"n\":\"Night - Far\"},{\"t\":5,\"p\":1,\"n\":\"Day - Power\"},{\"t\":5,\"p\":1,\"n\":\"Night - Fower\"}]},{\"t\":11,\"n\":\"INAM - Unused\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DATA - \",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Wind Speed\"},{\"t\":3,\"p\":1,\"n\":\"Cloud Speed (Lower)\"},{\"t\":3,\"p\":1,\"n\":\"Cloud Speed (Upper)\"},{\"t\":3,\"p\":1,\"n\":\"Trans Delta\"},{\"t\":3,\"p\":1,\"n\":\"Sun Glare\"},{\"t\":3,\"p\":1,\"n\":\"Sun Damage\"},{\"t\":3,\"p\":1,\"n\":\"Precipitation - Begin Fade In\"},{\"t\":3,\"p\":1,\"n\":\"Precipitation - End Fade Out\"},{\"t\":3,\"p\":1,\"n\":\"Thunder\\/Lightning - Begin Fade In\"},{\"t\":3,\"p\":1,\"n\":\"Thunder\\/Lightning - End Fade Out\"},{\"t\":3,\"p\":1,\"n\":\"Thunder\\/Lightning - Frequency\"},{\"t\":3,\"p\":1,\"n\":\"Weather Classification\"},{\"t\":6,\"p\":1,\"n\":\"Lightning Color\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"}]}]},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Sounds\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"SNAM - Sound\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Sound\"},{\"t\":3,\"p\":1,\"n\":\"Type\"}]}]}]},{\"t\":1,\"p\":1,\"n\":\"ACRE - Placed Creature\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":3,\"p\":1,\"n\":\"NAME - Base\"},{\"t\":3,\"p\":1,\"n\":\"XEZN - Encounter Zone\"},{\"t\":11,\"n\":\"XRGD - Ragdoll Data\"},{\"t\":11,\"n\":\"XRGB - Ragdoll Biped Data\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Patrol Data\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"XPRD - Idle Time\"},{\"p\":1,\"n\":\"XPPA - Patrol Script Marker\"},{\"t\":3,\"p\":1,\"n\":\"INAM - Idle\"},{\"t\":6,\"p\":1,\"n\":\"Embedded Script\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"SCHR - Basic Script Data\",\"c\":[{\"t\":11,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"RefCount\"},{\"t\":3,\"p\":1,\"n\":\"CompiledSize\"},{\"t\":3,\"p\":1,\"n\":\"VariableCount\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"}]},{\"t\":11,\"p\":1,\"n\":\"SCDA - Compiled Embedded Script\"},{\"t\":2,\"p\":1,\"n\":\"SCTX - Embedded Script Source\"},{\"t\":10,\"p\":1,\"n\":\"Local Variables\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Local Variable\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"SLSD - Local Variable Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Index\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"}]},{\"t\":2,\"p\":1,\"n\":\"SCVR - Name\"}]}]},{\"t\":8,\"p\":1,\"n\":\"References\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"SCRO - Global Reference\"},{\"t\":3,\"p\":1,\"n\":\"SCRV - Local Variable\"}]}]},{\"t\":3,\"p\":1,\"n\":\"TNAM - Topic\"}]},{\"t\":3,\"p\":1,\"n\":\"XLCM - Level Modifier\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Ownership\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"XOWN - Owner\"},{\"t\":3,\"p\":1,\"n\":\"XRNK - Faction rank\"}]},{\"t\":3,\"p\":1,\"n\":\"XMRC - Merchant Container\"},{\"t\":3,\"p\":1,\"n\":\"XCNT - Count\"},{\"t\":5,\"p\":1,\"n\":\"XRDS - Radius\"},{\"t\":5,\"p\":1,\"n\":\"XHLP - Health\"},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Linked Decals\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"XDCR - Decal\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":11,\"n\":\"Unknown\"}]}]},{\"t\":3,\"p\":1,\"n\":\"XLKR - Linked Reference\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"XCLP - Linked Reference Color\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Link Start Color\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Link End Color\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Activate Parents\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"XAPD - Flags\"},{\"t\":8,\"p\":1,\"n\":\"Activate Parent Refs\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"XAPR - Activate Parent Ref\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":5,\"p\":1,\"n\":\"Delay\"}]}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"XESP - Enable Parent\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":3,\"p\":1,\"n\":\"XEMI - Emittance\"},{\"t\":3,\"p\":1,\"n\":\"XMBR - MultiBound Reference\"},{\"p\":1,\"n\":\"XIBS - Ignored By Sandbox\"},{\"t\":5,\"p\":1,\"n\":\"XSCL - Scale\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DATA - Position\\/Rotation\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Position\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"X\"},{\"t\":5,\"p\":1,\"n\":\"Y\"},{\"t\":5,\"p\":1,\"n\":\"Z\"}]},{\"t\":6,\"p\":1,\"n\":\"Rotation\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"X\"},{\"t\":5,\"p\":1,\"n\":\"Y\"},{\"t\":5,\"p\":1,\"n\":\"Z\"}]}]}]}]},\"name\":\"Smash.All\",\"hash\":\"0BB5CBB2\",\"color\":128}"
  },
  {
    "path": "frontend/settings/Fallout4/Smash.All.json",
    "content": "{\"records\":\"ACHR,ACTI,ADDN,AECH,ALCH,AMDL,AMMO,ANIO,AORU,ARMA,ARMO,ARTO,ASPC,ASTP,AVIF,BNDS,BOOK,BPTD,CAMS,CELL,CLAS,CLFM,CLMT,CMPO,COBJ,COLL,CONT,CPTH,CSTY,DEBR,DFOB,DIAL,DLBR,DLVW,DMGT,DOOR,DUAL,ECZN,EFSH,ENCH,EQUP,EXPL,FACT,FLOR,FLST,FSTP,FSTS,FURN,GDRY,GLOB,GMST,GRAS,HAZD,HDPT,IDLM,IMAD,IMGS,INFO,INGR,INNR,IPCT,IPDS,KEYM,KSSM,KYWD,LAND,LAYR,LCRT,LENS,LGTM,LIGH,LSCR,LTEX,LVLI,LVLN,LVSP,MATO,MATT,MESG,MGEF,MISC,MOVT,MSTT,MSWP,MUSC,MUST,NOTE,NPC_,OMOD,OTFT,PACK,PARW,PBAR,PBEA,PCON,PERK,PFLA,PGRE,PHZD,PKIN,PMIS,PROJ,QUST,REFR,REGN,RELA,REVB,RFCT,RFGP,SCCO,SCEN,SCOL,SCSN,SMBN,SMEN,SMQN,SNCT,SNDR,SOPM,SOUN,SPEL,SPGD,STAG,STAT,TACT,TERM,TREE,TRNS,TXST,VTYP,WATR,WEAP,WRLD,WTHR,ZOOM,AACT\",\"description\":\"Smashes all the things.  Produced using autoset attributes on all record types found in Fallout4.esm.\\r\\n\\r\\nLast updated 05\\/01\\/2018.\",\"tree\":{\"records\":[{\"t\":1,\"p\":1,\"n\":\"ACHR - Placed NPC\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"VMAD - Virtual Machine Adapter\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Version\"},{\"t\":3,\"p\":1,\"n\":\"Object Format\"},{\"t\":7,\"p\":1,\"n\":\"Scripts\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Script\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"scriptName\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":7,\"p\":1,\"n\":\"Properties\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Property\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"propertyName\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]},{\"t\":2,\"p\":1,\"n\":\"String\"},{\"t\":3,\"p\":1,\"n\":\"Int32\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":3,\"p\":1,\"n\":\"Bool\"},{\"t\":7,\"p\":1,\"n\":\"Struct\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Member\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"memberName\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]},{\"t\":2,\"p\":1,\"n\":\"String\"},{\"t\":3,\"p\":1,\"n\":\"Int32\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":3,\"p\":1,\"n\":\"Bool\"},{\"t\":7,\"p\":1,\"n\":\"Array of Object\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]}]},{\"t\":7,\"p\":1,\"n\":\"Array of String\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Int32\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Float\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Bool\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]}]}]},{\"t\":7,\"p\":1,\"n\":\"Array of Object\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]}]},{\"t\":7,\"p\":1,\"n\":\"Array of String\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Int32\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Float\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Bool\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Struct\",\"c\":[{\"t\":7,\"p\":1,\"n\":\"Struct\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Member\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"memberName\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]},{\"t\":2,\"p\":1,\"n\":\"String\"},{\"t\":3,\"p\":1,\"n\":\"Int32\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":3,\"p\":1,\"n\":\"Bool\"},{\"t\":7,\"p\":1,\"n\":\"Array of Object\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]}]},{\"t\":7,\"p\":1,\"n\":\"Array of String\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Int32\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Float\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Bool\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]}]}]}]}]}]}]}]}]},{\"t\":3,\"p\":1,\"n\":\"NAME - Base\"},{\"t\":3,\"p\":1,\"n\":\"XEZN - Encounter Zone\"},{\"t\":11,\"n\":\"XRGD - Ragdoll Data\"},{\"t\":11,\"n\":\"XRGB - Ragdoll Biped Data\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Patrol Data\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"XPRD - Idle Time\"},{\"p\":1,\"n\":\"XPPA - Patrol Script Marker\"},{\"t\":3,\"p\":1,\"n\":\"INAM - Idle\"},{\"t\":8,\"p\":1,\"n\":\"Topic\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"PDTO - Topic Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Topic\"},{\"t\":2,\"p\":1,\"n\":\"Subtype\"}]}]},{\"t\":3,\"p\":1,\"n\":\"TNAM - Topic\"}]},{\"t\":3,\"p\":1,\"n\":\"XLCM - Level Modifier\"},{\"t\":3,\"p\":1,\"n\":\"XCNT - Count\"},{\"t\":5,\"p\":1,\"n\":\"XRDS - Radius\"},{\"t\":3,\"p\":1,\"n\":\"XHLT - Health %\"},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Linked References\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"XLKR - Linked Reference\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Keyword\\/Ref\"},{\"t\":3,\"p\":1,\"n\":\"Ref\"}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Activate Parents\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"XAPD - Flags\"},{\"t\":8,\"p\":1,\"n\":\"Activate Parent Refs\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"XAPR - Activate Parent Ref\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":5,\"p\":1,\"n\":\"Delay\"}]}]}]},{\"p\":1,\"n\":\"XLKT - Linked Ref Transient\"},{\"t\":3,\"p\":1,\"n\":\"XRFG - Reference Group\"},{\"t\":3,\"p\":1,\"n\":\"XLYR - Layer\"},{\"t\":3,\"p\":1,\"n\":\"XMSP - Material Swap\"},{\"t\":3,\"p\":1,\"n\":\"XLCN - Persistent Location\"},{\"t\":3,\"p\":1,\"n\":\"XLRL - Location Reference\"},{\"t\":7,\"p\":1,\"n\":\"XLRT - Location Ref Type\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Ref\"}]},{\"p\":1,\"n\":\"XIS2 - Ignored by Sandbox\"},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Spline Connection\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"XPLK - Link\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Ref\"},{\"t\":11,\"n\":\"Unknown\"}]}]},{\"t\":5,\"p\":1,\"n\":\"XHTW - Head-Tracking Weight\"},{\"t\":5,\"p\":1,\"n\":\"XFVC - Favor Cost\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"XESP - Enable Parent\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"XOWN - Owner\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Owner\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"}]},{\"t\":3,\"p\":1,\"n\":\"XRNK - Owner Faction Rank\"},{\"t\":3,\"p\":1,\"n\":\"XEMI - Emittance\"},{\"t\":3,\"p\":1,\"n\":\"XMBR - MultiBound Reference\"},{\"p\":1,\"n\":\"XIBS - Ignored By Sandbox\"},{\"t\":5,\"p\":1,\"n\":\"XSCL - Scale\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DATA - Position\\/Rotation\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Position\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"X\"},{\"t\":5,\"p\":1,\"n\":\"Y\"},{\"t\":5,\"p\":1,\"n\":\"Z\"}]},{\"t\":6,\"p\":1,\"n\":\"Rotation\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"X\"},{\"t\":5,\"p\":1,\"n\":\"Y\"},{\"t\":5,\"p\":1,\"n\":\"Z\"}]}]},{\"t\":2,\"p\":1,\"n\":\"MNAM - Comments\"}]},{\"t\":1,\"p\":1,\"n\":\"ACTI - Activator\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"VMAD - Virtual Machine Adapter\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Version\"},{\"t\":3,\"p\":1,\"n\":\"Object Format\"},{\"t\":7,\"p\":1,\"n\":\"Scripts\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Script\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"scriptName\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":7,\"p\":1,\"n\":\"Properties\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Property\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"propertyName\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]},{\"t\":2,\"p\":1,\"n\":\"String\"},{\"t\":3,\"p\":1,\"n\":\"Int32\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":3,\"p\":1,\"n\":\"Bool\"},{\"t\":7,\"p\":1,\"n\":\"Struct\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Member\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"memberName\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]},{\"t\":2,\"p\":1,\"n\":\"String\"},{\"t\":3,\"p\":1,\"n\":\"Int32\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":3,\"p\":1,\"n\":\"Bool\"},{\"t\":7,\"p\":1,\"n\":\"Array of Object\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]}]},{\"t\":7,\"p\":1,\"n\":\"Array of String\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Int32\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Float\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Bool\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]}]}]},{\"t\":7,\"p\":1,\"n\":\"Array of Object\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]}]},{\"t\":7,\"p\":1,\"n\":\"Array of String\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Int32\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Float\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Bool\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Struct\",\"c\":[{\"t\":7,\"p\":1,\"n\":\"Struct\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Member\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"memberName\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]},{\"t\":2,\"p\":1,\"n\":\"String\"},{\"t\":3,\"p\":1,\"n\":\"Int32\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":3,\"p\":1,\"n\":\"Bool\"},{\"t\":7,\"p\":1,\"n\":\"Array of Object\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]}]},{\"t\":7,\"p\":1,\"n\":\"Array of String\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Int32\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Float\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Bool\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]}]}]}]}]}]}]}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"X1\"},{\"t\":3,\"p\":1,\"n\":\"Y1\"},{\"t\":3,\"p\":1,\"n\":\"Z1\"},{\"t\":3,\"p\":1,\"n\":\"X2\"},{\"t\":3,\"p\":1,\"n\":\"Y2\"},{\"t\":3,\"p\":1,\"n\":\"Z2\"}]},{\"t\":3,\"p\":1,\"n\":\"PTRN - Preview Transform\"},{\"t\":3,\"p\":1,\"n\":\"STCP - Sound\"},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"MODT - Texture Files Hashes\"},{\"t\":3,\"p\":1,\"n\":\"MODS - Material Swap\"},{\"t\":5,\"p\":1,\"n\":\"MODC - Color Remapping Index\"},{\"t\":11,\"n\":\"MODF - Unknown\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Destructible\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"DEST - Header\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Health\"},{\"t\":3,\"p\":1,\"n\":\"DEST Count\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":7,\"p\":1,\"n\":\"DAMC - Resistances\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Resistance\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Damage Type\"},{\"t\":3,\"p\":1,\"n\":\"Value\"}]}]},{\"t\":8,\"p\":1,\"n\":\"Stages\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Stage\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"DSTD - Destruction Stage Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Health %\"},{\"t\":3,\"p\":1,\"n\":\"Index\"},{\"t\":3,\"p\":1,\"n\":\"Model Damage Stage\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":3,\"p\":1,\"n\":\"Self Damage per Second\"},{\"t\":3,\"p\":1,\"n\":\"Explosion\"},{\"t\":3,\"p\":1,\"n\":\"Debris\"},{\"t\":3,\"p\":1,\"n\":\"Debris Count\"}]},{\"t\":2,\"p\":1,\"n\":\"DSTA - Sequence Name\"},{\"t\":6,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"DMDL - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"DMDT - Texture Files Hashes\"},{\"t\":5,\"p\":1,\"n\":\"DMDC - Color Remapping Index\"},{\"t\":3,\"p\":1,\"n\":\"DMDS - Material Swap\"}]},{\"p\":1,\"n\":\"DSTF - End Marker\"}]}]}]},{\"t\":3,\"n\":\"KSIZ - Keyword Count\"},{\"t\":7,\"p\":1,\"n\":\"KWDA - Keywords\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Keyword\"}]},{\"t\":7,\"p\":1,\"n\":\"PRPS - Properties\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Property\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Actor Value\"},{\"t\":5,\"p\":1,\"n\":\"Value\"}]}]},{\"t\":3,\"p\":1,\"n\":\"NTRM - Native Terminal\"},{\"t\":3,\"p\":1,\"n\":\"FTYP - Forced Loc Ref Type\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"PNAM - Marker Color\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":3,\"n\":\"Unused\"}]},{\"t\":3,\"p\":1,\"n\":\"SNAM - Sound - Looping\"},{\"t\":3,\"p\":1,\"n\":\"VNAM - Sound - Activation\"},{\"t\":3,\"p\":1,\"n\":\"WNAM - Water Type\"},{\"t\":2,\"p\":1,\"n\":\"ATTX - Activate Text Override\"},{\"t\":3,\"p\":1,\"n\":\"FNAM - Flags\"},{\"t\":3,\"p\":1,\"n\":\"KNAM - Interaction Keyword\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"RADR - Radio Receiver\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Sound Model\"},{\"t\":5,\"p\":1,\"n\":\"Frequency\"},{\"t\":5,\"p\":1,\"n\":\"Volume\"},{\"t\":3,\"p\":1,\"n\":\"Starts Active\"},{\"t\":3,\"p\":1,\"n\":\"No Signal Static\"}]},{\"t\":3,\"n\":\"CITC - Condition Count\"},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Conditions\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Condition\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"CTDA - \",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":5,\"p\":1,\"n\":\"Comparison Value - Float\"},{\"t\":3,\"p\":1,\"n\":\"Comparison Value - Global\"},{\"t\":3,\"p\":1,\"n\":\"Function\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":11,\"p\":1,\"n\":\"None\"},{\"t\":3,\"p\":1,\"n\":\"Integer\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":3,\"p\":1,\"n\":\"Actor\"},{\"t\":3,\"p\":1,\"n\":\"Actor Base\"},{\"t\":3,\"p\":1,\"n\":\"Actor Value\"},{\"t\":3,\"p\":1,\"n\":\"Player Action\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"Alignment\"},{\"t\":3,\"p\":1,\"n\":\"Association Type\"},{\"t\":3,\"p\":1,\"n\":\"Axis\"},{\"t\":3,\"p\":1,\"n\":\"Casting Type\"},{\"t\":3,\"p\":1,\"n\":\"Cell\"},{\"t\":3,\"p\":1,\"n\":\"Class\"},{\"t\":3,\"p\":1,\"n\":\"Crime Type\"},{\"t\":3,\"p\":1,\"n\":\"Critical Stage\"},{\"t\":3,\"p\":1,\"n\":\"Encounter Zone\"},{\"t\":3,\"p\":1,\"n\":\"Equip Type\"},{\"t\":3,\"p\":1,\"n\":\"Event\"},{\"t\":3,\"p\":1,\"n\":\"Event Data\"},{\"t\":3,\"p\":1,\"n\":\"Faction\"},{\"t\":3,\"p\":1,\"n\":\"Form List\"},{\"t\":3,\"p\":1,\"n\":\"Form Type\"},{\"t\":3,\"p\":1,\"n\":\"Furniture\"},{\"t\":3,\"p\":1,\"n\":\"Furniture Anim\"},{\"t\":3,\"p\":1,\"n\":\"Furniture Entry\"},{\"t\":3,\"p\":1,\"n\":\"Global\"},{\"t\":3,\"p\":1,\"n\":\"Idle\"},{\"t\":3,\"p\":1,\"n\":\"Inventory Object\"},{\"t\":3,\"p\":1,\"n\":\"Keyword\"},{\"t\":3,\"p\":1,\"n\":\"Location\"},{\"t\":3,\"p\":1,\"n\":\"Base Effect\"},{\"t\":3,\"p\":1,\"n\":\"Effect Item\"},{\"t\":3,\"p\":1,\"n\":\"Misc Stat\"},{\"t\":3,\"p\":1,\"n\":\"Object Reference\"},{\"t\":3,\"p\":1,\"n\":\"Owner\"},{\"t\":3,\"p\":1,\"n\":\"Package\"},{\"t\":3,\"p\":1,\"n\":\"Packdata ID\"},{\"t\":3,\"p\":1,\"n\":\"Perk\"},{\"t\":3,\"p\":1,\"n\":\"Quest\"},{\"t\":3,\"p\":1,\"n\":\"Quest Stage\"},{\"t\":3,\"p\":1,\"n\":\"Race\"},{\"t\":3,\"p\":1,\"n\":\"Referenceable Object\"},{\"t\":3,\"p\":1,\"n\":\"Location Ref Type\"},{\"t\":3,\"p\":1,\"n\":\"Region\"},{\"t\":3,\"p\":1,\"n\":\"Scene\"},{\"t\":3,\"p\":1,\"n\":\"Sex\"},{\"t\":3,\"p\":1,\"n\":\"Shout\"},{\"t\":11,\"p\":1,\"n\":\"Variable Name (unused)\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Function\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Param (unused)\"},{\"t\":3,\"p\":1,\"n\":\"Voice Type\"},{\"t\":3,\"p\":1,\"n\":\"Ward State\"},{\"t\":3,\"p\":1,\"n\":\"Weather\"},{\"t\":3,\"p\":1,\"n\":\"Worldspace\"},{\"t\":3,\"p\":1,\"n\":\"Damage Type\"},{\"t\":3,\"p\":1,\"n\":\"Weapon\"},{\"t\":3,\"p\":1,\"n\":\"Weapon List\"},{\"t\":3,\"p\":1,\"n\":\"Target\"},{\"t\":3,\"p\":1,\"n\":\"Target List\"},{\"t\":3,\"p\":1,\"n\":\"Target Part\"},{\"t\":3,\"p\":1,\"n\":\"VATS Action\"},{\"t\":3,\"p\":1,\"n\":\"Critical Effect\"},{\"t\":3,\"p\":1,\"n\":\"Critical Effect List\"},{\"t\":3,\"p\":1,\"n\":\"Weapon Type\"},{\"t\":3,\"p\":1,\"n\":\"Projectile Type\"},{\"t\":3,\"p\":1,\"n\":\"Delivery Type\"},{\"t\":3,\"p\":1,\"n\":\"Run On\"},{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":3,\"p\":1,\"n\":\"Parameter #3\"}]},{\"t\":2,\"p\":1,\"n\":\"CIS1 - Parameter #1\"},{\"t\":2,\"p\":1,\"n\":\"CIS2 - Parameter #2\"}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"NVNM - Navmesh Geometry\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Version\"},{\"t\":11,\"p\":1,\"n\":\"Magic\"},{\"t\":3,\"p\":1,\"n\":\"Parent Worldspace\"},{\"t\":6,\"p\":1,\"n\":\"Coordinates\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Grid Y\"},{\"t\":3,\"p\":1,\"n\":\"Grid X\"}]},{\"t\":3,\"p\":1,\"n\":\"Parent Cell\"},{\"t\":11,\"p\":1,\"n\":\"Vertices and Triangles\"}]}]},{\"t\":1,\"p\":1,\"n\":\"ADDN - Addon Node\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"X1\"},{\"t\":3,\"p\":1,\"n\":\"Y1\"},{\"t\":3,\"p\":1,\"n\":\"Z1\"},{\"t\":3,\"p\":1,\"n\":\"X2\"},{\"t\":3,\"p\":1,\"n\":\"Y2\"},{\"t\":3,\"p\":1,\"n\":\"Z2\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"MODT - Texture Files Hashes\"},{\"t\":3,\"p\":1,\"n\":\"MODS - Material Swap\"},{\"t\":5,\"p\":1,\"n\":\"MODC - Color Remapping Index\"},{\"t\":11,\"n\":\"MODF - Unknown\"}]},{\"t\":3,\"p\":1,\"n\":\"DATA - Node Index\"},{\"t\":3,\"p\":1,\"n\":\"SNAM - Sound\"},{\"t\":3,\"p\":1,\"n\":\"LNAM - Light\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DNAM - Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Master Particle System Cap\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"}]}]},{\"t\":1,\"p\":1,\"n\":\"AECH - Audio Effect Chain\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Effects\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Effect\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"KNAM - Type\"},{\"t\":6,\"p\":1,\"n\":\"DNAM - Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Enabled\"},{\"t\":5,\"p\":1,\"n\":\"Input Gain\"},{\"t\":5,\"p\":1,\"n\":\"Center Freq\"},{\"t\":5,\"p\":1,\"n\":\"Feedback %\"},{\"t\":5,\"p\":1,\"n\":\"Output Gain\"},{\"t\":5,\"p\":1,\"n\":\"Q Value\"},{\"t\":5,\"p\":1,\"n\":\"Wet Mix %\"},{\"t\":5,\"p\":1,\"n\":\"Upper Threshold\"},{\"t\":3,\"p\":1,\"n\":\"Filter Mode\"},{\"t\":3,\"p\":1,\"n\":\"Delay MS\"},{\"t\":5,\"p\":1,\"n\":\"Lower Threshold\"},{\"t\":11,\"n\":\"Unused\"}]}]}]}]},{\"t\":1,\"p\":1,\"n\":\"ALCH - Ingestible\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"X1\"},{\"t\":3,\"p\":1,\"n\":\"Y1\"},{\"t\":3,\"p\":1,\"n\":\"Z1\"},{\"t\":3,\"p\":1,\"n\":\"X2\"},{\"t\":3,\"p\":1,\"n\":\"Y2\"},{\"t\":3,\"p\":1,\"n\":\"Z2\"}]},{\"t\":3,\"p\":1,\"n\":\"PTRN - Preview Transform\"},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":3,\"n\":\"KSIZ - Keyword Count\"},{\"t\":7,\"p\":1,\"n\":\"KWDA - Keywords\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Keyword\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"MODT - Texture Files Hashes\"},{\"t\":3,\"p\":1,\"n\":\"MODS - Material Swap\"},{\"t\":5,\"p\":1,\"n\":\"MODC - Color Remapping Index\"},{\"t\":11,\"n\":\"MODF - Unknown\"}]},{\"t\":2,\"p\":1,\"n\":\"ICON - Inventory Image\"},{\"t\":2,\"p\":1,\"n\":\"MICO - Message Icon\"},{\"t\":3,\"p\":1,\"n\":\"YNAM - Sound - Pick Up\"},{\"t\":3,\"p\":1,\"n\":\"ZNAM - Sound - Put Down\"},{\"t\":3,\"p\":1,\"n\":\"ETYP - Equipment Type\"},{\"t\":3,\"p\":1,\"n\":\"CUSD - Sound - Crafting\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Destructible\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"DEST - Header\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Health\"},{\"t\":3,\"p\":1,\"n\":\"DEST Count\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":7,\"p\":1,\"n\":\"DAMC - Resistances\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Resistance\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Damage Type\"},{\"t\":3,\"p\":1,\"n\":\"Value\"}]}]},{\"t\":8,\"p\":1,\"n\":\"Stages\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Stage\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"DSTD - Destruction Stage Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Health %\"},{\"t\":3,\"p\":1,\"n\":\"Index\"},{\"t\":3,\"p\":1,\"n\":\"Model Damage Stage\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":3,\"p\":1,\"n\":\"Self Damage per Second\"},{\"t\":3,\"p\":1,\"n\":\"Explosion\"},{\"t\":3,\"p\":1,\"n\":\"Debris\"},{\"t\":3,\"p\":1,\"n\":\"Debris Count\"}]},{\"t\":2,\"p\":1,\"n\":\"DSTA - Sequence Name\"},{\"t\":6,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"DMDL - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"DMDT - Texture Files Hashes\"},{\"t\":5,\"p\":1,\"n\":\"DMDC - Color Remapping Index\"},{\"t\":3,\"p\":1,\"n\":\"DMDS - Material Swap\"}]},{\"p\":1,\"n\":\"DSTF - End Marker\"}]}]}]},{\"t\":2,\"p\":1,\"n\":\"DESC - Description\"},{\"t\":5,\"p\":1,\"n\":\"DATA - Weight\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"ENIT - Effect Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Value\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":3,\"p\":1,\"n\":\"Addiction\"},{\"t\":5,\"p\":1,\"n\":\"Addiction Chance\"},{\"t\":3,\"p\":1,\"n\":\"Sound - Consume\"}]},{\"t\":2,\"p\":1,\"n\":\"DNAM - Addiction Name\"},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Effects\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Effect\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"EFID - Base Effect\"},{\"t\":6,\"p\":1,\"n\":\"EFIT - \",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Magnitude\"},{\"t\":3,\"p\":1,\"n\":\"Area\"},{\"t\":3,\"p\":1,\"n\":\"Duration\"}]},{\"t\":8,\"p\":1,\"n\":\"Conditions\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Condition\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"CTDA - \",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":5,\"p\":1,\"n\":\"Comparison Value - Float\"},{\"t\":3,\"p\":1,\"n\":\"Comparison Value - Global\"},{\"t\":3,\"p\":1,\"n\":\"Function\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":11,\"p\":1,\"n\":\"None\"},{\"t\":3,\"p\":1,\"n\":\"Integer\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":3,\"p\":1,\"n\":\"Actor\"},{\"t\":3,\"p\":1,\"n\":\"Actor Base\"},{\"t\":3,\"p\":1,\"n\":\"Actor Value\"},{\"t\":3,\"p\":1,\"n\":\"Player Action\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"Alignment\"},{\"t\":3,\"p\":1,\"n\":\"Association Type\"},{\"t\":3,\"p\":1,\"n\":\"Axis\"},{\"t\":3,\"p\":1,\"n\":\"Casting Type\"},{\"t\":3,\"p\":1,\"n\":\"Cell\"},{\"t\":3,\"p\":1,\"n\":\"Class\"},{\"t\":3,\"p\":1,\"n\":\"Crime Type\"},{\"t\":3,\"p\":1,\"n\":\"Critical Stage\"},{\"t\":3,\"p\":1,\"n\":\"Encounter Zone\"},{\"t\":3,\"p\":1,\"n\":\"Equip Type\"},{\"t\":3,\"p\":1,\"n\":\"Event\"},{\"t\":3,\"p\":1,\"n\":\"Event Data\"},{\"t\":3,\"p\":1,\"n\":\"Faction\"},{\"t\":3,\"p\":1,\"n\":\"Form List\"},{\"t\":3,\"p\":1,\"n\":\"Form Type\"},{\"t\":3,\"p\":1,\"n\":\"Furniture\"},{\"t\":3,\"p\":1,\"n\":\"Furniture Anim\"},{\"t\":3,\"p\":1,\"n\":\"Furniture Entry\"},{\"t\":3,\"p\":1,\"n\":\"Global\"},{\"t\":3,\"p\":1,\"n\":\"Idle\"},{\"t\":3,\"p\":1,\"n\":\"Inventory Object\"},{\"t\":3,\"p\":1,\"n\":\"Keyword\"},{\"t\":3,\"p\":1,\"n\":\"Location\"},{\"t\":3,\"p\":1,\"n\":\"Base Effect\"},{\"t\":3,\"p\":1,\"n\":\"Effect Item\"},{\"t\":3,\"p\":1,\"n\":\"Misc Stat\"},{\"t\":3,\"p\":1,\"n\":\"Object Reference\"},{\"t\":3,\"p\":1,\"n\":\"Owner\"},{\"t\":3,\"p\":1,\"n\":\"Package\"},{\"t\":3,\"p\":1,\"n\":\"Packdata ID\"},{\"t\":3,\"p\":1,\"n\":\"Perk\"},{\"t\":3,\"p\":1,\"n\":\"Quest\"},{\"t\":3,\"p\":1,\"n\":\"Quest Stage\"},{\"t\":3,\"p\":1,\"n\":\"Race\"},{\"t\":3,\"p\":1,\"n\":\"Referenceable Object\"},{\"t\":3,\"p\":1,\"n\":\"Location Ref Type\"},{\"t\":3,\"p\":1,\"n\":\"Region\"},{\"t\":3,\"p\":1,\"n\":\"Scene\"},{\"t\":3,\"p\":1,\"n\":\"Sex\"},{\"t\":3,\"p\":1,\"n\":\"Shout\"},{\"t\":11,\"p\":1,\"n\":\"Variable Name (unused)\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Function\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Param (unused)\"},{\"t\":3,\"p\":1,\"n\":\"Voice Type\"},{\"t\":3,\"p\":1,\"n\":\"Ward State\"},{\"t\":3,\"p\":1,\"n\":\"Weather\"},{\"t\":3,\"p\":1,\"n\":\"Worldspace\"},{\"t\":3,\"p\":1,\"n\":\"Damage Type\"},{\"t\":3,\"p\":1,\"n\":\"Weapon\"},{\"t\":3,\"p\":1,\"n\":\"Weapon List\"},{\"t\":3,\"p\":1,\"n\":\"Target\"},{\"t\":3,\"p\":1,\"n\":\"Target List\"},{\"t\":3,\"p\":1,\"n\":\"Target Part\"},{\"t\":3,\"p\":1,\"n\":\"VATS Action\"},{\"t\":3,\"p\":1,\"n\":\"Critical Effect\"},{\"t\":3,\"p\":1,\"n\":\"Critical Effect List\"},{\"t\":3,\"p\":1,\"n\":\"Weapon Type\"},{\"t\":3,\"p\":1,\"n\":\"Projectile Type\"},{\"t\":3,\"p\":1,\"n\":\"Delivery Type\"},{\"t\":3,\"p\":1,\"n\":\"Run On\"},{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":3,\"p\":1,\"n\":\"Parameter #3\"}]},{\"t\":2,\"p\":1,\"n\":\"CIS1 - Parameter #1\"},{\"t\":2,\"p\":1,\"n\":\"CIS2 - Parameter #2\"}]}]}]}]}]},{\"t\":1,\"p\":1,\"n\":\"AMDL - Aim Model\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DNAM - Data\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Cone of Fire - Min Angle\"},{\"t\":5,\"p\":1,\"n\":\"Cone of Fire - Max Angle\"},{\"t\":5,\"p\":1,\"n\":\"Cone of Fire - Increase Per Shot\"},{\"t\":5,\"p\":1,\"n\":\"Cone of Fire - Decrease Per Sec\"},{\"t\":3,\"p\":1,\"n\":\"Cone of Fire - Decrease Delay MS\"},{\"t\":5,\"p\":1,\"n\":\"Cone of Fire - Sneak Mult\"},{\"t\":5,\"p\":1,\"n\":\"Recoil - Diminish Spring Force\"},{\"t\":5,\"p\":1,\"n\":\"Recoil - Diminish Sights Mult\"},{\"t\":5,\"p\":1,\"n\":\"Recoil - Max Per Shot\"},{\"t\":5,\"p\":1,\"n\":\"Recoil - Min Per Shot\"},{\"t\":5,\"p\":1,\"n\":\"Recoil - Hip Mult\"},{\"t\":3,\"p\":1,\"n\":\"Runaway - Recoil Shots\"},{\"t\":5,\"p\":1,\"n\":\"Recoil - Arc\"},{\"t\":5,\"p\":1,\"n\":\"Recoil - Arc Rotate\"},{\"t\":5,\"p\":1,\"n\":\"Cone of Fire - Iron Sights Mult\"},{\"t\":5,\"p\":1,\"n\":\"Stability - Base Stability\"}]}]},{\"t\":1,\"p\":1,\"n\":\"AMMO - Ammunition\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"X1\"},{\"t\":3,\"p\":1,\"n\":\"Y1\"},{\"t\":3,\"p\":1,\"n\":\"Z1\"},{\"t\":3,\"p\":1,\"n\":\"X2\"},{\"t\":3,\"p\":1,\"n\":\"Y2\"},{\"t\":3,\"p\":1,\"n\":\"Z2\"}]},{\"t\":3,\"p\":1,\"n\":\"PTRN - Preview Transform\"},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"MODT - Texture Files Hashes\"},{\"t\":3,\"p\":1,\"n\":\"MODS - Material Swap\"},{\"t\":5,\"p\":1,\"n\":\"MODC - Color Remapping Index\"},{\"t\":11,\"n\":\"MODF - Unknown\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Destructible\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"DEST - Header\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Health\"},{\"t\":3,\"p\":1,\"n\":\"DEST Count\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":7,\"p\":1,\"n\":\"DAMC - Resistances\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Resistance\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Damage Type\"},{\"t\":3,\"p\":1,\"n\":\"Value\"}]}]},{\"t\":8,\"p\":1,\"n\":\"Stages\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Stage\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"DSTD - Destruction Stage Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Health %\"},{\"t\":3,\"p\":1,\"n\":\"Index\"},{\"t\":3,\"p\":1,\"n\":\"Model Damage Stage\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":3,\"p\":1,\"n\":\"Self Damage per Second\"},{\"t\":3,\"p\":1,\"n\":\"Explosion\"},{\"t\":3,\"p\":1,\"n\":\"Debris\"},{\"t\":3,\"p\":1,\"n\":\"Debris Count\"}]},{\"t\":2,\"p\":1,\"n\":\"DSTA - Sequence Name\"},{\"t\":6,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"DMDL - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"DMDT - Texture Files Hashes\"},{\"t\":5,\"p\":1,\"n\":\"DMDC - Color Remapping Index\"},{\"t\":3,\"p\":1,\"n\":\"DMDS - Material Swap\"}]},{\"p\":1,\"n\":\"DSTF - End Marker\"}]}]}]},{\"t\":3,\"p\":1,\"n\":\"YNAM - Sound - Pick Up\"},{\"t\":3,\"p\":1,\"n\":\"ZNAM - Sound - Put Down\"},{\"t\":2,\"p\":1,\"n\":\"DESC - Description\"},{\"t\":3,\"n\":\"KSIZ - Keyword Count\"},{\"t\":7,\"p\":1,\"n\":\"KWDA - Keywords\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Keyword\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DATA - Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Value\"},{\"t\":5,\"p\":1,\"n\":\"Weight\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DNAM - \",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Projectile\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":5,\"p\":1,\"n\":\"Damage\"},{\"t\":3,\"p\":1,\"n\":\"Health\"}]},{\"t\":2,\"p\":1,\"n\":\"ONAM - Short Name\"},{\"t\":2,\"p\":1,\"n\":\"NAM1 - Casing Model\"},{\"t\":11,\"n\":\"NAM2 - Texture Files Hashes\"}]},{\"t\":1,\"p\":1,\"n\":\"ANIO - Animated Object\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"MODT - Texture Files Hashes\"},{\"t\":3,\"p\":1,\"n\":\"MODS - Material Swap\"},{\"t\":5,\"p\":1,\"n\":\"MODC - Color Remapping Index\"},{\"t\":11,\"n\":\"MODF - Unknown\"}]},{\"t\":2,\"p\":1,\"n\":\"BNAM - Unload Event\"}]},{\"t\":1,\"p\":1,\"n\":\"AORU - Attraction Rule\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"AOR2 - Data\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Radius\"},{\"t\":5,\"p\":1,\"n\":\"Min Delay\"},{\"t\":5,\"p\":1,\"n\":\"Max Delay\"},{\"t\":3,\"p\":1,\"n\":\"Requires Line of Sight\"},{\"t\":3,\"p\":1,\"n\":\"Combat Target\"},{\"t\":11,\"n\":\"Unused\"}]}]},{\"t\":1,\"p\":1,\"n\":\"ARMA - Armor Addon\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"BOD2 - Biped Body Template\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"First Person Flags\"}]},{\"t\":3,\"p\":1,\"n\":\"RNAM - Race\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DNAM - Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Male Priority\"},{\"t\":3,\"p\":1,\"n\":\"Female Priority\"},{\"t\":3,\"p\":1,\"n\":\"Weight slider - Male\"},{\"t\":3,\"p\":1,\"n\":\"Weight slider - Female\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":3,\"p\":1,\"n\":\"Detection Sound Value\"},{\"t\":5,\"p\":1,\"n\":\"Weapon Adjust\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Male world model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MOD2 - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"MO2T - Texture Files Hashes\"},{\"t\":3,\"p\":1,\"n\":\"MO2S - Material Swap\"},{\"t\":5,\"p\":1,\"n\":\"MO2C - Color Remapping Index\"},{\"t\":11,\"n\":\"MO2F - Unknown\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Female world model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MOD3 - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"MO3T - Texture Files Hashes\"},{\"t\":3,\"p\":1,\"n\":\"MO3S - Material Swap\"},{\"t\":5,\"p\":1,\"n\":\"MO3C - Color Remapping Index\"},{\"t\":11,\"n\":\"MO3F - Unknown\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Male 1st Person\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MOD4 - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"MO4T - Texture Files Hashes\"},{\"t\":3,\"p\":1,\"n\":\"MO4S - Material Swap\"},{\"t\":5,\"p\":1,\"n\":\"MO4C - Color Remapping Index\"},{\"t\":11,\"n\":\"MO4F - Unknown\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Female 1st Person\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MOD5 - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"MO5T - Texture Files Hashes\"},{\"t\":3,\"p\":1,\"n\":\"MO5S - Material Swap\"},{\"t\":5,\"p\":1,\"n\":\"MO5C - Color Remapping Index\"},{\"t\":11,\"n\":\"MO5F - Unknown\"}]},{\"t\":3,\"p\":1,\"n\":\"NAM0 - Male Skin Texture\"},{\"t\":3,\"p\":1,\"n\":\"NAM1 - Female Skin Texture\"},{\"t\":3,\"p\":1,\"n\":\"NAM2 - Male Skin Texture Swap List\"},{\"t\":3,\"p\":1,\"n\":\"NAM3 - Female Skin Texture Swap List\"},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Additional Races\",\"d\":1,\"c\":[{\"t\":3,\"p\":1,\"n\":\"MODL - Race\"}]},{\"t\":3,\"p\":1,\"n\":\"SNDD - Footstep Sound\"},{\"t\":3,\"p\":1,\"n\":\"ONAM - Art Object\"},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Bone Data\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"BSMP - Gender\"},{\"t\":8,\"p\":1,\"n\":\"Bones\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Bone\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"BSMB - Name\"},{\"t\":7,\"p\":1,\"n\":\"BSMS - Values\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Value\"}]},{\"t\":11,\"n\":\"BMMP - Unknown\"}]}]}]}]}]},{\"t\":1,\"p\":1,\"n\":\"ARMO - Armor\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"VMAD - Virtual Machine Adapter\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Version\"},{\"t\":3,\"p\":1,\"n\":\"Object Format\"},{\"t\":7,\"p\":1,\"n\":\"Scripts\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Script\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"scriptName\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":7,\"p\":1,\"n\":\"Properties\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Property\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"propertyName\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]},{\"t\":2,\"p\":1,\"n\":\"String\"},{\"t\":3,\"p\":1,\"n\":\"Int32\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":3,\"p\":1,\"n\":\"Bool\"},{\"t\":7,\"p\":1,\"n\":\"Struct\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Member\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"memberName\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]},{\"t\":2,\"p\":1,\"n\":\"String\"},{\"t\":3,\"p\":1,\"n\":\"Int32\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":3,\"p\":1,\"n\":\"Bool\"},{\"t\":7,\"p\":1,\"n\":\"Array of Object\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]}]},{\"t\":7,\"p\":1,\"n\":\"Array of String\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Int32\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Float\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Bool\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]}]}]},{\"t\":7,\"p\":1,\"n\":\"Array of Object\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]}]},{\"t\":7,\"p\":1,\"n\":\"Array of String\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Int32\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Float\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Bool\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Struct\",\"c\":[{\"t\":7,\"p\":1,\"n\":\"Struct\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Member\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"memberName\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]},{\"t\":2,\"p\":1,\"n\":\"String\"},{\"t\":3,\"p\":1,\"n\":\"Int32\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":3,\"p\":1,\"n\":\"Bool\"},{\"t\":7,\"p\":1,\"n\":\"Array of Object\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]}]},{\"t\":7,\"p\":1,\"n\":\"Array of String\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Int32\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Float\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Bool\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]}]}]}]}]}]}]}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"X1\"},{\"t\":3,\"p\":1,\"n\":\"Y1\"},{\"t\":3,\"p\":1,\"n\":\"Z1\"},{\"t\":3,\"p\":1,\"n\":\"X2\"},{\"t\":3,\"p\":1,\"n\":\"Y2\"},{\"t\":3,\"p\":1,\"n\":\"Z2\"}]},{\"t\":3,\"p\":1,\"n\":\"PTRN - Preview Transform\"},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":3,\"p\":1,\"n\":\"EITM - Object Effect\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Male world model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MOD2 - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"MO2T - Texture Files Hashes\"},{\"t\":3,\"p\":1,\"n\":\"MO2S - Material Swap\"}]},{\"t\":2,\"p\":1,\"n\":\"ICON - Male Inventory Image\"},{\"t\":2,\"p\":1,\"n\":\"MICO - Male Message Icon\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Female world model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MOD4 - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"MO4T - Texture Files Hashes\"},{\"t\":3,\"p\":1,\"n\":\"MO4S - Material Swap\"}]},{\"t\":2,\"p\":1,\"n\":\"ICO2 - Female Inventory Image\"},{\"t\":2,\"p\":1,\"n\":\"MIC2 - Female Message Icon\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"BOD2 - Biped Body Template\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"First Person Flags\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Destructible\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"DEST - Header\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Health\"},{\"t\":3,\"p\":1,\"n\":\"DEST Count\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":7,\"p\":1,\"n\":\"DAMC - Resistances\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Resistance\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Damage Type\"},{\"t\":3,\"p\":1,\"n\":\"Value\"}]}]},{\"t\":8,\"p\":1,\"n\":\"Stages\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Stage\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"DSTD - Destruction Stage Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Health %\"},{\"t\":3,\"p\":1,\"n\":\"Index\"},{\"t\":3,\"p\":1,\"n\":\"Model Damage Stage\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":3,\"p\":1,\"n\":\"Self Damage per Second\"},{\"t\":3,\"p\":1,\"n\":\"Explosion\"},{\"t\":3,\"p\":1,\"n\":\"Debris\"},{\"t\":3,\"p\":1,\"n\":\"Debris Count\"}]},{\"t\":2,\"p\":1,\"n\":\"DSTA - Sequence Name\"},{\"t\":6,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"DMDL - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"DMDT - Texture Files Hashes\"},{\"t\":5,\"p\":1,\"n\":\"DMDC - Color Remapping Index\"},{\"t\":3,\"p\":1,\"n\":\"DMDS - Material Swap\"}]},{\"p\":1,\"n\":\"DSTF - End Marker\"}]}]}]},{\"t\":3,\"p\":1,\"n\":\"YNAM - Sound - Pick Up\"},{\"t\":3,\"p\":1,\"n\":\"ZNAM - Sound - Put Down\"},{\"t\":3,\"p\":1,\"n\":\"ETYP - Equipment Type\"},{\"t\":3,\"p\":1,\"n\":\"BIDS - Block Bash Impact Data Set\"},{\"t\":3,\"p\":1,\"n\":\"BAMT - Alternate Block Material\"},{\"t\":3,\"p\":1,\"n\":\"RNAM - Race\"},{\"t\":3,\"n\":\"KSIZ - Keyword Count\"},{\"t\":7,\"p\":1,\"n\":\"KWDA - Keywords\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Keyword\"}]},{\"t\":2,\"p\":1,\"n\":\"DESC - Description\"},{\"t\":3,\"p\":1,\"n\":\"INRD - Instance Naming\"},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Models\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"INDX - Addon Index\"},{\"t\":3,\"p\":1,\"n\":\"MODL - Armor Addon\"}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DATA - \",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Value\"},{\"t\":5,\"p\":1,\"n\":\"Weight\"},{\"t\":3,\"p\":1,\"n\":\"Health\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"FNAM - \",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Armor Rating\"},{\"t\":3,\"p\":1,\"n\":\"Base Addon Index\"},{\"t\":3,\"p\":1,\"n\":\"Stagger Rating\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":7,\"p\":1,\"n\":\"DAMA - Resistances\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Resistance\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Damage Type\"},{\"t\":3,\"p\":1,\"n\":\"Value\"}]}]},{\"t\":3,\"p\":1,\"n\":\"TNAM - Template Armor\"},{\"t\":7,\"p\":1,\"n\":\"APPR - Attach Parent Slots\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Keyword\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Object Template\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"OBTE - Count\"},{\"t\":8,\"p\":1,\"n\":\"Combinations\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Combination\",\"c\":[{\"p\":1,\"n\":\"OBTF - Editor Only\"},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":6,\"p\":1,\"n\":\"OBTS - Object Mod Template Item\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Include Count\"},{\"t\":3,\"p\":1,\"n\":\"Property Count\"},{\"t\":3,\"p\":1,\"n\":\"Level Min\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Level Max\"},{\"t\":3,\"p\":1,\"n\":\"ID\"},{\"t\":3,\"p\":1,\"n\":\"Default\"},{\"t\":7,\"p\":1,\"n\":\"Keywords\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Keyword\"}]},{\"t\":3,\"p\":1,\"n\":\"Min Level For Ranks\"},{\"t\":3,\"p\":1,\"n\":\"Alt Levels Per Tier\"},{\"t\":7,\"p\":1,\"n\":\"Includes\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Include\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Mod\"},{\"t\":3,\"p\":1,\"n\":\"Attach Point Index\"},{\"t\":3,\"p\":1,\"n\":\"Optional\"},{\"t\":3,\"p\":1,\"n\":\"Don't Use All\"}]}]},{\"t\":7,\"p\":1,\"n\":\"Properties\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Property\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Value Type\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Function Type\"},{\"t\":3,\"p\":1,\"n\":\"Property\"},{\"t\":11,\"n\":\"Value 1 - Unknown\"},{\"t\":3,\"p\":1,\"n\":\"Value 1 - Int\"},{\"t\":5,\"p\":1,\"n\":\"Value 1 - Float\"},{\"t\":3,\"p\":1,\"n\":\"Value 1 - Bool\"},{\"t\":3,\"p\":1,\"n\":\"Value 1 - FormID\"},{\"t\":3,\"p\":1,\"n\":\"Value 1 - Enum\"},{\"t\":3,\"p\":1,\"n\":\"Sound Level\"},{\"t\":3,\"p\":1,\"n\":\"Stagger Value\"},{\"t\":3,\"p\":1,\"n\":\"Hit Behaviour\"},{\"t\":3,\"p\":1,\"n\":\"Value 2 - Int\"},{\"t\":5,\"p\":1,\"n\":\"Value 2 - Float\"},{\"t\":3,\"p\":1,\"n\":\"Value 2 - Bool\"},{\"t\":5,\"p\":1,\"n\":\"Step\"}]}]}]}]}]},{\"p\":1,\"n\":\"STOP - Marker\"}]}]},{\"t\":1,\"p\":1,\"n\":\"ARTO - Art Object\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"X1\"},{\"t\":3,\"p\":1,\"n\":\"Y1\"},{\"t\":3,\"p\":1,\"n\":\"Z1\"},{\"t\":3,\"p\":1,\"n\":\"X2\"},{\"t\":3,\"p\":1,\"n\":\"Y2\"},{\"t\":3,\"p\":1,\"n\":\"Z2\"}]},{\"t\":3,\"p\":1,\"n\":\"PTRN - Preview Transform\"},{\"t\":3,\"n\":\"KSIZ - Keyword Count\"},{\"t\":7,\"p\":1,\"n\":\"KWDA - Keywords\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Keyword\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"MODT - Texture Files Hashes\"},{\"t\":3,\"p\":1,\"n\":\"MODS - Material Swap\"},{\"t\":5,\"p\":1,\"n\":\"MODC - Color Remapping Index\"},{\"t\":11,\"n\":\"MODF - Unknown\"}]},{\"t\":3,\"p\":1,\"n\":\"DNAM - Art Type\"}]},{\"t\":1,\"p\":1,\"n\":\"ASPC - Acoustic Space\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"X1\"},{\"t\":3,\"p\":1,\"n\":\"Y1\"},{\"t\":3,\"p\":1,\"n\":\"Z1\"},{\"t\":3,\"p\":1,\"n\":\"X2\"},{\"t\":3,\"p\":1,\"n\":\"Y2\"},{\"t\":3,\"p\":1,\"n\":\"Z2\"}]},{\"t\":3,\"p\":1,\"n\":\"SNAM - Looping Sound\"},{\"t\":3,\"p\":1,\"n\":\"RDAT - Use Sound from Region (Interiors Only)\"},{\"t\":3,\"p\":1,\"n\":\"BNAM - Environment Type\"},{\"t\":3,\"p\":1,\"n\":\"XTRI - Is Interior\"},{\"t\":3,\"p\":1,\"n\":\"WNAM - Weather Attenuation (dB)\"}]},{\"t\":1,\"p\":1,\"n\":\"ASTP - Association Type\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"p\":1,\"n\":\"MPRT - Male Parent Title\"},{\"t\":2,\"p\":1,\"n\":\"FPRT - Female Parent Title\"},{\"t\":2,\"p\":1,\"n\":\"MCHT - Male Child Title\"},{\"t\":2,\"p\":1,\"n\":\"FCHT - Female Child Title\"},{\"t\":3,\"p\":1,\"n\":\"DATA - Flags\"}]},{\"t\":1,\"p\":1,\"n\":\"AVIF - Actor Value Information\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":2,\"p\":1,\"n\":\"DESC - Description\"},{\"t\":2,\"p\":1,\"n\":\"ANAM - Abbreviation\"},{\"t\":5,\"p\":1,\"n\":\"NAM0 - Default Value\"},{\"t\":3,\"p\":1,\"n\":\"AVFL - Flags\"},{\"t\":3,\"p\":1,\"n\":\"NAM1 - Type\"}]},{\"t\":1,\"p\":1,\"n\":\"BNDS - Bendable Spline\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"X1\"},{\"t\":3,\"p\":1,\"n\":\"Y1\"},{\"t\":3,\"p\":1,\"n\":\"Z1\"},{\"t\":3,\"p\":1,\"n\":\"X2\"},{\"t\":3,\"p\":1,\"n\":\"Y2\"},{\"t\":3,\"p\":1,\"n\":\"Z2\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DNAM - Data\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Default Number of Tiles\"},{\"t\":3,\"p\":1,\"n\":\"Default Number of Slices\"},{\"t\":3,\"p\":1,\"n\":\"Default Number of Tiles - Relative to Length\"},{\"t\":6,\"p\":1,\"n\":\"Default Color\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Red\"},{\"t\":5,\"p\":1,\"n\":\"Green\"},{\"t\":5,\"p\":1,\"n\":\"Blue\"}]},{\"t\":5,\"p\":1,\"n\":\"Wind Settings - Sensibility\"},{\"t\":5,\"p\":1,\"n\":\"Wind Settings - Flexibility\"}]},{\"t\":3,\"p\":1,\"n\":\"TNAM - Texture\"}]},{\"t\":1,\"p\":1,\"n\":\"BOOK - Book\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"VMAD - Virtual Machine Adapter\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Version\"},{\"t\":3,\"p\":1,\"n\":\"Object Format\"},{\"t\":7,\"p\":1,\"n\":\"Scripts\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Script\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"scriptName\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":7,\"p\":1,\"n\":\"Properties\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Property\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"propertyName\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]},{\"t\":2,\"p\":1,\"n\":\"String\"},{\"t\":3,\"p\":1,\"n\":\"Int32\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":3,\"p\":1,\"n\":\"Bool\"},{\"t\":7,\"p\":1,\"n\":\"Struct\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Member\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"memberName\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]},{\"t\":2,\"p\":1,\"n\":\"String\"},{\"t\":3,\"p\":1,\"n\":\"Int32\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":3,\"p\":1,\"n\":\"Bool\"},{\"t\":7,\"p\":1,\"n\":\"Array of Object\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]}]},{\"t\":7,\"p\":1,\"n\":\"Array of String\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Int32\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Float\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Bool\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]}]}]},{\"t\":7,\"p\":1,\"n\":\"Array of Object\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]}]},{\"t\":7,\"p\":1,\"n\":\"Array of String\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Int32\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Float\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Bool\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Struct\",\"c\":[{\"t\":7,\"p\":1,\"n\":\"Struct\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Member\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"memberName\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]},{\"t\":2,\"p\":1,\"n\":\"String\"},{\"t\":3,\"p\":1,\"n\":\"Int32\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":3,\"p\":1,\"n\":\"Bool\"},{\"t\":7,\"p\":1,\"n\":\"Array of Object\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]}]},{\"t\":7,\"p\":1,\"n\":\"Array of String\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Int32\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Float\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Bool\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]}]}]}]}]}]}]}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"X1\"},{\"t\":3,\"p\":1,\"n\":\"Y1\"},{\"t\":3,\"p\":1,\"n\":\"Z1\"},{\"t\":3,\"p\":1,\"n\":\"X2\"},{\"t\":3,\"p\":1,\"n\":\"Y2\"},{\"t\":3,\"p\":1,\"n\":\"Z2\"}]},{\"t\":3,\"p\":1,\"n\":\"PTRN - Preview Transform\"},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"MODT - Texture Files Hashes\"},{\"t\":3,\"p\":1,\"n\":\"MODS - Material Swap\"},{\"t\":5,\"p\":1,\"n\":\"MODC - Color Remapping Index\"},{\"t\":11,\"n\":\"MODF - Unknown\"}]},{\"t\":2,\"p\":1,\"n\":\"ICON - Inventory Image\"},{\"t\":2,\"p\":1,\"n\":\"MICO - Message Icon\"},{\"t\":2,\"p\":1,\"n\":\"DESC - Description\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Destructible\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"DEST - Header\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Health\"},{\"t\":3,\"p\":1,\"n\":\"DEST Count\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":7,\"p\":1,\"n\":\"DAMC - Resistances\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Resistance\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Damage Type\"},{\"t\":3,\"p\":1,\"n\":\"Value\"}]}]},{\"t\":8,\"p\":1,\"n\":\"Stages\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Stage\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"DSTD - Destruction Stage Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Health %\"},{\"t\":3,\"p\":1,\"n\":\"Index\"},{\"t\":3,\"p\":1,\"n\":\"Model Damage Stage\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":3,\"p\":1,\"n\":\"Self Damage per Second\"},{\"t\":3,\"p\":1,\"n\":\"Explosion\"},{\"t\":3,\"p\":1,\"n\":\"Debris\"},{\"t\":3,\"p\":1,\"n\":\"Debris Count\"}]},{\"t\":2,\"p\":1,\"n\":\"DSTA - Sequence Name\"},{\"t\":6,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"DMDL - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"DMDT - Texture Files Hashes\"},{\"t\":5,\"p\":1,\"n\":\"DMDC - Color Remapping Index\"},{\"t\":3,\"p\":1,\"n\":\"DMDS - Material Swap\"}]},{\"p\":1,\"n\":\"DSTF - End Marker\"}]}]}]},{\"t\":3,\"p\":1,\"n\":\"YNAM - Sound - Pick Up\"},{\"t\":3,\"p\":1,\"n\":\"ZNAM - Sound - Put Down\"},{\"t\":3,\"n\":\"KSIZ - Keyword Count\"},{\"t\":7,\"p\":1,\"n\":\"KWDA - Keywords\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Keyword\"}]},{\"t\":3,\"p\":1,\"n\":\"FIMD - Featured Item Message\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DATA - Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Value\"},{\"t\":5,\"p\":1,\"n\":\"Weight\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DNAM - \",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Actor Value\"},{\"t\":3,\"p\":1,\"n\":\"Spell\"},{\"t\":3,\"p\":1,\"n\":\"Perk\"},{\"t\":6,\"p\":1,\"n\":\"Text Offset\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"X\"},{\"t\":3,\"p\":1,\"n\":\"Y\"}]}]},{\"t\":2,\"p\":1,\"n\":\"CNAM - Description\"},{\"t\":3,\"p\":1,\"n\":\"INAM - Inventory Art\"}]},{\"t\":1,\"p\":1,\"n\":\"BPTD - Body Part Data\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"MODT - Texture Files Hashes\"},{\"t\":3,\"p\":1,\"n\":\"MODS - Material Swap\"},{\"t\":5,\"p\":1,\"n\":\"MODC - Color Remapping Index\"},{\"t\":11,\"n\":\"MODF - Unknown\"}]},{\"t\":10,\"p\":1,\"n\":\"Body Parts\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Body Part\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"BPTN - Part Name\"},{\"t\":2,\"p\":1,\"n\":\"BPNN - Part Node\"},{\"t\":2,\"p\":1,\"n\":\"BPNT - VATS Target\"},{\"t\":6,\"p\":1,\"n\":\"BPND - \",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Damage Mult\"},{\"t\":3,\"p\":1,\"n\":\"Explodable - Debris\"},{\"t\":3,\"p\":1,\"n\":\"Explodable - Explosion\"},{\"t\":5,\"p\":1,\"n\":\"Explodable - Debris Scale\"},{\"t\":3,\"p\":1,\"n\":\"Severable - Debris\"},{\"t\":3,\"p\":1,\"n\":\"Severable - Explosion\"},{\"t\":5,\"p\":1,\"n\":\"Severable - Debris Scale\"},{\"t\":5,\"p\":1,\"n\":\"Cut - Min\"},{\"t\":5,\"p\":1,\"n\":\"Cut - Max\"},{\"t\":5,\"p\":1,\"n\":\"Cut - Radius\"},{\"t\":5,\"p\":1,\"n\":\"Gore Effects - Local Rotate X\"},{\"t\":5,\"p\":1,\"n\":\"Gore Effects - Local Rotate Y\"},{\"t\":5,\"p\":1,\"n\":\"Cut - Tesselation\"},{\"t\":3,\"p\":1,\"n\":\"Severable - Impact DataSet\"},{\"t\":3,\"p\":1,\"n\":\"Explodable - Impact DataSet\"},{\"t\":5,\"p\":1,\"n\":\"Explodable - Limb Replacement Scale\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":3,\"p\":1,\"n\":\"Part Type\"},{\"t\":3,\"p\":1,\"n\":\"Health Percent\"},{\"t\":3,\"p\":1,\"n\":\"Actor Value\"},{\"t\":3,\"p\":1,\"n\":\"To Hit Chance\"},{\"t\":3,\"p\":1,\"n\":\"Explodable - Explosion Chance %\"},{\"t\":3,\"p\":1,\"n\":\"Non-Lethal Dismemberment Chance\"},{\"t\":3,\"p\":1,\"n\":\"Severable - Debris Count\"},{\"t\":3,\"p\":1,\"n\":\"Explodable - Debris Count\"},{\"t\":3,\"p\":1,\"n\":\"Severable - Decal Count\"},{\"t\":3,\"p\":1,\"n\":\"Explodable - Decal Count\"},{\"t\":3,\"p\":1,\"n\":\"Geometry Segment Index\"},{\"t\":3,\"p\":1,\"n\":\"On Cripple - Art Object\"},{\"t\":3,\"p\":1,\"n\":\"On Cripple - Debris\"},{\"t\":3,\"p\":1,\"n\":\"On Cripple - Explosion\"},{\"t\":3,\"p\":1,\"n\":\"On Cripple - Impact DataSet\"},{\"t\":5,\"p\":1,\"n\":\"On Cripple - Debris Scale\"},{\"t\":3,\"p\":1,\"n\":\"On Cripple - Debris Count\"},{\"t\":3,\"p\":1,\"n\":\"On Cripple - Decal Count\"}]},{\"t\":2,\"p\":1,\"n\":\"NAM1 - Limb Replacement Model\"},{\"t\":2,\"p\":1,\"n\":\"NAM4 - Gore Effects - Target Bone\"},{\"t\":11,\"p\":1,\"n\":\"NAM5 - Texture Files Hashes\"},{\"t\":2,\"p\":1,\"n\":\"ENAM - Hit Reaction - Start\"},{\"t\":2,\"p\":1,\"n\":\"FNAM - Hit Reaction - End\"},{\"t\":3,\"p\":1,\"n\":\"BNAM - Gore Effects - Dismember Blood Art\"},{\"t\":3,\"p\":1,\"n\":\"INAM - Gore Effects - Blood Impact Material Type\"},{\"t\":3,\"p\":1,\"n\":\"JNAM - On Cripple - Blood Impact Material Type\"},{\"t\":3,\"p\":1,\"n\":\"CNAM - Meat Cap TextureSet\"},{\"t\":3,\"p\":1,\"n\":\"NAM2 - Collar TextureSet\"},{\"t\":2,\"p\":1,\"n\":\"DNAM - Twist Variable Prefix\"}]}]}]},{\"t\":1,\"p\":1,\"n\":\"CAMS - Camera Shot\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"MODT - Texture Files Hashes\"},{\"t\":3,\"p\":1,\"n\":\"MODS - Material Swap\"},{\"t\":5,\"p\":1,\"n\":\"MODC - Color Remapping Index\"},{\"t\":11,\"n\":\"MODF - Unknown\"}]},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Conditions\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Condition\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"CTDA - \",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":5,\"p\":1,\"n\":\"Comparison Value - Float\"},{\"t\":3,\"p\":1,\"n\":\"Comparison Value - Global\"},{\"t\":3,\"p\":1,\"n\":\"Function\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":11,\"p\":1,\"n\":\"None\"},{\"t\":3,\"p\":1,\"n\":\"Integer\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":3,\"p\":1,\"n\":\"Actor\"},{\"t\":3,\"p\":1,\"n\":\"Actor Base\"},{\"t\":3,\"p\":1,\"n\":\"Actor Value\"},{\"t\":3,\"p\":1,\"n\":\"Player Action\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"Alignment\"},{\"t\":3,\"p\":1,\"n\":\"Association Type\"},{\"t\":3,\"p\":1,\"n\":\"Axis\"},{\"t\":3,\"p\":1,\"n\":\"Casting Type\"},{\"t\":3,\"p\":1,\"n\":\"Cell\"},{\"t\":3,\"p\":1,\"n\":\"Class\"},{\"t\":3,\"p\":1,\"n\":\"Crime Type\"},{\"t\":3,\"p\":1,\"n\":\"Critical Stage\"},{\"t\":3,\"p\":1,\"n\":\"Encounter Zone\"},{\"t\":3,\"p\":1,\"n\":\"Equip Type\"},{\"t\":3,\"p\":1,\"n\":\"Event\"},{\"t\":3,\"p\":1,\"n\":\"Event Data\"},{\"t\":3,\"p\":1,\"n\":\"Faction\"},{\"t\":3,\"p\":1,\"n\":\"Form List\"},{\"t\":3,\"p\":1,\"n\":\"Form Type\"},{\"t\":3,\"p\":1,\"n\":\"Furniture\"},{\"t\":3,\"p\":1,\"n\":\"Furniture Anim\"},{\"t\":3,\"p\":1,\"n\":\"Furniture Entry\"},{\"t\":3,\"p\":1,\"n\":\"Global\"},{\"t\":3,\"p\":1,\"n\":\"Idle\"},{\"t\":3,\"p\":1,\"n\":\"Inventory Object\"},{\"t\":3,\"p\":1,\"n\":\"Keyword\"},{\"t\":3,\"p\":1,\"n\":\"Location\"},{\"t\":3,\"p\":1,\"n\":\"Base Effect\"},{\"t\":3,\"p\":1,\"n\":\"Effect Item\"},{\"t\":3,\"p\":1,\"n\":\"Misc Stat\"},{\"t\":3,\"p\":1,\"n\":\"Object Reference\"},{\"t\":3,\"p\":1,\"n\":\"Owner\"},{\"t\":3,\"p\":1,\"n\":\"Package\"},{\"t\":3,\"p\":1,\"n\":\"Packdata ID\"},{\"t\":3,\"p\":1,\"n\":\"Perk\"},{\"t\":3,\"p\":1,\"n\":\"Quest\"},{\"t\":3,\"p\":1,\"n\":\"Quest Stage\"},{\"t\":3,\"p\":1,\"n\":\"Race\"},{\"t\":3,\"p\":1,\"n\":\"Referenceable Object\"},{\"t\":3,\"p\":1,\"n\":\"Location Ref Type\"},{\"t\":3,\"p\":1,\"n\":\"Region\"},{\"t\":3,\"p\":1,\"n\":\"Scene\"},{\"t\":3,\"p\":1,\"n\":\"Sex\"},{\"t\":3,\"p\":1,\"n\":\"Shout\"},{\"t\":11,\"p\":1,\"n\":\"Variable Name (unused)\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Function\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Param (unused)\"},{\"t\":3,\"p\":1,\"n\":\"Voice Type\"},{\"t\":3,\"p\":1,\"n\":\"Ward State\"},{\"t\":3,\"p\":1,\"n\":\"Weather\"},{\"t\":3,\"p\":1,\"n\":\"Worldspace\"},{\"t\":3,\"p\":1,\"n\":\"Damage Type\"},{\"t\":3,\"p\":1,\"n\":\"Weapon\"},{\"t\":3,\"p\":1,\"n\":\"Weapon List\"},{\"t\":3,\"p\":1,\"n\":\"Target\"},{\"t\":3,\"p\":1,\"n\":\"Target List\"},{\"t\":3,\"p\":1,\"n\":\"Target Part\"},{\"t\":3,\"p\":1,\"n\":\"VATS Action\"},{\"t\":3,\"p\":1,\"n\":\"Critical Effect\"},{\"t\":3,\"p\":1,\"n\":\"Critical Effect List\"},{\"t\":3,\"p\":1,\"n\":\"Weapon Type\"},{\"t\":3,\"p\":1,\"n\":\"Projectile Type\"},{\"t\":3,\"p\":1,\"n\":\"Delivery Type\"},{\"t\":3,\"p\":1,\"n\":\"Run On\"},{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":3,\"p\":1,\"n\":\"Parameter #3\"}]},{\"t\":2,\"p\":1,\"n\":\"CIS1 - Parameter #1\"},{\"t\":2,\"p\":1,\"n\":\"CIS2 - Parameter #2\"}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DATA - Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Action\"},{\"t\":3,\"p\":1,\"n\":\"Location\"},{\"t\":3,\"p\":1,\"n\":\"Target\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":6,\"p\":1,\"n\":\"Time Multipliers\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Player\"},{\"t\":5,\"p\":1,\"n\":\"Target\"},{\"t\":5,\"p\":1,\"n\":\"Global\"}]},{\"t\":5,\"p\":1,\"n\":\"Max Time\"},{\"t\":5,\"p\":1,\"n\":\"Min Time\"},{\"t\":5,\"p\":1,\"n\":\"Target % Between Actors\"},{\"t\":5,\"p\":1,\"n\":\"Near Target Distance\"},{\"t\":5,\"p\":1,\"n\":\"Location Spring\"},{\"t\":5,\"p\":1,\"n\":\"Target Spring\"},{\"t\":6,\"p\":1,\"n\":\"Rotation Offset\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"X\"},{\"t\":5,\"p\":1,\"n\":\"Y\"},{\"t\":5,\"p\":1,\"n\":\"Z\"}]}]},{\"t\":3,\"p\":1,\"n\":\"MNAM - Image Space Modifier\"}]},{\"t\":1,\"p\":1,\"n\":\"CELL - Cell\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":3,\"p\":1,\"n\":\"DATA - Flags\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"XCLC - Grid\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"X\"},{\"t\":3,\"p\":1,\"n\":\"Y\"},{\"t\":3,\"p\":1,\"n\":\"Force Hide Land\"}]},{\"t\":11,\"n\":\"VISI - PreVis Files Timestamp\"},{\"t\":3,\"p\":1,\"n\":\"RVIS - In PreVis File Of\"},{\"t\":11,\"n\":\"PCMB - PreCombined Files Timestamp\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"XCLL - Lighting\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Ambient Color\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Directional Color\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Fog Color Near\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":5,\"p\":1,\"n\":\"Fog Near\"},{\"t\":5,\"p\":1,\"n\":\"Fog Far\"},{\"t\":3,\"p\":1,\"n\":\"Directional Rotation XY\"},{\"t\":3,\"p\":1,\"n\":\"Directional Rotation Z\"},{\"t\":5,\"p\":1,\"n\":\"Directional Fade\"},{\"t\":5,\"p\":1,\"n\":\"Fog Clip Distance\"},{\"t\":5,\"p\":1,\"n\":\"Fog Power\"},{\"t\":6,\"p\":1,\"n\":\"Directional Ambient Lighting Colors\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Directional\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"X+\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"X-\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Y+\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Y-\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Z+\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Z-\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]}]},{\"t\":6,\"p\":1,\"n\":\"Specular\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":5,\"p\":1,\"n\":\"Scale\"}]},{\"t\":6,\"p\":1,\"n\":\"Fog Color Far\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":5,\"p\":1,\"n\":\"Fog Max\"},{\"t\":5,\"p\":1,\"n\":\"Light Fade Begin\"},{\"t\":5,\"p\":1,\"n\":\"Light Fade End\"},{\"t\":3,\"p\":1,\"n\":\"Inherits\"},{\"t\":5,\"p\":1,\"n\":\"Near Height Mid\"},{\"t\":5,\"p\":1,\"n\":\"Near Height Range\"},{\"t\":6,\"p\":1,\"n\":\"Fog Color High Near\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Fog Color High Far\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":5,\"p\":1,\"n\":\"High Density Scale\"},{\"t\":5,\"p\":1,\"n\":\"Fog Near Scale\"},{\"t\":5,\"p\":1,\"n\":\"Fog Far Scale\"},{\"t\":5,\"p\":1,\"n\":\"Fog High Near Scale\"},{\"t\":5,\"p\":1,\"n\":\"Fog High Far Scale\"},{\"t\":5,\"p\":1,\"n\":\"Far Height Mid\"},{\"t\":5,\"p\":1,\"n\":\"Far Height Range\"}]},{\"t\":3,\"p\":1,\"n\":\"CNAM - Precombined Object Level XY\"},{\"t\":3,\"p\":1,\"n\":\"ZNAM - Precombined Object Level Z\"},{\"t\":11,\"n\":\"TVDT - Unknown\"},{\"t\":11,\"n\":\"MHDT - Max Height Data\"},{\"t\":3,\"p\":1,\"n\":\"LTMP - Lighting Template\"},{\"t\":5,\"p\":1,\"n\":\"XCLW - Water Height\"},{\"t\":7,\"p\":1,\"n\":\"XCLR - Regions\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Region\"}]},{\"t\":3,\"p\":1,\"n\":\"XLCN - Location\"},{\"t\":11,\"n\":\"XWCN - Unknown\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"XWCU - Water Velocity\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"X Offset\"},{\"t\":5,\"p\":1,\"n\":\"Y Offset\"},{\"t\":5,\"p\":1,\"n\":\"Z Offset\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":5,\"p\":1,\"n\":\"X Angle\"},{\"t\":5,\"p\":1,\"n\":\"Y Angle\"},{\"t\":5,\"p\":1,\"n\":\"Z Angle\"}]},{\"t\":3,\"p\":1,\"n\":\"XCWT - Water\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"XOWN - Owner\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Owner\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"}]},{\"t\":3,\"p\":1,\"n\":\"XRNK - Owner Faction Rank\"},{\"t\":3,\"p\":1,\"n\":\"XILL - Lock List\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"XILW - Exterior LOD\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Worldspace\"},{\"t\":5,\"p\":1,\"n\":\"Offset X\"},{\"t\":5,\"p\":1,\"n\":\"Offset Y\"},{\"t\":5,\"p\":1,\"n\":\"Offset Z\"}]},{\"t\":2,\"p\":1,\"n\":\"XWEM - Water Environment Map\"},{\"t\":3,\"p\":1,\"n\":\"XCCM - Sky\\/Weather from Region\"},{\"t\":3,\"p\":1,\"n\":\"XCAS - Acoustic Space\"},{\"t\":3,\"p\":1,\"n\":\"XEZN - Encounter Zone\"},{\"t\":3,\"p\":1,\"n\":\"XCMO - Music Type\"},{\"t\":3,\"p\":1,\"n\":\"XCIM - Image Space\"},{\"t\":3,\"p\":1,\"n\":\"XGDR - God Rays\"},{\"t\":7,\"p\":1,\"n\":\"XPRI - Physics References\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Reference\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"XCRI - Combined References\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Meshes Count\"},{\"t\":3,\"p\":1,\"n\":\"References Count\"},{\"t\":7,\"p\":1,\"n\":\"Meshes\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Combined Mesh\"}]},{\"t\":7,\"p\":1,\"n\":\"References\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Reference\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":3,\"p\":1,\"n\":\"Combined Mesh\"}]}]}]}]},{\"t\":1,\"p\":1,\"n\":\"CLAS - Class\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":2,\"p\":1,\"n\":\"DESC - Description\"},{\"t\":2,\"p\":1,\"n\":\"ICON - Inventory Image\"},{\"t\":7,\"p\":1,\"n\":\"PRPS - Properties\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Property\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Actor Value\"},{\"t\":5,\"p\":1,\"n\":\"Value\"}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DATA - Data\",\"c\":[{\"t\":11,\"n\":\"Unknown\"},{\"t\":5,\"p\":1,\"n\":\"Bleedout Default\"}]}]},{\"t\":1,\"p\":1,\"n\":\"CLFM - Color\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":3,\"p\":1,\"n\":\"CNAM - Color\\/Index\"},{\"t\":3,\"p\":1,\"n\":\"FNAM - Flags\"},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Conditions\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Condition\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"CTDA - \",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":5,\"p\":1,\"n\":\"Comparison Value - Float\"},{\"t\":3,\"p\":1,\"n\":\"Comparison Value - Global\"},{\"t\":3,\"p\":1,\"n\":\"Function\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":11,\"p\":1,\"n\":\"None\"},{\"t\":3,\"p\":1,\"n\":\"Integer\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":3,\"p\":1,\"n\":\"Actor\"},{\"t\":3,\"p\":1,\"n\":\"Actor Base\"},{\"t\":3,\"p\":1,\"n\":\"Actor Value\"},{\"t\":3,\"p\":1,\"n\":\"Player Action\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"Alignment\"},{\"t\":3,\"p\":1,\"n\":\"Association Type\"},{\"t\":3,\"p\":1,\"n\":\"Axis\"},{\"t\":3,\"p\":1,\"n\":\"Casting Type\"},{\"t\":3,\"p\":1,\"n\":\"Cell\"},{\"t\":3,\"p\":1,\"n\":\"Class\"},{\"t\":3,\"p\":1,\"n\":\"Crime Type\"},{\"t\":3,\"p\":1,\"n\":\"Critical Stage\"},{\"t\":3,\"p\":1,\"n\":\"Encounter Zone\"},{\"t\":3,\"p\":1,\"n\":\"Equip Type\"},{\"t\":3,\"p\":1,\"n\":\"Event\"},{\"t\":3,\"p\":1,\"n\":\"Event Data\"},{\"t\":3,\"p\":1,\"n\":\"Faction\"},{\"t\":3,\"p\":1,\"n\":\"Form List\"},{\"t\":3,\"p\":1,\"n\":\"Form Type\"},{\"t\":3,\"p\":1,\"n\":\"Furniture\"},{\"t\":3,\"p\":1,\"n\":\"Furniture Anim\"},{\"t\":3,\"p\":1,\"n\":\"Furniture Entry\"},{\"t\":3,\"p\":1,\"n\":\"Global\"},{\"t\":3,\"p\":1,\"n\":\"Idle\"},{\"t\":3,\"p\":1,\"n\":\"Inventory Object\"},{\"t\":3,\"p\":1,\"n\":\"Keyword\"},{\"t\":3,\"p\":1,\"n\":\"Location\"},{\"t\":3,\"p\":1,\"n\":\"Base Effect\"},{\"t\":3,\"p\":1,\"n\":\"Effect Item\"},{\"t\":3,\"p\":1,\"n\":\"Misc Stat\"},{\"t\":3,\"p\":1,\"n\":\"Object Reference\"},{\"t\":3,\"p\":1,\"n\":\"Owner\"},{\"t\":3,\"p\":1,\"n\":\"Package\"},{\"t\":3,\"p\":1,\"n\":\"Packdata ID\"},{\"t\":3,\"p\":1,\"n\":\"Perk\"},{\"t\":3,\"p\":1,\"n\":\"Quest\"},{\"t\":3,\"p\":1,\"n\":\"Quest Stage\"},{\"t\":3,\"p\":1,\"n\":\"Race\"},{\"t\":3,\"p\":1,\"n\":\"Referenceable Object\"},{\"t\":3,\"p\":1,\"n\":\"Location Ref Type\"},{\"t\":3,\"p\":1,\"n\":\"Region\"},{\"t\":3,\"p\":1,\"n\":\"Scene\"},{\"t\":3,\"p\":1,\"n\":\"Sex\"},{\"t\":3,\"p\":1,\"n\":\"Shout\"},{\"t\":11,\"p\":1,\"n\":\"Variable Name (unused)\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Function\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Param (unused)\"},{\"t\":3,\"p\":1,\"n\":\"Voice Type\"},{\"t\":3,\"p\":1,\"n\":\"Ward State\"},{\"t\":3,\"p\":1,\"n\":\"Weather\"},{\"t\":3,\"p\":1,\"n\":\"Worldspace\"},{\"t\":3,\"p\":1,\"n\":\"Damage Type\"},{\"t\":3,\"p\":1,\"n\":\"Weapon\"},{\"t\":3,\"p\":1,\"n\":\"Weapon List\"},{\"t\":3,\"p\":1,\"n\":\"Target\"},{\"t\":3,\"p\":1,\"n\":\"Target List\"},{\"t\":3,\"p\":1,\"n\":\"Target Part\"},{\"t\":3,\"p\":1,\"n\":\"VATS Action\"},{\"t\":3,\"p\":1,\"n\":\"Critical Effect\"},{\"t\":3,\"p\":1,\"n\":\"Critical Effect List\"},{\"t\":3,\"p\":1,\"n\":\"Weapon Type\"},{\"t\":3,\"p\":1,\"n\":\"Projectile Type\"},{\"t\":3,\"p\":1,\"n\":\"Delivery Type\"},{\"t\":3,\"p\":1,\"n\":\"Run On\"},{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":3,\"p\":1,\"n\":\"Parameter #3\"}]},{\"t\":2,\"p\":1,\"n\":\"CIS1 - Parameter #1\"},{\"t\":2,\"p\":1,\"n\":\"CIS2 - Parameter #2\"}]}]}]},{\"t\":1,\"p\":1,\"n\":\"CLMT - Climate\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":7,\"p\":1,\"n\":\"WLST - Weather Types\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Weather Type\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Weather\"},{\"t\":3,\"p\":1,\"n\":\"Chance\"},{\"t\":3,\"p\":1,\"n\":\"Global\"}]}]},{\"t\":2,\"p\":1,\"n\":\"FNAM - Sun Texture\"},{\"t\":2,\"p\":1,\"n\":\"GNAM - Sun Glare Texture\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"MODT - Texture Files Hashes\"},{\"t\":3,\"p\":1,\"n\":\"MODS - Material Swap\"},{\"t\":5,\"p\":1,\"n\":\"MODC - Color Remapping Index\"},{\"t\":11,\"n\":\"MODF - Unknown\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"TNAM - Timing\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Sunrise\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Begin\"},{\"t\":3,\"p\":1,\"n\":\"End\"}]},{\"t\":6,\"p\":1,\"n\":\"Sunset\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Begin\"},{\"t\":3,\"p\":1,\"n\":\"End\"}]},{\"t\":3,\"p\":1,\"n\":\"Volatility\"},{\"t\":3,\"p\":1,\"n\":\"Moons \\/ Phase Length\"}]}]},{\"t\":1,\"p\":1,\"n\":\"CMPO - Component\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"X1\"},{\"t\":3,\"p\":1,\"n\":\"Y1\"},{\"t\":3,\"p\":1,\"n\":\"Z1\"},{\"t\":3,\"p\":1,\"n\":\"X2\"},{\"t\":3,\"p\":1,\"n\":\"Y2\"},{\"t\":3,\"p\":1,\"n\":\"Z2\"}]},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":3,\"p\":1,\"n\":\"CUSD - Sound - Crafting\"},{\"t\":3,\"p\":1,\"n\":\"DATA - Auto Calc Value\"},{\"t\":3,\"p\":1,\"n\":\"MNAM - Scrap Item\"},{\"t\":3,\"p\":1,\"n\":\"GNAM - Mod Scrap Scalar\"}]},{\"t\":1,\"p\":1,\"n\":\"COBJ - Constructible Object\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":3,\"p\":1,\"n\":\"YNAM - Sound - Pick Up\"},{\"t\":3,\"p\":1,\"n\":\"ZNAM - Sound - Put Down\"},{\"t\":7,\"p\":1,\"n\":\"FVPA - Components\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Component\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Component\"},{\"t\":3,\"p\":1,\"n\":\"Count\"}]}]},{\"t\":2,\"p\":1,\"n\":\"DESC - Description\"},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Conditions\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Condition\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"CTDA - \",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":5,\"p\":1,\"n\":\"Comparison Value - Float\"},{\"t\":3,\"p\":1,\"n\":\"Comparison Value - Global\"},{\"t\":3,\"p\":1,\"n\":\"Function\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":11,\"p\":1,\"n\":\"None\"},{\"t\":3,\"p\":1,\"n\":\"Integer\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":3,\"p\":1,\"n\":\"Actor\"},{\"t\":3,\"p\":1,\"n\":\"Actor Base\"},{\"t\":3,\"p\":1,\"n\":\"Actor Value\"},{\"t\":3,\"p\":1,\"n\":\"Player Action\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"Alignment\"},{\"t\":3,\"p\":1,\"n\":\"Association Type\"},{\"t\":3,\"p\":1,\"n\":\"Axis\"},{\"t\":3,\"p\":1,\"n\":\"Casting Type\"},{\"t\":3,\"p\":1,\"n\":\"Cell\"},{\"t\":3,\"p\":1,\"n\":\"Class\"},{\"t\":3,\"p\":1,\"n\":\"Crime Type\"},{\"t\":3,\"p\":1,\"n\":\"Critical Stage\"},{\"t\":3,\"p\":1,\"n\":\"Encounter Zone\"},{\"t\":3,\"p\":1,\"n\":\"Equip Type\"},{\"t\":3,\"p\":1,\"n\":\"Event\"},{\"t\":3,\"p\":1,\"n\":\"Event Data\"},{\"t\":3,\"p\":1,\"n\":\"Faction\"},{\"t\":3,\"p\":1,\"n\":\"Form List\"},{\"t\":3,\"p\":1,\"n\":\"Form Type\"},{\"t\":3,\"p\":1,\"n\":\"Furniture\"},{\"t\":3,\"p\":1,\"n\":\"Furniture Anim\"},{\"t\":3,\"p\":1,\"n\":\"Furniture Entry\"},{\"t\":3,\"p\":1,\"n\":\"Global\"},{\"t\":3,\"p\":1,\"n\":\"Idle\"},{\"t\":3,\"p\":1,\"n\":\"Inventory Object\"},{\"t\":3,\"p\":1,\"n\":\"Keyword\"},{\"t\":3,\"p\":1,\"n\":\"Location\"},{\"t\":3,\"p\":1,\"n\":\"Base Effect\"},{\"t\":3,\"p\":1,\"n\":\"Effect Item\"},{\"t\":3,\"p\":1,\"n\":\"Misc Stat\"},{\"t\":3,\"p\":1,\"n\":\"Object Reference\"},{\"t\":3,\"p\":1,\"n\":\"Owner\"},{\"t\":3,\"p\":1,\"n\":\"Package\"},{\"t\":3,\"p\":1,\"n\":\"Packdata ID\"},{\"t\":3,\"p\":1,\"n\":\"Perk\"},{\"t\":3,\"p\":1,\"n\":\"Quest\"},{\"t\":3,\"p\":1,\"n\":\"Quest Stage\"},{\"t\":3,\"p\":1,\"n\":\"Race\"},{\"t\":3,\"p\":1,\"n\":\"Referenceable Object\"},{\"t\":3,\"p\":1,\"n\":\"Location Ref Type\"},{\"t\":3,\"p\":1,\"n\":\"Region\"},{\"t\":3,\"p\":1,\"n\":\"Scene\"},{\"t\":3,\"p\":1,\"n\":\"Sex\"},{\"t\":3,\"p\":1,\"n\":\"Shout\"},{\"t\":11,\"p\":1,\"n\":\"Variable Name (unused)\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Function\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Param (unused)\"},{\"t\":3,\"p\":1,\"n\":\"Voice Type\"},{\"t\":3,\"p\":1,\"n\":\"Ward State\"},{\"t\":3,\"p\":1,\"n\":\"Weather\"},{\"t\":3,\"p\":1,\"n\":\"Worldspace\"},{\"t\":3,\"p\":1,\"n\":\"Damage Type\"},{\"t\":3,\"p\":1,\"n\":\"Weapon\"},{\"t\":3,\"p\":1,\"n\":\"Weapon List\"},{\"t\":3,\"p\":1,\"n\":\"Target\"},{\"t\":3,\"p\":1,\"n\":\"Target List\"},{\"t\":3,\"p\":1,\"n\":\"Target Part\"},{\"t\":3,\"p\":1,\"n\":\"VATS Action\"},{\"t\":3,\"p\":1,\"n\":\"Critical Effect\"},{\"t\":3,\"p\":1,\"n\":\"Critical Effect List\"},{\"t\":3,\"p\":1,\"n\":\"Weapon Type\"},{\"t\":3,\"p\":1,\"n\":\"Projectile Type\"},{\"t\":3,\"p\":1,\"n\":\"Delivery Type\"},{\"t\":3,\"p\":1,\"n\":\"Run On\"},{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":3,\"p\":1,\"n\":\"Parameter #3\"}]},{\"t\":2,\"p\":1,\"n\":\"CIS1 - Parameter #1\"},{\"t\":2,\"p\":1,\"n\":\"CIS2 - Parameter #2\"}]}]},{\"t\":3,\"p\":1,\"n\":\"CNAM - Created Object\"},{\"t\":3,\"p\":1,\"n\":\"BNAM - Workbench Keyword\"},{\"t\":11,\"n\":\"NAM1 - Unused\"},{\"t\":11,\"n\":\"NAM2 - Unused\"},{\"t\":11,\"n\":\"NAM3 - Unused\"},{\"t\":3,\"p\":1,\"n\":\"ANAM - Menu Art Object\"},{\"t\":7,\"p\":1,\"n\":\"FNAM - Category\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Keyword\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"INTV - Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Created Object Count\"},{\"t\":3,\"p\":1,\"n\":\"Priority\"}]}]},{\"t\":1,\"p\":1,\"n\":\"COLL - Collision Layer\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"p\":1,\"n\":\"DESC - Description\"},{\"t\":3,\"p\":1,\"n\":\"BNAM - Index\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"FNAM - Debug Color\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":3,\"n\":\"Unused\"}]},{\"t\":3,\"p\":1,\"n\":\"GNAM - Flags\"},{\"t\":2,\"p\":1,\"n\":\"MNAM - Name\"},{\"t\":3,\"n\":\"INTV - Interactables Count\"},{\"t\":7,\"p\":1,\"n\":\"CNAM - Collides With\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Forms\"}]}]},{\"t\":1,\"p\":1,\"n\":\"CONT - Container\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"VMAD - Virtual Machine Adapter\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Version\"},{\"t\":3,\"p\":1,\"n\":\"Object Format\"},{\"t\":7,\"p\":1,\"n\":\"Scripts\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Script\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"scriptName\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":7,\"p\":1,\"n\":\"Properties\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Property\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"propertyName\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]},{\"t\":2,\"p\":1,\"n\":\"String\"},{\"t\":3,\"p\":1,\"n\":\"Int32\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":3,\"p\":1,\"n\":\"Bool\"},{\"t\":7,\"p\":1,\"n\":\"Struct\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Member\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"memberName\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]},{\"t\":2,\"p\":1,\"n\":\"String\"},{\"t\":3,\"p\":1,\"n\":\"Int32\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":3,\"p\":1,\"n\":\"Bool\"},{\"t\":7,\"p\":1,\"n\":\"Array of Object\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]}]},{\"t\":7,\"p\":1,\"n\":\"Array of String\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Int32\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Float\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Bool\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]}]}]},{\"t\":7,\"p\":1,\"n\":\"Array of Object\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]}]},{\"t\":7,\"p\":1,\"n\":\"Array of String\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Int32\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Float\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Bool\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Struct\",\"c\":[{\"t\":7,\"p\":1,\"n\":\"Struct\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Member\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"memberName\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]},{\"t\":2,\"p\":1,\"n\":\"String\"},{\"t\":3,\"p\":1,\"n\":\"Int32\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":3,\"p\":1,\"n\":\"Bool\"},{\"t\":7,\"p\":1,\"n\":\"Array of Object\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]}]},{\"t\":7,\"p\":1,\"n\":\"Array of String\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Int32\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Float\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Bool\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]}]}]}]}]}]}]}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"X1\"},{\"t\":3,\"p\":1,\"n\":\"Y1\"},{\"t\":3,\"p\":1,\"n\":\"Z1\"},{\"t\":3,\"p\":1,\"n\":\"X2\"},{\"t\":3,\"p\":1,\"n\":\"Y2\"},{\"t\":3,\"p\":1,\"n\":\"Z2\"}]},{\"t\":3,\"p\":1,\"n\":\"PTRN - Preview Transform\"},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"MODT - Texture Files Hashes\"},{\"t\":3,\"p\":1,\"n\":\"MODS - Material Swap\"},{\"t\":5,\"p\":1,\"n\":\"MODC - Color Remapping Index\"},{\"t\":11,\"n\":\"MODF - Unknown\"}]},{\"t\":3,\"n\":\"COCT - Count\"},{\"t\":10,\"p\":1,\"n\":\"Items\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Item\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"CNTO - Item\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Item\"},{\"t\":3,\"p\":1,\"n\":\"Count\"}]},{\"t\":6,\"p\":1,\"n\":\"COED - Extra Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Owner\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Global Variable\"},{\"t\":3,\"p\":1,\"n\":\"Required Rank\"},{\"t\":5,\"p\":1,\"n\":\"Item Condition\"}]}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Destructible\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"DEST - Header\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Health\"},{\"t\":3,\"p\":1,\"n\":\"DEST Count\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":7,\"p\":1,\"n\":\"DAMC - Resistances\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Resistance\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Damage Type\"},{\"t\":3,\"p\":1,\"n\":\"Value\"}]}]},{\"t\":8,\"p\":1,\"n\":\"Stages\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Stage\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"DSTD - Destruction Stage Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Health %\"},{\"t\":3,\"p\":1,\"n\":\"Index\"},{\"t\":3,\"p\":1,\"n\":\"Model Damage Stage\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":3,\"p\":1,\"n\":\"Self Damage per Second\"},{\"t\":3,\"p\":1,\"n\":\"Explosion\"},{\"t\":3,\"p\":1,\"n\":\"Debris\"},{\"t\":3,\"p\":1,\"n\":\"Debris Count\"}]},{\"t\":2,\"p\":1,\"n\":\"DSTA - Sequence Name\"},{\"t\":6,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"DMDL - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"DMDT - Texture Files Hashes\"},{\"t\":5,\"p\":1,\"n\":\"DMDC - Color Remapping Index\"},{\"t\":3,\"p\":1,\"n\":\"DMDS - Material Swap\"}]},{\"p\":1,\"n\":\"DSTF - End Marker\"}]}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DATA - \",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":5,\"p\":1,\"n\":\"Weight\"}]},{\"t\":3,\"n\":\"KSIZ - Keyword Count\"},{\"t\":7,\"p\":1,\"n\":\"KWDA - Keywords\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Keyword\"}]},{\"t\":3,\"p\":1,\"n\":\"FTYP - Forced Loc Ref Type\"},{\"t\":7,\"p\":1,\"n\":\"PRPS - Properties\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Property\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Actor Value\"},{\"t\":5,\"p\":1,\"n\":\"Value\"}]}]},{\"t\":3,\"p\":1,\"n\":\"NTRM - Native Terminal\"},{\"t\":3,\"p\":1,\"n\":\"SNAM - Sound - Open\"},{\"t\":3,\"p\":1,\"n\":\"QNAM - Sound - Close\"},{\"t\":3,\"p\":1,\"n\":\"TNAM - Sound - Take All\"},{\"t\":3,\"p\":1,\"n\":\"ONAM - Filter List\"}]},{\"t\":1,\"p\":1,\"n\":\"CPTH - Camera Path\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Conditions\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Condition\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"CTDA - \",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":5,\"p\":1,\"n\":\"Comparison Value - Float\"},{\"t\":3,\"p\":1,\"n\":\"Comparison Value - Global\"},{\"t\":3,\"p\":1,\"n\":\"Function\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":11,\"p\":1,\"n\":\"None\"},{\"t\":3,\"p\":1,\"n\":\"Integer\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":3,\"p\":1,\"n\":\"Actor\"},{\"t\":3,\"p\":1,\"n\":\"Actor Base\"},{\"t\":3,\"p\":1,\"n\":\"Actor Value\"},{\"t\":3,\"p\":1,\"n\":\"Player Action\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"Alignment\"},{\"t\":3,\"p\":1,\"n\":\"Association Type\"},{\"t\":3,\"p\":1,\"n\":\"Axis\"},{\"t\":3,\"p\":1,\"n\":\"Casting Type\"},{\"t\":3,\"p\":1,\"n\":\"Cell\"},{\"t\":3,\"p\":1,\"n\":\"Class\"},{\"t\":3,\"p\":1,\"n\":\"Crime Type\"},{\"t\":3,\"p\":1,\"n\":\"Critical Stage\"},{\"t\":3,\"p\":1,\"n\":\"Encounter Zone\"},{\"t\":3,\"p\":1,\"n\":\"Equip Type\"},{\"t\":3,\"p\":1,\"n\":\"Event\"},{\"t\":3,\"p\":1,\"n\":\"Event Data\"},{\"t\":3,\"p\":1,\"n\":\"Faction\"},{\"t\":3,\"p\":1,\"n\":\"Form List\"},{\"t\":3,\"p\":1,\"n\":\"Form Type\"},{\"t\":3,\"p\":1,\"n\":\"Furniture\"},{\"t\":3,\"p\":1,\"n\":\"Furniture Anim\"},{\"t\":3,\"p\":1,\"n\":\"Furniture Entry\"},{\"t\":3,\"p\":1,\"n\":\"Global\"},{\"t\":3,\"p\":1,\"n\":\"Idle\"},{\"t\":3,\"p\":1,\"n\":\"Inventory Object\"},{\"t\":3,\"p\":1,\"n\":\"Keyword\"},{\"t\":3,\"p\":1,\"n\":\"Location\"},{\"t\":3,\"p\":1,\"n\":\"Base Effect\"},{\"t\":3,\"p\":1,\"n\":\"Effect Item\"},{\"t\":3,\"p\":1,\"n\":\"Misc Stat\"},{\"t\":3,\"p\":1,\"n\":\"Object Reference\"},{\"t\":3,\"p\":1,\"n\":\"Owner\"},{\"t\":3,\"p\":1,\"n\":\"Package\"},{\"t\":3,\"p\":1,\"n\":\"Packdata ID\"},{\"t\":3,\"p\":1,\"n\":\"Perk\"},{\"t\":3,\"p\":1,\"n\":\"Quest\"},{\"t\":3,\"p\":1,\"n\":\"Quest Stage\"},{\"t\":3,\"p\":1,\"n\":\"Race\"},{\"t\":3,\"p\":1,\"n\":\"Referenceable Object\"},{\"t\":3,\"p\":1,\"n\":\"Location Ref Type\"},{\"t\":3,\"p\":1,\"n\":\"Region\"},{\"t\":3,\"p\":1,\"n\":\"Scene\"},{\"t\":3,\"p\":1,\"n\":\"Sex\"},{\"t\":3,\"p\":1,\"n\":\"Shout\"},{\"t\":11,\"p\":1,\"n\":\"Variable Name (unused)\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Function\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Param (unused)\"},{\"t\":3,\"p\":1,\"n\":\"Voice Type\"},{\"t\":3,\"p\":1,\"n\":\"Ward State\"},{\"t\":3,\"p\":1,\"n\":\"Weather\"},{\"t\":3,\"p\":1,\"n\":\"Worldspace\"},{\"t\":3,\"p\":1,\"n\":\"Damage Type\"},{\"t\":3,\"p\":1,\"n\":\"Weapon\"},{\"t\":3,\"p\":1,\"n\":\"Weapon List\"},{\"t\":3,\"p\":1,\"n\":\"Target\"},{\"t\":3,\"p\":1,\"n\":\"Target List\"},{\"t\":3,\"p\":1,\"n\":\"Target Part\"},{\"t\":3,\"p\":1,\"n\":\"VATS Action\"},{\"t\":3,\"p\":1,\"n\":\"Critical Effect\"},{\"t\":3,\"p\":1,\"n\":\"Critical Effect List\"},{\"t\":3,\"p\":1,\"n\":\"Weapon Type\"},{\"t\":3,\"p\":1,\"n\":\"Projectile Type\"},{\"t\":3,\"p\":1,\"n\":\"Delivery Type\"},{\"t\":3,\"p\":1,\"n\":\"Run On\"},{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":3,\"p\":1,\"n\":\"Parameter #3\"}]},{\"t\":2,\"p\":1,\"n\":\"CIS1 - Parameter #1\"},{\"t\":2,\"p\":1,\"n\":\"CIS2 - Parameter #2\"}]}]},{\"t\":7,\"p\":1,\"n\":\"ANAM - Related Camera Paths\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Related Camera Path\"}]},{\"t\":3,\"p\":1,\"n\":\"DATA - Camera Zoom \\/ Flags\"},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Camera Shots\",\"d\":1,\"c\":[{\"t\":3,\"p\":1,\"n\":\"SNAM - Camera Shot\"}]}]},{\"t\":1,\"p\":1,\"n\":\"CSTY - Combat Style\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"CSGD - General\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Offensive Mult\"},{\"t\":5,\"p\":1,\"n\":\"Defensive Mult\"},{\"t\":5,\"p\":1,\"n\":\"Group Offensive Mult\"},{\"t\":5,\"p\":1,\"n\":\"Equipment Score Mult - Melee\"},{\"t\":5,\"p\":1,\"n\":\"Equipment Score Mult - Magic\"},{\"t\":5,\"p\":1,\"n\":\"Equipment Score Mult - Ranged\"},{\"t\":5,\"p\":1,\"n\":\"Equipment Score Mult - Shout\"},{\"t\":5,\"p\":1,\"n\":\"Equipment Score Mult - Unarmed\"},{\"t\":5,\"p\":1,\"n\":\"Equipment Score Mult - Staff\"},{\"t\":5,\"p\":1,\"n\":\"Avoid Threat Chance\"},{\"t\":5,\"p\":1,\"n\":\"Dodge Threat Chance\"},{\"t\":5,\"p\":1,\"n\":\"Evade Threat Chance\"}]},{\"t\":11,\"n\":\"CSMD - Unknown\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"CSME - Melee\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Attack Staggered Mult\"},{\"t\":5,\"p\":1,\"n\":\"Power Attack Staggered Mult\"},{\"t\":5,\"p\":1,\"n\":\"Power Attack Blocking Mult\"},{\"t\":5,\"p\":1,\"n\":\"Bash Mult\"},{\"t\":5,\"p\":1,\"n\":\"Bash Recoil Mult\"},{\"t\":5,\"p\":1,\"n\":\"Bash Attack Mult\"},{\"t\":5,\"p\":1,\"n\":\"Bash Power Attack Mult\"},{\"t\":5,\"p\":1,\"n\":\"Special Attack Mult\"},{\"t\":5,\"p\":1,\"n\":\"Block When Staggered Mult\"},{\"t\":5,\"p\":1,\"n\":\"Attack When Staggered Mult\"}]},{\"t\":5,\"p\":1,\"n\":\"CSRA - Ranged Accuracy Mult\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"CSCR - Close Range\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Dueling - Circle Mult\"},{\"t\":5,\"p\":1,\"n\":\"Dueling - Fallback Mult\"},{\"t\":5,\"p\":1,\"n\":\"Flanking - Flank Distance\"},{\"t\":5,\"p\":1,\"n\":\"Flanking - Stalk Time\"},{\"t\":5,\"p\":1,\"n\":\"Charging - Charge Distance\"},{\"t\":5,\"p\":1,\"n\":\"Charging - Throw Probability\"},{\"t\":5,\"p\":1,\"n\":\"Charging - Sprint Fast Probability\"},{\"t\":5,\"p\":1,\"n\":\"Charging - Sideswipe Probability\"},{\"t\":5,\"p\":1,\"n\":\"Charging - Disengane Probability\"},{\"t\":3,\"p\":1,\"n\":\"Charging - Throw Max Targets\"},{\"t\":5,\"p\":1,\"n\":\"Flanking - Flank Variance\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"CSLR - Long Range\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Strafe Mult\"},{\"t\":5,\"p\":1,\"n\":\"Adjust Range Mult\"},{\"t\":5,\"p\":1,\"n\":\"Crouch Mult\"},{\"t\":5,\"p\":1,\"n\":\"Wait Mult\"},{\"t\":5,\"p\":1,\"n\":\"Range Mult\"}]},{\"t\":5,\"p\":1,\"n\":\"CSCV - Cover Search Distance Mult\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"CSFL - Flight\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Hover Chance\"},{\"t\":5,\"p\":1,\"n\":\"Dive Bomb Chance\"},{\"t\":5,\"p\":1,\"n\":\"Ground Attack Chance\"},{\"t\":5,\"p\":1,\"n\":\"Hover Time\"},{\"t\":5,\"p\":1,\"n\":\"Ground Attack Time\"},{\"t\":5,\"p\":1,\"n\":\"Perch Attack Chance\"},{\"t\":5,\"p\":1,\"n\":\"Perch Attack Time\"},{\"t\":5,\"p\":1,\"n\":\"Flying Attack Chance\"}]},{\"t\":3,\"p\":1,\"n\":\"DATA - Flags\"}]},{\"t\":1,\"p\":1,\"n\":\"DEBR - Debris\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Models\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"DATA - Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Percentage\"},{\"t\":2,\"p\":1,\"n\":\"Model Filename\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"}]},{\"t\":11,\"p\":1,\"n\":\"MODT - Texture Files Hashes\"}]}]}]},{\"t\":1,\"p\":1,\"n\":\"DFOB - Default Object\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":3,\"p\":1,\"n\":\"DATA - Object\"}]},{\"t\":1,\"p\":1,\"n\":\"DIAL - Dialog Topic\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":5,\"p\":1,\"n\":\"PNAM - Priority\"},{\"t\":3,\"p\":1,\"n\":\"BNAM - Branch\"},{\"t\":3,\"p\":1,\"n\":\"QNAM - Quest\"},{\"t\":3,\"p\":1,\"n\":\"KNAM - Keyword\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DATA - Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Topic Flags\"},{\"t\":3,\"p\":1,\"n\":\"Category\"},{\"t\":3,\"p\":1,\"n\":\"Subtype\"}]},{\"t\":2,\"p\":1,\"n\":\"SNAM - Subtype Name\"},{\"t\":3,\"p\":1,\"n\":\"TIFC - Info Count\"}]},{\"t\":1,\"p\":1,\"n\":\"DLBR - Dialog Branch\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":3,\"p\":1,\"n\":\"QNAM - Quest\"},{\"t\":3,\"n\":\"TNAM - Unknown\"},{\"t\":3,\"p\":1,\"n\":\"DNAM - Flags\"},{\"t\":3,\"p\":1,\"n\":\"SNAM - Starting Topic\"}]},{\"t\":1,\"p\":1,\"n\":\"DLVW - Dialog View\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":3,\"p\":1,\"n\":\"QNAM - Quest\"},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Branches\",\"d\":1,\"c\":[{\"t\":3,\"p\":1,\"n\":\"BNAM - Branch\"}]},{\"t\":8,\"n\":\"Unknown TNAM\",\"c\":[{\"t\":6,\"n\":\"Unknown\",\"c\":[{\"t\":11,\"n\":\"TNAM - Unknown\"}]}]},{\"t\":11,\"n\":\"ENAM - Unknown\"},{\"t\":11,\"n\":\"DNAM - Unknown\"}]},{\"t\":1,\"p\":1,\"n\":\"DMGT - Damage Type\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":7,\"p\":1,\"n\":\"Damage Types\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Actor Value Index\"}]}]},{\"t\":1,\"n\":\"DOBJ - Default Object Manager\",\"c\":[{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":7,\"n\":\"DNAM - Objects\",\"c\":[{\"t\":6,\"n\":\"Object\",\"c\":[{\"t\":3,\"n\":\"Use\"},{\"t\":3,\"n\":\"Object ID\"}]}]}]},{\"t\":1,\"p\":1,\"n\":\"DOOR - Door\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"VMAD - Virtual Machine Adapter\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Version\"},{\"t\":3,\"p\":1,\"n\":\"Object Format\"},{\"t\":7,\"p\":1,\"n\":\"Scripts\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Script\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"scriptName\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":7,\"p\":1,\"n\":\"Properties\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Property\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"propertyName\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]},{\"t\":2,\"p\":1,\"n\":\"String\"},{\"t\":3,\"p\":1,\"n\":\"Int32\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":3,\"p\":1,\"n\":\"Bool\"},{\"t\":7,\"p\":1,\"n\":\"Struct\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Member\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"memberName\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]},{\"t\":2,\"p\":1,\"n\":\"String\"},{\"t\":3,\"p\":1,\"n\":\"Int32\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":3,\"p\":1,\"n\":\"Bool\"},{\"t\":7,\"p\":1,\"n\":\"Array of Object\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]}]},{\"t\":7,\"p\":1,\"n\":\"Array of String\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Int32\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Float\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Bool\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]}]}]},{\"t\":7,\"p\":1,\"n\":\"Array of Object\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]}]},{\"t\":7,\"p\":1,\"n\":\"Array of String\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Int32\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Float\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Bool\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Struct\",\"c\":[{\"t\":7,\"p\":1,\"n\":\"Struct\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Member\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"memberName\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]},{\"t\":2,\"p\":1,\"n\":\"String\"},{\"t\":3,\"p\":1,\"n\":\"Int32\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":3,\"p\":1,\"n\":\"Bool\"},{\"t\":7,\"p\":1,\"n\":\"Array of Object\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]}]},{\"t\":7,\"p\":1,\"n\":\"Array of String\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Int32\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Float\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Bool\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]}]}]}]}]}]}]}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"X1\"},{\"t\":3,\"p\":1,\"n\":\"Y1\"},{\"t\":3,\"p\":1,\"n\":\"Z1\"},{\"t\":3,\"p\":1,\"n\":\"X2\"},{\"t\":3,\"p\":1,\"n\":\"Y2\"},{\"t\":3,\"p\":1,\"n\":\"Z2\"}]},{\"t\":3,\"p\":1,\"n\":\"PTRN - Preview Transform\"},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"MODT - Texture Files Hashes\"},{\"t\":3,\"p\":1,\"n\":\"MODS - Material Swap\"},{\"t\":5,\"p\":1,\"n\":\"MODC - Color Remapping Index\"},{\"t\":11,\"n\":\"MODF - Unknown\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Destructible\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"DEST - Header\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Health\"},{\"t\":3,\"p\":1,\"n\":\"DEST Count\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":7,\"p\":1,\"n\":\"DAMC - Resistances\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Resistance\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Damage Type\"},{\"t\":3,\"p\":1,\"n\":\"Value\"}]}]},{\"t\":8,\"p\":1,\"n\":\"Stages\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Stage\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"DSTD - Destruction Stage Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Health %\"},{\"t\":3,\"p\":1,\"n\":\"Index\"},{\"t\":3,\"p\":1,\"n\":\"Model Damage Stage\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":3,\"p\":1,\"n\":\"Self Damage per Second\"},{\"t\":3,\"p\":1,\"n\":\"Explosion\"},{\"t\":3,\"p\":1,\"n\":\"Debris\"},{\"t\":3,\"p\":1,\"n\":\"Debris Count\"}]},{\"t\":2,\"p\":1,\"n\":\"DSTA - Sequence Name\"},{\"t\":6,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"DMDL - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"DMDT - Texture Files Hashes\"},{\"t\":5,\"p\":1,\"n\":\"DMDC - Color Remapping Index\"},{\"t\":3,\"p\":1,\"n\":\"DMDS - Material Swap\"}]},{\"p\":1,\"n\":\"DSTF - End Marker\"}]}]}]},{\"t\":3,\"n\":\"KSIZ - Keyword Count\"},{\"t\":7,\"p\":1,\"n\":\"KWDA - Keywords\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Keyword\"}]},{\"t\":3,\"p\":1,\"n\":\"NTRM - Native Terminal\"},{\"t\":3,\"p\":1,\"n\":\"SNAM - Sound - Open\"},{\"t\":3,\"p\":1,\"n\":\"ANAM - Sound - Close\"},{\"t\":3,\"p\":1,\"n\":\"BNAM - Sound - Loop\"},{\"t\":3,\"p\":1,\"n\":\"FNAM - Flags\"},{\"t\":2,\"p\":1,\"n\":\"ONAM - Alternate Text - Open\"},{\"t\":2,\"p\":1,\"n\":\"CNAM - Alternate Text - Close\"}]},{\"t\":1,\"p\":1,\"n\":\"DUAL - Dual Cast Data\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"}]},{\"t\":1,\"p\":1,\"n\":\"ECZN - Encounter Zone\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DATA - \",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Owner\"},{\"t\":3,\"p\":1,\"n\":\"Location\"},{\"t\":3,\"p\":1,\"n\":\"Rank\"},{\"t\":3,\"p\":1,\"n\":\"Min Level\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":3,\"p\":1,\"n\":\"Max Level\"}]}]},{\"t\":1,\"p\":1,\"n\":\"EFSH - Effect Shader\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"p\":1,\"n\":\"ICON - Fill Texture\"},{\"t\":2,\"p\":1,\"n\":\"ICO2 - Particle Shader Texture\"},{\"t\":2,\"p\":1,\"n\":\"NAM7 - Holes Texture\"},{\"t\":2,\"p\":1,\"n\":\"NAM8 - Membrane Palette Texture\"},{\"t\":2,\"p\":1,\"n\":\"NAM9 - Particle Palette Texture\"},{\"t\":11,\"n\":\"DATA - Unknown\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Membrane Shader - Source Blend Mode\"},{\"t\":3,\"p\":1,\"n\":\"Membrane Shader - Blend Operation\"},{\"t\":3,\"p\":1,\"n\":\"Membrane Shader - Z Test Function\"},{\"t\":6,\"p\":1,\"n\":\"Fill\\/Texture Effect - Color Key 1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":5,\"p\":1,\"n\":\"Fill\\/Texture Effect - Alpha Fade In Time\"},{\"t\":5,\"p\":1,\"n\":\"Fill\\/Texture Effect - Full Alpha Time\"},{\"t\":5,\"p\":1,\"n\":\"Fill\\/Texture Effect - Alpha Fade Out Time\"},{\"t\":5,\"p\":1,\"n\":\"Fill\\/Texture Effect - Presistent Alpha Ratio\"},{\"t\":5,\"p\":1,\"n\":\"Fill\\/Texture Effect - Alpha Pulse Amplitude\"},{\"t\":5,\"p\":1,\"n\":\"Fill\\/Texture Effect - Alpha Pulse Frequency\"},{\"t\":5,\"p\":1,\"n\":\"Fill\\/Texture Effect - Texture Animation Speed (U)\"},{\"t\":5,\"p\":1,\"n\":\"Fill\\/Texture Effect - Texture Animation Speed (V)\"},{\"t\":5,\"p\":1,\"n\":\"Edge Effect - Fall Off\"},{\"t\":6,\"p\":1,\"n\":\"Edge Effect - Color\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":5,\"p\":1,\"n\":\"Edge Effect - Alpha Fade In Time\"},{\"t\":5,\"p\":1,\"n\":\"Edge Effect - Full Alpha Time\"},{\"t\":5,\"p\":1,\"n\":\"Edge Effect - Alpha Fade Out Time\"},{\"t\":5,\"p\":1,\"n\":\"Edge Effect - Persistent Alpha Ratio\"},{\"t\":5,\"p\":1,\"n\":\"Edge Effect - Alpha Pulse Amplitude\"},{\"t\":5,\"p\":1,\"n\":\"Edge Effect - Alpha Pulse Frequency\"},{\"t\":5,\"p\":1,\"n\":\"Fill\\/Texture Effect - Full Alpha Ratio\"},{\"t\":5,\"p\":1,\"n\":\"Edge Effect - Full Alpha Ratio\"},{\"t\":3,\"p\":1,\"n\":\"Membrane Shader - Dest Blend Mode\"},{\"t\":5,\"p\":1,\"n\":\"Holes Animation - Start Time\"},{\"t\":5,\"p\":1,\"n\":\"Holes Animation - End Time\"},{\"t\":5,\"p\":1,\"n\":\"Holes Animation - Start Value\"},{\"t\":5,\"p\":1,\"n\":\"Holes Animation - End Value\"},{\"t\":3,\"p\":1,\"n\":\"Ambient Sound\"},{\"t\":6,\"p\":1,\"n\":\"Fill\\/Texture Effect - Color Key 2\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Fill\\/Texture Effect - Color Key 3\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":3,\"n\":\"Unknown\"},{\"t\":6,\"p\":1,\"n\":\"Fill\\/Texture Effect - Color Key Scale\\/Time\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Color Key 1 - Scale\"},{\"t\":5,\"p\":1,\"n\":\"Color Key 2 - Scale\"},{\"t\":5,\"p\":1,\"n\":\"Color Key 3 - Scale\"},{\"t\":5,\"p\":1,\"n\":\"Color Key 1 - Time\"},{\"t\":5,\"p\":1,\"n\":\"Color Key 2 - Time\"},{\"t\":5,\"p\":1,\"n\":\"Color Key 3 - Time\"}]},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":5,\"p\":1,\"n\":\"Fill\\/Texture Effect - Texture Scale (U)\"},{\"t\":5,\"p\":1,\"n\":\"Fill\\/Texture Effect - Texture Scale (V)\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Data (old format)\",\"c\":[{\"t\":11,\"n\":\"Unknown\"},{\"t\":3,\"p\":1,\"n\":\"Membrane Shader - Source Blend Mode\"},{\"t\":3,\"p\":1,\"n\":\"Membrane Shader - Blend Operation\"},{\"t\":3,\"p\":1,\"n\":\"Membrane Shader - Z Test Function\"},{\"t\":6,\"p\":1,\"n\":\"Fill\\/Texture Effect - Color Key 1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":5,\"p\":1,\"n\":\"Fill\\/Texture Effect - Alpha Fade In Time\"},{\"t\":5,\"p\":1,\"n\":\"Fill\\/Texture Effect - Full Alpha Time\"},{\"t\":5,\"p\":1,\"n\":\"Fill\\/Texture Effect - Alpha Fade Out Time\"},{\"t\":5,\"p\":1,\"n\":\"Fill\\/Texture Effect - Presistent Alpha Ratio\"},{\"t\":5,\"p\":1,\"n\":\"Fill\\/Texture Effect - Alpha Pulse Amplitude\"},{\"t\":5,\"p\":1,\"n\":\"Fill\\/Texture Effect - Alpha Pulse Frequency\"},{\"t\":5,\"p\":1,\"n\":\"Fill\\/Texture Effect - Texture Animation Speed (U)\"},{\"t\":5,\"p\":1,\"n\":\"Fill\\/Texture Effect - Texture Animation Speed (V)\"},{\"t\":5,\"p\":1,\"n\":\"Edge Effect - Fall Off\"},{\"t\":6,\"p\":1,\"n\":\"Edge Effect - Color\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":5,\"p\":1,\"n\":\"Edge Effect - Alpha Fade In Time\"},{\"t\":5,\"p\":1,\"n\":\"Edge Effect - Full Alpha Time\"},{\"t\":5,\"p\":1,\"n\":\"Edge Effect - Alpha Fade Out Time\"},{\"t\":5,\"p\":1,\"n\":\"Edge Effect - Persistent Alpha Ratio\"},{\"t\":5,\"p\":1,\"n\":\"Edge Effect - Alpha Pulse Amplitude\"},{\"t\":5,\"p\":1,\"n\":\"Edge Effect - Alpha Pulse Frequency\"},{\"t\":5,\"p\":1,\"n\":\"Fill\\/Texture Effect - Full Alpha Ratio\"},{\"t\":5,\"p\":1,\"n\":\"Edge Effect - Full Alpha Ratio\"},{\"t\":3,\"p\":1,\"n\":\"Membrane Shader - Dest Blend Mode\"},{\"t\":3,\"p\":1,\"n\":\"Particle Shader - Source Blend Mode\"},{\"t\":3,\"p\":1,\"n\":\"Particle Shader - Blend Operation\"},{\"t\":3,\"p\":1,\"n\":\"Particle Shader - Z Test Function\"},{\"t\":3,\"p\":1,\"n\":\"Particle Shader - Dest Blend Mode\"},{\"t\":5,\"p\":1,\"n\":\"Particle Shader - Particle Birth Ramp Up Time\"},{\"t\":5,\"p\":1,\"n\":\"Particle Shader - Full Particle Birth Time\"},{\"t\":5,\"p\":1,\"n\":\"Particle Shader - Particle Birth Ramp Down Time\"},{\"t\":5,\"p\":1,\"n\":\"Particle Shader - Full Particle Birth Ratio\"},{\"t\":5,\"p\":1,\"n\":\"Particle Shader - Persistant Particle Count\"},{\"t\":5,\"p\":1,\"n\":\"Particle Shader - Particle Lifetime\"},{\"t\":5,\"p\":1,\"n\":\"Particle Shader - Particle Lifetime +\\/-\"},{\"t\":5,\"p\":1,\"n\":\"Particle Shader - Initial Speed Along Normal\"},{\"t\":5,\"p\":1,\"n\":\"Particle Shader - Acceleration Along Normal\"},{\"t\":5,\"p\":1,\"n\":\"Particle Shader - Initial Velocity #1\"},{\"t\":5,\"p\":1,\"n\":\"Particle Shader - Initial Velocity #2\"},{\"t\":5,\"p\":1,\"n\":\"Particle Shader - Initial Velocity #3\"},{\"t\":5,\"p\":1,\"n\":\"Particle Shader - Acceleration #1\"},{\"t\":5,\"p\":1,\"n\":\"Particle Shader - Acceleration #2\"},{\"t\":5,\"p\":1,\"n\":\"Particle Shader - Acceleration #3\"},{\"t\":5,\"p\":1,\"n\":\"Particle Shader - Scale Key 1\"},{\"t\":5,\"p\":1,\"n\":\"Particle Shader - Scale Key 2\"},{\"t\":5,\"p\":1,\"n\":\"Particle Shader - Scale Key 1 Time\"},{\"t\":5,\"p\":1,\"n\":\"Particle Shader - Scale Key 2 Time\"},{\"t\":6,\"p\":1,\"n\":\"Color Key 1 - Color\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Color Key 2 - Color\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Color Key 3 - Color\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":5,\"p\":1,\"n\":\"Color Key 1 - Color Alpha\"},{\"t\":5,\"p\":1,\"n\":\"Color Key 2 - Color Alpha\"},{\"t\":5,\"p\":1,\"n\":\"Color Key 3 - Color Alpha\"},{\"t\":5,\"p\":1,\"n\":\"Color Key 1 - Color Key Time\"},{\"t\":5,\"p\":1,\"n\":\"Color Key 2 - Color Key Time\"},{\"t\":5,\"p\":1,\"n\":\"Color Key 3 - Color Key Time\"},{\"t\":5,\"p\":1,\"n\":\"Particle Shader - Initial Speed Along Normal +\\/-\"},{\"t\":5,\"p\":1,\"n\":\"Particle Shader - Initial Rotation (deg)\"},{\"t\":5,\"p\":1,\"n\":\"Particle Shader - Initial Rotation (deg) +\\/-\"},{\"t\":5,\"p\":1,\"n\":\"Particle Shader - Rotation Speed (deg\\/sec)\"},{\"t\":5,\"p\":1,\"n\":\"Particle Shader - Rotation Speed (deg\\/sec) +\\/-\"},{\"t\":3,\"p\":1,\"n\":\"Addon Models\"},{\"t\":5,\"p\":1,\"n\":\"Holes - Start Time\"},{\"t\":5,\"p\":1,\"n\":\"Holes - End Time\"},{\"t\":5,\"p\":1,\"n\":\"Holes - Start Val\"},{\"t\":5,\"p\":1,\"n\":\"Holes - End Val\"},{\"t\":5,\"p\":1,\"n\":\"Edge Width (alpha units)\"},{\"t\":6,\"p\":1,\"n\":\"Edge Color\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":5,\"p\":1,\"n\":\"Explosion Wind Speed\"},{\"t\":3,\"p\":1,\"n\":\"Texture Count U\"},{\"t\":3,\"p\":1,\"n\":\"Texture Count V\"},{\"t\":5,\"p\":1,\"n\":\"Addon Models - Fade In Time\"},{\"t\":5,\"p\":1,\"n\":\"Addon Models - Fade Out Time\"},{\"t\":5,\"p\":1,\"n\":\"Addon Models - Scale Start\"},{\"t\":5,\"p\":1,\"n\":\"Addon Models - Scale End\"},{\"t\":5,\"p\":1,\"n\":\"Addon Models - Scale In Time\"},{\"t\":5,\"p\":1,\"n\":\"Addon Models - Scale Out Time\"},{\"t\":3,\"p\":1,\"n\":\"Ambient Sound\"},{\"t\":6,\"p\":1,\"n\":\"Fill\\/Texture Effect - Color Key 2\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Fill\\/Texture Effect - Color Key 3\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Fill\\/Texture Effect - Color Key Scale\\/Time\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Color Key 1 - Scale\"},{\"t\":5,\"p\":1,\"n\":\"Color Key 2 - Scale\"},{\"t\":5,\"p\":1,\"n\":\"Color Key 3 - Scale\"},{\"t\":5,\"p\":1,\"n\":\"Color Key 1 - Time\"},{\"t\":5,\"p\":1,\"n\":\"Color Key 2 - Time\"},{\"t\":5,\"p\":1,\"n\":\"Color Key 3 - Time\"}]},{\"t\":5,\"p\":1,\"n\":\"Color Scale\"},{\"t\":5,\"p\":1,\"n\":\"Birth Position Offset\"},{\"t\":5,\"p\":1,\"n\":\"Birth Position Offset Range +\\/-\"},{\"t\":6,\"p\":1,\"n\":\"Particle Shader Animated\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Start Frame\"},{\"t\":3,\"p\":1,\"n\":\"Start Frame Variation\"},{\"t\":3,\"p\":1,\"n\":\"End Frame\"},{\"t\":3,\"p\":1,\"n\":\"Loop Start Frame\"},{\"t\":3,\"p\":1,\"n\":\"Loop Start Variation\"},{\"t\":3,\"p\":1,\"n\":\"Frame Count\"},{\"t\":3,\"p\":1,\"n\":\"Frame Count Variation\"}]},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":5,\"p\":1,\"n\":\"Fill\\/Texture Effect - Texture Scale (U)\"},{\"t\":5,\"p\":1,\"n\":\"Fill\\/Texture Effect - Texture Scale (V)\"},{\"t\":3,\"p\":1,\"n\":\"Scene Graph Emit Depth Limit (unused)\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"MODT - Texture Files Hashes\"},{\"t\":3,\"p\":1,\"n\":\"MODS - Material Swap\"},{\"t\":5,\"p\":1,\"n\":\"MODC - Color Remapping Index\"},{\"t\":11,\"n\":\"MODF - Unknown\"}]}]},{\"t\":1,\"p\":1,\"n\":\"ENCH - Object Effect\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"X1\"},{\"t\":3,\"p\":1,\"n\":\"Y1\"},{\"t\":3,\"p\":1,\"n\":\"Z1\"},{\"t\":3,\"p\":1,\"n\":\"X2\"},{\"t\":3,\"p\":1,\"n\":\"Y2\"},{\"t\":3,\"p\":1,\"n\":\"Z2\"}]},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"ENIT - Effect Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Enchantment Cost\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":3,\"p\":1,\"n\":\"Cast Type\"},{\"t\":3,\"p\":1,\"n\":\"Enchantment Amount\"},{\"t\":3,\"p\":1,\"n\":\"Target Type\"},{\"t\":3,\"p\":1,\"n\":\"Enchant Type\"},{\"t\":5,\"p\":1,\"n\":\"Charge Time\"},{\"t\":3,\"p\":1,\"n\":\"Base Enchantment\"},{\"t\":3,\"p\":1,\"n\":\"Worn Restrictions\"}]},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Effects\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Effect\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"EFID - Base Effect\"},{\"t\":6,\"p\":1,\"n\":\"EFIT - \",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Magnitude\"},{\"t\":3,\"p\":1,\"n\":\"Area\"},{\"t\":3,\"p\":1,\"n\":\"Duration\"}]},{\"t\":8,\"p\":1,\"n\":\"Conditions\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Condition\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"CTDA - \",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":5,\"p\":1,\"n\":\"Comparison Value - Float\"},{\"t\":3,\"p\":1,\"n\":\"Comparison Value - Global\"},{\"t\":3,\"p\":1,\"n\":\"Function\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":11,\"p\":1,\"n\":\"None\"},{\"t\":3,\"p\":1,\"n\":\"Integer\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":3,\"p\":1,\"n\":\"Actor\"},{\"t\":3,\"p\":1,\"n\":\"Actor Base\"},{\"t\":3,\"p\":1,\"n\":\"Actor Value\"},{\"t\":3,\"p\":1,\"n\":\"Player Action\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"Alignment\"},{\"t\":3,\"p\":1,\"n\":\"Association Type\"},{\"t\":3,\"p\":1,\"n\":\"Axis\"},{\"t\":3,\"p\":1,\"n\":\"Casting Type\"},{\"t\":3,\"p\":1,\"n\":\"Cell\"},{\"t\":3,\"p\":1,\"n\":\"Class\"},{\"t\":3,\"p\":1,\"n\":\"Crime Type\"},{\"t\":3,\"p\":1,\"n\":\"Critical Stage\"},{\"t\":3,\"p\":1,\"n\":\"Encounter Zone\"},{\"t\":3,\"p\":1,\"n\":\"Equip Type\"},{\"t\":3,\"p\":1,\"n\":\"Event\"},{\"t\":3,\"p\":1,\"n\":\"Event Data\"},{\"t\":3,\"p\":1,\"n\":\"Faction\"},{\"t\":3,\"p\":1,\"n\":\"Form List\"},{\"t\":3,\"p\":1,\"n\":\"Form Type\"},{\"t\":3,\"p\":1,\"n\":\"Furniture\"},{\"t\":3,\"p\":1,\"n\":\"Furniture Anim\"},{\"t\":3,\"p\":1,\"n\":\"Furniture Entry\"},{\"t\":3,\"p\":1,\"n\":\"Global\"},{\"t\":3,\"p\":1,\"n\":\"Idle\"},{\"t\":3,\"p\":1,\"n\":\"Inventory Object\"},{\"t\":3,\"p\":1,\"n\":\"Keyword\"},{\"t\":3,\"p\":1,\"n\":\"Location\"},{\"t\":3,\"p\":1,\"n\":\"Base Effect\"},{\"t\":3,\"p\":1,\"n\":\"Effect Item\"},{\"t\":3,\"p\":1,\"n\":\"Misc Stat\"},{\"t\":3,\"p\":1,\"n\":\"Object Reference\"},{\"t\":3,\"p\":1,\"n\":\"Owner\"},{\"t\":3,\"p\":1,\"n\":\"Package\"},{\"t\":3,\"p\":1,\"n\":\"Packdata ID\"},{\"t\":3,\"p\":1,\"n\":\"Perk\"},{\"t\":3,\"p\":1,\"n\":\"Quest\"},{\"t\":3,\"p\":1,\"n\":\"Quest Stage\"},{\"t\":3,\"p\":1,\"n\":\"Race\"},{\"t\":3,\"p\":1,\"n\":\"Referenceable Object\"},{\"t\":3,\"p\":1,\"n\":\"Location Ref Type\"},{\"t\":3,\"p\":1,\"n\":\"Region\"},{\"t\":3,\"p\":1,\"n\":\"Scene\"},{\"t\":3,\"p\":1,\"n\":\"Sex\"},{\"t\":3,\"p\":1,\"n\":\"Shout\"},{\"t\":11,\"p\":1,\"n\":\"Variable Name (unused)\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Function\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Param (unused)\"},{\"t\":3,\"p\":1,\"n\":\"Voice Type\"},{\"t\":3,\"p\":1,\"n\":\"Ward State\"},{\"t\":3,\"p\":1,\"n\":\"Weather\"},{\"t\":3,\"p\":1,\"n\":\"Worldspace\"},{\"t\":3,\"p\":1,\"n\":\"Damage Type\"},{\"t\":3,\"p\":1,\"n\":\"Weapon\"},{\"t\":3,\"p\":1,\"n\":\"Weapon List\"},{\"t\":3,\"p\":1,\"n\":\"Target\"},{\"t\":3,\"p\":1,\"n\":\"Target List\"},{\"t\":3,\"p\":1,\"n\":\"Target Part\"},{\"t\":3,\"p\":1,\"n\":\"VATS Action\"},{\"t\":3,\"p\":1,\"n\":\"Critical Effect\"},{\"t\":3,\"p\":1,\"n\":\"Critical Effect List\"},{\"t\":3,\"p\":1,\"n\":\"Weapon Type\"},{\"t\":3,\"p\":1,\"n\":\"Projectile Type\"},{\"t\":3,\"p\":1,\"n\":\"Delivery Type\"},{\"t\":3,\"p\":1,\"n\":\"Run On\"},{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":3,\"p\":1,\"n\":\"Parameter #3\"}]},{\"t\":2,\"p\":1,\"n\":\"CIS1 - Parameter #1\"},{\"t\":2,\"p\":1,\"n\":\"CIS2 - Parameter #2\"}]}]}]}]}]},{\"t\":1,\"p\":1,\"n\":\"EQUP - Equip Type\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":7,\"p\":1,\"n\":\"PNAM - Slot Parents\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Parent\"}]},{\"t\":3,\"p\":1,\"n\":\"DATA - Flags\"},{\"t\":3,\"p\":1,\"n\":\"ANAM - Condition Actor Value\"}]},{\"t\":1,\"p\":1,\"n\":\"EXPL - Explosion\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"X1\"},{\"t\":3,\"p\":1,\"n\":\"Y1\"},{\"t\":3,\"p\":1,\"n\":\"Z1\"},{\"t\":3,\"p\":1,\"n\":\"X2\"},{\"t\":3,\"p\":1,\"n\":\"Y2\"},{\"t\":3,\"p\":1,\"n\":\"Z2\"}]},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"MODT - Texture Files Hashes\"},{\"t\":3,\"p\":1,\"n\":\"MODS - Material Swap\"},{\"t\":5,\"p\":1,\"n\":\"MODC - Color Remapping Index\"},{\"t\":11,\"n\":\"MODF - Unknown\"}]},{\"t\":3,\"p\":1,\"n\":\"EITM - Object Effect\"},{\"t\":3,\"p\":1,\"n\":\"MNAM - Image Space Modifier\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DATA - Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Light\"},{\"t\":3,\"p\":1,\"n\":\"Sound 1\"},{\"t\":3,\"p\":1,\"n\":\"Sound 2\"},{\"t\":3,\"p\":1,\"n\":\"Impact Data Set\"},{\"t\":3,\"p\":1,\"n\":\"Placed Object\"},{\"t\":3,\"p\":1,\"n\":\"Spawn Projectile\"},{\"t\":5,\"p\":1,\"n\":\"Force\"},{\"t\":5,\"p\":1,\"n\":\"Damage\"},{\"t\":5,\"p\":1,\"n\":\"Inner Radius\"},{\"t\":5,\"p\":1,\"n\":\"Outer Radius\"},{\"t\":5,\"p\":1,\"n\":\"IS Radius\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":5,\"p\":1,\"n\":\"Vertical Offset Mult\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":3,\"p\":1,\"n\":\"Sound Level\"},{\"t\":5,\"p\":1,\"n\":\"Placed Object AutoFade Delay\"},{\"t\":3,\"p\":1,\"n\":\"Stagger\"},{\"t\":6,\"p\":1,\"n\":\"Spawn\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"X\"},{\"t\":5,\"p\":1,\"n\":\"Y\"},{\"t\":5,\"p\":1,\"n\":\"Z\"},{\"t\":5,\"p\":1,\"n\":\"Spread Degrees\"},{\"t\":3,\"p\":1,\"n\":\"Count\"}]}]}]},{\"t\":1,\"p\":1,\"n\":\"FACT - Faction\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Relations\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"XNAM - Relation\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Faction\"},{\"t\":3,\"p\":1,\"n\":\"Modifier\"},{\"t\":3,\"p\":1,\"n\":\"Group Combat Reaction\"}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DATA - Flags\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Flags\"}]},{\"t\":3,\"p\":1,\"n\":\"JAIL - Exterior Jail Marker\"},{\"t\":3,\"p\":1,\"n\":\"WAIT - Follower Wait Marker\"},{\"t\":3,\"p\":1,\"n\":\"STOL - Stolen Goods Container\"},{\"t\":3,\"p\":1,\"n\":\"PLCN - Player Inventory Container\"},{\"t\":3,\"p\":1,\"n\":\"CRGR - Shared Crime Faction List\"},{\"t\":3,\"p\":1,\"n\":\"JOUT - Jail Outfit\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"CRVA - Crime Values\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Arrest\"},{\"t\":3,\"p\":1,\"n\":\"Attack On Sight\"},{\"t\":3,\"p\":1,\"n\":\"Murder\"},{\"t\":3,\"p\":1,\"n\":\"Assault\"},{\"t\":3,\"p\":1,\"n\":\"Trespass\"},{\"t\":3,\"p\":1,\"n\":\"Pickpocket\"},{\"t\":3,\"n\":\"Unknown\"},{\"t\":5,\"p\":1,\"n\":\"Steal Multiplier\"},{\"t\":3,\"p\":1,\"n\":\"Escape\"},{\"t\":3,\"p\":1,\"n\":\"Werewolf (unused)\"}]},{\"t\":10,\"p\":1,\"n\":\"Ranks\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Rank\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"RNAM - Rank#\"},{\"t\":2,\"p\":1,\"n\":\"MNAM - Male Title\"},{\"t\":2,\"p\":1,\"n\":\"FNAM - Female Title\"},{\"t\":2,\"p\":1,\"n\":\"INAM - Insignia (unused)\"}]}]},{\"t\":3,\"p\":1,\"n\":\"VEND - Vendor Buy\\/Sell List\"},{\"t\":3,\"p\":1,\"n\":\"VENC - Merchant Container\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"VENV - Vendor Values\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Start Hour\"},{\"t\":3,\"p\":1,\"n\":\"End Hour\"},{\"t\":3,\"p\":1,\"n\":\"Radius\"},{\"t\":11,\"n\":\"Unknown 1\"},{\"t\":3,\"p\":1,\"n\":\"Buys Stolen Items\"},{\"t\":3,\"p\":1,\"n\":\"Buy\\/Sell Everything Not In List?\"},{\"t\":3,\"p\":1,\"n\":\"Buys NonStolen Items\"},{\"t\":3,\"n\":\"Unknown\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"PLVD - Location\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":3,\"p\":1,\"n\":\"Cell\"},{\"t\":11,\"p\":1,\"n\":\"Near Package Start Location\"},{\"t\":11,\"p\":1,\"n\":\"Near Editor Location\"},{\"t\":3,\"p\":1,\"n\":\"Object ID\"},{\"t\":3,\"p\":1,\"n\":\"Object Type\"},{\"t\":3,\"p\":1,\"n\":\"Keyword\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Ref Alias\"},{\"t\":3,\"p\":1,\"n\":\"Loc Alias\"},{\"t\":3,\"p\":1,\"n\":\"Interrupt Data\"},{\"t\":3,\"p\":1,\"n\":\"Packdata Target\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":3,\"p\":1,\"n\":\"Ref Collection Alias\"},{\"t\":3,\"p\":1,\"n\":\"Radius\"},{\"t\":3,\"p\":1,\"n\":\"Collection Index\"}]},{\"t\":3,\"n\":\"CITC - Condition Count\"},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Conditions\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Condition\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"CTDA - \",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":5,\"p\":1,\"n\":\"Comparison Value - Float\"},{\"t\":3,\"p\":1,\"n\":\"Comparison Value - Global\"},{\"t\":3,\"p\":1,\"n\":\"Function\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":11,\"p\":1,\"n\":\"None\"},{\"t\":3,\"p\":1,\"n\":\"Integer\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":3,\"p\":1,\"n\":\"Actor\"},{\"t\":3,\"p\":1,\"n\":\"Actor Base\"},{\"t\":3,\"p\":1,\"n\":\"Actor Value\"},{\"t\":3,\"p\":1,\"n\":\"Player Action\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"Alignment\"},{\"t\":3,\"p\":1,\"n\":\"Association Type\"},{\"t\":3,\"p\":1,\"n\":\"Axis\"},{\"t\":3,\"p\":1,\"n\":\"Casting Type\"},{\"t\":3,\"p\":1,\"n\":\"Cell\"},{\"t\":3,\"p\":1,\"n\":\"Class\"},{\"t\":3,\"p\":1,\"n\":\"Crime Type\"},{\"t\":3,\"p\":1,\"n\":\"Critical Stage\"},{\"t\":3,\"p\":1,\"n\":\"Encounter Zone\"},{\"t\":3,\"p\":1,\"n\":\"Equip Type\"},{\"t\":3,\"p\":1,\"n\":\"Event\"},{\"t\":3,\"p\":1,\"n\":\"Event Data\"},{\"t\":3,\"p\":1,\"n\":\"Faction\"},{\"t\":3,\"p\":1,\"n\":\"Form List\"},{\"t\":3,\"p\":1,\"n\":\"Form Type\"},{\"t\":3,\"p\":1,\"n\":\"Furniture\"},{\"t\":3,\"p\":1,\"n\":\"Furniture Anim\"},{\"t\":3,\"p\":1,\"n\":\"Furniture Entry\"},{\"t\":3,\"p\":1,\"n\":\"Global\"},{\"t\":3,\"p\":1,\"n\":\"Idle\"},{\"t\":3,\"p\":1,\"n\":\"Inventory Object\"},{\"t\":3,\"p\":1,\"n\":\"Keyword\"},{\"t\":3,\"p\":1,\"n\":\"Location\"},{\"t\":3,\"p\":1,\"n\":\"Base Effect\"},{\"t\":3,\"p\":1,\"n\":\"Effect Item\"},{\"t\":3,\"p\":1,\"n\":\"Misc Stat\"},{\"t\":3,\"p\":1,\"n\":\"Object Reference\"},{\"t\":3,\"p\":1,\"n\":\"Owner\"},{\"t\":3,\"p\":1,\"n\":\"Package\"},{\"t\":3,\"p\":1,\"n\":\"Packdata ID\"},{\"t\":3,\"p\":1,\"n\":\"Perk\"},{\"t\":3,\"p\":1,\"n\":\"Quest\"},{\"t\":3,\"p\":1,\"n\":\"Quest Stage\"},{\"t\":3,\"p\":1,\"n\":\"Race\"},{\"t\":3,\"p\":1,\"n\":\"Referenceable Object\"},{\"t\":3,\"p\":1,\"n\":\"Location Ref Type\"},{\"t\":3,\"p\":1,\"n\":\"Region\"},{\"t\":3,\"p\":1,\"n\":\"Scene\"},{\"t\":3,\"p\":1,\"n\":\"Sex\"},{\"t\":3,\"p\":1,\"n\":\"Shout\"},{\"t\":11,\"p\":1,\"n\":\"Variable Name (unused)\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Function\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Param (unused)\"},{\"t\":3,\"p\":1,\"n\":\"Voice Type\"},{\"t\":3,\"p\":1,\"n\":\"Ward State\"},{\"t\":3,\"p\":1,\"n\":\"Weather\"},{\"t\":3,\"p\":1,\"n\":\"Worldspace\"},{\"t\":3,\"p\":1,\"n\":\"Damage Type\"},{\"t\":3,\"p\":1,\"n\":\"Weapon\"},{\"t\":3,\"p\":1,\"n\":\"Weapon List\"},{\"t\":3,\"p\":1,\"n\":\"Target\"},{\"t\":3,\"p\":1,\"n\":\"Target List\"},{\"t\":3,\"p\":1,\"n\":\"Target Part\"},{\"t\":3,\"p\":1,\"n\":\"VATS Action\"},{\"t\":3,\"p\":1,\"n\":\"Critical Effect\"},{\"t\":3,\"p\":1,\"n\":\"Critical Effect List\"},{\"t\":3,\"p\":1,\"n\":\"Weapon Type\"},{\"t\":3,\"p\":1,\"n\":\"Projectile Type\"},{\"t\":3,\"p\":1,\"n\":\"Delivery Type\"},{\"t\":3,\"p\":1,\"n\":\"Run On\"},{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":3,\"p\":1,\"n\":\"Parameter #3\"}]},{\"t\":2,\"p\":1,\"n\":\"CIS1 - Parameter #1\"},{\"t\":2,\"p\":1,\"n\":\"CIS2 - Parameter #2\"}]}]}]},{\"t\":1,\"p\":1,\"n\":\"FLOR - Flora\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"VMAD - Virtual Machine Adapter\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Version\"},{\"t\":3,\"p\":1,\"n\":\"Object Format\"},{\"t\":7,\"p\":1,\"n\":\"Scripts\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Script\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"scriptName\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":7,\"p\":1,\"n\":\"Properties\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Property\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"propertyName\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]},{\"t\":2,\"p\":1,\"n\":\"String\"},{\"t\":3,\"p\":1,\"n\":\"Int32\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":3,\"p\":1,\"n\":\"Bool\"},{\"t\":7,\"p\":1,\"n\":\"Struct\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Member\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"memberName\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]},{\"t\":2,\"p\":1,\"n\":\"String\"},{\"t\":3,\"p\":1,\"n\":\"Int32\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":3,\"p\":1,\"n\":\"Bool\"},{\"t\":7,\"p\":1,\"n\":\"Array of Object\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]}]},{\"t\":7,\"p\":1,\"n\":\"Array of String\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Int32\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Float\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Bool\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]}]}]},{\"t\":7,\"p\":1,\"n\":\"Array of Object\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]}]},{\"t\":7,\"p\":1,\"n\":\"Array of String\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Int32\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Float\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Bool\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Struct\",\"c\":[{\"t\":7,\"p\":1,\"n\":\"Struct\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Member\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"memberName\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]},{\"t\":2,\"p\":1,\"n\":\"String\"},{\"t\":3,\"p\":1,\"n\":\"Int32\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":3,\"p\":1,\"n\":\"Bool\"},{\"t\":7,\"p\":1,\"n\":\"Array of Object\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]}]},{\"t\":7,\"p\":1,\"n\":\"Array of String\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Int32\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Float\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Bool\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]}]}]}]}]}]}]}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"X1\"},{\"t\":3,\"p\":1,\"n\":\"Y1\"},{\"t\":3,\"p\":1,\"n\":\"Z1\"},{\"t\":3,\"p\":1,\"n\":\"X2\"},{\"t\":3,\"p\":1,\"n\":\"Y2\"},{\"t\":3,\"p\":1,\"n\":\"Z2\"}]},{\"t\":3,\"p\":1,\"n\":\"PTRN - Preview Transform\"},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"MODT - Texture Files Hashes\"},{\"t\":3,\"p\":1,\"n\":\"MODS - Material Swap\"},{\"t\":5,\"p\":1,\"n\":\"MODC - Color Remapping Index\"},{\"t\":11,\"n\":\"MODF - Unknown\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Destructible\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"DEST - Header\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Health\"},{\"t\":3,\"p\":1,\"n\":\"DEST Count\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":7,\"p\":1,\"n\":\"DAMC - Resistances\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Resistance\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Damage Type\"},{\"t\":3,\"p\":1,\"n\":\"Value\"}]}]},{\"t\":8,\"p\":1,\"n\":\"Stages\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Stage\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"DSTD - Destruction Stage Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Health %\"},{\"t\":3,\"p\":1,\"n\":\"Index\"},{\"t\":3,\"p\":1,\"n\":\"Model Damage Stage\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":3,\"p\":1,\"n\":\"Self Damage per Second\"},{\"t\":3,\"p\":1,\"n\":\"Explosion\"},{\"t\":3,\"p\":1,\"n\":\"Debris\"},{\"t\":3,\"p\":1,\"n\":\"Debris Count\"}]},{\"t\":2,\"p\":1,\"n\":\"DSTA - Sequence Name\"},{\"t\":6,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"DMDL - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"DMDT - Texture Files Hashes\"},{\"t\":5,\"p\":1,\"n\":\"DMDC - Color Remapping Index\"},{\"t\":3,\"p\":1,\"n\":\"DMDS - Material Swap\"}]},{\"p\":1,\"n\":\"DSTF - End Marker\"}]}]}]},{\"t\":3,\"n\":\"KSIZ - Keyword Count\"},{\"t\":7,\"p\":1,\"n\":\"KWDA - Keywords\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Keyword\"}]},{\"t\":7,\"p\":1,\"n\":\"PRPS - Properties\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Property\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Actor Value\"},{\"t\":5,\"p\":1,\"n\":\"Value\"}]}]},{\"t\":11,\"n\":\"PNAM - Unknown\"},{\"t\":2,\"p\":1,\"n\":\"ATTX - Activate Text Override\"},{\"t\":2,\"p\":1,\"n\":\"RNAM - Activate Text Override\"},{\"t\":11,\"n\":\"FNAM - Unknown\"},{\"t\":3,\"p\":1,\"n\":\"PFIG - Ingredient\"},{\"t\":3,\"p\":1,\"n\":\"SNAM - Harvest Sound\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"PFPC - Ingredient Production\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Spring\"},{\"t\":3,\"p\":1,\"n\":\"Summer \"},{\"t\":3,\"p\":1,\"n\":\"Fall\"},{\"t\":3,\"p\":1,\"n\":\"Winter\"}]}]},{\"t\":1,\"p\":1,\"n\":\"FLST - FormID List\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"FormIDs\",\"d\":1,\"c\":[{\"t\":3,\"p\":1,\"n\":\"LNAM - FormID\"}]}]},{\"t\":1,\"p\":1,\"n\":\"FSTP - Footstep\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":3,\"p\":1,\"n\":\"DATA - Impact Data Set\"},{\"t\":2,\"p\":1,\"n\":\"ANAM - Tag\"}]},{\"t\":1,\"p\":1,\"n\":\"FSTS - Footstep Set\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"n\":\"XCNT - Count\",\"c\":[{\"t\":3,\"n\":\"Walking\"},{\"t\":3,\"n\":\"Running\"},{\"t\":3,\"n\":\"Sprinting\"},{\"t\":3,\"n\":\"Sneaking\"},{\"t\":3,\"n\":\"Swimming\"}]},{\"t\":7,\"p\":1,\"n\":\"DATA - Footstep Sets\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Footstep\"}]}]},{\"t\":1,\"p\":1,\"n\":\"FURN - Furniture\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"VMAD - Virtual Machine Adapter\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Version\"},{\"t\":3,\"p\":1,\"n\":\"Object Format\"},{\"t\":7,\"p\":1,\"n\":\"Scripts\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Script\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"scriptName\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":7,\"p\":1,\"n\":\"Properties\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Property\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"propertyName\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]},{\"t\":2,\"p\":1,\"n\":\"String\"},{\"t\":3,\"p\":1,\"n\":\"Int32\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":3,\"p\":1,\"n\":\"Bool\"},{\"t\":7,\"p\":1,\"n\":\"Struct\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Member\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"memberName\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]},{\"t\":2,\"p\":1,\"n\":\"String\"},{\"t\":3,\"p\":1,\"n\":\"Int32\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":3,\"p\":1,\"n\":\"Bool\"},{\"t\":7,\"p\":1,\"n\":\"Array of Object\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]}]},{\"t\":7,\"p\":1,\"n\":\"Array of String\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Int32\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Float\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Bool\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]}]}]},{\"t\":7,\"p\":1,\"n\":\"Array of Object\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]}]},{\"t\":7,\"p\":1,\"n\":\"Array of String\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Int32\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Float\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Bool\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Struct\",\"c\":[{\"t\":7,\"p\":1,\"n\":\"Struct\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Member\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"memberName\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]},{\"t\":2,\"p\":1,\"n\":\"String\"},{\"t\":3,\"p\":1,\"n\":\"Int32\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":3,\"p\":1,\"n\":\"Bool\"},{\"t\":7,\"p\":1,\"n\":\"Array of Object\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]}]},{\"t\":7,\"p\":1,\"n\":\"Array of String\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Int32\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Float\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Bool\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]}]}]}]}]}]}]}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"X1\"},{\"t\":3,\"p\":1,\"n\":\"Y1\"},{\"t\":3,\"p\":1,\"n\":\"Z1\"},{\"t\":3,\"p\":1,\"n\":\"X2\"},{\"t\":3,\"p\":1,\"n\":\"Y2\"},{\"t\":3,\"p\":1,\"n\":\"Z2\"}]},{\"t\":3,\"p\":1,\"n\":\"PTRN - Preview Transform\"},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"MODT - Texture Files Hashes\"},{\"t\":3,\"p\":1,\"n\":\"MODS - Material Swap\"},{\"t\":5,\"p\":1,\"n\":\"MODC - Color Remapping Index\"},{\"t\":11,\"n\":\"MODF - Unknown\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Destructible\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"DEST - Header\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Health\"},{\"t\":3,\"p\":1,\"n\":\"DEST Count\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":7,\"p\":1,\"n\":\"DAMC - Resistances\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Resistance\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Damage Type\"},{\"t\":3,\"p\":1,\"n\":\"Value\"}]}]},{\"t\":8,\"p\":1,\"n\":\"Stages\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Stage\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"DSTD - Destruction Stage Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Health %\"},{\"t\":3,\"p\":1,\"n\":\"Index\"},{\"t\":3,\"p\":1,\"n\":\"Model Damage Stage\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":3,\"p\":1,\"n\":\"Self Damage per Second\"},{\"t\":3,\"p\":1,\"n\":\"Explosion\"},{\"t\":3,\"p\":1,\"n\":\"Debris\"},{\"t\":3,\"p\":1,\"n\":\"Debris Count\"}]},{\"t\":2,\"p\":1,\"n\":\"DSTA - Sequence Name\"},{\"t\":6,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"DMDL - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"DMDT - Texture Files Hashes\"},{\"t\":5,\"p\":1,\"n\":\"DMDC - Color Remapping Index\"},{\"t\":3,\"p\":1,\"n\":\"DMDS - Material Swap\"}]},{\"p\":1,\"n\":\"DSTF - End Marker\"}]}]}]},{\"t\":3,\"n\":\"KSIZ - Keyword Count\"},{\"t\":7,\"p\":1,\"n\":\"KWDA - Keywords\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Keyword\"}]},{\"t\":7,\"p\":1,\"n\":\"PRPS - Properties\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Property\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Actor Value\"},{\"t\":5,\"p\":1,\"n\":\"Value\"}]}]},{\"t\":3,\"p\":1,\"n\":\"NTRM - Native Terminal\"},{\"t\":3,\"p\":1,\"n\":\"FTYP - Forced Loc Ref Type\"},{\"t\":11,\"n\":\"PNAM - Unknown\"},{\"t\":3,\"p\":1,\"n\":\"WNAM - Drinking Water Type\"},{\"t\":2,\"p\":1,\"n\":\"ATTX - Activate Text Override\"},{\"t\":3,\"p\":1,\"n\":\"FNAM - Flags\"},{\"t\":3,\"n\":\"CITC - Condition Count\"},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Conditions\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Condition\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"CTDA - \",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":5,\"p\":1,\"n\":\"Comparison Value - Float\"},{\"t\":3,\"p\":1,\"n\":\"Comparison Value - Global\"},{\"t\":3,\"p\":1,\"n\":\"Function\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":11,\"p\":1,\"n\":\"None\"},{\"t\":3,\"p\":1,\"n\":\"Integer\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":3,\"p\":1,\"n\":\"Actor\"},{\"t\":3,\"p\":1,\"n\":\"Actor Base\"},{\"t\":3,\"p\":1,\"n\":\"Actor Value\"},{\"t\":3,\"p\":1,\"n\":\"Player Action\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"Alignment\"},{\"t\":3,\"p\":1,\"n\":\"Association Type\"},{\"t\":3,\"p\":1,\"n\":\"Axis\"},{\"t\":3,\"p\":1,\"n\":\"Casting Type\"},{\"t\":3,\"p\":1,\"n\":\"Cell\"},{\"t\":3,\"p\":1,\"n\":\"Class\"},{\"t\":3,\"p\":1,\"n\":\"Crime Type\"},{\"t\":3,\"p\":1,\"n\":\"Critical Stage\"},{\"t\":3,\"p\":1,\"n\":\"Encounter Zone\"},{\"t\":3,\"p\":1,\"n\":\"Equip Type\"},{\"t\":3,\"p\":1,\"n\":\"Event\"},{\"t\":3,\"p\":1,\"n\":\"Event Data\"},{\"t\":3,\"p\":1,\"n\":\"Faction\"},{\"t\":3,\"p\":1,\"n\":\"Form List\"},{\"t\":3,\"p\":1,\"n\":\"Form Type\"},{\"t\":3,\"p\":1,\"n\":\"Furniture\"},{\"t\":3,\"p\":1,\"n\":\"Furniture Anim\"},{\"t\":3,\"p\":1,\"n\":\"Furniture Entry\"},{\"t\":3,\"p\":1,\"n\":\"Global\"},{\"t\":3,\"p\":1,\"n\":\"Idle\"},{\"t\":3,\"p\":1,\"n\":\"Inventory Object\"},{\"t\":3,\"p\":1,\"n\":\"Keyword\"},{\"t\":3,\"p\":1,\"n\":\"Location\"},{\"t\":3,\"p\":1,\"n\":\"Base Effect\"},{\"t\":3,\"p\":1,\"n\":\"Effect Item\"},{\"t\":3,\"p\":1,\"n\":\"Misc Stat\"},{\"t\":3,\"p\":1,\"n\":\"Object Reference\"},{\"t\":3,\"p\":1,\"n\":\"Owner\"},{\"t\":3,\"p\":1,\"n\":\"Package\"},{\"t\":3,\"p\":1,\"n\":\"Packdata ID\"},{\"t\":3,\"p\":1,\"n\":\"Perk\"},{\"t\":3,\"p\":1,\"n\":\"Quest\"},{\"t\":3,\"p\":1,\"n\":\"Quest Stage\"},{\"t\":3,\"p\":1,\"n\":\"Race\"},{\"t\":3,\"p\":1,\"n\":\"Referenceable Object\"},{\"t\":3,\"p\":1,\"n\":\"Location Ref Type\"},{\"t\":3,\"p\":1,\"n\":\"Region\"},{\"t\":3,\"p\":1,\"n\":\"Scene\"},{\"t\":3,\"p\":1,\"n\":\"Sex\"},{\"t\":3,\"p\":1,\"n\":\"Shout\"},{\"t\":11,\"p\":1,\"n\":\"Variable Name (unused)\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Function\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Param (unused)\"},{\"t\":3,\"p\":1,\"n\":\"Voice Type\"},{\"t\":3,\"p\":1,\"n\":\"Ward State\"},{\"t\":3,\"p\":1,\"n\":\"Weather\"},{\"t\":3,\"p\":1,\"n\":\"Worldspace\"},{\"t\":3,\"p\":1,\"n\":\"Damage Type\"},{\"t\":3,\"p\":1,\"n\":\"Weapon\"},{\"t\":3,\"p\":1,\"n\":\"Weapon List\"},{\"t\":3,\"p\":1,\"n\":\"Target\"},{\"t\":3,\"p\":1,\"n\":\"Target List\"},{\"t\":3,\"p\":1,\"n\":\"Target Part\"},{\"t\":3,\"p\":1,\"n\":\"VATS Action\"},{\"t\":3,\"p\":1,\"n\":\"Critical Effect\"},{\"t\":3,\"p\":1,\"n\":\"Critical Effect List\"},{\"t\":3,\"p\":1,\"n\":\"Weapon Type\"},{\"t\":3,\"p\":1,\"n\":\"Projectile Type\"},{\"t\":3,\"p\":1,\"n\":\"Delivery Type\"},{\"t\":3,\"p\":1,\"n\":\"Run On\"},{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":3,\"p\":1,\"n\":\"Parameter #3\"}]},{\"t\":2,\"p\":1,\"n\":\"CIS1 - Parameter #1\"},{\"t\":2,\"p\":1,\"n\":\"CIS2 - Parameter #2\"}]}]},{\"t\":3,\"n\":\"COCT - Count\"},{\"t\":10,\"p\":1,\"n\":\"Items\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Item\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"CNTO - Item\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Item\"},{\"t\":3,\"p\":1,\"n\":\"Count\"}]},{\"t\":6,\"p\":1,\"n\":\"COED - Extra Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Owner\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Global Variable\"},{\"t\":3,\"p\":1,\"n\":\"Required Rank\"},{\"t\":5,\"p\":1,\"n\":\"Item Condition\"}]}]}]},{\"t\":3,\"p\":1,\"n\":\"MNAM - Active Markers \\/ Flags\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"WBDT - Workbench Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Bench Type\"},{\"t\":3,\"p\":1,\"n\":\"Uses Skill\"}]},{\"t\":3,\"p\":1,\"n\":\"NAM1 - Associated Form\"},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Markers\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Marker\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"ENAM - Marker Index\"},{\"t\":6,\"p\":1,\"n\":\"NAM0 - Disabled Entry Points\",\"c\":[{\"t\":11,\"n\":\"Unknown\"},{\"t\":3,\"p\":1,\"n\":\"Disabled Points\"}]}]}]},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Marker Entry Points\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"FNPR - Marker\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Entry Points\"}]}]},{\"t\":2,\"p\":1,\"n\":\"XMRK - Marker Model\"},{\"t\":7,\"p\":1,\"n\":\"SNAM - Marker Paramaters\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Marker\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Offset X\"},{\"t\":5,\"p\":1,\"n\":\"Offset Y\"},{\"t\":5,\"p\":1,\"n\":\"Offset Z\"},{\"t\":5,\"p\":1,\"n\":\"Rotation Z\"},{\"t\":3,\"p\":1,\"n\":\"Keyword\"},{\"t\":3,\"p\":1,\"n\":\"Entry Types\"},{\"t\":11,\"n\":\"Unknown\"}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"NVNM - Navmesh Geometry\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Version\"},{\"t\":11,\"p\":1,\"n\":\"Magic\"},{\"t\":3,\"p\":1,\"n\":\"Parent Worldspace\"},{\"t\":6,\"p\":1,\"n\":\"Coordinates\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Grid Y\"},{\"t\":3,\"p\":1,\"n\":\"Grid X\"}]},{\"t\":3,\"p\":1,\"n\":\"Parent Cell\"},{\"t\":11,\"p\":1,\"n\":\"Vertices and Triangles\"}]},{\"t\":7,\"p\":1,\"n\":\"APPR - Attach Parent Slots\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Keyword\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Object Template\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"OBTE - Count\"},{\"t\":8,\"p\":1,\"n\":\"Combinations\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Combination\",\"c\":[{\"p\":1,\"n\":\"OBTF - Editor Only\"},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":6,\"p\":1,\"n\":\"OBTS - Object Mod Template Item\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Include Count\"},{\"t\":3,\"p\":1,\"n\":\"Property Count\"},{\"t\":3,\"p\":1,\"n\":\"Level Min\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Level Max\"},{\"t\":3,\"p\":1,\"n\":\"ID\"},{\"t\":3,\"p\":1,\"n\":\"Default\"},{\"t\":7,\"p\":1,\"n\":\"Keywords\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Keyword\"}]},{\"t\":3,\"p\":1,\"n\":\"Min Level For Ranks\"},{\"t\":3,\"p\":1,\"n\":\"Alt Levels Per Tier\"},{\"t\":7,\"p\":1,\"n\":\"Includes\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Include\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Mod\"},{\"t\":3,\"p\":1,\"n\":\"Attach Point Index\"},{\"t\":3,\"p\":1,\"n\":\"Optional\"},{\"t\":3,\"p\":1,\"n\":\"Don't Use All\"}]}]},{\"t\":7,\"p\":1,\"n\":\"Properties\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Property\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Value Type\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Function Type\"},{\"t\":3,\"p\":1,\"n\":\"Property\"},{\"t\":11,\"n\":\"Value 1 - Unknown\"},{\"t\":3,\"p\":1,\"n\":\"Value 1 - Int\"},{\"t\":5,\"p\":1,\"n\":\"Value 1 - Float\"},{\"t\":3,\"p\":1,\"n\":\"Value 1 - Bool\"},{\"t\":3,\"p\":1,\"n\":\"Value 1 - FormID\"},{\"t\":3,\"p\":1,\"n\":\"Value 1 - Enum\"},{\"t\":3,\"p\":1,\"n\":\"Sound Level\"},{\"t\":3,\"p\":1,\"n\":\"Stagger Value\"},{\"t\":3,\"p\":1,\"n\":\"Hit Behaviour\"},{\"t\":3,\"p\":1,\"n\":\"Value 2 - Int\"},{\"t\":5,\"p\":1,\"n\":\"Value 2 - Float\"},{\"t\":3,\"p\":1,\"n\":\"Value 2 - Bool\"},{\"t\":5,\"p\":1,\"n\":\"Step\"}]}]}]}]}]},{\"p\":1,\"n\":\"STOP - Marker\"}]}]},{\"t\":1,\"p\":1,\"n\":\"GDRY - God Rays\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DATA - Data\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Back Color\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Red\"},{\"t\":5,\"p\":1,\"n\":\"Green\"},{\"t\":5,\"p\":1,\"n\":\"Blue\"}]},{\"t\":6,\"p\":1,\"n\":\"Fwd Color\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Red\"},{\"t\":5,\"p\":1,\"n\":\"Green\"},{\"t\":5,\"p\":1,\"n\":\"Blue\"}]},{\"t\":5,\"p\":1,\"n\":\"Intensity\"},{\"t\":5,\"p\":1,\"n\":\"Air Color - Scale\"},{\"t\":5,\"p\":1,\"n\":\"Back Color - Scale\"},{\"t\":5,\"p\":1,\"n\":\"Fwd Color - Scale\"},{\"t\":5,\"p\":1,\"n\":\"Back Phase\"},{\"t\":6,\"p\":1,\"n\":\"Air Color\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Red\"},{\"t\":5,\"p\":1,\"n\":\"Green\"},{\"t\":5,\"p\":1,\"n\":\"Blue\"}]},{\"t\":5,\"p\":1,\"n\":\"Fwd Phase\"}]}]},{\"t\":1,\"p\":1,\"n\":\"GLOB - Global\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":3,\"p\":1,\"n\":\"FNAM - Type\"},{\"t\":5,\"p\":1,\"n\":\"FLTV - Value\"}]},{\"t\":1,\"p\":1,\"n\":\"GMST - Game Setting\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"p\":1,\"n\":\"Name\"},{\"t\":3,\"p\":1,\"n\":\"Int\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":3,\"p\":1,\"n\":\"Bool\"}]},{\"t\":1,\"p\":1,\"n\":\"GRAS - Grass\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"X1\"},{\"t\":3,\"p\":1,\"n\":\"Y1\"},{\"t\":3,\"p\":1,\"n\":\"Z1\"},{\"t\":3,\"p\":1,\"n\":\"X2\"},{\"t\":3,\"p\":1,\"n\":\"Y2\"},{\"t\":3,\"p\":1,\"n\":\"Z2\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"MODT - Texture Files Hashes\"},{\"t\":3,\"p\":1,\"n\":\"MODS - Material Swap\"},{\"t\":5,\"p\":1,\"n\":\"MODC - Color Remapping Index\"},{\"t\":11,\"n\":\"MODF - Unknown\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DATA - \",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Density\"},{\"t\":3,\"p\":1,\"n\":\"Min Slope\"},{\"t\":3,\"p\":1,\"n\":\"Max Slope\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":3,\"p\":1,\"n\":\"Units From Water\"},{\"t\":3,\"p\":1,\"n\":\"Units From Water Type\"},{\"t\":5,\"p\":1,\"n\":\"Position Range\"},{\"t\":5,\"p\":1,\"n\":\"Height Range\"},{\"t\":5,\"p\":1,\"n\":\"Color Range\"},{\"t\":5,\"p\":1,\"n\":\"Wave Period\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"}]}]},{\"t\":1,\"p\":1,\"n\":\"HAZD - Hazard\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"X1\"},{\"t\":3,\"p\":1,\"n\":\"Y1\"},{\"t\":3,\"p\":1,\"n\":\"Z1\"},{\"t\":3,\"p\":1,\"n\":\"X2\"},{\"t\":3,\"p\":1,\"n\":\"Y2\"},{\"t\":3,\"p\":1,\"n\":\"Z2\"}]},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"MODT - Texture Files Hashes\"},{\"t\":3,\"p\":1,\"n\":\"MODS - Material Swap\"},{\"t\":5,\"p\":1,\"n\":\"MODC - Color Remapping Index\"},{\"t\":11,\"n\":\"MODF - Unknown\"}]},{\"t\":3,\"p\":1,\"n\":\"MNAM - Image Space Modifier\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DNAM - Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Limit\"},{\"t\":5,\"p\":1,\"n\":\"Radius\"},{\"t\":5,\"p\":1,\"n\":\"Lifetime\"},{\"t\":5,\"p\":1,\"n\":\"Image Space Radius\"},{\"t\":5,\"p\":1,\"n\":\"Target Interval\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":3,\"p\":1,\"n\":\"Effect\"},{\"t\":3,\"p\":1,\"n\":\"Light\"},{\"t\":3,\"p\":1,\"n\":\"Impact Data Set\"},{\"t\":3,\"p\":1,\"n\":\"Sound\"},{\"t\":6,\"p\":1,\"n\":\"Taper Effectiveness\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Full Effect Radius\"},{\"t\":5,\"p\":1,\"n\":\"Taper Weight\"},{\"t\":5,\"p\":1,\"n\":\"Taper Curse\"}]}]}]},{\"t\":1,\"p\":1,\"n\":\"HDPT - Head Part\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"MODT - Texture Files Hashes\"},{\"t\":3,\"p\":1,\"n\":\"MODS - Material Swap\"},{\"t\":5,\"p\":1,\"n\":\"MODC - Color Remapping Index\"},{\"t\":11,\"n\":\"MODF - Unknown\"}]},{\"t\":3,\"p\":1,\"n\":\"DATA - Flags\"},{\"t\":3,\"p\":1,\"n\":\"PNAM - Type\"},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Extra Parts\",\"d\":1,\"c\":[{\"t\":3,\"p\":1,\"n\":\"HNAM - Part\"}]},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Parts\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Part\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"NAM0 - Part Type\"},{\"t\":2,\"p\":1,\"n\":\"NAM1 - Filename\"}]}]},{\"t\":3,\"p\":1,\"n\":\"TNAM - Texture Set\"},{\"t\":3,\"p\":1,\"n\":\"CNAM - Color\"},{\"t\":3,\"p\":1,\"n\":\"RNAM - Valid Races\"},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Conditions\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Condition\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"CTDA - \",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":5,\"p\":1,\"n\":\"Comparison Value - Float\"},{\"t\":3,\"p\":1,\"n\":\"Comparison Value - Global\"},{\"t\":3,\"p\":1,\"n\":\"Function\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":11,\"p\":1,\"n\":\"None\"},{\"t\":3,\"p\":1,\"n\":\"Integer\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":3,\"p\":1,\"n\":\"Actor\"},{\"t\":3,\"p\":1,\"n\":\"Actor Base\"},{\"t\":3,\"p\":1,\"n\":\"Actor Value\"},{\"t\":3,\"p\":1,\"n\":\"Player Action\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"Alignment\"},{\"t\":3,\"p\":1,\"n\":\"Association Type\"},{\"t\":3,\"p\":1,\"n\":\"Axis\"},{\"t\":3,\"p\":1,\"n\":\"Casting Type\"},{\"t\":3,\"p\":1,\"n\":\"Cell\"},{\"t\":3,\"p\":1,\"n\":\"Class\"},{\"t\":3,\"p\":1,\"n\":\"Crime Type\"},{\"t\":3,\"p\":1,\"n\":\"Critical Stage\"},{\"t\":3,\"p\":1,\"n\":\"Encounter Zone\"},{\"t\":3,\"p\":1,\"n\":\"Equip Type\"},{\"t\":3,\"p\":1,\"n\":\"Event\"},{\"t\":3,\"p\":1,\"n\":\"Event Data\"},{\"t\":3,\"p\":1,\"n\":\"Faction\"},{\"t\":3,\"p\":1,\"n\":\"Form List\"},{\"t\":3,\"p\":1,\"n\":\"Form Type\"},{\"t\":3,\"p\":1,\"n\":\"Furniture\"},{\"t\":3,\"p\":1,\"n\":\"Furniture Anim\"},{\"t\":3,\"p\":1,\"n\":\"Furniture Entry\"},{\"t\":3,\"p\":1,\"n\":\"Global\"},{\"t\":3,\"p\":1,\"n\":\"Idle\"},{\"t\":3,\"p\":1,\"n\":\"Inventory Object\"},{\"t\":3,\"p\":1,\"n\":\"Keyword\"},{\"t\":3,\"p\":1,\"n\":\"Location\"},{\"t\":3,\"p\":1,\"n\":\"Base Effect\"},{\"t\":3,\"p\":1,\"n\":\"Effect Item\"},{\"t\":3,\"p\":1,\"n\":\"Misc Stat\"},{\"t\":3,\"p\":1,\"n\":\"Object Reference\"},{\"t\":3,\"p\":1,\"n\":\"Owner\"},{\"t\":3,\"p\":1,\"n\":\"Package\"},{\"t\":3,\"p\":1,\"n\":\"Packdata ID\"},{\"t\":3,\"p\":1,\"n\":\"Perk\"},{\"t\":3,\"p\":1,\"n\":\"Quest\"},{\"t\":3,\"p\":1,\"n\":\"Quest Stage\"},{\"t\":3,\"p\":1,\"n\":\"Race\"},{\"t\":3,\"p\":1,\"n\":\"Referenceable Object\"},{\"t\":3,\"p\":1,\"n\":\"Location Ref Type\"},{\"t\":3,\"p\":1,\"n\":\"Region\"},{\"t\":3,\"p\":1,\"n\":\"Scene\"},{\"t\":3,\"p\":1,\"n\":\"Sex\"},{\"t\":3,\"p\":1,\"n\":\"Shout\"},{\"t\":11,\"p\":1,\"n\":\"Variable Name (unused)\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Function\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Param (unused)\"},{\"t\":3,\"p\":1,\"n\":\"Voice Type\"},{\"t\":3,\"p\":1,\"n\":\"Ward State\"},{\"t\":3,\"p\":1,\"n\":\"Weather\"},{\"t\":3,\"p\":1,\"n\":\"Worldspace\"},{\"t\":3,\"p\":1,\"n\":\"Damage Type\"},{\"t\":3,\"p\":1,\"n\":\"Weapon\"},{\"t\":3,\"p\":1,\"n\":\"Weapon List\"},{\"t\":3,\"p\":1,\"n\":\"Target\"},{\"t\":3,\"p\":1,\"n\":\"Target List\"},{\"t\":3,\"p\":1,\"n\":\"Target Part\"},{\"t\":3,\"p\":1,\"n\":\"VATS Action\"},{\"t\":3,\"p\":1,\"n\":\"Critical Effect\"},{\"t\":3,\"p\":1,\"n\":\"Critical Effect List\"},{\"t\":3,\"p\":1,\"n\":\"Weapon Type\"},{\"t\":3,\"p\":1,\"n\":\"Projectile Type\"},{\"t\":3,\"p\":1,\"n\":\"Delivery Type\"},{\"t\":3,\"p\":1,\"n\":\"Run On\"},{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":3,\"p\":1,\"n\":\"Parameter #3\"}]},{\"t\":2,\"p\":1,\"n\":\"CIS1 - Parameter #1\"},{\"t\":2,\"p\":1,\"n\":\"CIS2 - Parameter #2\"}]}]}]},{\"t\":1,\"n\":\"IDLE - Idle Animation\",\"c\":[{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":8,\"n\":\"Conditions\",\"d\":1,\"c\":[{\"t\":6,\"n\":\"Condition\",\"c\":[{\"t\":6,\"n\":\"CTDA - \",\"c\":[{\"t\":3,\"n\":\"Type\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":5,\"n\":\"Comparison Value - Float\"},{\"t\":3,\"n\":\"Comparison Value - Global\"},{\"t\":3,\"n\":\"Function\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":11,\"n\":\"None\"},{\"t\":3,\"n\":\"Integer\"},{\"t\":5,\"n\":\"Float\"},{\"t\":3,\"n\":\"Actor\"},{\"t\":3,\"n\":\"Actor Base\"},{\"t\":3,\"n\":\"Actor Value\"},{\"t\":3,\"n\":\"Player Action\"},{\"t\":3,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Alignment\"},{\"t\":3,\"n\":\"Association Type\"},{\"t\":3,\"n\":\"Axis\"},{\"t\":3,\"n\":\"Casting Type\"},{\"t\":3,\"n\":\"Cell\"},{\"t\":3,\"n\":\"Class\"},{\"t\":3,\"n\":\"Crime Type\"},{\"t\":3,\"n\":\"Critical Stage\"},{\"t\":3,\"n\":\"Encounter Zone\"},{\"t\":3,\"n\":\"Equip Type\"},{\"t\":3,\"n\":\"Event\"},{\"t\":3,\"n\":\"Event Data\"},{\"t\":3,\"n\":\"Faction\"},{\"t\":3,\"n\":\"Form List\"},{\"t\":3,\"n\":\"Form Type\"},{\"t\":3,\"n\":\"Furniture\"},{\"t\":3,\"n\":\"Furniture Anim\"},{\"t\":3,\"n\":\"Furniture Entry\"},{\"t\":3,\"n\":\"Global\"},{\"t\":3,\"n\":\"Idle\"},{\"t\":3,\"n\":\"Inventory Object\"},{\"t\":3,\"n\":\"Keyword\"},{\"t\":3,\"n\":\"Location\"},{\"t\":3,\"n\":\"Base Effect\"},{\"t\":3,\"n\":\"Effect Item\"},{\"t\":3,\"n\":\"Misc Stat\"},{\"t\":3,\"n\":\"Object Reference\"},{\"t\":3,\"n\":\"Owner\"},{\"t\":3,\"n\":\"Package\"},{\"t\":3,\"n\":\"Packdata ID\"},{\"t\":3,\"n\":\"Perk\"},{\"t\":3,\"n\":\"Quest\"},{\"t\":3,\"n\":\"Quest Stage\"},{\"t\":3,\"n\":\"Race\"},{\"t\":3,\"n\":\"Referenceable Object\"},{\"t\":3,\"n\":\"Location Ref Type\"},{\"t\":3,\"n\":\"Region\"},{\"t\":3,\"n\":\"Scene\"},{\"t\":3,\"n\":\"Sex\"},{\"t\":3,\"n\":\"Shout\"},{\"t\":11,\"n\":\"Variable Name (unused)\"},{\"t\":3,\"n\":\"VATS Value Function\"},{\"t\":3,\"n\":\"VATS Value Param (unused)\"},{\"t\":3,\"n\":\"Voice Type\"},{\"t\":3,\"n\":\"Ward State\"},{\"t\":3,\"n\":\"Weather\"},{\"t\":3,\"n\":\"Worldspace\"},{\"t\":3,\"n\":\"Damage Type\"},{\"t\":3,\"n\":\"Weapon\"},{\"t\":3,\"n\":\"Weapon List\"},{\"t\":3,\"n\":\"Target\"},{\"t\":3,\"n\":\"Target List\"},{\"t\":3,\"n\":\"Target Part\"},{\"t\":3,\"n\":\"VATS Action\"},{\"t\":3,\"n\":\"Critical Effect\"},{\"t\":3,\"n\":\"Critical Effect List\"},{\"t\":3,\"n\":\"Weapon Type\"},{\"t\":3,\"n\":\"Projectile Type\"},{\"t\":3,\"n\":\"Delivery Type\"},{\"t\":3,\"n\":\"Run On\"},{\"t\":3,\"n\":\"Reference\"},{\"t\":3,\"n\":\"Parameter #3\"}]},{\"t\":2,\"n\":\"CIS1 - Parameter #1\"},{\"t\":2,\"n\":\"CIS2 - Parameter #2\"}]}]},{\"t\":2,\"n\":\"DNAM - Behavior Graph\"},{\"t\":2,\"n\":\"ENAM - Animation Event\"},{\"t\":7,\"n\":\"ANAM - Related Idle Animations\",\"c\":[{\"t\":3,\"n\":\"Related Idle Animation\"}]},{\"t\":6,\"n\":\"DATA - \",\"c\":[{\"t\":6,\"n\":\"Looping seconds (both 255 forever)\",\"c\":[{\"t\":3,\"n\":\"Min\"},{\"t\":3,\"n\":\"Max\"}]},{\"t\":3,\"n\":\"Flags\"},{\"t\":3,\"n\":\"Animation Group Section\"},{\"t\":3,\"n\":\"Replay Delay\"}]},{\"t\":2,\"n\":\"GNAM - Animation File\"}]},{\"t\":1,\"p\":1,\"n\":\"IDLM - Idle Marker\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"X1\"},{\"t\":3,\"p\":1,\"n\":\"Y1\"},{\"t\":3,\"p\":1,\"n\":\"Z1\"},{\"t\":3,\"p\":1,\"n\":\"X2\"},{\"t\":3,\"p\":1,\"n\":\"Y2\"},{\"t\":3,\"p\":1,\"n\":\"Z2\"}]},{\"t\":3,\"n\":\"KSIZ - Keyword Count\"},{\"t\":7,\"p\":1,\"n\":\"KWDA - Keywords\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Keyword\"}]},{\"t\":3,\"p\":1,\"n\":\"IDLF - Flags\"},{\"t\":3,\"p\":1,\"n\":\"IDLC - Animation Count\"},{\"t\":5,\"p\":1,\"n\":\"IDLT - Idle Timer Setting\"},{\"t\":7,\"p\":1,\"n\":\"IDLA - Animations\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Animation\"}]},{\"t\":3,\"n\":\"QNAM - Unknown\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"MODT - Texture Files Hashes\"},{\"t\":3,\"p\":1,\"n\":\"MODS - Material Swap\"},{\"t\":5,\"p\":1,\"n\":\"MODC - Color Remapping Index\"},{\"t\":11,\"n\":\"MODF - Unknown\"}]}]},{\"t\":1,\"p\":1,\"n\":\"IMAD - Image Space Adapter\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"n\":\"DNAM - Data Count\",\"c\":[{\"t\":3,\"n\":\"Flags\"},{\"t\":5,\"n\":\"Duration\"},{\"t\":6,\"n\":\"HDR\",\"c\":[{\"t\":3,\"n\":\"Eye Adapt Speed Mult\"},{\"t\":3,\"n\":\"Eye Adapt Speed Add\"},{\"t\":3,\"n\":\"Bloom Blur Radius Mult\"},{\"t\":3,\"n\":\"Bloom Blur Radius Add\"},{\"t\":3,\"n\":\"Bloom Threshold Mult\"},{\"t\":3,\"n\":\"Bloom Threshold Add\"},{\"t\":3,\"n\":\"Bloom Scale Mult\"},{\"t\":3,\"n\":\"Bloom Scale Add\"},{\"t\":3,\"n\":\"Target Lum Min Mult\"},{\"t\":3,\"n\":\"Target Lum Min Add\"},{\"t\":3,\"n\":\"Target Lum Max Mult\"},{\"t\":3,\"n\":\"Target Lum Max Add\"},{\"t\":3,\"n\":\"Sunlight Scale Mult\"},{\"t\":3,\"n\":\"Sunlight Scale Add\"},{\"t\":3,\"n\":\"Sky Scale Mult\"},{\"t\":3,\"n\":\"Sky Scale Add\"}]},{\"t\":3,\"n\":\"Unknown08 Mult\"},{\"t\":3,\"n\":\"Unknown48 Add\"},{\"t\":3,\"n\":\"Unknown09 Mult\"},{\"t\":3,\"n\":\"Unknown49 Add\"},{\"t\":3,\"n\":\"Unknown0A Mult\"},{\"t\":3,\"n\":\"Unknown4A Add\"},{\"t\":3,\"n\":\"Unknown0B Mult\"},{\"t\":3,\"n\":\"Unknown4B Add\"},{\"t\":3,\"n\":\"Unknown0C Mult\"},{\"t\":3,\"n\":\"Unknown4C Add\"},{\"t\":3,\"n\":\"Unknown0D Mult\"},{\"t\":3,\"n\":\"Unknown4D Add\"},{\"t\":3,\"n\":\"Unknown0E Mult\"},{\"t\":3,\"n\":\"Unknown4E Add\"},{\"t\":3,\"n\":\"Unknown0F Mult\"},{\"t\":3,\"n\":\"Unknown4F Add\"},{\"t\":3,\"n\":\"Unknown10 Mult\"},{\"t\":3,\"n\":\"Unknown50 Add\"},{\"t\":6,\"n\":\"Cinematic\",\"c\":[{\"t\":3,\"n\":\"Saturation Mult\"},{\"t\":3,\"n\":\"Saturation Add\"},{\"t\":3,\"n\":\"Brightness Mult\"},{\"t\":3,\"n\":\"Brightness Add\"},{\"t\":3,\"n\":\"Contrast Mult\"},{\"t\":3,\"n\":\"Contrast Add\"}]},{\"t\":3,\"n\":\"Unknown14 Mult\"},{\"t\":3,\"n\":\"Unknown54 Add\"},{\"t\":3,\"n\":\"Tint Color\"},{\"t\":3,\"n\":\"Blur Radius\"},{\"t\":3,\"n\":\"Double Vision Strength\"},{\"t\":3,\"n\":\"Radial Blur Strength\"},{\"t\":3,\"n\":\"Radial Blur Ramp Up\"},{\"t\":3,\"n\":\"Radial Blur Start\"},{\"t\":3,\"n\":\"Radial Blur Flags\"},{\"t\":5,\"n\":\"Radial Blur Center X\"},{\"t\":5,\"n\":\"Radial Blur Center Y\"},{\"t\":3,\"n\":\"DoF Strength\"},{\"t\":3,\"n\":\"DoF Distance\"},{\"t\":3,\"n\":\"DoF Range\"},{\"t\":3,\"n\":\"DoF Flags\"},{\"t\":3,\"n\":\"Radial Blur Ramp Down\"},{\"t\":3,\"n\":\"Radial Blur Down Start\"},{\"t\":3,\"n\":\"Fade Color\"},{\"t\":3,\"n\":\"Motion Blur Strength\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":7,\"p\":1,\"n\":\"BNAM - Blur Radius\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Data\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Time\"},{\"t\":5,\"p\":1,\"n\":\"Value\"}]}]},{\"t\":7,\"p\":1,\"n\":\"VNAM - Double Vision Strength\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Data\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Time\"},{\"t\":5,\"p\":1,\"n\":\"Value\"}]}]},{\"t\":7,\"p\":1,\"n\":\"TNAM - Tint Color\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Data\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Time\"},{\"t\":5,\"p\":1,\"n\":\"Red\"},{\"t\":5,\"p\":1,\"n\":\"Green\"},{\"t\":5,\"p\":1,\"n\":\"Blue\"},{\"t\":5,\"p\":1,\"n\":\"Alpha\"}]}]},{\"t\":7,\"p\":1,\"n\":\"NAM3 - Fade Color\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Data\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Time\"},{\"t\":5,\"p\":1,\"n\":\"Red\"},{\"t\":5,\"p\":1,\"n\":\"Green\"},{\"t\":5,\"p\":1,\"n\":\"Blue\"},{\"t\":5,\"p\":1,\"n\":\"Alpha\"}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Radial Blur\",\"c\":[{\"t\":7,\"p\":1,\"n\":\"RNAM - Strength\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Data\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Time\"},{\"t\":5,\"p\":1,\"n\":\"Value\"}]}]},{\"t\":7,\"p\":1,\"n\":\"SNAM - RampUp\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Data\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Time\"},{\"t\":5,\"p\":1,\"n\":\"Value\"}]}]},{\"t\":7,\"p\":1,\"n\":\"UNAM - Start\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Data\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Time\"},{\"t\":5,\"p\":1,\"n\":\"Value\"}]}]},{\"t\":7,\"p\":1,\"n\":\"NAM1 - RampDown\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Data\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Time\"},{\"t\":5,\"p\":1,\"n\":\"Value\"}]}]},{\"t\":7,\"p\":1,\"n\":\"NAM2 - DownStart\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Data\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Time\"},{\"t\":5,\"p\":1,\"n\":\"Value\"}]}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Depth of Field\",\"c\":[{\"t\":7,\"p\":1,\"n\":\"WNAM - Strength\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Data\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Time\"},{\"t\":5,\"p\":1,\"n\":\"Value\"}]}]},{\"t\":7,\"p\":1,\"n\":\"XNAM - Distance\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Data\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Time\"},{\"t\":5,\"p\":1,\"n\":\"Value\"}]}]},{\"t\":7,\"p\":1,\"n\":\"YNAM - Range\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Data\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Time\"},{\"t\":5,\"p\":1,\"n\":\"Value\"}]}]},{\"t\":7,\"p\":1,\"n\":\"NAM5 - Vignette Radius\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Data\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Time\"},{\"t\":5,\"p\":1,\"n\":\"Value\"}]}]},{\"t\":7,\"p\":1,\"n\":\"NAM6 - Vignette Strength\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Data\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Time\"},{\"t\":5,\"p\":1,\"n\":\"Value\"}]}]}]},{\"t\":7,\"p\":1,\"n\":\"NAM4 - Motion Blur Strength\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Data\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Time\"},{\"t\":5,\"p\":1,\"n\":\"Value\"}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"HDR\",\"c\":[{\"t\":7,\"p\":1,\"n\":\"aIAD - Eye Adapt Speed Mult\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Data\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Time\"},{\"t\":5,\"p\":1,\"n\":\"Value\"}]}]},{\"t\":7,\"p\":1,\"n\":\"@IAD - Eye Adapt Speed Add\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Data\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Time\"},{\"t\":5,\"p\":1,\"n\":\"Value\"}]}]},{\"t\":7,\"p\":1,\"n\":\"bIAD - Bloom Blur Radius Mult\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Data\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Time\"},{\"t\":5,\"p\":1,\"n\":\"Value\"}]}]},{\"t\":7,\"p\":1,\"n\":\"AIAD - Bloom Blur Radius Add\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Data\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Time\"},{\"t\":5,\"p\":1,\"n\":\"Value\"}]}]},{\"t\":7,\"p\":1,\"n\":\"cIAD - Bloom Threshold Mult\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Data\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Time\"},{\"t\":5,\"p\":1,\"n\":\"Value\"}]}]},{\"t\":7,\"p\":1,\"n\":\"BIAD - Bloom Threshold Add\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Data\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Time\"},{\"t\":5,\"p\":1,\"n\":\"Value\"}]}]},{\"t\":7,\"p\":1,\"n\":\"dIAD - Bloom Scale Mult\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Data\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Time\"},{\"t\":5,\"p\":1,\"n\":\"Value\"}]}]},{\"t\":7,\"p\":1,\"n\":\"CIAD - Bloom Scale Add\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Data\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Time\"},{\"t\":5,\"p\":1,\"n\":\"Value\"}]}]},{\"t\":7,\"p\":1,\"n\":\"eIAD - Target Lum Min Mult\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Data\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Time\"},{\"t\":5,\"p\":1,\"n\":\"Value\"}]}]},{\"t\":7,\"p\":1,\"n\":\"DIAD - Target Lum Min Add\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Data\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Time\"},{\"t\":5,\"p\":1,\"n\":\"Value\"}]}]},{\"t\":7,\"p\":1,\"n\":\"fIAD - Target Lum Max Mult\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Data\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Time\"},{\"t\":5,\"p\":1,\"n\":\"Value\"}]}]},{\"t\":7,\"p\":1,\"n\":\"EIAD - Target Lum Max Add\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Data\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Time\"},{\"t\":5,\"p\":1,\"n\":\"Value\"}]}]},{\"t\":7,\"p\":1,\"n\":\"gIAD - Sunlight Scale Mult\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Data\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Time\"},{\"t\":5,\"p\":1,\"n\":\"Value\"}]}]},{\"t\":7,\"p\":1,\"n\":\"FIAD - Sunlight Scale Add\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Data\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Time\"},{\"t\":5,\"p\":1,\"n\":\"Value\"}]}]},{\"t\":7,\"p\":1,\"n\":\"hIAD - Sky Scale Mult\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Data\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Time\"},{\"t\":5,\"p\":1,\"n\":\"Value\"}]}]},{\"t\":7,\"p\":1,\"n\":\"GIAD - Sky Scale Add\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Data\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Time\"},{\"t\":5,\"p\":1,\"n\":\"Value\"}]}]}]},{\"t\":11,\"n\":\"iIAD - Unknown\"},{\"t\":11,\"n\":\"HIAD - Unknown\"},{\"t\":11,\"n\":\"jIAD - Unknown\"},{\"t\":11,\"n\":\"IIAD - Unknown\"},{\"t\":11,\"n\":\"kIAD - Unknown\"},{\"t\":11,\"n\":\"JIAD - Unknown\"},{\"t\":11,\"n\":\"lIAD - Unknown\"},{\"t\":11,\"n\":\"KIAD - Unknown\"},{\"t\":11,\"n\":\"mIAD - Unknown\"},{\"t\":11,\"n\":\"LIAD - Unknown\"},{\"t\":11,\"n\":\"nIAD - Unknown\"},{\"t\":11,\"n\":\"MIAD - Unknown\"},{\"t\":11,\"n\":\"oIAD - Unknown\"},{\"t\":11,\"n\":\"NIAD - Unknown\"},{\"t\":11,\"n\":\"pIAD - Unknown\"},{\"t\":11,\"n\":\"OIAD - Unknown\"},{\"t\":11,\"n\":\"qIAD - Unknown\"},{\"t\":11,\"n\":\"PIAD - Unknown\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Cinematic\",\"c\":[{\"t\":7,\"p\":1,\"n\":\"rIAD - Saturation Mult\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Data\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Time\"},{\"t\":5,\"p\":1,\"n\":\"Value\"}]}]},{\"t\":7,\"p\":1,\"n\":\"QIAD - Saturation Add\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Data\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Time\"},{\"t\":5,\"p\":1,\"n\":\"Value\"}]}]},{\"t\":7,\"p\":1,\"n\":\"sIAD - Brightness Mult\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Data\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Time\"},{\"t\":5,\"p\":1,\"n\":\"Value\"}]}]},{\"t\":7,\"p\":1,\"n\":\"RIAD - Brightness Add\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Data\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Time\"},{\"t\":5,\"p\":1,\"n\":\"Value\"}]}]},{\"t\":7,\"p\":1,\"n\":\"tIAD - Contrast Mult\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Data\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Time\"},{\"t\":5,\"p\":1,\"n\":\"Value\"}]}]},{\"t\":7,\"p\":1,\"n\":\"SIAD - Contrast Add\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Data\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Time\"},{\"t\":5,\"p\":1,\"n\":\"Value\"}]}]}]},{\"t\":11,\"n\":\"uIAD - Unknown\"},{\"t\":11,\"n\":\"TIAD - Unknown\"}]},{\"t\":1,\"p\":1,\"n\":\"IMGS - Image Space\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":11,\"n\":\"ENAM - Unused\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"HNAM - HDR\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Eye Adapt Speed\"},{\"t\":5,\"p\":1,\"n\":\"Tonemap E\"},{\"t\":5,\"p\":1,\"n\":\"Bloom Threshold\"},{\"t\":5,\"p\":1,\"n\":\"Bloom Scale\"},{\"t\":5,\"p\":1,\"n\":\"Auto Exposure Max\"},{\"t\":5,\"p\":1,\"n\":\"Auto Exposure Min\"},{\"t\":5,\"p\":1,\"n\":\"Sunlight Scale\"},{\"t\":5,\"p\":1,\"n\":\"Sky Scale\"},{\"t\":5,\"p\":1,\"n\":\"Middle Gray\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"CNAM - Cinematic\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Saturation\"},{\"t\":5,\"p\":1,\"n\":\"Brightness\"},{\"t\":5,\"p\":1,\"n\":\"Contrast\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"TNAM - Tint\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Amount\"},{\"t\":6,\"p\":1,\"n\":\"Color\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Red\"},{\"t\":5,\"p\":1,\"n\":\"Green\"},{\"t\":5,\"p\":1,\"n\":\"Blue\"}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DNAM - Depth of Field\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Strength\"},{\"t\":5,\"p\":1,\"n\":\"Distance\"},{\"t\":5,\"p\":1,\"n\":\"Range\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Sky \\/ Blur Radius\"},{\"t\":5,\"p\":1,\"n\":\"Vignette Radius\"},{\"t\":5,\"p\":1,\"n\":\"Vignette Strength\"}]},{\"t\":2,\"p\":1,\"n\":\"TX00 - LUT\"}]},{\"t\":1,\"p\":1,\"n\":\"INFO - Dialog response\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"VMAD - Virtual Machine Adapter\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Version\"},{\"t\":3,\"p\":1,\"n\":\"Object Format\"},{\"t\":7,\"p\":1,\"n\":\"Scripts\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Script\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"scriptName\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":7,\"p\":1,\"n\":\"Properties\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Property\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"propertyName\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]},{\"t\":2,\"p\":1,\"n\":\"String\"},{\"t\":3,\"p\":1,\"n\":\"Int32\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":3,\"p\":1,\"n\":\"Bool\"},{\"t\":7,\"p\":1,\"n\":\"Struct\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Member\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"memberName\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]},{\"t\":2,\"p\":1,\"n\":\"String\"},{\"t\":3,\"p\":1,\"n\":\"Int32\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":3,\"p\":1,\"n\":\"Bool\"},{\"t\":7,\"p\":1,\"n\":\"Array of Object\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]}]},{\"t\":7,\"p\":1,\"n\":\"Array of String\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Int32\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Float\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Bool\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]}]}]},{\"t\":7,\"p\":1,\"n\":\"Array of Object\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]}]},{\"t\":7,\"p\":1,\"n\":\"Array of String\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Int32\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Float\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Bool\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Struct\",\"c\":[{\"t\":7,\"p\":1,\"n\":\"Struct\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Member\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"memberName\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]},{\"t\":2,\"p\":1,\"n\":\"String\"},{\"t\":3,\"p\":1,\"n\":\"Int32\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":3,\"p\":1,\"n\":\"Bool\"},{\"t\":7,\"p\":1,\"n\":\"Array of Object\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]}]},{\"t\":7,\"p\":1,\"n\":\"Array of String\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Int32\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Float\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Bool\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]}]}]}]}]}]}]}]},{\"t\":6,\"p\":1,\"n\":\"Script Fragments\",\"c\":[{\"t\":3,\"n\":\"Unknown\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":6,\"p\":1,\"n\":\"Script\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"scriptName\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":7,\"p\":1,\"n\":\"Properties\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Property\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"propertyName\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]},{\"t\":2,\"p\":1,\"n\":\"String\"},{\"t\":3,\"p\":1,\"n\":\"Int32\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":3,\"p\":1,\"n\":\"Bool\"},{\"t\":7,\"p\":1,\"n\":\"Struct\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Member\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"memberName\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]},{\"t\":2,\"p\":1,\"n\":\"String\"},{\"t\":3,\"p\":1,\"n\":\"Int32\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":3,\"p\":1,\"n\":\"Bool\"},{\"t\":7,\"p\":1,\"n\":\"Array of Object\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]}]},{\"t\":7,\"p\":1,\"n\":\"Array of String\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Int32\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Float\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Bool\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]}]}]},{\"t\":7,\"p\":1,\"n\":\"Array of Object\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]}]},{\"t\":7,\"p\":1,\"n\":\"Array of String\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Int32\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Float\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Bool\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Struct\",\"c\":[{\"t\":7,\"p\":1,\"n\":\"Struct\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Member\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"memberName\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]},{\"t\":2,\"p\":1,\"n\":\"String\"},{\"t\":3,\"p\":1,\"n\":\"Int32\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":3,\"p\":1,\"n\":\"Bool\"},{\"t\":7,\"p\":1,\"n\":\"Array of Object\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]}]},{\"t\":7,\"p\":1,\"n\":\"Array of String\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Int32\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Float\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Bool\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]}]}]}]}]}]}]},{\"t\":7,\"p\":1,\"n\":\"Fragments\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Fragment\",\"c\":[{\"t\":3,\"n\":\"Unknown\"},{\"t\":2,\"p\":1,\"n\":\"scriptName\"},{\"t\":2,\"p\":1,\"n\":\"fragmentName\"}]}]}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"ENAM - Response flags\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":3,\"p\":1,\"n\":\"Reset Hours\"}]},{\"t\":3,\"p\":1,\"n\":\"TPIC - Topic\"},{\"t\":3,\"p\":1,\"n\":\"PNAM - Previous INFO\"},{\"t\":3,\"p\":1,\"n\":\"DNAM - Shared INFO\"},{\"t\":3,\"n\":\"GNAM - Unknown\"},{\"t\":2,\"p\":1,\"n\":\"IOVR - Override Filename\"},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Responses\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Response\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"TRDA - Response Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Emotion\"},{\"t\":3,\"p\":1,\"n\":\"Response number\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":3,\"p\":1,\"n\":\"Interrupt Percentage\"},{\"t\":3,\"p\":1,\"n\":\"Camera Target Alias\"},{\"t\":3,\"p\":1,\"n\":\"Camera Location Alias\"}]},{\"t\":2,\"p\":1,\"n\":\"NAM1 - Response Text\"},{\"t\":2,\"p\":1,\"n\":\"NAM2 - Script Notes\"},{\"t\":2,\"p\":1,\"n\":\"NAM3 - Edits\"},{\"t\":2,\"p\":1,\"n\":\"NAM4 - Alternate LIP Text\"},{\"t\":3,\"p\":1,\"n\":\"SNAM - Idle Animations: Speaker\"},{\"t\":3,\"p\":1,\"n\":\"LNAM - Idle Animations: Listener\"},{\"t\":3,\"p\":1,\"n\":\"TNAM - Interrupt Percentage\"},{\"t\":11,\"p\":1,\"n\":\"NAM9 - Text Hash\"},{\"t\":3,\"p\":1,\"n\":\"SRAF - Camera Path\"},{\"p\":1,\"n\":\"WZMD - Stop on Scene End\"}]}]},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Conditions\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Condition\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"CTDA - \",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":5,\"p\":1,\"n\":\"Comparison Value - Float\"},{\"t\":3,\"p\":1,\"n\":\"Comparison Value - Global\"},{\"t\":3,\"p\":1,\"n\":\"Function\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":11,\"p\":1,\"n\":\"None\"},{\"t\":3,\"p\":1,\"n\":\"Integer\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":3,\"p\":1,\"n\":\"Actor\"},{\"t\":3,\"p\":1,\"n\":\"Actor Base\"},{\"t\":3,\"p\":1,\"n\":\"Actor Value\"},{\"t\":3,\"p\":1,\"n\":\"Player Action\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"Alignment\"},{\"t\":3,\"p\":1,\"n\":\"Association Type\"},{\"t\":3,\"p\":1,\"n\":\"Axis\"},{\"t\":3,\"p\":1,\"n\":\"Casting Type\"},{\"t\":3,\"p\":1,\"n\":\"Cell\"},{\"t\":3,\"p\":1,\"n\":\"Class\"},{\"t\":3,\"p\":1,\"n\":\"Crime Type\"},{\"t\":3,\"p\":1,\"n\":\"Critical Stage\"},{\"t\":3,\"p\":1,\"n\":\"Encounter Zone\"},{\"t\":3,\"p\":1,\"n\":\"Equip Type\"},{\"t\":3,\"p\":1,\"n\":\"Event\"},{\"t\":3,\"p\":1,\"n\":\"Event Data\"},{\"t\":3,\"p\":1,\"n\":\"Faction\"},{\"t\":3,\"p\":1,\"n\":\"Form List\"},{\"t\":3,\"p\":1,\"n\":\"Form Type\"},{\"t\":3,\"p\":1,\"n\":\"Furniture\"},{\"t\":3,\"p\":1,\"n\":\"Furniture Anim\"},{\"t\":3,\"p\":1,\"n\":\"Furniture Entry\"},{\"t\":3,\"p\":1,\"n\":\"Global\"},{\"t\":3,\"p\":1,\"n\":\"Idle\"},{\"t\":3,\"p\":1,\"n\":\"Inventory Object\"},{\"t\":3,\"p\":1,\"n\":\"Keyword\"},{\"t\":3,\"p\":1,\"n\":\"Location\"},{\"t\":3,\"p\":1,\"n\":\"Base Effect\"},{\"t\":3,\"p\":1,\"n\":\"Effect Item\"},{\"t\":3,\"p\":1,\"n\":\"Misc Stat\"},{\"t\":3,\"p\":1,\"n\":\"Object Reference\"},{\"t\":3,\"p\":1,\"n\":\"Owner\"},{\"t\":3,\"p\":1,\"n\":\"Package\"},{\"t\":3,\"p\":1,\"n\":\"Packdata ID\"},{\"t\":3,\"p\":1,\"n\":\"Perk\"},{\"t\":3,\"p\":1,\"n\":\"Quest\"},{\"t\":3,\"p\":1,\"n\":\"Quest Stage\"},{\"t\":3,\"p\":1,\"n\":\"Race\"},{\"t\":3,\"p\":1,\"n\":\"Referenceable Object\"},{\"t\":3,\"p\":1,\"n\":\"Location Ref Type\"},{\"t\":3,\"p\":1,\"n\":\"Region\"},{\"t\":3,\"p\":1,\"n\":\"Scene\"},{\"t\":3,\"p\":1,\"n\":\"Sex\"},{\"t\":3,\"p\":1,\"n\":\"Shout\"},{\"t\":11,\"p\":1,\"n\":\"Variable Name (unused)\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Function\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Param (unused)\"},{\"t\":3,\"p\":1,\"n\":\"Voice Type\"},{\"t\":3,\"p\":1,\"n\":\"Ward State\"},{\"t\":3,\"p\":1,\"n\":\"Weather\"},{\"t\":3,\"p\":1,\"n\":\"Worldspace\"},{\"t\":3,\"p\":1,\"n\":\"Damage Type\"},{\"t\":3,\"p\":1,\"n\":\"Weapon\"},{\"t\":3,\"p\":1,\"n\":\"Weapon List\"},{\"t\":3,\"p\":1,\"n\":\"Target\"},{\"t\":3,\"p\":1,\"n\":\"Target List\"},{\"t\":3,\"p\":1,\"n\":\"Target Part\"},{\"t\":3,\"p\":1,\"n\":\"VATS Action\"},{\"t\":3,\"p\":1,\"n\":\"Critical Effect\"},{\"t\":3,\"p\":1,\"n\":\"Critical Effect List\"},{\"t\":3,\"p\":1,\"n\":\"Weapon Type\"},{\"t\":3,\"p\":1,\"n\":\"Projectile Type\"},{\"t\":3,\"p\":1,\"n\":\"Delivery Type\"},{\"t\":3,\"p\":1,\"n\":\"Run On\"},{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":3,\"p\":1,\"n\":\"Parameter #3\"}]},{\"t\":2,\"p\":1,\"n\":\"CIS1 - Parameter #1\"},{\"t\":2,\"p\":1,\"n\":\"CIS2 - Parameter #2\"}]}]},{\"t\":2,\"p\":1,\"n\":\"RNAM - Prompt\"},{\"t\":3,\"p\":1,\"n\":\"ANAM - Speaker\"},{\"t\":3,\"p\":1,\"n\":\"TSCE - Start Scene\"},{\"t\":3,\"p\":1,\"n\":\"ALFA - Forced Alias\"},{\"t\":11,\"n\":\"INTV - Unknown\"},{\"t\":3,\"p\":1,\"n\":\"ONAM - Audio Output Override\"},{\"t\":3,\"p\":1,\"n\":\"GREE - Greet Distance\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"TIQS - Set Parent Quest Stage\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"On Begin\"},{\"t\":3,\"p\":1,\"n\":\"On End\"}]},{\"t\":2,\"p\":1,\"n\":\"NAM0 - Start Scene Phase\"},{\"t\":3,\"p\":1,\"n\":\"INCC - Challenge\"},{\"t\":3,\"p\":1,\"n\":\"MODQ - Reset Global\"},{\"t\":3,\"p\":1,\"n\":\"INAM - Subtitle Priority\"}]},{\"t\":1,\"p\":1,\"n\":\"INGR - Ingredient\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"VMAD - Virtual Machine Adapter\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Version\"},{\"t\":3,\"p\":1,\"n\":\"Object Format\"},{\"t\":7,\"p\":1,\"n\":\"Scripts\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Script\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"scriptName\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":7,\"p\":1,\"n\":\"Properties\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Property\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"propertyName\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]},{\"t\":2,\"p\":1,\"n\":\"String\"},{\"t\":3,\"p\":1,\"n\":\"Int32\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":3,\"p\":1,\"n\":\"Bool\"},{\"t\":7,\"p\":1,\"n\":\"Struct\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Member\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"memberName\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]},{\"t\":2,\"p\":1,\"n\":\"String\"},{\"t\":3,\"p\":1,\"n\":\"Int32\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":3,\"p\":1,\"n\":\"Bool\"},{\"t\":7,\"p\":1,\"n\":\"Array of Object\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]}]},{\"t\":7,\"p\":1,\"n\":\"Array of String\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Int32\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Float\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Bool\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]}]}]},{\"t\":7,\"p\":1,\"n\":\"Array of Object\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]}]},{\"t\":7,\"p\":1,\"n\":\"Array of String\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Int32\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Float\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Bool\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Struct\",\"c\":[{\"t\":7,\"p\":1,\"n\":\"Struct\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Member\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"memberName\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]},{\"t\":2,\"p\":1,\"n\":\"String\"},{\"t\":3,\"p\":1,\"n\":\"Int32\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":3,\"p\":1,\"n\":\"Bool\"},{\"t\":7,\"p\":1,\"n\":\"Array of Object\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]}]},{\"t\":7,\"p\":1,\"n\":\"Array of String\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Int32\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Float\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Bool\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]}]}]}]}]}]}]}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"X1\"},{\"t\":3,\"p\":1,\"n\":\"Y1\"},{\"t\":3,\"p\":1,\"n\":\"Z1\"},{\"t\":3,\"p\":1,\"n\":\"X2\"},{\"t\":3,\"p\":1,\"n\":\"Y2\"},{\"t\":3,\"p\":1,\"n\":\"Z2\"}]},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":3,\"n\":\"KSIZ - Keyword Count\"},{\"t\":7,\"p\":1,\"n\":\"KWDA - Keywords\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Keyword\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"MODT - Texture Files Hashes\"},{\"t\":3,\"p\":1,\"n\":\"MODS - Material Swap\"},{\"t\":5,\"p\":1,\"n\":\"MODC - Color Remapping Index\"},{\"t\":11,\"n\":\"MODF - Unknown\"}]},{\"t\":2,\"p\":1,\"n\":\"ICON - Inventory Image\"},{\"t\":2,\"p\":1,\"n\":\"MICO - Message Icon\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Destructible\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"DEST - Header\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Health\"},{\"t\":3,\"p\":1,\"n\":\"DEST Count\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":7,\"p\":1,\"n\":\"DAMC - Resistances\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Resistance\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Damage Type\"},{\"t\":3,\"p\":1,\"n\":\"Value\"}]}]},{\"t\":8,\"p\":1,\"n\":\"Stages\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Stage\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"DSTD - Destruction Stage Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Health %\"},{\"t\":3,\"p\":1,\"n\":\"Index\"},{\"t\":3,\"p\":1,\"n\":\"Model Damage Stage\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":3,\"p\":1,\"n\":\"Self Damage per Second\"},{\"t\":3,\"p\":1,\"n\":\"Explosion\"},{\"t\":3,\"p\":1,\"n\":\"Debris\"},{\"t\":3,\"p\":1,\"n\":\"Debris Count\"}]},{\"t\":2,\"p\":1,\"n\":\"DSTA - Sequence Name\"},{\"t\":6,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"DMDL - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"DMDT - Texture Files Hashes\"},{\"t\":5,\"p\":1,\"n\":\"DMDC - Color Remapping Index\"},{\"t\":3,\"p\":1,\"n\":\"DMDS - Material Swap\"}]},{\"p\":1,\"n\":\"DSTF - End Marker\"}]}]}]},{\"t\":3,\"p\":1,\"n\":\"ETYP - Equipment Type\"},{\"t\":3,\"p\":1,\"n\":\"YNAM - Sound - Pick Up\"},{\"t\":3,\"p\":1,\"n\":\"ZNAM - Sound - Put Down\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DATA - \",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Value\"},{\"t\":5,\"p\":1,\"n\":\"Weight\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"ENIT - Effect Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Ingredient Value\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"}]},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Effects\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Effect\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"EFID - Base Effect\"},{\"t\":6,\"p\":1,\"n\":\"EFIT - \",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Magnitude\"},{\"t\":3,\"p\":1,\"n\":\"Area\"},{\"t\":3,\"p\":1,\"n\":\"Duration\"}]},{\"t\":8,\"p\":1,\"n\":\"Conditions\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Condition\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"CTDA - \",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":5,\"p\":1,\"n\":\"Comparison Value - Float\"},{\"t\":3,\"p\":1,\"n\":\"Comparison Value - Global\"},{\"t\":3,\"p\":1,\"n\":\"Function\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":11,\"p\":1,\"n\":\"None\"},{\"t\":3,\"p\":1,\"n\":\"Integer\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":3,\"p\":1,\"n\":\"Actor\"},{\"t\":3,\"p\":1,\"n\":\"Actor Base\"},{\"t\":3,\"p\":1,\"n\":\"Actor Value\"},{\"t\":3,\"p\":1,\"n\":\"Player Action\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"Alignment\"},{\"t\":3,\"p\":1,\"n\":\"Association Type\"},{\"t\":3,\"p\":1,\"n\":\"Axis\"},{\"t\":3,\"p\":1,\"n\":\"Casting Type\"},{\"t\":3,\"p\":1,\"n\":\"Cell\"},{\"t\":3,\"p\":1,\"n\":\"Class\"},{\"t\":3,\"p\":1,\"n\":\"Crime Type\"},{\"t\":3,\"p\":1,\"n\":\"Critical Stage\"},{\"t\":3,\"p\":1,\"n\":\"Encounter Zone\"},{\"t\":3,\"p\":1,\"n\":\"Equip Type\"},{\"t\":3,\"p\":1,\"n\":\"Event\"},{\"t\":3,\"p\":1,\"n\":\"Event Data\"},{\"t\":3,\"p\":1,\"n\":\"Faction\"},{\"t\":3,\"p\":1,\"n\":\"Form List\"},{\"t\":3,\"p\":1,\"n\":\"Form Type\"},{\"t\":3,\"p\":1,\"n\":\"Furniture\"},{\"t\":3,\"p\":1,\"n\":\"Furniture Anim\"},{\"t\":3,\"p\":1,\"n\":\"Furniture Entry\"},{\"t\":3,\"p\":1,\"n\":\"Global\"},{\"t\":3,\"p\":1,\"n\":\"Idle\"},{\"t\":3,\"p\":1,\"n\":\"Inventory Object\"},{\"t\":3,\"p\":1,\"n\":\"Keyword\"},{\"t\":3,\"p\":1,\"n\":\"Location\"},{\"t\":3,\"p\":1,\"n\":\"Base Effect\"},{\"t\":3,\"p\":1,\"n\":\"Effect Item\"},{\"t\":3,\"p\":1,\"n\":\"Misc Stat\"},{\"t\":3,\"p\":1,\"n\":\"Object Reference\"},{\"t\":3,\"p\":1,\"n\":\"Owner\"},{\"t\":3,\"p\":1,\"n\":\"Package\"},{\"t\":3,\"p\":1,\"n\":\"Packdata ID\"},{\"t\":3,\"p\":1,\"n\":\"Perk\"},{\"t\":3,\"p\":1,\"n\":\"Quest\"},{\"t\":3,\"p\":1,\"n\":\"Quest Stage\"},{\"t\":3,\"p\":1,\"n\":\"Race\"},{\"t\":3,\"p\":1,\"n\":\"Referenceable Object\"},{\"t\":3,\"p\":1,\"n\":\"Location Ref Type\"},{\"t\":3,\"p\":1,\"n\":\"Region\"},{\"t\":3,\"p\":1,\"n\":\"Scene\"},{\"t\":3,\"p\":1,\"n\":\"Sex\"},{\"t\":3,\"p\":1,\"n\":\"Shout\"},{\"t\":11,\"p\":1,\"n\":\"Variable Name (unused)\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Function\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Param (unused)\"},{\"t\":3,\"p\":1,\"n\":\"Voice Type\"},{\"t\":3,\"p\":1,\"n\":\"Ward State\"},{\"t\":3,\"p\":1,\"n\":\"Weather\"},{\"t\":3,\"p\":1,\"n\":\"Worldspace\"},{\"t\":3,\"p\":1,\"n\":\"Damage Type\"},{\"t\":3,\"p\":1,\"n\":\"Weapon\"},{\"t\":3,\"p\":1,\"n\":\"Weapon List\"},{\"t\":3,\"p\":1,\"n\":\"Target\"},{\"t\":3,\"p\":1,\"n\":\"Target List\"},{\"t\":3,\"p\":1,\"n\":\"Target Part\"},{\"t\":3,\"p\":1,\"n\":\"VATS Action\"},{\"t\":3,\"p\":1,\"n\":\"Critical Effect\"},{\"t\":3,\"p\":1,\"n\":\"Critical Effect List\"},{\"t\":3,\"p\":1,\"n\":\"Weapon Type\"},{\"t\":3,\"p\":1,\"n\":\"Projectile Type\"},{\"t\":3,\"p\":1,\"n\":\"Delivery Type\"},{\"t\":3,\"p\":1,\"n\":\"Run On\"},{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":3,\"p\":1,\"n\":\"Parameter #3\"}]},{\"t\":2,\"p\":1,\"n\":\"CIS1 - Parameter #1\"},{\"t\":2,\"p\":1,\"n\":\"CIS2 - Parameter #2\"}]}]}]}]}]},{\"t\":1,\"p\":1,\"n\":\"INNR - Instance Naming Rules\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":3,\"p\":1,\"n\":\"UNAM - Target\"},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Naming Rules\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Ruleset\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"VNAM - Count\"},{\"t\":8,\"p\":1,\"n\":\"Names\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Name\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"WNAM - Text\"},{\"t\":3,\"p\":1,\"n\":\"KSIZ - Keyword Count\"},{\"t\":7,\"p\":1,\"n\":\"KWDA - Keywords\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Keyword\"}]},{\"t\":6,\"p\":1,\"n\":\"XNAM - Property\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Value\"},{\"t\":3,\"p\":1,\"n\":\"Target\"},{\"t\":3,\"p\":1,\"n\":\"Op\"}]},{\"t\":3,\"p\":1,\"n\":\"YNAM - Index\"}]}]}]}]}]},{\"t\":1,\"p\":1,\"n\":\"IPCT - Impact\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"MODT - Texture Files Hashes\"},{\"t\":3,\"p\":1,\"n\":\"MODS - Material Swap\"},{\"t\":5,\"p\":1,\"n\":\"MODC - Color Remapping Index\"},{\"t\":11,\"n\":\"MODF - Unknown\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DATA - \",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Effect - Duration\"},{\"t\":3,\"p\":1,\"n\":\"Effect - Orientation\"},{\"t\":5,\"p\":1,\"n\":\"Angle Threshold\"},{\"t\":5,\"p\":1,\"n\":\"Placement Radius\"},{\"t\":3,\"p\":1,\"n\":\"Sound Level\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":3,\"p\":1,\"n\":\"Impact Result\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DODT - Decal Data\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Min Width\"},{\"t\":5,\"p\":1,\"n\":\"Max Width\"},{\"t\":5,\"p\":1,\"n\":\"Min Height\"},{\"t\":5,\"p\":1,\"n\":\"Max Height\"},{\"t\":5,\"p\":1,\"n\":\"Depth\"},{\"t\":5,\"p\":1,\"n\":\"Shininess\"},{\"t\":6,\"p\":1,\"n\":\"Parallax\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Scale\"},{\"t\":3,\"p\":1,\"n\":\"Passes\"}]},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":3,\"p\":1,\"n\":\"Alpha Threshold?\"},{\"t\":6,\"p\":1,\"n\":\"Color\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]}]},{\"t\":3,\"p\":1,\"n\":\"DNAM - Texture Set\"},{\"t\":3,\"p\":1,\"n\":\"ENAM - Secondary Texture Set\"},{\"t\":3,\"p\":1,\"n\":\"SNAM - Sound 1\"},{\"t\":3,\"p\":1,\"n\":\"NAM1 - Sound 2\"},{\"t\":3,\"p\":1,\"n\":\"NAM3 - Footstep Explosion\"},{\"t\":3,\"p\":1,\"n\":\"NAM2 - Hazard\"},{\"t\":5,\"p\":1,\"n\":\"FNAM - Footstep Particle Max Dist\"}]},{\"t\":1,\"p\":1,\"n\":\"IPDS - Impact Data Set\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Data\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"PNAM - \",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Material\"},{\"t\":3,\"p\":1,\"n\":\"Impact\"}]}]}]},{\"t\":1,\"p\":1,\"n\":\"KEYM - Key\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"VMAD - Virtual Machine Adapter\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Version\"},{\"t\":3,\"p\":1,\"n\":\"Object Format\"},{\"t\":7,\"p\":1,\"n\":\"Scripts\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Script\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"scriptName\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":7,\"p\":1,\"n\":\"Properties\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Property\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"propertyName\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]},{\"t\":2,\"p\":1,\"n\":\"String\"},{\"t\":3,\"p\":1,\"n\":\"Int32\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":3,\"p\":1,\"n\":\"Bool\"},{\"t\":7,\"p\":1,\"n\":\"Struct\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Member\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"memberName\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]},{\"t\":2,\"p\":1,\"n\":\"String\"},{\"t\":3,\"p\":1,\"n\":\"Int32\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":3,\"p\":1,\"n\":\"Bool\"},{\"t\":7,\"p\":1,\"n\":\"Array of Object\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]}]},{\"t\":7,\"p\":1,\"n\":\"Array of String\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Int32\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Float\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Bool\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]}]}]},{\"t\":7,\"p\":1,\"n\":\"Array of Object\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]}]},{\"t\":7,\"p\":1,\"n\":\"Array of String\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Int32\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Float\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Bool\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Struct\",\"c\":[{\"t\":7,\"p\":1,\"n\":\"Struct\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Member\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"memberName\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]},{\"t\":2,\"p\":1,\"n\":\"String\"},{\"t\":3,\"p\":1,\"n\":\"Int32\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":3,\"p\":1,\"n\":\"Bool\"},{\"t\":7,\"p\":1,\"n\":\"Array of Object\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]}]},{\"t\":7,\"p\":1,\"n\":\"Array of String\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Int32\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Float\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Bool\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]}]}]}]}]}]}]}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"X1\"},{\"t\":3,\"p\":1,\"n\":\"Y1\"},{\"t\":3,\"p\":1,\"n\":\"Z1\"},{\"t\":3,\"p\":1,\"n\":\"X2\"},{\"t\":3,\"p\":1,\"n\":\"Y2\"},{\"t\":3,\"p\":1,\"n\":\"Z2\"}]},{\"t\":3,\"p\":1,\"n\":\"PTRN - Preview Transform\"},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"MODT - Texture Files Hashes\"},{\"t\":3,\"p\":1,\"n\":\"MODS - Material Swap\"},{\"t\":5,\"p\":1,\"n\":\"MODC - Color Remapping Index\"},{\"t\":11,\"n\":\"MODF - Unknown\"}]},{\"t\":2,\"p\":1,\"n\":\"ICON - Inventory Image\"},{\"t\":2,\"p\":1,\"n\":\"MICO - Message Icon\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Destructible\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"DEST - Header\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Health\"},{\"t\":3,\"p\":1,\"n\":\"DEST Count\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":7,\"p\":1,\"n\":\"DAMC - Resistances\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Resistance\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Damage Type\"},{\"t\":3,\"p\":1,\"n\":\"Value\"}]}]},{\"t\":8,\"p\":1,\"n\":\"Stages\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Stage\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"DSTD - Destruction Stage Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Health %\"},{\"t\":3,\"p\":1,\"n\":\"Index\"},{\"t\":3,\"p\":1,\"n\":\"Model Damage Stage\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":3,\"p\":1,\"n\":\"Self Damage per Second\"},{\"t\":3,\"p\":1,\"n\":\"Explosion\"},{\"t\":3,\"p\":1,\"n\":\"Debris\"},{\"t\":3,\"p\":1,\"n\":\"Debris Count\"}]},{\"t\":2,\"p\":1,\"n\":\"DSTA - Sequence Name\"},{\"t\":6,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"DMDL - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"DMDT - Texture Files Hashes\"},{\"t\":5,\"p\":1,\"n\":\"DMDC - Color Remapping Index\"},{\"t\":3,\"p\":1,\"n\":\"DMDS - Material Swap\"}]},{\"p\":1,\"n\":\"DSTF - End Marker\"}]}]}]},{\"t\":3,\"p\":1,\"n\":\"YNAM - Sound - Pick Up\"},{\"t\":3,\"p\":1,\"n\":\"ZNAM - Sound - Put Down\"},{\"t\":3,\"n\":\"KSIZ - Keyword Count\"},{\"t\":7,\"p\":1,\"n\":\"KWDA - Keywords\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Keyword\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DATA - \",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Value\"},{\"t\":5,\"p\":1,\"n\":\"Weight\"}]}]},{\"t\":1,\"p\":1,\"n\":\"KSSM - Sound Keyword Mapping\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":3,\"p\":1,\"n\":\"DNAM - Primary Descriptor\"},{\"t\":3,\"p\":1,\"n\":\"ENAM - Exterior Tail\"},{\"t\":3,\"p\":1,\"n\":\"VNAM - VATS Descriptor\"},{\"t\":5,\"p\":1,\"n\":\"TNAM - VATS Threshold\"},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Keywords\",\"d\":1,\"c\":[{\"t\":3,\"p\":1,\"n\":\"KNAM - Keyword\"}]},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Sounds\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"RNAM - Sound\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Reverb Class\"},{\"t\":3,\"p\":1,\"n\":\"Descriptor\"}]}]}]},{\"t\":1,\"p\":1,\"n\":\"KYWD - Keyword\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"CNAM - Color\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":2,\"p\":1,\"n\":\"DNAM - Notes\"},{\"t\":3,\"p\":1,\"n\":\"TNAM - Type\"},{\"t\":3,\"p\":1,\"n\":\"DATA - Attraction Rule\"},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":2,\"p\":1,\"n\":\"NNAM - Display Name\"}]},{\"t\":1,\"p\":1,\"n\":\"LAND - Landscape\",\"d\":1,\"c\":[{\"t\":11,\"n\":\"DATA - Unknown\"},{\"t\":11,\"n\":\"VNML - Vertex Normals\"},{\"t\":11,\"n\":\"VHGT - Vertext Height Map\"},{\"t\":11,\"n\":\"VCLR - Vertex Colours\"},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Layers\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Base Layer\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"BTXT - Base Layer Header\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Texture\"},{\"t\":3,\"p\":1,\"n\":\"Quadrant\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":3,\"p\":1,\"n\":\"Layer\"}]}]},{\"t\":6,\"p\":1,\"n\":\"Alpha Layer\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"ATXT - Alpha Layer Header\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Texture\"},{\"t\":3,\"p\":1,\"n\":\"Quadrant\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":3,\"p\":1,\"n\":\"Layer\"}]},{\"t\":11,\"p\":1,\"n\":\"VTXT - Alpha Layer Data\"}]}]},{\"t\":7,\"p\":1,\"n\":\"VTEX - Textures\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Texture\"}]},{\"t\":8,\"n\":\"Unknown\",\"c\":[{\"t\":11,\"n\":\"MPCD - Unknown\"}]}]},{\"t\":1,\"p\":1,\"n\":\"LAYR - Layer\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":3,\"p\":1,\"n\":\"PNAM - Parent\"}]},{\"t\":1,\"p\":1,\"n\":\"LCRT - Location Reference Type\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"CNAM - Color\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":11,\"n\":\"TNAM - Unknown\"}]},{\"t\":1,\"n\":\"LCTN - Location\",\"c\":[{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":7,\"n\":\"ACPR - Actor Cell Persistent Reference\",\"c\":[{\"t\":6,\"n\":\"\",\"c\":[{\"t\":3,\"n\":\"Actor\"},{\"t\":3,\"n\":\"Location\"},{\"t\":3,\"n\":\"Grid Y\"},{\"t\":3,\"n\":\"Grid X\"}]}]},{\"t\":7,\"n\":\"LCPR - Location Cell Persistent Reference\",\"c\":[{\"t\":6,\"n\":\"\",\"c\":[{\"t\":3,\"n\":\"Actor\"},{\"t\":3,\"n\":\"Location\"},{\"t\":3,\"n\":\"Grid Y\"},{\"t\":3,\"n\":\"Grid X\"}]}]},{\"t\":7,\"n\":\"RCPR - Reference Cell Persistent Reference\",\"c\":[{\"t\":3,\"n\":\"Ref\"}]},{\"t\":7,\"n\":\"ACUN - Actor Cell Unique\",\"c\":[{\"t\":6,\"n\":\"\",\"c\":[{\"t\":3,\"n\":\"Actor\"},{\"t\":3,\"n\":\"Ref\"},{\"t\":3,\"n\":\"Location\"}]}]},{\"t\":7,\"n\":\"LCUN - Location Cell Unique\",\"c\":[{\"t\":6,\"n\":\"\",\"c\":[{\"t\":3,\"n\":\"Actor\"},{\"t\":3,\"n\":\"Ref\"},{\"t\":3,\"n\":\"Location\"}]}]},{\"t\":7,\"n\":\"RCUN - Reference Cell Unique\",\"c\":[{\"t\":3,\"n\":\"Actor\"}]},{\"t\":7,\"n\":\"ACSR - Actor Cell Static Reference\",\"c\":[{\"t\":6,\"n\":\"\",\"c\":[{\"t\":3,\"n\":\"Loc Ref Type\"},{\"t\":3,\"n\":\"Marker\"},{\"t\":3,\"n\":\"Location\"},{\"t\":3,\"n\":\"Grid Y\"},{\"t\":3,\"n\":\"Grid X\"}]}]},{\"t\":7,\"n\":\"LCSR - Location Cell Static Reference\",\"c\":[{\"t\":6,\"n\":\"\",\"c\":[{\"t\":3,\"n\":\"Loc Ref Type\"},{\"t\":3,\"n\":\"Marker\"},{\"t\":3,\"n\":\"Location\"},{\"t\":3,\"n\":\"Grid Y\"},{\"t\":3,\"n\":\"Grid X\"}]}]},{\"t\":7,\"n\":\"RCSR - Reference Cell Static Reference\",\"c\":[{\"t\":3,\"n\":\"Ref\"}]},{\"t\":8,\"n\":\"Actor Cell Encounter Cell\",\"c\":[{\"t\":6,\"n\":\"ACEC - Unknown\",\"c\":[{\"t\":3,\"n\":\"Location\"},{\"t\":7,\"n\":\"Coordinates\",\"c\":[{\"t\":6,\"n\":\"\",\"c\":[{\"t\":3,\"n\":\"Grid Y\"},{\"t\":3,\"n\":\"Grid X\"}]}]}]}]},{\"t\":8,\"n\":\"Location Cell Encounter Cell\",\"c\":[{\"t\":6,\"n\":\"LCEC - Unknown\",\"c\":[{\"t\":3,\"n\":\"Location\"},{\"t\":7,\"n\":\"Coordinates\",\"c\":[{\"t\":6,\"n\":\"\",\"c\":[{\"t\":3,\"n\":\"Grid Y\"},{\"t\":3,\"n\":\"Grid X\"}]}]}]}]},{\"t\":8,\"n\":\"Reference Cell Encounter Cell\",\"c\":[{\"t\":6,\"n\":\"RCEC - Unknown\",\"c\":[{\"t\":3,\"n\":\"Location\"},{\"t\":7,\"n\":\"Coordinates\",\"c\":[{\"t\":6,\"n\":\"\",\"c\":[{\"t\":3,\"n\":\"Grid Y\"},{\"t\":3,\"n\":\"Grid X\"}]}]}]}]},{\"t\":7,\"n\":\"ACID - Actor Cell Marker Reference\",\"c\":[{\"t\":3,\"n\":\"Ref\"}]},{\"t\":7,\"n\":\"LCID - Location Cell Marker Reference\",\"c\":[{\"t\":3,\"n\":\"Ref\"}]},{\"t\":7,\"n\":\"ACEP - Actor Cell Enable Point\",\"c\":[{\"t\":6,\"n\":\"\",\"c\":[{\"t\":3,\"n\":\"Actor\"},{\"t\":3,\"n\":\"Ref\"},{\"t\":3,\"n\":\"Grid Y\"},{\"t\":3,\"n\":\"Grid X\"}]}]},{\"t\":7,\"n\":\"LCEP - Location Cell Enable Point\",\"c\":[{\"t\":6,\"n\":\"\",\"c\":[{\"t\":3,\"n\":\"Actor\"},{\"t\":3,\"n\":\"Ref\"},{\"t\":3,\"n\":\"Grid Y\"},{\"t\":3,\"n\":\"Grid X\"}]}]},{\"t\":2,\"n\":\"FULL - Name\"},{\"t\":3,\"n\":\"KSIZ - Keyword Count\"},{\"t\":7,\"n\":\"KWDA - Keywords\",\"d\":1,\"c\":[{\"t\":3,\"n\":\"Keyword\"}]},{\"t\":3,\"n\":\"PNAM - Parent Location\"},{\"t\":3,\"n\":\"NAM1 - Music\"},{\"t\":3,\"n\":\"FNAM - Unreported Crime Faction\"},{\"t\":3,\"n\":\"MNAM - World Location Marker Ref\"},{\"t\":5,\"n\":\"RNAM - World Location Radius\"},{\"t\":5,\"n\":\"ANAM - Unknown\"},{\"t\":6,\"n\":\"CNAM - Color\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unknown\"}]}]},{\"t\":1,\"p\":1,\"n\":\"LENS - Lens Flare\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":5,\"p\":1,\"n\":\"CNAM - Color Influence\"},{\"t\":5,\"p\":1,\"n\":\"DNAM - Fade Distance Radius Scale\"},{\"t\":3,\"n\":\"LFSP - Count\"},{\"t\":10,\"p\":1,\"n\":\"Lens Flare Sprites\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Flare\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"DNAM - Lens Flare Sprite ID\"},{\"t\":2,\"p\":1,\"n\":\"FNAM - Texture\"},{\"t\":6,\"p\":1,\"n\":\"LFSD - Lens Flare Data\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Tint\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Red\"},{\"t\":5,\"p\":1,\"n\":\"Green\"},{\"t\":5,\"p\":1,\"n\":\"Blue\"}]},{\"t\":5,\"p\":1,\"n\":\"Width\"},{\"t\":5,\"p\":1,\"n\":\"Height\"},{\"t\":5,\"p\":1,\"n\":\"Position\"},{\"t\":5,\"p\":1,\"n\":\"Angular Fade\"},{\"t\":5,\"p\":1,\"n\":\"Opacity\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"}]}]}]}]},{\"t\":1,\"p\":1,\"n\":\"LGTM - Lighting Template\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DATA - Lighting\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Ambient Color\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Directional Color\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Fog Color Near\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":5,\"p\":1,\"n\":\"Fog Near\"},{\"t\":5,\"p\":1,\"n\":\"Fog Far\"},{\"t\":3,\"p\":1,\"n\":\"Directional Rotation XY\"},{\"t\":3,\"p\":1,\"n\":\"Directional Rotation Z\"},{\"t\":5,\"p\":1,\"n\":\"Directional Fade\"},{\"t\":5,\"p\":1,\"n\":\"Fog Clip Distance\"},{\"t\":5,\"p\":1,\"n\":\"Fog Power\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":6,\"p\":1,\"n\":\"Fog Color Far\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":5,\"p\":1,\"n\":\"Fog Max\"},{\"t\":5,\"p\":1,\"n\":\"Light Fade Begin\"},{\"t\":5,\"p\":1,\"n\":\"Light Fade End\"},{\"t\":5,\"p\":1,\"n\":\"Near Height Mid\"},{\"t\":5,\"p\":1,\"n\":\"Near Height Range\"},{\"t\":6,\"p\":1,\"n\":\"Fog Color High Near\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Fog Color High Far\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":5,\"p\":1,\"n\":\"High Density Scale\"},{\"t\":5,\"p\":1,\"n\":\"Fog Near Scale\"},{\"t\":5,\"p\":1,\"n\":\"Fog Far Scale\"},{\"t\":5,\"p\":1,\"n\":\"Fog High Near Scale\"},{\"t\":5,\"p\":1,\"n\":\"Fog High Far Scale\"},{\"t\":5,\"p\":1,\"n\":\"Far Height Mid\"},{\"t\":5,\"p\":1,\"n\":\"Far Height Range\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DALC - Directional Ambient Lighting Colors\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Directional\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"X+\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"X-\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Y+\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Y-\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Z+\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Z-\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]}]},{\"t\":6,\"p\":1,\"n\":\"Specular\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":5,\"p\":1,\"n\":\"Scale\"}]},{\"t\":3,\"p\":1,\"n\":\"WGDR - God Rays\"}]},{\"t\":1,\"p\":1,\"n\":\"LIGH - Light\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"VMAD - Virtual Machine Adapter\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Version\"},{\"t\":3,\"p\":1,\"n\":\"Object Format\"},{\"t\":7,\"p\":1,\"n\":\"Scripts\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Script\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"scriptName\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":7,\"p\":1,\"n\":\"Properties\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Property\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"propertyName\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]},{\"t\":2,\"p\":1,\"n\":\"String\"},{\"t\":3,\"p\":1,\"n\":\"Int32\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":3,\"p\":1,\"n\":\"Bool\"},{\"t\":7,\"p\":1,\"n\":\"Struct\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Member\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"memberName\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]},{\"t\":2,\"p\":1,\"n\":\"String\"},{\"t\":3,\"p\":1,\"n\":\"Int32\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":3,\"p\":1,\"n\":\"Bool\"},{\"t\":7,\"p\":1,\"n\":\"Array of Object\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]}]},{\"t\":7,\"p\":1,\"n\":\"Array of String\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Int32\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Float\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Bool\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]}]}]},{\"t\":7,\"p\":1,\"n\":\"Array of Object\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]}]},{\"t\":7,\"p\":1,\"n\":\"Array of String\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Int32\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Float\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Bool\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Struct\",\"c\":[{\"t\":7,\"p\":1,\"n\":\"Struct\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Member\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"memberName\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]},{\"t\":2,\"p\":1,\"n\":\"String\"},{\"t\":3,\"p\":1,\"n\":\"Int32\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":3,\"p\":1,\"n\":\"Bool\"},{\"t\":7,\"p\":1,\"n\":\"Array of Object\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]}]},{\"t\":7,\"p\":1,\"n\":\"Array of String\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Int32\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Float\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Bool\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]}]}]}]}]}]}]}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"X1\"},{\"t\":3,\"p\":1,\"n\":\"Y1\"},{\"t\":3,\"p\":1,\"n\":\"Z1\"},{\"t\":3,\"p\":1,\"n\":\"X2\"},{\"t\":3,\"p\":1,\"n\":\"Y2\"},{\"t\":3,\"p\":1,\"n\":\"Z2\"}]},{\"t\":3,\"p\":1,\"n\":\"PTRN - Preview Transform\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"MODT - Texture Files Hashes\"},{\"t\":3,\"p\":1,\"n\":\"MODS - Material Swap\"},{\"t\":5,\"p\":1,\"n\":\"MODC - Color Remapping Index\"},{\"t\":11,\"n\":\"MODF - Unknown\"}]},{\"t\":3,\"n\":\"KSIZ - Keyword Count\"},{\"t\":7,\"p\":1,\"n\":\"KWDA - Keywords\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Keyword\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Destructible\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"DEST - Header\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Health\"},{\"t\":3,\"p\":1,\"n\":\"DEST Count\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":7,\"p\":1,\"n\":\"DAMC - Resistances\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Resistance\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Damage Type\"},{\"t\":3,\"p\":1,\"n\":\"Value\"}]}]},{\"t\":8,\"p\":1,\"n\":\"Stages\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Stage\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"DSTD - Destruction Stage Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Health %\"},{\"t\":3,\"p\":1,\"n\":\"Index\"},{\"t\":3,\"p\":1,\"n\":\"Model Damage Stage\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":3,\"p\":1,\"n\":\"Self Damage per Second\"},{\"t\":3,\"p\":1,\"n\":\"Explosion\"},{\"t\":3,\"p\":1,\"n\":\"Debris\"},{\"t\":3,\"p\":1,\"n\":\"Debris Count\"}]},{\"t\":2,\"p\":1,\"n\":\"DSTA - Sequence Name\"},{\"t\":6,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"DMDL - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"DMDT - Texture Files Hashes\"},{\"t\":5,\"p\":1,\"n\":\"DMDC - Color Remapping Index\"},{\"t\":3,\"p\":1,\"n\":\"DMDS - Material Swap\"}]},{\"p\":1,\"n\":\"DSTF - End Marker\"}]}]}]},{\"t\":7,\"p\":1,\"n\":\"PRPS - Properties\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Property\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Actor Value\"},{\"t\":5,\"p\":1,\"n\":\"Value\"}]}]},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":2,\"p\":1,\"n\":\"ICON - Inventory Image\"},{\"t\":2,\"p\":1,\"n\":\"MICO - Message Icon\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DATA - \",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Time\"},{\"t\":3,\"p\":1,\"n\":\"Radius\"},{\"t\":6,\"p\":1,\"n\":\"Color\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":5,\"p\":1,\"n\":\"Falloff Exponent\"},{\"t\":5,\"p\":1,\"n\":\"FOV\"},{\"t\":5,\"p\":1,\"n\":\"Near Clip\"},{\"t\":6,\"p\":1,\"n\":\"Flicker Effect\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Period\"},{\"t\":5,\"p\":1,\"n\":\"Intensity Amplitude\"},{\"t\":5,\"p\":1,\"n\":\"Movement Amplitude\"}]},{\"t\":5,\"p\":1,\"n\":\"Constant\"},{\"t\":5,\"p\":1,\"n\":\"Scalar\"},{\"t\":5,\"p\":1,\"n\":\"Exponent\"},{\"t\":5,\"p\":1,\"n\":\"God Rays - Near Clip\"},{\"t\":3,\"p\":1,\"n\":\"Value\"},{\"t\":5,\"p\":1,\"n\":\"Weight\"}]},{\"t\":5,\"p\":1,\"n\":\"FNAM - Fade value\"},{\"t\":2,\"p\":1,\"n\":\"NAM0 - Gobo\"},{\"t\":3,\"p\":1,\"n\":\"LNAM - Lens\"},{\"t\":3,\"p\":1,\"n\":\"WGDR - God Rays\"},{\"t\":3,\"p\":1,\"n\":\"SNAM - Sound\"}]},{\"t\":1,\"p\":1,\"n\":\"LSCR - Load Screen\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"p\":1,\"n\":\"DESC - Description\"},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Conditions\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Condition\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"CTDA - \",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":5,\"p\":1,\"n\":\"Comparison Value - Float\"},{\"t\":3,\"p\":1,\"n\":\"Comparison Value - Global\"},{\"t\":3,\"p\":1,\"n\":\"Function\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":11,\"p\":1,\"n\":\"None\"},{\"t\":3,\"p\":1,\"n\":\"Integer\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":3,\"p\":1,\"n\":\"Actor\"},{\"t\":3,\"p\":1,\"n\":\"Actor Base\"},{\"t\":3,\"p\":1,\"n\":\"Actor Value\"},{\"t\":3,\"p\":1,\"n\":\"Player Action\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"Alignment\"},{\"t\":3,\"p\":1,\"n\":\"Association Type\"},{\"t\":3,\"p\":1,\"n\":\"Axis\"},{\"t\":3,\"p\":1,\"n\":\"Casting Type\"},{\"t\":3,\"p\":1,\"n\":\"Cell\"},{\"t\":3,\"p\":1,\"n\":\"Class\"},{\"t\":3,\"p\":1,\"n\":\"Crime Type\"},{\"t\":3,\"p\":1,\"n\":\"Critical Stage\"},{\"t\":3,\"p\":1,\"n\":\"Encounter Zone\"},{\"t\":3,\"p\":1,\"n\":\"Equip Type\"},{\"t\":3,\"p\":1,\"n\":\"Event\"},{\"t\":3,\"p\":1,\"n\":\"Event Data\"},{\"t\":3,\"p\":1,\"n\":\"Faction\"},{\"t\":3,\"p\":1,\"n\":\"Form List\"},{\"t\":3,\"p\":1,\"n\":\"Form Type\"},{\"t\":3,\"p\":1,\"n\":\"Furniture\"},{\"t\":3,\"p\":1,\"n\":\"Furniture Anim\"},{\"t\":3,\"p\":1,\"n\":\"Furniture Entry\"},{\"t\":3,\"p\":1,\"n\":\"Global\"},{\"t\":3,\"p\":1,\"n\":\"Idle\"},{\"t\":3,\"p\":1,\"n\":\"Inventory Object\"},{\"t\":3,\"p\":1,\"n\":\"Keyword\"},{\"t\":3,\"p\":1,\"n\":\"Location\"},{\"t\":3,\"p\":1,\"n\":\"Base Effect\"},{\"t\":3,\"p\":1,\"n\":\"Effect Item\"},{\"t\":3,\"p\":1,\"n\":\"Misc Stat\"},{\"t\":3,\"p\":1,\"n\":\"Object Reference\"},{\"t\":3,\"p\":1,\"n\":\"Owner\"},{\"t\":3,\"p\":1,\"n\":\"Package\"},{\"t\":3,\"p\":1,\"n\":\"Packdata ID\"},{\"t\":3,\"p\":1,\"n\":\"Perk\"},{\"t\":3,\"p\":1,\"n\":\"Quest\"},{\"t\":3,\"p\":1,\"n\":\"Quest Stage\"},{\"t\":3,\"p\":1,\"n\":\"Race\"},{\"t\":3,\"p\":1,\"n\":\"Referenceable Object\"},{\"t\":3,\"p\":1,\"n\":\"Location Ref Type\"},{\"t\":3,\"p\":1,\"n\":\"Region\"},{\"t\":3,\"p\":1,\"n\":\"Scene\"},{\"t\":3,\"p\":1,\"n\":\"Sex\"},{\"t\":3,\"p\":1,\"n\":\"Shout\"},{\"t\":11,\"p\":1,\"n\":\"Variable Name (unused)\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Function\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Param (unused)\"},{\"t\":3,\"p\":1,\"n\":\"Voice Type\"},{\"t\":3,\"p\":1,\"n\":\"Ward State\"},{\"t\":3,\"p\":1,\"n\":\"Weather\"},{\"t\":3,\"p\":1,\"n\":\"Worldspace\"},{\"t\":3,\"p\":1,\"n\":\"Damage Type\"},{\"t\":3,\"p\":1,\"n\":\"Weapon\"},{\"t\":3,\"p\":1,\"n\":\"Weapon List\"},{\"t\":3,\"p\":1,\"n\":\"Target\"},{\"t\":3,\"p\":1,\"n\":\"Target List\"},{\"t\":3,\"p\":1,\"n\":\"Target Part\"},{\"t\":3,\"p\":1,\"n\":\"VATS Action\"},{\"t\":3,\"p\":1,\"n\":\"Critical Effect\"},{\"t\":3,\"p\":1,\"n\":\"Critical Effect List\"},{\"t\":3,\"p\":1,\"n\":\"Weapon Type\"},{\"t\":3,\"p\":1,\"n\":\"Projectile Type\"},{\"t\":3,\"p\":1,\"n\":\"Delivery Type\"},{\"t\":3,\"p\":1,\"n\":\"Run On\"},{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":3,\"p\":1,\"n\":\"Parameter #3\"}]},{\"t\":2,\"p\":1,\"n\":\"CIS1 - Parameter #1\"},{\"t\":2,\"p\":1,\"n\":\"CIS2 - Parameter #2\"}]}]},{\"t\":3,\"p\":1,\"n\":\"NNAM - Loading Screen NIF\"},{\"t\":3,\"p\":1,\"n\":\"TNAM - Transform\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"ONAM - Rotation\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Min\"},{\"t\":3,\"p\":1,\"n\":\"Max\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"ZNAM - Zoom\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Min\"},{\"t\":5,\"p\":1,\"n\":\"Max\"}]},{\"t\":2,\"p\":1,\"n\":\"MOD2 - Camera Path\"}]},{\"t\":1,\"p\":1,\"n\":\"LTEX - Landscape Texture\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":3,\"p\":1,\"n\":\"TNAM - Texture Set\"},{\"t\":3,\"p\":1,\"n\":\"MNAM - Material Type\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"HNAM - Havok Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Friction\"},{\"t\":3,\"p\":1,\"n\":\"Restitution\"}]},{\"t\":3,\"p\":1,\"n\":\"SNAM - Texture Specular Exponent\"},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Grasses\",\"d\":1,\"c\":[{\"t\":3,\"p\":1,\"n\":\"GNAM - Grass\"}]}]},{\"t\":1,\"p\":1,\"n\":\"LVLI - Leveled Item\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"X1\"},{\"t\":3,\"p\":1,\"n\":\"Y1\"},{\"t\":3,\"p\":1,\"n\":\"Z1\"},{\"t\":3,\"p\":1,\"n\":\"X2\"},{\"t\":3,\"p\":1,\"n\":\"Y2\"},{\"t\":3,\"p\":1,\"n\":\"Z2\"}]},{\"t\":3,\"p\":1,\"n\":\"LVLD - Chance None\"},{\"t\":3,\"p\":1,\"n\":\"LVLM - Max Count\"},{\"t\":3,\"p\":1,\"n\":\"LVLF - Flags\"},{\"t\":3,\"p\":1,\"n\":\"LVLG - Use Global\"},{\"t\":3,\"n\":\"LLCT - Count\"},{\"t\":10,\"p\":1,\"n\":\"Leveled List Entries\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Leveled List Entry\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"LVLO - Base Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Level\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":3,\"p\":1,\"n\":\"Count\"},{\"t\":3,\"p\":1,\"n\":\"Chance None\"}]},{\"t\":6,\"p\":1,\"n\":\"COED - Extra Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Owner\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Global Variable\"},{\"t\":3,\"p\":1,\"n\":\"Required Rank\"},{\"t\":5,\"p\":1,\"n\":\"Item Condition\"}]}]}]},{\"t\":7,\"p\":1,\"n\":\"LLKC - Filter Keyword Chances\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Filter\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Keyword\"},{\"t\":3,\"p\":1,\"n\":\"Chance\"}]}]},{\"t\":3,\"p\":1,\"n\":\"LVSG - Epic Loot Chance\"},{\"t\":2,\"p\":1,\"n\":\"ONAM - Override Name\"}]},{\"t\":1,\"p\":1,\"n\":\"LVLN - Leveled NPC\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"X1\"},{\"t\":3,\"p\":1,\"n\":\"Y1\"},{\"t\":3,\"p\":1,\"n\":\"Z1\"},{\"t\":3,\"p\":1,\"n\":\"X2\"},{\"t\":3,\"p\":1,\"n\":\"Y2\"},{\"t\":3,\"p\":1,\"n\":\"Z2\"}]},{\"t\":3,\"p\":1,\"n\":\"LVLD - Chance None\"},{\"t\":3,\"p\":1,\"n\":\"LVLM - Max Count\"},{\"t\":3,\"p\":1,\"n\":\"LVLF - Flags\"},{\"t\":3,\"p\":1,\"n\":\"LVLG - Use Global\"},{\"t\":3,\"n\":\"LLCT - Count\"},{\"t\":10,\"p\":1,\"n\":\"Leveled List Entries\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Leveled List Entry\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"LVLO - Base Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Level\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":3,\"p\":1,\"n\":\"Count\"},{\"t\":3,\"p\":1,\"n\":\"Chance None\"}]},{\"t\":6,\"p\":1,\"n\":\"COED - Extra Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Owner\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Global Variable\"},{\"t\":3,\"p\":1,\"n\":\"Required Rank\"},{\"t\":5,\"p\":1,\"n\":\"Item Condition\"}]}]}]},{\"t\":7,\"p\":1,\"n\":\"LLKC - Filter Keyword Chances\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Filter\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Keyword\"},{\"t\":3,\"p\":1,\"n\":\"Chance\"}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"MODT - Texture Files Hashes\"},{\"t\":3,\"p\":1,\"n\":\"MODS - Material Swap\"},{\"t\":5,\"p\":1,\"n\":\"MODC - Color Remapping Index\"},{\"t\":11,\"n\":\"MODF - Unknown\"}]}]},{\"t\":1,\"p\":1,\"n\":\"LVSP - Leveled Spell\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"}]},{\"t\":1,\"p\":1,\"n\":\"MATO - Material Object\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"MODT - Texture Files Hashes\"},{\"t\":3,\"p\":1,\"n\":\"MODS - Material Swap\"},{\"t\":5,\"p\":1,\"n\":\"MODC - Color Remapping Index\"},{\"t\":11,\"n\":\"MODF - Unknown\"}]},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Property Data\",\"d\":1,\"c\":[{\"t\":11,\"p\":1,\"n\":\"DNAM - Data\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DATA - Directional Material Data\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Falloff Scale\"},{\"t\":5,\"p\":1,\"n\":\"Falloff Bias\"},{\"t\":5,\"p\":1,\"n\":\"Noise UV Scale\"},{\"t\":5,\"p\":1,\"n\":\"Material UV Scale\"},{\"t\":6,\"p\":1,\"n\":\"Projection Vector\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"X\"},{\"t\":5,\"p\":1,\"n\":\"Y\"},{\"t\":5,\"p\":1,\"n\":\"Z\"}]},{\"t\":5,\"p\":1,\"n\":\"Normal Dampener\"},{\"t\":6,\"p\":1,\"n\":\"Single Pass Color\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Red\"},{\"t\":5,\"p\":1,\"n\":\"Green\"},{\"t\":5,\"p\":1,\"n\":\"Blue\"}]},{\"t\":3,\"p\":1,\"n\":\"Flags\"}]}]},{\"t\":1,\"p\":1,\"n\":\"MATT - Material Type\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":3,\"p\":1,\"n\":\"PNAM - Material Parent\"},{\"t\":2,\"p\":1,\"n\":\"MNAM - Material Name\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"CNAM - Havok Display Color\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Red\"},{\"t\":5,\"p\":1,\"n\":\"Green\"},{\"t\":5,\"p\":1,\"n\":\"Blue\"}]},{\"t\":5,\"p\":1,\"n\":\"BNAM - Buoyancy\"},{\"t\":3,\"p\":1,\"n\":\"FNAM - Flags\"},{\"t\":3,\"p\":1,\"n\":\"HNAM - Havok Impact Data Set\"},{\"t\":2,\"p\":1,\"n\":\"ANAM - Breakable FX\"},{\"t\":11,\"n\":\"MODT - Texture Files Hashes\"}]},{\"t\":1,\"p\":1,\"n\":\"MESG - Message\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"p\":1,\"n\":\"DESC - Description\"},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":3,\"p\":1,\"n\":\"INAM - Icon (unused)\"},{\"t\":3,\"p\":1,\"n\":\"QNAM - Owner Quest\"},{\"t\":3,\"p\":1,\"n\":\"DNAM - Flags\"},{\"t\":3,\"p\":1,\"n\":\"TNAM - Display Time\"},{\"t\":2,\"p\":1,\"n\":\"SNAM - SWF\"},{\"t\":2,\"p\":1,\"n\":\"NNAM - Short Title\"},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Menu Buttons\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Menu Button\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"ITXT - Button Text\"},{\"t\":8,\"p\":1,\"n\":\"Conditions\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Condition\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"CTDA - \",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":5,\"p\":1,\"n\":\"Comparison Value - Float\"},{\"t\":3,\"p\":1,\"n\":\"Comparison Value - Global\"},{\"t\":3,\"p\":1,\"n\":\"Function\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":11,\"p\":1,\"n\":\"None\"},{\"t\":3,\"p\":1,\"n\":\"Integer\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":3,\"p\":1,\"n\":\"Actor\"},{\"t\":3,\"p\":1,\"n\":\"Actor Base\"},{\"t\":3,\"p\":1,\"n\":\"Actor Value\"},{\"t\":3,\"p\":1,\"n\":\"Player Action\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"Alignment\"},{\"t\":3,\"p\":1,\"n\":\"Association Type\"},{\"t\":3,\"p\":1,\"n\":\"Axis\"},{\"t\":3,\"p\":1,\"n\":\"Casting Type\"},{\"t\":3,\"p\":1,\"n\":\"Cell\"},{\"t\":3,\"p\":1,\"n\":\"Class\"},{\"t\":3,\"p\":1,\"n\":\"Crime Type\"},{\"t\":3,\"p\":1,\"n\":\"Critical Stage\"},{\"t\":3,\"p\":1,\"n\":\"Encounter Zone\"},{\"t\":3,\"p\":1,\"n\":\"Equip Type\"},{\"t\":3,\"p\":1,\"n\":\"Event\"},{\"t\":3,\"p\":1,\"n\":\"Event Data\"},{\"t\":3,\"p\":1,\"n\":\"Faction\"},{\"t\":3,\"p\":1,\"n\":\"Form List\"},{\"t\":3,\"p\":1,\"n\":\"Form Type\"},{\"t\":3,\"p\":1,\"n\":\"Furniture\"},{\"t\":3,\"p\":1,\"n\":\"Furniture Anim\"},{\"t\":3,\"p\":1,\"n\":\"Furniture Entry\"},{\"t\":3,\"p\":1,\"n\":\"Global\"},{\"t\":3,\"p\":1,\"n\":\"Idle\"},{\"t\":3,\"p\":1,\"n\":\"Inventory Object\"},{\"t\":3,\"p\":1,\"n\":\"Keyword\"},{\"t\":3,\"p\":1,\"n\":\"Location\"},{\"t\":3,\"p\":1,\"n\":\"Base Effect\"},{\"t\":3,\"p\":1,\"n\":\"Effect Item\"},{\"t\":3,\"p\":1,\"n\":\"Misc Stat\"},{\"t\":3,\"p\":1,\"n\":\"Object Reference\"},{\"t\":3,\"p\":1,\"n\":\"Owner\"},{\"t\":3,\"p\":1,\"n\":\"Package\"},{\"t\":3,\"p\":1,\"n\":\"Packdata ID\"},{\"t\":3,\"p\":1,\"n\":\"Perk\"},{\"t\":3,\"p\":1,\"n\":\"Quest\"},{\"t\":3,\"p\":1,\"n\":\"Quest Stage\"},{\"t\":3,\"p\":1,\"n\":\"Race\"},{\"t\":3,\"p\":1,\"n\":\"Referenceable Object\"},{\"t\":3,\"p\":1,\"n\":\"Location Ref Type\"},{\"t\":3,\"p\":1,\"n\":\"Region\"},{\"t\":3,\"p\":1,\"n\":\"Scene\"},{\"t\":3,\"p\":1,\"n\":\"Sex\"},{\"t\":3,\"p\":1,\"n\":\"Shout\"},{\"t\":11,\"p\":1,\"n\":\"Variable Name (unused)\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Function\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Param (unused)\"},{\"t\":3,\"p\":1,\"n\":\"Voice Type\"},{\"t\":3,\"p\":1,\"n\":\"Ward State\"},{\"t\":3,\"p\":1,\"n\":\"Weather\"},{\"t\":3,\"p\":1,\"n\":\"Worldspace\"},{\"t\":3,\"p\":1,\"n\":\"Damage Type\"},{\"t\":3,\"p\":1,\"n\":\"Weapon\"},{\"t\":3,\"p\":1,\"n\":\"Weapon List\"},{\"t\":3,\"p\":1,\"n\":\"Target\"},{\"t\":3,\"p\":1,\"n\":\"Target List\"},{\"t\":3,\"p\":1,\"n\":\"Target Part\"},{\"t\":3,\"p\":1,\"n\":\"VATS Action\"},{\"t\":3,\"p\":1,\"n\":\"Critical Effect\"},{\"t\":3,\"p\":1,\"n\":\"Critical Effect List\"},{\"t\":3,\"p\":1,\"n\":\"Weapon Type\"},{\"t\":3,\"p\":1,\"n\":\"Projectile Type\"},{\"t\":3,\"p\":1,\"n\":\"Delivery Type\"},{\"t\":3,\"p\":1,\"n\":\"Run On\"},{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":3,\"p\":1,\"n\":\"Parameter #3\"}]},{\"t\":2,\"p\":1,\"n\":\"CIS1 - Parameter #1\"},{\"t\":2,\"p\":1,\"n\":\"CIS2 - Parameter #2\"}]}]}]}]}]},{\"t\":1,\"p\":1,\"n\":\"MGEF - Magic Effect\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"VMAD - Virtual Machine Adapter\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Version\"},{\"t\":3,\"p\":1,\"n\":\"Object Format\"},{\"t\":7,\"p\":1,\"n\":\"Scripts\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Script\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"scriptName\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":7,\"p\":1,\"n\":\"Properties\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Property\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"propertyName\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]},{\"t\":2,\"p\":1,\"n\":\"String\"},{\"t\":3,\"p\":1,\"n\":\"Int32\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":3,\"p\":1,\"n\":\"Bool\"},{\"t\":7,\"p\":1,\"n\":\"Struct\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Member\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"memberName\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]},{\"t\":2,\"p\":1,\"n\":\"String\"},{\"t\":3,\"p\":1,\"n\":\"Int32\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":3,\"p\":1,\"n\":\"Bool\"},{\"t\":7,\"p\":1,\"n\":\"Array of Object\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]}]},{\"t\":7,\"p\":1,\"n\":\"Array of String\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Int32\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Float\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Bool\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]}]}]},{\"t\":7,\"p\":1,\"n\":\"Array of Object\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]}]},{\"t\":7,\"p\":1,\"n\":\"Array of String\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Int32\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Float\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Bool\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Struct\",\"c\":[{\"t\":7,\"p\":1,\"n\":\"Struct\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Member\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"memberName\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]},{\"t\":2,\"p\":1,\"n\":\"String\"},{\"t\":3,\"p\":1,\"n\":\"Int32\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":3,\"p\":1,\"n\":\"Bool\"},{\"t\":7,\"p\":1,\"n\":\"Array of Object\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]}]},{\"t\":7,\"p\":1,\"n\":\"Array of String\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Int32\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Float\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Bool\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]}]}]}]}]}]}]}]}]},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":3,\"p\":1,\"n\":\"MDOB - Menu Display Object\"},{\"t\":3,\"n\":\"KSIZ - Keyword Count\"},{\"t\":7,\"p\":1,\"n\":\"KWDA - Keywords\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Keyword\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Magic Effect Data\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"DATA - Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":5,\"p\":1,\"n\":\"Base Cost\"},{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Assoc. Item\"},{\"t\":11,\"p\":1,\"n\":\"Magic Skill (unused)\"},{\"t\":3,\"p\":1,\"n\":\"Resist Value\"},{\"t\":3,\"p\":1,\"n\":\"Counter Effect count\"},{\"t\":3,\"p\":1,\"n\":\"Casting Light\"},{\"t\":5,\"p\":1,\"n\":\"Taper Weight\"},{\"t\":3,\"p\":1,\"n\":\"Hit Shader\"},{\"t\":3,\"p\":1,\"n\":\"Enchant Shader\"},{\"t\":3,\"p\":1,\"n\":\"Minimum Skill Level\"},{\"t\":6,\"p\":1,\"n\":\"Spellmaking\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Area\"},{\"t\":5,\"p\":1,\"n\":\"Casting Time\"}]},{\"t\":5,\"p\":1,\"n\":\"Taper Curve\"},{\"t\":5,\"p\":1,\"n\":\"Taper Duration\"},{\"t\":5,\"p\":1,\"n\":\"Second AV Weight\"},{\"t\":3,\"p\":1,\"n\":\"Archetype\"},{\"t\":3,\"p\":1,\"n\":\"Actor Value\"},{\"t\":3,\"p\":1,\"n\":\"Projectile\"},{\"t\":3,\"p\":1,\"n\":\"Explosion\"},{\"t\":3,\"p\":1,\"n\":\"Casting Type\"},{\"t\":3,\"p\":1,\"n\":\"Delivery\"},{\"t\":3,\"p\":1,\"n\":\"Casting Art\"},{\"t\":3,\"p\":1,\"n\":\"Hit Effect Art\"},{\"t\":3,\"p\":1,\"n\":\"Impact Data\"},{\"t\":5,\"p\":1,\"n\":\"Skill Usage Multiplier\"},{\"t\":6,\"p\":1,\"n\":\"Dual Casting\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Art\"},{\"t\":5,\"p\":1,\"n\":\"Scale\"}]},{\"t\":3,\"p\":1,\"n\":\"Enchant Art\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":3,\"p\":1,\"n\":\"Equip Ability\"},{\"t\":3,\"p\":1,\"n\":\"Image Space Modifier\"},{\"t\":3,\"p\":1,\"n\":\"Perk to Apply\"},{\"t\":3,\"p\":1,\"n\":\"Casting Sound Level\"},{\"t\":6,\"p\":1,\"n\":\"Script Effect AI\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Score\"},{\"t\":5,\"p\":1,\"n\":\"Delay Time\"}]}]}]},{\"t\":8,\"s\":1,\"n\":\"Counter Effects\",\"d\":1,\"c\":[{\"t\":3,\"n\":\"ESCE - Effect\"}]},{\"t\":7,\"p\":1,\"n\":\"SNDD - Sounds\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Sound\"}]}]},{\"t\":2,\"p\":1,\"n\":\"DNAM - Magic Item Description\"},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Conditions\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Condition\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"CTDA - \",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":5,\"p\":1,\"n\":\"Comparison Value - Float\"},{\"t\":3,\"p\":1,\"n\":\"Comparison Value - Global\"},{\"t\":3,\"p\":1,\"n\":\"Function\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":11,\"p\":1,\"n\":\"None\"},{\"t\":3,\"p\":1,\"n\":\"Integer\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":3,\"p\":1,\"n\":\"Actor\"},{\"t\":3,\"p\":1,\"n\":\"Actor Base\"},{\"t\":3,\"p\":1,\"n\":\"Actor Value\"},{\"t\":3,\"p\":1,\"n\":\"Player Action\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"Alignment\"},{\"t\":3,\"p\":1,\"n\":\"Association Type\"},{\"t\":3,\"p\":1,\"n\":\"Axis\"},{\"t\":3,\"p\":1,\"n\":\"Casting Type\"},{\"t\":3,\"p\":1,\"n\":\"Cell\"},{\"t\":3,\"p\":1,\"n\":\"Class\"},{\"t\":3,\"p\":1,\"n\":\"Crime Type\"},{\"t\":3,\"p\":1,\"n\":\"Critical Stage\"},{\"t\":3,\"p\":1,\"n\":\"Encounter Zone\"},{\"t\":3,\"p\":1,\"n\":\"Equip Type\"},{\"t\":3,\"p\":1,\"n\":\"Event\"},{\"t\":3,\"p\":1,\"n\":\"Event Data\"},{\"t\":3,\"p\":1,\"n\":\"Faction\"},{\"t\":3,\"p\":1,\"n\":\"Form List\"},{\"t\":3,\"p\":1,\"n\":\"Form Type\"},{\"t\":3,\"p\":1,\"n\":\"Furniture\"},{\"t\":3,\"p\":1,\"n\":\"Furniture Anim\"},{\"t\":3,\"p\":1,\"n\":\"Furniture Entry\"},{\"t\":3,\"p\":1,\"n\":\"Global\"},{\"t\":3,\"p\":1,\"n\":\"Idle\"},{\"t\":3,\"p\":1,\"n\":\"Inventory Object\"},{\"t\":3,\"p\":1,\"n\":\"Keyword\"},{\"t\":3,\"p\":1,\"n\":\"Location\"},{\"t\":3,\"p\":1,\"n\":\"Base Effect\"},{\"t\":3,\"p\":1,\"n\":\"Effect Item\"},{\"t\":3,\"p\":1,\"n\":\"Misc Stat\"},{\"t\":3,\"p\":1,\"n\":\"Object Reference\"},{\"t\":3,\"p\":1,\"n\":\"Owner\"},{\"t\":3,\"p\":1,\"n\":\"Package\"},{\"t\":3,\"p\":1,\"n\":\"Packdata ID\"},{\"t\":3,\"p\":1,\"n\":\"Perk\"},{\"t\":3,\"p\":1,\"n\":\"Quest\"},{\"t\":3,\"p\":1,\"n\":\"Quest Stage\"},{\"t\":3,\"p\":1,\"n\":\"Race\"},{\"t\":3,\"p\":1,\"n\":\"Referenceable Object\"},{\"t\":3,\"p\":1,\"n\":\"Location Ref Type\"},{\"t\":3,\"p\":1,\"n\":\"Region\"},{\"t\":3,\"p\":1,\"n\":\"Scene\"},{\"t\":3,\"p\":1,\"n\":\"Sex\"},{\"t\":3,\"p\":1,\"n\":\"Shout\"},{\"t\":11,\"p\":1,\"n\":\"Variable Name (unused)\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Function\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Param (unused)\"},{\"t\":3,\"p\":1,\"n\":\"Voice Type\"},{\"t\":3,\"p\":1,\"n\":\"Ward State\"},{\"t\":3,\"p\":1,\"n\":\"Weather\"},{\"t\":3,\"p\":1,\"n\":\"Worldspace\"},{\"t\":3,\"p\":1,\"n\":\"Damage Type\"},{\"t\":3,\"p\":1,\"n\":\"Weapon\"},{\"t\":3,\"p\":1,\"n\":\"Weapon List\"},{\"t\":3,\"p\":1,\"n\":\"Target\"},{\"t\":3,\"p\":1,\"n\":\"Target List\"},{\"t\":3,\"p\":1,\"n\":\"Target Part\"},{\"t\":3,\"p\":1,\"n\":\"VATS Action\"},{\"t\":3,\"p\":1,\"n\":\"Critical Effect\"},{\"t\":3,\"p\":1,\"n\":\"Critical Effect List\"},{\"t\":3,\"p\":1,\"n\":\"Weapon Type\"},{\"t\":3,\"p\":1,\"n\":\"Projectile Type\"},{\"t\":3,\"p\":1,\"n\":\"Delivery Type\"},{\"t\":3,\"p\":1,\"n\":\"Run On\"},{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":3,\"p\":1,\"n\":\"Parameter #3\"}]},{\"t\":2,\"p\":1,\"n\":\"CIS1 - Parameter #1\"},{\"t\":2,\"p\":1,\"n\":\"CIS2 - Parameter #2\"}]}]}]},{\"t\":1,\"p\":1,\"n\":\"MISC - Misc. Item\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"VMAD - Virtual Machine Adapter\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Version\"},{\"t\":3,\"p\":1,\"n\":\"Object Format\"},{\"t\":7,\"p\":1,\"n\":\"Scripts\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Script\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"scriptName\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":7,\"p\":1,\"n\":\"Properties\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Property\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"propertyName\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]},{\"t\":2,\"p\":1,\"n\":\"String\"},{\"t\":3,\"p\":1,\"n\":\"Int32\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":3,\"p\":1,\"n\":\"Bool\"},{\"t\":7,\"p\":1,\"n\":\"Struct\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Member\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"memberName\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]},{\"t\":2,\"p\":1,\"n\":\"String\"},{\"t\":3,\"p\":1,\"n\":\"Int32\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":3,\"p\":1,\"n\":\"Bool\"},{\"t\":7,\"p\":1,\"n\":\"Array of Object\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]}]},{\"t\":7,\"p\":1,\"n\":\"Array of String\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Int32\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Float\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Bool\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]}]}]},{\"t\":7,\"p\":1,\"n\":\"Array of Object\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]}]},{\"t\":7,\"p\":1,\"n\":\"Array of String\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Int32\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Float\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Bool\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Struct\",\"c\":[{\"t\":7,\"p\":1,\"n\":\"Struct\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Member\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"memberName\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]},{\"t\":2,\"p\":1,\"n\":\"String\"},{\"t\":3,\"p\":1,\"n\":\"Int32\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":3,\"p\":1,\"n\":\"Bool\"},{\"t\":7,\"p\":1,\"n\":\"Array of Object\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]}]},{\"t\":7,\"p\":1,\"n\":\"Array of String\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Int32\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Float\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Bool\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]}]}]}]}]}]}]}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"X1\"},{\"t\":3,\"p\":1,\"n\":\"Y1\"},{\"t\":3,\"p\":1,\"n\":\"Z1\"},{\"t\":3,\"p\":1,\"n\":\"X2\"},{\"t\":3,\"p\":1,\"n\":\"Y2\"},{\"t\":3,\"p\":1,\"n\":\"Z2\"}]},{\"t\":3,\"p\":1,\"n\":\"PTRN - Preview Transform\"},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"MODT - Texture Files Hashes\"},{\"t\":3,\"p\":1,\"n\":\"MODS - Material Swap\"},{\"t\":5,\"p\":1,\"n\":\"MODC - Color Remapping Index\"},{\"t\":11,\"n\":\"MODF - Unknown\"}]},{\"t\":2,\"p\":1,\"n\":\"ICON - Inventory Image\"},{\"t\":2,\"p\":1,\"n\":\"MICO - Message Icon\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Destructible\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"DEST - Header\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Health\"},{\"t\":3,\"p\":1,\"n\":\"DEST Count\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":7,\"p\":1,\"n\":\"DAMC - Resistances\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Resistance\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Damage Type\"},{\"t\":3,\"p\":1,\"n\":\"Value\"}]}]},{\"t\":8,\"p\":1,\"n\":\"Stages\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Stage\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"DSTD - Destruction Stage Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Health %\"},{\"t\":3,\"p\":1,\"n\":\"Index\"},{\"t\":3,\"p\":1,\"n\":\"Model Damage Stage\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":3,\"p\":1,\"n\":\"Self Damage per Second\"},{\"t\":3,\"p\":1,\"n\":\"Explosion\"},{\"t\":3,\"p\":1,\"n\":\"Debris\"},{\"t\":3,\"p\":1,\"n\":\"Debris Count\"}]},{\"t\":2,\"p\":1,\"n\":\"DSTA - Sequence Name\"},{\"t\":6,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"DMDL - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"DMDT - Texture Files Hashes\"},{\"t\":5,\"p\":1,\"n\":\"DMDC - Color Remapping Index\"},{\"t\":3,\"p\":1,\"n\":\"DMDS - Material Swap\"}]},{\"p\":1,\"n\":\"DSTF - End Marker\"}]}]}]},{\"t\":3,\"p\":1,\"n\":\"YNAM - Sound - Pick Up\"},{\"t\":3,\"p\":1,\"n\":\"ZNAM - Sound - Put Down\"},{\"t\":3,\"n\":\"KSIZ - Keyword Count\"},{\"t\":7,\"p\":1,\"n\":\"KWDA - Keywords\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Keyword\"}]},{\"t\":3,\"p\":1,\"n\":\"FIMD - Featured Item Message\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DATA - Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Value\"},{\"t\":5,\"p\":1,\"n\":\"Weight\"}]},{\"t\":7,\"p\":1,\"n\":\"CVPA - Components\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Component\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Component\"},{\"t\":3,\"p\":1,\"n\":\"Count\"}]}]},{\"t\":7,\"p\":1,\"n\":\"CDIX - Component Display Indices\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Display Index\"}]}]},{\"t\":1,\"p\":1,\"n\":\"MOVT - Movement Type\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"p\":1,\"n\":\"MNAM - Name\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"SPED - Movement Data\",\"c\":[{\"t\":5,\"n\":\"Unknown\"},{\"t\":5,\"p\":1,\"n\":\"Walk - Left\"},{\"t\":5,\"p\":1,\"n\":\"Run - Left\"},{\"t\":5,\"p\":1,\"n\":\"Walk - Right\"},{\"t\":5,\"p\":1,\"n\":\"Run - Right\"},{\"t\":5,\"p\":1,\"n\":\"Walk - Forward\"},{\"t\":5,\"p\":1,\"n\":\"Run - Forward\"},{\"t\":5,\"p\":1,\"n\":\"Sprint - Forward\"},{\"t\":5,\"p\":1,\"n\":\"Walk - Back\"},{\"t\":5,\"p\":1,\"n\":\"Run - Back\"},{\"t\":5,\"p\":1,\"n\":\"Standing - Pitch\"},{\"t\":5,\"p\":1,\"n\":\"Walk - Pitch\"},{\"t\":5,\"p\":1,\"n\":\"Run - Pitch\"},{\"t\":5,\"p\":1,\"n\":\"Sprint - Pitch\"},{\"t\":5,\"p\":1,\"n\":\"Standing - Yaw\"},{\"t\":5,\"p\":1,\"n\":\"Walk - Yaw\"},{\"t\":5,\"p\":1,\"n\":\"Run - Yaw\"},{\"t\":5,\"p\":1,\"n\":\"Sprint - Yaw\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"INAM - Anim Change Thresholds (unused)\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Directional\"},{\"t\":5,\"p\":1,\"n\":\"Movement Speed\"},{\"t\":5,\"p\":1,\"n\":\"Rotation Speed\"}]},{\"t\":5,\"p\":1,\"n\":\"JNAM - Float Height\"},{\"t\":5,\"p\":1,\"n\":\"LNAM - Flight - Angle Gain\"}]},{\"t\":1,\"p\":1,\"n\":\"MSTT - Moveable Static\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"VMAD - Virtual Machine Adapter\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Version\"},{\"t\":3,\"p\":1,\"n\":\"Object Format\"},{\"t\":7,\"p\":1,\"n\":\"Scripts\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Script\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"scriptName\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":7,\"p\":1,\"n\":\"Properties\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Property\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"propertyName\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]},{\"t\":2,\"p\":1,\"n\":\"String\"},{\"t\":3,\"p\":1,\"n\":\"Int32\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":3,\"p\":1,\"n\":\"Bool\"},{\"t\":7,\"p\":1,\"n\":\"Struct\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Member\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"memberName\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]},{\"t\":2,\"p\":1,\"n\":\"String\"},{\"t\":3,\"p\":1,\"n\":\"Int32\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":3,\"p\":1,\"n\":\"Bool\"},{\"t\":7,\"p\":1,\"n\":\"Array of Object\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]}]},{\"t\":7,\"p\":1,\"n\":\"Array of String\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Int32\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Float\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Bool\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]}]}]},{\"t\":7,\"p\":1,\"n\":\"Array of Object\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]}]},{\"t\":7,\"p\":1,\"n\":\"Array of String\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Int32\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Float\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Bool\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Struct\",\"c\":[{\"t\":7,\"p\":1,\"n\":\"Struct\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Member\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"memberName\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]},{\"t\":2,\"p\":1,\"n\":\"String\"},{\"t\":3,\"p\":1,\"n\":\"Int32\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":3,\"p\":1,\"n\":\"Bool\"},{\"t\":7,\"p\":1,\"n\":\"Array of Object\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]}]},{\"t\":7,\"p\":1,\"n\":\"Array of String\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Int32\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Float\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Bool\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]}]}]}]}]}]}]}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"X1\"},{\"t\":3,\"p\":1,\"n\":\"Y1\"},{\"t\":3,\"p\":1,\"n\":\"Z1\"},{\"t\":3,\"p\":1,\"n\":\"X2\"},{\"t\":3,\"p\":1,\"n\":\"Y2\"},{\"t\":3,\"p\":1,\"n\":\"Z2\"}]},{\"t\":3,\"p\":1,\"n\":\"PTRN - Preview Transform\"},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"MODT - Texture Files Hashes\"},{\"t\":3,\"p\":1,\"n\":\"MODS - Material Swap\"},{\"t\":5,\"p\":1,\"n\":\"MODC - Color Remapping Index\"},{\"t\":11,\"n\":\"MODF - Unknown\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Destructible\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"DEST - Header\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Health\"},{\"t\":3,\"p\":1,\"n\":\"DEST Count\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":7,\"p\":1,\"n\":\"DAMC - Resistances\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Resistance\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Damage Type\"},{\"t\":3,\"p\":1,\"n\":\"Value\"}]}]},{\"t\":8,\"p\":1,\"n\":\"Stages\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Stage\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"DSTD - Destruction Stage Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Health %\"},{\"t\":3,\"p\":1,\"n\":\"Index\"},{\"t\":3,\"p\":1,\"n\":\"Model Damage Stage\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":3,\"p\":1,\"n\":\"Self Damage per Second\"},{\"t\":3,\"p\":1,\"n\":\"Explosion\"},{\"t\":3,\"p\":1,\"n\":\"Debris\"},{\"t\":3,\"p\":1,\"n\":\"Debris Count\"}]},{\"t\":2,\"p\":1,\"n\":\"DSTA - Sequence Name\"},{\"t\":6,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"DMDL - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"DMDT - Texture Files Hashes\"},{\"t\":5,\"p\":1,\"n\":\"DMDC - Color Remapping Index\"},{\"t\":3,\"p\":1,\"n\":\"DMDS - Material Swap\"}]},{\"p\":1,\"n\":\"DSTF - End Marker\"}]}]}]},{\"t\":3,\"n\":\"KSIZ - Keyword Count\"},{\"t\":7,\"p\":1,\"n\":\"KWDA - Keywords\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Keyword\"}]},{\"t\":7,\"p\":1,\"n\":\"PRPS - Properties\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Property\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Actor Value\"},{\"t\":5,\"p\":1,\"n\":\"Value\"}]}]},{\"t\":3,\"p\":1,\"n\":\"DATA - On Local Map\"},{\"t\":3,\"p\":1,\"n\":\"SNAM - Looping Sound\"}]},{\"t\":1,\"p\":1,\"n\":\"MSWP - Material Swap\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"p\":1,\"n\":\"FNAM - Tree Folder\"},{\"t\":10,\"p\":1,\"n\":\"Material Substitutions\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Substitution\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"BNAM - Original Material\"},{\"t\":2,\"p\":1,\"n\":\"SNAM - Replacement Material\"},{\"t\":2,\"p\":1,\"n\":\"FNAM - Tree Folder (obsolete)\"},{\"t\":5,\"p\":1,\"n\":\"CNAM - Color Remapping Index\"}]}]}]},{\"t\":1,\"p\":1,\"n\":\"MUSC - Music Type\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":3,\"p\":1,\"n\":\"FNAM - Flags\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"PNAM - Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Priority\"},{\"t\":3,\"p\":1,\"n\":\"Ducking (dB)\"}]},{\"t\":5,\"p\":1,\"n\":\"WNAM - Fade Duration\"},{\"t\":7,\"p\":1,\"n\":\"TNAM - Music Tracks\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Track\"}]}]},{\"t\":1,\"p\":1,\"n\":\"MUST - Music Track\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":3,\"p\":1,\"n\":\"CNAM - Track Type\"},{\"t\":5,\"p\":1,\"n\":\"FLTV - Duration\"},{\"t\":5,\"p\":1,\"n\":\"DNAM - Fade-Out\"},{\"t\":2,\"p\":1,\"n\":\"ANAM - Track Filename\"},{\"t\":2,\"p\":1,\"n\":\"BNAM - Finale Filename\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"LNAM - Loop Data\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Loop Begins\"},{\"t\":5,\"p\":1,\"n\":\"Loop Ends\"},{\"t\":3,\"p\":1,\"n\":\"Loop Count\"}]},{\"t\":7,\"p\":1,\"n\":\"FNAM - Cue Points\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Point\"}]},{\"t\":3,\"n\":\"CITC - Condition Count\"},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Conditions\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Condition\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"CTDA - \",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":5,\"p\":1,\"n\":\"Comparison Value - Float\"},{\"t\":3,\"p\":1,\"n\":\"Comparison Value - Global\"},{\"t\":3,\"p\":1,\"n\":\"Function\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":11,\"p\":1,\"n\":\"None\"},{\"t\":3,\"p\":1,\"n\":\"Integer\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":3,\"p\":1,\"n\":\"Actor\"},{\"t\":3,\"p\":1,\"n\":\"Actor Base\"},{\"t\":3,\"p\":1,\"n\":\"Actor Value\"},{\"t\":3,\"p\":1,\"n\":\"Player Action\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"Alignment\"},{\"t\":3,\"p\":1,\"n\":\"Association Type\"},{\"t\":3,\"p\":1,\"n\":\"Axis\"},{\"t\":3,\"p\":1,\"n\":\"Casting Type\"},{\"t\":3,\"p\":1,\"n\":\"Cell\"},{\"t\":3,\"p\":1,\"n\":\"Class\"},{\"t\":3,\"p\":1,\"n\":\"Crime Type\"},{\"t\":3,\"p\":1,\"n\":\"Critical Stage\"},{\"t\":3,\"p\":1,\"n\":\"Encounter Zone\"},{\"t\":3,\"p\":1,\"n\":\"Equip Type\"},{\"t\":3,\"p\":1,\"n\":\"Event\"},{\"t\":3,\"p\":1,\"n\":\"Event Data\"},{\"t\":3,\"p\":1,\"n\":\"Faction\"},{\"t\":3,\"p\":1,\"n\":\"Form List\"},{\"t\":3,\"p\":1,\"n\":\"Form Type\"},{\"t\":3,\"p\":1,\"n\":\"Furniture\"},{\"t\":3,\"p\":1,\"n\":\"Furniture Anim\"},{\"t\":3,\"p\":1,\"n\":\"Furniture Entry\"},{\"t\":3,\"p\":1,\"n\":\"Global\"},{\"t\":3,\"p\":1,\"n\":\"Idle\"},{\"t\":3,\"p\":1,\"n\":\"Inventory Object\"},{\"t\":3,\"p\":1,\"n\":\"Keyword\"},{\"t\":3,\"p\":1,\"n\":\"Location\"},{\"t\":3,\"p\":1,\"n\":\"Base Effect\"},{\"t\":3,\"p\":1,\"n\":\"Effect Item\"},{\"t\":3,\"p\":1,\"n\":\"Misc Stat\"},{\"t\":3,\"p\":1,\"n\":\"Object Reference\"},{\"t\":3,\"p\":1,\"n\":\"Owner\"},{\"t\":3,\"p\":1,\"n\":\"Package\"},{\"t\":3,\"p\":1,\"n\":\"Packdata ID\"},{\"t\":3,\"p\":1,\"n\":\"Perk\"},{\"t\":3,\"p\":1,\"n\":\"Quest\"},{\"t\":3,\"p\":1,\"n\":\"Quest Stage\"},{\"t\":3,\"p\":1,\"n\":\"Race\"},{\"t\":3,\"p\":1,\"n\":\"Referenceable Object\"},{\"t\":3,\"p\":1,\"n\":\"Location Ref Type\"},{\"t\":3,\"p\":1,\"n\":\"Region\"},{\"t\":3,\"p\":1,\"n\":\"Scene\"},{\"t\":3,\"p\":1,\"n\":\"Sex\"},{\"t\":3,\"p\":1,\"n\":\"Shout\"},{\"t\":11,\"p\":1,\"n\":\"Variable Name (unused)\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Function\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Param (unused)\"},{\"t\":3,\"p\":1,\"n\":\"Voice Type\"},{\"t\":3,\"p\":1,\"n\":\"Ward State\"},{\"t\":3,\"p\":1,\"n\":\"Weather\"},{\"t\":3,\"p\":1,\"n\":\"Worldspace\"},{\"t\":3,\"p\":1,\"n\":\"Damage Type\"},{\"t\":3,\"p\":1,\"n\":\"Weapon\"},{\"t\":3,\"p\":1,\"n\":\"Weapon List\"},{\"t\":3,\"p\":1,\"n\":\"Target\"},{\"t\":3,\"p\":1,\"n\":\"Target List\"},{\"t\":3,\"p\":1,\"n\":\"Target Part\"},{\"t\":3,\"p\":1,\"n\":\"VATS Action\"},{\"t\":3,\"p\":1,\"n\":\"Critical Effect\"},{\"t\":3,\"p\":1,\"n\":\"Critical Effect List\"},{\"t\":3,\"p\":1,\"n\":\"Weapon Type\"},{\"t\":3,\"p\":1,\"n\":\"Projectile Type\"},{\"t\":3,\"p\":1,\"n\":\"Delivery Type\"},{\"t\":3,\"p\":1,\"n\":\"Run On\"},{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":3,\"p\":1,\"n\":\"Parameter #3\"}]},{\"t\":2,\"p\":1,\"n\":\"CIS1 - Parameter #1\"},{\"t\":2,\"p\":1,\"n\":\"CIS2 - Parameter #2\"}]}]},{\"t\":7,\"p\":1,\"n\":\"SNAM - Tracks\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Track\"}]}]},{\"t\":1,\"n\":\"NAVI - Navigation Mesh Info Map\",\"c\":[{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":3,\"n\":\"NVER - Version\"},{\"t\":8,\"n\":\"Navigation Map Infos\",\"c\":[{\"t\":6,\"n\":\"NVMI - Navigation Map Info\",\"c\":[{\"t\":3,\"n\":\"Navigation Mesh\"},{\"t\":11,\"n\":\"Data\"},{\"t\":7,\"n\":\"Merged To\",\"c\":[{\"t\":3,\"n\":\"Mesh\"}]},{\"t\":7,\"n\":\"Preferred Merges\",\"c\":[{\"t\":3,\"n\":\"Mesh\"}]},{\"t\":7,\"n\":\"Linked Doors\",\"c\":[{\"t\":6,\"n\":\"Door\",\"c\":[{\"t\":11,\"n\":\"Unknown\"},{\"t\":3,\"n\":\"Door Ref\"}]}]},{\"t\":3,\"n\":\"Is Island\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":6,\"n\":\"Island Data\",\"c\":[{\"t\":11,\"n\":\"Unknown\"},{\"t\":7,\"n\":\"Triangles\",\"c\":[{\"t\":11,\"n\":\"Triangle\"}]},{\"t\":7,\"n\":\"Vertices\",\"c\":[{\"t\":11,\"n\":\"Vertex\"}]}]},{\"t\":11,\"n\":\"Unknown\"},{\"t\":3,\"n\":\"Parent Worldspace\"},{\"t\":6,\"n\":\"Coordinates\",\"c\":[{\"t\":3,\"n\":\"Grid Y\"},{\"t\":3,\"n\":\"Grid X\"}]},{\"t\":3,\"n\":\"Parent Cell\"}]}]},{\"t\":6,\"n\":\"NVPP - Preferred Pathing\",\"c\":[{\"t\":7,\"n\":\"NavMeshes\",\"c\":[{\"t\":7,\"n\":\"Set\",\"c\":[{\"t\":3,\"n\":\"\"}]}]},{\"t\":7,\"n\":\"NavMesh Tree?\",\"c\":[{\"t\":6,\"n\":\"\",\"c\":[{\"t\":3,\"n\":\"NavMesh\"},{\"t\":3,\"n\":\"Index\\/Node\"}]}]}]},{\"t\":11,\"n\":\"NVSI - Unknown\"}]},{\"t\":1,\"n\":\"NAVM - Navigation Mesh\",\"c\":[{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"n\":\"NVNM - Navmesh Geometry\",\"c\":[{\"t\":3,\"n\":\"Version\"},{\"t\":11,\"n\":\"Magic\"},{\"t\":3,\"n\":\"Parent Worldspace\"},{\"t\":6,\"n\":\"Coordinates\",\"c\":[{\"t\":3,\"n\":\"Grid Y\"},{\"t\":3,\"n\":\"Grid X\"}]},{\"t\":3,\"n\":\"Parent Cell\"},{\"t\":11,\"n\":\"Vertices and Triangles\"}]},{\"t\":11,\"n\":\"ONAM - Unknown\"},{\"t\":11,\"n\":\"NNAM - Unknown\"},{\"t\":11,\"n\":\"MNAM - Unknown\"}]},{\"t\":1,\"n\":\"NOCM - Navigation Mesh Obstacle Manager\",\"d\":1,\"c\":[{\"t\":8,\"n\":\"Unknown\",\"c\":[{\"t\":6,\"n\":\"Unknown\",\"c\":[{\"t\":3,\"n\":\"INDX - Index\"},{\"t\":8,\"n\":\"Unknown\",\"c\":[{\"t\":11,\"n\":\"DATA - Unknown\"}]},{\"t\":11,\"n\":\"INTV - Unknown\"},{\"t\":2,\"n\":\"NAM1 - Model\"}]}]}]},{\"t\":1,\"p\":1,\"n\":\"NOTE - Note\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"VMAD - Virtual Machine Adapter\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Version\"},{\"t\":3,\"p\":1,\"n\":\"Object Format\"},{\"t\":7,\"p\":1,\"n\":\"Scripts\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Script\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"scriptName\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":7,\"p\":1,\"n\":\"Properties\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Property\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"propertyName\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]},{\"t\":2,\"p\":1,\"n\":\"String\"},{\"t\":3,\"p\":1,\"n\":\"Int32\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":3,\"p\":1,\"n\":\"Bool\"},{\"t\":7,\"p\":1,\"n\":\"Struct\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Member\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"memberName\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]},{\"t\":2,\"p\":1,\"n\":\"String\"},{\"t\":3,\"p\":1,\"n\":\"Int32\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":3,\"p\":1,\"n\":\"Bool\"},{\"t\":7,\"p\":1,\"n\":\"Array of Object\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]}]},{\"t\":7,\"p\":1,\"n\":\"Array of String\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Int32\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Float\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Bool\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]}]}]},{\"t\":7,\"p\":1,\"n\":\"Array of Object\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]}]},{\"t\":7,\"p\":1,\"n\":\"Array of String\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Int32\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Float\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Bool\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Struct\",\"c\":[{\"t\":7,\"p\":1,\"n\":\"Struct\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Member\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"memberName\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]},{\"t\":2,\"p\":1,\"n\":\"String\"},{\"t\":3,\"p\":1,\"n\":\"Int32\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":3,\"p\":1,\"n\":\"Bool\"},{\"t\":7,\"p\":1,\"n\":\"Array of Object\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]}]},{\"t\":7,\"p\":1,\"n\":\"Array of String\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Int32\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Float\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Bool\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]}]}]}]}]}]}]}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"X1\"},{\"t\":3,\"p\":1,\"n\":\"Y1\"},{\"t\":3,\"p\":1,\"n\":\"Z1\"},{\"t\":3,\"p\":1,\"n\":\"X2\"},{\"t\":3,\"p\":1,\"n\":\"Y2\"},{\"t\":3,\"p\":1,\"n\":\"Z2\"}]},{\"t\":3,\"p\":1,\"n\":\"PTRN - Preview Transform\"},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"MODT - Texture Files Hashes\"},{\"t\":3,\"p\":1,\"n\":\"MODS - Material Swap\"},{\"t\":5,\"p\":1,\"n\":\"MODC - Color Remapping Index\"},{\"t\":11,\"n\":\"MODF - Unknown\"}]},{\"t\":2,\"p\":1,\"n\":\"ICON - Inventory Image\"},{\"t\":3,\"p\":1,\"n\":\"YNAM - Sound - Pick Up\"},{\"t\":3,\"p\":1,\"n\":\"ZNAM - Sound - Put Down\"},{\"t\":3,\"p\":1,\"n\":\"DNAM - Type\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DATA - \",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Value\"},{\"t\":5,\"p\":1,\"n\":\"Weight\"}]},{\"t\":11,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Sound\"},{\"t\":3,\"p\":1,\"n\":\"Scene\"},{\"t\":3,\"p\":1,\"n\":\"Terminal\"},{\"t\":2,\"p\":1,\"n\":\"PNAM - Program File\"}]},{\"t\":1,\"p\":1,\"n\":\"NPC_ - Non-Player Character (Actor)\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"VMAD - Virtual Machine Adapter\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Version\"},{\"t\":3,\"p\":1,\"n\":\"Object Format\"},{\"t\":7,\"p\":1,\"n\":\"Scripts\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Script\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"scriptName\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":7,\"p\":1,\"n\":\"Properties\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Property\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"propertyName\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]},{\"t\":2,\"p\":1,\"n\":\"String\"},{\"t\":3,\"p\":1,\"n\":\"Int32\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":3,\"p\":1,\"n\":\"Bool\"},{\"t\":7,\"p\":1,\"n\":\"Struct\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Member\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"memberName\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]},{\"t\":2,\"p\":1,\"n\":\"String\"},{\"t\":3,\"p\":1,\"n\":\"Int32\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":3,\"p\":1,\"n\":\"Bool\"},{\"t\":7,\"p\":1,\"n\":\"Array of Object\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]}]},{\"t\":7,\"p\":1,\"n\":\"Array of String\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Int32\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Float\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Bool\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]}]}]},{\"t\":7,\"p\":1,\"n\":\"Array of Object\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]}]},{\"t\":7,\"p\":1,\"n\":\"Array of String\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Int32\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Float\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Bool\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Struct\",\"c\":[{\"t\":7,\"p\":1,\"n\":\"Struct\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Member\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"memberName\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]},{\"t\":2,\"p\":1,\"n\":\"String\"},{\"t\":3,\"p\":1,\"n\":\"Int32\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":3,\"p\":1,\"n\":\"Bool\"},{\"t\":7,\"p\":1,\"n\":\"Array of Object\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]}]},{\"t\":7,\"p\":1,\"n\":\"Array of String\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Int32\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Float\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Bool\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]}]}]}]}]}]}]}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"X1\"},{\"t\":3,\"p\":1,\"n\":\"Y1\"},{\"t\":3,\"p\":1,\"n\":\"Z1\"},{\"t\":3,\"p\":1,\"n\":\"X2\"},{\"t\":3,\"p\":1,\"n\":\"Y2\"},{\"t\":3,\"p\":1,\"n\":\"Z2\"}]},{\"t\":3,\"p\":1,\"n\":\"PTRN - Preview Transform\"},{\"t\":3,\"n\":\"STCP - Unknown\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"ACBS - Configuration\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":3,\"p\":1,\"n\":\"XP Value Offset\"},{\"t\":3,\"p\":1,\"n\":\"Level\"},{\"t\":3,\"p\":1,\"n\":\"Level Mult\"},{\"t\":3,\"p\":1,\"n\":\"Calc min level\"},{\"t\":3,\"p\":1,\"n\":\"Calc max level\"},{\"t\":3,\"p\":1,\"n\":\"Disposition Base\"},{\"t\":3,\"p\":1,\"n\":\"Use Template Actors\"},{\"t\":3,\"p\":1,\"n\":\"Bleedout Override\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Factions\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"SNAM - Faction\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Faction\"},{\"t\":3,\"p\":1,\"n\":\"Rank\"}]}]},{\"t\":3,\"p\":1,\"n\":\"INAM - Death item\"},{\"t\":3,\"p\":1,\"n\":\"VTCK - Voice\"},{\"t\":3,\"p\":1,\"n\":\"TPLT - Default Template\"},{\"t\":3,\"p\":1,\"n\":\"LTPT - Legendary Template\"},{\"t\":3,\"p\":1,\"n\":\"LTPC - Legendary Chance\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"TPTA - Template Actors\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Traits\"},{\"t\":3,\"p\":1,\"n\":\"Stats\"},{\"t\":3,\"p\":1,\"n\":\"Factions\"},{\"t\":3,\"p\":1,\"n\":\"Spell List\"},{\"t\":3,\"p\":1,\"n\":\"AI Data\"},{\"t\":3,\"p\":1,\"n\":\"AI Packages\"},{\"t\":3,\"p\":1,\"n\":\"Model\\/Animation\"},{\"t\":3,\"p\":1,\"n\":\"Base Data\"},{\"t\":3,\"p\":1,\"n\":\"Inventory\"},{\"t\":3,\"p\":1,\"n\":\"Script\"},{\"t\":3,\"p\":1,\"n\":\"Def Pack List\"},{\"t\":3,\"p\":1,\"n\":\"Attack Data\"},{\"t\":3,\"p\":1,\"n\":\"Keywords\"}]},{\"t\":3,\"p\":1,\"n\":\"RNAM - Race\"},{\"t\":3,\"n\":\"SPCT - Count\"},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Actor Effects\",\"d\":1,\"c\":[{\"t\":3,\"p\":1,\"n\":\"SPLO - Actor Effect\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Destructible\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"DEST - Header\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Health\"},{\"t\":3,\"p\":1,\"n\":\"DEST Count\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":7,\"p\":1,\"n\":\"DAMC - Resistances\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Resistance\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Damage Type\"},{\"t\":3,\"p\":1,\"n\":\"Value\"}]}]},{\"t\":8,\"p\":1,\"n\":\"Stages\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Stage\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"DSTD - Destruction Stage Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Health %\"},{\"t\":3,\"p\":1,\"n\":\"Index\"},{\"t\":3,\"p\":1,\"n\":\"Model Damage Stage\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":3,\"p\":1,\"n\":\"Self Damage per Second\"},{\"t\":3,\"p\":1,\"n\":\"Explosion\"},{\"t\":3,\"p\":1,\"n\":\"Debris\"},{\"t\":3,\"p\":1,\"n\":\"Debris Count\"}]},{\"t\":2,\"p\":1,\"n\":\"DSTA - Sequence Name\"},{\"t\":6,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"DMDL - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"DMDT - Texture Files Hashes\"},{\"t\":5,\"p\":1,\"n\":\"DMDC - Color Remapping Index\"},{\"t\":3,\"p\":1,\"n\":\"DMDS - Material Swap\"}]},{\"p\":1,\"n\":\"DSTF - End Marker\"}]}]}]},{\"t\":3,\"p\":1,\"n\":\"WNAM - Skin\"},{\"t\":3,\"p\":1,\"n\":\"ANAM - Far away model\"},{\"t\":3,\"p\":1,\"n\":\"ATKR - Attack Race\"},{\"t\":10,\"p\":1,\"n\":\"Attacks\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Attack\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"ATKD - Attack Data\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Damage Mult\"},{\"t\":5,\"p\":1,\"n\":\"Attack Chance\"},{\"t\":3,\"p\":1,\"n\":\"Attack Spell\"},{\"t\":3,\"p\":1,\"n\":\"Attack Flags\"},{\"t\":5,\"p\":1,\"n\":\"Attack Angle\"},{\"t\":5,\"p\":1,\"n\":\"Strike Angle\"},{\"t\":5,\"p\":1,\"n\":\"Stagger\"},{\"t\":5,\"p\":1,\"n\":\"Knockdown\"},{\"t\":5,\"p\":1,\"n\":\"Recovery Time\"},{\"t\":5,\"p\":1,\"n\":\"Action Points Mult\"},{\"t\":3,\"p\":1,\"n\":\"Stagger Offset\"}]},{\"t\":2,\"p\":1,\"n\":\"ATKE - Attack Event\"},{\"t\":3,\"p\":1,\"n\":\"ATKW - Weapon Slot\"},{\"t\":3,\"p\":1,\"n\":\"ATKS - Required Slot\"},{\"t\":2,\"p\":1,\"n\":\"ATKT - Description\"}]}]},{\"t\":3,\"p\":1,\"n\":\"SPOR - Spectator Override Package List\"},{\"t\":3,\"p\":1,\"n\":\"OCOR - Observe Dead Body Override Package List\"},{\"t\":3,\"p\":1,\"n\":\"GWOR - Guard Warn Override Package List\"},{\"t\":3,\"p\":1,\"n\":\"ECOR - Combat Override Package List\"},{\"t\":3,\"p\":1,\"n\":\"FCPL - Follower Command Package List\"},{\"t\":3,\"p\":1,\"n\":\"RCLR - Follower Elevator Package List\"},{\"t\":3,\"n\":\"PRKZ - Perk Count\"},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Perks\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"PRKR - Perk\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Perk\"},{\"t\":3,\"p\":1,\"n\":\"Rank\"}]}]},{\"t\":7,\"p\":1,\"n\":\"PRPS - Properties\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Property\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Actor Value\"},{\"t\":5,\"p\":1,\"n\":\"Value\"}]}]},{\"t\":3,\"p\":1,\"n\":\"FTYP - Forced Loc Ref Type\"},{\"t\":3,\"p\":1,\"n\":\"NTRM - Native Terminal\"},{\"t\":3,\"n\":\"COCT - Count\"},{\"t\":10,\"p\":1,\"n\":\"Items\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Item\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"CNTO - Item\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Item\"},{\"t\":3,\"p\":1,\"n\":\"Count\"}]},{\"t\":6,\"p\":1,\"n\":\"COED - Extra Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Owner\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Global Variable\"},{\"t\":3,\"p\":1,\"n\":\"Required Rank\"},{\"t\":5,\"p\":1,\"n\":\"Item Condition\"}]}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"AIDT - AI Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Aggression\"},{\"t\":3,\"p\":1,\"n\":\"Confidence\"},{\"t\":3,\"p\":1,\"n\":\"Energy Level\"},{\"t\":3,\"p\":1,\"n\":\"Responsibility\"},{\"t\":3,\"p\":1,\"n\":\"Mood\"},{\"t\":3,\"p\":1,\"n\":\"Assistance\"},{\"t\":6,\"p\":1,\"n\":\"Aggro\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Aggro Radius Behavior\"},{\"t\":3,\"n\":\"Unknown\"},{\"t\":3,\"p\":1,\"n\":\"Warn\"},{\"t\":3,\"p\":1,\"n\":\"Warn\\/Attack\"},{\"t\":3,\"p\":1,\"n\":\"Attack\"}]},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Packages\",\"d\":1,\"c\":[{\"t\":3,\"p\":1,\"n\":\"PKID - Package\"}]},{\"t\":3,\"n\":\"KSIZ - Keyword Count\"},{\"t\":7,\"p\":1,\"n\":\"KWDA - Keywords\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Keyword\"}]},{\"t\":7,\"p\":1,\"n\":\"APPR - Attach Parent Slots\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Keyword\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Object Template\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"OBTE - Count\"},{\"t\":8,\"p\":1,\"n\":\"Combinations\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Combination\",\"c\":[{\"p\":1,\"n\":\"OBTF - Editor Only\"},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":6,\"p\":1,\"n\":\"OBTS - Object Mod Template Item\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Include Count\"},{\"t\":3,\"p\":1,\"n\":\"Property Count\"},{\"t\":3,\"p\":1,\"n\":\"Level Min\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Level Max\"},{\"t\":3,\"p\":1,\"n\":\"ID\"},{\"t\":3,\"p\":1,\"n\":\"Default\"},{\"t\":7,\"p\":1,\"n\":\"Keywords\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Keyword\"}]},{\"t\":3,\"p\":1,\"n\":\"Min Level For Ranks\"},{\"t\":3,\"p\":1,\"n\":\"Alt Levels Per Tier\"},{\"t\":7,\"p\":1,\"n\":\"Includes\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Include\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Mod\"},{\"t\":3,\"p\":1,\"n\":\"Attach Point Index\"},{\"t\":3,\"p\":1,\"n\":\"Optional\"},{\"t\":3,\"p\":1,\"n\":\"Don't Use All\"}]}]},{\"t\":7,\"p\":1,\"n\":\"Properties\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Property\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Value Type\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Function Type\"},{\"t\":3,\"p\":1,\"n\":\"Property\"},{\"t\":11,\"n\":\"Value 1 - Unknown\"},{\"t\":3,\"p\":1,\"n\":\"Value 1 - Int\"},{\"t\":5,\"p\":1,\"n\":\"Value 1 - Float\"},{\"t\":3,\"p\":1,\"n\":\"Value 1 - Bool\"},{\"t\":3,\"p\":1,\"n\":\"Value 1 - FormID\"},{\"t\":3,\"p\":1,\"n\":\"Value 1 - Enum\"},{\"t\":3,\"p\":1,\"n\":\"Sound Level\"},{\"t\":3,\"p\":1,\"n\":\"Stagger Value\"},{\"t\":3,\"p\":1,\"n\":\"Hit Behaviour\"},{\"t\":3,\"p\":1,\"n\":\"Value 2 - Int\"},{\"t\":5,\"p\":1,\"n\":\"Value 2 - Float\"},{\"t\":3,\"p\":1,\"n\":\"Value 2 - Bool\"},{\"t\":5,\"p\":1,\"n\":\"Step\"}]}]}]}]}]},{\"p\":1,\"n\":\"STOP - Marker\"}]},{\"t\":3,\"p\":1,\"n\":\"CNAM - Class\"},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":2,\"p\":1,\"n\":\"SHRT - Short Name\"},{\"t\":11,\"n\":\"DATA - Marker\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DNAM - \",\"c\":[{\"t\":3,\"n\":\"Unknown\"},{\"t\":3,\"p\":1,\"n\":\"Far Away Model Distance\"},{\"t\":3,\"p\":1,\"n\":\"Geared Up Weapons\"}]},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Head Parts\",\"d\":1,\"c\":[{\"t\":3,\"p\":1,\"n\":\"PNAM - Head Part\"}]},{\"t\":3,\"p\":1,\"n\":\"HCLF - Hair Color\"},{\"t\":3,\"p\":1,\"n\":\"BCLF - Facial Hair Color\"},{\"t\":3,\"p\":1,\"n\":\"ZNAM - Combat Style\"},{\"t\":3,\"p\":1,\"n\":\"GNAM - Gift Filter\"},{\"t\":11,\"n\":\"NAM5 - Unknown\"},{\"t\":5,\"p\":1,\"n\":\"NAM6 - Height Min\"},{\"t\":5,\"n\":\"NAM7 - Unused\"},{\"t\":5,\"p\":1,\"n\":\"NAM4 - Height Max\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"MWGT - Weight\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Thin\"},{\"t\":5,\"p\":1,\"n\":\"Muscular\"},{\"t\":5,\"p\":1,\"n\":\"Fat\"}]},{\"t\":3,\"p\":1,\"n\":\"NAM8 - Sound Level\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Actor Sounds\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"CS2H - Count\"},{\"t\":10,\"p\":1,\"n\":\"Sounds\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Sound\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"CS2K - Keyword\"},{\"t\":3,\"p\":1,\"n\":\"CS2D - Sound\"}]}]},{\"p\":1,\"n\":\"CS2E - End Marker\"},{\"t\":11,\"p\":1,\"n\":\"CS2F - Finalize\"}]},{\"t\":3,\"p\":1,\"n\":\"CSCR - Inherits Sounds From\"},{\"t\":3,\"p\":1,\"n\":\"PFRN - Power Armor Stand\"},{\"t\":3,\"p\":1,\"n\":\"DOFT - Default Outfit\"},{\"t\":3,\"p\":1,\"n\":\"SOFT - Sleeping Outfit\"},{\"t\":3,\"p\":1,\"n\":\"DPLT - Default Package List\"},{\"t\":3,\"p\":1,\"n\":\"CRIF - Crime Faction\"},{\"t\":3,\"p\":1,\"n\":\"FTST - Head Texture\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"QNAM - Texture lighting\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Red\"},{\"t\":5,\"p\":1,\"n\":\"Green\"},{\"t\":5,\"p\":1,\"n\":\"Blue\"},{\"t\":5,\"p\":1,\"n\":\"Alpha\"}]},{\"t\":7,\"p\":1,\"n\":\"MSDK - Morph Keys\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Key\"}]},{\"t\":7,\"p\":1,\"n\":\"MSDV - Morph Values\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Value\"}]},{\"t\":10,\"p\":1,\"n\":\"Face Tinting Layers\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Layer\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"TETI - Index\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Data Type\"},{\"t\":3,\"p\":1,\"n\":\"Index\"}]},{\"t\":6,\"p\":1,\"n\":\"TEND - Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Value\"},{\"t\":6,\"p\":1,\"n\":\"Color\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":3,\"p\":1,\"n\":\"Template Color Index\"}]}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"MRSV - Body Morph Region Values\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Head\"},{\"t\":5,\"p\":1,\"n\":\"Upper Torso\"},{\"t\":5,\"p\":1,\"n\":\"Arms\"},{\"t\":5,\"p\":1,\"n\":\"Lower Torso\"},{\"t\":5,\"p\":1,\"n\":\"Legs\"}]},{\"t\":10,\"p\":1,\"n\":\"Face Morphs\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Face Morph\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FMRI - Index\"},{\"t\":6,\"p\":1,\"n\":\"FMRS - Values\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Position - X\"},{\"t\":5,\"p\":1,\"n\":\"Position - Y\"},{\"t\":5,\"p\":1,\"n\":\"Position - Z\"},{\"t\":5,\"p\":1,\"n\":\"Rotation - X\"},{\"t\":5,\"p\":1,\"n\":\"Rotation - Y\"},{\"t\":5,\"p\":1,\"n\":\"Rotation - Z\"},{\"t\":5,\"p\":1,\"n\":\"Scale\"},{\"t\":11,\"n\":\"Unknown\"}]}]}]},{\"t\":5,\"p\":1,\"n\":\"FMIN - Facial Morph Intensity\"},{\"t\":2,\"p\":1,\"n\":\"ATTX - Activate Text Override\"}]},{\"t\":1,\"p\":1,\"n\":\"OMOD - Object Modification\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":2,\"p\":1,\"n\":\"DESC - Description\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"MODT - Texture Files Hashes\"},{\"t\":3,\"p\":1,\"n\":\"MODS - Material Swap\"},{\"t\":5,\"p\":1,\"n\":\"MODC - Color Remapping Index\"},{\"t\":11,\"n\":\"MODF - Unknown\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DATA - Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Include Count\"},{\"t\":3,\"p\":1,\"n\":\"Property Count\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Form Type\"},{\"t\":3,\"p\":1,\"n\":\"Attach Point\"},{\"t\":7,\"p\":1,\"n\":\"Attach Parent Slots\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Keyword\"}]},{\"t\":7,\"p\":1,\"n\":\"Items\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Item\",\"c\":[{\"t\":11,\"p\":1,\"n\":\"Value 1\"},{\"t\":11,\"p\":1,\"n\":\"Value 2\"}]}]},{\"t\":7,\"p\":1,\"n\":\"Includes\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Include\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Mod\"},{\"t\":3,\"p\":1,\"n\":\"Minimum Level\"},{\"t\":3,\"p\":1,\"n\":\"Optional\"},{\"t\":3,\"p\":1,\"n\":\"Don't Use All\"}]}]},{\"t\":7,\"p\":1,\"n\":\"Properties\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Property\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Value Type\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Function Type\"},{\"t\":3,\"p\":1,\"n\":\"Property\"},{\"t\":11,\"n\":\"Value 1 - Unknown\"},{\"t\":3,\"p\":1,\"n\":\"Value 1 - Int\"},{\"t\":5,\"p\":1,\"n\":\"Value 1 - Float\"},{\"t\":3,\"p\":1,\"n\":\"Value 1 - Bool\"},{\"t\":3,\"p\":1,\"n\":\"Value 1 - FormID\"},{\"t\":3,\"p\":1,\"n\":\"Value 1 - Enum\"},{\"t\":3,\"p\":1,\"n\":\"Sound Level\"},{\"t\":3,\"p\":1,\"n\":\"Stagger Value\"},{\"t\":3,\"p\":1,\"n\":\"Hit Behaviour\"},{\"t\":3,\"p\":1,\"n\":\"Value 2 - Int\"},{\"t\":5,\"p\":1,\"n\":\"Value 2 - Float\"},{\"t\":3,\"p\":1,\"n\":\"Value 2 - Bool\"},{\"t\":5,\"p\":1,\"n\":\"Step\"}]}]}]},{\"t\":7,\"p\":1,\"n\":\"MNAM - Target OMOD Keywords\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Keyword\"}]},{\"t\":7,\"p\":1,\"n\":\"FNAM - Filter Keywords\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Keyword\"}]},{\"t\":3,\"p\":1,\"n\":\"LNAM - Loose Mod\"},{\"t\":3,\"p\":1,\"n\":\"NAM1 - Priority\"},{\"t\":2,\"p\":1,\"n\":\"FLTR - Filter\"}]},{\"t\":1,\"p\":1,\"n\":\"OTFT - Outfit\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":7,\"p\":1,\"n\":\"INAM - Items\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Item\"}]}]},{\"t\":1,\"n\":\"OVIS - Object Visibility Manager\",\"d\":1,\"c\":[{\"t\":8,\"n\":\"Unknown\",\"c\":[{\"t\":6,\"n\":\"Unknown\",\"c\":[{\"t\":3,\"n\":\"INDX - Object\"},{\"t\":6,\"n\":\"DATA - Object Bounds\",\"c\":[{\"t\":5,\"n\":\"X1\"},{\"t\":5,\"n\":\"Y1\"},{\"t\":5,\"n\":\"Z1\"},{\"t\":5,\"n\":\"X2\"},{\"t\":5,\"n\":\"Y2\"},{\"t\":5,\"n\":\"Z2\"}]}]}]}]},{\"t\":1,\"p\":1,\"n\":\"PACK - Package\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"VMAD - Virtual Machine Adapter\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Version\"},{\"t\":3,\"p\":1,\"n\":\"Object Format\"},{\"t\":7,\"p\":1,\"n\":\"Scripts\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Script\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"scriptName\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":7,\"p\":1,\"n\":\"Properties\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Property\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"propertyName\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]},{\"t\":2,\"p\":1,\"n\":\"String\"},{\"t\":3,\"p\":1,\"n\":\"Int32\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":3,\"p\":1,\"n\":\"Bool\"},{\"t\":7,\"p\":1,\"n\":\"Struct\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Member\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"memberName\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]},{\"t\":2,\"p\":1,\"n\":\"String\"},{\"t\":3,\"p\":1,\"n\":\"Int32\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":3,\"p\":1,\"n\":\"Bool\"},{\"t\":7,\"p\":1,\"n\":\"Array of Object\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]}]},{\"t\":7,\"p\":1,\"n\":\"Array of String\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Int32\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Float\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Bool\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]}]}]},{\"t\":7,\"p\":1,\"n\":\"Array of Object\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]}]},{\"t\":7,\"p\":1,\"n\":\"Array of String\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Int32\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Float\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Bool\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Struct\",\"c\":[{\"t\":7,\"p\":1,\"n\":\"Struct\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Member\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"memberName\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]},{\"t\":2,\"p\":1,\"n\":\"String\"},{\"t\":3,\"p\":1,\"n\":\"Int32\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":3,\"p\":1,\"n\":\"Bool\"},{\"t\":7,\"p\":1,\"n\":\"Array of Object\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]}]},{\"t\":7,\"p\":1,\"n\":\"Array of String\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Int32\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Float\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Bool\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]}]}]}]}]}]}]}]},{\"t\":6,\"p\":1,\"n\":\"Script Fragments\",\"c\":[{\"t\":3,\"n\":\"Unknown\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":6,\"p\":1,\"n\":\"Script\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"scriptName\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":7,\"p\":1,\"n\":\"Properties\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Property\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"propertyName\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]},{\"t\":2,\"p\":1,\"n\":\"String\"},{\"t\":3,\"p\":1,\"n\":\"Int32\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":3,\"p\":1,\"n\":\"Bool\"},{\"t\":7,\"p\":1,\"n\":\"Struct\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Member\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"memberName\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]},{\"t\":2,\"p\":1,\"n\":\"String\"},{\"t\":3,\"p\":1,\"n\":\"Int32\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":3,\"p\":1,\"n\":\"Bool\"},{\"t\":7,\"p\":1,\"n\":\"Array of Object\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]}]},{\"t\":7,\"p\":1,\"n\":\"Array of String\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Int32\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Float\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Bool\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]}]}]},{\"t\":7,\"p\":1,\"n\":\"Array of Object\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]}]},{\"t\":7,\"p\":1,\"n\":\"Array of String\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Int32\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Float\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Bool\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Struct\",\"c\":[{\"t\":7,\"p\":1,\"n\":\"Struct\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Member\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"memberName\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]},{\"t\":2,\"p\":1,\"n\":\"String\"},{\"t\":3,\"p\":1,\"n\":\"Int32\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":3,\"p\":1,\"n\":\"Bool\"},{\"t\":7,\"p\":1,\"n\":\"Array of Object\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]}]},{\"t\":7,\"p\":1,\"n\":\"Array of String\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Int32\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Float\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Bool\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]}]}]}]}]}]}]},{\"t\":7,\"p\":1,\"n\":\"Fragments\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Fragment\",\"c\":[{\"t\":3,\"n\":\"Unknown\"},{\"t\":2,\"p\":1,\"n\":\"scriptName\"},{\"t\":2,\"p\":1,\"n\":\"fragmentName\"}]}]}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"PKDT - Pack Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"General Flags\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Interrupt Override\"},{\"t\":3,\"p\":1,\"n\":\"Preferred Speed\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":3,\"p\":1,\"n\":\"Interrupt Flags\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"PSDT - Schedule\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Month\"},{\"t\":3,\"p\":1,\"n\":\"Day of week\"},{\"t\":3,\"p\":1,\"n\":\"Date\"},{\"t\":3,\"p\":1,\"n\":\"Hour\"},{\"t\":3,\"p\":1,\"n\":\"Minute\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Duration (minutes)\"}]},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Conditions\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Condition\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"CTDA - \",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":5,\"p\":1,\"n\":\"Comparison Value - Float\"},{\"t\":3,\"p\":1,\"n\":\"Comparison Value - Global\"},{\"t\":3,\"p\":1,\"n\":\"Function\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":11,\"p\":1,\"n\":\"None\"},{\"t\":3,\"p\":1,\"n\":\"Integer\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":3,\"p\":1,\"n\":\"Actor\"},{\"t\":3,\"p\":1,\"n\":\"Actor Base\"},{\"t\":3,\"p\":1,\"n\":\"Actor Value\"},{\"t\":3,\"p\":1,\"n\":\"Player Action\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"Alignment\"},{\"t\":3,\"p\":1,\"n\":\"Association Type\"},{\"t\":3,\"p\":1,\"n\":\"Axis\"},{\"t\":3,\"p\":1,\"n\":\"Casting Type\"},{\"t\":3,\"p\":1,\"n\":\"Cell\"},{\"t\":3,\"p\":1,\"n\":\"Class\"},{\"t\":3,\"p\":1,\"n\":\"Crime Type\"},{\"t\":3,\"p\":1,\"n\":\"Critical Stage\"},{\"t\":3,\"p\":1,\"n\":\"Encounter Zone\"},{\"t\":3,\"p\":1,\"n\":\"Equip Type\"},{\"t\":3,\"p\":1,\"n\":\"Event\"},{\"t\":3,\"p\":1,\"n\":\"Event Data\"},{\"t\":3,\"p\":1,\"n\":\"Faction\"},{\"t\":3,\"p\":1,\"n\":\"Form List\"},{\"t\":3,\"p\":1,\"n\":\"Form Type\"},{\"t\":3,\"p\":1,\"n\":\"Furniture\"},{\"t\":3,\"p\":1,\"n\":\"Furniture Anim\"},{\"t\":3,\"p\":1,\"n\":\"Furniture Entry\"},{\"t\":3,\"p\":1,\"n\":\"Global\"},{\"t\":3,\"p\":1,\"n\":\"Idle\"},{\"t\":3,\"p\":1,\"n\":\"Inventory Object\"},{\"t\":3,\"p\":1,\"n\":\"Keyword\"},{\"t\":3,\"p\":1,\"n\":\"Location\"},{\"t\":3,\"p\":1,\"n\":\"Base Effect\"},{\"t\":3,\"p\":1,\"n\":\"Effect Item\"},{\"t\":3,\"p\":1,\"n\":\"Misc Stat\"},{\"t\":3,\"p\":1,\"n\":\"Object Reference\"},{\"t\":3,\"p\":1,\"n\":\"Owner\"},{\"t\":3,\"p\":1,\"n\":\"Package\"},{\"t\":3,\"p\":1,\"n\":\"Packdata ID\"},{\"t\":3,\"p\":1,\"n\":\"Perk\"},{\"t\":3,\"p\":1,\"n\":\"Quest\"},{\"t\":3,\"p\":1,\"n\":\"Quest Stage\"},{\"t\":3,\"p\":1,\"n\":\"Race\"},{\"t\":3,\"p\":1,\"n\":\"Referenceable Object\"},{\"t\":3,\"p\":1,\"n\":\"Location Ref Type\"},{\"t\":3,\"p\":1,\"n\":\"Region\"},{\"t\":3,\"p\":1,\"n\":\"Scene\"},{\"t\":3,\"p\":1,\"n\":\"Sex\"},{\"t\":3,\"p\":1,\"n\":\"Shout\"},{\"t\":11,\"p\":1,\"n\":\"Variable Name (unused)\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Function\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Param (unused)\"},{\"t\":3,\"p\":1,\"n\":\"Voice Type\"},{\"t\":3,\"p\":1,\"n\":\"Ward State\"},{\"t\":3,\"p\":1,\"n\":\"Weather\"},{\"t\":3,\"p\":1,\"n\":\"Worldspace\"},{\"t\":3,\"p\":1,\"n\":\"Damage Type\"},{\"t\":3,\"p\":1,\"n\":\"Weapon\"},{\"t\":3,\"p\":1,\"n\":\"Weapon List\"},{\"t\":3,\"p\":1,\"n\":\"Target\"},{\"t\":3,\"p\":1,\"n\":\"Target List\"},{\"t\":3,\"p\":1,\"n\":\"Target Part\"},{\"t\":3,\"p\":1,\"n\":\"VATS Action\"},{\"t\":3,\"p\":1,\"n\":\"Critical Effect\"},{\"t\":3,\"p\":1,\"n\":\"Critical Effect List\"},{\"t\":3,\"p\":1,\"n\":\"Weapon Type\"},{\"t\":3,\"p\":1,\"n\":\"Projectile Type\"},{\"t\":3,\"p\":1,\"n\":\"Delivery Type\"},{\"t\":3,\"p\":1,\"n\":\"Run On\"},{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":3,\"p\":1,\"n\":\"Parameter #3\"}]},{\"t\":2,\"p\":1,\"n\":\"CIS1 - Parameter #1\"},{\"t\":2,\"p\":1,\"n\":\"CIS2 - Parameter #2\"}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Idle Animations\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"IDLF - Flags\"},{\"t\":3,\"p\":1,\"n\":\"IDLC - Animation Count\"},{\"t\":5,\"p\":1,\"n\":\"IDLT - Idle Timer Setting\"},{\"t\":7,\"p\":1,\"n\":\"IDLA - Animations\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Animation\"}]},{\"t\":11,\"n\":\"IDLB - Unknown\"}]},{\"t\":3,\"p\":1,\"n\":\"CNAM - Combat Style\"},{\"t\":3,\"p\":1,\"n\":\"QNAM - Owner Quest\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"PKCU - Counter\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Data Input Count\"},{\"t\":3,\"p\":1,\"n\":\"Package Template\"},{\"t\":3,\"p\":1,\"n\":\"Version Counter (autoincremented)\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Package Data\",\"c\":[{\"t\":8,\"p\":1,\"n\":\"Data Input Values\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Value\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"ANAM - Type\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":3,\"p\":1,\"n\":\"Bool\"},{\"t\":3,\"p\":1,\"n\":\"Integer\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":11,\"n\":\"BNAM - Unknown\"},{\"t\":8,\"p\":1,\"n\":\"Topic\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"PDTO - Topic Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Topic\"},{\"t\":2,\"p\":1,\"n\":\"Subtype\"}]}]},{\"t\":6,\"p\":1,\"n\":\"PLDT - Location\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":3,\"p\":1,\"n\":\"Cell\"},{\"t\":11,\"p\":1,\"n\":\"Near Package Start Location\"},{\"t\":11,\"p\":1,\"n\":\"Near Editor Location\"},{\"t\":3,\"p\":1,\"n\":\"Object ID\"},{\"t\":3,\"p\":1,\"n\":\"Object Type\"},{\"t\":3,\"p\":1,\"n\":\"Keyword\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Ref Alias\"},{\"t\":3,\"p\":1,\"n\":\"Loc Alias\"},{\"t\":3,\"p\":1,\"n\":\"Interrupt Data\"},{\"t\":3,\"p\":1,\"n\":\"Packdata Target\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":3,\"p\":1,\"n\":\"Ref Collection Alias\"},{\"t\":3,\"p\":1,\"n\":\"Radius\"},{\"t\":3,\"p\":1,\"n\":\"Collection Index\"}]},{\"t\":6,\"p\":1,\"n\":\"PTDA - Target\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Target Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":3,\"p\":1,\"n\":\"Object ID\"},{\"t\":3,\"p\":1,\"n\":\"Object Type\"},{\"t\":3,\"p\":1,\"n\":\"Keyword\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"Interrupt Data\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":3,\"p\":1,\"n\":\"Count \\/ Distance\"}]}]},{\"t\":11,\"n\":\"TPIC - Unknown\"}]}]},{\"t\":8,\"p\":1,\"n\":\"Data Inputs\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Data Input\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"UNAM - Index\"},{\"t\":2,\"p\":1,\"n\":\"BNAM - Name\"},{\"t\":3,\"p\":1,\"n\":\"PNAM - Flags\"}]}]}]},{\"t\":11,\"n\":\"XNAM - Marker\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Procedure Tree\",\"c\":[{\"t\":8,\"p\":1,\"n\":\"Branches\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Branch\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"ANAM - Branch Type\"},{\"t\":3,\"p\":1,\"n\":\"CITC - Condition Count\"},{\"t\":8,\"p\":1,\"n\":\"Conditions\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Condition\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"CTDA - \",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":5,\"p\":1,\"n\":\"Comparison Value - Float\"},{\"t\":3,\"p\":1,\"n\":\"Comparison Value - Global\"},{\"t\":3,\"p\":1,\"n\":\"Function\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":11,\"p\":1,\"n\":\"None\"},{\"t\":3,\"p\":1,\"n\":\"Integer\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":3,\"p\":1,\"n\":\"Actor\"},{\"t\":3,\"p\":1,\"n\":\"Actor Base\"},{\"t\":3,\"p\":1,\"n\":\"Actor Value\"},{\"t\":3,\"p\":1,\"n\":\"Player Action\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"Alignment\"},{\"t\":3,\"p\":1,\"n\":\"Association Type\"},{\"t\":3,\"p\":1,\"n\":\"Axis\"},{\"t\":3,\"p\":1,\"n\":\"Casting Type\"},{\"t\":3,\"p\":1,\"n\":\"Cell\"},{\"t\":3,\"p\":1,\"n\":\"Class\"},{\"t\":3,\"p\":1,\"n\":\"Crime Type\"},{\"t\":3,\"p\":1,\"n\":\"Critical Stage\"},{\"t\":3,\"p\":1,\"n\":\"Encounter Zone\"},{\"t\":3,\"p\":1,\"n\":\"Equip Type\"},{\"t\":3,\"p\":1,\"n\":\"Event\"},{\"t\":3,\"p\":1,\"n\":\"Event Data\"},{\"t\":3,\"p\":1,\"n\":\"Faction\"},{\"t\":3,\"p\":1,\"n\":\"Form List\"},{\"t\":3,\"p\":1,\"n\":\"Form Type\"},{\"t\":3,\"p\":1,\"n\":\"Furniture\"},{\"t\":3,\"p\":1,\"n\":\"Furniture Anim\"},{\"t\":3,\"p\":1,\"n\":\"Furniture Entry\"},{\"t\":3,\"p\":1,\"n\":\"Global\"},{\"t\":3,\"p\":1,\"n\":\"Idle\"},{\"t\":3,\"p\":1,\"n\":\"Inventory Object\"},{\"t\":3,\"p\":1,\"n\":\"Keyword\"},{\"t\":3,\"p\":1,\"n\":\"Location\"},{\"t\":3,\"p\":1,\"n\":\"Base Effect\"},{\"t\":3,\"p\":1,\"n\":\"Effect Item\"},{\"t\":3,\"p\":1,\"n\":\"Misc Stat\"},{\"t\":3,\"p\":1,\"n\":\"Object Reference\"},{\"t\":3,\"p\":1,\"n\":\"Owner\"},{\"t\":3,\"p\":1,\"n\":\"Package\"},{\"t\":3,\"p\":1,\"n\":\"Packdata ID\"},{\"t\":3,\"p\":1,\"n\":\"Perk\"},{\"t\":3,\"p\":1,\"n\":\"Quest\"},{\"t\":3,\"p\":1,\"n\":\"Quest Stage\"},{\"t\":3,\"p\":1,\"n\":\"Race\"},{\"t\":3,\"p\":1,\"n\":\"Referenceable Object\"},{\"t\":3,\"p\":1,\"n\":\"Location Ref Type\"},{\"t\":3,\"p\":1,\"n\":\"Region\"},{\"t\":3,\"p\":1,\"n\":\"Scene\"},{\"t\":3,\"p\":1,\"n\":\"Sex\"},{\"t\":3,\"p\":1,\"n\":\"Shout\"},{\"t\":11,\"p\":1,\"n\":\"Variable Name (unused)\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Function\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Param (unused)\"},{\"t\":3,\"p\":1,\"n\":\"Voice Type\"},{\"t\":3,\"p\":1,\"n\":\"Ward State\"},{\"t\":3,\"p\":1,\"n\":\"Weather\"},{\"t\":3,\"p\":1,\"n\":\"Worldspace\"},{\"t\":3,\"p\":1,\"n\":\"Damage Type\"},{\"t\":3,\"p\":1,\"n\":\"Weapon\"},{\"t\":3,\"p\":1,\"n\":\"Weapon List\"},{\"t\":3,\"p\":1,\"n\":\"Target\"},{\"t\":3,\"p\":1,\"n\":\"Target List\"},{\"t\":3,\"p\":1,\"n\":\"Target Part\"},{\"t\":3,\"p\":1,\"n\":\"VATS Action\"},{\"t\":3,\"p\":1,\"n\":\"Critical Effect\"},{\"t\":3,\"p\":1,\"n\":\"Critical Effect List\"},{\"t\":3,\"p\":1,\"n\":\"Weapon Type\"},{\"t\":3,\"p\":1,\"n\":\"Projectile Type\"},{\"t\":3,\"p\":1,\"n\":\"Delivery Type\"},{\"t\":3,\"p\":1,\"n\":\"Run On\"},{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":3,\"p\":1,\"n\":\"Parameter #3\"}]},{\"t\":2,\"p\":1,\"n\":\"CIS1 - Parameter #1\"},{\"t\":2,\"p\":1,\"n\":\"CIS2 - Parameter #2\"}]}]},{\"t\":6,\"p\":1,\"n\":\"PRCB - Root\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Branch Count\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"}]},{\"t\":2,\"p\":1,\"n\":\"PNAM - Procedure Type\"},{\"t\":3,\"p\":1,\"n\":\"FNAM - Flags\"},{\"t\":8,\"p\":1,\"n\":\"Data Input Indexes\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"PKC2 - Index\"}]},{\"t\":8,\"p\":1,\"n\":\"Flags Override\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"PFO2 - Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Set General Flags\"},{\"t\":3,\"p\":1,\"n\":\"Clear General Flags\"},{\"t\":3,\"p\":1,\"n\":\"Set Interrupt Flags\"},{\"t\":3,\"p\":1,\"n\":\"Clear Interrupt Flags\"},{\"t\":3,\"p\":1,\"n\":\"Preferred Speed Override\"},{\"t\":11,\"n\":\"Unknown\"}]}]},{\"t\":8,\"n\":\"Unknown\",\"c\":[{\"t\":11,\"n\":\"PFOR - Unknown\"}]}]}]}]},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Data Inputs\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Data Input\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"UNAM - Index\"},{\"t\":2,\"p\":1,\"n\":\"BNAM - Name\"},{\"t\":3,\"p\":1,\"n\":\"PNAM - Flags\"}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"OnBegin\",\"c\":[{\"p\":1,\"n\":\"POBA - OnBegin Marker\"},{\"t\":3,\"p\":1,\"n\":\"INAM - Idle\"},{\"t\":8,\"p\":1,\"n\":\"Topic\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"PDTO - Topic Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Topic\"},{\"t\":2,\"p\":1,\"n\":\"Subtype\"}]}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"OnEnd\",\"c\":[{\"p\":1,\"n\":\"POEA - OnEnd Marker\"},{\"t\":3,\"p\":1,\"n\":\"INAM - Idle\"},{\"t\":8,\"p\":1,\"n\":\"Topic\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"PDTO - Topic Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Topic\"},{\"t\":2,\"p\":1,\"n\":\"Subtype\"}]}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"OnChange\",\"c\":[{\"p\":1,\"n\":\"POCA - OnChange Marker\"},{\"t\":3,\"p\":1,\"n\":\"INAM - Idle\"},{\"t\":8,\"p\":1,\"n\":\"Topic\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"PDTO - Topic Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Topic\"},{\"t\":2,\"p\":1,\"n\":\"Subtype\"}]}]}]}]},{\"t\":1,\"p\":1,\"n\":\"PARW - Placed Arrow\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"VMAD - Virtual Machine Adapter\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Version\"},{\"t\":3,\"p\":1,\"n\":\"Object Format\"},{\"t\":7,\"p\":1,\"n\":\"Scripts\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Script\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"scriptName\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":7,\"p\":1,\"n\":\"Properties\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Property\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"propertyName\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]},{\"t\":2,\"p\":1,\"n\":\"String\"},{\"t\":3,\"p\":1,\"n\":\"Int32\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":3,\"p\":1,\"n\":\"Bool\"},{\"t\":7,\"p\":1,\"n\":\"Struct\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Member\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"memberName\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]},{\"t\":2,\"p\":1,\"n\":\"String\"},{\"t\":3,\"p\":1,\"n\":\"Int32\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":3,\"p\":1,\"n\":\"Bool\"},{\"t\":7,\"p\":1,\"n\":\"Array of Object\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]}]},{\"t\":7,\"p\":1,\"n\":\"Array of String\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Int32\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Float\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Bool\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]}]}]},{\"t\":7,\"p\":1,\"n\":\"Array of Object\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]}]},{\"t\":7,\"p\":1,\"n\":\"Array of String\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Int32\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Float\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Bool\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Struct\",\"c\":[{\"t\":7,\"p\":1,\"n\":\"Struct\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Member\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"memberName\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]},{\"t\":2,\"p\":1,\"n\":\"String\"},{\"t\":3,\"p\":1,\"n\":\"Int32\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":3,\"p\":1,\"n\":\"Bool\"},{\"t\":7,\"p\":1,\"n\":\"Array of Object\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]}]},{\"t\":7,\"p\":1,\"n\":\"Array of String\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Int32\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Float\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Bool\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]}]}]}]}]}]}]}]}]},{\"t\":3,\"p\":1,\"n\":\"NAME - Projectile\"},{\"t\":3,\"p\":1,\"n\":\"XEZN - Encounter Zone\"},{\"t\":5,\"p\":1,\"n\":\"XHTW - Head-Tracking Weight\"},{\"t\":5,\"p\":1,\"n\":\"XFVC - Favor Cost\"},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Reflected\\/Refracted By\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"XPWR - Water\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":3,\"p\":1,\"n\":\"Type\"}]}]},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Linked References\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"XLKR - Linked Reference\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Keyword\\/Ref\"},{\"t\":3,\"p\":1,\"n\":\"Ref\"}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Activate Parents\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"XAPD - Flags\"},{\"t\":8,\"p\":1,\"n\":\"Activate Parent Refs\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"XAPR - Activate Parent Ref\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":5,\"p\":1,\"n\":\"Delay\"}]}]}]},{\"t\":3,\"n\":\"XASP - Unknown\"},{\"t\":11,\"n\":\"XATP - Unknown\"},{\"t\":3,\"p\":1,\"n\":\"XAMC - Ammo Count\"},{\"p\":1,\"n\":\"XLKT - Linked Ref Transient\"},{\"t\":3,\"p\":1,\"n\":\"XLYR - Layer\"},{\"t\":3,\"p\":1,\"n\":\"XMSP - Material Swap\"},{\"t\":3,\"p\":1,\"n\":\"XRFG - Reference Group\"},{\"t\":11,\"n\":\"XCVR - Unknown\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"XESP - Enable Parent\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"XOWN - Owner\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Owner\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"}]},{\"t\":3,\"p\":1,\"n\":\"XRNK - Owner Faction Rank\"},{\"t\":3,\"p\":1,\"n\":\"XEMI - Emittance\"},{\"t\":3,\"p\":1,\"n\":\"XMBR - MultiBound Reference\"},{\"p\":1,\"n\":\"XIS2 - Ignored by Sandbox\"},{\"t\":7,\"p\":1,\"n\":\"XLRT - Location Ref Type\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Ref\"}]},{\"t\":3,\"p\":1,\"n\":\"XLRL - Location Reference\"},{\"t\":5,\"p\":1,\"n\":\"XSCL - Scale\"},{\"t\":7,\"n\":\"XLOD - Distant LOD Data\",\"c\":[{\"t\":5,\"n\":\"Unknown\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DATA - Position\\/Rotation\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Position\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"X\"},{\"t\":5,\"p\":1,\"n\":\"Y\"},{\"t\":5,\"p\":1,\"n\":\"Z\"}]},{\"t\":6,\"p\":1,\"n\":\"Rotation\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"X\"},{\"t\":5,\"p\":1,\"n\":\"Y\"},{\"t\":5,\"p\":1,\"n\":\"Z\"}]}]},{\"t\":2,\"p\":1,\"n\":\"MNAM - Comments\"}]},{\"t\":1,\"p\":1,\"n\":\"PBAR - Placed Barrier\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"VMAD - Virtual Machine Adapter\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Version\"},{\"t\":3,\"p\":1,\"n\":\"Object Format\"},{\"t\":7,\"p\":1,\"n\":\"Scripts\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Script\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"scriptName\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":7,\"p\":1,\"n\":\"Properties\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Property\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"propertyName\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]},{\"t\":2,\"p\":1,\"n\":\"String\"},{\"t\":3,\"p\":1,\"n\":\"Int32\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":3,\"p\":1,\"n\":\"Bool\"},{\"t\":7,\"p\":1,\"n\":\"Struct\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Member\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"memberName\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]},{\"t\":2,\"p\":1,\"n\":\"String\"},{\"t\":3,\"p\":1,\"n\":\"Int32\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":3,\"p\":1,\"n\":\"Bool\"},{\"t\":7,\"p\":1,\"n\":\"Array of Object\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]}]},{\"t\":7,\"p\":1,\"n\":\"Array of String\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Int32\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Float\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Bool\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]}]}]},{\"t\":7,\"p\":1,\"n\":\"Array of Object\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]}]},{\"t\":7,\"p\":1,\"n\":\"Array of String\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Int32\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Float\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Bool\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Struct\",\"c\":[{\"t\":7,\"p\":1,\"n\":\"Struct\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Member\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"memberName\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]},{\"t\":2,\"p\":1,\"n\":\"String\"},{\"t\":3,\"p\":1,\"n\":\"Int32\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":3,\"p\":1,\"n\":\"Bool\"},{\"t\":7,\"p\":1,\"n\":\"Array of Object\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]}]},{\"t\":7,\"p\":1,\"n\":\"Array of String\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Int32\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Float\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Bool\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]}]}]}]}]}]}]}]}]},{\"t\":3,\"p\":1,\"n\":\"NAME - Projectile\"},{\"t\":3,\"p\":1,\"n\":\"XEZN - Encounter Zone\"},{\"t\":5,\"p\":1,\"n\":\"XHTW - Head-Tracking Weight\"},{\"t\":5,\"p\":1,\"n\":\"XFVC - Favor Cost\"},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Reflected\\/Refracted By\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"XPWR - Water\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":3,\"p\":1,\"n\":\"Type\"}]}]},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Linked References\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"XLKR - Linked Reference\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Keyword\\/Ref\"},{\"t\":3,\"p\":1,\"n\":\"Ref\"}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Activate Parents\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"XAPD - Flags\"},{\"t\":8,\"p\":1,\"n\":\"Activate Parent Refs\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"XAPR - Activate Parent Ref\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":5,\"p\":1,\"n\":\"Delay\"}]}]}]},{\"t\":3,\"n\":\"XASP - Unknown\"},{\"t\":11,\"n\":\"XATP - Unknown\"},{\"t\":3,\"p\":1,\"n\":\"XAMC - Ammo Count\"},{\"p\":1,\"n\":\"XLKT - Linked Ref Transient\"},{\"t\":3,\"p\":1,\"n\":\"XLYR - Layer\"},{\"t\":3,\"p\":1,\"n\":\"XMSP - Material Swap\"},{\"t\":3,\"p\":1,\"n\":\"XRFG - Reference Group\"},{\"t\":11,\"n\":\"XCVR - Unknown\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"XESP - Enable Parent\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"XOWN - Owner\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Owner\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"}]},{\"t\":3,\"p\":1,\"n\":\"XRNK - Owner Faction Rank\"},{\"t\":3,\"p\":1,\"n\":\"XEMI - Emittance\"},{\"t\":3,\"p\":1,\"n\":\"XMBR - MultiBound Reference\"},{\"p\":1,\"n\":\"XIS2 - Ignored by Sandbox\"},{\"t\":7,\"p\":1,\"n\":\"XLRT - Location Ref Type\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Ref\"}]},{\"t\":3,\"p\":1,\"n\":\"XLRL - Location Reference\"},{\"t\":5,\"p\":1,\"n\":\"XSCL - Scale\"},{\"t\":7,\"n\":\"XLOD - Distant LOD Data\",\"c\":[{\"t\":5,\"n\":\"Unknown\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DATA - Position\\/Rotation\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Position\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"X\"},{\"t\":5,\"p\":1,\"n\":\"Y\"},{\"t\":5,\"p\":1,\"n\":\"Z\"}]},{\"t\":6,\"p\":1,\"n\":\"Rotation\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"X\"},{\"t\":5,\"p\":1,\"n\":\"Y\"},{\"t\":5,\"p\":1,\"n\":\"Z\"}]}]},{\"t\":2,\"p\":1,\"n\":\"MNAM - Comments\"}]},{\"t\":1,\"p\":1,\"n\":\"PBEA - Placed Beam\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"VMAD - Virtual Machine Adapter\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Version\"},{\"t\":3,\"p\":1,\"n\":\"Object Format\"},{\"t\":7,\"p\":1,\"n\":\"Scripts\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Script\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"scriptName\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":7,\"p\":1,\"n\":\"Properties\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Property\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"propertyName\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]},{\"t\":2,\"p\":1,\"n\":\"String\"},{\"t\":3,\"p\":1,\"n\":\"Int32\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":3,\"p\":1,\"n\":\"Bool\"},{\"t\":7,\"p\":1,\"n\":\"Struct\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Member\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"memberName\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]},{\"t\":2,\"p\":1,\"n\":\"String\"},{\"t\":3,\"p\":1,\"n\":\"Int32\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":3,\"p\":1,\"n\":\"Bool\"},{\"t\":7,\"p\":1,\"n\":\"Array of Object\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]}]},{\"t\":7,\"p\":1,\"n\":\"Array of String\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Int32\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Float\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Bool\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]}]}]},{\"t\":7,\"p\":1,\"n\":\"Array of Object\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]}]},{\"t\":7,\"p\":1,\"n\":\"Array of String\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Int32\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Float\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Bool\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Struct\",\"c\":[{\"t\":7,\"p\":1,\"n\":\"Struct\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Member\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"memberName\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]},{\"t\":2,\"p\":1,\"n\":\"String\"},{\"t\":3,\"p\":1,\"n\":\"Int32\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":3,\"p\":1,\"n\":\"Bool\"},{\"t\":7,\"p\":1,\"n\":\"Array of Object\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]}]},{\"t\":7,\"p\":1,\"n\":\"Array of String\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Int32\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Float\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Bool\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]}]}]}]}]}]}]}]}]},{\"t\":3,\"p\":1,\"n\":\"NAME - Projectile\"},{\"t\":3,\"p\":1,\"n\":\"XEZN - Encounter Zone\"},{\"t\":5,\"p\":1,\"n\":\"XHTW - Head-Tracking Weight\"},{\"t\":5,\"p\":1,\"n\":\"XFVC - Favor Cost\"},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Reflected\\/Refracted By\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"XPWR - Water\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":3,\"p\":1,\"n\":\"Type\"}]}]},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Linked References\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"XLKR - Linked Reference\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Keyword\\/Ref\"},{\"t\":3,\"p\":1,\"n\":\"Ref\"}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Activate Parents\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"XAPD - Flags\"},{\"t\":8,\"p\":1,\"n\":\"Activate Parent Refs\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"XAPR - Activate Parent Ref\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":5,\"p\":1,\"n\":\"Delay\"}]}]}]},{\"t\":3,\"n\":\"XASP - Unknown\"},{\"t\":11,\"n\":\"XATP - Unknown\"},{\"t\":3,\"p\":1,\"n\":\"XAMC - Ammo Count\"},{\"p\":1,\"n\":\"XLKT - Linked Ref Transient\"},{\"t\":3,\"p\":1,\"n\":\"XLYR - Layer\"},{\"t\":3,\"p\":1,\"n\":\"XMSP - Material Swap\"},{\"t\":3,\"p\":1,\"n\":\"XRFG - Reference Group\"},{\"t\":11,\"n\":\"XCVR - Unknown\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"XESP - Enable Parent\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"XOWN - Owner\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Owner\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"}]},{\"t\":3,\"p\":1,\"n\":\"XRNK - Owner Faction Rank\"},{\"t\":3,\"p\":1,\"n\":\"XEMI - Emittance\"},{\"t\":3,\"p\":1,\"n\":\"XMBR - MultiBound Reference\"},{\"p\":1,\"n\":\"XIS2 - Ignored by Sandbox\"},{\"t\":7,\"p\":1,\"n\":\"XLRT - Location Ref Type\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Ref\"}]},{\"t\":3,\"p\":1,\"n\":\"XLRL - Location Reference\"},{\"t\":5,\"p\":1,\"n\":\"XSCL - Scale\"},{\"t\":7,\"n\":\"XLOD - Distant LOD Data\",\"c\":[{\"t\":5,\"n\":\"Unknown\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DATA - Position\\/Rotation\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Position\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"X\"},{\"t\":5,\"p\":1,\"n\":\"Y\"},{\"t\":5,\"p\":1,\"n\":\"Z\"}]},{\"t\":6,\"p\":1,\"n\":\"Rotation\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"X\"},{\"t\":5,\"p\":1,\"n\":\"Y\"},{\"t\":5,\"p\":1,\"n\":\"Z\"}]}]},{\"t\":2,\"p\":1,\"n\":\"MNAM - Comments\"}]},{\"t\":1,\"p\":1,\"n\":\"PCON - Placed Cone\\/Voice\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"VMAD - Virtual Machine Adapter\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Version\"},{\"t\":3,\"p\":1,\"n\":\"Object Format\"},{\"t\":7,\"p\":1,\"n\":\"Scripts\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Script\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"scriptName\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":7,\"p\":1,\"n\":\"Properties\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Property\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"propertyName\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]},{\"t\":2,\"p\":1,\"n\":\"String\"},{\"t\":3,\"p\":1,\"n\":\"Int32\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":3,\"p\":1,\"n\":\"Bool\"},{\"t\":7,\"p\":1,\"n\":\"Struct\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Member\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"memberName\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]},{\"t\":2,\"p\":1,\"n\":\"String\"},{\"t\":3,\"p\":1,\"n\":\"Int32\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":3,\"p\":1,\"n\":\"Bool\"},{\"t\":7,\"p\":1,\"n\":\"Array of Object\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]}]},{\"t\":7,\"p\":1,\"n\":\"Array of String\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Int32\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Float\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Bool\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]}]}]},{\"t\":7,\"p\":1,\"n\":\"Array of Object\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]}]},{\"t\":7,\"p\":1,\"n\":\"Array of String\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Int32\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Float\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Bool\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Struct\",\"c\":[{\"t\":7,\"p\":1,\"n\":\"Struct\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Member\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"memberName\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]},{\"t\":2,\"p\":1,\"n\":\"String\"},{\"t\":3,\"p\":1,\"n\":\"Int32\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":3,\"p\":1,\"n\":\"Bool\"},{\"t\":7,\"p\":1,\"n\":\"Array of Object\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]}]},{\"t\":7,\"p\":1,\"n\":\"Array of String\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Int32\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Float\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Bool\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]}]}]}]}]}]}]}]}]},{\"t\":3,\"p\":1,\"n\":\"NAME - Projectile\"},{\"t\":3,\"p\":1,\"n\":\"XEZN - Encounter Zone\"},{\"t\":5,\"p\":1,\"n\":\"XHTW - Head-Tracking Weight\"},{\"t\":5,\"p\":1,\"n\":\"XFVC - Favor Cost\"},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Reflected\\/Refracted By\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"XPWR - Water\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":3,\"p\":1,\"n\":\"Type\"}]}]},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Linked References\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"XLKR - Linked Reference\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Keyword\\/Ref\"},{\"t\":3,\"p\":1,\"n\":\"Ref\"}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Activate Parents\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"XAPD - Flags\"},{\"t\":8,\"p\":1,\"n\":\"Activate Parent Refs\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"XAPR - Activate Parent Ref\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":5,\"p\":1,\"n\":\"Delay\"}]}]}]},{\"t\":3,\"n\":\"XASP - Unknown\"},{\"t\":11,\"n\":\"XATP - Unknown\"},{\"t\":3,\"p\":1,\"n\":\"XAMC - Ammo Count\"},{\"p\":1,\"n\":\"XLKT - Linked Ref Transient\"},{\"t\":3,\"p\":1,\"n\":\"XLYR - Layer\"},{\"t\":3,\"p\":1,\"n\":\"XMSP - Material Swap\"},{\"t\":3,\"p\":1,\"n\":\"XRFG - Reference Group\"},{\"t\":11,\"n\":\"XCVR - Unknown\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"XESP - Enable Parent\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"XOWN - Owner\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Owner\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"}]},{\"t\":3,\"p\":1,\"n\":\"XRNK - Owner Faction Rank\"},{\"t\":3,\"p\":1,\"n\":\"XEMI - Emittance\"},{\"t\":3,\"p\":1,\"n\":\"XMBR - MultiBound Reference\"},{\"p\":1,\"n\":\"XIS2 - Ignored by Sandbox\"},{\"t\":7,\"p\":1,\"n\":\"XLRT - Location Ref Type\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Ref\"}]},{\"t\":3,\"p\":1,\"n\":\"XLRL - Location Reference\"},{\"t\":5,\"p\":1,\"n\":\"XSCL - Scale\"},{\"t\":7,\"n\":\"XLOD - Distant LOD Data\",\"c\":[{\"t\":5,\"n\":\"Unknown\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DATA - Position\\/Rotation\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Position\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"X\"},{\"t\":5,\"p\":1,\"n\":\"Y\"},{\"t\":5,\"p\":1,\"n\":\"Z\"}]},{\"t\":6,\"p\":1,\"n\":\"Rotation\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"X\"},{\"t\":5,\"p\":1,\"n\":\"Y\"},{\"t\":5,\"p\":1,\"n\":\"Z\"}]}]},{\"t\":2,\"p\":1,\"n\":\"MNAM - Comments\"}]},{\"t\":1,\"p\":1,\"n\":\"PERK - Perk\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"VMAD - Virtual Machine Adapter\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Version\"},{\"t\":3,\"p\":1,\"n\":\"Object Format\"},{\"t\":7,\"p\":1,\"n\":\"Scripts\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Script\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"scriptName\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":7,\"p\":1,\"n\":\"Properties\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Property\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"propertyName\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]},{\"t\":2,\"p\":1,\"n\":\"String\"},{\"t\":3,\"p\":1,\"n\":\"Int32\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":3,\"p\":1,\"n\":\"Bool\"},{\"t\":7,\"p\":1,\"n\":\"Struct\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Member\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"memberName\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]},{\"t\":2,\"p\":1,\"n\":\"String\"},{\"t\":3,\"p\":1,\"n\":\"Int32\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":3,\"p\":1,\"n\":\"Bool\"},{\"t\":7,\"p\":1,\"n\":\"Array of Object\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]}]},{\"t\":7,\"p\":1,\"n\":\"Array of String\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Int32\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Float\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Bool\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]}]}]},{\"t\":7,\"p\":1,\"n\":\"Array of Object\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]}]},{\"t\":7,\"p\":1,\"n\":\"Array of String\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Int32\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Float\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Bool\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Struct\",\"c\":[{\"t\":7,\"p\":1,\"n\":\"Struct\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Member\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"memberName\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]},{\"t\":2,\"p\":1,\"n\":\"String\"},{\"t\":3,\"p\":1,\"n\":\"Int32\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":3,\"p\":1,\"n\":\"Bool\"},{\"t\":7,\"p\":1,\"n\":\"Array of Object\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]}]},{\"t\":7,\"p\":1,\"n\":\"Array of String\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Int32\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Float\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Bool\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]}]}]}]}]}]}]}]},{\"t\":6,\"p\":1,\"n\":\"Script Fragments\",\"c\":[{\"t\":3,\"n\":\"Unknown\"},{\"t\":6,\"p\":1,\"n\":\"Script\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"scriptName\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":7,\"p\":1,\"n\":\"Properties\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Property\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"propertyName\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]},{\"t\":2,\"p\":1,\"n\":\"String\"},{\"t\":3,\"p\":1,\"n\":\"Int32\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":3,\"p\":1,\"n\":\"Bool\"},{\"t\":7,\"p\":1,\"n\":\"Struct\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Member\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"memberName\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]},{\"t\":2,\"p\":1,\"n\":\"String\"},{\"t\":3,\"p\":1,\"n\":\"Int32\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":3,\"p\":1,\"n\":\"Bool\"},{\"t\":7,\"p\":1,\"n\":\"Array of Object\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]}]},{\"t\":7,\"p\":1,\"n\":\"Array of String\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Int32\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Float\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Bool\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]}]}]},{\"t\":7,\"p\":1,\"n\":\"Array of Object\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]}]},{\"t\":7,\"p\":1,\"n\":\"Array of String\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Int32\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Float\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Bool\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Struct\",\"c\":[{\"t\":7,\"p\":1,\"n\":\"Struct\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Member\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"memberName\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]},{\"t\":2,\"p\":1,\"n\":\"String\"},{\"t\":3,\"p\":1,\"n\":\"Int32\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":3,\"p\":1,\"n\":\"Bool\"},{\"t\":7,\"p\":1,\"n\":\"Array of Object\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]}]},{\"t\":7,\"p\":1,\"n\":\"Array of String\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Int32\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Float\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Bool\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]}]}]}]}]}]}]},{\"t\":7,\"p\":1,\"n\":\"Fragments\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Fragment\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Fragment Index\"},{\"t\":3,\"n\":\"Unknown\"},{\"t\":2,\"p\":1,\"n\":\"scriptName\"},{\"t\":2,\"p\":1,\"n\":\"fragmentName\"}]}]}]}]},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":2,\"p\":1,\"n\":\"DESC - Description\"},{\"t\":2,\"p\":1,\"n\":\"ICON - Image\"},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Conditions\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Condition\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"CTDA - \",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":5,\"p\":1,\"n\":\"Comparison Value - Float\"},{\"t\":3,\"p\":1,\"n\":\"Comparison Value - Global\"},{\"t\":3,\"p\":1,\"n\":\"Function\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":11,\"p\":1,\"n\":\"None\"},{\"t\":3,\"p\":1,\"n\":\"Integer\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":3,\"p\":1,\"n\":\"Actor\"},{\"t\":3,\"p\":1,\"n\":\"Actor Base\"},{\"t\":3,\"p\":1,\"n\":\"Actor Value\"},{\"t\":3,\"p\":1,\"n\":\"Player Action\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"Alignment\"},{\"t\":3,\"p\":1,\"n\":\"Association Type\"},{\"t\":3,\"p\":1,\"n\":\"Axis\"},{\"t\":3,\"p\":1,\"n\":\"Casting Type\"},{\"t\":3,\"p\":1,\"n\":\"Cell\"},{\"t\":3,\"p\":1,\"n\":\"Class\"},{\"t\":3,\"p\":1,\"n\":\"Crime Type\"},{\"t\":3,\"p\":1,\"n\":\"Critical Stage\"},{\"t\":3,\"p\":1,\"n\":\"Encounter Zone\"},{\"t\":3,\"p\":1,\"n\":\"Equip Type\"},{\"t\":3,\"p\":1,\"n\":\"Event\"},{\"t\":3,\"p\":1,\"n\":\"Event Data\"},{\"t\":3,\"p\":1,\"n\":\"Faction\"},{\"t\":3,\"p\":1,\"n\":\"Form List\"},{\"t\":3,\"p\":1,\"n\":\"Form Type\"},{\"t\":3,\"p\":1,\"n\":\"Furniture\"},{\"t\":3,\"p\":1,\"n\":\"Furniture Anim\"},{\"t\":3,\"p\":1,\"n\":\"Furniture Entry\"},{\"t\":3,\"p\":1,\"n\":\"Global\"},{\"t\":3,\"p\":1,\"n\":\"Idle\"},{\"t\":3,\"p\":1,\"n\":\"Inventory Object\"},{\"t\":3,\"p\":1,\"n\":\"Keyword\"},{\"t\":3,\"p\":1,\"n\":\"Location\"},{\"t\":3,\"p\":1,\"n\":\"Base Effect\"},{\"t\":3,\"p\":1,\"n\":\"Effect Item\"},{\"t\":3,\"p\":1,\"n\":\"Misc Stat\"},{\"t\":3,\"p\":1,\"n\":\"Object Reference\"},{\"t\":3,\"p\":1,\"n\":\"Owner\"},{\"t\":3,\"p\":1,\"n\":\"Package\"},{\"t\":3,\"p\":1,\"n\":\"Packdata ID\"},{\"t\":3,\"p\":1,\"n\":\"Perk\"},{\"t\":3,\"p\":1,\"n\":\"Quest\"},{\"t\":3,\"p\":1,\"n\":\"Quest Stage\"},{\"t\":3,\"p\":1,\"n\":\"Race\"},{\"t\":3,\"p\":1,\"n\":\"Referenceable Object\"},{\"t\":3,\"p\":1,\"n\":\"Location Ref Type\"},{\"t\":3,\"p\":1,\"n\":\"Region\"},{\"t\":3,\"p\":1,\"n\":\"Scene\"},{\"t\":3,\"p\":1,\"n\":\"Sex\"},{\"t\":3,\"p\":1,\"n\":\"Shout\"},{\"t\":11,\"p\":1,\"n\":\"Variable Name (unused)\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Function\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Param (unused)\"},{\"t\":3,\"p\":1,\"n\":\"Voice Type\"},{\"t\":3,\"p\":1,\"n\":\"Ward State\"},{\"t\":3,\"p\":1,\"n\":\"Weather\"},{\"t\":3,\"p\":1,\"n\":\"Worldspace\"},{\"t\":3,\"p\":1,\"n\":\"Damage Type\"},{\"t\":3,\"p\":1,\"n\":\"Weapon\"},{\"t\":3,\"p\":1,\"n\":\"Weapon List\"},{\"t\":3,\"p\":1,\"n\":\"Target\"},{\"t\":3,\"p\":1,\"n\":\"Target List\"},{\"t\":3,\"p\":1,\"n\":\"Target Part\"},{\"t\":3,\"p\":1,\"n\":\"VATS Action\"},{\"t\":3,\"p\":1,\"n\":\"Critical Effect\"},{\"t\":3,\"p\":1,\"n\":\"Critical Effect List\"},{\"t\":3,\"p\":1,\"n\":\"Weapon Type\"},{\"t\":3,\"p\":1,\"n\":\"Projectile Type\"},{\"t\":3,\"p\":1,\"n\":\"Delivery Type\"},{\"t\":3,\"p\":1,\"n\":\"Run On\"},{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":3,\"p\":1,\"n\":\"Parameter #3\"}]},{\"t\":2,\"p\":1,\"n\":\"CIS1 - Parameter #1\"},{\"t\":2,\"p\":1,\"n\":\"CIS2 - Parameter #2\"}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DATA - Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Trait\"},{\"t\":3,\"p\":1,\"n\":\"Level\"},{\"t\":3,\"p\":1,\"n\":\"Num Ranks\"},{\"t\":3,\"p\":1,\"n\":\"Playable\"},{\"t\":3,\"p\":1,\"n\":\"Hidden\"}]},{\"t\":3,\"p\":1,\"n\":\"SNAM - Sound\"},{\"t\":3,\"p\":1,\"n\":\"NNAM - Next Perk\"},{\"t\":2,\"p\":1,\"n\":\"FNAM - SWF\"},{\"t\":10,\"p\":1,\"n\":\"Effects\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Effect\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"PRKE - Header\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Rank\"},{\"t\":3,\"p\":1,\"n\":\"Priority\"}]},{\"t\":6,\"p\":1,\"n\":\"Quest + Stage\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Quest\"},{\"t\":3,\"p\":1,\"n\":\"Quest Stage\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":3,\"p\":1,\"n\":\"Ability\"},{\"t\":6,\"p\":1,\"n\":\"Entry Point\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Entry Point\"},{\"t\":3,\"p\":1,\"n\":\"Function\"},{\"t\":3,\"p\":1,\"n\":\"Perk Condition Tab Count\"}]},{\"t\":10,\"p\":1,\"n\":\"Perk Conditions\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Perk Condition\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"PRKC - Run On (Tab Index)\"},{\"t\":8,\"p\":1,\"n\":\"Conditions\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Condition\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"CTDA - \",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":5,\"p\":1,\"n\":\"Comparison Value - Float\"},{\"t\":3,\"p\":1,\"n\":\"Comparison Value - Global\"},{\"t\":3,\"p\":1,\"n\":\"Function\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":11,\"p\":1,\"n\":\"None\"},{\"t\":3,\"p\":1,\"n\":\"Integer\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":3,\"p\":1,\"n\":\"Actor\"},{\"t\":3,\"p\":1,\"n\":\"Actor Base\"},{\"t\":3,\"p\":1,\"n\":\"Actor Value\"},{\"t\":3,\"p\":1,\"n\":\"Player Action\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"Alignment\"},{\"t\":3,\"p\":1,\"n\":\"Association Type\"},{\"t\":3,\"p\":1,\"n\":\"Axis\"},{\"t\":3,\"p\":1,\"n\":\"Casting Type\"},{\"t\":3,\"p\":1,\"n\":\"Cell\"},{\"t\":3,\"p\":1,\"n\":\"Class\"},{\"t\":3,\"p\":1,\"n\":\"Crime Type\"},{\"t\":3,\"p\":1,\"n\":\"Critical Stage\"},{\"t\":3,\"p\":1,\"n\":\"Encounter Zone\"},{\"t\":3,\"p\":1,\"n\":\"Equip Type\"},{\"t\":3,\"p\":1,\"n\":\"Event\"},{\"t\":3,\"p\":1,\"n\":\"Event Data\"},{\"t\":3,\"p\":1,\"n\":\"Faction\"},{\"t\":3,\"p\":1,\"n\":\"Form List\"},{\"t\":3,\"p\":1,\"n\":\"Form Type\"},{\"t\":3,\"p\":1,\"n\":\"Furniture\"},{\"t\":3,\"p\":1,\"n\":\"Furniture Anim\"},{\"t\":3,\"p\":1,\"n\":\"Furniture Entry\"},{\"t\":3,\"p\":1,\"n\":\"Global\"},{\"t\":3,\"p\":1,\"n\":\"Idle\"},{\"t\":3,\"p\":1,\"n\":\"Inventory Object\"},{\"t\":3,\"p\":1,\"n\":\"Keyword\"},{\"t\":3,\"p\":1,\"n\":\"Location\"},{\"t\":3,\"p\":1,\"n\":\"Base Effect\"},{\"t\":3,\"p\":1,\"n\":\"Effect Item\"},{\"t\":3,\"p\":1,\"n\":\"Misc Stat\"},{\"t\":3,\"p\":1,\"n\":\"Object Reference\"},{\"t\":3,\"p\":1,\"n\":\"Owner\"},{\"t\":3,\"p\":1,\"n\":\"Package\"},{\"t\":3,\"p\":1,\"n\":\"Packdata ID\"},{\"t\":3,\"p\":1,\"n\":\"Perk\"},{\"t\":3,\"p\":1,\"n\":\"Quest\"},{\"t\":3,\"p\":1,\"n\":\"Quest Stage\"},{\"t\":3,\"p\":1,\"n\":\"Race\"},{\"t\":3,\"p\":1,\"n\":\"Referenceable Object\"},{\"t\":3,\"p\":1,\"n\":\"Location Ref Type\"},{\"t\":3,\"p\":1,\"n\":\"Region\"},{\"t\":3,\"p\":1,\"n\":\"Scene\"},{\"t\":3,\"p\":1,\"n\":\"Sex\"},{\"t\":3,\"p\":1,\"n\":\"Shout\"},{\"t\":11,\"p\":1,\"n\":\"Variable Name (unused)\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Function\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Param (unused)\"},{\"t\":3,\"p\":1,\"n\":\"Voice Type\"},{\"t\":3,\"p\":1,\"n\":\"Ward State\"},{\"t\":3,\"p\":1,\"n\":\"Weather\"},{\"t\":3,\"p\":1,\"n\":\"Worldspace\"},{\"t\":3,\"p\":1,\"n\":\"Damage Type\"},{\"t\":3,\"p\":1,\"n\":\"Weapon\"},{\"t\":3,\"p\":1,\"n\":\"Weapon List\"},{\"t\":3,\"p\":1,\"n\":\"Target\"},{\"t\":3,\"p\":1,\"n\":\"Target List\"},{\"t\":3,\"p\":1,\"n\":\"Target Part\"},{\"t\":3,\"p\":1,\"n\":\"VATS Action\"},{\"t\":3,\"p\":1,\"n\":\"Critical Effect\"},{\"t\":3,\"p\":1,\"n\":\"Critical Effect List\"},{\"t\":3,\"p\":1,\"n\":\"Weapon Type\"},{\"t\":3,\"p\":1,\"n\":\"Projectile Type\"},{\"t\":3,\"p\":1,\"n\":\"Delivery Type\"},{\"t\":3,\"p\":1,\"n\":\"Run On\"},{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":3,\"p\":1,\"n\":\"Parameter #3\"}]},{\"t\":2,\"p\":1,\"n\":\"CIS1 - Parameter #1\"},{\"t\":2,\"p\":1,\"n\":\"CIS2 - Parameter #2\"}]}]}]}]},{\"t\":6,\"p\":1,\"n\":\"Function Parameters\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"EPFT - Type\"},{\"t\":3,\"p\":1,\"n\":\"EPFB - Perk Entry ID (unique)\"},{\"t\":2,\"p\":1,\"n\":\"EPF2 - Button Label\"},{\"t\":6,\"p\":1,\"n\":\"EPF3 - Script Flags\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Script Flags\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":11,\"n\":\"Unknown\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":6,\"p\":1,\"n\":\"Float, Float\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Float 1\"},{\"t\":5,\"p\":1,\"n\":\"Float 2\"}]},{\"t\":3,\"p\":1,\"n\":\"Leveled Item\"},{\"t\":3,\"p\":1,\"n\":\"Spell\"},{\"t\":2,\"p\":1,\"n\":\"Text\"},{\"t\":6,\"p\":1,\"n\":\"Actor Value, Float\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Actor Value\"},{\"t\":5,\"p\":1,\"n\":\"Float\"}]}]},{\"p\":1,\"n\":\"PRKF - End Marker\"}]}]}]},{\"t\":1,\"p\":1,\"n\":\"PFLA - Placed Flame\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"VMAD - Virtual Machine Adapter\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Version\"},{\"t\":3,\"p\":1,\"n\":\"Object Format\"},{\"t\":7,\"p\":1,\"n\":\"Scripts\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Script\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"scriptName\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":7,\"p\":1,\"n\":\"Properties\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Property\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"propertyName\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]},{\"t\":2,\"p\":1,\"n\":\"String\"},{\"t\":3,\"p\":1,\"n\":\"Int32\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":3,\"p\":1,\"n\":\"Bool\"},{\"t\":7,\"p\":1,\"n\":\"Struct\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Member\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"memberName\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]},{\"t\":2,\"p\":1,\"n\":\"String\"},{\"t\":3,\"p\":1,\"n\":\"Int32\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":3,\"p\":1,\"n\":\"Bool\"},{\"t\":7,\"p\":1,\"n\":\"Array of Object\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]}]},{\"t\":7,\"p\":1,\"n\":\"Array of String\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Int32\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Float\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Bool\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]}]}]},{\"t\":7,\"p\":1,\"n\":\"Array of Object\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]}]},{\"t\":7,\"p\":1,\"n\":\"Array of String\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Int32\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Float\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Bool\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Struct\",\"c\":[{\"t\":7,\"p\":1,\"n\":\"Struct\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Member\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"memberName\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]},{\"t\":2,\"p\":1,\"n\":\"String\"},{\"t\":3,\"p\":1,\"n\":\"Int32\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":3,\"p\":1,\"n\":\"Bool\"},{\"t\":7,\"p\":1,\"n\":\"Array of Object\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]}]},{\"t\":7,\"p\":1,\"n\":\"Array of String\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Int32\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Float\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Bool\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]}]}]}]}]}]}]}]}]},{\"t\":3,\"p\":1,\"n\":\"NAME - Projectile\"},{\"t\":3,\"p\":1,\"n\":\"XEZN - Encounter Zone\"},{\"t\":5,\"p\":1,\"n\":\"XHTW - Head-Tracking Weight\"},{\"t\":5,\"p\":1,\"n\":\"XFVC - Favor Cost\"},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Reflected\\/Refracted By\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"XPWR - Water\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":3,\"p\":1,\"n\":\"Type\"}]}]},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Linked References\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"XLKR - Linked Reference\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Keyword\\/Ref\"},{\"t\":3,\"p\":1,\"n\":\"Ref\"}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Activate Parents\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"XAPD - Flags\"},{\"t\":8,\"p\":1,\"n\":\"Activate Parent Refs\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"XAPR - Activate Parent Ref\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":5,\"p\":1,\"n\":\"Delay\"}]}]}]},{\"t\":3,\"n\":\"XASP - Unknown\"},{\"t\":11,\"n\":\"XATP - Unknown\"},{\"t\":3,\"p\":1,\"n\":\"XAMC - Ammo Count\"},{\"p\":1,\"n\":\"XLKT - Linked Ref Transient\"},{\"t\":3,\"p\":1,\"n\":\"XLYR - Layer\"},{\"t\":3,\"p\":1,\"n\":\"XMSP - Material Swap\"},{\"t\":3,\"p\":1,\"n\":\"XRFG - Reference Group\"},{\"t\":11,\"n\":\"XCVR - Unknown\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"XESP - Enable Parent\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"XOWN - Owner\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Owner\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"}]},{\"t\":3,\"p\":1,\"n\":\"XRNK - Owner Faction Rank\"},{\"t\":3,\"p\":1,\"n\":\"XEMI - Emittance\"},{\"t\":3,\"p\":1,\"n\":\"XMBR - MultiBound Reference\"},{\"p\":1,\"n\":\"XIS2 - Ignored by Sandbox\"},{\"t\":7,\"p\":1,\"n\":\"XLRT - Location Ref Type\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Ref\"}]},{\"t\":3,\"p\":1,\"n\":\"XLRL - Location Reference\"},{\"t\":5,\"p\":1,\"n\":\"XSCL - Scale\"},{\"t\":7,\"n\":\"XLOD - Distant LOD Data\",\"c\":[{\"t\":5,\"n\":\"Unknown\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DATA - Position\\/Rotation\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Position\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"X\"},{\"t\":5,\"p\":1,\"n\":\"Y\"},{\"t\":5,\"p\":1,\"n\":\"Z\"}]},{\"t\":6,\"p\":1,\"n\":\"Rotation\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"X\"},{\"t\":5,\"p\":1,\"n\":\"Y\"},{\"t\":5,\"p\":1,\"n\":\"Z\"}]}]},{\"t\":2,\"p\":1,\"n\":\"MNAM - Comments\"}]},{\"t\":1,\"p\":1,\"n\":\"PGRE - Placed Projectile\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"VMAD - Virtual Machine Adapter\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Version\"},{\"t\":3,\"p\":1,\"n\":\"Object Format\"},{\"t\":7,\"p\":1,\"n\":\"Scripts\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Script\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"scriptName\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":7,\"p\":1,\"n\":\"Properties\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Property\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"propertyName\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]},{\"t\":2,\"p\":1,\"n\":\"String\"},{\"t\":3,\"p\":1,\"n\":\"Int32\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":3,\"p\":1,\"n\":\"Bool\"},{\"t\":7,\"p\":1,\"n\":\"Struct\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Member\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"memberName\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]},{\"t\":2,\"p\":1,\"n\":\"String\"},{\"t\":3,\"p\":1,\"n\":\"Int32\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":3,\"p\":1,\"n\":\"Bool\"},{\"t\":7,\"p\":1,\"n\":\"Array of Object\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]}]},{\"t\":7,\"p\":1,\"n\":\"Array of String\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Int32\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Float\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Bool\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]}]}]},{\"t\":7,\"p\":1,\"n\":\"Array of Object\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]}]},{\"t\":7,\"p\":1,\"n\":\"Array of String\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Int32\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Float\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Bool\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Struct\",\"c\":[{\"t\":7,\"p\":1,\"n\":\"Struct\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Member\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"memberName\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]},{\"t\":2,\"p\":1,\"n\":\"String\"},{\"t\":3,\"p\":1,\"n\":\"Int32\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":3,\"p\":1,\"n\":\"Bool\"},{\"t\":7,\"p\":1,\"n\":\"Array of Object\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]}]},{\"t\":7,\"p\":1,\"n\":\"Array of String\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Int32\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Float\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Bool\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]}]}]}]}]}]}]}]}]},{\"t\":3,\"p\":1,\"n\":\"NAME - Projectile\"},{\"t\":3,\"p\":1,\"n\":\"XEZN - Encounter Zone\"},{\"t\":5,\"p\":1,\"n\":\"XHTW - Head-Tracking Weight\"},{\"t\":5,\"p\":1,\"n\":\"XFVC - Favor Cost\"},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Reflected\\/Refracted By\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"XPWR - Water\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":3,\"p\":1,\"n\":\"Type\"}]}]},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Linked References\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"XLKR - Linked Reference\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Keyword\\/Ref\"},{\"t\":3,\"p\":1,\"n\":\"Ref\"}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Activate Parents\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"XAPD - Flags\"},{\"t\":8,\"p\":1,\"n\":\"Activate Parent Refs\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"XAPR - Activate Parent Ref\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":5,\"p\":1,\"n\":\"Delay\"}]}]}]},{\"t\":3,\"n\":\"XASP - Unknown\"},{\"t\":11,\"n\":\"XATP - Unknown\"},{\"t\":3,\"p\":1,\"n\":\"XAMC - Ammo Count\"},{\"p\":1,\"n\":\"XLKT - Linked Ref Transient\"},{\"t\":3,\"p\":1,\"n\":\"XLYR - Layer\"},{\"t\":3,\"p\":1,\"n\":\"XMSP - Material Swap\"},{\"t\":3,\"p\":1,\"n\":\"XRFG - Reference Group\"},{\"t\":11,\"n\":\"XCVR - Unknown\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"XESP - Enable Parent\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"XOWN - Owner\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Owner\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"}]},{\"t\":3,\"p\":1,\"n\":\"XRNK - Owner Faction Rank\"},{\"t\":3,\"p\":1,\"n\":\"XEMI - Emittance\"},{\"t\":3,\"p\":1,\"n\":\"XMBR - MultiBound Reference\"},{\"p\":1,\"n\":\"XIS2 - Ignored by Sandbox\"},{\"t\":7,\"p\":1,\"n\":\"XLRT - Location Ref Type\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Ref\"}]},{\"t\":3,\"p\":1,\"n\":\"XLRL - Location Reference\"},{\"t\":5,\"p\":1,\"n\":\"XSCL - Scale\"},{\"t\":7,\"n\":\"XLOD - Distant LOD Data\",\"c\":[{\"t\":5,\"n\":\"Unknown\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DATA - Position\\/Rotation\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Position\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"X\"},{\"t\":5,\"p\":1,\"n\":\"Y\"},{\"t\":5,\"p\":1,\"n\":\"Z\"}]},{\"t\":6,\"p\":1,\"n\":\"Rotation\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"X\"},{\"t\":5,\"p\":1,\"n\":\"Y\"},{\"t\":5,\"p\":1,\"n\":\"Z\"}]}]},{\"t\":2,\"p\":1,\"n\":\"MNAM - Comments\"}]},{\"t\":1,\"p\":1,\"n\":\"PHZD - Placed Hazard\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"VMAD - Virtual Machine Adapter\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Version\"},{\"t\":3,\"p\":1,\"n\":\"Object Format\"},{\"t\":7,\"p\":1,\"n\":\"Scripts\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Script\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"scriptName\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":7,\"p\":1,\"n\":\"Properties\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Property\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"propertyName\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]},{\"t\":2,\"p\":1,\"n\":\"String\"},{\"t\":3,\"p\":1,\"n\":\"Int32\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":3,\"p\":1,\"n\":\"Bool\"},{\"t\":7,\"p\":1,\"n\":\"Struct\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Member\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"memberName\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]},{\"t\":2,\"p\":1,\"n\":\"String\"},{\"t\":3,\"p\":1,\"n\":\"Int32\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":3,\"p\":1,\"n\":\"Bool\"},{\"t\":7,\"p\":1,\"n\":\"Array of Object\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]}]},{\"t\":7,\"p\":1,\"n\":\"Array of String\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Int32\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Float\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Bool\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]}]}]},{\"t\":7,\"p\":1,\"n\":\"Array of Object\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]}]},{\"t\":7,\"p\":1,\"n\":\"Array of String\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Int32\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Float\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Bool\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Struct\",\"c\":[{\"t\":7,\"p\":1,\"n\":\"Struct\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Member\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"memberName\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]},{\"t\":2,\"p\":1,\"n\":\"String\"},{\"t\":3,\"p\":1,\"n\":\"Int32\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":3,\"p\":1,\"n\":\"Bool\"},{\"t\":7,\"p\":1,\"n\":\"Array of Object\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]}]},{\"t\":7,\"p\":1,\"n\":\"Array of String\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Int32\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Float\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Bool\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]}]}]}]}]}]}]}]}]},{\"t\":3,\"p\":1,\"n\":\"NAME - Projectile\"},{\"t\":3,\"p\":1,\"n\":\"XEZN - Encounter Zone\"},{\"t\":5,\"p\":1,\"n\":\"XHTW - Head-Tracking Weight\"},{\"t\":5,\"p\":1,\"n\":\"XFVC - Favor Cost\"},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Reflected\\/Refracted By\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"XPWR - Water\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":3,\"p\":1,\"n\":\"Type\"}]}]},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Linked References\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"XLKR - Linked Reference\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Keyword\\/Ref\"},{\"t\":3,\"p\":1,\"n\":\"Ref\"}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Activate Parents\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"XAPD - Flags\"},{\"t\":8,\"p\":1,\"n\":\"Activate Parent Refs\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"XAPR - Activate Parent Ref\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":5,\"p\":1,\"n\":\"Delay\"}]}]}]},{\"t\":3,\"n\":\"XASP - Unknown\"},{\"t\":11,\"n\":\"XATP - Unknown\"},{\"t\":3,\"p\":1,\"n\":\"XAMC - Ammo Count\"},{\"p\":1,\"n\":\"XLKT - Linked Ref Transient\"},{\"t\":3,\"p\":1,\"n\":\"XLYR - Layer\"},{\"t\":3,\"p\":1,\"n\":\"XMSP - Material Swap\"},{\"t\":3,\"p\":1,\"n\":\"XRFG - Reference Group\"},{\"t\":11,\"n\":\"XCVR - Unknown\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"XESP - Enable Parent\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"XOWN - Owner\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Owner\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"}]},{\"t\":3,\"p\":1,\"n\":\"XRNK - Owner Faction Rank\"},{\"t\":3,\"p\":1,\"n\":\"XEMI - Emittance\"},{\"t\":3,\"p\":1,\"n\":\"XMBR - MultiBound Reference\"},{\"p\":1,\"n\":\"XIS2 - Ignored by Sandbox\"},{\"t\":7,\"p\":1,\"n\":\"XLRT - Location Ref Type\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Ref\"}]},{\"t\":3,\"p\":1,\"n\":\"XLRL - Location Reference\"},{\"t\":5,\"p\":1,\"n\":\"XSCL - Scale\"},{\"t\":7,\"n\":\"XLOD - Distant LOD Data\",\"c\":[{\"t\":5,\"n\":\"Unknown\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DATA - Position\\/Rotation\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Position\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"X\"},{\"t\":5,\"p\":1,\"n\":\"Y\"},{\"t\":5,\"p\":1,\"n\":\"Z\"}]},{\"t\":6,\"p\":1,\"n\":\"Rotation\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"X\"},{\"t\":5,\"p\":1,\"n\":\"Y\"},{\"t\":5,\"p\":1,\"n\":\"Z\"}]}]},{\"t\":2,\"p\":1,\"n\":\"MNAM - Comments\"}]},{\"t\":1,\"p\":1,\"n\":\"PKIN - Pack-In\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"X1\"},{\"t\":3,\"p\":1,\"n\":\"Y1\"},{\"t\":3,\"p\":1,\"n\":\"Z1\"},{\"t\":3,\"p\":1,\"n\":\"X2\"},{\"t\":3,\"p\":1,\"n\":\"Y2\"},{\"t\":3,\"p\":1,\"n\":\"Z2\"}]},{\"t\":2,\"p\":1,\"n\":\"FLTR - Filter\"},{\"t\":3,\"p\":1,\"n\":\"CNAM - Cell\"},{\"t\":3,\"p\":1,\"n\":\"VNAM - Version\"}]},{\"t\":1,\"p\":1,\"n\":\"PMIS - Placed Missile\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"VMAD - Virtual Machine Adapter\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Version\"},{\"t\":3,\"p\":1,\"n\":\"Object Format\"},{\"t\":7,\"p\":1,\"n\":\"Scripts\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Script\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"scriptName\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":7,\"p\":1,\"n\":\"Properties\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Property\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"propertyName\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]},{\"t\":2,\"p\":1,\"n\":\"String\"},{\"t\":3,\"p\":1,\"n\":\"Int32\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":3,\"p\":1,\"n\":\"Bool\"},{\"t\":7,\"p\":1,\"n\":\"Struct\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Member\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"memberName\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]},{\"t\":2,\"p\":1,\"n\":\"String\"},{\"t\":3,\"p\":1,\"n\":\"Int32\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":3,\"p\":1,\"n\":\"Bool\"},{\"t\":7,\"p\":1,\"n\":\"Array of Object\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]}]},{\"t\":7,\"p\":1,\"n\":\"Array of String\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Int32\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Float\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Bool\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]}]}]},{\"t\":7,\"p\":1,\"n\":\"Array of Object\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]}]},{\"t\":7,\"p\":1,\"n\":\"Array of String\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Int32\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Float\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Bool\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Struct\",\"c\":[{\"t\":7,\"p\":1,\"n\":\"Struct\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Member\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"memberName\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]},{\"t\":2,\"p\":1,\"n\":\"String\"},{\"t\":3,\"p\":1,\"n\":\"Int32\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":3,\"p\":1,\"n\":\"Bool\"},{\"t\":7,\"p\":1,\"n\":\"Array of Object\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]}]},{\"t\":7,\"p\":1,\"n\":\"Array of String\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Int32\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Float\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Bool\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]}]}]}]}]}]}]}]}]},{\"t\":3,\"p\":1,\"n\":\"NAME - Projectile\"},{\"t\":3,\"p\":1,\"n\":\"XEZN - Encounter Zone\"},{\"t\":5,\"p\":1,\"n\":\"XHTW - Head-Tracking Weight\"},{\"t\":5,\"p\":1,\"n\":\"XFVC - Favor Cost\"},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Reflected\\/Refracted By\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"XPWR - Water\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":3,\"p\":1,\"n\":\"Type\"}]}]},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Linked References\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"XLKR - Linked Reference\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Keyword\\/Ref\"},{\"t\":3,\"p\":1,\"n\":\"Ref\"}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Activate Parents\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"XAPD - Flags\"},{\"t\":8,\"p\":1,\"n\":\"Activate Parent Refs\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"XAPR - Activate Parent Ref\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":5,\"p\":1,\"n\":\"Delay\"}]}]}]},{\"t\":3,\"n\":\"XASP - Unknown\"},{\"t\":11,\"n\":\"XATP - Unknown\"},{\"t\":3,\"p\":1,\"n\":\"XAMC - Ammo Count\"},{\"p\":1,\"n\":\"XLKT - Linked Ref Transient\"},{\"t\":3,\"p\":1,\"n\":\"XLYR - Layer\"},{\"t\":3,\"p\":1,\"n\":\"XMSP - Material Swap\"},{\"t\":3,\"p\":1,\"n\":\"XRFG - Reference Group\"},{\"t\":11,\"n\":\"XCVR - Unknown\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"XESP - Enable Parent\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"XOWN - Owner\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Owner\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"}]},{\"t\":3,\"p\":1,\"n\":\"XRNK - Owner Faction Rank\"},{\"t\":3,\"p\":1,\"n\":\"XEMI - Emittance\"},{\"t\":3,\"p\":1,\"n\":\"XMBR - MultiBound Reference\"},{\"p\":1,\"n\":\"XIS2 - Ignored by Sandbox\"},{\"t\":7,\"p\":1,\"n\":\"XLRT - Location Ref Type\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Ref\"}]},{\"t\":3,\"p\":1,\"n\":\"XLRL - Location Reference\"},{\"t\":5,\"p\":1,\"n\":\"XSCL - Scale\"},{\"t\":7,\"n\":\"XLOD - Distant LOD Data\",\"c\":[{\"t\":5,\"n\":\"Unknown\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DATA - Position\\/Rotation\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Position\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"X\"},{\"t\":5,\"p\":1,\"n\":\"Y\"},{\"t\":5,\"p\":1,\"n\":\"Z\"}]},{\"t\":6,\"p\":1,\"n\":\"Rotation\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"X\"},{\"t\":5,\"p\":1,\"n\":\"Y\"},{\"t\":5,\"p\":1,\"n\":\"Z\"}]}]},{\"t\":2,\"p\":1,\"n\":\"MNAM - Comments\"}]},{\"t\":1,\"p\":1,\"n\":\"PROJ - Projectile\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"X1\"},{\"t\":3,\"p\":1,\"n\":\"Y1\"},{\"t\":3,\"p\":1,\"n\":\"Z1\"},{\"t\":3,\"p\":1,\"n\":\"X2\"},{\"t\":3,\"p\":1,\"n\":\"Y2\"},{\"t\":3,\"p\":1,\"n\":\"Z2\"}]},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"MODT - Texture Files Hashes\"},{\"t\":3,\"p\":1,\"n\":\"MODS - Material Swap\"},{\"t\":5,\"p\":1,\"n\":\"MODC - Color Remapping Index\"},{\"t\":11,\"n\":\"MODF - Unknown\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Destructible\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"DEST - Header\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Health\"},{\"t\":3,\"p\":1,\"n\":\"DEST Count\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":7,\"p\":1,\"n\":\"DAMC - Resistances\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Resistance\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Damage Type\"},{\"t\":3,\"p\":1,\"n\":\"Value\"}]}]},{\"t\":8,\"p\":1,\"n\":\"Stages\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Stage\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"DSTD - Destruction Stage Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Health %\"},{\"t\":3,\"p\":1,\"n\":\"Index\"},{\"t\":3,\"p\":1,\"n\":\"Model Damage Stage\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":3,\"p\":1,\"n\":\"Self Damage per Second\"},{\"t\":3,\"p\":1,\"n\":\"Explosion\"},{\"t\":3,\"p\":1,\"n\":\"Debris\"},{\"t\":3,\"p\":1,\"n\":\"Debris Count\"}]},{\"t\":2,\"p\":1,\"n\":\"DSTA - Sequence Name\"},{\"t\":6,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"DMDL - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"DMDT - Texture Files Hashes\"},{\"t\":5,\"p\":1,\"n\":\"DMDC - Color Remapping Index\"},{\"t\":3,\"p\":1,\"n\":\"DMDS - Material Swap\"}]},{\"p\":1,\"n\":\"DSTF - End Marker\"}]}]}]},{\"t\":11,\"n\":\"DATA - Unused\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DNAM - Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":5,\"p\":1,\"n\":\"Gravity\"},{\"t\":5,\"p\":1,\"n\":\"Speed\"},{\"t\":5,\"p\":1,\"n\":\"Range\"},{\"t\":3,\"p\":1,\"n\":\"Light\"},{\"t\":3,\"p\":1,\"n\":\"Muzzle Flash - Light\"},{\"t\":5,\"p\":1,\"n\":\"Explosion - Alt. Trigger - Proximity\"},{\"t\":5,\"p\":1,\"n\":\"Explosion - Alt. Trigger - Timer\"},{\"t\":3,\"p\":1,\"n\":\"Explosion\"},{\"t\":3,\"p\":1,\"n\":\"Sound\"},{\"t\":5,\"p\":1,\"n\":\"Muzzle Flash - Duration\"},{\"t\":5,\"p\":1,\"n\":\"Fade Duration\"},{\"t\":5,\"p\":1,\"n\":\"Impact Force\"},{\"t\":3,\"p\":1,\"n\":\"Sound - Countdown\"},{\"t\":3,\"p\":1,\"n\":\"Sound - Disable\"},{\"t\":3,\"p\":1,\"n\":\"Default Weapon Source\"},{\"t\":5,\"p\":1,\"n\":\"Cone Spread\"},{\"t\":5,\"p\":1,\"n\":\"Collision Radius\"},{\"t\":5,\"p\":1,\"n\":\"Lifetime\"},{\"t\":5,\"p\":1,\"n\":\"Relaunch Interval\"},{\"t\":3,\"p\":1,\"n\":\"Decal Data\"},{\"t\":3,\"p\":1,\"n\":\"Collision Layer\"},{\"t\":3,\"p\":1,\"n\":\"Tracer Frequency\"},{\"t\":3,\"p\":1,\"n\":\"VATS Projectile\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Muzzle Flash Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"NAM1 - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"NAM2 - Texture Files Hashes\"}]},{\"t\":3,\"p\":1,\"n\":\"VNAM - Sound Level\"}]},{\"t\":1,\"p\":1,\"n\":\"QUST - Quest\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"VMAD - Virtual Machine Adapter\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Version\"},{\"t\":3,\"p\":1,\"n\":\"Object Format\"},{\"t\":7,\"p\":1,\"n\":\"Scripts\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Script\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"scriptName\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":7,\"p\":1,\"n\":\"Properties\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Property\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"propertyName\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]},{\"t\":2,\"p\":1,\"n\":\"String\"},{\"t\":3,\"p\":1,\"n\":\"Int32\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":3,\"p\":1,\"n\":\"Bool\"},{\"t\":7,\"p\":1,\"n\":\"Struct\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Member\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"memberName\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]},{\"t\":2,\"p\":1,\"n\":\"String\"},{\"t\":3,\"p\":1,\"n\":\"Int32\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":3,\"p\":1,\"n\":\"Bool\"},{\"t\":7,\"p\":1,\"n\":\"Array of Object\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]}]},{\"t\":7,\"p\":1,\"n\":\"Array of String\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Int32\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Float\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Bool\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]}]}]},{\"t\":7,\"p\":1,\"n\":\"Array of Object\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]}]},{\"t\":7,\"p\":1,\"n\":\"Array of String\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Int32\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Float\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Bool\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Struct\",\"c\":[{\"t\":7,\"p\":1,\"n\":\"Struct\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Member\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"memberName\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]},{\"t\":2,\"p\":1,\"n\":\"String\"},{\"t\":3,\"p\":1,\"n\":\"Int32\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":3,\"p\":1,\"n\":\"Bool\"},{\"t\":7,\"p\":1,\"n\":\"Array of Object\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]}]},{\"t\":7,\"p\":1,\"n\":\"Array of String\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Int32\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Float\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Bool\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]}]}]}]}]}]}]}]},{\"t\":6,\"p\":1,\"n\":\"Script Fragments\",\"c\":[{\"t\":3,\"n\":\"Unknown\"},{\"t\":3,\"p\":1,\"n\":\"fragmentCount\"},{\"t\":2,\"p\":1,\"n\":\"scriptName\"},{\"t\":6,\"p\":1,\"n\":\"Script Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":7,\"p\":1,\"n\":\"Properties\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Property\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"propertyName\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]},{\"t\":2,\"p\":1,\"n\":\"String\"},{\"t\":3,\"p\":1,\"n\":\"Int32\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":3,\"p\":1,\"n\":\"Bool\"},{\"t\":7,\"p\":1,\"n\":\"Struct\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Member\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"memberName\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]},{\"t\":2,\"p\":1,\"n\":\"String\"},{\"t\":3,\"p\":1,\"n\":\"Int32\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":3,\"p\":1,\"n\":\"Bool\"},{\"t\":7,\"p\":1,\"n\":\"Array of Object\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]}]},{\"t\":7,\"p\":1,\"n\":\"Array of String\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Int32\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Float\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Bool\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]}]}]},{\"t\":7,\"p\":1,\"n\":\"Array of Object\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]}]},{\"t\":7,\"p\":1,\"n\":\"Array of String\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Int32\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Float\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Bool\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Struct\",\"c\":[{\"t\":7,\"p\":1,\"n\":\"Struct\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Member\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"memberName\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]},{\"t\":2,\"p\":1,\"n\":\"String\"},{\"t\":3,\"p\":1,\"n\":\"Int32\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":3,\"p\":1,\"n\":\"Bool\"},{\"t\":7,\"p\":1,\"n\":\"Array of Object\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]}]},{\"t\":7,\"p\":1,\"n\":\"Array of String\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Int32\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Float\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Bool\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]}]}]}]}]}]}]},{\"t\":11,\"n\":\"Unused\"},{\"t\":7,\"p\":1,\"n\":\"Fragments\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Fragment\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Quest Stage\"},{\"t\":3,\"n\":\"Unknown\"},{\"t\":3,\"p\":1,\"n\":\"Quest Stage Index\"},{\"t\":2,\"p\":1,\"n\":\"scriptName\"},{\"t\":2,\"p\":1,\"n\":\"fragmentName\"}]}]}]},{\"t\":7,\"p\":1,\"n\":\"Aliases\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alias\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]},{\"t\":3,\"p\":1,\"n\":\"Version\"},{\"t\":3,\"p\":1,\"n\":\"Object Format\"},{\"t\":7,\"p\":1,\"n\":\"Alias Scripts\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Script\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"scriptName\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":7,\"p\":1,\"n\":\"Properties\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Property\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"propertyName\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]},{\"t\":2,\"p\":1,\"n\":\"String\"},{\"t\":3,\"p\":1,\"n\":\"Int32\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":3,\"p\":1,\"n\":\"Bool\"},{\"t\":7,\"p\":1,\"n\":\"Struct\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Member\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"memberName\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]},{\"t\":2,\"p\":1,\"n\":\"String\"},{\"t\":3,\"p\":1,\"n\":\"Int32\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":3,\"p\":1,\"n\":\"Bool\"},{\"t\":7,\"p\":1,\"n\":\"Array of Object\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]}]},{\"t\":7,\"p\":1,\"n\":\"Array of String\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Int32\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Float\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Bool\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]}]}]},{\"t\":7,\"p\":1,\"n\":\"Array of Object\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]}]},{\"t\":7,\"p\":1,\"n\":\"Array of String\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Int32\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Float\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Bool\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Struct\",\"c\":[{\"t\":7,\"p\":1,\"n\":\"Struct\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Member\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"memberName\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]},{\"t\":2,\"p\":1,\"n\":\"String\"},{\"t\":3,\"p\":1,\"n\":\"Int32\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":3,\"p\":1,\"n\":\"Bool\"},{\"t\":7,\"p\":1,\"n\":\"Array of Object\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]}]},{\"t\":7,\"p\":1,\"n\":\"Array of String\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Int32\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Float\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Bool\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]}]}]}]}]}]}]}]}]}]}]},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DNAM - General\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":3,\"p\":1,\"n\":\"Priority\"},{\"t\":3,\"p\":1,\"n\":\"Form Version\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":3,\"p\":1,\"n\":\"Type\"}]},{\"t\":2,\"p\":1,\"n\":\"ENAM - Event\"},{\"t\":3,\"p\":1,\"n\":\"LNAM - Location\"},{\"t\":3,\"p\":1,\"n\":\"XNAM - Quest Completion XP\"},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Text Display Globals\",\"d\":1,\"c\":[{\"t\":3,\"p\":1,\"n\":\"QTGL - Global\"}]},{\"t\":2,\"p\":1,\"n\":\"FLTR - Filter\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Quest Dialogue Conditions\",\"c\":[{\"t\":8,\"p\":1,\"n\":\"Conditions\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Condition\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"CTDA - \",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":5,\"p\":1,\"n\":\"Comparison Value - Float\"},{\"t\":3,\"p\":1,\"n\":\"Comparison Value - Global\"},{\"t\":3,\"p\":1,\"n\":\"Function\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":11,\"p\":1,\"n\":\"None\"},{\"t\":3,\"p\":1,\"n\":\"Integer\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":3,\"p\":1,\"n\":\"Actor\"},{\"t\":3,\"p\":1,\"n\":\"Actor Base\"},{\"t\":3,\"p\":1,\"n\":\"Actor Value\"},{\"t\":3,\"p\":1,\"n\":\"Player Action\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"Alignment\"},{\"t\":3,\"p\":1,\"n\":\"Association Type\"},{\"t\":3,\"p\":1,\"n\":\"Axis\"},{\"t\":3,\"p\":1,\"n\":\"Casting Type\"},{\"t\":3,\"p\":1,\"n\":\"Cell\"},{\"t\":3,\"p\":1,\"n\":\"Class\"},{\"t\":3,\"p\":1,\"n\":\"Crime Type\"},{\"t\":3,\"p\":1,\"n\":\"Critical Stage\"},{\"t\":3,\"p\":1,\"n\":\"Encounter Zone\"},{\"t\":3,\"p\":1,\"n\":\"Equip Type\"},{\"t\":3,\"p\":1,\"n\":\"Event\"},{\"t\":3,\"p\":1,\"n\":\"Event Data\"},{\"t\":3,\"p\":1,\"n\":\"Faction\"},{\"t\":3,\"p\":1,\"n\":\"Form List\"},{\"t\":3,\"p\":1,\"n\":\"Form Type\"},{\"t\":3,\"p\":1,\"n\":\"Furniture\"},{\"t\":3,\"p\":1,\"n\":\"Furniture Anim\"},{\"t\":3,\"p\":1,\"n\":\"Furniture Entry\"},{\"t\":3,\"p\":1,\"n\":\"Global\"},{\"t\":3,\"p\":1,\"n\":\"Idle\"},{\"t\":3,\"p\":1,\"n\":\"Inventory Object\"},{\"t\":3,\"p\":1,\"n\":\"Keyword\"},{\"t\":3,\"p\":1,\"n\":\"Location\"},{\"t\":3,\"p\":1,\"n\":\"Base Effect\"},{\"t\":3,\"p\":1,\"n\":\"Effect Item\"},{\"t\":3,\"p\":1,\"n\":\"Misc Stat\"},{\"t\":3,\"p\":1,\"n\":\"Object Reference\"},{\"t\":3,\"p\":1,\"n\":\"Owner\"},{\"t\":3,\"p\":1,\"n\":\"Package\"},{\"t\":3,\"p\":1,\"n\":\"Packdata ID\"},{\"t\":3,\"p\":1,\"n\":\"Perk\"},{\"t\":3,\"p\":1,\"n\":\"Quest\"},{\"t\":3,\"p\":1,\"n\":\"Quest Stage\"},{\"t\":3,\"p\":1,\"n\":\"Race\"},{\"t\":3,\"p\":1,\"n\":\"Referenceable Object\"},{\"t\":3,\"p\":1,\"n\":\"Location Ref Type\"},{\"t\":3,\"p\":1,\"n\":\"Region\"},{\"t\":3,\"p\":1,\"n\":\"Scene\"},{\"t\":3,\"p\":1,\"n\":\"Sex\"},{\"t\":3,\"p\":1,\"n\":\"Shout\"},{\"t\":11,\"p\":1,\"n\":\"Variable Name (unused)\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Function\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Param (unused)\"},{\"t\":3,\"p\":1,\"n\":\"Voice Type\"},{\"t\":3,\"p\":1,\"n\":\"Ward State\"},{\"t\":3,\"p\":1,\"n\":\"Weather\"},{\"t\":3,\"p\":1,\"n\":\"Worldspace\"},{\"t\":3,\"p\":1,\"n\":\"Damage Type\"},{\"t\":3,\"p\":1,\"n\":\"Weapon\"},{\"t\":3,\"p\":1,\"n\":\"Weapon List\"},{\"t\":3,\"p\":1,\"n\":\"Target\"},{\"t\":3,\"p\":1,\"n\":\"Target List\"},{\"t\":3,\"p\":1,\"n\":\"Target Part\"},{\"t\":3,\"p\":1,\"n\":\"VATS Action\"},{\"t\":3,\"p\":1,\"n\":\"Critical Effect\"},{\"t\":3,\"p\":1,\"n\":\"Critical Effect List\"},{\"t\":3,\"p\":1,\"n\":\"Weapon Type\"},{\"t\":3,\"p\":1,\"n\":\"Projectile Type\"},{\"t\":3,\"p\":1,\"n\":\"Delivery Type\"},{\"t\":3,\"p\":1,\"n\":\"Run On\"},{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":3,\"p\":1,\"n\":\"Parameter #3\"}]},{\"t\":2,\"p\":1,\"n\":\"CIS1 - Parameter #1\"},{\"t\":2,\"p\":1,\"n\":\"CIS2 - Parameter #2\"}]}]}]},{\"p\":1,\"n\":\"NEXT - Marker\"},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Conditions\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Condition\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"CTDA - \",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":5,\"p\":1,\"n\":\"Comparison Value - Float\"},{\"t\":3,\"p\":1,\"n\":\"Comparison Value - Global\"},{\"t\":3,\"p\":1,\"n\":\"Function\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":11,\"p\":1,\"n\":\"None\"},{\"t\":3,\"p\":1,\"n\":\"Integer\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":3,\"p\":1,\"n\":\"Actor\"},{\"t\":3,\"p\":1,\"n\":\"Actor Base\"},{\"t\":3,\"p\":1,\"n\":\"Actor Value\"},{\"t\":3,\"p\":1,\"n\":\"Player Action\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"Alignment\"},{\"t\":3,\"p\":1,\"n\":\"Association Type\"},{\"t\":3,\"p\":1,\"n\":\"Axis\"},{\"t\":3,\"p\":1,\"n\":\"Casting Type\"},{\"t\":3,\"p\":1,\"n\":\"Cell\"},{\"t\":3,\"p\":1,\"n\":\"Class\"},{\"t\":3,\"p\":1,\"n\":\"Crime Type\"},{\"t\":3,\"p\":1,\"n\":\"Critical Stage\"},{\"t\":3,\"p\":1,\"n\":\"Encounter Zone\"},{\"t\":3,\"p\":1,\"n\":\"Equip Type\"},{\"t\":3,\"p\":1,\"n\":\"Event\"},{\"t\":3,\"p\":1,\"n\":\"Event Data\"},{\"t\":3,\"p\":1,\"n\":\"Faction\"},{\"t\":3,\"p\":1,\"n\":\"Form List\"},{\"t\":3,\"p\":1,\"n\":\"Form Type\"},{\"t\":3,\"p\":1,\"n\":\"Furniture\"},{\"t\":3,\"p\":1,\"n\":\"Furniture Anim\"},{\"t\":3,\"p\":1,\"n\":\"Furniture Entry\"},{\"t\":3,\"p\":1,\"n\":\"Global\"},{\"t\":3,\"p\":1,\"n\":\"Idle\"},{\"t\":3,\"p\":1,\"n\":\"Inventory Object\"},{\"t\":3,\"p\":1,\"n\":\"Keyword\"},{\"t\":3,\"p\":1,\"n\":\"Location\"},{\"t\":3,\"p\":1,\"n\":\"Base Effect\"},{\"t\":3,\"p\":1,\"n\":\"Effect Item\"},{\"t\":3,\"p\":1,\"n\":\"Misc Stat\"},{\"t\":3,\"p\":1,\"n\":\"Object Reference\"},{\"t\":3,\"p\":1,\"n\":\"Owner\"},{\"t\":3,\"p\":1,\"n\":\"Package\"},{\"t\":3,\"p\":1,\"n\":\"Packdata ID\"},{\"t\":3,\"p\":1,\"n\":\"Perk\"},{\"t\":3,\"p\":1,\"n\":\"Quest\"},{\"t\":3,\"p\":1,\"n\":\"Quest Stage\"},{\"t\":3,\"p\":1,\"n\":\"Race\"},{\"t\":3,\"p\":1,\"n\":\"Referenceable Object\"},{\"t\":3,\"p\":1,\"n\":\"Location Ref Type\"},{\"t\":3,\"p\":1,\"n\":\"Region\"},{\"t\":3,\"p\":1,\"n\":\"Scene\"},{\"t\":3,\"p\":1,\"n\":\"Sex\"},{\"t\":3,\"p\":1,\"n\":\"Shout\"},{\"t\":11,\"p\":1,\"n\":\"Variable Name (unused)\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Function\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Param (unused)\"},{\"t\":3,\"p\":1,\"n\":\"Voice Type\"},{\"t\":3,\"p\":1,\"n\":\"Ward State\"},{\"t\":3,\"p\":1,\"n\":\"Weather\"},{\"t\":3,\"p\":1,\"n\":\"Worldspace\"},{\"t\":3,\"p\":1,\"n\":\"Damage Type\"},{\"t\":3,\"p\":1,\"n\":\"Weapon\"},{\"t\":3,\"p\":1,\"n\":\"Weapon List\"},{\"t\":3,\"p\":1,\"n\":\"Target\"},{\"t\":3,\"p\":1,\"n\":\"Target List\"},{\"t\":3,\"p\":1,\"n\":\"Target Part\"},{\"t\":3,\"p\":1,\"n\":\"VATS Action\"},{\"t\":3,\"p\":1,\"n\":\"Critical Effect\"},{\"t\":3,\"p\":1,\"n\":\"Critical Effect List\"},{\"t\":3,\"p\":1,\"n\":\"Weapon Type\"},{\"t\":3,\"p\":1,\"n\":\"Projectile Type\"},{\"t\":3,\"p\":1,\"n\":\"Delivery Type\"},{\"t\":3,\"p\":1,\"n\":\"Run On\"},{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":3,\"p\":1,\"n\":\"Parameter #3\"}]},{\"t\":2,\"p\":1,\"n\":\"CIS1 - Parameter #1\"},{\"t\":2,\"p\":1,\"n\":\"CIS2 - Parameter #2\"}]}]},{\"t\":10,\"p\":1,\"n\":\"Stages\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Stage\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"INDX - Stage Index\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Stage Index\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":3,\"n\":\"Unknown\"}]},{\"t\":8,\"p\":1,\"n\":\"Log Entries\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Log Entry\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"QSDT - Stage Flags\"},{\"t\":8,\"p\":1,\"n\":\"Conditions\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Condition\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"CTDA - \",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":5,\"p\":1,\"n\":\"Comparison Value - Float\"},{\"t\":3,\"p\":1,\"n\":\"Comparison Value - Global\"},{\"t\":3,\"p\":1,\"n\":\"Function\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":11,\"p\":1,\"n\":\"None\"},{\"t\":3,\"p\":1,\"n\":\"Integer\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":3,\"p\":1,\"n\":\"Actor\"},{\"t\":3,\"p\":1,\"n\":\"Actor Base\"},{\"t\":3,\"p\":1,\"n\":\"Actor Value\"},{\"t\":3,\"p\":1,\"n\":\"Player Action\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"Alignment\"},{\"t\":3,\"p\":1,\"n\":\"Association Type\"},{\"t\":3,\"p\":1,\"n\":\"Axis\"},{\"t\":3,\"p\":1,\"n\":\"Casting Type\"},{\"t\":3,\"p\":1,\"n\":\"Cell\"},{\"t\":3,\"p\":1,\"n\":\"Class\"},{\"t\":3,\"p\":1,\"n\":\"Crime Type\"},{\"t\":3,\"p\":1,\"n\":\"Critical Stage\"},{\"t\":3,\"p\":1,\"n\":\"Encounter Zone\"},{\"t\":3,\"p\":1,\"n\":\"Equip Type\"},{\"t\":3,\"p\":1,\"n\":\"Event\"},{\"t\":3,\"p\":1,\"n\":\"Event Data\"},{\"t\":3,\"p\":1,\"n\":\"Faction\"},{\"t\":3,\"p\":1,\"n\":\"Form List\"},{\"t\":3,\"p\":1,\"n\":\"Form Type\"},{\"t\":3,\"p\":1,\"n\":\"Furniture\"},{\"t\":3,\"p\":1,\"n\":\"Furniture Anim\"},{\"t\":3,\"p\":1,\"n\":\"Furniture Entry\"},{\"t\":3,\"p\":1,\"n\":\"Global\"},{\"t\":3,\"p\":1,\"n\":\"Idle\"},{\"t\":3,\"p\":1,\"n\":\"Inventory Object\"},{\"t\":3,\"p\":1,\"n\":\"Keyword\"},{\"t\":3,\"p\":1,\"n\":\"Location\"},{\"t\":3,\"p\":1,\"n\":\"Base Effect\"},{\"t\":3,\"p\":1,\"n\":\"Effect Item\"},{\"t\":3,\"p\":1,\"n\":\"Misc Stat\"},{\"t\":3,\"p\":1,\"n\":\"Object Reference\"},{\"t\":3,\"p\":1,\"n\":\"Owner\"},{\"t\":3,\"p\":1,\"n\":\"Package\"},{\"t\":3,\"p\":1,\"n\":\"Packdata ID\"},{\"t\":3,\"p\":1,\"n\":\"Perk\"},{\"t\":3,\"p\":1,\"n\":\"Quest\"},{\"t\":3,\"p\":1,\"n\":\"Quest Stage\"},{\"t\":3,\"p\":1,\"n\":\"Race\"},{\"t\":3,\"p\":1,\"n\":\"Referenceable Object\"},{\"t\":3,\"p\":1,\"n\":\"Location Ref Type\"},{\"t\":3,\"p\":1,\"n\":\"Region\"},{\"t\":3,\"p\":1,\"n\":\"Scene\"},{\"t\":3,\"p\":1,\"n\":\"Sex\"},{\"t\":3,\"p\":1,\"n\":\"Shout\"},{\"t\":11,\"p\":1,\"n\":\"Variable Name (unused)\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Function\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Param (unused)\"},{\"t\":3,\"p\":1,\"n\":\"Voice Type\"},{\"t\":3,\"p\":1,\"n\":\"Ward State\"},{\"t\":3,\"p\":1,\"n\":\"Weather\"},{\"t\":3,\"p\":1,\"n\":\"Worldspace\"},{\"t\":3,\"p\":1,\"n\":\"Damage Type\"},{\"t\":3,\"p\":1,\"n\":\"Weapon\"},{\"t\":3,\"p\":1,\"n\":\"Weapon List\"},{\"t\":3,\"p\":1,\"n\":\"Target\"},{\"t\":3,\"p\":1,\"n\":\"Target List\"},{\"t\":3,\"p\":1,\"n\":\"Target Part\"},{\"t\":3,\"p\":1,\"n\":\"VATS Action\"},{\"t\":3,\"p\":1,\"n\":\"Critical Effect\"},{\"t\":3,\"p\":1,\"n\":\"Critical Effect List\"},{\"t\":3,\"p\":1,\"n\":\"Weapon Type\"},{\"t\":3,\"p\":1,\"n\":\"Projectile Type\"},{\"t\":3,\"p\":1,\"n\":\"Delivery Type\"},{\"t\":3,\"p\":1,\"n\":\"Run On\"},{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":3,\"p\":1,\"n\":\"Parameter #3\"}]},{\"t\":2,\"p\":1,\"n\":\"CIS1 - Parameter #1\"},{\"t\":2,\"p\":1,\"n\":\"CIS2 - Parameter #2\"}]}]},{\"t\":2,\"p\":1,\"n\":\"NAM2 - Note\"},{\"t\":2,\"p\":1,\"n\":\"CNAM - Log Entry\"},{\"t\":3,\"p\":1,\"n\":\"NAM0 - Next Quest\"}]}]}]}]},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Objectives\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Objective\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"QOBJ - Objective Index\"},{\"t\":3,\"p\":1,\"n\":\"FNAM - Flags\"},{\"t\":2,\"p\":1,\"n\":\"NNAM - Display Text\"},{\"t\":8,\"p\":1,\"n\":\"Targets\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Target\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"QSTA - Target\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":3,\"p\":1,\"n\":\"Keyword\"}]},{\"t\":8,\"p\":1,\"n\":\"Conditions\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Condition\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"CTDA - \",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":5,\"p\":1,\"n\":\"Comparison Value - Float\"},{\"t\":3,\"p\":1,\"n\":\"Comparison Value - Global\"},{\"t\":3,\"p\":1,\"n\":\"Function\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":11,\"p\":1,\"n\":\"None\"},{\"t\":3,\"p\":1,\"n\":\"Integer\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":3,\"p\":1,\"n\":\"Actor\"},{\"t\":3,\"p\":1,\"n\":\"Actor Base\"},{\"t\":3,\"p\":1,\"n\":\"Actor Value\"},{\"t\":3,\"p\":1,\"n\":\"Player Action\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"Alignment\"},{\"t\":3,\"p\":1,\"n\":\"Association Type\"},{\"t\":3,\"p\":1,\"n\":\"Axis\"},{\"t\":3,\"p\":1,\"n\":\"Casting Type\"},{\"t\":3,\"p\":1,\"n\":\"Cell\"},{\"t\":3,\"p\":1,\"n\":\"Class\"},{\"t\":3,\"p\":1,\"n\":\"Crime Type\"},{\"t\":3,\"p\":1,\"n\":\"Critical Stage\"},{\"t\":3,\"p\":1,\"n\":\"Encounter Zone\"},{\"t\":3,\"p\":1,\"n\":\"Equip Type\"},{\"t\":3,\"p\":1,\"n\":\"Event\"},{\"t\":3,\"p\":1,\"n\":\"Event Data\"},{\"t\":3,\"p\":1,\"n\":\"Faction\"},{\"t\":3,\"p\":1,\"n\":\"Form List\"},{\"t\":3,\"p\":1,\"n\":\"Form Type\"},{\"t\":3,\"p\":1,\"n\":\"Furniture\"},{\"t\":3,\"p\":1,\"n\":\"Furniture Anim\"},{\"t\":3,\"p\":1,\"n\":\"Furniture Entry\"},{\"t\":3,\"p\":1,\"n\":\"Global\"},{\"t\":3,\"p\":1,\"n\":\"Idle\"},{\"t\":3,\"p\":1,\"n\":\"Inventory Object\"},{\"t\":3,\"p\":1,\"n\":\"Keyword\"},{\"t\":3,\"p\":1,\"n\":\"Location\"},{\"t\":3,\"p\":1,\"n\":\"Base Effect\"},{\"t\":3,\"p\":1,\"n\":\"Effect Item\"},{\"t\":3,\"p\":1,\"n\":\"Misc Stat\"},{\"t\":3,\"p\":1,\"n\":\"Object Reference\"},{\"t\":3,\"p\":1,\"n\":\"Owner\"},{\"t\":3,\"p\":1,\"n\":\"Package\"},{\"t\":3,\"p\":1,\"n\":\"Packdata ID\"},{\"t\":3,\"p\":1,\"n\":\"Perk\"},{\"t\":3,\"p\":1,\"n\":\"Quest\"},{\"t\":3,\"p\":1,\"n\":\"Quest Stage\"},{\"t\":3,\"p\":1,\"n\":\"Race\"},{\"t\":3,\"p\":1,\"n\":\"Referenceable Object\"},{\"t\":3,\"p\":1,\"n\":\"Location Ref Type\"},{\"t\":3,\"p\":1,\"n\":\"Region\"},{\"t\":3,\"p\":1,\"n\":\"Scene\"},{\"t\":3,\"p\":1,\"n\":\"Sex\"},{\"t\":3,\"p\":1,\"n\":\"Shout\"},{\"t\":11,\"p\":1,\"n\":\"Variable Name (unused)\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Function\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Param (unused)\"},{\"t\":3,\"p\":1,\"n\":\"Voice Type\"},{\"t\":3,\"p\":1,\"n\":\"Ward State\"},{\"t\":3,\"p\":1,\"n\":\"Weather\"},{\"t\":3,\"p\":1,\"n\":\"Worldspace\"},{\"t\":3,\"p\":1,\"n\":\"Damage Type\"},{\"t\":3,\"p\":1,\"n\":\"Weapon\"},{\"t\":3,\"p\":1,\"n\":\"Weapon List\"},{\"t\":3,\"p\":1,\"n\":\"Target\"},{\"t\":3,\"p\":1,\"n\":\"Target List\"},{\"t\":3,\"p\":1,\"n\":\"Target Part\"},{\"t\":3,\"p\":1,\"n\":\"VATS Action\"},{\"t\":3,\"p\":1,\"n\":\"Critical Effect\"},{\"t\":3,\"p\":1,\"n\":\"Critical Effect List\"},{\"t\":3,\"p\":1,\"n\":\"Weapon Type\"},{\"t\":3,\"p\":1,\"n\":\"Projectile Type\"},{\"t\":3,\"p\":1,\"n\":\"Delivery Type\"},{\"t\":3,\"p\":1,\"n\":\"Run On\"},{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":3,\"p\":1,\"n\":\"Parameter #3\"}]},{\"t\":2,\"p\":1,\"n\":\"CIS1 - Parameter #1\"},{\"t\":2,\"p\":1,\"n\":\"CIS2 - Parameter #2\"}]}]}]}]}]}]},{\"t\":11,\"n\":\"ANAM - Aliases Marker\"},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Aliases\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alias\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"ALST - Reference Alias ID\"},{\"t\":2,\"p\":1,\"n\":\"ALID - Alias Name\"},{\"t\":3,\"p\":1,\"n\":\"FNAM - Flags\"},{\"t\":3,\"p\":1,\"n\":\"ALFI - Force Into Alias When Filled\"},{\"t\":3,\"p\":1,\"n\":\"ALFR - Forced Reference\"},{\"t\":3,\"p\":1,\"n\":\"ALUA - Unique Actor\"},{\"t\":6,\"p\":1,\"n\":\"Location Alias Reference\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"ALFA - Alias\"},{\"t\":3,\"p\":1,\"n\":\"KNAM - Keyword\"},{\"t\":3,\"p\":1,\"n\":\"ALRT - Ref Type\"}]},{\"t\":6,\"p\":1,\"n\":\"External Alias Reference\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"ALEQ - Quest\"},{\"t\":3,\"p\":1,\"n\":\"ALEA - Alias\"}]},{\"t\":6,\"p\":1,\"n\":\"Create Reference to Object\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"ALCO - Object\"},{\"t\":6,\"p\":1,\"n\":\"ALCA - Alias\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"Create\"}]},{\"t\":3,\"p\":1,\"n\":\"ALCL - Level\"}]},{\"t\":6,\"p\":1,\"n\":\"Find Matching Reference Near Alias\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"ALNA - Alias\"},{\"t\":3,\"p\":1,\"n\":\"ALNT - Type\"}]},{\"t\":6,\"p\":1,\"n\":\"Find Matching Reference From Event\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"ALFE - From Event\"},{\"t\":11,\"p\":1,\"n\":\"ALFD - Event Data\"}]},{\"t\":3,\"p\":1,\"n\":\"ALCC - Closest To Alias\"},{\"t\":8,\"p\":1,\"n\":\"Conditions\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Condition\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"CTDA - \",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":5,\"p\":1,\"n\":\"Comparison Value - Float\"},{\"t\":3,\"p\":1,\"n\":\"Comparison Value - Global\"},{\"t\":3,\"p\":1,\"n\":\"Function\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":11,\"p\":1,\"n\":\"None\"},{\"t\":3,\"p\":1,\"n\":\"Integer\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":3,\"p\":1,\"n\":\"Actor\"},{\"t\":3,\"p\":1,\"n\":\"Actor Base\"},{\"t\":3,\"p\":1,\"n\":\"Actor Value\"},{\"t\":3,\"p\":1,\"n\":\"Player Action\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"Alignment\"},{\"t\":3,\"p\":1,\"n\":\"Association Type\"},{\"t\":3,\"p\":1,\"n\":\"Axis\"},{\"t\":3,\"p\":1,\"n\":\"Casting Type\"},{\"t\":3,\"p\":1,\"n\":\"Cell\"},{\"t\":3,\"p\":1,\"n\":\"Class\"},{\"t\":3,\"p\":1,\"n\":\"Crime Type\"},{\"t\":3,\"p\":1,\"n\":\"Critical Stage\"},{\"t\":3,\"p\":1,\"n\":\"Encounter Zone\"},{\"t\":3,\"p\":1,\"n\":\"Equip Type\"},{\"t\":3,\"p\":1,\"n\":\"Event\"},{\"t\":3,\"p\":1,\"n\":\"Event Data\"},{\"t\":3,\"p\":1,\"n\":\"Faction\"},{\"t\":3,\"p\":1,\"n\":\"Form List\"},{\"t\":3,\"p\":1,\"n\":\"Form Type\"},{\"t\":3,\"p\":1,\"n\":\"Furniture\"},{\"t\":3,\"p\":1,\"n\":\"Furniture Anim\"},{\"t\":3,\"p\":1,\"n\":\"Furniture Entry\"},{\"t\":3,\"p\":1,\"n\":\"Global\"},{\"t\":3,\"p\":1,\"n\":\"Idle\"},{\"t\":3,\"p\":1,\"n\":\"Inventory Object\"},{\"t\":3,\"p\":1,\"n\":\"Keyword\"},{\"t\":3,\"p\":1,\"n\":\"Location\"},{\"t\":3,\"p\":1,\"n\":\"Base Effect\"},{\"t\":3,\"p\":1,\"n\":\"Effect Item\"},{\"t\":3,\"p\":1,\"n\":\"Misc Stat\"},{\"t\":3,\"p\":1,\"n\":\"Object Reference\"},{\"t\":3,\"p\":1,\"n\":\"Owner\"},{\"t\":3,\"p\":1,\"n\":\"Package\"},{\"t\":3,\"p\":1,\"n\":\"Packdata ID\"},{\"t\":3,\"p\":1,\"n\":\"Perk\"},{\"t\":3,\"p\":1,\"n\":\"Quest\"},{\"t\":3,\"p\":1,\"n\":\"Quest Stage\"},{\"t\":3,\"p\":1,\"n\":\"Race\"},{\"t\":3,\"p\":1,\"n\":\"Referenceable Object\"},{\"t\":3,\"p\":1,\"n\":\"Location Ref Type\"},{\"t\":3,\"p\":1,\"n\":\"Region\"},{\"t\":3,\"p\":1,\"n\":\"Scene\"},{\"t\":3,\"p\":1,\"n\":\"Sex\"},{\"t\":3,\"p\":1,\"n\":\"Shout\"},{\"t\":11,\"p\":1,\"n\":\"Variable Name (unused)\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Function\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Param (unused)\"},{\"t\":3,\"p\":1,\"n\":\"Voice Type\"},{\"t\":3,\"p\":1,\"n\":\"Ward State\"},{\"t\":3,\"p\":1,\"n\":\"Weather\"},{\"t\":3,\"p\":1,\"n\":\"Worldspace\"},{\"t\":3,\"p\":1,\"n\":\"Damage Type\"},{\"t\":3,\"p\":1,\"n\":\"Weapon\"},{\"t\":3,\"p\":1,\"n\":\"Weapon List\"},{\"t\":3,\"p\":1,\"n\":\"Target\"},{\"t\":3,\"p\":1,\"n\":\"Target List\"},{\"t\":3,\"p\":1,\"n\":\"Target Part\"},{\"t\":3,\"p\":1,\"n\":\"VATS Action\"},{\"t\":3,\"p\":1,\"n\":\"Critical Effect\"},{\"t\":3,\"p\":1,\"n\":\"Critical Effect List\"},{\"t\":3,\"p\":1,\"n\":\"Weapon Type\"},{\"t\":3,\"p\":1,\"n\":\"Projectile Type\"},{\"t\":3,\"p\":1,\"n\":\"Delivery Type\"},{\"t\":3,\"p\":1,\"n\":\"Run On\"},{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":3,\"p\":1,\"n\":\"Parameter #3\"}]},{\"t\":2,\"p\":1,\"n\":\"CIS1 - Parameter #1\"},{\"t\":2,\"p\":1,\"n\":\"CIS2 - Parameter #2\"}]}]},{\"t\":3,\"p\":1,\"n\":\"KSIZ - Keyword Count\"},{\"t\":7,\"p\":1,\"n\":\"KWDA - Keywords\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Keyword\"}]},{\"t\":3,\"p\":1,\"n\":\"COCT - Count\"},{\"t\":10,\"p\":1,\"n\":\"Items\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Item\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"CNTO - Item\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Item\"},{\"t\":3,\"p\":1,\"n\":\"Count\"}]},{\"t\":6,\"p\":1,\"n\":\"COED - Extra Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Owner\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Global Variable\"},{\"t\":3,\"p\":1,\"n\":\"Required Rank\"},{\"t\":5,\"p\":1,\"n\":\"Item Condition\"}]}]}]},{\"t\":3,\"p\":1,\"n\":\"SPOR - Spectator override package list\"},{\"t\":3,\"p\":1,\"n\":\"OCOR - Observe dead body override package list\"},{\"t\":3,\"p\":1,\"n\":\"GWOR - Guard warn override package list\"},{\"t\":3,\"p\":1,\"n\":\"ECOR - Combat override package list\"},{\"t\":7,\"p\":1,\"n\":\"ALLA - Linked Aliases\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Linked Alias\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Keyword\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"}]}]},{\"t\":3,\"p\":1,\"n\":\"ALDN - Display Name\"},{\"t\":3,\"p\":1,\"n\":\"ALFV - Forced Voice\"},{\"t\":3,\"p\":1,\"n\":\"ALDI - Death Item\"},{\"t\":8,\"p\":1,\"n\":\"Alias Spells\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"ALSP - Spell\"}]},{\"t\":8,\"p\":1,\"n\":\"Alias Factions\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"ALFC - Faction\"}]},{\"t\":8,\"p\":1,\"n\":\"Alias Package Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"ALPC - Package\"}]},{\"t\":3,\"p\":1,\"n\":\"VTCK - Voice Types\"},{\"p\":1,\"n\":\"ALED - Alias End\"}]}]},{\"t\":2,\"p\":1,\"n\":\"NNAM - Description\"},{\"t\":3,\"p\":1,\"n\":\"GNAM - Quest Group\"},{\"t\":2,\"p\":1,\"n\":\"SNAM - SWF File\"}]},{\"t\":1,\"n\":\"RACE - Race\",\"c\":[{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":3,\"n\":\"STCP - Sound\"},{\"t\":2,\"n\":\"FULL - Name\"},{\"t\":2,\"n\":\"DESC - Description\"},{\"t\":3,\"n\":\"SPCT - Count\"},{\"t\":8,\"n\":\"Actor Effects\",\"c\":[{\"t\":3,\"n\":\"SPLO - Actor Effect\"}]},{\"t\":3,\"n\":\"WNAM - Skin\"},{\"t\":6,\"n\":\"BOD2 - Biped Body Template\",\"c\":[{\"t\":3,\"n\":\"First Person Flags\"}]},{\"t\":3,\"n\":\"KSIZ - Keyword Count\"},{\"t\":7,\"n\":\"KWDA - Keywords\",\"c\":[{\"t\":3,\"n\":\"Keyword\"}]},{\"t\":7,\"n\":\"PRPS - Properties\",\"c\":[{\"t\":6,\"n\":\"Property\",\"c\":[{\"t\":3,\"n\":\"Actor Value\"},{\"t\":5,\"n\":\"Value\"}]}]},{\"t\":7,\"n\":\"APPR - Attach Parent Slots\",\"c\":[{\"t\":3,\"n\":\"Keyword\"}]},{\"t\":6,\"n\":\"DATA - Data\",\"c\":[{\"t\":5,\"n\":\"Male Height\"},{\"t\":5,\"n\":\"Female Height\"},{\"t\":6,\"n\":\"Male Default Weight\",\"c\":[{\"t\":5,\"n\":\"Thin\"},{\"t\":5,\"n\":\"Muscular\"},{\"t\":5,\"n\":\"Fat\"}]},{\"t\":6,\"n\":\"Female Default Weight\",\"c\":[{\"t\":5,\"n\":\"Thin\"},{\"t\":5,\"n\":\"Muscular\"},{\"t\":5,\"n\":\"Fat\"}]},{\"t\":3,\"n\":\"Flags\"},{\"t\":5,\"n\":\"Acceleration Rate\"},{\"t\":5,\"n\":\"Deceleration Rate\"},{\"t\":3,\"n\":\"Size\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":5,\"n\":\"Injured Health Pct\"},{\"t\":3,\"n\":\"Shield Biped Object\"},{\"t\":3,\"n\":\"Beard Biped Object\"},{\"t\":3,\"n\":\"Body Biped Object\"},{\"t\":5,\"n\":\"Aim Angle Tolerance\"},{\"t\":5,\"n\":\"Flight Radius\"},{\"t\":5,\"n\":\"Angular Acceleration Rate\"},{\"t\":5,\"n\":\"Angular Tolerance\"},{\"t\":3,\"n\":\"Flags 2\"},{\"t\":3,\"n\":\"Pipboy Biped Object\"},{\"t\":3,\"n\":\"XP Value\"},{\"t\":5,\"n\":\"Severable - Debris Scale\"},{\"t\":3,\"n\":\"Severable - Debris Count\"},{\"t\":3,\"n\":\"Severable - Decal Count\"},{\"t\":5,\"n\":\"Explodable - Debris Scale\"},{\"t\":3,\"n\":\"Explodable - Debris Count\"},{\"t\":3,\"n\":\"Explodable - Decal Count\"},{\"t\":3,\"n\":\"Severable - Explosion\"},{\"t\":3,\"n\":\"Severable - Debris\"},{\"t\":3,\"n\":\"Severable - Impact DataSet\"},{\"t\":3,\"n\":\"Explodable - Explosion\"},{\"t\":3,\"n\":\"Explodable - Debris\"},{\"t\":3,\"n\":\"Explodable - Impact DataSet\"},{\"t\":5,\"n\":\"OnCripple - Debris Scale\"},{\"t\":3,\"n\":\"OnCripple - Debris Count\"},{\"t\":3,\"n\":\"OnCripple - Decal Count\"},{\"t\":3,\"n\":\"OnCripple - Explosion\"},{\"t\":3,\"n\":\"OnCripple - Debris\"},{\"t\":3,\"n\":\"OnCripple - Impact DataSet\"},{\"t\":3,\"n\":\"Explodable - Subsegment Explosion\"},{\"t\":5,\"n\":\"Orientation Limits - Pitch\"},{\"t\":5,\"n\":\"Orientation Limits - Roll\"}]},{\"n\":\"MNAM - Male Marker\"},{\"t\":2,\"n\":\"ANAM - Male Skeletal Model\"},{\"t\":11,\"n\":\"MODT - Texture Files Hashes\"},{\"n\":\"FNAM - Female Marker\"},{\"t\":2,\"n\":\"ANAM - Female Skeletal Model\"},{\"n\":\"NAM2 - Marker NAM2 #1\"},{\"t\":8,\"n\":\"Movement Type Names\",\"c\":[{\"t\":2,\"n\":\"MTNM - Name\"}]},{\"t\":7,\"n\":\"VTCK - Voices\",\"c\":[{\"t\":3,\"n\":\"Voice\"}]},{\"t\":7,\"n\":\"HCLF - Default Hair Colors\",\"c\":[{\"t\":3,\"n\":\"Default Hair Color\"}]},{\"t\":3,\"n\":\"TINL - Total Number of Tints in List\"},{\"t\":5,\"n\":\"PNAM - FaceGen - Main clamp\"},{\"t\":5,\"n\":\"UNAM - FaceGen - Face clamp\"},{\"t\":3,\"n\":\"ATKR - Attack Race\"},{\"t\":10,\"n\":\"Attacks\",\"c\":[{\"t\":6,\"n\":\"Attack\",\"c\":[{\"t\":6,\"n\":\"ATKD - Attack Data\",\"c\":[{\"t\":5,\"n\":\"Damage Mult\"},{\"t\":5,\"n\":\"Attack Chance\"},{\"t\":3,\"n\":\"Attack Spell\"},{\"t\":3,\"n\":\"Attack Flags\"},{\"t\":5,\"n\":\"Attack Angle\"},{\"t\":5,\"n\":\"Strike Angle\"},{\"t\":5,\"n\":\"Stagger\"},{\"t\":5,\"n\":\"Knockdown\"},{\"t\":5,\"n\":\"Recovery Time\"},{\"t\":5,\"n\":\"Action Points Mult\"},{\"t\":3,\"n\":\"Stagger Offset\"}]},{\"t\":2,\"n\":\"ATKE - Attack Event\"},{\"t\":3,\"n\":\"ATKW - Weapon Slot\"},{\"t\":3,\"n\":\"ATKS - Required Slot\"},{\"t\":2,\"n\":\"ATKT - Description\"}]}]},{\"t\":6,\"n\":\"Body Data\",\"c\":[{\"n\":\"NAM1 - Body Data Marker\"},{\"t\":6,\"n\":\"Male Body Data\",\"c\":[{\"n\":\"MNAM - Male Data Marker\"},{\"t\":10,\"n\":\"Parts\",\"c\":[{\"t\":6,\"n\":\"Part\",\"c\":[{\"t\":3,\"n\":\"INDX - Index\"},{\"t\":6,\"n\":\"Model\",\"c\":[{\"t\":2,\"n\":\"MODL - Model Filename\"},{\"t\":11,\"n\":\"MODT - Texture Files Hashes\"},{\"t\":3,\"n\":\"MODS - Material Swap\"},{\"t\":5,\"n\":\"MODC - Color Remapping Index\"},{\"t\":11,\"n\":\"MODF - Unknown\"}]}]}]}]},{\"t\":6,\"n\":\"Female Body Data\",\"c\":[{\"n\":\"FNAM - Female Data Marker\"},{\"t\":10,\"n\":\"Parts\",\"c\":[{\"t\":6,\"n\":\"Part\",\"c\":[{\"t\":3,\"n\":\"INDX - Index\"},{\"t\":6,\"n\":\"Model\",\"c\":[{\"t\":2,\"n\":\"MODL - Model Filename\"},{\"t\":11,\"n\":\"MODT - Texture Files Hashes\"},{\"t\":3,\"n\":\"MODS - Material Swap\"},{\"t\":5,\"n\":\"MODC - Color Remapping Index\"},{\"t\":11,\"n\":\"MODF - Unknown\"}]}]}]}]}]},{\"t\":3,\"n\":\"GNAM - Body Part Data\"},{\"n\":\"NAM2 - Marker NAM2 #2\"},{\"n\":\"NAM3 - Marker NAM3 #3\"},{\"t\":6,\"n\":\"Male Behavior Graph\",\"c\":[{\"n\":\"MNAM - Male Data Marker\"},{\"t\":6,\"n\":\"Model\",\"c\":[{\"t\":2,\"n\":\"MODL - Model Filename\"},{\"t\":11,\"n\":\"MODT - Texture Files Hashes\"},{\"t\":3,\"n\":\"MODS - Material Swap\"},{\"t\":5,\"n\":\"MODC - Color Remapping Index\"},{\"t\":11,\"n\":\"MODF - Unknown\"}]}]},{\"t\":6,\"n\":\"Female Behavior Graph\",\"c\":[{\"n\":\"FNAM - Female Data Marker\"},{\"t\":6,\"n\":\"Model\",\"c\":[{\"t\":2,\"n\":\"MODL - Model Filename\"},{\"t\":11,\"n\":\"MODT - Texture Files Hashes\"},{\"t\":3,\"n\":\"MODS - Material Swap\"},{\"t\":5,\"n\":\"MODC - Color Remapping Index\"},{\"t\":11,\"n\":\"MODF - Unknown\"}]}]},{\"t\":3,\"n\":\"NAM4 - Impact Material Type\"},{\"t\":3,\"n\":\"NAM5 - Impact Data Set\"},{\"t\":3,\"n\":\"NAM7 - Dismember Blood Art\"},{\"t\":3,\"n\":\"CNAM - Meat Cap TextureSet\"},{\"t\":3,\"n\":\"NAM2 - Collar TextureSet\"},{\"t\":3,\"n\":\"ONAM - Sound - Open Corpse\"},{\"t\":3,\"n\":\"LNAM - Sound - Close Corpse\"},{\"t\":8,\"n\":\"Biped Object Names\",\"c\":[{\"t\":2,\"n\":\"NAME - Name\"}]},{\"t\":7,\"n\":\"RBPC - Biped Object Conditions\",\"c\":[{\"t\":3,\"n\":\"Slot 30+\"}]},{\"t\":10,\"n\":\"Movement Data Overrides\",\"c\":[{\"t\":6,\"n\":\"Override\",\"c\":[{\"t\":3,\"n\":\"MTYP - Movement Type\"},{\"t\":6,\"n\":\"SPED - Movement Data\",\"c\":[{\"t\":5,\"n\":\"Unknown\"},{\"t\":5,\"n\":\"Walk - Left\"},{\"t\":5,\"n\":\"Run - Left\"},{\"t\":5,\"n\":\"Walk - Right\"},{\"t\":5,\"n\":\"Run - Right\"},{\"t\":5,\"n\":\"Walk - Forward\"},{\"t\":5,\"n\":\"Run - Forward\"},{\"t\":5,\"n\":\"Sprint - Forward\"},{\"t\":5,\"n\":\"Walk - Back\"},{\"t\":5,\"n\":\"Run - Back\"},{\"t\":5,\"n\":\"Standing - Pitch\"},{\"t\":5,\"n\":\"Walk - Pitch\"},{\"t\":5,\"n\":\"Run - Pitch\"},{\"t\":5,\"n\":\"Sprint - Pitch\"},{\"t\":5,\"n\":\"Standing - Yaw\"},{\"t\":5,\"n\":\"Walk - Yaw\"},{\"t\":5,\"n\":\"Run - Yaw\"},{\"t\":5,\"n\":\"Sprint - Yaw\"}]}]}]},{\"t\":3,\"n\":\"VNAM - Equipment Flags\"},{\"t\":8,\"n\":\"Equip Slots\",\"c\":[{\"t\":6,\"n\":\"Equip Slot\",\"c\":[{\"t\":3,\"n\":\"QNAM - Equip Slot\"},{\"t\":2,\"n\":\"ZNAM - Node\"}]}]},{\"t\":3,\"n\":\"UNWP - Unarmed Weapon\"},{\"t\":8,\"n\":\"Phoneme Target Names\",\"c\":[{\"t\":2,\"n\":\"PHTN - Name\"}]},{\"t\":6,\"n\":\"FaceFX Phonemes\",\"c\":[{\"t\":6,\"n\":\"IY\",\"c\":[{\"t\":6,\"n\":\"PHWT - Phoneme Target Weight\",\"c\":[{\"t\":5,\"n\":\"Aah \\/ LipBigAah\"},{\"t\":5,\"n\":\"BigAah \\/ LipDST\"},{\"t\":5,\"n\":\"BMP \\/ LipEee\"},{\"t\":5,\"n\":\"ChJsh \\/ LipFV\"},{\"t\":5,\"n\":\"DST \\/ LipK\"},{\"t\":5,\"n\":\"Eee \\/ LipL\"},{\"t\":5,\"n\":\"Eh \\/ LipR\"},{\"t\":5,\"n\":\"FV \\/ LipTh\"},{\"t\":5,\"n\":\"I\"},{\"t\":5,\"n\":\"K\"},{\"t\":5,\"n\":\"N\"},{\"t\":5,\"n\":\"Oh\"},{\"t\":5,\"n\":\"OohQ\"},{\"t\":5,\"n\":\"R\"},{\"t\":5,\"n\":\"TH\"},{\"t\":5,\"n\":\"W\"},{\"t\":11,\"n\":\"Unknown\"}]}]},{\"t\":6,\"n\":\"IH\",\"c\":[{\"t\":6,\"n\":\"PHWT - Phoneme Target Weight\",\"c\":[{\"t\":5,\"n\":\"Aah \\/ LipBigAah\"},{\"t\":5,\"n\":\"BigAah \\/ LipDST\"},{\"t\":5,\"n\":\"BMP \\/ LipEee\"},{\"t\":5,\"n\":\"ChJsh \\/ LipFV\"},{\"t\":5,\"n\":\"DST \\/ LipK\"},{\"t\":5,\"n\":\"Eee \\/ LipL\"},{\"t\":5,\"n\":\"Eh \\/ LipR\"},{\"t\":5,\"n\":\"FV \\/ LipTh\"},{\"t\":5,\"n\":\"I\"},{\"t\":5,\"n\":\"K\"},{\"t\":5,\"n\":\"N\"},{\"t\":5,\"n\":\"Oh\"},{\"t\":5,\"n\":\"OohQ\"},{\"t\":5,\"n\":\"R\"},{\"t\":5,\"n\":\"TH\"},{\"t\":5,\"n\":\"W\"},{\"t\":11,\"n\":\"Unknown\"}]}]},{\"t\":6,\"n\":\"EH\",\"c\":[{\"t\":6,\"n\":\"PHWT - Phoneme Target Weight\",\"c\":[{\"t\":5,\"n\":\"Aah \\/ LipBigAah\"},{\"t\":5,\"n\":\"BigAah \\/ LipDST\"},{\"t\":5,\"n\":\"BMP \\/ LipEee\"},{\"t\":5,\"n\":\"ChJsh \\/ LipFV\"},{\"t\":5,\"n\":\"DST \\/ LipK\"},{\"t\":5,\"n\":\"Eee \\/ LipL\"},{\"t\":5,\"n\":\"Eh \\/ LipR\"},{\"t\":5,\"n\":\"FV \\/ LipTh\"},{\"t\":5,\"n\":\"I\"},{\"t\":5,\"n\":\"K\"},{\"t\":5,\"n\":\"N\"},{\"t\":5,\"n\":\"Oh\"},{\"t\":5,\"n\":\"OohQ\"},{\"t\":5,\"n\":\"R\"},{\"t\":5,\"n\":\"TH\"},{\"t\":5,\"n\":\"W\"},{\"t\":11,\"n\":\"Unknown\"}]}]},{\"t\":6,\"n\":\"EY\",\"c\":[{\"t\":6,\"n\":\"PHWT - Phoneme Target Weight\",\"c\":[{\"t\":5,\"n\":\"Aah \\/ LipBigAah\"},{\"t\":5,\"n\":\"BigAah \\/ LipDST\"},{\"t\":5,\"n\":\"BMP \\/ LipEee\"},{\"t\":5,\"n\":\"ChJsh \\/ LipFV\"},{\"t\":5,\"n\":\"DST \\/ LipK\"},{\"t\":5,\"n\":\"Eee \\/ LipL\"},{\"t\":5,\"n\":\"Eh \\/ LipR\"},{\"t\":5,\"n\":\"FV \\/ LipTh\"},{\"t\":5,\"n\":\"I\"},{\"t\":5,\"n\":\"K\"},{\"t\":5,\"n\":\"N\"},{\"t\":5,\"n\":\"Oh\"},{\"t\":5,\"n\":\"OohQ\"},{\"t\":5,\"n\":\"R\"},{\"t\":5,\"n\":\"TH\"},{\"t\":5,\"n\":\"W\"},{\"t\":11,\"n\":\"Unknown\"}]}]},{\"t\":6,\"n\":\"AE\",\"c\":[{\"t\":6,\"n\":\"PHWT - Phoneme Target Weight\",\"c\":[{\"t\":5,\"n\":\"Aah \\/ LipBigAah\"},{\"t\":5,\"n\":\"BigAah \\/ LipDST\"},{\"t\":5,\"n\":\"BMP \\/ LipEee\"},{\"t\":5,\"n\":\"ChJsh \\/ LipFV\"},{\"t\":5,\"n\":\"DST \\/ LipK\"},{\"t\":5,\"n\":\"Eee \\/ LipL\"},{\"t\":5,\"n\":\"Eh \\/ LipR\"},{\"t\":5,\"n\":\"FV \\/ LipTh\"},{\"t\":5,\"n\":\"I\"},{\"t\":5,\"n\":\"K\"},{\"t\":5,\"n\":\"N\"},{\"t\":5,\"n\":\"Oh\"},{\"t\":5,\"n\":\"OohQ\"},{\"t\":5,\"n\":\"R\"},{\"t\":5,\"n\":\"TH\"},{\"t\":5,\"n\":\"W\"},{\"t\":11,\"n\":\"Unknown\"}]}]},{\"t\":6,\"n\":\"AA\",\"c\":[{\"t\":6,\"n\":\"PHWT - Phoneme Target Weight\",\"c\":[{\"t\":5,\"n\":\"Aah \\/ LipBigAah\"},{\"t\":5,\"n\":\"BigAah \\/ LipDST\"},{\"t\":5,\"n\":\"BMP \\/ LipEee\"},{\"t\":5,\"n\":\"ChJsh \\/ LipFV\"},{\"t\":5,\"n\":\"DST \\/ LipK\"},{\"t\":5,\"n\":\"Eee \\/ LipL\"},{\"t\":5,\"n\":\"Eh \\/ LipR\"},{\"t\":5,\"n\":\"FV \\/ LipTh\"},{\"t\":5,\"n\":\"I\"},{\"t\":5,\"n\":\"K\"},{\"t\":5,\"n\":\"N\"},{\"t\":5,\"n\":\"Oh\"},{\"t\":5,\"n\":\"OohQ\"},{\"t\":5,\"n\":\"R\"},{\"t\":5,\"n\":\"TH\"},{\"t\":5,\"n\":\"W\"},{\"t\":11,\"n\":\"Unknown\"}]}]},{\"t\":6,\"n\":\"AW\",\"c\":[{\"t\":6,\"n\":\"PHWT - Phoneme Target Weight\",\"c\":[{\"t\":5,\"n\":\"Aah \\/ LipBigAah\"},{\"t\":5,\"n\":\"BigAah \\/ LipDST\"},{\"t\":5,\"n\":\"BMP \\/ LipEee\"},{\"t\":5,\"n\":\"ChJsh \\/ LipFV\"},{\"t\":5,\"n\":\"DST \\/ LipK\"},{\"t\":5,\"n\":\"Eee \\/ LipL\"},{\"t\":5,\"n\":\"Eh \\/ LipR\"},{\"t\":5,\"n\":\"FV \\/ LipTh\"},{\"t\":5,\"n\":\"I\"},{\"t\":5,\"n\":\"K\"},{\"t\":5,\"n\":\"N\"},{\"t\":5,\"n\":\"Oh\"},{\"t\":5,\"n\":\"OohQ\"},{\"t\":5,\"n\":\"R\"},{\"t\":5,\"n\":\"TH\"},{\"t\":5,\"n\":\"W\"},{\"t\":11,\"n\":\"Unknown\"}]}]},{\"t\":6,\"n\":\"AY\",\"c\":[{\"t\":6,\"n\":\"PHWT - Phoneme Target Weight\",\"c\":[{\"t\":5,\"n\":\"Aah \\/ LipBigAah\"},{\"t\":5,\"n\":\"BigAah \\/ LipDST\"},{\"t\":5,\"n\":\"BMP \\/ LipEee\"},{\"t\":5,\"n\":\"ChJsh \\/ LipFV\"},{\"t\":5,\"n\":\"DST \\/ LipK\"},{\"t\":5,\"n\":\"Eee \\/ LipL\"},{\"t\":5,\"n\":\"Eh \\/ LipR\"},{\"t\":5,\"n\":\"FV \\/ LipTh\"},{\"t\":5,\"n\":\"I\"},{\"t\":5,\"n\":\"K\"},{\"t\":5,\"n\":\"N\"},{\"t\":5,\"n\":\"Oh\"},{\"t\":5,\"n\":\"OohQ\"},{\"t\":5,\"n\":\"R\"},{\"t\":5,\"n\":\"TH\"},{\"t\":5,\"n\":\"W\"},{\"t\":11,\"n\":\"Unknown\"}]}]},{\"t\":6,\"n\":\"AH\",\"c\":[{\"t\":6,\"n\":\"PHWT - Phoneme Target Weight\",\"c\":[{\"t\":5,\"n\":\"Aah \\/ LipBigAah\"},{\"t\":5,\"n\":\"BigAah \\/ LipDST\"},{\"t\":5,\"n\":\"BMP \\/ LipEee\"},{\"t\":5,\"n\":\"ChJsh \\/ LipFV\"},{\"t\":5,\"n\":\"DST \\/ LipK\"},{\"t\":5,\"n\":\"Eee \\/ LipL\"},{\"t\":5,\"n\":\"Eh \\/ LipR\"},{\"t\":5,\"n\":\"FV \\/ LipTh\"},{\"t\":5,\"n\":\"I\"},{\"t\":5,\"n\":\"K\"},{\"t\":5,\"n\":\"N\"},{\"t\":5,\"n\":\"Oh\"},{\"t\":5,\"n\":\"OohQ\"},{\"t\":5,\"n\":\"R\"},{\"t\":5,\"n\":\"TH\"},{\"t\":5,\"n\":\"W\"},{\"t\":11,\"n\":\"Unknown\"}]}]},{\"t\":6,\"n\":\"AO\",\"c\":[{\"t\":6,\"n\":\"PHWT - Phoneme Target Weight\",\"c\":[{\"t\":5,\"n\":\"Aah \\/ LipBigAah\"},{\"t\":5,\"n\":\"BigAah \\/ LipDST\"},{\"t\":5,\"n\":\"BMP \\/ LipEee\"},{\"t\":5,\"n\":\"ChJsh \\/ LipFV\"},{\"t\":5,\"n\":\"DST \\/ LipK\"},{\"t\":5,\"n\":\"Eee \\/ LipL\"},{\"t\":5,\"n\":\"Eh \\/ LipR\"},{\"t\":5,\"n\":\"FV \\/ LipTh\"},{\"t\":5,\"n\":\"I\"},{\"t\":5,\"n\":\"K\"},{\"t\":5,\"n\":\"N\"},{\"t\":5,\"n\":\"Oh\"},{\"t\":5,\"n\":\"OohQ\"},{\"t\":5,\"n\":\"R\"},{\"t\":5,\"n\":\"TH\"},{\"t\":5,\"n\":\"W\"},{\"t\":11,\"n\":\"Unknown\"}]}]},{\"t\":6,\"n\":\"OY\",\"c\":[{\"t\":6,\"n\":\"PHWT - Phoneme Target Weight\",\"c\":[{\"t\":5,\"n\":\"Aah \\/ LipBigAah\"},{\"t\":5,\"n\":\"BigAah \\/ LipDST\"},{\"t\":5,\"n\":\"BMP \\/ LipEee\"},{\"t\":5,\"n\":\"ChJsh \\/ LipFV\"},{\"t\":5,\"n\":\"DST \\/ LipK\"},{\"t\":5,\"n\":\"Eee \\/ LipL\"},{\"t\":5,\"n\":\"Eh \\/ LipR\"},{\"t\":5,\"n\":\"FV \\/ LipTh\"},{\"t\":5,\"n\":\"I\"},{\"t\":5,\"n\":\"K\"},{\"t\":5,\"n\":\"N\"},{\"t\":5,\"n\":\"Oh\"},{\"t\":5,\"n\":\"OohQ\"},{\"t\":5,\"n\":\"R\"},{\"t\":5,\"n\":\"TH\"},{\"t\":5,\"n\":\"W\"},{\"t\":11,\"n\":\"Unknown\"}]}]},{\"t\":6,\"n\":\"OW\",\"c\":[{\"t\":6,\"n\":\"PHWT - Phoneme Target Weight\",\"c\":[{\"t\":5,\"n\":\"Aah \\/ LipBigAah\"},{\"t\":5,\"n\":\"BigAah \\/ LipDST\"},{\"t\":5,\"n\":\"BMP \\/ LipEee\"},{\"t\":5,\"n\":\"ChJsh \\/ LipFV\"},{\"t\":5,\"n\":\"DST \\/ LipK\"},{\"t\":5,\"n\":\"Eee \\/ LipL\"},{\"t\":5,\"n\":\"Eh \\/ LipR\"},{\"t\":5,\"n\":\"FV \\/ LipTh\"},{\"t\":5,\"n\":\"I\"},{\"t\":5,\"n\":\"K\"},{\"t\":5,\"n\":\"N\"},{\"t\":5,\"n\":\"Oh\"},{\"t\":5,\"n\":\"OohQ\"},{\"t\":5,\"n\":\"R\"},{\"t\":5,\"n\":\"TH\"},{\"t\":5,\"n\":\"W\"},{\"t\":11,\"n\":\"Unknown\"}]}]},{\"t\":6,\"n\":\"UH\",\"c\":[{\"t\":6,\"n\":\"PHWT - Phoneme Target Weight\",\"c\":[{\"t\":5,\"n\":\"Aah \\/ LipBigAah\"},{\"t\":5,\"n\":\"BigAah \\/ LipDST\"},{\"t\":5,\"n\":\"BMP \\/ LipEee\"},{\"t\":5,\"n\":\"ChJsh \\/ LipFV\"},{\"t\":5,\"n\":\"DST \\/ LipK\"},{\"t\":5,\"n\":\"Eee \\/ LipL\"},{\"t\":5,\"n\":\"Eh \\/ LipR\"},{\"t\":5,\"n\":\"FV \\/ LipTh\"},{\"t\":5,\"n\":\"I\"},{\"t\":5,\"n\":\"K\"},{\"t\":5,\"n\":\"N\"},{\"t\":5,\"n\":\"Oh\"},{\"t\":5,\"n\":\"OohQ\"},{\"t\":5,\"n\":\"R\"},{\"t\":5,\"n\":\"TH\"},{\"t\":5,\"n\":\"W\"},{\"t\":11,\"n\":\"Unknown\"}]}]},{\"t\":6,\"n\":\"UW\",\"c\":[{\"t\":6,\"n\":\"PHWT - Phoneme Target Weight\",\"c\":[{\"t\":5,\"n\":\"Aah \\/ LipBigAah\"},{\"t\":5,\"n\":\"BigAah \\/ LipDST\"},{\"t\":5,\"n\":\"BMP \\/ LipEee\"},{\"t\":5,\"n\":\"ChJsh \\/ LipFV\"},{\"t\":5,\"n\":\"DST \\/ LipK\"},{\"t\":5,\"n\":\"Eee \\/ LipL\"},{\"t\":5,\"n\":\"Eh \\/ LipR\"},{\"t\":5,\"n\":\"FV \\/ LipTh\"},{\"t\":5,\"n\":\"I\"},{\"t\":5,\"n\":\"K\"},{\"t\":5,\"n\":\"N\"},{\"t\":5,\"n\":\"Oh\"},{\"t\":5,\"n\":\"OohQ\"},{\"t\":5,\"n\":\"R\"},{\"t\":5,\"n\":\"TH\"},{\"t\":5,\"n\":\"W\"},{\"t\":11,\"n\":\"Unknown\"}]}]},{\"t\":6,\"n\":\"ER\",\"c\":[{\"t\":6,\"n\":\"PHWT - Phoneme Target Weight\",\"c\":[{\"t\":5,\"n\":\"Aah \\/ LipBigAah\"},{\"t\":5,\"n\":\"BigAah \\/ LipDST\"},{\"t\":5,\"n\":\"BMP \\/ LipEee\"},{\"t\":5,\"n\":\"ChJsh \\/ LipFV\"},{\"t\":5,\"n\":\"DST \\/ LipK\"},{\"t\":5,\"n\":\"Eee \\/ LipL\"},{\"t\":5,\"n\":\"Eh \\/ LipR\"},{\"t\":5,\"n\":\"FV \\/ LipTh\"},{\"t\":5,\"n\":\"I\"},{\"t\":5,\"n\":\"K\"},{\"t\":5,\"n\":\"N\"},{\"t\":5,\"n\":\"Oh\"},{\"t\":5,\"n\":\"OohQ\"},{\"t\":5,\"n\":\"R\"},{\"t\":5,\"n\":\"TH\"},{\"t\":5,\"n\":\"W\"},{\"t\":11,\"n\":\"Unknown\"}]}]},{\"t\":6,\"n\":\"AX\",\"c\":[{\"t\":6,\"n\":\"PHWT - Phoneme Target Weight\",\"c\":[{\"t\":5,\"n\":\"Aah \\/ LipBigAah\"},{\"t\":5,\"n\":\"BigAah \\/ LipDST\"},{\"t\":5,\"n\":\"BMP \\/ LipEee\"},{\"t\":5,\"n\":\"ChJsh \\/ LipFV\"},{\"t\":5,\"n\":\"DST \\/ LipK\"},{\"t\":5,\"n\":\"Eee \\/ LipL\"},{\"t\":5,\"n\":\"Eh \\/ LipR\"},{\"t\":5,\"n\":\"FV \\/ LipTh\"},{\"t\":5,\"n\":\"I\"},{\"t\":5,\"n\":\"K\"},{\"t\":5,\"n\":\"N\"},{\"t\":5,\"n\":\"Oh\"},{\"t\":5,\"n\":\"OohQ\"},{\"t\":5,\"n\":\"R\"},{\"t\":5,\"n\":\"TH\"},{\"t\":5,\"n\":\"W\"},{\"t\":11,\"n\":\"Unknown\"}]}]},{\"t\":6,\"n\":\"S\",\"c\":[{\"t\":6,\"n\":\"PHWT - Phoneme Target Weight\",\"c\":[{\"t\":5,\"n\":\"Aah \\/ LipBigAah\"},{\"t\":5,\"n\":\"BigAah \\/ LipDST\"},{\"t\":5,\"n\":\"BMP \\/ LipEee\"},{\"t\":5,\"n\":\"ChJsh \\/ LipFV\"},{\"t\":5,\"n\":\"DST \\/ LipK\"},{\"t\":5,\"n\":\"Eee \\/ LipL\"},{\"t\":5,\"n\":\"Eh \\/ LipR\"},{\"t\":5,\"n\":\"FV \\/ LipTh\"},{\"t\":5,\"n\":\"I\"},{\"t\":5,\"n\":\"K\"},{\"t\":5,\"n\":\"N\"},{\"t\":5,\"n\":\"Oh\"},{\"t\":5,\"n\":\"OohQ\"},{\"t\":5,\"n\":\"R\"},{\"t\":5,\"n\":\"TH\"},{\"t\":5,\"n\":\"W\"},{\"t\":11,\"n\":\"Unknown\"}]}]},{\"t\":6,\"n\":\"SH\",\"c\":[{\"t\":6,\"n\":\"PHWT - Phoneme Target Weight\",\"c\":[{\"t\":5,\"n\":\"Aah \\/ LipBigAah\"},{\"t\":5,\"n\":\"BigAah \\/ LipDST\"},{\"t\":5,\"n\":\"BMP \\/ LipEee\"},{\"t\":5,\"n\":\"ChJsh \\/ LipFV\"},{\"t\":5,\"n\":\"DST \\/ LipK\"},{\"t\":5,\"n\":\"Eee \\/ LipL\"},{\"t\":5,\"n\":\"Eh \\/ LipR\"},{\"t\":5,\"n\":\"FV \\/ LipTh\"},{\"t\":5,\"n\":\"I\"},{\"t\":5,\"n\":\"K\"},{\"t\":5,\"n\":\"N\"},{\"t\":5,\"n\":\"Oh\"},{\"t\":5,\"n\":\"OohQ\"},{\"t\":5,\"n\":\"R\"},{\"t\":5,\"n\":\"TH\"},{\"t\":5,\"n\":\"W\"},{\"t\":11,\"n\":\"Unknown\"}]}]},{\"t\":6,\"n\":\"Z\",\"c\":[{\"t\":6,\"n\":\"PHWT - Phoneme Target Weight\",\"c\":[{\"t\":5,\"n\":\"Aah \\/ LipBigAah\"},{\"t\":5,\"n\":\"BigAah \\/ LipDST\"},{\"t\":5,\"n\":\"BMP \\/ LipEee\"},{\"t\":5,\"n\":\"ChJsh \\/ LipFV\"},{\"t\":5,\"n\":\"DST \\/ LipK\"},{\"t\":5,\"n\":\"Eee \\/ LipL\"},{\"t\":5,\"n\":\"Eh \\/ LipR\"},{\"t\":5,\"n\":\"FV \\/ LipTh\"},{\"t\":5,\"n\":\"I\"},{\"t\":5,\"n\":\"K\"},{\"t\":5,\"n\":\"N\"},{\"t\":5,\"n\":\"Oh\"},{\"t\":5,\"n\":\"OohQ\"},{\"t\":5,\"n\":\"R\"},{\"t\":5,\"n\":\"TH\"},{\"t\":5,\"n\":\"W\"},{\"t\":11,\"n\":\"Unknown\"}]}]},{\"t\":6,\"n\":\"ZH\",\"c\":[{\"t\":6,\"n\":\"PHWT - Phoneme Target Weight\",\"c\":[{\"t\":5,\"n\":\"Aah \\/ LipBigAah\"},{\"t\":5,\"n\":\"BigAah \\/ LipDST\"},{\"t\":5,\"n\":\"BMP \\/ LipEee\"},{\"t\":5,\"n\":\"ChJsh \\/ LipFV\"},{\"t\":5,\"n\":\"DST \\/ LipK\"},{\"t\":5,\"n\":\"Eee \\/ LipL\"},{\"t\":5,\"n\":\"Eh \\/ LipR\"},{\"t\":5,\"n\":\"FV \\/ LipTh\"},{\"t\":5,\"n\":\"I\"},{\"t\":5,\"n\":\"K\"},{\"t\":5,\"n\":\"N\"},{\"t\":5,\"n\":\"Oh\"},{\"t\":5,\"n\":\"OohQ\"},{\"t\":5,\"n\":\"R\"},{\"t\":5,\"n\":\"TH\"},{\"t\":5,\"n\":\"W\"},{\"t\":11,\"n\":\"Unknown\"}]}]},{\"t\":6,\"n\":\"F\",\"c\":[{\"t\":6,\"n\":\"PHWT - Phoneme Target Weight\",\"c\":[{\"t\":5,\"n\":\"Aah \\/ LipBigAah\"},{\"t\":5,\"n\":\"BigAah \\/ LipDST\"},{\"t\":5,\"n\":\"BMP \\/ LipEee\"},{\"t\":5,\"n\":\"ChJsh \\/ LipFV\"},{\"t\":5,\"n\":\"DST \\/ LipK\"},{\"t\":5,\"n\":\"Eee \\/ LipL\"},{\"t\":5,\"n\":\"Eh \\/ LipR\"},{\"t\":5,\"n\":\"FV \\/ LipTh\"},{\"t\":5,\"n\":\"I\"},{\"t\":5,\"n\":\"K\"},{\"t\":5,\"n\":\"N\"},{\"t\":5,\"n\":\"Oh\"},{\"t\":5,\"n\":\"OohQ\"},{\"t\":5,\"n\":\"R\"},{\"t\":5,\"n\":\"TH\"},{\"t\":5,\"n\":\"W\"},{\"t\":11,\"n\":\"Unknown\"}]}]},{\"t\":6,\"n\":\"TH\",\"c\":[{\"t\":6,\"n\":\"PHWT - Phoneme Target Weight\",\"c\":[{\"t\":5,\"n\":\"Aah \\/ LipBigAah\"},{\"t\":5,\"n\":\"BigAah \\/ LipDST\"},{\"t\":5,\"n\":\"BMP \\/ LipEee\"},{\"t\":5,\"n\":\"ChJsh \\/ LipFV\"},{\"t\":5,\"n\":\"DST \\/ LipK\"},{\"t\":5,\"n\":\"Eee \\/ LipL\"},{\"t\":5,\"n\":\"Eh \\/ LipR\"},{\"t\":5,\"n\":\"FV \\/ LipTh\"},{\"t\":5,\"n\":\"I\"},{\"t\":5,\"n\":\"K\"},{\"t\":5,\"n\":\"N\"},{\"t\":5,\"n\":\"Oh\"},{\"t\":5,\"n\":\"OohQ\"},{\"t\":5,\"n\":\"R\"},{\"t\":5,\"n\":\"TH\"},{\"t\":5,\"n\":\"W\"},{\"t\":11,\"n\":\"Unknown\"}]}]},{\"t\":6,\"n\":\"V\",\"c\":[{\"t\":6,\"n\":\"PHWT - Phoneme Target Weight\",\"c\":[{\"t\":5,\"n\":\"Aah \\/ LipBigAah\"},{\"t\":5,\"n\":\"BigAah \\/ LipDST\"},{\"t\":5,\"n\":\"BMP \\/ LipEee\"},{\"t\":5,\"n\":\"ChJsh \\/ LipFV\"},{\"t\":5,\"n\":\"DST \\/ LipK\"},{\"t\":5,\"n\":\"Eee \\/ LipL\"},{\"t\":5,\"n\":\"Eh \\/ LipR\"},{\"t\":5,\"n\":\"FV \\/ LipTh\"},{\"t\":5,\"n\":\"I\"},{\"t\":5,\"n\":\"K\"},{\"t\":5,\"n\":\"N\"},{\"t\":5,\"n\":\"Oh\"},{\"t\":5,\"n\":\"OohQ\"},{\"t\":5,\"n\":\"R\"},{\"t\":5,\"n\":\"TH\"},{\"t\":5,\"n\":\"W\"},{\"t\":11,\"n\":\"Unknown\"}]}]},{\"t\":6,\"n\":\"DH\",\"c\":[{\"t\":6,\"n\":\"PHWT - Phoneme Target Weight\",\"c\":[{\"t\":5,\"n\":\"Aah \\/ LipBigAah\"},{\"t\":5,\"n\":\"BigAah \\/ LipDST\"},{\"t\":5,\"n\":\"BMP \\/ LipEee\"},{\"t\":5,\"n\":\"ChJsh \\/ LipFV\"},{\"t\":5,\"n\":\"DST \\/ LipK\"},{\"t\":5,\"n\":\"Eee \\/ LipL\"},{\"t\":5,\"n\":\"Eh \\/ LipR\"},{\"t\":5,\"n\":\"FV \\/ LipTh\"},{\"t\":5,\"n\":\"I\"},{\"t\":5,\"n\":\"K\"},{\"t\":5,\"n\":\"N\"},{\"t\":5,\"n\":\"Oh\"},{\"t\":5,\"n\":\"OohQ\"},{\"t\":5,\"n\":\"R\"},{\"t\":5,\"n\":\"TH\"},{\"t\":5,\"n\":\"W\"},{\"t\":11,\"n\":\"Unknown\"}]}]},{\"t\":6,\"n\":\"M\",\"c\":[{\"t\":6,\"n\":\"PHWT - Phoneme Target Weight\",\"c\":[{\"t\":5,\"n\":\"Aah \\/ LipBigAah\"},{\"t\":5,\"n\":\"BigAah \\/ LipDST\"},{\"t\":5,\"n\":\"BMP \\/ LipEee\"},{\"t\":5,\"n\":\"ChJsh \\/ LipFV\"},{\"t\":5,\"n\":\"DST \\/ LipK\"},{\"t\":5,\"n\":\"Eee \\/ LipL\"},{\"t\":5,\"n\":\"Eh \\/ LipR\"},{\"t\":5,\"n\":\"FV \\/ LipTh\"},{\"t\":5,\"n\":\"I\"},{\"t\":5,\"n\":\"K\"},{\"t\":5,\"n\":\"N\"},{\"t\":5,\"n\":\"Oh\"},{\"t\":5,\"n\":\"OohQ\"},{\"t\":5,\"n\":\"R\"},{\"t\":5,\"n\":\"TH\"},{\"t\":5,\"n\":\"W\"},{\"t\":11,\"n\":\"Unknown\"}]}]},{\"t\":6,\"n\":\"N\",\"c\":[{\"t\":6,\"n\":\"PHWT - Phoneme Target Weight\",\"c\":[{\"t\":5,\"n\":\"Aah \\/ LipBigAah\"},{\"t\":5,\"n\":\"BigAah \\/ LipDST\"},{\"t\":5,\"n\":\"BMP \\/ LipEee\"},{\"t\":5,\"n\":\"ChJsh \\/ LipFV\"},{\"t\":5,\"n\":\"DST \\/ LipK\"},{\"t\":5,\"n\":\"Eee \\/ LipL\"},{\"t\":5,\"n\":\"Eh \\/ LipR\"},{\"t\":5,\"n\":\"FV \\/ LipTh\"},{\"t\":5,\"n\":\"I\"},{\"t\":5,\"n\":\"K\"},{\"t\":5,\"n\":\"N\"},{\"t\":5,\"n\":\"Oh\"},{\"t\":5,\"n\":\"OohQ\"},{\"t\":5,\"n\":\"R\"},{\"t\":5,\"n\":\"TH\"},{\"t\":5,\"n\":\"W\"},{\"t\":11,\"n\":\"Unknown\"}]}]},{\"t\":6,\"n\":\"NG\",\"c\":[{\"t\":6,\"n\":\"PHWT - Phoneme Target Weight\",\"c\":[{\"t\":5,\"n\":\"Aah \\/ LipBigAah\"},{\"t\":5,\"n\":\"BigAah \\/ LipDST\"},{\"t\":5,\"n\":\"BMP \\/ LipEee\"},{\"t\":5,\"n\":\"ChJsh \\/ LipFV\"},{\"t\":5,\"n\":\"DST \\/ LipK\"},{\"t\":5,\"n\":\"Eee \\/ LipL\"},{\"t\":5,\"n\":\"Eh \\/ LipR\"},{\"t\":5,\"n\":\"FV \\/ LipTh\"},{\"t\":5,\"n\":\"I\"},{\"t\":5,\"n\":\"K\"},{\"t\":5,\"n\":\"N\"},{\"t\":5,\"n\":\"Oh\"},{\"t\":5,\"n\":\"OohQ\"},{\"t\":5,\"n\":\"R\"},{\"t\":5,\"n\":\"TH\"},{\"t\":5,\"n\":\"W\"},{\"t\":11,\"n\":\"Unknown\"}]}]},{\"t\":6,\"n\":\"L\",\"c\":[{\"t\":6,\"n\":\"PHWT - Phoneme Target Weight\",\"c\":[{\"t\":5,\"n\":\"Aah \\/ LipBigAah\"},{\"t\":5,\"n\":\"BigAah \\/ LipDST\"},{\"t\":5,\"n\":\"BMP \\/ LipEee\"},{\"t\":5,\"n\":\"ChJsh \\/ LipFV\"},{\"t\":5,\"n\":\"DST \\/ LipK\"},{\"t\":5,\"n\":\"Eee \\/ LipL\"},{\"t\":5,\"n\":\"Eh \\/ LipR\"},{\"t\":5,\"n\":\"FV \\/ LipTh\"},{\"t\":5,\"n\":\"I\"},{\"t\":5,\"n\":\"K\"},{\"t\":5,\"n\":\"N\"},{\"t\":5,\"n\":\"Oh\"},{\"t\":5,\"n\":\"OohQ\"},{\"t\":5,\"n\":\"R\"},{\"t\":5,\"n\":\"TH\"},{\"t\":5,\"n\":\"W\"},{\"t\":11,\"n\":\"Unknown\"}]}]},{\"t\":6,\"n\":\"R\",\"c\":[{\"t\":6,\"n\":\"PHWT - Phoneme Target Weight\",\"c\":[{\"t\":5,\"n\":\"Aah \\/ LipBigAah\"},{\"t\":5,\"n\":\"BigAah \\/ LipDST\"},{\"t\":5,\"n\":\"BMP \\/ LipEee\"},{\"t\":5,\"n\":\"ChJsh \\/ LipFV\"},{\"t\":5,\"n\":\"DST \\/ LipK\"},{\"t\":5,\"n\":\"Eee \\/ LipL\"},{\"t\":5,\"n\":\"Eh \\/ LipR\"},{\"t\":5,\"n\":\"FV \\/ LipTh\"},{\"t\":5,\"n\":\"I\"},{\"t\":5,\"n\":\"K\"},{\"t\":5,\"n\":\"N\"},{\"t\":5,\"n\":\"Oh\"},{\"t\":5,\"n\":\"OohQ\"},{\"t\":5,\"n\":\"R\"},{\"t\":5,\"n\":\"TH\"},{\"t\":5,\"n\":\"W\"},{\"t\":11,\"n\":\"Unknown\"}]}]},{\"t\":6,\"n\":\"W\",\"c\":[{\"t\":6,\"n\":\"PHWT - Phoneme Target Weight\",\"c\":[{\"t\":5,\"n\":\"Aah \\/ LipBigAah\"},{\"t\":5,\"n\":\"BigAah \\/ LipDST\"},{\"t\":5,\"n\":\"BMP \\/ LipEee\"},{\"t\":5,\"n\":\"ChJsh \\/ LipFV\"},{\"t\":5,\"n\":\"DST \\/ LipK\"},{\"t\":5,\"n\":\"Eee \\/ LipL\"},{\"t\":5,\"n\":\"Eh \\/ LipR\"},{\"t\":5,\"n\":\"FV \\/ LipTh\"},{\"t\":5,\"n\":\"I\"},{\"t\":5,\"n\":\"K\"},{\"t\":5,\"n\":\"N\"},{\"t\":5,\"n\":\"Oh\"},{\"t\":5,\"n\":\"OohQ\"},{\"t\":5,\"n\":\"R\"},{\"t\":5,\"n\":\"TH\"},{\"t\":5,\"n\":\"W\"},{\"t\":11,\"n\":\"Unknown\"}]}]},{\"t\":6,\"n\":\"Y\",\"c\":[{\"t\":6,\"n\":\"PHWT - Phoneme Target Weight\",\"c\":[{\"t\":5,\"n\":\"Aah \\/ LipBigAah\"},{\"t\":5,\"n\":\"BigAah \\/ LipDST\"},{\"t\":5,\"n\":\"BMP \\/ LipEee\"},{\"t\":5,\"n\":\"ChJsh \\/ LipFV\"},{\"t\":5,\"n\":\"DST \\/ LipK\"},{\"t\":5,\"n\":\"Eee \\/ LipL\"},{\"t\":5,\"n\":\"Eh \\/ LipR\"},{\"t\":5,\"n\":\"FV \\/ LipTh\"},{\"t\":5,\"n\":\"I\"},{\"t\":5,\"n\":\"K\"},{\"t\":5,\"n\":\"N\"},{\"t\":5,\"n\":\"Oh\"},{\"t\":5,\"n\":\"OohQ\"},{\"t\":5,\"n\":\"R\"},{\"t\":5,\"n\":\"TH\"},{\"t\":5,\"n\":\"W\"},{\"t\":11,\"n\":\"Unknown\"}]}]},{\"t\":6,\"n\":\"HH\",\"c\":[{\"t\":6,\"n\":\"PHWT - Phoneme Target Weight\",\"c\":[{\"t\":5,\"n\":\"Aah \\/ LipBigAah\"},{\"t\":5,\"n\":\"BigAah \\/ LipDST\"},{\"t\":5,\"n\":\"BMP \\/ LipEee\"},{\"t\":5,\"n\":\"ChJsh \\/ LipFV\"},{\"t\":5,\"n\":\"DST \\/ LipK\"},{\"t\":5,\"n\":\"Eee \\/ LipL\"},{\"t\":5,\"n\":\"Eh \\/ LipR\"},{\"t\":5,\"n\":\"FV \\/ LipTh\"},{\"t\":5,\"n\":\"I\"},{\"t\":5,\"n\":\"K\"},{\"t\":5,\"n\":\"N\"},{\"t\":5,\"n\":\"Oh\"},{\"t\":5,\"n\":\"OohQ\"},{\"t\":5,\"n\":\"R\"},{\"t\":5,\"n\":\"TH\"},{\"t\":5,\"n\":\"W\"},{\"t\":11,\"n\":\"Unknown\"}]}]},{\"t\":6,\"n\":\"B\",\"c\":[{\"t\":6,\"n\":\"PHWT - Phoneme Target Weight\",\"c\":[{\"t\":5,\"n\":\"Aah \\/ LipBigAah\"},{\"t\":5,\"n\":\"BigAah \\/ LipDST\"},{\"t\":5,\"n\":\"BMP \\/ LipEee\"},{\"t\":5,\"n\":\"ChJsh \\/ LipFV\"},{\"t\":5,\"n\":\"DST \\/ LipK\"},{\"t\":5,\"n\":\"Eee \\/ LipL\"},{\"t\":5,\"n\":\"Eh \\/ LipR\"},{\"t\":5,\"n\":\"FV \\/ LipTh\"},{\"t\":5,\"n\":\"I\"},{\"t\":5,\"n\":\"K\"},{\"t\":5,\"n\":\"N\"},{\"t\":5,\"n\":\"Oh\"},{\"t\":5,\"n\":\"OohQ\"},{\"t\":5,\"n\":\"R\"},{\"t\":5,\"n\":\"TH\"},{\"t\":5,\"n\":\"W\"},{\"t\":11,\"n\":\"Unknown\"}]}]},{\"t\":6,\"n\":\"D\",\"c\":[{\"t\":6,\"n\":\"PHWT - Phoneme Target Weight\",\"c\":[{\"t\":5,\"n\":\"Aah \\/ LipBigAah\"},{\"t\":5,\"n\":\"BigAah \\/ LipDST\"},{\"t\":5,\"n\":\"BMP \\/ LipEee\"},{\"t\":5,\"n\":\"ChJsh \\/ LipFV\"},{\"t\":5,\"n\":\"DST \\/ LipK\"},{\"t\":5,\"n\":\"Eee \\/ LipL\"},{\"t\":5,\"n\":\"Eh \\/ LipR\"},{\"t\":5,\"n\":\"FV \\/ LipTh\"},{\"t\":5,\"n\":\"I\"},{\"t\":5,\"n\":\"K\"},{\"t\":5,\"n\":\"N\"},{\"t\":5,\"n\":\"Oh\"},{\"t\":5,\"n\":\"OohQ\"},{\"t\":5,\"n\":\"R\"},{\"t\":5,\"n\":\"TH\"},{\"t\":5,\"n\":\"W\"},{\"t\":11,\"n\":\"Unknown\"}]}]},{\"t\":6,\"n\":\"JH\",\"c\":[{\"t\":6,\"n\":\"PHWT - Phoneme Target Weight\",\"c\":[{\"t\":5,\"n\":\"Aah \\/ LipBigAah\"},{\"t\":5,\"n\":\"BigAah \\/ LipDST\"},{\"t\":5,\"n\":\"BMP \\/ LipEee\"},{\"t\":5,\"n\":\"ChJsh \\/ LipFV\"},{\"t\":5,\"n\":\"DST \\/ LipK\"},{\"t\":5,\"n\":\"Eee \\/ LipL\"},{\"t\":5,\"n\":\"Eh \\/ LipR\"},{\"t\":5,\"n\":\"FV \\/ LipTh\"},{\"t\":5,\"n\":\"I\"},{\"t\":5,\"n\":\"K\"},{\"t\":5,\"n\":\"N\"},{\"t\":5,\"n\":\"Oh\"},{\"t\":5,\"n\":\"OohQ\"},{\"t\":5,\"n\":\"R\"},{\"t\":5,\"n\":\"TH\"},{\"t\":5,\"n\":\"W\"},{\"t\":11,\"n\":\"Unknown\"}]}]},{\"t\":6,\"n\":\"G\",\"c\":[{\"t\":6,\"n\":\"PHWT - Phoneme Target Weight\",\"c\":[{\"t\":5,\"n\":\"Aah \\/ LipBigAah\"},{\"t\":5,\"n\":\"BigAah \\/ LipDST\"},{\"t\":5,\"n\":\"BMP \\/ LipEee\"},{\"t\":5,\"n\":\"ChJsh \\/ LipFV\"},{\"t\":5,\"n\":\"DST \\/ LipK\"},{\"t\":5,\"n\":\"Eee \\/ LipL\"},{\"t\":5,\"n\":\"Eh \\/ LipR\"},{\"t\":5,\"n\":\"FV \\/ LipTh\"},{\"t\":5,\"n\":\"I\"},{\"t\":5,\"n\":\"K\"},{\"t\":5,\"n\":\"N\"},{\"t\":5,\"n\":\"Oh\"},{\"t\":5,\"n\":\"OohQ\"},{\"t\":5,\"n\":\"R\"},{\"t\":5,\"n\":\"TH\"},{\"t\":5,\"n\":\"W\"},{\"t\":11,\"n\":\"Unknown\"}]}]},{\"t\":6,\"n\":\"P\",\"c\":[{\"t\":6,\"n\":\"PHWT - Phoneme Target Weight\",\"c\":[{\"t\":5,\"n\":\"Aah \\/ LipBigAah\"},{\"t\":5,\"n\":\"BigAah \\/ LipDST\"},{\"t\":5,\"n\":\"BMP \\/ LipEee\"},{\"t\":5,\"n\":\"ChJsh \\/ LipFV\"},{\"t\":5,\"n\":\"DST \\/ LipK\"},{\"t\":5,\"n\":\"Eee \\/ LipL\"},{\"t\":5,\"n\":\"Eh \\/ LipR\"},{\"t\":5,\"n\":\"FV \\/ LipTh\"},{\"t\":5,\"n\":\"I\"},{\"t\":5,\"n\":\"K\"},{\"t\":5,\"n\":\"N\"},{\"t\":5,\"n\":\"Oh\"},{\"t\":5,\"n\":\"OohQ\"},{\"t\":5,\"n\":\"R\"},{\"t\":5,\"n\":\"TH\"},{\"t\":5,\"n\":\"W\"},{\"t\":11,\"n\":\"Unknown\"}]}]},{\"t\":6,\"n\":\"T\",\"c\":[{\"t\":6,\"n\":\"PHWT - Phoneme Target Weight\",\"c\":[{\"t\":5,\"n\":\"Aah \\/ LipBigAah\"},{\"t\":5,\"n\":\"BigAah \\/ LipDST\"},{\"t\":5,\"n\":\"BMP \\/ LipEee\"},{\"t\":5,\"n\":\"ChJsh \\/ LipFV\"},{\"t\":5,\"n\":\"DST \\/ LipK\"},{\"t\":5,\"n\":\"Eee \\/ LipL\"},{\"t\":5,\"n\":\"Eh \\/ LipR\"},{\"t\":5,\"n\":\"FV \\/ LipTh\"},{\"t\":5,\"n\":\"I\"},{\"t\":5,\"n\":\"K\"},{\"t\":5,\"n\":\"N\"},{\"t\":5,\"n\":\"Oh\"},{\"t\":5,\"n\":\"OohQ\"},{\"t\":5,\"n\":\"R\"},{\"t\":5,\"n\":\"TH\"},{\"t\":5,\"n\":\"W\"},{\"t\":11,\"n\":\"Unknown\"}]}]},{\"t\":6,\"n\":\"K\",\"c\":[{\"t\":6,\"n\":\"PHWT - Phoneme Target Weight\",\"c\":[{\"t\":5,\"n\":\"Aah \\/ LipBigAah\"},{\"t\":5,\"n\":\"BigAah \\/ LipDST\"},{\"t\":5,\"n\":\"BMP \\/ LipEee\"},{\"t\":5,\"n\":\"ChJsh \\/ LipFV\"},{\"t\":5,\"n\":\"DST \\/ LipK\"},{\"t\":5,\"n\":\"Eee \\/ LipL\"},{\"t\":5,\"n\":\"Eh \\/ LipR\"},{\"t\":5,\"n\":\"FV \\/ LipTh\"},{\"t\":5,\"n\":\"I\"},{\"t\":5,\"n\":\"K\"},{\"t\":5,\"n\":\"N\"},{\"t\":5,\"n\":\"Oh\"},{\"t\":5,\"n\":\"OohQ\"},{\"t\":5,\"n\":\"R\"},{\"t\":5,\"n\":\"TH\"},{\"t\":5,\"n\":\"W\"},{\"t\":11,\"n\":\"Unknown\"}]}]},{\"t\":6,\"n\":\"CH\",\"c\":[{\"t\":6,\"n\":\"PHWT - Phoneme Target Weight\",\"c\":[{\"t\":5,\"n\":\"Aah \\/ LipBigAah\"},{\"t\":5,\"n\":\"BigAah \\/ LipDST\"},{\"t\":5,\"n\":\"BMP \\/ LipEee\"},{\"t\":5,\"n\":\"ChJsh \\/ LipFV\"},{\"t\":5,\"n\":\"DST \\/ LipK\"},{\"t\":5,\"n\":\"Eee \\/ LipL\"},{\"t\":5,\"n\":\"Eh \\/ LipR\"},{\"t\":5,\"n\":\"FV \\/ LipTh\"},{\"t\":5,\"n\":\"I\"},{\"t\":5,\"n\":\"K\"},{\"t\":5,\"n\":\"N\"},{\"t\":5,\"n\":\"Oh\"},{\"t\":5,\"n\":\"OohQ\"},{\"t\":5,\"n\":\"R\"},{\"t\":5,\"n\":\"TH\"},{\"t\":5,\"n\":\"W\"},{\"t\":11,\"n\":\"Unknown\"}]}]},{\"t\":6,\"n\":\"SIL\",\"c\":[{\"t\":6,\"n\":\"PHWT - Phoneme Target Weight\",\"c\":[{\"t\":5,\"n\":\"Aah \\/ LipBigAah\"},{\"t\":5,\"n\":\"BigAah \\/ LipDST\"},{\"t\":5,\"n\":\"BMP \\/ LipEee\"},{\"t\":5,\"n\":\"ChJsh \\/ LipFV\"},{\"t\":5,\"n\":\"DST \\/ LipK\"},{\"t\":5,\"n\":\"Eee \\/ LipL\"},{\"t\":5,\"n\":\"Eh \\/ LipR\"},{\"t\":5,\"n\":\"FV \\/ LipTh\"},{\"t\":5,\"n\":\"I\"},{\"t\":5,\"n\":\"K\"},{\"t\":5,\"n\":\"N\"},{\"t\":5,\"n\":\"Oh\"},{\"t\":5,\"n\":\"OohQ\"},{\"t\":5,\"n\":\"R\"},{\"t\":5,\"n\":\"TH\"},{\"t\":5,\"n\":\"W\"},{\"t\":11,\"n\":\"Unknown\"}]}]},{\"t\":6,\"n\":\"SHOTSIL\",\"c\":[{\"t\":6,\"n\":\"PHWT - Phoneme Target Weight\",\"c\":[{\"t\":5,\"n\":\"Aah \\/ LipBigAah\"},{\"t\":5,\"n\":\"BigAah \\/ LipDST\"},{\"t\":5,\"n\":\"BMP \\/ LipEee\"},{\"t\":5,\"n\":\"ChJsh \\/ LipFV\"},{\"t\":5,\"n\":\"DST \\/ LipK\"},{\"t\":5,\"n\":\"Eee \\/ LipL\"},{\"t\":5,\"n\":\"Eh \\/ LipR\"},{\"t\":5,\"n\":\"FV \\/ LipTh\"},{\"t\":5,\"n\":\"I\"},{\"t\":5,\"n\":\"K\"},{\"t\":5,\"n\":\"N\"},{\"t\":5,\"n\":\"Oh\"},{\"t\":5,\"n\":\"OohQ\"},{\"t\":5,\"n\":\"R\"},{\"t\":5,\"n\":\"TH\"},{\"t\":5,\"n\":\"W\"},{\"t\":11,\"n\":\"Unknown\"}]}]},{\"t\":6,\"n\":\"FLAP\",\"c\":[{\"t\":6,\"n\":\"PHWT - Phoneme Target Weight\",\"c\":[{\"t\":5,\"n\":\"Aah \\/ LipBigAah\"},{\"t\":5,\"n\":\"BigAah \\/ LipDST\"},{\"t\":5,\"n\":\"BMP \\/ LipEee\"},{\"t\":5,\"n\":\"ChJsh \\/ LipFV\"},{\"t\":5,\"n\":\"DST \\/ LipK\"},{\"t\":5,\"n\":\"Eee \\/ LipL\"},{\"t\":5,\"n\":\"Eh \\/ LipR\"},{\"t\":5,\"n\":\"FV \\/ LipTh\"},{\"t\":5,\"n\":\"I\"},{\"t\":5,\"n\":\"K\"},{\"t\":5,\"n\":\"N\"},{\"t\":5,\"n\":\"Oh\"},{\"t\":5,\"n\":\"OohQ\"},{\"t\":5,\"n\":\"R\"},{\"t\":5,\"n\":\"TH\"},{\"t\":5,\"n\":\"W\"},{\"t\":11,\"n\":\"Unknown\"}]}]}]},{\"t\":3,\"n\":\"WKMV - Base Movement Defaults - Default\"},{\"t\":3,\"n\":\"SWMV - Base Movement Defaults - Swim\"},{\"t\":3,\"n\":\"FLMV - Base Movement Defaults - Fly\"},{\"t\":3,\"n\":\"SNMV - Base Movement Defaults - Sneak\"},{\"n\":\"NAM0 - Head Data Marker\"},{\"n\":\"MNAM - Male Data Marker\"},{\"t\":6,\"n\":\"NNAM - Male Neck Fat Adjustments Scale\",\"c\":[{\"t\":11,\"n\":\"Unknown\"},{\"t\":5,\"n\":\"X\"},{\"t\":5,\"n\":\"Y\"}]},{\"t\":10,\"n\":\"Male Head Parts\",\"c\":[{\"t\":6,\"n\":\"Head Part\",\"c\":[{\"t\":3,\"n\":\"INDX - Head Part Number\"},{\"t\":3,\"n\":\"HEAD - Head\"}]}]},{\"t\":8,\"n\":\"Male Race Presets\",\"c\":[{\"t\":3,\"n\":\"RPRM - Preset NPC\"}]},{\"t\":8,\"n\":\"Male Hair Colors\",\"c\":[{\"t\":3,\"n\":\"AHCM - Hair Color\"}]},{\"t\":8,\"n\":\"Male Face Details\",\"c\":[{\"t\":3,\"n\":\"FTSM - Texture Set\"}]},{\"t\":3,\"n\":\"DFTM - Male Default Face Texture\"},{\"t\":8,\"n\":\"Male Tint Layers\",\"c\":[{\"t\":6,\"n\":\"Group\",\"c\":[{\"t\":2,\"n\":\"TTGP - Group Name\"},{\"t\":8,\"n\":\"Options\",\"c\":[{\"t\":6,\"n\":\"Option\",\"c\":[{\"t\":6,\"n\":\"TETI - Index\",\"c\":[{\"t\":11,\"n\":\"Unknown\"},{\"t\":3,\"n\":\"Index\"}]},{\"t\":2,\"n\":\"TTGP - Name\"},{\"t\":11,\"n\":\"TTEF - Unknown\"},{\"t\":8,\"n\":\"Conditions\",\"c\":[{\"t\":6,\"n\":\"Condition\",\"c\":[{\"t\":6,\"n\":\"CTDA - \",\"c\":[{\"t\":3,\"n\":\"Type\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":5,\"n\":\"Comparison Value - Float\"},{\"t\":3,\"n\":\"Comparison Value - Global\"},{\"t\":3,\"n\":\"Function\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":11,\"n\":\"None\"},{\"t\":3,\"n\":\"Integer\"},{\"t\":5,\"n\":\"Float\"},{\"t\":3,\"n\":\"Actor\"},{\"t\":3,\"n\":\"Actor Base\"},{\"t\":3,\"n\":\"Actor Value\"},{\"t\":3,\"n\":\"Player Action\"},{\"t\":3,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Alignment\"},{\"t\":3,\"n\":\"Association Type\"},{\"t\":3,\"n\":\"Axis\"},{\"t\":3,\"n\":\"Casting Type\"},{\"t\":3,\"n\":\"Cell\"},{\"t\":3,\"n\":\"Class\"},{\"t\":3,\"n\":\"Crime Type\"},{\"t\":3,\"n\":\"Critical Stage\"},{\"t\":3,\"n\":\"Encounter Zone\"},{\"t\":3,\"n\":\"Equip Type\"},{\"t\":3,\"n\":\"Event\"},{\"t\":3,\"n\":\"Event Data\"},{\"t\":3,\"n\":\"Faction\"},{\"t\":3,\"n\":\"Form List\"},{\"t\":3,\"n\":\"Form Type\"},{\"t\":3,\"n\":\"Furniture\"},{\"t\":3,\"n\":\"Furniture Anim\"},{\"t\":3,\"n\":\"Furniture Entry\"},{\"t\":3,\"n\":\"Global\"},{\"t\":3,\"n\":\"Idle\"},{\"t\":3,\"n\":\"Inventory Object\"},{\"t\":3,\"n\":\"Keyword\"},{\"t\":3,\"n\":\"Location\"},{\"t\":3,\"n\":\"Base Effect\"},{\"t\":3,\"n\":\"Effect Item\"},{\"t\":3,\"n\":\"Misc Stat\"},{\"t\":3,\"n\":\"Object Reference\"},{\"t\":3,\"n\":\"Owner\"},{\"t\":3,\"n\":\"Package\"},{\"t\":3,\"n\":\"Packdata ID\"},{\"t\":3,\"n\":\"Perk\"},{\"t\":3,\"n\":\"Quest\"},{\"t\":3,\"n\":\"Quest Stage\"},{\"t\":3,\"n\":\"Race\"},{\"t\":3,\"n\":\"Referenceable Object\"},{\"t\":3,\"n\":\"Location Ref Type\"},{\"t\":3,\"n\":\"Region\"},{\"t\":3,\"n\":\"Scene\"},{\"t\":3,\"n\":\"Sex\"},{\"t\":3,\"n\":\"Shout\"},{\"t\":11,\"n\":\"Variable Name (unused)\"},{\"t\":3,\"n\":\"VATS Value Function\"},{\"t\":3,\"n\":\"VATS Value Param (unused)\"},{\"t\":3,\"n\":\"Voice Type\"},{\"t\":3,\"n\":\"Ward State\"},{\"t\":3,\"n\":\"Weather\"},{\"t\":3,\"n\":\"Worldspace\"},{\"t\":3,\"n\":\"Damage Type\"},{\"t\":3,\"n\":\"Weapon\"},{\"t\":3,\"n\":\"Weapon List\"},{\"t\":3,\"n\":\"Target\"},{\"t\":3,\"n\":\"Target List\"},{\"t\":3,\"n\":\"Target Part\"},{\"t\":3,\"n\":\"VATS Action\"},{\"t\":3,\"n\":\"Critical Effect\"},{\"t\":3,\"n\":\"Critical Effect List\"},{\"t\":3,\"n\":\"Weapon Type\"},{\"t\":3,\"n\":\"Projectile Type\"},{\"t\":3,\"n\":\"Delivery Type\"},{\"t\":3,\"n\":\"Run On\"},{\"t\":3,\"n\":\"Reference\"},{\"t\":3,\"n\":\"Parameter #3\"}]},{\"t\":2,\"n\":\"CIS1 - Parameter #1\"},{\"t\":2,\"n\":\"CIS2 - Parameter #2\"}]}]},{\"t\":8,\"n\":\"Textures\",\"c\":[{\"t\":2,\"n\":\"TTET - Texture\"}]},{\"t\":11,\"n\":\"TTEB - Unknown\"},{\"t\":7,\"n\":\"TTEC - Template Colors\",\"c\":[{\"t\":6,\"n\":\"Template Color\",\"c\":[{\"t\":3,\"n\":\"Color\"},{\"t\":5,\"n\":\"Alpha\"},{\"t\":3,\"n\":\"Template Index\"},{\"t\":11,\"n\":\"Unknown\"}]}]},{\"t\":5,\"n\":\"TTED - Unknown\"}]}]},{\"t\":11,\"n\":\"TTGE - Group End\"}]}]},{\"t\":8,\"n\":\"Male Morph Groups\",\"c\":[{\"t\":6,\"n\":\"Morph Group\",\"c\":[{\"t\":2,\"n\":\"MPGN - Name\"},{\"t\":3,\"n\":\"MPPC - Count\"},{\"t\":8,\"n\":\"Morph Presets\",\"c\":[{\"t\":6,\"n\":\"Morph Preset\",\"c\":[{\"t\":3,\"n\":\"MPPI - Index\"},{\"t\":2,\"n\":\"MPPN - Name\"},{\"t\":2,\"n\":\"MPPM - Unknown\"},{\"t\":3,\"n\":\"MPPT - Texture\"},{\"t\":11,\"n\":\"MPPF - Unknown\"}]}]},{\"t\":11,\"n\":\"MPPK - Unknown\"},{\"t\":11,\"n\":\"MPGS - Unknown\"}]}]},{\"t\":8,\"n\":\"Male Face Morphs\",\"c\":[{\"t\":6,\"n\":\"Face Morph\",\"c\":[{\"t\":3,\"n\":\"FMRI - Index\"},{\"t\":2,\"n\":\"FMRN - Name\"}]}]},{\"t\":2,\"n\":\"WMAP - Male Wrinkle Map Path\"},{\"n\":\"FNAM - Female Data Marker\"},{\"t\":6,\"n\":\"NNAM - Female Neck Fat Adjustments Scale\",\"c\":[{\"t\":11,\"n\":\"Unknown\"},{\"t\":5,\"n\":\"X\"},{\"t\":5,\"n\":\"Y\"}]},{\"t\":10,\"n\":\"Female Head Parts\",\"c\":[{\"t\":6,\"n\":\"Head Part\",\"c\":[{\"t\":3,\"n\":\"INDX - Head Part Number\"},{\"t\":3,\"n\":\"HEAD - Head\"}]}]},{\"t\":8,\"n\":\"Female Race Presets\",\"c\":[{\"t\":3,\"n\":\"RPRF - Preset NPC\"}]},{\"t\":8,\"n\":\"Female Hair Colors\",\"c\":[{\"t\":3,\"n\":\"AHCF - Hair Color\"}]},{\"t\":8,\"n\":\"Female Face Details\",\"c\":[{\"t\":3,\"n\":\"FTSF - Texture Set\"}]},{\"t\":3,\"n\":\"DFTF - Female Default Face Texture\"},{\"t\":8,\"n\":\"Female Tint Layers\",\"c\":[{\"t\":6,\"n\":\"Group\",\"c\":[{\"t\":2,\"n\":\"TTGP - Group Name\"},{\"t\":8,\"n\":\"Options\",\"c\":[{\"t\":6,\"n\":\"Option\",\"c\":[{\"t\":6,\"n\":\"TETI - Index\",\"c\":[{\"t\":11,\"n\":\"Unknown\"},{\"t\":3,\"n\":\"Index\"}]},{\"t\":2,\"n\":\"TTGP - Name\"},{\"t\":11,\"n\":\"TTEF - Unknown\"},{\"t\":8,\"n\":\"Conditions\",\"c\":[{\"t\":6,\"n\":\"Condition\",\"c\":[{\"t\":6,\"n\":\"CTDA - \",\"c\":[{\"t\":3,\"n\":\"Type\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":5,\"n\":\"Comparison Value - Float\"},{\"t\":3,\"n\":\"Comparison Value - Global\"},{\"t\":3,\"n\":\"Function\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":11,\"n\":\"None\"},{\"t\":3,\"n\":\"Integer\"},{\"t\":5,\"n\":\"Float\"},{\"t\":3,\"n\":\"Actor\"},{\"t\":3,\"n\":\"Actor Base\"},{\"t\":3,\"n\":\"Actor Value\"},{\"t\":3,\"n\":\"Player Action\"},{\"t\":3,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Alignment\"},{\"t\":3,\"n\":\"Association Type\"},{\"t\":3,\"n\":\"Axis\"},{\"t\":3,\"n\":\"Casting Type\"},{\"t\":3,\"n\":\"Cell\"},{\"t\":3,\"n\":\"Class\"},{\"t\":3,\"n\":\"Crime Type\"},{\"t\":3,\"n\":\"Critical Stage\"},{\"t\":3,\"n\":\"Encounter Zone\"},{\"t\":3,\"n\":\"Equip Type\"},{\"t\":3,\"n\":\"Event\"},{\"t\":3,\"n\":\"Event Data\"},{\"t\":3,\"n\":\"Faction\"},{\"t\":3,\"n\":\"Form List\"},{\"t\":3,\"n\":\"Form Type\"},{\"t\":3,\"n\":\"Furniture\"},{\"t\":3,\"n\":\"Furniture Anim\"},{\"t\":3,\"n\":\"Furniture Entry\"},{\"t\":3,\"n\":\"Global\"},{\"t\":3,\"n\":\"Idle\"},{\"t\":3,\"n\":\"Inventory Object\"},{\"t\":3,\"n\":\"Keyword\"},{\"t\":3,\"n\":\"Location\"},{\"t\":3,\"n\":\"Base Effect\"},{\"t\":3,\"n\":\"Effect Item\"},{\"t\":3,\"n\":\"Misc Stat\"},{\"t\":3,\"n\":\"Object Reference\"},{\"t\":3,\"n\":\"Owner\"},{\"t\":3,\"n\":\"Package\"},{\"t\":3,\"n\":\"Packdata ID\"},{\"t\":3,\"n\":\"Perk\"},{\"t\":3,\"n\":\"Quest\"},{\"t\":3,\"n\":\"Quest Stage\"},{\"t\":3,\"n\":\"Race\"},{\"t\":3,\"n\":\"Referenceable Object\"},{\"t\":3,\"n\":\"Location Ref Type\"},{\"t\":3,\"n\":\"Region\"},{\"t\":3,\"n\":\"Scene\"},{\"t\":3,\"n\":\"Sex\"},{\"t\":3,\"n\":\"Shout\"},{\"t\":11,\"n\":\"Variable Name (unused)\"},{\"t\":3,\"n\":\"VATS Value Function\"},{\"t\":3,\"n\":\"VATS Value Param (unused)\"},{\"t\":3,\"n\":\"Voice Type\"},{\"t\":3,\"n\":\"Ward State\"},{\"t\":3,\"n\":\"Weather\"},{\"t\":3,\"n\":\"Worldspace\"},{\"t\":3,\"n\":\"Damage Type\"},{\"t\":3,\"n\":\"Weapon\"},{\"t\":3,\"n\":\"Weapon List\"},{\"t\":3,\"n\":\"Target\"},{\"t\":3,\"n\":\"Target List\"},{\"t\":3,\"n\":\"Target Part\"},{\"t\":3,\"n\":\"VATS Action\"},{\"t\":3,\"n\":\"Critical Effect\"},{\"t\":3,\"n\":\"Critical Effect List\"},{\"t\":3,\"n\":\"Weapon Type\"},{\"t\":3,\"n\":\"Projectile Type\"},{\"t\":3,\"n\":\"Delivery Type\"},{\"t\":3,\"n\":\"Run On\"},{\"t\":3,\"n\":\"Reference\"},{\"t\":3,\"n\":\"Parameter #3\"}]},{\"t\":2,\"n\":\"CIS1 - Parameter #1\"},{\"t\":2,\"n\":\"CIS2 - Parameter #2\"}]}]},{\"t\":8,\"n\":\"Textures\",\"c\":[{\"t\":2,\"n\":\"TTET - Texture\"}]},{\"t\":11,\"n\":\"TTEB - Unknown\"},{\"t\":7,\"n\":\"TTEC - Template Colors\",\"c\":[{\"t\":6,\"n\":\"Template Color\",\"c\":[{\"t\":3,\"n\":\"Color\"},{\"t\":5,\"n\":\"Alpha\"},{\"t\":3,\"n\":\"Template Index\"},{\"t\":11,\"n\":\"Unknown\"}]}]},{\"t\":5,\"n\":\"TTED - Unknown\"}]}]},{\"t\":11,\"n\":\"TTGE - Group End\"}]}]},{\"t\":8,\"n\":\"Female Morph Groups\",\"c\":[{\"t\":6,\"n\":\"Morph Group\",\"c\":[{\"t\":2,\"n\":\"MPGN - Name\"},{\"t\":3,\"n\":\"MPPC - Count\"},{\"t\":8,\"n\":\"Morph Presets\",\"c\":[{\"t\":6,\"n\":\"Morph Preset\",\"c\":[{\"t\":3,\"n\":\"MPPI - Index\"},{\"t\":2,\"n\":\"MPPN - Name\"},{\"t\":2,\"n\":\"MPPM - Unknown\"},{\"t\":3,\"n\":\"MPPT - Texture\"},{\"t\":11,\"n\":\"MPPF - Unknown\"}]}]},{\"t\":11,\"n\":\"MPPK - Unknown\"},{\"t\":11,\"n\":\"MPGS - Unknown\"}]}]},{\"t\":8,\"n\":\"Female Face Morphs\",\"c\":[{\"t\":6,\"n\":\"Face Morph\",\"c\":[{\"t\":3,\"n\":\"FMRI - Index\"},{\"t\":2,\"n\":\"FMRN - Name\"}]}]},{\"t\":2,\"n\":\"WMAP - Female Wrinkle Map Path\"},{\"t\":3,\"n\":\"NAM8 - Morph Race\"},{\"t\":3,\"n\":\"RNAM - Armor Race\"},{\"t\":3,\"n\":\"SRAC - Subgraph Template Race\"},{\"t\":3,\"n\":\"SADD - Subgraph Additive Race\"},{\"t\":8,\"n\":\"Subgraph Data\",\"c\":[{\"t\":6,\"n\":\"Data\",\"c\":[{\"t\":2,\"n\":\"SGNM - Behaviour Graph\"},{\"t\":8,\"n\":\"Actor Keywords\",\"c\":[{\"t\":3,\"n\":\"SAKD - Keyword\"}]},{\"t\":8,\"n\":\"Target Keywords\",\"c\":[{\"t\":3,\"n\":\"STKD - Keyword\"}]},{\"t\":8,\"n\":\"Animation Paths\",\"c\":[{\"t\":2,\"n\":\"SAPT - Path\"}]},{\"t\":6,\"n\":\"SRAF - Flags\",\"c\":[{\"t\":3,\"n\":\"Role\"},{\"t\":3,\"n\":\"Perspective\"}]}]}]},{\"t\":5,\"n\":\"PTOP - Idle Chatter Time Min\"},{\"t\":5,\"n\":\"NTOP - Idle Chatter Time Max\"},{\"t\":8,\"n\":\"Morph Values\",\"c\":[{\"t\":6,\"n\":\"Value\",\"c\":[{\"t\":3,\"n\":\"MSID - Index\"},{\"t\":2,\"n\":\"MSM0 - Min Name\"},{\"t\":2,\"n\":\"MSM1 - Max Name\"}]}]},{\"t\":11,\"n\":\"MLSI - Unknown\"},{\"t\":2,\"n\":\"HNAM - Hair Color Lookup Texture\"},{\"t\":2,\"n\":\"HLTX - Hair Color Extended Lookup Texture\"},{\"t\":3,\"n\":\"QSTI - Dialogue Quest\"},{\"t\":8,\"n\":\"Bone Data\",\"c\":[{\"t\":6,\"n\":\"Data\",\"c\":[{\"t\":3,\"n\":\"BSMP - Gender\"},{\"t\":8,\"n\":\"Bones\",\"c\":[{\"t\":6,\"n\":\"Bone\",\"c\":[{\"t\":2,\"n\":\"BSMB - Name\"},{\"t\":7,\"n\":\"BSMS - Values\",\"c\":[{\"t\":5,\"n\":\"Value\"}]},{\"t\":11,\"n\":\"BMMP - Unknown\"}]}]}]}]}]},{\"t\":1,\"p\":1,\"n\":\"REFR - Placed Object\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"VMAD - Virtual Machine Adapter\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Version\"},{\"t\":3,\"p\":1,\"n\":\"Object Format\"},{\"t\":7,\"p\":1,\"n\":\"Scripts\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Script\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"scriptName\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":7,\"p\":1,\"n\":\"Properties\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Property\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"propertyName\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]},{\"t\":2,\"p\":1,\"n\":\"String\"},{\"t\":3,\"p\":1,\"n\":\"Int32\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":3,\"p\":1,\"n\":\"Bool\"},{\"t\":7,\"p\":1,\"n\":\"Struct\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Member\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"memberName\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]},{\"t\":2,\"p\":1,\"n\":\"String\"},{\"t\":3,\"p\":1,\"n\":\"Int32\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":3,\"p\":1,\"n\":\"Bool\"},{\"t\":7,\"p\":1,\"n\":\"Array of Object\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]}]},{\"t\":7,\"p\":1,\"n\":\"Array of String\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Int32\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Float\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Bool\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]}]}]},{\"t\":7,\"p\":1,\"n\":\"Array of Object\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]}]},{\"t\":7,\"p\":1,\"n\":\"Array of String\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Int32\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Float\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Bool\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Struct\",\"c\":[{\"t\":7,\"p\":1,\"n\":\"Struct\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Member\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"memberName\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]},{\"t\":2,\"p\":1,\"n\":\"String\"},{\"t\":3,\"p\":1,\"n\":\"Int32\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":3,\"p\":1,\"n\":\"Bool\"},{\"t\":7,\"p\":1,\"n\":\"Array of Object\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]}]},{\"t\":7,\"p\":1,\"n\":\"Array of String\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Int32\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Float\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Bool\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]}]}]}]}]}]}]}]}]},{\"t\":3,\"p\":1,\"n\":\"NAME - Base\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"XMBO - Bound Half Extents\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"X\"},{\"t\":5,\"p\":1,\"n\":\"Y\"},{\"t\":5,\"p\":1,\"n\":\"Z\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"XPRM - Primitive\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Bounds\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"X\"},{\"t\":5,\"p\":1,\"n\":\"Y\"},{\"t\":5,\"p\":1,\"n\":\"Z\"}]},{\"t\":6,\"p\":1,\"n\":\"Color\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Red\"},{\"t\":5,\"p\":1,\"n\":\"Green\"},{\"t\":5,\"p\":1,\"n\":\"Blue\"}]},{\"t\":5,\"n\":\"Unknown\"},{\"t\":3,\"p\":1,\"n\":\"Type\"}]},{\"t\":7,\"p\":1,\"n\":\"XPOD - Portal Data\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"References\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Origin\"},{\"t\":3,\"p\":1,\"n\":\"Destination\"}]}]},{\"t\":11,\"n\":\"XORD - Unknown\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"XOCP - Occlusion Plane Data\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Size\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Width\"},{\"t\":5,\"p\":1,\"n\":\"Height\"}]},{\"t\":6,\"p\":1,\"n\":\"Position\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"X\"},{\"t\":5,\"p\":1,\"n\":\"Y\"},{\"t\":5,\"p\":1,\"n\":\"Z\"}]},{\"t\":6,\"p\":1,\"n\":\"Rotation (Quaternion?)\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"q1\"},{\"t\":5,\"p\":1,\"n\":\"q2\"},{\"t\":5,\"p\":1,\"n\":\"q3\"},{\"t\":5,\"p\":1,\"n\":\"q4\"}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Bound Data\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"XRMR - Header\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Linked Rooms Count\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":3,\"p\":1,\"n\":\"LNAM - Lighting Template\"},{\"t\":3,\"p\":1,\"n\":\"INAM - Image Space\"},{\"t\":8,\"p\":1,\"n\":\"Linked Rooms\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"XLRM - Linked Room\"}]}]},{\"p\":1,\"n\":\"XMBP - MultiBound Primitive Marker\"},{\"t\":11,\"n\":\"XRGD - Ragdoll Data\"},{\"t\":11,\"n\":\"XRGB - Ragdoll Biped Data\"},{\"t\":5,\"p\":1,\"n\":\"XRDS - Radius\"},{\"t\":5,\"p\":1,\"n\":\"XSCL - Scale\"},{\"t\":3,\"p\":1,\"n\":\"XEMI - Emittance\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"XLIG - Light Data\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"FOV 90+\\/-\"},{\"t\":5,\"p\":1,\"n\":\"Fade 1.0+\\/-\"},{\"t\":5,\"p\":1,\"n\":\"End Distance Cap\"},{\"t\":5,\"p\":1,\"n\":\"Shadow Depth Bias\"},{\"t\":5,\"p\":1,\"n\":\"Near Clip\"},{\"t\":5,\"p\":1,\"n\":\"Volumetric Intensity\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"XALP - Alpha\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Cutoff\"},{\"t\":3,\"p\":1,\"n\":\"Base\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"XTEL - Teleport Destination\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Door\"},{\"t\":6,\"p\":1,\"n\":\"Position\\/Rotation\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Position\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"X\"},{\"t\":5,\"p\":1,\"n\":\"Y\"},{\"t\":5,\"p\":1,\"n\":\"Z\"}]},{\"t\":6,\"p\":1,\"n\":\"Rotation\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"X\"},{\"t\":5,\"p\":1,\"n\":\"Y\"},{\"t\":5,\"p\":1,\"n\":\"Z\"}]}]},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":3,\"p\":1,\"n\":\"Transition Interior\"}]},{\"t\":3,\"p\":1,\"n\":\"XTNM - Teleport Loc Name\"},{\"t\":3,\"p\":1,\"n\":\"XMBR - MultiBound Reference\"},{\"t\":11,\"n\":\"XWCN - Unknown\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"XWCU - Water Velocity\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"X Offset\"},{\"t\":5,\"p\":1,\"n\":\"Y Offset\"},{\"t\":5,\"p\":1,\"n\":\"Z Offset\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":5,\"p\":1,\"n\":\"X Angle\"},{\"t\":5,\"p\":1,\"n\":\"Y Angle\"},{\"t\":5,\"p\":1,\"n\":\"Z Angle\"}]},{\"t\":3,\"p\":1,\"n\":\"XASP - Acoustic Restriction\"},{\"p\":1,\"n\":\"XATP - Activation Point\"},{\"t\":3,\"p\":1,\"n\":\"XAMC - Ammo Count\"},{\"p\":1,\"n\":\"XLKT - Linked Ref Transient\"},{\"t\":3,\"p\":1,\"n\":\"XLYR - Layer\"},{\"t\":3,\"p\":1,\"n\":\"XMSP - Material Swap\"},{\"t\":3,\"p\":1,\"n\":\"XRFG - Reference Group\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"XRDO - Radio\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Frequency\"},{\"t\":5,\"p\":1,\"n\":\"Min Weak Distance\"},{\"t\":5,\"p\":1,\"n\":\"Max Weak Distance\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"XBSD - Spline\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Slack\"},{\"t\":5,\"p\":1,\"n\":\"Thickness\"},{\"t\":5,\"n\":\"Unknown\"},{\"t\":3,\"p\":1,\"n\":\"Wind - Detached End\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"XPDD - Projected Decal\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Width Scale\"},{\"t\":5,\"p\":1,\"n\":\"Height Scale\"}]},{\"t\":3,\"p\":1,\"n\":\"XSPC - Spawn Container\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Activate Parents\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"XAPD - Flags\"},{\"t\":8,\"p\":1,\"n\":\"Activate Parent Refs\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"XAPR - Activate Parent Ref\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":5,\"p\":1,\"n\":\"Delay\"}]}]}]},{\"t\":3,\"p\":1,\"n\":\"XLIB - Leveled Item Base Object\"},{\"t\":3,\"p\":1,\"n\":\"XLCM - Level Modifier\"},{\"t\":3,\"p\":1,\"n\":\"XLCN - Persistent Location\"},{\"t\":3,\"p\":1,\"n\":\"XTRI - Collision Layer\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"XLOC - Lock Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Level\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Key\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":3,\"p\":1,\"n\":\"XEZN - Encounter Zone\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"XNDP - Navigation Door Link\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Navigation Mesh\"},{\"t\":3,\"p\":1,\"n\":\"Teleport Marker Triangle\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":3,\"p\":1,\"n\":\"XLRL - Location Reference\"},{\"t\":7,\"p\":1,\"n\":\"XLRT - Location Ref Type\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Ref\"}]},{\"p\":1,\"n\":\"XIS2 - Ignored by Sandbox\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"XOWN - Owner\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Owner\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"}]},{\"t\":3,\"p\":1,\"n\":\"XRNK - Owner Faction Rank\"},{\"t\":3,\"p\":1,\"n\":\"XCNT - Item Count\"},{\"t\":3,\"p\":1,\"n\":\"XHLT - Health %\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"XESP - Enable Parent\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Linked References\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"XLKR - Linked Reference\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Keyword\\/Ref\"},{\"t\":3,\"p\":1,\"n\":\"Ref\"}]}]},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Patrol\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Data\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"XPRD - Idle Time\"},{\"p\":1,\"n\":\"XPPA - Patrol Script Marker\"},{\"t\":3,\"p\":1,\"n\":\"INAM - Idle\"},{\"t\":8,\"p\":1,\"n\":\"Topic\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"PDTO - Topic Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Topic\"},{\"t\":2,\"p\":1,\"n\":\"Subtype\"}]}]}]}]},{\"t\":3,\"p\":1,\"n\":\"XACT - Action Flag\"},{\"t\":5,\"p\":1,\"n\":\"XHTW - Head-Tracking Weight\"},{\"t\":5,\"p\":1,\"n\":\"XFVC - Favor Cost\"},{\"p\":1,\"n\":\"ONAM - Open by Default\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Map Marker\",\"c\":[{\"p\":1,\"n\":\"XMRK - Map Marker Data\"},{\"t\":3,\"p\":1,\"n\":\"FNAM - Map Flags\"},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":6,\"p\":1,\"n\":\"TNAM - \",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":11,\"n\":\"Unused\"}]}]},{\"t\":3,\"p\":1,\"n\":\"XATR - Attach Ref\"},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Spline Connection\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"XPLK - Link\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Ref\"},{\"t\":11,\"n\":\"Unknown\"}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Power Grid\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"XWPG - Count\"},{\"t\":8,\"p\":1,\"n\":\"Connections\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"XWPN - Connection\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Node 1\"},{\"t\":3,\"p\":1,\"n\":\"Node 2\"},{\"t\":3,\"p\":1,\"n\":\"Line\"}]}]}]},{\"t\":11,\"n\":\"XCVR - Unknown\"},{\"t\":11,\"n\":\"XCVL - Unknown\"},{\"t\":3,\"n\":\"XCZR - Unknown\"},{\"t\":11,\"n\":\"XCZA - Unknown\"},{\"t\":3,\"n\":\"XCZC - Unknown\"},{\"t\":7,\"n\":\"XLOD - Distant LOD Data\",\"c\":[{\"t\":5,\"n\":\"Unknown\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DATA - Position\\/Rotation\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Position\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"X\"},{\"t\":5,\"p\":1,\"n\":\"Y\"},{\"t\":5,\"p\":1,\"n\":\"Z\"}]},{\"t\":6,\"p\":1,\"n\":\"Rotation\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"X\"},{\"t\":5,\"p\":1,\"n\":\"Y\"},{\"t\":5,\"p\":1,\"n\":\"Z\"}]}]},{\"t\":2,\"p\":1,\"n\":\"MNAM - Comments\"}]},{\"t\":1,\"p\":1,\"n\":\"REGN - Region\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"RCLR - Map Color\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":3,\"p\":1,\"n\":\"WNAM - Worldspace\"},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Region Areas\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Region Area\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"RPLI - Edge Fall-off\"},{\"t\":7,\"p\":1,\"n\":\"RPLD - Region Point List Data\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Point\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"X\"},{\"t\":5,\"p\":1,\"n\":\"Y\"}]}]},{\"t\":11,\"n\":\"ANAM - Unknown\"}]}]},{\"t\":10,\"p\":1,\"n\":\"Region Data Entries\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Region Data Entry\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"RDAT - Data Header\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":3,\"p\":1,\"n\":\"Priority\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":2,\"p\":1,\"n\":\"ICON - Inventory Image\"},{\"t\":3,\"p\":1,\"n\":\"RDMO - Music\"},{\"t\":7,\"p\":1,\"n\":\"RDSA - Sounds\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Sound\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Sound\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":5,\"p\":1,\"n\":\"Chance\"}]}]},{\"t\":2,\"p\":1,\"n\":\"RDMP - Map Name\"},{\"t\":7,\"p\":1,\"n\":\"RDOT - Objects\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Object\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Object\"},{\"t\":3,\"p\":1,\"n\":\"Parent Index\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":5,\"p\":1,\"n\":\"Density\"},{\"t\":3,\"p\":1,\"n\":\"Clustering\"},{\"t\":3,\"p\":1,\"n\":\"Min Slope\"},{\"t\":3,\"p\":1,\"n\":\"Max Slope\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":3,\"p\":1,\"n\":\"Radius wrt Parent\"},{\"t\":3,\"p\":1,\"n\":\"Radius\"},{\"t\":5,\"p\":1,\"n\":\"Min Height\"},{\"t\":5,\"p\":1,\"n\":\"Max Height\"},{\"t\":5,\"p\":1,\"n\":\"Sink\"},{\"t\":5,\"p\":1,\"n\":\"Sink Variance\"},{\"t\":5,\"p\":1,\"n\":\"Size Variance\"},{\"t\":6,\"p\":1,\"n\":\"Angle Variance\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"X\"},{\"t\":3,\"p\":1,\"n\":\"Y\"},{\"t\":3,\"p\":1,\"n\":\"Z\"}]}]}]},{\"t\":7,\"p\":1,\"n\":\"RDGS - Grasses\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Grass\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Grass\"},{\"t\":11,\"n\":\"Unknown\"}]}]},{\"t\":7,\"p\":1,\"n\":\"RDWT - Weather Types\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Weather Type\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Weather\"},{\"t\":3,\"p\":1,\"n\":\"Chance\"},{\"t\":3,\"p\":1,\"n\":\"Global\"}]}]},{\"t\":5,\"p\":1,\"n\":\"RLDM - LOD Display Distance Multiplier\"},{\"t\":5,\"p\":1,\"n\":\"ANAM - Occlusion Accuracy Dist\"}]}]}]},{\"t\":1,\"p\":1,\"n\":\"RELA - Relationship\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DATA - Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Parent\"},{\"t\":3,\"p\":1,\"n\":\"Child\"},{\"t\":3,\"p\":1,\"n\":\"Rank\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":3,\"p\":1,\"n\":\"Association Type\"}]}]},{\"t\":1,\"p\":1,\"n\":\"REVB - Reverb Parameters\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DATA - Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Decay Time (ms)\"},{\"t\":3,\"p\":1,\"n\":\"HF Reference (Hz)\"},{\"t\":3,\"p\":1,\"n\":\"Room Filter\"},{\"t\":3,\"p\":1,\"n\":\"Room HF Filter\"},{\"t\":3,\"p\":1,\"n\":\"Reflections\"},{\"t\":3,\"p\":1,\"n\":\"Reverb Amp\"},{\"t\":3,\"p\":1,\"n\":\"Decay HF Ratio\"},{\"t\":3,\"p\":1,\"n\":\"Reflect Delay (ms), scaled\"},{\"t\":3,\"p\":1,\"n\":\"Reverb Delay (ms)\"},{\"t\":3,\"p\":1,\"n\":\"Diffusion %\"},{\"t\":3,\"p\":1,\"n\":\"Density %\"},{\"t\":3,\"n\":\"Unknown\"}]},{\"t\":3,\"p\":1,\"n\":\"ANAM - Reverb Class\"}]},{\"t\":1,\"p\":1,\"n\":\"RFCT - Visual Effect\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DATA - Effect Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Effect Art\"},{\"t\":3,\"p\":1,\"n\":\"Shader\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"}]}]},{\"t\":1,\"p\":1,\"n\":\"RFGP - Reference Group\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"p\":1,\"n\":\"NNAM - Name\"},{\"t\":3,\"p\":1,\"n\":\"RNAM - Reference\"},{\"t\":11,\"n\":\"PNAM - Unknown\"}]},{\"t\":1,\"p\":1,\"n\":\"SCCO - Scene Collection\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":3,\"p\":1,\"n\":\"QNAM - Quest\"},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Scenes\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Scene\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"SNAM - Scene\"},{\"t\":6,\"n\":\"XNAM - Unknown\",\"c\":[{\"t\":3,\"n\":\"Unknown\"}]}]}]},{\"t\":11,\"n\":\"VNAM - Unknown\"},{\"t\":8,\"n\":\"Unknown\",\"c\":[{\"t\":6,\"n\":\"XNAM - Unknown\",\"c\":[{\"t\":3,\"n\":\"Unknown\"}]}]}]},{\"t\":1,\"p\":1,\"n\":\"SCEN - Scene\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"VMAD - Virtual Machine Adapter\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Version\"},{\"t\":3,\"p\":1,\"n\":\"Object Format\"},{\"t\":7,\"p\":1,\"n\":\"Scripts\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Script\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"scriptName\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":7,\"p\":1,\"n\":\"Properties\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Property\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"propertyName\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]},{\"t\":2,\"p\":1,\"n\":\"String\"},{\"t\":3,\"p\":1,\"n\":\"Int32\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":3,\"p\":1,\"n\":\"Bool\"},{\"t\":7,\"p\":1,\"n\":\"Struct\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Member\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"memberName\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]},{\"t\":2,\"p\":1,\"n\":\"String\"},{\"t\":3,\"p\":1,\"n\":\"Int32\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":3,\"p\":1,\"n\":\"Bool\"},{\"t\":7,\"p\":1,\"n\":\"Array of Object\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]}]},{\"t\":7,\"p\":1,\"n\":\"Array of String\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Int32\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Float\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Bool\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]}]}]},{\"t\":7,\"p\":1,\"n\":\"Array of Object\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]}]},{\"t\":7,\"p\":1,\"n\":\"Array of String\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Int32\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Float\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Bool\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Struct\",\"c\":[{\"t\":7,\"p\":1,\"n\":\"Struct\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Member\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"memberName\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]},{\"t\":2,\"p\":1,\"n\":\"String\"},{\"t\":3,\"p\":1,\"n\":\"Int32\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":3,\"p\":1,\"n\":\"Bool\"},{\"t\":7,\"p\":1,\"n\":\"Array of Object\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]}]},{\"t\":7,\"p\":1,\"n\":\"Array of String\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Int32\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Float\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Bool\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]}]}]}]}]}]}]}]},{\"t\":6,\"p\":1,\"n\":\"Script Fragments\",\"c\":[{\"t\":3,\"n\":\"Unknown\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":6,\"p\":1,\"n\":\"Script\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"scriptName\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":7,\"p\":1,\"n\":\"Properties\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Property\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"propertyName\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]},{\"t\":2,\"p\":1,\"n\":\"String\"},{\"t\":3,\"p\":1,\"n\":\"Int32\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":3,\"p\":1,\"n\":\"Bool\"},{\"t\":7,\"p\":1,\"n\":\"Struct\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Member\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"memberName\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]},{\"t\":2,\"p\":1,\"n\":\"String\"},{\"t\":3,\"p\":1,\"n\":\"Int32\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":3,\"p\":1,\"n\":\"Bool\"},{\"t\":7,\"p\":1,\"n\":\"Array of Object\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]}]},{\"t\":7,\"p\":1,\"n\":\"Array of String\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Int32\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Float\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Bool\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]}]}]},{\"t\":7,\"p\":1,\"n\":\"Array of Object\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]}]},{\"t\":7,\"p\":1,\"n\":\"Array of String\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Int32\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Float\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Bool\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Struct\",\"c\":[{\"t\":7,\"p\":1,\"n\":\"Struct\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Member\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"memberName\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]},{\"t\":2,\"p\":1,\"n\":\"String\"},{\"t\":3,\"p\":1,\"n\":\"Int32\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":3,\"p\":1,\"n\":\"Bool\"},{\"t\":7,\"p\":1,\"n\":\"Array of Object\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]}]},{\"t\":7,\"p\":1,\"n\":\"Array of String\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Int32\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Float\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Bool\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]}]}]}]}]}]}]},{\"t\":7,\"p\":1,\"n\":\"Fragments\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Fragment\",\"c\":[{\"t\":3,\"n\":\"Unknown\"},{\"t\":2,\"p\":1,\"n\":\"scriptName\"},{\"t\":2,\"p\":1,\"n\":\"fragmentName\"}]}]},{\"t\":7,\"p\":1,\"n\":\"Phase Fragments\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Phase Fragment\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Phase Flag\"},{\"t\":3,\"p\":1,\"n\":\"Phase Index\"},{\"t\":3,\"n\":\"Unknown\"},{\"t\":2,\"p\":1,\"n\":\"scriptName\"},{\"t\":2,\"p\":1,\"n\":\"fragmentName\"}]}]}]}]},{\"t\":3,\"p\":1,\"n\":\"FNAM - Flags\"},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Phases\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Phase\",\"c\":[{\"p\":1,\"n\":\"HNAM - Marker Phase Start\"},{\"t\":2,\"p\":1,\"n\":\"NAM0 - Name\"},{\"t\":6,\"p\":1,\"n\":\"Start Conditions\",\"c\":[{\"t\":8,\"p\":1,\"n\":\"Conditions\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Condition\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"CTDA - \",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":5,\"p\":1,\"n\":\"Comparison Value - Float\"},{\"t\":3,\"p\":1,\"n\":\"Comparison Value - Global\"},{\"t\":3,\"p\":1,\"n\":\"Function\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":11,\"p\":1,\"n\":\"None\"},{\"t\":3,\"p\":1,\"n\":\"Integer\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":3,\"p\":1,\"n\":\"Actor\"},{\"t\":3,\"p\":1,\"n\":\"Actor Base\"},{\"t\":3,\"p\":1,\"n\":\"Actor Value\"},{\"t\":3,\"p\":1,\"n\":\"Player Action\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"Alignment\"},{\"t\":3,\"p\":1,\"n\":\"Association Type\"},{\"t\":3,\"p\":1,\"n\":\"Axis\"},{\"t\":3,\"p\":1,\"n\":\"Casting Type\"},{\"t\":3,\"p\":1,\"n\":\"Cell\"},{\"t\":3,\"p\":1,\"n\":\"Class\"},{\"t\":3,\"p\":1,\"n\":\"Crime Type\"},{\"t\":3,\"p\":1,\"n\":\"Critical Stage\"},{\"t\":3,\"p\":1,\"n\":\"Encounter Zone\"},{\"t\":3,\"p\":1,\"n\":\"Equip Type\"},{\"t\":3,\"p\":1,\"n\":\"Event\"},{\"t\":3,\"p\":1,\"n\":\"Event Data\"},{\"t\":3,\"p\":1,\"n\":\"Faction\"},{\"t\":3,\"p\":1,\"n\":\"Form List\"},{\"t\":3,\"p\":1,\"n\":\"Form Type\"},{\"t\":3,\"p\":1,\"n\":\"Furniture\"},{\"t\":3,\"p\":1,\"n\":\"Furniture Anim\"},{\"t\":3,\"p\":1,\"n\":\"Furniture Entry\"},{\"t\":3,\"p\":1,\"n\":\"Global\"},{\"t\":3,\"p\":1,\"n\":\"Idle\"},{\"t\":3,\"p\":1,\"n\":\"Inventory Object\"},{\"t\":3,\"p\":1,\"n\":\"Keyword\"},{\"t\":3,\"p\":1,\"n\":\"Location\"},{\"t\":3,\"p\":1,\"n\":\"Base Effect\"},{\"t\":3,\"p\":1,\"n\":\"Effect Item\"},{\"t\":3,\"p\":1,\"n\":\"Misc Stat\"},{\"t\":3,\"p\":1,\"n\":\"Object Reference\"},{\"t\":3,\"p\":1,\"n\":\"Owner\"},{\"t\":3,\"p\":1,\"n\":\"Package\"},{\"t\":3,\"p\":1,\"n\":\"Packdata ID\"},{\"t\":3,\"p\":1,\"n\":\"Perk\"},{\"t\":3,\"p\":1,\"n\":\"Quest\"},{\"t\":3,\"p\":1,\"n\":\"Quest Stage\"},{\"t\":3,\"p\":1,\"n\":\"Race\"},{\"t\":3,\"p\":1,\"n\":\"Referenceable Object\"},{\"t\":3,\"p\":1,\"n\":\"Location Ref Type\"},{\"t\":3,\"p\":1,\"n\":\"Region\"},{\"t\":3,\"p\":1,\"n\":\"Scene\"},{\"t\":3,\"p\":1,\"n\":\"Sex\"},{\"t\":3,\"p\":1,\"n\":\"Shout\"},{\"t\":11,\"p\":1,\"n\":\"Variable Name (unused)\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Function\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Param (unused)\"},{\"t\":3,\"p\":1,\"n\":\"Voice Type\"},{\"t\":3,\"p\":1,\"n\":\"Ward State\"},{\"t\":3,\"p\":1,\"n\":\"Weather\"},{\"t\":3,\"p\":1,\"n\":\"Worldspace\"},{\"t\":3,\"p\":1,\"n\":\"Damage Type\"},{\"t\":3,\"p\":1,\"n\":\"Weapon\"},{\"t\":3,\"p\":1,\"n\":\"Weapon List\"},{\"t\":3,\"p\":1,\"n\":\"Target\"},{\"t\":3,\"p\":1,\"n\":\"Target List\"},{\"t\":3,\"p\":1,\"n\":\"Target Part\"},{\"t\":3,\"p\":1,\"n\":\"VATS Action\"},{\"t\":3,\"p\":1,\"n\":\"Critical Effect\"},{\"t\":3,\"p\":1,\"n\":\"Critical Effect List\"},{\"t\":3,\"p\":1,\"n\":\"Weapon Type\"},{\"t\":3,\"p\":1,\"n\":\"Projectile Type\"},{\"t\":3,\"p\":1,\"n\":\"Delivery Type\"},{\"t\":3,\"p\":1,\"n\":\"Run On\"},{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":3,\"p\":1,\"n\":\"Parameter #3\"}]},{\"t\":2,\"p\":1,\"n\":\"CIS1 - Parameter #1\"},{\"t\":2,\"p\":1,\"n\":\"CIS2 - Parameter #2\"}]}]}]},{\"p\":1,\"n\":\"NEXT - Marker Start Conditions\"},{\"t\":6,\"p\":1,\"n\":\"Completion Conditions\",\"c\":[{\"t\":8,\"p\":1,\"n\":\"Conditions\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Condition\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"CTDA - \",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":5,\"p\":1,\"n\":\"Comparison Value - Float\"},{\"t\":3,\"p\":1,\"n\":\"Comparison Value - Global\"},{\"t\":3,\"p\":1,\"n\":\"Function\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":11,\"p\":1,\"n\":\"None\"},{\"t\":3,\"p\":1,\"n\":\"Integer\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":3,\"p\":1,\"n\":\"Actor\"},{\"t\":3,\"p\":1,\"n\":\"Actor Base\"},{\"t\":3,\"p\":1,\"n\":\"Actor Value\"},{\"t\":3,\"p\":1,\"n\":\"Player Action\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"Alignment\"},{\"t\":3,\"p\":1,\"n\":\"Association Type\"},{\"t\":3,\"p\":1,\"n\":\"Axis\"},{\"t\":3,\"p\":1,\"n\":\"Casting Type\"},{\"t\":3,\"p\":1,\"n\":\"Cell\"},{\"t\":3,\"p\":1,\"n\":\"Class\"},{\"t\":3,\"p\":1,\"n\":\"Crime Type\"},{\"t\":3,\"p\":1,\"n\":\"Critical Stage\"},{\"t\":3,\"p\":1,\"n\":\"Encounter Zone\"},{\"t\":3,\"p\":1,\"n\":\"Equip Type\"},{\"t\":3,\"p\":1,\"n\":\"Event\"},{\"t\":3,\"p\":1,\"n\":\"Event Data\"},{\"t\":3,\"p\":1,\"n\":\"Faction\"},{\"t\":3,\"p\":1,\"n\":\"Form List\"},{\"t\":3,\"p\":1,\"n\":\"Form Type\"},{\"t\":3,\"p\":1,\"n\":\"Furniture\"},{\"t\":3,\"p\":1,\"n\":\"Furniture Anim\"},{\"t\":3,\"p\":1,\"n\":\"Furniture Entry\"},{\"t\":3,\"p\":1,\"n\":\"Global\"},{\"t\":3,\"p\":1,\"n\":\"Idle\"},{\"t\":3,\"p\":1,\"n\":\"Inventory Object\"},{\"t\":3,\"p\":1,\"n\":\"Keyword\"},{\"t\":3,\"p\":1,\"n\":\"Location\"},{\"t\":3,\"p\":1,\"n\":\"Base Effect\"},{\"t\":3,\"p\":1,\"n\":\"Effect Item\"},{\"t\":3,\"p\":1,\"n\":\"Misc Stat\"},{\"t\":3,\"p\":1,\"n\":\"Object Reference\"},{\"t\":3,\"p\":1,\"n\":\"Owner\"},{\"t\":3,\"p\":1,\"n\":\"Package\"},{\"t\":3,\"p\":1,\"n\":\"Packdata ID\"},{\"t\":3,\"p\":1,\"n\":\"Perk\"},{\"t\":3,\"p\":1,\"n\":\"Quest\"},{\"t\":3,\"p\":1,\"n\":\"Quest Stage\"},{\"t\":3,\"p\":1,\"n\":\"Race\"},{\"t\":3,\"p\":1,\"n\":\"Referenceable Object\"},{\"t\":3,\"p\":1,\"n\":\"Location Ref Type\"},{\"t\":3,\"p\":1,\"n\":\"Region\"},{\"t\":3,\"p\":1,\"n\":\"Scene\"},{\"t\":3,\"p\":1,\"n\":\"Sex\"},{\"t\":3,\"p\":1,\"n\":\"Shout\"},{\"t\":11,\"p\":1,\"n\":\"Variable Name (unused)\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Function\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Param (unused)\"},{\"t\":3,\"p\":1,\"n\":\"Voice Type\"},{\"t\":3,\"p\":1,\"n\":\"Ward State\"},{\"t\":3,\"p\":1,\"n\":\"Weather\"},{\"t\":3,\"p\":1,\"n\":\"Worldspace\"},{\"t\":3,\"p\":1,\"n\":\"Damage Type\"},{\"t\":3,\"p\":1,\"n\":\"Weapon\"},{\"t\":3,\"p\":1,\"n\":\"Weapon List\"},{\"t\":3,\"p\":1,\"n\":\"Target\"},{\"t\":3,\"p\":1,\"n\":\"Target List\"},{\"t\":3,\"p\":1,\"n\":\"Target Part\"},{\"t\":3,\"p\":1,\"n\":\"VATS Action\"},{\"t\":3,\"p\":1,\"n\":\"Critical Effect\"},{\"t\":3,\"p\":1,\"n\":\"Critical Effect List\"},{\"t\":3,\"p\":1,\"n\":\"Weapon Type\"},{\"t\":3,\"p\":1,\"n\":\"Projectile Type\"},{\"t\":3,\"p\":1,\"n\":\"Delivery Type\"},{\"t\":3,\"p\":1,\"n\":\"Run On\"},{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":3,\"p\":1,\"n\":\"Parameter #3\"}]},{\"t\":2,\"p\":1,\"n\":\"CIS1 - Parameter #1\"},{\"t\":2,\"p\":1,\"n\":\"CIS2 - Parameter #2\"}]}]}]},{\"p\":1,\"n\":\"NEXT - Marker Completion Conditions\"},{\"t\":3,\"p\":1,\"n\":\"WNAM - Editor Width\"},{\"t\":3,\"p\":1,\"n\":\"FNAM - Flags\"},{\"t\":6,\"p\":1,\"n\":\"SCQS - Set Parent Quest Stage\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"On Start\"},{\"t\":3,\"p\":1,\"n\":\"On Completion\"}]},{\"p\":1,\"n\":\"HNAM - Marker Phase End\"}]}]},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Actors\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Actor\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"ALID - Alias ID\"},{\"t\":3,\"p\":1,\"n\":\"LNAM - Flags\"},{\"t\":3,\"p\":1,\"n\":\"DNAM - Behaviour Flags\"}]}]},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Actions\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Action\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"ANAM - Type\"},{\"t\":2,\"p\":1,\"n\":\"NAM0 - Name\"},{\"t\":3,\"p\":1,\"n\":\"ALID - Alias ID\"},{\"t\":3,\"p\":1,\"n\":\"INAM - Index\"},{\"t\":3,\"p\":1,\"n\":\"FNAM - Flags\"},{\"t\":3,\"p\":1,\"n\":\"SNAM - Start Phase\"},{\"t\":3,\"p\":1,\"n\":\"ENAM - End Phase\"},{\"t\":5,\"p\":1,\"n\":\"SNAM - Timer - Max Seconds\"},{\"t\":3,\"p\":1,\"n\":\"SCQS - Set Parent Quest Stage\"},{\"t\":5,\"p\":1,\"n\":\"TNAM - Timer - Min Seconds\"},{\"t\":11,\"n\":\"STSC - Unknown\"},{\"t\":8,\"p\":1,\"n\":\"Start Scenes\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Start Scene\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"LCEP - Scene\"},{\"t\":3,\"p\":1,\"n\":\"INTT - Phase Index\"},{\"t\":2,\"p\":1,\"n\":\"SSPN - Start Phase for Scene\"},{\"t\":3,\"p\":1,\"n\":\"CITC - Condition Count\"},{\"t\":8,\"p\":1,\"n\":\"Conditions\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Condition\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"CTDA - \",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":5,\"p\":1,\"n\":\"Comparison Value - Float\"},{\"t\":3,\"p\":1,\"n\":\"Comparison Value - Global\"},{\"t\":3,\"p\":1,\"n\":\"Function\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":11,\"p\":1,\"n\":\"None\"},{\"t\":3,\"p\":1,\"n\":\"Integer\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":3,\"p\":1,\"n\":\"Actor\"},{\"t\":3,\"p\":1,\"n\":\"Actor Base\"},{\"t\":3,\"p\":1,\"n\":\"Actor Value\"},{\"t\":3,\"p\":1,\"n\":\"Player Action\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"Alignment\"},{\"t\":3,\"p\":1,\"n\":\"Association Type\"},{\"t\":3,\"p\":1,\"n\":\"Axis\"},{\"t\":3,\"p\":1,\"n\":\"Casting Type\"},{\"t\":3,\"p\":1,\"n\":\"Cell\"},{\"t\":3,\"p\":1,\"n\":\"Class\"},{\"t\":3,\"p\":1,\"n\":\"Crime Type\"},{\"t\":3,\"p\":1,\"n\":\"Critical Stage\"},{\"t\":3,\"p\":1,\"n\":\"Encounter Zone\"},{\"t\":3,\"p\":1,\"n\":\"Equip Type\"},{\"t\":3,\"p\":1,\"n\":\"Event\"},{\"t\":3,\"p\":1,\"n\":\"Event Data\"},{\"t\":3,\"p\":1,\"n\":\"Faction\"},{\"t\":3,\"p\":1,\"n\":\"Form List\"},{\"t\":3,\"p\":1,\"n\":\"Form Type\"},{\"t\":3,\"p\":1,\"n\":\"Furniture\"},{\"t\":3,\"p\":1,\"n\":\"Furniture Anim\"},{\"t\":3,\"p\":1,\"n\":\"Furniture Entry\"},{\"t\":3,\"p\":1,\"n\":\"Global\"},{\"t\":3,\"p\":1,\"n\":\"Idle\"},{\"t\":3,\"p\":1,\"n\":\"Inventory Object\"},{\"t\":3,\"p\":1,\"n\":\"Keyword\"},{\"t\":3,\"p\":1,\"n\":\"Location\"},{\"t\":3,\"p\":1,\"n\":\"Base Effect\"},{\"t\":3,\"p\":1,\"n\":\"Effect Item\"},{\"t\":3,\"p\":1,\"n\":\"Misc Stat\"},{\"t\":3,\"p\":1,\"n\":\"Object Reference\"},{\"t\":3,\"p\":1,\"n\":\"Owner\"},{\"t\":3,\"p\":1,\"n\":\"Package\"},{\"t\":3,\"p\":1,\"n\":\"Packdata ID\"},{\"t\":3,\"p\":1,\"n\":\"Perk\"},{\"t\":3,\"p\":1,\"n\":\"Quest\"},{\"t\":3,\"p\":1,\"n\":\"Quest Stage\"},{\"t\":3,\"p\":1,\"n\":\"Race\"},{\"t\":3,\"p\":1,\"n\":\"Referenceable Object\"},{\"t\":3,\"p\":1,\"n\":\"Location Ref Type\"},{\"t\":3,\"p\":1,\"n\":\"Region\"},{\"t\":3,\"p\":1,\"n\":\"Scene\"},{\"t\":3,\"p\":1,\"n\":\"Sex\"},{\"t\":3,\"p\":1,\"n\":\"Shout\"},{\"t\":11,\"p\":1,\"n\":\"Variable Name (unused)\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Function\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Param (unused)\"},{\"t\":3,\"p\":1,\"n\":\"Voice Type\"},{\"t\":3,\"p\":1,\"n\":\"Ward State\"},{\"t\":3,\"p\":1,\"n\":\"Weather\"},{\"t\":3,\"p\":1,\"n\":\"Worldspace\"},{\"t\":3,\"p\":1,\"n\":\"Damage Type\"},{\"t\":3,\"p\":1,\"n\":\"Weapon\"},{\"t\":3,\"p\":1,\"n\":\"Weapon List\"},{\"t\":3,\"p\":1,\"n\":\"Target\"},{\"t\":3,\"p\":1,\"n\":\"Target List\"},{\"t\":3,\"p\":1,\"n\":\"Target Part\"},{\"t\":3,\"p\":1,\"n\":\"VATS Action\"},{\"t\":3,\"p\":1,\"n\":\"Critical Effect\"},{\"t\":3,\"p\":1,\"n\":\"Critical Effect List\"},{\"t\":3,\"p\":1,\"n\":\"Weapon Type\"},{\"t\":3,\"p\":1,\"n\":\"Projectile Type\"},{\"t\":3,\"p\":1,\"n\":\"Delivery Type\"},{\"t\":3,\"p\":1,\"n\":\"Run On\"},{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":3,\"p\":1,\"n\":\"Parameter #3\"}]},{\"t\":2,\"p\":1,\"n\":\"CIS1 - Parameter #1\"},{\"t\":2,\"p\":1,\"n\":\"CIS2 - Parameter #2\"}]}]}]}]},{\"t\":3,\"p\":1,\"n\":\"PTOP - Player Positive Response\"},{\"t\":3,\"p\":1,\"n\":\"NTOP - Player Negative Response\"},{\"t\":3,\"p\":1,\"n\":\"NETO - Player Neutral Response\"},{\"t\":3,\"p\":1,\"n\":\"QTOP - Player Question Response\"},{\"t\":3,\"p\":1,\"n\":\"VENC - Player Positive Dialogue Subtype\"},{\"t\":3,\"p\":1,\"n\":\"PLVD - Player Negative Dialogue Subtype\"},{\"t\":3,\"p\":1,\"n\":\"JOUT - Player Neutral Dialogue Subtype\"},{\"t\":3,\"p\":1,\"n\":\"DALC - Player Question Dialogue Subtype\"},{\"t\":7,\"p\":1,\"n\":\"DTID - NPC Headtracking\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Actor ID\"}]},{\"t\":3,\"p\":1,\"n\":\"NPOT - NPC Positive Response\"},{\"t\":3,\"p\":1,\"n\":\"NNGT - NPC Negative Response\"},{\"t\":3,\"p\":1,\"n\":\"NNUT - NPC Neutral Response\"},{\"t\":3,\"p\":1,\"n\":\"NQUT - NPC Question Response\"},{\"t\":3,\"p\":1,\"n\":\"NPOS - NPC Positive Dialogue Subtype\"},{\"t\":3,\"p\":1,\"n\":\"NNGS - NPC Negative Dialogue Subtype\"},{\"t\":3,\"p\":1,\"n\":\"NNUS - NPC Neutral Dialogue Subtype\"},{\"t\":3,\"p\":1,\"n\":\"NQUS - NPC Question Dialogue Subtype\"},{\"t\":3,\"p\":1,\"n\":\"DTGT - Dialogue Target Actor\"},{\"t\":8,\"p\":1,\"n\":\"Packages\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"PNAM - Package\"}]},{\"t\":3,\"p\":1,\"n\":\"DATA - Topic\"},{\"p\":1,\"n\":\"End Scene Say Greeting\"},{\"t\":3,\"p\":1,\"n\":\"Play Sound\"},{\"t\":5,\"p\":1,\"n\":\"DMAX - Looping - Max\"},{\"t\":5,\"p\":1,\"n\":\"DMIN - Looping - Min\"},{\"t\":6,\"p\":1,\"n\":\"CRIS - Camera\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"FOV On Player Camera\"},{\"t\":5,\"p\":1,\"n\":\"Rate Of Camera Change\"}]},{\"t\":3,\"p\":1,\"n\":\"DEMO - Emotion Type\"},{\"t\":3,\"p\":1,\"n\":\"DEVA - Emotion Value\"},{\"t\":7,\"p\":1,\"n\":\"HTID - Player Headtracking\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Actor ID\"}]},{\"t\":3,\"p\":1,\"n\":\"VENC - Dialogue Subtype\"},{\"t\":3,\"p\":1,\"n\":\"PNAM - AnimArchType\"},{\"t\":3,\"p\":1,\"n\":\"ONAM - Audio Output Override\"},{\"p\":1,\"n\":\"ANAM - End Marker\"}]}]},{\"t\":3,\"p\":1,\"n\":\"PNAM - Quest\"},{\"t\":3,\"p\":1,\"n\":\"INAM - Last Action Index\"},{\"t\":11,\"n\":\"VNAM - Unknown\"},{\"t\":5,\"p\":1,\"n\":\"CNAM - Camera Distance Override\"},{\"t\":5,\"p\":1,\"n\":\"ACTV - Dialogue Distance Override\"},{\"t\":5,\"p\":1,\"n\":\"CRIS - FOV Override\"},{\"t\":3,\"n\":\"KSIZ - Keyword Count\"},{\"t\":7,\"p\":1,\"n\":\"KWDA - Keywords\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Keyword\"}]},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Conditions\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Condition\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"CTDA - \",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":5,\"p\":1,\"n\":\"Comparison Value - Float\"},{\"t\":3,\"p\":1,\"n\":\"Comparison Value - Global\"},{\"t\":3,\"p\":1,\"n\":\"Function\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":11,\"p\":1,\"n\":\"None\"},{\"t\":3,\"p\":1,\"n\":\"Integer\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":3,\"p\":1,\"n\":\"Actor\"},{\"t\":3,\"p\":1,\"n\":\"Actor Base\"},{\"t\":3,\"p\":1,\"n\":\"Actor Value\"},{\"t\":3,\"p\":1,\"n\":\"Player Action\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"Alignment\"},{\"t\":3,\"p\":1,\"n\":\"Association Type\"},{\"t\":3,\"p\":1,\"n\":\"Axis\"},{\"t\":3,\"p\":1,\"n\":\"Casting Type\"},{\"t\":3,\"p\":1,\"n\":\"Cell\"},{\"t\":3,\"p\":1,\"n\":\"Class\"},{\"t\":3,\"p\":1,\"n\":\"Crime Type\"},{\"t\":3,\"p\":1,\"n\":\"Critical Stage\"},{\"t\":3,\"p\":1,\"n\":\"Encounter Zone\"},{\"t\":3,\"p\":1,\"n\":\"Equip Type\"},{\"t\":3,\"p\":1,\"n\":\"Event\"},{\"t\":3,\"p\":1,\"n\":\"Event Data\"},{\"t\":3,\"p\":1,\"n\":\"Faction\"},{\"t\":3,\"p\":1,\"n\":\"Form List\"},{\"t\":3,\"p\":1,\"n\":\"Form Type\"},{\"t\":3,\"p\":1,\"n\":\"Furniture\"},{\"t\":3,\"p\":1,\"n\":\"Furniture Anim\"},{\"t\":3,\"p\":1,\"n\":\"Furniture Entry\"},{\"t\":3,\"p\":1,\"n\":\"Global\"},{\"t\":3,\"p\":1,\"n\":\"Idle\"},{\"t\":3,\"p\":1,\"n\":\"Inventory Object\"},{\"t\":3,\"p\":1,\"n\":\"Keyword\"},{\"t\":3,\"p\":1,\"n\":\"Location\"},{\"t\":3,\"p\":1,\"n\":\"Base Effect\"},{\"t\":3,\"p\":1,\"n\":\"Effect Item\"},{\"t\":3,\"p\":1,\"n\":\"Misc Stat\"},{\"t\":3,\"p\":1,\"n\":\"Object Reference\"},{\"t\":3,\"p\":1,\"n\":\"Owner\"},{\"t\":3,\"p\":1,\"n\":\"Package\"},{\"t\":3,\"p\":1,\"n\":\"Packdata ID\"},{\"t\":3,\"p\":1,\"n\":\"Perk\"},{\"t\":3,\"p\":1,\"n\":\"Quest\"},{\"t\":3,\"p\":1,\"n\":\"Quest Stage\"},{\"t\":3,\"p\":1,\"n\":\"Race\"},{\"t\":3,\"p\":1,\"n\":\"Referenceable Object\"},{\"t\":3,\"p\":1,\"n\":\"Location Ref Type\"},{\"t\":3,\"p\":1,\"n\":\"Region\"},{\"t\":3,\"p\":1,\"n\":\"Scene\"},{\"t\":3,\"p\":1,\"n\":\"Sex\"},{\"t\":3,\"p\":1,\"n\":\"Shout\"},{\"t\":11,\"p\":1,\"n\":\"Variable Name (unused)\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Function\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Param (unused)\"},{\"t\":3,\"p\":1,\"n\":\"Voice Type\"},{\"t\":3,\"p\":1,\"n\":\"Ward State\"},{\"t\":3,\"p\":1,\"n\":\"Weather\"},{\"t\":3,\"p\":1,\"n\":\"Worldspace\"},{\"t\":3,\"p\":1,\"n\":\"Damage Type\"},{\"t\":3,\"p\":1,\"n\":\"Weapon\"},{\"t\":3,\"p\":1,\"n\":\"Weapon List\"},{\"t\":3,\"p\":1,\"n\":\"Target\"},{\"t\":3,\"p\":1,\"n\":\"Target List\"},{\"t\":3,\"p\":1,\"n\":\"Target Part\"},{\"t\":3,\"p\":1,\"n\":\"VATS Action\"},{\"t\":3,\"p\":1,\"n\":\"Critical Effect\"},{\"t\":3,\"p\":1,\"n\":\"Critical Effect List\"},{\"t\":3,\"p\":1,\"n\":\"Weapon Type\"},{\"t\":3,\"p\":1,\"n\":\"Projectile Type\"},{\"t\":3,\"p\":1,\"n\":\"Delivery Type\"},{\"t\":3,\"p\":1,\"n\":\"Run On\"},{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":3,\"p\":1,\"n\":\"Parameter #3\"}]},{\"t\":2,\"p\":1,\"n\":\"CIS1 - Parameter #1\"},{\"t\":2,\"p\":1,\"n\":\"CIS2 - Parameter #2\"}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"SCQS - Set Parent Quest Stage\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"On Begin\"},{\"t\":3,\"p\":1,\"n\":\"On End\"}]},{\"t\":2,\"p\":1,\"n\":\"NNAM - Notes\"},{\"t\":3,\"p\":1,\"n\":\"TNAM - Template Scene\"},{\"t\":3,\"p\":1,\"n\":\"XNAM - Index\"}]},{\"t\":1,\"p\":1,\"n\":\"SCOL - Static Collection\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"X1\"},{\"t\":3,\"p\":1,\"n\":\"Y1\"},{\"t\":3,\"p\":1,\"n\":\"Z1\"},{\"t\":3,\"p\":1,\"n\":\"X2\"},{\"t\":3,\"p\":1,\"n\":\"Y2\"},{\"t\":3,\"p\":1,\"n\":\"Z2\"}]},{\"t\":3,\"p\":1,\"n\":\"PTRN - Preview Transform\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"MODT - Texture Files Hashes\"},{\"t\":3,\"p\":1,\"n\":\"MODS - Material Swap\"},{\"t\":5,\"p\":1,\"n\":\"MODC - Color Remapping Index\"},{\"t\":11,\"n\":\"MODF - Unknown\"}]},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":2,\"p\":1,\"n\":\"FLTR - Filter\"},{\"t\":10,\"p\":1,\"n\":\"Parts\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Part\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"ONAM - Static\"},{\"t\":7,\"p\":1,\"n\":\"DATA - Placements\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Placement\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Position\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"X\"},{\"t\":5,\"p\":1,\"n\":\"Y\"},{\"t\":5,\"p\":1,\"n\":\"Z\"}]},{\"t\":6,\"p\":1,\"n\":\"Rotation\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"X\"},{\"t\":5,\"p\":1,\"n\":\"Y\"},{\"t\":5,\"p\":1,\"n\":\"Z\"}]},{\"t\":5,\"p\":1,\"n\":\"Scale\"}]}]}]}]}]},{\"t\":1,\"p\":1,\"n\":\"SCSN - Audio Category Snapshot\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":3,\"p\":1,\"n\":\"PNAM - Priority\"},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Category Multipliers\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"CNAM - Category Multiplier\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Categoty\"},{\"t\":5,\"p\":1,\"n\":\"Multiplier\"}]}]}]},{\"t\":1,\"p\":1,\"n\":\"SMBN - Story Manager Branch Node\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":3,\"p\":1,\"n\":\"PNAM - Parent \"},{\"t\":3,\"p\":1,\"n\":\"SNAM - Child \"},{\"t\":3,\"n\":\"CITC - Condition Count\"},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Conditions\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Condition\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"CTDA - \",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":5,\"p\":1,\"n\":\"Comparison Value - Float\"},{\"t\":3,\"p\":1,\"n\":\"Comparison Value - Global\"},{\"t\":3,\"p\":1,\"n\":\"Function\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":11,\"p\":1,\"n\":\"None\"},{\"t\":3,\"p\":1,\"n\":\"Integer\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":3,\"p\":1,\"n\":\"Actor\"},{\"t\":3,\"p\":1,\"n\":\"Actor Base\"},{\"t\":3,\"p\":1,\"n\":\"Actor Value\"},{\"t\":3,\"p\":1,\"n\":\"Player Action\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"Alignment\"},{\"t\":3,\"p\":1,\"n\":\"Association Type\"},{\"t\":3,\"p\":1,\"n\":\"Axis\"},{\"t\":3,\"p\":1,\"n\":\"Casting Type\"},{\"t\":3,\"p\":1,\"n\":\"Cell\"},{\"t\":3,\"p\":1,\"n\":\"Class\"},{\"t\":3,\"p\":1,\"n\":\"Crime Type\"},{\"t\":3,\"p\":1,\"n\":\"Critical Stage\"},{\"t\":3,\"p\":1,\"n\":\"Encounter Zone\"},{\"t\":3,\"p\":1,\"n\":\"Equip Type\"},{\"t\":3,\"p\":1,\"n\":\"Event\"},{\"t\":3,\"p\":1,\"n\":\"Event Data\"},{\"t\":3,\"p\":1,\"n\":\"Faction\"},{\"t\":3,\"p\":1,\"n\":\"Form List\"},{\"t\":3,\"p\":1,\"n\":\"Form Type\"},{\"t\":3,\"p\":1,\"n\":\"Furniture\"},{\"t\":3,\"p\":1,\"n\":\"Furniture Anim\"},{\"t\":3,\"p\":1,\"n\":\"Furniture Entry\"},{\"t\":3,\"p\":1,\"n\":\"Global\"},{\"t\":3,\"p\":1,\"n\":\"Idle\"},{\"t\":3,\"p\":1,\"n\":\"Inventory Object\"},{\"t\":3,\"p\":1,\"n\":\"Keyword\"},{\"t\":3,\"p\":1,\"n\":\"Location\"},{\"t\":3,\"p\":1,\"n\":\"Base Effect\"},{\"t\":3,\"p\":1,\"n\":\"Effect Item\"},{\"t\":3,\"p\":1,\"n\":\"Misc Stat\"},{\"t\":3,\"p\":1,\"n\":\"Object Reference\"},{\"t\":3,\"p\":1,\"n\":\"Owner\"},{\"t\":3,\"p\":1,\"n\":\"Package\"},{\"t\":3,\"p\":1,\"n\":\"Packdata ID\"},{\"t\":3,\"p\":1,\"n\":\"Perk\"},{\"t\":3,\"p\":1,\"n\":\"Quest\"},{\"t\":3,\"p\":1,\"n\":\"Quest Stage\"},{\"t\":3,\"p\":1,\"n\":\"Race\"},{\"t\":3,\"p\":1,\"n\":\"Referenceable Object\"},{\"t\":3,\"p\":1,\"n\":\"Location Ref Type\"},{\"t\":3,\"p\":1,\"n\":\"Region\"},{\"t\":3,\"p\":1,\"n\":\"Scene\"},{\"t\":3,\"p\":1,\"n\":\"Sex\"},{\"t\":3,\"p\":1,\"n\":\"Shout\"},{\"t\":11,\"p\":1,\"n\":\"Variable Name (unused)\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Function\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Param (unused)\"},{\"t\":3,\"p\":1,\"n\":\"Voice Type\"},{\"t\":3,\"p\":1,\"n\":\"Ward State\"},{\"t\":3,\"p\":1,\"n\":\"Weather\"},{\"t\":3,\"p\":1,\"n\":\"Worldspace\"},{\"t\":3,\"p\":1,\"n\":\"Damage Type\"},{\"t\":3,\"p\":1,\"n\":\"Weapon\"},{\"t\":3,\"p\":1,\"n\":\"Weapon List\"},{\"t\":3,\"p\":1,\"n\":\"Target\"},{\"t\":3,\"p\":1,\"n\":\"Target List\"},{\"t\":3,\"p\":1,\"n\":\"Target Part\"},{\"t\":3,\"p\":1,\"n\":\"VATS Action\"},{\"t\":3,\"p\":1,\"n\":\"Critical Effect\"},{\"t\":3,\"p\":1,\"n\":\"Critical Effect List\"},{\"t\":3,\"p\":1,\"n\":\"Weapon Type\"},{\"t\":3,\"p\":1,\"n\":\"Projectile Type\"},{\"t\":3,\"p\":1,\"n\":\"Delivery Type\"},{\"t\":3,\"p\":1,\"n\":\"Run On\"},{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":3,\"p\":1,\"n\":\"Parameter #3\"}]},{\"t\":2,\"p\":1,\"n\":\"CIS1 - Parameter #1\"},{\"t\":2,\"p\":1,\"n\":\"CIS2 - Parameter #2\"}]}]},{\"t\":3,\"p\":1,\"n\":\"DNAM - Flags\"},{\"t\":11,\"n\":\"XNAM - Unknown\"}]},{\"t\":1,\"p\":1,\"n\":\"SMEN - Story Manager Event Node\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":3,\"p\":1,\"n\":\"PNAM - Parent \"},{\"t\":3,\"p\":1,\"n\":\"SNAM - Child \"},{\"t\":3,\"n\":\"CITC - Condition Count\"},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Conditions\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Condition\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"CTDA - \",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":5,\"p\":1,\"n\":\"Comparison Value - Float\"},{\"t\":3,\"p\":1,\"n\":\"Comparison Value - Global\"},{\"t\":3,\"p\":1,\"n\":\"Function\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":11,\"p\":1,\"n\":\"None\"},{\"t\":3,\"p\":1,\"n\":\"Integer\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":3,\"p\":1,\"n\":\"Actor\"},{\"t\":3,\"p\":1,\"n\":\"Actor Base\"},{\"t\":3,\"p\":1,\"n\":\"Actor Value\"},{\"t\":3,\"p\":1,\"n\":\"Player Action\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"Alignment\"},{\"t\":3,\"p\":1,\"n\":\"Association Type\"},{\"t\":3,\"p\":1,\"n\":\"Axis\"},{\"t\":3,\"p\":1,\"n\":\"Casting Type\"},{\"t\":3,\"p\":1,\"n\":\"Cell\"},{\"t\":3,\"p\":1,\"n\":\"Class\"},{\"t\":3,\"p\":1,\"n\":\"Crime Type\"},{\"t\":3,\"p\":1,\"n\":\"Critical Stage\"},{\"t\":3,\"p\":1,\"n\":\"Encounter Zone\"},{\"t\":3,\"p\":1,\"n\":\"Equip Type\"},{\"t\":3,\"p\":1,\"n\":\"Event\"},{\"t\":3,\"p\":1,\"n\":\"Event Data\"},{\"t\":3,\"p\":1,\"n\":\"Faction\"},{\"t\":3,\"p\":1,\"n\":\"Form List\"},{\"t\":3,\"p\":1,\"n\":\"Form Type\"},{\"t\":3,\"p\":1,\"n\":\"Furniture\"},{\"t\":3,\"p\":1,\"n\":\"Furniture Anim\"},{\"t\":3,\"p\":1,\"n\":\"Furniture Entry\"},{\"t\":3,\"p\":1,\"n\":\"Global\"},{\"t\":3,\"p\":1,\"n\":\"Idle\"},{\"t\":3,\"p\":1,\"n\":\"Inventory Object\"},{\"t\":3,\"p\":1,\"n\":\"Keyword\"},{\"t\":3,\"p\":1,\"n\":\"Location\"},{\"t\":3,\"p\":1,\"n\":\"Base Effect\"},{\"t\":3,\"p\":1,\"n\":\"Effect Item\"},{\"t\":3,\"p\":1,\"n\":\"Misc Stat\"},{\"t\":3,\"p\":1,\"n\":\"Object Reference\"},{\"t\":3,\"p\":1,\"n\":\"Owner\"},{\"t\":3,\"p\":1,\"n\":\"Package\"},{\"t\":3,\"p\":1,\"n\":\"Packdata ID\"},{\"t\":3,\"p\":1,\"n\":\"Perk\"},{\"t\":3,\"p\":1,\"n\":\"Quest\"},{\"t\":3,\"p\":1,\"n\":\"Quest Stage\"},{\"t\":3,\"p\":1,\"n\":\"Race\"},{\"t\":3,\"p\":1,\"n\":\"Referenceable Object\"},{\"t\":3,\"p\":1,\"n\":\"Location Ref Type\"},{\"t\":3,\"p\":1,\"n\":\"Region\"},{\"t\":3,\"p\":1,\"n\":\"Scene\"},{\"t\":3,\"p\":1,\"n\":\"Sex\"},{\"t\":3,\"p\":1,\"n\":\"Shout\"},{\"t\":11,\"p\":1,\"n\":\"Variable Name (unused)\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Function\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Param (unused)\"},{\"t\":3,\"p\":1,\"n\":\"Voice Type\"},{\"t\":3,\"p\":1,\"n\":\"Ward State\"},{\"t\":3,\"p\":1,\"n\":\"Weather\"},{\"t\":3,\"p\":1,\"n\":\"Worldspace\"},{\"t\":3,\"p\":1,\"n\":\"Damage Type\"},{\"t\":3,\"p\":1,\"n\":\"Weapon\"},{\"t\":3,\"p\":1,\"n\":\"Weapon List\"},{\"t\":3,\"p\":1,\"n\":\"Target\"},{\"t\":3,\"p\":1,\"n\":\"Target List\"},{\"t\":3,\"p\":1,\"n\":\"Target Part\"},{\"t\":3,\"p\":1,\"n\":\"VATS Action\"},{\"t\":3,\"p\":1,\"n\":\"Critical Effect\"},{\"t\":3,\"p\":1,\"n\":\"Critical Effect List\"},{\"t\":3,\"p\":1,\"n\":\"Weapon Type\"},{\"t\":3,\"p\":1,\"n\":\"Projectile Type\"},{\"t\":3,\"p\":1,\"n\":\"Delivery Type\"},{\"t\":3,\"p\":1,\"n\":\"Run On\"},{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":3,\"p\":1,\"n\":\"Parameter #3\"}]},{\"t\":2,\"p\":1,\"n\":\"CIS1 - Parameter #1\"},{\"t\":2,\"p\":1,\"n\":\"CIS2 - Parameter #2\"}]}]},{\"t\":3,\"p\":1,\"n\":\"DNAM - Flags\"},{\"t\":11,\"n\":\"XNAM - Unknown\"},{\"t\":2,\"p\":1,\"n\":\"ENAM - Type\"}]},{\"t\":1,\"p\":1,\"n\":\"SMQN - Story Manager Quest Node\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":3,\"p\":1,\"n\":\"PNAM - Parent \"},{\"t\":3,\"p\":1,\"n\":\"SNAM - Child \"},{\"t\":3,\"n\":\"CITC - Condition Count\"},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Conditions\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Condition\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"CTDA - \",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":5,\"p\":1,\"n\":\"Comparison Value - Float\"},{\"t\":3,\"p\":1,\"n\":\"Comparison Value - Global\"},{\"t\":3,\"p\":1,\"n\":\"Function\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":11,\"p\":1,\"n\":\"None\"},{\"t\":3,\"p\":1,\"n\":\"Integer\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":3,\"p\":1,\"n\":\"Actor\"},{\"t\":3,\"p\":1,\"n\":\"Actor Base\"},{\"t\":3,\"p\":1,\"n\":\"Actor Value\"},{\"t\":3,\"p\":1,\"n\":\"Player Action\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"Alignment\"},{\"t\":3,\"p\":1,\"n\":\"Association Type\"},{\"t\":3,\"p\":1,\"n\":\"Axis\"},{\"t\":3,\"p\":1,\"n\":\"Casting Type\"},{\"t\":3,\"p\":1,\"n\":\"Cell\"},{\"t\":3,\"p\":1,\"n\":\"Class\"},{\"t\":3,\"p\":1,\"n\":\"Crime Type\"},{\"t\":3,\"p\":1,\"n\":\"Critical Stage\"},{\"t\":3,\"p\":1,\"n\":\"Encounter Zone\"},{\"t\":3,\"p\":1,\"n\":\"Equip Type\"},{\"t\":3,\"p\":1,\"n\":\"Event\"},{\"t\":3,\"p\":1,\"n\":\"Event Data\"},{\"t\":3,\"p\":1,\"n\":\"Faction\"},{\"t\":3,\"p\":1,\"n\":\"Form List\"},{\"t\":3,\"p\":1,\"n\":\"Form Type\"},{\"t\":3,\"p\":1,\"n\":\"Furniture\"},{\"t\":3,\"p\":1,\"n\":\"Furniture Anim\"},{\"t\":3,\"p\":1,\"n\":\"Furniture Entry\"},{\"t\":3,\"p\":1,\"n\":\"Global\"},{\"t\":3,\"p\":1,\"n\":\"Idle\"},{\"t\":3,\"p\":1,\"n\":\"Inventory Object\"},{\"t\":3,\"p\":1,\"n\":\"Keyword\"},{\"t\":3,\"p\":1,\"n\":\"Location\"},{\"t\":3,\"p\":1,\"n\":\"Base Effect\"},{\"t\":3,\"p\":1,\"n\":\"Effect Item\"},{\"t\":3,\"p\":1,\"n\":\"Misc Stat\"},{\"t\":3,\"p\":1,\"n\":\"Object Reference\"},{\"t\":3,\"p\":1,\"n\":\"Owner\"},{\"t\":3,\"p\":1,\"n\":\"Package\"},{\"t\":3,\"p\":1,\"n\":\"Packdata ID\"},{\"t\":3,\"p\":1,\"n\":\"Perk\"},{\"t\":3,\"p\":1,\"n\":\"Quest\"},{\"t\":3,\"p\":1,\"n\":\"Quest Stage\"},{\"t\":3,\"p\":1,\"n\":\"Race\"},{\"t\":3,\"p\":1,\"n\":\"Referenceable Object\"},{\"t\":3,\"p\":1,\"n\":\"Location Ref Type\"},{\"t\":3,\"p\":1,\"n\":\"Region\"},{\"t\":3,\"p\":1,\"n\":\"Scene\"},{\"t\":3,\"p\":1,\"n\":\"Sex\"},{\"t\":3,\"p\":1,\"n\":\"Shout\"},{\"t\":11,\"p\":1,\"n\":\"Variable Name (unused)\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Function\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Param (unused)\"},{\"t\":3,\"p\":1,\"n\":\"Voice Type\"},{\"t\":3,\"p\":1,\"n\":\"Ward State\"},{\"t\":3,\"p\":1,\"n\":\"Weather\"},{\"t\":3,\"p\":1,\"n\":\"Worldspace\"},{\"t\":3,\"p\":1,\"n\":\"Damage Type\"},{\"t\":3,\"p\":1,\"n\":\"Weapon\"},{\"t\":3,\"p\":1,\"n\":\"Weapon List\"},{\"t\":3,\"p\":1,\"n\":\"Target\"},{\"t\":3,\"p\":1,\"n\":\"Target List\"},{\"t\":3,\"p\":1,\"n\":\"Target Part\"},{\"t\":3,\"p\":1,\"n\":\"VATS Action\"},{\"t\":3,\"p\":1,\"n\":\"Critical Effect\"},{\"t\":3,\"p\":1,\"n\":\"Critical Effect List\"},{\"t\":3,\"p\":1,\"n\":\"Weapon Type\"},{\"t\":3,\"p\":1,\"n\":\"Projectile Type\"},{\"t\":3,\"p\":1,\"n\":\"Delivery Type\"},{\"t\":3,\"p\":1,\"n\":\"Run On\"},{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":3,\"p\":1,\"n\":\"Parameter #3\"}]},{\"t\":2,\"p\":1,\"n\":\"CIS1 - Parameter #1\"},{\"t\":2,\"p\":1,\"n\":\"CIS2 - Parameter #2\"}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DNAM - Flags\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Node Flags\"},{\"t\":3,\"p\":1,\"n\":\"Quest Flags\"}]},{\"t\":3,\"p\":1,\"n\":\"XNAM - Max concurrent quests\"},{\"t\":3,\"p\":1,\"n\":\"MNAM - Num quests to run\"},{\"t\":5,\"p\":1,\"n\":\"HNAM - Hours until reset\"},{\"t\":3,\"n\":\"QNAM - Quest Count\"},{\"t\":10,\"p\":1,\"n\":\"Quests\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Quest\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"NNAM - Quest\"},{\"t\":11,\"n\":\"FNAM - Unknown\"},{\"t\":5,\"p\":1,\"n\":\"RNAM - Hours until reset\"}]}]}]},{\"t\":1,\"p\":1,\"n\":\"SNCT - Sound Category\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":3,\"p\":1,\"n\":\"FNAM - Flags\"},{\"t\":3,\"p\":1,\"n\":\"PNAM - Parent Category\"},{\"t\":3,\"p\":1,\"n\":\"ONAM - Menu Slider Category\"},{\"t\":3,\"p\":1,\"n\":\"VNAM - Static Volume Multiplier\"},{\"t\":3,\"p\":1,\"n\":\"UNAM - Default Menu Value\"},{\"t\":5,\"p\":1,\"n\":\"MNAM - Min Frequency Multiplier\"},{\"t\":5,\"p\":1,\"n\":\"CNAM - Sidechain Target Multiplier\"}]},{\"t\":1,\"p\":1,\"n\":\"SNDR - Sound Descriptor\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"p\":1,\"n\":\"NNAM - Notes\"},{\"t\":3,\"p\":1,\"n\":\"CNAM - Descriptor Type\"},{\"t\":3,\"p\":1,\"n\":\"GNAM - Category\"},{\"t\":3,\"p\":1,\"n\":\"SNAM - Alternate Sound For\"},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Sounds\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Sound Files\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"ANAM - File Name\"}]}]},{\"t\":3,\"p\":1,\"n\":\"ONAM - Output Model\"},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Conditions\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Condition\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"CTDA - \",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":5,\"p\":1,\"n\":\"Comparison Value - Float\"},{\"t\":3,\"p\":1,\"n\":\"Comparison Value - Global\"},{\"t\":3,\"p\":1,\"n\":\"Function\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":11,\"p\":1,\"n\":\"None\"},{\"t\":3,\"p\":1,\"n\":\"Integer\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":3,\"p\":1,\"n\":\"Actor\"},{\"t\":3,\"p\":1,\"n\":\"Actor Base\"},{\"t\":3,\"p\":1,\"n\":\"Actor Value\"},{\"t\":3,\"p\":1,\"n\":\"Player Action\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"Alignment\"},{\"t\":3,\"p\":1,\"n\":\"Association Type\"},{\"t\":3,\"p\":1,\"n\":\"Axis\"},{\"t\":3,\"p\":1,\"n\":\"Casting Type\"},{\"t\":3,\"p\":1,\"n\":\"Cell\"},{\"t\":3,\"p\":1,\"n\":\"Class\"},{\"t\":3,\"p\":1,\"n\":\"Crime Type\"},{\"t\":3,\"p\":1,\"n\":\"Critical Stage\"},{\"t\":3,\"p\":1,\"n\":\"Encounter Zone\"},{\"t\":3,\"p\":1,\"n\":\"Equip Type\"},{\"t\":3,\"p\":1,\"n\":\"Event\"},{\"t\":3,\"p\":1,\"n\":\"Event Data\"},{\"t\":3,\"p\":1,\"n\":\"Faction\"},{\"t\":3,\"p\":1,\"n\":\"Form List\"},{\"t\":3,\"p\":1,\"n\":\"Form Type\"},{\"t\":3,\"p\":1,\"n\":\"Furniture\"},{\"t\":3,\"p\":1,\"n\":\"Furniture Anim\"},{\"t\":3,\"p\":1,\"n\":\"Furniture Entry\"},{\"t\":3,\"p\":1,\"n\":\"Global\"},{\"t\":3,\"p\":1,\"n\":\"Idle\"},{\"t\":3,\"p\":1,\"n\":\"Inventory Object\"},{\"t\":3,\"p\":1,\"n\":\"Keyword\"},{\"t\":3,\"p\":1,\"n\":\"Location\"},{\"t\":3,\"p\":1,\"n\":\"Base Effect\"},{\"t\":3,\"p\":1,\"n\":\"Effect Item\"},{\"t\":3,\"p\":1,\"n\":\"Misc Stat\"},{\"t\":3,\"p\":1,\"n\":\"Object Reference\"},{\"t\":3,\"p\":1,\"n\":\"Owner\"},{\"t\":3,\"p\":1,\"n\":\"Package\"},{\"t\":3,\"p\":1,\"n\":\"Packdata ID\"},{\"t\":3,\"p\":1,\"n\":\"Perk\"},{\"t\":3,\"p\":1,\"n\":\"Quest\"},{\"t\":3,\"p\":1,\"n\":\"Quest Stage\"},{\"t\":3,\"p\":1,\"n\":\"Race\"},{\"t\":3,\"p\":1,\"n\":\"Referenceable Object\"},{\"t\":3,\"p\":1,\"n\":\"Location Ref Type\"},{\"t\":3,\"p\":1,\"n\":\"Region\"},{\"t\":3,\"p\":1,\"n\":\"Scene\"},{\"t\":3,\"p\":1,\"n\":\"Sex\"},{\"t\":3,\"p\":1,\"n\":\"Shout\"},{\"t\":11,\"p\":1,\"n\":\"Variable Name (unused)\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Function\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Param (unused)\"},{\"t\":3,\"p\":1,\"n\":\"Voice Type\"},{\"t\":3,\"p\":1,\"n\":\"Ward State\"},{\"t\":3,\"p\":1,\"n\":\"Weather\"},{\"t\":3,\"p\":1,\"n\":\"Worldspace\"},{\"t\":3,\"p\":1,\"n\":\"Damage Type\"},{\"t\":3,\"p\":1,\"n\":\"Weapon\"},{\"t\":3,\"p\":1,\"n\":\"Weapon List\"},{\"t\":3,\"p\":1,\"n\":\"Target\"},{\"t\":3,\"p\":1,\"n\":\"Target List\"},{\"t\":3,\"p\":1,\"n\":\"Target Part\"},{\"t\":3,\"p\":1,\"n\":\"VATS Action\"},{\"t\":3,\"p\":1,\"n\":\"Critical Effect\"},{\"t\":3,\"p\":1,\"n\":\"Critical Effect List\"},{\"t\":3,\"p\":1,\"n\":\"Weapon Type\"},{\"t\":3,\"p\":1,\"n\":\"Projectile Type\"},{\"t\":3,\"p\":1,\"n\":\"Delivery Type\"},{\"t\":3,\"p\":1,\"n\":\"Run On\"},{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":3,\"p\":1,\"n\":\"Parameter #3\"}]},{\"t\":2,\"p\":1,\"n\":\"CIS1 - Parameter #1\"},{\"t\":2,\"p\":1,\"n\":\"CIS2 - Parameter #2\"}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"LNAM - Values\",\"c\":[{\"t\":11,\"n\":\"Unknown\"},{\"t\":3,\"p\":1,\"n\":\"Looping\"},{\"t\":3,\"p\":1,\"n\":\"Sidechain\"},{\"t\":3,\"p\":1,\"n\":\"Rumble Send Value = (Small \\/ 7) + ((Big \\/ 7) * 16)\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Values\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"% Frequency Shift\"},{\"t\":3,\"p\":1,\"n\":\"% Frequency Variance\"},{\"t\":3,\"p\":1,\"n\":\"Priority\"},{\"t\":3,\"p\":1,\"n\":\"db Variance\"},{\"t\":3,\"p\":1,\"n\":\"Static Attenuation (db)\"}]},{\"t\":3,\"p\":1,\"n\":\"Base Descriptor\"},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Descriptors\",\"d\":1,\"c\":[{\"t\":3,\"p\":1,\"n\":\"DNAM - Descriptor\"}]},{\"t\":3,\"n\":\"ITMC - Count\"},{\"t\":10,\"p\":1,\"n\":\"Rates of Fire\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Sound\",\"c\":[{\"p\":1,\"n\":\"ITMS - Marker Start\"},{\"t\":3,\"p\":1,\"n\":\"INTV - RoF (RPM)\"},{\"t\":2,\"p\":1,\"n\":\"FNAM - File\"},{\"p\":1,\"n\":\"ITME - Marker End\"}]}]}]},{\"t\":1,\"p\":1,\"n\":\"SOPM - Sound Output Model\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"NAM1 - Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":3,\"p\":1,\"n\":\"Reverb Send %\"}]},{\"t\":3,\"p\":1,\"n\":\"MNAM - Type\"},{\"t\":3,\"p\":1,\"n\":\"VNAM - Static Attenuation\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"ONAM - Output Values\",\"c\":[{\"t\":7,\"p\":1,\"n\":\"Channels\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FL\"},{\"t\":3,\"p\":1,\"n\":\"FR\"},{\"t\":3,\"p\":1,\"n\":\"C\"},{\"t\":3,\"p\":1,\"n\":\"LFE\"},{\"t\":3,\"p\":1,\"n\":\"RL\"},{\"t\":3,\"p\":1,\"n\":\"RR\"},{\"t\":3,\"p\":1,\"n\":\"SL\"},{\"t\":3,\"p\":1,\"n\":\"SR\"}]}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"ATTN - Attenuation Values\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Fade In Distance - Start\"},{\"t\":5,\"p\":1,\"n\":\"Fade In Distance - End\"},{\"t\":5,\"p\":1,\"n\":\"Fade Out Distance - Start\"},{\"t\":5,\"p\":1,\"n\":\"Fade Out Distance - End\"},{\"t\":6,\"p\":1,\"n\":\"Fade In Curve\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Value 1\"},{\"t\":3,\"p\":1,\"n\":\"Value 2\"},{\"t\":3,\"p\":1,\"n\":\"Value 3\"},{\"t\":3,\"p\":1,\"n\":\"Value 4\"}]},{\"t\":6,\"p\":1,\"n\":\"Fade Out Curve\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Value 1\"},{\"t\":3,\"p\":1,\"n\":\"Value 2\"},{\"t\":3,\"p\":1,\"n\":\"Value 3\"},{\"t\":3,\"p\":1,\"n\":\"Value 4\"}]}]},{\"t\":3,\"p\":1,\"n\":\"ENAM - Effect Chain\"}]},{\"t\":1,\"p\":1,\"n\":\"SOUN - Sound Marker\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"X1\"},{\"t\":3,\"p\":1,\"n\":\"Y1\"},{\"t\":3,\"p\":1,\"n\":\"Z1\"},{\"t\":3,\"p\":1,\"n\":\"X2\"},{\"t\":3,\"p\":1,\"n\":\"Y2\"},{\"t\":3,\"p\":1,\"n\":\"Z2\"}]},{\"t\":3,\"p\":1,\"n\":\"SDSC - Sound Descriptor\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"REPT - Repeat\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Min Time\"},{\"t\":5,\"p\":1,\"n\":\"Max Time\"},{\"t\":3,\"p\":1,\"n\":\"Stackable\"}]}]},{\"t\":1,\"p\":1,\"n\":\"SPEL - Spell\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"X1\"},{\"t\":3,\"p\":1,\"n\":\"Y1\"},{\"t\":3,\"p\":1,\"n\":\"Z1\"},{\"t\":3,\"p\":1,\"n\":\"X2\"},{\"t\":3,\"p\":1,\"n\":\"Y2\"},{\"t\":3,\"p\":1,\"n\":\"Z2\"}]},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":3,\"n\":\"KSIZ - Keyword Count\"},{\"t\":7,\"p\":1,\"n\":\"KWDA - Keywords\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Keyword\"}]},{\"t\":3,\"p\":1,\"n\":\"ETYP - Equipment Type\"},{\"t\":2,\"p\":1,\"n\":\"DESC - Description\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"SPIT - Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Base Cost\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":5,\"p\":1,\"n\":\"Charge Time\"},{\"t\":3,\"p\":1,\"n\":\"Cast Type\"},{\"t\":3,\"p\":1,\"n\":\"Target Type\"},{\"t\":5,\"p\":1,\"n\":\"Cast Duration\"},{\"t\":5,\"p\":1,\"n\":\"Range\"},{\"t\":3,\"p\":1,\"n\":\"Casting Perk\"}]},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Effects\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Effect\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"EFID - Base Effect\"},{\"t\":6,\"p\":1,\"n\":\"EFIT - \",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Magnitude\"},{\"t\":3,\"p\":1,\"n\":\"Area\"},{\"t\":3,\"p\":1,\"n\":\"Duration\"}]},{\"t\":8,\"p\":1,\"n\":\"Conditions\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Condition\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"CTDA - \",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":5,\"p\":1,\"n\":\"Comparison Value - Float\"},{\"t\":3,\"p\":1,\"n\":\"Comparison Value - Global\"},{\"t\":3,\"p\":1,\"n\":\"Function\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":11,\"p\":1,\"n\":\"None\"},{\"t\":3,\"p\":1,\"n\":\"Integer\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":3,\"p\":1,\"n\":\"Actor\"},{\"t\":3,\"p\":1,\"n\":\"Actor Base\"},{\"t\":3,\"p\":1,\"n\":\"Actor Value\"},{\"t\":3,\"p\":1,\"n\":\"Player Action\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"Alignment\"},{\"t\":3,\"p\":1,\"n\":\"Association Type\"},{\"t\":3,\"p\":1,\"n\":\"Axis\"},{\"t\":3,\"p\":1,\"n\":\"Casting Type\"},{\"t\":3,\"p\":1,\"n\":\"Cell\"},{\"t\":3,\"p\":1,\"n\":\"Class\"},{\"t\":3,\"p\":1,\"n\":\"Crime Type\"},{\"t\":3,\"p\":1,\"n\":\"Critical Stage\"},{\"t\":3,\"p\":1,\"n\":\"Encounter Zone\"},{\"t\":3,\"p\":1,\"n\":\"Equip Type\"},{\"t\":3,\"p\":1,\"n\":\"Event\"},{\"t\":3,\"p\":1,\"n\":\"Event Data\"},{\"t\":3,\"p\":1,\"n\":\"Faction\"},{\"t\":3,\"p\":1,\"n\":\"Form List\"},{\"t\":3,\"p\":1,\"n\":\"Form Type\"},{\"t\":3,\"p\":1,\"n\":\"Furniture\"},{\"t\":3,\"p\":1,\"n\":\"Furniture Anim\"},{\"t\":3,\"p\":1,\"n\":\"Furniture Entry\"},{\"t\":3,\"p\":1,\"n\":\"Global\"},{\"t\":3,\"p\":1,\"n\":\"Idle\"},{\"t\":3,\"p\":1,\"n\":\"Inventory Object\"},{\"t\":3,\"p\":1,\"n\":\"Keyword\"},{\"t\":3,\"p\":1,\"n\":\"Location\"},{\"t\":3,\"p\":1,\"n\":\"Base Effect\"},{\"t\":3,\"p\":1,\"n\":\"Effect Item\"},{\"t\":3,\"p\":1,\"n\":\"Misc Stat\"},{\"t\":3,\"p\":1,\"n\":\"Object Reference\"},{\"t\":3,\"p\":1,\"n\":\"Owner\"},{\"t\":3,\"p\":1,\"n\":\"Package\"},{\"t\":3,\"p\":1,\"n\":\"Packdata ID\"},{\"t\":3,\"p\":1,\"n\":\"Perk\"},{\"t\":3,\"p\":1,\"n\":\"Quest\"},{\"t\":3,\"p\":1,\"n\":\"Quest Stage\"},{\"t\":3,\"p\":1,\"n\":\"Race\"},{\"t\":3,\"p\":1,\"n\":\"Referenceable Object\"},{\"t\":3,\"p\":1,\"n\":\"Location Ref Type\"},{\"t\":3,\"p\":1,\"n\":\"Region\"},{\"t\":3,\"p\":1,\"n\":\"Scene\"},{\"t\":3,\"p\":1,\"n\":\"Sex\"},{\"t\":3,\"p\":1,\"n\":\"Shout\"},{\"t\":11,\"p\":1,\"n\":\"Variable Name (unused)\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Function\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Param (unused)\"},{\"t\":3,\"p\":1,\"n\":\"Voice Type\"},{\"t\":3,\"p\":1,\"n\":\"Ward State\"},{\"t\":3,\"p\":1,\"n\":\"Weather\"},{\"t\":3,\"p\":1,\"n\":\"Worldspace\"},{\"t\":3,\"p\":1,\"n\":\"Damage Type\"},{\"t\":3,\"p\":1,\"n\":\"Weapon\"},{\"t\":3,\"p\":1,\"n\":\"Weapon List\"},{\"t\":3,\"p\":1,\"n\":\"Target\"},{\"t\":3,\"p\":1,\"n\":\"Target List\"},{\"t\":3,\"p\":1,\"n\":\"Target Part\"},{\"t\":3,\"p\":1,\"n\":\"VATS Action\"},{\"t\":3,\"p\":1,\"n\":\"Critical Effect\"},{\"t\":3,\"p\":1,\"n\":\"Critical Effect List\"},{\"t\":3,\"p\":1,\"n\":\"Weapon Type\"},{\"t\":3,\"p\":1,\"n\":\"Projectile Type\"},{\"t\":3,\"p\":1,\"n\":\"Delivery Type\"},{\"t\":3,\"p\":1,\"n\":\"Run On\"},{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":3,\"p\":1,\"n\":\"Parameter #3\"}]},{\"t\":2,\"p\":1,\"n\":\"CIS1 - Parameter #1\"},{\"t\":2,\"p\":1,\"n\":\"CIS2 - Parameter #2\"}]}]}]}]}]},{\"t\":1,\"p\":1,\"n\":\"SPGD - Shader Particle Geometry\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DATA - Data\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Gravity Velocity\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":5,\"p\":1,\"n\":\"Rotation Velocity\"},{\"t\":5,\"p\":1,\"n\":\"Particle Size X\"},{\"t\":5,\"p\":1,\"n\":\"Center Offset Min\"},{\"t\":5,\"p\":1,\"n\":\"Particle Size Y\"},{\"t\":5,\"p\":1,\"n\":\"Center Offset Max\"},{\"t\":5,\"p\":1,\"n\":\"Initial Rotation\"},{\"t\":3,\"p\":1,\"n\":\"# of Subtextures X\"},{\"t\":3,\"p\":1,\"n\":\"# of Subtextures Y\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Box Size\"},{\"t\":5,\"p\":1,\"n\":\"Particle Density\"}]},{\"t\":2,\"p\":1,\"n\":\"MNAM - Particle Texture\"}]},{\"t\":1,\"p\":1,\"n\":\"STAG - Animation Sound Tag Set\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Sounds\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"TNAM - Sound\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Sound\"},{\"t\":2,\"p\":1,\"n\":\"Action\"}]}]}]},{\"t\":1,\"p\":1,\"n\":\"STAT - Static\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"VMAD - Virtual Machine Adapter\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Version\"},{\"t\":3,\"p\":1,\"n\":\"Object Format\"},{\"t\":7,\"p\":1,\"n\":\"Scripts\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Script\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"scriptName\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":7,\"p\":1,\"n\":\"Properties\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Property\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"propertyName\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]},{\"t\":2,\"p\":1,\"n\":\"String\"},{\"t\":3,\"p\":1,\"n\":\"Int32\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":3,\"p\":1,\"n\":\"Bool\"},{\"t\":7,\"p\":1,\"n\":\"Struct\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Member\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"memberName\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]},{\"t\":2,\"p\":1,\"n\":\"String\"},{\"t\":3,\"p\":1,\"n\":\"Int32\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":3,\"p\":1,\"n\":\"Bool\"},{\"t\":7,\"p\":1,\"n\":\"Array of Object\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]}]},{\"t\":7,\"p\":1,\"n\":\"Array of String\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Int32\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Float\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Bool\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]}]}]},{\"t\":7,\"p\":1,\"n\":\"Array of Object\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]}]},{\"t\":7,\"p\":1,\"n\":\"Array of String\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Int32\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Float\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Bool\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Struct\",\"c\":[{\"t\":7,\"p\":1,\"n\":\"Struct\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Member\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"memberName\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]},{\"t\":2,\"p\":1,\"n\":\"String\"},{\"t\":3,\"p\":1,\"n\":\"Int32\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":3,\"p\":1,\"n\":\"Bool\"},{\"t\":7,\"p\":1,\"n\":\"Array of Object\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]}]},{\"t\":7,\"p\":1,\"n\":\"Array of String\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Int32\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Float\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Bool\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]}]}]}]}]}]}]}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"X1\"},{\"t\":3,\"p\":1,\"n\":\"Y1\"},{\"t\":3,\"p\":1,\"n\":\"Z1\"},{\"t\":3,\"p\":1,\"n\":\"X2\"},{\"t\":3,\"p\":1,\"n\":\"Y2\"},{\"t\":3,\"p\":1,\"n\":\"Z2\"}]},{\"t\":3,\"p\":1,\"n\":\"PTRN - Preview Transform\"},{\"t\":3,\"p\":1,\"n\":\"FTYP - Forced Loc Ref Type\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"MODT - Texture Files Hashes\"},{\"t\":3,\"p\":1,\"n\":\"MODS - Material Swap\"},{\"t\":5,\"p\":1,\"n\":\"MODC - Color Remapping Index\"},{\"t\":11,\"n\":\"MODF - Unknown\"}]},{\"t\":7,\"p\":1,\"n\":\"PRPS - Properties\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Property\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Actor Value\"},{\"t\":5,\"p\":1,\"n\":\"Value\"}]}]},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DNAM - Direction Material\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Max Angle (30-120)\"},{\"t\":3,\"p\":1,\"n\":\"Material\"},{\"t\":5,\"p\":1,\"n\":\"Leaf Amplitude\"},{\"t\":5,\"p\":1,\"n\":\"Leaf Frequency\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"NVNM - Navmesh Geometry\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Version\"},{\"t\":11,\"p\":1,\"n\":\"Magic\"},{\"t\":3,\"p\":1,\"n\":\"Parent Worldspace\"},{\"t\":6,\"p\":1,\"n\":\"Coordinates\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Grid Y\"},{\"t\":3,\"p\":1,\"n\":\"Grid X\"}]},{\"t\":3,\"p\":1,\"n\":\"Parent Cell\"},{\"t\":11,\"p\":1,\"n\":\"Vertices and Triangles\"}]},{\"t\":7,\"p\":1,\"n\":\"MNAM - Distant LOD\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"LOD\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"Mesh\"}]}]}]},{\"t\":1,\"p\":1,\"n\":\"TACT - Talking Activator\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"VMAD - Virtual Machine Adapter\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Version\"},{\"t\":3,\"p\":1,\"n\":\"Object Format\"},{\"t\":7,\"p\":1,\"n\":\"Scripts\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Script\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"scriptName\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":7,\"p\":1,\"n\":\"Properties\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Property\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"propertyName\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]},{\"t\":2,\"p\":1,\"n\":\"String\"},{\"t\":3,\"p\":1,\"n\":\"Int32\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":3,\"p\":1,\"n\":\"Bool\"},{\"t\":7,\"p\":1,\"n\":\"Struct\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Member\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"memberName\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]},{\"t\":2,\"p\":1,\"n\":\"String\"},{\"t\":3,\"p\":1,\"n\":\"Int32\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":3,\"p\":1,\"n\":\"Bool\"},{\"t\":7,\"p\":1,\"n\":\"Array of Object\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]}]},{\"t\":7,\"p\":1,\"n\":\"Array of String\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Int32\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Float\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Bool\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]}]}]},{\"t\":7,\"p\":1,\"n\":\"Array of Object\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]}]},{\"t\":7,\"p\":1,\"n\":\"Array of String\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Int32\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Float\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Bool\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Struct\",\"c\":[{\"t\":7,\"p\":1,\"n\":\"Struct\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Member\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"memberName\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]},{\"t\":2,\"p\":1,\"n\":\"String\"},{\"t\":3,\"p\":1,\"n\":\"Int32\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":3,\"p\":1,\"n\":\"Bool\"},{\"t\":7,\"p\":1,\"n\":\"Array of Object\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]}]},{\"t\":7,\"p\":1,\"n\":\"Array of String\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Int32\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Float\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Bool\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]}]}]}]}]}]}]}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"X1\"},{\"t\":3,\"p\":1,\"n\":\"Y1\"},{\"t\":3,\"p\":1,\"n\":\"Z1\"},{\"t\":3,\"p\":1,\"n\":\"X2\"},{\"t\":3,\"p\":1,\"n\":\"Y2\"},{\"t\":3,\"p\":1,\"n\":\"Z2\"}]},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"MODT - Texture Files Hashes\"},{\"t\":3,\"p\":1,\"n\":\"MODS - Material Swap\"},{\"t\":5,\"p\":1,\"n\":\"MODC - Color Remapping Index\"},{\"t\":11,\"n\":\"MODF - Unknown\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Destructible\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"DEST - Header\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Health\"},{\"t\":3,\"p\":1,\"n\":\"DEST Count\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":7,\"p\":1,\"n\":\"DAMC - Resistances\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Resistance\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Damage Type\"},{\"t\":3,\"p\":1,\"n\":\"Value\"}]}]},{\"t\":8,\"p\":1,\"n\":\"Stages\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Stage\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"DSTD - Destruction Stage Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Health %\"},{\"t\":3,\"p\":1,\"n\":\"Index\"},{\"t\":3,\"p\":1,\"n\":\"Model Damage Stage\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":3,\"p\":1,\"n\":\"Self Damage per Second\"},{\"t\":3,\"p\":1,\"n\":\"Explosion\"},{\"t\":3,\"p\":1,\"n\":\"Debris\"},{\"t\":3,\"p\":1,\"n\":\"Debris Count\"}]},{\"t\":2,\"p\":1,\"n\":\"DSTA - Sequence Name\"},{\"t\":6,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"DMDL - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"DMDT - Texture Files Hashes\"},{\"t\":5,\"p\":1,\"n\":\"DMDC - Color Remapping Index\"},{\"t\":3,\"p\":1,\"n\":\"DMDS - Material Swap\"}]},{\"p\":1,\"n\":\"DSTF - End Marker\"}]}]}]},{\"t\":3,\"n\":\"KSIZ - Keyword Count\"},{\"t\":7,\"p\":1,\"n\":\"KWDA - Keywords\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Keyword\"}]},{\"t\":11,\"n\":\"PNAM - Unknown\"},{\"t\":3,\"p\":1,\"n\":\"SNAM - Looping Sound\"},{\"t\":11,\"n\":\"FNAM - Unknown\"},{\"t\":3,\"p\":1,\"n\":\"VNAM - Voice Type\"}]},{\"t\":1,\"p\":1,\"n\":\"TERM - Terminal\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"VMAD - Virtual Machine Adapter\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Version\"},{\"t\":3,\"p\":1,\"n\":\"Object Format\"},{\"t\":7,\"p\":1,\"n\":\"Scripts\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Script\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"scriptName\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":7,\"p\":1,\"n\":\"Properties\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Property\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"propertyName\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]},{\"t\":2,\"p\":1,\"n\":\"String\"},{\"t\":3,\"p\":1,\"n\":\"Int32\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":3,\"p\":1,\"n\":\"Bool\"},{\"t\":7,\"p\":1,\"n\":\"Struct\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Member\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"memberName\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]},{\"t\":2,\"p\":1,\"n\":\"String\"},{\"t\":3,\"p\":1,\"n\":\"Int32\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":3,\"p\":1,\"n\":\"Bool\"},{\"t\":7,\"p\":1,\"n\":\"Array of Object\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]}]},{\"t\":7,\"p\":1,\"n\":\"Array of String\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Int32\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Float\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Bool\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]}]}]},{\"t\":7,\"p\":1,\"n\":\"Array of Object\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]}]},{\"t\":7,\"p\":1,\"n\":\"Array of String\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Int32\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Float\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Bool\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Struct\",\"c\":[{\"t\":7,\"p\":1,\"n\":\"Struct\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Member\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"memberName\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]},{\"t\":2,\"p\":1,\"n\":\"String\"},{\"t\":3,\"p\":1,\"n\":\"Int32\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":3,\"p\":1,\"n\":\"Bool\"},{\"t\":7,\"p\":1,\"n\":\"Array of Object\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]}]},{\"t\":7,\"p\":1,\"n\":\"Array of String\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Int32\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Float\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Bool\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]}]}]}]}]}]}]}]},{\"t\":6,\"p\":1,\"n\":\"Script Fragments\",\"c\":[{\"t\":3,\"n\":\"Unknown\"},{\"t\":6,\"p\":1,\"n\":\"Script\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"scriptName\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":7,\"p\":1,\"n\":\"Properties\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Property\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"propertyName\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]},{\"t\":2,\"p\":1,\"n\":\"String\"},{\"t\":3,\"p\":1,\"n\":\"Int32\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":3,\"p\":1,\"n\":\"Bool\"},{\"t\":7,\"p\":1,\"n\":\"Struct\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Member\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"memberName\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]},{\"t\":2,\"p\":1,\"n\":\"String\"},{\"t\":3,\"p\":1,\"n\":\"Int32\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":3,\"p\":1,\"n\":\"Bool\"},{\"t\":7,\"p\":1,\"n\":\"Array of Object\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]}]},{\"t\":7,\"p\":1,\"n\":\"Array of String\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Int32\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Float\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Bool\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]}]}]},{\"t\":7,\"p\":1,\"n\":\"Array of Object\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]}]},{\"t\":7,\"p\":1,\"n\":\"Array of String\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Int32\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Float\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Bool\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Struct\",\"c\":[{\"t\":7,\"p\":1,\"n\":\"Struct\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Member\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"memberName\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]},{\"t\":2,\"p\":1,\"n\":\"String\"},{\"t\":3,\"p\":1,\"n\":\"Int32\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":3,\"p\":1,\"n\":\"Bool\"},{\"t\":7,\"p\":1,\"n\":\"Array of Object\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]}]},{\"t\":7,\"p\":1,\"n\":\"Array of String\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Int32\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Float\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Bool\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]}]}]}]}]}]}]},{\"t\":7,\"p\":1,\"n\":\"Fragments\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Fragment\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Fragment Index\"},{\"t\":3,\"n\":\"Unknown\"},{\"t\":2,\"p\":1,\"n\":\"scriptName\"},{\"t\":2,\"p\":1,\"n\":\"fragmentName\"}]}]}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"X1\"},{\"t\":3,\"p\":1,\"n\":\"Y1\"},{\"t\":3,\"p\":1,\"n\":\"Z1\"},{\"t\":3,\"p\":1,\"n\":\"X2\"},{\"t\":3,\"p\":1,\"n\":\"Y2\"},{\"t\":3,\"p\":1,\"n\":\"Z2\"}]},{\"t\":3,\"p\":1,\"n\":\"PTRN - Preview Transform\"},{\"t\":2,\"p\":1,\"n\":\"NAM0 - Header Text\"},{\"t\":2,\"p\":1,\"n\":\"WNAM - Welcome Text\"},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"MODT - Texture Files Hashes\"},{\"t\":3,\"p\":1,\"n\":\"MODS - Material Swap\"},{\"t\":5,\"p\":1,\"n\":\"MODC - Color Remapping Index\"},{\"t\":11,\"n\":\"MODF - Unknown\"}]},{\"t\":3,\"n\":\"KSIZ - Keyword Count\"},{\"t\":7,\"p\":1,\"n\":\"KWDA - Keywords\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Keyword\"}]},{\"t\":7,\"p\":1,\"n\":\"PRPS - Properties\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Property\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Actor Value\"},{\"t\":5,\"p\":1,\"n\":\"Value\"}]}]},{\"t\":11,\"n\":\"PNAM - Unknown\"},{\"t\":3,\"p\":1,\"n\":\"SNAM - Looping Sound\"},{\"t\":11,\"n\":\"FNAM - Unknown\"},{\"t\":3,\"n\":\"COCT - Count\"},{\"t\":10,\"p\":1,\"n\":\"Items\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Item\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"CNTO - Item\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Item\"},{\"t\":3,\"p\":1,\"n\":\"Count\"}]},{\"t\":6,\"p\":1,\"n\":\"COED - Extra Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Owner\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Global Variable\"},{\"t\":3,\"p\":1,\"n\":\"Required Rank\"},{\"t\":5,\"p\":1,\"n\":\"Item Condition\"}]}]}]},{\"t\":3,\"p\":1,\"n\":\"MNAM - Active Markers \\/ Flags\"},{\"t\":11,\"n\":\"WBDT - Workbench Data (unused)\"},{\"t\":2,\"p\":1,\"n\":\"XMRK - Marker Model\"},{\"t\":7,\"p\":1,\"n\":\"SNAM - Marker Paramaters\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Marker\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Offset X\"},{\"t\":5,\"p\":1,\"n\":\"Offset Y\"},{\"t\":5,\"p\":1,\"n\":\"Offset Z\"},{\"t\":5,\"p\":1,\"n\":\"Rotation Z\"},{\"t\":3,\"p\":1,\"n\":\"Keyword\"},{\"t\":3,\"p\":1,\"n\":\"Entry Types\"},{\"t\":11,\"n\":\"Unknown\"}]}]},{\"t\":3,\"n\":\"BSIZ - Count\"},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Body Text\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Item\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"BTXT - Text\"},{\"t\":8,\"p\":1,\"n\":\"Conditions\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Condition\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"CTDA - \",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":5,\"p\":1,\"n\":\"Comparison Value - Float\"},{\"t\":3,\"p\":1,\"n\":\"Comparison Value - Global\"},{\"t\":3,\"p\":1,\"n\":\"Function\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":11,\"p\":1,\"n\":\"None\"},{\"t\":3,\"p\":1,\"n\":\"Integer\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":3,\"p\":1,\"n\":\"Actor\"},{\"t\":3,\"p\":1,\"n\":\"Actor Base\"},{\"t\":3,\"p\":1,\"n\":\"Actor Value\"},{\"t\":3,\"p\":1,\"n\":\"Player Action\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"Alignment\"},{\"t\":3,\"p\":1,\"n\":\"Association Type\"},{\"t\":3,\"p\":1,\"n\":\"Axis\"},{\"t\":3,\"p\":1,\"n\":\"Casting Type\"},{\"t\":3,\"p\":1,\"n\":\"Cell\"},{\"t\":3,\"p\":1,\"n\":\"Class\"},{\"t\":3,\"p\":1,\"n\":\"Crime Type\"},{\"t\":3,\"p\":1,\"n\":\"Critical Stage\"},{\"t\":3,\"p\":1,\"n\":\"Encounter Zone\"},{\"t\":3,\"p\":1,\"n\":\"Equip Type\"},{\"t\":3,\"p\":1,\"n\":\"Event\"},{\"t\":3,\"p\":1,\"n\":\"Event Data\"},{\"t\":3,\"p\":1,\"n\":\"Faction\"},{\"t\":3,\"p\":1,\"n\":\"Form List\"},{\"t\":3,\"p\":1,\"n\":\"Form Type\"},{\"t\":3,\"p\":1,\"n\":\"Furniture\"},{\"t\":3,\"p\":1,\"n\":\"Furniture Anim\"},{\"t\":3,\"p\":1,\"n\":\"Furniture Entry\"},{\"t\":3,\"p\":1,\"n\":\"Global\"},{\"t\":3,\"p\":1,\"n\":\"Idle\"},{\"t\":3,\"p\":1,\"n\":\"Inventory Object\"},{\"t\":3,\"p\":1,\"n\":\"Keyword\"},{\"t\":3,\"p\":1,\"n\":\"Location\"},{\"t\":3,\"p\":1,\"n\":\"Base Effect\"},{\"t\":3,\"p\":1,\"n\":\"Effect Item\"},{\"t\":3,\"p\":1,\"n\":\"Misc Stat\"},{\"t\":3,\"p\":1,\"n\":\"Object Reference\"},{\"t\":3,\"p\":1,\"n\":\"Owner\"},{\"t\":3,\"p\":1,\"n\":\"Package\"},{\"t\":3,\"p\":1,\"n\":\"Packdata ID\"},{\"t\":3,\"p\":1,\"n\":\"Perk\"},{\"t\":3,\"p\":1,\"n\":\"Quest\"},{\"t\":3,\"p\":1,\"n\":\"Quest Stage\"},{\"t\":3,\"p\":1,\"n\":\"Race\"},{\"t\":3,\"p\":1,\"n\":\"Referenceable Object\"},{\"t\":3,\"p\":1,\"n\":\"Location Ref Type\"},{\"t\":3,\"p\":1,\"n\":\"Region\"},{\"t\":3,\"p\":1,\"n\":\"Scene\"},{\"t\":3,\"p\":1,\"n\":\"Sex\"},{\"t\":3,\"p\":1,\"n\":\"Shout\"},{\"t\":11,\"p\":1,\"n\":\"Variable Name (unused)\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Function\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Param (unused)\"},{\"t\":3,\"p\":1,\"n\":\"Voice Type\"},{\"t\":3,\"p\":1,\"n\":\"Ward State\"},{\"t\":3,\"p\":1,\"n\":\"Weather\"},{\"t\":3,\"p\":1,\"n\":\"Worldspace\"},{\"t\":3,\"p\":1,\"n\":\"Damage Type\"},{\"t\":3,\"p\":1,\"n\":\"Weapon\"},{\"t\":3,\"p\":1,\"n\":\"Weapon List\"},{\"t\":3,\"p\":1,\"n\":\"Target\"},{\"t\":3,\"p\":1,\"n\":\"Target List\"},{\"t\":3,\"p\":1,\"n\":\"Target Part\"},{\"t\":3,\"p\":1,\"n\":\"VATS Action\"},{\"t\":3,\"p\":1,\"n\":\"Critical Effect\"},{\"t\":3,\"p\":1,\"n\":\"Critical Effect List\"},{\"t\":3,\"p\":1,\"n\":\"Weapon Type\"},{\"t\":3,\"p\":1,\"n\":\"Projectile Type\"},{\"t\":3,\"p\":1,\"n\":\"Delivery Type\"},{\"t\":3,\"p\":1,\"n\":\"Run On\"},{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":3,\"p\":1,\"n\":\"Parameter #3\"}]},{\"t\":2,\"p\":1,\"n\":\"CIS1 - Parameter #1\"},{\"t\":2,\"p\":1,\"n\":\"CIS2 - Parameter #2\"}]}]}]}]},{\"t\":3,\"n\":\"ISIZ - Count\"},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Menu Items\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Menu Item\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"ITXT - Item Text\"},{\"t\":2,\"p\":1,\"n\":\"RNAM - Response Text\"},{\"t\":3,\"p\":1,\"n\":\"ANAM - Type\"},{\"t\":3,\"p\":1,\"n\":\"ITID - Item ID\"},{\"t\":2,\"p\":1,\"n\":\"UNAM - Display Text\"},{\"t\":2,\"p\":1,\"n\":\"VNAM - Show Image\"},{\"t\":3,\"p\":1,\"n\":\"TNAM - Submenu\"},{\"t\":8,\"p\":1,\"n\":\"Conditions\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Condition\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"CTDA - \",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":5,\"p\":1,\"n\":\"Comparison Value - Float\"},{\"t\":3,\"p\":1,\"n\":\"Comparison Value - Global\"},{\"t\":3,\"p\":1,\"n\":\"Function\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":11,\"p\":1,\"n\":\"None\"},{\"t\":3,\"p\":1,\"n\":\"Integer\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":3,\"p\":1,\"n\":\"Actor\"},{\"t\":3,\"p\":1,\"n\":\"Actor Base\"},{\"t\":3,\"p\":1,\"n\":\"Actor Value\"},{\"t\":3,\"p\":1,\"n\":\"Player Action\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"Alignment\"},{\"t\":3,\"p\":1,\"n\":\"Association Type\"},{\"t\":3,\"p\":1,\"n\":\"Axis\"},{\"t\":3,\"p\":1,\"n\":\"Casting Type\"},{\"t\":3,\"p\":1,\"n\":\"Cell\"},{\"t\":3,\"p\":1,\"n\":\"Class\"},{\"t\":3,\"p\":1,\"n\":\"Crime Type\"},{\"t\":3,\"p\":1,\"n\":\"Critical Stage\"},{\"t\":3,\"p\":1,\"n\":\"Encounter Zone\"},{\"t\":3,\"p\":1,\"n\":\"Equip Type\"},{\"t\":3,\"p\":1,\"n\":\"Event\"},{\"t\":3,\"p\":1,\"n\":\"Event Data\"},{\"t\":3,\"p\":1,\"n\":\"Faction\"},{\"t\":3,\"p\":1,\"n\":\"Form List\"},{\"t\":3,\"p\":1,\"n\":\"Form Type\"},{\"t\":3,\"p\":1,\"n\":\"Furniture\"},{\"t\":3,\"p\":1,\"n\":\"Furniture Anim\"},{\"t\":3,\"p\":1,\"n\":\"Furniture Entry\"},{\"t\":3,\"p\":1,\"n\":\"Global\"},{\"t\":3,\"p\":1,\"n\":\"Idle\"},{\"t\":3,\"p\":1,\"n\":\"Inventory Object\"},{\"t\":3,\"p\":1,\"n\":\"Keyword\"},{\"t\":3,\"p\":1,\"n\":\"Location\"},{\"t\":3,\"p\":1,\"n\":\"Base Effect\"},{\"t\":3,\"p\":1,\"n\":\"Effect Item\"},{\"t\":3,\"p\":1,\"n\":\"Misc Stat\"},{\"t\":3,\"p\":1,\"n\":\"Object Reference\"},{\"t\":3,\"p\":1,\"n\":\"Owner\"},{\"t\":3,\"p\":1,\"n\":\"Package\"},{\"t\":3,\"p\":1,\"n\":\"Packdata ID\"},{\"t\":3,\"p\":1,\"n\":\"Perk\"},{\"t\":3,\"p\":1,\"n\":\"Quest\"},{\"t\":3,\"p\":1,\"n\":\"Quest Stage\"},{\"t\":3,\"p\":1,\"n\":\"Race\"},{\"t\":3,\"p\":1,\"n\":\"Referenceable Object\"},{\"t\":3,\"p\":1,\"n\":\"Location Ref Type\"},{\"t\":3,\"p\":1,\"n\":\"Region\"},{\"t\":3,\"p\":1,\"n\":\"Scene\"},{\"t\":3,\"p\":1,\"n\":\"Sex\"},{\"t\":3,\"p\":1,\"n\":\"Shout\"},{\"t\":11,\"p\":1,\"n\":\"Variable Name (unused)\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Function\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Param (unused)\"},{\"t\":3,\"p\":1,\"n\":\"Voice Type\"},{\"t\":3,\"p\":1,\"n\":\"Ward State\"},{\"t\":3,\"p\":1,\"n\":\"Weather\"},{\"t\":3,\"p\":1,\"n\":\"Worldspace\"},{\"t\":3,\"p\":1,\"n\":\"Damage Type\"},{\"t\":3,\"p\":1,\"n\":\"Weapon\"},{\"t\":3,\"p\":1,\"n\":\"Weapon List\"},{\"t\":3,\"p\":1,\"n\":\"Target\"},{\"t\":3,\"p\":1,\"n\":\"Target List\"},{\"t\":3,\"p\":1,\"n\":\"Target Part\"},{\"t\":3,\"p\":1,\"n\":\"VATS Action\"},{\"t\":3,\"p\":1,\"n\":\"Critical Effect\"},{\"t\":3,\"p\":1,\"n\":\"Critical Effect List\"},{\"t\":3,\"p\":1,\"n\":\"Weapon Type\"},{\"t\":3,\"p\":1,\"n\":\"Projectile Type\"},{\"t\":3,\"p\":1,\"n\":\"Delivery Type\"},{\"t\":3,\"p\":1,\"n\":\"Run On\"},{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":3,\"p\":1,\"n\":\"Parameter #3\"}]},{\"t\":2,\"p\":1,\"n\":\"CIS1 - Parameter #1\"},{\"t\":2,\"p\":1,\"n\":\"CIS2 - Parameter #2\"}]}]}]}]}]},{\"t\":1,\"p\":1,\"n\":\"TREE - Tree\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"VMAD - Virtual Machine Adapter\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Version\"},{\"t\":3,\"p\":1,\"n\":\"Object Format\"},{\"t\":7,\"p\":1,\"n\":\"Scripts\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Script\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"scriptName\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":7,\"p\":1,\"n\":\"Properties\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Property\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"propertyName\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]},{\"t\":2,\"p\":1,\"n\":\"String\"},{\"t\":3,\"p\":1,\"n\":\"Int32\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":3,\"p\":1,\"n\":\"Bool\"},{\"t\":7,\"p\":1,\"n\":\"Struct\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Member\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"memberName\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]},{\"t\":2,\"p\":1,\"n\":\"String\"},{\"t\":3,\"p\":1,\"n\":\"Int32\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":3,\"p\":1,\"n\":\"Bool\"},{\"t\":7,\"p\":1,\"n\":\"Array of Object\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]}]},{\"t\":7,\"p\":1,\"n\":\"Array of String\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Int32\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Float\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Bool\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]}]}]},{\"t\":7,\"p\":1,\"n\":\"Array of Object\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]}]},{\"t\":7,\"p\":1,\"n\":\"Array of String\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Int32\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Float\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Bool\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Struct\",\"c\":[{\"t\":7,\"p\":1,\"n\":\"Struct\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Member\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"memberName\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]},{\"t\":2,\"p\":1,\"n\":\"String\"},{\"t\":3,\"p\":1,\"n\":\"Int32\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":3,\"p\":1,\"n\":\"Bool\"},{\"t\":7,\"p\":1,\"n\":\"Array of Object\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]}]},{\"t\":7,\"p\":1,\"n\":\"Array of String\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Int32\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Float\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Bool\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]}]}]}]}]}]}]}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"X1\"},{\"t\":3,\"p\":1,\"n\":\"Y1\"},{\"t\":3,\"p\":1,\"n\":\"Z1\"},{\"t\":3,\"p\":1,\"n\":\"X2\"},{\"t\":3,\"p\":1,\"n\":\"Y2\"},{\"t\":3,\"p\":1,\"n\":\"Z2\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"MODT - Texture Files Hashes\"},{\"t\":3,\"p\":1,\"n\":\"MODS - Material Swap\"},{\"t\":5,\"p\":1,\"n\":\"MODC - Color Remapping Index\"},{\"t\":11,\"n\":\"MODF - Unknown\"}]},{\"t\":3,\"p\":1,\"n\":\"PFIG - Ingredient\"},{\"t\":3,\"p\":1,\"n\":\"SNAM - Harvest Sound\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"PFPC - Ingredient Production\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Spring\"},{\"t\":3,\"p\":1,\"n\":\"Summer\"},{\"t\":3,\"p\":1,\"n\":\"Fall\"},{\"t\":3,\"p\":1,\"n\":\"Winter\"}]},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"CNAM - Tree Data\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Trunk Flexibility\"},{\"t\":5,\"p\":1,\"n\":\"Branch Flexibility\"},{\"t\":5,\"n\":\"Unknown\"},{\"t\":5,\"p\":1,\"n\":\"Leaf Amplitude\"},{\"t\":5,\"p\":1,\"n\":\"Leaf Frequency\"}]}]},{\"t\":1,\"p\":1,\"n\":\"TRNS - Transform\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DATA - Data\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Position\\/Rotation\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Position\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"X\"},{\"t\":5,\"p\":1,\"n\":\"Y\"},{\"t\":5,\"p\":1,\"n\":\"Z\"}]},{\"t\":6,\"p\":1,\"n\":\"Rotation\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"X\"},{\"t\":5,\"p\":1,\"n\":\"Y\"},{\"t\":5,\"p\":1,\"n\":\"Z\"}]}]},{\"t\":5,\"p\":1,\"n\":\"Scale\"},{\"t\":5,\"p\":1,\"n\":\"Zoom Min\"},{\"t\":5,\"p\":1,\"n\":\"Zoom Max\"}]}]},{\"t\":1,\"p\":1,\"n\":\"TXST - Texture Set\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"X1\"},{\"t\":3,\"p\":1,\"n\":\"Y1\"},{\"t\":3,\"p\":1,\"n\":\"Z1\"},{\"t\":3,\"p\":1,\"n\":\"X2\"},{\"t\":3,\"p\":1,\"n\":\"Y2\"},{\"t\":3,\"p\":1,\"n\":\"Z2\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Textures (RGB\\/A)\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"TX00 - Difuse\"},{\"t\":2,\"p\":1,\"n\":\"TX01 - Normal\\/Gloss\"},{\"t\":2,\"p\":1,\"n\":\"TX03 - Glow\"},{\"t\":2,\"p\":1,\"n\":\"TX04 - Height\"},{\"t\":2,\"p\":1,\"n\":\"TX05 - Environment\"},{\"t\":2,\"p\":1,\"n\":\"TX02 - Wrinkles\"},{\"t\":2,\"p\":1,\"n\":\"TX06 - Multilayer\"},{\"t\":2,\"p\":1,\"n\":\"TX07 - Smooth Spec\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DODT - Decal Data\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Min Width\"},{\"t\":5,\"p\":1,\"n\":\"Max Width\"},{\"t\":5,\"p\":1,\"n\":\"Min Height\"},{\"t\":5,\"p\":1,\"n\":\"Max Height\"},{\"t\":5,\"p\":1,\"n\":\"Depth\"},{\"t\":5,\"p\":1,\"n\":\"Shininess\"},{\"t\":6,\"p\":1,\"n\":\"Parallax\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Scale\"},{\"t\":3,\"p\":1,\"n\":\"Passes\"}]},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":3,\"p\":1,\"n\":\"Alpha Threshold?\"},{\"t\":6,\"p\":1,\"n\":\"Color\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]}]},{\"t\":3,\"p\":1,\"n\":\"DNAM - Flags\"},{\"t\":2,\"p\":1,\"n\":\"MNAM - Material\"}]},{\"t\":1,\"p\":1,\"n\":\"VTYP - Voice Type\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":3,\"p\":1,\"n\":\"DNAM - Flags\"}]},{\"t\":1,\"p\":1,\"n\":\"WATR - Water\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":3,\"p\":1,\"n\":\"ANAM - Opacity (unused)\"},{\"t\":3,\"p\":1,\"n\":\"FNAM - Flags\"},{\"t\":3,\"p\":1,\"n\":\"TNAM - Material (unused)\"},{\"t\":3,\"p\":1,\"n\":\"SNAM - Open Sound\"},{\"t\":3,\"p\":1,\"n\":\"XNAM - Consume Spell\"},{\"t\":3,\"p\":1,\"n\":\"YNAM - Contact Spell\"},{\"t\":3,\"p\":1,\"n\":\"INAM - Image Space\"},{\"t\":11,\"n\":\"DATA - Unused\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DNAM - Visual Data\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Fog Properties\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Depth Amount\"},{\"t\":6,\"p\":1,\"n\":\"Shallow Color\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Deep Color\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":5,\"p\":1,\"n\":\"Color Shallow Range\"},{\"t\":5,\"p\":1,\"n\":\"Color Deep Range\"},{\"t\":5,\"p\":1,\"n\":\"Shallow Alpha\"},{\"t\":5,\"p\":1,\"n\":\"Deep Alpha\"},{\"t\":5,\"p\":1,\"n\":\"Alpha Shallow Range\"},{\"t\":5,\"p\":1,\"n\":\"Alpha Deep Range\"},{\"t\":6,\"p\":1,\"n\":\"Underwater Color\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":5,\"p\":1,\"n\":\"Underwater Fog Amount\"},{\"t\":5,\"p\":1,\"n\":\"Underwater Near Fog\"},{\"t\":5,\"p\":1,\"n\":\"Underwater Far Fog\"}]},{\"t\":6,\"p\":1,\"n\":\"Physical Properties\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Normal Magnitude\"},{\"t\":5,\"p\":1,\"n\":\"Shallow Normal Falloff\"},{\"t\":5,\"p\":1,\"n\":\"Deep Normal Falloff\"},{\"t\":5,\"p\":1,\"n\":\"Reflectivity Amount\"},{\"t\":5,\"p\":1,\"n\":\"Fresnel Amount\"},{\"t\":5,\"p\":1,\"n\":\"Surface Effect Falloff\"},{\"t\":6,\"p\":1,\"n\":\"Displacement Simulator\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Force\"},{\"t\":5,\"p\":1,\"n\":\"Velocity\"},{\"t\":5,\"p\":1,\"n\":\"Falloff\"},{\"t\":5,\"p\":1,\"n\":\"Dampener\"},{\"t\":5,\"p\":1,\"n\":\"Starting Size\"}]},{\"t\":6,\"p\":1,\"n\":\"Reflection Color\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]}]},{\"t\":6,\"p\":1,\"n\":\"Specular Properties\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Sun Specular Power\"},{\"t\":5,\"p\":1,\"n\":\"Sun Specular Magnitude\"},{\"t\":5,\"p\":1,\"n\":\"Sun Sparkle Power\"},{\"t\":5,\"p\":1,\"n\":\"Sun Sparkle Magnitude\"},{\"t\":5,\"p\":1,\"n\":\"Interior Specular Radius\"},{\"t\":5,\"p\":1,\"n\":\"Interior Specular Brightness\"},{\"t\":5,\"p\":1,\"n\":\"Interior Specular Power\"}]},{\"t\":6,\"p\":1,\"n\":\"Noise Properties\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Layer 1 - Wind Direction\"},{\"t\":5,\"p\":1,\"n\":\"Layer 2 - Wind Direction\"},{\"t\":5,\"p\":1,\"n\":\"Layer 3 - Wind Direction\"},{\"t\":5,\"p\":1,\"n\":\"Layer 1 - Wind Speed\"},{\"t\":5,\"p\":1,\"n\":\"Layer 2 - Wind Speed\"},{\"t\":5,\"p\":1,\"n\":\"Layer 3 - Wind Speed\"},{\"t\":5,\"p\":1,\"n\":\"Layer 1 - Amplitude Scale\"},{\"t\":5,\"p\":1,\"n\":\"Layer 2 - Amplitude Scale\"},{\"t\":5,\"p\":1,\"n\":\"Layer 3 - Amplitude Scale\"},{\"t\":5,\"p\":1,\"n\":\"Layer 1 - UV Scale\"},{\"t\":5,\"p\":1,\"n\":\"Layer 2 - UV Scale\"},{\"t\":5,\"p\":1,\"n\":\"Layer 3 - UV Scale\"},{\"t\":5,\"p\":1,\"n\":\"Layer 1 - Noise Falloff\"},{\"t\":5,\"p\":1,\"n\":\"Layer 2 - Noise Falloff\"},{\"t\":5,\"p\":1,\"n\":\"Layer 3 - Noise Falloff\"}]},{\"t\":6,\"p\":1,\"n\":\"Silt Properties\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Silt Amount\"},{\"t\":6,\"p\":1,\"n\":\"Light Color\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Dark Color\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]}]},{\"t\":3,\"p\":1,\"n\":\"Screen Space Reflections\"}]},{\"t\":11,\"n\":\"GNAM - Unused\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"NAM0 - Linear Velocity\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"X\"},{\"t\":5,\"p\":1,\"n\":\"Y\"},{\"t\":5,\"p\":1,\"n\":\"Z\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"NAM1 - Angular Velocity\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"X\"},{\"t\":5,\"p\":1,\"n\":\"Y\"},{\"t\":5,\"p\":1,\"n\":\"Z\"}]},{\"t\":2,\"p\":1,\"n\":\"NAM2 - Layer 1 Noise Texture\"},{\"t\":2,\"p\":1,\"n\":\"NAM3 - Layer 2 Noise Texture\"},{\"t\":2,\"p\":1,\"n\":\"NAM4 - Layer 3 Noise Texture\"}]},{\"t\":1,\"p\":1,\"n\":\"WEAP - Weapon\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"VMAD - Virtual Machine Adapter\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Version\"},{\"t\":3,\"p\":1,\"n\":\"Object Format\"},{\"t\":7,\"p\":1,\"n\":\"Scripts\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Script\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"scriptName\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":7,\"p\":1,\"n\":\"Properties\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Property\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"propertyName\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]},{\"t\":2,\"p\":1,\"n\":\"String\"},{\"t\":3,\"p\":1,\"n\":\"Int32\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":3,\"p\":1,\"n\":\"Bool\"},{\"t\":7,\"p\":1,\"n\":\"Struct\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Member\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"memberName\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]},{\"t\":2,\"p\":1,\"n\":\"String\"},{\"t\":3,\"p\":1,\"n\":\"Int32\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":3,\"p\":1,\"n\":\"Bool\"},{\"t\":7,\"p\":1,\"n\":\"Array of Object\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]}]},{\"t\":7,\"p\":1,\"n\":\"Array of String\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Int32\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Float\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Bool\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]}]}]},{\"t\":7,\"p\":1,\"n\":\"Array of Object\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]}]},{\"t\":7,\"p\":1,\"n\":\"Array of String\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Int32\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Float\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Bool\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Struct\",\"c\":[{\"t\":7,\"p\":1,\"n\":\"Struct\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Member\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"memberName\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]},{\"t\":2,\"p\":1,\"n\":\"String\"},{\"t\":3,\"p\":1,\"n\":\"Int32\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":3,\"p\":1,\"n\":\"Bool\"},{\"t\":7,\"p\":1,\"n\":\"Array of Object\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]}]},{\"t\":7,\"p\":1,\"n\":\"Array of String\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Int32\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Float\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Bool\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]}]}]}]}]}]}]}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"X1\"},{\"t\":3,\"p\":1,\"n\":\"Y1\"},{\"t\":3,\"p\":1,\"n\":\"Z1\"},{\"t\":3,\"p\":1,\"n\":\"X2\"},{\"t\":3,\"p\":1,\"n\":\"Y2\"},{\"t\":3,\"p\":1,\"n\":\"Z2\"}]},{\"t\":3,\"p\":1,\"n\":\"PTRN - Preview Transform\"},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"MODT - Texture Files Hashes\"},{\"t\":3,\"p\":1,\"n\":\"MODS - Material Swap\"},{\"t\":5,\"p\":1,\"n\":\"MODC - Color Remapping Index\"},{\"t\":11,\"n\":\"MODF - Unknown\"}]},{\"t\":2,\"p\":1,\"n\":\"ICON - Inventory Image\"},{\"t\":2,\"p\":1,\"n\":\"MICO - Message Icon\"},{\"t\":3,\"p\":1,\"n\":\"EITM - Object Effect\"},{\"t\":3,\"p\":1,\"n\":\"EAMT - Enchantment Amount\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Destructible\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"DEST - Header\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Health\"},{\"t\":3,\"p\":1,\"n\":\"DEST Count\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":7,\"p\":1,\"n\":\"DAMC - Resistances\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Resistance\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Damage Type\"},{\"t\":3,\"p\":1,\"n\":\"Value\"}]}]},{\"t\":8,\"p\":1,\"n\":\"Stages\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Stage\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"DSTD - Destruction Stage Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Health %\"},{\"t\":3,\"p\":1,\"n\":\"Index\"},{\"t\":3,\"p\":1,\"n\":\"Model Damage Stage\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":3,\"p\":1,\"n\":\"Self Damage per Second\"},{\"t\":3,\"p\":1,\"n\":\"Explosion\"},{\"t\":3,\"p\":1,\"n\":\"Debris\"},{\"t\":3,\"p\":1,\"n\":\"Debris Count\"}]},{\"t\":2,\"p\":1,\"n\":\"DSTA - Sequence Name\"},{\"t\":6,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"DMDL - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"DMDT - Texture Files Hashes\"},{\"t\":5,\"p\":1,\"n\":\"DMDC - Color Remapping Index\"},{\"t\":3,\"p\":1,\"n\":\"DMDS - Material Swap\"}]},{\"p\":1,\"n\":\"DSTF - End Marker\"}]}]}]},{\"t\":3,\"p\":1,\"n\":\"ETYP - Equipment Type\"},{\"t\":3,\"p\":1,\"n\":\"BIDS - Block Bash Impact Data Set\"},{\"t\":3,\"p\":1,\"n\":\"BAMT - Alternate Block Material\"},{\"t\":3,\"p\":1,\"n\":\"YNAM - Sound - Pick Up\"},{\"t\":3,\"p\":1,\"n\":\"ZNAM - Sound - Put Down\"},{\"t\":3,\"n\":\"KSIZ - Keyword Count\"},{\"t\":7,\"p\":1,\"n\":\"KWDA - Keywords\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Keyword\"}]},{\"t\":2,\"p\":1,\"n\":\"DESC - Description\"},{\"t\":3,\"p\":1,\"n\":\"INRD - Instance Naming\"},{\"t\":7,\"p\":1,\"n\":\"APPR - Attach Parent Slots\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Keyword\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Object Template\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"OBTE - Count\"},{\"t\":8,\"p\":1,\"n\":\"Combinations\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Combination\",\"c\":[{\"p\":1,\"n\":\"OBTF - Editor Only\"},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":6,\"p\":1,\"n\":\"OBTS - Object Mod Template Item\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Include Count\"},{\"t\":3,\"p\":1,\"n\":\"Property Count\"},{\"t\":3,\"p\":1,\"n\":\"Level Min\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Level Max\"},{\"t\":3,\"p\":1,\"n\":\"ID\"},{\"t\":3,\"p\":1,\"n\":\"Default\"},{\"t\":7,\"p\":1,\"n\":\"Keywords\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Keyword\"}]},{\"t\":3,\"p\":1,\"n\":\"Min Level For Ranks\"},{\"t\":3,\"p\":1,\"n\":\"Alt Levels Per Tier\"},{\"t\":7,\"p\":1,\"n\":\"Includes\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Include\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Mod\"},{\"t\":3,\"p\":1,\"n\":\"Attach Point Index\"},{\"t\":3,\"p\":1,\"n\":\"Optional\"},{\"t\":3,\"p\":1,\"n\":\"Don't Use All\"}]}]},{\"t\":7,\"p\":1,\"n\":\"Properties\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Property\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Value Type\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Function Type\"},{\"t\":3,\"p\":1,\"n\":\"Property\"},{\"t\":11,\"n\":\"Value 1 - Unknown\"},{\"t\":3,\"p\":1,\"n\":\"Value 1 - Int\"},{\"t\":5,\"p\":1,\"n\":\"Value 1 - Float\"},{\"t\":3,\"p\":1,\"n\":\"Value 1 - Bool\"},{\"t\":3,\"p\":1,\"n\":\"Value 1 - FormID\"},{\"t\":3,\"p\":1,\"n\":\"Value 1 - Enum\"},{\"t\":3,\"p\":1,\"n\":\"Sound Level\"},{\"t\":3,\"p\":1,\"n\":\"Stagger Value\"},{\"t\":3,\"p\":1,\"n\":\"Hit Behaviour\"},{\"t\":3,\"p\":1,\"n\":\"Value 2 - Int\"},{\"t\":5,\"p\":1,\"n\":\"Value 2 - Float\"},{\"t\":3,\"p\":1,\"n\":\"Value 2 - Bool\"},{\"t\":5,\"p\":1,\"n\":\"Step\"}]}]}]}]}]},{\"p\":1,\"n\":\"STOP - Marker\"}]},{\"t\":3,\"p\":1,\"n\":\"NNAM - Embedded Weapon Mod\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"1st Person Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MOD4 - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"MO4T - Texture Files Hashes\"},{\"t\":3,\"p\":1,\"n\":\"MO4S - Material Swap\"},{\"t\":5,\"p\":1,\"n\":\"MO4C - Color Remapping Index\"},{\"t\":11,\"n\":\"MO4F - Unknown\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DNAM - Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Ammo\"},{\"t\":5,\"p\":1,\"n\":\"Speed\"},{\"t\":5,\"p\":1,\"n\":\"Reload Speed\"},{\"t\":5,\"p\":1,\"n\":\"Reach\"},{\"t\":5,\"p\":1,\"n\":\"Min Range\"},{\"t\":5,\"p\":1,\"n\":\"Max Range\"},{\"t\":5,\"p\":1,\"n\":\"Attack Delay\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":5,\"p\":1,\"n\":\"Damage - OutOfRange Mult\"},{\"t\":3,\"p\":1,\"n\":\"On Hit\"},{\"t\":3,\"p\":1,\"n\":\"Skill\"},{\"t\":3,\"p\":1,\"n\":\"Resist\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":3,\"p\":1,\"n\":\"Capacity\"},{\"t\":3,\"p\":1,\"n\":\"Animation Type\"},{\"t\":5,\"p\":1,\"n\":\"Damage - Secondary\"},{\"t\":5,\"p\":1,\"n\":\"Weight\"},{\"t\":3,\"p\":1,\"n\":\"Value\"},{\"t\":3,\"p\":1,\"n\":\"Damage - Base\"},{\"t\":3,\"p\":1,\"n\":\"Sound Level\"},{\"t\":3,\"p\":1,\"n\":\"Sound - Attack\"},{\"t\":3,\"p\":1,\"n\":\"Sound - Attack 2D\"},{\"t\":3,\"p\":1,\"n\":\"Sound - Attack Loop\"},{\"t\":3,\"p\":1,\"n\":\"Sound - Attack Fail\"},{\"t\":3,\"p\":1,\"n\":\"Sound - Idle\"},{\"t\":3,\"p\":1,\"n\":\"Sound - Equip Sound\"},{\"t\":3,\"p\":1,\"n\":\"Sound - UnEquip Sound\"},{\"t\":3,\"p\":1,\"n\":\"Sound - Fast Equip Sound\"},{\"t\":3,\"p\":1,\"n\":\"Accuracy Bonus\"},{\"t\":5,\"p\":1,\"n\":\"Animation Attack Seconds\"},{\"t\":5,\"p\":1,\"n\":\"Action Point Cost\"},{\"t\":5,\"p\":1,\"n\":\"Full Power Seconds\"},{\"t\":5,\"p\":1,\"n\":\"Min Power Per Shot\"},{\"t\":3,\"p\":1,\"n\":\"Stagger\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"FNAM - \",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Animation Fire Seconds\"},{\"t\":5,\"p\":1,\"n\":\"Rumble - Left Motor Strength\"},{\"t\":5,\"p\":1,\"n\":\"Rumble - Right Motor Strength\"},{\"t\":5,\"p\":1,\"n\":\"Rumble - Duration\"},{\"t\":5,\"p\":1,\"n\":\"Animation Reload Seconds\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":5,\"p\":1,\"n\":\"Sighted Transition Seconds\"},{\"t\":3,\"p\":1,\"n\":\"# Projectiles\"},{\"t\":3,\"p\":1,\"n\":\"Override Projectile\"},{\"t\":3,\"p\":1,\"n\":\"Pattern\"},{\"t\":3,\"p\":1,\"n\":\"Rumble - Peroid (ms)\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"CRDT - Critical Data\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Crit Damage Mult\"},{\"t\":5,\"p\":1,\"n\":\"Crit Charge Bonus\"},{\"t\":3,\"p\":1,\"n\":\"Crit Effect\"}]},{\"t\":3,\"p\":1,\"n\":\"INAM - Impact Data Set\"},{\"t\":3,\"p\":1,\"n\":\"LNAM - NPC Add Ammo List\"},{\"t\":3,\"p\":1,\"n\":\"WAMD - Aim Model\"},{\"t\":3,\"p\":1,\"n\":\"WZMD - Zoom\"},{\"t\":3,\"p\":1,\"n\":\"CNAM - Template\"},{\"t\":7,\"p\":1,\"n\":\"DAMA - Damage Types\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Damage Type\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Amount\"}]}]},{\"t\":2,\"p\":1,\"n\":\"FLTR - Filter\"},{\"t\":3,\"p\":1,\"n\":\"MASE - Melee Speed\"}]},{\"t\":1,\"p\":1,\"n\":\"WRLD - Worldspace\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":8,\"n\":\"Unused RNAM\",\"c\":[{\"t\":11,\"n\":\"RNAM - Unknown\"}]},{\"t\":11,\"n\":\"MHDT - Max Height Data\"},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"WCTR - Fixed Dimensions Center Cell\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"X\"},{\"t\":3,\"p\":1,\"n\":\"Y\"}]},{\"t\":3,\"p\":1,\"n\":\"LTMP - Interior Lighting\"},{\"t\":3,\"p\":1,\"n\":\"XEZN - Encounter Zone\"},{\"t\":3,\"p\":1,\"n\":\"XLCN - Location\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Parent\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"WNAM - Worldspace\"},{\"t\":6,\"p\":1,\"n\":\"PNAM - \",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unknown\"}]}]},{\"t\":3,\"p\":1,\"n\":\"CNAM - Climate\"},{\"t\":3,\"p\":1,\"n\":\"NAM2 - Water\"},{\"t\":3,\"p\":1,\"n\":\"NAM3 - LOD Water Type\"},{\"t\":5,\"p\":1,\"n\":\"NAM4 - LOD Water Height\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DNAM - Land Data\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Default Land Height\"},{\"t\":5,\"p\":1,\"n\":\"Default Water Height\"}]},{\"t\":2,\"p\":1,\"n\":\"ICON - Map Image\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Cloud Model\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"MODT - Texture Files Hashes\"},{\"t\":3,\"p\":1,\"n\":\"MODS - Material Swap\"},{\"t\":5,\"p\":1,\"n\":\"MODC - Color Remapping Index\"},{\"t\":11,\"n\":\"MODF - Unknown\"}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"MNAM - Map Data\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Usable Dimensions\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"X\"},{\"t\":3,\"p\":1,\"n\":\"Y\"}]},{\"t\":6,\"p\":1,\"n\":\"Cell Coordinates\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"NW Cell\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"X\"},{\"t\":3,\"p\":1,\"n\":\"Y\"}]},{\"t\":6,\"p\":1,\"n\":\"SE Cell\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"X\"},{\"t\":3,\"p\":1,\"n\":\"Y\"}]}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"ONAM - World Map Offset Data\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"World Map Scale\"},{\"t\":5,\"p\":1,\"n\":\"Cell X Offset\"},{\"t\":5,\"p\":1,\"n\":\"Cell Y Offset\"},{\"t\":5,\"p\":1,\"n\":\"Cell Z Offset\"}]},{\"t\":5,\"p\":1,\"n\":\"NAMA - Distant LOD Multiplier\"},{\"t\":3,\"p\":1,\"n\":\"DATA - Flags\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Object Bounds\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"NAM0 - Min\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"X\"},{\"t\":5,\"p\":1,\"n\":\"Y\"}]},{\"t\":6,\"p\":1,\"n\":\"NAM9 - Max\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"X\"},{\"t\":5,\"p\":1,\"n\":\"Y\"}]}]},{\"t\":3,\"p\":1,\"n\":\"ZNAM - Music\"},{\"t\":2,\"p\":1,\"n\":\"NNAM - Canopy Shadow (unused)\"},{\"t\":2,\"p\":1,\"n\":\"XWEM - Water Environment Map\"},{\"t\":2,\"p\":1,\"n\":\"TNAM - HD LOD Diffuse Texture\"},{\"t\":2,\"p\":1,\"n\":\"UNAM - HD LOD Normal Texture\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"World Default Level Data\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"WLEV - Dimension\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"NW Cell\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"X\"},{\"t\":3,\"p\":1,\"n\":\"Y\"}]},{\"t\":6,\"p\":1,\"n\":\"Size\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Width\"},{\"t\":3,\"p\":1,\"n\":\"Height\"}]}]},{\"t\":11,\"p\":1,\"n\":\"WLEV - Data\"}]},{\"t\":11,\"n\":\"OFST - Offset Data\"},{\"t\":11,\"n\":\"CLSZ - Unknown\"}]},{\"t\":1,\"p\":1,\"n\":\"WTHR - Weather\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"p\":1,\"n\":\"00TX - Cloud Texture Layer #0\"},{\"t\":2,\"p\":1,\"n\":\"10TX - Cloud Texture Layer #1\"},{\"t\":2,\"p\":1,\"n\":\"20TX - Cloud Texture Layer #2\"},{\"t\":2,\"p\":1,\"n\":\"30TX - Cloud Texture Layer #3\"},{\"t\":2,\"p\":1,\"n\":\"40TX - Cloud Texture Layer #4\"},{\"t\":2,\"p\":1,\"n\":\"50TX - Cloud Texture Layer #5\"},{\"t\":2,\"p\":1,\"n\":\"60TX - Cloud Texture Layer #6\"},{\"t\":2,\"p\":1,\"n\":\"70TX - Cloud Texture Layer #7\"},{\"t\":2,\"p\":1,\"n\":\"80TX - Cloud Texture Layer #8\"},{\"t\":2,\"p\":1,\"n\":\"90TX - Cloud Texture Layer #9\"},{\"t\":2,\"p\":1,\"n\":\":0TX - Cloud Texture Layer #10\"},{\"t\":2,\"p\":1,\"n\":\";0TX - Cloud Texture Layer #11\"},{\"t\":2,\"p\":1,\"n\":\"<0TX - Cloud Texture Layer #12\"},{\"t\":2,\"p\":1,\"n\":\"=0TX - Cloud Texture Layer #13\"},{\"t\":2,\"p\":1,\"n\":\">0TX - Cloud Texture Layer #14\"},{\"t\":2,\"p\":1,\"n\":\"?0TX - Cloud Texture Layer #15\"},{\"t\":2,\"p\":1,\"n\":\"@0TX - Cloud Texture Layer #16\"},{\"t\":2,\"p\":1,\"n\":\"A0TX - Cloud Texture Layer #17\"},{\"t\":2,\"p\":1,\"n\":\"B0TX - Cloud Texture Layer #18\"},{\"t\":2,\"p\":1,\"n\":\"C0TX - Cloud Texture Layer #19\"},{\"t\":2,\"p\":1,\"n\":\"D0TX - Cloud Texture Layer #20\"},{\"t\":2,\"p\":1,\"n\":\"E0TX - Cloud Texture Layer #21\"},{\"t\":2,\"p\":1,\"n\":\"F0TX - Cloud Texture Layer #22\"},{\"t\":2,\"p\":1,\"n\":\"G0TX - Cloud Texture Layer #23\"},{\"t\":2,\"p\":1,\"n\":\"H0TX - Cloud Texture Layer #24\"},{\"t\":2,\"p\":1,\"n\":\"I0TX - Cloud Texture Layer #25\"},{\"t\":2,\"p\":1,\"n\":\"J0TX - Cloud Texture Layer #26\"},{\"t\":2,\"p\":1,\"n\":\"K0TX - Cloud Texture Layer #27\"},{\"t\":2,\"p\":1,\"n\":\"L0TX - Cloud Texture Layer #28\"},{\"t\":11,\"n\":\"LNAM - Unknown\"},{\"t\":3,\"p\":1,\"n\":\"MNAM - Precipitation Type\"},{\"t\":3,\"p\":1,\"n\":\"NNAM - Visual Effect\"},{\"t\":11,\"n\":\"ONAM - Unused\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Cloud Speed\",\"c\":[{\"t\":7,\"p\":1,\"n\":\"RNAM - Y Speed\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Layer\"}]},{\"t\":7,\"p\":1,\"n\":\"QNAM - X Speed\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Layer\"}]}]},{\"t\":7,\"p\":1,\"n\":\"PNAM - Cloud Colors\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Layer\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Sunrise\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Day\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Sunset\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Night\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"EarlySunrise\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"LateSunrise\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"EarlySunset\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"LateSunset\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]}]}]},{\"t\":7,\"p\":1,\"n\":\"JNAM - Cloud Alphas\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Layer\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Sunrise\"},{\"t\":5,\"p\":1,\"n\":\"Day\"},{\"t\":5,\"p\":1,\"n\":\"Sunset\"},{\"t\":5,\"p\":1,\"n\":\"Night\"},{\"t\":5,\"p\":1,\"n\":\"EarlySunrise\"},{\"t\":5,\"p\":1,\"n\":\"LateSunrise\"},{\"t\":5,\"p\":1,\"n\":\"EarlySunset\"},{\"t\":5,\"p\":1,\"n\":\"LateSunset\"}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"NAM0 - Weather Colors\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Sky-Upper\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Sunrise\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Day\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Sunset\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Night\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"EarlySunrise\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"LateSunrise\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"EarlySunset\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"LateSunset\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]}]},{\"t\":6,\"p\":1,\"n\":\"Fog Near\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Sunrise\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Day\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Sunset\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Night\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"EarlySunrise\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"LateSunrise\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"EarlySunset\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"LateSunset\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]}]},{\"t\":6,\"n\":\"Unknown\",\"c\":[{\"t\":6,\"n\":\"Sunrise\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"n\":\"Day\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"n\":\"Sunset\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"n\":\"Night\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"n\":\"EarlySunrise\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"n\":\"LateSunrise\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"n\":\"EarlySunset\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"n\":\"LateSunset\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]}]},{\"t\":6,\"p\":1,\"n\":\"Ambient\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Sunrise\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Day\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Sunset\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Night\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"EarlySunrise\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"LateSunrise\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"EarlySunset\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"LateSunset\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]}]},{\"t\":6,\"p\":1,\"n\":\"Sunlight\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Sunrise\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Day\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Sunset\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Night\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"EarlySunrise\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"LateSunrise\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"EarlySunset\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"LateSunset\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]}]},{\"t\":6,\"p\":1,\"n\":\"Sun\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Sunrise\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Day\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Sunset\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Night\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"EarlySunrise\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"LateSunrise\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"EarlySunset\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"LateSunset\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]}]},{\"t\":6,\"p\":1,\"n\":\"Stars\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Sunrise\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Day\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Sunset\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Night\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"EarlySunrise\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"LateSunrise\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"EarlySunset\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"LateSunset\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]}]},{\"t\":6,\"p\":1,\"n\":\"Sky-Lower\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Sunrise\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Day\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Sunset\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Night\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"EarlySunrise\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"LateSunrise\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"EarlySunset\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"LateSunset\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]}]},{\"t\":6,\"p\":1,\"n\":\"Horizon\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Sunrise\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Day\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Sunset\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Night\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"EarlySunrise\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"LateSunrise\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"EarlySunset\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"LateSunset\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]}]},{\"t\":6,\"p\":1,\"n\":\"Effect Lighting\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Sunrise\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Day\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Sunset\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Night\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"EarlySunrise\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"LateSunrise\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"EarlySunset\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"LateSunset\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]}]},{\"t\":6,\"p\":1,\"n\":\"Cloud LOD Diffuse\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Sunrise\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Day\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Sunset\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Night\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"EarlySunrise\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"LateSunrise\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"EarlySunset\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"LateSunset\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]}]},{\"t\":6,\"p\":1,\"n\":\"Cloud LOD Ambient\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Sunrise\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Day\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Sunset\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Night\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"EarlySunrise\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"LateSunrise\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"EarlySunset\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"LateSunset\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]}]},{\"t\":6,\"p\":1,\"n\":\"Fog Far\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Sunrise\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Day\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Sunset\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Night\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"EarlySunrise\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"LateSunrise\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"EarlySunset\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"LateSunset\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]}]},{\"t\":6,\"p\":1,\"n\":\"Sky Statics\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Sunrise\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Day\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Sunset\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Night\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"EarlySunrise\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"LateSunrise\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"EarlySunset\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"LateSunset\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]}]},{\"t\":6,\"p\":1,\"n\":\"Water Multiplier\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Sunrise\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Day\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Sunset\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Night\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"EarlySunrise\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"LateSunrise\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"EarlySunset\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"LateSunset\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]}]},{\"t\":6,\"p\":1,\"n\":\"Sun Glare\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Sunrise\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Day\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Sunset\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Night\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"EarlySunrise\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"LateSunrise\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"EarlySunset\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"LateSunset\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]}]},{\"t\":6,\"p\":1,\"n\":\"Moon Glare\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Sunrise\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Day\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Sunset\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Night\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"EarlySunrise\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"LateSunrise\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"EarlySunset\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"LateSunset\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]}]},{\"t\":6,\"p\":1,\"n\":\"Fog Near High\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Sunrise\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Day\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Sunset\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Night\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"EarlySunrise\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"LateSunrise\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"EarlySunset\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"LateSunset\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]}]},{\"t\":6,\"p\":1,\"n\":\"Fog Far High\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Sunrise\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Day\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Sunset\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Night\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"EarlySunrise\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"LateSunrise\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"EarlySunset\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"LateSunset\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]}]}]},{\"t\":7,\"n\":\"NAM4 - Unknown\",\"c\":[{\"t\":5,\"n\":\"Unknown\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"FNAM - Fog Distance\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Day - Near\"},{\"t\":5,\"p\":1,\"n\":\"Day - Far\"},{\"t\":5,\"p\":1,\"n\":\"Night - Near\"},{\"t\":5,\"p\":1,\"n\":\"Night - Far\"},{\"t\":5,\"p\":1,\"n\":\"Day - Power\"},{\"t\":5,\"p\":1,\"n\":\"Night - Power\"},{\"t\":5,\"p\":1,\"n\":\"Day - Max\"},{\"t\":5,\"p\":1,\"n\":\"Night - Max\"},{\"t\":5,\"p\":1,\"n\":\"Day - Near Height Mid\"},{\"t\":5,\"p\":1,\"n\":\"Day - Near Height Range\"},{\"t\":5,\"p\":1,\"n\":\"Night - Near Height Mid\"},{\"t\":5,\"p\":1,\"n\":\"Night - Near Height Range\"},{\"t\":5,\"p\":1,\"n\":\"Day - High Density Scale\"},{\"t\":5,\"p\":1,\"n\":\"Night - High Density Scale\"},{\"t\":5,\"p\":1,\"n\":\"Day - Far Height Mid\"},{\"t\":5,\"p\":1,\"n\":\"Day - Far Height Range\"},{\"t\":5,\"p\":1,\"n\":\"Night - Far Height Mid\"},{\"t\":5,\"p\":1,\"n\":\"Night - Far Height Range\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DATA - Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Wind Speed\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":3,\"p\":1,\"n\":\"Trans Delta\"},{\"t\":3,\"p\":1,\"n\":\"Sun Glare\"},{\"t\":3,\"p\":1,\"n\":\"Sun Damage\"},{\"t\":3,\"p\":1,\"n\":\"Precipitation - Begin Fade In\"},{\"t\":3,\"p\":1,\"n\":\"Precipitation - End Fade Out\"},{\"t\":3,\"p\":1,\"n\":\"Thunder\\/Lightning - Begin Fade In\"},{\"t\":3,\"p\":1,\"n\":\"Thunder\\/Lightning - End Fade Out\"},{\"t\":3,\"p\":1,\"n\":\"Thunder\\/Lightning - Frequency\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":6,\"p\":1,\"n\":\"Lightning Color\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"}]},{\"t\":3,\"p\":1,\"n\":\"Visual Effect - Begin\"},{\"t\":3,\"p\":1,\"n\":\"Visual Effect - End\"},{\"t\":3,\"p\":1,\"n\":\"Wind Direction\"},{\"t\":3,\"p\":1,\"n\":\"Wind Direction Range\"}]},{\"t\":3,\"p\":1,\"n\":\"NAM1 - Disabled Cloud Layers\"},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Sounds\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"SNAM - Sound\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Sound\"},{\"t\":3,\"p\":1,\"n\":\"Type\"}]}]},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Sky Statics\",\"d\":1,\"c\":[{\"t\":3,\"p\":1,\"n\":\"TNAM - Static\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"IMSP - Image Spaces\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Sunrise\"},{\"t\":3,\"p\":1,\"n\":\"Day\"},{\"t\":3,\"p\":1,\"n\":\"Sunset\"},{\"t\":3,\"p\":1,\"n\":\"Night\"},{\"t\":3,\"p\":1,\"n\":\"EarlySunrise\"},{\"t\":3,\"p\":1,\"n\":\"LateSunrise\"},{\"t\":3,\"p\":1,\"n\":\"EarlySunset\"},{\"t\":3,\"p\":1,\"n\":\"LateSunset\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"WGDR - God Rays\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Sunrise\"},{\"t\":3,\"p\":1,\"n\":\"Day\"},{\"t\":3,\"p\":1,\"n\":\"Sunset\"},{\"t\":3,\"p\":1,\"n\":\"Night\"},{\"t\":3,\"p\":1,\"n\":\"EarlySunrise\"},{\"t\":3,\"p\":1,\"n\":\"LateSunrise\"},{\"t\":3,\"p\":1,\"n\":\"EarlySunset\"},{\"t\":3,\"p\":1,\"n\":\"LateSunset\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Directional Ambient Lighting Colors\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"DALC - Sunrise\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Directional\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"X+\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"X-\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Y+\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Y-\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Z+\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Z-\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]}]},{\"t\":6,\"p\":1,\"n\":\"Specular\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":5,\"p\":1,\"n\":\"Scale\"}]},{\"t\":6,\"p\":1,\"n\":\"DALC - Day\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Directional\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"X+\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"X-\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Y+\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Y-\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Z+\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Z-\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]}]},{\"t\":6,\"p\":1,\"n\":\"Specular\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":5,\"p\":1,\"n\":\"Scale\"}]},{\"t\":6,\"p\":1,\"n\":\"DALC - Sunset\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Directional\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"X+\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"X-\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Y+\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Y-\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Z+\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Z-\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]}]},{\"t\":6,\"p\":1,\"n\":\"Specular\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":5,\"p\":1,\"n\":\"Scale\"}]},{\"t\":6,\"p\":1,\"n\":\"DALC - Night\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Directional\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"X+\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"X-\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Y+\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Y-\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Z+\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Z-\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]}]},{\"t\":6,\"p\":1,\"n\":\"Specular\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":5,\"p\":1,\"n\":\"Scale\"}]},{\"t\":6,\"p\":1,\"n\":\"DALC - EarlySunrise\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Directional\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"X+\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"X-\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Y+\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Y-\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Z+\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Z-\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]}]},{\"t\":6,\"p\":1,\"n\":\"Specular\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":5,\"p\":1,\"n\":\"Scale\"}]},{\"t\":6,\"p\":1,\"n\":\"DALC - LateSunrise\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Directional\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"X+\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"X-\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Y+\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Y-\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Z+\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Z-\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]}]},{\"t\":6,\"p\":1,\"n\":\"Specular\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":5,\"p\":1,\"n\":\"Scale\"}]},{\"t\":6,\"p\":1,\"n\":\"DALC - EarlySunset\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Directional\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"X+\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"X-\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Y+\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Y-\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Z+\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Z-\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]}]},{\"t\":6,\"p\":1,\"n\":\"Specular\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":5,\"p\":1,\"n\":\"Scale\"}]},{\"t\":6,\"p\":1,\"n\":\"DALC - LateSunset\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Directional\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"X+\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"X-\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Y+\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Y-\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Z+\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Z-\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]}]},{\"t\":6,\"p\":1,\"n\":\"Specular\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":5,\"p\":1,\"n\":\"Scale\"}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Aurora\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"MODT - Texture Files Hashes\"},{\"t\":3,\"p\":1,\"n\":\"MODS - Material Swap\"},{\"t\":5,\"p\":1,\"n\":\"MODC - Color Remapping Index\"},{\"t\":11,\"n\":\"MODF - Unknown\"}]}]},{\"t\":3,\"p\":1,\"n\":\"GNAM - Sun Glare Lens Flare\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"UNAM - Magic\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"On Lightning Strike - Spell\"},{\"t\":5,\"p\":1,\"n\":\"On Lightning Strike - Threshold\"},{\"t\":3,\"p\":1,\"n\":\"On Weather Activate - Spell\"},{\"t\":5,\"p\":1,\"n\":\"On Weather Activate - Threshold\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":5,\"p\":1,\"n\":\"VNAM - Volatility Mult\"},{\"t\":5,\"p\":1,\"n\":\"WNAM - Visibility Mult\"}]},{\"t\":1,\"p\":1,\"n\":\"ZOOM - Zoom\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"GNAM - Data\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"FOV Mult\"},{\"t\":3,\"p\":1,\"n\":\"Overlay\"},{\"t\":3,\"p\":1,\"n\":\"Imagespace Modifier\"},{\"t\":6,\"p\":1,\"n\":\"Camera Offset\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"X\"},{\"t\":5,\"p\":1,\"n\":\"Y\"},{\"t\":5,\"p\":1,\"n\":\"Z\"}]}]}]},{\"t\":1,\"p\":1,\"n\":\"AACT - Action\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"CNAM - Color\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":2,\"p\":1,\"n\":\"DNAM - Notes\"},{\"t\":3,\"p\":1,\"n\":\"TNAM - Type\"},{\"t\":3,\"p\":1,\"n\":\"DATA - Attraction Rule\"},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"}]}]},\"name\":\"Smash.All\",\"hash\":\"A4B4931B\",\"color\":128}"
  },
  {
    "path": "frontend/settings/FalloutNV/Smash.All.json",
    "content": "{\"records\":\"ACHR,ACTI,ADDN,ALCH,ALOC,AMEF,AMMO,ANIO,ARMA,ARMO,ASPC,AVIF,BOOK,BPTD,CAMS,CCRD,CDCK,CELL,CHAL,CHIP,CLAS,CLMT,CMNY,COBJ,CONT,CPTH,CREA,CSNO,CSTY,DEBR,DEHY,DIAL,DOOR,ECZN,EFSH,ENCH,EXPL,EYES,FACT,FLST,FURN,GLOB,GMST,GRAS,HAIR,HDPT,HUNG,IDLM,IMAD,IMGS,IMOD,INFO,INGR,IPCT,IPDS,KEYM,LAND,LGTM,LIGH,LSCR,LSCT,LTEX,LVLC,LVLI,LVLN,MESG,MGEF,MICN,MISC,MSET,MSTT,MUSC,NOTE,NPC_,PACK,PBEA,PERK,PGRE,PMIS,PROJ,PWAT,QUST,RACE,RADS,RCCT,RCPE,REFR,REGN,REPU,RGDL,SCOL,SCPT,SLPD,SOUN,SPEL,STAT,TACT,TERM,TREE,TXST,VTYP,WATR,WEAP,WRLD,WTHR,ACRE\",\"description\":\"Smashes all the things.  Produced using autoset attributes on all record prototypes produced by v1.0.0.\\r\\n\\r\\nLast updated 04\\/30\\/2018.\",\"tree\":{\"records\":[{\"t\":1,\"p\":1,\"n\":\"ACHR - Placed NPC\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":3,\"p\":1,\"n\":\"NAME - Base\"},{\"t\":3,\"p\":1,\"n\":\"XEZN - Encounter Zone\"},{\"t\":11,\"n\":\"XRGD - Ragdoll Data\"},{\"t\":11,\"n\":\"XRGB - Ragdoll Biped Data\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Patrol Data\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"XPRD - Idle Time\"},{\"p\":1,\"n\":\"XPPA - Patrol Script Marker\"},{\"t\":3,\"p\":1,\"n\":\"INAM - Idle\"},{\"t\":6,\"p\":1,\"n\":\"Embedded Script\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"SCHR - Basic Script Data\",\"c\":[{\"t\":11,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"RefCount\"},{\"t\":3,\"p\":1,\"n\":\"CompiledSize\"},{\"t\":3,\"p\":1,\"n\":\"VariableCount\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"}]},{\"t\":11,\"p\":1,\"n\":\"SCDA - Compiled Embedded Script\"},{\"t\":2,\"p\":1,\"n\":\"SCTX - Embedded Script Source\"},{\"t\":10,\"p\":1,\"n\":\"Local Variables\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Local Variable\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"SLSD - Local Variable Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Index\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"}]},{\"t\":2,\"p\":1,\"n\":\"SCVR - Name\"}]}]},{\"t\":8,\"p\":1,\"n\":\"References\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"SCRO - Global Reference\"},{\"t\":3,\"p\":1,\"n\":\"SCRV - Local Variable\"}]}]},{\"t\":3,\"p\":1,\"n\":\"TNAM - Topic\"}]},{\"t\":3,\"p\":1,\"n\":\"XLCM - Level Modifier\"},{\"t\":3,\"p\":1,\"n\":\"XMRC - Merchant Container\"},{\"t\":3,\"p\":1,\"n\":\"XCNT - Count\"},{\"t\":5,\"p\":1,\"n\":\"XRDS - Radius\"},{\"t\":5,\"p\":1,\"n\":\"XHLP - Health\"},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Linked Decals\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"XDCR - Decal\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":11,\"n\":\"Unknown\"}]}]},{\"t\":3,\"p\":1,\"n\":\"XLKR - Linked Reference\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"XCLP - Linked Reference Color\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Link Start Color\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Link End Color\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Activate Parents\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"XAPD - Flags\"},{\"t\":8,\"p\":1,\"n\":\"Activate Parent Refs\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"XAPR - Activate Parent Ref\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":5,\"p\":1,\"n\":\"Delay\"}]}]}]},{\"t\":2,\"p\":1,\"n\":\"XATO - Activation Prompt\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"XESP - Enable Parent\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":3,\"p\":1,\"n\":\"XEMI - Emittance\"},{\"t\":3,\"p\":1,\"n\":\"XMBR - MultiBound Reference\"},{\"p\":1,\"n\":\"XIBS - Ignored By Sandbox\"},{\"t\":5,\"p\":1,\"n\":\"XSCL - Scale\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DATA - Position\\/Rotation\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Position\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"X\"},{\"t\":5,\"p\":1,\"n\":\"Y\"},{\"t\":5,\"p\":1,\"n\":\"Z\"}]},{\"t\":6,\"p\":1,\"n\":\"Rotation\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"X\"},{\"t\":5,\"p\":1,\"n\":\"Y\"},{\"t\":5,\"p\":1,\"n\":\"Z\"}]}]}]},{\"t\":1,\"p\":1,\"n\":\"ACTI - Activator\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"X1\"},{\"t\":3,\"p\":1,\"n\":\"Y1\"},{\"t\":3,\"p\":1,\"n\":\"Z1\"},{\"t\":3,\"p\":1,\"n\":\"X2\"},{\"t\":3,\"p\":1,\"n\":\"Y2\"},{\"t\":3,\"p\":1,\"n\":\"Z2\"}]},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"},{\"t\":11,\"n\":\"MODB - Unknown\"},{\"t\":11,\"p\":1,\"n\":\"MODT - Texture Files Hashes\"},{\"t\":7,\"p\":1,\"n\":\"MODS - Alternate Textures\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"3D Name\"},{\"t\":3,\"p\":1,\"n\":\"New Texture\"},{\"t\":3,\"p\":1,\"n\":\"3D Index\"}]}]},{\"t\":3,\"p\":1,\"n\":\"MODD - FaceGen Model Flags\"}]},{\"t\":3,\"p\":1,\"n\":\"SCRI - Script\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Destructable\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"DEST - Header\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Health\"},{\"t\":3,\"p\":1,\"n\":\"Count\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":8,\"p\":1,\"n\":\"Stages\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Stage\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"DSTD - Destruction Stage Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Health %\"},{\"t\":3,\"p\":1,\"n\":\"Index\"},{\"t\":3,\"p\":1,\"n\":\"Damage Stage\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":3,\"p\":1,\"n\":\"Self Damage per Second\"},{\"t\":3,\"p\":1,\"n\":\"Explosion\"},{\"t\":3,\"p\":1,\"n\":\"Debris\"},{\"t\":3,\"p\":1,\"n\":\"Debris Count\"}]},{\"t\":6,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"DMDL - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"DMDT - Texture Files Hashes\"}]},{\"p\":1,\"n\":\"DSTF - End Marker\"}]}]}]},{\"t\":3,\"p\":1,\"n\":\"SNAM - Sound - Looping\"},{\"t\":3,\"p\":1,\"n\":\"VNAM - Sound - Activation\"},{\"t\":3,\"p\":1,\"n\":\"INAM - Radio Template\"},{\"t\":3,\"p\":1,\"n\":\"RNAM - Radio Station\"},{\"t\":3,\"p\":1,\"n\":\"WNAM - Water Type\"},{\"t\":2,\"p\":1,\"n\":\"XATO - Activation Prompt\"}]},{\"t\":1,\"p\":1,\"n\":\"ADDN - Addon Node\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"X1\"},{\"t\":3,\"p\":1,\"n\":\"Y1\"},{\"t\":3,\"p\":1,\"n\":\"Z1\"},{\"t\":3,\"p\":1,\"n\":\"X2\"},{\"t\":3,\"p\":1,\"n\":\"Y2\"},{\"t\":3,\"p\":1,\"n\":\"Z2\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"},{\"t\":11,\"n\":\"MODB - Unknown\"},{\"t\":11,\"p\":1,\"n\":\"MODT - Texture Files Hashes\"},{\"t\":7,\"p\":1,\"n\":\"MODS - Alternate Textures\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"3D Name\"},{\"t\":3,\"p\":1,\"n\":\"New Texture\"},{\"t\":3,\"p\":1,\"n\":\"3D Index\"}]}]},{\"t\":3,\"p\":1,\"n\":\"MODD - FaceGen Model Flags\"}]},{\"t\":3,\"p\":1,\"n\":\"DATA - Node Index\"},{\"t\":3,\"p\":1,\"n\":\"SNAM - Sound\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DNAM - Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Master Particle System Cap\"},{\"t\":11,\"n\":\"Unknown\"}]}]},{\"t\":1,\"p\":1,\"n\":\"ALCH - Ingestible\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"X1\"},{\"t\":3,\"p\":1,\"n\":\"Y1\"},{\"t\":3,\"p\":1,\"n\":\"Z1\"},{\"t\":3,\"p\":1,\"n\":\"X2\"},{\"t\":3,\"p\":1,\"n\":\"Y2\"},{\"t\":3,\"p\":1,\"n\":\"Z2\"}]},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"},{\"t\":11,\"n\":\"MODB - Unknown\"},{\"t\":11,\"p\":1,\"n\":\"MODT - Texture Files Hashes\"},{\"t\":7,\"p\":1,\"n\":\"MODS - Alternate Textures\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"3D Name\"},{\"t\":3,\"p\":1,\"n\":\"New Texture\"},{\"t\":3,\"p\":1,\"n\":\"3D Index\"}]}]},{\"t\":3,\"p\":1,\"n\":\"MODD - FaceGen Model Flags\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Icon\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"ICON - Large Icon filename\"},{\"t\":2,\"p\":1,\"n\":\"MICO - Small Icon filename\"}]},{\"t\":3,\"p\":1,\"n\":\"SCRI - Script\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Destructable\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"DEST - Header\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Health\"},{\"t\":3,\"p\":1,\"n\":\"Count\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":8,\"p\":1,\"n\":\"Stages\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Stage\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"DSTD - Destruction Stage Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Health %\"},{\"t\":3,\"p\":1,\"n\":\"Index\"},{\"t\":3,\"p\":1,\"n\":\"Damage Stage\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":3,\"p\":1,\"n\":\"Self Damage per Second\"},{\"t\":3,\"p\":1,\"n\":\"Explosion\"},{\"t\":3,\"p\":1,\"n\":\"Debris\"},{\"t\":3,\"p\":1,\"n\":\"Debris Count\"}]},{\"t\":6,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"DMDL - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"DMDT - Texture Files Hashes\"}]},{\"p\":1,\"n\":\"DSTF - End Marker\"}]}]}]},{\"t\":3,\"p\":1,\"n\":\"YNAM - Sound - Pick Up\"},{\"t\":3,\"p\":1,\"n\":\"ZNAM - Sound - Drop\"},{\"t\":3,\"p\":1,\"n\":\"ETYP - Equiptment Type\"},{\"t\":5,\"p\":1,\"n\":\"DATA - Weight\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"ENIT - Effect Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Value\"},{\"t\":3,\"p\":1,\"n\":\"Flags?\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Withdrawal Effect\"},{\"t\":5,\"p\":1,\"n\":\"Addiction Chance\"},{\"t\":3,\"p\":1,\"n\":\"Sound - Consume\"}]},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Effects\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Effect\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"EFID - Base Effect\"},{\"t\":6,\"p\":1,\"n\":\"EFIT - \",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Magnitude\"},{\"t\":3,\"p\":1,\"n\":\"Area\"},{\"t\":3,\"p\":1,\"n\":\"Duration\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Actor Value\"}]},{\"t\":8,\"p\":1,\"n\":\"Conditions\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"CTDA - Condition\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":5,\"p\":1,\"n\":\"Comparison Value - Float\"},{\"t\":3,\"p\":1,\"n\":\"Comparison Value - Global\"},{\"t\":3,\"p\":1,\"n\":\"Function\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":11,\"p\":1,\"n\":\"None\"},{\"t\":3,\"p\":1,\"n\":\"Integer\"},{\"t\":3,\"p\":1,\"n\":\"Variable Name (INVALID)\"},{\"t\":3,\"p\":1,\"n\":\"Sex\"},{\"t\":3,\"p\":1,\"n\":\"Actor Value\"},{\"t\":3,\"p\":1,\"n\":\"Crime Type\"},{\"t\":3,\"p\":1,\"n\":\"Axis\"},{\"t\":3,\"p\":1,\"n\":\"Quest Stage (INVALID)\"},{\"t\":3,\"p\":1,\"n\":\"Misc Stat\"},{\"t\":3,\"p\":1,\"n\":\"Alignment\"},{\"t\":3,\"p\":1,\"n\":\"Equip Type\"},{\"t\":3,\"p\":1,\"n\":\"Form Type\"},{\"t\":3,\"p\":1,\"n\":\"Critical Stage\"},{\"t\":3,\"p\":1,\"n\":\"Object Reference\"},{\"t\":3,\"p\":1,\"n\":\"Inventory Object\"},{\"t\":3,\"p\":1,\"n\":\"Actor\"},{\"t\":3,\"p\":1,\"n\":\"Voice Type\"},{\"t\":3,\"p\":1,\"n\":\"Idle\"},{\"t\":3,\"p\":1,\"n\":\"Form List\"},{\"t\":3,\"p\":1,\"n\":\"Note\"},{\"t\":3,\"p\":1,\"n\":\"Quest\"},{\"t\":3,\"p\":1,\"n\":\"Faction\"},{\"t\":3,\"p\":1,\"n\":\"Weapon\"},{\"t\":3,\"p\":1,\"n\":\"Cell\"},{\"t\":3,\"p\":1,\"n\":\"Class\"},{\"t\":3,\"p\":1,\"n\":\"Race\"},{\"t\":3,\"p\":1,\"n\":\"Actor Base\"},{\"t\":3,\"p\":1,\"n\":\"Global\"},{\"t\":3,\"p\":1,\"n\":\"Weather\"},{\"t\":3,\"p\":1,\"n\":\"Package\"},{\"t\":3,\"p\":1,\"n\":\"Encounter Zone\"},{\"t\":3,\"p\":1,\"n\":\"Perk\"},{\"t\":3,\"p\":1,\"n\":\"Owner\"},{\"t\":3,\"p\":1,\"n\":\"Furniture\"},{\"t\":3,\"p\":1,\"n\":\"Effect Item\"},{\"t\":3,\"p\":1,\"n\":\"Base Effect\"},{\"t\":3,\"p\":1,\"n\":\"Worldspace\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Function\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Param (INVALID)\"},{\"t\":3,\"p\":1,\"n\":\"Creature Type\"},{\"t\":3,\"p\":1,\"n\":\"Menu Mode\"},{\"t\":3,\"p\":1,\"n\":\"Player Action\"},{\"t\":3,\"p\":1,\"n\":\"Body Location\"},{\"t\":3,\"p\":1,\"n\":\"Referenceable Object\"},{\"t\":3,\"p\":1,\"n\":\"Quest Objective (INVALID)\"},{\"t\":3,\"p\":1,\"n\":\"Reputation\"},{\"t\":3,\"p\":1,\"n\":\"Region\"},{\"t\":3,\"p\":1,\"n\":\"Challenge\"},{\"t\":3,\"p\":1,\"n\":\"Casino\"},{\"t\":3,\"p\":1,\"n\":\"Form\"},{\"t\":3,\"p\":1,\"n\":\"Variable Name\"},{\"t\":3,\"p\":1,\"n\":\"Quest Stage\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Function (INVALID)\"},{\"t\":3,\"p\":1,\"n\":\"Weapon List\"},{\"t\":3,\"p\":1,\"n\":\"Target\"},{\"t\":3,\"p\":1,\"n\":\"Target List\"},{\"t\":3,\"p\":1,\"n\":\"Target Part\"},{\"t\":3,\"p\":1,\"n\":\"VATS Action\"},{\"t\":3,\"p\":1,\"n\":\"Critical Effect\"},{\"t\":3,\"p\":1,\"n\":\"Critical Effect List\"},{\"t\":3,\"p\":1,\"n\":\"Weapon Type\"},{\"t\":3,\"p\":1,\"n\":\"Quest Objective\"},{\"t\":3,\"p\":1,\"n\":\"Run On\"},{\"t\":3,\"p\":1,\"n\":\"Reference\"}]}]}]}]}]},{\"t\":1,\"p\":1,\"n\":\"ALOC - Media Location Controller\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":11,\"n\":\"NAM1 - Flags and Enums, messily combined\"},{\"t\":11,\"n\":\"NAM2 - Unknown\"},{\"t\":11,\"n\":\"NAM3 - Unknown\"},{\"t\":5,\"p\":1,\"n\":\"NAM4 - Location Delay\"},{\"t\":3,\"p\":1,\"n\":\"NAM5 - Day Start\"},{\"t\":3,\"p\":1,\"n\":\"NAM6 - Night Start\"},{\"t\":5,\"p\":1,\"n\":\"NAM7 - Retrigger Delay\"},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Neutral Sets\",\"d\":1,\"c\":[{\"t\":3,\"p\":1,\"n\":\"HNAM - Media Set\"}]},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Ally Sets\",\"d\":1,\"c\":[{\"t\":3,\"p\":1,\"n\":\"ZNAM - Media Set\"}]},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Friend Sets\",\"d\":1,\"c\":[{\"t\":3,\"p\":1,\"n\":\"XNAM - Media Set\"}]},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Enemy Sets\",\"d\":1,\"c\":[{\"t\":3,\"p\":1,\"n\":\"YNAM - Media Set\"}]},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Location Sets\",\"d\":1,\"c\":[{\"t\":3,\"p\":1,\"n\":\"LNAM - Media Set\"}]},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Battle Sets\",\"d\":1,\"c\":[{\"t\":3,\"p\":1,\"n\":\"GNAM - Media Set\"}]},{\"t\":3,\"p\":1,\"n\":\"RNAM - Conditional Faction\"},{\"t\":11,\"n\":\"FNAM - Unknown\"}]},{\"t\":1,\"p\":1,\"n\":\"AMEF - Ammo Effect\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DATA - Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Operation\"},{\"t\":5,\"p\":1,\"n\":\"Value\"}]}]},{\"t\":1,\"p\":1,\"n\":\"AMMO - Ammunition\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"X1\"},{\"t\":3,\"p\":1,\"n\":\"Y1\"},{\"t\":3,\"p\":1,\"n\":\"Z1\"},{\"t\":3,\"p\":1,\"n\":\"X2\"},{\"t\":3,\"p\":1,\"n\":\"Y2\"},{\"t\":3,\"p\":1,\"n\":\"Z2\"}]},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"},{\"t\":11,\"n\":\"MODB - Unknown\"},{\"t\":11,\"p\":1,\"n\":\"MODT - Texture Files Hashes\"},{\"t\":7,\"p\":1,\"n\":\"MODS - Alternate Textures\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"3D Name\"},{\"t\":3,\"p\":1,\"n\":\"New Texture\"},{\"t\":3,\"p\":1,\"n\":\"3D Index\"}]}]},{\"t\":3,\"p\":1,\"n\":\"MODD - FaceGen Model Flags\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Icon\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"ICON - Large Icon filename\"},{\"t\":2,\"p\":1,\"n\":\"MICO - Small Icon filename\"}]},{\"t\":3,\"p\":1,\"n\":\"SCRI - Script\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Destructable\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"DEST - Header\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Health\"},{\"t\":3,\"p\":1,\"n\":\"Count\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":8,\"p\":1,\"n\":\"Stages\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Stage\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"DSTD - Destruction Stage Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Health %\"},{\"t\":3,\"p\":1,\"n\":\"Index\"},{\"t\":3,\"p\":1,\"n\":\"Damage Stage\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":3,\"p\":1,\"n\":\"Self Damage per Second\"},{\"t\":3,\"p\":1,\"n\":\"Explosion\"},{\"t\":3,\"p\":1,\"n\":\"Debris\"},{\"t\":3,\"p\":1,\"n\":\"Debris Count\"}]},{\"t\":6,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"DMDL - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"DMDT - Texture Files Hashes\"}]},{\"p\":1,\"n\":\"DSTF - End Marker\"}]}]}]},{\"t\":3,\"p\":1,\"n\":\"YNAM - Sound - Pick Up\"},{\"t\":3,\"p\":1,\"n\":\"ZNAM - Sound - Drop\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DATA - Data\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Speed\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Value\"},{\"t\":3,\"p\":1,\"n\":\"Clip Rounds\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DAT2 - Data 2\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Proj. per Shot\"},{\"t\":3,\"p\":1,\"n\":\"Projectile\"},{\"t\":5,\"p\":1,\"n\":\"Weight\"},{\"t\":3,\"p\":1,\"n\":\"Consumed Ammo\"},{\"t\":5,\"p\":1,\"n\":\"Consumed Percentage\"}]},{\"t\":2,\"p\":1,\"n\":\"ONAM - Short Name\"},{\"t\":2,\"p\":1,\"n\":\"QNAM - Abbrev.\"},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Ammo Effects\",\"d\":1,\"c\":[{\"t\":3,\"p\":1,\"n\":\"RCIL - Effect\"}]}]},{\"t\":1,\"p\":1,\"n\":\"ANIO - Animated Object\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"},{\"t\":11,\"n\":\"MODB - Unknown\"},{\"t\":11,\"p\":1,\"n\":\"MODT - Texture Files Hashes\"},{\"t\":7,\"p\":1,\"n\":\"MODS - Alternate Textures\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"3D Name\"},{\"t\":3,\"p\":1,\"n\":\"New Texture\"},{\"t\":3,\"p\":1,\"n\":\"3D Index\"}]}]},{\"t\":3,\"p\":1,\"n\":\"MODD - FaceGen Model Flags\"}]},{\"t\":3,\"p\":1,\"n\":\"DATA - Animation\"}]},{\"t\":1,\"p\":1,\"n\":\"ARMA - Armor Addon\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"X1\"},{\"t\":3,\"p\":1,\"n\":\"Y1\"},{\"t\":3,\"p\":1,\"n\":\"Z1\"},{\"t\":3,\"p\":1,\"n\":\"X2\"},{\"t\":3,\"p\":1,\"n\":\"Y2\"},{\"t\":3,\"p\":1,\"n\":\"Z2\"}]},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"BMDT - Biped Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Biped Flags\"},{\"t\":3,\"p\":1,\"n\":\"General Flags\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Male biped model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"MODT - Texture Files Hashes\"},{\"t\":7,\"p\":1,\"n\":\"MODS - Alternate Textures\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"3D Name\"},{\"t\":3,\"p\":1,\"n\":\"New Texture\"},{\"t\":3,\"p\":1,\"n\":\"3D Index\"}]}]},{\"t\":3,\"p\":1,\"n\":\"MODD - FaceGen Model Flags\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Male world model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MOD2 - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"MO2T - Texture Files Hashes\"},{\"t\":7,\"p\":1,\"n\":\"MO2S - Alternate Textures\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"3D Name\"},{\"t\":3,\"p\":1,\"n\":\"New Texture\"},{\"t\":3,\"p\":1,\"n\":\"3D Index\"}]}]}]},{\"t\":2,\"p\":1,\"n\":\"ICON - Male icon filename\"},{\"t\":2,\"p\":1,\"n\":\"MICO - Male mico filename\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Female biped model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MOD3 - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"MO3T - Texture Files Hashes\"},{\"t\":7,\"p\":1,\"n\":\"MO3S - Alternate Textures\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"3D Name\"},{\"t\":3,\"p\":1,\"n\":\"New Texture\"},{\"t\":3,\"p\":1,\"n\":\"3D Index\"}]}]},{\"t\":3,\"p\":1,\"n\":\"MOSD - FaceGen Model Flags\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Female world model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MOD4 - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"MO4T - Texture Files Hashes\"},{\"t\":7,\"p\":1,\"n\":\"MO4S - Alternate Textures\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"3D Name\"},{\"t\":3,\"p\":1,\"n\":\"New Texture\"},{\"t\":3,\"p\":1,\"n\":\"3D Index\"}]}]}]},{\"t\":2,\"p\":1,\"n\":\"ICO2 - Female icon filename\"},{\"t\":2,\"p\":1,\"n\":\"MIC2 - Female mico filename\"},{\"t\":3,\"p\":1,\"n\":\"ETYP - Equiptment Type\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DATA - Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Value\"},{\"t\":3,\"p\":1,\"n\":\"Max Condition\"},{\"t\":5,\"p\":1,\"n\":\"Weight\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DNAM - \",\"c\":[{\"t\":3,\"p\":1,\"n\":\"AR\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":5,\"p\":1,\"n\":\"DT\"},{\"t\":11,\"n\":\"Unused\"}]}]},{\"t\":1,\"p\":1,\"n\":\"ARMO - Armor\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"X1\"},{\"t\":3,\"p\":1,\"n\":\"Y1\"},{\"t\":3,\"p\":1,\"n\":\"Z1\"},{\"t\":3,\"p\":1,\"n\":\"X2\"},{\"t\":3,\"p\":1,\"n\":\"Y2\"},{\"t\":3,\"p\":1,\"n\":\"Z2\"}]},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":3,\"p\":1,\"n\":\"SCRI - Script\"},{\"t\":3,\"p\":1,\"n\":\"EITM - Object Effect\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"BMDT - Biped Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Biped Flags\"},{\"t\":3,\"p\":1,\"n\":\"General Flags\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Male biped model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"MODT - Texture Files Hashes\"},{\"t\":7,\"p\":1,\"n\":\"MODS - Alternate Textures\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"3D Name\"},{\"t\":3,\"p\":1,\"n\":\"New Texture\"},{\"t\":3,\"p\":1,\"n\":\"3D Index\"}]}]},{\"t\":3,\"p\":1,\"n\":\"MODD - FaceGen Model Flags\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Male world model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MOD2 - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"MO2T - Texture Files Hashes\"},{\"t\":7,\"p\":1,\"n\":\"MO2S - Alternate Textures\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"3D Name\"},{\"t\":3,\"p\":1,\"n\":\"New Texture\"},{\"t\":3,\"p\":1,\"n\":\"3D Index\"}]}]}]},{\"t\":2,\"p\":1,\"n\":\"ICON - Male icon filename\"},{\"t\":2,\"p\":1,\"n\":\"MICO - Male mico filename\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Female biped model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MOD3 - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"MO3T - Texture Files Hashes\"},{\"t\":7,\"p\":1,\"n\":\"MO3S - Alternate Textures\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"3D Name\"},{\"t\":3,\"p\":1,\"n\":\"New Texture\"},{\"t\":3,\"p\":1,\"n\":\"3D Index\"}]}]},{\"t\":3,\"p\":1,\"n\":\"MOSD - FaceGen Model Flags\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Female world model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MOD4 - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"MO4T - Texture Files Hashes\"},{\"t\":7,\"p\":1,\"n\":\"MO4S - Alternate Textures\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"3D Name\"},{\"t\":3,\"p\":1,\"n\":\"New Texture\"},{\"t\":3,\"p\":1,\"n\":\"3D Index\"}]}]}]},{\"t\":2,\"p\":1,\"n\":\"ICO2 - Female icon filename\"},{\"t\":2,\"p\":1,\"n\":\"MIC2 - Female mico filename\"},{\"t\":2,\"p\":1,\"n\":\"BMCT - Ragdoll Constraint Template\"},{\"t\":3,\"p\":1,\"n\":\"REPL - Repair List\"},{\"t\":3,\"p\":1,\"n\":\"BIPL - Biped Model List\"},{\"t\":3,\"p\":1,\"n\":\"ETYP - Equiptment Type\"},{\"t\":3,\"p\":1,\"n\":\"YNAM - Sound - Pick Up\"},{\"t\":3,\"p\":1,\"n\":\"ZNAM - Sound - Drop\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DATA - Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Value\"},{\"t\":3,\"p\":1,\"n\":\"Health\"},{\"t\":5,\"p\":1,\"n\":\"Weight\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DNAM - \",\"c\":[{\"t\":3,\"p\":1,\"n\":\"AR\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":5,\"p\":1,\"n\":\"DT\"},{\"t\":11,\"p\":1,\"n\":\"?\"}]},{\"t\":3,\"p\":1,\"n\":\"BNAM - Overrides Animation Sounds\"},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Animation Sounds\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"SNAM - Animation Sound\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Sound\"},{\"t\":3,\"p\":1,\"n\":\"Chance\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Type\"}]}]},{\"t\":3,\"p\":1,\"n\":\"TNAM - Animation Sounds Template\"}]},{\"t\":1,\"p\":1,\"n\":\"ASPC - Acoustic Space\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"X1\"},{\"t\":3,\"p\":1,\"n\":\"Y1\"},{\"t\":3,\"p\":1,\"n\":\"Z1\"},{\"t\":3,\"p\":1,\"n\":\"X2\"},{\"t\":3,\"p\":1,\"n\":\"Y2\"},{\"t\":3,\"p\":1,\"n\":\"Z2\"}]},{\"t\":3,\"p\":1,\"n\":\"SNAM - Dawn \\/ Default Loop\"},{\"t\":3,\"p\":1,\"n\":\"SNAM - Afternoon\"},{\"t\":3,\"p\":1,\"n\":\"SNAM - Dusk\"},{\"t\":3,\"p\":1,\"n\":\"SNAM - Night\"},{\"t\":3,\"p\":1,\"n\":\"SNAM - Walla\"},{\"t\":3,\"p\":1,\"n\":\"WNAM - Walla Trigger Count\"},{\"t\":3,\"p\":1,\"n\":\"RDAT - Use Sound from Region (Interiors Only)\"},{\"t\":3,\"p\":1,\"n\":\"ANAM - Environment Type\"},{\"t\":3,\"p\":1,\"n\":\"INAM - Is Interior\"}]},{\"t\":1,\"p\":1,\"n\":\"AVIF - ActorValue Information\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":2,\"p\":1,\"n\":\"DESC - Description\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Icon\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"ICON - Large Icon filename\"},{\"t\":2,\"p\":1,\"n\":\"MICO - Small Icon filename\"}]},{\"t\":2,\"p\":1,\"n\":\"ANAM - Short Name\"}]},{\"t\":1,\"p\":1,\"n\":\"BOOK - Book\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"X1\"},{\"t\":3,\"p\":1,\"n\":\"Y1\"},{\"t\":3,\"p\":1,\"n\":\"Z1\"},{\"t\":3,\"p\":1,\"n\":\"X2\"},{\"t\":3,\"p\":1,\"n\":\"Y2\"},{\"t\":3,\"p\":1,\"n\":\"Z2\"}]},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"},{\"t\":11,\"n\":\"MODB - Unknown\"},{\"t\":11,\"p\":1,\"n\":\"MODT - Texture Files Hashes\"},{\"t\":7,\"p\":1,\"n\":\"MODS - Alternate Textures\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"3D Name\"},{\"t\":3,\"p\":1,\"n\":\"New Texture\"},{\"t\":3,\"p\":1,\"n\":\"3D Index\"}]}]},{\"t\":3,\"p\":1,\"n\":\"MODD - FaceGen Model Flags\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Icon\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"ICON - Large Icon filename\"},{\"t\":2,\"p\":1,\"n\":\"MICO - Small Icon filename\"}]},{\"t\":3,\"p\":1,\"n\":\"SCRI - Script\"},{\"t\":2,\"p\":1,\"n\":\"DESC - Description\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Destructable\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"DEST - Header\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Health\"},{\"t\":3,\"p\":1,\"n\":\"Count\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":8,\"p\":1,\"n\":\"Stages\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Stage\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"DSTD - Destruction Stage Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Health %\"},{\"t\":3,\"p\":1,\"n\":\"Index\"},{\"t\":3,\"p\":1,\"n\":\"Damage Stage\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":3,\"p\":1,\"n\":\"Self Damage per Second\"},{\"t\":3,\"p\":1,\"n\":\"Explosion\"},{\"t\":3,\"p\":1,\"n\":\"Debris\"},{\"t\":3,\"p\":1,\"n\":\"Debris Count\"}]},{\"t\":6,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"DMDL - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"DMDT - Texture Files Hashes\"}]},{\"p\":1,\"n\":\"DSTF - End Marker\"}]}]}]},{\"t\":3,\"p\":1,\"n\":\"YNAM - Sound - Pick Up\"},{\"t\":3,\"p\":1,\"n\":\"ZNAM - Sound - Drop\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DATA - Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":3,\"p\":1,\"n\":\"Skill\"},{\"t\":3,\"p\":1,\"n\":\"Value\"},{\"t\":5,\"p\":1,\"n\":\"Weight\"}]}]},{\"t\":1,\"p\":1,\"n\":\"BPTD - Body Part Data\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"},{\"t\":11,\"n\":\"MODB - Unknown\"},{\"t\":11,\"p\":1,\"n\":\"MODT - Texture Files Hashes\"},{\"t\":7,\"p\":1,\"n\":\"MODS - Alternate Textures\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"3D Name\"},{\"t\":3,\"p\":1,\"n\":\"New Texture\"},{\"t\":3,\"p\":1,\"n\":\"3D Index\"}]}]},{\"t\":3,\"p\":1,\"n\":\"MODD - FaceGen Model Flags\"}]},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Body Parts\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Body Part\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"BPTN - Part Name\"},{\"t\":2,\"p\":1,\"n\":\"BPNN - Part Node\"},{\"t\":2,\"p\":1,\"n\":\"BPNT - VATS Target\"},{\"t\":2,\"p\":1,\"n\":\"BPNI - IK Data - Start Node\"},{\"t\":6,\"p\":1,\"n\":\"BPND - \",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Damage Mult\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":3,\"p\":1,\"n\":\"Part Type\"},{\"t\":3,\"p\":1,\"n\":\"Health Percent\"},{\"t\":3,\"p\":1,\"n\":\"Actor Value\"},{\"t\":3,\"p\":1,\"n\":\"To Hit Chance\"},{\"t\":3,\"p\":1,\"n\":\"Explodable - Explosion Chance %\"},{\"t\":3,\"p\":1,\"n\":\"Explodable - Debris Count\"},{\"t\":3,\"p\":1,\"n\":\"Explodable - Debris\"},{\"t\":3,\"p\":1,\"n\":\"Explodable - Explosion\"},{\"t\":5,\"p\":1,\"n\":\"Tracking Max Angle\"},{\"t\":5,\"p\":1,\"n\":\"Explodable - Debris Scale\"},{\"t\":3,\"p\":1,\"n\":\"Severable - Debris Count\"},{\"t\":3,\"p\":1,\"n\":\"Severable - Debris\"},{\"t\":3,\"p\":1,\"n\":\"Severable - Explosion\"},{\"t\":5,\"p\":1,\"n\":\"Severable - Debris Scale\"},{\"t\":6,\"p\":1,\"n\":\"Gore Effects Positioning\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Translate\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"X\"},{\"t\":5,\"p\":1,\"n\":\"Y\"},{\"t\":5,\"p\":1,\"n\":\"Z\"}]},{\"t\":6,\"p\":1,\"n\":\"Rotation\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"X\"},{\"t\":5,\"p\":1,\"n\":\"Y\"},{\"t\":5,\"p\":1,\"n\":\"Z\"}]}]},{\"t\":3,\"p\":1,\"n\":\"Severable - Impact DataSet\"},{\"t\":3,\"p\":1,\"n\":\"Explodable - Impact DataSet\"},{\"t\":3,\"p\":1,\"n\":\"Severable - Decal Count\"},{\"t\":3,\"p\":1,\"n\":\"Explodable - Decal Count\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":5,\"p\":1,\"n\":\"Limb Replacement Scale\"}]},{\"t\":2,\"p\":1,\"n\":\"NAM1 - Limb Replacement Model\"},{\"t\":2,\"p\":1,\"n\":\"NAM4 - Gore Effects - Target Bone\"},{\"t\":11,\"p\":1,\"n\":\"NAM5 - Texture Files Hashes\"}]}]},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Unnamed Body Parts\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Body Part\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"BPNN - Part Node\"},{\"t\":2,\"p\":1,\"n\":\"BPNT - VATS Target\"},{\"t\":2,\"p\":1,\"n\":\"BPNI - IK Data - Start Node\"},{\"t\":6,\"p\":1,\"n\":\"BPND - \",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Damage Mult\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":3,\"p\":1,\"n\":\"Part Type\"},{\"t\":3,\"p\":1,\"n\":\"Health Percent\"},{\"t\":3,\"p\":1,\"n\":\"Actor Value\"},{\"t\":3,\"p\":1,\"n\":\"To Hit Chance\"},{\"t\":3,\"p\":1,\"n\":\"Explodable - Explosion Chance %\"},{\"t\":3,\"p\":1,\"n\":\"Explodable - Debris Count\"},{\"t\":3,\"p\":1,\"n\":\"Explodable - Debris\"},{\"t\":3,\"p\":1,\"n\":\"Explodable - Explosion\"},{\"t\":5,\"p\":1,\"n\":\"Tracking Max Angle\"},{\"t\":5,\"p\":1,\"n\":\"Explodable - Debris Scale\"},{\"t\":3,\"p\":1,\"n\":\"Severable - Debris Count\"},{\"t\":3,\"p\":1,\"n\":\"Severable - Debris\"},{\"t\":3,\"p\":1,\"n\":\"Severable - Explosion\"},{\"t\":5,\"p\":1,\"n\":\"Severable - Debris Scale\"},{\"t\":6,\"p\":1,\"n\":\"Gore Effects Positioning\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Translate\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"X\"},{\"t\":5,\"p\":1,\"n\":\"Y\"},{\"t\":5,\"p\":1,\"n\":\"Z\"}]},{\"t\":6,\"p\":1,\"n\":\"Rotation\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"X\"},{\"t\":5,\"p\":1,\"n\":\"Y\"},{\"t\":5,\"p\":1,\"n\":\"Z\"}]}]},{\"t\":3,\"p\":1,\"n\":\"Severable - Impact DataSet\"},{\"t\":3,\"p\":1,\"n\":\"Explodable - Impact DataSet\"},{\"t\":3,\"p\":1,\"n\":\"Severable - Decal Count\"},{\"t\":3,\"p\":1,\"n\":\"Explodable - Decal Count\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":5,\"p\":1,\"n\":\"Limb Replacement Scale\"}]},{\"t\":2,\"p\":1,\"n\":\"NAM1 - Limb Replacement Model\"},{\"t\":2,\"p\":1,\"n\":\"NAM4 - Gore Effects - Target Bone\"},{\"t\":11,\"p\":1,\"n\":\"NAM5 - Texture Files Hashes\"}]}]},{\"t\":3,\"p\":1,\"n\":\"RAGA - Ragdoll\"}]},{\"t\":1,\"p\":1,\"n\":\"CAMS - Camera Shot\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"},{\"t\":11,\"n\":\"MODB - Unknown\"},{\"t\":11,\"p\":1,\"n\":\"MODT - Texture Files Hashes\"},{\"t\":7,\"p\":1,\"n\":\"MODS - Alternate Textures\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"3D Name\"},{\"t\":3,\"p\":1,\"n\":\"New Texture\"},{\"t\":3,\"p\":1,\"n\":\"3D Index\"}]}]},{\"t\":3,\"p\":1,\"n\":\"MODD - FaceGen Model Flags\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DATA - Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Action\"},{\"t\":3,\"p\":1,\"n\":\"Location\"},{\"t\":3,\"p\":1,\"n\":\"Target\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":6,\"p\":1,\"n\":\"Time Multipliers\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Player\"},{\"t\":5,\"p\":1,\"n\":\"Target\"},{\"t\":5,\"p\":1,\"n\":\"Global\"}]},{\"t\":5,\"p\":1,\"n\":\"Max Time\"},{\"t\":5,\"p\":1,\"n\":\"Min Time\"},{\"t\":5,\"p\":1,\"n\":\"Target % Between Actors\"}]},{\"t\":3,\"p\":1,\"n\":\"MNAM - Image Space Modifier\"}]},{\"t\":1,\"p\":1,\"n\":\"CCRD - Caravan Card\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"X1\"},{\"t\":3,\"p\":1,\"n\":\"Y1\"},{\"t\":3,\"p\":1,\"n\":\"Z1\"},{\"t\":3,\"p\":1,\"n\":\"X2\"},{\"t\":3,\"p\":1,\"n\":\"Y2\"},{\"t\":3,\"p\":1,\"n\":\"Z2\"}]},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"},{\"t\":11,\"n\":\"MODB - Unknown\"},{\"t\":11,\"p\":1,\"n\":\"MODT - Texture Files Hashes\"},{\"t\":7,\"p\":1,\"n\":\"MODS - Alternate Textures\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"3D Name\"},{\"t\":3,\"p\":1,\"n\":\"New Texture\"},{\"t\":3,\"p\":1,\"n\":\"3D Index\"}]}]},{\"t\":3,\"p\":1,\"n\":\"MODD - FaceGen Model Flags\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Icon\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"ICON - Large Icon filename\"},{\"t\":2,\"p\":1,\"n\":\"MICO - Small Icon filename\"}]},{\"t\":3,\"p\":1,\"n\":\"SCRI - Script\"},{\"t\":3,\"p\":1,\"n\":\"YNAM - Sound - Pick Up\"},{\"t\":3,\"p\":1,\"n\":\"ZNAM - Sound - Drop\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"High Res Image\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"TX00 - Face\"},{\"t\":2,\"p\":1,\"n\":\"TX01 - Back\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Card\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"INTV - Suit\"},{\"t\":3,\"p\":1,\"n\":\"INTV - Value\"}]},{\"t\":3,\"p\":1,\"n\":\"DATA - Value\"}]},{\"t\":1,\"p\":1,\"n\":\"CDCK - Caravan Deck\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Cards\",\"d\":1,\"c\":[{\"t\":3,\"p\":1,\"n\":\"CARD - Card\"}]},{\"t\":3,\"p\":1,\"n\":\"DATA - Count (broken)\"}]},{\"t\":1,\"p\":1,\"n\":\"CELL - Cell\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":3,\"p\":1,\"n\":\"DATA - Flags\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"XCLC - Grid\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"X\"},{\"t\":3,\"p\":1,\"n\":\"Y\"},{\"t\":3,\"p\":1,\"n\":\"Force Hide Land\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"XCLL - Lighting\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Ambient Color\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Directional Color\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Fog Color\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":5,\"p\":1,\"n\":\"Fog Near\"},{\"t\":5,\"p\":1,\"n\":\"Fog Far\"},{\"t\":3,\"p\":1,\"n\":\"Directional Rotation XY\"},{\"t\":3,\"p\":1,\"n\":\"Directional Rotation Z\"},{\"t\":5,\"p\":1,\"n\":\"Directional Fade\"},{\"t\":5,\"p\":1,\"n\":\"Fog Clip Dist\"},{\"t\":5,\"p\":1,\"n\":\"Fog Power\"}]},{\"t\":7,\"n\":\"IMPF - Footstep Materials\",\"c\":[{\"t\":2,\"n\":\"Unknown\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Light Template\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"LTMP - Template\"},{\"t\":3,\"p\":1,\"n\":\"LNAM - Inherit\"}]},{\"t\":5,\"p\":1,\"n\":\"XCLW - Water Height\"},{\"t\":2,\"p\":1,\"n\":\"XNAM - Water Noise Texture\"},{\"t\":7,\"p\":1,\"n\":\"XCLR - Regions\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Region\"}]},{\"t\":3,\"p\":1,\"n\":\"XCIM - Image Space\"},{\"t\":11,\"n\":\"XCET - Unknown\"},{\"t\":3,\"p\":1,\"n\":\"XEZN - Encounter Zone\"},{\"t\":3,\"p\":1,\"n\":\"XCCM - Climate\"},{\"t\":3,\"p\":1,\"n\":\"XCWT - Water\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Ownership\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"XOWN - Owner\"},{\"t\":3,\"p\":1,\"n\":\"XRNK - Faction rank\"}]},{\"t\":3,\"p\":1,\"n\":\"XCAS - Acoustic Space\"},{\"t\":11,\"n\":\"XCMT - Unused\"},{\"t\":3,\"p\":1,\"n\":\"XCMO - Music Type\"}]},{\"t\":1,\"p\":1,\"n\":\"CHAL - Challenge\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Icon\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"ICON - Large Icon filename\"},{\"t\":2,\"p\":1,\"n\":\"MICO - Small Icon filename\"}]},{\"t\":3,\"p\":1,\"n\":\"SCRI - Script\"},{\"t\":2,\"p\":1,\"n\":\"DESC - Description\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DATA - Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Threshold\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":3,\"p\":1,\"n\":\"Interval\"},{\"t\":11,\"p\":1,\"n\":\"(depends on type)\"}]},{\"t\":3,\"p\":1,\"n\":\"SNAM - (depends on type)\"},{\"t\":3,\"p\":1,\"n\":\"XNAM - (depends on type)\"}]},{\"t\":1,\"p\":1,\"n\":\"CHIP - Casino Chip\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"X1\"},{\"t\":3,\"p\":1,\"n\":\"Y1\"},{\"t\":3,\"p\":1,\"n\":\"Z1\"},{\"t\":3,\"p\":1,\"n\":\"X2\"},{\"t\":3,\"p\":1,\"n\":\"Y2\"},{\"t\":3,\"p\":1,\"n\":\"Z2\"}]},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"},{\"t\":11,\"n\":\"MODB - Unknown\"},{\"t\":11,\"p\":1,\"n\":\"MODT - Texture Files Hashes\"},{\"t\":7,\"p\":1,\"n\":\"MODS - Alternate Textures\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"3D Name\"},{\"t\":3,\"p\":1,\"n\":\"New Texture\"},{\"t\":3,\"p\":1,\"n\":\"3D Index\"}]}]},{\"t\":3,\"p\":1,\"n\":\"MODD - FaceGen Model Flags\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Icon\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"ICON - Large Icon filename\"},{\"t\":2,\"p\":1,\"n\":\"MICO - Small Icon filename\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Destructable\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"DEST - Header\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Health\"},{\"t\":3,\"p\":1,\"n\":\"Count\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":8,\"p\":1,\"n\":\"Stages\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Stage\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"DSTD - Destruction Stage Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Health %\"},{\"t\":3,\"p\":1,\"n\":\"Index\"},{\"t\":3,\"p\":1,\"n\":\"Damage Stage\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":3,\"p\":1,\"n\":\"Self Damage per Second\"},{\"t\":3,\"p\":1,\"n\":\"Explosion\"},{\"t\":3,\"p\":1,\"n\":\"Debris\"},{\"t\":3,\"p\":1,\"n\":\"Debris Count\"}]},{\"t\":6,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"DMDL - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"DMDT - Texture Files Hashes\"}]},{\"p\":1,\"n\":\"DSTF - End Marker\"}]}]}]},{\"t\":3,\"p\":1,\"n\":\"YNAM - Sound - Pick Up\"},{\"t\":3,\"p\":1,\"n\":\"ZNAM - Sound - Drop\"}]},{\"t\":1,\"p\":1,\"n\":\"CLAS - Class\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":2,\"p\":1,\"n\":\"DESC - Description\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Icon\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"ICON - Large Icon filename\"},{\"t\":2,\"p\":1,\"n\":\"MICO - Small Icon filename\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DATA - \",\"c\":[{\"t\":7,\"p\":1,\"n\":\"Tag Skills\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Tag Skill\"}]},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":3,\"p\":1,\"n\":\"Buys\\/Sells and Services\"},{\"t\":3,\"p\":1,\"n\":\"Teaches\"},{\"t\":3,\"p\":1,\"n\":\"Maximum training level\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":7,\"p\":1,\"n\":\"ATTR - Attributes\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Attribute\"}]}]},{\"t\":1,\"p\":1,\"n\":\"CLMT - Climate\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":7,\"p\":1,\"n\":\"WLST - Weather Types\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Weather Type\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Weather\"},{\"t\":3,\"p\":1,\"n\":\"Chance\"},{\"t\":3,\"p\":1,\"n\":\"Global\"}]}]},{\"t\":2,\"p\":1,\"n\":\"FNAM - Sun Texture\"},{\"t\":2,\"p\":1,\"n\":\"GNAM - Sun Glare Texture\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"},{\"t\":11,\"n\":\"MODB - Unknown\"},{\"t\":11,\"p\":1,\"n\":\"MODT - Texture Files Hashes\"},{\"t\":7,\"p\":1,\"n\":\"MODS - Alternate Textures\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"3D Name\"},{\"t\":3,\"p\":1,\"n\":\"New Texture\"},{\"t\":3,\"p\":1,\"n\":\"3D Index\"}]}]},{\"t\":3,\"p\":1,\"n\":\"MODD - FaceGen Model Flags\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"TNAM - Timing\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Sunrise\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Begin\"},{\"t\":3,\"p\":1,\"n\":\"End\"}]},{\"t\":6,\"p\":1,\"n\":\"Sunset\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Begin\"},{\"t\":3,\"p\":1,\"n\":\"End\"}]},{\"t\":3,\"p\":1,\"n\":\"Volatility\"},{\"t\":3,\"p\":1,\"n\":\"Moons \\/ Phase Length\"}]}]},{\"t\":1,\"p\":1,\"n\":\"CMNY - Caravan Money\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"X1\"},{\"t\":3,\"p\":1,\"n\":\"Y1\"},{\"t\":3,\"p\":1,\"n\":\"Z1\"},{\"t\":3,\"p\":1,\"n\":\"X2\"},{\"t\":3,\"p\":1,\"n\":\"Y2\"},{\"t\":3,\"p\":1,\"n\":\"Z2\"}]},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"},{\"t\":11,\"n\":\"MODB - Unknown\"},{\"t\":11,\"p\":1,\"n\":\"MODT - Texture Files Hashes\"},{\"t\":7,\"p\":1,\"n\":\"MODS - Alternate Textures\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"3D Name\"},{\"t\":3,\"p\":1,\"n\":\"New Texture\"},{\"t\":3,\"p\":1,\"n\":\"3D Index\"}]}]},{\"t\":3,\"p\":1,\"n\":\"MODD - FaceGen Model Flags\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Icon\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"ICON - Large Icon filename\"},{\"t\":2,\"p\":1,\"n\":\"MICO - Small Icon filename\"}]},{\"t\":3,\"p\":1,\"n\":\"YNAM - Sound - Pick Up\"},{\"t\":3,\"p\":1,\"n\":\"ZNAM - Sound - Drop\"},{\"t\":3,\"p\":1,\"n\":\"DATA - Absolute Value\"}]},{\"t\":1,\"p\":1,\"n\":\"COBJ - Constructible Object\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"X1\"},{\"t\":3,\"p\":1,\"n\":\"Y1\"},{\"t\":3,\"p\":1,\"n\":\"Z1\"},{\"t\":3,\"p\":1,\"n\":\"X2\"},{\"t\":3,\"p\":1,\"n\":\"Y2\"},{\"t\":3,\"p\":1,\"n\":\"Z2\"}]},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"},{\"t\":11,\"n\":\"MODB - Unknown\"},{\"t\":11,\"p\":1,\"n\":\"MODT - Texture Files Hashes\"},{\"t\":7,\"p\":1,\"n\":\"MODS - Alternate Textures\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"3D Name\"},{\"t\":3,\"p\":1,\"n\":\"New Texture\"},{\"t\":3,\"p\":1,\"n\":\"3D Index\"}]}]},{\"t\":3,\"p\":1,\"n\":\"MODD - FaceGen Model Flags\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Icon\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"ICON - Large Icon filename\"},{\"t\":2,\"p\":1,\"n\":\"MICO - Small Icon filename\"}]},{\"t\":3,\"p\":1,\"n\":\"SCRI - Script\"},{\"t\":3,\"p\":1,\"n\":\"YNAM - Sound - Pick Up\"},{\"t\":3,\"p\":1,\"n\":\"ZNAM - Sound - Drop\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DATA - \",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Value\"},{\"t\":5,\"p\":1,\"n\":\"Weight\"}]}]},{\"t\":1,\"p\":1,\"n\":\"CONT - Container\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"X1\"},{\"t\":3,\"p\":1,\"n\":\"Y1\"},{\"t\":3,\"p\":1,\"n\":\"Z1\"},{\"t\":3,\"p\":1,\"n\":\"X2\"},{\"t\":3,\"p\":1,\"n\":\"Y2\"},{\"t\":3,\"p\":1,\"n\":\"Z2\"}]},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"},{\"t\":11,\"n\":\"MODB - Unknown\"},{\"t\":11,\"p\":1,\"n\":\"MODT - Texture Files Hashes\"},{\"t\":7,\"p\":1,\"n\":\"MODS - Alternate Textures\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"3D Name\"},{\"t\":3,\"p\":1,\"n\":\"New Texture\"},{\"t\":3,\"p\":1,\"n\":\"3D Index\"}]}]},{\"t\":3,\"p\":1,\"n\":\"MODD - FaceGen Model Flags\"}]},{\"t\":3,\"p\":1,\"n\":\"SCRI - Script\"},{\"t\":10,\"p\":1,\"n\":\"Items\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Item\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"CNTO - Item\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Item\"},{\"t\":3,\"p\":1,\"n\":\"Count\"}]},{\"t\":6,\"p\":1,\"n\":\"COED - Extra Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Owner\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Global Variable\"},{\"t\":3,\"p\":1,\"n\":\"Required Rank\"},{\"t\":5,\"p\":1,\"n\":\"Item Condition\"}]}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Destructable\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"DEST - Header\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Health\"},{\"t\":3,\"p\":1,\"n\":\"Count\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":8,\"p\":1,\"n\":\"Stages\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Stage\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"DSTD - Destruction Stage Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Health %\"},{\"t\":3,\"p\":1,\"n\":\"Index\"},{\"t\":3,\"p\":1,\"n\":\"Damage Stage\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":3,\"p\":1,\"n\":\"Self Damage per Second\"},{\"t\":3,\"p\":1,\"n\":\"Explosion\"},{\"t\":3,\"p\":1,\"n\":\"Debris\"},{\"t\":3,\"p\":1,\"n\":\"Debris Count\"}]},{\"t\":6,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"DMDL - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"DMDT - Texture Files Hashes\"}]},{\"p\":1,\"n\":\"DSTF - End Marker\"}]}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DATA - \",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":5,\"p\":1,\"n\":\"Weight\"}]},{\"t\":3,\"p\":1,\"n\":\"SNAM - Sound - Open\"},{\"t\":3,\"p\":1,\"n\":\"QNAM - Sound - Close\"},{\"t\":3,\"p\":1,\"n\":\"RNAM - Sound - Random\\/Looping\"}]},{\"t\":1,\"p\":1,\"n\":\"CPTH - Camera Path\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Conditions\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"CTDA - Condition\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":5,\"p\":1,\"n\":\"Comparison Value - Float\"},{\"t\":3,\"p\":1,\"n\":\"Comparison Value - Global\"},{\"t\":3,\"p\":1,\"n\":\"Function\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":11,\"p\":1,\"n\":\"None\"},{\"t\":3,\"p\":1,\"n\":\"Integer\"},{\"t\":3,\"p\":1,\"n\":\"Variable Name (INVALID)\"},{\"t\":3,\"p\":1,\"n\":\"Sex\"},{\"t\":3,\"p\":1,\"n\":\"Actor Value\"},{\"t\":3,\"p\":1,\"n\":\"Crime Type\"},{\"t\":3,\"p\":1,\"n\":\"Axis\"},{\"t\":3,\"p\":1,\"n\":\"Quest Stage (INVALID)\"},{\"t\":3,\"p\":1,\"n\":\"Misc Stat\"},{\"t\":3,\"p\":1,\"n\":\"Alignment\"},{\"t\":3,\"p\":1,\"n\":\"Equip Type\"},{\"t\":3,\"p\":1,\"n\":\"Form Type\"},{\"t\":3,\"p\":1,\"n\":\"Critical Stage\"},{\"t\":3,\"p\":1,\"n\":\"Object Reference\"},{\"t\":3,\"p\":1,\"n\":\"Inventory Object\"},{\"t\":3,\"p\":1,\"n\":\"Actor\"},{\"t\":3,\"p\":1,\"n\":\"Voice Type\"},{\"t\":3,\"p\":1,\"n\":\"Idle\"},{\"t\":3,\"p\":1,\"n\":\"Form List\"},{\"t\":3,\"p\":1,\"n\":\"Note\"},{\"t\":3,\"p\":1,\"n\":\"Quest\"},{\"t\":3,\"p\":1,\"n\":\"Faction\"},{\"t\":3,\"p\":1,\"n\":\"Weapon\"},{\"t\":3,\"p\":1,\"n\":\"Cell\"},{\"t\":3,\"p\":1,\"n\":\"Class\"},{\"t\":3,\"p\":1,\"n\":\"Race\"},{\"t\":3,\"p\":1,\"n\":\"Actor Base\"},{\"t\":3,\"p\":1,\"n\":\"Global\"},{\"t\":3,\"p\":1,\"n\":\"Weather\"},{\"t\":3,\"p\":1,\"n\":\"Package\"},{\"t\":3,\"p\":1,\"n\":\"Encounter Zone\"},{\"t\":3,\"p\":1,\"n\":\"Perk\"},{\"t\":3,\"p\":1,\"n\":\"Owner\"},{\"t\":3,\"p\":1,\"n\":\"Furniture\"},{\"t\":3,\"p\":1,\"n\":\"Effect Item\"},{\"t\":3,\"p\":1,\"n\":\"Base Effect\"},{\"t\":3,\"p\":1,\"n\":\"Worldspace\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Function\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Param (INVALID)\"},{\"t\":3,\"p\":1,\"n\":\"Creature Type\"},{\"t\":3,\"p\":1,\"n\":\"Menu Mode\"},{\"t\":3,\"p\":1,\"n\":\"Player Action\"},{\"t\":3,\"p\":1,\"n\":\"Body Location\"},{\"t\":3,\"p\":1,\"n\":\"Referenceable Object\"},{\"t\":3,\"p\":1,\"n\":\"Quest Objective (INVALID)\"},{\"t\":3,\"p\":1,\"n\":\"Reputation\"},{\"t\":3,\"p\":1,\"n\":\"Region\"},{\"t\":3,\"p\":1,\"n\":\"Challenge\"},{\"t\":3,\"p\":1,\"n\":\"Casino\"},{\"t\":3,\"p\":1,\"n\":\"Form\"},{\"t\":3,\"p\":1,\"n\":\"Variable Name\"},{\"t\":3,\"p\":1,\"n\":\"Quest Stage\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Function (INVALID)\"},{\"t\":3,\"p\":1,\"n\":\"Weapon List\"},{\"t\":3,\"p\":1,\"n\":\"Target\"},{\"t\":3,\"p\":1,\"n\":\"Target List\"},{\"t\":3,\"p\":1,\"n\":\"Target Part\"},{\"t\":3,\"p\":1,\"n\":\"VATS Action\"},{\"t\":3,\"p\":1,\"n\":\"Critical Effect\"},{\"t\":3,\"p\":1,\"n\":\"Critical Effect List\"},{\"t\":3,\"p\":1,\"n\":\"Weapon Type\"},{\"t\":3,\"p\":1,\"n\":\"Quest Objective\"},{\"t\":3,\"p\":1,\"n\":\"Run On\"},{\"t\":3,\"p\":1,\"n\":\"Reference\"}]}]},{\"t\":7,\"p\":1,\"n\":\"ANAM - Related Camera Paths\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Related Camera Path\"}]},{\"t\":3,\"p\":1,\"n\":\"DATA - Camera Zoom\"},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Camera Shots\",\"d\":1,\"c\":[{\"t\":3,\"p\":1,\"n\":\"SNAM - Camera Shot\"}]}]},{\"t\":1,\"p\":1,\"n\":\"CREA - Creature\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"X1\"},{\"t\":3,\"p\":1,\"n\":\"Y1\"},{\"t\":3,\"p\":1,\"n\":\"Z1\"},{\"t\":3,\"p\":1,\"n\":\"X2\"},{\"t\":3,\"p\":1,\"n\":\"Y2\"},{\"t\":3,\"p\":1,\"n\":\"Z2\"}]},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"},{\"t\":11,\"n\":\"MODB - Unknown\"},{\"t\":11,\"p\":1,\"n\":\"MODT - Texture Files Hashes\"},{\"t\":7,\"p\":1,\"n\":\"MODS - Alternate Textures\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"3D Name\"},{\"t\":3,\"p\":1,\"n\":\"New Texture\"},{\"t\":3,\"p\":1,\"n\":\"3D Index\"}]}]},{\"t\":3,\"p\":1,\"n\":\"MODD - FaceGen Model Flags\"}]},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Actor Effects\",\"d\":1,\"c\":[{\"t\":3,\"p\":1,\"n\":\"SPLO - Actor Effect\"}]},{\"t\":3,\"p\":1,\"n\":\"EITM - Unarmed Attack Effect\"},{\"t\":3,\"p\":1,\"n\":\"EAMT - Unarmed Attack Animation\"},{\"t\":7,\"p\":1,\"n\":\"NIFZ - Model List\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"Model\"}]},{\"t\":11,\"n\":\"NIFT - Texture Files Hashes\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"ACBS - Configuration\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":3,\"p\":1,\"n\":\"Fatigue\"},{\"t\":3,\"p\":1,\"n\":\"Barter gold\"},{\"t\":3,\"p\":1,\"n\":\"Level\"},{\"t\":3,\"p\":1,\"n\":\"Level Mult\"},{\"t\":3,\"p\":1,\"n\":\"Calc min\"},{\"t\":3,\"p\":1,\"n\":\"Calc max\"},{\"t\":3,\"p\":1,\"n\":\"Speed Multiplier\"},{\"t\":5,\"p\":1,\"n\":\"Karma (Alignment)\"},{\"t\":3,\"p\":1,\"n\":\"Disposition Base\"},{\"t\":3,\"p\":1,\"n\":\"Template Flags\"}]},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Factions\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"SNAM - Faction\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Faction\"},{\"t\":3,\"p\":1,\"n\":\"Rank\"},{\"t\":11,\"n\":\"Unused\"}]}]},{\"t\":3,\"p\":1,\"n\":\"INAM - Death item\"},{\"t\":3,\"p\":1,\"n\":\"VTCK - Voice\"},{\"t\":3,\"p\":1,\"n\":\"TPLT - Template\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Destructable\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"DEST - Header\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Health\"},{\"t\":3,\"p\":1,\"n\":\"Count\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":8,\"p\":1,\"n\":\"Stages\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Stage\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"DSTD - Destruction Stage Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Health %\"},{\"t\":3,\"p\":1,\"n\":\"Index\"},{\"t\":3,\"p\":1,\"n\":\"Damage Stage\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":3,\"p\":1,\"n\":\"Self Damage per Second\"},{\"t\":3,\"p\":1,\"n\":\"Explosion\"},{\"t\":3,\"p\":1,\"n\":\"Debris\"},{\"t\":3,\"p\":1,\"n\":\"Debris Count\"}]},{\"t\":6,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"DMDL - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"DMDT - Texture Files Hashes\"}]},{\"p\":1,\"n\":\"DSTF - End Marker\"}]}]}]},{\"t\":3,\"p\":1,\"n\":\"SCRI - Script\"},{\"t\":10,\"p\":1,\"n\":\"Items\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Item\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"CNTO - Item\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Item\"},{\"t\":3,\"p\":1,\"n\":\"Count\"}]},{\"t\":6,\"p\":1,\"n\":\"COED - Extra Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Owner\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Global Variable\"},{\"t\":3,\"p\":1,\"n\":\"Required Rank\"},{\"t\":5,\"p\":1,\"n\":\"Item Condition\"}]}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"AIDT - AI Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Aggression\"},{\"t\":3,\"p\":1,\"n\":\"Confidence\"},{\"t\":3,\"p\":1,\"n\":\"Energy Level\"},{\"t\":3,\"p\":1,\"n\":\"Responsibility\"},{\"t\":3,\"p\":1,\"n\":\"Mood\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Buys\\/Sells and Services\"},{\"t\":3,\"p\":1,\"n\":\"Teaches\"},{\"t\":3,\"p\":1,\"n\":\"Maximum training level\"},{\"t\":3,\"p\":1,\"n\":\"Assistance\"},{\"t\":3,\"p\":1,\"n\":\"Aggro Radius Behavior\"},{\"t\":3,\"p\":1,\"n\":\"Aggro Radius\"}]},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Packages\",\"d\":1,\"c\":[{\"t\":3,\"p\":1,\"n\":\"PKID - Package\"}]},{\"t\":7,\"p\":1,\"n\":\"KFFZ - Animations\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"Animation\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DATA - \",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Combat Skill\"},{\"t\":3,\"p\":1,\"n\":\"Magic Skill\"},{\"t\":3,\"p\":1,\"n\":\"Stealth Skill\"},{\"t\":3,\"p\":1,\"n\":\"Health\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Damage\"},{\"t\":7,\"p\":1,\"n\":\"Attributes\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Attribute\"}]}]},{\"t\":3,\"p\":1,\"n\":\"RNAM - Attack reach\"},{\"t\":3,\"p\":1,\"n\":\"ZNAM - Combat Style\"},{\"t\":3,\"p\":1,\"n\":\"PNAM - Body Part Data\"},{\"t\":5,\"p\":1,\"n\":\"TNAM - Turning Speed\"},{\"t\":5,\"p\":1,\"n\":\"BNAM - Base Scale\"},{\"t\":5,\"p\":1,\"n\":\"WNAM - Foot Weight\"},{\"t\":3,\"p\":1,\"n\":\"NAM4 - Impact Material Type\"},{\"t\":3,\"p\":1,\"n\":\"NAM5 - Sound Level\"},{\"t\":3,\"p\":1,\"n\":\"CSCR - Inherits Sounds from\"},{\"t\":10,\"p\":1,\"n\":\"Sound Types\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Sound Type\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"CSDT - Type\"},{\"t\":10,\"p\":1,\"n\":\"Sounds\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Sound\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"CSDI - Sound\"},{\"t\":3,\"p\":1,\"n\":\"CSDC - Sound Chance\"}]}]}]}]},{\"t\":3,\"p\":1,\"n\":\"CNAM - Impact Dataset\"},{\"t\":3,\"p\":1,\"n\":\"LNAM - Melee Weapon List\"}]},{\"t\":1,\"p\":1,\"n\":\"CSNO - Casino\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DATA - Data\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Decks % Before Shuffle\"},{\"t\":5,\"p\":1,\"n\":\"BlackJack Payout Ratio\"},{\"t\":7,\"p\":1,\"n\":\"Slot Reel Stops\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Reel\"}]},{\"t\":3,\"p\":1,\"n\":\"Number of Decks\"},{\"t\":3,\"p\":1,\"n\":\"Max Winnings\"},{\"t\":3,\"p\":1,\"n\":\"Currency\"},{\"t\":3,\"p\":1,\"n\":\"Casino Winnings Quest\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Casino Chip Models\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - $1 Chip\"},{\"t\":2,\"p\":1,\"n\":\"MODL - $5 Chip\"},{\"t\":2,\"p\":1,\"n\":\"MODL - $10 Chip\"},{\"t\":2,\"p\":1,\"n\":\"MODL - $25 Chip\"},{\"t\":2,\"p\":1,\"n\":\"MODL - $100 Chip\"},{\"t\":2,\"p\":1,\"n\":\"MODL - $500 Chip\"},{\"t\":2,\"p\":1,\"n\":\"MODL - Roulette Chip\"}]},{\"t\":2,\"p\":1,\"n\":\"MODL - Slot Machine Model\"},{\"t\":2,\"p\":1,\"n\":\"MOD2 - Slot Machine Model (again?)\"},{\"t\":2,\"p\":1,\"n\":\"MOD3 - BlackJack Table Model\"},{\"t\":2,\"p\":1,\"n\":\"MODT - BlackJack Table Model related\"},{\"t\":2,\"p\":1,\"n\":\"MOD4 - Roulette Table Model\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Slot Reel Textures\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"ICON - Symbol 1\"},{\"t\":2,\"p\":1,\"n\":\"ICON - Symbol 2\"},{\"t\":2,\"p\":1,\"n\":\"ICON - Symbol 3\"},{\"t\":2,\"p\":1,\"n\":\"ICON - Symbol 4\"},{\"t\":2,\"p\":1,\"n\":\"ICON - Symbol 5\"},{\"t\":2,\"p\":1,\"n\":\"ICON - Symbol 6\"},{\"t\":2,\"p\":1,\"n\":\"ICON - Symbol W\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"BlackJack Decks\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"ICO2 - Deck 1\"},{\"t\":2,\"p\":1,\"n\":\"ICO2 - Deck 2\"},{\"t\":2,\"p\":1,\"n\":\"ICO2 - Deck 3\"},{\"t\":2,\"p\":1,\"n\":\"ICO2 - Deck 4\"}]}]},{\"t\":1,\"p\":1,\"n\":\"CSTY - Combat Style\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"CSTD - Advanced - Standard\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Maneuver Decision - Dodge % Chance\"},{\"t\":3,\"p\":1,\"n\":\"Maneuver Decision - Left\\/Right % Chance\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":5,\"p\":1,\"n\":\"Maneuver Decision - Dodge L\\/R Timer (min)\"},{\"t\":5,\"p\":1,\"n\":\"Maneuver Decision - Dodge L\\/R Timer (max)\"},{\"t\":5,\"p\":1,\"n\":\"Maneuver Decision - Dodge Forward Timer (min)\"},{\"t\":5,\"p\":1,\"n\":\"Maneuver Decision - Dodge Forward Timer (max)\"},{\"t\":5,\"p\":1,\"n\":\"Maneuver Decision - Dodge Back Timer Min\"},{\"t\":5,\"p\":1,\"n\":\"Maneuver Decision - Dodge Back Timer Max\"},{\"t\":5,\"p\":1,\"n\":\"Maneuver Decision - Idle Timer min\"},{\"t\":5,\"p\":1,\"n\":\"Maneuver Decision - Idle Timer max\"},{\"t\":3,\"p\":1,\"n\":\"Melee Decision - Block % Chance\"},{\"t\":3,\"p\":1,\"n\":\"Melee Decision - Attack % Chance\"},{\"t\":5,\"p\":1,\"n\":\"Melee Decision - Recoil\\/Stagger Bonus to Attack\"},{\"t\":5,\"p\":1,\"n\":\"Melee Decision - Unconscious Bonus to Attack\"},{\"t\":5,\"p\":1,\"n\":\"Melee Decision - Hand-To-Hand Bonus to Attack\"},{\"t\":3,\"p\":1,\"n\":\"Melee Decision - Power Attacks - Power Attack % Chance\"},{\"t\":5,\"p\":1,\"n\":\"Melee Decision - Power Attacks - Recoil\\/Stagger Bonus to Power\"},{\"t\":5,\"p\":1,\"n\":\"Melee Decision - Power Attacks - Unconscious Bonus to Power Attack\"},{\"t\":3,\"p\":1,\"n\":\"Melee Decision - Power Attacks - Normal\"},{\"t\":3,\"p\":1,\"n\":\"Melee Decision - Power Attacks - Forward\"},{\"t\":3,\"p\":1,\"n\":\"Melee Decision - Power Attacks - Back\"},{\"t\":3,\"p\":1,\"n\":\"Melee Decision - Power Attacks - Left\"},{\"t\":3,\"p\":1,\"n\":\"Melee Decision - Power Attacks - Right\"},{\"t\":5,\"p\":1,\"n\":\"Melee Decision - Hold Timer (min)\"},{\"t\":5,\"p\":1,\"n\":\"Melee Decision - Hold Timer (max)\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":3,\"p\":1,\"n\":\"Maneuver Decision - Acrobatic Dodge % Chance\"},{\"t\":3,\"p\":1,\"n\":\"Melee Decision - Power Attacks - Rushing Attack % Chance\"},{\"t\":5,\"p\":1,\"n\":\"Melee Decision - Power Attacks - Rushing Attack Distance Mult\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"CSAD - Advanced - Advanced\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Dodge Fatigue Mod Mult\"},{\"t\":5,\"p\":1,\"n\":\"Dodge Fatigue Mod Base\"},{\"t\":5,\"p\":1,\"n\":\"Encumb. Speed Mod Base\"},{\"t\":5,\"p\":1,\"n\":\"Encumb. Speed Mod Mult\"},{\"t\":5,\"p\":1,\"n\":\"Dodge While Under Attack Mult\"},{\"t\":5,\"p\":1,\"n\":\"Dodge Not Under Attack Mult\"},{\"t\":5,\"p\":1,\"n\":\"Dodge Back While Under Attack Mult\"},{\"t\":5,\"p\":1,\"n\":\"Dodge Back Not Under Attack Mult\"},{\"t\":5,\"p\":1,\"n\":\"Dodge Forward While Attacking Mult\"},{\"t\":5,\"p\":1,\"n\":\"Dodge Forward Not Attacking Mult\"},{\"t\":5,\"p\":1,\"n\":\"Block Skill Modifier Mult\"},{\"t\":5,\"p\":1,\"n\":\"Block Skill Modifier Base\"},{\"t\":5,\"p\":1,\"n\":\"Block While Under Attack Mult\"},{\"t\":5,\"p\":1,\"n\":\"Block Not Under Attack Mult\"},{\"t\":5,\"p\":1,\"n\":\"Attack Skill Modifier Mult\"},{\"t\":5,\"p\":1,\"n\":\"Attack Skill Modifier Base\"},{\"t\":5,\"p\":1,\"n\":\"Attack While Under Attack Mult\"},{\"t\":5,\"p\":1,\"n\":\"Attack Not Under Attack Mult\"},{\"t\":5,\"p\":1,\"n\":\"Attack During Block Mult\"},{\"t\":5,\"p\":1,\"n\":\"Power Att. Fatigue Mod Base\"},{\"t\":5,\"p\":1,\"n\":\"Power Att. Fatigue Mod Mult\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"CSSD - Simple\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Cover Search Radius\"},{\"t\":5,\"p\":1,\"n\":\"Take Cover Chance\"},{\"t\":5,\"p\":1,\"n\":\"Wait Timer (min)\"},{\"t\":5,\"p\":1,\"n\":\"Wait Timer (max)\"},{\"t\":5,\"p\":1,\"n\":\"Wait to Fire Timer (min)\"},{\"t\":5,\"p\":1,\"n\":\"Wait to Fire Timer (max)\"},{\"t\":5,\"p\":1,\"n\":\"Fire Timer (min)\"},{\"t\":5,\"p\":1,\"n\":\"Fire Timer (max)\"},{\"t\":5,\"p\":1,\"n\":\"Ranged Weapon Range Mult (min)\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Weapon Restrictions\"},{\"t\":5,\"p\":1,\"n\":\"Ranged Weapon Range Mult (max)\"},{\"t\":5,\"p\":1,\"n\":\"Max Targeting FOV\"},{\"t\":5,\"p\":1,\"n\":\"Combat Radius\"},{\"t\":5,\"p\":1,\"n\":\"Semi-Auto Firing Delay Mult (min)\"},{\"t\":5,\"p\":1,\"n\":\"Semi-Auto Firing Delay Mult (max)\"}]}]},{\"t\":1,\"p\":1,\"n\":\"DEBR - Debris\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Models\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"DATA - Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Percentage\"},{\"t\":2,\"p\":1,\"n\":\"Model Filename\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"}]},{\"t\":11,\"p\":1,\"n\":\"MODT - Texture Files Hashes\"}]}]}]},{\"t\":1,\"p\":1,\"n\":\"DEHY - Dehydration Stage\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DATA - \",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Trigger Threshold\"},{\"t\":3,\"p\":1,\"n\":\"Actor Effect\"}]}]},{\"t\":1,\"p\":1,\"n\":\"DIAL - Dialog Topic\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":10,\"p\":1,\"n\":\"Added Quests\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Added Quest\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"QSTI - Quest\"},{\"t\":8,\"p\":1,\"n\":\"Shared Infos\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Shared Info\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"INFC - Info Connection\"},{\"t\":3,\"p\":1,\"n\":\"INFX - Info Index\"}]}]}]}]},{\"t\":10,\"p\":1,\"n\":\"Removed Quests\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Removed Quest\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"QSTR - Quest\"}]}]},{\"t\":8,\"n\":\"Unused\",\"c\":[{\"t\":6,\"n\":\"Unused\",\"c\":[{\"t\":11,\"n\":\"INFC - Unknown\"},{\"t\":11,\"n\":\"INFX - Unknown\"}]}]},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":5,\"p\":1,\"n\":\"PNAM - Priority\"},{\"t\":2,\"p\":1,\"n\":\"TDUM - Dumb Response\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DATA - \",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"}]}]},{\"t\":1,\"p\":1,\"n\":\"DOOR - Door\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"X1\"},{\"t\":3,\"p\":1,\"n\":\"Y1\"},{\"t\":3,\"p\":1,\"n\":\"Z1\"},{\"t\":3,\"p\":1,\"n\":\"X2\"},{\"t\":3,\"p\":1,\"n\":\"Y2\"},{\"t\":3,\"p\":1,\"n\":\"Z2\"}]},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"},{\"t\":11,\"n\":\"MODB - Unknown\"},{\"t\":11,\"p\":1,\"n\":\"MODT - Texture Files Hashes\"},{\"t\":7,\"p\":1,\"n\":\"MODS - Alternate Textures\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"3D Name\"},{\"t\":3,\"p\":1,\"n\":\"New Texture\"},{\"t\":3,\"p\":1,\"n\":\"3D Index\"}]}]},{\"t\":3,\"p\":1,\"n\":\"MODD - FaceGen Model Flags\"}]},{\"t\":3,\"p\":1,\"n\":\"SCRI - Script\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Destructable\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"DEST - Header\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Health\"},{\"t\":3,\"p\":1,\"n\":\"Count\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":8,\"p\":1,\"n\":\"Stages\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Stage\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"DSTD - Destruction Stage Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Health %\"},{\"t\":3,\"p\":1,\"n\":\"Index\"},{\"t\":3,\"p\":1,\"n\":\"Damage Stage\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":3,\"p\":1,\"n\":\"Self Damage per Second\"},{\"t\":3,\"p\":1,\"n\":\"Explosion\"},{\"t\":3,\"p\":1,\"n\":\"Debris\"},{\"t\":3,\"p\":1,\"n\":\"Debris Count\"}]},{\"t\":6,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"DMDL - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"DMDT - Texture Files Hashes\"}]},{\"p\":1,\"n\":\"DSTF - End Marker\"}]}]}]},{\"t\":3,\"p\":1,\"n\":\"SNAM - Sound - Open\"},{\"t\":3,\"p\":1,\"n\":\"ANAM - Sound - Close\"},{\"t\":3,\"p\":1,\"n\":\"BNAM - Sound - Looping\"},{\"t\":3,\"p\":1,\"n\":\"FNAM - Flags\"}]},{\"t\":1,\"p\":1,\"n\":\"ECZN - Encounter Zone\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DATA - \",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Owner\"},{\"t\":3,\"p\":1,\"n\":\"Rank\"},{\"t\":3,\"p\":1,\"n\":\"Minimum Level\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"}]}]},{\"t\":1,\"p\":1,\"n\":\"EFSH - Effect Shader\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"p\":1,\"n\":\"ICON - Fill Texture\"},{\"t\":2,\"p\":1,\"n\":\"ICO2 - Particle Shader Texture\"},{\"t\":2,\"p\":1,\"n\":\"NAM7 - Holes Texture\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DATA - \",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Membrane Shader - Source Blend Mode\"},{\"t\":3,\"p\":1,\"n\":\"Membrane Shader - Blend Operation\"},{\"t\":3,\"p\":1,\"n\":\"Membrane Shader - Z Test Function\"},{\"t\":6,\"p\":1,\"n\":\"Fill\\/Texture Effect - Color\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":5,\"p\":1,\"n\":\"Fill\\/Texture Effect - Alpha Fade In Time\"},{\"t\":5,\"p\":1,\"n\":\"Fill\\/Texture Effect - Full Alpha Time\"},{\"t\":5,\"p\":1,\"n\":\"Fill\\/Texture Effect - Alpha Fade Out Time\"},{\"t\":5,\"p\":1,\"n\":\"Fill\\/Texture Effect - Presistent Alpha Ratio\"},{\"t\":5,\"p\":1,\"n\":\"Fill\\/Texture Effect - Alpha Pulse Amplitude\"},{\"t\":5,\"p\":1,\"n\":\"Fill\\/Texture Effect - Alpha Pulse Frequency\"},{\"t\":5,\"p\":1,\"n\":\"Fill\\/Texture Effect - Texture Animation Speed (U)\"},{\"t\":5,\"p\":1,\"n\":\"Fill\\/Texture Effect - Texture Animation Speed (V)\"},{\"t\":5,\"p\":1,\"n\":\"Edge Effect - Fall Off\"},{\"t\":6,\"p\":1,\"n\":\"Edge Effect - Color\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":5,\"p\":1,\"n\":\"Edge Effect - Alpha Fade In Time\"},{\"t\":5,\"p\":1,\"n\":\"Edge Effect - Full Alpha Time\"},{\"t\":5,\"p\":1,\"n\":\"Edge Effect - Alpha Fade Out Time\"},{\"t\":5,\"p\":1,\"n\":\"Edge Effect - Persistent Alpha Ratio\"},{\"t\":5,\"p\":1,\"n\":\"Edge Effect - Alpha Pulse Amplitude\"},{\"t\":5,\"p\":1,\"n\":\"Edge Effect - Alpha Pusle Frequence\"},{\"t\":5,\"p\":1,\"n\":\"Fill\\/Texture Effect - Full Alpha Ratio\"},{\"t\":5,\"p\":1,\"n\":\"Edge Effect - Full Alpha Ratio\"},{\"t\":3,\"p\":1,\"n\":\"Membrane Shader - Dest Blend Mode\"},{\"t\":3,\"p\":1,\"n\":\"Particle Shader - Source Blend Mode\"},{\"t\":3,\"p\":1,\"n\":\"Particle Shader - Blend Operation\"},{\"t\":3,\"p\":1,\"n\":\"Particle Shader - Z Test Function\"},{\"t\":3,\"p\":1,\"n\":\"Particle Shader - Dest Blend Mode\"},{\"t\":5,\"p\":1,\"n\":\"Particle Shader - Particle Birth Ramp Up Time\"},{\"t\":5,\"p\":1,\"n\":\"Particle Shader - Full Particle Birth Time\"},{\"t\":5,\"p\":1,\"n\":\"Particle Shader - Particle Birth Ramp Down Time\"},{\"t\":5,\"p\":1,\"n\":\"Particle Shader - Full Particle Birth Ratio\"},{\"t\":5,\"p\":1,\"n\":\"Particle Shader - Persistant Particle Birth Ratio\"},{\"t\":5,\"p\":1,\"n\":\"Particle Shader - Particle Lifetime\"},{\"t\":5,\"p\":1,\"n\":\"Particle Shader - Particle Lifetime +\\/-\"},{\"t\":5,\"p\":1,\"n\":\"Particle Shader - Initial Speed Along Normal\"},{\"t\":5,\"p\":1,\"n\":\"Particle Shader - Acceleration Along Normal\"},{\"t\":5,\"p\":1,\"n\":\"Particle Shader - Initial Velocity #1\"},{\"t\":5,\"p\":1,\"n\":\"Particle Shader - Initial Velocity #2\"},{\"t\":5,\"p\":1,\"n\":\"Particle Shader - Initial Velocity #3\"},{\"t\":5,\"p\":1,\"n\":\"Particle Shader - Acceleration #1\"},{\"t\":5,\"p\":1,\"n\":\"Particle Shader - Acceleration #2\"},{\"t\":5,\"p\":1,\"n\":\"Particle Shader - Acceleration #3\"},{\"t\":5,\"p\":1,\"n\":\"Particle Shader - Scale Key 1\"},{\"t\":5,\"p\":1,\"n\":\"Particle Shader - Scale Key 2\"},{\"t\":5,\"p\":1,\"n\":\"Particle Shader - Scale Key 1 Time\"},{\"t\":5,\"p\":1,\"n\":\"Particle Shader - Scale Key 2 Time\"},{\"t\":6,\"p\":1,\"n\":\"Color Key 1 - Color\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Color Key 2 - Color\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Color Key 3 - Color\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":5,\"p\":1,\"n\":\"Color Key 1 - Color Alpha\"},{\"t\":5,\"p\":1,\"n\":\"Color Key 2 - Color Alpha\"},{\"t\":5,\"p\":1,\"n\":\"Color Key 3 - Color Alpha\"},{\"t\":5,\"p\":1,\"n\":\"Color Key 1 - Color Key Time\"},{\"t\":5,\"p\":1,\"n\":\"Color Key 2 - Color Key Time\"},{\"t\":5,\"p\":1,\"n\":\"Color Key 3 - Color Key Time\"},{\"t\":5,\"p\":1,\"n\":\"Particle Shader - Initial Speed Along Normal +\\/-\"},{\"t\":5,\"p\":1,\"n\":\"Particle Shader - Initial Rotation (deg)\"},{\"t\":5,\"p\":1,\"n\":\"Particle Shader - Initial Rotation (deg) +\\/-\"},{\"t\":5,\"p\":1,\"n\":\"Particle Shader - Rotation Speed (deg\\/sec)\"},{\"t\":5,\"p\":1,\"n\":\"Particle Shader - Rotation Speed (deg\\/sec) +\\/-\"},{\"t\":3,\"p\":1,\"n\":\"Addon Models\"},{\"t\":5,\"p\":1,\"n\":\"Holes - Start Time\"},{\"t\":5,\"p\":1,\"n\":\"Holes - End Time\"},{\"t\":5,\"p\":1,\"n\":\"Holes - Start Val\"},{\"t\":5,\"p\":1,\"n\":\"Holes - End Val\"},{\"t\":5,\"p\":1,\"n\":\"Edge Width (alpha units)\"},{\"t\":6,\"p\":1,\"n\":\"Edge Color\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":5,\"p\":1,\"n\":\"Explosion Wind Speed\"},{\"t\":3,\"p\":1,\"n\":\"Texture Count U\"},{\"t\":3,\"p\":1,\"n\":\"Texture Count V\"},{\"t\":5,\"p\":1,\"n\":\"Addon Models - Fade In Time\"},{\"t\":5,\"p\":1,\"n\":\"Addon Models - Fade Out Time\"},{\"t\":5,\"p\":1,\"n\":\"Addon Models - Scale Start\"},{\"t\":5,\"p\":1,\"n\":\"Addon Models - Scale End\"},{\"t\":5,\"p\":1,\"n\":\"Addon Models - Scale In Time\"},{\"t\":5,\"p\":1,\"n\":\"Addon Models - Scale Out Time\"}]}]},{\"t\":1,\"p\":1,\"n\":\"ENCH - Object Effect\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"ENIT - Effect Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"}]},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Effects\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Effect\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"EFID - Base Effect\"},{\"t\":6,\"p\":1,\"n\":\"EFIT - \",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Magnitude\"},{\"t\":3,\"p\":1,\"n\":\"Area\"},{\"t\":3,\"p\":1,\"n\":\"Duration\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Actor Value\"}]},{\"t\":8,\"p\":1,\"n\":\"Conditions\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"CTDA - Condition\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":5,\"p\":1,\"n\":\"Comparison Value - Float\"},{\"t\":3,\"p\":1,\"n\":\"Comparison Value - Global\"},{\"t\":3,\"p\":1,\"n\":\"Function\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":11,\"p\":1,\"n\":\"None\"},{\"t\":3,\"p\":1,\"n\":\"Integer\"},{\"t\":3,\"p\":1,\"n\":\"Variable Name (INVALID)\"},{\"t\":3,\"p\":1,\"n\":\"Sex\"},{\"t\":3,\"p\":1,\"n\":\"Actor Value\"},{\"t\":3,\"p\":1,\"n\":\"Crime Type\"},{\"t\":3,\"p\":1,\"n\":\"Axis\"},{\"t\":3,\"p\":1,\"n\":\"Quest Stage (INVALID)\"},{\"t\":3,\"p\":1,\"n\":\"Misc Stat\"},{\"t\":3,\"p\":1,\"n\":\"Alignment\"},{\"t\":3,\"p\":1,\"n\":\"Equip Type\"},{\"t\":3,\"p\":1,\"n\":\"Form Type\"},{\"t\":3,\"p\":1,\"n\":\"Critical Stage\"},{\"t\":3,\"p\":1,\"n\":\"Object Reference\"},{\"t\":3,\"p\":1,\"n\":\"Inventory Object\"},{\"t\":3,\"p\":1,\"n\":\"Actor\"},{\"t\":3,\"p\":1,\"n\":\"Voice Type\"},{\"t\":3,\"p\":1,\"n\":\"Idle\"},{\"t\":3,\"p\":1,\"n\":\"Form List\"},{\"t\":3,\"p\":1,\"n\":\"Note\"},{\"t\":3,\"p\":1,\"n\":\"Quest\"},{\"t\":3,\"p\":1,\"n\":\"Faction\"},{\"t\":3,\"p\":1,\"n\":\"Weapon\"},{\"t\":3,\"p\":1,\"n\":\"Cell\"},{\"t\":3,\"p\":1,\"n\":\"Class\"},{\"t\":3,\"p\":1,\"n\":\"Race\"},{\"t\":3,\"p\":1,\"n\":\"Actor Base\"},{\"t\":3,\"p\":1,\"n\":\"Global\"},{\"t\":3,\"p\":1,\"n\":\"Weather\"},{\"t\":3,\"p\":1,\"n\":\"Package\"},{\"t\":3,\"p\":1,\"n\":\"Encounter Zone\"},{\"t\":3,\"p\":1,\"n\":\"Perk\"},{\"t\":3,\"p\":1,\"n\":\"Owner\"},{\"t\":3,\"p\":1,\"n\":\"Furniture\"},{\"t\":3,\"p\":1,\"n\":\"Effect Item\"},{\"t\":3,\"p\":1,\"n\":\"Base Effect\"},{\"t\":3,\"p\":1,\"n\":\"Worldspace\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Function\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Param (INVALID)\"},{\"t\":3,\"p\":1,\"n\":\"Creature Type\"},{\"t\":3,\"p\":1,\"n\":\"Menu Mode\"},{\"t\":3,\"p\":1,\"n\":\"Player Action\"},{\"t\":3,\"p\":1,\"n\":\"Body Location\"},{\"t\":3,\"p\":1,\"n\":\"Referenceable Object\"},{\"t\":3,\"p\":1,\"n\":\"Quest Objective (INVALID)\"},{\"t\":3,\"p\":1,\"n\":\"Reputation\"},{\"t\":3,\"p\":1,\"n\":\"Region\"},{\"t\":3,\"p\":1,\"n\":\"Challenge\"},{\"t\":3,\"p\":1,\"n\":\"Casino\"},{\"t\":3,\"p\":1,\"n\":\"Form\"},{\"t\":3,\"p\":1,\"n\":\"Variable Name\"},{\"t\":3,\"p\":1,\"n\":\"Quest Stage\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Function (INVALID)\"},{\"t\":3,\"p\":1,\"n\":\"Weapon List\"},{\"t\":3,\"p\":1,\"n\":\"Target\"},{\"t\":3,\"p\":1,\"n\":\"Target List\"},{\"t\":3,\"p\":1,\"n\":\"Target Part\"},{\"t\":3,\"p\":1,\"n\":\"VATS Action\"},{\"t\":3,\"p\":1,\"n\":\"Critical Effect\"},{\"t\":3,\"p\":1,\"n\":\"Critical Effect List\"},{\"t\":3,\"p\":1,\"n\":\"Weapon Type\"},{\"t\":3,\"p\":1,\"n\":\"Quest Objective\"},{\"t\":3,\"p\":1,\"n\":\"Run On\"},{\"t\":3,\"p\":1,\"n\":\"Reference\"}]}]}]}]}]},{\"t\":1,\"p\":1,\"n\":\"EXPL - Explosion\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"X1\"},{\"t\":3,\"p\":1,\"n\":\"Y1\"},{\"t\":3,\"p\":1,\"n\":\"Z1\"},{\"t\":3,\"p\":1,\"n\":\"X2\"},{\"t\":3,\"p\":1,\"n\":\"Y2\"},{\"t\":3,\"p\":1,\"n\":\"Z2\"}]},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"},{\"t\":11,\"n\":\"MODB - Unknown\"},{\"t\":11,\"p\":1,\"n\":\"MODT - Texture Files Hashes\"},{\"t\":7,\"p\":1,\"n\":\"MODS - Alternate Textures\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"3D Name\"},{\"t\":3,\"p\":1,\"n\":\"New Texture\"},{\"t\":3,\"p\":1,\"n\":\"3D Index\"}]}]},{\"t\":3,\"p\":1,\"n\":\"MODD - FaceGen Model Flags\"}]},{\"t\":3,\"p\":1,\"n\":\"EITM - Object Effect\"},{\"t\":3,\"p\":1,\"n\":\"MNAM - Image Space Modifier\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DATA - Data\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Force\"},{\"t\":5,\"p\":1,\"n\":\"Damage\"},{\"t\":5,\"p\":1,\"n\":\"Radius\"},{\"t\":3,\"p\":1,\"n\":\"Light\"},{\"t\":3,\"p\":1,\"n\":\"Sound 1\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":5,\"p\":1,\"n\":\"IS Radius\"},{\"t\":3,\"p\":1,\"n\":\"Impact DataSet\"},{\"t\":3,\"p\":1,\"n\":\"Sound 2\"},{\"t\":6,\"p\":1,\"n\":\"Radiation\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Level\"},{\"t\":5,\"p\":1,\"n\":\"Dissipation Time\"},{\"t\":5,\"p\":1,\"n\":\"Radius\"}]},{\"t\":3,\"p\":1,\"n\":\"Sound Level\"}]},{\"t\":3,\"p\":1,\"n\":\"INAM - Placed Impact Object\"}]},{\"t\":1,\"p\":1,\"n\":\"EYES - Eyes\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":2,\"p\":1,\"n\":\"ICON - Texture\"},{\"t\":3,\"p\":1,\"n\":\"DATA - Flags\"}]},{\"t\":1,\"p\":1,\"n\":\"FACT - Faction\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Relations\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"XNAM - Relation\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Faction\"},{\"t\":3,\"p\":1,\"n\":\"Modifier\"},{\"t\":3,\"p\":1,\"n\":\"Group Combat Reaction\"}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DATA - \",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Flags 1\"},{\"t\":3,\"p\":1,\"n\":\"Flags 2\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":5,\"n\":\"CNAM - Unused\"},{\"t\":10,\"p\":1,\"n\":\"Ranks\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Rank\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"RNAM - Rank#\"},{\"t\":2,\"p\":1,\"n\":\"MNAM - Male\"},{\"t\":2,\"p\":1,\"n\":\"FNAM - Female\"},{\"t\":2,\"n\":\"INAM - Insignia (Unused)\"}]}]},{\"t\":3,\"p\":1,\"n\":\"WMI1 - Reputation\"}]},{\"t\":1,\"p\":1,\"n\":\"FLST - FormID List\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"FormIDs\",\"d\":1,\"c\":[{\"t\":3,\"p\":1,\"n\":\"LNAM - FormID\"}]}]},{\"t\":1,\"p\":1,\"n\":\"FURN - Furniture\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"X1\"},{\"t\":3,\"p\":1,\"n\":\"Y1\"},{\"t\":3,\"p\":1,\"n\":\"Z1\"},{\"t\":3,\"p\":1,\"n\":\"X2\"},{\"t\":3,\"p\":1,\"n\":\"Y2\"},{\"t\":3,\"p\":1,\"n\":\"Z2\"}]},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"},{\"t\":11,\"n\":\"MODB - Unknown\"},{\"t\":11,\"p\":1,\"n\":\"MODT - Texture Files Hashes\"},{\"t\":7,\"p\":1,\"n\":\"MODS - Alternate Textures\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"3D Name\"},{\"t\":3,\"p\":1,\"n\":\"New Texture\"},{\"t\":3,\"p\":1,\"n\":\"3D Index\"}]}]},{\"t\":3,\"p\":1,\"n\":\"MODD - FaceGen Model Flags\"}]},{\"t\":3,\"p\":1,\"n\":\"SCRI - Script\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Destructable\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"DEST - Header\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Health\"},{\"t\":3,\"p\":1,\"n\":\"Count\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":8,\"p\":1,\"n\":\"Stages\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Stage\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"DSTD - Destruction Stage Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Health %\"},{\"t\":3,\"p\":1,\"n\":\"Index\"},{\"t\":3,\"p\":1,\"n\":\"Damage Stage\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":3,\"p\":1,\"n\":\"Self Damage per Second\"},{\"t\":3,\"p\":1,\"n\":\"Explosion\"},{\"t\":3,\"p\":1,\"n\":\"Debris\"},{\"t\":3,\"p\":1,\"n\":\"Debris Count\"}]},{\"t\":6,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"DMDL - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"DMDT - Texture Files Hashes\"}]},{\"p\":1,\"n\":\"DSTF - End Marker\"}]}]}]},{\"t\":11,\"n\":\"MNAM - Marker Flags\"}]},{\"t\":1,\"p\":1,\"n\":\"GLOB - Global\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":3,\"p\":1,\"n\":\"FNAM - Type\"},{\"t\":5,\"p\":1,\"n\":\"FLTV - Value\"}]},{\"t\":1,\"p\":1,\"n\":\"GMST - Game Setting\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"p\":1,\"n\":\"\"}]},{\"t\":1,\"p\":1,\"n\":\"GRAS - Grass\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"X1\"},{\"t\":3,\"p\":1,\"n\":\"Y1\"},{\"t\":3,\"p\":1,\"n\":\"Z1\"},{\"t\":3,\"p\":1,\"n\":\"X2\"},{\"t\":3,\"p\":1,\"n\":\"Y2\"},{\"t\":3,\"p\":1,\"n\":\"Z2\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"},{\"t\":11,\"n\":\"MODB - Unknown\"},{\"t\":11,\"p\":1,\"n\":\"MODT - Texture Files Hashes\"},{\"t\":7,\"p\":1,\"n\":\"MODS - Alternate Textures\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"3D Name\"},{\"t\":3,\"p\":1,\"n\":\"New Texture\"},{\"t\":3,\"p\":1,\"n\":\"3D Index\"}]}]},{\"t\":3,\"p\":1,\"n\":\"MODD - FaceGen Model Flags\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DATA - \",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Density\"},{\"t\":3,\"p\":1,\"n\":\"Min Slope\"},{\"t\":3,\"p\":1,\"n\":\"Max Slope\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Unit from water amount\"},{\"t\":3,\"p\":1,\"n\":\"Unit from water type\"},{\"t\":5,\"p\":1,\"n\":\"Position Range\"},{\"t\":5,\"p\":1,\"n\":\"Height Range\"},{\"t\":5,\"p\":1,\"n\":\"Color Range\"},{\"t\":5,\"p\":1,\"n\":\"Wave Period\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"}]}]},{\"t\":1,\"p\":1,\"n\":\"HAIR - Hair\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"},{\"t\":11,\"n\":\"MODB - Unknown\"},{\"t\":11,\"p\":1,\"n\":\"MODT - Texture Files Hashes\"},{\"t\":7,\"p\":1,\"n\":\"MODS - Alternate Textures\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"3D Name\"},{\"t\":3,\"p\":1,\"n\":\"New Texture\"},{\"t\":3,\"p\":1,\"n\":\"3D Index\"}]}]},{\"t\":3,\"p\":1,\"n\":\"MODD - FaceGen Model Flags\"}]},{\"t\":2,\"p\":1,\"n\":\"ICON - Texture\"},{\"t\":3,\"p\":1,\"n\":\"DATA - Flags\"}]},{\"t\":1,\"p\":1,\"n\":\"HDPT - Head Part\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"},{\"t\":11,\"n\":\"MODB - Unknown\"},{\"t\":11,\"p\":1,\"n\":\"MODT - Texture Files Hashes\"},{\"t\":7,\"p\":1,\"n\":\"MODS - Alternate Textures\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"3D Name\"},{\"t\":3,\"p\":1,\"n\":\"New Texture\"},{\"t\":3,\"p\":1,\"n\":\"3D Index\"}]}]},{\"t\":3,\"p\":1,\"n\":\"MODD - FaceGen Model Flags\"}]},{\"t\":3,\"p\":1,\"n\":\"DATA - Flags\"},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Extra Parts\",\"d\":1,\"c\":[{\"t\":3,\"p\":1,\"n\":\"HNAM - Part\"}]}]},{\"t\":1,\"p\":1,\"n\":\"HUNG - Hunger Stage\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DATA - \",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Trigger Threshold\"},{\"t\":3,\"p\":1,\"n\":\"Actor Effect\"}]}]},{\"t\":1,\"p\":1,\"n\":\"IDLM - Idle Marker\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"X1\"},{\"t\":3,\"p\":1,\"n\":\"Y1\"},{\"t\":3,\"p\":1,\"n\":\"Z1\"},{\"t\":3,\"p\":1,\"n\":\"X2\"},{\"t\":3,\"p\":1,\"n\":\"Y2\"},{\"t\":3,\"p\":1,\"n\":\"Z2\"}]},{\"t\":3,\"p\":1,\"n\":\"IDLF - Flags\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"IDLC - \",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Animation Count\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":5,\"p\":1,\"n\":\"IDLT - Idle Timer Setting\"},{\"t\":7,\"p\":1,\"n\":\"IDLA - Animations\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Animation\"}]}]},{\"t\":1,\"p\":1,\"n\":\"IMAD - Image Space Adapter\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DNAM - Data Count\",\"c\":[{\"t\":3,\"n\":\"Flags\"},{\"t\":5,\"n\":\"Duration\"},{\"t\":6,\"n\":\"HDR\",\"c\":[{\"t\":3,\"n\":\"Eye Adapt Speed Mult\"},{\"t\":3,\"n\":\"Eye Adapt Speed Add\"},{\"t\":3,\"n\":\"Bloom Blur Radius Mult\"},{\"t\":3,\"n\":\"Bloom Blur Radius Add\"},{\"t\":3,\"n\":\"Bloom Threshold Mult\"},{\"t\":3,\"n\":\"Bloom Threshold Add\"},{\"t\":3,\"n\":\"Bloom Scale Mult\"},{\"t\":3,\"n\":\"Bloom Scale Add\"},{\"t\":3,\"n\":\"Target Lum Min Mult\"},{\"t\":3,\"n\":\"Target Lum Min Add\"},{\"t\":3,\"n\":\"Target Lum Max Mult\"},{\"t\":3,\"n\":\"Target Lum Max Add\"},{\"t\":3,\"n\":\"Sunlight Scale Mult\"},{\"t\":3,\"n\":\"Sunlight Scale Add\"},{\"t\":3,\"n\":\"Sky Scale Mult\"},{\"t\":3,\"n\":\"Sky Scale Add\"}]},{\"t\":3,\"n\":\"Unknown08 Mult\"},{\"t\":3,\"n\":\"Unknown48 Add\"},{\"t\":3,\"n\":\"Unknown09 Mult\"},{\"t\":3,\"n\":\"Unknown49 Add\"},{\"t\":3,\"n\":\"Unknown0A Mult\"},{\"t\":3,\"n\":\"Unknown4A Add\"},{\"t\":3,\"n\":\"Unknown0B Mult\"},{\"t\":3,\"n\":\"Unknown4B Add\"},{\"t\":3,\"n\":\"Unknown0C Mult\"},{\"t\":3,\"n\":\"Unknown4C Add\"},{\"t\":3,\"n\":\"Unknown0D Mult\"},{\"t\":3,\"n\":\"Unknown4D Add\"},{\"t\":3,\"n\":\"Unknown0E Mult\"},{\"t\":3,\"n\":\"Unknown4E Add\"},{\"t\":3,\"n\":\"Unknown0F Mult\"},{\"t\":3,\"n\":\"Unknown4F Add\"},{\"t\":3,\"n\":\"Unknown10 Mult\"},{\"t\":3,\"n\":\"Unknown50 Add\"},{\"t\":6,\"n\":\"Cinematic\",\"c\":[{\"t\":3,\"n\":\"Saturation Mult\"},{\"t\":3,\"n\":\"Saturation Add\"},{\"t\":3,\"n\":\"Brightness Mult\"},{\"t\":3,\"n\":\"Brightness Add\"},{\"t\":3,\"n\":\"Contrast Mult\"},{\"t\":3,\"n\":\"Contrast Add\"}]},{\"t\":3,\"n\":\"Unknown14 Mult\"},{\"t\":3,\"n\":\"Unknown54 Add\"},{\"t\":3,\"n\":\"Tint Color\"},{\"t\":3,\"n\":\"Blur Radius\"},{\"t\":3,\"n\":\"Double Vision Strength\"},{\"t\":3,\"n\":\"Radial Blur Strength\"},{\"t\":3,\"n\":\"Radial Blur Ramp Up\"},{\"t\":3,\"n\":\"Radial Blur Start\"},{\"t\":3,\"n\":\"Radial Blur Flags\"},{\"t\":5,\"n\":\"Radial Blur Center X\"},{\"t\":5,\"n\":\"Radial Blur Center Y\"},{\"t\":3,\"n\":\"DoF Strength\"},{\"t\":3,\"n\":\"DoF Distance\"},{\"t\":3,\"n\":\"DoF Range\"},{\"t\":3,\"n\":\"DoF Flags\"},{\"t\":3,\"n\":\"Radial Blur Ramp Down\"},{\"t\":3,\"n\":\"Radial Blur Down Start\"},{\"t\":3,\"n\":\"Fade Color\"},{\"t\":3,\"n\":\"Motion Blur Strength\"}]},{\"t\":7,\"p\":1,\"n\":\"BNAM - Blur Radius\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Data\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Time\"},{\"t\":5,\"p\":1,\"n\":\"Value\"}]}]},{\"t\":7,\"p\":1,\"n\":\"VNAM - Double Vision Strength\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Data\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Time\"},{\"t\":5,\"p\":1,\"n\":\"Value\"}]}]},{\"t\":7,\"p\":1,\"n\":\"TNAM - Tint Color\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Data\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Time\"},{\"t\":5,\"p\":1,\"n\":\"Red\"},{\"t\":5,\"p\":1,\"n\":\"Green\"},{\"t\":5,\"p\":1,\"n\":\"Blue\"},{\"t\":5,\"p\":1,\"n\":\"Alpha\"}]}]},{\"t\":7,\"p\":1,\"n\":\"NAM3 - Fade Color\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Data\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Time\"},{\"t\":5,\"p\":1,\"n\":\"Red\"},{\"t\":5,\"p\":1,\"n\":\"Green\"},{\"t\":5,\"p\":1,\"n\":\"Blue\"},{\"t\":5,\"p\":1,\"n\":\"Alpha\"}]}]},{\"t\":7,\"p\":1,\"n\":\"RNAM - Radial Blur Strength\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Data\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Time\"},{\"t\":5,\"p\":1,\"n\":\"Value\"}]}]},{\"t\":7,\"p\":1,\"n\":\"SNAM - Radial Blur Ramp Up\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Data\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Time\"},{\"t\":5,\"p\":1,\"n\":\"Value\"}]}]},{\"t\":7,\"p\":1,\"n\":\"UNAM - Radial Blur Start\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Data\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Time\"},{\"t\":5,\"p\":1,\"n\":\"Value\"}]}]},{\"t\":7,\"p\":1,\"n\":\"NAM1 - Radial Blur Ramp Down\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Data\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Time\"},{\"t\":5,\"p\":1,\"n\":\"Value\"}]}]},{\"t\":7,\"p\":1,\"n\":\"NAM2 - Radial Blur Down Start\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Data\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Time\"},{\"t\":5,\"p\":1,\"n\":\"Value\"}]}]},{\"t\":7,\"p\":1,\"n\":\"WNAM - DoF Strength\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Data\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Time\"},{\"t\":5,\"p\":1,\"n\":\"Value\"}]}]},{\"t\":7,\"p\":1,\"n\":\"XNAM - DoF Distance\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Data\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Time\"},{\"t\":5,\"p\":1,\"n\":\"Value\"}]}]},{\"t\":7,\"p\":1,\"n\":\"YNAM - DoF Range\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Data\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Time\"},{\"t\":5,\"p\":1,\"n\":\"Value\"}]}]},{\"t\":7,\"p\":1,\"n\":\"NAM4 - Motion Blur Strength\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Data\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Time\"},{\"t\":5,\"p\":1,\"n\":\"Value\"}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"HDR\",\"c\":[{\"t\":7,\"p\":1,\"n\":\"aIAD - Eye Adapt Speed Mult\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Data\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Time\"},{\"t\":5,\"p\":1,\"n\":\"Value\"}]}]},{\"t\":7,\"p\":1,\"n\":\"@IAD - Eye Adapt Speed Add\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Data\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Time\"},{\"t\":5,\"p\":1,\"n\":\"Value\"}]}]},{\"t\":7,\"p\":1,\"n\":\"bIAD - Bloom Blur Radius Mult\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Data\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Time\"},{\"t\":5,\"p\":1,\"n\":\"Value\"}]}]},{\"t\":7,\"p\":1,\"n\":\"AIAD - Bloom Blur Radius Add\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Data\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Time\"},{\"t\":5,\"p\":1,\"n\":\"Value\"}]}]},{\"t\":7,\"p\":1,\"n\":\"cIAD - Bloom Threshold Mult\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Data\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Time\"},{\"t\":5,\"p\":1,\"n\":\"Value\"}]}]},{\"t\":7,\"p\":1,\"n\":\"BIAD - Bloom Threshold Add\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Data\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Time\"},{\"t\":5,\"p\":1,\"n\":\"Value\"}]}]},{\"t\":7,\"p\":1,\"n\":\"dIAD - Bloom Scale Mult\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Data\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Time\"},{\"t\":5,\"p\":1,\"n\":\"Value\"}]}]},{\"t\":7,\"p\":1,\"n\":\"CIAD - Bloom Scale Add\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Data\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Time\"},{\"t\":5,\"p\":1,\"n\":\"Value\"}]}]},{\"t\":7,\"p\":1,\"n\":\"eIAD - Target Lum Min Mult\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Data\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Time\"},{\"t\":5,\"p\":1,\"n\":\"Value\"}]}]},{\"t\":7,\"p\":1,\"n\":\"DIAD - Target Lum Min Add\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Data\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Time\"},{\"t\":5,\"p\":1,\"n\":\"Value\"}]}]},{\"t\":7,\"p\":1,\"n\":\"fIAD - Target Lum Max Mult\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Data\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Time\"},{\"t\":5,\"p\":1,\"n\":\"Value\"}]}]},{\"t\":7,\"p\":1,\"n\":\"EIAD - Target Lum Max Add\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Data\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Time\"},{\"t\":5,\"p\":1,\"n\":\"Value\"}]}]},{\"t\":7,\"p\":1,\"n\":\"gIAD - Sunlight Scale Mult\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Data\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Time\"},{\"t\":5,\"p\":1,\"n\":\"Value\"}]}]},{\"t\":7,\"p\":1,\"n\":\"FIAD - Sunlight Scale Add\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Data\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Time\"},{\"t\":5,\"p\":1,\"n\":\"Value\"}]}]},{\"t\":7,\"p\":1,\"n\":\"hIAD - Sky Scale Mult\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Data\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Time\"},{\"t\":5,\"p\":1,\"n\":\"Value\"}]}]},{\"t\":7,\"p\":1,\"n\":\"GIAD - Sky Scale Add\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Data\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Time\"},{\"t\":5,\"p\":1,\"n\":\"Value\"}]}]}]},{\"t\":11,\"n\":\"iIAD - Unknown\"},{\"t\":11,\"n\":\"HIAD - Unknown\"},{\"t\":11,\"n\":\"jIAD - Unknown\"},{\"t\":11,\"n\":\"IIAD - Unknown\"},{\"t\":11,\"n\":\"kIAD - Unknown\"},{\"t\":11,\"n\":\"JIAD - Unknown\"},{\"t\":11,\"n\":\"lIAD - Unknown\"},{\"t\":11,\"n\":\"KIAD - Unknown\"},{\"t\":11,\"n\":\"mIAD - Unknown\"},{\"t\":11,\"n\":\"LIAD - Unknown\"},{\"t\":11,\"n\":\"nIAD - Unknown\"},{\"t\":11,\"n\":\"MIAD - Unknown\"},{\"t\":11,\"n\":\"oIAD - Unknown\"},{\"t\":11,\"n\":\"NIAD - Unknown\"},{\"t\":11,\"n\":\"pIAD - Unknown\"},{\"t\":11,\"n\":\"OIAD - Unknown\"},{\"t\":11,\"n\":\"qIAD - Unknown\"},{\"t\":11,\"n\":\"PIAD - Unknown\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Cinematic\",\"c\":[{\"t\":7,\"p\":1,\"n\":\"rIAD - Saturation Mult\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Data\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Time\"},{\"t\":5,\"p\":1,\"n\":\"Value\"}]}]},{\"t\":7,\"p\":1,\"n\":\"QIAD - Saturation Add\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Data\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Time\"},{\"t\":5,\"p\":1,\"n\":\"Value\"}]}]},{\"t\":7,\"p\":1,\"n\":\"sIAD - Brightness Mult\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Data\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Time\"},{\"t\":5,\"p\":1,\"n\":\"Value\"}]}]},{\"t\":7,\"p\":1,\"n\":\"RIAD - Brightness Add\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Data\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Time\"},{\"t\":5,\"p\":1,\"n\":\"Value\"}]}]},{\"t\":7,\"p\":1,\"n\":\"tIAD - Contrast Mult\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Data\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Time\"},{\"t\":5,\"p\":1,\"n\":\"Value\"}]}]},{\"t\":7,\"p\":1,\"n\":\"SIAD - Contrast Add\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Data\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Time\"},{\"t\":5,\"p\":1,\"n\":\"Value\"}]}]}]},{\"t\":11,\"n\":\"uIAD - Unknown\"},{\"t\":11,\"n\":\"TIAD - Unknown\"},{\"t\":3,\"p\":1,\"n\":\"RDSD - Sound - Intro\"},{\"t\":3,\"p\":1,\"n\":\"RDSI - Sound - Outro\"}]},{\"t\":1,\"p\":1,\"n\":\"IMGS - Image Space\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DNAM - \",\"c\":[{\"t\":6,\"p\":1,\"n\":\"HDR\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Eye Adapt Speed\"},{\"t\":5,\"p\":1,\"n\":\"Blur Radius\"},{\"t\":5,\"p\":1,\"n\":\"Blur Passes\"},{\"t\":5,\"p\":1,\"n\":\"Emissive Mult\"},{\"t\":5,\"p\":1,\"n\":\"Target LUM\"},{\"t\":5,\"p\":1,\"n\":\"Upper LUM Clamp\"},{\"t\":5,\"p\":1,\"n\":\"Bright Scale\"},{\"t\":5,\"p\":1,\"n\":\"Bright Clamp\"},{\"t\":5,\"p\":1,\"n\":\"LUM Ramp No Tex\"},{\"t\":5,\"p\":1,\"n\":\"LUM Ramp Min\"},{\"t\":5,\"p\":1,\"n\":\"LUM Ramp Max\"},{\"t\":5,\"p\":1,\"n\":\"Sunlight Dimmer\"},{\"t\":5,\"p\":1,\"n\":\"Grass Dimmer\"},{\"t\":5,\"p\":1,\"n\":\"Tree Dimmer\"},{\"t\":5,\"p\":1,\"n\":\"Skin Dimmer\"}]},{\"t\":6,\"p\":1,\"n\":\"Bloom\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Blur Radius\"},{\"t\":5,\"p\":1,\"n\":\"Alpha Mult Interior\"},{\"t\":5,\"p\":1,\"n\":\"Alpha Mult Exterior\"}]},{\"t\":6,\"p\":1,\"n\":\"Get Hit\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Blur Radius\"},{\"t\":5,\"p\":1,\"n\":\"Blur Damping Constant\"},{\"t\":5,\"p\":1,\"n\":\"Damping Constant\"}]},{\"t\":6,\"p\":1,\"n\":\"Night Eye\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Tint Color\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Red\"},{\"t\":5,\"p\":1,\"n\":\"Green\"},{\"t\":5,\"p\":1,\"n\":\"Blue\"}]},{\"t\":5,\"p\":1,\"n\":\"Brightness\"}]},{\"t\":6,\"p\":1,\"n\":\"Cinematic\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Saturation\"},{\"t\":6,\"p\":1,\"n\":\"Contrast\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Avg Lum Value\"},{\"t\":5,\"p\":1,\"n\":\"Value\"}]},{\"t\":5,\"p\":1,\"n\":\"Cinematic - Brightness - Value\"},{\"t\":6,\"p\":1,\"n\":\"Tint\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Color\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Red\"},{\"t\":5,\"p\":1,\"n\":\"Green\"},{\"t\":5,\"p\":1,\"n\":\"Blue\"}]},{\"t\":5,\"p\":1,\"n\":\"Value\"}]}]},{\"t\":11,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"}]}]},{\"t\":1,\"p\":1,\"n\":\"IMOD - Item Mod\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"X1\"},{\"t\":3,\"p\":1,\"n\":\"Y1\"},{\"t\":3,\"p\":1,\"n\":\"Z1\"},{\"t\":3,\"p\":1,\"n\":\"X2\"},{\"t\":3,\"p\":1,\"n\":\"Y2\"},{\"t\":3,\"p\":1,\"n\":\"Z2\"}]},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"},{\"t\":11,\"n\":\"MODB - Unknown\"},{\"t\":11,\"p\":1,\"n\":\"MODT - Texture Files Hashes\"},{\"t\":7,\"p\":1,\"n\":\"MODS - Alternate Textures\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"3D Name\"},{\"t\":3,\"p\":1,\"n\":\"New Texture\"},{\"t\":3,\"p\":1,\"n\":\"3D Index\"}]}]},{\"t\":3,\"p\":1,\"n\":\"MODD - FaceGen Model Flags\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Icon\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"ICON - Large Icon filename\"},{\"t\":2,\"p\":1,\"n\":\"MICO - Small Icon filename\"}]},{\"t\":3,\"p\":1,\"n\":\"SCRI - Script\"},{\"t\":2,\"p\":1,\"n\":\"DESC - Description\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Destructable\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"DEST - Header\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Health\"},{\"t\":3,\"p\":1,\"n\":\"Count\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":8,\"p\":1,\"n\":\"Stages\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Stage\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"DSTD - Destruction Stage Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Health %\"},{\"t\":3,\"p\":1,\"n\":\"Index\"},{\"t\":3,\"p\":1,\"n\":\"Damage Stage\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":3,\"p\":1,\"n\":\"Self Damage per Second\"},{\"t\":3,\"p\":1,\"n\":\"Explosion\"},{\"t\":3,\"p\":1,\"n\":\"Debris\"},{\"t\":3,\"p\":1,\"n\":\"Debris Count\"}]},{\"t\":6,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"DMDL - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"DMDT - Texture Files Hashes\"}]},{\"p\":1,\"n\":\"DSTF - End Marker\"}]}]}]},{\"t\":3,\"p\":1,\"n\":\"YNAM - Sound - Pick Up\"},{\"t\":3,\"p\":1,\"n\":\"ZNAM - Sound - Drop\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DATA - Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Value\"},{\"t\":5,\"p\":1,\"n\":\"Weight\"}]}]},{\"t\":1,\"p\":1,\"n\":\"INFO - Dialog response\",\"d\":1,\"c\":[{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DATA - \",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Next Speaker\"},{\"t\":3,\"p\":1,\"n\":\"Flags 1\"},{\"t\":3,\"p\":1,\"n\":\"Flags 2\"}]},{\"t\":3,\"p\":1,\"n\":\"QSTI - Quest\"},{\"t\":3,\"p\":1,\"n\":\"TPIC - Topic\"},{\"t\":3,\"p\":1,\"n\":\"PNAM - Previous INFO\"},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Add Topics\",\"d\":1,\"c\":[{\"t\":3,\"p\":1,\"n\":\"NAME - Topic\"}]},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Responses\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Response\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"TRDT - Response Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Emotion Type\"},{\"t\":3,\"p\":1,\"n\":\"Emotion Value\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Response number\"},{\"t\":3,\"p\":1,\"n\":\"Sound\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"}]},{\"t\":2,\"p\":1,\"n\":\"NAM1 - Response Text\"},{\"t\":2,\"p\":1,\"n\":\"NAM2 - Script Notes\"},{\"t\":2,\"p\":1,\"n\":\"NAM3 - Edits\"},{\"t\":3,\"p\":1,\"n\":\"SNAM - Speaker Animation\"},{\"t\":3,\"p\":1,\"n\":\"LNAM - Listener Animation\"}]}]},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Conditions\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"CTDA - Condition\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":5,\"p\":1,\"n\":\"Comparison Value - Float\"},{\"t\":3,\"p\":1,\"n\":\"Comparison Value - Global\"},{\"t\":3,\"p\":1,\"n\":\"Function\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":11,\"p\":1,\"n\":\"None\"},{\"t\":3,\"p\":1,\"n\":\"Integer\"},{\"t\":3,\"p\":1,\"n\":\"Variable Name (INVALID)\"},{\"t\":3,\"p\":1,\"n\":\"Sex\"},{\"t\":3,\"p\":1,\"n\":\"Actor Value\"},{\"t\":3,\"p\":1,\"n\":\"Crime Type\"},{\"t\":3,\"p\":1,\"n\":\"Axis\"},{\"t\":3,\"p\":1,\"n\":\"Quest Stage (INVALID)\"},{\"t\":3,\"p\":1,\"n\":\"Misc Stat\"},{\"t\":3,\"p\":1,\"n\":\"Alignment\"},{\"t\":3,\"p\":1,\"n\":\"Equip Type\"},{\"t\":3,\"p\":1,\"n\":\"Form Type\"},{\"t\":3,\"p\":1,\"n\":\"Critical Stage\"},{\"t\":3,\"p\":1,\"n\":\"Object Reference\"},{\"t\":3,\"p\":1,\"n\":\"Inventory Object\"},{\"t\":3,\"p\":1,\"n\":\"Actor\"},{\"t\":3,\"p\":1,\"n\":\"Voice Type\"},{\"t\":3,\"p\":1,\"n\":\"Idle\"},{\"t\":3,\"p\":1,\"n\":\"Form List\"},{\"t\":3,\"p\":1,\"n\":\"Note\"},{\"t\":3,\"p\":1,\"n\":\"Quest\"},{\"t\":3,\"p\":1,\"n\":\"Faction\"},{\"t\":3,\"p\":1,\"n\":\"Weapon\"},{\"t\":3,\"p\":1,\"n\":\"Cell\"},{\"t\":3,\"p\":1,\"n\":\"Class\"},{\"t\":3,\"p\":1,\"n\":\"Race\"},{\"t\":3,\"p\":1,\"n\":\"Actor Base\"},{\"t\":3,\"p\":1,\"n\":\"Global\"},{\"t\":3,\"p\":1,\"n\":\"Weather\"},{\"t\":3,\"p\":1,\"n\":\"Package\"},{\"t\":3,\"p\":1,\"n\":\"Encounter Zone\"},{\"t\":3,\"p\":1,\"n\":\"Perk\"},{\"t\":3,\"p\":1,\"n\":\"Owner\"},{\"t\":3,\"p\":1,\"n\":\"Furniture\"},{\"t\":3,\"p\":1,\"n\":\"Effect Item\"},{\"t\":3,\"p\":1,\"n\":\"Base Effect\"},{\"t\":3,\"p\":1,\"n\":\"Worldspace\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Function\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Param (INVALID)\"},{\"t\":3,\"p\":1,\"n\":\"Creature Type\"},{\"t\":3,\"p\":1,\"n\":\"Menu Mode\"},{\"t\":3,\"p\":1,\"n\":\"Player Action\"},{\"t\":3,\"p\":1,\"n\":\"Body Location\"},{\"t\":3,\"p\":1,\"n\":\"Referenceable Object\"},{\"t\":3,\"p\":1,\"n\":\"Quest Objective (INVALID)\"},{\"t\":3,\"p\":1,\"n\":\"Reputation\"},{\"t\":3,\"p\":1,\"n\":\"Region\"},{\"t\":3,\"p\":1,\"n\":\"Challenge\"},{\"t\":3,\"p\":1,\"n\":\"Casino\"},{\"t\":3,\"p\":1,\"n\":\"Form\"},{\"t\":3,\"p\":1,\"n\":\"Variable Name\"},{\"t\":3,\"p\":1,\"n\":\"Quest Stage\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Function (INVALID)\"},{\"t\":3,\"p\":1,\"n\":\"Weapon List\"},{\"t\":3,\"p\":1,\"n\":\"Target\"},{\"t\":3,\"p\":1,\"n\":\"Target List\"},{\"t\":3,\"p\":1,\"n\":\"Target Part\"},{\"t\":3,\"p\":1,\"n\":\"VATS Action\"},{\"t\":3,\"p\":1,\"n\":\"Critical Effect\"},{\"t\":3,\"p\":1,\"n\":\"Critical Effect List\"},{\"t\":3,\"p\":1,\"n\":\"Weapon Type\"},{\"t\":3,\"p\":1,\"n\":\"Quest Objective\"},{\"t\":3,\"p\":1,\"n\":\"Run On\"},{\"t\":3,\"p\":1,\"n\":\"Reference\"}]}]},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Choices\",\"d\":1,\"c\":[{\"t\":3,\"p\":1,\"n\":\"TCLT - Choice\"}]},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Link From\",\"d\":1,\"c\":[{\"t\":3,\"p\":1,\"n\":\"TCLF - Topic\"}]},{\"t\":8,\"n\":\"Unknown\",\"c\":[{\"t\":3,\"n\":\"TCFU - Info\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Script (Begin)\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Embedded Script\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"SCHR - Basic Script Data\",\"c\":[{\"t\":11,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"RefCount\"},{\"t\":3,\"p\":1,\"n\":\"CompiledSize\"},{\"t\":3,\"p\":1,\"n\":\"VariableCount\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"}]},{\"t\":11,\"p\":1,\"n\":\"SCDA - Compiled Embedded Script\"},{\"t\":2,\"p\":1,\"n\":\"SCTX - Embedded Script Source\"},{\"t\":10,\"p\":1,\"n\":\"Local Variables\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Local Variable\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"SLSD - Local Variable Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Index\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"}]},{\"t\":2,\"p\":1,\"n\":\"SCVR - Name\"}]}]},{\"t\":8,\"p\":1,\"n\":\"References\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"SCRO - Global Reference\"},{\"t\":3,\"p\":1,\"n\":\"SCRV - Local Variable\"}]}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Script (End)\",\"c\":[{\"p\":1,\"n\":\"NEXT - Marker\"},{\"t\":6,\"p\":1,\"n\":\"Embedded Script\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"SCHR - Basic Script Data\",\"c\":[{\"t\":11,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"RefCount\"},{\"t\":3,\"p\":1,\"n\":\"CompiledSize\"},{\"t\":3,\"p\":1,\"n\":\"VariableCount\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"}]},{\"t\":11,\"p\":1,\"n\":\"SCDA - Compiled Embedded Script\"},{\"t\":2,\"p\":1,\"n\":\"SCTX - Embedded Script Source\"},{\"t\":10,\"p\":1,\"n\":\"Local Variables\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Local Variable\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"SLSD - Local Variable Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Index\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"}]},{\"t\":2,\"p\":1,\"n\":\"SCVR - Name\"}]}]},{\"t\":8,\"p\":1,\"n\":\"References\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"SCRO - Global Reference\"},{\"t\":3,\"p\":1,\"n\":\"SCRV - Local Variable\"}]}]}]},{\"t\":3,\"n\":\"SNDD - Unused\"},{\"t\":2,\"p\":1,\"n\":\"RNAM - Prompt\"},{\"t\":3,\"p\":1,\"n\":\"ANAM - Speaker\"},{\"t\":3,\"p\":1,\"n\":\"KNAM - ActorValue\\/Perk\"},{\"t\":3,\"p\":1,\"n\":\"DNAM - Speech Challenge\"}]},{\"t\":1,\"p\":1,\"n\":\"INGR - Ingredient\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"X1\"},{\"t\":3,\"p\":1,\"n\":\"Y1\"},{\"t\":3,\"p\":1,\"n\":\"Z1\"},{\"t\":3,\"p\":1,\"n\":\"X2\"},{\"t\":3,\"p\":1,\"n\":\"Y2\"},{\"t\":3,\"p\":1,\"n\":\"Z2\"}]},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"},{\"t\":11,\"n\":\"MODB - Unknown\"},{\"t\":11,\"p\":1,\"n\":\"MODT - Texture Files Hashes\"},{\"t\":7,\"p\":1,\"n\":\"MODS - Alternate Textures\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"3D Name\"},{\"t\":3,\"p\":1,\"n\":\"New Texture\"},{\"t\":3,\"p\":1,\"n\":\"3D Index\"}]}]},{\"t\":3,\"p\":1,\"n\":\"MODD - FaceGen Model Flags\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Icon\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"ICON - Large Icon filename\"},{\"t\":2,\"p\":1,\"n\":\"MICO - Small Icon filename\"}]},{\"t\":3,\"p\":1,\"n\":\"SCRI - Script\"},{\"t\":3,\"p\":1,\"n\":\"ETYP - Equiptment Type\"},{\"t\":5,\"p\":1,\"n\":\"DATA - Weight\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"ENIT - Effect Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Value\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Effects\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Effect\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"EFID - Base Effect\"},{\"t\":6,\"p\":1,\"n\":\"EFIT - \",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Magnitude\"},{\"t\":3,\"p\":1,\"n\":\"Area\"},{\"t\":3,\"p\":1,\"n\":\"Duration\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Actor Value\"}]},{\"t\":8,\"p\":1,\"n\":\"Conditions\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"CTDA - Condition\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":5,\"p\":1,\"n\":\"Comparison Value - Float\"},{\"t\":3,\"p\":1,\"n\":\"Comparison Value - Global\"},{\"t\":3,\"p\":1,\"n\":\"Function\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":11,\"p\":1,\"n\":\"None\"},{\"t\":3,\"p\":1,\"n\":\"Integer\"},{\"t\":3,\"p\":1,\"n\":\"Variable Name (INVALID)\"},{\"t\":3,\"p\":1,\"n\":\"Sex\"},{\"t\":3,\"p\":1,\"n\":\"Actor Value\"},{\"t\":3,\"p\":1,\"n\":\"Crime Type\"},{\"t\":3,\"p\":1,\"n\":\"Axis\"},{\"t\":3,\"p\":1,\"n\":\"Quest Stage (INVALID)\"},{\"t\":3,\"p\":1,\"n\":\"Misc Stat\"},{\"t\":3,\"p\":1,\"n\":\"Alignment\"},{\"t\":3,\"p\":1,\"n\":\"Equip Type\"},{\"t\":3,\"p\":1,\"n\":\"Form Type\"},{\"t\":3,\"p\":1,\"n\":\"Critical Stage\"},{\"t\":3,\"p\":1,\"n\":\"Object Reference\"},{\"t\":3,\"p\":1,\"n\":\"Inventory Object\"},{\"t\":3,\"p\":1,\"n\":\"Actor\"},{\"t\":3,\"p\":1,\"n\":\"Voice Type\"},{\"t\":3,\"p\":1,\"n\":\"Idle\"},{\"t\":3,\"p\":1,\"n\":\"Form List\"},{\"t\":3,\"p\":1,\"n\":\"Note\"},{\"t\":3,\"p\":1,\"n\":\"Quest\"},{\"t\":3,\"p\":1,\"n\":\"Faction\"},{\"t\":3,\"p\":1,\"n\":\"Weapon\"},{\"t\":3,\"p\":1,\"n\":\"Cell\"},{\"t\":3,\"p\":1,\"n\":\"Class\"},{\"t\":3,\"p\":1,\"n\":\"Race\"},{\"t\":3,\"p\":1,\"n\":\"Actor Base\"},{\"t\":3,\"p\":1,\"n\":\"Global\"},{\"t\":3,\"p\":1,\"n\":\"Weather\"},{\"t\":3,\"p\":1,\"n\":\"Package\"},{\"t\":3,\"p\":1,\"n\":\"Encounter Zone\"},{\"t\":3,\"p\":1,\"n\":\"Perk\"},{\"t\":3,\"p\":1,\"n\":\"Owner\"},{\"t\":3,\"p\":1,\"n\":\"Furniture\"},{\"t\":3,\"p\":1,\"n\":\"Effect Item\"},{\"t\":3,\"p\":1,\"n\":\"Base Effect\"},{\"t\":3,\"p\":1,\"n\":\"Worldspace\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Function\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Param (INVALID)\"},{\"t\":3,\"p\":1,\"n\":\"Creature Type\"},{\"t\":3,\"p\":1,\"n\":\"Menu Mode\"},{\"t\":3,\"p\":1,\"n\":\"Player Action\"},{\"t\":3,\"p\":1,\"n\":\"Body Location\"},{\"t\":3,\"p\":1,\"n\":\"Referenceable Object\"},{\"t\":3,\"p\":1,\"n\":\"Quest Objective (INVALID)\"},{\"t\":3,\"p\":1,\"n\":\"Reputation\"},{\"t\":3,\"p\":1,\"n\":\"Region\"},{\"t\":3,\"p\":1,\"n\":\"Challenge\"},{\"t\":3,\"p\":1,\"n\":\"Casino\"},{\"t\":3,\"p\":1,\"n\":\"Form\"},{\"t\":3,\"p\":1,\"n\":\"Variable Name\"},{\"t\":3,\"p\":1,\"n\":\"Quest Stage\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Function (INVALID)\"},{\"t\":3,\"p\":1,\"n\":\"Weapon List\"},{\"t\":3,\"p\":1,\"n\":\"Target\"},{\"t\":3,\"p\":1,\"n\":\"Target List\"},{\"t\":3,\"p\":1,\"n\":\"Target Part\"},{\"t\":3,\"p\":1,\"n\":\"VATS Action\"},{\"t\":3,\"p\":1,\"n\":\"Critical Effect\"},{\"t\":3,\"p\":1,\"n\":\"Critical Effect List\"},{\"t\":3,\"p\":1,\"n\":\"Weapon Type\"},{\"t\":3,\"p\":1,\"n\":\"Quest Objective\"},{\"t\":3,\"p\":1,\"n\":\"Run On\"},{\"t\":3,\"p\":1,\"n\":\"Reference\"}]}]}]}]}]},{\"t\":1,\"p\":1,\"n\":\"IPCT - Impact\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"},{\"t\":11,\"n\":\"MODB - Unknown\"},{\"t\":11,\"p\":1,\"n\":\"MODT - Texture Files Hashes\"},{\"t\":7,\"p\":1,\"n\":\"MODS - Alternate Textures\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"3D Name\"},{\"t\":3,\"p\":1,\"n\":\"New Texture\"},{\"t\":3,\"p\":1,\"n\":\"3D Index\"}]}]},{\"t\":3,\"p\":1,\"n\":\"MODD - FaceGen Model Flags\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DATA - \",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Effect - Duration\"},{\"t\":3,\"p\":1,\"n\":\"Effect - Orientation\"},{\"t\":5,\"p\":1,\"n\":\"Angle Threshold\"},{\"t\":5,\"p\":1,\"n\":\"Placement Radius\"},{\"t\":3,\"p\":1,\"n\":\"Sound Level\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DODT - Decal Data\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Min Width\"},{\"t\":5,\"p\":1,\"n\":\"Max Width\"},{\"t\":5,\"p\":1,\"n\":\"Min Height\"},{\"t\":5,\"p\":1,\"n\":\"Max Height\"},{\"t\":5,\"p\":1,\"n\":\"Depth\"},{\"t\":5,\"p\":1,\"n\":\"Shininess\"},{\"t\":6,\"p\":1,\"n\":\"Parallax\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Scale\"},{\"t\":3,\"p\":1,\"n\":\"Passes\"}]},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":6,\"p\":1,\"n\":\"Color\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]}]},{\"t\":3,\"p\":1,\"n\":\"DNAM - Texture Set\"},{\"t\":3,\"p\":1,\"n\":\"SNAM - Sound 1\"},{\"t\":3,\"p\":1,\"n\":\"NAM1 - Sound 2\"}]},{\"t\":1,\"p\":1,\"n\":\"IPDS - Impact DataSet\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DATA - Impacts\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Stone\"},{\"t\":3,\"p\":1,\"n\":\"Dirt\"},{\"t\":3,\"p\":1,\"n\":\"Grass\"},{\"t\":3,\"p\":1,\"n\":\"Glass\"},{\"t\":3,\"p\":1,\"n\":\"Metal\"},{\"t\":3,\"p\":1,\"n\":\"Wood\"},{\"t\":3,\"p\":1,\"n\":\"Organic\"},{\"t\":3,\"p\":1,\"n\":\"Cloth\"},{\"t\":3,\"p\":1,\"n\":\"Water\"},{\"t\":3,\"p\":1,\"n\":\"Hollow Metal\"},{\"t\":3,\"p\":1,\"n\":\"Organic Bug\"},{\"t\":3,\"p\":1,\"n\":\"Organic Glow\"}]}]},{\"t\":1,\"p\":1,\"n\":\"KEYM - Key\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"X1\"},{\"t\":3,\"p\":1,\"n\":\"Y1\"},{\"t\":3,\"p\":1,\"n\":\"Z1\"},{\"t\":3,\"p\":1,\"n\":\"X2\"},{\"t\":3,\"p\":1,\"n\":\"Y2\"},{\"t\":3,\"p\":1,\"n\":\"Z2\"}]},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"},{\"t\":11,\"n\":\"MODB - Unknown\"},{\"t\":11,\"p\":1,\"n\":\"MODT - Texture Files Hashes\"},{\"t\":7,\"p\":1,\"n\":\"MODS - Alternate Textures\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"3D Name\"},{\"t\":3,\"p\":1,\"n\":\"New Texture\"},{\"t\":3,\"p\":1,\"n\":\"3D Index\"}]}]},{\"t\":3,\"p\":1,\"n\":\"MODD - FaceGen Model Flags\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Icon\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"ICON - Large Icon filename\"},{\"t\":2,\"p\":1,\"n\":\"MICO - Small Icon filename\"}]},{\"t\":3,\"p\":1,\"n\":\"SCRI - Script\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Destructable\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"DEST - Header\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Health\"},{\"t\":3,\"p\":1,\"n\":\"Count\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":8,\"p\":1,\"n\":\"Stages\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Stage\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"DSTD - Destruction Stage Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Health %\"},{\"t\":3,\"p\":1,\"n\":\"Index\"},{\"t\":3,\"p\":1,\"n\":\"Damage Stage\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":3,\"p\":1,\"n\":\"Self Damage per Second\"},{\"t\":3,\"p\":1,\"n\":\"Explosion\"},{\"t\":3,\"p\":1,\"n\":\"Debris\"},{\"t\":3,\"p\":1,\"n\":\"Debris Count\"}]},{\"t\":6,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"DMDL - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"DMDT - Texture Files Hashes\"}]},{\"p\":1,\"n\":\"DSTF - End Marker\"}]}]}]},{\"t\":3,\"p\":1,\"n\":\"YNAM - Sound - Pick Up\"},{\"t\":3,\"p\":1,\"n\":\"ZNAM - Sound - Drop\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DATA - \",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Value\"},{\"t\":5,\"p\":1,\"n\":\"Weight\"}]},{\"t\":3,\"p\":1,\"n\":\"RNAM - Sound - Random\\/Looping\"}]},{\"t\":1,\"p\":1,\"n\":\"LAND - Landscape\",\"d\":1,\"c\":[{\"t\":11,\"n\":\"DATA - Unknown\"},{\"t\":11,\"n\":\"VNML - Vertex Normals\"},{\"t\":11,\"n\":\"VHGT - Vertext Height Map\"},{\"t\":11,\"n\":\"VCLR - Vertex Colours\"},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Layers\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Base Layer\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"BTXT - Base Layer Header\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Texture\"},{\"t\":3,\"p\":1,\"n\":\"Quadrant\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Layer\"}]}]},{\"t\":6,\"p\":1,\"n\":\"Alpha Layer\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"ATXT - Alpha Layer Header\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Texture\"},{\"t\":3,\"p\":1,\"n\":\"Quadrant\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Layer\"}]},{\"t\":11,\"p\":1,\"n\":\"VTXT - Alpha Layer Data\"}]}]},{\"t\":7,\"p\":1,\"n\":\"VTEX - Textures\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Texture\"}]}]},{\"t\":1,\"p\":1,\"n\":\"LGTM - Lighting Template\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DATA - Lighting\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Ambient Color\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Directional Color\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Fog Color\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":5,\"p\":1,\"n\":\"Fog Near\"},{\"t\":5,\"p\":1,\"n\":\"Fog Far\"},{\"t\":3,\"p\":1,\"n\":\"Directional Rotation XY\"},{\"t\":3,\"p\":1,\"n\":\"Directional Rotation Z\"},{\"t\":5,\"p\":1,\"n\":\"Directional Fade\"},{\"t\":5,\"p\":1,\"n\":\"Fog Clip Dist\"},{\"t\":5,\"p\":1,\"n\":\"Fog Power\"}]}]},{\"t\":1,\"p\":1,\"n\":\"LIGH - Light\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"X1\"},{\"t\":3,\"p\":1,\"n\":\"Y1\"},{\"t\":3,\"p\":1,\"n\":\"Z1\"},{\"t\":3,\"p\":1,\"n\":\"X2\"},{\"t\":3,\"p\":1,\"n\":\"Y2\"},{\"t\":3,\"p\":1,\"n\":\"Z2\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"},{\"t\":11,\"n\":\"MODB - Unknown\"},{\"t\":11,\"p\":1,\"n\":\"MODT - Texture Files Hashes\"},{\"t\":7,\"p\":1,\"n\":\"MODS - Alternate Textures\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"3D Name\"},{\"t\":3,\"p\":1,\"n\":\"New Texture\"},{\"t\":3,\"p\":1,\"n\":\"3D Index\"}]}]},{\"t\":3,\"p\":1,\"n\":\"MODD - FaceGen Model Flags\"}]},{\"t\":3,\"p\":1,\"n\":\"SCRI - Script\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Destructable\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"DEST - Header\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Health\"},{\"t\":3,\"p\":1,\"n\":\"Count\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":8,\"p\":1,\"n\":\"Stages\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Stage\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"DSTD - Destruction Stage Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Health %\"},{\"t\":3,\"p\":1,\"n\":\"Index\"},{\"t\":3,\"p\":1,\"n\":\"Damage Stage\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":3,\"p\":1,\"n\":\"Self Damage per Second\"},{\"t\":3,\"p\":1,\"n\":\"Explosion\"},{\"t\":3,\"p\":1,\"n\":\"Debris\"},{\"t\":3,\"p\":1,\"n\":\"Debris Count\"}]},{\"t\":6,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"DMDL - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"DMDT - Texture Files Hashes\"}]},{\"p\":1,\"n\":\"DSTF - End Marker\"}]}]}]},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Icon\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"ICON - Large Icon filename\"},{\"t\":2,\"p\":1,\"n\":\"MICO - Small Icon filename\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DATA - \",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Time\"},{\"t\":3,\"p\":1,\"n\":\"Radius\"},{\"t\":6,\"p\":1,\"n\":\"Color\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":3,\"n\":\"Unused\"}]},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":5,\"p\":1,\"n\":\"Falloff Exponent\"},{\"t\":5,\"p\":1,\"n\":\"FOV\"},{\"t\":3,\"p\":1,\"n\":\"Value\"},{\"t\":5,\"p\":1,\"n\":\"Weight\"}]},{\"t\":5,\"p\":1,\"n\":\"FNAM - Fade value\"},{\"t\":3,\"p\":1,\"n\":\"SNAM - Sound\"}]},{\"t\":1,\"p\":1,\"n\":\"LSCR - Load Screen\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Icon\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"ICON - Large Icon filename\"},{\"t\":2,\"p\":1,\"n\":\"MICO - Small Icon filename\"}]},{\"t\":2,\"p\":1,\"n\":\"DESC - Description\"},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Locations\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"LNAM - Location\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Direct\"},{\"t\":6,\"p\":1,\"n\":\"Indirect\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"World\"},{\"t\":6,\"p\":1,\"n\":\"Grid\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Y\"},{\"t\":3,\"p\":1,\"n\":\"X\"}]}]}]}]},{\"t\":3,\"p\":1,\"n\":\"WMI1 - Load Screen Type\"}]},{\"t\":1,\"p\":1,\"n\":\"LSCT - Load Screen Type\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DATA - Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":6,\"p\":1,\"n\":\"Data 1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"X\"},{\"t\":3,\"p\":1,\"n\":\"Y\"},{\"t\":3,\"p\":1,\"n\":\"Width\"},{\"t\":3,\"p\":1,\"n\":\"Height\"},{\"t\":5,\"p\":1,\"n\":\"Orientation\"},{\"t\":3,\"p\":1,\"n\":\"Font\"},{\"t\":6,\"p\":1,\"n\":\"Font Color\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"R\"},{\"t\":5,\"p\":1,\"n\":\"G\"},{\"t\":5,\"p\":1,\"n\":\"B\"}]}]},{\"t\":11,\"n\":\"Unknown\"},{\"t\":6,\"p\":1,\"n\":\"Data 2\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Font\"},{\"t\":6,\"p\":1,\"n\":\"Font Color\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"R\"},{\"t\":5,\"p\":1,\"n\":\"G\"},{\"t\":5,\"p\":1,\"n\":\"B\"}]},{\"t\":11,\"p\":1,\"n\":\"\"},{\"t\":3,\"p\":1,\"n\":\"Stats\"}]}]}]},{\"t\":1,\"p\":1,\"n\":\"LTEX - Landscape Texture\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Icon\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"ICON - Large Icon filename\"},{\"t\":2,\"p\":1,\"n\":\"MICO - Small Icon filename\"}]},{\"t\":3,\"p\":1,\"n\":\"TNAM - Texture\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"HNAM - Havok Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Material Type\"},{\"t\":3,\"p\":1,\"n\":\"Friction\"},{\"t\":3,\"p\":1,\"n\":\"Restitution\"}]},{\"t\":3,\"p\":1,\"n\":\"SNAM - Texture Specular Exponent\"},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Grasses\",\"d\":1,\"c\":[{\"t\":3,\"p\":1,\"n\":\"GNAM - Grass\"}]}]},{\"t\":1,\"p\":1,\"n\":\"LVLC - Leveled Creature\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"X1\"},{\"t\":3,\"p\":1,\"n\":\"Y1\"},{\"t\":3,\"p\":1,\"n\":\"Z1\"},{\"t\":3,\"p\":1,\"n\":\"X2\"},{\"t\":3,\"p\":1,\"n\":\"Y2\"},{\"t\":3,\"p\":1,\"n\":\"Z2\"}]},{\"t\":3,\"p\":1,\"n\":\"LVLD - Chance none\"},{\"t\":3,\"p\":1,\"n\":\"LVLF - Flags\"},{\"t\":10,\"p\":1,\"n\":\"Leveled List Entries\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Leveled List Entry\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"LVLO - Base Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Level\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":3,\"p\":1,\"n\":\"Count\"}]},{\"t\":6,\"p\":1,\"n\":\"COED - Extra Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Owner\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Global Variable\"},{\"t\":3,\"p\":1,\"n\":\"Required Rank\"},{\"t\":5,\"p\":1,\"n\":\"Item Condition\"}]}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"},{\"t\":11,\"n\":\"MODB - Unknown\"},{\"t\":11,\"p\":1,\"n\":\"MODT - Texture Files Hashes\"},{\"t\":7,\"p\":1,\"n\":\"MODS - Alternate Textures\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"3D Name\"},{\"t\":3,\"p\":1,\"n\":\"New Texture\"},{\"t\":3,\"p\":1,\"n\":\"3D Index\"}]}]},{\"t\":3,\"p\":1,\"n\":\"MODD - FaceGen Model Flags\"}]}]},{\"t\":1,\"p\":1,\"n\":\"LVLI - Leveled Item\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"X1\"},{\"t\":3,\"p\":1,\"n\":\"Y1\"},{\"t\":3,\"p\":1,\"n\":\"Z1\"},{\"t\":3,\"p\":1,\"n\":\"X2\"},{\"t\":3,\"p\":1,\"n\":\"Y2\"},{\"t\":3,\"p\":1,\"n\":\"Z2\"}]},{\"t\":3,\"p\":1,\"n\":\"LVLD - Chance none\"},{\"t\":3,\"p\":1,\"n\":\"LVLF - Flags\"},{\"t\":3,\"p\":1,\"n\":\"LVLG - Global\"},{\"t\":10,\"p\":1,\"n\":\"Leveled List Entries\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Leveled List Entry\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"LVLO - Base Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Level\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":3,\"p\":1,\"n\":\"Count\"}]},{\"t\":6,\"p\":1,\"n\":\"COED - Extra Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Owner\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Global Variable\"},{\"t\":3,\"p\":1,\"n\":\"Required Rank\"},{\"t\":5,\"p\":1,\"n\":\"Item Condition\"}]}]}]}]},{\"t\":1,\"p\":1,\"n\":\"LVLN - Leveled NPC\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"X1\"},{\"t\":3,\"p\":1,\"n\":\"Y1\"},{\"t\":3,\"p\":1,\"n\":\"Z1\"},{\"t\":3,\"p\":1,\"n\":\"X2\"},{\"t\":3,\"p\":1,\"n\":\"Y2\"},{\"t\":3,\"p\":1,\"n\":\"Z2\"}]},{\"t\":3,\"p\":1,\"n\":\"LVLD - Chance none\"},{\"t\":3,\"p\":1,\"n\":\"LVLF - Flags\"},{\"t\":10,\"p\":1,\"n\":\"Leveled List Entries\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Leveled List Entry\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"LVLO - Base Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Level\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":3,\"p\":1,\"n\":\"Count\"}]},{\"t\":6,\"p\":1,\"n\":\"COED - Extra Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Owner\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Global Variable\"},{\"t\":3,\"p\":1,\"n\":\"Required Rank\"},{\"t\":5,\"p\":1,\"n\":\"Item Condition\"}]}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"},{\"t\":11,\"n\":\"MODB - Unknown\"},{\"t\":11,\"p\":1,\"n\":\"MODT - Texture Files Hashes\"},{\"t\":7,\"p\":1,\"n\":\"MODS - Alternate Textures\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"3D Name\"},{\"t\":3,\"p\":1,\"n\":\"New Texture\"},{\"t\":3,\"p\":1,\"n\":\"3D Index\"}]}]},{\"t\":3,\"p\":1,\"n\":\"MODD - FaceGen Model Flags\"}]}]},{\"t\":1,\"p\":1,\"n\":\"MESG - Message\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"p\":1,\"n\":\"DESC - Description\"},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":3,\"p\":1,\"n\":\"INAM - Icon\"},{\"t\":11,\"n\":\"NAM0 - Unused\"},{\"t\":11,\"n\":\"NAM1 - Unused\"},{\"t\":11,\"n\":\"NAM2 - Unused\"},{\"t\":11,\"n\":\"NAM3 - Unused\"},{\"t\":11,\"n\":\"NAM4 - Unused\"},{\"t\":11,\"n\":\"NAM5 - Unused\"},{\"t\":11,\"n\":\"NAM6 - Unused\"},{\"t\":11,\"n\":\"NAM7 - Unused\"},{\"t\":11,\"n\":\"NAM8 - Unused\"},{\"t\":11,\"n\":\"NAM9 - Unused\"},{\"t\":3,\"p\":1,\"n\":\"DNAM - Flags\"},{\"t\":3,\"p\":1,\"n\":\"TNAM - Display Time\"},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Menu Buttons\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Menu Button\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"ITXT - Button Text\"},{\"t\":8,\"p\":1,\"n\":\"Conditions\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"CTDA - Condition\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":5,\"p\":1,\"n\":\"Comparison Value - Float\"},{\"t\":3,\"p\":1,\"n\":\"Comparison Value - Global\"},{\"t\":3,\"p\":1,\"n\":\"Function\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":11,\"p\":1,\"n\":\"None\"},{\"t\":3,\"p\":1,\"n\":\"Integer\"},{\"t\":3,\"p\":1,\"n\":\"Variable Name (INVALID)\"},{\"t\":3,\"p\":1,\"n\":\"Sex\"},{\"t\":3,\"p\":1,\"n\":\"Actor Value\"},{\"t\":3,\"p\":1,\"n\":\"Crime Type\"},{\"t\":3,\"p\":1,\"n\":\"Axis\"},{\"t\":3,\"p\":1,\"n\":\"Quest Stage (INVALID)\"},{\"t\":3,\"p\":1,\"n\":\"Misc Stat\"},{\"t\":3,\"p\":1,\"n\":\"Alignment\"},{\"t\":3,\"p\":1,\"n\":\"Equip Type\"},{\"t\":3,\"p\":1,\"n\":\"Form Type\"},{\"t\":3,\"p\":1,\"n\":\"Critical Stage\"},{\"t\":3,\"p\":1,\"n\":\"Object Reference\"},{\"t\":3,\"p\":1,\"n\":\"Inventory Object\"},{\"t\":3,\"p\":1,\"n\":\"Actor\"},{\"t\":3,\"p\":1,\"n\":\"Voice Type\"},{\"t\":3,\"p\":1,\"n\":\"Idle\"},{\"t\":3,\"p\":1,\"n\":\"Form List\"},{\"t\":3,\"p\":1,\"n\":\"Note\"},{\"t\":3,\"p\":1,\"n\":\"Quest\"},{\"t\":3,\"p\":1,\"n\":\"Faction\"},{\"t\":3,\"p\":1,\"n\":\"Weapon\"},{\"t\":3,\"p\":1,\"n\":\"Cell\"},{\"t\":3,\"p\":1,\"n\":\"Class\"},{\"t\":3,\"p\":1,\"n\":\"Race\"},{\"t\":3,\"p\":1,\"n\":\"Actor Base\"},{\"t\":3,\"p\":1,\"n\":\"Global\"},{\"t\":3,\"p\":1,\"n\":\"Weather\"},{\"t\":3,\"p\":1,\"n\":\"Package\"},{\"t\":3,\"p\":1,\"n\":\"Encounter Zone\"},{\"t\":3,\"p\":1,\"n\":\"Perk\"},{\"t\":3,\"p\":1,\"n\":\"Owner\"},{\"t\":3,\"p\":1,\"n\":\"Furniture\"},{\"t\":3,\"p\":1,\"n\":\"Effect Item\"},{\"t\":3,\"p\":1,\"n\":\"Base Effect\"},{\"t\":3,\"p\":1,\"n\":\"Worldspace\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Function\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Param (INVALID)\"},{\"t\":3,\"p\":1,\"n\":\"Creature Type\"},{\"t\":3,\"p\":1,\"n\":\"Menu Mode\"},{\"t\":3,\"p\":1,\"n\":\"Player Action\"},{\"t\":3,\"p\":1,\"n\":\"Body Location\"},{\"t\":3,\"p\":1,\"n\":\"Referenceable Object\"},{\"t\":3,\"p\":1,\"n\":\"Quest Objective (INVALID)\"},{\"t\":3,\"p\":1,\"n\":\"Reputation\"},{\"t\":3,\"p\":1,\"n\":\"Region\"},{\"t\":3,\"p\":1,\"n\":\"Challenge\"},{\"t\":3,\"p\":1,\"n\":\"Casino\"},{\"t\":3,\"p\":1,\"n\":\"Form\"},{\"t\":3,\"p\":1,\"n\":\"Variable Name\"},{\"t\":3,\"p\":1,\"n\":\"Quest Stage\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Function (INVALID)\"},{\"t\":3,\"p\":1,\"n\":\"Weapon List\"},{\"t\":3,\"p\":1,\"n\":\"Target\"},{\"t\":3,\"p\":1,\"n\":\"Target List\"},{\"t\":3,\"p\":1,\"n\":\"Target Part\"},{\"t\":3,\"p\":1,\"n\":\"VATS Action\"},{\"t\":3,\"p\":1,\"n\":\"Critical Effect\"},{\"t\":3,\"p\":1,\"n\":\"Critical Effect List\"},{\"t\":3,\"p\":1,\"n\":\"Weapon Type\"},{\"t\":3,\"p\":1,\"n\":\"Quest Objective\"},{\"t\":3,\"p\":1,\"n\":\"Run On\"},{\"t\":3,\"p\":1,\"n\":\"Reference\"}]}]}]}]}]},{\"t\":1,\"p\":1,\"n\":\"MGEF - Base Effect\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":2,\"p\":1,\"n\":\"DESC - Description\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Icon\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"ICON - Large Icon filename\"},{\"t\":2,\"p\":1,\"n\":\"MICO - Small Icon filename\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"},{\"t\":11,\"n\":\"MODB - Unknown\"},{\"t\":11,\"p\":1,\"n\":\"MODT - Texture Files Hashes\"},{\"t\":7,\"p\":1,\"n\":\"MODS - Alternate Textures\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"3D Name\"},{\"t\":3,\"p\":1,\"n\":\"New Texture\"},{\"t\":3,\"p\":1,\"n\":\"3D Index\"}]}]},{\"t\":3,\"p\":1,\"n\":\"MODD - FaceGen Model Flags\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DATA - Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":5,\"n\":\"Base cost (Unused)\"},{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Assoc. Item\"},{\"t\":3,\"p\":1,\"n\":\"Assoc. Script\"},{\"t\":3,\"p\":1,\"n\":\"Assoc. Creature\"},{\"t\":3,\"n\":\"Magic School (Unused)\"},{\"t\":3,\"p\":1,\"n\":\"Resistance Type\"},{\"t\":3,\"p\":1,\"n\":\"Counter effect count\"},{\"t\":3,\"p\":1,\"n\":\"Light\"},{\"t\":5,\"p\":1,\"n\":\"Projectile speed\"},{\"t\":3,\"p\":1,\"n\":\"Effect Shader\"},{\"t\":3,\"p\":1,\"n\":\"Object Display Shader\"},{\"t\":3,\"p\":1,\"n\":\"Effect sound\"},{\"t\":3,\"p\":1,\"n\":\"Bolt sound\"},{\"t\":3,\"p\":1,\"n\":\"Hit sound\"},{\"t\":3,\"p\":1,\"n\":\"Area sound\"},{\"t\":5,\"n\":\"Constant Effect enchantment factor  (Unused)\"},{\"t\":5,\"n\":\"Constant Effect barter factor (Unused)\"},{\"t\":3,\"p\":1,\"n\":\"Archtype\"},{\"t\":3,\"p\":1,\"n\":\"Actor Value\"}]},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Counter Effects\",\"d\":1,\"c\":[{\"t\":3,\"p\":1,\"n\":\"ESCE - Effect\"}]}]},{\"t\":1,\"p\":1,\"n\":\"MICN - Menu Icon\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Icon\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"ICON - Large Icon filename\"},{\"t\":2,\"p\":1,\"n\":\"MICO - Small Icon filename\"}]}]},{\"t\":1,\"p\":1,\"n\":\"MISC - Misc. Item\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"X1\"},{\"t\":3,\"p\":1,\"n\":\"Y1\"},{\"t\":3,\"p\":1,\"n\":\"Z1\"},{\"t\":3,\"p\":1,\"n\":\"X2\"},{\"t\":3,\"p\":1,\"n\":\"Y2\"},{\"t\":3,\"p\":1,\"n\":\"Z2\"}]},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"},{\"t\":11,\"n\":\"MODB - Unknown\"},{\"t\":11,\"p\":1,\"n\":\"MODT - Texture Files Hashes\"},{\"t\":7,\"p\":1,\"n\":\"MODS - Alternate Textures\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"3D Name\"},{\"t\":3,\"p\":1,\"n\":\"New Texture\"},{\"t\":3,\"p\":1,\"n\":\"3D Index\"}]}]},{\"t\":3,\"p\":1,\"n\":\"MODD - FaceGen Model Flags\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Icon\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"ICON - Large Icon filename\"},{\"t\":2,\"p\":1,\"n\":\"MICO - Small Icon filename\"}]},{\"t\":3,\"p\":1,\"n\":\"SCRI - Script\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Destructable\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"DEST - Header\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Health\"},{\"t\":3,\"p\":1,\"n\":\"Count\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":8,\"p\":1,\"n\":\"Stages\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Stage\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"DSTD - Destruction Stage Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Health %\"},{\"t\":3,\"p\":1,\"n\":\"Index\"},{\"t\":3,\"p\":1,\"n\":\"Damage Stage\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":3,\"p\":1,\"n\":\"Self Damage per Second\"},{\"t\":3,\"p\":1,\"n\":\"Explosion\"},{\"t\":3,\"p\":1,\"n\":\"Debris\"},{\"t\":3,\"p\":1,\"n\":\"Debris Count\"}]},{\"t\":6,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"DMDL - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"DMDT - Texture Files Hashes\"}]},{\"p\":1,\"n\":\"DSTF - End Marker\"}]}]}]},{\"t\":3,\"p\":1,\"n\":\"YNAM - Sound - Pick Up\"},{\"t\":3,\"p\":1,\"n\":\"ZNAM - Sound - Drop\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DATA - \",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Value\"},{\"t\":5,\"p\":1,\"n\":\"Weight\"}]},{\"t\":3,\"p\":1,\"n\":\"RNAM - Sound - Random\\/Looping\"}]},{\"t\":1,\"p\":1,\"n\":\"MSET - Media Set\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":3,\"p\":1,\"n\":\"NAM1 - Type\"},{\"t\":2,\"p\":1,\"n\":\"NAM2 - Loop (B) \\/ Battle (D) \\/ Day Outer (L)\"},{\"t\":2,\"p\":1,\"n\":\"NAM3 - Explore (D) \\/ Day Middle (L)\"},{\"t\":2,\"p\":1,\"n\":\"NAM4 - Suspense (D) \\/ Day Inner (L)\"},{\"t\":2,\"p\":1,\"n\":\"NAM5 - Night Outer (L)\"},{\"t\":2,\"p\":1,\"n\":\"NAM6 - Night Middle (L)\"},{\"t\":2,\"p\":1,\"n\":\"NAM7 - Night Inner (L)\"},{\"t\":5,\"p\":1,\"n\":\"NAM8 - Loop dB (B) \\/ Battle dB (D) \\/ Day Outer dB (L)\"},{\"t\":5,\"p\":1,\"n\":\"NAM9 - Explore dB (D) \\/ Day Middle dB (L)\"},{\"t\":5,\"p\":1,\"n\":\"NAM0 - Suspense dB (D) \\/ Day Inner dB (L)\"},{\"t\":5,\"p\":1,\"n\":\"ANAM - Night Outer dB (L)\"},{\"t\":5,\"p\":1,\"n\":\"BNAM - Night Middle dB (L)\"},{\"t\":5,\"p\":1,\"n\":\"CNAM - Night Inner dB (L)\"},{\"t\":5,\"p\":1,\"n\":\"JNAM - Day Outer Boundary % (L)\"},{\"t\":5,\"p\":1,\"n\":\"KNAM - Day Middle Boundary % (L)\"},{\"t\":5,\"p\":1,\"n\":\"LNAM - Day Inner Boundary % (L)\"},{\"t\":5,\"p\":1,\"n\":\"MNAM - Night Outer Boundary % (L)\"},{\"t\":5,\"p\":1,\"n\":\"NNAM - Night Middle Boundary % (L)\"},{\"t\":5,\"p\":1,\"n\":\"ONAM - Night Inner Boundary % (L)\"},{\"t\":3,\"p\":1,\"n\":\"PNAM - Enable Flags\"},{\"t\":5,\"p\":1,\"n\":\"DNAM - Wait Time (B) \\/ Minimum Time On (D,L) \\/ Daytime Min (I)\"},{\"t\":5,\"p\":1,\"n\":\"ENAM - Loop Fade Out (B) \\/ Looping\\/Random Crossfade Overlap (D,L) \\/ Nighttime Min (I)\"},{\"t\":5,\"p\":1,\"n\":\"FNAM - Recovery Time (B) \\/ Layer Crossfade Time (D,L) \\/ Daytime Max (I)\"},{\"t\":5,\"p\":1,\"n\":\"GNAM - Nighttime Max (I)\"},{\"t\":3,\"p\":1,\"n\":\"HNAM - Intro (B,D) \\/ Daytime (I)\"},{\"t\":3,\"p\":1,\"n\":\"INAM - Outro (B,D) \\/ Nighttime (I)\"},{\"t\":11,\"n\":\"DATA - Unknown\"}]},{\"t\":1,\"p\":1,\"n\":\"MSTT - Moveable Static\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"X1\"},{\"t\":3,\"p\":1,\"n\":\"Y1\"},{\"t\":3,\"p\":1,\"n\":\"Z1\"},{\"t\":3,\"p\":1,\"n\":\"X2\"},{\"t\":3,\"p\":1,\"n\":\"Y2\"},{\"t\":3,\"p\":1,\"n\":\"Z2\"}]},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"},{\"t\":11,\"n\":\"MODB - Unknown\"},{\"t\":11,\"p\":1,\"n\":\"MODT - Texture Files Hashes\"},{\"t\":7,\"p\":1,\"n\":\"MODS - Alternate Textures\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"3D Name\"},{\"t\":3,\"p\":1,\"n\":\"New Texture\"},{\"t\":3,\"p\":1,\"n\":\"3D Index\"}]}]},{\"t\":3,\"p\":1,\"n\":\"MODD - FaceGen Model Flags\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Destructable\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"DEST - Header\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Health\"},{\"t\":3,\"p\":1,\"n\":\"Count\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":8,\"p\":1,\"n\":\"Stages\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Stage\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"DSTD - Destruction Stage Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Health %\"},{\"t\":3,\"p\":1,\"n\":\"Index\"},{\"t\":3,\"p\":1,\"n\":\"Damage Stage\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":3,\"p\":1,\"n\":\"Self Damage per Second\"},{\"t\":3,\"p\":1,\"n\":\"Explosion\"},{\"t\":3,\"p\":1,\"n\":\"Debris\"},{\"t\":3,\"p\":1,\"n\":\"Debris Count\"}]},{\"t\":6,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"DMDL - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"DMDT - Texture Files Hashes\"}]},{\"p\":1,\"n\":\"DSTF - End Marker\"}]}]}]},{\"t\":11,\"n\":\"DATA - Unknown\"},{\"t\":3,\"p\":1,\"n\":\"SNAM - Sound\"}]},{\"t\":1,\"p\":1,\"n\":\"MUSC - Music Type\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"p\":1,\"n\":\"FNAM - Filename\"},{\"t\":5,\"p\":1,\"n\":\"ANAM - dB (positive = Loop)\"}]},{\"t\":1,\"p\":1,\"n\":\"NOTE - Note\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"X1\"},{\"t\":3,\"p\":1,\"n\":\"Y1\"},{\"t\":3,\"p\":1,\"n\":\"Z1\"},{\"t\":3,\"p\":1,\"n\":\"X2\"},{\"t\":3,\"p\":1,\"n\":\"Y2\"},{\"t\":3,\"p\":1,\"n\":\"Z2\"}]},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"},{\"t\":11,\"n\":\"MODB - Unknown\"},{\"t\":11,\"p\":1,\"n\":\"MODT - Texture Files Hashes\"},{\"t\":7,\"p\":1,\"n\":\"MODS - Alternate Textures\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"3D Name\"},{\"t\":3,\"p\":1,\"n\":\"New Texture\"},{\"t\":3,\"p\":1,\"n\":\"3D Index\"}]}]},{\"t\":3,\"p\":1,\"n\":\"MODD - FaceGen Model Flags\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Icon\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"ICON - Large Icon filename\"},{\"t\":2,\"p\":1,\"n\":\"MICO - Small Icon filename\"}]},{\"t\":3,\"p\":1,\"n\":\"YNAM - Sound - Pick Up\"},{\"t\":3,\"p\":1,\"n\":\"ZNAM - Sound - Drop\"},{\"t\":3,\"p\":1,\"n\":\"DATA - Type\"},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Quests\",\"d\":1,\"c\":[{\"t\":3,\"p\":1,\"n\":\"ONAM - Quest\"}]},{\"t\":2,\"p\":1,\"n\":\"XNAM - Texture\"},{\"t\":2,\"p\":1,\"n\":\"Text\"},{\"t\":3,\"p\":1,\"n\":\"Topic\"},{\"t\":3,\"p\":1,\"n\":\"Sound\"},{\"t\":3,\"p\":1,\"n\":\"Actor\"}]},{\"t\":1,\"p\":1,\"n\":\"NPC_ - Non-Player Character\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"X1\"},{\"t\":3,\"p\":1,\"n\":\"Y1\"},{\"t\":3,\"p\":1,\"n\":\"Z1\"},{\"t\":3,\"p\":1,\"n\":\"X2\"},{\"t\":3,\"p\":1,\"n\":\"Y2\"},{\"t\":3,\"p\":1,\"n\":\"Z2\"}]},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"},{\"t\":11,\"n\":\"MODB - Unknown\"},{\"t\":11,\"p\":1,\"n\":\"MODT - Texture Files Hashes\"},{\"t\":7,\"p\":1,\"n\":\"MODS - Alternate Textures\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"3D Name\"},{\"t\":3,\"p\":1,\"n\":\"New Texture\"},{\"t\":3,\"p\":1,\"n\":\"3D Index\"}]}]},{\"t\":3,\"p\":1,\"n\":\"MODD - FaceGen Model Flags\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"ACBS - Configuration\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":3,\"p\":1,\"n\":\"Fatigue\"},{\"t\":3,\"p\":1,\"n\":\"Barter gold\"},{\"t\":3,\"p\":1,\"n\":\"Level\"},{\"t\":3,\"p\":1,\"n\":\"Level Mult\"},{\"t\":3,\"p\":1,\"n\":\"Calc min\"},{\"t\":3,\"p\":1,\"n\":\"Calc max\"},{\"t\":3,\"p\":1,\"n\":\"Speed Multiplier\"},{\"t\":5,\"p\":1,\"n\":\"Karma (Alignment)\"},{\"t\":3,\"p\":1,\"n\":\"Disposition Base\"},{\"t\":3,\"p\":1,\"n\":\"Template Flags\"}]},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Factions\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"SNAM - Faction\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Faction\"},{\"t\":3,\"p\":1,\"n\":\"Rank\"},{\"t\":11,\"n\":\"Unused\"}]}]},{\"t\":3,\"p\":1,\"n\":\"INAM - Death item\"},{\"t\":3,\"p\":1,\"n\":\"VTCK - Voice\"},{\"t\":3,\"p\":1,\"n\":\"TPLT - Template\"},{\"t\":3,\"p\":1,\"n\":\"RNAM - Race\"},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Actor Effects\",\"d\":1,\"c\":[{\"t\":3,\"p\":1,\"n\":\"SPLO - Actor Effect\"}]},{\"t\":3,\"p\":1,\"n\":\"EITM - Unarmed Attack Effect\"},{\"t\":3,\"p\":1,\"n\":\"EAMT - Unarmed Attack Animation\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Destructable\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"DEST - Header\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Health\"},{\"t\":3,\"p\":1,\"n\":\"Count\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":8,\"p\":1,\"n\":\"Stages\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Stage\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"DSTD - Destruction Stage Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Health %\"},{\"t\":3,\"p\":1,\"n\":\"Index\"},{\"t\":3,\"p\":1,\"n\":\"Damage Stage\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":3,\"p\":1,\"n\":\"Self Damage per Second\"},{\"t\":3,\"p\":1,\"n\":\"Explosion\"},{\"t\":3,\"p\":1,\"n\":\"Debris\"},{\"t\":3,\"p\":1,\"n\":\"Debris Count\"}]},{\"t\":6,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"DMDL - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"DMDT - Texture Files Hashes\"}]},{\"p\":1,\"n\":\"DSTF - End Marker\"}]}]}]},{\"t\":3,\"p\":1,\"n\":\"SCRI - Script\"},{\"t\":10,\"p\":1,\"n\":\"Items\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Item\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"CNTO - Item\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Item\"},{\"t\":3,\"p\":1,\"n\":\"Count\"}]},{\"t\":6,\"p\":1,\"n\":\"COED - Extra Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Owner\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Global Variable\"},{\"t\":3,\"p\":1,\"n\":\"Required Rank\"},{\"t\":5,\"p\":1,\"n\":\"Item Condition\"}]}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"AIDT - AI Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Aggression\"},{\"t\":3,\"p\":1,\"n\":\"Confidence\"},{\"t\":3,\"p\":1,\"n\":\"Energy Level\"},{\"t\":3,\"p\":1,\"n\":\"Responsibility\"},{\"t\":3,\"p\":1,\"n\":\"Mood\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Buys\\/Sells and Services\"},{\"t\":3,\"p\":1,\"n\":\"Teaches\"},{\"t\":3,\"p\":1,\"n\":\"Maximum training level\"},{\"t\":3,\"p\":1,\"n\":\"Assistance\"},{\"t\":3,\"p\":1,\"n\":\"Aggro Radius Behavior\"},{\"t\":3,\"p\":1,\"n\":\"Aggro Radius\"}]},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Packages\",\"d\":1,\"c\":[{\"t\":3,\"p\":1,\"n\":\"PKID - Package\"}]},{\"t\":7,\"p\":1,\"n\":\"KFFZ - Animations\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"Animation\"}]},{\"t\":3,\"p\":1,\"n\":\"CNAM - Class\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DATA - \",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Base Health\"},{\"t\":7,\"p\":1,\"n\":\"Attributes\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Attribute\"}]},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DNAM - \",\"c\":[{\"t\":7,\"p\":1,\"n\":\"Skill Values\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Skill\"}]},{\"t\":7,\"p\":1,\"n\":\"Skill Offsets\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Skill\"}]}]},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Head Parts\",\"d\":1,\"c\":[{\"t\":3,\"p\":1,\"n\":\"PNAM - Head Part\"}]},{\"t\":3,\"p\":1,\"n\":\"HNAM - Hair\"},{\"t\":5,\"p\":1,\"n\":\"LNAM - Hair length\"},{\"t\":3,\"p\":1,\"n\":\"ENAM - Eyes\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"HCLR - Hair color\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":3,\"p\":1,\"n\":\"ZNAM - Combat Style\"},{\"t\":3,\"p\":1,\"n\":\"NAM4 - Impact Material Type\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"FaceGen Data\",\"c\":[{\"t\":11,\"p\":1,\"n\":\"FGGS - FaceGen Geometry-Symmetric\"},{\"t\":11,\"p\":1,\"n\":\"FGGA - FaceGen Geometry-Asymmetric\"},{\"t\":11,\"p\":1,\"n\":\"FGTS - FaceGen Texture-Symmetric\"}]},{\"t\":3,\"n\":\"NAM5 - Unknown\"},{\"t\":5,\"p\":1,\"n\":\"NAM6 - Height\"},{\"t\":5,\"p\":1,\"n\":\"NAM7 - Weight\"}]},{\"t\":1,\"p\":1,\"n\":\"PACK - Package\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"PKDT - General\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"General Flags\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Fallout Behavior Flags\"},{\"p\":1,\"n\":\"Type Specific Flags (missing)\"},{\"t\":3,\"p\":1,\"n\":\"Type Specific Flags - Find\"},{\"t\":3,\"p\":1,\"n\":\"Type Specific Flags - Follow\"},{\"t\":3,\"p\":1,\"n\":\"Type Specific Flags - Escort\"},{\"t\":3,\"p\":1,\"n\":\"Type Specific Flags - Eat\"},{\"t\":3,\"p\":1,\"n\":\"Type Specific Flags - Sleep\"},{\"t\":3,\"p\":1,\"n\":\"Type Specific Flags - Wander\"},{\"t\":3,\"p\":1,\"n\":\"Type Specific Flags - Travel\"},{\"t\":3,\"p\":1,\"n\":\"Type Specific Flags - Accompany\"},{\"t\":3,\"p\":1,\"n\":\"Type Specific Flags - Use Item At\"},{\"t\":3,\"p\":1,\"n\":\"Type Specific Flags - Ambush\"},{\"t\":3,\"p\":1,\"n\":\"Type Specific Flags - Flee Not Combat\"},{\"t\":3,\"p\":1,\"n\":\"Type Specific Flags - ?\"},{\"t\":3,\"p\":1,\"n\":\"Type Specific Flags - Sandbox\"},{\"t\":3,\"p\":1,\"n\":\"Type Specific Flags - Patrol\"},{\"t\":3,\"p\":1,\"n\":\"Type Specific Flags - Guard\"},{\"t\":3,\"p\":1,\"n\":\"Type Specific Flags - Dialogue\"},{\"t\":3,\"p\":1,\"n\":\"Type Specific Flags - Use Weapon\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Locations\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"PLDT - Location 1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":3,\"p\":1,\"n\":\"Cell\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Object ID\"},{\"t\":3,\"p\":1,\"n\":\"Object Type\"},{\"t\":3,\"p\":1,\"n\":\"Radius\"}]},{\"t\":6,\"p\":1,\"n\":\"PLD2 - Location 2\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":3,\"p\":1,\"n\":\"Cell\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Object ID\"},{\"t\":3,\"p\":1,\"n\":\"Object Type\"},{\"t\":3,\"p\":1,\"n\":\"Radius\"}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"PSDT - Schedule\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Month\"},{\"t\":3,\"p\":1,\"n\":\"Day of week\"},{\"t\":3,\"p\":1,\"n\":\"Date\"},{\"t\":3,\"p\":1,\"n\":\"Time\"},{\"t\":3,\"p\":1,\"n\":\"Duration\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"PTDT - Target 1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":3,\"p\":1,\"n\":\"Object ID\"},{\"t\":3,\"p\":1,\"n\":\"Object Type\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Count \\/ Distance\"},{\"t\":5,\"n\":\"Unknown\"}]},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Conditions\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"CTDA - Condition\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":5,\"p\":1,\"n\":\"Comparison Value - Float\"},{\"t\":3,\"p\":1,\"n\":\"Comparison Value - Global\"},{\"t\":3,\"p\":1,\"n\":\"Function\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":11,\"p\":1,\"n\":\"None\"},{\"t\":3,\"p\":1,\"n\":\"Integer\"},{\"t\":3,\"p\":1,\"n\":\"Variable Name (INVALID)\"},{\"t\":3,\"p\":1,\"n\":\"Sex\"},{\"t\":3,\"p\":1,\"n\":\"Actor Value\"},{\"t\":3,\"p\":1,\"n\":\"Crime Type\"},{\"t\":3,\"p\":1,\"n\":\"Axis\"},{\"t\":3,\"p\":1,\"n\":\"Quest Stage (INVALID)\"},{\"t\":3,\"p\":1,\"n\":\"Misc Stat\"},{\"t\":3,\"p\":1,\"n\":\"Alignment\"},{\"t\":3,\"p\":1,\"n\":\"Equip Type\"},{\"t\":3,\"p\":1,\"n\":\"Form Type\"},{\"t\":3,\"p\":1,\"n\":\"Critical Stage\"},{\"t\":3,\"p\":1,\"n\":\"Object Reference\"},{\"t\":3,\"p\":1,\"n\":\"Inventory Object\"},{\"t\":3,\"p\":1,\"n\":\"Actor\"},{\"t\":3,\"p\":1,\"n\":\"Voice Type\"},{\"t\":3,\"p\":1,\"n\":\"Idle\"},{\"t\":3,\"p\":1,\"n\":\"Form List\"},{\"t\":3,\"p\":1,\"n\":\"Note\"},{\"t\":3,\"p\":1,\"n\":\"Quest\"},{\"t\":3,\"p\":1,\"n\":\"Faction\"},{\"t\":3,\"p\":1,\"n\":\"Weapon\"},{\"t\":3,\"p\":1,\"n\":\"Cell\"},{\"t\":3,\"p\":1,\"n\":\"Class\"},{\"t\":3,\"p\":1,\"n\":\"Race\"},{\"t\":3,\"p\":1,\"n\":\"Actor Base\"},{\"t\":3,\"p\":1,\"n\":\"Global\"},{\"t\":3,\"p\":1,\"n\":\"Weather\"},{\"t\":3,\"p\":1,\"n\":\"Package\"},{\"t\":3,\"p\":1,\"n\":\"Encounter Zone\"},{\"t\":3,\"p\":1,\"n\":\"Perk\"},{\"t\":3,\"p\":1,\"n\":\"Owner\"},{\"t\":3,\"p\":1,\"n\":\"Furniture\"},{\"t\":3,\"p\":1,\"n\":\"Effect Item\"},{\"t\":3,\"p\":1,\"n\":\"Base Effect\"},{\"t\":3,\"p\":1,\"n\":\"Worldspace\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Function\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Param (INVALID)\"},{\"t\":3,\"p\":1,\"n\":\"Creature Type\"},{\"t\":3,\"p\":1,\"n\":\"Menu Mode\"},{\"t\":3,\"p\":1,\"n\":\"Player Action\"},{\"t\":3,\"p\":1,\"n\":\"Body Location\"},{\"t\":3,\"p\":1,\"n\":\"Referenceable Object\"},{\"t\":3,\"p\":1,\"n\":\"Quest Objective (INVALID)\"},{\"t\":3,\"p\":1,\"n\":\"Reputation\"},{\"t\":3,\"p\":1,\"n\":\"Region\"},{\"t\":3,\"p\":1,\"n\":\"Challenge\"},{\"t\":3,\"p\":1,\"n\":\"Casino\"},{\"t\":3,\"p\":1,\"n\":\"Form\"},{\"t\":3,\"p\":1,\"n\":\"Variable Name\"},{\"t\":3,\"p\":1,\"n\":\"Quest Stage\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Function (INVALID)\"},{\"t\":3,\"p\":1,\"n\":\"Weapon List\"},{\"t\":3,\"p\":1,\"n\":\"Target\"},{\"t\":3,\"p\":1,\"n\":\"Target List\"},{\"t\":3,\"p\":1,\"n\":\"Target Part\"},{\"t\":3,\"p\":1,\"n\":\"VATS Action\"},{\"t\":3,\"p\":1,\"n\":\"Critical Effect\"},{\"t\":3,\"p\":1,\"n\":\"Critical Effect List\"},{\"t\":3,\"p\":1,\"n\":\"Weapon Type\"},{\"t\":3,\"p\":1,\"n\":\"Quest Objective\"},{\"t\":3,\"p\":1,\"n\":\"Run On\"},{\"t\":3,\"p\":1,\"n\":\"Reference\"}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Idle Animations\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"IDLF - Flags\"},{\"t\":6,\"p\":1,\"n\":\"IDLC - \",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Animation Count\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":5,\"p\":1,\"n\":\"IDLT - Idle Timer Setting\"},{\"t\":7,\"p\":1,\"n\":\"IDLA - Animations\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Animation\"}]},{\"t\":11,\"n\":\"IDLB - Unused\"}]},{\"t\":3,\"p\":1,\"n\":\"CNAM - Combat Style\"},{\"p\":1,\"n\":\"PKED - Eat Marker\"},{\"t\":3,\"p\":1,\"n\":\"PKE2 - Escort Distance\"},{\"t\":5,\"p\":1,\"n\":\"PKFD - Follow - Start Location - Trigger Radius\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"PKPT - Patrol Flags\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Repeatable\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"PKW3 - Use Weapon Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":3,\"p\":1,\"n\":\"Fire Rate\"},{\"t\":3,\"p\":1,\"n\":\"Fire Count\"},{\"t\":3,\"p\":1,\"n\":\"Number of Bursts\"},{\"t\":6,\"p\":1,\"n\":\"Shoots Per Volleys\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Min\"},{\"t\":3,\"p\":1,\"n\":\"Max\"}]},{\"t\":6,\"p\":1,\"n\":\"Pause Between Volleys\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Min\"},{\"t\":5,\"p\":1,\"n\":\"Max\"}]},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"PTD2 - Target 2\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":3,\"p\":1,\"n\":\"Object ID\"},{\"t\":3,\"p\":1,\"n\":\"Object Type\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Count \\/ Distance\"},{\"t\":5,\"n\":\"Unknown\"}]},{\"p\":1,\"n\":\"PUID - Use Item Marker\"},{\"p\":1,\"n\":\"PKAM - Ambush Marker\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"PKDD - Dialogue Data\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"FOV\"},{\"t\":3,\"p\":1,\"n\":\"Topic\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Dialogue Type\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"PLD2 - Location 2 (again??)\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":3,\"p\":1,\"n\":\"Cell\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Object ID\"},{\"t\":3,\"p\":1,\"n\":\"Object Type\"},{\"t\":3,\"p\":1,\"n\":\"Radius\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"OnBegin\",\"c\":[{\"p\":1,\"n\":\"POBA - OnBegin Marker\"},{\"t\":3,\"p\":1,\"n\":\"INAM - Idle\"},{\"t\":6,\"p\":1,\"n\":\"Embedded Script\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"SCHR - Basic Script Data\",\"c\":[{\"t\":11,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"RefCount\"},{\"t\":3,\"p\":1,\"n\":\"CompiledSize\"},{\"t\":3,\"p\":1,\"n\":\"VariableCount\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"}]},{\"t\":11,\"p\":1,\"n\":\"SCDA - Compiled Embedded Script\"},{\"t\":2,\"p\":1,\"n\":\"SCTX - Embedded Script Source\"},{\"t\":10,\"p\":1,\"n\":\"Local Variables\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Local Variable\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"SLSD - Local Variable Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Index\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"}]},{\"t\":2,\"p\":1,\"n\":\"SCVR - Name\"}]}]},{\"t\":8,\"p\":1,\"n\":\"References\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"SCRO - Global Reference\"},{\"t\":3,\"p\":1,\"n\":\"SCRV - Local Variable\"}]}]},{\"t\":3,\"p\":1,\"n\":\"TNAM - Topic\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"OnEnd\",\"c\":[{\"p\":1,\"n\":\"POEA - OnEnd Marker\"},{\"t\":3,\"p\":1,\"n\":\"INAM - Idle\"},{\"t\":6,\"p\":1,\"n\":\"Embedded Script\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"SCHR - Basic Script Data\",\"c\":[{\"t\":11,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"RefCount\"},{\"t\":3,\"p\":1,\"n\":\"CompiledSize\"},{\"t\":3,\"p\":1,\"n\":\"VariableCount\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"}]},{\"t\":11,\"p\":1,\"n\":\"SCDA - Compiled Embedded Script\"},{\"t\":2,\"p\":1,\"n\":\"SCTX - Embedded Script Source\"},{\"t\":10,\"p\":1,\"n\":\"Local Variables\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Local Variable\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"SLSD - Local Variable Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Index\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"}]},{\"t\":2,\"p\":1,\"n\":\"SCVR - Name\"}]}]},{\"t\":8,\"p\":1,\"n\":\"References\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"SCRO - Global Reference\"},{\"t\":3,\"p\":1,\"n\":\"SCRV - Local Variable\"}]}]},{\"t\":3,\"p\":1,\"n\":\"TNAM - Topic\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"OnChange\",\"c\":[{\"p\":1,\"n\":\"POCA - OnChange Marker\"},{\"t\":3,\"p\":1,\"n\":\"INAM - Idle\"},{\"t\":6,\"p\":1,\"n\":\"Embedded Script\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"SCHR - Basic Script Data\",\"c\":[{\"t\":11,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"RefCount\"},{\"t\":3,\"p\":1,\"n\":\"CompiledSize\"},{\"t\":3,\"p\":1,\"n\":\"VariableCount\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"}]},{\"t\":11,\"p\":1,\"n\":\"SCDA - Compiled Embedded Script\"},{\"t\":2,\"p\":1,\"n\":\"SCTX - Embedded Script Source\"},{\"t\":10,\"p\":1,\"n\":\"Local Variables\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Local Variable\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"SLSD - Local Variable Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Index\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"}]},{\"t\":2,\"p\":1,\"n\":\"SCVR - Name\"}]}]},{\"t\":8,\"p\":1,\"n\":\"References\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"SCRO - Global Reference\"},{\"t\":3,\"p\":1,\"n\":\"SCRV - Local Variable\"}]}]},{\"t\":3,\"p\":1,\"n\":\"TNAM - Topic\"}]}]},{\"t\":1,\"p\":1,\"n\":\"PBEA - Placed Beam\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":3,\"p\":1,\"n\":\"NAME - Base\"},{\"t\":3,\"p\":1,\"n\":\"XEZN - Encounter Zone\"},{\"t\":11,\"n\":\"XRGD - Ragdoll Data\"},{\"t\":11,\"n\":\"XRGB - Ragdoll Biped Data\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Patrol Data\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"XPRD - Idle Time\"},{\"p\":1,\"n\":\"XPPA - Patrol Script Marker\"},{\"t\":3,\"p\":1,\"n\":\"INAM - Idle\"},{\"t\":6,\"p\":1,\"n\":\"Embedded Script\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"SCHR - Basic Script Data\",\"c\":[{\"t\":11,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"RefCount\"},{\"t\":3,\"p\":1,\"n\":\"CompiledSize\"},{\"t\":3,\"p\":1,\"n\":\"VariableCount\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"}]},{\"t\":11,\"p\":1,\"n\":\"SCDA - Compiled Embedded Script\"},{\"t\":2,\"p\":1,\"n\":\"SCTX - Embedded Script Source\"},{\"t\":10,\"p\":1,\"n\":\"Local Variables\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Local Variable\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"SLSD - Local Variable Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Index\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"}]},{\"t\":2,\"p\":1,\"n\":\"SCVR - Name\"}]}]},{\"t\":8,\"p\":1,\"n\":\"References\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"SCRO - Global Reference\"},{\"t\":3,\"p\":1,\"n\":\"SCRV - Local Variable\"}]}]},{\"t\":3,\"p\":1,\"n\":\"TNAM - Topic\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Ownership\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"XOWN - Owner\"},{\"t\":3,\"p\":1,\"n\":\"XRNK - Faction rank\"}]},{\"t\":3,\"p\":1,\"n\":\"XCNT - Count\"},{\"t\":5,\"p\":1,\"n\":\"XRDS - Radius\"},{\"t\":5,\"p\":1,\"n\":\"XHLP - Health\"},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Reflected\\/Refracted By\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"XPWR - Water\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":3,\"p\":1,\"n\":\"Type\"}]}]},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Linked Decals\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"XDCR - Decal\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":11,\"n\":\"Unknown\"}]}]},{\"t\":3,\"p\":1,\"n\":\"XLKR - Linked Reference\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"XCLP - Linked Reference Color\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Link Start Color\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Link End Color\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Activate Parents\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"XAPD - Flags\"},{\"t\":8,\"p\":1,\"n\":\"Activate Parent Refs\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"XAPR - Activate Parent Ref\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":5,\"p\":1,\"n\":\"Delay\"}]}]}]},{\"t\":2,\"p\":1,\"n\":\"XATO - Activation Prompt\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"XESP - Enable Parent\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":3,\"p\":1,\"n\":\"XEMI - Emittance\"},{\"t\":3,\"p\":1,\"n\":\"XMBR - MultiBound Reference\"},{\"p\":1,\"n\":\"XIBS - Ignored By Sandbox\"},{\"t\":5,\"p\":1,\"n\":\"XSCL - Scale\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DATA - Position\\/Rotation\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Position\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"X\"},{\"t\":5,\"p\":1,\"n\":\"Y\"},{\"t\":5,\"p\":1,\"n\":\"Z\"}]},{\"t\":6,\"p\":1,\"n\":\"Rotation\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"X\"},{\"t\":5,\"p\":1,\"n\":\"Y\"},{\"t\":5,\"p\":1,\"n\":\"Z\"}]}]}]},{\"t\":1,\"p\":1,\"n\":\"PERK - Perk\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":2,\"p\":1,\"n\":\"DESC - Description\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Icon\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"ICON - Large Icon filename\"},{\"t\":2,\"p\":1,\"n\":\"MICO - Small Icon filename\"}]},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Conditions\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"CTDA - Condition\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":5,\"p\":1,\"n\":\"Comparison Value - Float\"},{\"t\":3,\"p\":1,\"n\":\"Comparison Value - Global\"},{\"t\":3,\"p\":1,\"n\":\"Function\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":11,\"p\":1,\"n\":\"None\"},{\"t\":3,\"p\":1,\"n\":\"Integer\"},{\"t\":3,\"p\":1,\"n\":\"Variable Name (INVALID)\"},{\"t\":3,\"p\":1,\"n\":\"Sex\"},{\"t\":3,\"p\":1,\"n\":\"Actor Value\"},{\"t\":3,\"p\":1,\"n\":\"Crime Type\"},{\"t\":3,\"p\":1,\"n\":\"Axis\"},{\"t\":3,\"p\":1,\"n\":\"Quest Stage (INVALID)\"},{\"t\":3,\"p\":1,\"n\":\"Misc Stat\"},{\"t\":3,\"p\":1,\"n\":\"Alignment\"},{\"t\":3,\"p\":1,\"n\":\"Equip Type\"},{\"t\":3,\"p\":1,\"n\":\"Form Type\"},{\"t\":3,\"p\":1,\"n\":\"Critical Stage\"},{\"t\":3,\"p\":1,\"n\":\"Object Reference\"},{\"t\":3,\"p\":1,\"n\":\"Inventory Object\"},{\"t\":3,\"p\":1,\"n\":\"Actor\"},{\"t\":3,\"p\":1,\"n\":\"Voice Type\"},{\"t\":3,\"p\":1,\"n\":\"Idle\"},{\"t\":3,\"p\":1,\"n\":\"Form List\"},{\"t\":3,\"p\":1,\"n\":\"Note\"},{\"t\":3,\"p\":1,\"n\":\"Quest\"},{\"t\":3,\"p\":1,\"n\":\"Faction\"},{\"t\":3,\"p\":1,\"n\":\"Weapon\"},{\"t\":3,\"p\":1,\"n\":\"Cell\"},{\"t\":3,\"p\":1,\"n\":\"Class\"},{\"t\":3,\"p\":1,\"n\":\"Race\"},{\"t\":3,\"p\":1,\"n\":\"Actor Base\"},{\"t\":3,\"p\":1,\"n\":\"Global\"},{\"t\":3,\"p\":1,\"n\":\"Weather\"},{\"t\":3,\"p\":1,\"n\":\"Package\"},{\"t\":3,\"p\":1,\"n\":\"Encounter Zone\"},{\"t\":3,\"p\":1,\"n\":\"Perk\"},{\"t\":3,\"p\":1,\"n\":\"Owner\"},{\"t\":3,\"p\":1,\"n\":\"Furniture\"},{\"t\":3,\"p\":1,\"n\":\"Effect Item\"},{\"t\":3,\"p\":1,\"n\":\"Base Effect\"},{\"t\":3,\"p\":1,\"n\":\"Worldspace\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Function\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Param (INVALID)\"},{\"t\":3,\"p\":1,\"n\":\"Creature Type\"},{\"t\":3,\"p\":1,\"n\":\"Menu Mode\"},{\"t\":3,\"p\":1,\"n\":\"Player Action\"},{\"t\":3,\"p\":1,\"n\":\"Body Location\"},{\"t\":3,\"p\":1,\"n\":\"Referenceable Object\"},{\"t\":3,\"p\":1,\"n\":\"Quest Objective (INVALID)\"},{\"t\":3,\"p\":1,\"n\":\"Reputation\"},{\"t\":3,\"p\":1,\"n\":\"Region\"},{\"t\":3,\"p\":1,\"n\":\"Challenge\"},{\"t\":3,\"p\":1,\"n\":\"Casino\"},{\"t\":3,\"p\":1,\"n\":\"Form\"},{\"t\":3,\"p\":1,\"n\":\"Variable Name\"},{\"t\":3,\"p\":1,\"n\":\"Quest Stage\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Function (INVALID)\"},{\"t\":3,\"p\":1,\"n\":\"Weapon List\"},{\"t\":3,\"p\":1,\"n\":\"Target\"},{\"t\":3,\"p\":1,\"n\":\"Target List\"},{\"t\":3,\"p\":1,\"n\":\"Target Part\"},{\"t\":3,\"p\":1,\"n\":\"VATS Action\"},{\"t\":3,\"p\":1,\"n\":\"Critical Effect\"},{\"t\":3,\"p\":1,\"n\":\"Critical Effect List\"},{\"t\":3,\"p\":1,\"n\":\"Weapon Type\"},{\"t\":3,\"p\":1,\"n\":\"Quest Objective\"},{\"t\":3,\"p\":1,\"n\":\"Run On\"},{\"t\":3,\"p\":1,\"n\":\"Reference\"}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DATA - Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Trait\"},{\"t\":3,\"p\":1,\"n\":\"Min Level\"},{\"t\":3,\"p\":1,\"n\":\"Ranks\"},{\"t\":3,\"p\":1,\"n\":\"Playable\"},{\"t\":3,\"p\":1,\"n\":\"Hidden\"}]},{\"t\":10,\"p\":1,\"n\":\"Effects\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Effect\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"PRKE - Header\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Rank\"},{\"t\":3,\"p\":1,\"n\":\"Priority\"}]},{\"t\":6,\"p\":1,\"n\":\"Quest + Stage\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Quest\"},{\"t\":3,\"p\":1,\"n\":\"Quest Stage\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":3,\"p\":1,\"n\":\"Ability\"},{\"t\":6,\"p\":1,\"n\":\"Entry Point\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Entry Point\"},{\"t\":3,\"p\":1,\"n\":\"Function\"},{\"t\":3,\"p\":1,\"n\":\"Perk Condition Tab Count\"}]},{\"t\":10,\"p\":1,\"n\":\"Perk Conditions\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Perk Condition\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"PRKC - Run On\"},{\"t\":8,\"p\":1,\"n\":\"Conditions\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"CTDA - Condition\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":5,\"p\":1,\"n\":\"Comparison Value - Float\"},{\"t\":3,\"p\":1,\"n\":\"Comparison Value - Global\"},{\"t\":3,\"p\":1,\"n\":\"Function\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":11,\"p\":1,\"n\":\"None\"},{\"t\":3,\"p\":1,\"n\":\"Integer\"},{\"t\":3,\"p\":1,\"n\":\"Variable Name (INVALID)\"},{\"t\":3,\"p\":1,\"n\":\"Sex\"},{\"t\":3,\"p\":1,\"n\":\"Actor Value\"},{\"t\":3,\"p\":1,\"n\":\"Crime Type\"},{\"t\":3,\"p\":1,\"n\":\"Axis\"},{\"t\":3,\"p\":1,\"n\":\"Quest Stage (INVALID)\"},{\"t\":3,\"p\":1,\"n\":\"Misc Stat\"},{\"t\":3,\"p\":1,\"n\":\"Alignment\"},{\"t\":3,\"p\":1,\"n\":\"Equip Type\"},{\"t\":3,\"p\":1,\"n\":\"Form Type\"},{\"t\":3,\"p\":1,\"n\":\"Critical Stage\"},{\"t\":3,\"p\":1,\"n\":\"Object Reference\"},{\"t\":3,\"p\":1,\"n\":\"Inventory Object\"},{\"t\":3,\"p\":1,\"n\":\"Actor\"},{\"t\":3,\"p\":1,\"n\":\"Voice Type\"},{\"t\":3,\"p\":1,\"n\":\"Idle\"},{\"t\":3,\"p\":1,\"n\":\"Form List\"},{\"t\":3,\"p\":1,\"n\":\"Note\"},{\"t\":3,\"p\":1,\"n\":\"Quest\"},{\"t\":3,\"p\":1,\"n\":\"Faction\"},{\"t\":3,\"p\":1,\"n\":\"Weapon\"},{\"t\":3,\"p\":1,\"n\":\"Cell\"},{\"t\":3,\"p\":1,\"n\":\"Class\"},{\"t\":3,\"p\":1,\"n\":\"Race\"},{\"t\":3,\"p\":1,\"n\":\"Actor Base\"},{\"t\":3,\"p\":1,\"n\":\"Global\"},{\"t\":3,\"p\":1,\"n\":\"Weather\"},{\"t\":3,\"p\":1,\"n\":\"Package\"},{\"t\":3,\"p\":1,\"n\":\"Encounter Zone\"},{\"t\":3,\"p\":1,\"n\":\"Perk\"},{\"t\":3,\"p\":1,\"n\":\"Owner\"},{\"t\":3,\"p\":1,\"n\":\"Furniture\"},{\"t\":3,\"p\":1,\"n\":\"Effect Item\"},{\"t\":3,\"p\":1,\"n\":\"Base Effect\"},{\"t\":3,\"p\":1,\"n\":\"Worldspace\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Function\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Param (INVALID)\"},{\"t\":3,\"p\":1,\"n\":\"Creature Type\"},{\"t\":3,\"p\":1,\"n\":\"Menu Mode\"},{\"t\":3,\"p\":1,\"n\":\"Player Action\"},{\"t\":3,\"p\":1,\"n\":\"Body Location\"},{\"t\":3,\"p\":1,\"n\":\"Referenceable Object\"},{\"t\":3,\"p\":1,\"n\":\"Quest Objective (INVALID)\"},{\"t\":3,\"p\":1,\"n\":\"Reputation\"},{\"t\":3,\"p\":1,\"n\":\"Region\"},{\"t\":3,\"p\":1,\"n\":\"Challenge\"},{\"t\":3,\"p\":1,\"n\":\"Casino\"},{\"t\":3,\"p\":1,\"n\":\"Form\"},{\"t\":3,\"p\":1,\"n\":\"Variable Name\"},{\"t\":3,\"p\":1,\"n\":\"Quest Stage\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Function (INVALID)\"},{\"t\":3,\"p\":1,\"n\":\"Weapon List\"},{\"t\":3,\"p\":1,\"n\":\"Target\"},{\"t\":3,\"p\":1,\"n\":\"Target List\"},{\"t\":3,\"p\":1,\"n\":\"Target Part\"},{\"t\":3,\"p\":1,\"n\":\"VATS Action\"},{\"t\":3,\"p\":1,\"n\":\"Critical Effect\"},{\"t\":3,\"p\":1,\"n\":\"Critical Effect List\"},{\"t\":3,\"p\":1,\"n\":\"Weapon Type\"},{\"t\":3,\"p\":1,\"n\":\"Quest Objective\"},{\"t\":3,\"p\":1,\"n\":\"Run On\"},{\"t\":3,\"p\":1,\"n\":\"Reference\"}]}]}]}]},{\"t\":6,\"p\":1,\"n\":\"Entry Point Function Parameters\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"EPFT - Type\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":6,\"p\":1,\"n\":\"Float, Float\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Float 1\"},{\"t\":5,\"p\":1,\"n\":\"Float 2\"}]},{\"t\":3,\"p\":1,\"n\":\"Leveled Item\"},{\"p\":1,\"n\":\"None (Script)\"},{\"t\":6,\"p\":1,\"n\":\"Actor Value, Float\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Actor Value\"},{\"t\":5,\"p\":1,\"n\":\"Float\"}]},{\"t\":2,\"p\":1,\"n\":\"EPF2 - Button Label\"},{\"t\":3,\"p\":1,\"n\":\"EPF3 - Script Flags\"},{\"t\":6,\"p\":1,\"n\":\"Embedded Script\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"SCHR - Basic Script Data\",\"c\":[{\"t\":11,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"RefCount\"},{\"t\":3,\"p\":1,\"n\":\"CompiledSize\"},{\"t\":3,\"p\":1,\"n\":\"VariableCount\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"}]},{\"t\":11,\"p\":1,\"n\":\"SCDA - Compiled Embedded Script\"},{\"t\":2,\"p\":1,\"n\":\"SCTX - Embedded Script Source\"},{\"t\":10,\"p\":1,\"n\":\"Local Variables\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Local Variable\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"SLSD - Local Variable Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Index\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"}]},{\"t\":2,\"p\":1,\"n\":\"SCVR - Name\"}]}]},{\"t\":8,\"p\":1,\"n\":\"References\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"SCRO - Global Reference\"},{\"t\":3,\"p\":1,\"n\":\"SCRV - Local Variable\"}]}]}]},{\"p\":1,\"n\":\"PRKF - End Marker\"}]}]}]},{\"t\":1,\"p\":1,\"n\":\"PGRE - Placed Grenade\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":3,\"p\":1,\"n\":\"NAME - Base\"},{\"t\":3,\"p\":1,\"n\":\"XEZN - Encounter Zone\"},{\"t\":11,\"n\":\"XRGD - Ragdoll Data\"},{\"t\":11,\"n\":\"XRGB - Ragdoll Biped Data\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Patrol Data\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"XPRD - Idle Time\"},{\"p\":1,\"n\":\"XPPA - Patrol Script Marker\"},{\"t\":3,\"p\":1,\"n\":\"INAM - Idle\"},{\"t\":6,\"p\":1,\"n\":\"Embedded Script\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"SCHR - Basic Script Data\",\"c\":[{\"t\":11,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"RefCount\"},{\"t\":3,\"p\":1,\"n\":\"CompiledSize\"},{\"t\":3,\"p\":1,\"n\":\"VariableCount\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"}]},{\"t\":11,\"p\":1,\"n\":\"SCDA - Compiled Embedded Script\"},{\"t\":2,\"p\":1,\"n\":\"SCTX - Embedded Script Source\"},{\"t\":10,\"p\":1,\"n\":\"Local Variables\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Local Variable\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"SLSD - Local Variable Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Index\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"}]},{\"t\":2,\"p\":1,\"n\":\"SCVR - Name\"}]}]},{\"t\":8,\"p\":1,\"n\":\"References\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"SCRO - Global Reference\"},{\"t\":3,\"p\":1,\"n\":\"SCRV - Local Variable\"}]}]},{\"t\":3,\"p\":1,\"n\":\"TNAM - Topic\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Ownership\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"XOWN - Owner\"},{\"t\":3,\"p\":1,\"n\":\"XRNK - Faction rank\"}]},{\"t\":3,\"p\":1,\"n\":\"XCNT - Count\"},{\"t\":5,\"p\":1,\"n\":\"XRDS - Radius\"},{\"t\":5,\"p\":1,\"n\":\"XHLP - Health\"},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Reflected\\/Refracted By\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"XPWR - Water\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":3,\"p\":1,\"n\":\"Type\"}]}]},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Linked Decals\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"XDCR - Decal\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":11,\"n\":\"Unknown\"}]}]},{\"t\":3,\"p\":1,\"n\":\"XLKR - Linked Reference\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"XCLP - Linked Reference Color\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Link Start Color\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Link End Color\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Activate Parents\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"XAPD - Flags\"},{\"t\":8,\"p\":1,\"n\":\"Activate Parent Refs\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"XAPR - Activate Parent Ref\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":5,\"p\":1,\"n\":\"Delay\"}]}]}]},{\"t\":2,\"p\":1,\"n\":\"XATO - Activation Prompt\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"XESP - Enable Parent\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":3,\"p\":1,\"n\":\"XEMI - Emittance\"},{\"t\":3,\"p\":1,\"n\":\"XMBR - MultiBound Reference\"},{\"p\":1,\"n\":\"XIBS - Ignored By Sandbox\"},{\"t\":5,\"p\":1,\"n\":\"XSCL - Scale\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DATA - Position\\/Rotation\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Position\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"X\"},{\"t\":5,\"p\":1,\"n\":\"Y\"},{\"t\":5,\"p\":1,\"n\":\"Z\"}]},{\"t\":6,\"p\":1,\"n\":\"Rotation\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"X\"},{\"t\":5,\"p\":1,\"n\":\"Y\"},{\"t\":5,\"p\":1,\"n\":\"Z\"}]}]}]},{\"t\":1,\"p\":1,\"n\":\"PMIS - Placed Missile\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":3,\"p\":1,\"n\":\"NAME - Base\"},{\"t\":3,\"p\":1,\"n\":\"XEZN - Encounter Zone\"},{\"t\":11,\"n\":\"XRGD - Ragdoll Data\"},{\"t\":11,\"n\":\"XRGB - Ragdoll Biped Data\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Patrol Data\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"XPRD - Idle Time\"},{\"p\":1,\"n\":\"XPPA - Patrol Script Marker\"},{\"t\":3,\"p\":1,\"n\":\"INAM - Idle\"},{\"t\":6,\"p\":1,\"n\":\"Embedded Script\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"SCHR - Basic Script Data\",\"c\":[{\"t\":11,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"RefCount\"},{\"t\":3,\"p\":1,\"n\":\"CompiledSize\"},{\"t\":3,\"p\":1,\"n\":\"VariableCount\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"}]},{\"t\":11,\"p\":1,\"n\":\"SCDA - Compiled Embedded Script\"},{\"t\":2,\"p\":1,\"n\":\"SCTX - Embedded Script Source\"},{\"t\":10,\"p\":1,\"n\":\"Local Variables\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Local Variable\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"SLSD - Local Variable Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Index\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"}]},{\"t\":2,\"p\":1,\"n\":\"SCVR - Name\"}]}]},{\"t\":8,\"p\":1,\"n\":\"References\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"SCRO - Global Reference\"},{\"t\":3,\"p\":1,\"n\":\"SCRV - Local Variable\"}]}]},{\"t\":3,\"p\":1,\"n\":\"TNAM - Topic\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Ownership\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"XOWN - Owner\"},{\"t\":3,\"p\":1,\"n\":\"XRNK - Faction rank\"}]},{\"t\":3,\"p\":1,\"n\":\"XCNT - Count\"},{\"t\":5,\"p\":1,\"n\":\"XRDS - Radius\"},{\"t\":5,\"p\":1,\"n\":\"XHLP - Health\"},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Reflected\\/Refracted By\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"XPWR - Water\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":3,\"p\":1,\"n\":\"Type\"}]}]},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Linked Decals\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"XDCR - Decal\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":11,\"n\":\"Unknown\"}]}]},{\"t\":3,\"p\":1,\"n\":\"XLKR - Linked Reference\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"XCLP - Linked Reference Color\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Link Start Color\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Link End Color\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Activate Parents\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"XAPD - Flags\"},{\"t\":8,\"p\":1,\"n\":\"Activate Parent Refs\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"XAPR - Activate Parent Ref\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":5,\"p\":1,\"n\":\"Delay\"}]}]}]},{\"t\":2,\"p\":1,\"n\":\"XATO - Activation Prompt\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"XESP - Enable Parent\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":3,\"p\":1,\"n\":\"XEMI - Emittance\"},{\"t\":3,\"p\":1,\"n\":\"XMBR - MultiBound Reference\"},{\"p\":1,\"n\":\"XIBS - Ignored By Sandbox\"},{\"t\":5,\"p\":1,\"n\":\"XSCL - Scale\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DATA - Position\\/Rotation\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Position\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"X\"},{\"t\":5,\"p\":1,\"n\":\"Y\"},{\"t\":5,\"p\":1,\"n\":\"Z\"}]},{\"t\":6,\"p\":1,\"n\":\"Rotation\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"X\"},{\"t\":5,\"p\":1,\"n\":\"Y\"},{\"t\":5,\"p\":1,\"n\":\"Z\"}]}]}]},{\"t\":1,\"p\":1,\"n\":\"PROJ - Projectile\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"X1\"},{\"t\":3,\"p\":1,\"n\":\"Y1\"},{\"t\":3,\"p\":1,\"n\":\"Z1\"},{\"t\":3,\"p\":1,\"n\":\"X2\"},{\"t\":3,\"p\":1,\"n\":\"Y2\"},{\"t\":3,\"p\":1,\"n\":\"Z2\"}]},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"},{\"t\":11,\"n\":\"MODB - Unknown\"},{\"t\":11,\"p\":1,\"n\":\"MODT - Texture Files Hashes\"},{\"t\":7,\"p\":1,\"n\":\"MODS - Alternate Textures\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"3D Name\"},{\"t\":3,\"p\":1,\"n\":\"New Texture\"},{\"t\":3,\"p\":1,\"n\":\"3D Index\"}]}]},{\"t\":3,\"p\":1,\"n\":\"MODD - FaceGen Model Flags\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Destructable\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"DEST - Header\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Health\"},{\"t\":3,\"p\":1,\"n\":\"Count\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":8,\"p\":1,\"n\":\"Stages\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Stage\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"DSTD - Destruction Stage Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Health %\"},{\"t\":3,\"p\":1,\"n\":\"Index\"},{\"t\":3,\"p\":1,\"n\":\"Damage Stage\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":3,\"p\":1,\"n\":\"Self Damage per Second\"},{\"t\":3,\"p\":1,\"n\":\"Explosion\"},{\"t\":3,\"p\":1,\"n\":\"Debris\"},{\"t\":3,\"p\":1,\"n\":\"Debris Count\"}]},{\"t\":6,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"DMDL - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"DMDT - Texture Files Hashes\"}]},{\"p\":1,\"n\":\"DSTF - End Marker\"}]}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DATA - Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":5,\"p\":1,\"n\":\"Gravity\"},{\"t\":5,\"p\":1,\"n\":\"Speed\"},{\"t\":5,\"p\":1,\"n\":\"Range\"},{\"t\":3,\"p\":1,\"n\":\"Light\"},{\"t\":3,\"p\":1,\"n\":\"Muzzle Flash - Light\"},{\"t\":5,\"p\":1,\"n\":\"Tracer Chance\"},{\"t\":5,\"p\":1,\"n\":\"Explosion - Alt. Trigger - Proximity\"},{\"t\":5,\"p\":1,\"n\":\"Explosion - Alt. Trigger - Timer\"},{\"t\":3,\"p\":1,\"n\":\"Explosion\"},{\"t\":3,\"p\":1,\"n\":\"Sound\"},{\"t\":5,\"p\":1,\"n\":\"Muzzle Flash - Duration\"},{\"t\":5,\"p\":1,\"n\":\"Fade Duration\"},{\"t\":5,\"p\":1,\"n\":\"Impact Force\"},{\"t\":3,\"p\":1,\"n\":\"Sound - Countdown\"},{\"t\":3,\"p\":1,\"n\":\"Sound - Disable\"},{\"t\":3,\"p\":1,\"n\":\"Default Weapon Source\"},{\"t\":6,\"p\":1,\"n\":\"Rotation\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"X\"},{\"t\":5,\"p\":1,\"n\":\"Y\"},{\"t\":5,\"p\":1,\"n\":\"Z\"}]},{\"t\":5,\"p\":1,\"n\":\"Bouncy Mult\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Muzzle Flash Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"NAM1 - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"NAM2 - Texture Files Hashes\"}]},{\"t\":3,\"p\":1,\"n\":\"VNAM - Sound Level\"}]},{\"t\":1,\"p\":1,\"n\":\"PWAT - Placeable Water\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"X1\"},{\"t\":3,\"p\":1,\"n\":\"Y1\"},{\"t\":3,\"p\":1,\"n\":\"Z1\"},{\"t\":3,\"p\":1,\"n\":\"X2\"},{\"t\":3,\"p\":1,\"n\":\"Y2\"},{\"t\":3,\"p\":1,\"n\":\"Z2\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"},{\"t\":11,\"n\":\"MODB - Unknown\"},{\"t\":11,\"p\":1,\"n\":\"MODT - Texture Files Hashes\"},{\"t\":7,\"p\":1,\"n\":\"MODS - Alternate Textures\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"3D Name\"},{\"t\":3,\"p\":1,\"n\":\"New Texture\"},{\"t\":3,\"p\":1,\"n\":\"3D Index\"}]}]},{\"t\":3,\"p\":1,\"n\":\"MODD - FaceGen Model Flags\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DNAM - \",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":3,\"p\":1,\"n\":\"Water\"}]}]},{\"t\":1,\"p\":1,\"n\":\"QUST - Quest\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":3,\"p\":1,\"n\":\"SCRI - Script\"},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Icon\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"ICON - Large Icon filename\"},{\"t\":2,\"p\":1,\"n\":\"MICO - Small Icon filename\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DATA - General\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":3,\"p\":1,\"n\":\"Priority\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":5,\"p\":1,\"n\":\"Quest Delay\"}]},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Conditions\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"CTDA - Condition\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":5,\"p\":1,\"n\":\"Comparison Value - Float\"},{\"t\":3,\"p\":1,\"n\":\"Comparison Value - Global\"},{\"t\":3,\"p\":1,\"n\":\"Function\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":11,\"p\":1,\"n\":\"None\"},{\"t\":3,\"p\":1,\"n\":\"Integer\"},{\"t\":3,\"p\":1,\"n\":\"Variable Name (INVALID)\"},{\"t\":3,\"p\":1,\"n\":\"Sex\"},{\"t\":3,\"p\":1,\"n\":\"Actor Value\"},{\"t\":3,\"p\":1,\"n\":\"Crime Type\"},{\"t\":3,\"p\":1,\"n\":\"Axis\"},{\"t\":3,\"p\":1,\"n\":\"Quest Stage (INVALID)\"},{\"t\":3,\"p\":1,\"n\":\"Misc Stat\"},{\"t\":3,\"p\":1,\"n\":\"Alignment\"},{\"t\":3,\"p\":1,\"n\":\"Equip Type\"},{\"t\":3,\"p\":1,\"n\":\"Form Type\"},{\"t\":3,\"p\":1,\"n\":\"Critical Stage\"},{\"t\":3,\"p\":1,\"n\":\"Object Reference\"},{\"t\":3,\"p\":1,\"n\":\"Inventory Object\"},{\"t\":3,\"p\":1,\"n\":\"Actor\"},{\"t\":3,\"p\":1,\"n\":\"Voice Type\"},{\"t\":3,\"p\":1,\"n\":\"Idle\"},{\"t\":3,\"p\":1,\"n\":\"Form List\"},{\"t\":3,\"p\":1,\"n\":\"Note\"},{\"t\":3,\"p\":1,\"n\":\"Quest\"},{\"t\":3,\"p\":1,\"n\":\"Faction\"},{\"t\":3,\"p\":1,\"n\":\"Weapon\"},{\"t\":3,\"p\":1,\"n\":\"Cell\"},{\"t\":3,\"p\":1,\"n\":\"Class\"},{\"t\":3,\"p\":1,\"n\":\"Race\"},{\"t\":3,\"p\":1,\"n\":\"Actor Base\"},{\"t\":3,\"p\":1,\"n\":\"Global\"},{\"t\":3,\"p\":1,\"n\":\"Weather\"},{\"t\":3,\"p\":1,\"n\":\"Package\"},{\"t\":3,\"p\":1,\"n\":\"Encounter Zone\"},{\"t\":3,\"p\":1,\"n\":\"Perk\"},{\"t\":3,\"p\":1,\"n\":\"Owner\"},{\"t\":3,\"p\":1,\"n\":\"Furniture\"},{\"t\":3,\"p\":1,\"n\":\"Effect Item\"},{\"t\":3,\"p\":1,\"n\":\"Base Effect\"},{\"t\":3,\"p\":1,\"n\":\"Worldspace\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Function\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Param (INVALID)\"},{\"t\":3,\"p\":1,\"n\":\"Creature Type\"},{\"t\":3,\"p\":1,\"n\":\"Menu Mode\"},{\"t\":3,\"p\":1,\"n\":\"Player Action\"},{\"t\":3,\"p\":1,\"n\":\"Body Location\"},{\"t\":3,\"p\":1,\"n\":\"Referenceable Object\"},{\"t\":3,\"p\":1,\"n\":\"Quest Objective (INVALID)\"},{\"t\":3,\"p\":1,\"n\":\"Reputation\"},{\"t\":3,\"p\":1,\"n\":\"Region\"},{\"t\":3,\"p\":1,\"n\":\"Challenge\"},{\"t\":3,\"p\":1,\"n\":\"Casino\"},{\"t\":3,\"p\":1,\"n\":\"Form\"},{\"t\":3,\"p\":1,\"n\":\"Variable Name\"},{\"t\":3,\"p\":1,\"n\":\"Quest Stage\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Function (INVALID)\"},{\"t\":3,\"p\":1,\"n\":\"Weapon List\"},{\"t\":3,\"p\":1,\"n\":\"Target\"},{\"t\":3,\"p\":1,\"n\":\"Target List\"},{\"t\":3,\"p\":1,\"n\":\"Target Part\"},{\"t\":3,\"p\":1,\"n\":\"VATS Action\"},{\"t\":3,\"p\":1,\"n\":\"Critical Effect\"},{\"t\":3,\"p\":1,\"n\":\"Critical Effect List\"},{\"t\":3,\"p\":1,\"n\":\"Weapon Type\"},{\"t\":3,\"p\":1,\"n\":\"Quest Objective\"},{\"t\":3,\"p\":1,\"n\":\"Run On\"},{\"t\":3,\"p\":1,\"n\":\"Reference\"}]}]},{\"t\":10,\"p\":1,\"n\":\"Stages\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Stage\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"INDX - Stage Index\"},{\"t\":8,\"p\":1,\"n\":\"Log Entries\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Log Entry\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"QSDT - Stage Flags\"},{\"t\":8,\"p\":1,\"n\":\"Conditions\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"CTDA - Condition\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":5,\"p\":1,\"n\":\"Comparison Value - Float\"},{\"t\":3,\"p\":1,\"n\":\"Comparison Value - Global\"},{\"t\":3,\"p\":1,\"n\":\"Function\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":11,\"p\":1,\"n\":\"None\"},{\"t\":3,\"p\":1,\"n\":\"Integer\"},{\"t\":3,\"p\":1,\"n\":\"Variable Name (INVALID)\"},{\"t\":3,\"p\":1,\"n\":\"Sex\"},{\"t\":3,\"p\":1,\"n\":\"Actor Value\"},{\"t\":3,\"p\":1,\"n\":\"Crime Type\"},{\"t\":3,\"p\":1,\"n\":\"Axis\"},{\"t\":3,\"p\":1,\"n\":\"Quest Stage (INVALID)\"},{\"t\":3,\"p\":1,\"n\":\"Misc Stat\"},{\"t\":3,\"p\":1,\"n\":\"Alignment\"},{\"t\":3,\"p\":1,\"n\":\"Equip Type\"},{\"t\":3,\"p\":1,\"n\":\"Form Type\"},{\"t\":3,\"p\":1,\"n\":\"Critical Stage\"},{\"t\":3,\"p\":1,\"n\":\"Object Reference\"},{\"t\":3,\"p\":1,\"n\":\"Inventory Object\"},{\"t\":3,\"p\":1,\"n\":\"Actor\"},{\"t\":3,\"p\":1,\"n\":\"Voice Type\"},{\"t\":3,\"p\":1,\"n\":\"Idle\"},{\"t\":3,\"p\":1,\"n\":\"Form List\"},{\"t\":3,\"p\":1,\"n\":\"Note\"},{\"t\":3,\"p\":1,\"n\":\"Quest\"},{\"t\":3,\"p\":1,\"n\":\"Faction\"},{\"t\":3,\"p\":1,\"n\":\"Weapon\"},{\"t\":3,\"p\":1,\"n\":\"Cell\"},{\"t\":3,\"p\":1,\"n\":\"Class\"},{\"t\":3,\"p\":1,\"n\":\"Race\"},{\"t\":3,\"p\":1,\"n\":\"Actor Base\"},{\"t\":3,\"p\":1,\"n\":\"Global\"},{\"t\":3,\"p\":1,\"n\":\"Weather\"},{\"t\":3,\"p\":1,\"n\":\"Package\"},{\"t\":3,\"p\":1,\"n\":\"Encounter Zone\"},{\"t\":3,\"p\":1,\"n\":\"Perk\"},{\"t\":3,\"p\":1,\"n\":\"Owner\"},{\"t\":3,\"p\":1,\"n\":\"Furniture\"},{\"t\":3,\"p\":1,\"n\":\"Effect Item\"},{\"t\":3,\"p\":1,\"n\":\"Base Effect\"},{\"t\":3,\"p\":1,\"n\":\"Worldspace\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Function\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Param (INVALID)\"},{\"t\":3,\"p\":1,\"n\":\"Creature Type\"},{\"t\":3,\"p\":1,\"n\":\"Menu Mode\"},{\"t\":3,\"p\":1,\"n\":\"Player Action\"},{\"t\":3,\"p\":1,\"n\":\"Body Location\"},{\"t\":3,\"p\":1,\"n\":\"Referenceable Object\"},{\"t\":3,\"p\":1,\"n\":\"Quest Objective (INVALID)\"},{\"t\":3,\"p\":1,\"n\":\"Reputation\"},{\"t\":3,\"p\":1,\"n\":\"Region\"},{\"t\":3,\"p\":1,\"n\":\"Challenge\"},{\"t\":3,\"p\":1,\"n\":\"Casino\"},{\"t\":3,\"p\":1,\"n\":\"Form\"},{\"t\":3,\"p\":1,\"n\":\"Variable Name\"},{\"t\":3,\"p\":1,\"n\":\"Quest Stage\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Function (INVALID)\"},{\"t\":3,\"p\":1,\"n\":\"Weapon List\"},{\"t\":3,\"p\":1,\"n\":\"Target\"},{\"t\":3,\"p\":1,\"n\":\"Target List\"},{\"t\":3,\"p\":1,\"n\":\"Target Part\"},{\"t\":3,\"p\":1,\"n\":\"VATS Action\"},{\"t\":3,\"p\":1,\"n\":\"Critical Effect\"},{\"t\":3,\"p\":1,\"n\":\"Critical Effect List\"},{\"t\":3,\"p\":1,\"n\":\"Weapon Type\"},{\"t\":3,\"p\":1,\"n\":\"Quest Objective\"},{\"t\":3,\"p\":1,\"n\":\"Run On\"},{\"t\":3,\"p\":1,\"n\":\"Reference\"}]}]},{\"t\":2,\"p\":1,\"n\":\"CNAM - Log Entry\"},{\"t\":6,\"p\":1,\"n\":\"Embedded Script\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"SCHR - Basic Script Data\",\"c\":[{\"t\":11,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"RefCount\"},{\"t\":3,\"p\":1,\"n\":\"CompiledSize\"},{\"t\":3,\"p\":1,\"n\":\"VariableCount\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"}]},{\"t\":11,\"p\":1,\"n\":\"SCDA - Compiled Embedded Script\"},{\"t\":2,\"p\":1,\"n\":\"SCTX - Embedded Script Source\"},{\"t\":10,\"p\":1,\"n\":\"Local Variables\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Local Variable\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"SLSD - Local Variable Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Index\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"}]},{\"t\":2,\"p\":1,\"n\":\"SCVR - Name\"}]}]},{\"t\":8,\"p\":1,\"n\":\"References\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"SCRO - Global Reference\"},{\"t\":3,\"p\":1,\"n\":\"SCRV - Local Variable\"}]}]},{\"t\":3,\"p\":1,\"n\":\"NAM0 - Next Quest\"}]}]}]}]},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Objectives\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Objective\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"QOBJ - Objective Index\"},{\"t\":2,\"p\":1,\"n\":\"NNAM - Description\"},{\"t\":8,\"p\":1,\"n\":\"Targets\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Target\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"QSTA - Target\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Target\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":8,\"p\":1,\"n\":\"Conditions\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"CTDA - Condition\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":5,\"p\":1,\"n\":\"Comparison Value - Float\"},{\"t\":3,\"p\":1,\"n\":\"Comparison Value - Global\"},{\"t\":3,\"p\":1,\"n\":\"Function\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":11,\"p\":1,\"n\":\"None\"},{\"t\":3,\"p\":1,\"n\":\"Integer\"},{\"t\":3,\"p\":1,\"n\":\"Variable Name (INVALID)\"},{\"t\":3,\"p\":1,\"n\":\"Sex\"},{\"t\":3,\"p\":1,\"n\":\"Actor Value\"},{\"t\":3,\"p\":1,\"n\":\"Crime Type\"},{\"t\":3,\"p\":1,\"n\":\"Axis\"},{\"t\":3,\"p\":1,\"n\":\"Quest Stage (INVALID)\"},{\"t\":3,\"p\":1,\"n\":\"Misc Stat\"},{\"t\":3,\"p\":1,\"n\":\"Alignment\"},{\"t\":3,\"p\":1,\"n\":\"Equip Type\"},{\"t\":3,\"p\":1,\"n\":\"Form Type\"},{\"t\":3,\"p\":1,\"n\":\"Critical Stage\"},{\"t\":3,\"p\":1,\"n\":\"Object Reference\"},{\"t\":3,\"p\":1,\"n\":\"Inventory Object\"},{\"t\":3,\"p\":1,\"n\":\"Actor\"},{\"t\":3,\"p\":1,\"n\":\"Voice Type\"},{\"t\":3,\"p\":1,\"n\":\"Idle\"},{\"t\":3,\"p\":1,\"n\":\"Form List\"},{\"t\":3,\"p\":1,\"n\":\"Note\"},{\"t\":3,\"p\":1,\"n\":\"Quest\"},{\"t\":3,\"p\":1,\"n\":\"Faction\"},{\"t\":3,\"p\":1,\"n\":\"Weapon\"},{\"t\":3,\"p\":1,\"n\":\"Cell\"},{\"t\":3,\"p\":1,\"n\":\"Class\"},{\"t\":3,\"p\":1,\"n\":\"Race\"},{\"t\":3,\"p\":1,\"n\":\"Actor Base\"},{\"t\":3,\"p\":1,\"n\":\"Global\"},{\"t\":3,\"p\":1,\"n\":\"Weather\"},{\"t\":3,\"p\":1,\"n\":\"Package\"},{\"t\":3,\"p\":1,\"n\":\"Encounter Zone\"},{\"t\":3,\"p\":1,\"n\":\"Perk\"},{\"t\":3,\"p\":1,\"n\":\"Owner\"},{\"t\":3,\"p\":1,\"n\":\"Furniture\"},{\"t\":3,\"p\":1,\"n\":\"Effect Item\"},{\"t\":3,\"p\":1,\"n\":\"Base Effect\"},{\"t\":3,\"p\":1,\"n\":\"Worldspace\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Function\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Param (INVALID)\"},{\"t\":3,\"p\":1,\"n\":\"Creature Type\"},{\"t\":3,\"p\":1,\"n\":\"Menu Mode\"},{\"t\":3,\"p\":1,\"n\":\"Player Action\"},{\"t\":3,\"p\":1,\"n\":\"Body Location\"},{\"t\":3,\"p\":1,\"n\":\"Referenceable Object\"},{\"t\":3,\"p\":1,\"n\":\"Quest Objective (INVALID)\"},{\"t\":3,\"p\":1,\"n\":\"Reputation\"},{\"t\":3,\"p\":1,\"n\":\"Region\"},{\"t\":3,\"p\":1,\"n\":\"Challenge\"},{\"t\":3,\"p\":1,\"n\":\"Casino\"},{\"t\":3,\"p\":1,\"n\":\"Form\"},{\"t\":3,\"p\":1,\"n\":\"Variable Name\"},{\"t\":3,\"p\":1,\"n\":\"Quest Stage\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Function (INVALID)\"},{\"t\":3,\"p\":1,\"n\":\"Weapon List\"},{\"t\":3,\"p\":1,\"n\":\"Target\"},{\"t\":3,\"p\":1,\"n\":\"Target List\"},{\"t\":3,\"p\":1,\"n\":\"Target Part\"},{\"t\":3,\"p\":1,\"n\":\"VATS Action\"},{\"t\":3,\"p\":1,\"n\":\"Critical Effect\"},{\"t\":3,\"p\":1,\"n\":\"Critical Effect List\"},{\"t\":3,\"p\":1,\"n\":\"Weapon Type\"},{\"t\":3,\"p\":1,\"n\":\"Quest Objective\"},{\"t\":3,\"p\":1,\"n\":\"Run On\"},{\"t\":3,\"p\":1,\"n\":\"Reference\"}]}]}]}]}]}]}]},{\"t\":1,\"p\":1,\"n\":\"RACE - Race\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":2,\"p\":1,\"n\":\"DESC - Description\"},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Relations\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"XNAM - Relation\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Faction\"},{\"t\":3,\"p\":1,\"n\":\"Modifier\"},{\"t\":3,\"p\":1,\"n\":\"Group Combat Reaction\"}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DATA - \",\"c\":[{\"t\":7,\"p\":1,\"n\":\"Skill Boosts\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Skill Boost\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Skill\"},{\"t\":3,\"p\":1,\"n\":\"Boost\"}]}]},{\"t\":11,\"n\":\"Unused\"},{\"t\":5,\"p\":1,\"n\":\"Male Height\"},{\"t\":5,\"p\":1,\"n\":\"Female Height\"},{\"t\":5,\"p\":1,\"n\":\"Male Weight\"},{\"t\":5,\"p\":1,\"n\":\"Female Weight\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"}]},{\"t\":3,\"p\":1,\"n\":\"ONAM - Older\"},{\"t\":3,\"p\":1,\"n\":\"YNAM - Younger\"},{\"n\":\"NAM2 - Unknown Marker\"},{\"t\":7,\"s\":1,\"p\":1,\"n\":\"VTCK - Voices\",\"d\":1,\"c\":[{\"t\":3,\"p\":1,\"n\":\"Voice\"}]},{\"t\":7,\"s\":1,\"p\":1,\"n\":\"DNAM - Default Hair Styles\",\"d\":1,\"c\":[{\"t\":3,\"p\":1,\"n\":\"Default Hair Style\"}]},{\"t\":7,\"s\":1,\"p\":1,\"n\":\"CNAM - Default Hair Colors\",\"d\":1,\"c\":[{\"t\":3,\"p\":1,\"n\":\"Default Hair Color\"}]},{\"t\":5,\"p\":1,\"n\":\"PNAM - FaceGen - Main clamp\"},{\"t\":5,\"p\":1,\"n\":\"UNAM - FaceGen - Face clamp\"},{\"t\":11,\"n\":\"ATTR - Unused\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Head Data\",\"c\":[{\"p\":1,\"n\":\"NAM0 - Head Data Marker\"},{\"t\":6,\"p\":1,\"n\":\"Male Head Data\",\"c\":[{\"p\":1,\"n\":\"MNAM - Male Data Marker\"},{\"t\":10,\"p\":1,\"n\":\"Parts\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Part\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"INDX - Index\"},{\"t\":6,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"MODB - Unknown\"},{\"t\":11,\"p\":1,\"n\":\"MODT - Texture Files Hashes\"},{\"t\":7,\"p\":1,\"n\":\"MODS - Alternate Textures\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"3D Name\"},{\"t\":3,\"p\":1,\"n\":\"New Texture\"},{\"t\":3,\"p\":1,\"n\":\"3D Index\"}]}]},{\"t\":3,\"p\":1,\"n\":\"MODD - FaceGen Model Flags\"}]},{\"t\":6,\"p\":1,\"n\":\"Icon\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"ICON - Large Icon filename\"},{\"t\":2,\"p\":1,\"n\":\"MICO - Small Icon filename\"}]}]}]}]},{\"t\":6,\"p\":1,\"n\":\"Female Head Data\",\"c\":[{\"p\":1,\"n\":\"FNAM - Female Data Marker\"},{\"t\":10,\"p\":1,\"n\":\"Parts\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Part\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"INDX - Index\"},{\"t\":6,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"MODB - Unknown\"},{\"t\":11,\"p\":1,\"n\":\"MODT - Texture Files Hashes\"},{\"t\":7,\"p\":1,\"n\":\"MODS - Alternate Textures\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"3D Name\"},{\"t\":3,\"p\":1,\"n\":\"New Texture\"},{\"t\":3,\"p\":1,\"n\":\"3D Index\"}]}]},{\"t\":3,\"p\":1,\"n\":\"MODD - FaceGen Model Flags\"}]},{\"t\":6,\"p\":1,\"n\":\"Icon\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"ICON - Large Icon filename\"},{\"t\":2,\"p\":1,\"n\":\"MICO - Small Icon filename\"}]}]}]}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Body Data\",\"c\":[{\"p\":1,\"n\":\"NAM1 - Body Data Marker\"},{\"t\":6,\"p\":1,\"n\":\"Male Body Data\",\"c\":[{\"p\":1,\"n\":\"MNAM - Male Data Marker\"},{\"t\":10,\"p\":1,\"n\":\"Parts\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Part\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"INDX - Index\"},{\"t\":6,\"p\":1,\"n\":\"Icon\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"ICON - Large Icon filename\"},{\"t\":2,\"p\":1,\"n\":\"MICO - Small Icon filename\"}]},{\"t\":6,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"MODB - Unknown\"},{\"t\":11,\"p\":1,\"n\":\"MODT - Texture Files Hashes\"},{\"t\":7,\"p\":1,\"n\":\"MODS - Alternate Textures\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"3D Name\"},{\"t\":3,\"p\":1,\"n\":\"New Texture\"},{\"t\":3,\"p\":1,\"n\":\"3D Index\"}]}]},{\"t\":3,\"p\":1,\"n\":\"MODD - FaceGen Model Flags\"}]}]}]}]},{\"t\":6,\"p\":1,\"n\":\"Female Body Data\",\"c\":[{\"p\":1,\"n\":\"FNAM - Female Data Marker\"},{\"t\":10,\"p\":1,\"n\":\"Parts\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Part\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"INDX - Index\"},{\"t\":6,\"p\":1,\"n\":\"Icon\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"ICON - Large Icon filename\"},{\"t\":2,\"p\":1,\"n\":\"MICO - Small Icon filename\"}]},{\"t\":6,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"MODB - Unknown\"},{\"t\":11,\"p\":1,\"n\":\"MODT - Texture Files Hashes\"},{\"t\":7,\"p\":1,\"n\":\"MODS - Alternate Textures\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"3D Name\"},{\"t\":3,\"p\":1,\"n\":\"New Texture\"},{\"t\":3,\"p\":1,\"n\":\"3D Index\"}]}]},{\"t\":3,\"p\":1,\"n\":\"MODD - FaceGen Model Flags\"}]}]}]}]}]},{\"t\":7,\"s\":1,\"p\":1,\"n\":\"HNAM - Hairs\",\"d\":1,\"c\":[{\"t\":3,\"p\":1,\"n\":\"Hair\"}]},{\"t\":7,\"s\":1,\"p\":1,\"n\":\"ENAM - Eyes\",\"d\":1,\"c\":[{\"t\":3,\"p\":1,\"n\":\"Eye\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"FaceGen Data\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Male FaceGen Data\",\"c\":[{\"p\":1,\"n\":\"MNAM - Male Data Marker\"},{\"t\":6,\"p\":1,\"n\":\"FaceGen Data\",\"c\":[{\"t\":11,\"p\":1,\"n\":\"FGGS - FaceGen Geometry-Symmetric\"},{\"t\":11,\"p\":1,\"n\":\"FGGA - FaceGen Geometry-Asymmetric\"},{\"t\":11,\"p\":1,\"n\":\"FGTS - FaceGen Texture-Symmetric\"}]},{\"t\":3,\"n\":\"SNAM - Unknown\"}]},{\"t\":6,\"p\":1,\"n\":\"Female FaceGen Data\",\"c\":[{\"p\":1,\"n\":\"FNAM - Female Data Marker\"},{\"t\":6,\"p\":1,\"n\":\"FaceGen Data\",\"c\":[{\"t\":11,\"p\":1,\"n\":\"FGGS - FaceGen Geometry-Symmetric\"},{\"t\":11,\"p\":1,\"n\":\"FGGA - FaceGen Geometry-Asymmetric\"},{\"t\":11,\"p\":1,\"n\":\"FGTS - FaceGen Texture-Symmetric\"}]},{\"t\":3,\"n\":\"SNAM - Unknown\"}]}]}]},{\"t\":1,\"p\":1,\"n\":\"RADS - Radiation Stage\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DATA - \",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Trigger Threshold\"},{\"t\":3,\"p\":1,\"n\":\"Actor Effect\"}]}]},{\"t\":1,\"p\":1,\"n\":\"RCCT - Recipe Category\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":3,\"p\":1,\"n\":\"DATA - Flags\"}]},{\"t\":1,\"p\":1,\"n\":\"RCPE - Recipe\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Conditions\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"CTDA - Condition\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":5,\"p\":1,\"n\":\"Comparison Value - Float\"},{\"t\":3,\"p\":1,\"n\":\"Comparison Value - Global\"},{\"t\":3,\"p\":1,\"n\":\"Function\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":11,\"p\":1,\"n\":\"None\"},{\"t\":3,\"p\":1,\"n\":\"Integer\"},{\"t\":3,\"p\":1,\"n\":\"Variable Name (INVALID)\"},{\"t\":3,\"p\":1,\"n\":\"Sex\"},{\"t\":3,\"p\":1,\"n\":\"Actor Value\"},{\"t\":3,\"p\":1,\"n\":\"Crime Type\"},{\"t\":3,\"p\":1,\"n\":\"Axis\"},{\"t\":3,\"p\":1,\"n\":\"Quest Stage (INVALID)\"},{\"t\":3,\"p\":1,\"n\":\"Misc Stat\"},{\"t\":3,\"p\":1,\"n\":\"Alignment\"},{\"t\":3,\"p\":1,\"n\":\"Equip Type\"},{\"t\":3,\"p\":1,\"n\":\"Form Type\"},{\"t\":3,\"p\":1,\"n\":\"Critical Stage\"},{\"t\":3,\"p\":1,\"n\":\"Object Reference\"},{\"t\":3,\"p\":1,\"n\":\"Inventory Object\"},{\"t\":3,\"p\":1,\"n\":\"Actor\"},{\"t\":3,\"p\":1,\"n\":\"Voice Type\"},{\"t\":3,\"p\":1,\"n\":\"Idle\"},{\"t\":3,\"p\":1,\"n\":\"Form List\"},{\"t\":3,\"p\":1,\"n\":\"Note\"},{\"t\":3,\"p\":1,\"n\":\"Quest\"},{\"t\":3,\"p\":1,\"n\":\"Faction\"},{\"t\":3,\"p\":1,\"n\":\"Weapon\"},{\"t\":3,\"p\":1,\"n\":\"Cell\"},{\"t\":3,\"p\":1,\"n\":\"Class\"},{\"t\":3,\"p\":1,\"n\":\"Race\"},{\"t\":3,\"p\":1,\"n\":\"Actor Base\"},{\"t\":3,\"p\":1,\"n\":\"Global\"},{\"t\":3,\"p\":1,\"n\":\"Weather\"},{\"t\":3,\"p\":1,\"n\":\"Package\"},{\"t\":3,\"p\":1,\"n\":\"Encounter Zone\"},{\"t\":3,\"p\":1,\"n\":\"Perk\"},{\"t\":3,\"p\":1,\"n\":\"Owner\"},{\"t\":3,\"p\":1,\"n\":\"Furniture\"},{\"t\":3,\"p\":1,\"n\":\"Effect Item\"},{\"t\":3,\"p\":1,\"n\":\"Base Effect\"},{\"t\":3,\"p\":1,\"n\":\"Worldspace\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Function\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Param (INVALID)\"},{\"t\":3,\"p\":1,\"n\":\"Creature Type\"},{\"t\":3,\"p\":1,\"n\":\"Menu Mode\"},{\"t\":3,\"p\":1,\"n\":\"Player Action\"},{\"t\":3,\"p\":1,\"n\":\"Body Location\"},{\"t\":3,\"p\":1,\"n\":\"Referenceable Object\"},{\"t\":3,\"p\":1,\"n\":\"Quest Objective (INVALID)\"},{\"t\":3,\"p\":1,\"n\":\"Reputation\"},{\"t\":3,\"p\":1,\"n\":\"Region\"},{\"t\":3,\"p\":1,\"n\":\"Challenge\"},{\"t\":3,\"p\":1,\"n\":\"Casino\"},{\"t\":3,\"p\":1,\"n\":\"Form\"},{\"t\":3,\"p\":1,\"n\":\"Variable Name\"},{\"t\":3,\"p\":1,\"n\":\"Quest Stage\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Function (INVALID)\"},{\"t\":3,\"p\":1,\"n\":\"Weapon List\"},{\"t\":3,\"p\":1,\"n\":\"Target\"},{\"t\":3,\"p\":1,\"n\":\"Target List\"},{\"t\":3,\"p\":1,\"n\":\"Target Part\"},{\"t\":3,\"p\":1,\"n\":\"VATS Action\"},{\"t\":3,\"p\":1,\"n\":\"Critical Effect\"},{\"t\":3,\"p\":1,\"n\":\"Critical Effect List\"},{\"t\":3,\"p\":1,\"n\":\"Weapon Type\"},{\"t\":3,\"p\":1,\"n\":\"Quest Objective\"},{\"t\":3,\"p\":1,\"n\":\"Run On\"},{\"t\":3,\"p\":1,\"n\":\"Reference\"}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DATA - Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Skill\"},{\"t\":3,\"p\":1,\"n\":\"Level\"},{\"t\":3,\"p\":1,\"n\":\"Category\"},{\"t\":3,\"p\":1,\"n\":\"Sub-Category\"}]},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Ingredients\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Ingredient\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"RCIL - Item\"},{\"t\":3,\"p\":1,\"n\":\"RCQY - Quantity\"}]}]},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Outputs\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Output\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"RCOD - Item\"},{\"t\":3,\"p\":1,\"n\":\"RCQY - Quantity\"}]}]}]},{\"t\":1,\"p\":1,\"n\":\"REFR - Placed Object\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":11,\"n\":\"RCLR - Unused\"},{\"t\":3,\"p\":1,\"n\":\"NAME - Base\"},{\"t\":3,\"p\":1,\"n\":\"XEZN - Encounter Zone\"},{\"t\":11,\"n\":\"XRGD - Ragdoll Data\"},{\"t\":11,\"n\":\"XRGB - Ragdoll Biped Data\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"XPRM - Primitive\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Bounds\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"X\"},{\"t\":5,\"p\":1,\"n\":\"Y\"},{\"t\":5,\"p\":1,\"n\":\"Z\"}]},{\"t\":6,\"p\":1,\"n\":\"Color\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Red\"},{\"t\":5,\"p\":1,\"n\":\"Green\"},{\"t\":5,\"p\":1,\"n\":\"Blue\"}]},{\"t\":5,\"n\":\"Unknown\"},{\"t\":3,\"p\":1,\"n\":\"Type\"}]},{\"t\":3,\"p\":1,\"n\":\"XTRI - Collision Layer\"},{\"p\":1,\"n\":\"XMBP - MultiBound Primitive Marker\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"XMBO - Bound Half Extents\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"X\"},{\"t\":5,\"p\":1,\"n\":\"Y\"},{\"t\":5,\"p\":1,\"n\":\"Z\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"XTEL - Teleport Destination\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Door\"},{\"t\":6,\"p\":1,\"n\":\"Position\\/Rotation\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Position\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"X\"},{\"t\":5,\"p\":1,\"n\":\"Y\"},{\"t\":5,\"p\":1,\"n\":\"Z\"}]},{\"t\":6,\"p\":1,\"n\":\"Rotation\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"X\"},{\"t\":5,\"p\":1,\"n\":\"Y\"},{\"t\":5,\"p\":1,\"n\":\"Z\"}]}]},{\"t\":3,\"p\":1,\"n\":\"Flags\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Map Marker\",\"c\":[{\"p\":1,\"n\":\"XMRK - Map Marker Data\"},{\"t\":3,\"p\":1,\"n\":\"FNAM - Flags\"},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":6,\"p\":1,\"n\":\"TNAM - \",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":3,\"p\":1,\"n\":\"WMI1 - Reputation\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Audio Data\",\"c\":[{\"p\":1,\"n\":\"MMRK - Audio Marker\"},{\"t\":11,\"n\":\"FULL - Unknown\"},{\"t\":3,\"p\":1,\"n\":\"CNAM - Audio Location\"},{\"t\":3,\"p\":1,\"n\":\"BNAM - Flags\"},{\"t\":5,\"p\":1,\"n\":\"MNAM - Layer 2 Trigger %\"},{\"t\":5,\"p\":1,\"n\":\"NNAM - Layer 3 Trigger %\"}]},{\"t\":3,\"p\":1,\"n\":\"XSRF - Special Rendering Flags\"},{\"t\":11,\"n\":\"XSRD - Special Rendering Data\"},{\"t\":3,\"p\":1,\"n\":\"XTRG - Target\"},{\"t\":3,\"p\":1,\"n\":\"XLCM - Level Modifier\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Patrol Data\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"XPRD - Idle Time\"},{\"p\":1,\"n\":\"XPPA - Patrol Script Marker\"},{\"t\":3,\"p\":1,\"n\":\"INAM - Idle\"},{\"t\":6,\"p\":1,\"n\":\"Embedded Script\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"SCHR - Basic Script Data\",\"c\":[{\"t\":11,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"RefCount\"},{\"t\":3,\"p\":1,\"n\":\"CompiledSize\"},{\"t\":3,\"p\":1,\"n\":\"VariableCount\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"}]},{\"t\":11,\"p\":1,\"n\":\"SCDA - Compiled Embedded Script\"},{\"t\":2,\"p\":1,\"n\":\"SCTX - Embedded Script Source\"},{\"t\":10,\"p\":1,\"n\":\"Local Variables\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Local Variable\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"SLSD - Local Variable Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Index\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"}]},{\"t\":2,\"p\":1,\"n\":\"SCVR - Name\"}]}]},{\"t\":8,\"p\":1,\"n\":\"References\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"SCRO - Global Reference\"},{\"t\":3,\"p\":1,\"n\":\"SCRV - Local Variable\"}]}]},{\"t\":3,\"p\":1,\"n\":\"TNAM - Topic\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"XRDO - Radio Data\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Range Radius\"},{\"t\":3,\"p\":1,\"n\":\"Broadcast Range Type\"},{\"t\":5,\"p\":1,\"n\":\"Static Percentage\"},{\"t\":3,\"p\":1,\"n\":\"Position Reference\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Ownership\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"XOWN - Owner\"},{\"t\":3,\"p\":1,\"n\":\"XRNK - Faction rank\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"XLOC - Lock Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Level\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Key\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":3,\"p\":1,\"n\":\"XCNT - Count\"},{\"t\":5,\"p\":1,\"n\":\"XRDS - Radius\"},{\"t\":5,\"p\":1,\"n\":\"XHLP - Health\"},{\"t\":5,\"p\":1,\"n\":\"XRAD - Radiation\"},{\"t\":5,\"p\":1,\"n\":\"XCHG - Charge\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Ammo\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"XAMT - Type\"},{\"t\":3,\"p\":1,\"n\":\"XAMC - Count\"}]},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Reflected\\/Refracted By\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"XPWR - Water\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":3,\"p\":1,\"n\":\"Type\"}]}]},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Lit Water\",\"d\":1,\"c\":[{\"t\":3,\"p\":1,\"n\":\"XLTW - Water\"}]},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Linked Decals\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"XDCR - Decal\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":11,\"n\":\"Unknown\"}]}]},{\"t\":3,\"p\":1,\"n\":\"XLKR - Linked Reference\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"XCLP - Linked Reference Color\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Link Start Color\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Link End Color\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Activate Parents\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"XAPD - Flags\"},{\"t\":8,\"p\":1,\"n\":\"Activate Parent Refs\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"XAPR - Activate Parent Ref\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":5,\"p\":1,\"n\":\"Delay\"}]}]}]},{\"t\":2,\"p\":1,\"n\":\"XATO - Activation Prompt\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"XESP - Enable Parent\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":3,\"p\":1,\"n\":\"XEMI - Emittance\"},{\"t\":3,\"p\":1,\"n\":\"XMBR - MultiBound Reference\"},{\"t\":3,\"p\":1,\"n\":\"XACT - Action Flag\"},{\"p\":1,\"n\":\"ONAM - Open by Default\"},{\"p\":1,\"n\":\"XIBS - Ignored By Sandbox\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"XNDP - Navigation Door Link\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Navigation Mesh\"},{\"t\":3,\"p\":1,\"n\":\"Teleport Marker Triangle\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":7,\"p\":1,\"n\":\"XPOD - Portal Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Room\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"XPTL - Portal Data\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Size\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Width\"},{\"t\":5,\"p\":1,\"n\":\"Height\"}]},{\"t\":6,\"p\":1,\"n\":\"Position\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"X\"},{\"t\":5,\"p\":1,\"n\":\"Y\"},{\"t\":5,\"p\":1,\"n\":\"Z\"}]},{\"t\":6,\"p\":1,\"n\":\"Rotation (Quaternion?)\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"q1\"},{\"t\":5,\"p\":1,\"n\":\"q2\"},{\"t\":5,\"p\":1,\"n\":\"q3\"},{\"t\":5,\"p\":1,\"n\":\"q4\"}]}]},{\"t\":3,\"p\":1,\"n\":\"XSED - SpeedTree Seed\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Room Data\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"XRMR - Header\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Linked Rooms Count\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":8,\"p\":1,\"n\":\"Linked Rooms\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"XLRM - Linked Room\"}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"XOCP - Occlusion Plane Data\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Size\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Width\"},{\"t\":5,\"p\":1,\"n\":\"Height\"}]},{\"t\":6,\"p\":1,\"n\":\"Position\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"X\"},{\"t\":5,\"p\":1,\"n\":\"Y\"},{\"t\":5,\"p\":1,\"n\":\"Z\"}]},{\"t\":6,\"p\":1,\"n\":\"Rotation (Quaternion?)\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"q1\"},{\"t\":5,\"p\":1,\"n\":\"q2\"},{\"t\":5,\"p\":1,\"n\":\"q3\"},{\"t\":5,\"p\":1,\"n\":\"q4\"}]}]},{\"t\":7,\"p\":1,\"n\":\"XORD - Linked Occlusion Planes\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Plane\"}]},{\"t\":7,\"n\":\"XLOD - Distant LOD Data\",\"c\":[{\"t\":5,\"n\":\"Unknown\"}]},{\"t\":5,\"p\":1,\"n\":\"XSCL - Scale\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DATA - Position\\/Rotation\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Position\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"X\"},{\"t\":5,\"p\":1,\"n\":\"Y\"},{\"t\":5,\"p\":1,\"n\":\"Z\"}]},{\"t\":6,\"p\":1,\"n\":\"Rotation\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"X\"},{\"t\":5,\"p\":1,\"n\":\"Y\"},{\"t\":5,\"p\":1,\"n\":\"Z\"}]}]}]},{\"t\":1,\"p\":1,\"n\":\"REGN - Region\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Icon\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"ICON - Large Icon filename\"},{\"t\":2,\"p\":1,\"n\":\"MICO - Small Icon filename\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"RCLR - Map Color\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":3,\"p\":1,\"n\":\"WNAM - Worldspace\"},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Region Areas\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Region Area\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"RPLI - Edge Fall-off\"},{\"t\":7,\"p\":1,\"n\":\"RPLD - Region Point List Data\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Point\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"X\"},{\"t\":5,\"p\":1,\"n\":\"Y\"}]}]}]}]},{\"t\":10,\"p\":1,\"n\":\"Region Data Entries\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Region Data Entry\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"RDAT - Data Header\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":3,\"p\":1,\"n\":\"Priority\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":7,\"p\":1,\"n\":\"RDOT - Objects\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Object\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Object\"},{\"t\":3,\"p\":1,\"n\":\"Parent Index\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":5,\"p\":1,\"n\":\"Density\"},{\"t\":3,\"p\":1,\"n\":\"Clustering\"},{\"t\":3,\"p\":1,\"n\":\"Min Slope\"},{\"t\":3,\"p\":1,\"n\":\"Max Slope\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":3,\"p\":1,\"n\":\"Radius wrt Parent\"},{\"t\":3,\"p\":1,\"n\":\"Radius\"},{\"t\":5,\"p\":1,\"n\":\"Min Height\"},{\"t\":5,\"p\":1,\"n\":\"Max Height\"},{\"t\":5,\"p\":1,\"n\":\"Sink\"},{\"t\":5,\"p\":1,\"n\":\"Sink Variance\"},{\"t\":5,\"p\":1,\"n\":\"Size Variance\"},{\"t\":6,\"p\":1,\"n\":\"Angle Variance\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"X\"},{\"t\":3,\"p\":1,\"n\":\"Y\"},{\"t\":3,\"p\":1,\"n\":\"Z\"}]},{\"t\":11,\"n\":\"Unknown\"}]}]},{\"t\":2,\"p\":1,\"n\":\"RDMP - Map Name\"},{\"t\":7,\"p\":1,\"n\":\"RDGS - Grasses\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Grass\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Grass\"},{\"t\":11,\"n\":\"Unknown\"}]}]},{\"t\":3,\"p\":1,\"n\":\"RDMD - Music Type\"},{\"t\":3,\"p\":1,\"n\":\"RDMO - Music\"},{\"t\":3,\"p\":1,\"n\":\"RDSI - Incidental MediaSet\"},{\"t\":8,\"p\":1,\"n\":\"Battle MediaSets\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"RDSB - Battle MediaSet\"}]},{\"t\":7,\"p\":1,\"n\":\"RDSD - Sounds\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Sound\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Sound\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":3,\"p\":1,\"n\":\"Chance\"}]}]},{\"t\":7,\"p\":1,\"n\":\"RDWT - Weather Types\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Weather Type\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Weather\"},{\"t\":3,\"p\":1,\"n\":\"Chance\"},{\"t\":3,\"p\":1,\"n\":\"Global\"}]}]},{\"t\":7,\"p\":1,\"n\":\"RDID - Imposters\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Imposter\"}]}]}]}]},{\"t\":1,\"p\":1,\"n\":\"REPU - Reputation\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Icon\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"ICON - Large Icon filename\"},{\"t\":2,\"p\":1,\"n\":\"MICO - Small Icon filename\"}]},{\"t\":5,\"p\":1,\"n\":\"DATA - Value\"}]},{\"t\":1,\"p\":1,\"n\":\"RGDL - Ragdoll\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":3,\"p\":1,\"n\":\"NVER - Version\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DATA - General Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Dynamic Bone Count\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":6,\"p\":1,\"n\":\"Enabled\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Feedback\"},{\"t\":3,\"p\":1,\"n\":\"Foot IK (broken, don't use)\"},{\"t\":3,\"p\":1,\"n\":\"Look IK (broken, don't use)\"},{\"t\":3,\"p\":1,\"n\":\"Grab IK (broken, don't use)\"},{\"t\":3,\"p\":1,\"n\":\"Pose Matching\"}]}]},{\"t\":3,\"p\":1,\"n\":\"XNAM - Actor Base\"},{\"t\":3,\"p\":1,\"n\":\"TNAM - Body Part Data\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"RAFD - Feedback Data\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Dynamic\\/Keyframe Blend Amount\"},{\"t\":5,\"p\":1,\"n\":\"Hierarchy Gain\"},{\"t\":5,\"p\":1,\"n\":\"Position Gain\"},{\"t\":5,\"p\":1,\"n\":\"Velocity Gain\"},{\"t\":5,\"p\":1,\"n\":\"Acceleration Gain\"},{\"t\":5,\"p\":1,\"n\":\"Snap Gain\"},{\"t\":5,\"p\":1,\"n\":\"Velocity Damping\"},{\"t\":6,\"p\":1,\"n\":\"Snap Max Settings\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Linear Velocity\"},{\"t\":5,\"p\":1,\"n\":\"Angular Velocity\"},{\"t\":5,\"p\":1,\"n\":\"Linear Distance\"},{\"t\":5,\"p\":1,\"n\":\"Angular Distance\"}]},{\"t\":6,\"p\":1,\"n\":\"Position Max Velocity\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Linear\"},{\"t\":5,\"p\":1,\"n\":\"Angular\"}]}]},{\"t\":7,\"p\":1,\"n\":\"RAFB - Feedback Dynamic Bones\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Bone\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"RAPS - Pose Matching Data\",\"c\":[{\"t\":7,\"p\":1,\"n\":\"Match Bones\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Bone\"}]},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":5,\"p\":1,\"n\":\"Motors Strength\"},{\"t\":5,\"p\":1,\"n\":\"Pose Activation Delay Time\"},{\"t\":5,\"p\":1,\"n\":\"Match Error Allowance\"},{\"t\":5,\"p\":1,\"n\":\"Displacement To Disable\"}]},{\"t\":2,\"p\":1,\"n\":\"ANAM - Death Pose\"}]},{\"t\":1,\"p\":1,\"n\":\"SCOL - Static Collection\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"X1\"},{\"t\":3,\"p\":1,\"n\":\"Y1\"},{\"t\":3,\"p\":1,\"n\":\"Z1\"},{\"t\":3,\"p\":1,\"n\":\"X2\"},{\"t\":3,\"p\":1,\"n\":\"Y2\"},{\"t\":3,\"p\":1,\"n\":\"Z2\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"},{\"t\":11,\"n\":\"MODB - Unknown\"},{\"t\":11,\"p\":1,\"n\":\"MODT - Texture Files Hashes\"},{\"t\":7,\"p\":1,\"n\":\"MODS - Alternate Textures\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"3D Name\"},{\"t\":3,\"p\":1,\"n\":\"New Texture\"},{\"t\":3,\"p\":1,\"n\":\"3D Index\"}]}]},{\"t\":3,\"p\":1,\"n\":\"MODD - FaceGen Model Flags\"}]},{\"t\":10,\"p\":1,\"n\":\"Parts\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Part\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"ONAM - Static\"},{\"t\":7,\"p\":1,\"n\":\"DATA - Placements\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Placement\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Position\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"X\"},{\"t\":5,\"p\":1,\"n\":\"Y\"},{\"t\":5,\"p\":1,\"n\":\"Z\"}]},{\"t\":6,\"p\":1,\"n\":\"Rotation\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"X\"},{\"t\":5,\"p\":1,\"n\":\"Y\"},{\"t\":5,\"p\":1,\"n\":\"Z\"}]},{\"t\":5,\"p\":1,\"n\":\"Scale\"}]}]}]}]}]},{\"t\":1,\"p\":1,\"n\":\"SCPT - Script\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"SCHR - Basic Script Data\",\"c\":[{\"t\":11,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"RefCount\"},{\"t\":3,\"p\":1,\"n\":\"CompiledSize\"},{\"t\":3,\"p\":1,\"n\":\"VariableCount\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"}]},{\"t\":11,\"n\":\"SCDA - Compiled Script\"},{\"t\":2,\"p\":1,\"n\":\"SCTX - Script Source\"},{\"t\":10,\"p\":1,\"n\":\"Local Variables\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Local Variable\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"SLSD - Local Variable Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Index\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"}]},{\"t\":2,\"p\":1,\"n\":\"SCVR - Name\"}]}]},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"References\",\"d\":1,\"c\":[{\"t\":3,\"p\":1,\"n\":\"SCRO - Global Reference\"},{\"t\":3,\"p\":1,\"n\":\"SCRV - Local Variable\"}]}]},{\"t\":1,\"p\":1,\"n\":\"SLPD - Sleep Deprivation Stage\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DATA - \",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Trigger Threshold\"},{\"t\":3,\"p\":1,\"n\":\"Actor Effect\"}]}]},{\"t\":1,\"p\":1,\"n\":\"SOUN - Sound\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"X1\"},{\"t\":3,\"p\":1,\"n\":\"Y1\"},{\"t\":3,\"p\":1,\"n\":\"Z1\"},{\"t\":3,\"p\":1,\"n\":\"X2\"},{\"t\":3,\"p\":1,\"n\":\"Y2\"},{\"t\":3,\"p\":1,\"n\":\"Z2\"}]},{\"t\":2,\"p\":1,\"n\":\"FNAM - Sound Filename\"},{\"t\":3,\"p\":1,\"n\":\"RNAM - Random Chance %\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"SNDD - Sound Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Minimum Attentuation Distance\"},{\"t\":3,\"p\":1,\"n\":\"Maximum Attentuation Distance\"},{\"t\":3,\"p\":1,\"n\":\"Frequency Adjustment %\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":3,\"p\":1,\"n\":\"Static attentuation cdB\"},{\"t\":3,\"p\":1,\"n\":\"Stop time \"},{\"t\":3,\"p\":1,\"n\":\"Start time \"},{\"t\":7,\"p\":1,\"n\":\"Attenuation Curve\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Point\"}]},{\"t\":3,\"p\":1,\"n\":\"Reverb Attenuation Control\"},{\"t\":3,\"p\":1,\"n\":\"Priority\"},{\"t\":3,\"p\":1,\"n\":\"x\"},{\"t\":3,\"p\":1,\"n\":\"y\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"SNDX - Sound Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Minimum attentuation distance\"},{\"t\":3,\"p\":1,\"n\":\"Maximum attentuation distance\"},{\"t\":3,\"p\":1,\"n\":\"Frequency adjustment %\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":3,\"p\":1,\"n\":\"Static attentuation cdB\"},{\"t\":3,\"p\":1,\"n\":\"Stop time \"},{\"t\":3,\"p\":1,\"n\":\"Start time \"}]},{\"t\":7,\"p\":1,\"n\":\"ANAM - Attenuation Curve\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Point\"}]},{\"t\":3,\"p\":1,\"n\":\"GNAM - Reverb Attenuation Control\"},{\"t\":3,\"p\":1,\"n\":\"HNAM - Priority\"}]},{\"t\":1,\"p\":1,\"n\":\"SPEL - Actor Effect\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"SPIT - \",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"n\":\"Cost (Unused)\"},{\"t\":3,\"n\":\"Level (Unused)\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Effects\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Effect\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"EFID - Base Effect\"},{\"t\":6,\"p\":1,\"n\":\"EFIT - \",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Magnitude\"},{\"t\":3,\"p\":1,\"n\":\"Area\"},{\"t\":3,\"p\":1,\"n\":\"Duration\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Actor Value\"}]},{\"t\":8,\"p\":1,\"n\":\"Conditions\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"CTDA - Condition\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":5,\"p\":1,\"n\":\"Comparison Value - Float\"},{\"t\":3,\"p\":1,\"n\":\"Comparison Value - Global\"},{\"t\":3,\"p\":1,\"n\":\"Function\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":11,\"p\":1,\"n\":\"None\"},{\"t\":3,\"p\":1,\"n\":\"Integer\"},{\"t\":3,\"p\":1,\"n\":\"Variable Name (INVALID)\"},{\"t\":3,\"p\":1,\"n\":\"Sex\"},{\"t\":3,\"p\":1,\"n\":\"Actor Value\"},{\"t\":3,\"p\":1,\"n\":\"Crime Type\"},{\"t\":3,\"p\":1,\"n\":\"Axis\"},{\"t\":3,\"p\":1,\"n\":\"Quest Stage (INVALID)\"},{\"t\":3,\"p\":1,\"n\":\"Misc Stat\"},{\"t\":3,\"p\":1,\"n\":\"Alignment\"},{\"t\":3,\"p\":1,\"n\":\"Equip Type\"},{\"t\":3,\"p\":1,\"n\":\"Form Type\"},{\"t\":3,\"p\":1,\"n\":\"Critical Stage\"},{\"t\":3,\"p\":1,\"n\":\"Object Reference\"},{\"t\":3,\"p\":1,\"n\":\"Inventory Object\"},{\"t\":3,\"p\":1,\"n\":\"Actor\"},{\"t\":3,\"p\":1,\"n\":\"Voice Type\"},{\"t\":3,\"p\":1,\"n\":\"Idle\"},{\"t\":3,\"p\":1,\"n\":\"Form List\"},{\"t\":3,\"p\":1,\"n\":\"Note\"},{\"t\":3,\"p\":1,\"n\":\"Quest\"},{\"t\":3,\"p\":1,\"n\":\"Faction\"},{\"t\":3,\"p\":1,\"n\":\"Weapon\"},{\"t\":3,\"p\":1,\"n\":\"Cell\"},{\"t\":3,\"p\":1,\"n\":\"Class\"},{\"t\":3,\"p\":1,\"n\":\"Race\"},{\"t\":3,\"p\":1,\"n\":\"Actor Base\"},{\"t\":3,\"p\":1,\"n\":\"Global\"},{\"t\":3,\"p\":1,\"n\":\"Weather\"},{\"t\":3,\"p\":1,\"n\":\"Package\"},{\"t\":3,\"p\":1,\"n\":\"Encounter Zone\"},{\"t\":3,\"p\":1,\"n\":\"Perk\"},{\"t\":3,\"p\":1,\"n\":\"Owner\"},{\"t\":3,\"p\":1,\"n\":\"Furniture\"},{\"t\":3,\"p\":1,\"n\":\"Effect Item\"},{\"t\":3,\"p\":1,\"n\":\"Base Effect\"},{\"t\":3,\"p\":1,\"n\":\"Worldspace\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Function\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Param (INVALID)\"},{\"t\":3,\"p\":1,\"n\":\"Creature Type\"},{\"t\":3,\"p\":1,\"n\":\"Menu Mode\"},{\"t\":3,\"p\":1,\"n\":\"Player Action\"},{\"t\":3,\"p\":1,\"n\":\"Body Location\"},{\"t\":3,\"p\":1,\"n\":\"Referenceable Object\"},{\"t\":3,\"p\":1,\"n\":\"Quest Objective (INVALID)\"},{\"t\":3,\"p\":1,\"n\":\"Reputation\"},{\"t\":3,\"p\":1,\"n\":\"Region\"},{\"t\":3,\"p\":1,\"n\":\"Challenge\"},{\"t\":3,\"p\":1,\"n\":\"Casino\"},{\"t\":3,\"p\":1,\"n\":\"Form\"},{\"t\":3,\"p\":1,\"n\":\"Variable Name\"},{\"t\":3,\"p\":1,\"n\":\"Quest Stage\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Function (INVALID)\"},{\"t\":3,\"p\":1,\"n\":\"Weapon List\"},{\"t\":3,\"p\":1,\"n\":\"Target\"},{\"t\":3,\"p\":1,\"n\":\"Target List\"},{\"t\":3,\"p\":1,\"n\":\"Target Part\"},{\"t\":3,\"p\":1,\"n\":\"VATS Action\"},{\"t\":3,\"p\":1,\"n\":\"Critical Effect\"},{\"t\":3,\"p\":1,\"n\":\"Critical Effect List\"},{\"t\":3,\"p\":1,\"n\":\"Weapon Type\"},{\"t\":3,\"p\":1,\"n\":\"Quest Objective\"},{\"t\":3,\"p\":1,\"n\":\"Run On\"},{\"t\":3,\"p\":1,\"n\":\"Reference\"}]}]}]}]}]},{\"t\":1,\"p\":1,\"n\":\"STAT - Static\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"X1\"},{\"t\":3,\"p\":1,\"n\":\"Y1\"},{\"t\":3,\"p\":1,\"n\":\"Z1\"},{\"t\":3,\"p\":1,\"n\":\"X2\"},{\"t\":3,\"p\":1,\"n\":\"Y2\"},{\"t\":3,\"p\":1,\"n\":\"Z2\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"},{\"t\":11,\"n\":\"MODB - Unknown\"},{\"t\":11,\"p\":1,\"n\":\"MODT - Texture Files Hashes\"},{\"t\":7,\"p\":1,\"n\":\"MODS - Alternate Textures\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"3D Name\"},{\"t\":3,\"p\":1,\"n\":\"New Texture\"},{\"t\":3,\"p\":1,\"n\":\"3D Index\"}]}]},{\"t\":3,\"p\":1,\"n\":\"MODD - FaceGen Model Flags\"}]},{\"t\":3,\"p\":1,\"n\":\"BRUS - Passthrough Sound\"},{\"t\":3,\"p\":1,\"n\":\"RNAM - Sound - Looping\\/Random\"}]},{\"t\":1,\"p\":1,\"n\":\"TACT - Talking Activator\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"X1\"},{\"t\":3,\"p\":1,\"n\":\"Y1\"},{\"t\":3,\"p\":1,\"n\":\"Z1\"},{\"t\":3,\"p\":1,\"n\":\"X2\"},{\"t\":3,\"p\":1,\"n\":\"Y2\"},{\"t\":3,\"p\":1,\"n\":\"Z2\"}]},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"},{\"t\":11,\"n\":\"MODB - Unknown\"},{\"t\":11,\"p\":1,\"n\":\"MODT - Texture Files Hashes\"},{\"t\":7,\"p\":1,\"n\":\"MODS - Alternate Textures\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"3D Name\"},{\"t\":3,\"p\":1,\"n\":\"New Texture\"},{\"t\":3,\"p\":1,\"n\":\"3D Index\"}]}]},{\"t\":3,\"p\":1,\"n\":\"MODD - FaceGen Model Flags\"}]},{\"t\":3,\"p\":1,\"n\":\"SCRI - Script\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Destructable\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"DEST - Header\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Health\"},{\"t\":3,\"p\":1,\"n\":\"Count\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":8,\"p\":1,\"n\":\"Stages\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Stage\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"DSTD - Destruction Stage Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Health %\"},{\"t\":3,\"p\":1,\"n\":\"Index\"},{\"t\":3,\"p\":1,\"n\":\"Damage Stage\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":3,\"p\":1,\"n\":\"Self Damage per Second\"},{\"t\":3,\"p\":1,\"n\":\"Explosion\"},{\"t\":3,\"p\":1,\"n\":\"Debris\"},{\"t\":3,\"p\":1,\"n\":\"Debris Count\"}]},{\"t\":6,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"DMDL - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"DMDT - Texture Files Hashes\"}]},{\"p\":1,\"n\":\"DSTF - End Marker\"}]}]}]},{\"t\":3,\"p\":1,\"n\":\"SNAM - Looping Sound\"},{\"t\":3,\"p\":1,\"n\":\"VNAM - Voice Type\"},{\"t\":3,\"p\":1,\"n\":\"INAM - Radio Template\"}]},{\"t\":1,\"p\":1,\"n\":\"TERM - Terminal\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"X1\"},{\"t\":3,\"p\":1,\"n\":\"Y1\"},{\"t\":3,\"p\":1,\"n\":\"Z1\"},{\"t\":3,\"p\":1,\"n\":\"X2\"},{\"t\":3,\"p\":1,\"n\":\"Y2\"},{\"t\":3,\"p\":1,\"n\":\"Z2\"}]},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"},{\"t\":11,\"n\":\"MODB - Unknown\"},{\"t\":11,\"p\":1,\"n\":\"MODT - Texture Files Hashes\"},{\"t\":7,\"p\":1,\"n\":\"MODS - Alternate Textures\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"3D Name\"},{\"t\":3,\"p\":1,\"n\":\"New Texture\"},{\"t\":3,\"p\":1,\"n\":\"3D Index\"}]}]},{\"t\":3,\"p\":1,\"n\":\"MODD - FaceGen Model Flags\"}]},{\"t\":3,\"p\":1,\"n\":\"SCRI - Script\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Destructable\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"DEST - Header\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Health\"},{\"t\":3,\"p\":1,\"n\":\"Count\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":8,\"p\":1,\"n\":\"Stages\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Stage\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"DSTD - Destruction Stage Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Health %\"},{\"t\":3,\"p\":1,\"n\":\"Index\"},{\"t\":3,\"p\":1,\"n\":\"Damage Stage\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":3,\"p\":1,\"n\":\"Self Damage per Second\"},{\"t\":3,\"p\":1,\"n\":\"Explosion\"},{\"t\":3,\"p\":1,\"n\":\"Debris\"},{\"t\":3,\"p\":1,\"n\":\"Debris Count\"}]},{\"t\":6,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"DMDL - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"DMDT - Texture Files Hashes\"}]},{\"p\":1,\"n\":\"DSTF - End Marker\"}]}]}]},{\"t\":2,\"p\":1,\"n\":\"DESC - Description\"},{\"t\":3,\"p\":1,\"n\":\"SNAM - Sound - Looping\"},{\"t\":3,\"p\":1,\"n\":\"PNAM - Password Note\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DNAM - \",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Base Hacking Difficulty\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":3,\"p\":1,\"n\":\"ServerType\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Menu Items\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Menu Item\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"ITXT - Item Text\"},{\"t\":2,\"p\":1,\"n\":\"RNAM - Result Text\"},{\"t\":3,\"p\":1,\"n\":\"ANAM - Flags\"},{\"t\":3,\"p\":1,\"n\":\"INAM - Display Note\"},{\"t\":3,\"p\":1,\"n\":\"TNAM - Sub Menu\"},{\"t\":6,\"p\":1,\"n\":\"Embedded Script\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"SCHR - Basic Script Data\",\"c\":[{\"t\":11,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"RefCount\"},{\"t\":3,\"p\":1,\"n\":\"CompiledSize\"},{\"t\":3,\"p\":1,\"n\":\"VariableCount\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"}]},{\"t\":11,\"p\":1,\"n\":\"SCDA - Compiled Embedded Script\"},{\"t\":2,\"p\":1,\"n\":\"SCTX - Embedded Script Source\"},{\"t\":10,\"p\":1,\"n\":\"Local Variables\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Local Variable\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"SLSD - Local Variable Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Index\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"}]},{\"t\":2,\"p\":1,\"n\":\"SCVR - Name\"}]}]},{\"t\":8,\"p\":1,\"n\":\"References\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"SCRO - Global Reference\"},{\"t\":3,\"p\":1,\"n\":\"SCRV - Local Variable\"}]}]},{\"t\":8,\"p\":1,\"n\":\"Conditions\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"CTDA - Condition\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":5,\"p\":1,\"n\":\"Comparison Value - Float\"},{\"t\":3,\"p\":1,\"n\":\"Comparison Value - Global\"},{\"t\":3,\"p\":1,\"n\":\"Function\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":11,\"p\":1,\"n\":\"None\"},{\"t\":3,\"p\":1,\"n\":\"Integer\"},{\"t\":3,\"p\":1,\"n\":\"Variable Name (INVALID)\"},{\"t\":3,\"p\":1,\"n\":\"Sex\"},{\"t\":3,\"p\":1,\"n\":\"Actor Value\"},{\"t\":3,\"p\":1,\"n\":\"Crime Type\"},{\"t\":3,\"p\":1,\"n\":\"Axis\"},{\"t\":3,\"p\":1,\"n\":\"Quest Stage (INVALID)\"},{\"t\":3,\"p\":1,\"n\":\"Misc Stat\"},{\"t\":3,\"p\":1,\"n\":\"Alignment\"},{\"t\":3,\"p\":1,\"n\":\"Equip Type\"},{\"t\":3,\"p\":1,\"n\":\"Form Type\"},{\"t\":3,\"p\":1,\"n\":\"Critical Stage\"},{\"t\":3,\"p\":1,\"n\":\"Object Reference\"},{\"t\":3,\"p\":1,\"n\":\"Inventory Object\"},{\"t\":3,\"p\":1,\"n\":\"Actor\"},{\"t\":3,\"p\":1,\"n\":\"Voice Type\"},{\"t\":3,\"p\":1,\"n\":\"Idle\"},{\"t\":3,\"p\":1,\"n\":\"Form List\"},{\"t\":3,\"p\":1,\"n\":\"Note\"},{\"t\":3,\"p\":1,\"n\":\"Quest\"},{\"t\":3,\"p\":1,\"n\":\"Faction\"},{\"t\":3,\"p\":1,\"n\":\"Weapon\"},{\"t\":3,\"p\":1,\"n\":\"Cell\"},{\"t\":3,\"p\":1,\"n\":\"Class\"},{\"t\":3,\"p\":1,\"n\":\"Race\"},{\"t\":3,\"p\":1,\"n\":\"Actor Base\"},{\"t\":3,\"p\":1,\"n\":\"Global\"},{\"t\":3,\"p\":1,\"n\":\"Weather\"},{\"t\":3,\"p\":1,\"n\":\"Package\"},{\"t\":3,\"p\":1,\"n\":\"Encounter Zone\"},{\"t\":3,\"p\":1,\"n\":\"Perk\"},{\"t\":3,\"p\":1,\"n\":\"Owner\"},{\"t\":3,\"p\":1,\"n\":\"Furniture\"},{\"t\":3,\"p\":1,\"n\":\"Effect Item\"},{\"t\":3,\"p\":1,\"n\":\"Base Effect\"},{\"t\":3,\"p\":1,\"n\":\"Worldspace\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Function\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Param (INVALID)\"},{\"t\":3,\"p\":1,\"n\":\"Creature Type\"},{\"t\":3,\"p\":1,\"n\":\"Menu Mode\"},{\"t\":3,\"p\":1,\"n\":\"Player Action\"},{\"t\":3,\"p\":1,\"n\":\"Body Location\"},{\"t\":3,\"p\":1,\"n\":\"Referenceable Object\"},{\"t\":3,\"p\":1,\"n\":\"Quest Objective (INVALID)\"},{\"t\":3,\"p\":1,\"n\":\"Reputation\"},{\"t\":3,\"p\":1,\"n\":\"Region\"},{\"t\":3,\"p\":1,\"n\":\"Challenge\"},{\"t\":3,\"p\":1,\"n\":\"Casino\"},{\"t\":3,\"p\":1,\"n\":\"Form\"},{\"t\":3,\"p\":1,\"n\":\"Variable Name\"},{\"t\":3,\"p\":1,\"n\":\"Quest Stage\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Function (INVALID)\"},{\"t\":3,\"p\":1,\"n\":\"Weapon List\"},{\"t\":3,\"p\":1,\"n\":\"Target\"},{\"t\":3,\"p\":1,\"n\":\"Target List\"},{\"t\":3,\"p\":1,\"n\":\"Target Part\"},{\"t\":3,\"p\":1,\"n\":\"VATS Action\"},{\"t\":3,\"p\":1,\"n\":\"Critical Effect\"},{\"t\":3,\"p\":1,\"n\":\"Critical Effect List\"},{\"t\":3,\"p\":1,\"n\":\"Weapon Type\"},{\"t\":3,\"p\":1,\"n\":\"Quest Objective\"},{\"t\":3,\"p\":1,\"n\":\"Run On\"},{\"t\":3,\"p\":1,\"n\":\"Reference\"}]}]}]}]}]},{\"t\":1,\"p\":1,\"n\":\"TREE - Tree\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"X1\"},{\"t\":3,\"p\":1,\"n\":\"Y1\"},{\"t\":3,\"p\":1,\"n\":\"Z1\"},{\"t\":3,\"p\":1,\"n\":\"X2\"},{\"t\":3,\"p\":1,\"n\":\"Y2\"},{\"t\":3,\"p\":1,\"n\":\"Z2\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"},{\"t\":11,\"n\":\"MODB - Unknown\"},{\"t\":11,\"p\":1,\"n\":\"MODT - Texture Files Hashes\"},{\"t\":7,\"p\":1,\"n\":\"MODS - Alternate Textures\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"3D Name\"},{\"t\":3,\"p\":1,\"n\":\"New Texture\"},{\"t\":3,\"p\":1,\"n\":\"3D Index\"}]}]},{\"t\":3,\"p\":1,\"n\":\"MODD - FaceGen Model Flags\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Icon\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"ICON - Large Icon filename\"},{\"t\":2,\"p\":1,\"n\":\"MICO - Small Icon filename\"}]},{\"t\":7,\"p\":1,\"n\":\"SNAM - SpeedTree Seeds\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"SpeedTree Seed\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"CNAM - Tree Data\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Leaf Curvature\"},{\"t\":5,\"p\":1,\"n\":\"Minimum Leaf Angle\"},{\"t\":5,\"p\":1,\"n\":\"Maximum Leaf Angle\"},{\"t\":5,\"p\":1,\"n\":\"Branch Dimming Value\"},{\"t\":5,\"p\":1,\"n\":\"Leaf Dimming Value\"},{\"t\":3,\"p\":1,\"n\":\"Shadow Radius\"},{\"t\":5,\"p\":1,\"n\":\"Rock Speed\"},{\"t\":5,\"p\":1,\"n\":\"Rustle Speed\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"BNAM - Billboard Dimensions\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Width\"},{\"t\":5,\"p\":1,\"n\":\"Height\"}]}]},{\"t\":1,\"p\":1,\"n\":\"TXST - Texture Set\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"X1\"},{\"t\":3,\"p\":1,\"n\":\"Y1\"},{\"t\":3,\"p\":1,\"n\":\"Z1\"},{\"t\":3,\"p\":1,\"n\":\"X2\"},{\"t\":3,\"p\":1,\"n\":\"Y2\"},{\"t\":3,\"p\":1,\"n\":\"Z2\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Textures (RGB\\/A)\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"TX00 - Base Image \\/ Transparency\"},{\"t\":2,\"p\":1,\"n\":\"TX01 - Normal Map \\/ Specular\"},{\"t\":2,\"p\":1,\"n\":\"TX02 - Environment Map Mask \\/ ?\"},{\"t\":2,\"n\":\"TX03 - Glow Map \\/ Unused\"},{\"t\":2,\"n\":\"TX04 - Parallax Map \\/ Unused\"},{\"t\":2,\"n\":\"TX05 - Environment Map \\/ Unused\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DODT - Decal Data\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Min Width\"},{\"t\":5,\"p\":1,\"n\":\"Max Width\"},{\"t\":5,\"p\":1,\"n\":\"Min Height\"},{\"t\":5,\"p\":1,\"n\":\"Max Height\"},{\"t\":5,\"p\":1,\"n\":\"Depth\"},{\"t\":5,\"p\":1,\"n\":\"Shininess\"},{\"t\":6,\"p\":1,\"n\":\"Parallax\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Scale\"},{\"t\":3,\"p\":1,\"n\":\"Passes\"}]},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":6,\"p\":1,\"n\":\"Color\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]}]},{\"t\":3,\"p\":1,\"n\":\"DNAM - Flags\"}]},{\"t\":1,\"p\":1,\"n\":\"VTYP - Voice Type\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":3,\"p\":1,\"n\":\"DNAM - Flags\"}]},{\"t\":1,\"p\":1,\"n\":\"WATR - Water\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":2,\"p\":1,\"n\":\"NNAM - Noise Map\"},{\"t\":3,\"p\":1,\"n\":\"ANAM - Opacity\"},{\"t\":3,\"p\":1,\"n\":\"FNAM - Flags\"},{\"t\":2,\"p\":1,\"n\":\"MNAM - Material ID\"},{\"t\":3,\"p\":1,\"n\":\"SNAM - Sound\"},{\"t\":3,\"p\":1,\"n\":\"XNAM - Actor Effect\"},{\"t\":3,\"p\":1,\"n\":\"DATA - Damage\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DNAM - Visual Data\",\"c\":[{\"t\":5,\"n\":\"Unknown\"},{\"t\":5,\"p\":1,\"n\":\"Water Properties - Sun Power\"},{\"t\":5,\"p\":1,\"n\":\"Water Properties - Reflectivity Amount\"},{\"t\":5,\"p\":1,\"n\":\"Water Properties - Fresnel Amount\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":5,\"p\":1,\"n\":\"Fog Properties - Above Water - Fog Distance - Near Plane\"},{\"t\":5,\"p\":1,\"n\":\"Fog Properties - Above Water - Fog Distance - Far Plane\"},{\"t\":6,\"p\":1,\"n\":\"Shallow Color\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Deep Color\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Reflection Color\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":5,\"p\":1,\"n\":\"Rain Simulator - Force\"},{\"t\":5,\"p\":1,\"n\":\"Rain Simulator - Velocity\"},{\"t\":5,\"p\":1,\"n\":\"Rain Simulator - Falloff\"},{\"t\":5,\"p\":1,\"n\":\"Rain Simulator - Dampner\"},{\"t\":5,\"p\":1,\"n\":\"Displacement Simulator - Starting Size\"},{\"t\":5,\"p\":1,\"n\":\"Displacement Simulator - Force\"},{\"t\":5,\"p\":1,\"n\":\"Displacement Simulator - Velocity\"},{\"t\":5,\"p\":1,\"n\":\"Displacement Simulator - Falloff\"},{\"t\":5,\"p\":1,\"n\":\"Displacement Simulator - Dampner\"},{\"t\":5,\"p\":1,\"n\":\"Rain Simulator - Starting Size\"},{\"t\":5,\"p\":1,\"n\":\"Noise Properties - Normals - Noise Scale\"},{\"t\":5,\"p\":1,\"n\":\"Noise Properties - Noise Layer One - Wind Direction\"},{\"t\":5,\"p\":1,\"n\":\"Noise Properties - Noise Layer Two - Wind Direction\"},{\"t\":5,\"p\":1,\"n\":\"Noise Properties - Noise Layer Three - Wind Direction\"},{\"t\":5,\"p\":1,\"n\":\"Noise Properties - Noise Layer One - Wind Speed\"},{\"t\":5,\"p\":1,\"n\":\"Noise Properties - Noise Layer Two - Wind Speed\"},{\"t\":5,\"p\":1,\"n\":\"Noise Properties - Noise Layer Three - Wind Speed\"},{\"t\":5,\"p\":1,\"n\":\"Noise Properties - Normals - Depth Falloff Start\"},{\"t\":5,\"p\":1,\"n\":\"Noise Properties - Normals - Depth Falloff End\"},{\"t\":5,\"p\":1,\"n\":\"Fog Properties - Above Water - Fog Amount\"},{\"t\":5,\"p\":1,\"n\":\"Noise Properties - Normals - UV Scale\"},{\"t\":5,\"p\":1,\"n\":\"Fog Properties - Under Water - Fog Amount\"},{\"t\":5,\"p\":1,\"n\":\"Fog Properties - Under Water - Fog Distance - Near Plane\"},{\"t\":5,\"p\":1,\"n\":\"Fog Properties - Under Water - Fog Distance - Far Plane\"},{\"t\":5,\"p\":1,\"n\":\"Water Properties - Distortion Amount\"},{\"t\":5,\"p\":1,\"n\":\"Water Properties - Shininess\"},{\"t\":5,\"p\":1,\"n\":\"Water Properties - Reflection HDR Multiplier\"},{\"t\":5,\"p\":1,\"n\":\"Water Properties - Light Radius\"},{\"t\":5,\"p\":1,\"n\":\"Water Properties - Light Brightness\"},{\"t\":5,\"p\":1,\"n\":\"Noise Properties - Noise Layer One - UV Scale\"},{\"t\":5,\"p\":1,\"n\":\"Noise Properties - Noise Layer Two - UV Scale\"},{\"t\":5,\"p\":1,\"n\":\"Noise Properties - Noise Layer Three - UV Scale\"},{\"t\":5,\"p\":1,\"n\":\"Noise Properties - Noise Layer One - Amplitude Scale\"},{\"t\":5,\"p\":1,\"n\":\"Noise Properties - Noise Layer Two - Amplitude Scale\"},{\"t\":5,\"p\":1,\"n\":\"Noise Properties - Noise Layer Three - Amplitude Scale\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DATA - Visual Data\",\"c\":[{\"t\":5,\"n\":\"Unknown\"},{\"t\":5,\"p\":1,\"n\":\"Water Properties - Sun Power\"},{\"t\":5,\"p\":1,\"n\":\"Water Properties - Reflectivity Amount\"},{\"t\":5,\"p\":1,\"n\":\"Water Properties - Fresnel Amount\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":5,\"p\":1,\"n\":\"Fog Properties - Above Water - Fog Distance - Near Plane\"},{\"t\":5,\"p\":1,\"n\":\"Fog Properties - Above Water - Fog Distance - Far Plane\"},{\"t\":6,\"p\":1,\"n\":\"Shallow Color\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Deep Color\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Reflection Color\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":5,\"p\":1,\"n\":\"Rain Simulator - Force\"},{\"t\":5,\"p\":1,\"n\":\"Rain Simulator - Velocity\"},{\"t\":5,\"p\":1,\"n\":\"Rain Simulator - Falloff\"},{\"t\":5,\"p\":1,\"n\":\"Rain Simulator - Dampner\"},{\"t\":5,\"p\":1,\"n\":\"Displacement Simulator - Starting Size\"},{\"t\":5,\"p\":1,\"n\":\"Displacement Simulator - Force\"},{\"t\":5,\"p\":1,\"n\":\"Displacement Simulator - Velocity\"},{\"t\":5,\"p\":1,\"n\":\"Displacement Simulator - Falloff\"},{\"t\":5,\"p\":1,\"n\":\"Displacement Simulator - Dampner\"},{\"t\":5,\"p\":1,\"n\":\"Rain Simulator - Starting Size\"},{\"t\":5,\"p\":1,\"n\":\"Noise Properties - Normals - Noise Scale\"},{\"t\":5,\"p\":1,\"n\":\"Noise Properties - Noise Layer One - Wind Direction\"},{\"t\":5,\"p\":1,\"n\":\"Noise Properties - Noise Layer Two - Wind Direction\"},{\"t\":5,\"p\":1,\"n\":\"Noise Properties - Noise Layer Three - Wind Direction\"},{\"t\":5,\"p\":1,\"n\":\"Noise Properties - Noise Layer One - Wind Speed\"},{\"t\":5,\"p\":1,\"n\":\"Noise Properties - Noise Layer Two - Wind Speed\"},{\"t\":5,\"p\":1,\"n\":\"Noise Properties - Noise Layer Three - Wind Speed\"},{\"t\":5,\"p\":1,\"n\":\"Noise Properties - Normals - Depth Falloff Start\"},{\"t\":5,\"p\":1,\"n\":\"Noise Properties - Normals - Depth Falloff End\"},{\"t\":5,\"p\":1,\"n\":\"Fog Properties - Above Water - Fog Amount\"},{\"t\":5,\"p\":1,\"n\":\"Noise Properties - Normals - UV Scale\"},{\"t\":5,\"p\":1,\"n\":\"Fog Properties - Under Water - Fog Amount\"},{\"t\":5,\"p\":1,\"n\":\"Fog Properties - Under Water - Fog Distance - Near Plane\"},{\"t\":5,\"p\":1,\"n\":\"Fog Properties - Under Water - Fog Distance - Far Plane\"},{\"t\":5,\"p\":1,\"n\":\"Water Properties - Distortion Amount\"},{\"t\":5,\"p\":1,\"n\":\"Water Properties - Shininess\"},{\"t\":5,\"p\":1,\"n\":\"Water Properties - Reflection HDR Multiplier\"},{\"t\":5,\"p\":1,\"n\":\"Water Properties - Light Radius\"},{\"t\":5,\"p\":1,\"n\":\"Water Properties - Light Brightness\"},{\"t\":5,\"p\":1,\"n\":\"Noise Properties - Noise Layer One - UV Scale\"},{\"t\":5,\"p\":1,\"n\":\"Noise Properties - Noise Layer Two - UV Scale\"},{\"t\":5,\"p\":1,\"n\":\"Noise Properties - Noise Layer Three - UV Scale\"},{\"p\":1,\"n\":\"Noise Properties - Noise Layer One - Amplitude Scale\"},{\"p\":1,\"n\":\"Noise Properties - Noise Layer Two - Amplitude Scale\"},{\"p\":1,\"n\":\"Noise Properties - Noise Layer Three - Amplitude Scale\"},{\"t\":3,\"p\":1,\"n\":\"Damage (Old Format)\"}]},{\"t\":6,\"n\":\"GNAM - Related Waters (Unused)\",\"c\":[{\"t\":3,\"n\":\"Daytime\"},{\"t\":3,\"n\":\"Nighttime\"},{\"t\":3,\"n\":\"Underwater\"}]}]},{\"t\":1,\"p\":1,\"n\":\"WEAP - Weapon\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"X1\"},{\"t\":3,\"p\":1,\"n\":\"Y1\"},{\"t\":3,\"p\":1,\"n\":\"Z1\"},{\"t\":3,\"p\":1,\"n\":\"X2\"},{\"t\":3,\"p\":1,\"n\":\"Y2\"},{\"t\":3,\"p\":1,\"n\":\"Z2\"}]},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"},{\"t\":11,\"n\":\"MODB - Unknown\"},{\"t\":11,\"p\":1,\"n\":\"MODT - Texture Files Hashes\"},{\"t\":7,\"p\":1,\"n\":\"MODS - Alternate Textures\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"3D Name\"},{\"t\":3,\"p\":1,\"n\":\"New Texture\"},{\"t\":3,\"p\":1,\"n\":\"3D Index\"}]}]},{\"t\":3,\"p\":1,\"n\":\"MODD - FaceGen Model Flags\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Icon\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"ICON - Large Icon filename\"},{\"t\":2,\"p\":1,\"n\":\"MICO - Small Icon filename\"}]},{\"t\":3,\"p\":1,\"n\":\"SCRI - Script\"},{\"t\":3,\"p\":1,\"n\":\"EITM - Object Effect\"},{\"t\":3,\"p\":1,\"n\":\"EAMT - Enchantment Charge Amount\"},{\"t\":3,\"p\":1,\"n\":\"NAM0 - Ammo\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Destructable\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"DEST - Header\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Health\"},{\"t\":3,\"p\":1,\"n\":\"Count\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":8,\"p\":1,\"n\":\"Stages\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Stage\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"DSTD - Destruction Stage Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Health %\"},{\"t\":3,\"p\":1,\"n\":\"Index\"},{\"t\":3,\"p\":1,\"n\":\"Damage Stage\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":3,\"p\":1,\"n\":\"Self Damage per Second\"},{\"t\":3,\"p\":1,\"n\":\"Explosion\"},{\"t\":3,\"p\":1,\"n\":\"Debris\"},{\"t\":3,\"p\":1,\"n\":\"Debris Count\"}]},{\"t\":6,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"DMDL - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"DMDT - Texture Files Hashes\"}]},{\"p\":1,\"n\":\"DSTF - End Marker\"}]}]}]},{\"t\":3,\"p\":1,\"n\":\"REPL - Repair List\"},{\"t\":3,\"p\":1,\"n\":\"ETYP - Equiptment Type\"},{\"t\":3,\"p\":1,\"n\":\"BIPL - Biped Model List\"},{\"t\":3,\"p\":1,\"n\":\"YNAM - Sound - Pick Up\"},{\"t\":3,\"p\":1,\"n\":\"ZNAM - Sound - Drop\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Shell Casing Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MOD2 - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"MO2T - Texture Files Hashes\"},{\"t\":7,\"p\":1,\"n\":\"MO2S - Alternate Textures\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"3D Name\"},{\"t\":3,\"p\":1,\"n\":\"New Texture\"},{\"t\":3,\"p\":1,\"n\":\"3D Index\"}]}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Scope Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MOD3 - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"MO3T - Texture Files Hashes\"},{\"t\":7,\"p\":1,\"n\":\"MO3S - Alternate Textures\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"3D Name\"},{\"t\":3,\"p\":1,\"n\":\"New Texture\"},{\"t\":3,\"p\":1,\"n\":\"3D Index\"}]}]}]},{\"t\":3,\"p\":1,\"n\":\"EFSD - Scope Effect\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"World Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MOD4 - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"MO4T - Texture Files Hashes\"},{\"t\":7,\"p\":1,\"n\":\"MO4S - Alternate Textures\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"3D Name\"},{\"t\":3,\"p\":1,\"n\":\"New Texture\"},{\"t\":3,\"p\":1,\"n\":\"3D Index\"}]}]}]},{\"t\":2,\"p\":1,\"n\":\"MWD1 - Model - Mod 1\"},{\"t\":2,\"p\":1,\"n\":\"MWD2 - Model - Mod 2\"},{\"t\":2,\"p\":1,\"n\":\"MWD3 - Model - Mod 1 and 2\"},{\"t\":2,\"p\":1,\"n\":\"MWD4 - Model - Mod 3\"},{\"t\":2,\"p\":1,\"n\":\"MWD5 - Model - Mod 1 and 3\"},{\"t\":2,\"p\":1,\"n\":\"MWD6 - Model - Mod 2 and 3\"},{\"t\":2,\"p\":1,\"n\":\"MWD7 - Model - Mod 1, 2 and 3\"},{\"t\":2,\"p\":1,\"n\":\"VANM - VATS Attack Name\"},{\"t\":2,\"p\":1,\"n\":\"NNAM - Embedded Weapon Node\"},{\"t\":3,\"p\":1,\"n\":\"INAM - Impact DataSet\"},{\"t\":3,\"p\":1,\"n\":\"WNAM - 1st Person Model\"},{\"t\":3,\"p\":1,\"n\":\"WNM1 - 1st Person Model - Mod 1\"},{\"t\":3,\"p\":1,\"n\":\"WNM2 - 1st Person Model - Mod 2\"},{\"t\":3,\"p\":1,\"n\":\"WNM3 - 1st Person Model - Mod 1 and 2\"},{\"t\":3,\"p\":1,\"n\":\"WNM4 - 1st Person Model - Mod 3\"},{\"t\":3,\"p\":1,\"n\":\"WNM5 - 1st Person Model - Mod 1 and 3\"},{\"t\":3,\"p\":1,\"n\":\"WNM6 - 1st Person Model - Mod 2 and 3\"},{\"t\":3,\"p\":1,\"n\":\"WNM7 - 1st Person Model - Mod 1, 2 and 3\"},{\"t\":3,\"p\":1,\"n\":\"WMI1 - Weapon Mod 1\"},{\"t\":3,\"p\":1,\"n\":\"WMI2 - Weapon Mod 2\"},{\"t\":3,\"p\":1,\"n\":\"WMI3 - Weapon Mod 3\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Sound - Gun\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"SNAM - Shoot 3D\"},{\"t\":3,\"p\":1,\"n\":\"SNAM - Shoot Dist\"}]},{\"t\":3,\"p\":1,\"n\":\"XNAM - Sound - Gun - Shoot 2D\"},{\"t\":3,\"p\":1,\"n\":\"NAM7 - Sound - Gun - Shoot 3D Looping\"},{\"t\":3,\"p\":1,\"n\":\"TNAM - Sound - Melee - Swing \\/ Gun - No Ammo\"},{\"t\":3,\"p\":1,\"n\":\"NAM6 - Sound - Block\"},{\"t\":3,\"p\":1,\"n\":\"UNAM - Sound - Idle\"},{\"t\":3,\"p\":1,\"n\":\"NAM9 - Sound - Equip\"},{\"t\":3,\"p\":1,\"n\":\"NAM8 - Sound - Unequip\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Sound - Mod 1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"WMS1 - Shoot 3D\"},{\"t\":3,\"p\":1,\"n\":\"WMS1 - Shoot Dist\"}]},{\"t\":3,\"p\":1,\"n\":\"WMS2 - Sound - Mod 1 - Shoot 2D\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DATA - \",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Value\"},{\"t\":3,\"p\":1,\"n\":\"Health\"},{\"t\":5,\"p\":1,\"n\":\"Weight\"},{\"t\":3,\"p\":1,\"n\":\"Base Damage\"},{\"t\":3,\"p\":1,\"n\":\"Clip Size\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DNAM - \",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Animation Type\"},{\"t\":5,\"p\":1,\"n\":\"Animation Multiplier\"},{\"t\":5,\"p\":1,\"n\":\"Reach\"},{\"t\":3,\"p\":1,\"n\":\"Flags 1\"},{\"t\":3,\"p\":1,\"n\":\"Grip Animation\"},{\"t\":3,\"p\":1,\"n\":\"Ammo Use\"},{\"t\":3,\"p\":1,\"n\":\"Reload Animation\"},{\"t\":5,\"p\":1,\"n\":\"Min Spread\"},{\"t\":5,\"p\":1,\"n\":\"Spread\"},{\"t\":5,\"n\":\"Unknown\"},{\"t\":5,\"p\":1,\"n\":\"Sight FOV\"},{\"t\":3,\"p\":1,\"n\":\"Projectile\"},{\"t\":3,\"p\":1,\"n\":\"Base VATS To-Hit Chance\"},{\"t\":3,\"p\":1,\"n\":\"Attack Animation\"},{\"t\":3,\"p\":1,\"n\":\"Projectile Count\"},{\"t\":3,\"p\":1,\"n\":\"Embedded Weapon - Actor Value\"},{\"t\":5,\"p\":1,\"n\":\"Min Range\"},{\"t\":5,\"p\":1,\"n\":\"Max Range\"},{\"t\":3,\"p\":1,\"n\":\"On Hit\"},{\"t\":3,\"p\":1,\"n\":\"Flags 2\"},{\"t\":5,\"p\":1,\"n\":\"Animation Attack Multiplier\"},{\"t\":5,\"p\":1,\"n\":\"Fire Rate\"},{\"t\":5,\"p\":1,\"n\":\"Override - Action Points\"},{\"t\":5,\"p\":1,\"n\":\"Rumble - Left Motor Strength\"},{\"t\":5,\"p\":1,\"n\":\"Rumble - Right Motor Strength\"},{\"t\":5,\"p\":1,\"n\":\"Rumble - Duration\"},{\"t\":5,\"p\":1,\"n\":\"Override - Damage to Weapon Mult\"},{\"t\":5,\"p\":1,\"n\":\"Attack Shots\\/Sec\"},{\"t\":5,\"p\":1,\"n\":\"Reload Time\"},{\"t\":5,\"p\":1,\"n\":\"Jam Time\"},{\"t\":5,\"p\":1,\"n\":\"Aim Arc\"},{\"t\":3,\"p\":1,\"n\":\"Skill\"},{\"t\":3,\"p\":1,\"n\":\"Rumble - Pattern\"},{\"t\":5,\"p\":1,\"n\":\"Rumble - Wavelength\"},{\"t\":5,\"p\":1,\"n\":\"Limb Dmg Mult\"},{\"t\":3,\"p\":1,\"n\":\"Resist Type\"},{\"t\":5,\"p\":1,\"n\":\"Sight Usage\"},{\"t\":5,\"p\":1,\"n\":\"Semi-Automatic Fire Delay Min\"},{\"t\":5,\"p\":1,\"n\":\"Semi-Automatic Fire Delay Max\"},{\"t\":3,\"p\":1,\"n\":\"Effect - Mod 1\"},{\"t\":3,\"p\":1,\"n\":\"Effect - Mod 2\"},{\"t\":3,\"p\":1,\"n\":\"Effect - Mod 3\"},{\"t\":5,\"p\":1,\"n\":\"Value A - Mod 1\"},{\"t\":5,\"p\":1,\"n\":\"Value A - Mod 2\"},{\"t\":5,\"p\":1,\"n\":\"Value A - Mod 3\"},{\"t\":3,\"p\":1,\"n\":\"Power Attack Animation Override\"},{\"t\":3,\"p\":1,\"n\":\"Strength Req\"},{\"t\":3,\"p\":1,\"n\":\"Reload Animation - Mod\"},{\"t\":5,\"p\":1,\"n\":\"Regen Rate\"},{\"t\":5,\"p\":1,\"n\":\"Kill Impulse\"},{\"t\":5,\"p\":1,\"n\":\"Value B - Mod 1\"},{\"t\":5,\"p\":1,\"n\":\"Value B - Mod 2\"},{\"t\":5,\"p\":1,\"n\":\"Value B - Mod 3\"},{\"t\":5,\"p\":1,\"n\":\"Impulse Dist\"},{\"t\":3,\"p\":1,\"n\":\"Skill Req\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"CRDT - Critical Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Critical Damage\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":5,\"p\":1,\"n\":\"Crit % Mult\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":3,\"p\":1,\"n\":\"Effect\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"VATS - VATS\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Effect\"},{\"t\":5,\"p\":1,\"n\":\"Skill\"},{\"t\":5,\"p\":1,\"n\":\"Dam. Mult\"},{\"t\":5,\"p\":1,\"n\":\"AP\"},{\"t\":3,\"p\":1,\"n\":\"Silent\"},{\"t\":3,\"p\":1,\"n\":\"Mod Required\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":3,\"p\":1,\"n\":\"VNAM - Sound Level\"}]},{\"t\":1,\"p\":1,\"n\":\"WRLD - Worldspace\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":3,\"p\":1,\"n\":\"XEZN - Encounter Zone\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Parent\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"WNAM - Worldspace\"},{\"t\":3,\"p\":1,\"n\":\"PNAM - Flags\"}]},{\"t\":3,\"p\":1,\"n\":\"CNAM - Climate\"},{\"t\":3,\"p\":1,\"n\":\"NAM2 - Water\"},{\"t\":3,\"p\":1,\"n\":\"NAM3 - LOD Water Type\"},{\"t\":5,\"p\":1,\"n\":\"NAM4 - LOD Water Height\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DNAM - Land Data\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Default Land Height\"},{\"t\":5,\"p\":1,\"n\":\"Default Water Height\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Icon\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"ICON - Large Icon filename\"},{\"t\":2,\"p\":1,\"n\":\"MICO - Small Icon filename\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"MNAM - Map Data\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Usable Dimensions\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"X\"},{\"t\":3,\"p\":1,\"n\":\"Y\"}]},{\"t\":6,\"p\":1,\"n\":\"Cell Coordinates\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"NW Cell\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"X\"},{\"t\":3,\"p\":1,\"n\":\"Y\"}]},{\"t\":6,\"p\":1,\"n\":\"SE Cell\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"X\"},{\"t\":3,\"p\":1,\"n\":\"Y\"}]}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"ONAM - World Map Offset Data\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"World Map Scale\"},{\"t\":5,\"p\":1,\"n\":\"Cell X Offset\"},{\"t\":5,\"p\":1,\"n\":\"Cell Y Offset\"}]},{\"t\":3,\"p\":1,\"n\":\"INAM - Image Space\"},{\"t\":3,\"p\":1,\"n\":\"DATA - Flags\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Object Bounds\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"NAM0 - Min\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"X\"},{\"t\":5,\"p\":1,\"n\":\"Y\"}]},{\"t\":6,\"p\":1,\"n\":\"NAM9 - Max\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"X\"},{\"t\":5,\"p\":1,\"n\":\"Y\"}]}]},{\"t\":3,\"p\":1,\"n\":\"ZNAM - Music\"},{\"t\":2,\"p\":1,\"n\":\"NNAM - Canopy Shadow\"},{\"t\":2,\"p\":1,\"n\":\"XNAM - Water Noise Texture\"},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Swapped Impacts\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"IMPS - Swapped Impact\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Material Type\"},{\"t\":3,\"p\":1,\"n\":\"Old\"},{\"t\":3,\"p\":1,\"n\":\"New\"}]}]},{\"t\":7,\"n\":\"IMPF - Footstep Materials\",\"c\":[{\"t\":2,\"n\":\"Unknown\"}]},{\"t\":11,\"n\":\"OFST - Offset Data\"}]},{\"t\":1,\"p\":1,\"n\":\"WTHR - Weather\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":3,\"p\":1,\"n\":\"aIAD - Sunrise Image Space Modifier\"},{\"t\":3,\"p\":1,\"n\":\"bIAD - Day Image Space Modifier\"},{\"t\":3,\"p\":1,\"n\":\"cIAD - Sunset Image Space Modifier\"},{\"t\":3,\"p\":1,\"n\":\"dIAD - Night Image Space Modifier\"},{\"t\":3,\"n\":\"eIAD - Unknown\"},{\"t\":3,\"n\":\"fIAD - Unknown\"},{\"t\":2,\"p\":1,\"n\":\"DNAM - Cloud Textures - Layer 0\"},{\"t\":2,\"p\":1,\"n\":\"CNAM - Cloud Textures - Layer 1\"},{\"t\":2,\"p\":1,\"n\":\"ANAM - Cloud Textures - Layer 2\"},{\"t\":2,\"p\":1,\"n\":\"BNAM - Cloud Textures - Layer 3\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"},{\"t\":11,\"n\":\"MODB - Unknown\"},{\"t\":11,\"p\":1,\"n\":\"MODT - Texture Files Hashes\"},{\"t\":7,\"p\":1,\"n\":\"MODS - Alternate Textures\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"3D Name\"},{\"t\":3,\"p\":1,\"n\":\"New Texture\"},{\"t\":3,\"p\":1,\"n\":\"3D Index\"}]}]},{\"t\":3,\"p\":1,\"n\":\"MODD - FaceGen Model Flags\"}]},{\"t\":11,\"n\":\"LNAM - Unknown\"},{\"t\":7,\"p\":1,\"n\":\"ONAM - Cloud Speed\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Layer\"}]},{\"t\":7,\"p\":1,\"n\":\"PNAM - Cloud Layer Colors\",\"c\":[{\"t\":7,\"p\":1,\"n\":\"Layer\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Color\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]}]}]},{\"t\":7,\"p\":1,\"n\":\"NAM0 - Colors by Types\\/Times\",\"c\":[{\"t\":7,\"p\":1,\"n\":\"Type\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Time\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"FNAM - Fog Distance\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Day - Near\"},{\"t\":5,\"p\":1,\"n\":\"Day - Far\"},{\"t\":5,\"p\":1,\"n\":\"Night - Near\"},{\"t\":5,\"p\":1,\"n\":\"Night - Far\"},{\"t\":5,\"p\":1,\"n\":\"Day - Power\"},{\"t\":5,\"p\":1,\"n\":\"Night - Fower\"}]},{\"t\":11,\"n\":\"INAM - Unused\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DATA - \",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Wind Speed\"},{\"t\":3,\"p\":1,\"n\":\"Cloud Speed (Lower)\"},{\"t\":3,\"p\":1,\"n\":\"Cloud Speed (Upper)\"},{\"t\":3,\"p\":1,\"n\":\"Trans Delta\"},{\"t\":3,\"p\":1,\"n\":\"Sun Glare\"},{\"t\":3,\"p\":1,\"n\":\"Sun Damage\"},{\"t\":3,\"p\":1,\"n\":\"Precipitation - Begin Fade In\"},{\"t\":3,\"p\":1,\"n\":\"Precipitation - End Fade Out\"},{\"t\":3,\"p\":1,\"n\":\"Thunder\\/Lightning - Begin Fade In\"},{\"t\":3,\"p\":1,\"n\":\"Thunder\\/Lightning - End Fade Out\"},{\"t\":3,\"p\":1,\"n\":\"Thunder\\/Lightning - Frequency\"},{\"t\":3,\"p\":1,\"n\":\"Weather Classification\"},{\"t\":6,\"p\":1,\"n\":\"Lightning Color\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"}]}]},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Sounds\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"SNAM - Sound\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Sound\"},{\"t\":3,\"p\":1,\"n\":\"Type\"}]}]}]},{\"t\":1,\"p\":1,\"n\":\"ACRE - Placed Creature\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":3,\"p\":1,\"n\":\"NAME - Base\"},{\"t\":3,\"p\":1,\"n\":\"XEZN - Encounter Zone\"},{\"t\":11,\"n\":\"XRGD - Ragdoll Data\"},{\"t\":11,\"n\":\"XRGB - Ragdoll Biped Data\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Patrol Data\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"XPRD - Idle Time\"},{\"p\":1,\"n\":\"XPPA - Patrol Script Marker\"},{\"t\":3,\"p\":1,\"n\":\"INAM - Idle\"},{\"t\":6,\"p\":1,\"n\":\"Embedded Script\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"SCHR - Basic Script Data\",\"c\":[{\"t\":11,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"RefCount\"},{\"t\":3,\"p\":1,\"n\":\"CompiledSize\"},{\"t\":3,\"p\":1,\"n\":\"VariableCount\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"}]},{\"t\":11,\"p\":1,\"n\":\"SCDA - Compiled Embedded Script\"},{\"t\":2,\"p\":1,\"n\":\"SCTX - Embedded Script Source\"},{\"t\":10,\"p\":1,\"n\":\"Local Variables\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Local Variable\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"SLSD - Local Variable Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Index\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"}]},{\"t\":2,\"p\":1,\"n\":\"SCVR - Name\"}]}]},{\"t\":8,\"p\":1,\"n\":\"References\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"SCRO - Global Reference\"},{\"t\":3,\"p\":1,\"n\":\"SCRV - Local Variable\"}]}]},{\"t\":3,\"p\":1,\"n\":\"TNAM - Topic\"}]},{\"t\":3,\"p\":1,\"n\":\"XLCM - Level Modifier\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Ownership\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"XOWN - Owner\"},{\"t\":3,\"p\":1,\"n\":\"XRNK - Faction rank\"}]},{\"t\":3,\"p\":1,\"n\":\"XMRC - Merchant Container\"},{\"t\":3,\"p\":1,\"n\":\"XCNT - Count\"},{\"t\":5,\"p\":1,\"n\":\"XRDS - Radius\"},{\"t\":5,\"p\":1,\"n\":\"XHLP - Health\"},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Linked Decals\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"XDCR - Decal\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":11,\"n\":\"Unknown\"}]}]},{\"t\":3,\"p\":1,\"n\":\"XLKR - Linked Reference\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"XCLP - Linked Reference Color\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Link Start Color\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Link End Color\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Activate Parents\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"XAPD - Flags\"},{\"t\":8,\"p\":1,\"n\":\"Activate Parent Refs\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"XAPR - Activate Parent Ref\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":5,\"p\":1,\"n\":\"Delay\"}]}]}]},{\"t\":2,\"p\":1,\"n\":\"XATO - Activation Prompt\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"XESP - Enable Parent\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":3,\"p\":1,\"n\":\"XEMI - Emittance\"},{\"t\":3,\"p\":1,\"n\":\"XMBR - MultiBound Reference\"},{\"p\":1,\"n\":\"XIBS - Ignored By Sandbox\"},{\"t\":5,\"p\":1,\"n\":\"XSCL - Scale\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DATA - Position\\/Rotation\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Position\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"X\"},{\"t\":5,\"p\":1,\"n\":\"Y\"},{\"t\":5,\"p\":1,\"n\":\"Z\"}]},{\"t\":6,\"p\":1,\"n\":\"Rotation\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"X\"},{\"t\":5,\"p\":1,\"n\":\"Y\"},{\"t\":5,\"p\":1,\"n\":\"Z\"}]}]}]}]},\"name\":\"Smash.All\",\"hash\":\"522394C0\",\"color\":128}"
  },
  {
    "path": "frontend/settings/Oblivion/Bash.Actors.ACBS.json",
    "content": "{\"records\":\"NPC_,CREA\",\"description\":\"Actors.ACBS tag from Wrye Bash.\\r\\n\\r\\nUsed when the mod modifies NPC ACBS configuration.\",\"tree\":{\"records\":[{\"t\":1,\"p\":1,\"n\":\"NPC_ - Non-Player Character\",\"c\":[{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"n\":\"FULL - Name\"},{\"t\":6,\"n\":\"Model\",\"c\":[{\"t\":2,\"n\":\"MODL - Model Filename\"},{\"t\":5,\"n\":\"MODB - Bound Radius\"},{\"t\":11,\"n\":\"MODT - Texture Files Hashes\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"ACBS - Configuration\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":3,\"p\":1,\"n\":\"Base spell points\"},{\"t\":3,\"p\":1,\"n\":\"Fatigue\"},{\"t\":3,\"p\":1,\"n\":\"Barter gold\"},{\"t\":3,\"p\":1,\"n\":\"Level (offset)\"},{\"t\":3,\"p\":1,\"n\":\"Calc min\"},{\"t\":3,\"p\":1,\"n\":\"Calc max\"}]},{\"t\":8,\"n\":\"Factions\",\"c\":[{\"t\":6,\"n\":\"SNAM - Faction\",\"c\":[{\"t\":3,\"n\":\"Faction\"},{\"t\":3,\"n\":\"Rank\"},{\"t\":11,\"n\":\"Unused\"}]}]},{\"t\":3,\"n\":\"INAM - Death item\"},{\"t\":3,\"n\":\"RNAM - Race\"},{\"t\":8,\"n\":\"Items\",\"c\":[{\"t\":6,\"n\":\"CNTO - Item\",\"c\":[{\"t\":3,\"n\":\"Item\"},{\"t\":3,\"n\":\"Count\"}]}]},{\"t\":8,\"n\":\"Spells\",\"c\":[{\"t\":3,\"n\":\"SPLO - Spell\"}]},{\"t\":3,\"n\":\"SCRI - Script\"},{\"t\":6,\"n\":\"AIDT - AI Data\",\"c\":[{\"t\":3,\"n\":\"Aggression\"},{\"t\":3,\"n\":\"Confidence\"},{\"t\":3,\"n\":\"Energy Level\"},{\"t\":3,\"n\":\"Responsibility\"},{\"t\":3,\"n\":\"Buys\\/Sells and Services\"},{\"t\":3,\"n\":\"Teaches\"},{\"t\":3,\"n\":\"Maximum training level\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":8,\"n\":\"AI Packages\",\"c\":[{\"t\":3,\"n\":\"PKID - AI Package\"}]},{\"t\":7,\"n\":\"KFFZ - Animations\",\"c\":[{\"t\":2,\"n\":\"Animation\"}]},{\"t\":3,\"n\":\"CNAM - Class\"},{\"t\":6,\"n\":\"DATA - Stats\",\"c\":[{\"t\":3,\"n\":\"Armorer\"},{\"t\":3,\"n\":\"Athletics\"},{\"t\":3,\"n\":\"Blade\"},{\"t\":3,\"n\":\"Block\"},{\"t\":3,\"n\":\"Blunt\"},{\"t\":3,\"n\":\"Hand to Hand\"},{\"t\":3,\"n\":\"Heavy Armor\"},{\"t\":3,\"n\":\"Alchemy\"},{\"t\":3,\"n\":\"Alteration\"},{\"t\":3,\"n\":\"Conjuration\"},{\"t\":3,\"n\":\"Destruction\"},{\"t\":3,\"n\":\"Illusion\"},{\"t\":3,\"n\":\"Mysticism\"},{\"t\":3,\"n\":\"Restoration\"},{\"t\":3,\"n\":\"Acrobatics\"},{\"t\":3,\"n\":\"Light Armor\"},{\"t\":3,\"n\":\"Marksman\"},{\"t\":3,\"n\":\"Mercantile\"},{\"t\":3,\"n\":\"Security\"},{\"t\":3,\"n\":\"Sneak\"},{\"t\":3,\"n\":\"Speechcraft\"},{\"t\":3,\"n\":\"Health\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":3,\"n\":\"Strength\"},{\"t\":3,\"n\":\"Intelligence\"},{\"t\":3,\"n\":\"Willpower\"},{\"t\":3,\"n\":\"Agility\"},{\"t\":3,\"n\":\"Speed\"},{\"t\":3,\"n\":\"Endurance\"},{\"t\":3,\"n\":\"Personality\"},{\"t\":3,\"n\":\"Luck\"}]},{\"t\":3,\"n\":\"HNAM - Hair\"},{\"t\":5,\"n\":\"LNAM - Hair length\"},{\"t\":7,\"n\":\"ENAM - Eyes\",\"c\":[{\"t\":3,\"n\":\"Eyes\"}]},{\"t\":6,\"n\":\"HCLR - Hair color\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":3,\"n\":\"ZNAM - Combat Style\"},{\"t\":6,\"n\":\"FaceGen Data\",\"c\":[{\"t\":11,\"n\":\"FGGS - FaceGen Geometry-Symmetric\"},{\"t\":11,\"n\":\"FGGA - FaceGen Geometry-Asymmetric\"},{\"t\":11,\"n\":\"FGTS - FaceGen Texture-Symmetric\"}]},{\"t\":11,\"n\":\"FNAM - Unknown\"}]},{\"t\":1,\"p\":1,\"n\":\"CREA - Creature\",\"c\":[{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"n\":\"FULL - Name\"},{\"t\":6,\"n\":\"Model\",\"c\":[{\"t\":2,\"n\":\"MODL - Model Filename\"},{\"t\":5,\"n\":\"MODB - Bound Radius\"},{\"t\":11,\"n\":\"MODT - Texture Files Hashes\"}]},{\"t\":8,\"n\":\"Items\",\"c\":[{\"t\":6,\"n\":\"CNTO - Item\",\"c\":[{\"t\":3,\"n\":\"Item\"},{\"t\":3,\"n\":\"Count\"}]}]},{\"t\":8,\"n\":\"Spells\",\"c\":[{\"t\":3,\"n\":\"SPLO - Spell\"}]},{\"t\":7,\"n\":\"NIFZ - Models\",\"c\":[{\"t\":2,\"n\":\"Model\"}]},{\"t\":11,\"n\":\"NIFT - Texture Files Hashes\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"ACBS - Configuration\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":3,\"p\":1,\"n\":\"Base spell points\"},{\"t\":3,\"p\":1,\"n\":\"Fatigue\"},{\"t\":3,\"p\":1,\"n\":\"Barter gold\"},{\"t\":3,\"p\":1,\"n\":\"Level (offset)\"},{\"t\":3,\"p\":1,\"n\":\"Calc min\"},{\"t\":3,\"p\":1,\"n\":\"Calc max\"}]},{\"t\":8,\"n\":\"Factions\",\"c\":[{\"t\":6,\"n\":\"SNAM - Faction\",\"c\":[{\"t\":3,\"n\":\"Faction\"},{\"t\":3,\"n\":\"Rank\"},{\"t\":11,\"n\":\"Unused\"}]}]},{\"t\":3,\"n\":\"INAM - Death item\"},{\"t\":3,\"n\":\"SCRI - Script\"},{\"t\":6,\"n\":\"AIDT - AI Data\",\"c\":[{\"t\":3,\"n\":\"Aggression\"},{\"t\":3,\"n\":\"Confidence\"},{\"t\":3,\"n\":\"Energy Level\"},{\"t\":3,\"n\":\"Responsibility\"},{\"t\":3,\"n\":\"Buys\\/Sells and Services\"},{\"t\":3,\"n\":\"Teaches\"},{\"t\":3,\"n\":\"Maximum training level\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":8,\"n\":\"AI Packages\",\"c\":[{\"t\":3,\"n\":\"PKID - AI Package\"}]},{\"t\":7,\"n\":\"KFFZ - Animations\",\"c\":[{\"t\":2,\"n\":\"Animation\"}]},{\"t\":6,\"n\":\"DATA - Creature Data\",\"c\":[{\"t\":3,\"n\":\"Type\"},{\"t\":3,\"n\":\"Combat Skill\"},{\"t\":3,\"n\":\"Magic Skill\"},{\"t\":3,\"n\":\"Stealth Skill\"},{\"t\":3,\"n\":\"Soul\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":3,\"n\":\"Health\"},{\"t\":3,\"n\":\"Attack Damage\"},{\"t\":3,\"n\":\"Strength\"},{\"t\":3,\"n\":\"Intelligence\"},{\"t\":3,\"n\":\"Willpower\"},{\"t\":3,\"n\":\"Agility\"},{\"t\":3,\"n\":\"Speed\"},{\"t\":3,\"n\":\"Endurance\"},{\"t\":3,\"n\":\"Personality\"},{\"t\":3,\"n\":\"Luck\"}]},{\"t\":3,\"n\":\"RNAM - Attack reach\"},{\"t\":3,\"n\":\"ZNAM - Combat Style\"},{\"t\":5,\"n\":\"TNAM - Turning Speed\"},{\"t\":5,\"n\":\"BNAM - Base Scale\"},{\"t\":5,\"n\":\"WNAM - Foot Weight\"},{\"t\":2,\"n\":\"NAM0 - Blood Spray\"},{\"t\":2,\"n\":\"NAM1 - Blood Decal\"},{\"t\":3,\"n\":\"CSCR - Inherits Sounds from\"},{\"t\":10,\"n\":\"Sound Types\",\"c\":[{\"t\":6,\"n\":\"Sound Type\",\"c\":[{\"t\":3,\"n\":\"CSDT - Type\"},{\"t\":10,\"n\":\"Sounds\",\"c\":[{\"t\":6,\"n\":\"Sound\",\"c\":[{\"t\":3,\"n\":\"CSDI - Sound\"},{\"t\":3,\"n\":\"CSDC - Sound Chance\"}]}]}]}]}]}]},\"name\":\"Bash.Actors.ACBS\",\"hash\":\"0AE1EBDE\",\"color\":255}"
  },
  {
    "path": "frontend/settings/Oblivion/Bash.Actors.AIData.json",
    "content": "{\"records\":\"NPC_,CREA\",\"description\":\"Actors.AIData tag from Wrye Bash.\\r\\n\\r\\nUsed when the mod modifies NPC AI data.\",\"tree\":{\"records\":[{\"t\":1,\"p\":1,\"n\":\"NPC_ - Non-Player Character\",\"c\":[{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"n\":\"FULL - Name\"},{\"t\":6,\"n\":\"Model\",\"c\":[{\"t\":2,\"n\":\"MODL - Model Filename\"},{\"t\":5,\"n\":\"MODB - Bound Radius\"},{\"t\":11,\"n\":\"MODT - Texture Files Hashes\"}]},{\"t\":6,\"n\":\"ACBS - Configuration\",\"c\":[{\"t\":3,\"n\":\"Flags\"},{\"t\":3,\"n\":\"Base spell points\"},{\"t\":3,\"n\":\"Fatigue\"},{\"t\":3,\"n\":\"Barter gold\"},{\"t\":3,\"n\":\"Level (offset)\"},{\"t\":3,\"n\":\"Calc min\"},{\"t\":3,\"n\":\"Calc max\"}]},{\"t\":8,\"n\":\"Factions\",\"c\":[{\"t\":6,\"n\":\"SNAM - Faction\",\"c\":[{\"t\":3,\"n\":\"Faction\"},{\"t\":3,\"n\":\"Rank\"},{\"t\":11,\"n\":\"Unused\"}]}]},{\"t\":3,\"n\":\"INAM - Death item\"},{\"t\":3,\"n\":\"RNAM - Race\"},{\"t\":8,\"n\":\"Items\",\"c\":[{\"t\":6,\"n\":\"CNTO - Item\",\"c\":[{\"t\":3,\"n\":\"Item\"},{\"t\":3,\"n\":\"Count\"}]}]},{\"t\":8,\"n\":\"Spells\",\"c\":[{\"t\":3,\"n\":\"SPLO - Spell\"}]},{\"t\":3,\"n\":\"SCRI - Script\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"AIDT - AI Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Aggression\"},{\"t\":3,\"p\":1,\"n\":\"Confidence\"},{\"t\":3,\"p\":1,\"n\":\"Energy Level\"},{\"t\":3,\"p\":1,\"n\":\"Responsibility\"},{\"t\":3,\"p\":1,\"n\":\"Buys\\/Sells and Services\"},{\"t\":3,\"p\":1,\"n\":\"Teaches\"},{\"t\":3,\"p\":1,\"n\":\"Maximum training level\"},{\"t\":11,\"p\":1,\"n\":\"Unused\"}]},{\"t\":8,\"n\":\"AI Packages\",\"c\":[{\"t\":3,\"n\":\"PKID - AI Package\"}]},{\"t\":7,\"n\":\"KFFZ - Animations\",\"c\":[{\"t\":2,\"n\":\"Animation\"}]},{\"t\":3,\"n\":\"CNAM - Class\"},{\"t\":6,\"n\":\"DATA - Stats\",\"c\":[{\"t\":3,\"n\":\"Armorer\"},{\"t\":3,\"n\":\"Athletics\"},{\"t\":3,\"n\":\"Blade\"},{\"t\":3,\"n\":\"Block\"},{\"t\":3,\"n\":\"Blunt\"},{\"t\":3,\"n\":\"Hand to Hand\"},{\"t\":3,\"n\":\"Heavy Armor\"},{\"t\":3,\"n\":\"Alchemy\"},{\"t\":3,\"n\":\"Alteration\"},{\"t\":3,\"n\":\"Conjuration\"},{\"t\":3,\"n\":\"Destruction\"},{\"t\":3,\"n\":\"Illusion\"},{\"t\":3,\"n\":\"Mysticism\"},{\"t\":3,\"n\":\"Restoration\"},{\"t\":3,\"n\":\"Acrobatics\"},{\"t\":3,\"n\":\"Light Armor\"},{\"t\":3,\"n\":\"Marksman\"},{\"t\":3,\"n\":\"Mercantile\"},{\"t\":3,\"n\":\"Security\"},{\"t\":3,\"n\":\"Sneak\"},{\"t\":3,\"n\":\"Speechcraft\"},{\"t\":3,\"n\":\"Health\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":3,\"n\":\"Strength\"},{\"t\":3,\"n\":\"Intelligence\"},{\"t\":3,\"n\":\"Willpower\"},{\"t\":3,\"n\":\"Agility\"},{\"t\":3,\"n\":\"Speed\"},{\"t\":3,\"n\":\"Endurance\"},{\"t\":3,\"n\":\"Personality\"},{\"t\":3,\"n\":\"Luck\"}]},{\"t\":3,\"n\":\"HNAM - Hair\"},{\"t\":5,\"n\":\"LNAM - Hair length\"},{\"t\":7,\"n\":\"ENAM - Eyes\",\"c\":[{\"t\":3,\"n\":\"Eyes\"}]},{\"t\":6,\"n\":\"HCLR - Hair color\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":3,\"n\":\"ZNAM - Combat Style\"},{\"t\":6,\"n\":\"FaceGen Data\",\"c\":[{\"t\":11,\"n\":\"FGGS - FaceGen Geometry-Symmetric\"},{\"t\":11,\"n\":\"FGGA - FaceGen Geometry-Asymmetric\"},{\"t\":11,\"n\":\"FGTS - FaceGen Texture-Symmetric\"}]},{\"t\":11,\"n\":\"FNAM - Unknown\"}]},{\"t\":1,\"p\":1,\"n\":\"CREA - Creature\",\"c\":[{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"n\":\"FULL - Name\"},{\"t\":6,\"n\":\"Model\",\"c\":[{\"t\":2,\"n\":\"MODL - Model Filename\"},{\"t\":5,\"n\":\"MODB - Bound Radius\"},{\"t\":11,\"n\":\"MODT - Texture Files Hashes\"}]},{\"t\":8,\"n\":\"Items\",\"c\":[{\"t\":6,\"n\":\"CNTO - Item\",\"c\":[{\"t\":3,\"n\":\"Item\"},{\"t\":3,\"n\":\"Count\"}]}]},{\"t\":8,\"n\":\"Spells\",\"c\":[{\"t\":3,\"n\":\"SPLO - Spell\"}]},{\"t\":7,\"n\":\"NIFZ - Models\",\"c\":[{\"t\":2,\"n\":\"Model\"}]},{\"t\":11,\"n\":\"NIFT - Texture Files Hashes\"},{\"t\":6,\"n\":\"ACBS - Configuration\",\"c\":[{\"t\":3,\"n\":\"Flags\"},{\"t\":3,\"n\":\"Base spell points\"},{\"t\":3,\"n\":\"Fatigue\"},{\"t\":3,\"n\":\"Barter gold\"},{\"t\":3,\"n\":\"Level (offset)\"},{\"t\":3,\"n\":\"Calc min\"},{\"t\":3,\"n\":\"Calc max\"}]},{\"t\":8,\"n\":\"Factions\",\"c\":[{\"t\":6,\"n\":\"SNAM - Faction\",\"c\":[{\"t\":3,\"n\":\"Faction\"},{\"t\":3,\"n\":\"Rank\"},{\"t\":11,\"n\":\"Unused\"}]}]},{\"t\":3,\"n\":\"INAM - Death item\"},{\"t\":3,\"n\":\"SCRI - Script\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"AIDT - AI Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Aggression\"},{\"t\":3,\"p\":1,\"n\":\"Confidence\"},{\"t\":3,\"p\":1,\"n\":\"Energy Level\"},{\"t\":3,\"p\":1,\"n\":\"Responsibility\"},{\"t\":3,\"p\":1,\"n\":\"Buys\\/Sells and Services\"},{\"t\":3,\"p\":1,\"n\":\"Teaches\"},{\"t\":3,\"p\":1,\"n\":\"Maximum training level\"},{\"t\":11,\"p\":1,\"n\":\"Unused\"}]},{\"t\":8,\"n\":\"AI Packages\",\"c\":[{\"t\":3,\"n\":\"PKID - AI Package\"}]},{\"t\":7,\"n\":\"KFFZ - Animations\",\"c\":[{\"t\":2,\"n\":\"Animation\"}]},{\"t\":6,\"n\":\"DATA - Creature Data\",\"c\":[{\"t\":3,\"n\":\"Type\"},{\"t\":3,\"n\":\"Combat Skill\"},{\"t\":3,\"n\":\"Magic Skill\"},{\"t\":3,\"n\":\"Stealth Skill\"},{\"t\":3,\"n\":\"Soul\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":3,\"n\":\"Health\"},{\"t\":3,\"n\":\"Attack Damage\"},{\"t\":3,\"n\":\"Strength\"},{\"t\":3,\"n\":\"Intelligence\"},{\"t\":3,\"n\":\"Willpower\"},{\"t\":3,\"n\":\"Agility\"},{\"t\":3,\"n\":\"Speed\"},{\"t\":3,\"n\":\"Endurance\"},{\"t\":3,\"n\":\"Personality\"},{\"t\":3,\"n\":\"Luck\"}]},{\"t\":3,\"n\":\"RNAM - Attack reach\"},{\"t\":3,\"n\":\"ZNAM - Combat Style\"},{\"t\":5,\"n\":\"TNAM - Turning Speed\"},{\"t\":5,\"n\":\"BNAM - Base Scale\"},{\"t\":5,\"n\":\"WNAM - Foot Weight\"},{\"t\":2,\"n\":\"NAM0 - Blood Spray\"},{\"t\":2,\"n\":\"NAM1 - Blood Decal\"},{\"t\":3,\"n\":\"CSCR - Inherits Sounds from\"},{\"t\":10,\"n\":\"Sound Types\",\"c\":[{\"t\":6,\"n\":\"Sound Type\",\"c\":[{\"t\":3,\"n\":\"CSDT - Type\"},{\"t\":10,\"n\":\"Sounds\",\"c\":[{\"t\":6,\"n\":\"Sound\",\"c\":[{\"t\":3,\"n\":\"CSDI - Sound\"},{\"t\":3,\"n\":\"CSDC - Sound Chance\"}]}]}]}]}]}]},\"name\":\"Bash.Actors.AIData\",\"hash\":\"20E41AEA\",\"color\":255}"
  },
  {
    "path": "frontend/settings/Oblivion/Bash.Actors.AIPackages.json",
    "content": "{\"records\":\"NPC_,CREA\",\"description\":\"Actors.AIPackages tag from Wrye Bash.\\r\\n\\r\\nUsed when the mod modifies NPC AI packages list.\",\"tree\":{\"records\":[{\"t\":1,\"p\":1,\"n\":\"NPC_ - Non-Player Character\",\"c\":[{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"n\":\"FULL - Name\"},{\"t\":6,\"n\":\"Model\",\"c\":[{\"t\":2,\"n\":\"MODL - Model Filename\"},{\"t\":5,\"n\":\"MODB - Bound Radius\"},{\"t\":11,\"n\":\"MODT - Texture Files Hashes\"}]},{\"t\":6,\"n\":\"ACBS - Configuration\",\"c\":[{\"t\":3,\"n\":\"Flags\"},{\"t\":3,\"n\":\"Base spell points\"},{\"t\":3,\"n\":\"Fatigue\"},{\"t\":3,\"n\":\"Barter gold\"},{\"t\":3,\"n\":\"Level (offset)\"},{\"t\":3,\"n\":\"Calc min\"},{\"t\":3,\"n\":\"Calc max\"}]},{\"t\":8,\"n\":\"Factions\",\"c\":[{\"t\":6,\"n\":\"SNAM - Faction\",\"c\":[{\"t\":3,\"n\":\"Faction\"},{\"t\":3,\"n\":\"Rank\"},{\"t\":11,\"n\":\"Unused\"}]}]},{\"t\":3,\"n\":\"INAM - Death item\"},{\"t\":3,\"n\":\"RNAM - Race\"},{\"t\":8,\"n\":\"Items\",\"c\":[{\"t\":6,\"n\":\"CNTO - Item\",\"c\":[{\"t\":3,\"n\":\"Item\"},{\"t\":3,\"n\":\"Count\"}]}]},{\"t\":8,\"n\":\"Spells\",\"c\":[{\"t\":3,\"n\":\"SPLO - Spell\"}]},{\"t\":3,\"n\":\"SCRI - Script\"},{\"t\":6,\"n\":\"AIDT - AI Data\",\"c\":[{\"t\":3,\"n\":\"Aggression\"},{\"t\":3,\"n\":\"Confidence\"},{\"t\":3,\"n\":\"Energy Level\"},{\"t\":3,\"n\":\"Responsibility\"},{\"t\":3,\"n\":\"Buys\\/Sells and Services\"},{\"t\":3,\"n\":\"Teaches\"},{\"t\":3,\"n\":\"Maximum training level\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":8,\"p\":1,\"n\":\"AI Packages\",\"d\":1,\"c\":[{\"t\":3,\"p\":1,\"n\":\"PKID - AI Package\"}]},{\"t\":7,\"n\":\"KFFZ - Animations\",\"c\":[{\"t\":2,\"n\":\"Animation\"}]},{\"t\":3,\"n\":\"CNAM - Class\"},{\"t\":6,\"n\":\"DATA - Stats\",\"c\":[{\"t\":3,\"n\":\"Armorer\"},{\"t\":3,\"n\":\"Athletics\"},{\"t\":3,\"n\":\"Blade\"},{\"t\":3,\"n\":\"Block\"},{\"t\":3,\"n\":\"Blunt\"},{\"t\":3,\"n\":\"Hand to Hand\"},{\"t\":3,\"n\":\"Heavy Armor\"},{\"t\":3,\"n\":\"Alchemy\"},{\"t\":3,\"n\":\"Alteration\"},{\"t\":3,\"n\":\"Conjuration\"},{\"t\":3,\"n\":\"Destruction\"},{\"t\":3,\"n\":\"Illusion\"},{\"t\":3,\"n\":\"Mysticism\"},{\"t\":3,\"n\":\"Restoration\"},{\"t\":3,\"n\":\"Acrobatics\"},{\"t\":3,\"n\":\"Light Armor\"},{\"t\":3,\"n\":\"Marksman\"},{\"t\":3,\"n\":\"Mercantile\"},{\"t\":3,\"n\":\"Security\"},{\"t\":3,\"n\":\"Sneak\"},{\"t\":3,\"n\":\"Speechcraft\"},{\"t\":3,\"n\":\"Health\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":3,\"n\":\"Strength\"},{\"t\":3,\"n\":\"Intelligence\"},{\"t\":3,\"n\":\"Willpower\"},{\"t\":3,\"n\":\"Agility\"},{\"t\":3,\"n\":\"Speed\"},{\"t\":3,\"n\":\"Endurance\"},{\"t\":3,\"n\":\"Personality\"},{\"t\":3,\"n\":\"Luck\"}]},{\"t\":3,\"n\":\"HNAM - Hair\"},{\"t\":5,\"n\":\"LNAM - Hair length\"},{\"t\":7,\"n\":\"ENAM - Eyes\",\"c\":[{\"t\":3,\"n\":\"Eyes\"}]},{\"t\":6,\"n\":\"HCLR - Hair color\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":3,\"n\":\"ZNAM - Combat Style\"},{\"t\":6,\"n\":\"FaceGen Data\",\"c\":[{\"t\":11,\"n\":\"FGGS - FaceGen Geometry-Symmetric\"},{\"t\":11,\"n\":\"FGGA - FaceGen Geometry-Asymmetric\"},{\"t\":11,\"n\":\"FGTS - FaceGen Texture-Symmetric\"}]},{\"t\":11,\"n\":\"FNAM - Unknown\"}]},{\"t\":1,\"p\":1,\"n\":\"CREA - Creature\",\"c\":[{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"n\":\"FULL - Name\"},{\"t\":6,\"n\":\"Model\",\"c\":[{\"t\":2,\"n\":\"MODL - Model Filename\"},{\"t\":5,\"n\":\"MODB - Bound Radius\"},{\"t\":11,\"n\":\"MODT - Texture Files Hashes\"}]},{\"t\":8,\"n\":\"Items\",\"c\":[{\"t\":6,\"n\":\"CNTO - Item\",\"c\":[{\"t\":3,\"n\":\"Item\"},{\"t\":3,\"n\":\"Count\"}]}]},{\"t\":8,\"n\":\"Spells\",\"c\":[{\"t\":3,\"n\":\"SPLO - Spell\"}]},{\"t\":7,\"n\":\"NIFZ - Models\",\"c\":[{\"t\":2,\"n\":\"Model\"}]},{\"t\":11,\"n\":\"NIFT - Texture Files Hashes\"},{\"t\":6,\"n\":\"ACBS - Configuration\",\"c\":[{\"t\":3,\"n\":\"Flags\"},{\"t\":3,\"n\":\"Base spell points\"},{\"t\":3,\"n\":\"Fatigue\"},{\"t\":3,\"n\":\"Barter gold\"},{\"t\":3,\"n\":\"Level (offset)\"},{\"t\":3,\"n\":\"Calc min\"},{\"t\":3,\"n\":\"Calc max\"}]},{\"t\":8,\"n\":\"Factions\",\"c\":[{\"t\":6,\"n\":\"SNAM - Faction\",\"c\":[{\"t\":3,\"n\":\"Faction\"},{\"t\":3,\"n\":\"Rank\"},{\"t\":11,\"n\":\"Unused\"}]}]},{\"t\":3,\"n\":\"INAM - Death item\"},{\"t\":3,\"n\":\"SCRI - Script\"},{\"t\":6,\"n\":\"AIDT - AI Data\",\"c\":[{\"t\":3,\"n\":\"Aggression\"},{\"t\":3,\"n\":\"Confidence\"},{\"t\":3,\"n\":\"Energy Level\"},{\"t\":3,\"n\":\"Responsibility\"},{\"t\":3,\"n\":\"Buys\\/Sells and Services\"},{\"t\":3,\"n\":\"Teaches\"},{\"t\":3,\"n\":\"Maximum training level\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":8,\"p\":1,\"n\":\"AI Packages\",\"d\":1,\"c\":[{\"t\":3,\"p\":1,\"n\":\"PKID - AI Package\"}]},{\"t\":7,\"n\":\"KFFZ - Animations\",\"c\":[{\"t\":2,\"n\":\"Animation\"}]},{\"t\":6,\"n\":\"DATA - Creature Data\",\"c\":[{\"t\":3,\"n\":\"Type\"},{\"t\":3,\"n\":\"Combat Skill\"},{\"t\":3,\"n\":\"Magic Skill\"},{\"t\":3,\"n\":\"Stealth Skill\"},{\"t\":3,\"n\":\"Soul\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":3,\"n\":\"Health\"},{\"t\":3,\"n\":\"Attack Damage\"},{\"t\":3,\"n\":\"Strength\"},{\"t\":3,\"n\":\"Intelligence\"},{\"t\":3,\"n\":\"Willpower\"},{\"t\":3,\"n\":\"Agility\"},{\"t\":3,\"n\":\"Speed\"},{\"t\":3,\"n\":\"Endurance\"},{\"t\":3,\"n\":\"Personality\"},{\"t\":3,\"n\":\"Luck\"}]},{\"t\":3,\"n\":\"RNAM - Attack reach\"},{\"t\":3,\"n\":\"ZNAM - Combat Style\"},{\"t\":5,\"n\":\"TNAM - Turning Speed\"},{\"t\":5,\"n\":\"BNAM - Base Scale\"},{\"t\":5,\"n\":\"WNAM - Foot Weight\"},{\"t\":2,\"n\":\"NAM0 - Blood Spray\"},{\"t\":2,\"n\":\"NAM1 - Blood Decal\"},{\"t\":3,\"n\":\"CSCR - Inherits Sounds from\"},{\"t\":10,\"n\":\"Sound Types\",\"c\":[{\"t\":6,\"n\":\"Sound Type\",\"c\":[{\"t\":3,\"n\":\"CSDT - Type\"},{\"t\":10,\"n\":\"Sounds\",\"c\":[{\"t\":6,\"n\":\"Sound\",\"c\":[{\"t\":3,\"n\":\"CSDI - Sound\"},{\"t\":3,\"n\":\"CSDC - Sound Chance\"}]}]}]}]}]}]},\"name\":\"Bash.Actors.AIPackages\",\"hash\":\"D1B8291B\",\"color\":255}"
  },
  {
    "path": "frontend/settings/Oblivion/Bash.Actors.Animations.json",
    "content": "{\"records\":\"NPC_,CREA\",\"description\":\"Actors.Animations tag from Wrye Bash.\\r\\n\\r\\nUsed when the mod modifies creature or NPC special animations lists.\",\"tree\":{\"records\":[{\"t\":1,\"p\":1,\"n\":\"NPC_ - Non-Player Character\",\"c\":[{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"n\":\"FULL - Name\"},{\"t\":6,\"n\":\"Model\",\"c\":[{\"t\":2,\"n\":\"MODL - Model Filename\"},{\"t\":5,\"n\":\"MODB - Bound Radius\"},{\"t\":11,\"n\":\"MODT - Texture Files Hashes\"}]},{\"t\":6,\"n\":\"ACBS - Configuration\",\"c\":[{\"t\":3,\"n\":\"Flags\"},{\"t\":3,\"n\":\"Base spell points\"},{\"t\":3,\"n\":\"Fatigue\"},{\"t\":3,\"n\":\"Barter gold\"},{\"t\":3,\"n\":\"Level (offset)\"},{\"t\":3,\"n\":\"Calc min\"},{\"t\":3,\"n\":\"Calc max\"}]},{\"t\":8,\"n\":\"Factions\",\"c\":[{\"t\":6,\"n\":\"SNAM - Faction\",\"c\":[{\"t\":3,\"n\":\"Faction\"},{\"t\":3,\"n\":\"Rank\"},{\"t\":11,\"n\":\"Unused\"}]}]},{\"t\":3,\"n\":\"INAM - Death item\"},{\"t\":3,\"n\":\"RNAM - Race\"},{\"t\":8,\"n\":\"Items\",\"c\":[{\"t\":6,\"n\":\"CNTO - Item\",\"c\":[{\"t\":3,\"n\":\"Item\"},{\"t\":3,\"n\":\"Count\"}]}]},{\"t\":8,\"n\":\"Spells\",\"c\":[{\"t\":3,\"n\":\"SPLO - Spell\"}]},{\"t\":3,\"n\":\"SCRI - Script\"},{\"t\":6,\"n\":\"AIDT - AI Data\",\"c\":[{\"t\":3,\"n\":\"Aggression\"},{\"t\":3,\"n\":\"Confidence\"},{\"t\":3,\"n\":\"Energy Level\"},{\"t\":3,\"n\":\"Responsibility\"},{\"t\":3,\"n\":\"Buys\\/Sells and Services\"},{\"t\":3,\"n\":\"Teaches\"},{\"t\":3,\"n\":\"Maximum training level\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":8,\"n\":\"AI Packages\",\"c\":[{\"t\":3,\"n\":\"PKID - AI Package\"}]},{\"t\":7,\"s\":1,\"p\":1,\"n\":\"KFFZ - Animations\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"Animation\"}]},{\"t\":3,\"n\":\"CNAM - Class\"},{\"t\":6,\"n\":\"DATA - Stats\",\"c\":[{\"t\":3,\"n\":\"Armorer\"},{\"t\":3,\"n\":\"Athletics\"},{\"t\":3,\"n\":\"Blade\"},{\"t\":3,\"n\":\"Block\"},{\"t\":3,\"n\":\"Blunt\"},{\"t\":3,\"n\":\"Hand to Hand\"},{\"t\":3,\"n\":\"Heavy Armor\"},{\"t\":3,\"n\":\"Alchemy\"},{\"t\":3,\"n\":\"Alteration\"},{\"t\":3,\"n\":\"Conjuration\"},{\"t\":3,\"n\":\"Destruction\"},{\"t\":3,\"n\":\"Illusion\"},{\"t\":3,\"n\":\"Mysticism\"},{\"t\":3,\"n\":\"Restoration\"},{\"t\":3,\"n\":\"Acrobatics\"},{\"t\":3,\"n\":\"Light Armor\"},{\"t\":3,\"n\":\"Marksman\"},{\"t\":3,\"n\":\"Mercantile\"},{\"t\":3,\"n\":\"Security\"},{\"t\":3,\"n\":\"Sneak\"},{\"t\":3,\"n\":\"Speechcraft\"},{\"t\":3,\"n\":\"Health\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":3,\"n\":\"Strength\"},{\"t\":3,\"n\":\"Intelligence\"},{\"t\":3,\"n\":\"Willpower\"},{\"t\":3,\"n\":\"Agility\"},{\"t\":3,\"n\":\"Speed\"},{\"t\":3,\"n\":\"Endurance\"},{\"t\":3,\"n\":\"Personality\"},{\"t\":3,\"n\":\"Luck\"}]},{\"t\":3,\"n\":\"HNAM - Hair\"},{\"t\":5,\"n\":\"LNAM - Hair length\"},{\"t\":7,\"n\":\"ENAM - Eyes\",\"c\":[{\"t\":3,\"n\":\"Eyes\"}]},{\"t\":6,\"n\":\"HCLR - Hair color\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":3,\"n\":\"ZNAM - Combat Style\"},{\"t\":6,\"n\":\"FaceGen Data\",\"c\":[{\"t\":11,\"n\":\"FGGS - FaceGen Geometry-Symmetric\"},{\"t\":11,\"n\":\"FGGA - FaceGen Geometry-Asymmetric\"},{\"t\":11,\"n\":\"FGTS - FaceGen Texture-Symmetric\"}]},{\"t\":11,\"n\":\"FNAM - Unknown\"}]},{\"t\":1,\"p\":1,\"n\":\"CREA - Creature\",\"c\":[{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"n\":\"FULL - Name\"},{\"t\":6,\"n\":\"Model\",\"c\":[{\"t\":2,\"n\":\"MODL - Model Filename\"},{\"t\":5,\"n\":\"MODB - Bound Radius\"},{\"t\":11,\"n\":\"MODT - Texture Files Hashes\"}]},{\"t\":8,\"n\":\"Items\",\"c\":[{\"t\":6,\"n\":\"CNTO - Item\",\"c\":[{\"t\":3,\"n\":\"Item\"},{\"t\":3,\"n\":\"Count\"}]}]},{\"t\":8,\"n\":\"Spells\",\"c\":[{\"t\":3,\"n\":\"SPLO - Spell\"}]},{\"t\":7,\"n\":\"NIFZ - Models\",\"c\":[{\"t\":2,\"n\":\"Model\"}]},{\"t\":11,\"n\":\"NIFT - Texture Files Hashes\"},{\"t\":6,\"n\":\"ACBS - Configuration\",\"c\":[{\"t\":3,\"n\":\"Flags\"},{\"t\":3,\"n\":\"Base spell points\"},{\"t\":3,\"n\":\"Fatigue\"},{\"t\":3,\"n\":\"Barter gold\"},{\"t\":3,\"n\":\"Level (offset)\"},{\"t\":3,\"n\":\"Calc min\"},{\"t\":3,\"n\":\"Calc max\"}]},{\"t\":8,\"n\":\"Factions\",\"c\":[{\"t\":6,\"n\":\"SNAM - Faction\",\"c\":[{\"t\":3,\"n\":\"Faction\"},{\"t\":3,\"n\":\"Rank\"},{\"t\":11,\"n\":\"Unused\"}]}]},{\"t\":3,\"n\":\"INAM - Death item\"},{\"t\":3,\"n\":\"SCRI - Script\"},{\"t\":6,\"n\":\"AIDT - AI Data\",\"c\":[{\"t\":3,\"n\":\"Aggression\"},{\"t\":3,\"n\":\"Confidence\"},{\"t\":3,\"n\":\"Energy Level\"},{\"t\":3,\"n\":\"Responsibility\"},{\"t\":3,\"n\":\"Buys\\/Sells and Services\"},{\"t\":3,\"n\":\"Teaches\"},{\"t\":3,\"n\":\"Maximum training level\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":8,\"n\":\"AI Packages\",\"c\":[{\"t\":3,\"n\":\"PKID - AI Package\"}]},{\"t\":7,\"s\":1,\"p\":1,\"n\":\"KFFZ - Animations\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"Animation\"}]},{\"t\":6,\"n\":\"DATA - Creature Data\",\"c\":[{\"t\":3,\"n\":\"Type\"},{\"t\":3,\"n\":\"Combat Skill\"},{\"t\":3,\"n\":\"Magic Skill\"},{\"t\":3,\"n\":\"Stealth Skill\"},{\"t\":3,\"n\":\"Soul\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":3,\"n\":\"Health\"},{\"t\":3,\"n\":\"Attack Damage\"},{\"t\":3,\"n\":\"Strength\"},{\"t\":3,\"n\":\"Intelligence\"},{\"t\":3,\"n\":\"Willpower\"},{\"t\":3,\"n\":\"Agility\"},{\"t\":3,\"n\":\"Speed\"},{\"t\":3,\"n\":\"Endurance\"},{\"t\":3,\"n\":\"Personality\"},{\"t\":3,\"n\":\"Luck\"}]},{\"t\":3,\"n\":\"RNAM - Attack reach\"},{\"t\":3,\"n\":\"ZNAM - Combat Style\"},{\"t\":5,\"n\":\"TNAM - Turning Speed\"},{\"t\":5,\"n\":\"BNAM - Base Scale\"},{\"t\":5,\"n\":\"WNAM - Foot Weight\"},{\"t\":2,\"n\":\"NAM0 - Blood Spray\"},{\"t\":2,\"n\":\"NAM1 - Blood Decal\"},{\"t\":3,\"n\":\"CSCR - Inherits Sounds from\"},{\"t\":10,\"n\":\"Sound Types\",\"c\":[{\"t\":6,\"n\":\"Sound Type\",\"c\":[{\"t\":3,\"n\":\"CSDT - Type\"},{\"t\":10,\"n\":\"Sounds\",\"c\":[{\"t\":6,\"n\":\"Sound\",\"c\":[{\"t\":3,\"n\":\"CSDI - Sound\"},{\"t\":3,\"n\":\"CSDC - Sound Chance\"}]}]}]}]}]}]},\"name\":\"Bash.Actors.Animations\",\"hash\":\"F1DB25EA\",\"color\":255}"
  },
  {
    "path": "frontend/settings/Oblivion/Bash.Actors.CombatStyle.json",
    "content": "{\"records\":\"NPC_,CREA\",\"description\":\"Actors.CombatStyle tag from Wrye Bash.\\r\\n\\r\\nUsed when the mod modifies NPC combat styles.\",\"tree\":{\"records\":[{\"t\":1,\"p\":1,\"n\":\"NPC_ - Non-Player Character\",\"c\":[{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"n\":\"FULL - Name\"},{\"t\":6,\"n\":\"Model\",\"c\":[{\"t\":2,\"n\":\"MODL - Model Filename\"},{\"t\":5,\"n\":\"MODB - Bound Radius\"},{\"t\":11,\"n\":\"MODT - Texture Files Hashes\"}]},{\"t\":6,\"n\":\"ACBS - Configuration\",\"c\":[{\"t\":3,\"n\":\"Flags\"},{\"t\":3,\"n\":\"Base spell points\"},{\"t\":3,\"n\":\"Fatigue\"},{\"t\":3,\"n\":\"Barter gold\"},{\"t\":3,\"n\":\"Level (offset)\"},{\"t\":3,\"n\":\"Calc min\"},{\"t\":3,\"n\":\"Calc max\"}]},{\"t\":8,\"n\":\"Factions\",\"c\":[{\"t\":6,\"n\":\"SNAM - Faction\",\"c\":[{\"t\":3,\"n\":\"Faction\"},{\"t\":3,\"n\":\"Rank\"},{\"t\":11,\"n\":\"Unused\"}]}]},{\"t\":3,\"n\":\"INAM - Death item\"},{\"t\":3,\"n\":\"RNAM - Race\"},{\"t\":8,\"n\":\"Items\",\"c\":[{\"t\":6,\"n\":\"CNTO - Item\",\"c\":[{\"t\":3,\"n\":\"Item\"},{\"t\":3,\"n\":\"Count\"}]}]},{\"t\":8,\"n\":\"Spells\",\"c\":[{\"t\":3,\"n\":\"SPLO - Spell\"}]},{\"t\":3,\"n\":\"SCRI - Script\"},{\"t\":6,\"n\":\"AIDT - AI Data\",\"c\":[{\"t\":3,\"n\":\"Aggression\"},{\"t\":3,\"n\":\"Confidence\"},{\"t\":3,\"n\":\"Energy Level\"},{\"t\":3,\"n\":\"Responsibility\"},{\"t\":3,\"n\":\"Buys\\/Sells and Services\"},{\"t\":3,\"n\":\"Teaches\"},{\"t\":3,\"n\":\"Maximum training level\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":8,\"n\":\"AI Packages\",\"c\":[{\"t\":3,\"n\":\"PKID - AI Package\"}]},{\"t\":7,\"n\":\"KFFZ - Animations\",\"c\":[{\"t\":2,\"n\":\"Animation\"}]},{\"t\":3,\"n\":\"CNAM - Class\"},{\"t\":6,\"n\":\"DATA - Stats\",\"c\":[{\"t\":3,\"n\":\"Armorer\"},{\"t\":3,\"n\":\"Athletics\"},{\"t\":3,\"n\":\"Blade\"},{\"t\":3,\"n\":\"Block\"},{\"t\":3,\"n\":\"Blunt\"},{\"t\":3,\"n\":\"Hand to Hand\"},{\"t\":3,\"n\":\"Heavy Armor\"},{\"t\":3,\"n\":\"Alchemy\"},{\"t\":3,\"n\":\"Alteration\"},{\"t\":3,\"n\":\"Conjuration\"},{\"t\":3,\"n\":\"Destruction\"},{\"t\":3,\"n\":\"Illusion\"},{\"t\":3,\"n\":\"Mysticism\"},{\"t\":3,\"n\":\"Restoration\"},{\"t\":3,\"n\":\"Acrobatics\"},{\"t\":3,\"n\":\"Light Armor\"},{\"t\":3,\"n\":\"Marksman\"},{\"t\":3,\"n\":\"Mercantile\"},{\"t\":3,\"n\":\"Security\"},{\"t\":3,\"n\":\"Sneak\"},{\"t\":3,\"n\":\"Speechcraft\"},{\"t\":3,\"n\":\"Health\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":3,\"n\":\"Strength\"},{\"t\":3,\"n\":\"Intelligence\"},{\"t\":3,\"n\":\"Willpower\"},{\"t\":3,\"n\":\"Agility\"},{\"t\":3,\"n\":\"Speed\"},{\"t\":3,\"n\":\"Endurance\"},{\"t\":3,\"n\":\"Personality\"},{\"t\":3,\"n\":\"Luck\"}]},{\"t\":3,\"n\":\"HNAM - Hair\"},{\"t\":5,\"n\":\"LNAM - Hair length\"},{\"t\":7,\"n\":\"ENAM - Eyes\",\"c\":[{\"t\":3,\"n\":\"Eyes\"}]},{\"t\":6,\"n\":\"HCLR - Hair color\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":3,\"p\":1,\"n\":\"ZNAM - Combat Style\"},{\"t\":6,\"n\":\"FaceGen Data\",\"c\":[{\"t\":11,\"n\":\"FGGS - FaceGen Geometry-Symmetric\"},{\"t\":11,\"n\":\"FGGA - FaceGen Geometry-Asymmetric\"},{\"t\":11,\"n\":\"FGTS - FaceGen Texture-Symmetric\"}]},{\"t\":11,\"n\":\"FNAM - Unknown\"}]},{\"t\":1,\"p\":1,\"n\":\"CREA - Creature\",\"c\":[{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"n\":\"FULL - Name\"},{\"t\":6,\"n\":\"Model\",\"c\":[{\"t\":2,\"n\":\"MODL - Model Filename\"},{\"t\":5,\"n\":\"MODB - Bound Radius\"},{\"t\":11,\"n\":\"MODT - Texture Files Hashes\"}]},{\"t\":8,\"n\":\"Items\",\"c\":[{\"t\":6,\"n\":\"CNTO - Item\",\"c\":[{\"t\":3,\"n\":\"Item\"},{\"t\":3,\"n\":\"Count\"}]}]},{\"t\":8,\"n\":\"Spells\",\"c\":[{\"t\":3,\"n\":\"SPLO - Spell\"}]},{\"t\":7,\"n\":\"NIFZ - Models\",\"c\":[{\"t\":2,\"n\":\"Model\"}]},{\"t\":11,\"n\":\"NIFT - Texture Files Hashes\"},{\"t\":6,\"n\":\"ACBS - Configuration\",\"c\":[{\"t\":3,\"n\":\"Flags\"},{\"t\":3,\"n\":\"Base spell points\"},{\"t\":3,\"n\":\"Fatigue\"},{\"t\":3,\"n\":\"Barter gold\"},{\"t\":3,\"n\":\"Level (offset)\"},{\"t\":3,\"n\":\"Calc min\"},{\"t\":3,\"n\":\"Calc max\"}]},{\"t\":8,\"n\":\"Factions\",\"c\":[{\"t\":6,\"n\":\"SNAM - Faction\",\"c\":[{\"t\":3,\"n\":\"Faction\"},{\"t\":3,\"n\":\"Rank\"},{\"t\":11,\"n\":\"Unused\"}]}]},{\"t\":3,\"n\":\"INAM - Death item\"},{\"t\":3,\"n\":\"SCRI - Script\"},{\"t\":6,\"n\":\"AIDT - AI Data\",\"c\":[{\"t\":3,\"n\":\"Aggression\"},{\"t\":3,\"n\":\"Confidence\"},{\"t\":3,\"n\":\"Energy Level\"},{\"t\":3,\"n\":\"Responsibility\"},{\"t\":3,\"n\":\"Buys\\/Sells and Services\"},{\"t\":3,\"n\":\"Teaches\"},{\"t\":3,\"n\":\"Maximum training level\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":8,\"n\":\"AI Packages\",\"c\":[{\"t\":3,\"n\":\"PKID - AI Package\"}]},{\"t\":7,\"n\":\"KFFZ - Animations\",\"c\":[{\"t\":2,\"n\":\"Animation\"}]},{\"t\":6,\"n\":\"DATA - Creature Data\",\"c\":[{\"t\":3,\"n\":\"Type\"},{\"t\":3,\"n\":\"Combat Skill\"},{\"t\":3,\"n\":\"Magic Skill\"},{\"t\":3,\"n\":\"Stealth Skill\"},{\"t\":3,\"n\":\"Soul\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":3,\"n\":\"Health\"},{\"t\":3,\"n\":\"Attack Damage\"},{\"t\":3,\"n\":\"Strength\"},{\"t\":3,\"n\":\"Intelligence\"},{\"t\":3,\"n\":\"Willpower\"},{\"t\":3,\"n\":\"Agility\"},{\"t\":3,\"n\":\"Speed\"},{\"t\":3,\"n\":\"Endurance\"},{\"t\":3,\"n\":\"Personality\"},{\"t\":3,\"n\":\"Luck\"}]},{\"t\":3,\"n\":\"RNAM - Attack reach\"},{\"t\":3,\"p\":1,\"n\":\"ZNAM - Combat Style\"},{\"t\":5,\"n\":\"TNAM - Turning Speed\"},{\"t\":5,\"n\":\"BNAM - Base Scale\"},{\"t\":5,\"n\":\"WNAM - Foot Weight\"},{\"t\":2,\"n\":\"NAM0 - Blood Spray\"},{\"t\":2,\"n\":\"NAM1 - Blood Decal\"},{\"t\":3,\"n\":\"CSCR - Inherits Sounds from\"},{\"t\":10,\"n\":\"Sound Types\",\"c\":[{\"t\":6,\"n\":\"Sound Type\",\"c\":[{\"t\":3,\"n\":\"CSDT - Type\"},{\"t\":10,\"n\":\"Sounds\",\"c\":[{\"t\":6,\"n\":\"Sound\",\"c\":[{\"t\":3,\"n\":\"CSDI - Sound\"},{\"t\":3,\"n\":\"CSDC - Sound Chance\"}]}]}]}]}]}]},\"name\":\"Bash.Actors.CombatStyle\",\"hash\":\"6815F8AC\",\"color\":255}"
  },
  {
    "path": "frontend/settings/Oblivion/Bash.Actors.DeathItem.json",
    "content": "{\"records\":\"NPC_,CREA\",\"description\":\"Actors.DeathItem tag from Wrye Bash.\\r\\n\\r\\nUsed when the mod modifies creature or NPC death items.\",\"tree\":{\"records\":[{\"t\":1,\"p\":1,\"n\":\"NPC_ - Non-Player Character\",\"c\":[{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"n\":\"FULL - Name\"},{\"t\":6,\"n\":\"Model\",\"c\":[{\"t\":2,\"n\":\"MODL - Model Filename\"},{\"t\":5,\"n\":\"MODB - Bound Radius\"},{\"t\":11,\"n\":\"MODT - Texture Files Hashes\"}]},{\"t\":6,\"n\":\"ACBS - Configuration\",\"c\":[{\"t\":3,\"n\":\"Flags\"},{\"t\":3,\"n\":\"Base spell points\"},{\"t\":3,\"n\":\"Fatigue\"},{\"t\":3,\"n\":\"Barter gold\"},{\"t\":3,\"n\":\"Level (offset)\"},{\"t\":3,\"n\":\"Calc min\"},{\"t\":3,\"n\":\"Calc max\"}]},{\"t\":8,\"n\":\"Factions\",\"c\":[{\"t\":6,\"n\":\"SNAM - Faction\",\"c\":[{\"t\":3,\"n\":\"Faction\"},{\"t\":3,\"n\":\"Rank\"},{\"t\":11,\"n\":\"Unused\"}]}]},{\"t\":3,\"p\":1,\"n\":\"INAM - Death item\"},{\"t\":3,\"n\":\"RNAM - Race\"},{\"t\":8,\"n\":\"Items\",\"c\":[{\"t\":6,\"n\":\"CNTO - Item\",\"c\":[{\"t\":3,\"n\":\"Item\"},{\"t\":3,\"n\":\"Count\"}]}]},{\"t\":8,\"n\":\"Spells\",\"c\":[{\"t\":3,\"n\":\"SPLO - Spell\"}]},{\"t\":3,\"n\":\"SCRI - Script\"},{\"t\":6,\"n\":\"AIDT - AI Data\",\"c\":[{\"t\":3,\"n\":\"Aggression\"},{\"t\":3,\"n\":\"Confidence\"},{\"t\":3,\"n\":\"Energy Level\"},{\"t\":3,\"n\":\"Responsibility\"},{\"t\":3,\"n\":\"Buys\\/Sells and Services\"},{\"t\":3,\"n\":\"Teaches\"},{\"t\":3,\"n\":\"Maximum training level\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":8,\"n\":\"AI Packages\",\"c\":[{\"t\":3,\"n\":\"PKID - AI Package\"}]},{\"t\":7,\"n\":\"KFFZ - Animations\",\"c\":[{\"t\":2,\"n\":\"Animation\"}]},{\"t\":3,\"n\":\"CNAM - Class\"},{\"t\":6,\"n\":\"DATA - Stats\",\"c\":[{\"t\":3,\"n\":\"Armorer\"},{\"t\":3,\"n\":\"Athletics\"},{\"t\":3,\"n\":\"Blade\"},{\"t\":3,\"n\":\"Block\"},{\"t\":3,\"n\":\"Blunt\"},{\"t\":3,\"n\":\"Hand to Hand\"},{\"t\":3,\"n\":\"Heavy Armor\"},{\"t\":3,\"n\":\"Alchemy\"},{\"t\":3,\"n\":\"Alteration\"},{\"t\":3,\"n\":\"Conjuration\"},{\"t\":3,\"n\":\"Destruction\"},{\"t\":3,\"n\":\"Illusion\"},{\"t\":3,\"n\":\"Mysticism\"},{\"t\":3,\"n\":\"Restoration\"},{\"t\":3,\"n\":\"Acrobatics\"},{\"t\":3,\"n\":\"Light Armor\"},{\"t\":3,\"n\":\"Marksman\"},{\"t\":3,\"n\":\"Mercantile\"},{\"t\":3,\"n\":\"Security\"},{\"t\":3,\"n\":\"Sneak\"},{\"t\":3,\"n\":\"Speechcraft\"},{\"t\":3,\"n\":\"Health\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":3,\"n\":\"Strength\"},{\"t\":3,\"n\":\"Intelligence\"},{\"t\":3,\"n\":\"Willpower\"},{\"t\":3,\"n\":\"Agility\"},{\"t\":3,\"n\":\"Speed\"},{\"t\":3,\"n\":\"Endurance\"},{\"t\":3,\"n\":\"Personality\"},{\"t\":3,\"n\":\"Luck\"}]},{\"t\":3,\"n\":\"HNAM - Hair\"},{\"t\":5,\"n\":\"LNAM - Hair length\"},{\"t\":7,\"n\":\"ENAM - Eyes\",\"c\":[{\"t\":3,\"n\":\"Eyes\"}]},{\"t\":6,\"n\":\"HCLR - Hair color\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":3,\"n\":\"ZNAM - Combat Style\"},{\"t\":6,\"n\":\"FaceGen Data\",\"c\":[{\"t\":11,\"n\":\"FGGS - FaceGen Geometry-Symmetric\"},{\"t\":11,\"n\":\"FGGA - FaceGen Geometry-Asymmetric\"},{\"t\":11,\"n\":\"FGTS - FaceGen Texture-Symmetric\"}]},{\"t\":11,\"n\":\"FNAM - Unknown\"}]},{\"t\":1,\"p\":1,\"n\":\"CREA - Creature\",\"c\":[{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"n\":\"FULL - Name\"},{\"t\":6,\"n\":\"Model\",\"c\":[{\"t\":2,\"n\":\"MODL - Model Filename\"},{\"t\":5,\"n\":\"MODB - Bound Radius\"},{\"t\":11,\"n\":\"MODT - Texture Files Hashes\"}]},{\"t\":8,\"n\":\"Items\",\"c\":[{\"t\":6,\"n\":\"CNTO - Item\",\"c\":[{\"t\":3,\"n\":\"Item\"},{\"t\":3,\"n\":\"Count\"}]}]},{\"t\":8,\"n\":\"Spells\",\"c\":[{\"t\":3,\"n\":\"SPLO - Spell\"}]},{\"t\":7,\"n\":\"NIFZ - Models\",\"c\":[{\"t\":2,\"n\":\"Model\"}]},{\"t\":11,\"n\":\"NIFT - Texture Files Hashes\"},{\"t\":6,\"n\":\"ACBS - Configuration\",\"c\":[{\"t\":3,\"n\":\"Flags\"},{\"t\":3,\"n\":\"Base spell points\"},{\"t\":3,\"n\":\"Fatigue\"},{\"t\":3,\"n\":\"Barter gold\"},{\"t\":3,\"n\":\"Level (offset)\"},{\"t\":3,\"n\":\"Calc min\"},{\"t\":3,\"n\":\"Calc max\"}]},{\"t\":8,\"n\":\"Factions\",\"c\":[{\"t\":6,\"n\":\"SNAM - Faction\",\"c\":[{\"t\":3,\"n\":\"Faction\"},{\"t\":3,\"n\":\"Rank\"},{\"t\":11,\"n\":\"Unused\"}]}]},{\"t\":3,\"p\":1,\"n\":\"INAM - Death item\"},{\"t\":3,\"n\":\"SCRI - Script\"},{\"t\":6,\"n\":\"AIDT - AI Data\",\"c\":[{\"t\":3,\"n\":\"Aggression\"},{\"t\":3,\"n\":\"Confidence\"},{\"t\":3,\"n\":\"Energy Level\"},{\"t\":3,\"n\":\"Responsibility\"},{\"t\":3,\"n\":\"Buys\\/Sells and Services\"},{\"t\":3,\"n\":\"Teaches\"},{\"t\":3,\"n\":\"Maximum training level\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":8,\"n\":\"AI Packages\",\"c\":[{\"t\":3,\"n\":\"PKID - AI Package\"}]},{\"t\":7,\"n\":\"KFFZ - Animations\",\"c\":[{\"t\":2,\"n\":\"Animation\"}]},{\"t\":6,\"n\":\"DATA - Creature Data\",\"c\":[{\"t\":3,\"n\":\"Type\"},{\"t\":3,\"n\":\"Combat Skill\"},{\"t\":3,\"n\":\"Magic Skill\"},{\"t\":3,\"n\":\"Stealth Skill\"},{\"t\":3,\"n\":\"Soul\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":3,\"n\":\"Health\"},{\"t\":3,\"n\":\"Attack Damage\"},{\"t\":3,\"n\":\"Strength\"},{\"t\":3,\"n\":\"Intelligence\"},{\"t\":3,\"n\":\"Willpower\"},{\"t\":3,\"n\":\"Agility\"},{\"t\":3,\"n\":\"Speed\"},{\"t\":3,\"n\":\"Endurance\"},{\"t\":3,\"n\":\"Personality\"},{\"t\":3,\"n\":\"Luck\"}]},{\"t\":3,\"n\":\"RNAM - Attack reach\"},{\"t\":3,\"n\":\"ZNAM - Combat Style\"},{\"t\":5,\"n\":\"TNAM - Turning Speed\"},{\"t\":5,\"n\":\"BNAM - Base Scale\"},{\"t\":5,\"n\":\"WNAM - Foot Weight\"},{\"t\":2,\"n\":\"NAM0 - Blood Spray\"},{\"t\":2,\"n\":\"NAM1 - Blood Decal\"},{\"t\":3,\"n\":\"CSCR - Inherits Sounds from\"},{\"t\":10,\"n\":\"Sound Types\",\"c\":[{\"t\":6,\"n\":\"Sound Type\",\"c\":[{\"t\":3,\"n\":\"CSDT - Type\"},{\"t\":10,\"n\":\"Sounds\",\"c\":[{\"t\":6,\"n\":\"Sound\",\"c\":[{\"t\":3,\"n\":\"CSDI - Sound\"},{\"t\":3,\"n\":\"CSDC - Sound Chance\"}]}]}]}]}]}]},\"name\":\"Bash.Actors.DeathItem\",\"hash\":\"DAECBF12\",\"color\":255}"
  },
  {
    "path": "frontend/settings/Oblivion/Bash.Actors.Skeleton.json",
    "content": "{\"records\":\"NPC_,CREA\",\"description\":\"Actors.Skeleton from Wrye Bash.\\r\\n\\r\\nUsed when the mod modifies creature or NPC skeletons.\",\"tree\":{\"records\":[{\"t\":1,\"p\":1,\"n\":\"NPC_ - Non-Player Character\",\"c\":[{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"n\":\"FULL - Name\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"},{\"t\":5,\"p\":1,\"n\":\"MODB - Bound Radius\"},{\"t\":11,\"p\":1,\"n\":\"MODT - Texture Files Hashes\"}]},{\"t\":6,\"n\":\"ACBS - Configuration\",\"c\":[{\"t\":3,\"n\":\"Flags\"},{\"t\":3,\"n\":\"Base spell points\"},{\"t\":3,\"n\":\"Fatigue\"},{\"t\":3,\"n\":\"Barter gold\"},{\"t\":3,\"n\":\"Level (offset)\"},{\"t\":3,\"n\":\"Calc min\"},{\"t\":3,\"n\":\"Calc max\"}]},{\"t\":8,\"n\":\"Factions\",\"c\":[{\"t\":6,\"n\":\"SNAM - Faction\",\"c\":[{\"t\":3,\"n\":\"Faction\"},{\"t\":3,\"n\":\"Rank\"},{\"t\":11,\"n\":\"Unused\"}]}]},{\"t\":3,\"n\":\"INAM - Death item\"},{\"t\":3,\"n\":\"RNAM - Race\"},{\"t\":8,\"n\":\"Items\",\"c\":[{\"t\":6,\"n\":\"CNTO - Item\",\"c\":[{\"t\":3,\"n\":\"Item\"},{\"t\":3,\"n\":\"Count\"}]}]},{\"t\":8,\"n\":\"Spells\",\"c\":[{\"t\":3,\"n\":\"SPLO - Spell\"}]},{\"t\":3,\"n\":\"SCRI - Script\"},{\"t\":6,\"n\":\"AIDT - AI Data\",\"c\":[{\"t\":3,\"n\":\"Aggression\"},{\"t\":3,\"n\":\"Confidence\"},{\"t\":3,\"n\":\"Energy Level\"},{\"t\":3,\"n\":\"Responsibility\"},{\"t\":3,\"n\":\"Buys\\/Sells and Services\"},{\"t\":3,\"n\":\"Teaches\"},{\"t\":3,\"n\":\"Maximum training level\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":8,\"n\":\"AI Packages\",\"c\":[{\"t\":3,\"n\":\"PKID - AI Package\"}]},{\"t\":7,\"n\":\"KFFZ - Animations\",\"c\":[{\"t\":2,\"n\":\"Animation\"}]},{\"t\":3,\"n\":\"CNAM - Class\"},{\"t\":6,\"n\":\"DATA - Stats\",\"c\":[{\"t\":3,\"n\":\"Armorer\"},{\"t\":3,\"n\":\"Athletics\"},{\"t\":3,\"n\":\"Blade\"},{\"t\":3,\"n\":\"Block\"},{\"t\":3,\"n\":\"Blunt\"},{\"t\":3,\"n\":\"Hand to Hand\"},{\"t\":3,\"n\":\"Heavy Armor\"},{\"t\":3,\"n\":\"Alchemy\"},{\"t\":3,\"n\":\"Alteration\"},{\"t\":3,\"n\":\"Conjuration\"},{\"t\":3,\"n\":\"Destruction\"},{\"t\":3,\"n\":\"Illusion\"},{\"t\":3,\"n\":\"Mysticism\"},{\"t\":3,\"n\":\"Restoration\"},{\"t\":3,\"n\":\"Acrobatics\"},{\"t\":3,\"n\":\"Light Armor\"},{\"t\":3,\"n\":\"Marksman\"},{\"t\":3,\"n\":\"Mercantile\"},{\"t\":3,\"n\":\"Security\"},{\"t\":3,\"n\":\"Sneak\"},{\"t\":3,\"n\":\"Speechcraft\"},{\"t\":3,\"n\":\"Health\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":3,\"n\":\"Strength\"},{\"t\":3,\"n\":\"Intelligence\"},{\"t\":3,\"n\":\"Willpower\"},{\"t\":3,\"n\":\"Agility\"},{\"t\":3,\"n\":\"Speed\"},{\"t\":3,\"n\":\"Endurance\"},{\"t\":3,\"n\":\"Personality\"},{\"t\":3,\"n\":\"Luck\"}]},{\"t\":3,\"n\":\"HNAM - Hair\"},{\"t\":5,\"n\":\"LNAM - Hair length\"},{\"t\":7,\"n\":\"ENAM - Eyes\",\"c\":[{\"t\":3,\"n\":\"Eyes\"}]},{\"t\":6,\"n\":\"HCLR - Hair color\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":3,\"n\":\"ZNAM - Combat Style\"},{\"t\":6,\"n\":\"FaceGen Data\",\"c\":[{\"t\":11,\"n\":\"FGGS - FaceGen Geometry-Symmetric\"},{\"t\":11,\"n\":\"FGGA - FaceGen Geometry-Asymmetric\"},{\"t\":11,\"n\":\"FGTS - FaceGen Texture-Symmetric\"}]},{\"t\":11,\"n\":\"FNAM - Unknown\"}]},{\"t\":1,\"p\":1,\"n\":\"CREA - Creature\",\"c\":[{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"n\":\"FULL - Name\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"},{\"t\":5,\"p\":1,\"n\":\"MODB - Bound Radius\"},{\"t\":11,\"p\":1,\"n\":\"MODT - Texture Files Hashes\"}]},{\"t\":8,\"n\":\"Items\",\"c\":[{\"t\":6,\"n\":\"CNTO - Item\",\"c\":[{\"t\":3,\"n\":\"Item\"},{\"t\":3,\"n\":\"Count\"}]}]},{\"t\":8,\"n\":\"Spells\",\"c\":[{\"t\":3,\"n\":\"SPLO - Spell\"}]},{\"t\":7,\"n\":\"NIFZ - Models\",\"c\":[{\"t\":2,\"n\":\"Model\"}]},{\"t\":11,\"n\":\"NIFT - Texture Files Hashes\"},{\"t\":6,\"n\":\"ACBS - Configuration\",\"c\":[{\"t\":3,\"n\":\"Flags\"},{\"t\":3,\"n\":\"Base spell points\"},{\"t\":3,\"n\":\"Fatigue\"},{\"t\":3,\"n\":\"Barter gold\"},{\"t\":3,\"n\":\"Level (offset)\"},{\"t\":3,\"n\":\"Calc min\"},{\"t\":3,\"n\":\"Calc max\"}]},{\"t\":8,\"n\":\"Factions\",\"c\":[{\"t\":6,\"n\":\"SNAM - Faction\",\"c\":[{\"t\":3,\"n\":\"Faction\"},{\"t\":3,\"n\":\"Rank\"},{\"t\":11,\"n\":\"Unused\"}]}]},{\"t\":3,\"n\":\"INAM - Death item\"},{\"t\":3,\"n\":\"SCRI - Script\"},{\"t\":6,\"n\":\"AIDT - AI Data\",\"c\":[{\"t\":3,\"n\":\"Aggression\"},{\"t\":3,\"n\":\"Confidence\"},{\"t\":3,\"n\":\"Energy Level\"},{\"t\":3,\"n\":\"Responsibility\"},{\"t\":3,\"n\":\"Buys\\/Sells and Services\"},{\"t\":3,\"n\":\"Teaches\"},{\"t\":3,\"n\":\"Maximum training level\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":8,\"n\":\"AI Packages\",\"c\":[{\"t\":3,\"n\":\"PKID - AI Package\"}]},{\"t\":7,\"n\":\"KFFZ - Animations\",\"c\":[{\"t\":2,\"n\":\"Animation\"}]},{\"t\":6,\"n\":\"DATA - Creature Data\",\"c\":[{\"t\":3,\"n\":\"Type\"},{\"t\":3,\"n\":\"Combat Skill\"},{\"t\":3,\"n\":\"Magic Skill\"},{\"t\":3,\"n\":\"Stealth Skill\"},{\"t\":3,\"n\":\"Soul\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":3,\"n\":\"Health\"},{\"t\":3,\"n\":\"Attack Damage\"},{\"t\":3,\"n\":\"Strength\"},{\"t\":3,\"n\":\"Intelligence\"},{\"t\":3,\"n\":\"Willpower\"},{\"t\":3,\"n\":\"Agility\"},{\"t\":3,\"n\":\"Speed\"},{\"t\":3,\"n\":\"Endurance\"},{\"t\":3,\"n\":\"Personality\"},{\"t\":3,\"n\":\"Luck\"}]},{\"t\":3,\"n\":\"RNAM - Attack reach\"},{\"t\":3,\"n\":\"ZNAM - Combat Style\"},{\"t\":5,\"n\":\"TNAM - Turning Speed\"},{\"t\":5,\"n\":\"BNAM - Base Scale\"},{\"t\":5,\"n\":\"WNAM - Foot Weight\"},{\"t\":2,\"n\":\"NAM0 - Blood Spray\"},{\"t\":2,\"n\":\"NAM1 - Blood Decal\"},{\"t\":3,\"n\":\"CSCR - Inherits Sounds from\"},{\"t\":10,\"n\":\"Sound Types\",\"c\":[{\"t\":6,\"n\":\"Sound Type\",\"c\":[{\"t\":3,\"n\":\"CSDT - Type\"},{\"t\":10,\"n\":\"Sounds\",\"c\":[{\"t\":6,\"n\":\"Sound\",\"c\":[{\"t\":3,\"n\":\"CSDI - Sound\"},{\"t\":3,\"n\":\"CSDC - Sound Chance\"}]}]}]}]}]}]},\"name\":\"Bash.Actors.Skeleton\",\"hash\":\"FCEBB959\",\"color\":255}"
  },
  {
    "path": "frontend/settings/Oblivion/Bash.Actors.Spells.json",
    "content": "{\"records\":\"NPC_,CREA\",\"description\":\"Actors.Spells tag from Wrye Bash.\\r\\n\\r\\nUse when the mod modifies creature or NPC spell lists.\",\"tree\":{\"records\":[{\"t\":1,\"p\":1,\"n\":\"NPC_ - Non-Player Character\",\"c\":[{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"n\":\"FULL - Name\"},{\"t\":6,\"n\":\"Model\",\"c\":[{\"t\":2,\"n\":\"MODL - Model Filename\"},{\"t\":5,\"n\":\"MODB - Bound Radius\"},{\"t\":11,\"n\":\"MODT - Texture Files Hashes\"}]},{\"t\":6,\"n\":\"ACBS - Configuration\",\"c\":[{\"t\":3,\"n\":\"Flags\"},{\"t\":3,\"n\":\"Base spell points\"},{\"t\":3,\"n\":\"Fatigue\"},{\"t\":3,\"n\":\"Barter gold\"},{\"t\":3,\"n\":\"Level (offset)\"},{\"t\":3,\"n\":\"Calc min\"},{\"t\":3,\"n\":\"Calc max\"}]},{\"t\":8,\"n\":\"Factions\",\"c\":[{\"t\":6,\"n\":\"SNAM - Faction\",\"c\":[{\"t\":3,\"n\":\"Faction\"},{\"t\":3,\"n\":\"Rank\"},{\"t\":11,\"n\":\"Unused\"}]}]},{\"t\":3,\"n\":\"INAM - Death item\"},{\"t\":3,\"n\":\"RNAM - Race\"},{\"t\":8,\"n\":\"Items\",\"c\":[{\"t\":6,\"n\":\"CNTO - Item\",\"c\":[{\"t\":3,\"n\":\"Item\"},{\"t\":3,\"n\":\"Count\"}]}]},{\"t\":8,\"p\":1,\"n\":\"Spells\",\"d\":1,\"c\":[{\"t\":3,\"p\":1,\"n\":\"SPLO - Spell\"}]},{\"t\":3,\"n\":\"SCRI - Script\"},{\"t\":6,\"n\":\"AIDT - AI Data\",\"c\":[{\"t\":3,\"n\":\"Aggression\"},{\"t\":3,\"n\":\"Confidence\"},{\"t\":3,\"n\":\"Energy Level\"},{\"t\":3,\"n\":\"Responsibility\"},{\"t\":3,\"n\":\"Buys\\/Sells and Services\"},{\"t\":3,\"n\":\"Teaches\"},{\"t\":3,\"n\":\"Maximum training level\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":8,\"n\":\"AI Packages\",\"c\":[{\"t\":3,\"n\":\"PKID - AI Package\"}]},{\"t\":7,\"n\":\"KFFZ - Animations\",\"c\":[{\"t\":2,\"n\":\"Animation\"}]},{\"t\":3,\"n\":\"CNAM - Class\"},{\"t\":6,\"n\":\"DATA - Stats\",\"c\":[{\"t\":3,\"n\":\"Armorer\"},{\"t\":3,\"n\":\"Athletics\"},{\"t\":3,\"n\":\"Blade\"},{\"t\":3,\"n\":\"Block\"},{\"t\":3,\"n\":\"Blunt\"},{\"t\":3,\"n\":\"Hand to Hand\"},{\"t\":3,\"n\":\"Heavy Armor\"},{\"t\":3,\"n\":\"Alchemy\"},{\"t\":3,\"n\":\"Alteration\"},{\"t\":3,\"n\":\"Conjuration\"},{\"t\":3,\"n\":\"Destruction\"},{\"t\":3,\"n\":\"Illusion\"},{\"t\":3,\"n\":\"Mysticism\"},{\"t\":3,\"n\":\"Restoration\"},{\"t\":3,\"n\":\"Acrobatics\"},{\"t\":3,\"n\":\"Light Armor\"},{\"t\":3,\"n\":\"Marksman\"},{\"t\":3,\"n\":\"Mercantile\"},{\"t\":3,\"n\":\"Security\"},{\"t\":3,\"n\":\"Sneak\"},{\"t\":3,\"n\":\"Speechcraft\"},{\"t\":3,\"n\":\"Health\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":3,\"n\":\"Strength\"},{\"t\":3,\"n\":\"Intelligence\"},{\"t\":3,\"n\":\"Willpower\"},{\"t\":3,\"n\":\"Agility\"},{\"t\":3,\"n\":\"Speed\"},{\"t\":3,\"n\":\"Endurance\"},{\"t\":3,\"n\":\"Personality\"},{\"t\":3,\"n\":\"Luck\"}]},{\"t\":3,\"n\":\"HNAM - Hair\"},{\"t\":5,\"n\":\"LNAM - Hair length\"},{\"t\":7,\"n\":\"ENAM - Eyes\",\"c\":[{\"t\":3,\"n\":\"Eyes\"}]},{\"t\":6,\"n\":\"HCLR - Hair color\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":3,\"n\":\"ZNAM - Combat Style\"},{\"t\":6,\"n\":\"FaceGen Data\",\"c\":[{\"t\":11,\"n\":\"FGGS - FaceGen Geometry-Symmetric\"},{\"t\":11,\"n\":\"FGGA - FaceGen Geometry-Asymmetric\"},{\"t\":11,\"n\":\"FGTS - FaceGen Texture-Symmetric\"}]},{\"t\":11,\"n\":\"FNAM - Unknown\"}]},{\"t\":1,\"p\":1,\"n\":\"CREA - Creature\",\"c\":[{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"n\":\"FULL - Name\"},{\"t\":6,\"n\":\"Model\",\"c\":[{\"t\":2,\"n\":\"MODL - Model Filename\"},{\"t\":5,\"n\":\"MODB - Bound Radius\"},{\"t\":11,\"n\":\"MODT - Texture Files Hashes\"}]},{\"t\":8,\"n\":\"Items\",\"c\":[{\"t\":6,\"n\":\"CNTO - Item\",\"c\":[{\"t\":3,\"n\":\"Item\"},{\"t\":3,\"n\":\"Count\"}]}]},{\"t\":8,\"p\":1,\"n\":\"Spells\",\"d\":1,\"c\":[{\"t\":3,\"p\":1,\"n\":\"SPLO - Spell\"}]},{\"t\":7,\"n\":\"NIFZ - Models\",\"c\":[{\"t\":2,\"n\":\"Model\"}]},{\"t\":11,\"n\":\"NIFT - Texture Files Hashes\"},{\"t\":6,\"n\":\"ACBS - Configuration\",\"c\":[{\"t\":3,\"n\":\"Flags\"},{\"t\":3,\"n\":\"Base spell points\"},{\"t\":3,\"n\":\"Fatigue\"},{\"t\":3,\"n\":\"Barter gold\"},{\"t\":3,\"n\":\"Level (offset)\"},{\"t\":3,\"n\":\"Calc min\"},{\"t\":3,\"n\":\"Calc max\"}]},{\"t\":8,\"n\":\"Factions\",\"c\":[{\"t\":6,\"n\":\"SNAM - Faction\",\"c\":[{\"t\":3,\"n\":\"Faction\"},{\"t\":3,\"n\":\"Rank\"},{\"t\":11,\"n\":\"Unused\"}]}]},{\"t\":3,\"n\":\"INAM - Death item\"},{\"t\":3,\"n\":\"SCRI - Script\"},{\"t\":6,\"n\":\"AIDT - AI Data\",\"c\":[{\"t\":3,\"n\":\"Aggression\"},{\"t\":3,\"n\":\"Confidence\"},{\"t\":3,\"n\":\"Energy Level\"},{\"t\":3,\"n\":\"Responsibility\"},{\"t\":3,\"n\":\"Buys\\/Sells and Services\"},{\"t\":3,\"n\":\"Teaches\"},{\"t\":3,\"n\":\"Maximum training level\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":8,\"n\":\"AI Packages\",\"c\":[{\"t\":3,\"n\":\"PKID - AI Package\"}]},{\"t\":7,\"n\":\"KFFZ - Animations\",\"c\":[{\"t\":2,\"n\":\"Animation\"}]},{\"t\":6,\"n\":\"DATA - Creature Data\",\"c\":[{\"t\":3,\"n\":\"Type\"},{\"t\":3,\"n\":\"Combat Skill\"},{\"t\":3,\"n\":\"Magic Skill\"},{\"t\":3,\"n\":\"Stealth Skill\"},{\"t\":3,\"n\":\"Soul\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":3,\"n\":\"Health\"},{\"t\":3,\"n\":\"Attack Damage\"},{\"t\":3,\"n\":\"Strength\"},{\"t\":3,\"n\":\"Intelligence\"},{\"t\":3,\"n\":\"Willpower\"},{\"t\":3,\"n\":\"Agility\"},{\"t\":3,\"n\":\"Speed\"},{\"t\":3,\"n\":\"Endurance\"},{\"t\":3,\"n\":\"Personality\"},{\"t\":3,\"n\":\"Luck\"}]},{\"t\":3,\"n\":\"RNAM - Attack reach\"},{\"t\":3,\"n\":\"ZNAM - Combat Style\"},{\"t\":5,\"n\":\"TNAM - Turning Speed\"},{\"t\":5,\"n\":\"BNAM - Base Scale\"},{\"t\":5,\"n\":\"WNAM - Foot Weight\"},{\"t\":2,\"n\":\"NAM0 - Blood Spray\"},{\"t\":2,\"n\":\"NAM1 - Blood Decal\"},{\"t\":3,\"n\":\"CSCR - Inherits Sounds from\"},{\"t\":10,\"n\":\"Sound Types\",\"c\":[{\"t\":6,\"n\":\"Sound Type\",\"c\":[{\"t\":3,\"n\":\"CSDT - Type\"},{\"t\":10,\"n\":\"Sounds\",\"c\":[{\"t\":6,\"n\":\"Sound\",\"c\":[{\"t\":3,\"n\":\"CSDI - Sound\"},{\"t\":3,\"n\":\"CSDC - Sound Chance\"}]}]}]}]}]}]},\"name\":\"Bash.Actors.Spells\",\"hash\":\"4CFC09CA\",\"color\":255}"
  },
  {
    "path": "frontend/settings/Oblivion/Bash.Actors.Stats.json",
    "content": "{\"records\":\"NPC_,CREA\",\"description\":\"Actors.Stats tag from Wrye Bash.\\r\\n\\r\\nUsed when the mod modifies creature or NPC stats.\",\"tree\":{\"records\":[{\"t\":1,\"p\":1,\"n\":\"NPC_ - Non-Player Character\",\"c\":[{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"n\":\"FULL - Name\"},{\"t\":6,\"n\":\"Model\",\"c\":[{\"t\":2,\"n\":\"MODL - Model Filename\"},{\"t\":5,\"n\":\"MODB - Bound Radius\"},{\"t\":11,\"n\":\"MODT - Texture Files Hashes\"}]},{\"t\":6,\"n\":\"ACBS - Configuration\",\"c\":[{\"t\":3,\"n\":\"Flags\"},{\"t\":3,\"n\":\"Base spell points\"},{\"t\":3,\"n\":\"Fatigue\"},{\"t\":3,\"n\":\"Barter gold\"},{\"t\":3,\"n\":\"Level (offset)\"},{\"t\":3,\"n\":\"Calc min\"},{\"t\":3,\"n\":\"Calc max\"}]},{\"t\":8,\"n\":\"Factions\",\"c\":[{\"t\":6,\"n\":\"SNAM - Faction\",\"c\":[{\"t\":3,\"n\":\"Faction\"},{\"t\":3,\"n\":\"Rank\"},{\"t\":11,\"n\":\"Unused\"}]}]},{\"t\":3,\"n\":\"INAM - Death item\"},{\"t\":3,\"n\":\"RNAM - Race\"},{\"t\":8,\"n\":\"Items\",\"c\":[{\"t\":6,\"n\":\"CNTO - Item\",\"c\":[{\"t\":3,\"n\":\"Item\"},{\"t\":3,\"n\":\"Count\"}]}]},{\"t\":8,\"n\":\"Spells\",\"c\":[{\"t\":3,\"n\":\"SPLO - Spell\"}]},{\"t\":3,\"n\":\"SCRI - Script\"},{\"t\":6,\"n\":\"AIDT - AI Data\",\"c\":[{\"t\":3,\"n\":\"Aggression\"},{\"t\":3,\"n\":\"Confidence\"},{\"t\":3,\"n\":\"Energy Level\"},{\"t\":3,\"n\":\"Responsibility\"},{\"t\":3,\"n\":\"Buys\\/Sells and Services\"},{\"t\":3,\"n\":\"Teaches\"},{\"t\":3,\"n\":\"Maximum training level\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":8,\"n\":\"AI Packages\",\"c\":[{\"t\":3,\"n\":\"PKID - AI Package\"}]},{\"t\":7,\"n\":\"KFFZ - Animations\",\"c\":[{\"t\":2,\"n\":\"Animation\"}]},{\"t\":3,\"n\":\"CNAM - Class\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DATA - Stats\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Armorer\"},{\"t\":3,\"p\":1,\"n\":\"Athletics\"},{\"t\":3,\"p\":1,\"n\":\"Blade\"},{\"t\":3,\"p\":1,\"n\":\"Block\"},{\"t\":3,\"p\":1,\"n\":\"Blunt\"},{\"t\":3,\"p\":1,\"n\":\"Hand to Hand\"},{\"t\":3,\"p\":1,\"n\":\"Heavy Armor\"},{\"t\":3,\"p\":1,\"n\":\"Alchemy\"},{\"t\":3,\"p\":1,\"n\":\"Alteration\"},{\"t\":3,\"p\":1,\"n\":\"Conjuration\"},{\"t\":3,\"p\":1,\"n\":\"Destruction\"},{\"t\":3,\"p\":1,\"n\":\"Illusion\"},{\"t\":3,\"p\":1,\"n\":\"Mysticism\"},{\"t\":3,\"p\":1,\"n\":\"Restoration\"},{\"t\":3,\"p\":1,\"n\":\"Acrobatics\"},{\"t\":3,\"p\":1,\"n\":\"Light Armor\"},{\"t\":3,\"p\":1,\"n\":\"Marksman\"},{\"t\":3,\"p\":1,\"n\":\"Mercantile\"},{\"t\":3,\"p\":1,\"n\":\"Security\"},{\"t\":3,\"p\":1,\"n\":\"Sneak\"},{\"t\":3,\"p\":1,\"n\":\"Speechcraft\"},{\"t\":3,\"p\":1,\"n\":\"Health\"},{\"t\":11,\"p\":1,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Strength\"},{\"t\":3,\"p\":1,\"n\":\"Intelligence\"},{\"t\":3,\"p\":1,\"n\":\"Willpower\"},{\"t\":3,\"p\":1,\"n\":\"Agility\"},{\"t\":3,\"p\":1,\"n\":\"Speed\"},{\"t\":3,\"p\":1,\"n\":\"Endurance\"},{\"t\":3,\"p\":1,\"n\":\"Personality\"},{\"t\":3,\"p\":1,\"n\":\"Luck\"}]},{\"t\":3,\"n\":\"HNAM - Hair\"},{\"t\":5,\"n\":\"LNAM - Hair length\"},{\"t\":7,\"n\":\"ENAM - Eyes\",\"c\":[{\"t\":3,\"n\":\"Eyes\"}]},{\"t\":6,\"n\":\"HCLR - Hair color\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":3,\"n\":\"ZNAM - Combat Style\"},{\"t\":6,\"n\":\"FaceGen Data\",\"c\":[{\"t\":11,\"n\":\"FGGS - FaceGen Geometry-Symmetric\"},{\"t\":11,\"n\":\"FGGA - FaceGen Geometry-Asymmetric\"},{\"t\":11,\"n\":\"FGTS - FaceGen Texture-Symmetric\"}]},{\"t\":11,\"n\":\"FNAM - Unknown\"}]},{\"t\":1,\"p\":1,\"n\":\"CREA - Creature\",\"c\":[{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"n\":\"FULL - Name\"},{\"t\":6,\"n\":\"Model\",\"c\":[{\"t\":2,\"n\":\"MODL - Model Filename\"},{\"t\":5,\"n\":\"MODB - Bound Radius\"},{\"t\":11,\"n\":\"MODT - Texture Files Hashes\"}]},{\"t\":8,\"n\":\"Items\",\"c\":[{\"t\":6,\"n\":\"CNTO - Item\",\"c\":[{\"t\":3,\"n\":\"Item\"},{\"t\":3,\"n\":\"Count\"}]}]},{\"t\":8,\"n\":\"Spells\",\"c\":[{\"t\":3,\"n\":\"SPLO - Spell\"}]},{\"t\":7,\"n\":\"NIFZ - Models\",\"c\":[{\"t\":2,\"n\":\"Model\"}]},{\"t\":11,\"n\":\"NIFT - Texture Files Hashes\"},{\"t\":6,\"n\":\"ACBS - Configuration\",\"c\":[{\"t\":3,\"n\":\"Flags\"},{\"t\":3,\"n\":\"Base spell points\"},{\"t\":3,\"n\":\"Fatigue\"},{\"t\":3,\"n\":\"Barter gold\"},{\"t\":3,\"n\":\"Level (offset)\"},{\"t\":3,\"n\":\"Calc min\"},{\"t\":3,\"n\":\"Calc max\"}]},{\"t\":8,\"n\":\"Factions\",\"c\":[{\"t\":6,\"n\":\"SNAM - Faction\",\"c\":[{\"t\":3,\"n\":\"Faction\"},{\"t\":3,\"n\":\"Rank\"},{\"t\":11,\"n\":\"Unused\"}]}]},{\"t\":3,\"n\":\"INAM - Death item\"},{\"t\":3,\"n\":\"SCRI - Script\"},{\"t\":6,\"n\":\"AIDT - AI Data\",\"c\":[{\"t\":3,\"n\":\"Aggression\"},{\"t\":3,\"n\":\"Confidence\"},{\"t\":3,\"n\":\"Energy Level\"},{\"t\":3,\"n\":\"Responsibility\"},{\"t\":3,\"n\":\"Buys\\/Sells and Services\"},{\"t\":3,\"n\":\"Teaches\"},{\"t\":3,\"n\":\"Maximum training level\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":8,\"n\":\"AI Packages\",\"c\":[{\"t\":3,\"n\":\"PKID - AI Package\"}]},{\"t\":7,\"n\":\"KFFZ - Animations\",\"c\":[{\"t\":2,\"n\":\"Animation\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DATA - Creature Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Combat Skill\"},{\"t\":3,\"p\":1,\"n\":\"Magic Skill\"},{\"t\":3,\"p\":1,\"n\":\"Stealth Skill\"},{\"t\":3,\"p\":1,\"n\":\"Soul\"},{\"t\":11,\"p\":1,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Health\"},{\"t\":3,\"p\":1,\"n\":\"Attack Damage\"},{\"t\":3,\"p\":1,\"n\":\"Strength\"},{\"t\":3,\"p\":1,\"n\":\"Intelligence\"},{\"t\":3,\"p\":1,\"n\":\"Willpower\"},{\"t\":3,\"p\":1,\"n\":\"Agility\"},{\"t\":3,\"p\":1,\"n\":\"Speed\"},{\"t\":3,\"p\":1,\"n\":\"Endurance\"},{\"t\":3,\"p\":1,\"n\":\"Personality\"},{\"t\":3,\"p\":1,\"n\":\"Luck\"}]},{\"t\":3,\"n\":\"RNAM - Attack reach\"},{\"t\":3,\"n\":\"ZNAM - Combat Style\"},{\"t\":5,\"n\":\"TNAM - Turning Speed\"},{\"t\":5,\"n\":\"BNAM - Base Scale\"},{\"t\":5,\"n\":\"WNAM - Foot Weight\"},{\"t\":2,\"n\":\"NAM0 - Blood Spray\"},{\"t\":2,\"n\":\"NAM1 - Blood Decal\"},{\"t\":3,\"n\":\"CSCR - Inherits Sounds from\"},{\"t\":10,\"n\":\"Sound Types\",\"c\":[{\"t\":6,\"n\":\"Sound Type\",\"c\":[{\"t\":3,\"n\":\"CSDT - Type\"},{\"t\":10,\"n\":\"Sounds\",\"c\":[{\"t\":6,\"n\":\"Sound\",\"c\":[{\"t\":3,\"n\":\"CSDI - Sound\"},{\"t\":3,\"n\":\"CSDC - Sound Chance\"}]}]}]}]}]}]},\"name\":\"Bash.Actors.Stats\",\"hash\":\"98C8C674\",\"color\":255}"
  },
  {
    "path": "frontend/settings/Oblivion/Bash.Body-F.json",
    "content": "{\"records\":\"RACE\",\"description\":\"Body-F tag from Wrye Bash.\\r\\n\\r\\nUsed when the mod modifies female body mesh\\/texture definitions.\",\"tree\":{\"records\":[{\"t\":1,\"p\":1,\"n\":\"RACE - Race\",\"c\":[{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"n\":\"FULL - Name\"},{\"t\":2,\"n\":\"DESC - Description\"},{\"t\":8,\"n\":\"Spells\",\"c\":[{\"t\":3,\"n\":\"SPLO - Spell\"}]},{\"t\":8,\"n\":\"Relations\",\"c\":[{\"t\":6,\"n\":\"XNAM - Relation\",\"c\":[{\"t\":3,\"n\":\"Faction\"},{\"t\":3,\"n\":\"Modifier\"}]}]},{\"t\":6,\"n\":\"DATA - \",\"c\":[{\"t\":7,\"n\":\"Skill Boosts\",\"c\":[{\"t\":6,\"n\":\"Skill Boost\",\"c\":[{\"t\":3,\"n\":\"Skill\"},{\"t\":3,\"n\":\"Boost\"}]}]},{\"t\":11,\"n\":\"Unused\"},{\"t\":5,\"n\":\"Male Height\"},{\"t\":5,\"n\":\"Female Height\"},{\"t\":5,\"n\":\"Male Weight\"},{\"t\":5,\"n\":\"Female Weight\"},{\"t\":3,\"n\":\"Flags\"}]},{\"t\":6,\"n\":\"VNAM - Voice\",\"c\":[{\"t\":3,\"n\":\"Male\"},{\"t\":3,\"n\":\"Female\"}]},{\"t\":6,\"n\":\"DNAM - Default Hair\",\"c\":[{\"t\":3,\"n\":\"Male\"},{\"t\":3,\"n\":\"Female\"}]},{\"t\":3,\"n\":\"CNAM - Default Hair Color\"},{\"t\":5,\"n\":\"PNAM - FaceGen - Main clamp\"},{\"t\":5,\"n\":\"UNAM - FaceGen - Face clamp\"},{\"t\":6,\"n\":\"ATTR - Base Attributes\",\"c\":[{\"t\":6,\"n\":\"Male\",\"c\":[{\"t\":3,\"n\":\"Strength\"},{\"t\":3,\"n\":\"Intelligence\"},{\"t\":3,\"n\":\"Willpower\"},{\"t\":3,\"n\":\"Agility\"},{\"t\":3,\"n\":\"Speed\"},{\"t\":3,\"n\":\"Endurance\"},{\"t\":3,\"n\":\"Personality\"},{\"t\":3,\"n\":\"Luck\"}]},{\"t\":6,\"n\":\"Female\",\"c\":[{\"t\":3,\"n\":\"Strength\"},{\"t\":3,\"n\":\"Intelligence\"},{\"t\":3,\"n\":\"Willpower\"},{\"t\":3,\"n\":\"Agility\"},{\"t\":3,\"n\":\"Speed\"},{\"t\":3,\"n\":\"Endurance\"},{\"t\":3,\"n\":\"Personality\"},{\"t\":3,\"n\":\"Luck\"}]}]},{\"t\":6,\"n\":\"Face Data\",\"c\":[{\"n\":\"NAM0 - Face Data Marker\"},{\"t\":10,\"n\":\"Parts\",\"c\":[{\"t\":6,\"n\":\"Part\",\"c\":[{\"t\":3,\"n\":\"INDX - Index\"},{\"t\":6,\"n\":\"Model\",\"c\":[{\"t\":2,\"n\":\"MODL - Model Filename\"},{\"t\":5,\"n\":\"MODB - Bound Radius\"},{\"t\":11,\"n\":\"MODT - Texture Files Hashes\"}]},{\"t\":2,\"n\":\"ICON - Icon filename\"}]}]}]},{\"n\":\"NAM1 - Body Data Marker\"},{\"t\":6,\"n\":\"Male Body Data\",\"c\":[{\"n\":\"MNAM - Male Body Data Marker\"},{\"t\":6,\"n\":\"Model\",\"c\":[{\"t\":2,\"n\":\"MODL - Model Filename\"},{\"t\":5,\"n\":\"MODB - Bound Radius\"},{\"t\":11,\"n\":\"MODT - Texture Files Hashes\"}]},{\"t\":10,\"n\":\"Parts\",\"c\":[{\"t\":6,\"n\":\"Part\",\"c\":[{\"t\":3,\"n\":\"INDX - Index\"},{\"t\":2,\"n\":\"ICON - Icon filename\"}]}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Female Body Data\",\"c\":[{\"p\":1,\"n\":\"FNAM - Female Body Data Marker\"},{\"t\":6,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"},{\"t\":5,\"p\":1,\"n\":\"MODB - Bound Radius\"},{\"t\":11,\"p\":1,\"n\":\"MODT - Texture Files Hashes\"}]},{\"t\":10,\"p\":1,\"n\":\"Parts\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Part\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"INDX - Index\"},{\"t\":2,\"p\":1,\"n\":\"ICON - Icon filename\"}]}]}]},{\"t\":7,\"n\":\"HNAM - Hairs\",\"c\":[{\"t\":3,\"n\":\"Hair\"}]},{\"t\":7,\"n\":\"ENAM - Eyes\",\"c\":[{\"t\":3,\"n\":\"Eye\"}]},{\"t\":6,\"n\":\"FaceGen Data\",\"c\":[{\"t\":11,\"n\":\"FGGS - FaceGen Geometry-Symmetric\"},{\"t\":11,\"n\":\"FGGA - FaceGen Geometry-Asymmetric\"},{\"t\":11,\"n\":\"FGTS - FaceGen Texture-Symmetric\"}]},{\"t\":11,\"n\":\"SNAM - Unknown\"}]}]},\"name\":\"Bash.Body-F\",\"hash\":\"A14859EB\",\"color\":255}"
  },
  {
    "path": "frontend/settings/Oblivion/Bash.Body-M.json",
    "content": "{\"records\":\"RACE\",\"description\":\"Body-M tag from Wrye Bash.\\r\\n\\r\\nUsed when the mod modifies male body mesh\\/texture definitions.\",\"tree\":{\"records\":[{\"t\":1,\"p\":1,\"n\":\"RACE - Race\",\"c\":[{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"n\":\"FULL - Name\"},{\"t\":2,\"n\":\"DESC - Description\"},{\"t\":8,\"n\":\"Spells\",\"c\":[{\"t\":3,\"n\":\"SPLO - Spell\"}]},{\"t\":8,\"n\":\"Relations\",\"c\":[{\"t\":6,\"n\":\"XNAM - Relation\",\"c\":[{\"t\":3,\"n\":\"Faction\"},{\"t\":3,\"n\":\"Modifier\"}]}]},{\"t\":6,\"n\":\"DATA - \",\"c\":[{\"t\":7,\"n\":\"Skill Boosts\",\"c\":[{\"t\":6,\"n\":\"Skill Boost\",\"c\":[{\"t\":3,\"n\":\"Skill\"},{\"t\":3,\"n\":\"Boost\"}]}]},{\"t\":11,\"n\":\"Unused\"},{\"t\":5,\"n\":\"Male Height\"},{\"t\":5,\"n\":\"Female Height\"},{\"t\":5,\"n\":\"Male Weight\"},{\"t\":5,\"n\":\"Female Weight\"},{\"t\":3,\"n\":\"Flags\"}]},{\"t\":6,\"n\":\"VNAM - Voice\",\"c\":[{\"t\":3,\"n\":\"Male\"},{\"t\":3,\"n\":\"Female\"}]},{\"t\":6,\"n\":\"DNAM - Default Hair\",\"c\":[{\"t\":3,\"n\":\"Male\"},{\"t\":3,\"n\":\"Female\"}]},{\"t\":3,\"n\":\"CNAM - Default Hair Color\"},{\"t\":5,\"n\":\"PNAM - FaceGen - Main clamp\"},{\"t\":5,\"n\":\"UNAM - FaceGen - Face clamp\"},{\"t\":6,\"n\":\"ATTR - Base Attributes\",\"c\":[{\"t\":6,\"n\":\"Male\",\"c\":[{\"t\":3,\"n\":\"Strength\"},{\"t\":3,\"n\":\"Intelligence\"},{\"t\":3,\"n\":\"Willpower\"},{\"t\":3,\"n\":\"Agility\"},{\"t\":3,\"n\":\"Speed\"},{\"t\":3,\"n\":\"Endurance\"},{\"t\":3,\"n\":\"Personality\"},{\"t\":3,\"n\":\"Luck\"}]},{\"t\":6,\"n\":\"Female\",\"c\":[{\"t\":3,\"n\":\"Strength\"},{\"t\":3,\"n\":\"Intelligence\"},{\"t\":3,\"n\":\"Willpower\"},{\"t\":3,\"n\":\"Agility\"},{\"t\":3,\"n\":\"Speed\"},{\"t\":3,\"n\":\"Endurance\"},{\"t\":3,\"n\":\"Personality\"},{\"t\":3,\"n\":\"Luck\"}]}]},{\"t\":6,\"n\":\"Face Data\",\"c\":[{\"n\":\"NAM0 - Face Data Marker\"},{\"t\":10,\"n\":\"Parts\",\"c\":[{\"t\":6,\"n\":\"Part\",\"c\":[{\"t\":3,\"n\":\"INDX - Index\"},{\"t\":6,\"n\":\"Model\",\"c\":[{\"t\":2,\"n\":\"MODL - Model Filename\"},{\"t\":5,\"n\":\"MODB - Bound Radius\"},{\"t\":11,\"n\":\"MODT - Texture Files Hashes\"}]},{\"t\":2,\"n\":\"ICON - Icon filename\"}]}]}]},{\"n\":\"NAM1 - Body Data Marker\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Male Body Data\",\"c\":[{\"p\":1,\"n\":\"MNAM - Male Body Data Marker\"},{\"t\":6,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"},{\"t\":5,\"p\":1,\"n\":\"MODB - Bound Radius\"},{\"t\":11,\"p\":1,\"n\":\"MODT - Texture Files Hashes\"}]},{\"t\":10,\"p\":1,\"n\":\"Parts\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Part\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"INDX - Index\"},{\"t\":2,\"p\":1,\"n\":\"ICON - Icon filename\"}]}]}]},{\"t\":6,\"n\":\"Female Body Data\",\"c\":[{\"n\":\"FNAM - Female Body Data Marker\"},{\"t\":6,\"n\":\"Model\",\"c\":[{\"t\":2,\"n\":\"MODL - Model Filename\"},{\"t\":5,\"n\":\"MODB - Bound Radius\"},{\"t\":11,\"n\":\"MODT - Texture Files Hashes\"}]},{\"t\":10,\"n\":\"Parts\",\"c\":[{\"t\":6,\"n\":\"Part\",\"c\":[{\"t\":3,\"n\":\"INDX - Index\"},{\"t\":2,\"n\":\"ICON - Icon filename\"}]}]}]},{\"t\":7,\"n\":\"HNAM - Hairs\",\"c\":[{\"t\":3,\"n\":\"Hair\"}]},{\"t\":7,\"n\":\"ENAM - Eyes\",\"c\":[{\"t\":3,\"n\":\"Eye\"}]},{\"t\":6,\"n\":\"FaceGen Data\",\"c\":[{\"t\":11,\"n\":\"FGGS - FaceGen Geometry-Symmetric\"},{\"t\":11,\"n\":\"FGGA - FaceGen Geometry-Asymmetric\"},{\"t\":11,\"n\":\"FGTS - FaceGen Texture-Symmetric\"}]},{\"t\":11,\"n\":\"SNAM - Unknown\"}]}]},\"name\":\"Bash.Body-M\",\"hash\":\"83DA1936\",\"color\":255}"
  },
  {
    "path": "frontend/settings/Oblivion/Bash.Body-Size-F.json",
    "content": "{\"records\":\"RACE\",\"description\":\"Body-Size-F tag from Wrye Bash.\\r\\n\\r\\nUsed when the mod modifies female body weight\\/height definitions.\",\"tree\":{\"records\":[{\"t\":1,\"p\":1,\"n\":\"RACE - Race\",\"c\":[{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"n\":\"FULL - Name\"},{\"t\":2,\"n\":\"DESC - Description\"},{\"t\":8,\"n\":\"Spells\",\"c\":[{\"t\":3,\"n\":\"SPLO - Spell\"}]},{\"t\":8,\"n\":\"Relations\",\"c\":[{\"t\":6,\"n\":\"XNAM - Relation\",\"c\":[{\"t\":3,\"n\":\"Faction\"},{\"t\":3,\"n\":\"Modifier\"}]}]},{\"t\":6,\"p\":1,\"n\":\"DATA - \",\"c\":[{\"t\":7,\"n\":\"Skill Boosts\",\"c\":[{\"t\":6,\"n\":\"Skill Boost\",\"c\":[{\"t\":3,\"n\":\"Skill\"},{\"t\":3,\"n\":\"Boost\"}]}]},{\"t\":11,\"n\":\"Unused\"},{\"t\":5,\"n\":\"Male Height\"},{\"t\":5,\"p\":1,\"n\":\"Female Height\"},{\"t\":5,\"n\":\"Male Weight\"},{\"t\":5,\"p\":1,\"n\":\"Female Weight\"},{\"t\":3,\"n\":\"Flags\"}]},{\"t\":6,\"n\":\"VNAM - Voice\",\"c\":[{\"t\":3,\"n\":\"Male\"},{\"t\":3,\"n\":\"Female\"}]},{\"t\":6,\"n\":\"DNAM - Default Hair\",\"c\":[{\"t\":3,\"n\":\"Male\"},{\"t\":3,\"n\":\"Female\"}]},{\"t\":3,\"n\":\"CNAM - Default Hair Color\"},{\"t\":5,\"n\":\"PNAM - FaceGen - Main clamp\"},{\"t\":5,\"n\":\"UNAM - FaceGen - Face clamp\"},{\"t\":6,\"n\":\"ATTR - Base Attributes\",\"c\":[{\"t\":6,\"n\":\"Male\",\"c\":[{\"t\":3,\"n\":\"Strength\"},{\"t\":3,\"n\":\"Intelligence\"},{\"t\":3,\"n\":\"Willpower\"},{\"t\":3,\"n\":\"Agility\"},{\"t\":3,\"n\":\"Speed\"},{\"t\":3,\"n\":\"Endurance\"},{\"t\":3,\"n\":\"Personality\"},{\"t\":3,\"n\":\"Luck\"}]},{\"t\":6,\"n\":\"Female\",\"c\":[{\"t\":3,\"n\":\"Strength\"},{\"t\":3,\"n\":\"Intelligence\"},{\"t\":3,\"n\":\"Willpower\"},{\"t\":3,\"n\":\"Agility\"},{\"t\":3,\"n\":\"Speed\"},{\"t\":3,\"n\":\"Endurance\"},{\"t\":3,\"n\":\"Personality\"},{\"t\":3,\"n\":\"Luck\"}]}]},{\"t\":6,\"n\":\"Face Data\",\"c\":[{\"n\":\"NAM0 - Face Data Marker\"},{\"t\":10,\"n\":\"Parts\",\"c\":[{\"t\":6,\"n\":\"Part\",\"c\":[{\"t\":3,\"n\":\"INDX - Index\"},{\"t\":6,\"n\":\"Model\",\"c\":[{\"t\":2,\"n\":\"MODL - Model Filename\"},{\"t\":5,\"n\":\"MODB - Bound Radius\"},{\"t\":11,\"n\":\"MODT - Texture Files Hashes\"}]},{\"t\":2,\"n\":\"ICON - Icon filename\"}]}]}]},{\"n\":\"NAM1 - Body Data Marker\"},{\"t\":6,\"n\":\"Male Body Data\",\"c\":[{\"n\":\"MNAM - Male Body Data Marker\"},{\"t\":6,\"n\":\"Model\",\"c\":[{\"t\":2,\"n\":\"MODL - Model Filename\"},{\"t\":5,\"n\":\"MODB - Bound Radius\"},{\"t\":11,\"n\":\"MODT - Texture Files Hashes\"}]},{\"t\":10,\"n\":\"Parts\",\"c\":[{\"t\":6,\"n\":\"Part\",\"c\":[{\"t\":3,\"n\":\"INDX - Index\"},{\"t\":2,\"n\":\"ICON - Icon filename\"}]}]}]},{\"t\":6,\"n\":\"Female Body Data\",\"c\":[{\"n\":\"FNAM - Female Body Data Marker\"},{\"t\":6,\"n\":\"Model\",\"c\":[{\"t\":2,\"n\":\"MODL - Model Filename\"},{\"t\":5,\"n\":\"MODB - Bound Radius\"},{\"t\":11,\"n\":\"MODT - Texture Files Hashes\"}]},{\"t\":10,\"n\":\"Parts\",\"c\":[{\"t\":6,\"n\":\"Part\",\"c\":[{\"t\":3,\"n\":\"INDX - Index\"},{\"t\":2,\"n\":\"ICON - Icon filename\"}]}]}]},{\"t\":7,\"n\":\"HNAM - Hairs\",\"c\":[{\"t\":3,\"n\":\"Hair\"}]},{\"t\":7,\"n\":\"ENAM - Eyes\",\"c\":[{\"t\":3,\"n\":\"Eye\"}]},{\"t\":6,\"n\":\"FaceGen Data\",\"c\":[{\"t\":11,\"n\":\"FGGS - FaceGen Geometry-Symmetric\"},{\"t\":11,\"n\":\"FGGA - FaceGen Geometry-Asymmetric\"},{\"t\":11,\"n\":\"FGTS - FaceGen Texture-Symmetric\"}]},{\"t\":11,\"n\":\"SNAM - Unknown\"}]}]},\"name\":\"Bash.Body-Size-F\",\"hash\":\"C6CC40E5\",\"color\":255}"
  },
  {
    "path": "frontend/settings/Oblivion/Bash.Body-Size-M.json",
    "content": "{\"records\":\"RACE\",\"description\":\"Body-Size-M tag from Wrye Bash.\\r\\n\\r\\nUsed when the mod modifies male body weight\\/height definitions.\",\"tree\":{\"records\":[{\"t\":1,\"p\":1,\"n\":\"RACE - Race\",\"c\":[{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"n\":\"FULL - Name\"},{\"t\":2,\"n\":\"DESC - Description\"},{\"t\":8,\"n\":\"Spells\",\"c\":[{\"t\":3,\"n\":\"SPLO - Spell\"}]},{\"t\":8,\"n\":\"Relations\",\"c\":[{\"t\":6,\"n\":\"XNAM - Relation\",\"c\":[{\"t\":3,\"n\":\"Faction\"},{\"t\":3,\"n\":\"Modifier\"}]}]},{\"t\":6,\"p\":1,\"n\":\"DATA - \",\"c\":[{\"t\":7,\"n\":\"Skill Boosts\",\"c\":[{\"t\":6,\"n\":\"Skill Boost\",\"c\":[{\"t\":3,\"n\":\"Skill\"},{\"t\":3,\"n\":\"Boost\"}]}]},{\"t\":11,\"n\":\"Unused\"},{\"t\":5,\"p\":1,\"n\":\"Male Height\"},{\"t\":5,\"n\":\"Female Height\"},{\"t\":5,\"p\":1,\"n\":\"Male Weight\"},{\"t\":5,\"n\":\"Female Weight\"},{\"t\":3,\"n\":\"Flags\"}]},{\"t\":6,\"n\":\"VNAM - Voice\",\"c\":[{\"t\":3,\"n\":\"Male\"},{\"t\":3,\"n\":\"Female\"}]},{\"t\":6,\"n\":\"DNAM - Default Hair\",\"c\":[{\"t\":3,\"n\":\"Male\"},{\"t\":3,\"n\":\"Female\"}]},{\"t\":3,\"n\":\"CNAM - Default Hair Color\"},{\"t\":5,\"n\":\"PNAM - FaceGen - Main clamp\"},{\"t\":5,\"n\":\"UNAM - FaceGen - Face clamp\"},{\"t\":6,\"n\":\"ATTR - Base Attributes\",\"c\":[{\"t\":6,\"n\":\"Male\",\"c\":[{\"t\":3,\"n\":\"Strength\"},{\"t\":3,\"n\":\"Intelligence\"},{\"t\":3,\"n\":\"Willpower\"},{\"t\":3,\"n\":\"Agility\"},{\"t\":3,\"n\":\"Speed\"},{\"t\":3,\"n\":\"Endurance\"},{\"t\":3,\"n\":\"Personality\"},{\"t\":3,\"n\":\"Luck\"}]},{\"t\":6,\"n\":\"Female\",\"c\":[{\"t\":3,\"n\":\"Strength\"},{\"t\":3,\"n\":\"Intelligence\"},{\"t\":3,\"n\":\"Willpower\"},{\"t\":3,\"n\":\"Agility\"},{\"t\":3,\"n\":\"Speed\"},{\"t\":3,\"n\":\"Endurance\"},{\"t\":3,\"n\":\"Personality\"},{\"t\":3,\"n\":\"Luck\"}]}]},{\"t\":6,\"n\":\"Face Data\",\"c\":[{\"n\":\"NAM0 - Face Data Marker\"},{\"t\":10,\"n\":\"Parts\",\"c\":[{\"t\":6,\"n\":\"Part\",\"c\":[{\"t\":3,\"n\":\"INDX - Index\"},{\"t\":6,\"n\":\"Model\",\"c\":[{\"t\":2,\"n\":\"MODL - Model Filename\"},{\"t\":5,\"n\":\"MODB - Bound Radius\"},{\"t\":11,\"n\":\"MODT - Texture Files Hashes\"}]},{\"t\":2,\"n\":\"ICON - Icon filename\"}]}]}]},{\"n\":\"NAM1 - Body Data Marker\"},{\"t\":6,\"n\":\"Male Body Data\",\"c\":[{\"n\":\"MNAM - Male Body Data Marker\"},{\"t\":6,\"n\":\"Model\",\"c\":[{\"t\":2,\"n\":\"MODL - Model Filename\"},{\"t\":5,\"n\":\"MODB - Bound Radius\"},{\"t\":11,\"n\":\"MODT - Texture Files Hashes\"}]},{\"t\":10,\"n\":\"Parts\",\"c\":[{\"t\":6,\"n\":\"Part\",\"c\":[{\"t\":3,\"n\":\"INDX - Index\"},{\"t\":2,\"n\":\"ICON - Icon filename\"}]}]}]},{\"t\":6,\"n\":\"Female Body Data\",\"c\":[{\"n\":\"FNAM - Female Body Data Marker\"},{\"t\":6,\"n\":\"Model\",\"c\":[{\"t\":2,\"n\":\"MODL - Model Filename\"},{\"t\":5,\"n\":\"MODB - Bound Radius\"},{\"t\":11,\"n\":\"MODT - Texture Files Hashes\"}]},{\"t\":10,\"n\":\"Parts\",\"c\":[{\"t\":6,\"n\":\"Part\",\"c\":[{\"t\":3,\"n\":\"INDX - Index\"},{\"t\":2,\"n\":\"ICON - Icon filename\"}]}]}]},{\"t\":7,\"n\":\"HNAM - Hairs\",\"c\":[{\"t\":3,\"n\":\"Hair\"}]},{\"t\":7,\"n\":\"ENAM - Eyes\",\"c\":[{\"t\":3,\"n\":\"Eye\"}]},{\"t\":6,\"n\":\"FaceGen Data\",\"c\":[{\"t\":11,\"n\":\"FGGS - FaceGen Geometry-Symmetric\"},{\"t\":11,\"n\":\"FGGA - FaceGen Geometry-Asymmetric\"},{\"t\":11,\"n\":\"FGTS - FaceGen Texture-Symmetric\"}]},{\"t\":11,\"n\":\"SNAM - Unknown\"}]}]},\"name\":\"Bash.Body-Size-M\",\"hash\":\"FF3104AC\",\"color\":255}"
  },
  {
    "path": "frontend/settings/Oblivion/Bash.C.Climate.json",
    "content": "{\"records\":\"CELL\",\"description\":\"C.Climate tag from Wrye Bash.\\r\\n\\r\\nUsed when the mod modifies cell climates.\",\"tree\":{\"records\":[{\"t\":1,\"p\":1,\"n\":\"CELL - Cell\",\"c\":[{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"n\":\"FULL - Name\"},{\"t\":3,\"n\":\"DATA - Flags\"},{\"t\":6,\"n\":\"XCLC - Grid\",\"c\":[{\"t\":3,\"n\":\"X\"},{\"t\":3,\"n\":\"Y\"}]},{\"t\":6,\"n\":\"XCLL - Lighting\",\"c\":[{\"t\":6,\"n\":\"Ambient Color\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"n\":\"Directional Color\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"n\":\"Fog Color\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":5,\"n\":\"Fog Near\"},{\"t\":5,\"n\":\"Fog Far\"},{\"t\":3,\"n\":\"Directional Rotation XY\"},{\"t\":3,\"n\":\"Directional Rotation Z\"},{\"t\":5,\"n\":\"Directional Fade\"},{\"t\":5,\"n\":\"Fog Clip Dist\"}]},{\"t\":7,\"n\":\"XCLR - Regions\",\"c\":[{\"t\":3,\"n\":\"Region\"}]},{\"t\":3,\"n\":\"XCMT - Music\"},{\"t\":5,\"n\":\"XCLW - Water Height\"},{\"t\":3,\"p\":1,\"n\":\"XCCM - Climate\"},{\"t\":3,\"n\":\"XCWT - Water\"},{\"t\":6,\"n\":\"Ownership\",\"c\":[{\"t\":3,\"n\":\"XOWN - Owner\"},{\"t\":3,\"n\":\"XRNK - Faction rank\"},{\"t\":3,\"n\":\"XGLB - Global variable\"}]}]}]},\"name\":\"Bash.C.Climate\",\"hash\":\"2BA85E9B\",\"color\":255}"
  },
  {
    "path": "frontend/settings/Oblivion/Bash.C.Light.json",
    "content": "{\"records\":\"CELL\",\"description\":\"C.Light tag from Wrye Bash.\\r\\n\\r\\nUsed when the mod modifies cell lighting or fog.\",\"tree\":{\"records\":[{\"t\":1,\"p\":1,\"n\":\"CELL - Cell\",\"c\":[{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"n\":\"FULL - Name\"},{\"t\":3,\"n\":\"DATA - Flags\"},{\"t\":6,\"n\":\"XCLC - Grid\",\"c\":[{\"t\":3,\"n\":\"X\"},{\"t\":3,\"n\":\"Y\"}]},{\"t\":6,\"p\":1,\"n\":\"XCLL - Lighting\",\"c\":[{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Ambient Color\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"p\":1,\"n\":\"Unused\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Directional Color\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"p\":1,\"n\":\"Unused\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Fog Color\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"p\":1,\"n\":\"Unused\"}]},{\"t\":5,\"n\":\"Fog Near\"},{\"t\":5,\"n\":\"Fog Far\"},{\"t\":3,\"n\":\"Directional Rotation XY\"},{\"t\":3,\"n\":\"Directional Rotation Z\"},{\"t\":5,\"n\":\"Directional Fade\"},{\"t\":5,\"n\":\"Fog Clip Dist\"}]},{\"t\":7,\"n\":\"XCLR - Regions\",\"c\":[{\"t\":3,\"n\":\"Region\"}]},{\"t\":3,\"n\":\"XCMT - Music\"},{\"t\":5,\"n\":\"XCLW - Water Height\"},{\"t\":3,\"n\":\"XCCM - Climate\"},{\"t\":3,\"n\":\"XCWT - Water\"},{\"t\":6,\"n\":\"Ownership\",\"c\":[{\"t\":3,\"n\":\"XOWN - Owner\"},{\"t\":3,\"n\":\"XRNK - Faction rank\"},{\"t\":3,\"n\":\"XGLB - Global variable\"}]}]}]},\"name\":\"Bash.C.Light\",\"hash\":\"FD3FC808\",\"color\":255}"
  },
  {
    "path": "frontend/settings/Oblivion/Bash.C.Music.json",
    "content": "{\"records\":\"CELL\",\"description\":\"C.Music tag from Wrye Bash.\\r\\n\\r\\nUsed when the mod modifies cell music type.\",\"tree\":{\"records\":[{\"t\":1,\"p\":1,\"n\":\"CELL - Cell\",\"c\":[{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"n\":\"FULL - Name\"},{\"t\":3,\"n\":\"DATA - Flags\"},{\"t\":6,\"n\":\"XCLC - Grid\",\"c\":[{\"t\":3,\"n\":\"X\"},{\"t\":3,\"n\":\"Y\"}]},{\"t\":6,\"n\":\"XCLL - Lighting\",\"c\":[{\"t\":6,\"n\":\"Ambient Color\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"n\":\"Directional Color\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"n\":\"Fog Color\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":5,\"n\":\"Fog Near\"},{\"t\":5,\"n\":\"Fog Far\"},{\"t\":3,\"n\":\"Directional Rotation XY\"},{\"t\":3,\"n\":\"Directional Rotation Z\"},{\"t\":5,\"n\":\"Directional Fade\"},{\"t\":5,\"n\":\"Fog Clip Dist\"}]},{\"t\":7,\"n\":\"XCLR - Regions\",\"c\":[{\"t\":3,\"n\":\"Region\"}]},{\"t\":3,\"p\":1,\"n\":\"XCMT - Music\"},{\"t\":5,\"n\":\"XCLW - Water Height\"},{\"t\":3,\"n\":\"XCCM - Climate\"},{\"t\":3,\"n\":\"XCWT - Water\"},{\"t\":6,\"n\":\"Ownership\",\"c\":[{\"t\":3,\"n\":\"XOWN - Owner\"},{\"t\":3,\"n\":\"XRNK - Faction rank\"},{\"t\":3,\"n\":\"XGLB - Global variable\"}]}]}]},\"name\":\"Bash.C.Music\",\"hash\":\"2C2C6A24\",\"color\":255}"
  },
  {
    "path": "frontend/settings/Oblivion/Bash.C.Name.json",
    "content": "{\"records\":\"CELL\",\"description\":\"C.Name tag from Wrye Bash.\\r\\n\\r\\nUsed when the mod modifies cell names.\",\"tree\":{\"records\":[{\"t\":1,\"p\":1,\"n\":\"CELL - Cell\",\"c\":[{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":3,\"n\":\"DATA - Flags\"},{\"t\":6,\"n\":\"XCLC - Grid\",\"c\":[{\"t\":3,\"n\":\"X\"},{\"t\":3,\"n\":\"Y\"}]},{\"t\":6,\"n\":\"XCLL - Lighting\",\"c\":[{\"t\":6,\"n\":\"Ambient Color\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"n\":\"Directional Color\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"n\":\"Fog Color\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":5,\"n\":\"Fog Near\"},{\"t\":5,\"n\":\"Fog Far\"},{\"t\":3,\"n\":\"Directional Rotation XY\"},{\"t\":3,\"n\":\"Directional Rotation Z\"},{\"t\":5,\"n\":\"Directional Fade\"},{\"t\":5,\"n\":\"Fog Clip Dist\"}]},{\"t\":7,\"n\":\"XCLR - Regions\",\"c\":[{\"t\":3,\"n\":\"Region\"}]},{\"t\":3,\"n\":\"XCMT - Music\"},{\"t\":5,\"n\":\"XCLW - Water Height\"},{\"t\":3,\"n\":\"XCCM - Climate\"},{\"t\":3,\"n\":\"XCWT - Water\"},{\"t\":6,\"n\":\"Ownership\",\"c\":[{\"t\":3,\"n\":\"XOWN - Owner\"},{\"t\":3,\"n\":\"XRNK - Faction rank\"},{\"t\":3,\"n\":\"XGLB - Global variable\"}]}]}]},\"name\":\"Bash.C.Name\",\"hash\":\"2AE9B4F8\",\"color\":255}"
  },
  {
    "path": "frontend/settings/Oblivion/Bash.C.Owner.json",
    "content": "{\"records\":\"CELL\",\"description\":\"C.Owner tag from Wrye Bash.\\r\\n\\r\\nUsed when the mod modifies cell ownership.\",\"tree\":{\"records\":[{\"t\":1,\"p\":1,\"n\":\"CELL - Cell\",\"c\":[{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"n\":\"FULL - Name\"},{\"t\":3,\"n\":\"DATA - Flags\"},{\"t\":6,\"n\":\"XCLC - Grid\",\"c\":[{\"t\":3,\"n\":\"X\"},{\"t\":3,\"n\":\"Y\"}]},{\"t\":6,\"n\":\"XCLL - Lighting\",\"c\":[{\"t\":6,\"n\":\"Ambient Color\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"n\":\"Directional Color\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"n\":\"Fog Color\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":5,\"n\":\"Fog Near\"},{\"t\":5,\"n\":\"Fog Far\"},{\"t\":3,\"n\":\"Directional Rotation XY\"},{\"t\":3,\"n\":\"Directional Rotation Z\"},{\"t\":5,\"n\":\"Directional Fade\"},{\"t\":5,\"n\":\"Fog Clip Dist\"}]},{\"t\":7,\"n\":\"XCLR - Regions\",\"c\":[{\"t\":3,\"n\":\"Region\"}]},{\"t\":3,\"n\":\"XCMT - Music\"},{\"t\":5,\"n\":\"XCLW - Water Height\"},{\"t\":3,\"n\":\"XCCM - Climate\"},{\"t\":3,\"n\":\"XCWT - Water\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Ownership\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"XOWN - Owner\"},{\"t\":3,\"p\":1,\"n\":\"XRNK - Faction rank\"},{\"t\":3,\"p\":1,\"n\":\"XGLB - Global variable\"}]}]}]},\"name\":\"Bash.C.Owner\",\"hash\":\"B04A60C6\",\"color\":255}"
  },
  {
    "path": "frontend/settings/Oblivion/Bash.C.RecordFlags.json",
    "content": "{\"records\":\"CELL\",\"description\":\"C.RecordFlags tag from Wrye Bash.\\r\\n\\r\\nUsed when the mod modifies the off-limits or dangerous flags.\",\"tree\":{\"records\":[{\"t\":1,\"p\":1,\"n\":\"CELL - Cell\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"n\":\"FULL - Name\"},{\"t\":3,\"n\":\"DATA - Flags\"},{\"t\":6,\"n\":\"XCLC - Grid\",\"c\":[{\"t\":3,\"n\":\"X\"},{\"t\":3,\"n\":\"Y\"}]},{\"t\":6,\"n\":\"XCLL - Lighting\",\"c\":[{\"t\":6,\"n\":\"Ambient Color\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"n\":\"Directional Color\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"n\":\"Fog Color\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":5,\"n\":\"Fog Near\"},{\"t\":5,\"n\":\"Fog Far\"},{\"t\":3,\"n\":\"Directional Rotation XY\"},{\"t\":3,\"n\":\"Directional Rotation Z\"},{\"t\":5,\"n\":\"Directional Fade\"},{\"t\":5,\"n\":\"Fog Clip Dist\"}]},{\"t\":7,\"n\":\"XCLR - Regions\",\"c\":[{\"t\":3,\"n\":\"Region\"}]},{\"t\":3,\"n\":\"XCMT - Music\"},{\"t\":5,\"n\":\"XCLW - Water Height\"},{\"t\":3,\"n\":\"XCCM - Climate\"},{\"t\":3,\"n\":\"XCWT - Water\"},{\"t\":6,\"n\":\"Ownership\",\"c\":[{\"t\":3,\"n\":\"XOWN - Owner\"},{\"t\":3,\"n\":\"XRNK - Faction rank\"},{\"t\":3,\"n\":\"XGLB - Global variable\"}]}]}]},\"name\":\"Bash.C.RecordFlags\",\"hash\":\"FFCD1DD2\",\"color\":255}"
  },
  {
    "path": "frontend/settings/Oblivion/Bash.C.Water.json",
    "content": "{\"records\":\"CELL\",\"description\":\"C.Water tag from Wrye Bash.\\r\\n\\r\\nUsed when the mod modifies cell water type or level.\",\"tree\":{\"records\":[{\"t\":1,\"p\":1,\"n\":\"CELL - Cell\",\"c\":[{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"n\":\"FULL - Name\"},{\"t\":3,\"n\":\"DATA - Flags\"},{\"t\":6,\"n\":\"XCLC - Grid\",\"c\":[{\"t\":3,\"n\":\"X\"},{\"t\":3,\"n\":\"Y\"}]},{\"t\":6,\"n\":\"XCLL - Lighting\",\"c\":[{\"t\":6,\"n\":\"Ambient Color\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"n\":\"Directional Color\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"n\":\"Fog Color\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":5,\"n\":\"Fog Near\"},{\"t\":5,\"n\":\"Fog Far\"},{\"t\":3,\"n\":\"Directional Rotation XY\"},{\"t\":3,\"n\":\"Directional Rotation Z\"},{\"t\":5,\"n\":\"Directional Fade\"},{\"t\":5,\"n\":\"Fog Clip Dist\"}]},{\"t\":7,\"n\":\"XCLR - Regions\",\"c\":[{\"t\":3,\"n\":\"Region\"}]},{\"t\":3,\"n\":\"XCMT - Music\"},{\"t\":5,\"p\":1,\"n\":\"XCLW - Water Height\"},{\"t\":3,\"n\":\"XCCM - Climate\"},{\"t\":3,\"p\":1,\"n\":\"XCWT - Water\"},{\"t\":6,\"n\":\"Ownership\",\"c\":[{\"t\":3,\"n\":\"XOWN - Owner\"},{\"t\":3,\"n\":\"XRNK - Faction rank\"},{\"t\":3,\"n\":\"XGLB - Global variable\"}]}]}]},\"name\":\"Bash.C.Water\",\"hash\":\"3A3E7791\",\"color\":255}"
  },
  {
    "path": "frontend/settings/Oblivion/Bash.Creatures.Blood.json",
    "content": "{\"records\":\"CREA\",\"description\":\"Creatures.Blood tag from Wrye Bash.\\r\\n\\r\\nUsed when the mod modifies the creature blood subrecords.\",\"tree\":{\"records\":[{\"t\":1,\"p\":1,\"n\":\"CREA - Creature\",\"c\":[{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"n\":\"FULL - Name\"},{\"t\":6,\"n\":\"Model\",\"c\":[{\"t\":2,\"n\":\"MODL - Model Filename\"},{\"t\":5,\"n\":\"MODB - Bound Radius\"},{\"t\":11,\"n\":\"MODT - Texture Files Hashes\"}]},{\"t\":8,\"n\":\"Items\",\"c\":[{\"t\":6,\"n\":\"CNTO - Item\",\"c\":[{\"t\":3,\"n\":\"Item\"},{\"t\":3,\"n\":\"Count\"}]}]},{\"t\":8,\"n\":\"Spells\",\"c\":[{\"t\":3,\"n\":\"SPLO - Spell\"}]},{\"t\":7,\"n\":\"NIFZ - Models\",\"c\":[{\"t\":2,\"n\":\"Model\"}]},{\"t\":11,\"n\":\"NIFT - Texture Files Hashes\"},{\"t\":6,\"n\":\"ACBS - Configuration\",\"c\":[{\"t\":3,\"n\":\"Flags\"},{\"t\":3,\"n\":\"Base spell points\"},{\"t\":3,\"n\":\"Fatigue\"},{\"t\":3,\"n\":\"Barter gold\"},{\"t\":3,\"n\":\"Level (offset)\"},{\"t\":3,\"n\":\"Calc min\"},{\"t\":3,\"n\":\"Calc max\"}]},{\"t\":8,\"n\":\"Factions\",\"c\":[{\"t\":6,\"n\":\"SNAM - Faction\",\"c\":[{\"t\":3,\"n\":\"Faction\"},{\"t\":3,\"n\":\"Rank\"},{\"t\":11,\"n\":\"Unused\"}]}]},{\"t\":3,\"n\":\"INAM - Death item\"},{\"t\":3,\"n\":\"SCRI - Script\"},{\"t\":6,\"n\":\"AIDT - AI Data\",\"c\":[{\"t\":3,\"n\":\"Aggression\"},{\"t\":3,\"n\":\"Confidence\"},{\"t\":3,\"n\":\"Energy Level\"},{\"t\":3,\"n\":\"Responsibility\"},{\"t\":3,\"n\":\"Buys\\/Sells and Services\"},{\"t\":3,\"n\":\"Teaches\"},{\"t\":3,\"n\":\"Maximum training level\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":8,\"n\":\"AI Packages\",\"c\":[{\"t\":3,\"n\":\"PKID - AI Package\"}]},{\"t\":7,\"n\":\"KFFZ - Animations\",\"c\":[{\"t\":2,\"n\":\"Animation\"}]},{\"t\":6,\"n\":\"DATA - Creature Data\",\"c\":[{\"t\":3,\"n\":\"Type\"},{\"t\":3,\"n\":\"Combat Skill\"},{\"t\":3,\"n\":\"Magic Skill\"},{\"t\":3,\"n\":\"Stealth Skill\"},{\"t\":3,\"n\":\"Soul\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":3,\"n\":\"Health\"},{\"t\":3,\"n\":\"Attack Damage\"},{\"t\":3,\"n\":\"Strength\"},{\"t\":3,\"n\":\"Intelligence\"},{\"t\":3,\"n\":\"Willpower\"},{\"t\":3,\"n\":\"Agility\"},{\"t\":3,\"n\":\"Speed\"},{\"t\":3,\"n\":\"Endurance\"},{\"t\":3,\"n\":\"Personality\"},{\"t\":3,\"n\":\"Luck\"}]},{\"t\":3,\"n\":\"RNAM - Attack reach\"},{\"t\":3,\"n\":\"ZNAM - Combat Style\"},{\"t\":5,\"n\":\"TNAM - Turning Speed\"},{\"t\":5,\"n\":\"BNAM - Base Scale\"},{\"t\":5,\"n\":\"WNAM - Foot Weight\"},{\"t\":2,\"p\":1,\"n\":\"NAM0 - Blood Spray\"},{\"t\":2,\"p\":1,\"n\":\"NAM1 - Blood Decal\"},{\"t\":3,\"n\":\"CSCR - Inherits Sounds from\"},{\"t\":10,\"n\":\"Sound Types\",\"c\":[{\"t\":6,\"n\":\"Sound Type\",\"c\":[{\"t\":3,\"n\":\"CSDT - Type\"},{\"t\":10,\"n\":\"Sounds\",\"c\":[{\"t\":6,\"n\":\"Sound\",\"c\":[{\"t\":3,\"n\":\"CSDI - Sound\"},{\"t\":3,\"n\":\"CSDC - Sound Chance\"}]}]}]}]}]}]},\"name\":\"Bash.Creatures.Blood\",\"hash\":\"859EBB9B\",\"color\":255}"
  },
  {
    "path": "frontend/settings/Oblivion/Bash.Eyes.json",
    "content": "{\"records\":\"RACE\",\"description\":\"Eyes tag from Wrye Bash.\\r\\n\\r\\nUsed when the mod adds eyes to races.\",\"tree\":{\"records\":[{\"t\":1,\"p\":1,\"n\":\"RACE - Race\",\"c\":[{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"n\":\"FULL - Name\"},{\"t\":2,\"n\":\"DESC - Description\"},{\"t\":8,\"n\":\"Spells\",\"c\":[{\"t\":3,\"n\":\"SPLO - Spell\"}]},{\"t\":8,\"n\":\"Relations\",\"c\":[{\"t\":6,\"n\":\"XNAM - Relation\",\"c\":[{\"t\":3,\"n\":\"Faction\"},{\"t\":3,\"n\":\"Modifier\"}]}]},{\"t\":6,\"n\":\"DATA - \",\"c\":[{\"t\":7,\"n\":\"Skill Boosts\",\"c\":[{\"t\":6,\"n\":\"Skill Boost\",\"c\":[{\"t\":3,\"n\":\"Skill\"},{\"t\":3,\"n\":\"Boost\"}]}]},{\"t\":11,\"n\":\"Unused\"},{\"t\":5,\"n\":\"Male Height\"},{\"t\":5,\"n\":\"Female Height\"},{\"t\":5,\"n\":\"Male Weight\"},{\"t\":5,\"n\":\"Female Weight\"},{\"t\":3,\"n\":\"Flags\"}]},{\"t\":6,\"n\":\"VNAM - Voice\",\"c\":[{\"t\":3,\"n\":\"Male\"},{\"t\":3,\"n\":\"Female\"}]},{\"t\":6,\"n\":\"DNAM - Default Hair\",\"c\":[{\"t\":3,\"n\":\"Male\"},{\"t\":3,\"n\":\"Female\"}]},{\"t\":3,\"n\":\"CNAM - Default Hair Color\"},{\"t\":5,\"n\":\"PNAM - FaceGen - Main clamp\"},{\"t\":5,\"n\":\"UNAM - FaceGen - Face clamp\"},{\"t\":6,\"n\":\"ATTR - Base Attributes\",\"c\":[{\"t\":6,\"n\":\"Male\",\"c\":[{\"t\":3,\"n\":\"Strength\"},{\"t\":3,\"n\":\"Intelligence\"},{\"t\":3,\"n\":\"Willpower\"},{\"t\":3,\"n\":\"Agility\"},{\"t\":3,\"n\":\"Speed\"},{\"t\":3,\"n\":\"Endurance\"},{\"t\":3,\"n\":\"Personality\"},{\"t\":3,\"n\":\"Luck\"}]},{\"t\":6,\"n\":\"Female\",\"c\":[{\"t\":3,\"n\":\"Strength\"},{\"t\":3,\"n\":\"Intelligence\"},{\"t\":3,\"n\":\"Willpower\"},{\"t\":3,\"n\":\"Agility\"},{\"t\":3,\"n\":\"Speed\"},{\"t\":3,\"n\":\"Endurance\"},{\"t\":3,\"n\":\"Personality\"},{\"t\":3,\"n\":\"Luck\"}]}]},{\"t\":6,\"n\":\"Face Data\",\"c\":[{\"n\":\"NAM0 - Face Data Marker\"},{\"t\":10,\"n\":\"Parts\",\"c\":[{\"t\":6,\"n\":\"Part\",\"c\":[{\"t\":3,\"n\":\"INDX - Index\"},{\"t\":6,\"n\":\"Model\",\"c\":[{\"t\":2,\"n\":\"MODL - Model Filename\"},{\"t\":5,\"n\":\"MODB - Bound Radius\"},{\"t\":11,\"n\":\"MODT - Texture Files Hashes\"}]},{\"t\":2,\"n\":\"ICON - Icon filename\"}]}]}]},{\"n\":\"NAM1 - Body Data Marker\"},{\"t\":6,\"n\":\"Male Body Data\",\"c\":[{\"n\":\"MNAM - Male Body Data Marker\"},{\"t\":6,\"n\":\"Model\",\"c\":[{\"t\":2,\"n\":\"MODL - Model Filename\"},{\"t\":5,\"n\":\"MODB - Bound Radius\"},{\"t\":11,\"n\":\"MODT - Texture Files Hashes\"}]},{\"t\":10,\"n\":\"Parts\",\"c\":[{\"t\":6,\"n\":\"Part\",\"c\":[{\"t\":3,\"n\":\"INDX - Index\"},{\"t\":2,\"n\":\"ICON - Icon filename\"}]}]}]},{\"t\":6,\"n\":\"Female Body Data\",\"c\":[{\"n\":\"FNAM - Female Body Data Marker\"},{\"t\":6,\"n\":\"Model\",\"c\":[{\"t\":2,\"n\":\"MODL - Model Filename\"},{\"t\":5,\"n\":\"MODB - Bound Radius\"},{\"t\":11,\"n\":\"MODT - Texture Files Hashes\"}]},{\"t\":10,\"n\":\"Parts\",\"c\":[{\"t\":6,\"n\":\"Part\",\"c\":[{\"t\":3,\"n\":\"INDX - Index\"},{\"t\":2,\"n\":\"ICON - Icon filename\"}]}]}]},{\"t\":7,\"n\":\"HNAM - Hairs\",\"c\":[{\"t\":3,\"n\":\"Hair\"}]},{\"t\":7,\"p\":1,\"n\":\"ENAM - Eyes\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Eye\"}]},{\"t\":6,\"n\":\"FaceGen Data\",\"c\":[{\"t\":11,\"n\":\"FGGS - FaceGen Geometry-Symmetric\"},{\"t\":11,\"n\":\"FGGA - FaceGen Geometry-Asymmetric\"},{\"t\":11,\"n\":\"FGTS - FaceGen Texture-Symmetric\"}]},{\"t\":11,\"n\":\"SNAM - Unknown\"}]}]},\"name\":\"Bash.Eyes\",\"hash\":\"2EBA80F8\",\"color\":255}"
  },
  {
    "path": "frontend/settings/Oblivion/Bash.Factions.json",
    "content": "{\"records\":\"NPC_,CREA\",\"description\":\"Factions tag from Wrye Bash.\\r\\n\\r\\nUsed when the mod modifies creature or NPC factions.\",\"tree\":{\"records\":[{\"t\":1,\"p\":1,\"n\":\"NPC_ - Non-Player Character\",\"c\":[{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"n\":\"FULL - Name\"},{\"t\":6,\"n\":\"Model\",\"c\":[{\"t\":2,\"n\":\"MODL - Model Filename\"},{\"t\":5,\"n\":\"MODB - Bound Radius\"},{\"t\":11,\"n\":\"MODT - Texture Files Hashes\"}]},{\"t\":6,\"n\":\"ACBS - Configuration\",\"c\":[{\"t\":3,\"n\":\"Flags\"},{\"t\":3,\"n\":\"Base spell points\"},{\"t\":3,\"n\":\"Fatigue\"},{\"t\":3,\"n\":\"Barter gold\"},{\"t\":3,\"n\":\"Level (offset)\"},{\"t\":3,\"n\":\"Calc min\"},{\"t\":3,\"n\":\"Calc max\"}]},{\"t\":8,\"p\":1,\"n\":\"Factions\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"SNAM - Faction\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Faction\"},{\"t\":3,\"p\":1,\"n\":\"Rank\"},{\"t\":11,\"p\":1,\"n\":\"Unused\"}]}]},{\"t\":3,\"n\":\"INAM - Death item\"},{\"t\":3,\"n\":\"RNAM - Race\"},{\"t\":8,\"n\":\"Items\",\"c\":[{\"t\":6,\"n\":\"CNTO - Item\",\"c\":[{\"t\":3,\"n\":\"Item\"},{\"t\":3,\"n\":\"Count\"}]}]},{\"t\":8,\"n\":\"Spells\",\"c\":[{\"t\":3,\"n\":\"SPLO - Spell\"}]},{\"t\":3,\"n\":\"SCRI - Script\"},{\"t\":6,\"n\":\"AIDT - AI Data\",\"c\":[{\"t\":3,\"n\":\"Aggression\"},{\"t\":3,\"n\":\"Confidence\"},{\"t\":3,\"n\":\"Energy Level\"},{\"t\":3,\"n\":\"Responsibility\"},{\"t\":3,\"n\":\"Buys\\/Sells and Services\"},{\"t\":3,\"n\":\"Teaches\"},{\"t\":3,\"n\":\"Maximum training level\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":8,\"n\":\"AI Packages\",\"c\":[{\"t\":3,\"n\":\"PKID - AI Package\"}]},{\"t\":7,\"n\":\"KFFZ - Animations\",\"c\":[{\"t\":2,\"n\":\"Animation\"}]},{\"t\":3,\"n\":\"CNAM - Class\"},{\"t\":6,\"n\":\"DATA - Stats\",\"c\":[{\"t\":3,\"n\":\"Armorer\"},{\"t\":3,\"n\":\"Athletics\"},{\"t\":3,\"n\":\"Blade\"},{\"t\":3,\"n\":\"Block\"},{\"t\":3,\"n\":\"Blunt\"},{\"t\":3,\"n\":\"Hand to Hand\"},{\"t\":3,\"n\":\"Heavy Armor\"},{\"t\":3,\"n\":\"Alchemy\"},{\"t\":3,\"n\":\"Alteration\"},{\"t\":3,\"n\":\"Conjuration\"},{\"t\":3,\"n\":\"Destruction\"},{\"t\":3,\"n\":\"Illusion\"},{\"t\":3,\"n\":\"Mysticism\"},{\"t\":3,\"n\":\"Restoration\"},{\"t\":3,\"n\":\"Acrobatics\"},{\"t\":3,\"n\":\"Light Armor\"},{\"t\":3,\"n\":\"Marksman\"},{\"t\":3,\"n\":\"Mercantile\"},{\"t\":3,\"n\":\"Security\"},{\"t\":3,\"n\":\"Sneak\"},{\"t\":3,\"n\":\"Speechcraft\"},{\"t\":3,\"n\":\"Health\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":3,\"n\":\"Strength\"},{\"t\":3,\"n\":\"Intelligence\"},{\"t\":3,\"n\":\"Willpower\"},{\"t\":3,\"n\":\"Agility\"},{\"t\":3,\"n\":\"Speed\"},{\"t\":3,\"n\":\"Endurance\"},{\"t\":3,\"n\":\"Personality\"},{\"t\":3,\"n\":\"Luck\"}]},{\"t\":3,\"n\":\"HNAM - Hair\"},{\"t\":5,\"n\":\"LNAM - Hair length\"},{\"t\":7,\"n\":\"ENAM - Eyes\",\"c\":[{\"t\":3,\"n\":\"Eyes\"}]},{\"t\":6,\"n\":\"HCLR - Hair color\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":3,\"n\":\"ZNAM - Combat Style\"},{\"t\":6,\"n\":\"FaceGen Data\",\"c\":[{\"t\":11,\"n\":\"FGGS - FaceGen Geometry-Symmetric\"},{\"t\":11,\"n\":\"FGGA - FaceGen Geometry-Asymmetric\"},{\"t\":11,\"n\":\"FGTS - FaceGen Texture-Symmetric\"}]},{\"t\":11,\"n\":\"FNAM - Unknown\"}]},{\"t\":1,\"p\":1,\"n\":\"CREA - Creature\",\"c\":[{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"n\":\"FULL - Name\"},{\"t\":6,\"n\":\"Model\",\"c\":[{\"t\":2,\"n\":\"MODL - Model Filename\"},{\"t\":5,\"n\":\"MODB - Bound Radius\"},{\"t\":11,\"n\":\"MODT - Texture Files Hashes\"}]},{\"t\":8,\"n\":\"Items\",\"c\":[{\"t\":6,\"n\":\"CNTO - Item\",\"c\":[{\"t\":3,\"n\":\"Item\"},{\"t\":3,\"n\":\"Count\"}]}]},{\"t\":8,\"n\":\"Spells\",\"c\":[{\"t\":3,\"n\":\"SPLO - Spell\"}]},{\"t\":7,\"n\":\"NIFZ - Models\",\"c\":[{\"t\":2,\"n\":\"Model\"}]},{\"t\":11,\"n\":\"NIFT - Texture Files Hashes\"},{\"t\":6,\"n\":\"ACBS - Configuration\",\"c\":[{\"t\":3,\"n\":\"Flags\"},{\"t\":3,\"n\":\"Base spell points\"},{\"t\":3,\"n\":\"Fatigue\"},{\"t\":3,\"n\":\"Barter gold\"},{\"t\":3,\"n\":\"Level (offset)\"},{\"t\":3,\"n\":\"Calc min\"},{\"t\":3,\"n\":\"Calc max\"}]},{\"t\":8,\"p\":1,\"n\":\"Factions\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"SNAM - Faction\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Faction\"},{\"t\":3,\"p\":1,\"n\":\"Rank\"},{\"t\":11,\"p\":1,\"n\":\"Unused\"}]}]},{\"t\":3,\"n\":\"INAM - Death item\"},{\"t\":3,\"n\":\"SCRI - Script\"},{\"t\":6,\"n\":\"AIDT - AI Data\",\"c\":[{\"t\":3,\"n\":\"Aggression\"},{\"t\":3,\"n\":\"Confidence\"},{\"t\":3,\"n\":\"Energy Level\"},{\"t\":3,\"n\":\"Responsibility\"},{\"t\":3,\"n\":\"Buys\\/Sells and Services\"},{\"t\":3,\"n\":\"Teaches\"},{\"t\":3,\"n\":\"Maximum training level\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":8,\"n\":\"AI Packages\",\"c\":[{\"t\":3,\"n\":\"PKID - AI Package\"}]},{\"t\":7,\"n\":\"KFFZ - Animations\",\"c\":[{\"t\":2,\"n\":\"Animation\"}]},{\"t\":6,\"n\":\"DATA - Creature Data\",\"c\":[{\"t\":3,\"n\":\"Type\"},{\"t\":3,\"n\":\"Combat Skill\"},{\"t\":3,\"n\":\"Magic Skill\"},{\"t\":3,\"n\":\"Stealth Skill\"},{\"t\":3,\"n\":\"Soul\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":3,\"n\":\"Health\"},{\"t\":3,\"n\":\"Attack Damage\"},{\"t\":3,\"n\":\"Strength\"},{\"t\":3,\"n\":\"Intelligence\"},{\"t\":3,\"n\":\"Willpower\"},{\"t\":3,\"n\":\"Agility\"},{\"t\":3,\"n\":\"Speed\"},{\"t\":3,\"n\":\"Endurance\"},{\"t\":3,\"n\":\"Personality\"},{\"t\":3,\"n\":\"Luck\"}]},{\"t\":3,\"n\":\"RNAM - Attack reach\"},{\"t\":3,\"n\":\"ZNAM - Combat Style\"},{\"t\":5,\"n\":\"TNAM - Turning Speed\"},{\"t\":5,\"n\":\"BNAM - Base Scale\"},{\"t\":5,\"n\":\"WNAM - Foot Weight\"},{\"t\":2,\"n\":\"NAM0 - Blood Spray\"},{\"t\":2,\"n\":\"NAM1 - Blood Decal\"},{\"t\":3,\"n\":\"CSCR - Inherits Sounds from\"},{\"t\":10,\"n\":\"Sound Types\",\"c\":[{\"t\":6,\"n\":\"Sound Type\",\"c\":[{\"t\":3,\"n\":\"CSDT - Type\"},{\"t\":10,\"n\":\"Sounds\",\"c\":[{\"t\":6,\"n\":\"Sound\",\"c\":[{\"t\":3,\"n\":\"CSDI - Sound\"},{\"t\":3,\"n\":\"CSDC - Sound Chance\"}]}]}]}]}]}]},\"name\":\"Bash.Factions\",\"hash\":\"FB84E394\",\"color\":255}"
  },
  {
    "path": "frontend/settings/Oblivion/Bash.Graphics.json",
    "content": "{\"records\":\"ALCH,AMMO,APPA,ARMO,BOOK,BSGN,CLAS,CLOT,CREA,DOOR,EFSH,FLOR,FURN,GRAS,INGR,KEYM,LIGH,LSCR,LTEX,MGEF,MISC,REGN,SGST,SLGM,STAT,TREE,WEAP,ACTI\",\"description\":\"Graphics tag from Wrye Bash.\\r\\n\\r\\nUsed when the mod is a graphics replacer.\",\"tree\":{\"records\":[{\"t\":1,\"p\":1,\"n\":\"ALCH - Potion\",\"c\":[{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"n\":\"OBME - Oblivion Magic Extender\",\"c\":[{\"t\":3,\"n\":\"Record Version\"},{\"t\":6,\"n\":\"OBME Version\",\"c\":[{\"t\":3,\"n\":\"Beta\"},{\"t\":3,\"n\":\"Minor\"},{\"t\":3,\"n\":\"Major\"}]},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":2,\"n\":\"FULL - Name\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"},{\"t\":5,\"p\":1,\"n\":\"MODB - Bound Radius\"},{\"t\":11,\"p\":1,\"n\":\"MODT - Texture Files Hashes\"}]},{\"t\":2,\"p\":1,\"n\":\"ICON - Icon filename\"},{\"t\":3,\"n\":\"SCRI - Script\"},{\"t\":5,\"n\":\"DATA - Weight\"},{\"t\":6,\"n\":\"ENIT - \",\"c\":[{\"t\":3,\"n\":\"Value\"},{\"t\":3,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":8,\"n\":\"Effects\",\"c\":[{\"t\":6,\"n\":\"Effect\",\"c\":[{\"t\":3,\"n\":\"EFID - Magic effect name\"},{\"t\":6,\"n\":\"EFIT - \",\"c\":[{\"t\":3,\"n\":\"Magic effect name\"},{\"t\":3,\"n\":\"Magnitude\"},{\"t\":3,\"n\":\"Area\"},{\"t\":3,\"n\":\"Duration\"},{\"t\":3,\"n\":\"Type\"},{\"t\":3,\"n\":\"Actor Value\"}]},{\"t\":6,\"n\":\"Script effect\",\"c\":[{\"t\":6,\"n\":\"SCIT - Script effect data\",\"c\":[{\"t\":3,\"n\":\"Script effect\"},{\"t\":3,\"n\":\"Magic school\"},{\"t\":3,\"n\":\"Visual effect name\"},{\"t\":3,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":2,\"n\":\"FULL - Name\"}]}]},{\"t\":6,\"n\":\"Effects\",\"c\":[{\"t\":8,\"n\":\"Effects\",\"c\":[{\"t\":6,\"n\":\"Effect\",\"c\":[{\"t\":6,\"n\":\"EFME - Oblivion Magic Extender\",\"c\":[{\"t\":3,\"n\":\"Record Version\"},{\"t\":6,\"n\":\"OBME Version\",\"c\":[{\"t\":3,\"n\":\"Beta\"},{\"t\":3,\"n\":\"Minor\"},{\"t\":3,\"n\":\"Major\"}]},{\"t\":3,\"n\":\"EFIT Param Info\"},{\"t\":3,\"n\":\"EFIX Param Info\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":2,\"n\":\"EFID - Magic Effect Code\"},{\"t\":6,\"n\":\"EFIT - \",\"c\":[{\"t\":2,\"n\":\"Magic Effect Code\"},{\"t\":3,\"n\":\"Magnitude\"},{\"t\":3,\"n\":\"Area\"},{\"t\":3,\"n\":\"Duration\"},{\"t\":3,\"n\":\"Type\"},{\"t\":11,\"n\":\"Param #1 - Unknown Type\"},{\"t\":3,\"n\":\"Param #1 - FormID\"},{\"t\":2,\"n\":\"Param #1 - Magic Effect Code\"},{\"t\":3,\"n\":\"Param #1 - Actor Value\"}]},{\"t\":6,\"n\":\"Script effect\",\"c\":[{\"t\":6,\"n\":\"SCIT - Script effect data\",\"c\":[{\"t\":3,\"n\":\"Script effect\"},{\"t\":3,\"n\":\"Magic school\"},{\"t\":2,\"n\":\"Visual Effect Code\"},{\"t\":3,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":2,\"n\":\"FULL - Name\"}]},{\"t\":2,\"n\":\"EFII - Icon\"},{\"t\":6,\"n\":\"EFIX - \",\"c\":[{\"t\":3,\"n\":\"Override Mask\"},{\"t\":3,\"n\":\"Flags\"},{\"t\":5,\"n\":\"Base Cost\"},{\"t\":11,\"n\":\"Param #2 - Unknown Type\"},{\"t\":3,\"n\":\"Param #2 - FormID\"},{\"t\":2,\"n\":\"Param #2 - Magic Effect Code\"},{\"t\":3,\"n\":\"Param #2 - Actor Value\"}]}]}]},{\"n\":\"EFXX - Effects End Marker\"},{\"t\":2,\"n\":\"FULL - Name\"}]}]}]},{\"t\":1,\"p\":1,\"n\":\"AMMO - Ammunition\",\"c\":[{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"n\":\"FULL - Name\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"},{\"t\":5,\"p\":1,\"n\":\"MODB - Bound Radius\"},{\"t\":11,\"p\":1,\"n\":\"MODT - Texture Files Hashes\"}]},{\"t\":2,\"p\":1,\"n\":\"ICON - Icon filename\"},{\"t\":3,\"n\":\"ENAM - Enchantment\"},{\"t\":3,\"n\":\"ANAM - Enchantment Points\"},{\"t\":6,\"n\":\"DATA - \",\"c\":[{\"t\":5,\"n\":\"Speed\"},{\"t\":3,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":3,\"n\":\"Value\"},{\"t\":5,\"n\":\"Weight\"},{\"t\":3,\"n\":\"Damage\"}]}]},{\"t\":1,\"p\":1,\"n\":\"APPA - Alchemical Apparatus\",\"c\":[{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"n\":\"FULL - Name\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"},{\"t\":5,\"p\":1,\"n\":\"MODB - Bound Radius\"},{\"t\":11,\"p\":1,\"n\":\"MODT - Texture Files Hashes\"}]},{\"t\":2,\"p\":1,\"n\":\"ICON - Icon filename\"},{\"t\":3,\"n\":\"SCRI - Script\"},{\"t\":6,\"n\":\"DATA - \",\"c\":[{\"t\":3,\"n\":\"Type\"},{\"t\":3,\"n\":\"Value\"},{\"t\":5,\"n\":\"Weight\"},{\"t\":5,\"n\":\"Quality\"}]}]},{\"t\":1,\"p\":1,\"n\":\"ARMO - Armor\",\"c\":[{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"n\":\"FULL - Name\"},{\"t\":3,\"n\":\"SCRI - Script\"},{\"t\":3,\"n\":\"ENAM - Enchantment\"},{\"t\":3,\"n\":\"ANAM - Enchantment Points\"},{\"t\":6,\"n\":\"BMDT - \",\"c\":[{\"t\":3,\"n\":\"Biped Flags\"},{\"t\":3,\"n\":\"General Flags\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Male biped model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"},{\"t\":5,\"p\":1,\"n\":\"MODB - Bound Radius\"},{\"t\":11,\"p\":1,\"n\":\"MODT - Texture Files Hashes\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Male world model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MOD2 - Model Filename\"},{\"t\":5,\"p\":1,\"n\":\"MO2B - Bound Radius\"},{\"t\":11,\"p\":1,\"n\":\"MO2T - Texture Files Hashes\"}]},{\"t\":2,\"p\":1,\"n\":\"ICON - Male icon filename\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Female biped model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MOD3 - Model Filename\"},{\"t\":5,\"p\":1,\"n\":\"MO3B - Bound Radius\"},{\"t\":11,\"p\":1,\"n\":\"MO3T - Texture Files Hashes\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Female world model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MOD4 - Model Filename\"},{\"t\":5,\"p\":1,\"n\":\"MO4B - Bound Radius\"},{\"t\":11,\"p\":1,\"n\":\"MO4T - Texture Files Hashes\"}]},{\"t\":2,\"p\":1,\"n\":\"ICO2 - Female icon filename\"},{\"t\":6,\"n\":\"DATA - \",\"c\":[{\"t\":3,\"n\":\"Armor\"},{\"t\":3,\"n\":\"Value\"},{\"t\":3,\"n\":\"Health\"},{\"t\":5,\"n\":\"Weight\"}]}]},{\"t\":1,\"p\":1,\"n\":\"BOOK - Book\",\"c\":[{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"n\":\"FULL - Name\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"},{\"t\":5,\"p\":1,\"n\":\"MODB - Bound Radius\"},{\"t\":11,\"p\":1,\"n\":\"MODT - Texture Files Hashes\"}]},{\"t\":2,\"p\":1,\"n\":\"ICON - Icon filename\"},{\"t\":3,\"n\":\"SCRI - Script\"},{\"t\":3,\"n\":\"ENAM - Enchantment\"},{\"t\":3,\"n\":\"ANAM - Enchantment Points\"},{\"t\":2,\"n\":\"DESC - Description\"},{\"t\":6,\"n\":\"DATA - \",\"c\":[{\"t\":3,\"n\":\"Flags\"},{\"t\":3,\"n\":\"Teaches\"},{\"t\":3,\"n\":\"Value\"},{\"t\":5,\"n\":\"Weight\"}]}]},{\"t\":1,\"p\":1,\"n\":\"BSGN - Birthsign\",\"c\":[{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"n\":\"FULL - Name\"},{\"t\":2,\"p\":1,\"n\":\"ICON - Icon filename\"},{\"t\":2,\"n\":\"DESC - Description\"},{\"t\":8,\"n\":\"Spells\",\"c\":[{\"t\":3,\"n\":\"SPLO - Spell\"}]}]},{\"t\":1,\"p\":1,\"n\":\"CLAS - Class\",\"c\":[{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"n\":\"FULL - Name\"},{\"t\":2,\"n\":\"DESC - Description\"},{\"t\":2,\"p\":1,\"n\":\"ICON - Icon filename\"},{\"t\":6,\"n\":\"DATA - \",\"c\":[{\"t\":7,\"n\":\"Primary Attributes\",\"c\":[{\"t\":3,\"n\":\"Primary Attribute\"}]},{\"t\":3,\"n\":\"Specialization\"},{\"t\":7,\"n\":\"Major Skills\",\"c\":[{\"t\":3,\"n\":\"Major Skill\"}]},{\"t\":3,\"n\":\"Flags\"},{\"t\":3,\"n\":\"Buys\\/Sells and Services\"},{\"t\":3,\"n\":\"Teaches\"},{\"t\":3,\"n\":\"Maximum training level\"},{\"t\":3,\"n\":\"Unused\"}]}]},{\"t\":1,\"p\":1,\"n\":\"CLOT - Clothing\",\"c\":[{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"n\":\"FULL - Name\"},{\"t\":3,\"n\":\"SCRI - Script\"},{\"t\":3,\"n\":\"ENAM - Enchantment\"},{\"t\":3,\"n\":\"ANAM - Enchantment Points\"},{\"t\":6,\"n\":\"BMDT - \",\"c\":[{\"t\":3,\"n\":\"Biped Flags\"},{\"t\":3,\"n\":\"General Flags\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Male biped model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"},{\"t\":5,\"p\":1,\"n\":\"MODB - Bound Radius\"},{\"t\":11,\"p\":1,\"n\":\"MODT - Texture Files Hashes\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Male world model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MOD2 - Model Filename\"},{\"t\":5,\"p\":1,\"n\":\"MO2B - Bound Radius\"},{\"t\":11,\"p\":1,\"n\":\"MO2T - Texture Files Hashes\"}]},{\"t\":2,\"p\":1,\"n\":\"ICON - Male icon filename\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Female biped model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MOD3 - Model Filename\"},{\"t\":5,\"p\":1,\"n\":\"MO3B - Bound Radius\"},{\"t\":11,\"p\":1,\"n\":\"MO3T - Texture Files Hashes\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Female world model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MOD4 - Model Filename\"},{\"t\":5,\"p\":1,\"n\":\"MO4B - Bound Radius\"},{\"t\":11,\"p\":1,\"n\":\"MO4T - Texture Files Hashes\"}]},{\"t\":2,\"p\":1,\"n\":\"ICO2 - Female icon filename\"},{\"t\":6,\"n\":\"DATA - \",\"c\":[{\"t\":3,\"n\":\"Value\"},{\"t\":5,\"n\":\"Weight\"}]}]},{\"t\":1,\"p\":1,\"n\":\"CREA - Creature\",\"c\":[{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"n\":\"FULL - Name\"},{\"t\":6,\"n\":\"Model\",\"c\":[{\"t\":2,\"n\":\"MODL - Model Filename\"},{\"t\":5,\"n\":\"MODB - Bound Radius\"},{\"t\":11,\"n\":\"MODT - Texture Files Hashes\"}]},{\"t\":8,\"n\":\"Items\",\"c\":[{\"t\":6,\"n\":\"CNTO - Item\",\"c\":[{\"t\":3,\"n\":\"Item\"},{\"t\":3,\"n\":\"Count\"}]}]},{\"t\":8,\"n\":\"Spells\",\"c\":[{\"t\":3,\"n\":\"SPLO - Spell\"}]},{\"t\":7,\"s\":1,\"p\":1,\"n\":\"NIFZ - Models\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"Model\"}],\"lt\":\"NIFT - Texture Files Hashes\",\"lf\":\"NIFT - Texture Files Hashes\"},{\"t\":11,\"p\":1,\"n\":\"NIFT - Texture Files Hashes\",\"lt\":\"NIFZ - Models\",\"lf\":\"NIFZ - Models\"},{\"t\":6,\"n\":\"ACBS - Configuration\",\"c\":[{\"t\":3,\"n\":\"Flags\"},{\"t\":3,\"n\":\"Base spell points\"},{\"t\":3,\"n\":\"Fatigue\"},{\"t\":3,\"n\":\"Barter gold\"},{\"t\":3,\"n\":\"Level (offset)\"},{\"t\":3,\"n\":\"Calc min\"},{\"t\":3,\"n\":\"Calc max\"}]},{\"t\":8,\"n\":\"Factions\",\"c\":[{\"t\":6,\"n\":\"SNAM - Faction\",\"c\":[{\"t\":3,\"n\":\"Faction\"},{\"t\":3,\"n\":\"Rank\"},{\"t\":11,\"n\":\"Unused\"}]}]},{\"t\":3,\"n\":\"INAM - Death item\"},{\"t\":3,\"n\":\"SCRI - Script\"},{\"t\":6,\"n\":\"AIDT - AI Data\",\"c\":[{\"t\":3,\"n\":\"Aggression\"},{\"t\":3,\"n\":\"Confidence\"},{\"t\":3,\"n\":\"Energy Level\"},{\"t\":3,\"n\":\"Responsibility\"},{\"t\":3,\"n\":\"Buys\\/Sells and Services\"},{\"t\":3,\"n\":\"Teaches\"},{\"t\":3,\"n\":\"Maximum training level\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":8,\"n\":\"AI Packages\",\"c\":[{\"t\":3,\"n\":\"PKID - AI Package\"}]},{\"t\":7,\"n\":\"KFFZ - Animations\",\"c\":[{\"t\":2,\"n\":\"Animation\"}]},{\"t\":6,\"n\":\"DATA - Creature Data\",\"c\":[{\"t\":3,\"n\":\"Type\"},{\"t\":3,\"n\":\"Combat Skill\"},{\"t\":3,\"n\":\"Magic Skill\"},{\"t\":3,\"n\":\"Stealth Skill\"},{\"t\":3,\"n\":\"Soul\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":3,\"n\":\"Health\"},{\"t\":3,\"n\":\"Attack Damage\"},{\"t\":3,\"n\":\"Strength\"},{\"t\":3,\"n\":\"Intelligence\"},{\"t\":3,\"n\":\"Willpower\"},{\"t\":3,\"n\":\"Agility\"},{\"t\":3,\"n\":\"Speed\"},{\"t\":3,\"n\":\"Endurance\"},{\"t\":3,\"n\":\"Personality\"},{\"t\":3,\"n\":\"Luck\"}]},{\"t\":3,\"n\":\"RNAM - Attack reach\"},{\"t\":3,\"n\":\"ZNAM - Combat Style\"},{\"t\":5,\"n\":\"TNAM - Turning Speed\"},{\"t\":5,\"n\":\"BNAM - Base Scale\"},{\"t\":5,\"n\":\"WNAM - Foot Weight\"},{\"t\":2,\"n\":\"NAM0 - Blood Spray\"},{\"t\":2,\"n\":\"NAM1 - Blood Decal\"},{\"t\":3,\"n\":\"CSCR - Inherits Sounds from\"},{\"t\":10,\"n\":\"Sound Types\",\"c\":[{\"t\":6,\"n\":\"Sound Type\",\"c\":[{\"t\":3,\"n\":\"CSDT - Type\"},{\"t\":10,\"n\":\"Sounds\",\"c\":[{\"t\":6,\"n\":\"Sound\",\"c\":[{\"t\":3,\"n\":\"CSDI - Sound\"},{\"t\":3,\"n\":\"CSDC - Sound Chance\"}]}]}]}]}]},{\"t\":1,\"p\":1,\"n\":\"DOOR - Door\",\"c\":[{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"n\":\"FULL - Name\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"},{\"t\":5,\"p\":1,\"n\":\"MODB - Bound Radius\"},{\"t\":11,\"p\":1,\"n\":\"MODT - Texture Files Hashes\"}]},{\"t\":3,\"n\":\"SCRI - Script\"},{\"t\":3,\"n\":\"SNAM - Open sound\"},{\"t\":3,\"n\":\"ANAM - Close sound\"},{\"t\":3,\"n\":\"BNAM - Loop sound\"},{\"t\":3,\"n\":\"FNAM - Flags\"},{\"t\":8,\"n\":\"Random teleport destinations\",\"c\":[{\"t\":3,\"n\":\"TNAM - Destination\"}]}]},{\"t\":1,\"p\":1,\"n\":\"EFSH - Effect Shader\",\"c\":[{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"p\":1,\"n\":\"ICON - Fill Texture\"},{\"t\":2,\"p\":1,\"n\":\"ICO2 - Particle Shader Texture\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DATA - \",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"p\":1,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Membrane Shader - Source Blend Mode\"},{\"t\":3,\"p\":1,\"n\":\"Membrane Shader - Blend Operation\"},{\"t\":3,\"p\":1,\"n\":\"Membrane Shader - Z Test Function\"},{\"t\":6,\"p\":1,\"n\":\"Fill\\/Texture Effect - Color\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"p\":1,\"n\":\"Unused\"}]},{\"t\":5,\"p\":1,\"n\":\"Fill\\/Texture Effect - Alpha Fade In Time\"},{\"t\":5,\"p\":1,\"n\":\"Fill\\/Texture Effect - Full Alpha Time\"},{\"t\":5,\"p\":1,\"n\":\"Fill\\/Texture Effect - Alpha Fade Out Time\"},{\"t\":5,\"p\":1,\"n\":\"Fill\\/Texture Effect - Presistent Alpha Ratio\"},{\"t\":5,\"p\":1,\"n\":\"Fill\\/Texture Effect - Alpha Pulse Amplitude\"},{\"t\":5,\"p\":1,\"n\":\"Fill\\/Texture Effect - Alpha Pulse Frequency\"},{\"t\":5,\"p\":1,\"n\":\"Fill\\/Texture Effect - Texture Animation Speed (U)\"},{\"t\":5,\"p\":1,\"n\":\"Fill\\/Texture Effect - Texture Animation Speed (V)\"},{\"t\":5,\"p\":1,\"n\":\"Edge Effect - Fall Off\"},{\"t\":6,\"p\":1,\"n\":\"Edge Effect - Color\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"p\":1,\"n\":\"Unused\"}]},{\"t\":5,\"p\":1,\"n\":\"Edge Effect - Alpha Fade In Time\"},{\"t\":5,\"p\":1,\"n\":\"Edge Effect - Full Alpha Time\"},{\"t\":5,\"p\":1,\"n\":\"Edge Effect - Alpha Fade Out Time\"},{\"t\":5,\"p\":1,\"n\":\"Edge Effect - Persistent Alpha Ratio\"},{\"t\":5,\"p\":1,\"n\":\"Edge Effect - Alpha Pulse Amplitude\"},{\"t\":5,\"p\":1,\"n\":\"Edge Effect - Alpha Pusle Frequence\"},{\"t\":5,\"p\":1,\"n\":\"Fill\\/Texture Effect - Full Alpha Ratio\"},{\"t\":5,\"p\":1,\"n\":\"Edge Effect - Full Alpha Ratio\"},{\"t\":3,\"p\":1,\"n\":\"Membrane Shader - Dest Blend Mode\"},{\"t\":3,\"p\":1,\"n\":\"Particle Shader - Source Blend Mode\"},{\"t\":3,\"p\":1,\"n\":\"Particle Shader - Blend Operation\"},{\"t\":3,\"p\":1,\"n\":\"Particle Shader - Z Test Function\"},{\"t\":3,\"p\":1,\"n\":\"Particle Shader - Dest Blend Mode\"},{\"t\":5,\"p\":1,\"n\":\"Particle Shader - Particle Birth Ramp Up Time\"},{\"t\":5,\"p\":1,\"n\":\"Particle Shader - Full Particle Birth Time\"},{\"t\":5,\"p\":1,\"n\":\"Particle Shader - Particle Birth Ramp Down Time\"},{\"t\":5,\"p\":1,\"n\":\"Particle Shader - Full Particle Birth Ratio\"},{\"t\":5,\"p\":1,\"n\":\"Particle Shader - Persistant Particle Birth Ratio\"},{\"t\":5,\"p\":1,\"n\":\"Particle Shader - Particle Lifetime\"},{\"t\":5,\"p\":1,\"n\":\"Particle Shader - Particle Lifetime +\\/-\"},{\"t\":5,\"p\":1,\"n\":\"Particle Shader - Initial Speed Along Normal\"},{\"t\":5,\"p\":1,\"n\":\"Particle Shader - Acceleration Along Normal\"},{\"t\":5,\"p\":1,\"n\":\"Particle Shader - Initial Velocity #1\"},{\"t\":5,\"p\":1,\"n\":\"Particle Shader - Initial Velocity #2\"},{\"t\":5,\"p\":1,\"n\":\"Particle Shader - Initial Velocity #3\"},{\"t\":5,\"p\":1,\"n\":\"Particle Shader - Acceleration #1\"},{\"t\":5,\"p\":1,\"n\":\"Particle Shader - Acceleration #2\"},{\"t\":5,\"p\":1,\"n\":\"Particle Shader - Acceleration #3\"},{\"t\":5,\"p\":1,\"n\":\"Particle Shader - Scale Key 1\"},{\"t\":5,\"p\":1,\"n\":\"Particle Shader - Scale Key 2\"},{\"t\":5,\"p\":1,\"n\":\"Particle Shader - Scale Key 1 Time\"},{\"t\":5,\"p\":1,\"n\":\"Particle Shader - Scale Key 2 Time\"},{\"t\":6,\"p\":1,\"n\":\"Color Key 1 - Color\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"p\":1,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Color Key 2 - Color\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"p\":1,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Color Key 3 - Color\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"p\":1,\"n\":\"Unused\"}]},{\"t\":5,\"p\":1,\"n\":\"Color Key 1 - Color Alpha\"},{\"t\":5,\"p\":1,\"n\":\"Color Key 2 - Color Alpha\"},{\"t\":5,\"p\":1,\"n\":\"Color Key 3 - Color Alpha\"},{\"t\":5,\"p\":1,\"n\":\"Color Key 1 - Color Key Time\"},{\"t\":5,\"p\":1,\"n\":\"Color Key 2 - Color Key Time\"},{\"t\":5,\"p\":1,\"n\":\"Color Key 3 - Color Key Time\"}]}]},{\"t\":1,\"p\":1,\"n\":\"FLOR - Flora\",\"c\":[{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"n\":\"FULL - Name\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"},{\"t\":5,\"p\":1,\"n\":\"MODB - Bound Radius\"},{\"t\":11,\"p\":1,\"n\":\"MODT - Texture Files Hashes\"}]},{\"t\":3,\"n\":\"SCRI - Script\"},{\"t\":3,\"n\":\"PFIG - Ingredient\"},{\"t\":6,\"n\":\"PFPC - Seasonal ingredient production\",\"c\":[{\"t\":3,\"n\":\"Spring\"},{\"t\":3,\"n\":\"Summer \"},{\"t\":3,\"n\":\"Fall\"},{\"t\":3,\"n\":\"Winter\"}]}]},{\"t\":1,\"p\":1,\"n\":\"FURN - Furniture\",\"c\":[{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"n\":\"FULL - Name\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"},{\"t\":5,\"p\":1,\"n\":\"MODB - Bound Radius\"},{\"t\":11,\"p\":1,\"n\":\"MODT - Texture Files Hashes\"}]},{\"t\":3,\"n\":\"SCRI - Script\"},{\"t\":11,\"n\":\"MNAM - Marker Flags\"}]},{\"t\":1,\"p\":1,\"n\":\"GRAS - Grass\",\"c\":[{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"},{\"t\":5,\"p\":1,\"n\":\"MODB - Bound Radius\"},{\"t\":11,\"p\":1,\"n\":\"MODT - Texture Files Hashes\"}]},{\"t\":6,\"n\":\"DATA - \",\"c\":[{\"t\":3,\"n\":\"Density\"},{\"t\":3,\"n\":\"Min Slope\"},{\"t\":3,\"n\":\"Max Slope\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":3,\"n\":\"Unit from water amount\"},{\"t\":3,\"n\":\"Unit from water type\"},{\"t\":5,\"n\":\"Position Range\"},{\"t\":5,\"n\":\"Height Range\"},{\"t\":5,\"n\":\"Color Range\"},{\"t\":5,\"n\":\"Wave Period\"},{\"t\":3,\"n\":\"Flags\"}]}]},{\"t\":1,\"p\":1,\"n\":\"INGR - Ingredient\",\"c\":[{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"n\":\"OBME - Oblivion Magic Extender\",\"c\":[{\"t\":3,\"n\":\"Record Version\"},{\"t\":6,\"n\":\"OBME Version\",\"c\":[{\"t\":3,\"n\":\"Beta\"},{\"t\":3,\"n\":\"Minor\"},{\"t\":3,\"n\":\"Major\"}]},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":2,\"n\":\"FULL - Name\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"},{\"t\":5,\"p\":1,\"n\":\"MODB - Bound Radius\"},{\"t\":11,\"p\":1,\"n\":\"MODT - Texture Files Hashes\"}]},{\"t\":2,\"p\":1,\"n\":\"ICON - Icon filename\"},{\"t\":3,\"n\":\"SCRI - Script\"},{\"t\":5,\"n\":\"DATA - Weight\"},{\"t\":6,\"n\":\"ENIT - \",\"c\":[{\"t\":3,\"n\":\"Value\"},{\"t\":3,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":8,\"n\":\"Effects\",\"c\":[{\"t\":6,\"n\":\"Effect\",\"c\":[{\"t\":3,\"n\":\"EFID - Magic effect name\"},{\"t\":6,\"n\":\"EFIT - \",\"c\":[{\"t\":3,\"n\":\"Magic effect name\"},{\"t\":3,\"n\":\"Magnitude\"},{\"t\":3,\"n\":\"Area\"},{\"t\":3,\"n\":\"Duration\"},{\"t\":3,\"n\":\"Type\"},{\"t\":3,\"n\":\"Actor Value\"}]},{\"t\":6,\"n\":\"Script effect\",\"c\":[{\"t\":6,\"n\":\"SCIT - Script effect data\",\"c\":[{\"t\":3,\"n\":\"Script effect\"},{\"t\":3,\"n\":\"Magic school\"},{\"t\":3,\"n\":\"Visual effect name\"},{\"t\":3,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":2,\"n\":\"FULL - Name\"}]}]},{\"t\":6,\"n\":\"Effects\",\"c\":[{\"t\":8,\"n\":\"Effects\",\"c\":[{\"t\":6,\"n\":\"Effect\",\"c\":[{\"t\":6,\"n\":\"EFME - Oblivion Magic Extender\",\"c\":[{\"t\":3,\"n\":\"Record Version\"},{\"t\":6,\"n\":\"OBME Version\",\"c\":[{\"t\":3,\"n\":\"Beta\"},{\"t\":3,\"n\":\"Minor\"},{\"t\":3,\"n\":\"Major\"}]},{\"t\":3,\"n\":\"EFIT Param Info\"},{\"t\":3,\"n\":\"EFIX Param Info\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":2,\"n\":\"EFID - Magic Effect Code\"},{\"t\":6,\"n\":\"EFIT - \",\"c\":[{\"t\":2,\"n\":\"Magic Effect Code\"},{\"t\":3,\"n\":\"Magnitude\"},{\"t\":3,\"n\":\"Area\"},{\"t\":3,\"n\":\"Duration\"},{\"t\":3,\"n\":\"Type\"},{\"t\":11,\"n\":\"Param #1 - Unknown Type\"},{\"t\":3,\"n\":\"Param #1 - FormID\"},{\"t\":2,\"n\":\"Param #1 - Magic Effect Code\"},{\"t\":3,\"n\":\"Param #1 - Actor Value\"}]},{\"t\":6,\"n\":\"Script effect\",\"c\":[{\"t\":6,\"n\":\"SCIT - Script effect data\",\"c\":[{\"t\":3,\"n\":\"Script effect\"},{\"t\":3,\"n\":\"Magic school\"},{\"t\":2,\"n\":\"Visual Effect Code\"},{\"t\":3,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":2,\"n\":\"FULL - Name\"}]},{\"t\":2,\"n\":\"EFII - Icon\"},{\"t\":6,\"n\":\"EFIX - \",\"c\":[{\"t\":3,\"n\":\"Override Mask\"},{\"t\":3,\"n\":\"Flags\"},{\"t\":5,\"n\":\"Base Cost\"},{\"t\":11,\"n\":\"Param #2 - Unknown Type\"},{\"t\":3,\"n\":\"Param #2 - FormID\"},{\"t\":2,\"n\":\"Param #2 - Magic Effect Code\"},{\"t\":3,\"n\":\"Param #2 - Actor Value\"}]}]}]},{\"n\":\"EFXX - Effects End Marker\"},{\"t\":2,\"n\":\"FULL - Name\"}]}]}]},{\"t\":1,\"p\":1,\"n\":\"KEYM - Key\",\"c\":[{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"n\":\"FULL - Name\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"},{\"t\":5,\"p\":1,\"n\":\"MODB - Bound Radius\"},{\"t\":11,\"p\":1,\"n\":\"MODT - Texture Files Hashes\"}]},{\"t\":2,\"p\":1,\"n\":\"ICON - Icon filename\"},{\"t\":3,\"n\":\"SCRI - Script\"},{\"t\":6,\"n\":\"DATA - \",\"c\":[{\"t\":3,\"n\":\"Value\"},{\"t\":5,\"n\":\"Weight\"}]}]},{\"t\":1,\"p\":1,\"n\":\"LIGH - Light\",\"c\":[{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"},{\"t\":5,\"p\":1,\"n\":\"MODB - Bound Radius\"},{\"t\":11,\"p\":1,\"n\":\"MODT - Texture Files Hashes\"}]},{\"t\":3,\"n\":\"SCRI - Script\"},{\"t\":2,\"n\":\"FULL - Name\"},{\"t\":2,\"p\":1,\"n\":\"ICON - Icon filename\"},{\"t\":6,\"n\":\"DATA - \",\"c\":[{\"t\":3,\"n\":\"Time\"},{\"t\":3,\"n\":\"Radius\"},{\"t\":6,\"n\":\"Color\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":3,\"n\":\"Unused\"}]},{\"t\":3,\"n\":\"Flags\"},{\"t\":5,\"n\":\"Falloff Exponent\"},{\"t\":5,\"n\":\"FOV\"},{\"t\":3,\"n\":\"Value\"},{\"t\":5,\"n\":\"Weight\"}]},{\"t\":5,\"n\":\"FNAM - Fade value\"},{\"t\":3,\"n\":\"SNAM - Sound\"}]},{\"t\":1,\"p\":1,\"n\":\"LSCR - Load Screen\",\"c\":[{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"p\":1,\"n\":\"ICON - Icon filename\"},{\"t\":2,\"n\":\"DESC - Description\"},{\"t\":8,\"n\":\"Locations\",\"c\":[{\"t\":6,\"n\":\"LNAM - Location\",\"c\":[{\"t\":3,\"n\":\"Direct\"},{\"t\":6,\"n\":\"Indirect\",\"c\":[{\"t\":3,\"n\":\"World\"},{\"t\":6,\"n\":\"Grid\",\"c\":[{\"t\":3,\"n\":\"Y\"},{\"t\":3,\"n\":\"X\"}]}]}]}]}]},{\"t\":1,\"p\":1,\"n\":\"LTEX - Landscape Texture\",\"c\":[{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"p\":1,\"n\":\"ICON - Icon filename\"},{\"t\":6,\"n\":\"HNAM - Havok Data\",\"c\":[{\"t\":3,\"n\":\"Material Type\"},{\"t\":3,\"n\":\"Friction\"},{\"t\":3,\"n\":\"Restitution\"}]},{\"t\":3,\"n\":\"SNAM - Texture Specular Exponent\"},{\"t\":8,\"n\":\"Grasses\",\"c\":[{\"t\":3,\"n\":\"GNAM - Grass\"}]}]},{\"t\":1,\"p\":1,\"n\":\"MGEF - Magic Effect\",\"c\":[{\"t\":2,\"n\":\"EDID - Magic Effect Code\"},{\"t\":6,\"n\":\"OBME - Oblivion Magic Extender\",\"c\":[{\"t\":3,\"n\":\"Record Version\"},{\"t\":6,\"n\":\"OBME Version\",\"c\":[{\"t\":3,\"n\":\"Beta\"},{\"t\":3,\"n\":\"Minor\"},{\"t\":3,\"n\":\"Major\"}]},{\"t\":3,\"n\":\"Param A Info\"},{\"t\":3,\"n\":\"Param B Info\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":2,\"n\":\"Handler\"},{\"t\":3,\"n\":\"Flag Overrides\"},{\"t\":11,\"n\":\"ParamB\"}]},{\"t\":2,\"n\":\"EDDX - EditorID\"},{\"t\":2,\"n\":\"FULL - Name\"},{\"t\":2,\"n\":\"DESC - Description\"},{\"t\":2,\"p\":1,\"n\":\"ICON - Icon filename\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"},{\"t\":5,\"p\":1,\"n\":\"MODB - Bound Radius\"},{\"t\":11,\"p\":1,\"n\":\"MODT - Texture Files Hashes\"}]},{\"t\":6,\"n\":\"DATA - Data\",\"c\":[{\"t\":3,\"n\":\"Flags\"},{\"t\":5,\"n\":\"Base cost\"},{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"n\":\"Assoc. Weapon\"},{\"t\":3,\"n\":\"Assoc. Armor\"},{\"t\":3,\"n\":\"Assoc. Creature\"},{\"t\":3,\"n\":\"Assoc. Actor Value\"},{\"t\":3,\"n\":\"Magic School\"},{\"t\":3,\"n\":\"Resist value\"},{\"t\":3,\"n\":\"Counter Effect Count\"},{\"t\":3,\"n\":\"Light\"},{\"t\":5,\"n\":\"Projectile speed\"},{\"t\":3,\"n\":\"Effect Shader\"},{\"t\":3,\"n\":\"Enchant effect\"},{\"t\":3,\"n\":\"Casting sound\"},{\"t\":3,\"n\":\"Bolt sound\"},{\"t\":3,\"n\":\"Hit sound\"},{\"t\":3,\"n\":\"Area sound\"},{\"t\":5,\"n\":\"Constant Effect enchantment factor\"},{\"t\":5,\"n\":\"Constant Effect barter factor\"}]},{\"t\":7,\"n\":\"ESCE - Counter Effects\",\"c\":[{\"t\":2,\"n\":\"Counter Effect Code\"}]}]},{\"t\":1,\"p\":1,\"n\":\"MISC - Misc. Item\",\"c\":[{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"n\":\"FULL - Name\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"},{\"t\":5,\"p\":1,\"n\":\"MODB - Bound Radius\"},{\"t\":11,\"p\":1,\"n\":\"MODT - Texture Files Hashes\"}]},{\"t\":2,\"p\":1,\"n\":\"ICON - Icon filename\"},{\"t\":3,\"n\":\"SCRI - Script\"},{\"t\":6,\"n\":\"DATA - \",\"c\":[{\"t\":3,\"n\":\"Value\"},{\"t\":3,\"n\":\"Actor Value\"},{\"t\":5,\"n\":\"Weight\"},{\"t\":3,\"n\":\"Group\"}]}]},{\"t\":1,\"p\":1,\"n\":\"REGN - Region\",\"c\":[{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"p\":1,\"n\":\"ICON - Icon filename\"},{\"t\":6,\"n\":\"RCLR - Map Color\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":3,\"n\":\"WNAM - Worldspace\"},{\"t\":8,\"n\":\"Region Areas\",\"c\":[{\"t\":6,\"n\":\"Region Area\",\"c\":[{\"t\":3,\"n\":\"RPLI - Edge Fall-off\"},{\"t\":7,\"n\":\"RPLD - Region Point List Data\",\"c\":[{\"t\":6,\"n\":\"Point\",\"c\":[{\"t\":5,\"n\":\"X\"},{\"t\":5,\"n\":\"Y\"}]}]}]}]},{\"t\":10,\"n\":\"Region Data Entries\",\"c\":[{\"t\":6,\"n\":\"Region Data Entry\",\"c\":[{\"t\":6,\"n\":\"RDAT - Data Header\",\"c\":[{\"t\":3,\"n\":\"Type\"},{\"t\":3,\"n\":\"Flags\"},{\"t\":3,\"n\":\"Priority\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":7,\"n\":\"RDOT - Objects\",\"c\":[{\"t\":6,\"n\":\"Object\",\"c\":[{\"t\":3,\"n\":\"Object\"},{\"t\":3,\"n\":\"Parent Index\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":5,\"n\":\"Density\"},{\"t\":3,\"n\":\"Clustering\"},{\"t\":3,\"n\":\"Min Slope\"},{\"t\":3,\"n\":\"Max Slope\"},{\"t\":3,\"n\":\"Flags\"},{\"t\":3,\"n\":\"Radius wrt Parent\"},{\"t\":3,\"n\":\"Radius\"},{\"t\":5,\"n\":\"Min Height\"},{\"t\":5,\"n\":\"Max Height\"},{\"t\":5,\"n\":\"Sink\"},{\"t\":5,\"n\":\"Sink Variance\"},{\"t\":5,\"n\":\"Size Variance\"},{\"t\":6,\"n\":\"Angle Variance\",\"c\":[{\"t\":3,\"n\":\"X\"},{\"t\":3,\"n\":\"Y\"},{\"t\":3,\"n\":\"Z\"}]},{\"t\":11,\"n\":\"Unknown\"}]}]},{\"t\":2,\"n\":\"RDMP - Map Name\"},{\"t\":7,\"n\":\"RDGS - Grasses\",\"c\":[{\"t\":6,\"n\":\"Grass\",\"c\":[{\"t\":3,\"n\":\"Grass\"},{\"t\":11,\"n\":\"Unused\"}]}]},{\"t\":3,\"n\":\"RDMD - Music Type\"},{\"t\":7,\"n\":\"RDSD - Sounds\",\"c\":[{\"t\":6,\"n\":\"Sound\",\"c\":[{\"t\":3,\"n\":\"Sound\"},{\"t\":3,\"n\":\"Flags\"},{\"t\":3,\"n\":\"Chance\"}]}]},{\"t\":7,\"n\":\"RDWT - Weather Types\",\"c\":[{\"t\":6,\"n\":\"Weather Type\",\"c\":[{\"t\":3,\"n\":\"Weather\"},{\"t\":3,\"n\":\"Chance\"}]}]}]}]}]},{\"t\":1,\"p\":1,\"n\":\"SGST - Sigil Stone\",\"c\":[{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"n\":\"OBME - Oblivion Magic Extender\",\"c\":[{\"t\":3,\"n\":\"Record Version\"},{\"t\":6,\"n\":\"OBME Version\",\"c\":[{\"t\":3,\"n\":\"Beta\"},{\"t\":3,\"n\":\"Minor\"},{\"t\":3,\"n\":\"Major\"}]},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":2,\"n\":\"FULL - Name\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"},{\"t\":5,\"p\":1,\"n\":\"MODB - Bound Radius\"},{\"t\":11,\"p\":1,\"n\":\"MODT - Texture Files Hashes\"}]},{\"t\":2,\"p\":1,\"n\":\"ICON - Icon filename\"},{\"t\":3,\"n\":\"SCRI - Script\"},{\"t\":8,\"n\":\"Effects\",\"c\":[{\"t\":6,\"n\":\"Effect\",\"c\":[{\"t\":3,\"n\":\"EFID - Magic effect name\"},{\"t\":6,\"n\":\"EFIT - \",\"c\":[{\"t\":3,\"n\":\"Magic effect name\"},{\"t\":3,\"n\":\"Magnitude\"},{\"t\":3,\"n\":\"Area\"},{\"t\":3,\"n\":\"Duration\"},{\"t\":3,\"n\":\"Type\"},{\"t\":3,\"n\":\"Actor Value\"}]},{\"t\":6,\"n\":\"Script effect\",\"c\":[{\"t\":6,\"n\":\"SCIT - Script effect data\",\"c\":[{\"t\":3,\"n\":\"Script effect\"},{\"t\":3,\"n\":\"Magic school\"},{\"t\":3,\"n\":\"Visual effect name\"},{\"t\":3,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":2,\"n\":\"FULL - Name\"}]}]},{\"t\":6,\"n\":\"Effects\",\"c\":[{\"t\":8,\"n\":\"Effects\",\"c\":[{\"t\":6,\"n\":\"Effect\",\"c\":[{\"t\":6,\"n\":\"EFME - Oblivion Magic Extender\",\"c\":[{\"t\":3,\"n\":\"Record Version\"},{\"t\":6,\"n\":\"OBME Version\",\"c\":[{\"t\":3,\"n\":\"Beta\"},{\"t\":3,\"n\":\"Minor\"},{\"t\":3,\"n\":\"Major\"}]},{\"t\":3,\"n\":\"EFIT Param Info\"},{\"t\":3,\"n\":\"EFIX Param Info\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":2,\"n\":\"EFID - Magic Effect Code\"},{\"t\":6,\"n\":\"EFIT - \",\"c\":[{\"t\":2,\"n\":\"Magic Effect Code\"},{\"t\":3,\"n\":\"Magnitude\"},{\"t\":3,\"n\":\"Area\"},{\"t\":3,\"n\":\"Duration\"},{\"t\":3,\"n\":\"Type\"},{\"t\":11,\"n\":\"Param #1 - Unknown Type\"},{\"t\":3,\"n\":\"Param #1 - FormID\"},{\"t\":2,\"n\":\"Param #1 - Magic Effect Code\"},{\"t\":3,\"n\":\"Param #1 - Actor Value\"}]},{\"t\":6,\"n\":\"Script effect\",\"c\":[{\"t\":6,\"n\":\"SCIT - Script effect data\",\"c\":[{\"t\":3,\"n\":\"Script effect\"},{\"t\":3,\"n\":\"Magic school\"},{\"t\":2,\"n\":\"Visual Effect Code\"},{\"t\":3,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":2,\"n\":\"FULL - Name\"}]},{\"t\":2,\"n\":\"EFII - Icon\"},{\"t\":6,\"n\":\"EFIX - \",\"c\":[{\"t\":3,\"n\":\"Override Mask\"},{\"t\":3,\"n\":\"Flags\"},{\"t\":5,\"n\":\"Base Cost\"},{\"t\":11,\"n\":\"Param #2 - Unknown Type\"},{\"t\":3,\"n\":\"Param #2 - FormID\"},{\"t\":2,\"n\":\"Param #2 - Magic Effect Code\"},{\"t\":3,\"n\":\"Param #2 - Actor Value\"}]}]}]},{\"n\":\"EFXX - Effects End Marker\"},{\"t\":2,\"n\":\"FULL - Name\"}]}]},{\"t\":6,\"n\":\"DATA - \",\"c\":[{\"t\":3,\"n\":\"Uses \"},{\"t\":3,\"n\":\"Value\"},{\"t\":5,\"n\":\"Weight\"}]}]},{\"t\":1,\"p\":1,\"n\":\"SLGM - Soul Gem\",\"c\":[{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"n\":\"FULL - Name\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"},{\"t\":5,\"p\":1,\"n\":\"MODB - Bound Radius\"},{\"t\":11,\"p\":1,\"n\":\"MODT - Texture Files Hashes\"}]},{\"t\":2,\"p\":1,\"n\":\"ICON - Icon filename\"},{\"t\":3,\"n\":\"SCRI - Script\"},{\"t\":6,\"n\":\"DATA - \",\"c\":[{\"t\":3,\"n\":\"Value\"},{\"t\":5,\"n\":\"Weight\"}]},{\"t\":3,\"n\":\"SOUL - Contained Soul\"},{\"t\":3,\"n\":\"SLCP - Maximum Capacity\"}]},{\"t\":1,\"p\":1,\"n\":\"STAT - Static\",\"c\":[{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"},{\"t\":5,\"p\":1,\"n\":\"MODB - Bound Radius\"},{\"t\":11,\"p\":1,\"n\":\"MODT - Texture Files Hashes\"}]}]},{\"t\":1,\"p\":1,\"n\":\"TREE - Tree\",\"c\":[{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"},{\"t\":5,\"p\":1,\"n\":\"MODB - Bound Radius\"},{\"t\":11,\"p\":1,\"n\":\"MODT - Texture Files Hashes\"}]},{\"t\":2,\"p\":1,\"n\":\"ICON - Icon filename\"},{\"t\":7,\"n\":\"SNAM - SpeedTree Seeds\",\"c\":[{\"t\":3,\"n\":\"SpeedTree Seed\"}]},{\"t\":6,\"n\":\"CNAM - Tree Data\",\"c\":[{\"t\":5,\"n\":\"Leaf Curvature\"},{\"t\":5,\"n\":\"Minimum Leaf Angle\"},{\"t\":5,\"n\":\"Maximum Leaf Angle\"},{\"t\":5,\"n\":\"Branch Dimming Value\"},{\"t\":5,\"n\":\"Leaf Dimming Value\"},{\"t\":3,\"n\":\"Shadow Radius\"},{\"t\":5,\"n\":\"Rock Speed\"},{\"t\":5,\"n\":\"Rustle Speed\"}]},{\"t\":6,\"n\":\"BNAM - Billboard Dimensions\",\"c\":[{\"t\":5,\"n\":\"Width\"},{\"t\":5,\"n\":\"Height\"}]}]},{\"t\":1,\"p\":1,\"n\":\"WEAP - Weapon\",\"c\":[{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"n\":\"FULL - Name\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"},{\"t\":5,\"p\":1,\"n\":\"MODB - Bound Radius\"},{\"t\":11,\"p\":1,\"n\":\"MODT - Texture Files Hashes\"}]},{\"t\":2,\"p\":1,\"n\":\"ICON - Icon filename\"},{\"t\":3,\"n\":\"SCRI - Script\"},{\"t\":3,\"n\":\"ENAM - Enchantment\"},{\"t\":3,\"n\":\"ANAM - Enchantment Points\"},{\"t\":6,\"n\":\"DATA - \",\"c\":[{\"t\":3,\"n\":\"Type\"},{\"t\":5,\"n\":\"Speed\"},{\"t\":5,\"n\":\"Reach\"},{\"t\":3,\"n\":\"Flags\"},{\"t\":3,\"n\":\"Value\"},{\"t\":3,\"n\":\"Health\"},{\"t\":5,\"n\":\"Weight\"},{\"t\":3,\"n\":\"Damage\"}]}]},{\"t\":1,\"p\":1,\"n\":\"ACTI - Activator\",\"c\":[{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"n\":\"FULL - Name\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"},{\"t\":5,\"p\":1,\"n\":\"MODB - Bound Radius\"},{\"t\":11,\"p\":1,\"n\":\"MODT - Texture Files Hashes\"}]},{\"t\":3,\"n\":\"SCRI - Script\"},{\"t\":3,\"n\":\"SNAM - Sound\"}]}]},\"name\":\"Bash.Graphics\",\"hash\":\"655B6D00\",\"color\":255}"
  },
  {
    "path": "frontend/settings/Oblivion/Bash.Hair.json",
    "content": "{\"records\":\"RACE\",\"description\":\"Hair tag from Wrye Bash.\\r\\n\\r\\nUsed when the mod adds hairs to races.\",\"tree\":{\"records\":[{\"t\":1,\"p\":1,\"n\":\"RACE - Race\",\"c\":[{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"n\":\"FULL - Name\"},{\"t\":2,\"n\":\"DESC - Description\"},{\"t\":8,\"n\":\"Spells\",\"c\":[{\"t\":3,\"n\":\"SPLO - Spell\"}]},{\"t\":8,\"n\":\"Relations\",\"c\":[{\"t\":6,\"n\":\"XNAM - Relation\",\"c\":[{\"t\":3,\"n\":\"Faction\"},{\"t\":3,\"n\":\"Modifier\"}]}]},{\"t\":6,\"n\":\"DATA - \",\"c\":[{\"t\":7,\"n\":\"Skill Boosts\",\"c\":[{\"t\":6,\"n\":\"Skill Boost\",\"c\":[{\"t\":3,\"n\":\"Skill\"},{\"t\":3,\"n\":\"Boost\"}]}]},{\"t\":11,\"n\":\"Unused\"},{\"t\":5,\"n\":\"Male Height\"},{\"t\":5,\"n\":\"Female Height\"},{\"t\":5,\"n\":\"Male Weight\"},{\"t\":5,\"n\":\"Female Weight\"},{\"t\":3,\"n\":\"Flags\"}]},{\"t\":6,\"n\":\"VNAM - Voice\",\"c\":[{\"t\":3,\"n\":\"Male\"},{\"t\":3,\"n\":\"Female\"}]},{\"t\":6,\"n\":\"DNAM - Default Hair\",\"c\":[{\"t\":3,\"n\":\"Male\"},{\"t\":3,\"n\":\"Female\"}]},{\"t\":3,\"n\":\"CNAM - Default Hair Color\"},{\"t\":5,\"n\":\"PNAM - FaceGen - Main clamp\"},{\"t\":5,\"n\":\"UNAM - FaceGen - Face clamp\"},{\"t\":6,\"n\":\"ATTR - Base Attributes\",\"c\":[{\"t\":6,\"n\":\"Male\",\"c\":[{\"t\":3,\"n\":\"Strength\"},{\"t\":3,\"n\":\"Intelligence\"},{\"t\":3,\"n\":\"Willpower\"},{\"t\":3,\"n\":\"Agility\"},{\"t\":3,\"n\":\"Speed\"},{\"t\":3,\"n\":\"Endurance\"},{\"t\":3,\"n\":\"Personality\"},{\"t\":3,\"n\":\"Luck\"}]},{\"t\":6,\"n\":\"Female\",\"c\":[{\"t\":3,\"n\":\"Strength\"},{\"t\":3,\"n\":\"Intelligence\"},{\"t\":3,\"n\":\"Willpower\"},{\"t\":3,\"n\":\"Agility\"},{\"t\":3,\"n\":\"Speed\"},{\"t\":3,\"n\":\"Endurance\"},{\"t\":3,\"n\":\"Personality\"},{\"t\":3,\"n\":\"Luck\"}]}]},{\"t\":6,\"n\":\"Face Data\",\"c\":[{\"n\":\"NAM0 - Face Data Marker\"},{\"t\":10,\"n\":\"Parts\",\"c\":[{\"t\":6,\"n\":\"Part\",\"c\":[{\"t\":3,\"n\":\"INDX - Index\"},{\"t\":6,\"n\":\"Model\",\"c\":[{\"t\":2,\"n\":\"MODL - Model Filename\"},{\"t\":5,\"n\":\"MODB - Bound Radius\"},{\"t\":11,\"n\":\"MODT - Texture Files Hashes\"}]},{\"t\":2,\"n\":\"ICON - Icon filename\"}]}]}]},{\"n\":\"NAM1 - Body Data Marker\"},{\"t\":6,\"n\":\"Male Body Data\",\"c\":[{\"n\":\"MNAM - Male Body Data Marker\"},{\"t\":6,\"n\":\"Model\",\"c\":[{\"t\":2,\"n\":\"MODL - Model Filename\"},{\"t\":5,\"n\":\"MODB - Bound Radius\"},{\"t\":11,\"n\":\"MODT - Texture Files Hashes\"}]},{\"t\":10,\"n\":\"Parts\",\"c\":[{\"t\":6,\"n\":\"Part\",\"c\":[{\"t\":3,\"n\":\"INDX - Index\"},{\"t\":2,\"n\":\"ICON - Icon filename\"}]}]}]},{\"t\":6,\"n\":\"Female Body Data\",\"c\":[{\"n\":\"FNAM - Female Body Data Marker\"},{\"t\":6,\"n\":\"Model\",\"c\":[{\"t\":2,\"n\":\"MODL - Model Filename\"},{\"t\":5,\"n\":\"MODB - Bound Radius\"},{\"t\":11,\"n\":\"MODT - Texture Files Hashes\"}]},{\"t\":10,\"n\":\"Parts\",\"c\":[{\"t\":6,\"n\":\"Part\",\"c\":[{\"t\":3,\"n\":\"INDX - Index\"},{\"t\":2,\"n\":\"ICON - Icon filename\"}]}]}]},{\"t\":7,\"p\":1,\"n\":\"HNAM - Hairs\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Hair\"}]},{\"t\":7,\"n\":\"ENAM - Eyes\",\"c\":[{\"t\":3,\"n\":\"Eye\"}]},{\"t\":6,\"n\":\"FaceGen Data\",\"c\":[{\"t\":11,\"n\":\"FGGS - FaceGen Geometry-Symmetric\"},{\"t\":11,\"n\":\"FGGA - FaceGen Geometry-Asymmetric\"},{\"t\":11,\"n\":\"FGTS - FaceGen Texture-Symmetric\"}]},{\"t\":11,\"n\":\"SNAM - Unknown\"}]}]},\"name\":\"Bash.Hair\",\"hash\":\"3E90E02A\",\"color\":255}"
  },
  {
    "path": "frontend/settings/Oblivion/Bash.Invent.json",
    "content": "{\"records\":\"CREA,NPC_,CONT\",\"description\":\"Invent tag from Wrye Bash.\\r\\n\\r\\nUsed when the mod changes inventories.\",\"tree\":{\"records\":[{\"t\":1,\"p\":1,\"n\":\"CREA - Creature\",\"c\":[{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"n\":\"FULL - Name\"},{\"t\":6,\"n\":\"Model\",\"c\":[{\"t\":2,\"n\":\"MODL - Model Filename\"},{\"t\":5,\"n\":\"MODB - Bound Radius\"},{\"t\":11,\"n\":\"MODT - Texture Files Hashes\"}]},{\"t\":8,\"p\":1,\"n\":\"Items\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"CNTO - Item\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Item\"},{\"t\":3,\"p\":1,\"n\":\"Count\"}]}]},{\"t\":8,\"n\":\"Spells\",\"c\":[{\"t\":3,\"n\":\"SPLO - Spell\"}]},{\"t\":7,\"n\":\"NIFZ - Models\",\"c\":[{\"t\":2,\"n\":\"Model\"}]},{\"t\":11,\"n\":\"NIFT - Texture Files Hashes\"},{\"t\":6,\"n\":\"ACBS - Configuration\",\"c\":[{\"t\":3,\"n\":\"Flags\"},{\"t\":3,\"n\":\"Base spell points\"},{\"t\":3,\"n\":\"Fatigue\"},{\"t\":3,\"n\":\"Barter gold\"},{\"t\":3,\"n\":\"Level (offset)\"},{\"t\":3,\"n\":\"Calc min\"},{\"t\":3,\"n\":\"Calc max\"}]},{\"t\":8,\"n\":\"Factions\",\"c\":[{\"t\":6,\"n\":\"SNAM - Faction\",\"c\":[{\"t\":3,\"n\":\"Faction\"},{\"t\":3,\"n\":\"Rank\"},{\"t\":11,\"n\":\"Unused\"}]}]},{\"t\":3,\"n\":\"INAM - Death item\"},{\"t\":3,\"n\":\"SCRI - Script\"},{\"t\":6,\"n\":\"AIDT - AI Data\",\"c\":[{\"t\":3,\"n\":\"Aggression\"},{\"t\":3,\"n\":\"Confidence\"},{\"t\":3,\"n\":\"Energy Level\"},{\"t\":3,\"n\":\"Responsibility\"},{\"t\":3,\"n\":\"Buys\\/Sells and Services\"},{\"t\":3,\"n\":\"Teaches\"},{\"t\":3,\"n\":\"Maximum training level\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":8,\"n\":\"AI Packages\",\"c\":[{\"t\":3,\"n\":\"PKID - AI Package\"}]},{\"t\":7,\"n\":\"KFFZ - Animations\",\"c\":[{\"t\":2,\"n\":\"Animation\"}]},{\"t\":6,\"n\":\"DATA - Creature Data\",\"c\":[{\"t\":3,\"n\":\"Type\"},{\"t\":3,\"n\":\"Combat Skill\"},{\"t\":3,\"n\":\"Magic Skill\"},{\"t\":3,\"n\":\"Stealth Skill\"},{\"t\":3,\"n\":\"Soul\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":3,\"n\":\"Health\"},{\"t\":3,\"n\":\"Attack Damage\"},{\"t\":3,\"n\":\"Strength\"},{\"t\":3,\"n\":\"Intelligence\"},{\"t\":3,\"n\":\"Willpower\"},{\"t\":3,\"n\":\"Agility\"},{\"t\":3,\"n\":\"Speed\"},{\"t\":3,\"n\":\"Endurance\"},{\"t\":3,\"n\":\"Personality\"},{\"t\":3,\"n\":\"Luck\"}]},{\"t\":3,\"n\":\"RNAM - Attack reach\"},{\"t\":3,\"n\":\"ZNAM - Combat Style\"},{\"t\":5,\"n\":\"TNAM - Turning Speed\"},{\"t\":5,\"n\":\"BNAM - Base Scale\"},{\"t\":5,\"n\":\"WNAM - Foot Weight\"},{\"t\":2,\"n\":\"NAM0 - Blood Spray\"},{\"t\":2,\"n\":\"NAM1 - Blood Decal\"},{\"t\":3,\"n\":\"CSCR - Inherits Sounds from\"},{\"t\":10,\"n\":\"Sound Types\",\"c\":[{\"t\":6,\"n\":\"Sound Type\",\"c\":[{\"t\":3,\"n\":\"CSDT - Type\"},{\"t\":10,\"n\":\"Sounds\",\"c\":[{\"t\":6,\"n\":\"Sound\",\"c\":[{\"t\":3,\"n\":\"CSDI - Sound\"},{\"t\":3,\"n\":\"CSDC - Sound Chance\"}]}]}]}]}]},{\"t\":1,\"p\":1,\"n\":\"NPC_ - Non-Player Character\",\"c\":[{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"n\":\"FULL - Name\"},{\"t\":6,\"n\":\"Model\",\"c\":[{\"t\":2,\"n\":\"MODL - Model Filename\"},{\"t\":5,\"n\":\"MODB - Bound Radius\"},{\"t\":11,\"n\":\"MODT - Texture Files Hashes\"}]},{\"t\":6,\"n\":\"ACBS - Configuration\",\"c\":[{\"t\":3,\"n\":\"Flags\"},{\"t\":3,\"n\":\"Base spell points\"},{\"t\":3,\"n\":\"Fatigue\"},{\"t\":3,\"n\":\"Barter gold\"},{\"t\":3,\"n\":\"Level (offset)\"},{\"t\":3,\"n\":\"Calc min\"},{\"t\":3,\"n\":\"Calc max\"}]},{\"t\":8,\"n\":\"Factions\",\"c\":[{\"t\":6,\"n\":\"SNAM - Faction\",\"c\":[{\"t\":3,\"n\":\"Faction\"},{\"t\":3,\"n\":\"Rank\"},{\"t\":11,\"n\":\"Unused\"}]}]},{\"t\":3,\"n\":\"INAM - Death item\"},{\"t\":3,\"n\":\"RNAM - Race\"},{\"t\":8,\"p\":1,\"n\":\"Items\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"CNTO - Item\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Item\"},{\"t\":3,\"p\":1,\"n\":\"Count\"}]}]},{\"t\":8,\"n\":\"Spells\",\"c\":[{\"t\":3,\"n\":\"SPLO - Spell\"}]},{\"t\":3,\"n\":\"SCRI - Script\"},{\"t\":6,\"n\":\"AIDT - AI Data\",\"c\":[{\"t\":3,\"n\":\"Aggression\"},{\"t\":3,\"n\":\"Confidence\"},{\"t\":3,\"n\":\"Energy Level\"},{\"t\":3,\"n\":\"Responsibility\"},{\"t\":3,\"n\":\"Buys\\/Sells and Services\"},{\"t\":3,\"n\":\"Teaches\"},{\"t\":3,\"n\":\"Maximum training level\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":8,\"n\":\"AI Packages\",\"c\":[{\"t\":3,\"n\":\"PKID - AI Package\"}]},{\"t\":7,\"n\":\"KFFZ - Animations\",\"c\":[{\"t\":2,\"n\":\"Animation\"}]},{\"t\":3,\"n\":\"CNAM - Class\"},{\"t\":6,\"n\":\"DATA - Stats\",\"c\":[{\"t\":3,\"n\":\"Armorer\"},{\"t\":3,\"n\":\"Athletics\"},{\"t\":3,\"n\":\"Blade\"},{\"t\":3,\"n\":\"Block\"},{\"t\":3,\"n\":\"Blunt\"},{\"t\":3,\"n\":\"Hand to Hand\"},{\"t\":3,\"n\":\"Heavy Armor\"},{\"t\":3,\"n\":\"Alchemy\"},{\"t\":3,\"n\":\"Alteration\"},{\"t\":3,\"n\":\"Conjuration\"},{\"t\":3,\"n\":\"Destruction\"},{\"t\":3,\"n\":\"Illusion\"},{\"t\":3,\"n\":\"Mysticism\"},{\"t\":3,\"n\":\"Restoration\"},{\"t\":3,\"n\":\"Acrobatics\"},{\"t\":3,\"n\":\"Light Armor\"},{\"t\":3,\"n\":\"Marksman\"},{\"t\":3,\"n\":\"Mercantile\"},{\"t\":3,\"n\":\"Security\"},{\"t\":3,\"n\":\"Sneak\"},{\"t\":3,\"n\":\"Speechcraft\"},{\"t\":3,\"n\":\"Health\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":3,\"n\":\"Strength\"},{\"t\":3,\"n\":\"Intelligence\"},{\"t\":3,\"n\":\"Willpower\"},{\"t\":3,\"n\":\"Agility\"},{\"t\":3,\"n\":\"Speed\"},{\"t\":3,\"n\":\"Endurance\"},{\"t\":3,\"n\":\"Personality\"},{\"t\":3,\"n\":\"Luck\"}]},{\"t\":3,\"n\":\"HNAM - Hair\"},{\"t\":5,\"n\":\"LNAM - Hair length\"},{\"t\":7,\"n\":\"ENAM - Eyes\",\"c\":[{\"t\":3,\"n\":\"Eyes\"}]},{\"t\":6,\"n\":\"HCLR - Hair color\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":3,\"n\":\"ZNAM - Combat Style\"},{\"t\":6,\"n\":\"FaceGen Data\",\"c\":[{\"t\":11,\"n\":\"FGGS - FaceGen Geometry-Symmetric\"},{\"t\":11,\"n\":\"FGGA - FaceGen Geometry-Asymmetric\"},{\"t\":11,\"n\":\"FGTS - FaceGen Texture-Symmetric\"}]},{\"t\":11,\"n\":\"FNAM - Unknown\"}]},{\"t\":1,\"p\":1,\"n\":\"CONT - Container\",\"c\":[{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"n\":\"FULL - Name\"},{\"t\":6,\"n\":\"Model\",\"c\":[{\"t\":2,\"n\":\"MODL - Model Filename\"},{\"t\":5,\"n\":\"MODB - Bound Radius\"},{\"t\":11,\"n\":\"MODT - Texture Files Hashes\"}]},{\"t\":3,\"n\":\"SCRI - Script\"},{\"t\":8,\"p\":1,\"n\":\"Items\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"CNTO - Item\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Item\"},{\"t\":3,\"p\":1,\"n\":\"Count\"}]}]},{\"t\":6,\"n\":\"DATA - \",\"c\":[{\"t\":3,\"n\":\"Flags\"},{\"t\":5,\"n\":\"Weight\"}]},{\"t\":3,\"n\":\"SNAM - Open sound\"},{\"t\":3,\"n\":\"QNAM - Close sound\"}]}]},\"name\":\"Bash.Invent\",\"hash\":\"7774E3B4\",\"color\":255}"
  },
  {
    "path": "frontend/settings/Oblivion/Bash.Lev.json",
    "content": "{\"records\":\"LVLC,LVSP,LVLI\",\"description\":\"Base setting for Wrye Bash's leveled list handling.\\r\\n\\r\\nWhen used, leveled list entries will be merged.\",\"tree\":{\"records\":[{\"t\":1,\"p\":1,\"n\":\"LVLC - Leveled Creature\",\"c\":[{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":3,\"n\":\"LVLD - Chance none\"},{\"t\":3,\"n\":\"LVLF - Flags\"},{\"t\":8,\"p\":1,\"n\":\"Leveled List Entries\",\"c\":[{\"t\":6,\"s\":1,\"p\":1,\"n\":\"LVLO - Leveled List Entry\",\"c\":[{\"t\":3,\"n\":\"Level\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":3,\"n\":\"Reference\"},{\"t\":3,\"n\":\"Count\"}]}]},{\"t\":3,\"n\":\"SCRI - Script\"},{\"t\":3,\"n\":\"TNAM - Creature template\"}]},{\"t\":1,\"p\":1,\"n\":\"LVSP - Leveled Spell\",\"c\":[{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":3,\"n\":\"LVLD - Chance none\"},{\"t\":3,\"n\":\"LVLF - Flags\"},{\"t\":8,\"p\":1,\"n\":\"Leveled List Entries\",\"c\":[{\"t\":6,\"s\":1,\"p\":1,\"n\":\"LVLO - Leveled List Entry\",\"c\":[{\"t\":3,\"n\":\"Level\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":3,\"n\":\"Reference\"},{\"t\":3,\"n\":\"Count\"}]}]}]},{\"t\":1,\"p\":1,\"n\":\"LVLI - Leveled Item\",\"c\":[{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":3,\"n\":\"LVLD - Chance none\"},{\"t\":3,\"n\":\"LVLF - Flags\"},{\"t\":8,\"p\":1,\"n\":\"Leveled List Entries\",\"c\":[{\"t\":6,\"s\":1,\"p\":1,\"n\":\"LVLO - Leveled List Entry\",\"c\":[{\"t\":3,\"n\":\"Level\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":3,\"n\":\"Reference\"},{\"t\":3,\"n\":\"Count\"}]}]},{\"t\":11,\"n\":\"DATA - Unused\"}]}]},\"name\":\"Bash.Lev\",\"hash\":\"1AEC5FC1\",\"color\":255}"
  },
  {
    "path": "frontend/settings/Oblivion/Bash.NPC.Class.json",
    "content": "{\"records\":\"NPC_\",\"description\":\"NPC.Class tag from Wrye Bash.\\r\\n\\r\\nUsed when the mod changes the classes of NPCs.\",\"tree\":{\"records\":[{\"t\":1,\"p\":1,\"n\":\"NPC_ - Non-Player Character\",\"c\":[{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"n\":\"FULL - Name\"},{\"t\":6,\"n\":\"Model\",\"c\":[{\"t\":2,\"n\":\"MODL - Model Filename\"},{\"t\":5,\"n\":\"MODB - Bound Radius\"},{\"t\":11,\"n\":\"MODT - Texture Files Hashes\"}]},{\"t\":6,\"n\":\"ACBS - Configuration\",\"c\":[{\"t\":3,\"n\":\"Flags\"},{\"t\":3,\"n\":\"Base spell points\"},{\"t\":3,\"n\":\"Fatigue\"},{\"t\":3,\"n\":\"Barter gold\"},{\"t\":3,\"n\":\"Level (offset)\"},{\"t\":3,\"n\":\"Calc min\"},{\"t\":3,\"n\":\"Calc max\"}]},{\"t\":8,\"n\":\"Factions\",\"c\":[{\"t\":6,\"n\":\"SNAM - Faction\",\"c\":[{\"t\":3,\"n\":\"Faction\"},{\"t\":3,\"n\":\"Rank\"},{\"t\":11,\"n\":\"Unused\"}]}]},{\"t\":3,\"n\":\"INAM - Death item\"},{\"t\":3,\"n\":\"RNAM - Race\"},{\"t\":8,\"n\":\"Items\",\"c\":[{\"t\":6,\"n\":\"CNTO - Item\",\"c\":[{\"t\":3,\"n\":\"Item\"},{\"t\":3,\"n\":\"Count\"}]}]},{\"t\":8,\"n\":\"Spells\",\"c\":[{\"t\":3,\"n\":\"SPLO - Spell\"}]},{\"t\":3,\"n\":\"SCRI - Script\"},{\"t\":6,\"n\":\"AIDT - AI Data\",\"c\":[{\"t\":3,\"n\":\"Aggression\"},{\"t\":3,\"n\":\"Confidence\"},{\"t\":3,\"n\":\"Energy Level\"},{\"t\":3,\"n\":\"Responsibility\"},{\"t\":3,\"n\":\"Buys\\/Sells and Services\"},{\"t\":3,\"n\":\"Teaches\"},{\"t\":3,\"n\":\"Maximum training level\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":8,\"n\":\"AI Packages\",\"c\":[{\"t\":3,\"n\":\"PKID - AI Package\"}]},{\"t\":7,\"n\":\"KFFZ - Animations\",\"c\":[{\"t\":2,\"n\":\"Animation\"}]},{\"t\":3,\"p\":1,\"n\":\"CNAM - Class\"},{\"t\":6,\"n\":\"DATA - Stats\",\"c\":[{\"t\":3,\"n\":\"Armorer\"},{\"t\":3,\"n\":\"Athletics\"},{\"t\":3,\"n\":\"Blade\"},{\"t\":3,\"n\":\"Block\"},{\"t\":3,\"n\":\"Blunt\"},{\"t\":3,\"n\":\"Hand to Hand\"},{\"t\":3,\"n\":\"Heavy Armor\"},{\"t\":3,\"n\":\"Alchemy\"},{\"t\":3,\"n\":\"Alteration\"},{\"t\":3,\"n\":\"Conjuration\"},{\"t\":3,\"n\":\"Destruction\"},{\"t\":3,\"n\":\"Illusion\"},{\"t\":3,\"n\":\"Mysticism\"},{\"t\":3,\"n\":\"Restoration\"},{\"t\":3,\"n\":\"Acrobatics\"},{\"t\":3,\"n\":\"Light Armor\"},{\"t\":3,\"n\":\"Marksman\"},{\"t\":3,\"n\":\"Mercantile\"},{\"t\":3,\"n\":\"Security\"},{\"t\":3,\"n\":\"Sneak\"},{\"t\":3,\"n\":\"Speechcraft\"},{\"t\":3,\"n\":\"Health\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":3,\"n\":\"Strength\"},{\"t\":3,\"n\":\"Intelligence\"},{\"t\":3,\"n\":\"Willpower\"},{\"t\":3,\"n\":\"Agility\"},{\"t\":3,\"n\":\"Speed\"},{\"t\":3,\"n\":\"Endurance\"},{\"t\":3,\"n\":\"Personality\"},{\"t\":3,\"n\":\"Luck\"}]},{\"t\":3,\"n\":\"HNAM - Hair\"},{\"t\":5,\"n\":\"LNAM - Hair length\"},{\"t\":7,\"n\":\"ENAM - Eyes\",\"c\":[{\"t\":3,\"n\":\"Eyes\"}]},{\"t\":6,\"n\":\"HCLR - Hair color\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":3,\"n\":\"ZNAM - Combat Style\"},{\"t\":6,\"n\":\"FaceGen Data\",\"c\":[{\"t\":11,\"n\":\"FGGS - FaceGen Geometry-Symmetric\"},{\"t\":11,\"n\":\"FGGA - FaceGen Geometry-Asymmetric\"},{\"t\":11,\"n\":\"FGTS - FaceGen Texture-Symmetric\"}]},{\"t\":11,\"n\":\"FNAM - Unknown\"}]}]},\"name\":\"Bash.NPC.Class\",\"hash\":\"C435CA64\",\"color\":255}"
  },
  {
    "path": "frontend/settings/Oblivion/Bash.NPC.Race.json",
    "content": "{\"records\":\"NPC_\",\"description\":\"NPC.Race tag from Wrye Bash.\\r\\n\\r\\nUsed when the mod modifies NPC races.\",\"tree\":{\"records\":[{\"t\":1,\"p\":1,\"n\":\"NPC_ - Non-Player Character\",\"c\":[{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"n\":\"FULL - Name\"},{\"t\":6,\"n\":\"Model\",\"c\":[{\"t\":2,\"n\":\"MODL - Model Filename\"},{\"t\":5,\"n\":\"MODB - Bound Radius\"},{\"t\":11,\"n\":\"MODT - Texture Files Hashes\"}]},{\"t\":6,\"n\":\"ACBS - Configuration\",\"c\":[{\"t\":3,\"n\":\"Flags\"},{\"t\":3,\"n\":\"Base spell points\"},{\"t\":3,\"n\":\"Fatigue\"},{\"t\":3,\"n\":\"Barter gold\"},{\"t\":3,\"n\":\"Level (offset)\"},{\"t\":3,\"n\":\"Calc min\"},{\"t\":3,\"n\":\"Calc max\"}]},{\"t\":8,\"n\":\"Factions\",\"c\":[{\"t\":6,\"n\":\"SNAM - Faction\",\"c\":[{\"t\":3,\"n\":\"Faction\"},{\"t\":3,\"n\":\"Rank\"},{\"t\":11,\"n\":\"Unused\"}]}]},{\"t\":3,\"n\":\"INAM - Death item\"},{\"t\":3,\"p\":1,\"n\":\"RNAM - Race\"},{\"t\":8,\"n\":\"Items\",\"c\":[{\"t\":6,\"n\":\"CNTO - Item\",\"c\":[{\"t\":3,\"n\":\"Item\"},{\"t\":3,\"n\":\"Count\"}]}]},{\"t\":8,\"n\":\"Spells\",\"c\":[{\"t\":3,\"n\":\"SPLO - Spell\"}]},{\"t\":3,\"n\":\"SCRI - Script\"},{\"t\":6,\"n\":\"AIDT - AI Data\",\"c\":[{\"t\":3,\"n\":\"Aggression\"},{\"t\":3,\"n\":\"Confidence\"},{\"t\":3,\"n\":\"Energy Level\"},{\"t\":3,\"n\":\"Responsibility\"},{\"t\":3,\"n\":\"Buys\\/Sells and Services\"},{\"t\":3,\"n\":\"Teaches\"},{\"t\":3,\"n\":\"Maximum training level\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":8,\"n\":\"AI Packages\",\"c\":[{\"t\":3,\"n\":\"PKID - AI Package\"}]},{\"t\":7,\"n\":\"KFFZ - Animations\",\"c\":[{\"t\":2,\"n\":\"Animation\"}]},{\"t\":3,\"n\":\"CNAM - Class\"},{\"t\":6,\"n\":\"DATA - Stats\",\"c\":[{\"t\":3,\"n\":\"Armorer\"},{\"t\":3,\"n\":\"Athletics\"},{\"t\":3,\"n\":\"Blade\"},{\"t\":3,\"n\":\"Block\"},{\"t\":3,\"n\":\"Blunt\"},{\"t\":3,\"n\":\"Hand to Hand\"},{\"t\":3,\"n\":\"Heavy Armor\"},{\"t\":3,\"n\":\"Alchemy\"},{\"t\":3,\"n\":\"Alteration\"},{\"t\":3,\"n\":\"Conjuration\"},{\"t\":3,\"n\":\"Destruction\"},{\"t\":3,\"n\":\"Illusion\"},{\"t\":3,\"n\":\"Mysticism\"},{\"t\":3,\"n\":\"Restoration\"},{\"t\":3,\"n\":\"Acrobatics\"},{\"t\":3,\"n\":\"Light Armor\"},{\"t\":3,\"n\":\"Marksman\"},{\"t\":3,\"n\":\"Mercantile\"},{\"t\":3,\"n\":\"Security\"},{\"t\":3,\"n\":\"Sneak\"},{\"t\":3,\"n\":\"Speechcraft\"},{\"t\":3,\"n\":\"Health\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":3,\"n\":\"Strength\"},{\"t\":3,\"n\":\"Intelligence\"},{\"t\":3,\"n\":\"Willpower\"},{\"t\":3,\"n\":\"Agility\"},{\"t\":3,\"n\":\"Speed\"},{\"t\":3,\"n\":\"Endurance\"},{\"t\":3,\"n\":\"Personality\"},{\"t\":3,\"n\":\"Luck\"}]},{\"t\":3,\"n\":\"HNAM - Hair\"},{\"t\":5,\"n\":\"LNAM - Hair length\"},{\"t\":7,\"n\":\"ENAM - Eyes\",\"c\":[{\"t\":3,\"n\":\"Eyes\"}]},{\"t\":6,\"n\":\"HCLR - Hair color\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":3,\"n\":\"ZNAM - Combat Style\"},{\"t\":6,\"n\":\"FaceGen Data\",\"c\":[{\"t\":11,\"n\":\"FGGS - FaceGen Geometry-Symmetric\"},{\"t\":11,\"n\":\"FGGA - FaceGen Geometry-Asymmetric\"},{\"t\":11,\"n\":\"FGTS - FaceGen Texture-Symmetric\"}]},{\"t\":11,\"n\":\"FNAM - Unknown\"}]}]},\"name\":\"Bash.NPC.Race\",\"hash\":\"971AC450\",\"color\":255}"
  },
  {
    "path": "frontend/settings/Oblivion/Bash.Names.json",
    "content": "{\"records\":\"ALCH,AMMO,APPA,ARMO,BOOK,BSGN,CELL,CLAS,CLOT,CONT,CREA,DIAL,DOOR,ENCH,EYES,FACT,FLOR,FURN,HAIR,INGR,KEYM,LIGH,MGEF,MISC,NPC_,QUST,RACE,SGST,SLGM,SPEL,WEAP,WRLD,ACTI\",\"description\":\"Names tag from Wrye Bash.\\r\\n\\r\\nUsed when the mod changes the names of things.\",\"tree\":{\"records\":[{\"t\":1,\"p\":1,\"n\":\"ALCH - Potion\",\"c\":[{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"n\":\"OBME - Oblivion Magic Extender\",\"c\":[{\"t\":3,\"n\":\"Record Version\"},{\"t\":6,\"n\":\"OBME Version\",\"c\":[{\"t\":3,\"n\":\"Beta\"},{\"t\":3,\"n\":\"Minor\"},{\"t\":3,\"n\":\"Major\"}]},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":6,\"n\":\"Model\",\"c\":[{\"t\":2,\"n\":\"MODL - Model Filename\"},{\"t\":5,\"n\":\"MODB - Bound Radius\"},{\"t\":11,\"n\":\"MODT - Texture Files Hashes\"}]},{\"t\":2,\"n\":\"ICON - Icon filename\"},{\"t\":3,\"n\":\"SCRI - Script\"},{\"t\":5,\"n\":\"DATA - Weight\"},{\"t\":6,\"n\":\"ENIT - \",\"c\":[{\"t\":3,\"n\":\"Value\"},{\"t\":3,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":8,\"n\":\"Effects\",\"c\":[{\"t\":6,\"n\":\"Effect\",\"c\":[{\"t\":3,\"n\":\"EFID - Magic effect name\"},{\"t\":6,\"n\":\"EFIT - \",\"c\":[{\"t\":3,\"n\":\"Magic effect name\"},{\"t\":3,\"n\":\"Magnitude\"},{\"t\":3,\"n\":\"Area\"},{\"t\":3,\"n\":\"Duration\"},{\"t\":3,\"n\":\"Type\"},{\"t\":3,\"n\":\"Actor Value\"}]},{\"t\":6,\"n\":\"Script effect\",\"c\":[{\"t\":6,\"n\":\"SCIT - Script effect data\",\"c\":[{\"t\":3,\"n\":\"Script effect\"},{\"t\":3,\"n\":\"Magic school\"},{\"t\":3,\"n\":\"Visual effect name\"},{\"t\":3,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":2,\"n\":\"FULL - Name\"}]}]},{\"t\":6,\"n\":\"Effects\",\"c\":[{\"t\":8,\"n\":\"Effects\",\"c\":[{\"t\":6,\"n\":\"Effect\",\"c\":[{\"t\":6,\"n\":\"EFME - Oblivion Magic Extender\",\"c\":[{\"t\":3,\"n\":\"Record Version\"},{\"t\":6,\"n\":\"OBME Version\",\"c\":[{\"t\":3,\"n\":\"Beta\"},{\"t\":3,\"n\":\"Minor\"},{\"t\":3,\"n\":\"Major\"}]},{\"t\":3,\"n\":\"EFIT Param Info\"},{\"t\":3,\"n\":\"EFIX Param Info\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":2,\"n\":\"EFID - Magic Effect Code\"},{\"t\":6,\"n\":\"EFIT - \",\"c\":[{\"t\":2,\"n\":\"Magic Effect Code\"},{\"t\":3,\"n\":\"Magnitude\"},{\"t\":3,\"n\":\"Area\"},{\"t\":3,\"n\":\"Duration\"},{\"t\":3,\"n\":\"Type\"},{\"t\":11,\"n\":\"Param #1 - Unknown Type\"},{\"t\":3,\"n\":\"Param #1 - FormID\"},{\"t\":2,\"n\":\"Param #1 - Magic Effect Code\"},{\"t\":3,\"n\":\"Param #1 - Actor Value\"}]},{\"t\":6,\"n\":\"Script effect\",\"c\":[{\"t\":6,\"n\":\"SCIT - Script effect data\",\"c\":[{\"t\":3,\"n\":\"Script effect\"},{\"t\":3,\"n\":\"Magic school\"},{\"t\":2,\"n\":\"Visual Effect Code\"},{\"t\":3,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":2,\"n\":\"FULL - Name\"}]},{\"t\":2,\"n\":\"EFII - Icon\"},{\"t\":6,\"n\":\"EFIX - \",\"c\":[{\"t\":3,\"n\":\"Override Mask\"},{\"t\":3,\"n\":\"Flags\"},{\"t\":5,\"n\":\"Base Cost\"},{\"t\":11,\"n\":\"Param #2 - Unknown Type\"},{\"t\":3,\"n\":\"Param #2 - FormID\"},{\"t\":2,\"n\":\"Param #2 - Magic Effect Code\"},{\"t\":3,\"n\":\"Param #2 - Actor Value\"}]}]}]},{\"n\":\"EFXX - Effects End Marker\"},{\"t\":2,\"n\":\"FULL - Name\"}]}]}]},{\"t\":1,\"p\":1,\"n\":\"AMMO - Ammunition\",\"c\":[{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":6,\"n\":\"Model\",\"c\":[{\"t\":2,\"n\":\"MODL - Model Filename\"},{\"t\":5,\"n\":\"MODB - Bound Radius\"},{\"t\":11,\"n\":\"MODT - Texture Files Hashes\"}]},{\"t\":2,\"n\":\"ICON - Icon filename\"},{\"t\":3,\"n\":\"ENAM - Enchantment\"},{\"t\":3,\"n\":\"ANAM - Enchantment Points\"},{\"t\":6,\"n\":\"DATA - \",\"c\":[{\"t\":5,\"n\":\"Speed\"},{\"t\":3,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":3,\"n\":\"Value\"},{\"t\":5,\"n\":\"Weight\"},{\"t\":3,\"n\":\"Damage\"}]}]},{\"t\":1,\"p\":1,\"n\":\"APPA - Alchemical Apparatus\",\"c\":[{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":6,\"n\":\"Model\",\"c\":[{\"t\":2,\"n\":\"MODL - Model Filename\"},{\"t\":5,\"n\":\"MODB - Bound Radius\"},{\"t\":11,\"n\":\"MODT - Texture Files Hashes\"}]},{\"t\":2,\"n\":\"ICON - Icon filename\"},{\"t\":3,\"n\":\"SCRI - Script\"},{\"t\":6,\"n\":\"DATA - \",\"c\":[{\"t\":3,\"n\":\"Type\"},{\"t\":3,\"n\":\"Value\"},{\"t\":5,\"n\":\"Weight\"},{\"t\":5,\"n\":\"Quality\"}]}]},{\"t\":1,\"p\":1,\"n\":\"ARMO - Armor\",\"c\":[{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":3,\"n\":\"SCRI - Script\"},{\"t\":3,\"n\":\"ENAM - Enchantment\"},{\"t\":3,\"n\":\"ANAM - Enchantment Points\"},{\"t\":6,\"n\":\"BMDT - \",\"c\":[{\"t\":3,\"n\":\"Biped Flags\"},{\"t\":3,\"n\":\"General Flags\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"n\":\"Male biped model\",\"c\":[{\"t\":2,\"n\":\"MODL - Model Filename\"},{\"t\":5,\"n\":\"MODB - Bound Radius\"},{\"t\":11,\"n\":\"MODT - Texture Files Hashes\"}]},{\"t\":6,\"n\":\"Male world model\",\"c\":[{\"t\":2,\"n\":\"MOD2 - Model Filename\"},{\"t\":5,\"n\":\"MO2B - Bound Radius\"},{\"t\":11,\"n\":\"MO2T - Texture Files Hashes\"}]},{\"t\":2,\"n\":\"ICON - Male icon filename\"},{\"t\":6,\"n\":\"Female biped model\",\"c\":[{\"t\":2,\"n\":\"MOD3 - Model Filename\"},{\"t\":5,\"n\":\"MO3B - Bound Radius\"},{\"t\":11,\"n\":\"MO3T - Texture Files Hashes\"}]},{\"t\":6,\"n\":\"Female world model\",\"c\":[{\"t\":2,\"n\":\"MOD4 - Model Filename\"},{\"t\":5,\"n\":\"MO4B - Bound Radius\"},{\"t\":11,\"n\":\"MO4T - Texture Files Hashes\"}]},{\"t\":2,\"n\":\"ICO2 - Female icon filename\"},{\"t\":6,\"n\":\"DATA - \",\"c\":[{\"t\":3,\"n\":\"Armor\"},{\"t\":3,\"n\":\"Value\"},{\"t\":3,\"n\":\"Health\"},{\"t\":5,\"n\":\"Weight\"}]}]},{\"t\":1,\"p\":1,\"n\":\"BOOK - Book\",\"c\":[{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":6,\"n\":\"Model\",\"c\":[{\"t\":2,\"n\":\"MODL - Model Filename\"},{\"t\":5,\"n\":\"MODB - Bound Radius\"},{\"t\":11,\"n\":\"MODT - Texture Files Hashes\"}]},{\"t\":2,\"n\":\"ICON - Icon filename\"},{\"t\":3,\"n\":\"SCRI - Script\"},{\"t\":3,\"n\":\"ENAM - Enchantment\"},{\"t\":3,\"n\":\"ANAM - Enchantment Points\"},{\"t\":2,\"n\":\"DESC - Description\"},{\"t\":6,\"n\":\"DATA - \",\"c\":[{\"t\":3,\"n\":\"Flags\"},{\"t\":3,\"n\":\"Teaches\"},{\"t\":3,\"n\":\"Value\"},{\"t\":5,\"n\":\"Weight\"}]}]},{\"t\":1,\"p\":1,\"n\":\"BSGN - Birthsign\",\"c\":[{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":2,\"n\":\"ICON - Icon filename\"},{\"t\":2,\"n\":\"DESC - Description\"},{\"t\":8,\"n\":\"Spells\",\"c\":[{\"t\":3,\"n\":\"SPLO - Spell\"}]}]},{\"t\":1,\"p\":1,\"n\":\"CELL - Cell\",\"c\":[{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":3,\"n\":\"DATA - Flags\"},{\"t\":6,\"n\":\"XCLC - Grid\",\"c\":[{\"t\":3,\"n\":\"X\"},{\"t\":3,\"n\":\"Y\"}]},{\"t\":6,\"n\":\"XCLL - Lighting\",\"c\":[{\"t\":6,\"n\":\"Ambient Color\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"n\":\"Directional Color\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"n\":\"Fog Color\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":5,\"n\":\"Fog Near\"},{\"t\":5,\"n\":\"Fog Far\"},{\"t\":3,\"n\":\"Directional Rotation XY\"},{\"t\":3,\"n\":\"Directional Rotation Z\"},{\"t\":5,\"n\":\"Directional Fade\"},{\"t\":5,\"n\":\"Fog Clip Dist\"}]},{\"t\":7,\"n\":\"XCLR - Regions\",\"c\":[{\"t\":3,\"n\":\"Region\"}]},{\"t\":3,\"n\":\"XCMT - Music\"},{\"t\":5,\"n\":\"XCLW - Water Height\"},{\"t\":3,\"n\":\"XCCM - Climate\"},{\"t\":3,\"n\":\"XCWT - Water\"},{\"t\":6,\"n\":\"Ownership\",\"c\":[{\"t\":3,\"n\":\"XOWN - Owner\"},{\"t\":3,\"n\":\"XRNK - Faction rank\"},{\"t\":3,\"n\":\"XGLB - Global variable\"}]}]},{\"t\":1,\"p\":1,\"n\":\"CLAS - Class\",\"c\":[{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":2,\"n\":\"DESC - Description\"},{\"t\":2,\"n\":\"ICON - Icon filename\"},{\"t\":6,\"n\":\"DATA - \",\"c\":[{\"t\":7,\"n\":\"Primary Attributes\",\"c\":[{\"t\":3,\"n\":\"Primary Attribute\"}]},{\"t\":3,\"n\":\"Specialization\"},{\"t\":7,\"n\":\"Major Skills\",\"c\":[{\"t\":3,\"n\":\"Major Skill\"}]},{\"t\":3,\"n\":\"Flags\"},{\"t\":3,\"n\":\"Buys\\/Sells and Services\"},{\"t\":3,\"n\":\"Teaches\"},{\"t\":3,\"n\":\"Maximum training level\"},{\"t\":3,\"n\":\"Unused\"}]}]},{\"t\":1,\"p\":1,\"n\":\"CLOT - Clothing\",\"c\":[{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":3,\"n\":\"SCRI - Script\"},{\"t\":3,\"n\":\"ENAM - Enchantment\"},{\"t\":3,\"n\":\"ANAM - Enchantment Points\"},{\"t\":6,\"n\":\"BMDT - \",\"c\":[{\"t\":3,\"n\":\"Biped Flags\"},{\"t\":3,\"n\":\"General Flags\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"n\":\"Male biped model\",\"c\":[{\"t\":2,\"n\":\"MODL - Model Filename\"},{\"t\":5,\"n\":\"MODB - Bound Radius\"},{\"t\":11,\"n\":\"MODT - Texture Files Hashes\"}]},{\"t\":6,\"n\":\"Male world model\",\"c\":[{\"t\":2,\"n\":\"MOD2 - Model Filename\"},{\"t\":5,\"n\":\"MO2B - Bound Radius\"},{\"t\":11,\"n\":\"MO2T - Texture Files Hashes\"}]},{\"t\":2,\"n\":\"ICON - Male icon filename\"},{\"t\":6,\"n\":\"Female biped model\",\"c\":[{\"t\":2,\"n\":\"MOD3 - Model Filename\"},{\"t\":5,\"n\":\"MO3B - Bound Radius\"},{\"t\":11,\"n\":\"MO3T - Texture Files Hashes\"}]},{\"t\":6,\"n\":\"Female world model\",\"c\":[{\"t\":2,\"n\":\"MOD4 - Model Filename\"},{\"t\":5,\"n\":\"MO4B - Bound Radius\"},{\"t\":11,\"n\":\"MO4T - Texture Files Hashes\"}]},{\"t\":2,\"n\":\"ICO2 - Female icon filename\"},{\"t\":6,\"n\":\"DATA - \",\"c\":[{\"t\":3,\"n\":\"Value\"},{\"t\":5,\"n\":\"Weight\"}]}]},{\"t\":1,\"p\":1,\"n\":\"CONT - Container\",\"c\":[{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":6,\"n\":\"Model\",\"c\":[{\"t\":2,\"n\":\"MODL - Model Filename\"},{\"t\":5,\"n\":\"MODB - Bound Radius\"},{\"t\":11,\"n\":\"MODT - Texture Files Hashes\"}]},{\"t\":3,\"n\":\"SCRI - Script\"},{\"t\":8,\"n\":\"Items\",\"c\":[{\"t\":6,\"n\":\"CNTO - Item\",\"c\":[{\"t\":3,\"n\":\"Item\"},{\"t\":3,\"n\":\"Count\"}]}]},{\"t\":6,\"n\":\"DATA - \",\"c\":[{\"t\":3,\"n\":\"Flags\"},{\"t\":5,\"n\":\"Weight\"}]},{\"t\":3,\"n\":\"SNAM - Open sound\"},{\"t\":3,\"n\":\"QNAM - Close sound\"}]},{\"t\":1,\"p\":1,\"n\":\"CREA - Creature\",\"c\":[{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":6,\"n\":\"Model\",\"c\":[{\"t\":2,\"n\":\"MODL - Model Filename\"},{\"t\":5,\"n\":\"MODB - Bound Radius\"},{\"t\":11,\"n\":\"MODT - Texture Files Hashes\"}]},{\"t\":8,\"n\":\"Items\",\"c\":[{\"t\":6,\"n\":\"CNTO - Item\",\"c\":[{\"t\":3,\"n\":\"Item\"},{\"t\":3,\"n\":\"Count\"}]}]},{\"t\":8,\"n\":\"Spells\",\"c\":[{\"t\":3,\"n\":\"SPLO - Spell\"}]},{\"t\":7,\"n\":\"NIFZ - Models\",\"c\":[{\"t\":2,\"n\":\"Model\"}]},{\"t\":11,\"n\":\"NIFT - Texture Files Hashes\"},{\"t\":6,\"n\":\"ACBS - Configuration\",\"c\":[{\"t\":3,\"n\":\"Flags\"},{\"t\":3,\"n\":\"Base spell points\"},{\"t\":3,\"n\":\"Fatigue\"},{\"t\":3,\"n\":\"Barter gold\"},{\"t\":3,\"n\":\"Level (offset)\"},{\"t\":3,\"n\":\"Calc min\"},{\"t\":3,\"n\":\"Calc max\"}]},{\"t\":8,\"n\":\"Factions\",\"c\":[{\"t\":6,\"n\":\"SNAM - Faction\",\"c\":[{\"t\":3,\"n\":\"Faction\"},{\"t\":3,\"n\":\"Rank\"},{\"t\":11,\"n\":\"Unused\"}]}]},{\"t\":3,\"n\":\"INAM - Death item\"},{\"t\":3,\"n\":\"SCRI - Script\"},{\"t\":6,\"n\":\"AIDT - AI Data\",\"c\":[{\"t\":3,\"n\":\"Aggression\"},{\"t\":3,\"n\":\"Confidence\"},{\"t\":3,\"n\":\"Energy Level\"},{\"t\":3,\"n\":\"Responsibility\"},{\"t\":3,\"n\":\"Buys\\/Sells and Services\"},{\"t\":3,\"n\":\"Teaches\"},{\"t\":3,\"n\":\"Maximum training level\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":8,\"n\":\"AI Packages\",\"c\":[{\"t\":3,\"n\":\"PKID - AI Package\"}]},{\"t\":7,\"n\":\"KFFZ - Animations\",\"c\":[{\"t\":2,\"n\":\"Animation\"}]},{\"t\":6,\"n\":\"DATA - Creature Data\",\"c\":[{\"t\":3,\"n\":\"Type\"},{\"t\":3,\"n\":\"Combat Skill\"},{\"t\":3,\"n\":\"Magic Skill\"},{\"t\":3,\"n\":\"Stealth Skill\"},{\"t\":3,\"n\":\"Soul\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":3,\"n\":\"Health\"},{\"t\":3,\"n\":\"Attack Damage\"},{\"t\":3,\"n\":\"Strength\"},{\"t\":3,\"n\":\"Intelligence\"},{\"t\":3,\"n\":\"Willpower\"},{\"t\":3,\"n\":\"Agility\"},{\"t\":3,\"n\":\"Speed\"},{\"t\":3,\"n\":\"Endurance\"},{\"t\":3,\"n\":\"Personality\"},{\"t\":3,\"n\":\"Luck\"}]},{\"t\":3,\"n\":\"RNAM - Attack reach\"},{\"t\":3,\"n\":\"ZNAM - Combat Style\"},{\"t\":5,\"n\":\"TNAM - Turning Speed\"},{\"t\":5,\"n\":\"BNAM - Base Scale\"},{\"t\":5,\"n\":\"WNAM - Foot Weight\"},{\"t\":2,\"n\":\"NAM0 - Blood Spray\"},{\"t\":2,\"n\":\"NAM1 - Blood Decal\"},{\"t\":3,\"n\":\"CSCR - Inherits Sounds from\"},{\"t\":10,\"n\":\"Sound Types\",\"c\":[{\"t\":6,\"n\":\"Sound Type\",\"c\":[{\"t\":3,\"n\":\"CSDT - Type\"},{\"t\":10,\"n\":\"Sounds\",\"c\":[{\"t\":6,\"n\":\"Sound\",\"c\":[{\"t\":3,\"n\":\"CSDI - Sound\"},{\"t\":3,\"n\":\"CSDC - Sound Chance\"}]}]}]}]}]},{\"t\":1,\"p\":1,\"n\":\"DIAL - Dialog Topic\",\"c\":[{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":8,\"n\":\"Quests\",\"c\":[{\"t\":3,\"n\":\"QSTI - Quest\"}]},{\"t\":8,\"n\":\"Quests?\",\"c\":[{\"t\":3,\"n\":\"QSTR - Quest?\"}]},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":3,\"n\":\"DATA - Type\"}]},{\"t\":1,\"p\":1,\"n\":\"DOOR - Door\",\"c\":[{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":6,\"n\":\"Model\",\"c\":[{\"t\":2,\"n\":\"MODL - Model Filename\"},{\"t\":5,\"n\":\"MODB - Bound Radius\"},{\"t\":11,\"n\":\"MODT - Texture Files Hashes\"}]},{\"t\":3,\"n\":\"SCRI - Script\"},{\"t\":3,\"n\":\"SNAM - Open sound\"},{\"t\":3,\"n\":\"ANAM - Close sound\"},{\"t\":3,\"n\":\"BNAM - Loop sound\"},{\"t\":3,\"n\":\"FNAM - Flags\"},{\"t\":8,\"n\":\"Random teleport destinations\",\"c\":[{\"t\":3,\"n\":\"TNAM - Destination\"}]}]},{\"t\":1,\"p\":1,\"n\":\"ENCH - Enchantment\",\"c\":[{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"n\":\"OBME - Oblivion Magic Extender\",\"c\":[{\"t\":3,\"n\":\"Record Version\"},{\"t\":6,\"n\":\"OBME Version\",\"c\":[{\"t\":3,\"n\":\"Beta\"},{\"t\":3,\"n\":\"Minor\"},{\"t\":3,\"n\":\"Major\"}]},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":6,\"n\":\"ENIT - \",\"c\":[{\"t\":3,\"n\":\"Type\"},{\"t\":3,\"n\":\"Charge Amount\"},{\"t\":3,\"n\":\"Enchant Cost\"},{\"t\":3,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":8,\"n\":\"Effects\",\"c\":[{\"t\":6,\"n\":\"Effect\",\"c\":[{\"t\":3,\"n\":\"EFID - Magic effect name\"},{\"t\":6,\"n\":\"EFIT - \",\"c\":[{\"t\":3,\"n\":\"Magic effect name\"},{\"t\":3,\"n\":\"Magnitude\"},{\"t\":3,\"n\":\"Area\"},{\"t\":3,\"n\":\"Duration\"},{\"t\":3,\"n\":\"Type\"},{\"t\":3,\"n\":\"Actor Value\"}]},{\"t\":6,\"n\":\"Script effect\",\"c\":[{\"t\":6,\"n\":\"SCIT - Script effect data\",\"c\":[{\"t\":3,\"n\":\"Script effect\"},{\"t\":3,\"n\":\"Magic school\"},{\"t\":3,\"n\":\"Visual effect name\"},{\"t\":3,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":2,\"n\":\"FULL - Name\"}]}]},{\"t\":6,\"n\":\"Effects\",\"c\":[{\"t\":8,\"n\":\"Effects\",\"c\":[{\"t\":6,\"n\":\"Effect\",\"c\":[{\"t\":6,\"n\":\"EFME - Oblivion Magic Extender\",\"c\":[{\"t\":3,\"n\":\"Record Version\"},{\"t\":6,\"n\":\"OBME Version\",\"c\":[{\"t\":3,\"n\":\"Beta\"},{\"t\":3,\"n\":\"Minor\"},{\"t\":3,\"n\":\"Major\"}]},{\"t\":3,\"n\":\"EFIT Param Info\"},{\"t\":3,\"n\":\"EFIX Param Info\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":2,\"n\":\"EFID - Magic Effect Code\"},{\"t\":6,\"n\":\"EFIT - \",\"c\":[{\"t\":2,\"n\":\"Magic Effect Code\"},{\"t\":3,\"n\":\"Magnitude\"},{\"t\":3,\"n\":\"Area\"},{\"t\":3,\"n\":\"Duration\"},{\"t\":3,\"n\":\"Type\"},{\"t\":11,\"n\":\"Param #1 - Unknown Type\"},{\"t\":3,\"n\":\"Param #1 - FormID\"},{\"t\":2,\"n\":\"Param #1 - Magic Effect Code\"},{\"t\":3,\"n\":\"Param #1 - Actor Value\"}]},{\"t\":6,\"n\":\"Script effect\",\"c\":[{\"t\":6,\"n\":\"SCIT - Script effect data\",\"c\":[{\"t\":3,\"n\":\"Script effect\"},{\"t\":3,\"n\":\"Magic school\"},{\"t\":2,\"n\":\"Visual Effect Code\"},{\"t\":3,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":2,\"n\":\"FULL - Name\"}]},{\"t\":2,\"n\":\"EFII - Icon\"},{\"t\":6,\"n\":\"EFIX - \",\"c\":[{\"t\":3,\"n\":\"Override Mask\"},{\"t\":3,\"n\":\"Flags\"},{\"t\":5,\"n\":\"Base Cost\"},{\"t\":11,\"n\":\"Param #2 - Unknown Type\"},{\"t\":3,\"n\":\"Param #2 - FormID\"},{\"t\":2,\"n\":\"Param #2 - Magic Effect Code\"},{\"t\":3,\"n\":\"Param #2 - Actor Value\"}]}]}]},{\"n\":\"EFXX - Effects End Marker\"},{\"t\":2,\"n\":\"FULL - Name\"}]}]}]},{\"t\":1,\"p\":1,\"n\":\"EYES - Eyes\",\"c\":[{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":2,\"n\":\"ICON - Texture\"},{\"t\":3,\"n\":\"DATA - Flags\"}]},{\"t\":1,\"p\":1,\"n\":\"FACT - Faction\",\"c\":[{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":8,\"n\":\"Relations\",\"c\":[{\"t\":6,\"n\":\"XNAM - Relation\",\"c\":[{\"t\":3,\"n\":\"Faction\"},{\"t\":3,\"n\":\"Modifier\"}]}]},{\"t\":3,\"n\":\"DATA - Flags\"},{\"t\":5,\"n\":\"CNAM - Crime Gold Multiplier\"},{\"t\":10,\"n\":\"Ranks\",\"c\":[{\"t\":6,\"n\":\"Rank\",\"c\":[{\"t\":3,\"n\":\"RNAM - Rank#\"},{\"t\":2,\"n\":\"MNAM - Male\"},{\"t\":2,\"n\":\"FNAM - Female\"},{\"t\":2,\"n\":\"INAM - Insignia\"}]}]}]},{\"t\":1,\"p\":1,\"n\":\"FLOR - Flora\",\"c\":[{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":6,\"n\":\"Model\",\"c\":[{\"t\":2,\"n\":\"MODL - Model Filename\"},{\"t\":5,\"n\":\"MODB - Bound Radius\"},{\"t\":11,\"n\":\"MODT - Texture Files Hashes\"}]},{\"t\":3,\"n\":\"SCRI - Script\"},{\"t\":3,\"n\":\"PFIG - Ingredient\"},{\"t\":6,\"n\":\"PFPC - Seasonal ingredient production\",\"c\":[{\"t\":3,\"n\":\"Spring\"},{\"t\":3,\"n\":\"Summer \"},{\"t\":3,\"n\":\"Fall\"},{\"t\":3,\"n\":\"Winter\"}]}]},{\"t\":1,\"p\":1,\"n\":\"FURN - Furniture\",\"c\":[{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":6,\"n\":\"Model\",\"c\":[{\"t\":2,\"n\":\"MODL - Model Filename\"},{\"t\":5,\"n\":\"MODB - Bound Radius\"},{\"t\":11,\"n\":\"MODT - Texture Files Hashes\"}]},{\"t\":3,\"n\":\"SCRI - Script\"},{\"t\":11,\"n\":\"MNAM - Marker Flags\"}]},{\"t\":1,\"p\":1,\"n\":\"HAIR - Hair\",\"c\":[{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":6,\"n\":\"Model\",\"c\":[{\"t\":2,\"n\":\"MODL - Model Filename\"},{\"t\":5,\"n\":\"MODB - Bound Radius\"},{\"t\":11,\"n\":\"MODT - Texture Files Hashes\"}]},{\"t\":2,\"n\":\"ICON - Texture\"},{\"t\":3,\"n\":\"DATA - Flags\"}]},{\"t\":1,\"p\":1,\"n\":\"INGR - Ingredient\",\"c\":[{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"n\":\"OBME - Oblivion Magic Extender\",\"c\":[{\"t\":3,\"n\":\"Record Version\"},{\"t\":6,\"n\":\"OBME Version\",\"c\":[{\"t\":3,\"n\":\"Beta\"},{\"t\":3,\"n\":\"Minor\"},{\"t\":3,\"n\":\"Major\"}]},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":6,\"n\":\"Model\",\"c\":[{\"t\":2,\"n\":\"MODL - Model Filename\"},{\"t\":5,\"n\":\"MODB - Bound Radius\"},{\"t\":11,\"n\":\"MODT - Texture Files Hashes\"}]},{\"t\":2,\"n\":\"ICON - Icon filename\"},{\"t\":3,\"n\":\"SCRI - Script\"},{\"t\":5,\"n\":\"DATA - Weight\"},{\"t\":6,\"n\":\"ENIT - \",\"c\":[{\"t\":3,\"n\":\"Value\"},{\"t\":3,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":8,\"n\":\"Effects\",\"c\":[{\"t\":6,\"n\":\"Effect\",\"c\":[{\"t\":3,\"n\":\"EFID - Magic effect name\"},{\"t\":6,\"n\":\"EFIT - \",\"c\":[{\"t\":3,\"n\":\"Magic effect name\"},{\"t\":3,\"n\":\"Magnitude\"},{\"t\":3,\"n\":\"Area\"},{\"t\":3,\"n\":\"Duration\"},{\"t\":3,\"n\":\"Type\"},{\"t\":3,\"n\":\"Actor Value\"}]},{\"t\":6,\"n\":\"Script effect\",\"c\":[{\"t\":6,\"n\":\"SCIT - Script effect data\",\"c\":[{\"t\":3,\"n\":\"Script effect\"},{\"t\":3,\"n\":\"Magic school\"},{\"t\":3,\"n\":\"Visual effect name\"},{\"t\":3,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":2,\"n\":\"FULL - Name\"}]}]},{\"t\":6,\"n\":\"Effects\",\"c\":[{\"t\":8,\"n\":\"Effects\",\"c\":[{\"t\":6,\"n\":\"Effect\",\"c\":[{\"t\":6,\"n\":\"EFME - Oblivion Magic Extender\",\"c\":[{\"t\":3,\"n\":\"Record Version\"},{\"t\":6,\"n\":\"OBME Version\",\"c\":[{\"t\":3,\"n\":\"Beta\"},{\"t\":3,\"n\":\"Minor\"},{\"t\":3,\"n\":\"Major\"}]},{\"t\":3,\"n\":\"EFIT Param Info\"},{\"t\":3,\"n\":\"EFIX Param Info\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":2,\"n\":\"EFID - Magic Effect Code\"},{\"t\":6,\"n\":\"EFIT - \",\"c\":[{\"t\":2,\"n\":\"Magic Effect Code\"},{\"t\":3,\"n\":\"Magnitude\"},{\"t\":3,\"n\":\"Area\"},{\"t\":3,\"n\":\"Duration\"},{\"t\":3,\"n\":\"Type\"},{\"t\":11,\"n\":\"Param #1 - Unknown Type\"},{\"t\":3,\"n\":\"Param #1 - FormID\"},{\"t\":2,\"n\":\"Param #1 - Magic Effect Code\"},{\"t\":3,\"n\":\"Param #1 - Actor Value\"}]},{\"t\":6,\"n\":\"Script effect\",\"c\":[{\"t\":6,\"n\":\"SCIT - Script effect data\",\"c\":[{\"t\":3,\"n\":\"Script effect\"},{\"t\":3,\"n\":\"Magic school\"},{\"t\":2,\"n\":\"Visual Effect Code\"},{\"t\":3,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":2,\"n\":\"FULL - Name\"}]},{\"t\":2,\"n\":\"EFII - Icon\"},{\"t\":6,\"n\":\"EFIX - \",\"c\":[{\"t\":3,\"n\":\"Override Mask\"},{\"t\":3,\"n\":\"Flags\"},{\"t\":5,\"n\":\"Base Cost\"},{\"t\":11,\"n\":\"Param #2 - Unknown Type\"},{\"t\":3,\"n\":\"Param #2 - FormID\"},{\"t\":2,\"n\":\"Param #2 - Magic Effect Code\"},{\"t\":3,\"n\":\"Param #2 - Actor Value\"}]}]}]},{\"n\":\"EFXX - Effects End Marker\"},{\"t\":2,\"n\":\"FULL - Name\"}]}]}]},{\"t\":1,\"p\":1,\"n\":\"KEYM - Key\",\"c\":[{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":6,\"n\":\"Model\",\"c\":[{\"t\":2,\"n\":\"MODL - Model Filename\"},{\"t\":5,\"n\":\"MODB - Bound Radius\"},{\"t\":11,\"n\":\"MODT - Texture Files Hashes\"}]},{\"t\":2,\"n\":\"ICON - Icon filename\"},{\"t\":3,\"n\":\"SCRI - Script\"},{\"t\":6,\"n\":\"DATA - \",\"c\":[{\"t\":3,\"n\":\"Value\"},{\"t\":5,\"n\":\"Weight\"}]}]},{\"t\":1,\"p\":1,\"n\":\"LIGH - Light\",\"c\":[{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"n\":\"Model\",\"c\":[{\"t\":2,\"n\":\"MODL - Model Filename\"},{\"t\":5,\"n\":\"MODB - Bound Radius\"},{\"t\":11,\"n\":\"MODT - Texture Files Hashes\"}]},{\"t\":3,\"n\":\"SCRI - Script\"},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":2,\"n\":\"ICON - Icon filename\"},{\"t\":6,\"n\":\"DATA - \",\"c\":[{\"t\":3,\"n\":\"Time\"},{\"t\":3,\"n\":\"Radius\"},{\"t\":6,\"n\":\"Color\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":3,\"n\":\"Unused\"}]},{\"t\":3,\"n\":\"Flags\"},{\"t\":5,\"n\":\"Falloff Exponent\"},{\"t\":5,\"n\":\"FOV\"},{\"t\":3,\"n\":\"Value\"},{\"t\":5,\"n\":\"Weight\"}]},{\"t\":5,\"n\":\"FNAM - Fade value\"},{\"t\":3,\"n\":\"SNAM - Sound\"}]},{\"t\":1,\"p\":1,\"n\":\"MGEF - Magic Effect\",\"c\":[{\"t\":2,\"n\":\"EDID - Magic Effect Code\"},{\"t\":6,\"n\":\"OBME - Oblivion Magic Extender\",\"c\":[{\"t\":3,\"n\":\"Record Version\"},{\"t\":6,\"n\":\"OBME Version\",\"c\":[{\"t\":3,\"n\":\"Beta\"},{\"t\":3,\"n\":\"Minor\"},{\"t\":3,\"n\":\"Major\"}]},{\"t\":3,\"n\":\"Param A Info\"},{\"t\":3,\"n\":\"Param B Info\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":2,\"n\":\"Handler\"},{\"t\":3,\"n\":\"Flag Overrides\"},{\"t\":11,\"n\":\"ParamB\"}]},{\"t\":2,\"n\":\"EDDX - EditorID\"},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":2,\"n\":\"DESC - Description\"},{\"t\":2,\"n\":\"ICON - Icon filename\"},{\"t\":6,\"n\":\"Model\",\"c\":[{\"t\":2,\"n\":\"MODL - Model Filename\"},{\"t\":5,\"n\":\"MODB - Bound Radius\"},{\"t\":11,\"n\":\"MODT - Texture Files Hashes\"}]},{\"t\":6,\"n\":\"DATA - Data\",\"c\":[{\"t\":3,\"n\":\"Flags\"},{\"t\":5,\"n\":\"Base cost\"},{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"n\":\"Assoc. Weapon\"},{\"t\":3,\"n\":\"Assoc. Armor\"},{\"t\":3,\"n\":\"Assoc. Creature\"},{\"t\":3,\"n\":\"Assoc. Actor Value\"},{\"t\":3,\"n\":\"Magic School\"},{\"t\":3,\"n\":\"Resist value\"},{\"t\":3,\"n\":\"Counter Effect Count\"},{\"t\":3,\"n\":\"Light\"},{\"t\":5,\"n\":\"Projectile speed\"},{\"t\":3,\"n\":\"Effect Shader\"},{\"t\":3,\"n\":\"Enchant effect\"},{\"t\":3,\"n\":\"Casting sound\"},{\"t\":3,\"n\":\"Bolt sound\"},{\"t\":3,\"n\":\"Hit sound\"},{\"t\":3,\"n\":\"Area sound\"},{\"t\":5,\"n\":\"Constant Effect enchantment factor\"},{\"t\":5,\"n\":\"Constant Effect barter factor\"}]},{\"t\":7,\"n\":\"ESCE - Counter Effects\",\"c\":[{\"t\":2,\"n\":\"Counter Effect Code\"}]}]},{\"t\":1,\"p\":1,\"n\":\"MISC - Misc. Item\",\"c\":[{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":6,\"n\":\"Model\",\"c\":[{\"t\":2,\"n\":\"MODL - Model Filename\"},{\"t\":5,\"n\":\"MODB - Bound Radius\"},{\"t\":11,\"n\":\"MODT - Texture Files Hashes\"}]},{\"t\":2,\"n\":\"ICON - Icon filename\"},{\"t\":3,\"n\":\"SCRI - Script\"},{\"t\":6,\"n\":\"DATA - \",\"c\":[{\"t\":3,\"n\":\"Value\"},{\"t\":3,\"n\":\"Actor Value\"},{\"t\":5,\"n\":\"Weight\"},{\"t\":3,\"n\":\"Group\"}]}]},{\"t\":1,\"p\":1,\"n\":\"NPC_ - Non-Player Character\",\"c\":[{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":6,\"n\":\"Model\",\"c\":[{\"t\":2,\"n\":\"MODL - Model Filename\"},{\"t\":5,\"n\":\"MODB - Bound Radius\"},{\"t\":11,\"n\":\"MODT - Texture Files Hashes\"}]},{\"t\":6,\"n\":\"ACBS - Configuration\",\"c\":[{\"t\":3,\"n\":\"Flags\"},{\"t\":3,\"n\":\"Base spell points\"},{\"t\":3,\"n\":\"Fatigue\"},{\"t\":3,\"n\":\"Barter gold\"},{\"t\":3,\"n\":\"Level (offset)\"},{\"t\":3,\"n\":\"Calc min\"},{\"t\":3,\"n\":\"Calc max\"}]},{\"t\":8,\"n\":\"Factions\",\"c\":[{\"t\":6,\"n\":\"SNAM - Faction\",\"c\":[{\"t\":3,\"n\":\"Faction\"},{\"t\":3,\"n\":\"Rank\"},{\"t\":11,\"n\":\"Unused\"}]}]},{\"t\":3,\"n\":\"INAM - Death item\"},{\"t\":3,\"n\":\"RNAM - Race\"},{\"t\":8,\"n\":\"Items\",\"c\":[{\"t\":6,\"n\":\"CNTO - Item\",\"c\":[{\"t\":3,\"n\":\"Item\"},{\"t\":3,\"n\":\"Count\"}]}]},{\"t\":8,\"n\":\"Spells\",\"c\":[{\"t\":3,\"n\":\"SPLO - Spell\"}]},{\"t\":3,\"n\":\"SCRI - Script\"},{\"t\":6,\"n\":\"AIDT - AI Data\",\"c\":[{\"t\":3,\"n\":\"Aggression\"},{\"t\":3,\"n\":\"Confidence\"},{\"t\":3,\"n\":\"Energy Level\"},{\"t\":3,\"n\":\"Responsibility\"},{\"t\":3,\"n\":\"Buys\\/Sells and Services\"},{\"t\":3,\"n\":\"Teaches\"},{\"t\":3,\"n\":\"Maximum training level\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":8,\"n\":\"AI Packages\",\"c\":[{\"t\":3,\"n\":\"PKID - AI Package\"}]},{\"t\":7,\"n\":\"KFFZ - Animations\",\"c\":[{\"t\":2,\"n\":\"Animation\"}]},{\"t\":3,\"n\":\"CNAM - Class\"},{\"t\":6,\"n\":\"DATA - Stats\",\"c\":[{\"t\":3,\"n\":\"Armorer\"},{\"t\":3,\"n\":\"Athletics\"},{\"t\":3,\"n\":\"Blade\"},{\"t\":3,\"n\":\"Block\"},{\"t\":3,\"n\":\"Blunt\"},{\"t\":3,\"n\":\"Hand to Hand\"},{\"t\":3,\"n\":\"Heavy Armor\"},{\"t\":3,\"n\":\"Alchemy\"},{\"t\":3,\"n\":\"Alteration\"},{\"t\":3,\"n\":\"Conjuration\"},{\"t\":3,\"n\":\"Destruction\"},{\"t\":3,\"n\":\"Illusion\"},{\"t\":3,\"n\":\"Mysticism\"},{\"t\":3,\"n\":\"Restoration\"},{\"t\":3,\"n\":\"Acrobatics\"},{\"t\":3,\"n\":\"Light Armor\"},{\"t\":3,\"n\":\"Marksman\"},{\"t\":3,\"n\":\"Mercantile\"},{\"t\":3,\"n\":\"Security\"},{\"t\":3,\"n\":\"Sneak\"},{\"t\":3,\"n\":\"Speechcraft\"},{\"t\":3,\"n\":\"Health\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":3,\"n\":\"Strength\"},{\"t\":3,\"n\":\"Intelligence\"},{\"t\":3,\"n\":\"Willpower\"},{\"t\":3,\"n\":\"Agility\"},{\"t\":3,\"n\":\"Speed\"},{\"t\":3,\"n\":\"Endurance\"},{\"t\":3,\"n\":\"Personality\"},{\"t\":3,\"n\":\"Luck\"}]},{\"t\":3,\"n\":\"HNAM - Hair\"},{\"t\":5,\"n\":\"LNAM - Hair length\"},{\"t\":7,\"n\":\"ENAM - Eyes\",\"c\":[{\"t\":3,\"n\":\"Eyes\"}]},{\"t\":6,\"n\":\"HCLR - Hair color\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":3,\"n\":\"ZNAM - Combat Style\"},{\"t\":6,\"n\":\"FaceGen Data\",\"c\":[{\"t\":11,\"n\":\"FGGS - FaceGen Geometry-Symmetric\"},{\"t\":11,\"n\":\"FGGA - FaceGen Geometry-Asymmetric\"},{\"t\":11,\"n\":\"FGTS - FaceGen Texture-Symmetric\"}]},{\"t\":11,\"n\":\"FNAM - Unknown\"}]},{\"t\":1,\"p\":1,\"n\":\"QUST - Quest\",\"c\":[{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":3,\"n\":\"SCRI - Script\"},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":2,\"n\":\"ICON - Icon filename\"},{\"t\":6,\"n\":\"DATA - General\",\"c\":[{\"t\":3,\"n\":\"Flags\"},{\"t\":3,\"n\":\"Priority\"}]},{\"t\":8,\"n\":\"Conditions\",\"c\":[{\"t\":6,\"n\":\"CTDA - Condition\",\"c\":[{\"t\":3,\"n\":\"Type\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":5,\"n\":\"Comparison Value - Float\"},{\"t\":3,\"n\":\"Comparison Value - Global\"},{\"t\":3,\"n\":\"Function\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":11,\"n\":\"None\"},{\"t\":3,\"n\":\"Integer\"},{\"t\":3,\"n\":\"Variable Name (INVALID)\"},{\"t\":3,\"n\":\"Sex\"},{\"t\":3,\"n\":\"Actor Value\"},{\"t\":3,\"n\":\"Crime Type\"},{\"t\":3,\"n\":\"Axis\"},{\"t\":3,\"n\":\"Form Type\"},{\"t\":3,\"n\":\"Quest Stage (INVALID)\"},{\"t\":3,\"n\":\"Object Reference\"},{\"t\":3,\"n\":\"Inventory Object\"},{\"t\":3,\"n\":\"Actor\"},{\"t\":3,\"n\":\"Quest\"},{\"t\":3,\"n\":\"Faction\"},{\"t\":3,\"n\":\"Cell\"},{\"t\":3,\"n\":\"Class\"},{\"t\":3,\"n\":\"Race\"},{\"t\":3,\"n\":\"Actor Base\"},{\"t\":3,\"n\":\"Global\"},{\"t\":3,\"n\":\"Weather\"},{\"t\":3,\"n\":\"Package\"},{\"t\":3,\"n\":\"Owner\"},{\"t\":3,\"n\":\"Birthsign\"},{\"t\":3,\"n\":\"Furniture\"},{\"t\":3,\"n\":\"Magic Item\"},{\"t\":3,\"n\":\"Magic Effect\"},{\"t\":3,\"n\":\"Worldspace\"},{\"t\":3,\"n\":\"Referenceable Object\"},{\"t\":3,\"n\":\"Variable Name\"},{\"t\":3,\"n\":\"Quest Stage\"}]},{\"t\":6,\"n\":\"CTDT - Condition (old format)\",\"c\":[{\"t\":3,\"n\":\"Type\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":5,\"n\":\"Comparison Value - Float\"},{\"t\":3,\"n\":\"Comparison Value - Global\"},{\"t\":3,\"n\":\"Function\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":11,\"n\":\"None\"},{\"t\":3,\"n\":\"Integer\"},{\"t\":3,\"n\":\"Variable Name (INVALID)\"},{\"t\":3,\"n\":\"Sex\"},{\"t\":3,\"n\":\"Actor Value\"},{\"t\":3,\"n\":\"Crime Type\"},{\"t\":3,\"n\":\"Axis\"},{\"t\":3,\"n\":\"Form Type\"},{\"t\":3,\"n\":\"Quest Stage (INVALID)\"},{\"t\":3,\"n\":\"Object Reference\"},{\"t\":3,\"n\":\"Inventory Object\"},{\"t\":3,\"n\":\"Actor\"},{\"t\":3,\"n\":\"Quest\"},{\"t\":3,\"n\":\"Faction\"},{\"t\":3,\"n\":\"Cell\"},{\"t\":3,\"n\":\"Class\"},{\"t\":3,\"n\":\"Race\"},{\"t\":3,\"n\":\"Actor Base\"},{\"t\":3,\"n\":\"Global\"},{\"t\":3,\"n\":\"Weather\"},{\"t\":3,\"n\":\"Package\"},{\"t\":3,\"n\":\"Owner\"},{\"t\":3,\"n\":\"Birthsign\"},{\"t\":3,\"n\":\"Furniture\"},{\"t\":3,\"n\":\"Magic Item\"},{\"t\":3,\"n\":\"Magic Effect\"},{\"t\":3,\"n\":\"Worldspace\"},{\"t\":3,\"n\":\"Referenceable Object\"},{\"t\":3,\"n\":\"Variable Name\"},{\"t\":3,\"n\":\"Quest Stage\"}]}]},{\"t\":10,\"n\":\"Stages\",\"c\":[{\"t\":6,\"n\":\"Stage\",\"c\":[{\"t\":3,\"n\":\"INDX - Stage index\"},{\"t\":8,\"n\":\"Log Entries\",\"c\":[{\"t\":6,\"n\":\"Log Entry\",\"c\":[{\"t\":3,\"n\":\"QSDT - Stage Flags\"},{\"t\":8,\"n\":\"Conditions\",\"c\":[{\"t\":6,\"n\":\"CTDA - Condition\",\"c\":[{\"t\":3,\"n\":\"Type\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":5,\"n\":\"Comparison Value - Float\"},{\"t\":3,\"n\":\"Comparison Value - Global\"},{\"t\":3,\"n\":\"Function\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":11,\"n\":\"None\"},{\"t\":3,\"n\":\"Integer\"},{\"t\":3,\"n\":\"Variable Name (INVALID)\"},{\"t\":3,\"n\":\"Sex\"},{\"t\":3,\"n\":\"Actor Value\"},{\"t\":3,\"n\":\"Crime Type\"},{\"t\":3,\"n\":\"Axis\"},{\"t\":3,\"n\":\"Form Type\"},{\"t\":3,\"n\":\"Quest Stage (INVALID)\"},{\"t\":3,\"n\":\"Object Reference\"},{\"t\":3,\"n\":\"Inventory Object\"},{\"t\":3,\"n\":\"Actor\"},{\"t\":3,\"n\":\"Quest\"},{\"t\":3,\"n\":\"Faction\"},{\"t\":3,\"n\":\"Cell\"},{\"t\":3,\"n\":\"Class\"},{\"t\":3,\"n\":\"Race\"},{\"t\":3,\"n\":\"Actor Base\"},{\"t\":3,\"n\":\"Global\"},{\"t\":3,\"n\":\"Weather\"},{\"t\":3,\"n\":\"Package\"},{\"t\":3,\"n\":\"Owner\"},{\"t\":3,\"n\":\"Birthsign\"},{\"t\":3,\"n\":\"Furniture\"},{\"t\":3,\"n\":\"Magic Item\"},{\"t\":3,\"n\":\"Magic Effect\"},{\"t\":3,\"n\":\"Worldspace\"},{\"t\":3,\"n\":\"Referenceable Object\"},{\"t\":3,\"n\":\"Variable Name\"},{\"t\":3,\"n\":\"Quest Stage\"}]},{\"t\":6,\"n\":\"CTDT - Condition (old format)\",\"c\":[{\"t\":3,\"n\":\"Type\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":5,\"n\":\"Comparison Value - Float\"},{\"t\":3,\"n\":\"Comparison Value - Global\"},{\"t\":3,\"n\":\"Function\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":11,\"n\":\"None\"},{\"t\":3,\"n\":\"Integer\"},{\"t\":3,\"n\":\"Variable Name (INVALID)\"},{\"t\":3,\"n\":\"Sex\"},{\"t\":3,\"n\":\"Actor Value\"},{\"t\":3,\"n\":\"Crime Type\"},{\"t\":3,\"n\":\"Axis\"},{\"t\":3,\"n\":\"Form Type\"},{\"t\":3,\"n\":\"Quest Stage (INVALID)\"},{\"t\":3,\"n\":\"Object Reference\"},{\"t\":3,\"n\":\"Inventory Object\"},{\"t\":3,\"n\":\"Actor\"},{\"t\":3,\"n\":\"Quest\"},{\"t\":3,\"n\":\"Faction\"},{\"t\":3,\"n\":\"Cell\"},{\"t\":3,\"n\":\"Class\"},{\"t\":3,\"n\":\"Race\"},{\"t\":3,\"n\":\"Actor Base\"},{\"t\":3,\"n\":\"Global\"},{\"t\":3,\"n\":\"Weather\"},{\"t\":3,\"n\":\"Package\"},{\"t\":3,\"n\":\"Owner\"},{\"t\":3,\"n\":\"Birthsign\"},{\"t\":3,\"n\":\"Furniture\"},{\"t\":3,\"n\":\"Magic Item\"},{\"t\":3,\"n\":\"Magic Effect\"},{\"t\":3,\"n\":\"Worldspace\"},{\"t\":3,\"n\":\"Referenceable Object\"},{\"t\":3,\"n\":\"Variable Name\"},{\"t\":3,\"n\":\"Quest Stage\"}]}]},{\"t\":2,\"n\":\"CNAM - Log Entry\"},{\"t\":6,\"n\":\"Result Script\",\"c\":[{\"t\":6,\"n\":\"SCHR - Basic Script Data\",\"c\":[{\"t\":11,\"n\":\"Unused\"},{\"t\":3,\"n\":\"RefCount\"},{\"t\":3,\"n\":\"CompiledSize\"},{\"t\":3,\"n\":\"VariableCount\"},{\"t\":3,\"n\":\"Type\"}]},{\"t\":6,\"n\":\"SCHD - Basic Script Data\",\"c\":[{\"t\":11,\"n\":\"Unused\"},{\"t\":3,\"n\":\"RefCount\"},{\"t\":3,\"n\":\"CompiledSize\"},{\"t\":3,\"n\":\"VariableCount\"},{\"t\":3,\"n\":\"Type\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":11,\"n\":\"SCDA - Compiled result script\"},{\"t\":2,\"n\":\"SCTX - Result script source\"},{\"t\":8,\"n\":\"References\",\"c\":[{\"t\":3,\"n\":\"SCRO - Global Reference\"},{\"t\":3,\"n\":\"SCRV - Local Variable\"}]}]}]}]}]}]},{\"t\":8,\"n\":\"Targets\",\"c\":[{\"t\":6,\"n\":\"Target\",\"c\":[{\"t\":6,\"n\":\"QSTA - Target\",\"c\":[{\"t\":3,\"n\":\"Target\"},{\"t\":3,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":8,\"n\":\"Conditions\",\"c\":[{\"t\":6,\"n\":\"CTDA - Condition\",\"c\":[{\"t\":3,\"n\":\"Type\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":5,\"n\":\"Comparison Value - Float\"},{\"t\":3,\"n\":\"Comparison Value - Global\"},{\"t\":3,\"n\":\"Function\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":11,\"n\":\"None\"},{\"t\":3,\"n\":\"Integer\"},{\"t\":3,\"n\":\"Variable Name (INVALID)\"},{\"t\":3,\"n\":\"Sex\"},{\"t\":3,\"n\":\"Actor Value\"},{\"t\":3,\"n\":\"Crime Type\"},{\"t\":3,\"n\":\"Axis\"},{\"t\":3,\"n\":\"Form Type\"},{\"t\":3,\"n\":\"Quest Stage (INVALID)\"},{\"t\":3,\"n\":\"Object Reference\"},{\"t\":3,\"n\":\"Inventory Object\"},{\"t\":3,\"n\":\"Actor\"},{\"t\":3,\"n\":\"Quest\"},{\"t\":3,\"n\":\"Faction\"},{\"t\":3,\"n\":\"Cell\"},{\"t\":3,\"n\":\"Class\"},{\"t\":3,\"n\":\"Race\"},{\"t\":3,\"n\":\"Actor Base\"},{\"t\":3,\"n\":\"Global\"},{\"t\":3,\"n\":\"Weather\"},{\"t\":3,\"n\":\"Package\"},{\"t\":3,\"n\":\"Owner\"},{\"t\":3,\"n\":\"Birthsign\"},{\"t\":3,\"n\":\"Furniture\"},{\"t\":3,\"n\":\"Magic Item\"},{\"t\":3,\"n\":\"Magic Effect\"},{\"t\":3,\"n\":\"Worldspace\"},{\"t\":3,\"n\":\"Referenceable Object\"},{\"t\":3,\"n\":\"Variable Name\"},{\"t\":3,\"n\":\"Quest Stage\"}]},{\"t\":6,\"n\":\"CTDT - Condition (old format)\",\"c\":[{\"t\":3,\"n\":\"Type\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":5,\"n\":\"Comparison Value - Float\"},{\"t\":3,\"n\":\"Comparison Value - Global\"},{\"t\":3,\"n\":\"Function\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":11,\"n\":\"None\"},{\"t\":3,\"n\":\"Integer\"},{\"t\":3,\"n\":\"Variable Name (INVALID)\"},{\"t\":3,\"n\":\"Sex\"},{\"t\":3,\"n\":\"Actor Value\"},{\"t\":3,\"n\":\"Crime Type\"},{\"t\":3,\"n\":\"Axis\"},{\"t\":3,\"n\":\"Form Type\"},{\"t\":3,\"n\":\"Quest Stage (INVALID)\"},{\"t\":3,\"n\":\"Object Reference\"},{\"t\":3,\"n\":\"Inventory Object\"},{\"t\":3,\"n\":\"Actor\"},{\"t\":3,\"n\":\"Quest\"},{\"t\":3,\"n\":\"Faction\"},{\"t\":3,\"n\":\"Cell\"},{\"t\":3,\"n\":\"Class\"},{\"t\":3,\"n\":\"Race\"},{\"t\":3,\"n\":\"Actor Base\"},{\"t\":3,\"n\":\"Global\"},{\"t\":3,\"n\":\"Weather\"},{\"t\":3,\"n\":\"Package\"},{\"t\":3,\"n\":\"Owner\"},{\"t\":3,\"n\":\"Birthsign\"},{\"t\":3,\"n\":\"Furniture\"},{\"t\":3,\"n\":\"Magic Item\"},{\"t\":3,\"n\":\"Magic Effect\"},{\"t\":3,\"n\":\"Worldspace\"},{\"t\":3,\"n\":\"Referenceable Object\"},{\"t\":3,\"n\":\"Variable Name\"},{\"t\":3,\"n\":\"Quest Stage\"}]}]}]}]}]},{\"t\":1,\"p\":1,\"n\":\"RACE - Race\",\"c\":[{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":2,\"n\":\"DESC - Description\"},{\"t\":8,\"n\":\"Spells\",\"c\":[{\"t\":3,\"n\":\"SPLO - Spell\"}]},{\"t\":8,\"n\":\"Relations\",\"c\":[{\"t\":6,\"n\":\"XNAM - Relation\",\"c\":[{\"t\":3,\"n\":\"Faction\"},{\"t\":3,\"n\":\"Modifier\"}]}]},{\"t\":6,\"n\":\"DATA - \",\"c\":[{\"t\":7,\"n\":\"Skill Boosts\",\"c\":[{\"t\":6,\"n\":\"Skill Boost\",\"c\":[{\"t\":3,\"n\":\"Skill\"},{\"t\":3,\"n\":\"Boost\"}]}]},{\"t\":11,\"n\":\"Unused\"},{\"t\":5,\"n\":\"Male Height\"},{\"t\":5,\"n\":\"Female Height\"},{\"t\":5,\"n\":\"Male Weight\"},{\"t\":5,\"n\":\"Female Weight\"},{\"t\":3,\"n\":\"Flags\"}]},{\"t\":6,\"n\":\"VNAM - Voice\",\"c\":[{\"t\":3,\"n\":\"Male\"},{\"t\":3,\"n\":\"Female\"}]},{\"t\":6,\"n\":\"DNAM - Default Hair\",\"c\":[{\"t\":3,\"n\":\"Male\"},{\"t\":3,\"n\":\"Female\"}]},{\"t\":3,\"n\":\"CNAM - Default Hair Color\"},{\"t\":5,\"n\":\"PNAM - FaceGen - Main clamp\"},{\"t\":5,\"n\":\"UNAM - FaceGen - Face clamp\"},{\"t\":6,\"n\":\"ATTR - Base Attributes\",\"c\":[{\"t\":6,\"n\":\"Male\",\"c\":[{\"t\":3,\"n\":\"Strength\"},{\"t\":3,\"n\":\"Intelligence\"},{\"t\":3,\"n\":\"Willpower\"},{\"t\":3,\"n\":\"Agility\"},{\"t\":3,\"n\":\"Speed\"},{\"t\":3,\"n\":\"Endurance\"},{\"t\":3,\"n\":\"Personality\"},{\"t\":3,\"n\":\"Luck\"}]},{\"t\":6,\"n\":\"Female\",\"c\":[{\"t\":3,\"n\":\"Strength\"},{\"t\":3,\"n\":\"Intelligence\"},{\"t\":3,\"n\":\"Willpower\"},{\"t\":3,\"n\":\"Agility\"},{\"t\":3,\"n\":\"Speed\"},{\"t\":3,\"n\":\"Endurance\"},{\"t\":3,\"n\":\"Personality\"},{\"t\":3,\"n\":\"Luck\"}]}]},{\"t\":6,\"n\":\"Face Data\",\"c\":[{\"n\":\"NAM0 - Face Data Marker\"},{\"t\":10,\"n\":\"Parts\",\"c\":[{\"t\":6,\"n\":\"Part\",\"c\":[{\"t\":3,\"n\":\"INDX - Index\"},{\"t\":6,\"n\":\"Model\",\"c\":[{\"t\":2,\"n\":\"MODL - Model Filename\"},{\"t\":5,\"n\":\"MODB - Bound Radius\"},{\"t\":11,\"n\":\"MODT - Texture Files Hashes\"}]},{\"t\":2,\"n\":\"ICON - Icon filename\"}]}]}]},{\"n\":\"NAM1 - Body Data Marker\"},{\"t\":6,\"n\":\"Male Body Data\",\"c\":[{\"n\":\"MNAM - Male Body Data Marker\"},{\"t\":6,\"n\":\"Model\",\"c\":[{\"t\":2,\"n\":\"MODL - Model Filename\"},{\"t\":5,\"n\":\"MODB - Bound Radius\"},{\"t\":11,\"n\":\"MODT - Texture Files Hashes\"}]},{\"t\":10,\"n\":\"Parts\",\"c\":[{\"t\":6,\"n\":\"Part\",\"c\":[{\"t\":3,\"n\":\"INDX - Index\"},{\"t\":2,\"n\":\"ICON - Icon filename\"}]}]}]},{\"t\":6,\"n\":\"Female Body Data\",\"c\":[{\"n\":\"FNAM - Female Body Data Marker\"},{\"t\":6,\"n\":\"Model\",\"c\":[{\"t\":2,\"n\":\"MODL - Model Filename\"},{\"t\":5,\"n\":\"MODB - Bound Radius\"},{\"t\":11,\"n\":\"MODT - Texture Files Hashes\"}]},{\"t\":10,\"n\":\"Parts\",\"c\":[{\"t\":6,\"n\":\"Part\",\"c\":[{\"t\":3,\"n\":\"INDX - Index\"},{\"t\":2,\"n\":\"ICON - Icon filename\"}]}]}]},{\"t\":7,\"n\":\"HNAM - Hairs\",\"c\":[{\"t\":3,\"n\":\"Hair\"}]},{\"t\":7,\"n\":\"ENAM - Eyes\",\"c\":[{\"t\":3,\"n\":\"Eye\"}]},{\"t\":6,\"n\":\"FaceGen Data\",\"c\":[{\"t\":11,\"n\":\"FGGS - FaceGen Geometry-Symmetric\"},{\"t\":11,\"n\":\"FGGA - FaceGen Geometry-Asymmetric\"},{\"t\":11,\"n\":\"FGTS - FaceGen Texture-Symmetric\"}]},{\"t\":11,\"n\":\"SNAM - Unknown\"}]},{\"t\":1,\"p\":1,\"n\":\"SGST - Sigil Stone\",\"c\":[{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"n\":\"OBME - Oblivion Magic Extender\",\"c\":[{\"t\":3,\"n\":\"Record Version\"},{\"t\":6,\"n\":\"OBME Version\",\"c\":[{\"t\":3,\"n\":\"Beta\"},{\"t\":3,\"n\":\"Minor\"},{\"t\":3,\"n\":\"Major\"}]},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":6,\"n\":\"Model\",\"c\":[{\"t\":2,\"n\":\"MODL - Model Filename\"},{\"t\":5,\"n\":\"MODB - Bound Radius\"},{\"t\":11,\"n\":\"MODT - Texture Files Hashes\"}]},{\"t\":2,\"n\":\"ICON - Icon filename\"},{\"t\":3,\"n\":\"SCRI - Script\"},{\"t\":8,\"n\":\"Effects\",\"c\":[{\"t\":6,\"n\":\"Effect\",\"c\":[{\"t\":3,\"n\":\"EFID - Magic effect name\"},{\"t\":6,\"n\":\"EFIT - \",\"c\":[{\"t\":3,\"n\":\"Magic effect name\"},{\"t\":3,\"n\":\"Magnitude\"},{\"t\":3,\"n\":\"Area\"},{\"t\":3,\"n\":\"Duration\"},{\"t\":3,\"n\":\"Type\"},{\"t\":3,\"n\":\"Actor Value\"}]},{\"t\":6,\"n\":\"Script effect\",\"c\":[{\"t\":6,\"n\":\"SCIT - Script effect data\",\"c\":[{\"t\":3,\"n\":\"Script effect\"},{\"t\":3,\"n\":\"Magic school\"},{\"t\":3,\"n\":\"Visual effect name\"},{\"t\":3,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":2,\"n\":\"FULL - Name\"}]}]},{\"t\":6,\"n\":\"Effects\",\"c\":[{\"t\":8,\"n\":\"Effects\",\"c\":[{\"t\":6,\"n\":\"Effect\",\"c\":[{\"t\":6,\"n\":\"EFME - Oblivion Magic Extender\",\"c\":[{\"t\":3,\"n\":\"Record Version\"},{\"t\":6,\"n\":\"OBME Version\",\"c\":[{\"t\":3,\"n\":\"Beta\"},{\"t\":3,\"n\":\"Minor\"},{\"t\":3,\"n\":\"Major\"}]},{\"t\":3,\"n\":\"EFIT Param Info\"},{\"t\":3,\"n\":\"EFIX Param Info\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":2,\"n\":\"EFID - Magic Effect Code\"},{\"t\":6,\"n\":\"EFIT - \",\"c\":[{\"t\":2,\"n\":\"Magic Effect Code\"},{\"t\":3,\"n\":\"Magnitude\"},{\"t\":3,\"n\":\"Area\"},{\"t\":3,\"n\":\"Duration\"},{\"t\":3,\"n\":\"Type\"},{\"t\":11,\"n\":\"Param #1 - Unknown Type\"},{\"t\":3,\"n\":\"Param #1 - FormID\"},{\"t\":2,\"n\":\"Param #1 - Magic Effect Code\"},{\"t\":3,\"n\":\"Param #1 - Actor Value\"}]},{\"t\":6,\"n\":\"Script effect\",\"c\":[{\"t\":6,\"n\":\"SCIT - Script effect data\",\"c\":[{\"t\":3,\"n\":\"Script effect\"},{\"t\":3,\"n\":\"Magic school\"},{\"t\":2,\"n\":\"Visual Effect Code\"},{\"t\":3,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":2,\"n\":\"FULL - Name\"}]},{\"t\":2,\"n\":\"EFII - Icon\"},{\"t\":6,\"n\":\"EFIX - \",\"c\":[{\"t\":3,\"n\":\"Override Mask\"},{\"t\":3,\"n\":\"Flags\"},{\"t\":5,\"n\":\"Base Cost\"},{\"t\":11,\"n\":\"Param #2 - Unknown Type\"},{\"t\":3,\"n\":\"Param #2 - FormID\"},{\"t\":2,\"n\":\"Param #2 - Magic Effect Code\"},{\"t\":3,\"n\":\"Param #2 - Actor Value\"}]}]}]},{\"n\":\"EFXX - Effects End Marker\"},{\"t\":2,\"n\":\"FULL - Name\"}]}]},{\"t\":6,\"n\":\"DATA - \",\"c\":[{\"t\":3,\"n\":\"Uses \"},{\"t\":3,\"n\":\"Value\"},{\"t\":5,\"n\":\"Weight\"}]}]},{\"t\":1,\"p\":1,\"n\":\"SLGM - Soul Gem\",\"c\":[{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":6,\"n\":\"Model\",\"c\":[{\"t\":2,\"n\":\"MODL - Model Filename\"},{\"t\":5,\"n\":\"MODB - Bound Radius\"},{\"t\":11,\"n\":\"MODT - Texture Files Hashes\"}]},{\"t\":2,\"n\":\"ICON - Icon filename\"},{\"t\":3,\"n\":\"SCRI - Script\"},{\"t\":6,\"n\":\"DATA - \",\"c\":[{\"t\":3,\"n\":\"Value\"},{\"t\":5,\"n\":\"Weight\"}]},{\"t\":3,\"n\":\"SOUL - Contained Soul\"},{\"t\":3,\"n\":\"SLCP - Maximum Capacity\"}]},{\"t\":1,\"p\":1,\"n\":\"SPEL - Spell\",\"c\":[{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"n\":\"OBME - Oblivion Magic Extender\",\"c\":[{\"t\":3,\"n\":\"Record Version\"},{\"t\":6,\"n\":\"OBME Version\",\"c\":[{\"t\":3,\"n\":\"Beta\"},{\"t\":3,\"n\":\"Minor\"},{\"t\":3,\"n\":\"Major\"}]},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":6,\"n\":\"SPIT - \",\"c\":[{\"t\":3,\"n\":\"Type\"},{\"t\":3,\"n\":\"Cost\"},{\"t\":3,\"n\":\"Level\"},{\"t\":3,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":8,\"n\":\"Effects\",\"c\":[{\"t\":6,\"n\":\"Effect\",\"c\":[{\"t\":3,\"n\":\"EFID - Magic effect name\"},{\"t\":6,\"n\":\"EFIT - \",\"c\":[{\"t\":3,\"n\":\"Magic effect name\"},{\"t\":3,\"n\":\"Magnitude\"},{\"t\":3,\"n\":\"Area\"},{\"t\":3,\"n\":\"Duration\"},{\"t\":3,\"n\":\"Type\"},{\"t\":3,\"n\":\"Actor Value\"}]},{\"t\":6,\"n\":\"Script effect\",\"c\":[{\"t\":6,\"n\":\"SCIT - Script effect data\",\"c\":[{\"t\":3,\"n\":\"Script effect\"},{\"t\":3,\"n\":\"Magic school\"},{\"t\":3,\"n\":\"Visual effect name\"},{\"t\":3,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":2,\"n\":\"FULL - Name\"}]}]},{\"t\":6,\"n\":\"Effects\",\"c\":[{\"t\":8,\"n\":\"Effects\",\"c\":[{\"t\":6,\"n\":\"Effect\",\"c\":[{\"t\":6,\"n\":\"EFME - Oblivion Magic Extender\",\"c\":[{\"t\":3,\"n\":\"Record Version\"},{\"t\":6,\"n\":\"OBME Version\",\"c\":[{\"t\":3,\"n\":\"Beta\"},{\"t\":3,\"n\":\"Minor\"},{\"t\":3,\"n\":\"Major\"}]},{\"t\":3,\"n\":\"EFIT Param Info\"},{\"t\":3,\"n\":\"EFIX Param Info\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":2,\"n\":\"EFID - Magic Effect Code\"},{\"t\":6,\"n\":\"EFIT - \",\"c\":[{\"t\":2,\"n\":\"Magic Effect Code\"},{\"t\":3,\"n\":\"Magnitude\"},{\"t\":3,\"n\":\"Area\"},{\"t\":3,\"n\":\"Duration\"},{\"t\":3,\"n\":\"Type\"},{\"t\":11,\"n\":\"Param #1 - Unknown Type\"},{\"t\":3,\"n\":\"Param #1 - FormID\"},{\"t\":2,\"n\":\"Param #1 - Magic Effect Code\"},{\"t\":3,\"n\":\"Param #1 - Actor Value\"}]},{\"t\":6,\"n\":\"Script effect\",\"c\":[{\"t\":6,\"n\":\"SCIT - Script effect data\",\"c\":[{\"t\":3,\"n\":\"Script effect\"},{\"t\":3,\"n\":\"Magic school\"},{\"t\":2,\"n\":\"Visual Effect Code\"},{\"t\":3,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":2,\"n\":\"FULL - Name\"}]},{\"t\":2,\"n\":\"EFII - Icon\"},{\"t\":6,\"n\":\"EFIX - \",\"c\":[{\"t\":3,\"n\":\"Override Mask\"},{\"t\":3,\"n\":\"Flags\"},{\"t\":5,\"n\":\"Base Cost\"},{\"t\":11,\"n\":\"Param #2 - Unknown Type\"},{\"t\":3,\"n\":\"Param #2 - FormID\"},{\"t\":2,\"n\":\"Param #2 - Magic Effect Code\"},{\"t\":3,\"n\":\"Param #2 - Actor Value\"}]}]}]},{\"n\":\"EFXX - Effects End Marker\"},{\"t\":2,\"n\":\"FULL - Name\"}]}]}]},{\"t\":1,\"p\":1,\"n\":\"WEAP - Weapon\",\"c\":[{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":6,\"n\":\"Model\",\"c\":[{\"t\":2,\"n\":\"MODL - Model Filename\"},{\"t\":5,\"n\":\"MODB - Bound Radius\"},{\"t\":11,\"n\":\"MODT - Texture Files Hashes\"}]},{\"t\":2,\"n\":\"ICON - Icon filename\"},{\"t\":3,\"n\":\"SCRI - Script\"},{\"t\":3,\"n\":\"ENAM - Enchantment\"},{\"t\":3,\"n\":\"ANAM - Enchantment Points\"},{\"t\":6,\"n\":\"DATA - \",\"c\":[{\"t\":3,\"n\":\"Type\"},{\"t\":5,\"n\":\"Speed\"},{\"t\":5,\"n\":\"Reach\"},{\"t\":3,\"n\":\"Flags\"},{\"t\":3,\"n\":\"Value\"},{\"t\":3,\"n\":\"Health\"},{\"t\":5,\"n\":\"Weight\"},{\"t\":3,\"n\":\"Damage\"}]}]},{\"t\":1,\"p\":1,\"n\":\"WRLD - Worldspace\",\"c\":[{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":6,\"n\":\"Parent\",\"c\":[{\"t\":3,\"n\":\"WNAM - Worldspace\"}]},{\"t\":3,\"n\":\"CNAM - Climate\"},{\"t\":3,\"n\":\"NAM2 - Water\"},{\"t\":2,\"n\":\"ICON - Icon filename\"},{\"t\":6,\"n\":\"MNAM - Map Data\",\"c\":[{\"t\":6,\"n\":\"Usable Dimensions\",\"c\":[{\"t\":3,\"n\":\"X\"},{\"t\":3,\"n\":\"Y\"}]},{\"t\":6,\"n\":\"Cell Coordinates\",\"c\":[{\"t\":6,\"n\":\"NW Cell\",\"c\":[{\"t\":3,\"n\":\"X\"},{\"t\":3,\"n\":\"Y\"}]},{\"t\":6,\"n\":\"SE Cell\",\"c\":[{\"t\":3,\"n\":\"X\"},{\"t\":3,\"n\":\"Y\"}]}]}]},{\"t\":3,\"n\":\"DATA - Flags\"},{\"t\":6,\"n\":\"Object Bounds\",\"c\":[{\"t\":6,\"n\":\"NAM0 - Min\",\"c\":[{\"t\":5,\"n\":\"X\"},{\"t\":5,\"n\":\"Y\"}]},{\"t\":6,\"n\":\"NAM9 - Max\",\"c\":[{\"t\":5,\"n\":\"X\"},{\"t\":5,\"n\":\"Y\"}]}]},{\"t\":3,\"n\":\"SNAM - Music\"},{\"t\":11,\"n\":\"OFST - Offset Data\"}]},{\"t\":1,\"p\":1,\"n\":\"ACTI - Activator\",\"c\":[{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":6,\"n\":\"Model\",\"c\":[{\"t\":2,\"n\":\"MODL - Model Filename\"},{\"t\":5,\"n\":\"MODB - Bound Radius\"},{\"t\":11,\"n\":\"MODT - Texture Files Hashes\"}]},{\"t\":3,\"n\":\"SCRI - Script\"},{\"t\":3,\"n\":\"SNAM - Sound\"}]}]},\"name\":\"Bash.Names\",\"hash\":\"C16AAD3F\",\"color\":255}"
  },
  {
    "path": "frontend/settings/Oblivion/Bash.Npc.EyesOnly.json",
    "content": "{\"records\":\"NPC_\",\"description\":\"Npc.HairOnly tag from Wrye Bash.\\r\\n\\r\\nUse when the mod modifies NPC eyes.\",\"tree\":{\"records\":[{\"t\":1,\"p\":1,\"n\":\"NPC_ - Non-Player Character\",\"c\":[{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"n\":\"FULL - Name\"},{\"t\":6,\"n\":\"Model\",\"c\":[{\"t\":2,\"n\":\"MODL - Model Filename\"},{\"t\":5,\"n\":\"MODB - Bound Radius\"},{\"t\":11,\"n\":\"MODT - Texture Files Hashes\"}]},{\"t\":6,\"n\":\"ACBS - Configuration\",\"c\":[{\"t\":3,\"n\":\"Flags\"},{\"t\":3,\"n\":\"Base spell points\"},{\"t\":3,\"n\":\"Fatigue\"},{\"t\":3,\"n\":\"Barter gold\"},{\"t\":3,\"n\":\"Level (offset)\"},{\"t\":3,\"n\":\"Calc min\"},{\"t\":3,\"n\":\"Calc max\"}]},{\"t\":8,\"n\":\"Factions\",\"c\":[{\"t\":6,\"n\":\"SNAM - Faction\",\"c\":[{\"t\":3,\"n\":\"Faction\"},{\"t\":3,\"n\":\"Rank\"},{\"t\":11,\"n\":\"Unused\"}]}]},{\"t\":3,\"n\":\"INAM - Death item\"},{\"t\":3,\"n\":\"RNAM - Race\"},{\"t\":8,\"n\":\"Items\",\"c\":[{\"t\":6,\"n\":\"CNTO - Item\",\"c\":[{\"t\":3,\"n\":\"Item\"},{\"t\":3,\"n\":\"Count\"}]}]},{\"t\":8,\"n\":\"Spells\",\"c\":[{\"t\":3,\"n\":\"SPLO - Spell\"}]},{\"t\":3,\"n\":\"SCRI - Script\"},{\"t\":6,\"n\":\"AIDT - AI Data\",\"c\":[{\"t\":3,\"n\":\"Aggression\"},{\"t\":3,\"n\":\"Confidence\"},{\"t\":3,\"n\":\"Energy Level\"},{\"t\":3,\"n\":\"Responsibility\"},{\"t\":3,\"n\":\"Buys\\/Sells and Services\"},{\"t\":3,\"n\":\"Teaches\"},{\"t\":3,\"n\":\"Maximum training level\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":8,\"n\":\"AI Packages\",\"c\":[{\"t\":3,\"n\":\"PKID - AI Package\"}]},{\"t\":7,\"n\":\"KFFZ - Animations\",\"c\":[{\"t\":2,\"n\":\"Animation\"}]},{\"t\":3,\"n\":\"CNAM - Class\"},{\"t\":6,\"n\":\"DATA - Stats\",\"c\":[{\"t\":3,\"n\":\"Armorer\"},{\"t\":3,\"n\":\"Athletics\"},{\"t\":3,\"n\":\"Blade\"},{\"t\":3,\"n\":\"Block\"},{\"t\":3,\"n\":\"Blunt\"},{\"t\":3,\"n\":\"Hand to Hand\"},{\"t\":3,\"n\":\"Heavy Armor\"},{\"t\":3,\"n\":\"Alchemy\"},{\"t\":3,\"n\":\"Alteration\"},{\"t\":3,\"n\":\"Conjuration\"},{\"t\":3,\"n\":\"Destruction\"},{\"t\":3,\"n\":\"Illusion\"},{\"t\":3,\"n\":\"Mysticism\"},{\"t\":3,\"n\":\"Restoration\"},{\"t\":3,\"n\":\"Acrobatics\"},{\"t\":3,\"n\":\"Light Armor\"},{\"t\":3,\"n\":\"Marksman\"},{\"t\":3,\"n\":\"Mercantile\"},{\"t\":3,\"n\":\"Security\"},{\"t\":3,\"n\":\"Sneak\"},{\"t\":3,\"n\":\"Speechcraft\"},{\"t\":3,\"n\":\"Health\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":3,\"n\":\"Strength\"},{\"t\":3,\"n\":\"Intelligence\"},{\"t\":3,\"n\":\"Willpower\"},{\"t\":3,\"n\":\"Agility\"},{\"t\":3,\"n\":\"Speed\"},{\"t\":3,\"n\":\"Endurance\"},{\"t\":3,\"n\":\"Personality\"},{\"t\":3,\"n\":\"Luck\"}]},{\"t\":3,\"n\":\"HNAM - Hair\"},{\"t\":5,\"n\":\"LNAM - Hair length\"},{\"t\":7,\"s\":1,\"p\":1,\"n\":\"ENAM - Eyes\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Eyes\"}]},{\"t\":6,\"n\":\"HCLR - Hair color\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":3,\"n\":\"ZNAM - Combat Style\"},{\"t\":6,\"n\":\"FaceGen Data\",\"c\":[{\"t\":11,\"n\":\"FGGS - FaceGen Geometry-Symmetric\"},{\"t\":11,\"n\":\"FGGA - FaceGen Geometry-Asymmetric\"},{\"t\":11,\"n\":\"FGTS - FaceGen Texture-Symmetric\"}]},{\"t\":11,\"n\":\"FNAM - Unknown\"}]}]},\"name\":\"Bash.Npc.EyesOnly\",\"hash\":\"97266C5F\",\"color\":255}"
  },
  {
    "path": "frontend/settings/Oblivion/Bash.Npc.HairOnly.json",
    "content": "{\"records\":\"NPC_\",\"description\":\"Npc.HairOnly tag from Wrye Bash.\\r\\n\\r\\nUse when the mod modifies NPC hair.\",\"tree\":{\"records\":[{\"t\":1,\"p\":1,\"n\":\"NPC_ - Non-Player Character\",\"c\":[{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"n\":\"FULL - Name\"},{\"t\":6,\"n\":\"Model\",\"c\":[{\"t\":2,\"n\":\"MODL - Model Filename\"},{\"t\":5,\"n\":\"MODB - Bound Radius\"},{\"t\":11,\"n\":\"MODT - Texture Files Hashes\"}]},{\"t\":6,\"n\":\"ACBS - Configuration\",\"c\":[{\"t\":3,\"n\":\"Flags\"},{\"t\":3,\"n\":\"Base spell points\"},{\"t\":3,\"n\":\"Fatigue\"},{\"t\":3,\"n\":\"Barter gold\"},{\"t\":3,\"n\":\"Level (offset)\"},{\"t\":3,\"n\":\"Calc min\"},{\"t\":3,\"n\":\"Calc max\"}]},{\"t\":8,\"n\":\"Factions\",\"c\":[{\"t\":6,\"n\":\"SNAM - Faction\",\"c\":[{\"t\":3,\"n\":\"Faction\"},{\"t\":3,\"n\":\"Rank\"},{\"t\":11,\"n\":\"Unused\"}]}]},{\"t\":3,\"n\":\"INAM - Death item\"},{\"t\":3,\"n\":\"RNAM - Race\"},{\"t\":8,\"n\":\"Items\",\"c\":[{\"t\":6,\"n\":\"CNTO - Item\",\"c\":[{\"t\":3,\"n\":\"Item\"},{\"t\":3,\"n\":\"Count\"}]}]},{\"t\":8,\"n\":\"Spells\",\"c\":[{\"t\":3,\"n\":\"SPLO - Spell\"}]},{\"t\":3,\"n\":\"SCRI - Script\"},{\"t\":6,\"n\":\"AIDT - AI Data\",\"c\":[{\"t\":3,\"n\":\"Aggression\"},{\"t\":3,\"n\":\"Confidence\"},{\"t\":3,\"n\":\"Energy Level\"},{\"t\":3,\"n\":\"Responsibility\"},{\"t\":3,\"n\":\"Buys\\/Sells and Services\"},{\"t\":3,\"n\":\"Teaches\"},{\"t\":3,\"n\":\"Maximum training level\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":8,\"n\":\"AI Packages\",\"c\":[{\"t\":3,\"n\":\"PKID - AI Package\"}]},{\"t\":7,\"n\":\"KFFZ - Animations\",\"c\":[{\"t\":2,\"n\":\"Animation\"}]},{\"t\":3,\"n\":\"CNAM - Class\"},{\"t\":6,\"n\":\"DATA - Stats\",\"c\":[{\"t\":3,\"n\":\"Armorer\"},{\"t\":3,\"n\":\"Athletics\"},{\"t\":3,\"n\":\"Blade\"},{\"t\":3,\"n\":\"Block\"},{\"t\":3,\"n\":\"Blunt\"},{\"t\":3,\"n\":\"Hand to Hand\"},{\"t\":3,\"n\":\"Heavy Armor\"},{\"t\":3,\"n\":\"Alchemy\"},{\"t\":3,\"n\":\"Alteration\"},{\"t\":3,\"n\":\"Conjuration\"},{\"t\":3,\"n\":\"Destruction\"},{\"t\":3,\"n\":\"Illusion\"},{\"t\":3,\"n\":\"Mysticism\"},{\"t\":3,\"n\":\"Restoration\"},{\"t\":3,\"n\":\"Acrobatics\"},{\"t\":3,\"n\":\"Light Armor\"},{\"t\":3,\"n\":\"Marksman\"},{\"t\":3,\"n\":\"Mercantile\"},{\"t\":3,\"n\":\"Security\"},{\"t\":3,\"n\":\"Sneak\"},{\"t\":3,\"n\":\"Speechcraft\"},{\"t\":3,\"n\":\"Health\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":3,\"n\":\"Strength\"},{\"t\":3,\"n\":\"Intelligence\"},{\"t\":3,\"n\":\"Willpower\"},{\"t\":3,\"n\":\"Agility\"},{\"t\":3,\"n\":\"Speed\"},{\"t\":3,\"n\":\"Endurance\"},{\"t\":3,\"n\":\"Personality\"},{\"t\":3,\"n\":\"Luck\"}]},{\"t\":3,\"p\":1,\"n\":\"HNAM - Hair\"},{\"t\":5,\"n\":\"LNAM - Hair length\"},{\"t\":7,\"n\":\"ENAM - Eyes\",\"c\":[{\"t\":3,\"n\":\"Eyes\"}]},{\"t\":6,\"n\":\"HCLR - Hair color\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":3,\"n\":\"ZNAM - Combat Style\"},{\"t\":6,\"n\":\"FaceGen Data\",\"c\":[{\"t\":11,\"n\":\"FGGS - FaceGen Geometry-Symmetric\"},{\"t\":11,\"n\":\"FGGA - FaceGen Geometry-Asymmetric\"},{\"t\":11,\"n\":\"FGTS - FaceGen Texture-Symmetric\"}]},{\"t\":11,\"n\":\"FNAM - Unknown\"}]}]},\"name\":\"Bash.Npc.HairOnly\",\"hash\":\"8E1AE0C5\",\"color\":255}"
  },
  {
    "path": "frontend/settings/Oblivion/Bash.NpcFaces.json",
    "content": "{\"records\":\"NPC_\",\"description\":\"NpcFaces tag from Wrye Bash.\\r\\n\\r\\nUsed when the mod modifies NPC faces.\",\"tree\":{\"records\":[{\"t\":1,\"p\":1,\"n\":\"NPC_ - Non-Player Character\",\"c\":[{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"n\":\"FULL - Name\"},{\"t\":6,\"n\":\"Model\",\"c\":[{\"t\":2,\"n\":\"MODL - Model Filename\"},{\"t\":5,\"n\":\"MODB - Bound Radius\"},{\"t\":11,\"n\":\"MODT - Texture Files Hashes\"}]},{\"t\":6,\"n\":\"ACBS - Configuration\",\"c\":[{\"t\":3,\"n\":\"Flags\"},{\"t\":3,\"n\":\"Base spell points\"},{\"t\":3,\"n\":\"Fatigue\"},{\"t\":3,\"n\":\"Barter gold\"},{\"t\":3,\"n\":\"Level (offset)\"},{\"t\":3,\"n\":\"Calc min\"},{\"t\":3,\"n\":\"Calc max\"}]},{\"t\":8,\"n\":\"Factions\",\"c\":[{\"t\":6,\"n\":\"SNAM - Faction\",\"c\":[{\"t\":3,\"n\":\"Faction\"},{\"t\":3,\"n\":\"Rank\"},{\"t\":11,\"n\":\"Unused\"}]}]},{\"t\":3,\"n\":\"INAM - Death item\"},{\"t\":3,\"n\":\"RNAM - Race\"},{\"t\":8,\"n\":\"Items\",\"c\":[{\"t\":6,\"n\":\"CNTO - Item\",\"c\":[{\"t\":3,\"n\":\"Item\"},{\"t\":3,\"n\":\"Count\"}]}]},{\"t\":8,\"n\":\"Spells\",\"c\":[{\"t\":3,\"n\":\"SPLO - Spell\"}]},{\"t\":3,\"n\":\"SCRI - Script\"},{\"t\":6,\"n\":\"AIDT - AI Data\",\"c\":[{\"t\":3,\"n\":\"Aggression\"},{\"t\":3,\"n\":\"Confidence\"},{\"t\":3,\"n\":\"Energy Level\"},{\"t\":3,\"n\":\"Responsibility\"},{\"t\":3,\"n\":\"Buys\\/Sells and Services\"},{\"t\":3,\"n\":\"Teaches\"},{\"t\":3,\"n\":\"Maximum training level\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":8,\"n\":\"AI Packages\",\"c\":[{\"t\":3,\"n\":\"PKID - AI Package\"}]},{\"t\":7,\"n\":\"KFFZ - Animations\",\"c\":[{\"t\":2,\"n\":\"Animation\"}]},{\"t\":3,\"n\":\"CNAM - Class\"},{\"t\":6,\"n\":\"DATA - Stats\",\"c\":[{\"t\":3,\"n\":\"Armorer\"},{\"t\":3,\"n\":\"Athletics\"},{\"t\":3,\"n\":\"Blade\"},{\"t\":3,\"n\":\"Block\"},{\"t\":3,\"n\":\"Blunt\"},{\"t\":3,\"n\":\"Hand to Hand\"},{\"t\":3,\"n\":\"Heavy Armor\"},{\"t\":3,\"n\":\"Alchemy\"},{\"t\":3,\"n\":\"Alteration\"},{\"t\":3,\"n\":\"Conjuration\"},{\"t\":3,\"n\":\"Destruction\"},{\"t\":3,\"n\":\"Illusion\"},{\"t\":3,\"n\":\"Mysticism\"},{\"t\":3,\"n\":\"Restoration\"},{\"t\":3,\"n\":\"Acrobatics\"},{\"t\":3,\"n\":\"Light Armor\"},{\"t\":3,\"n\":\"Marksman\"},{\"t\":3,\"n\":\"Mercantile\"},{\"t\":3,\"n\":\"Security\"},{\"t\":3,\"n\":\"Sneak\"},{\"t\":3,\"n\":\"Speechcraft\"},{\"t\":3,\"n\":\"Health\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":3,\"n\":\"Strength\"},{\"t\":3,\"n\":\"Intelligence\"},{\"t\":3,\"n\":\"Willpower\"},{\"t\":3,\"n\":\"Agility\"},{\"t\":3,\"n\":\"Speed\"},{\"t\":3,\"n\":\"Endurance\"},{\"t\":3,\"n\":\"Personality\"},{\"t\":3,\"n\":\"Luck\"}]},{\"t\":3,\"p\":1,\"n\":\"HNAM - Hair\"},{\"t\":5,\"p\":1,\"n\":\"LNAM - Hair length\"},{\"t\":7,\"s\":1,\"p\":1,\"n\":\"ENAM - Eyes\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Eyes\"}]},{\"t\":6,\"p\":1,\"n\":\"HCLR - Hair color\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"p\":1,\"n\":\"Unused\"}]},{\"t\":3,\"n\":\"ZNAM - Combat Style\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"FaceGen Data\",\"c\":[{\"t\":11,\"p\":1,\"n\":\"FGGS - FaceGen Geometry-Symmetric\"},{\"t\":11,\"p\":1,\"n\":\"FGGA - FaceGen Geometry-Asymmetric\"},{\"t\":11,\"p\":1,\"n\":\"FGTS - FaceGen Texture-Symmetric\"}]},{\"t\":11,\"p\":1,\"n\":\"FNAM - Unknown\"}]}]},\"name\":\"Bash.NpcFaces\",\"hash\":\"CC68CF3A\",\"color\":255}"
  },
  {
    "path": "frontend/settings/Oblivion/Bash.NpcFacesForceFullImport.json",
    "content": "{\"records\":\"NPC_\",\"description\":\"NpcFacesForceFullImport tag from Wrye Bash.\\r\\n\\r\\nUsed when the mod modifies NPC faces, and you wish to import the unmodified subrecords as well as the modified subrecords.\",\"tree\":{\"records\":[{\"t\":1,\"p\":1,\"n\":\"NPC_ - Non-Player Character\",\"c\":[{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"n\":\"FULL - Name\"},{\"t\":6,\"n\":\"Model\",\"c\":[{\"t\":2,\"n\":\"MODL - Model Filename\"},{\"t\":5,\"n\":\"MODB - Bound Radius\"},{\"t\":11,\"n\":\"MODT - Texture Files Hashes\"}]},{\"t\":6,\"n\":\"ACBS - Configuration\",\"c\":[{\"t\":3,\"n\":\"Flags\"},{\"t\":3,\"n\":\"Base spell points\"},{\"t\":3,\"n\":\"Fatigue\"},{\"t\":3,\"n\":\"Barter gold\"},{\"t\":3,\"n\":\"Level (offset)\"},{\"t\":3,\"n\":\"Calc min\"},{\"t\":3,\"n\":\"Calc max\"}]},{\"t\":8,\"n\":\"Factions\",\"c\":[{\"t\":6,\"n\":\"SNAM - Faction\",\"c\":[{\"t\":3,\"n\":\"Faction\"},{\"t\":3,\"n\":\"Rank\"},{\"t\":11,\"n\":\"Unused\"}]}]},{\"t\":3,\"n\":\"INAM - Death item\"},{\"t\":3,\"n\":\"RNAM - Race\"},{\"t\":8,\"n\":\"Items\",\"c\":[{\"t\":6,\"n\":\"CNTO - Item\",\"c\":[{\"t\":3,\"n\":\"Item\"},{\"t\":3,\"n\":\"Count\"}]}]},{\"t\":8,\"n\":\"Spells\",\"c\":[{\"t\":3,\"n\":\"SPLO - Spell\"}]},{\"t\":3,\"n\":\"SCRI - Script\"},{\"t\":6,\"n\":\"AIDT - AI Data\",\"c\":[{\"t\":3,\"n\":\"Aggression\"},{\"t\":3,\"n\":\"Confidence\"},{\"t\":3,\"n\":\"Energy Level\"},{\"t\":3,\"n\":\"Responsibility\"},{\"t\":3,\"n\":\"Buys\\/Sells and Services\"},{\"t\":3,\"n\":\"Teaches\"},{\"t\":3,\"n\":\"Maximum training level\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":8,\"n\":\"AI Packages\",\"c\":[{\"t\":3,\"n\":\"PKID - AI Package\"}]},{\"t\":7,\"n\":\"KFFZ - Animations\",\"c\":[{\"t\":2,\"n\":\"Animation\"}]},{\"t\":3,\"n\":\"CNAM - Class\"},{\"t\":6,\"n\":\"DATA - Stats\",\"c\":[{\"t\":3,\"n\":\"Armorer\"},{\"t\":3,\"n\":\"Athletics\"},{\"t\":3,\"n\":\"Blade\"},{\"t\":3,\"n\":\"Block\"},{\"t\":3,\"n\":\"Blunt\"},{\"t\":3,\"n\":\"Hand to Hand\"},{\"t\":3,\"n\":\"Heavy Armor\"},{\"t\":3,\"n\":\"Alchemy\"},{\"t\":3,\"n\":\"Alteration\"},{\"t\":3,\"n\":\"Conjuration\"},{\"t\":3,\"n\":\"Destruction\"},{\"t\":3,\"n\":\"Illusion\"},{\"t\":3,\"n\":\"Mysticism\"},{\"t\":3,\"n\":\"Restoration\"},{\"t\":3,\"n\":\"Acrobatics\"},{\"t\":3,\"n\":\"Light Armor\"},{\"t\":3,\"n\":\"Marksman\"},{\"t\":3,\"n\":\"Mercantile\"},{\"t\":3,\"n\":\"Security\"},{\"t\":3,\"n\":\"Sneak\"},{\"t\":3,\"n\":\"Speechcraft\"},{\"t\":3,\"n\":\"Health\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":3,\"n\":\"Strength\"},{\"t\":3,\"n\":\"Intelligence\"},{\"t\":3,\"n\":\"Willpower\"},{\"t\":3,\"n\":\"Agility\"},{\"t\":3,\"n\":\"Speed\"},{\"t\":3,\"n\":\"Endurance\"},{\"t\":3,\"n\":\"Personality\"},{\"t\":3,\"n\":\"Luck\"}]},{\"t\":3,\"p\":1,\"n\":\"HNAM - Hair\",\"lt\":\"LNAM - Hair length\",\"lf\":\"FNAM - Unknown\"},{\"t\":5,\"p\":1,\"n\":\"LNAM - Hair length\",\"lt\":\"ENAM - Eyes\",\"lf\":\"HNAM - Hair\"},{\"t\":7,\"s\":1,\"p\":1,\"n\":\"ENAM - Eyes\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Eyes\"}],\"lt\":\"HCLR - Hair color\",\"lf\":\"LNAM - Hair length\"},{\"t\":6,\"p\":1,\"n\":\"HCLR - Hair color\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"p\":1,\"n\":\"Unused\"}],\"lt\":\"FaceGen Data\",\"lf\":\"ENAM - Eyes\"},{\"t\":3,\"n\":\"ZNAM - Combat Style\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"FaceGen Data\",\"c\":[{\"t\":11,\"p\":1,\"n\":\"FGGS - FaceGen Geometry-Symmetric\"},{\"t\":11,\"p\":1,\"n\":\"FGGA - FaceGen Geometry-Asymmetric\"},{\"t\":11,\"p\":1,\"n\":\"FGTS - FaceGen Texture-Symmetric\"}],\"lt\":\"FNAM - Unknown\",\"lf\":\"HCLR - Hair color\"},{\"t\":11,\"p\":1,\"n\":\"FNAM - Unknown\",\"lt\":\"HNAM - Hair\",\"lf\":\"FaceGen Data\"}]}]},\"name\":\"Bash.NpcFacesForceFullImport\",\"hash\":\"CA166AFE\",\"color\":255}"
  },
  {
    "path": "frontend/settings/Oblivion/Bash.R.AddSpells.json",
    "content": "{\"records\":\"RACE\",\"description\":\"R.AddSpells tag from Wrye Bash.\\r\\n\\r\\nUsed when the mod adds spells to racial spell list(s). Either R.ChangeSpells or R.AddSpells should be used for a plugin, not both.\",\"tree\":{\"records\":[{\"t\":1,\"p\":1,\"n\":\"RACE - Race\",\"c\":[{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"n\":\"FULL - Name\"},{\"t\":2,\"n\":\"DESC - Description\"},{\"t\":8,\"p\":1,\"n\":\"Spells\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"SPLO - Spell\"}]},{\"t\":8,\"n\":\"Relations\",\"c\":[{\"t\":6,\"n\":\"XNAM - Relation\",\"c\":[{\"t\":3,\"n\":\"Faction\"},{\"t\":3,\"n\":\"Modifier\"}]}]},{\"t\":6,\"n\":\"DATA - \",\"c\":[{\"t\":7,\"n\":\"Skill Boosts\",\"c\":[{\"t\":6,\"n\":\"Skill Boost\",\"c\":[{\"t\":3,\"n\":\"Skill\"},{\"t\":3,\"n\":\"Boost\"}]}]},{\"t\":11,\"n\":\"Unused\"},{\"t\":5,\"n\":\"Male Height\"},{\"t\":5,\"n\":\"Female Height\"},{\"t\":5,\"n\":\"Male Weight\"},{\"t\":5,\"n\":\"Female Weight\"},{\"t\":3,\"n\":\"Flags\"}]},{\"t\":6,\"n\":\"VNAM - Voice\",\"c\":[{\"t\":3,\"n\":\"Male\"},{\"t\":3,\"n\":\"Female\"}]},{\"t\":6,\"n\":\"DNAM - Default Hair\",\"c\":[{\"t\":3,\"n\":\"Male\"},{\"t\":3,\"n\":\"Female\"}]},{\"t\":3,\"n\":\"CNAM - Default Hair Color\"},{\"t\":5,\"n\":\"PNAM - FaceGen - Main clamp\"},{\"t\":5,\"n\":\"UNAM - FaceGen - Face clamp\"},{\"t\":6,\"n\":\"ATTR - Base Attributes\",\"c\":[{\"t\":6,\"n\":\"Male\",\"c\":[{\"t\":3,\"n\":\"Strength\"},{\"t\":3,\"n\":\"Intelligence\"},{\"t\":3,\"n\":\"Willpower\"},{\"t\":3,\"n\":\"Agility\"},{\"t\":3,\"n\":\"Speed\"},{\"t\":3,\"n\":\"Endurance\"},{\"t\":3,\"n\":\"Personality\"},{\"t\":3,\"n\":\"Luck\"}]},{\"t\":6,\"n\":\"Female\",\"c\":[{\"t\":3,\"n\":\"Strength\"},{\"t\":3,\"n\":\"Intelligence\"},{\"t\":3,\"n\":\"Willpower\"},{\"t\":3,\"n\":\"Agility\"},{\"t\":3,\"n\":\"Speed\"},{\"t\":3,\"n\":\"Endurance\"},{\"t\":3,\"n\":\"Personality\"},{\"t\":3,\"n\":\"Luck\"}]}]},{\"t\":6,\"n\":\"Face Data\",\"c\":[{\"n\":\"NAM0 - Face Data Marker\"},{\"t\":10,\"n\":\"Parts\",\"c\":[{\"t\":6,\"n\":\"Part\",\"c\":[{\"t\":3,\"n\":\"INDX - Index\"},{\"t\":6,\"n\":\"Model\",\"c\":[{\"t\":2,\"n\":\"MODL - Model Filename\"},{\"t\":5,\"n\":\"MODB - Bound Radius\"},{\"t\":11,\"n\":\"MODT - Texture Files Hashes\"}]},{\"t\":2,\"n\":\"ICON - Icon filename\"}]}]}]},{\"n\":\"NAM1 - Body Data Marker\"},{\"t\":6,\"n\":\"Male Body Data\",\"c\":[{\"n\":\"MNAM - Male Body Data Marker\"},{\"t\":6,\"n\":\"Model\",\"c\":[{\"t\":2,\"n\":\"MODL - Model Filename\"},{\"t\":5,\"n\":\"MODB - Bound Radius\"},{\"t\":11,\"n\":\"MODT - Texture Files Hashes\"}]},{\"t\":10,\"n\":\"Parts\",\"c\":[{\"t\":6,\"n\":\"Part\",\"c\":[{\"t\":3,\"n\":\"INDX - Index\"},{\"t\":2,\"n\":\"ICON - Icon filename\"}]}]}]},{\"t\":6,\"n\":\"Female Body Data\",\"c\":[{\"n\":\"FNAM - Female Body Data Marker\"},{\"t\":6,\"n\":\"Model\",\"c\":[{\"t\":2,\"n\":\"MODL - Model Filename\"},{\"t\":5,\"n\":\"MODB - Bound Radius\"},{\"t\":11,\"n\":\"MODT - Texture Files Hashes\"}]},{\"t\":10,\"n\":\"Parts\",\"c\":[{\"t\":6,\"n\":\"Part\",\"c\":[{\"t\":3,\"n\":\"INDX - Index\"},{\"t\":2,\"n\":\"ICON - Icon filename\"}]}]}]},{\"t\":7,\"n\":\"HNAM - Hairs\",\"c\":[{\"t\":3,\"n\":\"Hair\"}]},{\"t\":7,\"n\":\"ENAM - Eyes\",\"c\":[{\"t\":3,\"n\":\"Eye\"}]},{\"t\":6,\"n\":\"FaceGen Data\",\"c\":[{\"t\":11,\"n\":\"FGGS - FaceGen Geometry-Symmetric\"},{\"t\":11,\"n\":\"FGGA - FaceGen Geometry-Asymmetric\"},{\"t\":11,\"n\":\"FGTS - FaceGen Texture-Symmetric\"}]},{\"t\":11,\"n\":\"SNAM - Unknown\"}]}]},\"name\":\"Bash.R.AddSpells\",\"hash\":\"8BF9489F\",\"color\":255}"
  },
  {
    "path": "frontend/settings/Oblivion/Bash.R.Attributes-F.json",
    "content": "{\"records\":\"RACE\",\"description\":\"R.Attributes-F tag from Wrye Bash.\\r\\n\\r\\nUse when the mod modifies racial attributes for females.\",\"tree\":{\"records\":[{\"t\":1,\"p\":1,\"n\":\"RACE - Race\",\"c\":[{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"n\":\"FULL - Name\"},{\"t\":2,\"n\":\"DESC - Description\"},{\"t\":8,\"n\":\"Spells\",\"c\":[{\"t\":3,\"n\":\"SPLO - Spell\"}]},{\"t\":8,\"n\":\"Relations\",\"c\":[{\"t\":6,\"n\":\"XNAM - Relation\",\"c\":[{\"t\":3,\"n\":\"Faction\"},{\"t\":3,\"n\":\"Modifier\"}]}]},{\"t\":6,\"n\":\"DATA - \",\"c\":[{\"t\":7,\"n\":\"Skill Boosts\",\"c\":[{\"t\":6,\"n\":\"Skill Boost\",\"c\":[{\"t\":3,\"n\":\"Skill\"},{\"t\":3,\"n\":\"Boost\"}]}]},{\"t\":11,\"n\":\"Unused\"},{\"t\":5,\"n\":\"Male Height\"},{\"t\":5,\"n\":\"Female Height\"},{\"t\":5,\"n\":\"Male Weight\"},{\"t\":5,\"n\":\"Female Weight\"},{\"t\":3,\"n\":\"Flags\"}]},{\"t\":6,\"n\":\"VNAM - Voice\",\"c\":[{\"t\":3,\"n\":\"Male\"},{\"t\":3,\"n\":\"Female\"}]},{\"t\":6,\"n\":\"DNAM - Default Hair\",\"c\":[{\"t\":3,\"n\":\"Male\"},{\"t\":3,\"n\":\"Female\"}]},{\"t\":3,\"n\":\"CNAM - Default Hair Color\"},{\"t\":5,\"n\":\"PNAM - FaceGen - Main clamp\"},{\"t\":5,\"n\":\"UNAM - FaceGen - Face clamp\"},{\"t\":6,\"p\":1,\"n\":\"ATTR - Base Attributes\",\"c\":[{\"t\":6,\"n\":\"Male\",\"c\":[{\"t\":3,\"n\":\"Strength\"},{\"t\":3,\"n\":\"Intelligence\"},{\"t\":3,\"n\":\"Willpower\"},{\"t\":3,\"n\":\"Agility\"},{\"t\":3,\"n\":\"Speed\"},{\"t\":3,\"n\":\"Endurance\"},{\"t\":3,\"n\":\"Personality\"},{\"t\":3,\"n\":\"Luck\"}]},{\"t\":6,\"p\":1,\"n\":\"Female\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Strength\"},{\"t\":3,\"p\":1,\"n\":\"Intelligence\"},{\"t\":3,\"p\":1,\"n\":\"Willpower\"},{\"t\":3,\"p\":1,\"n\":\"Agility\"},{\"t\":3,\"p\":1,\"n\":\"Speed\"},{\"t\":3,\"p\":1,\"n\":\"Endurance\"},{\"t\":3,\"p\":1,\"n\":\"Personality\"},{\"t\":3,\"p\":1,\"n\":\"Luck\"}]}]},{\"t\":6,\"n\":\"Face Data\",\"c\":[{\"n\":\"NAM0 - Face Data Marker\"},{\"t\":10,\"n\":\"Parts\",\"c\":[{\"t\":6,\"n\":\"Part\",\"c\":[{\"t\":3,\"n\":\"INDX - Index\"},{\"t\":6,\"n\":\"Model\",\"c\":[{\"t\":2,\"n\":\"MODL - Model Filename\"},{\"t\":5,\"n\":\"MODB - Bound Radius\"},{\"t\":11,\"n\":\"MODT - Texture Files Hashes\"}]},{\"t\":2,\"n\":\"ICON - Icon filename\"}]}]}]},{\"n\":\"NAM1 - Body Data Marker\"},{\"t\":6,\"n\":\"Male Body Data\",\"c\":[{\"n\":\"MNAM - Male Body Data Marker\"},{\"t\":6,\"n\":\"Model\",\"c\":[{\"t\":2,\"n\":\"MODL - Model Filename\"},{\"t\":5,\"n\":\"MODB - Bound Radius\"},{\"t\":11,\"n\":\"MODT - Texture Files Hashes\"}]},{\"t\":10,\"n\":\"Parts\",\"c\":[{\"t\":6,\"n\":\"Part\",\"c\":[{\"t\":3,\"n\":\"INDX - Index\"},{\"t\":2,\"n\":\"ICON - Icon filename\"}]}]}]},{\"t\":6,\"n\":\"Female Body Data\",\"c\":[{\"n\":\"FNAM - Female Body Data Marker\"},{\"t\":6,\"n\":\"Model\",\"c\":[{\"t\":2,\"n\":\"MODL - Model Filename\"},{\"t\":5,\"n\":\"MODB - Bound Radius\"},{\"t\":11,\"n\":\"MODT - Texture Files Hashes\"}]},{\"t\":10,\"n\":\"Parts\",\"c\":[{\"t\":6,\"n\":\"Part\",\"c\":[{\"t\":3,\"n\":\"INDX - Index\"},{\"t\":2,\"n\":\"ICON - Icon filename\"}]}]}]},{\"t\":7,\"n\":\"HNAM - Hairs\",\"c\":[{\"t\":3,\"n\":\"Hair\"}]},{\"t\":7,\"n\":\"ENAM - Eyes\",\"c\":[{\"t\":3,\"n\":\"Eye\"}]},{\"t\":6,\"n\":\"FaceGen Data\",\"c\":[{\"t\":11,\"n\":\"FGGS - FaceGen Geometry-Symmetric\"},{\"t\":11,\"n\":\"FGGA - FaceGen Geometry-Asymmetric\"},{\"t\":11,\"n\":\"FGTS - FaceGen Texture-Symmetric\"}]},{\"t\":11,\"n\":\"SNAM - Unknown\"}]}]},\"name\":\"Bash.R.Attributes-F\",\"hash\":\"CD64505C\",\"color\":255}"
  },
  {
    "path": "frontend/settings/Oblivion/Bash.R.Attributes-M.json",
    "content": "{\"records\":\"RACE\",\"description\":\"R.Attributes-M tag from Wrye Bash.\\r\\n\\r\\nUse when the mod modifies racial attributes for males.\",\"tree\":{\"records\":[{\"t\":1,\"p\":1,\"n\":\"RACE - Race\",\"c\":[{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"n\":\"FULL - Name\"},{\"t\":2,\"n\":\"DESC - Description\"},{\"t\":8,\"n\":\"Spells\",\"c\":[{\"t\":3,\"n\":\"SPLO - Spell\"}]},{\"t\":8,\"n\":\"Relations\",\"c\":[{\"t\":6,\"n\":\"XNAM - Relation\",\"c\":[{\"t\":3,\"n\":\"Faction\"},{\"t\":3,\"n\":\"Modifier\"}]}]},{\"t\":6,\"n\":\"DATA - \",\"c\":[{\"t\":7,\"n\":\"Skill Boosts\",\"c\":[{\"t\":6,\"n\":\"Skill Boost\",\"c\":[{\"t\":3,\"n\":\"Skill\"},{\"t\":3,\"n\":\"Boost\"}]}]},{\"t\":11,\"n\":\"Unused\"},{\"t\":5,\"n\":\"Male Height\"},{\"t\":5,\"n\":\"Female Height\"},{\"t\":5,\"n\":\"Male Weight\"},{\"t\":5,\"n\":\"Female Weight\"},{\"t\":3,\"n\":\"Flags\"}]},{\"t\":6,\"n\":\"VNAM - Voice\",\"c\":[{\"t\":3,\"n\":\"Male\"},{\"t\":3,\"n\":\"Female\"}]},{\"t\":6,\"n\":\"DNAM - Default Hair\",\"c\":[{\"t\":3,\"n\":\"Male\"},{\"t\":3,\"n\":\"Female\"}]},{\"t\":3,\"n\":\"CNAM - Default Hair Color\"},{\"t\":5,\"n\":\"PNAM - FaceGen - Main clamp\"},{\"t\":5,\"n\":\"UNAM - FaceGen - Face clamp\"},{\"t\":6,\"p\":1,\"n\":\"ATTR - Base Attributes\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Male\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Strength\"},{\"t\":3,\"p\":1,\"n\":\"Intelligence\"},{\"t\":3,\"p\":1,\"n\":\"Willpower\"},{\"t\":3,\"p\":1,\"n\":\"Agility\"},{\"t\":3,\"p\":1,\"n\":\"Speed\"},{\"t\":3,\"p\":1,\"n\":\"Endurance\"},{\"t\":3,\"p\":1,\"n\":\"Personality\"},{\"t\":3,\"p\":1,\"n\":\"Luck\"}]},{\"t\":6,\"n\":\"Female\",\"c\":[{\"t\":3,\"n\":\"Strength\"},{\"t\":3,\"n\":\"Intelligence\"},{\"t\":3,\"n\":\"Willpower\"},{\"t\":3,\"n\":\"Agility\"},{\"t\":3,\"n\":\"Speed\"},{\"t\":3,\"n\":\"Endurance\"},{\"t\":3,\"n\":\"Personality\"},{\"t\":3,\"n\":\"Luck\"}]}]},{\"t\":6,\"n\":\"Face Data\",\"c\":[{\"n\":\"NAM0 - Face Data Marker\"},{\"t\":10,\"n\":\"Parts\",\"c\":[{\"t\":6,\"n\":\"Part\",\"c\":[{\"t\":3,\"n\":\"INDX - Index\"},{\"t\":6,\"n\":\"Model\",\"c\":[{\"t\":2,\"n\":\"MODL - Model Filename\"},{\"t\":5,\"n\":\"MODB - Bound Radius\"},{\"t\":11,\"n\":\"MODT - Texture Files Hashes\"}]},{\"t\":2,\"n\":\"ICON - Icon filename\"}]}]}]},{\"n\":\"NAM1 - Body Data Marker\"},{\"t\":6,\"n\":\"Male Body Data\",\"c\":[{\"n\":\"MNAM - Male Body Data Marker\"},{\"t\":6,\"n\":\"Model\",\"c\":[{\"t\":2,\"n\":\"MODL - Model Filename\"},{\"t\":5,\"n\":\"MODB - Bound Radius\"},{\"t\":11,\"n\":\"MODT - Texture Files Hashes\"}]},{\"t\":10,\"n\":\"Parts\",\"c\":[{\"t\":6,\"n\":\"Part\",\"c\":[{\"t\":3,\"n\":\"INDX - Index\"},{\"t\":2,\"n\":\"ICON - Icon filename\"}]}]}]},{\"t\":6,\"n\":\"Female Body Data\",\"c\":[{\"n\":\"FNAM - Female Body Data Marker\"},{\"t\":6,\"n\":\"Model\",\"c\":[{\"t\":2,\"n\":\"MODL - Model Filename\"},{\"t\":5,\"n\":\"MODB - Bound Radius\"},{\"t\":11,\"n\":\"MODT - Texture Files Hashes\"}]},{\"t\":10,\"n\":\"Parts\",\"c\":[{\"t\":6,\"n\":\"Part\",\"c\":[{\"t\":3,\"n\":\"INDX - Index\"},{\"t\":2,\"n\":\"ICON - Icon filename\"}]}]}]},{\"t\":7,\"n\":\"HNAM - Hairs\",\"c\":[{\"t\":3,\"n\":\"Hair\"}]},{\"t\":7,\"n\":\"ENAM - Eyes\",\"c\":[{\"t\":3,\"n\":\"Eye\"}]},{\"t\":6,\"n\":\"FaceGen Data\",\"c\":[{\"t\":11,\"n\":\"FGGS - FaceGen Geometry-Symmetric\"},{\"t\":11,\"n\":\"FGGA - FaceGen Geometry-Asymmetric\"},{\"t\":11,\"n\":\"FGTS - FaceGen Texture-Symmetric\"}]},{\"t\":11,\"n\":\"SNAM - Unknown\"}]}]},\"name\":\"Bash.R.Attributes-M\",\"hash\":\"424C5E7E\",\"color\":255}"
  },
  {
    "path": "frontend/settings/Oblivion/Bash.R.ChangeSpells.json",
    "content": "{\"records\":\"RACE\",\"description\":\"R.ChangeSpells tag from Wrye Bash.\\r\\n\\r\\nUsed when the mod modifies racial spell list(s) (beyond adding spells). Either R.ChangeSpells or R.AddSpells should be used for a plugin, not both.\",\"tree\":{\"records\":[{\"t\":1,\"p\":1,\"n\":\"RACE - Race\",\"c\":[{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"n\":\"FULL - Name\"},{\"t\":2,\"n\":\"DESC - Description\"},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Spells\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"SPLO - Spell\"}]},{\"t\":8,\"n\":\"Relations\",\"c\":[{\"t\":6,\"n\":\"XNAM - Relation\",\"c\":[{\"t\":3,\"n\":\"Faction\"},{\"t\":3,\"n\":\"Modifier\"}]}]},{\"t\":6,\"n\":\"DATA - \",\"c\":[{\"t\":7,\"n\":\"Skill Boosts\",\"c\":[{\"t\":6,\"n\":\"Skill Boost\",\"c\":[{\"t\":3,\"n\":\"Skill\"},{\"t\":3,\"n\":\"Boost\"}]}]},{\"t\":11,\"n\":\"Unused\"},{\"t\":5,\"n\":\"Male Height\"},{\"t\":5,\"n\":\"Female Height\"},{\"t\":5,\"n\":\"Male Weight\"},{\"t\":5,\"n\":\"Female Weight\"},{\"t\":3,\"n\":\"Flags\"}]},{\"t\":6,\"n\":\"VNAM - Voice\",\"c\":[{\"t\":3,\"n\":\"Male\"},{\"t\":3,\"n\":\"Female\"}]},{\"t\":6,\"n\":\"DNAM - Default Hair\",\"c\":[{\"t\":3,\"n\":\"Male\"},{\"t\":3,\"n\":\"Female\"}]},{\"t\":3,\"n\":\"CNAM - Default Hair Color\"},{\"t\":5,\"n\":\"PNAM - FaceGen - Main clamp\"},{\"t\":5,\"n\":\"UNAM - FaceGen - Face clamp\"},{\"t\":6,\"n\":\"ATTR - Base Attributes\",\"c\":[{\"t\":6,\"n\":\"Male\",\"c\":[{\"t\":3,\"n\":\"Strength\"},{\"t\":3,\"n\":\"Intelligence\"},{\"t\":3,\"n\":\"Willpower\"},{\"t\":3,\"n\":\"Agility\"},{\"t\":3,\"n\":\"Speed\"},{\"t\":3,\"n\":\"Endurance\"},{\"t\":3,\"n\":\"Personality\"},{\"t\":3,\"n\":\"Luck\"}]},{\"t\":6,\"n\":\"Female\",\"c\":[{\"t\":3,\"n\":\"Strength\"},{\"t\":3,\"n\":\"Intelligence\"},{\"t\":3,\"n\":\"Willpower\"},{\"t\":3,\"n\":\"Agility\"},{\"t\":3,\"n\":\"Speed\"},{\"t\":3,\"n\":\"Endurance\"},{\"t\":3,\"n\":\"Personality\"},{\"t\":3,\"n\":\"Luck\"}]}]},{\"t\":6,\"n\":\"Face Data\",\"c\":[{\"n\":\"NAM0 - Face Data Marker\"},{\"t\":10,\"n\":\"Parts\",\"c\":[{\"t\":6,\"n\":\"Part\",\"c\":[{\"t\":3,\"n\":\"INDX - Index\"},{\"t\":6,\"n\":\"Model\",\"c\":[{\"t\":2,\"n\":\"MODL - Model Filename\"},{\"t\":5,\"n\":\"MODB - Bound Radius\"},{\"t\":11,\"n\":\"MODT - Texture Files Hashes\"}]},{\"t\":2,\"n\":\"ICON - Icon filename\"}]}]}]},{\"n\":\"NAM1 - Body Data Marker\"},{\"t\":6,\"n\":\"Male Body Data\",\"c\":[{\"n\":\"MNAM - Male Body Data Marker\"},{\"t\":6,\"n\":\"Model\",\"c\":[{\"t\":2,\"n\":\"MODL - Model Filename\"},{\"t\":5,\"n\":\"MODB - Bound Radius\"},{\"t\":11,\"n\":\"MODT - Texture Files Hashes\"}]},{\"t\":10,\"n\":\"Parts\",\"c\":[{\"t\":6,\"n\":\"Part\",\"c\":[{\"t\":3,\"n\":\"INDX - Index\"},{\"t\":2,\"n\":\"ICON - Icon filename\"}]}]}]},{\"t\":6,\"n\":\"Female Body Data\",\"c\":[{\"n\":\"FNAM - Female Body Data Marker\"},{\"t\":6,\"n\":\"Model\",\"c\":[{\"t\":2,\"n\":\"MODL - Model Filename\"},{\"t\":5,\"n\":\"MODB - Bound Radius\"},{\"t\":11,\"n\":\"MODT - Texture Files Hashes\"}]},{\"t\":10,\"n\":\"Parts\",\"c\":[{\"t\":6,\"n\":\"Part\",\"c\":[{\"t\":3,\"n\":\"INDX - Index\"},{\"t\":2,\"n\":\"ICON - Icon filename\"}]}]}]},{\"t\":7,\"n\":\"HNAM - Hairs\",\"c\":[{\"t\":3,\"n\":\"Hair\"}]},{\"t\":7,\"n\":\"ENAM - Eyes\",\"c\":[{\"t\":3,\"n\":\"Eye\"}]},{\"t\":6,\"n\":\"FaceGen Data\",\"c\":[{\"t\":11,\"n\":\"FGGS - FaceGen Geometry-Symmetric\"},{\"t\":11,\"n\":\"FGGA - FaceGen Geometry-Asymmetric\"},{\"t\":11,\"n\":\"FGTS - FaceGen Texture-Symmetric\"}]},{\"t\":11,\"n\":\"SNAM - Unknown\"}]}]},\"name\":\"Bash.R.ChangeSpells\",\"hash\":\"0AB33E74\",\"color\":255}"
  },
  {
    "path": "frontend/settings/Oblivion/Bash.R.Description.json",
    "content": "{\"records\":\"RACE\",\"description\":\"R.Description tag from Wrye Bash.\\r\\n\\r\\nUsed when the mod modifies race descriptions.\",\"tree\":{\"records\":[{\"t\":1,\"p\":1,\"n\":\"RACE - Race\",\"c\":[{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"n\":\"FULL - Name\"},{\"t\":2,\"p\":1,\"n\":\"DESC - Description\"},{\"t\":8,\"n\":\"Spells\",\"c\":[{\"t\":3,\"n\":\"SPLO - Spell\"}]},{\"t\":8,\"n\":\"Relations\",\"c\":[{\"t\":6,\"n\":\"XNAM - Relation\",\"c\":[{\"t\":3,\"n\":\"Faction\"},{\"t\":3,\"n\":\"Modifier\"}]}]},{\"t\":6,\"n\":\"DATA - \",\"c\":[{\"t\":7,\"n\":\"Skill Boosts\",\"c\":[{\"t\":6,\"n\":\"Skill Boost\",\"c\":[{\"t\":3,\"n\":\"Skill\"},{\"t\":3,\"n\":\"Boost\"}]}]},{\"t\":11,\"n\":\"Unused\"},{\"t\":5,\"n\":\"Male Height\"},{\"t\":5,\"n\":\"Female Height\"},{\"t\":5,\"n\":\"Male Weight\"},{\"t\":5,\"n\":\"Female Weight\"},{\"t\":3,\"n\":\"Flags\"}]},{\"t\":6,\"n\":\"VNAM - Voice\",\"c\":[{\"t\":3,\"n\":\"Male\"},{\"t\":3,\"n\":\"Female\"}]},{\"t\":6,\"n\":\"DNAM - Default Hair\",\"c\":[{\"t\":3,\"n\":\"Male\"},{\"t\":3,\"n\":\"Female\"}]},{\"t\":3,\"n\":\"CNAM - Default Hair Color\"},{\"t\":5,\"n\":\"PNAM - FaceGen - Main clamp\"},{\"t\":5,\"n\":\"UNAM - FaceGen - Face clamp\"},{\"t\":6,\"n\":\"ATTR - Base Attributes\",\"c\":[{\"t\":6,\"n\":\"Male\",\"c\":[{\"t\":3,\"n\":\"Strength\"},{\"t\":3,\"n\":\"Intelligence\"},{\"t\":3,\"n\":\"Willpower\"},{\"t\":3,\"n\":\"Agility\"},{\"t\":3,\"n\":\"Speed\"},{\"t\":3,\"n\":\"Endurance\"},{\"t\":3,\"n\":\"Personality\"},{\"t\":3,\"n\":\"Luck\"}]},{\"t\":6,\"n\":\"Female\",\"c\":[{\"t\":3,\"n\":\"Strength\"},{\"t\":3,\"n\":\"Intelligence\"},{\"t\":3,\"n\":\"Willpower\"},{\"t\":3,\"n\":\"Agility\"},{\"t\":3,\"n\":\"Speed\"},{\"t\":3,\"n\":\"Endurance\"},{\"t\":3,\"n\":\"Personality\"},{\"t\":3,\"n\":\"Luck\"}]}]},{\"t\":6,\"n\":\"Face Data\",\"c\":[{\"n\":\"NAM0 - Face Data Marker\"},{\"t\":10,\"n\":\"Parts\",\"c\":[{\"t\":6,\"n\":\"Part\",\"c\":[{\"t\":3,\"n\":\"INDX - Index\"},{\"t\":6,\"n\":\"Model\",\"c\":[{\"t\":2,\"n\":\"MODL - Model Filename\"},{\"t\":5,\"n\":\"MODB - Bound Radius\"},{\"t\":11,\"n\":\"MODT - Texture Files Hashes\"}]},{\"t\":2,\"n\":\"ICON - Icon filename\"}]}]}]},{\"n\":\"NAM1 - Body Data Marker\"},{\"t\":6,\"n\":\"Male Body Data\",\"c\":[{\"n\":\"MNAM - Male Body Data Marker\"},{\"t\":6,\"n\":\"Model\",\"c\":[{\"t\":2,\"n\":\"MODL - Model Filename\"},{\"t\":5,\"n\":\"MODB - Bound Radius\"},{\"t\":11,\"n\":\"MODT - Texture Files Hashes\"}]},{\"t\":10,\"n\":\"Parts\",\"c\":[{\"t\":6,\"n\":\"Part\",\"c\":[{\"t\":3,\"n\":\"INDX - Index\"},{\"t\":2,\"n\":\"ICON - Icon filename\"}]}]}]},{\"t\":6,\"n\":\"Female Body Data\",\"c\":[{\"n\":\"FNAM - Female Body Data Marker\"},{\"t\":6,\"n\":\"Model\",\"c\":[{\"t\":2,\"n\":\"MODL - Model Filename\"},{\"t\":5,\"n\":\"MODB - Bound Radius\"},{\"t\":11,\"n\":\"MODT - Texture Files Hashes\"}]},{\"t\":10,\"n\":\"Parts\",\"c\":[{\"t\":6,\"n\":\"Part\",\"c\":[{\"t\":3,\"n\":\"INDX - Index\"},{\"t\":2,\"n\":\"ICON - Icon filename\"}]}]}]},{\"t\":7,\"n\":\"HNAM - Hairs\",\"c\":[{\"t\":3,\"n\":\"Hair\"}]},{\"t\":7,\"n\":\"ENAM - Eyes\",\"c\":[{\"t\":3,\"n\":\"Eye\"}]},{\"t\":6,\"n\":\"FaceGen Data\",\"c\":[{\"t\":11,\"n\":\"FGGS - FaceGen Geometry-Symmetric\"},{\"t\":11,\"n\":\"FGGA - FaceGen Geometry-Asymmetric\"},{\"t\":11,\"n\":\"FGTS - FaceGen Texture-Symmetric\"}]},{\"t\":11,\"n\":\"SNAM - Unknown\"}]}]},\"name\":\"Bash.R.Description\",\"hash\":\"73C945FB\",\"color\":255}"
  },
  {
    "path": "frontend/settings/Oblivion/Bash.Relations.json",
    "content": "{\"records\":\"FACT\",\"description\":\"Relations tag from Wrye Bash.\\r\\n\\r\\nUsed when the mod modifies faction relationships.\",\"tree\":{\"records\":[{\"t\":1,\"p\":1,\"n\":\"FACT - Faction\",\"c\":[{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"n\":\"FULL - Name\"},{\"t\":8,\"p\":1,\"n\":\"Relations\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"XNAM - Relation\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Faction\"},{\"t\":3,\"p\":1,\"n\":\"Modifier\"}]}]},{\"t\":3,\"n\":\"DATA - Flags\"},{\"t\":5,\"n\":\"CNAM - Crime Gold Multiplier\"},{\"t\":10,\"n\":\"Ranks\",\"c\":[{\"t\":6,\"n\":\"Rank\",\"c\":[{\"t\":3,\"n\":\"RNAM - Rank#\"},{\"t\":2,\"n\":\"MNAM - Male\"},{\"t\":2,\"n\":\"FNAM - Female\"},{\"t\":2,\"n\":\"INAM - Insignia\"}]}]}]}]},\"name\":\"Bash.Relations\",\"hash\":\"43A8A464\",\"color\":255}"
  },
  {
    "path": "frontend/settings/Oblivion/Bash.Scripts.json",
    "content": "{\"records\":\"ALCH,APPA,ARMO,BOOK,CLOT,CONT,CREA,DOOR,FLOR,FURN,INGR,KEYM,LIGH,LVLC,MISC,NPC_,QUST,SGST,SLGM,WEAP,ACTI\",\"description\":\"Scripts tag from Wrye Bash.\\r\\n\\r\\nUsed when the mod modifies item, NPC or object scripts.\",\"tree\":{\"records\":[{\"t\":1,\"p\":1,\"n\":\"ALCH - Potion\",\"c\":[{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"n\":\"OBME - Oblivion Magic Extender\",\"c\":[{\"t\":3,\"n\":\"Record Version\"},{\"t\":6,\"n\":\"OBME Version\",\"c\":[{\"t\":3,\"n\":\"Beta\"},{\"t\":3,\"n\":\"Minor\"},{\"t\":3,\"n\":\"Major\"}]},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":2,\"n\":\"FULL - Name\"},{\"t\":6,\"n\":\"Model\",\"c\":[{\"t\":2,\"n\":\"MODL - Model Filename\"},{\"t\":5,\"n\":\"MODB - Bound Radius\"},{\"t\":11,\"n\":\"MODT - Texture Files Hashes\"}]},{\"t\":2,\"n\":\"ICON - Icon filename\"},{\"t\":3,\"p\":1,\"n\":\"SCRI - Script\"},{\"t\":5,\"n\":\"DATA - Weight\"},{\"t\":6,\"n\":\"ENIT - \",\"c\":[{\"t\":3,\"n\":\"Value\"},{\"t\":3,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":8,\"n\":\"Effects\",\"c\":[{\"t\":6,\"n\":\"Effect\",\"c\":[{\"t\":3,\"n\":\"EFID - Magic effect name\"},{\"t\":6,\"n\":\"EFIT - \",\"c\":[{\"t\":3,\"n\":\"Magic effect name\"},{\"t\":3,\"n\":\"Magnitude\"},{\"t\":3,\"n\":\"Area\"},{\"t\":3,\"n\":\"Duration\"},{\"t\":3,\"n\":\"Type\"},{\"t\":3,\"n\":\"Actor Value\"}]},{\"t\":6,\"n\":\"Script effect\",\"c\":[{\"t\":6,\"n\":\"SCIT - Script effect data\",\"c\":[{\"t\":3,\"n\":\"Script effect\"},{\"t\":3,\"n\":\"Magic school\"},{\"t\":3,\"n\":\"Visual effect name\"},{\"t\":3,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":2,\"n\":\"FULL - Name\"}]}]},{\"t\":6,\"n\":\"Effects\",\"c\":[{\"t\":8,\"n\":\"Effects\",\"c\":[{\"t\":6,\"n\":\"Effect\",\"c\":[{\"t\":6,\"n\":\"EFME - Oblivion Magic Extender\",\"c\":[{\"t\":3,\"n\":\"Record Version\"},{\"t\":6,\"n\":\"OBME Version\",\"c\":[{\"t\":3,\"n\":\"Beta\"},{\"t\":3,\"n\":\"Minor\"},{\"t\":3,\"n\":\"Major\"}]},{\"t\":3,\"n\":\"EFIT Param Info\"},{\"t\":3,\"n\":\"EFIX Param Info\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":2,\"n\":\"EFID - Magic Effect Code\"},{\"t\":6,\"n\":\"EFIT - \",\"c\":[{\"t\":2,\"n\":\"Magic Effect Code\"},{\"t\":3,\"n\":\"Magnitude\"},{\"t\":3,\"n\":\"Area\"},{\"t\":3,\"n\":\"Duration\"},{\"t\":3,\"n\":\"Type\"},{\"t\":11,\"n\":\"Param #1 - Unknown Type\"},{\"t\":3,\"n\":\"Param #1 - FormID\"},{\"t\":2,\"n\":\"Param #1 - Magic Effect Code\"},{\"t\":3,\"n\":\"Param #1 - Actor Value\"}]},{\"t\":6,\"n\":\"Script effect\",\"c\":[{\"t\":6,\"n\":\"SCIT - Script effect data\",\"c\":[{\"t\":3,\"n\":\"Script effect\"},{\"t\":3,\"n\":\"Magic school\"},{\"t\":2,\"n\":\"Visual Effect Code\"},{\"t\":3,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":2,\"n\":\"FULL - Name\"}]},{\"t\":2,\"n\":\"EFII - Icon\"},{\"t\":6,\"n\":\"EFIX - \",\"c\":[{\"t\":3,\"n\":\"Override Mask\"},{\"t\":3,\"n\":\"Flags\"},{\"t\":5,\"n\":\"Base Cost\"},{\"t\":11,\"n\":\"Param #2 - Unknown Type\"},{\"t\":3,\"n\":\"Param #2 - FormID\"},{\"t\":2,\"n\":\"Param #2 - Magic Effect Code\"},{\"t\":3,\"n\":\"Param #2 - Actor Value\"}]}]}]},{\"n\":\"EFXX - Effects End Marker\"},{\"t\":2,\"n\":\"FULL - Name\"}]}]}]},{\"t\":1,\"p\":1,\"n\":\"APPA - Alchemical Apparatus\",\"c\":[{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"n\":\"FULL - Name\"},{\"t\":6,\"n\":\"Model\",\"c\":[{\"t\":2,\"n\":\"MODL - Model Filename\"},{\"t\":5,\"n\":\"MODB - Bound Radius\"},{\"t\":11,\"n\":\"MODT - Texture Files Hashes\"}]},{\"t\":2,\"n\":\"ICON - Icon filename\"},{\"t\":3,\"p\":1,\"n\":\"SCRI - Script\"},{\"t\":6,\"n\":\"DATA - \",\"c\":[{\"t\":3,\"n\":\"Type\"},{\"t\":3,\"n\":\"Value\"},{\"t\":5,\"n\":\"Weight\"},{\"t\":5,\"n\":\"Quality\"}]}]},{\"t\":1,\"p\":1,\"n\":\"ARMO - Armor\",\"c\":[{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"n\":\"FULL - Name\"},{\"t\":3,\"p\":1,\"n\":\"SCRI - Script\"},{\"t\":3,\"n\":\"ENAM - Enchantment\"},{\"t\":3,\"n\":\"ANAM - Enchantment Points\"},{\"t\":6,\"n\":\"BMDT - \",\"c\":[{\"t\":3,\"n\":\"Biped Flags\"},{\"t\":3,\"n\":\"General Flags\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"n\":\"Male biped model\",\"c\":[{\"t\":2,\"n\":\"MODL - Model Filename\"},{\"t\":5,\"n\":\"MODB - Bound Radius\"},{\"t\":11,\"n\":\"MODT - Texture Files Hashes\"}]},{\"t\":6,\"n\":\"Male world model\",\"c\":[{\"t\":2,\"n\":\"MOD2 - Model Filename\"},{\"t\":5,\"n\":\"MO2B - Bound Radius\"},{\"t\":11,\"n\":\"MO2T - Texture Files Hashes\"}]},{\"t\":2,\"n\":\"ICON - Male icon filename\"},{\"t\":6,\"n\":\"Female biped model\",\"c\":[{\"t\":2,\"n\":\"MOD3 - Model Filename\"},{\"t\":5,\"n\":\"MO3B - Bound Radius\"},{\"t\":11,\"n\":\"MO3T - Texture Files Hashes\"}]},{\"t\":6,\"n\":\"Female world model\",\"c\":[{\"t\":2,\"n\":\"MOD4 - Model Filename\"},{\"t\":5,\"n\":\"MO4B - Bound Radius\"},{\"t\":11,\"n\":\"MO4T - Texture Files Hashes\"}]},{\"t\":2,\"n\":\"ICO2 - Female icon filename\"},{\"t\":6,\"n\":\"DATA - \",\"c\":[{\"t\":3,\"n\":\"Armor\"},{\"t\":3,\"n\":\"Value\"},{\"t\":3,\"n\":\"Health\"},{\"t\":5,\"n\":\"Weight\"}]}]},{\"t\":1,\"p\":1,\"n\":\"BOOK - Book\",\"c\":[{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"n\":\"FULL - Name\"},{\"t\":6,\"n\":\"Model\",\"c\":[{\"t\":2,\"n\":\"MODL - Model Filename\"},{\"t\":5,\"n\":\"MODB - Bound Radius\"},{\"t\":11,\"n\":\"MODT - Texture Files Hashes\"}]},{\"t\":2,\"n\":\"ICON - Icon filename\"},{\"t\":3,\"p\":1,\"n\":\"SCRI - Script\"},{\"t\":3,\"n\":\"ENAM - Enchantment\"},{\"t\":3,\"n\":\"ANAM - Enchantment Points\"},{\"t\":2,\"n\":\"DESC - Description\"},{\"t\":6,\"n\":\"DATA - \",\"c\":[{\"t\":3,\"n\":\"Flags\"},{\"t\":3,\"n\":\"Teaches\"},{\"t\":3,\"n\":\"Value\"},{\"t\":5,\"n\":\"Weight\"}]}]},{\"t\":1,\"p\":1,\"n\":\"CLOT - Clothing\",\"c\":[{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"n\":\"FULL - Name\"},{\"t\":3,\"p\":1,\"n\":\"SCRI - Script\"},{\"t\":3,\"n\":\"ENAM - Enchantment\"},{\"t\":3,\"n\":\"ANAM - Enchantment Points\"},{\"t\":6,\"n\":\"BMDT - \",\"c\":[{\"t\":3,\"n\":\"Biped Flags\"},{\"t\":3,\"n\":\"General Flags\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"n\":\"Male biped model\",\"c\":[{\"t\":2,\"n\":\"MODL - Model Filename\"},{\"t\":5,\"n\":\"MODB - Bound Radius\"},{\"t\":11,\"n\":\"MODT - Texture Files Hashes\"}]},{\"t\":6,\"n\":\"Male world model\",\"c\":[{\"t\":2,\"n\":\"MOD2 - Model Filename\"},{\"t\":5,\"n\":\"MO2B - Bound Radius\"},{\"t\":11,\"n\":\"MO2T - Texture Files Hashes\"}]},{\"t\":2,\"n\":\"ICON - Male icon filename\"},{\"t\":6,\"n\":\"Female biped model\",\"c\":[{\"t\":2,\"n\":\"MOD3 - Model Filename\"},{\"t\":5,\"n\":\"MO3B - Bound Radius\"},{\"t\":11,\"n\":\"MO3T - Texture Files Hashes\"}]},{\"t\":6,\"n\":\"Female world model\",\"c\":[{\"t\":2,\"n\":\"MOD4 - Model Filename\"},{\"t\":5,\"n\":\"MO4B - Bound Radius\"},{\"t\":11,\"n\":\"MO4T - Texture Files Hashes\"}]},{\"t\":2,\"n\":\"ICO2 - Female icon filename\"},{\"t\":6,\"n\":\"DATA - \",\"c\":[{\"t\":3,\"n\":\"Value\"},{\"t\":5,\"n\":\"Weight\"}]}]},{\"t\":1,\"p\":1,\"n\":\"CONT - Container\",\"c\":[{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"n\":\"FULL - Name\"},{\"t\":6,\"n\":\"Model\",\"c\":[{\"t\":2,\"n\":\"MODL - Model Filename\"},{\"t\":5,\"n\":\"MODB - Bound Radius\"},{\"t\":11,\"n\":\"MODT - Texture Files Hashes\"}]},{\"t\":3,\"p\":1,\"n\":\"SCRI - Script\"},{\"t\":8,\"n\":\"Items\",\"c\":[{\"t\":6,\"n\":\"CNTO - Item\",\"c\":[{\"t\":3,\"n\":\"Item\"},{\"t\":3,\"n\":\"Count\"}]}]},{\"t\":6,\"n\":\"DATA - \",\"c\":[{\"t\":3,\"n\":\"Flags\"},{\"t\":5,\"n\":\"Weight\"}]},{\"t\":3,\"n\":\"SNAM - Open sound\"},{\"t\":3,\"n\":\"QNAM - Close sound\"}]},{\"t\":1,\"p\":1,\"n\":\"CREA - Creature\",\"c\":[{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"n\":\"FULL - Name\"},{\"t\":6,\"n\":\"Model\",\"c\":[{\"t\":2,\"n\":\"MODL - Model Filename\"},{\"t\":5,\"n\":\"MODB - Bound Radius\"},{\"t\":11,\"n\":\"MODT - Texture Files Hashes\"}]},{\"t\":8,\"n\":\"Items\",\"c\":[{\"t\":6,\"n\":\"CNTO - Item\",\"c\":[{\"t\":3,\"n\":\"Item\"},{\"t\":3,\"n\":\"Count\"}]}]},{\"t\":8,\"n\":\"Spells\",\"c\":[{\"t\":3,\"n\":\"SPLO - Spell\"}]},{\"t\":7,\"n\":\"NIFZ - Models\",\"c\":[{\"t\":2,\"n\":\"Model\"}]},{\"t\":11,\"n\":\"NIFT - Texture Files Hashes\"},{\"t\":6,\"n\":\"ACBS - Configuration\",\"c\":[{\"t\":3,\"n\":\"Flags\"},{\"t\":3,\"n\":\"Base spell points\"},{\"t\":3,\"n\":\"Fatigue\"},{\"t\":3,\"n\":\"Barter gold\"},{\"t\":3,\"n\":\"Level (offset)\"},{\"t\":3,\"n\":\"Calc min\"},{\"t\":3,\"n\":\"Calc max\"}]},{\"t\":8,\"n\":\"Factions\",\"c\":[{\"t\":6,\"n\":\"SNAM - Faction\",\"c\":[{\"t\":3,\"n\":\"Faction\"},{\"t\":3,\"n\":\"Rank\"},{\"t\":11,\"n\":\"Unused\"}]}]},{\"t\":3,\"n\":\"INAM - Death item\"},{\"t\":3,\"p\":1,\"n\":\"SCRI - Script\"},{\"t\":6,\"n\":\"AIDT - AI Data\",\"c\":[{\"t\":3,\"n\":\"Aggression\"},{\"t\":3,\"n\":\"Confidence\"},{\"t\":3,\"n\":\"Energy Level\"},{\"t\":3,\"n\":\"Responsibility\"},{\"t\":3,\"n\":\"Buys\\/Sells and Services\"},{\"t\":3,\"n\":\"Teaches\"},{\"t\":3,\"n\":\"Maximum training level\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":8,\"n\":\"AI Packages\",\"c\":[{\"t\":3,\"n\":\"PKID - AI Package\"}]},{\"t\":7,\"n\":\"KFFZ - Animations\",\"c\":[{\"t\":2,\"n\":\"Animation\"}]},{\"t\":6,\"n\":\"DATA - Creature Data\",\"c\":[{\"t\":3,\"n\":\"Type\"},{\"t\":3,\"n\":\"Combat Skill\"},{\"t\":3,\"n\":\"Magic Skill\"},{\"t\":3,\"n\":\"Stealth Skill\"},{\"t\":3,\"n\":\"Soul\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":3,\"n\":\"Health\"},{\"t\":3,\"n\":\"Attack Damage\"},{\"t\":3,\"n\":\"Strength\"},{\"t\":3,\"n\":\"Intelligence\"},{\"t\":3,\"n\":\"Willpower\"},{\"t\":3,\"n\":\"Agility\"},{\"t\":3,\"n\":\"Speed\"},{\"t\":3,\"n\":\"Endurance\"},{\"t\":3,\"n\":\"Personality\"},{\"t\":3,\"n\":\"Luck\"}]},{\"t\":3,\"n\":\"RNAM - Attack reach\"},{\"t\":3,\"n\":\"ZNAM - Combat Style\"},{\"t\":5,\"n\":\"TNAM - Turning Speed\"},{\"t\":5,\"n\":\"BNAM - Base Scale\"},{\"t\":5,\"n\":\"WNAM - Foot Weight\"},{\"t\":2,\"n\":\"NAM0 - Blood Spray\"},{\"t\":2,\"n\":\"NAM1 - Blood Decal\"},{\"t\":3,\"n\":\"CSCR - Inherits Sounds from\"},{\"t\":10,\"n\":\"Sound Types\",\"c\":[{\"t\":6,\"n\":\"Sound Type\",\"c\":[{\"t\":3,\"n\":\"CSDT - Type\"},{\"t\":10,\"n\":\"Sounds\",\"c\":[{\"t\":6,\"n\":\"Sound\",\"c\":[{\"t\":3,\"n\":\"CSDI - Sound\"},{\"t\":3,\"n\":\"CSDC - Sound Chance\"}]}]}]}]}]},{\"t\":1,\"p\":1,\"n\":\"DOOR - Door\",\"c\":[{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"n\":\"FULL - Name\"},{\"t\":6,\"n\":\"Model\",\"c\":[{\"t\":2,\"n\":\"MODL - Model Filename\"},{\"t\":5,\"n\":\"MODB - Bound Radius\"},{\"t\":11,\"n\":\"MODT - Texture Files Hashes\"}]},{\"t\":3,\"p\":1,\"n\":\"SCRI - Script\"},{\"t\":3,\"n\":\"SNAM - Open sound\"},{\"t\":3,\"n\":\"ANAM - Close sound\"},{\"t\":3,\"n\":\"BNAM - Loop sound\"},{\"t\":3,\"n\":\"FNAM - Flags\"},{\"t\":8,\"n\":\"Random teleport destinations\",\"c\":[{\"t\":3,\"n\":\"TNAM - Destination\"}]}]},{\"t\":1,\"p\":1,\"n\":\"FLOR - Flora\",\"c\":[{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"n\":\"FULL - Name\"},{\"t\":6,\"n\":\"Model\",\"c\":[{\"t\":2,\"n\":\"MODL - Model Filename\"},{\"t\":5,\"n\":\"MODB - Bound Radius\"},{\"t\":11,\"n\":\"MODT - Texture Files Hashes\"}]},{\"t\":3,\"p\":1,\"n\":\"SCRI - Script\"},{\"t\":3,\"n\":\"PFIG - Ingredient\"},{\"t\":6,\"n\":\"PFPC - Seasonal ingredient production\",\"c\":[{\"t\":3,\"n\":\"Spring\"},{\"t\":3,\"n\":\"Summer \"},{\"t\":3,\"n\":\"Fall\"},{\"t\":3,\"n\":\"Winter\"}]}]},{\"t\":1,\"p\":1,\"n\":\"FURN - Furniture\",\"c\":[{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"n\":\"FULL - Name\"},{\"t\":6,\"n\":\"Model\",\"c\":[{\"t\":2,\"n\":\"MODL - Model Filename\"},{\"t\":5,\"n\":\"MODB - Bound Radius\"},{\"t\":11,\"n\":\"MODT - Texture Files Hashes\"}]},{\"t\":3,\"p\":1,\"n\":\"SCRI - Script\"},{\"t\":11,\"n\":\"MNAM - Marker Flags\"}]},{\"t\":1,\"p\":1,\"n\":\"INGR - Ingredient\",\"c\":[{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"n\":\"OBME - Oblivion Magic Extender\",\"c\":[{\"t\":3,\"n\":\"Record Version\"},{\"t\":6,\"n\":\"OBME Version\",\"c\":[{\"t\":3,\"n\":\"Beta\"},{\"t\":3,\"n\":\"Minor\"},{\"t\":3,\"n\":\"Major\"}]},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":2,\"n\":\"FULL - Name\"},{\"t\":6,\"n\":\"Model\",\"c\":[{\"t\":2,\"n\":\"MODL - Model Filename\"},{\"t\":5,\"n\":\"MODB - Bound Radius\"},{\"t\":11,\"n\":\"MODT - Texture Files Hashes\"}]},{\"t\":2,\"n\":\"ICON - Icon filename\"},{\"t\":3,\"p\":1,\"n\":\"SCRI - Script\"},{\"t\":5,\"n\":\"DATA - Weight\"},{\"t\":6,\"n\":\"ENIT - \",\"c\":[{\"t\":3,\"n\":\"Value\"},{\"t\":3,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":8,\"n\":\"Effects\",\"c\":[{\"t\":6,\"n\":\"Effect\",\"c\":[{\"t\":3,\"n\":\"EFID - Magic effect name\"},{\"t\":6,\"n\":\"EFIT - \",\"c\":[{\"t\":3,\"n\":\"Magic effect name\"},{\"t\":3,\"n\":\"Magnitude\"},{\"t\":3,\"n\":\"Area\"},{\"t\":3,\"n\":\"Duration\"},{\"t\":3,\"n\":\"Type\"},{\"t\":3,\"n\":\"Actor Value\"}]},{\"t\":6,\"n\":\"Script effect\",\"c\":[{\"t\":6,\"n\":\"SCIT - Script effect data\",\"c\":[{\"t\":3,\"n\":\"Script effect\"},{\"t\":3,\"n\":\"Magic school\"},{\"t\":3,\"n\":\"Visual effect name\"},{\"t\":3,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":2,\"n\":\"FULL - Name\"}]}]},{\"t\":6,\"n\":\"Effects\",\"c\":[{\"t\":8,\"n\":\"Effects\",\"c\":[{\"t\":6,\"n\":\"Effect\",\"c\":[{\"t\":6,\"n\":\"EFME - Oblivion Magic Extender\",\"c\":[{\"t\":3,\"n\":\"Record Version\"},{\"t\":6,\"n\":\"OBME Version\",\"c\":[{\"t\":3,\"n\":\"Beta\"},{\"t\":3,\"n\":\"Minor\"},{\"t\":3,\"n\":\"Major\"}]},{\"t\":3,\"n\":\"EFIT Param Info\"},{\"t\":3,\"n\":\"EFIX Param Info\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":2,\"n\":\"EFID - Magic Effect Code\"},{\"t\":6,\"n\":\"EFIT - \",\"c\":[{\"t\":2,\"n\":\"Magic Effect Code\"},{\"t\":3,\"n\":\"Magnitude\"},{\"t\":3,\"n\":\"Area\"},{\"t\":3,\"n\":\"Duration\"},{\"t\":3,\"n\":\"Type\"},{\"t\":11,\"n\":\"Param #1 - Unknown Type\"},{\"t\":3,\"n\":\"Param #1 - FormID\"},{\"t\":2,\"n\":\"Param #1 - Magic Effect Code\"},{\"t\":3,\"n\":\"Param #1 - Actor Value\"}]},{\"t\":6,\"n\":\"Script effect\",\"c\":[{\"t\":6,\"n\":\"SCIT - Script effect data\",\"c\":[{\"t\":3,\"n\":\"Script effect\"},{\"t\":3,\"n\":\"Magic school\"},{\"t\":2,\"n\":\"Visual Effect Code\"},{\"t\":3,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":2,\"n\":\"FULL - Name\"}]},{\"t\":2,\"n\":\"EFII - Icon\"},{\"t\":6,\"n\":\"EFIX - \",\"c\":[{\"t\":3,\"n\":\"Override Mask\"},{\"t\":3,\"n\":\"Flags\"},{\"t\":5,\"n\":\"Base Cost\"},{\"t\":11,\"n\":\"Param #2 - Unknown Type\"},{\"t\":3,\"n\":\"Param #2 - FormID\"},{\"t\":2,\"n\":\"Param #2 - Magic Effect Code\"},{\"t\":3,\"n\":\"Param #2 - Actor Value\"}]}]}]},{\"n\":\"EFXX - Effects End Marker\"},{\"t\":2,\"n\":\"FULL - Name\"}]}]}]},{\"t\":1,\"p\":1,\"n\":\"KEYM - Key\",\"c\":[{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"n\":\"FULL - Name\"},{\"t\":6,\"n\":\"Model\",\"c\":[{\"t\":2,\"n\":\"MODL - Model Filename\"},{\"t\":5,\"n\":\"MODB - Bound Radius\"},{\"t\":11,\"n\":\"MODT - Texture Files Hashes\"}]},{\"t\":2,\"n\":\"ICON - Icon filename\"},{\"t\":3,\"p\":1,\"n\":\"SCRI - Script\"},{\"t\":6,\"n\":\"DATA - \",\"c\":[{\"t\":3,\"n\":\"Value\"},{\"t\":5,\"n\":\"Weight\"}]}]},{\"t\":1,\"p\":1,\"n\":\"LIGH - Light\",\"c\":[{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"n\":\"Model\",\"c\":[{\"t\":2,\"n\":\"MODL - Model Filename\"},{\"t\":5,\"n\":\"MODB - Bound Radius\"},{\"t\":11,\"n\":\"MODT - Texture Files Hashes\"}]},{\"t\":3,\"p\":1,\"n\":\"SCRI - Script\"},{\"t\":2,\"n\":\"FULL - Name\"},{\"t\":2,\"n\":\"ICON - Icon filename\"},{\"t\":6,\"n\":\"DATA - \",\"c\":[{\"t\":3,\"n\":\"Time\"},{\"t\":3,\"n\":\"Radius\"},{\"t\":6,\"n\":\"Color\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":3,\"n\":\"Unused\"}]},{\"t\":3,\"n\":\"Flags\"},{\"t\":5,\"n\":\"Falloff Exponent\"},{\"t\":5,\"n\":\"FOV\"},{\"t\":3,\"n\":\"Value\"},{\"t\":5,\"n\":\"Weight\"}]},{\"t\":5,\"n\":\"FNAM - Fade value\"},{\"t\":3,\"n\":\"SNAM - Sound\"}]},{\"t\":1,\"p\":1,\"n\":\"LVLC - Leveled Creature\",\"c\":[{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":3,\"n\":\"LVLD - Chance none\"},{\"t\":3,\"n\":\"LVLF - Flags\"},{\"t\":8,\"n\":\"Leveled List Entries\",\"c\":[{\"t\":6,\"n\":\"LVLO - Leveled List Entry\",\"c\":[{\"t\":3,\"n\":\"Level\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":3,\"n\":\"Reference\"},{\"t\":3,\"n\":\"Count\"}]}]},{\"t\":3,\"p\":1,\"n\":\"SCRI - Script\"},{\"t\":3,\"n\":\"TNAM - Creature template\"}]},{\"t\":1,\"p\":1,\"n\":\"MISC - Misc. Item\",\"c\":[{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"n\":\"FULL - Name\"},{\"t\":6,\"n\":\"Model\",\"c\":[{\"t\":2,\"n\":\"MODL - Model Filename\"},{\"t\":5,\"n\":\"MODB - Bound Radius\"},{\"t\":11,\"n\":\"MODT - Texture Files Hashes\"}]},{\"t\":2,\"n\":\"ICON - Icon filename\"},{\"t\":3,\"p\":1,\"n\":\"SCRI - Script\"},{\"t\":6,\"n\":\"DATA - \",\"c\":[{\"t\":3,\"n\":\"Value\"},{\"t\":3,\"n\":\"Actor Value\"},{\"t\":5,\"n\":\"Weight\"},{\"t\":3,\"n\":\"Group\"}]}]},{\"t\":1,\"p\":1,\"n\":\"NPC_ - Non-Player Character\",\"c\":[{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"n\":\"FULL - Name\"},{\"t\":6,\"n\":\"Model\",\"c\":[{\"t\":2,\"n\":\"MODL - Model Filename\"},{\"t\":5,\"n\":\"MODB - Bound Radius\"},{\"t\":11,\"n\":\"MODT - Texture Files Hashes\"}]},{\"t\":6,\"n\":\"ACBS - Configuration\",\"c\":[{\"t\":3,\"n\":\"Flags\"},{\"t\":3,\"n\":\"Base spell points\"},{\"t\":3,\"n\":\"Fatigue\"},{\"t\":3,\"n\":\"Barter gold\"},{\"t\":3,\"n\":\"Level (offset)\"},{\"t\":3,\"n\":\"Calc min\"},{\"t\":3,\"n\":\"Calc max\"}]},{\"t\":8,\"n\":\"Factions\",\"c\":[{\"t\":6,\"n\":\"SNAM - Faction\",\"c\":[{\"t\":3,\"n\":\"Faction\"},{\"t\":3,\"n\":\"Rank\"},{\"t\":11,\"n\":\"Unused\"}]}]},{\"t\":3,\"n\":\"INAM - Death item\"},{\"t\":3,\"n\":\"RNAM - Race\"},{\"t\":8,\"n\":\"Items\",\"c\":[{\"t\":6,\"n\":\"CNTO - Item\",\"c\":[{\"t\":3,\"n\":\"Item\"},{\"t\":3,\"n\":\"Count\"}]}]},{\"t\":8,\"n\":\"Spells\",\"c\":[{\"t\":3,\"n\":\"SPLO - Spell\"}]},{\"t\":3,\"p\":1,\"n\":\"SCRI - Script\"},{\"t\":6,\"n\":\"AIDT - AI Data\",\"c\":[{\"t\":3,\"n\":\"Aggression\"},{\"t\":3,\"n\":\"Confidence\"},{\"t\":3,\"n\":\"Energy Level\"},{\"t\":3,\"n\":\"Responsibility\"},{\"t\":3,\"n\":\"Buys\\/Sells and Services\"},{\"t\":3,\"n\":\"Teaches\"},{\"t\":3,\"n\":\"Maximum training level\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":8,\"n\":\"AI Packages\",\"c\":[{\"t\":3,\"n\":\"PKID - AI Package\"}]},{\"t\":7,\"n\":\"KFFZ - Animations\",\"c\":[{\"t\":2,\"n\":\"Animation\"}]},{\"t\":3,\"n\":\"CNAM - Class\"},{\"t\":6,\"n\":\"DATA - Stats\",\"c\":[{\"t\":3,\"n\":\"Armorer\"},{\"t\":3,\"n\":\"Athletics\"},{\"t\":3,\"n\":\"Blade\"},{\"t\":3,\"n\":\"Block\"},{\"t\":3,\"n\":\"Blunt\"},{\"t\":3,\"n\":\"Hand to Hand\"},{\"t\":3,\"n\":\"Heavy Armor\"},{\"t\":3,\"n\":\"Alchemy\"},{\"t\":3,\"n\":\"Alteration\"},{\"t\":3,\"n\":\"Conjuration\"},{\"t\":3,\"n\":\"Destruction\"},{\"t\":3,\"n\":\"Illusion\"},{\"t\":3,\"n\":\"Mysticism\"},{\"t\":3,\"n\":\"Restoration\"},{\"t\":3,\"n\":\"Acrobatics\"},{\"t\":3,\"n\":\"Light Armor\"},{\"t\":3,\"n\":\"Marksman\"},{\"t\":3,\"n\":\"Mercantile\"},{\"t\":3,\"n\":\"Security\"},{\"t\":3,\"n\":\"Sneak\"},{\"t\":3,\"n\":\"Speechcraft\"},{\"t\":3,\"n\":\"Health\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":3,\"n\":\"Strength\"},{\"t\":3,\"n\":\"Intelligence\"},{\"t\":3,\"n\":\"Willpower\"},{\"t\":3,\"n\":\"Agility\"},{\"t\":3,\"n\":\"Speed\"},{\"t\":3,\"n\":\"Endurance\"},{\"t\":3,\"n\":\"Personality\"},{\"t\":3,\"n\":\"Luck\"}]},{\"t\":3,\"n\":\"HNAM - Hair\"},{\"t\":5,\"n\":\"LNAM - Hair length\"},{\"t\":7,\"n\":\"ENAM - Eyes\",\"c\":[{\"t\":3,\"n\":\"Eyes\"}]},{\"t\":6,\"n\":\"HCLR - Hair color\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":3,\"n\":\"ZNAM - Combat Style\"},{\"t\":6,\"n\":\"FaceGen Data\",\"c\":[{\"t\":11,\"n\":\"FGGS - FaceGen Geometry-Symmetric\"},{\"t\":11,\"n\":\"FGGA - FaceGen Geometry-Asymmetric\"},{\"t\":11,\"n\":\"FGTS - FaceGen Texture-Symmetric\"}]},{\"t\":11,\"n\":\"FNAM - Unknown\"}]},{\"t\":1,\"p\":1,\"n\":\"QUST - Quest\",\"c\":[{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":3,\"p\":1,\"n\":\"SCRI - Script\"},{\"t\":2,\"n\":\"FULL - Name\"},{\"t\":2,\"n\":\"ICON - Icon filename\"},{\"t\":6,\"n\":\"DATA - General\",\"c\":[{\"t\":3,\"n\":\"Flags\"},{\"t\":3,\"n\":\"Priority\"}]},{\"t\":8,\"n\":\"Conditions\",\"c\":[{\"t\":6,\"n\":\"CTDA - Condition\",\"c\":[{\"t\":3,\"n\":\"Type\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":5,\"n\":\"Comparison Value - Float\"},{\"t\":3,\"n\":\"Comparison Value - Global\"},{\"t\":3,\"n\":\"Function\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":11,\"n\":\"None\"},{\"t\":3,\"n\":\"Integer\"},{\"t\":3,\"n\":\"Variable Name (INVALID)\"},{\"t\":3,\"n\":\"Sex\"},{\"t\":3,\"n\":\"Actor Value\"},{\"t\":3,\"n\":\"Crime Type\"},{\"t\":3,\"n\":\"Axis\"},{\"t\":3,\"n\":\"Form Type\"},{\"t\":3,\"n\":\"Quest Stage (INVALID)\"},{\"t\":3,\"n\":\"Object Reference\"},{\"t\":3,\"n\":\"Inventory Object\"},{\"t\":3,\"n\":\"Actor\"},{\"t\":3,\"n\":\"Quest\"},{\"t\":3,\"n\":\"Faction\"},{\"t\":3,\"n\":\"Cell\"},{\"t\":3,\"n\":\"Class\"},{\"t\":3,\"n\":\"Race\"},{\"t\":3,\"n\":\"Actor Base\"},{\"t\":3,\"n\":\"Global\"},{\"t\":3,\"n\":\"Weather\"},{\"t\":3,\"n\":\"Package\"},{\"t\":3,\"n\":\"Owner\"},{\"t\":3,\"n\":\"Birthsign\"},{\"t\":3,\"n\":\"Furniture\"},{\"t\":3,\"n\":\"Magic Item\"},{\"t\":3,\"n\":\"Magic Effect\"},{\"t\":3,\"n\":\"Worldspace\"},{\"t\":3,\"n\":\"Referenceable Object\"},{\"t\":3,\"n\":\"Variable Name\"},{\"t\":3,\"n\":\"Quest Stage\"}]},{\"t\":6,\"n\":\"CTDT - Condition (old format)\",\"c\":[{\"t\":3,\"n\":\"Type\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":5,\"n\":\"Comparison Value - Float\"},{\"t\":3,\"n\":\"Comparison Value - Global\"},{\"t\":3,\"n\":\"Function\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":11,\"n\":\"None\"},{\"t\":3,\"n\":\"Integer\"},{\"t\":3,\"n\":\"Variable Name (INVALID)\"},{\"t\":3,\"n\":\"Sex\"},{\"t\":3,\"n\":\"Actor Value\"},{\"t\":3,\"n\":\"Crime Type\"},{\"t\":3,\"n\":\"Axis\"},{\"t\":3,\"n\":\"Form Type\"},{\"t\":3,\"n\":\"Quest Stage (INVALID)\"},{\"t\":3,\"n\":\"Object Reference\"},{\"t\":3,\"n\":\"Inventory Object\"},{\"t\":3,\"n\":\"Actor\"},{\"t\":3,\"n\":\"Quest\"},{\"t\":3,\"n\":\"Faction\"},{\"t\":3,\"n\":\"Cell\"},{\"t\":3,\"n\":\"Class\"},{\"t\":3,\"n\":\"Race\"},{\"t\":3,\"n\":\"Actor Base\"},{\"t\":3,\"n\":\"Global\"},{\"t\":3,\"n\":\"Weather\"},{\"t\":3,\"n\":\"Package\"},{\"t\":3,\"n\":\"Owner\"},{\"t\":3,\"n\":\"Birthsign\"},{\"t\":3,\"n\":\"Furniture\"},{\"t\":3,\"n\":\"Magic Item\"},{\"t\":3,\"n\":\"Magic Effect\"},{\"t\":3,\"n\":\"Worldspace\"},{\"t\":3,\"n\":\"Referenceable Object\"},{\"t\":3,\"n\":\"Variable Name\"},{\"t\":3,\"n\":\"Quest Stage\"}]}]},{\"t\":10,\"n\":\"Stages\",\"c\":[{\"t\":6,\"n\":\"Stage\",\"c\":[{\"t\":3,\"n\":\"INDX - Stage index\"},{\"t\":8,\"n\":\"Log Entries\",\"c\":[{\"t\":6,\"n\":\"Log Entry\",\"c\":[{\"t\":3,\"n\":\"QSDT - Stage Flags\"},{\"t\":8,\"n\":\"Conditions\",\"c\":[{\"t\":6,\"n\":\"CTDA - Condition\",\"c\":[{\"t\":3,\"n\":\"Type\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":5,\"n\":\"Comparison Value - Float\"},{\"t\":3,\"n\":\"Comparison Value - Global\"},{\"t\":3,\"n\":\"Function\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":11,\"n\":\"None\"},{\"t\":3,\"n\":\"Integer\"},{\"t\":3,\"n\":\"Variable Name (INVALID)\"},{\"t\":3,\"n\":\"Sex\"},{\"t\":3,\"n\":\"Actor Value\"},{\"t\":3,\"n\":\"Crime Type\"},{\"t\":3,\"n\":\"Axis\"},{\"t\":3,\"n\":\"Form Type\"},{\"t\":3,\"n\":\"Quest Stage (INVALID)\"},{\"t\":3,\"n\":\"Object Reference\"},{\"t\":3,\"n\":\"Inventory Object\"},{\"t\":3,\"n\":\"Actor\"},{\"t\":3,\"n\":\"Quest\"},{\"t\":3,\"n\":\"Faction\"},{\"t\":3,\"n\":\"Cell\"},{\"t\":3,\"n\":\"Class\"},{\"t\":3,\"n\":\"Race\"},{\"t\":3,\"n\":\"Actor Base\"},{\"t\":3,\"n\":\"Global\"},{\"t\":3,\"n\":\"Weather\"},{\"t\":3,\"n\":\"Package\"},{\"t\":3,\"n\":\"Owner\"},{\"t\":3,\"n\":\"Birthsign\"},{\"t\":3,\"n\":\"Furniture\"},{\"t\":3,\"n\":\"Magic Item\"},{\"t\":3,\"n\":\"Magic Effect\"},{\"t\":3,\"n\":\"Worldspace\"},{\"t\":3,\"n\":\"Referenceable Object\"},{\"t\":3,\"n\":\"Variable Name\"},{\"t\":3,\"n\":\"Quest Stage\"}]},{\"t\":6,\"n\":\"CTDT - Condition (old format)\",\"c\":[{\"t\":3,\"n\":\"Type\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":5,\"n\":\"Comparison Value - Float\"},{\"t\":3,\"n\":\"Comparison Value - Global\"},{\"t\":3,\"n\":\"Function\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":11,\"n\":\"None\"},{\"t\":3,\"n\":\"Integer\"},{\"t\":3,\"n\":\"Variable Name (INVALID)\"},{\"t\":3,\"n\":\"Sex\"},{\"t\":3,\"n\":\"Actor Value\"},{\"t\":3,\"n\":\"Crime Type\"},{\"t\":3,\"n\":\"Axis\"},{\"t\":3,\"n\":\"Form Type\"},{\"t\":3,\"n\":\"Quest Stage (INVALID)\"},{\"t\":3,\"n\":\"Object Reference\"},{\"t\":3,\"n\":\"Inventory Object\"},{\"t\":3,\"n\":\"Actor\"},{\"t\":3,\"n\":\"Quest\"},{\"t\":3,\"n\":\"Faction\"},{\"t\":3,\"n\":\"Cell\"},{\"t\":3,\"n\":\"Class\"},{\"t\":3,\"n\":\"Race\"},{\"t\":3,\"n\":\"Actor Base\"},{\"t\":3,\"n\":\"Global\"},{\"t\":3,\"n\":\"Weather\"},{\"t\":3,\"n\":\"Package\"},{\"t\":3,\"n\":\"Owner\"},{\"t\":3,\"n\":\"Birthsign\"},{\"t\":3,\"n\":\"Furniture\"},{\"t\":3,\"n\":\"Magic Item\"},{\"t\":3,\"n\":\"Magic Effect\"},{\"t\":3,\"n\":\"Worldspace\"},{\"t\":3,\"n\":\"Referenceable Object\"},{\"t\":3,\"n\":\"Variable Name\"},{\"t\":3,\"n\":\"Quest Stage\"}]}]},{\"t\":2,\"n\":\"CNAM - Log Entry\"},{\"t\":6,\"n\":\"Result Script\",\"c\":[{\"t\":6,\"n\":\"SCHR - Basic Script Data\",\"c\":[{\"t\":11,\"n\":\"Unused\"},{\"t\":3,\"n\":\"RefCount\"},{\"t\":3,\"n\":\"CompiledSize\"},{\"t\":3,\"n\":\"VariableCount\"},{\"t\":3,\"n\":\"Type\"}]},{\"t\":6,\"n\":\"SCHD - Basic Script Data\",\"c\":[{\"t\":11,\"n\":\"Unused\"},{\"t\":3,\"n\":\"RefCount\"},{\"t\":3,\"n\":\"CompiledSize\"},{\"t\":3,\"n\":\"VariableCount\"},{\"t\":3,\"n\":\"Type\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":11,\"n\":\"SCDA - Compiled result script\"},{\"t\":2,\"n\":\"SCTX - Result script source\"},{\"t\":8,\"n\":\"References\",\"c\":[{\"t\":3,\"n\":\"SCRO - Global Reference\"},{\"t\":3,\"n\":\"SCRV - Local Variable\"}]}]}]}]}]}]},{\"t\":8,\"n\":\"Targets\",\"c\":[{\"t\":6,\"n\":\"Target\",\"c\":[{\"t\":6,\"n\":\"QSTA - Target\",\"c\":[{\"t\":3,\"n\":\"Target\"},{\"t\":3,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":8,\"n\":\"Conditions\",\"c\":[{\"t\":6,\"n\":\"CTDA - Condition\",\"c\":[{\"t\":3,\"n\":\"Type\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":5,\"n\":\"Comparison Value - Float\"},{\"t\":3,\"n\":\"Comparison Value - Global\"},{\"t\":3,\"n\":\"Function\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":11,\"n\":\"None\"},{\"t\":3,\"n\":\"Integer\"},{\"t\":3,\"n\":\"Variable Name (INVALID)\"},{\"t\":3,\"n\":\"Sex\"},{\"t\":3,\"n\":\"Actor Value\"},{\"t\":3,\"n\":\"Crime Type\"},{\"t\":3,\"n\":\"Axis\"},{\"t\":3,\"n\":\"Form Type\"},{\"t\":3,\"n\":\"Quest Stage (INVALID)\"},{\"t\":3,\"n\":\"Object Reference\"},{\"t\":3,\"n\":\"Inventory Object\"},{\"t\":3,\"n\":\"Actor\"},{\"t\":3,\"n\":\"Quest\"},{\"t\":3,\"n\":\"Faction\"},{\"t\":3,\"n\":\"Cell\"},{\"t\":3,\"n\":\"Class\"},{\"t\":3,\"n\":\"Race\"},{\"t\":3,\"n\":\"Actor Base\"},{\"t\":3,\"n\":\"Global\"},{\"t\":3,\"n\":\"Weather\"},{\"t\":3,\"n\":\"Package\"},{\"t\":3,\"n\":\"Owner\"},{\"t\":3,\"n\":\"Birthsign\"},{\"t\":3,\"n\":\"Furniture\"},{\"t\":3,\"n\":\"Magic Item\"},{\"t\":3,\"n\":\"Magic Effect\"},{\"t\":3,\"n\":\"Worldspace\"},{\"t\":3,\"n\":\"Referenceable Object\"},{\"t\":3,\"n\":\"Variable Name\"},{\"t\":3,\"n\":\"Quest Stage\"}]},{\"t\":6,\"n\":\"CTDT - Condition (old format)\",\"c\":[{\"t\":3,\"n\":\"Type\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":5,\"n\":\"Comparison Value - Float\"},{\"t\":3,\"n\":\"Comparison Value - Global\"},{\"t\":3,\"n\":\"Function\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":11,\"n\":\"None\"},{\"t\":3,\"n\":\"Integer\"},{\"t\":3,\"n\":\"Variable Name (INVALID)\"},{\"t\":3,\"n\":\"Sex\"},{\"t\":3,\"n\":\"Actor Value\"},{\"t\":3,\"n\":\"Crime Type\"},{\"t\":3,\"n\":\"Axis\"},{\"t\":3,\"n\":\"Form Type\"},{\"t\":3,\"n\":\"Quest Stage (INVALID)\"},{\"t\":3,\"n\":\"Object Reference\"},{\"t\":3,\"n\":\"Inventory Object\"},{\"t\":3,\"n\":\"Actor\"},{\"t\":3,\"n\":\"Quest\"},{\"t\":3,\"n\":\"Faction\"},{\"t\":3,\"n\":\"Cell\"},{\"t\":3,\"n\":\"Class\"},{\"t\":3,\"n\":\"Race\"},{\"t\":3,\"n\":\"Actor Base\"},{\"t\":3,\"n\":\"Global\"},{\"t\":3,\"n\":\"Weather\"},{\"t\":3,\"n\":\"Package\"},{\"t\":3,\"n\":\"Owner\"},{\"t\":3,\"n\":\"Birthsign\"},{\"t\":3,\"n\":\"Furniture\"},{\"t\":3,\"n\":\"Magic Item\"},{\"t\":3,\"n\":\"Magic Effect\"},{\"t\":3,\"n\":\"Worldspace\"},{\"t\":3,\"n\":\"Referenceable Object\"},{\"t\":3,\"n\":\"Variable Name\"},{\"t\":3,\"n\":\"Quest Stage\"}]}]}]}]}]},{\"t\":1,\"p\":1,\"n\":\"SGST - Sigil Stone\",\"c\":[{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"n\":\"OBME - Oblivion Magic Extender\",\"c\":[{\"t\":3,\"n\":\"Record Version\"},{\"t\":6,\"n\":\"OBME Version\",\"c\":[{\"t\":3,\"n\":\"Beta\"},{\"t\":3,\"n\":\"Minor\"},{\"t\":3,\"n\":\"Major\"}]},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":2,\"n\":\"FULL - Name\"},{\"t\":6,\"n\":\"Model\",\"c\":[{\"t\":2,\"n\":\"MODL - Model Filename\"},{\"t\":5,\"n\":\"MODB - Bound Radius\"},{\"t\":11,\"n\":\"MODT - Texture Files Hashes\"}]},{\"t\":2,\"n\":\"ICON - Icon filename\"},{\"t\":3,\"p\":1,\"n\":\"SCRI - Script\"},{\"t\":8,\"n\":\"Effects\",\"c\":[{\"t\":6,\"n\":\"Effect\",\"c\":[{\"t\":3,\"n\":\"EFID - Magic effect name\"},{\"t\":6,\"n\":\"EFIT - \",\"c\":[{\"t\":3,\"n\":\"Magic effect name\"},{\"t\":3,\"n\":\"Magnitude\"},{\"t\":3,\"n\":\"Area\"},{\"t\":3,\"n\":\"Duration\"},{\"t\":3,\"n\":\"Type\"},{\"t\":3,\"n\":\"Actor Value\"}]},{\"t\":6,\"n\":\"Script effect\",\"c\":[{\"t\":6,\"n\":\"SCIT - Script effect data\",\"c\":[{\"t\":3,\"n\":\"Script effect\"},{\"t\":3,\"n\":\"Magic school\"},{\"t\":3,\"n\":\"Visual effect name\"},{\"t\":3,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":2,\"n\":\"FULL - Name\"}]}]},{\"t\":6,\"n\":\"Effects\",\"c\":[{\"t\":8,\"n\":\"Effects\",\"c\":[{\"t\":6,\"n\":\"Effect\",\"c\":[{\"t\":6,\"n\":\"EFME - Oblivion Magic Extender\",\"c\":[{\"t\":3,\"n\":\"Record Version\"},{\"t\":6,\"n\":\"OBME Version\",\"c\":[{\"t\":3,\"n\":\"Beta\"},{\"t\":3,\"n\":\"Minor\"},{\"t\":3,\"n\":\"Major\"}]},{\"t\":3,\"n\":\"EFIT Param Info\"},{\"t\":3,\"n\":\"EFIX Param Info\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":2,\"n\":\"EFID - Magic Effect Code\"},{\"t\":6,\"n\":\"EFIT - \",\"c\":[{\"t\":2,\"n\":\"Magic Effect Code\"},{\"t\":3,\"n\":\"Magnitude\"},{\"t\":3,\"n\":\"Area\"},{\"t\":3,\"n\":\"Duration\"},{\"t\":3,\"n\":\"Type\"},{\"t\":11,\"n\":\"Param #1 - Unknown Type\"},{\"t\":3,\"n\":\"Param #1 - FormID\"},{\"t\":2,\"n\":\"Param #1 - Magic Effect Code\"},{\"t\":3,\"n\":\"Param #1 - Actor Value\"}]},{\"t\":6,\"n\":\"Script effect\",\"c\":[{\"t\":6,\"n\":\"SCIT - Script effect data\",\"c\":[{\"t\":3,\"n\":\"Script effect\"},{\"t\":3,\"n\":\"Magic school\"},{\"t\":2,\"n\":\"Visual Effect Code\"},{\"t\":3,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":2,\"n\":\"FULL - Name\"}]},{\"t\":2,\"n\":\"EFII - Icon\"},{\"t\":6,\"n\":\"EFIX - \",\"c\":[{\"t\":3,\"n\":\"Override Mask\"},{\"t\":3,\"n\":\"Flags\"},{\"t\":5,\"n\":\"Base Cost\"},{\"t\":11,\"n\":\"Param #2 - Unknown Type\"},{\"t\":3,\"n\":\"Param #2 - FormID\"},{\"t\":2,\"n\":\"Param #2 - Magic Effect Code\"},{\"t\":3,\"n\":\"Param #2 - Actor Value\"}]}]}]},{\"n\":\"EFXX - Effects End Marker\"},{\"t\":2,\"n\":\"FULL - Name\"}]}]},{\"t\":6,\"n\":\"DATA - \",\"c\":[{\"t\":3,\"n\":\"Uses \"},{\"t\":3,\"n\":\"Value\"},{\"t\":5,\"n\":\"Weight\"}]}]},{\"t\":1,\"p\":1,\"n\":\"SLGM - Soul Gem\",\"c\":[{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"n\":\"FULL - Name\"},{\"t\":6,\"n\":\"Model\",\"c\":[{\"t\":2,\"n\":\"MODL - Model Filename\"},{\"t\":5,\"n\":\"MODB - Bound Radius\"},{\"t\":11,\"n\":\"MODT - Texture Files Hashes\"}]},{\"t\":2,\"n\":\"ICON - Icon filename\"},{\"t\":3,\"p\":1,\"n\":\"SCRI - Script\"},{\"t\":6,\"n\":\"DATA - \",\"c\":[{\"t\":3,\"n\":\"Value\"},{\"t\":5,\"n\":\"Weight\"}]},{\"t\":3,\"n\":\"SOUL - Contained Soul\"},{\"t\":3,\"n\":\"SLCP - Maximum Capacity\"}]},{\"t\":1,\"p\":1,\"n\":\"WEAP - Weapon\",\"c\":[{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"n\":\"FULL - Name\"},{\"t\":6,\"n\":\"Model\",\"c\":[{\"t\":2,\"n\":\"MODL - Model Filename\"},{\"t\":5,\"n\":\"MODB - Bound Radius\"},{\"t\":11,\"n\":\"MODT - Texture Files Hashes\"}]},{\"t\":2,\"n\":\"ICON - Icon filename\"},{\"t\":3,\"p\":1,\"n\":\"SCRI - Script\"},{\"t\":3,\"n\":\"ENAM - Enchantment\"},{\"t\":3,\"n\":\"ANAM - Enchantment Points\"},{\"t\":6,\"n\":\"DATA - \",\"c\":[{\"t\":3,\"n\":\"Type\"},{\"t\":5,\"n\":\"Speed\"},{\"t\":5,\"n\":\"Reach\"},{\"t\":3,\"n\":\"Flags\"},{\"t\":3,\"n\":\"Value\"},{\"t\":3,\"n\":\"Health\"},{\"t\":5,\"n\":\"Weight\"},{\"t\":3,\"n\":\"Damage\"}]}]},{\"t\":1,\"p\":1,\"n\":\"ACTI - Activator\",\"c\":[{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"n\":\"FULL - Name\"},{\"t\":6,\"n\":\"Model\",\"c\":[{\"t\":2,\"n\":\"MODL - Model Filename\"},{\"t\":5,\"n\":\"MODB - Bound Radius\"},{\"t\":11,\"n\":\"MODT - Texture Files Hashes\"}]},{\"t\":3,\"p\":1,\"n\":\"SCRI - Script\"},{\"t\":3,\"n\":\"SNAM - Sound\"}]}]},\"name\":\"Bash.Scripts\",\"hash\":\"E3E9B7F3\",\"color\":255}"
  },
  {
    "path": "frontend/settings/Oblivion/Bash.Sound.json",
    "content": "{\"records\":\"CONT,CREA,DOOR,LIGH,MGEF,WTHR,ACTI\",\"description\":\"Sound tag from Wrye Bash.\\r\\n\\r\\nUsed when the mod replaces sounds.\",\"tree\":{\"records\":[{\"t\":1,\"p\":1,\"n\":\"CONT - Container\",\"c\":[{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"n\":\"FULL - Name\"},{\"t\":6,\"n\":\"Model\",\"c\":[{\"t\":2,\"n\":\"MODL - Model Filename\"},{\"t\":5,\"n\":\"MODB - Bound Radius\"},{\"t\":11,\"n\":\"MODT - Texture Files Hashes\"}]},{\"t\":3,\"n\":\"SCRI - Script\"},{\"t\":8,\"n\":\"Items\",\"c\":[{\"t\":6,\"n\":\"CNTO - Item\",\"c\":[{\"t\":3,\"n\":\"Item\"},{\"t\":3,\"n\":\"Count\"}]}]},{\"t\":6,\"n\":\"DATA - \",\"c\":[{\"t\":3,\"n\":\"Flags\"},{\"t\":5,\"n\":\"Weight\"}]},{\"t\":3,\"p\":1,\"n\":\"SNAM - Open sound\"},{\"t\":3,\"p\":1,\"n\":\"QNAM - Close sound\"}]},{\"t\":1,\"p\":1,\"n\":\"CREA - Creature\",\"c\":[{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"n\":\"FULL - Name\"},{\"t\":6,\"n\":\"Model\",\"c\":[{\"t\":2,\"n\":\"MODL - Model Filename\"},{\"t\":5,\"n\":\"MODB - Bound Radius\"},{\"t\":11,\"n\":\"MODT - Texture Files Hashes\"}]},{\"t\":8,\"n\":\"Items\",\"c\":[{\"t\":6,\"n\":\"CNTO - Item\",\"c\":[{\"t\":3,\"n\":\"Item\"},{\"t\":3,\"n\":\"Count\"}]}]},{\"t\":8,\"n\":\"Spells\",\"c\":[{\"t\":3,\"n\":\"SPLO - Spell\"}]},{\"t\":7,\"n\":\"NIFZ - Models\",\"c\":[{\"t\":2,\"n\":\"Model\"}]},{\"t\":11,\"n\":\"NIFT - Texture Files Hashes\"},{\"t\":6,\"n\":\"ACBS - Configuration\",\"c\":[{\"t\":3,\"n\":\"Flags\"},{\"t\":3,\"n\":\"Base spell points\"},{\"t\":3,\"n\":\"Fatigue\"},{\"t\":3,\"n\":\"Barter gold\"},{\"t\":3,\"n\":\"Level (offset)\"},{\"t\":3,\"n\":\"Calc min\"},{\"t\":3,\"n\":\"Calc max\"}]},{\"t\":8,\"n\":\"Factions\",\"c\":[{\"t\":6,\"n\":\"SNAM - Faction\",\"c\":[{\"t\":3,\"n\":\"Faction\"},{\"t\":3,\"n\":\"Rank\"},{\"t\":11,\"n\":\"Unused\"}]}]},{\"t\":3,\"n\":\"INAM - Death item\"},{\"t\":3,\"n\":\"SCRI - Script\"},{\"t\":6,\"n\":\"AIDT - AI Data\",\"c\":[{\"t\":3,\"n\":\"Aggression\"},{\"t\":3,\"n\":\"Confidence\"},{\"t\":3,\"n\":\"Energy Level\"},{\"t\":3,\"n\":\"Responsibility\"},{\"t\":3,\"n\":\"Buys\\/Sells and Services\"},{\"t\":3,\"n\":\"Teaches\"},{\"t\":3,\"n\":\"Maximum training level\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":8,\"n\":\"AI Packages\",\"c\":[{\"t\":3,\"n\":\"PKID - AI Package\"}]},{\"t\":7,\"n\":\"KFFZ - Animations\",\"c\":[{\"t\":2,\"n\":\"Animation\"}]},{\"t\":6,\"n\":\"DATA - Creature Data\",\"c\":[{\"t\":3,\"n\":\"Type\"},{\"t\":3,\"n\":\"Combat Skill\"},{\"t\":3,\"n\":\"Magic Skill\"},{\"t\":3,\"n\":\"Stealth Skill\"},{\"t\":3,\"n\":\"Soul\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":3,\"n\":\"Health\"},{\"t\":3,\"n\":\"Attack Damage\"},{\"t\":3,\"n\":\"Strength\"},{\"t\":3,\"n\":\"Intelligence\"},{\"t\":3,\"n\":\"Willpower\"},{\"t\":3,\"n\":\"Agility\"},{\"t\":3,\"n\":\"Speed\"},{\"t\":3,\"n\":\"Endurance\"},{\"t\":3,\"n\":\"Personality\"},{\"t\":3,\"n\":\"Luck\"}]},{\"t\":3,\"n\":\"RNAM - Attack reach\"},{\"t\":3,\"n\":\"ZNAM - Combat Style\"},{\"t\":5,\"n\":\"TNAM - Turning Speed\"},{\"t\":5,\"n\":\"BNAM - Base Scale\"},{\"t\":5,\"p\":1,\"n\":\"WNAM - Foot Weight\"},{\"t\":2,\"n\":\"NAM0 - Blood Spray\"},{\"t\":2,\"n\":\"NAM1 - Blood Decal\"},{\"t\":3,\"p\":1,\"n\":\"CSCR - Inherits Sounds from\"},{\"t\":10,\"s\":1,\"p\":1,\"n\":\"Sound Types\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Sound Type\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"CSDT - Type\"},{\"t\":10,\"p\":1,\"n\":\"Sounds\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Sound\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"CSDI - Sound\"},{\"t\":3,\"p\":1,\"n\":\"CSDC - Sound Chance\"}]}]}]}]}]},{\"t\":1,\"p\":1,\"n\":\"DOOR - Door\",\"c\":[{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"n\":\"FULL - Name\"},{\"t\":6,\"n\":\"Model\",\"c\":[{\"t\":2,\"n\":\"MODL - Model Filename\"},{\"t\":5,\"n\":\"MODB - Bound Radius\"},{\"t\":11,\"n\":\"MODT - Texture Files Hashes\"}]},{\"t\":3,\"n\":\"SCRI - Script\"},{\"t\":3,\"p\":1,\"n\":\"SNAM - Open sound\"},{\"t\":3,\"p\":1,\"n\":\"ANAM - Close sound\"},{\"t\":3,\"p\":1,\"n\":\"BNAM - Loop sound\"},{\"t\":3,\"n\":\"FNAM - Flags\"},{\"t\":8,\"n\":\"Random teleport destinations\",\"c\":[{\"t\":3,\"n\":\"TNAM - Destination\"}]}]},{\"t\":1,\"p\":1,\"n\":\"LIGH - Light\",\"c\":[{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"n\":\"Model\",\"c\":[{\"t\":2,\"n\":\"MODL - Model Filename\"},{\"t\":5,\"n\":\"MODB - Bound Radius\"},{\"t\":11,\"n\":\"MODT - Texture Files Hashes\"}]},{\"t\":3,\"n\":\"SCRI - Script\"},{\"t\":2,\"n\":\"FULL - Name\"},{\"t\":2,\"n\":\"ICON - Icon filename\"},{\"t\":6,\"n\":\"DATA - \",\"c\":[{\"t\":3,\"n\":\"Time\"},{\"t\":3,\"n\":\"Radius\"},{\"t\":6,\"n\":\"Color\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":3,\"n\":\"Unused\"}]},{\"t\":3,\"n\":\"Flags\"},{\"t\":5,\"n\":\"Falloff Exponent\"},{\"t\":5,\"n\":\"FOV\"},{\"t\":3,\"n\":\"Value\"},{\"t\":5,\"n\":\"Weight\"}]},{\"t\":5,\"n\":\"FNAM - Fade value\"},{\"t\":3,\"p\":1,\"n\":\"SNAM - Sound\"}]},{\"t\":1,\"p\":1,\"n\":\"MGEF - Magic Effect\",\"c\":[{\"t\":2,\"n\":\"EDID - Magic Effect Code\"},{\"t\":6,\"n\":\"OBME - Oblivion Magic Extender\",\"c\":[{\"t\":3,\"n\":\"Record Version\"},{\"t\":6,\"n\":\"OBME Version\",\"c\":[{\"t\":3,\"n\":\"Beta\"},{\"t\":3,\"n\":\"Minor\"},{\"t\":3,\"n\":\"Major\"}]},{\"t\":3,\"n\":\"Param A Info\"},{\"t\":3,\"n\":\"Param B Info\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":2,\"n\":\"Handler\"},{\"t\":3,\"n\":\"Flag Overrides\"},{\"t\":11,\"n\":\"ParamB\"}]},{\"t\":2,\"n\":\"EDDX - EditorID\"},{\"t\":2,\"n\":\"FULL - Name\"},{\"t\":2,\"n\":\"DESC - Description\"},{\"t\":2,\"n\":\"ICON - Icon filename\"},{\"t\":6,\"n\":\"Model\",\"c\":[{\"t\":2,\"n\":\"MODL - Model Filename\"},{\"t\":5,\"n\":\"MODB - Bound Radius\"},{\"t\":11,\"n\":\"MODT - Texture Files Hashes\"}]},{\"t\":6,\"p\":1,\"n\":\"DATA - Data\",\"c\":[{\"t\":3,\"n\":\"Flags\"},{\"t\":5,\"n\":\"Base cost\"},{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"n\":\"Assoc. Weapon\"},{\"t\":3,\"n\":\"Assoc. Armor\"},{\"t\":3,\"n\":\"Assoc. Creature\"},{\"t\":3,\"n\":\"Assoc. Actor Value\"},{\"t\":3,\"n\":\"Magic School\"},{\"t\":3,\"n\":\"Resist value\"},{\"t\":3,\"n\":\"Counter Effect Count\"},{\"t\":3,\"n\":\"Light\"},{\"t\":5,\"n\":\"Projectile speed\"},{\"t\":3,\"n\":\"Effect Shader\"},{\"t\":3,\"n\":\"Enchant effect\"},{\"t\":3,\"p\":1,\"n\":\"Casting sound\"},{\"t\":3,\"p\":1,\"n\":\"Bolt sound\"},{\"t\":3,\"p\":1,\"n\":\"Hit sound\"},{\"t\":3,\"p\":1,\"n\":\"Area sound\"},{\"t\":5,\"n\":\"Constant Effect enchantment factor\"},{\"t\":5,\"n\":\"Constant Effect barter factor\"}]},{\"t\":7,\"n\":\"ESCE - Counter Effects\",\"c\":[{\"t\":2,\"n\":\"Counter Effect Code\"}]}]},{\"t\":1,\"p\":1,\"n\":\"WTHR - Weather\",\"c\":[{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"n\":\"CNAM - Texture Lower Layer\"},{\"t\":2,\"n\":\"DNAM - Texture Upper Layer\"},{\"t\":6,\"n\":\"Model\",\"c\":[{\"t\":2,\"n\":\"MODL - Model Filename\"},{\"t\":5,\"n\":\"MODB - Bound Radius\"},{\"t\":11,\"n\":\"MODT - Texture Files Hashes\"}]},{\"t\":7,\"n\":\"NAM0 - Colors by Types\\/Times\",\"c\":[{\"t\":7,\"n\":\"Type\",\"c\":[{\"t\":6,\"n\":\"Time\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]}]}]},{\"t\":6,\"n\":\"FNAM - Fog Distance\",\"c\":[{\"t\":5,\"n\":\"Day Near\"},{\"t\":5,\"n\":\"Day Far\"},{\"t\":5,\"n\":\"Night Near\"},{\"t\":5,\"n\":\"Night Far\"}]},{\"t\":6,\"n\":\"HNAM - HDR Data\",\"c\":[{\"t\":5,\"n\":\"Eye Adapt Speed\"},{\"t\":5,\"n\":\"Blur Radius\"},{\"t\":5,\"n\":\"Blur Passes\"},{\"t\":5,\"n\":\"Emissive Mult\"},{\"t\":5,\"n\":\"Target LUM\"},{\"t\":5,\"n\":\"Upper LUM Clamp\"},{\"t\":5,\"n\":\"Bright Scale\"},{\"t\":5,\"n\":\"Bright Clamp\"},{\"t\":5,\"n\":\"LUM Ramp No Tex\"},{\"t\":5,\"n\":\"LUM Ramp Min\"},{\"t\":5,\"n\":\"LUM Ramp Max\"},{\"t\":5,\"n\":\"Sunlight Dimmer\"},{\"t\":5,\"n\":\"Grass Dimmer\"},{\"t\":5,\"n\":\"Tree Dimmer\"}]},{\"t\":6,\"n\":\"DATA - \",\"c\":[{\"t\":3,\"n\":\"Wind Speed\"},{\"t\":3,\"n\":\"Cloud Speed (Lower)\"},{\"t\":3,\"n\":\"Cloud Speed (Upper)\"},{\"t\":3,\"n\":\"Trans Delta\"},{\"t\":3,\"n\":\"Sun Glare\"},{\"t\":3,\"n\":\"Sun Damage\"},{\"t\":3,\"n\":\"Precipitation - Begin Fade In\"},{\"t\":3,\"n\":\"Precipitation - End Fade Out\"},{\"t\":3,\"n\":\"Thunder\\/Lightning - Begin Fade In\"},{\"t\":3,\"n\":\"Thunder\\/Lightning - End Fade Out\"},{\"t\":3,\"n\":\"Thunder\\/Lightning - Frequency\"},{\"t\":3,\"n\":\"Weather Classification\"},{\"t\":6,\"n\":\"Lightning Color\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"}]}]},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Sounds\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"SNAM - Sound\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Sound\"},{\"t\":3,\"p\":1,\"n\":\"Type\"}]}]}]},{\"t\":1,\"p\":1,\"n\":\"ACTI - Activator\",\"c\":[{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"n\":\"FULL - Name\"},{\"t\":6,\"n\":\"Model\",\"c\":[{\"t\":2,\"n\":\"MODL - Model Filename\"},{\"t\":5,\"n\":\"MODB - Bound Radius\"},{\"t\":11,\"n\":\"MODT - Texture Files Hashes\"}]},{\"t\":3,\"n\":\"SCRI - Script\"},{\"t\":3,\"p\":1,\"n\":\"SNAM - Sound\"}]}]},\"name\":\"Bash.Sound\",\"hash\":\"E24E2BAF\",\"color\":255}"
  },
  {
    "path": "frontend/settings/Oblivion/Bash.SpellStats.json",
    "content": "{\"records\":\"SPEL\",\"description\":\"SpellStats tag from Wrye Bash.\\r\\n\\r\\nUsed when the mod modifies spell stats.\",\"tree\":{\"records\":[{\"t\":1,\"p\":1,\"n\":\"SPEL - Spell\",\"c\":[{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"n\":\"OBME - Oblivion Magic Extender\",\"c\":[{\"t\":3,\"n\":\"Record Version\"},{\"t\":6,\"n\":\"OBME Version\",\"c\":[{\"t\":3,\"n\":\"Beta\"},{\"t\":3,\"n\":\"Minor\"},{\"t\":3,\"n\":\"Major\"}]},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":6,\"p\":1,\"n\":\"SPIT - \",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Cost\"},{\"t\":3,\"p\":1,\"n\":\"Level\"},{\"t\":3,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":8,\"n\":\"Effects\",\"c\":[{\"t\":6,\"n\":\"Effect\",\"c\":[{\"t\":3,\"n\":\"EFID - Magic effect name\"},{\"t\":6,\"n\":\"EFIT - \",\"c\":[{\"t\":3,\"n\":\"Magic effect name\"},{\"t\":3,\"n\":\"Magnitude\"},{\"t\":3,\"n\":\"Area\"},{\"t\":3,\"n\":\"Duration\"},{\"t\":3,\"n\":\"Type\"},{\"t\":3,\"n\":\"Actor Value\"}]},{\"t\":6,\"n\":\"Script effect\",\"c\":[{\"t\":6,\"n\":\"SCIT - Script effect data\",\"c\":[{\"t\":3,\"n\":\"Script effect\"},{\"t\":3,\"n\":\"Magic school\"},{\"t\":3,\"n\":\"Visual effect name\"},{\"t\":3,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":2,\"n\":\"FULL - Name\"}]}]},{\"t\":6,\"n\":\"Effects\",\"c\":[{\"t\":8,\"n\":\"Effects\",\"c\":[{\"t\":6,\"n\":\"Effect\",\"c\":[{\"t\":6,\"n\":\"EFME - Oblivion Magic Extender\",\"c\":[{\"t\":3,\"n\":\"Record Version\"},{\"t\":6,\"n\":\"OBME Version\",\"c\":[{\"t\":3,\"n\":\"Beta\"},{\"t\":3,\"n\":\"Minor\"},{\"t\":3,\"n\":\"Major\"}]},{\"t\":3,\"n\":\"EFIT Param Info\"},{\"t\":3,\"n\":\"EFIX Param Info\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":2,\"n\":\"EFID - Magic Effect Code\"},{\"t\":6,\"n\":\"EFIT - \",\"c\":[{\"t\":2,\"n\":\"Magic Effect Code\"},{\"t\":3,\"n\":\"Magnitude\"},{\"t\":3,\"n\":\"Area\"},{\"t\":3,\"n\":\"Duration\"},{\"t\":3,\"n\":\"Type\"},{\"t\":11,\"n\":\"Param #1 - Unknown Type\"},{\"t\":3,\"n\":\"Param #1 - FormID\"},{\"t\":2,\"n\":\"Param #1 - Magic Effect Code\"},{\"t\":3,\"n\":\"Param #1 - Actor Value\"}]},{\"t\":6,\"n\":\"Script effect\",\"c\":[{\"t\":6,\"n\":\"SCIT - Script effect data\",\"c\":[{\"t\":3,\"n\":\"Script effect\"},{\"t\":3,\"n\":\"Magic school\"},{\"t\":2,\"n\":\"Visual Effect Code\"},{\"t\":3,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":2,\"n\":\"FULL - Name\"}]},{\"t\":2,\"n\":\"EFII - Icon\"},{\"t\":6,\"n\":\"EFIX - \",\"c\":[{\"t\":3,\"n\":\"Override Mask\"},{\"t\":3,\"n\":\"Flags\"},{\"t\":5,\"n\":\"Base Cost\"},{\"t\":11,\"n\":\"Param #2 - Unknown Type\"},{\"t\":3,\"n\":\"Param #2 - FormID\"},{\"t\":2,\"n\":\"Param #2 - Magic Effect Code\"},{\"t\":3,\"n\":\"Param #2 - Actor Value\"}]}]}]},{\"n\":\"EFXX - Effects End Marker\"},{\"t\":2,\"n\":\"FULL - Name\"}]}]}]}]},\"name\":\"Bash.SpellStats\",\"hash\":\"F4C3769F\",\"color\":255}"
  },
  {
    "path": "frontend/settings/Oblivion/Bash.Stats.json",
    "content": "{\"records\":\"ALCH,APPA,ARMO,BOOK,CLOT,INGR,KEYM,LIGH,MISC,SGST,WEAP,AMMO\",\"description\":\"Stats tag from Wrye Bash.\\r\\n\\r\\nUsed when the mod modifies item stats.\",\"tree\":{\"records\":[{\"t\":1,\"p\":1,\"n\":\"ALCH - Potion\",\"c\":[{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"n\":\"OBME - Oblivion Magic Extender\",\"c\":[{\"t\":3,\"n\":\"Record Version\"},{\"t\":6,\"n\":\"OBME Version\",\"c\":[{\"t\":3,\"n\":\"Beta\"},{\"t\":3,\"n\":\"Minor\"},{\"t\":3,\"n\":\"Major\"}]},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":2,\"n\":\"FULL - Name\"},{\"t\":6,\"n\":\"Model\",\"c\":[{\"t\":2,\"n\":\"MODL - Model Filename\"},{\"t\":5,\"n\":\"MODB - Bound Radius\"},{\"t\":11,\"n\":\"MODT - Texture Files Hashes\"}]},{\"t\":2,\"n\":\"ICON - Icon filename\"},{\"t\":3,\"n\":\"SCRI - Script\"},{\"t\":5,\"p\":1,\"n\":\"DATA - Weight\"},{\"t\":6,\"p\":1,\"n\":\"ENIT - \",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Value\"},{\"t\":3,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":8,\"n\":\"Effects\",\"c\":[{\"t\":6,\"n\":\"Effect\",\"c\":[{\"t\":3,\"n\":\"EFID - Magic effect name\"},{\"t\":6,\"n\":\"EFIT - \",\"c\":[{\"t\":3,\"n\":\"Magic effect name\"},{\"t\":3,\"n\":\"Magnitude\"},{\"t\":3,\"n\":\"Area\"},{\"t\":3,\"n\":\"Duration\"},{\"t\":3,\"n\":\"Type\"},{\"t\":3,\"n\":\"Actor Value\"}]},{\"t\":6,\"n\":\"Script effect\",\"c\":[{\"t\":6,\"n\":\"SCIT - Script effect data\",\"c\":[{\"t\":3,\"n\":\"Script effect\"},{\"t\":3,\"n\":\"Magic school\"},{\"t\":3,\"n\":\"Visual effect name\"},{\"t\":3,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":2,\"n\":\"FULL - Name\"}]}]},{\"t\":6,\"n\":\"Effects\",\"c\":[{\"t\":8,\"n\":\"Effects\",\"c\":[{\"t\":6,\"n\":\"Effect\",\"c\":[{\"t\":6,\"n\":\"EFME - Oblivion Magic Extender\",\"c\":[{\"t\":3,\"n\":\"Record Version\"},{\"t\":6,\"n\":\"OBME Version\",\"c\":[{\"t\":3,\"n\":\"Beta\"},{\"t\":3,\"n\":\"Minor\"},{\"t\":3,\"n\":\"Major\"}]},{\"t\":3,\"n\":\"EFIT Param Info\"},{\"t\":3,\"n\":\"EFIX Param Info\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":2,\"n\":\"EFID - Magic Effect Code\"},{\"t\":6,\"n\":\"EFIT - \",\"c\":[{\"t\":2,\"n\":\"Magic Effect Code\"},{\"t\":3,\"n\":\"Magnitude\"},{\"t\":3,\"n\":\"Area\"},{\"t\":3,\"n\":\"Duration\"},{\"t\":3,\"n\":\"Type\"},{\"t\":11,\"n\":\"Param #1 - Unknown Type\"},{\"t\":3,\"n\":\"Param #1 - FormID\"},{\"t\":2,\"n\":\"Param #1 - Magic Effect Code\"},{\"t\":3,\"n\":\"Param #1 - Actor Value\"}]},{\"t\":6,\"n\":\"Script effect\",\"c\":[{\"t\":6,\"n\":\"SCIT - Script effect data\",\"c\":[{\"t\":3,\"n\":\"Script effect\"},{\"t\":3,\"n\":\"Magic school\"},{\"t\":2,\"n\":\"Visual Effect Code\"},{\"t\":3,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":2,\"n\":\"FULL - Name\"}]},{\"t\":2,\"n\":\"EFII - Icon\"},{\"t\":6,\"n\":\"EFIX - \",\"c\":[{\"t\":3,\"n\":\"Override Mask\"},{\"t\":3,\"n\":\"Flags\"},{\"t\":5,\"n\":\"Base Cost\"},{\"t\":11,\"n\":\"Param #2 - Unknown Type\"},{\"t\":3,\"n\":\"Param #2 - FormID\"},{\"t\":2,\"n\":\"Param #2 - Magic Effect Code\"},{\"t\":3,\"n\":\"Param #2 - Actor Value\"}]}]}]},{\"n\":\"EFXX - Effects End Marker\"},{\"t\":2,\"n\":\"FULL - Name\"}]}]}]},{\"t\":1,\"p\":1,\"n\":\"APPA - Alchemical Apparatus\",\"c\":[{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"n\":\"FULL - Name\"},{\"t\":6,\"n\":\"Model\",\"c\":[{\"t\":2,\"n\":\"MODL - Model Filename\"},{\"t\":5,\"n\":\"MODB - Bound Radius\"},{\"t\":11,\"n\":\"MODT - Texture Files Hashes\"}]},{\"t\":2,\"n\":\"ICON - Icon filename\"},{\"t\":3,\"n\":\"SCRI - Script\"},{\"t\":6,\"p\":1,\"n\":\"DATA - \",\"c\":[{\"t\":3,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Value\"},{\"t\":5,\"p\":1,\"n\":\"Weight\"},{\"t\":5,\"p\":1,\"n\":\"Quality\"}]}]},{\"t\":1,\"p\":1,\"n\":\"ARMO - Armor\",\"c\":[{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"n\":\"FULL - Name\"},{\"t\":3,\"n\":\"SCRI - Script\"},{\"t\":3,\"n\":\"ENAM - Enchantment\"},{\"t\":3,\"n\":\"ANAM - Enchantment Points\"},{\"t\":6,\"n\":\"BMDT - \",\"c\":[{\"t\":3,\"n\":\"Biped Flags\"},{\"t\":3,\"n\":\"General Flags\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"n\":\"Male biped model\",\"c\":[{\"t\":2,\"n\":\"MODL - Model Filename\"},{\"t\":5,\"n\":\"MODB - Bound Radius\"},{\"t\":11,\"n\":\"MODT - Texture Files Hashes\"}]},{\"t\":6,\"n\":\"Male world model\",\"c\":[{\"t\":2,\"n\":\"MOD2 - Model Filename\"},{\"t\":5,\"n\":\"MO2B - Bound Radius\"},{\"t\":11,\"n\":\"MO2T - Texture Files Hashes\"}]},{\"t\":2,\"n\":\"ICON - Male icon filename\"},{\"t\":6,\"n\":\"Female biped model\",\"c\":[{\"t\":2,\"n\":\"MOD3 - Model Filename\"},{\"t\":5,\"n\":\"MO3B - Bound Radius\"},{\"t\":11,\"n\":\"MO3T - Texture Files Hashes\"}]},{\"t\":6,\"n\":\"Female world model\",\"c\":[{\"t\":2,\"n\":\"MOD4 - Model Filename\"},{\"t\":5,\"n\":\"MO4B - Bound Radius\"},{\"t\":11,\"n\":\"MO4T - Texture Files Hashes\"}]},{\"t\":2,\"n\":\"ICO2 - Female icon filename\"},{\"t\":6,\"p\":1,\"n\":\"DATA - \",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Armor\"},{\"t\":3,\"p\":1,\"n\":\"Value\"},{\"t\":3,\"p\":1,\"n\":\"Health\"},{\"t\":5,\"p\":1,\"n\":\"Weight\"}]}]},{\"t\":1,\"p\":1,\"n\":\"BOOK - Book\",\"c\":[{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"n\":\"FULL - Name\"},{\"t\":6,\"n\":\"Model\",\"c\":[{\"t\":2,\"n\":\"MODL - Model Filename\"},{\"t\":5,\"n\":\"MODB - Bound Radius\"},{\"t\":11,\"n\":\"MODT - Texture Files Hashes\"}]},{\"t\":2,\"n\":\"ICON - Icon filename\"},{\"t\":3,\"n\":\"SCRI - Script\"},{\"t\":3,\"n\":\"ENAM - Enchantment\"},{\"t\":3,\"p\":1,\"n\":\"ANAM - Enchantment Points\"},{\"t\":2,\"n\":\"DESC - Description\"},{\"t\":6,\"p\":1,\"n\":\"DATA - \",\"c\":[{\"t\":3,\"n\":\"Flags\"},{\"t\":3,\"n\":\"Teaches\"},{\"t\":3,\"p\":1,\"n\":\"Value\"},{\"t\":5,\"p\":1,\"n\":\"Weight\"}]}]},{\"t\":1,\"p\":1,\"n\":\"CLOT - Clothing\",\"c\":[{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"n\":\"FULL - Name\"},{\"t\":3,\"n\":\"SCRI - Script\"},{\"t\":3,\"n\":\"ENAM - Enchantment\"},{\"t\":3,\"p\":1,\"n\":\"ANAM - Enchantment Points\"},{\"t\":6,\"n\":\"BMDT - \",\"c\":[{\"t\":3,\"n\":\"Biped Flags\"},{\"t\":3,\"n\":\"General Flags\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"n\":\"Male biped model\",\"c\":[{\"t\":2,\"n\":\"MODL - Model Filename\"},{\"t\":5,\"n\":\"MODB - Bound Radius\"},{\"t\":11,\"n\":\"MODT - Texture Files Hashes\"}]},{\"t\":6,\"n\":\"Male world model\",\"c\":[{\"t\":2,\"n\":\"MOD2 - Model Filename\"},{\"t\":5,\"n\":\"MO2B - Bound Radius\"},{\"t\":11,\"n\":\"MO2T - Texture Files Hashes\"}]},{\"t\":2,\"n\":\"ICON - Male icon filename\"},{\"t\":6,\"n\":\"Female biped model\",\"c\":[{\"t\":2,\"n\":\"MOD3 - Model Filename\"},{\"t\":5,\"n\":\"MO3B - Bound Radius\"},{\"t\":11,\"n\":\"MO3T - Texture Files Hashes\"}]},{\"t\":6,\"n\":\"Female world model\",\"c\":[{\"t\":2,\"n\":\"MOD4 - Model Filename\"},{\"t\":5,\"n\":\"MO4B - Bound Radius\"},{\"t\":11,\"n\":\"MO4T - Texture Files Hashes\"}]},{\"t\":2,\"n\":\"ICO2 - Female icon filename\"},{\"t\":6,\"p\":1,\"n\":\"DATA - \",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Value\"},{\"t\":5,\"p\":1,\"n\":\"Weight\"}]}]},{\"t\":1,\"p\":1,\"n\":\"INGR - Ingredient\",\"c\":[{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"n\":\"OBME - Oblivion Magic Extender\",\"c\":[{\"t\":3,\"n\":\"Record Version\"},{\"t\":6,\"n\":\"OBME Version\",\"c\":[{\"t\":3,\"n\":\"Beta\"},{\"t\":3,\"n\":\"Minor\"},{\"t\":3,\"n\":\"Major\"}]},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":2,\"n\":\"FULL - Name\"},{\"t\":6,\"n\":\"Model\",\"c\":[{\"t\":2,\"n\":\"MODL - Model Filename\"},{\"t\":5,\"n\":\"MODB - Bound Radius\"},{\"t\":11,\"n\":\"MODT - Texture Files Hashes\"}]},{\"t\":2,\"n\":\"ICON - Icon filename\"},{\"t\":3,\"n\":\"SCRI - Script\"},{\"t\":5,\"p\":1,\"n\":\"DATA - Weight\"},{\"t\":6,\"p\":1,\"n\":\"ENIT - \",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Value\"},{\"t\":3,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":8,\"n\":\"Effects\",\"c\":[{\"t\":6,\"n\":\"Effect\",\"c\":[{\"t\":3,\"n\":\"EFID - Magic effect name\"},{\"t\":6,\"n\":\"EFIT - \",\"c\":[{\"t\":3,\"n\":\"Magic effect name\"},{\"t\":3,\"n\":\"Magnitude\"},{\"t\":3,\"n\":\"Area\"},{\"t\":3,\"n\":\"Duration\"},{\"t\":3,\"n\":\"Type\"},{\"t\":3,\"n\":\"Actor Value\"}]},{\"t\":6,\"n\":\"Script effect\",\"c\":[{\"t\":6,\"n\":\"SCIT - Script effect data\",\"c\":[{\"t\":3,\"n\":\"Script effect\"},{\"t\":3,\"n\":\"Magic school\"},{\"t\":3,\"n\":\"Visual effect name\"},{\"t\":3,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":2,\"n\":\"FULL - Name\"}]}]},{\"t\":6,\"n\":\"Effects\",\"c\":[{\"t\":8,\"n\":\"Effects\",\"c\":[{\"t\":6,\"n\":\"Effect\",\"c\":[{\"t\":6,\"n\":\"EFME - Oblivion Magic Extender\",\"c\":[{\"t\":3,\"n\":\"Record Version\"},{\"t\":6,\"n\":\"OBME Version\",\"c\":[{\"t\":3,\"n\":\"Beta\"},{\"t\":3,\"n\":\"Minor\"},{\"t\":3,\"n\":\"Major\"}]},{\"t\":3,\"n\":\"EFIT Param Info\"},{\"t\":3,\"n\":\"EFIX Param Info\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":2,\"n\":\"EFID - Magic Effect Code\"},{\"t\":6,\"n\":\"EFIT - \",\"c\":[{\"t\":2,\"n\":\"Magic Effect Code\"},{\"t\":3,\"n\":\"Magnitude\"},{\"t\":3,\"n\":\"Area\"},{\"t\":3,\"n\":\"Duration\"},{\"t\":3,\"n\":\"Type\"},{\"t\":11,\"n\":\"Param #1 - Unknown Type\"},{\"t\":3,\"n\":\"Param #1 - FormID\"},{\"t\":2,\"n\":\"Param #1 - Magic Effect Code\"},{\"t\":3,\"n\":\"Param #1 - Actor Value\"}]},{\"t\":6,\"n\":\"Script effect\",\"c\":[{\"t\":6,\"n\":\"SCIT - Script effect data\",\"c\":[{\"t\":3,\"n\":\"Script effect\"},{\"t\":3,\"n\":\"Magic school\"},{\"t\":2,\"n\":\"Visual Effect Code\"},{\"t\":3,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":2,\"n\":\"FULL - Name\"}]},{\"t\":2,\"n\":\"EFII - Icon\"},{\"t\":6,\"n\":\"EFIX - \",\"c\":[{\"t\":3,\"n\":\"Override Mask\"},{\"t\":3,\"n\":\"Flags\"},{\"t\":5,\"n\":\"Base Cost\"},{\"t\":11,\"n\":\"Param #2 - Unknown Type\"},{\"t\":3,\"n\":\"Param #2 - FormID\"},{\"t\":2,\"n\":\"Param #2 - Magic Effect Code\"},{\"t\":3,\"n\":\"Param #2 - Actor Value\"}]}]}]},{\"n\":\"EFXX - Effects End Marker\"},{\"t\":2,\"n\":\"FULL - Name\"}]}]}]},{\"t\":1,\"p\":1,\"n\":\"KEYM - Key\",\"c\":[{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"n\":\"FULL - Name\"},{\"t\":6,\"n\":\"Model\",\"c\":[{\"t\":2,\"n\":\"MODL - Model Filename\"},{\"t\":5,\"n\":\"MODB - Bound Radius\"},{\"t\":11,\"n\":\"MODT - Texture Files Hashes\"}]},{\"t\":2,\"n\":\"ICON - Icon filename\"},{\"t\":3,\"n\":\"SCRI - Script\"},{\"t\":6,\"p\":1,\"n\":\"DATA - \",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Value\"},{\"t\":5,\"p\":1,\"n\":\"Weight\"}]}]},{\"t\":1,\"p\":1,\"n\":\"LIGH - Light\",\"c\":[{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"n\":\"Model\",\"c\":[{\"t\":2,\"n\":\"MODL - Model Filename\"},{\"t\":5,\"n\":\"MODB - Bound Radius\"},{\"t\":11,\"n\":\"MODT - Texture Files Hashes\"}]},{\"t\":3,\"n\":\"SCRI - Script\"},{\"t\":2,\"n\":\"FULL - Name\"},{\"t\":2,\"n\":\"ICON - Icon filename\"},{\"t\":6,\"p\":1,\"n\":\"DATA - \",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Time\"},{\"t\":3,\"n\":\"Radius\"},{\"t\":6,\"n\":\"Color\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":3,\"n\":\"Unused\"}]},{\"t\":3,\"n\":\"Flags\"},{\"t\":5,\"n\":\"Falloff Exponent\"},{\"t\":5,\"n\":\"FOV\"},{\"t\":3,\"p\":1,\"n\":\"Value\"},{\"t\":5,\"p\":1,\"n\":\"Weight\"}]},{\"t\":5,\"n\":\"FNAM - Fade value\"},{\"t\":3,\"n\":\"SNAM - Sound\"}]},{\"t\":1,\"p\":1,\"n\":\"MISC - Misc. Item\",\"c\":[{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"n\":\"FULL - Name\"},{\"t\":6,\"n\":\"Model\",\"c\":[{\"t\":2,\"n\":\"MODL - Model Filename\"},{\"t\":5,\"n\":\"MODB - Bound Radius\"},{\"t\":11,\"n\":\"MODT - Texture Files Hashes\"}]},{\"t\":2,\"n\":\"ICON - Icon filename\"},{\"t\":3,\"n\":\"SCRI - Script\"},{\"t\":6,\"p\":1,\"n\":\"DATA - \",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Value\"},{\"t\":3,\"n\":\"Actor Value\"},{\"t\":5,\"p\":1,\"n\":\"Weight\"},{\"t\":3,\"n\":\"Group\"}]}]},{\"t\":1,\"p\":1,\"n\":\"SGST - Sigil Stone\",\"c\":[{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"n\":\"OBME - Oblivion Magic Extender\",\"c\":[{\"t\":3,\"n\":\"Record Version\"},{\"t\":6,\"n\":\"OBME Version\",\"c\":[{\"t\":3,\"n\":\"Beta\"},{\"t\":3,\"n\":\"Minor\"},{\"t\":3,\"n\":\"Major\"}]},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":2,\"n\":\"FULL - Name\"},{\"t\":6,\"n\":\"Model\",\"c\":[{\"t\":2,\"n\":\"MODL - Model Filename\"},{\"t\":5,\"n\":\"MODB - Bound Radius\"},{\"t\":11,\"n\":\"MODT - Texture Files Hashes\"}]},{\"t\":2,\"n\":\"ICON - Icon filename\"},{\"t\":3,\"n\":\"SCRI - Script\"},{\"t\":8,\"n\":\"Effects\",\"c\":[{\"t\":6,\"n\":\"Effect\",\"c\":[{\"t\":3,\"n\":\"EFID - Magic effect name\"},{\"t\":6,\"n\":\"EFIT - \",\"c\":[{\"t\":3,\"n\":\"Magic effect name\"},{\"t\":3,\"n\":\"Magnitude\"},{\"t\":3,\"n\":\"Area\"},{\"t\":3,\"n\":\"Duration\"},{\"t\":3,\"n\":\"Type\"},{\"t\":3,\"n\":\"Actor Value\"}]},{\"t\":6,\"n\":\"Script effect\",\"c\":[{\"t\":6,\"n\":\"SCIT - Script effect data\",\"c\":[{\"t\":3,\"n\":\"Script effect\"},{\"t\":3,\"n\":\"Magic school\"},{\"t\":3,\"n\":\"Visual effect name\"},{\"t\":3,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":2,\"n\":\"FULL - Name\"}]}]},{\"t\":6,\"n\":\"Effects\",\"c\":[{\"t\":8,\"n\":\"Effects\",\"c\":[{\"t\":6,\"n\":\"Effect\",\"c\":[{\"t\":6,\"n\":\"EFME - Oblivion Magic Extender\",\"c\":[{\"t\":3,\"n\":\"Record Version\"},{\"t\":6,\"n\":\"OBME Version\",\"c\":[{\"t\":3,\"n\":\"Beta\"},{\"t\":3,\"n\":\"Minor\"},{\"t\":3,\"n\":\"Major\"}]},{\"t\":3,\"n\":\"EFIT Param Info\"},{\"t\":3,\"n\":\"EFIX Param Info\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":2,\"n\":\"EFID - Magic Effect Code\"},{\"t\":6,\"n\":\"EFIT - \",\"c\":[{\"t\":2,\"n\":\"Magic Effect Code\"},{\"t\":3,\"n\":\"Magnitude\"},{\"t\":3,\"n\":\"Area\"},{\"t\":3,\"n\":\"Duration\"},{\"t\":3,\"n\":\"Type\"},{\"t\":11,\"n\":\"Param #1 - Unknown Type\"},{\"t\":3,\"n\":\"Param #1 - FormID\"},{\"t\":2,\"n\":\"Param #1 - Magic Effect Code\"},{\"t\":3,\"n\":\"Param #1 - Actor Value\"}]},{\"t\":6,\"n\":\"Script effect\",\"c\":[{\"t\":6,\"n\":\"SCIT - Script effect data\",\"c\":[{\"t\":3,\"n\":\"Script effect\"},{\"t\":3,\"n\":\"Magic school\"},{\"t\":2,\"n\":\"Visual Effect Code\"},{\"t\":3,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":2,\"n\":\"FULL - Name\"}]},{\"t\":2,\"n\":\"EFII - Icon\"},{\"t\":6,\"n\":\"EFIX - \",\"c\":[{\"t\":3,\"n\":\"Override Mask\"},{\"t\":3,\"n\":\"Flags\"},{\"t\":5,\"n\":\"Base Cost\"},{\"t\":11,\"n\":\"Param #2 - Unknown Type\"},{\"t\":3,\"n\":\"Param #2 - FormID\"},{\"t\":2,\"n\":\"Param #2 - Magic Effect Code\"},{\"t\":3,\"n\":\"Param #2 - Actor Value\"}]}]}]},{\"n\":\"EFXX - Effects End Marker\"},{\"t\":2,\"n\":\"FULL - Name\"}]}]},{\"t\":6,\"p\":1,\"n\":\"DATA - \",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Uses \"},{\"t\":3,\"p\":1,\"n\":\"Value\"},{\"t\":5,\"p\":1,\"n\":\"Weight\"}]}]},{\"t\":1,\"p\":1,\"n\":\"WEAP - Weapon\",\"c\":[{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"n\":\"FULL - Name\"},{\"t\":6,\"n\":\"Model\",\"c\":[{\"t\":2,\"n\":\"MODL - Model Filename\"},{\"t\":5,\"n\":\"MODB - Bound Radius\"},{\"t\":11,\"n\":\"MODT - Texture Files Hashes\"}]},{\"t\":2,\"n\":\"ICON - Icon filename\"},{\"t\":3,\"n\":\"SCRI - Script\"},{\"t\":3,\"n\":\"ENAM - Enchantment\"},{\"t\":3,\"p\":1,\"n\":\"ANAM - Enchantment Points\"},{\"t\":6,\"p\":1,\"n\":\"DATA - \",\"c\":[{\"t\":3,\"n\":\"Type\"},{\"t\":5,\"p\":1,\"n\":\"Speed\"},{\"t\":5,\"p\":1,\"n\":\"Reach\"},{\"t\":3,\"n\":\"Flags\"},{\"t\":3,\"p\":1,\"n\":\"Value\"},{\"t\":3,\"p\":1,\"n\":\"Health\"},{\"t\":5,\"p\":1,\"n\":\"Weight\"},{\"t\":3,\"p\":1,\"n\":\"Damage\"}]}]},{\"t\":1,\"p\":1,\"n\":\"AMMO - Ammunition\",\"c\":[{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"n\":\"FULL - Name\"},{\"t\":6,\"n\":\"Model\",\"c\":[{\"t\":2,\"n\":\"MODL - Model Filename\"},{\"t\":5,\"n\":\"MODB - Bound Radius\"},{\"t\":11,\"n\":\"MODT - Texture Files Hashes\"}]},{\"t\":2,\"n\":\"ICON - Icon filename\"},{\"t\":3,\"n\":\"ENAM - Enchantment\"},{\"t\":3,\"p\":1,\"n\":\"ANAM - Enchantment Points\"},{\"t\":6,\"p\":1,\"n\":\"DATA - \",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Speed\"},{\"t\":3,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Value\"},{\"t\":5,\"p\":1,\"n\":\"Weight\"},{\"t\":3,\"p\":1,\"n\":\"Damage\"}]}]}]},\"name\":\"Bash.Stats\",\"hash\":\"3AA18F73\",\"color\":255}"
  },
  {
    "path": "frontend/settings/Oblivion/Bash.Voice-F.json",
    "content": "{\"records\":\"RACE\",\"description\":\"Voice-F tag from Wrye Bash.\\r\\n\\r\\nUsed when the mod modifies female voice definitions.\",\"tree\":{\"records\":[{\"t\":1,\"p\":1,\"n\":\"RACE - Race\",\"c\":[{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"n\":\"FULL - Name\"},{\"t\":2,\"n\":\"DESC - Description\"},{\"t\":8,\"n\":\"Spells\",\"c\":[{\"t\":3,\"n\":\"SPLO - Spell\"}]},{\"t\":8,\"n\":\"Relations\",\"c\":[{\"t\":6,\"n\":\"XNAM - Relation\",\"c\":[{\"t\":3,\"n\":\"Faction\"},{\"t\":3,\"n\":\"Modifier\"}]}]},{\"t\":6,\"n\":\"DATA - \",\"c\":[{\"t\":7,\"n\":\"Skill Boosts\",\"c\":[{\"t\":6,\"n\":\"Skill Boost\",\"c\":[{\"t\":3,\"n\":\"Skill\"},{\"t\":3,\"n\":\"Boost\"}]}]},{\"t\":11,\"n\":\"Unused\"},{\"t\":5,\"n\":\"Male Height\"},{\"t\":5,\"n\":\"Female Height\"},{\"t\":5,\"n\":\"Male Weight\"},{\"t\":5,\"n\":\"Female Weight\"},{\"t\":3,\"n\":\"Flags\"}]},{\"t\":6,\"p\":1,\"n\":\"VNAM - Voice\",\"c\":[{\"t\":3,\"n\":\"Male\"},{\"t\":3,\"p\":1,\"n\":\"Female\"}]},{\"t\":6,\"n\":\"DNAM - Default Hair\",\"c\":[{\"t\":3,\"n\":\"Male\"},{\"t\":3,\"n\":\"Female\"}]},{\"t\":3,\"n\":\"CNAM - Default Hair Color\"},{\"t\":5,\"n\":\"PNAM - FaceGen - Main clamp\"},{\"t\":5,\"n\":\"UNAM - FaceGen - Face clamp\"},{\"t\":6,\"n\":\"ATTR - Base Attributes\",\"c\":[{\"t\":6,\"n\":\"Male\",\"c\":[{\"t\":3,\"n\":\"Strength\"},{\"t\":3,\"n\":\"Intelligence\"},{\"t\":3,\"n\":\"Willpower\"},{\"t\":3,\"n\":\"Agility\"},{\"t\":3,\"n\":\"Speed\"},{\"t\":3,\"n\":\"Endurance\"},{\"t\":3,\"n\":\"Personality\"},{\"t\":3,\"n\":\"Luck\"}]},{\"t\":6,\"n\":\"Female\",\"c\":[{\"t\":3,\"n\":\"Strength\"},{\"t\":3,\"n\":\"Intelligence\"},{\"t\":3,\"n\":\"Willpower\"},{\"t\":3,\"n\":\"Agility\"},{\"t\":3,\"n\":\"Speed\"},{\"t\":3,\"n\":\"Endurance\"},{\"t\":3,\"n\":\"Personality\"},{\"t\":3,\"n\":\"Luck\"}]}]},{\"t\":6,\"n\":\"Face Data\",\"c\":[{\"n\":\"NAM0 - Face Data Marker\"},{\"t\":10,\"n\":\"Parts\",\"c\":[{\"t\":6,\"n\":\"Part\",\"c\":[{\"t\":3,\"n\":\"INDX - Index\"},{\"t\":6,\"n\":\"Model\",\"c\":[{\"t\":2,\"n\":\"MODL - Model Filename\"},{\"t\":5,\"n\":\"MODB - Bound Radius\"},{\"t\":11,\"n\":\"MODT - Texture Files Hashes\"}]},{\"t\":2,\"n\":\"ICON - Icon filename\"}]}]}]},{\"n\":\"NAM1 - Body Data Marker\"},{\"t\":6,\"n\":\"Male Body Data\",\"c\":[{\"n\":\"MNAM - Male Body Data Marker\"},{\"t\":6,\"n\":\"Model\",\"c\":[{\"t\":2,\"n\":\"MODL - Model Filename\"},{\"t\":5,\"n\":\"MODB - Bound Radius\"},{\"t\":11,\"n\":\"MODT - Texture Files Hashes\"}]},{\"t\":10,\"n\":\"Parts\",\"c\":[{\"t\":6,\"n\":\"Part\",\"c\":[{\"t\":3,\"n\":\"INDX - Index\"},{\"t\":2,\"n\":\"ICON - Icon filename\"}]}]}]},{\"t\":6,\"n\":\"Female Body Data\",\"c\":[{\"n\":\"FNAM - Female Body Data Marker\"},{\"t\":6,\"n\":\"Model\",\"c\":[{\"t\":2,\"n\":\"MODL - Model Filename\"},{\"t\":5,\"n\":\"MODB - Bound Radius\"},{\"t\":11,\"n\":\"MODT - Texture Files Hashes\"}]},{\"t\":10,\"n\":\"Parts\",\"c\":[{\"t\":6,\"n\":\"Part\",\"c\":[{\"t\":3,\"n\":\"INDX - Index\"},{\"t\":2,\"n\":\"ICON - Icon filename\"}]}]}]},{\"t\":7,\"n\":\"HNAM - Hairs\",\"c\":[{\"t\":3,\"n\":\"Hair\"}]},{\"t\":7,\"n\":\"ENAM - Eyes\",\"c\":[{\"t\":3,\"n\":\"Eye\"}]},{\"t\":6,\"n\":\"FaceGen Data\",\"c\":[{\"t\":11,\"n\":\"FGGS - FaceGen Geometry-Symmetric\"},{\"t\":11,\"n\":\"FGGA - FaceGen Geometry-Asymmetric\"},{\"t\":11,\"n\":\"FGTS - FaceGen Texture-Symmetric\"}]},{\"t\":11,\"n\":\"SNAM - Unknown\"}]}]},\"name\":\"Bash.Voice-F\",\"hash\":\"A74B2831\",\"color\":255}"
  },
  {
    "path": "frontend/settings/Oblivion/Bash.Voice-M.json",
    "content": "{\"records\":\"RACE\",\"description\":\"Voice-M tag from Wrye Bash.\\r\\n\\r\\nUsed when the mod modifies male voice definitions.\",\"tree\":{\"records\":[{\"t\":1,\"p\":1,\"n\":\"RACE - Race\",\"c\":[{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"n\":\"FULL - Name\"},{\"t\":2,\"n\":\"DESC - Description\"},{\"t\":8,\"n\":\"Spells\",\"c\":[{\"t\":3,\"n\":\"SPLO - Spell\"}]},{\"t\":8,\"n\":\"Relations\",\"c\":[{\"t\":6,\"n\":\"XNAM - Relation\",\"c\":[{\"t\":3,\"n\":\"Faction\"},{\"t\":3,\"n\":\"Modifier\"}]}]},{\"t\":6,\"n\":\"DATA - \",\"c\":[{\"t\":7,\"n\":\"Skill Boosts\",\"c\":[{\"t\":6,\"n\":\"Skill Boost\",\"c\":[{\"t\":3,\"n\":\"Skill\"},{\"t\":3,\"n\":\"Boost\"}]}]},{\"t\":11,\"n\":\"Unused\"},{\"t\":5,\"n\":\"Male Height\"},{\"t\":5,\"n\":\"Female Height\"},{\"t\":5,\"n\":\"Male Weight\"},{\"t\":5,\"n\":\"Female Weight\"},{\"t\":3,\"n\":\"Flags\"}]},{\"t\":6,\"p\":1,\"n\":\"VNAM - Voice\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Male\"},{\"t\":3,\"n\":\"Female\"}]},{\"t\":6,\"n\":\"DNAM - Default Hair\",\"c\":[{\"t\":3,\"n\":\"Male\"},{\"t\":3,\"n\":\"Female\"}]},{\"t\":3,\"n\":\"CNAM - Default Hair Color\"},{\"t\":5,\"n\":\"PNAM - FaceGen - Main clamp\"},{\"t\":5,\"n\":\"UNAM - FaceGen - Face clamp\"},{\"t\":6,\"n\":\"ATTR - Base Attributes\",\"c\":[{\"t\":6,\"n\":\"Male\",\"c\":[{\"t\":3,\"n\":\"Strength\"},{\"t\":3,\"n\":\"Intelligence\"},{\"t\":3,\"n\":\"Willpower\"},{\"t\":3,\"n\":\"Agility\"},{\"t\":3,\"n\":\"Speed\"},{\"t\":3,\"n\":\"Endurance\"},{\"t\":3,\"n\":\"Personality\"},{\"t\":3,\"n\":\"Luck\"}]},{\"t\":6,\"n\":\"Female\",\"c\":[{\"t\":3,\"n\":\"Strength\"},{\"t\":3,\"n\":\"Intelligence\"},{\"t\":3,\"n\":\"Willpower\"},{\"t\":3,\"n\":\"Agility\"},{\"t\":3,\"n\":\"Speed\"},{\"t\":3,\"n\":\"Endurance\"},{\"t\":3,\"n\":\"Personality\"},{\"t\":3,\"n\":\"Luck\"}]}]},{\"t\":6,\"n\":\"Face Data\",\"c\":[{\"n\":\"NAM0 - Face Data Marker\"},{\"t\":10,\"n\":\"Parts\",\"c\":[{\"t\":6,\"n\":\"Part\",\"c\":[{\"t\":3,\"n\":\"INDX - Index\"},{\"t\":6,\"n\":\"Model\",\"c\":[{\"t\":2,\"n\":\"MODL - Model Filename\"},{\"t\":5,\"n\":\"MODB - Bound Radius\"},{\"t\":11,\"n\":\"MODT - Texture Files Hashes\"}]},{\"t\":2,\"n\":\"ICON - Icon filename\"}]}]}]},{\"n\":\"NAM1 - Body Data Marker\"},{\"t\":6,\"n\":\"Male Body Data\",\"c\":[{\"n\":\"MNAM - Male Body Data Marker\"},{\"t\":6,\"n\":\"Model\",\"c\":[{\"t\":2,\"n\":\"MODL - Model Filename\"},{\"t\":5,\"n\":\"MODB - Bound Radius\"},{\"t\":11,\"n\":\"MODT - Texture Files Hashes\"}]},{\"t\":10,\"n\":\"Parts\",\"c\":[{\"t\":6,\"n\":\"Part\",\"c\":[{\"t\":3,\"n\":\"INDX - Index\"},{\"t\":2,\"n\":\"ICON - Icon filename\"}]}]}]},{\"t\":6,\"n\":\"Female Body Data\",\"c\":[{\"n\":\"FNAM - Female Body Data Marker\"},{\"t\":6,\"n\":\"Model\",\"c\":[{\"t\":2,\"n\":\"MODL - Model Filename\"},{\"t\":5,\"n\":\"MODB - Bound Radius\"},{\"t\":11,\"n\":\"MODT - Texture Files Hashes\"}]},{\"t\":10,\"n\":\"Parts\",\"c\":[{\"t\":6,\"n\":\"Part\",\"c\":[{\"t\":3,\"n\":\"INDX - Index\"},{\"t\":2,\"n\":\"ICON - Icon filename\"}]}]}]},{\"t\":7,\"n\":\"HNAM - Hairs\",\"c\":[{\"t\":3,\"n\":\"Hair\"}]},{\"t\":7,\"n\":\"ENAM - Eyes\",\"c\":[{\"t\":3,\"n\":\"Eye\"}]},{\"t\":6,\"n\":\"FaceGen Data\",\"c\":[{\"t\":11,\"n\":\"FGGS - FaceGen Geometry-Symmetric\"},{\"t\":11,\"n\":\"FGGA - FaceGen Geometry-Asymmetric\"},{\"t\":11,\"n\":\"FGTS - FaceGen Texture-Symmetric\"}]},{\"t\":11,\"n\":\"SNAM - Unknown\"}]}]},\"name\":\"Bash.Voice-M\",\"hash\":\"DEBE38B3\",\"color\":255}"
  },
  {
    "path": "frontend/settings/Oblivion/Smash.All.json",
    "content": "{\"records\":\"ACRE,ACTI,ALCH,AMMO,ANIO,APPA,ARMO,BOOK,BSGN,CELL,CLAS,CLMT,CLOT,CONT,CREA,CSTY,DIAL,DOOR,EFSH,ENCH,EYES,FACT,FLOR,FURN,GLOB,GMST,GRAS,HAIR,INFO,INGR,KEYM,LAND,LIGH,LSCR,LTEX,LVLC,LVLI,LVSP,MGEF,MISC,NPC_,PACK,PGRD,QUST,RACE,REFR,REGN,ROAD,SBSP,SCPT,SGST,SKIL,SLGM,SOUN,SPEL,STAT,TREE,WATR,WEAP,WRLD,WTHR,ACHR\",\"description\":\"Smashes all the things.  Produced using autoset attributes on all record types found in oblivion.esm and DLCs.\\r\\n\\r\\nLast updated 05\\/01\\/2018.\",\"tree\":{\"records\":[{\"t\":1,\"p\":1,\"n\":\"ACRE - Placed Creature\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":3,\"p\":1,\"n\":\"NAME - Base\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Ownership\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"XOWN - Owner\"},{\"t\":3,\"p\":1,\"n\":\"XRNK - Faction rank\"},{\"t\":3,\"p\":1,\"n\":\"XGLB - Global variable\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"XESP - Enable Parent\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":11,\"n\":\"XRGD - Ragdoll Data\"},{\"t\":5,\"p\":1,\"n\":\"XSCL - Scale\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DATA - Position\\/Rotation\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Position\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"X\"},{\"t\":5,\"p\":1,\"n\":\"Y\"},{\"t\":5,\"p\":1,\"n\":\"Z\"}]},{\"t\":6,\"p\":1,\"n\":\"Rotation\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"X\"},{\"t\":5,\"p\":1,\"n\":\"Y\"},{\"t\":5,\"p\":1,\"n\":\"Z\"}]}]}]},{\"t\":1,\"p\":1,\"n\":\"ACTI - Activator\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"},{\"t\":5,\"p\":1,\"n\":\"MODB - Bound Radius\"},{\"t\":11,\"p\":1,\"n\":\"MODT - Texture Files Hashes\"}]},{\"t\":3,\"p\":1,\"n\":\"SCRI - Script\"},{\"t\":3,\"p\":1,\"n\":\"SNAM - Sound\"}]},{\"t\":1,\"p\":1,\"n\":\"ALCH - Potion\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"OBME - Oblivion Magic Extender\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Record Version\"},{\"t\":6,\"p\":1,\"n\":\"OBME Version\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Beta\"},{\"t\":3,\"p\":1,\"n\":\"Minor\"},{\"t\":3,\"p\":1,\"n\":\"Major\"}]},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"},{\"t\":5,\"p\":1,\"n\":\"MODB - Bound Radius\"},{\"t\":11,\"p\":1,\"n\":\"MODT - Texture Files Hashes\"}]},{\"t\":2,\"p\":1,\"n\":\"ICON - Icon filename\"},{\"t\":3,\"p\":1,\"n\":\"SCRI - Script\"},{\"t\":5,\"p\":1,\"n\":\"DATA - Weight\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"ENIT - \",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Value\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Effects\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Effect\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"EFID - Magic effect name\"},{\"t\":6,\"p\":1,\"n\":\"EFIT - \",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Magic effect name\"},{\"t\":3,\"p\":1,\"n\":\"Magnitude\"},{\"t\":3,\"p\":1,\"n\":\"Area\"},{\"t\":3,\"p\":1,\"n\":\"Duration\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Actor Value\"}]},{\"t\":6,\"p\":1,\"n\":\"Script effect\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"SCIT - Script effect data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Script effect\"},{\"t\":3,\"p\":1,\"n\":\"Magic school\"},{\"t\":3,\"p\":1,\"n\":\"Visual effect name\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"}]}]},{\"t\":6,\"p\":1,\"n\":\"Effects\",\"c\":[{\"t\":8,\"p\":1,\"n\":\"Effects\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Effect\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"EFME - Oblivion Magic Extender\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Record Version\"},{\"t\":6,\"p\":1,\"n\":\"OBME Version\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Beta\"},{\"t\":3,\"p\":1,\"n\":\"Minor\"},{\"t\":3,\"p\":1,\"n\":\"Major\"}]},{\"t\":3,\"p\":1,\"n\":\"EFIT Param Info\"},{\"t\":3,\"p\":1,\"n\":\"EFIX Param Info\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":2,\"p\":1,\"n\":\"EFID - Magic Effect Code\"},{\"t\":6,\"p\":1,\"n\":\"EFIT - \",\"c\":[{\"t\":2,\"p\":1,\"n\":\"Magic Effect Code\"},{\"t\":3,\"p\":1,\"n\":\"Magnitude\"},{\"t\":3,\"p\":1,\"n\":\"Area\"},{\"t\":3,\"p\":1,\"n\":\"Duration\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":11,\"n\":\"Param #1 - Unknown Type\"},{\"t\":3,\"p\":1,\"n\":\"Param #1 - FormID\"},{\"t\":2,\"p\":1,\"n\":\"Param #1 - Magic Effect Code\"},{\"t\":3,\"p\":1,\"n\":\"Param #1 - Actor Value\"}]},{\"t\":6,\"p\":1,\"n\":\"Script effect\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"SCIT - Script effect data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Script effect\"},{\"t\":3,\"p\":1,\"n\":\"Magic school\"},{\"t\":2,\"p\":1,\"n\":\"Visual Effect Code\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"}]},{\"t\":2,\"p\":1,\"n\":\"EFII - Icon\"},{\"t\":6,\"p\":1,\"n\":\"EFIX - \",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Override Mask\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":5,\"p\":1,\"n\":\"Base Cost\"},{\"t\":11,\"n\":\"Param #2 - Unknown Type\"},{\"t\":3,\"p\":1,\"n\":\"Param #2 - FormID\"},{\"t\":2,\"p\":1,\"n\":\"Param #2 - Magic Effect Code\"},{\"t\":3,\"p\":1,\"n\":\"Param #2 - Actor Value\"}]}]}]},{\"p\":1,\"n\":\"EFXX - Effects End Marker\"},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"}]}]}]},{\"t\":1,\"p\":1,\"n\":\"AMMO - Ammunition\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"},{\"t\":5,\"p\":1,\"n\":\"MODB - Bound Radius\"},{\"t\":11,\"p\":1,\"n\":\"MODT - Texture Files Hashes\"}]},{\"t\":2,\"p\":1,\"n\":\"ICON - Icon filename\"},{\"t\":3,\"p\":1,\"n\":\"ENAM - Enchantment\"},{\"t\":3,\"p\":1,\"n\":\"ANAM - Enchantment Points\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DATA - \",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Speed\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Value\"},{\"t\":5,\"p\":1,\"n\":\"Weight\"},{\"t\":3,\"p\":1,\"n\":\"Damage\"}]}]},{\"t\":1,\"p\":1,\"n\":\"ANIO - Animated Object\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"},{\"t\":5,\"p\":1,\"n\":\"MODB - Bound Radius\"},{\"t\":11,\"p\":1,\"n\":\"MODT - Texture Files Hashes\"}]},{\"t\":3,\"p\":1,\"n\":\"DATA - IDLE animation\"}]},{\"t\":1,\"p\":1,\"n\":\"APPA - Alchemical Apparatus\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"},{\"t\":5,\"p\":1,\"n\":\"MODB - Bound Radius\"},{\"t\":11,\"p\":1,\"n\":\"MODT - Texture Files Hashes\"}]},{\"t\":2,\"p\":1,\"n\":\"ICON - Icon filename\"},{\"t\":3,\"p\":1,\"n\":\"SCRI - Script\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DATA - \",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Value\"},{\"t\":5,\"p\":1,\"n\":\"Weight\"},{\"t\":5,\"p\":1,\"n\":\"Quality\"}]}]},{\"t\":1,\"p\":1,\"n\":\"ARMO - Armor\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":3,\"p\":1,\"n\":\"SCRI - Script\"},{\"t\":3,\"p\":1,\"n\":\"ENAM - Enchantment\"},{\"t\":3,\"p\":1,\"n\":\"ANAM - Enchantment Points\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"BMDT - \",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Biped Flags\"},{\"t\":3,\"p\":1,\"n\":\"General Flags\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Male biped model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"},{\"t\":5,\"p\":1,\"n\":\"MODB - Bound Radius\"},{\"t\":11,\"p\":1,\"n\":\"MODT - Texture Files Hashes\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Male world model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MOD2 - Model Filename\"},{\"t\":5,\"p\":1,\"n\":\"MO2B - Bound Radius\"},{\"t\":11,\"p\":1,\"n\":\"MO2T - Texture Files Hashes\"}]},{\"t\":2,\"p\":1,\"n\":\"ICON - Male icon filename\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Female biped model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MOD3 - Model Filename\"},{\"t\":5,\"p\":1,\"n\":\"MO3B - Bound Radius\"},{\"t\":11,\"p\":1,\"n\":\"MO3T - Texture Files Hashes\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Female world model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MOD4 - Model Filename\"},{\"t\":5,\"p\":1,\"n\":\"MO4B - Bound Radius\"},{\"t\":11,\"p\":1,\"n\":\"MO4T - Texture Files Hashes\"}]},{\"t\":2,\"p\":1,\"n\":\"ICO2 - Female icon filename\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DATA - \",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Armor\"},{\"t\":3,\"p\":1,\"n\":\"Value\"},{\"t\":3,\"p\":1,\"n\":\"Health\"},{\"t\":5,\"p\":1,\"n\":\"Weight\"}]}]},{\"t\":1,\"p\":1,\"n\":\"BOOK - Book\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"},{\"t\":5,\"p\":1,\"n\":\"MODB - Bound Radius\"},{\"t\":11,\"p\":1,\"n\":\"MODT - Texture Files Hashes\"}]},{\"t\":2,\"p\":1,\"n\":\"ICON - Icon filename\"},{\"t\":3,\"p\":1,\"n\":\"SCRI - Script\"},{\"t\":3,\"p\":1,\"n\":\"ENAM - Enchantment\"},{\"t\":3,\"p\":1,\"n\":\"ANAM - Enchantment Points\"},{\"t\":2,\"p\":1,\"n\":\"DESC - Description\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DATA - \",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":3,\"p\":1,\"n\":\"Teaches\"},{\"t\":3,\"p\":1,\"n\":\"Value\"},{\"t\":5,\"p\":1,\"n\":\"Weight\"}]}]},{\"t\":1,\"p\":1,\"n\":\"BSGN - Birthsign\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":2,\"p\":1,\"n\":\"ICON - Icon filename\"},{\"t\":2,\"p\":1,\"n\":\"DESC - Description\"},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Spells\",\"d\":1,\"c\":[{\"t\":3,\"p\":1,\"n\":\"SPLO - Spell\"}]}]},{\"t\":1,\"p\":1,\"n\":\"CELL - Cell\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":3,\"p\":1,\"n\":\"DATA - Flags\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"XCLC - Grid\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"X\"},{\"t\":3,\"p\":1,\"n\":\"Y\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"XCLL - Lighting\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Ambient Color\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Directional Color\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Fog Color\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":5,\"p\":1,\"n\":\"Fog Near\"},{\"t\":5,\"p\":1,\"n\":\"Fog Far\"},{\"t\":3,\"p\":1,\"n\":\"Directional Rotation XY\"},{\"t\":3,\"p\":1,\"n\":\"Directional Rotation Z\"},{\"t\":5,\"p\":1,\"n\":\"Directional Fade\"},{\"t\":5,\"p\":1,\"n\":\"Fog Clip Dist\"}]},{\"t\":7,\"p\":1,\"n\":\"XCLR - Regions\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Region\"}]},{\"t\":3,\"p\":1,\"n\":\"XCMT - Music\"},{\"t\":5,\"p\":1,\"n\":\"XCLW - Water Height\"},{\"t\":3,\"p\":1,\"n\":\"XCCM - Climate\"},{\"t\":3,\"p\":1,\"n\":\"XCWT - Water\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Ownership\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"XOWN - Owner\"},{\"t\":3,\"p\":1,\"n\":\"XRNK - Faction rank\"},{\"t\":3,\"p\":1,\"n\":\"XGLB - Global variable\"}]}]},{\"t\":1,\"p\":1,\"n\":\"CLAS - Class\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":2,\"p\":1,\"n\":\"DESC - Description\"},{\"t\":2,\"p\":1,\"n\":\"ICON - Icon filename\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DATA - \",\"c\":[{\"t\":7,\"p\":1,\"n\":\"Primary Attributes\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Primary Attribute\"}]},{\"t\":3,\"p\":1,\"n\":\"Specialization\"},{\"t\":7,\"p\":1,\"n\":\"Major Skills\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Major Skill\"}]},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":3,\"p\":1,\"n\":\"Buys\\/Sells and Services\"},{\"t\":3,\"p\":1,\"n\":\"Teaches\"},{\"t\":3,\"p\":1,\"n\":\"Maximum training level\"},{\"t\":3,\"n\":\"Unused\"}]}]},{\"t\":1,\"p\":1,\"n\":\"CLMT - Climate\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":7,\"p\":1,\"n\":\"WLST - Weather Types\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Weather Type\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Weather\"},{\"t\":3,\"p\":1,\"n\":\"Chance\"}]}]},{\"t\":2,\"p\":1,\"n\":\"FNAM - Sun Texture\"},{\"t\":2,\"p\":1,\"n\":\"GNAM - Sun Glare Texture\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"},{\"t\":5,\"p\":1,\"n\":\"MODB - Bound Radius\"},{\"t\":11,\"p\":1,\"n\":\"MODT - Texture Files Hashes\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"TNAM - Timing\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Sunrise\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Begin\"},{\"t\":3,\"p\":1,\"n\":\"End\"}]},{\"t\":6,\"p\":1,\"n\":\"Sunset\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Begin\"},{\"t\":3,\"p\":1,\"n\":\"End\"}]},{\"t\":3,\"p\":1,\"n\":\"Volatility\"},{\"t\":3,\"p\":1,\"n\":\"Moons \\/ Phase Length\"}]}]},{\"t\":1,\"p\":1,\"n\":\"CLOT - Clothing\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":3,\"p\":1,\"n\":\"SCRI - Script\"},{\"t\":3,\"p\":1,\"n\":\"ENAM - Enchantment\"},{\"t\":3,\"p\":1,\"n\":\"ANAM - Enchantment Points\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"BMDT - \",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Biped Flags\"},{\"t\":3,\"p\":1,\"n\":\"General Flags\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Male biped model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"},{\"t\":5,\"p\":1,\"n\":\"MODB - Bound Radius\"},{\"t\":11,\"p\":1,\"n\":\"MODT - Texture Files Hashes\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Male world model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MOD2 - Model Filename\"},{\"t\":5,\"p\":1,\"n\":\"MO2B - Bound Radius\"},{\"t\":11,\"p\":1,\"n\":\"MO2T - Texture Files Hashes\"}]},{\"t\":2,\"p\":1,\"n\":\"ICON - Male icon filename\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Female biped model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MOD3 - Model Filename\"},{\"t\":5,\"p\":1,\"n\":\"MO3B - Bound Radius\"},{\"t\":11,\"p\":1,\"n\":\"MO3T - Texture Files Hashes\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Female world model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MOD4 - Model Filename\"},{\"t\":5,\"p\":1,\"n\":\"MO4B - Bound Radius\"},{\"t\":11,\"p\":1,\"n\":\"MO4T - Texture Files Hashes\"}]},{\"t\":2,\"p\":1,\"n\":\"ICO2 - Female icon filename\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DATA - \",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Value\"},{\"t\":5,\"p\":1,\"n\":\"Weight\"}]}]},{\"t\":1,\"p\":1,\"n\":\"CONT - Container\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"},{\"t\":5,\"p\":1,\"n\":\"MODB - Bound Radius\"},{\"t\":11,\"p\":1,\"n\":\"MODT - Texture Files Hashes\"}]},{\"t\":3,\"p\":1,\"n\":\"SCRI - Script\"},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Items\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"CNTO - Item\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Item\"},{\"t\":3,\"p\":1,\"n\":\"Count\"}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DATA - \",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":5,\"p\":1,\"n\":\"Weight\"}]},{\"t\":3,\"p\":1,\"n\":\"SNAM - Open sound\"},{\"t\":3,\"p\":1,\"n\":\"QNAM - Close sound\"}]},{\"t\":1,\"p\":1,\"n\":\"CREA - Creature\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"},{\"t\":5,\"p\":1,\"n\":\"MODB - Bound Radius\"},{\"t\":11,\"p\":1,\"n\":\"MODT - Texture Files Hashes\"}]},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Items\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"CNTO - Item\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Item\"},{\"t\":3,\"p\":1,\"n\":\"Count\"}]}]},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Spells\",\"d\":1,\"c\":[{\"t\":3,\"p\":1,\"n\":\"SPLO - Spell\"}]},{\"t\":7,\"p\":1,\"n\":\"NIFZ - Models\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"Model\"}]},{\"t\":11,\"n\":\"NIFT - Texture Files Hashes\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"ACBS - Configuration\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":3,\"p\":1,\"n\":\"Base spell points\"},{\"t\":3,\"p\":1,\"n\":\"Fatigue\"},{\"t\":3,\"p\":1,\"n\":\"Barter gold\"},{\"t\":3,\"p\":1,\"n\":\"Level (offset)\"},{\"t\":3,\"p\":1,\"n\":\"Calc min\"},{\"t\":3,\"p\":1,\"n\":\"Calc max\"}]},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Factions\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"SNAM - Faction\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Faction\"},{\"t\":3,\"p\":1,\"n\":\"Rank\"},{\"t\":11,\"n\":\"Unused\"}]}]},{\"t\":3,\"p\":1,\"n\":\"INAM - Death item\"},{\"t\":3,\"p\":1,\"n\":\"SCRI - Script\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"AIDT - AI Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Aggression\"},{\"t\":3,\"p\":1,\"n\":\"Confidence\"},{\"t\":3,\"p\":1,\"n\":\"Energy Level\"},{\"t\":3,\"p\":1,\"n\":\"Responsibility\"},{\"t\":3,\"p\":1,\"n\":\"Buys\\/Sells and Services\"},{\"t\":3,\"p\":1,\"n\":\"Teaches\"},{\"t\":3,\"p\":1,\"n\":\"Maximum training level\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"AI Packages\",\"d\":1,\"c\":[{\"t\":3,\"p\":1,\"n\":\"PKID - AI Package\"}]},{\"t\":7,\"p\":1,\"n\":\"KFFZ - Animations\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"Animation\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DATA - Creature Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Combat Skill\"},{\"t\":3,\"p\":1,\"n\":\"Magic Skill\"},{\"t\":3,\"p\":1,\"n\":\"Stealth Skill\"},{\"t\":3,\"p\":1,\"n\":\"Soul\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Health\"},{\"t\":3,\"p\":1,\"n\":\"Attack Damage\"},{\"t\":3,\"p\":1,\"n\":\"Strength\"},{\"t\":3,\"p\":1,\"n\":\"Intelligence\"},{\"t\":3,\"p\":1,\"n\":\"Willpower\"},{\"t\":3,\"p\":1,\"n\":\"Agility\"},{\"t\":3,\"p\":1,\"n\":\"Speed\"},{\"t\":3,\"p\":1,\"n\":\"Endurance\"},{\"t\":3,\"p\":1,\"n\":\"Personality\"},{\"t\":3,\"p\":1,\"n\":\"Luck\"}]},{\"t\":3,\"p\":1,\"n\":\"RNAM - Attack reach\"},{\"t\":3,\"p\":1,\"n\":\"ZNAM - Combat Style\"},{\"t\":5,\"p\":1,\"n\":\"TNAM - Turning Speed\"},{\"t\":5,\"p\":1,\"n\":\"BNAM - Base Scale\"},{\"t\":5,\"p\":1,\"n\":\"WNAM - Foot Weight\"},{\"t\":2,\"p\":1,\"n\":\"NAM0 - Blood Spray\"},{\"t\":2,\"p\":1,\"n\":\"NAM1 - Blood Decal\"},{\"t\":3,\"p\":1,\"n\":\"CSCR - Inherits Sounds from\"},{\"t\":10,\"p\":1,\"n\":\"Sound Types\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Sound Type\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"CSDT - Type\"},{\"t\":10,\"p\":1,\"n\":\"Sounds\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Sound\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"CSDI - Sound\"},{\"t\":3,\"p\":1,\"n\":\"CSDC - Sound Chance\"}]}]}]}]}]},{\"t\":1,\"p\":1,\"n\":\"CSTY - Combat Style\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"CSTD - Standard\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Dodge % Chance\"},{\"t\":3,\"p\":1,\"n\":\"Left\\/Right % Chance\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":5,\"p\":1,\"n\":\"Dodge L\\/R Timer (min)\"},{\"t\":5,\"p\":1,\"n\":\"Dodge L\\/R Timer (max)\"},{\"t\":5,\"p\":1,\"n\":\"Dodge Forward Timer (min)\"},{\"t\":5,\"p\":1,\"n\":\"Dodge Forward Timer (max)\"},{\"t\":5,\"p\":1,\"n\":\"Dodge Back Timer Min\"},{\"t\":5,\"p\":1,\"n\":\"Dodge Back Timer Max\"},{\"t\":5,\"p\":1,\"n\":\"Idle Timer min\"},{\"t\":5,\"p\":1,\"n\":\"Idle Timer max\"},{\"t\":3,\"p\":1,\"n\":\"Block % Chance\"},{\"t\":3,\"p\":1,\"n\":\"Attack % Chance\"},{\"t\":5,\"p\":1,\"n\":\"Recoil\\/Stagger Bonus to Attack\"},{\"t\":5,\"p\":1,\"n\":\"Unconscious Bonus to Attack\"},{\"t\":5,\"p\":1,\"n\":\"Hand-To-Hand Bonus to Attack\"},{\"t\":3,\"p\":1,\"n\":\"Power Attack % Chance\"},{\"t\":5,\"p\":1,\"n\":\"Recoil\\/Stagger Bonus to Power\"},{\"t\":5,\"p\":1,\"n\":\"Unconscious Bonus to Power Attack\"},{\"t\":3,\"p\":1,\"n\":\"Power Attack - Normal\"},{\"t\":3,\"p\":1,\"n\":\"Power Attack - Forward\"},{\"t\":3,\"p\":1,\"n\":\"Power Attack - Back\"},{\"t\":3,\"p\":1,\"n\":\"Power Attack - Left\"},{\"t\":3,\"p\":1,\"n\":\"Power Attack - Right\"},{\"t\":5,\"p\":1,\"n\":\"Hold Timer (min)\"},{\"t\":5,\"p\":1,\"n\":\"Hold Timer (max)\"},{\"t\":3,\"p\":1,\"n\":\"Flags 1\"},{\"t\":3,\"p\":1,\"n\":\"Acrobatic Dodge % Chance\"},{\"t\":5,\"p\":1,\"n\":\"Range Mult (Optimal)\"},{\"t\":5,\"p\":1,\"n\":\"Range Mult (Max)\"},{\"t\":5,\"p\":1,\"n\":\"Switch Distance (Melee)\"},{\"t\":5,\"p\":1,\"n\":\"Switch Distance (Ranged)\"},{\"t\":5,\"p\":1,\"n\":\"Buff standoff Distance\"},{\"t\":5,\"p\":1,\"n\":\"Ranged standoff Distance\"},{\"t\":5,\"p\":1,\"n\":\"Group standoff Distance\"},{\"t\":3,\"p\":1,\"n\":\"Rushing Attack % Chance\"},{\"t\":5,\"p\":1,\"n\":\"Rushing Attack Distance Mult\"},{\"t\":3,\"p\":1,\"n\":\"Flags 2\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"CSAD - Advanced\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Dodge Fatigue Mod Mult\"},{\"t\":5,\"p\":1,\"n\":\"Dodge Fatigue Mod Base\"},{\"t\":5,\"p\":1,\"n\":\"Encumb. Speed Mod Base\"},{\"t\":5,\"p\":1,\"n\":\"Encumb. Speed Mod Mult\"},{\"t\":5,\"p\":1,\"n\":\"Dodge While Under Attack Mult\"},{\"t\":5,\"p\":1,\"n\":\"Dodge Not Under Attack Mult\"},{\"t\":5,\"p\":1,\"n\":\"Dodge Back While Under Attack Mult\"},{\"t\":5,\"p\":1,\"n\":\"Dodge Back Not Under Attack Mult\"},{\"t\":5,\"p\":1,\"n\":\"Dodge Forward While Attacking Mult\"},{\"t\":5,\"p\":1,\"n\":\"Dodge Forward Not Attacking Mult\"},{\"t\":5,\"p\":1,\"n\":\"Block Skill Modifier Mult\"},{\"t\":5,\"p\":1,\"n\":\"Block Skill Modifier Base\"},{\"t\":5,\"p\":1,\"n\":\"Block While Under Attack Mult\"},{\"t\":5,\"p\":1,\"n\":\"Block Not Under Attack Mult\"},{\"t\":5,\"p\":1,\"n\":\"Attack Skill Modifier Mult\"},{\"t\":5,\"p\":1,\"n\":\"Attack Skill Modifier Base\"},{\"t\":5,\"p\":1,\"n\":\"Attack While Under Attack Mult\"},{\"t\":5,\"p\":1,\"n\":\"Attack Not Under Attack Mult\"},{\"t\":5,\"p\":1,\"n\":\"Attack During Block Mult\"},{\"t\":5,\"p\":1,\"n\":\"Power Att. Fatigue Mod Base\"},{\"t\":5,\"p\":1,\"n\":\"Power Att. Fatigue Mod Mult\"}]}]},{\"t\":1,\"p\":1,\"n\":\"DIAL - Dialog Topic\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Quests\",\"d\":1,\"c\":[{\"t\":3,\"p\":1,\"n\":\"QSTI - Quest\"}]},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Quests?\",\"d\":1,\"c\":[{\"t\":3,\"p\":1,\"n\":\"QSTR - Quest?\"}]},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":3,\"p\":1,\"n\":\"DATA - Type\"}]},{\"t\":1,\"p\":1,\"n\":\"DOOR - Door\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"},{\"t\":5,\"p\":1,\"n\":\"MODB - Bound Radius\"},{\"t\":11,\"p\":1,\"n\":\"MODT - Texture Files Hashes\"}]},{\"t\":3,\"p\":1,\"n\":\"SCRI - Script\"},{\"t\":3,\"p\":1,\"n\":\"SNAM - Open sound\"},{\"t\":3,\"p\":1,\"n\":\"ANAM - Close sound\"},{\"t\":3,\"p\":1,\"n\":\"BNAM - Loop sound\"},{\"t\":3,\"p\":1,\"n\":\"FNAM - Flags\"},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Random teleport destinations\",\"d\":1,\"c\":[{\"t\":3,\"p\":1,\"n\":\"TNAM - Destination\"}]}]},{\"t\":1,\"p\":1,\"n\":\"EFSH - Effect Shader\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"p\":1,\"n\":\"ICON - Fill Texture\"},{\"t\":2,\"p\":1,\"n\":\"ICO2 - Particle Shader Texture\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DATA - \",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Membrane Shader - Source Blend Mode\"},{\"t\":3,\"p\":1,\"n\":\"Membrane Shader - Blend Operation\"},{\"t\":3,\"p\":1,\"n\":\"Membrane Shader - Z Test Function\"},{\"t\":6,\"p\":1,\"n\":\"Fill\\/Texture Effect - Color\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":5,\"p\":1,\"n\":\"Fill\\/Texture Effect - Alpha Fade In Time\"},{\"t\":5,\"p\":1,\"n\":\"Fill\\/Texture Effect - Full Alpha Time\"},{\"t\":5,\"p\":1,\"n\":\"Fill\\/Texture Effect - Alpha Fade Out Time\"},{\"t\":5,\"p\":1,\"n\":\"Fill\\/Texture Effect - Presistent Alpha Ratio\"},{\"t\":5,\"p\":1,\"n\":\"Fill\\/Texture Effect - Alpha Pulse Amplitude\"},{\"t\":5,\"p\":1,\"n\":\"Fill\\/Texture Effect - Alpha Pulse Frequency\"},{\"t\":5,\"p\":1,\"n\":\"Fill\\/Texture Effect - Texture Animation Speed (U)\"},{\"t\":5,\"p\":1,\"n\":\"Fill\\/Texture Effect - Texture Animation Speed (V)\"},{\"t\":5,\"p\":1,\"n\":\"Edge Effect - Fall Off\"},{\"t\":6,\"p\":1,\"n\":\"Edge Effect - Color\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":5,\"p\":1,\"n\":\"Edge Effect - Alpha Fade In Time\"},{\"t\":5,\"p\":1,\"n\":\"Edge Effect - Full Alpha Time\"},{\"t\":5,\"p\":1,\"n\":\"Edge Effect - Alpha Fade Out Time\"},{\"t\":5,\"p\":1,\"n\":\"Edge Effect - Persistent Alpha Ratio\"},{\"t\":5,\"p\":1,\"n\":\"Edge Effect - Alpha Pulse Amplitude\"},{\"t\":5,\"p\":1,\"n\":\"Edge Effect - Alpha Pusle Frequence\"},{\"t\":5,\"p\":1,\"n\":\"Fill\\/Texture Effect - Full Alpha Ratio\"},{\"t\":5,\"p\":1,\"n\":\"Edge Effect - Full Alpha Ratio\"},{\"t\":3,\"p\":1,\"n\":\"Membrane Shader - Dest Blend Mode\"},{\"t\":3,\"p\":1,\"n\":\"Particle Shader - Source Blend Mode\"},{\"t\":3,\"p\":1,\"n\":\"Particle Shader - Blend Operation\"},{\"t\":3,\"p\":1,\"n\":\"Particle Shader - Z Test Function\"},{\"t\":3,\"p\":1,\"n\":\"Particle Shader - Dest Blend Mode\"},{\"t\":5,\"p\":1,\"n\":\"Particle Shader - Particle Birth Ramp Up Time\"},{\"t\":5,\"p\":1,\"n\":\"Particle Shader - Full Particle Birth Time\"},{\"t\":5,\"p\":1,\"n\":\"Particle Shader - Particle Birth Ramp Down Time\"},{\"t\":5,\"p\":1,\"n\":\"Particle Shader - Full Particle Birth Ratio\"},{\"t\":5,\"p\":1,\"n\":\"Particle Shader - Persistant Particle Birth Ratio\"},{\"t\":5,\"p\":1,\"n\":\"Particle Shader - Particle Lifetime\"},{\"t\":5,\"p\":1,\"n\":\"Particle Shader - Particle Lifetime +\\/-\"},{\"t\":5,\"p\":1,\"n\":\"Particle Shader - Initial Speed Along Normal\"},{\"t\":5,\"p\":1,\"n\":\"Particle Shader - Acceleration Along Normal\"},{\"t\":5,\"p\":1,\"n\":\"Particle Shader - Initial Velocity #1\"},{\"t\":5,\"p\":1,\"n\":\"Particle Shader - Initial Velocity #2\"},{\"t\":5,\"p\":1,\"n\":\"Particle Shader - Initial Velocity #3\"},{\"t\":5,\"p\":1,\"n\":\"Particle Shader - Acceleration #1\"},{\"t\":5,\"p\":1,\"n\":\"Particle Shader - Acceleration #2\"},{\"t\":5,\"p\":1,\"n\":\"Particle Shader - Acceleration #3\"},{\"t\":5,\"p\":1,\"n\":\"Particle Shader - Scale Key 1\"},{\"t\":5,\"p\":1,\"n\":\"Particle Shader - Scale Key 2\"},{\"t\":5,\"p\":1,\"n\":\"Particle Shader - Scale Key 1 Time\"},{\"t\":5,\"p\":1,\"n\":\"Particle Shader - Scale Key 2 Time\"},{\"t\":6,\"p\":1,\"n\":\"Color Key 1 - Color\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Color Key 2 - Color\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Color Key 3 - Color\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":5,\"p\":1,\"n\":\"Color Key 1 - Color Alpha\"},{\"t\":5,\"p\":1,\"n\":\"Color Key 2 - Color Alpha\"},{\"t\":5,\"p\":1,\"n\":\"Color Key 3 - Color Alpha\"},{\"t\":5,\"p\":1,\"n\":\"Color Key 1 - Color Key Time\"},{\"t\":5,\"p\":1,\"n\":\"Color Key 2 - Color Key Time\"},{\"t\":5,\"p\":1,\"n\":\"Color Key 3 - Color Key Time\"}]}]},{\"t\":1,\"p\":1,\"n\":\"ENCH - Enchantment\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"OBME - Oblivion Magic Extender\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Record Version\"},{\"t\":6,\"p\":1,\"n\":\"OBME Version\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Beta\"},{\"t\":3,\"p\":1,\"n\":\"Minor\"},{\"t\":3,\"p\":1,\"n\":\"Major\"}]},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"ENIT - \",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Charge Amount\"},{\"t\":3,\"p\":1,\"n\":\"Enchant Cost\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Effects\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Effect\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"EFID - Magic effect name\"},{\"t\":6,\"p\":1,\"n\":\"EFIT - \",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Magic effect name\"},{\"t\":3,\"p\":1,\"n\":\"Magnitude\"},{\"t\":3,\"p\":1,\"n\":\"Area\"},{\"t\":3,\"p\":1,\"n\":\"Duration\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Actor Value\"}]},{\"t\":6,\"p\":1,\"n\":\"Script effect\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"SCIT - Script effect data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Script effect\"},{\"t\":3,\"p\":1,\"n\":\"Magic school\"},{\"t\":3,\"p\":1,\"n\":\"Visual effect name\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"}]}]},{\"t\":6,\"p\":1,\"n\":\"Effects\",\"c\":[{\"t\":8,\"p\":1,\"n\":\"Effects\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Effect\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"EFME - Oblivion Magic Extender\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Record Version\"},{\"t\":6,\"p\":1,\"n\":\"OBME Version\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Beta\"},{\"t\":3,\"p\":1,\"n\":\"Minor\"},{\"t\":3,\"p\":1,\"n\":\"Major\"}]},{\"t\":3,\"p\":1,\"n\":\"EFIT Param Info\"},{\"t\":3,\"p\":1,\"n\":\"EFIX Param Info\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":2,\"p\":1,\"n\":\"EFID - Magic Effect Code\"},{\"t\":6,\"p\":1,\"n\":\"EFIT - \",\"c\":[{\"t\":2,\"p\":1,\"n\":\"Magic Effect Code\"},{\"t\":3,\"p\":1,\"n\":\"Magnitude\"},{\"t\":3,\"p\":1,\"n\":\"Area\"},{\"t\":3,\"p\":1,\"n\":\"Duration\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":11,\"n\":\"Param #1 - Unknown Type\"},{\"t\":3,\"p\":1,\"n\":\"Param #1 - FormID\"},{\"t\":2,\"p\":1,\"n\":\"Param #1 - Magic Effect Code\"},{\"t\":3,\"p\":1,\"n\":\"Param #1 - Actor Value\"}]},{\"t\":6,\"p\":1,\"n\":\"Script effect\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"SCIT - Script effect data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Script effect\"},{\"t\":3,\"p\":1,\"n\":\"Magic school\"},{\"t\":2,\"p\":1,\"n\":\"Visual Effect Code\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"}]},{\"t\":2,\"p\":1,\"n\":\"EFII - Icon\"},{\"t\":6,\"p\":1,\"n\":\"EFIX - \",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Override Mask\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":5,\"p\":1,\"n\":\"Base Cost\"},{\"t\":11,\"n\":\"Param #2 - Unknown Type\"},{\"t\":3,\"p\":1,\"n\":\"Param #2 - FormID\"},{\"t\":2,\"p\":1,\"n\":\"Param #2 - Magic Effect Code\"},{\"t\":3,\"p\":1,\"n\":\"Param #2 - Actor Value\"}]}]}]},{\"p\":1,\"n\":\"EFXX - Effects End Marker\"},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"}]}]}]},{\"t\":1,\"p\":1,\"n\":\"EYES - Eyes\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":2,\"p\":1,\"n\":\"ICON - Texture\"},{\"t\":3,\"p\":1,\"n\":\"DATA - Flags\"}]},{\"t\":1,\"p\":1,\"n\":\"FACT - Faction\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Relations\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"XNAM - Relation\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Faction\"},{\"t\":3,\"p\":1,\"n\":\"Modifier\"}]}]},{\"t\":3,\"p\":1,\"n\":\"DATA - Flags\"},{\"t\":5,\"p\":1,\"n\":\"CNAM - Crime Gold Multiplier\"},{\"t\":10,\"p\":1,\"n\":\"Ranks\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Rank\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"RNAM - Rank#\"},{\"t\":2,\"p\":1,\"n\":\"MNAM - Male\"},{\"t\":2,\"p\":1,\"n\":\"FNAM - Female\"},{\"t\":2,\"p\":1,\"n\":\"INAM - Insignia\"}]}]}]},{\"t\":1,\"p\":1,\"n\":\"FLOR - Flora\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"},{\"t\":5,\"p\":1,\"n\":\"MODB - Bound Radius\"},{\"t\":11,\"p\":1,\"n\":\"MODT - Texture Files Hashes\"}]},{\"t\":3,\"p\":1,\"n\":\"SCRI - Script\"},{\"t\":3,\"p\":1,\"n\":\"PFIG - Ingredient\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"PFPC - Seasonal ingredient production\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Spring\"},{\"t\":3,\"p\":1,\"n\":\"Summer \"},{\"t\":3,\"p\":1,\"n\":\"Fall\"},{\"t\":3,\"p\":1,\"n\":\"Winter\"}]}]},{\"t\":1,\"p\":1,\"n\":\"FURN - Furniture\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"},{\"t\":5,\"p\":1,\"n\":\"MODB - Bound Radius\"},{\"t\":11,\"p\":1,\"n\":\"MODT - Texture Files Hashes\"}]},{\"t\":3,\"p\":1,\"n\":\"SCRI - Script\"},{\"t\":11,\"n\":\"MNAM - Marker Flags\"}]},{\"t\":1,\"p\":1,\"n\":\"GLOB - Global\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":3,\"p\":1,\"n\":\"FNAM - Type\"},{\"t\":5,\"p\":1,\"n\":\"FLTV - Value\"}]},{\"t\":1,\"p\":1,\"n\":\"GMST - Game Setting\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"p\":1,\"n\":\"\"}]},{\"t\":1,\"p\":1,\"n\":\"GRAS - Grass\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"},{\"t\":5,\"p\":1,\"n\":\"MODB - Bound Radius\"},{\"t\":11,\"p\":1,\"n\":\"MODT - Texture Files Hashes\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DATA - \",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Density\"},{\"t\":3,\"p\":1,\"n\":\"Min Slope\"},{\"t\":3,\"p\":1,\"n\":\"Max Slope\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Unit from water amount\"},{\"t\":3,\"p\":1,\"n\":\"Unit from water type\"},{\"t\":5,\"p\":1,\"n\":\"Position Range\"},{\"t\":5,\"p\":1,\"n\":\"Height Range\"},{\"t\":5,\"p\":1,\"n\":\"Color Range\"},{\"t\":5,\"p\":1,\"n\":\"Wave Period\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"}]}]},{\"t\":1,\"p\":1,\"n\":\"HAIR - Hair\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"},{\"t\":5,\"p\":1,\"n\":\"MODB - Bound Radius\"},{\"t\":11,\"p\":1,\"n\":\"MODT - Texture Files Hashes\"}]},{\"t\":2,\"p\":1,\"n\":\"ICON - Texture\"},{\"t\":3,\"p\":1,\"n\":\"DATA - Flags\"}]},{\"t\":1,\"n\":\"IDLE - Idle Animation\",\"c\":[{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"n\":\"Model\",\"c\":[{\"t\":2,\"n\":\"MODL - Model Filename\"},{\"t\":5,\"n\":\"MODB - Bound Radius\"},{\"t\":11,\"n\":\"MODT - Texture Files Hashes\"}]},{\"t\":8,\"n\":\"Conditions\",\"c\":[{\"t\":6,\"n\":\"CTDA - Condition\",\"c\":[{\"t\":3,\"n\":\"Type\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":5,\"n\":\"Comparison Value - Float\"},{\"t\":3,\"n\":\"Comparison Value - Global\"},{\"t\":3,\"n\":\"Function\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":11,\"n\":\"None\"},{\"t\":3,\"n\":\"Integer\"},{\"t\":3,\"n\":\"Variable Name (INVALID)\"},{\"t\":3,\"n\":\"Sex\"},{\"t\":3,\"n\":\"Actor Value\"},{\"t\":3,\"n\":\"Crime Type\"},{\"t\":3,\"n\":\"Axis\"},{\"t\":3,\"n\":\"Form Type\"},{\"t\":3,\"n\":\"Quest Stage (INVALID)\"},{\"t\":3,\"n\":\"Object Reference\"},{\"t\":3,\"n\":\"Inventory Object\"},{\"t\":3,\"n\":\"Actor\"},{\"t\":3,\"n\":\"Quest\"},{\"t\":3,\"n\":\"Faction\"},{\"t\":3,\"n\":\"Cell\"},{\"t\":3,\"n\":\"Class\"},{\"t\":3,\"n\":\"Race\"},{\"t\":3,\"n\":\"Actor Base\"},{\"t\":3,\"n\":\"Global\"},{\"t\":3,\"n\":\"Weather\"},{\"t\":3,\"n\":\"Package\"},{\"t\":3,\"n\":\"Owner\"},{\"t\":3,\"n\":\"Birthsign\"},{\"t\":3,\"n\":\"Furniture\"},{\"t\":3,\"n\":\"Magic Item\"},{\"t\":3,\"n\":\"Magic Effect\"},{\"t\":3,\"n\":\"Worldspace\"},{\"t\":3,\"n\":\"Referenceable Object\"},{\"t\":3,\"n\":\"Variable Name\"},{\"t\":3,\"n\":\"Quest Stage\"}]},{\"t\":6,\"n\":\"CTDT - Condition (old format)\",\"c\":[{\"t\":3,\"n\":\"Type\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":5,\"n\":\"Comparison Value - Float\"},{\"t\":3,\"n\":\"Comparison Value - Global\"},{\"t\":3,\"n\":\"Function\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":11,\"n\":\"None\"},{\"t\":3,\"n\":\"Integer\"},{\"t\":3,\"n\":\"Variable Name (INVALID)\"},{\"t\":3,\"n\":\"Sex\"},{\"t\":3,\"n\":\"Actor Value\"},{\"t\":3,\"n\":\"Crime Type\"},{\"t\":3,\"n\":\"Axis\"},{\"t\":3,\"n\":\"Form Type\"},{\"t\":3,\"n\":\"Quest Stage (INVALID)\"},{\"t\":3,\"n\":\"Object Reference\"},{\"t\":3,\"n\":\"Inventory Object\"},{\"t\":3,\"n\":\"Actor\"},{\"t\":3,\"n\":\"Quest\"},{\"t\":3,\"n\":\"Faction\"},{\"t\":3,\"n\":\"Cell\"},{\"t\":3,\"n\":\"Class\"},{\"t\":3,\"n\":\"Race\"},{\"t\":3,\"n\":\"Actor Base\"},{\"t\":3,\"n\":\"Global\"},{\"t\":3,\"n\":\"Weather\"},{\"t\":3,\"n\":\"Package\"},{\"t\":3,\"n\":\"Owner\"},{\"t\":3,\"n\":\"Birthsign\"},{\"t\":3,\"n\":\"Furniture\"},{\"t\":3,\"n\":\"Magic Item\"},{\"t\":3,\"n\":\"Magic Effect\"},{\"t\":3,\"n\":\"Worldspace\"},{\"t\":3,\"n\":\"Referenceable Object\"},{\"t\":3,\"n\":\"Variable Name\"},{\"t\":3,\"n\":\"Quest Stage\"}]}]},{\"t\":3,\"n\":\"ANAM - Animation Group Section\"},{\"t\":7,\"n\":\"DATA - Related Idle Animations\",\"c\":[{\"t\":3,\"n\":\"Related Idle Animation\"}]}]},{\"t\":1,\"p\":1,\"n\":\"INFO - Dialog response\",\"d\":1,\"c\":[{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DATA - \",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Next Speaker\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"}]},{\"t\":3,\"p\":1,\"n\":\"QSTI - Quest\"},{\"t\":3,\"p\":1,\"n\":\"TPIC - Topic\"},{\"t\":3,\"p\":1,\"n\":\"PNAM - Previous INFO\"},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Add topics\",\"d\":1,\"c\":[{\"t\":3,\"p\":1,\"n\":\"NAME - Topic\"}]},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Responses\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Response\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"TRDT - Response Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Emotion Type\"},{\"t\":3,\"p\":1,\"n\":\"Emotion Value\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Response number\"}]},{\"t\":2,\"p\":1,\"n\":\"NAM1 - Response Text\"},{\"t\":2,\"p\":1,\"n\":\"NAM2 - Actor notes\"}]}]},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Conditions\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"CTDA - Condition\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":5,\"p\":1,\"n\":\"Comparison Value - Float\"},{\"t\":3,\"p\":1,\"n\":\"Comparison Value - Global\"},{\"t\":3,\"p\":1,\"n\":\"Function\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":11,\"p\":1,\"n\":\"None\"},{\"t\":3,\"p\":1,\"n\":\"Integer\"},{\"t\":3,\"p\":1,\"n\":\"Variable Name (INVALID)\"},{\"t\":3,\"p\":1,\"n\":\"Sex\"},{\"t\":3,\"p\":1,\"n\":\"Actor Value\"},{\"t\":3,\"p\":1,\"n\":\"Crime Type\"},{\"t\":3,\"p\":1,\"n\":\"Axis\"},{\"t\":3,\"p\":1,\"n\":\"Form Type\"},{\"t\":3,\"p\":1,\"n\":\"Quest Stage (INVALID)\"},{\"t\":3,\"p\":1,\"n\":\"Object Reference\"},{\"t\":3,\"p\":1,\"n\":\"Inventory Object\"},{\"t\":3,\"p\":1,\"n\":\"Actor\"},{\"t\":3,\"p\":1,\"n\":\"Quest\"},{\"t\":3,\"p\":1,\"n\":\"Faction\"},{\"t\":3,\"p\":1,\"n\":\"Cell\"},{\"t\":3,\"p\":1,\"n\":\"Class\"},{\"t\":3,\"p\":1,\"n\":\"Race\"},{\"t\":3,\"p\":1,\"n\":\"Actor Base\"},{\"t\":3,\"p\":1,\"n\":\"Global\"},{\"t\":3,\"p\":1,\"n\":\"Weather\"},{\"t\":3,\"p\":1,\"n\":\"Package\"},{\"t\":3,\"p\":1,\"n\":\"Owner\"},{\"t\":3,\"p\":1,\"n\":\"Birthsign\"},{\"t\":3,\"p\":1,\"n\":\"Furniture\"},{\"t\":3,\"p\":1,\"n\":\"Magic Item\"},{\"t\":3,\"p\":1,\"n\":\"Magic Effect\"},{\"t\":3,\"p\":1,\"n\":\"Worldspace\"},{\"t\":3,\"p\":1,\"n\":\"Referenceable Object\"},{\"t\":3,\"p\":1,\"n\":\"Variable Name\"},{\"t\":3,\"p\":1,\"n\":\"Quest Stage\"}]},{\"t\":6,\"p\":1,\"n\":\"CTDT - Condition (old format)\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":5,\"p\":1,\"n\":\"Comparison Value - Float\"},{\"t\":3,\"p\":1,\"n\":\"Comparison Value - Global\"},{\"t\":3,\"p\":1,\"n\":\"Function\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":11,\"p\":1,\"n\":\"None\"},{\"t\":3,\"p\":1,\"n\":\"Integer\"},{\"t\":3,\"p\":1,\"n\":\"Variable Name (INVALID)\"},{\"t\":3,\"p\":1,\"n\":\"Sex\"},{\"t\":3,\"p\":1,\"n\":\"Actor Value\"},{\"t\":3,\"p\":1,\"n\":\"Crime Type\"},{\"t\":3,\"p\":1,\"n\":\"Axis\"},{\"t\":3,\"p\":1,\"n\":\"Form Type\"},{\"t\":3,\"p\":1,\"n\":\"Quest Stage (INVALID)\"},{\"t\":3,\"p\":1,\"n\":\"Object Reference\"},{\"t\":3,\"p\":1,\"n\":\"Inventory Object\"},{\"t\":3,\"p\":1,\"n\":\"Actor\"},{\"t\":3,\"p\":1,\"n\":\"Quest\"},{\"t\":3,\"p\":1,\"n\":\"Faction\"},{\"t\":3,\"p\":1,\"n\":\"Cell\"},{\"t\":3,\"p\":1,\"n\":\"Class\"},{\"t\":3,\"p\":1,\"n\":\"Race\"},{\"t\":3,\"p\":1,\"n\":\"Actor Base\"},{\"t\":3,\"p\":1,\"n\":\"Global\"},{\"t\":3,\"p\":1,\"n\":\"Weather\"},{\"t\":3,\"p\":1,\"n\":\"Package\"},{\"t\":3,\"p\":1,\"n\":\"Owner\"},{\"t\":3,\"p\":1,\"n\":\"Birthsign\"},{\"t\":3,\"p\":1,\"n\":\"Furniture\"},{\"t\":3,\"p\":1,\"n\":\"Magic Item\"},{\"t\":3,\"p\":1,\"n\":\"Magic Effect\"},{\"t\":3,\"p\":1,\"n\":\"Worldspace\"},{\"t\":3,\"p\":1,\"n\":\"Referenceable Object\"},{\"t\":3,\"p\":1,\"n\":\"Variable Name\"},{\"t\":3,\"p\":1,\"n\":\"Quest Stage\"}]}]},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Choices\",\"d\":1,\"c\":[{\"t\":3,\"p\":1,\"n\":\"TCLT - Choice\"}]},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Link From\",\"d\":1,\"c\":[{\"t\":3,\"p\":1,\"n\":\"TCLF - Topic\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Result Script\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"SCHR - Basic Script Data\",\"c\":[{\"t\":11,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"RefCount\"},{\"t\":3,\"p\":1,\"n\":\"CompiledSize\"},{\"t\":3,\"p\":1,\"n\":\"VariableCount\"},{\"t\":3,\"p\":1,\"n\":\"Type\"}]},{\"t\":6,\"p\":1,\"n\":\"SCHD - Basic Script Data\",\"c\":[{\"t\":11,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"RefCount\"},{\"t\":3,\"p\":1,\"n\":\"CompiledSize\"},{\"t\":3,\"p\":1,\"n\":\"VariableCount\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":11,\"p\":1,\"n\":\"SCDA - Compiled result script\"},{\"t\":2,\"p\":1,\"n\":\"SCTX - Result script source\"},{\"t\":8,\"p\":1,\"n\":\"References\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"SCRO - Global Reference\"},{\"t\":3,\"p\":1,\"n\":\"SCRV - Local Variable\"}]}]}]},{\"t\":1,\"p\":1,\"n\":\"INGR - Ingredient\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"OBME - Oblivion Magic Extender\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Record Version\"},{\"t\":6,\"p\":1,\"n\":\"OBME Version\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Beta\"},{\"t\":3,\"p\":1,\"n\":\"Minor\"},{\"t\":3,\"p\":1,\"n\":\"Major\"}]},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"},{\"t\":5,\"p\":1,\"n\":\"MODB - Bound Radius\"},{\"t\":11,\"p\":1,\"n\":\"MODT - Texture Files Hashes\"}]},{\"t\":2,\"p\":1,\"n\":\"ICON - Icon filename\"},{\"t\":3,\"p\":1,\"n\":\"SCRI - Script\"},{\"t\":5,\"p\":1,\"n\":\"DATA - Weight\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"ENIT - \",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Value\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Effects\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Effect\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"EFID - Magic effect name\"},{\"t\":6,\"p\":1,\"n\":\"EFIT - \",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Magic effect name\"},{\"t\":3,\"p\":1,\"n\":\"Magnitude\"},{\"t\":3,\"p\":1,\"n\":\"Area\"},{\"t\":3,\"p\":1,\"n\":\"Duration\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Actor Value\"}]},{\"t\":6,\"p\":1,\"n\":\"Script effect\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"SCIT - Script effect data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Script effect\"},{\"t\":3,\"p\":1,\"n\":\"Magic school\"},{\"t\":3,\"p\":1,\"n\":\"Visual effect name\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"}]}]},{\"t\":6,\"p\":1,\"n\":\"Effects\",\"c\":[{\"t\":8,\"p\":1,\"n\":\"Effects\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Effect\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"EFME - Oblivion Magic Extender\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Record Version\"},{\"t\":6,\"p\":1,\"n\":\"OBME Version\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Beta\"},{\"t\":3,\"p\":1,\"n\":\"Minor\"},{\"t\":3,\"p\":1,\"n\":\"Major\"}]},{\"t\":3,\"p\":1,\"n\":\"EFIT Param Info\"},{\"t\":3,\"p\":1,\"n\":\"EFIX Param Info\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":2,\"p\":1,\"n\":\"EFID - Magic Effect Code\"},{\"t\":6,\"p\":1,\"n\":\"EFIT - \",\"c\":[{\"t\":2,\"p\":1,\"n\":\"Magic Effect Code\"},{\"t\":3,\"p\":1,\"n\":\"Magnitude\"},{\"t\":3,\"p\":1,\"n\":\"Area\"},{\"t\":3,\"p\":1,\"n\":\"Duration\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":11,\"n\":\"Param #1 - Unknown Type\"},{\"t\":3,\"p\":1,\"n\":\"Param #1 - FormID\"},{\"t\":2,\"p\":1,\"n\":\"Param #1 - Magic Effect Code\"},{\"t\":3,\"p\":1,\"n\":\"Param #1 - Actor Value\"}]},{\"t\":6,\"p\":1,\"n\":\"Script effect\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"SCIT - Script effect data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Script effect\"},{\"t\":3,\"p\":1,\"n\":\"Magic school\"},{\"t\":2,\"p\":1,\"n\":\"Visual Effect Code\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"}]},{\"t\":2,\"p\":1,\"n\":\"EFII - Icon\"},{\"t\":6,\"p\":1,\"n\":\"EFIX - \",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Override Mask\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":5,\"p\":1,\"n\":\"Base Cost\"},{\"t\":11,\"n\":\"Param #2 - Unknown Type\"},{\"t\":3,\"p\":1,\"n\":\"Param #2 - FormID\"},{\"t\":2,\"p\":1,\"n\":\"Param #2 - Magic Effect Code\"},{\"t\":3,\"p\":1,\"n\":\"Param #2 - Actor Value\"}]}]}]},{\"p\":1,\"n\":\"EFXX - Effects End Marker\"},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"}]}]}]},{\"t\":1,\"p\":1,\"n\":\"KEYM - Key\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"},{\"t\":5,\"p\":1,\"n\":\"MODB - Bound Radius\"},{\"t\":11,\"p\":1,\"n\":\"MODT - Texture Files Hashes\"}]},{\"t\":2,\"p\":1,\"n\":\"ICON - Icon filename\"},{\"t\":3,\"p\":1,\"n\":\"SCRI - Script\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DATA - \",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Value\"},{\"t\":5,\"p\":1,\"n\":\"Weight\"}]}]},{\"t\":1,\"p\":1,\"n\":\"LAND - Landscape\",\"d\":1,\"c\":[{\"t\":11,\"n\":\"DATA - Unknown\"},{\"t\":11,\"n\":\"VNML - Vertex Normals\"},{\"t\":11,\"n\":\"VHGT - Vertext Height Map\"},{\"t\":11,\"n\":\"VCLR - Vertex Colours\"},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Layers\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Base Layer\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"BTXT - Base Layer Header\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Texture\"},{\"t\":3,\"p\":1,\"n\":\"Quadrant\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Layer\"}]}]},{\"t\":6,\"p\":1,\"n\":\"Alpha Layer\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"ATXT - Alpha Layer Header\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Texture\"},{\"t\":3,\"p\":1,\"n\":\"Quadrant\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Layer\"}]},{\"t\":11,\"p\":1,\"n\":\"VTXT - Alpha Layer Data\"}]}]},{\"t\":7,\"p\":1,\"n\":\"VTEX - Textures\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Texture\"}]}]},{\"t\":1,\"p\":1,\"n\":\"LIGH - Light\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"},{\"t\":5,\"p\":1,\"n\":\"MODB - Bound Radius\"},{\"t\":11,\"p\":1,\"n\":\"MODT - Texture Files Hashes\"}]},{\"t\":3,\"p\":1,\"n\":\"SCRI - Script\"},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":2,\"p\":1,\"n\":\"ICON - Icon filename\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DATA - \",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Time\"},{\"t\":3,\"p\":1,\"n\":\"Radius\"},{\"t\":6,\"p\":1,\"n\":\"Color\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":3,\"n\":\"Unused\"}]},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":5,\"p\":1,\"n\":\"Falloff Exponent\"},{\"t\":5,\"p\":1,\"n\":\"FOV\"},{\"t\":3,\"p\":1,\"n\":\"Value\"},{\"t\":5,\"p\":1,\"n\":\"Weight\"}]},{\"t\":5,\"p\":1,\"n\":\"FNAM - Fade value\"},{\"t\":3,\"p\":1,\"n\":\"SNAM - Sound\"}]},{\"t\":1,\"p\":1,\"n\":\"LSCR - Load Screen\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"p\":1,\"n\":\"ICON - Icon filename\"},{\"t\":2,\"p\":1,\"n\":\"DESC - Description\"},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Locations\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"LNAM - Location\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Direct\"},{\"t\":6,\"p\":1,\"n\":\"Indirect\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"World\"},{\"t\":6,\"p\":1,\"n\":\"Grid\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Y\"},{\"t\":3,\"p\":1,\"n\":\"X\"}]}]}]}]}]},{\"t\":1,\"p\":1,\"n\":\"LTEX - Landscape Texture\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"p\":1,\"n\":\"ICON - Icon filename\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"HNAM - Havok Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Material Type\"},{\"t\":3,\"p\":1,\"n\":\"Friction\"},{\"t\":3,\"p\":1,\"n\":\"Restitution\"}]},{\"t\":3,\"p\":1,\"n\":\"SNAM - Texture Specular Exponent\"},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Grasses\",\"d\":1,\"c\":[{\"t\":3,\"p\":1,\"n\":\"GNAM - Grass\"}]}]},{\"t\":1,\"p\":1,\"n\":\"LVLC - Leveled Creature\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":3,\"p\":1,\"n\":\"LVLD - Chance none\"},{\"t\":3,\"p\":1,\"n\":\"LVLF - Flags\"},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Leveled List Entries\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"LVLO - Leveled List Entry\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Level\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":3,\"p\":1,\"n\":\"Count\"}]}]},{\"t\":3,\"p\":1,\"n\":\"SCRI - Script\"},{\"t\":3,\"p\":1,\"n\":\"TNAM - Creature template\"}]},{\"t\":1,\"p\":1,\"n\":\"LVLI - Leveled Item\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":3,\"p\":1,\"n\":\"LVLD - Chance none\"},{\"t\":3,\"p\":1,\"n\":\"LVLF - Flags\"},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Leveled List Entries\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"LVLO - Leveled List Entry\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Level\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":3,\"p\":1,\"n\":\"Count\"}]}]},{\"t\":11,\"n\":\"DATA - Unused\"}]},{\"t\":1,\"p\":1,\"n\":\"LVSP - Leveled Spell\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":3,\"p\":1,\"n\":\"LVLD - Chance none\"},{\"t\":3,\"p\":1,\"n\":\"LVLF - Flags\"},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Leveled List Entries\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"LVLO - Leveled List Entry\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Level\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":3,\"p\":1,\"n\":\"Count\"}]}]}]},{\"t\":1,\"p\":1,\"n\":\"MGEF - Magic Effect\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Magic Effect Code\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"OBME - Oblivion Magic Extender\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Record Version\"},{\"t\":6,\"p\":1,\"n\":\"OBME Version\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Beta\"},{\"t\":3,\"p\":1,\"n\":\"Minor\"},{\"t\":3,\"p\":1,\"n\":\"Major\"}]},{\"t\":3,\"p\":1,\"n\":\"Param A Info\"},{\"t\":3,\"p\":1,\"n\":\"Param B Info\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":2,\"p\":1,\"n\":\"Handler\"},{\"t\":3,\"p\":1,\"n\":\"Flag Overrides\"},{\"t\":11,\"p\":1,\"n\":\"ParamB\"}]},{\"t\":2,\"p\":1,\"n\":\"EDDX - EditorID\"},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":2,\"p\":1,\"n\":\"DESC - Description\"},{\"t\":2,\"p\":1,\"n\":\"ICON - Icon filename\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"},{\"t\":5,\"p\":1,\"n\":\"MODB - Bound Radius\"},{\"t\":11,\"p\":1,\"n\":\"MODT - Texture Files Hashes\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DATA - Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":5,\"p\":1,\"n\":\"Base cost\"},{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Assoc. Weapon\"},{\"t\":3,\"p\":1,\"n\":\"Assoc. Armor\"},{\"t\":3,\"p\":1,\"n\":\"Assoc. Creature\"},{\"t\":3,\"p\":1,\"n\":\"Assoc. Actor Value\"},{\"t\":3,\"p\":1,\"n\":\"Magic School\"},{\"t\":3,\"p\":1,\"n\":\"Resist value\"},{\"t\":3,\"p\":1,\"n\":\"Counter Effect Count\"},{\"t\":3,\"p\":1,\"n\":\"Light\"},{\"t\":5,\"p\":1,\"n\":\"Projectile speed\"},{\"t\":3,\"p\":1,\"n\":\"Effect Shader\"},{\"t\":3,\"p\":1,\"n\":\"Enchant effect\"},{\"t\":3,\"p\":1,\"n\":\"Casting sound\"},{\"t\":3,\"p\":1,\"n\":\"Bolt sound\"},{\"t\":3,\"p\":1,\"n\":\"Hit sound\"},{\"t\":3,\"p\":1,\"n\":\"Area sound\"},{\"t\":5,\"p\":1,\"n\":\"Constant Effect enchantment factor\"},{\"t\":5,\"p\":1,\"n\":\"Constant Effect barter factor\"}]},{\"t\":7,\"p\":1,\"n\":\"ESCE - Counter Effects\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"Counter Effect Code\"}]}]},{\"t\":1,\"p\":1,\"n\":\"MISC - Misc. Item\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"},{\"t\":5,\"p\":1,\"n\":\"MODB - Bound Radius\"},{\"t\":11,\"p\":1,\"n\":\"MODT - Texture Files Hashes\"}]},{\"t\":2,\"p\":1,\"n\":\"ICON - Icon filename\"},{\"t\":3,\"p\":1,\"n\":\"SCRI - Script\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DATA - \",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Value\"},{\"t\":3,\"p\":1,\"n\":\"Actor Value\"},{\"t\":5,\"p\":1,\"n\":\"Weight\"},{\"t\":3,\"p\":1,\"n\":\"Group\"}]}]},{\"t\":1,\"p\":1,\"n\":\"NPC_ - Non-Player Character\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"},{\"t\":5,\"p\":1,\"n\":\"MODB - Bound Radius\"},{\"t\":11,\"p\":1,\"n\":\"MODT - Texture Files Hashes\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"ACBS - Configuration\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":3,\"p\":1,\"n\":\"Base spell points\"},{\"t\":3,\"p\":1,\"n\":\"Fatigue\"},{\"t\":3,\"p\":1,\"n\":\"Barter gold\"},{\"t\":3,\"p\":1,\"n\":\"Level (offset)\"},{\"t\":3,\"p\":1,\"n\":\"Calc min\"},{\"t\":3,\"p\":1,\"n\":\"Calc max\"}]},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Factions\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"SNAM - Faction\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Faction\"},{\"t\":3,\"p\":1,\"n\":\"Rank\"},{\"t\":11,\"n\":\"Unused\"}]}]},{\"t\":3,\"p\":1,\"n\":\"INAM - Death item\"},{\"t\":3,\"p\":1,\"n\":\"RNAM - Race\"},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Items\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"CNTO - Item\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Item\"},{\"t\":3,\"p\":1,\"n\":\"Count\"}]}]},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Spells\",\"d\":1,\"c\":[{\"t\":3,\"p\":1,\"n\":\"SPLO - Spell\"}]},{\"t\":3,\"p\":1,\"n\":\"SCRI - Script\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"AIDT - AI Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Aggression\"},{\"t\":3,\"p\":1,\"n\":\"Confidence\"},{\"t\":3,\"p\":1,\"n\":\"Energy Level\"},{\"t\":3,\"p\":1,\"n\":\"Responsibility\"},{\"t\":3,\"p\":1,\"n\":\"Buys\\/Sells and Services\"},{\"t\":3,\"p\":1,\"n\":\"Teaches\"},{\"t\":3,\"p\":1,\"n\":\"Maximum training level\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"AI Packages\",\"d\":1,\"c\":[{\"t\":3,\"p\":1,\"n\":\"PKID - AI Package\"}]},{\"t\":7,\"p\":1,\"n\":\"KFFZ - Animations\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"Animation\"}]},{\"t\":3,\"p\":1,\"n\":\"CNAM - Class\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DATA - Stats\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Armorer\"},{\"t\":3,\"p\":1,\"n\":\"Athletics\"},{\"t\":3,\"p\":1,\"n\":\"Blade\"},{\"t\":3,\"p\":1,\"n\":\"Block\"},{\"t\":3,\"p\":1,\"n\":\"Blunt\"},{\"t\":3,\"p\":1,\"n\":\"Hand to Hand\"},{\"t\":3,\"p\":1,\"n\":\"Heavy Armor\"},{\"t\":3,\"p\":1,\"n\":\"Alchemy\"},{\"t\":3,\"p\":1,\"n\":\"Alteration\"},{\"t\":3,\"p\":1,\"n\":\"Conjuration\"},{\"t\":3,\"p\":1,\"n\":\"Destruction\"},{\"t\":3,\"p\":1,\"n\":\"Illusion\"},{\"t\":3,\"p\":1,\"n\":\"Mysticism\"},{\"t\":3,\"p\":1,\"n\":\"Restoration\"},{\"t\":3,\"p\":1,\"n\":\"Acrobatics\"},{\"t\":3,\"p\":1,\"n\":\"Light Armor\"},{\"t\":3,\"p\":1,\"n\":\"Marksman\"},{\"t\":3,\"p\":1,\"n\":\"Mercantile\"},{\"t\":3,\"p\":1,\"n\":\"Security\"},{\"t\":3,\"p\":1,\"n\":\"Sneak\"},{\"t\":3,\"p\":1,\"n\":\"Speechcraft\"},{\"t\":3,\"p\":1,\"n\":\"Health\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Strength\"},{\"t\":3,\"p\":1,\"n\":\"Intelligence\"},{\"t\":3,\"p\":1,\"n\":\"Willpower\"},{\"t\":3,\"p\":1,\"n\":\"Agility\"},{\"t\":3,\"p\":1,\"n\":\"Speed\"},{\"t\":3,\"p\":1,\"n\":\"Endurance\"},{\"t\":3,\"p\":1,\"n\":\"Personality\"},{\"t\":3,\"p\":1,\"n\":\"Luck\"}]},{\"t\":3,\"p\":1,\"n\":\"HNAM - Hair\"},{\"t\":5,\"p\":1,\"n\":\"LNAM - Hair length\"},{\"t\":7,\"p\":1,\"n\":\"ENAM - Eyes\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Eyes\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"HCLR - Hair color\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":3,\"p\":1,\"n\":\"ZNAM - Combat Style\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"FaceGen Data\",\"c\":[{\"t\":11,\"p\":1,\"n\":\"FGGS - FaceGen Geometry-Symmetric\"},{\"t\":11,\"p\":1,\"n\":\"FGGA - FaceGen Geometry-Asymmetric\"},{\"t\":11,\"p\":1,\"n\":\"FGTS - FaceGen Texture-Symmetric\"}]},{\"t\":11,\"n\":\"FNAM - Unknown\"}]},{\"t\":1,\"p\":1,\"n\":\"PACK - AI Package\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"General\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"PLDT - Location\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":3,\"p\":1,\"n\":\"Cell\"},{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Object ID\"},{\"t\":3,\"p\":1,\"n\":\"Object type\"},{\"t\":3,\"p\":1,\"n\":\"Radius\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"PSDT - Schedule\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Month\"},{\"t\":3,\"p\":1,\"n\":\"Day of week\"},{\"t\":3,\"p\":1,\"n\":\"Date\"},{\"t\":3,\"p\":1,\"n\":\"Time\"},{\"t\":3,\"p\":1,\"n\":\"Duration\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"PTDT - Target\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":3,\"p\":1,\"n\":\"Object ID\"},{\"t\":3,\"p\":1,\"n\":\"Object type\"},{\"t\":3,\"p\":1,\"n\":\"Count\"}]},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Conditions\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"CTDA - Condition\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":5,\"p\":1,\"n\":\"Comparison Value - Float\"},{\"t\":3,\"p\":1,\"n\":\"Comparison Value - Global\"},{\"t\":3,\"p\":1,\"n\":\"Function\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":11,\"p\":1,\"n\":\"None\"},{\"t\":3,\"p\":1,\"n\":\"Integer\"},{\"t\":3,\"p\":1,\"n\":\"Variable Name (INVALID)\"},{\"t\":3,\"p\":1,\"n\":\"Sex\"},{\"t\":3,\"p\":1,\"n\":\"Actor Value\"},{\"t\":3,\"p\":1,\"n\":\"Crime Type\"},{\"t\":3,\"p\":1,\"n\":\"Axis\"},{\"t\":3,\"p\":1,\"n\":\"Form Type\"},{\"t\":3,\"p\":1,\"n\":\"Quest Stage (INVALID)\"},{\"t\":3,\"p\":1,\"n\":\"Object Reference\"},{\"t\":3,\"p\":1,\"n\":\"Inventory Object\"},{\"t\":3,\"p\":1,\"n\":\"Actor\"},{\"t\":3,\"p\":1,\"n\":\"Quest\"},{\"t\":3,\"p\":1,\"n\":\"Faction\"},{\"t\":3,\"p\":1,\"n\":\"Cell\"},{\"t\":3,\"p\":1,\"n\":\"Class\"},{\"t\":3,\"p\":1,\"n\":\"Race\"},{\"t\":3,\"p\":1,\"n\":\"Actor Base\"},{\"t\":3,\"p\":1,\"n\":\"Global\"},{\"t\":3,\"p\":1,\"n\":\"Weather\"},{\"t\":3,\"p\":1,\"n\":\"Package\"},{\"t\":3,\"p\":1,\"n\":\"Owner\"},{\"t\":3,\"p\":1,\"n\":\"Birthsign\"},{\"t\":3,\"p\":1,\"n\":\"Furniture\"},{\"t\":3,\"p\":1,\"n\":\"Magic Item\"},{\"t\":3,\"p\":1,\"n\":\"Magic Effect\"},{\"t\":3,\"p\":1,\"n\":\"Worldspace\"},{\"t\":3,\"p\":1,\"n\":\"Referenceable Object\"},{\"t\":3,\"p\":1,\"n\":\"Variable Name\"},{\"t\":3,\"p\":1,\"n\":\"Quest Stage\"}]},{\"t\":6,\"p\":1,\"n\":\"CTDT - Condition (old format)\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":5,\"p\":1,\"n\":\"Comparison Value - Float\"},{\"t\":3,\"p\":1,\"n\":\"Comparison Value - Global\"},{\"t\":3,\"p\":1,\"n\":\"Function\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":11,\"p\":1,\"n\":\"None\"},{\"t\":3,\"p\":1,\"n\":\"Integer\"},{\"t\":3,\"p\":1,\"n\":\"Variable Name (INVALID)\"},{\"t\":3,\"p\":1,\"n\":\"Sex\"},{\"t\":3,\"p\":1,\"n\":\"Actor Value\"},{\"t\":3,\"p\":1,\"n\":\"Crime Type\"},{\"t\":3,\"p\":1,\"n\":\"Axis\"},{\"t\":3,\"p\":1,\"n\":\"Form Type\"},{\"t\":3,\"p\":1,\"n\":\"Quest Stage (INVALID)\"},{\"t\":3,\"p\":1,\"n\":\"Object Reference\"},{\"t\":3,\"p\":1,\"n\":\"Inventory Object\"},{\"t\":3,\"p\":1,\"n\":\"Actor\"},{\"t\":3,\"p\":1,\"n\":\"Quest\"},{\"t\":3,\"p\":1,\"n\":\"Faction\"},{\"t\":3,\"p\":1,\"n\":\"Cell\"},{\"t\":3,\"p\":1,\"n\":\"Class\"},{\"t\":3,\"p\":1,\"n\":\"Race\"},{\"t\":3,\"p\":1,\"n\":\"Actor Base\"},{\"t\":3,\"p\":1,\"n\":\"Global\"},{\"t\":3,\"p\":1,\"n\":\"Weather\"},{\"t\":3,\"p\":1,\"n\":\"Package\"},{\"t\":3,\"p\":1,\"n\":\"Owner\"},{\"t\":3,\"p\":1,\"n\":\"Birthsign\"},{\"t\":3,\"p\":1,\"n\":\"Furniture\"},{\"t\":3,\"p\":1,\"n\":\"Magic Item\"},{\"t\":3,\"p\":1,\"n\":\"Magic Effect\"},{\"t\":3,\"p\":1,\"n\":\"Worldspace\"},{\"t\":3,\"p\":1,\"n\":\"Referenceable Object\"},{\"t\":3,\"p\":1,\"n\":\"Variable Name\"},{\"t\":3,\"p\":1,\"n\":\"Quest Stage\"}]}]}]},{\"t\":1,\"p\":1,\"n\":\"PGRD - Path Grid\",\"d\":1,\"c\":[{\"t\":3,\"n\":\"DATA - Point Count\"},{\"t\":7,\"p\":1,\"n\":\"PGRP - Points\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Point\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"X\"},{\"t\":5,\"p\":1,\"n\":\"Y\"},{\"t\":5,\"p\":1,\"n\":\"Z (Even = Red\\/Orange, Odd = Blue)\"},{\"t\":3,\"p\":1,\"n\":\"Connections\"},{\"t\":11,\"n\":\"Unused\"}]}]},{\"t\":11,\"n\":\"PGAG - Unknown\"},{\"t\":7,\"p\":1,\"n\":\"PGRR - Point-to-Point Connections\",\"c\":[{\"t\":7,\"p\":1,\"n\":\"Point\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Point\"}]}]},{\"t\":7,\"p\":1,\"n\":\"PGRI - Inter-Cell Connections\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Inter-Cell Connection\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Point\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":5,\"p\":1,\"n\":\"X\"},{\"t\":5,\"p\":1,\"n\":\"Y\"},{\"t\":5,\"p\":1,\"n\":\"Z\"}]}]},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Point-to-Reference Mappings\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"PGRL - Point-to-Reference Mapping\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":7,\"p\":1,\"n\":\"Points\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Point\"}]}]}]}]},{\"t\":1,\"p\":1,\"n\":\"QUST - Quest\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":3,\"p\":1,\"n\":\"SCRI - Script\"},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":2,\"p\":1,\"n\":\"ICON - Icon filename\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DATA - General\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":3,\"p\":1,\"n\":\"Priority\"}]},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Conditions\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"CTDA - Condition\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":5,\"p\":1,\"n\":\"Comparison Value - Float\"},{\"t\":3,\"p\":1,\"n\":\"Comparison Value - Global\"},{\"t\":3,\"p\":1,\"n\":\"Function\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":11,\"p\":1,\"n\":\"None\"},{\"t\":3,\"p\":1,\"n\":\"Integer\"},{\"t\":3,\"p\":1,\"n\":\"Variable Name (INVALID)\"},{\"t\":3,\"p\":1,\"n\":\"Sex\"},{\"t\":3,\"p\":1,\"n\":\"Actor Value\"},{\"t\":3,\"p\":1,\"n\":\"Crime Type\"},{\"t\":3,\"p\":1,\"n\":\"Axis\"},{\"t\":3,\"p\":1,\"n\":\"Form Type\"},{\"t\":3,\"p\":1,\"n\":\"Quest Stage (INVALID)\"},{\"t\":3,\"p\":1,\"n\":\"Object Reference\"},{\"t\":3,\"p\":1,\"n\":\"Inventory Object\"},{\"t\":3,\"p\":1,\"n\":\"Actor\"},{\"t\":3,\"p\":1,\"n\":\"Quest\"},{\"t\":3,\"p\":1,\"n\":\"Faction\"},{\"t\":3,\"p\":1,\"n\":\"Cell\"},{\"t\":3,\"p\":1,\"n\":\"Class\"},{\"t\":3,\"p\":1,\"n\":\"Race\"},{\"t\":3,\"p\":1,\"n\":\"Actor Base\"},{\"t\":3,\"p\":1,\"n\":\"Global\"},{\"t\":3,\"p\":1,\"n\":\"Weather\"},{\"t\":3,\"p\":1,\"n\":\"Package\"},{\"t\":3,\"p\":1,\"n\":\"Owner\"},{\"t\":3,\"p\":1,\"n\":\"Birthsign\"},{\"t\":3,\"p\":1,\"n\":\"Furniture\"},{\"t\":3,\"p\":1,\"n\":\"Magic Item\"},{\"t\":3,\"p\":1,\"n\":\"Magic Effect\"},{\"t\":3,\"p\":1,\"n\":\"Worldspace\"},{\"t\":3,\"p\":1,\"n\":\"Referenceable Object\"},{\"t\":3,\"p\":1,\"n\":\"Variable Name\"},{\"t\":3,\"p\":1,\"n\":\"Quest Stage\"}]},{\"t\":6,\"p\":1,\"n\":\"CTDT - Condition (old format)\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":5,\"p\":1,\"n\":\"Comparison Value - Float\"},{\"t\":3,\"p\":1,\"n\":\"Comparison Value - Global\"},{\"t\":3,\"p\":1,\"n\":\"Function\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":11,\"p\":1,\"n\":\"None\"},{\"t\":3,\"p\":1,\"n\":\"Integer\"},{\"t\":3,\"p\":1,\"n\":\"Variable Name (INVALID)\"},{\"t\":3,\"p\":1,\"n\":\"Sex\"},{\"t\":3,\"p\":1,\"n\":\"Actor Value\"},{\"t\":3,\"p\":1,\"n\":\"Crime Type\"},{\"t\":3,\"p\":1,\"n\":\"Axis\"},{\"t\":3,\"p\":1,\"n\":\"Form Type\"},{\"t\":3,\"p\":1,\"n\":\"Quest Stage (INVALID)\"},{\"t\":3,\"p\":1,\"n\":\"Object Reference\"},{\"t\":3,\"p\":1,\"n\":\"Inventory Object\"},{\"t\":3,\"p\":1,\"n\":\"Actor\"},{\"t\":3,\"p\":1,\"n\":\"Quest\"},{\"t\":3,\"p\":1,\"n\":\"Faction\"},{\"t\":3,\"p\":1,\"n\":\"Cell\"},{\"t\":3,\"p\":1,\"n\":\"Class\"},{\"t\":3,\"p\":1,\"n\":\"Race\"},{\"t\":3,\"p\":1,\"n\":\"Actor Base\"},{\"t\":3,\"p\":1,\"n\":\"Global\"},{\"t\":3,\"p\":1,\"n\":\"Weather\"},{\"t\":3,\"p\":1,\"n\":\"Package\"},{\"t\":3,\"p\":1,\"n\":\"Owner\"},{\"t\":3,\"p\":1,\"n\":\"Birthsign\"},{\"t\":3,\"p\":1,\"n\":\"Furniture\"},{\"t\":3,\"p\":1,\"n\":\"Magic Item\"},{\"t\":3,\"p\":1,\"n\":\"Magic Effect\"},{\"t\":3,\"p\":1,\"n\":\"Worldspace\"},{\"t\":3,\"p\":1,\"n\":\"Referenceable Object\"},{\"t\":3,\"p\":1,\"n\":\"Variable Name\"},{\"t\":3,\"p\":1,\"n\":\"Quest Stage\"}]}]},{\"t\":10,\"p\":1,\"n\":\"Stages\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Stage\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"INDX - Stage index\"},{\"t\":8,\"p\":1,\"n\":\"Log Entries\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Log Entry\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"QSDT - Stage Flags\"},{\"t\":8,\"p\":1,\"n\":\"Conditions\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"CTDA - Condition\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":5,\"p\":1,\"n\":\"Comparison Value - Float\"},{\"t\":3,\"p\":1,\"n\":\"Comparison Value - Global\"},{\"t\":3,\"p\":1,\"n\":\"Function\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":11,\"p\":1,\"n\":\"None\"},{\"t\":3,\"p\":1,\"n\":\"Integer\"},{\"t\":3,\"p\":1,\"n\":\"Variable Name (INVALID)\"},{\"t\":3,\"p\":1,\"n\":\"Sex\"},{\"t\":3,\"p\":1,\"n\":\"Actor Value\"},{\"t\":3,\"p\":1,\"n\":\"Crime Type\"},{\"t\":3,\"p\":1,\"n\":\"Axis\"},{\"t\":3,\"p\":1,\"n\":\"Form Type\"},{\"t\":3,\"p\":1,\"n\":\"Quest Stage (INVALID)\"},{\"t\":3,\"p\":1,\"n\":\"Object Reference\"},{\"t\":3,\"p\":1,\"n\":\"Inventory Object\"},{\"t\":3,\"p\":1,\"n\":\"Actor\"},{\"t\":3,\"p\":1,\"n\":\"Quest\"},{\"t\":3,\"p\":1,\"n\":\"Faction\"},{\"t\":3,\"p\":1,\"n\":\"Cell\"},{\"t\":3,\"p\":1,\"n\":\"Class\"},{\"t\":3,\"p\":1,\"n\":\"Race\"},{\"t\":3,\"p\":1,\"n\":\"Actor Base\"},{\"t\":3,\"p\":1,\"n\":\"Global\"},{\"t\":3,\"p\":1,\"n\":\"Weather\"},{\"t\":3,\"p\":1,\"n\":\"Package\"},{\"t\":3,\"p\":1,\"n\":\"Owner\"},{\"t\":3,\"p\":1,\"n\":\"Birthsign\"},{\"t\":3,\"p\":1,\"n\":\"Furniture\"},{\"t\":3,\"p\":1,\"n\":\"Magic Item\"},{\"t\":3,\"p\":1,\"n\":\"Magic Effect\"},{\"t\":3,\"p\":1,\"n\":\"Worldspace\"},{\"t\":3,\"p\":1,\"n\":\"Referenceable Object\"},{\"t\":3,\"p\":1,\"n\":\"Variable Name\"},{\"t\":3,\"p\":1,\"n\":\"Quest Stage\"}]},{\"t\":6,\"p\":1,\"n\":\"CTDT - Condition (old format)\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":5,\"p\":1,\"n\":\"Comparison Value - Float\"},{\"t\":3,\"p\":1,\"n\":\"Comparison Value - Global\"},{\"t\":3,\"p\":1,\"n\":\"Function\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":11,\"p\":1,\"n\":\"None\"},{\"t\":3,\"p\":1,\"n\":\"Integer\"},{\"t\":3,\"p\":1,\"n\":\"Variable Name (INVALID)\"},{\"t\":3,\"p\":1,\"n\":\"Sex\"},{\"t\":3,\"p\":1,\"n\":\"Actor Value\"},{\"t\":3,\"p\":1,\"n\":\"Crime Type\"},{\"t\":3,\"p\":1,\"n\":\"Axis\"},{\"t\":3,\"p\":1,\"n\":\"Form Type\"},{\"t\":3,\"p\":1,\"n\":\"Quest Stage (INVALID)\"},{\"t\":3,\"p\":1,\"n\":\"Object Reference\"},{\"t\":3,\"p\":1,\"n\":\"Inventory Object\"},{\"t\":3,\"p\":1,\"n\":\"Actor\"},{\"t\":3,\"p\":1,\"n\":\"Quest\"},{\"t\":3,\"p\":1,\"n\":\"Faction\"},{\"t\":3,\"p\":1,\"n\":\"Cell\"},{\"t\":3,\"p\":1,\"n\":\"Class\"},{\"t\":3,\"p\":1,\"n\":\"Race\"},{\"t\":3,\"p\":1,\"n\":\"Actor Base\"},{\"t\":3,\"p\":1,\"n\":\"Global\"},{\"t\":3,\"p\":1,\"n\":\"Weather\"},{\"t\":3,\"p\":1,\"n\":\"Package\"},{\"t\":3,\"p\":1,\"n\":\"Owner\"},{\"t\":3,\"p\":1,\"n\":\"Birthsign\"},{\"t\":3,\"p\":1,\"n\":\"Furniture\"},{\"t\":3,\"p\":1,\"n\":\"Magic Item\"},{\"t\":3,\"p\":1,\"n\":\"Magic Effect\"},{\"t\":3,\"p\":1,\"n\":\"Worldspace\"},{\"t\":3,\"p\":1,\"n\":\"Referenceable Object\"},{\"t\":3,\"p\":1,\"n\":\"Variable Name\"},{\"t\":3,\"p\":1,\"n\":\"Quest Stage\"}]}]},{\"t\":2,\"p\":1,\"n\":\"CNAM - Log Entry\"},{\"t\":6,\"p\":1,\"n\":\"Result Script\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"SCHR - Basic Script Data\",\"c\":[{\"t\":11,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"RefCount\"},{\"t\":3,\"p\":1,\"n\":\"CompiledSize\"},{\"t\":3,\"p\":1,\"n\":\"VariableCount\"},{\"t\":3,\"p\":1,\"n\":\"Type\"}]},{\"t\":6,\"p\":1,\"n\":\"SCHD - Basic Script Data\",\"c\":[{\"t\":11,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"RefCount\"},{\"t\":3,\"p\":1,\"n\":\"CompiledSize\"},{\"t\":3,\"p\":1,\"n\":\"VariableCount\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":11,\"p\":1,\"n\":\"SCDA - Compiled result script\"},{\"t\":2,\"p\":1,\"n\":\"SCTX - Result script source\"},{\"t\":8,\"p\":1,\"n\":\"References\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"SCRO - Global Reference\"},{\"t\":3,\"p\":1,\"n\":\"SCRV - Local Variable\"}]}]}]}]}]}]},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Targets\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Target\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"QSTA - Target\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Target\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":8,\"p\":1,\"n\":\"Conditions\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"CTDA - Condition\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":5,\"p\":1,\"n\":\"Comparison Value - Float\"},{\"t\":3,\"p\":1,\"n\":\"Comparison Value - Global\"},{\"t\":3,\"p\":1,\"n\":\"Function\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":11,\"p\":1,\"n\":\"None\"},{\"t\":3,\"p\":1,\"n\":\"Integer\"},{\"t\":3,\"p\":1,\"n\":\"Variable Name (INVALID)\"},{\"t\":3,\"p\":1,\"n\":\"Sex\"},{\"t\":3,\"p\":1,\"n\":\"Actor Value\"},{\"t\":3,\"p\":1,\"n\":\"Crime Type\"},{\"t\":3,\"p\":1,\"n\":\"Axis\"},{\"t\":3,\"p\":1,\"n\":\"Form Type\"},{\"t\":3,\"p\":1,\"n\":\"Quest Stage (INVALID)\"},{\"t\":3,\"p\":1,\"n\":\"Object Reference\"},{\"t\":3,\"p\":1,\"n\":\"Inventory Object\"},{\"t\":3,\"p\":1,\"n\":\"Actor\"},{\"t\":3,\"p\":1,\"n\":\"Quest\"},{\"t\":3,\"p\":1,\"n\":\"Faction\"},{\"t\":3,\"p\":1,\"n\":\"Cell\"},{\"t\":3,\"p\":1,\"n\":\"Class\"},{\"t\":3,\"p\":1,\"n\":\"Race\"},{\"t\":3,\"p\":1,\"n\":\"Actor Base\"},{\"t\":3,\"p\":1,\"n\":\"Global\"},{\"t\":3,\"p\":1,\"n\":\"Weather\"},{\"t\":3,\"p\":1,\"n\":\"Package\"},{\"t\":3,\"p\":1,\"n\":\"Owner\"},{\"t\":3,\"p\":1,\"n\":\"Birthsign\"},{\"t\":3,\"p\":1,\"n\":\"Furniture\"},{\"t\":3,\"p\":1,\"n\":\"Magic Item\"},{\"t\":3,\"p\":1,\"n\":\"Magic Effect\"},{\"t\":3,\"p\":1,\"n\":\"Worldspace\"},{\"t\":3,\"p\":1,\"n\":\"Referenceable Object\"},{\"t\":3,\"p\":1,\"n\":\"Variable Name\"},{\"t\":3,\"p\":1,\"n\":\"Quest Stage\"}]},{\"t\":6,\"p\":1,\"n\":\"CTDT - Condition (old format)\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":5,\"p\":1,\"n\":\"Comparison Value - Float\"},{\"t\":3,\"p\":1,\"n\":\"Comparison Value - Global\"},{\"t\":3,\"p\":1,\"n\":\"Function\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":11,\"p\":1,\"n\":\"None\"},{\"t\":3,\"p\":1,\"n\":\"Integer\"},{\"t\":3,\"p\":1,\"n\":\"Variable Name (INVALID)\"},{\"t\":3,\"p\":1,\"n\":\"Sex\"},{\"t\":3,\"p\":1,\"n\":\"Actor Value\"},{\"t\":3,\"p\":1,\"n\":\"Crime Type\"},{\"t\":3,\"p\":1,\"n\":\"Axis\"},{\"t\":3,\"p\":1,\"n\":\"Form Type\"},{\"t\":3,\"p\":1,\"n\":\"Quest Stage (INVALID)\"},{\"t\":3,\"p\":1,\"n\":\"Object Reference\"},{\"t\":3,\"p\":1,\"n\":\"Inventory Object\"},{\"t\":3,\"p\":1,\"n\":\"Actor\"},{\"t\":3,\"p\":1,\"n\":\"Quest\"},{\"t\":3,\"p\":1,\"n\":\"Faction\"},{\"t\":3,\"p\":1,\"n\":\"Cell\"},{\"t\":3,\"p\":1,\"n\":\"Class\"},{\"t\":3,\"p\":1,\"n\":\"Race\"},{\"t\":3,\"p\":1,\"n\":\"Actor Base\"},{\"t\":3,\"p\":1,\"n\":\"Global\"},{\"t\":3,\"p\":1,\"n\":\"Weather\"},{\"t\":3,\"p\":1,\"n\":\"Package\"},{\"t\":3,\"p\":1,\"n\":\"Owner\"},{\"t\":3,\"p\":1,\"n\":\"Birthsign\"},{\"t\":3,\"p\":1,\"n\":\"Furniture\"},{\"t\":3,\"p\":1,\"n\":\"Magic Item\"},{\"t\":3,\"p\":1,\"n\":\"Magic Effect\"},{\"t\":3,\"p\":1,\"n\":\"Worldspace\"},{\"t\":3,\"p\":1,\"n\":\"Referenceable Object\"},{\"t\":3,\"p\":1,\"n\":\"Variable Name\"},{\"t\":3,\"p\":1,\"n\":\"Quest Stage\"}]}]}]}]}]},{\"t\":1,\"p\":1,\"n\":\"RACE - Race\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":2,\"p\":1,\"n\":\"DESC - Description\"},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Spells\",\"d\":1,\"c\":[{\"t\":3,\"p\":1,\"n\":\"SPLO - Spell\"}]},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Relations\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"XNAM - Relation\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Faction\"},{\"t\":3,\"p\":1,\"n\":\"Modifier\"}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DATA - \",\"c\":[{\"t\":7,\"p\":1,\"n\":\"Skill Boosts\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Skill Boost\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Skill\"},{\"t\":3,\"p\":1,\"n\":\"Boost\"}]}]},{\"t\":11,\"n\":\"Unused\"},{\"t\":5,\"p\":1,\"n\":\"Male Height\"},{\"t\":5,\"p\":1,\"n\":\"Female Height\"},{\"t\":5,\"p\":1,\"n\":\"Male Weight\"},{\"t\":5,\"p\":1,\"n\":\"Female Weight\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"VNAM - Voice\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Male\"},{\"t\":3,\"p\":1,\"n\":\"Female\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DNAM - Default Hair\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Male\"},{\"t\":3,\"p\":1,\"n\":\"Female\"}]},{\"t\":3,\"p\":1,\"n\":\"CNAM - Default Hair Color\"},{\"t\":5,\"p\":1,\"n\":\"PNAM - FaceGen - Main clamp\"},{\"t\":5,\"p\":1,\"n\":\"UNAM - FaceGen - Face clamp\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"ATTR - Base Attributes\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Male\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Strength\"},{\"t\":3,\"p\":1,\"n\":\"Intelligence\"},{\"t\":3,\"p\":1,\"n\":\"Willpower\"},{\"t\":3,\"p\":1,\"n\":\"Agility\"},{\"t\":3,\"p\":1,\"n\":\"Speed\"},{\"t\":3,\"p\":1,\"n\":\"Endurance\"},{\"t\":3,\"p\":1,\"n\":\"Personality\"},{\"t\":3,\"p\":1,\"n\":\"Luck\"}]},{\"t\":6,\"p\":1,\"n\":\"Female\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Strength\"},{\"t\":3,\"p\":1,\"n\":\"Intelligence\"},{\"t\":3,\"p\":1,\"n\":\"Willpower\"},{\"t\":3,\"p\":1,\"n\":\"Agility\"},{\"t\":3,\"p\":1,\"n\":\"Speed\"},{\"t\":3,\"p\":1,\"n\":\"Endurance\"},{\"t\":3,\"p\":1,\"n\":\"Personality\"},{\"t\":3,\"p\":1,\"n\":\"Luck\"}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Face Data\",\"c\":[{\"p\":1,\"n\":\"NAM0 - Face Data Marker\"},{\"t\":10,\"p\":1,\"n\":\"Parts\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Part\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"INDX - Index\"},{\"t\":6,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"},{\"t\":5,\"p\":1,\"n\":\"MODB - Bound Radius\"},{\"t\":11,\"p\":1,\"n\":\"MODT - Texture Files Hashes\"}]},{\"t\":2,\"p\":1,\"n\":\"ICON - Icon filename\"}]}]}]},{\"p\":1,\"n\":\"NAM1 - Body Data Marker\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Male Body Data\",\"c\":[{\"p\":1,\"n\":\"MNAM - Male Body Data Marker\"},{\"t\":6,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"},{\"t\":5,\"p\":1,\"n\":\"MODB - Bound Radius\"},{\"t\":11,\"p\":1,\"n\":\"MODT - Texture Files Hashes\"}]},{\"t\":10,\"p\":1,\"n\":\"Parts\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Part\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"INDX - Index\"},{\"t\":2,\"p\":1,\"n\":\"ICON - Icon filename\"}]}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Female Body Data\",\"c\":[{\"p\":1,\"n\":\"FNAM - Female Body Data Marker\"},{\"t\":6,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"},{\"t\":5,\"p\":1,\"n\":\"MODB - Bound Radius\"},{\"t\":11,\"p\":1,\"n\":\"MODT - Texture Files Hashes\"}]},{\"t\":10,\"p\":1,\"n\":\"Parts\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Part\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"INDX - Index\"},{\"t\":2,\"p\":1,\"n\":\"ICON - Icon filename\"}]}]}]},{\"t\":7,\"s\":1,\"p\":1,\"n\":\"HNAM - Hairs\",\"d\":1,\"c\":[{\"t\":3,\"p\":1,\"n\":\"Hair\"}]},{\"t\":7,\"s\":1,\"p\":1,\"n\":\"ENAM - Eyes\",\"d\":1,\"c\":[{\"t\":3,\"p\":1,\"n\":\"Eye\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"FaceGen Data\",\"c\":[{\"t\":11,\"p\":1,\"n\":\"FGGS - FaceGen Geometry-Symmetric\"},{\"t\":11,\"p\":1,\"n\":\"FGGA - FaceGen Geometry-Asymmetric\"},{\"t\":11,\"p\":1,\"n\":\"FGTS - FaceGen Texture-Symmetric\"}]},{\"t\":11,\"n\":\"SNAM - Unknown\"}]},{\"t\":1,\"p\":1,\"n\":\"REFR - Placed Object\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":3,\"p\":1,\"n\":\"NAME - Base\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"XTEL - Teleport Destination\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Door\"},{\"t\":6,\"p\":1,\"n\":\"Position\\/Rotation\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Position\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"X\"},{\"t\":5,\"p\":1,\"n\":\"Y\"},{\"t\":5,\"p\":1,\"n\":\"Z\"}]},{\"t\":6,\"p\":1,\"n\":\"Rotation\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"X\"},{\"t\":5,\"p\":1,\"n\":\"Y\"},{\"t\":5,\"p\":1,\"n\":\"Z\"}]}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"XLOC - Lock information\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Lock Level\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Key\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Ownership\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"XOWN - Owner\"},{\"t\":3,\"p\":1,\"n\":\"XRNK - Faction rank\"},{\"t\":3,\"p\":1,\"n\":\"XGLB - Global variable\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"XESP - Enable Parent\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":3,\"p\":1,\"n\":\"XTRG - Target\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"XSED - SpeedTree\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Seed\"},{\"n\":\"Unused\"}]},{\"t\":7,\"n\":\"XLOD - Distant LOD Data\",\"c\":[{\"t\":5,\"n\":\"Unknown\"}]},{\"t\":5,\"p\":1,\"n\":\"XCHG - Charge\"},{\"t\":3,\"p\":1,\"n\":\"XHLT - Health\"},{\"t\":6,\"n\":\"Unused\",\"c\":[{\"t\":3,\"n\":\"XPCI - Unused\"},{\"t\":2,\"n\":\"FULL - Unused\"}]},{\"t\":3,\"p\":1,\"n\":\"XLCM - Level Modifier\"},{\"t\":3,\"n\":\"XRTM - Unknown\"},{\"t\":3,\"p\":1,\"n\":\"XACT - Action Flag\"},{\"t\":3,\"p\":1,\"n\":\"XCNT - Count\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Map Marker\",\"c\":[{\"p\":1,\"n\":\"XMRK - Map Marker Data\"},{\"t\":3,\"p\":1,\"n\":\"FNAM - Map Flags\"},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":6,\"p\":1,\"n\":\"TNAM - \",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":11,\"n\":\"Unused\"}]}]},{\"p\":1,\"n\":\"ONAM - Open by Default\"},{\"t\":11,\"n\":\"XRGD - Ragdoll Data\"},{\"t\":5,\"p\":1,\"n\":\"XSCL - Scale\"},{\"t\":3,\"p\":1,\"n\":\"XSOL - Contained Soul\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DATA - Position\\/Rotation\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Position\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"X\"},{\"t\":5,\"p\":1,\"n\":\"Y\"},{\"t\":5,\"p\":1,\"n\":\"Z\"}]},{\"t\":6,\"p\":1,\"n\":\"Rotation\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"X\"},{\"t\":5,\"p\":1,\"n\":\"Y\"},{\"t\":5,\"p\":1,\"n\":\"Z\"}]}]}]},{\"t\":1,\"p\":1,\"n\":\"REGN - Region\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"p\":1,\"n\":\"ICON - Icon filename\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"RCLR - Map Color\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":3,\"p\":1,\"n\":\"WNAM - Worldspace\"},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Region Areas\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Region Area\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"RPLI - Edge Fall-off\"},{\"t\":7,\"p\":1,\"n\":\"RPLD - Region Point List Data\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Point\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"X\"},{\"t\":5,\"p\":1,\"n\":\"Y\"}]}]}]}]},{\"t\":10,\"p\":1,\"n\":\"Region Data Entries\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Region Data Entry\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"RDAT - Data Header\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":3,\"p\":1,\"n\":\"Priority\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":7,\"p\":1,\"n\":\"RDOT - Objects\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Object\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Object\"},{\"t\":3,\"p\":1,\"n\":\"Parent Index\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":5,\"p\":1,\"n\":\"Density\"},{\"t\":3,\"p\":1,\"n\":\"Clustering\"},{\"t\":3,\"p\":1,\"n\":\"Min Slope\"},{\"t\":3,\"p\":1,\"n\":\"Max Slope\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":3,\"p\":1,\"n\":\"Radius wrt Parent\"},{\"t\":3,\"p\":1,\"n\":\"Radius\"},{\"t\":5,\"p\":1,\"n\":\"Min Height\"},{\"t\":5,\"p\":1,\"n\":\"Max Height\"},{\"t\":5,\"p\":1,\"n\":\"Sink\"},{\"t\":5,\"p\":1,\"n\":\"Sink Variance\"},{\"t\":5,\"p\":1,\"n\":\"Size Variance\"},{\"t\":6,\"p\":1,\"n\":\"Angle Variance\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"X\"},{\"t\":3,\"p\":1,\"n\":\"Y\"},{\"t\":3,\"p\":1,\"n\":\"Z\"}]},{\"t\":11,\"n\":\"Unknown\"}]}]},{\"t\":2,\"p\":1,\"n\":\"RDMP - Map Name\"},{\"t\":7,\"p\":1,\"n\":\"RDGS - Grasses\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Grass\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Grass\"},{\"t\":11,\"n\":\"Unused\"}]}]},{\"t\":3,\"p\":1,\"n\":\"RDMD - Music Type\"},{\"t\":7,\"p\":1,\"n\":\"RDSD - Sounds\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Sound\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Sound\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":3,\"p\":1,\"n\":\"Chance\"}]}]},{\"t\":7,\"p\":1,\"n\":\"RDWT - Weather Types\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Weather Type\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Weather\"},{\"t\":3,\"p\":1,\"n\":\"Chance\"}]}]}]}]}]},{\"t\":1,\"p\":1,\"n\":\"ROAD - Road\",\"d\":1,\"c\":[{\"t\":7,\"p\":1,\"n\":\"PGRP - Points\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Point\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"X\"},{\"t\":5,\"p\":1,\"n\":\"Y\"},{\"t\":5,\"p\":1,\"n\":\"Z (Even = Red\\/Orange, Odd = Blue)\"},{\"t\":3,\"p\":1,\"n\":\"Connections\"},{\"t\":11,\"n\":\"Unused\"}]}]},{\"t\":7,\"p\":1,\"n\":\"PGRR - Point-to-Point Connections (complex structure can't be represented, see source)\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Point\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"X\"},{\"t\":5,\"p\":1,\"n\":\"Y\"},{\"t\":5,\"p\":1,\"n\":\"Z\"}]}]}]},{\"t\":1,\"p\":1,\"n\":\"SBSP - Subspace\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DNAM - \",\"c\":[{\"t\":5,\"p\":1,\"n\":\"X\"},{\"t\":5,\"p\":1,\"n\":\"Y\"},{\"t\":5,\"p\":1,\"n\":\"Z\"}]}]},{\"t\":1,\"p\":1,\"n\":\"SCPT - Script\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":11,\"n\":\"SCHD - Unknown (Script Header?)\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"SCHR - Basic Script Data\",\"c\":[{\"t\":11,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"RefCount\"},{\"t\":3,\"p\":1,\"n\":\"CompiledSize\"},{\"t\":3,\"p\":1,\"n\":\"VariableCount\"},{\"t\":3,\"p\":1,\"n\":\"Type\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"SCHD - Basic Script Data\",\"c\":[{\"t\":11,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"RefCount\"},{\"t\":3,\"p\":1,\"n\":\"CompiledSize\"},{\"t\":3,\"p\":1,\"n\":\"VariableCount\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":11,\"n\":\"SCDA - Compiled Script\"},{\"t\":2,\"p\":1,\"n\":\"SCTX - Script Source\"},{\"t\":10,\"p\":1,\"n\":\"Local Variables\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Local Variable\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"SLSD - Local Variable Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Index\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"}]},{\"t\":2,\"p\":1,\"n\":\"SCVR - Name\"}]}]},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"References\",\"d\":1,\"c\":[{\"t\":3,\"p\":1,\"n\":\"SCRO - Global Reference\"},{\"t\":3,\"p\":1,\"n\":\"SCRV - Local Variable\"}]}]},{\"t\":1,\"p\":1,\"n\":\"SGST - Sigil Stone\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"OBME - Oblivion Magic Extender\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Record Version\"},{\"t\":6,\"p\":1,\"n\":\"OBME Version\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Beta\"},{\"t\":3,\"p\":1,\"n\":\"Minor\"},{\"t\":3,\"p\":1,\"n\":\"Major\"}]},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"},{\"t\":5,\"p\":1,\"n\":\"MODB - Bound Radius\"},{\"t\":11,\"p\":1,\"n\":\"MODT - Texture Files Hashes\"}]},{\"t\":2,\"p\":1,\"n\":\"ICON - Icon filename\"},{\"t\":3,\"p\":1,\"n\":\"SCRI - Script\"},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Effects\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Effect\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"EFID - Magic effect name\"},{\"t\":6,\"p\":1,\"n\":\"EFIT - \",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Magic effect name\"},{\"t\":3,\"p\":1,\"n\":\"Magnitude\"},{\"t\":3,\"p\":1,\"n\":\"Area\"},{\"t\":3,\"p\":1,\"n\":\"Duration\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Actor Value\"}]},{\"t\":6,\"p\":1,\"n\":\"Script effect\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"SCIT - Script effect data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Script effect\"},{\"t\":3,\"p\":1,\"n\":\"Magic school\"},{\"t\":3,\"p\":1,\"n\":\"Visual effect name\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"}]}]},{\"t\":6,\"p\":1,\"n\":\"Effects\",\"c\":[{\"t\":8,\"p\":1,\"n\":\"Effects\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Effect\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"EFME - Oblivion Magic Extender\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Record Version\"},{\"t\":6,\"p\":1,\"n\":\"OBME Version\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Beta\"},{\"t\":3,\"p\":1,\"n\":\"Minor\"},{\"t\":3,\"p\":1,\"n\":\"Major\"}]},{\"t\":3,\"p\":1,\"n\":\"EFIT Param Info\"},{\"t\":3,\"p\":1,\"n\":\"EFIX Param Info\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":2,\"p\":1,\"n\":\"EFID - Magic Effect Code\"},{\"t\":6,\"p\":1,\"n\":\"EFIT - \",\"c\":[{\"t\":2,\"p\":1,\"n\":\"Magic Effect Code\"},{\"t\":3,\"p\":1,\"n\":\"Magnitude\"},{\"t\":3,\"p\":1,\"n\":\"Area\"},{\"t\":3,\"p\":1,\"n\":\"Duration\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":11,\"n\":\"Param #1 - Unknown Type\"},{\"t\":3,\"p\":1,\"n\":\"Param #1 - FormID\"},{\"t\":2,\"p\":1,\"n\":\"Param #1 - Magic Effect Code\"},{\"t\":3,\"p\":1,\"n\":\"Param #1 - Actor Value\"}]},{\"t\":6,\"p\":1,\"n\":\"Script effect\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"SCIT - Script effect data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Script effect\"},{\"t\":3,\"p\":1,\"n\":\"Magic school\"},{\"t\":2,\"p\":1,\"n\":\"Visual Effect Code\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"}]},{\"t\":2,\"p\":1,\"n\":\"EFII - Icon\"},{\"t\":6,\"p\":1,\"n\":\"EFIX - \",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Override Mask\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":5,\"p\":1,\"n\":\"Base Cost\"},{\"t\":11,\"n\":\"Param #2 - Unknown Type\"},{\"t\":3,\"p\":1,\"n\":\"Param #2 - FormID\"},{\"t\":2,\"p\":1,\"n\":\"Param #2 - Magic Effect Code\"},{\"t\":3,\"p\":1,\"n\":\"Param #2 - Actor Value\"}]}]}]},{\"p\":1,\"n\":\"EFXX - Effects End Marker\"},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DATA - \",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Uses \"},{\"t\":3,\"p\":1,\"n\":\"Value\"},{\"t\":5,\"p\":1,\"n\":\"Weight\"}]}]},{\"t\":1,\"p\":1,\"n\":\"SKIL - Skill\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":3,\"p\":1,\"n\":\"INDX - Skill\"},{\"t\":2,\"p\":1,\"n\":\"DESC - Description\"},{\"t\":2,\"p\":1,\"n\":\"ICON - Icon filename\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DATA - Skill Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Action\"},{\"t\":3,\"p\":1,\"n\":\"Attribute\"},{\"t\":3,\"p\":1,\"n\":\"Specialization\"},{\"t\":7,\"p\":1,\"n\":\"Use Values\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Use Value\"}]}]},{\"t\":2,\"p\":1,\"n\":\"ANAM - Apprentice Text\"},{\"t\":2,\"p\":1,\"n\":\"JNAM - Journeyman Text\"},{\"t\":2,\"p\":1,\"n\":\"ENAM - Expert Text\"},{\"t\":2,\"p\":1,\"n\":\"MNAM - Master Text\"}]},{\"t\":1,\"p\":1,\"n\":\"SLGM - Soul Gem\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"},{\"t\":5,\"p\":1,\"n\":\"MODB - Bound Radius\"},{\"t\":11,\"p\":1,\"n\":\"MODT - Texture Files Hashes\"}]},{\"t\":2,\"p\":1,\"n\":\"ICON - Icon filename\"},{\"t\":3,\"p\":1,\"n\":\"SCRI - Script\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DATA - \",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Value\"},{\"t\":5,\"p\":1,\"n\":\"Weight\"}]},{\"t\":3,\"p\":1,\"n\":\"SOUL - Contained Soul\"},{\"t\":3,\"p\":1,\"n\":\"SLCP - Maximum Capacity\"}]},{\"t\":1,\"p\":1,\"n\":\"SOUN - Sound\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"p\":1,\"n\":\"FNAM - Sound Filename\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"SNDX - Sound Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Minimum attenuation distance\"},{\"t\":3,\"p\":1,\"n\":\"Maximum attenuation distance\"},{\"t\":3,\"p\":1,\"n\":\"Frequency adjustment %\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":3,\"p\":1,\"n\":\"Static Attenuation (db)\"},{\"t\":3,\"p\":1,\"n\":\"Stop time\"},{\"t\":3,\"p\":1,\"n\":\"Start time\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"SNDD - Sound Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Minimum attenuation distance\"},{\"t\":3,\"p\":1,\"n\":\"Maximum attenuation distance\"},{\"t\":3,\"p\":1,\"n\":\"Frequency adjustment %\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"}]}]},{\"t\":1,\"p\":1,\"n\":\"SPEL - Spell\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"OBME - Oblivion Magic Extender\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Record Version\"},{\"t\":6,\"p\":1,\"n\":\"OBME Version\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Beta\"},{\"t\":3,\"p\":1,\"n\":\"Minor\"},{\"t\":3,\"p\":1,\"n\":\"Major\"}]},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"SPIT - \",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Cost\"},{\"t\":3,\"p\":1,\"n\":\"Level\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Effects\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Effect\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"EFID - Magic effect name\"},{\"t\":6,\"p\":1,\"n\":\"EFIT - \",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Magic effect name\"},{\"t\":3,\"p\":1,\"n\":\"Magnitude\"},{\"t\":3,\"p\":1,\"n\":\"Area\"},{\"t\":3,\"p\":1,\"n\":\"Duration\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Actor Value\"}]},{\"t\":6,\"p\":1,\"n\":\"Script effect\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"SCIT - Script effect data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Script effect\"},{\"t\":3,\"p\":1,\"n\":\"Magic school\"},{\"t\":3,\"p\":1,\"n\":\"Visual effect name\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"}]}]},{\"t\":6,\"p\":1,\"n\":\"Effects\",\"c\":[{\"t\":8,\"p\":1,\"n\":\"Effects\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Effect\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"EFME - Oblivion Magic Extender\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Record Version\"},{\"t\":6,\"p\":1,\"n\":\"OBME Version\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Beta\"},{\"t\":3,\"p\":1,\"n\":\"Minor\"},{\"t\":3,\"p\":1,\"n\":\"Major\"}]},{\"t\":3,\"p\":1,\"n\":\"EFIT Param Info\"},{\"t\":3,\"p\":1,\"n\":\"EFIX Param Info\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":2,\"p\":1,\"n\":\"EFID - Magic Effect Code\"},{\"t\":6,\"p\":1,\"n\":\"EFIT - \",\"c\":[{\"t\":2,\"p\":1,\"n\":\"Magic Effect Code\"},{\"t\":3,\"p\":1,\"n\":\"Magnitude\"},{\"t\":3,\"p\":1,\"n\":\"Area\"},{\"t\":3,\"p\":1,\"n\":\"Duration\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":11,\"n\":\"Param #1 - Unknown Type\"},{\"t\":3,\"p\":1,\"n\":\"Param #1 - FormID\"},{\"t\":2,\"p\":1,\"n\":\"Param #1 - Magic Effect Code\"},{\"t\":3,\"p\":1,\"n\":\"Param #1 - Actor Value\"}]},{\"t\":6,\"p\":1,\"n\":\"Script effect\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"SCIT - Script effect data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Script effect\"},{\"t\":3,\"p\":1,\"n\":\"Magic school\"},{\"t\":2,\"p\":1,\"n\":\"Visual Effect Code\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"}]},{\"t\":2,\"p\":1,\"n\":\"EFII - Icon\"},{\"t\":6,\"p\":1,\"n\":\"EFIX - \",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Override Mask\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":5,\"p\":1,\"n\":\"Base Cost\"},{\"t\":11,\"n\":\"Param #2 - Unknown Type\"},{\"t\":3,\"p\":1,\"n\":\"Param #2 - FormID\"},{\"t\":2,\"p\":1,\"n\":\"Param #2 - Magic Effect Code\"},{\"t\":3,\"p\":1,\"n\":\"Param #2 - Actor Value\"}]}]}]},{\"p\":1,\"n\":\"EFXX - Effects End Marker\"},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"}]}]}]},{\"t\":1,\"p\":1,\"n\":\"STAT - Static\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"},{\"t\":5,\"p\":1,\"n\":\"MODB - Bound Radius\"},{\"t\":11,\"p\":1,\"n\":\"MODT - Texture Files Hashes\"}]}]},{\"t\":1,\"p\":1,\"n\":\"TREE - Tree\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"},{\"t\":5,\"p\":1,\"n\":\"MODB - Bound Radius\"},{\"t\":11,\"p\":1,\"n\":\"MODT - Texture Files Hashes\"}]},{\"t\":2,\"p\":1,\"n\":\"ICON - Icon filename\"},{\"t\":7,\"p\":1,\"n\":\"SNAM - SpeedTree Seeds\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"SpeedTree Seed\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"CNAM - Tree Data\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Leaf Curvature\"},{\"t\":5,\"p\":1,\"n\":\"Minimum Leaf Angle\"},{\"t\":5,\"p\":1,\"n\":\"Maximum Leaf Angle\"},{\"t\":5,\"p\":1,\"n\":\"Branch Dimming Value\"},{\"t\":5,\"p\":1,\"n\":\"Leaf Dimming Value\"},{\"t\":3,\"p\":1,\"n\":\"Shadow Radius\"},{\"t\":5,\"p\":1,\"n\":\"Rock Speed\"},{\"t\":5,\"p\":1,\"n\":\"Rustle Speed\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"BNAM - Billboard Dimensions\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Width\"},{\"t\":5,\"p\":1,\"n\":\"Height\"}]}]},{\"t\":1,\"p\":1,\"n\":\"WATR - Water\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"p\":1,\"n\":\"TNAM - Texture\"},{\"t\":3,\"p\":1,\"n\":\"ANAM - Opacity\"},{\"t\":3,\"p\":1,\"n\":\"FNAM - Flags\"},{\"t\":2,\"p\":1,\"n\":\"MNAM - Material ID\"},{\"t\":3,\"p\":1,\"n\":\"SNAM - Sound\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DATA - \",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Wind Velocity\"},{\"t\":5,\"p\":1,\"n\":\"Wind Direction\"},{\"t\":5,\"p\":1,\"n\":\"Wave Amplitude\"},{\"t\":5,\"p\":1,\"n\":\"Wave Frequency\"},{\"t\":5,\"p\":1,\"n\":\"Sun Power\"},{\"t\":5,\"p\":1,\"n\":\"Reflectivity Amount\"},{\"t\":5,\"p\":1,\"n\":\"Fresnel Amount\"},{\"t\":5,\"p\":1,\"n\":\"Scroll X Speed\"},{\"t\":5,\"p\":1,\"n\":\"Scroll Y Speed\"},{\"t\":5,\"p\":1,\"n\":\"Fog Distance - Near Plane\"},{\"t\":5,\"p\":1,\"n\":\"Fog Distance - Far Plane\"},{\"t\":6,\"p\":1,\"n\":\"Shallow Color\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Deep Color\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Reflection Color\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":3,\"p\":1,\"n\":\"Texture Blend\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":5,\"p\":1,\"n\":\"Rain Simulator - Force\"},{\"t\":5,\"p\":1,\"n\":\"Rain Simulator - Velocity\"},{\"t\":5,\"p\":1,\"n\":\"Rain Simulator - Falloff\"},{\"t\":5,\"p\":1,\"n\":\"Rain Simulator - Dampner\"},{\"t\":5,\"p\":1,\"n\":\"Rain Simulator - Starting Size\"},{\"t\":5,\"p\":1,\"n\":\"Displacement Simulator - Force\"},{\"t\":5,\"p\":1,\"n\":\"Displacement Simulator - Velocity\"},{\"t\":5,\"p\":1,\"n\":\"Displacement Simulator - Falloff\"},{\"t\":5,\"p\":1,\"n\":\"Displacement Simulator - Dampner\"},{\"t\":5,\"p\":1,\"n\":\"Displacement Simulator - Starting Size\"},{\"t\":3,\"p\":1,\"n\":\"Damage\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"GNAM - Related Waters\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Daytime\"},{\"t\":3,\"p\":1,\"n\":\"Nighttime\"},{\"t\":3,\"p\":1,\"n\":\"Underwater\"}]}]},{\"t\":1,\"p\":1,\"n\":\"WEAP - Weapon\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"},{\"t\":5,\"p\":1,\"n\":\"MODB - Bound Radius\"},{\"t\":11,\"p\":1,\"n\":\"MODT - Texture Files Hashes\"}]},{\"t\":2,\"p\":1,\"n\":\"ICON - Icon filename\"},{\"t\":3,\"p\":1,\"n\":\"SCRI - Script\"},{\"t\":3,\"p\":1,\"n\":\"ENAM - Enchantment\"},{\"t\":3,\"p\":1,\"n\":\"ANAM - Enchantment Points\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DATA - \",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":5,\"p\":1,\"n\":\"Speed\"},{\"t\":5,\"p\":1,\"n\":\"Reach\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":3,\"p\":1,\"n\":\"Value\"},{\"t\":3,\"p\":1,\"n\":\"Health\"},{\"t\":5,\"p\":1,\"n\":\"Weight\"},{\"t\":3,\"p\":1,\"n\":\"Damage\"}]}]},{\"t\":1,\"p\":1,\"n\":\"WRLD - Worldspace\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Parent\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"WNAM - Worldspace\"}]},{\"t\":3,\"p\":1,\"n\":\"CNAM - Climate\"},{\"t\":3,\"p\":1,\"n\":\"NAM2 - Water\"},{\"t\":2,\"p\":1,\"n\":\"ICON - Icon filename\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"MNAM - Map Data\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Usable Dimensions\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"X\"},{\"t\":3,\"p\":1,\"n\":\"Y\"}]},{\"t\":6,\"p\":1,\"n\":\"Cell Coordinates\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"NW Cell\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"X\"},{\"t\":3,\"p\":1,\"n\":\"Y\"}]},{\"t\":6,\"p\":1,\"n\":\"SE Cell\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"X\"},{\"t\":3,\"p\":1,\"n\":\"Y\"}]}]}]},{\"t\":3,\"p\":1,\"n\":\"DATA - Flags\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Object Bounds\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"NAM0 - Min\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"X\"},{\"t\":5,\"p\":1,\"n\":\"Y\"}]},{\"t\":6,\"p\":1,\"n\":\"NAM9 - Max\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"X\"},{\"t\":5,\"p\":1,\"n\":\"Y\"}]}]},{\"t\":3,\"p\":1,\"n\":\"SNAM - Music\"},{\"t\":11,\"n\":\"OFST - Offset Data\"}]},{\"t\":1,\"p\":1,\"n\":\"WTHR - Weather\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"p\":1,\"n\":\"CNAM - Texture Lower Layer\"},{\"t\":2,\"p\":1,\"n\":\"DNAM - Texture Upper Layer\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"},{\"t\":5,\"p\":1,\"n\":\"MODB - Bound Radius\"},{\"t\":11,\"p\":1,\"n\":\"MODT - Texture Files Hashes\"}]},{\"t\":7,\"p\":1,\"n\":\"NAM0 - Colors by Types\\/Times\",\"c\":[{\"t\":7,\"p\":1,\"n\":\"Type\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Time\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"FNAM - Fog Distance\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Day Near\"},{\"t\":5,\"p\":1,\"n\":\"Day Far\"},{\"t\":5,\"p\":1,\"n\":\"Night Near\"},{\"t\":5,\"p\":1,\"n\":\"Night Far\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"HNAM - HDR Data\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Eye Adapt Speed\"},{\"t\":5,\"p\":1,\"n\":\"Blur Radius\"},{\"t\":5,\"p\":1,\"n\":\"Blur Passes\"},{\"t\":5,\"p\":1,\"n\":\"Emissive Mult\"},{\"t\":5,\"p\":1,\"n\":\"Target LUM\"},{\"t\":5,\"p\":1,\"n\":\"Upper LUM Clamp\"},{\"t\":5,\"p\":1,\"n\":\"Bright Scale\"},{\"t\":5,\"p\":1,\"n\":\"Bright Clamp\"},{\"t\":5,\"p\":1,\"n\":\"LUM Ramp No Tex\"},{\"t\":5,\"p\":1,\"n\":\"LUM Ramp Min\"},{\"t\":5,\"p\":1,\"n\":\"LUM Ramp Max\"},{\"t\":5,\"p\":1,\"n\":\"Sunlight Dimmer\"},{\"t\":5,\"p\":1,\"n\":\"Grass Dimmer\"},{\"t\":5,\"p\":1,\"n\":\"Tree Dimmer\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DATA - \",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Wind Speed\"},{\"t\":3,\"p\":1,\"n\":\"Cloud Speed (Lower)\"},{\"t\":3,\"p\":1,\"n\":\"Cloud Speed (Upper)\"},{\"t\":3,\"p\":1,\"n\":\"Trans Delta\"},{\"t\":3,\"p\":1,\"n\":\"Sun Glare\"},{\"t\":3,\"p\":1,\"n\":\"Sun Damage\"},{\"t\":3,\"p\":1,\"n\":\"Precipitation - Begin Fade In\"},{\"t\":3,\"p\":1,\"n\":\"Precipitation - End Fade Out\"},{\"t\":3,\"p\":1,\"n\":\"Thunder\\/Lightning - Begin Fade In\"},{\"t\":3,\"p\":1,\"n\":\"Thunder\\/Lightning - End Fade Out\"},{\"t\":3,\"p\":1,\"n\":\"Thunder\\/Lightning - Frequency\"},{\"t\":3,\"p\":1,\"n\":\"Weather Classification\"},{\"t\":6,\"p\":1,\"n\":\"Lightning Color\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"}]}]},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Sounds\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"SNAM - Sound\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Sound\"},{\"t\":3,\"p\":1,\"n\":\"Type\"}]}]}]},{\"t\":1,\"p\":1,\"n\":\"ACHR - Placed NPC\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":3,\"p\":1,\"n\":\"NAME - Base\"},{\"t\":6,\"n\":\"Unused\",\"c\":[{\"t\":3,\"n\":\"XPCI - Unused\"},{\"t\":2,\"n\":\"FULL - Unused\"}]},{\"t\":7,\"n\":\"XLOD - Distant LOD Data\",\"c\":[{\"t\":5,\"n\":\"Unknown\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"XESP - Enable Parent\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":3,\"p\":1,\"n\":\"XMRC - Merchant container\"},{\"t\":3,\"p\":1,\"n\":\"XHRS - Horse\"},{\"t\":11,\"n\":\"XRGD - Ragdoll Data\"},{\"t\":5,\"p\":1,\"n\":\"XSCL - Scale\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DATA - Position\\/Rotation\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Position\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"X\"},{\"t\":5,\"p\":1,\"n\":\"Y\"},{\"t\":5,\"p\":1,\"n\":\"Z\"}]},{\"t\":6,\"p\":1,\"n\":\"Rotation\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"X\"},{\"t\":5,\"p\":1,\"n\":\"Y\"},{\"t\":5,\"p\":1,\"n\":\"Z\"}]}]}]}]},\"name\":\"Smash.All\",\"hash\":\"E9DB3045\",\"color\":128}"
  },
  {
    "path": "frontend/settings/Skyrim/Bash.Actors.ACBS.json",
    "content": "{\"records\":\"NPC_\",\"description\":\"Actors.ACBS tag from Wrye Bash.\\r\\n\\r\\nUsed when the mod modifies NPC ACBS configuration.\",\"tree\":{\"records\":[{\"t\":1,\"p\":1,\"n\":\"NPC_ - Non-Player Character (Actor)\",\"c\":[{\"t\":6,\"n\":\"Record Header\",\"c\":[{\"t\":2,\"n\":\"Signature\"},{\"t\":3,\"n\":\"Data Size\"},{\"t\":3,\"n\":\"Record Flags\"},{\"t\":3,\"n\":\"FormID\"},{\"t\":11,\"n\":\"Version Control Info 1\"},{\"t\":3,\"n\":\"Form Version\"},{\"t\":11,\"n\":\"Version Control Info 2\"}]},{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"n\":\"VMAD - Virtual Machine Adapter\",\"c\":[{\"t\":3,\"n\":\"Version\"},{\"t\":3,\"n\":\"Object Format\"},{\"t\":12,\"n\":\"Data\",\"c\":[{\"t\":9,\"n\":\"Scripts\",\"c\":[{\"t\":6,\"n\":\"Script\",\"c\":[{\"t\":2,\"n\":\"scriptName\"},{\"t\":3,\"n\":\"Flags\"},{\"t\":9,\"n\":\"Properties\",\"c\":[{\"t\":6,\"n\":\"Property\",\"c\":[{\"t\":2,\"n\":\"propertyName\"},{\"t\":3,\"n\":\"Type\"},{\"t\":3,\"n\":\"Flags\"},{\"t\":12,\"n\":\"Value\"}]}]}]}]}]}]},{\"t\":6,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"n\":\"X1\"},{\"t\":3,\"n\":\"Y1\"},{\"t\":3,\"n\":\"Z1\"},{\"t\":3,\"n\":\"X2\"},{\"t\":3,\"n\":\"Y2\"},{\"t\":3,\"n\":\"Z2\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"ACBS - Configuration\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":3,\"p\":1,\"n\":\"Magicka Offset\"},{\"t\":3,\"p\":1,\"n\":\"Stamina Offset\"},{\"t\":12,\"p\":1,\"n\":\"Level\"},{\"t\":3,\"p\":1,\"n\":\"Calc min level\"},{\"t\":3,\"p\":1,\"n\":\"Calc max level\"},{\"t\":3,\"p\":1,\"n\":\"Speed Multiplier\"},{\"t\":3,\"p\":1,\"n\":\"Disposition Base (unused)\"},{\"t\":3,\"p\":1,\"n\":\"Template Flags\"},{\"t\":3,\"p\":1,\"n\":\"Health Offset\"},{\"t\":3,\"p\":1,\"n\":\"Bleedout Override\"}]},{\"t\":10,\"n\":\"Factions\",\"c\":[{\"t\":6,\"n\":\"SNAM - Faction\",\"c\":[{\"t\":3,\"n\":\"Faction\"},{\"t\":3,\"n\":\"Rank\"},{\"t\":11,\"n\":\"Unused\"}]}]},{\"t\":3,\"n\":\"INAM - Death item\"},{\"t\":3,\"n\":\"VTCK - Voice\"},{\"t\":3,\"n\":\"TPLT - Template\"},{\"t\":3,\"n\":\"RNAM - Race\"},{\"t\":3,\"n\":\"SPCT - Count\"},{\"t\":9,\"n\":\"Actor Effects\",\"c\":[{\"t\":3,\"n\":\"SPLO - Actor Effect\"}]},{\"t\":6,\"n\":\"Destructable\",\"c\":[{\"t\":6,\"n\":\"DEST - Header\",\"c\":[{\"t\":3,\"n\":\"Health\"},{\"t\":3,\"n\":\"DEST Count\"},{\"t\":3,\"n\":\"VATS Targetable\"},{\"t\":11,\"n\":\"Unknown\"}]}]},{\"t\":3,\"n\":\"WNAM - Worn Armor\"},{\"t\":3,\"n\":\"ANAM - Far away model\"},{\"t\":3,\"n\":\"ATKR - Attack Race\"},{\"t\":10,\"n\":\"Attacks\",\"c\":[{\"t\":6,\"n\":\"Attack\",\"c\":[{\"t\":6,\"n\":\"ATKD - Attack Data\",\"c\":[{\"t\":5,\"n\":\"Damage Mult\"},{\"t\":5,\"n\":\"Attack Chance\"},{\"t\":3,\"n\":\"Attack Spell\"},{\"t\":3,\"n\":\"Attack Flags\"},{\"t\":5,\"n\":\"Attack Angle\"},{\"t\":5,\"n\":\"Strike Angle\"},{\"t\":5,\"n\":\"Stagger\"},{\"t\":3,\"n\":\"Attack Type\"},{\"t\":5,\"n\":\"Knockdown\"},{\"t\":5,\"n\":\"Recovery Time\"},{\"t\":5,\"n\":\"Stamina Mult\"}]}]}]},{\"t\":3,\"n\":\"SPOR - Spectator override package list\"},{\"t\":3,\"n\":\"OCOR - Observe dead body override package list\"},{\"t\":3,\"n\":\"GWOR - Guard warn override package list\"},{\"t\":3,\"n\":\"ECOR - Combat override package list\"},{\"t\":3,\"n\":\"PRKZ - Perk Count\"},{\"t\":10,\"n\":\"Perks\",\"c\":[{\"t\":6,\"n\":\"PRKR - Perk\",\"c\":[{\"t\":3,\"n\":\"Perk\"},{\"t\":3,\"n\":\"Rank\"},{\"t\":11,\"n\":\"Unused\"}]}]},{\"t\":3,\"n\":\"COCT - Count\"},{\"t\":10,\"n\":\"Items\",\"c\":[{\"t\":6,\"n\":\"Item\",\"c\":[{\"t\":6,\"n\":\"CNTO - Item\",\"c\":[{\"t\":3,\"n\":\"Item\"},{\"t\":3,\"n\":\"Count\"}]}]}]},{\"t\":6,\"n\":\"AIDT - AI Data\",\"c\":[{\"t\":3,\"n\":\"Aggression\"},{\"t\":3,\"n\":\"Confidence\"},{\"t\":3,\"n\":\"Energy Level\"},{\"t\":3,\"n\":\"Responsibility\"},{\"t\":3,\"n\":\"Mood\"},{\"t\":3,\"n\":\"Assistance\"},{\"t\":6,\"n\":\"Aggro\",\"c\":[{\"t\":3,\"n\":\"Aggro Radius Behavior\"},{\"t\":3,\"n\":\"Unknown\"},{\"t\":3,\"n\":\"Warn\"},{\"t\":3,\"n\":\"Warn\\/Attack\"},{\"t\":3,\"n\":\"Attack\"}]}]},{\"t\":7,\"n\":\"Packages\",\"c\":[{\"t\":3,\"n\":\"PKID - Package\"}]},{\"t\":3,\"n\":\"KSIZ - Keyword Count\"},{\"t\":9,\"n\":\"KWDA - Keywords\",\"c\":[{\"t\":3,\"n\":\"Keyword\"}]},{\"t\":3,\"n\":\"CNAM - Class\"},{\"t\":2,\"n\":\"FULL - Name\"},{\"t\":2,\"n\":\"SHRT - Short Name\"},{\"t\":11,\"n\":\"DATA - Marker\"},{\"t\":6,\"n\":\"DNAM - Player Skills\",\"c\":[{\"t\":7,\"n\":\"Skill Values\",\"c\":[{\"t\":3,\"n\":\"Skill #0 (OneHanded)\"},{\"t\":3,\"n\":\"Skill #1 (TwoHanded)\"},{\"t\":3,\"n\":\"Skill #2 (Marksman)\"},{\"t\":3,\"n\":\"Skill #3 (Block)\"},{\"t\":3,\"n\":\"Skill #4 (Smithing)\"},{\"t\":3,\"n\":\"Skill #5 (HeavyArmor)\"},{\"t\":3,\"n\":\"Skill #6 (LightArmor)\"},{\"t\":3,\"n\":\"Skill #7 (Pickpocket)\"},{\"t\":3,\"n\":\"Skill #8 (Lockpicking)\"},{\"t\":3,\"n\":\"Skill #9 (Sneak)\"},{\"t\":3,\"n\":\"Skill #10 (Alchemy)\"},{\"t\":3,\"n\":\"Skill #11 (Speechcraft)\"},{\"t\":3,\"n\":\"Skill #12 (Alteration)\"},{\"t\":3,\"n\":\"Skill #13 (Conjuration)\"},{\"t\":3,\"n\":\"Skill #14 (Destruction)\"},{\"t\":3,\"n\":\"Skill #15 (Illusion)\"},{\"t\":3,\"n\":\"Skill #16 (Restoration)\"},{\"t\":3,\"n\":\"Skill #17 (Enchanting)\"}]},{\"t\":7,\"n\":\"Skill Offsets\",\"c\":[{\"t\":3,\"n\":\"Skill #0 (OneHanded)\"},{\"t\":3,\"n\":\"Skill #1 (TwoHanded)\"},{\"t\":3,\"n\":\"Skill #2 (Marksman)\"},{\"t\":3,\"n\":\"Skill #3 (Block)\"},{\"t\":3,\"n\":\"Skill #4 (Smithing)\"},{\"t\":3,\"n\":\"Skill #5 (HeavyArmor)\"},{\"t\":3,\"n\":\"Skill #6 (LightArmor)\"},{\"t\":3,\"n\":\"Skill #7 (Pickpocket)\"},{\"t\":3,\"n\":\"Skill #8 (Lockpicking)\"},{\"t\":3,\"n\":\"Skill #9 (Sneak)\"},{\"t\":3,\"n\":\"Skill #10 (Alchemy)\"},{\"t\":3,\"n\":\"Skill #11 (Speechcraft)\"},{\"t\":3,\"n\":\"Skill #12 (Alteration)\"},{\"t\":3,\"n\":\"Skill #13 (Conjuration)\"},{\"t\":3,\"n\":\"Skill #14 (Destruction)\"},{\"t\":3,\"n\":\"Skill #15 (Illusion)\"},{\"t\":3,\"n\":\"Skill #16 (Restoration)\"},{\"t\":3,\"n\":\"Skill #17 (Enchanting)\"}]},{\"t\":3,\"n\":\"Health\"},{\"t\":3,\"n\":\"Magicka\"},{\"t\":3,\"n\":\"Stamina\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":5,\"n\":\"Far away model distance\"},{\"t\":3,\"n\":\"Geared up weapons\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":9,\"n\":\"Head Parts\",\"c\":[{\"t\":3,\"n\":\"PNAM - Head Part\"}]},{\"t\":3,\"n\":\"HCLF - Hair Color\"},{\"t\":3,\"n\":\"ZNAM - Combat Style\"},{\"t\":3,\"n\":\"GNAM - Gift Filter\"},{\"t\":11,\"n\":\"NAM5 - Unknown\"},{\"t\":5,\"n\":\"NAM6 - Height\"},{\"t\":5,\"n\":\"NAM7 - Weight\"},{\"t\":3,\"n\":\"NAM8 - Sound Level\"},{\"t\":10,\"n\":\"Sound Types\",\"c\":[{\"t\":6,\"n\":\"Sound Type\",\"c\":[{\"t\":3,\"n\":\"CSDT - Type\"},{\"t\":10,\"n\":\"Sounds\",\"c\":[{\"t\":6,\"n\":\"Sound\",\"c\":[{\"t\":3,\"n\":\"CSDI - Sound\"},{\"t\":3,\"n\":\"CSDC - Sound Chance\"}]}]}]}]},{\"t\":3,\"n\":\"CSCR - Inherits Sounds From\"},{\"t\":3,\"n\":\"DOFT - Default outfit\"},{\"t\":3,\"n\":\"SOFT - Sleeping outfit\"},{\"t\":3,\"n\":\"DPLT - Default Package List\"},{\"t\":3,\"n\":\"CRIF - Crime faction\"},{\"t\":3,\"n\":\"FTST - Head texture\"},{\"t\":6,\"n\":\"QNAM - Texture lighting\",\"c\":[{\"t\":5,\"n\":\"Red\"},{\"t\":5,\"n\":\"Green\"},{\"t\":5,\"n\":\"Blue\"}]},{\"t\":6,\"n\":\"NAM9 - Face morph\",\"c\":[{\"t\":5,\"n\":\"Nose Long\\/Short\"},{\"t\":5,\"n\":\"Nose Up\\/Down\"},{\"t\":5,\"n\":\"Jaw Up\\/Down\"},{\"t\":5,\"n\":\"Jaw Narrow\\/Wide\"},{\"t\":5,\"n\":\"Jaw Farward\\/Back\"},{\"t\":5,\"n\":\"Cheeks Up\\/Down\"},{\"t\":5,\"n\":\"Cheeks Farward\\/Back\"},{\"t\":5,\"n\":\"Eyes Up\\/Down\"},{\"t\":5,\"n\":\"Eyes In\\/Out\"},{\"t\":5,\"n\":\"Brows Up\\/Down\"},{\"t\":5,\"n\":\"Brows In\\/Out\"},{\"t\":5,\"n\":\"Brows Farward\\/Back\"},{\"t\":5,\"n\":\"Lips Up\\/Down\"},{\"t\":5,\"n\":\"Lips In\\/Out\"},{\"t\":5,\"n\":\"Chin Narrow\\/Wide\"},{\"t\":5,\"n\":\"Chin Up\\/Down\"},{\"t\":5,\"n\":\"Chin Underbite\\/Overbite\"},{\"t\":5,\"n\":\"Eyes Farward\\/Back\"},{\"t\":5,\"n\":\"Unknown\"}]},{\"t\":6,\"n\":\"NAMA - Face parts\",\"c\":[{\"t\":3,\"n\":\"Nose\"},{\"t\":3,\"n\":\"Unknown\"},{\"t\":3,\"n\":\"Eyes\"},{\"t\":3,\"n\":\"Mouth\"}]},{\"t\":10,\"n\":\"Tint Layers\",\"c\":[{\"t\":6,\"n\":\"Layer\",\"c\":[{\"t\":3,\"n\":\"TINI - Tint Index\"}]}]}]}]},\"name\":\"Bash.Actors.ACBS\",\"hash\":\"$75515CF0\",\"color\":255}"
  },
  {
    "path": "frontend/settings/Skyrim/Bash.Actors.AIData.json",
    "content": "{\"records\":\"NPC_\",\"description\":\"Actors.AIData tag from Wrye Bash.\\r\\n\\r\\nUsed when the mod modifies NPC AI data.\",\"tree\":{\"records\":[{\"t\":1,\"p\":1,\"n\":\"NPC_ - Non-Player Character (Actor)\",\"c\":[{\"t\":6,\"n\":\"Record Header\",\"c\":[{\"t\":2,\"n\":\"Signature\"},{\"t\":3,\"n\":\"Data Size\"},{\"t\":3,\"n\":\"Record Flags\"},{\"t\":3,\"n\":\"FormID\"},{\"t\":11,\"n\":\"Version Control Info 1\"},{\"t\":3,\"n\":\"Form Version\"},{\"t\":11,\"n\":\"Version Control Info 2\"}]},{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"n\":\"VMAD - Virtual Machine Adapter\",\"c\":[{\"t\":3,\"n\":\"Version\"},{\"t\":3,\"n\":\"Object Format\"},{\"t\":12,\"n\":\"Data\",\"c\":[{\"t\":9,\"n\":\"Scripts\",\"c\":[{\"t\":6,\"n\":\"Script\",\"c\":[{\"t\":2,\"n\":\"scriptName\"},{\"t\":3,\"n\":\"Flags\"},{\"t\":9,\"n\":\"Properties\",\"c\":[{\"t\":6,\"n\":\"Property\",\"c\":[{\"t\":2,\"n\":\"propertyName\"},{\"t\":3,\"n\":\"Type\"},{\"t\":3,\"n\":\"Flags\"},{\"t\":12,\"n\":\"Value\"}]}]}]}]}]}]},{\"t\":6,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"n\":\"X1\"},{\"t\":3,\"n\":\"Y1\"},{\"t\":3,\"n\":\"Z1\"},{\"t\":3,\"n\":\"X2\"},{\"t\":3,\"n\":\"Y2\"},{\"t\":3,\"n\":\"Z2\"}]},{\"t\":6,\"n\":\"ACBS - Configuration\",\"c\":[{\"t\":3,\"n\":\"Flags\"},{\"t\":3,\"n\":\"Magicka Offset\"},{\"t\":3,\"n\":\"Stamina Offset\"},{\"t\":12,\"n\":\"Level\"},{\"t\":3,\"n\":\"Calc min level\"},{\"t\":3,\"n\":\"Calc max level\"},{\"t\":3,\"n\":\"Speed Multiplier\"},{\"t\":3,\"n\":\"Disposition Base (unused)\"},{\"t\":3,\"n\":\"Template Flags\"},{\"t\":3,\"n\":\"Health Offset\"},{\"t\":3,\"n\":\"Bleedout Override\"}]},{\"t\":10,\"n\":\"Factions\",\"c\":[{\"t\":6,\"n\":\"SNAM - Faction\",\"c\":[{\"t\":3,\"n\":\"Faction\"},{\"t\":3,\"n\":\"Rank\"},{\"t\":11,\"n\":\"Unused\"}]}]},{\"t\":3,\"n\":\"INAM - Death item\"},{\"t\":3,\"n\":\"VTCK - Voice\"},{\"t\":3,\"n\":\"TPLT - Template\"},{\"t\":3,\"n\":\"RNAM - Race\"},{\"t\":3,\"n\":\"SPCT - Count\"},{\"t\":9,\"n\":\"Actor Effects\",\"c\":[{\"t\":3,\"n\":\"SPLO - Actor Effect\"}]},{\"t\":6,\"n\":\"Destructable\",\"c\":[{\"t\":6,\"n\":\"DEST - Header\",\"c\":[{\"t\":3,\"n\":\"Health\"},{\"t\":3,\"n\":\"DEST Count\"},{\"t\":3,\"n\":\"VATS Targetable\"},{\"t\":11,\"n\":\"Unknown\"}]}]},{\"t\":3,\"n\":\"WNAM - Worn Armor\"},{\"t\":3,\"n\":\"ANAM - Far away model\"},{\"t\":3,\"n\":\"ATKR - Attack Race\"},{\"t\":10,\"n\":\"Attacks\",\"c\":[{\"t\":6,\"n\":\"Attack\",\"c\":[{\"t\":6,\"n\":\"ATKD - Attack Data\",\"c\":[{\"t\":5,\"n\":\"Damage Mult\"},{\"t\":5,\"n\":\"Attack Chance\"},{\"t\":3,\"n\":\"Attack Spell\"},{\"t\":3,\"n\":\"Attack Flags\"},{\"t\":5,\"n\":\"Attack Angle\"},{\"t\":5,\"n\":\"Strike Angle\"},{\"t\":5,\"n\":\"Stagger\"},{\"t\":3,\"n\":\"Attack Type\"},{\"t\":5,\"n\":\"Knockdown\"},{\"t\":5,\"n\":\"Recovery Time\"},{\"t\":5,\"n\":\"Stamina Mult\"}]}]}]},{\"t\":3,\"n\":\"SPOR - Spectator override package list\"},{\"t\":3,\"n\":\"OCOR - Observe dead body override package list\"},{\"t\":3,\"n\":\"GWOR - Guard warn override package list\"},{\"t\":3,\"n\":\"ECOR - Combat override package list\"},{\"t\":3,\"n\":\"PRKZ - Perk Count\"},{\"t\":10,\"n\":\"Perks\",\"c\":[{\"t\":6,\"n\":\"PRKR - Perk\",\"c\":[{\"t\":3,\"n\":\"Perk\"},{\"t\":3,\"n\":\"Rank\"},{\"t\":11,\"n\":\"Unused\"}]}]},{\"t\":3,\"n\":\"COCT - Count\"},{\"t\":10,\"n\":\"Items\",\"c\":[{\"t\":6,\"n\":\"Item\",\"c\":[{\"t\":6,\"n\":\"CNTO - Item\",\"c\":[{\"t\":3,\"n\":\"Item\"},{\"t\":3,\"n\":\"Count\"}]}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"AIDT - AI Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Aggression\"},{\"t\":3,\"p\":1,\"n\":\"Confidence\"},{\"t\":3,\"p\":1,\"n\":\"Energy Level\"},{\"t\":3,\"p\":1,\"n\":\"Responsibility\"},{\"t\":3,\"p\":1,\"n\":\"Mood\"},{\"t\":3,\"p\":1,\"n\":\"Assistance\"},{\"t\":6,\"p\":1,\"n\":\"Aggro\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Aggro Radius Behavior\"},{\"t\":3,\"p\":1,\"n\":\"Unknown\"},{\"t\":3,\"p\":1,\"n\":\"Warn\"},{\"t\":3,\"p\":1,\"n\":\"Warn\\/Attack\"},{\"t\":3,\"p\":1,\"n\":\"Attack\"}]}]},{\"t\":7,\"n\":\"Packages\",\"c\":[{\"t\":3,\"n\":\"PKID - Package\"}]},{\"t\":3,\"n\":\"KSIZ - Keyword Count\"},{\"t\":9,\"n\":\"KWDA - Keywords\",\"c\":[{\"t\":3,\"n\":\"Keyword\"}]},{\"t\":3,\"n\":\"CNAM - Class\"},{\"t\":2,\"n\":\"FULL - Name\"},{\"t\":2,\"n\":\"SHRT - Short Name\"},{\"t\":11,\"n\":\"DATA - Marker\"},{\"t\":6,\"n\":\"DNAM - Player Skills\",\"c\":[{\"t\":7,\"n\":\"Skill Values\",\"c\":[{\"t\":3,\"n\":\"Skill #0 (OneHanded)\"},{\"t\":3,\"n\":\"Skill #1 (TwoHanded)\"},{\"t\":3,\"n\":\"Skill #2 (Marksman)\"},{\"t\":3,\"n\":\"Skill #3 (Block)\"},{\"t\":3,\"n\":\"Skill #4 (Smithing)\"},{\"t\":3,\"n\":\"Skill #5 (HeavyArmor)\"},{\"t\":3,\"n\":\"Skill #6 (LightArmor)\"},{\"t\":3,\"n\":\"Skill #7 (Pickpocket)\"},{\"t\":3,\"n\":\"Skill #8 (Lockpicking)\"},{\"t\":3,\"n\":\"Skill #9 (Sneak)\"},{\"t\":3,\"n\":\"Skill #10 (Alchemy)\"},{\"t\":3,\"n\":\"Skill #11 (Speechcraft)\"},{\"t\":3,\"n\":\"Skill #12 (Alteration)\"},{\"t\":3,\"n\":\"Skill #13 (Conjuration)\"},{\"t\":3,\"n\":\"Skill #14 (Destruction)\"},{\"t\":3,\"n\":\"Skill #15 (Illusion)\"},{\"t\":3,\"n\":\"Skill #16 (Restoration)\"},{\"t\":3,\"n\":\"Skill #17 (Enchanting)\"}]},{\"t\":7,\"n\":\"Skill Offsets\",\"c\":[{\"t\":3,\"n\":\"Skill #0 (OneHanded)\"},{\"t\":3,\"n\":\"Skill #1 (TwoHanded)\"},{\"t\":3,\"n\":\"Skill #2 (Marksman)\"},{\"t\":3,\"n\":\"Skill #3 (Block)\"},{\"t\":3,\"n\":\"Skill #4 (Smithing)\"},{\"t\":3,\"n\":\"Skill #5 (HeavyArmor)\"},{\"t\":3,\"n\":\"Skill #6 (LightArmor)\"},{\"t\":3,\"n\":\"Skill #7 (Pickpocket)\"},{\"t\":3,\"n\":\"Skill #8 (Lockpicking)\"},{\"t\":3,\"n\":\"Skill #9 (Sneak)\"},{\"t\":3,\"n\":\"Skill #10 (Alchemy)\"},{\"t\":3,\"n\":\"Skill #11 (Speechcraft)\"},{\"t\":3,\"n\":\"Skill #12 (Alteration)\"},{\"t\":3,\"n\":\"Skill #13 (Conjuration)\"},{\"t\":3,\"n\":\"Skill #14 (Destruction)\"},{\"t\":3,\"n\":\"Skill #15 (Illusion)\"},{\"t\":3,\"n\":\"Skill #16 (Restoration)\"},{\"t\":3,\"n\":\"Skill #17 (Enchanting)\"}]},{\"t\":3,\"n\":\"Health\"},{\"t\":3,\"n\":\"Magicka\"},{\"t\":3,\"n\":\"Stamina\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":5,\"n\":\"Far away model distance\"},{\"t\":3,\"n\":\"Geared up weapons\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":9,\"n\":\"Head Parts\",\"c\":[{\"t\":3,\"n\":\"PNAM - Head Part\"}]},{\"t\":3,\"n\":\"HCLF - Hair Color\"},{\"t\":3,\"n\":\"ZNAM - Combat Style\"},{\"t\":3,\"n\":\"GNAM - Gift Filter\"},{\"t\":11,\"n\":\"NAM5 - Unknown\"},{\"t\":5,\"n\":\"NAM6 - Height\"},{\"t\":5,\"n\":\"NAM7 - Weight\"},{\"t\":3,\"n\":\"NAM8 - Sound Level\"},{\"t\":10,\"n\":\"Sound Types\",\"c\":[{\"t\":6,\"n\":\"Sound Type\",\"c\":[{\"t\":3,\"n\":\"CSDT - Type\"},{\"t\":10,\"n\":\"Sounds\",\"c\":[{\"t\":6,\"n\":\"Sound\",\"c\":[{\"t\":3,\"n\":\"CSDI - Sound\"},{\"t\":3,\"n\":\"CSDC - Sound Chance\"}]}]}]}]},{\"t\":3,\"n\":\"CSCR - Inherits Sounds From\"},{\"t\":3,\"n\":\"DOFT - Default outfit\"},{\"t\":3,\"n\":\"SOFT - Sleeping outfit\"},{\"t\":3,\"n\":\"DPLT - Default Package List\"},{\"t\":3,\"n\":\"CRIF - Crime faction\"},{\"t\":3,\"n\":\"FTST - Head texture\"},{\"t\":6,\"n\":\"QNAM - Texture lighting\",\"c\":[{\"t\":5,\"n\":\"Red\"},{\"t\":5,\"n\":\"Green\"},{\"t\":5,\"n\":\"Blue\"}]},{\"t\":6,\"n\":\"NAM9 - Face morph\",\"c\":[{\"t\":5,\"n\":\"Nose Long\\/Short\"},{\"t\":5,\"n\":\"Nose Up\\/Down\"},{\"t\":5,\"n\":\"Jaw Up\\/Down\"},{\"t\":5,\"n\":\"Jaw Narrow\\/Wide\"},{\"t\":5,\"n\":\"Jaw Farward\\/Back\"},{\"t\":5,\"n\":\"Cheeks Up\\/Down\"},{\"t\":5,\"n\":\"Cheeks Farward\\/Back\"},{\"t\":5,\"n\":\"Eyes Up\\/Down\"},{\"t\":5,\"n\":\"Eyes In\\/Out\"},{\"t\":5,\"n\":\"Brows Up\\/Down\"},{\"t\":5,\"n\":\"Brows In\\/Out\"},{\"t\":5,\"n\":\"Brows Farward\\/Back\"},{\"t\":5,\"n\":\"Lips Up\\/Down\"},{\"t\":5,\"n\":\"Lips In\\/Out\"},{\"t\":5,\"n\":\"Chin Narrow\\/Wide\"},{\"t\":5,\"n\":\"Chin Up\\/Down\"},{\"t\":5,\"n\":\"Chin Underbite\\/Overbite\"},{\"t\":5,\"n\":\"Eyes Farward\\/Back\"},{\"t\":5,\"n\":\"Unknown\"}]},{\"t\":6,\"n\":\"NAMA - Face parts\",\"c\":[{\"t\":3,\"n\":\"Nose\"},{\"t\":3,\"n\":\"Unknown\"},{\"t\":3,\"n\":\"Eyes\"},{\"t\":3,\"n\":\"Mouth\"}]},{\"t\":10,\"n\":\"Tint Layers\",\"c\":[{\"t\":6,\"n\":\"Layer\",\"c\":[{\"t\":3,\"n\":\"TINI - Tint Index\"}]}]}]}]},\"name\":\"Bash.Actors.AIData\",\"hash\":\"$E4A27332\",\"color\":255}"
  },
  {
    "path": "frontend/settings/Skyrim/Bash.Actors.AIPackages.json",
    "content": "{\"records\":\"NPC_\",\"description\":\"Actors.AIPackages tag from Wrye Bash.\\r\\n\\r\\nUsed when the mod modifies NPC AI packages list.\",\"tree\":{\"records\":[{\"t\":1,\"p\":1,\"n\":\"NPC_ - Non-Player Character (Actor)\",\"c\":[{\"t\":6,\"n\":\"Record Header\",\"c\":[{\"t\":2,\"n\":\"Signature\"},{\"t\":3,\"n\":\"Data Size\"},{\"t\":3,\"n\":\"Record Flags\"},{\"t\":3,\"n\":\"FormID\"},{\"t\":11,\"n\":\"Version Control Info 1\"},{\"t\":3,\"n\":\"Form Version\"},{\"t\":11,\"n\":\"Version Control Info 2\"}]},{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"n\":\"VMAD - Virtual Machine Adapter\",\"c\":[{\"t\":3,\"n\":\"Version\"},{\"t\":3,\"n\":\"Object Format\"},{\"t\":12,\"n\":\"Data\",\"c\":[{\"t\":9,\"n\":\"Scripts\",\"c\":[{\"t\":6,\"n\":\"Script\",\"c\":[{\"t\":2,\"n\":\"scriptName\"},{\"t\":3,\"n\":\"Flags\"},{\"t\":9,\"n\":\"Properties\",\"c\":[{\"t\":6,\"n\":\"Property\",\"c\":[{\"t\":2,\"n\":\"propertyName\"},{\"t\":3,\"n\":\"Type\"},{\"t\":3,\"n\":\"Flags\"},{\"t\":12,\"n\":\"Value\"}]}]}]}]}]}]},{\"t\":6,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"n\":\"X1\"},{\"t\":3,\"n\":\"Y1\"},{\"t\":3,\"n\":\"Z1\"},{\"t\":3,\"n\":\"X2\"},{\"t\":3,\"n\":\"Y2\"},{\"t\":3,\"n\":\"Z2\"}]},{\"t\":6,\"n\":\"ACBS - Configuration\",\"c\":[{\"t\":3,\"n\":\"Flags\"},{\"t\":3,\"n\":\"Magicka Offset\"},{\"t\":3,\"n\":\"Stamina Offset\"},{\"t\":12,\"n\":\"Level\"},{\"t\":3,\"n\":\"Calc min level\"},{\"t\":3,\"n\":\"Calc max level\"},{\"t\":3,\"n\":\"Speed Multiplier\"},{\"t\":3,\"n\":\"Disposition Base (unused)\"},{\"t\":3,\"n\":\"Template Flags\"},{\"t\":3,\"n\":\"Health Offset\"},{\"t\":3,\"n\":\"Bleedout Override\"}]},{\"t\":10,\"n\":\"Factions\",\"c\":[{\"t\":6,\"n\":\"SNAM - Faction\",\"c\":[{\"t\":3,\"n\":\"Faction\"},{\"t\":3,\"n\":\"Rank\"},{\"t\":11,\"n\":\"Unused\"}]}]},{\"t\":3,\"n\":\"INAM - Death item\"},{\"t\":3,\"n\":\"VTCK - Voice\"},{\"t\":3,\"n\":\"TPLT - Template\"},{\"t\":3,\"n\":\"RNAM - Race\"},{\"t\":3,\"n\":\"SPCT - Count\"},{\"t\":9,\"n\":\"Actor Effects\",\"c\":[{\"t\":3,\"n\":\"SPLO - Actor Effect\"}]},{\"t\":6,\"n\":\"Destructable\",\"c\":[{\"t\":6,\"n\":\"DEST - Header\",\"c\":[{\"t\":3,\"n\":\"Health\"},{\"t\":3,\"n\":\"DEST Count\"},{\"t\":3,\"n\":\"VATS Targetable\"},{\"t\":11,\"n\":\"Unknown\"}]}]},{\"t\":3,\"n\":\"WNAM - Worn Armor\"},{\"t\":3,\"n\":\"ANAM - Far away model\"},{\"t\":3,\"n\":\"ATKR - Attack Race\"},{\"t\":10,\"n\":\"Attacks\",\"c\":[{\"t\":6,\"n\":\"Attack\",\"c\":[{\"t\":6,\"n\":\"ATKD - Attack Data\",\"c\":[{\"t\":5,\"n\":\"Damage Mult\"},{\"t\":5,\"n\":\"Attack Chance\"},{\"t\":3,\"n\":\"Attack Spell\"},{\"t\":3,\"n\":\"Attack Flags\"},{\"t\":5,\"n\":\"Attack Angle\"},{\"t\":5,\"n\":\"Strike Angle\"},{\"t\":5,\"n\":\"Stagger\"},{\"t\":3,\"n\":\"Attack Type\"},{\"t\":5,\"n\":\"Knockdown\"},{\"t\":5,\"n\":\"Recovery Time\"},{\"t\":5,\"n\":\"Stamina Mult\"}]}]}]},{\"t\":3,\"n\":\"SPOR - Spectator override package list\"},{\"t\":3,\"n\":\"OCOR - Observe dead body override package list\"},{\"t\":3,\"n\":\"GWOR - Guard warn override package list\"},{\"t\":3,\"n\":\"ECOR - Combat override package list\"},{\"t\":3,\"n\":\"PRKZ - Perk Count\"},{\"t\":10,\"n\":\"Perks\",\"c\":[{\"t\":6,\"n\":\"PRKR - Perk\",\"c\":[{\"t\":3,\"n\":\"Perk\"},{\"t\":3,\"n\":\"Rank\"},{\"t\":11,\"n\":\"Unused\"}]}]},{\"t\":3,\"n\":\"COCT - Count\"},{\"t\":10,\"n\":\"Items\",\"c\":[{\"t\":6,\"n\":\"Item\",\"c\":[{\"t\":6,\"n\":\"CNTO - Item\",\"c\":[{\"t\":3,\"n\":\"Item\"},{\"t\":3,\"n\":\"Count\"}]}]}]},{\"t\":6,\"n\":\"AIDT - AI Data\",\"c\":[{\"t\":3,\"n\":\"Aggression\"},{\"t\":3,\"n\":\"Confidence\"},{\"t\":3,\"n\":\"Energy Level\"},{\"t\":3,\"n\":\"Responsibility\"},{\"t\":3,\"n\":\"Mood\"},{\"t\":3,\"n\":\"Assistance\"},{\"t\":6,\"n\":\"Aggro\",\"c\":[{\"t\":3,\"n\":\"Aggro Radius Behavior\"},{\"t\":3,\"n\":\"Unknown\"},{\"t\":3,\"n\":\"Warn\"},{\"t\":3,\"n\":\"Warn\\/Attack\"},{\"t\":3,\"n\":\"Attack\"}]}]},{\"t\":7,\"s\":1,\"p\":1,\"n\":\"Packages\",\"d\":1,\"c\":[{\"t\":3,\"p\":1,\"n\":\"PKID - Package\"}]},{\"t\":3,\"n\":\"KSIZ - Keyword Count\"},{\"t\":9,\"n\":\"KWDA - Keywords\",\"c\":[{\"t\":3,\"n\":\"Keyword\"}]},{\"t\":3,\"n\":\"CNAM - Class\"},{\"t\":2,\"n\":\"FULL - Name\"},{\"t\":2,\"n\":\"SHRT - Short Name\"},{\"t\":11,\"n\":\"DATA - Marker\"},{\"t\":6,\"n\":\"DNAM - Player Skills\",\"c\":[{\"t\":7,\"n\":\"Skill Values\",\"c\":[{\"t\":3,\"n\":\"Skill #0 (OneHanded)\"},{\"t\":3,\"n\":\"Skill #1 (TwoHanded)\"},{\"t\":3,\"n\":\"Skill #2 (Marksman)\"},{\"t\":3,\"n\":\"Skill #3 (Block)\"},{\"t\":3,\"n\":\"Skill #4 (Smithing)\"},{\"t\":3,\"n\":\"Skill #5 (HeavyArmor)\"},{\"t\":3,\"n\":\"Skill #6 (LightArmor)\"},{\"t\":3,\"n\":\"Skill #7 (Pickpocket)\"},{\"t\":3,\"n\":\"Skill #8 (Lockpicking)\"},{\"t\":3,\"n\":\"Skill #9 (Sneak)\"},{\"t\":3,\"n\":\"Skill #10 (Alchemy)\"},{\"t\":3,\"n\":\"Skill #11 (Speechcraft)\"},{\"t\":3,\"n\":\"Skill #12 (Alteration)\"},{\"t\":3,\"n\":\"Skill #13 (Conjuration)\"},{\"t\":3,\"n\":\"Skill #14 (Destruction)\"},{\"t\":3,\"n\":\"Skill #15 (Illusion)\"},{\"t\":3,\"n\":\"Skill #16 (Restoration)\"},{\"t\":3,\"n\":\"Skill #17 (Enchanting)\"}]},{\"t\":7,\"n\":\"Skill Offsets\",\"c\":[{\"t\":3,\"n\":\"Skill #0 (OneHanded)\"},{\"t\":3,\"n\":\"Skill #1 (TwoHanded)\"},{\"t\":3,\"n\":\"Skill #2 (Marksman)\"},{\"t\":3,\"n\":\"Skill #3 (Block)\"},{\"t\":3,\"n\":\"Skill #4 (Smithing)\"},{\"t\":3,\"n\":\"Skill #5 (HeavyArmor)\"},{\"t\":3,\"n\":\"Skill #6 (LightArmor)\"},{\"t\":3,\"n\":\"Skill #7 (Pickpocket)\"},{\"t\":3,\"n\":\"Skill #8 (Lockpicking)\"},{\"t\":3,\"n\":\"Skill #9 (Sneak)\"},{\"t\":3,\"n\":\"Skill #10 (Alchemy)\"},{\"t\":3,\"n\":\"Skill #11 (Speechcraft)\"},{\"t\":3,\"n\":\"Skill #12 (Alteration)\"},{\"t\":3,\"n\":\"Skill #13 (Conjuration)\"},{\"t\":3,\"n\":\"Skill #14 (Destruction)\"},{\"t\":3,\"n\":\"Skill #15 (Illusion)\"},{\"t\":3,\"n\":\"Skill #16 (Restoration)\"},{\"t\":3,\"n\":\"Skill #17 (Enchanting)\"}]},{\"t\":3,\"n\":\"Health\"},{\"t\":3,\"n\":\"Magicka\"},{\"t\":3,\"n\":\"Stamina\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":5,\"n\":\"Far away model distance\"},{\"t\":3,\"n\":\"Geared up weapons\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":9,\"n\":\"Head Parts\",\"c\":[{\"t\":3,\"n\":\"PNAM - Head Part\"}]},{\"t\":3,\"n\":\"HCLF - Hair Color\"},{\"t\":3,\"n\":\"ZNAM - Combat Style\"},{\"t\":3,\"n\":\"GNAM - Gift Filter\"},{\"t\":11,\"n\":\"NAM5 - Unknown\"},{\"t\":5,\"n\":\"NAM6 - Height\"},{\"t\":5,\"n\":\"NAM7 - Weight\"},{\"t\":3,\"n\":\"NAM8 - Sound Level\"},{\"t\":10,\"n\":\"Sound Types\",\"c\":[{\"t\":6,\"n\":\"Sound Type\",\"c\":[{\"t\":3,\"n\":\"CSDT - Type\"},{\"t\":10,\"n\":\"Sounds\",\"c\":[{\"t\":6,\"n\":\"Sound\",\"c\":[{\"t\":3,\"n\":\"CSDI - Sound\"},{\"t\":3,\"n\":\"CSDC - Sound Chance\"}]}]}]}]},{\"t\":3,\"n\":\"CSCR - Inherits Sounds From\"},{\"t\":3,\"n\":\"DOFT - Default outfit\"},{\"t\":3,\"n\":\"SOFT - Sleeping outfit\"},{\"t\":3,\"n\":\"DPLT - Default Package List\"},{\"t\":3,\"n\":\"CRIF - Crime faction\"},{\"t\":3,\"n\":\"FTST - Head texture\"},{\"t\":6,\"n\":\"QNAM - Texture lighting\",\"c\":[{\"t\":5,\"n\":\"Red\"},{\"t\":5,\"n\":\"Green\"},{\"t\":5,\"n\":\"Blue\"}]},{\"t\":6,\"n\":\"NAM9 - Face morph\",\"c\":[{\"t\":5,\"n\":\"Nose Long\\/Short\"},{\"t\":5,\"n\":\"Nose Up\\/Down\"},{\"t\":5,\"n\":\"Jaw Up\\/Down\"},{\"t\":5,\"n\":\"Jaw Narrow\\/Wide\"},{\"t\":5,\"n\":\"Jaw Farward\\/Back\"},{\"t\":5,\"n\":\"Cheeks Up\\/Down\"},{\"t\":5,\"n\":\"Cheeks Farward\\/Back\"},{\"t\":5,\"n\":\"Eyes Up\\/Down\"},{\"t\":5,\"n\":\"Eyes In\\/Out\"},{\"t\":5,\"n\":\"Brows Up\\/Down\"},{\"t\":5,\"n\":\"Brows In\\/Out\"},{\"t\":5,\"n\":\"Brows Farward\\/Back\"},{\"t\":5,\"n\":\"Lips Up\\/Down\"},{\"t\":5,\"n\":\"Lips In\\/Out\"},{\"t\":5,\"n\":\"Chin Narrow\\/Wide\"},{\"t\":5,\"n\":\"Chin Up\\/Down\"},{\"t\":5,\"n\":\"Chin Underbite\\/Overbite\"},{\"t\":5,\"n\":\"Eyes Farward\\/Back\"},{\"t\":5,\"n\":\"Unknown\"}]},{\"t\":6,\"n\":\"NAMA - Face parts\",\"c\":[{\"t\":3,\"n\":\"Nose\"},{\"t\":3,\"n\":\"Unknown\"},{\"t\":3,\"n\":\"Eyes\"},{\"t\":3,\"n\":\"Mouth\"}]},{\"t\":10,\"n\":\"Tint Layers\",\"c\":[{\"t\":6,\"n\":\"Layer\",\"c\":[{\"t\":3,\"n\":\"TINI - Tint Index\"}]}]}]}]},\"name\":\"Bash.Actors.AIPackages\",\"hash\":\"$4707BEC7\",\"color\":255}"
  },
  {
    "path": "frontend/settings/Skyrim/Bash.Actors.AIPackagesMerge.json",
    "content": "{\"records\":\"NPC_\",\"description\":\"An alternative to the Actors.AIPackagesForceAdd tag from Wrye Bash.\\r\\n\\r\\nMator Smash cannot currently perform the logic for a forced addition as Wrye Bash does with the Actors.AIPackagesForceAdd tag.  This tag does the next best thing, which causes packages to be merged.\",\"tree\":{\"records\":[{\"t\":1,\"p\":1,\"n\":\"NPC_ - Non-Player Character (Actor)\",\"c\":[{\"t\":6,\"n\":\"Record Header\",\"c\":[{\"t\":2,\"n\":\"Signature\"},{\"t\":3,\"n\":\"Data Size\"},{\"t\":3,\"n\":\"Record Flags\"},{\"t\":3,\"n\":\"FormID\"},{\"t\":11,\"n\":\"Version Control Info 1\"},{\"t\":3,\"n\":\"Form Version\"},{\"t\":11,\"n\":\"Version Control Info 2\"}]},{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"n\":\"VMAD - Virtual Machine Adapter\",\"c\":[{\"t\":3,\"n\":\"Version\"},{\"t\":3,\"n\":\"Object Format\"},{\"t\":12,\"n\":\"Data\",\"c\":[{\"t\":9,\"n\":\"Scripts\",\"c\":[{\"t\":6,\"n\":\"Script\",\"c\":[{\"t\":2,\"n\":\"scriptName\"},{\"t\":3,\"n\":\"Flags\"},{\"t\":9,\"n\":\"Properties\",\"c\":[{\"t\":6,\"n\":\"Property\",\"c\":[{\"t\":2,\"n\":\"propertyName\"},{\"t\":3,\"n\":\"Type\"},{\"t\":3,\"n\":\"Flags\"},{\"t\":12,\"n\":\"Value\"}]}]}]}]}]}]},{\"t\":6,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"n\":\"X1\"},{\"t\":3,\"n\":\"Y1\"},{\"t\":3,\"n\":\"Z1\"},{\"t\":3,\"n\":\"X2\"},{\"t\":3,\"n\":\"Y2\"},{\"t\":3,\"n\":\"Z2\"}]},{\"t\":6,\"n\":\"ACBS - Configuration\",\"c\":[{\"t\":3,\"n\":\"Flags\"},{\"t\":3,\"n\":\"Magicka Offset\"},{\"t\":3,\"n\":\"Stamina Offset\"},{\"t\":12,\"n\":\"Level\"},{\"t\":3,\"n\":\"Calc min level\"},{\"t\":3,\"n\":\"Calc max level\"},{\"t\":3,\"n\":\"Speed Multiplier\"},{\"t\":3,\"n\":\"Disposition Base (unused)\"},{\"t\":3,\"n\":\"Template Flags\"},{\"t\":3,\"n\":\"Health Offset\"},{\"t\":3,\"n\":\"Bleedout Override\"}]},{\"t\":10,\"n\":\"Factions\",\"c\":[{\"t\":6,\"n\":\"SNAM - Faction\",\"c\":[{\"t\":3,\"n\":\"Faction\"},{\"t\":3,\"n\":\"Rank\"},{\"t\":11,\"n\":\"Unused\"}]}]},{\"t\":3,\"n\":\"INAM - Death item\"},{\"t\":3,\"n\":\"VTCK - Voice\"},{\"t\":3,\"n\":\"TPLT - Template\"},{\"t\":3,\"n\":\"RNAM - Race\"},{\"t\":3,\"n\":\"SPCT - Count\"},{\"t\":9,\"n\":\"Actor Effects\",\"c\":[{\"t\":3,\"n\":\"SPLO - Actor Effect\"}]},{\"t\":6,\"n\":\"Destructable\",\"c\":[{\"t\":6,\"n\":\"DEST - Header\",\"c\":[{\"t\":3,\"n\":\"Health\"},{\"t\":3,\"n\":\"DEST Count\"},{\"t\":3,\"n\":\"VATS Targetable\"},{\"t\":11,\"n\":\"Unknown\"}]}]},{\"t\":3,\"n\":\"WNAM - Worn Armor\"},{\"t\":3,\"n\":\"ANAM - Far away model\"},{\"t\":3,\"n\":\"ATKR - Attack Race\"},{\"t\":10,\"n\":\"Attacks\",\"c\":[{\"t\":6,\"n\":\"Attack\",\"c\":[{\"t\":6,\"n\":\"ATKD - Attack Data\",\"c\":[{\"t\":5,\"n\":\"Damage Mult\"},{\"t\":5,\"n\":\"Attack Chance\"},{\"t\":3,\"n\":\"Attack Spell\"},{\"t\":3,\"n\":\"Attack Flags\"},{\"t\":5,\"n\":\"Attack Angle\"},{\"t\":5,\"n\":\"Strike Angle\"},{\"t\":5,\"n\":\"Stagger\"},{\"t\":3,\"n\":\"Attack Type\"},{\"t\":5,\"n\":\"Knockdown\"},{\"t\":5,\"n\":\"Recovery Time\"},{\"t\":5,\"n\":\"Stamina Mult\"}]}]}]},{\"t\":3,\"n\":\"SPOR - Spectator override package list\"},{\"t\":3,\"n\":\"OCOR - Observe dead body override package list\"},{\"t\":3,\"n\":\"GWOR - Guard warn override package list\"},{\"t\":3,\"n\":\"ECOR - Combat override package list\"},{\"t\":3,\"n\":\"PRKZ - Perk Count\"},{\"t\":10,\"n\":\"Perks\",\"c\":[{\"t\":6,\"n\":\"PRKR - Perk\",\"c\":[{\"t\":3,\"n\":\"Perk\"},{\"t\":3,\"n\":\"Rank\"},{\"t\":11,\"n\":\"Unused\"}]}]},{\"t\":3,\"n\":\"COCT - Count\"},{\"t\":10,\"n\":\"Items\",\"c\":[{\"t\":6,\"n\":\"Item\",\"c\":[{\"t\":6,\"n\":\"CNTO - Item\",\"c\":[{\"t\":3,\"n\":\"Item\"},{\"t\":3,\"n\":\"Count\"}]}]}]},{\"t\":6,\"n\":\"AIDT - AI Data\",\"c\":[{\"t\":3,\"n\":\"Aggression\"},{\"t\":3,\"n\":\"Confidence\"},{\"t\":3,\"n\":\"Energy Level\"},{\"t\":3,\"n\":\"Responsibility\"},{\"t\":3,\"n\":\"Mood\"},{\"t\":3,\"n\":\"Assistance\"},{\"t\":6,\"n\":\"Aggro\",\"c\":[{\"t\":3,\"n\":\"Aggro Radius Behavior\"},{\"t\":3,\"n\":\"Unknown\"},{\"t\":3,\"n\":\"Warn\"},{\"t\":3,\"n\":\"Warn\\/Attack\"},{\"t\":3,\"n\":\"Attack\"}]}]},{\"t\":7,\"p\":1,\"n\":\"Packages\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"PKID - Package\"}]},{\"t\":3,\"n\":\"KSIZ - Keyword Count\"},{\"t\":9,\"n\":\"KWDA - Keywords\",\"c\":[{\"t\":3,\"n\":\"Keyword\"}]},{\"t\":3,\"n\":\"CNAM - Class\"},{\"t\":2,\"n\":\"FULL - Name\"},{\"t\":2,\"n\":\"SHRT - Short Name\"},{\"t\":11,\"n\":\"DATA - Marker\"},{\"t\":6,\"n\":\"DNAM - Player Skills\",\"c\":[{\"t\":7,\"n\":\"Skill Values\",\"c\":[{\"t\":3,\"n\":\"Skill #0 (OneHanded)\"},{\"t\":3,\"n\":\"Skill #1 (TwoHanded)\"},{\"t\":3,\"n\":\"Skill #2 (Marksman)\"},{\"t\":3,\"n\":\"Skill #3 (Block)\"},{\"t\":3,\"n\":\"Skill #4 (Smithing)\"},{\"t\":3,\"n\":\"Skill #5 (HeavyArmor)\"},{\"t\":3,\"n\":\"Skill #6 (LightArmor)\"},{\"t\":3,\"n\":\"Skill #7 (Pickpocket)\"},{\"t\":3,\"n\":\"Skill #8 (Lockpicking)\"},{\"t\":3,\"n\":\"Skill #9 (Sneak)\"},{\"t\":3,\"n\":\"Skill #10 (Alchemy)\"},{\"t\":3,\"n\":\"Skill #11 (Speechcraft)\"},{\"t\":3,\"n\":\"Skill #12 (Alteration)\"},{\"t\":3,\"n\":\"Skill #13 (Conjuration)\"},{\"t\":3,\"n\":\"Skill #14 (Destruction)\"},{\"t\":3,\"n\":\"Skill #15 (Illusion)\"},{\"t\":3,\"n\":\"Skill #16 (Restoration)\"},{\"t\":3,\"n\":\"Skill #17 (Enchanting)\"}]},{\"t\":7,\"n\":\"Skill Offsets\",\"c\":[{\"t\":3,\"n\":\"Skill #0 (OneHanded)\"},{\"t\":3,\"n\":\"Skill #1 (TwoHanded)\"},{\"t\":3,\"n\":\"Skill #2 (Marksman)\"},{\"t\":3,\"n\":\"Skill #3 (Block)\"},{\"t\":3,\"n\":\"Skill #4 (Smithing)\"},{\"t\":3,\"n\":\"Skill #5 (HeavyArmor)\"},{\"t\":3,\"n\":\"Skill #6 (LightArmor)\"},{\"t\":3,\"n\":\"Skill #7 (Pickpocket)\"},{\"t\":3,\"n\":\"Skill #8 (Lockpicking)\"},{\"t\":3,\"n\":\"Skill #9 (Sneak)\"},{\"t\":3,\"n\":\"Skill #10 (Alchemy)\"},{\"t\":3,\"n\":\"Skill #11 (Speechcraft)\"},{\"t\":3,\"n\":\"Skill #12 (Alteration)\"},{\"t\":3,\"n\":\"Skill #13 (Conjuration)\"},{\"t\":3,\"n\":\"Skill #14 (Destruction)\"},{\"t\":3,\"n\":\"Skill #15 (Illusion)\"},{\"t\":3,\"n\":\"Skill #16 (Restoration)\"},{\"t\":3,\"n\":\"Skill #17 (Enchanting)\"}]},{\"t\":3,\"n\":\"Health\"},{\"t\":3,\"n\":\"Magicka\"},{\"t\":3,\"n\":\"Stamina\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":5,\"n\":\"Far away model distance\"},{\"t\":3,\"n\":\"Geared up weapons\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":9,\"n\":\"Head Parts\",\"c\":[{\"t\":3,\"n\":\"PNAM - Head Part\"}]},{\"t\":3,\"n\":\"HCLF - Hair Color\"},{\"t\":3,\"n\":\"ZNAM - Combat Style\"},{\"t\":3,\"n\":\"GNAM - Gift Filter\"},{\"t\":11,\"n\":\"NAM5 - Unknown\"},{\"t\":5,\"n\":\"NAM6 - Height\"},{\"t\":5,\"n\":\"NAM7 - Weight\"},{\"t\":3,\"n\":\"NAM8 - Sound Level\"},{\"t\":10,\"n\":\"Sound Types\",\"c\":[{\"t\":6,\"n\":\"Sound Type\",\"c\":[{\"t\":3,\"n\":\"CSDT - Type\"},{\"t\":10,\"n\":\"Sounds\",\"c\":[{\"t\":6,\"n\":\"Sound\",\"c\":[{\"t\":3,\"n\":\"CSDI - Sound\"},{\"t\":3,\"n\":\"CSDC - Sound Chance\"}]}]}]}]},{\"t\":3,\"n\":\"CSCR - Inherits Sounds From\"},{\"t\":3,\"n\":\"DOFT - Default outfit\"},{\"t\":3,\"n\":\"SOFT - Sleeping outfit\"},{\"t\":3,\"n\":\"DPLT - Default Package List\"},{\"t\":3,\"n\":\"CRIF - Crime faction\"},{\"t\":3,\"n\":\"FTST - Head texture\"},{\"t\":6,\"n\":\"QNAM - Texture lighting\",\"c\":[{\"t\":5,\"n\":\"Red\"},{\"t\":5,\"n\":\"Green\"},{\"t\":5,\"n\":\"Blue\"}]},{\"t\":6,\"n\":\"NAM9 - Face morph\",\"c\":[{\"t\":5,\"n\":\"Nose Long\\/Short\"},{\"t\":5,\"n\":\"Nose Up\\/Down\"},{\"t\":5,\"n\":\"Jaw Up\\/Down\"},{\"t\":5,\"n\":\"Jaw Narrow\\/Wide\"},{\"t\":5,\"n\":\"Jaw Farward\\/Back\"},{\"t\":5,\"n\":\"Cheeks Up\\/Down\"},{\"t\":5,\"n\":\"Cheeks Farward\\/Back\"},{\"t\":5,\"n\":\"Eyes Up\\/Down\"},{\"t\":5,\"n\":\"Eyes In\\/Out\"},{\"t\":5,\"n\":\"Brows Up\\/Down\"},{\"t\":5,\"n\":\"Brows In\\/Out\"},{\"t\":5,\"n\":\"Brows Farward\\/Back\"},{\"t\":5,\"n\":\"Lips Up\\/Down\"},{\"t\":5,\"n\":\"Lips In\\/Out\"},{\"t\":5,\"n\":\"Chin Narrow\\/Wide\"},{\"t\":5,\"n\":\"Chin Up\\/Down\"},{\"t\":5,\"n\":\"Chin Underbite\\/Overbite\"},{\"t\":5,\"n\":\"Eyes Farward\\/Back\"},{\"t\":5,\"n\":\"Unknown\"}]},{\"t\":6,\"n\":\"NAMA - Face parts\",\"c\":[{\"t\":3,\"n\":\"Nose\"},{\"t\":3,\"n\":\"Unknown\"},{\"t\":3,\"n\":\"Eyes\"},{\"t\":3,\"n\":\"Mouth\"}]},{\"t\":10,\"n\":\"Tint Layers\",\"c\":[{\"t\":6,\"n\":\"Layer\",\"c\":[{\"t\":3,\"n\":\"TINI - Tint Index\"}]}]}]}]},\"name\":\"Bash.Actors.AIPackagesMerge\",\"hash\":\"$11434ADE\",\"color\":255}"
  },
  {
    "path": "frontend/settings/Skyrim/Bash.Actors.CombatStyle.json",
    "content": "{\"records\":\"NPC_\",\"description\":\"Actors.CombatStyle tag from Wrye Bash.\\r\\n\\r\\nUsed when the mod modifies NPC combat styles.\",\"tree\":{\"records\":[{\"t\":1,\"p\":1,\"n\":\"NPC_ - Non-Player Character (Actor)\",\"c\":[{\"t\":6,\"n\":\"Record Header\",\"c\":[{\"t\":2,\"n\":\"Signature\"},{\"t\":3,\"n\":\"Data Size\"},{\"t\":3,\"n\":\"Record Flags\"},{\"t\":3,\"n\":\"FormID\"},{\"t\":11,\"n\":\"Version Control Info 1\"},{\"t\":3,\"n\":\"Form Version\"},{\"t\":11,\"n\":\"Version Control Info 2\"}]},{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"n\":\"VMAD - Virtual Machine Adapter\",\"c\":[{\"t\":3,\"n\":\"Version\"},{\"t\":3,\"n\":\"Object Format\"},{\"t\":12,\"n\":\"Data\",\"c\":[{\"t\":9,\"n\":\"Scripts\",\"c\":[{\"t\":6,\"n\":\"Script\",\"c\":[{\"t\":2,\"n\":\"scriptName\"},{\"t\":3,\"n\":\"Flags\"},{\"t\":9,\"n\":\"Properties\",\"c\":[{\"t\":6,\"n\":\"Property\",\"c\":[{\"t\":2,\"n\":\"propertyName\"},{\"t\":3,\"n\":\"Type\"},{\"t\":3,\"n\":\"Flags\"},{\"t\":12,\"n\":\"Value\"}]}]}]}]}]}]},{\"t\":6,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"n\":\"X1\"},{\"t\":3,\"n\":\"Y1\"},{\"t\":3,\"n\":\"Z1\"},{\"t\":3,\"n\":\"X2\"},{\"t\":3,\"n\":\"Y2\"},{\"t\":3,\"n\":\"Z2\"}]},{\"t\":6,\"n\":\"ACBS - Configuration\",\"c\":[{\"t\":3,\"n\":\"Flags\"},{\"t\":3,\"n\":\"Magicka Offset\"},{\"t\":3,\"n\":\"Stamina Offset\"},{\"t\":12,\"n\":\"Level\"},{\"t\":3,\"n\":\"Calc min level\"},{\"t\":3,\"n\":\"Calc max level\"},{\"t\":3,\"n\":\"Speed Multiplier\"},{\"t\":3,\"n\":\"Disposition Base (unused)\"},{\"t\":3,\"n\":\"Template Flags\"},{\"t\":3,\"n\":\"Health Offset\"},{\"t\":3,\"n\":\"Bleedout Override\"}]},{\"t\":10,\"n\":\"Factions\",\"c\":[{\"t\":6,\"n\":\"SNAM - Faction\",\"c\":[{\"t\":3,\"n\":\"Faction\"},{\"t\":3,\"n\":\"Rank\"},{\"t\":11,\"n\":\"Unused\"}]}]},{\"t\":3,\"n\":\"INAM - Death item\"},{\"t\":3,\"n\":\"VTCK - Voice\"},{\"t\":3,\"n\":\"TPLT - Template\"},{\"t\":3,\"n\":\"RNAM - Race\"},{\"t\":3,\"n\":\"SPCT - Count\"},{\"t\":9,\"n\":\"Actor Effects\",\"c\":[{\"t\":3,\"n\":\"SPLO - Actor Effect\"}]},{\"t\":6,\"n\":\"Destructable\",\"c\":[{\"t\":6,\"n\":\"DEST - Header\",\"c\":[{\"t\":3,\"n\":\"Health\"},{\"t\":3,\"n\":\"DEST Count\"},{\"t\":3,\"n\":\"VATS Targetable\"},{\"t\":11,\"n\":\"Unknown\"}]}]},{\"t\":3,\"n\":\"WNAM - Worn Armor\"},{\"t\":3,\"n\":\"ANAM - Far away model\"},{\"t\":3,\"n\":\"ATKR - Attack Race\"},{\"t\":10,\"n\":\"Attacks\",\"c\":[{\"t\":6,\"n\":\"Attack\",\"c\":[{\"t\":6,\"n\":\"ATKD - Attack Data\",\"c\":[{\"t\":5,\"n\":\"Damage Mult\"},{\"t\":5,\"n\":\"Attack Chance\"},{\"t\":3,\"n\":\"Attack Spell\"},{\"t\":3,\"n\":\"Attack Flags\"},{\"t\":5,\"n\":\"Attack Angle\"},{\"t\":5,\"n\":\"Strike Angle\"},{\"t\":5,\"n\":\"Stagger\"},{\"t\":3,\"n\":\"Attack Type\"},{\"t\":5,\"n\":\"Knockdown\"},{\"t\":5,\"n\":\"Recovery Time\"},{\"t\":5,\"n\":\"Stamina Mult\"}]}]}]},{\"t\":3,\"n\":\"SPOR - Spectator override package list\"},{\"t\":3,\"n\":\"OCOR - Observe dead body override package list\"},{\"t\":3,\"n\":\"GWOR - Guard warn override package list\"},{\"t\":3,\"n\":\"ECOR - Combat override package list\"},{\"t\":3,\"n\":\"PRKZ - Perk Count\"},{\"t\":10,\"n\":\"Perks\",\"c\":[{\"t\":6,\"n\":\"PRKR - Perk\",\"c\":[{\"t\":3,\"n\":\"Perk\"},{\"t\":3,\"n\":\"Rank\"},{\"t\":11,\"n\":\"Unused\"}]}]},{\"t\":3,\"n\":\"COCT - Count\"},{\"t\":10,\"n\":\"Items\",\"c\":[{\"t\":6,\"n\":\"Item\",\"c\":[{\"t\":6,\"n\":\"CNTO - Item\",\"c\":[{\"t\":3,\"n\":\"Item\"},{\"t\":3,\"n\":\"Count\"}]}]}]},{\"t\":6,\"n\":\"AIDT - AI Data\",\"c\":[{\"t\":3,\"n\":\"Aggression\"},{\"t\":3,\"n\":\"Confidence\"},{\"t\":3,\"n\":\"Energy Level\"},{\"t\":3,\"n\":\"Responsibility\"},{\"t\":3,\"n\":\"Mood\"},{\"t\":3,\"n\":\"Assistance\"},{\"t\":6,\"n\":\"Aggro\",\"c\":[{\"t\":3,\"n\":\"Aggro Radius Behavior\"},{\"t\":3,\"n\":\"Unknown\"},{\"t\":3,\"n\":\"Warn\"},{\"t\":3,\"n\":\"Warn\\/Attack\"},{\"t\":3,\"n\":\"Attack\"}]}]},{\"t\":7,\"n\":\"Packages\",\"c\":[{\"t\":3,\"n\":\"PKID - Package\"}]},{\"t\":3,\"n\":\"KSIZ - Keyword Count\"},{\"t\":9,\"n\":\"KWDA - Keywords\",\"c\":[{\"t\":3,\"n\":\"Keyword\"}]},{\"t\":3,\"n\":\"CNAM - Class\"},{\"t\":2,\"n\":\"FULL - Name\"},{\"t\":2,\"n\":\"SHRT - Short Name\"},{\"t\":11,\"n\":\"DATA - Marker\"},{\"t\":6,\"n\":\"DNAM - Player Skills\",\"c\":[{\"t\":7,\"n\":\"Skill Values\",\"c\":[{\"t\":3,\"n\":\"Skill #0 (OneHanded)\"},{\"t\":3,\"n\":\"Skill #1 (TwoHanded)\"},{\"t\":3,\"n\":\"Skill #2 (Marksman)\"},{\"t\":3,\"n\":\"Skill #3 (Block)\"},{\"t\":3,\"n\":\"Skill #4 (Smithing)\"},{\"t\":3,\"n\":\"Skill #5 (HeavyArmor)\"},{\"t\":3,\"n\":\"Skill #6 (LightArmor)\"},{\"t\":3,\"n\":\"Skill #7 (Pickpocket)\"},{\"t\":3,\"n\":\"Skill #8 (Lockpicking)\"},{\"t\":3,\"n\":\"Skill #9 (Sneak)\"},{\"t\":3,\"n\":\"Skill #10 (Alchemy)\"},{\"t\":3,\"n\":\"Skill #11 (Speechcraft)\"},{\"t\":3,\"n\":\"Skill #12 (Alteration)\"},{\"t\":3,\"n\":\"Skill #13 (Conjuration)\"},{\"t\":3,\"n\":\"Skill #14 (Destruction)\"},{\"t\":3,\"n\":\"Skill #15 (Illusion)\"},{\"t\":3,\"n\":\"Skill #16 (Restoration)\"},{\"t\":3,\"n\":\"Skill #17 (Enchanting)\"}]},{\"t\":7,\"n\":\"Skill Offsets\",\"c\":[{\"t\":3,\"n\":\"Skill #0 (OneHanded)\"},{\"t\":3,\"n\":\"Skill #1 (TwoHanded)\"},{\"t\":3,\"n\":\"Skill #2 (Marksman)\"},{\"t\":3,\"n\":\"Skill #3 (Block)\"},{\"t\":3,\"n\":\"Skill #4 (Smithing)\"},{\"t\":3,\"n\":\"Skill #5 (HeavyArmor)\"},{\"t\":3,\"n\":\"Skill #6 (LightArmor)\"},{\"t\":3,\"n\":\"Skill #7 (Pickpocket)\"},{\"t\":3,\"n\":\"Skill #8 (Lockpicking)\"},{\"t\":3,\"n\":\"Skill #9 (Sneak)\"},{\"t\":3,\"n\":\"Skill #10 (Alchemy)\"},{\"t\":3,\"n\":\"Skill #11 (Speechcraft)\"},{\"t\":3,\"n\":\"Skill #12 (Alteration)\"},{\"t\":3,\"n\":\"Skill #13 (Conjuration)\"},{\"t\":3,\"n\":\"Skill #14 (Destruction)\"},{\"t\":3,\"n\":\"Skill #15 (Illusion)\"},{\"t\":3,\"n\":\"Skill #16 (Restoration)\"},{\"t\":3,\"n\":\"Skill #17 (Enchanting)\"}]},{\"t\":3,\"n\":\"Health\"},{\"t\":3,\"n\":\"Magicka\"},{\"t\":3,\"n\":\"Stamina\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":5,\"n\":\"Far away model distance\"},{\"t\":3,\"n\":\"Geared up weapons\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":9,\"n\":\"Head Parts\",\"c\":[{\"t\":3,\"n\":\"PNAM - Head Part\"}]},{\"t\":3,\"n\":\"HCLF - Hair Color\"},{\"t\":3,\"p\":1,\"n\":\"ZNAM - Combat Style\"},{\"t\":3,\"n\":\"GNAM - Gift Filter\"},{\"t\":11,\"n\":\"NAM5 - Unknown\"},{\"t\":5,\"n\":\"NAM6 - Height\"},{\"t\":5,\"n\":\"NAM7 - Weight\"},{\"t\":3,\"n\":\"NAM8 - Sound Level\"},{\"t\":10,\"n\":\"Sound Types\",\"c\":[{\"t\":6,\"n\":\"Sound Type\",\"c\":[{\"t\":3,\"n\":\"CSDT - Type\"},{\"t\":10,\"n\":\"Sounds\",\"c\":[{\"t\":6,\"n\":\"Sound\",\"c\":[{\"t\":3,\"n\":\"CSDI - Sound\"},{\"t\":3,\"n\":\"CSDC - Sound Chance\"}]}]}]}]},{\"t\":3,\"n\":\"CSCR - Inherits Sounds From\"},{\"t\":3,\"n\":\"DOFT - Default outfit\"},{\"t\":3,\"n\":\"SOFT - Sleeping outfit\"},{\"t\":3,\"n\":\"DPLT - Default Package List\"},{\"t\":3,\"n\":\"CRIF - Crime faction\"},{\"t\":3,\"n\":\"FTST - Head texture\"},{\"t\":6,\"n\":\"QNAM - Texture lighting\",\"c\":[{\"t\":5,\"n\":\"Red\"},{\"t\":5,\"n\":\"Green\"},{\"t\":5,\"n\":\"Blue\"}]},{\"t\":6,\"n\":\"NAM9 - Face morph\",\"c\":[{\"t\":5,\"n\":\"Nose Long\\/Short\"},{\"t\":5,\"n\":\"Nose Up\\/Down\"},{\"t\":5,\"n\":\"Jaw Up\\/Down\"},{\"t\":5,\"n\":\"Jaw Narrow\\/Wide\"},{\"t\":5,\"n\":\"Jaw Farward\\/Back\"},{\"t\":5,\"n\":\"Cheeks Up\\/Down\"},{\"t\":5,\"n\":\"Cheeks Farward\\/Back\"},{\"t\":5,\"n\":\"Eyes Up\\/Down\"},{\"t\":5,\"n\":\"Eyes In\\/Out\"},{\"t\":5,\"n\":\"Brows Up\\/Down\"},{\"t\":5,\"n\":\"Brows In\\/Out\"},{\"t\":5,\"n\":\"Brows Farward\\/Back\"},{\"t\":5,\"n\":\"Lips Up\\/Down\"},{\"t\":5,\"n\":\"Lips In\\/Out\"},{\"t\":5,\"n\":\"Chin Narrow\\/Wide\"},{\"t\":5,\"n\":\"Chin Up\\/Down\"},{\"t\":5,\"n\":\"Chin Underbite\\/Overbite\"},{\"t\":5,\"n\":\"Eyes Farward\\/Back\"},{\"t\":5,\"n\":\"Unknown\"}]},{\"t\":6,\"n\":\"NAMA - Face parts\",\"c\":[{\"t\":3,\"n\":\"Nose\"},{\"t\":3,\"n\":\"Unknown\"},{\"t\":3,\"n\":\"Eyes\"},{\"t\":3,\"n\":\"Mouth\"}]},{\"t\":10,\"n\":\"Tint Layers\",\"c\":[{\"t\":6,\"n\":\"Layer\",\"c\":[{\"t\":3,\"n\":\"TINI - Tint Index\"}]}]}]}]},\"name\":\"Bash.Actors.CombatStyle\",\"hash\":\"$1593A13F\",\"color\":255}"
  },
  {
    "path": "frontend/settings/Skyrim/Bash.Actors.DeathItem.json",
    "content": "{\"records\":\"NPC_\",\"description\":\"Actors.DeathItem tag from Wrye Bash.\\r\\n\\r\\nUsed when the mod modifies NPC death items.\",\"tree\":{\"records\":[{\"t\":1,\"p\":1,\"n\":\"NPC_ - Non-Player Character (Actor)\",\"c\":[{\"t\":6,\"n\":\"Record Header\",\"c\":[{\"t\":2,\"n\":\"Signature\"},{\"t\":3,\"n\":\"Data Size\"},{\"t\":3,\"n\":\"Record Flags\"},{\"t\":3,\"n\":\"FormID\"},{\"t\":11,\"n\":\"Version Control Info 1\"},{\"t\":3,\"n\":\"Form Version\"},{\"t\":11,\"n\":\"Version Control Info 2\"}]},{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"n\":\"VMAD - Virtual Machine Adapter\",\"c\":[{\"t\":3,\"n\":\"Version\"},{\"t\":3,\"n\":\"Object Format\"},{\"t\":12,\"n\":\"Data\",\"c\":[{\"t\":9,\"n\":\"Scripts\",\"c\":[{\"t\":6,\"n\":\"Script\",\"c\":[{\"t\":2,\"n\":\"scriptName\"},{\"t\":3,\"n\":\"Flags\"},{\"t\":9,\"n\":\"Properties\",\"c\":[{\"t\":6,\"n\":\"Property\",\"c\":[{\"t\":2,\"n\":\"propertyName\"},{\"t\":3,\"n\":\"Type\"},{\"t\":3,\"n\":\"Flags\"},{\"t\":12,\"n\":\"Value\"}]}]}]}]}]}]},{\"t\":6,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"n\":\"X1\"},{\"t\":3,\"n\":\"Y1\"},{\"t\":3,\"n\":\"Z1\"},{\"t\":3,\"n\":\"X2\"},{\"t\":3,\"n\":\"Y2\"},{\"t\":3,\"n\":\"Z2\"}]},{\"t\":6,\"n\":\"ACBS - Configuration\",\"c\":[{\"t\":3,\"n\":\"Flags\"},{\"t\":3,\"n\":\"Magicka Offset\"},{\"t\":3,\"n\":\"Stamina Offset\"},{\"t\":12,\"n\":\"Level\"},{\"t\":3,\"n\":\"Calc min level\"},{\"t\":3,\"n\":\"Calc max level\"},{\"t\":3,\"n\":\"Speed Multiplier\"},{\"t\":3,\"n\":\"Disposition Base (unused)\"},{\"t\":3,\"n\":\"Template Flags\"},{\"t\":3,\"n\":\"Health Offset\"},{\"t\":3,\"n\":\"Bleedout Override\"}]},{\"t\":10,\"n\":\"Factions\",\"c\":[{\"t\":6,\"n\":\"SNAM - Faction\",\"c\":[{\"t\":3,\"n\":\"Faction\"},{\"t\":3,\"n\":\"Rank\"},{\"t\":11,\"n\":\"Unused\"}]}]},{\"t\":3,\"p\":1,\"n\":\"INAM - Death item\"},{\"t\":3,\"n\":\"VTCK - Voice\"},{\"t\":3,\"n\":\"TPLT - Template\"},{\"t\":3,\"n\":\"RNAM - Race\"},{\"t\":3,\"n\":\"SPCT - Count\"},{\"t\":9,\"n\":\"Actor Effects\",\"c\":[{\"t\":3,\"n\":\"SPLO - Actor Effect\"}]},{\"t\":6,\"n\":\"Destructable\",\"c\":[{\"t\":6,\"n\":\"DEST - Header\",\"c\":[{\"t\":3,\"n\":\"Health\"},{\"t\":3,\"n\":\"DEST Count\"},{\"t\":3,\"n\":\"VATS Targetable\"},{\"t\":11,\"n\":\"Unknown\"}]}]},{\"t\":3,\"n\":\"WNAM - Worn Armor\"},{\"t\":3,\"n\":\"ANAM - Far away model\"},{\"t\":3,\"n\":\"ATKR - Attack Race\"},{\"t\":10,\"n\":\"Attacks\",\"c\":[{\"t\":6,\"n\":\"Attack\",\"c\":[{\"t\":6,\"n\":\"ATKD - Attack Data\",\"c\":[{\"t\":5,\"n\":\"Damage Mult\"},{\"t\":5,\"n\":\"Attack Chance\"},{\"t\":3,\"n\":\"Attack Spell\"},{\"t\":3,\"n\":\"Attack Flags\"},{\"t\":5,\"n\":\"Attack Angle\"},{\"t\":5,\"n\":\"Strike Angle\"},{\"t\":5,\"n\":\"Stagger\"},{\"t\":3,\"n\":\"Attack Type\"},{\"t\":5,\"n\":\"Knockdown\"},{\"t\":5,\"n\":\"Recovery Time\"},{\"t\":5,\"n\":\"Stamina Mult\"}]}]}]},{\"t\":3,\"n\":\"SPOR - Spectator override package list\"},{\"t\":3,\"n\":\"OCOR - Observe dead body override package list\"},{\"t\":3,\"n\":\"GWOR - Guard warn override package list\"},{\"t\":3,\"n\":\"ECOR - Combat override package list\"},{\"t\":3,\"n\":\"PRKZ - Perk Count\"},{\"t\":10,\"n\":\"Perks\",\"c\":[{\"t\":6,\"n\":\"PRKR - Perk\",\"c\":[{\"t\":3,\"n\":\"Perk\"},{\"t\":3,\"n\":\"Rank\"},{\"t\":11,\"n\":\"Unused\"}]}]},{\"t\":3,\"n\":\"COCT - Count\"},{\"t\":10,\"n\":\"Items\",\"c\":[{\"t\":6,\"n\":\"Item\",\"c\":[{\"t\":6,\"n\":\"CNTO - Item\",\"c\":[{\"t\":3,\"n\":\"Item\"},{\"t\":3,\"n\":\"Count\"}]}]}]},{\"t\":6,\"n\":\"AIDT - AI Data\",\"c\":[{\"t\":3,\"n\":\"Aggression\"},{\"t\":3,\"n\":\"Confidence\"},{\"t\":3,\"n\":\"Energy Level\"},{\"t\":3,\"n\":\"Responsibility\"},{\"t\":3,\"n\":\"Mood\"},{\"t\":3,\"n\":\"Assistance\"},{\"t\":6,\"n\":\"Aggro\",\"c\":[{\"t\":3,\"n\":\"Aggro Radius Behavior\"},{\"t\":3,\"n\":\"Unknown\"},{\"t\":3,\"n\":\"Warn\"},{\"t\":3,\"n\":\"Warn\\/Attack\"},{\"t\":3,\"n\":\"Attack\"}]}]},{\"t\":7,\"n\":\"Packages\",\"c\":[{\"t\":3,\"n\":\"PKID - Package\"}]},{\"t\":3,\"n\":\"KSIZ - Keyword Count\"},{\"t\":9,\"n\":\"KWDA - Keywords\",\"c\":[{\"t\":3,\"n\":\"Keyword\"}]},{\"t\":3,\"n\":\"CNAM - Class\"},{\"t\":2,\"n\":\"FULL - Name\"},{\"t\":2,\"n\":\"SHRT - Short Name\"},{\"t\":11,\"n\":\"DATA - Marker\"},{\"t\":6,\"n\":\"DNAM - Player Skills\",\"c\":[{\"t\":7,\"n\":\"Skill Values\",\"c\":[{\"t\":3,\"n\":\"Skill #0 (OneHanded)\"},{\"t\":3,\"n\":\"Skill #1 (TwoHanded)\"},{\"t\":3,\"n\":\"Skill #2 (Marksman)\"},{\"t\":3,\"n\":\"Skill #3 (Block)\"},{\"t\":3,\"n\":\"Skill #4 (Smithing)\"},{\"t\":3,\"n\":\"Skill #5 (HeavyArmor)\"},{\"t\":3,\"n\":\"Skill #6 (LightArmor)\"},{\"t\":3,\"n\":\"Skill #7 (Pickpocket)\"},{\"t\":3,\"n\":\"Skill #8 (Lockpicking)\"},{\"t\":3,\"n\":\"Skill #9 (Sneak)\"},{\"t\":3,\"n\":\"Skill #10 (Alchemy)\"},{\"t\":3,\"n\":\"Skill #11 (Speechcraft)\"},{\"t\":3,\"n\":\"Skill #12 (Alteration)\"},{\"t\":3,\"n\":\"Skill #13 (Conjuration)\"},{\"t\":3,\"n\":\"Skill #14 (Destruction)\"},{\"t\":3,\"n\":\"Skill #15 (Illusion)\"},{\"t\":3,\"n\":\"Skill #16 (Restoration)\"},{\"t\":3,\"n\":\"Skill #17 (Enchanting)\"}]},{\"t\":7,\"n\":\"Skill Offsets\",\"c\":[{\"t\":3,\"n\":\"Skill #0 (OneHanded)\"},{\"t\":3,\"n\":\"Skill #1 (TwoHanded)\"},{\"t\":3,\"n\":\"Skill #2 (Marksman)\"},{\"t\":3,\"n\":\"Skill #3 (Block)\"},{\"t\":3,\"n\":\"Skill #4 (Smithing)\"},{\"t\":3,\"n\":\"Skill #5 (HeavyArmor)\"},{\"t\":3,\"n\":\"Skill #6 (LightArmor)\"},{\"t\":3,\"n\":\"Skill #7 (Pickpocket)\"},{\"t\":3,\"n\":\"Skill #8 (Lockpicking)\"},{\"t\":3,\"n\":\"Skill #9 (Sneak)\"},{\"t\":3,\"n\":\"Skill #10 (Alchemy)\"},{\"t\":3,\"n\":\"Skill #11 (Speechcraft)\"},{\"t\":3,\"n\":\"Skill #12 (Alteration)\"},{\"t\":3,\"n\":\"Skill #13 (Conjuration)\"},{\"t\":3,\"n\":\"Skill #14 (Destruction)\"},{\"t\":3,\"n\":\"Skill #15 (Illusion)\"},{\"t\":3,\"n\":\"Skill #16 (Restoration)\"},{\"t\":3,\"n\":\"Skill #17 (Enchanting)\"}]},{\"t\":3,\"n\":\"Health\"},{\"t\":3,\"n\":\"Magicka\"},{\"t\":3,\"n\":\"Stamina\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":5,\"n\":\"Far away model distance\"},{\"t\":3,\"n\":\"Geared up weapons\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":9,\"n\":\"Head Parts\",\"c\":[{\"t\":3,\"n\":\"PNAM - Head Part\"}]},{\"t\":3,\"n\":\"HCLF - Hair Color\"},{\"t\":3,\"n\":\"ZNAM - Combat Style\"},{\"t\":3,\"n\":\"GNAM - Gift Filter\"},{\"t\":11,\"n\":\"NAM5 - Unknown\"},{\"t\":5,\"n\":\"NAM6 - Height\"},{\"t\":5,\"n\":\"NAM7 - Weight\"},{\"t\":3,\"n\":\"NAM8 - Sound Level\"},{\"t\":10,\"n\":\"Sound Types\",\"c\":[{\"t\":6,\"n\":\"Sound Type\",\"c\":[{\"t\":3,\"n\":\"CSDT - Type\"},{\"t\":10,\"n\":\"Sounds\",\"c\":[{\"t\":6,\"n\":\"Sound\",\"c\":[{\"t\":3,\"n\":\"CSDI - Sound\"},{\"t\":3,\"n\":\"CSDC - Sound Chance\"}]}]}]}]},{\"t\":3,\"n\":\"CSCR - Inherits Sounds From\"},{\"t\":3,\"n\":\"DOFT - Default outfit\"},{\"t\":3,\"n\":\"SOFT - Sleeping outfit\"},{\"t\":3,\"n\":\"DPLT - Default Package List\"},{\"t\":3,\"n\":\"CRIF - Crime faction\"},{\"t\":3,\"n\":\"FTST - Head texture\"},{\"t\":6,\"n\":\"QNAM - Texture lighting\",\"c\":[{\"t\":5,\"n\":\"Red\"},{\"t\":5,\"n\":\"Green\"},{\"t\":5,\"n\":\"Blue\"}]},{\"t\":6,\"n\":\"NAM9 - Face morph\",\"c\":[{\"t\":5,\"n\":\"Nose Long\\/Short\"},{\"t\":5,\"n\":\"Nose Up\\/Down\"},{\"t\":5,\"n\":\"Jaw Up\\/Down\"},{\"t\":5,\"n\":\"Jaw Narrow\\/Wide\"},{\"t\":5,\"n\":\"Jaw Farward\\/Back\"},{\"t\":5,\"n\":\"Cheeks Up\\/Down\"},{\"t\":5,\"n\":\"Cheeks Farward\\/Back\"},{\"t\":5,\"n\":\"Eyes Up\\/Down\"},{\"t\":5,\"n\":\"Eyes In\\/Out\"},{\"t\":5,\"n\":\"Brows Up\\/Down\"},{\"t\":5,\"n\":\"Brows In\\/Out\"},{\"t\":5,\"n\":\"Brows Farward\\/Back\"},{\"t\":5,\"n\":\"Lips Up\\/Down\"},{\"t\":5,\"n\":\"Lips In\\/Out\"},{\"t\":5,\"n\":\"Chin Narrow\\/Wide\"},{\"t\":5,\"n\":\"Chin Up\\/Down\"},{\"t\":5,\"n\":\"Chin Underbite\\/Overbite\"},{\"t\":5,\"n\":\"Eyes Farward\\/Back\"},{\"t\":5,\"n\":\"Unknown\"}]},{\"t\":6,\"n\":\"NAMA - Face parts\",\"c\":[{\"t\":3,\"n\":\"Nose\"},{\"t\":3,\"n\":\"Unknown\"},{\"t\":3,\"n\":\"Eyes\"},{\"t\":3,\"n\":\"Mouth\"}]},{\"t\":10,\"n\":\"Tint Layers\",\"c\":[{\"t\":6,\"n\":\"Layer\",\"c\":[{\"t\":3,\"n\":\"TINI - Tint Index\"}]}]}]}]},\"name\":\"Bash.Actors.DeathItem\",\"hash\":\"$EB6FA4F8\",\"color\":255}"
  },
  {
    "path": "frontend/settings/Skyrim/Bash.Actors.Spells.json",
    "content": "{\"records\":\"NPC_\",\"description\":\"Actors.Spells tag from Wrye Bash.\\r\\n\\r\\nUsed when the mod modifies NPC spell lists.\",\"tree\":{\"records\":[{\"t\":1,\"p\":1,\"n\":\"NPC_ - Non-Player Character (Actor)\",\"c\":[{\"t\":6,\"n\":\"Record Header\",\"c\":[{\"t\":2,\"n\":\"Signature\"},{\"t\":3,\"n\":\"Data Size\"},{\"t\":3,\"n\":\"Record Flags\"},{\"t\":3,\"n\":\"FormID\"},{\"t\":11,\"n\":\"Version Control Info 1\"},{\"t\":3,\"n\":\"Form Version\"},{\"t\":11,\"n\":\"Version Control Info 2\"}]},{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"n\":\"VMAD - Virtual Machine Adapter\",\"c\":[{\"t\":3,\"n\":\"Version\"},{\"t\":3,\"n\":\"Object Format\"},{\"t\":12,\"n\":\"Data\",\"c\":[{\"t\":9,\"n\":\"Scripts\",\"c\":[{\"t\":6,\"n\":\"Script\",\"c\":[{\"t\":2,\"n\":\"scriptName\"},{\"t\":3,\"n\":\"Flags\"},{\"t\":9,\"n\":\"Properties\",\"c\":[{\"t\":6,\"n\":\"Property\",\"c\":[{\"t\":2,\"n\":\"propertyName\"},{\"t\":3,\"n\":\"Type\"},{\"t\":3,\"n\":\"Flags\"},{\"t\":12,\"n\":\"Value\"}]}]}]}]}]}]},{\"t\":6,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"n\":\"X1\"},{\"t\":3,\"n\":\"Y1\"},{\"t\":3,\"n\":\"Z1\"},{\"t\":3,\"n\":\"X2\"},{\"t\":3,\"n\":\"Y2\"},{\"t\":3,\"n\":\"Z2\"}]},{\"t\":6,\"n\":\"ACBS - Configuration\",\"c\":[{\"t\":3,\"n\":\"Flags\"},{\"t\":3,\"n\":\"Magicka Offset\"},{\"t\":3,\"n\":\"Stamina Offset\"},{\"t\":12,\"n\":\"Level\"},{\"t\":3,\"n\":\"Calc min level\"},{\"t\":3,\"n\":\"Calc max level\"},{\"t\":3,\"n\":\"Speed Multiplier\"},{\"t\":3,\"n\":\"Disposition Base (unused)\"},{\"t\":3,\"n\":\"Template Flags\"},{\"t\":3,\"n\":\"Health Offset\"},{\"t\":3,\"n\":\"Bleedout Override\"}]},{\"t\":10,\"n\":\"Factions\",\"c\":[{\"t\":6,\"n\":\"SNAM - Faction\",\"c\":[{\"t\":3,\"n\":\"Faction\"},{\"t\":3,\"n\":\"Rank\"},{\"t\":11,\"n\":\"Unused\"}]}]},{\"t\":3,\"n\":\"INAM - Death item\"},{\"t\":3,\"n\":\"VTCK - Voice\"},{\"t\":3,\"n\":\"TPLT - Template\"},{\"t\":3,\"n\":\"RNAM - Race\"},{\"t\":3,\"n\":\"SPCT - Count\"},{\"t\":9,\"s\":1,\"p\":1,\"n\":\"Actor Effects\",\"d\":1,\"c\":[{\"t\":3,\"p\":1,\"n\":\"SPLO - Actor Effect\"}]},{\"t\":6,\"n\":\"Destructable\",\"c\":[{\"t\":6,\"n\":\"DEST - Header\",\"c\":[{\"t\":3,\"n\":\"Health\"},{\"t\":3,\"n\":\"DEST Count\"},{\"t\":3,\"n\":\"VATS Targetable\"},{\"t\":11,\"n\":\"Unknown\"}]}]},{\"t\":3,\"n\":\"WNAM - Worn Armor\"},{\"t\":3,\"n\":\"ANAM - Far away model\"},{\"t\":3,\"n\":\"ATKR - Attack Race\"},{\"t\":10,\"n\":\"Attacks\",\"c\":[{\"t\":6,\"n\":\"Attack\",\"c\":[{\"t\":6,\"n\":\"ATKD - Attack Data\",\"c\":[{\"t\":5,\"n\":\"Damage Mult\"},{\"t\":5,\"n\":\"Attack Chance\"},{\"t\":3,\"n\":\"Attack Spell\"},{\"t\":3,\"n\":\"Attack Flags\"},{\"t\":5,\"n\":\"Attack Angle\"},{\"t\":5,\"n\":\"Strike Angle\"},{\"t\":5,\"n\":\"Stagger\"},{\"t\":3,\"n\":\"Attack Type\"},{\"t\":5,\"n\":\"Knockdown\"},{\"t\":5,\"n\":\"Recovery Time\"},{\"t\":5,\"n\":\"Stamina Mult\"}]}]}]},{\"t\":3,\"n\":\"SPOR - Spectator override package list\"},{\"t\":3,\"n\":\"OCOR - Observe dead body override package list\"},{\"t\":3,\"n\":\"GWOR - Guard warn override package list\"},{\"t\":3,\"n\":\"ECOR - Combat override package list\"},{\"t\":3,\"n\":\"PRKZ - Perk Count\"},{\"t\":10,\"n\":\"Perks\",\"c\":[{\"t\":6,\"n\":\"PRKR - Perk\",\"c\":[{\"t\":3,\"n\":\"Perk\"},{\"t\":3,\"n\":\"Rank\"},{\"t\":11,\"n\":\"Unused\"}]}]},{\"t\":3,\"n\":\"COCT - Count\"},{\"t\":10,\"n\":\"Items\",\"c\":[{\"t\":6,\"n\":\"Item\",\"c\":[{\"t\":6,\"n\":\"CNTO - Item\",\"c\":[{\"t\":3,\"n\":\"Item\"},{\"t\":3,\"n\":\"Count\"}]}]}]},{\"t\":6,\"n\":\"AIDT - AI Data\",\"c\":[{\"t\":3,\"n\":\"Aggression\"},{\"t\":3,\"n\":\"Confidence\"},{\"t\":3,\"n\":\"Energy Level\"},{\"t\":3,\"n\":\"Responsibility\"},{\"t\":3,\"n\":\"Mood\"},{\"t\":3,\"n\":\"Assistance\"},{\"t\":6,\"n\":\"Aggro\",\"c\":[{\"t\":3,\"n\":\"Aggro Radius Behavior\"},{\"t\":3,\"n\":\"Unknown\"},{\"t\":3,\"n\":\"Warn\"},{\"t\":3,\"n\":\"Warn\\/Attack\"},{\"t\":3,\"n\":\"Attack\"}]}]},{\"t\":7,\"n\":\"Packages\",\"c\":[{\"t\":3,\"n\":\"PKID - Package\"}]},{\"t\":3,\"n\":\"KSIZ - Keyword Count\"},{\"t\":9,\"n\":\"KWDA - Keywords\",\"c\":[{\"t\":3,\"n\":\"Keyword\"}]},{\"t\":3,\"n\":\"CNAM - Class\"},{\"t\":2,\"n\":\"FULL - Name\"},{\"t\":2,\"n\":\"SHRT - Short Name\"},{\"t\":11,\"n\":\"DATA - Marker\"},{\"t\":6,\"n\":\"DNAM - Player Skills\",\"c\":[{\"t\":7,\"n\":\"Skill Values\",\"c\":[{\"t\":3,\"n\":\"Skill #0 (OneHanded)\"},{\"t\":3,\"n\":\"Skill #1 (TwoHanded)\"},{\"t\":3,\"n\":\"Skill #2 (Marksman)\"},{\"t\":3,\"n\":\"Skill #3 (Block)\"},{\"t\":3,\"n\":\"Skill #4 (Smithing)\"},{\"t\":3,\"n\":\"Skill #5 (HeavyArmor)\"},{\"t\":3,\"n\":\"Skill #6 (LightArmor)\"},{\"t\":3,\"n\":\"Skill #7 (Pickpocket)\"},{\"t\":3,\"n\":\"Skill #8 (Lockpicking)\"},{\"t\":3,\"n\":\"Skill #9 (Sneak)\"},{\"t\":3,\"n\":\"Skill #10 (Alchemy)\"},{\"t\":3,\"n\":\"Skill #11 (Speechcraft)\"},{\"t\":3,\"n\":\"Skill #12 (Alteration)\"},{\"t\":3,\"n\":\"Skill #13 (Conjuration)\"},{\"t\":3,\"n\":\"Skill #14 (Destruction)\"},{\"t\":3,\"n\":\"Skill #15 (Illusion)\"},{\"t\":3,\"n\":\"Skill #16 (Restoration)\"},{\"t\":3,\"n\":\"Skill #17 (Enchanting)\"}]},{\"t\":7,\"n\":\"Skill Offsets\",\"c\":[{\"t\":3,\"n\":\"Skill #0 (OneHanded)\"},{\"t\":3,\"n\":\"Skill #1 (TwoHanded)\"},{\"t\":3,\"n\":\"Skill #2 (Marksman)\"},{\"t\":3,\"n\":\"Skill #3 (Block)\"},{\"t\":3,\"n\":\"Skill #4 (Smithing)\"},{\"t\":3,\"n\":\"Skill #5 (HeavyArmor)\"},{\"t\":3,\"n\":\"Skill #6 (LightArmor)\"},{\"t\":3,\"n\":\"Skill #7 (Pickpocket)\"},{\"t\":3,\"n\":\"Skill #8 (Lockpicking)\"},{\"t\":3,\"n\":\"Skill #9 (Sneak)\"},{\"t\":3,\"n\":\"Skill #10 (Alchemy)\"},{\"t\":3,\"n\":\"Skill #11 (Speechcraft)\"},{\"t\":3,\"n\":\"Skill #12 (Alteration)\"},{\"t\":3,\"n\":\"Skill #13 (Conjuration)\"},{\"t\":3,\"n\":\"Skill #14 (Destruction)\"},{\"t\":3,\"n\":\"Skill #15 (Illusion)\"},{\"t\":3,\"n\":\"Skill #16 (Restoration)\"},{\"t\":3,\"n\":\"Skill #17 (Enchanting)\"}]},{\"t\":3,\"n\":\"Health\"},{\"t\":3,\"n\":\"Magicka\"},{\"t\":3,\"n\":\"Stamina\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":5,\"n\":\"Far away model distance\"},{\"t\":3,\"n\":\"Geared up weapons\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":9,\"n\":\"Head Parts\",\"c\":[{\"t\":3,\"n\":\"PNAM - Head Part\"}]},{\"t\":3,\"n\":\"HCLF - Hair Color\"},{\"t\":3,\"n\":\"ZNAM - Combat Style\"},{\"t\":3,\"n\":\"GNAM - Gift Filter\"},{\"t\":11,\"n\":\"NAM5 - Unknown\"},{\"t\":5,\"n\":\"NAM6 - Height\"},{\"t\":5,\"n\":\"NAM7 - Weight\"},{\"t\":3,\"n\":\"NAM8 - Sound Level\"},{\"t\":10,\"n\":\"Sound Types\",\"c\":[{\"t\":6,\"n\":\"Sound Type\",\"c\":[{\"t\":3,\"n\":\"CSDT - Type\"},{\"t\":10,\"n\":\"Sounds\",\"c\":[{\"t\":6,\"n\":\"Sound\",\"c\":[{\"t\":3,\"n\":\"CSDI - Sound\"},{\"t\":3,\"n\":\"CSDC - Sound Chance\"}]}]}]}]},{\"t\":3,\"n\":\"CSCR - Inherits Sounds From\"},{\"t\":3,\"n\":\"DOFT - Default outfit\"},{\"t\":3,\"n\":\"SOFT - Sleeping outfit\"},{\"t\":3,\"n\":\"DPLT - Default Package List\"},{\"t\":3,\"n\":\"CRIF - Crime faction\"},{\"t\":3,\"n\":\"FTST - Head texture\"},{\"t\":6,\"n\":\"QNAM - Texture lighting\",\"c\":[{\"t\":5,\"n\":\"Red\"},{\"t\":5,\"n\":\"Green\"},{\"t\":5,\"n\":\"Blue\"}]},{\"t\":6,\"n\":\"NAM9 - Face morph\",\"c\":[{\"t\":5,\"n\":\"Nose Long\\/Short\"},{\"t\":5,\"n\":\"Nose Up\\/Down\"},{\"t\":5,\"n\":\"Jaw Up\\/Down\"},{\"t\":5,\"n\":\"Jaw Narrow\\/Wide\"},{\"t\":5,\"n\":\"Jaw Farward\\/Back\"},{\"t\":5,\"n\":\"Cheeks Up\\/Down\"},{\"t\":5,\"n\":\"Cheeks Farward\\/Back\"},{\"t\":5,\"n\":\"Eyes Up\\/Down\"},{\"t\":5,\"n\":\"Eyes In\\/Out\"},{\"t\":5,\"n\":\"Brows Up\\/Down\"},{\"t\":5,\"n\":\"Brows In\\/Out\"},{\"t\":5,\"n\":\"Brows Farward\\/Back\"},{\"t\":5,\"n\":\"Lips Up\\/Down\"},{\"t\":5,\"n\":\"Lips In\\/Out\"},{\"t\":5,\"n\":\"Chin Narrow\\/Wide\"},{\"t\":5,\"n\":\"Chin Up\\/Down\"},{\"t\":5,\"n\":\"Chin Underbite\\/Overbite\"},{\"t\":5,\"n\":\"Eyes Farward\\/Back\"},{\"t\":5,\"n\":\"Unknown\"}]},{\"t\":6,\"n\":\"NAMA - Face parts\",\"c\":[{\"t\":3,\"n\":\"Nose\"},{\"t\":3,\"n\":\"Unknown\"},{\"t\":3,\"n\":\"Eyes\"},{\"t\":3,\"n\":\"Mouth\"}]},{\"t\":10,\"n\":\"Tint Layers\",\"c\":[{\"t\":6,\"n\":\"Layer\",\"c\":[{\"t\":3,\"n\":\"TINI - Tint Index\"}]}]}]}]},\"name\":\"Bash.Actors.Spells\",\"hash\":\"$EA31B7C4\",\"color\":255}"
  },
  {
    "path": "frontend/settings/Skyrim/Bash.Actors.SpellsMerge.json",
    "content": "{\"records\":\"NPC_\",\"description\":\"An alternative to the Actors.SpellsForceAdd tag from Wrye Bash.\\r\\n\\r\\nMator Smash cannot currently perform the logic for a forced addition as Wrye Bash does with the Actors.SpellsForceAdd tag.  This tag does the next best thing, which causes spells to be merged.\",\"tree\":{\"records\":[{\"t\":1,\"p\":1,\"n\":\"NPC_ - Non-Player Character (Actor)\",\"c\":[{\"t\":6,\"n\":\"Record Header\",\"c\":[{\"t\":2,\"n\":\"Signature\"},{\"t\":3,\"n\":\"Data Size\"},{\"t\":3,\"n\":\"Record Flags\"},{\"t\":3,\"n\":\"FormID\"},{\"t\":11,\"n\":\"Version Control Info 1\"},{\"t\":3,\"n\":\"Form Version\"},{\"t\":11,\"n\":\"Version Control Info 2\"}]},{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"n\":\"VMAD - Virtual Machine Adapter\",\"c\":[{\"t\":3,\"n\":\"Version\"},{\"t\":3,\"n\":\"Object Format\"},{\"t\":12,\"n\":\"Data\",\"c\":[{\"t\":9,\"n\":\"Scripts\",\"c\":[{\"t\":6,\"n\":\"Script\",\"c\":[{\"t\":2,\"n\":\"scriptName\"},{\"t\":3,\"n\":\"Flags\"},{\"t\":9,\"n\":\"Properties\",\"c\":[{\"t\":6,\"n\":\"Property\",\"c\":[{\"t\":2,\"n\":\"propertyName\"},{\"t\":3,\"n\":\"Type\"},{\"t\":3,\"n\":\"Flags\"},{\"t\":12,\"n\":\"Value\"}]}]}]}]}]}]},{\"t\":6,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"n\":\"X1\"},{\"t\":3,\"n\":\"Y1\"},{\"t\":3,\"n\":\"Z1\"},{\"t\":3,\"n\":\"X2\"},{\"t\":3,\"n\":\"Y2\"},{\"t\":3,\"n\":\"Z2\"}]},{\"t\":6,\"n\":\"ACBS - Configuration\",\"c\":[{\"t\":3,\"n\":\"Flags\"},{\"t\":3,\"n\":\"Magicka Offset\"},{\"t\":3,\"n\":\"Stamina Offset\"},{\"t\":12,\"n\":\"Level\"},{\"t\":3,\"n\":\"Calc min level\"},{\"t\":3,\"n\":\"Calc max level\"},{\"t\":3,\"n\":\"Speed Multiplier\"},{\"t\":3,\"n\":\"Disposition Base (unused)\"},{\"t\":3,\"n\":\"Template Flags\"},{\"t\":3,\"n\":\"Health Offset\"},{\"t\":3,\"n\":\"Bleedout Override\"}]},{\"t\":10,\"n\":\"Factions\",\"c\":[{\"t\":6,\"n\":\"SNAM - Faction\",\"c\":[{\"t\":3,\"n\":\"Faction\"},{\"t\":3,\"n\":\"Rank\"},{\"t\":11,\"n\":\"Unused\"}]}]},{\"t\":3,\"n\":\"INAM - Death item\"},{\"t\":3,\"n\":\"VTCK - Voice\"},{\"t\":3,\"n\":\"TPLT - Template\"},{\"t\":3,\"n\":\"RNAM - Race\"},{\"t\":3,\"n\":\"SPCT - Count\"},{\"t\":9,\"p\":1,\"n\":\"Actor Effects\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"SPLO - Actor Effect\"}]},{\"t\":6,\"n\":\"Destructable\",\"c\":[{\"t\":6,\"n\":\"DEST - Header\",\"c\":[{\"t\":3,\"n\":\"Health\"},{\"t\":3,\"n\":\"DEST Count\"},{\"t\":3,\"n\":\"VATS Targetable\"},{\"t\":11,\"n\":\"Unknown\"}]}]},{\"t\":3,\"n\":\"WNAM - Worn Armor\"},{\"t\":3,\"n\":\"ANAM - Far away model\"},{\"t\":3,\"n\":\"ATKR - Attack Race\"},{\"t\":10,\"n\":\"Attacks\",\"c\":[{\"t\":6,\"n\":\"Attack\",\"c\":[{\"t\":6,\"n\":\"ATKD - Attack Data\",\"c\":[{\"t\":5,\"n\":\"Damage Mult\"},{\"t\":5,\"n\":\"Attack Chance\"},{\"t\":3,\"n\":\"Attack Spell\"},{\"t\":3,\"n\":\"Attack Flags\"},{\"t\":5,\"n\":\"Attack Angle\"},{\"t\":5,\"n\":\"Strike Angle\"},{\"t\":5,\"n\":\"Stagger\"},{\"t\":3,\"n\":\"Attack Type\"},{\"t\":5,\"n\":\"Knockdown\"},{\"t\":5,\"n\":\"Recovery Time\"},{\"t\":5,\"n\":\"Stamina Mult\"}]}]}]},{\"t\":3,\"n\":\"SPOR - Spectator override package list\"},{\"t\":3,\"n\":\"OCOR - Observe dead body override package list\"},{\"t\":3,\"n\":\"GWOR - Guard warn override package list\"},{\"t\":3,\"n\":\"ECOR - Combat override package list\"},{\"t\":3,\"n\":\"PRKZ - Perk Count\"},{\"t\":10,\"n\":\"Perks\",\"c\":[{\"t\":6,\"n\":\"PRKR - Perk\",\"c\":[{\"t\":3,\"n\":\"Perk\"},{\"t\":3,\"n\":\"Rank\"},{\"t\":11,\"n\":\"Unused\"}]}]},{\"t\":3,\"n\":\"COCT - Count\"},{\"t\":10,\"n\":\"Items\",\"c\":[{\"t\":6,\"n\":\"Item\",\"c\":[{\"t\":6,\"n\":\"CNTO - Item\",\"c\":[{\"t\":3,\"n\":\"Item\"},{\"t\":3,\"n\":\"Count\"}]}]}]},{\"t\":6,\"n\":\"AIDT - AI Data\",\"c\":[{\"t\":3,\"n\":\"Aggression\"},{\"t\":3,\"n\":\"Confidence\"},{\"t\":3,\"n\":\"Energy Level\"},{\"t\":3,\"n\":\"Responsibility\"},{\"t\":3,\"n\":\"Mood\"},{\"t\":3,\"n\":\"Assistance\"},{\"t\":6,\"n\":\"Aggro\",\"c\":[{\"t\":3,\"n\":\"Aggro Radius Behavior\"},{\"t\":3,\"n\":\"Unknown\"},{\"t\":3,\"n\":\"Warn\"},{\"t\":3,\"n\":\"Warn\\/Attack\"},{\"t\":3,\"n\":\"Attack\"}]}]},{\"t\":7,\"n\":\"Packages\",\"c\":[{\"t\":3,\"n\":\"PKID - Package\"}]},{\"t\":3,\"n\":\"KSIZ - Keyword Count\"},{\"t\":9,\"n\":\"KWDA - Keywords\",\"c\":[{\"t\":3,\"n\":\"Keyword\"}]},{\"t\":3,\"n\":\"CNAM - Class\"},{\"t\":2,\"n\":\"FULL - Name\"},{\"t\":2,\"n\":\"SHRT - Short Name\"},{\"t\":11,\"n\":\"DATA - Marker\"},{\"t\":6,\"n\":\"DNAM - Player Skills\",\"c\":[{\"t\":7,\"n\":\"Skill Values\",\"c\":[{\"t\":3,\"n\":\"Skill #0 (OneHanded)\"},{\"t\":3,\"n\":\"Skill #1 (TwoHanded)\"},{\"t\":3,\"n\":\"Skill #2 (Marksman)\"},{\"t\":3,\"n\":\"Skill #3 (Block)\"},{\"t\":3,\"n\":\"Skill #4 (Smithing)\"},{\"t\":3,\"n\":\"Skill #5 (HeavyArmor)\"},{\"t\":3,\"n\":\"Skill #6 (LightArmor)\"},{\"t\":3,\"n\":\"Skill #7 (Pickpocket)\"},{\"t\":3,\"n\":\"Skill #8 (Lockpicking)\"},{\"t\":3,\"n\":\"Skill #9 (Sneak)\"},{\"t\":3,\"n\":\"Skill #10 (Alchemy)\"},{\"t\":3,\"n\":\"Skill #11 (Speechcraft)\"},{\"t\":3,\"n\":\"Skill #12 (Alteration)\"},{\"t\":3,\"n\":\"Skill #13 (Conjuration)\"},{\"t\":3,\"n\":\"Skill #14 (Destruction)\"},{\"t\":3,\"n\":\"Skill #15 (Illusion)\"},{\"t\":3,\"n\":\"Skill #16 (Restoration)\"},{\"t\":3,\"n\":\"Skill #17 (Enchanting)\"}]},{\"t\":7,\"n\":\"Skill Offsets\",\"c\":[{\"t\":3,\"n\":\"Skill #0 (OneHanded)\"},{\"t\":3,\"n\":\"Skill #1 (TwoHanded)\"},{\"t\":3,\"n\":\"Skill #2 (Marksman)\"},{\"t\":3,\"n\":\"Skill #3 (Block)\"},{\"t\":3,\"n\":\"Skill #4 (Smithing)\"},{\"t\":3,\"n\":\"Skill #5 (HeavyArmor)\"},{\"t\":3,\"n\":\"Skill #6 (LightArmor)\"},{\"t\":3,\"n\":\"Skill #7 (Pickpocket)\"},{\"t\":3,\"n\":\"Skill #8 (Lockpicking)\"},{\"t\":3,\"n\":\"Skill #9 (Sneak)\"},{\"t\":3,\"n\":\"Skill #10 (Alchemy)\"},{\"t\":3,\"n\":\"Skill #11 (Speechcraft)\"},{\"t\":3,\"n\":\"Skill #12 (Alteration)\"},{\"t\":3,\"n\":\"Skill #13 (Conjuration)\"},{\"t\":3,\"n\":\"Skill #14 (Destruction)\"},{\"t\":3,\"n\":\"Skill #15 (Illusion)\"},{\"t\":3,\"n\":\"Skill #16 (Restoration)\"},{\"t\":3,\"n\":\"Skill #17 (Enchanting)\"}]},{\"t\":3,\"n\":\"Health\"},{\"t\":3,\"n\":\"Magicka\"},{\"t\":3,\"n\":\"Stamina\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":5,\"n\":\"Far away model distance\"},{\"t\":3,\"n\":\"Geared up weapons\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":9,\"n\":\"Head Parts\",\"c\":[{\"t\":3,\"n\":\"PNAM - Head Part\"}]},{\"t\":3,\"n\":\"HCLF - Hair Color\"},{\"t\":3,\"n\":\"ZNAM - Combat Style\"},{\"t\":3,\"n\":\"GNAM - Gift Filter\"},{\"t\":11,\"n\":\"NAM5 - Unknown\"},{\"t\":5,\"n\":\"NAM6 - Height\"},{\"t\":5,\"n\":\"NAM7 - Weight\"},{\"t\":3,\"n\":\"NAM8 - Sound Level\"},{\"t\":10,\"n\":\"Sound Types\",\"c\":[{\"t\":6,\"n\":\"Sound Type\",\"c\":[{\"t\":3,\"n\":\"CSDT - Type\"},{\"t\":10,\"n\":\"Sounds\",\"c\":[{\"t\":6,\"n\":\"Sound\",\"c\":[{\"t\":3,\"n\":\"CSDI - Sound\"},{\"t\":3,\"n\":\"CSDC - Sound Chance\"}]}]}]}]},{\"t\":3,\"n\":\"CSCR - Inherits Sounds From\"},{\"t\":3,\"n\":\"DOFT - Default outfit\"},{\"t\":3,\"n\":\"SOFT - Sleeping outfit\"},{\"t\":3,\"n\":\"DPLT - Default Package List\"},{\"t\":3,\"n\":\"CRIF - Crime faction\"},{\"t\":3,\"n\":\"FTST - Head texture\"},{\"t\":6,\"n\":\"QNAM - Texture lighting\",\"c\":[{\"t\":5,\"n\":\"Red\"},{\"t\":5,\"n\":\"Green\"},{\"t\":5,\"n\":\"Blue\"}]},{\"t\":6,\"n\":\"NAM9 - Face morph\",\"c\":[{\"t\":5,\"n\":\"Nose Long\\/Short\"},{\"t\":5,\"n\":\"Nose Up\\/Down\"},{\"t\":5,\"n\":\"Jaw Up\\/Down\"},{\"t\":5,\"n\":\"Jaw Narrow\\/Wide\"},{\"t\":5,\"n\":\"Jaw Farward\\/Back\"},{\"t\":5,\"n\":\"Cheeks Up\\/Down\"},{\"t\":5,\"n\":\"Cheeks Farward\\/Back\"},{\"t\":5,\"n\":\"Eyes Up\\/Down\"},{\"t\":5,\"n\":\"Eyes In\\/Out\"},{\"t\":5,\"n\":\"Brows Up\\/Down\"},{\"t\":5,\"n\":\"Brows In\\/Out\"},{\"t\":5,\"n\":\"Brows Farward\\/Back\"},{\"t\":5,\"n\":\"Lips Up\\/Down\"},{\"t\":5,\"n\":\"Lips In\\/Out\"},{\"t\":5,\"n\":\"Chin Narrow\\/Wide\"},{\"t\":5,\"n\":\"Chin Up\\/Down\"},{\"t\":5,\"n\":\"Chin Underbite\\/Overbite\"},{\"t\":5,\"n\":\"Eyes Farward\\/Back\"},{\"t\":5,\"n\":\"Unknown\"}]},{\"t\":6,\"n\":\"NAMA - Face parts\",\"c\":[{\"t\":3,\"n\":\"Nose\"},{\"t\":3,\"n\":\"Unknown\"},{\"t\":3,\"n\":\"Eyes\"},{\"t\":3,\"n\":\"Mouth\"}]},{\"t\":10,\"n\":\"Tint Layers\",\"c\":[{\"t\":6,\"n\":\"Layer\",\"c\":[{\"t\":3,\"n\":\"TINI - Tint Index\"}]}]}]}]},\"name\":\"Bash.Actors.SpellsMerge\",\"hash\":\"$F37D6A14\",\"color\":255}"
  },
  {
    "path": "frontend/settings/Skyrim/Bash.Actors.Stats.json",
    "content": "{\"records\":\"NPC_\",\"description\":\"Actors.Stats tag from Wrye Bash.\\r\\n\\r\\nUsed when the mod modifies NPC stats.\",\"tree\":{\"records\":[{\"t\":1,\"p\":1,\"n\":\"NPC_ - Non-Player Character (Actor)\",\"c\":[{\"t\":6,\"n\":\"Record Header\",\"c\":[{\"t\":2,\"n\":\"Signature\"},{\"t\":3,\"n\":\"Data Size\"},{\"t\":3,\"n\":\"Record Flags\"},{\"t\":3,\"n\":\"FormID\"},{\"t\":11,\"n\":\"Version Control Info 1\"},{\"t\":3,\"n\":\"Form Version\"},{\"t\":11,\"n\":\"Version Control Info 2\"}]},{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"n\":\"VMAD - Virtual Machine Adapter\",\"c\":[{\"t\":3,\"n\":\"Version\"},{\"t\":3,\"n\":\"Object Format\"},{\"t\":12,\"n\":\"Data\",\"c\":[{\"t\":9,\"n\":\"Scripts\",\"c\":[{\"t\":6,\"n\":\"Script\",\"c\":[{\"t\":2,\"n\":\"scriptName\"},{\"t\":3,\"n\":\"Flags\"},{\"t\":9,\"n\":\"Properties\",\"c\":[{\"t\":6,\"n\":\"Property\",\"c\":[{\"t\":2,\"n\":\"propertyName\"},{\"t\":3,\"n\":\"Type\"},{\"t\":3,\"n\":\"Flags\"},{\"t\":12,\"n\":\"Value\"}]}]}]}]}]}]},{\"t\":6,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"n\":\"X1\"},{\"t\":3,\"n\":\"Y1\"},{\"t\":3,\"n\":\"Z1\"},{\"t\":3,\"n\":\"X2\"},{\"t\":3,\"n\":\"Y2\"},{\"t\":3,\"n\":\"Z2\"}]},{\"t\":6,\"n\":\"ACBS - Configuration\",\"c\":[{\"t\":3,\"n\":\"Flags\"},{\"t\":3,\"n\":\"Magicka Offset\"},{\"t\":3,\"n\":\"Stamina Offset\"},{\"t\":12,\"n\":\"Level\"},{\"t\":3,\"n\":\"Calc min level\"},{\"t\":3,\"n\":\"Calc max level\"},{\"t\":3,\"n\":\"Speed Multiplier\"},{\"t\":3,\"n\":\"Disposition Base (unused)\"},{\"t\":3,\"n\":\"Template Flags\"},{\"t\":3,\"n\":\"Health Offset\"},{\"t\":3,\"n\":\"Bleedout Override\"}]},{\"t\":10,\"n\":\"Factions\",\"c\":[{\"t\":6,\"n\":\"SNAM - Faction\",\"c\":[{\"t\":3,\"n\":\"Faction\"},{\"t\":3,\"n\":\"Rank\"},{\"t\":11,\"n\":\"Unused\"}]}]},{\"t\":3,\"n\":\"INAM - Death item\"},{\"t\":3,\"n\":\"VTCK - Voice\"},{\"t\":3,\"n\":\"TPLT - Template\"},{\"t\":3,\"n\":\"RNAM - Race\"},{\"t\":3,\"n\":\"SPCT - Count\"},{\"t\":9,\"n\":\"Actor Effects\",\"c\":[{\"t\":3,\"n\":\"SPLO - Actor Effect\"}]},{\"t\":6,\"n\":\"Destructable\",\"c\":[{\"t\":6,\"n\":\"DEST - Header\",\"c\":[{\"t\":3,\"n\":\"Health\"},{\"t\":3,\"n\":\"DEST Count\"},{\"t\":3,\"n\":\"VATS Targetable\"},{\"t\":11,\"n\":\"Unknown\"}]}]},{\"t\":3,\"n\":\"WNAM - Worn Armor\"},{\"t\":3,\"n\":\"ANAM - Far away model\"},{\"t\":3,\"n\":\"ATKR - Attack Race\"},{\"t\":10,\"n\":\"Attacks\",\"c\":[{\"t\":6,\"n\":\"Attack\",\"c\":[{\"t\":6,\"n\":\"ATKD - Attack Data\",\"c\":[{\"t\":5,\"n\":\"Damage Mult\"},{\"t\":5,\"n\":\"Attack Chance\"},{\"t\":3,\"n\":\"Attack Spell\"},{\"t\":3,\"n\":\"Attack Flags\"},{\"t\":5,\"n\":\"Attack Angle\"},{\"t\":5,\"n\":\"Strike Angle\"},{\"t\":5,\"n\":\"Stagger\"},{\"t\":3,\"n\":\"Attack Type\"},{\"t\":5,\"n\":\"Knockdown\"},{\"t\":5,\"n\":\"Recovery Time\"},{\"t\":5,\"n\":\"Stamina Mult\"}]}]}]},{\"t\":3,\"n\":\"SPOR - Spectator override package list\"},{\"t\":3,\"n\":\"OCOR - Observe dead body override package list\"},{\"t\":3,\"n\":\"GWOR - Guard warn override package list\"},{\"t\":3,\"n\":\"ECOR - Combat override package list\"},{\"t\":3,\"n\":\"PRKZ - Perk Count\"},{\"t\":10,\"n\":\"Perks\",\"c\":[{\"t\":6,\"n\":\"PRKR - Perk\",\"c\":[{\"t\":3,\"n\":\"Perk\"},{\"t\":3,\"n\":\"Rank\"},{\"t\":11,\"n\":\"Unused\"}]}]},{\"t\":3,\"n\":\"COCT - Count\"},{\"t\":10,\"n\":\"Items\",\"c\":[{\"t\":6,\"n\":\"Item\",\"c\":[{\"t\":6,\"n\":\"CNTO - Item\",\"c\":[{\"t\":3,\"n\":\"Item\"},{\"t\":3,\"n\":\"Count\"}]}]}]},{\"t\":6,\"n\":\"AIDT - AI Data\",\"c\":[{\"t\":3,\"n\":\"Aggression\"},{\"t\":3,\"n\":\"Confidence\"},{\"t\":3,\"n\":\"Energy Level\"},{\"t\":3,\"n\":\"Responsibility\"},{\"t\":3,\"n\":\"Mood\"},{\"t\":3,\"n\":\"Assistance\"},{\"t\":6,\"n\":\"Aggro\",\"c\":[{\"t\":3,\"n\":\"Aggro Radius Behavior\"},{\"t\":3,\"n\":\"Unknown\"},{\"t\":3,\"n\":\"Warn\"},{\"t\":3,\"n\":\"Warn\\/Attack\"},{\"t\":3,\"n\":\"Attack\"}]}]},{\"t\":7,\"n\":\"Packages\",\"c\":[{\"t\":3,\"n\":\"PKID - Package\"}]},{\"t\":3,\"n\":\"KSIZ - Keyword Count\"},{\"t\":9,\"n\":\"KWDA - Keywords\",\"c\":[{\"t\":3,\"n\":\"Keyword\"}]},{\"t\":3,\"n\":\"CNAM - Class\"},{\"t\":2,\"n\":\"FULL - Name\"},{\"t\":2,\"n\":\"SHRT - Short Name\"},{\"t\":11,\"n\":\"DATA - Marker\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DNAM - Player Skills\",\"c\":[{\"t\":7,\"p\":1,\"n\":\"Skill Values\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Skill #0 (OneHanded)\"},{\"t\":3,\"p\":1,\"n\":\"Skill #1 (TwoHanded)\"},{\"t\":3,\"p\":1,\"n\":\"Skill #2 (Marksman)\"},{\"t\":3,\"p\":1,\"n\":\"Skill #3 (Block)\"},{\"t\":3,\"p\":1,\"n\":\"Skill #4 (Smithing)\"},{\"t\":3,\"p\":1,\"n\":\"Skill #5 (HeavyArmor)\"},{\"t\":3,\"p\":1,\"n\":\"Skill #6 (LightArmor)\"},{\"t\":3,\"p\":1,\"n\":\"Skill #7 (Pickpocket)\"},{\"t\":3,\"p\":1,\"n\":\"Skill #8 (Lockpicking)\"},{\"t\":3,\"p\":1,\"n\":\"Skill #9 (Sneak)\"},{\"t\":3,\"p\":1,\"n\":\"Skill #10 (Alchemy)\"},{\"t\":3,\"p\":1,\"n\":\"Skill #11 (Speechcraft)\"},{\"t\":3,\"p\":1,\"n\":\"Skill #12 (Alteration)\"},{\"t\":3,\"p\":1,\"n\":\"Skill #13 (Conjuration)\"},{\"t\":3,\"p\":1,\"n\":\"Skill #14 (Destruction)\"},{\"t\":3,\"p\":1,\"n\":\"Skill #15 (Illusion)\"},{\"t\":3,\"p\":1,\"n\":\"Skill #16 (Restoration)\"},{\"t\":3,\"p\":1,\"n\":\"Skill #17 (Enchanting)\"}]},{\"t\":7,\"p\":1,\"n\":\"Skill Offsets\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Skill #0 (OneHanded)\"},{\"t\":3,\"p\":1,\"n\":\"Skill #1 (TwoHanded)\"},{\"t\":3,\"p\":1,\"n\":\"Skill #2 (Marksman)\"},{\"t\":3,\"p\":1,\"n\":\"Skill #3 (Block)\"},{\"t\":3,\"p\":1,\"n\":\"Skill #4 (Smithing)\"},{\"t\":3,\"p\":1,\"n\":\"Skill #5 (HeavyArmor)\"},{\"t\":3,\"p\":1,\"n\":\"Skill #6 (LightArmor)\"},{\"t\":3,\"p\":1,\"n\":\"Skill #7 (Pickpocket)\"},{\"t\":3,\"p\":1,\"n\":\"Skill #8 (Lockpicking)\"},{\"t\":3,\"p\":1,\"n\":\"Skill #9 (Sneak)\"},{\"t\":3,\"p\":1,\"n\":\"Skill #10 (Alchemy)\"},{\"t\":3,\"p\":1,\"n\":\"Skill #11 (Speechcraft)\"},{\"t\":3,\"p\":1,\"n\":\"Skill #12 (Alteration)\"},{\"t\":3,\"p\":1,\"n\":\"Skill #13 (Conjuration)\"},{\"t\":3,\"p\":1,\"n\":\"Skill #14 (Destruction)\"},{\"t\":3,\"p\":1,\"n\":\"Skill #15 (Illusion)\"},{\"t\":3,\"p\":1,\"n\":\"Skill #16 (Restoration)\"},{\"t\":3,\"p\":1,\"n\":\"Skill #17 (Enchanting)\"}]},{\"t\":3,\"p\":1,\"n\":\"Health\"},{\"t\":3,\"p\":1,\"n\":\"Magicka\"},{\"t\":3,\"p\":1,\"n\":\"Stamina\"},{\"t\":11,\"p\":1,\"n\":\"Unused\"},{\"t\":5,\"p\":1,\"n\":\"Far away model distance\"},{\"t\":3,\"p\":1,\"n\":\"Geared up weapons\"},{\"t\":11,\"p\":1,\"n\":\"Unused\"}]},{\"t\":9,\"n\":\"Head Parts\",\"c\":[{\"t\":3,\"n\":\"PNAM - Head Part\"}]},{\"t\":3,\"n\":\"HCLF - Hair Color\"},{\"t\":3,\"n\":\"ZNAM - Combat Style\"},{\"t\":3,\"n\":\"GNAM - Gift Filter\"},{\"t\":11,\"n\":\"NAM5 - Unknown\"},{\"t\":5,\"n\":\"NAM6 - Height\"},{\"t\":5,\"n\":\"NAM7 - Weight\"},{\"t\":3,\"n\":\"NAM8 - Sound Level\"},{\"t\":10,\"n\":\"Sound Types\",\"c\":[{\"t\":6,\"n\":\"Sound Type\",\"c\":[{\"t\":3,\"n\":\"CSDT - Type\"},{\"t\":10,\"n\":\"Sounds\",\"c\":[{\"t\":6,\"n\":\"Sound\",\"c\":[{\"t\":3,\"n\":\"CSDI - Sound\"},{\"t\":3,\"n\":\"CSDC - Sound Chance\"}]}]}]}]},{\"t\":3,\"n\":\"CSCR - Inherits Sounds From\"},{\"t\":3,\"n\":\"DOFT - Default outfit\"},{\"t\":3,\"n\":\"SOFT - Sleeping outfit\"},{\"t\":3,\"n\":\"DPLT - Default Package List\"},{\"t\":3,\"n\":\"CRIF - Crime faction\"},{\"t\":3,\"n\":\"FTST - Head texture\"},{\"t\":6,\"n\":\"QNAM - Texture lighting\",\"c\":[{\"t\":5,\"n\":\"Red\"},{\"t\":5,\"n\":\"Green\"},{\"t\":5,\"n\":\"Blue\"}]},{\"t\":6,\"n\":\"NAM9 - Face morph\",\"c\":[{\"t\":5,\"n\":\"Nose Long\\/Short\"},{\"t\":5,\"n\":\"Nose Up\\/Down\"},{\"t\":5,\"n\":\"Jaw Up\\/Down\"},{\"t\":5,\"n\":\"Jaw Narrow\\/Wide\"},{\"t\":5,\"n\":\"Jaw Farward\\/Back\"},{\"t\":5,\"n\":\"Cheeks Up\\/Down\"},{\"t\":5,\"n\":\"Cheeks Farward\\/Back\"},{\"t\":5,\"n\":\"Eyes Up\\/Down\"},{\"t\":5,\"n\":\"Eyes In\\/Out\"},{\"t\":5,\"n\":\"Brows Up\\/Down\"},{\"t\":5,\"n\":\"Brows In\\/Out\"},{\"t\":5,\"n\":\"Brows Farward\\/Back\"},{\"t\":5,\"n\":\"Lips Up\\/Down\"},{\"t\":5,\"n\":\"Lips In\\/Out\"},{\"t\":5,\"n\":\"Chin Narrow\\/Wide\"},{\"t\":5,\"n\":\"Chin Up\\/Down\"},{\"t\":5,\"n\":\"Chin Underbite\\/Overbite\"},{\"t\":5,\"n\":\"Eyes Farward\\/Back\"},{\"t\":5,\"n\":\"Unknown\"}]},{\"t\":6,\"n\":\"NAMA - Face parts\",\"c\":[{\"t\":3,\"n\":\"Nose\"},{\"t\":3,\"n\":\"Unknown\"},{\"t\":3,\"n\":\"Eyes\"},{\"t\":3,\"n\":\"Mouth\"}]},{\"t\":10,\"n\":\"Tint Layers\",\"c\":[{\"t\":6,\"n\":\"Layer\",\"c\":[{\"t\":3,\"n\":\"TINI - Tint Index\"}]}]}]}]},\"name\":\"Bash.Actors.Stats\",\"hash\":\"$5853D7A6\",\"color\":255}"
  },
  {
    "path": "frontend/settings/Skyrim/Bash.All.json",
    "content": "{\"records\":\"ACTI,ALCH,AMMO,APPA,ARMA,ARMO,ARTO,ASPC,AVIF,BOOK,CELL,CLAS,CONT,DEBR,DIAL,DOOR,EFSH,ENCH,EXPL,FACT,FLOR,FURN,GRAS,HAZD,HDPT,INFO,INGR,IPCT,KEYM,LCTN,LIGH,LSCR,LVLI,LVLN,LVSP,MESG,MGEF,MISC,MSTT,NPC_,PACK,PERK,PHZD,PROJ,QUST,RACE,REFR,REVB,SCEN,SCRL,SHOU,SLGM,SNCT,SNDR,SOPM,SOUN,SPEL,STAT,TREE,WATR,WEAP,WRLD,WTHR,ACHR\",\"description\":\"Combined setting:\\r\\nBash.Actors.ACBS,Bash.Actors.AIData,Bash.Actors.AIPackages,Bash.Actors.AIPackagesMerge,Bash.Actors.CombatStyle,Bash.Actors.DeathItem,Bash.Actors.Spells,Bash.Actors.SpellsMerge,Bash.Actors.Stats,Bash.Body-F,Bash.Body-M,Bash.Body-Size-F,Bash.Body-Size-M,Bash.C.Climate,Bash.C.Light,Bash.C.Music,Bash.C.Name,Bash.C.Owner,Bash.C.RecordFlags,Bash.C.Water,Bash.Delev,Bash.Eyes,Bash.Factions,Bash.Graphics,Bash.Hairs,Bash.Invent,Bash.Names,Bash.NPC.Class,Bash.NPC.Race,Bash.NpcFaces,Bash.NpcFacesForceFullImport,Bash.R.AddSpells,Bash.R.ChangeSpells,Bash.R.Description,Bash.R.Head,Bash.R.Skills,Bash.Relations,Bash.Relev,Bash.Scripts,Bash.Sound,Bash.SpellStats,Bash.Stats,Bash.Voice-F,Bash.Voice-M\",\"tree\":{\"records\":[{\"t\":1,\"p\":1,\"n\":\"ACTI - Activator\",\"c\":[{\"t\":6,\"n\":\"Record Header\",\"c\":[{\"t\":2,\"n\":\"Signature\"},{\"t\":3,\"n\":\"Data Size\"},{\"t\":3,\"n\":\"Record Flags\"},{\"t\":3,\"n\":\"FormID\"},{\"t\":11,\"n\":\"Version Control Info 1\"},{\"t\":3,\"n\":\"Form Version\"},{\"t\":11,\"n\":\"Version Control Info 2\"}]},{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"VMAD - Virtual Machine Adapter\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Version\"},{\"t\":3,\"p\":1,\"n\":\"Object Format\"},{\"t\":12,\"p\":1,\"n\":\"Data\",\"c\":[{\"t\":9,\"p\":1,\"n\":\"Scripts\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Script\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"scriptName\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":9,\"p\":1,\"n\":\"Properties\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Property\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"propertyName\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":12,\"p\":1,\"n\":\"Value\"}]}]}]}]}]}]},{\"t\":6,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"n\":\"X1\"},{\"t\":3,\"n\":\"Y1\"},{\"t\":3,\"n\":\"Z1\"},{\"t\":3,\"n\":\"X2\"},{\"t\":3,\"n\":\"Y2\"},{\"t\":3,\"n\":\"Z2\"}]},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"}]},{\"t\":6,\"n\":\"Destructable\",\"c\":[{\"t\":6,\"n\":\"DEST - Header\",\"c\":[{\"t\":3,\"n\":\"Health\"},{\"t\":3,\"n\":\"DEST Count\"},{\"t\":3,\"n\":\"VATS Targetable\"},{\"t\":11,\"n\":\"Unknown\"}]}]},{\"t\":3,\"n\":\"KSIZ - Keyword Count\"},{\"t\":9,\"n\":\"KWDA - Keywords\",\"c\":[{\"t\":3,\"n\":\"Keyword\"}]},{\"t\":6,\"n\":\"PNAM - Marker Color\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":3,\"n\":\"Unused\"}]},{\"t\":3,\"p\":1,\"n\":\"SNAM - Sound - Looping\"},{\"t\":3,\"p\":1,\"n\":\"VNAM - Sound - Activation\"},{\"t\":3,\"n\":\"WNAM - Water Type\"},{\"t\":2,\"n\":\"RNAM - Activate Text Override\"},{\"t\":3,\"n\":\"FNAM - Flags\"},{\"t\":3,\"n\":\"KNAM - Interaction Keyword\"}]},{\"t\":1,\"p\":1,\"n\":\"ALCH - Ingestible\",\"c\":[{\"t\":6,\"n\":\"Record Header\",\"c\":[{\"t\":2,\"n\":\"Signature\"},{\"t\":3,\"n\":\"Data Size\"},{\"t\":3,\"n\":\"Record Flags\"},{\"t\":3,\"n\":\"FormID\"},{\"t\":11,\"n\":\"Version Control Info 1\"},{\"t\":3,\"n\":\"Form Version\"},{\"t\":11,\"n\":\"Version Control Info 2\"}]},{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"n\":\"X1\"},{\"t\":3,\"n\":\"Y1\"},{\"t\":3,\"n\":\"Z1\"},{\"t\":3,\"n\":\"X2\"},{\"t\":3,\"n\":\"Y2\"},{\"t\":3,\"n\":\"Z2\"}]},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":3,\"n\":\"KSIZ - Keyword Count\"},{\"t\":9,\"n\":\"KWDA - Keywords\",\"c\":[{\"t\":3,\"n\":\"Keyword\"}]},{\"t\":2,\"n\":\"DESC - Description\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"}]},{\"t\":6,\"n\":\"Destructable\",\"c\":[{\"t\":6,\"n\":\"DEST - Header\",\"c\":[{\"t\":3,\"n\":\"Health\"},{\"t\":3,\"n\":\"DEST Count\"},{\"t\":3,\"n\":\"VATS Targetable\"},{\"t\":11,\"n\":\"Unknown\"}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Icon\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"ICON - Large Icon filename\"}]},{\"t\":3,\"n\":\"YNAM - Sound - Pick Up\"},{\"t\":3,\"n\":\"ZNAM - Sound - Drop\"},{\"t\":3,\"n\":\"ETYP - Equipment Type\"},{\"t\":5,\"p\":1,\"n\":\"DATA - Weight\"},{\"t\":6,\"n\":\"ENIT - Effect Data\",\"c\":[{\"t\":3,\"n\":\"Value\"},{\"t\":3,\"n\":\"Flags\"},{\"t\":3,\"n\":\"Addiction\"},{\"t\":5,\"n\":\"Addiction Chance\"},{\"t\":3,\"n\":\"Sound - Consume\"}]},{\"t\":8,\"n\":\"Effects\",\"c\":[{\"t\":6,\"n\":\"Effect\",\"c\":[{\"t\":3,\"n\":\"EFID - Base Effect\"},{\"t\":6,\"n\":\"EFIT - \",\"c\":[{\"t\":5,\"n\":\"Magnitude\"},{\"t\":3,\"n\":\"Area\"},{\"t\":3,\"n\":\"Duration\"}]}]}]}]},{\"t\":1,\"p\":1,\"n\":\"AMMO - Ammunition\",\"c\":[{\"t\":6,\"n\":\"Record Header\",\"c\":[{\"t\":2,\"n\":\"Signature\"},{\"t\":3,\"n\":\"Data Size\"},{\"t\":3,\"n\":\"Record Flags\"},{\"t\":3,\"n\":\"FormID\"},{\"t\":11,\"n\":\"Version Control Info 1\"},{\"t\":3,\"n\":\"Form Version\"},{\"t\":11,\"n\":\"Version Control Info 2\"}]},{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"n\":\"X1\"},{\"t\":3,\"n\":\"Y1\"},{\"t\":3,\"n\":\"Z1\"},{\"t\":3,\"n\":\"X2\"},{\"t\":3,\"n\":\"Y2\"},{\"t\":3,\"n\":\"Z2\"}]},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Icon\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"ICON - Large Icon filename\"}]},{\"t\":6,\"n\":\"Destructable\",\"c\":[{\"t\":6,\"n\":\"DEST - Header\",\"c\":[{\"t\":3,\"n\":\"Health\"},{\"t\":3,\"n\":\"DEST Count\"},{\"t\":3,\"n\":\"VATS Targetable\"},{\"t\":11,\"n\":\"Unknown\"}]}]},{\"t\":3,\"n\":\"YNAM - Sound - Pick Up\"},{\"t\":3,\"n\":\"ZNAM - Sound - Drop\"},{\"t\":2,\"n\":\"DESC - Description\"},{\"t\":3,\"n\":\"KSIZ - Keyword Count\"},{\"t\":9,\"n\":\"KWDA - Keywords\",\"c\":[{\"t\":3,\"n\":\"Keyword\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DATA - Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Projectile\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":5,\"p\":1,\"n\":\"Damage\"},{\"t\":3,\"p\":1,\"n\":\"Value\"}]},{\"t\":2,\"n\":\"ONAM - Short Name\"}]},{\"t\":1,\"p\":1,\"n\":\"APPA - Alchemical Apparatus\",\"c\":[{\"t\":6,\"n\":\"Record Header\",\"c\":[{\"t\":2,\"n\":\"Signature\"},{\"t\":3,\"n\":\"Data Size\"},{\"t\":3,\"n\":\"Record Flags\"},{\"t\":3,\"n\":\"FormID\"},{\"t\":11,\"n\":\"Version Control Info 1\"},{\"t\":3,\"n\":\"Form Version\"},{\"t\":11,\"n\":\"Version Control Info 2\"}]},{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"n\":\"VMAD - Virtual Machine Adapter\",\"c\":[{\"t\":3,\"n\":\"Version\"},{\"t\":3,\"n\":\"Object Format\"},{\"t\":12,\"n\":\"Data\",\"c\":[{\"t\":9,\"n\":\"Scripts\",\"c\":[{\"t\":6,\"n\":\"Script\",\"c\":[{\"t\":2,\"n\":\"scriptName\"},{\"t\":3,\"n\":\"Flags\"},{\"t\":9,\"n\":\"Properties\",\"c\":[{\"t\":6,\"n\":\"Property\",\"c\":[{\"t\":2,\"n\":\"propertyName\"},{\"t\":3,\"n\":\"Type\"},{\"t\":3,\"n\":\"Flags\"},{\"t\":12,\"n\":\"Value\"}]}]}]}]}]}]},{\"t\":6,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"n\":\"X1\"},{\"t\":3,\"n\":\"Y1\"},{\"t\":3,\"n\":\"Z1\"},{\"t\":3,\"n\":\"X2\"},{\"t\":3,\"n\":\"Y2\"},{\"t\":3,\"n\":\"Z2\"}]},{\"t\":2,\"n\":\"FULL - Name\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Icon\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"ICON - Large Icon filename\"}]},{\"t\":6,\"n\":\"Destructable\",\"c\":[{\"t\":6,\"n\":\"DEST - Header\",\"c\":[{\"t\":3,\"n\":\"Health\"},{\"t\":3,\"n\":\"DEST Count\"},{\"t\":3,\"n\":\"VATS Targetable\"},{\"t\":11,\"n\":\"Unknown\"}]}]},{\"t\":3,\"n\":\"YNAM - Sound - Pick Up\"},{\"t\":3,\"n\":\"ZNAM - Sound - Drop\"},{\"t\":3,\"n\":\"QUAL - Quality\"},{\"t\":2,\"n\":\"DESC - Description\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DATA - Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Value\"},{\"t\":5,\"p\":1,\"n\":\"Weight\"}]}]},{\"t\":1,\"p\":1,\"n\":\"ARMA - Armor Addon\",\"c\":[{\"t\":6,\"n\":\"Record Header\",\"c\":[{\"t\":2,\"n\":\"Signature\"},{\"t\":3,\"n\":\"Data Size\"},{\"t\":3,\"n\":\"Record Flags\"},{\"t\":3,\"n\":\"FormID\"},{\"t\":11,\"n\":\"Version Control Info 1\"},{\"t\":3,\"n\":\"Form Version\"},{\"t\":11,\"n\":\"Version Control Info 2\"}]},{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"n\":\"BOD2 - Biped Body Template\",\"c\":[{\"t\":3,\"n\":\"First Person Flags\"},{\"t\":3,\"n\":\"General Flags\"},{\"n\":\"Unused\"},{\"t\":3,\"n\":\"Armor Type\"}]},{\"t\":3,\"n\":\"RNAM - Race\"},{\"t\":6,\"n\":\"DNAM - Data\",\"c\":[{\"t\":3,\"n\":\"Male Priority\"},{\"t\":3,\"n\":\"Female Priority\"},{\"t\":3,\"n\":\"Weight slider - Male\"},{\"t\":3,\"n\":\"Weight slider - Female\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":3,\"n\":\"Detection Sound Value\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":5,\"n\":\"Weapon Adjust\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Male world model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MOD2 - Model Filename\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Female world model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MOD3 - Model Filename\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Male 1st Person\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MOD4 - Model Filename\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Female 1st Person\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MOD5 - Model Filename\"}]},{\"t\":3,\"n\":\"NAM0 - Male Skin Texture\"},{\"t\":3,\"n\":\"NAM1 - Female Skin texture\"},{\"t\":3,\"n\":\"NAM2 - Male Skin Texture Swap List\"},{\"t\":3,\"n\":\"NAM3 - Female Skin Texture Swap List\"},{\"t\":9,\"n\":\"Additional Races\",\"c\":[{\"t\":3,\"n\":\"MODL - Race\"}]},{\"t\":3,\"p\":1,\"n\":\"SNDD - Footstep Sound\"},{\"t\":3,\"n\":\"ONAM - Art Object\"}]},{\"t\":1,\"p\":1,\"n\":\"ARMO - Armor\",\"c\":[{\"t\":6,\"n\":\"Record Header\",\"c\":[{\"t\":2,\"n\":\"Signature\"},{\"t\":3,\"n\":\"Data Size\"},{\"t\":3,\"n\":\"Record Flags\"},{\"t\":3,\"n\":\"FormID\"},{\"t\":11,\"n\":\"Version Control Info 1\"},{\"t\":3,\"n\":\"Form Version\"},{\"t\":11,\"n\":\"Version Control Info 2\"}]},{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"VMAD - Virtual Machine Adapter\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Version\"},{\"t\":3,\"p\":1,\"n\":\"Object Format\"},{\"t\":12,\"p\":1,\"n\":\"Data\",\"c\":[{\"t\":9,\"p\":1,\"n\":\"Scripts\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Script\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"scriptName\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":9,\"p\":1,\"n\":\"Properties\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Property\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"propertyName\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":12,\"p\":1,\"n\":\"Value\"}]}]}]}]}]}]},{\"t\":6,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"n\":\"X1\"},{\"t\":3,\"n\":\"Y1\"},{\"t\":3,\"n\":\"Z1\"},{\"t\":3,\"n\":\"X2\"},{\"t\":3,\"n\":\"Y2\"},{\"t\":3,\"n\":\"Z2\"}]},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":3,\"n\":\"EITM - Object Effect\"},{\"t\":3,\"n\":\"EAMT - Enchantment Amount\"},{\"t\":6,\"n\":\"Male world model\",\"c\":[{\"t\":2,\"n\":\"MOD2 - Model Filename\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Icon\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"ICON - Large Icon filename\"}]},{\"t\":6,\"n\":\"Female world model\",\"c\":[{\"t\":2,\"n\":\"MOD4 - Model Filename\"}]},{\"t\":6,\"n\":\"Icon 2 (female)\",\"c\":[{\"t\":2,\"n\":\"ICO2 - Large Icon filename\"}]},{\"t\":6,\"n\":\"BOD2 - Biped Body Template\",\"c\":[{\"t\":3,\"n\":\"First Person Flags\"},{\"t\":3,\"n\":\"General Flags\"},{\"n\":\"Unused\"},{\"t\":3,\"n\":\"Armor Type\"}]},{\"t\":6,\"n\":\"Destructable\",\"c\":[{\"t\":6,\"n\":\"DEST - Header\",\"c\":[{\"t\":3,\"n\":\"Health\"},{\"t\":3,\"n\":\"DEST Count\"},{\"t\":3,\"n\":\"VATS Targetable\"},{\"t\":11,\"n\":\"Unknown\"}]}]},{\"t\":3,\"n\":\"YNAM - Sound - Pick Up\"},{\"t\":3,\"n\":\"ZNAM - Sound - Drop\"},{\"t\":2,\"n\":\"BMCT - Ragdoll Constraint Template\"},{\"t\":3,\"n\":\"ETYP - Equipment Type\"},{\"t\":3,\"n\":\"BIDS - Bash Impact Data Set\"},{\"t\":3,\"n\":\"BAMT - Alternate Block Material\"},{\"t\":3,\"n\":\"RNAM - Race\"},{\"t\":3,\"n\":\"KSIZ - Keyword Count\"},{\"t\":9,\"n\":\"KWDA - Keywords\",\"c\":[{\"t\":3,\"n\":\"Keyword\"}]},{\"t\":2,\"n\":\"DESC - Description\"},{\"t\":7,\"p\":1,\"n\":\"Armature\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"MODL - Model Filename\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DATA - Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Value\"},{\"t\":5,\"p\":1,\"n\":\"Weight\"}]},{\"t\":3,\"n\":\"DNAM - Armor Rating\"},{\"t\":3,\"n\":\"TNAM - Template Armor\"}]},{\"t\":1,\"p\":1,\"n\":\"ARTO - Art Object\",\"c\":[{\"t\":6,\"n\":\"Record Header\",\"c\":[{\"t\":2,\"n\":\"Signature\"},{\"t\":3,\"n\":\"Data Size\"},{\"t\":3,\"n\":\"Record Flags\"},{\"t\":3,\"n\":\"FormID\"},{\"t\":11,\"n\":\"Version Control Info 1\"},{\"t\":3,\"n\":\"Form Version\"},{\"t\":11,\"n\":\"Version Control Info 2\"}]},{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"n\":\"X1\"},{\"t\":3,\"n\":\"Y1\"},{\"t\":3,\"n\":\"Z1\"},{\"t\":3,\"n\":\"X2\"},{\"t\":3,\"n\":\"Y2\"},{\"t\":3,\"n\":\"Z2\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"}]},{\"t\":3,\"n\":\"DNAM - Art Type\"}]},{\"t\":1,\"p\":1,\"n\":\"ASPC - Acoustic Space\",\"c\":[{\"t\":6,\"n\":\"Record Header\",\"c\":[{\"t\":2,\"n\":\"Signature\"},{\"t\":3,\"n\":\"Data Size\"},{\"t\":3,\"n\":\"Record Flags\"},{\"t\":3,\"n\":\"FormID\"},{\"t\":11,\"n\":\"Version Control Info 1\"},{\"t\":3,\"n\":\"Form Version\"},{\"t\":11,\"n\":\"Version Control Info 2\"}]},{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"X1\"},{\"t\":3,\"p\":1,\"n\":\"Y1\"},{\"t\":3,\"p\":1,\"n\":\"Z1\"},{\"t\":3,\"p\":1,\"n\":\"X2\"},{\"t\":3,\"p\":1,\"n\":\"Y2\"},{\"t\":3,\"p\":1,\"n\":\"Z2\"}],\"lt\":\"BNAM - Environment Type (reverb)\",\"lf\":\"SNAM - Ambient Sound\"},{\"t\":3,\"p\":1,\"n\":\"SNAM - Ambient Sound\",\"lt\":\"OBND - Object Bounds\",\"lf\":\"RDAT - Use Sound from Region (Interiors Only)\"},{\"t\":3,\"p\":1,\"n\":\"RDAT - Use Sound from Region (Interiors Only)\",\"lt\":\"SNAM - Ambient Sound\",\"lf\":\"BNAM - Environment Type (reverb)\"},{\"t\":3,\"p\":1,\"n\":\"BNAM - Environment Type (reverb)\",\"lt\":\"RDAT - Use Sound from Region (Interiors Only)\",\"lf\":\"OBND - Object Bounds\"}]},{\"t\":1,\"p\":1,\"n\":\"AVIF - Actor Value Information\",\"c\":[{\"t\":6,\"n\":\"Record Header\",\"c\":[{\"t\":2,\"n\":\"Signature\"},{\"t\":3,\"n\":\"Data Size\"},{\"t\":3,\"n\":\"Record Flags\"},{\"t\":3,\"n\":\"FormID\"},{\"t\":11,\"n\":\"Version Control Info 1\"},{\"t\":3,\"n\":\"Form Version\"},{\"t\":11,\"n\":\"Version Control Info 2\"}]},{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":2,\"n\":\"DESC - Description\"},{\"t\":2,\"n\":\"ANAM - Abbreviation\"},{\"t\":11,\"n\":\"CNAM - Unknown\"},{\"t\":6,\"n\":\"AVSK - Skill\",\"c\":[{\"t\":5,\"n\":\"Skill Use Mult\"},{\"t\":5,\"n\":\"Skill Offset Mult\"},{\"t\":5,\"n\":\"Skill Improve Mult\"},{\"t\":5,\"n\":\"Skill Improve Offset\"}]},{\"t\":8,\"n\":\"Perk Tree\",\"c\":[{\"t\":6,\"n\":\"Node\",\"c\":[{\"t\":3,\"n\":\"PNAM - Perk\"}]}]}]},{\"t\":1,\"p\":1,\"n\":\"BOOK - Book\",\"c\":[{\"t\":6,\"n\":\"Record Header\",\"c\":[{\"t\":2,\"n\":\"Signature\"},{\"t\":3,\"n\":\"Data Size\"},{\"t\":3,\"n\":\"Record Flags\"},{\"t\":3,\"n\":\"FormID\"},{\"t\":11,\"n\":\"Version Control Info 1\"},{\"t\":3,\"n\":\"Form Version\"},{\"t\":11,\"n\":\"Version Control Info 2\"}]},{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"VMAD - Virtual Machine Adapter\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Version\"},{\"t\":3,\"p\":1,\"n\":\"Object Format\"},{\"t\":12,\"p\":1,\"n\":\"Data\",\"c\":[{\"t\":9,\"p\":1,\"n\":\"Scripts\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Script\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"scriptName\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":9,\"p\":1,\"n\":\"Properties\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Property\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"propertyName\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":12,\"p\":1,\"n\":\"Value\"}]}]}]}]}]}]},{\"t\":6,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"n\":\"X1\"},{\"t\":3,\"n\":\"Y1\"},{\"t\":3,\"n\":\"Z1\"},{\"t\":3,\"n\":\"X2\"},{\"t\":3,\"n\":\"Y2\"},{\"t\":3,\"n\":\"Z2\"}]},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Icon\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"ICON - Large Icon filename\"}]},{\"t\":2,\"n\":\"DESC - Book Text\"},{\"t\":6,\"n\":\"Destructable\",\"c\":[{\"t\":6,\"n\":\"DEST - Header\",\"c\":[{\"t\":3,\"n\":\"Health\"},{\"t\":3,\"n\":\"DEST Count\"},{\"t\":3,\"n\":\"VATS Targetable\"},{\"t\":11,\"n\":\"Unknown\"}]}]},{\"t\":3,\"n\":\"YNAM - Sound - Pick Up\"},{\"t\":3,\"n\":\"ZNAM - Sound - Drop\"},{\"t\":3,\"n\":\"KSIZ - Keyword Count\"},{\"t\":9,\"n\":\"KWDA - Keywords\",\"c\":[{\"t\":3,\"n\":\"Keyword\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DATA - Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":11,\"p\":1,\"n\":\"Unused\"},{\"t\":12,\"p\":1,\"n\":\"Teaches\"},{\"t\":3,\"p\":1,\"n\":\"Value\"},{\"t\":5,\"p\":1,\"n\":\"Weight\"}]},{\"t\":3,\"n\":\"INAM - Inventory Art\"},{\"t\":2,\"n\":\"CNAM - Description\"}]},{\"t\":1,\"p\":1,\"n\":\"CELL - Cell\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Record Header\",\"c\":[{\"t\":2,\"n\":\"Signature\"},{\"t\":3,\"n\":\"Data Size\"},{\"t\":3,\"p\":1,\"n\":\"Record Flags\"},{\"t\":3,\"n\":\"FormID\"},{\"t\":11,\"n\":\"Version Control Info 1\"},{\"t\":3,\"n\":\"Form Version\"},{\"t\":11,\"n\":\"Version Control Info 2\"}]},{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":3,\"n\":\"DATA - Flags\",\"c\":[{\"t\":4,\"n\":\"Is Interior Cell\"}]},{\"t\":6,\"n\":\"XCLC - Grid\",\"c\":[{\"t\":3,\"n\":\"X\"},{\"t\":3,\"n\":\"Y\"},{\"t\":3,\"n\":\"Force Hide Land\"}]},{\"t\":6,\"p\":1,\"n\":\"XCLL - Lighting\",\"c\":[{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Ambient Color\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"p\":1,\"n\":\"Unknown\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Directional Color\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"p\":1,\"n\":\"Unknown\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Fog Color Near\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"p\":1,\"n\":\"Unknown\"}]},{\"t\":5,\"n\":\"Fog Near\"},{\"t\":5,\"n\":\"Fog Far\"},{\"t\":3,\"n\":\"Directional Rotation XY\"},{\"t\":3,\"n\":\"Directional Rotation Z\"},{\"t\":5,\"n\":\"Directional Fade\"},{\"t\":5,\"n\":\"Fog Clip Distance\"},{\"t\":5,\"n\":\"Fog Power\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Ambient Colors\",\"c\":[{\"t\":8,\"p\":1,\"n\":\"Colors\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Color #0 (X+)\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"p\":1,\"n\":\"Unknown\"}]},{\"t\":6,\"p\":1,\"n\":\"Color #1 (X-)\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"p\":1,\"n\":\"Unknown\"}]},{\"t\":6,\"p\":1,\"n\":\"Color #2 (Y+)\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"p\":1,\"n\":\"Unknown\"}]},{\"t\":6,\"p\":1,\"n\":\"Color #3 (Y-)\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"p\":1,\"n\":\"Unknown\"}]},{\"t\":6,\"p\":1,\"n\":\"Color #4 (Z+)\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"p\":1,\"n\":\"Unknown\"}]},{\"t\":6,\"p\":1,\"n\":\"Color #5 (Z-)\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"p\":1,\"n\":\"Unknown\"}]}]},{\"t\":6,\"p\":1,\"n\":\"Specular\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Color\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"p\":1,\"n\":\"Unknown\"}]},{\"t\":5,\"p\":1,\"n\":\"Fresnel Power\"}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Fog Color Far\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"p\":1,\"n\":\"Unknown\"}]},{\"t\":5,\"n\":\"Fog Max\"},{\"t\":5,\"n\":\"Light Fade Begin\"},{\"t\":5,\"n\":\"Light Fade End\"},{\"t\":3,\"n\":\"Inherits\"}]},{\"t\":11,\"n\":\"TVDT - Unknown\"},{\"t\":11,\"n\":\"MHDT - Max Height Data\"},{\"t\":3,\"n\":\"LTMP - Lighting Template\"},{\"t\":11,\"n\":\"LNAM - Unknown\"},{\"t\":5,\"p\":1,\"n\":\"XCLW - Water Height\"},{\"t\":2,\"n\":\"XNAM - Water Noise Texture\"},{\"t\":9,\"n\":\"XCLR - Regions\",\"c\":[{\"t\":3,\"n\":\"Region\"}]},{\"t\":3,\"n\":\"XLCN - Location\"},{\"t\":11,\"n\":\"XWCN - Unknown\"},{\"t\":11,\"n\":\"XWCS - Unknown\"},{\"t\":6,\"n\":\"XWCU - Water Velocity\",\"c\":[{\"t\":5,\"n\":\"X Offset\"},{\"t\":5,\"n\":\"Y Offset\"},{\"t\":5,\"n\":\"Z Offset\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":5,\"n\":\"X Angle\"},{\"t\":5,\"n\":\"Y Angle\"},{\"t\":5,\"n\":\"Z Angle\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":3,\"p\":1,\"n\":\"XCWT - Water\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Ownership\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"XOWN - Owner\"}]},{\"t\":3,\"n\":\"XILL - Lock List\"},{\"t\":2,\"n\":\"XWEM - Water Environment Map\"},{\"t\":3,\"p\":1,\"n\":\"XCCM - Sky\\/Weather from Region\"},{\"t\":3,\"n\":\"XCAS - Acoustic Space\"},{\"t\":3,\"n\":\"XEZN - Encounter Zone\"},{\"t\":3,\"p\":1,\"n\":\"XCMO - Music Type\"},{\"t\":3,\"n\":\"XCIM - Image Space\"}]},{\"t\":1,\"p\":1,\"n\":\"CLAS - Class\",\"c\":[{\"t\":6,\"n\":\"Record Header\",\"c\":[{\"t\":2,\"n\":\"Signature\"},{\"t\":3,\"n\":\"Data Size\"},{\"t\":3,\"n\":\"Record Flags\"},{\"t\":3,\"n\":\"FormID\"},{\"t\":11,\"n\":\"Version Control Info 1\"},{\"t\":3,\"n\":\"Form Version\"},{\"t\":11,\"n\":\"Version Control Info 2\"}]},{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":2,\"n\":\"DESC - Description\"},{\"t\":6,\"n\":\"Icon\",\"c\":[{\"t\":2,\"n\":\"ICON - Large Icon filename\"}]},{\"t\":6,\"n\":\"DATA - \",\"c\":[{\"t\":11,\"n\":\"Unknown\"},{\"t\":3,\"n\":\"Teaches\"},{\"t\":3,\"n\":\"Maximum training level\"},{\"t\":7,\"n\":\"Skill Weights\",\"c\":[{\"t\":3,\"n\":\"Weight #0 (One Handed)\"},{\"t\":3,\"n\":\"Weight #1 (Two Handed)\"},{\"t\":3,\"n\":\"Weight #2 (Archery)\"},{\"t\":3,\"n\":\"Weight #3 (Block)\"},{\"t\":3,\"n\":\"Weight #4 (Smithing)\"},{\"t\":3,\"n\":\"Weight #5 (Heavy Armor)\"},{\"t\":3,\"n\":\"Weight #6 (Light Armor)\"},{\"t\":3,\"n\":\"Weight #7 (Pickpocket)\"},{\"t\":3,\"n\":\"Weight #8 (Lockpicking)\"},{\"t\":3,\"n\":\"Weight #9 (Sneak)\"},{\"t\":3,\"n\":\"Weight #10 (Alchemy)\"},{\"t\":3,\"n\":\"Weight #11 (Speech)\"},{\"t\":3,\"n\":\"Weight #12 (Alteration)\"},{\"t\":3,\"n\":\"Weight #13 (Conjuration)\"},{\"t\":3,\"n\":\"Weight #14 (Destruction)\"},{\"t\":3,\"n\":\"Weight #15 (Illusion)\"},{\"t\":3,\"n\":\"Weight #16 (Restoration)\"},{\"t\":3,\"n\":\"Weight #17 (Enchanting)\"}]},{\"t\":5,\"n\":\"Bleedout Default\"},{\"t\":3,\"n\":\"Voice Points\"},{\"t\":7,\"n\":\"Attribute Weights\",\"c\":[{\"t\":3,\"n\":\"Weight #0 (Health)\"},{\"t\":3,\"n\":\"Weight #1 (Magicka)\"},{\"t\":3,\"n\":\"Weight #2 (Stamina)\"},{\"t\":3,\"n\":\"Weight #3 (Unknown)\"}]}]}]},{\"t\":1,\"p\":1,\"n\":\"CONT - Container\",\"c\":[{\"t\":6,\"n\":\"Record Header\",\"c\":[{\"t\":2,\"n\":\"Signature\"},{\"t\":3,\"n\":\"Data Size\"},{\"t\":3,\"n\":\"Record Flags\"},{\"t\":3,\"n\":\"FormID\"},{\"t\":11,\"n\":\"Version Control Info 1\"},{\"t\":3,\"n\":\"Form Version\"},{\"t\":11,\"n\":\"Version Control Info 2\"}]},{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"VMAD - Virtual Machine Adapter\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Version\"},{\"t\":3,\"p\":1,\"n\":\"Object Format\"},{\"t\":12,\"p\":1,\"n\":\"Data\",\"c\":[{\"t\":9,\"p\":1,\"n\":\"Scripts\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Script\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"scriptName\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":9,\"p\":1,\"n\":\"Properties\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Property\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"propertyName\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":12,\"p\":1,\"n\":\"Value\"}]}]}]}]}]}]},{\"t\":6,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"n\":\"X1\"},{\"t\":3,\"n\":\"Y1\"},{\"t\":3,\"n\":\"Z1\"},{\"t\":3,\"n\":\"X2\"},{\"t\":3,\"n\":\"Y2\"},{\"t\":3,\"n\":\"Z2\"}]},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":6,\"n\":\"Model\",\"c\":[{\"t\":2,\"n\":\"MODL - Model Filename\"}]},{\"t\":3,\"n\":\"COCT - Count\"},{\"t\":10,\"p\":1,\"n\":\"Items\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Item\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"CNTO - Item\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Item\"},{\"t\":3,\"p\":1,\"n\":\"Count\"}]}]}]},{\"t\":6,\"n\":\"Destructable\",\"c\":[{\"t\":6,\"n\":\"DEST - Header\",\"c\":[{\"t\":3,\"n\":\"Health\"},{\"t\":3,\"n\":\"DEST Count\"},{\"t\":3,\"n\":\"VATS Targetable\"},{\"t\":11,\"n\":\"Unknown\"}]}]},{\"t\":6,\"n\":\"DATA - \",\"c\":[{\"t\":3,\"n\":\"Flags\"},{\"t\":5,\"n\":\"Weight\"}]},{\"t\":3,\"n\":\"SNAM - Sound - Open\"},{\"t\":3,\"n\":\"QNAM - Sound - Close\"}]},{\"t\":1,\"p\":1,\"n\":\"DEBR - Debris\",\"c\":[{\"t\":6,\"n\":\"Record Header\",\"c\":[{\"t\":2,\"n\":\"Signature\"},{\"t\":3,\"n\":\"Data Size\"},{\"t\":3,\"n\":\"Record Flags\"},{\"t\":3,\"n\":\"FormID\"},{\"t\":11,\"n\":\"Version Control Info 1\"},{\"t\":3,\"n\":\"Form Version\"},{\"t\":11,\"n\":\"Version Control Info 2\"}]},{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":8,\"p\":1,\"n\":\"Models\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"DATA - Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Percentage\"},{\"t\":2,\"p\":1,\"n\":\"Model Filename\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"}]}]}]}]},{\"t\":1,\"p\":1,\"n\":\"DIAL - Dialog Topic\",\"c\":[{\"t\":6,\"n\":\"Record Header\",\"c\":[{\"t\":2,\"n\":\"Signature\"},{\"t\":3,\"n\":\"Data Size\"},{\"t\":3,\"n\":\"Record Flags\"},{\"t\":3,\"n\":\"FormID\"},{\"t\":11,\"n\":\"Version Control Info 1\"},{\"t\":3,\"n\":\"Form Version\"},{\"t\":11,\"n\":\"Version Control Info 2\"}]},{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":5,\"n\":\"PNAM - Priority\"},{\"t\":3,\"n\":\"BNAM - Branch\"},{\"t\":3,\"n\":\"QNAM - Quest\"},{\"t\":6,\"n\":\"DATA - Data\",\"c\":[{\"t\":3,\"n\":\"Topic Flags\"},{\"t\":3,\"n\":\"Category\"},{\"t\":3,\"n\":\"Subtype\"}]},{\"t\":2,\"n\":\"SNAM - Subtype Name\"},{\"t\":3,\"n\":\"TIFC - Info Count\"}]},{\"t\":1,\"p\":1,\"n\":\"DOOR - Door\",\"c\":[{\"t\":6,\"n\":\"Record Header\",\"c\":[{\"t\":2,\"n\":\"Signature\"},{\"t\":3,\"n\":\"Data Size\"},{\"t\":3,\"n\":\"Record Flags\"},{\"t\":3,\"n\":\"FormID\"},{\"t\":11,\"n\":\"Version Control Info 1\"},{\"t\":3,\"n\":\"Form Version\"},{\"t\":11,\"n\":\"Version Control Info 2\"}]},{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"VMAD - Virtual Machine Adapter\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Version\"},{\"t\":3,\"p\":1,\"n\":\"Object Format\"},{\"t\":12,\"p\":1,\"n\":\"Data\",\"c\":[{\"t\":9,\"p\":1,\"n\":\"Scripts\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Script\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"scriptName\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":9,\"p\":1,\"n\":\"Properties\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Property\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"propertyName\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":12,\"p\":1,\"n\":\"Value\"}]}]}]}]}]}]},{\"t\":6,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"n\":\"X1\"},{\"t\":3,\"n\":\"Y1\"},{\"t\":3,\"n\":\"Z1\"},{\"t\":3,\"n\":\"X2\"},{\"t\":3,\"n\":\"Y2\"},{\"t\":3,\"n\":\"Z2\"}]},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"}]},{\"t\":6,\"n\":\"Destructable\",\"c\":[{\"t\":6,\"n\":\"DEST - Header\",\"c\":[{\"t\":3,\"n\":\"Health\"},{\"t\":3,\"n\":\"DEST Count\"},{\"t\":3,\"n\":\"VATS Targetable\"},{\"t\":11,\"n\":\"Unknown\"}]}]},{\"t\":3,\"n\":\"SNAM - Sound - Open\"},{\"t\":3,\"n\":\"ANAM - Sound - Close\"},{\"t\":3,\"n\":\"BNAM - Sound - Loop\"},{\"t\":3,\"n\":\"FNAM - Flags\"}]},{\"t\":1,\"p\":1,\"n\":\"EFSH - Effect Shader\",\"c\":[{\"t\":6,\"n\":\"Record Header\",\"c\":[{\"t\":2,\"n\":\"Signature\"},{\"t\":3,\"n\":\"Data Size\"},{\"t\":3,\"n\":\"Record Flags\"},{\"t\":3,\"n\":\"FormID\"},{\"t\":11,\"n\":\"Version Control Info 1\"},{\"t\":3,\"n\":\"Form Version\"},{\"t\":11,\"n\":\"Version Control Info 2\"}]},{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"p\":1,\"n\":\"ICON - Fill Texture\",\"lt\":\"ICO2 - Particle Shader Texture\",\"lf\":\"DATA - \"},{\"t\":2,\"p\":1,\"n\":\"ICO2 - Particle Shader Texture\",\"lt\":\"NAM7 - Holes Texture\",\"lf\":\"ICON - Fill Texture\"},{\"t\":2,\"p\":1,\"n\":\"NAM7 - Holes Texture\",\"lt\":\"NAM8 - Membrane Palette Texture\",\"lf\":\"ICO2 - Particle Shader Texture\"},{\"t\":2,\"p\":1,\"n\":\"NAM8 - Membrane Palette Texture\",\"lt\":\"NAM9 - Particle Palette Texture\",\"lf\":\"NAM7 - Holes Texture\"},{\"t\":2,\"p\":1,\"n\":\"NAM9 - Particle Palette Texture\",\"lt\":\"DATA - \",\"lf\":\"NAM8 - Membrane Palette Texture\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DATA - \",\"c\":[{\"t\":11,\"p\":1,\"n\":\"Unknown\"},{\"t\":3,\"p\":1,\"n\":\"Membrane Shader - Source Blend Mode\"},{\"t\":3,\"p\":1,\"n\":\"Membrane Shader - Blend Operation\"},{\"t\":3,\"p\":1,\"n\":\"Membrane Shader - Z Test Function\"},{\"t\":6,\"p\":1,\"n\":\"Fill\\/Texture Effect - Color Key 1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"p\":1,\"n\":\"Unknown\"}]},{\"t\":5,\"p\":1,\"n\":\"Fill\\/Texture Effect - Alpha Fade In Time\"},{\"t\":5,\"p\":1,\"n\":\"Fill\\/Texture Effect - Full Alpha Time\"},{\"t\":5,\"p\":1,\"n\":\"Fill\\/Texture Effect - Alpha Fade Out Time\"},{\"t\":5,\"p\":1,\"n\":\"Fill\\/Texture Effect - Presistent Alpha Ratio\"},{\"t\":5,\"p\":1,\"n\":\"Fill\\/Texture Effect - Alpha Pulse Amplitude\"},{\"t\":5,\"p\":1,\"n\":\"Fill\\/Texture Effect - Alpha Pulse Frequency\"},{\"t\":5,\"p\":1,\"n\":\"Fill\\/Texture Effect - Texture Animation Speed (U)\"},{\"t\":5,\"p\":1,\"n\":\"Fill\\/Texture Effect - Texture Animation Speed (V)\"},{\"t\":5,\"p\":1,\"n\":\"Edge Effect - Fall Off\"},{\"t\":6,\"p\":1,\"n\":\"Edge Effect - Color\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"p\":1,\"n\":\"Unknown\"}]},{\"t\":5,\"p\":1,\"n\":\"Edge Effect - Alpha Fade In Time\"},{\"t\":5,\"p\":1,\"n\":\"Edge Effect - Full Alpha Time\"},{\"t\":5,\"p\":1,\"n\":\"Edge Effect - Alpha Fade Out Time\"},{\"t\":5,\"p\":1,\"n\":\"Edge Effect - Persistent Alpha Ratio\"},{\"t\":5,\"p\":1,\"n\":\"Edge Effect - Alpha Pulse Amplitude\"},{\"t\":5,\"p\":1,\"n\":\"Edge Effect - Alpha Pulse Frequency\"},{\"t\":5,\"p\":1,\"n\":\"Fill\\/Texture Effect - Full Alpha Ratio\"},{\"t\":5,\"p\":1,\"n\":\"Edge Effect - Full Alpha Ratio\"},{\"t\":3,\"p\":1,\"n\":\"Membrane Shader - Dest Blend Mode\"},{\"t\":3,\"p\":1,\"n\":\"Particle Shader - Source Blend Mode\"},{\"t\":3,\"p\":1,\"n\":\"Particle Shader - Blend Operation\"},{\"t\":3,\"p\":1,\"n\":\"Particle Shader - Z Test Function\"},{\"t\":3,\"p\":1,\"n\":\"Particle Shader - Dest Blend Mode\"},{\"t\":5,\"p\":1,\"n\":\"Particle Shader - Particle Birth Ramp Up Time\"},{\"t\":5,\"p\":1,\"n\":\"Particle Shader - Full Particle Birth Time\"},{\"t\":5,\"p\":1,\"n\":\"Particle Shader - Particle Birth Ramp Down Time\"},{\"t\":5,\"p\":1,\"n\":\"Particle Shader - Full Particle Birth Ratio\"},{\"t\":5,\"p\":1,\"n\":\"Particle Shader - Persistant Particle Count\"},{\"t\":5,\"p\":1,\"n\":\"Particle Shader - Particle Lifetime\"},{\"t\":5,\"p\":1,\"n\":\"Particle Shader - Particle Lifetime +\\/-\"},{\"t\":5,\"p\":1,\"n\":\"Particle Shader - Initial Speed Along Normal\"},{\"t\":5,\"p\":1,\"n\":\"Particle Shader - Acceleration Along Normal\"},{\"t\":5,\"p\":1,\"n\":\"Particle Shader - Initial Velocity #1\"},{\"t\":5,\"p\":1,\"n\":\"Particle Shader - Initial Velocity #2\"},{\"t\":5,\"p\":1,\"n\":\"Particle Shader - Initial Velocity #3\"},{\"t\":5,\"p\":1,\"n\":\"Particle Shader - Acceleration #1\"},{\"t\":5,\"p\":1,\"n\":\"Particle Shader - Acceleration #2\"},{\"t\":5,\"p\":1,\"n\":\"Particle Shader - Acceleration #3\"},{\"t\":5,\"p\":1,\"n\":\"Particle Shader - Scale Key 1\"},{\"t\":5,\"p\":1,\"n\":\"Particle Shader - Scale Key 2\"},{\"t\":5,\"p\":1,\"n\":\"Particle Shader - Scale Key 1 Time\"},{\"t\":5,\"p\":1,\"n\":\"Particle Shader - Scale Key 2 Time\"},{\"t\":6,\"p\":1,\"n\":\"Color Key 1 - Color\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"p\":1,\"n\":\"Unknown\"}]},{\"t\":6,\"p\":1,\"n\":\"Color Key 2 - Color\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"p\":1,\"n\":\"Unknown\"}]},{\"t\":6,\"p\":1,\"n\":\"Color Key 3 - Color\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"p\":1,\"n\":\"Unknown\"}]},{\"t\":5,\"p\":1,\"n\":\"Color Key 1 - Color Alpha\"},{\"t\":5,\"p\":1,\"n\":\"Color Key 2 - Color Alpha\"},{\"t\":5,\"p\":1,\"n\":\"Color Key 3 - Color Alpha\"},{\"t\":5,\"p\":1,\"n\":\"Color Key 1 - Color Key Time\"},{\"t\":5,\"p\":1,\"n\":\"Color Key 2 - Color Key Time\"},{\"t\":5,\"p\":1,\"n\":\"Color Key 3 - Color Key Time\"},{\"t\":5,\"p\":1,\"n\":\"Particle Shader - Initial Speed Along Normal +\\/-\"},{\"t\":5,\"p\":1,\"n\":\"Particle Shader - Initial Rotation (deg)\"},{\"t\":5,\"p\":1,\"n\":\"Particle Shader - Initial Rotation (deg) +\\/-\"},{\"t\":5,\"p\":1,\"n\":\"Particle Shader - Rotation Speed (deg\\/sec)\"},{\"t\":5,\"p\":1,\"n\":\"Particle Shader - Rotation Speed (deg\\/sec) +\\/-\"},{\"t\":3,\"p\":1,\"n\":\"Addon Models\"},{\"t\":5,\"p\":1,\"n\":\"Holes - Start Time\"},{\"t\":5,\"p\":1,\"n\":\"Holes - End Time\"},{\"t\":5,\"p\":1,\"n\":\"Holes - Start Val\"},{\"t\":5,\"p\":1,\"n\":\"Holes - End Val\"},{\"t\":5,\"p\":1,\"n\":\"Edge Width (alpha units)\"},{\"t\":6,\"p\":1,\"n\":\"Edge Color\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"p\":1,\"n\":\"Unknown\"}]},{\"t\":5,\"p\":1,\"n\":\"Explosion Wind Speed\"},{\"t\":3,\"p\":1,\"n\":\"Texture Count U\"},{\"t\":3,\"p\":1,\"n\":\"Texture Count V\"},{\"t\":5,\"p\":1,\"n\":\"Addon Models - Fade In Time\"},{\"t\":5,\"p\":1,\"n\":\"Addon Models - Fade Out Time\"},{\"t\":5,\"p\":1,\"n\":\"Addon Models - Scale Start\"},{\"t\":5,\"p\":1,\"n\":\"Addon Models - Scale End\"},{\"t\":5,\"p\":1,\"n\":\"Addon Models - Scale In Time\"},{\"t\":5,\"p\":1,\"n\":\"Addon Models - Scale Out Time\"},{\"t\":3,\"p\":1,\"n\":\"Ambient Sound\"},{\"t\":6,\"p\":1,\"n\":\"Fill\\/Texture Effect - Color Key 2\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"p\":1,\"n\":\"Unknown\"}]},{\"t\":6,\"p\":1,\"n\":\"Fill\\/Texture Effect - Color Key 3\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"p\":1,\"n\":\"Unknown\"}]},{\"t\":6,\"p\":1,\"n\":\"Fill\\/Texture Effect - Color Key Scale\\/Time\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Color Key 1 - Scale\"},{\"t\":5,\"p\":1,\"n\":\"Color Key 2 - Scale\"},{\"t\":5,\"p\":1,\"n\":\"Color Key 3 - Scale\"},{\"t\":5,\"p\":1,\"n\":\"Color Key 1 - Time\"},{\"t\":5,\"p\":1,\"n\":\"Color Key 2 - Time\"},{\"t\":5,\"p\":1,\"n\":\"Color Key 3 - Time\"}]},{\"t\":5,\"p\":1,\"n\":\"Color Scale\"},{\"t\":5,\"p\":1,\"n\":\"Birth Position Offset\"},{\"t\":5,\"p\":1,\"n\":\"Birth Position Offset Range +\\/-\"},{\"t\":6,\"p\":1,\"n\":\"Particle Shader Animated\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Start Frame\"},{\"t\":3,\"p\":1,\"n\":\"Start Frame Variation\"},{\"t\":3,\"p\":1,\"n\":\"End Frame\"},{\"t\":3,\"p\":1,\"n\":\"Loop Start Frame\"},{\"t\":3,\"p\":1,\"n\":\"Loop Start Variation\"},{\"t\":3,\"p\":1,\"n\":\"Frame Count\"},{\"t\":3,\"p\":1,\"n\":\"Frame Count Variation\"}]},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":5,\"p\":1,\"n\":\"Fill\\/Texture Effect - Texture Scale (U)\"},{\"t\":5,\"p\":1,\"n\":\"Fill\\/Texture Effect - Texture Scale (V)\"},{\"t\":3,\"p\":1,\"n\":\"Scene Graph Emit Depth Limit (unused)\"}],\"lt\":\"ICON - Fill Texture\",\"lf\":\"NAM9 - Particle Palette Texture\"}]},{\"t\":1,\"p\":1,\"n\":\"ENCH - Object Effect\",\"c\":[{\"t\":6,\"n\":\"Record Header\",\"c\":[{\"t\":2,\"n\":\"Signature\"},{\"t\":3,\"n\":\"Data Size\"},{\"t\":3,\"n\":\"Record Flags\"},{\"t\":3,\"n\":\"FormID\"},{\"t\":11,\"n\":\"Version Control Info 1\"},{\"t\":3,\"n\":\"Form Version\"},{\"t\":11,\"n\":\"Version Control Info 2\"}]},{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"n\":\"X1\"},{\"t\":3,\"n\":\"Y1\"},{\"t\":3,\"n\":\"Z1\"},{\"t\":3,\"n\":\"X2\"},{\"t\":3,\"n\":\"Y2\"},{\"t\":3,\"n\":\"Z2\"}]},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":6,\"n\":\"ENIT - Effect Data\",\"c\":[{\"t\":3,\"n\":\"Enchantment Cost\"},{\"t\":3,\"n\":\"Flags\"},{\"t\":3,\"n\":\"Cast Type\"},{\"t\":3,\"n\":\"Enchantment Amount\"},{\"t\":3,\"n\":\"Target Type\"},{\"t\":3,\"n\":\"Enchant Type\"},{\"t\":5,\"n\":\"Charge Time\"},{\"t\":3,\"n\":\"Base Enchantment\"},{\"t\":3,\"n\":\"Worn Restrictions\"}]},{\"t\":8,\"n\":\"Effects\",\"c\":[{\"t\":6,\"n\":\"Effect\",\"c\":[{\"t\":3,\"n\":\"EFID - Base Effect\"},{\"t\":6,\"n\":\"EFIT - \",\"c\":[{\"t\":5,\"n\":\"Magnitude\"},{\"t\":3,\"n\":\"Area\"},{\"t\":3,\"n\":\"Duration\"}]}]}]}]},{\"t\":1,\"p\":1,\"n\":\"EXPL - Explosion\",\"c\":[{\"t\":6,\"n\":\"Record Header\",\"c\":[{\"t\":2,\"n\":\"Signature\"},{\"t\":3,\"n\":\"Data Size\"},{\"t\":3,\"n\":\"Record Flags\"},{\"t\":3,\"n\":\"FormID\"},{\"t\":11,\"n\":\"Version Control Info 1\"},{\"t\":3,\"n\":\"Form Version\"},{\"t\":11,\"n\":\"Version Control Info 2\"}]},{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"n\":\"X1\"},{\"t\":3,\"n\":\"Y1\"},{\"t\":3,\"n\":\"Z1\"},{\"t\":3,\"n\":\"X2\"},{\"t\":3,\"n\":\"Y2\"},{\"t\":3,\"n\":\"Z2\"}]},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"}]},{\"t\":3,\"n\":\"EITM - Object Effect\"},{\"t\":3,\"n\":\"MNAM - Image Space Modifier\"},{\"t\":6,\"p\":1,\"n\":\"DATA - Data\",\"c\":[{\"t\":3,\"n\":\"Light\"},{\"t\":3,\"p\":1,\"n\":\"Sound 1\",\"lt\":\"Sound 2\",\"lf\":\"Sound Level\"},{\"t\":3,\"p\":1,\"n\":\"Sound 2\",\"lt\":\"Sound Level\",\"lf\":\"Sound 1\"},{\"t\":3,\"n\":\"Impact Data Set\"},{\"t\":3,\"n\":\"Placed Object\"},{\"t\":3,\"n\":\"Spawn Projectile\"},{\"t\":5,\"n\":\"Force\"},{\"t\":5,\"n\":\"Damage\"},{\"t\":5,\"n\":\"Radius\"},{\"t\":5,\"n\":\"IS Radius\"},{\"t\":5,\"n\":\"Vertical Offset Mult\"},{\"t\":3,\"n\":\"Flags\"},{\"t\":3,\"p\":1,\"n\":\"Sound Level\",\"lt\":\"Sound 1\",\"lf\":\"Sound 2\"}]}]},{\"t\":1,\"p\":1,\"n\":\"FACT - Faction\",\"c\":[{\"t\":6,\"n\":\"Record Header\",\"c\":[{\"t\":2,\"n\":\"Signature\"},{\"t\":3,\"n\":\"Data Size\"},{\"t\":3,\"n\":\"Record Flags\"},{\"t\":3,\"n\":\"FormID\"},{\"t\":11,\"n\":\"Version Control Info 1\"},{\"t\":3,\"n\":\"Form Version\"},{\"t\":11,\"n\":\"Version Control Info 2\"}]},{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":10,\"p\":1,\"n\":\"Relations\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"XNAM - Relation\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Faction\"},{\"t\":3,\"p\":1,\"n\":\"Modifier\"},{\"t\":3,\"p\":1,\"n\":\"Group Combat Reaction\"}]}]},{\"t\":6,\"n\":\"DATA - Flags\",\"c\":[{\"t\":3,\"n\":\"Flags\"}]},{\"t\":3,\"n\":\"JAIL - Exterior Jail Marker\"},{\"t\":3,\"n\":\"WAIT - Follower Wait Marker\"},{\"t\":3,\"n\":\"STOL - Stolen Goods Container\"},{\"t\":3,\"n\":\"PLCN - Player Inventory Container\"},{\"t\":3,\"n\":\"CRGR - Shared Crime Faction List\"},{\"t\":3,\"n\":\"JOUT - Jail Outfit\"},{\"t\":6,\"n\":\"CRVA - Crime Values\",\"c\":[{\"t\":3,\"n\":\"Arrest\"},{\"t\":3,\"n\":\"Attack On Sight\"},{\"t\":3,\"n\":\"Murder\"},{\"t\":3,\"n\":\"Assault\"},{\"t\":3,\"n\":\"Trespass\"},{\"t\":3,\"n\":\"Pickpocket\"},{\"t\":3,\"n\":\"Unknown\"},{\"t\":5,\"n\":\"Steal Multiplier\"},{\"t\":3,\"n\":\"Escape\"},{\"t\":3,\"n\":\"Werewolf\"}]},{\"t\":10,\"n\":\"Ranks\",\"c\":[{\"t\":6,\"n\":\"Rank\",\"c\":[{\"t\":3,\"n\":\"RNAM - Rank#\"}]}]},{\"t\":3,\"n\":\"VEND - Vendor Buy\\/Sell List\"},{\"t\":3,\"n\":\"VENC - Merchant Container\"},{\"t\":6,\"n\":\"VENV - Vendor Values\",\"c\":[{\"t\":3,\"n\":\"Start Hour\"},{\"t\":3,\"n\":\"End Hour\"},{\"t\":3,\"n\":\"Radius\"},{\"t\":11,\"n\":\"Unknown 1\"},{\"t\":3,\"n\":\"Only Buys Stolen Items\"},{\"t\":3,\"n\":\"Not\\/Sell Buy\"},{\"t\":11,\"n\":\"Unknown 2\"}]},{\"t\":6,\"n\":\"PLVD - Location\",\"c\":[{\"t\":3,\"n\":\"Type\"},{\"t\":12,\"n\":\"Location Value\"},{\"t\":3,\"n\":\"Radius\"}]},{\"t\":3,\"n\":\"CITC - Condition Count\"},{\"t\":8,\"n\":\"Conditions\",\"c\":[{\"t\":6,\"n\":\"Condition\",\"c\":[{\"t\":6,\"n\":\"CTDA - \",\"c\":[{\"t\":3,\"n\":\"Type\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":12,\"n\":\"Comparison Value\"},{\"t\":3,\"n\":\"Function\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":12,\"n\":\"Parameter #1\"},{\"t\":12,\"n\":\"Parameter #2\"},{\"t\":3,\"n\":\"Run On\"},{\"t\":12,\"n\":\"Reference\"},{\"t\":3,\"n\":\"Parameter #3\"}]}]}]}]},{\"t\":1,\"p\":1,\"n\":\"FLOR - Flora\",\"c\":[{\"t\":6,\"n\":\"Record Header\",\"c\":[{\"t\":2,\"n\":\"Signature\"},{\"t\":3,\"n\":\"Data Size\"},{\"t\":3,\"n\":\"Record Flags\"},{\"t\":3,\"n\":\"FormID\"},{\"t\":11,\"n\":\"Version Control Info 1\"},{\"t\":3,\"n\":\"Form Version\"},{\"t\":11,\"n\":\"Version Control Info 2\"}]},{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"VMAD - Virtual Machine Adapter\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Version\"},{\"t\":3,\"p\":1,\"n\":\"Object Format\"},{\"t\":12,\"p\":1,\"n\":\"Data\",\"c\":[{\"t\":9,\"p\":1,\"n\":\"Scripts\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Script\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"scriptName\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":9,\"p\":1,\"n\":\"Properties\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Property\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"propertyName\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":12,\"p\":1,\"n\":\"Value\"}]}]}]}]}]}]},{\"t\":6,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"n\":\"X1\"},{\"t\":3,\"n\":\"Y1\"},{\"t\":3,\"n\":\"Z1\"},{\"t\":3,\"n\":\"X2\"},{\"t\":3,\"n\":\"Y2\"},{\"t\":3,\"n\":\"Z2\"}]},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"}]},{\"t\":6,\"n\":\"Destructable\",\"c\":[{\"t\":6,\"n\":\"DEST - Header\",\"c\":[{\"t\":3,\"n\":\"Health\"},{\"t\":3,\"n\":\"DEST Count\"},{\"t\":3,\"n\":\"VATS Targetable\"},{\"t\":11,\"n\":\"Unknown\"}]}]},{\"t\":3,\"n\":\"KSIZ - Keyword Count\"},{\"t\":9,\"n\":\"KWDA - Keywords\",\"c\":[{\"t\":3,\"n\":\"Keyword\"}]},{\"t\":11,\"n\":\"PNAM - Unknown\"},{\"t\":2,\"n\":\"RNAM - Activate Text Override\"},{\"t\":11,\"n\":\"FNAM - Unknown\"},{\"t\":3,\"n\":\"PFIG - Ingredient\"},{\"t\":3,\"n\":\"SNAM - Sound\"},{\"t\":6,\"n\":\"PFPC - Seasonal ingredient production\",\"c\":[{\"t\":3,\"n\":\"Spring\"},{\"t\":3,\"n\":\"Summer \"},{\"t\":3,\"n\":\"Fall\"},{\"t\":3,\"n\":\"Winter\"}]}]},{\"t\":1,\"p\":1,\"n\":\"FURN - Furniture\",\"c\":[{\"t\":6,\"n\":\"Record Header\",\"c\":[{\"t\":2,\"n\":\"Signature\"},{\"t\":3,\"n\":\"Data Size\"},{\"t\":3,\"n\":\"Record Flags\"},{\"t\":3,\"n\":\"FormID\"},{\"t\":11,\"n\":\"Version Control Info 1\"},{\"t\":3,\"n\":\"Form Version\"},{\"t\":11,\"n\":\"Version Control Info 2\"}]},{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"VMAD - Virtual Machine Adapter\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Version\"},{\"t\":3,\"p\":1,\"n\":\"Object Format\"},{\"t\":12,\"p\":1,\"n\":\"Data\",\"c\":[{\"t\":9,\"p\":1,\"n\":\"Scripts\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Script\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"scriptName\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":9,\"p\":1,\"n\":\"Properties\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Property\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"propertyName\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":12,\"p\":1,\"n\":\"Value\"}]}]}]}]}]}]},{\"t\":6,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"n\":\"X1\"},{\"t\":3,\"n\":\"Y1\"},{\"t\":3,\"n\":\"Z1\"},{\"t\":3,\"n\":\"X2\"},{\"t\":3,\"n\":\"Y2\"},{\"t\":3,\"n\":\"Z2\"}]},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"}]},{\"t\":6,\"n\":\"Destructable\",\"c\":[{\"t\":6,\"n\":\"DEST - Header\",\"c\":[{\"t\":3,\"n\":\"Health\"},{\"t\":3,\"n\":\"DEST Count\"},{\"t\":3,\"n\":\"VATS Targetable\"},{\"t\":11,\"n\":\"Unknown\"}]}]},{\"t\":3,\"n\":\"KSIZ - Keyword Count\"},{\"t\":9,\"n\":\"KWDA - Keywords\",\"c\":[{\"t\":3,\"n\":\"Keyword\"}]},{\"t\":11,\"n\":\"PNAM - Unknown\"},{\"t\":3,\"n\":\"FNAM - Flags\"},{\"t\":3,\"n\":\"KNAM - Interaction Keyword\"},{\"t\":3,\"n\":\"MNAM - Active Markers \\/ Flags\"},{\"t\":6,\"n\":\"WBDT - Workbench Data\",\"c\":[{\"t\":3,\"n\":\"Bench Type\"},{\"t\":3,\"n\":\"Uses Skill\"}]},{\"t\":3,\"n\":\"NAM1 - Associated Spell\"},{\"t\":8,\"n\":\"Markers\",\"c\":[{\"t\":6,\"n\":\"Marker\",\"c\":[{\"t\":3,\"n\":\"ENAM - Marker Index\"}]}]},{\"t\":8,\"n\":\"Marker Entry Points\",\"c\":[{\"t\":6,\"n\":\"FNPR - Marker\",\"c\":[{\"t\":3,\"n\":\"Type\"},{\"t\":3,\"n\":\"Entry Points\"}]}]},{\"t\":2,\"n\":\"XMRK - Model Filename\"}]},{\"t\":1,\"p\":1,\"n\":\"GRAS - Grass\",\"c\":[{\"t\":6,\"n\":\"Record Header\",\"c\":[{\"t\":2,\"n\":\"Signature\"},{\"t\":3,\"n\":\"Data Size\"},{\"t\":3,\"n\":\"Record Flags\"},{\"t\":3,\"n\":\"FormID\"},{\"t\":11,\"n\":\"Version Control Info 1\"},{\"t\":3,\"n\":\"Form Version\"},{\"t\":11,\"n\":\"Version Control Info 2\"}]},{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"n\":\"X1\"},{\"t\":3,\"n\":\"Y1\"},{\"t\":3,\"n\":\"Z1\"},{\"t\":3,\"n\":\"X2\"},{\"t\":3,\"n\":\"Y2\"},{\"t\":3,\"n\":\"Z2\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"}]},{\"t\":6,\"n\":\"DATA - \",\"c\":[{\"t\":3,\"n\":\"Density\"},{\"t\":3,\"n\":\"Min Slope\"},{\"t\":3,\"n\":\"Max Slope\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":3,\"n\":\"Units From Water\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":3,\"n\":\"Units From Water Type\"},{\"t\":5,\"n\":\"Position Range\"},{\"t\":5,\"n\":\"Height Range\"},{\"t\":5,\"n\":\"Color Range\"},{\"t\":5,\"n\":\"Wave Period\"},{\"t\":3,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unknown\"}]}]},{\"t\":1,\"p\":1,\"n\":\"HAZD - Hazard\",\"c\":[{\"t\":6,\"n\":\"Record Header\",\"c\":[{\"t\":2,\"n\":\"Signature\"},{\"t\":3,\"n\":\"Data Size\"},{\"t\":3,\"n\":\"Record Flags\"},{\"t\":3,\"n\":\"FormID\"},{\"t\":11,\"n\":\"Version Control Info 1\"},{\"t\":3,\"n\":\"Form Version\"},{\"t\":11,\"n\":\"Version Control Info 2\"}]},{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"n\":\"X1\"},{\"t\":3,\"n\":\"Y1\"},{\"t\":3,\"n\":\"Z1\"},{\"t\":3,\"n\":\"X2\"},{\"t\":3,\"n\":\"Y2\"},{\"t\":3,\"n\":\"Z2\"}]},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":6,\"n\":\"Model\",\"c\":[{\"t\":2,\"n\":\"MODL - Model Filename\"}]},{\"t\":3,\"n\":\"MNAM - Image Space Modifier\"},{\"t\":6,\"n\":\"DATA - Data\",\"c\":[{\"t\":3,\"n\":\"Limit\"},{\"t\":5,\"n\":\"Radius\"},{\"t\":5,\"n\":\"Lifetime\"},{\"t\":5,\"n\":\"Image Space Radius\"},{\"t\":5,\"n\":\"Target Interval\"},{\"t\":3,\"n\":\"Flags\"},{\"t\":3,\"n\":\"Spell\"},{\"t\":3,\"n\":\"Light\"},{\"t\":3,\"n\":\"Impact Data Set\"},{\"t\":3,\"n\":\"Sound\"}]}]},{\"t\":1,\"p\":1,\"n\":\"HDPT - Head Part\",\"c\":[{\"t\":6,\"n\":\"Record Header\",\"c\":[{\"t\":2,\"n\":\"Signature\"},{\"t\":3,\"n\":\"Data Size\"},{\"t\":3,\"n\":\"Record Flags\"},{\"t\":3,\"n\":\"FormID\"},{\"t\":11,\"n\":\"Version Control Info 1\"},{\"t\":3,\"n\":\"Form Version\"},{\"t\":11,\"n\":\"Version Control Info 2\"}]},{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":6,\"n\":\"Model\",\"c\":[{\"t\":2,\"n\":\"MODL - Model Filename\"}]},{\"t\":3,\"n\":\"DATA - Flags\"},{\"t\":3,\"n\":\"PNAM - Type\"},{\"t\":9,\"n\":\"Extra Parts\",\"c\":[{\"t\":3,\"n\":\"HNAM - Part\"}]},{\"t\":8,\"n\":\"Parts\",\"c\":[{\"t\":6,\"n\":\"Part\",\"c\":[{\"t\":3,\"n\":\"NAM0 - Part Type\"},{\"t\":2,\"n\":\"NAM1 - Filename\"}]}]},{\"t\":3,\"n\":\"TNAM - Texture Set\"},{\"t\":3,\"n\":\"CNAM - Color\"},{\"t\":3,\"n\":\"RNAM - Valid Races\"}]},{\"t\":1,\"p\":1,\"n\":\"INFO - Dialog response\",\"c\":[{\"t\":3,\"n\":\"Topic\"},{\"t\":6,\"n\":\"Record Header\",\"c\":[{\"t\":2,\"n\":\"Signature\"},{\"t\":3,\"n\":\"Data Size\"},{\"t\":3,\"n\":\"Record Flags\"},{\"t\":3,\"n\":\"FormID\"},{\"t\":11,\"n\":\"Version Control Info 1\"},{\"t\":3,\"n\":\"Form Version\"},{\"t\":11,\"n\":\"Version Control Info 2\"}]},{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"VMAD - Virtual Machine Adapter\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Version\"},{\"t\":3,\"p\":1,\"n\":\"Object Format\"},{\"t\":12,\"p\":1,\"n\":\"Data\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Info VMAD\",\"c\":[{\"t\":9,\"p\":1,\"n\":\"Scripts\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Script\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"scriptName\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":9,\"p\":1,\"n\":\"Properties\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Property\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"propertyName\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":12,\"p\":1,\"n\":\"Value\"}]}]}]}]},{\"t\":6,\"p\":1,\"n\":\"Script Fragments Info\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Unknown\"},{\"t\":3,\"p\":1,\"n\":\"Info Fragments Flags\"},{\"t\":2,\"p\":1,\"n\":\"fileName\"},{\"t\":7,\"p\":1,\"n\":\"Info Fragments\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Info Fragment #0\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Unknown\"},{\"t\":2,\"p\":1,\"n\":\"scriptName\"},{\"t\":2,\"p\":1,\"n\":\"fragmentName\"}]}]}]}]}]}]},{\"t\":11,\"n\":\"DATA - Unknown\"},{\"t\":6,\"n\":\"ENAM - Response flags\",\"c\":[{\"t\":3,\"n\":\"Flags\"},{\"t\":3,\"n\":\"Reset Hours\"}]},{\"t\":3,\"n\":\"TPIC - Topic\"},{\"t\":3,\"n\":\"PNAM - Previous INFO\"},{\"t\":3,\"n\":\"CNAM - Favor Level\"},{\"t\":7,\"n\":\"Link To\",\"c\":[{\"t\":3,\"n\":\"TCLT - Response\"}]},{\"t\":3,\"n\":\"DNAM - Response Data\"},{\"t\":8,\"n\":\"Responses\",\"c\":[{\"t\":6,\"n\":\"Response\",\"c\":[{\"t\":6,\"n\":\"TRDT - Response Data\",\"c\":[{\"t\":3,\"n\":\"Emotion Type\"},{\"t\":3,\"n\":\"Emotion Value\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":3,\"n\":\"Response number\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":3,\"n\":\"Sound\"},{\"t\":3,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"}]}]}]},{\"t\":8,\"n\":\"Conditions\",\"c\":[{\"t\":6,\"n\":\"Condition\",\"c\":[{\"t\":6,\"n\":\"CTDA - \",\"c\":[{\"t\":3,\"n\":\"Type\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":12,\"n\":\"Comparison Value\"},{\"t\":3,\"n\":\"Function\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":12,\"n\":\"Parameter #1\"},{\"t\":12,\"n\":\"Parameter #2\"},{\"t\":3,\"n\":\"Run On\"},{\"t\":12,\"n\":\"Reference\"},{\"t\":3,\"n\":\"Parameter #3\"}]}]}]},{\"t\":8,\"n\":\"Unknown\",\"c\":[{\"t\":6,\"n\":\"Unknown\",\"c\":[{\"t\":11,\"n\":\"SCHR - Unknown\"}]}]},{\"t\":2,\"n\":\"RNAM - Prompt\"},{\"t\":3,\"n\":\"ANAM - Speaker\"},{\"t\":3,\"n\":\"TWAT - Walk Away Topic\"},{\"t\":3,\"n\":\"ONAM - Audio Output Override\"}]},{\"t\":1,\"p\":1,\"n\":\"INGR - Ingredient\",\"c\":[{\"t\":6,\"n\":\"Record Header\",\"c\":[{\"t\":2,\"n\":\"Signature\"},{\"t\":3,\"n\":\"Data Size\"},{\"t\":3,\"n\":\"Record Flags\"},{\"t\":3,\"n\":\"FormID\"},{\"t\":11,\"n\":\"Version Control Info 1\"},{\"t\":3,\"n\":\"Form Version\"},{\"t\":11,\"n\":\"Version Control Info 2\"}]},{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"VMAD - Virtual Machine Adapter\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Version\"},{\"t\":3,\"p\":1,\"n\":\"Object Format\"},{\"t\":12,\"p\":1,\"n\":\"Data\",\"c\":[{\"t\":9,\"p\":1,\"n\":\"Scripts\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Script\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"scriptName\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":9,\"p\":1,\"n\":\"Properties\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Property\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"propertyName\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":12,\"p\":1,\"n\":\"Value\"}]}]}]}]}]}]},{\"t\":6,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"n\":\"X1\"},{\"t\":3,\"n\":\"Y1\"},{\"t\":3,\"n\":\"Z1\"},{\"t\":3,\"n\":\"X2\"},{\"t\":3,\"n\":\"Y2\"},{\"t\":3,\"n\":\"Z2\"}]},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":3,\"n\":\"KSIZ - Keyword Count\"},{\"t\":9,\"n\":\"KWDA - Keywords\",\"c\":[{\"t\":3,\"n\":\"Keyword\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Icon\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"ICON - Large Icon filename\"}]},{\"t\":6,\"n\":\"Destructable\",\"c\":[{\"t\":6,\"n\":\"DEST - Header\",\"c\":[{\"t\":3,\"n\":\"Health\"},{\"t\":3,\"n\":\"DEST Count\"},{\"t\":3,\"n\":\"VATS Targetable\"},{\"t\":11,\"n\":\"Unknown\"}]}]},{\"t\":3,\"n\":\"ETYP - Equipment Type\"},{\"t\":3,\"n\":\"YNAM - Sound - Pick Up\"},{\"t\":3,\"n\":\"ZNAM - Sound - Drop\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DATA - \",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Value\"},{\"t\":5,\"p\":1,\"n\":\"Weight\"}]},{\"t\":6,\"n\":\"ENIT - Effect Data\",\"c\":[{\"t\":3,\"n\":\"Ingredient Value\"},{\"t\":3,\"n\":\"Flags\"}]},{\"t\":8,\"n\":\"Effects\",\"c\":[{\"t\":6,\"n\":\"Effect\",\"c\":[{\"t\":3,\"n\":\"EFID - Base Effect\"},{\"t\":6,\"n\":\"EFIT - \",\"c\":[{\"t\":5,\"n\":\"Magnitude\"},{\"t\":3,\"n\":\"Area\"},{\"t\":3,\"n\":\"Duration\"}]}]}]}]},{\"t\":1,\"p\":1,\"n\":\"IPCT - Impact\",\"c\":[{\"t\":6,\"n\":\"Record Header\",\"c\":[{\"t\":2,\"n\":\"Signature\"},{\"t\":3,\"n\":\"Data Size\"},{\"t\":3,\"n\":\"Record Flags\"},{\"t\":3,\"n\":\"FormID\"},{\"t\":11,\"n\":\"Version Control Info 1\"},{\"t\":3,\"n\":\"Form Version\"},{\"t\":11,\"n\":\"Version Control Info 2\"}]},{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"n\":\"Model\",\"c\":[{\"t\":2,\"n\":\"MODL - Model Filename\"}]},{\"t\":6,\"n\":\"DATA - \",\"c\":[{\"t\":5,\"n\":\"Effect - Duration\"},{\"t\":3,\"n\":\"Effect - Orientation\"},{\"t\":5,\"n\":\"Angle Threshold\"},{\"t\":5,\"n\":\"Placement Radius\"},{\"t\":3,\"n\":\"Sound Level\"},{\"t\":3,\"n\":\"Flags\"},{\"t\":3,\"n\":\"Impact Result\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":6,\"n\":\"DODT - Decal Data\",\"c\":[{\"t\":5,\"n\":\"Min Width\"},{\"t\":5,\"n\":\"Max Width\"},{\"t\":5,\"n\":\"Min Height\"},{\"t\":5,\"n\":\"Max Height\"},{\"t\":5,\"n\":\"Depth\"},{\"t\":5,\"n\":\"Shininess\"},{\"t\":6,\"n\":\"Parallax\",\"c\":[{\"t\":5,\"n\":\"Scale\"},{\"t\":3,\"n\":\"Passes\"}]},{\"t\":3,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":6,\"n\":\"Color\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unknown\"}]}]},{\"t\":3,\"n\":\"DNAM - Texture Set\"},{\"t\":3,\"n\":\"ENAM - Secondary Texture Set\"},{\"t\":3,\"p\":1,\"n\":\"SNAM - Sound 1\",\"lt\":\"NAM1 - Sound 2\",\"lf\":\"NAM1 - Sound 2\"},{\"t\":3,\"p\":1,\"n\":\"NAM1 - Sound 2\",\"lt\":\"SNAM - Sound 1\",\"lf\":\"SNAM - Sound 1\"},{\"t\":3,\"n\":\"NAM2 - Hazard\"}]},{\"t\":1,\"p\":1,\"n\":\"KEYM - Key\",\"c\":[{\"t\":6,\"n\":\"Record Header\",\"c\":[{\"t\":2,\"n\":\"Signature\"},{\"t\":3,\"n\":\"Data Size\"},{\"t\":3,\"n\":\"Record Flags\"},{\"t\":3,\"n\":\"FormID\"},{\"t\":11,\"n\":\"Version Control Info 1\"},{\"t\":3,\"n\":\"Form Version\"},{\"t\":11,\"n\":\"Version Control Info 2\"}]},{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"VMAD - Virtual Machine Adapter\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Version\"},{\"t\":3,\"p\":1,\"n\":\"Object Format\"},{\"t\":12,\"p\":1,\"n\":\"Data\",\"c\":[{\"t\":9,\"p\":1,\"n\":\"Scripts\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Script\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"scriptName\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":9,\"p\":1,\"n\":\"Properties\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Property\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"propertyName\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":12,\"p\":1,\"n\":\"Value\"}]}]}]}]}]}]},{\"t\":6,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"n\":\"X1\"},{\"t\":3,\"n\":\"Y1\"},{\"t\":3,\"n\":\"Z1\"},{\"t\":3,\"n\":\"X2\"},{\"t\":3,\"n\":\"Y2\"},{\"t\":3,\"n\":\"Z2\"}]},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":6,\"n\":\"Model\",\"c\":[{\"t\":2,\"n\":\"MODL - Model Filename\"}]},{\"t\":6,\"n\":\"Icon\",\"c\":[{\"t\":2,\"n\":\"ICON - Large Icon filename\"}]},{\"t\":6,\"n\":\"Destructable\",\"c\":[{\"t\":6,\"n\":\"DEST - Header\",\"c\":[{\"t\":3,\"n\":\"Health\"},{\"t\":3,\"n\":\"DEST Count\"},{\"t\":3,\"n\":\"VATS Targetable\"},{\"t\":11,\"n\":\"Unknown\"}]}]},{\"t\":3,\"n\":\"YNAM - Sound - Pick Up\"},{\"t\":3,\"n\":\"ZNAM - Sound - Drop\"},{\"t\":3,\"n\":\"KSIZ - Keyword Count\"},{\"t\":9,\"n\":\"KWDA - Keywords\",\"c\":[{\"t\":3,\"n\":\"Keyword\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DATA - \",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Value\"},{\"t\":5,\"p\":1,\"n\":\"Weight\"}]}]},{\"t\":1,\"p\":1,\"n\":\"LCTN - Location\",\"c\":[{\"t\":6,\"n\":\"Record Header\",\"c\":[{\"t\":2,\"n\":\"Signature\"},{\"t\":3,\"n\":\"Data Size\"},{\"t\":3,\"n\":\"Record Flags\"},{\"t\":3,\"n\":\"FormID\"},{\"t\":11,\"n\":\"Version Control Info 1\"},{\"t\":3,\"n\":\"Form Version\"},{\"t\":11,\"n\":\"Version Control Info 2\"}]},{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":8,\"n\":\"ACPR - Actor Cell Persistent Reference\",\"c\":[{\"t\":6,\"n\":\" #0\",\"c\":[{\"t\":3,\"n\":\"Actor\"},{\"t\":3,\"n\":\"Location\"},{\"t\":3,\"n\":\"Grid Y\"},{\"t\":3,\"n\":\"Grid X\"}]}]},{\"t\":8,\"n\":\"LCPR - Location Cell Persistent Reference\",\"c\":[{\"t\":6,\"n\":\" #0\",\"c\":[{\"t\":3,\"n\":\"Actor\"},{\"t\":3,\"n\":\"Location\"},{\"t\":3,\"n\":\"Grid Y\"},{\"t\":3,\"n\":\"Grid X\"}]}]},{\"t\":7,\"n\":\"RCPR - Reference Cell Persistent Reference\",\"c\":[{\"t\":3,\"n\":\"Ref #0\"}]},{\"t\":8,\"n\":\"ACUN - Actor Cell Unique\",\"c\":[{\"t\":6,\"n\":\" #0\",\"c\":[{\"t\":3,\"n\":\"Actor\"},{\"t\":3,\"n\":\"Ref\"},{\"t\":3,\"n\":\"Location\"}]}]},{\"t\":8,\"n\":\"LCUN - Location Cell Unique\",\"c\":[{\"t\":6,\"n\":\" #0\",\"c\":[{\"t\":3,\"n\":\"Actor\"},{\"t\":3,\"n\":\"Ref\"},{\"t\":3,\"n\":\"Location\"}]}]},{\"t\":7,\"n\":\"RCUN - Reference Cell Unique\",\"c\":[{\"t\":3,\"n\":\"Actor #0\"}]},{\"t\":8,\"n\":\"ACSR - Actor Cell Static Reference\",\"c\":[{\"t\":6,\"n\":\" #0\",\"c\":[{\"t\":3,\"n\":\"Loc Ref Type\"},{\"t\":3,\"n\":\"Marker\"},{\"t\":3,\"n\":\"Location\"},{\"t\":3,\"n\":\"Grid Y\"},{\"t\":3,\"n\":\"Grid X\"}]}]},{\"t\":8,\"n\":\"LCSR - Location Cell Static Reference\",\"c\":[{\"t\":6,\"n\":\" #0\",\"c\":[{\"t\":3,\"n\":\"Loc Ref Type\"},{\"t\":3,\"n\":\"Marker\"},{\"t\":3,\"n\":\"Location\"},{\"t\":3,\"n\":\"Grid Y\"},{\"t\":3,\"n\":\"Grid X\"}]}]},{\"t\":7,\"n\":\"RCSR - Reference Cell Static Reference\",\"c\":[{\"t\":3,\"n\":\"Ref #0\"}]},{\"t\":8,\"n\":\"Actor Cell Encounter Cell\",\"c\":[{\"t\":6,\"n\":\"ACEC - Unknown\",\"c\":[{\"t\":3,\"n\":\"Location\"},{\"t\":8,\"n\":\"Coordinates\",\"c\":[{\"t\":6,\"n\":\" #0\",\"c\":[{\"t\":3,\"n\":\"Grid Y\"},{\"t\":3,\"n\":\"Grid X\"}]}]}]}]},{\"t\":8,\"n\":\"Location Cell Encounter Cell\",\"c\":[{\"t\":6,\"n\":\"LCEC - Unknown\",\"c\":[{\"t\":3,\"n\":\"Location\"},{\"t\":8,\"n\":\"Coordinates\",\"c\":[{\"t\":6,\"n\":\" #0\",\"c\":[{\"t\":3,\"n\":\"Grid Y\"},{\"t\":3,\"n\":\"Grid X\"}]}]}]}]},{\"t\":8,\"n\":\"Reference Cell Encounter Cell\",\"c\":[{\"t\":6,\"n\":\"RCEC - Unknown\",\"c\":[{\"t\":3,\"n\":\"Location\"},{\"t\":8,\"n\":\"Coordinates\",\"c\":[{\"t\":6,\"n\":\" #0\",\"c\":[{\"t\":3,\"n\":\"Grid Y\"},{\"t\":3,\"n\":\"Grid X\"}]}]}]}]},{\"t\":7,\"n\":\"ACID - Actor Cell Marker Reference\",\"c\":[{\"t\":3,\"n\":\"Ref #0\"}]},{\"t\":7,\"n\":\"LCID - Location Cell Marker Reference\",\"c\":[{\"t\":3,\"n\":\"Ref #0\"}]},{\"t\":8,\"n\":\"ACEP - Actor Cell Enable Point\",\"c\":[{\"t\":6,\"n\":\" #0\",\"c\":[{\"t\":3,\"n\":\"Actor\"},{\"t\":3,\"n\":\"Ref\"},{\"t\":3,\"n\":\"Grid Y\"},{\"t\":3,\"n\":\"Grid X\"}]}]},{\"t\":8,\"n\":\"LCEP - Location Cell Enable Point\",\"c\":[{\"t\":6,\"n\":\" #0\",\"c\":[{\"t\":3,\"n\":\"Actor\"},{\"t\":3,\"n\":\"Ref\"},{\"t\":3,\"n\":\"Grid Y\"},{\"t\":3,\"n\":\"Grid X\"}]}]},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":3,\"n\":\"KSIZ - Keyword Count\"},{\"t\":9,\"n\":\"KWDA - Keywords\",\"c\":[{\"t\":3,\"n\":\"Keyword\"}]},{\"t\":3,\"n\":\"PNAM - Parent Location\"},{\"t\":3,\"n\":\"NAM1 - Music\"},{\"t\":3,\"n\":\"FNAM - Unreported Crime Faction\"},{\"t\":3,\"n\":\"MNAM - World Location Marker Ref\"},{\"t\":5,\"n\":\"RNAM - World Location Radius\"},{\"t\":3,\"n\":\"NAM0 - Horse Marker Ref\"},{\"t\":6,\"n\":\"CNAM - Color\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unknown\"}]}]},{\"t\":1,\"p\":1,\"n\":\"LIGH - Light\",\"c\":[{\"t\":6,\"n\":\"Record Header\",\"c\":[{\"t\":2,\"n\":\"Signature\"},{\"t\":3,\"n\":\"Data Size\"},{\"t\":3,\"n\":\"Record Flags\"},{\"t\":3,\"n\":\"FormID\"},{\"t\":11,\"n\":\"Version Control Info 1\"},{\"t\":3,\"n\":\"Form Version\"},{\"t\":11,\"n\":\"Version Control Info 2\"}]},{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"VMAD - Virtual Machine Adapter\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Version\"},{\"t\":3,\"p\":1,\"n\":\"Object Format\"},{\"t\":12,\"p\":1,\"n\":\"Data\",\"c\":[{\"t\":9,\"p\":1,\"n\":\"Scripts\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Script\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"scriptName\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":9,\"p\":1,\"n\":\"Properties\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Property\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"propertyName\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":12,\"p\":1,\"n\":\"Value\"}]}]}]}]}]}]},{\"t\":6,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"n\":\"X1\"},{\"t\":3,\"n\":\"Y1\"},{\"t\":3,\"n\":\"Z1\"},{\"t\":3,\"n\":\"X2\"},{\"t\":3,\"n\":\"Y2\"},{\"t\":3,\"n\":\"Z2\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"}]},{\"t\":6,\"n\":\"Destructable\",\"c\":[{\"t\":6,\"n\":\"DEST - Header\",\"c\":[{\"t\":3,\"n\":\"Health\"},{\"t\":3,\"n\":\"DEST Count\"},{\"t\":3,\"n\":\"VATS Targetable\"},{\"t\":11,\"n\":\"Unknown\"}]}]},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Icon\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"ICON - Large Icon filename\"}]},{\"t\":6,\"n\":\"DATA - \",\"c\":[{\"t\":3,\"n\":\"Time\"},{\"t\":3,\"n\":\"Radius\"},{\"t\":6,\"n\":\"Color\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":3,\"n\":\"Unknown\"}]},{\"t\":3,\"n\":\"Flags\"},{\"t\":5,\"n\":\"Falloff Exponent\"},{\"t\":5,\"n\":\"FOV\"},{\"t\":5,\"n\":\"Near Clip\"},{\"t\":6,\"n\":\"Flicker Effect\",\"c\":[{\"t\":5,\"n\":\"Period\"},{\"t\":5,\"n\":\"Intensity Amplitude\"},{\"t\":5,\"n\":\"Movement Amplitude\"}]},{\"t\":3,\"n\":\"Value\"},{\"t\":5,\"n\":\"Weight\"}]},{\"t\":5,\"n\":\"FNAM - Fade value\"},{\"t\":3,\"n\":\"SNAM - Sound\"}]},{\"t\":1,\"p\":1,\"n\":\"LSCR - Load Screen\",\"c\":[{\"t\":6,\"n\":\"Record Header\",\"c\":[{\"t\":2,\"n\":\"Signature\"},{\"t\":3,\"n\":\"Data Size\"},{\"t\":3,\"n\":\"Record Flags\"},{\"t\":3,\"n\":\"FormID\"},{\"t\":11,\"n\":\"Version Control Info 1\"},{\"t\":3,\"n\":\"Form Version\"},{\"t\":11,\"n\":\"Version Control Info 2\"}]},{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Icon\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"ICON - Large Icon filename\"}]},{\"t\":2,\"n\":\"DESC - Description\"},{\"t\":8,\"n\":\"Conditions\",\"c\":[{\"t\":6,\"n\":\"Condition\",\"c\":[{\"t\":6,\"n\":\"CTDA - \",\"c\":[{\"t\":3,\"n\":\"Type\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":12,\"n\":\"Comparison Value\"},{\"t\":3,\"n\":\"Function\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":12,\"n\":\"Parameter #1\"},{\"t\":12,\"n\":\"Parameter #2\"},{\"t\":3,\"n\":\"Run On\"},{\"t\":12,\"n\":\"Reference\"},{\"t\":3,\"n\":\"Parameter #3\"}]}]}]},{\"t\":3,\"n\":\"NNAM - Loading Screen NIF\"},{\"t\":5,\"n\":\"SNAM - Initial Scale\"},{\"t\":6,\"n\":\"RNAM - Initial Rotation\",\"c\":[{\"t\":3,\"n\":\"X\"},{\"t\":3,\"n\":\"Y\"},{\"t\":3,\"n\":\"Z\"}]},{\"t\":6,\"n\":\"ONAM - Rotation Offset Constraints\",\"c\":[{\"t\":3,\"n\":\"Min\"},{\"t\":3,\"n\":\"Max\"}]},{\"t\":6,\"n\":\"XNAM - Initial Translation Offset\",\"c\":[{\"t\":5,\"n\":\"X\"},{\"t\":5,\"n\":\"Y\"},{\"t\":5,\"n\":\"Z\"}]},{\"t\":2,\"n\":\"MOD2 - Camera Path\"}]},{\"t\":1,\"p\":1,\"n\":\"LVLI - Leveled Item\",\"c\":[{\"t\":6,\"n\":\"Record Header\",\"c\":[{\"t\":2,\"n\":\"Signature\"},{\"t\":3,\"n\":\"Data Size\"},{\"t\":3,\"n\":\"Record Flags\"},{\"t\":3,\"n\":\"FormID\"},{\"t\":11,\"n\":\"Version Control Info 1\"},{\"t\":3,\"n\":\"Form Version\"},{\"t\":11,\"n\":\"Version Control Info 2\"}]},{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"n\":\"X1\"},{\"t\":3,\"n\":\"Y1\"},{\"t\":3,\"n\":\"Z1\"},{\"t\":3,\"n\":\"X2\"},{\"t\":3,\"n\":\"Y2\"},{\"t\":3,\"n\":\"Z2\"}]},{\"t\":3,\"n\":\"LVLD - Chance None\"},{\"t\":3,\"n\":\"LVLF - Flags\"},{\"t\":3,\"n\":\"LVLG - Global\"},{\"t\":3,\"n\":\"LLCT - Count\"},{\"t\":10,\"p\":1,\"o\":1,\"n\":\"Leveled List Entries\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Leveled List Entry\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"LVLO - Base Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Level\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":3,\"n\":\"Count\"},{\"t\":11,\"n\":\"Unknown\"}]}]}]}]},{\"t\":1,\"p\":1,\"n\":\"LVLN - Leveled NPC\",\"c\":[{\"t\":6,\"n\":\"Record Header\",\"c\":[{\"t\":2,\"n\":\"Signature\"},{\"t\":3,\"n\":\"Data Size\"},{\"t\":3,\"n\":\"Record Flags\"},{\"t\":3,\"n\":\"FormID\"},{\"t\":11,\"n\":\"Version Control Info 1\"},{\"t\":3,\"n\":\"Form Version\"},{\"t\":11,\"n\":\"Version Control Info 2\"}]},{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"n\":\"X1\"},{\"t\":3,\"n\":\"Y1\"},{\"t\":3,\"n\":\"Z1\"},{\"t\":3,\"n\":\"X2\"},{\"t\":3,\"n\":\"Y2\"},{\"t\":3,\"n\":\"Z2\"}]},{\"t\":3,\"n\":\"LVLD - Chance None\"},{\"t\":3,\"n\":\"LVLF - Flags\"},{\"t\":3,\"n\":\"LVLG - Global\"},{\"t\":3,\"n\":\"LLCT - Count\"},{\"t\":10,\"p\":1,\"o\":1,\"n\":\"Leveled List Entries\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Leveled List Entry\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"LVLO - Base Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Level\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":3,\"n\":\"Count\"},{\"t\":11,\"n\":\"Unknown\"}]}]}]},{\"t\":6,\"n\":\"Model\",\"c\":[{\"t\":2,\"n\":\"MODL - Model Filename\"}]}]},{\"t\":1,\"p\":1,\"n\":\"LVSP - Leveled Spell\",\"c\":[{\"t\":6,\"n\":\"Record Header\",\"c\":[{\"t\":2,\"n\":\"Signature\"},{\"t\":3,\"n\":\"Data Size\"},{\"t\":3,\"n\":\"Record Flags\"},{\"t\":3,\"n\":\"FormID\"},{\"t\":11,\"n\":\"Version Control Info 1\"},{\"t\":3,\"n\":\"Form Version\"},{\"t\":11,\"n\":\"Version Control Info 2\"}]},{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"n\":\"X1\"},{\"t\":3,\"n\":\"Y1\"},{\"t\":3,\"n\":\"Z1\"},{\"t\":3,\"n\":\"X2\"},{\"t\":3,\"n\":\"Y2\"},{\"t\":3,\"n\":\"Z2\"}]},{\"t\":3,\"n\":\"LVLD - Chance None\"},{\"t\":3,\"n\":\"LVLF - Flags\"},{\"t\":3,\"n\":\"LLCT - Count\"},{\"t\":10,\"p\":1,\"o\":1,\"n\":\"Leveled List Entries\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Leveled List Entry\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"LVLO - Base Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Level\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":3,\"n\":\"Count\"},{\"t\":11,\"n\":\"Unknown\"}]}]}]}]},{\"t\":1,\"p\":1,\"n\":\"MESG - Message\",\"c\":[{\"t\":6,\"n\":\"Record Header\",\"c\":[{\"t\":2,\"n\":\"Signature\"},{\"t\":3,\"n\":\"Data Size\"},{\"t\":3,\"n\":\"Record Flags\"},{\"t\":3,\"n\":\"FormID\"},{\"t\":11,\"n\":\"Version Control Info 1\"},{\"t\":3,\"n\":\"Form Version\"},{\"t\":11,\"n\":\"Version Control Info 2\"}]},{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"n\":\"DESC - Description\"},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":3,\"n\":\"INAM - Icon (unused)\"},{\"t\":3,\"n\":\"QNAM - Owner Quest\"},{\"t\":3,\"n\":\"DNAM - Flags\",\"c\":[{\"t\":4,\"n\":\"Message Box\"}]},{\"t\":3,\"n\":\"TNAM - Display Time\"},{\"t\":8,\"n\":\"Menu Buttons\",\"c\":[{\"t\":6,\"n\":\"Menu Button\",\"c\":[{\"t\":2,\"n\":\"ITXT - Button Text\"}]}]}]},{\"t\":1,\"p\":1,\"n\":\"MGEF - Magic Effect\",\"c\":[{\"t\":6,\"n\":\"Record Header\",\"c\":[{\"t\":2,\"n\":\"Signature\"},{\"t\":3,\"n\":\"Data Size\"},{\"t\":3,\"n\":\"Record Flags\"},{\"t\":3,\"n\":\"FormID\"},{\"t\":11,\"n\":\"Version Control Info 1\"},{\"t\":3,\"n\":\"Form Version\"},{\"t\":11,\"n\":\"Version Control Info 2\"}]},{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"VMAD - Virtual Machine Adapter\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Version\"},{\"t\":3,\"p\":1,\"n\":\"Object Format\"},{\"t\":12,\"p\":1,\"n\":\"Data\",\"c\":[{\"t\":9,\"p\":1,\"n\":\"Scripts\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Script\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"scriptName\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":9,\"p\":1,\"n\":\"Properties\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Property\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"propertyName\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":12,\"p\":1,\"n\":\"Value\"}]}]}]}]}]}]},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":3,\"p\":1,\"n\":\"MDOB - Menu Display Object\"},{\"t\":3,\"n\":\"KSIZ - Keyword Count\"},{\"t\":9,\"n\":\"KWDA - Keywords\",\"c\":[{\"t\":3,\"n\":\"Keyword\"}]},{\"t\":6,\"n\":\"Magic Effect Data\",\"c\":[{\"t\":6,\"n\":\"DATA - Data\",\"c\":[{\"t\":3,\"n\":\"Flags\"},{\"t\":5,\"n\":\"Base Cost\"},{\"t\":12,\"n\":\"Assoc. Item\"},{\"t\":3,\"n\":\"Magic Skill\"},{\"t\":3,\"n\":\"Resist Value\"},{\"t\":3,\"n\":\"Counter Effect count\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":3,\"n\":\"Casting Light\"},{\"t\":5,\"n\":\"Taper Weight\"},{\"t\":3,\"n\":\"Hit Shader\"},{\"t\":3,\"n\":\"Enchant Shader\"},{\"t\":3,\"n\":\"Minimum Skill Level\"},{\"t\":6,\"n\":\"Spellmaking\",\"c\":[{\"t\":3,\"n\":\"Area\"},{\"t\":5,\"n\":\"Casting Time\"}]},{\"t\":5,\"n\":\"Taper Curve\"},{\"t\":5,\"n\":\"Taper Duration\"},{\"t\":5,\"n\":\"Second AV Weight\"},{\"t\":3,\"n\":\"Archtype\"},{\"t\":3,\"n\":\"Actor Value\"},{\"t\":3,\"n\":\"Projectile\"},{\"t\":3,\"n\":\"Explosion\"},{\"t\":3,\"n\":\"Casting Type\"},{\"t\":3,\"n\":\"Delivery\"},{\"t\":3,\"n\":\"Second Actor Value\"},{\"t\":3,\"n\":\"Casting Art\"},{\"t\":3,\"n\":\"Hit Effect Art\"},{\"t\":3,\"n\":\"Impact Data\"},{\"t\":5,\"n\":\"Skill Usage Multiplier\"},{\"t\":6,\"n\":\"Dual Casting\",\"c\":[{\"t\":3,\"n\":\"Art\"},{\"t\":5,\"n\":\"Scale\"}]},{\"t\":3,\"n\":\"Enchant Art\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":3,\"n\":\"Equip Ability\"},{\"t\":3,\"n\":\"Image Space Modifier\"},{\"t\":3,\"n\":\"Perk to Apply\"},{\"t\":3,\"n\":\"Casting Sound Level\"},{\"t\":6,\"n\":\"Script Effect AI\",\"c\":[{\"t\":5,\"n\":\"Score\"},{\"t\":5,\"n\":\"Delay Time\"}]}]}]},{\"t\":9,\"n\":\"Counter Effects\",\"c\":[{\"t\":3,\"n\":\"ESCE - Effect\"}]},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"SNDD - Sounds\",\"c\":[{\"t\":6,\"p\":1,\"n\":\" #0\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Sound\"}]}]},{\"t\":2,\"n\":\"DNAM - Magic Item Description\"},{\"t\":8,\"n\":\"Conditions\",\"c\":[{\"t\":6,\"n\":\"Condition\",\"c\":[{\"t\":6,\"n\":\"CTDA - \",\"c\":[{\"t\":3,\"n\":\"Type\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":12,\"n\":\"Comparison Value\"},{\"t\":3,\"n\":\"Function\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":12,\"n\":\"Parameter #1\"},{\"t\":12,\"n\":\"Parameter #2\"},{\"t\":3,\"n\":\"Run On\"},{\"t\":12,\"n\":\"Reference\"},{\"t\":3,\"n\":\"Parameter #3\"}]}]}]}]},{\"t\":1,\"p\":1,\"n\":\"MISC - Misc. Item\",\"c\":[{\"t\":6,\"n\":\"Record Header\",\"c\":[{\"t\":2,\"n\":\"Signature\"},{\"t\":3,\"n\":\"Data Size\"},{\"t\":3,\"n\":\"Record Flags\"},{\"t\":3,\"n\":\"FormID\"},{\"t\":11,\"n\":\"Version Control Info 1\"},{\"t\":3,\"n\":\"Form Version\"},{\"t\":11,\"n\":\"Version Control Info 2\"}]},{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"VMAD - Virtual Machine Adapter\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Version\"},{\"t\":3,\"p\":1,\"n\":\"Object Format\"},{\"t\":12,\"p\":1,\"n\":\"Data\",\"c\":[{\"t\":9,\"p\":1,\"n\":\"Scripts\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Script\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"scriptName\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":9,\"p\":1,\"n\":\"Properties\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Property\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"propertyName\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":12,\"p\":1,\"n\":\"Value\"}]}]}]}]}]}]},{\"t\":6,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"n\":\"X1\"},{\"t\":3,\"n\":\"Y1\"},{\"t\":3,\"n\":\"Z1\"},{\"t\":3,\"n\":\"X2\"},{\"t\":3,\"n\":\"Y2\"},{\"t\":3,\"n\":\"Z2\"}]},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Icon\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"ICON - Large Icon filename\"}]},{\"t\":6,\"n\":\"Destructable\",\"c\":[{\"t\":6,\"n\":\"DEST - Header\",\"c\":[{\"t\":3,\"n\":\"Health\"},{\"t\":3,\"n\":\"DEST Count\"},{\"t\":3,\"n\":\"VATS Targetable\"},{\"t\":11,\"n\":\"Unknown\"}]}]},{\"t\":3,\"n\":\"YNAM - Sound - Pick Up\"},{\"t\":3,\"n\":\"ZNAM - Sound - Drop\"},{\"t\":3,\"n\":\"KSIZ - Keyword Count\"},{\"t\":9,\"n\":\"KWDA - Keywords\",\"c\":[{\"t\":3,\"n\":\"Keyword\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DATA - Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Value\"},{\"t\":5,\"p\":1,\"n\":\"Weight\"}]}]},{\"t\":1,\"p\":1,\"n\":\"MSTT - Moveable Static\",\"c\":[{\"t\":6,\"n\":\"Record Header\",\"c\":[{\"t\":2,\"n\":\"Signature\"},{\"t\":3,\"n\":\"Data Size\"},{\"t\":3,\"n\":\"Record Flags\"},{\"t\":3,\"n\":\"FormID\"},{\"t\":11,\"n\":\"Version Control Info 1\"},{\"t\":3,\"n\":\"Form Version\"},{\"t\":11,\"n\":\"Version Control Info 2\"}]},{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"n\":\"X1\"},{\"t\":3,\"n\":\"Y1\"},{\"t\":3,\"n\":\"Z1\"},{\"t\":3,\"n\":\"X2\"},{\"t\":3,\"n\":\"Y2\"},{\"t\":3,\"n\":\"Z2\"}]},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"}]},{\"t\":6,\"n\":\"Destructable\",\"c\":[{\"t\":6,\"n\":\"DEST - Header\",\"c\":[{\"t\":3,\"n\":\"Health\"},{\"t\":3,\"n\":\"DEST Count\"},{\"t\":3,\"n\":\"VATS Targetable\"},{\"t\":11,\"n\":\"Unknown\"}]}]},{\"t\":3,\"n\":\"DATA - Flags\"},{\"t\":3,\"p\":1,\"n\":\"SNAM - Looping Sound\"}]},{\"t\":1,\"p\":1,\"n\":\"NPC_ - Non-Player Character (Actor)\",\"c\":[{\"t\":6,\"n\":\"Record Header\",\"c\":[{\"t\":2,\"n\":\"Signature\"},{\"t\":3,\"n\":\"Data Size\"},{\"t\":3,\"n\":\"Record Flags\"},{\"t\":3,\"n\":\"FormID\"},{\"t\":11,\"n\":\"Version Control Info 1\"},{\"t\":3,\"n\":\"Form Version\"},{\"t\":11,\"n\":\"Version Control Info 2\"}]},{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"VMAD - Virtual Machine Adapter\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Version\"},{\"t\":3,\"p\":1,\"n\":\"Object Format\"},{\"t\":12,\"p\":1,\"n\":\"Data\",\"c\":[{\"t\":9,\"p\":1,\"n\":\"Scripts\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Script\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"scriptName\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":9,\"p\":1,\"n\":\"Properties\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Property\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"propertyName\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":12,\"p\":1,\"n\":\"Value\"}]}]}]}]}]}]},{\"t\":6,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"n\":\"X1\"},{\"t\":3,\"n\":\"Y1\"},{\"t\":3,\"n\":\"Z1\"},{\"t\":3,\"n\":\"X2\"},{\"t\":3,\"n\":\"Y2\"},{\"t\":3,\"n\":\"Z2\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"ACBS - Configuration\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":3,\"p\":1,\"n\":\"Magicka Offset\"},{\"t\":3,\"p\":1,\"n\":\"Stamina Offset\"},{\"t\":12,\"p\":1,\"n\":\"Level\"},{\"t\":3,\"p\":1,\"n\":\"Calc min level\"},{\"t\":3,\"p\":1,\"n\":\"Calc max level\"},{\"t\":3,\"p\":1,\"n\":\"Speed Multiplier\"},{\"t\":3,\"p\":1,\"n\":\"Disposition Base (unused)\"},{\"t\":3,\"p\":1,\"n\":\"Template Flags\"},{\"t\":3,\"p\":1,\"n\":\"Health Offset\"},{\"t\":3,\"p\":1,\"n\":\"Bleedout Override\"}]},{\"t\":10,\"s\":1,\"p\":1,\"n\":\"Factions\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"SNAM - Faction\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Faction\"},{\"t\":3,\"p\":1,\"n\":\"Rank\"},{\"t\":11,\"p\":1,\"n\":\"Unused\"}]}]},{\"t\":3,\"p\":1,\"n\":\"INAM - Death item\"},{\"t\":3,\"n\":\"VTCK - Voice\"},{\"t\":3,\"n\":\"TPLT - Template\"},{\"t\":3,\"p\":1,\"n\":\"RNAM - Race\"},{\"t\":3,\"n\":\"SPCT - Count\"},{\"t\":9,\"s\":1,\"p\":1,\"n\":\"Actor Effects\",\"d\":1,\"c\":[{\"t\":3,\"p\":1,\"n\":\"SPLO - Actor Effect\"}]},{\"t\":6,\"n\":\"Destructable\",\"c\":[{\"t\":6,\"n\":\"DEST - Header\",\"c\":[{\"t\":3,\"n\":\"Health\"},{\"t\":3,\"n\":\"DEST Count\"},{\"t\":3,\"n\":\"VATS Targetable\"},{\"t\":11,\"n\":\"Unknown\"}]}]},{\"t\":3,\"n\":\"WNAM - Worn Armor\"},{\"t\":3,\"n\":\"ANAM - Far away model\"},{\"t\":3,\"n\":\"ATKR - Attack Race\"},{\"t\":10,\"n\":\"Attacks\",\"c\":[{\"t\":6,\"n\":\"Attack\",\"c\":[{\"t\":6,\"n\":\"ATKD - Attack Data\",\"c\":[{\"t\":5,\"n\":\"Damage Mult\"},{\"t\":5,\"n\":\"Attack Chance\"},{\"t\":3,\"n\":\"Attack Spell\"},{\"t\":3,\"n\":\"Attack Flags\"},{\"t\":5,\"n\":\"Attack Angle\"},{\"t\":5,\"n\":\"Strike Angle\"},{\"t\":5,\"n\":\"Stagger\"},{\"t\":3,\"n\":\"Attack Type\"},{\"t\":5,\"n\":\"Knockdown\"},{\"t\":5,\"n\":\"Recovery Time\"},{\"t\":5,\"n\":\"Stamina Mult\"}]}]}]},{\"t\":3,\"n\":\"SPOR - Spectator override package list\"},{\"t\":3,\"n\":\"OCOR - Observe dead body override package list\"},{\"t\":3,\"n\":\"GWOR - Guard warn override package list\"},{\"t\":3,\"n\":\"ECOR - Combat override package list\"},{\"t\":3,\"n\":\"PRKZ - Perk Count\"},{\"t\":10,\"n\":\"Perks\",\"c\":[{\"t\":6,\"n\":\"PRKR - Perk\",\"c\":[{\"t\":3,\"n\":\"Perk\"},{\"t\":3,\"n\":\"Rank\"},{\"t\":11,\"n\":\"Unused\"}]}]},{\"t\":3,\"n\":\"COCT - Count\"},{\"t\":10,\"p\":1,\"n\":\"Items\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Item\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"CNTO - Item\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Item\"},{\"t\":3,\"p\":1,\"n\":\"Count\"}]}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"AIDT - AI Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Aggression\"},{\"t\":3,\"p\":1,\"n\":\"Confidence\"},{\"t\":3,\"p\":1,\"n\":\"Energy Level\"},{\"t\":3,\"p\":1,\"n\":\"Responsibility\"},{\"t\":3,\"p\":1,\"n\":\"Mood\"},{\"t\":3,\"p\":1,\"n\":\"Assistance\"},{\"t\":6,\"p\":1,\"n\":\"Aggro\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Aggro Radius Behavior\"},{\"t\":3,\"p\":1,\"n\":\"Unknown\"},{\"t\":3,\"p\":1,\"n\":\"Warn\"},{\"t\":3,\"p\":1,\"n\":\"Warn\\/Attack\"},{\"t\":3,\"p\":1,\"n\":\"Attack\"}]}]},{\"t\":7,\"s\":1,\"p\":1,\"n\":\"Packages\",\"d\":1,\"c\":[{\"t\":3,\"p\":1,\"n\":\"PKID - Package\"}]},{\"t\":3,\"n\":\"KSIZ - Keyword Count\"},{\"t\":9,\"n\":\"KWDA - Keywords\",\"c\":[{\"t\":3,\"n\":\"Keyword\"}]},{\"t\":3,\"p\":1,\"n\":\"CNAM - Class\"},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":2,\"n\":\"SHRT - Short Name\"},{\"t\":11,\"n\":\"DATA - Marker\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DNAM - Player Skills\",\"c\":[{\"t\":7,\"p\":1,\"n\":\"Skill Values\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Skill #0 (OneHanded)\"},{\"t\":3,\"p\":1,\"n\":\"Skill #1 (TwoHanded)\"},{\"t\":3,\"p\":1,\"n\":\"Skill #2 (Marksman)\"},{\"t\":3,\"p\":1,\"n\":\"Skill #3 (Block)\"},{\"t\":3,\"p\":1,\"n\":\"Skill #4 (Smithing)\"},{\"t\":3,\"p\":1,\"n\":\"Skill #5 (HeavyArmor)\"},{\"t\":3,\"p\":1,\"n\":\"Skill #6 (LightArmor)\"},{\"t\":3,\"p\":1,\"n\":\"Skill #7 (Pickpocket)\"},{\"t\":3,\"p\":1,\"n\":\"Skill #8 (Lockpicking)\"},{\"t\":3,\"p\":1,\"n\":\"Skill #9 (Sneak)\"},{\"t\":3,\"p\":1,\"n\":\"Skill #10 (Alchemy)\"},{\"t\":3,\"p\":1,\"n\":\"Skill #11 (Speechcraft)\"},{\"t\":3,\"p\":1,\"n\":\"Skill #12 (Alteration)\"},{\"t\":3,\"p\":1,\"n\":\"Skill #13 (Conjuration)\"},{\"t\":3,\"p\":1,\"n\":\"Skill #14 (Destruction)\"},{\"t\":3,\"p\":1,\"n\":\"Skill #15 (Illusion)\"},{\"t\":3,\"p\":1,\"n\":\"Skill #16 (Restoration)\"},{\"t\":3,\"p\":1,\"n\":\"Skill #17 (Enchanting)\"}]},{\"t\":7,\"p\":1,\"n\":\"Skill Offsets\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Skill #0 (OneHanded)\"},{\"t\":3,\"p\":1,\"n\":\"Skill #1 (TwoHanded)\"},{\"t\":3,\"p\":1,\"n\":\"Skill #2 (Marksman)\"},{\"t\":3,\"p\":1,\"n\":\"Skill #3 (Block)\"},{\"t\":3,\"p\":1,\"n\":\"Skill #4 (Smithing)\"},{\"t\":3,\"p\":1,\"n\":\"Skill #5 (HeavyArmor)\"},{\"t\":3,\"p\":1,\"n\":\"Skill #6 (LightArmor)\"},{\"t\":3,\"p\":1,\"n\":\"Skill #7 (Pickpocket)\"},{\"t\":3,\"p\":1,\"n\":\"Skill #8 (Lockpicking)\"},{\"t\":3,\"p\":1,\"n\":\"Skill #9 (Sneak)\"},{\"t\":3,\"p\":1,\"n\":\"Skill #10 (Alchemy)\"},{\"t\":3,\"p\":1,\"n\":\"Skill #11 (Speechcraft)\"},{\"t\":3,\"p\":1,\"n\":\"Skill #12 (Alteration)\"},{\"t\":3,\"p\":1,\"n\":\"Skill #13 (Conjuration)\"},{\"t\":3,\"p\":1,\"n\":\"Skill #14 (Destruction)\"},{\"t\":3,\"p\":1,\"n\":\"Skill #15 (Illusion)\"},{\"t\":3,\"p\":1,\"n\":\"Skill #16 (Restoration)\"},{\"t\":3,\"p\":1,\"n\":\"Skill #17 (Enchanting)\"}]},{\"t\":3,\"p\":1,\"n\":\"Health\"},{\"t\":3,\"p\":1,\"n\":\"Magicka\"},{\"t\":3,\"p\":1,\"n\":\"Stamina\"},{\"t\":11,\"p\":1,\"n\":\"Unused\"},{\"t\":5,\"p\":1,\"n\":\"Far away model distance\"},{\"t\":3,\"p\":1,\"n\":\"Geared up weapons\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":9,\"s\":1,\"p\":1,\"n\":\"Head Parts\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"PNAM - Head Part\"}],\"lt\":\"HCLF - Hair Color\",\"lf\":\"QNAM - Texture lighting\"},{\"t\":3,\"p\":1,\"n\":\"HCLF - Hair Color\",\"lt\":\"FTST - Head texture\",\"lf\":\"Head Parts\"},{\"t\":3,\"p\":1,\"n\":\"ZNAM - Combat Style\"},{\"t\":3,\"n\":\"GNAM - Gift Filter\"},{\"t\":11,\"n\":\"NAM5 - Unknown\"},{\"t\":5,\"n\":\"NAM6 - Height\"},{\"t\":5,\"n\":\"NAM7 - Weight\"},{\"t\":3,\"n\":\"NAM8 - Sound Level\"},{\"t\":10,\"n\":\"Sound Types\",\"c\":[{\"t\":6,\"n\":\"Sound Type\",\"c\":[{\"t\":3,\"n\":\"CSDT - Type\"},{\"t\":10,\"n\":\"Sounds\",\"c\":[{\"t\":6,\"n\":\"Sound\",\"c\":[{\"t\":3,\"n\":\"CSDI - Sound\"},{\"t\":3,\"n\":\"CSDC - Sound Chance\"}]}]}]}]},{\"t\":3,\"n\":\"CSCR - Inherits Sounds From\"},{\"t\":3,\"n\":\"DOFT - Default outfit\"},{\"t\":3,\"n\":\"SOFT - Sleeping outfit\"},{\"t\":3,\"n\":\"DPLT - Default Package List\"},{\"t\":3,\"n\":\"CRIF - Crime faction\"},{\"t\":3,\"p\":1,\"n\":\"FTST - Head texture\",\"lt\":\"Tint Layers\",\"lf\":\"HCLF - Hair Color\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"QNAM - Texture lighting\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Red\"},{\"t\":5,\"p\":1,\"n\":\"Green\"},{\"t\":5,\"p\":1,\"n\":\"Blue\"}],\"lt\":\"Head Parts\",\"lf\":\"NAM9 - Face morph\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"NAM9 - Face morph\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Nose Long\\/Short\"},{\"t\":5,\"p\":1,\"n\":\"Nose Up\\/Down\"},{\"t\":5,\"p\":1,\"n\":\"Jaw Up\\/Down\"},{\"t\":5,\"p\":1,\"n\":\"Jaw Narrow\\/Wide\"},{\"t\":5,\"p\":1,\"n\":\"Jaw Farward\\/Back\"},{\"t\":5,\"p\":1,\"n\":\"Cheeks Up\\/Down\"},{\"t\":5,\"p\":1,\"n\":\"Cheeks Farward\\/Back\"},{\"t\":5,\"p\":1,\"n\":\"Eyes Up\\/Down\"},{\"t\":5,\"p\":1,\"n\":\"Eyes In\\/Out\"},{\"t\":5,\"p\":1,\"n\":\"Brows Up\\/Down\"},{\"t\":5,\"p\":1,\"n\":\"Brows In\\/Out\"},{\"t\":5,\"p\":1,\"n\":\"Brows Farward\\/Back\"},{\"t\":5,\"p\":1,\"n\":\"Lips Up\\/Down\"},{\"t\":5,\"p\":1,\"n\":\"Lips In\\/Out\"},{\"t\":5,\"p\":1,\"n\":\"Chin Narrow\\/Wide\"},{\"t\":5,\"p\":1,\"n\":\"Chin Up\\/Down\"},{\"t\":5,\"p\":1,\"n\":\"Chin Underbite\\/Overbite\"},{\"t\":5,\"p\":1,\"n\":\"Eyes Farward\\/Back\"},{\"t\":5,\"p\":1,\"n\":\"Unknown\"}],\"lt\":\"QNAM - Texture lighting\",\"lf\":\"NAMA - Face parts\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"NAMA - Face parts\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Nose\"},{\"t\":3,\"p\":1,\"n\":\"Unknown\"},{\"t\":3,\"p\":1,\"n\":\"Eyes\"},{\"t\":3,\"p\":1,\"n\":\"Mouth\"}],\"lt\":\"NAM9 - Face morph\",\"lf\":\"Tint Layers\"},{\"t\":10,\"s\":1,\"p\":1,\"n\":\"Tint Layers\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Layer\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"TINI - Tint Index\"}]}],\"lt\":\"NAMA - Face parts\",\"lf\":\"FTST - Head texture\"}]},{\"t\":1,\"p\":1,\"n\":\"PACK - Package\",\"c\":[{\"t\":6,\"n\":\"Record Header\",\"c\":[{\"t\":2,\"n\":\"Signature\"},{\"t\":3,\"n\":\"Data Size\"},{\"t\":3,\"n\":\"Record Flags\"},{\"t\":3,\"n\":\"FormID\"},{\"t\":11,\"n\":\"Version Control Info 1\"},{\"t\":3,\"n\":\"Form Version\"},{\"t\":11,\"n\":\"Version Control Info 2\"}]},{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"VMAD - Virtual Machine Adapter\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Version\"},{\"t\":3,\"p\":1,\"n\":\"Object Format\"},{\"t\":12,\"p\":1,\"n\":\"Data\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Pack VMAD\",\"c\":[{\"t\":9,\"p\":1,\"n\":\"Scripts\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Script\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"scriptName\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":9,\"p\":1,\"n\":\"Properties\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Property\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"propertyName\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":12,\"p\":1,\"n\":\"Value\"}]}]}]}]},{\"t\":6,\"p\":1,\"n\":\"Script Fragments Package\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Unknown\"},{\"t\":3,\"p\":1,\"n\":\"Package Fragments Flags\"},{\"t\":2,\"p\":1,\"n\":\"fileName\"},{\"t\":7,\"p\":1,\"n\":\"Package Fragments\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Package Fragment #0\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Unknown\"},{\"t\":2,\"p\":1,\"n\":\"scriptName\"},{\"t\":2,\"p\":1,\"n\":\"fragmentName\"}]}]}]}]}]}]},{\"t\":6,\"n\":\"PKDT - Pack Data\",\"c\":[{\"t\":3,\"n\":\"General Flags\"},{\"t\":3,\"n\":\"Type\"},{\"t\":3,\"n\":\"Interrupt Override\"},{\"t\":3,\"n\":\"Preferred Speed\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":3,\"n\":\"Interrupt Flags\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":6,\"n\":\"PSDT - Schedule\",\"c\":[{\"t\":3,\"n\":\"Month\"},{\"t\":3,\"n\":\"Day of week\"},{\"t\":3,\"n\":\"Date\"},{\"t\":3,\"n\":\"Hour\"},{\"t\":3,\"n\":\"Minute\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":3,\"n\":\"Duration (minutes)\"}]},{\"t\":8,\"n\":\"Conditions\",\"c\":[{\"t\":6,\"n\":\"Condition\",\"c\":[{\"t\":6,\"n\":\"CTDA - \",\"c\":[{\"t\":3,\"n\":\"Type\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":12,\"n\":\"Comparison Value\"},{\"t\":3,\"n\":\"Function\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":12,\"n\":\"Parameter #1\"},{\"t\":12,\"n\":\"Parameter #2\"},{\"t\":3,\"n\":\"Run On\"},{\"t\":12,\"n\":\"Reference\"},{\"t\":3,\"n\":\"Parameter #3\"}]}]}]},{\"t\":6,\"n\":\"Idle Animations\",\"c\":[{\"t\":3,\"n\":\"IDLF - Flags\"},{\"t\":6,\"n\":\"IDLC - \",\"c\":[{\"t\":3,\"n\":\"Animation Count\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":5,\"n\":\"IDLT - Idle Timer Setting\"},{\"t\":7,\"n\":\"IDLA - Animations\",\"c\":[{\"t\":3,\"n\":\"Animation #0\"}]}]},{\"t\":3,\"n\":\"CNAM - Combat Style\"},{\"t\":3,\"n\":\"QNAM - Owner Quest\"},{\"t\":6,\"n\":\"PKCU - Counter\",\"c\":[{\"t\":3,\"n\":\"Data Input Count\"},{\"t\":3,\"n\":\"Package Template\"},{\"t\":3,\"n\":\"Version Counter (autoincremented)\"}]},{\"t\":6,\"n\":\"Package Data\",\"c\":[{\"t\":8,\"n\":\"Data Input Values\",\"c\":[{\"t\":6,\"n\":\"Value\",\"c\":[{\"t\":2,\"n\":\"ANAM - Type\"}]}]}]},{\"t\":11,\"n\":\"XNAM - Marker\"},{\"t\":6,\"n\":\"Procedure Tree\",\"c\":[{\"t\":8,\"n\":\"Branches\",\"c\":[{\"t\":6,\"n\":\"Branch\",\"c\":[{\"t\":2,\"n\":\"ANAM - Branch Type\"}]}]}]},{\"t\":8,\"n\":\"Data Inputs\",\"c\":[{\"t\":6,\"n\":\"Data Input\",\"c\":[{\"t\":3,\"n\":\"UNAM - Index\"}]}]},{\"t\":6,\"n\":\"OnBegin\",\"c\":[{\"n\":\"POBA - OnBegin Marker\"},{\"t\":3,\"n\":\"INAM - Idle\"}]},{\"t\":6,\"n\":\"OnEnd\",\"c\":[{\"n\":\"POEA - OnEnd Marker\"},{\"t\":3,\"n\":\"INAM - Idle\"}]},{\"t\":6,\"n\":\"OnChange\",\"c\":[{\"n\":\"POCA - OnChange Marker\"},{\"t\":3,\"n\":\"INAM - Idle\"}]}]},{\"t\":1,\"p\":1,\"n\":\"PERK - Perk\",\"c\":[{\"t\":6,\"n\":\"Record Header\",\"c\":[{\"t\":2,\"n\":\"Signature\"},{\"t\":3,\"n\":\"Data Size\"},{\"t\":3,\"n\":\"Record Flags\"},{\"t\":3,\"n\":\"FormID\"},{\"t\":11,\"n\":\"Version Control Info 1\"},{\"t\":3,\"n\":\"Form Version\"},{\"t\":11,\"n\":\"Version Control Info 2\"}]},{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"VMAD - Virtual Machine Adapter\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Version\"},{\"t\":3,\"p\":1,\"n\":\"Object Format\"},{\"t\":12,\"p\":1,\"n\":\"Data\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Perk VMAD\",\"c\":[{\"t\":9,\"p\":1,\"n\":\"Scripts\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Script\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"scriptName\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":9,\"p\":1,\"n\":\"Properties\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Property\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"propertyName\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":12,\"p\":1,\"n\":\"Value\"}]}]}]}]},{\"t\":6,\"p\":1,\"n\":\"Script Fragments Perk\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Unknown\"},{\"t\":2,\"p\":1,\"n\":\"fileName\"},{\"t\":9,\"p\":1,\"n\":\"Perk Fragments\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Perk Fragment\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Fragment Index\"},{\"t\":3,\"p\":1,\"n\":\"Unknown\"},{\"t\":3,\"n\":\"Unknown\"},{\"t\":2,\"p\":1,\"n\":\"scriptName\"},{\"t\":2,\"p\":1,\"n\":\"fragmentName\"}]}]}]}]}]}]},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":2,\"n\":\"DESC - Description\"},{\"t\":6,\"n\":\"Icon\",\"c\":[{\"t\":2,\"n\":\"ICON - Large Icon filename\"}]},{\"t\":8,\"n\":\"Conditions\",\"c\":[{\"t\":6,\"n\":\"Condition\",\"c\":[{\"t\":6,\"n\":\"CTDA - \",\"c\":[{\"t\":3,\"n\":\"Type\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":12,\"n\":\"Comparison Value\"},{\"t\":3,\"n\":\"Function\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":12,\"n\":\"Parameter #1\"},{\"t\":12,\"n\":\"Parameter #2\"},{\"t\":3,\"n\":\"Run On\"},{\"t\":12,\"n\":\"Reference\"},{\"t\":3,\"n\":\"Parameter #3\"}]}]}]},{\"t\":6,\"n\":\"DATA - Data\",\"c\":[{\"t\":3,\"n\":\"Trait\"},{\"t\":3,\"n\":\"Level\"},{\"t\":3,\"n\":\"Num Ranks\"},{\"t\":3,\"n\":\"Playable\"},{\"t\":3,\"n\":\"Hidden\"}]},{\"t\":3,\"n\":\"NNAM - Next Perk\"},{\"t\":10,\"n\":\"Effects\",\"c\":[{\"t\":6,\"n\":\"Effect\",\"c\":[{\"t\":6,\"n\":\"PRKE - Header\",\"c\":[{\"t\":3,\"n\":\"Type\"},{\"t\":3,\"n\":\"Rank\"},{\"t\":3,\"n\":\"Priority\"}]},{\"t\":12,\"n\":\"DATA - Effect Data\",\"c\":[{\"t\":6,\"n\":\"Quest + Stage\",\"c\":[{\"t\":3,\"n\":\"Quest\"},{\"t\":3,\"n\":\"Quest Stage\"},{\"t\":11,\"n\":\"Unused\"}]}]},{\"n\":\"PRKF - End Marker\"}]}]}]},{\"t\":1,\"p\":1,\"n\":\"PHZD - Placed Hazard\",\"c\":[{\"t\":3,\"n\":\"Cell\"},{\"t\":6,\"n\":\"Record Header\",\"c\":[{\"t\":2,\"n\":\"Signature\"},{\"t\":3,\"n\":\"Data Size\"},{\"t\":3,\"n\":\"Record Flags\"},{\"t\":3,\"n\":\"FormID\"},{\"t\":11,\"n\":\"Version Control Info 1\"},{\"t\":3,\"n\":\"Form Version\"},{\"t\":11,\"n\":\"Version Control Info 2\"}]},{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"VMAD - Virtual Machine Adapter\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Version\"},{\"t\":3,\"p\":1,\"n\":\"Object Format\"},{\"t\":12,\"p\":1,\"n\":\"Data\",\"c\":[{\"t\":9,\"p\":1,\"n\":\"Scripts\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Script\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"scriptName\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":9,\"p\":1,\"n\":\"Properties\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Property\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"propertyName\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":12,\"p\":1,\"n\":\"Value\"}]}]}]}]}]}]},{\"t\":3,\"n\":\"NAME - Projectile\"},{\"t\":3,\"n\":\"XEZN - Encounter Zone\"},{\"t\":6,\"n\":\"Ownership\",\"c\":[{\"t\":3,\"n\":\"XOWN - Owner\"}]},{\"t\":5,\"n\":\"XHTW - Head-Tracking Weight\"},{\"t\":5,\"n\":\"XFVC - Favor Cost\"},{\"t\":10,\"n\":\"Reflected\\/Refracted By\",\"c\":[{\"t\":6,\"n\":\"XPWR - Water\",\"c\":[{\"t\":3,\"n\":\"Reference\"},{\"t\":3,\"n\":\"Type\"}]}]},{\"t\":10,\"n\":\"Linked References\",\"c\":[{\"t\":6,\"n\":\"XLKR - Linked Reference\",\"c\":[{\"t\":3,\"n\":\"Keyword\\/Ref\"},{\"t\":3,\"n\":\"Ref\"}]}]},{\"t\":6,\"n\":\"Activate Parents\",\"c\":[{\"t\":3,\"n\":\"XAPD - Flags\"}]},{\"t\":6,\"n\":\"XESP - Enable Parent\",\"c\":[{\"t\":3,\"n\":\"Reference\"},{\"t\":3,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":3,\"n\":\"XEMI - Emittance\"},{\"t\":3,\"n\":\"XMBR - MultiBound Reference\"},{\"n\":\"XIS2 - Ignored by Sandbox\"},{\"t\":7,\"n\":\"XLRT - Location Ref Type\",\"c\":[{\"t\":3,\"n\":\"Ref #0\"}]},{\"t\":3,\"n\":\"XLRL - Location Reference\"},{\"t\":7,\"n\":\"XLOD - Distant LOD Data\",\"c\":[{\"t\":5,\"n\":\"Unknown #0\"},{\"t\":5,\"n\":\"Unknown #1\"},{\"t\":5,\"n\":\"Unknown #2\"}]},{\"t\":5,\"n\":\"XSCL - Scale\"},{\"t\":6,\"n\":\"DATA - Position\\/Rotation\",\"c\":[{\"t\":6,\"n\":\"Position\",\"c\":[{\"t\":5,\"n\":\"X\"},{\"t\":5,\"n\":\"Y\"},{\"t\":5,\"n\":\"Z\"}]},{\"t\":6,\"n\":\"Rotation\",\"c\":[{\"t\":5,\"n\":\"X\"},{\"t\":5,\"n\":\"Y\"},{\"t\":5,\"n\":\"Z\"}]}]}]},{\"t\":1,\"p\":1,\"n\":\"PROJ - Projectile\",\"c\":[{\"t\":6,\"n\":\"Record Header\",\"c\":[{\"t\":2,\"n\":\"Signature\"},{\"t\":3,\"n\":\"Data Size\"},{\"t\":3,\"n\":\"Record Flags\"},{\"t\":3,\"n\":\"FormID\"},{\"t\":11,\"n\":\"Version Control Info 1\"},{\"t\":3,\"n\":\"Form Version\"},{\"t\":11,\"n\":\"Version Control Info 2\"}]},{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"n\":\"X1\"},{\"t\":3,\"n\":\"Y1\"},{\"t\":3,\"n\":\"Z1\"},{\"t\":3,\"n\":\"X2\"},{\"t\":3,\"n\":\"Y2\"},{\"t\":3,\"n\":\"Z2\"}]},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"}]},{\"t\":6,\"n\":\"Destructable\",\"c\":[{\"t\":6,\"n\":\"DEST - Header\",\"c\":[{\"t\":3,\"n\":\"Health\"},{\"t\":3,\"n\":\"DEST Count\"},{\"t\":3,\"n\":\"VATS Targetable\"},{\"t\":11,\"n\":\"Unknown\"}]}]},{\"t\":6,\"p\":1,\"n\":\"DATA - Data\",\"c\":[{\"t\":3,\"n\":\"Flags\"},{\"t\":3,\"n\":\"Type\"},{\"t\":5,\"p\":1,\"n\":\"Gravity\",\"lt\":\"Range\",\"lf\":\"Speed\"},{\"t\":5,\"p\":1,\"n\":\"Speed\",\"lt\":\"Gravity\",\"lf\":\"Range\"},{\"t\":5,\"p\":1,\"n\":\"Range\",\"lt\":\"Speed\",\"lf\":\"Gravity\"},{\"t\":3,\"n\":\"Light\"},{\"t\":3,\"n\":\"Muzzle Flash - Light\"},{\"t\":5,\"n\":\"Tracer Chance\"},{\"t\":5,\"n\":\"Explosion - Alt. Trigger - Proximity\"},{\"t\":5,\"n\":\"Explosion - Alt. Trigger - Timer\"},{\"t\":3,\"n\":\"Explosion\"},{\"t\":3,\"n\":\"Sound\"},{\"t\":5,\"n\":\"Muzzle Flash - Duration\"},{\"t\":5,\"n\":\"Fade Duration\"},{\"t\":5,\"n\":\"Impact Force\"},{\"t\":3,\"n\":\"Sound - Countdown\"},{\"t\":3,\"n\":\"Sound - Disable\"},{\"t\":3,\"n\":\"Default Weapon Source\"},{\"t\":5,\"n\":\"Cone Spread\"},{\"t\":5,\"n\":\"Collision Radius\"},{\"t\":5,\"n\":\"Lifetime\"},{\"t\":5,\"n\":\"Relaunch Interval\"},{\"t\":3,\"n\":\"Decal Data\"},{\"t\":3,\"n\":\"Collision Layer\"}]},{\"t\":6,\"n\":\"Muzzle Flash Model\",\"c\":[{\"t\":2,\"n\":\"NAM1 - Model Filename\"}]},{\"t\":3,\"n\":\"VNAM - Sound Level\"}]},{\"t\":1,\"p\":1,\"n\":\"QUST - Quest\",\"c\":[{\"t\":6,\"n\":\"Record Header\",\"c\":[{\"t\":2,\"n\":\"Signature\"},{\"t\":3,\"n\":\"Data Size\"},{\"t\":3,\"n\":\"Record Flags\"},{\"t\":3,\"n\":\"FormID\"},{\"t\":11,\"n\":\"Version Control Info 1\"},{\"t\":3,\"n\":\"Form Version\"},{\"t\":11,\"n\":\"Version Control Info 2\"}]},{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"VMAD - Virtual Machine Adapter\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Version\"},{\"t\":3,\"p\":1,\"n\":\"Object Format\"},{\"t\":12,\"p\":1,\"n\":\"Data\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Quest VMAD\",\"c\":[{\"t\":9,\"p\":1,\"n\":\"Scripts\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Script\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"scriptName\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":9,\"p\":1,\"n\":\"Properties\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Property\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"propertyName\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":12,\"p\":1,\"n\":\"Value\"}]}]}]}]},{\"t\":6,\"p\":1,\"n\":\"Script Fragments Quest\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Unknown\"},{\"t\":3,\"p\":1,\"n\":\"fragmentCount\"},{\"t\":2,\"p\":1,\"n\":\"fileName\"},{\"t\":9,\"p\":1,\"n\":\"Quest Fragments\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Quest Fragment\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Quest Stage\"},{\"t\":3,\"p\":1,\"n\":\"Unknown\"},{\"t\":3,\"p\":1,\"n\":\"Quest Stage Index\"},{\"t\":3,\"n\":\"Unknown\"},{\"t\":2,\"p\":1,\"n\":\"scriptName\"},{\"t\":2,\"p\":1,\"n\":\"fragmentName\"}]}]},{\"t\":9,\"p\":1,\"n\":\"Aliases\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alias\",\"c\":[{\"t\":12,\"p\":1,\"n\":\"Object Union\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"Unused\"}]}]},{\"t\":3,\"p\":1,\"n\":\"Version\"},{\"t\":3,\"p\":1,\"n\":\"Object Format\"},{\"t\":9,\"p\":1,\"n\":\"Alias Scripts\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Script\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"scriptName\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":9,\"p\":1,\"n\":\"Properties\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Property\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"propertyName\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":12,\"p\":1,\"n\":\"Value\"}]}]}]}]}]}]}]}]}]}]},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":6,\"n\":\"DNAM - General\",\"c\":[{\"t\":3,\"n\":\"Flags\"},{\"t\":3,\"n\":\"Priority\"},{\"t\":3,\"n\":\"Form Version\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":3,\"n\":\"Type\"}]},{\"t\":2,\"n\":\"ENAM - Event\"},{\"t\":7,\"n\":\"Text Display Globals\",\"c\":[{\"t\":3,\"n\":\"QTGL - Global\"}]},{\"t\":2,\"n\":\"FLTR - Object Window Filter\"},{\"t\":6,\"n\":\"Quest Dialogue Conditions\",\"c\":[{\"t\":8,\"n\":\"Conditions\",\"c\":[{\"t\":6,\"n\":\"Condition\",\"c\":[{\"t\":6,\"n\":\"CTDA - \",\"c\":[{\"t\":3,\"n\":\"Type\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":12,\"n\":\"Comparison Value\"},{\"t\":3,\"n\":\"Function\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":12,\"n\":\"Parameter #1\"},{\"t\":12,\"n\":\"Parameter #2\"},{\"t\":3,\"n\":\"Run On\"},{\"t\":12,\"n\":\"Reference\"},{\"t\":3,\"n\":\"Parameter #3\"}]}]}]}]},{\"n\":\"NEXT - Marker\"},{\"t\":8,\"n\":\"Conditions\",\"c\":[{\"t\":6,\"n\":\"Condition\",\"c\":[{\"t\":6,\"n\":\"CTDA - \",\"c\":[{\"t\":3,\"n\":\"Type\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":12,\"n\":\"Comparison Value\"},{\"t\":3,\"n\":\"Function\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":12,\"n\":\"Parameter #1\"},{\"t\":12,\"n\":\"Parameter #2\"},{\"t\":3,\"n\":\"Run On\"},{\"t\":12,\"n\":\"Reference\"},{\"t\":3,\"n\":\"Parameter #3\"}]}]}]},{\"t\":10,\"n\":\"Stages\",\"c\":[{\"t\":6,\"n\":\"Stage\",\"c\":[{\"t\":6,\"n\":\"INDX - Stage Index\",\"c\":[{\"t\":3,\"n\":\"Stage Index\"},{\"t\":3,\"n\":\"Flags\"},{\"t\":3,\"n\":\"Unknown\"}]}]}]},{\"t\":8,\"n\":\"Objectives\",\"c\":[{\"t\":6,\"n\":\"Objective\",\"c\":[{\"t\":3,\"n\":\"QOBJ - Objective Index\"},{\"t\":2,\"n\":\"NNAM - Display Text\"}]}]},{\"t\":11,\"n\":\"ANAM - Aliases Marker\"},{\"t\":8,\"n\":\"Aliases\",\"c\":[{\"t\":6,\"n\":\"Alias\",\"c\":[{\"t\":3,\"n\":\"ALST - Reference Alias ID\"},{\"n\":\"ALED - Alias End\"}]}]},{\"t\":2,\"n\":\"NNAM - Description\"},{\"t\":8,\"n\":\"Targets\",\"c\":[{\"t\":6,\"n\":\"Target\",\"c\":[{\"t\":6,\"n\":\"QSTA - Target\",\"c\":[{\"t\":3,\"n\":\"Target\"},{\"t\":3,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unknown\"}]}]}]}]},{\"t\":1,\"p\":1,\"n\":\"RACE - Race\",\"c\":[{\"t\":6,\"n\":\"Record Header\",\"c\":[{\"t\":2,\"n\":\"Signature\"},{\"t\":3,\"n\":\"Data Size\"},{\"t\":3,\"n\":\"Record Flags\"},{\"t\":3,\"n\":\"FormID\"},{\"t\":11,\"n\":\"Version Control Info 1\"},{\"t\":3,\"n\":\"Form Version\"},{\"t\":11,\"n\":\"Version Control Info 2\"}]},{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":2,\"p\":1,\"n\":\"DESC - Description\"},{\"t\":3,\"n\":\"SPCT - Count\"},{\"t\":9,\"s\":1,\"p\":1,\"n\":\"Actor Effects\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"SPLO - Actor Effect\"}]},{\"t\":3,\"n\":\"WNAM - Skin\"},{\"t\":6,\"n\":\"BOD2 - Biped Body Template\",\"c\":[{\"t\":3,\"n\":\"First Person Flags\"},{\"t\":3,\"n\":\"General Flags\"},{\"n\":\"Unused\"},{\"t\":3,\"n\":\"Armor Type\"}]},{\"t\":3,\"n\":\"KSIZ - Keyword Count\"},{\"t\":9,\"n\":\"KWDA - Keywords\",\"c\":[{\"t\":3,\"n\":\"Keyword\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DATA - \",\"c\":[{\"t\":10,\"p\":1,\"n\":\"Skill Boosts\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Skill Boost\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Skill\"},{\"t\":3,\"p\":1,\"n\":\"Boost\"}]},{\"t\":6,\"n\":\"Skill Boost\",\"c\":[{\"t\":3,\"n\":\"Skill\"},{\"t\":3,\"n\":\"Boost\"}]},{\"t\":6,\"n\":\"Skill Boost\",\"c\":[{\"t\":3,\"n\":\"Skill\"},{\"t\":3,\"n\":\"Boost\"}]},{\"t\":6,\"n\":\"Skill Boost\",\"c\":[{\"t\":3,\"n\":\"Skill\"},{\"t\":3,\"n\":\"Boost\"}]},{\"t\":6,\"n\":\"Skill Boost\",\"c\":[{\"t\":3,\"n\":\"Skill\"},{\"t\":3,\"n\":\"Boost\"}]},{\"t\":6,\"n\":\"Skill Boost\",\"c\":[{\"t\":3,\"n\":\"Skill\"},{\"t\":3,\"n\":\"Boost\"}]},{\"t\":6,\"n\":\"Skill Boost\",\"c\":[{\"t\":3,\"n\":\"Skill\"},{\"t\":3,\"n\":\"Boost\"}]}]},{\"t\":11,\"p\":1,\"n\":\"Unknown\"},{\"t\":5,\"p\":1,\"n\":\"Male Height\"},{\"t\":5,\"p\":1,\"n\":\"Female Height\"},{\"t\":5,\"p\":1,\"n\":\"Male Weight\"},{\"t\":5,\"p\":1,\"n\":\"Female Weight\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":5,\"p\":1,\"n\":\"Starting Health\"},{\"t\":5,\"p\":1,\"n\":\"Starting Magicka\"},{\"t\":5,\"p\":1,\"n\":\"Starting Stamina\"},{\"t\":5,\"p\":1,\"n\":\"Base Carry Weight\"},{\"t\":5,\"p\":1,\"n\":\"Base Mass\"},{\"t\":5,\"p\":1,\"n\":\"Acceleration rate\"},{\"t\":5,\"p\":1,\"n\":\"Deceleration rate\"},{\"t\":3,\"p\":1,\"n\":\"Size\"},{\"t\":3,\"p\":1,\"n\":\"Head Biped Object\"},{\"t\":3,\"p\":1,\"n\":\"Hair Biped Object\"},{\"t\":5,\"p\":1,\"n\":\"Injured Health Pct\"},{\"t\":3,\"p\":1,\"n\":\"Shield Biped Object\"},{\"t\":5,\"p\":1,\"n\":\"Health Regen\"},{\"t\":5,\"p\":1,\"n\":\"Magicka Regen\"},{\"t\":5,\"p\":1,\"n\":\"Stamina Regen\"},{\"t\":5,\"p\":1,\"n\":\"Unarmed Damage\"},{\"t\":5,\"p\":1,\"n\":\"Unarmed Reach\"},{\"t\":3,\"p\":1,\"n\":\"Body Biped Object\"},{\"t\":5,\"p\":1,\"n\":\"Aim Angle Tolerance\"},{\"t\":5,\"p\":1,\"n\":\"Flight Radius\"},{\"t\":5,\"p\":1,\"n\":\"Angular Acceleration Rate\"},{\"t\":5,\"p\":1,\"n\":\"Angular Tolerance\"},{\"t\":3,\"p\":1,\"n\":\"Flags 2\"},{\"t\":6,\"p\":1,\"n\":\"Mount Data\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Offset X\"},{\"t\":5,\"p\":1,\"n\":\"Offset Y\"},{\"t\":5,\"p\":1,\"n\":\"Unknown\"},{\"t\":5,\"n\":\"Unknown\"},{\"t\":5,\"n\":\"Unknown\"},{\"t\":5,\"n\":\"Unknown\"},{\"t\":5,\"n\":\"Unknown\"},{\"t\":5,\"n\":\"Unknown\"},{\"t\":5,\"n\":\"Unknown\"}]}]},{\"n\":\"MNAM - Male Marker\"},{\"t\":2,\"n\":\"ANAM - Male Skeletal Model\"},{\"t\":11,\"n\":\"MODT - Texture Files Hashes\"},{\"n\":\"FNAM - Female Marker\"},{\"t\":2,\"n\":\"ANAM - Female Skeletal Model\"},{\"t\":11,\"n\":\"MODT - Texture Files Hashes\"},{\"n\":\"NAM2 - Marker NAM2 #1\"},{\"t\":9,\"n\":\"Movement Type Names\",\"c\":[{\"t\":2,\"n\":\"MTNM - Name\"}]},{\"t\":7,\"p\":1,\"n\":\"VTCK - Voices\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Voice #0 (Male)\"},{\"t\":3,\"p\":1,\"n\":\"Voice #1 (Female)\"}]},{\"t\":7,\"n\":\"DNAM - Decapitate Armors\",\"c\":[{\"t\":3,\"n\":\"Decapitate Armor #0 (Male)\"},{\"t\":3,\"n\":\"Decapitate Armor #1 (Female)\"}]},{\"t\":7,\"n\":\"HCLF - Default Hair Colors\",\"c\":[{\"t\":3,\"n\":\"Default Hair Color #0 (Male)\"},{\"t\":3,\"n\":\"Default Hair Color #1 (Female)\"}]},{\"t\":3,\"n\":\"TINL - Total Number of Tints in List\"},{\"t\":5,\"n\":\"PNAM - FaceGen - Main clamp\"},{\"t\":5,\"n\":\"UNAM - FaceGen - Face clamp\"},{\"t\":3,\"n\":\"ATKR - Attack Race\"},{\"t\":10,\"n\":\"Attacks\",\"c\":[{\"t\":6,\"n\":\"Attack\",\"c\":[{\"t\":6,\"n\":\"ATKD - Attack Data\",\"c\":[{\"t\":5,\"n\":\"Damage Mult\"},{\"t\":5,\"n\":\"Attack Chance\"},{\"t\":3,\"n\":\"Attack Spell\"},{\"t\":3,\"n\":\"Attack Flags\"},{\"t\":5,\"n\":\"Attack Angle\"},{\"t\":5,\"n\":\"Strike Angle\"},{\"t\":5,\"n\":\"Stagger\"},{\"t\":3,\"n\":\"Attack Type\"},{\"t\":5,\"n\":\"Knockdown\"},{\"t\":5,\"n\":\"Recovery Time\"},{\"t\":5,\"n\":\"Stamina Mult\"}]}]}]},{\"t\":6,\"p\":1,\"n\":\"Body Data\",\"c\":[{\"n\":\"NAM1 - Body Data Marker\"},{\"t\":6,\"p\":1,\"n\":\"Male Body Data\",\"c\":[{\"n\":\"MNAM - Male Data Marker\"},{\"t\":10,\"s\":1,\"p\":1,\"n\":\"Parts\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Part\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"INDX - Index\"}]}]}]},{\"t\":6,\"p\":1,\"n\":\"Female Body Data\",\"c\":[{\"n\":\"FNAM - Female Data Marker\"},{\"t\":10,\"s\":1,\"p\":1,\"n\":\"Parts\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Part\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"INDX - Index\"}]}]}]}]},{\"t\":9,\"p\":1,\"n\":\"HNAM - Hairs\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Hair\"}]},{\"t\":9,\"p\":1,\"n\":\"ENAM - Eyes\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Eye\"}]},{\"t\":3,\"n\":\"GNAM - Body Part Data\"},{\"n\":\"NAM2 - Marker NAM2 #2\"},{\"n\":\"NAM3 - Marker NAM3 #3\"},{\"t\":6,\"n\":\"Male Behavior Graph\",\"c\":[{\"n\":\"MNAM - Male Data Marker\"}]},{\"t\":6,\"n\":\"Female Behavior Graph\",\"c\":[{\"n\":\"FNAM - Female Data Marker\"}]},{\"t\":3,\"n\":\"NAM4 - Material Type\"},{\"t\":3,\"n\":\"NAM5 - Impact Data Set\"},{\"t\":3,\"n\":\"NAM7 - Decapitation FX\"},{\"t\":3,\"p\":1,\"n\":\"ONAM - Open Loot Sound\"},{\"t\":3,\"p\":1,\"n\":\"LNAM - Close Loot Sound\"},{\"t\":7,\"n\":\"Biped Object Names\",\"c\":[{\"t\":2,\"n\":\"NAME - Name\"}]},{\"t\":10,\"n\":\"Movement Types\",\"c\":[{\"t\":6,\"n\":\"Movement Types\",\"c\":[{\"t\":3,\"n\":\"MTYP - Movement Type\"}]}]},{\"t\":3,\"n\":\"VNAM - Equipment Flags\"},{\"t\":9,\"n\":\"Equip Slots\",\"c\":[{\"t\":3,\"n\":\"QNAM - Equip Slot\"}]},{\"t\":3,\"n\":\"UNES - Unarmed Equip Slot\"},{\"t\":7,\"n\":\"Phoneme Target Names\",\"c\":[{\"t\":2,\"n\":\"PHTN - Name\"}]},{\"t\":6,\"n\":\"FaceFX Phonemes\",\"c\":[{\"t\":6,\"n\":\"IY\",\"c\":[{\"t\":6,\"n\":\"PHWT - Phoneme Target Weight\",\"c\":[{\"t\":5,\"n\":\"Aah \\/ LipBigAah\"},{\"t\":5,\"n\":\"BigAah \\/ LipDST\"},{\"t\":5,\"n\":\"BMP \\/ LipEee\"},{\"t\":5,\"n\":\"ChJsh \\/ LipFV\"},{\"t\":5,\"n\":\"DST \\/ LipK\"},{\"t\":5,\"n\":\"Eee \\/ LipL\"},{\"t\":5,\"n\":\"Eh \\/ LipR\"},{\"t\":5,\"n\":\"FV \\/ LipTh\"},{\"t\":5,\"n\":\"I\"},{\"t\":5,\"n\":\"K\"},{\"t\":5,\"n\":\"N\"},{\"t\":5,\"n\":\"Oh\"},{\"t\":5,\"n\":\"OohQ\"},{\"t\":5,\"n\":\"R\"},{\"t\":5,\"n\":\"TH\"},{\"t\":5,\"n\":\"W\"}]}]}]},{\"t\":3,\"n\":\"WKMV - Base Movement Default - Walk\"},{\"t\":3,\"n\":\"RNMV - Base Movement Default - Run\"},{\"t\":3,\"n\":\"SWMV - Base Movement Default - Swim\"},{\"t\":3,\"n\":\"FLMV - Base Movement Default - Fly\"},{\"t\":3,\"n\":\"SNMV - Base Movement Default - Sneak\"},{\"t\":3,\"n\":\"SPMV - Base Movement Default - Sprint\"},{\"t\":6,\"p\":1,\"n\":\"Head Data\",\"c\":[{\"n\":\"NAM0 - Head Data Marker\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Male Head Data\",\"d\":1,\"c\":[{\"p\":1,\"n\":\"MNAM - Male Data Marker\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Female Head Data\",\"d\":1,\"c\":[{\"p\":1,\"n\":\"NAM0 - Head Data Marker\"},{\"p\":1,\"n\":\"FNAM - Female Data Marker\"}]}]},{\"t\":3,\"n\":\"NAM8 - Morph race\"},{\"t\":3,\"n\":\"RNAM - Armor race\"}]},{\"t\":1,\"p\":1,\"n\":\"REFR - Placed Object\",\"c\":[{\"t\":3,\"n\":\"Cell\"},{\"t\":6,\"n\":\"Record Header\",\"c\":[{\"t\":2,\"n\":\"Signature\"},{\"t\":3,\"n\":\"Data Size\"},{\"t\":3,\"n\":\"Record Flags\",\"c\":[{\"t\":4,\"n\":\"Persistent\"}]},{\"t\":3,\"n\":\"FormID\"},{\"t\":11,\"n\":\"Version Control Info 1\"},{\"t\":3,\"n\":\"Form Version\"},{\"t\":11,\"n\":\"Version Control Info 2\"}]},{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"VMAD - Virtual Machine Adapter\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Version\"},{\"t\":3,\"p\":1,\"n\":\"Object Format\"},{\"t\":12,\"p\":1,\"n\":\"Data\",\"c\":[{\"t\":9,\"p\":1,\"n\":\"Scripts\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Script\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"scriptName\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":9,\"p\":1,\"n\":\"Properties\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Property\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"propertyName\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":12,\"p\":1,\"n\":\"Value\"}]}]}]}]}]}]},{\"t\":3,\"n\":\"NAME - Base\"},{\"t\":6,\"n\":\"XMBO - Bound Half Extents\",\"c\":[{\"t\":5,\"n\":\"X\"},{\"t\":5,\"n\":\"Y\"},{\"t\":5,\"n\":\"Z\"}]},{\"t\":6,\"n\":\"XPRM - Primitive\",\"c\":[{\"t\":6,\"n\":\"Bounds\",\"c\":[{\"t\":5,\"n\":\"X\"},{\"t\":5,\"n\":\"Y\"},{\"t\":5,\"n\":\"Z\"}]},{\"t\":6,\"n\":\"Color\",\"c\":[{\"t\":5,\"n\":\"Red\"},{\"t\":5,\"n\":\"Green\"},{\"t\":5,\"n\":\"Blue\"}]},{\"t\":5,\"n\":\"Unknown\"},{\"t\":3,\"n\":\"Type\"}]},{\"t\":11,\"n\":\"XORD - Unknown\"},{\"t\":6,\"n\":\"XOCP - Occlusion Plane Data\",\"c\":[{\"t\":6,\"n\":\"Size\",\"c\":[{\"t\":5,\"n\":\"Width\"},{\"t\":5,\"n\":\"Height\"}]},{\"t\":6,\"n\":\"Position\",\"c\":[{\"t\":5,\"n\":\"X\"},{\"t\":5,\"n\":\"Y\"},{\"t\":5,\"n\":\"Z\"}]},{\"t\":6,\"n\":\"Rotation (Quaternion?)\",\"c\":[{\"t\":5,\"n\":\"q1\"},{\"t\":5,\"n\":\"q2\"},{\"t\":5,\"n\":\"q3\"},{\"t\":5,\"n\":\"q4\"}]}]},{\"t\":8,\"n\":\"XPOD - Portal Data\",\"c\":[{\"t\":6,\"n\":\"References #0\",\"c\":[{\"t\":3,\"n\":\"Origin\"},{\"t\":3,\"n\":\"Destination\"}]}]},{\"t\":6,\"n\":\"XPTL - Room Portal (unused)\",\"c\":[{\"t\":6,\"n\":\"Size\",\"c\":[{\"t\":5,\"n\":\"Width\"},{\"t\":5,\"n\":\"Height\"}]},{\"t\":6,\"n\":\"Position\",\"c\":[{\"t\":5,\"n\":\"X\"},{\"t\":5,\"n\":\"Y\"},{\"t\":5,\"n\":\"Z\"}]},{\"t\":6,\"n\":\"Rotation (Quaternion?)\",\"c\":[{\"t\":5,\"n\":\"q1\"},{\"t\":5,\"n\":\"q2\"},{\"t\":5,\"n\":\"q3\"},{\"t\":5,\"n\":\"q4\"}]}]},{\"t\":6,\"n\":\"Bound Data\",\"c\":[{\"t\":6,\"n\":\"XRMR - Header\",\"c\":[{\"t\":3,\"n\":\"Linked Rooms Count\"},{\"t\":3,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unknown\"}]}]},{\"n\":\"XMBP - MultiBound Primitive Marker\"},{\"t\":11,\"n\":\"XRGD - Ragdoll Data\"},{\"t\":11,\"n\":\"XRGB - Ragdoll Biped Data\"},{\"t\":5,\"n\":\"XRDS - Radius\"},{\"t\":10,\"n\":\"Reflected\\/Refracted By\",\"c\":[{\"t\":6,\"n\":\"XPWR - Water\",\"c\":[{\"t\":3,\"n\":\"Reference\"},{\"t\":3,\"n\":\"Type\"}]}]},{\"t\":9,\"n\":\"Lit Water\",\"c\":[{\"t\":3,\"n\":\"XLTW - Water\"}]},{\"t\":3,\"n\":\"XEMI - Emittance\"},{\"t\":6,\"n\":\"XLIG - Light Data\",\"c\":[{\"t\":5,\"n\":\"FOV 90+\\/-\"},{\"t\":5,\"n\":\"Fade 1.35+\\/-\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":5,\"n\":\"Shadow Depth Bias\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":6,\"n\":\"XALP - Alpha\",\"c\":[{\"t\":3,\"n\":\"Cutoff\"},{\"t\":3,\"n\":\"Base\"}]},{\"t\":6,\"n\":\"XTEL - Teleport Destination\",\"c\":[{\"t\":3,\"n\":\"Door\"},{\"t\":6,\"n\":\"Position\\/Rotation\",\"c\":[{\"t\":6,\"n\":\"Position\",\"c\":[{\"t\":5,\"n\":\"X\"},{\"t\":5,\"n\":\"Y\"},{\"t\":5,\"n\":\"Z\"}]},{\"t\":6,\"n\":\"Rotation\",\"c\":[{\"t\":5,\"n\":\"X\"},{\"t\":5,\"n\":\"Y\"},{\"t\":5,\"n\":\"Z\"}]}]},{\"t\":3,\"n\":\"Flags\"}]},{\"t\":3,\"n\":\"XTNM - Teleport Message Box\"},{\"t\":3,\"n\":\"XMBR - MultiBound Reference\"},{\"t\":11,\"n\":\"XWCN - Unknown\"},{\"t\":11,\"n\":\"XWCS - Unknown\"},{\"t\":6,\"n\":\"XWCU - Water Velocity\",\"c\":[{\"t\":5,\"n\":\"X Offset\"},{\"t\":5,\"n\":\"Y Offset\"},{\"t\":5,\"n\":\"Z Offset\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":5,\"n\":\"X Angle\"},{\"t\":5,\"n\":\"Y Angle\"},{\"t\":5,\"n\":\"Z Angle\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":6,\"n\":\"XCVL - Unknown\",\"c\":[{\"t\":11,\"n\":\"Unknown\"},{\"t\":5,\"n\":\"X Angle\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":3,\"n\":\"XCZR - Unknown\"},{\"t\":11,\"n\":\"XCZA - Unknown\"},{\"t\":3,\"n\":\"XCZC - Unknown\"},{\"t\":5,\"n\":\"XSCL - Scale\"},{\"t\":3,\"n\":\"XSPC - Spawn Container\"},{\"t\":6,\"n\":\"Activate Parents\",\"c\":[{\"t\":3,\"n\":\"XAPD - Flags\"}]},{\"t\":3,\"n\":\"XLIB - Leveled Item Base Object\"},{\"t\":3,\"n\":\"XLCM - Level Modifier\"},{\"t\":3,\"n\":\"XLCN - Persistent Location\"},{\"t\":3,\"n\":\"XTRI - Collision Layer\"},{\"t\":6,\"n\":\"XLOC - Lock Data\",\"c\":[{\"t\":3,\"n\":\"Level\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":3,\"n\":\"Key\"},{\"t\":3,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":3,\"n\":\"XEZN - Encounter Zone\"},{\"t\":6,\"n\":\"XNDP - Navigation Door Link\",\"c\":[{\"t\":3,\"n\":\"Navigation Mesh\"},{\"t\":3,\"n\":\"Teleport Marker Triangle\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":7,\"n\":\"XLRT - Location Ref Type\",\"c\":[{\"t\":3,\"n\":\"Ref #0\"}]},{\"n\":\"XIS2 - Ignored by Sandbox\"},{\"t\":6,\"n\":\"Ownership\",\"c\":[{\"t\":3,\"n\":\"XOWN - Owner\"}]},{\"t\":3,\"n\":\"XCNT - Item Count\"},{\"t\":5,\"n\":\"XCHG - Charge\"},{\"t\":3,\"n\":\"XLRL - Location Reference\"},{\"t\":6,\"n\":\"XESP - Enable Parent\",\"c\":[{\"t\":3,\"n\":\"Reference\"},{\"t\":3,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":8,\"n\":\"Linked References\",\"c\":[{\"t\":6,\"n\":\"XLKR - Linked Reference\",\"c\":[{\"t\":3,\"n\":\"Keyword\\/Ref\"},{\"t\":3,\"n\":\"Ref\"}]}]},{\"t\":8,\"n\":\"Patrol\",\"c\":[{\"t\":6,\"n\":\"Data\",\"c\":[{\"t\":5,\"n\":\"XPRD - Idle Time\"},{\"n\":\"XPPA - Patrol Script Marker\"},{\"t\":3,\"n\":\"INAM - Idle\"}]}]},{\"t\":3,\"n\":\"XACT - Action Flag\"},{\"t\":5,\"n\":\"XHTW - Head-Tracking Weight\"},{\"t\":5,\"n\":\"XFVC - Favor Cost\"},{\"n\":\"ONAM - Open by Default\"},{\"t\":6,\"p\":1,\"n\":\"Map Marker\",\"c\":[{\"n\":\"XMRK - Map Marker Data\"},{\"t\":3,\"n\":\"FNAM - Map Flags\"},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":6,\"n\":\"TNAM - \",\"c\":[{\"t\":3,\"n\":\"Type\"},{\"t\":11,\"n\":\"Unused\"}]}]},{\"t\":3,\"n\":\"XATR - Attach Ref\"},{\"t\":7,\"n\":\"XLOD - Distant LOD Data\",\"c\":[{\"t\":5,\"n\":\"Unknown #0\"},{\"t\":5,\"n\":\"Unknown #1\"},{\"t\":5,\"n\":\"Unknown #2\"}]},{\"t\":6,\"n\":\"DATA - Position\\/Rotation\",\"c\":[{\"t\":6,\"n\":\"Position\",\"c\":[{\"t\":5,\"n\":\"X\"},{\"t\":5,\"n\":\"Y\"},{\"t\":5,\"n\":\"Z\"}]},{\"t\":6,\"n\":\"Rotation\",\"c\":[{\"t\":5,\"n\":\"X\"},{\"t\":5,\"n\":\"Y\"},{\"t\":5,\"n\":\"Z\"}]}]}]},{\"t\":1,\"p\":1,\"n\":\"REVB - Reverb Parameters\",\"c\":[{\"t\":6,\"n\":\"Record Header\",\"c\":[{\"t\":2,\"n\":\"Signature\"},{\"t\":3,\"n\":\"Data Size\"},{\"t\":3,\"n\":\"Record Flags\"},{\"t\":3,\"n\":\"FormID\"},{\"t\":11,\"n\":\"Version Control Info 1\"},{\"t\":3,\"n\":\"Form Version\"},{\"t\":11,\"n\":\"Version Control Info 2\"}]},{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DATA - Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Decay Time (ms)\"},{\"t\":3,\"p\":1,\"n\":\"HF Reference (Hz)\"},{\"t\":3,\"p\":1,\"n\":\"Room Filter\"},{\"t\":3,\"p\":1,\"n\":\"Room HF Filter\"},{\"t\":3,\"p\":1,\"n\":\"Reflections\"},{\"t\":3,\"p\":1,\"n\":\"Reverb Amp\"},{\"t\":3,\"p\":1,\"n\":\"Decay HF Ratio\"},{\"t\":3,\"p\":1,\"n\":\"Reflect Delay (ms), scaled\"},{\"t\":3,\"p\":1,\"n\":\"Reverb Delay (ms)\"},{\"t\":3,\"p\":1,\"n\":\"Diffusion %\"},{\"t\":3,\"p\":1,\"n\":\"Density %\"},{\"t\":3,\"p\":1,\"n\":\"Unknown\"}]}]},{\"t\":1,\"p\":1,\"n\":\"SCEN - Scene\",\"c\":[{\"t\":6,\"n\":\"Record Header\",\"c\":[{\"t\":2,\"n\":\"Signature\"},{\"t\":3,\"n\":\"Data Size\"},{\"t\":3,\"n\":\"Record Flags\"},{\"t\":3,\"n\":\"FormID\"},{\"t\":11,\"n\":\"Version Control Info 1\"},{\"t\":3,\"n\":\"Form Version\"},{\"t\":11,\"n\":\"Version Control Info 2\"}]},{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"VMAD - Virtual Machine Adapter\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Version\"},{\"t\":3,\"p\":1,\"n\":\"Object Format\"},{\"t\":12,\"p\":1,\"n\":\"Data\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Scene VMAD\",\"c\":[{\"t\":9,\"p\":1,\"n\":\"Scripts\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Script\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"scriptName\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":9,\"p\":1,\"n\":\"Properties\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Property\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"propertyName\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":12,\"p\":1,\"n\":\"Value\"}]}]}]}]},{\"t\":6,\"p\":1,\"n\":\"Script Fragments Scene\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Unknown\"},{\"t\":3,\"p\":1,\"n\":\"Scene Fragments Flags\"},{\"t\":2,\"p\":1,\"n\":\"fileName\"},{\"t\":7,\"p\":1,\"n\":\"Scene Fragments\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Scene Fragment #0\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Unknown\"},{\"t\":2,\"p\":1,\"n\":\"scriptName\"},{\"t\":2,\"p\":1,\"n\":\"fragmentName\"}]}]},{\"t\":7,\"p\":1,\"n\":\"Phase Fragments\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Phase Fragment #0\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Phase Flag\"},{\"t\":3,\"p\":1,\"n\":\"Phase Index\"},{\"t\":3,\"p\":1,\"n\":\"Unknown\"},{\"t\":3,\"p\":1,\"n\":\"Unknown\"},{\"t\":3,\"p\":1,\"n\":\"Unknown\"},{\"t\":2,\"p\":1,\"n\":\"scriptName\"},{\"t\":2,\"p\":1,\"n\":\"fragmentName\"}]}]}]}]}]}]},{\"t\":3,\"n\":\"FNAM - Flags\"},{\"t\":8,\"n\":\"Phases\",\"c\":[{\"t\":6,\"n\":\"Phase\",\"c\":[{\"n\":\"HNAM - Marker Phase Start\"}]}]},{\"t\":8,\"n\":\"Actors\",\"c\":[{\"t\":6,\"n\":\"Actor\",\"c\":[{\"t\":3,\"n\":\"ALID - Actor ID\"}]}]},{\"t\":8,\"n\":\"Actions\",\"c\":[{\"t\":6,\"n\":\"Action\",\"c\":[{\"t\":3,\"n\":\"ANAM - Type\"}]}]},{\"t\":6,\"n\":\"Unused\",\"c\":[{\"t\":11,\"n\":\"SCHR - Unknown\"}]},{\"n\":\"NEXT - Marker\"},{\"t\":6,\"n\":\"Unused\",\"c\":[{\"t\":11,\"n\":\"SCHR - Unknown\"}]},{\"t\":3,\"n\":\"PNAM - Quest\"},{\"t\":3,\"n\":\"INAM - Last Action Index\"},{\"t\":11,\"n\":\"VNAM - Unknown\"},{\"t\":8,\"n\":\"Conditions\",\"c\":[{\"t\":6,\"n\":\"Condition\",\"c\":[{\"t\":6,\"n\":\"CTDA - \",\"c\":[{\"t\":3,\"n\":\"Type\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":12,\"n\":\"Comparison Value\"},{\"t\":3,\"n\":\"Function\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":12,\"n\":\"Parameter #1\"},{\"t\":12,\"n\":\"Parameter #2\"},{\"t\":3,\"n\":\"Run On\"},{\"t\":12,\"n\":\"Reference\"},{\"t\":3,\"n\":\"Parameter #3\"}]}]}]}]},{\"t\":1,\"p\":1,\"n\":\"SCRL - Scroll\",\"c\":[{\"t\":6,\"n\":\"Record Header\",\"c\":[{\"t\":2,\"n\":\"Signature\"},{\"t\":3,\"n\":\"Data Size\"},{\"t\":3,\"n\":\"Record Flags\"},{\"t\":3,\"n\":\"FormID\"},{\"t\":11,\"n\":\"Version Control Info 1\"},{\"t\":3,\"n\":\"Form Version\"},{\"t\":11,\"n\":\"Version Control Info 2\"}]},{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"n\":\"X1\"},{\"t\":3,\"n\":\"Y1\"},{\"t\":3,\"n\":\"Z1\"},{\"t\":3,\"n\":\"X2\"},{\"t\":3,\"n\":\"Y2\"},{\"t\":3,\"n\":\"Z2\"}]},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":3,\"n\":\"KSIZ - Keyword Count\"},{\"t\":9,\"n\":\"KWDA - Keywords\",\"c\":[{\"t\":3,\"n\":\"Keyword\"}]},{\"t\":3,\"n\":\"MDOB - Menu Display Object\"},{\"t\":3,\"n\":\"ETYP - Equipment Type\"},{\"t\":2,\"n\":\"DESC - Description\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"}]},{\"t\":6,\"n\":\"Destructable\",\"c\":[{\"t\":6,\"n\":\"DEST - Header\",\"c\":[{\"t\":3,\"n\":\"Health\"},{\"t\":3,\"n\":\"DEST Count\"},{\"t\":3,\"n\":\"VATS Targetable\"},{\"t\":11,\"n\":\"Unknown\"}]}]},{\"t\":3,\"n\":\"YNAM - Sound - Pick Up\"},{\"t\":3,\"n\":\"ZNAM - Sound - Drop\"},{\"t\":6,\"n\":\"DATA - Item\",\"c\":[{\"t\":3,\"n\":\"Value\"},{\"t\":5,\"n\":\"Weight\"}]},{\"t\":6,\"n\":\"SPIT - Data\",\"c\":[{\"t\":3,\"n\":\"Base Cost\"},{\"t\":3,\"n\":\"Flags\"},{\"t\":3,\"n\":\"Type\"},{\"t\":5,\"n\":\"Charge Time\"},{\"t\":3,\"n\":\"Cast Type\"},{\"t\":3,\"n\":\"Target Type\"},{\"t\":5,\"n\":\"Cast Duration\"},{\"t\":5,\"n\":\"Range\"},{\"t\":3,\"n\":\"Half-cost Perk\"}]},{\"t\":8,\"n\":\"Effects\",\"c\":[{\"t\":6,\"n\":\"Effect\",\"c\":[{\"t\":3,\"n\":\"EFID - Base Effect\"},{\"t\":6,\"n\":\"EFIT - \",\"c\":[{\"t\":5,\"n\":\"Magnitude\"},{\"t\":3,\"n\":\"Area\"},{\"t\":3,\"n\":\"Duration\"}]}]}]}]},{\"t\":1,\"p\":1,\"n\":\"SHOU - Shout\",\"c\":[{\"t\":6,\"n\":\"Record Header\",\"c\":[{\"t\":2,\"n\":\"Signature\"},{\"t\":3,\"n\":\"Data Size\"},{\"t\":3,\"n\":\"Record Flags\"},{\"t\":3,\"n\":\"FormID\"},{\"t\":11,\"n\":\"Version Control Info 1\"},{\"t\":3,\"n\":\"Form Version\"},{\"t\":11,\"n\":\"Version Control Info 2\"}]},{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":3,\"n\":\"MDOB - Menu Display Object\"},{\"t\":2,\"n\":\"DESC - Description\"},{\"t\":8,\"n\":\"Words of Power\",\"c\":[{\"t\":6,\"n\":\"SNAM - \",\"c\":[{\"t\":3,\"n\":\"Word\"},{\"t\":3,\"n\":\"Spell\"},{\"t\":5,\"n\":\"Recovery Time\"}]}]}]},{\"t\":1,\"p\":1,\"n\":\"SLGM - Soul Gem\",\"c\":[{\"t\":6,\"n\":\"Record Header\",\"c\":[{\"t\":2,\"n\":\"Signature\"},{\"t\":3,\"n\":\"Data Size\"},{\"t\":3,\"n\":\"Record Flags\"},{\"t\":3,\"n\":\"FormID\"},{\"t\":11,\"n\":\"Version Control Info 1\"},{\"t\":3,\"n\":\"Form Version\"},{\"t\":11,\"n\":\"Version Control Info 2\"}]},{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"n\":\"X1\"},{\"t\":3,\"n\":\"Y1\"},{\"t\":3,\"n\":\"Z1\"},{\"t\":3,\"n\":\"X2\"},{\"t\":3,\"n\":\"Y2\"},{\"t\":3,\"n\":\"Z2\"}]},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Icon\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"ICON - Large Icon filename\"}]},{\"t\":6,\"n\":\"Destructable\",\"c\":[{\"t\":6,\"n\":\"DEST - Header\",\"c\":[{\"t\":3,\"n\":\"Health\"},{\"t\":3,\"n\":\"DEST Count\"},{\"t\":3,\"n\":\"VATS Targetable\"},{\"t\":11,\"n\":\"Unknown\"}]}]},{\"t\":3,\"n\":\"YNAM - Sound - Pick Up\"},{\"t\":3,\"n\":\"ZNAM - Sound - Drop\"},{\"t\":3,\"n\":\"KSIZ - Keyword Count\"},{\"t\":9,\"n\":\"KWDA - Keywords\",\"c\":[{\"t\":3,\"n\":\"Keyword\"}]},{\"t\":6,\"n\":\"DATA - \",\"c\":[{\"t\":3,\"n\":\"Value\"},{\"t\":5,\"n\":\"Weight\"}]},{\"t\":3,\"n\":\"SOUL - Contained Soul\"},{\"t\":3,\"n\":\"SLCP - Maximum Capacity\"},{\"t\":3,\"n\":\"NAM0 - Linked To\"}]},{\"t\":1,\"p\":1,\"n\":\"SNCT - Sound Category\",\"c\":[{\"t\":6,\"n\":\"Record Header\",\"c\":[{\"t\":2,\"n\":\"Signature\"},{\"t\":3,\"n\":\"Data Size\"},{\"t\":3,\"n\":\"Record Flags\"},{\"t\":3,\"n\":\"FormID\"},{\"t\":11,\"n\":\"Version Control Info 1\"},{\"t\":3,\"n\":\"Form Version\"},{\"t\":11,\"n\":\"Version Control Info 2\"}]},{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":3,\"p\":1,\"n\":\"FNAM - Flags\",\"lt\":\"UNAM - Default Menu Value\",\"lf\":\"PNAM - Parent\"},{\"t\":3,\"p\":1,\"n\":\"PNAM - Parent\",\"lt\":\"FNAM - Flags\",\"lf\":\"VNAM - Static Volume Multiplier\"},{\"t\":3,\"p\":1,\"n\":\"VNAM - Static Volume Multiplier\",\"lt\":\"PNAM - Parent\",\"lf\":\"UNAM - Default Menu Value\"},{\"t\":3,\"p\":1,\"n\":\"UNAM - Default Menu Value\",\"lt\":\"VNAM - Static Volume Multiplier\",\"lf\":\"FNAM - Flags\"}]},{\"t\":1,\"p\":1,\"n\":\"SNDR - Sound Descriptor\",\"c\":[{\"t\":6,\"n\":\"Record Header\",\"c\":[{\"t\":2,\"n\":\"Signature\"},{\"t\":3,\"n\":\"Data Size\"},{\"t\":3,\"n\":\"Record Flags\"},{\"t\":3,\"n\":\"FormID\"},{\"t\":11,\"n\":\"Version Control Info 1\"},{\"t\":3,\"n\":\"Form Version\"},{\"t\":11,\"n\":\"Version Control Info 2\"}]},{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":11,\"n\":\"CNAM - Unknown\"},{\"t\":3,\"p\":1,\"n\":\"GNAM - Category\",\"lt\":\"BNAM - Values\",\"lf\":\"SNAM - Alternate Sound For\"},{\"t\":3,\"p\":1,\"n\":\"SNAM - Alternate Sound For\",\"lt\":\"GNAM - Category\",\"lf\":\"Sounds\"},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Sounds\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Sound Files\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"ANAM - File Name\"}]}],\"lt\":\"SNAM - Alternate Sound For\",\"lf\":\"ONAM - Output Model\"},{\"t\":3,\"p\":1,\"n\":\"ONAM - Output Model\",\"lt\":\"Sounds\",\"lf\":\"FNAM - String\"},{\"t\":2,\"p\":1,\"n\":\"FNAM - String\",\"lt\":\"ONAM - Output Model\",\"lf\":\"Conditions\"},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Conditions\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Condition\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"CTDA - \",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":11,\"p\":1,\"n\":\"Unused\"},{\"t\":12,\"p\":1,\"n\":\"Comparison Value\"},{\"t\":3,\"p\":1,\"n\":\"Function\"},{\"t\":11,\"p\":1,\"n\":\"Unused\"},{\"t\":12,\"p\":1,\"n\":\"Parameter #1\"},{\"t\":12,\"p\":1,\"n\":\"Parameter #2\"},{\"t\":3,\"p\":1,\"n\":\"Run On\"},{\"t\":12,\"p\":1,\"n\":\"Reference\"},{\"t\":3,\"p\":1,\"n\":\"Parameter #3\"}]}]}],\"lt\":\"FNAM - String\",\"lf\":\"LNAM - Values\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"LNAM - Values\",\"c\":[{\"t\":11,\"p\":1,\"n\":\"Unknown\"},{\"t\":3,\"p\":1,\"n\":\"Looping\"},{\"t\":11,\"p\":1,\"n\":\"Unknown\"},{\"t\":3,\"p\":1,\"n\":\"Rumble Send Value = (Small \\/ 7) + ((Big \\/ 7) * 16)\"}],\"lt\":\"Conditions\",\"lf\":\"BNAM - Values\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"BNAM - Values\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"% Frequency Shift\"},{\"t\":3,\"p\":1,\"n\":\"% Frequency Variance\"},{\"t\":3,\"p\":1,\"n\":\"Priority\"},{\"t\":3,\"p\":1,\"n\":\"db Variance\"},{\"t\":3,\"p\":1,\"n\":\"Static Attenuation (db)\"}],\"lt\":\"LNAM - Values\",\"lf\":\"GNAM - Category\"}]},{\"t\":1,\"p\":1,\"n\":\"SOPM - Sound Output Model\",\"c\":[{\"t\":6,\"n\":\"Record Header\",\"c\":[{\"t\":2,\"n\":\"Signature\"},{\"t\":3,\"n\":\"Data Size\"},{\"t\":3,\"n\":\"Record Flags\"},{\"t\":3,\"n\":\"FormID\"},{\"t\":11,\"n\":\"Version Control Info 1\"},{\"t\":3,\"n\":\"Form Version\"},{\"t\":11,\"n\":\"Version Control Info 2\"}]},{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"NAM1 - Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"p\":1,\"n\":\"Unknown\"},{\"t\":3,\"p\":1,\"n\":\"Reverb Send %\"}],\"lt\":\"ANAM - Attenuation Values\",\"lf\":\"MNAM - Type\"},{\"t\":11,\"n\":\"FNAM - Unknown\"},{\"t\":3,\"p\":1,\"n\":\"MNAM - Type\",\"lt\":\"NAM1 - Data\",\"lf\":\"ONAM - Output Values\"},{\"t\":11,\"n\":\"CNAM - Unknown\"},{\"t\":11,\"n\":\"SNAM - Unknown\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"ONAM - Output Values\",\"c\":[{\"t\":8,\"p\":1,\"n\":\"Channels\",\"c\":[{\"t\":6,\"p\":1,\"n\":\" #0 (Channel 0)\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"L\"},{\"t\":3,\"p\":1,\"n\":\"R\"},{\"t\":3,\"p\":1,\"n\":\"C\"},{\"t\":3,\"p\":1,\"n\":\"LFE\"},{\"t\":3,\"p\":1,\"n\":\"RL\"},{\"t\":3,\"p\":1,\"n\":\"RR\"},{\"t\":3,\"p\":1,\"n\":\"BL\"},{\"t\":3,\"p\":1,\"n\":\"BR\"}]},{\"t\":6,\"p\":1,\"n\":\" #1 (Channel 1)\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"L\"},{\"t\":3,\"p\":1,\"n\":\"R\"},{\"t\":3,\"p\":1,\"n\":\"C\"},{\"t\":3,\"p\":1,\"n\":\"LFE\"},{\"t\":3,\"p\":1,\"n\":\"RL\"},{\"t\":3,\"p\":1,\"n\":\"RR\"},{\"t\":3,\"p\":1,\"n\":\"BL\"},{\"t\":3,\"p\":1,\"n\":\"BR\"}]},{\"t\":6,\"p\":1,\"n\":\" #2 (Channel 2? (unused))\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"L\"},{\"t\":3,\"p\":1,\"n\":\"R\"},{\"t\":3,\"p\":1,\"n\":\"C\"},{\"t\":3,\"p\":1,\"n\":\"LFE\"},{\"t\":3,\"p\":1,\"n\":\"RL\"},{\"t\":3,\"p\":1,\"n\":\"RR\"},{\"t\":3,\"p\":1,\"n\":\"BL\"},{\"t\":3,\"p\":1,\"n\":\"BR\"}]}]}],\"lt\":\"MNAM - Type\",\"lf\":\"ANAM - Attenuation Values\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"ANAM - Attenuation Values\",\"c\":[{\"t\":11,\"p\":1,\"n\":\"Unknown\"},{\"t\":5,\"p\":1,\"n\":\"Min Distance\"},{\"t\":5,\"p\":1,\"n\":\"Max Distance\"},{\"t\":7,\"p\":1,\"n\":\"Curve\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Value #0\"},{\"t\":3,\"p\":1,\"n\":\"Value #1\"},{\"t\":3,\"p\":1,\"n\":\"Value #2\"},{\"t\":3,\"p\":1,\"n\":\"Value #3\"},{\"t\":3,\"p\":1,\"n\":\"Value #4\"}]},{\"t\":11,\"p\":1,\"n\":\"Unknown\"}],\"lt\":\"ONAM - Output Values\",\"lf\":\"NAM1 - Data\"}]},{\"t\":1,\"p\":1,\"n\":\"SOUN - Sound Marker\",\"c\":[{\"t\":6,\"n\":\"Record Header\",\"c\":[{\"t\":2,\"n\":\"Signature\"},{\"t\":3,\"n\":\"Data Size\"},{\"t\":3,\"n\":\"Record Flags\"},{\"t\":3,\"n\":\"FormID\"},{\"t\":11,\"n\":\"Version Control Info 1\"},{\"t\":3,\"n\":\"Form Version\"},{\"t\":11,\"n\":\"Version Control Info 2\"}]},{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"n\":\"X1\"},{\"t\":3,\"n\":\"Y1\"},{\"t\":3,\"n\":\"Z1\"},{\"t\":3,\"n\":\"X2\"},{\"t\":3,\"n\":\"Y2\"},{\"t\":3,\"n\":\"Z2\"}]},{\"t\":11,\"n\":\"FNAM - Unknown\"},{\"t\":11,\"n\":\"SNDD - Unknown\"},{\"t\":3,\"p\":1,\"n\":\"SDSC - Sound Descriptor\"}]},{\"t\":1,\"p\":1,\"n\":\"SPEL - Spell\",\"c\":[{\"t\":6,\"n\":\"Record Header\",\"c\":[{\"t\":2,\"n\":\"Signature\"},{\"t\":3,\"n\":\"Data Size\"},{\"t\":3,\"n\":\"Record Flags\"},{\"t\":3,\"n\":\"FormID\"},{\"t\":11,\"n\":\"Version Control Info 1\"},{\"t\":3,\"n\":\"Form Version\"},{\"t\":11,\"n\":\"Version Control Info 2\"}]},{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"n\":\"X1\"},{\"t\":3,\"n\":\"Y1\"},{\"t\":3,\"n\":\"Z1\"},{\"t\":3,\"n\":\"X2\"},{\"t\":3,\"n\":\"Y2\"},{\"t\":3,\"n\":\"Z2\"}]},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":3,\"n\":\"KSIZ - Keyword Count\"},{\"t\":9,\"n\":\"KWDA - Keywords\",\"c\":[{\"t\":3,\"n\":\"Keyword\"}]},{\"t\":3,\"n\":\"MDOB - Menu Display Object\"},{\"t\":3,\"n\":\"ETYP - Equipment Type\"},{\"t\":2,\"n\":\"DESC - Description\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"SPIT - Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Base Cost\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":5,\"p\":1,\"n\":\"Charge Time\"},{\"t\":3,\"p\":1,\"n\":\"Cast Type\"},{\"t\":3,\"p\":1,\"n\":\"Target Type\"},{\"t\":5,\"p\":1,\"n\":\"Cast Duration\"},{\"t\":5,\"p\":1,\"n\":\"Range\"},{\"t\":3,\"p\":1,\"n\":\"Half-cost Perk\"}]},{\"t\":8,\"n\":\"Effects\",\"c\":[{\"t\":6,\"n\":\"Effect\",\"c\":[{\"t\":3,\"n\":\"EFID - Base Effect\"},{\"t\":6,\"n\":\"EFIT - \",\"c\":[{\"t\":5,\"n\":\"Magnitude\"},{\"t\":3,\"n\":\"Area\"},{\"t\":3,\"n\":\"Duration\"}]}]}]}]},{\"t\":1,\"p\":1,\"n\":\"STAT - Static\",\"c\":[{\"t\":6,\"n\":\"Record Header\",\"c\":[{\"t\":2,\"n\":\"Signature\"},{\"t\":3,\"n\":\"Data Size\"},{\"t\":3,\"n\":\"Record Flags\"},{\"t\":3,\"n\":\"FormID\"},{\"t\":11,\"n\":\"Version Control Info 1\"},{\"t\":3,\"n\":\"Form Version\"},{\"t\":11,\"n\":\"Version Control Info 2\"}]},{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"n\":\"X1\"},{\"t\":3,\"n\":\"Y1\"},{\"t\":3,\"n\":\"Z1\"},{\"t\":3,\"n\":\"X2\"},{\"t\":3,\"n\":\"Y2\"},{\"t\":3,\"n\":\"Z2\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"}]},{\"t\":6,\"n\":\"DNAM - Direction Material\",\"c\":[{\"t\":5,\"n\":\"Max Angle (30-120)\"},{\"t\":3,\"n\":\"Material\"}]},{\"t\":8,\"n\":\"MNAM - Distant LOD\",\"c\":[{\"t\":6,\"n\":\"LOD #0 (Level 0)\",\"c\":[{\"t\":2,\"n\":\"Mesh\"}]},{\"t\":6,\"n\":\"LOD #1 (Level 1)\",\"c\":[{\"t\":2,\"n\":\"Mesh\"}]},{\"t\":6,\"n\":\"LOD #2 (Level 2)\",\"c\":[{\"t\":2,\"n\":\"Mesh\"}]},{\"t\":6,\"n\":\"LOD #3 (Level 3)\",\"c\":[{\"t\":2,\"n\":\"Mesh\"}]}]}]},{\"t\":1,\"p\":1,\"n\":\"TREE - Tree\",\"c\":[{\"t\":6,\"n\":\"Record Header\",\"c\":[{\"t\":2,\"n\":\"Signature\"},{\"t\":3,\"n\":\"Data Size\"},{\"t\":3,\"n\":\"Record Flags\"},{\"t\":3,\"n\":\"FormID\"},{\"t\":11,\"n\":\"Version Control Info 1\"},{\"t\":3,\"n\":\"Form Version\"},{\"t\":11,\"n\":\"Version Control Info 2\"}]},{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"VMAD - Virtual Machine Adapter\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Version\"},{\"t\":3,\"p\":1,\"n\":\"Object Format\"},{\"t\":12,\"p\":1,\"n\":\"Data\",\"c\":[{\"t\":9,\"p\":1,\"n\":\"Scripts\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Script\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"scriptName\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":9,\"p\":1,\"n\":\"Properties\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Property\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"propertyName\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":12,\"p\":1,\"n\":\"Value\"}]}]}]}]}]}]},{\"t\":6,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"n\":\"X1\"},{\"t\":3,\"n\":\"Y1\"},{\"t\":3,\"n\":\"Z1\"},{\"t\":3,\"n\":\"X2\"},{\"t\":3,\"n\":\"Y2\"},{\"t\":3,\"n\":\"Z2\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"}]},{\"t\":3,\"n\":\"PFIG - Ingredient\"},{\"t\":3,\"n\":\"SNAM - Harvest Sound\"},{\"t\":6,\"n\":\"PFPC - Ingredient Production\",\"c\":[{\"t\":3,\"n\":\"Spring\"},{\"t\":3,\"n\":\"Summer\"},{\"t\":3,\"n\":\"Fall\"},{\"t\":3,\"n\":\"Winter\"}]},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":6,\"n\":\"CNAM - Tree Data\",\"c\":[{\"t\":5,\"n\":\"Trunk Flexibility\"},{\"t\":5,\"n\":\"Branch Flexibility\"},{\"t\":5,\"n\":\"Unknown\"},{\"t\":5,\"n\":\"Unknown\"},{\"t\":5,\"n\":\"Unknown\"},{\"t\":5,\"n\":\"Unknown\"},{\"t\":5,\"n\":\"Unknown\"},{\"t\":5,\"n\":\"Unknown\"},{\"t\":5,\"n\":\"Unknown\"},{\"t\":5,\"n\":\"Unknown\"},{\"t\":5,\"n\":\"Leaf Amplitude\"},{\"t\":5,\"n\":\"Leaf Frequency\"}]}]},{\"t\":1,\"p\":1,\"n\":\"WATR - Water\",\"c\":[{\"t\":6,\"n\":\"Record Header\",\"c\":[{\"t\":2,\"n\":\"Signature\"},{\"t\":3,\"n\":\"Data Size\"},{\"t\":3,\"n\":\"Record Flags\"},{\"t\":3,\"n\":\"FormID\"},{\"t\":11,\"n\":\"Version Control Info 1\"},{\"t\":3,\"n\":\"Form Version\"},{\"t\":11,\"n\":\"Version Control Info 2\"}]},{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":7,\"n\":\"Unused\",\"c\":[{\"t\":2,\"n\":\"NNAM - Noise Map\"}]},{\"t\":3,\"n\":\"ANAM - Opacity\"},{\"t\":3,\"n\":\"FNAM - Flags\"},{\"t\":11,\"n\":\"MNAM - Unused\"},{\"t\":3,\"n\":\"TNAM - Material\"},{\"t\":3,\"n\":\"SNAM - Open Sound\"},{\"t\":3,\"n\":\"XNAM - Spell\"},{\"t\":3,\"n\":\"INAM - Image Space\"},{\"t\":3,\"n\":\"DATA - Damage Per Second\"},{\"t\":6,\"n\":\"DNAM - Visual Data\",\"c\":[{\"t\":5,\"n\":\"Unknown\"},{\"t\":5,\"n\":\"Unknown\"},{\"t\":5,\"n\":\"Unknown\"},{\"t\":5,\"n\":\"Unknown\"},{\"t\":5,\"n\":\"Specular Properties - Sun Specular Power\"},{\"t\":5,\"n\":\"Water Properties - Reflectivity Amount\"},{\"t\":5,\"n\":\"Water Properties - Fresnel Amount\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":5,\"n\":\"Fog Properties - Above Water - Fog Distance - Near Plane\"},{\"t\":5,\"n\":\"Fog Properties - Above Water - Fog Distance - Far Plane\"},{\"t\":6,\"n\":\"Shallow Color\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":6,\"n\":\"Deep Color\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":6,\"n\":\"Reflection Color\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":11,\"n\":\"Unknown\"},{\"t\":5,\"n\":\"Unknown\"},{\"t\":5,\"n\":\"Unknown\"},{\"t\":5,\"n\":\"Unknown\"},{\"t\":5,\"n\":\"Unknown\"},{\"t\":5,\"n\":\"Displacement Simulator - Starting Size\"},{\"t\":5,\"n\":\"Displacement Simulator - Force\"},{\"t\":5,\"n\":\"Displacement Simulator - Velocity\"},{\"t\":5,\"n\":\"Displacement Simulator - Falloff\"},{\"t\":5,\"n\":\"Displacement Simulator - Dampner\"},{\"t\":5,\"n\":\"Unknown\"},{\"t\":5,\"n\":\"Noise Properties - Noise Falloff\"},{\"t\":5,\"n\":\"Noise Properties - Layer One - Wind Direction\"},{\"t\":5,\"n\":\"Noise Properties - Layer Two - Wind Direction\"},{\"t\":5,\"n\":\"Noise Properties - Layer Three - Wind Direction\"},{\"t\":5,\"n\":\"Noise Properties - Layer One - Wind Speed\"},{\"t\":5,\"n\":\"Noise Properties - Layer Two - Wind Speed\"},{\"t\":5,\"n\":\"Noise Properties - Layer Three - Wind Speed\"},{\"t\":5,\"n\":\"Unknown\"},{\"t\":5,\"n\":\"Unknown\"},{\"t\":5,\"n\":\"Fog Properties - Above Water - Fog Amount\"},{\"t\":5,\"n\":\"Unknown\"},{\"t\":5,\"n\":\"Fog Properties - Under Water - Fog Amount\"},{\"t\":5,\"n\":\"Fog Properties - Under Water - Fog Distance - Near Plane\"},{\"t\":5,\"n\":\"Fog Properties - Under Water - Fog Distance - Far Plane\"},{\"t\":5,\"n\":\"Water Properties - Refraction Magnitude\"},{\"t\":5,\"n\":\"Specular Properties - Specular Power\"},{\"t\":5,\"n\":\"Unknown\"},{\"t\":5,\"n\":\"Specular Properties - Specular Radius\"},{\"t\":5,\"n\":\"Specular Properties - Specular Brightness\"},{\"t\":5,\"n\":\"Noise Properties - Layer One - UV Scale\"},{\"t\":5,\"n\":\"Noise Properties - Layer Two - UV Scale\"},{\"t\":5,\"n\":\"Noise Properties - Layer Three - UV Scale\"},{\"t\":5,\"n\":\"Noise Properties - Layer One - Amplitude Scale\"},{\"t\":5,\"n\":\"Noise Properties - Layer Two - Amplitude Scale\"},{\"t\":5,\"n\":\"Noise Properties - Layer Three - Amplitude Scale\"},{\"t\":5,\"n\":\"Water Properties - Reflection Magnitude\"},{\"t\":5,\"n\":\"Specular Properties - Sun Sparkle Magnitude\"},{\"t\":5,\"n\":\"Specular Properties - Sun Specular Magnitude\"},{\"t\":5,\"n\":\"Depth Properties - Reflections\"},{\"t\":5,\"n\":\"Depth Properties - Refraction\"},{\"t\":5,\"n\":\"Depth Properties - Normals\"},{\"t\":5,\"n\":\"Depth Properties - Specular Lighting\"},{\"t\":5,\"n\":\"Specular Properties - Sun Sparkle Power\"}]},{\"t\":11,\"n\":\"GNAM - Unused\"},{\"t\":6,\"n\":\"NAM0 - Linear Velocity\",\"c\":[{\"t\":5,\"n\":\"X\"},{\"t\":5,\"n\":\"Y\"},{\"t\":5,\"n\":\"Z\"}]},{\"t\":6,\"n\":\"NAM1 - Angular Velocity\",\"c\":[{\"t\":5,\"n\":\"X\"},{\"t\":5,\"n\":\"Y\"},{\"t\":5,\"n\":\"Z\"}]},{\"t\":2,\"n\":\"NAM2 - Noise Texture\"},{\"t\":2,\"n\":\"NAM3 - Unused\"},{\"t\":2,\"n\":\"NAM4 - Unused\"}]},{\"t\":1,\"p\":1,\"n\":\"WEAP - Weapon\",\"c\":[{\"t\":6,\"n\":\"Record Header\",\"c\":[{\"t\":2,\"n\":\"Signature\"},{\"t\":3,\"n\":\"Data Size\"},{\"t\":3,\"n\":\"Record Flags\"},{\"t\":3,\"n\":\"FormID\"},{\"t\":11,\"n\":\"Version Control Info 1\"},{\"t\":3,\"n\":\"Form Version\"},{\"t\":11,\"n\":\"Version Control Info 2\"}]},{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"VMAD - Virtual Machine Adapter\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Version\"},{\"t\":3,\"p\":1,\"n\":\"Object Format\"},{\"t\":12,\"p\":1,\"n\":\"Data\",\"c\":[{\"t\":9,\"p\":1,\"n\":\"Scripts\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Script\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"scriptName\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":9,\"p\":1,\"n\":\"Properties\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Property\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"propertyName\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":12,\"p\":1,\"n\":\"Value\"}]}]}]}]}]}]},{\"t\":6,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"n\":\"X1\"},{\"t\":3,\"n\":\"Y1\"},{\"t\":3,\"n\":\"Z1\"},{\"t\":3,\"n\":\"X2\"},{\"t\":3,\"n\":\"Y2\"},{\"t\":3,\"n\":\"Z2\"}]},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Icon\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"ICON - Large Icon filename\"}]},{\"t\":3,\"n\":\"EITM - Object Effect\"},{\"t\":3,\"n\":\"EAMT - Enchantment Amount\"},{\"t\":6,\"n\":\"Destructable\",\"c\":[{\"t\":6,\"n\":\"DEST - Header\",\"c\":[{\"t\":3,\"n\":\"Health\"},{\"t\":3,\"n\":\"DEST Count\"},{\"t\":3,\"n\":\"VATS Targetable\"},{\"t\":11,\"n\":\"Unknown\"}]}]},{\"t\":3,\"n\":\"ETYP - Equipment Type\"},{\"t\":3,\"n\":\"BIDS - Block Bash Impact Data Set\"},{\"t\":3,\"n\":\"BAMT - Alternate Block Material\"},{\"t\":3,\"p\":1,\"n\":\"YNAM - Sound - Pick Up\"},{\"t\":3,\"p\":1,\"n\":\"ZNAM - Sound - Drop\"},{\"t\":3,\"n\":\"KSIZ - Keyword Count\"},{\"t\":9,\"n\":\"KWDA - Keywords\",\"c\":[{\"t\":3,\"n\":\"Keyword\"}]},{\"t\":2,\"n\":\"DESC - Description\"},{\"t\":6,\"n\":\"Has Scope\",\"c\":[{\"t\":2,\"n\":\"MOD3 - Model Filename\"}]},{\"t\":11,\"n\":\"NNAM - Unused\"},{\"t\":3,\"n\":\"INAM - Impact Data Set\"},{\"t\":3,\"p\":1,\"n\":\"WNAM - 1st Person Model Object\"},{\"t\":3,\"p\":1,\"n\":\"SNAM - Attack Sound\"},{\"t\":3,\"p\":1,\"n\":\"XNAM - Attack Sound 2D\"},{\"t\":3,\"p\":1,\"n\":\"NAM7 - Attack Loop Sound\"},{\"t\":3,\"p\":1,\"n\":\"TNAM - Attack Fail Sound\"},{\"t\":3,\"p\":1,\"n\":\"UNAM - Idle Sound\"},{\"t\":3,\"p\":1,\"n\":\"NAM9 - Equip Sound\"},{\"t\":3,\"p\":1,\"n\":\"NAM8 - Unequip Sound\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DATA - Game Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Value\"},{\"t\":5,\"p\":1,\"n\":\"Weight\"},{\"t\":3,\"p\":1,\"n\":\"Damage\"}]},{\"t\":6,\"p\":1,\"n\":\"DNAM - Data\",\"c\":[{\"t\":3,\"n\":\"Animation Type\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":5,\"p\":1,\"n\":\"Speed\",\"lt\":\"Reach\",\"lf\":\"Stagger\"},{\"t\":5,\"p\":1,\"n\":\"Reach\",\"lt\":\"Resist\",\"lf\":\"Speed\"},{\"t\":3,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":5,\"n\":\"Sight FOV\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":3,\"n\":\"Base VATS To-Hit Chance\"},{\"t\":3,\"n\":\"Attack Animation\"},{\"t\":3,\"n\":\"# Projectiles\"},{\"t\":3,\"n\":\"Embedded Weapon AV (unused)\"},{\"t\":5,\"n\":\"Range Min\"},{\"t\":5,\"n\":\"Range Max\"},{\"t\":3,\"n\":\"On Hit\"},{\"t\":3,\"n\":\"Flags2\"},{\"t\":5,\"n\":\"Animation Attack Mult\"},{\"t\":5,\"n\":\"Unknown\"},{\"t\":5,\"n\":\"Rumble - Left Motor Strength\"},{\"t\":5,\"n\":\"Rumble - Right Motor Strength\"},{\"t\":5,\"n\":\"Rumble - Duration\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":3,\"n\":\"Skill\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":3,\"p\":1,\"n\":\"Resist\",\"lt\":\"Stagger\",\"lf\":\"Reach\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":5,\"p\":1,\"n\":\"Stagger\",\"lt\":\"Speed\",\"lf\":\"Resist\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"CRDT - Critical Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Damage\"},{\"t\":11,\"p\":1,\"n\":\"Unused\"},{\"t\":5,\"p\":1,\"n\":\"% Mult\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Effect\"}]},{\"t\":3,\"n\":\"VNAM - Detection Sound Level\"},{\"t\":3,\"n\":\"CNAM - Template\"}]},{\"t\":1,\"p\":1,\"n\":\"WRLD - Worldspace\",\"c\":[{\"t\":6,\"n\":\"Record Header\",\"c\":[{\"t\":2,\"n\":\"Signature\"},{\"t\":3,\"n\":\"Data Size\"},{\"t\":3,\"n\":\"Record Flags\"},{\"t\":3,\"n\":\"FormID\"},{\"t\":11,\"n\":\"Version Control Info 1\"},{\"t\":3,\"n\":\"Form Version\"},{\"t\":11,\"n\":\"Version Control Info 2\"}]},{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":7,\"n\":\"Unused RNAM\",\"c\":[{\"t\":11,\"n\":\"RNAM - Unknown\"}]},{\"t\":11,\"n\":\"MHDT - Max Height Data\"},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":6,\"n\":\"WCTR - Fixed Dimensions Center Cell\",\"c\":[{\"t\":3,\"n\":\"X\"},{\"t\":3,\"n\":\"Y\"}]},{\"t\":3,\"n\":\"LTMP - Interior Lighting\"},{\"t\":3,\"n\":\"XEZN - Encounter Zone\"},{\"t\":3,\"n\":\"XLCN - Location\"},{\"t\":6,\"n\":\"Parent\",\"c\":[{\"t\":3,\"n\":\"WNAM - Worldspace\"},{\"t\":6,\"n\":\"PNAM - \",\"c\":[{\"t\":3,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unknown\"}]}]},{\"t\":3,\"n\":\"CNAM - Climate\"},{\"t\":3,\"n\":\"NAM2 - Water\"},{\"t\":3,\"n\":\"NAM3 - LOD Water Type\"},{\"t\":5,\"n\":\"NAM4 - LOD Water Height\"},{\"t\":6,\"n\":\"DNAM - Land Data\",\"c\":[{\"t\":5,\"n\":\"Default Land Height\"},{\"t\":5,\"n\":\"Default Water Height\"}]},{\"t\":2,\"n\":\"ICON - Map Image\"},{\"t\":6,\"n\":\"Cloud Model\",\"c\":[{\"t\":6,\"n\":\"Model\",\"c\":[{\"t\":2,\"n\":\"MODL - Model Filename\"}]}]},{\"t\":6,\"n\":\"MNAM - Map Data\",\"c\":[{\"t\":6,\"n\":\"Usable Dimensions\",\"c\":[{\"t\":3,\"n\":\"X\"},{\"t\":3,\"n\":\"Y\"}]},{\"t\":6,\"n\":\"Cell Coordinates\",\"c\":[{\"t\":6,\"n\":\"NW Cell\",\"c\":[{\"t\":3,\"n\":\"X\"},{\"t\":3,\"n\":\"Y\"}]},{\"t\":6,\"n\":\"SE Cell\",\"c\":[{\"t\":3,\"n\":\"X\"},{\"t\":3,\"n\":\"Y\"}]}]},{\"t\":6,\"n\":\"Camera Data\",\"c\":[{\"t\":5,\"n\":\"Min Height\"},{\"t\":5,\"n\":\"Max Height\"},{\"t\":5,\"n\":\"Initial Pitch\"}]}]},{\"t\":6,\"n\":\"ONAM - World Map Offset Data\",\"c\":[{\"t\":5,\"n\":\"World Map Scale\"},{\"t\":5,\"n\":\"Cell X Offset\"},{\"t\":5,\"n\":\"Cell Y Offset\"},{\"t\":5,\"n\":\"Cell Z Offset\"}]},{\"t\":5,\"n\":\"NAMA - Distant LOD Multiplier\"},{\"t\":3,\"n\":\"DATA - Flags\"},{\"t\":6,\"n\":\"Object Bounds\",\"c\":[{\"t\":6,\"n\":\"NAM0 - Min\",\"c\":[{\"t\":5,\"n\":\"X\"},{\"t\":5,\"n\":\"Y\"}]},{\"t\":6,\"n\":\"NAM9 - Max\",\"c\":[{\"t\":5,\"n\":\"X\"},{\"t\":5,\"n\":\"Y\"}]}]},{\"t\":3,\"n\":\"ZNAM - Music\"},{\"t\":2,\"n\":\"NNAM - Canopy Shadow (unused)\"},{\"t\":2,\"n\":\"XNAM - Water Noise Texture\"},{\"t\":2,\"n\":\"TNAM - HD LOD Diffuse Texture\"},{\"t\":2,\"n\":\"UNAM - HD LOD Normal Texture\"},{\"t\":2,\"n\":\"XWEM - Water Environment Map (unused)\"},{\"t\":11,\"n\":\"OFST - Offset Data\"}]},{\"t\":1,\"p\":1,\"n\":\"WTHR - Weather\",\"c\":[{\"t\":6,\"n\":\"Record Header\",\"c\":[{\"t\":2,\"n\":\"Signature\"},{\"t\":3,\"n\":\"Data Size\"},{\"t\":3,\"n\":\"Record Flags\"},{\"t\":3,\"n\":\"FormID\"},{\"t\":11,\"n\":\"Version Control Info 1\"},{\"t\":3,\"n\":\"Form Version\"},{\"t\":11,\"n\":\"Version Control Info 2\"}]},{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"n\":\"00TX - Cloud Texture Layer #0\"},{\"t\":2,\"n\":\"10TX - Cloud Texture Layer #1\"},{\"t\":2,\"n\":\"20TX - Cloud Texture Layer #2\"},{\"t\":2,\"n\":\"30TX - Cloud Texture Layer #3\"},{\"t\":2,\"n\":\"40TX - Cloud Texture Layer #4\"},{\"t\":2,\"n\":\"50TX - Cloud Texture Layer #5\"},{\"t\":2,\"n\":\"60TX - Cloud Texture Layer #6\"},{\"t\":2,\"n\":\"70TX - Cloud Texture Layer #7\"},{\"t\":2,\"n\":\"80TX - Cloud Texture Layer #8\"},{\"t\":2,\"n\":\"90TX - Cloud Texture Layer #9\"},{\"t\":2,\"n\":\":0TX - Cloud Texture Layer #10\"},{\"t\":2,\"n\":\";0TX - Cloud Texture Layer #11\"},{\"t\":2,\"n\":\"<0TX - Cloud Texture Layer #12\"},{\"t\":2,\"n\":\"=0TX - Cloud Texture Layer #13\"},{\"t\":2,\"n\":\">0TX - Cloud Texture Layer #14\"},{\"t\":2,\"n\":\"?0TX - Cloud Texture Layer #15\"},{\"t\":2,\"n\":\"@0TX - Cloud Texture Layer #16\"},{\"t\":2,\"n\":\"A0TX - Cloud Texture Layer #17\"},{\"t\":2,\"n\":\"B0TX - Cloud Texture Layer #18\"},{\"t\":2,\"n\":\"C0TX - Cloud Texture Layer #19\"},{\"t\":2,\"n\":\"D0TX - Cloud Texture Layer #20\"},{\"t\":2,\"n\":\"E0TX - Cloud Texture Layer #21\"},{\"t\":2,\"n\":\"F0TX - Cloud Texture Layer #22\"},{\"t\":2,\"n\":\"G0TX - Cloud Texture Layer #23\"},{\"t\":2,\"n\":\"H0TX - Cloud Texture Layer #24\"},{\"t\":2,\"n\":\"I0TX - Cloud Texture Layer #25\"},{\"t\":2,\"n\":\"J0TX - Cloud Texture Layer #26\"},{\"t\":2,\"n\":\"K0TX - Cloud Texture Layer #27\"},{\"t\":2,\"n\":\"L0TX - Cloud Texture Layer #28\"},{\"t\":11,\"n\":\"DNAM - Unused\"},{\"t\":11,\"n\":\"CNAM - Unused\"},{\"t\":11,\"n\":\"ANAM - Unused\"},{\"t\":11,\"n\":\"BNAM - Unused\"},{\"t\":11,\"n\":\"LNAM - Unknown\"},{\"t\":3,\"n\":\"MNAM - Precipitation Type\"},{\"t\":3,\"n\":\"NNAM - Visual Effect\"},{\"t\":11,\"n\":\"ONAM - Unused\"},{\"t\":6,\"n\":\"Cloud Speed\",\"c\":[{\"t\":7,\"n\":\"RNAM - Y Speed\",\"c\":[{\"t\":3,\"n\":\"Layer #0\"}]}]},{\"t\":8,\"n\":\"PNAM - Cloud Colors\",\"c\":[{\"t\":6,\"n\":\"Layer #0\",\"c\":[{\"t\":8,\"n\":\"Colors\",\"c\":[{\"t\":6,\"n\":\"Time #0 (Sunrise)\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":6,\"n\":\"Time #1 (Day)\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":6,\"n\":\"Time #2 (Sunset)\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":6,\"n\":\"Time #3 (Night)\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unknown\"}]}]}]}]},{\"t\":8,\"n\":\"JNAM - Cloud Alphas\",\"c\":[{\"t\":6,\"n\":\"Layer #0\",\"c\":[{\"t\":5,\"n\":\"Sunrise\"},{\"t\":5,\"n\":\"Day\"},{\"t\":5,\"n\":\"Sunset\"},{\"t\":5,\"n\":\"Night\"}]}]},{\"t\":6,\"n\":\"NAM0 - Weather Colors\",\"c\":[{\"t\":8,\"n\":\"Sky-Upper\",\"c\":[{\"t\":6,\"n\":\"Color #0 (Sunrise)\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":6,\"n\":\"Color #1 (Day)\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":6,\"n\":\"Color #2 (Sunset)\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":6,\"n\":\"Color #3 (Night)\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unknown\"}]}]},{\"t\":8,\"n\":\"Fog Near\",\"c\":[{\"t\":6,\"n\":\"Color #0 (Sunrise)\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":6,\"n\":\"Color #1 (Day)\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":6,\"n\":\"Color #2 (Sunset)\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":6,\"n\":\"Color #3 (Night)\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unknown\"}]}]},{\"t\":8,\"n\":\"Unknown\",\"c\":[{\"t\":6,\"n\":\"Color #0 (Sunrise)\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":6,\"n\":\"Color #1 (Day)\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":6,\"n\":\"Color #2 (Sunset)\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":6,\"n\":\"Color #3 (Night)\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unknown\"}]}]},{\"t\":8,\"n\":\"Ambient\",\"c\":[{\"t\":6,\"n\":\"Color #0 (Sunrise)\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":6,\"n\":\"Color #1 (Day)\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":6,\"n\":\"Color #2 (Sunset)\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":6,\"n\":\"Color #3 (Night)\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unknown\"}]}]},{\"t\":8,\"n\":\"Sunlight\",\"c\":[{\"t\":6,\"n\":\"Color #0 (Sunrise)\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":6,\"n\":\"Color #1 (Day)\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":6,\"n\":\"Color #2 (Sunset)\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":6,\"n\":\"Color #3 (Night)\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unknown\"}]}]},{\"t\":8,\"n\":\"Sun\",\"c\":[{\"t\":6,\"n\":\"Color #0 (Sunrise)\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":6,\"n\":\"Color #1 (Day)\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":6,\"n\":\"Color #2 (Sunset)\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":6,\"n\":\"Color #3 (Night)\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unknown\"}]}]},{\"t\":8,\"n\":\"Stars\",\"c\":[{\"t\":6,\"n\":\"Color #0 (Sunrise)\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":6,\"n\":\"Color #1 (Day)\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":6,\"n\":\"Color #2 (Sunset)\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":6,\"n\":\"Color #3 (Night)\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unknown\"}]}]},{\"t\":8,\"n\":\"Sky-Lower\",\"c\":[{\"t\":6,\"n\":\"Color #0 (Sunrise)\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":6,\"n\":\"Color #1 (Day)\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":6,\"n\":\"Color #2 (Sunset)\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":6,\"n\":\"Color #3 (Night)\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unknown\"}]}]},{\"t\":8,\"n\":\"Horizon\",\"c\":[{\"t\":6,\"n\":\"Color #0 (Sunrise)\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":6,\"n\":\"Color #1 (Day)\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":6,\"n\":\"Color #2 (Sunset)\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":6,\"n\":\"Color #3 (Night)\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unknown\"}]}]},{\"t\":8,\"n\":\"Effect Lighting\",\"c\":[{\"t\":6,\"n\":\"Color #0 (Sunrise)\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":6,\"n\":\"Color #1 (Day)\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":6,\"n\":\"Color #2 (Sunset)\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":6,\"n\":\"Color #3 (Night)\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unknown\"}]}]},{\"t\":8,\"n\":\"Cloud LOD Diffuse\",\"c\":[{\"t\":6,\"n\":\"Color #0 (Sunrise)\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":6,\"n\":\"Color #1 (Day)\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":6,\"n\":\"Color #2 (Sunset)\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":6,\"n\":\"Color #3 (Night)\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unknown\"}]}]},{\"t\":8,\"n\":\"Cloud LOD Ambient\",\"c\":[{\"t\":6,\"n\":\"Color #0 (Sunrise)\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":6,\"n\":\"Color #1 (Day)\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":6,\"n\":\"Color #2 (Sunset)\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":6,\"n\":\"Color #3 (Night)\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unknown\"}]}]},{\"t\":8,\"n\":\"Fog Far\",\"c\":[{\"t\":6,\"n\":\"Color #0 (Sunrise)\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":6,\"n\":\"Color #1 (Day)\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":6,\"n\":\"Color #2 (Sunset)\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":6,\"n\":\"Color #3 (Night)\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unknown\"}]}]},{\"t\":8,\"n\":\"Sky Statics\",\"c\":[{\"t\":6,\"n\":\"Color #0 (Sunrise)\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":6,\"n\":\"Color #1 (Day)\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":6,\"n\":\"Color #2 (Sunset)\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":6,\"n\":\"Color #3 (Night)\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unknown\"}]}]},{\"t\":8,\"n\":\"Water Multiplier\",\"c\":[{\"t\":6,\"n\":\"Color #0 (Sunrise)\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":6,\"n\":\"Color #1 (Day)\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":6,\"n\":\"Color #2 (Sunset)\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":6,\"n\":\"Color #3 (Night)\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unknown\"}]}]},{\"t\":8,\"n\":\"Sun Glare\",\"c\":[{\"t\":6,\"n\":\"Color #0 (Sunrise)\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":6,\"n\":\"Color #1 (Day)\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":6,\"n\":\"Color #2 (Sunset)\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":6,\"n\":\"Color #3 (Night)\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unknown\"}]}]},{\"t\":8,\"n\":\"Moon Glare\",\"c\":[{\"t\":6,\"n\":\"Color #0 (Sunrise)\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":6,\"n\":\"Color #1 (Day)\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":6,\"n\":\"Color #2 (Sunset)\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":6,\"n\":\"Color #3 (Night)\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unknown\"}]}]}]},{\"t\":6,\"n\":\"FNAM - Fog Distance\",\"c\":[{\"t\":5,\"n\":\"Day - Near\"},{\"t\":5,\"n\":\"Day - Far\"},{\"t\":5,\"n\":\"Night - Near\"},{\"t\":5,\"n\":\"Night - Far\"},{\"t\":5,\"n\":\"Day - Power\"},{\"t\":5,\"n\":\"Night - Power\"},{\"t\":5,\"n\":\"Day - Max\"},{\"t\":5,\"n\":\"Night - Max\"}]},{\"t\":6,\"n\":\"DATA - Data\",\"c\":[{\"t\":3,\"n\":\"Wind Speed\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":3,\"n\":\"Trans Delta\"},{\"t\":3,\"n\":\"Sun Glare\"},{\"t\":3,\"n\":\"Sun Damage\"},{\"t\":3,\"n\":\"Precipitation - Begin Fade In\"},{\"t\":3,\"n\":\"Precipitation - End Fade Out\"},{\"t\":3,\"n\":\"Thunder\\/Lightning - Begin Fade In\"},{\"t\":3,\"n\":\"Thunder\\/Lightning - End Fade Out\"},{\"t\":3,\"n\":\"Thunder\\/Lightning - Frequency\"},{\"t\":3,\"n\":\"Flags\"},{\"t\":6,\"n\":\"Lightning Color\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"}]},{\"t\":3,\"n\":\"Visual Effect - Begin\"},{\"t\":3,\"n\":\"Visual Effect - End\"},{\"t\":3,\"n\":\"Wind Direction\"},{\"t\":3,\"n\":\"Wind Direction Range\"}]},{\"t\":3,\"n\":\"NAM1 - Disabled Cloud Layers\"},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Sounds\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"SNAM - Sound\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Sound\"},{\"t\":3,\"p\":1,\"n\":\"Type\"}]}]},{\"t\":9,\"n\":\"Sky Statics\",\"c\":[{\"t\":3,\"n\":\"TNAM - Static\"}]},{\"t\":6,\"n\":\"IMSP - Image Spaces\",\"c\":[{\"t\":3,\"n\":\"Sunrise\"},{\"t\":3,\"n\":\"Day\"},{\"t\":3,\"n\":\"Sunset\"},{\"t\":3,\"n\":\"Night\"}]},{\"t\":8,\"n\":\"Directional Ambient Lighting Colors\",\"c\":[{\"t\":6,\"n\":\"DALC - Sunrise\\/Day\\/Sunset\\/Night Order\",\"c\":[{\"t\":6,\"n\":\"Ambient Colors\",\"c\":[{\"t\":8,\"n\":\"Colors\",\"c\":[{\"t\":6,\"n\":\"Color #0 (X+)\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":6,\"n\":\"Color #1 (X-)\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":6,\"n\":\"Color #2 (Y+)\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":6,\"n\":\"Color #3 (Y-)\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":6,\"n\":\"Color #4 (Z+)\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":6,\"n\":\"Color #5 (Z-)\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unknown\"}]}]},{\"t\":6,\"n\":\"Specular\",\"c\":[{\"t\":6,\"n\":\"Color\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":5,\"n\":\"Fresnel Power\"}]}]}]}]},{\"t\":11,\"n\":\"NAM2 - Unused\"},{\"t\":11,\"n\":\"NAM3 - Unused\"},{\"t\":6,\"n\":\"Aurora\",\"c\":[{\"t\":6,\"n\":\"Model\",\"c\":[{\"t\":2,\"n\":\"MODL - Model Filename\"}]}]}]},{\"t\":1,\"p\":1,\"n\":\"ACHR - Placed NPC\",\"c\":[{\"t\":3,\"n\":\"Cell\"},{\"t\":6,\"n\":\"Record Header\",\"c\":[{\"t\":2,\"n\":\"Signature\"},{\"t\":3,\"n\":\"Data Size\"},{\"t\":3,\"n\":\"Record Flags\",\"c\":[{\"t\":4,\"n\":\"Persistent\"}]},{\"t\":3,\"n\":\"FormID\"},{\"t\":11,\"n\":\"Version Control Info 1\"},{\"t\":3,\"n\":\"Form Version\"},{\"t\":11,\"n\":\"Version Control Info 2\"}]},{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"VMAD - Virtual Machine Adapter\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Version\"},{\"t\":3,\"p\":1,\"n\":\"Object Format\"},{\"t\":12,\"p\":1,\"n\":\"Data\",\"c\":[{\"t\":9,\"p\":1,\"n\":\"Scripts\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Script\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"scriptName\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":9,\"p\":1,\"n\":\"Properties\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Property\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"propertyName\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":12,\"p\":1,\"n\":\"Value\"}]}]}]}]}]}]},{\"t\":3,\"n\":\"NAME - Base\"},{\"t\":3,\"n\":\"XEZN - Encounter Zone\"},{\"t\":11,\"n\":\"XRGD - Ragdoll Data\"},{\"t\":11,\"n\":\"XRGB - Ragdoll Biped Data\"},{\"t\":6,\"n\":\"Patrol Data\",\"c\":[{\"t\":5,\"n\":\"XPRD - Idle Time\"},{\"n\":\"XPPA - Patrol Script Marker\"},{\"t\":3,\"n\":\"INAM - Idle\"}]},{\"t\":3,\"n\":\"XLCM - Level Modifier\"},{\"t\":3,\"n\":\"XMRC - Merchant Container\"},{\"t\":3,\"n\":\"XCNT - Count\"},{\"t\":5,\"n\":\"XRDS - Radius\"},{\"t\":5,\"n\":\"XHLP - Health\"},{\"t\":10,\"n\":\"Linked References\",\"c\":[{\"t\":6,\"n\":\"XLKR - Linked Reference\",\"c\":[{\"t\":3,\"n\":\"Keyword\\/Ref\"},{\"t\":3,\"n\":\"Ref\"}]}]},{\"t\":6,\"n\":\"Activate Parents\",\"c\":[{\"t\":3,\"n\":\"XAPD - Flags\"}]},{\"t\":6,\"n\":\"XCLP - Linked Reference Color\",\"c\":[{\"t\":6,\"n\":\"Link Start Color\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":6,\"n\":\"Link End Color\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unknown\"}]}]},{\"t\":3,\"n\":\"XLCN - Persistent Location\"},{\"t\":3,\"n\":\"XLRL - Location Reference\"},{\"n\":\"XIS2 - Ignored by Sandbox\"},{\"t\":7,\"n\":\"XLRT - Location Ref Type\",\"c\":[{\"t\":3,\"n\":\"Ref #0\"}]},{\"t\":3,\"n\":\"XHOR - Horse\"},{\"t\":5,\"n\":\"XHTW - Head-Tracking Weight\"},{\"t\":5,\"n\":\"XFVC - Favor Cost\"},{\"t\":6,\"n\":\"XESP - Enable Parent\",\"c\":[{\"t\":3,\"n\":\"Reference\"},{\"t\":3,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"n\":\"Ownership\",\"c\":[{\"t\":3,\"n\":\"XOWN - Owner\"}]},{\"t\":3,\"n\":\"XEMI - Emittance\"},{\"t\":3,\"n\":\"XMBR - MultiBound Reference\"},{\"n\":\"XIBS - Ignored By Sandbox\"},{\"t\":5,\"n\":\"XSCL - Scale\"},{\"t\":6,\"n\":\"DATA - Position\\/Rotation\",\"c\":[{\"t\":6,\"n\":\"Position\",\"c\":[{\"t\":5,\"n\":\"X\"},{\"t\":5,\"n\":\"Y\"},{\"t\":5,\"n\":\"Z\"}]},{\"t\":6,\"n\":\"Rotation\",\"c\":[{\"t\":5,\"n\":\"X\"},{\"t\":5,\"n\":\"Y\"},{\"t\":5,\"n\":\"Z\"}]}]}]}]},\"name\":\"Bash.All\",\"hash\":\"51EC207C\",\"color\":255}"
  },
  {
    "path": "frontend/settings/Skyrim/Bash.Body-F.json",
    "content": "{\"records\":\"RACE\",\"description\":\"Body-F tag from Wrye Bash.\\r\\n\\r\\nUsed when the mod modifies female body mesh\\/texture definitions.\",\"tree\":{\"records\":[{\"t\":1,\"p\":1,\"n\":\"RACE - Race\",\"c\":[{\"t\":6,\"n\":\"Record Header\",\"c\":[{\"t\":2,\"n\":\"Signature\"},{\"t\":3,\"n\":\"Data Size\"},{\"t\":3,\"n\":\"Record Flags\"},{\"t\":3,\"n\":\"FormID\"},{\"t\":11,\"n\":\"Version Control Info 1\"},{\"t\":3,\"n\":\"Form Version\"},{\"t\":11,\"n\":\"Version Control Info 2\"}]},{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"n\":\"FULL - Name\"},{\"t\":2,\"n\":\"DESC - Description\"},{\"t\":3,\"n\":\"SPCT - Count\"},{\"t\":9,\"n\":\"Actor Effects\",\"c\":[{\"t\":3,\"n\":\"SPLO - Actor Effect\"}]},{\"t\":3,\"n\":\"WNAM - Skin\"},{\"t\":6,\"n\":\"BOD2 - Biped Body Template\",\"c\":[{\"t\":3,\"n\":\"First Person Flags\"},{\"t\":3,\"n\":\"General Flags\"},{\"n\":\"Unused\"},{\"t\":3,\"n\":\"Armor Type\"}]},{\"t\":3,\"n\":\"KSIZ - Keyword Count\"},{\"t\":9,\"n\":\"KWDA - Keywords\",\"c\":[{\"t\":3,\"n\":\"Keyword\"}]},{\"t\":6,\"n\":\"DATA - \",\"c\":[{\"t\":10,\"n\":\"Skill Boosts\",\"c\":[{\"t\":6,\"n\":\"Skill Boost\",\"c\":[{\"t\":3,\"n\":\"Skill\"},{\"t\":3,\"n\":\"Boost\"}]},{\"t\":6,\"n\":\"Skill Boost\",\"c\":[{\"t\":3,\"n\":\"Skill\"},{\"t\":3,\"n\":\"Boost\"}]},{\"t\":6,\"n\":\"Skill Boost\",\"c\":[{\"t\":3,\"n\":\"Skill\"},{\"t\":3,\"n\":\"Boost\"}]},{\"t\":6,\"n\":\"Skill Boost\",\"c\":[{\"t\":3,\"n\":\"Skill\"},{\"t\":3,\"n\":\"Boost\"}]},{\"t\":6,\"n\":\"Skill Boost\",\"c\":[{\"t\":3,\"n\":\"Skill\"},{\"t\":3,\"n\":\"Boost\"}]},{\"t\":6,\"n\":\"Skill Boost\",\"c\":[{\"t\":3,\"n\":\"Skill\"},{\"t\":3,\"n\":\"Boost\"}]},{\"t\":6,\"n\":\"Skill Boost\",\"c\":[{\"t\":3,\"n\":\"Skill\"},{\"t\":3,\"n\":\"Boost\"}]}]},{\"t\":11,\"n\":\"Unknown\"},{\"t\":5,\"n\":\"Male Height\"},{\"t\":5,\"n\":\"Female Height\"},{\"t\":5,\"n\":\"Male Weight\"},{\"t\":5,\"n\":\"Female Weight\"},{\"t\":3,\"n\":\"Flags\"},{\"t\":5,\"n\":\"Starting Health\"},{\"t\":5,\"n\":\"Starting Magicka\"},{\"t\":5,\"n\":\"Starting Stamina\"},{\"t\":5,\"n\":\"Base Carry Weight\"},{\"t\":5,\"n\":\"Base Mass\"},{\"t\":5,\"n\":\"Acceleration rate\"},{\"t\":5,\"n\":\"Deceleration rate\"},{\"t\":3,\"n\":\"Size\"},{\"t\":3,\"n\":\"Head Biped Object\"},{\"t\":3,\"n\":\"Hair Biped Object\"},{\"t\":5,\"n\":\"Injured Health Pct\"},{\"t\":3,\"n\":\"Shield Biped Object\"},{\"t\":5,\"n\":\"Health Regen\"},{\"t\":5,\"n\":\"Magicka Regen\"},{\"t\":5,\"n\":\"Stamina Regen\"},{\"t\":5,\"n\":\"Unarmed Damage\"},{\"t\":5,\"n\":\"Unarmed Reach\"},{\"t\":3,\"n\":\"Body Biped Object\"},{\"t\":5,\"n\":\"Aim Angle Tolerance\"},{\"t\":5,\"n\":\"Flight Radius\"},{\"t\":5,\"n\":\"Angular Acceleration Rate\"},{\"t\":5,\"n\":\"Angular Tolerance\"},{\"t\":3,\"n\":\"Flags 2\"},{\"t\":6,\"n\":\"Mount Data\",\"c\":[{\"t\":5,\"n\":\"Offset X\"},{\"t\":5,\"n\":\"Offset Y\"},{\"t\":5,\"n\":\"Unknown\"},{\"t\":5,\"n\":\"Unknown\"},{\"t\":5,\"n\":\"Unknown\"},{\"t\":5,\"n\":\"Unknown\"},{\"t\":5,\"n\":\"Unknown\"},{\"t\":5,\"n\":\"Unknown\"},{\"t\":5,\"n\":\"Unknown\"}]}]},{\"n\":\"MNAM - Male Marker\"},{\"t\":2,\"n\":\"ANAM - Male Skeletal Model\"},{\"t\":11,\"n\":\"MODT - Texture Files Hashes\"},{\"n\":\"FNAM - Female Marker\"},{\"t\":2,\"n\":\"ANAM - Female Skeletal Model\"},{\"t\":11,\"n\":\"MODT - Texture Files Hashes\"},{\"n\":\"NAM2 - Marker NAM2 #1\"},{\"t\":9,\"n\":\"Movement Type Names\",\"c\":[{\"t\":2,\"n\":\"MTNM - Name\"}]},{\"t\":7,\"n\":\"VTCK - Voices\",\"c\":[{\"t\":3,\"n\":\"Voice #0 (Male)\"},{\"t\":3,\"n\":\"Voice #1 (Female)\"}]},{\"t\":7,\"n\":\"DNAM - Decapitate Armors\",\"c\":[{\"t\":3,\"n\":\"Decapitate Armor #0 (Male)\"},{\"t\":3,\"n\":\"Decapitate Armor #1 (Female)\"}]},{\"t\":7,\"n\":\"HCLF - Default Hair Colors\",\"c\":[{\"t\":3,\"n\":\"Default Hair Color #0 (Male)\"},{\"t\":3,\"n\":\"Default Hair Color #1 (Female)\"}]},{\"t\":3,\"n\":\"TINL - Total Number of Tints in List\"},{\"t\":5,\"n\":\"PNAM - FaceGen - Main clamp\"},{\"t\":5,\"n\":\"UNAM - FaceGen - Face clamp\"},{\"t\":3,\"n\":\"ATKR - Attack Race\"},{\"t\":10,\"n\":\"Attacks\",\"c\":[{\"t\":6,\"n\":\"Attack\",\"c\":[{\"t\":6,\"n\":\"ATKD - Attack Data\",\"c\":[{\"t\":5,\"n\":\"Damage Mult\"},{\"t\":5,\"n\":\"Attack Chance\"},{\"t\":3,\"n\":\"Attack Spell\"},{\"t\":3,\"n\":\"Attack Flags\"},{\"t\":5,\"n\":\"Attack Angle\"},{\"t\":5,\"n\":\"Strike Angle\"},{\"t\":5,\"n\":\"Stagger\"},{\"t\":3,\"n\":\"Attack Type\"},{\"t\":5,\"n\":\"Knockdown\"},{\"t\":5,\"n\":\"Recovery Time\"},{\"t\":5,\"n\":\"Stamina Mult\"}]}]}]},{\"t\":6,\"p\":1,\"n\":\"Body Data\",\"c\":[{\"n\":\"NAM1 - Body Data Marker\"},{\"t\":6,\"n\":\"Male Body Data\",\"c\":[{\"n\":\"MNAM - Male Data Marker\"},{\"t\":10,\"n\":\"Parts\",\"c\":[{\"t\":6,\"n\":\"Part\",\"c\":[{\"t\":3,\"n\":\"INDX - Index\"}]}]}]},{\"t\":6,\"p\":1,\"n\":\"Female Body Data\",\"c\":[{\"n\":\"FNAM - Female Data Marker\"},{\"t\":10,\"s\":1,\"p\":1,\"n\":\"Parts\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Part\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"INDX - Index\"}]}]}]}]},{\"t\":9,\"n\":\"HNAM - Hairs\",\"c\":[{\"t\":3,\"n\":\"Hair\"}]},{\"t\":9,\"n\":\"ENAM - Eyes\",\"c\":[{\"t\":3,\"n\":\"Eye\"}]},{\"t\":3,\"n\":\"GNAM - Body Part Data\"},{\"n\":\"NAM2 - Marker NAM2 #2\"},{\"n\":\"NAM3 - Marker NAM3 #3\"},{\"t\":6,\"n\":\"Male Behavior Graph\",\"c\":[{\"n\":\"MNAM - Male Data Marker\"}]},{\"t\":6,\"n\":\"Female Behavior Graph\",\"c\":[{\"n\":\"FNAM - Female Data Marker\"}]},{\"t\":3,\"n\":\"NAM4 - Material Type\"},{\"t\":3,\"n\":\"NAM5 - Impact Data Set\"},{\"t\":3,\"n\":\"NAM7 - Decapitation FX\"},{\"t\":3,\"n\":\"ONAM - Open Loot Sound\"},{\"t\":3,\"n\":\"LNAM - Close Loot Sound\"},{\"t\":7,\"n\":\"Biped Object Names\",\"c\":[{\"t\":2,\"n\":\"NAME - Name\"}]},{\"t\":10,\"n\":\"Movement Types\",\"c\":[{\"t\":6,\"n\":\"Movement Types\",\"c\":[{\"t\":3,\"n\":\"MTYP - Movement Type\"}]}]},{\"t\":3,\"n\":\"VNAM - Equipment Flags\"},{\"t\":9,\"n\":\"Equip Slots\",\"c\":[{\"t\":3,\"n\":\"QNAM - Equip Slot\"}]},{\"t\":3,\"n\":\"UNES - Unarmed Equip Slot\"},{\"t\":7,\"n\":\"Phoneme Target Names\",\"c\":[{\"t\":2,\"n\":\"PHTN - Name\"}]},{\"t\":6,\"n\":\"FaceFX Phonemes\",\"c\":[{\"t\":6,\"n\":\"IY\",\"c\":[{\"t\":6,\"n\":\"PHWT - Phoneme Target Weight\",\"c\":[{\"t\":5,\"n\":\"Aah \\/ LipBigAah\"},{\"t\":5,\"n\":\"BigAah \\/ LipDST\"},{\"t\":5,\"n\":\"BMP \\/ LipEee\"},{\"t\":5,\"n\":\"ChJsh \\/ LipFV\"},{\"t\":5,\"n\":\"DST \\/ LipK\"},{\"t\":5,\"n\":\"Eee \\/ LipL\"},{\"t\":5,\"n\":\"Eh \\/ LipR\"},{\"t\":5,\"n\":\"FV \\/ LipTh\"},{\"t\":5,\"n\":\"I\"},{\"t\":5,\"n\":\"K\"},{\"t\":5,\"n\":\"N\"},{\"t\":5,\"n\":\"Oh\"},{\"t\":5,\"n\":\"OohQ\"},{\"t\":5,\"n\":\"R\"},{\"t\":5,\"n\":\"TH\"},{\"t\":5,\"n\":\"W\"}]}]}]},{\"t\":3,\"n\":\"WKMV - Base Movement Default - Walk\"},{\"t\":3,\"n\":\"RNMV - Base Movement Default - Run\"},{\"t\":3,\"n\":\"SWMV - Base Movement Default - Swim\"},{\"t\":3,\"n\":\"FLMV - Base Movement Default - Fly\"},{\"t\":3,\"n\":\"SNMV - Base Movement Default - Sneak\"},{\"t\":3,\"n\":\"SPMV - Base Movement Default - Sprint\"},{\"t\":6,\"n\":\"Head Data\",\"c\":[{\"n\":\"NAM0 - Head Data Marker\"},{\"t\":6,\"n\":\"Male Head Data\",\"c\":[{\"n\":\"MNAM - Male Data Marker\"}]},{\"t\":6,\"n\":\"Female Head Data\",\"c\":[{\"n\":\"NAM0 - Head Data Marker\"},{\"n\":\"FNAM - Female Data Marker\"}]}]},{\"t\":3,\"n\":\"NAM8 - Morph race\"},{\"t\":3,\"n\":\"RNAM - Armor race\"}]}]},\"name\":\"Bash.Body-F\",\"hash\":\"$8D501033\",\"color\":255}"
  },
  {
    "path": "frontend/settings/Skyrim/Bash.Body-M.json",
    "content": "{\"records\":\"RACE\",\"description\":\"Body-M tag from Wrye Bash.\\r\\n\\r\\nUsed when the mod modifies male body mesh\\/texture definitions.\",\"tree\":{\"records\":[{\"t\":1,\"p\":1,\"n\":\"RACE - Race\",\"c\":[{\"t\":6,\"n\":\"Record Header\",\"c\":[{\"t\":2,\"n\":\"Signature\"},{\"t\":3,\"n\":\"Data Size\"},{\"t\":3,\"n\":\"Record Flags\"},{\"t\":3,\"n\":\"FormID\"},{\"t\":11,\"n\":\"Version Control Info 1\"},{\"t\":3,\"n\":\"Form Version\"},{\"t\":11,\"n\":\"Version Control Info 2\"}]},{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"n\":\"FULL - Name\"},{\"t\":2,\"n\":\"DESC - Description\"},{\"t\":3,\"n\":\"SPCT - Count\"},{\"t\":9,\"n\":\"Actor Effects\",\"c\":[{\"t\":3,\"n\":\"SPLO - Actor Effect\"}]},{\"t\":3,\"n\":\"WNAM - Skin\"},{\"t\":6,\"n\":\"BOD2 - Biped Body Template\",\"c\":[{\"t\":3,\"n\":\"First Person Flags\"},{\"t\":3,\"n\":\"General Flags\"},{\"n\":\"Unused\"},{\"t\":3,\"n\":\"Armor Type\"}]},{\"t\":3,\"n\":\"KSIZ - Keyword Count\"},{\"t\":9,\"n\":\"KWDA - Keywords\",\"c\":[{\"t\":3,\"n\":\"Keyword\"}]},{\"t\":6,\"n\":\"DATA - \",\"c\":[{\"t\":10,\"n\":\"Skill Boosts\",\"c\":[{\"t\":6,\"n\":\"Skill Boost\",\"c\":[{\"t\":3,\"n\":\"Skill\"},{\"t\":3,\"n\":\"Boost\"}]},{\"t\":6,\"n\":\"Skill Boost\",\"c\":[{\"t\":3,\"n\":\"Skill\"},{\"t\":3,\"n\":\"Boost\"}]},{\"t\":6,\"n\":\"Skill Boost\",\"c\":[{\"t\":3,\"n\":\"Skill\"},{\"t\":3,\"n\":\"Boost\"}]},{\"t\":6,\"n\":\"Skill Boost\",\"c\":[{\"t\":3,\"n\":\"Skill\"},{\"t\":3,\"n\":\"Boost\"}]},{\"t\":6,\"n\":\"Skill Boost\",\"c\":[{\"t\":3,\"n\":\"Skill\"},{\"t\":3,\"n\":\"Boost\"}]},{\"t\":6,\"n\":\"Skill Boost\",\"c\":[{\"t\":3,\"n\":\"Skill\"},{\"t\":3,\"n\":\"Boost\"}]},{\"t\":6,\"n\":\"Skill Boost\",\"c\":[{\"t\":3,\"n\":\"Skill\"},{\"t\":3,\"n\":\"Boost\"}]}]},{\"t\":11,\"n\":\"Unknown\"},{\"t\":5,\"n\":\"Male Height\"},{\"t\":5,\"n\":\"Female Height\"},{\"t\":5,\"n\":\"Male Weight\"},{\"t\":5,\"n\":\"Female Weight\"},{\"t\":3,\"n\":\"Flags\"},{\"t\":5,\"n\":\"Starting Health\"},{\"t\":5,\"n\":\"Starting Magicka\"},{\"t\":5,\"n\":\"Starting Stamina\"},{\"t\":5,\"n\":\"Base Carry Weight\"},{\"t\":5,\"n\":\"Base Mass\"},{\"t\":5,\"n\":\"Acceleration rate\"},{\"t\":5,\"n\":\"Deceleration rate\"},{\"t\":3,\"n\":\"Size\"},{\"t\":3,\"n\":\"Head Biped Object\"},{\"t\":3,\"n\":\"Hair Biped Object\"},{\"t\":5,\"n\":\"Injured Health Pct\"},{\"t\":3,\"n\":\"Shield Biped Object\"},{\"t\":5,\"n\":\"Health Regen\"},{\"t\":5,\"n\":\"Magicka Regen\"},{\"t\":5,\"n\":\"Stamina Regen\"},{\"t\":5,\"n\":\"Unarmed Damage\"},{\"t\":5,\"n\":\"Unarmed Reach\"},{\"t\":3,\"n\":\"Body Biped Object\"},{\"t\":5,\"n\":\"Aim Angle Tolerance\"},{\"t\":5,\"n\":\"Flight Radius\"},{\"t\":5,\"n\":\"Angular Acceleration Rate\"},{\"t\":5,\"n\":\"Angular Tolerance\"},{\"t\":3,\"n\":\"Flags 2\"},{\"t\":6,\"n\":\"Mount Data\",\"c\":[{\"t\":5,\"n\":\"Offset X\"},{\"t\":5,\"n\":\"Offset Y\"},{\"t\":5,\"n\":\"Unknown\"},{\"t\":5,\"n\":\"Unknown\"},{\"t\":5,\"n\":\"Unknown\"},{\"t\":5,\"n\":\"Unknown\"},{\"t\":5,\"n\":\"Unknown\"},{\"t\":5,\"n\":\"Unknown\"},{\"t\":5,\"n\":\"Unknown\"}]}]},{\"n\":\"MNAM - Male Marker\"},{\"t\":2,\"n\":\"ANAM - Male Skeletal Model\"},{\"t\":11,\"n\":\"MODT - Texture Files Hashes\"},{\"n\":\"FNAM - Female Marker\"},{\"t\":2,\"n\":\"ANAM - Female Skeletal Model\"},{\"t\":11,\"n\":\"MODT - Texture Files Hashes\"},{\"n\":\"NAM2 - Marker NAM2 #1\"},{\"t\":9,\"n\":\"Movement Type Names\",\"c\":[{\"t\":2,\"n\":\"MTNM - Name\"}]},{\"t\":7,\"n\":\"VTCK - Voices\",\"c\":[{\"t\":3,\"n\":\"Voice #0 (Male)\"},{\"t\":3,\"n\":\"Voice #1 (Female)\"}]},{\"t\":7,\"n\":\"DNAM - Decapitate Armors\",\"c\":[{\"t\":3,\"n\":\"Decapitate Armor #0 (Male)\"},{\"t\":3,\"n\":\"Decapitate Armor #1 (Female)\"}]},{\"t\":7,\"n\":\"HCLF - Default Hair Colors\",\"c\":[{\"t\":3,\"n\":\"Default Hair Color #0 (Male)\"},{\"t\":3,\"n\":\"Default Hair Color #1 (Female)\"}]},{\"t\":3,\"n\":\"TINL - Total Number of Tints in List\"},{\"t\":5,\"n\":\"PNAM - FaceGen - Main clamp\"},{\"t\":5,\"n\":\"UNAM - FaceGen - Face clamp\"},{\"t\":3,\"n\":\"ATKR - Attack Race\"},{\"t\":10,\"n\":\"Attacks\",\"c\":[{\"t\":6,\"n\":\"Attack\",\"c\":[{\"t\":6,\"n\":\"ATKD - Attack Data\",\"c\":[{\"t\":5,\"n\":\"Damage Mult\"},{\"t\":5,\"n\":\"Attack Chance\"},{\"t\":3,\"n\":\"Attack Spell\"},{\"t\":3,\"n\":\"Attack Flags\"},{\"t\":5,\"n\":\"Attack Angle\"},{\"t\":5,\"n\":\"Strike Angle\"},{\"t\":5,\"n\":\"Stagger\"},{\"t\":3,\"n\":\"Attack Type\"},{\"t\":5,\"n\":\"Knockdown\"},{\"t\":5,\"n\":\"Recovery Time\"},{\"t\":5,\"n\":\"Stamina Mult\"}]}]}]},{\"t\":6,\"p\":1,\"n\":\"Body Data\",\"c\":[{\"n\":\"NAM1 - Body Data Marker\"},{\"t\":6,\"p\":1,\"n\":\"Male Body Data\",\"c\":[{\"n\":\"MNAM - Male Data Marker\"},{\"t\":10,\"s\":1,\"p\":1,\"n\":\"Parts\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Part\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"INDX - Index\"}]}]}]},{\"t\":6,\"n\":\"Female Body Data\",\"c\":[{\"n\":\"FNAM - Female Data Marker\"},{\"t\":10,\"n\":\"Parts\",\"c\":[{\"t\":6,\"n\":\"Part\",\"c\":[{\"t\":3,\"n\":\"INDX - Index\"}]}]}]}]},{\"t\":9,\"n\":\"HNAM - Hairs\",\"c\":[{\"t\":3,\"n\":\"Hair\"}]},{\"t\":9,\"n\":\"ENAM - Eyes\",\"c\":[{\"t\":3,\"n\":\"Eye\"}]},{\"t\":3,\"n\":\"GNAM - Body Part Data\"},{\"n\":\"NAM2 - Marker NAM2 #2\"},{\"n\":\"NAM3 - Marker NAM3 #3\"},{\"t\":6,\"n\":\"Male Behavior Graph\",\"c\":[{\"n\":\"MNAM - Male Data Marker\"}]},{\"t\":6,\"n\":\"Female Behavior Graph\",\"c\":[{\"n\":\"FNAM - Female Data Marker\"}]},{\"t\":3,\"n\":\"NAM4 - Material Type\"},{\"t\":3,\"n\":\"NAM5 - Impact Data Set\"},{\"t\":3,\"n\":\"NAM7 - Decapitation FX\"},{\"t\":3,\"n\":\"ONAM - Open Loot Sound\"},{\"t\":3,\"n\":\"LNAM - Close Loot Sound\"},{\"t\":7,\"n\":\"Biped Object Names\",\"c\":[{\"t\":2,\"n\":\"NAME - Name\"}]},{\"t\":10,\"n\":\"Movement Types\",\"c\":[{\"t\":6,\"n\":\"Movement Types\",\"c\":[{\"t\":3,\"n\":\"MTYP - Movement Type\"}]}]},{\"t\":3,\"n\":\"VNAM - Equipment Flags\"},{\"t\":9,\"n\":\"Equip Slots\",\"c\":[{\"t\":3,\"n\":\"QNAM - Equip Slot\"}]},{\"t\":3,\"n\":\"UNES - Unarmed Equip Slot\"},{\"t\":7,\"n\":\"Phoneme Target Names\",\"c\":[{\"t\":2,\"n\":\"PHTN - Name\"}]},{\"t\":6,\"n\":\"FaceFX Phonemes\",\"c\":[{\"t\":6,\"n\":\"IY\",\"c\":[{\"t\":6,\"n\":\"PHWT - Phoneme Target Weight\",\"c\":[{\"t\":5,\"n\":\"Aah \\/ LipBigAah\"},{\"t\":5,\"n\":\"BigAah \\/ LipDST\"},{\"t\":5,\"n\":\"BMP \\/ LipEee\"},{\"t\":5,\"n\":\"ChJsh \\/ LipFV\"},{\"t\":5,\"n\":\"DST \\/ LipK\"},{\"t\":5,\"n\":\"Eee \\/ LipL\"},{\"t\":5,\"n\":\"Eh \\/ LipR\"},{\"t\":5,\"n\":\"FV \\/ LipTh\"},{\"t\":5,\"n\":\"I\"},{\"t\":5,\"n\":\"K\"},{\"t\":5,\"n\":\"N\"},{\"t\":5,\"n\":\"Oh\"},{\"t\":5,\"n\":\"OohQ\"},{\"t\":5,\"n\":\"R\"},{\"t\":5,\"n\":\"TH\"},{\"t\":5,\"n\":\"W\"}]}]}]},{\"t\":3,\"n\":\"WKMV - Base Movement Default - Walk\"},{\"t\":3,\"n\":\"RNMV - Base Movement Default - Run\"},{\"t\":3,\"n\":\"SWMV - Base Movement Default - Swim\"},{\"t\":3,\"n\":\"FLMV - Base Movement Default - Fly\"},{\"t\":3,\"n\":\"SNMV - Base Movement Default - Sneak\"},{\"t\":3,\"n\":\"SPMV - Base Movement Default - Sprint\"},{\"t\":6,\"n\":\"Head Data\",\"c\":[{\"n\":\"NAM0 - Head Data Marker\"},{\"t\":6,\"n\":\"Male Head Data\",\"c\":[{\"n\":\"MNAM - Male Data Marker\"}]},{\"t\":6,\"n\":\"Female Head Data\",\"c\":[{\"n\":\"NAM0 - Head Data Marker\"},{\"n\":\"FNAM - Female Data Marker\"}]}]},{\"t\":3,\"n\":\"NAM8 - Morph race\"},{\"t\":3,\"n\":\"RNAM - Armor race\"}]}]},\"name\":\"Bash.Body-M\",\"hash\":\"$8D185280\",\"color\":255}"
  },
  {
    "path": "frontend/settings/Skyrim/Bash.Body-Size-F.json",
    "content": "{\"records\":\"RACE\",\"description\":\"Body-Size-F tag from Wrye Bash.\\r\\n\\r\\nUsed when the mod modifies female body weight\\/height definitions.\",\"tree\":{\"records\":[{\"t\":1,\"p\":1,\"n\":\"RACE - Race\",\"c\":[{\"t\":6,\"n\":\"Record Header\",\"c\":[{\"t\":2,\"n\":\"Signature\"},{\"t\":3,\"n\":\"Data Size\"},{\"t\":3,\"n\":\"Record Flags\"},{\"t\":3,\"n\":\"FormID\"},{\"t\":11,\"n\":\"Version Control Info 1\"},{\"t\":3,\"n\":\"Form Version\"},{\"t\":11,\"n\":\"Version Control Info 2\"}]},{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"n\":\"FULL - Name\"},{\"t\":2,\"n\":\"DESC - Description\"},{\"t\":3,\"n\":\"SPCT - Count\"},{\"t\":9,\"n\":\"Actor Effects\",\"c\":[{\"t\":3,\"n\":\"SPLO - Actor Effect\"}]},{\"t\":3,\"n\":\"WNAM - Skin\"},{\"t\":6,\"n\":\"BOD2 - Biped Body Template\",\"c\":[{\"t\":3,\"n\":\"First Person Flags\"},{\"t\":3,\"n\":\"General Flags\"},{\"n\":\"Unused\"},{\"t\":3,\"n\":\"Armor Type\"}]},{\"t\":3,\"n\":\"KSIZ - Keyword Count\"},{\"t\":9,\"n\":\"KWDA - Keywords\",\"c\":[{\"t\":3,\"n\":\"Keyword\"}]},{\"t\":6,\"p\":1,\"n\":\"DATA - \",\"c\":[{\"t\":10,\"n\":\"Skill Boosts\",\"c\":[{\"t\":6,\"n\":\"Skill Boost\",\"c\":[{\"t\":3,\"n\":\"Skill\"},{\"t\":3,\"n\":\"Boost\"}]},{\"t\":6,\"n\":\"Skill Boost\",\"c\":[{\"t\":3,\"n\":\"Skill\"},{\"t\":3,\"n\":\"Boost\"}]},{\"t\":6,\"n\":\"Skill Boost\",\"c\":[{\"t\":3,\"n\":\"Skill\"},{\"t\":3,\"n\":\"Boost\"}]},{\"t\":6,\"n\":\"Skill Boost\",\"c\":[{\"t\":3,\"n\":\"Skill\"},{\"t\":3,\"n\":\"Boost\"}]},{\"t\":6,\"n\":\"Skill Boost\",\"c\":[{\"t\":3,\"n\":\"Skill\"},{\"t\":3,\"n\":\"Boost\"}]},{\"t\":6,\"n\":\"Skill Boost\",\"c\":[{\"t\":3,\"n\":\"Skill\"},{\"t\":3,\"n\":\"Boost\"}]},{\"t\":6,\"n\":\"Skill Boost\",\"c\":[{\"t\":3,\"n\":\"Skill\"},{\"t\":3,\"n\":\"Boost\"}]}]},{\"t\":11,\"n\":\"Unknown\"},{\"t\":5,\"n\":\"Male Height\"},{\"t\":5,\"p\":1,\"n\":\"Female Height\"},{\"t\":5,\"n\":\"Male Weight\"},{\"t\":5,\"p\":1,\"n\":\"Female Weight\"},{\"t\":3,\"n\":\"Flags\"},{\"t\":5,\"n\":\"Starting Health\"},{\"t\":5,\"n\":\"Starting Magicka\"},{\"t\":5,\"n\":\"Starting Stamina\"},{\"t\":5,\"n\":\"Base Carry Weight\"},{\"t\":5,\"n\":\"Base Mass\"},{\"t\":5,\"n\":\"Acceleration rate\"},{\"t\":5,\"n\":\"Deceleration rate\"},{\"t\":3,\"n\":\"Size\"},{\"t\":3,\"n\":\"Head Biped Object\"},{\"t\":3,\"n\":\"Hair Biped Object\"},{\"t\":5,\"n\":\"Injured Health Pct\"},{\"t\":3,\"n\":\"Shield Biped Object\"},{\"t\":5,\"n\":\"Health Regen\"},{\"t\":5,\"n\":\"Magicka Regen\"},{\"t\":5,\"n\":\"Stamina Regen\"},{\"t\":5,\"n\":\"Unarmed Damage\"},{\"t\":5,\"n\":\"Unarmed Reach\"},{\"t\":3,\"n\":\"Body Biped Object\"},{\"t\":5,\"n\":\"Aim Angle Tolerance\"},{\"t\":5,\"n\":\"Flight Radius\"},{\"t\":5,\"n\":\"Angular Acceleration Rate\"},{\"t\":5,\"n\":\"Angular Tolerance\"},{\"t\":3,\"n\":\"Flags 2\"},{\"t\":6,\"n\":\"Mount Data\",\"c\":[{\"t\":5,\"n\":\"Offset X\"},{\"t\":5,\"n\":\"Offset Y\"},{\"t\":5,\"n\":\"Unknown\"},{\"t\":5,\"n\":\"Unknown\"},{\"t\":5,\"n\":\"Unknown\"},{\"t\":5,\"n\":\"Unknown\"},{\"t\":5,\"n\":\"Unknown\"},{\"t\":5,\"n\":\"Unknown\"},{\"t\":5,\"n\":\"Unknown\"}]}]},{\"n\":\"MNAM - Male Marker\"},{\"t\":2,\"n\":\"ANAM - Male Skeletal Model\"},{\"t\":11,\"n\":\"MODT - Texture Files Hashes\"},{\"n\":\"FNAM - Female Marker\"},{\"t\":2,\"n\":\"ANAM - Female Skeletal Model\"},{\"t\":11,\"n\":\"MODT - Texture Files Hashes\"},{\"n\":\"NAM2 - Marker NAM2 #1\"},{\"t\":9,\"n\":\"Movement Type Names\",\"c\":[{\"t\":2,\"n\":\"MTNM - Name\"}]},{\"t\":7,\"n\":\"VTCK - Voices\",\"c\":[{\"t\":3,\"n\":\"Voice #0 (Male)\"},{\"t\":3,\"n\":\"Voice #1 (Female)\"}]},{\"t\":7,\"n\":\"DNAM - Decapitate Armors\",\"c\":[{\"t\":3,\"n\":\"Decapitate Armor #0 (Male)\"},{\"t\":3,\"n\":\"Decapitate Armor #1 (Female)\"}]},{\"t\":7,\"n\":\"HCLF - Default Hair Colors\",\"c\":[{\"t\":3,\"n\":\"Default Hair Color #0 (Male)\"},{\"t\":3,\"n\":\"Default Hair Color #1 (Female)\"}]},{\"t\":3,\"n\":\"TINL - Total Number of Tints in List\"},{\"t\":5,\"n\":\"PNAM - FaceGen - Main clamp\"},{\"t\":5,\"n\":\"UNAM - FaceGen - Face clamp\"},{\"t\":3,\"n\":\"ATKR - Attack Race\"},{\"t\":10,\"n\":\"Attacks\",\"c\":[{\"t\":6,\"n\":\"Attack\",\"c\":[{\"t\":6,\"n\":\"ATKD - Attack Data\",\"c\":[{\"t\":5,\"n\":\"Damage Mult\"},{\"t\":5,\"n\":\"Attack Chance\"},{\"t\":3,\"n\":\"Attack Spell\"},{\"t\":3,\"n\":\"Attack Flags\"},{\"t\":5,\"n\":\"Attack Angle\"},{\"t\":5,\"n\":\"Strike Angle\"},{\"t\":5,\"n\":\"Stagger\"},{\"t\":3,\"n\":\"Attack Type\"},{\"t\":5,\"n\":\"Knockdown\"},{\"t\":5,\"n\":\"Recovery Time\"},{\"t\":5,\"n\":\"Stamina Mult\"}]}]}]},{\"t\":6,\"n\":\"Body Data\",\"c\":[{\"n\":\"NAM1 - Body Data Marker\"},{\"t\":6,\"n\":\"Male Body Data\",\"c\":[{\"n\":\"MNAM - Male Data Marker\"},{\"t\":10,\"n\":\"Parts\",\"d\":1,\"c\":[{\"t\":6,\"n\":\"Part\",\"c\":[{\"t\":3,\"n\":\"INDX - Index\"}]}]}]},{\"t\":6,\"n\":\"Female Body Data\",\"c\":[{\"n\":\"FNAM - Female Data Marker\"},{\"t\":10,\"n\":\"Parts\",\"c\":[{\"t\":6,\"n\":\"Part\",\"c\":[{\"t\":3,\"n\":\"INDX - Index\"}]}]}]}]},{\"t\":9,\"n\":\"HNAM - Hairs\",\"c\":[{\"t\":3,\"n\":\"Hair\"}]},{\"t\":9,\"n\":\"ENAM - Eyes\",\"c\":[{\"t\":3,\"n\":\"Eye\"}]},{\"t\":3,\"n\":\"GNAM - Body Part Data\"},{\"n\":\"NAM2 - Marker NAM2 #2\"},{\"n\":\"NAM3 - Marker NAM3 #3\"},{\"t\":6,\"n\":\"Male Behavior Graph\",\"c\":[{\"n\":\"MNAM - Male Data Marker\"}]},{\"t\":6,\"n\":\"Female Behavior Graph\",\"c\":[{\"n\":\"FNAM - Female Data Marker\"}]},{\"t\":3,\"n\":\"NAM4 - Material Type\"},{\"t\":3,\"n\":\"NAM5 - Impact Data Set\"},{\"t\":3,\"n\":\"NAM7 - Decapitation FX\"},{\"t\":3,\"n\":\"ONAM - Open Loot Sound\"},{\"t\":3,\"n\":\"LNAM - Close Loot Sound\"},{\"t\":7,\"n\":\"Biped Object Names\",\"c\":[{\"t\":2,\"n\":\"NAME - Name\"}]},{\"t\":10,\"n\":\"Movement Types\",\"c\":[{\"t\":6,\"n\":\"Movement Types\",\"c\":[{\"t\":3,\"n\":\"MTYP - Movement Type\"}]}]},{\"t\":3,\"n\":\"VNAM - Equipment Flags\"},{\"t\":9,\"n\":\"Equip Slots\",\"c\":[{\"t\":3,\"n\":\"QNAM - Equip Slot\"}]},{\"t\":3,\"n\":\"UNES - Unarmed Equip Slot\"},{\"t\":7,\"n\":\"Phoneme Target Names\",\"c\":[{\"t\":2,\"n\":\"PHTN - Name\"}]},{\"t\":6,\"n\":\"FaceFX Phonemes\",\"c\":[{\"t\":6,\"n\":\"IY\",\"c\":[{\"t\":6,\"n\":\"PHWT - Phoneme Target Weight\",\"c\":[{\"t\":5,\"n\":\"Aah \\/ LipBigAah\"},{\"t\":5,\"n\":\"BigAah \\/ LipDST\"},{\"t\":5,\"n\":\"BMP \\/ LipEee\"},{\"t\":5,\"n\":\"ChJsh \\/ LipFV\"},{\"t\":5,\"n\":\"DST \\/ LipK\"},{\"t\":5,\"n\":\"Eee \\/ LipL\"},{\"t\":5,\"n\":\"Eh \\/ LipR\"},{\"t\":5,\"n\":\"FV \\/ LipTh\"},{\"t\":5,\"n\":\"I\"},{\"t\":5,\"n\":\"K\"},{\"t\":5,\"n\":\"N\"},{\"t\":5,\"n\":\"Oh\"},{\"t\":5,\"n\":\"OohQ\"},{\"t\":5,\"n\":\"R\"},{\"t\":5,\"n\":\"TH\"},{\"t\":5,\"n\":\"W\"}]}]}]},{\"t\":3,\"n\":\"WKMV - Base Movement Default - Walk\"},{\"t\":3,\"n\":\"RNMV - Base Movement Default - Run\"},{\"t\":3,\"n\":\"SWMV - Base Movement Default - Swim\"},{\"t\":3,\"n\":\"FLMV - Base Movement Default - Fly\"},{\"t\":3,\"n\":\"SNMV - Base Movement Default - Sneak\"},{\"t\":3,\"n\":\"SPMV - Base Movement Default - Sprint\"},{\"t\":6,\"n\":\"Head Data\",\"c\":[{\"n\":\"NAM0 - Head Data Marker\"},{\"t\":6,\"n\":\"Male Head Data\",\"c\":[{\"n\":\"MNAM - Male Data Marker\"}]},{\"t\":6,\"n\":\"Female Head Data\",\"c\":[{\"n\":\"NAM0 - Head Data Marker\"},{\"n\":\"FNAM - Female Data Marker\"}]}]},{\"t\":3,\"n\":\"NAM8 - Morph race\"},{\"t\":3,\"n\":\"RNAM - Armor race\"}]}]},\"name\":\"Bash.Body-Size-F\",\"hash\":\"$3ED676FA\",\"color\":255}"
  },
  {
    "path": "frontend/settings/Skyrim/Bash.Body-Size-M.json",
    "content": "{\"records\":\"RACE\",\"description\":\"Body-Size-M tag from Wrye Bash.\\r\\n\\r\\nUsed when the mod modifies male body weight\\/height definitions.\",\"tree\":{\"records\":[{\"t\":1,\"p\":1,\"n\":\"RACE - Race\",\"c\":[{\"t\":6,\"n\":\"Record Header\",\"c\":[{\"t\":2,\"n\":\"Signature\"},{\"t\":3,\"n\":\"Data Size\"},{\"t\":3,\"n\":\"Record Flags\"},{\"t\":3,\"n\":\"FormID\"},{\"t\":11,\"n\":\"Version Control Info 1\"},{\"t\":3,\"n\":\"Form Version\"},{\"t\":11,\"n\":\"Version Control Info 2\"}]},{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"n\":\"FULL - Name\"},{\"t\":2,\"n\":\"DESC - Description\"},{\"t\":3,\"n\":\"SPCT - Count\"},{\"t\":9,\"n\":\"Actor Effects\",\"c\":[{\"t\":3,\"n\":\"SPLO - Actor Effect\"}]},{\"t\":3,\"n\":\"WNAM - Skin\"},{\"t\":6,\"n\":\"BOD2 - Biped Body Template\",\"c\":[{\"t\":3,\"n\":\"First Person Flags\"},{\"t\":3,\"n\":\"General Flags\"},{\"n\":\"Unused\"},{\"t\":3,\"n\":\"Armor Type\"}]},{\"t\":3,\"n\":\"KSIZ - Keyword Count\"},{\"t\":9,\"n\":\"KWDA - Keywords\",\"c\":[{\"t\":3,\"n\":\"Keyword\"}]},{\"t\":6,\"p\":1,\"n\":\"DATA - \",\"c\":[{\"t\":10,\"n\":\"Skill Boosts\",\"c\":[{\"t\":6,\"n\":\"Skill Boost\",\"c\":[{\"t\":3,\"n\":\"Skill\"},{\"t\":3,\"n\":\"Boost\"}]},{\"t\":6,\"n\":\"Skill Boost\",\"c\":[{\"t\":3,\"n\":\"Skill\"},{\"t\":3,\"n\":\"Boost\"}]},{\"t\":6,\"n\":\"Skill Boost\",\"c\":[{\"t\":3,\"n\":\"Skill\"},{\"t\":3,\"n\":\"Boost\"}]},{\"t\":6,\"n\":\"Skill Boost\",\"c\":[{\"t\":3,\"n\":\"Skill\"},{\"t\":3,\"n\":\"Boost\"}]},{\"t\":6,\"n\":\"Skill Boost\",\"c\":[{\"t\":3,\"n\":\"Skill\"},{\"t\":3,\"n\":\"Boost\"}]},{\"t\":6,\"n\":\"Skill Boost\",\"c\":[{\"t\":3,\"n\":\"Skill\"},{\"t\":3,\"n\":\"Boost\"}]},{\"t\":6,\"n\":\"Skill Boost\",\"c\":[{\"t\":3,\"n\":\"Skill\"},{\"t\":3,\"n\":\"Boost\"}]}]},{\"t\":11,\"n\":\"Unknown\"},{\"t\":5,\"p\":1,\"n\":\"Male Height\"},{\"t\":5,\"n\":\"Female Height\"},{\"t\":5,\"p\":1,\"n\":\"Male Weight\"},{\"t\":5,\"n\":\"Female Weight\"},{\"t\":3,\"n\":\"Flags\"},{\"t\":5,\"n\":\"Starting Health\"},{\"t\":5,\"n\":\"Starting Magicka\"},{\"t\":5,\"n\":\"Starting Stamina\"},{\"t\":5,\"n\":\"Base Carry Weight\"},{\"t\":5,\"n\":\"Base Mass\"},{\"t\":5,\"n\":\"Acceleration rate\"},{\"t\":5,\"n\":\"Deceleration rate\"},{\"t\":3,\"n\":\"Size\"},{\"t\":3,\"n\":\"Head Biped Object\"},{\"t\":3,\"n\":\"Hair Biped Object\"},{\"t\":5,\"n\":\"Injured Health Pct\"},{\"t\":3,\"n\":\"Shield Biped Object\"},{\"t\":5,\"n\":\"Health Regen\"},{\"t\":5,\"n\":\"Magicka Regen\"},{\"t\":5,\"n\":\"Stamina Regen\"},{\"t\":5,\"n\":\"Unarmed Damage\"},{\"t\":5,\"n\":\"Unarmed Reach\"},{\"t\":3,\"n\":\"Body Biped Object\"},{\"t\":5,\"n\":\"Aim Angle Tolerance\"},{\"t\":5,\"n\":\"Flight Radius\"},{\"t\":5,\"n\":\"Angular Acceleration Rate\"},{\"t\":5,\"n\":\"Angular Tolerance\"},{\"t\":3,\"n\":\"Flags 2\"},{\"t\":6,\"n\":\"Mount Data\",\"c\":[{\"t\":5,\"n\":\"Offset X\"},{\"t\":5,\"n\":\"Offset Y\"},{\"t\":5,\"n\":\"Unknown\"},{\"t\":5,\"n\":\"Unknown\"},{\"t\":5,\"n\":\"Unknown\"},{\"t\":5,\"n\":\"Unknown\"},{\"t\":5,\"n\":\"Unknown\"},{\"t\":5,\"n\":\"Unknown\"},{\"t\":5,\"n\":\"Unknown\"}]}]},{\"n\":\"MNAM - Male Marker\"},{\"t\":2,\"n\":\"ANAM - Male Skeletal Model\"},{\"t\":11,\"n\":\"MODT - Texture Files Hashes\"},{\"n\":\"FNAM - Female Marker\"},{\"t\":2,\"n\":\"ANAM - Female Skeletal Model\"},{\"t\":11,\"n\":\"MODT - Texture Files Hashes\"},{\"n\":\"NAM2 - Marker NAM2 #1\"},{\"t\":9,\"n\":\"Movement Type Names\",\"c\":[{\"t\":2,\"n\":\"MTNM - Name\"}]},{\"t\":7,\"n\":\"VTCK - Voices\",\"c\":[{\"t\":3,\"n\":\"Voice #0 (Male)\"},{\"t\":3,\"n\":\"Voice #1 (Female)\"}]},{\"t\":7,\"n\":\"DNAM - Decapitate Armors\",\"c\":[{\"t\":3,\"n\":\"Decapitate Armor #0 (Male)\"},{\"t\":3,\"n\":\"Decapitate Armor #1 (Female)\"}]},{\"t\":7,\"n\":\"HCLF - Default Hair Colors\",\"c\":[{\"t\":3,\"n\":\"Default Hair Color #0 (Male)\"},{\"t\":3,\"n\":\"Default Hair Color #1 (Female)\"}]},{\"t\":3,\"n\":\"TINL - Total Number of Tints in List\"},{\"t\":5,\"n\":\"PNAM - FaceGen - Main clamp\"},{\"t\":5,\"n\":\"UNAM - FaceGen - Face clamp\"},{\"t\":3,\"n\":\"ATKR - Attack Race\"},{\"t\":10,\"n\":\"Attacks\",\"c\":[{\"t\":6,\"n\":\"Attack\",\"c\":[{\"t\":6,\"n\":\"ATKD - Attack Data\",\"c\":[{\"t\":5,\"n\":\"Damage Mult\"},{\"t\":5,\"n\":\"Attack Chance\"},{\"t\":3,\"n\":\"Attack Spell\"},{\"t\":3,\"n\":\"Attack Flags\"},{\"t\":5,\"n\":\"Attack Angle\"},{\"t\":5,\"n\":\"Strike Angle\"},{\"t\":5,\"n\":\"Stagger\"},{\"t\":3,\"n\":\"Attack Type\"},{\"t\":5,\"n\":\"Knockdown\"},{\"t\":5,\"n\":\"Recovery Time\"},{\"t\":5,\"n\":\"Stamina Mult\"}]}]}]},{\"t\":6,\"n\":\"Body Data\",\"c\":[{\"n\":\"NAM1 - Body Data Marker\"},{\"t\":6,\"n\":\"Male Body Data\",\"c\":[{\"n\":\"MNAM - Male Data Marker\"},{\"t\":10,\"n\":\"Parts\",\"d\":1,\"c\":[{\"t\":6,\"n\":\"Part\",\"c\":[{\"t\":3,\"n\":\"INDX - Index\"}]}]}]},{\"t\":6,\"n\":\"Female Body Data\",\"c\":[{\"n\":\"FNAM - Female Data Marker\"},{\"t\":10,\"n\":\"Parts\",\"c\":[{\"t\":6,\"n\":\"Part\",\"c\":[{\"t\":3,\"n\":\"INDX - Index\"}]}]}]}]},{\"t\":9,\"n\":\"HNAM - Hairs\",\"c\":[{\"t\":3,\"n\":\"Hair\"}]},{\"t\":9,\"n\":\"ENAM - Eyes\",\"c\":[{\"t\":3,\"n\":\"Eye\"}]},{\"t\":3,\"n\":\"GNAM - Body Part Data\"},{\"n\":\"NAM2 - Marker NAM2 #2\"},{\"n\":\"NAM3 - Marker NAM3 #3\"},{\"t\":6,\"n\":\"Male Behavior Graph\",\"c\":[{\"n\":\"MNAM - Male Data Marker\"}]},{\"t\":6,\"n\":\"Female Behavior Graph\",\"c\":[{\"n\":\"FNAM - Female Data Marker\"}]},{\"t\":3,\"n\":\"NAM4 - Material Type\"},{\"t\":3,\"n\":\"NAM5 - Impact Data Set\"},{\"t\":3,\"n\":\"NAM7 - Decapitation FX\"},{\"t\":3,\"n\":\"ONAM - Open Loot Sound\"},{\"t\":3,\"n\":\"LNAM - Close Loot Sound\"},{\"t\":7,\"n\":\"Biped Object Names\",\"c\":[{\"t\":2,\"n\":\"NAME - Name\"}]},{\"t\":10,\"n\":\"Movement Types\",\"c\":[{\"t\":6,\"n\":\"Movement Types\",\"c\":[{\"t\":3,\"n\":\"MTYP - Movement Type\"}]}]},{\"t\":3,\"n\":\"VNAM - Equipment Flags\"},{\"t\":9,\"n\":\"Equip Slots\",\"c\":[{\"t\":3,\"n\":\"QNAM - Equip Slot\"}]},{\"t\":3,\"n\":\"UNES - Unarmed Equip Slot\"},{\"t\":7,\"n\":\"Phoneme Target Names\",\"c\":[{\"t\":2,\"n\":\"PHTN - Name\"}]},{\"t\":6,\"n\":\"FaceFX Phonemes\",\"c\":[{\"t\":6,\"n\":\"IY\",\"c\":[{\"t\":6,\"n\":\"PHWT - Phoneme Target Weight\",\"c\":[{\"t\":5,\"n\":\"Aah \\/ LipBigAah\"},{\"t\":5,\"n\":\"BigAah \\/ LipDST\"},{\"t\":5,\"n\":\"BMP \\/ LipEee\"},{\"t\":5,\"n\":\"ChJsh \\/ LipFV\"},{\"t\":5,\"n\":\"DST \\/ LipK\"},{\"t\":5,\"n\":\"Eee \\/ LipL\"},{\"t\":5,\"n\":\"Eh \\/ LipR\"},{\"t\":5,\"n\":\"FV \\/ LipTh\"},{\"t\":5,\"n\":\"I\"},{\"t\":5,\"n\":\"K\"},{\"t\":5,\"n\":\"N\"},{\"t\":5,\"n\":\"Oh\"},{\"t\":5,\"n\":\"OohQ\"},{\"t\":5,\"n\":\"R\"},{\"t\":5,\"n\":\"TH\"},{\"t\":5,\"n\":\"W\"}]}]}]},{\"t\":3,\"n\":\"WKMV - Base Movement Default - Walk\"},{\"t\":3,\"n\":\"RNMV - Base Movement Default - Run\"},{\"t\":3,\"n\":\"SWMV - Base Movement Default - Swim\"},{\"t\":3,\"n\":\"FLMV - Base Movement Default - Fly\"},{\"t\":3,\"n\":\"SNMV - Base Movement Default - Sneak\"},{\"t\":3,\"n\":\"SPMV - Base Movement Default - Sprint\"},{\"t\":6,\"n\":\"Head Data\",\"c\":[{\"n\":\"NAM0 - Head Data Marker\"},{\"t\":6,\"n\":\"Male Head Data\",\"c\":[{\"n\":\"MNAM - Male Data Marker\"}]},{\"t\":6,\"n\":\"Female Head Data\",\"c\":[{\"n\":\"NAM0 - Head Data Marker\"},{\"n\":\"FNAM - Female Data Marker\"}]}]},{\"t\":3,\"n\":\"NAM8 - Morph race\"},{\"t\":3,\"n\":\"RNAM - Armor race\"}]}]},\"name\":\"Bash.Body-Size-M\",\"hash\":\"$37B99D6E\",\"color\":255}"
  },
  {
    "path": "frontend/settings/Skyrim/Bash.C.Acoustic.json",
    "content": "{\"records\":\"CELL\",\"description\":\"\",\"tree\":{\"records\":[{\"t\":1,\"p\":1,\"n\":\"CELL - Cell\",\"c\":[{\"t\":6,\"n\":\"Record Header\",\"c\":[{\"t\":2,\"n\":\"Signature\"},{\"t\":3,\"n\":\"Data Size\"},{\"t\":3,\"n\":\"Record Flags\"},{\"t\":3,\"n\":\"FormID\"},{\"t\":11,\"n\":\"Version Control Info 1\"},{\"t\":3,\"n\":\"Form Version\"},{\"t\":11,\"n\":\"Version Control Info 2\"}]},{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"n\":\"FULL - Name\"},{\"t\":3,\"n\":\"DATA - Flags\",\"c\":[{\"t\":4,\"n\":\"Is Interior Cell\"}]},{\"t\":6,\"n\":\"XCLC - Grid\",\"c\":[{\"t\":3,\"n\":\"X\"},{\"t\":3,\"n\":\"Y\"},{\"t\":3,\"n\":\"Force Hide Land\"}]},{\"t\":6,\"n\":\"XCLL - Lighting\",\"c\":[{\"t\":6,\"n\":\"Ambient Color\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":6,\"n\":\"Directional Color\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":6,\"n\":\"Fog Color Near\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":5,\"n\":\"Fog Near\"},{\"t\":5,\"n\":\"Fog Far\"},{\"t\":3,\"n\":\"Directional Rotation XY\"},{\"t\":3,\"n\":\"Directional Rotation Z\"},{\"t\":5,\"n\":\"Directional Fade\"},{\"t\":5,\"n\":\"Fog Clip Distance\"},{\"t\":5,\"n\":\"Fog Power\"},{\"t\":6,\"n\":\"Ambient Colors\",\"c\":[{\"t\":8,\"n\":\"Colors\",\"c\":[{\"t\":6,\"n\":\"Color #0 (X+)\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":6,\"n\":\"Color #1 (X-)\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":6,\"n\":\"Color #2 (Y+)\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":6,\"n\":\"Color #3 (Y-)\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":6,\"n\":\"Color #4 (Z+)\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":6,\"n\":\"Color #5 (Z-)\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unknown\"}]}]},{\"t\":6,\"n\":\"Specular\",\"c\":[{\"t\":6,\"n\":\"Color\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":5,\"n\":\"Fresnel Power\"}]}]},{\"t\":6,\"n\":\"Fog Color Far\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":5,\"n\":\"Fog Max\"},{\"t\":5,\"n\":\"Light Fade Begin\"},{\"t\":5,\"n\":\"Light Fade End\"},{\"t\":3,\"n\":\"Inherits\"}]},{\"t\":11,\"n\":\"TVDT - Unknown\"},{\"t\":11,\"n\":\"MHDT - Max Height Data\"},{\"t\":3,\"n\":\"LTMP - Lighting Template\"},{\"t\":11,\"n\":\"LNAM - Unknown\"},{\"t\":5,\"n\":\"XCLW - Water Height\"},{\"t\":2,\"n\":\"XNAM - Water Noise Texture\"},{\"t\":9,\"n\":\"XCLR - Regions\",\"c\":[{\"t\":3,\"n\":\"Region\"}]},{\"t\":3,\"n\":\"XLCN - Location\"},{\"t\":11,\"n\":\"XWCN - Unknown\"},{\"t\":11,\"n\":\"XWCS - Unknown\"},{\"t\":6,\"n\":\"XWCU - Water Velocity\",\"c\":[{\"t\":5,\"n\":\"X Offset\"},{\"t\":5,\"n\":\"Y Offset\"},{\"t\":5,\"n\":\"Z Offset\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":5,\"n\":\"X Angle\"},{\"t\":5,\"n\":\"Y Angle\"},{\"t\":5,\"n\":\"Z Angle\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":3,\"n\":\"XCWT - Water\"},{\"t\":6,\"n\":\"Ownership\",\"c\":[{\"t\":3,\"n\":\"XOWN - Owner\"}]},{\"t\":3,\"n\":\"XILL - Lock List\"},{\"t\":2,\"n\":\"XWEM - Water Environment Map\"},{\"t\":3,\"n\":\"XCCM - Sky\\/Weather from Region\"},{\"t\":3,\"p\":1,\"n\":\"XCAS - Acoustic Space\"},{\"t\":3,\"n\":\"XEZN - Encounter Zone\"},{\"t\":3,\"n\":\"XCMO - Music Type\"},{\"t\":3,\"n\":\"XCIM - Image Space\"}]}]},\"name\":\"Bash.C.Acoustic\",\"hash\":\"$65B5135E\",\"color\":255}"
  },
  {
    "path": "frontend/settings/Skyrim/Bash.C.Climate.json",
    "content": "{\"records\":\"CELL\",\"description\":\"C.Climate tag from Wrye Bash.\\r\\n\\r\\nUsed when the mod modifies cell climates.\",\"tree\":{\"records\":[{\"t\":1,\"p\":1,\"n\":\"CELL - Cell\",\"c\":[{\"t\":6,\"n\":\"Record Header\",\"c\":[{\"t\":2,\"n\":\"Signature\"},{\"t\":3,\"n\":\"Data Size\"},{\"t\":3,\"n\":\"Record Flags\"},{\"t\":3,\"n\":\"FormID\"},{\"t\":11,\"n\":\"Version Control Info 1\"},{\"t\":3,\"n\":\"Form Version\"},{\"t\":11,\"n\":\"Version Control Info 2\"}]},{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"n\":\"FULL - Name\"},{\"t\":3,\"n\":\"DATA - Flags\",\"c\":[{\"t\":4,\"n\":\"Is Interior Cell\"}]},{\"t\":6,\"n\":\"XCLC - Grid\",\"c\":[{\"t\":3,\"n\":\"X\"},{\"t\":3,\"n\":\"Y\"},{\"t\":3,\"n\":\"Force Hide Land\"}]},{\"t\":6,\"n\":\"XCLL - Lighting\",\"c\":[{\"t\":6,\"n\":\"Ambient Color\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":6,\"n\":\"Directional Color\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":6,\"n\":\"Fog Color Near\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":5,\"n\":\"Fog Near\"},{\"t\":5,\"n\":\"Fog Far\"},{\"t\":3,\"n\":\"Directional Rotation XY\"},{\"t\":3,\"n\":\"Directional Rotation Z\"},{\"t\":5,\"n\":\"Directional Fade\"},{\"t\":5,\"n\":\"Fog Clip Distance\"},{\"t\":5,\"n\":\"Fog Power\"},{\"t\":6,\"n\":\"Ambient Colors\",\"c\":[{\"t\":8,\"n\":\"Colors\",\"c\":[{\"t\":6,\"n\":\"Color #0 (X+)\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":6,\"n\":\"Color #1 (X-)\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":6,\"n\":\"Color #2 (Y+)\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":6,\"n\":\"Color #3 (Y-)\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":6,\"n\":\"Color #4 (Z+)\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":6,\"n\":\"Color #5 (Z-)\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unknown\"}]}]},{\"t\":6,\"n\":\"Specular\",\"c\":[{\"t\":6,\"n\":\"Color\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":5,\"n\":\"Fresnel Power\"}]}]},{\"t\":6,\"n\":\"Fog Color Far\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":5,\"n\":\"Fog Max\"},{\"t\":5,\"n\":\"Light Fade Begin\"},{\"t\":5,\"n\":\"Light Fade End\"},{\"t\":3,\"n\":\"Inherits\"}]},{\"t\":11,\"n\":\"TVDT - Unknown\"},{\"t\":11,\"n\":\"MHDT - Max Height Data\"},{\"t\":3,\"n\":\"LTMP - Lighting Template\"},{\"t\":11,\"n\":\"LNAM - Unknown\"},{\"t\":5,\"n\":\"XCLW - Water Height\"},{\"t\":2,\"n\":\"XNAM - Water Noise Texture\"},{\"t\":9,\"n\":\"XCLR - Regions\",\"c\":[{\"t\":3,\"n\":\"Region\"}]},{\"t\":3,\"n\":\"XLCN - Location\"},{\"t\":11,\"n\":\"XWCN - Unknown\"},{\"t\":11,\"n\":\"XWCS - Unknown\"},{\"t\":6,\"n\":\"XWCU - Water Velocity\",\"c\":[{\"t\":5,\"n\":\"X Offset\"},{\"t\":5,\"n\":\"Y Offset\"},{\"t\":5,\"n\":\"Z Offset\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":5,\"n\":\"X Angle\"},{\"t\":5,\"n\":\"Y Angle\"},{\"t\":5,\"n\":\"Z Angle\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":3,\"n\":\"XCWT - Water\"},{\"t\":6,\"n\":\"Ownership\",\"c\":[{\"t\":3,\"n\":\"XOWN - Owner\"}]},{\"t\":3,\"n\":\"XILL - Lock List\"},{\"t\":2,\"n\":\"XWEM - Water Environment Map\"},{\"t\":3,\"p\":1,\"n\":\"XCCM - Sky\\/Weather from Region\"},{\"t\":3,\"n\":\"XCAS - Acoustic Space\"},{\"t\":3,\"n\":\"XEZN - Encounter Zone\"},{\"t\":3,\"n\":\"XCMO - Music Type\"},{\"t\":3,\"n\":\"XCIM - Image Space\"}]}]},\"name\":\"Bash.C.Climate\",\"hash\":\"$595B86E0\",\"color\":255}"
  },
  {
    "path": "frontend/settings/Skyrim/Bash.C.Encounter.json",
    "content": "{\"records\":\"CELL\",\"description\":\"\",\"tree\":{\"records\":[{\"t\":1,\"p\":1,\"n\":\"CELL - Cell\",\"c\":[{\"t\":6,\"n\":\"Record Header\",\"c\":[{\"t\":2,\"n\":\"Signature\"},{\"t\":3,\"n\":\"Data Size\"},{\"t\":3,\"n\":\"Record Flags\"},{\"t\":3,\"n\":\"FormID\"},{\"t\":11,\"n\":\"Version Control Info 1\"},{\"t\":3,\"n\":\"Form Version\"},{\"t\":11,\"n\":\"Version Control Info 2\"}]},{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"n\":\"FULL - Name\"},{\"t\":3,\"n\":\"DATA - Flags\",\"c\":[{\"t\":4,\"n\":\"Is Interior Cell\"}]},{\"t\":6,\"n\":\"XCLC - Grid\",\"c\":[{\"t\":3,\"n\":\"X\"},{\"t\":3,\"n\":\"Y\"},{\"t\":3,\"n\":\"Force Hide Land\"}]},{\"t\":6,\"n\":\"XCLL - Lighting\",\"c\":[{\"t\":6,\"n\":\"Ambient Color\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":6,\"n\":\"Directional Color\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":6,\"n\":\"Fog Color Near\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":5,\"n\":\"Fog Near\"},{\"t\":5,\"n\":\"Fog Far\"},{\"t\":3,\"n\":\"Directional Rotation XY\"},{\"t\":3,\"n\":\"Directional Rotation Z\"},{\"t\":5,\"n\":\"Directional Fade\"},{\"t\":5,\"n\":\"Fog Clip Distance\"},{\"t\":5,\"n\":\"Fog Power\"},{\"t\":6,\"n\":\"Ambient Colors\",\"c\":[{\"t\":8,\"n\":\"Colors\",\"c\":[{\"t\":6,\"n\":\"Color #0 (X+)\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":6,\"n\":\"Color #1 (X-)\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":6,\"n\":\"Color #2 (Y+)\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":6,\"n\":\"Color #3 (Y-)\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":6,\"n\":\"Color #4 (Z+)\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":6,\"n\":\"Color #5 (Z-)\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unknown\"}]}]},{\"t\":6,\"n\":\"Specular\",\"c\":[{\"t\":6,\"n\":\"Color\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":5,\"n\":\"Fresnel Power\"}]}]},{\"t\":6,\"n\":\"Fog Color Far\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":5,\"n\":\"Fog Max\"},{\"t\":5,\"n\":\"Light Fade Begin\"},{\"t\":5,\"n\":\"Light Fade End\"},{\"t\":3,\"n\":\"Inherits\"}]},{\"t\":11,\"n\":\"TVDT - Unknown\"},{\"t\":11,\"n\":\"MHDT - Max Height Data\"},{\"t\":3,\"n\":\"LTMP - Lighting Template\"},{\"t\":11,\"n\":\"LNAM - Unknown\"},{\"t\":5,\"n\":\"XCLW - Water Height\"},{\"t\":2,\"n\":\"XNAM - Water Noise Texture\"},{\"t\":9,\"n\":\"XCLR - Regions\",\"c\":[{\"t\":3,\"n\":\"Region\"}]},{\"t\":3,\"n\":\"XLCN - Location\"},{\"t\":11,\"n\":\"XWCN - Unknown\"},{\"t\":11,\"n\":\"XWCS - Unknown\"},{\"t\":6,\"n\":\"XWCU - Water Velocity\",\"c\":[{\"t\":5,\"n\":\"X Offset\"},{\"t\":5,\"n\":\"Y Offset\"},{\"t\":5,\"n\":\"Z Offset\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":5,\"n\":\"X Angle\"},{\"t\":5,\"n\":\"Y Angle\"},{\"t\":5,\"n\":\"Z Angle\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":3,\"n\":\"XCWT - Water\"},{\"t\":6,\"n\":\"Ownership\",\"c\":[{\"t\":3,\"n\":\"XOWN - Owner\"}]},{\"t\":3,\"n\":\"XILL - Lock List\"},{\"t\":2,\"n\":\"XWEM - Water Environment Map\"},{\"t\":3,\"n\":\"XCCM - Sky\\/Weather from Region\"},{\"t\":3,\"n\":\"XCAS - Acoustic Space\"},{\"t\":3,\"p\":1,\"n\":\"XEZN - Encounter Zone\"},{\"t\":3,\"n\":\"XCMO - Music Type\"},{\"t\":3,\"n\":\"XCIM - Image Space\"}]}]},\"name\":\"Bash.C.Encounter\",\"hash\":\"$C39BCB8D\",\"color\":255}"
  },
  {
    "path": "frontend/settings/Skyrim/Bash.C.ImageSpace.json",
    "content": "{\"records\":\"CELL\",\"description\":\"\",\"tree\":{\"records\":[{\"t\":1,\"p\":1,\"n\":\"CELL - Cell\",\"d\":1,\"c\":[{\"t\":6,\"n\":\"Record Header\",\"c\":[{\"t\":2,\"n\":\"Signature\"},{\"t\":3,\"n\":\"Data Size\"},{\"t\":3,\"n\":\"Record Flags\"},{\"t\":3,\"n\":\"FormID\"},{\"t\":11,\"n\":\"Version Control Info 1\"},{\"t\":3,\"n\":\"Form Version\"},{\"t\":11,\"n\":\"Version Control Info 2\"}]},{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"n\":\"FULL - Name\"},{\"t\":3,\"n\":\"DATA - Flags\",\"c\":[{\"t\":4,\"n\":\"Is Interior Cell\"}]},{\"t\":6,\"n\":\"XCLC - Grid\",\"c\":[{\"t\":3,\"n\":\"X\"},{\"t\":3,\"n\":\"Y\"},{\"t\":3,\"n\":\"Force Hide Land\"}]},{\"t\":6,\"n\":\"XCLL - Lighting\",\"c\":[{\"t\":6,\"n\":\"Ambient Color\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":6,\"n\":\"Directional Color\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":6,\"n\":\"Fog Color Near\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":5,\"n\":\"Fog Near\"},{\"t\":5,\"n\":\"Fog Far\"},{\"t\":3,\"n\":\"Directional Rotation XY\"},{\"t\":3,\"n\":\"Directional Rotation Z\"},{\"t\":5,\"n\":\"Directional Fade\"},{\"t\":5,\"n\":\"Fog Clip Distance\"},{\"t\":5,\"n\":\"Fog Power\"},{\"t\":6,\"n\":\"Ambient Colors\",\"c\":[{\"t\":8,\"n\":\"Colors\",\"c\":[{\"t\":6,\"n\":\"Color #0 (X+)\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":6,\"n\":\"Color #1 (X-)\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":6,\"n\":\"Color #2 (Y+)\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":6,\"n\":\"Color #3 (Y-)\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":6,\"n\":\"Color #4 (Z+)\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":6,\"n\":\"Color #5 (Z-)\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unknown\"}]}]},{\"t\":6,\"n\":\"Specular\",\"c\":[{\"t\":6,\"n\":\"Color\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":5,\"n\":\"Fresnel Power\"}]}]},{\"t\":6,\"n\":\"Fog Color Far\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":5,\"n\":\"Fog Max\"},{\"t\":5,\"n\":\"Light Fade Begin\"},{\"t\":5,\"n\":\"Light Fade End\"},{\"t\":3,\"n\":\"Inherits\"}]},{\"t\":11,\"n\":\"TVDT - Unknown\"},{\"t\":11,\"n\":\"MHDT - Max Height Data\"},{\"t\":3,\"n\":\"LTMP - Lighting Template\"},{\"t\":11,\"n\":\"LNAM - Unknown\"},{\"t\":5,\"n\":\"XCLW - Water Height\"},{\"t\":2,\"n\":\"XNAM - Water Noise Texture\"},{\"t\":9,\"n\":\"XCLR - Regions\",\"d\":1,\"c\":[{\"t\":3,\"n\":\"Region\"}]},{\"t\":3,\"n\":\"XLCN - Location\"},{\"t\":11,\"n\":\"XWCN - Unknown\"},{\"t\":11,\"n\":\"XWCS - Unknown\"},{\"t\":6,\"n\":\"XWCU - Water Velocity\",\"c\":[{\"t\":5,\"n\":\"X Offset\"},{\"t\":5,\"n\":\"Y Offset\"},{\"t\":5,\"n\":\"Z Offset\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":5,\"n\":\"X Angle\"},{\"t\":5,\"n\":\"Y Angle\"},{\"t\":5,\"n\":\"Z Angle\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":3,\"n\":\"XCWT - Water\"},{\"t\":6,\"n\":\"Ownership\",\"c\":[{\"t\":3,\"n\":\"XOWN - Owner\"}]},{\"t\":3,\"n\":\"XILL - Lock List\"},{\"t\":2,\"n\":\"XWEM - Water Environment Map\"},{\"t\":3,\"n\":\"XCCM - Sky\\/Weather from Region\"},{\"t\":3,\"n\":\"XCAS - Acoustic Space\"},{\"t\":3,\"n\":\"XEZN - Encounter Zone\"},{\"t\":3,\"n\":\"XCMO - Music Type\"},{\"t\":3,\"p\":1,\"n\":\"XCIM - Image Space\"}]}]},\"name\":\"Bash.C.ImageSpace\",\"hash\":\"$B06BA239\",\"color\":255}"
  },
  {
    "path": "frontend/settings/Skyrim/Bash.C.Light.json",
    "content": "{\"records\":\"CELL\",\"description\":\"C.Light tag from Wrye Bash.\\r\\n\\r\\nUsed when the mod modifies cell lighting or fog.\",\"tree\":{\"records\":[{\"t\":1,\"p\":1,\"n\":\"CELL - Cell\",\"c\":[{\"t\":6,\"n\":\"Record Header\",\"c\":[{\"t\":2,\"n\":\"Signature\"},{\"t\":3,\"n\":\"Data Size\"},{\"t\":3,\"n\":\"Record Flags\"},{\"t\":3,\"n\":\"FormID\"},{\"t\":11,\"n\":\"Version Control Info 1\"},{\"t\":3,\"n\":\"Form Version\"},{\"t\":11,\"n\":\"Version Control Info 2\"}]},{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"n\":\"FULL - Name\"},{\"t\":3,\"n\":\"DATA - Flags\",\"c\":[{\"t\":4,\"n\":\"Is Interior Cell\"}]},{\"t\":6,\"n\":\"XCLC - Grid\",\"c\":[{\"t\":3,\"n\":\"X\"},{\"t\":3,\"n\":\"Y\"},{\"t\":3,\"n\":\"Force Hide Land\"}]},{\"t\":6,\"p\":1,\"n\":\"XCLL - Lighting\",\"c\":[{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Ambient Color\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"p\":1,\"n\":\"Unknown\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Directional Color\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"p\":1,\"n\":\"Unknown\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Fog Color Near\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"p\":1,\"n\":\"Unknown\"}]},{\"t\":5,\"n\":\"Fog Near\"},{\"t\":5,\"n\":\"Fog Far\"},{\"t\":3,\"n\":\"Directional Rotation XY\"},{\"t\":3,\"n\":\"Directional Rotation Z\"},{\"t\":5,\"n\":\"Directional Fade\"},{\"t\":5,\"n\":\"Fog Clip Distance\"},{\"t\":5,\"n\":\"Fog Power\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Ambient Colors\",\"c\":[{\"t\":8,\"p\":1,\"n\":\"Colors\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Color #0 (X+)\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"p\":1,\"n\":\"Unknown\"}]},{\"t\":6,\"p\":1,\"n\":\"Color #1 (X-)\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"p\":1,\"n\":\"Unknown\"}]},{\"t\":6,\"p\":1,\"n\":\"Color #2 (Y+)\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"p\":1,\"n\":\"Unknown\"}]},{\"t\":6,\"p\":1,\"n\":\"Color #3 (Y-)\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"p\":1,\"n\":\"Unknown\"}]},{\"t\":6,\"p\":1,\"n\":\"Color #4 (Z+)\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"p\":1,\"n\":\"Unknown\"}]},{\"t\":6,\"p\":1,\"n\":\"Color #5 (Z-)\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"p\":1,\"n\":\"Unknown\"}]}]},{\"t\":6,\"p\":1,\"n\":\"Specular\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Color\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"p\":1,\"n\":\"Unknown\"}]},{\"t\":5,\"p\":1,\"n\":\"Fresnel Power\"}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Fog Color Far\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"p\":1,\"n\":\"Unknown\"}]},{\"t\":5,\"n\":\"Fog Max\"},{\"t\":5,\"n\":\"Light Fade Begin\"},{\"t\":5,\"n\":\"Light Fade End\"},{\"t\":3,\"n\":\"Inherits\"}]},{\"t\":11,\"n\":\"TVDT - Unknown\"},{\"t\":11,\"n\":\"MHDT - Max Height Data\"},{\"t\":3,\"n\":\"LTMP - Lighting Template\"},{\"t\":11,\"n\":\"LNAM - Unknown\"},{\"t\":5,\"n\":\"XCLW - Water Height\"},{\"t\":2,\"n\":\"XNAM - Water Noise Texture\"},{\"t\":9,\"n\":\"XCLR - Regions\",\"c\":[{\"t\":3,\"n\":\"Region\"}]},{\"t\":3,\"n\":\"XLCN - Location\"},{\"t\":11,\"n\":\"XWCN - Unknown\"},{\"t\":11,\"n\":\"XWCS - Unknown\"},{\"t\":6,\"n\":\"XWCU - Water Velocity\",\"c\":[{\"t\":5,\"n\":\"X Offset\"},{\"t\":5,\"n\":\"Y Offset\"},{\"t\":5,\"n\":\"Z Offset\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":5,\"n\":\"X Angle\"},{\"t\":5,\"n\":\"Y Angle\"},{\"t\":5,\"n\":\"Z Angle\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":3,\"n\":\"XCWT - Water\"},{\"t\":6,\"n\":\"Ownership\",\"c\":[{\"t\":3,\"n\":\"XOWN - Owner\"}]},{\"t\":3,\"n\":\"XILL - Lock List\"},{\"t\":2,\"n\":\"XWEM - Water Environment Map\"},{\"t\":3,\"n\":\"XCCM - Sky\\/Weather from Region\"},{\"t\":3,\"n\":\"XCAS - Acoustic Space\"},{\"t\":3,\"n\":\"XEZN - Encounter Zone\"},{\"t\":3,\"n\":\"XCMO - Music Type\"},{\"t\":3,\"n\":\"XCIM - Image Space\"}]}]},\"name\":\"Bash.C.Light\",\"hash\":\"$4E94E72C\",\"color\":255}"
  },
  {
    "path": "frontend/settings/Skyrim/Bash.C.Location.json",
    "content": "{\"records\":\"CELL\",\"description\":\"\",\"tree\":{\"records\":[{\"t\":1,\"p\":1,\"n\":\"CELL - Cell\",\"c\":[{\"t\":6,\"n\":\"Record Header\",\"c\":[{\"t\":2,\"n\":\"Signature\"},{\"t\":3,\"n\":\"Data Size\"},{\"t\":3,\"n\":\"Record Flags\"},{\"t\":3,\"n\":\"FormID\"},{\"t\":11,\"n\":\"Version Control Info 1\"},{\"t\":3,\"n\":\"Form Version\"},{\"t\":11,\"n\":\"Version Control Info 2\"}]},{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"n\":\"FULL - Name\"},{\"t\":3,\"n\":\"DATA - Flags\",\"c\":[{\"t\":4,\"n\":\"Is Interior Cell\"}]},{\"t\":6,\"n\":\"XCLC - Grid\",\"c\":[{\"t\":3,\"n\":\"X\"},{\"t\":3,\"n\":\"Y\"},{\"t\":3,\"n\":\"Force Hide Land\"}]},{\"t\":6,\"n\":\"XCLL - Lighting\",\"c\":[{\"t\":6,\"n\":\"Ambient Color\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":6,\"n\":\"Directional Color\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":6,\"n\":\"Fog Color Near\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":5,\"n\":\"Fog Near\"},{\"t\":5,\"n\":\"Fog Far\"},{\"t\":3,\"n\":\"Directional Rotation XY\"},{\"t\":3,\"n\":\"Directional Rotation Z\"},{\"t\":5,\"n\":\"Directional Fade\"},{\"t\":5,\"n\":\"Fog Clip Distance\"},{\"t\":5,\"n\":\"Fog Power\"},{\"t\":6,\"n\":\"Ambient Colors\",\"c\":[{\"t\":8,\"n\":\"Colors\",\"c\":[{\"t\":6,\"n\":\"Color #0 (X+)\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":6,\"n\":\"Color #1 (X-)\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":6,\"n\":\"Color #2 (Y+)\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":6,\"n\":\"Color #3 (Y-)\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":6,\"n\":\"Color #4 (Z+)\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":6,\"n\":\"Color #5 (Z-)\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unknown\"}]}]},{\"t\":6,\"n\":\"Specular\",\"c\":[{\"t\":6,\"n\":\"Color\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":5,\"n\":\"Fresnel Power\"}]}]},{\"t\":6,\"n\":\"Fog Color Far\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":5,\"n\":\"Fog Max\"},{\"t\":5,\"n\":\"Light Fade Begin\"},{\"t\":5,\"n\":\"Light Fade End\"},{\"t\":3,\"n\":\"Inherits\"}]},{\"t\":11,\"n\":\"TVDT - Unknown\"},{\"t\":11,\"n\":\"MHDT - Max Height Data\"},{\"t\":3,\"n\":\"LTMP - Lighting Template\"},{\"t\":11,\"n\":\"LNAM - Unknown\"},{\"t\":5,\"n\":\"XCLW - Water Height\"},{\"t\":2,\"n\":\"XNAM - Water Noise Texture\"},{\"t\":9,\"n\":\"XCLR - Regions\",\"c\":[{\"t\":3,\"n\":\"Region\"}]},{\"t\":3,\"p\":1,\"n\":\"XLCN - Location\"},{\"t\":11,\"n\":\"XWCN - Unknown\"},{\"t\":11,\"n\":\"XWCS - Unknown\"},{\"t\":6,\"n\":\"XWCU - Water Velocity\",\"c\":[{\"t\":5,\"n\":\"X Offset\"},{\"t\":5,\"n\":\"Y Offset\"},{\"t\":5,\"n\":\"Z Offset\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":5,\"n\":\"X Angle\"},{\"t\":5,\"n\":\"Y Angle\"},{\"t\":5,\"n\":\"Z Angle\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":3,\"n\":\"XCWT - Water\"},{\"t\":6,\"n\":\"Ownership\",\"c\":[{\"t\":3,\"n\":\"XOWN - Owner\"}]},{\"t\":3,\"n\":\"XILL - Lock List\"},{\"t\":2,\"n\":\"XWEM - Water Environment Map\"},{\"t\":3,\"n\":\"XCCM - Sky\\/Weather from Region\"},{\"t\":3,\"n\":\"XCAS - Acoustic Space\"},{\"t\":3,\"n\":\"XEZN - Encounter Zone\"},{\"t\":3,\"n\":\"XCMO - Music Type\"},{\"t\":3,\"n\":\"XCIM - Image Space\"}]}]},\"name\":\"Bash.C.Location\",\"hash\":\"$3E1F8F01\",\"color\":255}"
  },
  {
    "path": "frontend/settings/Skyrim/Bash.C.Music.json",
    "content": "{\"records\":\"CELL\",\"description\":\"C.Music tag from Wrye Bash.\\r\\n\\r\\nUsed when the mod modifies cell music type.\",\"tree\":{\"records\":[{\"t\":1,\"p\":1,\"n\":\"CELL - Cell\",\"c\":[{\"t\":6,\"n\":\"Record Header\",\"c\":[{\"t\":2,\"n\":\"Signature\"},{\"t\":3,\"n\":\"Data Size\"},{\"t\":3,\"n\":\"Record Flags\"},{\"t\":3,\"n\":\"FormID\"},{\"t\":11,\"n\":\"Version Control Info 1\"},{\"t\":3,\"n\":\"Form Version\"},{\"t\":11,\"n\":\"Version Control Info 2\"}]},{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"n\":\"FULL - Name\"},{\"t\":3,\"n\":\"DATA - Flags\",\"c\":[{\"t\":4,\"n\":\"Is Interior Cell\"}]},{\"t\":6,\"n\":\"XCLC - Grid\",\"c\":[{\"t\":3,\"n\":\"X\"},{\"t\":3,\"n\":\"Y\"},{\"t\":3,\"n\":\"Force Hide Land\"}]},{\"t\":6,\"n\":\"XCLL - Lighting\",\"c\":[{\"t\":6,\"n\":\"Ambient Color\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":6,\"n\":\"Directional Color\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":6,\"n\":\"Fog Color Near\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":5,\"n\":\"Fog Near\"},{\"t\":5,\"n\":\"Fog Far\"},{\"t\":3,\"n\":\"Directional Rotation XY\"},{\"t\":3,\"n\":\"Directional Rotation Z\"},{\"t\":5,\"n\":\"Directional Fade\"},{\"t\":5,\"n\":\"Fog Clip Distance\"},{\"t\":5,\"n\":\"Fog Power\"},{\"t\":6,\"n\":\"Ambient Colors\",\"c\":[{\"t\":8,\"n\":\"Colors\",\"c\":[{\"t\":6,\"n\":\"Color #0 (X+)\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":6,\"n\":\"Color #1 (X-)\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":6,\"n\":\"Color #2 (Y+)\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":6,\"n\":\"Color #3 (Y-)\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":6,\"n\":\"Color #4 (Z+)\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":6,\"n\":\"Color #5 (Z-)\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unknown\"}]}]},{\"t\":6,\"n\":\"Specular\",\"c\":[{\"t\":6,\"n\":\"Color\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":5,\"n\":\"Fresnel Power\"}]}]},{\"t\":6,\"n\":\"Fog Color Far\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":5,\"n\":\"Fog Max\"},{\"t\":5,\"n\":\"Light Fade Begin\"},{\"t\":5,\"n\":\"Light Fade End\"},{\"t\":3,\"n\":\"Inherits\"}]},{\"t\":11,\"n\":\"TVDT - Unknown\"},{\"t\":11,\"n\":\"MHDT - Max Height Data\"},{\"t\":3,\"n\":\"LTMP - Lighting Template\"},{\"t\":11,\"n\":\"LNAM - Unknown\"},{\"t\":5,\"n\":\"XCLW - Water Height\"},{\"t\":2,\"n\":\"XNAM - Water Noise Texture\"},{\"t\":9,\"n\":\"XCLR - Regions\",\"c\":[{\"t\":3,\"n\":\"Region\"}]},{\"t\":3,\"n\":\"XLCN - Location\"},{\"t\":11,\"n\":\"XWCN - Unknown\"},{\"t\":11,\"n\":\"XWCS - Unknown\"},{\"t\":6,\"n\":\"XWCU - Water Velocity\",\"c\":[{\"t\":5,\"n\":\"X Offset\"},{\"t\":5,\"n\":\"Y Offset\"},{\"t\":5,\"n\":\"Z Offset\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":5,\"n\":\"X Angle\"},{\"t\":5,\"n\":\"Y Angle\"},{\"t\":5,\"n\":\"Z Angle\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":3,\"n\":\"XCWT - Water\"},{\"t\":6,\"n\":\"Ownership\",\"c\":[{\"t\":3,\"n\":\"XOWN - Owner\"}]},{\"t\":3,\"n\":\"XILL - Lock List\"},{\"t\":2,\"n\":\"XWEM - Water Environment Map\"},{\"t\":3,\"n\":\"XCCM - Sky\\/Weather from Region\"},{\"t\":3,\"n\":\"XCAS - Acoustic Space\"},{\"t\":3,\"n\":\"XEZN - Encounter Zone\"},{\"t\":3,\"p\":1,\"n\":\"XCMO - Music Type\"},{\"t\":3,\"n\":\"XCIM - Image Space\"}]}]},\"name\":\"Bash.C.Music\",\"hash\":\"$A62AFF38\",\"color\":255}"
  },
  {
    "path": "frontend/settings/Skyrim/Bash.C.Name.json",
    "content": "{\"records\":\"CELL\",\"description\":\"C.Name tag from Wrye Bash.\\r\\n\\r\\nUsed when the mod modifies cell names.\",\"tree\":{\"records\":[{\"t\":1,\"p\":1,\"n\":\"CELL - Cell\",\"c\":[{\"t\":6,\"n\":\"Record Header\",\"c\":[{\"t\":2,\"n\":\"Signature\"},{\"t\":3,\"n\":\"Data Size\"},{\"t\":3,\"n\":\"Record Flags\"},{\"t\":3,\"n\":\"FormID\"},{\"t\":11,\"n\":\"Version Control Info 1\"},{\"t\":3,\"n\":\"Form Version\"},{\"t\":11,\"n\":\"Version Control Info 2\"}]},{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":3,\"n\":\"DATA - Flags\",\"c\":[{\"t\":4,\"n\":\"Is Interior Cell\"}]},{\"t\":6,\"n\":\"XCLC - Grid\",\"c\":[{\"t\":3,\"n\":\"X\"},{\"t\":3,\"n\":\"Y\"},{\"t\":3,\"n\":\"Force Hide Land\"}]},{\"t\":6,\"n\":\"XCLL - Lighting\",\"c\":[{\"t\":6,\"n\":\"Ambient Color\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":6,\"n\":\"Directional Color\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":6,\"n\":\"Fog Color Near\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":5,\"n\":\"Fog Near\"},{\"t\":5,\"n\":\"Fog Far\"},{\"t\":3,\"n\":\"Directional Rotation XY\"},{\"t\":3,\"n\":\"Directional Rotation Z\"},{\"t\":5,\"n\":\"Directional Fade\"},{\"t\":5,\"n\":\"Fog Clip Distance\"},{\"t\":5,\"n\":\"Fog Power\"},{\"t\":6,\"n\":\"Ambient Colors\",\"c\":[{\"t\":8,\"n\":\"Colors\",\"c\":[{\"t\":6,\"n\":\"Color #0 (X+)\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":6,\"n\":\"Color #1 (X-)\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":6,\"n\":\"Color #2 (Y+)\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":6,\"n\":\"Color #3 (Y-)\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":6,\"n\":\"Color #4 (Z+)\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":6,\"n\":\"Color #5 (Z-)\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unknown\"}]}]},{\"t\":6,\"n\":\"Specular\",\"c\":[{\"t\":6,\"n\":\"Color\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":5,\"n\":\"Fresnel Power\"}]}]},{\"t\":6,\"n\":\"Fog Color Far\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":5,\"n\":\"Fog Max\"},{\"t\":5,\"n\":\"Light Fade Begin\"},{\"t\":5,\"n\":\"Light Fade End\"},{\"t\":3,\"n\":\"Inherits\"}]},{\"t\":11,\"n\":\"TVDT - Unknown\"},{\"t\":11,\"n\":\"MHDT - Max Height Data\"},{\"t\":3,\"n\":\"LTMP - Lighting Template\"},{\"t\":11,\"n\":\"LNAM - Unknown\"},{\"t\":5,\"n\":\"XCLW - Water Height\"},{\"t\":2,\"n\":\"XNAM - Water Noise Texture\"},{\"t\":9,\"n\":\"XCLR - Regions\",\"c\":[{\"t\":3,\"n\":\"Region\"}]},{\"t\":3,\"n\":\"XLCN - Location\"},{\"t\":11,\"n\":\"XWCN - Unknown\"},{\"t\":11,\"n\":\"XWCS - Unknown\"},{\"t\":6,\"n\":\"XWCU - Water Velocity\",\"c\":[{\"t\":5,\"n\":\"X Offset\"},{\"t\":5,\"n\":\"Y Offset\"},{\"t\":5,\"n\":\"Z Offset\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":5,\"n\":\"X Angle\"},{\"t\":5,\"n\":\"Y Angle\"},{\"t\":5,\"n\":\"Z Angle\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":3,\"n\":\"XCWT - Water\"},{\"t\":6,\"n\":\"Ownership\",\"c\":[{\"t\":3,\"n\":\"XOWN - Owner\"}]},{\"t\":3,\"n\":\"XILL - Lock List\"},{\"t\":2,\"n\":\"XWEM - Water Environment Map\"},{\"t\":3,\"n\":\"XCCM - Sky\\/Weather from Region\"},{\"t\":3,\"n\":\"XCAS - Acoustic Space\"},{\"t\":3,\"n\":\"XEZN - Encounter Zone\"},{\"t\":3,\"n\":\"XCMO - Music Type\"},{\"t\":3,\"n\":\"XCIM - Image Space\"}]}]},\"name\":\"Bash.C.Name\",\"hash\":\"$F1A2C84F\",\"color\":255}"
  },
  {
    "path": "frontend/settings/Skyrim/Bash.C.Owner.json",
    "content": "{\"records\":\"CELL\",\"description\":\"C.Owner tag from Wrye Bash.\\r\\n\\r\\nUsed when the mod modifies cell ownership.\",\"tree\":{\"records\":[{\"t\":1,\"p\":1,\"n\":\"CELL - Cell\",\"c\":[{\"t\":6,\"n\":\"Record Header\",\"c\":[{\"t\":2,\"n\":\"Signature\"},{\"t\":3,\"n\":\"Data Size\"},{\"t\":3,\"n\":\"Record Flags\"},{\"t\":3,\"n\":\"FormID\"},{\"t\":11,\"n\":\"Version Control Info 1\"},{\"t\":3,\"n\":\"Form Version\"},{\"t\":11,\"n\":\"Version Control Info 2\"}]},{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"n\":\"FULL - Name\"},{\"t\":3,\"n\":\"DATA - Flags\",\"c\":[{\"t\":4,\"n\":\"Is Interior Cell\"}]},{\"t\":6,\"n\":\"XCLC - Grid\",\"c\":[{\"t\":3,\"n\":\"X\"},{\"t\":3,\"n\":\"Y\"},{\"t\":3,\"n\":\"Force Hide Land\"}]},{\"t\":6,\"n\":\"XCLL - Lighting\",\"c\":[{\"t\":6,\"n\":\"Ambient Color\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":6,\"n\":\"Directional Color\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":6,\"n\":\"Fog Color Near\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":5,\"n\":\"Fog Near\"},{\"t\":5,\"n\":\"Fog Far\"},{\"t\":3,\"n\":\"Directional Rotation XY\"},{\"t\":3,\"n\":\"Directional Rotation Z\"},{\"t\":5,\"n\":\"Directional Fade\"},{\"t\":5,\"n\":\"Fog Clip Distance\"},{\"t\":5,\"n\":\"Fog Power\"},{\"t\":6,\"n\":\"Ambient Colors\",\"c\":[{\"t\":8,\"n\":\"Colors\",\"c\":[{\"t\":6,\"n\":\"Color #0 (X+)\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":6,\"n\":\"Color #1 (X-)\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":6,\"n\":\"Color #2 (Y+)\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":6,\"n\":\"Color #3 (Y-)\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":6,\"n\":\"Color #4 (Z+)\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":6,\"n\":\"Color #5 (Z-)\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unknown\"}]}]},{\"t\":6,\"n\":\"Specular\",\"c\":[{\"t\":6,\"n\":\"Color\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":5,\"n\":\"Fresnel Power\"}]}]},{\"t\":6,\"n\":\"Fog Color Far\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":5,\"n\":\"Fog Max\"},{\"t\":5,\"n\":\"Light Fade Begin\"},{\"t\":5,\"n\":\"Light Fade End\"},{\"t\":3,\"n\":\"Inherits\"}]},{\"t\":11,\"n\":\"TVDT - Unknown\"},{\"t\":11,\"n\":\"MHDT - Max Height Data\"},{\"t\":3,\"n\":\"LTMP - Lighting Template\"},{\"t\":11,\"n\":\"LNAM - Unknown\"},{\"t\":5,\"n\":\"XCLW - Water Height\"},{\"t\":2,\"n\":\"XNAM - Water Noise Texture\"},{\"t\":9,\"n\":\"XCLR - Regions\",\"c\":[{\"t\":3,\"n\":\"Region\"}]},{\"t\":3,\"n\":\"XLCN - Location\"},{\"t\":11,\"n\":\"XWCN - Unknown\"},{\"t\":11,\"n\":\"XWCS - Unknown\"},{\"t\":6,\"n\":\"XWCU - Water Velocity\",\"c\":[{\"t\":5,\"n\":\"X Offset\"},{\"t\":5,\"n\":\"Y Offset\"},{\"t\":5,\"n\":\"Z Offset\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":5,\"n\":\"X Angle\"},{\"t\":5,\"n\":\"Y Angle\"},{\"t\":5,\"n\":\"Z Angle\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":3,\"n\":\"XCWT - Water\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Ownership\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"XOWN - Owner\"}]},{\"t\":3,\"n\":\"XILL - Lock List\"},{\"t\":2,\"n\":\"XWEM - Water Environment Map\"},{\"t\":3,\"n\":\"XCCM - Sky\\/Weather from Region\"},{\"t\":3,\"n\":\"XCAS - Acoustic Space\"},{\"t\":3,\"n\":\"XEZN - Encounter Zone\"},{\"t\":3,\"n\":\"XCMO - Music Type\"},{\"t\":3,\"n\":\"XCIM - Image Space\"}]}]},\"name\":\"Bash.C.Owner\",\"hash\":\"$C13A1CEE\",\"color\":255}"
  },
  {
    "path": "frontend/settings/Skyrim/Bash.C.RecordFlags.json",
    "content": "{\"records\":\"CELL\",\"description\":\"C.RecordFlags tag from Wrye Bash.\\r\\n\\r\\nUsed when the mod modifies the off-limits or dangerous flags.\",\"tree\":{\"records\":[{\"t\":1,\"p\":1,\"n\":\"CELL - Cell\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Record Header\",\"c\":[{\"t\":2,\"n\":\"Signature\"},{\"t\":3,\"n\":\"Data Size\"},{\"t\":3,\"p\":1,\"n\":\"Record Flags\"},{\"t\":3,\"n\":\"FormID\"},{\"t\":11,\"n\":\"Version Control Info 1\"},{\"t\":3,\"n\":\"Form Version\"},{\"t\":11,\"n\":\"Version Control Info 2\"}]},{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"n\":\"FULL - Name\"},{\"t\":3,\"n\":\"DATA - Flags\",\"c\":[{\"t\":4,\"n\":\"Is Interior Cell\"}]},{\"t\":6,\"n\":\"XCLC - Grid\",\"c\":[{\"t\":3,\"n\":\"X\"},{\"t\":3,\"n\":\"Y\"},{\"t\":3,\"n\":\"Force Hide Land\"}]},{\"t\":6,\"n\":\"XCLL - Lighting\",\"c\":[{\"t\":6,\"n\":\"Ambient Color\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":6,\"n\":\"Directional Color\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":6,\"n\":\"Fog Color Near\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":5,\"n\":\"Fog Near\"},{\"t\":5,\"n\":\"Fog Far\"},{\"t\":3,\"n\":\"Directional Rotation XY\"},{\"t\":3,\"n\":\"Directional Rotation Z\"},{\"t\":5,\"n\":\"Directional Fade\"},{\"t\":5,\"n\":\"Fog Clip Distance\"},{\"t\":5,\"n\":\"Fog Power\"},{\"t\":6,\"n\":\"Ambient Colors\",\"c\":[{\"t\":8,\"n\":\"Colors\",\"c\":[{\"t\":6,\"n\":\"Color #0 (X+)\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":6,\"n\":\"Color #1 (X-)\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":6,\"n\":\"Color #2 (Y+)\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":6,\"n\":\"Color #3 (Y-)\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":6,\"n\":\"Color #4 (Z+)\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":6,\"n\":\"Color #5 (Z-)\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unknown\"}]}]},{\"t\":6,\"n\":\"Specular\",\"c\":[{\"t\":6,\"n\":\"Color\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":5,\"n\":\"Fresnel Power\"}]}]},{\"t\":6,\"n\":\"Fog Color Far\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":5,\"n\":\"Fog Max\"},{\"t\":5,\"n\":\"Light Fade Begin\"},{\"t\":5,\"n\":\"Light Fade End\"},{\"t\":3,\"n\":\"Inherits\"}]},{\"t\":11,\"n\":\"TVDT - Unknown\"},{\"t\":11,\"n\":\"MHDT - Max Height Data\"},{\"t\":3,\"n\":\"LTMP - Lighting Template\"},{\"t\":11,\"n\":\"LNAM - Unknown\"},{\"t\":5,\"n\":\"XCLW - Water Height\"},{\"t\":2,\"n\":\"XNAM - Water Noise Texture\"},{\"t\":9,\"n\":\"XCLR - Regions\",\"c\":[{\"t\":3,\"n\":\"Region\"}]},{\"t\":3,\"n\":\"XLCN - Location\"},{\"t\":11,\"n\":\"XWCN - Unknown\"},{\"t\":11,\"n\":\"XWCS - Unknown\"},{\"t\":6,\"n\":\"XWCU - Water Velocity\",\"c\":[{\"t\":5,\"n\":\"X Offset\"},{\"t\":5,\"n\":\"Y Offset\"},{\"t\":5,\"n\":\"Z Offset\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":5,\"n\":\"X Angle\"},{\"t\":5,\"n\":\"Y Angle\"},{\"t\":5,\"n\":\"Z Angle\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":3,\"n\":\"XCWT - Water\"},{\"t\":6,\"n\":\"Ownership\",\"c\":[{\"t\":3,\"n\":\"XOWN - Owner\"}]},{\"t\":3,\"n\":\"XILL - Lock List\"},{\"t\":2,\"n\":\"XWEM - Water Environment Map\"},{\"t\":3,\"n\":\"XCCM - Sky\\/Weather from Region\"},{\"t\":3,\"n\":\"XCAS - Acoustic Space\"},{\"t\":3,\"n\":\"XEZN - Encounter Zone\"},{\"t\":3,\"n\":\"XCMO - Music Type\"},{\"t\":3,\"n\":\"XCIM - Image Space\"}]}]},\"name\":\"Bash.C.RecordFlags\",\"hash\":\"$BA9E2375\",\"color\":255}"
  },
  {
    "path": "frontend/settings/Skyrim/Bash.C.Regions.json",
    "content": "{\"records\":\"CELL\",\"description\":\"\",\"tree\":{\"records\":[{\"t\":1,\"p\":1,\"n\":\"CELL - Cell\",\"c\":[{\"t\":6,\"n\":\"Record Header\",\"c\":[{\"t\":2,\"n\":\"Signature\"},{\"t\":3,\"n\":\"Data Size\"},{\"t\":3,\"n\":\"Record Flags\"},{\"t\":3,\"n\":\"FormID\"},{\"t\":11,\"n\":\"Version Control Info 1\"},{\"t\":3,\"n\":\"Form Version\"},{\"t\":11,\"n\":\"Version Control Info 2\"}]},{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"n\":\"FULL - Name\"},{\"t\":3,\"n\":\"DATA - Flags\",\"c\":[{\"t\":4,\"n\":\"Is Interior Cell\"}]},{\"t\":6,\"n\":\"XCLC - Grid\",\"c\":[{\"t\":3,\"n\":\"X\"},{\"t\":3,\"n\":\"Y\"},{\"t\":3,\"n\":\"Force Hide Land\"}]},{\"t\":6,\"n\":\"XCLL - Lighting\",\"c\":[{\"t\":6,\"n\":\"Ambient Color\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":6,\"n\":\"Directional Color\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":6,\"n\":\"Fog Color Near\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":5,\"n\":\"Fog Near\"},{\"t\":5,\"n\":\"Fog Far\"},{\"t\":3,\"n\":\"Directional Rotation XY\"},{\"t\":3,\"n\":\"Directional Rotation Z\"},{\"t\":5,\"n\":\"Directional Fade\"},{\"t\":5,\"n\":\"Fog Clip Distance\"},{\"t\":5,\"n\":\"Fog Power\"},{\"t\":6,\"n\":\"Ambient Colors\",\"c\":[{\"t\":8,\"n\":\"Colors\",\"c\":[{\"t\":6,\"n\":\"Color #0 (X+)\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":6,\"n\":\"Color #1 (X-)\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":6,\"n\":\"Color #2 (Y+)\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":6,\"n\":\"Color #3 (Y-)\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":6,\"n\":\"Color #4 (Z+)\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":6,\"n\":\"Color #5 (Z-)\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unknown\"}]}]},{\"t\":6,\"n\":\"Specular\",\"c\":[{\"t\":6,\"n\":\"Color\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":5,\"n\":\"Fresnel Power\"}]}]},{\"t\":6,\"n\":\"Fog Color Far\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":5,\"n\":\"Fog Max\"},{\"t\":5,\"n\":\"Light Fade Begin\"},{\"t\":5,\"n\":\"Light Fade End\"},{\"t\":3,\"n\":\"Inherits\"}]},{\"t\":11,\"n\":\"TVDT - Unknown\"},{\"t\":11,\"n\":\"MHDT - Max Height Data\"},{\"t\":3,\"n\":\"LTMP - Lighting Template\"},{\"t\":11,\"n\":\"LNAM - Unknown\"},{\"t\":5,\"n\":\"XCLW - Water Height\"},{\"t\":2,\"n\":\"XNAM - Water Noise Texture\"},{\"t\":9,\"p\":1,\"n\":\"XCLR - Regions\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Region\"}]},{\"t\":3,\"n\":\"XLCN - Location\"},{\"t\":11,\"n\":\"XWCN - Unknown\"},{\"t\":11,\"n\":\"XWCS - Unknown\"},{\"t\":6,\"n\":\"XWCU - Water Velocity\",\"c\":[{\"t\":5,\"n\":\"X Offset\"},{\"t\":5,\"n\":\"Y Offset\"},{\"t\":5,\"n\":\"Z Offset\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":5,\"n\":\"X Angle\"},{\"t\":5,\"n\":\"Y Angle\"},{\"t\":5,\"n\":\"Z Angle\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":3,\"n\":\"XCWT - Water\"},{\"t\":6,\"n\":\"Ownership\",\"c\":[{\"t\":3,\"n\":\"XOWN - Owner\"}]},{\"t\":3,\"n\":\"XILL - Lock List\"},{\"t\":2,\"n\":\"XWEM - Water Environment Map\"},{\"t\":3,\"n\":\"XCCM - Sky\\/Weather from Region\"},{\"t\":3,\"n\":\"XCAS - Acoustic Space\"},{\"t\":3,\"n\":\"XEZN - Encounter Zone\"},{\"t\":3,\"n\":\"XCMO - Music Type\"},{\"t\":3,\"n\":\"XCIM - Image Space\"}]}]},\"name\":\"Bash.C.Regions\",\"hash\":\"$5ED0AD06\",\"color\":255}"
  },
  {
    "path": "frontend/settings/Skyrim/Bash.C.Water.json",
    "content": "{\"records\":\"CELL\",\"description\":\"C.Water tag from Wrye Bash.\\r\\n\\r\\nUsed when the mod modifies cell water type or level.\",\"tree\":{\"records\":[{\"t\":1,\"p\":1,\"n\":\"CELL - Cell\",\"c\":[{\"t\":6,\"n\":\"Record Header\",\"c\":[{\"t\":2,\"n\":\"Signature\"},{\"t\":3,\"n\":\"Data Size\"},{\"t\":3,\"n\":\"Record Flags\"},{\"t\":3,\"n\":\"FormID\"},{\"t\":11,\"n\":\"Version Control Info 1\"},{\"t\":3,\"n\":\"Form Version\"},{\"t\":11,\"n\":\"Version Control Info 2\"}]},{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"n\":\"FULL - Name\"},{\"t\":3,\"n\":\"DATA - Flags\",\"c\":[{\"t\":4,\"n\":\"Is Interior Cell\"}]},{\"t\":6,\"n\":\"XCLC - Grid\",\"c\":[{\"t\":3,\"n\":\"X\"},{\"t\":3,\"n\":\"Y\"},{\"t\":3,\"n\":\"Force Hide Land\"}]},{\"t\":6,\"n\":\"XCLL - Lighting\",\"c\":[{\"t\":6,\"n\":\"Ambient Color\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":6,\"n\":\"Directional Color\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":6,\"n\":\"Fog Color Near\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":5,\"n\":\"Fog Near\"},{\"t\":5,\"n\":\"Fog Far\"},{\"t\":3,\"n\":\"Directional Rotation XY\"},{\"t\":3,\"n\":\"Directional Rotation Z\"},{\"t\":5,\"n\":\"Directional Fade\"},{\"t\":5,\"n\":\"Fog Clip Distance\"},{\"t\":5,\"n\":\"Fog Power\"},{\"t\":6,\"n\":\"Ambient Colors\",\"c\":[{\"t\":8,\"n\":\"Colors\",\"c\":[{\"t\":6,\"n\":\"Color #0 (X+)\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":6,\"n\":\"Color #1 (X-)\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":6,\"n\":\"Color #2 (Y+)\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":6,\"n\":\"Color #3 (Y-)\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":6,\"n\":\"Color #4 (Z+)\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":6,\"n\":\"Color #5 (Z-)\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unknown\"}]}]},{\"t\":6,\"n\":\"Specular\",\"c\":[{\"t\":6,\"n\":\"Color\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":5,\"n\":\"Fresnel Power\"}]}]},{\"t\":6,\"n\":\"Fog Color Far\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":5,\"n\":\"Fog Max\"},{\"t\":5,\"n\":\"Light Fade Begin\"},{\"t\":5,\"n\":\"Light Fade End\"},{\"t\":3,\"n\":\"Inherits\"}]},{\"t\":11,\"n\":\"TVDT - Unknown\"},{\"t\":11,\"n\":\"MHDT - Max Height Data\"},{\"t\":3,\"n\":\"LTMP - Lighting Template\"},{\"t\":11,\"n\":\"LNAM - Unknown\"},{\"t\":5,\"p\":1,\"n\":\"XCLW - Water Height\"},{\"t\":2,\"n\":\"XNAM - Water Noise Texture\"},{\"t\":9,\"n\":\"XCLR - Regions\",\"c\":[{\"t\":3,\"n\":\"Region\"}]},{\"t\":3,\"n\":\"XLCN - Location\"},{\"t\":11,\"n\":\"XWCN - Unknown\"},{\"t\":11,\"n\":\"XWCS - Unknown\"},{\"t\":6,\"n\":\"XWCU - Water Velocity\",\"c\":[{\"t\":5,\"n\":\"X Offset\"},{\"t\":5,\"n\":\"Y Offset\"},{\"t\":5,\"n\":\"Z Offset\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":5,\"n\":\"X Angle\"},{\"t\":5,\"n\":\"Y Angle\"},{\"t\":5,\"n\":\"Z Angle\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":3,\"p\":1,\"n\":\"XCWT - Water\"},{\"t\":6,\"n\":\"Ownership\",\"c\":[{\"t\":3,\"n\":\"XOWN - Owner\"}]},{\"t\":3,\"n\":\"XILL - Lock List\"},{\"t\":2,\"n\":\"XWEM - Water Environment Map\"},{\"t\":3,\"n\":\"XCCM - Sky\\/Weather from Region\"},{\"t\":3,\"n\":\"XCAS - Acoustic Space\"},{\"t\":3,\"n\":\"XEZN - Encounter Zone\"},{\"t\":3,\"n\":\"XCMO - Music Type\"},{\"t\":3,\"n\":\"XCIM - Image Space\"}]}]},\"name\":\"Bash.C.Water\",\"hash\":\"$1C99179F\",\"color\":255}"
  },
  {
    "path": "frontend/settings/Skyrim/Bash.Delev.json",
    "content": "{\"records\":\"LVLI,LVSP,LVLN\",\"description\":\"Delev tag from Wrye Bash.\\r\\n\\r\\nRemoval of entries from the leveled list entries of Leveled Actor (LVLN), Leveled Item (LVLI) or Leveled Spell (LVSP) records.\",\"tree\":{\"records\":[{\"t\":1,\"p\":1,\"n\":\"LVLI - Leveled Item\",\"c\":[{\"t\":6,\"n\":\"Record Header\",\"c\":[{\"t\":2,\"n\":\"Signature\"},{\"t\":3,\"n\":\"Data Size\"},{\"t\":3,\"n\":\"Record Flags\"},{\"t\":3,\"n\":\"FormID\"},{\"t\":11,\"n\":\"Version Control Info 1\"},{\"t\":3,\"n\":\"Form Version\"},{\"t\":11,\"n\":\"Version Control Info 2\"}]},{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"n\":\"X1\"},{\"t\":3,\"n\":\"Y1\"},{\"t\":3,\"n\":\"Z1\"},{\"t\":3,\"n\":\"X2\"},{\"t\":3,\"n\":\"Y2\"},{\"t\":3,\"n\":\"Z2\"}]},{\"t\":3,\"n\":\"LVLD - Chance None\"},{\"t\":3,\"n\":\"LVLF - Flags\"},{\"t\":3,\"n\":\"LVLG - Global\"},{\"t\":3,\"n\":\"LLCT - Count\"},{\"t\":10,\"p\":1,\"n\":\"Leveled List Entries\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Leveled List Entry\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"LVLO - Base Data\",\"c\":[{\"t\":3,\"n\":\"Level\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":3,\"n\":\"Count\"},{\"t\":11,\"n\":\"Unknown\"}]}]}]}]},{\"t\":1,\"p\":1,\"n\":\"LVSP - Leveled Spell\",\"c\":[{\"t\":6,\"n\":\"Record Header\",\"c\":[{\"t\":2,\"n\":\"Signature\"},{\"t\":3,\"n\":\"Data Size\"},{\"t\":3,\"n\":\"Record Flags\"},{\"t\":3,\"n\":\"FormID\"},{\"t\":11,\"n\":\"Version Control Info 1\"},{\"t\":3,\"n\":\"Form Version\"},{\"t\":11,\"n\":\"Version Control Info 2\"}]},{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"n\":\"X1\"},{\"t\":3,\"n\":\"Y1\"},{\"t\":3,\"n\":\"Z1\"},{\"t\":3,\"n\":\"X2\"},{\"t\":3,\"n\":\"Y2\"},{\"t\":3,\"n\":\"Z2\"}]},{\"t\":3,\"n\":\"LVLD - Chance None\"},{\"t\":3,\"n\":\"LVLF - Flags\"},{\"t\":3,\"n\":\"LLCT - Count\"},{\"t\":10,\"p\":1,\"n\":\"Leveled List Entries\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Leveled List Entry\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"LVLO - Base Data\",\"c\":[{\"t\":3,\"n\":\"Level\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":3,\"n\":\"Count\"},{\"t\":11,\"n\":\"Unknown\"}]}]}]}]},{\"t\":1,\"p\":1,\"n\":\"LVLN - Leveled NPC\",\"c\":[{\"t\":6,\"n\":\"Record Header\",\"c\":[{\"t\":2,\"n\":\"Signature\"},{\"t\":3,\"n\":\"Data Size\"},{\"t\":3,\"n\":\"Record Flags\"},{\"t\":3,\"n\":\"FormID\"},{\"t\":11,\"n\":\"Version Control Info 1\"},{\"t\":3,\"n\":\"Form Version\"},{\"t\":11,\"n\":\"Version Control Info 2\"}]},{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"n\":\"X1\"},{\"t\":3,\"n\":\"Y1\"},{\"t\":3,\"n\":\"Z1\"},{\"t\":3,\"n\":\"X2\"},{\"t\":3,\"n\":\"Y2\"},{\"t\":3,\"n\":\"Z2\"}]},{\"t\":3,\"n\":\"LVLD - Chance None\"},{\"t\":3,\"n\":\"LVLF - Flags\"},{\"t\":3,\"n\":\"LVLG - Global\"},{\"t\":3,\"n\":\"LLCT - Count\"},{\"t\":10,\"p\":1,\"n\":\"Leveled List Entries\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Leveled List Entry\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"LVLO - Base Data\",\"c\":[{\"t\":3,\"n\":\"Level\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":3,\"n\":\"Count\"},{\"t\":11,\"n\":\"Unknown\"}]}]}]},{\"t\":6,\"n\":\"Model\",\"c\":[{\"t\":2,\"n\":\"MODL - Model Filename\"}]}]}]},\"name\":\"Bash.Delev\",\"hash\":\"$90E3A612\",\"color\":255}"
  },
  {
    "path": "frontend/settings/Skyrim/Bash.Eyes.json",
    "content": "{\"records\":\"RACE\",\"description\":\"Eyes tag from Wrye Bash.\\r\\n\\r\\nUsed when the mod adds eyes to races.\",\"tree\":{\"records\":[{\"t\":1,\"p\":1,\"n\":\"RACE - Race\",\"c\":[{\"t\":6,\"n\":\"Record Header\",\"c\":[{\"t\":2,\"n\":\"Signature\"},{\"t\":3,\"n\":\"Data Size\"},{\"t\":3,\"n\":\"Record Flags\"},{\"t\":3,\"n\":\"FormID\"},{\"t\":11,\"n\":\"Version Control Info 1\"},{\"t\":3,\"n\":\"Form Version\"},{\"t\":11,\"n\":\"Version Control Info 2\"}]},{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"n\":\"FULL - Name\"},{\"t\":2,\"n\":\"DESC - Description\"},{\"t\":3,\"n\":\"SPCT - Count\"},{\"t\":9,\"n\":\"Actor Effects\",\"c\":[{\"t\":3,\"n\":\"SPLO - Actor Effect\"}]},{\"t\":3,\"n\":\"WNAM - Skin\"},{\"t\":6,\"n\":\"BOD2 - Biped Body Template\",\"c\":[{\"t\":3,\"n\":\"First Person Flags\"},{\"t\":3,\"n\":\"General Flags\"},{\"n\":\"Unused\"},{\"t\":3,\"n\":\"Armor Type\"}]},{\"t\":3,\"n\":\"KSIZ - Keyword Count\"},{\"t\":9,\"n\":\"KWDA - Keywords\",\"c\":[{\"t\":3,\"n\":\"Keyword\"}]},{\"t\":6,\"n\":\"DATA - \",\"c\":[{\"t\":10,\"n\":\"Skill Boosts\",\"c\":[{\"t\":6,\"n\":\"Skill Boost\",\"c\":[{\"t\":3,\"n\":\"Skill\"},{\"t\":3,\"n\":\"Boost\"}]},{\"t\":6,\"n\":\"Skill Boost\",\"c\":[{\"t\":3,\"n\":\"Skill\"},{\"t\":3,\"n\":\"Boost\"}]},{\"t\":6,\"n\":\"Skill Boost\",\"c\":[{\"t\":3,\"n\":\"Skill\"},{\"t\":3,\"n\":\"Boost\"}]},{\"t\":6,\"n\":\"Skill Boost\",\"c\":[{\"t\":3,\"n\":\"Skill\"},{\"t\":3,\"n\":\"Boost\"}]},{\"t\":6,\"n\":\"Skill Boost\",\"c\":[{\"t\":3,\"n\":\"Skill\"},{\"t\":3,\"n\":\"Boost\"}]},{\"t\":6,\"n\":\"Skill Boost\",\"c\":[{\"t\":3,\"n\":\"Skill\"},{\"t\":3,\"n\":\"Boost\"}]},{\"t\":6,\"n\":\"Skill Boost\",\"c\":[{\"t\":3,\"n\":\"Skill\"},{\"t\":3,\"n\":\"Boost\"}]}]},{\"t\":11,\"n\":\"Unknown\"},{\"t\":5,\"n\":\"Male Height\"},{\"t\":5,\"n\":\"Female Height\"},{\"t\":5,\"n\":\"Male Weight\"},{\"t\":5,\"n\":\"Female Weight\"},{\"t\":3,\"n\":\"Flags\"},{\"t\":5,\"n\":\"Starting Health\"},{\"t\":5,\"n\":\"Starting Magicka\"},{\"t\":5,\"n\":\"Starting Stamina\"},{\"t\":5,\"n\":\"Base Carry Weight\"},{\"t\":5,\"n\":\"Base Mass\"},{\"t\":5,\"n\":\"Acceleration rate\"},{\"t\":5,\"n\":\"Deceleration rate\"},{\"t\":3,\"n\":\"Size\"},{\"t\":3,\"n\":\"Head Biped Object\"},{\"t\":3,\"n\":\"Hair Biped Object\"},{\"t\":5,\"n\":\"Injured Health Pct\"},{\"t\":3,\"n\":\"Shield Biped Object\"},{\"t\":5,\"n\":\"Health Regen\"},{\"t\":5,\"n\":\"Magicka Regen\"},{\"t\":5,\"n\":\"Stamina Regen\"},{\"t\":5,\"n\":\"Unarmed Damage\"},{\"t\":5,\"n\":\"Unarmed Reach\"},{\"t\":3,\"n\":\"Body Biped Object\"},{\"t\":5,\"n\":\"Aim Angle Tolerance\"},{\"t\":5,\"n\":\"Flight Radius\"},{\"t\":5,\"n\":\"Angular Acceleration Rate\"},{\"t\":5,\"n\":\"Angular Tolerance\"},{\"t\":3,\"n\":\"Flags 2\"},{\"t\":6,\"n\":\"Mount Data\",\"c\":[{\"t\":5,\"n\":\"Offset X\"},{\"t\":5,\"n\":\"Offset Y\"},{\"t\":5,\"n\":\"Unknown\"},{\"t\":5,\"n\":\"Unknown\"},{\"t\":5,\"n\":\"Unknown\"},{\"t\":5,\"n\":\"Unknown\"},{\"t\":5,\"n\":\"Unknown\"},{\"t\":5,\"n\":\"Unknown\"},{\"t\":5,\"n\":\"Unknown\"}]}]},{\"n\":\"MNAM - Male Marker\"},{\"t\":2,\"n\":\"ANAM - Male Skeletal Model\"},{\"t\":11,\"n\":\"MODT - Texture Files Hashes\"},{\"n\":\"FNAM - Female Marker\"},{\"t\":2,\"n\":\"ANAM - Female Skeletal Model\"},{\"t\":11,\"n\":\"MODT - Texture Files Hashes\"},{\"n\":\"NAM2 - Marker NAM2 #1\"},{\"t\":9,\"n\":\"Movement Type Names\",\"c\":[{\"t\":2,\"n\":\"MTNM - Name\"}]},{\"t\":7,\"n\":\"VTCK - Voices\",\"c\":[{\"t\":3,\"n\":\"Voice #0 (Male)\"},{\"t\":3,\"n\":\"Voice #1 (Female)\"}]},{\"t\":7,\"n\":\"DNAM - Decapitate Armors\",\"c\":[{\"t\":3,\"n\":\"Decapitate Armor #0 (Male)\"},{\"t\":3,\"n\":\"Decapitate Armor #1 (Female)\"}]},{\"t\":7,\"n\":\"HCLF - Default Hair Colors\",\"c\":[{\"t\":3,\"n\":\"Default Hair Color #0 (Male)\"},{\"t\":3,\"n\":\"Default Hair Color #1 (Female)\"}]},{\"t\":3,\"n\":\"TINL - Total Number of Tints in List\"},{\"t\":5,\"n\":\"PNAM - FaceGen - Main clamp\"},{\"t\":5,\"n\":\"UNAM - FaceGen - Face clamp\"},{\"t\":3,\"n\":\"ATKR - Attack Race\"},{\"t\":10,\"n\":\"Attacks\",\"c\":[{\"t\":6,\"n\":\"Attack\",\"c\":[{\"t\":6,\"n\":\"ATKD - Attack Data\",\"c\":[{\"t\":5,\"n\":\"Damage Mult\"},{\"t\":5,\"n\":\"Attack Chance\"},{\"t\":3,\"n\":\"Attack Spell\"},{\"t\":3,\"n\":\"Attack Flags\"},{\"t\":5,\"n\":\"Attack Angle\"},{\"t\":5,\"n\":\"Strike Angle\"},{\"t\":5,\"n\":\"Stagger\"},{\"t\":3,\"n\":\"Attack Type\"},{\"t\":5,\"n\":\"Knockdown\"},{\"t\":5,\"n\":\"Recovery Time\"},{\"t\":5,\"n\":\"Stamina Mult\"}]}]}]},{\"t\":6,\"n\":\"Body Data\",\"c\":[{\"n\":\"NAM1 - Body Data Marker\"},{\"t\":6,\"n\":\"Male Body Data\",\"c\":[{\"n\":\"MNAM - Male Data Marker\"},{\"t\":10,\"n\":\"Parts\",\"c\":[{\"t\":6,\"n\":\"Part\",\"c\":[{\"t\":3,\"n\":\"INDX - Index\"}]}]}]},{\"t\":6,\"n\":\"Female Body Data\",\"c\":[{\"n\":\"FNAM - Female Data Marker\"},{\"t\":10,\"n\":\"Parts\",\"c\":[{\"t\":6,\"n\":\"Part\",\"c\":[{\"t\":3,\"n\":\"INDX - Index\"}]}]}]}]},{\"t\":9,\"n\":\"HNAM - Hairs\",\"c\":[{\"t\":3,\"n\":\"Hair\"}]},{\"t\":9,\"p\":1,\"n\":\"ENAM - Eyes\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Eye\"}]},{\"t\":3,\"n\":\"GNAM - Body Part Data\"},{\"n\":\"NAM2 - Marker NAM2 #2\"},{\"n\":\"NAM3 - Marker NAM3 #3\"},{\"t\":6,\"n\":\"Male Behavior Graph\",\"c\":[{\"n\":\"MNAM - Male Data Marker\"}]},{\"t\":6,\"n\":\"Female Behavior Graph\",\"c\":[{\"n\":\"FNAM - Female Data Marker\"}]},{\"t\":3,\"n\":\"NAM4 - Material Type\"},{\"t\":3,\"n\":\"NAM5 - Impact Data Set\"},{\"t\":3,\"n\":\"NAM7 - Decapitation FX\"},{\"t\":3,\"n\":\"ONAM - Open Loot Sound\"},{\"t\":3,\"n\":\"LNAM - Close Loot Sound\"},{\"t\":7,\"n\":\"Biped Object Names\",\"c\":[{\"t\":2,\"n\":\"NAME - Name\"}]},{\"t\":10,\"n\":\"Movement Types\",\"c\":[{\"t\":6,\"n\":\"Movement Types\",\"c\":[{\"t\":3,\"n\":\"MTYP - Movement Type\"}]}]},{\"t\":3,\"n\":\"VNAM - Equipment Flags\"},{\"t\":9,\"n\":\"Equip Slots\",\"c\":[{\"t\":3,\"n\":\"QNAM - Equip Slot\"}]},{\"t\":3,\"n\":\"UNES - Unarmed Equip Slot\"},{\"t\":7,\"n\":\"Phoneme Target Names\",\"c\":[{\"t\":2,\"n\":\"PHTN - Name\"}]},{\"t\":6,\"n\":\"FaceFX Phonemes\",\"c\":[{\"t\":6,\"n\":\"IY\",\"c\":[{\"t\":6,\"n\":\"PHWT - Phoneme Target Weight\",\"c\":[{\"t\":5,\"n\":\"Aah \\/ LipBigAah\"},{\"t\":5,\"n\":\"BigAah \\/ LipDST\"},{\"t\":5,\"n\":\"BMP \\/ LipEee\"},{\"t\":5,\"n\":\"ChJsh \\/ LipFV\"},{\"t\":5,\"n\":\"DST \\/ LipK\"},{\"t\":5,\"n\":\"Eee \\/ LipL\"},{\"t\":5,\"n\":\"Eh \\/ LipR\"},{\"t\":5,\"n\":\"FV \\/ LipTh\"},{\"t\":5,\"n\":\"I\"},{\"t\":5,\"n\":\"K\"},{\"t\":5,\"n\":\"N\"},{\"t\":5,\"n\":\"Oh\"},{\"t\":5,\"n\":\"OohQ\"},{\"t\":5,\"n\":\"R\"},{\"t\":5,\"n\":\"TH\"},{\"t\":5,\"n\":\"W\"}]}]}]},{\"t\":3,\"n\":\"WKMV - Base Movement Default - Walk\"},{\"t\":3,\"n\":\"RNMV - Base Movement Default - Run\"},{\"t\":3,\"n\":\"SWMV - Base Movement Default - Swim\"},{\"t\":3,\"n\":\"FLMV - Base Movement Default - Fly\"},{\"t\":3,\"n\":\"SNMV - Base Movement Default - Sneak\"},{\"t\":3,\"n\":\"SPMV - Base Movement Default - Sprint\"},{\"t\":6,\"n\":\"Head Data\",\"c\":[{\"n\":\"NAM0 - Head Data Marker\"},{\"t\":6,\"n\":\"Male Head Data\",\"c\":[{\"n\":\"MNAM - Male Data Marker\"}]},{\"t\":6,\"n\":\"Female Head Data\",\"c\":[{\"n\":\"NAM0 - Head Data Marker\"},{\"n\":\"FNAM - Female Data Marker\"}]}]},{\"t\":3,\"n\":\"NAM8 - Morph race\"},{\"t\":3,\"n\":\"RNAM - Armor race\"}]}]},\"name\":\"Bash.Eyes\",\"hash\":\"3992F5B6\",\"color\":255}"
  },
  {
    "path": "frontend/settings/Skyrim/Bash.Factions.json",
    "content": "{\"records\":\"NPC_\",\"description\":\"Factions tag from Wrye Bash.\\r\\n\\r\\nUsed when the mod modifies NPC factions.\",\"tree\":{\"records\":[{\"t\":1,\"p\":1,\"n\":\"NPC_ - Non-Player Character (Actor)\",\"c\":[{\"t\":6,\"n\":\"Record Header\",\"c\":[{\"t\":2,\"n\":\"Signature\"},{\"t\":3,\"n\":\"Data Size\"},{\"t\":3,\"n\":\"Record Flags\"},{\"t\":3,\"n\":\"FormID\"},{\"t\":11,\"n\":\"Version Control Info 1\"},{\"t\":3,\"n\":\"Form Version\"},{\"t\":11,\"n\":\"Version Control Info 2\"}]},{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"n\":\"VMAD - Virtual Machine Adapter\",\"c\":[{\"t\":3,\"n\":\"Version\"},{\"t\":3,\"n\":\"Object Format\"},{\"t\":12,\"n\":\"Data\",\"c\":[{\"t\":9,\"n\":\"Scripts\",\"c\":[{\"t\":6,\"n\":\"Script\",\"c\":[{\"t\":2,\"n\":\"scriptName\"},{\"t\":3,\"n\":\"Flags\"},{\"t\":9,\"n\":\"Properties\",\"c\":[{\"t\":6,\"n\":\"Property\",\"c\":[{\"t\":2,\"n\":\"propertyName\"},{\"t\":3,\"n\":\"Type\"},{\"t\":3,\"n\":\"Flags\"},{\"t\":12,\"n\":\"Value\"}]}]}]}]}]}]},{\"t\":6,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"n\":\"X1\"},{\"t\":3,\"n\":\"Y1\"},{\"t\":3,\"n\":\"Z1\"},{\"t\":3,\"n\":\"X2\"},{\"t\":3,\"n\":\"Y2\"},{\"t\":3,\"n\":\"Z2\"}]},{\"t\":6,\"n\":\"ACBS - Configuration\",\"c\":[{\"t\":3,\"n\":\"Flags\"},{\"t\":3,\"n\":\"Magicka Offset\"},{\"t\":3,\"n\":\"Stamina Offset\"},{\"t\":12,\"n\":\"Level\"},{\"t\":3,\"n\":\"Calc min level\"},{\"t\":3,\"n\":\"Calc max level\"},{\"t\":3,\"n\":\"Speed Multiplier\"},{\"t\":3,\"n\":\"Disposition Base (unused)\"},{\"t\":3,\"n\":\"Template Flags\"},{\"t\":3,\"n\":\"Health Offset\"},{\"t\":3,\"n\":\"Bleedout Override\"}]},{\"t\":10,\"s\":1,\"p\":1,\"n\":\"Factions\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"SNAM - Faction\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Faction\"},{\"t\":3,\"p\":1,\"n\":\"Rank\"},{\"t\":11,\"p\":1,\"n\":\"Unused\"}]}]},{\"t\":3,\"n\":\"INAM - Death item\"},{\"t\":3,\"n\":\"VTCK - Voice\"},{\"t\":3,\"n\":\"TPLT - Template\"},{\"t\":3,\"n\":\"RNAM - Race\"},{\"t\":3,\"n\":\"SPCT - Count\"},{\"t\":9,\"n\":\"Actor Effects\",\"c\":[{\"t\":3,\"n\":\"SPLO - Actor Effect\"}]},{\"t\":6,\"n\":\"Destructable\",\"c\":[{\"t\":6,\"n\":\"DEST - Header\",\"c\":[{\"t\":3,\"n\":\"Health\"},{\"t\":3,\"n\":\"DEST Count\"},{\"t\":3,\"n\":\"VATS Targetable\"},{\"t\":11,\"n\":\"Unknown\"}]}]},{\"t\":3,\"n\":\"WNAM - Worn Armor\"},{\"t\":3,\"n\":\"ANAM - Far away model\"},{\"t\":3,\"n\":\"ATKR - Attack Race\"},{\"t\":10,\"n\":\"Attacks\",\"c\":[{\"t\":6,\"n\":\"Attack\",\"c\":[{\"t\":6,\"n\":\"ATKD - Attack Data\",\"c\":[{\"t\":5,\"n\":\"Damage Mult\"},{\"t\":5,\"n\":\"Attack Chance\"},{\"t\":3,\"n\":\"Attack Spell\"},{\"t\":3,\"n\":\"Attack Flags\"},{\"t\":5,\"n\":\"Attack Angle\"},{\"t\":5,\"n\":\"Strike Angle\"},{\"t\":5,\"n\":\"Stagger\"},{\"t\":3,\"n\":\"Attack Type\"},{\"t\":5,\"n\":\"Knockdown\"},{\"t\":5,\"n\":\"Recovery Time\"},{\"t\":5,\"n\":\"Stamina Mult\"}]}]}]},{\"t\":3,\"n\":\"SPOR - Spectator override package list\"},{\"t\":3,\"n\":\"OCOR - Observe dead body override package list\"},{\"t\":3,\"n\":\"GWOR - Guard warn override package list\"},{\"t\":3,\"n\":\"ECOR - Combat override package list\"},{\"t\":3,\"n\":\"PRKZ - Perk Count\"},{\"t\":10,\"n\":\"Perks\",\"c\":[{\"t\":6,\"n\":\"PRKR - Perk\",\"c\":[{\"t\":3,\"n\":\"Perk\"},{\"t\":3,\"n\":\"Rank\"},{\"t\":11,\"n\":\"Unused\"}]}]},{\"t\":3,\"n\":\"COCT - Count\"},{\"t\":10,\"n\":\"Items\",\"c\":[{\"t\":6,\"n\":\"Item\",\"c\":[{\"t\":6,\"n\":\"CNTO - Item\",\"c\":[{\"t\":3,\"n\":\"Item\"},{\"t\":3,\"n\":\"Count\"}]}]}]},{\"t\":6,\"n\":\"AIDT - AI Data\",\"c\":[{\"t\":3,\"n\":\"Aggression\"},{\"t\":3,\"n\":\"Confidence\"},{\"t\":3,\"n\":\"Energy Level\"},{\"t\":3,\"n\":\"Responsibility\"},{\"t\":3,\"n\":\"Mood\"},{\"t\":3,\"n\":\"Assistance\"},{\"t\":6,\"n\":\"Aggro\",\"c\":[{\"t\":3,\"n\":\"Aggro Radius Behavior\"},{\"t\":3,\"n\":\"Unknown\"},{\"t\":3,\"n\":\"Warn\"},{\"t\":3,\"n\":\"Warn\\/Attack\"},{\"t\":3,\"n\":\"Attack\"}]}]},{\"t\":7,\"n\":\"Packages\",\"c\":[{\"t\":3,\"n\":\"PKID - Package\"}]},{\"t\":3,\"n\":\"KSIZ - Keyword Count\"},{\"t\":9,\"n\":\"KWDA - Keywords\",\"c\":[{\"t\":3,\"n\":\"Keyword\"}]},{\"t\":3,\"n\":\"CNAM - Class\"},{\"t\":2,\"n\":\"FULL - Name\"},{\"t\":2,\"n\":\"SHRT - Short Name\"},{\"t\":11,\"n\":\"DATA - Marker\"},{\"t\":6,\"n\":\"DNAM - Player Skills\",\"c\":[{\"t\":7,\"n\":\"Skill Values\",\"c\":[{\"t\":3,\"n\":\"Skill #0 (OneHanded)\"},{\"t\":3,\"n\":\"Skill #1 (TwoHanded)\"},{\"t\":3,\"n\":\"Skill #2 (Marksman)\"},{\"t\":3,\"n\":\"Skill #3 (Block)\"},{\"t\":3,\"n\":\"Skill #4 (Smithing)\"},{\"t\":3,\"n\":\"Skill #5 (HeavyArmor)\"},{\"t\":3,\"n\":\"Skill #6 (LightArmor)\"},{\"t\":3,\"n\":\"Skill #7 (Pickpocket)\"},{\"t\":3,\"n\":\"Skill #8 (Lockpicking)\"},{\"t\":3,\"n\":\"Skill #9 (Sneak)\"},{\"t\":3,\"n\":\"Skill #10 (Alchemy)\"},{\"t\":3,\"n\":\"Skill #11 (Speechcraft)\"},{\"t\":3,\"n\":\"Skill #12 (Alteration)\"},{\"t\":3,\"n\":\"Skill #13 (Conjuration)\"},{\"t\":3,\"n\":\"Skill #14 (Destruction)\"},{\"t\":3,\"n\":\"Skill #15 (Illusion)\"},{\"t\":3,\"n\":\"Skill #16 (Restoration)\"},{\"t\":3,\"n\":\"Skill #17 (Enchanting)\"}]},{\"t\":7,\"n\":\"Skill Offsets\",\"c\":[{\"t\":3,\"n\":\"Skill #0 (OneHanded)\"},{\"t\":3,\"n\":\"Skill #1 (TwoHanded)\"},{\"t\":3,\"n\":\"Skill #2 (Marksman)\"},{\"t\":3,\"n\":\"Skill #3 (Block)\"},{\"t\":3,\"n\":\"Skill #4 (Smithing)\"},{\"t\":3,\"n\":\"Skill #5 (HeavyArmor)\"},{\"t\":3,\"n\":\"Skill #6 (LightArmor)\"},{\"t\":3,\"n\":\"Skill #7 (Pickpocket)\"},{\"t\":3,\"n\":\"Skill #8 (Lockpicking)\"},{\"t\":3,\"n\":\"Skill #9 (Sneak)\"},{\"t\":3,\"n\":\"Skill #10 (Alchemy)\"},{\"t\":3,\"n\":\"Skill #11 (Speechcraft)\"},{\"t\":3,\"n\":\"Skill #12 (Alteration)\"},{\"t\":3,\"n\":\"Skill #13 (Conjuration)\"},{\"t\":3,\"n\":\"Skill #14 (Destruction)\"},{\"t\":3,\"n\":\"Skill #15 (Illusion)\"},{\"t\":3,\"n\":\"Skill #16 (Restoration)\"},{\"t\":3,\"n\":\"Skill #17 (Enchanting)\"}]},{\"t\":3,\"n\":\"Health\"},{\"t\":3,\"n\":\"Magicka\"},{\"t\":3,\"n\":\"Stamina\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":5,\"n\":\"Far away model distance\"},{\"t\":3,\"n\":\"Geared up weapons\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":9,\"n\":\"Head Parts\",\"c\":[{\"t\":3,\"n\":\"PNAM - Head Part\"}]},{\"t\":3,\"n\":\"HCLF - Hair Color\"},{\"t\":3,\"n\":\"ZNAM - Combat Style\"},{\"t\":3,\"n\":\"GNAM - Gift Filter\"},{\"t\":11,\"n\":\"NAM5 - Unknown\"},{\"t\":5,\"n\":\"NAM6 - Height\"},{\"t\":5,\"n\":\"NAM7 - Weight\"},{\"t\":3,\"n\":\"NAM8 - Sound Level\"},{\"t\":10,\"n\":\"Sound Types\",\"c\":[{\"t\":6,\"n\":\"Sound Type\",\"c\":[{\"t\":3,\"n\":\"CSDT - Type\"},{\"t\":10,\"n\":\"Sounds\",\"c\":[{\"t\":6,\"n\":\"Sound\",\"c\":[{\"t\":3,\"n\":\"CSDI - Sound\"},{\"t\":3,\"n\":\"CSDC - Sound Chance\"}]}]}]}]},{\"t\":3,\"n\":\"CSCR - Inherits Sounds From\"},{\"t\":3,\"n\":\"DOFT - Default outfit\"},{\"t\":3,\"n\":\"SOFT - Sleeping outfit\"},{\"t\":3,\"n\":\"DPLT - Default Package List\"},{\"t\":3,\"n\":\"CRIF - Crime faction\"},{\"t\":3,\"n\":\"FTST - Head texture\"},{\"t\":6,\"n\":\"QNAM - Texture lighting\",\"c\":[{\"t\":5,\"n\":\"Red\"},{\"t\":5,\"n\":\"Green\"},{\"t\":5,\"n\":\"Blue\"}]},{\"t\":6,\"n\":\"NAM9 - Face morph\",\"c\":[{\"t\":5,\"n\":\"Nose Long\\/Short\"},{\"t\":5,\"n\":\"Nose Up\\/Down\"},{\"t\":5,\"n\":\"Jaw Up\\/Down\"},{\"t\":5,\"n\":\"Jaw Narrow\\/Wide\"},{\"t\":5,\"n\":\"Jaw Farward\\/Back\"},{\"t\":5,\"n\":\"Cheeks Up\\/Down\"},{\"t\":5,\"n\":\"Cheeks Farward\\/Back\"},{\"t\":5,\"n\":\"Eyes Up\\/Down\"},{\"t\":5,\"n\":\"Eyes In\\/Out\"},{\"t\":5,\"n\":\"Brows Up\\/Down\"},{\"t\":5,\"n\":\"Brows In\\/Out\"},{\"t\":5,\"n\":\"Brows Farward\\/Back\"},{\"t\":5,\"n\":\"Lips Up\\/Down\"},{\"t\":5,\"n\":\"Lips In\\/Out\"},{\"t\":5,\"n\":\"Chin Narrow\\/Wide\"},{\"t\":5,\"n\":\"Chin Up\\/Down\"},{\"t\":5,\"n\":\"Chin Underbite\\/Overbite\"},{\"t\":5,\"n\":\"Eyes Farward\\/Back\"},{\"t\":5,\"n\":\"Unknown\"}]},{\"t\":6,\"n\":\"NAMA - Face parts\",\"c\":[{\"t\":3,\"n\":\"Nose\"},{\"t\":3,\"n\":\"Unknown\"},{\"t\":3,\"n\":\"Eyes\"},{\"t\":3,\"n\":\"Mouth\"}]},{\"t\":10,\"n\":\"Tint Layers\",\"c\":[{\"t\":6,\"n\":\"Layer\",\"c\":[{\"t\":3,\"n\":\"TINI - Tint Index\"}]}]}]}]},\"name\":\"Bash.Factions\",\"hash\":\"$727C24D6\",\"color\":255}"
  },
  {
    "path": "frontend/settings/Skyrim/Bash.Graphics.json",
    "content": "{\"records\":\"ACTI,AMMO,APPA,ARMA,ARMO,ARTO,BOOK,DEBR,DOOR,EFSH,EXPL,FLOR,FURN,GRAS,INGR,LIGH,LSCR,MGEF,MISC,MSTT,PROJ,SCRL,SLGM,STAT,TREE,WEAP,ALCH\",\"description\":\"Graphics tag from Wrye Bash.\\r\\n\\r\\nUsed when the mod is a graphics replacer.\\r\\n\\r\\nNote: I tried my best to get all appropriate records and subrecords for Skyrim in the spirit of this Bash Tag, but I may have missed things.  Please let me know if I did.  -Mator\",\"tree\":{\"records\":[{\"t\":1,\"p\":1,\"n\":\"ACTI - Activator\",\"c\":[{\"t\":6,\"n\":\"Record Header\",\"c\":[{\"t\":2,\"n\":\"Signature\"},{\"t\":3,\"n\":\"Data Size\"},{\"t\":3,\"n\":\"Record Flags\"},{\"t\":3,\"n\":\"FormID\"},{\"t\":11,\"n\":\"Version Control Info 1\"},{\"t\":3,\"n\":\"Form Version\"},{\"t\":11,\"n\":\"Version Control Info 2\"}]},{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"n\":\"VMAD - Virtual Machine Adapter\",\"c\":[{\"t\":3,\"n\":\"Version\"},{\"t\":3,\"n\":\"Object Format\"},{\"t\":12,\"n\":\"Data\",\"c\":[{\"t\":9,\"n\":\"Scripts\",\"c\":[{\"t\":6,\"n\":\"Script\",\"c\":[{\"t\":2,\"n\":\"scriptName\"},{\"t\":3,\"n\":\"Flags\"},{\"t\":9,\"n\":\"Properties\",\"c\":[{\"t\":6,\"n\":\"Property\",\"c\":[{\"t\":2,\"n\":\"propertyName\"},{\"t\":3,\"n\":\"Type\"},{\"t\":3,\"n\":\"Flags\"},{\"t\":12,\"n\":\"Value\"}]}]}]}]}]}]},{\"t\":6,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"n\":\"X1\"},{\"t\":3,\"n\":\"Y1\"},{\"t\":3,\"n\":\"Z1\"},{\"t\":3,\"n\":\"X2\"},{\"t\":3,\"n\":\"Y2\"},{\"t\":3,\"n\":\"Z2\"}]},{\"t\":2,\"n\":\"FULL - Name\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"}]},{\"t\":6,\"n\":\"Destructable\",\"c\":[{\"t\":6,\"n\":\"DEST - Header\",\"c\":[{\"t\":3,\"n\":\"Health\"},{\"t\":3,\"n\":\"DEST Count\"},{\"t\":3,\"n\":\"VATS Targetable\"},{\"t\":11,\"n\":\"Unknown\"}]}]},{\"t\":3,\"n\":\"KSIZ - Keyword Count\"},{\"t\":9,\"n\":\"KWDA - Keywords\",\"c\":[{\"t\":3,\"n\":\"Keyword\"}]},{\"t\":6,\"n\":\"PNAM - Marker Color\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":3,\"n\":\"Unused\"}]},{\"t\":3,\"n\":\"SNAM - Sound - Looping\"},{\"t\":3,\"n\":\"VNAM - Sound - Activation\"},{\"t\":3,\"n\":\"WNAM - Water Type\"},{\"t\":2,\"n\":\"RNAM - Activate Text Override\"},{\"t\":3,\"n\":\"FNAM - Flags\"},{\"t\":3,\"n\":\"KNAM - Interaction Keyword\"}]},{\"t\":1,\"p\":1,\"n\":\"AMMO - Ammunition\",\"c\":[{\"t\":6,\"n\":\"Record Header\",\"c\":[{\"t\":2,\"n\":\"Signature\"},{\"t\":3,\"n\":\"Data Size\"},{\"t\":3,\"n\":\"Record Flags\"},{\"t\":3,\"n\":\"FormID\"},{\"t\":11,\"n\":\"Version Control Info 1\"},{\"t\":3,\"n\":\"Form Version\"},{\"t\":11,\"n\":\"Version Control Info 2\"}]},{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"n\":\"X1\"},{\"t\":3,\"n\":\"Y1\"},{\"t\":3,\"n\":\"Z1\"},{\"t\":3,\"n\":\"X2\"},{\"t\":3,\"n\":\"Y2\"},{\"t\":3,\"n\":\"Z2\"}]},{\"t\":2,\"n\":\"FULL - Name\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Icon\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"ICON - Large Icon filename\"}]},{\"t\":6,\"n\":\"Destructable\",\"c\":[{\"t\":6,\"n\":\"DEST - Header\",\"c\":[{\"t\":3,\"n\":\"Health\"},{\"t\":3,\"n\":\"DEST Count\"},{\"t\":3,\"n\":\"VATS Targetable\"},{\"t\":11,\"n\":\"Unknown\"}]}]},{\"t\":3,\"n\":\"YNAM - Sound - Pick Up\"},{\"t\":3,\"n\":\"ZNAM - Sound - Drop\"},{\"t\":2,\"n\":\"DESC - Description\"},{\"t\":3,\"n\":\"KSIZ - Keyword Count\"},{\"t\":9,\"n\":\"KWDA - Keywords\",\"c\":[{\"t\":3,\"n\":\"Keyword\"}]},{\"t\":6,\"n\":\"DATA - Data\",\"c\":[{\"t\":3,\"n\":\"Projectile\"},{\"t\":3,\"n\":\"Flags\"},{\"t\":5,\"n\":\"Damage\"},{\"t\":3,\"n\":\"Value\"}]},{\"t\":2,\"n\":\"ONAM - Short Name\"}]},{\"t\":1,\"p\":1,\"n\":\"APPA - Alchemical Apparatus\",\"c\":[{\"t\":6,\"n\":\"Record Header\",\"c\":[{\"t\":2,\"n\":\"Signature\"},{\"t\":3,\"n\":\"Data Size\"},{\"t\":3,\"n\":\"Record Flags\"},{\"t\":3,\"n\":\"FormID\"},{\"t\":11,\"n\":\"Version Control Info 1\"},{\"t\":3,\"n\":\"Form Version\"},{\"t\":11,\"n\":\"Version Control Info 2\"}]},{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"n\":\"VMAD - Virtual Machine Adapter\",\"c\":[{\"t\":3,\"n\":\"Version\"},{\"t\":3,\"n\":\"Object Format\"},{\"t\":12,\"n\":\"Data\",\"c\":[{\"t\":9,\"n\":\"Scripts\",\"c\":[{\"t\":6,\"n\":\"Script\",\"c\":[{\"t\":2,\"n\":\"scriptName\"},{\"t\":3,\"n\":\"Flags\"},{\"t\":9,\"n\":\"Properties\",\"c\":[{\"t\":6,\"n\":\"Property\",\"c\":[{\"t\":2,\"n\":\"propertyName\"},{\"t\":3,\"n\":\"Type\"},{\"t\":3,\"n\":\"Flags\"},{\"t\":12,\"n\":\"Value\"}]}]}]}]}]}]},{\"t\":6,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"n\":\"X1\"},{\"t\":3,\"n\":\"Y1\"},{\"t\":3,\"n\":\"Z1\"},{\"t\":3,\"n\":\"X2\"},{\"t\":3,\"n\":\"Y2\"},{\"t\":3,\"n\":\"Z2\"}]},{\"t\":2,\"n\":\"FULL - Name\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Icon\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"ICON - Large Icon filename\"}]},{\"t\":6,\"n\":\"Destructable\",\"c\":[{\"t\":6,\"n\":\"DEST - Header\",\"c\":[{\"t\":3,\"n\":\"Health\"},{\"t\":3,\"n\":\"DEST Count\"},{\"t\":3,\"n\":\"VATS Targetable\"},{\"t\":11,\"n\":\"Unknown\"}]}]},{\"t\":3,\"n\":\"YNAM - Sound - Pick Up\"},{\"t\":3,\"n\":\"ZNAM - Sound - Drop\"},{\"t\":3,\"n\":\"QUAL - Quality\"},{\"t\":2,\"n\":\"DESC - Description\"},{\"t\":6,\"n\":\"DATA - Data\",\"c\":[{\"t\":3,\"n\":\"Value\"},{\"t\":5,\"n\":\"Weight\"}]}]},{\"t\":1,\"p\":1,\"n\":\"ARMA - Armor Addon\",\"c\":[{\"t\":6,\"n\":\"Record Header\",\"c\":[{\"t\":2,\"n\":\"Signature\"},{\"t\":3,\"n\":\"Data Size\"},{\"t\":3,\"n\":\"Record Flags\"},{\"t\":3,\"n\":\"FormID\"},{\"t\":11,\"n\":\"Version Control Info 1\"},{\"t\":3,\"n\":\"Form Version\"},{\"t\":11,\"n\":\"Version Control Info 2\"}]},{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"n\":\"BOD2 - Biped Body Template\",\"c\":[{\"t\":3,\"n\":\"First Person Flags\"},{\"t\":3,\"n\":\"General Flags\"},{\"n\":\"Unused\"},{\"t\":3,\"n\":\"Armor Type\"}]},{\"t\":3,\"n\":\"RNAM - Race\"},{\"t\":6,\"n\":\"DNAM - Data\",\"c\":[{\"t\":3,\"n\":\"Male Priority\"},{\"t\":3,\"n\":\"Female Priority\"},{\"t\":3,\"n\":\"Weight slider - Male\"},{\"t\":3,\"n\":\"Weight slider - Female\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":3,\"n\":\"Detection Sound Value\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":5,\"n\":\"Weapon Adjust\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Male world model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MOD2 - Model Filename\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Female world model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MOD3 - Model Filename\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Male 1st Person\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MOD4 - Model Filename\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Female 1st Person\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MOD5 - Model Filename\"}]},{\"t\":3,\"n\":\"NAM0 - Male Skin Texture\"},{\"t\":3,\"n\":\"NAM1 - Female Skin texture\"},{\"t\":3,\"n\":\"NAM2 - Male Skin Texture Swap List\"},{\"t\":3,\"n\":\"NAM3 - Female Skin Texture Swap List\"},{\"t\":9,\"n\":\"Additional Races\",\"c\":[{\"t\":3,\"n\":\"MODL - Race\"}]},{\"t\":3,\"n\":\"SNDD - Footstep Sound\"},{\"t\":3,\"n\":\"ONAM - Art Object\"}]},{\"t\":1,\"p\":1,\"n\":\"ARMO - Armor\",\"c\":[{\"t\":6,\"n\":\"Record Header\",\"c\":[{\"t\":2,\"n\":\"Signature\"},{\"t\":3,\"n\":\"Data Size\"},{\"t\":3,\"n\":\"Record Flags\"},{\"t\":3,\"n\":\"FormID\"},{\"t\":11,\"n\":\"Version Control Info 1\"},{\"t\":3,\"n\":\"Form Version\"},{\"t\":11,\"n\":\"Version Control Info 2\"}]},{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"n\":\"VMAD - Virtual Machine Adapter\",\"c\":[{\"t\":3,\"n\":\"Version\"},{\"t\":3,\"n\":\"Object Format\"},{\"t\":12,\"n\":\"Data\",\"c\":[{\"t\":9,\"n\":\"Scripts\",\"c\":[{\"t\":6,\"n\":\"Script\",\"c\":[{\"t\":2,\"n\":\"scriptName\"},{\"t\":3,\"n\":\"Flags\"},{\"t\":9,\"n\":\"Properties\",\"c\":[{\"t\":6,\"n\":\"Property\",\"c\":[{\"t\":2,\"n\":\"propertyName\"},{\"t\":3,\"n\":\"Type\"},{\"t\":3,\"n\":\"Flags\"},{\"t\":12,\"n\":\"Value\"}]}]}]}]}]}]},{\"t\":6,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"n\":\"X1\"},{\"t\":3,\"n\":\"Y1\"},{\"t\":3,\"n\":\"Z1\"},{\"t\":3,\"n\":\"X2\"},{\"t\":3,\"n\":\"Y2\"},{\"t\":3,\"n\":\"Z2\"}]},{\"t\":2,\"n\":\"FULL - Name\"},{\"t\":3,\"n\":\"EITM - Object Effect\"},{\"t\":3,\"n\":\"EAMT - Enchantment Amount\"},{\"t\":6,\"n\":\"Male world model\",\"c\":[{\"t\":2,\"n\":\"MOD2 - Model Filename\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Icon\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"ICON - Large Icon filename\"}]},{\"t\":6,\"n\":\"Female world model\",\"c\":[{\"t\":2,\"n\":\"MOD4 - Model Filename\"}]},{\"t\":6,\"n\":\"Icon 2 (female)\",\"c\":[{\"t\":2,\"n\":\"ICO2 - Large Icon filename\"}]},{\"t\":6,\"n\":\"BOD2 - Biped Body Template\",\"c\":[{\"t\":3,\"n\":\"First Person Flags\"},{\"t\":3,\"n\":\"General Flags\"},{\"n\":\"Unused\"},{\"t\":3,\"n\":\"Armor Type\"}]},{\"t\":6,\"n\":\"Destructable\",\"c\":[{\"t\":6,\"n\":\"DEST - Header\",\"c\":[{\"t\":3,\"n\":\"Health\"},{\"t\":3,\"n\":\"DEST Count\"},{\"t\":3,\"n\":\"VATS Targetable\"},{\"t\":11,\"n\":\"Unknown\"}]}]},{\"t\":3,\"n\":\"YNAM - Sound - Pick Up\"},{\"t\":3,\"n\":\"ZNAM - Sound - Drop\"},{\"t\":2,\"n\":\"BMCT - Ragdoll Constraint Template\"},{\"t\":3,\"n\":\"ETYP - Equipment Type\"},{\"t\":3,\"n\":\"BIDS - Bash Impact Data Set\"},{\"t\":3,\"n\":\"BAMT - Alternate Block Material\"},{\"t\":3,\"n\":\"RNAM - Race\"},{\"t\":3,\"n\":\"KSIZ - Keyword Count\"},{\"t\":9,\"n\":\"KWDA - Keywords\",\"c\":[{\"t\":3,\"n\":\"Keyword\"}]},{\"t\":2,\"n\":\"DESC - Description\"},{\"t\":7,\"p\":1,\"n\":\"Armature\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"MODL - Model Filename\"}]},{\"t\":6,\"n\":\"DATA - Data\",\"c\":[{\"t\":3,\"n\":\"Value\"},{\"t\":5,\"n\":\"Weight\"}]},{\"t\":3,\"n\":\"DNAM - Armor Rating\"},{\"t\":3,\"n\":\"TNAM - Template Armor\"}]},{\"t\":1,\"p\":1,\"n\":\"ARTO - Art Object\",\"c\":[{\"t\":6,\"n\":\"Record Header\",\"c\":[{\"t\":2,\"n\":\"Signature\"},{\"t\":3,\"n\":\"Data Size\"},{\"t\":3,\"n\":\"Record Flags\"},{\"t\":3,\"n\":\"FormID\"},{\"t\":11,\"n\":\"Version Control Info 1\"},{\"t\":3,\"n\":\"Form Version\"},{\"t\":11,\"n\":\"Version Control Info 2\"}]},{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"n\":\"X1\"},{\"t\":3,\"n\":\"Y1\"},{\"t\":3,\"n\":\"Z1\"},{\"t\":3,\"n\":\"X2\"},{\"t\":3,\"n\":\"Y2\"},{\"t\":3,\"n\":\"Z2\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"}]},{\"t\":3,\"n\":\"DNAM - Art Type\"}]},{\"t\":1,\"p\":1,\"n\":\"BOOK - Book\",\"c\":[{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"n\":\"VMAD - Virtual Machine Adapter\",\"c\":[{\"t\":3,\"n\":\"Version\"},{\"t\":3,\"n\":\"Object Format\"},{\"t\":7,\"n\":\"Scripts\",\"c\":[{\"t\":6,\"n\":\"Script\",\"c\":[{\"t\":2,\"n\":\"scriptName\"},{\"t\":3,\"n\":\"Flags\"},{\"t\":7,\"n\":\"Properties\",\"c\":[{\"t\":6,\"n\":\"Property\",\"c\":[{\"t\":2,\"n\":\"propertyName\"},{\"t\":3,\"n\":\"Type\"},{\"t\":3,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":6,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"n\":\"Alias\"},{\"t\":3,\"n\":\"FormID\"}]},{\"t\":6,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"n\":\"FormID\"},{\"t\":3,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]},{\"t\":2,\"n\":\"String\"},{\"t\":3,\"n\":\"Int32\"},{\"t\":5,\"n\":\"Float\"},{\"t\":3,\"n\":\"Bool\"},{\"t\":7,\"n\":\"Array of Object\",\"c\":[{\"t\":6,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"n\":\"Alias\"},{\"t\":3,\"n\":\"FormID\"}]},{\"t\":6,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"n\":\"FormID\"},{\"t\":3,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]}]},{\"t\":7,\"n\":\"Array of String\",\"c\":[{\"t\":2,\"n\":\"Element\"}]},{\"t\":7,\"n\":\"Array of Int32\",\"c\":[{\"t\":3,\"n\":\"Element\"}]},{\"t\":7,\"n\":\"Array of Float\",\"c\":[{\"t\":5,\"n\":\"Element\"}]},{\"t\":7,\"n\":\"Array of Bool\",\"c\":[{\"t\":3,\"n\":\"Element\"}]}]}]}]}]}]},{\"t\":6,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"n\":\"X1\"},{\"t\":3,\"n\":\"Y1\"},{\"t\":3,\"n\":\"Z1\"},{\"t\":3,\"n\":\"X2\"},{\"t\":3,\"n\":\"Y2\"},{\"t\":3,\"n\":\"Z2\"}]},{\"t\":2,\"n\":\"FULL - Name\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"MODT - Texture Files Hashes\"},{\"t\":7,\"p\":1,\"n\":\"MODS - Alternate Textures\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"3D Name\"},{\"t\":3,\"p\":1,\"n\":\"New Texture\"},{\"t\":3,\"p\":1,\"n\":\"3D Index\"}]}]}]},{\"t\":6,\"n\":\"Icon\",\"c\":[{\"t\":2,\"n\":\"ICON - Large Icon filename\"},{\"t\":2,\"n\":\"MICO - Small Icon filename\"}]},{\"t\":2,\"n\":\"DESC - Book Text\"},{\"t\":6,\"n\":\"Destructable\",\"c\":[{\"t\":6,\"n\":\"DEST - Header\",\"c\":[{\"t\":3,\"n\":\"Health\"},{\"t\":3,\"n\":\"DEST Count\"},{\"t\":3,\"n\":\"VATS Targetable\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":8,\"n\":\"Stages\",\"c\":[{\"t\":6,\"n\":\"Stage\",\"c\":[{\"t\":6,\"n\":\"DSTD - Destruction Stage Data\",\"c\":[{\"t\":3,\"n\":\"Health %\"},{\"t\":3,\"n\":\"Index\"},{\"t\":3,\"n\":\"Model Damage Stage\"},{\"t\":3,\"n\":\"Flags\"},{\"t\":3,\"n\":\"Self Damage per Second\"},{\"t\":3,\"n\":\"Explosion\"},{\"t\":3,\"n\":\"Debris\"},{\"t\":3,\"n\":\"Debris Count\"}]},{\"t\":6,\"n\":\"Model\",\"c\":[{\"t\":2,\"n\":\"DMDL - Model Filename\"},{\"t\":11,\"n\":\"DMDT - Texture Files Hashes\"},{\"t\":7,\"n\":\"DMDS - Alternate Textures\",\"c\":[{\"t\":6,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"n\":\"3D Name\"},{\"t\":3,\"n\":\"New Texture\"},{\"t\":3,\"n\":\"3D Index\"}]}]}]},{\"n\":\"DSTF - End Marker\"}]}]}]},{\"t\":3,\"n\":\"YNAM - Sound - Pick Up\"},{\"t\":3,\"n\":\"ZNAM - Sound - Put Down\"},{\"t\":3,\"n\":\"KSIZ - Keyword Count\"},{\"t\":7,\"n\":\"KWDA - Keywords\",\"c\":[{\"t\":3,\"n\":\"Keyword\"}]},{\"t\":6,\"n\":\"DATA - Data\",\"c\":[{\"t\":3,\"n\":\"Flags\"},{\"t\":3,\"n\":\"Type\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":3,\"n\":\"Skill\"},{\"t\":3,\"n\":\"Spell\"},{\"t\":3,\"n\":\"Value\"},{\"t\":5,\"n\":\"Weight\"}]},{\"t\":3,\"p\":1,\"n\":\"INAM - Inventory Art\"},{\"t\":2,\"n\":\"CNAM - Description\"}]},{\"t\":1,\"p\":1,\"n\":\"DEBR - Debris\",\"c\":[{\"t\":6,\"n\":\"Record Header\",\"c\":[{\"t\":2,\"n\":\"Signature\"},{\"t\":3,\"n\":\"Data Size\"},{\"t\":3,\"n\":\"Record Flags\"},{\"t\":3,\"n\":\"FormID\"},{\"t\":11,\"n\":\"Version Control Info 1\"},{\"t\":3,\"n\":\"Form Version\"},{\"t\":11,\"n\":\"Version Control Info 2\"}]},{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":8,\"p\":1,\"n\":\"Models\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"DATA - Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Percentage\"},{\"t\":2,\"p\":1,\"n\":\"Model Filename\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"}]}]}]}]},{\"t\":1,\"p\":1,\"n\":\"DOOR - Door\",\"c\":[{\"t\":6,\"n\":\"Record Header\",\"c\":[{\"t\":2,\"n\":\"Signature\"},{\"t\":3,\"n\":\"Data Size\"},{\"t\":3,\"n\":\"Record Flags\"},{\"t\":3,\"n\":\"FormID\"},{\"t\":11,\"n\":\"Version Control Info 1\"},{\"t\":3,\"n\":\"Form Version\"},{\"t\":11,\"n\":\"Version Control Info 2\"}]},{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"n\":\"VMAD - Virtual Machine Adapter\",\"c\":[{\"t\":3,\"n\":\"Version\"},{\"t\":3,\"n\":\"Object Format\"},{\"t\":12,\"n\":\"Data\",\"c\":[{\"t\":9,\"n\":\"Scripts\",\"c\":[{\"t\":6,\"n\":\"Script\",\"c\":[{\"t\":2,\"n\":\"scriptName\"},{\"t\":3,\"n\":\"Flags\"},{\"t\":9,\"n\":\"Properties\",\"c\":[{\"t\":6,\"n\":\"Property\",\"c\":[{\"t\":2,\"n\":\"propertyName\"},{\"t\":3,\"n\":\"Type\"},{\"t\":3,\"n\":\"Flags\"},{\"t\":12,\"n\":\"Value\"}]}]}]}]}]}]},{\"t\":6,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"n\":\"X1\"},{\"t\":3,\"n\":\"Y1\"},{\"t\":3,\"n\":\"Z1\"},{\"t\":3,\"n\":\"X2\"},{\"t\":3,\"n\":\"Y2\"},{\"t\":3,\"n\":\"Z2\"}]},{\"t\":2,\"n\":\"FULL - Name\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"}]},{\"t\":6,\"n\":\"Destructable\",\"c\":[{\"t\":6,\"n\":\"DEST - Header\",\"c\":[{\"t\":3,\"n\":\"Health\"},{\"t\":3,\"n\":\"DEST Count\"},{\"t\":3,\"n\":\"VATS Targetable\"},{\"t\":11,\"n\":\"Unknown\"}]}]},{\"t\":3,\"n\":\"SNAM - Sound - Open\"},{\"t\":3,\"n\":\"ANAM - Sound - Close\"},{\"t\":3,\"n\":\"BNAM - Sound - Loop\"},{\"t\":3,\"n\":\"FNAM - Flags\"}]},{\"t\":1,\"p\":1,\"n\":\"EFSH - Effect Shader\",\"c\":[{\"t\":6,\"n\":\"Record Header\",\"c\":[{\"t\":2,\"n\":\"Signature\"},{\"t\":3,\"n\":\"Data Size\"},{\"t\":3,\"n\":\"Record Flags\"},{\"t\":3,\"n\":\"FormID\"},{\"t\":11,\"n\":\"Version Control Info 1\"},{\"t\":3,\"n\":\"Form Version\"},{\"t\":11,\"n\":\"Version Control Info 2\"}]},{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"p\":1,\"n\":\"ICON - Fill Texture\",\"lt\":\"ICO2 - Particle Shader Texture\",\"lf\":\"DATA - \"},{\"t\":2,\"p\":1,\"n\":\"ICO2 - Particle Shader Texture\",\"lt\":\"NAM7 - Holes Texture\",\"lf\":\"ICON - Fill Texture\"},{\"t\":2,\"p\":1,\"n\":\"NAM7 - Holes Texture\",\"lt\":\"NAM8 - Membrane Palette Texture\",\"lf\":\"ICO2 - Particle Shader Texture\"},{\"t\":2,\"p\":1,\"n\":\"NAM8 - Membrane Palette Texture\",\"lt\":\"NAM9 - Particle Palette Texture\",\"lf\":\"NAM7 - Holes Texture\"},{\"t\":2,\"p\":1,\"n\":\"NAM9 - Particle Palette Texture\",\"lt\":\"DATA - \",\"lf\":\"NAM8 - Membrane Palette Texture\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DATA - \",\"c\":[{\"t\":11,\"p\":1,\"n\":\"Unknown\"},{\"t\":3,\"p\":1,\"n\":\"Membrane Shader - Source Blend Mode\"},{\"t\":3,\"p\":1,\"n\":\"Membrane Shader - Blend Operation\"},{\"t\":3,\"p\":1,\"n\":\"Membrane Shader - Z Test Function\"},{\"t\":6,\"p\":1,\"n\":\"Fill\\/Texture Effect - Color Key 1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"p\":1,\"n\":\"Unknown\"}]},{\"t\":5,\"p\":1,\"n\":\"Fill\\/Texture Effect - Alpha Fade In Time\"},{\"t\":5,\"p\":1,\"n\":\"Fill\\/Texture Effect - Full Alpha Time\"},{\"t\":5,\"p\":1,\"n\":\"Fill\\/Texture Effect - Alpha Fade Out Time\"},{\"t\":5,\"p\":1,\"n\":\"Fill\\/Texture Effect - Presistent Alpha Ratio\"},{\"t\":5,\"p\":1,\"n\":\"Fill\\/Texture Effect - Alpha Pulse Amplitude\"},{\"t\":5,\"p\":1,\"n\":\"Fill\\/Texture Effect - Alpha Pulse Frequency\"},{\"t\":5,\"p\":1,\"n\":\"Fill\\/Texture Effect - Texture Animation Speed (U)\"},{\"t\":5,\"p\":1,\"n\":\"Fill\\/Texture Effect - Texture Animation Speed (V)\"},{\"t\":5,\"p\":1,\"n\":\"Edge Effect - Fall Off\"},{\"t\":6,\"p\":1,\"n\":\"Edge Effect - Color\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"p\":1,\"n\":\"Unknown\"}]},{\"t\":5,\"p\":1,\"n\":\"Edge Effect - Alpha Fade In Time\"},{\"t\":5,\"p\":1,\"n\":\"Edge Effect - Full Alpha Time\"},{\"t\":5,\"p\":1,\"n\":\"Edge Effect - Alpha Fade Out Time\"},{\"t\":5,\"p\":1,\"n\":\"Edge Effect - Persistent Alpha Ratio\"},{\"t\":5,\"p\":1,\"n\":\"Edge Effect - Alpha Pulse Amplitude\"},{\"t\":5,\"p\":1,\"n\":\"Edge Effect - Alpha Pulse Frequency\"},{\"t\":5,\"p\":1,\"n\":\"Fill\\/Texture Effect - Full Alpha Ratio\"},{\"t\":5,\"p\":1,\"n\":\"Edge Effect - Full Alpha Ratio\"},{\"t\":3,\"p\":1,\"n\":\"Membrane Shader - Dest Blend Mode\"},{\"t\":3,\"p\":1,\"n\":\"Particle Shader - Source Blend Mode\"},{\"t\":3,\"p\":1,\"n\":\"Particle Shader - Blend Operation\"},{\"t\":3,\"p\":1,\"n\":\"Particle Shader - Z Test Function\"},{\"t\":3,\"p\":1,\"n\":\"Particle Shader - Dest Blend Mode\"},{\"t\":5,\"p\":1,\"n\":\"Particle Shader - Particle Birth Ramp Up Time\"},{\"t\":5,\"p\":1,\"n\":\"Particle Shader - Full Particle Birth Time\"},{\"t\":5,\"p\":1,\"n\":\"Particle Shader - Particle Birth Ramp Down Time\"},{\"t\":5,\"p\":1,\"n\":\"Particle Shader - Full Particle Birth Ratio\"},{\"t\":5,\"p\":1,\"n\":\"Particle Shader - Persistant Particle Count\"},{\"t\":5,\"p\":1,\"n\":\"Particle Shader - Particle Lifetime\"},{\"t\":5,\"p\":1,\"n\":\"Particle Shader - Particle Lifetime +\\/-\"},{\"t\":5,\"p\":1,\"n\":\"Particle Shader - Initial Speed Along Normal\"},{\"t\":5,\"p\":1,\"n\":\"Particle Shader - Acceleration Along Normal\"},{\"t\":5,\"p\":1,\"n\":\"Particle Shader - Initial Velocity #1\"},{\"t\":5,\"p\":1,\"n\":\"Particle Shader - Initial Velocity #2\"},{\"t\":5,\"p\":1,\"n\":\"Particle Shader - Initial Velocity #3\"},{\"t\":5,\"p\":1,\"n\":\"Particle Shader - Acceleration #1\"},{\"t\":5,\"p\":1,\"n\":\"Particle Shader - Acceleration #2\"},{\"t\":5,\"p\":1,\"n\":\"Particle Shader - Acceleration #3\"},{\"t\":5,\"p\":1,\"n\":\"Particle Shader - Scale Key 1\"},{\"t\":5,\"p\":1,\"n\":\"Particle Shader - Scale Key 2\"},{\"t\":5,\"p\":1,\"n\":\"Particle Shader - Scale Key 1 Time\"},{\"t\":5,\"p\":1,\"n\":\"Particle Shader - Scale Key 2 Time\"},{\"t\":6,\"p\":1,\"n\":\"Color Key 1 - Color\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"p\":1,\"n\":\"Unknown\"}]},{\"t\":6,\"p\":1,\"n\":\"Color Key 2 - Color\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"p\":1,\"n\":\"Unknown\"}]},{\"t\":6,\"p\":1,\"n\":\"Color Key 3 - Color\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"p\":1,\"n\":\"Unknown\"}]},{\"t\":5,\"p\":1,\"n\":\"Color Key 1 - Color Alpha\"},{\"t\":5,\"p\":1,\"n\":\"Color Key 2 - Color Alpha\"},{\"t\":5,\"p\":1,\"n\":\"Color Key 3 - Color Alpha\"},{\"t\":5,\"p\":1,\"n\":\"Color Key 1 - Color Key Time\"},{\"t\":5,\"p\":1,\"n\":\"Color Key 2 - Color Key Time\"},{\"t\":5,\"p\":1,\"n\":\"Color Key 3 - Color Key Time\"},{\"t\":5,\"p\":1,\"n\":\"Particle Shader - Initial Speed Along Normal +\\/-\"},{\"t\":5,\"p\":1,\"n\":\"Particle Shader - Initial Rotation (deg)\"},{\"t\":5,\"p\":1,\"n\":\"Particle Shader - Initial Rotation (deg) +\\/-\"},{\"t\":5,\"p\":1,\"n\":\"Particle Shader - Rotation Speed (deg\\/sec)\"},{\"t\":5,\"p\":1,\"n\":\"Particle Shader - Rotation Speed (deg\\/sec) +\\/-\"},{\"t\":3,\"p\":1,\"n\":\"Addon Models\"},{\"t\":5,\"p\":1,\"n\":\"Holes - Start Time\"},{\"t\":5,\"p\":1,\"n\":\"Holes - End Time\"},{\"t\":5,\"p\":1,\"n\":\"Holes - Start Val\"},{\"t\":5,\"p\":1,\"n\":\"Holes - End Val\"},{\"t\":5,\"p\":1,\"n\":\"Edge Width (alpha units)\"},{\"t\":6,\"p\":1,\"n\":\"Edge Color\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"p\":1,\"n\":\"Unknown\"}]},{\"t\":5,\"p\":1,\"n\":\"Explosion Wind Speed\"},{\"t\":3,\"p\":1,\"n\":\"Texture Count U\"},{\"t\":3,\"p\":1,\"n\":\"Texture Count V\"},{\"t\":5,\"p\":1,\"n\":\"Addon Models - Fade In Time\"},{\"t\":5,\"p\":1,\"n\":\"Addon Models - Fade Out Time\"},{\"t\":5,\"p\":1,\"n\":\"Addon Models - Scale Start\"},{\"t\":5,\"p\":1,\"n\":\"Addon Models - Scale End\"},{\"t\":5,\"p\":1,\"n\":\"Addon Models - Scale In Time\"},{\"t\":5,\"p\":1,\"n\":\"Addon Models - Scale Out Time\"},{\"t\":3,\"p\":1,\"n\":\"Ambient Sound\"},{\"t\":6,\"p\":1,\"n\":\"Fill\\/Texture Effect - Color Key 2\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"p\":1,\"n\":\"Unknown\"}]},{\"t\":6,\"p\":1,\"n\":\"Fill\\/Texture Effect - Color Key 3\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"p\":1,\"n\":\"Unknown\"}]},{\"t\":6,\"p\":1,\"n\":\"Fill\\/Texture Effect - Color Key Scale\\/Time\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Color Key 1 - Scale\"},{\"t\":5,\"p\":1,\"n\":\"Color Key 2 - Scale\"},{\"t\":5,\"p\":1,\"n\":\"Color Key 3 - Scale\"},{\"t\":5,\"p\":1,\"n\":\"Color Key 1 - Time\"},{\"t\":5,\"p\":1,\"n\":\"Color Key 2 - Time\"},{\"t\":5,\"p\":1,\"n\":\"Color Key 3 - Time\"}]},{\"t\":5,\"p\":1,\"n\":\"Color Scale\"},{\"t\":5,\"p\":1,\"n\":\"Birth Position Offset\"},{\"t\":5,\"p\":1,\"n\":\"Birth Position Offset Range +\\/-\"},{\"t\":6,\"p\":1,\"n\":\"Particle Shader Animated\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Start Frame\"},{\"t\":3,\"p\":1,\"n\":\"Start Frame Variation\"},{\"t\":3,\"p\":1,\"n\":\"End Frame\"},{\"t\":3,\"p\":1,\"n\":\"Loop Start Frame\"},{\"t\":3,\"p\":1,\"n\":\"Loop Start Variation\"},{\"t\":3,\"p\":1,\"n\":\"Frame Count\"},{\"t\":3,\"p\":1,\"n\":\"Frame Count Variation\"}]},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":5,\"p\":1,\"n\":\"Fill\\/Texture Effect - Texture Scale (U)\"},{\"t\":5,\"p\":1,\"n\":\"Fill\\/Texture Effect - Texture Scale (V)\"},{\"t\":3,\"p\":1,\"n\":\"Scene Graph Emit Depth Limit (unused)\"}],\"lt\":\"ICON - Fill Texture\",\"lf\":\"NAM9 - Particle Palette Texture\"}]},{\"t\":1,\"p\":1,\"n\":\"EXPL - Explosion\",\"c\":[{\"t\":6,\"n\":\"Record Header\",\"c\":[{\"t\":2,\"n\":\"Signature\"},{\"t\":3,\"n\":\"Data Size\"},{\"t\":3,\"n\":\"Record Flags\"},{\"t\":3,\"n\":\"FormID\"},{\"t\":11,\"n\":\"Version Control Info 1\"},{\"t\":3,\"n\":\"Form Version\"},{\"t\":11,\"n\":\"Version Control Info 2\"}]},{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"n\":\"X1\"},{\"t\":3,\"n\":\"Y1\"},{\"t\":3,\"n\":\"Z1\"},{\"t\":3,\"n\":\"X2\"},{\"t\":3,\"n\":\"Y2\"},{\"t\":3,\"n\":\"Z2\"}]},{\"t\":2,\"n\":\"FULL - Name\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"}]},{\"t\":3,\"n\":\"EITM - Object Effect\"},{\"t\":3,\"n\":\"MNAM - Image Space Modifier\"},{\"t\":6,\"n\":\"DATA - Data\",\"c\":[{\"t\":3,\"n\":\"Light\"},{\"t\":3,\"n\":\"Sound 1\"},{\"t\":3,\"n\":\"Sound 2\"},{\"t\":3,\"n\":\"Impact Data Set\"},{\"t\":3,\"n\":\"Placed Object\"},{\"t\":3,\"n\":\"Spawn Projectile\"},{\"t\":5,\"n\":\"Force\"},{\"t\":5,\"n\":\"Damage\"},{\"t\":5,\"n\":\"Radius\"},{\"t\":5,\"n\":\"IS Radius\"},{\"t\":5,\"n\":\"Vertical Offset Mult\"},{\"t\":3,\"n\":\"Flags\"},{\"t\":3,\"n\":\"Sound Level\"}]}]},{\"t\":1,\"p\":1,\"n\":\"FLOR - Flora\",\"c\":[{\"t\":6,\"n\":\"Record Header\",\"c\":[{\"t\":2,\"n\":\"Signature\"},{\"t\":3,\"n\":\"Data Size\"},{\"t\":3,\"n\":\"Record Flags\"},{\"t\":3,\"n\":\"FormID\"},{\"t\":11,\"n\":\"Version Control Info 1\"},{\"t\":3,\"n\":\"Form Version\"},{\"t\":11,\"n\":\"Version Control Info 2\"}]},{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"n\":\"VMAD - Virtual Machine Adapter\",\"c\":[{\"t\":3,\"n\":\"Version\"},{\"t\":3,\"n\":\"Object Format\"},{\"t\":12,\"n\":\"Data\",\"c\":[{\"t\":9,\"n\":\"Scripts\",\"c\":[{\"t\":6,\"n\":\"Script\",\"c\":[{\"t\":2,\"n\":\"scriptName\"},{\"t\":3,\"n\":\"Flags\"},{\"t\":9,\"n\":\"Properties\",\"c\":[{\"t\":6,\"n\":\"Property\",\"c\":[{\"t\":2,\"n\":\"propertyName\"},{\"t\":3,\"n\":\"Type\"},{\"t\":3,\"n\":\"Flags\"},{\"t\":12,\"n\":\"Value\"}]}]}]}]}]}]},{\"t\":6,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"n\":\"X1\"},{\"t\":3,\"n\":\"Y1\"},{\"t\":3,\"n\":\"Z1\"},{\"t\":3,\"n\":\"X2\"},{\"t\":3,\"n\":\"Y2\"},{\"t\":3,\"n\":\"Z2\"}]},{\"t\":2,\"n\":\"FULL - Name\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"}]},{\"t\":6,\"n\":\"Destructable\",\"c\":[{\"t\":6,\"n\":\"DEST - Header\",\"c\":[{\"t\":3,\"n\":\"Health\"},{\"t\":3,\"n\":\"DEST Count\"},{\"t\":3,\"n\":\"VATS Targetable\"},{\"t\":11,\"n\":\"Unknown\"}]}]},{\"t\":3,\"n\":\"KSIZ - Keyword Count\"},{\"t\":9,\"n\":\"KWDA - Keywords\",\"c\":[{\"t\":3,\"n\":\"Keyword\"}]},{\"t\":11,\"n\":\"PNAM - Unknown\"},{\"t\":2,\"n\":\"RNAM - Activate Text Override\"},{\"t\":11,\"n\":\"FNAM - Unknown\"},{\"t\":3,\"n\":\"PFIG - Ingredient\"},{\"t\":3,\"n\":\"SNAM - Sound\"},{\"t\":6,\"n\":\"PFPC - Seasonal ingredient production\",\"c\":[{\"t\":3,\"n\":\"Spring\"},{\"t\":3,\"n\":\"Summer \"},{\"t\":3,\"n\":\"Fall\"},{\"t\":3,\"n\":\"Winter\"}]}]},{\"t\":1,\"p\":1,\"n\":\"FURN - Furniture\",\"c\":[{\"t\":6,\"n\":\"Record Header\",\"c\":[{\"t\":2,\"n\":\"Signature\"},{\"t\":3,\"n\":\"Data Size\"},{\"t\":3,\"n\":\"Record Flags\"},{\"t\":3,\"n\":\"FormID\"},{\"t\":11,\"n\":\"Version Control Info 1\"},{\"t\":3,\"n\":\"Form Version\"},{\"t\":11,\"n\":\"Version Control Info 2\"}]},{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"n\":\"VMAD - Virtual Machine Adapter\",\"c\":[{\"t\":3,\"n\":\"Version\"},{\"t\":3,\"n\":\"Object Format\"},{\"t\":12,\"n\":\"Data\",\"c\":[{\"t\":9,\"n\":\"Scripts\",\"c\":[{\"t\":6,\"n\":\"Script\",\"c\":[{\"t\":2,\"n\":\"scriptName\"},{\"t\":3,\"n\":\"Flags\"},{\"t\":9,\"n\":\"Properties\",\"c\":[{\"t\":6,\"n\":\"Property\",\"c\":[{\"t\":2,\"n\":\"propertyName\"},{\"t\":3,\"n\":\"Type\"},{\"t\":3,\"n\":\"Flags\"},{\"t\":12,\"n\":\"Value\"}]}]}]}]}]}]},{\"t\":6,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"n\":\"X1\"},{\"t\":3,\"n\":\"Y1\"},{\"t\":3,\"n\":\"Z1\"},{\"t\":3,\"n\":\"X2\"},{\"t\":3,\"n\":\"Y2\"},{\"t\":3,\"n\":\"Z2\"}]},{\"t\":2,\"n\":\"FULL - Name\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"}]},{\"t\":6,\"n\":\"Destructable\",\"c\":[{\"t\":6,\"n\":\"DEST - Header\",\"c\":[{\"t\":3,\"n\":\"Health\"},{\"t\":3,\"n\":\"DEST Count\"},{\"t\":3,\"n\":\"VATS Targetable\"},{\"t\":11,\"n\":\"Unknown\"}]}]},{\"t\":3,\"n\":\"KSIZ - Keyword Count\"},{\"t\":9,\"n\":\"KWDA - Keywords\",\"c\":[{\"t\":3,\"n\":\"Keyword\"}]},{\"t\":11,\"n\":\"PNAM - Unknown\"},{\"t\":3,\"n\":\"FNAM - Flags\"},{\"t\":3,\"n\":\"KNAM - Interaction Keyword\"},{\"t\":3,\"n\":\"MNAM - Active Markers \\/ Flags\"},{\"t\":6,\"n\":\"WBDT - Workbench Data\",\"c\":[{\"t\":3,\"n\":\"Bench Type\"},{\"t\":3,\"n\":\"Uses Skill\"}]},{\"t\":3,\"n\":\"NAM1 - Associated Spell\"},{\"t\":8,\"n\":\"Markers\",\"c\":[{\"t\":6,\"n\":\"Marker\",\"c\":[{\"t\":3,\"n\":\"ENAM - Marker Index\"}]}]},{\"t\":8,\"n\":\"Marker Entry Points\",\"c\":[{\"t\":6,\"n\":\"FNPR - Marker\",\"c\":[{\"t\":3,\"n\":\"Type\"},{\"t\":3,\"n\":\"Entry Points\"}]}]},{\"t\":2,\"n\":\"XMRK - Model Filename\"}]},{\"t\":1,\"p\":1,\"n\":\"GRAS - Grass\",\"c\":[{\"t\":6,\"n\":\"Record Header\",\"c\":[{\"t\":2,\"n\":\"Signature\"},{\"t\":3,\"n\":\"Data Size\"},{\"t\":3,\"n\":\"Record Flags\"},{\"t\":3,\"n\":\"FormID\"},{\"t\":11,\"n\":\"Version Control Info 1\"},{\"t\":3,\"n\":\"Form Version\"},{\"t\":11,\"n\":\"Version Control Info 2\"}]},{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"n\":\"X1\"},{\"t\":3,\"n\":\"Y1\"},{\"t\":3,\"n\":\"Z1\"},{\"t\":3,\"n\":\"X2\"},{\"t\":3,\"n\":\"Y2\"},{\"t\":3,\"n\":\"Z2\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"}]},{\"t\":6,\"n\":\"DATA - \",\"c\":[{\"t\":3,\"n\":\"Density\"},{\"t\":3,\"n\":\"Min Slope\"},{\"t\":3,\"n\":\"Max Slope\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":3,\"n\":\"Units From Water\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":3,\"n\":\"Units From Water Type\"},{\"t\":5,\"n\":\"Position Range\"},{\"t\":5,\"n\":\"Height Range\"},{\"t\":5,\"n\":\"Color Range\"},{\"t\":5,\"n\":\"Wave Period\"},{\"t\":3,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unknown\"}]}]},{\"t\":1,\"p\":1,\"n\":\"INGR - Ingredient\",\"c\":[{\"t\":6,\"n\":\"Record Header\",\"c\":[{\"t\":2,\"n\":\"Signature\"},{\"t\":3,\"n\":\"Data Size\"},{\"t\":3,\"n\":\"Record Flags\"},{\"t\":3,\"n\":\"FormID\"},{\"t\":11,\"n\":\"Version Control Info 1\"},{\"t\":3,\"n\":\"Form Version\"},{\"t\":11,\"n\":\"Version Control Info 2\"}]},{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"n\":\"VMAD - Virtual Machine Adapter\",\"c\":[{\"t\":3,\"n\":\"Version\"},{\"t\":3,\"n\":\"Object Format\"},{\"t\":12,\"n\":\"Data\",\"c\":[{\"t\":9,\"n\":\"Scripts\",\"c\":[{\"t\":6,\"n\":\"Script\",\"c\":[{\"t\":2,\"n\":\"scriptName\"},{\"t\":3,\"n\":\"Flags\"},{\"t\":9,\"n\":\"Properties\",\"c\":[{\"t\":6,\"n\":\"Property\",\"c\":[{\"t\":2,\"n\":\"propertyName\"},{\"t\":3,\"n\":\"Type\"},{\"t\":3,\"n\":\"Flags\"},{\"t\":12,\"n\":\"Value\"}]}]}]}]}]}]},{\"t\":6,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"n\":\"X1\"},{\"t\":3,\"n\":\"Y1\"},{\"t\":3,\"n\":\"Z1\"},{\"t\":3,\"n\":\"X2\"},{\"t\":3,\"n\":\"Y2\"},{\"t\":3,\"n\":\"Z2\"}]},{\"t\":2,\"n\":\"FULL - Name\"},{\"t\":3,\"n\":\"KSIZ - Keyword Count\"},{\"t\":9,\"n\":\"KWDA - Keywords\",\"c\":[{\"t\":3,\"n\":\"Keyword\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Icon\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"ICON - Large Icon filename\"}]},{\"t\":6,\"n\":\"Destructable\",\"c\":[{\"t\":6,\"n\":\"DEST - Header\",\"c\":[{\"t\":3,\"n\":\"Health\"},{\"t\":3,\"n\":\"DEST Count\"},{\"t\":3,\"n\":\"VATS Targetable\"},{\"t\":11,\"n\":\"Unknown\"}]}]},{\"t\":3,\"n\":\"ETYP - Equipment Type\"},{\"t\":3,\"n\":\"YNAM - Sound - Pick Up\"},{\"t\":3,\"n\":\"ZNAM - Sound - Drop\"},{\"t\":6,\"n\":\"DATA - \",\"c\":[{\"t\":3,\"n\":\"Value\"},{\"t\":5,\"n\":\"Weight\"}]},{\"t\":6,\"n\":\"ENIT - Effect Data\",\"c\":[{\"t\":3,\"n\":\"Ingredient Value\"},{\"t\":3,\"n\":\"Flags\"}]},{\"t\":8,\"n\":\"Effects\",\"c\":[{\"t\":6,\"n\":\"Effect\",\"c\":[{\"t\":3,\"n\":\"EFID - Base Effect\"},{\"t\":6,\"n\":\"EFIT - \",\"c\":[{\"t\":5,\"n\":\"Magnitude\"},{\"t\":3,\"n\":\"Area\"},{\"t\":3,\"n\":\"Duration\"}]}]}]}]},{\"t\":1,\"p\":1,\"n\":\"LIGH - Light\",\"c\":[{\"t\":6,\"n\":\"Record Header\",\"c\":[{\"t\":2,\"n\":\"Signature\"},{\"t\":3,\"n\":\"Data Size\"},{\"t\":3,\"n\":\"Record Flags\"},{\"t\":3,\"n\":\"FormID\"},{\"t\":11,\"n\":\"Version Control Info 1\"},{\"t\":3,\"n\":\"Form Version\"},{\"t\":11,\"n\":\"Version Control Info 2\"}]},{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"n\":\"VMAD - Virtual Machine Adapter\",\"c\":[{\"t\":3,\"n\":\"Version\"},{\"t\":3,\"n\":\"Object Format\"},{\"t\":12,\"n\":\"Data\",\"c\":[{\"t\":9,\"n\":\"Scripts\",\"c\":[{\"t\":6,\"n\":\"Script\",\"c\":[{\"t\":2,\"n\":\"scriptName\"},{\"t\":3,\"n\":\"Flags\"},{\"t\":9,\"n\":\"Properties\",\"c\":[{\"t\":6,\"n\":\"Property\",\"c\":[{\"t\":2,\"n\":\"propertyName\"},{\"t\":3,\"n\":\"Type\"},{\"t\":3,\"n\":\"Flags\"},{\"t\":12,\"n\":\"Value\"}]}]}]}]}]}]},{\"t\":6,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"n\":\"X1\"},{\"t\":3,\"n\":\"Y1\"},{\"t\":3,\"n\":\"Z1\"},{\"t\":3,\"n\":\"X2\"},{\"t\":3,\"n\":\"Y2\"},{\"t\":3,\"n\":\"Z2\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"}]},{\"t\":6,\"n\":\"Destructable\",\"c\":[{\"t\":6,\"n\":\"DEST - Header\",\"c\":[{\"t\":3,\"n\":\"Health\"},{\"t\":3,\"n\":\"DEST Count\"},{\"t\":3,\"n\":\"VATS Targetable\"},{\"t\":11,\"n\":\"Unknown\"}]}]},{\"t\":2,\"n\":\"FULL - Name\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Icon\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"ICON - Large Icon filename\"}]},{\"t\":6,\"n\":\"DATA - \",\"c\":[{\"t\":3,\"n\":\"Time\"},{\"t\":3,\"n\":\"Radius\"},{\"t\":6,\"n\":\"Color\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":3,\"n\":\"Unknown\"}]},{\"t\":3,\"n\":\"Flags\"},{\"t\":5,\"n\":\"Falloff Exponent\"},{\"t\":5,\"n\":\"FOV\"},{\"t\":5,\"n\":\"Near Clip\"},{\"t\":6,\"n\":\"Flicker Effect\",\"c\":[{\"t\":5,\"n\":\"Period\"},{\"t\":5,\"n\":\"Intensity Amplitude\"},{\"t\":5,\"n\":\"Movement Amplitude\"}]},{\"t\":3,\"n\":\"Value\"},{\"t\":5,\"n\":\"Weight\"}]},{\"t\":5,\"n\":\"FNAM - Fade value\"},{\"t\":3,\"n\":\"SNAM - Sound\"}]},{\"t\":1,\"p\":1,\"n\":\"LSCR - Load Screen\",\"c\":[{\"t\":6,\"n\":\"Record Header\",\"c\":[{\"t\":2,\"n\":\"Signature\"},{\"t\":3,\"n\":\"Data Size\"},{\"t\":3,\"n\":\"Record Flags\"},{\"t\":3,\"n\":\"FormID\"},{\"t\":11,\"n\":\"Version Control Info 1\"},{\"t\":3,\"n\":\"Form Version\"},{\"t\":11,\"n\":\"Version Control Info 2\"}]},{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Icon\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"ICON - Large Icon filename\"}]},{\"t\":2,\"n\":\"DESC - Description\"},{\"t\":8,\"n\":\"Conditions\",\"c\":[{\"t\":6,\"n\":\"Condition\",\"c\":[{\"t\":6,\"n\":\"CTDA - \",\"c\":[{\"t\":3,\"n\":\"Type\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":12,\"n\":\"Comparison Value\"},{\"t\":3,\"n\":\"Function\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":12,\"n\":\"Parameter #1\"},{\"t\":12,\"n\":\"Parameter #2\"},{\"t\":3,\"n\":\"Run On\"},{\"t\":12,\"n\":\"Reference\"},{\"t\":3,\"n\":\"Parameter #3\"}]}]}]},{\"t\":3,\"n\":\"NNAM - Loading Screen NIF\"},{\"t\":5,\"n\":\"SNAM - Initial Scale\"},{\"t\":6,\"n\":\"RNAM - Initial Rotation\",\"c\":[{\"t\":3,\"n\":\"X\"},{\"t\":3,\"n\":\"Y\"},{\"t\":3,\"n\":\"Z\"}]},{\"t\":6,\"n\":\"ONAM - Rotation Offset Constraints\",\"c\":[{\"t\":3,\"n\":\"Min\"},{\"t\":3,\"n\":\"Max\"}]},{\"t\":6,\"n\":\"XNAM - Initial Translation Offset\",\"c\":[{\"t\":5,\"n\":\"X\"},{\"t\":5,\"n\":\"Y\"},{\"t\":5,\"n\":\"Z\"}]},{\"t\":2,\"n\":\"MOD2 - Camera Path\"}]},{\"t\":1,\"p\":1,\"n\":\"MGEF - Magic Effect\",\"c\":[{\"t\":6,\"n\":\"Record Header\",\"c\":[{\"t\":2,\"n\":\"Signature\"},{\"t\":3,\"n\":\"Data Size\"},{\"t\":3,\"n\":\"Record Flags\"},{\"t\":3,\"n\":\"FormID\"},{\"t\":11,\"n\":\"Version Control Info 1\"},{\"t\":3,\"n\":\"Form Version\"},{\"t\":11,\"n\":\"Version Control Info 2\"}]},{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"n\":\"VMAD - Virtual Machine Adapter\",\"c\":[{\"t\":3,\"n\":\"Version\"},{\"t\":3,\"n\":\"Object Format\"},{\"t\":12,\"n\":\"Data\",\"c\":[{\"t\":9,\"n\":\"Scripts\",\"c\":[{\"t\":6,\"n\":\"Script\",\"c\":[{\"t\":2,\"n\":\"scriptName\"},{\"t\":3,\"n\":\"Flags\"},{\"t\":9,\"n\":\"Properties\",\"c\":[{\"t\":6,\"n\":\"Property\",\"c\":[{\"t\":2,\"n\":\"propertyName\"},{\"t\":3,\"n\":\"Type\"},{\"t\":3,\"n\":\"Flags\"},{\"t\":12,\"n\":\"Value\"}]}]}]}]}]}]},{\"t\":2,\"n\":\"FULL - Name\"},{\"t\":3,\"p\":1,\"n\":\"MDOB - Menu Display Object\"},{\"t\":3,\"n\":\"KSIZ - Keyword Count\"},{\"t\":9,\"n\":\"KWDA - Keywords\",\"c\":[{\"t\":3,\"n\":\"Keyword\"}]},{\"t\":6,\"n\":\"Magic Effect Data\",\"c\":[{\"t\":6,\"n\":\"DATA - Data\",\"c\":[{\"t\":3,\"n\":\"Flags\"},{\"t\":5,\"n\":\"Base Cost\"},{\"t\":12,\"n\":\"Assoc. Item\"},{\"t\":3,\"n\":\"Magic Skill\"},{\"t\":3,\"n\":\"Resist Value\"},{\"t\":3,\"n\":\"Counter Effect count\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":3,\"n\":\"Casting Light\"},{\"t\":5,\"n\":\"Taper Weight\"},{\"t\":3,\"n\":\"Hit Shader\"},{\"t\":3,\"n\":\"Enchant Shader\"},{\"t\":3,\"n\":\"Minimum Skill Level\"},{\"t\":6,\"n\":\"Spellmaking\",\"c\":[{\"t\":3,\"n\":\"Area\"},{\"t\":5,\"n\":\"Casting Time\"}]},{\"t\":5,\"n\":\"Taper Curve\"},{\"t\":5,\"n\":\"Taper Duration\"},{\"t\":5,\"n\":\"Second AV Weight\"},{\"t\":3,\"n\":\"Archtype\"},{\"t\":3,\"n\":\"Actor Value\"},{\"t\":3,\"n\":\"Projectile\"},{\"t\":3,\"n\":\"Explosion\"},{\"t\":3,\"n\":\"Casting Type\"},{\"t\":3,\"n\":\"Delivery\"},{\"t\":3,\"n\":\"Second Actor Value\"},{\"t\":3,\"n\":\"Casting Art\"},{\"t\":3,\"n\":\"Hit Effect Art\"},{\"t\":3,\"n\":\"Impact Data\"},{\"t\":5,\"n\":\"Skill Usage Multiplier\"},{\"t\":6,\"n\":\"Dual Casting\",\"c\":[{\"t\":3,\"n\":\"Art\"},{\"t\":5,\"n\":\"Scale\"}]},{\"t\":3,\"n\":\"Enchant Art\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":3,\"n\":\"Equip Ability\"},{\"t\":3,\"n\":\"Image Space Modifier\"},{\"t\":3,\"n\":\"Perk to Apply\"},{\"t\":3,\"n\":\"Casting Sound Level\"},{\"t\":6,\"n\":\"Script Effect AI\",\"c\":[{\"t\":5,\"n\":\"Score\"},{\"t\":5,\"n\":\"Delay Time\"}]}]}]},{\"t\":9,\"n\":\"Counter Effects\",\"c\":[{\"t\":3,\"n\":\"ESCE - Effect\"}]},{\"t\":8,\"n\":\"SNDD - Sounds\",\"c\":[{\"t\":6,\"n\":\" #0\",\"c\":[{\"t\":3,\"n\":\"Type\"},{\"t\":3,\"n\":\"Sound\"}]}]},{\"t\":2,\"n\":\"DNAM - Magic Item Description\"},{\"t\":8,\"n\":\"Conditions\",\"c\":[{\"t\":6,\"n\":\"Condition\",\"c\":[{\"t\":6,\"n\":\"CTDA - \",\"c\":[{\"t\":3,\"n\":\"Type\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":12,\"n\":\"Comparison Value\"},{\"t\":3,\"n\":\"Function\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":12,\"n\":\"Parameter #1\"},{\"t\":12,\"n\":\"Parameter #2\"},{\"t\":3,\"n\":\"Run On\"},{\"t\":12,\"n\":\"Reference\"},{\"t\":3,\"n\":\"Parameter #3\"}]}]}]}]},{\"t\":1,\"p\":1,\"n\":\"MISC - Misc. Item\",\"c\":[{\"t\":6,\"n\":\"Record Header\",\"c\":[{\"t\":2,\"n\":\"Signature\"},{\"t\":3,\"n\":\"Data Size\"},{\"t\":3,\"n\":\"Record Flags\"},{\"t\":3,\"n\":\"FormID\"},{\"t\":11,\"n\":\"Version Control Info 1\"},{\"t\":3,\"n\":\"Form Version\"},{\"t\":11,\"n\":\"Version Control Info 2\"}]},{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"n\":\"VMAD - Virtual Machine Adapter\",\"c\":[{\"t\":3,\"n\":\"Version\"},{\"t\":3,\"n\":\"Object Format\"},{\"t\":12,\"n\":\"Data\",\"c\":[{\"t\":9,\"n\":\"Scripts\",\"c\":[{\"t\":6,\"n\":\"Script\",\"c\":[{\"t\":2,\"n\":\"scriptName\"},{\"t\":3,\"n\":\"Flags\"},{\"t\":9,\"n\":\"Properties\",\"c\":[{\"t\":6,\"n\":\"Property\",\"c\":[{\"t\":2,\"n\":\"propertyName\"},{\"t\":3,\"n\":\"Type\"},{\"t\":3,\"n\":\"Flags\"},{\"t\":12,\"n\":\"Value\"}]}]}]}]}]}]},{\"t\":6,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"n\":\"X1\"},{\"t\":3,\"n\":\"Y1\"},{\"t\":3,\"n\":\"Z1\"},{\"t\":3,\"n\":\"X2\"},{\"t\":3,\"n\":\"Y2\"},{\"t\":3,\"n\":\"Z2\"}]},{\"t\":2,\"n\":\"FULL - Name\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Icon\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"ICON - Large Icon filename\"}]},{\"t\":6,\"n\":\"Destructable\",\"c\":[{\"t\":6,\"n\":\"DEST - Header\",\"c\":[{\"t\":3,\"n\":\"Health\"},{\"t\":3,\"n\":\"DEST Count\"},{\"t\":3,\"n\":\"VATS Targetable\"},{\"t\":11,\"n\":\"Unknown\"}]}]},{\"t\":3,\"n\":\"YNAM - Sound - Pick Up\"},{\"t\":3,\"n\":\"ZNAM - Sound - Drop\"},{\"t\":3,\"n\":\"KSIZ - Keyword Count\"},{\"t\":9,\"n\":\"KWDA - Keywords\",\"c\":[{\"t\":3,\"n\":\"Keyword\"}]},{\"t\":6,\"n\":\"DATA - Data\",\"c\":[{\"t\":3,\"n\":\"Value\"},{\"t\":5,\"n\":\"Weight\"}]}]},{\"t\":1,\"p\":1,\"n\":\"MSTT - Moveable Static\",\"c\":[{\"t\":6,\"n\":\"Record Header\",\"c\":[{\"t\":2,\"n\":\"Signature\"},{\"t\":3,\"n\":\"Data Size\"},{\"t\":3,\"n\":\"Record Flags\"},{\"t\":3,\"n\":\"FormID\"},{\"t\":11,\"n\":\"Version Control Info 1\"},{\"t\":3,\"n\":\"Form Version\"},{\"t\":11,\"n\":\"Version Control Info 2\"}]},{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"n\":\"X1\"},{\"t\":3,\"n\":\"Y1\"},{\"t\":3,\"n\":\"Z1\"},{\"t\":3,\"n\":\"X2\"},{\"t\":3,\"n\":\"Y2\"},{\"t\":3,\"n\":\"Z2\"}]},{\"t\":2,\"n\":\"FULL - Name\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"}]},{\"t\":6,\"n\":\"Destructable\",\"c\":[{\"t\":6,\"n\":\"DEST - Header\",\"c\":[{\"t\":3,\"n\":\"Health\"},{\"t\":3,\"n\":\"DEST Count\"},{\"t\":3,\"n\":\"VATS Targetable\"},{\"t\":11,\"n\":\"Unknown\"}]}]},{\"t\":3,\"n\":\"DATA - Flags\"},{\"t\":3,\"n\":\"SNAM - Looping Sound\"}]},{\"t\":1,\"p\":1,\"n\":\"PROJ - Projectile\",\"c\":[{\"t\":6,\"n\":\"Record Header\",\"c\":[{\"t\":2,\"n\":\"Signature\"},{\"t\":3,\"n\":\"Data Size\"},{\"t\":3,\"n\":\"Record Flags\"},{\"t\":3,\"n\":\"FormID\"},{\"t\":11,\"n\":\"Version Control Info 1\"},{\"t\":3,\"n\":\"Form Version\"},{\"t\":11,\"n\":\"Version Control Info 2\"}]},{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"n\":\"X1\"},{\"t\":3,\"n\":\"Y1\"},{\"t\":3,\"n\":\"Z1\"},{\"t\":3,\"n\":\"X2\"},{\"t\":3,\"n\":\"Y2\"},{\"t\":3,\"n\":\"Z2\"}]},{\"t\":2,\"n\":\"FULL - Name\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"}]},{\"t\":6,\"n\":\"Destructable\",\"c\":[{\"t\":6,\"n\":\"DEST - Header\",\"c\":[{\"t\":3,\"n\":\"Health\"},{\"t\":3,\"n\":\"DEST Count\"},{\"t\":3,\"n\":\"VATS Targetable\"},{\"t\":11,\"n\":\"Unknown\"}]}]},{\"t\":6,\"n\":\"DATA - Data\",\"c\":[{\"t\":3,\"n\":\"Flags\"},{\"t\":3,\"n\":\"Type\"},{\"t\":5,\"n\":\"Gravity\"},{\"t\":5,\"n\":\"Speed\"},{\"t\":5,\"n\":\"Range\"},{\"t\":3,\"n\":\"Light\"},{\"t\":3,\"n\":\"Muzzle Flash - Light\"},{\"t\":5,\"n\":\"Tracer Chance\"},{\"t\":5,\"n\":\"Explosion - Alt. Trigger - Proximity\"},{\"t\":5,\"n\":\"Explosion - Alt. Trigger - Timer\"},{\"t\":3,\"n\":\"Explosion\"},{\"t\":3,\"n\":\"Sound\"},{\"t\":5,\"n\":\"Muzzle Flash - Duration\"},{\"t\":5,\"n\":\"Fade Duration\"},{\"t\":5,\"n\":\"Impact Force\"},{\"t\":3,\"n\":\"Sound - Countdown\"},{\"t\":3,\"n\":\"Sound - Disable\"},{\"t\":3,\"n\":\"Default Weapon Source\"},{\"t\":5,\"n\":\"Cone Spread\"},{\"t\":5,\"n\":\"Collision Radius\"},{\"t\":5,\"n\":\"Lifetime\"},{\"t\":5,\"n\":\"Relaunch Interval\"},{\"t\":3,\"n\":\"Decal Data\"},{\"t\":3,\"n\":\"Collision Layer\"}]},{\"t\":6,\"n\":\"Muzzle Flash Model\",\"c\":[{\"t\":2,\"n\":\"NAM1 - Model Filename\"}]},{\"t\":3,\"n\":\"VNAM - Sound Level\"}]},{\"t\":1,\"p\":1,\"n\":\"SCRL - Scroll\",\"c\":[{\"t\":6,\"n\":\"Record Header\",\"c\":[{\"t\":2,\"n\":\"Signature\"},{\"t\":3,\"n\":\"Data Size\"},{\"t\":3,\"n\":\"Record Flags\"},{\"t\":3,\"n\":\"FormID\"},{\"t\":11,\"n\":\"Version Control Info 1\"},{\"t\":3,\"n\":\"Form Version\"},{\"t\":11,\"n\":\"Version Control Info 2\"}]},{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"n\":\"X1\"},{\"t\":3,\"n\":\"Y1\"},{\"t\":3,\"n\":\"Z1\"},{\"t\":3,\"n\":\"X2\"},{\"t\":3,\"n\":\"Y2\"},{\"t\":3,\"n\":\"Z2\"}]},{\"t\":2,\"n\":\"FULL - Name\"},{\"t\":3,\"n\":\"KSIZ - Keyword Count\"},{\"t\":9,\"n\":\"KWDA - Keywords\",\"c\":[{\"t\":3,\"n\":\"Keyword\"}]},{\"t\":3,\"n\":\"MDOB - Menu Display Object\"},{\"t\":3,\"n\":\"ETYP - Equipment Type\"},{\"t\":2,\"n\":\"DESC - Description\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"}]},{\"t\":6,\"n\":\"Destructable\",\"c\":[{\"t\":6,\"n\":\"DEST - Header\",\"c\":[{\"t\":3,\"n\":\"Health\"},{\"t\":3,\"n\":\"DEST Count\"},{\"t\":3,\"n\":\"VATS Targetable\"},{\"t\":11,\"n\":\"Unknown\"}]}]},{\"t\":3,\"n\":\"YNAM - Sound - Pick Up\"},{\"t\":3,\"n\":\"ZNAM - Sound - Drop\"},{\"t\":6,\"n\":\"DATA - Item\",\"c\":[{\"t\":3,\"n\":\"Value\"},{\"t\":5,\"n\":\"Weight\"}]},{\"t\":6,\"n\":\"SPIT - Data\",\"c\":[{\"t\":3,\"n\":\"Base Cost\"},{\"t\":3,\"n\":\"Flags\"},{\"t\":3,\"n\":\"Type\"},{\"t\":5,\"n\":\"Charge Time\"},{\"t\":3,\"n\":\"Cast Type\"},{\"t\":3,\"n\":\"Target Type\"},{\"t\":5,\"n\":\"Cast Duration\"},{\"t\":5,\"n\":\"Range\"},{\"t\":3,\"n\":\"Half-cost Perk\"}]},{\"t\":8,\"n\":\"Effects\",\"c\":[{\"t\":6,\"n\":\"Effect\",\"c\":[{\"t\":3,\"n\":\"EFID - Base Effect\"},{\"t\":6,\"n\":\"EFIT - \",\"c\":[{\"t\":5,\"n\":\"Magnitude\"},{\"t\":3,\"n\":\"Area\"},{\"t\":3,\"n\":\"Duration\"}]}]}]}]},{\"t\":1,\"p\":1,\"n\":\"SLGM - Soul Gem\",\"c\":[{\"t\":6,\"n\":\"Record Header\",\"c\":[{\"t\":2,\"n\":\"Signature\"},{\"t\":3,\"n\":\"Data Size\"},{\"t\":3,\"n\":\"Record Flags\"},{\"t\":3,\"n\":\"FormID\"},{\"t\":11,\"n\":\"Version Control Info 1\"},{\"t\":3,\"n\":\"Form Version\"},{\"t\":11,\"n\":\"Version Control Info 2\"}]},{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"n\":\"X1\"},{\"t\":3,\"n\":\"Y1\"},{\"t\":3,\"n\":\"Z1\"},{\"t\":3,\"n\":\"X2\"},{\"t\":3,\"n\":\"Y2\"},{\"t\":3,\"n\":\"Z2\"}]},{\"t\":2,\"n\":\"FULL - Name\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Icon\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"ICON - Large Icon filename\"}]},{\"t\":6,\"n\":\"Destructable\",\"c\":[{\"t\":6,\"n\":\"DEST - Header\",\"c\":[{\"t\":3,\"n\":\"Health\"},{\"t\":3,\"n\":\"DEST Count\"},{\"t\":3,\"n\":\"VATS Targetable\"},{\"t\":11,\"n\":\"Unknown\"}]}]},{\"t\":3,\"n\":\"YNAM - Sound - Pick Up\"},{\"t\":3,\"n\":\"ZNAM - Sound - Drop\"},{\"t\":3,\"n\":\"KSIZ - Keyword Count\"},{\"t\":9,\"n\":\"KWDA - Keywords\",\"c\":[{\"t\":3,\"n\":\"Keyword\"}]},{\"t\":6,\"n\":\"DATA - \",\"c\":[{\"t\":3,\"n\":\"Value\"},{\"t\":5,\"n\":\"Weight\"}]},{\"t\":3,\"n\":\"SOUL - Contained Soul\"},{\"t\":3,\"n\":\"SLCP - Maximum Capacity\"},{\"t\":3,\"n\":\"NAM0 - Linked To\"}]},{\"t\":1,\"p\":1,\"n\":\"STAT - Static\",\"c\":[{\"t\":6,\"n\":\"Record Header\",\"c\":[{\"t\":2,\"n\":\"Signature\"},{\"t\":3,\"n\":\"Data Size\"},{\"t\":3,\"n\":\"Record Flags\"},{\"t\":3,\"n\":\"FormID\"},{\"t\":11,\"n\":\"Version Control Info 1\"},{\"t\":3,\"n\":\"Form Version\"},{\"t\":11,\"n\":\"Version Control Info 2\"}]},{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"n\":\"X1\"},{\"t\":3,\"n\":\"Y1\"},{\"t\":3,\"n\":\"Z1\"},{\"t\":3,\"n\":\"X2\"},{\"t\":3,\"n\":\"Y2\"},{\"t\":3,\"n\":\"Z2\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"}]},{\"t\":6,\"n\":\"DNAM - Direction Material\",\"c\":[{\"t\":5,\"n\":\"Max Angle (30-120)\"},{\"t\":3,\"n\":\"Material\"}]},{\"t\":8,\"n\":\"MNAM - Distant LOD\",\"c\":[{\"t\":6,\"n\":\"LOD #0 (Level 0)\",\"c\":[{\"t\":2,\"n\":\"Mesh\"}]},{\"t\":6,\"n\":\"LOD #1 (Level 1)\",\"c\":[{\"t\":2,\"n\":\"Mesh\"}]},{\"t\":6,\"n\":\"LOD #2 (Level 2)\",\"c\":[{\"t\":2,\"n\":\"Mesh\"}]},{\"t\":6,\"n\":\"LOD #3 (Level 3)\",\"c\":[{\"t\":2,\"n\":\"Mesh\"}]}]}]},{\"t\":1,\"p\":1,\"n\":\"TREE - Tree\",\"c\":[{\"t\":6,\"n\":\"Record Header\",\"c\":[{\"t\":2,\"n\":\"Signature\"},{\"t\":3,\"n\":\"Data Size\"},{\"t\":3,\"n\":\"Record Flags\"},{\"t\":3,\"n\":\"FormID\"},{\"t\":11,\"n\":\"Version Control Info 1\"},{\"t\":3,\"n\":\"Form Version\"},{\"t\":11,\"n\":\"Version Control Info 2\"}]},{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"n\":\"VMAD - Virtual Machine Adapter\",\"c\":[{\"t\":3,\"n\":\"Version\"},{\"t\":3,\"n\":\"Object Format\"},{\"t\":12,\"n\":\"Data\",\"c\":[{\"t\":9,\"n\":\"Scripts\",\"c\":[{\"t\":6,\"n\":\"Script\",\"c\":[{\"t\":2,\"n\":\"scriptName\"},{\"t\":3,\"n\":\"Flags\"},{\"t\":9,\"n\":\"Properties\",\"c\":[{\"t\":6,\"n\":\"Property\",\"c\":[{\"t\":2,\"n\":\"propertyName\"},{\"t\":3,\"n\":\"Type\"},{\"t\":3,\"n\":\"Flags\"},{\"t\":12,\"n\":\"Value\"}]}]}]}]}]}]},{\"t\":6,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"n\":\"X1\"},{\"t\":3,\"n\":\"Y1\"},{\"t\":3,\"n\":\"Z1\"},{\"t\":3,\"n\":\"X2\"},{\"t\":3,\"n\":\"Y2\"},{\"t\":3,\"n\":\"Z2\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"}]},{\"t\":3,\"n\":\"PFIG - Ingredient\"},{\"t\":3,\"n\":\"SNAM - Harvest Sound\"},{\"t\":6,\"n\":\"PFPC - Ingredient Production\",\"c\":[{\"t\":3,\"n\":\"Spring\"},{\"t\":3,\"n\":\"Summer\"},{\"t\":3,\"n\":\"Fall\"},{\"t\":3,\"n\":\"Winter\"}]},{\"t\":2,\"n\":\"FULL - Name\"},{\"t\":6,\"n\":\"CNAM - Tree Data\",\"c\":[{\"t\":5,\"n\":\"Trunk Flexibility\"},{\"t\":5,\"n\":\"Branch Flexibility\"},{\"t\":5,\"n\":\"Unknown\"},{\"t\":5,\"n\":\"Unknown\"},{\"t\":5,\"n\":\"Unknown\"},{\"t\":5,\"n\":\"Unknown\"},{\"t\":5,\"n\":\"Unknown\"},{\"t\":5,\"n\":\"Unknown\"},{\"t\":5,\"n\":\"Unknown\"},{\"t\":5,\"n\":\"Unknown\"},{\"t\":5,\"n\":\"Leaf Amplitude\"},{\"t\":5,\"n\":\"Leaf Frequency\"}]}]},{\"t\":1,\"p\":1,\"n\":\"WEAP - Weapon\",\"c\":[{\"t\":6,\"n\":\"Record Header\",\"c\":[{\"t\":2,\"n\":\"Signature\"},{\"t\":3,\"n\":\"Data Size\"},{\"t\":3,\"n\":\"Record Flags\"},{\"t\":3,\"n\":\"FormID\"},{\"t\":11,\"n\":\"Version Control Info 1\"},{\"t\":3,\"n\":\"Form Version\"},{\"t\":11,\"n\":\"Version Control Info 2\"}]},{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"n\":\"VMAD - Virtual Machine Adapter\",\"c\":[{\"t\":3,\"n\":\"Version\"},{\"t\":3,\"n\":\"Object Format\"},{\"t\":12,\"n\":\"Data\",\"c\":[{\"t\":9,\"n\":\"Scripts\",\"c\":[{\"t\":6,\"n\":\"Script\",\"c\":[{\"t\":2,\"n\":\"scriptName\"},{\"t\":3,\"n\":\"Flags\"},{\"t\":9,\"n\":\"Properties\",\"c\":[{\"t\":6,\"n\":\"Property\",\"c\":[{\"t\":2,\"n\":\"propertyName\"},{\"t\":3,\"n\":\"Type\"},{\"t\":3,\"n\":\"Flags\"},{\"t\":12,\"n\":\"Value\"}]}]}]}]}]}]},{\"t\":6,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"n\":\"X1\"},{\"t\":3,\"n\":\"Y1\"},{\"t\":3,\"n\":\"Z1\"},{\"t\":3,\"n\":\"X2\"},{\"t\":3,\"n\":\"Y2\"},{\"t\":3,\"n\":\"Z2\"}]},{\"t\":2,\"n\":\"FULL - Name\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Icon\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"ICON - Large Icon filename\"}]},{\"t\":3,\"n\":\"EITM - Object Effect\"},{\"t\":3,\"n\":\"EAMT - Enchantment Amount\"},{\"t\":6,\"n\":\"Destructable\",\"c\":[{\"t\":6,\"n\":\"DEST - Header\",\"c\":[{\"t\":3,\"n\":\"Health\"},{\"t\":3,\"n\":\"DEST Count\"},{\"t\":3,\"n\":\"VATS Targetable\"},{\"t\":11,\"n\":\"Unknown\"}]}]},{\"t\":3,\"n\":\"ETYP - Equipment Type\"},{\"t\":3,\"n\":\"BIDS - Block Bash Impact Data Set\"},{\"t\":3,\"n\":\"BAMT - Alternate Block Material\"},{\"t\":3,\"n\":\"YNAM - Sound - Pick Up\"},{\"t\":3,\"n\":\"ZNAM - Sound - Drop\"},{\"t\":3,\"n\":\"KSIZ - Keyword Count\"},{\"t\":9,\"n\":\"KWDA - Keywords\",\"c\":[{\"t\":3,\"n\":\"Keyword\"}]},{\"t\":2,\"n\":\"DESC - Description\"},{\"t\":6,\"n\":\"Has Scope\",\"c\":[{\"t\":2,\"n\":\"MOD3 - Model Filename\"}]},{\"t\":11,\"n\":\"NNAM - Unused\"},{\"t\":3,\"n\":\"INAM - Impact Data Set\"},{\"t\":3,\"p\":1,\"n\":\"WNAM - 1st Person Model Object\"},{\"t\":3,\"n\":\"SNAM - Attack Sound\"},{\"t\":3,\"n\":\"XNAM - Attack Sound 2D\"},{\"t\":3,\"n\":\"NAM7 - Attack Loop Sound\"},{\"t\":3,\"n\":\"TNAM - Attack Fail Sound\"},{\"t\":3,\"n\":\"UNAM - Idle Sound\"},{\"t\":3,\"n\":\"NAM9 - Equip Sound\"},{\"t\":3,\"n\":\"NAM8 - Unequip Sound\"},{\"t\":6,\"n\":\"DATA - Game Data\",\"c\":[{\"t\":3,\"n\":\"Value\"},{\"t\":5,\"n\":\"Weight\"},{\"t\":3,\"n\":\"Damage\"}]},{\"t\":6,\"n\":\"DNAM - Data\",\"c\":[{\"t\":3,\"n\":\"Animation Type\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":5,\"n\":\"Speed\"},{\"t\":5,\"n\":\"Reach\"},{\"t\":3,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":5,\"n\":\"Sight FOV\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":3,\"n\":\"Base VATS To-Hit Chance\"},{\"t\":3,\"n\":\"Attack Animation\"},{\"t\":3,\"n\":\"# Projectiles\"},{\"t\":3,\"n\":\"Embedded Weapon AV (unused)\"},{\"t\":5,\"n\":\"Range Min\"},{\"t\":5,\"n\":\"Range Max\"},{\"t\":3,\"n\":\"On Hit\"},{\"t\":3,\"n\":\"Flags2\"},{\"t\":5,\"n\":\"Animation Attack Mult\"},{\"t\":5,\"n\":\"Unknown\"},{\"t\":5,\"n\":\"Rumble - Left Motor Strength\"},{\"t\":5,\"n\":\"Rumble - Right Motor Strength\"},{\"t\":5,\"n\":\"Rumble - Duration\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":3,\"n\":\"Skill\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":3,\"n\":\"Resist\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":5,\"n\":\"Stagger\"}]},{\"t\":6,\"n\":\"CRDT - Critical Data\",\"c\":[{\"t\":3,\"n\":\"Damage\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":5,\"n\":\"% Mult\"},{\"t\":3,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":3,\"n\":\"Effect\"}]},{\"t\":3,\"n\":\"VNAM - Detection Sound Level\"},{\"t\":3,\"n\":\"CNAM - Template\"}]},{\"t\":1,\"p\":1,\"n\":\"ALCH - Ingestible\",\"c\":[{\"t\":6,\"n\":\"Record Header\",\"c\":[{\"t\":2,\"n\":\"Signature\"},{\"t\":3,\"n\":\"Data Size\"},{\"t\":3,\"n\":\"Record Flags\"},{\"t\":3,\"n\":\"FormID\"},{\"t\":11,\"n\":\"Version Control Info 1\"},{\"t\":3,\"n\":\"Form Version\"},{\"t\":11,\"n\":\"Version Control Info 2\"}]},{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"n\":\"X1\"},{\"t\":3,\"n\":\"Y1\"},{\"t\":3,\"n\":\"Z1\"},{\"t\":3,\"n\":\"X2\"},{\"t\":3,\"n\":\"Y2\"},{\"t\":3,\"n\":\"Z2\"}]},{\"t\":2,\"n\":\"FULL - Name\"},{\"t\":3,\"n\":\"KSIZ - Keyword Count\"},{\"t\":9,\"n\":\"KWDA - Keywords\",\"c\":[{\"t\":3,\"n\":\"Keyword\"}]},{\"t\":2,\"n\":\"DESC - Description\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"}]},{\"t\":6,\"n\":\"Destructable\",\"c\":[{\"t\":6,\"n\":\"DEST - Header\",\"c\":[{\"t\":3,\"n\":\"Health\"},{\"t\":3,\"n\":\"DEST Count\"},{\"t\":3,\"n\":\"VATS Targetable\"},{\"t\":11,\"n\":\"Unknown\"}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Icon\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"ICON - Large Icon filename\"}]},{\"t\":3,\"n\":\"YNAM - Sound - Pick Up\"},{\"t\":3,\"n\":\"ZNAM - Sound - Drop\"},{\"t\":3,\"n\":\"ETYP - Equipment Type\"},{\"t\":5,\"n\":\"DATA - Weight\"},{\"t\":6,\"n\":\"ENIT - Effect Data\",\"c\":[{\"t\":3,\"n\":\"Value\"},{\"t\":3,\"n\":\"Flags\"},{\"t\":3,\"n\":\"Addiction\"},{\"t\":5,\"n\":\"Addiction Chance\"},{\"t\":3,\"n\":\"Sound - Consume\"}]},{\"t\":8,\"n\":\"Effects\",\"c\":[{\"t\":6,\"n\":\"Effect\",\"c\":[{\"t\":3,\"n\":\"EFID - Base Effect\"},{\"t\":6,\"n\":\"EFIT - \",\"c\":[{\"t\":5,\"n\":\"Magnitude\"},{\"t\":3,\"n\":\"Area\"},{\"t\":3,\"n\":\"Duration\"}]}]}]}]}]},\"name\":\"Bash.Graphics\",\"hash\":\"8A68A29F\",\"color\":255}"
  },
  {
    "path": "frontend/settings/Skyrim/Bash.Hairs.json",
    "content": "{\"records\":\"RACE\",\"description\":\"Hairs tag from Wrye Bash.\\r\\n\\r\\nUsed when the mod adds hairs to races.\",\"tree\":{\"records\":[{\"t\":1,\"p\":1,\"n\":\"RACE - Race\",\"c\":[{\"t\":6,\"n\":\"Record Header\",\"c\":[{\"t\":2,\"n\":\"Signature\"},{\"t\":3,\"n\":\"Data Size\"},{\"t\":3,\"n\":\"Record Flags\"},{\"t\":3,\"n\":\"FormID\"},{\"t\":11,\"n\":\"Version Control Info 1\"},{\"t\":3,\"n\":\"Form Version\"},{\"t\":11,\"n\":\"Version Control Info 2\"}]},{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"n\":\"FULL - Name\"},{\"t\":2,\"n\":\"DESC - Description\"},{\"t\":3,\"n\":\"SPCT - Count\"},{\"t\":9,\"n\":\"Actor Effects\",\"c\":[{\"t\":3,\"n\":\"SPLO - Actor Effect\"}]},{\"t\":3,\"n\":\"WNAM - Skin\"},{\"t\":6,\"n\":\"BOD2 - Biped Body Template\",\"c\":[{\"t\":3,\"n\":\"First Person Flags\"},{\"t\":3,\"n\":\"General Flags\"},{\"n\":\"Unused\"},{\"t\":3,\"n\":\"Armor Type\"}]},{\"t\":3,\"n\":\"KSIZ - Keyword Count\"},{\"t\":9,\"n\":\"KWDA - Keywords\",\"c\":[{\"t\":3,\"n\":\"Keyword\"}]},{\"t\":6,\"n\":\"DATA - \",\"c\":[{\"t\":10,\"n\":\"Skill Boosts\",\"c\":[{\"t\":6,\"n\":\"Skill Boost\",\"c\":[{\"t\":3,\"n\":\"Skill\"},{\"t\":3,\"n\":\"Boost\"}]},{\"t\":6,\"n\":\"Skill Boost\",\"c\":[{\"t\":3,\"n\":\"Skill\"},{\"t\":3,\"n\":\"Boost\"}]},{\"t\":6,\"n\":\"Skill Boost\",\"c\":[{\"t\":3,\"n\":\"Skill\"},{\"t\":3,\"n\":\"Boost\"}]},{\"t\":6,\"n\":\"Skill Boost\",\"c\":[{\"t\":3,\"n\":\"Skill\"},{\"t\":3,\"n\":\"Boost\"}]},{\"t\":6,\"n\":\"Skill Boost\",\"c\":[{\"t\":3,\"n\":\"Skill\"},{\"t\":3,\"n\":\"Boost\"}]},{\"t\":6,\"n\":\"Skill Boost\",\"c\":[{\"t\":3,\"n\":\"Skill\"},{\"t\":3,\"n\":\"Boost\"}]},{\"t\":6,\"n\":\"Skill Boost\",\"c\":[{\"t\":3,\"n\":\"Skill\"},{\"t\":3,\"n\":\"Boost\"}]}]},{\"t\":11,\"n\":\"Unknown\"},{\"t\":5,\"n\":\"Male Height\"},{\"t\":5,\"n\":\"Female Height\"},{\"t\":5,\"n\":\"Male Weight\"},{\"t\":5,\"n\":\"Female Weight\"},{\"t\":3,\"n\":\"Flags\"},{\"t\":5,\"n\":\"Starting Health\"},{\"t\":5,\"n\":\"Starting Magicka\"},{\"t\":5,\"n\":\"Starting Stamina\"},{\"t\":5,\"n\":\"Base Carry Weight\"},{\"t\":5,\"n\":\"Base Mass\"},{\"t\":5,\"n\":\"Acceleration rate\"},{\"t\":5,\"n\":\"Deceleration rate\"},{\"t\":3,\"n\":\"Size\"},{\"t\":3,\"n\":\"Head Biped Object\"},{\"t\":3,\"n\":\"Hair Biped Object\"},{\"t\":5,\"n\":\"Injured Health Pct\"},{\"t\":3,\"n\":\"Shield Biped Object\"},{\"t\":5,\"n\":\"Health Regen\"},{\"t\":5,\"n\":\"Magicka Regen\"},{\"t\":5,\"n\":\"Stamina Regen\"},{\"t\":5,\"n\":\"Unarmed Damage\"},{\"t\":5,\"n\":\"Unarmed Reach\"},{\"t\":3,\"n\":\"Body Biped Object\"},{\"t\":5,\"n\":\"Aim Angle Tolerance\"},{\"t\":5,\"n\":\"Flight Radius\"},{\"t\":5,\"n\":\"Angular Acceleration Rate\"},{\"t\":5,\"n\":\"Angular Tolerance\"},{\"t\":3,\"n\":\"Flags 2\"},{\"t\":6,\"n\":\"Mount Data\",\"c\":[{\"t\":5,\"n\":\"Offset X\"},{\"t\":5,\"n\":\"Offset Y\"},{\"t\":5,\"n\":\"Unknown\"},{\"t\":5,\"n\":\"Unknown\"},{\"t\":5,\"n\":\"Unknown\"},{\"t\":5,\"n\":\"Unknown\"},{\"t\":5,\"n\":\"Unknown\"},{\"t\":5,\"n\":\"Unknown\"},{\"t\":5,\"n\":\"Unknown\"}]}]},{\"n\":\"MNAM - Male Marker\"},{\"t\":2,\"n\":\"ANAM - Male Skeletal Model\"},{\"t\":11,\"n\":\"MODT - Texture Files Hashes\"},{\"n\":\"FNAM - Female Marker\"},{\"t\":2,\"n\":\"ANAM - Female Skeletal Model\"},{\"t\":11,\"n\":\"MODT - Texture Files Hashes\"},{\"n\":\"NAM2 - Marker NAM2 #1\"},{\"t\":9,\"n\":\"Movement Type Names\",\"c\":[{\"t\":2,\"n\":\"MTNM - Name\"}]},{\"t\":7,\"n\":\"VTCK - Voices\",\"c\":[{\"t\":3,\"n\":\"Voice #0 (Male)\"},{\"t\":3,\"n\":\"Voice #1 (Female)\"}]},{\"t\":7,\"n\":\"DNAM - Decapitate Armors\",\"c\":[{\"t\":3,\"n\":\"Decapitate Armor #0 (Male)\"},{\"t\":3,\"n\":\"Decapitate Armor #1 (Female)\"}]},{\"t\":7,\"n\":\"HCLF - Default Hair Colors\",\"c\":[{\"t\":3,\"n\":\"Default Hair Color #0 (Male)\"},{\"t\":3,\"n\":\"Default Hair Color #1 (Female)\"}]},{\"t\":3,\"n\":\"TINL - Total Number of Tints in List\"},{\"t\":5,\"n\":\"PNAM - FaceGen - Main clamp\"},{\"t\":5,\"n\":\"UNAM - FaceGen - Face clamp\"},{\"t\":3,\"n\":\"ATKR - Attack Race\"},{\"t\":10,\"n\":\"Attacks\",\"c\":[{\"t\":6,\"n\":\"Attack\",\"c\":[{\"t\":6,\"n\":\"ATKD - Attack Data\",\"c\":[{\"t\":5,\"n\":\"Damage Mult\"},{\"t\":5,\"n\":\"Attack Chance\"},{\"t\":3,\"n\":\"Attack Spell\"},{\"t\":3,\"n\":\"Attack Flags\"},{\"t\":5,\"n\":\"Attack Angle\"},{\"t\":5,\"n\":\"Strike Angle\"},{\"t\":5,\"n\":\"Stagger\"},{\"t\":3,\"n\":\"Attack Type\"},{\"t\":5,\"n\":\"Knockdown\"},{\"t\":5,\"n\":\"Recovery Time\"},{\"t\":5,\"n\":\"Stamina Mult\"}]}]}]},{\"t\":6,\"n\":\"Body Data\",\"c\":[{\"n\":\"NAM1 - Body Data Marker\"},{\"t\":6,\"n\":\"Male Body Data\",\"c\":[{\"n\":\"MNAM - Male Data Marker\"},{\"t\":10,\"n\":\"Parts\",\"c\":[{\"t\":6,\"n\":\"Part\",\"c\":[{\"t\":3,\"n\":\"INDX - Index\"}]}]}]},{\"t\":6,\"n\":\"Female Body Data\",\"c\":[{\"n\":\"FNAM - Female Data Marker\"},{\"t\":10,\"n\":\"Parts\",\"c\":[{\"t\":6,\"n\":\"Part\",\"c\":[{\"t\":3,\"n\":\"INDX - Index\"}]}]}]}]},{\"t\":9,\"p\":1,\"n\":\"HNAM - Hairs\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Hair\"}]},{\"t\":9,\"n\":\"ENAM - Eyes\",\"c\":[{\"t\":3,\"n\":\"Eye\"}]},{\"t\":3,\"n\":\"GNAM - Body Part Data\"},{\"n\":\"NAM2 - Marker NAM2 #2\"},{\"n\":\"NAM3 - Marker NAM3 #3\"},{\"t\":6,\"n\":\"Male Behavior Graph\",\"c\":[{\"n\":\"MNAM - Male Data Marker\"}]},{\"t\":6,\"n\":\"Female Behavior Graph\",\"c\":[{\"n\":\"FNAM - Female Data Marker\"}]},{\"t\":3,\"n\":\"NAM4 - Material Type\"},{\"t\":3,\"n\":\"NAM5 - Impact Data Set\"},{\"t\":3,\"n\":\"NAM7 - Decapitation FX\"},{\"t\":3,\"n\":\"ONAM - Open Loot Sound\"},{\"t\":3,\"n\":\"LNAM - Close Loot Sound\"},{\"t\":7,\"n\":\"Biped Object Names\",\"c\":[{\"t\":2,\"n\":\"NAME - Name\"}]},{\"t\":10,\"n\":\"Movement Types\",\"c\":[{\"t\":6,\"n\":\"Movement Types\",\"c\":[{\"t\":3,\"n\":\"MTYP - Movement Type\"}]}]},{\"t\":3,\"n\":\"VNAM - Equipment Flags\"},{\"t\":9,\"n\":\"Equip Slots\",\"c\":[{\"t\":3,\"n\":\"QNAM - Equip Slot\"}]},{\"t\":3,\"n\":\"UNES - Unarmed Equip Slot\"},{\"t\":7,\"n\":\"Phoneme Target Names\",\"c\":[{\"t\":2,\"n\":\"PHTN - Name\"}]},{\"t\":6,\"n\":\"FaceFX Phonemes\",\"c\":[{\"t\":6,\"n\":\"IY\",\"c\":[{\"t\":6,\"n\":\"PHWT - Phoneme Target Weight\",\"c\":[{\"t\":5,\"n\":\"Aah \\/ LipBigAah\"},{\"t\":5,\"n\":\"BigAah \\/ LipDST\"},{\"t\":5,\"n\":\"BMP \\/ LipEee\"},{\"t\":5,\"n\":\"ChJsh \\/ LipFV\"},{\"t\":5,\"n\":\"DST \\/ LipK\"},{\"t\":5,\"n\":\"Eee \\/ LipL\"},{\"t\":5,\"n\":\"Eh \\/ LipR\"},{\"t\":5,\"n\":\"FV \\/ LipTh\"},{\"t\":5,\"n\":\"I\"},{\"t\":5,\"n\":\"K\"},{\"t\":5,\"n\":\"N\"},{\"t\":5,\"n\":\"Oh\"},{\"t\":5,\"n\":\"OohQ\"},{\"t\":5,\"n\":\"R\"},{\"t\":5,\"n\":\"TH\"},{\"t\":5,\"n\":\"W\"}]}]}]},{\"t\":3,\"n\":\"WKMV - Base Movement Default - Walk\"},{\"t\":3,\"n\":\"RNMV - Base Movement Default - Run\"},{\"t\":3,\"n\":\"SWMV - Base Movement Default - Swim\"},{\"t\":3,\"n\":\"FLMV - Base Movement Default - Fly\"},{\"t\":3,\"n\":\"SNMV - Base Movement Default - Sneak\"},{\"t\":3,\"n\":\"SPMV - Base Movement Default - Sprint\"},{\"t\":6,\"n\":\"Head Data\",\"c\":[{\"n\":\"NAM0 - Head Data Marker\"},{\"t\":6,\"n\":\"Male Head Data\",\"c\":[{\"n\":\"MNAM - Male Data Marker\"}]},{\"t\":6,\"n\":\"Female Head Data\",\"c\":[{\"n\":\"NAM0 - Head Data Marker\"},{\"n\":\"FNAM - Female Data Marker\"}]}]},{\"t\":3,\"n\":\"NAM8 - Morph race\"},{\"t\":3,\"n\":\"RNAM - Armor race\"}]}]},\"name\":\"Bash.Hairs\",\"hash\":\"$533161C6\",\"color\":255}"
  },
  {
    "path": "frontend/settings/Skyrim/Bash.Invent.json",
    "content": "{\"records\":\"NPC_,CONT\",\"description\":\"Invent tag from Wrye Bash.\\r\\n\\r\\nUsed when the mod changes inventories.\",\"tree\":{\"records\":[{\"t\":1,\"p\":1,\"n\":\"NPC_ - Non-Player Character (Actor)\",\"c\":[{\"t\":6,\"n\":\"Record Header\",\"c\":[{\"t\":2,\"n\":\"Signature\"},{\"t\":3,\"n\":\"Data Size\"},{\"t\":3,\"n\":\"Record Flags\"},{\"t\":3,\"n\":\"FormID\"},{\"t\":11,\"n\":\"Version Control Info 1\"},{\"t\":3,\"n\":\"Form Version\"},{\"t\":11,\"n\":\"Version Control Info 2\"}]},{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"n\":\"VMAD - Virtual Machine Adapter\",\"c\":[{\"t\":3,\"n\":\"Version\"},{\"t\":3,\"n\":\"Object Format\"},{\"t\":12,\"n\":\"Data\",\"c\":[{\"t\":9,\"n\":\"Scripts\",\"c\":[{\"t\":6,\"n\":\"Script\",\"c\":[{\"t\":2,\"n\":\"scriptName\"},{\"t\":3,\"n\":\"Flags\"},{\"t\":9,\"n\":\"Properties\",\"c\":[{\"t\":6,\"n\":\"Property\",\"c\":[{\"t\":2,\"n\":\"propertyName\"},{\"t\":3,\"n\":\"Type\"},{\"t\":3,\"n\":\"Flags\"},{\"t\":12,\"n\":\"Value\"}]}]}]}]}]}]},{\"t\":6,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"n\":\"X1\"},{\"t\":3,\"n\":\"Y1\"},{\"t\":3,\"n\":\"Z1\"},{\"t\":3,\"n\":\"X2\"},{\"t\":3,\"n\":\"Y2\"},{\"t\":3,\"n\":\"Z2\"}]},{\"t\":6,\"n\":\"ACBS - Configuration\",\"c\":[{\"t\":3,\"n\":\"Flags\"},{\"t\":3,\"n\":\"Magicka Offset\"},{\"t\":3,\"n\":\"Stamina Offset\"},{\"t\":12,\"n\":\"Level\"},{\"t\":3,\"n\":\"Calc min level\"},{\"t\":3,\"n\":\"Calc max level\"},{\"t\":3,\"n\":\"Speed Multiplier\"},{\"t\":3,\"n\":\"Disposition Base (unused)\"},{\"t\":3,\"n\":\"Template Flags\"},{\"t\":3,\"n\":\"Health Offset\"},{\"t\":3,\"n\":\"Bleedout Override\"}]},{\"t\":10,\"n\":\"Factions\",\"c\":[{\"t\":6,\"n\":\"SNAM - Faction\",\"c\":[{\"t\":3,\"n\":\"Faction\"},{\"t\":3,\"n\":\"Rank\"},{\"t\":11,\"n\":\"Unused\"}]}]},{\"t\":3,\"n\":\"INAM - Death item\"},{\"t\":3,\"n\":\"VTCK - Voice\"},{\"t\":3,\"n\":\"TPLT - Template\"},{\"t\":3,\"n\":\"RNAM - Race\"},{\"t\":3,\"n\":\"SPCT - Count\"},{\"t\":9,\"n\":\"Actor Effects\",\"c\":[{\"t\":3,\"n\":\"SPLO - Actor Effect\"}]},{\"t\":6,\"n\":\"Destructable\",\"c\":[{\"t\":6,\"n\":\"DEST - Header\",\"c\":[{\"t\":3,\"n\":\"Health\"},{\"t\":3,\"n\":\"DEST Count\"},{\"t\":3,\"n\":\"VATS Targetable\"},{\"t\":11,\"n\":\"Unknown\"}]}]},{\"t\":3,\"n\":\"WNAM - Worn Armor\"},{\"t\":3,\"n\":\"ANAM - Far away model\"},{\"t\":3,\"n\":\"ATKR - Attack Race\"},{\"t\":10,\"n\":\"Attacks\",\"c\":[{\"t\":6,\"n\":\"Attack\",\"c\":[{\"t\":6,\"n\":\"ATKD - Attack Data\",\"c\":[{\"t\":5,\"n\":\"Damage Mult\"},{\"t\":5,\"n\":\"Attack Chance\"},{\"t\":3,\"n\":\"Attack Spell\"},{\"t\":3,\"n\":\"Attack Flags\"},{\"t\":5,\"n\":\"Attack Angle\"},{\"t\":5,\"n\":\"Strike Angle\"},{\"t\":5,\"n\":\"Stagger\"},{\"t\":3,\"n\":\"Attack Type\"},{\"t\":5,\"n\":\"Knockdown\"},{\"t\":5,\"n\":\"Recovery Time\"},{\"t\":5,\"n\":\"Stamina Mult\"}]}]}]},{\"t\":3,\"n\":\"SPOR - Spectator override package list\"},{\"t\":3,\"n\":\"OCOR - Observe dead body override package list\"},{\"t\":3,\"n\":\"GWOR - Guard warn override package list\"},{\"t\":3,\"n\":\"ECOR - Combat override package list\"},{\"t\":3,\"n\":\"PRKZ - Perk Count\"},{\"t\":10,\"n\":\"Perks\",\"c\":[{\"t\":6,\"n\":\"PRKR - Perk\",\"c\":[{\"t\":3,\"n\":\"Perk\"},{\"t\":3,\"n\":\"Rank\"},{\"t\":11,\"n\":\"Unused\"}]}]},{\"t\":3,\"n\":\"COCT - Count\"},{\"t\":10,\"p\":1,\"n\":\"Items\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Item\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"CNTO - Item\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Item\"},{\"t\":3,\"p\":1,\"n\":\"Count\"}]}]}]},{\"t\":6,\"n\":\"AIDT - AI Data\",\"c\":[{\"t\":3,\"n\":\"Aggression\"},{\"t\":3,\"n\":\"Confidence\"},{\"t\":3,\"n\":\"Energy Level\"},{\"t\":3,\"n\":\"Responsibility\"},{\"t\":3,\"n\":\"Mood\"},{\"t\":3,\"n\":\"Assistance\"},{\"t\":6,\"n\":\"Aggro\",\"c\":[{\"t\":3,\"n\":\"Aggro Radius Behavior\"},{\"t\":3,\"n\":\"Unknown\"},{\"t\":3,\"n\":\"Warn\"},{\"t\":3,\"n\":\"Warn\\/Attack\"},{\"t\":3,\"n\":\"Attack\"}]}]},{\"t\":7,\"n\":\"Packages\",\"c\":[{\"t\":3,\"n\":\"PKID - Package\"}]},{\"t\":3,\"n\":\"KSIZ - Keyword Count\"},{\"t\":9,\"n\":\"KWDA - Keywords\",\"c\":[{\"t\":3,\"n\":\"Keyword\"}]},{\"t\":3,\"n\":\"CNAM - Class\"},{\"t\":2,\"n\":\"FULL - Name\"},{\"t\":2,\"n\":\"SHRT - Short Name\"},{\"t\":11,\"n\":\"DATA - Marker\"},{\"t\":6,\"n\":\"DNAM - Player Skills\",\"c\":[{\"t\":7,\"n\":\"Skill Values\",\"c\":[{\"t\":3,\"n\":\"Skill #0 (OneHanded)\"},{\"t\":3,\"n\":\"Skill #1 (TwoHanded)\"},{\"t\":3,\"n\":\"Skill #2 (Marksman)\"},{\"t\":3,\"n\":\"Skill #3 (Block)\"},{\"t\":3,\"n\":\"Skill #4 (Smithing)\"},{\"t\":3,\"n\":\"Skill #5 (HeavyArmor)\"},{\"t\":3,\"n\":\"Skill #6 (LightArmor)\"},{\"t\":3,\"n\":\"Skill #7 (Pickpocket)\"},{\"t\":3,\"n\":\"Skill #8 (Lockpicking)\"},{\"t\":3,\"n\":\"Skill #9 (Sneak)\"},{\"t\":3,\"n\":\"Skill #10 (Alchemy)\"},{\"t\":3,\"n\":\"Skill #11 (Speechcraft)\"},{\"t\":3,\"n\":\"Skill #12 (Alteration)\"},{\"t\":3,\"n\":\"Skill #13 (Conjuration)\"},{\"t\":3,\"n\":\"Skill #14 (Destruction)\"},{\"t\":3,\"n\":\"Skill #15 (Illusion)\"},{\"t\":3,\"n\":\"Skill #16 (Restoration)\"},{\"t\":3,\"n\":\"Skill #17 (Enchanting)\"}]},{\"t\":7,\"n\":\"Skill Offsets\",\"c\":[{\"t\":3,\"n\":\"Skill #0 (OneHanded)\"},{\"t\":3,\"n\":\"Skill #1 (TwoHanded)\"},{\"t\":3,\"n\":\"Skill #2 (Marksman)\"},{\"t\":3,\"n\":\"Skill #3 (Block)\"},{\"t\":3,\"n\":\"Skill #4 (Smithing)\"},{\"t\":3,\"n\":\"Skill #5 (HeavyArmor)\"},{\"t\":3,\"n\":\"Skill #6 (LightArmor)\"},{\"t\":3,\"n\":\"Skill #7 (Pickpocket)\"},{\"t\":3,\"n\":\"Skill #8 (Lockpicking)\"},{\"t\":3,\"n\":\"Skill #9 (Sneak)\"},{\"t\":3,\"n\":\"Skill #10 (Alchemy)\"},{\"t\":3,\"n\":\"Skill #11 (Speechcraft)\"},{\"t\":3,\"n\":\"Skill #12 (Alteration)\"},{\"t\":3,\"n\":\"Skill #13 (Conjuration)\"},{\"t\":3,\"n\":\"Skill #14 (Destruction)\"},{\"t\":3,\"n\":\"Skill #15 (Illusion)\"},{\"t\":3,\"n\":\"Skill #16 (Restoration)\"},{\"t\":3,\"n\":\"Skill #17 (Enchanting)\"}]},{\"t\":3,\"n\":\"Health\"},{\"t\":3,\"n\":\"Magicka\"},{\"t\":3,\"n\":\"Stamina\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":5,\"n\":\"Far away model distance\"},{\"t\":3,\"n\":\"Geared up weapons\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":9,\"n\":\"Head Parts\",\"c\":[{\"t\":3,\"n\":\"PNAM - Head Part\"}]},{\"t\":3,\"n\":\"HCLF - Hair Color\"},{\"t\":3,\"n\":\"ZNAM - Combat Style\"},{\"t\":3,\"n\":\"GNAM - Gift Filter\"},{\"t\":11,\"n\":\"NAM5 - Unknown\"},{\"t\":5,\"n\":\"NAM6 - Height\"},{\"t\":5,\"n\":\"NAM7 - Weight\"},{\"t\":3,\"n\":\"NAM8 - Sound Level\"},{\"t\":10,\"n\":\"Sound Types\",\"c\":[{\"t\":6,\"n\":\"Sound Type\",\"c\":[{\"t\":3,\"n\":\"CSDT - Type\"},{\"t\":10,\"n\":\"Sounds\",\"c\":[{\"t\":6,\"n\":\"Sound\",\"c\":[{\"t\":3,\"n\":\"CSDI - Sound\"},{\"t\":3,\"n\":\"CSDC - Sound Chance\"}]}]}]}]},{\"t\":3,\"n\":\"CSCR - Inherits Sounds From\"},{\"t\":3,\"n\":\"DOFT - Default outfit\"},{\"t\":3,\"n\":\"SOFT - Sleeping outfit\"},{\"t\":3,\"n\":\"DPLT - Default Package List\"},{\"t\":3,\"n\":\"CRIF - Crime faction\"},{\"t\":3,\"n\":\"FTST - Head texture\"},{\"t\":6,\"n\":\"QNAM - Texture lighting\",\"c\":[{\"t\":5,\"n\":\"Red\"},{\"t\":5,\"n\":\"Green\"},{\"t\":5,\"n\":\"Blue\"}]},{\"t\":6,\"n\":\"NAM9 - Face morph\",\"c\":[{\"t\":5,\"n\":\"Nose Long\\/Short\"},{\"t\":5,\"n\":\"Nose Up\\/Down\"},{\"t\":5,\"n\":\"Jaw Up\\/Down\"},{\"t\":5,\"n\":\"Jaw Narrow\\/Wide\"},{\"t\":5,\"n\":\"Jaw Farward\\/Back\"},{\"t\":5,\"n\":\"Cheeks Up\\/Down\"},{\"t\":5,\"n\":\"Cheeks Farward\\/Back\"},{\"t\":5,\"n\":\"Eyes Up\\/Down\"},{\"t\":5,\"n\":\"Eyes In\\/Out\"},{\"t\":5,\"n\":\"Brows Up\\/Down\"},{\"t\":5,\"n\":\"Brows In\\/Out\"},{\"t\":5,\"n\":\"Brows Farward\\/Back\"},{\"t\":5,\"n\":\"Lips Up\\/Down\"},{\"t\":5,\"n\":\"Lips In\\/Out\"},{\"t\":5,\"n\":\"Chin Narrow\\/Wide\"},{\"t\":5,\"n\":\"Chin Up\\/Down\"},{\"t\":5,\"n\":\"Chin Underbite\\/Overbite\"},{\"t\":5,\"n\":\"Eyes Farward\\/Back\"},{\"t\":5,\"n\":\"Unknown\"}]},{\"t\":6,\"n\":\"NAMA - Face parts\",\"c\":[{\"t\":3,\"n\":\"Nose\"},{\"t\":3,\"n\":\"Unknown\"},{\"t\":3,\"n\":\"Eyes\"},{\"t\":3,\"n\":\"Mouth\"}]},{\"t\":10,\"n\":\"Tint Layers\",\"c\":[{\"t\":6,\"n\":\"Layer\",\"c\":[{\"t\":3,\"n\":\"TINI - Tint Index\"}]}]}]},{\"t\":1,\"p\":1,\"n\":\"CONT - Container\",\"c\":[{\"t\":6,\"n\":\"Record Header\",\"c\":[{\"t\":2,\"n\":\"Signature\"},{\"t\":3,\"n\":\"Data Size\"},{\"t\":3,\"n\":\"Record Flags\"},{\"t\":3,\"n\":\"FormID\"},{\"t\":11,\"n\":\"Version Control Info 1\"},{\"t\":3,\"n\":\"Form Version\"},{\"t\":11,\"n\":\"Version Control Info 2\"}]},{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"n\":\"VMAD - Virtual Machine Adapter\",\"c\":[{\"t\":3,\"n\":\"Version\"},{\"t\":3,\"n\":\"Object Format\"},{\"t\":12,\"n\":\"Data\",\"c\":[{\"t\":9,\"n\":\"Scripts\",\"c\":[{\"t\":6,\"n\":\"Script\",\"c\":[{\"t\":2,\"n\":\"scriptName\"},{\"t\":3,\"n\":\"Flags\"},{\"t\":9,\"n\":\"Properties\",\"c\":[{\"t\":6,\"n\":\"Property\",\"c\":[{\"t\":2,\"n\":\"propertyName\"},{\"t\":3,\"n\":\"Type\"},{\"t\":3,\"n\":\"Flags\"},{\"t\":12,\"n\":\"Value\"}]}]}]}]}]}]},{\"t\":6,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"n\":\"X1\"},{\"t\":3,\"n\":\"Y1\"},{\"t\":3,\"n\":\"Z1\"},{\"t\":3,\"n\":\"X2\"},{\"t\":3,\"n\":\"Y2\"},{\"t\":3,\"n\":\"Z2\"}]},{\"t\":2,\"n\":\"FULL - Name\"},{\"t\":6,\"n\":\"Model\",\"c\":[{\"t\":2,\"n\":\"MODL - Model Filename\"}]},{\"t\":3,\"n\":\"COCT - Count\"},{\"t\":10,\"p\":1,\"n\":\"Items\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Item\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"CNTO - Item\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Item\"},{\"t\":3,\"p\":1,\"n\":\"Count\"}]}]}]},{\"t\":6,\"n\":\"Destructable\",\"c\":[{\"t\":6,\"n\":\"DEST - Header\",\"c\":[{\"t\":3,\"n\":\"Health\"},{\"t\":3,\"n\":\"DEST Count\"},{\"t\":3,\"n\":\"VATS Targetable\"},{\"t\":11,\"n\":\"Unknown\"}]}]},{\"t\":6,\"n\":\"DATA - \",\"c\":[{\"t\":3,\"n\":\"Flags\"},{\"t\":5,\"n\":\"Weight\"}]},{\"t\":3,\"n\":\"SNAM - Sound - Open\"},{\"t\":3,\"n\":\"QNAM - Sound - Close\"}]}]},\"name\":\"Bash.Invent\",\"hash\":\"$7F0C9C4C\",\"color\":255}"
  },
  {
    "path": "frontend/settings/Skyrim/Bash.Lev.json",
    "content": "{\"records\":\"LVLI,LVSP,LVLN\",\"description\":\"Base setting for Wrye Bash's leveled list handling.\\r\\n\\r\\nWhen used, leveled list entries will be merged.\",\"tree\":{\"records\":[{\"t\":1,\"p\":1,\"n\":\"LVLI - Leveled Item\",\"c\":[{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"n\":\"X1\"},{\"t\":3,\"n\":\"Y1\"},{\"t\":3,\"n\":\"Z1\"},{\"t\":3,\"n\":\"X2\"},{\"t\":3,\"n\":\"Y2\"},{\"t\":3,\"n\":\"Z2\"}]},{\"t\":3,\"n\":\"LVLD - Chance None\"},{\"t\":3,\"n\":\"LVLF - Flags\"},{\"t\":3,\"n\":\"LVLG - Global\"},{\"t\":3,\"n\":\"LLCT - Count\"},{\"t\":10,\"p\":1,\"n\":\"Leveled List Entries\",\"c\":[{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Leveled List Entry\",\"c\":[{\"t\":6,\"n\":\"LVLO - Base Data\",\"c\":[{\"t\":3,\"n\":\"Level\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":3,\"n\":\"Reference\"},{\"t\":3,\"n\":\"Count\"}]},{\"t\":6,\"n\":\"COED - Extra Data\",\"c\":[{\"t\":3,\"n\":\"Owner\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":3,\"n\":\"Global Variable\"},{\"t\":3,\"n\":\"Required Rank\"},{\"t\":5,\"n\":\"Item Condition\"}]}]}]}]},{\"t\":1,\"p\":1,\"n\":\"LVSP - Leveled Spell\",\"c\":[{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"n\":\"X1\"},{\"t\":3,\"n\":\"Y1\"},{\"t\":3,\"n\":\"Z1\"},{\"t\":3,\"n\":\"X2\"},{\"t\":3,\"n\":\"Y2\"},{\"t\":3,\"n\":\"Z2\"}]},{\"t\":3,\"n\":\"LVLD - Chance None\"},{\"t\":3,\"n\":\"LVLF - Flags\"},{\"t\":3,\"n\":\"LLCT - Count\"},{\"t\":10,\"p\":1,\"n\":\"Leveled List Entries\",\"c\":[{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Leveled List Entry\",\"c\":[{\"t\":6,\"n\":\"LVLO - Base Data\",\"c\":[{\"t\":3,\"n\":\"Level\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":3,\"n\":\"Reference\"},{\"t\":3,\"n\":\"Count\"}]}]}]}]},{\"t\":1,\"p\":1,\"n\":\"LVLN - Leveled NPC\",\"c\":[{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"n\":\"X1\"},{\"t\":3,\"n\":\"Y1\"},{\"t\":3,\"n\":\"Z1\"},{\"t\":3,\"n\":\"X2\"},{\"t\":3,\"n\":\"Y2\"},{\"t\":3,\"n\":\"Z2\"}]},{\"t\":3,\"n\":\"LVLD - Chance None\"},{\"t\":3,\"n\":\"LVLF - Flags\"},{\"t\":3,\"n\":\"LVLG - Global\"},{\"t\":3,\"n\":\"LLCT - Count\"},{\"t\":10,\"p\":1,\"n\":\"Leveled List Entries\",\"c\":[{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Leveled List Entry\",\"c\":[{\"t\":6,\"n\":\"LVLO - Base Data\",\"c\":[{\"t\":3,\"n\":\"Level\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":3,\"n\":\"Reference\"},{\"t\":3,\"n\":\"Count\"}]},{\"t\":6,\"n\":\"COED - Extra Data\",\"c\":[{\"t\":3,\"n\":\"Owner\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":3,\"n\":\"Global Variable\"},{\"t\":3,\"n\":\"Required Rank\"},{\"t\":5,\"n\":\"Item Condition\"}]}]}]},{\"t\":6,\"n\":\"Model\",\"c\":[{\"t\":2,\"n\":\"MODL - Model Filename\"},{\"t\":11,\"n\":\"MODT - Texture Files Hashes\"},{\"t\":7,\"n\":\"MODS - Alternate Textures\",\"c\":[{\"t\":6,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"n\":\"3D Name\"},{\"t\":3,\"n\":\"New Texture\"},{\"t\":3,\"n\":\"3D Index\"}]}]}]}]}]},\"name\":\"Bash.Lev\",\"hash\":\"E5E41BEB\",\"color\":255}"
  },
  {
    "path": "frontend/settings/Skyrim/Bash.NPC.Class.json",
    "content": "{\"records\":\"NPC_\",\"description\":\"NPC.Class tag from Wrye Bash.\\r\\n\\r\\nUsed when the mod changes the classes of NPCs.\",\"tree\":{\"records\":[{\"t\":1,\"p\":1,\"n\":\"NPC_ - Non-Player Character (Actor)\",\"c\":[{\"t\":6,\"n\":\"Record Header\",\"c\":[{\"t\":2,\"n\":\"Signature\"},{\"t\":3,\"n\":\"Data Size\"},{\"t\":3,\"n\":\"Record Flags\"},{\"t\":3,\"n\":\"FormID\"},{\"t\":11,\"n\":\"Version Control Info 1\"},{\"t\":3,\"n\":\"Form Version\"},{\"t\":11,\"n\":\"Version Control Info 2\"}]},{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"n\":\"VMAD - Virtual Machine Adapter\",\"c\":[{\"t\":3,\"n\":\"Version\"},{\"t\":3,\"n\":\"Object Format\"},{\"t\":12,\"n\":\"Data\",\"c\":[{\"t\":9,\"n\":\"Scripts\",\"c\":[{\"t\":6,\"n\":\"Script\",\"c\":[{\"t\":2,\"n\":\"scriptName\"},{\"t\":3,\"n\":\"Flags\"},{\"t\":9,\"n\":\"Properties\",\"c\":[{\"t\":6,\"n\":\"Property\",\"c\":[{\"t\":2,\"n\":\"propertyName\"},{\"t\":3,\"n\":\"Type\"},{\"t\":3,\"n\":\"Flags\"},{\"t\":12,\"n\":\"Value\"}]}]}]}]}]}]},{\"t\":6,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"n\":\"X1\"},{\"t\":3,\"n\":\"Y1\"},{\"t\":3,\"n\":\"Z1\"},{\"t\":3,\"n\":\"X2\"},{\"t\":3,\"n\":\"Y2\"},{\"t\":3,\"n\":\"Z2\"}]},{\"t\":6,\"n\":\"ACBS - Configuration\",\"c\":[{\"t\":3,\"n\":\"Flags\"},{\"t\":3,\"n\":\"Magicka Offset\"},{\"t\":3,\"n\":\"Stamina Offset\"},{\"t\":12,\"n\":\"Level\"},{\"t\":3,\"n\":\"Calc min level\"},{\"t\":3,\"n\":\"Calc max level\"},{\"t\":3,\"n\":\"Speed Multiplier\"},{\"t\":3,\"n\":\"Disposition Base (unused)\"},{\"t\":3,\"n\":\"Template Flags\"},{\"t\":3,\"n\":\"Health Offset\"},{\"t\":3,\"n\":\"Bleedout Override\"}]},{\"t\":10,\"n\":\"Factions\",\"c\":[{\"t\":6,\"n\":\"SNAM - Faction\",\"c\":[{\"t\":3,\"n\":\"Faction\"},{\"t\":3,\"n\":\"Rank\"},{\"t\":11,\"n\":\"Unused\"}]}]},{\"t\":3,\"n\":\"INAM - Death item\"},{\"t\":3,\"n\":\"VTCK - Voice\"},{\"t\":3,\"n\":\"TPLT - Template\"},{\"t\":3,\"n\":\"RNAM - Race\"},{\"t\":3,\"n\":\"SPCT - Count\"},{\"t\":9,\"n\":\"Actor Effects\",\"c\":[{\"t\":3,\"n\":\"SPLO - Actor Effect\"}]},{\"t\":6,\"n\":\"Destructable\",\"c\":[{\"t\":6,\"n\":\"DEST - Header\",\"c\":[{\"t\":3,\"n\":\"Health\"},{\"t\":3,\"n\":\"DEST Count\"},{\"t\":3,\"n\":\"VATS Targetable\"},{\"t\":11,\"n\":\"Unknown\"}]}]},{\"t\":3,\"n\":\"WNAM - Worn Armor\"},{\"t\":3,\"n\":\"ANAM - Far away model\"},{\"t\":3,\"n\":\"ATKR - Attack Race\"},{\"t\":10,\"n\":\"Attacks\",\"c\":[{\"t\":6,\"n\":\"Attack\",\"c\":[{\"t\":6,\"n\":\"ATKD - Attack Data\",\"c\":[{\"t\":5,\"n\":\"Damage Mult\"},{\"t\":5,\"n\":\"Attack Chance\"},{\"t\":3,\"n\":\"Attack Spell\"},{\"t\":3,\"n\":\"Attack Flags\"},{\"t\":5,\"n\":\"Attack Angle\"},{\"t\":5,\"n\":\"Strike Angle\"},{\"t\":5,\"n\":\"Stagger\"},{\"t\":3,\"n\":\"Attack Type\"},{\"t\":5,\"n\":\"Knockdown\"},{\"t\":5,\"n\":\"Recovery Time\"},{\"t\":5,\"n\":\"Stamina Mult\"}]}]}]},{\"t\":3,\"n\":\"SPOR - Spectator override package list\"},{\"t\":3,\"n\":\"OCOR - Observe dead body override package list\"},{\"t\":3,\"n\":\"GWOR - Guard warn override package list\"},{\"t\":3,\"n\":\"ECOR - Combat override package list\"},{\"t\":3,\"n\":\"PRKZ - Perk Count\"},{\"t\":10,\"n\":\"Perks\",\"c\":[{\"t\":6,\"n\":\"PRKR - Perk\",\"c\":[{\"t\":3,\"n\":\"Perk\"},{\"t\":3,\"n\":\"Rank\"},{\"t\":11,\"n\":\"Unused\"}]}]},{\"t\":3,\"n\":\"COCT - Count\"},{\"t\":10,\"n\":\"Items\",\"c\":[{\"t\":6,\"n\":\"Item\",\"c\":[{\"t\":6,\"n\":\"CNTO - Item\",\"c\":[{\"t\":3,\"n\":\"Item\"},{\"t\":3,\"n\":\"Count\"}]}]}]},{\"t\":6,\"n\":\"AIDT - AI Data\",\"c\":[{\"t\":3,\"n\":\"Aggression\"},{\"t\":3,\"n\":\"Confidence\"},{\"t\":3,\"n\":\"Energy Level\"},{\"t\":3,\"n\":\"Responsibility\"},{\"t\":3,\"n\":\"Mood\"},{\"t\":3,\"n\":\"Assistance\"},{\"t\":6,\"n\":\"Aggro\",\"c\":[{\"t\":3,\"n\":\"Aggro Radius Behavior\"},{\"t\":3,\"n\":\"Unknown\"},{\"t\":3,\"n\":\"Warn\"},{\"t\":3,\"n\":\"Warn\\/Attack\"},{\"t\":3,\"n\":\"Attack\"}]}]},{\"t\":7,\"n\":\"Packages\",\"c\":[{\"t\":3,\"n\":\"PKID - Package\"}]},{\"t\":3,\"n\":\"KSIZ - Keyword Count\"},{\"t\":9,\"n\":\"KWDA - Keywords\",\"c\":[{\"t\":3,\"n\":\"Keyword\"}]},{\"t\":3,\"p\":1,\"n\":\"CNAM - Class\"},{\"t\":2,\"n\":\"FULL - Name\"},{\"t\":2,\"n\":\"SHRT - Short Name\"},{\"t\":11,\"n\":\"DATA - Marker\"},{\"t\":6,\"n\":\"DNAM - Player Skills\",\"c\":[{\"t\":7,\"n\":\"Skill Values\",\"c\":[{\"t\":3,\"n\":\"Skill #0 (OneHanded)\"},{\"t\":3,\"n\":\"Skill #1 (TwoHanded)\"},{\"t\":3,\"n\":\"Skill #2 (Marksman)\"},{\"t\":3,\"n\":\"Skill #3 (Block)\"},{\"t\":3,\"n\":\"Skill #4 (Smithing)\"},{\"t\":3,\"n\":\"Skill #5 (HeavyArmor)\"},{\"t\":3,\"n\":\"Skill #6 (LightArmor)\"},{\"t\":3,\"n\":\"Skill #7 (Pickpocket)\"},{\"t\":3,\"n\":\"Skill #8 (Lockpicking)\"},{\"t\":3,\"n\":\"Skill #9 (Sneak)\"},{\"t\":3,\"n\":\"Skill #10 (Alchemy)\"},{\"t\":3,\"n\":\"Skill #11 (Speechcraft)\"},{\"t\":3,\"n\":\"Skill #12 (Alteration)\"},{\"t\":3,\"n\":\"Skill #13 (Conjuration)\"},{\"t\":3,\"n\":\"Skill #14 (Destruction)\"},{\"t\":3,\"n\":\"Skill #15 (Illusion)\"},{\"t\":3,\"n\":\"Skill #16 (Restoration)\"},{\"t\":3,\"n\":\"Skill #17 (Enchanting)\"}]},{\"t\":7,\"n\":\"Skill Offsets\",\"c\":[{\"t\":3,\"n\":\"Skill #0 (OneHanded)\"},{\"t\":3,\"n\":\"Skill #1 (TwoHanded)\"},{\"t\":3,\"n\":\"Skill #2 (Marksman)\"},{\"t\":3,\"n\":\"Skill #3 (Block)\"},{\"t\":3,\"n\":\"Skill #4 (Smithing)\"},{\"t\":3,\"n\":\"Skill #5 (HeavyArmor)\"},{\"t\":3,\"n\":\"Skill #6 (LightArmor)\"},{\"t\":3,\"n\":\"Skill #7 (Pickpocket)\"},{\"t\":3,\"n\":\"Skill #8 (Lockpicking)\"},{\"t\":3,\"n\":\"Skill #9 (Sneak)\"},{\"t\":3,\"n\":\"Skill #10 (Alchemy)\"},{\"t\":3,\"n\":\"Skill #11 (Speechcraft)\"},{\"t\":3,\"n\":\"Skill #12 (Alteration)\"},{\"t\":3,\"n\":\"Skill #13 (Conjuration)\"},{\"t\":3,\"n\":\"Skill #14 (Destruction)\"},{\"t\":3,\"n\":\"Skill #15 (Illusion)\"},{\"t\":3,\"n\":\"Skill #16 (Restoration)\"},{\"t\":3,\"n\":\"Skill #17 (Enchanting)\"}]},{\"t\":3,\"n\":\"Health\"},{\"t\":3,\"n\":\"Magicka\"},{\"t\":3,\"n\":\"Stamina\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":5,\"n\":\"Far away model distance\"},{\"t\":3,\"n\":\"Geared up weapons\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":9,\"n\":\"Head Parts\",\"c\":[{\"t\":3,\"n\":\"PNAM - Head Part\"}]},{\"t\":3,\"n\":\"HCLF - Hair Color\"},{\"t\":3,\"n\":\"ZNAM - Combat Style\"},{\"t\":3,\"n\":\"GNAM - Gift Filter\"},{\"t\":11,\"n\":\"NAM5 - Unknown\"},{\"t\":5,\"n\":\"NAM6 - Height\"},{\"t\":5,\"n\":\"NAM7 - Weight\"},{\"t\":3,\"n\":\"NAM8 - Sound Level\"},{\"t\":10,\"n\":\"Sound Types\",\"c\":[{\"t\":6,\"n\":\"Sound Type\",\"c\":[{\"t\":3,\"n\":\"CSDT - Type\"},{\"t\":10,\"n\":\"Sounds\",\"c\":[{\"t\":6,\"n\":\"Sound\",\"c\":[{\"t\":3,\"n\":\"CSDI - Sound\"},{\"t\":3,\"n\":\"CSDC - Sound Chance\"}]}]}]}]},{\"t\":3,\"n\":\"CSCR - Inherits Sounds From\"},{\"t\":3,\"n\":\"DOFT - Default outfit\"},{\"t\":3,\"n\":\"SOFT - Sleeping outfit\"},{\"t\":3,\"n\":\"DPLT - Default Package List\"},{\"t\":3,\"n\":\"CRIF - Crime faction\"},{\"t\":3,\"n\":\"FTST - Head texture\"},{\"t\":6,\"n\":\"QNAM - Texture lighting\",\"c\":[{\"t\":5,\"n\":\"Red\"},{\"t\":5,\"n\":\"Green\"},{\"t\":5,\"n\":\"Blue\"}]},{\"t\":6,\"n\":\"NAM9 - Face morph\",\"c\":[{\"t\":5,\"n\":\"Nose Long\\/Short\"},{\"t\":5,\"n\":\"Nose Up\\/Down\"},{\"t\":5,\"n\":\"Jaw Up\\/Down\"},{\"t\":5,\"n\":\"Jaw Narrow\\/Wide\"},{\"t\":5,\"n\":\"Jaw Farward\\/Back\"},{\"t\":5,\"n\":\"Cheeks Up\\/Down\"},{\"t\":5,\"n\":\"Cheeks Farward\\/Back\"},{\"t\":5,\"n\":\"Eyes Up\\/Down\"},{\"t\":5,\"n\":\"Eyes In\\/Out\"},{\"t\":5,\"n\":\"Brows Up\\/Down\"},{\"t\":5,\"n\":\"Brows In\\/Out\"},{\"t\":5,\"n\":\"Brows Farward\\/Back\"},{\"t\":5,\"n\":\"Lips Up\\/Down\"},{\"t\":5,\"n\":\"Lips In\\/Out\"},{\"t\":5,\"n\":\"Chin Narrow\\/Wide\"},{\"t\":5,\"n\":\"Chin Up\\/Down\"},{\"t\":5,\"n\":\"Chin Underbite\\/Overbite\"},{\"t\":5,\"n\":\"Eyes Farward\\/Back\"},{\"t\":5,\"n\":\"Unknown\"}]},{\"t\":6,\"n\":\"NAMA - Face parts\",\"c\":[{\"t\":3,\"n\":\"Nose\"},{\"t\":3,\"n\":\"Unknown\"},{\"t\":3,\"n\":\"Eyes\"},{\"t\":3,\"n\":\"Mouth\"}]},{\"t\":10,\"n\":\"Tint Layers\",\"c\":[{\"t\":6,\"n\":\"Layer\",\"c\":[{\"t\":3,\"n\":\"TINI - Tint Index\"}]}]}]}]},\"name\":\"Bash.NPC.Class\",\"hash\":\"$0B2151B6\",\"color\":255}"
  },
  {
    "path": "frontend/settings/Skyrim/Bash.NPC.Race.json",
    "content": "{\"records\":\"NPC_\",\"description\":\"NPC.Race tag from Wrye Bash.\\r\\n\\r\\nUsed when the mod modifies NPC races.\",\"tree\":{\"records\":[{\"t\":1,\"p\":1,\"n\":\"NPC_ - Non-Player Character (Actor)\",\"c\":[{\"t\":6,\"n\":\"Record Header\",\"c\":[{\"t\":2,\"n\":\"Signature\"},{\"t\":3,\"n\":\"Data Size\"},{\"t\":3,\"n\":\"Record Flags\"},{\"t\":3,\"n\":\"FormID\"},{\"t\":11,\"n\":\"Version Control Info 1\"},{\"t\":3,\"n\":\"Form Version\"},{\"t\":11,\"n\":\"Version Control Info 2\"}]},{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"n\":\"VMAD - Virtual Machine Adapter\",\"c\":[{\"t\":3,\"n\":\"Version\"},{\"t\":3,\"n\":\"Object Format\"},{\"t\":12,\"n\":\"Data\",\"c\":[{\"t\":9,\"n\":\"Scripts\",\"c\":[{\"t\":6,\"n\":\"Script\",\"c\":[{\"t\":2,\"n\":\"scriptName\"},{\"t\":3,\"n\":\"Flags\"},{\"t\":9,\"n\":\"Properties\",\"c\":[{\"t\":6,\"n\":\"Property\",\"c\":[{\"t\":2,\"n\":\"propertyName\"},{\"t\":3,\"n\":\"Type\"},{\"t\":3,\"n\":\"Flags\"},{\"t\":12,\"n\":\"Value\"}]}]}]}]}]}]},{\"t\":6,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"n\":\"X1\"},{\"t\":3,\"n\":\"Y1\"},{\"t\":3,\"n\":\"Z1\"},{\"t\":3,\"n\":\"X2\"},{\"t\":3,\"n\":\"Y2\"},{\"t\":3,\"n\":\"Z2\"}]},{\"t\":6,\"n\":\"ACBS - Configuration\",\"c\":[{\"t\":3,\"n\":\"Flags\"},{\"t\":3,\"n\":\"Magicka Offset\"},{\"t\":3,\"n\":\"Stamina Offset\"},{\"t\":12,\"n\":\"Level\"},{\"t\":3,\"n\":\"Calc min level\"},{\"t\":3,\"n\":\"Calc max level\"},{\"t\":3,\"n\":\"Speed Multiplier\"},{\"t\":3,\"n\":\"Disposition Base (unused)\"},{\"t\":3,\"n\":\"Template Flags\"},{\"t\":3,\"n\":\"Health Offset\"},{\"t\":3,\"n\":\"Bleedout Override\"}]},{\"t\":10,\"n\":\"Factions\",\"c\":[{\"t\":6,\"n\":\"SNAM - Faction\",\"c\":[{\"t\":3,\"n\":\"Faction\"},{\"t\":3,\"n\":\"Rank\"},{\"t\":11,\"n\":\"Unused\"}]}]},{\"t\":3,\"n\":\"INAM - Death item\"},{\"t\":3,\"n\":\"VTCK - Voice\"},{\"t\":3,\"n\":\"TPLT - Template\"},{\"t\":3,\"p\":1,\"n\":\"RNAM - Race\"},{\"t\":3,\"n\":\"SPCT - Count\"},{\"t\":9,\"n\":\"Actor Effects\",\"c\":[{\"t\":3,\"n\":\"SPLO - Actor Effect\"}]},{\"t\":6,\"n\":\"Destructable\",\"c\":[{\"t\":6,\"n\":\"DEST - Header\",\"c\":[{\"t\":3,\"n\":\"Health\"},{\"t\":3,\"n\":\"DEST Count\"},{\"t\":3,\"n\":\"VATS Targetable\"},{\"t\":11,\"n\":\"Unknown\"}]}]},{\"t\":3,\"n\":\"WNAM - Worn Armor\"},{\"t\":3,\"n\":\"ANAM - Far away model\"},{\"t\":3,\"n\":\"ATKR - Attack Race\"},{\"t\":10,\"n\":\"Attacks\",\"c\":[{\"t\":6,\"n\":\"Attack\",\"c\":[{\"t\":6,\"n\":\"ATKD - Attack Data\",\"c\":[{\"t\":5,\"n\":\"Damage Mult\"},{\"t\":5,\"n\":\"Attack Chance\"},{\"t\":3,\"n\":\"Attack Spell\"},{\"t\":3,\"n\":\"Attack Flags\"},{\"t\":5,\"n\":\"Attack Angle\"},{\"t\":5,\"n\":\"Strike Angle\"},{\"t\":5,\"n\":\"Stagger\"},{\"t\":3,\"n\":\"Attack Type\"},{\"t\":5,\"n\":\"Knockdown\"},{\"t\":5,\"n\":\"Recovery Time\"},{\"t\":5,\"n\":\"Stamina Mult\"}]}]}]},{\"t\":3,\"n\":\"SPOR - Spectator override package list\"},{\"t\":3,\"n\":\"OCOR - Observe dead body override package list\"},{\"t\":3,\"n\":\"GWOR - Guard warn override package list\"},{\"t\":3,\"n\":\"ECOR - Combat override package list\"},{\"t\":3,\"n\":\"PRKZ - Perk Count\"},{\"t\":10,\"n\":\"Perks\",\"c\":[{\"t\":6,\"n\":\"PRKR - Perk\",\"c\":[{\"t\":3,\"n\":\"Perk\"},{\"t\":3,\"n\":\"Rank\"},{\"t\":11,\"n\":\"Unused\"}]}]},{\"t\":3,\"n\":\"COCT - Count\"},{\"t\":10,\"n\":\"Items\",\"c\":[{\"t\":6,\"n\":\"Item\",\"c\":[{\"t\":6,\"n\":\"CNTO - Item\",\"c\":[{\"t\":3,\"n\":\"Item\"},{\"t\":3,\"n\":\"Count\"}]}]}]},{\"t\":6,\"n\":\"AIDT - AI Data\",\"c\":[{\"t\":3,\"n\":\"Aggression\"},{\"t\":3,\"n\":\"Confidence\"},{\"t\":3,\"n\":\"Energy Level\"},{\"t\":3,\"n\":\"Responsibility\"},{\"t\":3,\"n\":\"Mood\"},{\"t\":3,\"n\":\"Assistance\"},{\"t\":6,\"n\":\"Aggro\",\"c\":[{\"t\":3,\"n\":\"Aggro Radius Behavior\"},{\"t\":3,\"n\":\"Unknown\"},{\"t\":3,\"n\":\"Warn\"},{\"t\":3,\"n\":\"Warn\\/Attack\"},{\"t\":3,\"n\":\"Attack\"}]}]},{\"t\":7,\"n\":\"Packages\",\"c\":[{\"t\":3,\"n\":\"PKID - Package\"}]},{\"t\":3,\"n\":\"KSIZ - Keyword Count\"},{\"t\":9,\"n\":\"KWDA - Keywords\",\"c\":[{\"t\":3,\"n\":\"Keyword\"}]},{\"t\":3,\"n\":\"CNAM - Class\"},{\"t\":2,\"n\":\"FULL - Name\"},{\"t\":2,\"n\":\"SHRT - Short Name\"},{\"t\":11,\"n\":\"DATA - Marker\"},{\"t\":6,\"n\":\"DNAM - Player Skills\",\"c\":[{\"t\":7,\"n\":\"Skill Values\",\"c\":[{\"t\":3,\"n\":\"Skill #0 (OneHanded)\"},{\"t\":3,\"n\":\"Skill #1 (TwoHanded)\"},{\"t\":3,\"n\":\"Skill #2 (Marksman)\"},{\"t\":3,\"n\":\"Skill #3 (Block)\"},{\"t\":3,\"n\":\"Skill #4 (Smithing)\"},{\"t\":3,\"n\":\"Skill #5 (HeavyArmor)\"},{\"t\":3,\"n\":\"Skill #6 (LightArmor)\"},{\"t\":3,\"n\":\"Skill #7 (Pickpocket)\"},{\"t\":3,\"n\":\"Skill #8 (Lockpicking)\"},{\"t\":3,\"n\":\"Skill #9 (Sneak)\"},{\"t\":3,\"n\":\"Skill #10 (Alchemy)\"},{\"t\":3,\"n\":\"Skill #11 (Speechcraft)\"},{\"t\":3,\"n\":\"Skill #12 (Alteration)\"},{\"t\":3,\"n\":\"Skill #13 (Conjuration)\"},{\"t\":3,\"n\":\"Skill #14 (Destruction)\"},{\"t\":3,\"n\":\"Skill #15 (Illusion)\"},{\"t\":3,\"n\":\"Skill #16 (Restoration)\"},{\"t\":3,\"n\":\"Skill #17 (Enchanting)\"}]},{\"t\":7,\"n\":\"Skill Offsets\",\"c\":[{\"t\":3,\"n\":\"Skill #0 (OneHanded)\"},{\"t\":3,\"n\":\"Skill #1 (TwoHanded)\"},{\"t\":3,\"n\":\"Skill #2 (Marksman)\"},{\"t\":3,\"n\":\"Skill #3 (Block)\"},{\"t\":3,\"n\":\"Skill #4 (Smithing)\"},{\"t\":3,\"n\":\"Skill #5 (HeavyArmor)\"},{\"t\":3,\"n\":\"Skill #6 (LightArmor)\"},{\"t\":3,\"n\":\"Skill #7 (Pickpocket)\"},{\"t\":3,\"n\":\"Skill #8 (Lockpicking)\"},{\"t\":3,\"n\":\"Skill #9 (Sneak)\"},{\"t\":3,\"n\":\"Skill #10 (Alchemy)\"},{\"t\":3,\"n\":\"Skill #11 (Speechcraft)\"},{\"t\":3,\"n\":\"Skill #12 (Alteration)\"},{\"t\":3,\"n\":\"Skill #13 (Conjuration)\"},{\"t\":3,\"n\":\"Skill #14 (Destruction)\"},{\"t\":3,\"n\":\"Skill #15 (Illusion)\"},{\"t\":3,\"n\":\"Skill #16 (Restoration)\"},{\"t\":3,\"n\":\"Skill #17 (Enchanting)\"}]},{\"t\":3,\"n\":\"Health\"},{\"t\":3,\"n\":\"Magicka\"},{\"t\":3,\"n\":\"Stamina\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":5,\"n\":\"Far away model distance\"},{\"t\":3,\"n\":\"Geared up weapons\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":9,\"n\":\"Head Parts\",\"c\":[{\"t\":3,\"n\":\"PNAM - Head Part\"}]},{\"t\":3,\"n\":\"HCLF - Hair Color\"},{\"t\":3,\"n\":\"ZNAM - Combat Style\"},{\"t\":3,\"n\":\"GNAM - Gift Filter\"},{\"t\":11,\"n\":\"NAM5 - Unknown\"},{\"t\":5,\"n\":\"NAM6 - Height\"},{\"t\":5,\"n\":\"NAM7 - Weight\"},{\"t\":3,\"n\":\"NAM8 - Sound Level\"},{\"t\":10,\"n\":\"Sound Types\",\"c\":[{\"t\":6,\"n\":\"Sound Type\",\"c\":[{\"t\":3,\"n\":\"CSDT - Type\"},{\"t\":10,\"n\":\"Sounds\",\"c\":[{\"t\":6,\"n\":\"Sound\",\"c\":[{\"t\":3,\"n\":\"CSDI - Sound\"},{\"t\":3,\"n\":\"CSDC - Sound Chance\"}]}]}]}]},{\"t\":3,\"n\":\"CSCR - Inherits Sounds From\"},{\"t\":3,\"n\":\"DOFT - Default outfit\"},{\"t\":3,\"n\":\"SOFT - Sleeping outfit\"},{\"t\":3,\"n\":\"DPLT - Default Package List\"},{\"t\":3,\"n\":\"CRIF - Crime faction\"},{\"t\":3,\"n\":\"FTST - Head texture\"},{\"t\":6,\"n\":\"QNAM - Texture lighting\",\"c\":[{\"t\":5,\"n\":\"Red\"},{\"t\":5,\"n\":\"Green\"},{\"t\":5,\"n\":\"Blue\"}]},{\"t\":6,\"n\":\"NAM9 - Face morph\",\"c\":[{\"t\":5,\"n\":\"Nose Long\\/Short\"},{\"t\":5,\"n\":\"Nose Up\\/Down\"},{\"t\":5,\"n\":\"Jaw Up\\/Down\"},{\"t\":5,\"n\":\"Jaw Narrow\\/Wide\"},{\"t\":5,\"n\":\"Jaw Farward\\/Back\"},{\"t\":5,\"n\":\"Cheeks Up\\/Down\"},{\"t\":5,\"n\":\"Cheeks Farward\\/Back\"},{\"t\":5,\"n\":\"Eyes Up\\/Down\"},{\"t\":5,\"n\":\"Eyes In\\/Out\"},{\"t\":5,\"n\":\"Brows Up\\/Down\"},{\"t\":5,\"n\":\"Brows In\\/Out\"},{\"t\":5,\"n\":\"Brows Farward\\/Back\"},{\"t\":5,\"n\":\"Lips Up\\/Down\"},{\"t\":5,\"n\":\"Lips In\\/Out\"},{\"t\":5,\"n\":\"Chin Narrow\\/Wide\"},{\"t\":5,\"n\":\"Chin Up\\/Down\"},{\"t\":5,\"n\":\"Chin Underbite\\/Overbite\"},{\"t\":5,\"n\":\"Eyes Farward\\/Back\"},{\"t\":5,\"n\":\"Unknown\"}]},{\"t\":6,\"n\":\"NAMA - Face parts\",\"c\":[{\"t\":3,\"n\":\"Nose\"},{\"t\":3,\"n\":\"Unknown\"},{\"t\":3,\"n\":\"Eyes\"},{\"t\":3,\"n\":\"Mouth\"}]},{\"t\":10,\"n\":\"Tint Layers\",\"c\":[{\"t\":6,\"n\":\"Layer\",\"c\":[{\"t\":3,\"n\":\"TINI - Tint Index\"}]}]}]}]},\"name\":\"Bash.NPC.Race\",\"hash\":\"$1058B5BF\",\"color\":255}"
  },
  {
    "path": "frontend/settings/Skyrim/Bash.Names.json",
    "content": "{\"records\":\"ACTI,AMMO,ARMO,AVIF,BOOK,CLAS,CONT,DIAL,DOOR,ENCH,EXPL,FACT,FLOR,FURN,HAZD,HDPT,INGR,KEYM,LCTN,LIGH,MESG,MGEF,MISC,MSTT,NPC_,PERK,PROJ,QUST,RACE,REFR,SCRL,SHOU,SLGM,SNCT,SPEL,TREE,WATR,WEAP,WRLD,ALCH\",\"description\":\"Names tag from Wrye Bash.\\r\\n\\r\\nUsed when the mod changes the names of things.\",\"tree\":{\"records\":[{\"t\":1,\"p\":1,\"n\":\"ACTI - Activator\",\"c\":[{\"t\":6,\"n\":\"Record Header\",\"c\":[{\"t\":2,\"n\":\"Signature\"},{\"t\":3,\"n\":\"Data Size\"},{\"t\":3,\"n\":\"Record Flags\"},{\"t\":3,\"n\":\"FormID\"},{\"t\":11,\"n\":\"Version Control Info 1\"},{\"t\":3,\"n\":\"Form Version\"},{\"t\":11,\"n\":\"Version Control Info 2\"}]},{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"n\":\"VMAD - Virtual Machine Adapter\",\"c\":[{\"t\":3,\"n\":\"Version\"},{\"t\":3,\"n\":\"Object Format\"},{\"t\":12,\"n\":\"Data\",\"c\":[{\"t\":9,\"n\":\"Scripts\",\"c\":[{\"t\":6,\"n\":\"Script\",\"c\":[{\"t\":2,\"n\":\"scriptName\"},{\"t\":3,\"n\":\"Flags\"},{\"t\":9,\"n\":\"Properties\",\"c\":[{\"t\":6,\"n\":\"Property\",\"c\":[{\"t\":2,\"n\":\"propertyName\"},{\"t\":3,\"n\":\"Type\"},{\"t\":3,\"n\":\"Flags\"},{\"t\":12,\"n\":\"Value\"}]}]}]}]}]}]},{\"t\":6,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"n\":\"X1\"},{\"t\":3,\"n\":\"Y1\"},{\"t\":3,\"n\":\"Z1\"},{\"t\":3,\"n\":\"X2\"},{\"t\":3,\"n\":\"Y2\"},{\"t\":3,\"n\":\"Z2\"}]},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":6,\"n\":\"Model\",\"c\":[{\"t\":2,\"n\":\"MODL - Model Filename\"}]},{\"t\":6,\"n\":\"Destructable\",\"c\":[{\"t\":6,\"n\":\"DEST - Header\",\"c\":[{\"t\":3,\"n\":\"Health\"},{\"t\":3,\"n\":\"DEST Count\"},{\"t\":3,\"n\":\"VATS Targetable\"},{\"t\":11,\"n\":\"Unknown\"}]}]},{\"t\":3,\"n\":\"KSIZ - Keyword Count\"},{\"t\":9,\"n\":\"KWDA - Keywords\",\"c\":[{\"t\":3,\"n\":\"Keyword\"}]},{\"t\":6,\"n\":\"PNAM - Marker Color\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":3,\"n\":\"Unused\"}]},{\"t\":3,\"n\":\"SNAM - Sound - Looping\"},{\"t\":3,\"n\":\"VNAM - Sound - Activation\"},{\"t\":3,\"n\":\"WNAM - Water Type\"},{\"t\":2,\"n\":\"RNAM - Activate Text Override\"},{\"t\":3,\"n\":\"FNAM - Flags\"},{\"t\":3,\"n\":\"KNAM - Interaction Keyword\"}]},{\"t\":1,\"p\":1,\"n\":\"AMMO - Ammunition\",\"c\":[{\"t\":6,\"n\":\"Record Header\",\"c\":[{\"t\":2,\"n\":\"Signature\"},{\"t\":3,\"n\":\"Data Size\"},{\"t\":3,\"n\":\"Record Flags\"},{\"t\":3,\"n\":\"FormID\"},{\"t\":11,\"n\":\"Version Control Info 1\"},{\"t\":3,\"n\":\"Form Version\"},{\"t\":11,\"n\":\"Version Control Info 2\"}]},{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"n\":\"X1\"},{\"t\":3,\"n\":\"Y1\"},{\"t\":3,\"n\":\"Z1\"},{\"t\":3,\"n\":\"X2\"},{\"t\":3,\"n\":\"Y2\"},{\"t\":3,\"n\":\"Z2\"}]},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":6,\"n\":\"Model\",\"c\":[{\"t\":2,\"n\":\"MODL - Model Filename\"}]},{\"t\":6,\"n\":\"Icon\",\"c\":[{\"t\":2,\"n\":\"ICON - Large Icon filename\"}]},{\"t\":6,\"n\":\"Destructable\",\"c\":[{\"t\":6,\"n\":\"DEST - Header\",\"c\":[{\"t\":3,\"n\":\"Health\"},{\"t\":3,\"n\":\"DEST Count\"},{\"t\":3,\"n\":\"VATS Targetable\"},{\"t\":11,\"n\":\"Unknown\"}]}]},{\"t\":3,\"n\":\"YNAM - Sound - Pick Up\"},{\"t\":3,\"n\":\"ZNAM - Sound - Drop\"},{\"t\":2,\"n\":\"DESC - Description\"},{\"t\":3,\"n\":\"KSIZ - Keyword Count\"},{\"t\":9,\"n\":\"KWDA - Keywords\",\"c\":[{\"t\":3,\"n\":\"Keyword\"}]},{\"t\":6,\"n\":\"DATA - Data\",\"c\":[{\"t\":3,\"n\":\"Projectile\"},{\"t\":3,\"n\":\"Flags\"},{\"t\":5,\"n\":\"Damage\"},{\"t\":3,\"n\":\"Value\"}]},{\"t\":2,\"n\":\"ONAM - Short Name\"}]},{\"t\":1,\"p\":1,\"n\":\"ARMO - Armor\",\"c\":[{\"t\":6,\"n\":\"Record Header\",\"c\":[{\"t\":2,\"n\":\"Signature\"},{\"t\":3,\"n\":\"Data Size\"},{\"t\":3,\"n\":\"Record Flags\"},{\"t\":3,\"n\":\"FormID\"},{\"t\":11,\"n\":\"Version Control Info 1\"},{\"t\":3,\"n\":\"Form Version\"},{\"t\":11,\"n\":\"Version Control Info 2\"}]},{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"n\":\"VMAD - Virtual Machine Adapter\",\"c\":[{\"t\":3,\"n\":\"Version\"},{\"t\":3,\"n\":\"Object Format\"},{\"t\":12,\"n\":\"Data\",\"c\":[{\"t\":9,\"n\":\"Scripts\",\"c\":[{\"t\":6,\"n\":\"Script\",\"c\":[{\"t\":2,\"n\":\"scriptName\"},{\"t\":3,\"n\":\"Flags\"},{\"t\":9,\"n\":\"Properties\",\"c\":[{\"t\":6,\"n\":\"Property\",\"c\":[{\"t\":2,\"n\":\"propertyName\"},{\"t\":3,\"n\":\"Type\"},{\"t\":3,\"n\":\"Flags\"},{\"t\":12,\"n\":\"Value\"}]}]}]}]}]}]},{\"t\":6,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"n\":\"X1\"},{\"t\":3,\"n\":\"Y1\"},{\"t\":3,\"n\":\"Z1\"},{\"t\":3,\"n\":\"X2\"},{\"t\":3,\"n\":\"Y2\"},{\"t\":3,\"n\":\"Z2\"}]},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":3,\"n\":\"EITM - Object Effect\"},{\"t\":3,\"n\":\"EAMT - Enchantment Amount\"},{\"t\":6,\"n\":\"Male world model\",\"c\":[{\"t\":2,\"n\":\"MOD2 - Model Filename\"}]},{\"t\":6,\"n\":\"Icon\",\"c\":[{\"t\":2,\"n\":\"ICON - Large Icon filename\"}]},{\"t\":6,\"n\":\"Female world model\",\"c\":[{\"t\":2,\"n\":\"MOD4 - Model Filename\"}]},{\"t\":6,\"n\":\"Icon 2 (female)\",\"c\":[{\"t\":2,\"n\":\"ICO2 - Large Icon filename\"}]},{\"t\":6,\"n\":\"BOD2 - Biped Body Template\",\"c\":[{\"t\":3,\"n\":\"First Person Flags\"},{\"t\":3,\"n\":\"General Flags\"},{\"n\":\"Unused\"},{\"t\":3,\"n\":\"Armor Type\"}]},{\"t\":6,\"n\":\"Destructable\",\"c\":[{\"t\":6,\"n\":\"DEST - Header\",\"c\":[{\"t\":3,\"n\":\"Health\"},{\"t\":3,\"n\":\"DEST Count\"},{\"t\":3,\"n\":\"VATS Targetable\"},{\"t\":11,\"n\":\"Unknown\"}]}]},{\"t\":3,\"n\":\"YNAM - Sound - Pick Up\"},{\"t\":3,\"n\":\"ZNAM - Sound - Drop\"},{\"t\":2,\"n\":\"BMCT - Ragdoll Constraint Template\"},{\"t\":3,\"n\":\"ETYP - Equipment Type\"},{\"t\":3,\"n\":\"BIDS - Bash Impact Data Set\"},{\"t\":3,\"n\":\"BAMT - Alternate Block Material\"},{\"t\":3,\"n\":\"RNAM - Race\"},{\"t\":3,\"n\":\"KSIZ - Keyword Count\"},{\"t\":9,\"n\":\"KWDA - Keywords\",\"c\":[{\"t\":3,\"n\":\"Keyword\"}]},{\"t\":2,\"n\":\"DESC - Description\"},{\"t\":7,\"n\":\"Armature\",\"c\":[{\"t\":3,\"n\":\"MODL - Model Filename\"}]},{\"t\":6,\"n\":\"DATA - Data\",\"c\":[{\"t\":3,\"n\":\"Value\"},{\"t\":5,\"n\":\"Weight\"}]},{\"t\":3,\"n\":\"DNAM - Armor Rating\"},{\"t\":3,\"n\":\"TNAM - Template Armor\"}]},{\"t\":1,\"p\":1,\"n\":\"AVIF - Actor Value Information\",\"c\":[{\"t\":6,\"n\":\"Record Header\",\"c\":[{\"t\":2,\"n\":\"Signature\"},{\"t\":3,\"n\":\"Data Size\"},{\"t\":3,\"n\":\"Record Flags\"},{\"t\":3,\"n\":\"FormID\"},{\"t\":11,\"n\":\"Version Control Info 1\"},{\"t\":3,\"n\":\"Form Version\"},{\"t\":11,\"n\":\"Version Control Info 2\"}]},{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":2,\"n\":\"DESC - Description\"},{\"t\":2,\"n\":\"ANAM - Abbreviation\"},{\"t\":11,\"n\":\"CNAM - Unknown\"},{\"t\":6,\"n\":\"AVSK - Skill\",\"c\":[{\"t\":5,\"n\":\"Skill Use Mult\"},{\"t\":5,\"n\":\"Skill Offset Mult\"},{\"t\":5,\"n\":\"Skill Improve Mult\"},{\"t\":5,\"n\":\"Skill Improve Offset\"}]},{\"t\":8,\"n\":\"Perk Tree\",\"c\":[{\"t\":6,\"n\":\"Node\",\"c\":[{\"t\":3,\"n\":\"PNAM - Perk\"}]}]}]},{\"t\":1,\"p\":1,\"n\":\"BOOK - Book\",\"c\":[{\"t\":6,\"n\":\"Record Header\",\"c\":[{\"t\":2,\"n\":\"Signature\"},{\"t\":3,\"n\":\"Data Size\"},{\"t\":3,\"n\":\"Record Flags\"},{\"t\":3,\"n\":\"FormID\"},{\"t\":11,\"n\":\"Version Control Info 1\"},{\"t\":3,\"n\":\"Form Version\"},{\"t\":11,\"n\":\"Version Control Info 2\"}]},{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"n\":\"VMAD - Virtual Machine Adapter\",\"c\":[{\"t\":3,\"n\":\"Version\"},{\"t\":3,\"n\":\"Object Format\"},{\"t\":12,\"n\":\"Data\",\"c\":[{\"t\":9,\"n\":\"Scripts\",\"c\":[{\"t\":6,\"n\":\"Script\",\"c\":[{\"t\":2,\"n\":\"scriptName\"},{\"t\":3,\"n\":\"Flags\"},{\"t\":9,\"n\":\"Properties\",\"c\":[{\"t\":6,\"n\":\"Property\",\"c\":[{\"t\":2,\"n\":\"propertyName\"},{\"t\":3,\"n\":\"Type\"},{\"t\":3,\"n\":\"Flags\"},{\"t\":12,\"n\":\"Value\"}]}]}]}]}]}]},{\"t\":6,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"n\":\"X1\"},{\"t\":3,\"n\":\"Y1\"},{\"t\":3,\"n\":\"Z1\"},{\"t\":3,\"n\":\"X2\"},{\"t\":3,\"n\":\"Y2\"},{\"t\":3,\"n\":\"Z2\"}]},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":6,\"n\":\"Model\",\"c\":[{\"t\":2,\"n\":\"MODL - Model Filename\"}]},{\"t\":6,\"n\":\"Icon\",\"c\":[{\"t\":2,\"n\":\"ICON - Large Icon filename\"}]},{\"t\":2,\"n\":\"DESC - Book Text\"},{\"t\":6,\"n\":\"Destructable\",\"c\":[{\"t\":6,\"n\":\"DEST - Header\",\"c\":[{\"t\":3,\"n\":\"Health\"},{\"t\":3,\"n\":\"DEST Count\"},{\"t\":3,\"n\":\"VATS Targetable\"},{\"t\":11,\"n\":\"Unknown\"}]}]},{\"t\":3,\"n\":\"YNAM - Sound - Pick Up\"},{\"t\":3,\"n\":\"ZNAM - Sound - Drop\"},{\"t\":3,\"n\":\"KSIZ - Keyword Count\"},{\"t\":9,\"n\":\"KWDA - Keywords\",\"c\":[{\"t\":3,\"n\":\"Keyword\"}]},{\"t\":6,\"n\":\"DATA - Data\",\"c\":[{\"t\":3,\"n\":\"Flags\"},{\"t\":3,\"n\":\"Type\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":12,\"n\":\"Teaches\"},{\"t\":3,\"n\":\"Value\"},{\"t\":5,\"n\":\"Weight\"}]},{\"t\":3,\"n\":\"INAM - Inventory Art\"},{\"t\":2,\"n\":\"CNAM - Description\"}]},{\"t\":1,\"p\":1,\"n\":\"CLAS - Class\",\"c\":[{\"t\":6,\"n\":\"Record Header\",\"c\":[{\"t\":2,\"n\":\"Signature\"},{\"t\":3,\"n\":\"Data Size\"},{\"t\":3,\"n\":\"Record Flags\"},{\"t\":3,\"n\":\"FormID\"},{\"t\":11,\"n\":\"Version Control Info 1\"},{\"t\":3,\"n\":\"Form Version\"},{\"t\":11,\"n\":\"Version Control Info 2\"}]},{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":2,\"n\":\"DESC - Description\"},{\"t\":6,\"n\":\"Icon\",\"c\":[{\"t\":2,\"n\":\"ICON - Large Icon filename\"}]},{\"t\":6,\"n\":\"DATA - \",\"c\":[{\"t\":11,\"n\":\"Unknown\"},{\"t\":3,\"n\":\"Teaches\"},{\"t\":3,\"n\":\"Maximum training level\"},{\"t\":7,\"n\":\"Skill Weights\",\"c\":[{\"t\":3,\"n\":\"Weight #0 (One Handed)\"},{\"t\":3,\"n\":\"Weight #1 (Two Handed)\"},{\"t\":3,\"n\":\"Weight #2 (Archery)\"},{\"t\":3,\"n\":\"Weight #3 (Block)\"},{\"t\":3,\"n\":\"Weight #4 (Smithing)\"},{\"t\":3,\"n\":\"Weight #5 (Heavy Armor)\"},{\"t\":3,\"n\":\"Weight #6 (Light Armor)\"},{\"t\":3,\"n\":\"Weight #7 (Pickpocket)\"},{\"t\":3,\"n\":\"Weight #8 (Lockpicking)\"},{\"t\":3,\"n\":\"Weight #9 (Sneak)\"},{\"t\":3,\"n\":\"Weight #10 (Alchemy)\"},{\"t\":3,\"n\":\"Weight #11 (Speech)\"},{\"t\":3,\"n\":\"Weight #12 (Alteration)\"},{\"t\":3,\"n\":\"Weight #13 (Conjuration)\"},{\"t\":3,\"n\":\"Weight #14 (Destruction)\"},{\"t\":3,\"n\":\"Weight #15 (Illusion)\"},{\"t\":3,\"n\":\"Weight #16 (Restoration)\"},{\"t\":3,\"n\":\"Weight #17 (Enchanting)\"}]},{\"t\":5,\"n\":\"Bleedout Default\"},{\"t\":3,\"n\":\"Voice Points\"},{\"t\":7,\"n\":\"Attribute Weights\",\"c\":[{\"t\":3,\"n\":\"Weight #0 (Health)\"},{\"t\":3,\"n\":\"Weight #1 (Magicka)\"},{\"t\":3,\"n\":\"Weight #2 (Stamina)\"},{\"t\":3,\"n\":\"Weight #3 (Unknown)\"}]}]}]},{\"t\":1,\"p\":1,\"n\":\"CONT - Container\",\"c\":[{\"t\":6,\"n\":\"Record Header\",\"c\":[{\"t\":2,\"n\":\"Signature\"},{\"t\":3,\"n\":\"Data Size\"},{\"t\":3,\"n\":\"Record Flags\"},{\"t\":3,\"n\":\"FormID\"},{\"t\":11,\"n\":\"Version Control Info 1\"},{\"t\":3,\"n\":\"Form Version\"},{\"t\":11,\"n\":\"Version Control Info 2\"}]},{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"n\":\"VMAD - Virtual Machine Adapter\",\"c\":[{\"t\":3,\"n\":\"Version\"},{\"t\":3,\"n\":\"Object Format\"},{\"t\":12,\"n\":\"Data\",\"c\":[{\"t\":9,\"n\":\"Scripts\",\"c\":[{\"t\":6,\"n\":\"Script\",\"c\":[{\"t\":2,\"n\":\"scriptName\"},{\"t\":3,\"n\":\"Flags\"},{\"t\":9,\"n\":\"Properties\",\"c\":[{\"t\":6,\"n\":\"Property\",\"c\":[{\"t\":2,\"n\":\"propertyName\"},{\"t\":3,\"n\":\"Type\"},{\"t\":3,\"n\":\"Flags\"},{\"t\":12,\"n\":\"Value\"}]}]}]}]}]}]},{\"t\":6,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"n\":\"X1\"},{\"t\":3,\"n\":\"Y1\"},{\"t\":3,\"n\":\"Z1\"},{\"t\":3,\"n\":\"X2\"},{\"t\":3,\"n\":\"Y2\"},{\"t\":3,\"n\":\"Z2\"}]},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":6,\"n\":\"Model\",\"c\":[{\"t\":2,\"n\":\"MODL - Model Filename\"}]},{\"t\":3,\"n\":\"COCT - Count\"},{\"t\":10,\"n\":\"Items\",\"c\":[{\"t\":6,\"n\":\"Item\",\"c\":[{\"t\":6,\"n\":\"CNTO - Item\",\"c\":[{\"t\":3,\"n\":\"Item\"},{\"t\":3,\"n\":\"Count\"}]}]}]},{\"t\":6,\"n\":\"Destructable\",\"c\":[{\"t\":6,\"n\":\"DEST - Header\",\"c\":[{\"t\":3,\"n\":\"Health\"},{\"t\":3,\"n\":\"DEST Count\"},{\"t\":3,\"n\":\"VATS Targetable\"},{\"t\":11,\"n\":\"Unknown\"}]}]},{\"t\":6,\"n\":\"DATA - \",\"c\":[{\"t\":3,\"n\":\"Flags\"},{\"t\":5,\"n\":\"Weight\"}]},{\"t\":3,\"n\":\"SNAM - Sound - Open\"},{\"t\":3,\"n\":\"QNAM - Sound - Close\"}]},{\"t\":1,\"p\":1,\"n\":\"DIAL - Dialog Topic\",\"c\":[{\"t\":6,\"n\":\"Record Header\",\"c\":[{\"t\":2,\"n\":\"Signature\"},{\"t\":3,\"n\":\"Data Size\"},{\"t\":3,\"n\":\"Record Flags\"},{\"t\":3,\"n\":\"FormID\"},{\"t\":11,\"n\":\"Version Control Info 1\"},{\"t\":3,\"n\":\"Form Version\"},{\"t\":11,\"n\":\"Version Control Info 2\"}]},{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":5,\"n\":\"PNAM - Priority\"},{\"t\":3,\"n\":\"BNAM - Branch\"},{\"t\":3,\"n\":\"QNAM - Quest\"},{\"t\":6,\"n\":\"DATA - Data\",\"c\":[{\"t\":3,\"n\":\"Topic Flags\"},{\"t\":3,\"n\":\"Category\"},{\"t\":3,\"n\":\"Subtype\"}]},{\"t\":2,\"n\":\"SNAM - Subtype Name\"},{\"t\":3,\"n\":\"TIFC - Info Count\"}]},{\"t\":1,\"p\":1,\"n\":\"DOOR - Door\",\"c\":[{\"t\":6,\"n\":\"Record Header\",\"c\":[{\"t\":2,\"n\":\"Signature\"},{\"t\":3,\"n\":\"Data Size\"},{\"t\":3,\"n\":\"Record Flags\"},{\"t\":3,\"n\":\"FormID\"},{\"t\":11,\"n\":\"Version Control Info 1\"},{\"t\":3,\"n\":\"Form Version\"},{\"t\":11,\"n\":\"Version Control Info 2\"}]},{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"n\":\"VMAD - Virtual Machine Adapter\",\"c\":[{\"t\":3,\"n\":\"Version\"},{\"t\":3,\"n\":\"Object Format\"},{\"t\":12,\"n\":\"Data\",\"c\":[{\"t\":9,\"n\":\"Scripts\",\"c\":[{\"t\":6,\"n\":\"Script\",\"c\":[{\"t\":2,\"n\":\"scriptName\"},{\"t\":3,\"n\":\"Flags\"},{\"t\":9,\"n\":\"Properties\",\"c\":[{\"t\":6,\"n\":\"Property\",\"c\":[{\"t\":2,\"n\":\"propertyName\"},{\"t\":3,\"n\":\"Type\"},{\"t\":3,\"n\":\"Flags\"},{\"t\":12,\"n\":\"Value\"}]}]}]}]}]}]},{\"t\":6,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"n\":\"X1\"},{\"t\":3,\"n\":\"Y1\"},{\"t\":3,\"n\":\"Z1\"},{\"t\":3,\"n\":\"X2\"},{\"t\":3,\"n\":\"Y2\"},{\"t\":3,\"n\":\"Z2\"}]},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":6,\"n\":\"Model\",\"c\":[{\"t\":2,\"n\":\"MODL - Model Filename\"}]},{\"t\":6,\"n\":\"Destructable\",\"c\":[{\"t\":6,\"n\":\"DEST - Header\",\"c\":[{\"t\":3,\"n\":\"Health\"},{\"t\":3,\"n\":\"DEST Count\"},{\"t\":3,\"n\":\"VATS Targetable\"},{\"t\":11,\"n\":\"Unknown\"}]}]},{\"t\":3,\"n\":\"SNAM - Sound - Open\"},{\"t\":3,\"n\":\"ANAM - Sound - Close\"},{\"t\":3,\"n\":\"BNAM - Sound - Loop\"},{\"t\":3,\"n\":\"FNAM - Flags\"}]},{\"t\":1,\"p\":1,\"n\":\"ENCH - Object Effect\",\"c\":[{\"t\":6,\"n\":\"Record Header\",\"c\":[{\"t\":2,\"n\":\"Signature\"},{\"t\":3,\"n\":\"Data Size\"},{\"t\":3,\"n\":\"Record Flags\"},{\"t\":3,\"n\":\"FormID\"},{\"t\":11,\"n\":\"Version Control Info 1\"},{\"t\":3,\"n\":\"Form Version\"},{\"t\":11,\"n\":\"Version Control Info 2\"}]},{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"n\":\"X1\"},{\"t\":3,\"n\":\"Y1\"},{\"t\":3,\"n\":\"Z1\"},{\"t\":3,\"n\":\"X2\"},{\"t\":3,\"n\":\"Y2\"},{\"t\":3,\"n\":\"Z2\"}]},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":6,\"n\":\"ENIT - Effect Data\",\"c\":[{\"t\":3,\"n\":\"Enchantment Cost\"},{\"t\":3,\"n\":\"Flags\"},{\"t\":3,\"n\":\"Cast Type\"},{\"t\":3,\"n\":\"Enchantment Amount\"},{\"t\":3,\"n\":\"Target Type\"},{\"t\":3,\"n\":\"Enchant Type\"},{\"t\":5,\"n\":\"Charge Time\"},{\"t\":3,\"n\":\"Base Enchantment\"},{\"t\":3,\"n\":\"Worn Restrictions\"}]},{\"t\":8,\"n\":\"Effects\",\"c\":[{\"t\":6,\"n\":\"Effect\",\"c\":[{\"t\":3,\"n\":\"EFID - Base Effect\"},{\"t\":6,\"n\":\"EFIT - \",\"c\":[{\"t\":5,\"n\":\"Magnitude\"},{\"t\":3,\"n\":\"Area\"},{\"t\":3,\"n\":\"Duration\"}]}]}]}]},{\"t\":1,\"p\":1,\"n\":\"EXPL - Explosion\",\"c\":[{\"t\":6,\"n\":\"Record Header\",\"c\":[{\"t\":2,\"n\":\"Signature\"},{\"t\":3,\"n\":\"Data Size\"},{\"t\":3,\"n\":\"Record Flags\"},{\"t\":3,\"n\":\"FormID\"},{\"t\":11,\"n\":\"Version Control Info 1\"},{\"t\":3,\"n\":\"Form Version\"},{\"t\":11,\"n\":\"Version Control Info 2\"}]},{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"n\":\"X1\"},{\"t\":3,\"n\":\"Y1\"},{\"t\":3,\"n\":\"Z1\"},{\"t\":3,\"n\":\"X2\"},{\"t\":3,\"n\":\"Y2\"},{\"t\":3,\"n\":\"Z2\"}]},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":6,\"n\":\"Model\",\"c\":[{\"t\":2,\"n\":\"MODL - Model Filename\"}]},{\"t\":3,\"n\":\"EITM - Object Effect\"},{\"t\":3,\"n\":\"MNAM - Image Space Modifier\"},{\"t\":6,\"n\":\"DATA - Data\",\"c\":[{\"t\":3,\"n\":\"Light\"},{\"t\":3,\"n\":\"Sound 1\"},{\"t\":3,\"n\":\"Sound 2\"},{\"t\":3,\"n\":\"Impact Data Set\"},{\"t\":3,\"n\":\"Placed Object\"},{\"t\":3,\"n\":\"Spawn Projectile\"},{\"t\":5,\"n\":\"Force\"},{\"t\":5,\"n\":\"Damage\"},{\"t\":5,\"n\":\"Radius\"},{\"t\":5,\"n\":\"IS Radius\"},{\"t\":5,\"n\":\"Vertical Offset Mult\"},{\"t\":3,\"n\":\"Flags\"},{\"t\":3,\"n\":\"Sound Level\"}]}]},{\"t\":1,\"p\":1,\"n\":\"FACT - Faction\",\"c\":[{\"t\":6,\"n\":\"Record Header\",\"c\":[{\"t\":2,\"n\":\"Signature\"},{\"t\":3,\"n\":\"Data Size\"},{\"t\":3,\"n\":\"Record Flags\"},{\"t\":3,\"n\":\"FormID\"},{\"t\":11,\"n\":\"Version Control Info 1\"},{\"t\":3,\"n\":\"Form Version\"},{\"t\":11,\"n\":\"Version Control Info 2\"}]},{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":10,\"n\":\"Relations\",\"c\":[{\"t\":6,\"n\":\"XNAM - Relation\",\"c\":[{\"t\":3,\"n\":\"Faction\"},{\"t\":3,\"n\":\"Modifier\"},{\"t\":3,\"n\":\"Group Combat Reaction\"}]}]},{\"t\":6,\"n\":\"DATA - Flags\",\"c\":[{\"t\":3,\"n\":\"Flags\"}]},{\"t\":3,\"n\":\"JAIL - Exterior Jail Marker\"},{\"t\":3,\"n\":\"WAIT - Follower Wait Marker\"},{\"t\":3,\"n\":\"STOL - Stolen Goods Container\"},{\"t\":3,\"n\":\"PLCN - Player Inventory Container\"},{\"t\":3,\"n\":\"CRGR - Shared Crime Faction List\"},{\"t\":3,\"n\":\"JOUT - Jail Outfit\"},{\"t\":6,\"n\":\"CRVA - Crime Values\",\"c\":[{\"t\":3,\"n\":\"Arrest\"},{\"t\":3,\"n\":\"Attack On Sight\"},{\"t\":3,\"n\":\"Murder\"},{\"t\":3,\"n\":\"Assault\"},{\"t\":3,\"n\":\"Trespass\"},{\"t\":3,\"n\":\"Pickpocket\"},{\"t\":3,\"n\":\"Unknown\"},{\"t\":5,\"n\":\"Steal Multiplier\"},{\"t\":3,\"n\":\"Escape\"},{\"t\":3,\"n\":\"Werewolf\"}]},{\"t\":10,\"n\":\"Ranks\",\"c\":[{\"t\":6,\"n\":\"Rank\",\"c\":[{\"t\":3,\"n\":\"RNAM - Rank#\"}]}]},{\"t\":3,\"n\":\"VEND - Vendor Buy\\/Sell List\"},{\"t\":3,\"n\":\"VENC - Merchant Container\"},{\"t\":6,\"n\":\"VENV - Vendor Values\",\"c\":[{\"t\":3,\"n\":\"Start Hour\"},{\"t\":3,\"n\":\"End Hour\"},{\"t\":3,\"n\":\"Radius\"},{\"t\":11,\"n\":\"Unknown 1\"},{\"t\":3,\"n\":\"Only Buys Stolen Items\"},{\"t\":3,\"n\":\"Not\\/Sell Buy\"},{\"t\":11,\"n\":\"Unknown 2\"}]},{\"t\":6,\"n\":\"PLVD - Location\",\"c\":[{\"t\":3,\"n\":\"Type\"},{\"t\":12,\"n\":\"Location Value\"},{\"t\":3,\"n\":\"Radius\"}]},{\"t\":3,\"n\":\"CITC - Condition Count\"},{\"t\":8,\"n\":\"Conditions\",\"c\":[{\"t\":6,\"n\":\"Condition\",\"c\":[{\"t\":6,\"n\":\"CTDA - \",\"c\":[{\"t\":3,\"n\":\"Type\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":12,\"n\":\"Comparison Value\"},{\"t\":3,\"n\":\"Function\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":12,\"n\":\"Parameter #1\"},{\"t\":12,\"n\":\"Parameter #2\"},{\"t\":3,\"n\":\"Run On\"},{\"t\":12,\"n\":\"Reference\"},{\"t\":3,\"n\":\"Parameter #3\"}]}]}]}]},{\"t\":1,\"p\":1,\"n\":\"FLOR - Flora\",\"c\":[{\"t\":6,\"n\":\"Record Header\",\"c\":[{\"t\":2,\"n\":\"Signature\"},{\"t\":3,\"n\":\"Data Size\"},{\"t\":3,\"n\":\"Record Flags\"},{\"t\":3,\"n\":\"FormID\"},{\"t\":11,\"n\":\"Version Control Info 1\"},{\"t\":3,\"n\":\"Form Version\"},{\"t\":11,\"n\":\"Version Control Info 2\"}]},{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"n\":\"VMAD - Virtual Machine Adapter\",\"c\":[{\"t\":3,\"n\":\"Version\"},{\"t\":3,\"n\":\"Object Format\"},{\"t\":12,\"n\":\"Data\",\"c\":[{\"t\":9,\"n\":\"Scripts\",\"c\":[{\"t\":6,\"n\":\"Script\",\"c\":[{\"t\":2,\"n\":\"scriptName\"},{\"t\":3,\"n\":\"Flags\"},{\"t\":9,\"n\":\"Properties\",\"c\":[{\"t\":6,\"n\":\"Property\",\"c\":[{\"t\":2,\"n\":\"propertyName\"},{\"t\":3,\"n\":\"Type\"},{\"t\":3,\"n\":\"Flags\"},{\"t\":12,\"n\":\"Value\"}]}]}]}]}]}]},{\"t\":6,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"n\":\"X1\"},{\"t\":3,\"n\":\"Y1\"},{\"t\":3,\"n\":\"Z1\"},{\"t\":3,\"n\":\"X2\"},{\"t\":3,\"n\":\"Y2\"},{\"t\":3,\"n\":\"Z2\"}]},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":6,\"n\":\"Model\",\"c\":[{\"t\":2,\"n\":\"MODL - Model Filename\"}]},{\"t\":6,\"n\":\"Destructable\",\"c\":[{\"t\":6,\"n\":\"DEST - Header\",\"c\":[{\"t\":3,\"n\":\"Health\"},{\"t\":3,\"n\":\"DEST Count\"},{\"t\":3,\"n\":\"VATS Targetable\"},{\"t\":11,\"n\":\"Unknown\"}]}]},{\"t\":3,\"n\":\"KSIZ - Keyword Count\"},{\"t\":9,\"n\":\"KWDA - Keywords\",\"c\":[{\"t\":3,\"n\":\"Keyword\"}]},{\"t\":11,\"n\":\"PNAM - Unknown\"},{\"t\":2,\"n\":\"RNAM - Activate Text Override\"},{\"t\":11,\"n\":\"FNAM - Unknown\"},{\"t\":3,\"n\":\"PFIG - Ingredient\"},{\"t\":3,\"n\":\"SNAM - Sound\"},{\"t\":6,\"n\":\"PFPC - Seasonal ingredient production\",\"c\":[{\"t\":3,\"n\":\"Spring\"},{\"t\":3,\"n\":\"Summer \"},{\"t\":3,\"n\":\"Fall\"},{\"t\":3,\"n\":\"Winter\"}]}]},{\"t\":1,\"p\":1,\"n\":\"FURN - Furniture\",\"c\":[{\"t\":6,\"n\":\"Record Header\",\"c\":[{\"t\":2,\"n\":\"Signature\"},{\"t\":3,\"n\":\"Data Size\"},{\"t\":3,\"n\":\"Record Flags\"},{\"t\":3,\"n\":\"FormID\"},{\"t\":11,\"n\":\"Version Control Info 1\"},{\"t\":3,\"n\":\"Form Version\"},{\"t\":11,\"n\":\"Version Control Info 2\"}]},{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"n\":\"VMAD - Virtual Machine Adapter\",\"c\":[{\"t\":3,\"n\":\"Version\"},{\"t\":3,\"n\":\"Object Format\"},{\"t\":12,\"n\":\"Data\",\"c\":[{\"t\":9,\"n\":\"Scripts\",\"c\":[{\"t\":6,\"n\":\"Script\",\"c\":[{\"t\":2,\"n\":\"scriptName\"},{\"t\":3,\"n\":\"Flags\"},{\"t\":9,\"n\":\"Properties\",\"c\":[{\"t\":6,\"n\":\"Property\",\"c\":[{\"t\":2,\"n\":\"propertyName\"},{\"t\":3,\"n\":\"Type\"},{\"t\":3,\"n\":\"Flags\"},{\"t\":12,\"n\":\"Value\"}]}]}]}]}]}]},{\"t\":6,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"n\":\"X1\"},{\"t\":3,\"n\":\"Y1\"},{\"t\":3,\"n\":\"Z1\"},{\"t\":3,\"n\":\"X2\"},{\"t\":3,\"n\":\"Y2\"},{\"t\":3,\"n\":\"Z2\"}]},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":6,\"n\":\"Model\",\"c\":[{\"t\":2,\"n\":\"MODL - Model Filename\"}]},{\"t\":6,\"n\":\"Destructable\",\"c\":[{\"t\":6,\"n\":\"DEST - Header\",\"c\":[{\"t\":3,\"n\":\"Health\"},{\"t\":3,\"n\":\"DEST Count\"},{\"t\":3,\"n\":\"VATS Targetable\"},{\"t\":11,\"n\":\"Unknown\"}]}]},{\"t\":3,\"n\":\"KSIZ - Keyword Count\"},{\"t\":9,\"n\":\"KWDA - Keywords\",\"c\":[{\"t\":3,\"n\":\"Keyword\"}]},{\"t\":11,\"n\":\"PNAM - Unknown\"},{\"t\":3,\"n\":\"FNAM - Flags\"},{\"t\":3,\"n\":\"KNAM - Interaction Keyword\"},{\"t\":3,\"n\":\"MNAM - Active Markers \\/ Flags\"},{\"t\":6,\"n\":\"WBDT - Workbench Data\",\"c\":[{\"t\":3,\"n\":\"Bench Type\"},{\"t\":3,\"n\":\"Uses Skill\"}]},{\"t\":3,\"n\":\"NAM1 - Associated Spell\"},{\"t\":8,\"n\":\"Markers\",\"c\":[{\"t\":6,\"n\":\"Marker\",\"c\":[{\"t\":3,\"n\":\"ENAM - Marker Index\"}]}]},{\"t\":8,\"n\":\"Marker Entry Points\",\"c\":[{\"t\":6,\"n\":\"FNPR - Marker\",\"c\":[{\"t\":3,\"n\":\"Type\"},{\"t\":3,\"n\":\"Entry Points\"}]}]},{\"t\":2,\"n\":\"XMRK - Model Filename\"}]},{\"t\":1,\"p\":1,\"n\":\"HAZD - Hazard\",\"c\":[{\"t\":6,\"n\":\"Record Header\",\"c\":[{\"t\":2,\"n\":\"Signature\"},{\"t\":3,\"n\":\"Data Size\"},{\"t\":3,\"n\":\"Record Flags\"},{\"t\":3,\"n\":\"FormID\"},{\"t\":11,\"n\":\"Version Control Info 1\"},{\"t\":3,\"n\":\"Form Version\"},{\"t\":11,\"n\":\"Version Control Info 2\"}]},{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"n\":\"X1\"},{\"t\":3,\"n\":\"Y1\"},{\"t\":3,\"n\":\"Z1\"},{\"t\":3,\"n\":\"X2\"},{\"t\":3,\"n\":\"Y2\"},{\"t\":3,\"n\":\"Z2\"}]},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":6,\"n\":\"Model\",\"c\":[{\"t\":2,\"n\":\"MODL - Model Filename\"}]},{\"t\":3,\"n\":\"MNAM - Image Space Modifier\"},{\"t\":6,\"n\":\"DATA - Data\",\"c\":[{\"t\":3,\"n\":\"Limit\"},{\"t\":5,\"n\":\"Radius\"},{\"t\":5,\"n\":\"Lifetime\"},{\"t\":5,\"n\":\"Image Space Radius\"},{\"t\":5,\"n\":\"Target Interval\"},{\"t\":3,\"n\":\"Flags\"},{\"t\":3,\"n\":\"Spell\"},{\"t\":3,\"n\":\"Light\"},{\"t\":3,\"n\":\"Impact Data Set\"},{\"t\":3,\"n\":\"Sound\"}]}]},{\"t\":1,\"p\":1,\"n\":\"HDPT - Head Part\",\"c\":[{\"t\":6,\"n\":\"Record Header\",\"c\":[{\"t\":2,\"n\":\"Signature\"},{\"t\":3,\"n\":\"Data Size\"},{\"t\":3,\"n\":\"Record Flags\"},{\"t\":3,\"n\":\"FormID\"},{\"t\":11,\"n\":\"Version Control Info 1\"},{\"t\":3,\"n\":\"Form Version\"},{\"t\":11,\"n\":\"Version Control Info 2\"}]},{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":6,\"n\":\"Model\",\"c\":[{\"t\":2,\"n\":\"MODL - Model Filename\"}]},{\"t\":3,\"n\":\"DATA - Flags\"},{\"t\":3,\"n\":\"PNAM - Type\"},{\"t\":9,\"n\":\"Extra Parts\",\"c\":[{\"t\":3,\"n\":\"HNAM - Part\"}]},{\"t\":8,\"n\":\"Parts\",\"c\":[{\"t\":6,\"n\":\"Part\",\"c\":[{\"t\":3,\"n\":\"NAM0 - Part Type\"},{\"t\":2,\"n\":\"NAM1 - Filename\"}]}]},{\"t\":3,\"n\":\"TNAM - Texture Set\"},{\"t\":3,\"n\":\"CNAM - Color\"},{\"t\":3,\"n\":\"RNAM - Valid Races\"}]},{\"t\":1,\"p\":1,\"n\":\"INGR - Ingredient\",\"c\":[{\"t\":6,\"n\":\"Record Header\",\"c\":[{\"t\":2,\"n\":\"Signature\"},{\"t\":3,\"n\":\"Data Size\"},{\"t\":3,\"n\":\"Record Flags\"},{\"t\":3,\"n\":\"FormID\"},{\"t\":11,\"n\":\"Version Control Info 1\"},{\"t\":3,\"n\":\"Form Version\"},{\"t\":11,\"n\":\"Version Control Info 2\"}]},{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"n\":\"VMAD - Virtual Machine Adapter\",\"c\":[{\"t\":3,\"n\":\"Version\"},{\"t\":3,\"n\":\"Object Format\"},{\"t\":12,\"n\":\"Data\",\"c\":[{\"t\":9,\"n\":\"Scripts\",\"c\":[{\"t\":6,\"n\":\"Script\",\"c\":[{\"t\":2,\"n\":\"scriptName\"},{\"t\":3,\"n\":\"Flags\"},{\"t\":9,\"n\":\"Properties\",\"c\":[{\"t\":6,\"n\":\"Property\",\"c\":[{\"t\":2,\"n\":\"propertyName\"},{\"t\":3,\"n\":\"Type\"},{\"t\":3,\"n\":\"Flags\"},{\"t\":12,\"n\":\"Value\"}]}]}]}]}]}]},{\"t\":6,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"n\":\"X1\"},{\"t\":3,\"n\":\"Y1\"},{\"t\":3,\"n\":\"Z1\"},{\"t\":3,\"n\":\"X2\"},{\"t\":3,\"n\":\"Y2\"},{\"t\":3,\"n\":\"Z2\"}]},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":3,\"n\":\"KSIZ - Keyword Count\"},{\"t\":9,\"n\":\"KWDA - Keywords\",\"c\":[{\"t\":3,\"n\":\"Keyword\"}]},{\"t\":6,\"n\":\"Model\",\"c\":[{\"t\":2,\"n\":\"MODL - Model Filename\"}]},{\"t\":6,\"n\":\"Icon\",\"c\":[{\"t\":2,\"n\":\"ICON - Large Icon filename\"}]},{\"t\":6,\"n\":\"Destructable\",\"c\":[{\"t\":6,\"n\":\"DEST - Header\",\"c\":[{\"t\":3,\"n\":\"Health\"},{\"t\":3,\"n\":\"DEST Count\"},{\"t\":3,\"n\":\"VATS Targetable\"},{\"t\":11,\"n\":\"Unknown\"}]}]},{\"t\":3,\"n\":\"ETYP - Equipment Type\"},{\"t\":3,\"n\":\"YNAM - Sound - Pick Up\"},{\"t\":3,\"n\":\"ZNAM - Sound - Drop\"},{\"t\":6,\"n\":\"DATA - \",\"c\":[{\"t\":3,\"n\":\"Value\"},{\"t\":5,\"n\":\"Weight\"}]},{\"t\":6,\"n\":\"ENIT - Effect Data\",\"c\":[{\"t\":3,\"n\":\"Ingredient Value\"},{\"t\":3,\"n\":\"Flags\"}]},{\"t\":8,\"n\":\"Effects\",\"c\":[{\"t\":6,\"n\":\"Effect\",\"c\":[{\"t\":3,\"n\":\"EFID - Base Effect\"},{\"t\":6,\"n\":\"EFIT - \",\"c\":[{\"t\":5,\"n\":\"Magnitude\"},{\"t\":3,\"n\":\"Area\"},{\"t\":3,\"n\":\"Duration\"}]}]}]}]},{\"t\":1,\"p\":1,\"n\":\"KEYM - Key\",\"c\":[{\"t\":6,\"n\":\"Record Header\",\"c\":[{\"t\":2,\"n\":\"Signature\"},{\"t\":3,\"n\":\"Data Size\"},{\"t\":3,\"n\":\"Record Flags\"},{\"t\":3,\"n\":\"FormID\"},{\"t\":11,\"n\":\"Version Control Info 1\"},{\"t\":3,\"n\":\"Form Version\"},{\"t\":11,\"n\":\"Version Control Info 2\"}]},{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"n\":\"VMAD - Virtual Machine Adapter\",\"c\":[{\"t\":3,\"n\":\"Version\"},{\"t\":3,\"n\":\"Object Format\"},{\"t\":12,\"n\":\"Data\",\"c\":[{\"t\":9,\"n\":\"Scripts\",\"c\":[{\"t\":6,\"n\":\"Script\",\"c\":[{\"t\":2,\"n\":\"scriptName\"},{\"t\":3,\"n\":\"Flags\"},{\"t\":9,\"n\":\"Properties\",\"c\":[{\"t\":6,\"n\":\"Property\",\"c\":[{\"t\":2,\"n\":\"propertyName\"},{\"t\":3,\"n\":\"Type\"},{\"t\":3,\"n\":\"Flags\"},{\"t\":12,\"n\":\"Value\"}]}]}]}]}]}]},{\"t\":6,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"n\":\"X1\"},{\"t\":3,\"n\":\"Y1\"},{\"t\":3,\"n\":\"Z1\"},{\"t\":3,\"n\":\"X2\"},{\"t\":3,\"n\":\"Y2\"},{\"t\":3,\"n\":\"Z2\"}]},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":6,\"n\":\"Model\",\"c\":[{\"t\":2,\"n\":\"MODL - Model Filename\"}]},{\"t\":6,\"n\":\"Icon\",\"c\":[{\"t\":2,\"n\":\"ICON - Large Icon filename\"}]},{\"t\":6,\"n\":\"Destructable\",\"c\":[{\"t\":6,\"n\":\"DEST - Header\",\"c\":[{\"t\":3,\"n\":\"Health\"},{\"t\":3,\"n\":\"DEST Count\"},{\"t\":3,\"n\":\"VATS Targetable\"},{\"t\":11,\"n\":\"Unknown\"}]}]},{\"t\":3,\"n\":\"YNAM - Sound - Pick Up\"},{\"t\":3,\"n\":\"ZNAM - Sound - Drop\"},{\"t\":3,\"n\":\"KSIZ - Keyword Count\"},{\"t\":9,\"n\":\"KWDA - Keywords\",\"c\":[{\"t\":3,\"n\":\"Keyword\"}]},{\"t\":6,\"n\":\"DATA - \",\"c\":[{\"t\":3,\"n\":\"Value\"},{\"t\":5,\"n\":\"Weight\"}]}]},{\"t\":1,\"p\":1,\"n\":\"LCTN - Location\",\"c\":[{\"t\":6,\"n\":\"Record Header\",\"c\":[{\"t\":2,\"n\":\"Signature\"},{\"t\":3,\"n\":\"Data Size\"},{\"t\":3,\"n\":\"Record Flags\"},{\"t\":3,\"n\":\"FormID\"},{\"t\":11,\"n\":\"Version Control Info 1\"},{\"t\":3,\"n\":\"Form Version\"},{\"t\":11,\"n\":\"Version Control Info 2\"}]},{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":8,\"n\":\"ACPR - Actor Cell Persistent Reference\",\"c\":[{\"t\":6,\"n\":\" #0\",\"c\":[{\"t\":3,\"n\":\"Actor\"},{\"t\":3,\"n\":\"Location\"},{\"t\":3,\"n\":\"Grid Y\"},{\"t\":3,\"n\":\"Grid X\"}]}]},{\"t\":8,\"n\":\"LCPR - Location Cell Persistent Reference\",\"c\":[{\"t\":6,\"n\":\" #0\",\"c\":[{\"t\":3,\"n\":\"Actor\"},{\"t\":3,\"n\":\"Location\"},{\"t\":3,\"n\":\"Grid Y\"},{\"t\":3,\"n\":\"Grid X\"}]}]},{\"t\":7,\"n\":\"RCPR - Reference Cell Persistent Reference\",\"c\":[{\"t\":3,\"n\":\"Ref #0\"}]},{\"t\":8,\"n\":\"ACUN - Actor Cell Unique\",\"c\":[{\"t\":6,\"n\":\" #0\",\"c\":[{\"t\":3,\"n\":\"Actor\"},{\"t\":3,\"n\":\"Ref\"},{\"t\":3,\"n\":\"Location\"}]}]},{\"t\":8,\"n\":\"LCUN - Location Cell Unique\",\"c\":[{\"t\":6,\"n\":\" #0\",\"c\":[{\"t\":3,\"n\":\"Actor\"},{\"t\":3,\"n\":\"Ref\"},{\"t\":3,\"n\":\"Location\"}]}]},{\"t\":7,\"n\":\"RCUN - Reference Cell Unique\",\"c\":[{\"t\":3,\"n\":\"Actor #0\"}]},{\"t\":8,\"n\":\"ACSR - Actor Cell Static Reference\",\"c\":[{\"t\":6,\"n\":\" #0\",\"c\":[{\"t\":3,\"n\":\"Loc Ref Type\"},{\"t\":3,\"n\":\"Marker\"},{\"t\":3,\"n\":\"Location\"},{\"t\":3,\"n\":\"Grid Y\"},{\"t\":3,\"n\":\"Grid X\"}]}]},{\"t\":8,\"n\":\"LCSR - Location Cell Static Reference\",\"c\":[{\"t\":6,\"n\":\" #0\",\"c\":[{\"t\":3,\"n\":\"Loc Ref Type\"},{\"t\":3,\"n\":\"Marker\"},{\"t\":3,\"n\":\"Location\"},{\"t\":3,\"n\":\"Grid Y\"},{\"t\":3,\"n\":\"Grid X\"}]}]},{\"t\":7,\"n\":\"RCSR - Reference Cell Static Reference\",\"c\":[{\"t\":3,\"n\":\"Ref #0\"}]},{\"t\":8,\"n\":\"Actor Cell Encounter Cell\",\"c\":[{\"t\":6,\"n\":\"ACEC - Unknown\",\"c\":[{\"t\":3,\"n\":\"Location\"},{\"t\":8,\"n\":\"Coordinates\",\"c\":[{\"t\":6,\"n\":\" #0\",\"c\":[{\"t\":3,\"n\":\"Grid Y\"},{\"t\":3,\"n\":\"Grid X\"}]}]}]}]},{\"t\":8,\"n\":\"Location Cell Encounter Cell\",\"c\":[{\"t\":6,\"n\":\"LCEC - Unknown\",\"c\":[{\"t\":3,\"n\":\"Location\"},{\"t\":8,\"n\":\"Coordinates\",\"c\":[{\"t\":6,\"n\":\" #0\",\"c\":[{\"t\":3,\"n\":\"Grid Y\"},{\"t\":3,\"n\":\"Grid X\"}]}]}]}]},{\"t\":8,\"n\":\"Reference Cell Encounter Cell\",\"c\":[{\"t\":6,\"n\":\"RCEC - Unknown\",\"c\":[{\"t\":3,\"n\":\"Location\"},{\"t\":8,\"n\":\"Coordinates\",\"c\":[{\"t\":6,\"n\":\" #0\",\"c\":[{\"t\":3,\"n\":\"Grid Y\"},{\"t\":3,\"n\":\"Grid X\"}]}]}]}]},{\"t\":7,\"n\":\"ACID - Actor Cell Marker Reference\",\"c\":[{\"t\":3,\"n\":\"Ref #0\"}]},{\"t\":7,\"n\":\"LCID - Location Cell Marker Reference\",\"c\":[{\"t\":3,\"n\":\"Ref #0\"}]},{\"t\":8,\"n\":\"ACEP - Actor Cell Enable Point\",\"c\":[{\"t\":6,\"n\":\" #0\",\"c\":[{\"t\":3,\"n\":\"Actor\"},{\"t\":3,\"n\":\"Ref\"},{\"t\":3,\"n\":\"Grid Y\"},{\"t\":3,\"n\":\"Grid X\"}]}]},{\"t\":8,\"n\":\"LCEP - Location Cell Enable Point\",\"c\":[{\"t\":6,\"n\":\" #0\",\"c\":[{\"t\":3,\"n\":\"Actor\"},{\"t\":3,\"n\":\"Ref\"},{\"t\":3,\"n\":\"Grid Y\"},{\"t\":3,\"n\":\"Grid X\"}]}]},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":3,\"n\":\"KSIZ - Keyword Count\"},{\"t\":9,\"n\":\"KWDA - Keywords\",\"c\":[{\"t\":3,\"n\":\"Keyword\"}]},{\"t\":3,\"n\":\"PNAM - Parent Location\"},{\"t\":3,\"n\":\"NAM1 - Music\"},{\"t\":3,\"n\":\"FNAM - Unreported Crime Faction\"},{\"t\":3,\"n\":\"MNAM - World Location Marker Ref\"},{\"t\":5,\"n\":\"RNAM - World Location Radius\"},{\"t\":3,\"n\":\"NAM0 - Horse Marker Ref\"},{\"t\":6,\"n\":\"CNAM - Color\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unknown\"}]}]},{\"t\":1,\"p\":1,\"n\":\"LIGH - Light\",\"c\":[{\"t\":6,\"n\":\"Record Header\",\"c\":[{\"t\":2,\"n\":\"Signature\"},{\"t\":3,\"n\":\"Data Size\"},{\"t\":3,\"n\":\"Record Flags\"},{\"t\":3,\"n\":\"FormID\"},{\"t\":11,\"n\":\"Version Control Info 1\"},{\"t\":3,\"n\":\"Form Version\"},{\"t\":11,\"n\":\"Version Control Info 2\"}]},{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"n\":\"VMAD - Virtual Machine Adapter\",\"c\":[{\"t\":3,\"n\":\"Version\"},{\"t\":3,\"n\":\"Object Format\"},{\"t\":12,\"n\":\"Data\",\"c\":[{\"t\":9,\"n\":\"Scripts\",\"c\":[{\"t\":6,\"n\":\"Script\",\"c\":[{\"t\":2,\"n\":\"scriptName\"},{\"t\":3,\"n\":\"Flags\"},{\"t\":9,\"n\":\"Properties\",\"c\":[{\"t\":6,\"n\":\"Property\",\"c\":[{\"t\":2,\"n\":\"propertyName\"},{\"t\":3,\"n\":\"Type\"},{\"t\":3,\"n\":\"Flags\"},{\"t\":12,\"n\":\"Value\"}]}]}]}]}]}]},{\"t\":6,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"n\":\"X1\"},{\"t\":3,\"n\":\"Y1\"},{\"t\":3,\"n\":\"Z1\"},{\"t\":3,\"n\":\"X2\"},{\"t\":3,\"n\":\"Y2\"},{\"t\":3,\"n\":\"Z2\"}]},{\"t\":6,\"n\":\"Model\",\"c\":[{\"t\":2,\"n\":\"MODL - Model Filename\"}]},{\"t\":6,\"n\":\"Destructable\",\"c\":[{\"t\":6,\"n\":\"DEST - Header\",\"c\":[{\"t\":3,\"n\":\"Health\"},{\"t\":3,\"n\":\"DEST Count\"},{\"t\":3,\"n\":\"VATS Targetable\"},{\"t\":11,\"n\":\"Unknown\"}]}]},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":6,\"n\":\"Icon\",\"c\":[{\"t\":2,\"n\":\"ICON - Large Icon filename\"}]},{\"t\":6,\"n\":\"DATA - \",\"c\":[{\"t\":3,\"n\":\"Time\"},{\"t\":3,\"n\":\"Radius\"},{\"t\":6,\"n\":\"Color\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":3,\"n\":\"Unknown\"}]},{\"t\":3,\"n\":\"Flags\"},{\"t\":5,\"n\":\"Falloff Exponent\"},{\"t\":5,\"n\":\"FOV\"},{\"t\":5,\"n\":\"Near Clip\"},{\"t\":6,\"n\":\"Flicker Effect\",\"c\":[{\"t\":5,\"n\":\"Period\"},{\"t\":5,\"n\":\"Intensity Amplitude\"},{\"t\":5,\"n\":\"Movement Amplitude\"}]},{\"t\":3,\"n\":\"Value\"},{\"t\":5,\"n\":\"Weight\"}]},{\"t\":5,\"n\":\"FNAM - Fade value\"},{\"t\":3,\"n\":\"SNAM - Sound\"}]},{\"t\":1,\"p\":1,\"n\":\"MESG - Message\",\"c\":[{\"t\":6,\"n\":\"Record Header\",\"c\":[{\"t\":2,\"n\":\"Signature\"},{\"t\":3,\"n\":\"Data Size\"},{\"t\":3,\"n\":\"Record Flags\"},{\"t\":3,\"n\":\"FormID\"},{\"t\":11,\"n\":\"Version Control Info 1\"},{\"t\":3,\"n\":\"Form Version\"},{\"t\":11,\"n\":\"Version Control Info 2\"}]},{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"n\":\"DESC - Description\"},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":3,\"n\":\"INAM - Icon (unused)\"},{\"t\":3,\"n\":\"QNAM - Owner Quest\"},{\"t\":3,\"n\":\"DNAM - Flags\",\"c\":[{\"t\":4,\"n\":\"Message Box\"}]},{\"t\":3,\"n\":\"TNAM - Display Time\"},{\"t\":8,\"n\":\"Menu Buttons\",\"c\":[{\"t\":6,\"n\":\"Menu Button\",\"c\":[{\"t\":2,\"n\":\"ITXT - Button Text\"}]}]}]},{\"t\":1,\"p\":1,\"n\":\"MGEF - Magic Effect\",\"c\":[{\"t\":6,\"n\":\"Record Header\",\"c\":[{\"t\":2,\"n\":\"Signature\"},{\"t\":3,\"n\":\"Data Size\"},{\"t\":3,\"n\":\"Record Flags\"},{\"t\":3,\"n\":\"FormID\"},{\"t\":11,\"n\":\"Version Control Info 1\"},{\"t\":3,\"n\":\"Form Version\"},{\"t\":11,\"n\":\"Version Control Info 2\"}]},{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"n\":\"VMAD - Virtual Machine Adapter\",\"c\":[{\"t\":3,\"n\":\"Version\"},{\"t\":3,\"n\":\"Object Format\"},{\"t\":12,\"n\":\"Data\",\"c\":[{\"t\":9,\"n\":\"Scripts\",\"c\":[{\"t\":6,\"n\":\"Script\",\"c\":[{\"t\":2,\"n\":\"scriptName\"},{\"t\":3,\"n\":\"Flags\"},{\"t\":9,\"n\":\"Properties\",\"c\":[{\"t\":6,\"n\":\"Property\",\"c\":[{\"t\":2,\"n\":\"propertyName\"},{\"t\":3,\"n\":\"Type\"},{\"t\":3,\"n\":\"Flags\"},{\"t\":12,\"n\":\"Value\"}]}]}]}]}]}]},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":3,\"n\":\"MDOB - Menu Display Object\"},{\"t\":3,\"n\":\"KSIZ - Keyword Count\"},{\"t\":9,\"n\":\"KWDA - Keywords\",\"c\":[{\"t\":3,\"n\":\"Keyword\"}]},{\"t\":6,\"n\":\"Magic Effect Data\",\"c\":[{\"t\":6,\"n\":\"DATA - Data\",\"c\":[{\"t\":3,\"n\":\"Flags\"},{\"t\":5,\"n\":\"Base Cost\"},{\"t\":12,\"n\":\"Assoc. Item\"},{\"t\":3,\"n\":\"Magic Skill\"},{\"t\":3,\"n\":\"Resist Value\"},{\"t\":3,\"n\":\"Counter Effect count\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":3,\"n\":\"Casting Light\"},{\"t\":5,\"n\":\"Taper Weight\"},{\"t\":3,\"n\":\"Hit Shader\"},{\"t\":3,\"n\":\"Enchant Shader\"},{\"t\":3,\"n\":\"Minimum Skill Level\"},{\"t\":6,\"n\":\"Spellmaking\",\"c\":[{\"t\":3,\"n\":\"Area\"},{\"t\":5,\"n\":\"Casting Time\"}]},{\"t\":5,\"n\":\"Taper Curve\"},{\"t\":5,\"n\":\"Taper Duration\"},{\"t\":5,\"n\":\"Second AV Weight\"},{\"t\":3,\"n\":\"Archtype\"},{\"t\":3,\"n\":\"Actor Value\"},{\"t\":3,\"n\":\"Projectile\"},{\"t\":3,\"n\":\"Explosion\"},{\"t\":3,\"n\":\"Casting Type\"},{\"t\":3,\"n\":\"Delivery\"},{\"t\":3,\"n\":\"Second Actor Value\"},{\"t\":3,\"n\":\"Casting Art\"},{\"t\":3,\"n\":\"Hit Effect Art\"},{\"t\":3,\"n\":\"Impact Data\"},{\"t\":5,\"n\":\"Skill Usage Multiplier\"},{\"t\":6,\"n\":\"Dual Casting\",\"c\":[{\"t\":3,\"n\":\"Art\"},{\"t\":5,\"n\":\"Scale\"}]},{\"t\":3,\"n\":\"Enchant Art\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":3,\"n\":\"Equip Ability\"},{\"t\":3,\"n\":\"Image Space Modifier\"},{\"t\":3,\"n\":\"Perk to Apply\"},{\"t\":3,\"n\":\"Casting Sound Level\"},{\"t\":6,\"n\":\"Script Effect AI\",\"c\":[{\"t\":5,\"n\":\"Score\"},{\"t\":5,\"n\":\"Delay Time\"}]}]}]},{\"t\":9,\"n\":\"Counter Effects\",\"c\":[{\"t\":3,\"n\":\"ESCE - Effect\"}]},{\"t\":8,\"n\":\"SNDD - Sounds\",\"c\":[{\"t\":6,\"n\":\" #0\",\"c\":[{\"t\":3,\"n\":\"Type\"},{\"t\":3,\"n\":\"Sound\"}]}]},{\"t\":2,\"n\":\"DNAM - Magic Item Description\"},{\"t\":8,\"n\":\"Conditions\",\"c\":[{\"t\":6,\"n\":\"Condition\",\"c\":[{\"t\":6,\"n\":\"CTDA - \",\"c\":[{\"t\":3,\"n\":\"Type\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":12,\"n\":\"Comparison Value\"},{\"t\":3,\"n\":\"Function\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":12,\"n\":\"Parameter #1\"},{\"t\":12,\"n\":\"Parameter #2\"},{\"t\":3,\"n\":\"Run On\"},{\"t\":12,\"n\":\"Reference\"},{\"t\":3,\"n\":\"Parameter #3\"}]}]}]}]},{\"t\":1,\"p\":1,\"n\":\"MISC - Misc. Item\",\"c\":[{\"t\":6,\"n\":\"Record Header\",\"c\":[{\"t\":2,\"n\":\"Signature\"},{\"t\":3,\"n\":\"Data Size\"},{\"t\":3,\"n\":\"Record Flags\"},{\"t\":3,\"n\":\"FormID\"},{\"t\":11,\"n\":\"Version Control Info 1\"},{\"t\":3,\"n\":\"Form Version\"},{\"t\":11,\"n\":\"Version Control Info 2\"}]},{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"n\":\"VMAD - Virtual Machine Adapter\",\"c\":[{\"t\":3,\"n\":\"Version\"},{\"t\":3,\"n\":\"Object Format\"},{\"t\":12,\"n\":\"Data\",\"c\":[{\"t\":9,\"n\":\"Scripts\",\"c\":[{\"t\":6,\"n\":\"Script\",\"c\":[{\"t\":2,\"n\":\"scriptName\"},{\"t\":3,\"n\":\"Flags\"},{\"t\":9,\"n\":\"Properties\",\"c\":[{\"t\":6,\"n\":\"Property\",\"c\":[{\"t\":2,\"n\":\"propertyName\"},{\"t\":3,\"n\":\"Type\"},{\"t\":3,\"n\":\"Flags\"},{\"t\":12,\"n\":\"Value\"}]}]}]}]}]}]},{\"t\":6,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"n\":\"X1\"},{\"t\":3,\"n\":\"Y1\"},{\"t\":3,\"n\":\"Z1\"},{\"t\":3,\"n\":\"X2\"},{\"t\":3,\"n\":\"Y2\"},{\"t\":3,\"n\":\"Z2\"}]},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":6,\"n\":\"Model\",\"c\":[{\"t\":2,\"n\":\"MODL - Model Filename\"}]},{\"t\":6,\"n\":\"Icon\",\"c\":[{\"t\":2,\"n\":\"ICON - Large Icon filename\"}]},{\"t\":6,\"n\":\"Destructable\",\"c\":[{\"t\":6,\"n\":\"DEST - Header\",\"c\":[{\"t\":3,\"n\":\"Health\"},{\"t\":3,\"n\":\"DEST Count\"},{\"t\":3,\"n\":\"VATS Targetable\"},{\"t\":11,\"n\":\"Unknown\"}]}]},{\"t\":3,\"n\":\"YNAM - Sound - Pick Up\"},{\"t\":3,\"n\":\"ZNAM - Sound - Drop\"},{\"t\":3,\"n\":\"KSIZ - Keyword Count\"},{\"t\":9,\"n\":\"KWDA - Keywords\",\"c\":[{\"t\":3,\"n\":\"Keyword\"}]},{\"t\":6,\"n\":\"DATA - Data\",\"c\":[{\"t\":3,\"n\":\"Value\"},{\"t\":5,\"n\":\"Weight\"}]}]},{\"t\":1,\"p\":1,\"n\":\"MSTT - Moveable Static\",\"c\":[{\"t\":6,\"n\":\"Record Header\",\"c\":[{\"t\":2,\"n\":\"Signature\"},{\"t\":3,\"n\":\"Data Size\"},{\"t\":3,\"n\":\"Record Flags\"},{\"t\":3,\"n\":\"FormID\"},{\"t\":11,\"n\":\"Version Control Info 1\"},{\"t\":3,\"n\":\"Form Version\"},{\"t\":11,\"n\":\"Version Control Info 2\"}]},{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"n\":\"X1\"},{\"t\":3,\"n\":\"Y1\"},{\"t\":3,\"n\":\"Z1\"},{\"t\":3,\"n\":\"X2\"},{\"t\":3,\"n\":\"Y2\"},{\"t\":3,\"n\":\"Z2\"}]},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":6,\"n\":\"Model\",\"c\":[{\"t\":2,\"n\":\"MODL - Model Filename\"}]},{\"t\":6,\"n\":\"Destructable\",\"c\":[{\"t\":6,\"n\":\"DEST - Header\",\"c\":[{\"t\":3,\"n\":\"Health\"},{\"t\":3,\"n\":\"DEST Count\"},{\"t\":3,\"n\":\"VATS Targetable\"},{\"t\":11,\"n\":\"Unknown\"}]}]},{\"t\":3,\"n\":\"DATA - Flags\"},{\"t\":3,\"n\":\"SNAM - Looping Sound\"}]},{\"t\":1,\"p\":1,\"n\":\"NPC_ - Non-Player Character (Actor)\",\"c\":[{\"t\":6,\"n\":\"Record Header\",\"c\":[{\"t\":2,\"n\":\"Signature\"},{\"t\":3,\"n\":\"Data Size\"},{\"t\":3,\"n\":\"Record Flags\"},{\"t\":3,\"n\":\"FormID\"},{\"t\":11,\"n\":\"Version Control Info 1\"},{\"t\":3,\"n\":\"Form Version\"},{\"t\":11,\"n\":\"Version Control Info 2\"}]},{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"n\":\"VMAD - Virtual Machine Adapter\",\"c\":[{\"t\":3,\"n\":\"Version\"},{\"t\":3,\"n\":\"Object Format\"},{\"t\":12,\"n\":\"Data\",\"c\":[{\"t\":9,\"n\":\"Scripts\",\"c\":[{\"t\":6,\"n\":\"Script\",\"c\":[{\"t\":2,\"n\":\"scriptName\"},{\"t\":3,\"n\":\"Flags\"},{\"t\":9,\"n\":\"Properties\",\"c\":[{\"t\":6,\"n\":\"Property\",\"c\":[{\"t\":2,\"n\":\"propertyName\"},{\"t\":3,\"n\":\"Type\"},{\"t\":3,\"n\":\"Flags\"},{\"t\":12,\"n\":\"Value\"}]}]}]}]}]}]},{\"t\":6,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"n\":\"X1\"},{\"t\":3,\"n\":\"Y1\"},{\"t\":3,\"n\":\"Z1\"},{\"t\":3,\"n\":\"X2\"},{\"t\":3,\"n\":\"Y2\"},{\"t\":3,\"n\":\"Z2\"}]},{\"t\":6,\"n\":\"ACBS - Configuration\",\"c\":[{\"t\":3,\"n\":\"Flags\"},{\"t\":3,\"n\":\"Magicka Offset\"},{\"t\":3,\"n\":\"Stamina Offset\"},{\"t\":12,\"n\":\"Level\"},{\"t\":3,\"n\":\"Calc min level\"},{\"t\":3,\"n\":\"Calc max level\"},{\"t\":3,\"n\":\"Speed Multiplier\"},{\"t\":3,\"n\":\"Disposition Base (unused)\"},{\"t\":3,\"n\":\"Template Flags\"},{\"t\":3,\"n\":\"Health Offset\"},{\"t\":3,\"n\":\"Bleedout Override\"}]},{\"t\":10,\"n\":\"Factions\",\"c\":[{\"t\":6,\"n\":\"SNAM - Faction\",\"c\":[{\"t\":3,\"n\":\"Faction\"},{\"t\":3,\"n\":\"Rank\"},{\"t\":11,\"n\":\"Unused\"}]}]},{\"t\":3,\"n\":\"INAM - Death item\"},{\"t\":3,\"n\":\"VTCK - Voice\"},{\"t\":3,\"n\":\"TPLT - Template\"},{\"t\":3,\"n\":\"RNAM - Race\"},{\"t\":3,\"n\":\"SPCT - Count\"},{\"t\":9,\"n\":\"Actor Effects\",\"c\":[{\"t\":3,\"n\":\"SPLO - Actor Effect\"}]},{\"t\":6,\"n\":\"Destructable\",\"c\":[{\"t\":6,\"n\":\"DEST - Header\",\"c\":[{\"t\":3,\"n\":\"Health\"},{\"t\":3,\"n\":\"DEST Count\"},{\"t\":3,\"n\":\"VATS Targetable\"},{\"t\":11,\"n\":\"Unknown\"}]}]},{\"t\":3,\"n\":\"WNAM - Worn Armor\"},{\"t\":3,\"n\":\"ANAM - Far away model\"},{\"t\":3,\"n\":\"ATKR - Attack Race\"},{\"t\":10,\"n\":\"Attacks\",\"c\":[{\"t\":6,\"n\":\"Attack\",\"c\":[{\"t\":6,\"n\":\"ATKD - Attack Data\",\"c\":[{\"t\":5,\"n\":\"Damage Mult\"},{\"t\":5,\"n\":\"Attack Chance\"},{\"t\":3,\"n\":\"Attack Spell\"},{\"t\":3,\"n\":\"Attack Flags\"},{\"t\":5,\"n\":\"Attack Angle\"},{\"t\":5,\"n\":\"Strike Angle\"},{\"t\":5,\"n\":\"Stagger\"},{\"t\":3,\"n\":\"Attack Type\"},{\"t\":5,\"n\":\"Knockdown\"},{\"t\":5,\"n\":\"Recovery Time\"},{\"t\":5,\"n\":\"Stamina Mult\"}]}]}]},{\"t\":3,\"n\":\"SPOR - Spectator override package list\"},{\"t\":3,\"n\":\"OCOR - Observe dead body override package list\"},{\"t\":3,\"n\":\"GWOR - Guard warn override package list\"},{\"t\":3,\"n\":\"ECOR - Combat override package list\"},{\"t\":3,\"n\":\"PRKZ - Perk Count\"},{\"t\":10,\"n\":\"Perks\",\"c\":[{\"t\":6,\"n\":\"PRKR - Perk\",\"c\":[{\"t\":3,\"n\":\"Perk\"},{\"t\":3,\"n\":\"Rank\"},{\"t\":11,\"n\":\"Unused\"}]}]},{\"t\":3,\"n\":\"COCT - Count\"},{\"t\":10,\"n\":\"Items\",\"c\":[{\"t\":6,\"n\":\"Item\",\"c\":[{\"t\":6,\"n\":\"CNTO - Item\",\"c\":[{\"t\":3,\"n\":\"Item\"},{\"t\":3,\"n\":\"Count\"}]}]}]},{\"t\":6,\"n\":\"AIDT - AI Data\",\"c\":[{\"t\":3,\"n\":\"Aggression\"},{\"t\":3,\"n\":\"Confidence\"},{\"t\":3,\"n\":\"Energy Level\"},{\"t\":3,\"n\":\"Responsibility\"},{\"t\":3,\"n\":\"Mood\"},{\"t\":3,\"n\":\"Assistance\"},{\"t\":6,\"n\":\"Aggro\",\"c\":[{\"t\":3,\"n\":\"Aggro Radius Behavior\"},{\"t\":3,\"n\":\"Unknown\"},{\"t\":3,\"n\":\"Warn\"},{\"t\":3,\"n\":\"Warn\\/Attack\"},{\"t\":3,\"n\":\"Attack\"}]}]},{\"t\":7,\"n\":\"Packages\",\"c\":[{\"t\":3,\"n\":\"PKID - Package\"}]},{\"t\":3,\"n\":\"KSIZ - Keyword Count\"},{\"t\":9,\"n\":\"KWDA - Keywords\",\"c\":[{\"t\":3,\"n\":\"Keyword\"}]},{\"t\":3,\"n\":\"CNAM - Class\"},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":2,\"n\":\"SHRT - Short Name\"},{\"t\":11,\"n\":\"DATA - Marker\"},{\"t\":6,\"n\":\"DNAM - Player Skills\",\"c\":[{\"t\":7,\"n\":\"Skill Values\",\"c\":[{\"t\":3,\"n\":\"Skill #0 (OneHanded)\"},{\"t\":3,\"n\":\"Skill #1 (TwoHanded)\"},{\"t\":3,\"n\":\"Skill #2 (Marksman)\"},{\"t\":3,\"n\":\"Skill #3 (Block)\"},{\"t\":3,\"n\":\"Skill #4 (Smithing)\"},{\"t\":3,\"n\":\"Skill #5 (HeavyArmor)\"},{\"t\":3,\"n\":\"Skill #6 (LightArmor)\"},{\"t\":3,\"n\":\"Skill #7 (Pickpocket)\"},{\"t\":3,\"n\":\"Skill #8 (Lockpicking)\"},{\"t\":3,\"n\":\"Skill #9 (Sneak)\"},{\"t\":3,\"n\":\"Skill #10 (Alchemy)\"},{\"t\":3,\"n\":\"Skill #11 (Speechcraft)\"},{\"t\":3,\"n\":\"Skill #12 (Alteration)\"},{\"t\":3,\"n\":\"Skill #13 (Conjuration)\"},{\"t\":3,\"n\":\"Skill #14 (Destruction)\"},{\"t\":3,\"n\":\"Skill #15 (Illusion)\"},{\"t\":3,\"n\":\"Skill #16 (Restoration)\"},{\"t\":3,\"n\":\"Skill #17 (Enchanting)\"}]},{\"t\":7,\"n\":\"Skill Offsets\",\"c\":[{\"t\":3,\"n\":\"Skill #0 (OneHanded)\"},{\"t\":3,\"n\":\"Skill #1 (TwoHanded)\"},{\"t\":3,\"n\":\"Skill #2 (Marksman)\"},{\"t\":3,\"n\":\"Skill #3 (Block)\"},{\"t\":3,\"n\":\"Skill #4 (Smithing)\"},{\"t\":3,\"n\":\"Skill #5 (HeavyArmor)\"},{\"t\":3,\"n\":\"Skill #6 (LightArmor)\"},{\"t\":3,\"n\":\"Skill #7 (Pickpocket)\"},{\"t\":3,\"n\":\"Skill #8 (Lockpicking)\"},{\"t\":3,\"n\":\"Skill #9 (Sneak)\"},{\"t\":3,\"n\":\"Skill #10 (Alchemy)\"},{\"t\":3,\"n\":\"Skill #11 (Speechcraft)\"},{\"t\":3,\"n\":\"Skill #12 (Alteration)\"},{\"t\":3,\"n\":\"Skill #13 (Conjuration)\"},{\"t\":3,\"n\":\"Skill #14 (Destruction)\"},{\"t\":3,\"n\":\"Skill #15 (Illusion)\"},{\"t\":3,\"n\":\"Skill #16 (Restoration)\"},{\"t\":3,\"n\":\"Skill #17 (Enchanting)\"}]},{\"t\":3,\"n\":\"Health\"},{\"t\":3,\"n\":\"Magicka\"},{\"t\":3,\"n\":\"Stamina\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":5,\"n\":\"Far away model distance\"},{\"t\":3,\"n\":\"Geared up weapons\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":9,\"n\":\"Head Parts\",\"c\":[{\"t\":3,\"n\":\"PNAM - Head Part\"}]},{\"t\":3,\"n\":\"HCLF - Hair Color\"},{\"t\":3,\"n\":\"ZNAM - Combat Style\"},{\"t\":3,\"n\":\"GNAM - Gift Filter\"},{\"t\":11,\"n\":\"NAM5 - Unknown\"},{\"t\":5,\"n\":\"NAM6 - Height\"},{\"t\":5,\"n\":\"NAM7 - Weight\"},{\"t\":3,\"n\":\"NAM8 - Sound Level\"},{\"t\":10,\"n\":\"Sound Types\",\"c\":[{\"t\":6,\"n\":\"Sound Type\",\"c\":[{\"t\":3,\"n\":\"CSDT - Type\"},{\"t\":10,\"n\":\"Sounds\",\"c\":[{\"t\":6,\"n\":\"Sound\",\"c\":[{\"t\":3,\"n\":\"CSDI - Sound\"},{\"t\":3,\"n\":\"CSDC - Sound Chance\"}]}]}]}]},{\"t\":3,\"n\":\"CSCR - Inherits Sounds From\"},{\"t\":3,\"n\":\"DOFT - Default outfit\"},{\"t\":3,\"n\":\"SOFT - Sleeping outfit\"},{\"t\":3,\"n\":\"DPLT - Default Package List\"},{\"t\":3,\"n\":\"CRIF - Crime faction\"},{\"t\":3,\"n\":\"FTST - Head texture\"},{\"t\":6,\"n\":\"QNAM - Texture lighting\",\"c\":[{\"t\":5,\"n\":\"Red\"},{\"t\":5,\"n\":\"Green\"},{\"t\":5,\"n\":\"Blue\"}]},{\"t\":6,\"n\":\"NAM9 - Face morph\",\"c\":[{\"t\":5,\"n\":\"Nose Long\\/Short\"},{\"t\":5,\"n\":\"Nose Up\\/Down\"},{\"t\":5,\"n\":\"Jaw Up\\/Down\"},{\"t\":5,\"n\":\"Jaw Narrow\\/Wide\"},{\"t\":5,\"n\":\"Jaw Farward\\/Back\"},{\"t\":5,\"n\":\"Cheeks Up\\/Down\"},{\"t\":5,\"n\":\"Cheeks Farward\\/Back\"},{\"t\":5,\"n\":\"Eyes Up\\/Down\"},{\"t\":5,\"n\":\"Eyes In\\/Out\"},{\"t\":5,\"n\":\"Brows Up\\/Down\"},{\"t\":5,\"n\":\"Brows In\\/Out\"},{\"t\":5,\"n\":\"Brows Farward\\/Back\"},{\"t\":5,\"n\":\"Lips Up\\/Down\"},{\"t\":5,\"n\":\"Lips In\\/Out\"},{\"t\":5,\"n\":\"Chin Narrow\\/Wide\"},{\"t\":5,\"n\":\"Chin Up\\/Down\"},{\"t\":5,\"n\":\"Chin Underbite\\/Overbite\"},{\"t\":5,\"n\":\"Eyes Farward\\/Back\"},{\"t\":5,\"n\":\"Unknown\"}]},{\"t\":6,\"n\":\"NAMA - Face parts\",\"c\":[{\"t\":3,\"n\":\"Nose\"},{\"t\":3,\"n\":\"Unknown\"},{\"t\":3,\"n\":\"Eyes\"},{\"t\":3,\"n\":\"Mouth\"}]},{\"t\":10,\"n\":\"Tint Layers\",\"c\":[{\"t\":6,\"n\":\"Layer\",\"c\":[{\"t\":3,\"n\":\"TINI - Tint Index\"}]}]}]},{\"t\":1,\"p\":1,\"n\":\"PERK - Perk\",\"c\":[{\"t\":6,\"n\":\"Record Header\",\"c\":[{\"t\":2,\"n\":\"Signature\"},{\"t\":3,\"n\":\"Data Size\"},{\"t\":3,\"n\":\"Record Flags\"},{\"t\":3,\"n\":\"FormID\"},{\"t\":11,\"n\":\"Version Control Info 1\"},{\"t\":3,\"n\":\"Form Version\"},{\"t\":11,\"n\":\"Version Control Info 2\"}]},{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"n\":\"VMAD - Virtual Machine Adapter\",\"c\":[{\"t\":3,\"n\":\"Version\"},{\"t\":3,\"n\":\"Object Format\"},{\"t\":12,\"n\":\"Data\",\"c\":[{\"t\":6,\"n\":\"Perk VMAD\",\"c\":[{\"t\":9,\"n\":\"Scripts\",\"c\":[{\"t\":6,\"n\":\"Script\",\"c\":[{\"t\":2,\"n\":\"scriptName\"},{\"t\":3,\"n\":\"Flags\"},{\"t\":9,\"n\":\"Properties\",\"c\":[{\"t\":6,\"n\":\"Property\",\"c\":[{\"t\":2,\"n\":\"propertyName\"},{\"t\":3,\"n\":\"Type\"},{\"t\":3,\"n\":\"Flags\"},{\"t\":12,\"n\":\"Value\"}]}]}]}]},{\"t\":6,\"n\":\"Script Fragments Perk\",\"c\":[{\"t\":3,\"n\":\"Unknown\"},{\"t\":2,\"n\":\"fileName\"},{\"t\":9,\"n\":\"Perk Fragments\",\"c\":[{\"t\":6,\"n\":\"Perk Fragment\",\"c\":[{\"t\":3,\"n\":\"Fragment Index\"},{\"t\":3,\"n\":\"Unknown\"},{\"t\":3,\"n\":\"Unknown\"},{\"t\":2,\"n\":\"scriptName\"},{\"t\":2,\"n\":\"fragmentName\"}]}]}]}]}]}]},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":2,\"n\":\"DESC - Description\"},{\"t\":6,\"n\":\"Icon\",\"c\":[{\"t\":2,\"n\":\"ICON - Large Icon filename\"}]},{\"t\":8,\"n\":\"Conditions\",\"c\":[{\"t\":6,\"n\":\"Condition\",\"c\":[{\"t\":6,\"n\":\"CTDA - \",\"c\":[{\"t\":3,\"n\":\"Type\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":12,\"n\":\"Comparison Value\"},{\"t\":3,\"n\":\"Function\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":12,\"n\":\"Parameter #1\"},{\"t\":12,\"n\":\"Parameter #2\"},{\"t\":3,\"n\":\"Run On\"},{\"t\":12,\"n\":\"Reference\"},{\"t\":3,\"n\":\"Parameter #3\"}]}]}]},{\"t\":6,\"n\":\"DATA - Data\",\"c\":[{\"t\":3,\"n\":\"Trait\"},{\"t\":3,\"n\":\"Level\"},{\"t\":3,\"n\":\"Num Ranks\"},{\"t\":3,\"n\":\"Playable\"},{\"t\":3,\"n\":\"Hidden\"}]},{\"t\":3,\"n\":\"NNAM - Next Perk\"},{\"t\":10,\"n\":\"Effects\",\"c\":[{\"t\":6,\"n\":\"Effect\",\"c\":[{\"t\":6,\"n\":\"PRKE - Header\",\"c\":[{\"t\":3,\"n\":\"Type\"},{\"t\":3,\"n\":\"Rank\"},{\"t\":3,\"n\":\"Priority\"}]},{\"t\":12,\"n\":\"DATA - Effect Data\",\"c\":[{\"t\":6,\"n\":\"Quest + Stage\",\"c\":[{\"t\":3,\"n\":\"Quest\"},{\"t\":3,\"n\":\"Quest Stage\"},{\"t\":11,\"n\":\"Unused\"}]}]},{\"n\":\"PRKF - End Marker\"}]}]}]},{\"t\":1,\"p\":1,\"n\":\"PROJ - Projectile\",\"c\":[{\"t\":6,\"n\":\"Record Header\",\"c\":[{\"t\":2,\"n\":\"Signature\"},{\"t\":3,\"n\":\"Data Size\"},{\"t\":3,\"n\":\"Record Flags\"},{\"t\":3,\"n\":\"FormID\"},{\"t\":11,\"n\":\"Version Control Info 1\"},{\"t\":3,\"n\":\"Form Version\"},{\"t\":11,\"n\":\"Version Control Info 2\"}]},{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"n\":\"X1\"},{\"t\":3,\"n\":\"Y1\"},{\"t\":3,\"n\":\"Z1\"},{\"t\":3,\"n\":\"X2\"},{\"t\":3,\"n\":\"Y2\"},{\"t\":3,\"n\":\"Z2\"}]},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":6,\"n\":\"Model\",\"c\":[{\"t\":2,\"n\":\"MODL - Model Filename\"}]},{\"t\":6,\"n\":\"Destructable\",\"c\":[{\"t\":6,\"n\":\"DEST - Header\",\"c\":[{\"t\":3,\"n\":\"Health\"},{\"t\":3,\"n\":\"DEST Count\"},{\"t\":3,\"n\":\"VATS Targetable\"},{\"t\":11,\"n\":\"Unknown\"}]}]},{\"t\":6,\"n\":\"DATA - Data\",\"c\":[{\"t\":3,\"n\":\"Flags\"},{\"t\":3,\"n\":\"Type\"},{\"t\":5,\"n\":\"Gravity\"},{\"t\":5,\"n\":\"Speed\"},{\"t\":5,\"n\":\"Range\"},{\"t\":3,\"n\":\"Light\"},{\"t\":3,\"n\":\"Muzzle Flash - Light\"},{\"t\":5,\"n\":\"Tracer Chance\"},{\"t\":5,\"n\":\"Explosion - Alt. Trigger - Proximity\"},{\"t\":5,\"n\":\"Explosion - Alt. Trigger - Timer\"},{\"t\":3,\"n\":\"Explosion\"},{\"t\":3,\"n\":\"Sound\"},{\"t\":5,\"n\":\"Muzzle Flash - Duration\"},{\"t\":5,\"n\":\"Fade Duration\"},{\"t\":5,\"n\":\"Impact Force\"},{\"t\":3,\"n\":\"Sound - Countdown\"},{\"t\":3,\"n\":\"Sound - Disable\"},{\"t\":3,\"n\":\"Default Weapon Source\"},{\"t\":5,\"n\":\"Cone Spread\"},{\"t\":5,\"n\":\"Collision Radius\"},{\"t\":5,\"n\":\"Lifetime\"},{\"t\":5,\"n\":\"Relaunch Interval\"},{\"t\":3,\"n\":\"Decal Data\"},{\"t\":3,\"n\":\"Collision Layer\"}]},{\"t\":6,\"n\":\"Muzzle Flash Model\",\"c\":[{\"t\":2,\"n\":\"NAM1 - Model Filename\"}]},{\"t\":3,\"n\":\"VNAM - Sound Level\"}]},{\"t\":1,\"p\":1,\"n\":\"QUST - Quest\",\"c\":[{\"t\":6,\"n\":\"Record Header\",\"c\":[{\"t\":2,\"n\":\"Signature\"},{\"t\":3,\"n\":\"Data Size\"},{\"t\":3,\"n\":\"Record Flags\"},{\"t\":3,\"n\":\"FormID\"},{\"t\":11,\"n\":\"Version Control Info 1\"},{\"t\":3,\"n\":\"Form Version\"},{\"t\":11,\"n\":\"Version Control Info 2\"}]},{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"n\":\"VMAD - Virtual Machine Adapter\",\"c\":[{\"t\":3,\"n\":\"Version\"},{\"t\":3,\"n\":\"Object Format\"},{\"t\":12,\"n\":\"Data\",\"c\":[{\"t\":6,\"n\":\"Quest VMAD\",\"c\":[{\"t\":9,\"n\":\"Scripts\",\"c\":[{\"t\":6,\"n\":\"Script\",\"c\":[{\"t\":2,\"n\":\"scriptName\"},{\"t\":3,\"n\":\"Flags\"},{\"t\":9,\"n\":\"Properties\",\"c\":[{\"t\":6,\"n\":\"Property\",\"c\":[{\"t\":2,\"n\":\"propertyName\"},{\"t\":3,\"n\":\"Type\"},{\"t\":3,\"n\":\"Flags\"},{\"t\":12,\"n\":\"Value\"}]}]}]}]},{\"t\":6,\"n\":\"Script Fragments Quest\",\"c\":[{\"t\":3,\"n\":\"Unknown\"},{\"t\":3,\"n\":\"fragmentCount\"},{\"t\":2,\"n\":\"fileName\"},{\"t\":9,\"n\":\"Quest Fragments\",\"c\":[{\"t\":6,\"n\":\"Quest Fragment\",\"c\":[{\"t\":3,\"n\":\"Quest Stage\"},{\"t\":3,\"n\":\"Unknown\"},{\"t\":3,\"n\":\"Quest Stage Index\"},{\"t\":3,\"n\":\"Unknown\"},{\"t\":2,\"n\":\"scriptName\"},{\"t\":2,\"n\":\"fragmentName\"}]}]},{\"t\":9,\"n\":\"Aliases\",\"c\":[{\"t\":6,\"n\":\"Alias\",\"c\":[{\"t\":12,\"n\":\"Object Union\",\"c\":[{\"t\":6,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"FormID\"},{\"t\":3,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]}]},{\"t\":3,\"n\":\"Version\"},{\"t\":3,\"n\":\"Object Format\"},{\"t\":9,\"n\":\"Alias Scripts\",\"c\":[{\"t\":6,\"n\":\"Script\",\"c\":[{\"t\":2,\"n\":\"scriptName\"},{\"t\":3,\"n\":\"Flags\"},{\"t\":9,\"n\":\"Properties\",\"c\":[{\"t\":6,\"n\":\"Property\",\"c\":[{\"t\":2,\"n\":\"propertyName\"},{\"t\":3,\"n\":\"Type\"},{\"t\":3,\"n\":\"Flags\"},{\"t\":12,\"n\":\"Value\"}]}]}]}]}]}]}]}]}]}]},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":6,\"n\":\"DNAM - General\",\"c\":[{\"t\":3,\"n\":\"Flags\"},{\"t\":3,\"n\":\"Priority\"},{\"t\":3,\"n\":\"Form Version\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":3,\"n\":\"Type\"}]},{\"t\":2,\"n\":\"ENAM - Event\"},{\"t\":7,\"n\":\"Text Display Globals\",\"c\":[{\"t\":3,\"n\":\"QTGL - Global\"}]},{\"t\":2,\"n\":\"FLTR - Object Window Filter\"},{\"t\":6,\"n\":\"Quest Dialogue Conditions\",\"c\":[{\"t\":8,\"n\":\"Conditions\",\"c\":[{\"t\":6,\"n\":\"Condition\",\"c\":[{\"t\":6,\"n\":\"CTDA - \",\"c\":[{\"t\":3,\"n\":\"Type\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":12,\"n\":\"Comparison Value\"},{\"t\":3,\"n\":\"Function\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":12,\"n\":\"Parameter #1\"},{\"t\":12,\"n\":\"Parameter #2\"},{\"t\":3,\"n\":\"Run On\"},{\"t\":12,\"n\":\"Reference\"},{\"t\":3,\"n\":\"Parameter #3\"}]}]}]}]},{\"n\":\"NEXT - Marker\"},{\"t\":8,\"n\":\"Conditions\",\"c\":[{\"t\":6,\"n\":\"Condition\",\"c\":[{\"t\":6,\"n\":\"CTDA - \",\"c\":[{\"t\":3,\"n\":\"Type\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":12,\"n\":\"Comparison Value\"},{\"t\":3,\"n\":\"Function\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":12,\"n\":\"Parameter #1\"},{\"t\":12,\"n\":\"Parameter #2\"},{\"t\":3,\"n\":\"Run On\"},{\"t\":12,\"n\":\"Reference\"},{\"t\":3,\"n\":\"Parameter #3\"}]}]}]},{\"t\":10,\"n\":\"Stages\",\"c\":[{\"t\":6,\"n\":\"Stage\",\"c\":[{\"t\":6,\"n\":\"INDX - Stage Index\",\"c\":[{\"t\":3,\"n\":\"Stage Index\"},{\"t\":3,\"n\":\"Flags\"},{\"t\":3,\"n\":\"Unknown\"}]}]}]},{\"t\":8,\"n\":\"Objectives\",\"c\":[{\"t\":6,\"n\":\"Objective\",\"c\":[{\"t\":3,\"n\":\"QOBJ - Objective Index\"},{\"t\":2,\"n\":\"NNAM - Display Text\"}]}]},{\"t\":11,\"n\":\"ANAM - Aliases Marker\"},{\"t\":8,\"n\":\"Aliases\",\"c\":[{\"t\":6,\"n\":\"Alias\",\"c\":[{\"t\":3,\"n\":\"ALST - Reference Alias ID\"},{\"n\":\"ALED - Alias End\"}]}]},{\"t\":2,\"n\":\"NNAM - Description\"},{\"t\":8,\"n\":\"Targets\",\"c\":[{\"t\":6,\"n\":\"Target\",\"c\":[{\"t\":6,\"n\":\"QSTA - Target\",\"c\":[{\"t\":3,\"n\":\"Target\"},{\"t\":3,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unknown\"}]}]}]}]},{\"t\":1,\"p\":1,\"n\":\"RACE - Race\",\"c\":[{\"t\":6,\"n\":\"Record Header\",\"c\":[{\"t\":2,\"n\":\"Signature\"},{\"t\":3,\"n\":\"Data Size\"},{\"t\":3,\"n\":\"Record Flags\"},{\"t\":3,\"n\":\"FormID\"},{\"t\":11,\"n\":\"Version Control Info 1\"},{\"t\":3,\"n\":\"Form Version\"},{\"t\":11,\"n\":\"Version Control Info 2\"}]},{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":2,\"n\":\"DESC - Description\"},{\"t\":3,\"n\":\"SPCT - Count\"},{\"t\":9,\"n\":\"Actor Effects\",\"c\":[{\"t\":3,\"n\":\"SPLO - Actor Effect\"}]},{\"t\":3,\"n\":\"WNAM - Skin\"},{\"t\":6,\"n\":\"BOD2 - Biped Body Template\",\"c\":[{\"t\":3,\"n\":\"First Person Flags\"},{\"t\":3,\"n\":\"General Flags\"},{\"n\":\"Unused\"},{\"t\":3,\"n\":\"Armor Type\"}]},{\"t\":3,\"n\":\"KSIZ - Keyword Count\"},{\"t\":9,\"n\":\"KWDA - Keywords\",\"c\":[{\"t\":3,\"n\":\"Keyword\"}]},{\"t\":6,\"n\":\"DATA - \",\"c\":[{\"t\":10,\"n\":\"Skill Boosts\",\"c\":[{\"t\":6,\"n\":\"Skill Boost\",\"c\":[{\"t\":3,\"n\":\"Skill\"},{\"t\":3,\"n\":\"Boost\"}]},{\"t\":6,\"n\":\"Skill Boost\",\"c\":[{\"t\":3,\"n\":\"Skill\"},{\"t\":3,\"n\":\"Boost\"}]},{\"t\":6,\"n\":\"Skill Boost\",\"c\":[{\"t\":3,\"n\":\"Skill\"},{\"t\":3,\"n\":\"Boost\"}]},{\"t\":6,\"n\":\"Skill Boost\",\"c\":[{\"t\":3,\"n\":\"Skill\"},{\"t\":3,\"n\":\"Boost\"}]},{\"t\":6,\"n\":\"Skill Boost\",\"c\":[{\"t\":3,\"n\":\"Skill\"},{\"t\":3,\"n\":\"Boost\"}]},{\"t\":6,\"n\":\"Skill Boost\",\"c\":[{\"t\":3,\"n\":\"Skill\"},{\"t\":3,\"n\":\"Boost\"}]},{\"t\":6,\"n\":\"Skill Boost\",\"c\":[{\"t\":3,\"n\":\"Skill\"},{\"t\":3,\"n\":\"Boost\"}]}]},{\"t\":11,\"n\":\"Unknown\"},{\"t\":5,\"n\":\"Male Height\"},{\"t\":5,\"n\":\"Female Height\"},{\"t\":5,\"n\":\"Male Weight\"},{\"t\":5,\"n\":\"Female Weight\"},{\"t\":3,\"n\":\"Flags\"},{\"t\":5,\"n\":\"Starting Health\"},{\"t\":5,\"n\":\"Starting Magicka\"},{\"t\":5,\"n\":\"Starting Stamina\"},{\"t\":5,\"n\":\"Base Carry Weight\"},{\"t\":5,\"n\":\"Base Mass\"},{\"t\":5,\"n\":\"Acceleration rate\"},{\"t\":5,\"n\":\"Deceleration rate\"},{\"t\":3,\"n\":\"Size\"},{\"t\":3,\"n\":\"Head Biped Object\"},{\"t\":3,\"n\":\"Hair Biped Object\"},{\"t\":5,\"n\":\"Injured Health Pct\"},{\"t\":3,\"n\":\"Shield Biped Object\"},{\"t\":5,\"n\":\"Health Regen\"},{\"t\":5,\"n\":\"Magicka Regen\"},{\"t\":5,\"n\":\"Stamina Regen\"},{\"t\":5,\"n\":\"Unarmed Damage\"},{\"t\":5,\"n\":\"Unarmed Reach\"},{\"t\":3,\"n\":\"Body Biped Object\"},{\"t\":5,\"n\":\"Aim Angle Tolerance\"},{\"t\":5,\"n\":\"Flight Radius\"},{\"t\":5,\"n\":\"Angular Acceleration Rate\"},{\"t\":5,\"n\":\"Angular Tolerance\"},{\"t\":3,\"n\":\"Flags 2\"},{\"t\":6,\"n\":\"Mount Data\",\"c\":[{\"t\":5,\"n\":\"Offset X\"},{\"t\":5,\"n\":\"Offset Y\"},{\"t\":5,\"n\":\"Unknown\"},{\"t\":5,\"n\":\"Unknown\"},{\"t\":5,\"n\":\"Unknown\"},{\"t\":5,\"n\":\"Unknown\"},{\"t\":5,\"n\":\"Unknown\"},{\"t\":5,\"n\":\"Unknown\"},{\"t\":5,\"n\":\"Unknown\"}]}]},{\"n\":\"MNAM - Male Marker\"},{\"t\":2,\"n\":\"ANAM - Male Skeletal Model\"},{\"t\":11,\"n\":\"MODT - Texture Files Hashes\"},{\"n\":\"FNAM - Female Marker\"},{\"t\":2,\"n\":\"ANAM - Female Skeletal Model\"},{\"t\":11,\"n\":\"MODT - Texture Files Hashes\"},{\"n\":\"NAM2 - Marker NAM2 #1\"},{\"t\":9,\"n\":\"Movement Type Names\",\"c\":[{\"t\":2,\"n\":\"MTNM - Name\"}]},{\"t\":7,\"n\":\"VTCK - Voices\",\"c\":[{\"t\":3,\"n\":\"Voice #0 (Male)\"},{\"t\":3,\"n\":\"Voice #1 (Female)\"}]},{\"t\":7,\"n\":\"DNAM - Decapitate Armors\",\"c\":[{\"t\":3,\"n\":\"Decapitate Armor #0 (Male)\"},{\"t\":3,\"n\":\"Decapitate Armor #1 (Female)\"}]},{\"t\":7,\"n\":\"HCLF - Default Hair Colors\",\"c\":[{\"t\":3,\"n\":\"Default Hair Color #0 (Male)\"},{\"t\":3,\"n\":\"Default Hair Color #1 (Female)\"}]},{\"t\":3,\"n\":\"TINL - Total Number of Tints in List\"},{\"t\":5,\"n\":\"PNAM - FaceGen - Main clamp\"},{\"t\":5,\"n\":\"UNAM - FaceGen - Face clamp\"},{\"t\":3,\"n\":\"ATKR - Attack Race\"},{\"t\":10,\"n\":\"Attacks\",\"c\":[{\"t\":6,\"n\":\"Attack\",\"c\":[{\"t\":6,\"n\":\"ATKD - Attack Data\",\"c\":[{\"t\":5,\"n\":\"Damage Mult\"},{\"t\":5,\"n\":\"Attack Chance\"},{\"t\":3,\"n\":\"Attack Spell\"},{\"t\":3,\"n\":\"Attack Flags\"},{\"t\":5,\"n\":\"Attack Angle\"},{\"t\":5,\"n\":\"Strike Angle\"},{\"t\":5,\"n\":\"Stagger\"},{\"t\":3,\"n\":\"Attack Type\"},{\"t\":5,\"n\":\"Knockdown\"},{\"t\":5,\"n\":\"Recovery Time\"},{\"t\":5,\"n\":\"Stamina Mult\"}]}]}]},{\"t\":6,\"n\":\"Body Data\",\"c\":[{\"n\":\"NAM1 - Body Data Marker\"},{\"t\":6,\"n\":\"Male Body Data\",\"c\":[{\"n\":\"MNAM - Male Data Marker\"},{\"t\":10,\"n\":\"Parts\",\"c\":[{\"t\":6,\"n\":\"Part\",\"c\":[{\"t\":3,\"n\":\"INDX - Index\"}]}]}]},{\"t\":6,\"n\":\"Female Body Data\",\"c\":[{\"n\":\"FNAM - Female Data Marker\"},{\"t\":10,\"n\":\"Parts\",\"c\":[{\"t\":6,\"n\":\"Part\",\"c\":[{\"t\":3,\"n\":\"INDX - Index\"}]}]}]}]},{\"t\":9,\"n\":\"HNAM - Hairs\",\"c\":[{\"t\":3,\"n\":\"Hair\"}]},{\"t\":9,\"n\":\"ENAM - Eyes\",\"c\":[{\"t\":3,\"n\":\"Eye\"}]},{\"t\":3,\"n\":\"GNAM - Body Part Data\"},{\"n\":\"NAM2 - Marker NAM2 #2\"},{\"n\":\"NAM3 - Marker NAM3 #3\"},{\"t\":6,\"n\":\"Male Behavior Graph\",\"c\":[{\"n\":\"MNAM - Male Data Marker\"}]},{\"t\":6,\"n\":\"Female Behavior Graph\",\"c\":[{\"n\":\"FNAM - Female Data Marker\"}]},{\"t\":3,\"n\":\"NAM4 - Material Type\"},{\"t\":3,\"n\":\"NAM5 - Impact Data Set\"},{\"t\":3,\"n\":\"NAM7 - Decapitation FX\"},{\"t\":3,\"n\":\"ONAM - Open Loot Sound\"},{\"t\":3,\"n\":\"LNAM - Close Loot Sound\"},{\"t\":7,\"n\":\"Biped Object Names\",\"c\":[{\"t\":2,\"n\":\"NAME - Name\"}]},{\"t\":10,\"n\":\"Movement Types\",\"c\":[{\"t\":6,\"n\":\"Movement Types\",\"c\":[{\"t\":3,\"n\":\"MTYP - Movement Type\"}]}]},{\"t\":3,\"n\":\"VNAM - Equipment Flags\"},{\"t\":9,\"n\":\"Equip Slots\",\"c\":[{\"t\":3,\"n\":\"QNAM - Equip Slot\"}]},{\"t\":3,\"n\":\"UNES - Unarmed Equip Slot\"},{\"t\":7,\"n\":\"Phoneme Target Names\",\"c\":[{\"t\":2,\"n\":\"PHTN - Name\"}]},{\"t\":6,\"n\":\"FaceFX Phonemes\",\"c\":[{\"t\":6,\"n\":\"IY\",\"c\":[{\"t\":6,\"n\":\"PHWT - Phoneme Target Weight\",\"c\":[{\"t\":5,\"n\":\"Aah \\/ LipBigAah\"},{\"t\":5,\"n\":\"BigAah \\/ LipDST\"},{\"t\":5,\"n\":\"BMP \\/ LipEee\"},{\"t\":5,\"n\":\"ChJsh \\/ LipFV\"},{\"t\":5,\"n\":\"DST \\/ LipK\"},{\"t\":5,\"n\":\"Eee \\/ LipL\"},{\"t\":5,\"n\":\"Eh \\/ LipR\"},{\"t\":5,\"n\":\"FV \\/ LipTh\"},{\"t\":5,\"n\":\"I\"},{\"t\":5,\"n\":\"K\"},{\"t\":5,\"n\":\"N\"},{\"t\":5,\"n\":\"Oh\"},{\"t\":5,\"n\":\"OohQ\"},{\"t\":5,\"n\":\"R\"},{\"t\":5,\"n\":\"TH\"},{\"t\":5,\"n\":\"W\"}]}]}]},{\"t\":3,\"n\":\"WKMV - Base Movement Default - Walk\"},{\"t\":3,\"n\":\"RNMV - Base Movement Default - Run\"},{\"t\":3,\"n\":\"SWMV - Base Movement Default - Swim\"},{\"t\":3,\"n\":\"FLMV - Base Movement Default - Fly\"},{\"t\":3,\"n\":\"SNMV - Base Movement Default - Sneak\"},{\"t\":3,\"n\":\"SPMV - Base Movement Default - Sprint\"},{\"t\":6,\"n\":\"Head Data\",\"c\":[{\"n\":\"NAM0 - Head Data Marker\"},{\"t\":6,\"n\":\"Male Head Data\",\"c\":[{\"n\":\"MNAM - Male Data Marker\"}]},{\"t\":6,\"n\":\"Female Head Data\",\"c\":[{\"n\":\"NAM0 - Head Data Marker\"},{\"n\":\"FNAM - Female Data Marker\"}]}]},{\"t\":3,\"n\":\"NAM8 - Morph race\"},{\"t\":3,\"n\":\"RNAM - Armor race\"}]},{\"t\":1,\"p\":1,\"n\":\"REFR - Placed Object\",\"c\":[{\"t\":3,\"n\":\"Cell\"},{\"t\":6,\"n\":\"Record Header\",\"c\":[{\"t\":2,\"n\":\"Signature\"},{\"t\":3,\"n\":\"Data Size\"},{\"t\":3,\"n\":\"Record Flags\",\"c\":[{\"t\":4,\"n\":\"Persistent\"}]},{\"t\":3,\"n\":\"FormID\"},{\"t\":11,\"n\":\"Version Control Info 1\"},{\"t\":3,\"n\":\"Form Version\"},{\"t\":11,\"n\":\"Version Control Info 2\"}]},{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"n\":\"VMAD - Virtual Machine Adapter\",\"c\":[{\"t\":3,\"n\":\"Version\"},{\"t\":3,\"n\":\"Object Format\"},{\"t\":12,\"n\":\"Data\",\"c\":[{\"t\":9,\"n\":\"Scripts\",\"c\":[{\"t\":6,\"n\":\"Script\",\"c\":[{\"t\":2,\"n\":\"scriptName\"},{\"t\":3,\"n\":\"Flags\"},{\"t\":9,\"n\":\"Properties\",\"c\":[{\"t\":6,\"n\":\"Property\",\"c\":[{\"t\":2,\"n\":\"propertyName\"},{\"t\":3,\"n\":\"Type\"},{\"t\":3,\"n\":\"Flags\"},{\"t\":12,\"n\":\"Value\"}]}]}]}]}]}]},{\"t\":3,\"n\":\"NAME - Base\"},{\"t\":6,\"n\":\"XMBO - Bound Half Extents\",\"c\":[{\"t\":5,\"n\":\"X\"},{\"t\":5,\"n\":\"Y\"},{\"t\":5,\"n\":\"Z\"}]},{\"t\":6,\"n\":\"XPRM - Primitive\",\"c\":[{\"t\":6,\"n\":\"Bounds\",\"c\":[{\"t\":5,\"n\":\"X\"},{\"t\":5,\"n\":\"Y\"},{\"t\":5,\"n\":\"Z\"}]},{\"t\":6,\"n\":\"Color\",\"c\":[{\"t\":5,\"n\":\"Red\"},{\"t\":5,\"n\":\"Green\"},{\"t\":5,\"n\":\"Blue\"}]},{\"t\":5,\"n\":\"Unknown\"},{\"t\":3,\"n\":\"Type\"}]},{\"t\":11,\"n\":\"XORD - Unknown\"},{\"t\":6,\"n\":\"XOCP - Occlusion Plane Data\",\"c\":[{\"t\":6,\"n\":\"Size\",\"c\":[{\"t\":5,\"n\":\"Width\"},{\"t\":5,\"n\":\"Height\"}]},{\"t\":6,\"n\":\"Position\",\"c\":[{\"t\":5,\"n\":\"X\"},{\"t\":5,\"n\":\"Y\"},{\"t\":5,\"n\":\"Z\"}]},{\"t\":6,\"n\":\"Rotation (Quaternion?)\",\"c\":[{\"t\":5,\"n\":\"q1\"},{\"t\":5,\"n\":\"q2\"},{\"t\":5,\"n\":\"q3\"},{\"t\":5,\"n\":\"q4\"}]}]},{\"t\":8,\"n\":\"XPOD - Portal Data\",\"c\":[{\"t\":6,\"n\":\"References #0\",\"c\":[{\"t\":3,\"n\":\"Origin\"},{\"t\":3,\"n\":\"Destination\"}]}]},{\"t\":6,\"n\":\"XPTL - Room Portal (unused)\",\"c\":[{\"t\":6,\"n\":\"Size\",\"c\":[{\"t\":5,\"n\":\"Width\"},{\"t\":5,\"n\":\"Height\"}]},{\"t\":6,\"n\":\"Position\",\"c\":[{\"t\":5,\"n\":\"X\"},{\"t\":5,\"n\":\"Y\"},{\"t\":5,\"n\":\"Z\"}]},{\"t\":6,\"n\":\"Rotation (Quaternion?)\",\"c\":[{\"t\":5,\"n\":\"q1\"},{\"t\":5,\"n\":\"q2\"},{\"t\":5,\"n\":\"q3\"},{\"t\":5,\"n\":\"q4\"}]}]},{\"t\":6,\"n\":\"Bound Data\",\"c\":[{\"t\":6,\"n\":\"XRMR - Header\",\"c\":[{\"t\":3,\"n\":\"Linked Rooms Count\"},{\"t\":3,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unknown\"}]}]},{\"n\":\"XMBP - MultiBound Primitive Marker\"},{\"t\":11,\"n\":\"XRGD - Ragdoll Data\"},{\"t\":11,\"n\":\"XRGB - Ragdoll Biped Data\"},{\"t\":5,\"n\":\"XRDS - Radius\"},{\"t\":10,\"n\":\"Reflected\\/Refracted By\",\"c\":[{\"t\":6,\"n\":\"XPWR - Water\",\"c\":[{\"t\":3,\"n\":\"Reference\"},{\"t\":3,\"n\":\"Type\"}]}]},{\"t\":9,\"n\":\"Lit Water\",\"c\":[{\"t\":3,\"n\":\"XLTW - Water\"}]},{\"t\":3,\"n\":\"XEMI - Emittance\"},{\"t\":6,\"n\":\"XLIG - Light Data\",\"c\":[{\"t\":5,\"n\":\"FOV 90+\\/-\"},{\"t\":5,\"n\":\"Fade 1.35+\\/-\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":5,\"n\":\"Shadow Depth Bias\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":6,\"n\":\"XALP - Alpha\",\"c\":[{\"t\":3,\"n\":\"Cutoff\"},{\"t\":3,\"n\":\"Base\"}]},{\"t\":6,\"n\":\"XTEL - Teleport Destination\",\"c\":[{\"t\":3,\"n\":\"Door\"},{\"t\":6,\"n\":\"Position\\/Rotation\",\"c\":[{\"t\":6,\"n\":\"Position\",\"c\":[{\"t\":5,\"n\":\"X\"},{\"t\":5,\"n\":\"Y\"},{\"t\":5,\"n\":\"Z\"}]},{\"t\":6,\"n\":\"Rotation\",\"c\":[{\"t\":5,\"n\":\"X\"},{\"t\":5,\"n\":\"Y\"},{\"t\":5,\"n\":\"Z\"}]}]},{\"t\":3,\"n\":\"Flags\"}]},{\"t\":3,\"n\":\"XTNM - Teleport Message Box\"},{\"t\":3,\"n\":\"XMBR - MultiBound Reference\"},{\"t\":11,\"n\":\"XWCN - Unknown\"},{\"t\":11,\"n\":\"XWCS - Unknown\"},{\"t\":6,\"n\":\"XWCU - Water Velocity\",\"c\":[{\"t\":5,\"n\":\"X Offset\"},{\"t\":5,\"n\":\"Y Offset\"},{\"t\":5,\"n\":\"Z Offset\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":5,\"n\":\"X Angle\"},{\"t\":5,\"n\":\"Y Angle\"},{\"t\":5,\"n\":\"Z Angle\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":6,\"n\":\"XCVL - Unknown\",\"c\":[{\"t\":11,\"n\":\"Unknown\"},{\"t\":5,\"n\":\"X Angle\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":3,\"n\":\"XCZR - Unknown\"},{\"t\":11,\"n\":\"XCZA - Unknown\"},{\"t\":3,\"n\":\"XCZC - Unknown\"},{\"t\":5,\"n\":\"XSCL - Scale\"},{\"t\":3,\"n\":\"XSPC - Spawn Container\"},{\"t\":6,\"n\":\"Activate Parents\",\"c\":[{\"t\":3,\"n\":\"XAPD - Flags\"}]},{\"t\":3,\"n\":\"XLIB - Leveled Item Base Object\"},{\"t\":3,\"n\":\"XLCM - Level Modifier\"},{\"t\":3,\"n\":\"XLCN - Persistent Location\"},{\"t\":3,\"n\":\"XTRI - Collision Layer\"},{\"t\":6,\"n\":\"XLOC - Lock Data\",\"c\":[{\"t\":3,\"n\":\"Level\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":3,\"n\":\"Key\"},{\"t\":3,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":3,\"n\":\"XEZN - Encounter Zone\"},{\"t\":6,\"n\":\"XNDP - Navigation Door Link\",\"c\":[{\"t\":3,\"n\":\"Navigation Mesh\"},{\"t\":3,\"n\":\"Teleport Marker Triangle\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":7,\"n\":\"XLRT - Location Ref Type\",\"c\":[{\"t\":3,\"n\":\"Ref #0\"}]},{\"n\":\"XIS2 - Ignored by Sandbox\"},{\"t\":6,\"n\":\"Ownership\",\"c\":[{\"t\":3,\"n\":\"XOWN - Owner\"}]},{\"t\":3,\"n\":\"XCNT - Item Count\"},{\"t\":5,\"n\":\"XCHG - Charge\"},{\"t\":3,\"n\":\"XLRL - Location Reference\"},{\"t\":6,\"n\":\"XESP - Enable Parent\",\"c\":[{\"t\":3,\"n\":\"Reference\"},{\"t\":3,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":8,\"n\":\"Linked References\",\"c\":[{\"t\":6,\"n\":\"XLKR - Linked Reference\",\"c\":[{\"t\":3,\"n\":\"Keyword\\/Ref\"},{\"t\":3,\"n\":\"Ref\"}]}]},{\"t\":8,\"n\":\"Patrol\",\"c\":[{\"t\":6,\"n\":\"Data\",\"c\":[{\"t\":5,\"n\":\"XPRD - Idle Time\"},{\"n\":\"XPPA - Patrol Script Marker\"},{\"t\":3,\"n\":\"INAM - Idle\"}]}]},{\"t\":3,\"n\":\"XACT - Action Flag\"},{\"t\":5,\"n\":\"XHTW - Head-Tracking Weight\"},{\"t\":5,\"n\":\"XFVC - Favor Cost\"},{\"n\":\"ONAM - Open by Default\"},{\"t\":6,\"p\":1,\"n\":\"Map Marker\",\"c\":[{\"n\":\"XMRK - Map Marker Data\"},{\"t\":3,\"n\":\"FNAM - Map Flags\"},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":6,\"n\":\"TNAM - \",\"c\":[{\"t\":3,\"n\":\"Type\"},{\"t\":11,\"n\":\"Unused\"}]}]},{\"t\":3,\"n\":\"XATR - Attach Ref\"},{\"t\":7,\"n\":\"XLOD - Distant LOD Data\",\"c\":[{\"t\":5,\"n\":\"Unknown #0\"},{\"t\":5,\"n\":\"Unknown #1\"},{\"t\":5,\"n\":\"Unknown #2\"}]},{\"t\":6,\"n\":\"DATA - Position\\/Rotation\",\"c\":[{\"t\":6,\"n\":\"Position\",\"c\":[{\"t\":5,\"n\":\"X\"},{\"t\":5,\"n\":\"Y\"},{\"t\":5,\"n\":\"Z\"}]},{\"t\":6,\"n\":\"Rotation\",\"c\":[{\"t\":5,\"n\":\"X\"},{\"t\":5,\"n\":\"Y\"},{\"t\":5,\"n\":\"Z\"}]}]}]},{\"t\":1,\"p\":1,\"n\":\"SCRL - Scroll\",\"c\":[{\"t\":6,\"n\":\"Record Header\",\"c\":[{\"t\":2,\"n\":\"Signature\"},{\"t\":3,\"n\":\"Data Size\"},{\"t\":3,\"n\":\"Record Flags\"},{\"t\":3,\"n\":\"FormID\"},{\"t\":11,\"n\":\"Version Control Info 1\"},{\"t\":3,\"n\":\"Form Version\"},{\"t\":11,\"n\":\"Version Control Info 2\"}]},{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"n\":\"X1\"},{\"t\":3,\"n\":\"Y1\"},{\"t\":3,\"n\":\"Z1\"},{\"t\":3,\"n\":\"X2\"},{\"t\":3,\"n\":\"Y2\"},{\"t\":3,\"n\":\"Z2\"}]},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":3,\"n\":\"KSIZ - Keyword Count\"},{\"t\":9,\"n\":\"KWDA - Keywords\",\"c\":[{\"t\":3,\"n\":\"Keyword\"}]},{\"t\":3,\"n\":\"MDOB - Menu Display Object\"},{\"t\":3,\"n\":\"ETYP - Equipment Type\"},{\"t\":2,\"n\":\"DESC - Description\"},{\"t\":6,\"n\":\"Model\",\"c\":[{\"t\":2,\"n\":\"MODL - Model Filename\"}]},{\"t\":6,\"n\":\"Destructable\",\"c\":[{\"t\":6,\"n\":\"DEST - Header\",\"c\":[{\"t\":3,\"n\":\"Health\"},{\"t\":3,\"n\":\"DEST Count\"},{\"t\":3,\"n\":\"VATS Targetable\"},{\"t\":11,\"n\":\"Unknown\"}]}]},{\"t\":3,\"n\":\"YNAM - Sound - Pick Up\"},{\"t\":3,\"n\":\"ZNAM - Sound - Drop\"},{\"t\":6,\"n\":\"DATA - Item\",\"c\":[{\"t\":3,\"n\":\"Value\"},{\"t\":5,\"n\":\"Weight\"}]},{\"t\":6,\"n\":\"SPIT - Data\",\"c\":[{\"t\":3,\"n\":\"Base Cost\"},{\"t\":3,\"n\":\"Flags\"},{\"t\":3,\"n\":\"Type\"},{\"t\":5,\"n\":\"Charge Time\"},{\"t\":3,\"n\":\"Cast Type\"},{\"t\":3,\"n\":\"Target Type\"},{\"t\":5,\"n\":\"Cast Duration\"},{\"t\":5,\"n\":\"Range\"},{\"t\":3,\"n\":\"Half-cost Perk\"}]},{\"t\":8,\"n\":\"Effects\",\"c\":[{\"t\":6,\"n\":\"Effect\",\"c\":[{\"t\":3,\"n\":\"EFID - Base Effect\"},{\"t\":6,\"n\":\"EFIT - \",\"c\":[{\"t\":5,\"n\":\"Magnitude\"},{\"t\":3,\"n\":\"Area\"},{\"t\":3,\"n\":\"Duration\"}]}]}]}]},{\"t\":1,\"p\":1,\"n\":\"SHOU - Shout\",\"c\":[{\"t\":6,\"n\":\"Record Header\",\"c\":[{\"t\":2,\"n\":\"Signature\"},{\"t\":3,\"n\":\"Data Size\"},{\"t\":3,\"n\":\"Record Flags\"},{\"t\":3,\"n\":\"FormID\"},{\"t\":11,\"n\":\"Version Control Info 1\"},{\"t\":3,\"n\":\"Form Version\"},{\"t\":11,\"n\":\"Version Control Info 2\"}]},{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":3,\"n\":\"MDOB - Menu Display Object\"},{\"t\":2,\"n\":\"DESC - Description\"},{\"t\":8,\"n\":\"Words of Power\",\"c\":[{\"t\":6,\"n\":\"SNAM - \",\"c\":[{\"t\":3,\"n\":\"Word\"},{\"t\":3,\"n\":\"Spell\"},{\"t\":5,\"n\":\"Recovery Time\"}]}]}]},{\"t\":1,\"p\":1,\"n\":\"SLGM - Soul Gem\",\"c\":[{\"t\":6,\"n\":\"Record Header\",\"c\":[{\"t\":2,\"n\":\"Signature\"},{\"t\":3,\"n\":\"Data Size\"},{\"t\":3,\"n\":\"Record Flags\"},{\"t\":3,\"n\":\"FormID\"},{\"t\":11,\"n\":\"Version Control Info 1\"},{\"t\":3,\"n\":\"Form Version\"},{\"t\":11,\"n\":\"Version Control Info 2\"}]},{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"n\":\"X1\"},{\"t\":3,\"n\":\"Y1\"},{\"t\":3,\"n\":\"Z1\"},{\"t\":3,\"n\":\"X2\"},{\"t\":3,\"n\":\"Y2\"},{\"t\":3,\"n\":\"Z2\"}]},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":6,\"n\":\"Model\",\"c\":[{\"t\":2,\"n\":\"MODL - Model Filename\"}]},{\"t\":6,\"n\":\"Icon\",\"c\":[{\"t\":2,\"n\":\"ICON - Large Icon filename\"}]},{\"t\":6,\"n\":\"Destructable\",\"c\":[{\"t\":6,\"n\":\"DEST - Header\",\"c\":[{\"t\":3,\"n\":\"Health\"},{\"t\":3,\"n\":\"DEST Count\"},{\"t\":3,\"n\":\"VATS Targetable\"},{\"t\":11,\"n\":\"Unknown\"}]}]},{\"t\":3,\"n\":\"YNAM - Sound - Pick Up\"},{\"t\":3,\"n\":\"ZNAM - Sound - Drop\"},{\"t\":3,\"n\":\"KSIZ - Keyword Count\"},{\"t\":9,\"n\":\"KWDA - Keywords\",\"c\":[{\"t\":3,\"n\":\"Keyword\"}]},{\"t\":6,\"n\":\"DATA - \",\"c\":[{\"t\":3,\"n\":\"Value\"},{\"t\":5,\"n\":\"Weight\"}]},{\"t\":3,\"n\":\"SOUL - Contained Soul\"},{\"t\":3,\"n\":\"SLCP - Maximum Capacity\"},{\"t\":3,\"n\":\"NAM0 - Linked To\"}]},{\"t\":1,\"p\":1,\"n\":\"SNCT - Sound Category\",\"c\":[{\"t\":6,\"n\":\"Record Header\",\"c\":[{\"t\":2,\"n\":\"Signature\"},{\"t\":3,\"n\":\"Data Size\"},{\"t\":3,\"n\":\"Record Flags\"},{\"t\":3,\"n\":\"FormID\"},{\"t\":11,\"n\":\"Version Control Info 1\"},{\"t\":3,\"n\":\"Form Version\"},{\"t\":11,\"n\":\"Version Control Info 2\"}]},{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":3,\"n\":\"FNAM - Flags\"},{\"t\":3,\"n\":\"PNAM - Parent\"},{\"t\":3,\"n\":\"VNAM - Static Volume Multiplier\"},{\"t\":3,\"n\":\"UNAM - Default Menu Value\"}]},{\"t\":1,\"p\":1,\"n\":\"SPEL - Spell\",\"c\":[{\"t\":6,\"n\":\"Record Header\",\"c\":[{\"t\":2,\"n\":\"Signature\"},{\"t\":3,\"n\":\"Data Size\"},{\"t\":3,\"n\":\"Record Flags\"},{\"t\":3,\"n\":\"FormID\"},{\"t\":11,\"n\":\"Version Control Info 1\"},{\"t\":3,\"n\":\"Form Version\"},{\"t\":11,\"n\":\"Version Control Info 2\"}]},{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"n\":\"X1\"},{\"t\":3,\"n\":\"Y1\"},{\"t\":3,\"n\":\"Z1\"},{\"t\":3,\"n\":\"X2\"},{\"t\":3,\"n\":\"Y2\"},{\"t\":3,\"n\":\"Z2\"}]},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":3,\"n\":\"KSIZ - Keyword Count\"},{\"t\":9,\"n\":\"KWDA - Keywords\",\"c\":[{\"t\":3,\"n\":\"Keyword\"}]},{\"t\":3,\"n\":\"MDOB - Menu Display Object\"},{\"t\":3,\"n\":\"ETYP - Equipment Type\"},{\"t\":2,\"n\":\"DESC - Description\"},{\"t\":6,\"n\":\"SPIT - Data\",\"c\":[{\"t\":3,\"n\":\"Base Cost\"},{\"t\":3,\"n\":\"Flags\"},{\"t\":3,\"n\":\"Type\"},{\"t\":5,\"n\":\"Charge Time\"},{\"t\":3,\"n\":\"Cast Type\"},{\"t\":3,\"n\":\"Target Type\"},{\"t\":5,\"n\":\"Cast Duration\"},{\"t\":5,\"n\":\"Range\"},{\"t\":3,\"n\":\"Half-cost Perk\"}]},{\"t\":8,\"n\":\"Effects\",\"c\":[{\"t\":6,\"n\":\"Effect\",\"c\":[{\"t\":3,\"n\":\"EFID - Base Effect\"},{\"t\":6,\"n\":\"EFIT - \",\"c\":[{\"t\":5,\"n\":\"Magnitude\"},{\"t\":3,\"n\":\"Area\"},{\"t\":3,\"n\":\"Duration\"}]}]}]}]},{\"t\":1,\"p\":1,\"n\":\"TREE - Tree\",\"c\":[{\"t\":6,\"n\":\"Record Header\",\"c\":[{\"t\":2,\"n\":\"Signature\"},{\"t\":3,\"n\":\"Data Size\"},{\"t\":3,\"n\":\"Record Flags\"},{\"t\":3,\"n\":\"FormID\"},{\"t\":11,\"n\":\"Version Control Info 1\"},{\"t\":3,\"n\":\"Form Version\"},{\"t\":11,\"n\":\"Version Control Info 2\"}]},{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"n\":\"VMAD - Virtual Machine Adapter\",\"c\":[{\"t\":3,\"n\":\"Version\"},{\"t\":3,\"n\":\"Object Format\"},{\"t\":12,\"n\":\"Data\",\"c\":[{\"t\":9,\"n\":\"Scripts\",\"c\":[{\"t\":6,\"n\":\"Script\",\"c\":[{\"t\":2,\"n\":\"scriptName\"},{\"t\":3,\"n\":\"Flags\"},{\"t\":9,\"n\":\"Properties\",\"c\":[{\"t\":6,\"n\":\"Property\",\"c\":[{\"t\":2,\"n\":\"propertyName\"},{\"t\":3,\"n\":\"Type\"},{\"t\":3,\"n\":\"Flags\"},{\"t\":12,\"n\":\"Value\"}]}]}]}]}]}]},{\"t\":6,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"n\":\"X1\"},{\"t\":3,\"n\":\"Y1\"},{\"t\":3,\"n\":\"Z1\"},{\"t\":3,\"n\":\"X2\"},{\"t\":3,\"n\":\"Y2\"},{\"t\":3,\"n\":\"Z2\"}]},{\"t\":6,\"n\":\"Model\",\"c\":[{\"t\":2,\"n\":\"MODL - Model Filename\"}]},{\"t\":3,\"n\":\"PFIG - Ingredient\"},{\"t\":3,\"n\":\"SNAM - Harvest Sound\"},{\"t\":6,\"n\":\"PFPC - Ingredient Production\",\"c\":[{\"t\":3,\"n\":\"Spring\"},{\"t\":3,\"n\":\"Summer\"},{\"t\":3,\"n\":\"Fall\"},{\"t\":3,\"n\":\"Winter\"}]},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":6,\"n\":\"CNAM - Tree Data\",\"c\":[{\"t\":5,\"n\":\"Trunk Flexibility\"},{\"t\":5,\"n\":\"Branch Flexibility\"},{\"t\":5,\"n\":\"Unknown\"},{\"t\":5,\"n\":\"Unknown\"},{\"t\":5,\"n\":\"Unknown\"},{\"t\":5,\"n\":\"Unknown\"},{\"t\":5,\"n\":\"Unknown\"},{\"t\":5,\"n\":\"Unknown\"},{\"t\":5,\"n\":\"Unknown\"},{\"t\":5,\"n\":\"Unknown\"},{\"t\":5,\"n\":\"Leaf Amplitude\"},{\"t\":5,\"n\":\"Leaf Frequency\"}]}]},{\"t\":1,\"p\":1,\"n\":\"WATR - Water\",\"c\":[{\"t\":6,\"n\":\"Record Header\",\"c\":[{\"t\":2,\"n\":\"Signature\"},{\"t\":3,\"n\":\"Data Size\"},{\"t\":3,\"n\":\"Record Flags\"},{\"t\":3,\"n\":\"FormID\"},{\"t\":11,\"n\":\"Version Control Info 1\"},{\"t\":3,\"n\":\"Form Version\"},{\"t\":11,\"n\":\"Version Control Info 2\"}]},{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":7,\"n\":\"Unused\",\"c\":[{\"t\":2,\"n\":\"NNAM - Noise Map\"}]},{\"t\":3,\"n\":\"ANAM - Opacity\"},{\"t\":3,\"n\":\"FNAM - Flags\"},{\"t\":11,\"n\":\"MNAM - Unused\"},{\"t\":3,\"n\":\"TNAM - Material\"},{\"t\":3,\"n\":\"SNAM - Open Sound\"},{\"t\":3,\"n\":\"XNAM - Spell\"},{\"t\":3,\"n\":\"INAM - Image Space\"},{\"t\":3,\"n\":\"DATA - Damage Per Second\"},{\"t\":6,\"n\":\"DNAM - Visual Data\",\"c\":[{\"t\":5,\"n\":\"Unknown\"},{\"t\":5,\"n\":\"Unknown\"},{\"t\":5,\"n\":\"Unknown\"},{\"t\":5,\"n\":\"Unknown\"},{\"t\":5,\"n\":\"Specular Properties - Sun Specular Power\"},{\"t\":5,\"n\":\"Water Properties - Reflectivity Amount\"},{\"t\":5,\"n\":\"Water Properties - Fresnel Amount\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":5,\"n\":\"Fog Properties - Above Water - Fog Distance - Near Plane\"},{\"t\":5,\"n\":\"Fog Properties - Above Water - Fog Distance - Far Plane\"},{\"t\":6,\"n\":\"Shallow Color\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":6,\"n\":\"Deep Color\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":6,\"n\":\"Reflection Color\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":11,\"n\":\"Unknown\"},{\"t\":5,\"n\":\"Unknown\"},{\"t\":5,\"n\":\"Unknown\"},{\"t\":5,\"n\":\"Unknown\"},{\"t\":5,\"n\":\"Unknown\"},{\"t\":5,\"n\":\"Displacement Simulator - Starting Size\"},{\"t\":5,\"n\":\"Displacement Simulator - Force\"},{\"t\":5,\"n\":\"Displacement Simulator - Velocity\"},{\"t\":5,\"n\":\"Displacement Simulator - Falloff\"},{\"t\":5,\"n\":\"Displacement Simulator - Dampner\"},{\"t\":5,\"n\":\"Unknown\"},{\"t\":5,\"n\":\"Noise Properties - Noise Falloff\"},{\"t\":5,\"n\":\"Noise Properties - Layer One - Wind Direction\"},{\"t\":5,\"n\":\"Noise Properties - Layer Two - Wind Direction\"},{\"t\":5,\"n\":\"Noise Properties - Layer Three - Wind Direction\"},{\"t\":5,\"n\":\"Noise Properties - Layer One - Wind Speed\"},{\"t\":5,\"n\":\"Noise Properties - Layer Two - Wind Speed\"},{\"t\":5,\"n\":\"Noise Properties - Layer Three - Wind Speed\"},{\"t\":5,\"n\":\"Unknown\"},{\"t\":5,\"n\":\"Unknown\"},{\"t\":5,\"n\":\"Fog Properties - Above Water - Fog Amount\"},{\"t\":5,\"n\":\"Unknown\"},{\"t\":5,\"n\":\"Fog Properties - Under Water - Fog Amount\"},{\"t\":5,\"n\":\"Fog Properties - Under Water - Fog Distance - Near Plane\"},{\"t\":5,\"n\":\"Fog Properties - Under Water - Fog Distance - Far Plane\"},{\"t\":5,\"n\":\"Water Properties - Refraction Magnitude\"},{\"t\":5,\"n\":\"Specular Properties - Specular Power\"},{\"t\":5,\"n\":\"Unknown\"},{\"t\":5,\"n\":\"Specular Properties - Specular Radius\"},{\"t\":5,\"n\":\"Specular Properties - Specular Brightness\"},{\"t\":5,\"n\":\"Noise Properties - Layer One - UV Scale\"},{\"t\":5,\"n\":\"Noise Properties - Layer Two - UV Scale\"},{\"t\":5,\"n\":\"Noise Properties - Layer Three - UV Scale\"},{\"t\":5,\"n\":\"Noise Properties - Layer One - Amplitude Scale\"},{\"t\":5,\"n\":\"Noise Properties - Layer Two - Amplitude Scale\"},{\"t\":5,\"n\":\"Noise Properties - Layer Three - Amplitude Scale\"},{\"t\":5,\"n\":\"Water Properties - Reflection Magnitude\"},{\"t\":5,\"n\":\"Specular Properties - Sun Sparkle Magnitude\"},{\"t\":5,\"n\":\"Specular Properties - Sun Specular Magnitude\"},{\"t\":5,\"n\":\"Depth Properties - Reflections\"},{\"t\":5,\"n\":\"Depth Properties - Refraction\"},{\"t\":5,\"n\":\"Depth Properties - Normals\"},{\"t\":5,\"n\":\"Depth Properties - Specular Lighting\"},{\"t\":5,\"n\":\"Specular Properties - Sun Sparkle Power\"}]},{\"t\":11,\"n\":\"GNAM - Unused\"},{\"t\":6,\"n\":\"NAM0 - Linear Velocity\",\"c\":[{\"t\":5,\"n\":\"X\"},{\"t\":5,\"n\":\"Y\"},{\"t\":5,\"n\":\"Z\"}]},{\"t\":6,\"n\":\"NAM1 - Angular Velocity\",\"c\":[{\"t\":5,\"n\":\"X\"},{\"t\":5,\"n\":\"Y\"},{\"t\":5,\"n\":\"Z\"}]},{\"t\":2,\"n\":\"NAM2 - Noise Texture\"},{\"t\":2,\"n\":\"NAM3 - Unused\"},{\"t\":2,\"n\":\"NAM4 - Unused\"}]},{\"t\":1,\"p\":1,\"n\":\"WEAP - Weapon\",\"c\":[{\"t\":6,\"n\":\"Record Header\",\"c\":[{\"t\":2,\"n\":\"Signature\"},{\"t\":3,\"n\":\"Data Size\"},{\"t\":3,\"n\":\"Record Flags\"},{\"t\":3,\"n\":\"FormID\"},{\"t\":11,\"n\":\"Version Control Info 1\"},{\"t\":3,\"n\":\"Form Version\"},{\"t\":11,\"n\":\"Version Control Info 2\"}]},{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"n\":\"VMAD - Virtual Machine Adapter\",\"c\":[{\"t\":3,\"n\":\"Version\"},{\"t\":3,\"n\":\"Object Format\"},{\"t\":12,\"n\":\"Data\",\"c\":[{\"t\":9,\"n\":\"Scripts\",\"c\":[{\"t\":6,\"n\":\"Script\",\"c\":[{\"t\":2,\"n\":\"scriptName\"},{\"t\":3,\"n\":\"Flags\"},{\"t\":9,\"n\":\"Properties\",\"c\":[{\"t\":6,\"n\":\"Property\",\"c\":[{\"t\":2,\"n\":\"propertyName\"},{\"t\":3,\"n\":\"Type\"},{\"t\":3,\"n\":\"Flags\"},{\"t\":12,\"n\":\"Value\"}]}]}]}]}]}]},{\"t\":6,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"n\":\"X1\"},{\"t\":3,\"n\":\"Y1\"},{\"t\":3,\"n\":\"Z1\"},{\"t\":3,\"n\":\"X2\"},{\"t\":3,\"n\":\"Y2\"},{\"t\":3,\"n\":\"Z2\"}]},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":6,\"n\":\"Model\",\"c\":[{\"t\":2,\"n\":\"MODL - Model Filename\"}]},{\"t\":6,\"n\":\"Icon\",\"c\":[{\"t\":2,\"n\":\"ICON - Large Icon filename\"}]},{\"t\":3,\"n\":\"EITM - Object Effect\"},{\"t\":3,\"n\":\"EAMT - Enchantment Amount\"},{\"t\":6,\"n\":\"Destructable\",\"c\":[{\"t\":6,\"n\":\"DEST - Header\",\"c\":[{\"t\":3,\"n\":\"Health\"},{\"t\":3,\"n\":\"DEST Count\"},{\"t\":3,\"n\":\"VATS Targetable\"},{\"t\":11,\"n\":\"Unknown\"}]}]},{\"t\":3,\"n\":\"ETYP - Equipment Type\"},{\"t\":3,\"n\":\"BIDS - Block Bash Impact Data Set\"},{\"t\":3,\"n\":\"BAMT - Alternate Block Material\"},{\"t\":3,\"n\":\"YNAM - Sound - Pick Up\"},{\"t\":3,\"n\":\"ZNAM - Sound - Drop\"},{\"t\":3,\"n\":\"KSIZ - Keyword Count\"},{\"t\":9,\"n\":\"KWDA - Keywords\",\"c\":[{\"t\":3,\"n\":\"Keyword\"}]},{\"t\":2,\"n\":\"DESC - Description\"},{\"t\":6,\"n\":\"Has Scope\",\"c\":[{\"t\":2,\"n\":\"MOD3 - Model Filename\"}]},{\"t\":11,\"n\":\"NNAM - Unused\"},{\"t\":3,\"n\":\"INAM - Impact Data Set\"},{\"t\":3,\"n\":\"WNAM - 1st Person Model Object\"},{\"t\":3,\"n\":\"SNAM - Attack Sound\"},{\"t\":3,\"n\":\"XNAM - Attack Sound 2D\"},{\"t\":3,\"n\":\"NAM7 - Attack Loop Sound\"},{\"t\":3,\"n\":\"TNAM - Attack Fail Sound\"},{\"t\":3,\"n\":\"UNAM - Idle Sound\"},{\"t\":3,\"n\":\"NAM9 - Equip Sound\"},{\"t\":3,\"n\":\"NAM8 - Unequip Sound\"},{\"t\":6,\"n\":\"DATA - Game Data\",\"c\":[{\"t\":3,\"n\":\"Value\"},{\"t\":5,\"n\":\"Weight\"},{\"t\":3,\"n\":\"Damage\"}]},{\"t\":6,\"n\":\"DNAM - Data\",\"c\":[{\"t\":3,\"n\":\"Animation Type\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":5,\"n\":\"Speed\"},{\"t\":5,\"n\":\"Reach\"},{\"t\":3,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":5,\"n\":\"Sight FOV\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":3,\"n\":\"Base VATS To-Hit Chance\"},{\"t\":3,\"n\":\"Attack Animation\"},{\"t\":3,\"n\":\"# Projectiles\"},{\"t\":3,\"n\":\"Embedded Weapon AV (unused)\"},{\"t\":5,\"n\":\"Range Min\"},{\"t\":5,\"n\":\"Range Max\"},{\"t\":3,\"n\":\"On Hit\"},{\"t\":3,\"n\":\"Flags2\"},{\"t\":5,\"n\":\"Animation Attack Mult\"},{\"t\":5,\"n\":\"Unknown\"},{\"t\":5,\"n\":\"Rumble - Left Motor Strength\"},{\"t\":5,\"n\":\"Rumble - Right Motor Strength\"},{\"t\":5,\"n\":\"Rumble - Duration\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":3,\"n\":\"Skill\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":3,\"n\":\"Resist\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":5,\"n\":\"Stagger\"}]},{\"t\":6,\"n\":\"CRDT - Critical Data\",\"c\":[{\"t\":3,\"n\":\"Damage\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":5,\"n\":\"% Mult\"},{\"t\":3,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":3,\"n\":\"Effect\"}]},{\"t\":3,\"n\":\"VNAM - Detection Sound Level\"},{\"t\":3,\"n\":\"CNAM - Template\"}]},{\"t\":1,\"p\":1,\"n\":\"WRLD - Worldspace\",\"c\":[{\"t\":6,\"n\":\"Record Header\",\"c\":[{\"t\":2,\"n\":\"Signature\"},{\"t\":3,\"n\":\"Data Size\"},{\"t\":3,\"n\":\"Record Flags\"},{\"t\":3,\"n\":\"FormID\"},{\"t\":11,\"n\":\"Version Control Info 1\"},{\"t\":3,\"n\":\"Form Version\"},{\"t\":11,\"n\":\"Version Control Info 2\"}]},{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":7,\"n\":\"Unused RNAM\",\"c\":[{\"t\":11,\"n\":\"RNAM - Unknown\"}]},{\"t\":11,\"n\":\"MHDT - Max Height Data\"},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":6,\"n\":\"WCTR - Fixed Dimensions Center Cell\",\"c\":[{\"t\":3,\"n\":\"X\"},{\"t\":3,\"n\":\"Y\"}]},{\"t\":3,\"n\":\"LTMP - Interior Lighting\"},{\"t\":3,\"n\":\"XEZN - Encounter Zone\"},{\"t\":3,\"n\":\"XLCN - Location\"},{\"t\":6,\"n\":\"Parent\",\"c\":[{\"t\":3,\"n\":\"WNAM - Worldspace\"},{\"t\":6,\"n\":\"PNAM - \",\"c\":[{\"t\":3,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unknown\"}]}]},{\"t\":3,\"n\":\"CNAM - Climate\"},{\"t\":3,\"n\":\"NAM2 - Water\"},{\"t\":3,\"n\":\"NAM3 - LOD Water Type\"},{\"t\":5,\"n\":\"NAM4 - LOD Water Height\"},{\"t\":6,\"n\":\"DNAM - Land Data\",\"c\":[{\"t\":5,\"n\":\"Default Land Height\"},{\"t\":5,\"n\":\"Default Water Height\"}]},{\"t\":2,\"n\":\"ICON - Map Image\"},{\"t\":6,\"n\":\"Cloud Model\",\"c\":[{\"t\":6,\"n\":\"Model\",\"c\":[{\"t\":2,\"n\":\"MODL - Model Filename\"}]}]},{\"t\":6,\"n\":\"MNAM - Map Data\",\"c\":[{\"t\":6,\"n\":\"Usable Dimensions\",\"c\":[{\"t\":3,\"n\":\"X\"},{\"t\":3,\"n\":\"Y\"}]},{\"t\":6,\"n\":\"Cell Coordinates\",\"c\":[{\"t\":6,\"n\":\"NW Cell\",\"c\":[{\"t\":3,\"n\":\"X\"},{\"t\":3,\"n\":\"Y\"}]},{\"t\":6,\"n\":\"SE Cell\",\"c\":[{\"t\":3,\"n\":\"X\"},{\"t\":3,\"n\":\"Y\"}]}]},{\"t\":6,\"n\":\"Camera Data\",\"c\":[{\"t\":5,\"n\":\"Min Height\"},{\"t\":5,\"n\":\"Max Height\"},{\"t\":5,\"n\":\"Initial Pitch\"}]}]},{\"t\":6,\"n\":\"ONAM - World Map Offset Data\",\"c\":[{\"t\":5,\"n\":\"World Map Scale\"},{\"t\":5,\"n\":\"Cell X Offset\"},{\"t\":5,\"n\":\"Cell Y Offset\"},{\"t\":5,\"n\":\"Cell Z Offset\"}]},{\"t\":5,\"n\":\"NAMA - Distant LOD Multiplier\"},{\"t\":3,\"n\":\"DATA - Flags\"},{\"t\":6,\"n\":\"Object Bounds\",\"c\":[{\"t\":6,\"n\":\"NAM0 - Min\",\"c\":[{\"t\":5,\"n\":\"X\"},{\"t\":5,\"n\":\"Y\"}]},{\"t\":6,\"n\":\"NAM9 - Max\",\"c\":[{\"t\":5,\"n\":\"X\"},{\"t\":5,\"n\":\"Y\"}]}]},{\"t\":3,\"n\":\"ZNAM - Music\"},{\"t\":2,\"n\":\"NNAM - Canopy Shadow (unused)\"},{\"t\":2,\"n\":\"XNAM - Water Noise Texture\"},{\"t\":2,\"n\":\"TNAM - HD LOD Diffuse Texture\"},{\"t\":2,\"n\":\"UNAM - HD LOD Normal Texture\"},{\"t\":2,\"n\":\"XWEM - Water Environment Map (unused)\"},{\"t\":11,\"n\":\"OFST - Offset Data\"}]},{\"t\":1,\"p\":1,\"n\":\"ALCH - Ingestible\",\"c\":[{\"t\":6,\"n\":\"Record Header\",\"c\":[{\"t\":2,\"n\":\"Signature\"},{\"t\":3,\"n\":\"Data Size\"},{\"t\":3,\"n\":\"Record Flags\"},{\"t\":3,\"n\":\"FormID\"},{\"t\":11,\"n\":\"Version Control Info 1\"},{\"t\":3,\"n\":\"Form Version\"},{\"t\":11,\"n\":\"Version Control Info 2\"}]},{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"n\":\"X1\"},{\"t\":3,\"n\":\"Y1\"},{\"t\":3,\"n\":\"Z1\"},{\"t\":3,\"n\":\"X2\"},{\"t\":3,\"n\":\"Y2\"},{\"t\":3,\"n\":\"Z2\"}]},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":3,\"n\":\"KSIZ - Keyword Count\"},{\"t\":9,\"n\":\"KWDA - Keywords\",\"c\":[{\"t\":3,\"n\":\"Keyword\"}]},{\"t\":2,\"n\":\"DESC - Description\"},{\"t\":6,\"n\":\"Model\",\"c\":[{\"t\":2,\"n\":\"MODL - Model Filename\"}]},{\"t\":6,\"n\":\"Destructable\",\"c\":[{\"t\":6,\"n\":\"DEST - Header\",\"c\":[{\"t\":3,\"n\":\"Health\"},{\"t\":3,\"n\":\"DEST Count\"},{\"t\":3,\"n\":\"VATS Targetable\"},{\"t\":11,\"n\":\"Unknown\"}]}]},{\"t\":6,\"n\":\"Icon\",\"c\":[{\"t\":2,\"n\":\"ICON - Large Icon filename\"}]},{\"t\":3,\"n\":\"YNAM - Sound - Pick Up\"},{\"t\":3,\"n\":\"ZNAM - Sound - Drop\"},{\"t\":3,\"n\":\"ETYP - Equipment Type\"},{\"t\":5,\"n\":\"DATA - Weight\"},{\"t\":6,\"n\":\"ENIT - Effect Data\",\"c\":[{\"t\":3,\"n\":\"Value\"},{\"t\":3,\"n\":\"Flags\"},{\"t\":3,\"n\":\"Addiction\"},{\"t\":5,\"n\":\"Addiction Chance\"},{\"t\":3,\"n\":\"Sound - Consume\"}]},{\"t\":8,\"n\":\"Effects\",\"c\":[{\"t\":6,\"n\":\"Effect\",\"c\":[{\"t\":3,\"n\":\"EFID - Base Effect\"},{\"t\":6,\"n\":\"EFIT - \",\"c\":[{\"t\":5,\"n\":\"Magnitude\"},{\"t\":3,\"n\":\"Area\"},{\"t\":3,\"n\":\"Duration\"}]}]}]}]}]},\"name\":\"Bash.Names\",\"hash\":\"$BB2ECCA2\",\"color\":255}"
  },
  {
    "path": "frontend/settings/Skyrim/Bash.NpcFaces.json",
    "content": "{\"records\":\"NPC_\",\"description\":\"NpcFaces tag from Wrye Bash.\\r\\n\\r\\nUsed when the mod modifies NPC faces.\",\"tree\":{\"records\":[{\"t\":1,\"p\":1,\"n\":\"NPC_ - Non-Player Character (Actor)\",\"c\":[{\"t\":6,\"n\":\"Record Header\",\"c\":[{\"t\":2,\"n\":\"Signature\"},{\"t\":3,\"n\":\"Data Size\"},{\"t\":3,\"n\":\"Record Flags\"},{\"t\":3,\"n\":\"FormID\"},{\"t\":11,\"n\":\"Version Control Info 1\"},{\"t\":3,\"n\":\"Form Version\"},{\"t\":11,\"n\":\"Version Control Info 2\"}]},{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"n\":\"VMAD - Virtual Machine Adapter\",\"c\":[{\"t\":3,\"n\":\"Version\"},{\"t\":3,\"n\":\"Object Format\"},{\"t\":12,\"n\":\"Data\",\"c\":[{\"t\":9,\"n\":\"Scripts\",\"c\":[{\"t\":6,\"n\":\"Script\",\"c\":[{\"t\":2,\"n\":\"scriptName\"},{\"t\":3,\"n\":\"Flags\"},{\"t\":9,\"n\":\"Properties\",\"c\":[{\"t\":6,\"n\":\"Property\",\"c\":[{\"t\":2,\"n\":\"propertyName\"},{\"t\":3,\"n\":\"Type\"},{\"t\":3,\"n\":\"Flags\"},{\"t\":12,\"n\":\"Value\"}]}]}]}]}]}]},{\"t\":6,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"n\":\"X1\"},{\"t\":3,\"n\":\"Y1\"},{\"t\":3,\"n\":\"Z1\"},{\"t\":3,\"n\":\"X2\"},{\"t\":3,\"n\":\"Y2\"},{\"t\":3,\"n\":\"Z2\"}]},{\"t\":6,\"n\":\"ACBS - Configuration\",\"c\":[{\"t\":3,\"n\":\"Flags\"},{\"t\":3,\"n\":\"Magicka Offset\"},{\"t\":3,\"n\":\"Stamina Offset\"},{\"t\":12,\"n\":\"Level\"},{\"t\":3,\"n\":\"Calc min level\"},{\"t\":3,\"n\":\"Calc max level\"},{\"t\":3,\"n\":\"Speed Multiplier\"},{\"t\":3,\"n\":\"Disposition Base (unused)\"},{\"t\":3,\"n\":\"Template Flags\"},{\"t\":3,\"n\":\"Health Offset\"},{\"t\":3,\"n\":\"Bleedout Override\"}]},{\"t\":10,\"n\":\"Factions\",\"c\":[{\"t\":6,\"n\":\"SNAM - Faction\",\"c\":[{\"t\":3,\"n\":\"Faction\"},{\"t\":3,\"n\":\"Rank\"},{\"t\":11,\"n\":\"Unused\"}]}]},{\"t\":3,\"n\":\"INAM - Death item\"},{\"t\":3,\"n\":\"VTCK - Voice\"},{\"t\":3,\"n\":\"TPLT - Template\"},{\"t\":3,\"n\":\"RNAM - Race\"},{\"t\":3,\"n\":\"SPCT - Count\"},{\"t\":9,\"n\":\"Actor Effects\",\"c\":[{\"t\":3,\"n\":\"SPLO - Actor Effect\"}]},{\"t\":6,\"n\":\"Destructable\",\"c\":[{\"t\":6,\"n\":\"DEST - Header\",\"c\":[{\"t\":3,\"n\":\"Health\"},{\"t\":3,\"n\":\"DEST Count\"},{\"t\":3,\"n\":\"VATS Targetable\"},{\"t\":11,\"n\":\"Unknown\"}]}]},{\"t\":3,\"n\":\"WNAM - Worn Armor\"},{\"t\":3,\"n\":\"ANAM - Far away model\"},{\"t\":3,\"n\":\"ATKR - Attack Race\"},{\"t\":10,\"n\":\"Attacks\",\"c\":[{\"t\":6,\"n\":\"Attack\",\"c\":[{\"t\":6,\"n\":\"ATKD - Attack Data\",\"c\":[{\"t\":5,\"n\":\"Damage Mult\"},{\"t\":5,\"n\":\"Attack Chance\"},{\"t\":3,\"n\":\"Attack Spell\"},{\"t\":3,\"n\":\"Attack Flags\"},{\"t\":5,\"n\":\"Attack Angle\"},{\"t\":5,\"n\":\"Strike Angle\"},{\"t\":5,\"n\":\"Stagger\"},{\"t\":3,\"n\":\"Attack Type\"},{\"t\":5,\"n\":\"Knockdown\"},{\"t\":5,\"n\":\"Recovery Time\"},{\"t\":5,\"n\":\"Stamina Mult\"}]}]}]},{\"t\":3,\"n\":\"SPOR - Spectator override package list\"},{\"t\":3,\"n\":\"OCOR - Observe dead body override package list\"},{\"t\":3,\"n\":\"GWOR - Guard warn override package list\"},{\"t\":3,\"n\":\"ECOR - Combat override package list\"},{\"t\":3,\"n\":\"PRKZ - Perk Count\"},{\"t\":10,\"n\":\"Perks\",\"c\":[{\"t\":6,\"n\":\"PRKR - Perk\",\"c\":[{\"t\":3,\"n\":\"Perk\"},{\"t\":3,\"n\":\"Rank\"},{\"t\":11,\"n\":\"Unused\"}]}]},{\"t\":3,\"n\":\"COCT - Count\"},{\"t\":10,\"n\":\"Items\",\"c\":[{\"t\":6,\"n\":\"Item\",\"c\":[{\"t\":6,\"n\":\"CNTO - Item\",\"c\":[{\"t\":3,\"n\":\"Item\"},{\"t\":3,\"n\":\"Count\"}]}]}]},{\"t\":6,\"n\":\"AIDT - AI Data\",\"c\":[{\"t\":3,\"n\":\"Aggression\"},{\"t\":3,\"n\":\"Confidence\"},{\"t\":3,\"n\":\"Energy Level\"},{\"t\":3,\"n\":\"Responsibility\"},{\"t\":3,\"n\":\"Mood\"},{\"t\":3,\"n\":\"Assistance\"},{\"t\":6,\"n\":\"Aggro\",\"c\":[{\"t\":3,\"n\":\"Aggro Radius Behavior\"},{\"t\":3,\"n\":\"Unknown\"},{\"t\":3,\"n\":\"Warn\"},{\"t\":3,\"n\":\"Warn\\/Attack\"},{\"t\":3,\"n\":\"Attack\"}]}]},{\"t\":7,\"n\":\"Packages\",\"c\":[{\"t\":3,\"n\":\"PKID - Package\"}]},{\"t\":3,\"n\":\"KSIZ - Keyword Count\"},{\"t\":9,\"n\":\"KWDA - Keywords\",\"c\":[{\"t\":3,\"n\":\"Keyword\"}]},{\"t\":3,\"n\":\"CNAM - Class\"},{\"t\":2,\"n\":\"FULL - Name\"},{\"t\":2,\"n\":\"SHRT - Short Name\"},{\"t\":11,\"n\":\"DATA - Marker\"},{\"t\":6,\"n\":\"DNAM - Player Skills\",\"c\":[{\"t\":7,\"n\":\"Skill Values\",\"c\":[{\"t\":3,\"n\":\"Skill #0 (OneHanded)\"},{\"t\":3,\"n\":\"Skill #1 (TwoHanded)\"},{\"t\":3,\"n\":\"Skill #2 (Marksman)\"},{\"t\":3,\"n\":\"Skill #3 (Block)\"},{\"t\":3,\"n\":\"Skill #4 (Smithing)\"},{\"t\":3,\"n\":\"Skill #5 (HeavyArmor)\"},{\"t\":3,\"n\":\"Skill #6 (LightArmor)\"},{\"t\":3,\"n\":\"Skill #7 (Pickpocket)\"},{\"t\":3,\"n\":\"Skill #8 (Lockpicking)\"},{\"t\":3,\"n\":\"Skill #9 (Sneak)\"},{\"t\":3,\"n\":\"Skill #10 (Alchemy)\"},{\"t\":3,\"n\":\"Skill #11 (Speechcraft)\"},{\"t\":3,\"n\":\"Skill #12 (Alteration)\"},{\"t\":3,\"n\":\"Skill #13 (Conjuration)\"},{\"t\":3,\"n\":\"Skill #14 (Destruction)\"},{\"t\":3,\"n\":\"Skill #15 (Illusion)\"},{\"t\":3,\"n\":\"Skill #16 (Restoration)\"},{\"t\":3,\"n\":\"Skill #17 (Enchanting)\"}]},{\"t\":7,\"n\":\"Skill Offsets\",\"c\":[{\"t\":3,\"n\":\"Skill #0 (OneHanded)\"},{\"t\":3,\"n\":\"Skill #1 (TwoHanded)\"},{\"t\":3,\"n\":\"Skill #2 (Marksman)\"},{\"t\":3,\"n\":\"Skill #3 (Block)\"},{\"t\":3,\"n\":\"Skill #4 (Smithing)\"},{\"t\":3,\"n\":\"Skill #5 (HeavyArmor)\"},{\"t\":3,\"n\":\"Skill #6 (LightArmor)\"},{\"t\":3,\"n\":\"Skill #7 (Pickpocket)\"},{\"t\":3,\"n\":\"Skill #8 (Lockpicking)\"},{\"t\":3,\"n\":\"Skill #9 (Sneak)\"},{\"t\":3,\"n\":\"Skill #10 (Alchemy)\"},{\"t\":3,\"n\":\"Skill #11 (Speechcraft)\"},{\"t\":3,\"n\":\"Skill #12 (Alteration)\"},{\"t\":3,\"n\":\"Skill #13 (Conjuration)\"},{\"t\":3,\"n\":\"Skill #14 (Destruction)\"},{\"t\":3,\"n\":\"Skill #15 (Illusion)\"},{\"t\":3,\"n\":\"Skill #16 (Restoration)\"},{\"t\":3,\"n\":\"Skill #17 (Enchanting)\"}]},{\"t\":3,\"n\":\"Health\"},{\"t\":3,\"n\":\"Magicka\"},{\"t\":3,\"n\":\"Stamina\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":5,\"n\":\"Far away model distance\"},{\"t\":3,\"n\":\"Geared up weapons\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":9,\"s\":1,\"p\":1,\"n\":\"Head Parts\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"PNAM - Head Part\"}]},{\"t\":3,\"p\":1,\"n\":\"HCLF - Hair Color\"},{\"t\":3,\"n\":\"ZNAM - Combat Style\"},{\"t\":3,\"n\":\"GNAM - Gift Filter\"},{\"t\":11,\"n\":\"NAM5 - Unknown\"},{\"t\":5,\"n\":\"NAM6 - Height\"},{\"t\":5,\"n\":\"NAM7 - Weight\"},{\"t\":3,\"n\":\"NAM8 - Sound Level\"},{\"t\":10,\"n\":\"Sound Types\",\"c\":[{\"t\":6,\"n\":\"Sound Type\",\"c\":[{\"t\":3,\"n\":\"CSDT - Type\"},{\"t\":10,\"n\":\"Sounds\",\"c\":[{\"t\":6,\"n\":\"Sound\",\"c\":[{\"t\":3,\"n\":\"CSDI - Sound\"},{\"t\":3,\"n\":\"CSDC - Sound Chance\"}]}]}]}]},{\"t\":3,\"n\":\"CSCR - Inherits Sounds From\"},{\"t\":3,\"n\":\"DOFT - Default outfit\"},{\"t\":3,\"n\":\"SOFT - Sleeping outfit\"},{\"t\":3,\"n\":\"DPLT - Default Package List\"},{\"t\":3,\"n\":\"CRIF - Crime faction\"},{\"t\":3,\"p\":1,\"n\":\"FTST - Head texture\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"QNAM - Texture lighting\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Red\"},{\"t\":5,\"p\":1,\"n\":\"Green\"},{\"t\":5,\"p\":1,\"n\":\"Blue\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"NAM9 - Face morph\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Nose Long\\/Short\"},{\"t\":5,\"p\":1,\"n\":\"Nose Up\\/Down\"},{\"t\":5,\"p\":1,\"n\":\"Jaw Up\\/Down\"},{\"t\":5,\"p\":1,\"n\":\"Jaw Narrow\\/Wide\"},{\"t\":5,\"p\":1,\"n\":\"Jaw Farward\\/Back\"},{\"t\":5,\"p\":1,\"n\":\"Cheeks Up\\/Down\"},{\"t\":5,\"p\":1,\"n\":\"Cheeks Farward\\/Back\"},{\"t\":5,\"p\":1,\"n\":\"Eyes Up\\/Down\"},{\"t\":5,\"p\":1,\"n\":\"Eyes In\\/Out\"},{\"t\":5,\"p\":1,\"n\":\"Brows Up\\/Down\"},{\"t\":5,\"p\":1,\"n\":\"Brows In\\/Out\"},{\"t\":5,\"p\":1,\"n\":\"Brows Farward\\/Back\"},{\"t\":5,\"p\":1,\"n\":\"Lips Up\\/Down\"},{\"t\":5,\"p\":1,\"n\":\"Lips In\\/Out\"},{\"t\":5,\"p\":1,\"n\":\"Chin Narrow\\/Wide\"},{\"t\":5,\"p\":1,\"n\":\"Chin Up\\/Down\"},{\"t\":5,\"p\":1,\"n\":\"Chin Underbite\\/Overbite\"},{\"t\":5,\"p\":1,\"n\":\"Eyes Farward\\/Back\"},{\"t\":5,\"p\":1,\"n\":\"Unknown\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"NAMA - Face parts\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Nose\"},{\"t\":3,\"p\":1,\"n\":\"Unknown\"},{\"t\":3,\"p\":1,\"n\":\"Eyes\"},{\"t\":3,\"p\":1,\"n\":\"Mouth\"}]},{\"t\":10,\"s\":1,\"p\":1,\"n\":\"Tint Layers\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Layer\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"TINI - Tint Index\"}]}]}]}]},\"name\":\"Bash.NpcFaces\",\"hash\":\"$E8292148\",\"color\":255}"
  },
  {
    "path": "frontend/settings/Skyrim/Bash.NpcFacesForceFullImport.json",
    "content": "{\"records\":\"NPC_\",\"description\":\"NpcFacesForceFullImport tag from Wrye Bash.\\r\\n\\r\\nUsed when the mod modifies NPC faces, and you wish to import the unmodified subrecords as well as the modified subrecords.\",\"tree\":{\"records\":[{\"t\":1,\"p\":1,\"n\":\"NPC_ - Non-Player Character (Actor)\",\"c\":[{\"t\":6,\"n\":\"Record Header\",\"c\":[{\"t\":2,\"n\":\"Signature\"},{\"t\":3,\"n\":\"Data Size\"},{\"t\":3,\"n\":\"Record Flags\"},{\"t\":3,\"n\":\"FormID\"},{\"t\":11,\"n\":\"Version Control Info 1\"},{\"t\":3,\"n\":\"Form Version\"},{\"t\":11,\"n\":\"Version Control Info 2\"}]},{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"n\":\"VMAD - Virtual Machine Adapter\",\"c\":[{\"t\":3,\"n\":\"Version\"},{\"t\":3,\"n\":\"Object Format\"},{\"t\":12,\"n\":\"Data\",\"c\":[{\"t\":9,\"n\":\"Scripts\",\"c\":[{\"t\":6,\"n\":\"Script\",\"c\":[{\"t\":2,\"n\":\"scriptName\"},{\"t\":3,\"n\":\"Flags\"},{\"t\":9,\"n\":\"Properties\",\"c\":[{\"t\":6,\"n\":\"Property\",\"c\":[{\"t\":2,\"n\":\"propertyName\"},{\"t\":3,\"n\":\"Type\"},{\"t\":3,\"n\":\"Flags\"},{\"t\":12,\"n\":\"Value\"}]}]}]}]}]}]},{\"t\":6,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"n\":\"X1\"},{\"t\":3,\"n\":\"Y1\"},{\"t\":3,\"n\":\"Z1\"},{\"t\":3,\"n\":\"X2\"},{\"t\":3,\"n\":\"Y2\"},{\"t\":3,\"n\":\"Z2\"}]},{\"t\":6,\"n\":\"ACBS - Configuration\",\"c\":[{\"t\":3,\"n\":\"Flags\"},{\"t\":3,\"n\":\"Magicka Offset\"},{\"t\":3,\"n\":\"Stamina Offset\"},{\"t\":12,\"n\":\"Level\"},{\"t\":3,\"n\":\"Calc min level\"},{\"t\":3,\"n\":\"Calc max level\"},{\"t\":3,\"n\":\"Speed Multiplier\"},{\"t\":3,\"n\":\"Disposition Base (unused)\"},{\"t\":3,\"n\":\"Template Flags\"},{\"t\":3,\"n\":\"Health Offset\"},{\"t\":3,\"n\":\"Bleedout Override\"}]},{\"t\":10,\"n\":\"Factions\",\"c\":[{\"t\":6,\"n\":\"SNAM - Faction\",\"c\":[{\"t\":3,\"n\":\"Faction\"},{\"t\":3,\"n\":\"Rank\"},{\"t\":11,\"n\":\"Unused\"}]}]},{\"t\":3,\"n\":\"INAM - Death item\"},{\"t\":3,\"n\":\"VTCK - Voice\"},{\"t\":3,\"n\":\"TPLT - Template\"},{\"t\":3,\"n\":\"RNAM - Race\"},{\"t\":3,\"n\":\"SPCT - Count\"},{\"t\":9,\"n\":\"Actor Effects\",\"c\":[{\"t\":3,\"n\":\"SPLO - Actor Effect\"}]},{\"t\":6,\"n\":\"Destructable\",\"c\":[{\"t\":6,\"n\":\"DEST - Header\",\"c\":[{\"t\":3,\"n\":\"Health\"},{\"t\":3,\"n\":\"DEST Count\"},{\"t\":3,\"n\":\"VATS Targetable\"},{\"t\":11,\"n\":\"Unknown\"}]}]},{\"t\":3,\"n\":\"WNAM - Worn Armor\"},{\"t\":3,\"n\":\"ANAM - Far away model\"},{\"t\":3,\"n\":\"ATKR - Attack Race\"},{\"t\":10,\"n\":\"Attacks\",\"c\":[{\"t\":6,\"n\":\"Attack\",\"c\":[{\"t\":6,\"n\":\"ATKD - Attack Data\",\"c\":[{\"t\":5,\"n\":\"Damage Mult\"},{\"t\":5,\"n\":\"Attack Chance\"},{\"t\":3,\"n\":\"Attack Spell\"},{\"t\":3,\"n\":\"Attack Flags\"},{\"t\":5,\"n\":\"Attack Angle\"},{\"t\":5,\"n\":\"Strike Angle\"},{\"t\":5,\"n\":\"Stagger\"},{\"t\":3,\"n\":\"Attack Type\"},{\"t\":5,\"n\":\"Knockdown\"},{\"t\":5,\"n\":\"Recovery Time\"},{\"t\":5,\"n\":\"Stamina Mult\"}]}]}]},{\"t\":3,\"n\":\"SPOR - Spectator override package list\"},{\"t\":3,\"n\":\"OCOR - Observe dead body override package list\"},{\"t\":3,\"n\":\"GWOR - Guard warn override package list\"},{\"t\":3,\"n\":\"ECOR - Combat override package list\"},{\"t\":3,\"n\":\"PRKZ - Perk Count\"},{\"t\":10,\"n\":\"Perks\",\"c\":[{\"t\":6,\"n\":\"PRKR - Perk\",\"c\":[{\"t\":3,\"n\":\"Perk\"},{\"t\":3,\"n\":\"Rank\"},{\"t\":11,\"n\":\"Unused\"}]}]},{\"t\":3,\"n\":\"COCT - Count\"},{\"t\":10,\"n\":\"Items\",\"c\":[{\"t\":6,\"n\":\"Item\",\"c\":[{\"t\":6,\"n\":\"CNTO - Item\",\"c\":[{\"t\":3,\"n\":\"Item\"},{\"t\":3,\"n\":\"Count\"}]}]}]},{\"t\":6,\"n\":\"AIDT - AI Data\",\"c\":[{\"t\":3,\"n\":\"Aggression\"},{\"t\":3,\"n\":\"Confidence\"},{\"t\":3,\"n\":\"Energy Level\"},{\"t\":3,\"n\":\"Responsibility\"},{\"t\":3,\"n\":\"Mood\"},{\"t\":3,\"n\":\"Assistance\"},{\"t\":6,\"n\":\"Aggro\",\"c\":[{\"t\":3,\"n\":\"Aggro Radius Behavior\"},{\"t\":3,\"n\":\"Unknown\"},{\"t\":3,\"n\":\"Warn\"},{\"t\":3,\"n\":\"Warn\\/Attack\"},{\"t\":3,\"n\":\"Attack\"}]}]},{\"t\":7,\"n\":\"Packages\",\"c\":[{\"t\":3,\"n\":\"PKID - Package\"}]},{\"t\":3,\"n\":\"KSIZ - Keyword Count\"},{\"t\":9,\"n\":\"KWDA - Keywords\",\"c\":[{\"t\":3,\"n\":\"Keyword\"}]},{\"t\":3,\"n\":\"CNAM - Class\"},{\"t\":2,\"n\":\"FULL - Name\"},{\"t\":2,\"n\":\"SHRT - Short Name\"},{\"t\":11,\"n\":\"DATA - Marker\"},{\"t\":6,\"n\":\"DNAM - Player Skills\",\"c\":[{\"t\":7,\"n\":\"Skill Values\",\"c\":[{\"t\":3,\"n\":\"Skill #0 (OneHanded)\"},{\"t\":3,\"n\":\"Skill #1 (TwoHanded)\"},{\"t\":3,\"n\":\"Skill #2 (Marksman)\"},{\"t\":3,\"n\":\"Skill #3 (Block)\"},{\"t\":3,\"n\":\"Skill #4 (Smithing)\"},{\"t\":3,\"n\":\"Skill #5 (HeavyArmor)\"},{\"t\":3,\"n\":\"Skill #6 (LightArmor)\"},{\"t\":3,\"n\":\"Skill #7 (Pickpocket)\"},{\"t\":3,\"n\":\"Skill #8 (Lockpicking)\"},{\"t\":3,\"n\":\"Skill #9 (Sneak)\"},{\"t\":3,\"n\":\"Skill #10 (Alchemy)\"},{\"t\":3,\"n\":\"Skill #11 (Speechcraft)\"},{\"t\":3,\"n\":\"Skill #12 (Alteration)\"},{\"t\":3,\"n\":\"Skill #13 (Conjuration)\"},{\"t\":3,\"n\":\"Skill #14 (Destruction)\"},{\"t\":3,\"n\":\"Skill #15 (Illusion)\"},{\"t\":3,\"n\":\"Skill #16 (Restoration)\"},{\"t\":3,\"n\":\"Skill #17 (Enchanting)\"}]},{\"t\":7,\"n\":\"Skill Offsets\",\"c\":[{\"t\":3,\"n\":\"Skill #0 (OneHanded)\"},{\"t\":3,\"n\":\"Skill #1 (TwoHanded)\"},{\"t\":3,\"n\":\"Skill #2 (Marksman)\"},{\"t\":3,\"n\":\"Skill #3 (Block)\"},{\"t\":3,\"n\":\"Skill #4 (Smithing)\"},{\"t\":3,\"n\":\"Skill #5 (HeavyArmor)\"},{\"t\":3,\"n\":\"Skill #6 (LightArmor)\"},{\"t\":3,\"n\":\"Skill #7 (Pickpocket)\"},{\"t\":3,\"n\":\"Skill #8 (Lockpicking)\"},{\"t\":3,\"n\":\"Skill #9 (Sneak)\"},{\"t\":3,\"n\":\"Skill #10 (Alchemy)\"},{\"t\":3,\"n\":\"Skill #11 (Speechcraft)\"},{\"t\":3,\"n\":\"Skill #12 (Alteration)\"},{\"t\":3,\"n\":\"Skill #13 (Conjuration)\"},{\"t\":3,\"n\":\"Skill #14 (Destruction)\"},{\"t\":3,\"n\":\"Skill #15 (Illusion)\"},{\"t\":3,\"n\":\"Skill #16 (Restoration)\"},{\"t\":3,\"n\":\"Skill #17 (Enchanting)\"}]},{\"t\":3,\"n\":\"Health\"},{\"t\":3,\"n\":\"Magicka\"},{\"t\":3,\"n\":\"Stamina\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":5,\"n\":\"Far away model distance\"},{\"t\":3,\"n\":\"Geared up weapons\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":9,\"s\":1,\"p\":1,\"n\":\"Head Parts\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"PNAM - Head Part\"}],\"lt\":\"HCLF - Hair Color\",\"lf\":\"QNAM - Texture lighting\"},{\"t\":3,\"p\":1,\"n\":\"HCLF - Hair Color\",\"lt\":\"FTST - Head texture\",\"lf\":\"Head Parts\"},{\"t\":3,\"n\":\"ZNAM - Combat Style\"},{\"t\":3,\"n\":\"GNAM - Gift Filter\"},{\"t\":11,\"n\":\"NAM5 - Unknown\"},{\"t\":5,\"n\":\"NAM6 - Height\"},{\"t\":5,\"n\":\"NAM7 - Weight\"},{\"t\":3,\"n\":\"NAM8 - Sound Level\"},{\"t\":10,\"n\":\"Sound Types\",\"c\":[{\"t\":6,\"n\":\"Sound Type\",\"c\":[{\"t\":3,\"n\":\"CSDT - Type\"},{\"t\":10,\"n\":\"Sounds\",\"c\":[{\"t\":6,\"n\":\"Sound\",\"c\":[{\"t\":3,\"n\":\"CSDI - Sound\"},{\"t\":3,\"n\":\"CSDC - Sound Chance\"}]}]}]}]},{\"t\":3,\"n\":\"CSCR - Inherits Sounds From\"},{\"t\":3,\"n\":\"DOFT - Default outfit\"},{\"t\":3,\"n\":\"SOFT - Sleeping outfit\"},{\"t\":3,\"n\":\"DPLT - Default Package List\"},{\"t\":3,\"n\":\"CRIF - Crime faction\"},{\"t\":3,\"p\":1,\"n\":\"FTST - Head texture\",\"lt\":\"Tint Layers\",\"lf\":\"HCLF - Hair Color\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"QNAM - Texture lighting\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Red\"},{\"t\":5,\"p\":1,\"n\":\"Green\"},{\"t\":5,\"p\":1,\"n\":\"Blue\"}],\"lt\":\"Head Parts\",\"lf\":\"NAM9 - Face morph\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"NAM9 - Face morph\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Nose Long\\/Short\"},{\"t\":5,\"p\":1,\"n\":\"Nose Up\\/Down\"},{\"t\":5,\"p\":1,\"n\":\"Jaw Up\\/Down\"},{\"t\":5,\"p\":1,\"n\":\"Jaw Narrow\\/Wide\"},{\"t\":5,\"p\":1,\"n\":\"Jaw Farward\\/Back\"},{\"t\":5,\"p\":1,\"n\":\"Cheeks Up\\/Down\"},{\"t\":5,\"p\":1,\"n\":\"Cheeks Farward\\/Back\"},{\"t\":5,\"p\":1,\"n\":\"Eyes Up\\/Down\"},{\"t\":5,\"p\":1,\"n\":\"Eyes In\\/Out\"},{\"t\":5,\"p\":1,\"n\":\"Brows Up\\/Down\"},{\"t\":5,\"p\":1,\"n\":\"Brows In\\/Out\"},{\"t\":5,\"p\":1,\"n\":\"Brows Farward\\/Back\"},{\"t\":5,\"p\":1,\"n\":\"Lips Up\\/Down\"},{\"t\":5,\"p\":1,\"n\":\"Lips In\\/Out\"},{\"t\":5,\"p\":1,\"n\":\"Chin Narrow\\/Wide\"},{\"t\":5,\"p\":1,\"n\":\"Chin Up\\/Down\"},{\"t\":5,\"p\":1,\"n\":\"Chin Underbite\\/Overbite\"},{\"t\":5,\"p\":1,\"n\":\"Eyes Farward\\/Back\"},{\"t\":5,\"p\":1,\"n\":\"Unknown\"}],\"lt\":\"QNAM - Texture lighting\",\"lf\":\"NAMA - Face parts\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"NAMA - Face parts\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Nose\"},{\"t\":3,\"p\":1,\"n\":\"Unknown\"},{\"t\":3,\"p\":1,\"n\":\"Eyes\"},{\"t\":3,\"p\":1,\"n\":\"Mouth\"}],\"lt\":\"NAM9 - Face morph\",\"lf\":\"Tint Layers\"},{\"t\":10,\"s\":1,\"p\":1,\"n\":\"Tint Layers\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Layer\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"TINI - Tint Index\"}]}],\"lt\":\"NAMA - Face parts\",\"lf\":\"FTST - Head texture\"}]}]},\"name\":\"Bash.NpcFacesForceFullImport\",\"hash\":\"$3A36AED9\",\"color\":255}"
  },
  {
    "path": "frontend/settings/Skyrim/Bash.R.AddSpells.json",
    "content": "{\"records\":\"RACE\",\"description\":\"R.AddSpells tag from Wrye Bash.\\r\\n\\r\\nUsed when the mod adds spells to racial spell list(s). Either R.ChangeSpells or R.AddSpells should be used for a plugin, not both.\",\"tree\":{\"records\":[{\"t\":1,\"p\":1,\"n\":\"RACE - Race\",\"c\":[{\"t\":6,\"n\":\"Record Header\",\"c\":[{\"t\":2,\"n\":\"Signature\"},{\"t\":3,\"n\":\"Data Size\"},{\"t\":3,\"n\":\"Record Flags\"},{\"t\":3,\"n\":\"FormID\"},{\"t\":11,\"n\":\"Version Control Info 1\"},{\"t\":3,\"n\":\"Form Version\"},{\"t\":11,\"n\":\"Version Control Info 2\"}]},{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"n\":\"FULL - Name\"},{\"t\":2,\"n\":\"DESC - Description\"},{\"t\":3,\"n\":\"SPCT - Count\"},{\"t\":9,\"p\":1,\"n\":\"Actor Effects\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"SPLO - Actor Effect\"}]},{\"t\":3,\"n\":\"WNAM - Skin\"},{\"t\":6,\"n\":\"BOD2 - Biped Body Template\",\"c\":[{\"t\":3,\"n\":\"First Person Flags\"},{\"t\":3,\"n\":\"General Flags\"},{\"n\":\"Unused\"},{\"t\":3,\"n\":\"Armor Type\"}]},{\"t\":3,\"n\":\"KSIZ - Keyword Count\"},{\"t\":9,\"n\":\"KWDA - Keywords\",\"c\":[{\"t\":3,\"n\":\"Keyword\"}]},{\"t\":6,\"n\":\"DATA - \",\"c\":[{\"t\":10,\"n\":\"Skill Boosts\",\"c\":[{\"t\":6,\"n\":\"Skill Boost\",\"c\":[{\"t\":3,\"n\":\"Skill\"},{\"t\":3,\"n\":\"Boost\"}]},{\"t\":6,\"n\":\"Skill Boost\",\"c\":[{\"t\":3,\"n\":\"Skill\"},{\"t\":3,\"n\":\"Boost\"}]},{\"t\":6,\"n\":\"Skill Boost\",\"c\":[{\"t\":3,\"n\":\"Skill\"},{\"t\":3,\"n\":\"Boost\"}]},{\"t\":6,\"n\":\"Skill Boost\",\"c\":[{\"t\":3,\"n\":\"Skill\"},{\"t\":3,\"n\":\"Boost\"}]},{\"t\":6,\"n\":\"Skill Boost\",\"c\":[{\"t\":3,\"n\":\"Skill\"},{\"t\":3,\"n\":\"Boost\"}]},{\"t\":6,\"n\":\"Skill Boost\",\"c\":[{\"t\":3,\"n\":\"Skill\"},{\"t\":3,\"n\":\"Boost\"}]},{\"t\":6,\"n\":\"Skill Boost\",\"c\":[{\"t\":3,\"n\":\"Skill\"},{\"t\":3,\"n\":\"Boost\"}]}]},{\"t\":11,\"n\":\"Unknown\"},{\"t\":5,\"n\":\"Male Height\"},{\"t\":5,\"n\":\"Female Height\"},{\"t\":5,\"n\":\"Male Weight\"},{\"t\":5,\"n\":\"Female Weight\"},{\"t\":3,\"n\":\"Flags\"},{\"t\":5,\"n\":\"Starting Health\"},{\"t\":5,\"n\":\"Starting Magicka\"},{\"t\":5,\"n\":\"Starting Stamina\"},{\"t\":5,\"n\":\"Base Carry Weight\"},{\"t\":5,\"n\":\"Base Mass\"},{\"t\":5,\"n\":\"Acceleration rate\"},{\"t\":5,\"n\":\"Deceleration rate\"},{\"t\":3,\"n\":\"Size\"},{\"t\":3,\"n\":\"Head Biped Object\"},{\"t\":3,\"n\":\"Hair Biped Object\"},{\"t\":5,\"n\":\"Injured Health Pct\"},{\"t\":3,\"n\":\"Shield Biped Object\"},{\"t\":5,\"n\":\"Health Regen\"},{\"t\":5,\"n\":\"Magicka Regen\"},{\"t\":5,\"n\":\"Stamina Regen\"},{\"t\":5,\"n\":\"Unarmed Damage\"},{\"t\":5,\"n\":\"Unarmed Reach\"},{\"t\":3,\"n\":\"Body Biped Object\"},{\"t\":5,\"n\":\"Aim Angle Tolerance\"},{\"t\":5,\"n\":\"Flight Radius\"},{\"t\":5,\"n\":\"Angular Acceleration Rate\"},{\"t\":5,\"n\":\"Angular Tolerance\"},{\"t\":3,\"n\":\"Flags 2\"},{\"t\":6,\"n\":\"Mount Data\",\"c\":[{\"t\":5,\"n\":\"Offset X\"},{\"t\":5,\"n\":\"Offset Y\"},{\"t\":5,\"n\":\"Unknown\"},{\"t\":5,\"n\":\"Unknown\"},{\"t\":5,\"n\":\"Unknown\"},{\"t\":5,\"n\":\"Unknown\"},{\"t\":5,\"n\":\"Unknown\"},{\"t\":5,\"n\":\"Unknown\"},{\"t\":5,\"n\":\"Unknown\"}]}]},{\"n\":\"MNAM - Male Marker\"},{\"t\":2,\"n\":\"ANAM - Male Skeletal Model\"},{\"t\":11,\"n\":\"MODT - Texture Files Hashes\"},{\"n\":\"FNAM - Female Marker\"},{\"t\":2,\"n\":\"ANAM - Female Skeletal Model\"},{\"t\":11,\"n\":\"MODT - Texture Files Hashes\"},{\"n\":\"NAM2 - Marker NAM2 #1\"},{\"t\":9,\"n\":\"Movement Type Names\",\"c\":[{\"t\":2,\"n\":\"MTNM - Name\"}]},{\"t\":7,\"n\":\"VTCK - Voices\",\"c\":[{\"t\":3,\"n\":\"Voice #0 (Male)\"},{\"t\":3,\"n\":\"Voice #1 (Female)\"}]},{\"t\":7,\"n\":\"DNAM - Decapitate Armors\",\"c\":[{\"t\":3,\"n\":\"Decapitate Armor #0 (Male)\"},{\"t\":3,\"n\":\"Decapitate Armor #1 (Female)\"}]},{\"t\":7,\"n\":\"HCLF - Default Hair Colors\",\"c\":[{\"t\":3,\"n\":\"Default Hair Color #0 (Male)\"},{\"t\":3,\"n\":\"Default Hair Color #1 (Female)\"}]},{\"t\":3,\"n\":\"TINL - Total Number of Tints in List\"},{\"t\":5,\"n\":\"PNAM - FaceGen - Main clamp\"},{\"t\":5,\"n\":\"UNAM - FaceGen - Face clamp\"},{\"t\":3,\"n\":\"ATKR - Attack Race\"},{\"t\":10,\"n\":\"Attacks\",\"c\":[{\"t\":6,\"n\":\"Attack\",\"c\":[{\"t\":6,\"n\":\"ATKD - Attack Data\",\"c\":[{\"t\":5,\"n\":\"Damage Mult\"},{\"t\":5,\"n\":\"Attack Chance\"},{\"t\":3,\"n\":\"Attack Spell\"},{\"t\":3,\"n\":\"Attack Flags\"},{\"t\":5,\"n\":\"Attack Angle\"},{\"t\":5,\"n\":\"Strike Angle\"},{\"t\":5,\"n\":\"Stagger\"},{\"t\":3,\"n\":\"Attack Type\"},{\"t\":5,\"n\":\"Knockdown\"},{\"t\":5,\"n\":\"Recovery Time\"},{\"t\":5,\"n\":\"Stamina Mult\"}]}]}]},{\"t\":6,\"n\":\"Body Data\",\"c\":[{\"n\":\"NAM1 - Body Data Marker\"},{\"t\":6,\"n\":\"Male Body Data\",\"c\":[{\"n\":\"MNAM - Male Data Marker\"},{\"t\":10,\"n\":\"Parts\",\"c\":[{\"t\":6,\"n\":\"Part\",\"c\":[{\"t\":3,\"n\":\"INDX - Index\"}]}]}]},{\"t\":6,\"n\":\"Female Body Data\",\"c\":[{\"n\":\"FNAM - Female Data Marker\"},{\"t\":10,\"n\":\"Parts\",\"c\":[{\"t\":6,\"n\":\"Part\",\"c\":[{\"t\":3,\"n\":\"INDX - Index\"}]}]}]}]},{\"t\":9,\"n\":\"HNAM - Hairs\",\"c\":[{\"t\":3,\"n\":\"Hair\"}]},{\"t\":9,\"n\":\"ENAM - Eyes\",\"c\":[{\"t\":3,\"n\":\"Eye\"}]},{\"t\":3,\"n\":\"GNAM - Body Part Data\"},{\"n\":\"NAM2 - Marker NAM2 #2\"},{\"n\":\"NAM3 - Marker NAM3 #3\"},{\"t\":6,\"n\":\"Male Behavior Graph\",\"c\":[{\"n\":\"MNAM - Male Data Marker\"}]},{\"t\":6,\"n\":\"Female Behavior Graph\",\"c\":[{\"n\":\"FNAM - Female Data Marker\"}]},{\"t\":3,\"n\":\"NAM4 - Material Type\"},{\"t\":3,\"n\":\"NAM5 - Impact Data Set\"},{\"t\":3,\"n\":\"NAM7 - Decapitation FX\"},{\"t\":3,\"n\":\"ONAM - Open Loot Sound\"},{\"t\":3,\"n\":\"LNAM - Close Loot Sound\"},{\"t\":7,\"n\":\"Biped Object Names\",\"c\":[{\"t\":2,\"n\":\"NAME - Name\"}]},{\"t\":10,\"n\":\"Movement Types\",\"c\":[{\"t\":6,\"n\":\"Movement Types\",\"c\":[{\"t\":3,\"n\":\"MTYP - Movement Type\"}]}]},{\"t\":3,\"n\":\"VNAM - Equipment Flags\"},{\"t\":9,\"n\":\"Equip Slots\",\"c\":[{\"t\":3,\"n\":\"QNAM - Equip Slot\"}]},{\"t\":3,\"n\":\"UNES - Unarmed Equip Slot\"},{\"t\":7,\"n\":\"Phoneme Target Names\",\"c\":[{\"t\":2,\"n\":\"PHTN - Name\"}]},{\"t\":6,\"n\":\"FaceFX Phonemes\",\"c\":[{\"t\":6,\"n\":\"IY\",\"c\":[{\"t\":6,\"n\":\"PHWT - Phoneme Target Weight\",\"c\":[{\"t\":5,\"n\":\"Aah \\/ LipBigAah\"},{\"t\":5,\"n\":\"BigAah \\/ LipDST\"},{\"t\":5,\"n\":\"BMP \\/ LipEee\"},{\"t\":5,\"n\":\"ChJsh \\/ LipFV\"},{\"t\":5,\"n\":\"DST \\/ LipK\"},{\"t\":5,\"n\":\"Eee \\/ LipL\"},{\"t\":5,\"n\":\"Eh \\/ LipR\"},{\"t\":5,\"n\":\"FV \\/ LipTh\"},{\"t\":5,\"n\":\"I\"},{\"t\":5,\"n\":\"K\"},{\"t\":5,\"n\":\"N\"},{\"t\":5,\"n\":\"Oh\"},{\"t\":5,\"n\":\"OohQ\"},{\"t\":5,\"n\":\"R\"},{\"t\":5,\"n\":\"TH\"},{\"t\":5,\"n\":\"W\"}]}]}]},{\"t\":3,\"n\":\"WKMV - Base Movement Default - Walk\"},{\"t\":3,\"n\":\"RNMV - Base Movement Default - Run\"},{\"t\":3,\"n\":\"SWMV - Base Movement Default - Swim\"},{\"t\":3,\"n\":\"FLMV - Base Movement Default - Fly\"},{\"t\":3,\"n\":\"SNMV - Base Movement Default - Sneak\"},{\"t\":3,\"n\":\"SPMV - Base Movement Default - Sprint\"},{\"t\":6,\"n\":\"Head Data\",\"c\":[{\"n\":\"NAM0 - Head Data Marker\"},{\"t\":6,\"n\":\"Male Head Data\",\"c\":[{\"n\":\"MNAM - Male Data Marker\"}]},{\"t\":6,\"n\":\"Female Head Data\",\"c\":[{\"n\":\"NAM0 - Head Data Marker\"},{\"n\":\"FNAM - Female Data Marker\"}]}]},{\"t\":3,\"n\":\"NAM8 - Morph race\"},{\"t\":3,\"n\":\"RNAM - Armor race\"}]}]},\"name\":\"Bash.R.AddSpells\",\"hash\":\"$4A672F91\",\"color\":255}"
  },
  {
    "path": "frontend/settings/Skyrim/Bash.R.ChangeSpells.json",
    "content": "{\"records\":\"RACE\",\"description\":\"R.ChangeSpells tag from Wrye Bash.\\r\\n\\r\\nUsed when the mod modifies racial spell list(s) (beyond adding spells). Either R.ChangeSpells or R.AddSpells should be used for a plugin, not both.\",\"tree\":{\"records\":[{\"t\":1,\"p\":1,\"n\":\"RACE - Race\",\"c\":[{\"t\":6,\"n\":\"Record Header\",\"c\":[{\"t\":2,\"n\":\"Signature\"},{\"t\":3,\"n\":\"Data Size\"},{\"t\":3,\"n\":\"Record Flags\"},{\"t\":3,\"n\":\"FormID\"},{\"t\":11,\"n\":\"Version Control Info 1\"},{\"t\":3,\"n\":\"Form Version\"},{\"t\":11,\"n\":\"Version Control Info 2\"}]},{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"n\":\"FULL - Name\"},{\"t\":2,\"n\":\"DESC - Description\"},{\"t\":3,\"n\":\"SPCT - Count\"},{\"t\":9,\"s\":1,\"p\":1,\"n\":\"Actor Effects\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"SPLO - Actor Effect\"}]},{\"t\":3,\"n\":\"WNAM - Skin\"},{\"t\":6,\"n\":\"BOD2 - Biped Body Template\",\"c\":[{\"t\":3,\"n\":\"First Person Flags\"},{\"t\":3,\"n\":\"General Flags\"},{\"n\":\"Unused\"},{\"t\":3,\"n\":\"Armor Type\"}]},{\"t\":3,\"n\":\"KSIZ - Keyword Count\"},{\"t\":9,\"n\":\"KWDA - Keywords\",\"c\":[{\"t\":3,\"n\":\"Keyword\"}]},{\"t\":6,\"n\":\"DATA - \",\"c\":[{\"t\":10,\"n\":\"Skill Boosts\",\"c\":[{\"t\":6,\"n\":\"Skill Boost\",\"c\":[{\"t\":3,\"n\":\"Skill\"},{\"t\":3,\"n\":\"Boost\"}]},{\"t\":6,\"n\":\"Skill Boost\",\"c\":[{\"t\":3,\"n\":\"Skill\"},{\"t\":3,\"n\":\"Boost\"}]},{\"t\":6,\"n\":\"Skill Boost\",\"c\":[{\"t\":3,\"n\":\"Skill\"},{\"t\":3,\"n\":\"Boost\"}]},{\"t\":6,\"n\":\"Skill Boost\",\"c\":[{\"t\":3,\"n\":\"Skill\"},{\"t\":3,\"n\":\"Boost\"}]},{\"t\":6,\"n\":\"Skill Boost\",\"c\":[{\"t\":3,\"n\":\"Skill\"},{\"t\":3,\"n\":\"Boost\"}]},{\"t\":6,\"n\":\"Skill Boost\",\"c\":[{\"t\":3,\"n\":\"Skill\"},{\"t\":3,\"n\":\"Boost\"}]},{\"t\":6,\"n\":\"Skill Boost\",\"c\":[{\"t\":3,\"n\":\"Skill\"},{\"t\":3,\"n\":\"Boost\"}]}]},{\"t\":11,\"n\":\"Unknown\"},{\"t\":5,\"n\":\"Male Height\"},{\"t\":5,\"n\":\"Female Height\"},{\"t\":5,\"n\":\"Male Weight\"},{\"t\":5,\"n\":\"Female Weight\"},{\"t\":3,\"n\":\"Flags\"},{\"t\":5,\"n\":\"Starting Health\"},{\"t\":5,\"n\":\"Starting Magicka\"},{\"t\":5,\"n\":\"Starting Stamina\"},{\"t\":5,\"n\":\"Base Carry Weight\"},{\"t\":5,\"n\":\"Base Mass\"},{\"t\":5,\"n\":\"Acceleration rate\"},{\"t\":5,\"n\":\"Deceleration rate\"},{\"t\":3,\"n\":\"Size\"},{\"t\":3,\"n\":\"Head Biped Object\"},{\"t\":3,\"n\":\"Hair Biped Object\"},{\"t\":5,\"n\":\"Injured Health Pct\"},{\"t\":3,\"n\":\"Shield Biped Object\"},{\"t\":5,\"n\":\"Health Regen\"},{\"t\":5,\"n\":\"Magicka Regen\"},{\"t\":5,\"n\":\"Stamina Regen\"},{\"t\":5,\"n\":\"Unarmed Damage\"},{\"t\":5,\"n\":\"Unarmed Reach\"},{\"t\":3,\"n\":\"Body Biped Object\"},{\"t\":5,\"n\":\"Aim Angle Tolerance\"},{\"t\":5,\"n\":\"Flight Radius\"},{\"t\":5,\"n\":\"Angular Acceleration Rate\"},{\"t\":5,\"n\":\"Angular Tolerance\"},{\"t\":3,\"n\":\"Flags 2\"},{\"t\":6,\"n\":\"Mount Data\",\"c\":[{\"t\":5,\"n\":\"Offset X\"},{\"t\":5,\"n\":\"Offset Y\"},{\"t\":5,\"n\":\"Unknown\"},{\"t\":5,\"n\":\"Unknown\"},{\"t\":5,\"n\":\"Unknown\"},{\"t\":5,\"n\":\"Unknown\"},{\"t\":5,\"n\":\"Unknown\"},{\"t\":5,\"n\":\"Unknown\"},{\"t\":5,\"n\":\"Unknown\"}]}]},{\"n\":\"MNAM - Male Marker\"},{\"t\":2,\"n\":\"ANAM - Male Skeletal Model\"},{\"t\":11,\"n\":\"MODT - Texture Files Hashes\"},{\"n\":\"FNAM - Female Marker\"},{\"t\":2,\"n\":\"ANAM - Female Skeletal Model\"},{\"t\":11,\"n\":\"MODT - Texture Files Hashes\"},{\"n\":\"NAM2 - Marker NAM2 #1\"},{\"t\":9,\"n\":\"Movement Type Names\",\"c\":[{\"t\":2,\"n\":\"MTNM - Name\"}]},{\"t\":7,\"n\":\"VTCK - Voices\",\"c\":[{\"t\":3,\"n\":\"Voice #0 (Male)\"},{\"t\":3,\"n\":\"Voice #1 (Female)\"}]},{\"t\":7,\"n\":\"DNAM - Decapitate Armors\",\"c\":[{\"t\":3,\"n\":\"Decapitate Armor #0 (Male)\"},{\"t\":3,\"n\":\"Decapitate Armor #1 (Female)\"}]},{\"t\":7,\"n\":\"HCLF - Default Hair Colors\",\"c\":[{\"t\":3,\"n\":\"Default Hair Color #0 (Male)\"},{\"t\":3,\"n\":\"Default Hair Color #1 (Female)\"}]},{\"t\":3,\"n\":\"TINL - Total Number of Tints in List\"},{\"t\":5,\"n\":\"PNAM - FaceGen - Main clamp\"},{\"t\":5,\"n\":\"UNAM - FaceGen - Face clamp\"},{\"t\":3,\"n\":\"ATKR - Attack Race\"},{\"t\":10,\"n\":\"Attacks\",\"c\":[{\"t\":6,\"n\":\"Attack\",\"c\":[{\"t\":6,\"n\":\"ATKD - Attack Data\",\"c\":[{\"t\":5,\"n\":\"Damage Mult\"},{\"t\":5,\"n\":\"Attack Chance\"},{\"t\":3,\"n\":\"Attack Spell\"},{\"t\":3,\"n\":\"Attack Flags\"},{\"t\":5,\"n\":\"Attack Angle\"},{\"t\":5,\"n\":\"Strike Angle\"},{\"t\":5,\"n\":\"Stagger\"},{\"t\":3,\"n\":\"Attack Type\"},{\"t\":5,\"n\":\"Knockdown\"},{\"t\":5,\"n\":\"Recovery Time\"},{\"t\":5,\"n\":\"Stamina Mult\"}]}]}]},{\"t\":6,\"n\":\"Body Data\",\"c\":[{\"n\":\"NAM1 - Body Data Marker\"},{\"t\":6,\"n\":\"Male Body Data\",\"c\":[{\"n\":\"MNAM - Male Data Marker\"},{\"t\":10,\"n\":\"Parts\",\"c\":[{\"t\":6,\"n\":\"Part\",\"c\":[{\"t\":3,\"n\":\"INDX - Index\"}]}]}]},{\"t\":6,\"n\":\"Female Body Data\",\"c\":[{\"n\":\"FNAM - Female Data Marker\"},{\"t\":10,\"n\":\"Parts\",\"c\":[{\"t\":6,\"n\":\"Part\",\"c\":[{\"t\":3,\"n\":\"INDX - Index\"}]}]}]}]},{\"t\":9,\"n\":\"HNAM - Hairs\",\"c\":[{\"t\":3,\"n\":\"Hair\"}]},{\"t\":9,\"n\":\"ENAM - Eyes\",\"c\":[{\"t\":3,\"n\":\"Eye\"}]},{\"t\":3,\"n\":\"GNAM - Body Part Data\"},{\"n\":\"NAM2 - Marker NAM2 #2\"},{\"n\":\"NAM3 - Marker NAM3 #3\"},{\"t\":6,\"n\":\"Male Behavior Graph\",\"c\":[{\"n\":\"MNAM - Male Data Marker\"}]},{\"t\":6,\"n\":\"Female Behavior Graph\",\"c\":[{\"n\":\"FNAM - Female Data Marker\"}]},{\"t\":3,\"n\":\"NAM4 - Material Type\"},{\"t\":3,\"n\":\"NAM5 - Impact Data Set\"},{\"t\":3,\"n\":\"NAM7 - Decapitation FX\"},{\"t\":3,\"n\":\"ONAM - Open Loot Sound\"},{\"t\":3,\"n\":\"LNAM - Close Loot Sound\"},{\"t\":7,\"n\":\"Biped Object Names\",\"c\":[{\"t\":2,\"n\":\"NAME - Name\"}]},{\"t\":10,\"n\":\"Movement Types\",\"c\":[{\"t\":6,\"n\":\"Movement Types\",\"c\":[{\"t\":3,\"n\":\"MTYP - Movement Type\"}]}]},{\"t\":3,\"n\":\"VNAM - Equipment Flags\"},{\"t\":9,\"n\":\"Equip Slots\",\"c\":[{\"t\":3,\"n\":\"QNAM - Equip Slot\"}]},{\"t\":3,\"n\":\"UNES - Unarmed Equip Slot\"},{\"t\":7,\"n\":\"Phoneme Target Names\",\"c\":[{\"t\":2,\"n\":\"PHTN - Name\"}]},{\"t\":6,\"n\":\"FaceFX Phonemes\",\"c\":[{\"t\":6,\"n\":\"IY\",\"c\":[{\"t\":6,\"n\":\"PHWT - Phoneme Target Weight\",\"c\":[{\"t\":5,\"n\":\"Aah \\/ LipBigAah\"},{\"t\":5,\"n\":\"BigAah \\/ LipDST\"},{\"t\":5,\"n\":\"BMP \\/ LipEee\"},{\"t\":5,\"n\":\"ChJsh \\/ LipFV\"},{\"t\":5,\"n\":\"DST \\/ LipK\"},{\"t\":5,\"n\":\"Eee \\/ LipL\"},{\"t\":5,\"n\":\"Eh \\/ LipR\"},{\"t\":5,\"n\":\"FV \\/ LipTh\"},{\"t\":5,\"n\":\"I\"},{\"t\":5,\"n\":\"K\"},{\"t\":5,\"n\":\"N\"},{\"t\":5,\"n\":\"Oh\"},{\"t\":5,\"n\":\"OohQ\"},{\"t\":5,\"n\":\"R\"},{\"t\":5,\"n\":\"TH\"},{\"t\":5,\"n\":\"W\"}]}]}]},{\"t\":3,\"n\":\"WKMV - Base Movement Default - Walk\"},{\"t\":3,\"n\":\"RNMV - Base Movement Default - Run\"},{\"t\":3,\"n\":\"SWMV - Base Movement Default - Swim\"},{\"t\":3,\"n\":\"FLMV - Base Movement Default - Fly\"},{\"t\":3,\"n\":\"SNMV - Base Movement Default - Sneak\"},{\"t\":3,\"n\":\"SPMV - Base Movement Default - Sprint\"},{\"t\":6,\"n\":\"Head Data\",\"c\":[{\"n\":\"NAM0 - Head Data Marker\"},{\"t\":6,\"n\":\"Male Head Data\",\"c\":[{\"n\":\"MNAM - Male Data Marker\"}]},{\"t\":6,\"n\":\"Female Head Data\",\"c\":[{\"n\":\"NAM0 - Head Data Marker\"},{\"n\":\"FNAM - Female Data Marker\"}]}]},{\"t\":3,\"n\":\"NAM8 - Morph race\"},{\"t\":3,\"n\":\"RNAM - Armor race\"}]}]},\"name\":\"Bash.R.ChangeSpells\",\"hash\":\"$14C55D3A\",\"color\":255}"
  },
  {
    "path": "frontend/settings/Skyrim/Bash.R.Description.json",
    "content": "{\"records\":\"RACE\",\"description\":\"R.Description tag from Wrye Bash.\\r\\n\\r\\nUsed when the mod modifies race descriptions.\",\"tree\":{\"records\":[{\"t\":1,\"p\":1,\"n\":\"RACE - Race\",\"c\":[{\"t\":6,\"n\":\"Record Header\",\"c\":[{\"t\":2,\"n\":\"Signature\"},{\"t\":3,\"n\":\"Data Size\"},{\"t\":3,\"n\":\"Record Flags\"},{\"t\":3,\"n\":\"FormID\"},{\"t\":11,\"n\":\"Version Control Info 1\"},{\"t\":3,\"n\":\"Form Version\"},{\"t\":11,\"n\":\"Version Control Info 2\"}]},{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"n\":\"FULL - Name\"},{\"t\":2,\"p\":1,\"n\":\"DESC - Description\"},{\"t\":3,\"n\":\"SPCT - Count\"},{\"t\":9,\"n\":\"Actor Effects\",\"c\":[{\"t\":3,\"n\":\"SPLO - Actor Effect\"}]},{\"t\":3,\"n\":\"WNAM - Skin\"},{\"t\":6,\"n\":\"BOD2 - Biped Body Template\",\"c\":[{\"t\":3,\"n\":\"First Person Flags\"},{\"t\":3,\"n\":\"General Flags\"},{\"n\":\"Unused\"},{\"t\":3,\"n\":\"Armor Type\"}]},{\"t\":3,\"n\":\"KSIZ - Keyword Count\"},{\"t\":9,\"n\":\"KWDA - Keywords\",\"c\":[{\"t\":3,\"n\":\"Keyword\"}]},{\"t\":6,\"n\":\"DATA - \",\"c\":[{\"t\":10,\"n\":\"Skill Boosts\",\"c\":[{\"t\":6,\"n\":\"Skill Boost\",\"c\":[{\"t\":3,\"n\":\"Skill\"},{\"t\":3,\"n\":\"Boost\"}]},{\"t\":6,\"n\":\"Skill Boost\",\"c\":[{\"t\":3,\"n\":\"Skill\"},{\"t\":3,\"n\":\"Boost\"}]},{\"t\":6,\"n\":\"Skill Boost\",\"c\":[{\"t\":3,\"n\":\"Skill\"},{\"t\":3,\"n\":\"Boost\"}]},{\"t\":6,\"n\":\"Skill Boost\",\"c\":[{\"t\":3,\"n\":\"Skill\"},{\"t\":3,\"n\":\"Boost\"}]},{\"t\":6,\"n\":\"Skill Boost\",\"c\":[{\"t\":3,\"n\":\"Skill\"},{\"t\":3,\"n\":\"Boost\"}]},{\"t\":6,\"n\":\"Skill Boost\",\"c\":[{\"t\":3,\"n\":\"Skill\"},{\"t\":3,\"n\":\"Boost\"}]},{\"t\":6,\"n\":\"Skill Boost\",\"c\":[{\"t\":3,\"n\":\"Skill\"},{\"t\":3,\"n\":\"Boost\"}]}]},{\"t\":11,\"n\":\"Unknown\"},{\"t\":5,\"n\":\"Male Height\"},{\"t\":5,\"n\":\"Female Height\"},{\"t\":5,\"n\":\"Male Weight\"},{\"t\":5,\"n\":\"Female Weight\"},{\"t\":3,\"n\":\"Flags\"},{\"t\":5,\"n\":\"Starting Health\"},{\"t\":5,\"n\":\"Starting Magicka\"},{\"t\":5,\"n\":\"Starting Stamina\"},{\"t\":5,\"n\":\"Base Carry Weight\"},{\"t\":5,\"n\":\"Base Mass\"},{\"t\":5,\"n\":\"Acceleration rate\"},{\"t\":5,\"n\":\"Deceleration rate\"},{\"t\":3,\"n\":\"Size\"},{\"t\":3,\"n\":\"Head Biped Object\"},{\"t\":3,\"n\":\"Hair Biped Object\"},{\"t\":5,\"n\":\"Injured Health Pct\"},{\"t\":3,\"n\":\"Shield Biped Object\"},{\"t\":5,\"n\":\"Health Regen\"},{\"t\":5,\"n\":\"Magicka Regen\"},{\"t\":5,\"n\":\"Stamina Regen\"},{\"t\":5,\"n\":\"Unarmed Damage\"},{\"t\":5,\"n\":\"Unarmed Reach\"},{\"t\":3,\"n\":\"Body Biped Object\"},{\"t\":5,\"n\":\"Aim Angle Tolerance\"},{\"t\":5,\"n\":\"Flight Radius\"},{\"t\":5,\"n\":\"Angular Acceleration Rate\"},{\"t\":5,\"n\":\"Angular Tolerance\"},{\"t\":3,\"n\":\"Flags 2\"},{\"t\":6,\"n\":\"Mount Data\",\"c\":[{\"t\":5,\"n\":\"Offset X\"},{\"t\":5,\"n\":\"Offset Y\"},{\"t\":5,\"n\":\"Unknown\"},{\"t\":5,\"n\":\"Unknown\"},{\"t\":5,\"n\":\"Unknown\"},{\"t\":5,\"n\":\"Unknown\"},{\"t\":5,\"n\":\"Unknown\"},{\"t\":5,\"n\":\"Unknown\"},{\"t\":5,\"n\":\"Unknown\"}]}]},{\"n\":\"MNAM - Male Marker\"},{\"t\":2,\"n\":\"ANAM - Male Skeletal Model\"},{\"t\":11,\"n\":\"MODT - Texture Files Hashes\"},{\"n\":\"FNAM - Female Marker\"},{\"t\":2,\"n\":\"ANAM - Female Skeletal Model\"},{\"t\":11,\"n\":\"MODT - Texture Files Hashes\"},{\"n\":\"NAM2 - Marker NAM2 #1\"},{\"t\":9,\"n\":\"Movement Type Names\",\"c\":[{\"t\":2,\"n\":\"MTNM - Name\"}]},{\"t\":7,\"n\":\"VTCK - Voices\",\"c\":[{\"t\":3,\"n\":\"Voice #0 (Male)\"},{\"t\":3,\"n\":\"Voice #1 (Female)\"}]},{\"t\":7,\"n\":\"DNAM - Decapitate Armors\",\"c\":[{\"t\":3,\"n\":\"Decapitate Armor #0 (Male)\"},{\"t\":3,\"n\":\"Decapitate Armor #1 (Female)\"}]},{\"t\":7,\"n\":\"HCLF - Default Hair Colors\",\"c\":[{\"t\":3,\"n\":\"Default Hair Color #0 (Male)\"},{\"t\":3,\"n\":\"Default Hair Color #1 (Female)\"}]},{\"t\":3,\"n\":\"TINL - Total Number of Tints in List\"},{\"t\":5,\"n\":\"PNAM - FaceGen - Main clamp\"},{\"t\":5,\"n\":\"UNAM - FaceGen - Face clamp\"},{\"t\":3,\"n\":\"ATKR - Attack Race\"},{\"t\":10,\"n\":\"Attacks\",\"c\":[{\"t\":6,\"n\":\"Attack\",\"c\":[{\"t\":6,\"n\":\"ATKD - Attack Data\",\"c\":[{\"t\":5,\"n\":\"Damage Mult\"},{\"t\":5,\"n\":\"Attack Chance\"},{\"t\":3,\"n\":\"Attack Spell\"},{\"t\":3,\"n\":\"Attack Flags\"},{\"t\":5,\"n\":\"Attack Angle\"},{\"t\":5,\"n\":\"Strike Angle\"},{\"t\":5,\"n\":\"Stagger\"},{\"t\":3,\"n\":\"Attack Type\"},{\"t\":5,\"n\":\"Knockdown\"},{\"t\":5,\"n\":\"Recovery Time\"},{\"t\":5,\"n\":\"Stamina Mult\"}]}]}]},{\"t\":6,\"n\":\"Body Data\",\"c\":[{\"n\":\"NAM1 - Body Data Marker\"},{\"t\":6,\"n\":\"Male Body Data\",\"c\":[{\"n\":\"MNAM - Male Data Marker\"},{\"t\":10,\"n\":\"Parts\",\"c\":[{\"t\":6,\"n\":\"Part\",\"c\":[{\"t\":3,\"n\":\"INDX - Index\"}]}]}]},{\"t\":6,\"n\":\"Female Body Data\",\"c\":[{\"n\":\"FNAM - Female Data Marker\"},{\"t\":10,\"n\":\"Parts\",\"c\":[{\"t\":6,\"n\":\"Part\",\"c\":[{\"t\":3,\"n\":\"INDX - Index\"}]}]}]}]},{\"t\":9,\"n\":\"HNAM - Hairs\",\"c\":[{\"t\":3,\"n\":\"Hair\"}]},{\"t\":9,\"n\":\"ENAM - Eyes\",\"c\":[{\"t\":3,\"n\":\"Eye\"}]},{\"t\":3,\"n\":\"GNAM - Body Part Data\"},{\"n\":\"NAM2 - Marker NAM2 #2\"},{\"n\":\"NAM3 - Marker NAM3 #3\"},{\"t\":6,\"n\":\"Male Behavior Graph\",\"c\":[{\"n\":\"MNAM - Male Data Marker\"}]},{\"t\":6,\"n\":\"Female Behavior Graph\",\"c\":[{\"n\":\"FNAM - Female Data Marker\"}]},{\"t\":3,\"n\":\"NAM4 - Material Type\"},{\"t\":3,\"n\":\"NAM5 - Impact Data Set\"},{\"t\":3,\"n\":\"NAM7 - Decapitation FX\"},{\"t\":3,\"n\":\"ONAM - Open Loot Sound\"},{\"t\":3,\"n\":\"LNAM - Close Loot Sound\"},{\"t\":7,\"n\":\"Biped Object Names\",\"c\":[{\"t\":2,\"n\":\"NAME - Name\"}]},{\"t\":10,\"n\":\"Movement Types\",\"c\":[{\"t\":6,\"n\":\"Movement Types\",\"c\":[{\"t\":3,\"n\":\"MTYP - Movement Type\"}]}]},{\"t\":3,\"n\":\"VNAM - Equipment Flags\"},{\"t\":9,\"n\":\"Equip Slots\",\"c\":[{\"t\":3,\"n\":\"QNAM - Equip Slot\"}]},{\"t\":3,\"n\":\"UNES - Unarmed Equip Slot\"},{\"t\":7,\"n\":\"Phoneme Target Names\",\"c\":[{\"t\":2,\"n\":\"PHTN - Name\"}]},{\"t\":6,\"n\":\"FaceFX Phonemes\",\"c\":[{\"t\":6,\"n\":\"IY\",\"c\":[{\"t\":6,\"n\":\"PHWT - Phoneme Target Weight\",\"c\":[{\"t\":5,\"n\":\"Aah \\/ LipBigAah\"},{\"t\":5,\"n\":\"BigAah \\/ LipDST\"},{\"t\":5,\"n\":\"BMP \\/ LipEee\"},{\"t\":5,\"n\":\"ChJsh \\/ LipFV\"},{\"t\":5,\"n\":\"DST \\/ LipK\"},{\"t\":5,\"n\":\"Eee \\/ LipL\"},{\"t\":5,\"n\":\"Eh \\/ LipR\"},{\"t\":5,\"n\":\"FV \\/ LipTh\"},{\"t\":5,\"n\":\"I\"},{\"t\":5,\"n\":\"K\"},{\"t\":5,\"n\":\"N\"},{\"t\":5,\"n\":\"Oh\"},{\"t\":5,\"n\":\"OohQ\"},{\"t\":5,\"n\":\"R\"},{\"t\":5,\"n\":\"TH\"},{\"t\":5,\"n\":\"W\"}]}]}]},{\"t\":3,\"n\":\"WKMV - Base Movement Default - Walk\"},{\"t\":3,\"n\":\"RNMV - Base Movement Default - Run\"},{\"t\":3,\"n\":\"SWMV - Base Movement Default - Swim\"},{\"t\":3,\"n\":\"FLMV - Base Movement Default - Fly\"},{\"t\":3,\"n\":\"SNMV - Base Movement Default - Sneak\"},{\"t\":3,\"n\":\"SPMV - Base Movement Default - Sprint\"},{\"t\":6,\"n\":\"Head Data\",\"c\":[{\"n\":\"NAM0 - Head Data Marker\"},{\"t\":6,\"n\":\"Male Head Data\",\"c\":[{\"n\":\"MNAM - Male Data Marker\"}]},{\"t\":6,\"n\":\"Female Head Data\",\"c\":[{\"n\":\"NAM0 - Head Data Marker\"},{\"n\":\"FNAM - Female Data Marker\"}]}]},{\"t\":3,\"n\":\"NAM8 - Morph race\"},{\"t\":3,\"n\":\"RNAM - Armor race\"}]}]},\"name\":\"Bash.R.Description\",\"hash\":\"$66D005FB\",\"color\":255}"
  },
  {
    "path": "frontend/settings/Skyrim/Bash.R.Head.json",
    "content": "{\"records\":\"RACE\",\"description\":\"R.Head tag from Wrye Bash.\\r\\n\\r\\nUsed when the mod modifies race heads.\",\"tree\":{\"records\":[{\"t\":1,\"p\":1,\"n\":\"RACE - Race\",\"c\":[{\"t\":6,\"n\":\"Record Header\",\"c\":[{\"t\":2,\"n\":\"Signature\"},{\"t\":3,\"n\":\"Data Size\"},{\"t\":3,\"n\":\"Record Flags\"},{\"t\":3,\"n\":\"FormID\"},{\"t\":11,\"n\":\"Version Control Info 1\"},{\"t\":3,\"n\":\"Form Version\"},{\"t\":11,\"n\":\"Version Control Info 2\"}]},{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"n\":\"FULL - Name\"},{\"t\":2,\"p\":1,\"n\":\"DESC - Description\"},{\"t\":3,\"n\":\"SPCT - Count\"},{\"t\":9,\"n\":\"Actor Effects\",\"c\":[{\"t\":3,\"n\":\"SPLO - Actor Effect\"}]},{\"t\":3,\"n\":\"WNAM - Skin\"},{\"t\":6,\"n\":\"BOD2 - Biped Body Template\",\"c\":[{\"t\":3,\"n\":\"First Person Flags\"},{\"t\":3,\"n\":\"General Flags\"},{\"n\":\"Unused\"},{\"t\":3,\"n\":\"Armor Type\"}]},{\"t\":3,\"n\":\"KSIZ - Keyword Count\"},{\"t\":9,\"n\":\"KWDA - Keywords\",\"c\":[{\"t\":3,\"n\":\"Keyword\"}]},{\"t\":6,\"n\":\"DATA - \",\"c\":[{\"t\":10,\"n\":\"Skill Boosts\",\"c\":[{\"t\":6,\"n\":\"Skill Boost\",\"c\":[{\"t\":3,\"n\":\"Skill\"},{\"t\":3,\"n\":\"Boost\"}]},{\"t\":6,\"n\":\"Skill Boost\",\"c\":[{\"t\":3,\"n\":\"Skill\"},{\"t\":3,\"n\":\"Boost\"}]},{\"t\":6,\"n\":\"Skill Boost\",\"c\":[{\"t\":3,\"n\":\"Skill\"},{\"t\":3,\"n\":\"Boost\"}]},{\"t\":6,\"n\":\"Skill Boost\",\"c\":[{\"t\":3,\"n\":\"Skill\"},{\"t\":3,\"n\":\"Boost\"}]},{\"t\":6,\"n\":\"Skill Boost\",\"c\":[{\"t\":3,\"n\":\"Skill\"},{\"t\":3,\"n\":\"Boost\"}]},{\"t\":6,\"n\":\"Skill Boost\",\"c\":[{\"t\":3,\"n\":\"Skill\"},{\"t\":3,\"n\":\"Boost\"}]},{\"t\":6,\"n\":\"Skill Boost\",\"c\":[{\"t\":3,\"n\":\"Skill\"},{\"t\":3,\"n\":\"Boost\"}]}]},{\"t\":11,\"n\":\"Unknown\"},{\"t\":5,\"n\":\"Male Height\"},{\"t\":5,\"n\":\"Female Height\"},{\"t\":5,\"n\":\"Male Weight\"},{\"t\":5,\"n\":\"Female Weight\"},{\"t\":3,\"n\":\"Flags\"},{\"t\":5,\"n\":\"Starting Health\"},{\"t\":5,\"n\":\"Starting Magicka\"},{\"t\":5,\"n\":\"Starting Stamina\"},{\"t\":5,\"n\":\"Base Carry Weight\"},{\"t\":5,\"n\":\"Base Mass\"},{\"t\":5,\"n\":\"Acceleration rate\"},{\"t\":5,\"n\":\"Deceleration rate\"},{\"t\":3,\"n\":\"Size\"},{\"t\":3,\"n\":\"Head Biped Object\"},{\"t\":3,\"n\":\"Hair Biped Object\"},{\"t\":5,\"n\":\"Injured Health Pct\"},{\"t\":3,\"n\":\"Shield Biped Object\"},{\"t\":5,\"n\":\"Health Regen\"},{\"t\":5,\"n\":\"Magicka Regen\"},{\"t\":5,\"n\":\"Stamina Regen\"},{\"t\":5,\"n\":\"Unarmed Damage\"},{\"t\":5,\"n\":\"Unarmed Reach\"},{\"t\":3,\"n\":\"Body Biped Object\"},{\"t\":5,\"n\":\"Aim Angle Tolerance\"},{\"t\":5,\"n\":\"Flight Radius\"},{\"t\":5,\"n\":\"Angular Acceleration Rate\"},{\"t\":5,\"n\":\"Angular Tolerance\"},{\"t\":3,\"n\":\"Flags 2\"},{\"t\":6,\"n\":\"Mount Data\",\"c\":[{\"t\":5,\"n\":\"Offset X\"},{\"t\":5,\"n\":\"Offset Y\"},{\"t\":5,\"n\":\"Unknown\"},{\"t\":5,\"n\":\"Unknown\"},{\"t\":5,\"n\":\"Unknown\"},{\"t\":5,\"n\":\"Unknown\"},{\"t\":5,\"n\":\"Unknown\"},{\"t\":5,\"n\":\"Unknown\"},{\"t\":5,\"n\":\"Unknown\"}]}]},{\"n\":\"MNAM - Male Marker\"},{\"t\":2,\"n\":\"ANAM - Male Skeletal Model\"},{\"t\":11,\"n\":\"MODT - Texture Files Hashes\"},{\"n\":\"FNAM - Female Marker\"},{\"t\":2,\"n\":\"ANAM - Female Skeletal Model\"},{\"t\":11,\"n\":\"MODT - Texture Files Hashes\"},{\"n\":\"NAM2 - Marker NAM2 #1\"},{\"t\":9,\"n\":\"Movement Type Names\",\"c\":[{\"t\":2,\"n\":\"MTNM - Name\"}]},{\"t\":7,\"n\":\"VTCK - Voices\",\"c\":[{\"t\":3,\"n\":\"Voice #0 (Male)\"},{\"t\":3,\"n\":\"Voice #1 (Female)\"}]},{\"t\":7,\"n\":\"DNAM - Decapitate Armors\",\"c\":[{\"t\":3,\"n\":\"Decapitate Armor #0 (Male)\"},{\"t\":3,\"n\":\"Decapitate Armor #1 (Female)\"}]},{\"t\":7,\"n\":\"HCLF - Default Hair Colors\",\"c\":[{\"t\":3,\"n\":\"Default Hair Color #0 (Male)\"},{\"t\":3,\"n\":\"Default Hair Color #1 (Female)\"}]},{\"t\":3,\"n\":\"TINL - Total Number of Tints in List\"},{\"t\":5,\"n\":\"PNAM - FaceGen - Main clamp\"},{\"t\":5,\"n\":\"UNAM - FaceGen - Face clamp\"},{\"t\":3,\"n\":\"ATKR - Attack Race\"},{\"t\":10,\"n\":\"Attacks\",\"c\":[{\"t\":6,\"n\":\"Attack\",\"c\":[{\"t\":6,\"n\":\"ATKD - Attack Data\",\"c\":[{\"t\":5,\"n\":\"Damage Mult\"},{\"t\":5,\"n\":\"Attack Chance\"},{\"t\":3,\"n\":\"Attack Spell\"},{\"t\":3,\"n\":\"Attack Flags\"},{\"t\":5,\"n\":\"Attack Angle\"},{\"t\":5,\"n\":\"Strike Angle\"},{\"t\":5,\"n\":\"Stagger\"},{\"t\":3,\"n\":\"Attack Type\"},{\"t\":5,\"n\":\"Knockdown\"},{\"t\":5,\"n\":\"Recovery Time\"},{\"t\":5,\"n\":\"Stamina Mult\"}]}]}]},{\"t\":6,\"n\":\"Body Data\",\"c\":[{\"n\":\"NAM1 - Body Data Marker\"},{\"t\":6,\"n\":\"Male Body Data\",\"c\":[{\"n\":\"MNAM - Male Data Marker\"},{\"t\":10,\"n\":\"Parts\",\"c\":[{\"t\":6,\"n\":\"Part\",\"c\":[{\"t\":3,\"n\":\"INDX - Index\"}]}]}]},{\"t\":6,\"n\":\"Female Body Data\",\"c\":[{\"n\":\"FNAM - Female Data Marker\"},{\"t\":10,\"n\":\"Parts\",\"c\":[{\"t\":6,\"n\":\"Part\",\"c\":[{\"t\":3,\"n\":\"INDX - Index\"}]}]}]}]},{\"t\":9,\"n\":\"HNAM - Hairs\",\"c\":[{\"t\":3,\"n\":\"Hair\"}]},{\"t\":9,\"n\":\"ENAM - Eyes\",\"c\":[{\"t\":3,\"n\":\"Eye\"}]},{\"t\":3,\"n\":\"GNAM - Body Part Data\"},{\"n\":\"NAM2 - Marker NAM2 #2\"},{\"n\":\"NAM3 - Marker NAM3 #3\"},{\"t\":6,\"n\":\"Male Behavior Graph\",\"c\":[{\"n\":\"MNAM - Male Data Marker\"}]},{\"t\":6,\"n\":\"Female Behavior Graph\",\"c\":[{\"n\":\"FNAM - Female Data Marker\"}]},{\"t\":3,\"n\":\"NAM4 - Material Type\"},{\"t\":3,\"n\":\"NAM5 - Impact Data Set\"},{\"t\":3,\"n\":\"NAM7 - Decapitation FX\"},{\"t\":3,\"n\":\"ONAM - Open Loot Sound\"},{\"t\":3,\"n\":\"LNAM - Close Loot Sound\"},{\"t\":7,\"n\":\"Biped Object Names\",\"c\":[{\"t\":2,\"n\":\"NAME - Name\"}]},{\"t\":10,\"n\":\"Movement Types\",\"c\":[{\"t\":6,\"n\":\"Movement Types\",\"c\":[{\"t\":3,\"n\":\"MTYP - Movement Type\"}]}]},{\"t\":3,\"n\":\"VNAM - Equipment Flags\"},{\"t\":9,\"n\":\"Equip Slots\",\"c\":[{\"t\":3,\"n\":\"QNAM - Equip Slot\"}]},{\"t\":3,\"n\":\"UNES - Unarmed Equip Slot\"},{\"t\":7,\"n\":\"Phoneme Target Names\",\"c\":[{\"t\":2,\"n\":\"PHTN - Name\"}]},{\"t\":6,\"n\":\"FaceFX Phonemes\",\"c\":[{\"t\":6,\"n\":\"IY\",\"c\":[{\"t\":6,\"n\":\"PHWT - Phoneme Target Weight\",\"c\":[{\"t\":5,\"n\":\"Aah \\/ LipBigAah\"},{\"t\":5,\"n\":\"BigAah \\/ LipDST\"},{\"t\":5,\"n\":\"BMP \\/ LipEee\"},{\"t\":5,\"n\":\"ChJsh \\/ LipFV\"},{\"t\":5,\"n\":\"DST \\/ LipK\"},{\"t\":5,\"n\":\"Eee \\/ LipL\"},{\"t\":5,\"n\":\"Eh \\/ LipR\"},{\"t\":5,\"n\":\"FV \\/ LipTh\"},{\"t\":5,\"n\":\"I\"},{\"t\":5,\"n\":\"K\"},{\"t\":5,\"n\":\"N\"},{\"t\":5,\"n\":\"Oh\"},{\"t\":5,\"n\":\"OohQ\"},{\"t\":5,\"n\":\"R\"},{\"t\":5,\"n\":\"TH\"},{\"t\":5,\"n\":\"W\"}]}]}]},{\"t\":3,\"n\":\"WKMV - Base Movement Default - Walk\"},{\"t\":3,\"n\":\"RNMV - Base Movement Default - Run\"},{\"t\":3,\"n\":\"SWMV - Base Movement Default - Swim\"},{\"t\":3,\"n\":\"FLMV - Base Movement Default - Fly\"},{\"t\":3,\"n\":\"SNMV - Base Movement Default - Sneak\"},{\"t\":3,\"n\":\"SPMV - Base Movement Default - Sprint\"},{\"t\":6,\"p\":1,\"n\":\"Head Data\",\"c\":[{\"n\":\"NAM0 - Head Data Marker\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Male Head Data\",\"d\":1,\"c\":[{\"p\":1,\"n\":\"MNAM - Male Data Marker\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Female Head Data\",\"d\":1,\"c\":[{\"p\":1,\"n\":\"NAM0 - Head Data Marker\"},{\"p\":1,\"n\":\"FNAM - Female Data Marker\"}]}]},{\"t\":3,\"n\":\"NAM8 - Morph race\"},{\"t\":3,\"n\":\"RNAM - Armor race\"}]}]},\"name\":\"Bash.R.Head\",\"hash\":\"$57481EA8\",\"color\":255}"
  },
  {
    "path": "frontend/settings/Skyrim/Bash.R.Skills.json",
    "content": "{\"records\":\"RACE\",\"description\":\"R.Skills tag from Wrye Bash.\\r\\n\\r\\nUsed when the mod modifies race skill bonuses.\",\"tree\":{\"records\":[{\"t\":1,\"p\":1,\"n\":\"RACE - Race\",\"c\":[{\"t\":6,\"n\":\"Record Header\",\"c\":[{\"t\":2,\"n\":\"Signature\"},{\"t\":3,\"n\":\"Data Size\"},{\"t\":3,\"n\":\"Record Flags\"},{\"t\":3,\"n\":\"FormID\"},{\"t\":11,\"n\":\"Version Control Info 1\"},{\"t\":3,\"n\":\"Form Version\"},{\"t\":11,\"n\":\"Version Control Info 2\"}]},{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"n\":\"FULL - Name\"},{\"t\":2,\"p\":1,\"n\":\"DESC - Description\"},{\"t\":3,\"n\":\"SPCT - Count\"},{\"t\":9,\"n\":\"Actor Effects\",\"c\":[{\"t\":3,\"n\":\"SPLO - Actor Effect\"}]},{\"t\":3,\"n\":\"WNAM - Skin\"},{\"t\":6,\"n\":\"BOD2 - Biped Body Template\",\"c\":[{\"t\":3,\"n\":\"First Person Flags\"},{\"t\":3,\"n\":\"General Flags\"},{\"n\":\"Unused\"},{\"t\":3,\"n\":\"Armor Type\"}]},{\"t\":3,\"n\":\"KSIZ - Keyword Count\"},{\"t\":9,\"n\":\"KWDA - Keywords\",\"c\":[{\"t\":3,\"n\":\"Keyword\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DATA - \",\"c\":[{\"t\":10,\"p\":1,\"n\":\"Skill Boosts\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Skill Boost\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Skill\"},{\"t\":3,\"p\":1,\"n\":\"Boost\"}]},{\"t\":6,\"p\":1,\"n\":\"Skill Boost\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Skill\"},{\"t\":3,\"p\":1,\"n\":\"Boost\"}]},{\"t\":6,\"p\":1,\"n\":\"Skill Boost\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Skill\"},{\"t\":3,\"p\":1,\"n\":\"Boost\"}]},{\"t\":6,\"p\":1,\"n\":\"Skill Boost\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Skill\"},{\"t\":3,\"p\":1,\"n\":\"Boost\"}]},{\"t\":6,\"p\":1,\"n\":\"Skill Boost\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Skill\"},{\"t\":3,\"p\":1,\"n\":\"Boost\"}]},{\"t\":6,\"p\":1,\"n\":\"Skill Boost\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Skill\"},{\"t\":3,\"p\":1,\"n\":\"Boost\"}]},{\"t\":6,\"p\":1,\"n\":\"Skill Boost\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Skill\"},{\"t\":3,\"p\":1,\"n\":\"Boost\"}]}]},{\"t\":11,\"p\":1,\"n\":\"Unknown\"},{\"t\":5,\"p\":1,\"n\":\"Male Height\"},{\"t\":5,\"p\":1,\"n\":\"Female Height\"},{\"t\":5,\"p\":1,\"n\":\"Male Weight\"},{\"t\":5,\"p\":1,\"n\":\"Female Weight\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":5,\"p\":1,\"n\":\"Starting Health\"},{\"t\":5,\"p\":1,\"n\":\"Starting Magicka\"},{\"t\":5,\"p\":1,\"n\":\"Starting Stamina\"},{\"t\":5,\"p\":1,\"n\":\"Base Carry Weight\"},{\"t\":5,\"p\":1,\"n\":\"Base Mass\"},{\"t\":5,\"p\":1,\"n\":\"Acceleration rate\"},{\"t\":5,\"p\":1,\"n\":\"Deceleration rate\"},{\"t\":3,\"p\":1,\"n\":\"Size\"},{\"t\":3,\"p\":1,\"n\":\"Head Biped Object\"},{\"t\":3,\"p\":1,\"n\":\"Hair Biped Object\"},{\"t\":5,\"p\":1,\"n\":\"Injured Health Pct\"},{\"t\":3,\"p\":1,\"n\":\"Shield Biped Object\"},{\"t\":5,\"p\":1,\"n\":\"Health Regen\"},{\"t\":5,\"p\":1,\"n\":\"Magicka Regen\"},{\"t\":5,\"p\":1,\"n\":\"Stamina Regen\"},{\"t\":5,\"p\":1,\"n\":\"Unarmed Damage\"},{\"t\":5,\"p\":1,\"n\":\"Unarmed Reach\"},{\"t\":3,\"p\":1,\"n\":\"Body Biped Object\"},{\"t\":5,\"p\":1,\"n\":\"Aim Angle Tolerance\"},{\"t\":5,\"p\":1,\"n\":\"Flight Radius\"},{\"t\":5,\"p\":1,\"n\":\"Angular Acceleration Rate\"},{\"t\":5,\"p\":1,\"n\":\"Angular Tolerance\"},{\"t\":3,\"p\":1,\"n\":\"Flags 2\"},{\"t\":6,\"p\":1,\"n\":\"Mount Data\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Offset X\"},{\"t\":5,\"p\":1,\"n\":\"Offset Y\"},{\"t\":5,\"p\":1,\"n\":\"Unknown\"},{\"t\":5,\"p\":1,\"n\":\"Unknown\"},{\"t\":5,\"p\":1,\"n\":\"Unknown\"},{\"t\":5,\"p\":1,\"n\":\"Unknown\"},{\"t\":5,\"p\":1,\"n\":\"Unknown\"},{\"t\":5,\"p\":1,\"n\":\"Unknown\"},{\"t\":5,\"p\":1,\"n\":\"Unknown\"}]}]},{\"n\":\"MNAM - Male Marker\"},{\"t\":2,\"n\":\"ANAM - Male Skeletal Model\"},{\"t\":11,\"n\":\"MODT - Texture Files Hashes\"},{\"n\":\"FNAM - Female Marker\"},{\"t\":2,\"n\":\"ANAM - Female Skeletal Model\"},{\"t\":11,\"n\":\"MODT - Texture Files Hashes\"},{\"n\":\"NAM2 - Marker NAM2 #1\"},{\"t\":9,\"n\":\"Movement Type Names\",\"c\":[{\"t\":2,\"n\":\"MTNM - Name\"}]},{\"t\":7,\"n\":\"VTCK - Voices\",\"c\":[{\"t\":3,\"n\":\"Voice #0 (Male)\"},{\"t\":3,\"n\":\"Voice #1 (Female)\"}]},{\"t\":7,\"n\":\"DNAM - Decapitate Armors\",\"c\":[{\"t\":3,\"n\":\"Decapitate Armor #0 (Male)\"},{\"t\":3,\"n\":\"Decapitate Armor #1 (Female)\"}]},{\"t\":7,\"n\":\"HCLF - Default Hair Colors\",\"c\":[{\"t\":3,\"n\":\"Default Hair Color #0 (Male)\"},{\"t\":3,\"n\":\"Default Hair Color #1 (Female)\"}]},{\"t\":3,\"n\":\"TINL - Total Number of Tints in List\"},{\"t\":5,\"n\":\"PNAM - FaceGen - Main clamp\"},{\"t\":5,\"n\":\"UNAM - FaceGen - Face clamp\"},{\"t\":3,\"n\":\"ATKR - Attack Race\"},{\"t\":10,\"n\":\"Attacks\",\"c\":[{\"t\":6,\"n\":\"Attack\",\"c\":[{\"t\":6,\"n\":\"ATKD - Attack Data\",\"c\":[{\"t\":5,\"n\":\"Damage Mult\"},{\"t\":5,\"n\":\"Attack Chance\"},{\"t\":3,\"n\":\"Attack Spell\"},{\"t\":3,\"n\":\"Attack Flags\"},{\"t\":5,\"n\":\"Attack Angle\"},{\"t\":5,\"n\":\"Strike Angle\"},{\"t\":5,\"n\":\"Stagger\"},{\"t\":3,\"n\":\"Attack Type\"},{\"t\":5,\"n\":\"Knockdown\"},{\"t\":5,\"n\":\"Recovery Time\"},{\"t\":5,\"n\":\"Stamina Mult\"}]}]}]},{\"t\":6,\"n\":\"Body Data\",\"c\":[{\"n\":\"NAM1 - Body Data Marker\"},{\"t\":6,\"n\":\"Male Body Data\",\"c\":[{\"n\":\"MNAM - Male Data Marker\"},{\"t\":10,\"n\":\"Parts\",\"c\":[{\"t\":6,\"n\":\"Part\",\"c\":[{\"t\":3,\"n\":\"INDX - Index\"}]}]}]},{\"t\":6,\"n\":\"Female Body Data\",\"c\":[{\"n\":\"FNAM - Female Data Marker\"},{\"t\":10,\"n\":\"Parts\",\"c\":[{\"t\":6,\"n\":\"Part\",\"c\":[{\"t\":3,\"n\":\"INDX - Index\"}]}]}]}]},{\"t\":9,\"n\":\"HNAM - Hairs\",\"c\":[{\"t\":3,\"n\":\"Hair\"}]},{\"t\":9,\"n\":\"ENAM - Eyes\",\"c\":[{\"t\":3,\"n\":\"Eye\"}]},{\"t\":3,\"n\":\"GNAM - Body Part Data\"},{\"n\":\"NAM2 - Marker NAM2 #2\"},{\"n\":\"NAM3 - Marker NAM3 #3\"},{\"t\":6,\"n\":\"Male Behavior Graph\",\"c\":[{\"n\":\"MNAM - Male Data Marker\"}]},{\"t\":6,\"n\":\"Female Behavior Graph\",\"c\":[{\"n\":\"FNAM - Female Data Marker\"}]},{\"t\":3,\"n\":\"NAM4 - Material Type\"},{\"t\":3,\"n\":\"NAM5 - Impact Data Set\"},{\"t\":3,\"n\":\"NAM7 - Decapitation FX\"},{\"t\":3,\"n\":\"ONAM - Open Loot Sound\"},{\"t\":3,\"n\":\"LNAM - Close Loot Sound\"},{\"t\":7,\"n\":\"Biped Object Names\",\"c\":[{\"t\":2,\"n\":\"NAME - Name\"}]},{\"t\":10,\"n\":\"Movement Types\",\"c\":[{\"t\":6,\"n\":\"Movement Types\",\"c\":[{\"t\":3,\"n\":\"MTYP - Movement Type\"}]}]},{\"t\":3,\"n\":\"VNAM - Equipment Flags\"},{\"t\":9,\"n\":\"Equip Slots\",\"c\":[{\"t\":3,\"n\":\"QNAM - Equip Slot\"}]},{\"t\":3,\"n\":\"UNES - Unarmed Equip Slot\"},{\"t\":7,\"n\":\"Phoneme Target Names\",\"c\":[{\"t\":2,\"n\":\"PHTN - Name\"}]},{\"t\":6,\"n\":\"FaceFX Phonemes\",\"c\":[{\"t\":6,\"n\":\"IY\",\"c\":[{\"t\":6,\"n\":\"PHWT - Phoneme Target Weight\",\"c\":[{\"t\":5,\"n\":\"Aah \\/ LipBigAah\"},{\"t\":5,\"n\":\"BigAah \\/ LipDST\"},{\"t\":5,\"n\":\"BMP \\/ LipEee\"},{\"t\":5,\"n\":\"ChJsh \\/ LipFV\"},{\"t\":5,\"n\":\"DST \\/ LipK\"},{\"t\":5,\"n\":\"Eee \\/ LipL\"},{\"t\":5,\"n\":\"Eh \\/ LipR\"},{\"t\":5,\"n\":\"FV \\/ LipTh\"},{\"t\":5,\"n\":\"I\"},{\"t\":5,\"n\":\"K\"},{\"t\":5,\"n\":\"N\"},{\"t\":5,\"n\":\"Oh\"},{\"t\":5,\"n\":\"OohQ\"},{\"t\":5,\"n\":\"R\"},{\"t\":5,\"n\":\"TH\"},{\"t\":5,\"n\":\"W\"}]}]}]},{\"t\":3,\"n\":\"WKMV - Base Movement Default - Walk\"},{\"t\":3,\"n\":\"RNMV - Base Movement Default - Run\"},{\"t\":3,\"n\":\"SWMV - Base Movement Default - Swim\"},{\"t\":3,\"n\":\"FLMV - Base Movement Default - Fly\"},{\"t\":3,\"n\":\"SNMV - Base Movement Default - Sneak\"},{\"t\":3,\"n\":\"SPMV - Base Movement Default - Sprint\"},{\"t\":6,\"n\":\"Head Data\",\"c\":[{\"n\":\"NAM0 - Head Data Marker\"},{\"t\":6,\"n\":\"Male Head Data\",\"d\":1,\"c\":[{\"n\":\"MNAM - Male Data Marker\"}]},{\"t\":6,\"n\":\"Female Head Data\",\"d\":1,\"c\":[{\"n\":\"NAM0 - Head Data Marker\"},{\"n\":\"FNAM - Female Data Marker\"}]}]},{\"t\":3,\"n\":\"NAM8 - Morph race\"},{\"t\":3,\"n\":\"RNAM - Armor race\"}]}]},\"name\":\"Bash.R.Skills\",\"hash\":\"$6C639A99\",\"color\":255}"
  },
  {
    "path": "frontend/settings/Skyrim/Bash.Relations.json",
    "content": "{\"records\":\"FACT\",\"description\":\"Relations tag from Wrye Bash.\\r\\n\\r\\nUsed when the mod modifies faction relationships.\",\"tree\":{\"records\":[{\"t\":1,\"p\":1,\"n\":\"FACT - Faction\",\"c\":[{\"t\":6,\"n\":\"Record Header\",\"c\":[{\"t\":2,\"n\":\"Signature\"},{\"t\":3,\"n\":\"Data Size\"},{\"t\":3,\"n\":\"Record Flags\"},{\"t\":3,\"n\":\"FormID\"},{\"t\":11,\"n\":\"Version Control Info 1\"},{\"t\":3,\"n\":\"Form Version\"},{\"t\":11,\"n\":\"Version Control Info 2\"}]},{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"n\":\"FULL - Name\"},{\"t\":10,\"p\":1,\"n\":\"Relations\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"XNAM - Relation\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Faction\"},{\"t\":3,\"p\":1,\"n\":\"Modifier\"},{\"t\":3,\"p\":1,\"n\":\"Group Combat Reaction\"}]}]},{\"t\":6,\"n\":\"DATA - Flags\",\"c\":[{\"t\":3,\"n\":\"Flags\"}]},{\"t\":3,\"n\":\"JAIL - Exterior Jail Marker\"},{\"t\":3,\"n\":\"WAIT - Follower Wait Marker\"},{\"t\":3,\"n\":\"STOL - Stolen Goods Container\"},{\"t\":3,\"n\":\"PLCN - Player Inventory Container\"},{\"t\":3,\"n\":\"CRGR - Shared Crime Faction List\"},{\"t\":3,\"n\":\"JOUT - Jail Outfit\"},{\"t\":6,\"n\":\"CRVA - Crime Values\",\"c\":[{\"t\":3,\"n\":\"Arrest\"},{\"t\":3,\"n\":\"Attack On Sight\"},{\"t\":3,\"n\":\"Murder\"},{\"t\":3,\"n\":\"Assault\"},{\"t\":3,\"n\":\"Trespass\"},{\"t\":3,\"n\":\"Pickpocket\"},{\"t\":3,\"n\":\"Unknown\"},{\"t\":5,\"n\":\"Steal Multiplier\"},{\"t\":3,\"n\":\"Escape\"},{\"t\":3,\"n\":\"Werewolf\"}]},{\"t\":10,\"n\":\"Ranks\",\"c\":[{\"t\":6,\"n\":\"Rank\",\"c\":[{\"t\":3,\"n\":\"RNAM - Rank#\"}]}]},{\"t\":3,\"n\":\"VEND - Vendor Buy\\/Sell List\"},{\"t\":3,\"n\":\"VENC - Merchant Container\"},{\"t\":6,\"n\":\"VENV - Vendor Values\",\"c\":[{\"t\":3,\"n\":\"Start Hour\"},{\"t\":3,\"n\":\"End Hour\"},{\"t\":3,\"n\":\"Radius\"},{\"t\":11,\"n\":\"Unknown 1\"},{\"t\":3,\"n\":\"Only Buys Stolen Items\"},{\"t\":3,\"n\":\"Not\\/Sell Buy\"},{\"t\":11,\"n\":\"Unknown 2\"}]},{\"t\":6,\"n\":\"PLVD - Location\",\"c\":[{\"t\":3,\"n\":\"Type\"},{\"t\":12,\"n\":\"Location Value\"},{\"t\":3,\"n\":\"Radius\"}]},{\"t\":3,\"n\":\"CITC - Condition Count\"},{\"t\":8,\"n\":\"Conditions\",\"c\":[{\"t\":6,\"n\":\"Condition\",\"c\":[{\"t\":6,\"n\":\"CTDA - \",\"c\":[{\"t\":3,\"n\":\"Type\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":12,\"n\":\"Comparison Value\"},{\"t\":3,\"n\":\"Function\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":12,\"n\":\"Parameter #1\"},{\"t\":12,\"n\":\"Parameter #2\"},{\"t\":3,\"n\":\"Run On\"},{\"t\":12,\"n\":\"Reference\"},{\"t\":3,\"n\":\"Parameter #3\"}]}]}]}]}]},\"name\":\"Bash.Relations\",\"hash\":\"$D2149284\",\"color\":255}"
  },
  {
    "path": "frontend/settings/Skyrim/Bash.Relev.json",
    "content": "{\"records\":\"LVLI,LVSP,LVLN\",\"description\":\"Relev tag from Wrye Bash.\\r\\n\\r\\nRe-levelling of entries from the leveled list entries in Leveled Actor (LVLN), Leveled Item (LVLI) or Leveled Spell (LVSP) records.\\r\\n\\r\\nOnly changes to existing leveled list entries in the Level or Count element will be carried forward.  Will also restore deleted leveled list entries.\",\"tree\":{\"records\":[{\"t\":1,\"p\":1,\"n\":\"LVLI - Leveled Item\",\"c\":[{\"t\":6,\"n\":\"Record Header\",\"c\":[{\"t\":2,\"n\":\"Signature\"},{\"t\":3,\"n\":\"Data Size\"},{\"t\":3,\"n\":\"Record Flags\"},{\"t\":3,\"n\":\"FormID\"},{\"t\":11,\"n\":\"Version Control Info 1\"},{\"t\":3,\"n\":\"Form Version\"},{\"t\":11,\"n\":\"Version Control Info 2\"}]},{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"n\":\"X1\"},{\"t\":3,\"n\":\"Y1\"},{\"t\":3,\"n\":\"Z1\"},{\"t\":3,\"n\":\"X2\"},{\"t\":3,\"n\":\"Y2\"},{\"t\":3,\"n\":\"Z2\"}]},{\"t\":3,\"n\":\"LVLD - Chance None\"},{\"t\":3,\"n\":\"LVLF - Flags\"},{\"t\":3,\"n\":\"LVLG - Global\"},{\"t\":3,\"n\":\"LLCT - Count\"},{\"t\":10,\"p\":1,\"o\":1,\"n\":\"Leveled List Entries\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Leveled List Entry\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"LVLO - Base Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Level\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":3,\"n\":\"Reference\"},{\"t\":3,\"p\":1,\"n\":\"Count\"},{\"t\":11,\"n\":\"Unknown\"}]}]}]}]},{\"t\":1,\"p\":1,\"n\":\"LVSP - Leveled Spell\",\"c\":[{\"t\":6,\"n\":\"Record Header\",\"c\":[{\"t\":2,\"n\":\"Signature\"},{\"t\":3,\"n\":\"Data Size\"},{\"t\":3,\"n\":\"Record Flags\"},{\"t\":3,\"n\":\"FormID\"},{\"t\":11,\"n\":\"Version Control Info 1\"},{\"t\":3,\"n\":\"Form Version\"},{\"t\":11,\"n\":\"Version Control Info 2\"}]},{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"n\":\"X1\"},{\"t\":3,\"n\":\"Y1\"},{\"t\":3,\"n\":\"Z1\"},{\"t\":3,\"n\":\"X2\"},{\"t\":3,\"n\":\"Y2\"},{\"t\":3,\"n\":\"Z2\"}]},{\"t\":3,\"n\":\"LVLD - Chance None\"},{\"t\":3,\"n\":\"LVLF - Flags\"},{\"t\":3,\"n\":\"LLCT - Count\"},{\"t\":10,\"p\":1,\"o\":1,\"n\":\"Leveled List Entries\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Leveled List Entry\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"LVLO - Base Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Level\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":3,\"n\":\"Reference\"},{\"t\":3,\"p\":1,\"n\":\"Count\"},{\"t\":11,\"n\":\"Unknown\"}]}]}]}]},{\"t\":1,\"p\":1,\"n\":\"LVLN - Leveled NPC\",\"c\":[{\"t\":6,\"n\":\"Record Header\",\"c\":[{\"t\":2,\"n\":\"Signature\"},{\"t\":3,\"n\":\"Data Size\"},{\"t\":3,\"n\":\"Record Flags\"},{\"t\":3,\"n\":\"FormID\"},{\"t\":11,\"n\":\"Version Control Info 1\"},{\"t\":3,\"n\":\"Form Version\"},{\"t\":11,\"n\":\"Version Control Info 2\"}]},{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"n\":\"X1\"},{\"t\":3,\"n\":\"Y1\"},{\"t\":3,\"n\":\"Z1\"},{\"t\":3,\"n\":\"X2\"},{\"t\":3,\"n\":\"Y2\"},{\"t\":3,\"n\":\"Z2\"}]},{\"t\":3,\"n\":\"LVLD - Chance None\"},{\"t\":3,\"n\":\"LVLF - Flags\"},{\"t\":3,\"n\":\"LVLG - Global\"},{\"t\":3,\"n\":\"LLCT - Count\"},{\"t\":10,\"p\":1,\"o\":1,\"n\":\"Leveled List Entries\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Leveled List Entry\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"LVLO - Base Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Level\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":3,\"n\":\"Reference\"},{\"t\":3,\"p\":1,\"n\":\"Count\"},{\"t\":11,\"n\":\"Unknown\"}]}]}]},{\"t\":6,\"n\":\"Model\",\"c\":[{\"t\":2,\"n\":\"MODL - Model Filename\"}]}]}]},\"name\":\"Bash.Relev\",\"hash\":\"1DFD70D9\",\"color\":255}"
  },
  {
    "path": "frontend/settings/Skyrim/Bash.Scripts.json",
    "content": "{\"records\":\"ACHR,ACTI,ARMO,BOOK,CONT,DOOR,FLOR,FURN,INFO,INGR,KEYM,LIGH,MGEF,MISC,NPC_,PACK,PERK,PHZD,QUST,REFR,SCEN,TREE,WEAP\",\"description\":\"Scripts tag from Wrye Bash.\\r\\n\\r\\nUsed when the mod modifies item, NPC or object scripts.\",\"tree\":{\"records\":[{\"t\":1,\"p\":1,\"n\":\"ACHR - Placed NPC\",\"c\":[{\"t\":3,\"n\":\"Cell\"},{\"t\":6,\"n\":\"Record Header\",\"c\":[{\"t\":2,\"n\":\"Signature\"},{\"t\":3,\"n\":\"Data Size\"},{\"t\":3,\"n\":\"Record Flags\",\"c\":[{\"t\":4,\"n\":\"Persistent\"}]},{\"t\":3,\"n\":\"FormID\"},{\"t\":11,\"n\":\"Version Control Info 1\"},{\"t\":3,\"n\":\"Form Version\"},{\"t\":11,\"n\":\"Version Control Info 2\"}]},{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"VMAD - Virtual Machine Adapter\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Version\"},{\"t\":3,\"p\":1,\"n\":\"Object Format\"},{\"t\":12,\"p\":1,\"n\":\"Data\",\"c\":[{\"t\":9,\"p\":1,\"n\":\"Scripts\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Script\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"scriptName\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":9,\"p\":1,\"n\":\"Properties\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Property\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"propertyName\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":12,\"p\":1,\"n\":\"Value\"}]}]}]}]}]}]},{\"t\":3,\"n\":\"NAME - Base\"},{\"t\":3,\"n\":\"XEZN - Encounter Zone\"},{\"t\":11,\"n\":\"XRGD - Ragdoll Data\"},{\"t\":11,\"n\":\"XRGB - Ragdoll Biped Data\"},{\"t\":6,\"n\":\"Patrol Data\",\"c\":[{\"t\":5,\"n\":\"XPRD - Idle Time\"},{\"n\":\"XPPA - Patrol Script Marker\"},{\"t\":3,\"n\":\"INAM - Idle\"}]},{\"t\":3,\"n\":\"XLCM - Level Modifier\"},{\"t\":3,\"n\":\"XMRC - Merchant Container\"},{\"t\":3,\"n\":\"XCNT - Count\"},{\"t\":5,\"n\":\"XRDS - Radius\"},{\"t\":5,\"n\":\"XHLP - Health\"},{\"t\":10,\"n\":\"Linked References\",\"c\":[{\"t\":6,\"n\":\"XLKR - Linked Reference\",\"c\":[{\"t\":3,\"n\":\"Keyword\\/Ref\"},{\"t\":3,\"n\":\"Ref\"}]}]},{\"t\":6,\"n\":\"Activate Parents\",\"c\":[{\"t\":3,\"n\":\"XAPD - Flags\"}]},{\"t\":6,\"n\":\"XCLP - Linked Reference Color\",\"c\":[{\"t\":6,\"n\":\"Link Start Color\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":6,\"n\":\"Link End Color\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unknown\"}]}]},{\"t\":3,\"n\":\"XLCN - Persistent Location\"},{\"t\":3,\"n\":\"XLRL - Location Reference\"},{\"n\":\"XIS2 - Ignored by Sandbox\"},{\"t\":7,\"n\":\"XLRT - Location Ref Type\",\"c\":[{\"t\":3,\"n\":\"Ref #0\"}]},{\"t\":3,\"n\":\"XHOR - Horse\"},{\"t\":5,\"n\":\"XHTW - Head-Tracking Weight\"},{\"t\":5,\"n\":\"XFVC - Favor Cost\"},{\"t\":6,\"n\":\"XESP - Enable Parent\",\"c\":[{\"t\":3,\"n\":\"Reference\"},{\"t\":3,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"n\":\"Ownership\",\"c\":[{\"t\":3,\"n\":\"XOWN - Owner\"}]},{\"t\":3,\"n\":\"XEMI - Emittance\"},{\"t\":3,\"n\":\"XMBR - MultiBound Reference\"},{\"n\":\"XIBS - Ignored By Sandbox\"},{\"t\":5,\"n\":\"XSCL - Scale\"},{\"t\":6,\"n\":\"DATA - Position\\/Rotation\",\"c\":[{\"t\":6,\"n\":\"Position\",\"c\":[{\"t\":5,\"n\":\"X\"},{\"t\":5,\"n\":\"Y\"},{\"t\":5,\"n\":\"Z\"}]},{\"t\":6,\"n\":\"Rotation\",\"c\":[{\"t\":5,\"n\":\"X\"},{\"t\":5,\"n\":\"Y\"},{\"t\":5,\"n\":\"Z\"}]}]}]},{\"t\":1,\"p\":1,\"n\":\"ACTI - Activator\",\"c\":[{\"t\":6,\"n\":\"Record Header\",\"c\":[{\"t\":2,\"n\":\"Signature\"},{\"t\":3,\"n\":\"Data Size\"},{\"t\":3,\"n\":\"Record Flags\"},{\"t\":3,\"n\":\"FormID\"},{\"t\":11,\"n\":\"Version Control Info 1\"},{\"t\":3,\"n\":\"Form Version\"},{\"t\":11,\"n\":\"Version Control Info 2\"}]},{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"VMAD - Virtual Machine Adapter\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Version\"},{\"t\":3,\"p\":1,\"n\":\"Object Format\"},{\"t\":12,\"p\":1,\"n\":\"Data\",\"c\":[{\"t\":9,\"p\":1,\"n\":\"Scripts\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Script\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"scriptName\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":9,\"p\":1,\"n\":\"Properties\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Property\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"propertyName\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":12,\"p\":1,\"n\":\"Value\"}]}]}]}]}]}]},{\"t\":6,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"n\":\"X1\"},{\"t\":3,\"n\":\"Y1\"},{\"t\":3,\"n\":\"Z1\"},{\"t\":3,\"n\":\"X2\"},{\"t\":3,\"n\":\"Y2\"},{\"t\":3,\"n\":\"Z2\"}]},{\"t\":2,\"n\":\"FULL - Name\"},{\"t\":6,\"n\":\"Model\",\"c\":[{\"t\":2,\"n\":\"MODL - Model Filename\"}]},{\"t\":6,\"n\":\"Destructable\",\"c\":[{\"t\":6,\"n\":\"DEST - Header\",\"c\":[{\"t\":3,\"n\":\"Health\"},{\"t\":3,\"n\":\"DEST Count\"},{\"t\":3,\"n\":\"VATS Targetable\"},{\"t\":11,\"n\":\"Unknown\"}]}]},{\"t\":3,\"n\":\"KSIZ - Keyword Count\"},{\"t\":9,\"n\":\"KWDA - Keywords\",\"c\":[{\"t\":3,\"n\":\"Keyword\"}]},{\"t\":6,\"n\":\"PNAM - Marker Color\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":3,\"n\":\"Unused\"}]},{\"t\":3,\"n\":\"SNAM - Sound - Looping\"},{\"t\":3,\"n\":\"VNAM - Sound - Activation\"},{\"t\":3,\"n\":\"WNAM - Water Type\"},{\"t\":2,\"n\":\"RNAM - Activate Text Override\"},{\"t\":3,\"n\":\"FNAM - Flags\"},{\"t\":3,\"n\":\"KNAM - Interaction Keyword\"}]},{\"t\":1,\"p\":1,\"n\":\"ARMO - Armor\",\"c\":[{\"t\":6,\"n\":\"Record Header\",\"c\":[{\"t\":2,\"n\":\"Signature\"},{\"t\":3,\"n\":\"Data Size\"},{\"t\":3,\"n\":\"Record Flags\"},{\"t\":3,\"n\":\"FormID\"},{\"t\":11,\"n\":\"Version Control Info 1\"},{\"t\":3,\"n\":\"Form Version\"},{\"t\":11,\"n\":\"Version Control Info 2\"}]},{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"VMAD - Virtual Machine Adapter\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Version\"},{\"t\":3,\"p\":1,\"n\":\"Object Format\"},{\"t\":12,\"p\":1,\"n\":\"Data\",\"c\":[{\"t\":9,\"p\":1,\"n\":\"Scripts\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Script\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"scriptName\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":9,\"p\":1,\"n\":\"Properties\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Property\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"propertyName\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":12,\"p\":1,\"n\":\"Value\"}]}]}]}]}]}]},{\"t\":6,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"n\":\"X1\"},{\"t\":3,\"n\":\"Y1\"},{\"t\":3,\"n\":\"Z1\"},{\"t\":3,\"n\":\"X2\"},{\"t\":3,\"n\":\"Y2\"},{\"t\":3,\"n\":\"Z2\"}]},{\"t\":2,\"n\":\"FULL - Name\"},{\"t\":3,\"n\":\"EITM - Object Effect\"},{\"t\":3,\"n\":\"EAMT - Enchantment Amount\"},{\"t\":6,\"n\":\"Male world model\",\"c\":[{\"t\":2,\"n\":\"MOD2 - Model Filename\"}]},{\"t\":6,\"n\":\"Icon\",\"c\":[{\"t\":2,\"n\":\"ICON - Large Icon filename\"}]},{\"t\":6,\"n\":\"Female world model\",\"c\":[{\"t\":2,\"n\":\"MOD4 - Model Filename\"}]},{\"t\":6,\"n\":\"Icon 2 (female)\",\"c\":[{\"t\":2,\"n\":\"ICO2 - Large Icon filename\"}]},{\"t\":6,\"n\":\"BOD2 - Biped Body Template\",\"c\":[{\"t\":3,\"n\":\"First Person Flags\"},{\"t\":3,\"n\":\"General Flags\"},{\"n\":\"Unused\"},{\"t\":3,\"n\":\"Armor Type\"}]},{\"t\":6,\"n\":\"Destructable\",\"c\":[{\"t\":6,\"n\":\"DEST - Header\",\"c\":[{\"t\":3,\"n\":\"Health\"},{\"t\":3,\"n\":\"DEST Count\"},{\"t\":3,\"n\":\"VATS Targetable\"},{\"t\":11,\"n\":\"Unknown\"}]}]},{\"t\":3,\"n\":\"YNAM - Sound - Pick Up\"},{\"t\":3,\"n\":\"ZNAM - Sound - Drop\"},{\"t\":2,\"n\":\"BMCT - Ragdoll Constraint Template\"},{\"t\":3,\"n\":\"ETYP - Equipment Type\"},{\"t\":3,\"n\":\"BIDS - Bash Impact Data Set\"},{\"t\":3,\"n\":\"BAMT - Alternate Block Material\"},{\"t\":3,\"n\":\"RNAM - Race\"},{\"t\":3,\"n\":\"KSIZ - Keyword Count\"},{\"t\":9,\"n\":\"KWDA - Keywords\",\"c\":[{\"t\":3,\"n\":\"Keyword\"}]},{\"t\":2,\"n\":\"DESC - Description\"},{\"t\":7,\"n\":\"Armature\",\"c\":[{\"t\":3,\"n\":\"MODL - Model Filename\"}]},{\"t\":6,\"n\":\"DATA - Data\",\"c\":[{\"t\":3,\"n\":\"Value\"},{\"t\":5,\"n\":\"Weight\"}]},{\"t\":3,\"n\":\"DNAM - Armor Rating\"},{\"t\":3,\"n\":\"TNAM - Template Armor\"}]},{\"t\":1,\"p\":1,\"n\":\"BOOK - Book\",\"c\":[{\"t\":6,\"n\":\"Record Header\",\"c\":[{\"t\":2,\"n\":\"Signature\"},{\"t\":3,\"n\":\"Data Size\"},{\"t\":3,\"n\":\"Record Flags\"},{\"t\":3,\"n\":\"FormID\"},{\"t\":11,\"n\":\"Version Control Info 1\"},{\"t\":3,\"n\":\"Form Version\"},{\"t\":11,\"n\":\"Version Control Info 2\"}]},{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"VMAD - Virtual Machine Adapter\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Version\"},{\"t\":3,\"p\":1,\"n\":\"Object Format\"},{\"t\":12,\"p\":1,\"n\":\"Data\",\"c\":[{\"t\":9,\"p\":1,\"n\":\"Scripts\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Script\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"scriptName\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":9,\"p\":1,\"n\":\"Properties\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Property\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"propertyName\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":12,\"p\":1,\"n\":\"Value\"}]}]}]}]}]}]},{\"t\":6,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"n\":\"X1\"},{\"t\":3,\"n\":\"Y1\"},{\"t\":3,\"n\":\"Z1\"},{\"t\":3,\"n\":\"X2\"},{\"t\":3,\"n\":\"Y2\"},{\"t\":3,\"n\":\"Z2\"}]},{\"t\":2,\"n\":\"FULL - Name\"},{\"t\":6,\"n\":\"Model\",\"c\":[{\"t\":2,\"n\":\"MODL - Model Filename\"}]},{\"t\":6,\"n\":\"Icon\",\"c\":[{\"t\":2,\"n\":\"ICON - Large Icon filename\"}]},{\"t\":2,\"n\":\"DESC - Book Text\"},{\"t\":6,\"n\":\"Destructable\",\"c\":[{\"t\":6,\"n\":\"DEST - Header\",\"c\":[{\"t\":3,\"n\":\"Health\"},{\"t\":3,\"n\":\"DEST Count\"},{\"t\":3,\"n\":\"VATS Targetable\"},{\"t\":11,\"n\":\"Unknown\"}]}]},{\"t\":3,\"n\":\"YNAM - Sound - Pick Up\"},{\"t\":3,\"n\":\"ZNAM - Sound - Drop\"},{\"t\":3,\"n\":\"KSIZ - Keyword Count\"},{\"t\":9,\"n\":\"KWDA - Keywords\",\"c\":[{\"t\":3,\"n\":\"Keyword\"}]},{\"t\":6,\"n\":\"DATA - Data\",\"c\":[{\"t\":3,\"n\":\"Flags\"},{\"t\":3,\"n\":\"Type\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":12,\"n\":\"Teaches\"},{\"t\":3,\"n\":\"Value\"},{\"t\":5,\"n\":\"Weight\"}]},{\"t\":3,\"n\":\"INAM - Inventory Art\"},{\"t\":2,\"n\":\"CNAM - Description\"}]},{\"t\":1,\"p\":1,\"n\":\"CONT - Container\",\"c\":[{\"t\":6,\"n\":\"Record Header\",\"c\":[{\"t\":2,\"n\":\"Signature\"},{\"t\":3,\"n\":\"Data Size\"},{\"t\":3,\"n\":\"Record Flags\"},{\"t\":3,\"n\":\"FormID\"},{\"t\":11,\"n\":\"Version Control Info 1\"},{\"t\":3,\"n\":\"Form Version\"},{\"t\":11,\"n\":\"Version Control Info 2\"}]},{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"VMAD - Virtual Machine Adapter\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Version\"},{\"t\":3,\"p\":1,\"n\":\"Object Format\"},{\"t\":12,\"p\":1,\"n\":\"Data\",\"c\":[{\"t\":9,\"p\":1,\"n\":\"Scripts\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Script\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"scriptName\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":9,\"p\":1,\"n\":\"Properties\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Property\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"propertyName\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":12,\"p\":1,\"n\":\"Value\"}]}]}]}]}]}]},{\"t\":6,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"n\":\"X1\"},{\"t\":3,\"n\":\"Y1\"},{\"t\":3,\"n\":\"Z1\"},{\"t\":3,\"n\":\"X2\"},{\"t\":3,\"n\":\"Y2\"},{\"t\":3,\"n\":\"Z2\"}]},{\"t\":2,\"n\":\"FULL - Name\"},{\"t\":6,\"n\":\"Model\",\"c\":[{\"t\":2,\"n\":\"MODL - Model Filename\"}]},{\"t\":3,\"n\":\"COCT - Count\"},{\"t\":10,\"n\":\"Items\",\"c\":[{\"t\":6,\"n\":\"Item\",\"c\":[{\"t\":6,\"n\":\"CNTO - Item\",\"c\":[{\"t\":3,\"n\":\"Item\"},{\"t\":3,\"n\":\"Count\"}]}]}]},{\"t\":6,\"n\":\"Destructable\",\"c\":[{\"t\":6,\"n\":\"DEST - Header\",\"c\":[{\"t\":3,\"n\":\"Health\"},{\"t\":3,\"n\":\"DEST Count\"},{\"t\":3,\"n\":\"VATS Targetable\"},{\"t\":11,\"n\":\"Unknown\"}]}]},{\"t\":6,\"n\":\"DATA - \",\"c\":[{\"t\":3,\"n\":\"Flags\"},{\"t\":5,\"n\":\"Weight\"}]},{\"t\":3,\"n\":\"SNAM - Sound - Open\"},{\"t\":3,\"n\":\"QNAM - Sound - Close\"}]},{\"t\":1,\"p\":1,\"n\":\"DOOR - Door\",\"c\":[{\"t\":6,\"n\":\"Record Header\",\"c\":[{\"t\":2,\"n\":\"Signature\"},{\"t\":3,\"n\":\"Data Size\"},{\"t\":3,\"n\":\"Record Flags\"},{\"t\":3,\"n\":\"FormID\"},{\"t\":11,\"n\":\"Version Control Info 1\"},{\"t\":3,\"n\":\"Form Version\"},{\"t\":11,\"n\":\"Version Control Info 2\"}]},{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"VMAD - Virtual Machine Adapter\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Version\"},{\"t\":3,\"p\":1,\"n\":\"Object Format\"},{\"t\":12,\"p\":1,\"n\":\"Data\",\"c\":[{\"t\":9,\"p\":1,\"n\":\"Scripts\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Script\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"scriptName\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":9,\"p\":1,\"n\":\"Properties\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Property\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"propertyName\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":12,\"p\":1,\"n\":\"Value\"}]}]}]}]}]}]},{\"t\":6,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"n\":\"X1\"},{\"t\":3,\"n\":\"Y1\"},{\"t\":3,\"n\":\"Z1\"},{\"t\":3,\"n\":\"X2\"},{\"t\":3,\"n\":\"Y2\"},{\"t\":3,\"n\":\"Z2\"}]},{\"t\":2,\"n\":\"FULL - Name\"},{\"t\":6,\"n\":\"Model\",\"c\":[{\"t\":2,\"n\":\"MODL - Model Filename\"}]},{\"t\":6,\"n\":\"Destructable\",\"c\":[{\"t\":6,\"n\":\"DEST - Header\",\"c\":[{\"t\":3,\"n\":\"Health\"},{\"t\":3,\"n\":\"DEST Count\"},{\"t\":3,\"n\":\"VATS Targetable\"},{\"t\":11,\"n\":\"Unknown\"}]}]},{\"t\":3,\"n\":\"SNAM - Sound - Open\"},{\"t\":3,\"n\":\"ANAM - Sound - Close\"},{\"t\":3,\"n\":\"BNAM - Sound - Loop\"},{\"t\":3,\"n\":\"FNAM - Flags\"}]},{\"t\":1,\"p\":1,\"n\":\"FLOR - Flora\",\"c\":[{\"t\":6,\"n\":\"Record Header\",\"c\":[{\"t\":2,\"n\":\"Signature\"},{\"t\":3,\"n\":\"Data Size\"},{\"t\":3,\"n\":\"Record Flags\"},{\"t\":3,\"n\":\"FormID\"},{\"t\":11,\"n\":\"Version Control Info 1\"},{\"t\":3,\"n\":\"Form Version\"},{\"t\":11,\"n\":\"Version Control Info 2\"}]},{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"VMAD - Virtual Machine Adapter\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Version\"},{\"t\":3,\"p\":1,\"n\":\"Object Format\"},{\"t\":12,\"p\":1,\"n\":\"Data\",\"c\":[{\"t\":9,\"p\":1,\"n\":\"Scripts\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Script\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"scriptName\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":9,\"p\":1,\"n\":\"Properties\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Property\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"propertyName\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":12,\"p\":1,\"n\":\"Value\"}]}]}]}]}]}]},{\"t\":6,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"n\":\"X1\"},{\"t\":3,\"n\":\"Y1\"},{\"t\":3,\"n\":\"Z1\"},{\"t\":3,\"n\":\"X2\"},{\"t\":3,\"n\":\"Y2\"},{\"t\":3,\"n\":\"Z2\"}]},{\"t\":2,\"n\":\"FULL - Name\"},{\"t\":6,\"n\":\"Model\",\"c\":[{\"t\":2,\"n\":\"MODL - Model Filename\"}]},{\"t\":6,\"n\":\"Destructable\",\"c\":[{\"t\":6,\"n\":\"DEST - Header\",\"c\":[{\"t\":3,\"n\":\"Health\"},{\"t\":3,\"n\":\"DEST Count\"},{\"t\":3,\"n\":\"VATS Targetable\"},{\"t\":11,\"n\":\"Unknown\"}]}]},{\"t\":3,\"n\":\"KSIZ - Keyword Count\"},{\"t\":9,\"n\":\"KWDA - Keywords\",\"c\":[{\"t\":3,\"n\":\"Keyword\"}]},{\"t\":11,\"n\":\"PNAM - Unknown\"},{\"t\":2,\"n\":\"RNAM - Activate Text Override\"},{\"t\":11,\"n\":\"FNAM - Unknown\"},{\"t\":3,\"n\":\"PFIG - Ingredient\"},{\"t\":3,\"n\":\"SNAM - Sound\"},{\"t\":6,\"n\":\"PFPC - Seasonal ingredient production\",\"c\":[{\"t\":3,\"n\":\"Spring\"},{\"t\":3,\"n\":\"Summer \"},{\"t\":3,\"n\":\"Fall\"},{\"t\":3,\"n\":\"Winter\"}]}]},{\"t\":1,\"p\":1,\"n\":\"FURN - Furniture\",\"c\":[{\"t\":6,\"n\":\"Record Header\",\"c\":[{\"t\":2,\"n\":\"Signature\"},{\"t\":3,\"n\":\"Data Size\"},{\"t\":3,\"n\":\"Record Flags\"},{\"t\":3,\"n\":\"FormID\"},{\"t\":11,\"n\":\"Version Control Info 1\"},{\"t\":3,\"n\":\"Form Version\"},{\"t\":11,\"n\":\"Version Control Info 2\"}]},{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"VMAD - Virtual Machine Adapter\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Version\"},{\"t\":3,\"p\":1,\"n\":\"Object Format\"},{\"t\":12,\"p\":1,\"n\":\"Data\",\"c\":[{\"t\":9,\"p\":1,\"n\":\"Scripts\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Script\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"scriptName\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":9,\"p\":1,\"n\":\"Properties\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Property\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"propertyName\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":12,\"p\":1,\"n\":\"Value\"}]}]}]}]}]}]},{\"t\":6,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"n\":\"X1\"},{\"t\":3,\"n\":\"Y1\"},{\"t\":3,\"n\":\"Z1\"},{\"t\":3,\"n\":\"X2\"},{\"t\":3,\"n\":\"Y2\"},{\"t\":3,\"n\":\"Z2\"}]},{\"t\":2,\"n\":\"FULL - Name\"},{\"t\":6,\"n\":\"Model\",\"c\":[{\"t\":2,\"n\":\"MODL - Model Filename\"}]},{\"t\":6,\"n\":\"Destructable\",\"c\":[{\"t\":6,\"n\":\"DEST - Header\",\"c\":[{\"t\":3,\"n\":\"Health\"},{\"t\":3,\"n\":\"DEST Count\"},{\"t\":3,\"n\":\"VATS Targetable\"},{\"t\":11,\"n\":\"Unknown\"}]}]},{\"t\":3,\"n\":\"KSIZ - Keyword Count\"},{\"t\":9,\"n\":\"KWDA - Keywords\",\"c\":[{\"t\":3,\"n\":\"Keyword\"}]},{\"t\":11,\"n\":\"PNAM - Unknown\"},{\"t\":3,\"n\":\"FNAM - Flags\"},{\"t\":3,\"n\":\"KNAM - Interaction Keyword\"},{\"t\":3,\"n\":\"MNAM - Active Markers \\/ Flags\"},{\"t\":6,\"n\":\"WBDT - Workbench Data\",\"c\":[{\"t\":3,\"n\":\"Bench Type\"},{\"t\":3,\"n\":\"Uses Skill\"}]},{\"t\":3,\"n\":\"NAM1 - Associated Spell\"},{\"t\":8,\"n\":\"Markers\",\"c\":[{\"t\":6,\"n\":\"Marker\",\"c\":[{\"t\":3,\"n\":\"ENAM - Marker Index\"}]}]},{\"t\":8,\"n\":\"Marker Entry Points\",\"c\":[{\"t\":6,\"n\":\"FNPR - Marker\",\"c\":[{\"t\":3,\"n\":\"Type\"},{\"t\":3,\"n\":\"Entry Points\"}]}]},{\"t\":2,\"n\":\"XMRK - Model Filename\"}]},{\"t\":1,\"p\":1,\"n\":\"INFO - Dialog response\",\"c\":[{\"t\":3,\"n\":\"Topic\"},{\"t\":6,\"n\":\"Record Header\",\"c\":[{\"t\":2,\"n\":\"Signature\"},{\"t\":3,\"n\":\"Data Size\"},{\"t\":3,\"n\":\"Record Flags\"},{\"t\":3,\"n\":\"FormID\"},{\"t\":11,\"n\":\"Version Control Info 1\"},{\"t\":3,\"n\":\"Form Version\"},{\"t\":11,\"n\":\"Version Control Info 2\"}]},{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"VMAD - Virtual Machine Adapter\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Version\"},{\"t\":3,\"p\":1,\"n\":\"Object Format\"},{\"t\":12,\"p\":1,\"n\":\"Data\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Info VMAD\",\"c\":[{\"t\":9,\"p\":1,\"n\":\"Scripts\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Script\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"scriptName\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":9,\"p\":1,\"n\":\"Properties\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Property\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"propertyName\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":12,\"p\":1,\"n\":\"Value\"}]}]}]}]},{\"t\":6,\"p\":1,\"n\":\"Script Fragments Info\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Unknown\"},{\"t\":3,\"p\":1,\"n\":\"Info Fragments Flags\"},{\"t\":2,\"p\":1,\"n\":\"fileName\"},{\"t\":7,\"p\":1,\"n\":\"Info Fragments\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Info Fragment #0\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Unknown\"},{\"t\":2,\"p\":1,\"n\":\"scriptName\"},{\"t\":2,\"p\":1,\"n\":\"fragmentName\"}]}]}]}]}]}]},{\"t\":11,\"n\":\"DATA - Unknown\"},{\"t\":6,\"n\":\"ENAM - Response flags\",\"c\":[{\"t\":3,\"n\":\"Flags\"},{\"t\":3,\"n\":\"Reset Hours\"}]},{\"t\":3,\"n\":\"TPIC - Topic\"},{\"t\":3,\"n\":\"PNAM - Previous INFO\"},{\"t\":3,\"n\":\"CNAM - Favor Level\"},{\"t\":7,\"n\":\"Link To\",\"c\":[{\"t\":3,\"n\":\"TCLT - Response\"}]},{\"t\":3,\"n\":\"DNAM - Response Data\"},{\"t\":8,\"n\":\"Responses\",\"c\":[{\"t\":6,\"n\":\"Response\",\"c\":[{\"t\":6,\"n\":\"TRDT - Response Data\",\"c\":[{\"t\":3,\"n\":\"Emotion Type\"},{\"t\":3,\"n\":\"Emotion Value\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":3,\"n\":\"Response number\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":3,\"n\":\"Sound\"},{\"t\":3,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"}]}]}]},{\"t\":8,\"n\":\"Conditions\",\"c\":[{\"t\":6,\"n\":\"Condition\",\"c\":[{\"t\":6,\"n\":\"CTDA - \",\"c\":[{\"t\":3,\"n\":\"Type\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":12,\"n\":\"Comparison Value\"},{\"t\":3,\"n\":\"Function\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":12,\"n\":\"Parameter #1\"},{\"t\":12,\"n\":\"Parameter #2\"},{\"t\":3,\"n\":\"Run On\"},{\"t\":12,\"n\":\"Reference\"},{\"t\":3,\"n\":\"Parameter #3\"}]}]}]},{\"t\":8,\"n\":\"Unknown\",\"c\":[{\"t\":6,\"n\":\"Unknown\",\"c\":[{\"t\":11,\"n\":\"SCHR - Unknown\"}]}]},{\"t\":2,\"n\":\"RNAM - Prompt\"},{\"t\":3,\"n\":\"ANAM - Speaker\"},{\"t\":3,\"n\":\"TWAT - Walk Away Topic\"},{\"t\":3,\"n\":\"ONAM - Audio Output Override\"}]},{\"t\":1,\"p\":1,\"n\":\"INGR - Ingredient\",\"c\":[{\"t\":6,\"n\":\"Record Header\",\"c\":[{\"t\":2,\"n\":\"Signature\"},{\"t\":3,\"n\":\"Data Size\"},{\"t\":3,\"n\":\"Record Flags\"},{\"t\":3,\"n\":\"FormID\"},{\"t\":11,\"n\":\"Version Control Info 1\"},{\"t\":3,\"n\":\"Form Version\"},{\"t\":11,\"n\":\"Version Control Info 2\"}]},{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"VMAD - Virtual Machine Adapter\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Version\"},{\"t\":3,\"p\":1,\"n\":\"Object Format\"},{\"t\":12,\"p\":1,\"n\":\"Data\",\"c\":[{\"t\":9,\"p\":1,\"n\":\"Scripts\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Script\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"scriptName\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":9,\"p\":1,\"n\":\"Properties\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Property\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"propertyName\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":12,\"p\":1,\"n\":\"Value\"}]}]}]}]}]}]},{\"t\":6,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"n\":\"X1\"},{\"t\":3,\"n\":\"Y1\"},{\"t\":3,\"n\":\"Z1\"},{\"t\":3,\"n\":\"X2\"},{\"t\":3,\"n\":\"Y2\"},{\"t\":3,\"n\":\"Z2\"}]},{\"t\":2,\"n\":\"FULL - Name\"},{\"t\":3,\"n\":\"KSIZ - Keyword Count\"},{\"t\":9,\"n\":\"KWDA - Keywords\",\"c\":[{\"t\":3,\"n\":\"Keyword\"}]},{\"t\":6,\"n\":\"Model\",\"c\":[{\"t\":2,\"n\":\"MODL - Model Filename\"}]},{\"t\":6,\"n\":\"Icon\",\"c\":[{\"t\":2,\"n\":\"ICON - Large Icon filename\"}]},{\"t\":6,\"n\":\"Destructable\",\"c\":[{\"t\":6,\"n\":\"DEST - Header\",\"c\":[{\"t\":3,\"n\":\"Health\"},{\"t\":3,\"n\":\"DEST Count\"},{\"t\":3,\"n\":\"VATS Targetable\"},{\"t\":11,\"n\":\"Unknown\"}]}]},{\"t\":3,\"n\":\"ETYP - Equipment Type\"},{\"t\":3,\"n\":\"YNAM - Sound - Pick Up\"},{\"t\":3,\"n\":\"ZNAM - Sound - Drop\"},{\"t\":6,\"n\":\"DATA - \",\"c\":[{\"t\":3,\"n\":\"Value\"},{\"t\":5,\"n\":\"Weight\"}]},{\"t\":6,\"n\":\"ENIT - Effect Data\",\"c\":[{\"t\":3,\"n\":\"Ingredient Value\"},{\"t\":3,\"n\":\"Flags\"}]},{\"t\":8,\"n\":\"Effects\",\"c\":[{\"t\":6,\"n\":\"Effect\",\"c\":[{\"t\":3,\"n\":\"EFID - Base Effect\"},{\"t\":6,\"n\":\"EFIT - \",\"c\":[{\"t\":5,\"n\":\"Magnitude\"},{\"t\":3,\"n\":\"Area\"},{\"t\":3,\"n\":\"Duration\"}]}]}]}]},{\"t\":1,\"p\":1,\"n\":\"KEYM - Key\",\"c\":[{\"t\":6,\"n\":\"Record Header\",\"c\":[{\"t\":2,\"n\":\"Signature\"},{\"t\":3,\"n\":\"Data Size\"},{\"t\":3,\"n\":\"Record Flags\"},{\"t\":3,\"n\":\"FormID\"},{\"t\":11,\"n\":\"Version Control Info 1\"},{\"t\":3,\"n\":\"Form Version\"},{\"t\":11,\"n\":\"Version Control Info 2\"}]},{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"VMAD - Virtual Machine Adapter\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Version\"},{\"t\":3,\"p\":1,\"n\":\"Object Format\"},{\"t\":12,\"p\":1,\"n\":\"Data\",\"c\":[{\"t\":9,\"p\":1,\"n\":\"Scripts\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Script\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"scriptName\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":9,\"p\":1,\"n\":\"Properties\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Property\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"propertyName\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":12,\"p\":1,\"n\":\"Value\"}]}]}]}]}]}]},{\"t\":6,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"n\":\"X1\"},{\"t\":3,\"n\":\"Y1\"},{\"t\":3,\"n\":\"Z1\"},{\"t\":3,\"n\":\"X2\"},{\"t\":3,\"n\":\"Y2\"},{\"t\":3,\"n\":\"Z2\"}]},{\"t\":2,\"n\":\"FULL - Name\"},{\"t\":6,\"n\":\"Model\",\"c\":[{\"t\":2,\"n\":\"MODL - Model Filename\"}]},{\"t\":6,\"n\":\"Icon\",\"c\":[{\"t\":2,\"n\":\"ICON - Large Icon filename\"}]},{\"t\":6,\"n\":\"Destructable\",\"c\":[{\"t\":6,\"n\":\"DEST - Header\",\"c\":[{\"t\":3,\"n\":\"Health\"},{\"t\":3,\"n\":\"DEST Count\"},{\"t\":3,\"n\":\"VATS Targetable\"},{\"t\":11,\"n\":\"Unknown\"}]}]},{\"t\":3,\"n\":\"YNAM - Sound - Pick Up\"},{\"t\":3,\"n\":\"ZNAM - Sound - Drop\"},{\"t\":3,\"n\":\"KSIZ - Keyword Count\"},{\"t\":9,\"n\":\"KWDA - Keywords\",\"c\":[{\"t\":3,\"n\":\"Keyword\"}]},{\"t\":6,\"n\":\"DATA - \",\"c\":[{\"t\":3,\"n\":\"Value\"},{\"t\":5,\"n\":\"Weight\"}]}]},{\"t\":1,\"p\":1,\"n\":\"LIGH - Light\",\"c\":[{\"t\":6,\"n\":\"Record Header\",\"c\":[{\"t\":2,\"n\":\"Signature\"},{\"t\":3,\"n\":\"Data Size\"},{\"t\":3,\"n\":\"Record Flags\"},{\"t\":3,\"n\":\"FormID\"},{\"t\":11,\"n\":\"Version Control Info 1\"},{\"t\":3,\"n\":\"Form Version\"},{\"t\":11,\"n\":\"Version Control Info 2\"}]},{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"VMAD - Virtual Machine Adapter\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Version\"},{\"t\":3,\"p\":1,\"n\":\"Object Format\"},{\"t\":12,\"p\":1,\"n\":\"Data\",\"c\":[{\"t\":9,\"p\":1,\"n\":\"Scripts\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Script\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"scriptName\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":9,\"p\":1,\"n\":\"Properties\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Property\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"propertyName\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":12,\"p\":1,\"n\":\"Value\"}]}]}]}]}]}]},{\"t\":6,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"n\":\"X1\"},{\"t\":3,\"n\":\"Y1\"},{\"t\":3,\"n\":\"Z1\"},{\"t\":3,\"n\":\"X2\"},{\"t\":3,\"n\":\"Y2\"},{\"t\":3,\"n\":\"Z2\"}]},{\"t\":6,\"n\":\"Model\",\"c\":[{\"t\":2,\"n\":\"MODL - Model Filename\"}]},{\"t\":6,\"n\":\"Destructable\",\"c\":[{\"t\":6,\"n\":\"DEST - Header\",\"c\":[{\"t\":3,\"n\":\"Health\"},{\"t\":3,\"n\":\"DEST Count\"},{\"t\":3,\"n\":\"VATS Targetable\"},{\"t\":11,\"n\":\"Unknown\"}]}]},{\"t\":2,\"n\":\"FULL - Name\"},{\"t\":6,\"n\":\"Icon\",\"c\":[{\"t\":2,\"n\":\"ICON - Large Icon filename\"}]},{\"t\":6,\"n\":\"DATA - \",\"c\":[{\"t\":3,\"n\":\"Time\"},{\"t\":3,\"n\":\"Radius\"},{\"t\":6,\"n\":\"Color\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":3,\"n\":\"Unknown\"}]},{\"t\":3,\"n\":\"Flags\"},{\"t\":5,\"n\":\"Falloff Exponent\"},{\"t\":5,\"n\":\"FOV\"},{\"t\":5,\"n\":\"Near Clip\"},{\"t\":6,\"n\":\"Flicker Effect\",\"c\":[{\"t\":5,\"n\":\"Period\"},{\"t\":5,\"n\":\"Intensity Amplitude\"},{\"t\":5,\"n\":\"Movement Amplitude\"}]},{\"t\":3,\"n\":\"Value\"},{\"t\":5,\"n\":\"Weight\"}]},{\"t\":5,\"n\":\"FNAM - Fade value\"},{\"t\":3,\"n\":\"SNAM - Sound\"}]},{\"t\":1,\"p\":1,\"n\":\"MGEF - Magic Effect\",\"c\":[{\"t\":6,\"n\":\"Record Header\",\"c\":[{\"t\":2,\"n\":\"Signature\"},{\"t\":3,\"n\":\"Data Size\"},{\"t\":3,\"n\":\"Record Flags\"},{\"t\":3,\"n\":\"FormID\"},{\"t\":11,\"n\":\"Version Control Info 1\"},{\"t\":3,\"n\":\"Form Version\"},{\"t\":11,\"n\":\"Version Control Info 2\"}]},{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"VMAD - Virtual Machine Adapter\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Version\"},{\"t\":3,\"p\":1,\"n\":\"Object Format\"},{\"t\":12,\"p\":1,\"n\":\"Data\",\"c\":[{\"t\":9,\"p\":1,\"n\":\"Scripts\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Script\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"scriptName\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":9,\"p\":1,\"n\":\"Properties\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Property\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"propertyName\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":12,\"p\":1,\"n\":\"Value\"}]}]}]}]}]}]},{\"t\":2,\"n\":\"FULL - Name\"},{\"t\":3,\"n\":\"MDOB - Menu Display Object\"},{\"t\":3,\"n\":\"KSIZ - Keyword Count\"},{\"t\":9,\"n\":\"KWDA - Keywords\",\"c\":[{\"t\":3,\"n\":\"Keyword\"}]},{\"t\":6,\"n\":\"Magic Effect Data\",\"c\":[{\"t\":6,\"n\":\"DATA - Data\",\"c\":[{\"t\":3,\"n\":\"Flags\"},{\"t\":5,\"n\":\"Base Cost\"},{\"t\":12,\"n\":\"Assoc. Item\"},{\"t\":3,\"n\":\"Magic Skill\"},{\"t\":3,\"n\":\"Resist Value\"},{\"t\":3,\"n\":\"Counter Effect count\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":3,\"n\":\"Casting Light\"},{\"t\":5,\"n\":\"Taper Weight\"},{\"t\":3,\"n\":\"Hit Shader\"},{\"t\":3,\"n\":\"Enchant Shader\"},{\"t\":3,\"n\":\"Minimum Skill Level\"},{\"t\":6,\"n\":\"Spellmaking\",\"c\":[{\"t\":3,\"n\":\"Area\"},{\"t\":5,\"n\":\"Casting Time\"}]},{\"t\":5,\"n\":\"Taper Curve\"},{\"t\":5,\"n\":\"Taper Duration\"},{\"t\":5,\"n\":\"Second AV Weight\"},{\"t\":3,\"n\":\"Archtype\"},{\"t\":3,\"n\":\"Actor Value\"},{\"t\":3,\"n\":\"Projectile\"},{\"t\":3,\"n\":\"Explosion\"},{\"t\":3,\"n\":\"Casting Type\"},{\"t\":3,\"n\":\"Delivery\"},{\"t\":3,\"n\":\"Second Actor Value\"},{\"t\":3,\"n\":\"Casting Art\"},{\"t\":3,\"n\":\"Hit Effect Art\"},{\"t\":3,\"n\":\"Impact Data\"},{\"t\":5,\"n\":\"Skill Usage Multiplier\"},{\"t\":6,\"n\":\"Dual Casting\",\"c\":[{\"t\":3,\"n\":\"Art\"},{\"t\":5,\"n\":\"Scale\"}]},{\"t\":3,\"n\":\"Enchant Art\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":3,\"n\":\"Equip Ability\"},{\"t\":3,\"n\":\"Image Space Modifier\"},{\"t\":3,\"n\":\"Perk to Apply\"},{\"t\":3,\"n\":\"Casting Sound Level\"},{\"t\":6,\"n\":\"Script Effect AI\",\"c\":[{\"t\":5,\"n\":\"Score\"},{\"t\":5,\"n\":\"Delay Time\"}]}]}]},{\"t\":9,\"n\":\"Counter Effects\",\"c\":[{\"t\":3,\"n\":\"ESCE - Effect\"}]},{\"t\":8,\"n\":\"SNDD - Sounds\",\"c\":[{\"t\":6,\"n\":\" #0\",\"c\":[{\"t\":3,\"n\":\"Type\"},{\"t\":3,\"n\":\"Sound\"}]}]},{\"t\":2,\"n\":\"DNAM - Magic Item Description\"},{\"t\":8,\"n\":\"Conditions\",\"c\":[{\"t\":6,\"n\":\"Condition\",\"c\":[{\"t\":6,\"n\":\"CTDA - \",\"c\":[{\"t\":3,\"n\":\"Type\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":12,\"n\":\"Comparison Value\"},{\"t\":3,\"n\":\"Function\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":12,\"n\":\"Parameter #1\"},{\"t\":12,\"n\":\"Parameter #2\"},{\"t\":3,\"n\":\"Run On\"},{\"t\":12,\"n\":\"Reference\"},{\"t\":3,\"n\":\"Parameter #3\"}]}]}]}]},{\"t\":1,\"p\":1,\"n\":\"MISC - Misc. Item\",\"c\":[{\"t\":6,\"n\":\"Record Header\",\"c\":[{\"t\":2,\"n\":\"Signature\"},{\"t\":3,\"n\":\"Data Size\"},{\"t\":3,\"n\":\"Record Flags\"},{\"t\":3,\"n\":\"FormID\"},{\"t\":11,\"n\":\"Version Control Info 1\"},{\"t\":3,\"n\":\"Form Version\"},{\"t\":11,\"n\":\"Version Control Info 2\"}]},{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"VMAD - Virtual Machine Adapter\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Version\"},{\"t\":3,\"p\":1,\"n\":\"Object Format\"},{\"t\":12,\"p\":1,\"n\":\"Data\",\"c\":[{\"t\":9,\"p\":1,\"n\":\"Scripts\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Script\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"scriptName\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":9,\"p\":1,\"n\":\"Properties\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Property\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"propertyName\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":12,\"p\":1,\"n\":\"Value\"}]}]}]}]}]}]},{\"t\":6,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"n\":\"X1\"},{\"t\":3,\"n\":\"Y1\"},{\"t\":3,\"n\":\"Z1\"},{\"t\":3,\"n\":\"X2\"},{\"t\":3,\"n\":\"Y2\"},{\"t\":3,\"n\":\"Z2\"}]},{\"t\":2,\"n\":\"FULL - Name\"},{\"t\":6,\"n\":\"Model\",\"c\":[{\"t\":2,\"n\":\"MODL - Model Filename\"}]},{\"t\":6,\"n\":\"Icon\",\"c\":[{\"t\":2,\"n\":\"ICON - Large Icon filename\"}]},{\"t\":6,\"n\":\"Destructable\",\"c\":[{\"t\":6,\"n\":\"DEST - Header\",\"c\":[{\"t\":3,\"n\":\"Health\"},{\"t\":3,\"n\":\"DEST Count\"},{\"t\":3,\"n\":\"VATS Targetable\"},{\"t\":11,\"n\":\"Unknown\"}]}]},{\"t\":3,\"n\":\"YNAM - Sound - Pick Up\"},{\"t\":3,\"n\":\"ZNAM - Sound - Drop\"},{\"t\":3,\"n\":\"KSIZ - Keyword Count\"},{\"t\":9,\"n\":\"KWDA - Keywords\",\"c\":[{\"t\":3,\"n\":\"Keyword\"}]},{\"t\":6,\"n\":\"DATA - Data\",\"c\":[{\"t\":3,\"n\":\"Value\"},{\"t\":5,\"n\":\"Weight\"}]}]},{\"t\":1,\"p\":1,\"n\":\"NPC_ - Non-Player Character (Actor)\",\"c\":[{\"t\":6,\"n\":\"Record Header\",\"c\":[{\"t\":2,\"n\":\"Signature\"},{\"t\":3,\"n\":\"Data Size\"},{\"t\":3,\"n\":\"Record Flags\"},{\"t\":3,\"n\":\"FormID\"},{\"t\":11,\"n\":\"Version Control Info 1\"},{\"t\":3,\"n\":\"Form Version\"},{\"t\":11,\"n\":\"Version Control Info 2\"}]},{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"VMAD - Virtual Machine Adapter\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Version\"},{\"t\":3,\"p\":1,\"n\":\"Object Format\"},{\"t\":12,\"p\":1,\"n\":\"Data\",\"c\":[{\"t\":9,\"p\":1,\"n\":\"Scripts\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Script\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"scriptName\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":9,\"p\":1,\"n\":\"Properties\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Property\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"propertyName\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":12,\"p\":1,\"n\":\"Value\"}]}]}]}]}]}]},{\"t\":6,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"n\":\"X1\"},{\"t\":3,\"n\":\"Y1\"},{\"t\":3,\"n\":\"Z1\"},{\"t\":3,\"n\":\"X2\"},{\"t\":3,\"n\":\"Y2\"},{\"t\":3,\"n\":\"Z2\"}]},{\"t\":6,\"n\":\"ACBS - Configuration\",\"c\":[{\"t\":3,\"n\":\"Flags\"},{\"t\":3,\"n\":\"Magicka Offset\"},{\"t\":3,\"n\":\"Stamina Offset\"},{\"t\":12,\"n\":\"Level\"},{\"t\":3,\"n\":\"Calc min level\"},{\"t\":3,\"n\":\"Calc max level\"},{\"t\":3,\"n\":\"Speed Multiplier\"},{\"t\":3,\"n\":\"Disposition Base (unused)\"},{\"t\":3,\"n\":\"Template Flags\"},{\"t\":3,\"n\":\"Health Offset\"},{\"t\":3,\"n\":\"Bleedout Override\"}]},{\"t\":10,\"n\":\"Factions\",\"c\":[{\"t\":6,\"n\":\"SNAM - Faction\",\"c\":[{\"t\":3,\"n\":\"Faction\"},{\"t\":3,\"n\":\"Rank\"},{\"t\":11,\"n\":\"Unused\"}]}]},{\"t\":3,\"n\":\"INAM - Death item\"},{\"t\":3,\"n\":\"VTCK - Voice\"},{\"t\":3,\"n\":\"TPLT - Template\"},{\"t\":3,\"n\":\"RNAM - Race\"},{\"t\":3,\"n\":\"SPCT - Count\"},{\"t\":9,\"n\":\"Actor Effects\",\"c\":[{\"t\":3,\"n\":\"SPLO - Actor Effect\"}]},{\"t\":6,\"n\":\"Destructable\",\"c\":[{\"t\":6,\"n\":\"DEST - Header\",\"c\":[{\"t\":3,\"n\":\"Health\"},{\"t\":3,\"n\":\"DEST Count\"},{\"t\":3,\"n\":\"VATS Targetable\"},{\"t\":11,\"n\":\"Unknown\"}]}]},{\"t\":3,\"n\":\"WNAM - Worn Armor\"},{\"t\":3,\"n\":\"ANAM - Far away model\"},{\"t\":3,\"n\":\"ATKR - Attack Race\"},{\"t\":10,\"n\":\"Attacks\",\"c\":[{\"t\":6,\"n\":\"Attack\",\"c\":[{\"t\":6,\"n\":\"ATKD - Attack Data\",\"c\":[{\"t\":5,\"n\":\"Damage Mult\"},{\"t\":5,\"n\":\"Attack Chance\"},{\"t\":3,\"n\":\"Attack Spell\"},{\"t\":3,\"n\":\"Attack Flags\"},{\"t\":5,\"n\":\"Attack Angle\"},{\"t\":5,\"n\":\"Strike Angle\"},{\"t\":5,\"n\":\"Stagger\"},{\"t\":3,\"n\":\"Attack Type\"},{\"t\":5,\"n\":\"Knockdown\"},{\"t\":5,\"n\":\"Recovery Time\"},{\"t\":5,\"n\":\"Stamina Mult\"}]}]}]},{\"t\":3,\"n\":\"SPOR - Spectator override package list\"},{\"t\":3,\"n\":\"OCOR - Observe dead body override package list\"},{\"t\":3,\"n\":\"GWOR - Guard warn override package list\"},{\"t\":3,\"n\":\"ECOR - Combat override package list\"},{\"t\":3,\"n\":\"PRKZ - Perk Count\"},{\"t\":10,\"n\":\"Perks\",\"c\":[{\"t\":6,\"n\":\"PRKR - Perk\",\"c\":[{\"t\":3,\"n\":\"Perk\"},{\"t\":3,\"n\":\"Rank\"},{\"t\":11,\"n\":\"Unused\"}]}]},{\"t\":3,\"n\":\"COCT - Count\"},{\"t\":10,\"n\":\"Items\",\"c\":[{\"t\":6,\"n\":\"Item\",\"c\":[{\"t\":6,\"n\":\"CNTO - Item\",\"c\":[{\"t\":3,\"n\":\"Item\"},{\"t\":3,\"n\":\"Count\"}]}]}]},{\"t\":6,\"n\":\"AIDT - AI Data\",\"c\":[{\"t\":3,\"n\":\"Aggression\"},{\"t\":3,\"n\":\"Confidence\"},{\"t\":3,\"n\":\"Energy Level\"},{\"t\":3,\"n\":\"Responsibility\"},{\"t\":3,\"n\":\"Mood\"},{\"t\":3,\"n\":\"Assistance\"},{\"t\":6,\"n\":\"Aggro\",\"c\":[{\"t\":3,\"n\":\"Aggro Radius Behavior\"},{\"t\":3,\"n\":\"Unknown\"},{\"t\":3,\"n\":\"Warn\"},{\"t\":3,\"n\":\"Warn\\/Attack\"},{\"t\":3,\"n\":\"Attack\"}]}]},{\"t\":7,\"n\":\"Packages\",\"c\":[{\"t\":3,\"n\":\"PKID - Package\"}]},{\"t\":3,\"n\":\"KSIZ - Keyword Count\"},{\"t\":9,\"n\":\"KWDA - Keywords\",\"c\":[{\"t\":3,\"n\":\"Keyword\"}]},{\"t\":3,\"n\":\"CNAM - Class\"},{\"t\":2,\"n\":\"FULL - Name\"},{\"t\":2,\"n\":\"SHRT - Short Name\"},{\"t\":11,\"n\":\"DATA - Marker\"},{\"t\":6,\"n\":\"DNAM - Player Skills\",\"c\":[{\"t\":7,\"n\":\"Skill Values\",\"c\":[{\"t\":3,\"n\":\"Skill #0 (OneHanded)\"},{\"t\":3,\"n\":\"Skill #1 (TwoHanded)\"},{\"t\":3,\"n\":\"Skill #2 (Marksman)\"},{\"t\":3,\"n\":\"Skill #3 (Block)\"},{\"t\":3,\"n\":\"Skill #4 (Smithing)\"},{\"t\":3,\"n\":\"Skill #5 (HeavyArmor)\"},{\"t\":3,\"n\":\"Skill #6 (LightArmor)\"},{\"t\":3,\"n\":\"Skill #7 (Pickpocket)\"},{\"t\":3,\"n\":\"Skill #8 (Lockpicking)\"},{\"t\":3,\"n\":\"Skill #9 (Sneak)\"},{\"t\":3,\"n\":\"Skill #10 (Alchemy)\"},{\"t\":3,\"n\":\"Skill #11 (Speechcraft)\"},{\"t\":3,\"n\":\"Skill #12 (Alteration)\"},{\"t\":3,\"n\":\"Skill #13 (Conjuration)\"},{\"t\":3,\"n\":\"Skill #14 (Destruction)\"},{\"t\":3,\"n\":\"Skill #15 (Illusion)\"},{\"t\":3,\"n\":\"Skill #16 (Restoration)\"},{\"t\":3,\"n\":\"Skill #17 (Enchanting)\"}]},{\"t\":7,\"n\":\"Skill Offsets\",\"c\":[{\"t\":3,\"n\":\"Skill #0 (OneHanded)\"},{\"t\":3,\"n\":\"Skill #1 (TwoHanded)\"},{\"t\":3,\"n\":\"Skill #2 (Marksman)\"},{\"t\":3,\"n\":\"Skill #3 (Block)\"},{\"t\":3,\"n\":\"Skill #4 (Smithing)\"},{\"t\":3,\"n\":\"Skill #5 (HeavyArmor)\"},{\"t\":3,\"n\":\"Skill #6 (LightArmor)\"},{\"t\":3,\"n\":\"Skill #7 (Pickpocket)\"},{\"t\":3,\"n\":\"Skill #8 (Lockpicking)\"},{\"t\":3,\"n\":\"Skill #9 (Sneak)\"},{\"t\":3,\"n\":\"Skill #10 (Alchemy)\"},{\"t\":3,\"n\":\"Skill #11 (Speechcraft)\"},{\"t\":3,\"n\":\"Skill #12 (Alteration)\"},{\"t\":3,\"n\":\"Skill #13 (Conjuration)\"},{\"t\":3,\"n\":\"Skill #14 (Destruction)\"},{\"t\":3,\"n\":\"Skill #15 (Illusion)\"},{\"t\":3,\"n\":\"Skill #16 (Restoration)\"},{\"t\":3,\"n\":\"Skill #17 (Enchanting)\"}]},{\"t\":3,\"n\":\"Health\"},{\"t\":3,\"n\":\"Magicka\"},{\"t\":3,\"n\":\"Stamina\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":5,\"n\":\"Far away model distance\"},{\"t\":3,\"n\":\"Geared up weapons\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":9,\"n\":\"Head Parts\",\"c\":[{\"t\":3,\"n\":\"PNAM - Head Part\"}]},{\"t\":3,\"n\":\"HCLF - Hair Color\"},{\"t\":3,\"n\":\"ZNAM - Combat Style\"},{\"t\":3,\"n\":\"GNAM - Gift Filter\"},{\"t\":11,\"n\":\"NAM5 - Unknown\"},{\"t\":5,\"n\":\"NAM6 - Height\"},{\"t\":5,\"n\":\"NAM7 - Weight\"},{\"t\":3,\"n\":\"NAM8 - Sound Level\"},{\"t\":10,\"n\":\"Sound Types\",\"c\":[{\"t\":6,\"n\":\"Sound Type\",\"c\":[{\"t\":3,\"n\":\"CSDT - Type\"},{\"t\":10,\"n\":\"Sounds\",\"c\":[{\"t\":6,\"n\":\"Sound\",\"c\":[{\"t\":3,\"n\":\"CSDI - Sound\"},{\"t\":3,\"n\":\"CSDC - Sound Chance\"}]}]}]}]},{\"t\":3,\"n\":\"CSCR - Inherits Sounds From\"},{\"t\":3,\"n\":\"DOFT - Default outfit\"},{\"t\":3,\"n\":\"SOFT - Sleeping outfit\"},{\"t\":3,\"n\":\"DPLT - Default Package List\"},{\"t\":3,\"n\":\"CRIF - Crime faction\"},{\"t\":3,\"n\":\"FTST - Head texture\"},{\"t\":6,\"n\":\"QNAM - Texture lighting\",\"c\":[{\"t\":5,\"n\":\"Red\"},{\"t\":5,\"n\":\"Green\"},{\"t\":5,\"n\":\"Blue\"}]},{\"t\":6,\"n\":\"NAM9 - Face morph\",\"c\":[{\"t\":5,\"n\":\"Nose Long\\/Short\"},{\"t\":5,\"n\":\"Nose Up\\/Down\"},{\"t\":5,\"n\":\"Jaw Up\\/Down\"},{\"t\":5,\"n\":\"Jaw Narrow\\/Wide\"},{\"t\":5,\"n\":\"Jaw Farward\\/Back\"},{\"t\":5,\"n\":\"Cheeks Up\\/Down\"},{\"t\":5,\"n\":\"Cheeks Farward\\/Back\"},{\"t\":5,\"n\":\"Eyes Up\\/Down\"},{\"t\":5,\"n\":\"Eyes In\\/Out\"},{\"t\":5,\"n\":\"Brows Up\\/Down\"},{\"t\":5,\"n\":\"Brows In\\/Out\"},{\"t\":5,\"n\":\"Brows Farward\\/Back\"},{\"t\":5,\"n\":\"Lips Up\\/Down\"},{\"t\":5,\"n\":\"Lips In\\/Out\"},{\"t\":5,\"n\":\"Chin Narrow\\/Wide\"},{\"t\":5,\"n\":\"Chin Up\\/Down\"},{\"t\":5,\"n\":\"Chin Underbite\\/Overbite\"},{\"t\":5,\"n\":\"Eyes Farward\\/Back\"},{\"t\":5,\"n\":\"Unknown\"}]},{\"t\":6,\"n\":\"NAMA - Face parts\",\"c\":[{\"t\":3,\"n\":\"Nose\"},{\"t\":3,\"n\":\"Unknown\"},{\"t\":3,\"n\":\"Eyes\"},{\"t\":3,\"n\":\"Mouth\"}]},{\"t\":10,\"n\":\"Tint Layers\",\"c\":[{\"t\":6,\"n\":\"Layer\",\"c\":[{\"t\":3,\"n\":\"TINI - Tint Index\"}]}]}]},{\"t\":1,\"p\":1,\"n\":\"PACK - Package\",\"c\":[{\"t\":6,\"n\":\"Record Header\",\"c\":[{\"t\":2,\"n\":\"Signature\"},{\"t\":3,\"n\":\"Data Size\"},{\"t\":3,\"n\":\"Record Flags\"},{\"t\":3,\"n\":\"FormID\"},{\"t\":11,\"n\":\"Version Control Info 1\"},{\"t\":3,\"n\":\"Form Version\"},{\"t\":11,\"n\":\"Version Control Info 2\"}]},{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"VMAD - Virtual Machine Adapter\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Version\"},{\"t\":3,\"p\":1,\"n\":\"Object Format\"},{\"t\":12,\"p\":1,\"n\":\"Data\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Pack VMAD\",\"c\":[{\"t\":9,\"p\":1,\"n\":\"Scripts\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Script\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"scriptName\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":9,\"p\":1,\"n\":\"Properties\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Property\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"propertyName\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":12,\"p\":1,\"n\":\"Value\"}]}]}]}]},{\"t\":6,\"p\":1,\"n\":\"Script Fragments Package\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Unknown\"},{\"t\":3,\"p\":1,\"n\":\"Package Fragments Flags\"},{\"t\":2,\"p\":1,\"n\":\"fileName\"},{\"t\":7,\"p\":1,\"n\":\"Package Fragments\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Package Fragment #0\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Unknown\"},{\"t\":2,\"p\":1,\"n\":\"scriptName\"},{\"t\":2,\"p\":1,\"n\":\"fragmentName\"}]}]}]}]}]}]},{\"t\":6,\"n\":\"PKDT - Pack Data\",\"c\":[{\"t\":3,\"n\":\"General Flags\"},{\"t\":3,\"n\":\"Type\"},{\"t\":3,\"n\":\"Interrupt Override\"},{\"t\":3,\"n\":\"Preferred Speed\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":3,\"n\":\"Interrupt Flags\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":6,\"n\":\"PSDT - Schedule\",\"c\":[{\"t\":3,\"n\":\"Month\"},{\"t\":3,\"n\":\"Day of week\"},{\"t\":3,\"n\":\"Date\"},{\"t\":3,\"n\":\"Hour\"},{\"t\":3,\"n\":\"Minute\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":3,\"n\":\"Duration (minutes)\"}]},{\"t\":8,\"n\":\"Conditions\",\"c\":[{\"t\":6,\"n\":\"Condition\",\"c\":[{\"t\":6,\"n\":\"CTDA - \",\"c\":[{\"t\":3,\"n\":\"Type\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":12,\"n\":\"Comparison Value\"},{\"t\":3,\"n\":\"Function\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":12,\"n\":\"Parameter #1\"},{\"t\":12,\"n\":\"Parameter #2\"},{\"t\":3,\"n\":\"Run On\"},{\"t\":12,\"n\":\"Reference\"},{\"t\":3,\"n\":\"Parameter #3\"}]}]}]},{\"t\":6,\"n\":\"Idle Animations\",\"c\":[{\"t\":3,\"n\":\"IDLF - Flags\"},{\"t\":6,\"n\":\"IDLC - \",\"c\":[{\"t\":3,\"n\":\"Animation Count\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":5,\"n\":\"IDLT - Idle Timer Setting\"},{\"t\":7,\"n\":\"IDLA - Animations\",\"c\":[{\"t\":3,\"n\":\"Animation #0\"}]}]},{\"t\":3,\"n\":\"CNAM - Combat Style\"},{\"t\":3,\"n\":\"QNAM - Owner Quest\"},{\"t\":6,\"n\":\"PKCU - Counter\",\"c\":[{\"t\":3,\"n\":\"Data Input Count\"},{\"t\":3,\"n\":\"Package Template\"},{\"t\":3,\"n\":\"Version Counter (autoincremented)\"}]},{\"t\":6,\"n\":\"Package Data\",\"c\":[{\"t\":8,\"n\":\"Data Input Values\",\"c\":[{\"t\":6,\"n\":\"Value\",\"c\":[{\"t\":2,\"n\":\"ANAM - Type\"}]}]}]},{\"t\":11,\"n\":\"XNAM - Marker\"},{\"t\":6,\"n\":\"Procedure Tree\",\"c\":[{\"t\":8,\"n\":\"Branches\",\"c\":[{\"t\":6,\"n\":\"Branch\",\"c\":[{\"t\":2,\"n\":\"ANAM - Branch Type\"}]}]}]},{\"t\":8,\"n\":\"Data Inputs\",\"c\":[{\"t\":6,\"n\":\"Data Input\",\"c\":[{\"t\":3,\"n\":\"UNAM - Index\"}]}]},{\"t\":6,\"n\":\"OnBegin\",\"c\":[{\"n\":\"POBA - OnBegin Marker\"},{\"t\":3,\"n\":\"INAM - Idle\"}]},{\"t\":6,\"n\":\"OnEnd\",\"c\":[{\"n\":\"POEA - OnEnd Marker\"},{\"t\":3,\"n\":\"INAM - Idle\"}]},{\"t\":6,\"n\":\"OnChange\",\"c\":[{\"n\":\"POCA - OnChange Marker\"},{\"t\":3,\"n\":\"INAM - Idle\"}]}]},{\"t\":1,\"p\":1,\"n\":\"PERK - Perk\",\"c\":[{\"t\":6,\"n\":\"Record Header\",\"c\":[{\"t\":2,\"n\":\"Signature\"},{\"t\":3,\"n\":\"Data Size\"},{\"t\":3,\"n\":\"Record Flags\"},{\"t\":3,\"n\":\"FormID\"},{\"t\":11,\"n\":\"Version Control Info 1\"},{\"t\":3,\"n\":\"Form Version\"},{\"t\":11,\"n\":\"Version Control Info 2\"}]},{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"VMAD - Virtual Machine Adapter\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Version\"},{\"t\":3,\"p\":1,\"n\":\"Object Format\"},{\"t\":12,\"p\":1,\"n\":\"Data\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Perk VMAD\",\"c\":[{\"t\":9,\"p\":1,\"n\":\"Scripts\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Script\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"scriptName\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":9,\"p\":1,\"n\":\"Properties\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Property\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"propertyName\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":12,\"p\":1,\"n\":\"Value\"}]}]}]}]},{\"t\":6,\"p\":1,\"n\":\"Script Fragments Perk\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Unknown\"},{\"t\":2,\"p\":1,\"n\":\"fileName\"},{\"t\":9,\"p\":1,\"n\":\"Perk Fragments\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Perk Fragment\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Fragment Index\"},{\"t\":3,\"p\":1,\"n\":\"Unknown\"},{\"t\":3,\"p\":1,\"n\":\"Unknown\"},{\"t\":2,\"p\":1,\"n\":\"scriptName\"},{\"t\":2,\"p\":1,\"n\":\"fragmentName\"}]}]}]}]}]}]},{\"t\":2,\"n\":\"FULL - Name\"},{\"t\":2,\"n\":\"DESC - Description\"},{\"t\":6,\"n\":\"Icon\",\"c\":[{\"t\":2,\"n\":\"ICON - Large Icon filename\"}]},{\"t\":8,\"n\":\"Conditions\",\"c\":[{\"t\":6,\"n\":\"Condition\",\"c\":[{\"t\":6,\"n\":\"CTDA - \",\"c\":[{\"t\":3,\"n\":\"Type\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":12,\"n\":\"Comparison Value\"},{\"t\":3,\"n\":\"Function\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":12,\"n\":\"Parameter #1\"},{\"t\":12,\"n\":\"Parameter #2\"},{\"t\":3,\"n\":\"Run On\"},{\"t\":12,\"n\":\"Reference\"},{\"t\":3,\"n\":\"Parameter #3\"}]}]}]},{\"t\":6,\"n\":\"DATA - Data\",\"c\":[{\"t\":3,\"n\":\"Trait\"},{\"t\":3,\"n\":\"Level\"},{\"t\":3,\"n\":\"Num Ranks\"},{\"t\":3,\"n\":\"Playable\"},{\"t\":3,\"n\":\"Hidden\"}]},{\"t\":3,\"n\":\"NNAM - Next Perk\"},{\"t\":10,\"n\":\"Effects\",\"c\":[{\"t\":6,\"n\":\"Effect\",\"c\":[{\"t\":6,\"n\":\"PRKE - Header\",\"c\":[{\"t\":3,\"n\":\"Type\"},{\"t\":3,\"n\":\"Rank\"},{\"t\":3,\"n\":\"Priority\"}]},{\"t\":12,\"n\":\"DATA - Effect Data\",\"c\":[{\"t\":6,\"n\":\"Quest + Stage\",\"c\":[{\"t\":3,\"n\":\"Quest\"},{\"t\":3,\"n\":\"Quest Stage\"},{\"t\":11,\"n\":\"Unused\"}]}]},{\"n\":\"PRKF - End Marker\"}]}]}]},{\"t\":1,\"p\":1,\"n\":\"PHZD - Placed Hazard\",\"c\":[{\"t\":3,\"n\":\"Cell\"},{\"t\":6,\"n\":\"Record Header\",\"c\":[{\"t\":2,\"n\":\"Signature\"},{\"t\":3,\"n\":\"Data Size\"},{\"t\":3,\"n\":\"Record Flags\"},{\"t\":3,\"n\":\"FormID\"},{\"t\":11,\"n\":\"Version Control Info 1\"},{\"t\":3,\"n\":\"Form Version\"},{\"t\":11,\"n\":\"Version Control Info 2\"}]},{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"VMAD - Virtual Machine Adapter\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Version\"},{\"t\":3,\"p\":1,\"n\":\"Object Format\"},{\"t\":12,\"p\":1,\"n\":\"Data\",\"c\":[{\"t\":9,\"p\":1,\"n\":\"Scripts\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Script\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"scriptName\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":9,\"p\":1,\"n\":\"Properties\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Property\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"propertyName\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":12,\"p\":1,\"n\":\"Value\"}]}]}]}]}]}]},{\"t\":3,\"n\":\"NAME - Projectile\"},{\"t\":3,\"n\":\"XEZN - Encounter Zone\"},{\"t\":6,\"n\":\"Ownership\",\"c\":[{\"t\":3,\"n\":\"XOWN - Owner\"}]},{\"t\":5,\"n\":\"XHTW - Head-Tracking Weight\"},{\"t\":5,\"n\":\"XFVC - Favor Cost\"},{\"t\":10,\"n\":\"Reflected\\/Refracted By\",\"c\":[{\"t\":6,\"n\":\"XPWR - Water\",\"c\":[{\"t\":3,\"n\":\"Reference\"},{\"t\":3,\"n\":\"Type\"}]}]},{\"t\":10,\"n\":\"Linked References\",\"c\":[{\"t\":6,\"n\":\"XLKR - Linked Reference\",\"c\":[{\"t\":3,\"n\":\"Keyword\\/Ref\"},{\"t\":3,\"n\":\"Ref\"}]}]},{\"t\":6,\"n\":\"Activate Parents\",\"c\":[{\"t\":3,\"n\":\"XAPD - Flags\"}]},{\"t\":6,\"n\":\"XESP - Enable Parent\",\"c\":[{\"t\":3,\"n\":\"Reference\"},{\"t\":3,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":3,\"n\":\"XEMI - Emittance\"},{\"t\":3,\"n\":\"XMBR - MultiBound Reference\"},{\"n\":\"XIS2 - Ignored by Sandbox\"},{\"t\":7,\"n\":\"XLRT - Location Ref Type\",\"c\":[{\"t\":3,\"n\":\"Ref #0\"}]},{\"t\":3,\"n\":\"XLRL - Location Reference\"},{\"t\":7,\"n\":\"XLOD - Distant LOD Data\",\"c\":[{\"t\":5,\"n\":\"Unknown #0\"},{\"t\":5,\"n\":\"Unknown #1\"},{\"t\":5,\"n\":\"Unknown #2\"}]},{\"t\":5,\"n\":\"XSCL - Scale\"},{\"t\":6,\"n\":\"DATA - Position\\/Rotation\",\"c\":[{\"t\":6,\"n\":\"Position\",\"c\":[{\"t\":5,\"n\":\"X\"},{\"t\":5,\"n\":\"Y\"},{\"t\":5,\"n\":\"Z\"}]},{\"t\":6,\"n\":\"Rotation\",\"c\":[{\"t\":5,\"n\":\"X\"},{\"t\":5,\"n\":\"Y\"},{\"t\":5,\"n\":\"Z\"}]}]}]},{\"t\":1,\"p\":1,\"n\":\"QUST - Quest\",\"c\":[{\"t\":6,\"n\":\"Record Header\",\"c\":[{\"t\":2,\"n\":\"Signature\"},{\"t\":3,\"n\":\"Data Size\"},{\"t\":3,\"n\":\"Record Flags\"},{\"t\":3,\"n\":\"FormID\"},{\"t\":11,\"n\":\"Version Control Info 1\"},{\"t\":3,\"n\":\"Form Version\"},{\"t\":11,\"n\":\"Version Control Info 2\"}]},{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"VMAD - Virtual Machine Adapter\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Version\"},{\"t\":3,\"p\":1,\"n\":\"Object Format\"},{\"t\":12,\"p\":1,\"n\":\"Data\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Quest VMAD\",\"c\":[{\"t\":9,\"p\":1,\"n\":\"Scripts\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Script\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"scriptName\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":9,\"p\":1,\"n\":\"Properties\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Property\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"propertyName\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":12,\"p\":1,\"n\":\"Value\"}]}]}]}]},{\"t\":6,\"p\":1,\"n\":\"Script Fragments Quest\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Unknown\"},{\"t\":3,\"p\":1,\"n\":\"fragmentCount\"},{\"t\":2,\"p\":1,\"n\":\"fileName\"},{\"t\":9,\"p\":1,\"n\":\"Quest Fragments\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Quest Fragment\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Quest Stage\"},{\"t\":3,\"p\":1,\"n\":\"Unknown\"},{\"t\":3,\"p\":1,\"n\":\"Quest Stage Index\"},{\"t\":3,\"p\":1,\"n\":\"Unknown\"},{\"t\":2,\"p\":1,\"n\":\"scriptName\"},{\"t\":2,\"p\":1,\"n\":\"fragmentName\"}]}]},{\"t\":9,\"p\":1,\"n\":\"Aliases\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alias\",\"c\":[{\"t\":12,\"p\":1,\"n\":\"Object Union\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"Unused\"}]}]},{\"t\":3,\"p\":1,\"n\":\"Version\"},{\"t\":3,\"p\":1,\"n\":\"Object Format\"},{\"t\":9,\"p\":1,\"n\":\"Alias Scripts\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Script\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"scriptName\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":9,\"p\":1,\"n\":\"Properties\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Property\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"propertyName\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":12,\"p\":1,\"n\":\"Value\"}]}]}]}]}]}]}]}]}]}]},{\"t\":2,\"n\":\"FULL - Name\"},{\"t\":6,\"n\":\"DNAM - General\",\"c\":[{\"t\":3,\"n\":\"Flags\"},{\"t\":3,\"n\":\"Priority\"},{\"t\":3,\"n\":\"Form Version\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":3,\"n\":\"Type\"}]},{\"t\":2,\"n\":\"ENAM - Event\"},{\"t\":7,\"n\":\"Text Display Globals\",\"c\":[{\"t\":3,\"n\":\"QTGL - Global\"}]},{\"t\":2,\"n\":\"FLTR - Object Window Filter\"},{\"t\":6,\"n\":\"Quest Dialogue Conditions\",\"c\":[{\"t\":8,\"n\":\"Conditions\",\"c\":[{\"t\":6,\"n\":\"Condition\",\"c\":[{\"t\":6,\"n\":\"CTDA - \",\"c\":[{\"t\":3,\"n\":\"Type\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":12,\"n\":\"Comparison Value\"},{\"t\":3,\"n\":\"Function\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":12,\"n\":\"Parameter #1\"},{\"t\":12,\"n\":\"Parameter #2\"},{\"t\":3,\"n\":\"Run On\"},{\"t\":12,\"n\":\"Reference\"},{\"t\":3,\"n\":\"Parameter #3\"}]}]}]}]},{\"n\":\"NEXT - Marker\"},{\"t\":8,\"n\":\"Conditions\",\"c\":[{\"t\":6,\"n\":\"Condition\",\"c\":[{\"t\":6,\"n\":\"CTDA - \",\"c\":[{\"t\":3,\"n\":\"Type\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":12,\"n\":\"Comparison Value\"},{\"t\":3,\"n\":\"Function\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":12,\"n\":\"Parameter #1\"},{\"t\":12,\"n\":\"Parameter #2\"},{\"t\":3,\"n\":\"Run On\"},{\"t\":12,\"n\":\"Reference\"},{\"t\":3,\"n\":\"Parameter #3\"}]}]}]},{\"t\":10,\"n\":\"Stages\",\"c\":[{\"t\":6,\"n\":\"Stage\",\"c\":[{\"t\":6,\"n\":\"INDX - Stage Index\",\"c\":[{\"t\":3,\"n\":\"Stage Index\"},{\"t\":3,\"n\":\"Flags\"},{\"t\":3,\"n\":\"Unknown\"}]}]}]},{\"t\":8,\"n\":\"Objectives\",\"c\":[{\"t\":6,\"n\":\"Objective\",\"c\":[{\"t\":3,\"n\":\"QOBJ - Objective Index\"},{\"t\":2,\"n\":\"NNAM - Display Text\"}]}]},{\"t\":11,\"n\":\"ANAM - Aliases Marker\"},{\"t\":8,\"n\":\"Aliases\",\"c\":[{\"t\":6,\"n\":\"Alias\",\"c\":[{\"t\":3,\"n\":\"ALST - Reference Alias ID\"},{\"n\":\"ALED - Alias End\"}]}]},{\"t\":2,\"n\":\"NNAM - Description\"},{\"t\":8,\"n\":\"Targets\",\"c\":[{\"t\":6,\"n\":\"Target\",\"c\":[{\"t\":6,\"n\":\"QSTA - Target\",\"c\":[{\"t\":3,\"n\":\"Target\"},{\"t\":3,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unknown\"}]}]}]}]},{\"t\":1,\"p\":1,\"n\":\"REFR - Placed Object\",\"c\":[{\"t\":3,\"n\":\"Cell\"},{\"t\":6,\"n\":\"Record Header\",\"c\":[{\"t\":2,\"n\":\"Signature\"},{\"t\":3,\"n\":\"Data Size\"},{\"t\":3,\"n\":\"Record Flags\",\"c\":[{\"t\":4,\"n\":\"Persistent\"}]},{\"t\":3,\"n\":\"FormID\"},{\"t\":11,\"n\":\"Version Control Info 1\"},{\"t\":3,\"n\":\"Form Version\"},{\"t\":11,\"n\":\"Version Control Info 2\"}]},{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"VMAD - Virtual Machine Adapter\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Version\"},{\"t\":3,\"p\":1,\"n\":\"Object Format\"},{\"t\":12,\"p\":1,\"n\":\"Data\",\"c\":[{\"t\":9,\"p\":1,\"n\":\"Scripts\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Script\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"scriptName\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":9,\"p\":1,\"n\":\"Properties\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Property\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"propertyName\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":12,\"p\":1,\"n\":\"Value\"}]}]}]}]}]}]},{\"t\":3,\"n\":\"NAME - Base\"},{\"t\":6,\"n\":\"XMBO - Bound Half Extents\",\"c\":[{\"t\":5,\"n\":\"X\"},{\"t\":5,\"n\":\"Y\"},{\"t\":5,\"n\":\"Z\"}]},{\"t\":6,\"n\":\"XPRM - Primitive\",\"c\":[{\"t\":6,\"n\":\"Bounds\",\"c\":[{\"t\":5,\"n\":\"X\"},{\"t\":5,\"n\":\"Y\"},{\"t\":5,\"n\":\"Z\"}]},{\"t\":6,\"n\":\"Color\",\"c\":[{\"t\":5,\"n\":\"Red\"},{\"t\":5,\"n\":\"Green\"},{\"t\":5,\"n\":\"Blue\"}]},{\"t\":5,\"n\":\"Unknown\"},{\"t\":3,\"n\":\"Type\"}]},{\"t\":11,\"n\":\"XORD - Unknown\"},{\"t\":6,\"n\":\"XOCP - Occlusion Plane Data\",\"c\":[{\"t\":6,\"n\":\"Size\",\"c\":[{\"t\":5,\"n\":\"Width\"},{\"t\":5,\"n\":\"Height\"}]},{\"t\":6,\"n\":\"Position\",\"c\":[{\"t\":5,\"n\":\"X\"},{\"t\":5,\"n\":\"Y\"},{\"t\":5,\"n\":\"Z\"}]},{\"t\":6,\"n\":\"Rotation (Quaternion?)\",\"c\":[{\"t\":5,\"n\":\"q1\"},{\"t\":5,\"n\":\"q2\"},{\"t\":5,\"n\":\"q3\"},{\"t\":5,\"n\":\"q4\"}]}]},{\"t\":8,\"n\":\"XPOD - Portal Data\",\"c\":[{\"t\":6,\"n\":\"References #0\",\"c\":[{\"t\":3,\"n\":\"Origin\"},{\"t\":3,\"n\":\"Destination\"}]}]},{\"t\":6,\"n\":\"XPTL - Room Portal (unused)\",\"c\":[{\"t\":6,\"n\":\"Size\",\"c\":[{\"t\":5,\"n\":\"Width\"},{\"t\":5,\"n\":\"Height\"}]},{\"t\":6,\"n\":\"Position\",\"c\":[{\"t\":5,\"n\":\"X\"},{\"t\":5,\"n\":\"Y\"},{\"t\":5,\"n\":\"Z\"}]},{\"t\":6,\"n\":\"Rotation (Quaternion?)\",\"c\":[{\"t\":5,\"n\":\"q1\"},{\"t\":5,\"n\":\"q2\"},{\"t\":5,\"n\":\"q3\"},{\"t\":5,\"n\":\"q4\"}]}]},{\"t\":6,\"n\":\"Bound Data\",\"c\":[{\"t\":6,\"n\":\"XRMR - Header\",\"c\":[{\"t\":3,\"n\":\"Linked Rooms Count\"},{\"t\":3,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unknown\"}]}]},{\"n\":\"XMBP - MultiBound Primitive Marker\"},{\"t\":11,\"n\":\"XRGD - Ragdoll Data\"},{\"t\":11,\"n\":\"XRGB - Ragdoll Biped Data\"},{\"t\":5,\"n\":\"XRDS - Radius\"},{\"t\":10,\"n\":\"Reflected\\/Refracted By\",\"c\":[{\"t\":6,\"n\":\"XPWR - Water\",\"c\":[{\"t\":3,\"n\":\"Reference\"},{\"t\":3,\"n\":\"Type\"}]}]},{\"t\":9,\"n\":\"Lit Water\",\"c\":[{\"t\":3,\"n\":\"XLTW - Water\"}]},{\"t\":3,\"n\":\"XEMI - Emittance\"},{\"t\":6,\"n\":\"XLIG - Light Data\",\"c\":[{\"t\":5,\"n\":\"FOV 90+\\/-\"},{\"t\":5,\"n\":\"Fade 1.35+\\/-\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":5,\"n\":\"Shadow Depth Bias\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":6,\"n\":\"XALP - Alpha\",\"c\":[{\"t\":3,\"n\":\"Cutoff\"},{\"t\":3,\"n\":\"Base\"}]},{\"t\":6,\"n\":\"XTEL - Teleport Destination\",\"c\":[{\"t\":3,\"n\":\"Door\"},{\"t\":6,\"n\":\"Position\\/Rotation\",\"c\":[{\"t\":6,\"n\":\"Position\",\"c\":[{\"t\":5,\"n\":\"X\"},{\"t\":5,\"n\":\"Y\"},{\"t\":5,\"n\":\"Z\"}]},{\"t\":6,\"n\":\"Rotation\",\"c\":[{\"t\":5,\"n\":\"X\"},{\"t\":5,\"n\":\"Y\"},{\"t\":5,\"n\":\"Z\"}]}]},{\"t\":3,\"n\":\"Flags\"}]},{\"t\":3,\"n\":\"XTNM - Teleport Message Box\"},{\"t\":3,\"n\":\"XMBR - MultiBound Reference\"},{\"t\":11,\"n\":\"XWCN - Unknown\"},{\"t\":11,\"n\":\"XWCS - Unknown\"},{\"t\":6,\"n\":\"XWCU - Water Velocity\",\"c\":[{\"t\":5,\"n\":\"X Offset\"},{\"t\":5,\"n\":\"Y Offset\"},{\"t\":5,\"n\":\"Z Offset\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":5,\"n\":\"X Angle\"},{\"t\":5,\"n\":\"Y Angle\"},{\"t\":5,\"n\":\"Z Angle\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":6,\"n\":\"XCVL - Unknown\",\"c\":[{\"t\":11,\"n\":\"Unknown\"},{\"t\":5,\"n\":\"X Angle\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":3,\"n\":\"XCZR - Unknown\"},{\"t\":11,\"n\":\"XCZA - Unknown\"},{\"t\":3,\"n\":\"XCZC - Unknown\"},{\"t\":5,\"n\":\"XSCL - Scale\"},{\"t\":3,\"n\":\"XSPC - Spawn Container\"},{\"t\":6,\"n\":\"Activate Parents\",\"c\":[{\"t\":3,\"n\":\"XAPD - Flags\"}]},{\"t\":3,\"n\":\"XLIB - Leveled Item Base Object\"},{\"t\":3,\"n\":\"XLCM - Level Modifier\"},{\"t\":3,\"n\":\"XLCN - Persistent Location\"},{\"t\":3,\"n\":\"XTRI - Collision Layer\"},{\"t\":6,\"n\":\"XLOC - Lock Data\",\"c\":[{\"t\":3,\"n\":\"Level\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":3,\"n\":\"Key\"},{\"t\":3,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":3,\"n\":\"XEZN - Encounter Zone\"},{\"t\":6,\"n\":\"XNDP - Navigation Door Link\",\"c\":[{\"t\":3,\"n\":\"Navigation Mesh\"},{\"t\":3,\"n\":\"Teleport Marker Triangle\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":7,\"n\":\"XLRT - Location Ref Type\",\"c\":[{\"t\":3,\"n\":\"Ref #0\"}]},{\"n\":\"XIS2 - Ignored by Sandbox\"},{\"t\":6,\"n\":\"Ownership\",\"c\":[{\"t\":3,\"n\":\"XOWN - Owner\"}]},{\"t\":3,\"n\":\"XCNT - Item Count\"},{\"t\":5,\"n\":\"XCHG - Charge\"},{\"t\":3,\"n\":\"XLRL - Location Reference\"},{\"t\":6,\"n\":\"XESP - Enable Parent\",\"c\":[{\"t\":3,\"n\":\"Reference\"},{\"t\":3,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":8,\"n\":\"Linked References\",\"c\":[{\"t\":6,\"n\":\"XLKR - Linked Reference\",\"c\":[{\"t\":3,\"n\":\"Keyword\\/Ref\"},{\"t\":3,\"n\":\"Ref\"}]}]},{\"t\":8,\"n\":\"Patrol\",\"c\":[{\"t\":6,\"n\":\"Data\",\"c\":[{\"t\":5,\"n\":\"XPRD - Idle Time\"},{\"n\":\"XPPA - Patrol Script Marker\"},{\"t\":3,\"n\":\"INAM - Idle\"}]}]},{\"t\":3,\"n\":\"XACT - Action Flag\"},{\"t\":5,\"n\":\"XHTW - Head-Tracking Weight\"},{\"t\":5,\"n\":\"XFVC - Favor Cost\"},{\"n\":\"ONAM - Open by Default\"},{\"t\":6,\"n\":\"Map Marker\",\"c\":[{\"n\":\"XMRK - Map Marker Data\"},{\"t\":3,\"n\":\"FNAM - Map Flags\"},{\"t\":2,\"n\":\"FULL - Name\"},{\"t\":6,\"n\":\"TNAM - \",\"c\":[{\"t\":3,\"n\":\"Type\"},{\"t\":11,\"n\":\"Unused\"}]}]},{\"t\":3,\"n\":\"XATR - Attach Ref\"},{\"t\":7,\"n\":\"XLOD - Distant LOD Data\",\"c\":[{\"t\":5,\"n\":\"Unknown #0\"},{\"t\":5,\"n\":\"Unknown #1\"},{\"t\":5,\"n\":\"Unknown #2\"}]},{\"t\":6,\"n\":\"DATA - Position\\/Rotation\",\"c\":[{\"t\":6,\"n\":\"Position\",\"c\":[{\"t\":5,\"n\":\"X\"},{\"t\":5,\"n\":\"Y\"},{\"t\":5,\"n\":\"Z\"}]},{\"t\":6,\"n\":\"Rotation\",\"c\":[{\"t\":5,\"n\":\"X\"},{\"t\":5,\"n\":\"Y\"},{\"t\":5,\"n\":\"Z\"}]}]}]},{\"t\":1,\"p\":1,\"n\":\"SCEN - Scene\",\"c\":[{\"t\":6,\"n\":\"Record Header\",\"c\":[{\"t\":2,\"n\":\"Signature\"},{\"t\":3,\"n\":\"Data Size\"},{\"t\":3,\"n\":\"Record Flags\"},{\"t\":3,\"n\":\"FormID\"},{\"t\":11,\"n\":\"Version Control Info 1\"},{\"t\":3,\"n\":\"Form Version\"},{\"t\":11,\"n\":\"Version Control Info 2\"}]},{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"VMAD - Virtual Machine Adapter\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Version\"},{\"t\":3,\"p\":1,\"n\":\"Object Format\"},{\"t\":12,\"p\":1,\"n\":\"Data\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Scene VMAD\",\"c\":[{\"t\":9,\"p\":1,\"n\":\"Scripts\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Script\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"scriptName\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":9,\"p\":1,\"n\":\"Properties\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Property\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"propertyName\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":12,\"p\":1,\"n\":\"Value\"}]}]}]}]},{\"t\":6,\"p\":1,\"n\":\"Script Fragments Scene\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Unknown\"},{\"t\":3,\"p\":1,\"n\":\"Scene Fragments Flags\"},{\"t\":2,\"p\":1,\"n\":\"fileName\"},{\"t\":7,\"p\":1,\"n\":\"Scene Fragments\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Scene Fragment #0\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Unknown\"},{\"t\":2,\"p\":1,\"n\":\"scriptName\"},{\"t\":2,\"p\":1,\"n\":\"fragmentName\"}]}]},{\"t\":7,\"p\":1,\"n\":\"Phase Fragments\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Phase Fragment #0\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Phase Flag\"},{\"t\":3,\"p\":1,\"n\":\"Phase Index\"},{\"t\":3,\"p\":1,\"n\":\"Unknown\"},{\"t\":3,\"p\":1,\"n\":\"Unknown\"},{\"t\":3,\"p\":1,\"n\":\"Unknown\"},{\"t\":2,\"p\":1,\"n\":\"scriptName\"},{\"t\":2,\"p\":1,\"n\":\"fragmentName\"}]}]}]}]}]}]},{\"t\":3,\"n\":\"FNAM - Flags\"},{\"t\":8,\"n\":\"Phases\",\"c\":[{\"t\":6,\"n\":\"Phase\",\"c\":[{\"n\":\"HNAM - Marker Phase Start\"}]}]},{\"t\":8,\"n\":\"Actors\",\"c\":[{\"t\":6,\"n\":\"Actor\",\"c\":[{\"t\":3,\"n\":\"ALID - Actor ID\"}]}]},{\"t\":8,\"n\":\"Actions\",\"c\":[{\"t\":6,\"n\":\"Action\",\"c\":[{\"t\":3,\"n\":\"ANAM - Type\"}]}]},{\"t\":6,\"n\":\"Unused\",\"c\":[{\"t\":11,\"n\":\"SCHR - Unknown\"}]},{\"n\":\"NEXT - Marker\"},{\"t\":6,\"n\":\"Unused\",\"c\":[{\"t\":11,\"n\":\"SCHR - Unknown\"}]},{\"t\":3,\"n\":\"PNAM - Quest\"},{\"t\":3,\"n\":\"INAM - Last Action Index\"},{\"t\":11,\"n\":\"VNAM - Unknown\"},{\"t\":8,\"n\":\"Conditions\",\"c\":[{\"t\":6,\"n\":\"Condition\",\"c\":[{\"t\":6,\"n\":\"CTDA - \",\"c\":[{\"t\":3,\"n\":\"Type\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":12,\"n\":\"Comparison Value\"},{\"t\":3,\"n\":\"Function\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":12,\"n\":\"Parameter #1\"},{\"t\":12,\"n\":\"Parameter #2\"},{\"t\":3,\"n\":\"Run On\"},{\"t\":12,\"n\":\"Reference\"},{\"t\":3,\"n\":\"Parameter #3\"}]}]}]}]},{\"t\":1,\"p\":1,\"n\":\"TREE - Tree\",\"c\":[{\"t\":6,\"n\":\"Record Header\",\"c\":[{\"t\":2,\"n\":\"Signature\"},{\"t\":3,\"n\":\"Data Size\"},{\"t\":3,\"n\":\"Record Flags\"},{\"t\":3,\"n\":\"FormID\"},{\"t\":11,\"n\":\"Version Control Info 1\"},{\"t\":3,\"n\":\"Form Version\"},{\"t\":11,\"n\":\"Version Control Info 2\"}]},{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"VMAD - Virtual Machine Adapter\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Version\"},{\"t\":3,\"p\":1,\"n\":\"Object Format\"},{\"t\":12,\"p\":1,\"n\":\"Data\",\"c\":[{\"t\":9,\"p\":1,\"n\":\"Scripts\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Script\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"scriptName\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":9,\"p\":1,\"n\":\"Properties\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Property\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"propertyName\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":12,\"p\":1,\"n\":\"Value\"}]}]}]}]}]}]},{\"t\":6,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"n\":\"X1\"},{\"t\":3,\"n\":\"Y1\"},{\"t\":3,\"n\":\"Z1\"},{\"t\":3,\"n\":\"X2\"},{\"t\":3,\"n\":\"Y2\"},{\"t\":3,\"n\":\"Z2\"}]},{\"t\":6,\"n\":\"Model\",\"c\":[{\"t\":2,\"n\":\"MODL - Model Filename\"}]},{\"t\":3,\"n\":\"PFIG - Ingredient\"},{\"t\":3,\"n\":\"SNAM - Harvest Sound\"},{\"t\":6,\"n\":\"PFPC - Ingredient Production\",\"c\":[{\"t\":3,\"n\":\"Spring\"},{\"t\":3,\"n\":\"Summer\"},{\"t\":3,\"n\":\"Fall\"},{\"t\":3,\"n\":\"Winter\"}]},{\"t\":2,\"n\":\"FULL - Name\"},{\"t\":6,\"n\":\"CNAM - Tree Data\",\"c\":[{\"t\":5,\"n\":\"Trunk Flexibility\"},{\"t\":5,\"n\":\"Branch Flexibility\"},{\"t\":5,\"n\":\"Unknown\"},{\"t\":5,\"n\":\"Unknown\"},{\"t\":5,\"n\":\"Unknown\"},{\"t\":5,\"n\":\"Unknown\"},{\"t\":5,\"n\":\"Unknown\"},{\"t\":5,\"n\":\"Unknown\"},{\"t\":5,\"n\":\"Unknown\"},{\"t\":5,\"n\":\"Unknown\"},{\"t\":5,\"n\":\"Leaf Amplitude\"},{\"t\":5,\"n\":\"Leaf Frequency\"}]}]},{\"t\":1,\"p\":1,\"n\":\"WEAP - Weapon\",\"c\":[{\"t\":6,\"n\":\"Record Header\",\"c\":[{\"t\":2,\"n\":\"Signature\"},{\"t\":3,\"n\":\"Data Size\"},{\"t\":3,\"n\":\"Record Flags\"},{\"t\":3,\"n\":\"FormID\"},{\"t\":11,\"n\":\"Version Control Info 1\"},{\"t\":3,\"n\":\"Form Version\"},{\"t\":11,\"n\":\"Version Control Info 2\"}]},{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"VMAD - Virtual Machine Adapter\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Version\"},{\"t\":3,\"p\":1,\"n\":\"Object Format\"},{\"t\":12,\"p\":1,\"n\":\"Data\",\"c\":[{\"t\":9,\"p\":1,\"n\":\"Scripts\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Script\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"scriptName\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":9,\"p\":1,\"n\":\"Properties\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Property\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"propertyName\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":12,\"p\":1,\"n\":\"Value\"}]}]}]}]}]}]},{\"t\":6,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"n\":\"X1\"},{\"t\":3,\"n\":\"Y1\"},{\"t\":3,\"n\":\"Z1\"},{\"t\":3,\"n\":\"X2\"},{\"t\":3,\"n\":\"Y2\"},{\"t\":3,\"n\":\"Z2\"}]},{\"t\":2,\"n\":\"FULL - Name\"},{\"t\":6,\"n\":\"Model\",\"c\":[{\"t\":2,\"n\":\"MODL - Model Filename\"}]},{\"t\":6,\"n\":\"Icon\",\"c\":[{\"t\":2,\"n\":\"ICON - Large Icon filename\"}]},{\"t\":3,\"n\":\"EITM - Object Effect\"},{\"t\":3,\"n\":\"EAMT - Enchantment Amount\"},{\"t\":6,\"n\":\"Destructable\",\"c\":[{\"t\":6,\"n\":\"DEST - Header\",\"c\":[{\"t\":3,\"n\":\"Health\"},{\"t\":3,\"n\":\"DEST Count\"},{\"t\":3,\"n\":\"VATS Targetable\"},{\"t\":11,\"n\":\"Unknown\"}]}]},{\"t\":3,\"n\":\"ETYP - Equipment Type\"},{\"t\":3,\"n\":\"BIDS - Block Bash Impact Data Set\"},{\"t\":3,\"n\":\"BAMT - Alternate Block Material\"},{\"t\":3,\"n\":\"YNAM - Sound - Pick Up\"},{\"t\":3,\"n\":\"ZNAM - Sound - Drop\"},{\"t\":3,\"n\":\"KSIZ - Keyword Count\"},{\"t\":9,\"n\":\"KWDA - Keywords\",\"c\":[{\"t\":3,\"n\":\"Keyword\"}]},{\"t\":2,\"n\":\"DESC - Description\"},{\"t\":6,\"n\":\"Has Scope\",\"c\":[{\"t\":2,\"n\":\"MOD3 - Model Filename\"}]},{\"t\":11,\"n\":\"NNAM - Unused\"},{\"t\":3,\"n\":\"INAM - Impact Data Set\"},{\"t\":3,\"n\":\"WNAM - 1st Person Model Object\"},{\"t\":3,\"n\":\"SNAM - Attack Sound\"},{\"t\":3,\"n\":\"XNAM - Attack Sound 2D\"},{\"t\":3,\"n\":\"NAM7 - Attack Loop Sound\"},{\"t\":3,\"n\":\"TNAM - Attack Fail Sound\"},{\"t\":3,\"n\":\"UNAM - Idle Sound\"},{\"t\":3,\"n\":\"NAM9 - Equip Sound\"},{\"t\":3,\"n\":\"NAM8 - Unequip Sound\"},{\"t\":6,\"n\":\"DATA - Game Data\",\"c\":[{\"t\":3,\"n\":\"Value\"},{\"t\":5,\"n\":\"Weight\"},{\"t\":3,\"n\":\"Damage\"}]},{\"t\":6,\"n\":\"DNAM - Data\",\"c\":[{\"t\":3,\"n\":\"Animation Type\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":5,\"n\":\"Speed\"},{\"t\":5,\"n\":\"Reach\"},{\"t\":3,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":5,\"n\":\"Sight FOV\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":3,\"n\":\"Base VATS To-Hit Chance\"},{\"t\":3,\"n\":\"Attack Animation\"},{\"t\":3,\"n\":\"# Projectiles\"},{\"t\":3,\"n\":\"Embedded Weapon AV (unused)\"},{\"t\":5,\"n\":\"Range Min\"},{\"t\":5,\"n\":\"Range Max\"},{\"t\":3,\"n\":\"On Hit\"},{\"t\":3,\"n\":\"Flags2\"},{\"t\":5,\"n\":\"Animation Attack Mult\"},{\"t\":5,\"n\":\"Unknown\"},{\"t\":5,\"n\":\"Rumble - Left Motor Strength\"},{\"t\":5,\"n\":\"Rumble - Right Motor Strength\"},{\"t\":5,\"n\":\"Rumble - Duration\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":3,\"n\":\"Skill\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":3,\"n\":\"Resist\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":5,\"n\":\"Stagger\"}]},{\"t\":6,\"n\":\"CRDT - Critical Data\",\"c\":[{\"t\":3,\"n\":\"Damage\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":5,\"n\":\"% Mult\"},{\"t\":3,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":3,\"n\":\"Effect\"}]},{\"t\":3,\"n\":\"VNAM - Detection Sound Level\"},{\"t\":3,\"n\":\"CNAM - Template\"}]}]},\"name\":\"Bash.Scripts\",\"hash\":\"$C2588973\",\"color\":255}"
  },
  {
    "path": "frontend/settings/Skyrim/Bash.Sound.json",
    "content": "{\"records\":\"ARMA,ARMO,ASPC,EXPL,IPCT,MGEF,MISC,MSTT,RACE,REVB,SLGM,SNCT,SNDR,SOPM,SOUN,WEAP,WTHR,ACTI\",\"description\":\"Sound tag from Wrye Bash.\\r\\n\\r\\nUsed when the mod replaces sounds.\\r\\n\\r\\nNote: I tried my best to get all appropriate records and subrecords for Skyrim in the spirit of this Bash Tag, but I may have missed things.  Please let me know if I did.  -Mator\",\"tree\":{\"records\":[{\"t\":1,\"p\":1,\"n\":\"ARMA - Armor Addon\",\"c\":[{\"t\":6,\"n\":\"Record Header\",\"c\":[{\"t\":2,\"n\":\"Signature\"},{\"t\":3,\"n\":\"Data Size\"},{\"t\":3,\"n\":\"Record Flags\"},{\"t\":3,\"n\":\"FormID\"},{\"t\":11,\"n\":\"Version Control Info 1\"},{\"t\":3,\"n\":\"Form Version\"},{\"t\":11,\"n\":\"Version Control Info 2\"}]},{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"n\":\"BOD2 - Biped Body Template\",\"c\":[{\"t\":3,\"n\":\"First Person Flags\"},{\"t\":3,\"n\":\"General Flags\"},{\"n\":\"Unused\"},{\"t\":3,\"n\":\"Armor Type\"}]},{\"t\":3,\"n\":\"RNAM - Race\"},{\"t\":6,\"n\":\"DNAM - Data\",\"c\":[{\"t\":3,\"n\":\"Male Priority\"},{\"t\":3,\"n\":\"Female Priority\"},{\"t\":3,\"n\":\"Weight slider - Male\"},{\"t\":3,\"n\":\"Weight slider - Female\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":3,\"n\":\"Detection Sound Value\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":5,\"n\":\"Weapon Adjust\"}]},{\"t\":6,\"n\":\"Male world model\",\"c\":[{\"t\":2,\"n\":\"MOD2 - Model Filename\"}]},{\"t\":6,\"n\":\"Female world model\",\"c\":[{\"t\":2,\"n\":\"MOD3 - Model Filename\"}]},{\"t\":6,\"n\":\"Male 1st Person\",\"c\":[{\"t\":2,\"n\":\"MOD4 - Model Filename\"}]},{\"t\":6,\"n\":\"Female 1st Person\",\"c\":[{\"t\":2,\"n\":\"MOD5 - Model Filename\"}]},{\"t\":3,\"n\":\"NAM0 - Male Skin Texture\"},{\"t\":3,\"n\":\"NAM1 - Female Skin texture\"},{\"t\":3,\"n\":\"NAM2 - Male Skin Texture Swap List\"},{\"t\":3,\"n\":\"NAM3 - Female Skin Texture Swap List\"},{\"t\":9,\"n\":\"Additional Races\",\"c\":[{\"t\":3,\"n\":\"MODL - Race\"}]},{\"t\":3,\"p\":1,\"n\":\"SNDD - Footstep Sound\"},{\"t\":3,\"n\":\"ONAM - Art Object\"}]},{\"t\":1,\"p\":1,\"n\":\"ARMO - Armor\",\"c\":[{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"n\":\"VMAD - Virtual Machine Adapter\",\"c\":[{\"t\":3,\"n\":\"Version\"},{\"t\":3,\"n\":\"Object Format\"},{\"t\":7,\"n\":\"Scripts\",\"c\":[{\"t\":6,\"n\":\"Script\",\"c\":[{\"t\":2,\"n\":\"scriptName\"},{\"t\":3,\"n\":\"Flags\"},{\"t\":7,\"n\":\"Properties\",\"c\":[{\"t\":6,\"n\":\"Property\",\"c\":[{\"t\":2,\"n\":\"propertyName\"},{\"t\":3,\"n\":\"Type\"},{\"t\":3,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":6,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"n\":\"Alias\"},{\"t\":3,\"n\":\"FormID\"}]},{\"t\":6,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"n\":\"FormID\"},{\"t\":3,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]},{\"t\":2,\"n\":\"String\"},{\"t\":3,\"n\":\"Int32\"},{\"t\":5,\"n\":\"Float\"},{\"t\":3,\"n\":\"Bool\"},{\"t\":7,\"n\":\"Array of Object\",\"c\":[{\"t\":6,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"n\":\"Alias\"},{\"t\":3,\"n\":\"FormID\"}]},{\"t\":6,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"n\":\"FormID\"},{\"t\":3,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]}]},{\"t\":7,\"n\":\"Array of String\",\"c\":[{\"t\":2,\"n\":\"Element\"}]},{\"t\":7,\"n\":\"Array of Int32\",\"c\":[{\"t\":3,\"n\":\"Element\"}]},{\"t\":7,\"n\":\"Array of Float\",\"c\":[{\"t\":5,\"n\":\"Element\"}]},{\"t\":7,\"n\":\"Array of Bool\",\"c\":[{\"t\":3,\"n\":\"Element\"}]}]}]}]}]}]},{\"t\":6,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"n\":\"X1\"},{\"t\":3,\"n\":\"Y1\"},{\"t\":3,\"n\":\"Z1\"},{\"t\":3,\"n\":\"X2\"},{\"t\":3,\"n\":\"Y2\"},{\"t\":3,\"n\":\"Z2\"}]},{\"t\":2,\"n\":\"FULL - Name\"},{\"t\":3,\"n\":\"EITM - Object Effect\"},{\"t\":3,\"n\":\"EAMT - Enchantment Amount\"},{\"t\":6,\"n\":\"Male world model\",\"c\":[{\"t\":2,\"n\":\"MOD2 - Model Filename\"},{\"t\":11,\"n\":\"MO2T - Texture Files Hashes\"},{\"t\":7,\"n\":\"MO2S - Alternate Textures\",\"c\":[{\"t\":6,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"n\":\"3D Name\"},{\"t\":3,\"n\":\"New Texture\"},{\"t\":3,\"n\":\"3D Index\"}]}]}]},{\"t\":6,\"n\":\"Icon\",\"c\":[{\"t\":2,\"n\":\"ICON - Large Icon filename\"},{\"t\":2,\"n\":\"MICO - Small Icon filename\"}]},{\"t\":6,\"n\":\"Female world model\",\"c\":[{\"t\":2,\"n\":\"MOD4 - Model Filename\"},{\"t\":11,\"n\":\"MO4T - Texture Files Hashes\"},{\"t\":7,\"n\":\"MO4S - Alternate Textures\",\"c\":[{\"t\":6,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"n\":\"3D Name\"},{\"t\":3,\"n\":\"New Texture\"},{\"t\":3,\"n\":\"3D Index\"}]}]}]},{\"t\":6,\"n\":\"Icon 2 (female)\",\"c\":[{\"t\":2,\"n\":\"ICO2 - Large Icon filename\"},{\"t\":2,\"n\":\"MIC2 - Small Icon filename\"}]},{\"t\":6,\"n\":\"BOD2 - Biped Body Template\",\"c\":[{\"t\":3,\"n\":\"First Person Flags\"},{\"t\":3,\"n\":\"General Flags\"},{\"n\":\"Unused\"},{\"t\":3,\"n\":\"Armor Type\"}]},{\"t\":6,\"n\":\"BODT - Body Template\",\"c\":[{\"t\":3,\"n\":\"First Person Flags\"},{\"t\":3,\"n\":\"General Flags\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":3,\"n\":\"Armor Type\"}]},{\"t\":6,\"n\":\"Destructable\",\"c\":[{\"t\":6,\"n\":\"DEST - Header\",\"c\":[{\"t\":3,\"n\":\"Health\"},{\"t\":3,\"n\":\"DEST Count\"},{\"t\":3,\"n\":\"VATS Targetable\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":8,\"n\":\"Stages\",\"c\":[{\"t\":6,\"n\":\"Stage\",\"c\":[{\"t\":6,\"n\":\"DSTD - Destruction Stage Data\",\"c\":[{\"t\":3,\"n\":\"Health %\"},{\"t\":3,\"n\":\"Index\"},{\"t\":3,\"n\":\"Model Damage Stage\"},{\"t\":3,\"n\":\"Flags\"},{\"t\":3,\"n\":\"Self Damage per Second\"},{\"t\":3,\"n\":\"Explosion\"},{\"t\":3,\"n\":\"Debris\"},{\"t\":3,\"n\":\"Debris Count\"}]},{\"t\":6,\"n\":\"Model\",\"c\":[{\"t\":2,\"n\":\"DMDL - Model Filename\"},{\"t\":11,\"n\":\"DMDT - Texture Files Hashes\"},{\"t\":7,\"n\":\"DMDS - Alternate Textures\",\"c\":[{\"t\":6,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"n\":\"3D Name\"},{\"t\":3,\"n\":\"New Texture\"},{\"t\":3,\"n\":\"3D Index\"}]}]}]},{\"n\":\"DSTF - End Marker\"}]}]}]},{\"t\":3,\"p\":1,\"n\":\"YNAM - Sound - Pick Up\"},{\"t\":3,\"p\":1,\"n\":\"ZNAM - Sound - Put Down\"},{\"t\":2,\"n\":\"BMCT - Ragdoll Constraint Template\"},{\"t\":3,\"n\":\"ETYP - Equipment Type\"},{\"t\":3,\"n\":\"BIDS - Bash Impact Data Set\"},{\"t\":3,\"n\":\"BAMT - Alternate Block Material\"},{\"t\":3,\"n\":\"RNAM - Race\"},{\"t\":3,\"n\":\"KSIZ - Keyword Count\"},{\"t\":7,\"n\":\"KWDA - Keywords\",\"c\":[{\"t\":3,\"n\":\"Keyword\"}]},{\"t\":2,\"n\":\"DESC - Description\"},{\"t\":8,\"n\":\"Armature\",\"c\":[{\"t\":3,\"n\":\"MODL - Model Filename\"}]},{\"t\":6,\"n\":\"DATA - Data\",\"c\":[{\"t\":3,\"n\":\"Value\"},{\"t\":5,\"n\":\"Weight\"}]},{\"t\":3,\"n\":\"DNAM - Armor Rating\"},{\"t\":3,\"n\":\"TNAM - Template Armor\"}]},{\"t\":1,\"p\":1,\"n\":\"ASPC - Acoustic Space\",\"c\":[{\"t\":6,\"n\":\"Record Header\",\"c\":[{\"t\":2,\"n\":\"Signature\"},{\"t\":3,\"n\":\"Data Size\"},{\"t\":3,\"n\":\"Record Flags\"},{\"t\":3,\"n\":\"FormID\"},{\"t\":11,\"n\":\"Version Control Info 1\"},{\"t\":3,\"n\":\"Form Version\"},{\"t\":11,\"n\":\"Version Control Info 2\"}]},{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"X1\"},{\"t\":3,\"p\":1,\"n\":\"Y1\"},{\"t\":3,\"p\":1,\"n\":\"Z1\"},{\"t\":3,\"p\":1,\"n\":\"X2\"},{\"t\":3,\"p\":1,\"n\":\"Y2\"},{\"t\":3,\"p\":1,\"n\":\"Z2\"}],\"lt\":\"BNAM - Environment Type (reverb)\",\"lf\":\"SNAM - Ambient Sound\"},{\"t\":3,\"p\":1,\"n\":\"SNAM - Ambient Sound\",\"lt\":\"OBND - Object Bounds\",\"lf\":\"RDAT - Use Sound from Region (Interiors Only)\"},{\"t\":3,\"p\":1,\"n\":\"RDAT - Use Sound from Region (Interiors Only)\",\"lt\":\"SNAM - Ambient Sound\",\"lf\":\"BNAM - Environment Type (reverb)\"},{\"t\":3,\"p\":1,\"n\":\"BNAM - Environment Type (reverb)\",\"lt\":\"RDAT - Use Sound from Region (Interiors Only)\",\"lf\":\"OBND - Object Bounds\"}]},{\"t\":1,\"p\":1,\"n\":\"EXPL - Explosion\",\"c\":[{\"t\":6,\"n\":\"Record Header\",\"c\":[{\"t\":2,\"n\":\"Signature\"},{\"t\":3,\"n\":\"Data Size\"},{\"t\":3,\"n\":\"Record Flags\"},{\"t\":3,\"n\":\"FormID\"},{\"t\":11,\"n\":\"Version Control Info 1\"},{\"t\":3,\"n\":\"Form Version\"},{\"t\":11,\"n\":\"Version Control Info 2\"}]},{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"n\":\"X1\"},{\"t\":3,\"n\":\"Y1\"},{\"t\":3,\"n\":\"Z1\"},{\"t\":3,\"n\":\"X2\"},{\"t\":3,\"n\":\"Y2\"},{\"t\":3,\"n\":\"Z2\"}]},{\"t\":2,\"n\":\"FULL - Name\"},{\"t\":6,\"n\":\"Model\",\"c\":[{\"t\":2,\"n\":\"MODL - Model Filename\"}]},{\"t\":3,\"n\":\"EITM - Object Effect\"},{\"t\":3,\"n\":\"MNAM - Image Space Modifier\"},{\"t\":6,\"p\":1,\"n\":\"DATA - Data\",\"c\":[{\"t\":3,\"n\":\"Light\"},{\"t\":3,\"p\":1,\"n\":\"Sound 1\",\"lt\":\"Sound 2\",\"lf\":\"Sound Level\"},{\"t\":3,\"p\":1,\"n\":\"Sound 2\",\"lt\":\"Sound Level\",\"lf\":\"Sound 1\"},{\"t\":3,\"n\":\"Impact Data Set\"},{\"t\":3,\"n\":\"Placed Object\"},{\"t\":3,\"n\":\"Spawn Projectile\"},{\"t\":5,\"n\":\"Force\"},{\"t\":5,\"n\":\"Damage\"},{\"t\":5,\"n\":\"Radius\"},{\"t\":5,\"n\":\"IS Radius\"},{\"t\":5,\"n\":\"Vertical Offset Mult\"},{\"t\":3,\"n\":\"Flags\"},{\"t\":3,\"p\":1,\"n\":\"Sound Level\",\"lt\":\"Sound 1\",\"lf\":\"Sound 2\"}]}]},{\"t\":1,\"p\":1,\"n\":\"IPCT - Impact\",\"c\":[{\"t\":6,\"n\":\"Record Header\",\"c\":[{\"t\":2,\"n\":\"Signature\"},{\"t\":3,\"n\":\"Data Size\"},{\"t\":3,\"n\":\"Record Flags\"},{\"t\":3,\"n\":\"FormID\"},{\"t\":11,\"n\":\"Version Control Info 1\"},{\"t\":3,\"n\":\"Form Version\"},{\"t\":11,\"n\":\"Version Control Info 2\"}]},{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"n\":\"Model\",\"c\":[{\"t\":2,\"n\":\"MODL - Model Filename\"}]},{\"t\":6,\"n\":\"DATA - \",\"c\":[{\"t\":5,\"n\":\"Effect - Duration\"},{\"t\":3,\"n\":\"Effect - Orientation\"},{\"t\":5,\"n\":\"Angle Threshold\"},{\"t\":5,\"n\":\"Placement Radius\"},{\"t\":3,\"n\":\"Sound Level\"},{\"t\":3,\"n\":\"Flags\"},{\"t\":3,\"n\":\"Impact Result\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":6,\"n\":\"DODT - Decal Data\",\"c\":[{\"t\":5,\"n\":\"Min Width\"},{\"t\":5,\"n\":\"Max Width\"},{\"t\":5,\"n\":\"Min Height\"},{\"t\":5,\"n\":\"Max Height\"},{\"t\":5,\"n\":\"Depth\"},{\"t\":5,\"n\":\"Shininess\"},{\"t\":6,\"n\":\"Parallax\",\"c\":[{\"t\":5,\"n\":\"Scale\"},{\"t\":3,\"n\":\"Passes\"}]},{\"t\":3,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":6,\"n\":\"Color\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unknown\"}]}]},{\"t\":3,\"n\":\"DNAM - Texture Set\"},{\"t\":3,\"n\":\"ENAM - Secondary Texture Set\"},{\"t\":3,\"p\":1,\"n\":\"SNAM - Sound 1\",\"lt\":\"NAM1 - Sound 2\",\"lf\":\"NAM1 - Sound 2\"},{\"t\":3,\"p\":1,\"n\":\"NAM1 - Sound 2\",\"lt\":\"SNAM - Sound 1\",\"lf\":\"SNAM - Sound 1\"},{\"t\":3,\"n\":\"NAM2 - Hazard\"}]},{\"t\":1,\"p\":1,\"n\":\"MGEF - Magic Effect\",\"c\":[{\"t\":6,\"n\":\"Record Header\",\"c\":[{\"t\":2,\"n\":\"Signature\"},{\"t\":3,\"n\":\"Data Size\"},{\"t\":3,\"n\":\"Record Flags\"},{\"t\":3,\"n\":\"FormID\"},{\"t\":11,\"n\":\"Version Control Info 1\"},{\"t\":3,\"n\":\"Form Version\"},{\"t\":11,\"n\":\"Version Control Info 2\"}]},{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"n\":\"VMAD - Virtual Machine Adapter\",\"c\":[{\"t\":3,\"n\":\"Version\"},{\"t\":3,\"n\":\"Object Format\"},{\"t\":12,\"n\":\"Data\",\"c\":[{\"t\":9,\"n\":\"Scripts\",\"c\":[{\"t\":6,\"n\":\"Script\",\"c\":[{\"t\":2,\"n\":\"scriptName\"},{\"t\":3,\"n\":\"Flags\"},{\"t\":9,\"n\":\"Properties\",\"c\":[{\"t\":6,\"n\":\"Property\",\"c\":[{\"t\":2,\"n\":\"propertyName\"},{\"t\":3,\"n\":\"Type\"},{\"t\":3,\"n\":\"Flags\"},{\"t\":12,\"n\":\"Value\"}]}]}]}]}]}]},{\"t\":2,\"n\":\"FULL - Name\"},{\"t\":3,\"n\":\"MDOB - Menu Display Object\"},{\"t\":3,\"n\":\"KSIZ - Keyword Count\"},{\"t\":9,\"n\":\"KWDA - Keywords\",\"c\":[{\"t\":3,\"n\":\"Keyword\"}]},{\"t\":6,\"n\":\"Magic Effect Data\",\"c\":[{\"t\":6,\"n\":\"DATA - Data\",\"c\":[{\"t\":3,\"n\":\"Flags\"},{\"t\":5,\"n\":\"Base Cost\"},{\"t\":12,\"n\":\"Assoc. Item\"},{\"t\":3,\"n\":\"Magic Skill\"},{\"t\":3,\"n\":\"Resist Value\"},{\"t\":3,\"n\":\"Counter Effect count\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":3,\"n\":\"Casting Light\"},{\"t\":5,\"n\":\"Taper Weight\"},{\"t\":3,\"n\":\"Hit Shader\"},{\"t\":3,\"n\":\"Enchant Shader\"},{\"t\":3,\"n\":\"Minimum Skill Level\"},{\"t\":6,\"n\":\"Spellmaking\",\"c\":[{\"t\":3,\"n\":\"Area\"},{\"t\":5,\"n\":\"Casting Time\"}]},{\"t\":5,\"n\":\"Taper Curve\"},{\"t\":5,\"n\":\"Taper Duration\"},{\"t\":5,\"n\":\"Second AV Weight\"},{\"t\":3,\"n\":\"Archtype\"},{\"t\":3,\"n\":\"Actor Value\"},{\"t\":3,\"n\":\"Projectile\"},{\"t\":3,\"n\":\"Explosion\"},{\"t\":3,\"n\":\"Casting Type\"},{\"t\":3,\"n\":\"Delivery\"},{\"t\":3,\"n\":\"Second Actor Value\"},{\"t\":3,\"n\":\"Casting Art\"},{\"t\":3,\"n\":\"Hit Effect Art\"},{\"t\":3,\"n\":\"Impact Data\"},{\"t\":5,\"n\":\"Skill Usage Multiplier\"},{\"t\":6,\"n\":\"Dual Casting\",\"c\":[{\"t\":3,\"n\":\"Art\"},{\"t\":5,\"n\":\"Scale\"}]},{\"t\":3,\"n\":\"Enchant Art\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":3,\"n\":\"Equip Ability\"},{\"t\":3,\"n\":\"Image Space Modifier\"},{\"t\":3,\"n\":\"Perk to Apply\"},{\"t\":3,\"n\":\"Casting Sound Level\"},{\"t\":6,\"n\":\"Script Effect AI\",\"c\":[{\"t\":5,\"n\":\"Score\"},{\"t\":5,\"n\":\"Delay Time\"}]}]}]},{\"t\":9,\"n\":\"Counter Effects\",\"c\":[{\"t\":3,\"n\":\"ESCE - Effect\"}]},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"SNDD - Sounds\",\"c\":[{\"t\":6,\"p\":1,\"n\":\" #0\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Sound\"}]}]},{\"t\":2,\"n\":\"DNAM - Magic Item Description\"},{\"t\":8,\"n\":\"Conditions\",\"c\":[{\"t\":6,\"n\":\"Condition\",\"c\":[{\"t\":6,\"n\":\"CTDA - \",\"c\":[{\"t\":3,\"n\":\"Type\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":12,\"n\":\"Comparison Value\"},{\"t\":3,\"n\":\"Function\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":12,\"n\":\"Parameter #1\"},{\"t\":12,\"n\":\"Parameter #2\"},{\"t\":3,\"n\":\"Run On\"},{\"t\":12,\"n\":\"Reference\"},{\"t\":3,\"n\":\"Parameter #3\"}]}]}]}]},{\"t\":1,\"p\":1,\"n\":\"MISC - Misc. Item\",\"c\":[{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"n\":\"VMAD - Virtual Machine Adapter\",\"c\":[{\"t\":3,\"n\":\"Version\"},{\"t\":3,\"n\":\"Object Format\"},{\"t\":7,\"n\":\"Scripts\",\"c\":[{\"t\":6,\"n\":\"Script\",\"c\":[{\"t\":2,\"n\":\"scriptName\"},{\"t\":3,\"n\":\"Flags\"},{\"t\":7,\"n\":\"Properties\",\"c\":[{\"t\":6,\"n\":\"Property\",\"c\":[{\"t\":2,\"n\":\"propertyName\"},{\"t\":3,\"n\":\"Type\"},{\"t\":3,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":6,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"n\":\"Alias\"},{\"t\":3,\"n\":\"FormID\"}]},{\"t\":6,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"n\":\"FormID\"},{\"t\":3,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]},{\"t\":2,\"n\":\"String\"},{\"t\":3,\"n\":\"Int32\"},{\"t\":5,\"n\":\"Float\"},{\"t\":3,\"n\":\"Bool\"},{\"t\":7,\"n\":\"Array of Object\",\"c\":[{\"t\":6,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"n\":\"Alias\"},{\"t\":3,\"n\":\"FormID\"}]},{\"t\":6,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"n\":\"FormID\"},{\"t\":3,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]}]},{\"t\":7,\"n\":\"Array of String\",\"c\":[{\"t\":2,\"n\":\"Element\"}]},{\"t\":7,\"n\":\"Array of Int32\",\"c\":[{\"t\":3,\"n\":\"Element\"}]},{\"t\":7,\"n\":\"Array of Float\",\"c\":[{\"t\":5,\"n\":\"Element\"}]},{\"t\":7,\"n\":\"Array of Bool\",\"c\":[{\"t\":3,\"n\":\"Element\"}]}]}]}]}]}]},{\"t\":6,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"n\":\"X1\"},{\"t\":3,\"n\":\"Y1\"},{\"t\":3,\"n\":\"Z1\"},{\"t\":3,\"n\":\"X2\"},{\"t\":3,\"n\":\"Y2\"},{\"t\":3,\"n\":\"Z2\"}]},{\"t\":2,\"n\":\"FULL - Name\"},{\"t\":6,\"n\":\"Model\",\"c\":[{\"t\":2,\"n\":\"MODL - Model Filename\"},{\"t\":11,\"n\":\"MODT - Texture Files Hashes\"},{\"t\":7,\"n\":\"MODS - Alternate Textures\",\"c\":[{\"t\":6,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"n\":\"3D Name\"},{\"t\":3,\"n\":\"New Texture\"},{\"t\":3,\"n\":\"3D Index\"}]}]}]},{\"t\":6,\"n\":\"Icon\",\"c\":[{\"t\":2,\"n\":\"ICON - Large Icon filename\"},{\"t\":2,\"n\":\"MICO - Small Icon filename\"}]},{\"t\":6,\"n\":\"Destructable\",\"c\":[{\"t\":6,\"n\":\"DEST - Header\",\"c\":[{\"t\":3,\"n\":\"Health\"},{\"t\":3,\"n\":\"DEST Count\"},{\"t\":3,\"n\":\"VATS Targetable\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":8,\"n\":\"Stages\",\"c\":[{\"t\":6,\"n\":\"Stage\",\"c\":[{\"t\":6,\"n\":\"DSTD - Destruction Stage Data\",\"c\":[{\"t\":3,\"n\":\"Health %\"},{\"t\":3,\"n\":\"Index\"},{\"t\":3,\"n\":\"Model Damage Stage\"},{\"t\":3,\"n\":\"Flags\"},{\"t\":3,\"n\":\"Self Damage per Second\"},{\"t\":3,\"n\":\"Explosion\"},{\"t\":3,\"n\":\"Debris\"},{\"t\":3,\"n\":\"Debris Count\"}]},{\"t\":6,\"n\":\"Model\",\"c\":[{\"t\":2,\"n\":\"DMDL - Model Filename\"},{\"t\":11,\"n\":\"DMDT - Texture Files Hashes\"},{\"t\":7,\"n\":\"DMDS - Alternate Textures\",\"c\":[{\"t\":6,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"n\":\"3D Name\"},{\"t\":3,\"n\":\"New Texture\"},{\"t\":3,\"n\":\"3D Index\"}]}]}]},{\"n\":\"DSTF - End Marker\"}]}]}]},{\"t\":3,\"p\":1,\"n\":\"YNAM - Sound - Pick Up\"},{\"t\":3,\"p\":1,\"n\":\"ZNAM - Sound - Put Down\"},{\"t\":3,\"n\":\"KSIZ - Keyword Count\"},{\"t\":7,\"n\":\"KWDA - Keywords\",\"c\":[{\"t\":3,\"n\":\"Keyword\"}]},{\"t\":6,\"n\":\"DATA - Data\",\"c\":[{\"t\":3,\"n\":\"Value\"},{\"t\":5,\"n\":\"Weight\"}]}]},{\"t\":1,\"p\":1,\"n\":\"MSTT - Moveable Static\",\"c\":[{\"t\":6,\"n\":\"Record Header\",\"c\":[{\"t\":2,\"n\":\"Signature\"},{\"t\":3,\"n\":\"Data Size\"},{\"t\":3,\"n\":\"Record Flags\"},{\"t\":3,\"n\":\"FormID\"},{\"t\":11,\"n\":\"Version Control Info 1\"},{\"t\":3,\"n\":\"Form Version\"},{\"t\":11,\"n\":\"Version Control Info 2\"}]},{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"n\":\"X1\"},{\"t\":3,\"n\":\"Y1\"},{\"t\":3,\"n\":\"Z1\"},{\"t\":3,\"n\":\"X2\"},{\"t\":3,\"n\":\"Y2\"},{\"t\":3,\"n\":\"Z2\"}]},{\"t\":2,\"n\":\"FULL - Name\"},{\"t\":6,\"n\":\"Model\",\"c\":[{\"t\":2,\"n\":\"MODL - Model Filename\"}]},{\"t\":6,\"n\":\"Destructable\",\"c\":[{\"t\":6,\"n\":\"DEST - Header\",\"c\":[{\"t\":3,\"n\":\"Health\"},{\"t\":3,\"n\":\"DEST Count\"},{\"t\":3,\"n\":\"VATS Targetable\"},{\"t\":11,\"n\":\"Unknown\"}]}]},{\"t\":3,\"n\":\"DATA - Flags\"},{\"t\":3,\"p\":1,\"n\":\"SNAM - Looping Sound\"}]},{\"t\":1,\"p\":1,\"n\":\"RACE - Race\",\"c\":[{\"t\":6,\"n\":\"Record Header\",\"c\":[{\"t\":2,\"n\":\"Signature\"},{\"t\":3,\"n\":\"Data Size\"},{\"t\":3,\"n\":\"Record Flags\"},{\"t\":3,\"n\":\"FormID\"},{\"t\":11,\"n\":\"Version Control Info 1\"},{\"t\":3,\"n\":\"Form Version\"},{\"t\":11,\"n\":\"Version Control Info 2\"}]},{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"n\":\"FULL - Name\"},{\"t\":2,\"n\":\"DESC - Description\"},{\"t\":3,\"n\":\"SPCT - Count\"},{\"t\":9,\"n\":\"Actor Effects\",\"c\":[{\"t\":3,\"n\":\"SPLO - Actor Effect\"}]},{\"t\":3,\"n\":\"WNAM - Skin\"},{\"t\":6,\"n\":\"BOD2 - Biped Body Template\",\"c\":[{\"t\":3,\"n\":\"First Person Flags\"},{\"t\":3,\"n\":\"General Flags\"},{\"n\":\"Unused\"},{\"t\":3,\"n\":\"Armor Type\"}]},{\"t\":3,\"n\":\"KSIZ - Keyword Count\"},{\"t\":9,\"n\":\"KWDA - Keywords\",\"c\":[{\"t\":3,\"n\":\"Keyword\"}]},{\"t\":6,\"n\":\"DATA - \",\"c\":[{\"t\":10,\"n\":\"Skill Boosts\",\"c\":[{\"t\":6,\"n\":\"Skill Boost\",\"c\":[{\"t\":3,\"n\":\"Skill\"},{\"t\":3,\"n\":\"Boost\"}]},{\"t\":6,\"n\":\"Skill Boost\",\"c\":[{\"t\":3,\"n\":\"Skill\"},{\"t\":3,\"n\":\"Boost\"}]},{\"t\":6,\"n\":\"Skill Boost\",\"c\":[{\"t\":3,\"n\":\"Skill\"},{\"t\":3,\"n\":\"Boost\"}]},{\"t\":6,\"n\":\"Skill Boost\",\"c\":[{\"t\":3,\"n\":\"Skill\"},{\"t\":3,\"n\":\"Boost\"}]},{\"t\":6,\"n\":\"Skill Boost\",\"c\":[{\"t\":3,\"n\":\"Skill\"},{\"t\":3,\"n\":\"Boost\"}]},{\"t\":6,\"n\":\"Skill Boost\",\"c\":[{\"t\":3,\"n\":\"Skill\"},{\"t\":3,\"n\":\"Boost\"}]},{\"t\":6,\"n\":\"Skill Boost\",\"c\":[{\"t\":3,\"n\":\"Skill\"},{\"t\":3,\"n\":\"Boost\"}]}]},{\"t\":11,\"n\":\"Unknown\"},{\"t\":5,\"n\":\"Male Height\"},{\"t\":5,\"n\":\"Female Height\"},{\"t\":5,\"n\":\"Male Weight\"},{\"t\":5,\"n\":\"Female Weight\"},{\"t\":3,\"n\":\"Flags\"},{\"t\":5,\"n\":\"Starting Health\"},{\"t\":5,\"n\":\"Starting Magicka\"},{\"t\":5,\"n\":\"Starting Stamina\"},{\"t\":5,\"n\":\"Base Carry Weight\"},{\"t\":5,\"n\":\"Base Mass\"},{\"t\":5,\"n\":\"Acceleration rate\"},{\"t\":5,\"n\":\"Deceleration rate\"},{\"t\":3,\"n\":\"Size\"},{\"t\":3,\"n\":\"Head Biped Object\"},{\"t\":3,\"n\":\"Hair Biped Object\"},{\"t\":5,\"n\":\"Injured Health Pct\"},{\"t\":3,\"n\":\"Shield Biped Object\"},{\"t\":5,\"n\":\"Health Regen\"},{\"t\":5,\"n\":\"Magicka Regen\"},{\"t\":5,\"n\":\"Stamina Regen\"},{\"t\":5,\"n\":\"Unarmed Damage\"},{\"t\":5,\"n\":\"Unarmed Reach\"},{\"t\":3,\"n\":\"Body Biped Object\"},{\"t\":5,\"n\":\"Aim Angle Tolerance\"},{\"t\":5,\"n\":\"Flight Radius\"},{\"t\":5,\"n\":\"Angular Acceleration Rate\"},{\"t\":5,\"n\":\"Angular Tolerance\"},{\"t\":3,\"n\":\"Flags 2\"},{\"t\":6,\"n\":\"Mount Data\",\"c\":[{\"t\":5,\"n\":\"Offset X\"},{\"t\":5,\"n\":\"Offset Y\"},{\"t\":5,\"n\":\"Unknown\"},{\"t\":5,\"n\":\"Unknown\"},{\"t\":5,\"n\":\"Unknown\"},{\"t\":5,\"n\":\"Unknown\"},{\"t\":5,\"n\":\"Unknown\"},{\"t\":5,\"n\":\"Unknown\"},{\"t\":5,\"n\":\"Unknown\"}]}]},{\"n\":\"MNAM - Male Marker\"},{\"t\":2,\"n\":\"ANAM - Male Skeletal Model\"},{\"t\":11,\"n\":\"MODT - Texture Files Hashes\"},{\"n\":\"FNAM - Female Marker\"},{\"t\":2,\"n\":\"ANAM - Female Skeletal Model\"},{\"t\":11,\"n\":\"MODT - Texture Files Hashes\"},{\"n\":\"NAM2 - Marker NAM2 #1\"},{\"t\":9,\"n\":\"Movement Type Names\",\"c\":[{\"t\":2,\"n\":\"MTNM - Name\"}]},{\"t\":7,\"n\":\"VTCK - Voices\",\"c\":[{\"t\":3,\"n\":\"Voice #0 (Male)\"},{\"t\":3,\"n\":\"Voice #1 (Female)\"}]},{\"t\":7,\"n\":\"DNAM - Decapitate Armors\",\"c\":[{\"t\":3,\"n\":\"Decapitate Armor #0 (Male)\"},{\"t\":3,\"n\":\"Decapitate Armor #1 (Female)\"}]},{\"t\":7,\"n\":\"HCLF - Default Hair Colors\",\"c\":[{\"t\":3,\"n\":\"Default Hair Color #0 (Male)\"},{\"t\":3,\"n\":\"Default Hair Color #1 (Female)\"}]},{\"t\":3,\"n\":\"TINL - Total Number of Tints in List\"},{\"t\":5,\"n\":\"PNAM - FaceGen - Main clamp\"},{\"t\":5,\"n\":\"UNAM - FaceGen - Face clamp\"},{\"t\":3,\"n\":\"ATKR - Attack Race\"},{\"t\":10,\"n\":\"Attacks\",\"c\":[{\"t\":6,\"n\":\"Attack\",\"c\":[{\"t\":6,\"n\":\"ATKD - Attack Data\",\"c\":[{\"t\":5,\"n\":\"Damage Mult\"},{\"t\":5,\"n\":\"Attack Chance\"},{\"t\":3,\"n\":\"Attack Spell\"},{\"t\":3,\"n\":\"Attack Flags\"},{\"t\":5,\"n\":\"Attack Angle\"},{\"t\":5,\"n\":\"Strike Angle\"},{\"t\":5,\"n\":\"Stagger\"},{\"t\":3,\"n\":\"Attack Type\"},{\"t\":5,\"n\":\"Knockdown\"},{\"t\":5,\"n\":\"Recovery Time\"},{\"t\":5,\"n\":\"Stamina Mult\"}]}]}]},{\"t\":6,\"n\":\"Body Data\",\"c\":[{\"n\":\"NAM1 - Body Data Marker\"},{\"t\":6,\"n\":\"Male Body Data\",\"c\":[{\"n\":\"MNAM - Male Data Marker\"},{\"t\":10,\"n\":\"Parts\",\"c\":[{\"t\":6,\"n\":\"Part\",\"c\":[{\"t\":3,\"n\":\"INDX - Index\"}]}]}]},{\"t\":6,\"n\":\"Female Body Data\",\"c\":[{\"n\":\"FNAM - Female Data Marker\"},{\"t\":10,\"n\":\"Parts\",\"c\":[{\"t\":6,\"n\":\"Part\",\"c\":[{\"t\":3,\"n\":\"INDX - Index\"}]}]}]}]},{\"t\":9,\"n\":\"HNAM - Hairs\",\"c\":[{\"t\":3,\"n\":\"Hair\"}]},{\"t\":9,\"n\":\"ENAM - Eyes\",\"c\":[{\"t\":3,\"n\":\"Eye\"}]},{\"t\":3,\"n\":\"GNAM - Body Part Data\"},{\"n\":\"NAM2 - Marker NAM2 #2\"},{\"n\":\"NAM3 - Marker NAM3 #3\"},{\"t\":6,\"n\":\"Male Behavior Graph\",\"c\":[{\"n\":\"MNAM - Male Data Marker\"}]},{\"t\":6,\"n\":\"Female Behavior Graph\",\"c\":[{\"n\":\"FNAM - Female Data Marker\"}]},{\"t\":3,\"n\":\"NAM4 - Material Type\"},{\"t\":3,\"n\":\"NAM5 - Impact Data Set\"},{\"t\":3,\"n\":\"NAM7 - Decapitation FX\"},{\"t\":3,\"p\":1,\"n\":\"ONAM - Open Loot Sound\"},{\"t\":3,\"p\":1,\"n\":\"LNAM - Close Loot Sound\"},{\"t\":7,\"n\":\"Biped Object Names\",\"c\":[{\"t\":2,\"n\":\"NAME - Name\"}]},{\"t\":10,\"n\":\"Movement Types\",\"c\":[{\"t\":6,\"n\":\"Movement Types\",\"c\":[{\"t\":3,\"n\":\"MTYP - Movement Type\"}]}]},{\"t\":3,\"n\":\"VNAM - Equipment Flags\"},{\"t\":9,\"n\":\"Equip Slots\",\"c\":[{\"t\":3,\"n\":\"QNAM - Equip Slot\"}]},{\"t\":3,\"n\":\"UNES - Unarmed Equip Slot\"},{\"t\":7,\"n\":\"Phoneme Target Names\",\"c\":[{\"t\":2,\"n\":\"PHTN - Name\"}]},{\"t\":6,\"n\":\"FaceFX Phonemes\",\"c\":[{\"t\":6,\"n\":\"IY\",\"c\":[{\"t\":6,\"n\":\"PHWT - Phoneme Target Weight\",\"c\":[{\"t\":5,\"n\":\"Aah \\/ LipBigAah\"},{\"t\":5,\"n\":\"BigAah \\/ LipDST\"},{\"t\":5,\"n\":\"BMP \\/ LipEee\"},{\"t\":5,\"n\":\"ChJsh \\/ LipFV\"},{\"t\":5,\"n\":\"DST \\/ LipK\"},{\"t\":5,\"n\":\"Eee \\/ LipL\"},{\"t\":5,\"n\":\"Eh \\/ LipR\"},{\"t\":5,\"n\":\"FV \\/ LipTh\"},{\"t\":5,\"n\":\"I\"},{\"t\":5,\"n\":\"K\"},{\"t\":5,\"n\":\"N\"},{\"t\":5,\"n\":\"Oh\"},{\"t\":5,\"n\":\"OohQ\"},{\"t\":5,\"n\":\"R\"},{\"t\":5,\"n\":\"TH\"},{\"t\":5,\"n\":\"W\"}]}]}]},{\"t\":3,\"n\":\"WKMV - Base Movement Default - Walk\"},{\"t\":3,\"n\":\"RNMV - Base Movement Default - Run\"},{\"t\":3,\"n\":\"SWMV - Base Movement Default - Swim\"},{\"t\":3,\"n\":\"FLMV - Base Movement Default - Fly\"},{\"t\":3,\"n\":\"SNMV - Base Movement Default - Sneak\"},{\"t\":3,\"n\":\"SPMV - Base Movement Default - Sprint\"},{\"t\":6,\"n\":\"Head Data\",\"c\":[{\"n\":\"NAM0 - Head Data Marker\"},{\"t\":6,\"n\":\"Male Head Data\",\"c\":[{\"n\":\"MNAM - Male Data Marker\"}]},{\"t\":6,\"n\":\"Female Head Data\",\"c\":[{\"n\":\"NAM0 - Head Data Marker\"},{\"n\":\"FNAM - Female Data Marker\"}]}]},{\"t\":3,\"n\":\"NAM8 - Morph race\"},{\"t\":3,\"n\":\"RNAM - Armor race\"}]},{\"t\":1,\"p\":1,\"n\":\"REVB - Reverb Parameters\",\"c\":[{\"t\":6,\"n\":\"Record Header\",\"c\":[{\"t\":2,\"n\":\"Signature\"},{\"t\":3,\"n\":\"Data Size\"},{\"t\":3,\"n\":\"Record Flags\"},{\"t\":3,\"n\":\"FormID\"},{\"t\":11,\"n\":\"Version Control Info 1\"},{\"t\":3,\"n\":\"Form Version\"},{\"t\":11,\"n\":\"Version Control Info 2\"}]},{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DATA - Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Decay Time (ms)\"},{\"t\":3,\"p\":1,\"n\":\"HF Reference (Hz)\"},{\"t\":3,\"p\":1,\"n\":\"Room Filter\"},{\"t\":3,\"p\":1,\"n\":\"Room HF Filter\"},{\"t\":3,\"p\":1,\"n\":\"Reflections\"},{\"t\":3,\"p\":1,\"n\":\"Reverb Amp\"},{\"t\":3,\"p\":1,\"n\":\"Decay HF Ratio\"},{\"t\":3,\"p\":1,\"n\":\"Reflect Delay (ms), scaled\"},{\"t\":3,\"p\":1,\"n\":\"Reverb Delay (ms)\"},{\"t\":3,\"p\":1,\"n\":\"Diffusion %\"},{\"t\":3,\"p\":1,\"n\":\"Density %\"},{\"t\":3,\"p\":1,\"n\":\"Unknown\"}]}]},{\"t\":1,\"p\":1,\"n\":\"SLGM - Soul Gem\",\"c\":[{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"n\":\"X1\"},{\"t\":3,\"n\":\"Y1\"},{\"t\":3,\"n\":\"Z1\"},{\"t\":3,\"n\":\"X2\"},{\"t\":3,\"n\":\"Y2\"},{\"t\":3,\"n\":\"Z2\"}]},{\"t\":2,\"n\":\"FULL - Name\"},{\"t\":6,\"n\":\"Model\",\"c\":[{\"t\":2,\"n\":\"MODL - Model Filename\"},{\"t\":11,\"n\":\"MODT - Texture Files Hashes\"},{\"t\":7,\"n\":\"MODS - Alternate Textures\",\"c\":[{\"t\":6,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"n\":\"3D Name\"},{\"t\":3,\"n\":\"New Texture\"},{\"t\":3,\"n\":\"3D Index\"}]}]}]},{\"t\":6,\"n\":\"Icon\",\"c\":[{\"t\":2,\"n\":\"ICON - Large Icon filename\"},{\"t\":2,\"n\":\"MICO - Small Icon filename\"}]},{\"t\":6,\"n\":\"Destructable\",\"c\":[{\"t\":6,\"n\":\"DEST - Header\",\"c\":[{\"t\":3,\"n\":\"Health\"},{\"t\":3,\"n\":\"DEST Count\"},{\"t\":3,\"n\":\"VATS Targetable\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":8,\"n\":\"Stages\",\"c\":[{\"t\":6,\"n\":\"Stage\",\"c\":[{\"t\":6,\"n\":\"DSTD - Destruction Stage Data\",\"c\":[{\"t\":3,\"n\":\"Health %\"},{\"t\":3,\"n\":\"Index\"},{\"t\":3,\"n\":\"Model Damage Stage\"},{\"t\":3,\"n\":\"Flags\"},{\"t\":3,\"n\":\"Self Damage per Second\"},{\"t\":3,\"n\":\"Explosion\"},{\"t\":3,\"n\":\"Debris\"},{\"t\":3,\"n\":\"Debris Count\"}]},{\"t\":6,\"n\":\"Model\",\"c\":[{\"t\":2,\"n\":\"DMDL - Model Filename\"},{\"t\":11,\"n\":\"DMDT - Texture Files Hashes\"},{\"t\":7,\"n\":\"DMDS - Alternate Textures\",\"c\":[{\"t\":6,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"n\":\"3D Name\"},{\"t\":3,\"n\":\"New Texture\"},{\"t\":3,\"n\":\"3D Index\"}]}]}]},{\"n\":\"DSTF - End Marker\"}]}]}]},{\"t\":3,\"p\":1,\"n\":\"YNAM - Sound - Pick Up\"},{\"t\":3,\"p\":1,\"n\":\"ZNAM - Sound - Put Down\"},{\"t\":3,\"n\":\"KSIZ - Keyword Count\"},{\"t\":7,\"n\":\"KWDA - Keywords\",\"c\":[{\"t\":3,\"n\":\"Keyword\"}]},{\"t\":6,\"n\":\"DATA - \",\"c\":[{\"t\":3,\"n\":\"Value\"},{\"t\":5,\"n\":\"Weight\"}]},{\"t\":3,\"n\":\"SOUL - Contained Soul\"},{\"t\":3,\"n\":\"SLCP - Maximum Capacity\"},{\"t\":3,\"n\":\"NAM0 - Linked To\"}]},{\"t\":1,\"p\":1,\"n\":\"SNCT - Sound Category\",\"c\":[{\"t\":6,\"n\":\"Record Header\",\"c\":[{\"t\":2,\"n\":\"Signature\"},{\"t\":3,\"n\":\"Data Size\"},{\"t\":3,\"n\":\"Record Flags\"},{\"t\":3,\"n\":\"FormID\"},{\"t\":11,\"n\":\"Version Control Info 1\"},{\"t\":3,\"n\":\"Form Version\"},{\"t\":11,\"n\":\"Version Control Info 2\"}]},{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"n\":\"FULL - Name\"},{\"t\":3,\"p\":1,\"n\":\"FNAM - Flags\",\"lt\":\"UNAM - Default Menu Value\",\"lf\":\"PNAM - Parent\"},{\"t\":3,\"p\":1,\"n\":\"PNAM - Parent\",\"lt\":\"FNAM - Flags\",\"lf\":\"VNAM - Static Volume Multiplier\"},{\"t\":3,\"p\":1,\"n\":\"VNAM - Static Volume Multiplier\",\"lt\":\"PNAM - Parent\",\"lf\":\"UNAM - Default Menu Value\"},{\"t\":3,\"p\":1,\"n\":\"UNAM - Default Menu Value\",\"lt\":\"VNAM - Static Volume Multiplier\",\"lf\":\"FNAM - Flags\"}]},{\"t\":1,\"p\":1,\"n\":\"SNDR - Sound Descriptor\",\"c\":[{\"t\":6,\"n\":\"Record Header\",\"c\":[{\"t\":2,\"n\":\"Signature\"},{\"t\":3,\"n\":\"Data Size\"},{\"t\":3,\"n\":\"Record Flags\"},{\"t\":3,\"n\":\"FormID\"},{\"t\":11,\"n\":\"Version Control Info 1\"},{\"t\":3,\"n\":\"Form Version\"},{\"t\":11,\"n\":\"Version Control Info 2\"}]},{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":11,\"n\":\"CNAM - Unknown\"},{\"t\":3,\"p\":1,\"n\":\"GNAM - Category\",\"lt\":\"BNAM - Values\",\"lf\":\"SNAM - Alternate Sound For\"},{\"t\":3,\"p\":1,\"n\":\"SNAM - Alternate Sound For\",\"lt\":\"GNAM - Category\",\"lf\":\"Sounds\"},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Sounds\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Sound Files\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"ANAM - File Name\"}]}],\"lt\":\"SNAM - Alternate Sound For\",\"lf\":\"ONAM - Output Model\"},{\"t\":3,\"p\":1,\"n\":\"ONAM - Output Model\",\"lt\":\"Sounds\",\"lf\":\"FNAM - String\"},{\"t\":2,\"p\":1,\"n\":\"FNAM - String\",\"lt\":\"ONAM - Output Model\",\"lf\":\"Conditions\"},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Conditions\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Condition\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"CTDA - \",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":11,\"p\":1,\"n\":\"Unused\"},{\"t\":12,\"p\":1,\"n\":\"Comparison Value\"},{\"t\":3,\"p\":1,\"n\":\"Function\"},{\"t\":11,\"p\":1,\"n\":\"Unused\"},{\"t\":12,\"p\":1,\"n\":\"Parameter #1\"},{\"t\":12,\"p\":1,\"n\":\"Parameter #2\"},{\"t\":3,\"p\":1,\"n\":\"Run On\"},{\"t\":12,\"p\":1,\"n\":\"Reference\"},{\"t\":3,\"p\":1,\"n\":\"Parameter #3\"}]}]}],\"lt\":\"FNAM - String\",\"lf\":\"LNAM - Values\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"LNAM - Values\",\"c\":[{\"t\":11,\"p\":1,\"n\":\"Unknown\"},{\"t\":3,\"p\":1,\"n\":\"Looping\"},{\"t\":11,\"p\":1,\"n\":\"Unknown\"},{\"t\":3,\"p\":1,\"n\":\"Rumble Send Value = (Small \\/ 7) + ((Big \\/ 7) * 16)\"}],\"lt\":\"Conditions\",\"lf\":\"BNAM - Values\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"BNAM - Values\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"% Frequency Shift\"},{\"t\":3,\"p\":1,\"n\":\"% Frequency Variance\"},{\"t\":3,\"p\":1,\"n\":\"Priority\"},{\"t\":3,\"p\":1,\"n\":\"db Variance\"},{\"t\":3,\"p\":1,\"n\":\"Static Attenuation (db)\"}],\"lt\":\"LNAM - Values\",\"lf\":\"GNAM - Category\"}]},{\"t\":1,\"p\":1,\"n\":\"SOPM - Sound Output Model\",\"c\":[{\"t\":6,\"n\":\"Record Header\",\"c\":[{\"t\":2,\"n\":\"Signature\"},{\"t\":3,\"n\":\"Data Size\"},{\"t\":3,\"n\":\"Record Flags\"},{\"t\":3,\"n\":\"FormID\"},{\"t\":11,\"n\":\"Version Control Info 1\"},{\"t\":3,\"n\":\"Form Version\"},{\"t\":11,\"n\":\"Version Control Info 2\"}]},{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"NAM1 - Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"p\":1,\"n\":\"Unknown\"},{\"t\":3,\"p\":1,\"n\":\"Reverb Send %\"}],\"lt\":\"ANAM - Attenuation Values\",\"lf\":\"MNAM - Type\"},{\"t\":11,\"n\":\"FNAM - Unknown\"},{\"t\":3,\"p\":1,\"n\":\"MNAM - Type\",\"lt\":\"NAM1 - Data\",\"lf\":\"ONAM - Output Values\"},{\"t\":11,\"n\":\"CNAM - Unknown\"},{\"t\":11,\"n\":\"SNAM - Unknown\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"ONAM - Output Values\",\"c\":[{\"t\":8,\"p\":1,\"n\":\"Channels\",\"c\":[{\"t\":6,\"p\":1,\"n\":\" #0 (Channel 0)\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"L\"},{\"t\":3,\"p\":1,\"n\":\"R\"},{\"t\":3,\"p\":1,\"n\":\"C\"},{\"t\":3,\"p\":1,\"n\":\"LFE\"},{\"t\":3,\"p\":1,\"n\":\"RL\"},{\"t\":3,\"p\":1,\"n\":\"RR\"},{\"t\":3,\"p\":1,\"n\":\"BL\"},{\"t\":3,\"p\":1,\"n\":\"BR\"}]},{\"t\":6,\"p\":1,\"n\":\" #1 (Channel 1)\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"L\"},{\"t\":3,\"p\":1,\"n\":\"R\"},{\"t\":3,\"p\":1,\"n\":\"C\"},{\"t\":3,\"p\":1,\"n\":\"LFE\"},{\"t\":3,\"p\":1,\"n\":\"RL\"},{\"t\":3,\"p\":1,\"n\":\"RR\"},{\"t\":3,\"p\":1,\"n\":\"BL\"},{\"t\":3,\"p\":1,\"n\":\"BR\"}]},{\"t\":6,\"p\":1,\"n\":\" #2 (Channel 2? (unused))\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"L\"},{\"t\":3,\"p\":1,\"n\":\"R\"},{\"t\":3,\"p\":1,\"n\":\"C\"},{\"t\":3,\"p\":1,\"n\":\"LFE\"},{\"t\":3,\"p\":1,\"n\":\"RL\"},{\"t\":3,\"p\":1,\"n\":\"RR\"},{\"t\":3,\"p\":1,\"n\":\"BL\"},{\"t\":3,\"p\":1,\"n\":\"BR\"}]}]}],\"lt\":\"MNAM - Type\",\"lf\":\"ANAM - Attenuation Values\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"ANAM - Attenuation Values\",\"c\":[{\"t\":11,\"p\":1,\"n\":\"Unknown\"},{\"t\":5,\"p\":1,\"n\":\"Min Distance\"},{\"t\":5,\"p\":1,\"n\":\"Max Distance\"},{\"t\":7,\"p\":1,\"n\":\"Curve\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Value #0\"},{\"t\":3,\"p\":1,\"n\":\"Value #1\"},{\"t\":3,\"p\":1,\"n\":\"Value #2\"},{\"t\":3,\"p\":1,\"n\":\"Value #3\"},{\"t\":3,\"p\":1,\"n\":\"Value #4\"}]},{\"t\":11,\"p\":1,\"n\":\"Unknown\"}],\"lt\":\"ONAM - Output Values\",\"lf\":\"NAM1 - Data\"}]},{\"t\":1,\"p\":1,\"n\":\"SOUN - Sound Marker\",\"c\":[{\"t\":6,\"n\":\"Record Header\",\"c\":[{\"t\":2,\"n\":\"Signature\"},{\"t\":3,\"n\":\"Data Size\"},{\"t\":3,\"n\":\"Record Flags\"},{\"t\":3,\"n\":\"FormID\"},{\"t\":11,\"n\":\"Version Control Info 1\"},{\"t\":3,\"n\":\"Form Version\"},{\"t\":11,\"n\":\"Version Control Info 2\"}]},{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"n\":\"X1\"},{\"t\":3,\"n\":\"Y1\"},{\"t\":3,\"n\":\"Z1\"},{\"t\":3,\"n\":\"X2\"},{\"t\":3,\"n\":\"Y2\"},{\"t\":3,\"n\":\"Z2\"}]},{\"t\":11,\"n\":\"FNAM - Unknown\"},{\"t\":11,\"n\":\"SNDD - Unknown\"},{\"t\":3,\"p\":1,\"n\":\"SDSC - Sound Descriptor\"}]},{\"t\":1,\"p\":1,\"n\":\"WEAP - Weapon\",\"c\":[{\"t\":6,\"n\":\"Record Header\",\"c\":[{\"t\":2,\"n\":\"Signature\"},{\"t\":3,\"n\":\"Data Size\"},{\"t\":3,\"n\":\"Record Flags\"},{\"t\":3,\"n\":\"FormID\"},{\"t\":11,\"n\":\"Version Control Info 1\"},{\"t\":3,\"n\":\"Form Version\"},{\"t\":11,\"n\":\"Version Control Info 2\"}]},{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"n\":\"VMAD - Virtual Machine Adapter\",\"c\":[{\"t\":3,\"n\":\"Version\"},{\"t\":3,\"n\":\"Object Format\"},{\"t\":12,\"n\":\"Data\",\"c\":[{\"t\":9,\"n\":\"Scripts\",\"c\":[{\"t\":6,\"n\":\"Script\",\"c\":[{\"t\":2,\"n\":\"scriptName\"},{\"t\":3,\"n\":\"Flags\"},{\"t\":9,\"n\":\"Properties\",\"c\":[{\"t\":6,\"n\":\"Property\",\"c\":[{\"t\":2,\"n\":\"propertyName\"},{\"t\":3,\"n\":\"Type\"},{\"t\":3,\"n\":\"Flags\"},{\"t\":12,\"n\":\"Value\"}]}]}]}]}]}]},{\"t\":6,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"n\":\"X1\"},{\"t\":3,\"n\":\"Y1\"},{\"t\":3,\"n\":\"Z1\"},{\"t\":3,\"n\":\"X2\"},{\"t\":3,\"n\":\"Y2\"},{\"t\":3,\"n\":\"Z2\"}]},{\"t\":2,\"n\":\"FULL - Name\"},{\"t\":6,\"n\":\"Model\",\"c\":[{\"t\":2,\"n\":\"MODL - Model Filename\"}]},{\"t\":6,\"n\":\"Icon\",\"c\":[{\"t\":2,\"n\":\"ICON - Large Icon filename\"}]},{\"t\":3,\"n\":\"EITM - Object Effect\"},{\"t\":3,\"n\":\"EAMT - Enchantment Amount\"},{\"t\":6,\"n\":\"Destructable\",\"c\":[{\"t\":6,\"n\":\"DEST - Header\",\"c\":[{\"t\":3,\"n\":\"Health\"},{\"t\":3,\"n\":\"DEST Count\"},{\"t\":3,\"n\":\"VATS Targetable\"},{\"t\":11,\"n\":\"Unknown\"}]}]},{\"t\":3,\"n\":\"ETYP - Equipment Type\"},{\"t\":3,\"p\":1,\"n\":\"BIDS - Block Bash Impact Data Set\"},{\"t\":3,\"n\":\"BAMT - Alternate Block Material\"},{\"t\":3,\"p\":1,\"n\":\"YNAM - Sound - Pick Up\"},{\"t\":3,\"p\":1,\"n\":\"ZNAM - Sound - Drop\"},{\"t\":3,\"n\":\"KSIZ - Keyword Count\"},{\"t\":9,\"n\":\"KWDA - Keywords\",\"c\":[{\"t\":3,\"n\":\"Keyword\"}]},{\"t\":2,\"n\":\"DESC - Description\"},{\"t\":6,\"n\":\"Has Scope\",\"c\":[{\"t\":2,\"n\":\"MOD3 - Model Filename\"}]},{\"t\":11,\"n\":\"NNAM - Unused\"},{\"t\":3,\"p\":1,\"n\":\"INAM - Impact Data Set\"},{\"t\":3,\"n\":\"WNAM - 1st Person Model Object\"},{\"t\":3,\"p\":1,\"n\":\"SNAM - Attack Sound\"},{\"t\":3,\"p\":1,\"n\":\"XNAM - Attack Sound 2D\"},{\"t\":3,\"p\":1,\"n\":\"NAM7 - Attack Loop Sound\"},{\"t\":3,\"p\":1,\"n\":\"TNAM - Attack Fail Sound\"},{\"t\":3,\"p\":1,\"n\":\"UNAM - Idle Sound\"},{\"t\":3,\"p\":1,\"n\":\"NAM9 - Equip Sound\"},{\"t\":3,\"p\":1,\"n\":\"NAM8 - Unequip Sound\"},{\"t\":6,\"n\":\"DATA - Game Data\",\"c\":[{\"t\":3,\"n\":\"Value\"},{\"t\":5,\"n\":\"Weight\"},{\"t\":3,\"n\":\"Damage\"}]},{\"t\":6,\"n\":\"DNAM - Data\",\"c\":[{\"t\":3,\"n\":\"Animation Type\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":5,\"n\":\"Speed\"},{\"t\":5,\"n\":\"Reach\"},{\"t\":3,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":5,\"n\":\"Sight FOV\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":3,\"n\":\"Base VATS To-Hit Chance\"},{\"t\":3,\"n\":\"Attack Animation\"},{\"t\":3,\"n\":\"# Projectiles\"},{\"t\":3,\"n\":\"Embedded Weapon AV (unused)\"},{\"t\":5,\"n\":\"Range Min\"},{\"t\":5,\"n\":\"Range Max\"},{\"t\":3,\"n\":\"On Hit\"},{\"t\":3,\"n\":\"Flags2\"},{\"t\":5,\"n\":\"Animation Attack Mult\"},{\"t\":5,\"n\":\"Unknown\"},{\"t\":5,\"n\":\"Rumble - Left Motor Strength\"},{\"t\":5,\"n\":\"Rumble - Right Motor Strength\"},{\"t\":5,\"n\":\"Rumble - Duration\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":3,\"n\":\"Skill\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":3,\"n\":\"Resist\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":5,\"n\":\"Stagger\"}]},{\"t\":6,\"n\":\"CRDT - Critical Data\",\"c\":[{\"t\":3,\"n\":\"Damage\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":5,\"n\":\"% Mult\"},{\"t\":3,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":3,\"n\":\"Effect\"}]},{\"t\":3,\"n\":\"VNAM - Detection Sound Level\"},{\"t\":3,\"n\":\"CNAM - Template\"}]},{\"t\":1,\"p\":1,\"n\":\"WTHR - Weather\",\"c\":[{\"t\":6,\"n\":\"Record Header\",\"c\":[{\"t\":2,\"n\":\"Signature\"},{\"t\":3,\"n\":\"Data Size\"},{\"t\":3,\"n\":\"Record Flags\"},{\"t\":3,\"n\":\"FormID\"},{\"t\":11,\"n\":\"Version Control Info 1\"},{\"t\":3,\"n\":\"Form Version\"},{\"t\":11,\"n\":\"Version Control Info 2\"}]},{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"n\":\"00TX - Cloud Texture Layer #0\"},{\"t\":2,\"n\":\"10TX - Cloud Texture Layer #1\"},{\"t\":2,\"n\":\"20TX - Cloud Texture Layer #2\"},{\"t\":2,\"n\":\"30TX - Cloud Texture Layer #3\"},{\"t\":2,\"n\":\"40TX - Cloud Texture Layer #4\"},{\"t\":2,\"n\":\"50TX - Cloud Texture Layer #5\"},{\"t\":2,\"n\":\"60TX - Cloud Texture Layer #6\"},{\"t\":2,\"n\":\"70TX - Cloud Texture Layer #7\"},{\"t\":2,\"n\":\"80TX - Cloud Texture Layer #8\"},{\"t\":2,\"n\":\"90TX - Cloud Texture Layer #9\"},{\"t\":2,\"n\":\":0TX - Cloud Texture Layer #10\"},{\"t\":2,\"n\":\";0TX - Cloud Texture Layer #11\"},{\"t\":2,\"n\":\"<0TX - Cloud Texture Layer #12\"},{\"t\":2,\"n\":\"=0TX - Cloud Texture Layer #13\"},{\"t\":2,\"n\":\">0TX - Cloud Texture Layer #14\"},{\"t\":2,\"n\":\"?0TX - Cloud Texture Layer #15\"},{\"t\":2,\"n\":\"@0TX - Cloud Texture Layer #16\"},{\"t\":2,\"n\":\"A0TX - Cloud Texture Layer #17\"},{\"t\":2,\"n\":\"B0TX - Cloud Texture Layer #18\"},{\"t\":2,\"n\":\"C0TX - Cloud Texture Layer #19\"},{\"t\":2,\"n\":\"D0TX - Cloud Texture Layer #20\"},{\"t\":2,\"n\":\"E0TX - Cloud Texture Layer #21\"},{\"t\":2,\"n\":\"F0TX - Cloud Texture Layer #22\"},{\"t\":2,\"n\":\"G0TX - Cloud Texture Layer #23\"},{\"t\":2,\"n\":\"H0TX - Cloud Texture Layer #24\"},{\"t\":2,\"n\":\"I0TX - Cloud Texture Layer #25\"},{\"t\":2,\"n\":\"J0TX - Cloud Texture Layer #26\"},{\"t\":2,\"n\":\"K0TX - Cloud Texture Layer #27\"},{\"t\":2,\"n\":\"L0TX - Cloud Texture Layer #28\"},{\"t\":11,\"n\":\"DNAM - Unused\"},{\"t\":11,\"n\":\"CNAM - Unused\"},{\"t\":11,\"n\":\"ANAM - Unused\"},{\"t\":11,\"n\":\"BNAM - Unused\"},{\"t\":11,\"n\":\"LNAM - Unknown\"},{\"t\":3,\"n\":\"MNAM - Precipitation Type\"},{\"t\":3,\"n\":\"NNAM - Visual Effect\"},{\"t\":11,\"n\":\"ONAM - Unused\"},{\"t\":6,\"n\":\"Cloud Speed\",\"c\":[{\"t\":7,\"n\":\"RNAM - Y Speed\",\"c\":[{\"t\":3,\"n\":\"Layer #0\"}]}]},{\"t\":8,\"n\":\"PNAM - Cloud Colors\",\"c\":[{\"t\":6,\"n\":\"Layer #0\",\"c\":[{\"t\":8,\"n\":\"Colors\",\"c\":[{\"t\":6,\"n\":\"Time #0 (Sunrise)\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":6,\"n\":\"Time #1 (Day)\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":6,\"n\":\"Time #2 (Sunset)\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":6,\"n\":\"Time #3 (Night)\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unknown\"}]}]}]}]},{\"t\":8,\"n\":\"JNAM - Cloud Alphas\",\"c\":[{\"t\":6,\"n\":\"Layer #0\",\"c\":[{\"t\":5,\"n\":\"Sunrise\"},{\"t\":5,\"n\":\"Day\"},{\"t\":5,\"n\":\"Sunset\"},{\"t\":5,\"n\":\"Night\"}]}]},{\"t\":6,\"n\":\"NAM0 - Weather Colors\",\"c\":[{\"t\":8,\"n\":\"Sky-Upper\",\"c\":[{\"t\":6,\"n\":\"Color #0 (Sunrise)\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":6,\"n\":\"Color #1 (Day)\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":6,\"n\":\"Color #2 (Sunset)\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":6,\"n\":\"Color #3 (Night)\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unknown\"}]}]},{\"t\":8,\"n\":\"Fog Near\",\"c\":[{\"t\":6,\"n\":\"Color #0 (Sunrise)\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":6,\"n\":\"Color #1 (Day)\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":6,\"n\":\"Color #2 (Sunset)\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":6,\"n\":\"Color #3 (Night)\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unknown\"}]}]},{\"t\":8,\"n\":\"Unknown\",\"c\":[{\"t\":6,\"n\":\"Color #0 (Sunrise)\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":6,\"n\":\"Color #1 (Day)\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":6,\"n\":\"Color #2 (Sunset)\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":6,\"n\":\"Color #3 (Night)\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unknown\"}]}]},{\"t\":8,\"n\":\"Ambient\",\"c\":[{\"t\":6,\"n\":\"Color #0 (Sunrise)\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":6,\"n\":\"Color #1 (Day)\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":6,\"n\":\"Color #2 (Sunset)\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":6,\"n\":\"Color #3 (Night)\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unknown\"}]}]},{\"t\":8,\"n\":\"Sunlight\",\"c\":[{\"t\":6,\"n\":\"Color #0 (Sunrise)\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":6,\"n\":\"Color #1 (Day)\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":6,\"n\":\"Color #2 (Sunset)\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":6,\"n\":\"Color #3 (Night)\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unknown\"}]}]},{\"t\":8,\"n\":\"Sun\",\"c\":[{\"t\":6,\"n\":\"Color #0 (Sunrise)\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":6,\"n\":\"Color #1 (Day)\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":6,\"n\":\"Color #2 (Sunset)\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":6,\"n\":\"Color #3 (Night)\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unknown\"}]}]},{\"t\":8,\"n\":\"Stars\",\"c\":[{\"t\":6,\"n\":\"Color #0 (Sunrise)\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":6,\"n\":\"Color #1 (Day)\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":6,\"n\":\"Color #2 (Sunset)\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":6,\"n\":\"Color #3 (Night)\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unknown\"}]}]},{\"t\":8,\"n\":\"Sky-Lower\",\"c\":[{\"t\":6,\"n\":\"Color #0 (Sunrise)\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":6,\"n\":\"Color #1 (Day)\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":6,\"n\":\"Color #2 (Sunset)\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":6,\"n\":\"Color #3 (Night)\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unknown\"}]}]},{\"t\":8,\"n\":\"Horizon\",\"c\":[{\"t\":6,\"n\":\"Color #0 (Sunrise)\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":6,\"n\":\"Color #1 (Day)\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":6,\"n\":\"Color #2 (Sunset)\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":6,\"n\":\"Color #3 (Night)\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unknown\"}]}]},{\"t\":8,\"n\":\"Effect Lighting\",\"c\":[{\"t\":6,\"n\":\"Color #0 (Sunrise)\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":6,\"n\":\"Color #1 (Day)\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":6,\"n\":\"Color #2 (Sunset)\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":6,\"n\":\"Color #3 (Night)\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unknown\"}]}]},{\"t\":8,\"n\":\"Cloud LOD Diffuse\",\"c\":[{\"t\":6,\"n\":\"Color #0 (Sunrise)\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":6,\"n\":\"Color #1 (Day)\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":6,\"n\":\"Color #2 (Sunset)\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":6,\"n\":\"Color #3 (Night)\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unknown\"}]}]},{\"t\":8,\"n\":\"Cloud LOD Ambient\",\"c\":[{\"t\":6,\"n\":\"Color #0 (Sunrise)\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":6,\"n\":\"Color #1 (Day)\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":6,\"n\":\"Color #2 (Sunset)\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":6,\"n\":\"Color #3 (Night)\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unknown\"}]}]},{\"t\":8,\"n\":\"Fog Far\",\"c\":[{\"t\":6,\"n\":\"Color #0 (Sunrise)\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":6,\"n\":\"Color #1 (Day)\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":6,\"n\":\"Color #2 (Sunset)\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":6,\"n\":\"Color #3 (Night)\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unknown\"}]}]},{\"t\":8,\"n\":\"Sky Statics\",\"c\":[{\"t\":6,\"n\":\"Color #0 (Sunrise)\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":6,\"n\":\"Color #1 (Day)\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":6,\"n\":\"Color #2 (Sunset)\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":6,\"n\":\"Color #3 (Night)\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unknown\"}]}]},{\"t\":8,\"n\":\"Water Multiplier\",\"c\":[{\"t\":6,\"n\":\"Color #0 (Sunrise)\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":6,\"n\":\"Color #1 (Day)\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":6,\"n\":\"Color #2 (Sunset)\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":6,\"n\":\"Color #3 (Night)\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unknown\"}]}]},{\"t\":8,\"n\":\"Sun Glare\",\"c\":[{\"t\":6,\"n\":\"Color #0 (Sunrise)\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":6,\"n\":\"Color #1 (Day)\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":6,\"n\":\"Color #2 (Sunset)\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":6,\"n\":\"Color #3 (Night)\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unknown\"}]}]},{\"t\":8,\"n\":\"Moon Glare\",\"c\":[{\"t\":6,\"n\":\"Color #0 (Sunrise)\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":6,\"n\":\"Color #1 (Day)\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":6,\"n\":\"Color #2 (Sunset)\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":6,\"n\":\"Color #3 (Night)\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unknown\"}]}]}]},{\"t\":6,\"n\":\"FNAM - Fog Distance\",\"c\":[{\"t\":5,\"n\":\"Day - Near\"},{\"t\":5,\"n\":\"Day - Far\"},{\"t\":5,\"n\":\"Night - Near\"},{\"t\":5,\"n\":\"Night - Far\"},{\"t\":5,\"n\":\"Day - Power\"},{\"t\":5,\"n\":\"Night - Power\"},{\"t\":5,\"n\":\"Day - Max\"},{\"t\":5,\"n\":\"Night - Max\"}]},{\"t\":6,\"n\":\"DATA - Data\",\"c\":[{\"t\":3,\"n\":\"Wind Speed\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":3,\"n\":\"Trans Delta\"},{\"t\":3,\"n\":\"Sun Glare\"},{\"t\":3,\"n\":\"Sun Damage\"},{\"t\":3,\"n\":\"Precipitation - Begin Fade In\"},{\"t\":3,\"n\":\"Precipitation - End Fade Out\"},{\"t\":3,\"n\":\"Thunder\\/Lightning - Begin Fade In\"},{\"t\":3,\"n\":\"Thunder\\/Lightning - End Fade Out\"},{\"t\":3,\"n\":\"Thunder\\/Lightning - Frequency\"},{\"t\":3,\"n\":\"Flags\"},{\"t\":6,\"n\":\"Lightning Color\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"}]},{\"t\":3,\"n\":\"Visual Effect - Begin\"},{\"t\":3,\"n\":\"Visual Effect - End\"},{\"t\":3,\"n\":\"Wind Direction\"},{\"t\":3,\"n\":\"Wind Direction Range\"}]},{\"t\":3,\"n\":\"NAM1 - Disabled Cloud Layers\"},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Sounds\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"SNAM - Sound\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Sound\"},{\"t\":3,\"p\":1,\"n\":\"Type\"}]}]},{\"t\":9,\"n\":\"Sky Statics\",\"c\":[{\"t\":3,\"n\":\"TNAM - Static\"}]},{\"t\":6,\"n\":\"IMSP - Image Spaces\",\"c\":[{\"t\":3,\"n\":\"Sunrise\"},{\"t\":3,\"n\":\"Day\"},{\"t\":3,\"n\":\"Sunset\"},{\"t\":3,\"n\":\"Night\"}]},{\"t\":8,\"n\":\"Directional Ambient Lighting Colors\",\"c\":[{\"t\":6,\"n\":\"DALC - Sunrise\\/Day\\/Sunset\\/Night Order\",\"c\":[{\"t\":6,\"n\":\"Ambient Colors\",\"c\":[{\"t\":8,\"n\":\"Colors\",\"c\":[{\"t\":6,\"n\":\"Color #0 (X+)\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":6,\"n\":\"Color #1 (X-)\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":6,\"n\":\"Color #2 (Y+)\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":6,\"n\":\"Color #3 (Y-)\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":6,\"n\":\"Color #4 (Z+)\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":6,\"n\":\"Color #5 (Z-)\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unknown\"}]}]},{\"t\":6,\"n\":\"Specular\",\"c\":[{\"t\":6,\"n\":\"Color\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":5,\"n\":\"Fresnel Power\"}]}]}]}]},{\"t\":11,\"n\":\"NAM2 - Unused\"},{\"t\":11,\"n\":\"NAM3 - Unused\"},{\"t\":6,\"n\":\"Aurora\",\"c\":[{\"t\":6,\"n\":\"Model\",\"c\":[{\"t\":2,\"n\":\"MODL - Model Filename\"}]}]}]},{\"t\":1,\"p\":1,\"n\":\"ACTI - Activator\",\"c\":[{\"t\":6,\"n\":\"Record Header\",\"c\":[{\"t\":2,\"n\":\"Signature\"},{\"t\":3,\"n\":\"Data Size\"},{\"t\":3,\"n\":\"Record Flags\"},{\"t\":3,\"n\":\"FormID\"},{\"t\":11,\"n\":\"Version Control Info 1\"},{\"t\":3,\"n\":\"Form Version\"},{\"t\":11,\"n\":\"Version Control Info 2\"}]},{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"n\":\"VMAD - Virtual Machine Adapter\",\"c\":[{\"t\":3,\"n\":\"Version\"},{\"t\":3,\"n\":\"Object Format\"},{\"t\":12,\"n\":\"Data\",\"c\":[{\"t\":9,\"n\":\"Scripts\",\"c\":[{\"t\":6,\"n\":\"Script\",\"c\":[{\"t\":2,\"n\":\"scriptName\"},{\"t\":3,\"n\":\"Flags\"},{\"t\":9,\"n\":\"Properties\",\"c\":[{\"t\":6,\"n\":\"Property\",\"c\":[{\"t\":2,\"n\":\"propertyName\"},{\"t\":3,\"n\":\"Type\"},{\"t\":3,\"n\":\"Flags\"},{\"t\":12,\"n\":\"Value\"}]}]}]}]}]}]},{\"t\":6,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"n\":\"X1\"},{\"t\":3,\"n\":\"Y1\"},{\"t\":3,\"n\":\"Z1\"},{\"t\":3,\"n\":\"X2\"},{\"t\":3,\"n\":\"Y2\"},{\"t\":3,\"n\":\"Z2\"}]},{\"t\":2,\"n\":\"FULL - Name\"},{\"t\":6,\"n\":\"Model\",\"c\":[{\"t\":2,\"n\":\"MODL - Model Filename\"}]},{\"t\":6,\"n\":\"Destructable\",\"c\":[{\"t\":6,\"n\":\"DEST - Header\",\"c\":[{\"t\":3,\"n\":\"Health\"},{\"t\":3,\"n\":\"DEST Count\"},{\"t\":3,\"n\":\"VATS Targetable\"},{\"t\":11,\"n\":\"Unknown\"}]}]},{\"t\":3,\"n\":\"KSIZ - Keyword Count\"},{\"t\":9,\"n\":\"KWDA - Keywords\",\"c\":[{\"t\":3,\"n\":\"Keyword\"}]},{\"t\":6,\"n\":\"PNAM - Marker Color\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":3,\"n\":\"Unused\"}]},{\"t\":3,\"p\":1,\"n\":\"SNAM - Sound - Looping\"},{\"t\":3,\"p\":1,\"n\":\"VNAM - Sound - Activation\"},{\"t\":3,\"n\":\"WNAM - Water Type\"},{\"t\":2,\"n\":\"RNAM - Activate Text Override\"},{\"t\":3,\"n\":\"FNAM - Flags\"},{\"t\":3,\"n\":\"KNAM - Interaction Keyword\"}]}]},\"name\":\"Bash.Sound\",\"hash\":\"9FC91972\",\"color\":255}"
  },
  {
    "path": "frontend/settings/Skyrim/Bash.SpellStats.json",
    "content": "{\"records\":\"SPEL\",\"description\":\"SpellStats tag from Wrye Bash.\\r\\n\\r\\nUsed when the mod modifies spell stats.\",\"tree\":{\"records\":[{\"t\":1,\"p\":1,\"n\":\"SPEL - Spell\",\"c\":[{\"t\":6,\"n\":\"Record Header\",\"c\":[{\"t\":2,\"n\":\"Signature\"},{\"t\":3,\"n\":\"Data Size\"},{\"t\":3,\"n\":\"Record Flags\"},{\"t\":3,\"n\":\"FormID\"},{\"t\":11,\"n\":\"Version Control Info 1\"},{\"t\":3,\"n\":\"Form Version\"},{\"t\":11,\"n\":\"Version Control Info 2\"}]},{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"n\":\"X1\"},{\"t\":3,\"n\":\"Y1\"},{\"t\":3,\"n\":\"Z1\"},{\"t\":3,\"n\":\"X2\"},{\"t\":3,\"n\":\"Y2\"},{\"t\":3,\"n\":\"Z2\"}]},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":3,\"n\":\"KSIZ - Keyword Count\"},{\"t\":9,\"n\":\"KWDA - Keywords\",\"c\":[{\"t\":3,\"n\":\"Keyword\"}]},{\"t\":3,\"n\":\"MDOB - Menu Display Object\"},{\"t\":3,\"n\":\"ETYP - Equipment Type\"},{\"t\":2,\"n\":\"DESC - Description\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"SPIT - Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Base Cost\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":5,\"p\":1,\"n\":\"Charge Time\"},{\"t\":3,\"p\":1,\"n\":\"Cast Type\"},{\"t\":3,\"p\":1,\"n\":\"Target Type\"},{\"t\":5,\"p\":1,\"n\":\"Cast Duration\"},{\"t\":5,\"p\":1,\"n\":\"Range\"},{\"t\":3,\"p\":1,\"n\":\"Half-cost Perk\"}]},{\"t\":8,\"n\":\"Effects\",\"c\":[{\"t\":6,\"n\":\"Effect\",\"c\":[{\"t\":3,\"n\":\"EFID - Base Effect\"},{\"t\":6,\"n\":\"EFIT - \",\"c\":[{\"t\":5,\"n\":\"Magnitude\"},{\"t\":3,\"n\":\"Area\"},{\"t\":3,\"n\":\"Duration\"}]}]}]}]}]},\"name\":\"Bash.SpellStats\",\"hash\":\"$33DCE408\",\"color\":255}"
  },
  {
    "path": "frontend/settings/Skyrim/Bash.Stats.json",
    "content": "{\"records\":\"AMMO,APPA,ARMO,BOOK,INGR,KEYM,MISC,PROJ,WEAP,ALCH\",\"description\":\"Stats tag from Wrye Bash.\\r\\n\\r\\nUsed when the mod modifies item stats.\",\"tree\":{\"records\":[{\"t\":1,\"p\":1,\"n\":\"AMMO - Ammunition\",\"c\":[{\"t\":6,\"n\":\"Record Header\",\"c\":[{\"t\":2,\"n\":\"Signature\"},{\"t\":3,\"n\":\"Data Size\"},{\"t\":3,\"n\":\"Record Flags\"},{\"t\":3,\"n\":\"FormID\"},{\"t\":11,\"n\":\"Version Control Info 1\"},{\"t\":3,\"n\":\"Form Version\"},{\"t\":11,\"n\":\"Version Control Info 2\"}]},{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"n\":\"X1\"},{\"t\":3,\"n\":\"Y1\"},{\"t\":3,\"n\":\"Z1\"},{\"t\":3,\"n\":\"X2\"},{\"t\":3,\"n\":\"Y2\"},{\"t\":3,\"n\":\"Z2\"}]},{\"t\":2,\"n\":\"FULL - Name\"},{\"t\":6,\"n\":\"Model\",\"c\":[{\"t\":2,\"n\":\"MODL - Model Filename\"}]},{\"t\":6,\"n\":\"Icon\",\"c\":[{\"t\":2,\"n\":\"ICON - Large Icon filename\"}]},{\"t\":6,\"n\":\"Destructable\",\"c\":[{\"t\":6,\"n\":\"DEST - Header\",\"c\":[{\"t\":3,\"n\":\"Health\"},{\"t\":3,\"n\":\"DEST Count\"},{\"t\":3,\"n\":\"VATS Targetable\"},{\"t\":11,\"n\":\"Unknown\"}]}]},{\"t\":3,\"n\":\"YNAM - Sound - Pick Up\"},{\"t\":3,\"n\":\"ZNAM - Sound - Drop\"},{\"t\":2,\"n\":\"DESC - Description\"},{\"t\":3,\"n\":\"KSIZ - Keyword Count\"},{\"t\":9,\"n\":\"KWDA - Keywords\",\"c\":[{\"t\":3,\"n\":\"Keyword\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DATA - Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Projectile\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":5,\"p\":1,\"n\":\"Damage\"},{\"t\":3,\"p\":1,\"n\":\"Value\"}]},{\"t\":2,\"n\":\"ONAM - Short Name\"}]},{\"t\":1,\"p\":1,\"n\":\"APPA - Alchemical Apparatus\",\"c\":[{\"t\":6,\"n\":\"Record Header\",\"c\":[{\"t\":2,\"n\":\"Signature\"},{\"t\":3,\"n\":\"Data Size\"},{\"t\":3,\"n\":\"Record Flags\"},{\"t\":3,\"n\":\"FormID\"},{\"t\":11,\"n\":\"Version Control Info 1\"},{\"t\":3,\"n\":\"Form Version\"},{\"t\":11,\"n\":\"Version Control Info 2\"}]},{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"n\":\"VMAD - Virtual Machine Adapter\",\"c\":[{\"t\":3,\"n\":\"Version\"},{\"t\":3,\"n\":\"Object Format\"},{\"t\":12,\"n\":\"Data\",\"c\":[{\"t\":9,\"n\":\"Scripts\",\"c\":[{\"t\":6,\"n\":\"Script\",\"c\":[{\"t\":2,\"n\":\"scriptName\"},{\"t\":3,\"n\":\"Flags\"},{\"t\":9,\"n\":\"Properties\",\"c\":[{\"t\":6,\"n\":\"Property\",\"c\":[{\"t\":2,\"n\":\"propertyName\"},{\"t\":3,\"n\":\"Type\"},{\"t\":3,\"n\":\"Flags\"},{\"t\":12,\"n\":\"Value\"}]}]}]}]}]}]},{\"t\":6,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"n\":\"X1\"},{\"t\":3,\"n\":\"Y1\"},{\"t\":3,\"n\":\"Z1\"},{\"t\":3,\"n\":\"X2\"},{\"t\":3,\"n\":\"Y2\"},{\"t\":3,\"n\":\"Z2\"}]},{\"t\":2,\"n\":\"FULL - Name\"},{\"t\":6,\"n\":\"Model\",\"c\":[{\"t\":2,\"n\":\"MODL - Model Filename\"}]},{\"t\":6,\"n\":\"Icon\",\"c\":[{\"t\":2,\"n\":\"ICON - Large Icon filename\"}]},{\"t\":6,\"n\":\"Destructable\",\"c\":[{\"t\":6,\"n\":\"DEST - Header\",\"c\":[{\"t\":3,\"n\":\"Health\"},{\"t\":3,\"n\":\"DEST Count\"},{\"t\":3,\"n\":\"VATS Targetable\"},{\"t\":11,\"n\":\"Unknown\"}]}]},{\"t\":3,\"n\":\"YNAM - Sound - Pick Up\"},{\"t\":3,\"n\":\"ZNAM - Sound - Drop\"},{\"t\":3,\"n\":\"QUAL - Quality\"},{\"t\":2,\"n\":\"DESC - Description\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DATA - Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Value\"},{\"t\":5,\"p\":1,\"n\":\"Weight\"}]}]},{\"t\":1,\"p\":1,\"n\":\"ARMO - Armor\",\"c\":[{\"t\":6,\"n\":\"Record Header\",\"c\":[{\"t\":2,\"n\":\"Signature\"},{\"t\":3,\"n\":\"Data Size\"},{\"t\":3,\"n\":\"Record Flags\"},{\"t\":3,\"n\":\"FormID\"},{\"t\":11,\"n\":\"Version Control Info 1\"},{\"t\":3,\"n\":\"Form Version\"},{\"t\":11,\"n\":\"Version Control Info 2\"}]},{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"n\":\"VMAD - Virtual Machine Adapter\",\"c\":[{\"t\":3,\"n\":\"Version\"},{\"t\":3,\"n\":\"Object Format\"},{\"t\":12,\"n\":\"Data\",\"c\":[{\"t\":9,\"n\":\"Scripts\",\"c\":[{\"t\":6,\"n\":\"Script\",\"c\":[{\"t\":2,\"n\":\"scriptName\"},{\"t\":3,\"n\":\"Flags\"},{\"t\":9,\"n\":\"Properties\",\"c\":[{\"t\":6,\"n\":\"Property\",\"c\":[{\"t\":2,\"n\":\"propertyName\"},{\"t\":3,\"n\":\"Type\"},{\"t\":3,\"n\":\"Flags\"},{\"t\":12,\"n\":\"Value\"}]}]}]}]}]}]},{\"t\":6,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"n\":\"X1\"},{\"t\":3,\"n\":\"Y1\"},{\"t\":3,\"n\":\"Z1\"},{\"t\":3,\"n\":\"X2\"},{\"t\":3,\"n\":\"Y2\"},{\"t\":3,\"n\":\"Z2\"}]},{\"t\":2,\"n\":\"FULL - Name\"},{\"t\":3,\"n\":\"EITM - Object Effect\"},{\"t\":3,\"n\":\"EAMT - Enchantment Amount\"},{\"t\":6,\"n\":\"Male world model\",\"c\":[{\"t\":2,\"n\":\"MOD2 - Model Filename\"}]},{\"t\":6,\"n\":\"Icon\",\"c\":[{\"t\":2,\"n\":\"ICON - Large Icon filename\"}]},{\"t\":6,\"n\":\"Female world model\",\"c\":[{\"t\":2,\"n\":\"MOD4 - Model Filename\"}]},{\"t\":6,\"n\":\"Icon 2 (female)\",\"c\":[{\"t\":2,\"n\":\"ICO2 - Large Icon filename\"}]},{\"t\":6,\"n\":\"BOD2 - Biped Body Template\",\"c\":[{\"t\":3,\"n\":\"First Person Flags\"},{\"t\":3,\"n\":\"General Flags\"},{\"n\":\"Unused\"},{\"t\":3,\"n\":\"Armor Type\"}]},{\"t\":6,\"n\":\"Destructable\",\"c\":[{\"t\":6,\"n\":\"DEST - Header\",\"c\":[{\"t\":3,\"n\":\"Health\"},{\"t\":3,\"n\":\"DEST Count\"},{\"t\":3,\"n\":\"VATS Targetable\"},{\"t\":11,\"n\":\"Unknown\"}]}]},{\"t\":3,\"n\":\"YNAM - Sound - Pick Up\"},{\"t\":3,\"n\":\"ZNAM - Sound - Drop\"},{\"t\":2,\"n\":\"BMCT - Ragdoll Constraint Template\"},{\"t\":3,\"n\":\"ETYP - Equipment Type\"},{\"t\":3,\"n\":\"BIDS - Bash Impact Data Set\"},{\"t\":3,\"n\":\"BAMT - Alternate Block Material\"},{\"t\":3,\"n\":\"RNAM - Race\"},{\"t\":3,\"n\":\"KSIZ - Keyword Count\"},{\"t\":9,\"n\":\"KWDA - Keywords\",\"c\":[{\"t\":3,\"n\":\"Keyword\"}]},{\"t\":2,\"n\":\"DESC - Description\"},{\"t\":7,\"n\":\"Armature\",\"c\":[{\"t\":3,\"n\":\"MODL - Model Filename\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DATA - Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Value\"},{\"t\":5,\"p\":1,\"n\":\"Weight\"}]},{\"t\":3,\"n\":\"DNAM - Armor Rating\",\"p\":1},{\"t\":3,\"n\":\"TNAM - Template Armor\"}]},{\"t\":1,\"p\":1,\"n\":\"BOOK - Book\",\"c\":[{\"t\":6,\"n\":\"Record Header\",\"c\":[{\"t\":2,\"n\":\"Signature\"},{\"t\":3,\"n\":\"Data Size\"},{\"t\":3,\"n\":\"Record Flags\"},{\"t\":3,\"n\":\"FormID\"},{\"t\":11,\"n\":\"Version Control Info 1\"},{\"t\":3,\"n\":\"Form Version\"},{\"t\":11,\"n\":\"Version Control Info 2\"}]},{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"n\":\"VMAD - Virtual Machine Adapter\",\"c\":[{\"t\":3,\"n\":\"Version\"},{\"t\":3,\"n\":\"Object Format\"},{\"t\":12,\"n\":\"Data\",\"c\":[{\"t\":9,\"n\":\"Scripts\",\"c\":[{\"t\":6,\"n\":\"Script\",\"c\":[{\"t\":2,\"n\":\"scriptName\"},{\"t\":3,\"n\":\"Flags\"},{\"t\":9,\"n\":\"Properties\",\"c\":[{\"t\":6,\"n\":\"Property\",\"c\":[{\"t\":2,\"n\":\"propertyName\"},{\"t\":3,\"n\":\"Type\"},{\"t\":3,\"n\":\"Flags\"},{\"t\":12,\"n\":\"Value\"}]}]}]}]}]}]},{\"t\":6,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"n\":\"X1\"},{\"t\":3,\"n\":\"Y1\"},{\"t\":3,\"n\":\"Z1\"},{\"t\":3,\"n\":\"X2\"},{\"t\":3,\"n\":\"Y2\"},{\"t\":3,\"n\":\"Z2\"}]},{\"t\":2,\"n\":\"FULL - Name\"},{\"t\":6,\"n\":\"Model\",\"c\":[{\"t\":2,\"n\":\"MODL - Model Filename\"}]},{\"t\":6,\"n\":\"Icon\",\"c\":[{\"t\":2,\"n\":\"ICON - Large Icon filename\"}]},{\"t\":2,\"n\":\"DESC - Book Text\"},{\"t\":6,\"n\":\"Destructable\",\"c\":[{\"t\":6,\"n\":\"DEST - Header\",\"c\":[{\"t\":3,\"n\":\"Health\"},{\"t\":3,\"n\":\"DEST Count\"},{\"t\":3,\"n\":\"VATS Targetable\"},{\"t\":11,\"n\":\"Unknown\"}]}]},{\"t\":3,\"n\":\"YNAM - Sound - Pick Up\"},{\"t\":3,\"n\":\"ZNAM - Sound - Drop\"},{\"t\":3,\"n\":\"KSIZ - Keyword Count\"},{\"t\":9,\"n\":\"KWDA - Keywords\",\"c\":[{\"t\":3,\"n\":\"Keyword\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DATA - Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":11,\"p\":1,\"n\":\"Unused\"},{\"t\":12,\"p\":1,\"n\":\"Teaches\"},{\"t\":3,\"p\":1,\"n\":\"Value\"},{\"t\":5,\"p\":1,\"n\":\"Weight\"}]},{\"t\":3,\"n\":\"INAM - Inventory Art\"},{\"t\":2,\"n\":\"CNAM - Description\"}]},{\"t\":1,\"p\":1,\"n\":\"INGR - Ingredient\",\"c\":[{\"t\":6,\"n\":\"Record Header\",\"c\":[{\"t\":2,\"n\":\"Signature\"},{\"t\":3,\"n\":\"Data Size\"},{\"t\":3,\"n\":\"Record Flags\"},{\"t\":3,\"n\":\"FormID\"},{\"t\":11,\"n\":\"Version Control Info 1\"},{\"t\":3,\"n\":\"Form Version\"},{\"t\":11,\"n\":\"Version Control Info 2\"}]},{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"n\":\"VMAD - Virtual Machine Adapter\",\"c\":[{\"t\":3,\"n\":\"Version\"},{\"t\":3,\"n\":\"Object Format\"},{\"t\":12,\"n\":\"Data\",\"c\":[{\"t\":9,\"n\":\"Scripts\",\"c\":[{\"t\":6,\"n\":\"Script\",\"c\":[{\"t\":2,\"n\":\"scriptName\"},{\"t\":3,\"n\":\"Flags\"},{\"t\":9,\"n\":\"Properties\",\"c\":[{\"t\":6,\"n\":\"Property\",\"c\":[{\"t\":2,\"n\":\"propertyName\"},{\"t\":3,\"n\":\"Type\"},{\"t\":3,\"n\":\"Flags\"},{\"t\":12,\"n\":\"Value\"}]}]}]}]}]}]},{\"t\":6,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"n\":\"X1\"},{\"t\":3,\"n\":\"Y1\"},{\"t\":3,\"n\":\"Z1\"},{\"t\":3,\"n\":\"X2\"},{\"t\":3,\"n\":\"Y2\"},{\"t\":3,\"n\":\"Z2\"}]},{\"t\":2,\"n\":\"FULL - Name\"},{\"t\":3,\"n\":\"KSIZ - Keyword Count\"},{\"t\":9,\"n\":\"KWDA - Keywords\",\"c\":[{\"t\":3,\"n\":\"Keyword\"}]},{\"t\":6,\"n\":\"Model\",\"c\":[{\"t\":2,\"n\":\"MODL - Model Filename\"}]},{\"t\":6,\"n\":\"Icon\",\"c\":[{\"t\":2,\"n\":\"ICON - Large Icon filename\"}]},{\"t\":6,\"n\":\"Destructable\",\"c\":[{\"t\":6,\"n\":\"DEST - Header\",\"c\":[{\"t\":3,\"n\":\"Health\"},{\"t\":3,\"n\":\"DEST Count\"},{\"t\":3,\"n\":\"VATS Targetable\"},{\"t\":11,\"n\":\"Unknown\"}]}]},{\"t\":3,\"n\":\"ETYP - Equipment Type\"},{\"t\":3,\"n\":\"YNAM - Sound - Pick Up\"},{\"t\":3,\"n\":\"ZNAM - Sound - Drop\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DATA - \",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Value\"},{\"t\":5,\"p\":1,\"n\":\"Weight\"}]},{\"t\":6,\"n\":\"ENIT - Effect Data\",\"c\":[{\"t\":3,\"n\":\"Ingredient Value\"},{\"t\":3,\"n\":\"Flags\"}]},{\"t\":8,\"n\":\"Effects\",\"c\":[{\"t\":6,\"n\":\"Effect\",\"c\":[{\"t\":3,\"n\":\"EFID - Base Effect\"},{\"t\":6,\"n\":\"EFIT - \",\"c\":[{\"t\":5,\"n\":\"Magnitude\"},{\"t\":3,\"n\":\"Area\"},{\"t\":3,\"n\":\"Duration\"}]}]}]}]},{\"t\":1,\"p\":1,\"n\":\"KEYM - Key\",\"c\":[{\"t\":6,\"n\":\"Record Header\",\"c\":[{\"t\":2,\"n\":\"Signature\"},{\"t\":3,\"n\":\"Data Size\"},{\"t\":3,\"n\":\"Record Flags\"},{\"t\":3,\"n\":\"FormID\"},{\"t\":11,\"n\":\"Version Control Info 1\"},{\"t\":3,\"n\":\"Form Version\"},{\"t\":11,\"n\":\"Version Control Info 2\"}]},{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"n\":\"VMAD - Virtual Machine Adapter\",\"c\":[{\"t\":3,\"n\":\"Version\"},{\"t\":3,\"n\":\"Object Format\"},{\"t\":12,\"n\":\"Data\",\"c\":[{\"t\":9,\"n\":\"Scripts\",\"c\":[{\"t\":6,\"n\":\"Script\",\"c\":[{\"t\":2,\"n\":\"scriptName\"},{\"t\":3,\"n\":\"Flags\"},{\"t\":9,\"n\":\"Properties\",\"c\":[{\"t\":6,\"n\":\"Property\",\"c\":[{\"t\":2,\"n\":\"propertyName\"},{\"t\":3,\"n\":\"Type\"},{\"t\":3,\"n\":\"Flags\"},{\"t\":12,\"n\":\"Value\"}]}]}]}]}]}]},{\"t\":6,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"n\":\"X1\"},{\"t\":3,\"n\":\"Y1\"},{\"t\":3,\"n\":\"Z1\"},{\"t\":3,\"n\":\"X2\"},{\"t\":3,\"n\":\"Y2\"},{\"t\":3,\"n\":\"Z2\"}]},{\"t\":2,\"n\":\"FULL - Name\"},{\"t\":6,\"n\":\"Model\",\"c\":[{\"t\":2,\"n\":\"MODL - Model Filename\"}]},{\"t\":6,\"n\":\"Icon\",\"c\":[{\"t\":2,\"n\":\"ICON - Large Icon filename\"}]},{\"t\":6,\"n\":\"Destructable\",\"c\":[{\"t\":6,\"n\":\"DEST - Header\",\"c\":[{\"t\":3,\"n\":\"Health\"},{\"t\":3,\"n\":\"DEST Count\"},{\"t\":3,\"n\":\"VATS Targetable\"},{\"t\":11,\"n\":\"Unknown\"}]}]},{\"t\":3,\"n\":\"YNAM - Sound - Pick Up\"},{\"t\":3,\"n\":\"ZNAM - Sound - Drop\"},{\"t\":3,\"n\":\"KSIZ - Keyword Count\"},{\"t\":9,\"n\":\"KWDA - Keywords\",\"c\":[{\"t\":3,\"n\":\"Keyword\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DATA - \",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Value\"},{\"t\":5,\"p\":1,\"n\":\"Weight\"}]}]},{\"t\":1,\"p\":1,\"n\":\"MISC - Misc. Item\",\"c\":[{\"t\":6,\"n\":\"Record Header\",\"c\":[{\"t\":2,\"n\":\"Signature\"},{\"t\":3,\"n\":\"Data Size\"},{\"t\":3,\"n\":\"Record Flags\"},{\"t\":3,\"n\":\"FormID\"},{\"t\":11,\"n\":\"Version Control Info 1\"},{\"t\":3,\"n\":\"Form Version\"},{\"t\":11,\"n\":\"Version Control Info 2\"}]},{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"n\":\"VMAD - Virtual Machine Adapter\",\"c\":[{\"t\":3,\"n\":\"Version\"},{\"t\":3,\"n\":\"Object Format\"},{\"t\":12,\"n\":\"Data\",\"c\":[{\"t\":9,\"n\":\"Scripts\",\"c\":[{\"t\":6,\"n\":\"Script\",\"c\":[{\"t\":2,\"n\":\"scriptName\"},{\"t\":3,\"n\":\"Flags\"},{\"t\":9,\"n\":\"Properties\",\"c\":[{\"t\":6,\"n\":\"Property\",\"c\":[{\"t\":2,\"n\":\"propertyName\"},{\"t\":3,\"n\":\"Type\"},{\"t\":3,\"n\":\"Flags\"},{\"t\":12,\"n\":\"Value\"}]}]}]}]}]}]},{\"t\":6,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"n\":\"X1\"},{\"t\":3,\"n\":\"Y1\"},{\"t\":3,\"n\":\"Z1\"},{\"t\":3,\"n\":\"X2\"},{\"t\":3,\"n\":\"Y2\"},{\"t\":3,\"n\":\"Z2\"}]},{\"t\":2,\"n\":\"FULL - Name\"},{\"t\":6,\"n\":\"Model\",\"c\":[{\"t\":2,\"n\":\"MODL - Model Filename\"}]},{\"t\":6,\"n\":\"Icon\",\"c\":[{\"t\":2,\"n\":\"ICON - Large Icon filename\"}]},{\"t\":6,\"n\":\"Destructable\",\"c\":[{\"t\":6,\"n\":\"DEST - Header\",\"c\":[{\"t\":3,\"n\":\"Health\"},{\"t\":3,\"n\":\"DEST Count\"},{\"t\":3,\"n\":\"VATS Targetable\"},{\"t\":11,\"n\":\"Unknown\"}]}]},{\"t\":3,\"n\":\"YNAM - Sound - Pick Up\"},{\"t\":3,\"n\":\"ZNAM - Sound - Drop\"},{\"t\":3,\"n\":\"KSIZ - Keyword Count\"},{\"t\":9,\"n\":\"KWDA - Keywords\",\"c\":[{\"t\":3,\"n\":\"Keyword\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DATA - Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Value\"},{\"t\":5,\"p\":1,\"n\":\"Weight\"}]}]},{\"t\":1,\"p\":1,\"n\":\"PROJ - Projectile\",\"c\":[{\"t\":6,\"n\":\"Record Header\",\"c\":[{\"t\":2,\"n\":\"Signature\"},{\"t\":3,\"n\":\"Data Size\"},{\"t\":3,\"n\":\"Record Flags\"},{\"t\":3,\"n\":\"FormID\"},{\"t\":11,\"n\":\"Version Control Info 1\"},{\"t\":3,\"n\":\"Form Version\"},{\"t\":11,\"n\":\"Version Control Info 2\"}]},{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"n\":\"X1\"},{\"t\":3,\"n\":\"Y1\"},{\"t\":3,\"n\":\"Z1\"},{\"t\":3,\"n\":\"X2\"},{\"t\":3,\"n\":\"Y2\"},{\"t\":3,\"n\":\"Z2\"}]},{\"t\":2,\"n\":\"FULL - Name\"},{\"t\":6,\"n\":\"Model\",\"c\":[{\"t\":2,\"n\":\"MODL - Model Filename\"}]},{\"t\":6,\"n\":\"Destructable\",\"c\":[{\"t\":6,\"n\":\"DEST - Header\",\"c\":[{\"t\":3,\"n\":\"Health\"},{\"t\":3,\"n\":\"DEST Count\"},{\"t\":3,\"n\":\"VATS Targetable\"},{\"t\":11,\"n\":\"Unknown\"}]}]},{\"t\":6,\"p\":1,\"n\":\"DATA - Data\",\"c\":[{\"t\":3,\"n\":\"Flags\"},{\"t\":3,\"n\":\"Type\"},{\"t\":5,\"p\":1,\"n\":\"Gravity\",\"lt\":\"Range\",\"lf\":\"Speed\"},{\"t\":5,\"p\":1,\"n\":\"Speed\",\"lt\":\"Gravity\",\"lf\":\"Range\"},{\"t\":5,\"p\":1,\"n\":\"Range\",\"lt\":\"Speed\",\"lf\":\"Gravity\"},{\"t\":3,\"n\":\"Light\"},{\"t\":3,\"n\":\"Muzzle Flash - Light\"},{\"t\":5,\"n\":\"Tracer Chance\"},{\"t\":5,\"n\":\"Explosion - Alt. Trigger - Proximity\"},{\"t\":5,\"n\":\"Explosion - Alt. Trigger - Timer\"},{\"t\":3,\"n\":\"Explosion\"},{\"t\":3,\"n\":\"Sound\"},{\"t\":5,\"n\":\"Muzzle Flash - Duration\"},{\"t\":5,\"n\":\"Fade Duration\"},{\"t\":5,\"n\":\"Impact Force\"},{\"t\":3,\"n\":\"Sound - Countdown\"},{\"t\":3,\"n\":\"Sound - Disable\"},{\"t\":3,\"n\":\"Default Weapon Source\"},{\"t\":5,\"n\":\"Cone Spread\"},{\"t\":5,\"n\":\"Collision Radius\"},{\"t\":5,\"n\":\"Lifetime\"},{\"t\":5,\"n\":\"Relaunch Interval\"},{\"t\":3,\"n\":\"Decal Data\"},{\"t\":3,\"n\":\"Collision Layer\"}]},{\"t\":6,\"n\":\"Muzzle Flash Model\",\"c\":[{\"t\":2,\"n\":\"NAM1 - Model Filename\"}]},{\"t\":3,\"n\":\"VNAM - Sound Level\"}]},{\"t\":1,\"p\":1,\"n\":\"WEAP - Weapon\",\"c\":[{\"t\":6,\"n\":\"Record Header\",\"c\":[{\"t\":2,\"n\":\"Signature\"},{\"t\":3,\"n\":\"Data Size\"},{\"t\":3,\"n\":\"Record Flags\"},{\"t\":3,\"n\":\"FormID\"},{\"t\":11,\"n\":\"Version Control Info 1\"},{\"t\":3,\"n\":\"Form Version\"},{\"t\":11,\"n\":\"Version Control Info 2\"}]},{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"n\":\"VMAD - Virtual Machine Adapter\",\"c\":[{\"t\":3,\"n\":\"Version\"},{\"t\":3,\"n\":\"Object Format\"},{\"t\":12,\"n\":\"Data\",\"c\":[{\"t\":9,\"n\":\"Scripts\",\"c\":[{\"t\":6,\"n\":\"Script\",\"c\":[{\"t\":2,\"n\":\"scriptName\"},{\"t\":3,\"n\":\"Flags\"},{\"t\":9,\"n\":\"Properties\",\"c\":[{\"t\":6,\"n\":\"Property\",\"c\":[{\"t\":2,\"n\":\"propertyName\"},{\"t\":3,\"n\":\"Type\"},{\"t\":3,\"n\":\"Flags\"},{\"t\":12,\"n\":\"Value\"}]}]}]}]}]}]},{\"t\":6,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"n\":\"X1\"},{\"t\":3,\"n\":\"Y1\"},{\"t\":3,\"n\":\"Z1\"},{\"t\":3,\"n\":\"X2\"},{\"t\":3,\"n\":\"Y2\"},{\"t\":3,\"n\":\"Z2\"}]},{\"t\":2,\"n\":\"FULL - Name\"},{\"t\":6,\"n\":\"Model\",\"c\":[{\"t\":2,\"n\":\"MODL - Model Filename\"}]},{\"t\":6,\"n\":\"Icon\",\"c\":[{\"t\":2,\"n\":\"ICON - Large Icon filename\"}]},{\"t\":3,\"n\":\"EITM - Object Effect\"},{\"t\":3,\"n\":\"EAMT - Enchantment Amount\"},{\"t\":6,\"n\":\"Destructable\",\"c\":[{\"t\":6,\"n\":\"DEST - Header\",\"c\":[{\"t\":3,\"n\":\"Health\"},{\"t\":3,\"n\":\"DEST Count\"},{\"t\":3,\"n\":\"VATS Targetable\"},{\"t\":11,\"n\":\"Unknown\"}]}]},{\"t\":3,\"n\":\"ETYP - Equipment Type\"},{\"t\":3,\"n\":\"BIDS - Block Bash Impact Data Set\"},{\"t\":3,\"n\":\"BAMT - Alternate Block Material\"},{\"t\":3,\"n\":\"YNAM - Sound - Pick Up\"},{\"t\":3,\"n\":\"ZNAM - Sound - Drop\"},{\"t\":3,\"n\":\"KSIZ - Keyword Count\"},{\"t\":9,\"n\":\"KWDA - Keywords\",\"c\":[{\"t\":3,\"n\":\"Keyword\"}]},{\"t\":2,\"n\":\"DESC - Description\"},{\"t\":6,\"n\":\"Has Scope\",\"c\":[{\"t\":2,\"n\":\"MOD3 - Model Filename\"}]},{\"t\":11,\"n\":\"NNAM - Unused\"},{\"t\":3,\"n\":\"INAM - Impact Data Set\"},{\"t\":3,\"n\":\"WNAM - 1st Person Model Object\"},{\"t\":3,\"n\":\"SNAM - Attack Sound\"},{\"t\":3,\"n\":\"XNAM - Attack Sound 2D\"},{\"t\":3,\"n\":\"NAM7 - Attack Loop Sound\"},{\"t\":3,\"n\":\"TNAM - Attack Fail Sound\"},{\"t\":3,\"n\":\"UNAM - Idle Sound\"},{\"t\":3,\"n\":\"NAM9 - Equip Sound\"},{\"t\":3,\"n\":\"NAM8 - Unequip Sound\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DATA - Game Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Value\"},{\"t\":5,\"p\":1,\"n\":\"Weight\"},{\"t\":3,\"p\":1,\"n\":\"Damage\"}]},{\"t\":6,\"p\":1,\"n\":\"DNAM - Data\",\"c\":[{\"t\":3,\"n\":\"Animation Type\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":5,\"p\":1,\"n\":\"Speed\",\"lt\":\"Reach\",\"lf\":\"Stagger\"},{\"t\":5,\"p\":1,\"n\":\"Reach\",\"lt\":\"Resist\",\"lf\":\"Speed\"},{\"t\":3,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":5,\"n\":\"Sight FOV\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":3,\"n\":\"Base VATS To-Hit Chance\"},{\"t\":3,\"n\":\"Attack Animation\"},{\"t\":3,\"n\":\"# Projectiles\"},{\"t\":3,\"n\":\"Embedded Weapon AV (unused)\"},{\"t\":5,\"n\":\"Range Min\"},{\"t\":5,\"n\":\"Range Max\"},{\"t\":3,\"n\":\"On Hit\"},{\"t\":3,\"n\":\"Flags2\"},{\"t\":5,\"n\":\"Animation Attack Mult\"},{\"t\":5,\"n\":\"Unknown\"},{\"t\":5,\"n\":\"Rumble - Left Motor Strength\"},{\"t\":5,\"n\":\"Rumble - Right Motor Strength\"},{\"t\":5,\"n\":\"Rumble - Duration\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":3,\"n\":\"Skill\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":3,\"p\":1,\"n\":\"Resist\",\"lt\":\"Stagger\",\"lf\":\"Reach\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":5,\"p\":1,\"n\":\"Stagger\",\"lt\":\"Speed\",\"lf\":\"Resist\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"CRDT - Critical Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Damage\"},{\"t\":11,\"p\":1,\"n\":\"Unused\"},{\"t\":5,\"p\":1,\"n\":\"% Mult\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"p\":1,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Effect\"}]},{\"t\":3,\"n\":\"VNAM - Detection Sound Level\"},{\"t\":3,\"n\":\"CNAM - Template\"}]},{\"t\":1,\"p\":1,\"n\":\"ALCH - Ingestible\",\"c\":[{\"t\":6,\"n\":\"Record Header\",\"c\":[{\"t\":2,\"n\":\"Signature\"},{\"t\":3,\"n\":\"Data Size\"},{\"t\":3,\"n\":\"Record Flags\"},{\"t\":3,\"n\":\"FormID\"},{\"t\":11,\"n\":\"Version Control Info 1\"},{\"t\":3,\"n\":\"Form Version\"},{\"t\":11,\"n\":\"Version Control Info 2\"}]},{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"n\":\"X1\"},{\"t\":3,\"n\":\"Y1\"},{\"t\":3,\"n\":\"Z1\"},{\"t\":3,\"n\":\"X2\"},{\"t\":3,\"n\":\"Y2\"},{\"t\":3,\"n\":\"Z2\"}]},{\"t\":2,\"n\":\"FULL - Name\"},{\"t\":3,\"n\":\"KSIZ - Keyword Count\"},{\"t\":9,\"n\":\"KWDA - Keywords\",\"c\":[{\"t\":3,\"n\":\"Keyword\"}]},{\"t\":2,\"n\":\"DESC - Description\"},{\"t\":6,\"n\":\"Model\",\"c\":[{\"t\":2,\"n\":\"MODL - Model Filename\"}]},{\"t\":6,\"n\":\"Destructable\",\"c\":[{\"t\":6,\"n\":\"DEST - Header\",\"c\":[{\"t\":3,\"n\":\"Health\"},{\"t\":3,\"n\":\"DEST Count\"},{\"t\":3,\"n\":\"VATS Targetable\"},{\"t\":11,\"n\":\"Unknown\"}]}]},{\"t\":6,\"n\":\"Icon\",\"c\":[{\"t\":2,\"n\":\"ICON - Large Icon filename\"}]},{\"t\":3,\"n\":\"YNAM - Sound - Pick Up\"},{\"t\":3,\"n\":\"ZNAM - Sound - Drop\"},{\"t\":3,\"n\":\"ETYP - Equipment Type\"},{\"t\":5,\"p\":1,\"n\":\"DATA - Weight\"},{\"t\":6,\"n\":\"ENIT - Effect Data\",\"c\":[{\"t\":3,\"n\":\"Value\"},{\"t\":3,\"n\":\"Flags\"},{\"t\":3,\"n\":\"Addiction\"},{\"t\":5,\"n\":\"Addiction Chance\"},{\"t\":3,\"n\":\"Sound - Consume\"}]},{\"t\":8,\"n\":\"Effects\",\"c\":[{\"t\":6,\"n\":\"Effect\",\"c\":[{\"t\":3,\"n\":\"EFID - Base Effect\"},{\"t\":6,\"n\":\"EFIT - \",\"c\":[{\"t\":5,\"n\":\"Magnitude\"},{\"t\":3,\"n\":\"Area\"},{\"t\":3,\"n\":\"Duration\"}]}]}]}]}]},\"name\":\"Bash.Stats\",\"hash\":\"9BB78E19\",\"color\":255}"
  },
  {
    "path": "frontend/settings/Skyrim/Bash.Voice-F.json",
    "content": "{\"records\":\"RACE\",\"description\":\"Voice-F tag from Wrye Bash.\\r\\n\\r\\nUsed when the mod modifies female voice definitions.\",\"tree\":{\"records\":[{\"t\":1,\"p\":1,\"n\":\"RACE - Race\",\"c\":[{\"t\":6,\"n\":\"Record Header\",\"c\":[{\"t\":2,\"n\":\"Signature\"},{\"t\":3,\"n\":\"Data Size\"},{\"t\":3,\"n\":\"Record Flags\"},{\"t\":3,\"n\":\"FormID\"},{\"t\":11,\"n\":\"Version Control Info 1\"},{\"t\":3,\"n\":\"Form Version\"},{\"t\":11,\"n\":\"Version Control Info 2\"}]},{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"n\":\"FULL - Name\"},{\"t\":2,\"n\":\"DESC - Description\"},{\"t\":3,\"n\":\"SPCT - Count\"},{\"t\":9,\"n\":\"Actor Effects\",\"c\":[{\"t\":3,\"n\":\"SPLO - Actor Effect\"}]},{\"t\":3,\"n\":\"WNAM - Skin\"},{\"t\":6,\"n\":\"BOD2 - Biped Body Template\",\"c\":[{\"t\":3,\"n\":\"First Person Flags\"},{\"t\":3,\"n\":\"General Flags\"},{\"n\":\"Unused\"},{\"t\":3,\"n\":\"Armor Type\"}]},{\"t\":3,\"n\":\"KSIZ - Keyword Count\"},{\"t\":9,\"n\":\"KWDA - Keywords\",\"c\":[{\"t\":3,\"n\":\"Keyword\"}]},{\"t\":6,\"n\":\"DATA - \",\"c\":[{\"t\":10,\"n\":\"Skill Boosts\",\"c\":[{\"t\":6,\"n\":\"Skill Boost\",\"c\":[{\"t\":3,\"n\":\"Skill\"},{\"t\":3,\"n\":\"Boost\"}]},{\"t\":6,\"n\":\"Skill Boost\",\"c\":[{\"t\":3,\"n\":\"Skill\"},{\"t\":3,\"n\":\"Boost\"}]},{\"t\":6,\"n\":\"Skill Boost\",\"c\":[{\"t\":3,\"n\":\"Skill\"},{\"t\":3,\"n\":\"Boost\"}]},{\"t\":6,\"n\":\"Skill Boost\",\"c\":[{\"t\":3,\"n\":\"Skill\"},{\"t\":3,\"n\":\"Boost\"}]},{\"t\":6,\"n\":\"Skill Boost\",\"c\":[{\"t\":3,\"n\":\"Skill\"},{\"t\":3,\"n\":\"Boost\"}]},{\"t\":6,\"n\":\"Skill Boost\",\"c\":[{\"t\":3,\"n\":\"Skill\"},{\"t\":3,\"n\":\"Boost\"}]},{\"t\":6,\"n\":\"Skill Boost\",\"c\":[{\"t\":3,\"n\":\"Skill\"},{\"t\":3,\"n\":\"Boost\"}]}]},{\"t\":11,\"n\":\"Unknown\"},{\"t\":5,\"n\":\"Male Height\"},{\"t\":5,\"n\":\"Female Height\"},{\"t\":5,\"n\":\"Male Weight\"},{\"t\":5,\"n\":\"Female Weight\"},{\"t\":3,\"n\":\"Flags\"},{\"t\":5,\"n\":\"Starting Health\"},{\"t\":5,\"n\":\"Starting Magicka\"},{\"t\":5,\"n\":\"Starting Stamina\"},{\"t\":5,\"n\":\"Base Carry Weight\"},{\"t\":5,\"n\":\"Base Mass\"},{\"t\":5,\"n\":\"Acceleration rate\"},{\"t\":5,\"n\":\"Deceleration rate\"},{\"t\":3,\"n\":\"Size\"},{\"t\":3,\"n\":\"Head Biped Object\"},{\"t\":3,\"n\":\"Hair Biped Object\"},{\"t\":5,\"n\":\"Injured Health Pct\"},{\"t\":3,\"n\":\"Shield Biped Object\"},{\"t\":5,\"n\":\"Health Regen\"},{\"t\":5,\"n\":\"Magicka Regen\"},{\"t\":5,\"n\":\"Stamina Regen\"},{\"t\":5,\"n\":\"Unarmed Damage\"},{\"t\":5,\"n\":\"Unarmed Reach\"},{\"t\":3,\"n\":\"Body Biped Object\"},{\"t\":5,\"n\":\"Aim Angle Tolerance\"},{\"t\":5,\"n\":\"Flight Radius\"},{\"t\":5,\"n\":\"Angular Acceleration Rate\"},{\"t\":5,\"n\":\"Angular Tolerance\"},{\"t\":3,\"n\":\"Flags 2\"},{\"t\":6,\"n\":\"Mount Data\",\"c\":[{\"t\":5,\"n\":\"Offset X\"},{\"t\":5,\"n\":\"Offset Y\"},{\"t\":5,\"n\":\"Unknown\"},{\"t\":5,\"n\":\"Unknown\"},{\"t\":5,\"n\":\"Unknown\"},{\"t\":5,\"n\":\"Unknown\"},{\"t\":5,\"n\":\"Unknown\"},{\"t\":5,\"n\":\"Unknown\"},{\"t\":5,\"n\":\"Unknown\"}]}]},{\"n\":\"MNAM - Male Marker\"},{\"t\":2,\"n\":\"ANAM - Male Skeletal Model\"},{\"t\":11,\"n\":\"MODT - Texture Files Hashes\"},{\"n\":\"FNAM - Female Marker\"},{\"t\":2,\"n\":\"ANAM - Female Skeletal Model\"},{\"t\":11,\"n\":\"MODT - Texture Files Hashes\"},{\"n\":\"NAM2 - Marker NAM2 #1\"},{\"t\":9,\"n\":\"Movement Type Names\",\"c\":[{\"t\":2,\"n\":\"MTNM - Name\"}]},{\"t\":7,\"p\":1,\"n\":\"VTCK - Voices\",\"c\":[{\"t\":3,\"n\":\"Voice #0 (Male)\"},{\"t\":3,\"p\":1,\"n\":\"Voice #1 (Female)\"}]},{\"t\":7,\"n\":\"DNAM - Decapitate Armors\",\"c\":[{\"t\":3,\"n\":\"Decapitate Armor #0 (Male)\"},{\"t\":3,\"n\":\"Decapitate Armor #1 (Female)\"}]},{\"t\":7,\"n\":\"HCLF - Default Hair Colors\",\"c\":[{\"t\":3,\"n\":\"Default Hair Color #0 (Male)\"},{\"t\":3,\"n\":\"Default Hair Color #1 (Female)\"}]},{\"t\":3,\"n\":\"TINL - Total Number of Tints in List\"},{\"t\":5,\"n\":\"PNAM - FaceGen - Main clamp\"},{\"t\":5,\"n\":\"UNAM - FaceGen - Face clamp\"},{\"t\":3,\"n\":\"ATKR - Attack Race\"},{\"t\":10,\"n\":\"Attacks\",\"c\":[{\"t\":6,\"n\":\"Attack\",\"c\":[{\"t\":6,\"n\":\"ATKD - Attack Data\",\"c\":[{\"t\":5,\"n\":\"Damage Mult\"},{\"t\":5,\"n\":\"Attack Chance\"},{\"t\":3,\"n\":\"Attack Spell\"},{\"t\":3,\"n\":\"Attack Flags\"},{\"t\":5,\"n\":\"Attack Angle\"},{\"t\":5,\"n\":\"Strike Angle\"},{\"t\":5,\"n\":\"Stagger\"},{\"t\":3,\"n\":\"Attack Type\"},{\"t\":5,\"n\":\"Knockdown\"},{\"t\":5,\"n\":\"Recovery Time\"},{\"t\":5,\"n\":\"Stamina Mult\"}]}]}]},{\"t\":6,\"n\":\"Body Data\",\"c\":[{\"n\":\"NAM1 - Body Data Marker\"},{\"t\":6,\"n\":\"Male Body Data\",\"c\":[{\"n\":\"MNAM - Male Data Marker\"},{\"t\":10,\"n\":\"Parts\",\"c\":[{\"t\":6,\"n\":\"Part\",\"c\":[{\"t\":3,\"n\":\"INDX - Index\"}]}]}]},{\"t\":6,\"n\":\"Female Body Data\",\"c\":[{\"n\":\"FNAM - Female Data Marker\"},{\"t\":10,\"n\":\"Parts\",\"c\":[{\"t\":6,\"n\":\"Part\",\"c\":[{\"t\":3,\"n\":\"INDX - Index\"}]}]}]}]},{\"t\":9,\"n\":\"HNAM - Hairs\",\"c\":[{\"t\":3,\"n\":\"Hair\"}]},{\"t\":9,\"n\":\"ENAM - Eyes\",\"c\":[{\"t\":3,\"n\":\"Eye\"}]},{\"t\":3,\"n\":\"GNAM - Body Part Data\"},{\"n\":\"NAM2 - Marker NAM2 #2\"},{\"n\":\"NAM3 - Marker NAM3 #3\"},{\"t\":6,\"n\":\"Male Behavior Graph\",\"c\":[{\"n\":\"MNAM - Male Data Marker\"}]},{\"t\":6,\"n\":\"Female Behavior Graph\",\"c\":[{\"n\":\"FNAM - Female Data Marker\"}]},{\"t\":3,\"n\":\"NAM4 - Material Type\"},{\"t\":3,\"n\":\"NAM5 - Impact Data Set\"},{\"t\":3,\"n\":\"NAM7 - Decapitation FX\"},{\"t\":3,\"n\":\"ONAM - Open Loot Sound\"},{\"t\":3,\"n\":\"LNAM - Close Loot Sound\"},{\"t\":7,\"n\":\"Biped Object Names\",\"c\":[{\"t\":2,\"n\":\"NAME - Name\"}]},{\"t\":10,\"n\":\"Movement Types\",\"c\":[{\"t\":6,\"n\":\"Movement Types\",\"c\":[{\"t\":3,\"n\":\"MTYP - Movement Type\"}]}]},{\"t\":3,\"n\":\"VNAM - Equipment Flags\"},{\"t\":9,\"n\":\"Equip Slots\",\"c\":[{\"t\":3,\"n\":\"QNAM - Equip Slot\"}]},{\"t\":3,\"n\":\"UNES - Unarmed Equip Slot\"},{\"t\":7,\"n\":\"Phoneme Target Names\",\"c\":[{\"t\":2,\"n\":\"PHTN - Name\"}]},{\"t\":6,\"n\":\"FaceFX Phonemes\",\"c\":[{\"t\":6,\"n\":\"IY\",\"c\":[{\"t\":6,\"n\":\"PHWT - Phoneme Target Weight\",\"c\":[{\"t\":5,\"n\":\"Aah \\/ LipBigAah\"},{\"t\":5,\"n\":\"BigAah \\/ LipDST\"},{\"t\":5,\"n\":\"BMP \\/ LipEee\"},{\"t\":5,\"n\":\"ChJsh \\/ LipFV\"},{\"t\":5,\"n\":\"DST \\/ LipK\"},{\"t\":5,\"n\":\"Eee \\/ LipL\"},{\"t\":5,\"n\":\"Eh \\/ LipR\"},{\"t\":5,\"n\":\"FV \\/ LipTh\"},{\"t\":5,\"n\":\"I\"},{\"t\":5,\"n\":\"K\"},{\"t\":5,\"n\":\"N\"},{\"t\":5,\"n\":\"Oh\"},{\"t\":5,\"n\":\"OohQ\"},{\"t\":5,\"n\":\"R\"},{\"t\":5,\"n\":\"TH\"},{\"t\":5,\"n\":\"W\"}]}]}]},{\"t\":3,\"n\":\"WKMV - Base Movement Default - Walk\"},{\"t\":3,\"n\":\"RNMV - Base Movement Default - Run\"},{\"t\":3,\"n\":\"SWMV - Base Movement Default - Swim\"},{\"t\":3,\"n\":\"FLMV - Base Movement Default - Fly\"},{\"t\":3,\"n\":\"SNMV - Base Movement Default - Sneak\"},{\"t\":3,\"n\":\"SPMV - Base Movement Default - Sprint\"},{\"t\":6,\"n\":\"Head Data\",\"c\":[{\"n\":\"NAM0 - Head Data Marker\"},{\"t\":6,\"n\":\"Male Head Data\",\"d\":1,\"c\":[{\"n\":\"MNAM - Male Data Marker\"}]},{\"t\":6,\"n\":\"Female Head Data\",\"d\":1,\"c\":[{\"n\":\"NAM0 - Head Data Marker\"},{\"n\":\"FNAM - Female Data Marker\"}]}]},{\"t\":3,\"n\":\"NAM8 - Morph race\"},{\"t\":3,\"n\":\"RNAM - Armor race\"}]}]},\"name\":\"Bash.Voice-F\",\"hash\":\"$F6404D03\",\"color\":255}"
  },
  {
    "path": "frontend/settings/Skyrim/Bash.Voice-M.json",
    "content": "{\"records\":\"RACE\",\"description\":\"Voice-M tag from Wrye Bash.\\r\\n\\r\\nUsed when the mod modifies male voice definitions.\",\"tree\":{\"records\":[{\"t\":1,\"p\":1,\"n\":\"RACE - Race\",\"c\":[{\"t\":6,\"n\":\"Record Header\",\"c\":[{\"t\":2,\"n\":\"Signature\"},{\"t\":3,\"n\":\"Data Size\"},{\"t\":3,\"n\":\"Record Flags\"},{\"t\":3,\"n\":\"FormID\"},{\"t\":11,\"n\":\"Version Control Info 1\"},{\"t\":3,\"n\":\"Form Version\"},{\"t\":11,\"n\":\"Version Control Info 2\"}]},{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"n\":\"FULL - Name\"},{\"t\":2,\"n\":\"DESC - Description\"},{\"t\":3,\"n\":\"SPCT - Count\"},{\"t\":9,\"n\":\"Actor Effects\",\"c\":[{\"t\":3,\"n\":\"SPLO - Actor Effect\"}]},{\"t\":3,\"n\":\"WNAM - Skin\"},{\"t\":6,\"n\":\"BOD2 - Biped Body Template\",\"c\":[{\"t\":3,\"n\":\"First Person Flags\"},{\"t\":3,\"n\":\"General Flags\"},{\"n\":\"Unused\"},{\"t\":3,\"n\":\"Armor Type\"}]},{\"t\":3,\"n\":\"KSIZ - Keyword Count\"},{\"t\":9,\"n\":\"KWDA - Keywords\",\"c\":[{\"t\":3,\"n\":\"Keyword\"}]},{\"t\":6,\"n\":\"DATA - \",\"c\":[{\"t\":10,\"n\":\"Skill Boosts\",\"c\":[{\"t\":6,\"n\":\"Skill Boost\",\"c\":[{\"t\":3,\"n\":\"Skill\"},{\"t\":3,\"n\":\"Boost\"}]},{\"t\":6,\"n\":\"Skill Boost\",\"c\":[{\"t\":3,\"n\":\"Skill\"},{\"t\":3,\"n\":\"Boost\"}]},{\"t\":6,\"n\":\"Skill Boost\",\"c\":[{\"t\":3,\"n\":\"Skill\"},{\"t\":3,\"n\":\"Boost\"}]},{\"t\":6,\"n\":\"Skill Boost\",\"c\":[{\"t\":3,\"n\":\"Skill\"},{\"t\":3,\"n\":\"Boost\"}]},{\"t\":6,\"n\":\"Skill Boost\",\"c\":[{\"t\":3,\"n\":\"Skill\"},{\"t\":3,\"n\":\"Boost\"}]},{\"t\":6,\"n\":\"Skill Boost\",\"c\":[{\"t\":3,\"n\":\"Skill\"},{\"t\":3,\"n\":\"Boost\"}]},{\"t\":6,\"n\":\"Skill Boost\",\"c\":[{\"t\":3,\"n\":\"Skill\"},{\"t\":3,\"n\":\"Boost\"}]}]},{\"t\":11,\"n\":\"Unknown\"},{\"t\":5,\"n\":\"Male Height\"},{\"t\":5,\"n\":\"Female Height\"},{\"t\":5,\"n\":\"Male Weight\"},{\"t\":5,\"n\":\"Female Weight\"},{\"t\":3,\"n\":\"Flags\"},{\"t\":5,\"n\":\"Starting Health\"},{\"t\":5,\"n\":\"Starting Magicka\"},{\"t\":5,\"n\":\"Starting Stamina\"},{\"t\":5,\"n\":\"Base Carry Weight\"},{\"t\":5,\"n\":\"Base Mass\"},{\"t\":5,\"n\":\"Acceleration rate\"},{\"t\":5,\"n\":\"Deceleration rate\"},{\"t\":3,\"n\":\"Size\"},{\"t\":3,\"n\":\"Head Biped Object\"},{\"t\":3,\"n\":\"Hair Biped Object\"},{\"t\":5,\"n\":\"Injured Health Pct\"},{\"t\":3,\"n\":\"Shield Biped Object\"},{\"t\":5,\"n\":\"Health Regen\"},{\"t\":5,\"n\":\"Magicka Regen\"},{\"t\":5,\"n\":\"Stamina Regen\"},{\"t\":5,\"n\":\"Unarmed Damage\"},{\"t\":5,\"n\":\"Unarmed Reach\"},{\"t\":3,\"n\":\"Body Biped Object\"},{\"t\":5,\"n\":\"Aim Angle Tolerance\"},{\"t\":5,\"n\":\"Flight Radius\"},{\"t\":5,\"n\":\"Angular Acceleration Rate\"},{\"t\":5,\"n\":\"Angular Tolerance\"},{\"t\":3,\"n\":\"Flags 2\"},{\"t\":6,\"n\":\"Mount Data\",\"c\":[{\"t\":5,\"n\":\"Offset X\"},{\"t\":5,\"n\":\"Offset Y\"},{\"t\":5,\"n\":\"Unknown\"},{\"t\":5,\"n\":\"Unknown\"},{\"t\":5,\"n\":\"Unknown\"},{\"t\":5,\"n\":\"Unknown\"},{\"t\":5,\"n\":\"Unknown\"},{\"t\":5,\"n\":\"Unknown\"},{\"t\":5,\"n\":\"Unknown\"}]}]},{\"n\":\"MNAM - Male Marker\"},{\"t\":2,\"n\":\"ANAM - Male Skeletal Model\"},{\"t\":11,\"n\":\"MODT - Texture Files Hashes\"},{\"n\":\"FNAM - Female Marker\"},{\"t\":2,\"n\":\"ANAM - Female Skeletal Model\"},{\"t\":11,\"n\":\"MODT - Texture Files Hashes\"},{\"n\":\"NAM2 - Marker NAM2 #1\"},{\"t\":9,\"n\":\"Movement Type Names\",\"c\":[{\"t\":2,\"n\":\"MTNM - Name\"}]},{\"t\":7,\"p\":1,\"n\":\"VTCK - Voices\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Voice #0 (Male)\"},{\"t\":3,\"n\":\"Voice #1 (Female)\"}]},{\"t\":7,\"n\":\"DNAM - Decapitate Armors\",\"c\":[{\"t\":3,\"n\":\"Decapitate Armor #0 (Male)\"},{\"t\":3,\"n\":\"Decapitate Armor #1 (Female)\"}]},{\"t\":7,\"n\":\"HCLF - Default Hair Colors\",\"c\":[{\"t\":3,\"n\":\"Default Hair Color #0 (Male)\"},{\"t\":3,\"n\":\"Default Hair Color #1 (Female)\"}]},{\"t\":3,\"n\":\"TINL - Total Number of Tints in List\"},{\"t\":5,\"n\":\"PNAM - FaceGen - Main clamp\"},{\"t\":5,\"n\":\"UNAM - FaceGen - Face clamp\"},{\"t\":3,\"n\":\"ATKR - Attack Race\"},{\"t\":10,\"n\":\"Attacks\",\"c\":[{\"t\":6,\"n\":\"Attack\",\"c\":[{\"t\":6,\"n\":\"ATKD - Attack Data\",\"c\":[{\"t\":5,\"n\":\"Damage Mult\"},{\"t\":5,\"n\":\"Attack Chance\"},{\"t\":3,\"n\":\"Attack Spell\"},{\"t\":3,\"n\":\"Attack Flags\"},{\"t\":5,\"n\":\"Attack Angle\"},{\"t\":5,\"n\":\"Strike Angle\"},{\"t\":5,\"n\":\"Stagger\"},{\"t\":3,\"n\":\"Attack Type\"},{\"t\":5,\"n\":\"Knockdown\"},{\"t\":5,\"n\":\"Recovery Time\"},{\"t\":5,\"n\":\"Stamina Mult\"}]}]}]},{\"t\":6,\"n\":\"Body Data\",\"c\":[{\"n\":\"NAM1 - Body Data Marker\"},{\"t\":6,\"n\":\"Male Body Data\",\"c\":[{\"n\":\"MNAM - Male Data Marker\"},{\"t\":10,\"n\":\"Parts\",\"c\":[{\"t\":6,\"n\":\"Part\",\"c\":[{\"t\":3,\"n\":\"INDX - Index\"}]}]}]},{\"t\":6,\"n\":\"Female Body Data\",\"c\":[{\"n\":\"FNAM - Female Data Marker\"},{\"t\":10,\"n\":\"Parts\",\"c\":[{\"t\":6,\"n\":\"Part\",\"c\":[{\"t\":3,\"n\":\"INDX - Index\"}]}]}]}]},{\"t\":9,\"n\":\"HNAM - Hairs\",\"c\":[{\"t\":3,\"n\":\"Hair\"}]},{\"t\":9,\"n\":\"ENAM - Eyes\",\"c\":[{\"t\":3,\"n\":\"Eye\"}]},{\"t\":3,\"n\":\"GNAM - Body Part Data\"},{\"n\":\"NAM2 - Marker NAM2 #2\"},{\"n\":\"NAM3 - Marker NAM3 #3\"},{\"t\":6,\"n\":\"Male Behavior Graph\",\"c\":[{\"n\":\"MNAM - Male Data Marker\"}]},{\"t\":6,\"n\":\"Female Behavior Graph\",\"c\":[{\"n\":\"FNAM - Female Data Marker\"}]},{\"t\":3,\"n\":\"NAM4 - Material Type\"},{\"t\":3,\"n\":\"NAM5 - Impact Data Set\"},{\"t\":3,\"n\":\"NAM7 - Decapitation FX\"},{\"t\":3,\"n\":\"ONAM - Open Loot Sound\"},{\"t\":3,\"n\":\"LNAM - Close Loot Sound\"},{\"t\":7,\"n\":\"Biped Object Names\",\"c\":[{\"t\":2,\"n\":\"NAME - Name\"}]},{\"t\":10,\"n\":\"Movement Types\",\"c\":[{\"t\":6,\"n\":\"Movement Types\",\"c\":[{\"t\":3,\"n\":\"MTYP - Movement Type\"}]}]},{\"t\":3,\"n\":\"VNAM - Equipment Flags\"},{\"t\":9,\"n\":\"Equip Slots\",\"c\":[{\"t\":3,\"n\":\"QNAM - Equip Slot\"}]},{\"t\":3,\"n\":\"UNES - Unarmed Equip Slot\"},{\"t\":7,\"n\":\"Phoneme Target Names\",\"c\":[{\"t\":2,\"n\":\"PHTN - Name\"}]},{\"t\":6,\"n\":\"FaceFX Phonemes\",\"c\":[{\"t\":6,\"n\":\"IY\",\"c\":[{\"t\":6,\"n\":\"PHWT - Phoneme Target Weight\",\"c\":[{\"t\":5,\"n\":\"Aah \\/ LipBigAah\"},{\"t\":5,\"n\":\"BigAah \\/ LipDST\"},{\"t\":5,\"n\":\"BMP \\/ LipEee\"},{\"t\":5,\"n\":\"ChJsh \\/ LipFV\"},{\"t\":5,\"n\":\"DST \\/ LipK\"},{\"t\":5,\"n\":\"Eee \\/ LipL\"},{\"t\":5,\"n\":\"Eh \\/ LipR\"},{\"t\":5,\"n\":\"FV \\/ LipTh\"},{\"t\":5,\"n\":\"I\"},{\"t\":5,\"n\":\"K\"},{\"t\":5,\"n\":\"N\"},{\"t\":5,\"n\":\"Oh\"},{\"t\":5,\"n\":\"OohQ\"},{\"t\":5,\"n\":\"R\"},{\"t\":5,\"n\":\"TH\"},{\"t\":5,\"n\":\"W\"}]}]}]},{\"t\":3,\"n\":\"WKMV - Base Movement Default - Walk\"},{\"t\":3,\"n\":\"RNMV - Base Movement Default - Run\"},{\"t\":3,\"n\":\"SWMV - Base Movement Default - Swim\"},{\"t\":3,\"n\":\"FLMV - Base Movement Default - Fly\"},{\"t\":3,\"n\":\"SNMV - Base Movement Default - Sneak\"},{\"t\":3,\"n\":\"SPMV - Base Movement Default - Sprint\"},{\"t\":6,\"n\":\"Head Data\",\"c\":[{\"n\":\"NAM0 - Head Data Marker\"},{\"t\":6,\"n\":\"Male Head Data\",\"d\":1,\"c\":[{\"n\":\"MNAM - Male Data Marker\"}]},{\"t\":6,\"n\":\"Female Head Data\",\"d\":1,\"c\":[{\"n\":\"NAM0 - Head Data Marker\"},{\"n\":\"FNAM - Female Data Marker\"}]}]},{\"t\":3,\"n\":\"NAM8 - Morph race\"},{\"t\":3,\"n\":\"RNAM - Armor race\"}]}]},\"name\":\"Bash.Voice-M\",\"hash\":\"$E9C18B2C\",\"color\":255}"
  },
  {
    "path": "frontend/settings/Skyrim/Skip.json",
    "content": "{\"records\":\"\",\"description\":\"Special setting.  Any plugin with this setting will be excluded from patch creation.\",\"tree\":{\"records\":[]},\"name\":\"Skip\",\"hash\":\"$8ED3D1DA\",\"color\":8421504}"
  },
  {
    "path": "frontend/settings/Skyrim/Smash.All.json",
    "content": "{\"records\":\"AACT,ACTI,ADDN,ALCH,AMMO,ANIO,APPA,ARMA,ARMO,ARTO,ASPC,ASTP,AVIF,BOOK,BPTD,CAMS,CELL,CLAS,CLDC,CLFM,CLMT,COBJ,COLL,CONT,CPTH,CSTY,DEBR,DIAL,DLBR,DLVW,DOOR,DUAL,ECZN,EFSH,ENCH,EQUP,EXPL,EYES,FACT,FLOR,FLST,FSTP,FSTS,FURN,GLOB,GMST,GRAS,HAIR,HAZD,HDPT,IDLM,IMAD,IMGS,INFO,INGR,IPCT,IPDS,KEYM,KYWD,LAND,LCRT,LENS,LGTM,LIGH,LSCR,LTEX,LVLI,LVLN,LVSP,MATO,MATT,MESG,MGEF,MISC,MOVT,MSTT,MUSC,MUST,NPC_,OTFT,PACK,PARW,PBAR,PBEA,PCON,PERK,PFLA,PGRE,PHZD,PMIS,PROJ,PWAT,QUST,RACE,REFR,REGN,RELA,REVB,RFCT,RGDL,SCEN,SCOL,SCPT,SCRL,SHOU,SLGM,SMBN,SMEN,SMQN,SNCT,SNDR,SOPM,SOUN,SPEL,SPGD,STAT,TACT,TREE,TXST,VOLI,VTYP,WATR,WEAP,WOOP,WRLD,WTHR,ACHR\",\"description\":\"Smashes all the things.  Produced using autoset attributes on all record types found in Skyrim.esm and DLCs.  Replaces the old \\\"Automatic\\\" setting.\\r\\n\\r\\nLast updated 04\\/14\\/2018.\",\"tree\":{\"records\":[{\"t\":1,\"p\":1,\"n\":\"AACT - Action\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"CNAM - Color\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unknown\"}]}]},{\"t\":1,\"p\":1,\"n\":\"ACTI - Activator\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"VMAD - Virtual Machine Adapter\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Version\"},{\"t\":3,\"p\":1,\"n\":\"Object Format\"},{\"t\":7,\"p\":1,\"n\":\"Scripts\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Script\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"scriptName\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":7,\"p\":1,\"n\":\"Properties\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Property\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"propertyName\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]},{\"t\":2,\"p\":1,\"n\":\"String\"},{\"t\":3,\"p\":1,\"n\":\"Int32\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":3,\"p\":1,\"n\":\"Bool\"},{\"t\":7,\"p\":1,\"n\":\"Array of Object\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]}]},{\"t\":7,\"p\":1,\"n\":\"Array of String\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Int32\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Float\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Bool\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]}]}]}]}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"X1\"},{\"t\":3,\"p\":1,\"n\":\"Y1\"},{\"t\":3,\"p\":1,\"n\":\"Z1\"},{\"t\":3,\"p\":1,\"n\":\"X2\"},{\"t\":3,\"p\":1,\"n\":\"Y2\"},{\"t\":3,\"p\":1,\"n\":\"Z2\"}]},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"MODT - Texture Files Hashes\"},{\"t\":7,\"p\":1,\"n\":\"MODS - Alternate Textures\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"3D Name\"},{\"t\":3,\"p\":1,\"n\":\"New Texture\"},{\"t\":3,\"p\":1,\"n\":\"3D Index\"}]}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Destructable\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"DEST - Header\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Health\"},{\"t\":3,\"p\":1,\"n\":\"DEST Count\"},{\"t\":3,\"p\":1,\"n\":\"VATS Targetable\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":8,\"p\":1,\"n\":\"Stages\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Stage\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"DSTD - Destruction Stage Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Health %\"},{\"t\":3,\"p\":1,\"n\":\"Index\"},{\"t\":3,\"p\":1,\"n\":\"Model Damage Stage\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":3,\"p\":1,\"n\":\"Self Damage per Second\"},{\"t\":3,\"p\":1,\"n\":\"Explosion\"},{\"t\":3,\"p\":1,\"n\":\"Debris\"},{\"t\":3,\"p\":1,\"n\":\"Debris Count\"}]},{\"t\":6,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"DMDL - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"DMDT - Texture Files Hashes\"},{\"t\":7,\"p\":1,\"n\":\"DMDS - Alternate Textures\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"3D Name\"},{\"t\":3,\"p\":1,\"n\":\"New Texture\"},{\"t\":3,\"p\":1,\"n\":\"3D Index\"}]}]}]},{\"p\":1,\"n\":\"DSTF - End Marker\"}]}]}]},{\"t\":3,\"n\":\"KSIZ - Keyword Count\"},{\"t\":7,\"p\":1,\"n\":\"KWDA - Keywords\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Keyword\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"PNAM - Marker Color\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":3,\"n\":\"Unused\"}]},{\"t\":3,\"p\":1,\"n\":\"SNAM - Sound - Looping\"},{\"t\":3,\"p\":1,\"n\":\"VNAM - Sound - Activation\"},{\"t\":3,\"p\":1,\"n\":\"WNAM - Water Type\"},{\"t\":2,\"p\":1,\"n\":\"RNAM - Activate Text Override\"},{\"t\":3,\"p\":1,\"n\":\"FNAM - Flags\"},{\"t\":3,\"p\":1,\"n\":\"KNAM - Interaction Keyword\"}]},{\"t\":1,\"p\":1,\"n\":\"ADDN - Addon Node\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"X1\"},{\"t\":3,\"p\":1,\"n\":\"Y1\"},{\"t\":3,\"p\":1,\"n\":\"Z1\"},{\"t\":3,\"p\":1,\"n\":\"X2\"},{\"t\":3,\"p\":1,\"n\":\"Y2\"},{\"t\":3,\"p\":1,\"n\":\"Z2\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"MODT - Texture Files Hashes\"},{\"t\":7,\"p\":1,\"n\":\"MODS - Alternate Textures\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"3D Name\"},{\"t\":3,\"p\":1,\"n\":\"New Texture\"},{\"t\":3,\"p\":1,\"n\":\"3D Index\"}]}]}]},{\"t\":3,\"p\":1,\"n\":\"DATA - Node Index\"},{\"t\":3,\"p\":1,\"n\":\"SNAM - Sound\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DNAM - Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Master Particle System Cap\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"}]}]},{\"t\":1,\"p\":1,\"n\":\"ALCH - Ingestible\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"X1\"},{\"t\":3,\"p\":1,\"n\":\"Y1\"},{\"t\":3,\"p\":1,\"n\":\"Z1\"},{\"t\":3,\"p\":1,\"n\":\"X2\"},{\"t\":3,\"p\":1,\"n\":\"Y2\"},{\"t\":3,\"p\":1,\"n\":\"Z2\"}]},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":3,\"n\":\"KSIZ - Keyword Count\"},{\"t\":7,\"p\":1,\"n\":\"KWDA - Keywords\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Keyword\"}]},{\"t\":2,\"p\":1,\"n\":\"DESC - Description\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"MODT - Texture Files Hashes\"},{\"t\":7,\"p\":1,\"n\":\"MODS - Alternate Textures\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"3D Name\"},{\"t\":3,\"p\":1,\"n\":\"New Texture\"},{\"t\":3,\"p\":1,\"n\":\"3D Index\"}]}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Destructable\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"DEST - Header\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Health\"},{\"t\":3,\"p\":1,\"n\":\"DEST Count\"},{\"t\":3,\"p\":1,\"n\":\"VATS Targetable\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":8,\"p\":1,\"n\":\"Stages\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Stage\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"DSTD - Destruction Stage Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Health %\"},{\"t\":3,\"p\":1,\"n\":\"Index\"},{\"t\":3,\"p\":1,\"n\":\"Model Damage Stage\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":3,\"p\":1,\"n\":\"Self Damage per Second\"},{\"t\":3,\"p\":1,\"n\":\"Explosion\"},{\"t\":3,\"p\":1,\"n\":\"Debris\"},{\"t\":3,\"p\":1,\"n\":\"Debris Count\"}]},{\"t\":6,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"DMDL - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"DMDT - Texture Files Hashes\"},{\"t\":7,\"p\":1,\"n\":\"DMDS - Alternate Textures\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"3D Name\"},{\"t\":3,\"p\":1,\"n\":\"New Texture\"},{\"t\":3,\"p\":1,\"n\":\"3D Index\"}]}]}]},{\"p\":1,\"n\":\"DSTF - End Marker\"}]}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Icon\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"ICON - Large Icon filename\"},{\"t\":2,\"p\":1,\"n\":\"MICO - Small Icon filename\"}]},{\"t\":3,\"p\":1,\"n\":\"YNAM - Sound - Pick Up\"},{\"t\":3,\"p\":1,\"n\":\"ZNAM - Sound - Put Down\"},{\"t\":3,\"p\":1,\"n\":\"ETYP - Equipment Type\"},{\"t\":5,\"p\":1,\"n\":\"DATA - Weight\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"ENIT - Effect Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Value\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":3,\"p\":1,\"n\":\"Addiction\"},{\"t\":5,\"p\":1,\"n\":\"Addiction Chance\"},{\"t\":3,\"p\":1,\"n\":\"Sound - Consume\"}]},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Effects\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Effect\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"EFID - Base Effect\"},{\"t\":6,\"p\":1,\"n\":\"EFIT - \",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Magnitude\"},{\"t\":3,\"p\":1,\"n\":\"Area\"},{\"t\":3,\"p\":1,\"n\":\"Duration\"}]},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Conditions\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Condition\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"CTDA - \",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":5,\"p\":1,\"n\":\"Comparison Value - Float\"},{\"t\":3,\"p\":1,\"n\":\"Comparison Value - Global\"},{\"t\":3,\"p\":1,\"n\":\"Function\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":11,\"p\":1,\"n\":\"None\"},{\"t\":3,\"p\":1,\"n\":\"Integer\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":11,\"p\":1,\"n\":\"Variable Name (unused)\"},{\"t\":3,\"p\":1,\"n\":\"Sex\"},{\"t\":3,\"p\":1,\"n\":\"Actor Value\"},{\"t\":3,\"p\":1,\"n\":\"Crime Type\"},{\"t\":3,\"p\":1,\"n\":\"Axis\"},{\"t\":3,\"p\":1,\"n\":\"Quest Stage (unused)\"},{\"t\":3,\"p\":1,\"n\":\"Misc Stat\"},{\"t\":3,\"p\":1,\"n\":\"Alignment\"},{\"t\":3,\"p\":1,\"n\":\"Equip Type\"},{\"t\":3,\"p\":1,\"n\":\"Form Type\"},{\"t\":3,\"p\":1,\"n\":\"Critical Stage\"},{\"t\":3,\"p\":1,\"n\":\"Object Reference\"},{\"t\":3,\"p\":1,\"n\":\"Inventory Object\"},{\"t\":3,\"p\":1,\"n\":\"Actor\"},{\"t\":3,\"p\":1,\"n\":\"Voice Type\"},{\"t\":3,\"p\":1,\"n\":\"Idle\"},{\"t\":3,\"p\":1,\"n\":\"Form List\"},{\"t\":3,\"p\":1,\"n\":\"Quest\"},{\"t\":3,\"p\":1,\"n\":\"Faction\"},{\"t\":3,\"p\":1,\"n\":\"Cell\"},{\"t\":3,\"p\":1,\"n\":\"Class\"},{\"t\":3,\"p\":1,\"n\":\"Race\"},{\"t\":3,\"p\":1,\"n\":\"Actor Base\"},{\"t\":3,\"p\":1,\"n\":\"Global\"},{\"t\":3,\"p\":1,\"n\":\"Weather\"},{\"t\":3,\"p\":1,\"n\":\"Package\"},{\"t\":3,\"p\":1,\"n\":\"Encounter Zone\"},{\"t\":3,\"p\":1,\"n\":\"Perk\"},{\"t\":3,\"p\":1,\"n\":\"Owner\"},{\"t\":3,\"p\":1,\"n\":\"Furniture\"},{\"t\":3,\"p\":1,\"n\":\"Effect Item\"},{\"t\":3,\"p\":1,\"n\":\"Base Effect\"},{\"t\":3,\"p\":1,\"n\":\"Worldspace\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Function\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Param (INVALID)\"},{\"t\":3,\"p\":1,\"n\":\"Referenceable Object\"},{\"t\":3,\"p\":1,\"n\":\"Region\"},{\"t\":3,\"p\":1,\"n\":\"Keyword\"},{\"t\":3,\"p\":1,\"n\":\"Player Action\"},{\"t\":3,\"p\":1,\"n\":\"Casting Type\"},{\"t\":3,\"p\":1,\"n\":\"Shout\"},{\"t\":3,\"p\":1,\"n\":\"Location\"},{\"t\":3,\"p\":1,\"n\":\"Location Ref Type\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"Packdata ID\"},{\"t\":3,\"p\":1,\"n\":\"Association Type\"},{\"t\":3,\"p\":1,\"n\":\"Furniture Anim\"},{\"t\":3,\"p\":1,\"n\":\"Furniture Entry\"},{\"t\":3,\"p\":1,\"n\":\"Scene\"},{\"t\":3,\"p\":1,\"n\":\"Ward State\"},{\"t\":3,\"p\":1,\"n\":\"Event\"},{\"t\":3,\"p\":1,\"n\":\"Event Data\"},{\"t\":3,\"p\":1,\"n\":\"Quest Stage\"},{\"t\":3,\"p\":1,\"n\":\"Weapon\"},{\"t\":3,\"p\":1,\"n\":\"Weapon List\"},{\"t\":3,\"p\":1,\"n\":\"Target\"},{\"t\":3,\"p\":1,\"n\":\"Target List\"},{\"t\":3,\"p\":1,\"n\":\"Target Part\"},{\"t\":3,\"p\":1,\"n\":\"VATS Action\"},{\"t\":3,\"p\":1,\"n\":\"Critical Effect\"},{\"t\":3,\"p\":1,\"n\":\"Critical Effect List\"},{\"t\":3,\"p\":1,\"n\":\"Weapon Type\"},{\"t\":3,\"p\":1,\"n\":\"Projectile Type\"},{\"t\":3,\"p\":1,\"n\":\"Delivery Type\"},{\"t\":3,\"p\":1,\"n\":\"Run On\"},{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":3,\"p\":1,\"n\":\"Parameter #3\"}]},{\"t\":2,\"p\":1,\"n\":\"CIS1 - Parameter #1\"},{\"t\":2,\"p\":1,\"n\":\"CIS2 - Parameter #2\"}]}]}]}]}]},{\"t\":1,\"p\":1,\"n\":\"AMMO - Ammunition\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"X1\"},{\"t\":3,\"p\":1,\"n\":\"Y1\"},{\"t\":3,\"p\":1,\"n\":\"Z1\"},{\"t\":3,\"p\":1,\"n\":\"X2\"},{\"t\":3,\"p\":1,\"n\":\"Y2\"},{\"t\":3,\"p\":1,\"n\":\"Z2\"}]},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"MODT - Texture Files Hashes\"},{\"t\":7,\"p\":1,\"n\":\"MODS - Alternate Textures\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"3D Name\"},{\"t\":3,\"p\":1,\"n\":\"New Texture\"},{\"t\":3,\"p\":1,\"n\":\"3D Index\"}]}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Icon\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"ICON - Large Icon filename\"},{\"t\":2,\"p\":1,\"n\":\"MICO - Small Icon filename\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Destructable\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"DEST - Header\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Health\"},{\"t\":3,\"p\":1,\"n\":\"DEST Count\"},{\"t\":3,\"p\":1,\"n\":\"VATS Targetable\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":8,\"p\":1,\"n\":\"Stages\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Stage\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"DSTD - Destruction Stage Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Health %\"},{\"t\":3,\"p\":1,\"n\":\"Index\"},{\"t\":3,\"p\":1,\"n\":\"Model Damage Stage\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":3,\"p\":1,\"n\":\"Self Damage per Second\"},{\"t\":3,\"p\":1,\"n\":\"Explosion\"},{\"t\":3,\"p\":1,\"n\":\"Debris\"},{\"t\":3,\"p\":1,\"n\":\"Debris Count\"}]},{\"t\":6,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"DMDL - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"DMDT - Texture Files Hashes\"},{\"t\":7,\"p\":1,\"n\":\"DMDS - Alternate Textures\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"3D Name\"},{\"t\":3,\"p\":1,\"n\":\"New Texture\"},{\"t\":3,\"p\":1,\"n\":\"3D Index\"}]}]}]},{\"p\":1,\"n\":\"DSTF - End Marker\"}]}]}]},{\"t\":3,\"p\":1,\"n\":\"YNAM - Sound - Pick Up\"},{\"t\":3,\"p\":1,\"n\":\"ZNAM - Sound - Put Down\"},{\"t\":2,\"p\":1,\"n\":\"DESC - Description\"},{\"t\":3,\"n\":\"KSIZ - Keyword Count\"},{\"t\":7,\"p\":1,\"n\":\"KWDA - Keywords\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Keyword\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DATA - Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Projectile\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":5,\"p\":1,\"n\":\"Damage\"},{\"t\":3,\"p\":1,\"n\":\"Value\"}]},{\"t\":2,\"p\":1,\"n\":\"ONAM - Short Name\"}]},{\"t\":1,\"p\":1,\"n\":\"ANIO - Animated Object\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"MODT - Texture Files Hashes\"},{\"t\":7,\"p\":1,\"n\":\"MODS - Alternate Textures\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"3D Name\"},{\"t\":3,\"p\":1,\"n\":\"New Texture\"},{\"t\":3,\"p\":1,\"n\":\"3D Index\"}]}]}]},{\"t\":2,\"p\":1,\"n\":\"BNAM - Unload Event\"}]},{\"t\":1,\"p\":1,\"n\":\"APPA - Alchemical Apparatus\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"VMAD - Virtual Machine Adapter\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Version\"},{\"t\":3,\"p\":1,\"n\":\"Object Format\"},{\"t\":7,\"p\":1,\"n\":\"Scripts\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Script\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"scriptName\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":7,\"p\":1,\"n\":\"Properties\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Property\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"propertyName\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]},{\"t\":2,\"p\":1,\"n\":\"String\"},{\"t\":3,\"p\":1,\"n\":\"Int32\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":3,\"p\":1,\"n\":\"Bool\"},{\"t\":7,\"p\":1,\"n\":\"Array of Object\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]}]},{\"t\":7,\"p\":1,\"n\":\"Array of String\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Int32\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Float\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Bool\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]}]}]}]}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"X1\"},{\"t\":3,\"p\":1,\"n\":\"Y1\"},{\"t\":3,\"p\":1,\"n\":\"Z1\"},{\"t\":3,\"p\":1,\"n\":\"X2\"},{\"t\":3,\"p\":1,\"n\":\"Y2\"},{\"t\":3,\"p\":1,\"n\":\"Z2\"}]},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"MODT - Texture Files Hashes\"},{\"t\":7,\"p\":1,\"n\":\"MODS - Alternate Textures\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"3D Name\"},{\"t\":3,\"p\":1,\"n\":\"New Texture\"},{\"t\":3,\"p\":1,\"n\":\"3D Index\"}]}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Icon\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"ICON - Large Icon filename\"},{\"t\":2,\"p\":1,\"n\":\"MICO - Small Icon filename\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Destructable\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"DEST - Header\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Health\"},{\"t\":3,\"p\":1,\"n\":\"DEST Count\"},{\"t\":3,\"p\":1,\"n\":\"VATS Targetable\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":8,\"p\":1,\"n\":\"Stages\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Stage\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"DSTD - Destruction Stage Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Health %\"},{\"t\":3,\"p\":1,\"n\":\"Index\"},{\"t\":3,\"p\":1,\"n\":\"Model Damage Stage\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":3,\"p\":1,\"n\":\"Self Damage per Second\"},{\"t\":3,\"p\":1,\"n\":\"Explosion\"},{\"t\":3,\"p\":1,\"n\":\"Debris\"},{\"t\":3,\"p\":1,\"n\":\"Debris Count\"}]},{\"t\":6,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"DMDL - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"DMDT - Texture Files Hashes\"},{\"t\":7,\"p\":1,\"n\":\"DMDS - Alternate Textures\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"3D Name\"},{\"t\":3,\"p\":1,\"n\":\"New Texture\"},{\"t\":3,\"p\":1,\"n\":\"3D Index\"}]}]}]},{\"p\":1,\"n\":\"DSTF - End Marker\"}]}]}]},{\"t\":3,\"p\":1,\"n\":\"YNAM - Sound - Pick Up\"},{\"t\":3,\"p\":1,\"n\":\"ZNAM - Sound - Put Down\"},{\"t\":3,\"p\":1,\"n\":\"QUAL - Quality\"},{\"t\":2,\"p\":1,\"n\":\"DESC - Description\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DATA - Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Value\"},{\"t\":5,\"p\":1,\"n\":\"Weight\"}]}]},{\"t\":1,\"p\":1,\"n\":\"ARMA - Armor Addon\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"BOD2 - Biped Body Template\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"First Person Flags\"},{\"t\":3,\"p\":1,\"n\":\"General Flags\"},{\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Armor Type\"}],\"lt\":\"BODT - Body Template\",\"lf\":\"BODT - Body Template\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"BODT - Body Template\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"First Person Flags\"},{\"t\":3,\"p\":1,\"n\":\"General Flags\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Armor Type\"}],\"lt\":\"BOD2 - Biped Body Template\",\"lf\":\"BOD2 - Biped Body Template\"},{\"t\":3,\"p\":1,\"n\":\"RNAM - Race\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DNAM - Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Male Priority\"},{\"t\":3,\"p\":1,\"n\":\"Female Priority\"},{\"t\":3,\"p\":1,\"n\":\"Weight slider - Male\"},{\"t\":3,\"p\":1,\"n\":\"Weight slider - Female\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":3,\"p\":1,\"n\":\"Detection Sound Value\"},{\"t\":5,\"p\":1,\"n\":\"Weapon Adjust\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Male world model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MOD2 - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"MO2T - Texture Files Hashes\"},{\"t\":7,\"p\":1,\"n\":\"MO2S - Alternate Textures\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"3D Name\"},{\"t\":3,\"p\":1,\"n\":\"New Texture\"},{\"t\":3,\"p\":1,\"n\":\"3D Index\"}]}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Female world model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MOD3 - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"MO3T - Texture Files Hashes\"},{\"t\":7,\"p\":1,\"n\":\"MO3S - Alternate Textures\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"3D Name\"},{\"t\":3,\"p\":1,\"n\":\"New Texture\"},{\"t\":3,\"p\":1,\"n\":\"3D Index\"}]}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Male 1st Person\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MOD4 - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"MO4T - Texture Files Hashes\"},{\"t\":7,\"p\":1,\"n\":\"MO4S - Alternate Textures\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"3D Name\"},{\"t\":3,\"p\":1,\"n\":\"New Texture\"},{\"t\":3,\"p\":1,\"n\":\"3D Index\"}]}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Female 1st Person\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MOD5 - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"MO5T - Texture Files Hashes\"},{\"t\":7,\"p\":1,\"n\":\"MO5S - Alternate Textures\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"3D Name\"},{\"t\":3,\"p\":1,\"n\":\"New Texture\"},{\"t\":3,\"p\":1,\"n\":\"3D Index\"}]}]}]},{\"t\":3,\"p\":1,\"n\":\"NAM0 - Male Skin Texture\"},{\"t\":3,\"p\":1,\"n\":\"NAM1 - Female Skin texture\"},{\"t\":3,\"p\":1,\"n\":\"NAM2 - Male Skin Texture Swap List\"},{\"t\":3,\"p\":1,\"n\":\"NAM3 - Female Skin Texture Swap List\"},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Additional Races\",\"d\":1,\"c\":[{\"t\":3,\"p\":1,\"n\":\"MODL - Race\"}]},{\"t\":3,\"p\":1,\"n\":\"SNDD - Footstep Sound\"},{\"t\":3,\"p\":1,\"n\":\"ONAM - Art Object\"}]},{\"t\":1,\"p\":1,\"n\":\"ARMO - Armor\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"VMAD - Virtual Machine Adapter\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Version\"},{\"t\":3,\"p\":1,\"n\":\"Object Format\"},{\"t\":7,\"p\":1,\"n\":\"Scripts\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Script\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"scriptName\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":7,\"p\":1,\"n\":\"Properties\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Property\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"propertyName\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]},{\"t\":2,\"p\":1,\"n\":\"String\"},{\"t\":3,\"p\":1,\"n\":\"Int32\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":3,\"p\":1,\"n\":\"Bool\"},{\"t\":7,\"p\":1,\"n\":\"Array of Object\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]}]},{\"t\":7,\"p\":1,\"n\":\"Array of String\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Int32\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Float\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Bool\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]}]}]}]}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"X1\"},{\"t\":3,\"p\":1,\"n\":\"Y1\"},{\"t\":3,\"p\":1,\"n\":\"Z1\"},{\"t\":3,\"p\":1,\"n\":\"X2\"},{\"t\":3,\"p\":1,\"n\":\"Y2\"},{\"t\":3,\"p\":1,\"n\":\"Z2\"}]},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":3,\"p\":1,\"n\":\"EITM - Object Effect\"},{\"t\":3,\"p\":1,\"n\":\"EAMT - Enchantment Amount\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Male world model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MOD2 - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"MO2T - Texture Files Hashes\"},{\"t\":7,\"p\":1,\"n\":\"MO2S - Alternate Textures\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"3D Name\"},{\"t\":3,\"p\":1,\"n\":\"New Texture\"},{\"t\":3,\"p\":1,\"n\":\"3D Index\"}]}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Icon\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"ICON - Large Icon filename\"},{\"t\":2,\"p\":1,\"n\":\"MICO - Small Icon filename\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Female world model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MOD4 - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"MO4T - Texture Files Hashes\"},{\"t\":7,\"p\":1,\"n\":\"MO4S - Alternate Textures\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"3D Name\"},{\"t\":3,\"p\":1,\"n\":\"New Texture\"},{\"t\":3,\"p\":1,\"n\":\"3D Index\"}]}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Icon 2 (female)\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"ICO2 - Large Icon filename\"},{\"t\":2,\"p\":1,\"n\":\"MIC2 - Small Icon filename\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"BOD2 - Biped Body Template\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"First Person Flags\"},{\"t\":3,\"p\":1,\"n\":\"General Flags\"},{\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Armor Type\"}],\"lt\":\"BODT - Body Template\",\"lf\":\"BODT - Body Template\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"BODT - Body Template\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"First Person Flags\"},{\"t\":3,\"p\":1,\"n\":\"General Flags\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Armor Type\"}],\"lt\":\"BOD2 - Biped Body Template\",\"lf\":\"BOD2 - Biped Body Template\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Destructable\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"DEST - Header\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Health\"},{\"t\":3,\"p\":1,\"n\":\"DEST Count\"},{\"t\":3,\"p\":1,\"n\":\"VATS Targetable\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":8,\"p\":1,\"n\":\"Stages\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Stage\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"DSTD - Destruction Stage Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Health %\"},{\"t\":3,\"p\":1,\"n\":\"Index\"},{\"t\":3,\"p\":1,\"n\":\"Model Damage Stage\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":3,\"p\":1,\"n\":\"Self Damage per Second\"},{\"t\":3,\"p\":1,\"n\":\"Explosion\"},{\"t\":3,\"p\":1,\"n\":\"Debris\"},{\"t\":3,\"p\":1,\"n\":\"Debris Count\"}]},{\"t\":6,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"DMDL - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"DMDT - Texture Files Hashes\"},{\"t\":7,\"p\":1,\"n\":\"DMDS - Alternate Textures\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"3D Name\"},{\"t\":3,\"p\":1,\"n\":\"New Texture\"},{\"t\":3,\"p\":1,\"n\":\"3D Index\"}]}]}]},{\"p\":1,\"n\":\"DSTF - End Marker\"}]}]}]},{\"t\":3,\"p\":1,\"n\":\"YNAM - Sound - Pick Up\"},{\"t\":3,\"p\":1,\"n\":\"ZNAM - Sound - Put Down\"},{\"t\":2,\"p\":1,\"n\":\"BMCT - Ragdoll Constraint Template\"},{\"t\":3,\"p\":1,\"n\":\"ETYP - Equipment Type\"},{\"t\":3,\"p\":1,\"n\":\"BIDS - Bash Impact Data Set\"},{\"t\":3,\"p\":1,\"n\":\"BAMT - Alternate Block Material\"},{\"t\":3,\"p\":1,\"n\":\"RNAM - Race\"},{\"t\":3,\"n\":\"KSIZ - Keyword Count\"},{\"t\":7,\"p\":1,\"n\":\"KWDA - Keywords\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Keyword\"}]},{\"t\":2,\"p\":1,\"n\":\"DESC - Description\"},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Armature\",\"d\":1,\"c\":[{\"t\":3,\"p\":1,\"n\":\"MODL - Model Filename\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DATA - Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Value\"},{\"t\":5,\"p\":1,\"n\":\"Weight\"}]},{\"t\":3,\"p\":1,\"n\":\"DNAM - Armor Rating\"},{\"t\":3,\"p\":1,\"n\":\"TNAM - Template Armor\"}]},{\"t\":1,\"p\":1,\"n\":\"ARTO - Art Object\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"X1\"},{\"t\":3,\"p\":1,\"n\":\"Y1\"},{\"t\":3,\"p\":1,\"n\":\"Z1\"},{\"t\":3,\"p\":1,\"n\":\"X2\"},{\"t\":3,\"p\":1,\"n\":\"Y2\"},{\"t\":3,\"p\":1,\"n\":\"Z2\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"MODT - Texture Files Hashes\"},{\"t\":7,\"p\":1,\"n\":\"MODS - Alternate Textures\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"3D Name\"},{\"t\":3,\"p\":1,\"n\":\"New Texture\"},{\"t\":3,\"p\":1,\"n\":\"3D Index\"}]}]}]},{\"t\":3,\"p\":1,\"n\":\"DNAM - Art Type\"}]},{\"t\":1,\"p\":1,\"n\":\"ASPC - Acoustic Space\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"X1\"},{\"t\":3,\"p\":1,\"n\":\"Y1\"},{\"t\":3,\"p\":1,\"n\":\"Z1\"},{\"t\":3,\"p\":1,\"n\":\"X2\"},{\"t\":3,\"p\":1,\"n\":\"Y2\"},{\"t\":3,\"p\":1,\"n\":\"Z2\"}]},{\"t\":3,\"p\":1,\"n\":\"SNAM - Ambient Sound\"},{\"t\":3,\"p\":1,\"n\":\"RDAT - Use Sound from Region (Interiors Only)\"},{\"t\":3,\"p\":1,\"n\":\"BNAM - Environment Type (reverb)\"}]},{\"t\":1,\"p\":1,\"n\":\"ASTP - Association Type\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"p\":1,\"n\":\"MPRT - Male Parent Title\"},{\"t\":2,\"p\":1,\"n\":\"FPRT - Female Parent Title\"},{\"t\":2,\"p\":1,\"n\":\"MCHT - Male Child Title\"},{\"t\":2,\"p\":1,\"n\":\"FCHT - Female Child Title\"},{\"t\":3,\"p\":1,\"n\":\"DATA - Flags\"}]},{\"t\":1,\"p\":1,\"n\":\"AVIF - Actor Value Information\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":2,\"p\":1,\"n\":\"DESC - Description\"},{\"t\":2,\"p\":1,\"n\":\"ANAM - Abbreviation\"},{\"t\":11,\"n\":\"CNAM - Unknown\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"AVSK - Skill\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Skill Use Mult\"},{\"t\":5,\"p\":1,\"n\":\"Skill Offset Mult\"},{\"t\":5,\"p\":1,\"n\":\"Skill Improve Mult\"},{\"t\":5,\"p\":1,\"n\":\"Skill Improve Offset\"}]},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Perk Tree\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Node\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"PNAM - Perk\"},{\"t\":11,\"n\":\"FNAM - Unknown\"},{\"t\":3,\"p\":1,\"n\":\"XNAM - Perk-Grid X\"},{\"t\":3,\"p\":1,\"n\":\"YNAM - Perk-Grid Y\"},{\"t\":5,\"p\":1,\"n\":\"HNAM - Horizontal Position\"},{\"t\":5,\"p\":1,\"n\":\"VNAM - Vertical Position\"},{\"t\":3,\"p\":1,\"n\":\"SNAM - Associated Skill\"},{\"t\":8,\"p\":1,\"n\":\"Connections\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"CNAM - Line to Index\"}]},{\"t\":3,\"p\":1,\"n\":\"INAM - Index\"}]}]}]},{\"t\":1,\"p\":1,\"n\":\"BOOK - Book\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"VMAD - Virtual Machine Adapter\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Version\"},{\"t\":3,\"p\":1,\"n\":\"Object Format\"},{\"t\":7,\"p\":1,\"n\":\"Scripts\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Script\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"scriptName\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":7,\"p\":1,\"n\":\"Properties\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Property\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"propertyName\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]},{\"t\":2,\"p\":1,\"n\":\"String\"},{\"t\":3,\"p\":1,\"n\":\"Int32\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":3,\"p\":1,\"n\":\"Bool\"},{\"t\":7,\"p\":1,\"n\":\"Array of Object\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]}]},{\"t\":7,\"p\":1,\"n\":\"Array of String\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Int32\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Float\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Bool\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]}]}]}]}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"X1\"},{\"t\":3,\"p\":1,\"n\":\"Y1\"},{\"t\":3,\"p\":1,\"n\":\"Z1\"},{\"t\":3,\"p\":1,\"n\":\"X2\"},{\"t\":3,\"p\":1,\"n\":\"Y2\"},{\"t\":3,\"p\":1,\"n\":\"Z2\"}]},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"MODT - Texture Files Hashes\"},{\"t\":7,\"p\":1,\"n\":\"MODS - Alternate Textures\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"3D Name\"},{\"t\":3,\"p\":1,\"n\":\"New Texture\"},{\"t\":3,\"p\":1,\"n\":\"3D Index\"}]}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Icon\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"ICON - Large Icon filename\"},{\"t\":2,\"p\":1,\"n\":\"MICO - Small Icon filename\"}]},{\"t\":2,\"p\":1,\"n\":\"DESC - Book Text\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Destructable\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"DEST - Header\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Health\"},{\"t\":3,\"p\":1,\"n\":\"DEST Count\"},{\"t\":3,\"p\":1,\"n\":\"VATS Targetable\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":8,\"p\":1,\"n\":\"Stages\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Stage\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"DSTD - Destruction Stage Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Health %\"},{\"t\":3,\"p\":1,\"n\":\"Index\"},{\"t\":3,\"p\":1,\"n\":\"Model Damage Stage\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":3,\"p\":1,\"n\":\"Self Damage per Second\"},{\"t\":3,\"p\":1,\"n\":\"Explosion\"},{\"t\":3,\"p\":1,\"n\":\"Debris\"},{\"t\":3,\"p\":1,\"n\":\"Debris Count\"}]},{\"t\":6,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"DMDL - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"DMDT - Texture Files Hashes\"},{\"t\":7,\"p\":1,\"n\":\"DMDS - Alternate Textures\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"3D Name\"},{\"t\":3,\"p\":1,\"n\":\"New Texture\"},{\"t\":3,\"p\":1,\"n\":\"3D Index\"}]}]}]},{\"p\":1,\"n\":\"DSTF - End Marker\"}]}]}]},{\"t\":3,\"p\":1,\"n\":\"YNAM - Sound - Pick Up\"},{\"t\":3,\"p\":1,\"n\":\"ZNAM - Sound - Put Down\"},{\"t\":3,\"n\":\"KSIZ - Keyword Count\"},{\"t\":7,\"p\":1,\"n\":\"KWDA - Keywords\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Keyword\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DATA - Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Skill\"},{\"t\":3,\"p\":1,\"n\":\"Spell\"},{\"t\":3,\"p\":1,\"n\":\"Value\"},{\"t\":5,\"p\":1,\"n\":\"Weight\"}]},{\"t\":3,\"p\":1,\"n\":\"INAM - Inventory Art\"},{\"t\":2,\"p\":1,\"n\":\"CNAM - Description\"}]},{\"t\":1,\"p\":1,\"n\":\"BPTD - Body Part Data\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"MODT - Texture Files Hashes\"},{\"t\":7,\"p\":1,\"n\":\"MODS - Alternate Textures\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"3D Name\"},{\"t\":3,\"p\":1,\"n\":\"New Texture\"},{\"t\":3,\"p\":1,\"n\":\"3D Index\"}]}]}]},{\"t\":10,\"p\":1,\"n\":\"Body Parts\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Body Part\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"BPTN - Part Name\"},{\"t\":2,\"p\":1,\"n\":\"PNAM - Pose Matching\"},{\"t\":2,\"p\":1,\"n\":\"BPNN - Part Node\"},{\"t\":2,\"p\":1,\"n\":\"BPNT - VATS Target\"},{\"t\":2,\"p\":1,\"n\":\"BPNI - IK Data - Start Node\"},{\"t\":6,\"p\":1,\"n\":\"BPND - \",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Damage Mult\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":3,\"p\":1,\"n\":\"Part Type\"},{\"t\":3,\"p\":1,\"n\":\"Health Percent\"},{\"t\":3,\"p\":1,\"n\":\"Actor Value\"},{\"t\":3,\"p\":1,\"n\":\"To Hit Chance\"},{\"t\":3,\"p\":1,\"n\":\"Explodable - Explosion Chance %\"},{\"t\":3,\"p\":1,\"n\":\"Explodable - Debris Count\"},{\"t\":3,\"p\":1,\"n\":\"Explodable - Debris\"},{\"t\":3,\"p\":1,\"n\":\"Explodable - Explosion\"},{\"t\":5,\"p\":1,\"n\":\"Tracking Max Angle\"},{\"t\":5,\"p\":1,\"n\":\"Explodable - Debris Scale\"},{\"t\":3,\"p\":1,\"n\":\"Severable - Debris Count\"},{\"t\":3,\"p\":1,\"n\":\"Severable - Debris\"},{\"t\":3,\"p\":1,\"n\":\"Severable - Explosion\"},{\"t\":5,\"p\":1,\"n\":\"Severable - Debris Scale\"},{\"t\":6,\"p\":1,\"n\":\"Gore Effects Positioning\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Translate\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"X\"},{\"t\":5,\"p\":1,\"n\":\"Y\"},{\"t\":5,\"p\":1,\"n\":\"Z\"}]},{\"t\":6,\"p\":1,\"n\":\"Rotation\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"X\"},{\"t\":5,\"p\":1,\"n\":\"Y\"},{\"t\":5,\"p\":1,\"n\":\"Z\"}]}]},{\"t\":3,\"p\":1,\"n\":\"Severable - Impact DataSet\"},{\"t\":3,\"p\":1,\"n\":\"Explodable - Impact DataSet\"},{\"t\":3,\"p\":1,\"n\":\"Severable - Decal Count\"},{\"t\":3,\"p\":1,\"n\":\"Explodable - Decal Count\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":5,\"p\":1,\"n\":\"Limb Replacement Scale\"}]},{\"t\":2,\"p\":1,\"n\":\"NAM1 - Limb Replacement Model\"},{\"t\":2,\"p\":1,\"n\":\"NAM4 - Gore Effects - Target Bone\"},{\"t\":11,\"p\":1,\"n\":\"NAM5 - Texture Files Hashes\"}]}]}]},{\"t\":1,\"p\":1,\"n\":\"CAMS - Camera Shot\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"MODT - Texture Files Hashes\"},{\"t\":7,\"p\":1,\"n\":\"MODS - Alternate Textures\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"3D Name\"},{\"t\":3,\"p\":1,\"n\":\"New Texture\"},{\"t\":3,\"p\":1,\"n\":\"3D Index\"}]}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DATA - Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Action\"},{\"t\":3,\"p\":1,\"n\":\"Location\"},{\"t\":3,\"p\":1,\"n\":\"Target\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":6,\"p\":1,\"n\":\"Time Multipliers\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Player\"},{\"t\":5,\"p\":1,\"n\":\"Target\"},{\"t\":5,\"p\":1,\"n\":\"Global\"}]},{\"t\":5,\"p\":1,\"n\":\"Max Time\"},{\"t\":5,\"p\":1,\"n\":\"Min Time\"},{\"t\":5,\"p\":1,\"n\":\"Target % Between Actors\"},{\"t\":5,\"p\":1,\"n\":\"Near Target Distance\"}]},{\"t\":3,\"p\":1,\"n\":\"MNAM - Image Space Modifier\"}]},{\"t\":1,\"p\":1,\"n\":\"CELL - Cell\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":3,\"p\":1,\"n\":\"DATA - Flags\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"XCLC - Grid\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"X\"},{\"t\":3,\"p\":1,\"n\":\"Y\"},{\"t\":3,\"p\":1,\"n\":\"Force Hide Land\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"XCLL - Lighting\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Ambient Color\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Directional Color\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Fog Color Near\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":5,\"p\":1,\"n\":\"Fog Near\"},{\"t\":5,\"p\":1,\"n\":\"Fog Far\"},{\"t\":3,\"p\":1,\"n\":\"Directional Rotation XY\"},{\"t\":3,\"p\":1,\"n\":\"Directional Rotation Z\"},{\"t\":5,\"p\":1,\"n\":\"Directional Fade\"},{\"t\":5,\"p\":1,\"n\":\"Fog Clip Distance\"},{\"t\":5,\"p\":1,\"n\":\"Fog Power\"},{\"t\":6,\"p\":1,\"n\":\"Ambient Colors\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Directional\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"X+\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"X-\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Y+\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Y-\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Z+\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Z-\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]}]},{\"t\":6,\"p\":1,\"n\":\"Specular\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":5,\"p\":1,\"n\":\"Scale\"}]},{\"t\":6,\"p\":1,\"n\":\"Fog Color Far\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":5,\"p\":1,\"n\":\"Fog Max\"},{\"t\":5,\"p\":1,\"n\":\"Light Fade Begin\"},{\"t\":5,\"p\":1,\"n\":\"Light Fade End\"},{\"t\":3,\"p\":1,\"n\":\"Inherits\"}]},{\"t\":11,\"n\":\"TVDT - Occlusion Data\"},{\"t\":11,\"n\":\"MHDT - Max Height Data\"},{\"t\":3,\"p\":1,\"n\":\"LTMP - Lighting Template\"},{\"t\":11,\"n\":\"LNAM - Unknown\"},{\"t\":5,\"p\":1,\"n\":\"XCLW - Water Height\"},{\"t\":2,\"p\":1,\"n\":\"XNAM - Water Noise Texture\"},{\"t\":7,\"p\":1,\"n\":\"XCLR - Regions\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Region\"}]},{\"t\":3,\"p\":1,\"n\":\"XLCN - Location\"},{\"t\":11,\"n\":\"XWCN - Unknown\"},{\"t\":11,\"n\":\"XWCS - Unknown\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"XWCU - Water Velocity\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"X Offset\"},{\"t\":5,\"p\":1,\"n\":\"Y Offset\"},{\"t\":5,\"p\":1,\"n\":\"Z Offset\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":5,\"p\":1,\"n\":\"X Angle\"},{\"t\":5,\"p\":1,\"n\":\"Y Angle\"},{\"t\":5,\"p\":1,\"n\":\"Z Angle\"}]},{\"t\":3,\"p\":1,\"n\":\"XCWT - Water\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Ownership\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"XOWN - Owner\"},{\"t\":3,\"p\":1,\"n\":\"XRNK - Faction rank\"}]},{\"t\":3,\"p\":1,\"n\":\"XILL - Lock List\"},{\"t\":2,\"p\":1,\"n\":\"XWEM - Water Environment Map\"},{\"t\":3,\"p\":1,\"n\":\"XCCM - Sky\\/Weather from Region\"},{\"t\":3,\"p\":1,\"n\":\"XCAS - Acoustic Space\"},{\"t\":3,\"p\":1,\"n\":\"XEZN - Encounter Zone\"},{\"t\":3,\"p\":1,\"n\":\"XCMO - Music Type\"},{\"t\":3,\"p\":1,\"n\":\"XCIM - Image Space\"}]},{\"t\":1,\"p\":1,\"n\":\"CLAS - Class\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":2,\"p\":1,\"n\":\"DESC - Description\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Icon\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"ICON - Large Icon filename\"},{\"t\":2,\"p\":1,\"n\":\"MICO - Small Icon filename\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DATA - \",\"c\":[{\"t\":11,\"n\":\"Unknown\"},{\"t\":3,\"p\":1,\"n\":\"Teaches\"},{\"t\":3,\"p\":1,\"n\":\"Maximum training level\"},{\"t\":7,\"p\":1,\"n\":\"Skill Weights\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Weight\"}]},{\"t\":5,\"p\":1,\"n\":\"Bleedout Default\"},{\"t\":3,\"p\":1,\"n\":\"Voice Points\"},{\"t\":7,\"p\":1,\"n\":\"Attribute Weights\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Weight\"}]}]}]},{\"t\":1,\"p\":1,\"n\":\"CLDC\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"}]},{\"t\":1,\"p\":1,\"n\":\"CLFM - Color\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"CNAM - Color\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":3,\"p\":1,\"n\":\"FNAM - Playable\"}]},{\"t\":1,\"p\":1,\"n\":\"CLMT - Climate\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":7,\"p\":1,\"n\":\"WLST - Weather Types\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Weather Type\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Weather\"},{\"t\":3,\"p\":1,\"n\":\"Chance\"},{\"t\":3,\"p\":1,\"n\":\"Global\"}]}]},{\"t\":2,\"p\":1,\"n\":\"FNAM - Sun Texture\"},{\"t\":2,\"p\":1,\"n\":\"GNAM - Sun Glare Texture\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"MODT - Texture Files Hashes\"},{\"t\":7,\"p\":1,\"n\":\"MODS - Alternate Textures\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"3D Name\"},{\"t\":3,\"p\":1,\"n\":\"New Texture\"},{\"t\":3,\"p\":1,\"n\":\"3D Index\"}]}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"TNAM - Timing\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Sunrise\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Begin\"},{\"t\":3,\"p\":1,\"n\":\"End\"}]},{\"t\":6,\"p\":1,\"n\":\"Sunset\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Begin\"},{\"t\":3,\"p\":1,\"n\":\"End\"}]},{\"t\":3,\"p\":1,\"n\":\"Volatility\"},{\"t\":3,\"p\":1,\"n\":\"Moons \\/ Phase Length\"}]}]},{\"t\":1,\"p\":1,\"n\":\"COBJ - Constructible Object\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":3,\"n\":\"COCT - Count\"},{\"t\":10,\"p\":1,\"n\":\"Items\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Item\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"CNTO - Item\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Item\"},{\"t\":3,\"p\":1,\"n\":\"Count\"}]},{\"t\":6,\"p\":1,\"n\":\"COED - Extra Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Owner\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Global Variable\"},{\"t\":3,\"p\":1,\"n\":\"Required Rank\"},{\"t\":5,\"p\":1,\"n\":\"Item Condition\"}]}]}]},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Conditions\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Condition\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"CTDA - \",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":5,\"p\":1,\"n\":\"Comparison Value - Float\"},{\"t\":3,\"p\":1,\"n\":\"Comparison Value - Global\"},{\"t\":3,\"p\":1,\"n\":\"Function\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":11,\"p\":1,\"n\":\"None\"},{\"t\":3,\"p\":1,\"n\":\"Integer\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":11,\"p\":1,\"n\":\"Variable Name (unused)\"},{\"t\":3,\"p\":1,\"n\":\"Sex\"},{\"t\":3,\"p\":1,\"n\":\"Actor Value\"},{\"t\":3,\"p\":1,\"n\":\"Crime Type\"},{\"t\":3,\"p\":1,\"n\":\"Axis\"},{\"t\":3,\"p\":1,\"n\":\"Quest Stage (unused)\"},{\"t\":3,\"p\":1,\"n\":\"Misc Stat\"},{\"t\":3,\"p\":1,\"n\":\"Alignment\"},{\"t\":3,\"p\":1,\"n\":\"Equip Type\"},{\"t\":3,\"p\":1,\"n\":\"Form Type\"},{\"t\":3,\"p\":1,\"n\":\"Critical Stage\"},{\"t\":3,\"p\":1,\"n\":\"Object Reference\"},{\"t\":3,\"p\":1,\"n\":\"Inventory Object\"},{\"t\":3,\"p\":1,\"n\":\"Actor\"},{\"t\":3,\"p\":1,\"n\":\"Voice Type\"},{\"t\":3,\"p\":1,\"n\":\"Idle\"},{\"t\":3,\"p\":1,\"n\":\"Form List\"},{\"t\":3,\"p\":1,\"n\":\"Quest\"},{\"t\":3,\"p\":1,\"n\":\"Faction\"},{\"t\":3,\"p\":1,\"n\":\"Cell\"},{\"t\":3,\"p\":1,\"n\":\"Class\"},{\"t\":3,\"p\":1,\"n\":\"Race\"},{\"t\":3,\"p\":1,\"n\":\"Actor Base\"},{\"t\":3,\"p\":1,\"n\":\"Global\"},{\"t\":3,\"p\":1,\"n\":\"Weather\"},{\"t\":3,\"p\":1,\"n\":\"Package\"},{\"t\":3,\"p\":1,\"n\":\"Encounter Zone\"},{\"t\":3,\"p\":1,\"n\":\"Perk\"},{\"t\":3,\"p\":1,\"n\":\"Owner\"},{\"t\":3,\"p\":1,\"n\":\"Furniture\"},{\"t\":3,\"p\":1,\"n\":\"Effect Item\"},{\"t\":3,\"p\":1,\"n\":\"Base Effect\"},{\"t\":3,\"p\":1,\"n\":\"Worldspace\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Function\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Param (INVALID)\"},{\"t\":3,\"p\":1,\"n\":\"Referenceable Object\"},{\"t\":3,\"p\":1,\"n\":\"Region\"},{\"t\":3,\"p\":1,\"n\":\"Keyword\"},{\"t\":3,\"p\":1,\"n\":\"Player Action\"},{\"t\":3,\"p\":1,\"n\":\"Casting Type\"},{\"t\":3,\"p\":1,\"n\":\"Shout\"},{\"t\":3,\"p\":1,\"n\":\"Location\"},{\"t\":3,\"p\":1,\"n\":\"Location Ref Type\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"Packdata ID\"},{\"t\":3,\"p\":1,\"n\":\"Association Type\"},{\"t\":3,\"p\":1,\"n\":\"Furniture Anim\"},{\"t\":3,\"p\":1,\"n\":\"Furniture Entry\"},{\"t\":3,\"p\":1,\"n\":\"Scene\"},{\"t\":3,\"p\":1,\"n\":\"Ward State\"},{\"t\":3,\"p\":1,\"n\":\"Event\"},{\"t\":3,\"p\":1,\"n\":\"Event Data\"},{\"t\":3,\"p\":1,\"n\":\"Quest Stage\"},{\"t\":3,\"p\":1,\"n\":\"Weapon\"},{\"t\":3,\"p\":1,\"n\":\"Weapon List\"},{\"t\":3,\"p\":1,\"n\":\"Target\"},{\"t\":3,\"p\":1,\"n\":\"Target List\"},{\"t\":3,\"p\":1,\"n\":\"Target Part\"},{\"t\":3,\"p\":1,\"n\":\"VATS Action\"},{\"t\":3,\"p\":1,\"n\":\"Critical Effect\"},{\"t\":3,\"p\":1,\"n\":\"Critical Effect List\"},{\"t\":3,\"p\":1,\"n\":\"Weapon Type\"},{\"t\":3,\"p\":1,\"n\":\"Projectile Type\"},{\"t\":3,\"p\":1,\"n\":\"Delivery Type\"},{\"t\":3,\"p\":1,\"n\":\"Run On\"},{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":3,\"p\":1,\"n\":\"Parameter #3\"}]},{\"t\":2,\"p\":1,\"n\":\"CIS1 - Parameter #1\"},{\"t\":2,\"p\":1,\"n\":\"CIS2 - Parameter #2\"}]}]},{\"t\":3,\"p\":1,\"n\":\"CNAM - Created Object\"},{\"t\":3,\"p\":1,\"n\":\"BNAM - Workbench Keyword\"},{\"t\":3,\"p\":1,\"n\":\"NAM1 - Created Object Count\"}]},{\"t\":1,\"p\":1,\"n\":\"COLL - Collision Layer\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"p\":1,\"n\":\"DESC - Description\"},{\"t\":3,\"p\":1,\"n\":\"BNAM - Index\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"FNAM - Debug Color\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":3,\"n\":\"Unused\"}]},{\"t\":3,\"p\":1,\"n\":\"GNAM - Flags\"},{\"t\":2,\"p\":1,\"n\":\"MNAM - Name\"},{\"t\":3,\"n\":\"INTV - Interactables Count\"},{\"t\":7,\"p\":1,\"n\":\"CNAM - Collides With\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Forms\"}]}]},{\"t\":1,\"p\":1,\"n\":\"CONT - Container\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"VMAD - Virtual Machine Adapter\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Version\"},{\"t\":3,\"p\":1,\"n\":\"Object Format\"},{\"t\":7,\"p\":1,\"n\":\"Scripts\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Script\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"scriptName\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":7,\"p\":1,\"n\":\"Properties\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Property\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"propertyName\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]},{\"t\":2,\"p\":1,\"n\":\"String\"},{\"t\":3,\"p\":1,\"n\":\"Int32\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":3,\"p\":1,\"n\":\"Bool\"},{\"t\":7,\"p\":1,\"n\":\"Array of Object\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]}]},{\"t\":7,\"p\":1,\"n\":\"Array of String\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Int32\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Float\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Bool\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]}]}]}]}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"X1\"},{\"t\":3,\"p\":1,\"n\":\"Y1\"},{\"t\":3,\"p\":1,\"n\":\"Z1\"},{\"t\":3,\"p\":1,\"n\":\"X2\"},{\"t\":3,\"p\":1,\"n\":\"Y2\"},{\"t\":3,\"p\":1,\"n\":\"Z2\"}]},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"MODT - Texture Files Hashes\"},{\"t\":7,\"p\":1,\"n\":\"MODS - Alternate Textures\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"3D Name\"},{\"t\":3,\"p\":1,\"n\":\"New Texture\"},{\"t\":3,\"p\":1,\"n\":\"3D Index\"}]}]}]},{\"t\":3,\"n\":\"COCT - Count\"},{\"t\":10,\"p\":1,\"n\":\"Items\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Item\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"CNTO - Item\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Item\"},{\"t\":3,\"p\":1,\"n\":\"Count\"}]},{\"t\":6,\"p\":1,\"n\":\"COED - Extra Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Owner\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Global Variable\"},{\"t\":3,\"p\":1,\"n\":\"Required Rank\"},{\"t\":5,\"p\":1,\"n\":\"Item Condition\"}]}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Destructable\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"DEST - Header\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Health\"},{\"t\":3,\"p\":1,\"n\":\"DEST Count\"},{\"t\":3,\"p\":1,\"n\":\"VATS Targetable\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":8,\"p\":1,\"n\":\"Stages\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Stage\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"DSTD - Destruction Stage Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Health %\"},{\"t\":3,\"p\":1,\"n\":\"Index\"},{\"t\":3,\"p\":1,\"n\":\"Model Damage Stage\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":3,\"p\":1,\"n\":\"Self Damage per Second\"},{\"t\":3,\"p\":1,\"n\":\"Explosion\"},{\"t\":3,\"p\":1,\"n\":\"Debris\"},{\"t\":3,\"p\":1,\"n\":\"Debris Count\"}]},{\"t\":6,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"DMDL - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"DMDT - Texture Files Hashes\"},{\"t\":7,\"p\":1,\"n\":\"DMDS - Alternate Textures\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"3D Name\"},{\"t\":3,\"p\":1,\"n\":\"New Texture\"},{\"t\":3,\"p\":1,\"n\":\"3D Index\"}]}]}]},{\"p\":1,\"n\":\"DSTF - End Marker\"}]}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DATA - \",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":5,\"p\":1,\"n\":\"Weight\"}]},{\"t\":3,\"p\":1,\"n\":\"SNAM - Sound - Open\"},{\"t\":3,\"p\":1,\"n\":\"QNAM - Sound - Close\"}]},{\"t\":1,\"p\":1,\"n\":\"CPTH - Camera Path\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Conditions\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Condition\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"CTDA - \",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":5,\"p\":1,\"n\":\"Comparison Value - Float\"},{\"t\":3,\"p\":1,\"n\":\"Comparison Value - Global\"},{\"t\":3,\"p\":1,\"n\":\"Function\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":11,\"p\":1,\"n\":\"None\"},{\"t\":3,\"p\":1,\"n\":\"Integer\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":11,\"p\":1,\"n\":\"Variable Name (unused)\"},{\"t\":3,\"p\":1,\"n\":\"Sex\"},{\"t\":3,\"p\":1,\"n\":\"Actor Value\"},{\"t\":3,\"p\":1,\"n\":\"Crime Type\"},{\"t\":3,\"p\":1,\"n\":\"Axis\"},{\"t\":3,\"p\":1,\"n\":\"Quest Stage (unused)\"},{\"t\":3,\"p\":1,\"n\":\"Misc Stat\"},{\"t\":3,\"p\":1,\"n\":\"Alignment\"},{\"t\":3,\"p\":1,\"n\":\"Equip Type\"},{\"t\":3,\"p\":1,\"n\":\"Form Type\"},{\"t\":3,\"p\":1,\"n\":\"Critical Stage\"},{\"t\":3,\"p\":1,\"n\":\"Object Reference\"},{\"t\":3,\"p\":1,\"n\":\"Inventory Object\"},{\"t\":3,\"p\":1,\"n\":\"Actor\"},{\"t\":3,\"p\":1,\"n\":\"Voice Type\"},{\"t\":3,\"p\":1,\"n\":\"Idle\"},{\"t\":3,\"p\":1,\"n\":\"Form List\"},{\"t\":3,\"p\":1,\"n\":\"Quest\"},{\"t\":3,\"p\":1,\"n\":\"Faction\"},{\"t\":3,\"p\":1,\"n\":\"Cell\"},{\"t\":3,\"p\":1,\"n\":\"Class\"},{\"t\":3,\"p\":1,\"n\":\"Race\"},{\"t\":3,\"p\":1,\"n\":\"Actor Base\"},{\"t\":3,\"p\":1,\"n\":\"Global\"},{\"t\":3,\"p\":1,\"n\":\"Weather\"},{\"t\":3,\"p\":1,\"n\":\"Package\"},{\"t\":3,\"p\":1,\"n\":\"Encounter Zone\"},{\"t\":3,\"p\":1,\"n\":\"Perk\"},{\"t\":3,\"p\":1,\"n\":\"Owner\"},{\"t\":3,\"p\":1,\"n\":\"Furniture\"},{\"t\":3,\"p\":1,\"n\":\"Effect Item\"},{\"t\":3,\"p\":1,\"n\":\"Base Effect\"},{\"t\":3,\"p\":1,\"n\":\"Worldspace\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Function\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Param (INVALID)\"},{\"t\":3,\"p\":1,\"n\":\"Referenceable Object\"},{\"t\":3,\"p\":1,\"n\":\"Region\"},{\"t\":3,\"p\":1,\"n\":\"Keyword\"},{\"t\":3,\"p\":1,\"n\":\"Player Action\"},{\"t\":3,\"p\":1,\"n\":\"Casting Type\"},{\"t\":3,\"p\":1,\"n\":\"Shout\"},{\"t\":3,\"p\":1,\"n\":\"Location\"},{\"t\":3,\"p\":1,\"n\":\"Location Ref Type\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"Packdata ID\"},{\"t\":3,\"p\":1,\"n\":\"Association Type\"},{\"t\":3,\"p\":1,\"n\":\"Furniture Anim\"},{\"t\":3,\"p\":1,\"n\":\"Furniture Entry\"},{\"t\":3,\"p\":1,\"n\":\"Scene\"},{\"t\":3,\"p\":1,\"n\":\"Ward State\"},{\"t\":3,\"p\":1,\"n\":\"Event\"},{\"t\":3,\"p\":1,\"n\":\"Event Data\"},{\"t\":3,\"p\":1,\"n\":\"Quest Stage\"},{\"t\":3,\"p\":1,\"n\":\"Weapon\"},{\"t\":3,\"p\":1,\"n\":\"Weapon List\"},{\"t\":3,\"p\":1,\"n\":\"Target\"},{\"t\":3,\"p\":1,\"n\":\"Target List\"},{\"t\":3,\"p\":1,\"n\":\"Target Part\"},{\"t\":3,\"p\":1,\"n\":\"VATS Action\"},{\"t\":3,\"p\":1,\"n\":\"Critical Effect\"},{\"t\":3,\"p\":1,\"n\":\"Critical Effect List\"},{\"t\":3,\"p\":1,\"n\":\"Weapon Type\"},{\"t\":3,\"p\":1,\"n\":\"Projectile Type\"},{\"t\":3,\"p\":1,\"n\":\"Delivery Type\"},{\"t\":3,\"p\":1,\"n\":\"Run On\"},{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":3,\"p\":1,\"n\":\"Parameter #3\"}]},{\"t\":2,\"p\":1,\"n\":\"CIS1 - Parameter #1\"},{\"t\":2,\"p\":1,\"n\":\"CIS2 - Parameter #2\"}]}]},{\"t\":7,\"p\":1,\"n\":\"ANAM - Related Camera Paths\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Related Camera Path\"}]},{\"t\":3,\"p\":1,\"n\":\"DATA - Camera Zoom\"},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Camera Shots\",\"d\":1,\"c\":[{\"t\":3,\"p\":1,\"n\":\"SNAM - Camera Shot\"}]}]},{\"t\":1,\"p\":1,\"n\":\"CSTY - Combat Style\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"CSGD - General\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Offensive Mult\"},{\"t\":5,\"p\":1,\"n\":\"Defensive Mult\"},{\"t\":5,\"p\":1,\"n\":\"Group Offensive Mult\"},{\"t\":5,\"p\":1,\"n\":\"Equipment Score Mult - Melee\"},{\"t\":5,\"p\":1,\"n\":\"Equipment Score Mult - Magic\"},{\"t\":5,\"p\":1,\"n\":\"Equipment Score Mult - Ranged\"},{\"t\":5,\"p\":1,\"n\":\"Equipment Score Mult - Shout\"},{\"t\":5,\"p\":1,\"n\":\"Equipment Score Mult - Unarmed\"},{\"t\":5,\"p\":1,\"n\":\"Equipment Score Mult - Staff\"},{\"t\":5,\"p\":1,\"n\":\"Avoid Threat Chance\"}]},{\"t\":11,\"n\":\"CSMD - Unknown\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"CSME - Melee\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Attack Staggered Mult\"},{\"t\":5,\"p\":1,\"n\":\"Power Attack Staggered Mult\"},{\"t\":5,\"p\":1,\"n\":\"Power Attack Blocking Mult\"},{\"t\":5,\"p\":1,\"n\":\"Bash Mult\"},{\"t\":5,\"p\":1,\"n\":\"Bash Recoil Mult\"},{\"t\":5,\"p\":1,\"n\":\"Bash Attack Mult\"},{\"t\":5,\"p\":1,\"n\":\"Bash Power Attack Mult\"},{\"t\":5,\"p\":1,\"n\":\"Special Attack Mult\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"CSCR - Close Range\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Circle Mult\"},{\"t\":5,\"p\":1,\"n\":\"Fallback Mult\"},{\"t\":5,\"p\":1,\"n\":\"Flank Distance\"},{\"t\":5,\"p\":1,\"n\":\"Stalk Time\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"CSLR - Long Range\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Strafe Mult\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"CSFL - Flight\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Hover Chance\"},{\"t\":5,\"p\":1,\"n\":\"Dive Bomb Chance\"},{\"t\":5,\"p\":1,\"n\":\"Ground Attack Chance\"},{\"t\":5,\"p\":1,\"n\":\"Hover Time\"},{\"t\":5,\"p\":1,\"n\":\"Ground Attack Time\"},{\"t\":5,\"p\":1,\"n\":\"Perch Attack Chance\"},{\"t\":5,\"p\":1,\"n\":\"Perch Attack Time\"},{\"t\":5,\"p\":1,\"n\":\"Flying Attack Chance\"}]},{\"t\":3,\"p\":1,\"n\":\"DATA - Flags\"}]},{\"t\":1,\"p\":1,\"n\":\"DEBR - Debris\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Models\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"DATA - Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Percentage\"},{\"t\":2,\"p\":1,\"n\":\"Model Filename\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"}]},{\"t\":11,\"p\":1,\"n\":\"MODT - Texture Files Hashes\"}]}]}]},{\"t\":1,\"p\":1,\"n\":\"DIAL - Dialog Topic\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":5,\"p\":1,\"n\":\"PNAM - Priority\"},{\"t\":3,\"p\":1,\"n\":\"BNAM - Branch\"},{\"t\":3,\"p\":1,\"n\":\"QNAM - Quest\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DATA - Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Topic Flags\"},{\"t\":3,\"p\":1,\"n\":\"Category\"},{\"t\":3,\"p\":1,\"n\":\"Subtype\"}]},{\"t\":2,\"p\":1,\"n\":\"SNAM - Subtype Name\"},{\"t\":3,\"p\":1,\"n\":\"TIFC - Info Count\"}]},{\"t\":1,\"p\":1,\"n\":\"DLBR - Dialog Branch\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":3,\"p\":1,\"n\":\"QNAM - Quest\"},{\"t\":3,\"n\":\"TNAM - Unknown\"},{\"t\":3,\"p\":1,\"n\":\"DNAM - Flags\"},{\"t\":3,\"p\":1,\"n\":\"SNAM - Starting Topic\"}]},{\"t\":1,\"p\":1,\"n\":\"DLVW - Dialog View\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":3,\"p\":1,\"n\":\"QNAM - Quest\"},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Branches\",\"d\":1,\"c\":[{\"t\":3,\"p\":1,\"n\":\"BNAM - Branch\"}]},{\"t\":8,\"n\":\"Unknown TNAM\",\"c\":[{\"t\":6,\"n\":\"Unknown\",\"c\":[{\"t\":11,\"n\":\"TNAM - Unknown\"}]}]},{\"t\":11,\"n\":\"ENAM - Unknown\"},{\"t\":11,\"n\":\"DNAM - Unknown\"}]},{\"t\":1,\"n\":\"DOBJ - Default Object Manager\",\"c\":[{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":7,\"n\":\"DNAM - Objects\",\"c\":[{\"t\":6,\"n\":\"Object\",\"c\":[{\"t\":3,\"n\":\"Use\"},{\"t\":3,\"n\":\"Object ID\"}]}]}]},{\"t\":1,\"p\":1,\"n\":\"DOOR - Door\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"VMAD - Virtual Machine Adapter\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Version\"},{\"t\":3,\"p\":1,\"n\":\"Object Format\"},{\"t\":7,\"p\":1,\"n\":\"Scripts\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Script\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"scriptName\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":7,\"p\":1,\"n\":\"Properties\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Property\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"propertyName\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]},{\"t\":2,\"p\":1,\"n\":\"String\"},{\"t\":3,\"p\":1,\"n\":\"Int32\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":3,\"p\":1,\"n\":\"Bool\"},{\"t\":7,\"p\":1,\"n\":\"Array of Object\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]}]},{\"t\":7,\"p\":1,\"n\":\"Array of String\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Int32\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Float\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Bool\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]}]}]}]}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"X1\"},{\"t\":3,\"p\":1,\"n\":\"Y1\"},{\"t\":3,\"p\":1,\"n\":\"Z1\"},{\"t\":3,\"p\":1,\"n\":\"X2\"},{\"t\":3,\"p\":1,\"n\":\"Y2\"},{\"t\":3,\"p\":1,\"n\":\"Z2\"}]},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"MODT - Texture Files Hashes\"},{\"t\":7,\"p\":1,\"n\":\"MODS - Alternate Textures\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"3D Name\"},{\"t\":3,\"p\":1,\"n\":\"New Texture\"},{\"t\":3,\"p\":1,\"n\":\"3D Index\"}]}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Destructable\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"DEST - Header\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Health\"},{\"t\":3,\"p\":1,\"n\":\"DEST Count\"},{\"t\":3,\"p\":1,\"n\":\"VATS Targetable\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":8,\"p\":1,\"n\":\"Stages\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Stage\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"DSTD - Destruction Stage Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Health %\"},{\"t\":3,\"p\":1,\"n\":\"Index\"},{\"t\":3,\"p\":1,\"n\":\"Model Damage Stage\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":3,\"p\":1,\"n\":\"Self Damage per Second\"},{\"t\":3,\"p\":1,\"n\":\"Explosion\"},{\"t\":3,\"p\":1,\"n\":\"Debris\"},{\"t\":3,\"p\":1,\"n\":\"Debris Count\"}]},{\"t\":6,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"DMDL - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"DMDT - Texture Files Hashes\"},{\"t\":7,\"p\":1,\"n\":\"DMDS - Alternate Textures\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"3D Name\"},{\"t\":3,\"p\":1,\"n\":\"New Texture\"},{\"t\":3,\"p\":1,\"n\":\"3D Index\"}]}]}]},{\"p\":1,\"n\":\"DSTF - End Marker\"}]}]}]},{\"t\":3,\"p\":1,\"n\":\"SNAM - Sound - Open\"},{\"t\":3,\"p\":1,\"n\":\"ANAM - Sound - Close\"},{\"t\":3,\"p\":1,\"n\":\"BNAM - Sound - Loop\"},{\"t\":3,\"p\":1,\"n\":\"FNAM - Flags\"}]},{\"t\":1,\"p\":1,\"n\":\"DUAL - Dual Cast Data\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"X1\"},{\"t\":3,\"p\":1,\"n\":\"Y1\"},{\"t\":3,\"p\":1,\"n\":\"Z1\"},{\"t\":3,\"p\":1,\"n\":\"X2\"},{\"t\":3,\"p\":1,\"n\":\"Y2\"},{\"t\":3,\"p\":1,\"n\":\"Z2\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DATA - Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Projectile\"},{\"t\":3,\"p\":1,\"n\":\"Explosion\"},{\"t\":3,\"p\":1,\"n\":\"Effect Shader\"},{\"t\":3,\"p\":1,\"n\":\"Hit Effect Art\"},{\"t\":3,\"p\":1,\"n\":\"Impact Data Set\"},{\"t\":3,\"p\":1,\"n\":\"Inherit Scale\"}]}]},{\"t\":1,\"p\":1,\"n\":\"ECZN - Encounter Zone\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DATA - \",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Owner\"},{\"t\":3,\"p\":1,\"n\":\"Location\"},{\"t\":3,\"p\":1,\"n\":\"Rank\"},{\"t\":3,\"p\":1,\"n\":\"Min Level\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":3,\"p\":1,\"n\":\"Max Level\"}]}]},{\"t\":1,\"p\":1,\"n\":\"EFSH - Effect Shader\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"p\":1,\"n\":\"ICON - Fill Texture\"},{\"t\":2,\"p\":1,\"n\":\"ICO2 - Particle Shader Texture\"},{\"t\":2,\"p\":1,\"n\":\"NAM7 - Holes Texture\"},{\"t\":2,\"p\":1,\"n\":\"NAM8 - Membrane Palette Texture\"},{\"t\":2,\"p\":1,\"n\":\"NAM9 - Particle Palette Texture\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DATA - \",\"c\":[{\"t\":11,\"n\":\"Unknown\"},{\"t\":3,\"p\":1,\"n\":\"Membrane Shader - Source Blend Mode\"},{\"t\":3,\"p\":1,\"n\":\"Membrane Shader - Blend Operation\"},{\"t\":3,\"p\":1,\"n\":\"Membrane Shader - Z Test Function\"},{\"t\":6,\"p\":1,\"n\":\"Fill\\/Texture Effect - Color Key 1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":5,\"p\":1,\"n\":\"Fill\\/Texture Effect - Alpha Fade In Time\"},{\"t\":5,\"p\":1,\"n\":\"Fill\\/Texture Effect - Full Alpha Time\"},{\"t\":5,\"p\":1,\"n\":\"Fill\\/Texture Effect - Alpha Fade Out Time\"},{\"t\":5,\"p\":1,\"n\":\"Fill\\/Texture Effect - Presistent Alpha Ratio\"},{\"t\":5,\"p\":1,\"n\":\"Fill\\/Texture Effect - Alpha Pulse Amplitude\"},{\"t\":5,\"p\":1,\"n\":\"Fill\\/Texture Effect - Alpha Pulse Frequency\"},{\"t\":5,\"p\":1,\"n\":\"Fill\\/Texture Effect - Texture Animation Speed (U)\"},{\"t\":5,\"p\":1,\"n\":\"Fill\\/Texture Effect - Texture Animation Speed (V)\"},{\"t\":5,\"p\":1,\"n\":\"Edge Effect - Fall Off\"},{\"t\":6,\"p\":1,\"n\":\"Edge Effect - Color\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":5,\"p\":1,\"n\":\"Edge Effect - Alpha Fade In Time\"},{\"t\":5,\"p\":1,\"n\":\"Edge Effect - Full Alpha Time\"},{\"t\":5,\"p\":1,\"n\":\"Edge Effect - Alpha Fade Out Time\"},{\"t\":5,\"p\":1,\"n\":\"Edge Effect - Persistent Alpha Ratio\"},{\"t\":5,\"p\":1,\"n\":\"Edge Effect - Alpha Pulse Amplitude\"},{\"t\":5,\"p\":1,\"n\":\"Edge Effect - Alpha Pulse Frequency\"},{\"t\":5,\"p\":1,\"n\":\"Fill\\/Texture Effect - Full Alpha Ratio\"},{\"t\":5,\"p\":1,\"n\":\"Edge Effect - Full Alpha Ratio\"},{\"t\":3,\"p\":1,\"n\":\"Membrane Shader - Dest Blend Mode\"},{\"t\":3,\"p\":1,\"n\":\"Particle Shader - Source Blend Mode\"},{\"t\":3,\"p\":1,\"n\":\"Particle Shader - Blend Operation\"},{\"t\":3,\"p\":1,\"n\":\"Particle Shader - Z Test Function\"},{\"t\":3,\"p\":1,\"n\":\"Particle Shader - Dest Blend Mode\"},{\"t\":5,\"p\":1,\"n\":\"Particle Shader - Particle Birth Ramp Up Time\"},{\"t\":5,\"p\":1,\"n\":\"Particle Shader - Full Particle Birth Time\"},{\"t\":5,\"p\":1,\"n\":\"Particle Shader - Particle Birth Ramp Down Time\"},{\"t\":5,\"p\":1,\"n\":\"Particle Shader - Full Particle Birth Ratio\"},{\"t\":5,\"p\":1,\"n\":\"Particle Shader - Persistant Particle Count\"},{\"t\":5,\"p\":1,\"n\":\"Particle Shader - Particle Lifetime\"},{\"t\":5,\"p\":1,\"n\":\"Particle Shader - Particle Lifetime +\\/-\"},{\"t\":5,\"p\":1,\"n\":\"Particle Shader - Initial Speed Along Normal\"},{\"t\":5,\"p\":1,\"n\":\"Particle Shader - Acceleration Along Normal\"},{\"t\":5,\"p\":1,\"n\":\"Particle Shader - Initial Velocity #1\"},{\"t\":5,\"p\":1,\"n\":\"Particle Shader - Initial Velocity #2\"},{\"t\":5,\"p\":1,\"n\":\"Particle Shader - Initial Velocity #3\"},{\"t\":5,\"p\":1,\"n\":\"Particle Shader - Acceleration #1\"},{\"t\":5,\"p\":1,\"n\":\"Particle Shader - Acceleration #2\"},{\"t\":5,\"p\":1,\"n\":\"Particle Shader - Acceleration #3\"},{\"t\":5,\"p\":1,\"n\":\"Particle Shader - Scale Key 1\"},{\"t\":5,\"p\":1,\"n\":\"Particle Shader - Scale Key 2\"},{\"t\":5,\"p\":1,\"n\":\"Particle Shader - Scale Key 1 Time\"},{\"t\":5,\"p\":1,\"n\":\"Particle Shader - Scale Key 2 Time\"},{\"t\":6,\"p\":1,\"n\":\"Color Key 1 - Color\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Color Key 2 - Color\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Color Key 3 - Color\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":5,\"p\":1,\"n\":\"Color Key 1 - Color Alpha\"},{\"t\":5,\"p\":1,\"n\":\"Color Key 2 - Color Alpha\"},{\"t\":5,\"p\":1,\"n\":\"Color Key 3 - Color Alpha\"},{\"t\":5,\"p\":1,\"n\":\"Color Key 1 - Color Key Time\"},{\"t\":5,\"p\":1,\"n\":\"Color Key 2 - Color Key Time\"},{\"t\":5,\"p\":1,\"n\":\"Color Key 3 - Color Key Time\"},{\"t\":5,\"p\":1,\"n\":\"Particle Shader - Initial Speed Along Normal +\\/-\"},{\"t\":5,\"p\":1,\"n\":\"Particle Shader - Initial Rotation (deg)\"},{\"t\":5,\"p\":1,\"n\":\"Particle Shader - Initial Rotation (deg) +\\/-\"},{\"t\":5,\"p\":1,\"n\":\"Particle Shader - Rotation Speed (deg\\/sec)\"},{\"t\":5,\"p\":1,\"n\":\"Particle Shader - Rotation Speed (deg\\/sec) +\\/-\"},{\"t\":3,\"p\":1,\"n\":\"Addon Models\"},{\"t\":5,\"p\":1,\"n\":\"Holes - Start Time\"},{\"t\":5,\"p\":1,\"n\":\"Holes - End Time\"},{\"t\":5,\"p\":1,\"n\":\"Holes - Start Val\"},{\"t\":5,\"p\":1,\"n\":\"Holes - End Val\"},{\"t\":5,\"p\":1,\"n\":\"Edge Width (alpha units)\"},{\"t\":6,\"p\":1,\"n\":\"Edge Color\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":5,\"p\":1,\"n\":\"Explosion Wind Speed\"},{\"t\":3,\"p\":1,\"n\":\"Texture Count U\"},{\"t\":3,\"p\":1,\"n\":\"Texture Count V\"},{\"t\":5,\"p\":1,\"n\":\"Addon Models - Fade In Time\"},{\"t\":5,\"p\":1,\"n\":\"Addon Models - Fade Out Time\"},{\"t\":5,\"p\":1,\"n\":\"Addon Models - Scale Start\"},{\"t\":5,\"p\":1,\"n\":\"Addon Models - Scale End\"},{\"t\":5,\"p\":1,\"n\":\"Addon Models - Scale In Time\"},{\"t\":5,\"p\":1,\"n\":\"Addon Models - Scale Out Time\"},{\"t\":3,\"p\":1,\"n\":\"Ambient Sound\"},{\"t\":6,\"p\":1,\"n\":\"Fill\\/Texture Effect - Color Key 2\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Fill\\/Texture Effect - Color Key 3\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Fill\\/Texture Effect - Color Key Scale\\/Time\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Color Key 1 - Scale\"},{\"t\":5,\"p\":1,\"n\":\"Color Key 2 - Scale\"},{\"t\":5,\"p\":1,\"n\":\"Color Key 3 - Scale\"},{\"t\":5,\"p\":1,\"n\":\"Color Key 1 - Time\"},{\"t\":5,\"p\":1,\"n\":\"Color Key 2 - Time\"},{\"t\":5,\"p\":1,\"n\":\"Color Key 3 - Time\"}]},{\"t\":5,\"p\":1,\"n\":\"Color Scale\"},{\"t\":5,\"p\":1,\"n\":\"Birth Position Offset\"},{\"t\":5,\"p\":1,\"n\":\"Birth Position Offset Range +\\/-\"},{\"t\":6,\"p\":1,\"n\":\"Particle Shader Animated\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Start Frame\"},{\"t\":3,\"p\":1,\"n\":\"Start Frame Variation\"},{\"t\":3,\"p\":1,\"n\":\"End Frame\"},{\"t\":3,\"p\":1,\"n\":\"Loop Start Frame\"},{\"t\":3,\"p\":1,\"n\":\"Loop Start Variation\"},{\"t\":3,\"p\":1,\"n\":\"Frame Count\"},{\"t\":3,\"p\":1,\"n\":\"Frame Count Variation\"}]},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":5,\"p\":1,\"n\":\"Fill\\/Texture Effect - Texture Scale (U)\"},{\"t\":5,\"p\":1,\"n\":\"Fill\\/Texture Effect - Texture Scale (V)\"},{\"t\":3,\"p\":1,\"n\":\"Scene Graph Emit Depth Limit (unused)\"}]}]},{\"t\":1,\"p\":1,\"n\":\"ENCH - Object Effect\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"X1\"},{\"t\":3,\"p\":1,\"n\":\"Y1\"},{\"t\":3,\"p\":1,\"n\":\"Z1\"},{\"t\":3,\"p\":1,\"n\":\"X2\"},{\"t\":3,\"p\":1,\"n\":\"Y2\"},{\"t\":3,\"p\":1,\"n\":\"Z2\"}]},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"ENIT - Effect Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Enchantment Cost\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":3,\"p\":1,\"n\":\"Cast Type\"},{\"t\":3,\"p\":1,\"n\":\"Enchantment Amount\"},{\"t\":3,\"p\":1,\"n\":\"Target Type\"},{\"t\":3,\"p\":1,\"n\":\"Enchant Type\"},{\"t\":5,\"p\":1,\"n\":\"Charge Time\"},{\"t\":3,\"p\":1,\"n\":\"Base Enchantment\"},{\"t\":3,\"p\":1,\"n\":\"Worn Restrictions\"}]},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Effects\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Effect\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"EFID - Base Effect\"},{\"t\":6,\"p\":1,\"n\":\"EFIT - \",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Magnitude\"},{\"t\":3,\"p\":1,\"n\":\"Area\"},{\"t\":3,\"p\":1,\"n\":\"Duration\"}]},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Conditions\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Condition\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"CTDA - \",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":5,\"p\":1,\"n\":\"Comparison Value - Float\"},{\"t\":3,\"p\":1,\"n\":\"Comparison Value - Global\"},{\"t\":3,\"p\":1,\"n\":\"Function\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":11,\"p\":1,\"n\":\"None\"},{\"t\":3,\"p\":1,\"n\":\"Integer\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":11,\"p\":1,\"n\":\"Variable Name (unused)\"},{\"t\":3,\"p\":1,\"n\":\"Sex\"},{\"t\":3,\"p\":1,\"n\":\"Actor Value\"},{\"t\":3,\"p\":1,\"n\":\"Crime Type\"},{\"t\":3,\"p\":1,\"n\":\"Axis\"},{\"t\":3,\"p\":1,\"n\":\"Quest Stage (unused)\"},{\"t\":3,\"p\":1,\"n\":\"Misc Stat\"},{\"t\":3,\"p\":1,\"n\":\"Alignment\"},{\"t\":3,\"p\":1,\"n\":\"Equip Type\"},{\"t\":3,\"p\":1,\"n\":\"Form Type\"},{\"t\":3,\"p\":1,\"n\":\"Critical Stage\"},{\"t\":3,\"p\":1,\"n\":\"Object Reference\"},{\"t\":3,\"p\":1,\"n\":\"Inventory Object\"},{\"t\":3,\"p\":1,\"n\":\"Actor\"},{\"t\":3,\"p\":1,\"n\":\"Voice Type\"},{\"t\":3,\"p\":1,\"n\":\"Idle\"},{\"t\":3,\"p\":1,\"n\":\"Form List\"},{\"t\":3,\"p\":1,\"n\":\"Quest\"},{\"t\":3,\"p\":1,\"n\":\"Faction\"},{\"t\":3,\"p\":1,\"n\":\"Cell\"},{\"t\":3,\"p\":1,\"n\":\"Class\"},{\"t\":3,\"p\":1,\"n\":\"Race\"},{\"t\":3,\"p\":1,\"n\":\"Actor Base\"},{\"t\":3,\"p\":1,\"n\":\"Global\"},{\"t\":3,\"p\":1,\"n\":\"Weather\"},{\"t\":3,\"p\":1,\"n\":\"Package\"},{\"t\":3,\"p\":1,\"n\":\"Encounter Zone\"},{\"t\":3,\"p\":1,\"n\":\"Perk\"},{\"t\":3,\"p\":1,\"n\":\"Owner\"},{\"t\":3,\"p\":1,\"n\":\"Furniture\"},{\"t\":3,\"p\":1,\"n\":\"Effect Item\"},{\"t\":3,\"p\":1,\"n\":\"Base Effect\"},{\"t\":3,\"p\":1,\"n\":\"Worldspace\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Function\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Param (INVALID)\"},{\"t\":3,\"p\":1,\"n\":\"Referenceable Object\"},{\"t\":3,\"p\":1,\"n\":\"Region\"},{\"t\":3,\"p\":1,\"n\":\"Keyword\"},{\"t\":3,\"p\":1,\"n\":\"Player Action\"},{\"t\":3,\"p\":1,\"n\":\"Casting Type\"},{\"t\":3,\"p\":1,\"n\":\"Shout\"},{\"t\":3,\"p\":1,\"n\":\"Location\"},{\"t\":3,\"p\":1,\"n\":\"Location Ref Type\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"Packdata ID\"},{\"t\":3,\"p\":1,\"n\":\"Association Type\"},{\"t\":3,\"p\":1,\"n\":\"Furniture Anim\"},{\"t\":3,\"p\":1,\"n\":\"Furniture Entry\"},{\"t\":3,\"p\":1,\"n\":\"Scene\"},{\"t\":3,\"p\":1,\"n\":\"Ward State\"},{\"t\":3,\"p\":1,\"n\":\"Event\"},{\"t\":3,\"p\":1,\"n\":\"Event Data\"},{\"t\":3,\"p\":1,\"n\":\"Quest Stage\"},{\"t\":3,\"p\":1,\"n\":\"Weapon\"},{\"t\":3,\"p\":1,\"n\":\"Weapon List\"},{\"t\":3,\"p\":1,\"n\":\"Target\"},{\"t\":3,\"p\":1,\"n\":\"Target List\"},{\"t\":3,\"p\":1,\"n\":\"Target Part\"},{\"t\":3,\"p\":1,\"n\":\"VATS Action\"},{\"t\":3,\"p\":1,\"n\":\"Critical Effect\"},{\"t\":3,\"p\":1,\"n\":\"Critical Effect List\"},{\"t\":3,\"p\":1,\"n\":\"Weapon Type\"},{\"t\":3,\"p\":1,\"n\":\"Projectile Type\"},{\"t\":3,\"p\":1,\"n\":\"Delivery Type\"},{\"t\":3,\"p\":1,\"n\":\"Run On\"},{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":3,\"p\":1,\"n\":\"Parameter #3\"}]},{\"t\":2,\"p\":1,\"n\":\"CIS1 - Parameter #1\"},{\"t\":2,\"p\":1,\"n\":\"CIS2 - Parameter #2\"}]}]}]}]}]},{\"t\":1,\"p\":1,\"n\":\"EQUP - Equip Type\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":7,\"p\":1,\"n\":\"PNAM - Slot Parents\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Can Be Equipped\"}]},{\"t\":3,\"p\":1,\"n\":\"DATA - Use All Parents\"}]},{\"t\":1,\"p\":1,\"n\":\"EXPL - Explosion\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"VMAD - Virtual Machine Adapter\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Version\"},{\"t\":3,\"p\":1,\"n\":\"Object Format\"},{\"t\":7,\"p\":1,\"n\":\"Scripts\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Script\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"scriptName\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":7,\"p\":1,\"n\":\"Properties\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Property\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"propertyName\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]},{\"t\":2,\"p\":1,\"n\":\"String\"},{\"t\":3,\"p\":1,\"n\":\"Int32\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":3,\"p\":1,\"n\":\"Bool\"},{\"t\":7,\"p\":1,\"n\":\"Array of Object\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]}]},{\"t\":7,\"p\":1,\"n\":\"Array of String\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Int32\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Float\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Bool\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]}]}]}]}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"X1\"},{\"t\":3,\"p\":1,\"n\":\"Y1\"},{\"t\":3,\"p\":1,\"n\":\"Z1\"},{\"t\":3,\"p\":1,\"n\":\"X2\"},{\"t\":3,\"p\":1,\"n\":\"Y2\"},{\"t\":3,\"p\":1,\"n\":\"Z2\"}]},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"MODT - Texture Files Hashes\"},{\"t\":7,\"p\":1,\"n\":\"MODS - Alternate Textures\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"3D Name\"},{\"t\":3,\"p\":1,\"n\":\"New Texture\"},{\"t\":3,\"p\":1,\"n\":\"3D Index\"}]}]}]},{\"t\":3,\"p\":1,\"n\":\"EITM - Object Effect\"},{\"t\":3,\"p\":1,\"n\":\"MNAM - Image Space Modifier\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DATA - Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Light\"},{\"t\":3,\"p\":1,\"n\":\"Sound 1\"},{\"t\":3,\"p\":1,\"n\":\"Sound 2\"},{\"t\":3,\"p\":1,\"n\":\"Impact Data Set\"},{\"t\":3,\"p\":1,\"n\":\"Placed Object\"},{\"t\":3,\"p\":1,\"n\":\"Spawn Projectile\"},{\"t\":5,\"p\":1,\"n\":\"Force\"},{\"t\":5,\"p\":1,\"n\":\"Damage\"},{\"t\":5,\"p\":1,\"n\":\"Radius\"},{\"t\":5,\"p\":1,\"n\":\"IS Radius\"},{\"t\":5,\"p\":1,\"n\":\"Vertical Offset Mult\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":3,\"p\":1,\"n\":\"Sound Level\"}]}]},{\"t\":1,\"p\":1,\"n\":\"EYES - Eyes\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":2,\"p\":1,\"n\":\"ICON - Texture\"},{\"t\":3,\"p\":1,\"n\":\"DATA - Flags\"}]},{\"t\":1,\"p\":1,\"n\":\"FACT - Faction\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Relations\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"XNAM - Relation\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Faction\"},{\"t\":3,\"p\":1,\"n\":\"Modifier\"},{\"t\":3,\"p\":1,\"n\":\"Group Combat Reaction\"}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DATA - Flags\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Flags\"}]},{\"t\":3,\"p\":1,\"n\":\"JAIL - Exterior Jail Marker\"},{\"t\":3,\"p\":1,\"n\":\"WAIT - Follower Wait Marker\"},{\"t\":3,\"p\":1,\"n\":\"STOL - Stolen Goods Container\"},{\"t\":3,\"p\":1,\"n\":\"PLCN - Player Inventory Container\"},{\"t\":3,\"p\":1,\"n\":\"CRGR - Shared Crime Faction List\"},{\"t\":3,\"p\":1,\"n\":\"JOUT - Jail Outfit\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"CRVA - Crime Values\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Arrest\"},{\"t\":3,\"p\":1,\"n\":\"Attack On Sight\"},{\"t\":3,\"p\":1,\"n\":\"Murder\"},{\"t\":3,\"p\":1,\"n\":\"Assault\"},{\"t\":3,\"p\":1,\"n\":\"Trespass\"},{\"t\":3,\"p\":1,\"n\":\"Pickpocket\"},{\"t\":3,\"n\":\"Unknown\"},{\"t\":5,\"p\":1,\"n\":\"Steal Multiplier\"},{\"t\":3,\"p\":1,\"n\":\"Escape\"},{\"t\":3,\"p\":1,\"n\":\"Werewolf\"}]},{\"t\":10,\"p\":1,\"n\":\"Ranks\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Rank\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"RNAM - Rank#\"},{\"t\":2,\"p\":1,\"n\":\"MNAM - Male Title\"},{\"t\":2,\"p\":1,\"n\":\"FNAM - Female Title\"},{\"t\":2,\"n\":\"INAM - Insignia Unused\"}]}]},{\"t\":3,\"p\":1,\"n\":\"VEND - Vendor Buy\\/Sell List\"},{\"t\":3,\"p\":1,\"n\":\"VENC - Merchant Container\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"VENV - Vendor Values\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Start Hour\"},{\"t\":3,\"p\":1,\"n\":\"End Hour\"},{\"t\":3,\"p\":1,\"n\":\"Radius\"},{\"t\":11,\"n\":\"Unknown 1\"},{\"t\":3,\"p\":1,\"n\":\"Only Buys Stolen Items\"},{\"t\":3,\"p\":1,\"n\":\"Not\\/Sell Buy\"},{\"t\":11,\"n\":\"Unknown 2\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"PLVD - Location\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":3,\"p\":1,\"n\":\"Cell\"},{\"t\":11,\"p\":1,\"n\":\"Near Package Start Location\"},{\"t\":11,\"p\":1,\"n\":\"Near Editor Location\"},{\"t\":3,\"p\":1,\"n\":\"Object ID\"},{\"t\":3,\"p\":1,\"n\":\"Object Type\"},{\"t\":3,\"p\":1,\"n\":\"Keyword\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":3,\"p\":1,\"n\":\"Radius\"}]},{\"t\":3,\"n\":\"CITC - Condition Count\"},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Conditions\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Condition\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"CTDA - \",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":5,\"p\":1,\"n\":\"Comparison Value - Float\"},{\"t\":3,\"p\":1,\"n\":\"Comparison Value - Global\"},{\"t\":3,\"p\":1,\"n\":\"Function\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":11,\"p\":1,\"n\":\"None\"},{\"t\":3,\"p\":1,\"n\":\"Integer\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":11,\"p\":1,\"n\":\"Variable Name (unused)\"},{\"t\":3,\"p\":1,\"n\":\"Sex\"},{\"t\":3,\"p\":1,\"n\":\"Actor Value\"},{\"t\":3,\"p\":1,\"n\":\"Crime Type\"},{\"t\":3,\"p\":1,\"n\":\"Axis\"},{\"t\":3,\"p\":1,\"n\":\"Quest Stage (unused)\"},{\"t\":3,\"p\":1,\"n\":\"Misc Stat\"},{\"t\":3,\"p\":1,\"n\":\"Alignment\"},{\"t\":3,\"p\":1,\"n\":\"Equip Type\"},{\"t\":3,\"p\":1,\"n\":\"Form Type\"},{\"t\":3,\"p\":1,\"n\":\"Critical Stage\"},{\"t\":3,\"p\":1,\"n\":\"Object Reference\"},{\"t\":3,\"p\":1,\"n\":\"Inventory Object\"},{\"t\":3,\"p\":1,\"n\":\"Actor\"},{\"t\":3,\"p\":1,\"n\":\"Voice Type\"},{\"t\":3,\"p\":1,\"n\":\"Idle\"},{\"t\":3,\"p\":1,\"n\":\"Form List\"},{\"t\":3,\"p\":1,\"n\":\"Quest\"},{\"t\":3,\"p\":1,\"n\":\"Faction\"},{\"t\":3,\"p\":1,\"n\":\"Cell\"},{\"t\":3,\"p\":1,\"n\":\"Class\"},{\"t\":3,\"p\":1,\"n\":\"Race\"},{\"t\":3,\"p\":1,\"n\":\"Actor Base\"},{\"t\":3,\"p\":1,\"n\":\"Global\"},{\"t\":3,\"p\":1,\"n\":\"Weather\"},{\"t\":3,\"p\":1,\"n\":\"Package\"},{\"t\":3,\"p\":1,\"n\":\"Encounter Zone\"},{\"t\":3,\"p\":1,\"n\":\"Perk\"},{\"t\":3,\"p\":1,\"n\":\"Owner\"},{\"t\":3,\"p\":1,\"n\":\"Furniture\"},{\"t\":3,\"p\":1,\"n\":\"Effect Item\"},{\"t\":3,\"p\":1,\"n\":\"Base Effect\"},{\"t\":3,\"p\":1,\"n\":\"Worldspace\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Function\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Param (INVALID)\"},{\"t\":3,\"p\":1,\"n\":\"Referenceable Object\"},{\"t\":3,\"p\":1,\"n\":\"Region\"},{\"t\":3,\"p\":1,\"n\":\"Keyword\"},{\"t\":3,\"p\":1,\"n\":\"Player Action\"},{\"t\":3,\"p\":1,\"n\":\"Casting Type\"},{\"t\":3,\"p\":1,\"n\":\"Shout\"},{\"t\":3,\"p\":1,\"n\":\"Location\"},{\"t\":3,\"p\":1,\"n\":\"Location Ref Type\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"Packdata ID\"},{\"t\":3,\"p\":1,\"n\":\"Association Type\"},{\"t\":3,\"p\":1,\"n\":\"Furniture Anim\"},{\"t\":3,\"p\":1,\"n\":\"Furniture Entry\"},{\"t\":3,\"p\":1,\"n\":\"Scene\"},{\"t\":3,\"p\":1,\"n\":\"Ward State\"},{\"t\":3,\"p\":1,\"n\":\"Event\"},{\"t\":3,\"p\":1,\"n\":\"Event Data\"},{\"t\":3,\"p\":1,\"n\":\"Quest Stage\"},{\"t\":3,\"p\":1,\"n\":\"Weapon\"},{\"t\":3,\"p\":1,\"n\":\"Weapon List\"},{\"t\":3,\"p\":1,\"n\":\"Target\"},{\"t\":3,\"p\":1,\"n\":\"Target List\"},{\"t\":3,\"p\":1,\"n\":\"Target Part\"},{\"t\":3,\"p\":1,\"n\":\"VATS Action\"},{\"t\":3,\"p\":1,\"n\":\"Critical Effect\"},{\"t\":3,\"p\":1,\"n\":\"Critical Effect List\"},{\"t\":3,\"p\":1,\"n\":\"Weapon Type\"},{\"t\":3,\"p\":1,\"n\":\"Projectile Type\"},{\"t\":3,\"p\":1,\"n\":\"Delivery Type\"},{\"t\":3,\"p\":1,\"n\":\"Run On\"},{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":3,\"p\":1,\"n\":\"Parameter #3\"}]},{\"t\":2,\"p\":1,\"n\":\"CIS1 - Parameter #1\"},{\"t\":2,\"p\":1,\"n\":\"CIS2 - Parameter #2\"}]}]}]},{\"t\":1,\"p\":1,\"n\":\"FLOR - Flora\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"VMAD - Virtual Machine Adapter\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Version\"},{\"t\":3,\"p\":1,\"n\":\"Object Format\"},{\"t\":7,\"p\":1,\"n\":\"Scripts\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Script\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"scriptName\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":7,\"p\":1,\"n\":\"Properties\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Property\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"propertyName\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]},{\"t\":2,\"p\":1,\"n\":\"String\"},{\"t\":3,\"p\":1,\"n\":\"Int32\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":3,\"p\":1,\"n\":\"Bool\"},{\"t\":7,\"p\":1,\"n\":\"Array of Object\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]}]},{\"t\":7,\"p\":1,\"n\":\"Array of String\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Int32\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Float\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Bool\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]}]}]}]}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"X1\"},{\"t\":3,\"p\":1,\"n\":\"Y1\"},{\"t\":3,\"p\":1,\"n\":\"Z1\"},{\"t\":3,\"p\":1,\"n\":\"X2\"},{\"t\":3,\"p\":1,\"n\":\"Y2\"},{\"t\":3,\"p\":1,\"n\":\"Z2\"}]},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"MODT - Texture Files Hashes\"},{\"t\":7,\"p\":1,\"n\":\"MODS - Alternate Textures\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"3D Name\"},{\"t\":3,\"p\":1,\"n\":\"New Texture\"},{\"t\":3,\"p\":1,\"n\":\"3D Index\"}]}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Destructable\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"DEST - Header\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Health\"},{\"t\":3,\"p\":1,\"n\":\"DEST Count\"},{\"t\":3,\"p\":1,\"n\":\"VATS Targetable\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":8,\"p\":1,\"n\":\"Stages\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Stage\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"DSTD - Destruction Stage Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Health %\"},{\"t\":3,\"p\":1,\"n\":\"Index\"},{\"t\":3,\"p\":1,\"n\":\"Model Damage Stage\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":3,\"p\":1,\"n\":\"Self Damage per Second\"},{\"t\":3,\"p\":1,\"n\":\"Explosion\"},{\"t\":3,\"p\":1,\"n\":\"Debris\"},{\"t\":3,\"p\":1,\"n\":\"Debris Count\"}]},{\"t\":6,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"DMDL - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"DMDT - Texture Files Hashes\"},{\"t\":7,\"p\":1,\"n\":\"DMDS - Alternate Textures\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"3D Name\"},{\"t\":3,\"p\":1,\"n\":\"New Texture\"},{\"t\":3,\"p\":1,\"n\":\"3D Index\"}]}]}]},{\"p\":1,\"n\":\"DSTF - End Marker\"}]}]}]},{\"t\":3,\"n\":\"KSIZ - Keyword Count\"},{\"t\":7,\"p\":1,\"n\":\"KWDA - Keywords\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Keyword\"}]},{\"t\":11,\"n\":\"PNAM - Unknown\"},{\"t\":2,\"p\":1,\"n\":\"RNAM - Activate Text Override\"},{\"t\":11,\"n\":\"FNAM - Unknown\"},{\"t\":3,\"p\":1,\"n\":\"PFIG - Ingredient\"},{\"t\":3,\"p\":1,\"n\":\"SNAM - Sound\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"PFPC - Seasonal ingredient production\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Spring\"},{\"t\":3,\"p\":1,\"n\":\"Summer \"},{\"t\":3,\"p\":1,\"n\":\"Fall\"},{\"t\":3,\"p\":1,\"n\":\"Winter\"}]}]},{\"t\":1,\"p\":1,\"n\":\"FLST - FormID List\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"FormIDs\",\"d\":1,\"c\":[{\"t\":3,\"p\":1,\"n\":\"LNAM - FormID\"}]}]},{\"t\":1,\"p\":1,\"n\":\"FSTP - Footstep\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":3,\"p\":1,\"n\":\"DATA - Impact Data Set\"},{\"t\":2,\"p\":1,\"n\":\"ANAM - Tag\"}]},{\"t\":1,\"p\":1,\"n\":\"FSTS - Footstep Set\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"XCNT - Count\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Walk Forward Sets\"},{\"t\":3,\"p\":1,\"n\":\"Run Forward Sets\"},{\"t\":3,\"p\":1,\"n\":\"Walk Forward Alternate Sets\"},{\"t\":3,\"p\":1,\"n\":\"Run Forward Alternate Sets\"},{\"t\":3,\"p\":1,\"n\":\"Walk Forward Alternate 2 Sets\"}]},{\"t\":7,\"s\":1,\"p\":1,\"n\":\"DATA - Footstep Sets\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Footstep\"}]}]},{\"t\":1,\"p\":1,\"n\":\"FURN - Furniture\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"VMAD - Virtual Machine Adapter\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Version\"},{\"t\":3,\"p\":1,\"n\":\"Object Format\"},{\"t\":7,\"p\":1,\"n\":\"Scripts\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Script\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"scriptName\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":7,\"p\":1,\"n\":\"Properties\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Property\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"propertyName\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]},{\"t\":2,\"p\":1,\"n\":\"String\"},{\"t\":3,\"p\":1,\"n\":\"Int32\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":3,\"p\":1,\"n\":\"Bool\"},{\"t\":7,\"p\":1,\"n\":\"Array of Object\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]}]},{\"t\":7,\"p\":1,\"n\":\"Array of String\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Int32\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Float\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Bool\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]}]}]}]}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"X1\"},{\"t\":3,\"p\":1,\"n\":\"Y1\"},{\"t\":3,\"p\":1,\"n\":\"Z1\"},{\"t\":3,\"p\":1,\"n\":\"X2\"},{\"t\":3,\"p\":1,\"n\":\"Y2\"},{\"t\":3,\"p\":1,\"n\":\"Z2\"}]},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"MODT - Texture Files Hashes\"},{\"t\":7,\"p\":1,\"n\":\"MODS - Alternate Textures\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"3D Name\"},{\"t\":3,\"p\":1,\"n\":\"New Texture\"},{\"t\":3,\"p\":1,\"n\":\"3D Index\"}]}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Destructable\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"DEST - Header\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Health\"},{\"t\":3,\"p\":1,\"n\":\"DEST Count\"},{\"t\":3,\"p\":1,\"n\":\"VATS Targetable\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":8,\"p\":1,\"n\":\"Stages\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Stage\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"DSTD - Destruction Stage Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Health %\"},{\"t\":3,\"p\":1,\"n\":\"Index\"},{\"t\":3,\"p\":1,\"n\":\"Model Damage Stage\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":3,\"p\":1,\"n\":\"Self Damage per Second\"},{\"t\":3,\"p\":1,\"n\":\"Explosion\"},{\"t\":3,\"p\":1,\"n\":\"Debris\"},{\"t\":3,\"p\":1,\"n\":\"Debris Count\"}]},{\"t\":6,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"DMDL - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"DMDT - Texture Files Hashes\"},{\"t\":7,\"p\":1,\"n\":\"DMDS - Alternate Textures\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"3D Name\"},{\"t\":3,\"p\":1,\"n\":\"New Texture\"},{\"t\":3,\"p\":1,\"n\":\"3D Index\"}]}]}]},{\"p\":1,\"n\":\"DSTF - End Marker\"}]}]}]},{\"t\":3,\"n\":\"KSIZ - Keyword Count\"},{\"t\":7,\"p\":1,\"n\":\"KWDA - Keywords\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Keyword\"}]},{\"t\":11,\"n\":\"PNAM - Unknown\"},{\"t\":3,\"p\":1,\"n\":\"FNAM - Flags\"},{\"t\":3,\"p\":1,\"n\":\"KNAM - Interaction Keyword\"},{\"t\":3,\"p\":1,\"n\":\"MNAM - Active Markers \\/ Flags\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"WBDT - Workbench Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Bench Type\"},{\"t\":3,\"p\":1,\"n\":\"Uses Skill\"}]},{\"t\":3,\"p\":1,\"n\":\"NAM1 - Associated Spell\"},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Markers\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Marker\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"ENAM - Marker Index\"},{\"t\":6,\"p\":1,\"n\":\"NAM0 - Disabled Entry Points\",\"c\":[{\"t\":11,\"n\":\"Unknown\"},{\"t\":3,\"p\":1,\"n\":\"Disabled Points\"}]},{\"t\":3,\"p\":1,\"n\":\"FNMK - Marker Keyword\"}]}]},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Marker Entry Points\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"FNPR - Marker\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Entry Points\"}]}]},{\"t\":2,\"p\":1,\"n\":\"XMRK - Model Filename\"}]},{\"t\":1,\"p\":1,\"n\":\"GLOB - Global\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":3,\"p\":1,\"n\":\"FNAM - Type\"},{\"t\":5,\"p\":1,\"n\":\"FLTV - Value\"}]},{\"t\":1,\"p\":1,\"n\":\"GMST - Game Setting\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"p\":1,\"n\":\"Name\"},{\"t\":3,\"p\":1,\"n\":\"Int\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":3,\"p\":1,\"n\":\"Bool\"}]},{\"t\":1,\"p\":1,\"n\":\"GRAS - Grass\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"X1\"},{\"t\":3,\"p\":1,\"n\":\"Y1\"},{\"t\":3,\"p\":1,\"n\":\"Z1\"},{\"t\":3,\"p\":1,\"n\":\"X2\"},{\"t\":3,\"p\":1,\"n\":\"Y2\"},{\"t\":3,\"p\":1,\"n\":\"Z2\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"MODT - Texture Files Hashes\"},{\"t\":7,\"p\":1,\"n\":\"MODS - Alternate Textures\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"3D Name\"},{\"t\":3,\"p\":1,\"n\":\"New Texture\"},{\"t\":3,\"p\":1,\"n\":\"3D Index\"}]}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DATA - \",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Density\"},{\"t\":3,\"p\":1,\"n\":\"Min Slope\"},{\"t\":3,\"p\":1,\"n\":\"Max Slope\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":3,\"p\":1,\"n\":\"Units From Water\"},{\"t\":3,\"p\":1,\"n\":\"Units From Water Type\"},{\"t\":5,\"p\":1,\"n\":\"Position Range\"},{\"t\":5,\"p\":1,\"n\":\"Height Range\"},{\"t\":5,\"p\":1,\"n\":\"Color Range\"},{\"t\":5,\"p\":1,\"n\":\"Wave Period\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"}]}]},{\"t\":1,\"p\":1,\"n\":\"HAIR\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"}]},{\"t\":1,\"p\":1,\"n\":\"HAZD - Hazard\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"X1\"},{\"t\":3,\"p\":1,\"n\":\"Y1\"},{\"t\":3,\"p\":1,\"n\":\"Z1\"},{\"t\":3,\"p\":1,\"n\":\"X2\"},{\"t\":3,\"p\":1,\"n\":\"Y2\"},{\"t\":3,\"p\":1,\"n\":\"Z2\"}]},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"MODT - Texture Files Hashes\"},{\"t\":7,\"p\":1,\"n\":\"MODS - Alternate Textures\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"3D Name\"},{\"t\":3,\"p\":1,\"n\":\"New Texture\"},{\"t\":3,\"p\":1,\"n\":\"3D Index\"}]}]}]},{\"t\":3,\"p\":1,\"n\":\"MNAM - Image Space Modifier\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DATA - Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Limit\"},{\"t\":5,\"p\":1,\"n\":\"Radius\"},{\"t\":5,\"p\":1,\"n\":\"Lifetime\"},{\"t\":5,\"p\":1,\"n\":\"Image Space Radius\"},{\"t\":5,\"p\":1,\"n\":\"Target Interval\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":3,\"p\":1,\"n\":\"Spell\"},{\"t\":3,\"p\":1,\"n\":\"Light\"},{\"t\":3,\"p\":1,\"n\":\"Impact Data Set\"},{\"t\":3,\"p\":1,\"n\":\"Sound\"}]}]},{\"t\":1,\"p\":1,\"n\":\"HDPT - Head Part\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"MODT - Texture Files Hashes\"},{\"t\":7,\"p\":1,\"n\":\"MODS - Alternate Textures\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"3D Name\"},{\"t\":3,\"p\":1,\"n\":\"New Texture\"},{\"t\":3,\"p\":1,\"n\":\"3D Index\"}]}]}]},{\"t\":3,\"p\":1,\"n\":\"DATA - Flags\"},{\"t\":3,\"p\":1,\"n\":\"PNAM - Type\"},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Extra Parts\",\"d\":1,\"c\":[{\"t\":3,\"p\":1,\"n\":\"HNAM - Part\"}]},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Parts\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Part\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"NAM0 - Part Type\"},{\"t\":2,\"p\":1,\"n\":\"NAM1 - Filename\"}]}]},{\"t\":3,\"p\":1,\"n\":\"TNAM - Texture Set\"},{\"t\":3,\"p\":1,\"n\":\"CNAM - Color\"},{\"t\":3,\"p\":1,\"n\":\"RNAM - Valid Races\"}]},{\"t\":1,\"n\":\"IDLE - Idle Animation\",\"c\":[{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":8,\"n\":\"Conditions\",\"c\":[{\"t\":6,\"n\":\"Condition\",\"c\":[{\"t\":6,\"n\":\"CTDA - \",\"c\":[{\"t\":3,\"n\":\"Type\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":5,\"n\":\"Comparison Value - Float\"},{\"t\":3,\"n\":\"Comparison Value - Global\"},{\"t\":3,\"n\":\"Function\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":11,\"n\":\"None\"},{\"t\":3,\"n\":\"Integer\"},{\"t\":5,\"n\":\"Float\"},{\"t\":11,\"n\":\"Variable Name (unused)\"},{\"t\":3,\"n\":\"Sex\"},{\"t\":3,\"n\":\"Actor Value\"},{\"t\":3,\"n\":\"Crime Type\"},{\"t\":3,\"n\":\"Axis\"},{\"t\":3,\"n\":\"Quest Stage (unused)\"},{\"t\":3,\"n\":\"Misc Stat\"},{\"t\":3,\"n\":\"Alignment\"},{\"t\":3,\"n\":\"Equip Type\"},{\"t\":3,\"n\":\"Form Type\"},{\"t\":3,\"n\":\"Critical Stage\"},{\"t\":3,\"n\":\"Object Reference\"},{\"t\":3,\"n\":\"Inventory Object\"},{\"t\":3,\"n\":\"Actor\"},{\"t\":3,\"n\":\"Voice Type\"},{\"t\":3,\"n\":\"Idle\"},{\"t\":3,\"n\":\"Form List\"},{\"t\":3,\"n\":\"Quest\"},{\"t\":3,\"n\":\"Faction\"},{\"t\":3,\"n\":\"Cell\"},{\"t\":3,\"n\":\"Class\"},{\"t\":3,\"n\":\"Race\"},{\"t\":3,\"n\":\"Actor Base\"},{\"t\":3,\"n\":\"Global\"},{\"t\":3,\"n\":\"Weather\"},{\"t\":3,\"n\":\"Package\"},{\"t\":3,\"n\":\"Encounter Zone\"},{\"t\":3,\"n\":\"Perk\"},{\"t\":3,\"n\":\"Owner\"},{\"t\":3,\"n\":\"Furniture\"},{\"t\":3,\"n\":\"Effect Item\"},{\"t\":3,\"n\":\"Base Effect\"},{\"t\":3,\"n\":\"Worldspace\"},{\"t\":3,\"n\":\"VATS Value Function\"},{\"t\":3,\"n\":\"VATS Value Param (INVALID)\"},{\"t\":3,\"n\":\"Referenceable Object\"},{\"t\":3,\"n\":\"Region\"},{\"t\":3,\"n\":\"Keyword\"},{\"t\":3,\"n\":\"Player Action\"},{\"t\":3,\"n\":\"Casting Type\"},{\"t\":3,\"n\":\"Shout\"},{\"t\":3,\"n\":\"Location\"},{\"t\":3,\"n\":\"Location Ref Type\"},{\"t\":3,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Packdata ID\"},{\"t\":3,\"n\":\"Association Type\"},{\"t\":3,\"n\":\"Furniture Anim\"},{\"t\":3,\"n\":\"Furniture Entry\"},{\"t\":3,\"n\":\"Scene\"},{\"t\":3,\"n\":\"Ward State\"},{\"t\":3,\"n\":\"Event\"},{\"t\":3,\"n\":\"Event Data\"},{\"t\":3,\"n\":\"Quest Stage\"},{\"t\":3,\"n\":\"Weapon\"},{\"t\":3,\"n\":\"Weapon List\"},{\"t\":3,\"n\":\"Target\"},{\"t\":3,\"n\":\"Target List\"},{\"t\":3,\"n\":\"Target Part\"},{\"t\":3,\"n\":\"VATS Action\"},{\"t\":3,\"n\":\"Critical Effect\"},{\"t\":3,\"n\":\"Critical Effect List\"},{\"t\":3,\"n\":\"Weapon Type\"},{\"t\":3,\"n\":\"Projectile Type\"},{\"t\":3,\"n\":\"Delivery Type\"},{\"t\":3,\"n\":\"Run On\"},{\"t\":3,\"n\":\"Reference\"},{\"t\":3,\"n\":\"Parameter #3\"}]},{\"t\":2,\"n\":\"CIS1 - Parameter #1\"},{\"t\":2,\"n\":\"CIS2 - Parameter #2\"}]}]},{\"t\":2,\"n\":\"DNAM - Filename\"},{\"t\":2,\"n\":\"ENAM - Animation Event\"},{\"t\":7,\"n\":\"ANAM - Related Idle Animations\",\"c\":[{\"t\":3,\"n\":\"Related Idle Animation\"}]},{\"t\":6,\"n\":\"DATA - Data (unused)\",\"c\":[{\"t\":6,\"n\":\"Looping seconds (both 255 forever)\",\"c\":[{\"t\":3,\"n\":\"Min\"},{\"t\":3,\"n\":\"Max\"}]},{\"t\":3,\"n\":\"Flags\"},{\"t\":3,\"n\":\"Animation Group Section\"},{\"t\":3,\"n\":\"Replay Delay\"}]}]},{\"t\":1,\"p\":1,\"n\":\"IDLM - Idle Marker\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"X1\"},{\"t\":3,\"p\":1,\"n\":\"Y1\"},{\"t\":3,\"p\":1,\"n\":\"Z1\"},{\"t\":3,\"p\":1,\"n\":\"X2\"},{\"t\":3,\"p\":1,\"n\":\"Y2\"},{\"t\":3,\"p\":1,\"n\":\"Z2\"}]},{\"t\":3,\"p\":1,\"n\":\"IDLF - Flags\"},{\"t\":3,\"p\":1,\"n\":\"IDLC - Animation Count\"},{\"t\":5,\"p\":1,\"n\":\"IDLT - Idle Timer Setting\"},{\"t\":7,\"p\":1,\"n\":\"IDLA - Animations\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Animation\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"MODT - Texture Files Hashes\"},{\"t\":7,\"p\":1,\"n\":\"MODS - Alternate Textures\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"3D Name\"},{\"t\":3,\"p\":1,\"n\":\"New Texture\"},{\"t\":3,\"p\":1,\"n\":\"3D Index\"}]}]}]}]},{\"t\":1,\"p\":1,\"n\":\"IMAD - Image Space Adapter\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DNAM - Data Count\",\"c\":[{\"t\":3,\"n\":\"Flags\"},{\"t\":5,\"n\":\"Duration\"},{\"t\":6,\"n\":\"HDR\",\"c\":[{\"t\":3,\"n\":\"Eye Adapt Speed Mult\"},{\"t\":3,\"n\":\"Eye Adapt Speed Add\"},{\"t\":3,\"n\":\"Bloom Blur Radius Mult\"},{\"t\":3,\"n\":\"Bloom Blur Radius Add\"},{\"t\":3,\"n\":\"Bloom Threshold Mult\"},{\"t\":3,\"n\":\"Bloom Threshold Add\"},{\"t\":3,\"n\":\"Bloom Scale Mult\"},{\"t\":3,\"n\":\"Bloom Scale Add\"},{\"t\":3,\"n\":\"Target Lum Min Mult\"},{\"t\":3,\"n\":\"Target Lum Min Add\"},{\"t\":3,\"n\":\"Target Lum Max Mult\"},{\"t\":3,\"n\":\"Target Lum Max Add\"},{\"t\":3,\"n\":\"Sunlight Scale Mult\"},{\"t\":3,\"n\":\"Sunlight Scale Add\"},{\"t\":3,\"n\":\"Sky Scale Mult\"},{\"t\":3,\"n\":\"Sky Scale Add\"}]},{\"t\":3,\"n\":\"Unknown08 Mult\"},{\"t\":3,\"n\":\"Unknown48 Add\"},{\"t\":3,\"n\":\"Unknown09 Mult\"},{\"t\":3,\"n\":\"Unknown49 Add\"},{\"t\":3,\"n\":\"Unknown0A Mult\"},{\"t\":3,\"n\":\"Unknown4A Add\"},{\"t\":3,\"n\":\"Unknown0B Mult\"},{\"t\":3,\"n\":\"Unknown4B Add\"},{\"t\":3,\"n\":\"Unknown0C Mult\"},{\"t\":3,\"n\":\"Unknown4C Add\"},{\"t\":3,\"n\":\"Unknown0D Mult\"},{\"t\":3,\"n\":\"Unknown4D Add\"},{\"t\":3,\"n\":\"Unknown0E Mult\"},{\"t\":3,\"n\":\"Unknown4E Add\"},{\"t\":3,\"n\":\"Unknown0F Mult\"},{\"t\":3,\"n\":\"Unknown4F Add\"},{\"t\":3,\"n\":\"Unknown10 Mult\"},{\"t\":3,\"n\":\"Unknown50 Add\"},{\"t\":6,\"n\":\"Cinematic\",\"c\":[{\"t\":3,\"n\":\"Saturation Mult\"},{\"t\":3,\"n\":\"Saturation Add\"},{\"t\":3,\"n\":\"Brightness Mult\"},{\"t\":3,\"n\":\"Brightness Add\"},{\"t\":3,\"n\":\"Contrast Mult\"},{\"t\":3,\"n\":\"Contrast Add\"}]},{\"t\":3,\"n\":\"Unknown14 Mult\"},{\"t\":3,\"n\":\"Unknown54 Add\"},{\"t\":3,\"n\":\"Tint Color\"},{\"t\":3,\"n\":\"Blur Radius\"},{\"t\":3,\"n\":\"Double Vision Strength\"},{\"t\":3,\"n\":\"Radial Blur Strength\"},{\"t\":3,\"n\":\"Radial Blur Ramp Up\"},{\"t\":3,\"n\":\"Radial Blur Start\"},{\"t\":3,\"n\":\"Radial Blur Flags\"},{\"t\":5,\"n\":\"Radial Blur Center X\"},{\"t\":5,\"n\":\"Radial Blur Center Y\"},{\"t\":3,\"n\":\"DoF Strength\"},{\"t\":3,\"n\":\"DoF Distance\"},{\"t\":3,\"n\":\"DoF Range\"},{\"t\":3,\"n\":\"DoF Flags\"},{\"t\":3,\"n\":\"Radial Blur Ramp Down\"},{\"t\":3,\"n\":\"Radial Blur Down Start\"},{\"t\":3,\"n\":\"Fade Color\"},{\"t\":3,\"n\":\"Motion Blur Strength\"}]},{\"t\":7,\"p\":1,\"n\":\"BNAM - Blur Radius\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Data\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Time\"},{\"t\":5,\"p\":1,\"n\":\"Value\"}]}]},{\"t\":7,\"p\":1,\"n\":\"VNAM - Double Vision Strength\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Data\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Time\"},{\"t\":5,\"p\":1,\"n\":\"Value\"}]}]},{\"t\":7,\"p\":1,\"n\":\"TNAM - Tint Color\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Data\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Time\"},{\"t\":5,\"p\":1,\"n\":\"Red\"},{\"t\":5,\"p\":1,\"n\":\"Green\"},{\"t\":5,\"p\":1,\"n\":\"Blue\"},{\"t\":5,\"p\":1,\"n\":\"Alpha\"}]}]},{\"t\":7,\"p\":1,\"n\":\"NAM3 - Fade Color\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Data\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Time\"},{\"t\":5,\"p\":1,\"n\":\"Red\"},{\"t\":5,\"p\":1,\"n\":\"Green\"},{\"t\":5,\"p\":1,\"n\":\"Blue\"},{\"t\":5,\"p\":1,\"n\":\"Alpha\"}]}]},{\"t\":7,\"p\":1,\"n\":\"RNAM - Radial Blur Strength\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Data\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Time\"},{\"t\":5,\"p\":1,\"n\":\"Value\"}]}]},{\"t\":7,\"p\":1,\"n\":\"SNAM - Radial Blur Ramp Up\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Data\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Time\"},{\"t\":5,\"p\":1,\"n\":\"Value\"}]}]},{\"t\":7,\"p\":1,\"n\":\"UNAM - Radial Blur Start\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Data\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Time\"},{\"t\":5,\"p\":1,\"n\":\"Value\"}]}]},{\"t\":7,\"p\":1,\"n\":\"NAM1 - Radial Blur Ramp Down\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Data\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Time\"},{\"t\":5,\"p\":1,\"n\":\"Value\"}]}]},{\"t\":7,\"p\":1,\"n\":\"NAM2 - Radial Blur Down Start\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Data\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Time\"},{\"t\":5,\"p\":1,\"n\":\"Value\"}]}]},{\"t\":7,\"p\":1,\"n\":\"WNAM - DoF Strength\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Data\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Time\"},{\"t\":5,\"p\":1,\"n\":\"Value\"}]}]},{\"t\":7,\"p\":1,\"n\":\"XNAM - DoF Distance\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Data\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Time\"},{\"t\":5,\"p\":1,\"n\":\"Value\"}]}]},{\"t\":7,\"p\":1,\"n\":\"YNAM - DoF Range\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Data\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Time\"},{\"t\":5,\"p\":1,\"n\":\"Value\"}]}]},{\"t\":7,\"p\":1,\"n\":\"NAM4 - Motion Blur Strength\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Data\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Time\"},{\"t\":5,\"p\":1,\"n\":\"Value\"}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"HDR\",\"c\":[{\"t\":7,\"p\":1,\"n\":\"aIAD - Eye Adapt Speed Mult\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Data\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Time\"},{\"t\":5,\"p\":1,\"n\":\"Value\"}]}]},{\"t\":7,\"p\":1,\"n\":\"@IAD - Eye Adapt Speed Add\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Data\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Time\"},{\"t\":5,\"p\":1,\"n\":\"Value\"}]}]},{\"t\":7,\"p\":1,\"n\":\"bIAD - Bloom Blur Radius Mult\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Data\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Time\"},{\"t\":5,\"p\":1,\"n\":\"Value\"}]}]},{\"t\":7,\"p\":1,\"n\":\"AIAD - Bloom Blur Radius Add\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Data\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Time\"},{\"t\":5,\"p\":1,\"n\":\"Value\"}]}]},{\"t\":7,\"p\":1,\"n\":\"cIAD - Bloom Threshold Mult\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Data\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Time\"},{\"t\":5,\"p\":1,\"n\":\"Value\"}]}]},{\"t\":7,\"p\":1,\"n\":\"BIAD - Bloom Threshold Add\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Data\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Time\"},{\"t\":5,\"p\":1,\"n\":\"Value\"}]}]},{\"t\":7,\"p\":1,\"n\":\"dIAD - Bloom Scale Mult\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Data\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Time\"},{\"t\":5,\"p\":1,\"n\":\"Value\"}]}]},{\"t\":7,\"p\":1,\"n\":\"CIAD - Bloom Scale Add\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Data\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Time\"},{\"t\":5,\"p\":1,\"n\":\"Value\"}]}]},{\"t\":7,\"p\":1,\"n\":\"eIAD - Target Lum Min Mult\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Data\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Time\"},{\"t\":5,\"p\":1,\"n\":\"Value\"}]}]},{\"t\":7,\"p\":1,\"n\":\"DIAD - Target Lum Min Add\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Data\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Time\"},{\"t\":5,\"p\":1,\"n\":\"Value\"}]}]},{\"t\":7,\"p\":1,\"n\":\"fIAD - Target Lum Max Mult\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Data\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Time\"},{\"t\":5,\"p\":1,\"n\":\"Value\"}]}]},{\"t\":7,\"p\":1,\"n\":\"EIAD - Target Lum Max Add\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Data\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Time\"},{\"t\":5,\"p\":1,\"n\":\"Value\"}]}]},{\"t\":7,\"p\":1,\"n\":\"gIAD - Sunlight Scale Mult\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Data\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Time\"},{\"t\":5,\"p\":1,\"n\":\"Value\"}]}]},{\"t\":7,\"p\":1,\"n\":\"FIAD - Sunlight Scale Add\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Data\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Time\"},{\"t\":5,\"p\":1,\"n\":\"Value\"}]}]},{\"t\":7,\"p\":1,\"n\":\"hIAD - Sky Scale Mult\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Data\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Time\"},{\"t\":5,\"p\":1,\"n\":\"Value\"}]}]},{\"t\":7,\"p\":1,\"n\":\"GIAD - Sky Scale Add\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Data\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Time\"},{\"t\":5,\"p\":1,\"n\":\"Value\"}]}]}]},{\"t\":11,\"n\":\"iIAD - Unknown\"},{\"t\":11,\"n\":\"HIAD - Unknown\"},{\"t\":11,\"n\":\"jIAD - Unknown\"},{\"t\":11,\"n\":\"IIAD - Unknown\"},{\"t\":11,\"n\":\"kIAD - Unknown\"},{\"t\":11,\"n\":\"JIAD - Unknown\"},{\"t\":11,\"n\":\"lIAD - Unknown\"},{\"t\":11,\"n\":\"KIAD - Unknown\"},{\"t\":11,\"n\":\"mIAD - Unknown\"},{\"t\":11,\"n\":\"LIAD - Unknown\"},{\"t\":11,\"n\":\"nIAD - Unknown\"},{\"t\":11,\"n\":\"MIAD - Unknown\"},{\"t\":11,\"n\":\"oIAD - Unknown\"},{\"t\":11,\"n\":\"NIAD - Unknown\"},{\"t\":11,\"n\":\"pIAD - Unknown\"},{\"t\":11,\"n\":\"OIAD - Unknown\"},{\"t\":11,\"n\":\"qIAD - Unknown\"},{\"t\":11,\"n\":\"PIAD - Unknown\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Cinematic\",\"c\":[{\"t\":7,\"p\":1,\"n\":\"rIAD - Saturation Mult\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Data\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Time\"},{\"t\":5,\"p\":1,\"n\":\"Value\"}]}]},{\"t\":7,\"p\":1,\"n\":\"QIAD - Saturation Add\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Data\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Time\"},{\"t\":5,\"p\":1,\"n\":\"Value\"}]}]},{\"t\":7,\"p\":1,\"n\":\"sIAD - Brightness Mult\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Data\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Time\"},{\"t\":5,\"p\":1,\"n\":\"Value\"}]}]},{\"t\":7,\"p\":1,\"n\":\"RIAD - Brightness Add\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Data\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Time\"},{\"t\":5,\"p\":1,\"n\":\"Value\"}]}]},{\"t\":7,\"p\":1,\"n\":\"tIAD - Contrast Mult\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Data\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Time\"},{\"t\":5,\"p\":1,\"n\":\"Value\"}]}]},{\"t\":7,\"p\":1,\"n\":\"SIAD - Contrast Add\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Data\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Time\"},{\"t\":5,\"p\":1,\"n\":\"Value\"}]}]}]},{\"t\":11,\"n\":\"uIAD - Unknown\"},{\"t\":11,\"n\":\"TIAD - Unknown\"}]},{\"t\":1,\"p\":1,\"n\":\"IMGS - Image Space\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":11,\"n\":\"ENAM - Unknown\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"HNAM - HDR\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Eye Adapt Speed\"},{\"t\":5,\"p\":1,\"n\":\"Bloom Blur Radius\"},{\"t\":5,\"p\":1,\"n\":\"Bloom Threshold\"},{\"t\":5,\"p\":1,\"n\":\"Bloom Scale\"},{\"t\":5,\"p\":1,\"n\":\"Receive Bloom Threshold\"},{\"t\":5,\"p\":1,\"n\":\"White\"},{\"t\":5,\"p\":1,\"n\":\"Sunlight Scale\"},{\"t\":5,\"p\":1,\"n\":\"Sky Scale\"},{\"t\":5,\"p\":1,\"n\":\"Eye Adapt Strength\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"CNAM - Cinematic\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Saturation\"},{\"t\":5,\"p\":1,\"n\":\"Brightness\"},{\"t\":5,\"p\":1,\"n\":\"Contrast\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"TNAM - Tint\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Amount\"},{\"t\":6,\"p\":1,\"n\":\"Color\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Red\"},{\"t\":5,\"p\":1,\"n\":\"Green\"},{\"t\":5,\"p\":1,\"n\":\"Blue\"}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DNAM - Depth of Field\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Strength\"},{\"t\":5,\"p\":1,\"n\":\"Distance\"},{\"t\":5,\"p\":1,\"n\":\"Range\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":3,\"p\":1,\"n\":\"Sky \\/ Blur Radius\"}]}]},{\"t\":1,\"p\":1,\"n\":\"INFO - Dialog response\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"VMAD - Virtual Machine Adapter\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Version\"},{\"t\":3,\"p\":1,\"n\":\"Object Format\"},{\"t\":7,\"p\":1,\"n\":\"Scripts\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Script\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"scriptName\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":7,\"p\":1,\"n\":\"Properties\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Property\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"propertyName\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]},{\"t\":2,\"p\":1,\"n\":\"String\"},{\"t\":3,\"p\":1,\"n\":\"Int32\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":3,\"p\":1,\"n\":\"Bool\"},{\"t\":7,\"p\":1,\"n\":\"Array of Object\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]}]},{\"t\":7,\"p\":1,\"n\":\"Array of String\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Int32\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Float\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Bool\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]}]}]}]}]},{\"t\":6,\"p\":1,\"n\":\"Script Fragments\",\"c\":[{\"t\":3,\"n\":\"Unknown\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":2,\"p\":1,\"n\":\"fileName\"},{\"t\":7,\"p\":1,\"n\":\"Fragments\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Fragment\",\"c\":[{\"t\":3,\"n\":\"Unknown\"},{\"t\":2,\"p\":1,\"n\":\"scriptName\"},{\"t\":2,\"p\":1,\"n\":\"fragmentName\"}]}]}]}]},{\"t\":11,\"n\":\"DATA - Unknown\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"ENAM - Response flags\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":3,\"p\":1,\"n\":\"Reset Hours\"}]},{\"t\":3,\"p\":1,\"n\":\"TPIC - Topic\"},{\"t\":3,\"p\":1,\"n\":\"PNAM - Previous INFO\"},{\"t\":3,\"p\":1,\"n\":\"CNAM - Favor Level\"},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Link To\",\"d\":1,\"c\":[{\"t\":3,\"p\":1,\"n\":\"TCLT - Response\"}]},{\"t\":3,\"p\":1,\"n\":\"DNAM - Response Data\"},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Responses\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Response\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"TRDT - Response Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Emotion Type\"},{\"t\":3,\"p\":1,\"n\":\"Emotion Value\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Response number\"},{\"t\":3,\"p\":1,\"n\":\"Sound\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"}]},{\"t\":2,\"p\":1,\"n\":\"NAM1 - Response Text\"},{\"t\":2,\"p\":1,\"n\":\"NAM2 - Script Notes\"},{\"t\":2,\"p\":1,\"n\":\"NAM3 - Edits\"},{\"t\":3,\"p\":1,\"n\":\"SNAM - Idle Animations: Speaker\"},{\"t\":3,\"p\":1,\"n\":\"LNAM - Idle Animations: Listener\"}]}]},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Conditions\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Condition\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"CTDA - \",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":5,\"p\":1,\"n\":\"Comparison Value - Float\"},{\"t\":3,\"p\":1,\"n\":\"Comparison Value - Global\"},{\"t\":3,\"p\":1,\"n\":\"Function\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":11,\"p\":1,\"n\":\"None\"},{\"t\":3,\"p\":1,\"n\":\"Integer\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":11,\"p\":1,\"n\":\"Variable Name (unused)\"},{\"t\":3,\"p\":1,\"n\":\"Sex\"},{\"t\":3,\"p\":1,\"n\":\"Actor Value\"},{\"t\":3,\"p\":1,\"n\":\"Crime Type\"},{\"t\":3,\"p\":1,\"n\":\"Axis\"},{\"t\":3,\"p\":1,\"n\":\"Quest Stage (unused)\"},{\"t\":3,\"p\":1,\"n\":\"Misc Stat\"},{\"t\":3,\"p\":1,\"n\":\"Alignment\"},{\"t\":3,\"p\":1,\"n\":\"Equip Type\"},{\"t\":3,\"p\":1,\"n\":\"Form Type\"},{\"t\":3,\"p\":1,\"n\":\"Critical Stage\"},{\"t\":3,\"p\":1,\"n\":\"Object Reference\"},{\"t\":3,\"p\":1,\"n\":\"Inventory Object\"},{\"t\":3,\"p\":1,\"n\":\"Actor\"},{\"t\":3,\"p\":1,\"n\":\"Voice Type\"},{\"t\":3,\"p\":1,\"n\":\"Idle\"},{\"t\":3,\"p\":1,\"n\":\"Form List\"},{\"t\":3,\"p\":1,\"n\":\"Quest\"},{\"t\":3,\"p\":1,\"n\":\"Faction\"},{\"t\":3,\"p\":1,\"n\":\"Cell\"},{\"t\":3,\"p\":1,\"n\":\"Class\"},{\"t\":3,\"p\":1,\"n\":\"Race\"},{\"t\":3,\"p\":1,\"n\":\"Actor Base\"},{\"t\":3,\"p\":1,\"n\":\"Global\"},{\"t\":3,\"p\":1,\"n\":\"Weather\"},{\"t\":3,\"p\":1,\"n\":\"Package\"},{\"t\":3,\"p\":1,\"n\":\"Encounter Zone\"},{\"t\":3,\"p\":1,\"n\":\"Perk\"},{\"t\":3,\"p\":1,\"n\":\"Owner\"},{\"t\":3,\"p\":1,\"n\":\"Furniture\"},{\"t\":3,\"p\":1,\"n\":\"Effect Item\"},{\"t\":3,\"p\":1,\"n\":\"Base Effect\"},{\"t\":3,\"p\":1,\"n\":\"Worldspace\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Function\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Param (INVALID)\"},{\"t\":3,\"p\":1,\"n\":\"Referenceable Object\"},{\"t\":3,\"p\":1,\"n\":\"Region\"},{\"t\":3,\"p\":1,\"n\":\"Keyword\"},{\"t\":3,\"p\":1,\"n\":\"Player Action\"},{\"t\":3,\"p\":1,\"n\":\"Casting Type\"},{\"t\":3,\"p\":1,\"n\":\"Shout\"},{\"t\":3,\"p\":1,\"n\":\"Location\"},{\"t\":3,\"p\":1,\"n\":\"Location Ref Type\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"Packdata ID\"},{\"t\":3,\"p\":1,\"n\":\"Association Type\"},{\"t\":3,\"p\":1,\"n\":\"Furniture Anim\"},{\"t\":3,\"p\":1,\"n\":\"Furniture Entry\"},{\"t\":3,\"p\":1,\"n\":\"Scene\"},{\"t\":3,\"p\":1,\"n\":\"Ward State\"},{\"t\":3,\"p\":1,\"n\":\"Event\"},{\"t\":3,\"p\":1,\"n\":\"Event Data\"},{\"t\":3,\"p\":1,\"n\":\"Quest Stage\"},{\"t\":3,\"p\":1,\"n\":\"Weapon\"},{\"t\":3,\"p\":1,\"n\":\"Weapon List\"},{\"t\":3,\"p\":1,\"n\":\"Target\"},{\"t\":3,\"p\":1,\"n\":\"Target List\"},{\"t\":3,\"p\":1,\"n\":\"Target Part\"},{\"t\":3,\"p\":1,\"n\":\"VATS Action\"},{\"t\":3,\"p\":1,\"n\":\"Critical Effect\"},{\"t\":3,\"p\":1,\"n\":\"Critical Effect List\"},{\"t\":3,\"p\":1,\"n\":\"Weapon Type\"},{\"t\":3,\"p\":1,\"n\":\"Projectile Type\"},{\"t\":3,\"p\":1,\"n\":\"Delivery Type\"},{\"t\":3,\"p\":1,\"n\":\"Run On\"},{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":3,\"p\":1,\"n\":\"Parameter #3\"}]},{\"t\":2,\"p\":1,\"n\":\"CIS1 - Parameter #1\"},{\"t\":2,\"p\":1,\"n\":\"CIS2 - Parameter #2\"}]}]},{\"t\":8,\"n\":\"Unknown\",\"c\":[{\"t\":6,\"n\":\"Unknown\",\"c\":[{\"t\":11,\"n\":\"SCHR - Unknown\"},{\"t\":3,\"n\":\"QNAM - Unknown\"},{\"n\":\"NEXT - Marker\"}]}]},{\"t\":2,\"p\":1,\"n\":\"RNAM - Prompt\"},{\"t\":3,\"p\":1,\"n\":\"ANAM - Speaker\"},{\"t\":3,\"p\":1,\"n\":\"TWAT - Walk Away Topic\"},{\"t\":3,\"p\":1,\"n\":\"ONAM - Audio Output Override\"}]},{\"t\":1,\"p\":1,\"n\":\"INGR - Ingredient\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"VMAD - Virtual Machine Adapter\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Version\"},{\"t\":3,\"p\":1,\"n\":\"Object Format\"},{\"t\":7,\"p\":1,\"n\":\"Scripts\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Script\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"scriptName\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":7,\"p\":1,\"n\":\"Properties\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Property\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"propertyName\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]},{\"t\":2,\"p\":1,\"n\":\"String\"},{\"t\":3,\"p\":1,\"n\":\"Int32\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":3,\"p\":1,\"n\":\"Bool\"},{\"t\":7,\"p\":1,\"n\":\"Array of Object\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]}]},{\"t\":7,\"p\":1,\"n\":\"Array of String\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Int32\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Float\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Bool\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]}]}]}]}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"X1\"},{\"t\":3,\"p\":1,\"n\":\"Y1\"},{\"t\":3,\"p\":1,\"n\":\"Z1\"},{\"t\":3,\"p\":1,\"n\":\"X2\"},{\"t\":3,\"p\":1,\"n\":\"Y2\"},{\"t\":3,\"p\":1,\"n\":\"Z2\"}]},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":3,\"n\":\"KSIZ - Keyword Count\"},{\"t\":7,\"p\":1,\"n\":\"KWDA - Keywords\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Keyword\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"MODT - Texture Files Hashes\"},{\"t\":7,\"p\":1,\"n\":\"MODS - Alternate Textures\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"3D Name\"},{\"t\":3,\"p\":1,\"n\":\"New Texture\"},{\"t\":3,\"p\":1,\"n\":\"3D Index\"}]}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Icon\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"ICON - Large Icon filename\"},{\"t\":2,\"p\":1,\"n\":\"MICO - Small Icon filename\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Destructable\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"DEST - Header\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Health\"},{\"t\":3,\"p\":1,\"n\":\"DEST Count\"},{\"t\":3,\"p\":1,\"n\":\"VATS Targetable\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":8,\"p\":1,\"n\":\"Stages\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Stage\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"DSTD - Destruction Stage Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Health %\"},{\"t\":3,\"p\":1,\"n\":\"Index\"},{\"t\":3,\"p\":1,\"n\":\"Model Damage Stage\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":3,\"p\":1,\"n\":\"Self Damage per Second\"},{\"t\":3,\"p\":1,\"n\":\"Explosion\"},{\"t\":3,\"p\":1,\"n\":\"Debris\"},{\"t\":3,\"p\":1,\"n\":\"Debris Count\"}]},{\"t\":6,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"DMDL - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"DMDT - Texture Files Hashes\"},{\"t\":7,\"p\":1,\"n\":\"DMDS - Alternate Textures\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"3D Name\"},{\"t\":3,\"p\":1,\"n\":\"New Texture\"},{\"t\":3,\"p\":1,\"n\":\"3D Index\"}]}]}]},{\"p\":1,\"n\":\"DSTF - End Marker\"}]}]}]},{\"t\":3,\"p\":1,\"n\":\"ETYP - Equipment Type\"},{\"t\":3,\"p\":1,\"n\":\"YNAM - Sound - Pick Up\"},{\"t\":3,\"p\":1,\"n\":\"ZNAM - Sound - Put Down\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DATA - \",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Value\"},{\"t\":5,\"p\":1,\"n\":\"Weight\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"ENIT - Effect Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Ingredient Value\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"}]},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Effects\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Effect\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"EFID - Base Effect\"},{\"t\":6,\"p\":1,\"n\":\"EFIT - \",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Magnitude\"},{\"t\":3,\"p\":1,\"n\":\"Area\"},{\"t\":3,\"p\":1,\"n\":\"Duration\"}]},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Conditions\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Condition\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"CTDA - \",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":5,\"p\":1,\"n\":\"Comparison Value - Float\"},{\"t\":3,\"p\":1,\"n\":\"Comparison Value - Global\"},{\"t\":3,\"p\":1,\"n\":\"Function\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":11,\"p\":1,\"n\":\"None\"},{\"t\":3,\"p\":1,\"n\":\"Integer\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":11,\"p\":1,\"n\":\"Variable Name (unused)\"},{\"t\":3,\"p\":1,\"n\":\"Sex\"},{\"t\":3,\"p\":1,\"n\":\"Actor Value\"},{\"t\":3,\"p\":1,\"n\":\"Crime Type\"},{\"t\":3,\"p\":1,\"n\":\"Axis\"},{\"t\":3,\"p\":1,\"n\":\"Quest Stage (unused)\"},{\"t\":3,\"p\":1,\"n\":\"Misc Stat\"},{\"t\":3,\"p\":1,\"n\":\"Alignment\"},{\"t\":3,\"p\":1,\"n\":\"Equip Type\"},{\"t\":3,\"p\":1,\"n\":\"Form Type\"},{\"t\":3,\"p\":1,\"n\":\"Critical Stage\"},{\"t\":3,\"p\":1,\"n\":\"Object Reference\"},{\"t\":3,\"p\":1,\"n\":\"Inventory Object\"},{\"t\":3,\"p\":1,\"n\":\"Actor\"},{\"t\":3,\"p\":1,\"n\":\"Voice Type\"},{\"t\":3,\"p\":1,\"n\":\"Idle\"},{\"t\":3,\"p\":1,\"n\":\"Form List\"},{\"t\":3,\"p\":1,\"n\":\"Quest\"},{\"t\":3,\"p\":1,\"n\":\"Faction\"},{\"t\":3,\"p\":1,\"n\":\"Cell\"},{\"t\":3,\"p\":1,\"n\":\"Class\"},{\"t\":3,\"p\":1,\"n\":\"Race\"},{\"t\":3,\"p\":1,\"n\":\"Actor Base\"},{\"t\":3,\"p\":1,\"n\":\"Global\"},{\"t\":3,\"p\":1,\"n\":\"Weather\"},{\"t\":3,\"p\":1,\"n\":\"Package\"},{\"t\":3,\"p\":1,\"n\":\"Encounter Zone\"},{\"t\":3,\"p\":1,\"n\":\"Perk\"},{\"t\":3,\"p\":1,\"n\":\"Owner\"},{\"t\":3,\"p\":1,\"n\":\"Furniture\"},{\"t\":3,\"p\":1,\"n\":\"Effect Item\"},{\"t\":3,\"p\":1,\"n\":\"Base Effect\"},{\"t\":3,\"p\":1,\"n\":\"Worldspace\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Function\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Param (INVALID)\"},{\"t\":3,\"p\":1,\"n\":\"Referenceable Object\"},{\"t\":3,\"p\":1,\"n\":\"Region\"},{\"t\":3,\"p\":1,\"n\":\"Keyword\"},{\"t\":3,\"p\":1,\"n\":\"Player Action\"},{\"t\":3,\"p\":1,\"n\":\"Casting Type\"},{\"t\":3,\"p\":1,\"n\":\"Shout\"},{\"t\":3,\"p\":1,\"n\":\"Location\"},{\"t\":3,\"p\":1,\"n\":\"Location Ref Type\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"Packdata ID\"},{\"t\":3,\"p\":1,\"n\":\"Association Type\"},{\"t\":3,\"p\":1,\"n\":\"Furniture Anim\"},{\"t\":3,\"p\":1,\"n\":\"Furniture Entry\"},{\"t\":3,\"p\":1,\"n\":\"Scene\"},{\"t\":3,\"p\":1,\"n\":\"Ward State\"},{\"t\":3,\"p\":1,\"n\":\"Event\"},{\"t\":3,\"p\":1,\"n\":\"Event Data\"},{\"t\":3,\"p\":1,\"n\":\"Quest Stage\"},{\"t\":3,\"p\":1,\"n\":\"Weapon\"},{\"t\":3,\"p\":1,\"n\":\"Weapon List\"},{\"t\":3,\"p\":1,\"n\":\"Target\"},{\"t\":3,\"p\":1,\"n\":\"Target List\"},{\"t\":3,\"p\":1,\"n\":\"Target Part\"},{\"t\":3,\"p\":1,\"n\":\"VATS Action\"},{\"t\":3,\"p\":1,\"n\":\"Critical Effect\"},{\"t\":3,\"p\":1,\"n\":\"Critical Effect List\"},{\"t\":3,\"p\":1,\"n\":\"Weapon Type\"},{\"t\":3,\"p\":1,\"n\":\"Projectile Type\"},{\"t\":3,\"p\":1,\"n\":\"Delivery Type\"},{\"t\":3,\"p\":1,\"n\":\"Run On\"},{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":3,\"p\":1,\"n\":\"Parameter #3\"}]},{\"t\":2,\"p\":1,\"n\":\"CIS1 - Parameter #1\"},{\"t\":2,\"p\":1,\"n\":\"CIS2 - Parameter #2\"}]}]}]}]}]},{\"t\":1,\"p\":1,\"n\":\"IPCT - Impact\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"MODT - Texture Files Hashes\"},{\"t\":7,\"p\":1,\"n\":\"MODS - Alternate Textures\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"3D Name\"},{\"t\":3,\"p\":1,\"n\":\"New Texture\"},{\"t\":3,\"p\":1,\"n\":\"3D Index\"}]}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DATA - \",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Effect - Duration\"},{\"t\":3,\"p\":1,\"n\":\"Effect - Orientation\"},{\"t\":5,\"p\":1,\"n\":\"Angle Threshold\"},{\"t\":5,\"p\":1,\"n\":\"Placement Radius\"},{\"t\":3,\"p\":1,\"n\":\"Sound Level\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":3,\"p\":1,\"n\":\"Impact Result\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DODT - Decal Data\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Min Width\"},{\"t\":5,\"p\":1,\"n\":\"Max Width\"},{\"t\":5,\"p\":1,\"n\":\"Min Height\"},{\"t\":5,\"p\":1,\"n\":\"Max Height\"},{\"t\":5,\"p\":1,\"n\":\"Depth\"},{\"t\":5,\"p\":1,\"n\":\"Shininess\"},{\"t\":6,\"p\":1,\"n\":\"Parallax\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Scale\"},{\"t\":3,\"p\":1,\"n\":\"Passes\"}]},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":6,\"p\":1,\"n\":\"Color\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]}]},{\"t\":3,\"p\":1,\"n\":\"DNAM - Texture Set\"},{\"t\":3,\"p\":1,\"n\":\"ENAM - Secondary Texture Set\"},{\"t\":3,\"p\":1,\"n\":\"SNAM - Sound 1\"},{\"t\":3,\"p\":1,\"n\":\"NAM1 - Sound 2\"},{\"t\":3,\"p\":1,\"n\":\"NAM2 - Hazard\"}]},{\"t\":1,\"p\":1,\"n\":\"IPDS - Impact Data Set\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Data\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"PNAM - \",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Material\"},{\"t\":3,\"p\":1,\"n\":\"Impact\"}]}]}]},{\"t\":1,\"p\":1,\"n\":\"KEYM - Key\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"VMAD - Virtual Machine Adapter\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Version\"},{\"t\":3,\"p\":1,\"n\":\"Object Format\"},{\"t\":7,\"p\":1,\"n\":\"Scripts\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Script\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"scriptName\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":7,\"p\":1,\"n\":\"Properties\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Property\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"propertyName\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]},{\"t\":2,\"p\":1,\"n\":\"String\"},{\"t\":3,\"p\":1,\"n\":\"Int32\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":3,\"p\":1,\"n\":\"Bool\"},{\"t\":7,\"p\":1,\"n\":\"Array of Object\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]}]},{\"t\":7,\"p\":1,\"n\":\"Array of String\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Int32\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Float\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Bool\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]}]}]}]}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"X1\"},{\"t\":3,\"p\":1,\"n\":\"Y1\"},{\"t\":3,\"p\":1,\"n\":\"Z1\"},{\"t\":3,\"p\":1,\"n\":\"X2\"},{\"t\":3,\"p\":1,\"n\":\"Y2\"},{\"t\":3,\"p\":1,\"n\":\"Z2\"}]},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"MODT - Texture Files Hashes\"},{\"t\":7,\"p\":1,\"n\":\"MODS - Alternate Textures\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"3D Name\"},{\"t\":3,\"p\":1,\"n\":\"New Texture\"},{\"t\":3,\"p\":1,\"n\":\"3D Index\"}]}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Icon\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"ICON - Large Icon filename\"},{\"t\":2,\"p\":1,\"n\":\"MICO - Small Icon filename\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Destructable\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"DEST - Header\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Health\"},{\"t\":3,\"p\":1,\"n\":\"DEST Count\"},{\"t\":3,\"p\":1,\"n\":\"VATS Targetable\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":8,\"p\":1,\"n\":\"Stages\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Stage\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"DSTD - Destruction Stage Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Health %\"},{\"t\":3,\"p\":1,\"n\":\"Index\"},{\"t\":3,\"p\":1,\"n\":\"Model Damage Stage\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":3,\"p\":1,\"n\":\"Self Damage per Second\"},{\"t\":3,\"p\":1,\"n\":\"Explosion\"},{\"t\":3,\"p\":1,\"n\":\"Debris\"},{\"t\":3,\"p\":1,\"n\":\"Debris Count\"}]},{\"t\":6,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"DMDL - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"DMDT - Texture Files Hashes\"},{\"t\":7,\"p\":1,\"n\":\"DMDS - Alternate Textures\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"3D Name\"},{\"t\":3,\"p\":1,\"n\":\"New Texture\"},{\"t\":3,\"p\":1,\"n\":\"3D Index\"}]}]}]},{\"p\":1,\"n\":\"DSTF - End Marker\"}]}]}]},{\"t\":3,\"p\":1,\"n\":\"YNAM - Sound - Pick Up\"},{\"t\":3,\"p\":1,\"n\":\"ZNAM - Sound - Put Down\"},{\"t\":3,\"n\":\"KSIZ - Keyword Count\"},{\"t\":7,\"p\":1,\"n\":\"KWDA - Keywords\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Keyword\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DATA - \",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Value\"},{\"t\":5,\"p\":1,\"n\":\"Weight\"}]}]},{\"t\":1,\"p\":1,\"n\":\"KYWD - Keyword\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"CNAM - Color\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unknown\"}]}]},{\"t\":1,\"p\":1,\"n\":\"LAND - Landscape\",\"d\":1,\"c\":[{\"t\":11,\"n\":\"DATA - Unknown\"},{\"t\":11,\"n\":\"VNML - Vertex Normals\"},{\"t\":11,\"n\":\"VHGT - Vertext Height Map\"},{\"t\":11,\"n\":\"VCLR - Vertex Colours\"},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Layers\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Base Layer\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"BTXT - Base Layer Header\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Texture\"},{\"t\":3,\"p\":1,\"n\":\"Quadrant\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":3,\"p\":1,\"n\":\"Layer\"}]}]},{\"t\":6,\"p\":1,\"n\":\"Alpha Layer\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"ATXT - Alpha Layer Header\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Texture\"},{\"t\":3,\"p\":1,\"n\":\"Quadrant\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":3,\"p\":1,\"n\":\"Layer\"}]},{\"t\":11,\"p\":1,\"n\":\"VTXT - Alpha Layer Data\"}]}]},{\"t\":7,\"p\":1,\"n\":\"VTEX - Textures\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Texture\"}]}]},{\"t\":1,\"p\":1,\"n\":\"LCRT - Location Reference Type\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"CNAM - Color\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unknown\"}]}]},{\"t\":1,\"n\":\"LCTN - Location\",\"c\":[{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":7,\"n\":\"ACPR - Actor Cell Persistent Reference\",\"c\":[{\"t\":6,\"n\":\"\",\"c\":[{\"t\":3,\"n\":\"Actor\"},{\"t\":3,\"n\":\"Location\"},{\"t\":3,\"n\":\"Grid Y\"},{\"t\":3,\"n\":\"Grid X\"}]}]},{\"t\":7,\"n\":\"LCPR - Location Cell Persistent Reference\",\"c\":[{\"t\":6,\"n\":\"\",\"c\":[{\"t\":3,\"n\":\"Actor\"},{\"t\":3,\"n\":\"Location\"},{\"t\":3,\"n\":\"Grid Y\"},{\"t\":3,\"n\":\"Grid X\"}]}]},{\"t\":7,\"n\":\"RCPR - Reference Cell Persistent Reference\",\"c\":[{\"t\":3,\"n\":\"Ref\"}]},{\"t\":7,\"n\":\"ACUN - Actor Cell Unique\",\"c\":[{\"t\":6,\"n\":\"\",\"c\":[{\"t\":3,\"n\":\"Actor\"},{\"t\":3,\"n\":\"Ref\"},{\"t\":3,\"n\":\"Location\"}]}]},{\"t\":7,\"n\":\"LCUN - Location Cell Unique\",\"c\":[{\"t\":6,\"n\":\"\",\"c\":[{\"t\":3,\"n\":\"Actor\"},{\"t\":3,\"n\":\"Ref\"},{\"t\":3,\"n\":\"Location\"}]}]},{\"t\":7,\"n\":\"RCUN - Reference Cell Unique\",\"c\":[{\"t\":3,\"n\":\"Actor\"}]},{\"t\":7,\"n\":\"ACSR - Actor Cell Static Reference\",\"c\":[{\"t\":6,\"n\":\"\",\"c\":[{\"t\":3,\"n\":\"Loc Ref Type\"},{\"t\":3,\"n\":\"Marker\"},{\"t\":3,\"n\":\"Location\"},{\"t\":3,\"n\":\"Grid Y\"},{\"t\":3,\"n\":\"Grid X\"}]}]},{\"t\":7,\"n\":\"LCSR - Location Cell Static Reference\",\"c\":[{\"t\":6,\"n\":\"\",\"c\":[{\"t\":3,\"n\":\"Loc Ref Type\"},{\"t\":3,\"n\":\"Marker\"},{\"t\":3,\"n\":\"Location\"},{\"t\":3,\"n\":\"Grid Y\"},{\"t\":3,\"n\":\"Grid X\"}]}]},{\"t\":7,\"n\":\"RCSR - Reference Cell Static Reference\",\"c\":[{\"t\":3,\"n\":\"Ref\"}]},{\"t\":8,\"n\":\"Actor Cell Encounter Cell\",\"c\":[{\"t\":6,\"n\":\"ACEC - Unknown\",\"c\":[{\"t\":3,\"n\":\"Location\"},{\"t\":7,\"n\":\"Coordinates\",\"c\":[{\"t\":6,\"n\":\"\",\"c\":[{\"t\":3,\"n\":\"Grid Y\"},{\"t\":3,\"n\":\"Grid X\"}]}]}]}]},{\"t\":8,\"n\":\"Location Cell Encounter Cell\",\"c\":[{\"t\":6,\"n\":\"LCEC - Unknown\",\"c\":[{\"t\":3,\"n\":\"Location\"},{\"t\":7,\"n\":\"Coordinates\",\"c\":[{\"t\":6,\"n\":\"\",\"c\":[{\"t\":3,\"n\":\"Grid Y\"},{\"t\":3,\"n\":\"Grid X\"}]}]}]}]},{\"t\":8,\"n\":\"Reference Cell Encounter Cell\",\"c\":[{\"t\":6,\"n\":\"RCEC - Unknown\",\"c\":[{\"t\":3,\"n\":\"Location\"},{\"t\":7,\"n\":\"Coordinates\",\"c\":[{\"t\":6,\"n\":\"\",\"c\":[{\"t\":3,\"n\":\"Grid Y\"},{\"t\":3,\"n\":\"Grid X\"}]}]}]}]},{\"t\":7,\"n\":\"ACID - Actor Cell Marker Reference\",\"c\":[{\"t\":3,\"n\":\"Ref\"}]},{\"t\":7,\"n\":\"LCID - Location Cell Marker Reference\",\"c\":[{\"t\":3,\"n\":\"Ref\"}]},{\"t\":7,\"n\":\"ACEP - Actor Cell Enable Point\",\"c\":[{\"t\":6,\"n\":\"\",\"c\":[{\"t\":3,\"n\":\"Actor\"},{\"t\":3,\"n\":\"Ref\"},{\"t\":3,\"n\":\"Grid Y\"},{\"t\":3,\"n\":\"Grid X\"}]}]},{\"t\":7,\"n\":\"LCEP - Location Cell Enable Point\",\"c\":[{\"t\":6,\"n\":\"\",\"c\":[{\"t\":3,\"n\":\"Actor\"},{\"t\":3,\"n\":\"Ref\"},{\"t\":3,\"n\":\"Grid Y\"},{\"t\":3,\"n\":\"Grid X\"}]}]},{\"t\":2,\"n\":\"FULL - Name\"},{\"t\":3,\"n\":\"KSIZ - Keyword Count\"},{\"t\":7,\"n\":\"KWDA - Keywords\",\"c\":[{\"t\":3,\"n\":\"Keyword\"}]},{\"t\":3,\"n\":\"PNAM - Parent Location\"},{\"t\":3,\"n\":\"NAM1 - Music\"},{\"t\":3,\"n\":\"FNAM - Unreported Crime Faction\"},{\"t\":3,\"n\":\"MNAM - World Location Marker Ref\"},{\"t\":5,\"n\":\"RNAM - World Location Radius\"},{\"t\":3,\"n\":\"NAM0 - Horse Marker Ref\"},{\"t\":6,\"n\":\"CNAM - Color\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unknown\"}]}]},{\"t\":1,\"p\":1,\"n\":\"LENS - Lens Flare\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":5,\"p\":1,\"n\":\"CNAM - Color Influence\"},{\"t\":5,\"p\":1,\"n\":\"DNAM - Fade Distance Radius Scale\"},{\"t\":3,\"n\":\"LFSP - Count\"},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Lens Flare Sprites\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Flare\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"DNAM - Lens Flare Sprite ID\"},{\"t\":2,\"p\":1,\"n\":\"FNAM - Texture\"},{\"t\":6,\"p\":1,\"n\":\"LFSD - Lens Flare Data\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Tint\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Red\"},{\"t\":5,\"p\":1,\"n\":\"Green\"},{\"t\":5,\"p\":1,\"n\":\"Blue\"}]},{\"t\":5,\"p\":1,\"n\":\"Width\"},{\"t\":5,\"p\":1,\"n\":\"Height\"},{\"t\":5,\"p\":1,\"n\":\"Position\"},{\"t\":5,\"p\":1,\"n\":\"Angular Fade\"},{\"t\":5,\"p\":1,\"n\":\"Opacity\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"}]}]}]}]},{\"t\":1,\"p\":1,\"n\":\"LGTM - Lighting Template\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DATA - Lighting\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Ambient Color\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Directional Color\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Fog Color Near\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":5,\"p\":1,\"n\":\"Fog Near\"},{\"t\":5,\"p\":1,\"n\":\"Fog Far\"},{\"t\":3,\"p\":1,\"n\":\"Directional Rotation XY\"},{\"t\":3,\"p\":1,\"n\":\"Directional Rotation Z\"},{\"t\":5,\"p\":1,\"n\":\"Directional Fade\"},{\"t\":5,\"p\":1,\"n\":\"Fog Clip Dist\"},{\"t\":5,\"p\":1,\"n\":\"Fog Power\"},{\"t\":6,\"p\":1,\"n\":\"Ambient Colors\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Directional\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"X+\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"X-\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Y+\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Y-\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Z+\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Z-\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]}]},{\"t\":6,\"p\":1,\"n\":\"Specular\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":5,\"p\":1,\"n\":\"Scale\"}]},{\"t\":6,\"p\":1,\"n\":\"Fog Color Far\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":5,\"p\":1,\"n\":\"Fog Max\"},{\"t\":6,\"p\":1,\"n\":\"Light Fade Distances\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Start\"},{\"t\":5,\"p\":1,\"n\":\"End\"}]},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DALC - Directional Ambient Lighting Colors\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Directional\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"X+\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"X-\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Y+\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Y-\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Z+\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Z-\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]}]},{\"t\":6,\"p\":1,\"n\":\"Specular\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":5,\"p\":1,\"n\":\"Scale\"}]}]},{\"t\":1,\"p\":1,\"n\":\"LIGH - Light\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"VMAD - Virtual Machine Adapter\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Version\"},{\"t\":3,\"p\":1,\"n\":\"Object Format\"},{\"t\":7,\"p\":1,\"n\":\"Scripts\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Script\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"scriptName\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":7,\"p\":1,\"n\":\"Properties\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Property\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"propertyName\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]},{\"t\":2,\"p\":1,\"n\":\"String\"},{\"t\":3,\"p\":1,\"n\":\"Int32\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":3,\"p\":1,\"n\":\"Bool\"},{\"t\":7,\"p\":1,\"n\":\"Array of Object\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]}]},{\"t\":7,\"p\":1,\"n\":\"Array of String\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Int32\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Float\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Bool\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]}]}]}]}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"X1\"},{\"t\":3,\"p\":1,\"n\":\"Y1\"},{\"t\":3,\"p\":1,\"n\":\"Z1\"},{\"t\":3,\"p\":1,\"n\":\"X2\"},{\"t\":3,\"p\":1,\"n\":\"Y2\"},{\"t\":3,\"p\":1,\"n\":\"Z2\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"MODT - Texture Files Hashes\"},{\"t\":7,\"p\":1,\"n\":\"MODS - Alternate Textures\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"3D Name\"},{\"t\":3,\"p\":1,\"n\":\"New Texture\"},{\"t\":3,\"p\":1,\"n\":\"3D Index\"}]}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Destructable\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"DEST - Header\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Health\"},{\"t\":3,\"p\":1,\"n\":\"DEST Count\"},{\"t\":3,\"p\":1,\"n\":\"VATS Targetable\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":8,\"p\":1,\"n\":\"Stages\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Stage\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"DSTD - Destruction Stage Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Health %\"},{\"t\":3,\"p\":1,\"n\":\"Index\"},{\"t\":3,\"p\":1,\"n\":\"Model Damage Stage\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":3,\"p\":1,\"n\":\"Self Damage per Second\"},{\"t\":3,\"p\":1,\"n\":\"Explosion\"},{\"t\":3,\"p\":1,\"n\":\"Debris\"},{\"t\":3,\"p\":1,\"n\":\"Debris Count\"}]},{\"t\":6,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"DMDL - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"DMDT - Texture Files Hashes\"},{\"t\":7,\"p\":1,\"n\":\"DMDS - Alternate Textures\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"3D Name\"},{\"t\":3,\"p\":1,\"n\":\"New Texture\"},{\"t\":3,\"p\":1,\"n\":\"3D Index\"}]}]}]},{\"p\":1,\"n\":\"DSTF - End Marker\"}]}]}]},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Icon\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"ICON - Large Icon filename\"},{\"t\":2,\"p\":1,\"n\":\"MICO - Small Icon filename\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DATA - \",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Time\"},{\"t\":3,\"p\":1,\"n\":\"Radius\"},{\"t\":6,\"p\":1,\"n\":\"Color\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":5,\"p\":1,\"n\":\"Falloff Exponent\"},{\"t\":5,\"p\":1,\"n\":\"FOV\"},{\"t\":5,\"p\":1,\"n\":\"Near Clip\"},{\"t\":6,\"p\":1,\"n\":\"Flicker Effect\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Period\"},{\"t\":5,\"p\":1,\"n\":\"Intensity Amplitude\"},{\"t\":5,\"p\":1,\"n\":\"Movement Amplitude\"}]},{\"t\":3,\"p\":1,\"n\":\"Value\"},{\"t\":5,\"p\":1,\"n\":\"Weight\"}]},{\"t\":5,\"p\":1,\"n\":\"FNAM - Fade value\"},{\"t\":3,\"p\":1,\"n\":\"SNAM - Sound\"}]},{\"t\":1,\"p\":1,\"n\":\"LSCR - Load Screen\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Icon\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"ICON - Large Icon filename\"},{\"t\":2,\"p\":1,\"n\":\"MICO - Small Icon filename\"}]},{\"t\":2,\"p\":1,\"n\":\"DESC - Description\"},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Conditions\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Condition\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"CTDA - \",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":5,\"p\":1,\"n\":\"Comparison Value - Float\"},{\"t\":3,\"p\":1,\"n\":\"Comparison Value - Global\"},{\"t\":3,\"p\":1,\"n\":\"Function\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":11,\"p\":1,\"n\":\"None\"},{\"t\":3,\"p\":1,\"n\":\"Integer\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":11,\"p\":1,\"n\":\"Variable Name (unused)\"},{\"t\":3,\"p\":1,\"n\":\"Sex\"},{\"t\":3,\"p\":1,\"n\":\"Actor Value\"},{\"t\":3,\"p\":1,\"n\":\"Crime Type\"},{\"t\":3,\"p\":1,\"n\":\"Axis\"},{\"t\":3,\"p\":1,\"n\":\"Quest Stage (unused)\"},{\"t\":3,\"p\":1,\"n\":\"Misc Stat\"},{\"t\":3,\"p\":1,\"n\":\"Alignment\"},{\"t\":3,\"p\":1,\"n\":\"Equip Type\"},{\"t\":3,\"p\":1,\"n\":\"Form Type\"},{\"t\":3,\"p\":1,\"n\":\"Critical Stage\"},{\"t\":3,\"p\":1,\"n\":\"Object Reference\"},{\"t\":3,\"p\":1,\"n\":\"Inventory Object\"},{\"t\":3,\"p\":1,\"n\":\"Actor\"},{\"t\":3,\"p\":1,\"n\":\"Voice Type\"},{\"t\":3,\"p\":1,\"n\":\"Idle\"},{\"t\":3,\"p\":1,\"n\":\"Form List\"},{\"t\":3,\"p\":1,\"n\":\"Quest\"},{\"t\":3,\"p\":1,\"n\":\"Faction\"},{\"t\":3,\"p\":1,\"n\":\"Cell\"},{\"t\":3,\"p\":1,\"n\":\"Class\"},{\"t\":3,\"p\":1,\"n\":\"Race\"},{\"t\":3,\"p\":1,\"n\":\"Actor Base\"},{\"t\":3,\"p\":1,\"n\":\"Global\"},{\"t\":3,\"p\":1,\"n\":\"Weather\"},{\"t\":3,\"p\":1,\"n\":\"Package\"},{\"t\":3,\"p\":1,\"n\":\"Encounter Zone\"},{\"t\":3,\"p\":1,\"n\":\"Perk\"},{\"t\":3,\"p\":1,\"n\":\"Owner\"},{\"t\":3,\"p\":1,\"n\":\"Furniture\"},{\"t\":3,\"p\":1,\"n\":\"Effect Item\"},{\"t\":3,\"p\":1,\"n\":\"Base Effect\"},{\"t\":3,\"p\":1,\"n\":\"Worldspace\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Function\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Param (INVALID)\"},{\"t\":3,\"p\":1,\"n\":\"Referenceable Object\"},{\"t\":3,\"p\":1,\"n\":\"Region\"},{\"t\":3,\"p\":1,\"n\":\"Keyword\"},{\"t\":3,\"p\":1,\"n\":\"Player Action\"},{\"t\":3,\"p\":1,\"n\":\"Casting Type\"},{\"t\":3,\"p\":1,\"n\":\"Shout\"},{\"t\":3,\"p\":1,\"n\":\"Location\"},{\"t\":3,\"p\":1,\"n\":\"Location Ref Type\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"Packdata ID\"},{\"t\":3,\"p\":1,\"n\":\"Association Type\"},{\"t\":3,\"p\":1,\"n\":\"Furniture Anim\"},{\"t\":3,\"p\":1,\"n\":\"Furniture Entry\"},{\"t\":3,\"p\":1,\"n\":\"Scene\"},{\"t\":3,\"p\":1,\"n\":\"Ward State\"},{\"t\":3,\"p\":1,\"n\":\"Event\"},{\"t\":3,\"p\":1,\"n\":\"Event Data\"},{\"t\":3,\"p\":1,\"n\":\"Quest Stage\"},{\"t\":3,\"p\":1,\"n\":\"Weapon\"},{\"t\":3,\"p\":1,\"n\":\"Weapon List\"},{\"t\":3,\"p\":1,\"n\":\"Target\"},{\"t\":3,\"p\":1,\"n\":\"Target List\"},{\"t\":3,\"p\":1,\"n\":\"Target Part\"},{\"t\":3,\"p\":1,\"n\":\"VATS Action\"},{\"t\":3,\"p\":1,\"n\":\"Critical Effect\"},{\"t\":3,\"p\":1,\"n\":\"Critical Effect List\"},{\"t\":3,\"p\":1,\"n\":\"Weapon Type\"},{\"t\":3,\"p\":1,\"n\":\"Projectile Type\"},{\"t\":3,\"p\":1,\"n\":\"Delivery Type\"},{\"t\":3,\"p\":1,\"n\":\"Run On\"},{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":3,\"p\":1,\"n\":\"Parameter #3\"}]},{\"t\":2,\"p\":1,\"n\":\"CIS1 - Parameter #1\"},{\"t\":2,\"p\":1,\"n\":\"CIS2 - Parameter #2\"}]}]},{\"t\":3,\"p\":1,\"n\":\"NNAM - Loading Screen NIF\"},{\"t\":5,\"p\":1,\"n\":\"SNAM - Initial Scale\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"RNAM - Initial Rotation\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"X\"},{\"t\":3,\"p\":1,\"n\":\"Y\"},{\"t\":3,\"p\":1,\"n\":\"Z\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"ONAM - Rotation Offset Constraints\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Min\"},{\"t\":3,\"p\":1,\"n\":\"Max\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"XNAM - Initial Translation Offset\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"X\"},{\"t\":5,\"p\":1,\"n\":\"Y\"},{\"t\":5,\"p\":1,\"n\":\"Z\"}]},{\"t\":2,\"p\":1,\"n\":\"MOD2 - Camera Path\"}]},{\"t\":1,\"p\":1,\"n\":\"LTEX - Landscape Texture\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":3,\"p\":1,\"n\":\"TNAM - Texture Set\"},{\"t\":3,\"p\":1,\"n\":\"MNAM - Material Type\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"HNAM - Havok Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Friction\"},{\"t\":3,\"p\":1,\"n\":\"Restitution\"}]},{\"t\":3,\"p\":1,\"n\":\"SNAM - Texture Specular Exponent\"},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Grasses\",\"d\":1,\"c\":[{\"t\":3,\"p\":1,\"n\":\"GNAM - Grass\"}]},{\"t\":3,\"n\":\"INAM - Unused\"}]},{\"t\":1,\"p\":1,\"n\":\"LVLI - Leveled Item\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"X1\"},{\"t\":3,\"p\":1,\"n\":\"Y1\"},{\"t\":3,\"p\":1,\"n\":\"Z1\"},{\"t\":3,\"p\":1,\"n\":\"X2\"},{\"t\":3,\"p\":1,\"n\":\"Y2\"},{\"t\":3,\"p\":1,\"n\":\"Z2\"}]},{\"t\":3,\"p\":1,\"n\":\"LVLD - Chance None\"},{\"t\":3,\"p\":1,\"n\":\"LVLF - Flags\"},{\"t\":3,\"p\":1,\"n\":\"LVLG - Global\"},{\"t\":3,\"n\":\"LLCT - Count\"},{\"t\":10,\"p\":1,\"n\":\"Leveled List Entries\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Leveled List Entry\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"LVLO - Base Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Level\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":3,\"p\":1,\"n\":\"Count\"}]},{\"t\":6,\"p\":1,\"n\":\"COED - Extra Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Owner\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Global Variable\"},{\"t\":3,\"p\":1,\"n\":\"Required Rank\"},{\"t\":5,\"p\":1,\"n\":\"Item Condition\"}]}]}]}]},{\"t\":1,\"p\":1,\"n\":\"LVLN - Leveled NPC\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"X1\"},{\"t\":3,\"p\":1,\"n\":\"Y1\"},{\"t\":3,\"p\":1,\"n\":\"Z1\"},{\"t\":3,\"p\":1,\"n\":\"X2\"},{\"t\":3,\"p\":1,\"n\":\"Y2\"},{\"t\":3,\"p\":1,\"n\":\"Z2\"}]},{\"t\":3,\"p\":1,\"n\":\"LVLD - Chance None\"},{\"t\":3,\"p\":1,\"n\":\"LVLF - Flags\"},{\"t\":3,\"p\":1,\"n\":\"LVLG - Global\"},{\"t\":3,\"n\":\"LLCT - Count\"},{\"t\":10,\"p\":1,\"n\":\"Leveled List Entries\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Leveled List Entry\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"LVLO - Base Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Level\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":3,\"p\":1,\"n\":\"Count\"}]},{\"t\":6,\"p\":1,\"n\":\"COED - Extra Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Owner\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Global Variable\"},{\"t\":3,\"p\":1,\"n\":\"Required Rank\"},{\"t\":5,\"p\":1,\"n\":\"Item Condition\"}]}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"MODT - Texture Files Hashes\"},{\"t\":7,\"p\":1,\"n\":\"MODS - Alternate Textures\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"3D Name\"},{\"t\":3,\"p\":1,\"n\":\"New Texture\"},{\"t\":3,\"p\":1,\"n\":\"3D Index\"}]}]}]}]},{\"t\":1,\"p\":1,\"n\":\"LVSP - Leveled Spell\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"X1\"},{\"t\":3,\"p\":1,\"n\":\"Y1\"},{\"t\":3,\"p\":1,\"n\":\"Z1\"},{\"t\":3,\"p\":1,\"n\":\"X2\"},{\"t\":3,\"p\":1,\"n\":\"Y2\"},{\"t\":3,\"p\":1,\"n\":\"Z2\"}]},{\"t\":3,\"p\":1,\"n\":\"LVLD - Chance None\"},{\"t\":3,\"p\":1,\"n\":\"LVLF - Flags\"},{\"t\":3,\"n\":\"LLCT - Count\"},{\"t\":10,\"p\":1,\"n\":\"Leveled List Entries\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Leveled List Entry\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"LVLO - Base Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Level\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":3,\"p\":1,\"n\":\"Count\"}]}]}]}]},{\"t\":1,\"p\":1,\"n\":\"MATO - Material Object\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"MODT - Texture Files Hashes\"},{\"t\":7,\"p\":1,\"n\":\"MODS - Alternate Textures\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"3D Name\"},{\"t\":3,\"p\":1,\"n\":\"New Texture\"},{\"t\":3,\"p\":1,\"n\":\"3D Index\"}]}]}]},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Property Data\",\"d\":1,\"c\":[{\"t\":11,\"p\":1,\"n\":\"DNAM - Data\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DATA - Directional Material Data\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Falloff Scale\"},{\"t\":5,\"p\":1,\"n\":\"Falloff Bias\"},{\"t\":5,\"p\":1,\"n\":\"Noise UV Scale\"},{\"t\":5,\"p\":1,\"n\":\"Material UV Scale\"},{\"t\":6,\"p\":1,\"n\":\"Projection Vector\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"X\"},{\"t\":5,\"p\":1,\"n\":\"Y\"},{\"t\":5,\"p\":1,\"n\":\"Z\"}]},{\"t\":5,\"p\":1,\"n\":\"Normal Dampener\"},{\"t\":6,\"p\":1,\"n\":\"Single Pass Color\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Red\"},{\"t\":5,\"p\":1,\"n\":\"Green\"},{\"t\":5,\"p\":1,\"n\":\"Blue\"}]},{\"t\":3,\"p\":1,\"n\":\"Flags\"}]}]},{\"t\":1,\"p\":1,\"n\":\"MATT - Material Type\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":3,\"p\":1,\"n\":\"PNAM - Material Parent\"},{\"t\":2,\"p\":1,\"n\":\"MNAM - Material Name\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"CNAM - Havok Display Color\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Red\"},{\"t\":5,\"p\":1,\"n\":\"Green\"},{\"t\":5,\"p\":1,\"n\":\"Blue\"}]},{\"t\":5,\"p\":1,\"n\":\"BNAM - Buoyancy\"},{\"t\":3,\"p\":1,\"n\":\"FNAM - Flags\"},{\"t\":3,\"p\":1,\"n\":\"HNAM - Havok Impact Data Set\"}]},{\"t\":1,\"p\":1,\"n\":\"MESG - Message\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"p\":1,\"n\":\"DESC - Description\"},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":3,\"p\":1,\"n\":\"INAM - Icon (unused)\"},{\"t\":3,\"p\":1,\"n\":\"QNAM - Owner Quest\"},{\"t\":3,\"p\":1,\"n\":\"DNAM - Flags\"},{\"t\":3,\"p\":1,\"n\":\"TNAM - Display Time\"},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Menu Buttons\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Menu Button\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"ITXT - Button Text\"},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Conditions\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Condition\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"CTDA - \",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":5,\"p\":1,\"n\":\"Comparison Value - Float\"},{\"t\":3,\"p\":1,\"n\":\"Comparison Value - Global\"},{\"t\":3,\"p\":1,\"n\":\"Function\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":11,\"p\":1,\"n\":\"None\"},{\"t\":3,\"p\":1,\"n\":\"Integer\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":11,\"p\":1,\"n\":\"Variable Name (unused)\"},{\"t\":3,\"p\":1,\"n\":\"Sex\"},{\"t\":3,\"p\":1,\"n\":\"Actor Value\"},{\"t\":3,\"p\":1,\"n\":\"Crime Type\"},{\"t\":3,\"p\":1,\"n\":\"Axis\"},{\"t\":3,\"p\":1,\"n\":\"Quest Stage (unused)\"},{\"t\":3,\"p\":1,\"n\":\"Misc Stat\"},{\"t\":3,\"p\":1,\"n\":\"Alignment\"},{\"t\":3,\"p\":1,\"n\":\"Equip Type\"},{\"t\":3,\"p\":1,\"n\":\"Form Type\"},{\"t\":3,\"p\":1,\"n\":\"Critical Stage\"},{\"t\":3,\"p\":1,\"n\":\"Object Reference\"},{\"t\":3,\"p\":1,\"n\":\"Inventory Object\"},{\"t\":3,\"p\":1,\"n\":\"Actor\"},{\"t\":3,\"p\":1,\"n\":\"Voice Type\"},{\"t\":3,\"p\":1,\"n\":\"Idle\"},{\"t\":3,\"p\":1,\"n\":\"Form List\"},{\"t\":3,\"p\":1,\"n\":\"Quest\"},{\"t\":3,\"p\":1,\"n\":\"Faction\"},{\"t\":3,\"p\":1,\"n\":\"Cell\"},{\"t\":3,\"p\":1,\"n\":\"Class\"},{\"t\":3,\"p\":1,\"n\":\"Race\"},{\"t\":3,\"p\":1,\"n\":\"Actor Base\"},{\"t\":3,\"p\":1,\"n\":\"Global\"},{\"t\":3,\"p\":1,\"n\":\"Weather\"},{\"t\":3,\"p\":1,\"n\":\"Package\"},{\"t\":3,\"p\":1,\"n\":\"Encounter Zone\"},{\"t\":3,\"p\":1,\"n\":\"Perk\"},{\"t\":3,\"p\":1,\"n\":\"Owner\"},{\"t\":3,\"p\":1,\"n\":\"Furniture\"},{\"t\":3,\"p\":1,\"n\":\"Effect Item\"},{\"t\":3,\"p\":1,\"n\":\"Base Effect\"},{\"t\":3,\"p\":1,\"n\":\"Worldspace\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Function\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Param (INVALID)\"},{\"t\":3,\"p\":1,\"n\":\"Referenceable Object\"},{\"t\":3,\"p\":1,\"n\":\"Region\"},{\"t\":3,\"p\":1,\"n\":\"Keyword\"},{\"t\":3,\"p\":1,\"n\":\"Player Action\"},{\"t\":3,\"p\":1,\"n\":\"Casting Type\"},{\"t\":3,\"p\":1,\"n\":\"Shout\"},{\"t\":3,\"p\":1,\"n\":\"Location\"},{\"t\":3,\"p\":1,\"n\":\"Location Ref Type\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"Packdata ID\"},{\"t\":3,\"p\":1,\"n\":\"Association Type\"},{\"t\":3,\"p\":1,\"n\":\"Furniture Anim\"},{\"t\":3,\"p\":1,\"n\":\"Furniture Entry\"},{\"t\":3,\"p\":1,\"n\":\"Scene\"},{\"t\":3,\"p\":1,\"n\":\"Ward State\"},{\"t\":3,\"p\":1,\"n\":\"Event\"},{\"t\":3,\"p\":1,\"n\":\"Event Data\"},{\"t\":3,\"p\":1,\"n\":\"Quest Stage\"},{\"t\":3,\"p\":1,\"n\":\"Weapon\"},{\"t\":3,\"p\":1,\"n\":\"Weapon List\"},{\"t\":3,\"p\":1,\"n\":\"Target\"},{\"t\":3,\"p\":1,\"n\":\"Target List\"},{\"t\":3,\"p\":1,\"n\":\"Target Part\"},{\"t\":3,\"p\":1,\"n\":\"VATS Action\"},{\"t\":3,\"p\":1,\"n\":\"Critical Effect\"},{\"t\":3,\"p\":1,\"n\":\"Critical Effect List\"},{\"t\":3,\"p\":1,\"n\":\"Weapon Type\"},{\"t\":3,\"p\":1,\"n\":\"Projectile Type\"},{\"t\":3,\"p\":1,\"n\":\"Delivery Type\"},{\"t\":3,\"p\":1,\"n\":\"Run On\"},{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":3,\"p\":1,\"n\":\"Parameter #3\"}]},{\"t\":2,\"p\":1,\"n\":\"CIS1 - Parameter #1\"},{\"t\":2,\"p\":1,\"n\":\"CIS2 - Parameter #2\"}]}]}]}]}]},{\"t\":1,\"p\":1,\"n\":\"MGEF - Magic Effect\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"VMAD - Virtual Machine Adapter\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Version\"},{\"t\":3,\"p\":1,\"n\":\"Object Format\"},{\"t\":7,\"p\":1,\"n\":\"Scripts\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Script\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"scriptName\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":7,\"p\":1,\"n\":\"Properties\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Property\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"propertyName\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]},{\"t\":2,\"p\":1,\"n\":\"String\"},{\"t\":3,\"p\":1,\"n\":\"Int32\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":3,\"p\":1,\"n\":\"Bool\"},{\"t\":7,\"p\":1,\"n\":\"Array of Object\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]}]},{\"t\":7,\"p\":1,\"n\":\"Array of String\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Int32\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Float\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Bool\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]}]}]}]}]}]},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":3,\"p\":1,\"n\":\"MDOB - Menu Display Object\"},{\"t\":3,\"n\":\"KSIZ - Keyword Count\"},{\"t\":7,\"p\":1,\"n\":\"KWDA - Keywords\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Keyword\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Magic Effect Data\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"DATA - Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":5,\"p\":1,\"n\":\"Base Cost\"},{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Assoc. Item\"},{\"t\":3,\"p\":1,\"n\":\"Magic Skill\"},{\"t\":3,\"p\":1,\"n\":\"Resist Value\"},{\"t\":3,\"p\":1,\"n\":\"Counter Effect count\"},{\"t\":3,\"p\":1,\"n\":\"Casting Light\"},{\"t\":5,\"p\":1,\"n\":\"Taper Weight\"},{\"t\":3,\"p\":1,\"n\":\"Hit Shader\"},{\"t\":3,\"p\":1,\"n\":\"Enchant Shader\"},{\"t\":3,\"p\":1,\"n\":\"Minimum Skill Level\"},{\"t\":6,\"p\":1,\"n\":\"Spellmaking\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Area\"},{\"t\":5,\"p\":1,\"n\":\"Casting Time\"}]},{\"t\":5,\"p\":1,\"n\":\"Taper Curve\"},{\"t\":5,\"p\":1,\"n\":\"Taper Duration\"},{\"t\":5,\"p\":1,\"n\":\"Second AV Weight\"},{\"t\":3,\"p\":1,\"n\":\"Archtype\"},{\"t\":3,\"p\":1,\"n\":\"Actor Value\"},{\"t\":3,\"p\":1,\"n\":\"Projectile\"},{\"t\":3,\"p\":1,\"n\":\"Explosion\"},{\"t\":3,\"p\":1,\"n\":\"Casting Type\"},{\"t\":3,\"p\":1,\"n\":\"Delivery\"},{\"t\":3,\"p\":1,\"n\":\"Second Actor Value\"},{\"t\":3,\"p\":1,\"n\":\"Casting Art\"},{\"t\":3,\"p\":1,\"n\":\"Hit Effect Art\"},{\"t\":3,\"p\":1,\"n\":\"Impact Data\"},{\"t\":5,\"p\":1,\"n\":\"Skill Usage Multiplier\"},{\"t\":6,\"p\":1,\"n\":\"Dual Casting\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Art\"},{\"t\":5,\"p\":1,\"n\":\"Scale\"}]},{\"t\":3,\"p\":1,\"n\":\"Enchant Art\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":3,\"p\":1,\"n\":\"Equip Ability\"},{\"t\":3,\"p\":1,\"n\":\"Image Space Modifier\"},{\"t\":3,\"p\":1,\"n\":\"Perk to Apply\"},{\"t\":3,\"p\":1,\"n\":\"Casting Sound Level\"},{\"t\":6,\"p\":1,\"n\":\"Script Effect AI\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Score\"},{\"t\":5,\"p\":1,\"n\":\"Delay Time\"}]}]}]},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Counter Effects\",\"d\":1,\"c\":[{\"t\":3,\"n\":\"ESCE - Effect\"}]},{\"t\":7,\"p\":1,\"n\":\"SNDD - Sounds\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Sound\"}]}]},{\"t\":2,\"p\":1,\"n\":\"DNAM - Magic Item Description\"},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Conditions\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Condition\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"CTDA - \",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":5,\"p\":1,\"n\":\"Comparison Value - Float\"},{\"t\":3,\"p\":1,\"n\":\"Comparison Value - Global\"},{\"t\":3,\"p\":1,\"n\":\"Function\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":11,\"p\":1,\"n\":\"None\"},{\"t\":3,\"p\":1,\"n\":\"Integer\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":11,\"p\":1,\"n\":\"Variable Name (unused)\"},{\"t\":3,\"p\":1,\"n\":\"Sex\"},{\"t\":3,\"p\":1,\"n\":\"Actor Value\"},{\"t\":3,\"p\":1,\"n\":\"Crime Type\"},{\"t\":3,\"p\":1,\"n\":\"Axis\"},{\"t\":3,\"p\":1,\"n\":\"Quest Stage (unused)\"},{\"t\":3,\"p\":1,\"n\":\"Misc Stat\"},{\"t\":3,\"p\":1,\"n\":\"Alignment\"},{\"t\":3,\"p\":1,\"n\":\"Equip Type\"},{\"t\":3,\"p\":1,\"n\":\"Form Type\"},{\"t\":3,\"p\":1,\"n\":\"Critical Stage\"},{\"t\":3,\"p\":1,\"n\":\"Object Reference\"},{\"t\":3,\"p\":1,\"n\":\"Inventory Object\"},{\"t\":3,\"p\":1,\"n\":\"Actor\"},{\"t\":3,\"p\":1,\"n\":\"Voice Type\"},{\"t\":3,\"p\":1,\"n\":\"Idle\"},{\"t\":3,\"p\":1,\"n\":\"Form List\"},{\"t\":3,\"p\":1,\"n\":\"Quest\"},{\"t\":3,\"p\":1,\"n\":\"Faction\"},{\"t\":3,\"p\":1,\"n\":\"Cell\"},{\"t\":3,\"p\":1,\"n\":\"Class\"},{\"t\":3,\"p\":1,\"n\":\"Race\"},{\"t\":3,\"p\":1,\"n\":\"Actor Base\"},{\"t\":3,\"p\":1,\"n\":\"Global\"},{\"t\":3,\"p\":1,\"n\":\"Weather\"},{\"t\":3,\"p\":1,\"n\":\"Package\"},{\"t\":3,\"p\":1,\"n\":\"Encounter Zone\"},{\"t\":3,\"p\":1,\"n\":\"Perk\"},{\"t\":3,\"p\":1,\"n\":\"Owner\"},{\"t\":3,\"p\":1,\"n\":\"Furniture\"},{\"t\":3,\"p\":1,\"n\":\"Effect Item\"},{\"t\":3,\"p\":1,\"n\":\"Base Effect\"},{\"t\":3,\"p\":1,\"n\":\"Worldspace\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Function\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Param (INVALID)\"},{\"t\":3,\"p\":1,\"n\":\"Referenceable Object\"},{\"t\":3,\"p\":1,\"n\":\"Region\"},{\"t\":3,\"p\":1,\"n\":\"Keyword\"},{\"t\":3,\"p\":1,\"n\":\"Player Action\"},{\"t\":3,\"p\":1,\"n\":\"Casting Type\"},{\"t\":3,\"p\":1,\"n\":\"Shout\"},{\"t\":3,\"p\":1,\"n\":\"Location\"},{\"t\":3,\"p\":1,\"n\":\"Location Ref Type\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"Packdata ID\"},{\"t\":3,\"p\":1,\"n\":\"Association Type\"},{\"t\":3,\"p\":1,\"n\":\"Furniture Anim\"},{\"t\":3,\"p\":1,\"n\":\"Furniture Entry\"},{\"t\":3,\"p\":1,\"n\":\"Scene\"},{\"t\":3,\"p\":1,\"n\":\"Ward State\"},{\"t\":3,\"p\":1,\"n\":\"Event\"},{\"t\":3,\"p\":1,\"n\":\"Event Data\"},{\"t\":3,\"p\":1,\"n\":\"Quest Stage\"},{\"t\":3,\"p\":1,\"n\":\"Weapon\"},{\"t\":3,\"p\":1,\"n\":\"Weapon List\"},{\"t\":3,\"p\":1,\"n\":\"Target\"},{\"t\":3,\"p\":1,\"n\":\"Target List\"},{\"t\":3,\"p\":1,\"n\":\"Target Part\"},{\"t\":3,\"p\":1,\"n\":\"VATS Action\"},{\"t\":3,\"p\":1,\"n\":\"Critical Effect\"},{\"t\":3,\"p\":1,\"n\":\"Critical Effect List\"},{\"t\":3,\"p\":1,\"n\":\"Weapon Type\"},{\"t\":3,\"p\":1,\"n\":\"Projectile Type\"},{\"t\":3,\"p\":1,\"n\":\"Delivery Type\"},{\"t\":3,\"p\":1,\"n\":\"Run On\"},{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":3,\"p\":1,\"n\":\"Parameter #3\"}]},{\"t\":2,\"p\":1,\"n\":\"CIS1 - Parameter #1\"},{\"t\":2,\"p\":1,\"n\":\"CIS2 - Parameter #2\"}]}]}]},{\"t\":1,\"p\":1,\"n\":\"MISC - Misc. Item\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"VMAD - Virtual Machine Adapter\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Version\"},{\"t\":3,\"p\":1,\"n\":\"Object Format\"},{\"t\":7,\"p\":1,\"n\":\"Scripts\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Script\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"scriptName\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":7,\"p\":1,\"n\":\"Properties\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Property\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"propertyName\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]},{\"t\":2,\"p\":1,\"n\":\"String\"},{\"t\":3,\"p\":1,\"n\":\"Int32\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":3,\"p\":1,\"n\":\"Bool\"},{\"t\":7,\"p\":1,\"n\":\"Array of Object\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]}]},{\"t\":7,\"p\":1,\"n\":\"Array of String\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Int32\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Float\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Bool\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]}]}]}]}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"X1\"},{\"t\":3,\"p\":1,\"n\":\"Y1\"},{\"t\":3,\"p\":1,\"n\":\"Z1\"},{\"t\":3,\"p\":1,\"n\":\"X2\"},{\"t\":3,\"p\":1,\"n\":\"Y2\"},{\"t\":3,\"p\":1,\"n\":\"Z2\"}]},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"MODT - Texture Files Hashes\"},{\"t\":7,\"p\":1,\"n\":\"MODS - Alternate Textures\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"3D Name\"},{\"t\":3,\"p\":1,\"n\":\"New Texture\"},{\"t\":3,\"p\":1,\"n\":\"3D Index\"}]}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Icon\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"ICON - Large Icon filename\"},{\"t\":2,\"p\":1,\"n\":\"MICO - Small Icon filename\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Destructable\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"DEST - Header\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Health\"},{\"t\":3,\"p\":1,\"n\":\"DEST Count\"},{\"t\":3,\"p\":1,\"n\":\"VATS Targetable\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":8,\"p\":1,\"n\":\"Stages\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Stage\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"DSTD - Destruction Stage Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Health %\"},{\"t\":3,\"p\":1,\"n\":\"Index\"},{\"t\":3,\"p\":1,\"n\":\"Model Damage Stage\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":3,\"p\":1,\"n\":\"Self Damage per Second\"},{\"t\":3,\"p\":1,\"n\":\"Explosion\"},{\"t\":3,\"p\":1,\"n\":\"Debris\"},{\"t\":3,\"p\":1,\"n\":\"Debris Count\"}]},{\"t\":6,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"DMDL - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"DMDT - Texture Files Hashes\"},{\"t\":7,\"p\":1,\"n\":\"DMDS - Alternate Textures\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"3D Name\"},{\"t\":3,\"p\":1,\"n\":\"New Texture\"},{\"t\":3,\"p\":1,\"n\":\"3D Index\"}]}]}]},{\"p\":1,\"n\":\"DSTF - End Marker\"}]}]}]},{\"t\":3,\"p\":1,\"n\":\"YNAM - Sound - Pick Up\"},{\"t\":3,\"p\":1,\"n\":\"ZNAM - Sound - Put Down\"},{\"t\":3,\"n\":\"KSIZ - Keyword Count\"},{\"t\":7,\"p\":1,\"n\":\"KWDA - Keywords\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Keyword\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DATA - Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Value\"},{\"t\":5,\"p\":1,\"n\":\"Weight\"}]}]},{\"t\":1,\"p\":1,\"n\":\"MOVT - Movement Type\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"p\":1,\"n\":\"MNAM - Name\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"SPED - Default Data\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Left Walk\"},{\"t\":5,\"p\":1,\"n\":\"Left Run\"},{\"t\":5,\"p\":1,\"n\":\"Right Walk\"},{\"t\":5,\"p\":1,\"n\":\"Right Run\"},{\"t\":5,\"p\":1,\"n\":\"Forward Walk\"},{\"t\":5,\"p\":1,\"n\":\"Forward Run\"},{\"t\":5,\"p\":1,\"n\":\"Back Walk\"},{\"t\":5,\"p\":1,\"n\":\"Back Run\"},{\"t\":5,\"p\":1,\"n\":\"Rotate in Place Walk\"},{\"t\":5,\"p\":1,\"n\":\"Rotate in Place Run\"},{\"t\":5,\"p\":1,\"n\":\"Rotate while Moving Run\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"INAM - Anim Change Thresholds\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Directional\"},{\"t\":5,\"p\":1,\"n\":\"Movement Speed\"},{\"t\":5,\"p\":1,\"n\":\"Rotation Speed\"}]}]},{\"t\":1,\"p\":1,\"n\":\"MSTT - Moveable Static\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"X1\"},{\"t\":3,\"p\":1,\"n\":\"Y1\"},{\"t\":3,\"p\":1,\"n\":\"Z1\"},{\"t\":3,\"p\":1,\"n\":\"X2\"},{\"t\":3,\"p\":1,\"n\":\"Y2\"},{\"t\":3,\"p\":1,\"n\":\"Z2\"}]},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"MODT - Texture Files Hashes\"},{\"t\":7,\"p\":1,\"n\":\"MODS - Alternate Textures\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"3D Name\"},{\"t\":3,\"p\":1,\"n\":\"New Texture\"},{\"t\":3,\"p\":1,\"n\":\"3D Index\"}]}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Destructable\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"DEST - Header\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Health\"},{\"t\":3,\"p\":1,\"n\":\"DEST Count\"},{\"t\":3,\"p\":1,\"n\":\"VATS Targetable\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":8,\"p\":1,\"n\":\"Stages\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Stage\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"DSTD - Destruction Stage Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Health %\"},{\"t\":3,\"p\":1,\"n\":\"Index\"},{\"t\":3,\"p\":1,\"n\":\"Model Damage Stage\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":3,\"p\":1,\"n\":\"Self Damage per Second\"},{\"t\":3,\"p\":1,\"n\":\"Explosion\"},{\"t\":3,\"p\":1,\"n\":\"Debris\"},{\"t\":3,\"p\":1,\"n\":\"Debris Count\"}]},{\"t\":6,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"DMDL - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"DMDT - Texture Files Hashes\"},{\"t\":7,\"p\":1,\"n\":\"DMDS - Alternate Textures\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"3D Name\"},{\"t\":3,\"p\":1,\"n\":\"New Texture\"},{\"t\":3,\"p\":1,\"n\":\"3D Index\"}]}]}]},{\"p\":1,\"n\":\"DSTF - End Marker\"}]}]}]},{\"t\":3,\"p\":1,\"n\":\"DATA - Flags\"},{\"t\":3,\"p\":1,\"n\":\"SNAM - Looping Sound\"}]},{\"t\":1,\"p\":1,\"n\":\"MUSC - Music Type\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":3,\"p\":1,\"n\":\"FNAM - Flags\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"PNAM - Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Priority\"},{\"t\":3,\"p\":1,\"n\":\"Ducking (dB)\"}]},{\"t\":5,\"p\":1,\"n\":\"WNAM - Fade Duration\"},{\"t\":7,\"p\":1,\"n\":\"TNAM - Music Tracks\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Track\"}]}]},{\"t\":1,\"p\":1,\"n\":\"MUST - Music Track\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":3,\"p\":1,\"n\":\"CNAM - Track Type\"},{\"t\":5,\"p\":1,\"n\":\"FLTV - Duration\"},{\"t\":5,\"p\":1,\"n\":\"DNAM - Fade-Out\"},{\"t\":2,\"p\":1,\"n\":\"ANAM - Track Filename\"},{\"t\":2,\"p\":1,\"n\":\"BNAM - Finale Filename\"},{\"t\":7,\"p\":1,\"n\":\"FNAM - Cue Points\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Point\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"LNAM - Loop Data\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Loop Begins\"},{\"t\":5,\"p\":1,\"n\":\"Loop Ends\"},{\"t\":3,\"p\":1,\"n\":\"Loop Count\"}]},{\"t\":3,\"n\":\"CITC - Condition Count\"},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Conditions\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Condition\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"CTDA - \",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":5,\"p\":1,\"n\":\"Comparison Value - Float\"},{\"t\":3,\"p\":1,\"n\":\"Comparison Value - Global\"},{\"t\":3,\"p\":1,\"n\":\"Function\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":11,\"p\":1,\"n\":\"None\"},{\"t\":3,\"p\":1,\"n\":\"Integer\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":11,\"p\":1,\"n\":\"Variable Name (unused)\"},{\"t\":3,\"p\":1,\"n\":\"Sex\"},{\"t\":3,\"p\":1,\"n\":\"Actor Value\"},{\"t\":3,\"p\":1,\"n\":\"Crime Type\"},{\"t\":3,\"p\":1,\"n\":\"Axis\"},{\"t\":3,\"p\":1,\"n\":\"Quest Stage (unused)\"},{\"t\":3,\"p\":1,\"n\":\"Misc Stat\"},{\"t\":3,\"p\":1,\"n\":\"Alignment\"},{\"t\":3,\"p\":1,\"n\":\"Equip Type\"},{\"t\":3,\"p\":1,\"n\":\"Form Type\"},{\"t\":3,\"p\":1,\"n\":\"Critical Stage\"},{\"t\":3,\"p\":1,\"n\":\"Object Reference\"},{\"t\":3,\"p\":1,\"n\":\"Inventory Object\"},{\"t\":3,\"p\":1,\"n\":\"Actor\"},{\"t\":3,\"p\":1,\"n\":\"Voice Type\"},{\"t\":3,\"p\":1,\"n\":\"Idle\"},{\"t\":3,\"p\":1,\"n\":\"Form List\"},{\"t\":3,\"p\":1,\"n\":\"Quest\"},{\"t\":3,\"p\":1,\"n\":\"Faction\"},{\"t\":3,\"p\":1,\"n\":\"Cell\"},{\"t\":3,\"p\":1,\"n\":\"Class\"},{\"t\":3,\"p\":1,\"n\":\"Race\"},{\"t\":3,\"p\":1,\"n\":\"Actor Base\"},{\"t\":3,\"p\":1,\"n\":\"Global\"},{\"t\":3,\"p\":1,\"n\":\"Weather\"},{\"t\":3,\"p\":1,\"n\":\"Package\"},{\"t\":3,\"p\":1,\"n\":\"Encounter Zone\"},{\"t\":3,\"p\":1,\"n\":\"Perk\"},{\"t\":3,\"p\":1,\"n\":\"Owner\"},{\"t\":3,\"p\":1,\"n\":\"Furniture\"},{\"t\":3,\"p\":1,\"n\":\"Effect Item\"},{\"t\":3,\"p\":1,\"n\":\"Base Effect\"},{\"t\":3,\"p\":1,\"n\":\"Worldspace\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Function\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Param (INVALID)\"},{\"t\":3,\"p\":1,\"n\":\"Referenceable Object\"},{\"t\":3,\"p\":1,\"n\":\"Region\"},{\"t\":3,\"p\":1,\"n\":\"Keyword\"},{\"t\":3,\"p\":1,\"n\":\"Player Action\"},{\"t\":3,\"p\":1,\"n\":\"Casting Type\"},{\"t\":3,\"p\":1,\"n\":\"Shout\"},{\"t\":3,\"p\":1,\"n\":\"Location\"},{\"t\":3,\"p\":1,\"n\":\"Location Ref Type\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"Packdata ID\"},{\"t\":3,\"p\":1,\"n\":\"Association Type\"},{\"t\":3,\"p\":1,\"n\":\"Furniture Anim\"},{\"t\":3,\"p\":1,\"n\":\"Furniture Entry\"},{\"t\":3,\"p\":1,\"n\":\"Scene\"},{\"t\":3,\"p\":1,\"n\":\"Ward State\"},{\"t\":3,\"p\":1,\"n\":\"Event\"},{\"t\":3,\"p\":1,\"n\":\"Event Data\"},{\"t\":3,\"p\":1,\"n\":\"Quest Stage\"},{\"t\":3,\"p\":1,\"n\":\"Weapon\"},{\"t\":3,\"p\":1,\"n\":\"Weapon List\"},{\"t\":3,\"p\":1,\"n\":\"Target\"},{\"t\":3,\"p\":1,\"n\":\"Target List\"},{\"t\":3,\"p\":1,\"n\":\"Target Part\"},{\"t\":3,\"p\":1,\"n\":\"VATS Action\"},{\"t\":3,\"p\":1,\"n\":\"Critical Effect\"},{\"t\":3,\"p\":1,\"n\":\"Critical Effect List\"},{\"t\":3,\"p\":1,\"n\":\"Weapon Type\"},{\"t\":3,\"p\":1,\"n\":\"Projectile Type\"},{\"t\":3,\"p\":1,\"n\":\"Delivery Type\"},{\"t\":3,\"p\":1,\"n\":\"Run On\"},{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":3,\"p\":1,\"n\":\"Parameter #3\"}]},{\"t\":2,\"p\":1,\"n\":\"CIS1 - Parameter #1\"},{\"t\":2,\"p\":1,\"n\":\"CIS2 - Parameter #2\"}]}]},{\"t\":7,\"p\":1,\"n\":\"SNAM - Tracks\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Track\"}]}]},{\"t\":1,\"n\":\"NAVI - Navigation Mesh Info Map\",\"c\":[{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":3,\"n\":\"NVER - Version\"},{\"t\":8,\"n\":\"Navigation Map Infos\",\"c\":[{\"t\":6,\"n\":\"NVMI - Navigation Map Info\",\"c\":[{\"t\":3,\"n\":\"Navigation Mesh\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":5,\"n\":\"X\"},{\"t\":5,\"n\":\"Y\"},{\"t\":5,\"n\":\"Z\"},{\"t\":3,\"n\":\"Preferred Merges Flag\"},{\"t\":7,\"n\":\"Merged To\",\"c\":[{\"t\":3,\"n\":\"Mesh\"}]},{\"t\":7,\"n\":\"Preferred Merges\",\"c\":[{\"t\":3,\"n\":\"Mesh\"}]},{\"t\":7,\"n\":\"Linked Doors\",\"c\":[{\"t\":6,\"n\":\"Door\",\"c\":[{\"t\":11,\"n\":\"Unknown\"},{\"t\":3,\"n\":\"Door Ref\"}]}]},{\"t\":3,\"n\":\"Is Island\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":6,\"n\":\"Island Data\",\"c\":[{\"t\":11,\"n\":\"Unknown\"},{\"t\":7,\"n\":\"Triangles\",\"c\":[{\"t\":11,\"n\":\"Triangle\"}]},{\"t\":7,\"n\":\"Vertices\",\"c\":[{\"t\":11,\"n\":\"Vertex\"}]}]},{\"t\":3,\"n\":\"Parent Worldspace\"},{\"t\":6,\"n\":\"Coordinates\",\"c\":[{\"t\":3,\"n\":\"Grid Y\"},{\"t\":3,\"n\":\"Grid X\"}]},{\"t\":3,\"n\":\"Parent Cell\"}]}]},{\"t\":6,\"n\":\"NVPP - Preferred Pathing\",\"c\":[{\"t\":7,\"n\":\"NavMeshes\",\"c\":[{\"t\":7,\"n\":\"Set\",\"c\":[{\"t\":3,\"n\":\"\"}]}]},{\"t\":7,\"n\":\"NavMesh Tree?\",\"c\":[{\"t\":6,\"n\":\"\",\"c\":[{\"t\":3,\"n\":\"NavMesh\"},{\"t\":3,\"n\":\"Index\\/Node\"}]}]}]},{\"t\":7,\"n\":\"NVSI - Unknown\",\"c\":[{\"t\":3,\"n\":\"Navigation Mesh\"}]}]},{\"t\":1,\"n\":\"NAVM - Navigation Mesh\",\"c\":[{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"n\":\"NVNM - Geometry\",\"c\":[{\"t\":11,\"n\":\"Unknown\"},{\"t\":3,\"n\":\"Parent Worldspace\"},{\"t\":6,\"n\":\"Coordinates\",\"c\":[{\"t\":3,\"n\":\"Grid Y\"},{\"t\":3,\"n\":\"Grid X\"}]},{\"t\":3,\"n\":\"Parent Cell\"},{\"t\":7,\"n\":\"Vertices\",\"c\":[{\"t\":11,\"n\":\"Vertex\"}]},{\"t\":7,\"n\":\"Triangles\",\"c\":[{\"t\":11,\"n\":\"Triangle\"}]},{\"t\":7,\"n\":\"External Connections\",\"c\":[{\"t\":6,\"n\":\"Connection\",\"c\":[{\"t\":11,\"n\":\"Unknown\"},{\"t\":3,\"n\":\"Mesh\"},{\"t\":3,\"n\":\"Triangle\"}]}]},{\"t\":7,\"n\":\"Door Triangles\",\"c\":[{\"t\":6,\"n\":\"Door Triangle\",\"c\":[{\"t\":3,\"n\":\"Triangle before door\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":3,\"n\":\"Door\"}]}]}]},{\"t\":11,\"n\":\"ONAM - Unknown\"},{\"t\":11,\"n\":\"PNAM - Unknown\"},{\"t\":11,\"n\":\"NNAM - Unknown\"}]},{\"t\":1,\"p\":1,\"n\":\"NPC_ - Non-Player Character (Actor)\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"VMAD - Virtual Machine Adapter\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Version\"},{\"t\":3,\"p\":1,\"n\":\"Object Format\"},{\"t\":7,\"p\":1,\"n\":\"Scripts\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Script\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"scriptName\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":7,\"p\":1,\"n\":\"Properties\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Property\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"propertyName\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]},{\"t\":2,\"p\":1,\"n\":\"String\"},{\"t\":3,\"p\":1,\"n\":\"Int32\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":3,\"p\":1,\"n\":\"Bool\"},{\"t\":7,\"p\":1,\"n\":\"Array of Object\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]}]},{\"t\":7,\"p\":1,\"n\":\"Array of String\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Int32\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Float\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Bool\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]}]}]}]}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"X1\"},{\"t\":3,\"p\":1,\"n\":\"Y1\"},{\"t\":3,\"p\":1,\"n\":\"Z1\"},{\"t\":3,\"p\":1,\"n\":\"X2\"},{\"t\":3,\"p\":1,\"n\":\"Y2\"},{\"t\":3,\"p\":1,\"n\":\"Z2\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"ACBS - Configuration\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":3,\"p\":1,\"n\":\"Magicka Offset\"},{\"t\":3,\"p\":1,\"n\":\"Stamina Offset\"},{\"t\":3,\"p\":1,\"n\":\"Level\"},{\"t\":3,\"p\":1,\"n\":\"Level Mult\"},{\"t\":3,\"p\":1,\"n\":\"Calc min level\"},{\"t\":3,\"p\":1,\"n\":\"Calc max level\"},{\"t\":3,\"p\":1,\"n\":\"Speed Multiplier\"},{\"t\":3,\"p\":1,\"n\":\"Disposition Base (unused)\"},{\"t\":3,\"p\":1,\"n\":\"Template Flags\"},{\"t\":3,\"p\":1,\"n\":\"Health Offset\"},{\"t\":3,\"p\":1,\"n\":\"Bleedout Override\"}]},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Factions\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"SNAM - Faction\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Faction\"},{\"t\":3,\"p\":1,\"n\":\"Rank\"},{\"t\":11,\"n\":\"Unused\"}]}]},{\"t\":3,\"p\":1,\"n\":\"INAM - Death item\"},{\"t\":3,\"p\":1,\"n\":\"VTCK - Voice\"},{\"t\":3,\"p\":1,\"n\":\"TPLT - Template\"},{\"t\":3,\"p\":1,\"n\":\"RNAM - Race\",\"lt\":\"Tint Layers\",\"lf\":\"NAM7 - Weight\"},{\"t\":3,\"n\":\"SPCT - Count\"},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Actor Effects\",\"d\":1,\"c\":[{\"t\":3,\"p\":1,\"n\":\"SPLO - Actor Effect\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Destructable\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"DEST - Header\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Health\"},{\"t\":3,\"p\":1,\"n\":\"DEST Count\"},{\"t\":3,\"p\":1,\"n\":\"VATS Targetable\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":8,\"p\":1,\"n\":\"Stages\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Stage\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"DSTD - Destruction Stage Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Health %\"},{\"t\":3,\"p\":1,\"n\":\"Index\"},{\"t\":3,\"p\":1,\"n\":\"Model Damage Stage\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":3,\"p\":1,\"n\":\"Self Damage per Second\"},{\"t\":3,\"p\":1,\"n\":\"Explosion\"},{\"t\":3,\"p\":1,\"n\":\"Debris\"},{\"t\":3,\"p\":1,\"n\":\"Debris Count\"}]},{\"t\":6,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"DMDL - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"DMDT - Texture Files Hashes\"},{\"t\":7,\"p\":1,\"n\":\"DMDS - Alternate Textures\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"3D Name\"},{\"t\":3,\"p\":1,\"n\":\"New Texture\"},{\"t\":3,\"p\":1,\"n\":\"3D Index\"}]}]}]},{\"p\":1,\"n\":\"DSTF - End Marker\"}]}]}]},{\"t\":3,\"p\":1,\"n\":\"WNAM - Worn Armor\"},{\"t\":3,\"p\":1,\"n\":\"ANAM - Far away model\"},{\"t\":3,\"p\":1,\"n\":\"ATKR - Attack Race\"},{\"t\":10,\"p\":1,\"n\":\"Attacks\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Attack\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"ATKD - Attack Data\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Damage Mult\"},{\"t\":5,\"p\":1,\"n\":\"Attack Chance\"},{\"t\":3,\"p\":1,\"n\":\"Attack Spell\"},{\"t\":3,\"p\":1,\"n\":\"Attack Flags\"},{\"t\":5,\"p\":1,\"n\":\"Attack Angle\"},{\"t\":5,\"p\":1,\"n\":\"Strike Angle\"},{\"t\":5,\"p\":1,\"n\":\"Stagger\"},{\"t\":3,\"p\":1,\"n\":\"Attack Type\"},{\"t\":5,\"p\":1,\"n\":\"Knockdown\"},{\"t\":5,\"p\":1,\"n\":\"Recovery Time\"},{\"t\":5,\"p\":1,\"n\":\"Stamina Mult\"}]},{\"t\":2,\"p\":1,\"n\":\"ATKE - Attack Event\"}]}]},{\"t\":3,\"p\":1,\"n\":\"SPOR - Spectator override package list\"},{\"t\":3,\"p\":1,\"n\":\"OCOR - Observe dead body override package list\"},{\"t\":3,\"p\":1,\"n\":\"GWOR - Guard warn override package list\"},{\"t\":3,\"p\":1,\"n\":\"ECOR - Combat override package list\"},{\"t\":3,\"n\":\"PRKZ - Perk Count\"},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Perks\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"PRKR - Perk\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Perk\"},{\"t\":3,\"p\":1,\"n\":\"Rank\"},{\"t\":11,\"n\":\"Unused\"}]}]},{\"t\":3,\"n\":\"COCT - Count\"},{\"t\":10,\"p\":1,\"n\":\"Items\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Item\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"CNTO - Item\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Item\"},{\"t\":3,\"p\":1,\"n\":\"Count\"}]},{\"t\":6,\"p\":1,\"n\":\"COED - Extra Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Owner\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Global Variable\"},{\"t\":3,\"p\":1,\"n\":\"Required Rank\"},{\"t\":5,\"p\":1,\"n\":\"Item Condition\"}]}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"AIDT - AI Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Aggression\"},{\"t\":3,\"p\":1,\"n\":\"Confidence\"},{\"t\":3,\"p\":1,\"n\":\"Energy Level\"},{\"t\":3,\"p\":1,\"n\":\"Responsibility\"},{\"t\":3,\"p\":1,\"n\":\"Mood\"},{\"t\":3,\"p\":1,\"n\":\"Assistance\"},{\"t\":6,\"p\":1,\"n\":\"Aggro\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Aggro Radius Behavior\"},{\"t\":3,\"n\":\"Unknown\"},{\"t\":3,\"p\":1,\"n\":\"Warn\"},{\"t\":3,\"p\":1,\"n\":\"Warn\\/Attack\"},{\"t\":3,\"p\":1,\"n\":\"Attack\"}]}]},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Packages\",\"d\":1,\"c\":[{\"t\":3,\"p\":1,\"n\":\"PKID - Package\"}]},{\"t\":3,\"n\":\"KSIZ - Keyword Count\"},{\"t\":7,\"p\":1,\"n\":\"KWDA - Keywords\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Keyword\"}]},{\"t\":3,\"p\":1,\"n\":\"CNAM - Class\"},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":2,\"p\":1,\"n\":\"SHRT - Short Name\"},{\"t\":11,\"n\":\"DATA - Marker\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DNAM - Player Skills\",\"c\":[{\"t\":7,\"p\":1,\"n\":\"Skill Values\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Skill\"}]},{\"t\":7,\"p\":1,\"n\":\"Skill Offsets\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Skill\"}]},{\"t\":3,\"p\":1,\"n\":\"Health\"},{\"t\":3,\"p\":1,\"n\":\"Magicka\"},{\"t\":3,\"p\":1,\"n\":\"Stamina\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":5,\"p\":1,\"n\":\"Far away model distance\"},{\"t\":3,\"p\":1,\"n\":\"Geared up weapons\"}]},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Head Parts\",\"d\":1,\"c\":[{\"t\":3,\"p\":1,\"n\":\"PNAM - Head Part\"}],\"lt\":\"NAM6 - Height\",\"lf\":\"HCLF - Hair Color\"},{\"t\":3,\"p\":1,\"n\":\"HCLF - Hair Color\",\"lt\":\"Head Parts\",\"lf\":\"FTST - Head texture\"},{\"t\":3,\"p\":1,\"n\":\"ZNAM - Combat Style\"},{\"t\":3,\"p\":1,\"n\":\"GNAM - Gift Filter\"},{\"t\":11,\"n\":\"NAM5 - Unknown\"},{\"t\":5,\"p\":1,\"n\":\"NAM6 - Height\",\"lt\":\"NAM7 - Weight\",\"lf\":\"Head Parts\"},{\"t\":5,\"p\":1,\"n\":\"NAM7 - Weight\",\"lt\":\"RNAM - Race\",\"lf\":\"NAM6 - Height\"},{\"t\":3,\"p\":1,\"n\":\"NAM8 - Sound Level\"},{\"t\":10,\"p\":1,\"n\":\"Sound Types\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Sound Type\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"CSDT - Type\"},{\"t\":10,\"p\":1,\"n\":\"Sounds\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Sound\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"CSDI - Sound\"},{\"t\":3,\"p\":1,\"n\":\"CSDC - Sound Chance\"}]}]}]}]},{\"t\":3,\"p\":1,\"n\":\"CSCR - Inherits Sounds From\"},{\"t\":3,\"p\":1,\"n\":\"DOFT - Default outfit\"},{\"t\":3,\"p\":1,\"n\":\"SOFT - Sleeping outfit\"},{\"t\":3,\"p\":1,\"n\":\"DPLT - Default Package List\"},{\"t\":3,\"p\":1,\"n\":\"CRIF - Crime faction\"},{\"t\":3,\"p\":1,\"n\":\"FTST - Head texture\",\"lt\":\"HCLF - Hair Color\",\"lf\":\"QNAM - Texture lighting\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"QNAM - Texture lighting\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Red\"},{\"t\":5,\"p\":1,\"n\":\"Green\"},{\"t\":5,\"p\":1,\"n\":\"Blue\"}],\"lt\":\"FTST - Head texture\",\"lf\":\"NAM9 - Face morph\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"NAM9 - Face morph\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Nose Long\\/Short\"},{\"t\":5,\"p\":1,\"n\":\"Nose Up\\/Down\"},{\"t\":5,\"p\":1,\"n\":\"Jaw Up\\/Down\"},{\"t\":5,\"p\":1,\"n\":\"Jaw Narrow\\/Wide\"},{\"t\":5,\"p\":1,\"n\":\"Jaw Farward\\/Back\"},{\"t\":5,\"p\":1,\"n\":\"Cheeks Up\\/Down\"},{\"t\":5,\"p\":1,\"n\":\"Cheeks Farward\\/Back\"},{\"t\":5,\"p\":1,\"n\":\"Eyes Up\\/Down\"},{\"t\":5,\"p\":1,\"n\":\"Eyes In\\/Out\"},{\"t\":5,\"p\":1,\"n\":\"Brows Up\\/Down\"},{\"t\":5,\"p\":1,\"n\":\"Brows In\\/Out\"},{\"t\":5,\"p\":1,\"n\":\"Brows Farward\\/Back\"},{\"t\":5,\"p\":1,\"n\":\"Lips Up\\/Down\"},{\"t\":5,\"p\":1,\"n\":\"Lips In\\/Out\"},{\"t\":5,\"p\":1,\"n\":\"Chin Narrow\\/Wide\"},{\"t\":5,\"p\":1,\"n\":\"Chin Up\\/Down\"},{\"t\":5,\"p\":1,\"n\":\"Chin Underbite\\/Overbite\"},{\"t\":5,\"p\":1,\"n\":\"Eyes Farward\\/Back\"},{\"t\":5,\"n\":\"Unknown\"}],\"lt\":\"QNAM - Texture lighting\",\"lf\":\"NAMA - Face parts\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"NAMA - Face parts\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Nose\"},{\"t\":3,\"n\":\"Unknown\"},{\"t\":3,\"p\":1,\"n\":\"Eyes\"},{\"t\":3,\"p\":1,\"n\":\"Mouth\"}],\"lt\":\"NAM9 - Face morph\",\"lf\":\"Tint Layers\"},{\"t\":10,\"p\":1,\"n\":\"Tint Layers\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Layer\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"TINI - Tint Index\"},{\"t\":6,\"p\":1,\"n\":\"TINC - Tint Color\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":3,\"p\":1,\"n\":\"Alpha\"}]},{\"t\":3,\"p\":1,\"n\":\"TINV - Interpolation Value\"},{\"t\":3,\"p\":1,\"n\":\"TIAS - Preset\"}]}],\"lt\":\"NAMA - Face parts\",\"lf\":\"RNAM - Race\"}]},{\"t\":1,\"p\":1,\"n\":\"OTFT - Outfit\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":7,\"s\":1,\"p\":1,\"n\":\"INAM - Items\",\"d\":1,\"c\":[{\"t\":3,\"p\":1,\"n\":\"Item\"}]}]},{\"t\":1,\"p\":1,\"n\":\"PACK - Package\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"VMAD - Virtual Machine Adapter\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Version\"},{\"t\":3,\"p\":1,\"n\":\"Object Format\"},{\"t\":7,\"p\":1,\"n\":\"Scripts\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Script\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"scriptName\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":7,\"p\":1,\"n\":\"Properties\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Property\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"propertyName\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]},{\"t\":2,\"p\":1,\"n\":\"String\"},{\"t\":3,\"p\":1,\"n\":\"Int32\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":3,\"p\":1,\"n\":\"Bool\"},{\"t\":7,\"p\":1,\"n\":\"Array of Object\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]}]},{\"t\":7,\"p\":1,\"n\":\"Array of String\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Int32\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Float\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Bool\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]}]}]}]}]},{\"t\":6,\"p\":1,\"n\":\"Script Fragments\",\"c\":[{\"t\":3,\"n\":\"Unknown\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":2,\"p\":1,\"n\":\"fileName\"},{\"t\":7,\"p\":1,\"n\":\"Fragments\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Fragment\",\"c\":[{\"t\":3,\"n\":\"Unknown\"},{\"t\":2,\"p\":1,\"n\":\"scriptName\"},{\"t\":2,\"p\":1,\"n\":\"fragmentName\"}]}]}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"PKDT - Pack Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"General Flags\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Interrupt Override\"},{\"t\":3,\"p\":1,\"n\":\"Preferred Speed\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":3,\"p\":1,\"n\":\"Interrupt Flags\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"PSDT - Schedule\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Month\"},{\"t\":3,\"p\":1,\"n\":\"Day of week\"},{\"t\":3,\"p\":1,\"n\":\"Date\"},{\"t\":3,\"p\":1,\"n\":\"Hour\"},{\"t\":3,\"p\":1,\"n\":\"Minute\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Duration (minutes)\"}]},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Conditions\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Condition\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"CTDA - \",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":5,\"p\":1,\"n\":\"Comparison Value - Float\"},{\"t\":3,\"p\":1,\"n\":\"Comparison Value - Global\"},{\"t\":3,\"p\":1,\"n\":\"Function\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":11,\"p\":1,\"n\":\"None\"},{\"t\":3,\"p\":1,\"n\":\"Integer\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":11,\"p\":1,\"n\":\"Variable Name (unused)\"},{\"t\":3,\"p\":1,\"n\":\"Sex\"},{\"t\":3,\"p\":1,\"n\":\"Actor Value\"},{\"t\":3,\"p\":1,\"n\":\"Crime Type\"},{\"t\":3,\"p\":1,\"n\":\"Axis\"},{\"t\":3,\"p\":1,\"n\":\"Quest Stage (unused)\"},{\"t\":3,\"p\":1,\"n\":\"Misc Stat\"},{\"t\":3,\"p\":1,\"n\":\"Alignment\"},{\"t\":3,\"p\":1,\"n\":\"Equip Type\"},{\"t\":3,\"p\":1,\"n\":\"Form Type\"},{\"t\":3,\"p\":1,\"n\":\"Critical Stage\"},{\"t\":3,\"p\":1,\"n\":\"Object Reference\"},{\"t\":3,\"p\":1,\"n\":\"Inventory Object\"},{\"t\":3,\"p\":1,\"n\":\"Actor\"},{\"t\":3,\"p\":1,\"n\":\"Voice Type\"},{\"t\":3,\"p\":1,\"n\":\"Idle\"},{\"t\":3,\"p\":1,\"n\":\"Form List\"},{\"t\":3,\"p\":1,\"n\":\"Quest\"},{\"t\":3,\"p\":1,\"n\":\"Faction\"},{\"t\":3,\"p\":1,\"n\":\"Cell\"},{\"t\":3,\"p\":1,\"n\":\"Class\"},{\"t\":3,\"p\":1,\"n\":\"Race\"},{\"t\":3,\"p\":1,\"n\":\"Actor Base\"},{\"t\":3,\"p\":1,\"n\":\"Global\"},{\"t\":3,\"p\":1,\"n\":\"Weather\"},{\"t\":3,\"p\":1,\"n\":\"Package\"},{\"t\":3,\"p\":1,\"n\":\"Encounter Zone\"},{\"t\":3,\"p\":1,\"n\":\"Perk\"},{\"t\":3,\"p\":1,\"n\":\"Owner\"},{\"t\":3,\"p\":1,\"n\":\"Furniture\"},{\"t\":3,\"p\":1,\"n\":\"Effect Item\"},{\"t\":3,\"p\":1,\"n\":\"Base Effect\"},{\"t\":3,\"p\":1,\"n\":\"Worldspace\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Function\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Param (INVALID)\"},{\"t\":3,\"p\":1,\"n\":\"Referenceable Object\"},{\"t\":3,\"p\":1,\"n\":\"Region\"},{\"t\":3,\"p\":1,\"n\":\"Keyword\"},{\"t\":3,\"p\":1,\"n\":\"Player Action\"},{\"t\":3,\"p\":1,\"n\":\"Casting Type\"},{\"t\":3,\"p\":1,\"n\":\"Shout\"},{\"t\":3,\"p\":1,\"n\":\"Location\"},{\"t\":3,\"p\":1,\"n\":\"Location Ref Type\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"Packdata ID\"},{\"t\":3,\"p\":1,\"n\":\"Association Type\"},{\"t\":3,\"p\":1,\"n\":\"Furniture Anim\"},{\"t\":3,\"p\":1,\"n\":\"Furniture Entry\"},{\"t\":3,\"p\":1,\"n\":\"Scene\"},{\"t\":3,\"p\":1,\"n\":\"Ward State\"},{\"t\":3,\"p\":1,\"n\":\"Event\"},{\"t\":3,\"p\":1,\"n\":\"Event Data\"},{\"t\":3,\"p\":1,\"n\":\"Quest Stage\"},{\"t\":3,\"p\":1,\"n\":\"Weapon\"},{\"t\":3,\"p\":1,\"n\":\"Weapon List\"},{\"t\":3,\"p\":1,\"n\":\"Target\"},{\"t\":3,\"p\":1,\"n\":\"Target List\"},{\"t\":3,\"p\":1,\"n\":\"Target Part\"},{\"t\":3,\"p\":1,\"n\":\"VATS Action\"},{\"t\":3,\"p\":1,\"n\":\"Critical Effect\"},{\"t\":3,\"p\":1,\"n\":\"Critical Effect List\"},{\"t\":3,\"p\":1,\"n\":\"Weapon Type\"},{\"t\":3,\"p\":1,\"n\":\"Projectile Type\"},{\"t\":3,\"p\":1,\"n\":\"Delivery Type\"},{\"t\":3,\"p\":1,\"n\":\"Run On\"},{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":3,\"p\":1,\"n\":\"Parameter #3\"}]},{\"t\":2,\"p\":1,\"n\":\"CIS1 - Parameter #1\"},{\"t\":2,\"p\":1,\"n\":\"CIS2 - Parameter #2\"}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Idle Animations\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"IDLF - Flags\"},{\"t\":6,\"p\":1,\"n\":\"IDLC - \",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Animation Count\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":5,\"p\":1,\"n\":\"IDLT - Idle Timer Setting\"},{\"t\":7,\"p\":1,\"n\":\"IDLA - Animations\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Animation\"}]},{\"t\":11,\"n\":\"IDLB - Unknown\"}]},{\"t\":3,\"p\":1,\"n\":\"CNAM - Combat Style\"},{\"t\":3,\"p\":1,\"n\":\"QNAM - Owner Quest\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"PKCU - Counter\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Data Input Count\"},{\"t\":3,\"p\":1,\"n\":\"Package Template\"},{\"t\":3,\"p\":1,\"n\":\"Version Counter (autoincremented)\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Package Data\",\"c\":[{\"t\":8,\"p\":1,\"n\":\"Data Input Values\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Value\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"ANAM - Type\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":3,\"p\":1,\"n\":\"Bool\"},{\"t\":3,\"p\":1,\"n\":\"Integer\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":11,\"n\":\"BNAM - Unknown\"},{\"t\":8,\"p\":1,\"n\":\"Topic\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"PDTO - Topic Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Topic\"},{\"t\":2,\"p\":1,\"n\":\"Subtype\"}]}]},{\"t\":6,\"p\":1,\"n\":\"PLDT - Location\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":3,\"p\":1,\"n\":\"Cell\"},{\"t\":11,\"p\":1,\"n\":\"Near Package Start Location\"},{\"t\":11,\"p\":1,\"n\":\"Near Editor Location\"},{\"t\":3,\"p\":1,\"n\":\"Object ID\"},{\"t\":3,\"p\":1,\"n\":\"Object Type\"},{\"t\":3,\"p\":1,\"n\":\"Keyword\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":3,\"p\":1,\"n\":\"Radius\"}]},{\"t\":6,\"p\":1,\"n\":\"PTDA - Target\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Target Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":3,\"p\":1,\"n\":\"Object ID\"},{\"t\":3,\"p\":1,\"n\":\"Object Type\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":3,\"p\":1,\"n\":\"Count \\/ Distance\"}]}]},{\"t\":11,\"n\":\"TPIC - Unknown\"}]}]},{\"t\":8,\"p\":1,\"n\":\"Data Inputs\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Data Input\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"UNAM - Index\"},{\"t\":2,\"p\":1,\"n\":\"BNAM - Name\"},{\"t\":3,\"p\":1,\"n\":\"PNAM - Flags\"}]}]}]},{\"t\":11,\"n\":\"XNAM - Marker\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Procedure Tree\",\"c\":[{\"t\":8,\"p\":1,\"n\":\"Branches\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Branch\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"ANAM - Branch Type\"},{\"t\":3,\"p\":1,\"n\":\"CITC - Condition Count\"},{\"t\":8,\"p\":1,\"n\":\"Conditions\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Condition\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"CTDA - \",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":5,\"p\":1,\"n\":\"Comparison Value - Float\"},{\"t\":3,\"p\":1,\"n\":\"Comparison Value - Global\"},{\"t\":3,\"p\":1,\"n\":\"Function\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":11,\"p\":1,\"n\":\"None\"},{\"t\":3,\"p\":1,\"n\":\"Integer\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":11,\"p\":1,\"n\":\"Variable Name (unused)\"},{\"t\":3,\"p\":1,\"n\":\"Sex\"},{\"t\":3,\"p\":1,\"n\":\"Actor Value\"},{\"t\":3,\"p\":1,\"n\":\"Crime Type\"},{\"t\":3,\"p\":1,\"n\":\"Axis\"},{\"t\":3,\"p\":1,\"n\":\"Quest Stage (unused)\"},{\"t\":3,\"p\":1,\"n\":\"Misc Stat\"},{\"t\":3,\"p\":1,\"n\":\"Alignment\"},{\"t\":3,\"p\":1,\"n\":\"Equip Type\"},{\"t\":3,\"p\":1,\"n\":\"Form Type\"},{\"t\":3,\"p\":1,\"n\":\"Critical Stage\"},{\"t\":3,\"p\":1,\"n\":\"Object Reference\"},{\"t\":3,\"p\":1,\"n\":\"Inventory Object\"},{\"t\":3,\"p\":1,\"n\":\"Actor\"},{\"t\":3,\"p\":1,\"n\":\"Voice Type\"},{\"t\":3,\"p\":1,\"n\":\"Idle\"},{\"t\":3,\"p\":1,\"n\":\"Form List\"},{\"t\":3,\"p\":1,\"n\":\"Quest\"},{\"t\":3,\"p\":1,\"n\":\"Faction\"},{\"t\":3,\"p\":1,\"n\":\"Cell\"},{\"t\":3,\"p\":1,\"n\":\"Class\"},{\"t\":3,\"p\":1,\"n\":\"Race\"},{\"t\":3,\"p\":1,\"n\":\"Actor Base\"},{\"t\":3,\"p\":1,\"n\":\"Global\"},{\"t\":3,\"p\":1,\"n\":\"Weather\"},{\"t\":3,\"p\":1,\"n\":\"Package\"},{\"t\":3,\"p\":1,\"n\":\"Encounter Zone\"},{\"t\":3,\"p\":1,\"n\":\"Perk\"},{\"t\":3,\"p\":1,\"n\":\"Owner\"},{\"t\":3,\"p\":1,\"n\":\"Furniture\"},{\"t\":3,\"p\":1,\"n\":\"Effect Item\"},{\"t\":3,\"p\":1,\"n\":\"Base Effect\"},{\"t\":3,\"p\":1,\"n\":\"Worldspace\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Function\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Param (INVALID)\"},{\"t\":3,\"p\":1,\"n\":\"Referenceable Object\"},{\"t\":3,\"p\":1,\"n\":\"Region\"},{\"t\":3,\"p\":1,\"n\":\"Keyword\"},{\"t\":3,\"p\":1,\"n\":\"Player Action\"},{\"t\":3,\"p\":1,\"n\":\"Casting Type\"},{\"t\":3,\"p\":1,\"n\":\"Shout\"},{\"t\":3,\"p\":1,\"n\":\"Location\"},{\"t\":3,\"p\":1,\"n\":\"Location Ref Type\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"Packdata ID\"},{\"t\":3,\"p\":1,\"n\":\"Association Type\"},{\"t\":3,\"p\":1,\"n\":\"Furniture Anim\"},{\"t\":3,\"p\":1,\"n\":\"Furniture Entry\"},{\"t\":3,\"p\":1,\"n\":\"Scene\"},{\"t\":3,\"p\":1,\"n\":\"Ward State\"},{\"t\":3,\"p\":1,\"n\":\"Event\"},{\"t\":3,\"p\":1,\"n\":\"Event Data\"},{\"t\":3,\"p\":1,\"n\":\"Quest Stage\"},{\"t\":3,\"p\":1,\"n\":\"Weapon\"},{\"t\":3,\"p\":1,\"n\":\"Weapon List\"},{\"t\":3,\"p\":1,\"n\":\"Target\"},{\"t\":3,\"p\":1,\"n\":\"Target List\"},{\"t\":3,\"p\":1,\"n\":\"Target Part\"},{\"t\":3,\"p\":1,\"n\":\"VATS Action\"},{\"t\":3,\"p\":1,\"n\":\"Critical Effect\"},{\"t\":3,\"p\":1,\"n\":\"Critical Effect List\"},{\"t\":3,\"p\":1,\"n\":\"Weapon Type\"},{\"t\":3,\"p\":1,\"n\":\"Projectile Type\"},{\"t\":3,\"p\":1,\"n\":\"Delivery Type\"},{\"t\":3,\"p\":1,\"n\":\"Run On\"},{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":3,\"p\":1,\"n\":\"Parameter #3\"}]},{\"t\":2,\"p\":1,\"n\":\"CIS1 - Parameter #1\"},{\"t\":2,\"p\":1,\"n\":\"CIS2 - Parameter #2\"}]}]},{\"t\":6,\"p\":1,\"n\":\"PRCB - Root\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Branch Count\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"}]},{\"t\":2,\"p\":1,\"n\":\"PNAM - Procedure Type\"},{\"t\":3,\"p\":1,\"n\":\"FNAM - Flags\"},{\"t\":8,\"p\":1,\"n\":\"Data Input Indexes\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"PKC2 - Index\"}]},{\"t\":8,\"p\":1,\"n\":\"Flags Override\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"PFO2 - Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Set General Flags\"},{\"t\":3,\"p\":1,\"n\":\"Clear General Flags\"},{\"t\":3,\"p\":1,\"n\":\"Set Interrupt Flags\"},{\"t\":3,\"p\":1,\"n\":\"Clear Interrupt Flags\"},{\"t\":3,\"p\":1,\"n\":\"Preferred Speed Override\"},{\"t\":11,\"n\":\"Unknown\"}]}]},{\"t\":8,\"n\":\"Unknown\",\"c\":[{\"t\":11,\"n\":\"PFOR - Unknown\"}]}]}]}]},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Data Inputs\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Data Input\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"UNAM - Index\"},{\"t\":2,\"p\":1,\"n\":\"BNAM - Name\"},{\"t\":3,\"p\":1,\"n\":\"PNAM - Flags\"}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"OnBegin\",\"c\":[{\"p\":1,\"n\":\"POBA - OnBegin Marker\"},{\"t\":3,\"p\":1,\"n\":\"INAM - Idle\"},{\"t\":11,\"n\":\"SCHR - Unused\"},{\"t\":11,\"n\":\"SCTX - Unused\"},{\"t\":11,\"n\":\"QNAM - Unused\"},{\"t\":11,\"n\":\"TNAM - Unused\"},{\"t\":8,\"p\":1,\"n\":\"Topic\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"PDTO - Topic Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Topic\"},{\"t\":2,\"p\":1,\"n\":\"Subtype\"}]}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"OnEnd\",\"c\":[{\"p\":1,\"n\":\"POEA - OnEnd Marker\"},{\"t\":3,\"p\":1,\"n\":\"INAM - Idle\"},{\"t\":11,\"n\":\"SCHR - Unused\"},{\"t\":11,\"n\":\"SCTX - Unused\"},{\"t\":11,\"n\":\"QNAM - Unused\"},{\"t\":11,\"n\":\"TNAM - Unused\"},{\"t\":8,\"p\":1,\"n\":\"Topic\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"PDTO - Topic Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Topic\"},{\"t\":2,\"p\":1,\"n\":\"Subtype\"}]}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"OnChange\",\"c\":[{\"p\":1,\"n\":\"POCA - OnChange Marker\"},{\"t\":3,\"p\":1,\"n\":\"INAM - Idle\"},{\"t\":11,\"n\":\"SCHR - Unused\"},{\"t\":11,\"n\":\"SCDA - Unused\"},{\"t\":11,\"n\":\"SCTX - Unused\"},{\"t\":11,\"n\":\"QNAM - Unused\"},{\"t\":11,\"n\":\"TNAM - Unused\"},{\"t\":8,\"p\":1,\"n\":\"Topic\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"PDTO - Topic Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Topic\"},{\"t\":2,\"p\":1,\"n\":\"Subtype\"}]}]}]}]},{\"t\":1,\"p\":1,\"n\":\"PARW - Placed Arrow\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"VMAD - Virtual Machine Adapter\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Version\"},{\"t\":3,\"p\":1,\"n\":\"Object Format\"},{\"t\":7,\"p\":1,\"n\":\"Scripts\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Script\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"scriptName\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":7,\"p\":1,\"n\":\"Properties\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Property\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"propertyName\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]},{\"t\":2,\"p\":1,\"n\":\"String\"},{\"t\":3,\"p\":1,\"n\":\"Int32\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":3,\"p\":1,\"n\":\"Bool\"},{\"t\":7,\"p\":1,\"n\":\"Array of Object\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]}]},{\"t\":7,\"p\":1,\"n\":\"Array of String\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Int32\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Float\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Bool\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]}]}]}]}]}]},{\"t\":3,\"p\":1,\"n\":\"NAME - Projectile\"},{\"t\":3,\"p\":1,\"n\":\"XEZN - Encounter Zone\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Ownership\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"XOWN - Owner\"},{\"t\":3,\"p\":1,\"n\":\"XRNK - Faction rank\"}]},{\"t\":5,\"p\":1,\"n\":\"XHTW - Head-Tracking Weight\"},{\"t\":5,\"p\":1,\"n\":\"XFVC - Favor Cost\"},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Reflected\\/Refracted By\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"XPWR - Water\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":3,\"p\":1,\"n\":\"Type\"}]}]},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Linked References\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"XLKR - Linked Reference\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Keyword\\/Ref\"},{\"t\":3,\"p\":1,\"n\":\"Ref\"}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Activate Parents\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"XAPD - Flags\"},{\"t\":8,\"p\":1,\"n\":\"Activate Parent Refs\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"XAPR - Activate Parent Ref\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":5,\"p\":1,\"n\":\"Delay\"}]}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"XESP - Enable Parent\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":3,\"p\":1,\"n\":\"XEMI - Emittance\"},{\"t\":3,\"p\":1,\"n\":\"XMBR - MultiBound Reference\"},{\"p\":1,\"n\":\"XIS2 - Ignored by Sandbox\"},{\"t\":7,\"p\":1,\"n\":\"XLRT - Location Ref Type\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Ref\"}]},{\"t\":3,\"p\":1,\"n\":\"XLRL - Location Reference\"},{\"t\":7,\"n\":\"XLOD - Distant LOD Data\",\"c\":[{\"t\":5,\"n\":\"Unknown\"}]},{\"t\":5,\"p\":1,\"n\":\"XSCL - Scale\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DATA - Position\\/Rotation\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Position\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"X\"},{\"t\":5,\"p\":1,\"n\":\"Y\"},{\"t\":5,\"p\":1,\"n\":\"Z\"}]},{\"t\":6,\"p\":1,\"n\":\"Rotation\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"X\"},{\"t\":5,\"p\":1,\"n\":\"Y\"},{\"t\":5,\"p\":1,\"n\":\"Z\"}]}]}]},{\"t\":1,\"p\":1,\"n\":\"PBAR - Placed Barrier\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"VMAD - Virtual Machine Adapter\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Version\"},{\"t\":3,\"p\":1,\"n\":\"Object Format\"},{\"t\":7,\"p\":1,\"n\":\"Scripts\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Script\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"scriptName\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":7,\"p\":1,\"n\":\"Properties\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Property\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"propertyName\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]},{\"t\":2,\"p\":1,\"n\":\"String\"},{\"t\":3,\"p\":1,\"n\":\"Int32\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":3,\"p\":1,\"n\":\"Bool\"},{\"t\":7,\"p\":1,\"n\":\"Array of Object\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]}]},{\"t\":7,\"p\":1,\"n\":\"Array of String\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Int32\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Float\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Bool\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]}]}]}]}]}]},{\"t\":3,\"p\":1,\"n\":\"NAME - Projectile\"},{\"t\":3,\"p\":1,\"n\":\"XEZN - Encounter Zone\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Ownership\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"XOWN - Owner\"},{\"t\":3,\"p\":1,\"n\":\"XRNK - Faction rank\"}]},{\"t\":5,\"p\":1,\"n\":\"XHTW - Head-Tracking Weight\"},{\"t\":5,\"p\":1,\"n\":\"XFVC - Favor Cost\"},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Reflected\\/Refracted By\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"XPWR - Water\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":3,\"p\":1,\"n\":\"Type\"}]}]},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Linked References\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"XLKR - Linked Reference\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Keyword\\/Ref\"},{\"t\":3,\"p\":1,\"n\":\"Ref\"}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Activate Parents\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"XAPD - Flags\"},{\"t\":8,\"p\":1,\"n\":\"Activate Parent Refs\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"XAPR - Activate Parent Ref\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":5,\"p\":1,\"n\":\"Delay\"}]}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"XESP - Enable Parent\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":3,\"p\":1,\"n\":\"XEMI - Emittance\"},{\"t\":3,\"p\":1,\"n\":\"XMBR - MultiBound Reference\"},{\"p\":1,\"n\":\"XIS2 - Ignored by Sandbox\"},{\"t\":7,\"p\":1,\"n\":\"XLRT - Location Ref Type\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Ref\"}]},{\"t\":3,\"p\":1,\"n\":\"XLRL - Location Reference\"},{\"t\":7,\"n\":\"XLOD - Distant LOD Data\",\"c\":[{\"t\":5,\"n\":\"Unknown\"}]},{\"t\":5,\"p\":1,\"n\":\"XSCL - Scale\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DATA - Position\\/Rotation\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Position\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"X\"},{\"t\":5,\"p\":1,\"n\":\"Y\"},{\"t\":5,\"p\":1,\"n\":\"Z\"}]},{\"t\":6,\"p\":1,\"n\":\"Rotation\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"X\"},{\"t\":5,\"p\":1,\"n\":\"Y\"},{\"t\":5,\"p\":1,\"n\":\"Z\"}]}]}]},{\"t\":1,\"p\":1,\"n\":\"PBEA - Placed Beam\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"VMAD - Virtual Machine Adapter\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Version\"},{\"t\":3,\"p\":1,\"n\":\"Object Format\"},{\"t\":7,\"p\":1,\"n\":\"Scripts\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Script\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"scriptName\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":7,\"p\":1,\"n\":\"Properties\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Property\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"propertyName\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]},{\"t\":2,\"p\":1,\"n\":\"String\"},{\"t\":3,\"p\":1,\"n\":\"Int32\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":3,\"p\":1,\"n\":\"Bool\"},{\"t\":7,\"p\":1,\"n\":\"Array of Object\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]}]},{\"t\":7,\"p\":1,\"n\":\"Array of String\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Int32\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Float\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Bool\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]}]}]}]}]}]},{\"t\":3,\"p\":1,\"n\":\"NAME - Projectile\"},{\"t\":3,\"p\":1,\"n\":\"XEZN - Encounter Zone\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Ownership\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"XOWN - Owner\"},{\"t\":3,\"p\":1,\"n\":\"XRNK - Faction rank\"}]},{\"t\":5,\"p\":1,\"n\":\"XHTW - Head-Tracking Weight\"},{\"t\":5,\"p\":1,\"n\":\"XFVC - Favor Cost\"},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Reflected\\/Refracted By\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"XPWR - Water\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":3,\"p\":1,\"n\":\"Type\"}]}]},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Linked References\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"XLKR - Linked Reference\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Keyword\\/Ref\"},{\"t\":3,\"p\":1,\"n\":\"Ref\"}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Activate Parents\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"XAPD - Flags\"},{\"t\":8,\"p\":1,\"n\":\"Activate Parent Refs\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"XAPR - Activate Parent Ref\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":5,\"p\":1,\"n\":\"Delay\"}]}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"XESP - Enable Parent\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":3,\"p\":1,\"n\":\"XEMI - Emittance\"},{\"t\":3,\"p\":1,\"n\":\"XMBR - MultiBound Reference\"},{\"p\":1,\"n\":\"XIS2 - Ignored by Sandbox\"},{\"t\":7,\"p\":1,\"n\":\"XLRT - Location Ref Type\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Ref\"}]},{\"t\":3,\"p\":1,\"n\":\"XLRL - Location Reference\"},{\"t\":7,\"n\":\"XLOD - Distant LOD Data\",\"c\":[{\"t\":5,\"n\":\"Unknown\"}]},{\"t\":5,\"p\":1,\"n\":\"XSCL - Scale\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DATA - Position\\/Rotation\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Position\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"X\"},{\"t\":5,\"p\":1,\"n\":\"Y\"},{\"t\":5,\"p\":1,\"n\":\"Z\"}]},{\"t\":6,\"p\":1,\"n\":\"Rotation\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"X\"},{\"t\":5,\"p\":1,\"n\":\"Y\"},{\"t\":5,\"p\":1,\"n\":\"Z\"}]}]}]},{\"t\":1,\"p\":1,\"n\":\"PCON - Placed Cone\\/Voice\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"VMAD - Virtual Machine Adapter\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Version\"},{\"t\":3,\"p\":1,\"n\":\"Object Format\"},{\"t\":7,\"p\":1,\"n\":\"Scripts\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Script\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"scriptName\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":7,\"p\":1,\"n\":\"Properties\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Property\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"propertyName\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]},{\"t\":2,\"p\":1,\"n\":\"String\"},{\"t\":3,\"p\":1,\"n\":\"Int32\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":3,\"p\":1,\"n\":\"Bool\"},{\"t\":7,\"p\":1,\"n\":\"Array of Object\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]}]},{\"t\":7,\"p\":1,\"n\":\"Array of String\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Int32\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Float\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Bool\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]}]}]}]}]}]},{\"t\":3,\"p\":1,\"n\":\"NAME - Projectile\"},{\"t\":3,\"p\":1,\"n\":\"XEZN - Encounter Zone\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Ownership\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"XOWN - Owner\"},{\"t\":3,\"p\":1,\"n\":\"XRNK - Faction rank\"}]},{\"t\":5,\"p\":1,\"n\":\"XHTW - Head-Tracking Weight\"},{\"t\":5,\"p\":1,\"n\":\"XFVC - Favor Cost\"},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Reflected\\/Refracted By\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"XPWR - Water\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":3,\"p\":1,\"n\":\"Type\"}]}]},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Linked References\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"XLKR - Linked Reference\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Keyword\\/Ref\"},{\"t\":3,\"p\":1,\"n\":\"Ref\"}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Activate Parents\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"XAPD - Flags\"},{\"t\":8,\"p\":1,\"n\":\"Activate Parent Refs\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"XAPR - Activate Parent Ref\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":5,\"p\":1,\"n\":\"Delay\"}]}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"XESP - Enable Parent\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":3,\"p\":1,\"n\":\"XEMI - Emittance\"},{\"t\":3,\"p\":1,\"n\":\"XMBR - MultiBound Reference\"},{\"p\":1,\"n\":\"XIS2 - Ignored by Sandbox\"},{\"t\":7,\"p\":1,\"n\":\"XLRT - Location Ref Type\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Ref\"}]},{\"t\":3,\"p\":1,\"n\":\"XLRL - Location Reference\"},{\"t\":7,\"n\":\"XLOD - Distant LOD Data\",\"c\":[{\"t\":5,\"n\":\"Unknown\"}]},{\"t\":5,\"p\":1,\"n\":\"XSCL - Scale\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DATA - Position\\/Rotation\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Position\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"X\"},{\"t\":5,\"p\":1,\"n\":\"Y\"},{\"t\":5,\"p\":1,\"n\":\"Z\"}]},{\"t\":6,\"p\":1,\"n\":\"Rotation\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"X\"},{\"t\":5,\"p\":1,\"n\":\"Y\"},{\"t\":5,\"p\":1,\"n\":\"Z\"}]}]}]},{\"t\":1,\"p\":1,\"n\":\"PERK - Perk\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"VMAD - Virtual Machine Adapter\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Version\"},{\"t\":3,\"p\":1,\"n\":\"Object Format\"},{\"t\":7,\"p\":1,\"n\":\"Scripts\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Script\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"scriptName\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":7,\"p\":1,\"n\":\"Properties\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Property\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"propertyName\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]},{\"t\":2,\"p\":1,\"n\":\"String\"},{\"t\":3,\"p\":1,\"n\":\"Int32\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":3,\"p\":1,\"n\":\"Bool\"},{\"t\":7,\"p\":1,\"n\":\"Array of Object\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]}]},{\"t\":7,\"p\":1,\"n\":\"Array of String\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Int32\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Float\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Bool\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]}]}]}]}]},{\"t\":6,\"p\":1,\"n\":\"Script Fragments\",\"c\":[{\"t\":3,\"n\":\"Unknown\"},{\"t\":2,\"p\":1,\"n\":\"fileName\"},{\"t\":7,\"p\":1,\"n\":\"Fragments\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Fragment\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Fragment Index\"},{\"t\":3,\"n\":\"Unknown\"},{\"t\":2,\"p\":1,\"n\":\"scriptName\"},{\"t\":2,\"p\":1,\"n\":\"fragmentName\"}]}]}]}]},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":2,\"p\":1,\"n\":\"DESC - Description\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Icon\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"ICON - Large Icon filename\"},{\"t\":2,\"p\":1,\"n\":\"MICO - Small Icon filename\"}]},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Conditions\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Condition\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"CTDA - \",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":5,\"p\":1,\"n\":\"Comparison Value - Float\"},{\"t\":3,\"p\":1,\"n\":\"Comparison Value - Global\"},{\"t\":3,\"p\":1,\"n\":\"Function\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":11,\"p\":1,\"n\":\"None\"},{\"t\":3,\"p\":1,\"n\":\"Integer\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":11,\"p\":1,\"n\":\"Variable Name (unused)\"},{\"t\":3,\"p\":1,\"n\":\"Sex\"},{\"t\":3,\"p\":1,\"n\":\"Actor Value\"},{\"t\":3,\"p\":1,\"n\":\"Crime Type\"},{\"t\":3,\"p\":1,\"n\":\"Axis\"},{\"t\":3,\"p\":1,\"n\":\"Quest Stage (unused)\"},{\"t\":3,\"p\":1,\"n\":\"Misc Stat\"},{\"t\":3,\"p\":1,\"n\":\"Alignment\"},{\"t\":3,\"p\":1,\"n\":\"Equip Type\"},{\"t\":3,\"p\":1,\"n\":\"Form Type\"},{\"t\":3,\"p\":1,\"n\":\"Critical Stage\"},{\"t\":3,\"p\":1,\"n\":\"Object Reference\"},{\"t\":3,\"p\":1,\"n\":\"Inventory Object\"},{\"t\":3,\"p\":1,\"n\":\"Actor\"},{\"t\":3,\"p\":1,\"n\":\"Voice Type\"},{\"t\":3,\"p\":1,\"n\":\"Idle\"},{\"t\":3,\"p\":1,\"n\":\"Form List\"},{\"t\":3,\"p\":1,\"n\":\"Quest\"},{\"t\":3,\"p\":1,\"n\":\"Faction\"},{\"t\":3,\"p\":1,\"n\":\"Cell\"},{\"t\":3,\"p\":1,\"n\":\"Class\"},{\"t\":3,\"p\":1,\"n\":\"Race\"},{\"t\":3,\"p\":1,\"n\":\"Actor Base\"},{\"t\":3,\"p\":1,\"n\":\"Global\"},{\"t\":3,\"p\":1,\"n\":\"Weather\"},{\"t\":3,\"p\":1,\"n\":\"Package\"},{\"t\":3,\"p\":1,\"n\":\"Encounter Zone\"},{\"t\":3,\"p\":1,\"n\":\"Perk\"},{\"t\":3,\"p\":1,\"n\":\"Owner\"},{\"t\":3,\"p\":1,\"n\":\"Furniture\"},{\"t\":3,\"p\":1,\"n\":\"Effect Item\"},{\"t\":3,\"p\":1,\"n\":\"Base Effect\"},{\"t\":3,\"p\":1,\"n\":\"Worldspace\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Function\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Param (INVALID)\"},{\"t\":3,\"p\":1,\"n\":\"Referenceable Object\"},{\"t\":3,\"p\":1,\"n\":\"Region\"},{\"t\":3,\"p\":1,\"n\":\"Keyword\"},{\"t\":3,\"p\":1,\"n\":\"Player Action\"},{\"t\":3,\"p\":1,\"n\":\"Casting Type\"},{\"t\":3,\"p\":1,\"n\":\"Shout\"},{\"t\":3,\"p\":1,\"n\":\"Location\"},{\"t\":3,\"p\":1,\"n\":\"Location Ref Type\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"Packdata ID\"},{\"t\":3,\"p\":1,\"n\":\"Association Type\"},{\"t\":3,\"p\":1,\"n\":\"Furniture Anim\"},{\"t\":3,\"p\":1,\"n\":\"Furniture Entry\"},{\"t\":3,\"p\":1,\"n\":\"Scene\"},{\"t\":3,\"p\":1,\"n\":\"Ward State\"},{\"t\":3,\"p\":1,\"n\":\"Event\"},{\"t\":3,\"p\":1,\"n\":\"Event Data\"},{\"t\":3,\"p\":1,\"n\":\"Quest Stage\"},{\"t\":3,\"p\":1,\"n\":\"Weapon\"},{\"t\":3,\"p\":1,\"n\":\"Weapon List\"},{\"t\":3,\"p\":1,\"n\":\"Target\"},{\"t\":3,\"p\":1,\"n\":\"Target List\"},{\"t\":3,\"p\":1,\"n\":\"Target Part\"},{\"t\":3,\"p\":1,\"n\":\"VATS Action\"},{\"t\":3,\"p\":1,\"n\":\"Critical Effect\"},{\"t\":3,\"p\":1,\"n\":\"Critical Effect List\"},{\"t\":3,\"p\":1,\"n\":\"Weapon Type\"},{\"t\":3,\"p\":1,\"n\":\"Projectile Type\"},{\"t\":3,\"p\":1,\"n\":\"Delivery Type\"},{\"t\":3,\"p\":1,\"n\":\"Run On\"},{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":3,\"p\":1,\"n\":\"Parameter #3\"}]},{\"t\":2,\"p\":1,\"n\":\"CIS1 - Parameter #1\"},{\"t\":2,\"p\":1,\"n\":\"CIS2 - Parameter #2\"}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DATA - Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Trait\"},{\"t\":3,\"p\":1,\"n\":\"Level\"},{\"t\":3,\"p\":1,\"n\":\"Num Ranks\"},{\"t\":3,\"p\":1,\"n\":\"Playable\"},{\"t\":3,\"p\":1,\"n\":\"Hidden\"}]},{\"t\":3,\"p\":1,\"n\":\"NNAM - Next Perk\"},{\"t\":10,\"p\":1,\"n\":\"Effects\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Effect\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"PRKE - Header\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Rank\"},{\"t\":3,\"p\":1,\"n\":\"Priority\"}]},{\"t\":6,\"p\":1,\"n\":\"Quest + Stage\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Quest\"},{\"t\":3,\"p\":1,\"n\":\"Quest Stage\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":3,\"p\":1,\"n\":\"Ability\"},{\"t\":6,\"p\":1,\"n\":\"Entry Point\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Entry Point\"},{\"t\":3,\"p\":1,\"n\":\"Function\"},{\"t\":3,\"p\":1,\"n\":\"Perk Condition Tab Count\"}]},{\"t\":10,\"p\":1,\"n\":\"Perk Conditions\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Perk Condition\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"PRKC - Run On (Tab Index)\"},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Conditions\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Condition\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"CTDA - \",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":11,\"p\":1,\"n\":\"Unused\"},{\"t\":5,\"p\":1,\"n\":\"Comparison Value - Float\"},{\"t\":3,\"p\":1,\"n\":\"Comparison Value - Global\"},{\"t\":3,\"p\":1,\"n\":\"Function\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":11,\"p\":1,\"n\":\"None\"},{\"t\":3,\"p\":1,\"n\":\"Integer\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":11,\"p\":1,\"n\":\"Variable Name (unused)\"},{\"t\":3,\"p\":1,\"n\":\"Sex\"},{\"t\":3,\"p\":1,\"n\":\"Actor Value\"},{\"t\":3,\"p\":1,\"n\":\"Crime Type\"},{\"t\":3,\"p\":1,\"n\":\"Axis\"},{\"t\":3,\"p\":1,\"n\":\"Quest Stage (unused)\"},{\"t\":3,\"p\":1,\"n\":\"Misc Stat\"},{\"t\":3,\"p\":1,\"n\":\"Alignment\"},{\"t\":3,\"p\":1,\"n\":\"Equip Type\"},{\"t\":3,\"p\":1,\"n\":\"Form Type\"},{\"t\":3,\"p\":1,\"n\":\"Critical Stage\"},{\"t\":3,\"p\":1,\"n\":\"Object Reference\"},{\"t\":3,\"p\":1,\"n\":\"Inventory Object\"},{\"t\":3,\"p\":1,\"n\":\"Actor\"},{\"t\":3,\"p\":1,\"n\":\"Voice Type\"},{\"t\":3,\"p\":1,\"n\":\"Idle\"},{\"t\":3,\"p\":1,\"n\":\"Form List\"},{\"t\":3,\"p\":1,\"n\":\"Quest\"},{\"t\":3,\"p\":1,\"n\":\"Faction\"},{\"t\":3,\"p\":1,\"n\":\"Cell\"},{\"t\":3,\"p\":1,\"n\":\"Class\"},{\"t\":3,\"p\":1,\"n\":\"Race\"},{\"t\":3,\"p\":1,\"n\":\"Actor Base\"},{\"t\":3,\"p\":1,\"n\":\"Global\"},{\"t\":3,\"p\":1,\"n\":\"Weather\"},{\"t\":3,\"p\":1,\"n\":\"Package\"},{\"t\":3,\"p\":1,\"n\":\"Encounter Zone\"},{\"t\":3,\"p\":1,\"n\":\"Perk\"},{\"t\":3,\"p\":1,\"n\":\"Owner\"},{\"t\":3,\"p\":1,\"n\":\"Furniture\"},{\"t\":3,\"p\":1,\"n\":\"Effect Item\"},{\"t\":3,\"p\":1,\"n\":\"Base Effect\"},{\"t\":3,\"p\":1,\"n\":\"Worldspace\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Function\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Param (INVALID)\"},{\"t\":3,\"p\":1,\"n\":\"Referenceable Object\"},{\"t\":3,\"p\":1,\"n\":\"Region\"},{\"t\":3,\"p\":1,\"n\":\"Keyword\"},{\"t\":3,\"p\":1,\"n\":\"Player Action\"},{\"t\":3,\"p\":1,\"n\":\"Casting Type\"},{\"t\":3,\"p\":1,\"n\":\"Shout\"},{\"t\":3,\"p\":1,\"n\":\"Location\"},{\"t\":3,\"p\":1,\"n\":\"Location Ref Type\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"Packdata ID\"},{\"t\":3,\"p\":1,\"n\":\"Association Type\"},{\"t\":3,\"p\":1,\"n\":\"Furniture Anim\"},{\"t\":3,\"p\":1,\"n\":\"Furniture Entry\"},{\"t\":3,\"p\":1,\"n\":\"Scene\"},{\"t\":3,\"p\":1,\"n\":\"Ward State\"},{\"t\":3,\"p\":1,\"n\":\"Event\"},{\"t\":3,\"p\":1,\"n\":\"Event Data\"},{\"t\":3,\"p\":1,\"n\":\"Quest Stage\"},{\"t\":3,\"p\":1,\"n\":\"Weapon\"},{\"t\":3,\"p\":1,\"n\":\"Weapon List\"},{\"t\":3,\"p\":1,\"n\":\"Target\"},{\"t\":3,\"p\":1,\"n\":\"Target List\"},{\"t\":3,\"p\":1,\"n\":\"Target Part\"},{\"t\":3,\"p\":1,\"n\":\"VATS Action\"},{\"t\":3,\"p\":1,\"n\":\"Critical Effect\"},{\"t\":3,\"p\":1,\"n\":\"Critical Effect List\"},{\"t\":3,\"p\":1,\"n\":\"Weapon Type\"},{\"t\":3,\"p\":1,\"n\":\"Projectile Type\"},{\"t\":3,\"p\":1,\"n\":\"Delivery Type\"},{\"t\":3,\"p\":1,\"n\":\"Run On\"},{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":3,\"p\":1,\"n\":\"Parameter #3\"}]},{\"t\":2,\"p\":1,\"n\":\"CIS1 - Parameter #1\"},{\"t\":2,\"p\":1,\"n\":\"CIS2 - Parameter #2\"}]}]}]}]},{\"t\":6,\"p\":1,\"n\":\"Function Parameters\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"EPFT - Type\"},{\"t\":2,\"p\":1,\"n\":\"EPF2 - Button Label\"},{\"t\":6,\"p\":1,\"n\":\"EPF3 - Script Flags\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Script Flags\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":11,\"n\":\"Unknown\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":6,\"p\":1,\"n\":\"Float, Float\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Float 1\"},{\"t\":5,\"p\":1,\"n\":\"Float 2\"}]},{\"t\":3,\"p\":1,\"n\":\"Leveled Item\"},{\"t\":3,\"p\":1,\"n\":\"Spell\"},{\"t\":2,\"p\":1,\"n\":\"Text\"},{\"t\":6,\"p\":1,\"n\":\"Actor Value, Float\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Actor Value\"},{\"t\":5,\"p\":1,\"n\":\"Float\"}]}]},{\"p\":1,\"n\":\"PRKF - End Marker\"}]}]}]},{\"t\":1,\"p\":1,\"n\":\"PFLA - Placed Flame\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"VMAD - Virtual Machine Adapter\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Version\"},{\"t\":3,\"p\":1,\"n\":\"Object Format\"},{\"t\":7,\"p\":1,\"n\":\"Scripts\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Script\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"scriptName\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":7,\"p\":1,\"n\":\"Properties\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Property\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"propertyName\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]},{\"t\":2,\"p\":1,\"n\":\"String\"},{\"t\":3,\"p\":1,\"n\":\"Int32\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":3,\"p\":1,\"n\":\"Bool\"},{\"t\":7,\"p\":1,\"n\":\"Array of Object\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]}]},{\"t\":7,\"p\":1,\"n\":\"Array of String\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Int32\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Float\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Bool\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]}]}]}]}]}]},{\"t\":3,\"p\":1,\"n\":\"NAME - Projectile\"},{\"t\":3,\"p\":1,\"n\":\"XEZN - Encounter Zone\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Ownership\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"XOWN - Owner\"},{\"t\":3,\"p\":1,\"n\":\"XRNK - Faction rank\"}]},{\"t\":5,\"p\":1,\"n\":\"XHTW - Head-Tracking Weight\"},{\"t\":5,\"p\":1,\"n\":\"XFVC - Favor Cost\"},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Reflected\\/Refracted By\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"XPWR - Water\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":3,\"p\":1,\"n\":\"Type\"}]}]},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Linked References\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"XLKR - Linked Reference\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Keyword\\/Ref\"},{\"t\":3,\"p\":1,\"n\":\"Ref\"}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Activate Parents\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"XAPD - Flags\"},{\"t\":8,\"p\":1,\"n\":\"Activate Parent Refs\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"XAPR - Activate Parent Ref\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":5,\"p\":1,\"n\":\"Delay\"}]}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"XESP - Enable Parent\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":3,\"p\":1,\"n\":\"XEMI - Emittance\"},{\"t\":3,\"p\":1,\"n\":\"XMBR - MultiBound Reference\"},{\"p\":1,\"n\":\"XIS2 - Ignored by Sandbox\"},{\"t\":7,\"p\":1,\"n\":\"XLRT - Location Ref Type\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Ref\"}]},{\"t\":3,\"p\":1,\"n\":\"XLRL - Location Reference\"},{\"t\":7,\"n\":\"XLOD - Distant LOD Data\",\"c\":[{\"t\":5,\"n\":\"Unknown\"}]},{\"t\":5,\"p\":1,\"n\":\"XSCL - Scale\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DATA - Position\\/Rotation\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Position\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"X\"},{\"t\":5,\"p\":1,\"n\":\"Y\"},{\"t\":5,\"p\":1,\"n\":\"Z\"}]},{\"t\":6,\"p\":1,\"n\":\"Rotation\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"X\"},{\"t\":5,\"p\":1,\"n\":\"Y\"},{\"t\":5,\"p\":1,\"n\":\"Z\"}]}]}]},{\"t\":1,\"p\":1,\"n\":\"PGRE - Placed Projectile\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"VMAD - Virtual Machine Adapter\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Version\"},{\"t\":3,\"p\":1,\"n\":\"Object Format\"},{\"t\":7,\"p\":1,\"n\":\"Scripts\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Script\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"scriptName\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":7,\"p\":1,\"n\":\"Properties\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Property\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"propertyName\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]},{\"t\":2,\"p\":1,\"n\":\"String\"},{\"t\":3,\"p\":1,\"n\":\"Int32\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":3,\"p\":1,\"n\":\"Bool\"},{\"t\":7,\"p\":1,\"n\":\"Array of Object\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]}]},{\"t\":7,\"p\":1,\"n\":\"Array of String\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Int32\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Float\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Bool\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]}]}]}]}]}]},{\"t\":3,\"p\":1,\"n\":\"NAME - Projectile\"},{\"t\":3,\"p\":1,\"n\":\"XEZN - Encounter Zone\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Ownership\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"XOWN - Owner\"},{\"t\":3,\"p\":1,\"n\":\"XRNK - Faction rank\"}]},{\"t\":5,\"p\":1,\"n\":\"XHTW - Head-Tracking Weight\"},{\"t\":5,\"p\":1,\"n\":\"XFVC - Favor Cost\"},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Reflected\\/Refracted By\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"XPWR - Water\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":3,\"p\":1,\"n\":\"Type\"}]}]},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Linked References\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"XLKR - Linked Reference\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Keyword\\/Ref\"},{\"t\":3,\"p\":1,\"n\":\"Ref\"}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Activate Parents\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"XAPD - Flags\"},{\"t\":8,\"p\":1,\"n\":\"Activate Parent Refs\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"XAPR - Activate Parent Ref\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":5,\"p\":1,\"n\":\"Delay\"}]}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"XESP - Enable Parent\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":3,\"p\":1,\"n\":\"XEMI - Emittance\"},{\"t\":3,\"p\":1,\"n\":\"XMBR - MultiBound Reference\"},{\"p\":1,\"n\":\"XIS2 - Ignored by Sandbox\"},{\"t\":7,\"p\":1,\"n\":\"XLRT - Location Ref Type\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Ref\"}]},{\"t\":3,\"p\":1,\"n\":\"XLRL - Location Reference\"},{\"t\":7,\"n\":\"XLOD - Distant LOD Data\",\"c\":[{\"t\":5,\"n\":\"Unknown\"}]},{\"t\":5,\"p\":1,\"n\":\"XSCL - Scale\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DATA - Position\\/Rotation\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Position\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"X\"},{\"t\":5,\"p\":1,\"n\":\"Y\"},{\"t\":5,\"p\":1,\"n\":\"Z\"}]},{\"t\":6,\"p\":1,\"n\":\"Rotation\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"X\"},{\"t\":5,\"p\":1,\"n\":\"Y\"},{\"t\":5,\"p\":1,\"n\":\"Z\"}]}]}]},{\"t\":1,\"p\":1,\"n\":\"PHZD - Placed Hazard\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"VMAD - Virtual Machine Adapter\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Version\"},{\"t\":3,\"p\":1,\"n\":\"Object Format\"},{\"t\":7,\"p\":1,\"n\":\"Scripts\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Script\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"scriptName\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":7,\"p\":1,\"n\":\"Properties\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Property\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"propertyName\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]},{\"t\":2,\"p\":1,\"n\":\"String\"},{\"t\":3,\"p\":1,\"n\":\"Int32\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":3,\"p\":1,\"n\":\"Bool\"},{\"t\":7,\"p\":1,\"n\":\"Array of Object\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]}]},{\"t\":7,\"p\":1,\"n\":\"Array of String\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Int32\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Float\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Bool\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]}]}]}]}]}]},{\"t\":3,\"p\":1,\"n\":\"NAME - Projectile\"},{\"t\":3,\"p\":1,\"n\":\"XEZN - Encounter Zone\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Ownership\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"XOWN - Owner\"},{\"t\":3,\"p\":1,\"n\":\"XRNK - Faction rank\"}]},{\"t\":5,\"p\":1,\"n\":\"XHTW - Head-Tracking Weight\"},{\"t\":5,\"p\":1,\"n\":\"XFVC - Favor Cost\"},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Reflected\\/Refracted By\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"XPWR - Water\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":3,\"p\":1,\"n\":\"Type\"}]}]},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Linked References\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"XLKR - Linked Reference\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Keyword\\/Ref\"},{\"t\":3,\"p\":1,\"n\":\"Ref\"}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Activate Parents\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"XAPD - Flags\"},{\"t\":8,\"p\":1,\"n\":\"Activate Parent Refs\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"XAPR - Activate Parent Ref\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":5,\"p\":1,\"n\":\"Delay\"}]}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"XESP - Enable Parent\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":3,\"p\":1,\"n\":\"XEMI - Emittance\"},{\"t\":3,\"p\":1,\"n\":\"XMBR - MultiBound Reference\"},{\"p\":1,\"n\":\"XIS2 - Ignored by Sandbox\"},{\"t\":7,\"p\":1,\"n\":\"XLRT - Location Ref Type\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Ref\"}]},{\"t\":3,\"p\":1,\"n\":\"XLRL - Location Reference\"},{\"t\":7,\"n\":\"XLOD - Distant LOD Data\",\"c\":[{\"t\":5,\"n\":\"Unknown\"}]},{\"t\":5,\"p\":1,\"n\":\"XSCL - Scale\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DATA - Position\\/Rotation\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Position\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"X\"},{\"t\":5,\"p\":1,\"n\":\"Y\"},{\"t\":5,\"p\":1,\"n\":\"Z\"}]},{\"t\":6,\"p\":1,\"n\":\"Rotation\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"X\"},{\"t\":5,\"p\":1,\"n\":\"Y\"},{\"t\":5,\"p\":1,\"n\":\"Z\"}]}]}]},{\"t\":1,\"p\":1,\"n\":\"PMIS - Placed Missile\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"VMAD - Virtual Machine Adapter\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Version\"},{\"t\":3,\"p\":1,\"n\":\"Object Format\"},{\"t\":7,\"p\":1,\"n\":\"Scripts\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Script\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"scriptName\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":7,\"p\":1,\"n\":\"Properties\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Property\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"propertyName\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]},{\"t\":2,\"p\":1,\"n\":\"String\"},{\"t\":3,\"p\":1,\"n\":\"Int32\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":3,\"p\":1,\"n\":\"Bool\"},{\"t\":7,\"p\":1,\"n\":\"Array of Object\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]}]},{\"t\":7,\"p\":1,\"n\":\"Array of String\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Int32\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Float\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Bool\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]}]}]}]}]}]},{\"t\":3,\"p\":1,\"n\":\"NAME - Projectile\"},{\"t\":3,\"p\":1,\"n\":\"XEZN - Encounter Zone\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Ownership\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"XOWN - Owner\"},{\"t\":3,\"p\":1,\"n\":\"XRNK - Faction rank\"}]},{\"t\":5,\"p\":1,\"n\":\"XHTW - Head-Tracking Weight\"},{\"t\":5,\"p\":1,\"n\":\"XFVC - Favor Cost\"},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Reflected\\/Refracted By\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"XPWR - Water\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":3,\"p\":1,\"n\":\"Type\"}]}]},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Linked References\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"XLKR - Linked Reference\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Keyword\\/Ref\"},{\"t\":3,\"p\":1,\"n\":\"Ref\"}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Activate Parents\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"XAPD - Flags\"},{\"t\":8,\"p\":1,\"n\":\"Activate Parent Refs\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"XAPR - Activate Parent Ref\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":5,\"p\":1,\"n\":\"Delay\"}]}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"XESP - Enable Parent\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":3,\"p\":1,\"n\":\"XEMI - Emittance\"},{\"t\":3,\"p\":1,\"n\":\"XMBR - MultiBound Reference\"},{\"p\":1,\"n\":\"XIS2 - Ignored by Sandbox\"},{\"t\":7,\"p\":1,\"n\":\"XLRT - Location Ref Type\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Ref\"}]},{\"t\":3,\"p\":1,\"n\":\"XLRL - Location Reference\"},{\"t\":7,\"n\":\"XLOD - Distant LOD Data\",\"c\":[{\"t\":5,\"n\":\"Unknown\"}]},{\"t\":5,\"p\":1,\"n\":\"XSCL - Scale\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DATA - Position\\/Rotation\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Position\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"X\"},{\"t\":5,\"p\":1,\"n\":\"Y\"},{\"t\":5,\"p\":1,\"n\":\"Z\"}]},{\"t\":6,\"p\":1,\"n\":\"Rotation\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"X\"},{\"t\":5,\"p\":1,\"n\":\"Y\"},{\"t\":5,\"p\":1,\"n\":\"Z\"}]}]}]},{\"t\":1,\"p\":1,\"n\":\"PROJ - Projectile\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"X1\"},{\"t\":3,\"p\":1,\"n\":\"Y1\"},{\"t\":3,\"p\":1,\"n\":\"Z1\"},{\"t\":3,\"p\":1,\"n\":\"X2\"},{\"t\":3,\"p\":1,\"n\":\"Y2\"},{\"t\":3,\"p\":1,\"n\":\"Z2\"}]},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"MODT - Texture Files Hashes\"},{\"t\":7,\"p\":1,\"n\":\"MODS - Alternate Textures\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"3D Name\"},{\"t\":3,\"p\":1,\"n\":\"New Texture\"},{\"t\":3,\"p\":1,\"n\":\"3D Index\"}]}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Destructable\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"DEST - Header\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Health\"},{\"t\":3,\"p\":1,\"n\":\"DEST Count\"},{\"t\":3,\"p\":1,\"n\":\"VATS Targetable\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":8,\"p\":1,\"n\":\"Stages\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Stage\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"DSTD - Destruction Stage Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Health %\"},{\"t\":3,\"p\":1,\"n\":\"Index\"},{\"t\":3,\"p\":1,\"n\":\"Model Damage Stage\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":3,\"p\":1,\"n\":\"Self Damage per Second\"},{\"t\":3,\"p\":1,\"n\":\"Explosion\"},{\"t\":3,\"p\":1,\"n\":\"Debris\"},{\"t\":3,\"p\":1,\"n\":\"Debris Count\"}]},{\"t\":6,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"DMDL - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"DMDT - Texture Files Hashes\"},{\"t\":7,\"p\":1,\"n\":\"DMDS - Alternate Textures\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"3D Name\"},{\"t\":3,\"p\":1,\"n\":\"New Texture\"},{\"t\":3,\"p\":1,\"n\":\"3D Index\"}]}]}]},{\"p\":1,\"n\":\"DSTF - End Marker\"}]}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DATA - Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":5,\"p\":1,\"n\":\"Gravity\"},{\"t\":5,\"p\":1,\"n\":\"Speed\"},{\"t\":5,\"p\":1,\"n\":\"Range\"},{\"t\":3,\"p\":1,\"n\":\"Light\"},{\"t\":3,\"p\":1,\"n\":\"Muzzle Flash - Light\"},{\"t\":5,\"p\":1,\"n\":\"Tracer Chance\"},{\"t\":5,\"p\":1,\"n\":\"Explosion - Alt. Trigger - Proximity\"},{\"t\":5,\"p\":1,\"n\":\"Explosion - Alt. Trigger - Timer\"},{\"t\":3,\"p\":1,\"n\":\"Explosion\"},{\"t\":3,\"p\":1,\"n\":\"Sound\"},{\"t\":5,\"p\":1,\"n\":\"Muzzle Flash - Duration\"},{\"t\":5,\"p\":1,\"n\":\"Fade Duration\"},{\"t\":5,\"p\":1,\"n\":\"Impact Force\"},{\"t\":3,\"p\":1,\"n\":\"Sound - Countdown\"},{\"t\":3,\"p\":1,\"n\":\"Sound - Disable\"},{\"t\":3,\"p\":1,\"n\":\"Default Weapon Source\"},{\"t\":5,\"p\":1,\"n\":\"Cone Spread\"},{\"t\":5,\"p\":1,\"n\":\"Collision Radius\"},{\"t\":5,\"p\":1,\"n\":\"Lifetime\"},{\"t\":5,\"p\":1,\"n\":\"Relaunch Interval\"},{\"t\":3,\"p\":1,\"n\":\"Decal Data\"},{\"t\":3,\"p\":1,\"n\":\"Collision Layer\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Muzzle Flash Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"NAM1 - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"NAM2 - Texture Files Hashes\"}]},{\"t\":3,\"p\":1,\"n\":\"VNAM - Sound Level\"}]},{\"t\":1,\"p\":1,\"n\":\"PWAT\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"}]},{\"t\":1,\"p\":1,\"n\":\"QUST - Quest\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"VMAD - Virtual Machine Adapter\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Version\"},{\"t\":3,\"p\":1,\"n\":\"Object Format\"},{\"t\":7,\"p\":1,\"n\":\"Scripts\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Script\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"scriptName\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":7,\"p\":1,\"n\":\"Properties\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Property\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"propertyName\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]},{\"t\":2,\"p\":1,\"n\":\"String\"},{\"t\":3,\"p\":1,\"n\":\"Int32\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":3,\"p\":1,\"n\":\"Bool\"},{\"t\":7,\"p\":1,\"n\":\"Array of Object\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]}]},{\"t\":7,\"p\":1,\"n\":\"Array of String\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Int32\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Float\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Bool\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]}]}]}]}]},{\"t\":6,\"p\":1,\"n\":\"Script Fragments\",\"c\":[{\"t\":3,\"n\":\"Unknown\"},{\"t\":3,\"p\":1,\"n\":\"fragmentCount\"},{\"t\":2,\"p\":1,\"n\":\"fileName\"},{\"t\":7,\"p\":1,\"n\":\"Fragments\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Fragment\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Quest Stage\"},{\"t\":3,\"n\":\"Unknown\"},{\"t\":3,\"p\":1,\"n\":\"Quest Stage Index\"},{\"t\":2,\"p\":1,\"n\":\"scriptName\"},{\"t\":2,\"p\":1,\"n\":\"fragmentName\"}]}]}]},{\"t\":7,\"p\":1,\"n\":\"Aliases\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alias\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]},{\"t\":3,\"p\":1,\"n\":\"Version\"},{\"t\":3,\"p\":1,\"n\":\"Object Format\"},{\"t\":7,\"p\":1,\"n\":\"Alias Scripts\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Script\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"scriptName\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":7,\"p\":1,\"n\":\"Properties\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Property\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"propertyName\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]},{\"t\":2,\"p\":1,\"n\":\"String\"},{\"t\":3,\"p\":1,\"n\":\"Int32\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":3,\"p\":1,\"n\":\"Bool\"},{\"t\":7,\"p\":1,\"n\":\"Array of Object\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]}]},{\"t\":7,\"p\":1,\"n\":\"Array of String\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Int32\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Float\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Bool\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]}]}]}]}]}]}]}]},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DNAM - General\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":3,\"p\":1,\"n\":\"Priority\"},{\"t\":3,\"p\":1,\"n\":\"Form Version\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":3,\"p\":1,\"n\":\"Type\"}]},{\"t\":2,\"p\":1,\"n\":\"ENAM - Event\"},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Text Display Globals\",\"d\":1,\"c\":[{\"t\":3,\"p\":1,\"n\":\"QTGL - Global\"}]},{\"t\":2,\"p\":1,\"n\":\"FLTR - Object Window Filter\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Quest Dialogue Conditions\",\"c\":[{\"t\":8,\"p\":1,\"n\":\"Conditions\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Condition\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"CTDA - \",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":5,\"p\":1,\"n\":\"Comparison Value - Float\"},{\"t\":3,\"p\":1,\"n\":\"Comparison Value - Global\"},{\"t\":3,\"p\":1,\"n\":\"Function\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":11,\"p\":1,\"n\":\"None\"},{\"t\":3,\"p\":1,\"n\":\"Integer\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":11,\"p\":1,\"n\":\"Variable Name (unused)\"},{\"t\":3,\"p\":1,\"n\":\"Sex\"},{\"t\":3,\"p\":1,\"n\":\"Actor Value\"},{\"t\":3,\"p\":1,\"n\":\"Crime Type\"},{\"t\":3,\"p\":1,\"n\":\"Axis\"},{\"t\":3,\"p\":1,\"n\":\"Quest Stage (unused)\"},{\"t\":3,\"p\":1,\"n\":\"Misc Stat\"},{\"t\":3,\"p\":1,\"n\":\"Alignment\"},{\"t\":3,\"p\":1,\"n\":\"Equip Type\"},{\"t\":3,\"p\":1,\"n\":\"Form Type\"},{\"t\":3,\"p\":1,\"n\":\"Critical Stage\"},{\"t\":3,\"p\":1,\"n\":\"Object Reference\"},{\"t\":3,\"p\":1,\"n\":\"Inventory Object\"},{\"t\":3,\"p\":1,\"n\":\"Actor\"},{\"t\":3,\"p\":1,\"n\":\"Voice Type\"},{\"t\":3,\"p\":1,\"n\":\"Idle\"},{\"t\":3,\"p\":1,\"n\":\"Form List\"},{\"t\":3,\"p\":1,\"n\":\"Quest\"},{\"t\":3,\"p\":1,\"n\":\"Faction\"},{\"t\":3,\"p\":1,\"n\":\"Cell\"},{\"t\":3,\"p\":1,\"n\":\"Class\"},{\"t\":3,\"p\":1,\"n\":\"Race\"},{\"t\":3,\"p\":1,\"n\":\"Actor Base\"},{\"t\":3,\"p\":1,\"n\":\"Global\"},{\"t\":3,\"p\":1,\"n\":\"Weather\"},{\"t\":3,\"p\":1,\"n\":\"Package\"},{\"t\":3,\"p\":1,\"n\":\"Encounter Zone\"},{\"t\":3,\"p\":1,\"n\":\"Perk\"},{\"t\":3,\"p\":1,\"n\":\"Owner\"},{\"t\":3,\"p\":1,\"n\":\"Furniture\"},{\"t\":3,\"p\":1,\"n\":\"Effect Item\"},{\"t\":3,\"p\":1,\"n\":\"Base Effect\"},{\"t\":3,\"p\":1,\"n\":\"Worldspace\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Function\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Param (INVALID)\"},{\"t\":3,\"p\":1,\"n\":\"Referenceable Object\"},{\"t\":3,\"p\":1,\"n\":\"Region\"},{\"t\":3,\"p\":1,\"n\":\"Keyword\"},{\"t\":3,\"p\":1,\"n\":\"Player Action\"},{\"t\":3,\"p\":1,\"n\":\"Casting Type\"},{\"t\":3,\"p\":1,\"n\":\"Shout\"},{\"t\":3,\"p\":1,\"n\":\"Location\"},{\"t\":3,\"p\":1,\"n\":\"Location Ref Type\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"Packdata ID\"},{\"t\":3,\"p\":1,\"n\":\"Association Type\"},{\"t\":3,\"p\":1,\"n\":\"Furniture Anim\"},{\"t\":3,\"p\":1,\"n\":\"Furniture Entry\"},{\"t\":3,\"p\":1,\"n\":\"Scene\"},{\"t\":3,\"p\":1,\"n\":\"Ward State\"},{\"t\":3,\"p\":1,\"n\":\"Event\"},{\"t\":3,\"p\":1,\"n\":\"Event Data\"},{\"t\":3,\"p\":1,\"n\":\"Quest Stage\"},{\"t\":3,\"p\":1,\"n\":\"Weapon\"},{\"t\":3,\"p\":1,\"n\":\"Weapon List\"},{\"t\":3,\"p\":1,\"n\":\"Target\"},{\"t\":3,\"p\":1,\"n\":\"Target List\"},{\"t\":3,\"p\":1,\"n\":\"Target Part\"},{\"t\":3,\"p\":1,\"n\":\"VATS Action\"},{\"t\":3,\"p\":1,\"n\":\"Critical Effect\"},{\"t\":3,\"p\":1,\"n\":\"Critical Effect List\"},{\"t\":3,\"p\":1,\"n\":\"Weapon Type\"},{\"t\":3,\"p\":1,\"n\":\"Projectile Type\"},{\"t\":3,\"p\":1,\"n\":\"Delivery Type\"},{\"t\":3,\"p\":1,\"n\":\"Run On\"},{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":3,\"p\":1,\"n\":\"Parameter #3\"}]},{\"t\":2,\"p\":1,\"n\":\"CIS1 - Parameter #1\"},{\"t\":2,\"p\":1,\"n\":\"CIS2 - Parameter #2\"}]}]}]},{\"p\":1,\"n\":\"NEXT - Marker\"},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Conditions\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Condition\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"CTDA - \",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":5,\"p\":1,\"n\":\"Comparison Value - Float\"},{\"t\":3,\"p\":1,\"n\":\"Comparison Value - Global\"},{\"t\":3,\"p\":1,\"n\":\"Function\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":11,\"p\":1,\"n\":\"None\"},{\"t\":3,\"p\":1,\"n\":\"Integer\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":11,\"p\":1,\"n\":\"Variable Name (unused)\"},{\"t\":3,\"p\":1,\"n\":\"Sex\"},{\"t\":3,\"p\":1,\"n\":\"Actor Value\"},{\"t\":3,\"p\":1,\"n\":\"Crime Type\"},{\"t\":3,\"p\":1,\"n\":\"Axis\"},{\"t\":3,\"p\":1,\"n\":\"Quest Stage (unused)\"},{\"t\":3,\"p\":1,\"n\":\"Misc Stat\"},{\"t\":3,\"p\":1,\"n\":\"Alignment\"},{\"t\":3,\"p\":1,\"n\":\"Equip Type\"},{\"t\":3,\"p\":1,\"n\":\"Form Type\"},{\"t\":3,\"p\":1,\"n\":\"Critical Stage\"},{\"t\":3,\"p\":1,\"n\":\"Object Reference\"},{\"t\":3,\"p\":1,\"n\":\"Inventory Object\"},{\"t\":3,\"p\":1,\"n\":\"Actor\"},{\"t\":3,\"p\":1,\"n\":\"Voice Type\"},{\"t\":3,\"p\":1,\"n\":\"Idle\"},{\"t\":3,\"p\":1,\"n\":\"Form List\"},{\"t\":3,\"p\":1,\"n\":\"Quest\"},{\"t\":3,\"p\":1,\"n\":\"Faction\"},{\"t\":3,\"p\":1,\"n\":\"Cell\"},{\"t\":3,\"p\":1,\"n\":\"Class\"},{\"t\":3,\"p\":1,\"n\":\"Race\"},{\"t\":3,\"p\":1,\"n\":\"Actor Base\"},{\"t\":3,\"p\":1,\"n\":\"Global\"},{\"t\":3,\"p\":1,\"n\":\"Weather\"},{\"t\":3,\"p\":1,\"n\":\"Package\"},{\"t\":3,\"p\":1,\"n\":\"Encounter Zone\"},{\"t\":3,\"p\":1,\"n\":\"Perk\"},{\"t\":3,\"p\":1,\"n\":\"Owner\"},{\"t\":3,\"p\":1,\"n\":\"Furniture\"},{\"t\":3,\"p\":1,\"n\":\"Effect Item\"},{\"t\":3,\"p\":1,\"n\":\"Base Effect\"},{\"t\":3,\"p\":1,\"n\":\"Worldspace\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Function\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Param (INVALID)\"},{\"t\":3,\"p\":1,\"n\":\"Referenceable Object\"},{\"t\":3,\"p\":1,\"n\":\"Region\"},{\"t\":3,\"p\":1,\"n\":\"Keyword\"},{\"t\":3,\"p\":1,\"n\":\"Player Action\"},{\"t\":3,\"p\":1,\"n\":\"Casting Type\"},{\"t\":3,\"p\":1,\"n\":\"Shout\"},{\"t\":3,\"p\":1,\"n\":\"Location\"},{\"t\":3,\"p\":1,\"n\":\"Location Ref Type\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"Packdata ID\"},{\"t\":3,\"p\":1,\"n\":\"Association Type\"},{\"t\":3,\"p\":1,\"n\":\"Furniture Anim\"},{\"t\":3,\"p\":1,\"n\":\"Furniture Entry\"},{\"t\":3,\"p\":1,\"n\":\"Scene\"},{\"t\":3,\"p\":1,\"n\":\"Ward State\"},{\"t\":3,\"p\":1,\"n\":\"Event\"},{\"t\":3,\"p\":1,\"n\":\"Event Data\"},{\"t\":3,\"p\":1,\"n\":\"Quest Stage\"},{\"t\":3,\"p\":1,\"n\":\"Weapon\"},{\"t\":3,\"p\":1,\"n\":\"Weapon List\"},{\"t\":3,\"p\":1,\"n\":\"Target\"},{\"t\":3,\"p\":1,\"n\":\"Target List\"},{\"t\":3,\"p\":1,\"n\":\"Target Part\"},{\"t\":3,\"p\":1,\"n\":\"VATS Action\"},{\"t\":3,\"p\":1,\"n\":\"Critical Effect\"},{\"t\":3,\"p\":1,\"n\":\"Critical Effect List\"},{\"t\":3,\"p\":1,\"n\":\"Weapon Type\"},{\"t\":3,\"p\":1,\"n\":\"Projectile Type\"},{\"t\":3,\"p\":1,\"n\":\"Delivery Type\"},{\"t\":3,\"p\":1,\"n\":\"Run On\"},{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":3,\"p\":1,\"n\":\"Parameter #3\"}]},{\"t\":2,\"p\":1,\"n\":\"CIS1 - Parameter #1\"},{\"t\":2,\"p\":1,\"n\":\"CIS2 - Parameter #2\"}]}]},{\"t\":10,\"s\":1,\"p\":1,\"n\":\"Stages\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Stage\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"INDX - Stage Index\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Stage Index\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":3,\"n\":\"Unknown\"}]},{\"t\":8,\"p\":1,\"n\":\"Log Entries\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Log Entry\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"QSDT - Stage Flags\"},{\"t\":8,\"p\":1,\"n\":\"Conditions\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Condition\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"CTDA - \",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":5,\"p\":1,\"n\":\"Comparison Value - Float\"},{\"t\":3,\"p\":1,\"n\":\"Comparison Value - Global\"},{\"t\":3,\"p\":1,\"n\":\"Function\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":11,\"p\":1,\"n\":\"None\"},{\"t\":3,\"p\":1,\"n\":\"Integer\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":11,\"p\":1,\"n\":\"Variable Name (unused)\"},{\"t\":3,\"p\":1,\"n\":\"Sex\"},{\"t\":3,\"p\":1,\"n\":\"Actor Value\"},{\"t\":3,\"p\":1,\"n\":\"Crime Type\"},{\"t\":3,\"p\":1,\"n\":\"Axis\"},{\"t\":3,\"p\":1,\"n\":\"Quest Stage (unused)\"},{\"t\":3,\"p\":1,\"n\":\"Misc Stat\"},{\"t\":3,\"p\":1,\"n\":\"Alignment\"},{\"t\":3,\"p\":1,\"n\":\"Equip Type\"},{\"t\":3,\"p\":1,\"n\":\"Form Type\"},{\"t\":3,\"p\":1,\"n\":\"Critical Stage\"},{\"t\":3,\"p\":1,\"n\":\"Object Reference\"},{\"t\":3,\"p\":1,\"n\":\"Inventory Object\"},{\"t\":3,\"p\":1,\"n\":\"Actor\"},{\"t\":3,\"p\":1,\"n\":\"Voice Type\"},{\"t\":3,\"p\":1,\"n\":\"Idle\"},{\"t\":3,\"p\":1,\"n\":\"Form List\"},{\"t\":3,\"p\":1,\"n\":\"Quest\"},{\"t\":3,\"p\":1,\"n\":\"Faction\"},{\"t\":3,\"p\":1,\"n\":\"Cell\"},{\"t\":3,\"p\":1,\"n\":\"Class\"},{\"t\":3,\"p\":1,\"n\":\"Race\"},{\"t\":3,\"p\":1,\"n\":\"Actor Base\"},{\"t\":3,\"p\":1,\"n\":\"Global\"},{\"t\":3,\"p\":1,\"n\":\"Weather\"},{\"t\":3,\"p\":1,\"n\":\"Package\"},{\"t\":3,\"p\":1,\"n\":\"Encounter Zone\"},{\"t\":3,\"p\":1,\"n\":\"Perk\"},{\"t\":3,\"p\":1,\"n\":\"Owner\"},{\"t\":3,\"p\":1,\"n\":\"Furniture\"},{\"t\":3,\"p\":1,\"n\":\"Effect Item\"},{\"t\":3,\"p\":1,\"n\":\"Base Effect\"},{\"t\":3,\"p\":1,\"n\":\"Worldspace\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Function\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Param (INVALID)\"},{\"t\":3,\"p\":1,\"n\":\"Referenceable Object\"},{\"t\":3,\"p\":1,\"n\":\"Region\"},{\"t\":3,\"p\":1,\"n\":\"Keyword\"},{\"t\":3,\"p\":1,\"n\":\"Player Action\"},{\"t\":3,\"p\":1,\"n\":\"Casting Type\"},{\"t\":3,\"p\":1,\"n\":\"Shout\"},{\"t\":3,\"p\":1,\"n\":\"Location\"},{\"t\":3,\"p\":1,\"n\":\"Location Ref Type\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"Packdata ID\"},{\"t\":3,\"p\":1,\"n\":\"Association Type\"},{\"t\":3,\"p\":1,\"n\":\"Furniture Anim\"},{\"t\":3,\"p\":1,\"n\":\"Furniture Entry\"},{\"t\":3,\"p\":1,\"n\":\"Scene\"},{\"t\":3,\"p\":1,\"n\":\"Ward State\"},{\"t\":3,\"p\":1,\"n\":\"Event\"},{\"t\":3,\"p\":1,\"n\":\"Event Data\"},{\"t\":3,\"p\":1,\"n\":\"Quest Stage\"},{\"t\":3,\"p\":1,\"n\":\"Weapon\"},{\"t\":3,\"p\":1,\"n\":\"Weapon List\"},{\"t\":3,\"p\":1,\"n\":\"Target\"},{\"t\":3,\"p\":1,\"n\":\"Target List\"},{\"t\":3,\"p\":1,\"n\":\"Target Part\"},{\"t\":3,\"p\":1,\"n\":\"VATS Action\"},{\"t\":3,\"p\":1,\"n\":\"Critical Effect\"},{\"t\":3,\"p\":1,\"n\":\"Critical Effect List\"},{\"t\":3,\"p\":1,\"n\":\"Weapon Type\"},{\"t\":3,\"p\":1,\"n\":\"Projectile Type\"},{\"t\":3,\"p\":1,\"n\":\"Delivery Type\"},{\"t\":3,\"p\":1,\"n\":\"Run On\"},{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":3,\"p\":1,\"n\":\"Parameter #3\"}]},{\"t\":2,\"p\":1,\"n\":\"CIS1 - Parameter #1\"},{\"t\":2,\"p\":1,\"n\":\"CIS2 - Parameter #2\"}]}]},{\"t\":2,\"p\":1,\"n\":\"CNAM - Log Entry\"},{\"t\":3,\"p\":1,\"n\":\"NAM0 - Next Quest\"},{\"t\":11,\"n\":\"SCHR - Unused\"},{\"t\":11,\"n\":\"SCTX - Unused\"},{\"t\":11,\"n\":\"QNAM - Unused\"}]}]}]}]},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Objectives\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Objective\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"QOBJ - Objective Index\"},{\"t\":3,\"p\":1,\"n\":\"FNAM - Flags\"},{\"t\":2,\"p\":1,\"n\":\"NNAM - Display Text\"},{\"t\":8,\"p\":1,\"n\":\"Targets\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Target\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"QSTA - Target\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":8,\"p\":1,\"n\":\"Conditions\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Condition\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"CTDA - \",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":5,\"p\":1,\"n\":\"Comparison Value - Float\"},{\"t\":3,\"p\":1,\"n\":\"Comparison Value - Global\"},{\"t\":3,\"p\":1,\"n\":\"Function\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":11,\"p\":1,\"n\":\"None\"},{\"t\":3,\"p\":1,\"n\":\"Integer\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":11,\"p\":1,\"n\":\"Variable Name (unused)\"},{\"t\":3,\"p\":1,\"n\":\"Sex\"},{\"t\":3,\"p\":1,\"n\":\"Actor Value\"},{\"t\":3,\"p\":1,\"n\":\"Crime Type\"},{\"t\":3,\"p\":1,\"n\":\"Axis\"},{\"t\":3,\"p\":1,\"n\":\"Quest Stage (unused)\"},{\"t\":3,\"p\":1,\"n\":\"Misc Stat\"},{\"t\":3,\"p\":1,\"n\":\"Alignment\"},{\"t\":3,\"p\":1,\"n\":\"Equip Type\"},{\"t\":3,\"p\":1,\"n\":\"Form Type\"},{\"t\":3,\"p\":1,\"n\":\"Critical Stage\"},{\"t\":3,\"p\":1,\"n\":\"Object Reference\"},{\"t\":3,\"p\":1,\"n\":\"Inventory Object\"},{\"t\":3,\"p\":1,\"n\":\"Actor\"},{\"t\":3,\"p\":1,\"n\":\"Voice Type\"},{\"t\":3,\"p\":1,\"n\":\"Idle\"},{\"t\":3,\"p\":1,\"n\":\"Form List\"},{\"t\":3,\"p\":1,\"n\":\"Quest\"},{\"t\":3,\"p\":1,\"n\":\"Faction\"},{\"t\":3,\"p\":1,\"n\":\"Cell\"},{\"t\":3,\"p\":1,\"n\":\"Class\"},{\"t\":3,\"p\":1,\"n\":\"Race\"},{\"t\":3,\"p\":1,\"n\":\"Actor Base\"},{\"t\":3,\"p\":1,\"n\":\"Global\"},{\"t\":3,\"p\":1,\"n\":\"Weather\"},{\"t\":3,\"p\":1,\"n\":\"Package\"},{\"t\":3,\"p\":1,\"n\":\"Encounter Zone\"},{\"t\":3,\"p\":1,\"n\":\"Perk\"},{\"t\":3,\"p\":1,\"n\":\"Owner\"},{\"t\":3,\"p\":1,\"n\":\"Furniture\"},{\"t\":3,\"p\":1,\"n\":\"Effect Item\"},{\"t\":3,\"p\":1,\"n\":\"Base Effect\"},{\"t\":3,\"p\":1,\"n\":\"Worldspace\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Function\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Param (INVALID)\"},{\"t\":3,\"p\":1,\"n\":\"Referenceable Object\"},{\"t\":3,\"p\":1,\"n\":\"Region\"},{\"t\":3,\"p\":1,\"n\":\"Keyword\"},{\"t\":3,\"p\":1,\"n\":\"Player Action\"},{\"t\":3,\"p\":1,\"n\":\"Casting Type\"},{\"t\":3,\"p\":1,\"n\":\"Shout\"},{\"t\":3,\"p\":1,\"n\":\"Location\"},{\"t\":3,\"p\":1,\"n\":\"Location Ref Type\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"Packdata ID\"},{\"t\":3,\"p\":1,\"n\":\"Association Type\"},{\"t\":3,\"p\":1,\"n\":\"Furniture Anim\"},{\"t\":3,\"p\":1,\"n\":\"Furniture Entry\"},{\"t\":3,\"p\":1,\"n\":\"Scene\"},{\"t\":3,\"p\":1,\"n\":\"Ward State\"},{\"t\":3,\"p\":1,\"n\":\"Event\"},{\"t\":3,\"p\":1,\"n\":\"Event Data\"},{\"t\":3,\"p\":1,\"n\":\"Quest Stage\"},{\"t\":3,\"p\":1,\"n\":\"Weapon\"},{\"t\":3,\"p\":1,\"n\":\"Weapon List\"},{\"t\":3,\"p\":1,\"n\":\"Target\"},{\"t\":3,\"p\":1,\"n\":\"Target List\"},{\"t\":3,\"p\":1,\"n\":\"Target Part\"},{\"t\":3,\"p\":1,\"n\":\"VATS Action\"},{\"t\":3,\"p\":1,\"n\":\"Critical Effect\"},{\"t\":3,\"p\":1,\"n\":\"Critical Effect List\"},{\"t\":3,\"p\":1,\"n\":\"Weapon Type\"},{\"t\":3,\"p\":1,\"n\":\"Projectile Type\"},{\"t\":3,\"p\":1,\"n\":\"Delivery Type\"},{\"t\":3,\"p\":1,\"n\":\"Run On\"},{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":3,\"p\":1,\"n\":\"Parameter #3\"}]},{\"t\":2,\"p\":1,\"n\":\"CIS1 - Parameter #1\"},{\"t\":2,\"p\":1,\"n\":\"CIS2 - Parameter #2\"}]}]}]}]}]}]},{\"t\":11,\"n\":\"ANAM - Aliases Marker\"},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Aliases\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alias\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"ALST - Reference Alias ID\"},{\"t\":2,\"p\":1,\"n\":\"ALID - Alias Name\"},{\"t\":6,\"p\":1,\"n\":\"FNAM - Alias Flags\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":3,\"p\":1,\"n\":\"Additional Flags\"}]},{\"t\":3,\"p\":1,\"n\":\"ALFI - Force Into Alias When Filled\"},{\"t\":3,\"p\":1,\"n\":\"ALFL - Specific Location\"},{\"t\":3,\"p\":1,\"n\":\"ALFR - Forced Reference\"},{\"t\":3,\"p\":1,\"n\":\"ALUA - Unique Actor\"},{\"t\":6,\"p\":1,\"n\":\"Location Alias Reference\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"ALFA - Alias\"},{\"t\":3,\"p\":1,\"n\":\"KNAM - Keyword\"},{\"t\":3,\"p\":1,\"n\":\"ALRT - Ref Type\"}]},{\"t\":6,\"p\":1,\"n\":\"External Alias Reference\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"ALEQ - Quest\"},{\"t\":3,\"p\":1,\"n\":\"ALEA - Alias\"}]},{\"t\":6,\"p\":1,\"n\":\"Create Reference to Object\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"ALCO - Object\"},{\"t\":6,\"p\":1,\"n\":\"ALCA - Alias\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"Create\"}]},{\"t\":3,\"p\":1,\"n\":\"ALCL - Level\"}]},{\"t\":6,\"p\":1,\"n\":\"Find Matching Reference Near Alias\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"ALNA - Alias\"},{\"t\":3,\"p\":1,\"n\":\"ALNT - Type\"}]},{\"t\":6,\"p\":1,\"n\":\"Find Matching Reference From Event\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"ALFE - From Event\"},{\"t\":11,\"p\":1,\"n\":\"ALFD - Event Data\"}]},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Conditions\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Condition\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"CTDA - \",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":5,\"p\":1,\"n\":\"Comparison Value - Float\"},{\"t\":3,\"p\":1,\"n\":\"Comparison Value - Global\"},{\"t\":3,\"p\":1,\"n\":\"Function\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":11,\"p\":1,\"n\":\"None\"},{\"t\":3,\"p\":1,\"n\":\"Integer\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":11,\"p\":1,\"n\":\"Variable Name (unused)\"},{\"t\":3,\"p\":1,\"n\":\"Sex\"},{\"t\":3,\"p\":1,\"n\":\"Actor Value\"},{\"t\":3,\"p\":1,\"n\":\"Crime Type\"},{\"t\":3,\"p\":1,\"n\":\"Axis\"},{\"t\":3,\"p\":1,\"n\":\"Quest Stage (unused)\"},{\"t\":3,\"p\":1,\"n\":\"Misc Stat\"},{\"t\":3,\"p\":1,\"n\":\"Alignment\"},{\"t\":3,\"p\":1,\"n\":\"Equip Type\"},{\"t\":3,\"p\":1,\"n\":\"Form Type\"},{\"t\":3,\"p\":1,\"n\":\"Critical Stage\"},{\"t\":3,\"p\":1,\"n\":\"Object Reference\"},{\"t\":3,\"p\":1,\"n\":\"Inventory Object\"},{\"t\":3,\"p\":1,\"n\":\"Actor\"},{\"t\":3,\"p\":1,\"n\":\"Voice Type\"},{\"t\":3,\"p\":1,\"n\":\"Idle\"},{\"t\":3,\"p\":1,\"n\":\"Form List\"},{\"t\":3,\"p\":1,\"n\":\"Quest\"},{\"t\":3,\"p\":1,\"n\":\"Faction\"},{\"t\":3,\"p\":1,\"n\":\"Cell\"},{\"t\":3,\"p\":1,\"n\":\"Class\"},{\"t\":3,\"p\":1,\"n\":\"Race\"},{\"t\":3,\"p\":1,\"n\":\"Actor Base\"},{\"t\":3,\"p\":1,\"n\":\"Global\"},{\"t\":3,\"p\":1,\"n\":\"Weather\"},{\"t\":3,\"p\":1,\"n\":\"Package\"},{\"t\":3,\"p\":1,\"n\":\"Encounter Zone\"},{\"t\":3,\"p\":1,\"n\":\"Perk\"},{\"t\":3,\"p\":1,\"n\":\"Owner\"},{\"t\":3,\"p\":1,\"n\":\"Furniture\"},{\"t\":3,\"p\":1,\"n\":\"Effect Item\"},{\"t\":3,\"p\":1,\"n\":\"Base Effect\"},{\"t\":3,\"p\":1,\"n\":\"Worldspace\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Function\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Param (INVALID)\"},{\"t\":3,\"p\":1,\"n\":\"Referenceable Object\"},{\"t\":3,\"p\":1,\"n\":\"Region\"},{\"t\":3,\"p\":1,\"n\":\"Keyword\"},{\"t\":3,\"p\":1,\"n\":\"Player Action\"},{\"t\":3,\"p\":1,\"n\":\"Casting Type\"},{\"t\":3,\"p\":1,\"n\":\"Shout\"},{\"t\":3,\"p\":1,\"n\":\"Location\"},{\"t\":3,\"p\":1,\"n\":\"Location Ref Type\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"Packdata ID\"},{\"t\":3,\"p\":1,\"n\":\"Association Type\"},{\"t\":3,\"p\":1,\"n\":\"Furniture Anim\"},{\"t\":3,\"p\":1,\"n\":\"Furniture Entry\"},{\"t\":3,\"p\":1,\"n\":\"Scene\"},{\"t\":3,\"p\":1,\"n\":\"Ward State\"},{\"t\":3,\"p\":1,\"n\":\"Event\"},{\"t\":3,\"p\":1,\"n\":\"Event Data\"},{\"t\":3,\"p\":1,\"n\":\"Quest Stage\"},{\"t\":3,\"p\":1,\"n\":\"Weapon\"},{\"t\":3,\"p\":1,\"n\":\"Weapon List\"},{\"t\":3,\"p\":1,\"n\":\"Target\"},{\"t\":3,\"p\":1,\"n\":\"Target List\"},{\"t\":3,\"p\":1,\"n\":\"Target Part\"},{\"t\":3,\"p\":1,\"n\":\"VATS Action\"},{\"t\":3,\"p\":1,\"n\":\"Critical Effect\"},{\"t\":3,\"p\":1,\"n\":\"Critical Effect List\"},{\"t\":3,\"p\":1,\"n\":\"Weapon Type\"},{\"t\":3,\"p\":1,\"n\":\"Projectile Type\"},{\"t\":3,\"p\":1,\"n\":\"Delivery Type\"},{\"t\":3,\"p\":1,\"n\":\"Run On\"},{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":3,\"p\":1,\"n\":\"Parameter #3\"}]},{\"t\":2,\"p\":1,\"n\":\"CIS1 - Parameter #1\"},{\"t\":2,\"p\":1,\"n\":\"CIS2 - Parameter #2\"}]}]},{\"t\":3,\"p\":1,\"n\":\"KSIZ - Keyword Count\"},{\"t\":7,\"p\":1,\"n\":\"KWDA - Keywords\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Keyword\"}]},{\"t\":3,\"p\":1,\"n\":\"COCT - Count\"},{\"t\":10,\"p\":1,\"n\":\"Items\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Item\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"CNTO - Item\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Item\"},{\"t\":3,\"p\":1,\"n\":\"Count\"}]},{\"t\":6,\"p\":1,\"n\":\"COED - Extra Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Owner\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Global Variable\"},{\"t\":3,\"p\":1,\"n\":\"Required Rank\"},{\"t\":5,\"p\":1,\"n\":\"Item Condition\"}]}]}]},{\"t\":3,\"p\":1,\"n\":\"SPOR - Spectator override package list\"},{\"t\":3,\"p\":1,\"n\":\"OCOR - Observe dead body override package list\"},{\"t\":3,\"p\":1,\"n\":\"GWOR - Guard warn override package list\"},{\"t\":3,\"p\":1,\"n\":\"ECOR - Combat override package list\"},{\"t\":3,\"p\":1,\"n\":\"ALDN - Display Name\"},{\"t\":8,\"p\":1,\"n\":\"Alias Spells\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"ALSP - Spell\"}]},{\"t\":8,\"p\":1,\"n\":\"Alias Factions\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"ALFC - Faction\"}]},{\"t\":8,\"p\":1,\"n\":\"Alias Package Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"ALPC - Package\"}]},{\"t\":3,\"p\":1,\"n\":\"VTCK - Voice Types\"},{\"p\":1,\"n\":\"ALED - Alias End\"}]}]},{\"t\":2,\"p\":1,\"n\":\"NNAM - Description\"},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Targets\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Target\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"QSTA - Target\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Target\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Conditions\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Condition\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"CTDA - \",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":5,\"p\":1,\"n\":\"Comparison Value - Float\"},{\"t\":3,\"p\":1,\"n\":\"Comparison Value - Global\"},{\"t\":3,\"p\":1,\"n\":\"Function\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":11,\"p\":1,\"n\":\"None\"},{\"t\":3,\"p\":1,\"n\":\"Integer\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":11,\"p\":1,\"n\":\"Variable Name (unused)\"},{\"t\":3,\"p\":1,\"n\":\"Sex\"},{\"t\":3,\"p\":1,\"n\":\"Actor Value\"},{\"t\":3,\"p\":1,\"n\":\"Crime Type\"},{\"t\":3,\"p\":1,\"n\":\"Axis\"},{\"t\":3,\"p\":1,\"n\":\"Quest Stage (unused)\"},{\"t\":3,\"p\":1,\"n\":\"Misc Stat\"},{\"t\":3,\"p\":1,\"n\":\"Alignment\"},{\"t\":3,\"p\":1,\"n\":\"Equip Type\"},{\"t\":3,\"p\":1,\"n\":\"Form Type\"},{\"t\":3,\"p\":1,\"n\":\"Critical Stage\"},{\"t\":3,\"p\":1,\"n\":\"Object Reference\"},{\"t\":3,\"p\":1,\"n\":\"Inventory Object\"},{\"t\":3,\"p\":1,\"n\":\"Actor\"},{\"t\":3,\"p\":1,\"n\":\"Voice Type\"},{\"t\":3,\"p\":1,\"n\":\"Idle\"},{\"t\":3,\"p\":1,\"n\":\"Form List\"},{\"t\":3,\"p\":1,\"n\":\"Quest\"},{\"t\":3,\"p\":1,\"n\":\"Faction\"},{\"t\":3,\"p\":1,\"n\":\"Cell\"},{\"t\":3,\"p\":1,\"n\":\"Class\"},{\"t\":3,\"p\":1,\"n\":\"Race\"},{\"t\":3,\"p\":1,\"n\":\"Actor Base\"},{\"t\":3,\"p\":1,\"n\":\"Global\"},{\"t\":3,\"p\":1,\"n\":\"Weather\"},{\"t\":3,\"p\":1,\"n\":\"Package\"},{\"t\":3,\"p\":1,\"n\":\"Encounter Zone\"},{\"t\":3,\"p\":1,\"n\":\"Perk\"},{\"t\":3,\"p\":1,\"n\":\"Owner\"},{\"t\":3,\"p\":1,\"n\":\"Furniture\"},{\"t\":3,\"p\":1,\"n\":\"Effect Item\"},{\"t\":3,\"p\":1,\"n\":\"Base Effect\"},{\"t\":3,\"p\":1,\"n\":\"Worldspace\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Function\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Param (INVALID)\"},{\"t\":3,\"p\":1,\"n\":\"Referenceable Object\"},{\"t\":3,\"p\":1,\"n\":\"Region\"},{\"t\":3,\"p\":1,\"n\":\"Keyword\"},{\"t\":3,\"p\":1,\"n\":\"Player Action\"},{\"t\":3,\"p\":1,\"n\":\"Casting Type\"},{\"t\":3,\"p\":1,\"n\":\"Shout\"},{\"t\":3,\"p\":1,\"n\":\"Location\"},{\"t\":3,\"p\":1,\"n\":\"Location Ref Type\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"Packdata ID\"},{\"t\":3,\"p\":1,\"n\":\"Association Type\"},{\"t\":3,\"p\":1,\"n\":\"Furniture Anim\"},{\"t\":3,\"p\":1,\"n\":\"Furniture Entry\"},{\"t\":3,\"p\":1,\"n\":\"Scene\"},{\"t\":3,\"p\":1,\"n\":\"Ward State\"},{\"t\":3,\"p\":1,\"n\":\"Event\"},{\"t\":3,\"p\":1,\"n\":\"Event Data\"},{\"t\":3,\"p\":1,\"n\":\"Quest Stage\"},{\"t\":3,\"p\":1,\"n\":\"Weapon\"},{\"t\":3,\"p\":1,\"n\":\"Weapon List\"},{\"t\":3,\"p\":1,\"n\":\"Target\"},{\"t\":3,\"p\":1,\"n\":\"Target List\"},{\"t\":3,\"p\":1,\"n\":\"Target Part\"},{\"t\":3,\"p\":1,\"n\":\"VATS Action\"},{\"t\":3,\"p\":1,\"n\":\"Critical Effect\"},{\"t\":3,\"p\":1,\"n\":\"Critical Effect List\"},{\"t\":3,\"p\":1,\"n\":\"Weapon Type\"},{\"t\":3,\"p\":1,\"n\":\"Projectile Type\"},{\"t\":3,\"p\":1,\"n\":\"Delivery Type\"},{\"t\":3,\"p\":1,\"n\":\"Run On\"},{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":3,\"p\":1,\"n\":\"Parameter #3\"}]},{\"t\":2,\"p\":1,\"n\":\"CIS1 - Parameter #1\"},{\"t\":2,\"p\":1,\"n\":\"CIS2 - Parameter #2\"}]}]}]}]}]},{\"t\":1,\"p\":1,\"n\":\"RACE - Race\",\"c\":[{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":2,\"p\":1,\"n\":\"DESC - Description\"},{\"t\":3,\"n\":\"SPCT - Count\"},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Actor Effects\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"SPLO - Actor Effect\"}]},{\"t\":3,\"p\":1,\"n\":\"WNAM - Skin\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"BOD2 - Biped Body Template\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"First Person Flags\"},{\"t\":3,\"p\":1,\"n\":\"General Flags\"},{\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Armor Type\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"BODT - Body Template\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"First Person Flags\"},{\"t\":3,\"p\":1,\"n\":\"General Flags\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Armor Type\"}]},{\"t\":3,\"n\":\"KSIZ - Keyword Count\"},{\"t\":7,\"p\":1,\"n\":\"KWDA - Keywords\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Keyword\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DATA - \",\"c\":[{\"t\":7,\"p\":1,\"n\":\"Skill Boosts\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Skill Boost\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Skill\"},{\"t\":3,\"p\":1,\"n\":\"Boost\"}]}]},{\"t\":11,\"n\":\"Unknown\"},{\"t\":5,\"p\":1,\"n\":\"Male Height\"},{\"t\":5,\"p\":1,\"n\":\"Female Height\"},{\"t\":5,\"p\":1,\"n\":\"Male Weight\"},{\"t\":5,\"p\":1,\"n\":\"Female Weight\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":5,\"p\":1,\"n\":\"Starting Health\"},{\"t\":5,\"p\":1,\"n\":\"Starting Magicka\"},{\"t\":5,\"p\":1,\"n\":\"Starting Stamina\"},{\"t\":5,\"p\":1,\"n\":\"Base Carry Weight\"},{\"t\":5,\"p\":1,\"n\":\"Base Mass\"},{\"t\":5,\"p\":1,\"n\":\"Acceleration rate\"},{\"t\":5,\"p\":1,\"n\":\"Deceleration rate\"},{\"t\":3,\"p\":1,\"n\":\"Size\"},{\"t\":3,\"p\":1,\"n\":\"Head Biped Object\"},{\"t\":3,\"p\":1,\"n\":\"Hair Biped Object\"},{\"t\":5,\"p\":1,\"n\":\"Injured Health Pct\"},{\"t\":3,\"p\":1,\"n\":\"Shield Biped Object\"},{\"t\":5,\"p\":1,\"n\":\"Health Regen\"},{\"t\":5,\"p\":1,\"n\":\"Magicka Regen\"},{\"t\":5,\"p\":1,\"n\":\"Stamina Regen\"},{\"t\":5,\"p\":1,\"n\":\"Unarmed Damage\"},{\"t\":5,\"p\":1,\"n\":\"Unarmed Reach\"},{\"t\":3,\"p\":1,\"n\":\"Body Biped Object\"},{\"t\":5,\"p\":1,\"n\":\"Aim Angle Tolerance\"},{\"t\":5,\"p\":1,\"n\":\"Flight Radius\"},{\"t\":5,\"p\":1,\"n\":\"Angular Acceleration Rate\"},{\"t\":5,\"p\":1,\"n\":\"Angular Tolerance\"},{\"t\":3,\"p\":1,\"n\":\"Flags 2\"},{\"t\":6,\"p\":1,\"n\":\"Mount Data\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Offset X\"},{\"t\":5,\"p\":1,\"n\":\"Offset Y\"},{\"t\":5,\"p\":1,\"n\":\"Unknown\"}]}]},{\"p\":1,\"n\":\"MNAM - Male Marker\"},{\"t\":2,\"p\":1,\"n\":\"ANAM - Male Skeletal Model\"},{\"t\":11,\"p\":1,\"n\":\"MODT - Texture Files Hashes\"},{\"p\":1,\"n\":\"FNAM - Female Marker\"},{\"t\":2,\"p\":1,\"n\":\"ANAM - Female Skeletal Model\"},{\"p\":1,\"n\":\"NAM2 - Marker NAM2 #1\"},{\"t\":8,\"p\":1,\"n\":\"Movement Type Names\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MTNM - Name\"}]},{\"t\":7,\"p\":1,\"n\":\"VTCK - Voices\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Voice\"}]},{\"t\":7,\"p\":1,\"n\":\"DNAM - Decapitate Armors\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Decapitate Armor\"}]},{\"t\":7,\"p\":1,\"n\":\"HCLF - Default Hair Colors\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Default Hair Color\"}]},{\"t\":3,\"n\":\"TINL - Total Number of Tints in List\"},{\"t\":5,\"p\":1,\"n\":\"PNAM - FaceGen - Main clamp\"},{\"t\":5,\"p\":1,\"n\":\"UNAM - FaceGen - Face clamp\"},{\"t\":3,\"p\":1,\"n\":\"ATKR - Attack Race\"},{\"t\":10,\"p\":1,\"n\":\"Attacks\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Attack\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"ATKD - Attack Data\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Damage Mult\"},{\"t\":5,\"p\":1,\"n\":\"Attack Chance\"},{\"t\":3,\"p\":1,\"n\":\"Attack Spell\"},{\"t\":3,\"p\":1,\"n\":\"Attack Flags\"},{\"t\":5,\"p\":1,\"n\":\"Attack Angle\"},{\"t\":5,\"p\":1,\"n\":\"Strike Angle\"},{\"t\":5,\"p\":1,\"n\":\"Stagger\"},{\"t\":3,\"p\":1,\"n\":\"Attack Type\"},{\"t\":5,\"p\":1,\"n\":\"Knockdown\"},{\"t\":5,\"p\":1,\"n\":\"Recovery Time\"},{\"t\":5,\"p\":1,\"n\":\"Stamina Mult\"}]},{\"t\":2,\"p\":1,\"n\":\"ATKE - Attack Event\"}]}]},{\"t\":6,\"p\":1,\"n\":\"Body Data\",\"c\":[{\"n\":\"NAM1 - Body Data Marker\"},{\"t\":6,\"p\":1,\"n\":\"Male Body Data\",\"c\":[{\"n\":\"MNAM - Male Data Marker\"},{\"t\":10,\"s\":1,\"p\":1,\"n\":\"Parts\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Part\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"INDX - Index\"},{\"t\":6,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"MODT - Texture Files Hashes\"},{\"t\":7,\"p\":1,\"n\":\"MODS - Alternate Textures\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"3D Name\"},{\"t\":3,\"p\":1,\"n\":\"New Texture\"},{\"t\":3,\"p\":1,\"n\":\"3D Index\"}]}]}]}]}]}]},{\"t\":6,\"p\":1,\"n\":\"Female Body Data\",\"c\":[{\"n\":\"FNAM - Female Data Marker\"},{\"t\":10,\"s\":1,\"p\":1,\"n\":\"Parts\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Part\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"INDX - Index\"},{\"t\":6,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"MODT - Texture Files Hashes\"},{\"t\":7,\"p\":1,\"n\":\"MODS - Alternate Textures\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"3D Name\"},{\"t\":3,\"p\":1,\"n\":\"New Texture\"},{\"t\":3,\"p\":1,\"n\":\"3D Index\"}]}]}]}]}]}]}]},{\"t\":7,\"p\":1,\"n\":\"HNAM - Hairs\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Hair\"}]},{\"t\":7,\"p\":1,\"n\":\"ENAM - Eyes\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Eye\"}]},{\"t\":3,\"p\":1,\"n\":\"GNAM - Body Part Data\"},{\"p\":1,\"n\":\"NAM2 - Marker NAM2 #2\"},{\"p\":1,\"n\":\"NAM3 - Marker NAM3 #3\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Male Behavior Graph\",\"c\":[{\"p\":1,\"n\":\"MNAM - Male Data Marker\"},{\"t\":6,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"MODT - Texture Files Hashes\"},{\"t\":7,\"p\":1,\"n\":\"MODS - Alternate Textures\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"3D Name\"},{\"t\":3,\"p\":1,\"n\":\"New Texture\"},{\"t\":3,\"p\":1,\"n\":\"3D Index\"}]}]}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Female Behavior Graph\",\"c\":[{\"p\":1,\"n\":\"FNAM - Female Data Marker\"},{\"t\":6,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"MODT - Texture Files Hashes\"},{\"t\":7,\"p\":1,\"n\":\"MODS - Alternate Textures\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"3D Name\"},{\"t\":3,\"p\":1,\"n\":\"New Texture\"},{\"t\":3,\"p\":1,\"n\":\"3D Index\"}]}]}]}]},{\"t\":3,\"p\":1,\"n\":\"NAM4 - Material Type\"},{\"t\":3,\"p\":1,\"n\":\"NAM5 - Impact Data Set\"},{\"t\":3,\"p\":1,\"n\":\"NAM7 - Decapitation FX\"},{\"t\":3,\"p\":1,\"n\":\"ONAM - Open Loot Sound\"},{\"t\":3,\"p\":1,\"n\":\"LNAM - Close Loot Sound\"},{\"t\":8,\"p\":1,\"n\":\"Biped Object Names\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"NAME - Name\"}]},{\"t\":10,\"n\":\"Movement Types\",\"c\":[{\"t\":6,\"n\":\"Movement Types\",\"c\":[{\"t\":3,\"n\":\"MTYP - Movement Type\"},{\"t\":6,\"n\":\"SPED - Override Values\",\"c\":[{\"t\":5,\"n\":\"Left - Walk\"},{\"t\":5,\"n\":\"Left - Run\"},{\"t\":5,\"n\":\"Right - Walk\"},{\"t\":5,\"n\":\"Right - Run\"},{\"t\":5,\"n\":\"Forward - Walk\"},{\"t\":5,\"n\":\"Forward - Run\"},{\"t\":5,\"n\":\"Back - Walk\"},{\"t\":5,\"n\":\"Back - Run\"},{\"t\":5,\"n\":\"Rotate - Walk\"},{\"t\":5,\"n\":\"Unknown\"}]}]}]},{\"t\":3,\"n\":\"VNAM - Equipment Flags\"},{\"t\":8,\"p\":1,\"n\":\"Equip Slots\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"QNAM - Equip Slot\"}]},{\"t\":3,\"n\":\"UNES - Unarmed Equip Slot\"},{\"t\":8,\"n\":\"Phoneme Target Names\",\"c\":[{\"t\":2,\"n\":\"PHTN - Name\"}]},{\"t\":6,\"n\":\"FaceFX Phonemes\",\"c\":[{\"t\":6,\"n\":\"IY\",\"c\":[{\"t\":6,\"n\":\"PHWT - Phoneme Target Weight\",\"c\":[{\"t\":5,\"n\":\"Aah \\/ LipBigAah\"},{\"t\":5,\"n\":\"BigAah \\/ LipDST\"},{\"t\":5,\"n\":\"BMP \\/ LipEee\"},{\"t\":5,\"n\":\"ChJsh \\/ LipFV\"},{\"t\":5,\"n\":\"DST \\/ LipK\"},{\"t\":5,\"n\":\"Eee \\/ LipL\"},{\"t\":5,\"n\":\"Eh \\/ LipR\"},{\"t\":5,\"n\":\"FV \\/ LipTh\"},{\"t\":5,\"n\":\"I\"},{\"t\":5,\"n\":\"K\"},{\"t\":5,\"n\":\"N\"},{\"t\":5,\"n\":\"Oh\"},{\"t\":5,\"n\":\"OohQ\"},{\"t\":5,\"n\":\"R\"},{\"t\":5,\"n\":\"TH\"},{\"t\":5,\"n\":\"W\"}]}]},{\"t\":6,\"n\":\"IH\",\"c\":[{\"t\":6,\"n\":\"PHWT - Phoneme Target Weight\",\"c\":[{\"t\":5,\"n\":\"Aah \\/ LipBigAah\"},{\"t\":5,\"n\":\"BigAah \\/ LipDST\"},{\"t\":5,\"n\":\"BMP \\/ LipEee\"},{\"t\":5,\"n\":\"ChJsh \\/ LipFV\"},{\"t\":5,\"n\":\"DST \\/ LipK\"},{\"t\":5,\"n\":\"Eee \\/ LipL\"},{\"t\":5,\"n\":\"Eh \\/ LipR\"},{\"t\":5,\"n\":\"FV \\/ LipTh\"},{\"t\":5,\"n\":\"I\"},{\"t\":5,\"n\":\"K\"},{\"t\":5,\"n\":\"N\"},{\"t\":5,\"n\":\"Oh\"},{\"t\":5,\"n\":\"OohQ\"},{\"t\":5,\"n\":\"R\"},{\"t\":5,\"n\":\"TH\"},{\"t\":5,\"n\":\"W\"}]}]},{\"t\":6,\"n\":\"EH\",\"c\":[{\"t\":6,\"n\":\"PHWT - Phoneme Target Weight\",\"c\":[{\"t\":5,\"n\":\"Aah \\/ LipBigAah\"},{\"t\":5,\"n\":\"BigAah \\/ LipDST\"},{\"t\":5,\"n\":\"BMP \\/ LipEee\"},{\"t\":5,\"n\":\"ChJsh \\/ LipFV\"},{\"t\":5,\"n\":\"DST \\/ LipK\"},{\"t\":5,\"n\":\"Eee \\/ LipL\"},{\"t\":5,\"n\":\"Eh \\/ LipR\"},{\"t\":5,\"n\":\"FV \\/ LipTh\"},{\"t\":5,\"n\":\"I\"},{\"t\":5,\"n\":\"K\"},{\"t\":5,\"n\":\"N\"},{\"t\":5,\"n\":\"Oh\"},{\"t\":5,\"n\":\"OohQ\"},{\"t\":5,\"n\":\"R\"},{\"t\":5,\"n\":\"TH\"},{\"t\":5,\"n\":\"W\"}]}]},{\"t\":6,\"n\":\"EY\",\"c\":[{\"t\":6,\"n\":\"PHWT - Phoneme Target Weight\",\"c\":[{\"t\":5,\"n\":\"Aah \\/ LipBigAah\"},{\"t\":5,\"n\":\"BigAah \\/ LipDST\"},{\"t\":5,\"n\":\"BMP \\/ LipEee\"},{\"t\":5,\"n\":\"ChJsh \\/ LipFV\"},{\"t\":5,\"n\":\"DST \\/ LipK\"},{\"t\":5,\"n\":\"Eee \\/ LipL\"},{\"t\":5,\"n\":\"Eh \\/ LipR\"},{\"t\":5,\"n\":\"FV \\/ LipTh\"},{\"t\":5,\"n\":\"I\"},{\"t\":5,\"n\":\"K\"},{\"t\":5,\"n\":\"N\"},{\"t\":5,\"n\":\"Oh\"},{\"t\":5,\"n\":\"OohQ\"},{\"t\":5,\"n\":\"R\"},{\"t\":5,\"n\":\"TH\"},{\"t\":5,\"n\":\"W\"}]}]},{\"t\":6,\"n\":\"AE\",\"c\":[{\"t\":6,\"n\":\"PHWT - Phoneme Target Weight\",\"c\":[{\"t\":5,\"n\":\"Aah \\/ LipBigAah\"},{\"t\":5,\"n\":\"BigAah \\/ LipDST\"},{\"t\":5,\"n\":\"BMP \\/ LipEee\"},{\"t\":5,\"n\":\"ChJsh \\/ LipFV\"},{\"t\":5,\"n\":\"DST \\/ LipK\"},{\"t\":5,\"n\":\"Eee \\/ LipL\"},{\"t\":5,\"n\":\"Eh \\/ LipR\"},{\"t\":5,\"n\":\"FV \\/ LipTh\"},{\"t\":5,\"n\":\"I\"},{\"t\":5,\"n\":\"K\"},{\"t\":5,\"n\":\"N\"},{\"t\":5,\"n\":\"Oh\"},{\"t\":5,\"n\":\"OohQ\"},{\"t\":5,\"n\":\"R\"},{\"t\":5,\"n\":\"TH\"},{\"t\":5,\"n\":\"W\"}]}]},{\"t\":6,\"n\":\"AA\",\"c\":[{\"t\":6,\"n\":\"PHWT - Phoneme Target Weight\",\"c\":[{\"t\":5,\"n\":\"Aah \\/ LipBigAah\"},{\"t\":5,\"n\":\"BigAah \\/ LipDST\"},{\"t\":5,\"n\":\"BMP \\/ LipEee\"},{\"t\":5,\"n\":\"ChJsh \\/ LipFV\"},{\"t\":5,\"n\":\"DST \\/ LipK\"},{\"t\":5,\"n\":\"Eee \\/ LipL\"},{\"t\":5,\"n\":\"Eh \\/ LipR\"},{\"t\":5,\"n\":\"FV \\/ LipTh\"},{\"t\":5,\"n\":\"I\"},{\"t\":5,\"n\":\"K\"},{\"t\":5,\"n\":\"N\"},{\"t\":5,\"n\":\"Oh\"},{\"t\":5,\"n\":\"OohQ\"},{\"t\":5,\"n\":\"R\"},{\"t\":5,\"n\":\"TH\"},{\"t\":5,\"n\":\"W\"}]}]},{\"t\":6,\"n\":\"AW\",\"c\":[{\"t\":6,\"n\":\"PHWT - Phoneme Target Weight\",\"c\":[{\"t\":5,\"n\":\"Aah \\/ LipBigAah\"},{\"t\":5,\"n\":\"BigAah \\/ LipDST\"},{\"t\":5,\"n\":\"BMP \\/ LipEee\"},{\"t\":5,\"n\":\"ChJsh \\/ LipFV\"},{\"t\":5,\"n\":\"DST \\/ LipK\"},{\"t\":5,\"n\":\"Eee \\/ LipL\"},{\"t\":5,\"n\":\"Eh \\/ LipR\"},{\"t\":5,\"n\":\"FV \\/ LipTh\"},{\"t\":5,\"n\":\"I\"},{\"t\":5,\"n\":\"K\"},{\"t\":5,\"n\":\"N\"},{\"t\":5,\"n\":\"Oh\"},{\"t\":5,\"n\":\"OohQ\"},{\"t\":5,\"n\":\"R\"},{\"t\":5,\"n\":\"TH\"},{\"t\":5,\"n\":\"W\"}]}]},{\"t\":6,\"n\":\"AY\",\"c\":[{\"t\":6,\"n\":\"PHWT - Phoneme Target Weight\",\"c\":[{\"t\":5,\"n\":\"Aah \\/ LipBigAah\"},{\"t\":5,\"n\":\"BigAah \\/ LipDST\"},{\"t\":5,\"n\":\"BMP \\/ LipEee\"},{\"t\":5,\"n\":\"ChJsh \\/ LipFV\"},{\"t\":5,\"n\":\"DST \\/ LipK\"},{\"t\":5,\"n\":\"Eee \\/ LipL\"},{\"t\":5,\"n\":\"Eh \\/ LipR\"},{\"t\":5,\"n\":\"FV \\/ LipTh\"},{\"t\":5,\"n\":\"I\"},{\"t\":5,\"n\":\"K\"},{\"t\":5,\"n\":\"N\"},{\"t\":5,\"n\":\"Oh\"},{\"t\":5,\"n\":\"OohQ\"},{\"t\":5,\"n\":\"R\"},{\"t\":5,\"n\":\"TH\"},{\"t\":5,\"n\":\"W\"}]}]},{\"t\":6,\"n\":\"AH\",\"c\":[{\"t\":6,\"n\":\"PHWT - Phoneme Target Weight\",\"c\":[{\"t\":5,\"n\":\"Aah \\/ LipBigAah\"},{\"t\":5,\"n\":\"BigAah \\/ LipDST\"},{\"t\":5,\"n\":\"BMP \\/ LipEee\"},{\"t\":5,\"n\":\"ChJsh \\/ LipFV\"},{\"t\":5,\"n\":\"DST \\/ LipK\"},{\"t\":5,\"n\":\"Eee \\/ LipL\"},{\"t\":5,\"n\":\"Eh \\/ LipR\"},{\"t\":5,\"n\":\"FV \\/ LipTh\"},{\"t\":5,\"n\":\"I\"},{\"t\":5,\"n\":\"K\"},{\"t\":5,\"n\":\"N\"},{\"t\":5,\"n\":\"Oh\"},{\"t\":5,\"n\":\"OohQ\"},{\"t\":5,\"n\":\"R\"},{\"t\":5,\"n\":\"TH\"},{\"t\":5,\"n\":\"W\"}]}]},{\"t\":6,\"n\":\"AO\",\"c\":[{\"t\":6,\"n\":\"PHWT - Phoneme Target Weight\",\"c\":[{\"t\":5,\"n\":\"Aah \\/ LipBigAah\"},{\"t\":5,\"n\":\"BigAah \\/ LipDST\"},{\"t\":5,\"n\":\"BMP \\/ LipEee\"},{\"t\":5,\"n\":\"ChJsh \\/ LipFV\"},{\"t\":5,\"n\":\"DST \\/ LipK\"},{\"t\":5,\"n\":\"Eee \\/ LipL\"},{\"t\":5,\"n\":\"Eh \\/ LipR\"},{\"t\":5,\"n\":\"FV \\/ LipTh\"},{\"t\":5,\"n\":\"I\"},{\"t\":5,\"n\":\"K\"},{\"t\":5,\"n\":\"N\"},{\"t\":5,\"n\":\"Oh\"},{\"t\":5,\"n\":\"OohQ\"},{\"t\":5,\"n\":\"R\"},{\"t\":5,\"n\":\"TH\"},{\"t\":5,\"n\":\"W\"}]}]},{\"t\":6,\"n\":\"OY\",\"c\":[{\"t\":6,\"n\":\"PHWT - Phoneme Target Weight\",\"c\":[{\"t\":5,\"n\":\"Aah \\/ LipBigAah\"},{\"t\":5,\"n\":\"BigAah \\/ LipDST\"},{\"t\":5,\"n\":\"BMP \\/ LipEee\"},{\"t\":5,\"n\":\"ChJsh \\/ LipFV\"},{\"t\":5,\"n\":\"DST \\/ LipK\"},{\"t\":5,\"n\":\"Eee \\/ LipL\"},{\"t\":5,\"n\":\"Eh \\/ LipR\"},{\"t\":5,\"n\":\"FV \\/ LipTh\"},{\"t\":5,\"n\":\"I\"},{\"t\":5,\"n\":\"K\"},{\"t\":5,\"n\":\"N\"},{\"t\":5,\"n\":\"Oh\"},{\"t\":5,\"n\":\"OohQ\"},{\"t\":5,\"n\":\"R\"},{\"t\":5,\"n\":\"TH\"},{\"t\":5,\"n\":\"W\"}]}]},{\"t\":6,\"n\":\"OW\",\"c\":[{\"t\":6,\"n\":\"PHWT - Phoneme Target Weight\",\"c\":[{\"t\":5,\"n\":\"Aah \\/ LipBigAah\"},{\"t\":5,\"n\":\"BigAah \\/ LipDST\"},{\"t\":5,\"n\":\"BMP \\/ LipEee\"},{\"t\":5,\"n\":\"ChJsh \\/ LipFV\"},{\"t\":5,\"n\":\"DST \\/ LipK\"},{\"t\":5,\"n\":\"Eee \\/ LipL\"},{\"t\":5,\"n\":\"Eh \\/ LipR\"},{\"t\":5,\"n\":\"FV \\/ LipTh\"},{\"t\":5,\"n\":\"I\"},{\"t\":5,\"n\":\"K\"},{\"t\":5,\"n\":\"N\"},{\"t\":5,\"n\":\"Oh\"},{\"t\":5,\"n\":\"OohQ\"},{\"t\":5,\"n\":\"R\"},{\"t\":5,\"n\":\"TH\"},{\"t\":5,\"n\":\"W\"}]}]},{\"t\":6,\"n\":\"UH\",\"c\":[{\"t\":6,\"n\":\"PHWT - Phoneme Target Weight\",\"c\":[{\"t\":5,\"n\":\"Aah \\/ LipBigAah\"},{\"t\":5,\"n\":\"BigAah \\/ LipDST\"},{\"t\":5,\"n\":\"BMP \\/ LipEee\"},{\"t\":5,\"n\":\"ChJsh \\/ LipFV\"},{\"t\":5,\"n\":\"DST \\/ LipK\"},{\"t\":5,\"n\":\"Eee \\/ LipL\"},{\"t\":5,\"n\":\"Eh \\/ LipR\"},{\"t\":5,\"n\":\"FV \\/ LipTh\"},{\"t\":5,\"n\":\"I\"},{\"t\":5,\"n\":\"K\"},{\"t\":5,\"n\":\"N\"},{\"t\":5,\"n\":\"Oh\"},{\"t\":5,\"n\":\"OohQ\"},{\"t\":5,\"n\":\"R\"},{\"t\":5,\"n\":\"TH\"},{\"t\":5,\"n\":\"W\"}]}]},{\"t\":6,\"n\":\"UW\",\"c\":[{\"t\":6,\"n\":\"PHWT - Phoneme Target Weight\",\"c\":[{\"t\":5,\"n\":\"Aah \\/ LipBigAah\"},{\"t\":5,\"n\":\"BigAah \\/ LipDST\"},{\"t\":5,\"n\":\"BMP \\/ LipEee\"},{\"t\":5,\"n\":\"ChJsh \\/ LipFV\"},{\"t\":5,\"n\":\"DST \\/ LipK\"},{\"t\":5,\"n\":\"Eee \\/ LipL\"},{\"t\":5,\"n\":\"Eh \\/ LipR\"},{\"t\":5,\"n\":\"FV \\/ LipTh\"},{\"t\":5,\"n\":\"I\"},{\"t\":5,\"n\":\"K\"},{\"t\":5,\"n\":\"N\"},{\"t\":5,\"n\":\"Oh\"},{\"t\":5,\"n\":\"OohQ\"},{\"t\":5,\"n\":\"R\"},{\"t\":5,\"n\":\"TH\"},{\"t\":5,\"n\":\"W\"}]}]},{\"t\":6,\"n\":\"ER\",\"c\":[{\"t\":6,\"n\":\"PHWT - Phoneme Target Weight\",\"c\":[{\"t\":5,\"n\":\"Aah \\/ LipBigAah\"},{\"t\":5,\"n\":\"BigAah \\/ LipDST\"},{\"t\":5,\"n\":\"BMP \\/ LipEee\"},{\"t\":5,\"n\":\"ChJsh \\/ LipFV\"},{\"t\":5,\"n\":\"DST \\/ LipK\"},{\"t\":5,\"n\":\"Eee \\/ LipL\"},{\"t\":5,\"n\":\"Eh \\/ LipR\"},{\"t\":5,\"n\":\"FV \\/ LipTh\"},{\"t\":5,\"n\":\"I\"},{\"t\":5,\"n\":\"K\"},{\"t\":5,\"n\":\"N\"},{\"t\":5,\"n\":\"Oh\"},{\"t\":5,\"n\":\"OohQ\"},{\"t\":5,\"n\":\"R\"},{\"t\":5,\"n\":\"TH\"},{\"t\":5,\"n\":\"W\"}]}]},{\"t\":6,\"n\":\"AX\",\"c\":[{\"t\":6,\"n\":\"PHWT - Phoneme Target Weight\",\"c\":[{\"t\":5,\"n\":\"Aah \\/ LipBigAah\"},{\"t\":5,\"n\":\"BigAah \\/ LipDST\"},{\"t\":5,\"n\":\"BMP \\/ LipEee\"},{\"t\":5,\"n\":\"ChJsh \\/ LipFV\"},{\"t\":5,\"n\":\"DST \\/ LipK\"},{\"t\":5,\"n\":\"Eee \\/ LipL\"},{\"t\":5,\"n\":\"Eh \\/ LipR\"},{\"t\":5,\"n\":\"FV \\/ LipTh\"},{\"t\":5,\"n\":\"I\"},{\"t\":5,\"n\":\"K\"},{\"t\":5,\"n\":\"N\"},{\"t\":5,\"n\":\"Oh\"},{\"t\":5,\"n\":\"OohQ\"},{\"t\":5,\"n\":\"R\"},{\"t\":5,\"n\":\"TH\"},{\"t\":5,\"n\":\"W\"}]}]},{\"t\":6,\"n\":\"S\",\"c\":[{\"t\":6,\"n\":\"PHWT - Phoneme Target Weight\",\"c\":[{\"t\":5,\"n\":\"Aah \\/ LipBigAah\"},{\"t\":5,\"n\":\"BigAah \\/ LipDST\"},{\"t\":5,\"n\":\"BMP \\/ LipEee\"},{\"t\":5,\"n\":\"ChJsh \\/ LipFV\"},{\"t\":5,\"n\":\"DST \\/ LipK\"},{\"t\":5,\"n\":\"Eee \\/ LipL\"},{\"t\":5,\"n\":\"Eh \\/ LipR\"},{\"t\":5,\"n\":\"FV \\/ LipTh\"},{\"t\":5,\"n\":\"I\"},{\"t\":5,\"n\":\"K\"},{\"t\":5,\"n\":\"N\"},{\"t\":5,\"n\":\"Oh\"},{\"t\":5,\"n\":\"OohQ\"},{\"t\":5,\"n\":\"R\"},{\"t\":5,\"n\":\"TH\"},{\"t\":5,\"n\":\"W\"}]}]},{\"t\":6,\"n\":\"SH\",\"c\":[{\"t\":6,\"n\":\"PHWT - Phoneme Target Weight\",\"c\":[{\"t\":5,\"n\":\"Aah \\/ LipBigAah\"},{\"t\":5,\"n\":\"BigAah \\/ LipDST\"},{\"t\":5,\"n\":\"BMP \\/ LipEee\"},{\"t\":5,\"n\":\"ChJsh \\/ LipFV\"},{\"t\":5,\"n\":\"DST \\/ LipK\"},{\"t\":5,\"n\":\"Eee \\/ LipL\"},{\"t\":5,\"n\":\"Eh \\/ LipR\"},{\"t\":5,\"n\":\"FV \\/ LipTh\"},{\"t\":5,\"n\":\"I\"},{\"t\":5,\"n\":\"K\"},{\"t\":5,\"n\":\"N\"},{\"t\":5,\"n\":\"Oh\"},{\"t\":5,\"n\":\"OohQ\"},{\"t\":5,\"n\":\"R\"},{\"t\":5,\"n\":\"TH\"},{\"t\":5,\"n\":\"W\"}]}]},{\"t\":6,\"n\":\"Z\",\"c\":[{\"t\":6,\"n\":\"PHWT - Phoneme Target Weight\",\"c\":[{\"t\":5,\"n\":\"Aah \\/ LipBigAah\"},{\"t\":5,\"n\":\"BigAah \\/ LipDST\"},{\"t\":5,\"n\":\"BMP \\/ LipEee\"},{\"t\":5,\"n\":\"ChJsh \\/ LipFV\"},{\"t\":5,\"n\":\"DST \\/ LipK\"},{\"t\":5,\"n\":\"Eee \\/ LipL\"},{\"t\":5,\"n\":\"Eh \\/ LipR\"},{\"t\":5,\"n\":\"FV \\/ LipTh\"},{\"t\":5,\"n\":\"I\"},{\"t\":5,\"n\":\"K\"},{\"t\":5,\"n\":\"N\"},{\"t\":5,\"n\":\"Oh\"},{\"t\":5,\"n\":\"OohQ\"},{\"t\":5,\"n\":\"R\"},{\"t\":5,\"n\":\"TH\"},{\"t\":5,\"n\":\"W\"}]}]},{\"t\":6,\"n\":\"ZH\",\"c\":[{\"t\":6,\"n\":\"PHWT - Phoneme Target Weight\",\"c\":[{\"t\":5,\"n\":\"Aah \\/ LipBigAah\"},{\"t\":5,\"n\":\"BigAah \\/ LipDST\"},{\"t\":5,\"n\":\"BMP \\/ LipEee\"},{\"t\":5,\"n\":\"ChJsh \\/ LipFV\"},{\"t\":5,\"n\":\"DST \\/ LipK\"},{\"t\":5,\"n\":\"Eee \\/ LipL\"},{\"t\":5,\"n\":\"Eh \\/ LipR\"},{\"t\":5,\"n\":\"FV \\/ LipTh\"},{\"t\":5,\"n\":\"I\"},{\"t\":5,\"n\":\"K\"},{\"t\":5,\"n\":\"N\"},{\"t\":5,\"n\":\"Oh\"},{\"t\":5,\"n\":\"OohQ\"},{\"t\":5,\"n\":\"R\"},{\"t\":5,\"n\":\"TH\"},{\"t\":5,\"n\":\"W\"}]}]},{\"t\":6,\"n\":\"F\",\"c\":[{\"t\":6,\"n\":\"PHWT - Phoneme Target Weight\",\"c\":[{\"t\":5,\"n\":\"Aah \\/ LipBigAah\"},{\"t\":5,\"n\":\"BigAah \\/ LipDST\"},{\"t\":5,\"n\":\"BMP \\/ LipEee\"},{\"t\":5,\"n\":\"ChJsh \\/ LipFV\"},{\"t\":5,\"n\":\"DST \\/ LipK\"},{\"t\":5,\"n\":\"Eee \\/ LipL\"},{\"t\":5,\"n\":\"Eh \\/ LipR\"},{\"t\":5,\"n\":\"FV \\/ LipTh\"},{\"t\":5,\"n\":\"I\"},{\"t\":5,\"n\":\"K\"},{\"t\":5,\"n\":\"N\"},{\"t\":5,\"n\":\"Oh\"},{\"t\":5,\"n\":\"OohQ\"},{\"t\":5,\"n\":\"R\"},{\"t\":5,\"n\":\"TH\"},{\"t\":5,\"n\":\"W\"}]}]},{\"t\":6,\"n\":\"TH\",\"c\":[{\"t\":6,\"n\":\"PHWT - Phoneme Target Weight\",\"c\":[{\"t\":5,\"n\":\"Aah \\/ LipBigAah\"},{\"t\":5,\"n\":\"BigAah \\/ LipDST\"},{\"t\":5,\"n\":\"BMP \\/ LipEee\"},{\"t\":5,\"n\":\"ChJsh \\/ LipFV\"},{\"t\":5,\"n\":\"DST \\/ LipK\"},{\"t\":5,\"n\":\"Eee \\/ LipL\"},{\"t\":5,\"n\":\"Eh \\/ LipR\"},{\"t\":5,\"n\":\"FV \\/ LipTh\"},{\"t\":5,\"n\":\"I\"},{\"t\":5,\"n\":\"K\"},{\"t\":5,\"n\":\"N\"},{\"t\":5,\"n\":\"Oh\"},{\"t\":5,\"n\":\"OohQ\"},{\"t\":5,\"n\":\"R\"},{\"t\":5,\"n\":\"TH\"},{\"t\":5,\"n\":\"W\"}]}]},{\"t\":6,\"n\":\"V\",\"c\":[{\"t\":6,\"n\":\"PHWT - Phoneme Target Weight\",\"c\":[{\"t\":5,\"n\":\"Aah \\/ LipBigAah\"},{\"t\":5,\"n\":\"BigAah \\/ LipDST\"},{\"t\":5,\"n\":\"BMP \\/ LipEee\"},{\"t\":5,\"n\":\"ChJsh \\/ LipFV\"},{\"t\":5,\"n\":\"DST \\/ LipK\"},{\"t\":5,\"n\":\"Eee \\/ LipL\"},{\"t\":5,\"n\":\"Eh \\/ LipR\"},{\"t\":5,\"n\":\"FV \\/ LipTh\"},{\"t\":5,\"n\":\"I\"},{\"t\":5,\"n\":\"K\"},{\"t\":5,\"n\":\"N\"},{\"t\":5,\"n\":\"Oh\"},{\"t\":5,\"n\":\"OohQ\"},{\"t\":5,\"n\":\"R\"},{\"t\":5,\"n\":\"TH\"},{\"t\":5,\"n\":\"W\"}]}]},{\"t\":6,\"n\":\"DH\",\"c\":[{\"t\":6,\"n\":\"PHWT - Phoneme Target Weight\",\"c\":[{\"t\":5,\"n\":\"Aah \\/ LipBigAah\"},{\"t\":5,\"n\":\"BigAah \\/ LipDST\"},{\"t\":5,\"n\":\"BMP \\/ LipEee\"},{\"t\":5,\"n\":\"ChJsh \\/ LipFV\"},{\"t\":5,\"n\":\"DST \\/ LipK\"},{\"t\":5,\"n\":\"Eee \\/ LipL\"},{\"t\":5,\"n\":\"Eh \\/ LipR\"},{\"t\":5,\"n\":\"FV \\/ LipTh\"},{\"t\":5,\"n\":\"I\"},{\"t\":5,\"n\":\"K\"},{\"t\":5,\"n\":\"N\"},{\"t\":5,\"n\":\"Oh\"},{\"t\":5,\"n\":\"OohQ\"},{\"t\":5,\"n\":\"R\"},{\"t\":5,\"n\":\"TH\"},{\"t\":5,\"n\":\"W\"}]}]},{\"t\":6,\"n\":\"M\",\"c\":[{\"t\":6,\"n\":\"PHWT - Phoneme Target Weight\",\"c\":[{\"t\":5,\"n\":\"Aah \\/ LipBigAah\"},{\"t\":5,\"n\":\"BigAah \\/ LipDST\"},{\"t\":5,\"n\":\"BMP \\/ LipEee\"},{\"t\":5,\"n\":\"ChJsh \\/ LipFV\"},{\"t\":5,\"n\":\"DST \\/ LipK\"},{\"t\":5,\"n\":\"Eee \\/ LipL\"},{\"t\":5,\"n\":\"Eh \\/ LipR\"},{\"t\":5,\"n\":\"FV \\/ LipTh\"},{\"t\":5,\"n\":\"I\"},{\"t\":5,\"n\":\"K\"},{\"t\":5,\"n\":\"N\"},{\"t\":5,\"n\":\"Oh\"},{\"t\":5,\"n\":\"OohQ\"},{\"t\":5,\"n\":\"R\"},{\"t\":5,\"n\":\"TH\"},{\"t\":5,\"n\":\"W\"}]}]},{\"t\":6,\"n\":\"N\",\"c\":[{\"t\":6,\"n\":\"PHWT - Phoneme Target Weight\",\"c\":[{\"t\":5,\"n\":\"Aah \\/ LipBigAah\"},{\"t\":5,\"n\":\"BigAah \\/ LipDST\"},{\"t\":5,\"n\":\"BMP \\/ LipEee\"},{\"t\":5,\"n\":\"ChJsh \\/ LipFV\"},{\"t\":5,\"n\":\"DST \\/ LipK\"},{\"t\":5,\"n\":\"Eee \\/ LipL\"},{\"t\":5,\"n\":\"Eh \\/ LipR\"},{\"t\":5,\"n\":\"FV \\/ LipTh\"},{\"t\":5,\"n\":\"I\"},{\"t\":5,\"n\":\"K\"},{\"t\":5,\"n\":\"N\"},{\"t\":5,\"n\":\"Oh\"},{\"t\":5,\"n\":\"OohQ\"},{\"t\":5,\"n\":\"R\"},{\"t\":5,\"n\":\"TH\"},{\"t\":5,\"n\":\"W\"}]}]},{\"t\":6,\"n\":\"NG\",\"c\":[{\"t\":6,\"n\":\"PHWT - Phoneme Target Weight\",\"c\":[{\"t\":5,\"n\":\"Aah \\/ LipBigAah\"},{\"t\":5,\"n\":\"BigAah \\/ LipDST\"},{\"t\":5,\"n\":\"BMP \\/ LipEee\"},{\"t\":5,\"n\":\"ChJsh \\/ LipFV\"},{\"t\":5,\"n\":\"DST \\/ LipK\"},{\"t\":5,\"n\":\"Eee \\/ LipL\"},{\"t\":5,\"n\":\"Eh \\/ LipR\"},{\"t\":5,\"n\":\"FV \\/ LipTh\"},{\"t\":5,\"n\":\"I\"},{\"t\":5,\"n\":\"K\"},{\"t\":5,\"n\":\"N\"},{\"t\":5,\"n\":\"Oh\"},{\"t\":5,\"n\":\"OohQ\"},{\"t\":5,\"n\":\"R\"},{\"t\":5,\"n\":\"TH\"},{\"t\":5,\"n\":\"W\"}]}]},{\"t\":6,\"n\":\"L\",\"c\":[{\"t\":6,\"n\":\"PHWT - Phoneme Target Weight\",\"c\":[{\"t\":5,\"n\":\"Aah \\/ LipBigAah\"},{\"t\":5,\"n\":\"BigAah \\/ LipDST\"},{\"t\":5,\"n\":\"BMP \\/ LipEee\"},{\"t\":5,\"n\":\"ChJsh \\/ LipFV\"},{\"t\":5,\"n\":\"DST \\/ LipK\"},{\"t\":5,\"n\":\"Eee \\/ LipL\"},{\"t\":5,\"n\":\"Eh \\/ LipR\"},{\"t\":5,\"n\":\"FV \\/ LipTh\"},{\"t\":5,\"n\":\"I\"},{\"t\":5,\"n\":\"K\"},{\"t\":5,\"n\":\"N\"},{\"t\":5,\"n\":\"Oh\"},{\"t\":5,\"n\":\"OohQ\"},{\"t\":5,\"n\":\"R\"},{\"t\":5,\"n\":\"TH\"},{\"t\":5,\"n\":\"W\"}]}]},{\"t\":6,\"n\":\"R\",\"c\":[{\"t\":6,\"n\":\"PHWT - Phoneme Target Weight\",\"c\":[{\"t\":5,\"n\":\"Aah \\/ LipBigAah\"},{\"t\":5,\"n\":\"BigAah \\/ LipDST\"},{\"t\":5,\"n\":\"BMP \\/ LipEee\"},{\"t\":5,\"n\":\"ChJsh \\/ LipFV\"},{\"t\":5,\"n\":\"DST \\/ LipK\"},{\"t\":5,\"n\":\"Eee \\/ LipL\"},{\"t\":5,\"n\":\"Eh \\/ LipR\"},{\"t\":5,\"n\":\"FV \\/ LipTh\"},{\"t\":5,\"n\":\"I\"},{\"t\":5,\"n\":\"K\"},{\"t\":5,\"n\":\"N\"},{\"t\":5,\"n\":\"Oh\"},{\"t\":5,\"n\":\"OohQ\"},{\"t\":5,\"n\":\"R\"},{\"t\":5,\"n\":\"TH\"},{\"t\":5,\"n\":\"W\"}]}]},{\"t\":6,\"n\":\"W\",\"c\":[{\"t\":6,\"n\":\"PHWT - Phoneme Target Weight\",\"c\":[{\"t\":5,\"n\":\"Aah \\/ LipBigAah\"},{\"t\":5,\"n\":\"BigAah \\/ LipDST\"},{\"t\":5,\"n\":\"BMP \\/ LipEee\"},{\"t\":5,\"n\":\"ChJsh \\/ LipFV\"},{\"t\":5,\"n\":\"DST \\/ LipK\"},{\"t\":5,\"n\":\"Eee \\/ LipL\"},{\"t\":5,\"n\":\"Eh \\/ LipR\"},{\"t\":5,\"n\":\"FV \\/ LipTh\"},{\"t\":5,\"n\":\"I\"},{\"t\":5,\"n\":\"K\"},{\"t\":5,\"n\":\"N\"},{\"t\":5,\"n\":\"Oh\"},{\"t\":5,\"n\":\"OohQ\"},{\"t\":5,\"n\":\"R\"},{\"t\":5,\"n\":\"TH\"},{\"t\":5,\"n\":\"W\"}]}]},{\"t\":6,\"n\":\"Y\",\"c\":[{\"t\":6,\"n\":\"PHWT - Phoneme Target Weight\",\"c\":[{\"t\":5,\"n\":\"Aah \\/ LipBigAah\"},{\"t\":5,\"n\":\"BigAah \\/ LipDST\"},{\"t\":5,\"n\":\"BMP \\/ LipEee\"},{\"t\":5,\"n\":\"ChJsh \\/ LipFV\"},{\"t\":5,\"n\":\"DST \\/ LipK\"},{\"t\":5,\"n\":\"Eee \\/ LipL\"},{\"t\":5,\"n\":\"Eh \\/ LipR\"},{\"t\":5,\"n\":\"FV \\/ LipTh\"},{\"t\":5,\"n\":\"I\"},{\"t\":5,\"n\":\"K\"},{\"t\":5,\"n\":\"N\"},{\"t\":5,\"n\":\"Oh\"},{\"t\":5,\"n\":\"OohQ\"},{\"t\":5,\"n\":\"R\"},{\"t\":5,\"n\":\"TH\"},{\"t\":5,\"n\":\"W\"}]}]},{\"t\":6,\"n\":\"HH\",\"c\":[{\"t\":6,\"n\":\"PHWT - Phoneme Target Weight\",\"c\":[{\"t\":5,\"n\":\"Aah \\/ LipBigAah\"},{\"t\":5,\"n\":\"BigAah \\/ LipDST\"},{\"t\":5,\"n\":\"BMP \\/ LipEee\"},{\"t\":5,\"n\":\"ChJsh \\/ LipFV\"},{\"t\":5,\"n\":\"DST \\/ LipK\"},{\"t\":5,\"n\":\"Eee \\/ LipL\"},{\"t\":5,\"n\":\"Eh \\/ LipR\"},{\"t\":5,\"n\":\"FV \\/ LipTh\"},{\"t\":5,\"n\":\"I\"},{\"t\":5,\"n\":\"K\"},{\"t\":5,\"n\":\"N\"},{\"t\":5,\"n\":\"Oh\"},{\"t\":5,\"n\":\"OohQ\"},{\"t\":5,\"n\":\"R\"},{\"t\":5,\"n\":\"TH\"},{\"t\":5,\"n\":\"W\"}]}]},{\"t\":6,\"n\":\"B\",\"c\":[{\"t\":6,\"n\":\"PHWT - Phoneme Target Weight\",\"c\":[{\"t\":5,\"n\":\"Aah \\/ LipBigAah\"},{\"t\":5,\"n\":\"BigAah \\/ LipDST\"},{\"t\":5,\"n\":\"BMP \\/ LipEee\"},{\"t\":5,\"n\":\"ChJsh \\/ LipFV\"},{\"t\":5,\"n\":\"DST \\/ LipK\"},{\"t\":5,\"n\":\"Eee \\/ LipL\"},{\"t\":5,\"n\":\"Eh \\/ LipR\"},{\"t\":5,\"n\":\"FV \\/ LipTh\"},{\"t\":5,\"n\":\"I\"},{\"t\":5,\"n\":\"K\"},{\"t\":5,\"n\":\"N\"},{\"t\":5,\"n\":\"Oh\"},{\"t\":5,\"n\":\"OohQ\"},{\"t\":5,\"n\":\"R\"},{\"t\":5,\"n\":\"TH\"},{\"t\":5,\"n\":\"W\"}]}]},{\"t\":6,\"n\":\"D\",\"c\":[{\"t\":6,\"n\":\"PHWT - Phoneme Target Weight\",\"c\":[{\"t\":5,\"n\":\"Aah \\/ LipBigAah\"},{\"t\":5,\"n\":\"BigAah \\/ LipDST\"},{\"t\":5,\"n\":\"BMP \\/ LipEee\"},{\"t\":5,\"n\":\"ChJsh \\/ LipFV\"},{\"t\":5,\"n\":\"DST \\/ LipK\"},{\"t\":5,\"n\":\"Eee \\/ LipL\"},{\"t\":5,\"n\":\"Eh \\/ LipR\"},{\"t\":5,\"n\":\"FV \\/ LipTh\"},{\"t\":5,\"n\":\"I\"},{\"t\":5,\"n\":\"K\"},{\"t\":5,\"n\":\"N\"},{\"t\":5,\"n\":\"Oh\"},{\"t\":5,\"n\":\"OohQ\"},{\"t\":5,\"n\":\"R\"},{\"t\":5,\"n\":\"TH\"},{\"t\":5,\"n\":\"W\"}]}]},{\"t\":6,\"n\":\"JH\",\"c\":[{\"t\":6,\"n\":\"PHWT - Phoneme Target Weight\",\"c\":[{\"t\":5,\"n\":\"Aah \\/ LipBigAah\"},{\"t\":5,\"n\":\"BigAah \\/ LipDST\"},{\"t\":5,\"n\":\"BMP \\/ LipEee\"},{\"t\":5,\"n\":\"ChJsh \\/ LipFV\"},{\"t\":5,\"n\":\"DST \\/ LipK\"},{\"t\":5,\"n\":\"Eee \\/ LipL\"},{\"t\":5,\"n\":\"Eh \\/ LipR\"},{\"t\":5,\"n\":\"FV \\/ LipTh\"},{\"t\":5,\"n\":\"I\"},{\"t\":5,\"n\":\"K\"},{\"t\":5,\"n\":\"N\"},{\"t\":5,\"n\":\"Oh\"},{\"t\":5,\"n\":\"OohQ\"},{\"t\":5,\"n\":\"R\"},{\"t\":5,\"n\":\"TH\"},{\"t\":5,\"n\":\"W\"}]}]},{\"t\":6,\"n\":\"G\",\"c\":[{\"t\":6,\"n\":\"PHWT - Phoneme Target Weight\",\"c\":[{\"t\":5,\"n\":\"Aah \\/ LipBigAah\"},{\"t\":5,\"n\":\"BigAah \\/ LipDST\"},{\"t\":5,\"n\":\"BMP \\/ LipEee\"},{\"t\":5,\"n\":\"ChJsh \\/ LipFV\"},{\"t\":5,\"n\":\"DST \\/ LipK\"},{\"t\":5,\"n\":\"Eee \\/ LipL\"},{\"t\":5,\"n\":\"Eh \\/ LipR\"},{\"t\":5,\"n\":\"FV \\/ LipTh\"},{\"t\":5,\"n\":\"I\"},{\"t\":5,\"n\":\"K\"},{\"t\":5,\"n\":\"N\"},{\"t\":5,\"n\":\"Oh\"},{\"t\":5,\"n\":\"OohQ\"},{\"t\":5,\"n\":\"R\"},{\"t\":5,\"n\":\"TH\"},{\"t\":5,\"n\":\"W\"}]}]},{\"t\":6,\"n\":\"P\",\"c\":[{\"t\":6,\"n\":\"PHWT - Phoneme Target Weight\",\"c\":[{\"t\":5,\"n\":\"Aah \\/ LipBigAah\"},{\"t\":5,\"n\":\"BigAah \\/ LipDST\"},{\"t\":5,\"n\":\"BMP \\/ LipEee\"},{\"t\":5,\"n\":\"ChJsh \\/ LipFV\"},{\"t\":5,\"n\":\"DST \\/ LipK\"},{\"t\":5,\"n\":\"Eee \\/ LipL\"},{\"t\":5,\"n\":\"Eh \\/ LipR\"},{\"t\":5,\"n\":\"FV \\/ LipTh\"},{\"t\":5,\"n\":\"I\"},{\"t\":5,\"n\":\"K\"},{\"t\":5,\"n\":\"N\"},{\"t\":5,\"n\":\"Oh\"},{\"t\":5,\"n\":\"OohQ\"},{\"t\":5,\"n\":\"R\"},{\"t\":5,\"n\":\"TH\"},{\"t\":5,\"n\":\"W\"}]}]},{\"t\":6,\"n\":\"T\",\"c\":[{\"t\":6,\"n\":\"PHWT - Phoneme Target Weight\",\"c\":[{\"t\":5,\"n\":\"Aah \\/ LipBigAah\"},{\"t\":5,\"n\":\"BigAah \\/ LipDST\"},{\"t\":5,\"n\":\"BMP \\/ LipEee\"},{\"t\":5,\"n\":\"ChJsh \\/ LipFV\"},{\"t\":5,\"n\":\"DST \\/ LipK\"},{\"t\":5,\"n\":\"Eee \\/ LipL\"},{\"t\":5,\"n\":\"Eh \\/ LipR\"},{\"t\":5,\"n\":\"FV \\/ LipTh\"},{\"t\":5,\"n\":\"I\"},{\"t\":5,\"n\":\"K\"},{\"t\":5,\"n\":\"N\"},{\"t\":5,\"n\":\"Oh\"},{\"t\":5,\"n\":\"OohQ\"},{\"t\":5,\"n\":\"R\"},{\"t\":5,\"n\":\"TH\"},{\"t\":5,\"n\":\"W\"}]}]},{\"t\":6,\"n\":\"K\",\"c\":[{\"t\":6,\"n\":\"PHWT - Phoneme Target Weight\",\"c\":[{\"t\":5,\"n\":\"Aah \\/ LipBigAah\"},{\"t\":5,\"n\":\"BigAah \\/ LipDST\"},{\"t\":5,\"n\":\"BMP \\/ LipEee\"},{\"t\":5,\"n\":\"ChJsh \\/ LipFV\"},{\"t\":5,\"n\":\"DST \\/ LipK\"},{\"t\":5,\"n\":\"Eee \\/ LipL\"},{\"t\":5,\"n\":\"Eh \\/ LipR\"},{\"t\":5,\"n\":\"FV \\/ LipTh\"},{\"t\":5,\"n\":\"I\"},{\"t\":5,\"n\":\"K\"},{\"t\":5,\"n\":\"N\"},{\"t\":5,\"n\":\"Oh\"},{\"t\":5,\"n\":\"OohQ\"},{\"t\":5,\"n\":\"R\"},{\"t\":5,\"n\":\"TH\"},{\"t\":5,\"n\":\"W\"}]}]},{\"t\":6,\"n\":\"CH\",\"c\":[{\"t\":6,\"n\":\"PHWT - Phoneme Target Weight\",\"c\":[{\"t\":5,\"n\":\"Aah \\/ LipBigAah\"},{\"t\":5,\"n\":\"BigAah \\/ LipDST\"},{\"t\":5,\"n\":\"BMP \\/ LipEee\"},{\"t\":5,\"n\":\"ChJsh \\/ LipFV\"},{\"t\":5,\"n\":\"DST \\/ LipK\"},{\"t\":5,\"n\":\"Eee \\/ LipL\"},{\"t\":5,\"n\":\"Eh \\/ LipR\"},{\"t\":5,\"n\":\"FV \\/ LipTh\"},{\"t\":5,\"n\":\"I\"},{\"t\":5,\"n\":\"K\"},{\"t\":5,\"n\":\"N\"},{\"t\":5,\"n\":\"Oh\"},{\"t\":5,\"n\":\"OohQ\"},{\"t\":5,\"n\":\"R\"},{\"t\":5,\"n\":\"TH\"},{\"t\":5,\"n\":\"W\"}]}]},{\"t\":6,\"n\":\"SIL\",\"c\":[{\"t\":6,\"n\":\"PHWT - Phoneme Target Weight\",\"c\":[{\"t\":5,\"n\":\"Aah \\/ LipBigAah\"},{\"t\":5,\"n\":\"BigAah \\/ LipDST\"},{\"t\":5,\"n\":\"BMP \\/ LipEee\"},{\"t\":5,\"n\":\"ChJsh \\/ LipFV\"},{\"t\":5,\"n\":\"DST \\/ LipK\"},{\"t\":5,\"n\":\"Eee \\/ LipL\"},{\"t\":5,\"n\":\"Eh \\/ LipR\"},{\"t\":5,\"n\":\"FV \\/ LipTh\"},{\"t\":5,\"n\":\"I\"},{\"t\":5,\"n\":\"K\"},{\"t\":5,\"n\":\"N\"},{\"t\":5,\"n\":\"Oh\"},{\"t\":5,\"n\":\"OohQ\"},{\"t\":5,\"n\":\"R\"},{\"t\":5,\"n\":\"TH\"},{\"t\":5,\"n\":\"W\"}]}]},{\"t\":6,\"n\":\"SHOTSIL\",\"c\":[{\"t\":6,\"n\":\"PHWT - Phoneme Target Weight\",\"c\":[{\"t\":5,\"n\":\"Aah \\/ LipBigAah\"},{\"t\":5,\"n\":\"BigAah \\/ LipDST\"},{\"t\":5,\"n\":\"BMP \\/ LipEee\"},{\"t\":5,\"n\":\"ChJsh \\/ LipFV\"},{\"t\":5,\"n\":\"DST \\/ LipK\"},{\"t\":5,\"n\":\"Eee \\/ LipL\"},{\"t\":5,\"n\":\"Eh \\/ LipR\"},{\"t\":5,\"n\":\"FV \\/ LipTh\"},{\"t\":5,\"n\":\"I\"},{\"t\":5,\"n\":\"K\"},{\"t\":5,\"n\":\"N\"},{\"t\":5,\"n\":\"Oh\"},{\"t\":5,\"n\":\"OohQ\"},{\"t\":5,\"n\":\"R\"},{\"t\":5,\"n\":\"TH\"},{\"t\":5,\"n\":\"W\"}]}]},{\"t\":6,\"n\":\"FLAP\",\"c\":[{\"t\":6,\"n\":\"PHWT - Phoneme Target Weight\",\"c\":[{\"t\":5,\"n\":\"Aah \\/ LipBigAah\"},{\"t\":5,\"n\":\"BigAah \\/ LipDST\"},{\"t\":5,\"n\":\"BMP \\/ LipEee\"},{\"t\":5,\"n\":\"ChJsh \\/ LipFV\"},{\"t\":5,\"n\":\"DST \\/ LipK\"},{\"t\":5,\"n\":\"Eee \\/ LipL\"},{\"t\":5,\"n\":\"Eh \\/ LipR\"},{\"t\":5,\"n\":\"FV \\/ LipTh\"},{\"t\":5,\"n\":\"I\"},{\"t\":5,\"n\":\"K\"},{\"t\":5,\"n\":\"N\"},{\"t\":5,\"n\":\"Oh\"},{\"t\":5,\"n\":\"OohQ\"},{\"t\":5,\"n\":\"R\"},{\"t\":5,\"n\":\"TH\"},{\"t\":5,\"n\":\"W\"}]}]}]},{\"t\":3,\"n\":\"WKMV - Base Movement Default - Walk\"},{\"t\":3,\"n\":\"RNMV - Base Movement Default - Run\"},{\"t\":3,\"n\":\"SWMV - Base Movement Default - Swim\"},{\"t\":3,\"n\":\"FLMV - Base Movement Default - Fly\"},{\"t\":3,\"n\":\"SNMV - Base Movement Default - Sneak\"},{\"t\":3,\"n\":\"SPMV - Base Movement Default - Sprint\"},{\"t\":6,\"p\":1,\"n\":\"Head Data\",\"c\":[{\"n\":\"NAM0 - Head Data Marker\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Male Head Data\",\"c\":[{\"p\":1,\"n\":\"MNAM - Male Data Marker\"},{\"t\":10,\"p\":1,\"n\":\"Head Parts\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Head Part\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"INDX - Head Part Number\"},{\"t\":3,\"p\":1,\"n\":\"HEAD - Head\"}]}]},{\"t\":6,\"n\":\"Available Morphs\",\"c\":[{\"t\":11,\"n\":\"MPAI - Unknown\"},{\"t\":6,\"n\":\"MPAV - Nose Variants\",\"c\":[{\"t\":3,\"n\":\"Nose Morph Flags\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":6,\"n\":\"MPAV - Brow Variants\",\"c\":[{\"t\":3,\"n\":\"Brow Morph Flags\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":6,\"n\":\"MPAV - Eye Variants\",\"c\":[{\"t\":3,\"n\":\"Eye Morph Flags 1\"},{\"t\":3,\"n\":\"Eye Morph Flags 2\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":6,\"n\":\"MPAV - Lip Variants\",\"c\":[{\"t\":3,\"n\":\"Lip Morph Flags\"},{\"t\":11,\"n\":\"Unknown\"}]}]},{\"t\":8,\"n\":\"Race Presets Male\",\"c\":[{\"t\":3,\"n\":\"RPRM - Preset NPC\"}]},{\"t\":8,\"n\":\"Available Hair Colors Male\",\"c\":[{\"t\":3,\"n\":\"AHCM - Hair Color\"}]},{\"t\":8,\"n\":\"Face Details Texture Set List Male\",\"c\":[{\"t\":3,\"n\":\"FTSM - Texture Set\"}]},{\"t\":3,\"n\":\"DFTM - Default Face Texture Male\"},{\"t\":8,\"p\":1,\"n\":\"Tint Masks\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Tint Assets\",\"c\":[{\"t\":8,\"p\":1,\"n\":\"Tint Layer\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Texture\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"TINI - Index\"},{\"t\":2,\"p\":1,\"n\":\"TINT - File Name\"},{\"t\":3,\"p\":1,\"n\":\"TINP - Mask Type\"},{\"t\":3,\"p\":1,\"n\":\"TIND - Preset Default\"}]}]},{\"t\":8,\"p\":1,\"n\":\"Presets\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Preset\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"TINC - Color\"},{\"t\":5,\"p\":1,\"n\":\"TINV - Default Value\"},{\"t\":3,\"p\":1,\"n\":\"TIRS - Index\"}]}]}]}]},{\"t\":6,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"MODT - Texture Files Hashes\"},{\"t\":7,\"p\":1,\"n\":\"MODS - Alternate Textures\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"3D Name\"},{\"t\":3,\"p\":1,\"n\":\"New Texture\"},{\"t\":3,\"p\":1,\"n\":\"3D Index\"}]}]}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Female Head Data\",\"c\":[{\"p\":1,\"n\":\"NAM0 - Head Data Marker\"},{\"p\":1,\"n\":\"FNAM - Female Data Marker\"},{\"t\":10,\"p\":1,\"n\":\"Head Parts\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Head Part\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"INDX - Head Part Number\"},{\"t\":3,\"p\":1,\"n\":\"HEAD - Head\"}]}]},{\"t\":6,\"n\":\"Available Morphs\",\"c\":[{\"t\":11,\"n\":\"MPAI - Unknown\"},{\"t\":6,\"n\":\"MPAV - Nose Variants\",\"c\":[{\"t\":3,\"n\":\"Nose Morph Flags\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":6,\"n\":\"MPAV - Brow Variants\",\"c\":[{\"t\":3,\"n\":\"Brow Morph Flags\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":6,\"n\":\"MPAV - Eye Variants\",\"c\":[{\"t\":3,\"n\":\"Eye Morph Flags 1\"},{\"t\":3,\"n\":\"Eye Morph Flags 2\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":6,\"n\":\"MPAV - Lip Variants\",\"c\":[{\"t\":3,\"n\":\"Lip Morph Flags\"},{\"t\":11,\"n\":\"Unknown\"}]}]},{\"t\":8,\"n\":\"Race Presets Female\",\"c\":[{\"t\":3,\"n\":\"RPRF - Preset NPC\"}]},{\"t\":8,\"n\":\"Available Hair Colors Female\",\"c\":[{\"t\":3,\"n\":\"AHCF - Hair Color\"}]},{\"t\":8,\"n\":\"Face Details Texture Set List Female\",\"c\":[{\"t\":3,\"n\":\"FTSF - Texture Set\"}]},{\"t\":3,\"n\":\"DFTF - Default Face Texture Female\"},{\"t\":8,\"p\":1,\"n\":\"Tint Masks\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Tint Assets\",\"c\":[{\"t\":8,\"p\":1,\"n\":\"Tint Layer\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Texture\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"TINI - Index\"},{\"t\":2,\"p\":1,\"n\":\"TINT - File Name\"},{\"t\":3,\"p\":1,\"n\":\"TINP - Mask Type\"},{\"t\":3,\"p\":1,\"n\":\"TIND - Preset Default\"}]}]},{\"t\":8,\"p\":1,\"n\":\"Presets\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Preset\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"TINC - Color\"},{\"t\":5,\"p\":1,\"n\":\"TINV - Default Value\"},{\"t\":3,\"p\":1,\"n\":\"TIRS - Index\"}]}]}]}]},{\"t\":6,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"MODT - Texture Files Hashes\"},{\"t\":7,\"p\":1,\"n\":\"MODS - Alternate Textures\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"3D Name\"},{\"t\":3,\"p\":1,\"n\":\"New Texture\"},{\"t\":3,\"p\":1,\"n\":\"3D Index\"}]}]}]}]}]},{\"t\":3,\"n\":\"NAM8 - Morph race\"},{\"t\":3,\"n\":\"RNAM - Armor race\"}]},{\"t\":1,\"p\":1,\"n\":\"REFR - Placed Object\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"VMAD - Virtual Machine Adapter\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Version\"},{\"t\":3,\"p\":1,\"n\":\"Object Format\"},{\"t\":7,\"p\":1,\"n\":\"Scripts\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Script\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"scriptName\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":7,\"p\":1,\"n\":\"Properties\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Property\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"propertyName\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]},{\"t\":2,\"p\":1,\"n\":\"String\"},{\"t\":3,\"p\":1,\"n\":\"Int32\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":3,\"p\":1,\"n\":\"Bool\"},{\"t\":7,\"p\":1,\"n\":\"Array of Object\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]}]},{\"t\":7,\"p\":1,\"n\":\"Array of String\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Int32\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Float\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Bool\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]}]}]}]}]}]},{\"t\":3,\"p\":1,\"n\":\"NAME - Base\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"XMBO - Bound Half Extents\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"X\"},{\"t\":5,\"p\":1,\"n\":\"Y\"},{\"t\":5,\"p\":1,\"n\":\"Z\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"XPRM - Primitive\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Bounds\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"X\"},{\"t\":5,\"p\":1,\"n\":\"Y\"},{\"t\":5,\"p\":1,\"n\":\"Z\"}]},{\"t\":6,\"p\":1,\"n\":\"Color\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Red\"},{\"t\":5,\"p\":1,\"n\":\"Green\"},{\"t\":5,\"p\":1,\"n\":\"Blue\"}]},{\"t\":5,\"n\":\"Unknown\"},{\"t\":3,\"p\":1,\"n\":\"Type\"}]},{\"t\":11,\"n\":\"XORD - Unknown\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"XOCP - Occlusion Plane Data\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Size\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Width\"},{\"t\":5,\"p\":1,\"n\":\"Height\"}]},{\"t\":6,\"p\":1,\"n\":\"Position\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"X\"},{\"t\":5,\"p\":1,\"n\":\"Y\"},{\"t\":5,\"p\":1,\"n\":\"Z\"}]},{\"t\":6,\"p\":1,\"n\":\"Rotation (Quaternion?)\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"q1\"},{\"t\":5,\"p\":1,\"n\":\"q2\"},{\"t\":5,\"p\":1,\"n\":\"q3\"},{\"t\":5,\"p\":1,\"n\":\"q4\"}]}]},{\"t\":7,\"p\":1,\"n\":\"XPOD - Portal Data\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"References\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Origin\"},{\"t\":3,\"p\":1,\"n\":\"Destination\"}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"XPTL - Room Portal (unused)\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Size\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Width\"},{\"t\":5,\"p\":1,\"n\":\"Height\"}]},{\"t\":6,\"p\":1,\"n\":\"Position\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"X\"},{\"t\":5,\"p\":1,\"n\":\"Y\"},{\"t\":5,\"p\":1,\"n\":\"Z\"}]},{\"t\":6,\"p\":1,\"n\":\"Rotation (Quaternion?)\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"q1\"},{\"t\":5,\"p\":1,\"n\":\"q2\"},{\"t\":5,\"p\":1,\"n\":\"q3\"},{\"t\":5,\"p\":1,\"n\":\"q4\"}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Bound Data\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"XRMR - Header\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Linked Rooms Count\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":3,\"p\":1,\"n\":\"LNAM - Lighting Template\"},{\"t\":3,\"p\":1,\"n\":\"INAM - Image Space\"},{\"t\":8,\"p\":1,\"n\":\"Linked Rooms\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"XLRM - Linked Room\"}]}]},{\"p\":1,\"n\":\"XMBP - MultiBound Primitive Marker\"},{\"t\":11,\"n\":\"XRGD - Ragdoll Data\"},{\"t\":11,\"n\":\"XRGB - Ragdoll Biped Data\"},{\"t\":5,\"p\":1,\"n\":\"XRDS - Radius\"},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Reflected\\/Refracted By\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"XPWR - Water\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":3,\"p\":1,\"n\":\"Type\"}]}]},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Lit Water\",\"d\":1,\"c\":[{\"t\":3,\"p\":1,\"n\":\"XLTW - Water\"}]},{\"t\":3,\"p\":1,\"n\":\"XEMI - Emittance\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"XLIG - Light Data\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"FOV 90+\\/-\"},{\"t\":5,\"p\":1,\"n\":\"Fade 1.35+\\/-\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":5,\"p\":1,\"n\":\"Shadow Depth Bias\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"XALP - Alpha\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Cutoff\"},{\"t\":3,\"p\":1,\"n\":\"Base\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"XTEL - Teleport Destination\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Door\"},{\"t\":6,\"p\":1,\"n\":\"Position\\/Rotation\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Position\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"X\"},{\"t\":5,\"p\":1,\"n\":\"Y\"},{\"t\":5,\"p\":1,\"n\":\"Z\"}]},{\"t\":6,\"p\":1,\"n\":\"Rotation\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"X\"},{\"t\":5,\"p\":1,\"n\":\"Y\"},{\"t\":5,\"p\":1,\"n\":\"Z\"}]}]},{\"t\":3,\"p\":1,\"n\":\"Flags\"}]},{\"t\":3,\"p\":1,\"n\":\"XTNM - Teleport Message Box\"},{\"t\":3,\"p\":1,\"n\":\"XMBR - MultiBound Reference\"},{\"t\":11,\"n\":\"XWCN - Unknown\"},{\"t\":11,\"n\":\"XWCS - Unknown\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"XWCU - Water Velocity\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"X Offset\"},{\"t\":5,\"p\":1,\"n\":\"Y Offset\"},{\"t\":5,\"p\":1,\"n\":\"Z Offset\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":5,\"p\":1,\"n\":\"X Angle\"},{\"t\":5,\"p\":1,\"n\":\"Y Angle\"},{\"t\":5,\"p\":1,\"n\":\"Z Angle\"}]},{\"t\":6,\"n\":\"XCVL - Unknown\",\"c\":[{\"t\":11,\"n\":\"Unknown\"},{\"t\":5,\"n\":\"X Angle\"}]},{\"t\":3,\"n\":\"XCZR - Unknown\"},{\"t\":11,\"n\":\"XCZA - Unknown\"},{\"t\":3,\"n\":\"XCZC - Unknown\"},{\"t\":5,\"p\":1,\"n\":\"XSCL - Scale\"},{\"t\":3,\"p\":1,\"n\":\"XSPC - Spawn Container\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Activate Parents\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"XAPD - Flags\"},{\"t\":8,\"p\":1,\"n\":\"Activate Parent Refs\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"XAPR - Activate Parent Ref\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":5,\"p\":1,\"n\":\"Delay\"}]}]}]},{\"t\":3,\"p\":1,\"n\":\"XLIB - Leveled Item Base Object\"},{\"t\":3,\"p\":1,\"n\":\"XLCM - Level Modifier\"},{\"t\":3,\"p\":1,\"n\":\"XLCN - Persistent Location\"},{\"t\":3,\"p\":1,\"n\":\"XTRI - Collision Layer\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"XLOC - Lock Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Level\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Key\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"}]},{\"t\":3,\"p\":1,\"n\":\"XEZN - Encounter Zone\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"XNDP - Navigation Door Link\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Navigation Mesh\"},{\"t\":3,\"p\":1,\"n\":\"Teleport Marker Triangle\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":7,\"p\":1,\"n\":\"XLRT - Location Ref Type\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Ref\"}]},{\"p\":1,\"n\":\"XIS2 - Ignored by Sandbox\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Ownership\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"XOWN - Owner\"},{\"t\":3,\"p\":1,\"n\":\"XRNK - Faction rank\"}]},{\"t\":3,\"p\":1,\"n\":\"XCNT - Item Count\"},{\"t\":5,\"p\":1,\"n\":\"XCHG - Charge\"},{\"t\":3,\"p\":1,\"n\":\"XLRL - Location Reference\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"XESP - Enable Parent\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Linked References\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"XLKR - Linked Reference\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Keyword\\/Ref\"},{\"t\":3,\"p\":1,\"n\":\"Ref\"}]}]},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Patrol\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Data\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"XPRD - Idle Time\"},{\"p\":1,\"n\":\"XPPA - Patrol Script Marker\"},{\"t\":3,\"p\":1,\"n\":\"INAM - Idle\"},{\"t\":11,\"n\":\"SCHR - Unused\"},{\"t\":11,\"n\":\"SCTX - Unused\"},{\"t\":8,\"p\":1,\"n\":\"Topic\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"PDTO - Topic Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Topic\"},{\"t\":2,\"p\":1,\"n\":\"Subtype\"}]}]}]}]},{\"t\":3,\"p\":1,\"n\":\"XACT - Action Flag\"},{\"t\":5,\"p\":1,\"n\":\"XHTW - Head-Tracking Weight\"},{\"t\":5,\"p\":1,\"n\":\"XFVC - Favor Cost\"},{\"p\":1,\"n\":\"ONAM - Open by Default\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Map Marker\",\"c\":[{\"p\":1,\"n\":\"XMRK - Map Marker Data\"},{\"t\":3,\"p\":1,\"n\":\"FNAM - Map Flags\"},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":6,\"p\":1,\"n\":\"TNAM - \",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":11,\"n\":\"Unused\"}]}]},{\"t\":3,\"p\":1,\"n\":\"XATR - Attach Ref\"},{\"t\":7,\"n\":\"XLOD - Distant LOD Data\",\"c\":[{\"t\":5,\"n\":\"Unknown\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DATA - Position\\/Rotation\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Position\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"X\"},{\"t\":5,\"p\":1,\"n\":\"Y\"},{\"t\":5,\"p\":1,\"n\":\"Z\"}]},{\"t\":6,\"p\":1,\"n\":\"Rotation\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"X\"},{\"t\":5,\"p\":1,\"n\":\"Y\"},{\"t\":5,\"p\":1,\"n\":\"Z\"}]}]}]},{\"t\":1,\"p\":1,\"n\":\"REGN - Region\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"RCLR - Map Color\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":3,\"p\":1,\"n\":\"WNAM - Worldspace\"},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Region Areas\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Region Area\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"RPLI - Edge Fall-off\"},{\"t\":7,\"p\":1,\"n\":\"RPLD - Region Point List Data\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Point\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"X\"},{\"t\":5,\"p\":1,\"n\":\"Y\"}]}]}]}]},{\"t\":10,\"p\":1,\"n\":\"Region Data Entries\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Region Data Entry\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"RDAT - Data Header\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":3,\"p\":1,\"n\":\"Priority\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":6,\"p\":1,\"n\":\"Icon\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"ICON - Large Icon filename\"},{\"t\":2,\"p\":1,\"n\":\"MICO - Small Icon filename\"}]},{\"t\":3,\"p\":1,\"n\":\"RDMO - Music\"},{\"t\":7,\"p\":1,\"n\":\"RDSA - Sounds\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Sound\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Sound\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":5,\"p\":1,\"n\":\"Chance\"}]}]},{\"t\":2,\"p\":1,\"n\":\"RDMP - Map Name\"},{\"t\":7,\"p\":1,\"n\":\"RDOT - Objects\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Object\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Object\"},{\"t\":3,\"p\":1,\"n\":\"Parent Index\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":5,\"p\":1,\"n\":\"Density\"},{\"t\":3,\"p\":1,\"n\":\"Clustering\"},{\"t\":3,\"p\":1,\"n\":\"Min Slope\"},{\"t\":3,\"p\":1,\"n\":\"Max Slope\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":3,\"p\":1,\"n\":\"Radius wrt Parent\"},{\"t\":3,\"p\":1,\"n\":\"Radius\"},{\"t\":5,\"p\":1,\"n\":\"Min Height\"},{\"t\":5,\"p\":1,\"n\":\"Max Height\"},{\"t\":5,\"p\":1,\"n\":\"Sink\"},{\"t\":5,\"p\":1,\"n\":\"Sink Variance\"},{\"t\":5,\"p\":1,\"n\":\"Size Variance\"},{\"t\":6,\"p\":1,\"n\":\"Angle Variance\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"X\"},{\"t\":3,\"p\":1,\"n\":\"Y\"},{\"t\":3,\"p\":1,\"n\":\"Z\"}]}]}]},{\"t\":7,\"p\":1,\"n\":\"RDGS - Grasses\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Grass\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Grass\"},{\"t\":11,\"n\":\"Unknown\"}]}]},{\"t\":7,\"p\":1,\"n\":\"RDWT - Weather Types\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Weather Type\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Weather\"},{\"t\":3,\"p\":1,\"n\":\"Chance\"},{\"t\":3,\"p\":1,\"n\":\"Global\"}]}]}]}]}]},{\"t\":1,\"p\":1,\"n\":\"RELA - Relationship\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DATA - Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Parent\"},{\"t\":3,\"p\":1,\"n\":\"Child\"},{\"t\":3,\"p\":1,\"n\":\"Rank\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":3,\"p\":1,\"n\":\"Association Type\"}]}]},{\"t\":1,\"p\":1,\"n\":\"REVB - Reverb Parameters\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DATA - Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Decay Time (ms)\"},{\"t\":3,\"p\":1,\"n\":\"HF Reference (Hz)\"},{\"t\":3,\"p\":1,\"n\":\"Room Filter\"},{\"t\":3,\"p\":1,\"n\":\"Room HF Filter\"},{\"t\":3,\"p\":1,\"n\":\"Reflections\"},{\"t\":3,\"p\":1,\"n\":\"Reverb Amp\"},{\"t\":3,\"p\":1,\"n\":\"Decay HF Ratio\"},{\"t\":3,\"p\":1,\"n\":\"Reflect Delay (ms), scaled\"},{\"t\":3,\"p\":1,\"n\":\"Reverb Delay (ms)\"},{\"t\":3,\"p\":1,\"n\":\"Diffusion %\"},{\"t\":3,\"p\":1,\"n\":\"Density %\"},{\"t\":3,\"n\":\"Unknown\"}]}]},{\"t\":1,\"p\":1,\"n\":\"RFCT - Visual Effect\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DATA - Effect Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Effect Art\"},{\"t\":3,\"p\":1,\"n\":\"Shader\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"}]}]},{\"t\":1,\"p\":1,\"n\":\"RGDL\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"}]},{\"t\":1,\"p\":1,\"n\":\"SCEN - Scene\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"VMAD - Virtual Machine Adapter\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Version\"},{\"t\":3,\"p\":1,\"n\":\"Object Format\"},{\"t\":7,\"p\":1,\"n\":\"Scripts\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Script\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"scriptName\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":7,\"p\":1,\"n\":\"Properties\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Property\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"propertyName\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]},{\"t\":2,\"p\":1,\"n\":\"String\"},{\"t\":3,\"p\":1,\"n\":\"Int32\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":3,\"p\":1,\"n\":\"Bool\"},{\"t\":7,\"p\":1,\"n\":\"Array of Object\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]}]},{\"t\":7,\"p\":1,\"n\":\"Array of String\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Int32\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Float\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Bool\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]}]}]}]}]},{\"t\":6,\"p\":1,\"n\":\"Script Fragments\",\"c\":[{\"t\":3,\"n\":\"Unknown\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":2,\"p\":1,\"n\":\"fileName\"},{\"t\":7,\"p\":1,\"n\":\"Fragments\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Fragment\",\"c\":[{\"t\":3,\"n\":\"Unknown\"},{\"t\":2,\"p\":1,\"n\":\"scriptName\"},{\"t\":2,\"p\":1,\"n\":\"fragmentName\"}]}]},{\"t\":7,\"p\":1,\"n\":\"Phase Fragments\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Phase Fragment\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Phase Flag\"},{\"t\":3,\"p\":1,\"n\":\"Phase Index\"},{\"t\":3,\"n\":\"Unknown\"},{\"t\":2,\"p\":1,\"n\":\"scriptName\"},{\"t\":2,\"p\":1,\"n\":\"fragmentName\"}]}]}]}]},{\"t\":3,\"p\":1,\"n\":\"FNAM - Flags\"},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Phases\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Phase\",\"c\":[{\"p\":1,\"n\":\"HNAM - Marker Phase Start\"},{\"t\":2,\"p\":1,\"n\":\"NAM0 - Name\"},{\"t\":6,\"p\":1,\"n\":\"Start Conditions\",\"c\":[{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Conditions\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Condition\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"CTDA - \",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":5,\"p\":1,\"n\":\"Comparison Value - Float\"},{\"t\":3,\"p\":1,\"n\":\"Comparison Value - Global\"},{\"t\":3,\"p\":1,\"n\":\"Function\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":11,\"p\":1,\"n\":\"None\"},{\"t\":3,\"p\":1,\"n\":\"Integer\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":11,\"p\":1,\"n\":\"Variable Name (unused)\"},{\"t\":3,\"p\":1,\"n\":\"Sex\"},{\"t\":3,\"p\":1,\"n\":\"Actor Value\"},{\"t\":3,\"p\":1,\"n\":\"Crime Type\"},{\"t\":3,\"p\":1,\"n\":\"Axis\"},{\"t\":3,\"p\":1,\"n\":\"Quest Stage (unused)\"},{\"t\":3,\"p\":1,\"n\":\"Misc Stat\"},{\"t\":3,\"p\":1,\"n\":\"Alignment\"},{\"t\":3,\"p\":1,\"n\":\"Equip Type\"},{\"t\":3,\"p\":1,\"n\":\"Form Type\"},{\"t\":3,\"p\":1,\"n\":\"Critical Stage\"},{\"t\":3,\"p\":1,\"n\":\"Object Reference\"},{\"t\":3,\"p\":1,\"n\":\"Inventory Object\"},{\"t\":3,\"p\":1,\"n\":\"Actor\"},{\"t\":3,\"p\":1,\"n\":\"Voice Type\"},{\"t\":3,\"p\":1,\"n\":\"Idle\"},{\"t\":3,\"p\":1,\"n\":\"Form List\"},{\"t\":3,\"p\":1,\"n\":\"Quest\"},{\"t\":3,\"p\":1,\"n\":\"Faction\"},{\"t\":3,\"p\":1,\"n\":\"Cell\"},{\"t\":3,\"p\":1,\"n\":\"Class\"},{\"t\":3,\"p\":1,\"n\":\"Race\"},{\"t\":3,\"p\":1,\"n\":\"Actor Base\"},{\"t\":3,\"p\":1,\"n\":\"Global\"},{\"t\":3,\"p\":1,\"n\":\"Weather\"},{\"t\":3,\"p\":1,\"n\":\"Package\"},{\"t\":3,\"p\":1,\"n\":\"Encounter Zone\"},{\"t\":3,\"p\":1,\"n\":\"Perk\"},{\"t\":3,\"p\":1,\"n\":\"Owner\"},{\"t\":3,\"p\":1,\"n\":\"Furniture\"},{\"t\":3,\"p\":1,\"n\":\"Effect Item\"},{\"t\":3,\"p\":1,\"n\":\"Base Effect\"},{\"t\":3,\"p\":1,\"n\":\"Worldspace\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Function\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Param (INVALID)\"},{\"t\":3,\"p\":1,\"n\":\"Referenceable Object\"},{\"t\":3,\"p\":1,\"n\":\"Region\"},{\"t\":3,\"p\":1,\"n\":\"Keyword\"},{\"t\":3,\"p\":1,\"n\":\"Player Action\"},{\"t\":3,\"p\":1,\"n\":\"Casting Type\"},{\"t\":3,\"p\":1,\"n\":\"Shout\"},{\"t\":3,\"p\":1,\"n\":\"Location\"},{\"t\":3,\"p\":1,\"n\":\"Location Ref Type\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"Packdata ID\"},{\"t\":3,\"p\":1,\"n\":\"Association Type\"},{\"t\":3,\"p\":1,\"n\":\"Furniture Anim\"},{\"t\":3,\"p\":1,\"n\":\"Furniture Entry\"},{\"t\":3,\"p\":1,\"n\":\"Scene\"},{\"t\":3,\"p\":1,\"n\":\"Ward State\"},{\"t\":3,\"p\":1,\"n\":\"Event\"},{\"t\":3,\"p\":1,\"n\":\"Event Data\"},{\"t\":3,\"p\":1,\"n\":\"Quest Stage\"},{\"t\":3,\"p\":1,\"n\":\"Weapon\"},{\"t\":3,\"p\":1,\"n\":\"Weapon List\"},{\"t\":3,\"p\":1,\"n\":\"Target\"},{\"t\":3,\"p\":1,\"n\":\"Target List\"},{\"t\":3,\"p\":1,\"n\":\"Target Part\"},{\"t\":3,\"p\":1,\"n\":\"VATS Action\"},{\"t\":3,\"p\":1,\"n\":\"Critical Effect\"},{\"t\":3,\"p\":1,\"n\":\"Critical Effect List\"},{\"t\":3,\"p\":1,\"n\":\"Weapon Type\"},{\"t\":3,\"p\":1,\"n\":\"Projectile Type\"},{\"t\":3,\"p\":1,\"n\":\"Delivery Type\"},{\"t\":3,\"p\":1,\"n\":\"Run On\"},{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":3,\"p\":1,\"n\":\"Parameter #3\"}]},{\"t\":2,\"p\":1,\"n\":\"CIS1 - Parameter #1\"},{\"t\":2,\"p\":1,\"n\":\"CIS2 - Parameter #2\"}]}]}]},{\"p\":1,\"n\":\"NEXT - Marker\"},{\"t\":6,\"p\":1,\"n\":\"Completion Conditions\",\"c\":[{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Conditions\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Condition\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"CTDA - \",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":5,\"p\":1,\"n\":\"Comparison Value - Float\"},{\"t\":3,\"p\":1,\"n\":\"Comparison Value - Global\"},{\"t\":3,\"p\":1,\"n\":\"Function\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":11,\"p\":1,\"n\":\"None\"},{\"t\":3,\"p\":1,\"n\":\"Integer\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":11,\"p\":1,\"n\":\"Variable Name (unused)\"},{\"t\":3,\"p\":1,\"n\":\"Sex\"},{\"t\":3,\"p\":1,\"n\":\"Actor Value\"},{\"t\":3,\"p\":1,\"n\":\"Crime Type\"},{\"t\":3,\"p\":1,\"n\":\"Axis\"},{\"t\":3,\"p\":1,\"n\":\"Quest Stage (unused)\"},{\"t\":3,\"p\":1,\"n\":\"Misc Stat\"},{\"t\":3,\"p\":1,\"n\":\"Alignment\"},{\"t\":3,\"p\":1,\"n\":\"Equip Type\"},{\"t\":3,\"p\":1,\"n\":\"Form Type\"},{\"t\":3,\"p\":1,\"n\":\"Critical Stage\"},{\"t\":3,\"p\":1,\"n\":\"Object Reference\"},{\"t\":3,\"p\":1,\"n\":\"Inventory Object\"},{\"t\":3,\"p\":1,\"n\":\"Actor\"},{\"t\":3,\"p\":1,\"n\":\"Voice Type\"},{\"t\":3,\"p\":1,\"n\":\"Idle\"},{\"t\":3,\"p\":1,\"n\":\"Form List\"},{\"t\":3,\"p\":1,\"n\":\"Quest\"},{\"t\":3,\"p\":1,\"n\":\"Faction\"},{\"t\":3,\"p\":1,\"n\":\"Cell\"},{\"t\":3,\"p\":1,\"n\":\"Class\"},{\"t\":3,\"p\":1,\"n\":\"Race\"},{\"t\":3,\"p\":1,\"n\":\"Actor Base\"},{\"t\":3,\"p\":1,\"n\":\"Global\"},{\"t\":3,\"p\":1,\"n\":\"Weather\"},{\"t\":3,\"p\":1,\"n\":\"Package\"},{\"t\":3,\"p\":1,\"n\":\"Encounter Zone\"},{\"t\":3,\"p\":1,\"n\":\"Perk\"},{\"t\":3,\"p\":1,\"n\":\"Owner\"},{\"t\":3,\"p\":1,\"n\":\"Furniture\"},{\"t\":3,\"p\":1,\"n\":\"Effect Item\"},{\"t\":3,\"p\":1,\"n\":\"Base Effect\"},{\"t\":3,\"p\":1,\"n\":\"Worldspace\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Function\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Param (INVALID)\"},{\"t\":3,\"p\":1,\"n\":\"Referenceable Object\"},{\"t\":3,\"p\":1,\"n\":\"Region\"},{\"t\":3,\"p\":1,\"n\":\"Keyword\"},{\"t\":3,\"p\":1,\"n\":\"Player Action\"},{\"t\":3,\"p\":1,\"n\":\"Casting Type\"},{\"t\":3,\"p\":1,\"n\":\"Shout\"},{\"t\":3,\"p\":1,\"n\":\"Location\"},{\"t\":3,\"p\":1,\"n\":\"Location Ref Type\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"Packdata ID\"},{\"t\":3,\"p\":1,\"n\":\"Association Type\"},{\"t\":3,\"p\":1,\"n\":\"Furniture Anim\"},{\"t\":3,\"p\":1,\"n\":\"Furniture Entry\"},{\"t\":3,\"p\":1,\"n\":\"Scene\"},{\"t\":3,\"p\":1,\"n\":\"Ward State\"},{\"t\":3,\"p\":1,\"n\":\"Event\"},{\"t\":3,\"p\":1,\"n\":\"Event Data\"},{\"t\":3,\"p\":1,\"n\":\"Quest Stage\"},{\"t\":3,\"p\":1,\"n\":\"Weapon\"},{\"t\":3,\"p\":1,\"n\":\"Weapon List\"},{\"t\":3,\"p\":1,\"n\":\"Target\"},{\"t\":3,\"p\":1,\"n\":\"Target List\"},{\"t\":3,\"p\":1,\"n\":\"Target Part\"},{\"t\":3,\"p\":1,\"n\":\"VATS Action\"},{\"t\":3,\"p\":1,\"n\":\"Critical Effect\"},{\"t\":3,\"p\":1,\"n\":\"Critical Effect List\"},{\"t\":3,\"p\":1,\"n\":\"Weapon Type\"},{\"t\":3,\"p\":1,\"n\":\"Projectile Type\"},{\"t\":3,\"p\":1,\"n\":\"Delivery Type\"},{\"t\":3,\"p\":1,\"n\":\"Run On\"},{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":3,\"p\":1,\"n\":\"Parameter #3\"}]},{\"t\":2,\"p\":1,\"n\":\"CIS1 - Parameter #1\"},{\"t\":2,\"p\":1,\"n\":\"CIS2 - Parameter #2\"}]}]}]},{\"t\":6,\"n\":\"Unused\",\"c\":[{\"t\":11,\"n\":\"SCHR - Unknown\"},{\"t\":11,\"n\":\"SCDA - Unknown\"},{\"t\":11,\"n\":\"SCTX - Unknown\"},{\"t\":11,\"n\":\"QNAM - Unknown\"},{\"t\":11,\"n\":\"SCRO - Unknown\"}]},{\"t\":3,\"p\":1,\"n\":\"WNAM - Editor Width\"},{\"p\":1,\"n\":\"HNAM - Marker Phase End\"}]}]},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Actors\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Actor\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"ALID - Actor ID\"},{\"t\":3,\"p\":1,\"n\":\"LNAM - Flags\"},{\"t\":3,\"p\":1,\"n\":\"DNAM - Behaviour Flags\"}]}]},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Actions\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Action\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"ANAM - Type\"},{\"t\":2,\"p\":1,\"n\":\"NAM0 - Name\"},{\"t\":3,\"p\":1,\"n\":\"ALID - Actor ID\"},{\"t\":11,\"n\":\"LNAM - Unknown\"},{\"t\":3,\"p\":1,\"n\":\"INAM - Index\"},{\"t\":3,\"p\":1,\"n\":\"FNAM - Flags\"},{\"t\":3,\"p\":1,\"n\":\"SNAM - Start Phase\"},{\"t\":3,\"p\":1,\"n\":\"ENAM - End Phase\"},{\"t\":5,\"p\":1,\"n\":\"SNAM - Timer Seconds\"},{\"t\":8,\"p\":1,\"n\":\"Packages\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"PNAM - Package\"}]},{\"t\":3,\"p\":1,\"n\":\"DATA - Topic\"},{\"t\":3,\"p\":1,\"n\":\"HTID - Headtrack Actor ID\"},{\"t\":5,\"p\":1,\"n\":\"DMAX - Looping - Max\"},{\"t\":5,\"p\":1,\"n\":\"DMIN - Looping - Min\"},{\"t\":3,\"p\":1,\"n\":\"DEMO - Emotion Type\"},{\"t\":3,\"p\":1,\"n\":\"DEVA - Emotion Value\"},{\"t\":6,\"n\":\"Unused\",\"c\":[{\"t\":11,\"n\":\"SCHR - Unknown\"},{\"t\":11,\"n\":\"SCDA - Unknown\"},{\"t\":11,\"n\":\"SCTX - Unknown\"},{\"t\":11,\"n\":\"QNAM - Unknown\"},{\"t\":11,\"n\":\"SCRO - Unknown\"}]},{\"p\":1,\"n\":\"ANAM - End Marker\"}]}]},{\"t\":6,\"n\":\"Unused\",\"c\":[{\"t\":11,\"n\":\"SCHR - Unknown\"},{\"t\":11,\"n\":\"SCDA - Unknown\"},{\"t\":11,\"n\":\"SCTX - Unknown\"},{\"t\":11,\"n\":\"QNAM - Unknown\"},{\"t\":11,\"n\":\"SCRO - Unknown\"}]},{\"p\":1,\"n\":\"NEXT - Marker\"},{\"t\":3,\"p\":1,\"n\":\"PNAM - Quest\"},{\"t\":3,\"p\":1,\"n\":\"INAM - Last Action Index\"},{\"t\":11,\"n\":\"VNAM - Unknown\"},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Conditions\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Condition\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"CTDA - \",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":5,\"p\":1,\"n\":\"Comparison Value - Float\"},{\"t\":3,\"p\":1,\"n\":\"Comparison Value - Global\"},{\"t\":3,\"p\":1,\"n\":\"Function\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":11,\"p\":1,\"n\":\"None\"},{\"t\":3,\"p\":1,\"n\":\"Integer\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":11,\"p\":1,\"n\":\"Variable Name (unused)\"},{\"t\":3,\"p\":1,\"n\":\"Sex\"},{\"t\":3,\"p\":1,\"n\":\"Actor Value\"},{\"t\":3,\"p\":1,\"n\":\"Crime Type\"},{\"t\":3,\"p\":1,\"n\":\"Axis\"},{\"t\":3,\"p\":1,\"n\":\"Quest Stage (unused)\"},{\"t\":3,\"p\":1,\"n\":\"Misc Stat\"},{\"t\":3,\"p\":1,\"n\":\"Alignment\"},{\"t\":3,\"p\":1,\"n\":\"Equip Type\"},{\"t\":3,\"p\":1,\"n\":\"Form Type\"},{\"t\":3,\"p\":1,\"n\":\"Critical Stage\"},{\"t\":3,\"p\":1,\"n\":\"Object Reference\"},{\"t\":3,\"p\":1,\"n\":\"Inventory Object\"},{\"t\":3,\"p\":1,\"n\":\"Actor\"},{\"t\":3,\"p\":1,\"n\":\"Voice Type\"},{\"t\":3,\"p\":1,\"n\":\"Idle\"},{\"t\":3,\"p\":1,\"n\":\"Form List\"},{\"t\":3,\"p\":1,\"n\":\"Quest\"},{\"t\":3,\"p\":1,\"n\":\"Faction\"},{\"t\":3,\"p\":1,\"n\":\"Cell\"},{\"t\":3,\"p\":1,\"n\":\"Class\"},{\"t\":3,\"p\":1,\"n\":\"Race\"},{\"t\":3,\"p\":1,\"n\":\"Actor Base\"},{\"t\":3,\"p\":1,\"n\":\"Global\"},{\"t\":3,\"p\":1,\"n\":\"Weather\"},{\"t\":3,\"p\":1,\"n\":\"Package\"},{\"t\":3,\"p\":1,\"n\":\"Encounter Zone\"},{\"t\":3,\"p\":1,\"n\":\"Perk\"},{\"t\":3,\"p\":1,\"n\":\"Owner\"},{\"t\":3,\"p\":1,\"n\":\"Furniture\"},{\"t\":3,\"p\":1,\"n\":\"Effect Item\"},{\"t\":3,\"p\":1,\"n\":\"Base Effect\"},{\"t\":3,\"p\":1,\"n\":\"Worldspace\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Function\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Param (INVALID)\"},{\"t\":3,\"p\":1,\"n\":\"Referenceable Object\"},{\"t\":3,\"p\":1,\"n\":\"Region\"},{\"t\":3,\"p\":1,\"n\":\"Keyword\"},{\"t\":3,\"p\":1,\"n\":\"Player Action\"},{\"t\":3,\"p\":1,\"n\":\"Casting Type\"},{\"t\":3,\"p\":1,\"n\":\"Shout\"},{\"t\":3,\"p\":1,\"n\":\"Location\"},{\"t\":3,\"p\":1,\"n\":\"Location Ref Type\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"Packdata ID\"},{\"t\":3,\"p\":1,\"n\":\"Association Type\"},{\"t\":3,\"p\":1,\"n\":\"Furniture Anim\"},{\"t\":3,\"p\":1,\"n\":\"Furniture Entry\"},{\"t\":3,\"p\":1,\"n\":\"Scene\"},{\"t\":3,\"p\":1,\"n\":\"Ward State\"},{\"t\":3,\"p\":1,\"n\":\"Event\"},{\"t\":3,\"p\":1,\"n\":\"Event Data\"},{\"t\":3,\"p\":1,\"n\":\"Quest Stage\"},{\"t\":3,\"p\":1,\"n\":\"Weapon\"},{\"t\":3,\"p\":1,\"n\":\"Weapon List\"},{\"t\":3,\"p\":1,\"n\":\"Target\"},{\"t\":3,\"p\":1,\"n\":\"Target List\"},{\"t\":3,\"p\":1,\"n\":\"Target Part\"},{\"t\":3,\"p\":1,\"n\":\"VATS Action\"},{\"t\":3,\"p\":1,\"n\":\"Critical Effect\"},{\"t\":3,\"p\":1,\"n\":\"Critical Effect List\"},{\"t\":3,\"p\":1,\"n\":\"Weapon Type\"},{\"t\":3,\"p\":1,\"n\":\"Projectile Type\"},{\"t\":3,\"p\":1,\"n\":\"Delivery Type\"},{\"t\":3,\"p\":1,\"n\":\"Run On\"},{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":3,\"p\":1,\"n\":\"Parameter #3\"}]},{\"t\":2,\"p\":1,\"n\":\"CIS1 - Parameter #1\"},{\"t\":2,\"p\":1,\"n\":\"CIS2 - Parameter #2\"}]}]}]},{\"t\":1,\"p\":1,\"n\":\"SCOL\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"}]},{\"t\":1,\"p\":1,\"n\":\"SCPT\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"}]},{\"t\":1,\"p\":1,\"n\":\"SCRL - Scroll\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"X1\"},{\"t\":3,\"p\":1,\"n\":\"Y1\"},{\"t\":3,\"p\":1,\"n\":\"Z1\"},{\"t\":3,\"p\":1,\"n\":\"X2\"},{\"t\":3,\"p\":1,\"n\":\"Y2\"},{\"t\":3,\"p\":1,\"n\":\"Z2\"}]},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":3,\"n\":\"KSIZ - Keyword Count\"},{\"t\":7,\"p\":1,\"n\":\"KWDA - Keywords\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Keyword\"}]},{\"t\":3,\"p\":1,\"n\":\"MDOB - Menu Display Object\"},{\"t\":3,\"p\":1,\"n\":\"ETYP - Equipment Type\"},{\"t\":2,\"p\":1,\"n\":\"DESC - Description\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"MODT - Texture Files Hashes\"},{\"t\":7,\"p\":1,\"n\":\"MODS - Alternate Textures\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"3D Name\"},{\"t\":3,\"p\":1,\"n\":\"New Texture\"},{\"t\":3,\"p\":1,\"n\":\"3D Index\"}]}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Destructable\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"DEST - Header\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Health\"},{\"t\":3,\"p\":1,\"n\":\"DEST Count\"},{\"t\":3,\"p\":1,\"n\":\"VATS Targetable\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":8,\"p\":1,\"n\":\"Stages\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Stage\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"DSTD - Destruction Stage Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Health %\"},{\"t\":3,\"p\":1,\"n\":\"Index\"},{\"t\":3,\"p\":1,\"n\":\"Model Damage Stage\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":3,\"p\":1,\"n\":\"Self Damage per Second\"},{\"t\":3,\"p\":1,\"n\":\"Explosion\"},{\"t\":3,\"p\":1,\"n\":\"Debris\"},{\"t\":3,\"p\":1,\"n\":\"Debris Count\"}]},{\"t\":6,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"DMDL - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"DMDT - Texture Files Hashes\"},{\"t\":7,\"p\":1,\"n\":\"DMDS - Alternate Textures\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"3D Name\"},{\"t\":3,\"p\":1,\"n\":\"New Texture\"},{\"t\":3,\"p\":1,\"n\":\"3D Index\"}]}]}]},{\"p\":1,\"n\":\"DSTF - End Marker\"}]}]}]},{\"t\":3,\"p\":1,\"n\":\"YNAM - Sound - Pick Up\"},{\"t\":3,\"p\":1,\"n\":\"ZNAM - Sound - Put Down\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DATA - Item\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Value\"},{\"t\":5,\"p\":1,\"n\":\"Weight\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"SPIT - Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Base Cost\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":5,\"p\":1,\"n\":\"Charge Time\"},{\"t\":3,\"p\":1,\"n\":\"Cast Type\"},{\"t\":3,\"p\":1,\"n\":\"Target Type\"},{\"t\":5,\"p\":1,\"n\":\"Cast Duration\"},{\"t\":5,\"p\":1,\"n\":\"Range\"},{\"t\":3,\"p\":1,\"n\":\"Half-cost Perk\"}]},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Effects\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Effect\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"EFID - Base Effect\"},{\"t\":6,\"p\":1,\"n\":\"EFIT - \",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Magnitude\"},{\"t\":3,\"p\":1,\"n\":\"Area\"},{\"t\":3,\"p\":1,\"n\":\"Duration\"}]},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Conditions\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Condition\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"CTDA - \",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":5,\"p\":1,\"n\":\"Comparison Value - Float\"},{\"t\":3,\"p\":1,\"n\":\"Comparison Value - Global\"},{\"t\":3,\"p\":1,\"n\":\"Function\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":11,\"p\":1,\"n\":\"None\"},{\"t\":3,\"p\":1,\"n\":\"Integer\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":11,\"p\":1,\"n\":\"Variable Name (unused)\"},{\"t\":3,\"p\":1,\"n\":\"Sex\"},{\"t\":3,\"p\":1,\"n\":\"Actor Value\"},{\"t\":3,\"p\":1,\"n\":\"Crime Type\"},{\"t\":3,\"p\":1,\"n\":\"Axis\"},{\"t\":3,\"p\":1,\"n\":\"Quest Stage (unused)\"},{\"t\":3,\"p\":1,\"n\":\"Misc Stat\"},{\"t\":3,\"p\":1,\"n\":\"Alignment\"},{\"t\":3,\"p\":1,\"n\":\"Equip Type\"},{\"t\":3,\"p\":1,\"n\":\"Form Type\"},{\"t\":3,\"p\":1,\"n\":\"Critical Stage\"},{\"t\":3,\"p\":1,\"n\":\"Object Reference\"},{\"t\":3,\"p\":1,\"n\":\"Inventory Object\"},{\"t\":3,\"p\":1,\"n\":\"Actor\"},{\"t\":3,\"p\":1,\"n\":\"Voice Type\"},{\"t\":3,\"p\":1,\"n\":\"Idle\"},{\"t\":3,\"p\":1,\"n\":\"Form List\"},{\"t\":3,\"p\":1,\"n\":\"Quest\"},{\"t\":3,\"p\":1,\"n\":\"Faction\"},{\"t\":3,\"p\":1,\"n\":\"Cell\"},{\"t\":3,\"p\":1,\"n\":\"Class\"},{\"t\":3,\"p\":1,\"n\":\"Race\"},{\"t\":3,\"p\":1,\"n\":\"Actor Base\"},{\"t\":3,\"p\":1,\"n\":\"Global\"},{\"t\":3,\"p\":1,\"n\":\"Weather\"},{\"t\":3,\"p\":1,\"n\":\"Package\"},{\"t\":3,\"p\":1,\"n\":\"Encounter Zone\"},{\"t\":3,\"p\":1,\"n\":\"Perk\"},{\"t\":3,\"p\":1,\"n\":\"Owner\"},{\"t\":3,\"p\":1,\"n\":\"Furniture\"},{\"t\":3,\"p\":1,\"n\":\"Effect Item\"},{\"t\":3,\"p\":1,\"n\":\"Base Effect\"},{\"t\":3,\"p\":1,\"n\":\"Worldspace\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Function\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Param (INVALID)\"},{\"t\":3,\"p\":1,\"n\":\"Referenceable Object\"},{\"t\":3,\"p\":1,\"n\":\"Region\"},{\"t\":3,\"p\":1,\"n\":\"Keyword\"},{\"t\":3,\"p\":1,\"n\":\"Player Action\"},{\"t\":3,\"p\":1,\"n\":\"Casting Type\"},{\"t\":3,\"p\":1,\"n\":\"Shout\"},{\"t\":3,\"p\":1,\"n\":\"Location\"},{\"t\":3,\"p\":1,\"n\":\"Location Ref Type\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"Packdata ID\"},{\"t\":3,\"p\":1,\"n\":\"Association Type\"},{\"t\":3,\"p\":1,\"n\":\"Furniture Anim\"},{\"t\":3,\"p\":1,\"n\":\"Furniture Entry\"},{\"t\":3,\"p\":1,\"n\":\"Scene\"},{\"t\":3,\"p\":1,\"n\":\"Ward State\"},{\"t\":3,\"p\":1,\"n\":\"Event\"},{\"t\":3,\"p\":1,\"n\":\"Event Data\"},{\"t\":3,\"p\":1,\"n\":\"Quest Stage\"},{\"t\":3,\"p\":1,\"n\":\"Weapon\"},{\"t\":3,\"p\":1,\"n\":\"Weapon List\"},{\"t\":3,\"p\":1,\"n\":\"Target\"},{\"t\":3,\"p\":1,\"n\":\"Target List\"},{\"t\":3,\"p\":1,\"n\":\"Target Part\"},{\"t\":3,\"p\":1,\"n\":\"VATS Action\"},{\"t\":3,\"p\":1,\"n\":\"Critical Effect\"},{\"t\":3,\"p\":1,\"n\":\"Critical Effect List\"},{\"t\":3,\"p\":1,\"n\":\"Weapon Type\"},{\"t\":3,\"p\":1,\"n\":\"Projectile Type\"},{\"t\":3,\"p\":1,\"n\":\"Delivery Type\"},{\"t\":3,\"p\":1,\"n\":\"Run On\"},{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":3,\"p\":1,\"n\":\"Parameter #3\"}]},{\"t\":2,\"p\":1,\"n\":\"CIS1 - Parameter #1\"},{\"t\":2,\"p\":1,\"n\":\"CIS2 - Parameter #2\"}]}]}]}]}]},{\"t\":1,\"p\":1,\"n\":\"SHOU - Shout\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":3,\"p\":1,\"n\":\"MDOB - Menu Display Object\"},{\"t\":2,\"p\":1,\"n\":\"DESC - Description\"},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Words of Power\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"SNAM - \",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Word\"},{\"t\":3,\"p\":1,\"n\":\"Spell\"},{\"t\":5,\"p\":1,\"n\":\"Recovery Time\"}]}]}]},{\"t\":1,\"p\":1,\"n\":\"SLGM - Soul Gem\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"X1\"},{\"t\":3,\"p\":1,\"n\":\"Y1\"},{\"t\":3,\"p\":1,\"n\":\"Z1\"},{\"t\":3,\"p\":1,\"n\":\"X2\"},{\"t\":3,\"p\":1,\"n\":\"Y2\"},{\"t\":3,\"p\":1,\"n\":\"Z2\"}]},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"MODT - Texture Files Hashes\"},{\"t\":7,\"p\":1,\"n\":\"MODS - Alternate Textures\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"3D Name\"},{\"t\":3,\"p\":1,\"n\":\"New Texture\"},{\"t\":3,\"p\":1,\"n\":\"3D Index\"}]}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Icon\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"ICON - Large Icon filename\"},{\"t\":2,\"p\":1,\"n\":\"MICO - Small Icon filename\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Destructable\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"DEST - Header\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Health\"},{\"t\":3,\"p\":1,\"n\":\"DEST Count\"},{\"t\":3,\"p\":1,\"n\":\"VATS Targetable\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":8,\"p\":1,\"n\":\"Stages\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Stage\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"DSTD - Destruction Stage Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Health %\"},{\"t\":3,\"p\":1,\"n\":\"Index\"},{\"t\":3,\"p\":1,\"n\":\"Model Damage Stage\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":3,\"p\":1,\"n\":\"Self Damage per Second\"},{\"t\":3,\"p\":1,\"n\":\"Explosion\"},{\"t\":3,\"p\":1,\"n\":\"Debris\"},{\"t\":3,\"p\":1,\"n\":\"Debris Count\"}]},{\"t\":6,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"DMDL - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"DMDT - Texture Files Hashes\"},{\"t\":7,\"p\":1,\"n\":\"DMDS - Alternate Textures\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"3D Name\"},{\"t\":3,\"p\":1,\"n\":\"New Texture\"},{\"t\":3,\"p\":1,\"n\":\"3D Index\"}]}]}]},{\"p\":1,\"n\":\"DSTF - End Marker\"}]}]}]},{\"t\":3,\"p\":1,\"n\":\"YNAM - Sound - Pick Up\"},{\"t\":3,\"p\":1,\"n\":\"ZNAM - Sound - Put Down\"},{\"t\":3,\"n\":\"KSIZ - Keyword Count\"},{\"t\":7,\"p\":1,\"n\":\"KWDA - Keywords\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Keyword\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DATA - \",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Value\"},{\"t\":5,\"p\":1,\"n\":\"Weight\"}]},{\"t\":3,\"p\":1,\"n\":\"SOUL - Contained Soul\"},{\"t\":3,\"p\":1,\"n\":\"SLCP - Maximum Capacity\"},{\"t\":3,\"p\":1,\"n\":\"NAM0 - Linked To\"}]},{\"t\":1,\"p\":1,\"n\":\"SMBN - Story Manager Branch Node\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":3,\"p\":1,\"n\":\"PNAM - Parent \"},{\"t\":3,\"p\":1,\"n\":\"SNAM - Child \"},{\"t\":3,\"n\":\"CITC - Condition Count\"},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Conditions\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Condition\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"CTDA - \",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":5,\"p\":1,\"n\":\"Comparison Value - Float\"},{\"t\":3,\"p\":1,\"n\":\"Comparison Value - Global\"},{\"t\":3,\"p\":1,\"n\":\"Function\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":11,\"p\":1,\"n\":\"None\"},{\"t\":3,\"p\":1,\"n\":\"Integer\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":11,\"p\":1,\"n\":\"Variable Name (unused)\"},{\"t\":3,\"p\":1,\"n\":\"Sex\"},{\"t\":3,\"p\":1,\"n\":\"Actor Value\"},{\"t\":3,\"p\":1,\"n\":\"Crime Type\"},{\"t\":3,\"p\":1,\"n\":\"Axis\"},{\"t\":3,\"p\":1,\"n\":\"Quest Stage (unused)\"},{\"t\":3,\"p\":1,\"n\":\"Misc Stat\"},{\"t\":3,\"p\":1,\"n\":\"Alignment\"},{\"t\":3,\"p\":1,\"n\":\"Equip Type\"},{\"t\":3,\"p\":1,\"n\":\"Form Type\"},{\"t\":3,\"p\":1,\"n\":\"Critical Stage\"},{\"t\":3,\"p\":1,\"n\":\"Object Reference\"},{\"t\":3,\"p\":1,\"n\":\"Inventory Object\"},{\"t\":3,\"p\":1,\"n\":\"Actor\"},{\"t\":3,\"p\":1,\"n\":\"Voice Type\"},{\"t\":3,\"p\":1,\"n\":\"Idle\"},{\"t\":3,\"p\":1,\"n\":\"Form List\"},{\"t\":3,\"p\":1,\"n\":\"Quest\"},{\"t\":3,\"p\":1,\"n\":\"Faction\"},{\"t\":3,\"p\":1,\"n\":\"Cell\"},{\"t\":3,\"p\":1,\"n\":\"Class\"},{\"t\":3,\"p\":1,\"n\":\"Race\"},{\"t\":3,\"p\":1,\"n\":\"Actor Base\"},{\"t\":3,\"p\":1,\"n\":\"Global\"},{\"t\":3,\"p\":1,\"n\":\"Weather\"},{\"t\":3,\"p\":1,\"n\":\"Package\"},{\"t\":3,\"p\":1,\"n\":\"Encounter Zone\"},{\"t\":3,\"p\":1,\"n\":\"Perk\"},{\"t\":3,\"p\":1,\"n\":\"Owner\"},{\"t\":3,\"p\":1,\"n\":\"Furniture\"},{\"t\":3,\"p\":1,\"n\":\"Effect Item\"},{\"t\":3,\"p\":1,\"n\":\"Base Effect\"},{\"t\":3,\"p\":1,\"n\":\"Worldspace\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Function\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Param (INVALID)\"},{\"t\":3,\"p\":1,\"n\":\"Referenceable Object\"},{\"t\":3,\"p\":1,\"n\":\"Region\"},{\"t\":3,\"p\":1,\"n\":\"Keyword\"},{\"t\":3,\"p\":1,\"n\":\"Player Action\"},{\"t\":3,\"p\":1,\"n\":\"Casting Type\"},{\"t\":3,\"p\":1,\"n\":\"Shout\"},{\"t\":3,\"p\":1,\"n\":\"Location\"},{\"t\":3,\"p\":1,\"n\":\"Location Ref Type\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"Packdata ID\"},{\"t\":3,\"p\":1,\"n\":\"Association Type\"},{\"t\":3,\"p\":1,\"n\":\"Furniture Anim\"},{\"t\":3,\"p\":1,\"n\":\"Furniture Entry\"},{\"t\":3,\"p\":1,\"n\":\"Scene\"},{\"t\":3,\"p\":1,\"n\":\"Ward State\"},{\"t\":3,\"p\":1,\"n\":\"Event\"},{\"t\":3,\"p\":1,\"n\":\"Event Data\"},{\"t\":3,\"p\":1,\"n\":\"Quest Stage\"},{\"t\":3,\"p\":1,\"n\":\"Weapon\"},{\"t\":3,\"p\":1,\"n\":\"Weapon List\"},{\"t\":3,\"p\":1,\"n\":\"Target\"},{\"t\":3,\"p\":1,\"n\":\"Target List\"},{\"t\":3,\"p\":1,\"n\":\"Target Part\"},{\"t\":3,\"p\":1,\"n\":\"VATS Action\"},{\"t\":3,\"p\":1,\"n\":\"Critical Effect\"},{\"t\":3,\"p\":1,\"n\":\"Critical Effect List\"},{\"t\":3,\"p\":1,\"n\":\"Weapon Type\"},{\"t\":3,\"p\":1,\"n\":\"Projectile Type\"},{\"t\":3,\"p\":1,\"n\":\"Delivery Type\"},{\"t\":3,\"p\":1,\"n\":\"Run On\"},{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":3,\"p\":1,\"n\":\"Parameter #3\"}]},{\"t\":2,\"p\":1,\"n\":\"CIS1 - Parameter #1\"},{\"t\":2,\"p\":1,\"n\":\"CIS2 - Parameter #2\"}]}]},{\"t\":3,\"p\":1,\"n\":\"DNAM - Flags\"},{\"t\":11,\"n\":\"XNAM - Unknown\"}]},{\"t\":1,\"p\":1,\"n\":\"SMEN - Story Manager Event Node\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":3,\"p\":1,\"n\":\"PNAM - Parent \"},{\"t\":3,\"p\":1,\"n\":\"SNAM - Child \"},{\"t\":3,\"n\":\"CITC - Condition Count\"},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Conditions\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Condition\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"CTDA - \",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":5,\"p\":1,\"n\":\"Comparison Value - Float\"},{\"t\":3,\"p\":1,\"n\":\"Comparison Value - Global\"},{\"t\":3,\"p\":1,\"n\":\"Function\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":11,\"p\":1,\"n\":\"None\"},{\"t\":3,\"p\":1,\"n\":\"Integer\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":11,\"p\":1,\"n\":\"Variable Name (unused)\"},{\"t\":3,\"p\":1,\"n\":\"Sex\"},{\"t\":3,\"p\":1,\"n\":\"Actor Value\"},{\"t\":3,\"p\":1,\"n\":\"Crime Type\"},{\"t\":3,\"p\":1,\"n\":\"Axis\"},{\"t\":3,\"p\":1,\"n\":\"Quest Stage (unused)\"},{\"t\":3,\"p\":1,\"n\":\"Misc Stat\"},{\"t\":3,\"p\":1,\"n\":\"Alignment\"},{\"t\":3,\"p\":1,\"n\":\"Equip Type\"},{\"t\":3,\"p\":1,\"n\":\"Form Type\"},{\"t\":3,\"p\":1,\"n\":\"Critical Stage\"},{\"t\":3,\"p\":1,\"n\":\"Object Reference\"},{\"t\":3,\"p\":1,\"n\":\"Inventory Object\"},{\"t\":3,\"p\":1,\"n\":\"Actor\"},{\"t\":3,\"p\":1,\"n\":\"Voice Type\"},{\"t\":3,\"p\":1,\"n\":\"Idle\"},{\"t\":3,\"p\":1,\"n\":\"Form List\"},{\"t\":3,\"p\":1,\"n\":\"Quest\"},{\"t\":3,\"p\":1,\"n\":\"Faction\"},{\"t\":3,\"p\":1,\"n\":\"Cell\"},{\"t\":3,\"p\":1,\"n\":\"Class\"},{\"t\":3,\"p\":1,\"n\":\"Race\"},{\"t\":3,\"p\":1,\"n\":\"Actor Base\"},{\"t\":3,\"p\":1,\"n\":\"Global\"},{\"t\":3,\"p\":1,\"n\":\"Weather\"},{\"t\":3,\"p\":1,\"n\":\"Package\"},{\"t\":3,\"p\":1,\"n\":\"Encounter Zone\"},{\"t\":3,\"p\":1,\"n\":\"Perk\"},{\"t\":3,\"p\":1,\"n\":\"Owner\"},{\"t\":3,\"p\":1,\"n\":\"Furniture\"},{\"t\":3,\"p\":1,\"n\":\"Effect Item\"},{\"t\":3,\"p\":1,\"n\":\"Base Effect\"},{\"t\":3,\"p\":1,\"n\":\"Worldspace\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Function\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Param (INVALID)\"},{\"t\":3,\"p\":1,\"n\":\"Referenceable Object\"},{\"t\":3,\"p\":1,\"n\":\"Region\"},{\"t\":3,\"p\":1,\"n\":\"Keyword\"},{\"t\":3,\"p\":1,\"n\":\"Player Action\"},{\"t\":3,\"p\":1,\"n\":\"Casting Type\"},{\"t\":3,\"p\":1,\"n\":\"Shout\"},{\"t\":3,\"p\":1,\"n\":\"Location\"},{\"t\":3,\"p\":1,\"n\":\"Location Ref Type\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"Packdata ID\"},{\"t\":3,\"p\":1,\"n\":\"Association Type\"},{\"t\":3,\"p\":1,\"n\":\"Furniture Anim\"},{\"t\":3,\"p\":1,\"n\":\"Furniture Entry\"},{\"t\":3,\"p\":1,\"n\":\"Scene\"},{\"t\":3,\"p\":1,\"n\":\"Ward State\"},{\"t\":3,\"p\":1,\"n\":\"Event\"},{\"t\":3,\"p\":1,\"n\":\"Event Data\"},{\"t\":3,\"p\":1,\"n\":\"Quest Stage\"},{\"t\":3,\"p\":1,\"n\":\"Weapon\"},{\"t\":3,\"p\":1,\"n\":\"Weapon List\"},{\"t\":3,\"p\":1,\"n\":\"Target\"},{\"t\":3,\"p\":1,\"n\":\"Target List\"},{\"t\":3,\"p\":1,\"n\":\"Target Part\"},{\"t\":3,\"p\":1,\"n\":\"VATS Action\"},{\"t\":3,\"p\":1,\"n\":\"Critical Effect\"},{\"t\":3,\"p\":1,\"n\":\"Critical Effect List\"},{\"t\":3,\"p\":1,\"n\":\"Weapon Type\"},{\"t\":3,\"p\":1,\"n\":\"Projectile Type\"},{\"t\":3,\"p\":1,\"n\":\"Delivery Type\"},{\"t\":3,\"p\":1,\"n\":\"Run On\"},{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":3,\"p\":1,\"n\":\"Parameter #3\"}]},{\"t\":2,\"p\":1,\"n\":\"CIS1 - Parameter #1\"},{\"t\":2,\"p\":1,\"n\":\"CIS2 - Parameter #2\"}]}]},{\"t\":3,\"p\":1,\"n\":\"DNAM - Flags\"},{\"t\":11,\"n\":\"XNAM - Unknown\"},{\"t\":2,\"p\":1,\"n\":\"ENAM - Type\"}]},{\"t\":1,\"p\":1,\"n\":\"SMQN - Story Manager Quest Node\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":3,\"p\":1,\"n\":\"PNAM - Parent \"},{\"t\":3,\"p\":1,\"n\":\"SNAM - Child \"},{\"t\":3,\"n\":\"CITC - Condition Count\"},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Conditions\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Condition\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"CTDA - \",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":5,\"p\":1,\"n\":\"Comparison Value - Float\"},{\"t\":3,\"p\":1,\"n\":\"Comparison Value - Global\"},{\"t\":3,\"p\":1,\"n\":\"Function\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":11,\"p\":1,\"n\":\"None\"},{\"t\":3,\"p\":1,\"n\":\"Integer\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":11,\"p\":1,\"n\":\"Variable Name (unused)\"},{\"t\":3,\"p\":1,\"n\":\"Sex\"},{\"t\":3,\"p\":1,\"n\":\"Actor Value\"},{\"t\":3,\"p\":1,\"n\":\"Crime Type\"},{\"t\":3,\"p\":1,\"n\":\"Axis\"},{\"t\":3,\"p\":1,\"n\":\"Quest Stage (unused)\"},{\"t\":3,\"p\":1,\"n\":\"Misc Stat\"},{\"t\":3,\"p\":1,\"n\":\"Alignment\"},{\"t\":3,\"p\":1,\"n\":\"Equip Type\"},{\"t\":3,\"p\":1,\"n\":\"Form Type\"},{\"t\":3,\"p\":1,\"n\":\"Critical Stage\"},{\"t\":3,\"p\":1,\"n\":\"Object Reference\"},{\"t\":3,\"p\":1,\"n\":\"Inventory Object\"},{\"t\":3,\"p\":1,\"n\":\"Actor\"},{\"t\":3,\"p\":1,\"n\":\"Voice Type\"},{\"t\":3,\"p\":1,\"n\":\"Idle\"},{\"t\":3,\"p\":1,\"n\":\"Form List\"},{\"t\":3,\"p\":1,\"n\":\"Quest\"},{\"t\":3,\"p\":1,\"n\":\"Faction\"},{\"t\":3,\"p\":1,\"n\":\"Cell\"},{\"t\":3,\"p\":1,\"n\":\"Class\"},{\"t\":3,\"p\":1,\"n\":\"Race\"},{\"t\":3,\"p\":1,\"n\":\"Actor Base\"},{\"t\":3,\"p\":1,\"n\":\"Global\"},{\"t\":3,\"p\":1,\"n\":\"Weather\"},{\"t\":3,\"p\":1,\"n\":\"Package\"},{\"t\":3,\"p\":1,\"n\":\"Encounter Zone\"},{\"t\":3,\"p\":1,\"n\":\"Perk\"},{\"t\":3,\"p\":1,\"n\":\"Owner\"},{\"t\":3,\"p\":1,\"n\":\"Furniture\"},{\"t\":3,\"p\":1,\"n\":\"Effect Item\"},{\"t\":3,\"p\":1,\"n\":\"Base Effect\"},{\"t\":3,\"p\":1,\"n\":\"Worldspace\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Function\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Param (INVALID)\"},{\"t\":3,\"p\":1,\"n\":\"Referenceable Object\"},{\"t\":3,\"p\":1,\"n\":\"Region\"},{\"t\":3,\"p\":1,\"n\":\"Keyword\"},{\"t\":3,\"p\":1,\"n\":\"Player Action\"},{\"t\":3,\"p\":1,\"n\":\"Casting Type\"},{\"t\":3,\"p\":1,\"n\":\"Shout\"},{\"t\":3,\"p\":1,\"n\":\"Location\"},{\"t\":3,\"p\":1,\"n\":\"Location Ref Type\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"Packdata ID\"},{\"t\":3,\"p\":1,\"n\":\"Association Type\"},{\"t\":3,\"p\":1,\"n\":\"Furniture Anim\"},{\"t\":3,\"p\":1,\"n\":\"Furniture Entry\"},{\"t\":3,\"p\":1,\"n\":\"Scene\"},{\"t\":3,\"p\":1,\"n\":\"Ward State\"},{\"t\":3,\"p\":1,\"n\":\"Event\"},{\"t\":3,\"p\":1,\"n\":\"Event Data\"},{\"t\":3,\"p\":1,\"n\":\"Quest Stage\"},{\"t\":3,\"p\":1,\"n\":\"Weapon\"},{\"t\":3,\"p\":1,\"n\":\"Weapon List\"},{\"t\":3,\"p\":1,\"n\":\"Target\"},{\"t\":3,\"p\":1,\"n\":\"Target List\"},{\"t\":3,\"p\":1,\"n\":\"Target Part\"},{\"t\":3,\"p\":1,\"n\":\"VATS Action\"},{\"t\":3,\"p\":1,\"n\":\"Critical Effect\"},{\"t\":3,\"p\":1,\"n\":\"Critical Effect List\"},{\"t\":3,\"p\":1,\"n\":\"Weapon Type\"},{\"t\":3,\"p\":1,\"n\":\"Projectile Type\"},{\"t\":3,\"p\":1,\"n\":\"Delivery Type\"},{\"t\":3,\"p\":1,\"n\":\"Run On\"},{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":3,\"p\":1,\"n\":\"Parameter #3\"}]},{\"t\":2,\"p\":1,\"n\":\"CIS1 - Parameter #1\"},{\"t\":2,\"p\":1,\"n\":\"CIS2 - Parameter #2\"}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DNAM - Flags\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Node Flags\"},{\"t\":3,\"p\":1,\"n\":\"Quest Flags\"}]},{\"t\":3,\"p\":1,\"n\":\"XNAM - Max concurrent quests\"},{\"t\":3,\"p\":1,\"n\":\"MNAM - Num quests to run\"},{\"t\":3,\"n\":\"QNAM - Quest Count\"},{\"t\":10,\"p\":1,\"n\":\"Quests\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Quest\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"NNAM - Quest\"},{\"t\":11,\"n\":\"FNAM - Unknown\"},{\"t\":5,\"p\":1,\"n\":\"RNAM - Hours until reset\"}]}]}]},{\"t\":1,\"p\":1,\"n\":\"SNCT - Sound Category\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":3,\"p\":1,\"n\":\"FNAM - Flags\"},{\"t\":3,\"p\":1,\"n\":\"PNAM - Parent\"},{\"t\":3,\"p\":1,\"n\":\"VNAM - Static Volume Multiplier\"},{\"t\":3,\"p\":1,\"n\":\"UNAM - Default Menu Value\"}]},{\"t\":1,\"p\":1,\"n\":\"SNDR - Sound Descriptor\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":11,\"n\":\"CNAM - Unknown\"},{\"t\":3,\"p\":1,\"n\":\"GNAM - Category\"},{\"t\":3,\"p\":1,\"n\":\"SNAM - Alternate Sound For\"},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Sounds\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Sound Files\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"ANAM - File Name\"}]}]},{\"t\":3,\"p\":1,\"n\":\"ONAM - Output Model\"},{\"t\":2,\"p\":1,\"n\":\"FNAM - String\"},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Conditions\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Condition\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"CTDA - \",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":5,\"p\":1,\"n\":\"Comparison Value - Float\"},{\"t\":3,\"p\":1,\"n\":\"Comparison Value - Global\"},{\"t\":3,\"p\":1,\"n\":\"Function\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":11,\"p\":1,\"n\":\"None\"},{\"t\":3,\"p\":1,\"n\":\"Integer\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":11,\"p\":1,\"n\":\"Variable Name (unused)\"},{\"t\":3,\"p\":1,\"n\":\"Sex\"},{\"t\":3,\"p\":1,\"n\":\"Actor Value\"},{\"t\":3,\"p\":1,\"n\":\"Crime Type\"},{\"t\":3,\"p\":1,\"n\":\"Axis\"},{\"t\":3,\"p\":1,\"n\":\"Quest Stage (unused)\"},{\"t\":3,\"p\":1,\"n\":\"Misc Stat\"},{\"t\":3,\"p\":1,\"n\":\"Alignment\"},{\"t\":3,\"p\":1,\"n\":\"Equip Type\"},{\"t\":3,\"p\":1,\"n\":\"Form Type\"},{\"t\":3,\"p\":1,\"n\":\"Critical Stage\"},{\"t\":3,\"p\":1,\"n\":\"Object Reference\"},{\"t\":3,\"p\":1,\"n\":\"Inventory Object\"},{\"t\":3,\"p\":1,\"n\":\"Actor\"},{\"t\":3,\"p\":1,\"n\":\"Voice Type\"},{\"t\":3,\"p\":1,\"n\":\"Idle\"},{\"t\":3,\"p\":1,\"n\":\"Form List\"},{\"t\":3,\"p\":1,\"n\":\"Quest\"},{\"t\":3,\"p\":1,\"n\":\"Faction\"},{\"t\":3,\"p\":1,\"n\":\"Cell\"},{\"t\":3,\"p\":1,\"n\":\"Class\"},{\"t\":3,\"p\":1,\"n\":\"Race\"},{\"t\":3,\"p\":1,\"n\":\"Actor Base\"},{\"t\":3,\"p\":1,\"n\":\"Global\"},{\"t\":3,\"p\":1,\"n\":\"Weather\"},{\"t\":3,\"p\":1,\"n\":\"Package\"},{\"t\":3,\"p\":1,\"n\":\"Encounter Zone\"},{\"t\":3,\"p\":1,\"n\":\"Perk\"},{\"t\":3,\"p\":1,\"n\":\"Owner\"},{\"t\":3,\"p\":1,\"n\":\"Furniture\"},{\"t\":3,\"p\":1,\"n\":\"Effect Item\"},{\"t\":3,\"p\":1,\"n\":\"Base Effect\"},{\"t\":3,\"p\":1,\"n\":\"Worldspace\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Function\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Param (INVALID)\"},{\"t\":3,\"p\":1,\"n\":\"Referenceable Object\"},{\"t\":3,\"p\":1,\"n\":\"Region\"},{\"t\":3,\"p\":1,\"n\":\"Keyword\"},{\"t\":3,\"p\":1,\"n\":\"Player Action\"},{\"t\":3,\"p\":1,\"n\":\"Casting Type\"},{\"t\":3,\"p\":1,\"n\":\"Shout\"},{\"t\":3,\"p\":1,\"n\":\"Location\"},{\"t\":3,\"p\":1,\"n\":\"Location Ref Type\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"Packdata ID\"},{\"t\":3,\"p\":1,\"n\":\"Association Type\"},{\"t\":3,\"p\":1,\"n\":\"Furniture Anim\"},{\"t\":3,\"p\":1,\"n\":\"Furniture Entry\"},{\"t\":3,\"p\":1,\"n\":\"Scene\"},{\"t\":3,\"p\":1,\"n\":\"Ward State\"},{\"t\":3,\"p\":1,\"n\":\"Event\"},{\"t\":3,\"p\":1,\"n\":\"Event Data\"},{\"t\":3,\"p\":1,\"n\":\"Quest Stage\"},{\"t\":3,\"p\":1,\"n\":\"Weapon\"},{\"t\":3,\"p\":1,\"n\":\"Weapon List\"},{\"t\":3,\"p\":1,\"n\":\"Target\"},{\"t\":3,\"p\":1,\"n\":\"Target List\"},{\"t\":3,\"p\":1,\"n\":\"Target Part\"},{\"t\":3,\"p\":1,\"n\":\"VATS Action\"},{\"t\":3,\"p\":1,\"n\":\"Critical Effect\"},{\"t\":3,\"p\":1,\"n\":\"Critical Effect List\"},{\"t\":3,\"p\":1,\"n\":\"Weapon Type\"},{\"t\":3,\"p\":1,\"n\":\"Projectile Type\"},{\"t\":3,\"p\":1,\"n\":\"Delivery Type\"},{\"t\":3,\"p\":1,\"n\":\"Run On\"},{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":3,\"p\":1,\"n\":\"Parameter #3\"}]},{\"t\":2,\"p\":1,\"n\":\"CIS1 - Parameter #1\"},{\"t\":2,\"p\":1,\"n\":\"CIS2 - Parameter #2\"}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"LNAM - Values\",\"c\":[{\"t\":11,\"n\":\"Unknown\"},{\"t\":3,\"p\":1,\"n\":\"Looping\"},{\"t\":3,\"p\":1,\"n\":\"Rumble Send Value = (Small \\/ 7) + ((Big \\/ 7) * 16)\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"BNAM - Values\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"% Frequency Shift\"},{\"t\":3,\"p\":1,\"n\":\"% Frequency Variance\"},{\"t\":3,\"p\":1,\"n\":\"Priority\"},{\"t\":3,\"p\":1,\"n\":\"db Variance\"},{\"t\":3,\"p\":1,\"n\":\"Static Attenuation (db)\"}]}]},{\"t\":1,\"p\":1,\"n\":\"SOPM - Sound Output Model\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"NAM1 - Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":3,\"p\":1,\"n\":\"Reverb Send %\"}]},{\"t\":11,\"n\":\"FNAM - Unknown\"},{\"t\":3,\"p\":1,\"n\":\"MNAM - Type\"},{\"t\":11,\"n\":\"CNAM - Unknown\"},{\"t\":11,\"n\":\"SNAM - Unknown\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"ONAM - Output Values\",\"c\":[{\"t\":7,\"p\":1,\"n\":\"Channels\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"L\"},{\"t\":3,\"p\":1,\"n\":\"R\"},{\"t\":3,\"p\":1,\"n\":\"C\"},{\"t\":3,\"p\":1,\"n\":\"LFE\"},{\"t\":3,\"p\":1,\"n\":\"RL\"},{\"t\":3,\"p\":1,\"n\":\"RR\"},{\"t\":3,\"p\":1,\"n\":\"BL\"},{\"t\":3,\"p\":1,\"n\":\"BR\"}]}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"ANAM - Attenuation Values\",\"c\":[{\"t\":11,\"n\":\"Unknown\"},{\"t\":5,\"p\":1,\"n\":\"Min Distance\"},{\"t\":5,\"p\":1,\"n\":\"Max Distance\"},{\"t\":7,\"p\":1,\"n\":\"Curve\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Value\"}]}]}]},{\"t\":1,\"p\":1,\"n\":\"SOUN - Sound Marker\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"X1\"},{\"t\":3,\"p\":1,\"n\":\"Y1\"},{\"t\":3,\"p\":1,\"n\":\"Z1\"},{\"t\":3,\"p\":1,\"n\":\"X2\"},{\"t\":3,\"p\":1,\"n\":\"Y2\"},{\"t\":3,\"p\":1,\"n\":\"Z2\"}]},{\"t\":11,\"n\":\"FNAM - Unknown\"},{\"t\":11,\"n\":\"SNDD - Unknown\"},{\"t\":3,\"p\":1,\"n\":\"SDSC - Sound Descriptor\"}]},{\"t\":1,\"p\":1,\"n\":\"SPEL - Spell\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"X1\"},{\"t\":3,\"p\":1,\"n\":\"Y1\"},{\"t\":3,\"p\":1,\"n\":\"Z1\"},{\"t\":3,\"p\":1,\"n\":\"X2\"},{\"t\":3,\"p\":1,\"n\":\"Y2\"},{\"t\":3,\"p\":1,\"n\":\"Z2\"}]},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":3,\"n\":\"KSIZ - Keyword Count\"},{\"t\":7,\"p\":1,\"n\":\"KWDA - Keywords\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Keyword\"}]},{\"t\":3,\"p\":1,\"n\":\"MDOB - Menu Display Object\"},{\"t\":3,\"p\":1,\"n\":\"ETYP - Equipment Type\"},{\"t\":2,\"p\":1,\"n\":\"DESC - Description\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"SPIT - Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Base Cost\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":5,\"p\":1,\"n\":\"Charge Time\"},{\"t\":3,\"p\":1,\"n\":\"Cast Type\"},{\"t\":3,\"p\":1,\"n\":\"Target Type\"},{\"t\":5,\"p\":1,\"n\":\"Cast Duration\"},{\"t\":5,\"p\":1,\"n\":\"Range\"},{\"t\":3,\"p\":1,\"n\":\"Half-cost Perk\"}]},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Effects\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Effect\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"EFID - Base Effect\"},{\"t\":6,\"p\":1,\"n\":\"EFIT - \",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Magnitude\"},{\"t\":3,\"p\":1,\"n\":\"Area\"},{\"t\":3,\"p\":1,\"n\":\"Duration\"}]},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Conditions\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Condition\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"CTDA - \",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":5,\"p\":1,\"n\":\"Comparison Value - Float\"},{\"t\":3,\"p\":1,\"n\":\"Comparison Value - Global\"},{\"t\":3,\"p\":1,\"n\":\"Function\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":11,\"p\":1,\"n\":\"None\"},{\"t\":3,\"p\":1,\"n\":\"Integer\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":11,\"p\":1,\"n\":\"Variable Name (unused)\"},{\"t\":3,\"p\":1,\"n\":\"Sex\"},{\"t\":3,\"p\":1,\"n\":\"Actor Value\"},{\"t\":3,\"p\":1,\"n\":\"Crime Type\"},{\"t\":3,\"p\":1,\"n\":\"Axis\"},{\"t\":3,\"p\":1,\"n\":\"Quest Stage (unused)\"},{\"t\":3,\"p\":1,\"n\":\"Misc Stat\"},{\"t\":3,\"p\":1,\"n\":\"Alignment\"},{\"t\":3,\"p\":1,\"n\":\"Equip Type\"},{\"t\":3,\"p\":1,\"n\":\"Form Type\"},{\"t\":3,\"p\":1,\"n\":\"Critical Stage\"},{\"t\":3,\"p\":1,\"n\":\"Object Reference\"},{\"t\":3,\"p\":1,\"n\":\"Inventory Object\"},{\"t\":3,\"p\":1,\"n\":\"Actor\"},{\"t\":3,\"p\":1,\"n\":\"Voice Type\"},{\"t\":3,\"p\":1,\"n\":\"Idle\"},{\"t\":3,\"p\":1,\"n\":\"Form List\"},{\"t\":3,\"p\":1,\"n\":\"Quest\"},{\"t\":3,\"p\":1,\"n\":\"Faction\"},{\"t\":3,\"p\":1,\"n\":\"Cell\"},{\"t\":3,\"p\":1,\"n\":\"Class\"},{\"t\":3,\"p\":1,\"n\":\"Race\"},{\"t\":3,\"p\":1,\"n\":\"Actor Base\"},{\"t\":3,\"p\":1,\"n\":\"Global\"},{\"t\":3,\"p\":1,\"n\":\"Weather\"},{\"t\":3,\"p\":1,\"n\":\"Package\"},{\"t\":3,\"p\":1,\"n\":\"Encounter Zone\"},{\"t\":3,\"p\":1,\"n\":\"Perk\"},{\"t\":3,\"p\":1,\"n\":\"Owner\"},{\"t\":3,\"p\":1,\"n\":\"Furniture\"},{\"t\":3,\"p\":1,\"n\":\"Effect Item\"},{\"t\":3,\"p\":1,\"n\":\"Base Effect\"},{\"t\":3,\"p\":1,\"n\":\"Worldspace\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Function\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Param (INVALID)\"},{\"t\":3,\"p\":1,\"n\":\"Referenceable Object\"},{\"t\":3,\"p\":1,\"n\":\"Region\"},{\"t\":3,\"p\":1,\"n\":\"Keyword\"},{\"t\":3,\"p\":1,\"n\":\"Player Action\"},{\"t\":3,\"p\":1,\"n\":\"Casting Type\"},{\"t\":3,\"p\":1,\"n\":\"Shout\"},{\"t\":3,\"p\":1,\"n\":\"Location\"},{\"t\":3,\"p\":1,\"n\":\"Location Ref Type\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"Packdata ID\"},{\"t\":3,\"p\":1,\"n\":\"Association Type\"},{\"t\":3,\"p\":1,\"n\":\"Furniture Anim\"},{\"t\":3,\"p\":1,\"n\":\"Furniture Entry\"},{\"t\":3,\"p\":1,\"n\":\"Scene\"},{\"t\":3,\"p\":1,\"n\":\"Ward State\"},{\"t\":3,\"p\":1,\"n\":\"Event\"},{\"t\":3,\"p\":1,\"n\":\"Event Data\"},{\"t\":3,\"p\":1,\"n\":\"Quest Stage\"},{\"t\":3,\"p\":1,\"n\":\"Weapon\"},{\"t\":3,\"p\":1,\"n\":\"Weapon List\"},{\"t\":3,\"p\":1,\"n\":\"Target\"},{\"t\":3,\"p\":1,\"n\":\"Target List\"},{\"t\":3,\"p\":1,\"n\":\"Target Part\"},{\"t\":3,\"p\":1,\"n\":\"VATS Action\"},{\"t\":3,\"p\":1,\"n\":\"Critical Effect\"},{\"t\":3,\"p\":1,\"n\":\"Critical Effect List\"},{\"t\":3,\"p\":1,\"n\":\"Weapon Type\"},{\"t\":3,\"p\":1,\"n\":\"Projectile Type\"},{\"t\":3,\"p\":1,\"n\":\"Delivery Type\"},{\"t\":3,\"p\":1,\"n\":\"Run On\"},{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":3,\"p\":1,\"n\":\"Parameter #3\"}]},{\"t\":2,\"p\":1,\"n\":\"CIS1 - Parameter #1\"},{\"t\":2,\"p\":1,\"n\":\"CIS2 - Parameter #2\"}]}]}]}]}]},{\"t\":1,\"p\":1,\"n\":\"SPGD - Shader Particle Geometry\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Data\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Gravity Velocity\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":5,\"p\":1,\"n\":\"Rotation Velocity\"},{\"t\":5,\"p\":1,\"n\":\"Particle Size X\"},{\"t\":5,\"p\":1,\"n\":\"Center Offset Min\"},{\"t\":5,\"p\":1,\"n\":\"Particle Size Y\"},{\"t\":5,\"p\":1,\"n\":\"Center Offset Max\"},{\"t\":5,\"p\":1,\"n\":\"Initial Rotation\"},{\"t\":3,\"p\":1,\"n\":\"# of Subtextures X\"},{\"t\":3,\"p\":1,\"n\":\"# of Subtextures Y\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Box Size\"},{\"t\":5,\"p\":1,\"n\":\"Particle Density\"}]},{\"t\":2,\"p\":1,\"n\":\"ICON - Particle Texture\"}]},{\"t\":1,\"p\":1,\"n\":\"STAT - Static\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"X1\"},{\"t\":3,\"p\":1,\"n\":\"Y1\"},{\"t\":3,\"p\":1,\"n\":\"Z1\"},{\"t\":3,\"p\":1,\"n\":\"X2\"},{\"t\":3,\"p\":1,\"n\":\"Y2\"},{\"t\":3,\"p\":1,\"n\":\"Z2\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"MODT - Texture Files Hashes\"},{\"t\":7,\"p\":1,\"n\":\"MODS - Alternate Textures\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"3D Name\"},{\"t\":3,\"p\":1,\"n\":\"New Texture\"},{\"t\":3,\"p\":1,\"n\":\"3D Index\"}]}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DNAM - Direction Material\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Max Angle (30-120)\"},{\"t\":3,\"p\":1,\"n\":\"Material\"}]},{\"t\":7,\"p\":1,\"n\":\"MNAM - Distant LOD\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"LOD\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"Mesh\"}]}]}]},{\"t\":1,\"p\":1,\"n\":\"TACT - Talking Activator\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"VMAD - Virtual Machine Adapter\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Version\"},{\"t\":3,\"p\":1,\"n\":\"Object Format\"},{\"t\":7,\"p\":1,\"n\":\"Scripts\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Script\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"scriptName\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":7,\"p\":1,\"n\":\"Properties\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Property\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"propertyName\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]},{\"t\":2,\"p\":1,\"n\":\"String\"},{\"t\":3,\"p\":1,\"n\":\"Int32\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":3,\"p\":1,\"n\":\"Bool\"},{\"t\":7,\"p\":1,\"n\":\"Array of Object\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]}]},{\"t\":7,\"p\":1,\"n\":\"Array of String\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Int32\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Float\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Bool\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]}]}]}]}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"X1\"},{\"t\":3,\"p\":1,\"n\":\"Y1\"},{\"t\":3,\"p\":1,\"n\":\"Z1\"},{\"t\":3,\"p\":1,\"n\":\"X2\"},{\"t\":3,\"p\":1,\"n\":\"Y2\"},{\"t\":3,\"p\":1,\"n\":\"Z2\"}]},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"MODT - Texture Files Hashes\"},{\"t\":7,\"p\":1,\"n\":\"MODS - Alternate Textures\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"3D Name\"},{\"t\":3,\"p\":1,\"n\":\"New Texture\"},{\"t\":3,\"p\":1,\"n\":\"3D Index\"}]}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Destructable\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"DEST - Header\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Health\"},{\"t\":3,\"p\":1,\"n\":\"DEST Count\"},{\"t\":3,\"p\":1,\"n\":\"VATS Targetable\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":8,\"p\":1,\"n\":\"Stages\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Stage\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"DSTD - Destruction Stage Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Health %\"},{\"t\":3,\"p\":1,\"n\":\"Index\"},{\"t\":3,\"p\":1,\"n\":\"Model Damage Stage\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":3,\"p\":1,\"n\":\"Self Damage per Second\"},{\"t\":3,\"p\":1,\"n\":\"Explosion\"},{\"t\":3,\"p\":1,\"n\":\"Debris\"},{\"t\":3,\"p\":1,\"n\":\"Debris Count\"}]},{\"t\":6,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"DMDL - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"DMDT - Texture Files Hashes\"},{\"t\":7,\"p\":1,\"n\":\"DMDS - Alternate Textures\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"3D Name\"},{\"t\":3,\"p\":1,\"n\":\"New Texture\"},{\"t\":3,\"p\":1,\"n\":\"3D Index\"}]}]}]},{\"p\":1,\"n\":\"DSTF - End Marker\"}]}]}]},{\"t\":3,\"n\":\"KSIZ - Keyword Count\"},{\"t\":7,\"p\":1,\"n\":\"KWDA - Keywords\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Keyword\"}]},{\"t\":11,\"n\":\"PNAM - Unknown\"},{\"t\":3,\"p\":1,\"n\":\"SNAM - Looping Sound\"},{\"t\":11,\"n\":\"FNAM - Unknown\"},{\"t\":3,\"p\":1,\"n\":\"VNAM - Voice Type\"}]},{\"t\":1,\"p\":1,\"n\":\"TREE - Tree\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"VMAD - Virtual Machine Adapter\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Version\"},{\"t\":3,\"p\":1,\"n\":\"Object Format\"},{\"t\":7,\"p\":1,\"n\":\"Scripts\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Script\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"scriptName\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":7,\"p\":1,\"n\":\"Properties\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Property\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"propertyName\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]},{\"t\":2,\"p\":1,\"n\":\"String\"},{\"t\":3,\"p\":1,\"n\":\"Int32\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":3,\"p\":1,\"n\":\"Bool\"},{\"t\":7,\"p\":1,\"n\":\"Array of Object\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]}]},{\"t\":7,\"p\":1,\"n\":\"Array of String\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Int32\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Float\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Bool\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]}]}]}]}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"X1\"},{\"t\":3,\"p\":1,\"n\":\"Y1\"},{\"t\":3,\"p\":1,\"n\":\"Z1\"},{\"t\":3,\"p\":1,\"n\":\"X2\"},{\"t\":3,\"p\":1,\"n\":\"Y2\"},{\"t\":3,\"p\":1,\"n\":\"Z2\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"MODT - Texture Files Hashes\"},{\"t\":7,\"p\":1,\"n\":\"MODS - Alternate Textures\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"3D Name\"},{\"t\":3,\"p\":1,\"n\":\"New Texture\"},{\"t\":3,\"p\":1,\"n\":\"3D Index\"}]}]}]},{\"t\":3,\"p\":1,\"n\":\"PFIG - Ingredient\"},{\"t\":3,\"p\":1,\"n\":\"SNAM - Harvest Sound\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"PFPC - Ingredient Production\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Spring\"},{\"t\":3,\"p\":1,\"n\":\"Summer\"},{\"t\":3,\"p\":1,\"n\":\"Fall\"},{\"t\":3,\"p\":1,\"n\":\"Winter\"}]},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"CNAM - Tree Data\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Trunk Flexibility\"},{\"t\":5,\"p\":1,\"n\":\"Branch Flexibility\"},{\"t\":5,\"n\":\"Unknown\"},{\"t\":5,\"p\":1,\"n\":\"Leaf Amplitude\"},{\"t\":5,\"p\":1,\"n\":\"Leaf Frequency\"}]}]},{\"t\":1,\"p\":1,\"n\":\"TXST - Texture Set\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"X1\"},{\"t\":3,\"p\":1,\"n\":\"Y1\"},{\"t\":3,\"p\":1,\"n\":\"Z1\"},{\"t\":3,\"p\":1,\"n\":\"X2\"},{\"t\":3,\"p\":1,\"n\":\"Y2\"},{\"t\":3,\"p\":1,\"n\":\"Z2\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Textures (RGB\\/A)\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"TX00 - Difuse\"},{\"t\":2,\"p\":1,\"n\":\"TX01 - Normal\\/Gloss\"},{\"t\":2,\"p\":1,\"n\":\"TX02 - Environment Mask\\/Subsurface Tint\"},{\"t\":2,\"p\":1,\"n\":\"TX03 - Glow\\/Detail Map\"},{\"t\":2,\"p\":1,\"n\":\"TX04 - Height\"},{\"t\":2,\"p\":1,\"n\":\"TX05 - Environment\"},{\"t\":2,\"p\":1,\"n\":\"TX06 - Multilayer\"},{\"t\":2,\"p\":1,\"n\":\"TX07 - Backlight Mask\\/Specular\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DODT - Decal Data\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Min Width\"},{\"t\":5,\"p\":1,\"n\":\"Max Width\"},{\"t\":5,\"p\":1,\"n\":\"Min Height\"},{\"t\":5,\"p\":1,\"n\":\"Max Height\"},{\"t\":5,\"p\":1,\"n\":\"Depth\"},{\"t\":5,\"p\":1,\"n\":\"Shininess\"},{\"t\":6,\"p\":1,\"n\":\"Parallax\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Scale\"},{\"t\":3,\"p\":1,\"n\":\"Passes\"}]},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":6,\"p\":1,\"n\":\"Color\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]}]},{\"t\":3,\"p\":1,\"n\":\"DNAM - Flags\"}]},{\"t\":1,\"p\":1,\"n\":\"VOLI - Volumetric Lighting\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":5,\"p\":1,\"n\":\"CNAM - Intensity\"},{\"t\":5,\"p\":1,\"n\":\"DNAM - Custom Color - Contribution\"},{\"t\":5,\"p\":1,\"n\":\"ENAM - Red\"},{\"t\":5,\"p\":1,\"n\":\"FNAM - Green\"},{\"t\":5,\"p\":1,\"n\":\"GNAM - Blue\"},{\"t\":5,\"p\":1,\"n\":\"HNAM - Density - Contribution\"},{\"t\":5,\"p\":1,\"n\":\"INAM - Density - Size\"},{\"t\":5,\"p\":1,\"n\":\"JNAM - Density - Wind Speed\"},{\"t\":5,\"p\":1,\"n\":\"KNAM - Density - Falling Speed\"},{\"t\":5,\"p\":1,\"n\":\"LNAM - Phase Function - Contribution\"},{\"t\":5,\"p\":1,\"n\":\"MNAM - Phase Function - Scattering\"},{\"t\":5,\"p\":1,\"n\":\"NNAM - Sampling Repartition - Range Factor\"}]},{\"t\":1,\"p\":1,\"n\":\"VTYP - Voice Type\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":3,\"p\":1,\"n\":\"DNAM - Flags\"}]},{\"t\":1,\"p\":1,\"n\":\"WATR - Water\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":8,\"n\":\"Unused\",\"c\":[{\"t\":2,\"n\":\"NNAM - Noise Map\"}]},{\"t\":3,\"p\":1,\"n\":\"ANAM - Opacity\"},{\"t\":3,\"p\":1,\"n\":\"FNAM - Flags\"},{\"t\":11,\"n\":\"MNAM - Unused\"},{\"t\":3,\"p\":1,\"n\":\"TNAM - Material\"},{\"t\":3,\"p\":1,\"n\":\"SNAM - Open Sound\"},{\"t\":3,\"p\":1,\"n\":\"XNAM - Spell\"},{\"t\":3,\"p\":1,\"n\":\"INAM - Image Space\"},{\"t\":3,\"p\":1,\"n\":\"DATA - Damage Per Second\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DNAM - Visual Data\",\"c\":[{\"t\":5,\"n\":\"Unknown\"},{\"t\":5,\"p\":1,\"n\":\"Specular Properties - Sun Specular Power\"},{\"t\":5,\"p\":1,\"n\":\"Water Properties - Reflectivity Amount\"},{\"t\":5,\"p\":1,\"n\":\"Water Properties - Fresnel Amount\"},{\"t\":5,\"p\":1,\"n\":\"Fog Properties - Above Water - Fog Distance - Near Plane\"},{\"t\":5,\"p\":1,\"n\":\"Fog Properties - Above Water - Fog Distance - Far Plane\"},{\"t\":6,\"p\":1,\"n\":\"Shallow Color\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Deep Color\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Reflection Color\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":5,\"p\":1,\"n\":\"Displacement Simulator - Starting Size\"},{\"t\":5,\"p\":1,\"n\":\"Displacement Simulator - Force\"},{\"t\":5,\"p\":1,\"n\":\"Displacement Simulator - Velocity\"},{\"t\":5,\"p\":1,\"n\":\"Displacement Simulator - Falloff\"},{\"t\":5,\"p\":1,\"n\":\"Displacement Simulator - Dampner\"},{\"t\":5,\"p\":1,\"n\":\"Noise Properties - Noise Falloff\"},{\"t\":5,\"p\":1,\"n\":\"Noise Properties - Layer One - Wind Direction\"},{\"t\":5,\"p\":1,\"n\":\"Noise Properties - Layer Two - Wind Direction\"},{\"t\":5,\"p\":1,\"n\":\"Noise Properties - Layer Three - Wind Direction\"},{\"t\":5,\"p\":1,\"n\":\"Noise Properties - Layer One - Wind Speed\"},{\"t\":5,\"p\":1,\"n\":\"Noise Properties - Layer Two - Wind Speed\"},{\"t\":5,\"p\":1,\"n\":\"Noise Properties - Layer Three - Wind Speed\"},{\"t\":5,\"p\":1,\"n\":\"Fog Properties - Above Water - Fog Amount\"},{\"t\":5,\"p\":1,\"n\":\"Fog Properties - Under Water - Fog Amount\"},{\"t\":5,\"p\":1,\"n\":\"Fog Properties - Under Water - Fog Distance - Near Plane\"},{\"t\":5,\"p\":1,\"n\":\"Fog Properties - Under Water - Fog Distance - Far Plane\"},{\"t\":5,\"p\":1,\"n\":\"Water Properties - Refraction Magnitude\"},{\"t\":5,\"p\":1,\"n\":\"Specular Properties - Specular Power\"},{\"t\":5,\"p\":1,\"n\":\"Specular Properties - Specular Radius\"},{\"t\":5,\"p\":1,\"n\":\"Specular Properties - Specular Brightness\"},{\"t\":5,\"p\":1,\"n\":\"Noise Properties - Layer One - UV Scale\"},{\"t\":5,\"p\":1,\"n\":\"Noise Properties - Layer Two - UV Scale\"},{\"t\":5,\"p\":1,\"n\":\"Noise Properties - Layer Three - UV Scale\"},{\"t\":5,\"p\":1,\"n\":\"Noise Properties - Layer One - Amplitude Scale\"},{\"t\":5,\"p\":1,\"n\":\"Noise Properties - Layer Two - Amplitude Scale\"},{\"t\":5,\"p\":1,\"n\":\"Noise Properties - Layer Three - Amplitude Scale\"},{\"t\":5,\"p\":1,\"n\":\"Water Properties - Reflection Magnitude\"},{\"t\":5,\"p\":1,\"n\":\"Specular Properties - Sun Sparkle Magnitude\"},{\"t\":5,\"p\":1,\"n\":\"Specular Properties - Sun Specular Magnitude\"},{\"t\":5,\"p\":1,\"n\":\"Depth Properties - Reflections\"},{\"t\":5,\"p\":1,\"n\":\"Depth Properties - Refraction\"},{\"t\":5,\"p\":1,\"n\":\"Depth Properties - Normals\"},{\"t\":5,\"p\":1,\"n\":\"Depth Properties - Specular Lighting\"},{\"t\":5,\"p\":1,\"n\":\"Specular Properties - Sun Sparkle Power\"}]},{\"t\":11,\"n\":\"GNAM - Unused\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"NAM0 - Linear Velocity\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"X\"},{\"t\":5,\"p\":1,\"n\":\"Y\"},{\"t\":5,\"p\":1,\"n\":\"Z\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"NAM1 - Angular Velocity\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"X\"},{\"t\":5,\"p\":1,\"n\":\"Y\"},{\"t\":5,\"p\":1,\"n\":\"Z\"}]},{\"t\":2,\"p\":1,\"n\":\"NAM2 - Noise Layer One - Noise Texture\"},{\"t\":2,\"p\":1,\"n\":\"NAM3 - Noise Layer Two - Noise Texture\"},{\"t\":2,\"p\":1,\"n\":\"NAM4 - Noise Layer Three - Noise Texture\"},{\"t\":2,\"p\":1,\"n\":\"NAM5 - Flow Normals - Noise Texture\"}]},{\"t\":1,\"p\":1,\"n\":\"WEAP - Weapon\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"VMAD - Virtual Machine Adapter\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Version\"},{\"t\":3,\"p\":1,\"n\":\"Object Format\"},{\"t\":7,\"p\":1,\"n\":\"Scripts\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Script\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"scriptName\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":7,\"p\":1,\"n\":\"Properties\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Property\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"propertyName\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]},{\"t\":2,\"p\":1,\"n\":\"String\"},{\"t\":3,\"p\":1,\"n\":\"Int32\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":3,\"p\":1,\"n\":\"Bool\"},{\"t\":7,\"p\":1,\"n\":\"Array of Object\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]}]},{\"t\":7,\"p\":1,\"n\":\"Array of String\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Int32\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Float\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Bool\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]}]}]}]}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"X1\"},{\"t\":3,\"p\":1,\"n\":\"Y1\"},{\"t\":3,\"p\":1,\"n\":\"Z1\"},{\"t\":3,\"p\":1,\"n\":\"X2\"},{\"t\":3,\"p\":1,\"n\":\"Y2\"},{\"t\":3,\"p\":1,\"n\":\"Z2\"}]},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"MODT - Texture Files Hashes\"},{\"t\":7,\"p\":1,\"n\":\"MODS - Alternate Textures\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"3D Name\"},{\"t\":3,\"p\":1,\"n\":\"New Texture\"},{\"t\":3,\"p\":1,\"n\":\"3D Index\"}]}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Icon\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"ICON - Large Icon filename\"},{\"t\":2,\"p\":1,\"n\":\"MICO - Small Icon filename\"}]},{\"t\":3,\"p\":1,\"n\":\"EITM - Object Effect\"},{\"t\":3,\"p\":1,\"n\":\"EAMT - Enchantment Amount\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Destructable\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"DEST - Header\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Health\"},{\"t\":3,\"p\":1,\"n\":\"DEST Count\"},{\"t\":3,\"p\":1,\"n\":\"VATS Targetable\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":8,\"p\":1,\"n\":\"Stages\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Stage\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"DSTD - Destruction Stage Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Health %\"},{\"t\":3,\"p\":1,\"n\":\"Index\"},{\"t\":3,\"p\":1,\"n\":\"Model Damage Stage\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":3,\"p\":1,\"n\":\"Self Damage per Second\"},{\"t\":3,\"p\":1,\"n\":\"Explosion\"},{\"t\":3,\"p\":1,\"n\":\"Debris\"},{\"t\":3,\"p\":1,\"n\":\"Debris Count\"}]},{\"t\":6,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"DMDL - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"DMDT - Texture Files Hashes\"},{\"t\":7,\"p\":1,\"n\":\"DMDS - Alternate Textures\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"3D Name\"},{\"t\":3,\"p\":1,\"n\":\"New Texture\"},{\"t\":3,\"p\":1,\"n\":\"3D Index\"}]}]}]},{\"p\":1,\"n\":\"DSTF - End Marker\"}]}]}]},{\"t\":3,\"p\":1,\"n\":\"ETYP - Equipment Type\"},{\"t\":3,\"p\":1,\"n\":\"BIDS - Block Bash Impact Data Set\"},{\"t\":3,\"p\":1,\"n\":\"BAMT - Alternate Block Material\"},{\"t\":3,\"p\":1,\"n\":\"YNAM - Sound - Pick Up\"},{\"t\":3,\"p\":1,\"n\":\"ZNAM - Sound - Put Down\"},{\"t\":3,\"n\":\"KSIZ - Keyword Count\"},{\"t\":7,\"p\":1,\"n\":\"KWDA - Keywords\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Keyword\"}]},{\"t\":2,\"p\":1,\"n\":\"DESC - Description\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Has Scope\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MOD3 - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"MO3T - Texture Files Hashes\"},{\"t\":7,\"p\":1,\"n\":\"MO3S - Alternate Textures\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"3D Name\"},{\"t\":3,\"p\":1,\"n\":\"New Texture\"},{\"t\":3,\"p\":1,\"n\":\"3D Index\"}]}]}]},{\"t\":11,\"n\":\"NNAM - Unused\"},{\"t\":3,\"p\":1,\"n\":\"INAM - Impact Data Set\"},{\"t\":3,\"p\":1,\"n\":\"WNAM - 1st Person Model Object\"},{\"t\":3,\"p\":1,\"n\":\"SNAM - Attack Sound\"},{\"t\":3,\"p\":1,\"n\":\"XNAM - Attack Sound 2D\"},{\"t\":3,\"p\":1,\"n\":\"NAM7 - Attack Loop Sound\"},{\"t\":3,\"p\":1,\"n\":\"TNAM - Attack Fail Sound\"},{\"t\":3,\"p\":1,\"n\":\"UNAM - Idle Sound\"},{\"t\":3,\"p\":1,\"n\":\"NAM9 - Equip Sound\"},{\"t\":3,\"p\":1,\"n\":\"NAM8 - Unequip Sound\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DATA - Game Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Value\"},{\"t\":5,\"p\":1,\"n\":\"Weight\"},{\"t\":3,\"p\":1,\"n\":\"Damage\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DNAM - Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Animation Type\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":5,\"p\":1,\"n\":\"Speed\"},{\"t\":5,\"p\":1,\"n\":\"Reach\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":5,\"p\":1,\"n\":\"Sight FOV\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":3,\"p\":1,\"n\":\"Base VATS To-Hit Chance\"},{\"t\":3,\"p\":1,\"n\":\"Attack Animation\"},{\"t\":3,\"p\":1,\"n\":\"# Projectiles\"},{\"t\":3,\"p\":1,\"n\":\"Embedded Weapon AV (unused)\"},{\"t\":5,\"p\":1,\"n\":\"Range Min\"},{\"t\":5,\"p\":1,\"n\":\"Range Max\"},{\"t\":3,\"p\":1,\"n\":\"On Hit\"},{\"t\":3,\"p\":1,\"n\":\"Flags2\"},{\"t\":5,\"p\":1,\"n\":\"Animation Attack Mult\"},{\"t\":5,\"p\":1,\"n\":\"Rumble - Left Motor Strength\"},{\"t\":5,\"p\":1,\"n\":\"Rumble - Right Motor Strength\"},{\"t\":5,\"p\":1,\"n\":\"Rumble - Duration\"},{\"t\":3,\"p\":1,\"n\":\"Skill\"},{\"t\":3,\"p\":1,\"n\":\"Resist\"},{\"t\":5,\"p\":1,\"n\":\"Stagger\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"CRDT - Critical Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Damage\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":5,\"p\":1,\"n\":\"% Mult\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Effect\"}]},{\"t\":3,\"p\":1,\"n\":\"VNAM - Detection Sound Level\"},{\"t\":3,\"p\":1,\"n\":\"CNAM - Template\"}]},{\"t\":1,\"p\":1,\"n\":\"WOOP - Word of Power\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":2,\"p\":1,\"n\":\"TNAM - Translation\"}]},{\"t\":1,\"p\":1,\"n\":\"WRLD - Worldspace\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":8,\"n\":\"Unused RNAM\",\"c\":[{\"t\":6,\"n\":\"RNAM - Grid\",\"c\":[{\"t\":3,\"n\":\"Y\"},{\"t\":3,\"n\":\"X\"},{\"t\":7,\"n\":\"References\",\"c\":[{\"t\":6,\"n\":\"Reference\",\"c\":[{\"t\":3,\"n\":\"Ref\"},{\"t\":3,\"n\":\"Y\"},{\"t\":3,\"n\":\"X\"}]}]}]}]},{\"t\":11,\"n\":\"MHDT - Max Height Data\"},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"WCTR - Fixed Dimensions Center Cell\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"X\"},{\"t\":3,\"p\":1,\"n\":\"Y\"}]},{\"t\":3,\"p\":1,\"n\":\"LTMP - Interior Lighting\"},{\"t\":3,\"p\":1,\"n\":\"XEZN - Encounter Zone\"},{\"t\":3,\"p\":1,\"n\":\"XLCN - Location\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Parent\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"WNAM - Worldspace\"},{\"t\":6,\"p\":1,\"n\":\"PNAM - \",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unknown\"}]}]},{\"t\":3,\"p\":1,\"n\":\"CNAM - Climate\"},{\"t\":3,\"p\":1,\"n\":\"NAM2 - Water\"},{\"t\":3,\"p\":1,\"n\":\"NAM3 - LOD Water Type\"},{\"t\":5,\"p\":1,\"n\":\"NAM4 - LOD Water Height\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DNAM - Land Data\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Default Land Height\"},{\"t\":5,\"p\":1,\"n\":\"Default Water Height\"}]},{\"t\":2,\"p\":1,\"n\":\"ICON - Map Image\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Cloud Model\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"MODT - Texture Files Hashes\"},{\"t\":7,\"p\":1,\"n\":\"MODS - Alternate Textures\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"3D Name\"},{\"t\":3,\"p\":1,\"n\":\"New Texture\"},{\"t\":3,\"p\":1,\"n\":\"3D Index\"}]}]}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"MNAM - Map Data\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Usable Dimensions\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"X\"},{\"t\":3,\"p\":1,\"n\":\"Y\"}]},{\"t\":6,\"p\":1,\"n\":\"Cell Coordinates\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"NW Cell\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"X\"},{\"t\":3,\"p\":1,\"n\":\"Y\"}]},{\"t\":6,\"p\":1,\"n\":\"SE Cell\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"X\"},{\"t\":3,\"p\":1,\"n\":\"Y\"}]}]},{\"t\":6,\"p\":1,\"n\":\"Camera Data\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Min Height\"},{\"t\":5,\"p\":1,\"n\":\"Max Height\"},{\"t\":5,\"p\":1,\"n\":\"Initial Pitch\"}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"ONAM - World Map Offset Data\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"World Map Scale\"},{\"t\":5,\"p\":1,\"n\":\"Cell X Offset\"},{\"t\":5,\"p\":1,\"n\":\"Cell Y Offset\"},{\"t\":5,\"p\":1,\"n\":\"Cell Z Offset\"}]},{\"t\":5,\"p\":1,\"n\":\"NAMA - Distant LOD Multiplier\"},{\"t\":3,\"p\":1,\"n\":\"DATA - Flags\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Object Bounds\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"NAM0 - Min\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"X\"},{\"t\":5,\"p\":1,\"n\":\"Y\"}]},{\"t\":6,\"p\":1,\"n\":\"NAM9 - Max\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"X\"},{\"t\":5,\"p\":1,\"n\":\"Y\"}]}]},{\"t\":3,\"p\":1,\"n\":\"ZNAM - Music\"},{\"t\":2,\"p\":1,\"n\":\"NNAM - Canopy Shadow (unused)\"},{\"t\":2,\"p\":1,\"n\":\"XNAM - Water Noise Texture\"},{\"t\":2,\"p\":1,\"n\":\"TNAM - HD LOD Diffuse Texture\"},{\"t\":2,\"p\":1,\"n\":\"UNAM - HD LOD Normal Texture\"},{\"t\":2,\"p\":1,\"n\":\"XWEM - Water Environment Map (unused)\"},{\"t\":11,\"n\":\"OFST - Offset Data\"}]},{\"t\":1,\"p\":1,\"n\":\"WTHR - Weather\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"p\":1,\"n\":\"00TX - Cloud Texture Layer #0\"},{\"t\":2,\"p\":1,\"n\":\"10TX - Cloud Texture Layer #1\"},{\"t\":2,\"p\":1,\"n\":\"20TX - Cloud Texture Layer #2\"},{\"t\":2,\"p\":1,\"n\":\"30TX - Cloud Texture Layer #3\"},{\"t\":2,\"p\":1,\"n\":\"40TX - Cloud Texture Layer #4\"},{\"t\":2,\"p\":1,\"n\":\"50TX - Cloud Texture Layer #5\"},{\"t\":2,\"p\":1,\"n\":\"60TX - Cloud Texture Layer #6\"},{\"t\":2,\"p\":1,\"n\":\"70TX - Cloud Texture Layer #7\"},{\"t\":2,\"p\":1,\"n\":\"80TX - Cloud Texture Layer #8\"},{\"t\":2,\"p\":1,\"n\":\"90TX - Cloud Texture Layer #9\"},{\"t\":2,\"p\":1,\"n\":\":0TX - Cloud Texture Layer #10\"},{\"t\":2,\"p\":1,\"n\":\";0TX - Cloud Texture Layer #11\"},{\"t\":2,\"p\":1,\"n\":\"<0TX - Cloud Texture Layer #12\"},{\"t\":2,\"p\":1,\"n\":\"=0TX - Cloud Texture Layer #13\"},{\"t\":2,\"p\":1,\"n\":\">0TX - Cloud Texture Layer #14\"},{\"t\":2,\"p\":1,\"n\":\"?0TX - Cloud Texture Layer #15\"},{\"t\":2,\"p\":1,\"n\":\"@0TX - Cloud Texture Layer #16\"},{\"t\":2,\"p\":1,\"n\":\"A0TX - Cloud Texture Layer #17\"},{\"t\":2,\"p\":1,\"n\":\"B0TX - Cloud Texture Layer #18\"},{\"t\":2,\"p\":1,\"n\":\"C0TX - Cloud Texture Layer #19\"},{\"t\":2,\"p\":1,\"n\":\"D0TX - Cloud Texture Layer #20\"},{\"t\":2,\"p\":1,\"n\":\"E0TX - Cloud Texture Layer #21\"},{\"t\":2,\"p\":1,\"n\":\"F0TX - Cloud Texture Layer #22\"},{\"t\":2,\"p\":1,\"n\":\"G0TX - Cloud Texture Layer #23\"},{\"t\":2,\"p\":1,\"n\":\"H0TX - Cloud Texture Layer #24\"},{\"t\":2,\"p\":1,\"n\":\"I0TX - Cloud Texture Layer #25\"},{\"t\":2,\"p\":1,\"n\":\"J0TX - Cloud Texture Layer #26\"},{\"t\":2,\"p\":1,\"n\":\"K0TX - Cloud Texture Layer #27\"},{\"t\":2,\"p\":1,\"n\":\"L0TX - Cloud Texture Layer #28\"},{\"t\":11,\"n\":\"DNAM - Unused\"},{\"t\":11,\"n\":\"CNAM - Unused\"},{\"t\":11,\"n\":\"ANAM - Unused\"},{\"t\":11,\"n\":\"BNAM - Unused\"},{\"t\":11,\"n\":\"LNAM - Unknown\"},{\"t\":3,\"p\":1,\"n\":\"MNAM - Precipitation Type\"},{\"t\":3,\"p\":1,\"n\":\"NNAM - Visual Effect\"},{\"t\":11,\"n\":\"ONAM - Unused\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Cloud Speed\",\"c\":[{\"t\":7,\"p\":1,\"n\":\"RNAM - Y Speed\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Layer\"}]},{\"t\":7,\"p\":1,\"n\":\"QNAM - X Speed\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Layer\"}]}]},{\"t\":7,\"s\":1,\"p\":1,\"n\":\"PNAM - Cloud Colors\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Layer\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Sunrise\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Day\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Sunset\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Night\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]}]}]},{\"t\":7,\"s\":1,\"p\":1,\"n\":\"JNAM - Cloud Alphas\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Layer\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Sunrise\"},{\"t\":5,\"p\":1,\"n\":\"Day\"},{\"t\":5,\"p\":1,\"n\":\"Sunset\"},{\"t\":5,\"p\":1,\"n\":\"Night\"}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"NAM0 - Weather Colors\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Sky-Upper\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Sunrise\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Day\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Sunset\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Night\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]}]},{\"t\":6,\"p\":1,\"n\":\"Fog Near\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Sunrise\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Day\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Sunset\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Night\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]}]},{\"t\":6,\"n\":\"Unknown\",\"c\":[{\"t\":6,\"n\":\"Sunrise\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"n\":\"Day\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"n\":\"Sunset\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"n\":\"Night\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]}]},{\"t\":6,\"p\":1,\"n\":\"Ambient\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Sunrise\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Day\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Sunset\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Night\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]}]},{\"t\":6,\"p\":1,\"n\":\"Sunlight\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Sunrise\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Day\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Sunset\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Night\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]}]},{\"t\":6,\"p\":1,\"n\":\"Sun\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Sunrise\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Day\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Sunset\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Night\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]}]},{\"t\":6,\"p\":1,\"n\":\"Stars\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Sunrise\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Day\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Sunset\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Night\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]}]},{\"t\":6,\"p\":1,\"n\":\"Sky-Lower\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Sunrise\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Day\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Sunset\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Night\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]}]},{\"t\":6,\"p\":1,\"n\":\"Horizon\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Sunrise\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Day\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Sunset\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Night\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]}]},{\"t\":6,\"p\":1,\"n\":\"Effect Lighting\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Sunrise\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Day\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Sunset\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Night\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]}]},{\"t\":6,\"p\":1,\"n\":\"Cloud LOD Diffuse\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Sunrise\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Day\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Sunset\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Night\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]}]},{\"t\":6,\"p\":1,\"n\":\"Cloud LOD Ambient\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Sunrise\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Day\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Sunset\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Night\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]}]},{\"t\":6,\"p\":1,\"n\":\"Fog Far\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Sunrise\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Day\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Sunset\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Night\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]}]},{\"t\":6,\"p\":1,\"n\":\"Sky Statics\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Sunrise\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Day\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Sunset\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Night\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]}]},{\"t\":6,\"p\":1,\"n\":\"Water Multiplier\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Sunrise\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Day\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Sunset\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Night\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]}]},{\"t\":6,\"p\":1,\"n\":\"Sun Glare\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Sunrise\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Day\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Sunset\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Night\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]}]},{\"t\":6,\"p\":1,\"n\":\"Moon Glare\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Sunrise\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Day\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Sunset\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Night\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"FNAM - Fog Distance\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Day - Near\"},{\"t\":5,\"p\":1,\"n\":\"Day - Far\"},{\"t\":5,\"p\":1,\"n\":\"Night - Near\"},{\"t\":5,\"p\":1,\"n\":\"Night - Far\"},{\"t\":5,\"p\":1,\"n\":\"Day - Power\"},{\"t\":5,\"p\":1,\"n\":\"Night - Power\"},{\"t\":5,\"p\":1,\"n\":\"Day - Max\"},{\"t\":5,\"p\":1,\"n\":\"Night - Max\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DATA - Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Wind Speed\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":3,\"p\":1,\"n\":\"Trans Delta\"},{\"t\":3,\"p\":1,\"n\":\"Sun Glare\"},{\"t\":3,\"p\":1,\"n\":\"Sun Damage\"},{\"t\":3,\"p\":1,\"n\":\"Precipitation - Begin Fade In\"},{\"t\":3,\"p\":1,\"n\":\"Precipitation - End Fade Out\"},{\"t\":3,\"p\":1,\"n\":\"Thunder\\/Lightning - Begin Fade In\"},{\"t\":3,\"p\":1,\"n\":\"Thunder\\/Lightning - End Fade Out\"},{\"t\":3,\"p\":1,\"n\":\"Thunder\\/Lightning - Frequency\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":6,\"p\":1,\"n\":\"Lightning Color\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"}]},{\"t\":3,\"p\":1,\"n\":\"Visual Effect - Begin\"},{\"t\":3,\"p\":1,\"n\":\"Visual Effect - End\"},{\"t\":3,\"p\":1,\"n\":\"Wind Direction\"},{\"t\":3,\"p\":1,\"n\":\"Wind Direction Range\"}]},{\"t\":3,\"p\":1,\"n\":\"NAM1 - Disabled Cloud Layers\"},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Sounds\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"SNAM - Sound\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Sound\"},{\"t\":3,\"p\":1,\"n\":\"Type\"}]}]},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Sky Statics\",\"d\":1,\"c\":[{\"t\":3,\"p\":1,\"n\":\"TNAM - Static\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"IMSP - Image Spaces\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Sunrise\"},{\"t\":3,\"p\":1,\"n\":\"Day\"},{\"t\":3,\"p\":1,\"n\":\"Sunset\"},{\"t\":3,\"p\":1,\"n\":\"Night\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"HNAM - Volumetric Lighting\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Sunrise\"},{\"t\":3,\"p\":1,\"n\":\"Day\"},{\"t\":3,\"p\":1,\"n\":\"Sunset\"},{\"t\":3,\"p\":1,\"n\":\"Night\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Directional Ambient Lighting Colors\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"DALC - Sunrise\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Directional\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"X+\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"X-\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Y+\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Y-\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Z+\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Z-\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]}]},{\"t\":6,\"p\":1,\"n\":\"Specular\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":5,\"p\":1,\"n\":\"Scale\"}]},{\"t\":6,\"p\":1,\"n\":\"DALC - Day\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Directional\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"X+\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"X-\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Y+\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Y-\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Z+\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Z-\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]}]},{\"t\":6,\"p\":1,\"n\":\"Specular\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":5,\"p\":1,\"n\":\"Scale\"}]},{\"t\":6,\"p\":1,\"n\":\"DALC - Sunset\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Directional\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"X+\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"X-\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Y+\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Y-\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Z+\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Z-\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]}]},{\"t\":6,\"p\":1,\"n\":\"Specular\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":5,\"p\":1,\"n\":\"Scale\"}]},{\"t\":6,\"p\":1,\"n\":\"DALC - Night\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Directional\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"X+\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"X-\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Y+\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Y-\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Z+\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Z-\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]}]},{\"t\":6,\"p\":1,\"n\":\"Specular\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":5,\"p\":1,\"n\":\"Scale\"}]}]},{\"t\":11,\"n\":\"NAM2 - Unused\"},{\"t\":11,\"n\":\"NAM3 - Unused\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Aurora\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"MODT - Texture Files Hashes\"},{\"t\":7,\"p\":1,\"n\":\"MODS - Alternate Textures\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"3D Name\"},{\"t\":3,\"p\":1,\"n\":\"New Texture\"},{\"t\":3,\"p\":1,\"n\":\"3D Index\"}]}]}]}]},{\"t\":3,\"p\":1,\"n\":\"GNAM - Sun Glare Lens Flare\"}]},{\"t\":1,\"p\":1,\"n\":\"ACHR - Placed NPC\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"VMAD - Virtual Machine Adapter\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Version\"},{\"t\":3,\"p\":1,\"n\":\"Object Format\"},{\"t\":7,\"p\":1,\"n\":\"Scripts\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Script\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"scriptName\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":7,\"p\":1,\"n\":\"Properties\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Property\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"propertyName\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]},{\"t\":2,\"p\":1,\"n\":\"String\"},{\"t\":3,\"p\":1,\"n\":\"Int32\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":3,\"p\":1,\"n\":\"Bool\"},{\"t\":7,\"p\":1,\"n\":\"Array of Object\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]}]},{\"t\":7,\"p\":1,\"n\":\"Array of String\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Int32\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Float\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Bool\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]}]}]}]}]}]},{\"t\":3,\"p\":1,\"n\":\"NAME - Base\"},{\"t\":3,\"p\":1,\"n\":\"XEZN - Encounter Zone\"},{\"t\":11,\"n\":\"XRGD - Ragdoll Data\"},{\"t\":11,\"n\":\"XRGB - Ragdoll Biped Data\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Patrol Data\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"XPRD - Idle Time\"},{\"p\":1,\"n\":\"XPPA - Patrol Script Marker\"},{\"t\":3,\"p\":1,\"n\":\"INAM - Idle\"},{\"t\":6,\"n\":\"Unused\",\"c\":[{\"t\":11,\"n\":\"SCHR - Unknown\"},{\"t\":11,\"n\":\"SCDA - Unknown\"},{\"t\":11,\"n\":\"SCTX - Unknown\"},{\"t\":11,\"n\":\"QNAM - Unknown\"},{\"t\":11,\"n\":\"SCRO - Unknown\"}]},{\"t\":8,\"p\":1,\"n\":\"Topic\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"PDTO - Topic Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Topic\"},{\"t\":2,\"p\":1,\"n\":\"Subtype\"}]}]},{\"t\":3,\"p\":1,\"n\":\"TNAM - Topic\"}]},{\"t\":3,\"p\":1,\"n\":\"XLCM - Level Modifier\"},{\"t\":3,\"p\":1,\"n\":\"XMRC - Merchant Container\"},{\"t\":3,\"p\":1,\"n\":\"XCNT - Count\"},{\"t\":5,\"p\":1,\"n\":\"XRDS - Radius\"},{\"t\":5,\"p\":1,\"n\":\"XHLP - Health\"},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Linked References\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"XLKR - Linked Reference\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Keyword\\/Ref\"},{\"t\":3,\"p\":1,\"n\":\"Ref\"}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Activate Parents\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"XAPD - Flags\"},{\"t\":8,\"p\":1,\"n\":\"Activate Parent Refs\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"XAPR - Activate Parent Ref\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":5,\"p\":1,\"n\":\"Delay\"}]}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"XCLP - Linked Reference Color\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Link Start Color\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Link End Color\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]}]},{\"t\":3,\"p\":1,\"n\":\"XLCN - Persistent Location\"},{\"t\":3,\"p\":1,\"n\":\"XLRL - Location Reference\"},{\"p\":1,\"n\":\"XIS2 - Ignored by Sandbox\"},{\"t\":7,\"p\":1,\"n\":\"XLRT - Location Ref Type\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Ref\"}]},{\"t\":3,\"p\":1,\"n\":\"XHOR - Horse\"},{\"t\":5,\"p\":1,\"n\":\"XHTW - Head-Tracking Weight\"},{\"t\":5,\"p\":1,\"n\":\"XFVC - Favor Cost\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"XESP - Enable Parent\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Ownership\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"XOWN - Owner\"},{\"t\":3,\"p\":1,\"n\":\"XRNK - Faction rank\"}]},{\"t\":3,\"p\":1,\"n\":\"XEMI - Emittance\"},{\"t\":3,\"p\":1,\"n\":\"XMBR - MultiBound Reference\"},{\"p\":1,\"n\":\"XIBS - Ignored By Sandbox\"},{\"t\":5,\"p\":1,\"n\":\"XSCL - Scale\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DATA - Position\\/Rotation\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Position\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"X\"},{\"t\":5,\"p\":1,\"n\":\"Y\"},{\"t\":5,\"p\":1,\"n\":\"Z\"}]},{\"t\":6,\"p\":1,\"n\":\"Rotation\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"X\"},{\"t\":5,\"p\":1,\"n\":\"Y\"},{\"t\":5,\"p\":1,\"n\":\"Z\"}]}]}]}]},\"name\":\"Smash.All\",\"hash\":\"B5A65E9D\",\"color\":128}"
  },
  {
    "path": "frontend/settings/Skyrim/Smash.ForceAll.json",
    "content": "{\"records\":\"AACT,ACTI,ADDN,ALCH,AMMO,ANIO,APPA,ARMA,ARMO,ARTO,ASPC,ASTP,AVIF,BOOK,BPTD,CAMS,CELL,CLAS,CLDC,CLFM,CLMT,COBJ,COLL,CONT,CPTH,CSTY,DEBR,DIAL,DLBR,DLVW,DOOR,DUAL,ECZN,EFSH,ENCH,EQUP,EXPL,EYES,FACT,FLOR,FLST,FSTP,FSTS,FURN,GLOB,GMST,GRAS,HAIR,HAZD,HDPT,IDLM,IMAD,IMGS,INFO,INGR,IPCT,IPDS,KEYM,KYWD,LAND,LCRT,LENS,LGTM,LIGH,LSCR,LTEX,LVLI,LVLN,LVSP,MATO,MATT,MESG,MGEF,MISC,MOVT,MSTT,MUSC,MUST,NPC_,OTFT,PACK,PARW,PBAR,PBEA,PCON,PERK,PFLA,PGRE,PHZD,PMIS,PROJ,PWAT,QUST,RACE,REFR,REGN,RELA,REVB,RFCT,RGDL,SCEN,SCOL,SCPT,SCRL,SHOU,SLGM,SMBN,SMEN,SMQN,SNCT,SNDR,SOPM,SOUN,SPEL,SPGD,STAT,TACT,TREE,TXST,VOLI,VTYP,WATR,WEAP,WOOP,WRLD,WTHR,ACHR\",\"description\":\"Forces the smashed patch to use records from the plugin this is applied to, and only allows changes in plugins that require the plugin this is applied to when resolving further conflicts.\",\"tree\":{\"records\":[{\"t\":1,\"p\":1,\"n\":\"AACT - Action\",\"f\":1,\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"CNAM - Color\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unknown\"}]}]},{\"t\":1,\"p\":1,\"n\":\"ACTI - Activator\",\"f\":1,\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"VMAD - Virtual Machine Adapter\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Version\"},{\"t\":3,\"p\":1,\"n\":\"Object Format\"},{\"t\":7,\"p\":1,\"n\":\"Scripts\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Script\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"scriptName\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":7,\"p\":1,\"n\":\"Properties\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Property\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"propertyName\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]},{\"t\":2,\"p\":1,\"n\":\"String\"},{\"t\":3,\"p\":1,\"n\":\"Int32\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":3,\"p\":1,\"n\":\"Bool\"},{\"t\":7,\"p\":1,\"n\":\"Array of Object\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]}]},{\"t\":7,\"p\":1,\"n\":\"Array of String\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Int32\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Float\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Bool\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]}]}]}]}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"X1\"},{\"t\":3,\"p\":1,\"n\":\"Y1\"},{\"t\":3,\"p\":1,\"n\":\"Z1\"},{\"t\":3,\"p\":1,\"n\":\"X2\"},{\"t\":3,\"p\":1,\"n\":\"Y2\"},{\"t\":3,\"p\":1,\"n\":\"Z2\"}]},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"MODT - Texture Files Hashes\"},{\"t\":7,\"p\":1,\"n\":\"MODS - Alternate Textures\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"3D Name\"},{\"t\":3,\"p\":1,\"n\":\"New Texture\"},{\"t\":3,\"p\":1,\"n\":\"3D Index\"}]}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Destructable\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"DEST - Header\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Health\"},{\"t\":3,\"p\":1,\"n\":\"DEST Count\"},{\"t\":3,\"p\":1,\"n\":\"VATS Targetable\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":8,\"p\":1,\"n\":\"Stages\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Stage\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"DSTD - Destruction Stage Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Health %\"},{\"t\":3,\"p\":1,\"n\":\"Index\"},{\"t\":3,\"p\":1,\"n\":\"Model Damage Stage\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":3,\"p\":1,\"n\":\"Self Damage per Second\"},{\"t\":3,\"p\":1,\"n\":\"Explosion\"},{\"t\":3,\"p\":1,\"n\":\"Debris\"},{\"t\":3,\"p\":1,\"n\":\"Debris Count\"}]},{\"t\":6,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"DMDL - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"DMDT - Texture Files Hashes\"},{\"t\":7,\"p\":1,\"n\":\"DMDS - Alternate Textures\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"3D Name\"},{\"t\":3,\"p\":1,\"n\":\"New Texture\"},{\"t\":3,\"p\":1,\"n\":\"3D Index\"}]}]}]},{\"p\":1,\"n\":\"DSTF - End Marker\"}]}]}]},{\"t\":3,\"n\":\"KSIZ - Keyword Count\"},{\"t\":7,\"p\":1,\"n\":\"KWDA - Keywords\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Keyword\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"PNAM - Marker Color\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":3,\"n\":\"Unused\"}]},{\"t\":3,\"p\":1,\"n\":\"SNAM - Sound - Looping\"},{\"t\":3,\"p\":1,\"n\":\"VNAM - Sound - Activation\"},{\"t\":3,\"p\":1,\"n\":\"WNAM - Water Type\"},{\"t\":2,\"p\":1,\"n\":\"RNAM - Activate Text Override\"},{\"t\":3,\"p\":1,\"n\":\"FNAM - Flags\"},{\"t\":3,\"p\":1,\"n\":\"KNAM - Interaction Keyword\"}]},{\"t\":1,\"p\":1,\"n\":\"ADDN - Addon Node\",\"f\":1,\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"X1\"},{\"t\":3,\"p\":1,\"n\":\"Y1\"},{\"t\":3,\"p\":1,\"n\":\"Z1\"},{\"t\":3,\"p\":1,\"n\":\"X2\"},{\"t\":3,\"p\":1,\"n\":\"Y2\"},{\"t\":3,\"p\":1,\"n\":\"Z2\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"MODT - Texture Files Hashes\"},{\"t\":7,\"p\":1,\"n\":\"MODS - Alternate Textures\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"3D Name\"},{\"t\":3,\"p\":1,\"n\":\"New Texture\"},{\"t\":3,\"p\":1,\"n\":\"3D Index\"}]}]}]},{\"t\":3,\"p\":1,\"n\":\"DATA - Node Index\"},{\"t\":3,\"p\":1,\"n\":\"SNAM - Sound\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DNAM - Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Master Particle System Cap\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"}]}]},{\"t\":1,\"p\":1,\"n\":\"ALCH - Ingestible\",\"f\":1,\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"X1\"},{\"t\":3,\"p\":1,\"n\":\"Y1\"},{\"t\":3,\"p\":1,\"n\":\"Z1\"},{\"t\":3,\"p\":1,\"n\":\"X2\"},{\"t\":3,\"p\":1,\"n\":\"Y2\"},{\"t\":3,\"p\":1,\"n\":\"Z2\"}]},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":3,\"n\":\"KSIZ - Keyword Count\"},{\"t\":7,\"p\":1,\"n\":\"KWDA - Keywords\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Keyword\"}]},{\"t\":2,\"p\":1,\"n\":\"DESC - Description\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"MODT - Texture Files Hashes\"},{\"t\":7,\"p\":1,\"n\":\"MODS - Alternate Textures\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"3D Name\"},{\"t\":3,\"p\":1,\"n\":\"New Texture\"},{\"t\":3,\"p\":1,\"n\":\"3D Index\"}]}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Destructable\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"DEST - Header\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Health\"},{\"t\":3,\"p\":1,\"n\":\"DEST Count\"},{\"t\":3,\"p\":1,\"n\":\"VATS Targetable\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":8,\"p\":1,\"n\":\"Stages\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Stage\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"DSTD - Destruction Stage Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Health %\"},{\"t\":3,\"p\":1,\"n\":\"Index\"},{\"t\":3,\"p\":1,\"n\":\"Model Damage Stage\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":3,\"p\":1,\"n\":\"Self Damage per Second\"},{\"t\":3,\"p\":1,\"n\":\"Explosion\"},{\"t\":3,\"p\":1,\"n\":\"Debris\"},{\"t\":3,\"p\":1,\"n\":\"Debris Count\"}]},{\"t\":6,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"DMDL - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"DMDT - Texture Files Hashes\"},{\"t\":7,\"p\":1,\"n\":\"DMDS - Alternate Textures\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"3D Name\"},{\"t\":3,\"p\":1,\"n\":\"New Texture\"},{\"t\":3,\"p\":1,\"n\":\"3D Index\"}]}]}]},{\"p\":1,\"n\":\"DSTF - End Marker\"}]}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Icon\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"ICON - Large Icon filename\"},{\"t\":2,\"p\":1,\"n\":\"MICO - Small Icon filename\"}]},{\"t\":3,\"p\":1,\"n\":\"YNAM - Sound - Pick Up\"},{\"t\":3,\"p\":1,\"n\":\"ZNAM - Sound - Put Down\"},{\"t\":3,\"p\":1,\"n\":\"ETYP - Equipment Type\"},{\"t\":5,\"p\":1,\"n\":\"DATA - Weight\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"ENIT - Effect Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Value\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":3,\"p\":1,\"n\":\"Addiction\"},{\"t\":5,\"p\":1,\"n\":\"Addiction Chance\"},{\"t\":3,\"p\":1,\"n\":\"Sound - Consume\"}]},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Effects\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Effect\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"EFID - Base Effect\"},{\"t\":6,\"p\":1,\"n\":\"EFIT - \",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Magnitude\"},{\"t\":3,\"p\":1,\"n\":\"Area\"},{\"t\":3,\"p\":1,\"n\":\"Duration\"}]},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Conditions\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Condition\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"CTDA - \",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":5,\"p\":1,\"n\":\"Comparison Value - Float\"},{\"t\":3,\"p\":1,\"n\":\"Comparison Value - Global\"},{\"t\":3,\"p\":1,\"n\":\"Function\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":11,\"p\":1,\"n\":\"None\"},{\"t\":3,\"p\":1,\"n\":\"Integer\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":11,\"p\":1,\"n\":\"Variable Name (unused)\"},{\"t\":3,\"p\":1,\"n\":\"Sex\"},{\"t\":3,\"p\":1,\"n\":\"Actor Value\"},{\"t\":3,\"p\":1,\"n\":\"Crime Type\"},{\"t\":3,\"p\":1,\"n\":\"Axis\"},{\"t\":3,\"p\":1,\"n\":\"Quest Stage (unused)\"},{\"t\":3,\"p\":1,\"n\":\"Misc Stat\"},{\"t\":3,\"p\":1,\"n\":\"Alignment\"},{\"t\":3,\"p\":1,\"n\":\"Equip Type\"},{\"t\":3,\"p\":1,\"n\":\"Form Type\"},{\"t\":3,\"p\":1,\"n\":\"Critical Stage\"},{\"t\":3,\"p\":1,\"n\":\"Object Reference\"},{\"t\":3,\"p\":1,\"n\":\"Inventory Object\"},{\"t\":3,\"p\":1,\"n\":\"Actor\"},{\"t\":3,\"p\":1,\"n\":\"Voice Type\"},{\"t\":3,\"p\":1,\"n\":\"Idle\"},{\"t\":3,\"p\":1,\"n\":\"Form List\"},{\"t\":3,\"p\":1,\"n\":\"Quest\"},{\"t\":3,\"p\":1,\"n\":\"Faction\"},{\"t\":3,\"p\":1,\"n\":\"Cell\"},{\"t\":3,\"p\":1,\"n\":\"Class\"},{\"t\":3,\"p\":1,\"n\":\"Race\"},{\"t\":3,\"p\":1,\"n\":\"Actor Base\"},{\"t\":3,\"p\":1,\"n\":\"Global\"},{\"t\":3,\"p\":1,\"n\":\"Weather\"},{\"t\":3,\"p\":1,\"n\":\"Package\"},{\"t\":3,\"p\":1,\"n\":\"Encounter Zone\"},{\"t\":3,\"p\":1,\"n\":\"Perk\"},{\"t\":3,\"p\":1,\"n\":\"Owner\"},{\"t\":3,\"p\":1,\"n\":\"Furniture\"},{\"t\":3,\"p\":1,\"n\":\"Effect Item\"},{\"t\":3,\"p\":1,\"n\":\"Base Effect\"},{\"t\":3,\"p\":1,\"n\":\"Worldspace\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Function\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Param (INVALID)\"},{\"t\":3,\"p\":1,\"n\":\"Referenceable Object\"},{\"t\":3,\"p\":1,\"n\":\"Region\"},{\"t\":3,\"p\":1,\"n\":\"Keyword\"},{\"t\":3,\"p\":1,\"n\":\"Player Action\"},{\"t\":3,\"p\":1,\"n\":\"Casting Type\"},{\"t\":3,\"p\":1,\"n\":\"Shout\"},{\"t\":3,\"p\":1,\"n\":\"Location\"},{\"t\":3,\"p\":1,\"n\":\"Location Ref Type\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"Packdata ID\"},{\"t\":3,\"p\":1,\"n\":\"Association Type\"},{\"t\":3,\"p\":1,\"n\":\"Furniture Anim\"},{\"t\":3,\"p\":1,\"n\":\"Furniture Entry\"},{\"t\":3,\"p\":1,\"n\":\"Scene\"},{\"t\":3,\"p\":1,\"n\":\"Ward State\"},{\"t\":3,\"p\":1,\"n\":\"Event\"},{\"t\":3,\"p\":1,\"n\":\"Event Data\"},{\"t\":3,\"p\":1,\"n\":\"Quest Stage\"},{\"t\":3,\"p\":1,\"n\":\"Weapon\"},{\"t\":3,\"p\":1,\"n\":\"Weapon List\"},{\"t\":3,\"p\":1,\"n\":\"Target\"},{\"t\":3,\"p\":1,\"n\":\"Target List\"},{\"t\":3,\"p\":1,\"n\":\"Target Part\"},{\"t\":3,\"p\":1,\"n\":\"VATS Action\"},{\"t\":3,\"p\":1,\"n\":\"Critical Effect\"},{\"t\":3,\"p\":1,\"n\":\"Critical Effect List\"},{\"t\":3,\"p\":1,\"n\":\"Weapon Type\"},{\"t\":3,\"p\":1,\"n\":\"Projectile Type\"},{\"t\":3,\"p\":1,\"n\":\"Delivery Type\"},{\"t\":3,\"p\":1,\"n\":\"Run On\"},{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":3,\"p\":1,\"n\":\"Parameter #3\"}]},{\"t\":2,\"p\":1,\"n\":\"CIS1 - Parameter #1\"},{\"t\":2,\"p\":1,\"n\":\"CIS2 - Parameter #2\"}]}]}]}]}]},{\"t\":1,\"p\":1,\"n\":\"AMMO - Ammunition\",\"f\":1,\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"X1\"},{\"t\":3,\"p\":1,\"n\":\"Y1\"},{\"t\":3,\"p\":1,\"n\":\"Z1\"},{\"t\":3,\"p\":1,\"n\":\"X2\"},{\"t\":3,\"p\":1,\"n\":\"Y2\"},{\"t\":3,\"p\":1,\"n\":\"Z2\"}]},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"MODT - Texture Files Hashes\"},{\"t\":7,\"p\":1,\"n\":\"MODS - Alternate Textures\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"3D Name\"},{\"t\":3,\"p\":1,\"n\":\"New Texture\"},{\"t\":3,\"p\":1,\"n\":\"3D Index\"}]}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Icon\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"ICON - Large Icon filename\"},{\"t\":2,\"p\":1,\"n\":\"MICO - Small Icon filename\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Destructable\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"DEST - Header\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Health\"},{\"t\":3,\"p\":1,\"n\":\"DEST Count\"},{\"t\":3,\"p\":1,\"n\":\"VATS Targetable\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":8,\"p\":1,\"n\":\"Stages\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Stage\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"DSTD - Destruction Stage Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Health %\"},{\"t\":3,\"p\":1,\"n\":\"Index\"},{\"t\":3,\"p\":1,\"n\":\"Model Damage Stage\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":3,\"p\":1,\"n\":\"Self Damage per Second\"},{\"t\":3,\"p\":1,\"n\":\"Explosion\"},{\"t\":3,\"p\":1,\"n\":\"Debris\"},{\"t\":3,\"p\":1,\"n\":\"Debris Count\"}]},{\"t\":6,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"DMDL - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"DMDT - Texture Files Hashes\"},{\"t\":7,\"p\":1,\"n\":\"DMDS - Alternate Textures\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"3D Name\"},{\"t\":3,\"p\":1,\"n\":\"New Texture\"},{\"t\":3,\"p\":1,\"n\":\"3D Index\"}]}]}]},{\"p\":1,\"n\":\"DSTF - End Marker\"}]}]}]},{\"t\":3,\"p\":1,\"n\":\"YNAM - Sound - Pick Up\"},{\"t\":3,\"p\":1,\"n\":\"ZNAM - Sound - Put Down\"},{\"t\":2,\"p\":1,\"n\":\"DESC - Description\"},{\"t\":3,\"n\":\"KSIZ - Keyword Count\"},{\"t\":7,\"p\":1,\"n\":\"KWDA - Keywords\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Keyword\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DATA - Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Projectile\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":5,\"p\":1,\"n\":\"Damage\"},{\"t\":3,\"p\":1,\"n\":\"Value\"}]},{\"t\":2,\"p\":1,\"n\":\"ONAM - Short Name\"}]},{\"t\":1,\"p\":1,\"n\":\"ANIO - Animated Object\",\"f\":1,\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"MODT - Texture Files Hashes\"},{\"t\":7,\"p\":1,\"n\":\"MODS - Alternate Textures\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"3D Name\"},{\"t\":3,\"p\":1,\"n\":\"New Texture\"},{\"t\":3,\"p\":1,\"n\":\"3D Index\"}]}]}]},{\"t\":2,\"p\":1,\"n\":\"BNAM - Unload Event\"}]},{\"t\":1,\"p\":1,\"n\":\"APPA - Alchemical Apparatus\",\"f\":1,\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"VMAD - Virtual Machine Adapter\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Version\"},{\"t\":3,\"p\":1,\"n\":\"Object Format\"},{\"t\":7,\"p\":1,\"n\":\"Scripts\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Script\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"scriptName\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":7,\"p\":1,\"n\":\"Properties\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Property\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"propertyName\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]},{\"t\":2,\"p\":1,\"n\":\"String\"},{\"t\":3,\"p\":1,\"n\":\"Int32\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":3,\"p\":1,\"n\":\"Bool\"},{\"t\":7,\"p\":1,\"n\":\"Array of Object\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]}]},{\"t\":7,\"p\":1,\"n\":\"Array of String\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Int32\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Float\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Bool\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]}]}]}]}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"X1\"},{\"t\":3,\"p\":1,\"n\":\"Y1\"},{\"t\":3,\"p\":1,\"n\":\"Z1\"},{\"t\":3,\"p\":1,\"n\":\"X2\"},{\"t\":3,\"p\":1,\"n\":\"Y2\"},{\"t\":3,\"p\":1,\"n\":\"Z2\"}]},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"MODT - Texture Files Hashes\"},{\"t\":7,\"p\":1,\"n\":\"MODS - Alternate Textures\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"3D Name\"},{\"t\":3,\"p\":1,\"n\":\"New Texture\"},{\"t\":3,\"p\":1,\"n\":\"3D Index\"}]}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Icon\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"ICON - Large Icon filename\"},{\"t\":2,\"p\":1,\"n\":\"MICO - Small Icon filename\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Destructable\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"DEST - Header\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Health\"},{\"t\":3,\"p\":1,\"n\":\"DEST Count\"},{\"t\":3,\"p\":1,\"n\":\"VATS Targetable\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":8,\"p\":1,\"n\":\"Stages\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Stage\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"DSTD - Destruction Stage Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Health %\"},{\"t\":3,\"p\":1,\"n\":\"Index\"},{\"t\":3,\"p\":1,\"n\":\"Model Damage Stage\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":3,\"p\":1,\"n\":\"Self Damage per Second\"},{\"t\":3,\"p\":1,\"n\":\"Explosion\"},{\"t\":3,\"p\":1,\"n\":\"Debris\"},{\"t\":3,\"p\":1,\"n\":\"Debris Count\"}]},{\"t\":6,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"DMDL - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"DMDT - Texture Files Hashes\"},{\"t\":7,\"p\":1,\"n\":\"DMDS - Alternate Textures\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"3D Name\"},{\"t\":3,\"p\":1,\"n\":\"New Texture\"},{\"t\":3,\"p\":1,\"n\":\"3D Index\"}]}]}]},{\"p\":1,\"n\":\"DSTF - End Marker\"}]}]}]},{\"t\":3,\"p\":1,\"n\":\"YNAM - Sound - Pick Up\"},{\"t\":3,\"p\":1,\"n\":\"ZNAM - Sound - Put Down\"},{\"t\":3,\"p\":1,\"n\":\"QUAL - Quality\"},{\"t\":2,\"p\":1,\"n\":\"DESC - Description\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DATA - Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Value\"},{\"t\":5,\"p\":1,\"n\":\"Weight\"}]}]},{\"t\":1,\"p\":1,\"n\":\"ARMA - Armor Addon\",\"f\":1,\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"BOD2 - Biped Body Template\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"First Person Flags\"},{\"t\":3,\"p\":1,\"n\":\"General Flags\"},{\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Armor Type\"}],\"lt\":\"BODT - Body Template\",\"lf\":\"BODT - Body Template\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"BODT - Body Template\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"First Person Flags\"},{\"t\":3,\"p\":1,\"n\":\"General Flags\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Armor Type\"}],\"lt\":\"BOD2 - Biped Body Template\",\"lf\":\"BOD2 - Biped Body Template\"},{\"t\":3,\"p\":1,\"n\":\"RNAM - Race\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DNAM - Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Male Priority\"},{\"t\":3,\"p\":1,\"n\":\"Female Priority\"},{\"t\":3,\"p\":1,\"n\":\"Weight slider - Male\"},{\"t\":3,\"p\":1,\"n\":\"Weight slider - Female\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":3,\"p\":1,\"n\":\"Detection Sound Value\"},{\"t\":5,\"p\":1,\"n\":\"Weapon Adjust\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Male world model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MOD2 - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"MO2T - Texture Files Hashes\"},{\"t\":7,\"p\":1,\"n\":\"MO2S - Alternate Textures\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"3D Name\"},{\"t\":3,\"p\":1,\"n\":\"New Texture\"},{\"t\":3,\"p\":1,\"n\":\"3D Index\"}]}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Female world model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MOD3 - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"MO3T - Texture Files Hashes\"},{\"t\":7,\"p\":1,\"n\":\"MO3S - Alternate Textures\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"3D Name\"},{\"t\":3,\"p\":1,\"n\":\"New Texture\"},{\"t\":3,\"p\":1,\"n\":\"3D Index\"}]}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Male 1st Person\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MOD4 - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"MO4T - Texture Files Hashes\"},{\"t\":7,\"p\":1,\"n\":\"MO4S - Alternate Textures\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"3D Name\"},{\"t\":3,\"p\":1,\"n\":\"New Texture\"},{\"t\":3,\"p\":1,\"n\":\"3D Index\"}]}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Female 1st Person\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MOD5 - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"MO5T - Texture Files Hashes\"},{\"t\":7,\"p\":1,\"n\":\"MO5S - Alternate Textures\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"3D Name\"},{\"t\":3,\"p\":1,\"n\":\"New Texture\"},{\"t\":3,\"p\":1,\"n\":\"3D Index\"}]}]}]},{\"t\":3,\"p\":1,\"n\":\"NAM0 - Male Skin Texture\"},{\"t\":3,\"p\":1,\"n\":\"NAM1 - Female Skin texture\"},{\"t\":3,\"p\":1,\"n\":\"NAM2 - Male Skin Texture Swap List\"},{\"t\":3,\"p\":1,\"n\":\"NAM3 - Female Skin Texture Swap List\"},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Additional Races\",\"d\":1,\"c\":[{\"t\":3,\"p\":1,\"n\":\"MODL - Race\"}]},{\"t\":3,\"p\":1,\"n\":\"SNDD - Footstep Sound\"},{\"t\":3,\"p\":1,\"n\":\"ONAM - Art Object\"}]},{\"t\":1,\"p\":1,\"n\":\"ARMO - Armor\",\"f\":1,\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"VMAD - Virtual Machine Adapter\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Version\"},{\"t\":3,\"p\":1,\"n\":\"Object Format\"},{\"t\":7,\"p\":1,\"n\":\"Scripts\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Script\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"scriptName\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":7,\"p\":1,\"n\":\"Properties\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Property\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"propertyName\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]},{\"t\":2,\"p\":1,\"n\":\"String\"},{\"t\":3,\"p\":1,\"n\":\"Int32\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":3,\"p\":1,\"n\":\"Bool\"},{\"t\":7,\"p\":1,\"n\":\"Array of Object\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]}]},{\"t\":7,\"p\":1,\"n\":\"Array of String\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Int32\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Float\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Bool\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]}]}]}]}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"X1\"},{\"t\":3,\"p\":1,\"n\":\"Y1\"},{\"t\":3,\"p\":1,\"n\":\"Z1\"},{\"t\":3,\"p\":1,\"n\":\"X2\"},{\"t\":3,\"p\":1,\"n\":\"Y2\"},{\"t\":3,\"p\":1,\"n\":\"Z2\"}]},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":3,\"p\":1,\"n\":\"EITM - Object Effect\"},{\"t\":3,\"p\":1,\"n\":\"EAMT - Enchantment Amount\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Male world model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MOD2 - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"MO2T - Texture Files Hashes\"},{\"t\":7,\"p\":1,\"n\":\"MO2S - Alternate Textures\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"3D Name\"},{\"t\":3,\"p\":1,\"n\":\"New Texture\"},{\"t\":3,\"p\":1,\"n\":\"3D Index\"}]}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Icon\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"ICON - Large Icon filename\"},{\"t\":2,\"p\":1,\"n\":\"MICO - Small Icon filename\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Female world model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MOD4 - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"MO4T - Texture Files Hashes\"},{\"t\":7,\"p\":1,\"n\":\"MO4S - Alternate Textures\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"3D Name\"},{\"t\":3,\"p\":1,\"n\":\"New Texture\"},{\"t\":3,\"p\":1,\"n\":\"3D Index\"}]}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Icon 2 (female)\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"ICO2 - Large Icon filename\"},{\"t\":2,\"p\":1,\"n\":\"MIC2 - Small Icon filename\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"BOD2 - Biped Body Template\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"First Person Flags\"},{\"t\":3,\"p\":1,\"n\":\"General Flags\"},{\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Armor Type\"}],\"lt\":\"BODT - Body Template\",\"lf\":\"BODT - Body Template\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"BODT - Body Template\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"First Person Flags\"},{\"t\":3,\"p\":1,\"n\":\"General Flags\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Armor Type\"}],\"lt\":\"BOD2 - Biped Body Template\",\"lf\":\"BOD2 - Biped Body Template\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Destructable\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"DEST - Header\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Health\"},{\"t\":3,\"p\":1,\"n\":\"DEST Count\"},{\"t\":3,\"p\":1,\"n\":\"VATS Targetable\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":8,\"p\":1,\"n\":\"Stages\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Stage\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"DSTD - Destruction Stage Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Health %\"},{\"t\":3,\"p\":1,\"n\":\"Index\"},{\"t\":3,\"p\":1,\"n\":\"Model Damage Stage\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":3,\"p\":1,\"n\":\"Self Damage per Second\"},{\"t\":3,\"p\":1,\"n\":\"Explosion\"},{\"t\":3,\"p\":1,\"n\":\"Debris\"},{\"t\":3,\"p\":1,\"n\":\"Debris Count\"}]},{\"t\":6,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"DMDL - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"DMDT - Texture Files Hashes\"},{\"t\":7,\"p\":1,\"n\":\"DMDS - Alternate Textures\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"3D Name\"},{\"t\":3,\"p\":1,\"n\":\"New Texture\"},{\"t\":3,\"p\":1,\"n\":\"3D Index\"}]}]}]},{\"p\":1,\"n\":\"DSTF - End Marker\"}]}]}]},{\"t\":3,\"p\":1,\"n\":\"YNAM - Sound - Pick Up\"},{\"t\":3,\"p\":1,\"n\":\"ZNAM - Sound - Put Down\"},{\"t\":2,\"p\":1,\"n\":\"BMCT - Ragdoll Constraint Template\"},{\"t\":3,\"p\":1,\"n\":\"ETYP - Equipment Type\"},{\"t\":3,\"p\":1,\"n\":\"BIDS - Bash Impact Data Set\"},{\"t\":3,\"p\":1,\"n\":\"BAMT - Alternate Block Material\"},{\"t\":3,\"p\":1,\"n\":\"RNAM - Race\"},{\"t\":3,\"n\":\"KSIZ - Keyword Count\"},{\"t\":7,\"p\":1,\"n\":\"KWDA - Keywords\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Keyword\"}]},{\"t\":2,\"p\":1,\"n\":\"DESC - Description\"},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Armature\",\"d\":1,\"c\":[{\"t\":3,\"p\":1,\"n\":\"MODL - Model Filename\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DATA - Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Value\"},{\"t\":5,\"p\":1,\"n\":\"Weight\"}]},{\"t\":3,\"p\":1,\"n\":\"DNAM - Armor Rating\"},{\"t\":3,\"p\":1,\"n\":\"TNAM - Template Armor\"}]},{\"t\":1,\"p\":1,\"n\":\"ARTO - Art Object\",\"f\":1,\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"X1\"},{\"t\":3,\"p\":1,\"n\":\"Y1\"},{\"t\":3,\"p\":1,\"n\":\"Z1\"},{\"t\":3,\"p\":1,\"n\":\"X2\"},{\"t\":3,\"p\":1,\"n\":\"Y2\"},{\"t\":3,\"p\":1,\"n\":\"Z2\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"MODT - Texture Files Hashes\"},{\"t\":7,\"p\":1,\"n\":\"MODS - Alternate Textures\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"3D Name\"},{\"t\":3,\"p\":1,\"n\":\"New Texture\"},{\"t\":3,\"p\":1,\"n\":\"3D Index\"}]}]}]},{\"t\":3,\"p\":1,\"n\":\"DNAM - Art Type\"}]},{\"t\":1,\"p\":1,\"n\":\"ASPC - Acoustic Space\",\"f\":1,\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"X1\"},{\"t\":3,\"p\":1,\"n\":\"Y1\"},{\"t\":3,\"p\":1,\"n\":\"Z1\"},{\"t\":3,\"p\":1,\"n\":\"X2\"},{\"t\":3,\"p\":1,\"n\":\"Y2\"},{\"t\":3,\"p\":1,\"n\":\"Z2\"}]},{\"t\":3,\"p\":1,\"n\":\"SNAM - Ambient Sound\"},{\"t\":3,\"p\":1,\"n\":\"RDAT - Use Sound from Region (Interiors Only)\"},{\"t\":3,\"p\":1,\"n\":\"BNAM - Environment Type (reverb)\"}]},{\"t\":1,\"p\":1,\"n\":\"ASTP - Association Type\",\"f\":1,\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"p\":1,\"n\":\"MPRT - Male Parent Title\"},{\"t\":2,\"p\":1,\"n\":\"FPRT - Female Parent Title\"},{\"t\":2,\"p\":1,\"n\":\"MCHT - Male Child Title\"},{\"t\":2,\"p\":1,\"n\":\"FCHT - Female Child Title\"},{\"t\":3,\"p\":1,\"n\":\"DATA - Flags\"}]},{\"t\":1,\"p\":1,\"n\":\"AVIF - Actor Value Information\",\"f\":1,\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":2,\"p\":1,\"n\":\"DESC - Description\"},{\"t\":2,\"p\":1,\"n\":\"ANAM - Abbreviation\"},{\"t\":11,\"n\":\"CNAM - Unknown\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"AVSK - Skill\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Skill Use Mult\"},{\"t\":5,\"p\":1,\"n\":\"Skill Offset Mult\"},{\"t\":5,\"p\":1,\"n\":\"Skill Improve Mult\"},{\"t\":5,\"p\":1,\"n\":\"Skill Improve Offset\"}]},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Perk Tree\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Node\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"PNAM - Perk\"},{\"t\":11,\"n\":\"FNAM - Unknown\"},{\"t\":3,\"p\":1,\"n\":\"XNAM - Perk-Grid X\"},{\"t\":3,\"p\":1,\"n\":\"YNAM - Perk-Grid Y\"},{\"t\":5,\"p\":1,\"n\":\"HNAM - Horizontal Position\"},{\"t\":5,\"p\":1,\"n\":\"VNAM - Vertical Position\"},{\"t\":3,\"p\":1,\"n\":\"SNAM - Associated Skill\"},{\"t\":8,\"p\":1,\"n\":\"Connections\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"CNAM - Line to Index\"}]},{\"t\":3,\"p\":1,\"n\":\"INAM - Index\"}]}]}]},{\"t\":1,\"p\":1,\"n\":\"BOOK - Book\",\"f\":1,\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"VMAD - Virtual Machine Adapter\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Version\"},{\"t\":3,\"p\":1,\"n\":\"Object Format\"},{\"t\":7,\"p\":1,\"n\":\"Scripts\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Script\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"scriptName\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":7,\"p\":1,\"n\":\"Properties\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Property\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"propertyName\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]},{\"t\":2,\"p\":1,\"n\":\"String\"},{\"t\":3,\"p\":1,\"n\":\"Int32\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":3,\"p\":1,\"n\":\"Bool\"},{\"t\":7,\"p\":1,\"n\":\"Array of Object\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]}]},{\"t\":7,\"p\":1,\"n\":\"Array of String\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Int32\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Float\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Bool\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]}]}]}]}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"X1\"},{\"t\":3,\"p\":1,\"n\":\"Y1\"},{\"t\":3,\"p\":1,\"n\":\"Z1\"},{\"t\":3,\"p\":1,\"n\":\"X2\"},{\"t\":3,\"p\":1,\"n\":\"Y2\"},{\"t\":3,\"p\":1,\"n\":\"Z2\"}]},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"MODT - Texture Files Hashes\"},{\"t\":7,\"p\":1,\"n\":\"MODS - Alternate Textures\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"3D Name\"},{\"t\":3,\"p\":1,\"n\":\"New Texture\"},{\"t\":3,\"p\":1,\"n\":\"3D Index\"}]}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Icon\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"ICON - Large Icon filename\"},{\"t\":2,\"p\":1,\"n\":\"MICO - Small Icon filename\"}]},{\"t\":2,\"p\":1,\"n\":\"DESC - Book Text\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Destructable\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"DEST - Header\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Health\"},{\"t\":3,\"p\":1,\"n\":\"DEST Count\"},{\"t\":3,\"p\":1,\"n\":\"VATS Targetable\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":8,\"p\":1,\"n\":\"Stages\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Stage\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"DSTD - Destruction Stage Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Health %\"},{\"t\":3,\"p\":1,\"n\":\"Index\"},{\"t\":3,\"p\":1,\"n\":\"Model Damage Stage\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":3,\"p\":1,\"n\":\"Self Damage per Second\"},{\"t\":3,\"p\":1,\"n\":\"Explosion\"},{\"t\":3,\"p\":1,\"n\":\"Debris\"},{\"t\":3,\"p\":1,\"n\":\"Debris Count\"}]},{\"t\":6,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"DMDL - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"DMDT - Texture Files Hashes\"},{\"t\":7,\"p\":1,\"n\":\"DMDS - Alternate Textures\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"3D Name\"},{\"t\":3,\"p\":1,\"n\":\"New Texture\"},{\"t\":3,\"p\":1,\"n\":\"3D Index\"}]}]}]},{\"p\":1,\"n\":\"DSTF - End Marker\"}]}]}]},{\"t\":3,\"p\":1,\"n\":\"YNAM - Sound - Pick Up\"},{\"t\":3,\"p\":1,\"n\":\"ZNAM - Sound - Put Down\"},{\"t\":3,\"n\":\"KSIZ - Keyword Count\"},{\"t\":7,\"p\":1,\"n\":\"KWDA - Keywords\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Keyword\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DATA - Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Skill\"},{\"t\":3,\"p\":1,\"n\":\"Spell\"},{\"t\":3,\"p\":1,\"n\":\"Value\"},{\"t\":5,\"p\":1,\"n\":\"Weight\"}]},{\"t\":3,\"p\":1,\"n\":\"INAM - Inventory Art\"},{\"t\":2,\"p\":1,\"n\":\"CNAM - Description\"}]},{\"t\":1,\"p\":1,\"n\":\"BPTD - Body Part Data\",\"f\":1,\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"MODT - Texture Files Hashes\"},{\"t\":7,\"p\":1,\"n\":\"MODS - Alternate Textures\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"3D Name\"},{\"t\":3,\"p\":1,\"n\":\"New Texture\"},{\"t\":3,\"p\":1,\"n\":\"3D Index\"}]}]}]},{\"t\":10,\"p\":1,\"n\":\"Body Parts\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Body Part\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"BPTN - Part Name\"},{\"t\":2,\"p\":1,\"n\":\"PNAM - Pose Matching\"},{\"t\":2,\"p\":1,\"n\":\"BPNN - Part Node\"},{\"t\":2,\"p\":1,\"n\":\"BPNT - VATS Target\"},{\"t\":2,\"p\":1,\"n\":\"BPNI - IK Data - Start Node\"},{\"t\":6,\"p\":1,\"n\":\"BPND - \",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Damage Mult\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":3,\"p\":1,\"n\":\"Part Type\"},{\"t\":3,\"p\":1,\"n\":\"Health Percent\"},{\"t\":3,\"p\":1,\"n\":\"Actor Value\"},{\"t\":3,\"p\":1,\"n\":\"To Hit Chance\"},{\"t\":3,\"p\":1,\"n\":\"Explodable - Explosion Chance %\"},{\"t\":3,\"p\":1,\"n\":\"Explodable - Debris Count\"},{\"t\":3,\"p\":1,\"n\":\"Explodable - Debris\"},{\"t\":3,\"p\":1,\"n\":\"Explodable - Explosion\"},{\"t\":5,\"p\":1,\"n\":\"Tracking Max Angle\"},{\"t\":5,\"p\":1,\"n\":\"Explodable - Debris Scale\"},{\"t\":3,\"p\":1,\"n\":\"Severable - Debris Count\"},{\"t\":3,\"p\":1,\"n\":\"Severable - Debris\"},{\"t\":3,\"p\":1,\"n\":\"Severable - Explosion\"},{\"t\":5,\"p\":1,\"n\":\"Severable - Debris Scale\"},{\"t\":6,\"p\":1,\"n\":\"Gore Effects Positioning\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Translate\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"X\"},{\"t\":5,\"p\":1,\"n\":\"Y\"},{\"t\":5,\"p\":1,\"n\":\"Z\"}]},{\"t\":6,\"p\":1,\"n\":\"Rotation\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"X\"},{\"t\":5,\"p\":1,\"n\":\"Y\"},{\"t\":5,\"p\":1,\"n\":\"Z\"}]}]},{\"t\":3,\"p\":1,\"n\":\"Severable - Impact DataSet\"},{\"t\":3,\"p\":1,\"n\":\"Explodable - Impact DataSet\"},{\"t\":3,\"p\":1,\"n\":\"Severable - Decal Count\"},{\"t\":3,\"p\":1,\"n\":\"Explodable - Decal Count\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":5,\"p\":1,\"n\":\"Limb Replacement Scale\"}]},{\"t\":2,\"p\":1,\"n\":\"NAM1 - Limb Replacement Model\"},{\"t\":2,\"p\":1,\"n\":\"NAM4 - Gore Effects - Target Bone\"},{\"t\":11,\"p\":1,\"n\":\"NAM5 - Texture Files Hashes\"}]}]}]},{\"t\":1,\"p\":1,\"n\":\"CAMS - Camera Shot\",\"f\":1,\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"MODT - Texture Files Hashes\"},{\"t\":7,\"p\":1,\"n\":\"MODS - Alternate Textures\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"3D Name\"},{\"t\":3,\"p\":1,\"n\":\"New Texture\"},{\"t\":3,\"p\":1,\"n\":\"3D Index\"}]}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DATA - Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Action\"},{\"t\":3,\"p\":1,\"n\":\"Location\"},{\"t\":3,\"p\":1,\"n\":\"Target\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":6,\"p\":1,\"n\":\"Time Multipliers\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Player\"},{\"t\":5,\"p\":1,\"n\":\"Target\"},{\"t\":5,\"p\":1,\"n\":\"Global\"}]},{\"t\":5,\"p\":1,\"n\":\"Max Time\"},{\"t\":5,\"p\":1,\"n\":\"Min Time\"},{\"t\":5,\"p\":1,\"n\":\"Target % Between Actors\"},{\"t\":5,\"p\":1,\"n\":\"Near Target Distance\"}]},{\"t\":3,\"p\":1,\"n\":\"MNAM - Image Space Modifier\"}]},{\"t\":1,\"p\":1,\"n\":\"CELL - Cell\",\"f\":1,\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":3,\"p\":1,\"n\":\"DATA - Flags\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"XCLC - Grid\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"X\"},{\"t\":3,\"p\":1,\"n\":\"Y\"},{\"t\":3,\"p\":1,\"n\":\"Force Hide Land\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"XCLL - Lighting\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Ambient Color\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Directional Color\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Fog Color Near\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":5,\"p\":1,\"n\":\"Fog Near\"},{\"t\":5,\"p\":1,\"n\":\"Fog Far\"},{\"t\":3,\"p\":1,\"n\":\"Directional Rotation XY\"},{\"t\":3,\"p\":1,\"n\":\"Directional Rotation Z\"},{\"t\":5,\"p\":1,\"n\":\"Directional Fade\"},{\"t\":5,\"p\":1,\"n\":\"Fog Clip Distance\"},{\"t\":5,\"p\":1,\"n\":\"Fog Power\"},{\"t\":6,\"p\":1,\"n\":\"Ambient Colors\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Directional\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"X+\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"X-\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Y+\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Y-\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Z+\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Z-\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]}]},{\"t\":6,\"p\":1,\"n\":\"Specular\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":5,\"p\":1,\"n\":\"Scale\"}]},{\"t\":6,\"p\":1,\"n\":\"Fog Color Far\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":5,\"p\":1,\"n\":\"Fog Max\"},{\"t\":5,\"p\":1,\"n\":\"Light Fade Begin\"},{\"t\":5,\"p\":1,\"n\":\"Light Fade End\"},{\"t\":3,\"p\":1,\"n\":\"Inherits\"}]},{\"t\":11,\"n\":\"TVDT - Occlusion Data\"},{\"t\":11,\"n\":\"MHDT - Max Height Data\"},{\"t\":3,\"p\":1,\"n\":\"LTMP - Lighting Template\"},{\"t\":11,\"n\":\"LNAM - Unknown\"},{\"t\":5,\"p\":1,\"n\":\"XCLW - Water Height\"},{\"t\":2,\"p\":1,\"n\":\"XNAM - Water Noise Texture\"},{\"t\":7,\"p\":1,\"n\":\"XCLR - Regions\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Region\"}]},{\"t\":3,\"p\":1,\"n\":\"XLCN - Location\"},{\"t\":11,\"n\":\"XWCN - Unknown\"},{\"t\":11,\"n\":\"XWCS - Unknown\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"XWCU - Water Velocity\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"X Offset\"},{\"t\":5,\"p\":1,\"n\":\"Y Offset\"},{\"t\":5,\"p\":1,\"n\":\"Z Offset\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":5,\"p\":1,\"n\":\"X Angle\"},{\"t\":5,\"p\":1,\"n\":\"Y Angle\"},{\"t\":5,\"p\":1,\"n\":\"Z Angle\"}]},{\"t\":3,\"p\":1,\"n\":\"XCWT - Water\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Ownership\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"XOWN - Owner\"},{\"t\":3,\"p\":1,\"n\":\"XRNK - Faction rank\"}]},{\"t\":3,\"p\":1,\"n\":\"XILL - Lock List\"},{\"t\":2,\"p\":1,\"n\":\"XWEM - Water Environment Map\"},{\"t\":3,\"p\":1,\"n\":\"XCCM - Sky\\/Weather from Region\"},{\"t\":3,\"p\":1,\"n\":\"XCAS - Acoustic Space\"},{\"t\":3,\"p\":1,\"n\":\"XEZN - Encounter Zone\"},{\"t\":3,\"p\":1,\"n\":\"XCMO - Music Type\"},{\"t\":3,\"p\":1,\"n\":\"XCIM - Image Space\"}]},{\"t\":1,\"p\":1,\"n\":\"CLAS - Class\",\"f\":1,\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":2,\"p\":1,\"n\":\"DESC - Description\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Icon\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"ICON - Large Icon filename\"},{\"t\":2,\"p\":1,\"n\":\"MICO - Small Icon filename\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DATA - \",\"c\":[{\"t\":11,\"n\":\"Unknown\"},{\"t\":3,\"p\":1,\"n\":\"Teaches\"},{\"t\":3,\"p\":1,\"n\":\"Maximum training level\"},{\"t\":7,\"p\":1,\"n\":\"Skill Weights\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Weight\"}]},{\"t\":5,\"p\":1,\"n\":\"Bleedout Default\"},{\"t\":3,\"p\":1,\"n\":\"Voice Points\"},{\"t\":7,\"p\":1,\"n\":\"Attribute Weights\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Weight\"}]}]}]},{\"t\":1,\"p\":1,\"n\":\"CLDC\",\"f\":1,\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"}]},{\"t\":1,\"p\":1,\"n\":\"CLFM - Color\",\"f\":1,\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"CNAM - Color\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":3,\"p\":1,\"n\":\"FNAM - Playable\"}]},{\"t\":1,\"p\":1,\"n\":\"CLMT - Climate\",\"f\":1,\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":7,\"p\":1,\"n\":\"WLST - Weather Types\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Weather Type\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Weather\"},{\"t\":3,\"p\":1,\"n\":\"Chance\"},{\"t\":3,\"p\":1,\"n\":\"Global\"}]}]},{\"t\":2,\"p\":1,\"n\":\"FNAM - Sun Texture\"},{\"t\":2,\"p\":1,\"n\":\"GNAM - Sun Glare Texture\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"MODT - Texture Files Hashes\"},{\"t\":7,\"p\":1,\"n\":\"MODS - Alternate Textures\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"3D Name\"},{\"t\":3,\"p\":1,\"n\":\"New Texture\"},{\"t\":3,\"p\":1,\"n\":\"3D Index\"}]}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"TNAM - Timing\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Sunrise\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Begin\"},{\"t\":3,\"p\":1,\"n\":\"End\"}]},{\"t\":6,\"p\":1,\"n\":\"Sunset\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Begin\"},{\"t\":3,\"p\":1,\"n\":\"End\"}]},{\"t\":3,\"p\":1,\"n\":\"Volatility\"},{\"t\":3,\"p\":1,\"n\":\"Moons \\/ Phase Length\"}]}]},{\"t\":1,\"p\":1,\"n\":\"COBJ - Constructible Object\",\"f\":1,\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":3,\"n\":\"COCT - Count\"},{\"t\":10,\"p\":1,\"n\":\"Items\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Item\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"CNTO - Item\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Item\"},{\"t\":3,\"p\":1,\"n\":\"Count\"}]},{\"t\":6,\"p\":1,\"n\":\"COED - Extra Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Owner\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Global Variable\"},{\"t\":3,\"p\":1,\"n\":\"Required Rank\"},{\"t\":5,\"p\":1,\"n\":\"Item Condition\"}]}]}]},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Conditions\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Condition\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"CTDA - \",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":5,\"p\":1,\"n\":\"Comparison Value - Float\"},{\"t\":3,\"p\":1,\"n\":\"Comparison Value - Global\"},{\"t\":3,\"p\":1,\"n\":\"Function\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":11,\"p\":1,\"n\":\"None\"},{\"t\":3,\"p\":1,\"n\":\"Integer\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":11,\"p\":1,\"n\":\"Variable Name (unused)\"},{\"t\":3,\"p\":1,\"n\":\"Sex\"},{\"t\":3,\"p\":1,\"n\":\"Actor Value\"},{\"t\":3,\"p\":1,\"n\":\"Crime Type\"},{\"t\":3,\"p\":1,\"n\":\"Axis\"},{\"t\":3,\"p\":1,\"n\":\"Quest Stage (unused)\"},{\"t\":3,\"p\":1,\"n\":\"Misc Stat\"},{\"t\":3,\"p\":1,\"n\":\"Alignment\"},{\"t\":3,\"p\":1,\"n\":\"Equip Type\"},{\"t\":3,\"p\":1,\"n\":\"Form Type\"},{\"t\":3,\"p\":1,\"n\":\"Critical Stage\"},{\"t\":3,\"p\":1,\"n\":\"Object Reference\"},{\"t\":3,\"p\":1,\"n\":\"Inventory Object\"},{\"t\":3,\"p\":1,\"n\":\"Actor\"},{\"t\":3,\"p\":1,\"n\":\"Voice Type\"},{\"t\":3,\"p\":1,\"n\":\"Idle\"},{\"t\":3,\"p\":1,\"n\":\"Form List\"},{\"t\":3,\"p\":1,\"n\":\"Quest\"},{\"t\":3,\"p\":1,\"n\":\"Faction\"},{\"t\":3,\"p\":1,\"n\":\"Cell\"},{\"t\":3,\"p\":1,\"n\":\"Class\"},{\"t\":3,\"p\":1,\"n\":\"Race\"},{\"t\":3,\"p\":1,\"n\":\"Actor Base\"},{\"t\":3,\"p\":1,\"n\":\"Global\"},{\"t\":3,\"p\":1,\"n\":\"Weather\"},{\"t\":3,\"p\":1,\"n\":\"Package\"},{\"t\":3,\"p\":1,\"n\":\"Encounter Zone\"},{\"t\":3,\"p\":1,\"n\":\"Perk\"},{\"t\":3,\"p\":1,\"n\":\"Owner\"},{\"t\":3,\"p\":1,\"n\":\"Furniture\"},{\"t\":3,\"p\":1,\"n\":\"Effect Item\"},{\"t\":3,\"p\":1,\"n\":\"Base Effect\"},{\"t\":3,\"p\":1,\"n\":\"Worldspace\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Function\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Param (INVALID)\"},{\"t\":3,\"p\":1,\"n\":\"Referenceable Object\"},{\"t\":3,\"p\":1,\"n\":\"Region\"},{\"t\":3,\"p\":1,\"n\":\"Keyword\"},{\"t\":3,\"p\":1,\"n\":\"Player Action\"},{\"t\":3,\"p\":1,\"n\":\"Casting Type\"},{\"t\":3,\"p\":1,\"n\":\"Shout\"},{\"t\":3,\"p\":1,\"n\":\"Location\"},{\"t\":3,\"p\":1,\"n\":\"Location Ref Type\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"Packdata ID\"},{\"t\":3,\"p\":1,\"n\":\"Association Type\"},{\"t\":3,\"p\":1,\"n\":\"Furniture Anim\"},{\"t\":3,\"p\":1,\"n\":\"Furniture Entry\"},{\"t\":3,\"p\":1,\"n\":\"Scene\"},{\"t\":3,\"p\":1,\"n\":\"Ward State\"},{\"t\":3,\"p\":1,\"n\":\"Event\"},{\"t\":3,\"p\":1,\"n\":\"Event Data\"},{\"t\":3,\"p\":1,\"n\":\"Quest Stage\"},{\"t\":3,\"p\":1,\"n\":\"Weapon\"},{\"t\":3,\"p\":1,\"n\":\"Weapon List\"},{\"t\":3,\"p\":1,\"n\":\"Target\"},{\"t\":3,\"p\":1,\"n\":\"Target List\"},{\"t\":3,\"p\":1,\"n\":\"Target Part\"},{\"t\":3,\"p\":1,\"n\":\"VATS Action\"},{\"t\":3,\"p\":1,\"n\":\"Critical Effect\"},{\"t\":3,\"p\":1,\"n\":\"Critical Effect List\"},{\"t\":3,\"p\":1,\"n\":\"Weapon Type\"},{\"t\":3,\"p\":1,\"n\":\"Projectile Type\"},{\"t\":3,\"p\":1,\"n\":\"Delivery Type\"},{\"t\":3,\"p\":1,\"n\":\"Run On\"},{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":3,\"p\":1,\"n\":\"Parameter #3\"}]},{\"t\":2,\"p\":1,\"n\":\"CIS1 - Parameter #1\"},{\"t\":2,\"p\":1,\"n\":\"CIS2 - Parameter #2\"}]}]},{\"t\":3,\"p\":1,\"n\":\"CNAM - Created Object\"},{\"t\":3,\"p\":1,\"n\":\"BNAM - Workbench Keyword\"},{\"t\":3,\"p\":1,\"n\":\"NAM1 - Created Object Count\"}]},{\"t\":1,\"p\":1,\"n\":\"COLL - Collision Layer\",\"f\":1,\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"p\":1,\"n\":\"DESC - Description\"},{\"t\":3,\"p\":1,\"n\":\"BNAM - Index\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"FNAM - Debug Color\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":3,\"n\":\"Unused\"}]},{\"t\":3,\"p\":1,\"n\":\"GNAM - Flags\"},{\"t\":2,\"p\":1,\"n\":\"MNAM - Name\"},{\"t\":3,\"n\":\"INTV - Interactables Count\"},{\"t\":7,\"p\":1,\"n\":\"CNAM - Collides With\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Forms\"}]}]},{\"t\":1,\"p\":1,\"n\":\"CONT - Container\",\"f\":1,\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"VMAD - Virtual Machine Adapter\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Version\"},{\"t\":3,\"p\":1,\"n\":\"Object Format\"},{\"t\":7,\"p\":1,\"n\":\"Scripts\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Script\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"scriptName\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":7,\"p\":1,\"n\":\"Properties\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Property\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"propertyName\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]},{\"t\":2,\"p\":1,\"n\":\"String\"},{\"t\":3,\"p\":1,\"n\":\"Int32\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":3,\"p\":1,\"n\":\"Bool\"},{\"t\":7,\"p\":1,\"n\":\"Array of Object\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]}]},{\"t\":7,\"p\":1,\"n\":\"Array of String\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Int32\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Float\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Bool\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]}]}]}]}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"X1\"},{\"t\":3,\"p\":1,\"n\":\"Y1\"},{\"t\":3,\"p\":1,\"n\":\"Z1\"},{\"t\":3,\"p\":1,\"n\":\"X2\"},{\"t\":3,\"p\":1,\"n\":\"Y2\"},{\"t\":3,\"p\":1,\"n\":\"Z2\"}]},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"MODT - Texture Files Hashes\"},{\"t\":7,\"p\":1,\"n\":\"MODS - Alternate Textures\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"3D Name\"},{\"t\":3,\"p\":1,\"n\":\"New Texture\"},{\"t\":3,\"p\":1,\"n\":\"3D Index\"}]}]}]},{\"t\":3,\"n\":\"COCT - Count\"},{\"t\":10,\"p\":1,\"n\":\"Items\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Item\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"CNTO - Item\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Item\"},{\"t\":3,\"p\":1,\"n\":\"Count\"}]},{\"t\":6,\"p\":1,\"n\":\"COED - Extra Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Owner\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Global Variable\"},{\"t\":3,\"p\":1,\"n\":\"Required Rank\"},{\"t\":5,\"p\":1,\"n\":\"Item Condition\"}]}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Destructable\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"DEST - Header\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Health\"},{\"t\":3,\"p\":1,\"n\":\"DEST Count\"},{\"t\":3,\"p\":1,\"n\":\"VATS Targetable\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":8,\"p\":1,\"n\":\"Stages\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Stage\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"DSTD - Destruction Stage Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Health %\"},{\"t\":3,\"p\":1,\"n\":\"Index\"},{\"t\":3,\"p\":1,\"n\":\"Model Damage Stage\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":3,\"p\":1,\"n\":\"Self Damage per Second\"},{\"t\":3,\"p\":1,\"n\":\"Explosion\"},{\"t\":3,\"p\":1,\"n\":\"Debris\"},{\"t\":3,\"p\":1,\"n\":\"Debris Count\"}]},{\"t\":6,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"DMDL - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"DMDT - Texture Files Hashes\"},{\"t\":7,\"p\":1,\"n\":\"DMDS - Alternate Textures\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"3D Name\"},{\"t\":3,\"p\":1,\"n\":\"New Texture\"},{\"t\":3,\"p\":1,\"n\":\"3D Index\"}]}]}]},{\"p\":1,\"n\":\"DSTF - End Marker\"}]}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DATA - \",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":5,\"p\":1,\"n\":\"Weight\"}]},{\"t\":3,\"p\":1,\"n\":\"SNAM - Sound - Open\"},{\"t\":3,\"p\":1,\"n\":\"QNAM - Sound - Close\"}]},{\"t\":1,\"p\":1,\"n\":\"CPTH - Camera Path\",\"f\":1,\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Conditions\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Condition\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"CTDA - \",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":5,\"p\":1,\"n\":\"Comparison Value - Float\"},{\"t\":3,\"p\":1,\"n\":\"Comparison Value - Global\"},{\"t\":3,\"p\":1,\"n\":\"Function\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":11,\"p\":1,\"n\":\"None\"},{\"t\":3,\"p\":1,\"n\":\"Integer\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":11,\"p\":1,\"n\":\"Variable Name (unused)\"},{\"t\":3,\"p\":1,\"n\":\"Sex\"},{\"t\":3,\"p\":1,\"n\":\"Actor Value\"},{\"t\":3,\"p\":1,\"n\":\"Crime Type\"},{\"t\":3,\"p\":1,\"n\":\"Axis\"},{\"t\":3,\"p\":1,\"n\":\"Quest Stage (unused)\"},{\"t\":3,\"p\":1,\"n\":\"Misc Stat\"},{\"t\":3,\"p\":1,\"n\":\"Alignment\"},{\"t\":3,\"p\":1,\"n\":\"Equip Type\"},{\"t\":3,\"p\":1,\"n\":\"Form Type\"},{\"t\":3,\"p\":1,\"n\":\"Critical Stage\"},{\"t\":3,\"p\":1,\"n\":\"Object Reference\"},{\"t\":3,\"p\":1,\"n\":\"Inventory Object\"},{\"t\":3,\"p\":1,\"n\":\"Actor\"},{\"t\":3,\"p\":1,\"n\":\"Voice Type\"},{\"t\":3,\"p\":1,\"n\":\"Idle\"},{\"t\":3,\"p\":1,\"n\":\"Form List\"},{\"t\":3,\"p\":1,\"n\":\"Quest\"},{\"t\":3,\"p\":1,\"n\":\"Faction\"},{\"t\":3,\"p\":1,\"n\":\"Cell\"},{\"t\":3,\"p\":1,\"n\":\"Class\"},{\"t\":3,\"p\":1,\"n\":\"Race\"},{\"t\":3,\"p\":1,\"n\":\"Actor Base\"},{\"t\":3,\"p\":1,\"n\":\"Global\"},{\"t\":3,\"p\":1,\"n\":\"Weather\"},{\"t\":3,\"p\":1,\"n\":\"Package\"},{\"t\":3,\"p\":1,\"n\":\"Encounter Zone\"},{\"t\":3,\"p\":1,\"n\":\"Perk\"},{\"t\":3,\"p\":1,\"n\":\"Owner\"},{\"t\":3,\"p\":1,\"n\":\"Furniture\"},{\"t\":3,\"p\":1,\"n\":\"Effect Item\"},{\"t\":3,\"p\":1,\"n\":\"Base Effect\"},{\"t\":3,\"p\":1,\"n\":\"Worldspace\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Function\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Param (INVALID)\"},{\"t\":3,\"p\":1,\"n\":\"Referenceable Object\"},{\"t\":3,\"p\":1,\"n\":\"Region\"},{\"t\":3,\"p\":1,\"n\":\"Keyword\"},{\"t\":3,\"p\":1,\"n\":\"Player Action\"},{\"t\":3,\"p\":1,\"n\":\"Casting Type\"},{\"t\":3,\"p\":1,\"n\":\"Shout\"},{\"t\":3,\"p\":1,\"n\":\"Location\"},{\"t\":3,\"p\":1,\"n\":\"Location Ref Type\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"Packdata ID\"},{\"t\":3,\"p\":1,\"n\":\"Association Type\"},{\"t\":3,\"p\":1,\"n\":\"Furniture Anim\"},{\"t\":3,\"p\":1,\"n\":\"Furniture Entry\"},{\"t\":3,\"p\":1,\"n\":\"Scene\"},{\"t\":3,\"p\":1,\"n\":\"Ward State\"},{\"t\":3,\"p\":1,\"n\":\"Event\"},{\"t\":3,\"p\":1,\"n\":\"Event Data\"},{\"t\":3,\"p\":1,\"n\":\"Quest Stage\"},{\"t\":3,\"p\":1,\"n\":\"Weapon\"},{\"t\":3,\"p\":1,\"n\":\"Weapon List\"},{\"t\":3,\"p\":1,\"n\":\"Target\"},{\"t\":3,\"p\":1,\"n\":\"Target List\"},{\"t\":3,\"p\":1,\"n\":\"Target Part\"},{\"t\":3,\"p\":1,\"n\":\"VATS Action\"},{\"t\":3,\"p\":1,\"n\":\"Critical Effect\"},{\"t\":3,\"p\":1,\"n\":\"Critical Effect List\"},{\"t\":3,\"p\":1,\"n\":\"Weapon Type\"},{\"t\":3,\"p\":1,\"n\":\"Projectile Type\"},{\"t\":3,\"p\":1,\"n\":\"Delivery Type\"},{\"t\":3,\"p\":1,\"n\":\"Run On\"},{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":3,\"p\":1,\"n\":\"Parameter #3\"}]},{\"t\":2,\"p\":1,\"n\":\"CIS1 - Parameter #1\"},{\"t\":2,\"p\":1,\"n\":\"CIS2 - Parameter #2\"}]}]},{\"t\":7,\"p\":1,\"n\":\"ANAM - Related Camera Paths\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Related Camera Path\"}]},{\"t\":3,\"p\":1,\"n\":\"DATA - Camera Zoom\"},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Camera Shots\",\"d\":1,\"c\":[{\"t\":3,\"p\":1,\"n\":\"SNAM - Camera Shot\"}]}]},{\"t\":1,\"p\":1,\"n\":\"CSTY - Combat Style\",\"f\":1,\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"CSGD - General\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Offensive Mult\"},{\"t\":5,\"p\":1,\"n\":\"Defensive Mult\"},{\"t\":5,\"p\":1,\"n\":\"Group Offensive Mult\"},{\"t\":5,\"p\":1,\"n\":\"Equipment Score Mult - Melee\"},{\"t\":5,\"p\":1,\"n\":\"Equipment Score Mult - Magic\"},{\"t\":5,\"p\":1,\"n\":\"Equipment Score Mult - Ranged\"},{\"t\":5,\"p\":1,\"n\":\"Equipment Score Mult - Shout\"},{\"t\":5,\"p\":1,\"n\":\"Equipment Score Mult - Unarmed\"},{\"t\":5,\"p\":1,\"n\":\"Equipment Score Mult - Staff\"},{\"t\":5,\"p\":1,\"n\":\"Avoid Threat Chance\"}]},{\"t\":11,\"n\":\"CSMD - Unknown\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"CSME - Melee\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Attack Staggered Mult\"},{\"t\":5,\"p\":1,\"n\":\"Power Attack Staggered Mult\"},{\"t\":5,\"p\":1,\"n\":\"Power Attack Blocking Mult\"},{\"t\":5,\"p\":1,\"n\":\"Bash Mult\"},{\"t\":5,\"p\":1,\"n\":\"Bash Recoil Mult\"},{\"t\":5,\"p\":1,\"n\":\"Bash Attack Mult\"},{\"t\":5,\"p\":1,\"n\":\"Bash Power Attack Mult\"},{\"t\":5,\"p\":1,\"n\":\"Special Attack Mult\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"CSCR - Close Range\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Circle Mult\"},{\"t\":5,\"p\":1,\"n\":\"Fallback Mult\"},{\"t\":5,\"p\":1,\"n\":\"Flank Distance\"},{\"t\":5,\"p\":1,\"n\":\"Stalk Time\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"CSLR - Long Range\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Strafe Mult\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"CSFL - Flight\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Hover Chance\"},{\"t\":5,\"p\":1,\"n\":\"Dive Bomb Chance\"},{\"t\":5,\"p\":1,\"n\":\"Ground Attack Chance\"},{\"t\":5,\"p\":1,\"n\":\"Hover Time\"},{\"t\":5,\"p\":1,\"n\":\"Ground Attack Time\"},{\"t\":5,\"p\":1,\"n\":\"Perch Attack Chance\"},{\"t\":5,\"p\":1,\"n\":\"Perch Attack Time\"},{\"t\":5,\"p\":1,\"n\":\"Flying Attack Chance\"}]},{\"t\":3,\"p\":1,\"n\":\"DATA - Flags\"}]},{\"t\":1,\"p\":1,\"n\":\"DEBR - Debris\",\"f\":1,\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Models\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"DATA - Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Percentage\"},{\"t\":2,\"p\":1,\"n\":\"Model Filename\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"}]},{\"t\":11,\"p\":1,\"n\":\"MODT - Texture Files Hashes\"}]}]}]},{\"t\":1,\"p\":1,\"n\":\"DIAL - Dialog Topic\",\"f\":1,\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":5,\"p\":1,\"n\":\"PNAM - Priority\"},{\"t\":3,\"p\":1,\"n\":\"BNAM - Branch\"},{\"t\":3,\"p\":1,\"n\":\"QNAM - Quest\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DATA - Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Topic Flags\"},{\"t\":3,\"p\":1,\"n\":\"Category\"},{\"t\":3,\"p\":1,\"n\":\"Subtype\"}]},{\"t\":2,\"p\":1,\"n\":\"SNAM - Subtype Name\"},{\"t\":3,\"p\":1,\"n\":\"TIFC - Info Count\"}]},{\"t\":1,\"p\":1,\"n\":\"DLBR - Dialog Branch\",\"f\":1,\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":3,\"p\":1,\"n\":\"QNAM - Quest\"},{\"t\":3,\"n\":\"TNAM - Unknown\"},{\"t\":3,\"p\":1,\"n\":\"DNAM - Flags\"},{\"t\":3,\"p\":1,\"n\":\"SNAM - Starting Topic\"}]},{\"t\":1,\"p\":1,\"n\":\"DLVW - Dialog View\",\"f\":1,\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":3,\"p\":1,\"n\":\"QNAM - Quest\"},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Branches\",\"d\":1,\"c\":[{\"t\":3,\"p\":1,\"n\":\"BNAM - Branch\"}]},{\"t\":8,\"n\":\"Unknown TNAM\",\"c\":[{\"t\":6,\"n\":\"Unknown\",\"c\":[{\"t\":11,\"n\":\"TNAM - Unknown\"}]}]},{\"t\":11,\"n\":\"ENAM - Unknown\"},{\"t\":11,\"n\":\"DNAM - Unknown\"}]},{\"t\":1,\"n\":\"DOBJ - Default Object Manager\",\"c\":[{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":7,\"n\":\"DNAM - Objects\",\"c\":[{\"t\":6,\"n\":\"Object\",\"c\":[{\"t\":3,\"n\":\"Use\"},{\"t\":3,\"n\":\"Object ID\"}]}]}]},{\"t\":1,\"p\":1,\"n\":\"DOOR - Door\",\"f\":1,\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"VMAD - Virtual Machine Adapter\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Version\"},{\"t\":3,\"p\":1,\"n\":\"Object Format\"},{\"t\":7,\"p\":1,\"n\":\"Scripts\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Script\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"scriptName\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":7,\"p\":1,\"n\":\"Properties\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Property\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"propertyName\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]},{\"t\":2,\"p\":1,\"n\":\"String\"},{\"t\":3,\"p\":1,\"n\":\"Int32\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":3,\"p\":1,\"n\":\"Bool\"},{\"t\":7,\"p\":1,\"n\":\"Array of Object\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]}]},{\"t\":7,\"p\":1,\"n\":\"Array of String\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Int32\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Float\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Bool\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]}]}]}]}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"X1\"},{\"t\":3,\"p\":1,\"n\":\"Y1\"},{\"t\":3,\"p\":1,\"n\":\"Z1\"},{\"t\":3,\"p\":1,\"n\":\"X2\"},{\"t\":3,\"p\":1,\"n\":\"Y2\"},{\"t\":3,\"p\":1,\"n\":\"Z2\"}]},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"MODT - Texture Files Hashes\"},{\"t\":7,\"p\":1,\"n\":\"MODS - Alternate Textures\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"3D Name\"},{\"t\":3,\"p\":1,\"n\":\"New Texture\"},{\"t\":3,\"p\":1,\"n\":\"3D Index\"}]}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Destructable\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"DEST - Header\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Health\"},{\"t\":3,\"p\":1,\"n\":\"DEST Count\"},{\"t\":3,\"p\":1,\"n\":\"VATS Targetable\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":8,\"p\":1,\"n\":\"Stages\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Stage\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"DSTD - Destruction Stage Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Health %\"},{\"t\":3,\"p\":1,\"n\":\"Index\"},{\"t\":3,\"p\":1,\"n\":\"Model Damage Stage\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":3,\"p\":1,\"n\":\"Self Damage per Second\"},{\"t\":3,\"p\":1,\"n\":\"Explosion\"},{\"t\":3,\"p\":1,\"n\":\"Debris\"},{\"t\":3,\"p\":1,\"n\":\"Debris Count\"}]},{\"t\":6,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"DMDL - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"DMDT - Texture Files Hashes\"},{\"t\":7,\"p\":1,\"n\":\"DMDS - Alternate Textures\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"3D Name\"},{\"t\":3,\"p\":1,\"n\":\"New Texture\"},{\"t\":3,\"p\":1,\"n\":\"3D Index\"}]}]}]},{\"p\":1,\"n\":\"DSTF - End Marker\"}]}]}]},{\"t\":3,\"p\":1,\"n\":\"SNAM - Sound - Open\"},{\"t\":3,\"p\":1,\"n\":\"ANAM - Sound - Close\"},{\"t\":3,\"p\":1,\"n\":\"BNAM - Sound - Loop\"},{\"t\":3,\"p\":1,\"n\":\"FNAM - Flags\"}]},{\"t\":1,\"p\":1,\"n\":\"DUAL - Dual Cast Data\",\"f\":1,\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"X1\"},{\"t\":3,\"p\":1,\"n\":\"Y1\"},{\"t\":3,\"p\":1,\"n\":\"Z1\"},{\"t\":3,\"p\":1,\"n\":\"X2\"},{\"t\":3,\"p\":1,\"n\":\"Y2\"},{\"t\":3,\"p\":1,\"n\":\"Z2\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DATA - Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Projectile\"},{\"t\":3,\"p\":1,\"n\":\"Explosion\"},{\"t\":3,\"p\":1,\"n\":\"Effect Shader\"},{\"t\":3,\"p\":1,\"n\":\"Hit Effect Art\"},{\"t\":3,\"p\":1,\"n\":\"Impact Data Set\"},{\"t\":3,\"p\":1,\"n\":\"Inherit Scale\"}]}]},{\"t\":1,\"p\":1,\"n\":\"ECZN - Encounter Zone\",\"f\":1,\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DATA - \",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Owner\"},{\"t\":3,\"p\":1,\"n\":\"Location\"},{\"t\":3,\"p\":1,\"n\":\"Rank\"},{\"t\":3,\"p\":1,\"n\":\"Min Level\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":3,\"p\":1,\"n\":\"Max Level\"}]}]},{\"t\":1,\"p\":1,\"n\":\"EFSH - Effect Shader\",\"f\":1,\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"p\":1,\"n\":\"ICON - Fill Texture\"},{\"t\":2,\"p\":1,\"n\":\"ICO2 - Particle Shader Texture\"},{\"t\":2,\"p\":1,\"n\":\"NAM7 - Holes Texture\"},{\"t\":2,\"p\":1,\"n\":\"NAM8 - Membrane Palette Texture\"},{\"t\":2,\"p\":1,\"n\":\"NAM9 - Particle Palette Texture\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DATA - \",\"c\":[{\"t\":11,\"n\":\"Unknown\"},{\"t\":3,\"p\":1,\"n\":\"Membrane Shader - Source Blend Mode\"},{\"t\":3,\"p\":1,\"n\":\"Membrane Shader - Blend Operation\"},{\"t\":3,\"p\":1,\"n\":\"Membrane Shader - Z Test Function\"},{\"t\":6,\"p\":1,\"n\":\"Fill\\/Texture Effect - Color Key 1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":5,\"p\":1,\"n\":\"Fill\\/Texture Effect - Alpha Fade In Time\"},{\"t\":5,\"p\":1,\"n\":\"Fill\\/Texture Effect - Full Alpha Time\"},{\"t\":5,\"p\":1,\"n\":\"Fill\\/Texture Effect - Alpha Fade Out Time\"},{\"t\":5,\"p\":1,\"n\":\"Fill\\/Texture Effect - Presistent Alpha Ratio\"},{\"t\":5,\"p\":1,\"n\":\"Fill\\/Texture Effect - Alpha Pulse Amplitude\"},{\"t\":5,\"p\":1,\"n\":\"Fill\\/Texture Effect - Alpha Pulse Frequency\"},{\"t\":5,\"p\":1,\"n\":\"Fill\\/Texture Effect - Texture Animation Speed (U)\"},{\"t\":5,\"p\":1,\"n\":\"Fill\\/Texture Effect - Texture Animation Speed (V)\"},{\"t\":5,\"p\":1,\"n\":\"Edge Effect - Fall Off\"},{\"t\":6,\"p\":1,\"n\":\"Edge Effect - Color\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":5,\"p\":1,\"n\":\"Edge Effect - Alpha Fade In Time\"},{\"t\":5,\"p\":1,\"n\":\"Edge Effect - Full Alpha Time\"},{\"t\":5,\"p\":1,\"n\":\"Edge Effect - Alpha Fade Out Time\"},{\"t\":5,\"p\":1,\"n\":\"Edge Effect - Persistent Alpha Ratio\"},{\"t\":5,\"p\":1,\"n\":\"Edge Effect - Alpha Pulse Amplitude\"},{\"t\":5,\"p\":1,\"n\":\"Edge Effect - Alpha Pulse Frequency\"},{\"t\":5,\"p\":1,\"n\":\"Fill\\/Texture Effect - Full Alpha Ratio\"},{\"t\":5,\"p\":1,\"n\":\"Edge Effect - Full Alpha Ratio\"},{\"t\":3,\"p\":1,\"n\":\"Membrane Shader - Dest Blend Mode\"},{\"t\":3,\"p\":1,\"n\":\"Particle Shader - Source Blend Mode\"},{\"t\":3,\"p\":1,\"n\":\"Particle Shader - Blend Operation\"},{\"t\":3,\"p\":1,\"n\":\"Particle Shader - Z Test Function\"},{\"t\":3,\"p\":1,\"n\":\"Particle Shader - Dest Blend Mode\"},{\"t\":5,\"p\":1,\"n\":\"Particle Shader - Particle Birth Ramp Up Time\"},{\"t\":5,\"p\":1,\"n\":\"Particle Shader - Full Particle Birth Time\"},{\"t\":5,\"p\":1,\"n\":\"Particle Shader - Particle Birth Ramp Down Time\"},{\"t\":5,\"p\":1,\"n\":\"Particle Shader - Full Particle Birth Ratio\"},{\"t\":5,\"p\":1,\"n\":\"Particle Shader - Persistant Particle Count\"},{\"t\":5,\"p\":1,\"n\":\"Particle Shader - Particle Lifetime\"},{\"t\":5,\"p\":1,\"n\":\"Particle Shader - Particle Lifetime +\\/-\"},{\"t\":5,\"p\":1,\"n\":\"Particle Shader - Initial Speed Along Normal\"},{\"t\":5,\"p\":1,\"n\":\"Particle Shader - Acceleration Along Normal\"},{\"t\":5,\"p\":1,\"n\":\"Particle Shader - Initial Velocity #1\"},{\"t\":5,\"p\":1,\"n\":\"Particle Shader - Initial Velocity #2\"},{\"t\":5,\"p\":1,\"n\":\"Particle Shader - Initial Velocity #3\"},{\"t\":5,\"p\":1,\"n\":\"Particle Shader - Acceleration #1\"},{\"t\":5,\"p\":1,\"n\":\"Particle Shader - Acceleration #2\"},{\"t\":5,\"p\":1,\"n\":\"Particle Shader - Acceleration #3\"},{\"t\":5,\"p\":1,\"n\":\"Particle Shader - Scale Key 1\"},{\"t\":5,\"p\":1,\"n\":\"Particle Shader - Scale Key 2\"},{\"t\":5,\"p\":1,\"n\":\"Particle Shader - Scale Key 1 Time\"},{\"t\":5,\"p\":1,\"n\":\"Particle Shader - Scale Key 2 Time\"},{\"t\":6,\"p\":1,\"n\":\"Color Key 1 - Color\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Color Key 2 - Color\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Color Key 3 - Color\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":5,\"p\":1,\"n\":\"Color Key 1 - Color Alpha\"},{\"t\":5,\"p\":1,\"n\":\"Color Key 2 - Color Alpha\"},{\"t\":5,\"p\":1,\"n\":\"Color Key 3 - Color Alpha\"},{\"t\":5,\"p\":1,\"n\":\"Color Key 1 - Color Key Time\"},{\"t\":5,\"p\":1,\"n\":\"Color Key 2 - Color Key Time\"},{\"t\":5,\"p\":1,\"n\":\"Color Key 3 - Color Key Time\"},{\"t\":5,\"p\":1,\"n\":\"Particle Shader - Initial Speed Along Normal +\\/-\"},{\"t\":5,\"p\":1,\"n\":\"Particle Shader - Initial Rotation (deg)\"},{\"t\":5,\"p\":1,\"n\":\"Particle Shader - Initial Rotation (deg) +\\/-\"},{\"t\":5,\"p\":1,\"n\":\"Particle Shader - Rotation Speed (deg\\/sec)\"},{\"t\":5,\"p\":1,\"n\":\"Particle Shader - Rotation Speed (deg\\/sec) +\\/-\"},{\"t\":3,\"p\":1,\"n\":\"Addon Models\"},{\"t\":5,\"p\":1,\"n\":\"Holes - Start Time\"},{\"t\":5,\"p\":1,\"n\":\"Holes - End Time\"},{\"t\":5,\"p\":1,\"n\":\"Holes - Start Val\"},{\"t\":5,\"p\":1,\"n\":\"Holes - End Val\"},{\"t\":5,\"p\":1,\"n\":\"Edge Width (alpha units)\"},{\"t\":6,\"p\":1,\"n\":\"Edge Color\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":5,\"p\":1,\"n\":\"Explosion Wind Speed\"},{\"t\":3,\"p\":1,\"n\":\"Texture Count U\"},{\"t\":3,\"p\":1,\"n\":\"Texture Count V\"},{\"t\":5,\"p\":1,\"n\":\"Addon Models - Fade In Time\"},{\"t\":5,\"p\":1,\"n\":\"Addon Models - Fade Out Time\"},{\"t\":5,\"p\":1,\"n\":\"Addon Models - Scale Start\"},{\"t\":5,\"p\":1,\"n\":\"Addon Models - Scale End\"},{\"t\":5,\"p\":1,\"n\":\"Addon Models - Scale In Time\"},{\"t\":5,\"p\":1,\"n\":\"Addon Models - Scale Out Time\"},{\"t\":3,\"p\":1,\"n\":\"Ambient Sound\"},{\"t\":6,\"p\":1,\"n\":\"Fill\\/Texture Effect - Color Key 2\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Fill\\/Texture Effect - Color Key 3\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Fill\\/Texture Effect - Color Key Scale\\/Time\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Color Key 1 - Scale\"},{\"t\":5,\"p\":1,\"n\":\"Color Key 2 - Scale\"},{\"t\":5,\"p\":1,\"n\":\"Color Key 3 - Scale\"},{\"t\":5,\"p\":1,\"n\":\"Color Key 1 - Time\"},{\"t\":5,\"p\":1,\"n\":\"Color Key 2 - Time\"},{\"t\":5,\"p\":1,\"n\":\"Color Key 3 - Time\"}]},{\"t\":5,\"p\":1,\"n\":\"Color Scale\"},{\"t\":5,\"p\":1,\"n\":\"Birth Position Offset\"},{\"t\":5,\"p\":1,\"n\":\"Birth Position Offset Range +\\/-\"},{\"t\":6,\"p\":1,\"n\":\"Particle Shader Animated\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Start Frame\"},{\"t\":3,\"p\":1,\"n\":\"Start Frame Variation\"},{\"t\":3,\"p\":1,\"n\":\"End Frame\"},{\"t\":3,\"p\":1,\"n\":\"Loop Start Frame\"},{\"t\":3,\"p\":1,\"n\":\"Loop Start Variation\"},{\"t\":3,\"p\":1,\"n\":\"Frame Count\"},{\"t\":3,\"p\":1,\"n\":\"Frame Count Variation\"}]},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":5,\"p\":1,\"n\":\"Fill\\/Texture Effect - Texture Scale (U)\"},{\"t\":5,\"p\":1,\"n\":\"Fill\\/Texture Effect - Texture Scale (V)\"},{\"t\":3,\"p\":1,\"n\":\"Scene Graph Emit Depth Limit (unused)\"}]}]},{\"t\":1,\"p\":1,\"n\":\"ENCH - Object Effect\",\"f\":1,\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"X1\"},{\"t\":3,\"p\":1,\"n\":\"Y1\"},{\"t\":3,\"p\":1,\"n\":\"Z1\"},{\"t\":3,\"p\":1,\"n\":\"X2\"},{\"t\":3,\"p\":1,\"n\":\"Y2\"},{\"t\":3,\"p\":1,\"n\":\"Z2\"}]},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"ENIT - Effect Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Enchantment Cost\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":3,\"p\":1,\"n\":\"Cast Type\"},{\"t\":3,\"p\":1,\"n\":\"Enchantment Amount\"},{\"t\":3,\"p\":1,\"n\":\"Target Type\"},{\"t\":3,\"p\":1,\"n\":\"Enchant Type\"},{\"t\":5,\"p\":1,\"n\":\"Charge Time\"},{\"t\":3,\"p\":1,\"n\":\"Base Enchantment\"},{\"t\":3,\"p\":1,\"n\":\"Worn Restrictions\"}]},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Effects\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Effect\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"EFID - Base Effect\"},{\"t\":6,\"p\":1,\"n\":\"EFIT - \",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Magnitude\"},{\"t\":3,\"p\":1,\"n\":\"Area\"},{\"t\":3,\"p\":1,\"n\":\"Duration\"}]},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Conditions\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Condition\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"CTDA - \",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":5,\"p\":1,\"n\":\"Comparison Value - Float\"},{\"t\":3,\"p\":1,\"n\":\"Comparison Value - Global\"},{\"t\":3,\"p\":1,\"n\":\"Function\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":11,\"p\":1,\"n\":\"None\"},{\"t\":3,\"p\":1,\"n\":\"Integer\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":11,\"p\":1,\"n\":\"Variable Name (unused)\"},{\"t\":3,\"p\":1,\"n\":\"Sex\"},{\"t\":3,\"p\":1,\"n\":\"Actor Value\"},{\"t\":3,\"p\":1,\"n\":\"Crime Type\"},{\"t\":3,\"p\":1,\"n\":\"Axis\"},{\"t\":3,\"p\":1,\"n\":\"Quest Stage (unused)\"},{\"t\":3,\"p\":1,\"n\":\"Misc Stat\"},{\"t\":3,\"p\":1,\"n\":\"Alignment\"},{\"t\":3,\"p\":1,\"n\":\"Equip Type\"},{\"t\":3,\"p\":1,\"n\":\"Form Type\"},{\"t\":3,\"p\":1,\"n\":\"Critical Stage\"},{\"t\":3,\"p\":1,\"n\":\"Object Reference\"},{\"t\":3,\"p\":1,\"n\":\"Inventory Object\"},{\"t\":3,\"p\":1,\"n\":\"Actor\"},{\"t\":3,\"p\":1,\"n\":\"Voice Type\"},{\"t\":3,\"p\":1,\"n\":\"Idle\"},{\"t\":3,\"p\":1,\"n\":\"Form List\"},{\"t\":3,\"p\":1,\"n\":\"Quest\"},{\"t\":3,\"p\":1,\"n\":\"Faction\"},{\"t\":3,\"p\":1,\"n\":\"Cell\"},{\"t\":3,\"p\":1,\"n\":\"Class\"},{\"t\":3,\"p\":1,\"n\":\"Race\"},{\"t\":3,\"p\":1,\"n\":\"Actor Base\"},{\"t\":3,\"p\":1,\"n\":\"Global\"},{\"t\":3,\"p\":1,\"n\":\"Weather\"},{\"t\":3,\"p\":1,\"n\":\"Package\"},{\"t\":3,\"p\":1,\"n\":\"Encounter Zone\"},{\"t\":3,\"p\":1,\"n\":\"Perk\"},{\"t\":3,\"p\":1,\"n\":\"Owner\"},{\"t\":3,\"p\":1,\"n\":\"Furniture\"},{\"t\":3,\"p\":1,\"n\":\"Effect Item\"},{\"t\":3,\"p\":1,\"n\":\"Base Effect\"},{\"t\":3,\"p\":1,\"n\":\"Worldspace\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Function\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Param (INVALID)\"},{\"t\":3,\"p\":1,\"n\":\"Referenceable Object\"},{\"t\":3,\"p\":1,\"n\":\"Region\"},{\"t\":3,\"p\":1,\"n\":\"Keyword\"},{\"t\":3,\"p\":1,\"n\":\"Player Action\"},{\"t\":3,\"p\":1,\"n\":\"Casting Type\"},{\"t\":3,\"p\":1,\"n\":\"Shout\"},{\"t\":3,\"p\":1,\"n\":\"Location\"},{\"t\":3,\"p\":1,\"n\":\"Location Ref Type\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"Packdata ID\"},{\"t\":3,\"p\":1,\"n\":\"Association Type\"},{\"t\":3,\"p\":1,\"n\":\"Furniture Anim\"},{\"t\":3,\"p\":1,\"n\":\"Furniture Entry\"},{\"t\":3,\"p\":1,\"n\":\"Scene\"},{\"t\":3,\"p\":1,\"n\":\"Ward State\"},{\"t\":3,\"p\":1,\"n\":\"Event\"},{\"t\":3,\"p\":1,\"n\":\"Event Data\"},{\"t\":3,\"p\":1,\"n\":\"Quest Stage\"},{\"t\":3,\"p\":1,\"n\":\"Weapon\"},{\"t\":3,\"p\":1,\"n\":\"Weapon List\"},{\"t\":3,\"p\":1,\"n\":\"Target\"},{\"t\":3,\"p\":1,\"n\":\"Target List\"},{\"t\":3,\"p\":1,\"n\":\"Target Part\"},{\"t\":3,\"p\":1,\"n\":\"VATS Action\"},{\"t\":3,\"p\":1,\"n\":\"Critical Effect\"},{\"t\":3,\"p\":1,\"n\":\"Critical Effect List\"},{\"t\":3,\"p\":1,\"n\":\"Weapon Type\"},{\"t\":3,\"p\":1,\"n\":\"Projectile Type\"},{\"t\":3,\"p\":1,\"n\":\"Delivery Type\"},{\"t\":3,\"p\":1,\"n\":\"Run On\"},{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":3,\"p\":1,\"n\":\"Parameter #3\"}]},{\"t\":2,\"p\":1,\"n\":\"CIS1 - Parameter #1\"},{\"t\":2,\"p\":1,\"n\":\"CIS2 - Parameter #2\"}]}]}]}]}]},{\"t\":1,\"p\":1,\"n\":\"EQUP - Equip Type\",\"f\":1,\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":7,\"p\":1,\"n\":\"PNAM - Slot Parents\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Can Be Equipped\"}]},{\"t\":3,\"p\":1,\"n\":\"DATA - Use All Parents\"}]},{\"t\":1,\"p\":1,\"n\":\"EXPL - Explosion\",\"f\":1,\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"VMAD - Virtual Machine Adapter\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Version\"},{\"t\":3,\"p\":1,\"n\":\"Object Format\"},{\"t\":7,\"p\":1,\"n\":\"Scripts\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Script\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"scriptName\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":7,\"p\":1,\"n\":\"Properties\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Property\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"propertyName\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]},{\"t\":2,\"p\":1,\"n\":\"String\"},{\"t\":3,\"p\":1,\"n\":\"Int32\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":3,\"p\":1,\"n\":\"Bool\"},{\"t\":7,\"p\":1,\"n\":\"Array of Object\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]}]},{\"t\":7,\"p\":1,\"n\":\"Array of String\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Int32\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Float\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Bool\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]}]}]}]}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"X1\"},{\"t\":3,\"p\":1,\"n\":\"Y1\"},{\"t\":3,\"p\":1,\"n\":\"Z1\"},{\"t\":3,\"p\":1,\"n\":\"X2\"},{\"t\":3,\"p\":1,\"n\":\"Y2\"},{\"t\":3,\"p\":1,\"n\":\"Z2\"}]},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"MODT - Texture Files Hashes\"},{\"t\":7,\"p\":1,\"n\":\"MODS - Alternate Textures\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"3D Name\"},{\"t\":3,\"p\":1,\"n\":\"New Texture\"},{\"t\":3,\"p\":1,\"n\":\"3D Index\"}]}]}]},{\"t\":3,\"p\":1,\"n\":\"EITM - Object Effect\"},{\"t\":3,\"p\":1,\"n\":\"MNAM - Image Space Modifier\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DATA - Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Light\"},{\"t\":3,\"p\":1,\"n\":\"Sound 1\"},{\"t\":3,\"p\":1,\"n\":\"Sound 2\"},{\"t\":3,\"p\":1,\"n\":\"Impact Data Set\"},{\"t\":3,\"p\":1,\"n\":\"Placed Object\"},{\"t\":3,\"p\":1,\"n\":\"Spawn Projectile\"},{\"t\":5,\"p\":1,\"n\":\"Force\"},{\"t\":5,\"p\":1,\"n\":\"Damage\"},{\"t\":5,\"p\":1,\"n\":\"Radius\"},{\"t\":5,\"p\":1,\"n\":\"IS Radius\"},{\"t\":5,\"p\":1,\"n\":\"Vertical Offset Mult\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":3,\"p\":1,\"n\":\"Sound Level\"}]}]},{\"t\":1,\"p\":1,\"n\":\"EYES - Eyes\",\"f\":1,\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":2,\"p\":1,\"n\":\"ICON - Texture\"},{\"t\":3,\"p\":1,\"n\":\"DATA - Flags\"}]},{\"t\":1,\"p\":1,\"n\":\"FACT - Faction\",\"f\":1,\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Relations\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"XNAM - Relation\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Faction\"},{\"t\":3,\"p\":1,\"n\":\"Modifier\"},{\"t\":3,\"p\":1,\"n\":\"Group Combat Reaction\"}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DATA - Flags\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Flags\"}]},{\"t\":3,\"p\":1,\"n\":\"JAIL - Exterior Jail Marker\"},{\"t\":3,\"p\":1,\"n\":\"WAIT - Follower Wait Marker\"},{\"t\":3,\"p\":1,\"n\":\"STOL - Stolen Goods Container\"},{\"t\":3,\"p\":1,\"n\":\"PLCN - Player Inventory Container\"},{\"t\":3,\"p\":1,\"n\":\"CRGR - Shared Crime Faction List\"},{\"t\":3,\"p\":1,\"n\":\"JOUT - Jail Outfit\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"CRVA - Crime Values\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Arrest\"},{\"t\":3,\"p\":1,\"n\":\"Attack On Sight\"},{\"t\":3,\"p\":1,\"n\":\"Murder\"},{\"t\":3,\"p\":1,\"n\":\"Assault\"},{\"t\":3,\"p\":1,\"n\":\"Trespass\"},{\"t\":3,\"p\":1,\"n\":\"Pickpocket\"},{\"t\":3,\"n\":\"Unknown\"},{\"t\":5,\"p\":1,\"n\":\"Steal Multiplier\"},{\"t\":3,\"p\":1,\"n\":\"Escape\"},{\"t\":3,\"p\":1,\"n\":\"Werewolf\"}]},{\"t\":10,\"p\":1,\"n\":\"Ranks\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Rank\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"RNAM - Rank#\"},{\"t\":2,\"p\":1,\"n\":\"MNAM - Male Title\"},{\"t\":2,\"p\":1,\"n\":\"FNAM - Female Title\"},{\"t\":2,\"n\":\"INAM - Insignia Unused\"}]}]},{\"t\":3,\"p\":1,\"n\":\"VEND - Vendor Buy\\/Sell List\"},{\"t\":3,\"p\":1,\"n\":\"VENC - Merchant Container\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"VENV - Vendor Values\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Start Hour\"},{\"t\":3,\"p\":1,\"n\":\"End Hour\"},{\"t\":3,\"p\":1,\"n\":\"Radius\"},{\"t\":11,\"n\":\"Unknown 1\"},{\"t\":3,\"p\":1,\"n\":\"Only Buys Stolen Items\"},{\"t\":3,\"p\":1,\"n\":\"Not\\/Sell Buy\"},{\"t\":11,\"n\":\"Unknown 2\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"PLVD - Location\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":3,\"p\":1,\"n\":\"Cell\"},{\"t\":11,\"p\":1,\"n\":\"Near Package Start Location\"},{\"t\":11,\"p\":1,\"n\":\"Near Editor Location\"},{\"t\":3,\"p\":1,\"n\":\"Object ID\"},{\"t\":3,\"p\":1,\"n\":\"Object Type\"},{\"t\":3,\"p\":1,\"n\":\"Keyword\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":3,\"p\":1,\"n\":\"Radius\"}]},{\"t\":3,\"n\":\"CITC - Condition Count\"},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Conditions\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Condition\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"CTDA - \",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":5,\"p\":1,\"n\":\"Comparison Value - Float\"},{\"t\":3,\"p\":1,\"n\":\"Comparison Value - Global\"},{\"t\":3,\"p\":1,\"n\":\"Function\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":11,\"p\":1,\"n\":\"None\"},{\"t\":3,\"p\":1,\"n\":\"Integer\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":11,\"p\":1,\"n\":\"Variable Name (unused)\"},{\"t\":3,\"p\":1,\"n\":\"Sex\"},{\"t\":3,\"p\":1,\"n\":\"Actor Value\"},{\"t\":3,\"p\":1,\"n\":\"Crime Type\"},{\"t\":3,\"p\":1,\"n\":\"Axis\"},{\"t\":3,\"p\":1,\"n\":\"Quest Stage (unused)\"},{\"t\":3,\"p\":1,\"n\":\"Misc Stat\"},{\"t\":3,\"p\":1,\"n\":\"Alignment\"},{\"t\":3,\"p\":1,\"n\":\"Equip Type\"},{\"t\":3,\"p\":1,\"n\":\"Form Type\"},{\"t\":3,\"p\":1,\"n\":\"Critical Stage\"},{\"t\":3,\"p\":1,\"n\":\"Object Reference\"},{\"t\":3,\"p\":1,\"n\":\"Inventory Object\"},{\"t\":3,\"p\":1,\"n\":\"Actor\"},{\"t\":3,\"p\":1,\"n\":\"Voice Type\"},{\"t\":3,\"p\":1,\"n\":\"Idle\"},{\"t\":3,\"p\":1,\"n\":\"Form List\"},{\"t\":3,\"p\":1,\"n\":\"Quest\"},{\"t\":3,\"p\":1,\"n\":\"Faction\"},{\"t\":3,\"p\":1,\"n\":\"Cell\"},{\"t\":3,\"p\":1,\"n\":\"Class\"},{\"t\":3,\"p\":1,\"n\":\"Race\"},{\"t\":3,\"p\":1,\"n\":\"Actor Base\"},{\"t\":3,\"p\":1,\"n\":\"Global\"},{\"t\":3,\"p\":1,\"n\":\"Weather\"},{\"t\":3,\"p\":1,\"n\":\"Package\"},{\"t\":3,\"p\":1,\"n\":\"Encounter Zone\"},{\"t\":3,\"p\":1,\"n\":\"Perk\"},{\"t\":3,\"p\":1,\"n\":\"Owner\"},{\"t\":3,\"p\":1,\"n\":\"Furniture\"},{\"t\":3,\"p\":1,\"n\":\"Effect Item\"},{\"t\":3,\"p\":1,\"n\":\"Base Effect\"},{\"t\":3,\"p\":1,\"n\":\"Worldspace\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Function\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Param (INVALID)\"},{\"t\":3,\"p\":1,\"n\":\"Referenceable Object\"},{\"t\":3,\"p\":1,\"n\":\"Region\"},{\"t\":3,\"p\":1,\"n\":\"Keyword\"},{\"t\":3,\"p\":1,\"n\":\"Player Action\"},{\"t\":3,\"p\":1,\"n\":\"Casting Type\"},{\"t\":3,\"p\":1,\"n\":\"Shout\"},{\"t\":3,\"p\":1,\"n\":\"Location\"},{\"t\":3,\"p\":1,\"n\":\"Location Ref Type\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"Packdata ID\"},{\"t\":3,\"p\":1,\"n\":\"Association Type\"},{\"t\":3,\"p\":1,\"n\":\"Furniture Anim\"},{\"t\":3,\"p\":1,\"n\":\"Furniture Entry\"},{\"t\":3,\"p\":1,\"n\":\"Scene\"},{\"t\":3,\"p\":1,\"n\":\"Ward State\"},{\"t\":3,\"p\":1,\"n\":\"Event\"},{\"t\":3,\"p\":1,\"n\":\"Event Data\"},{\"t\":3,\"p\":1,\"n\":\"Quest Stage\"},{\"t\":3,\"p\":1,\"n\":\"Weapon\"},{\"t\":3,\"p\":1,\"n\":\"Weapon List\"},{\"t\":3,\"p\":1,\"n\":\"Target\"},{\"t\":3,\"p\":1,\"n\":\"Target List\"},{\"t\":3,\"p\":1,\"n\":\"Target Part\"},{\"t\":3,\"p\":1,\"n\":\"VATS Action\"},{\"t\":3,\"p\":1,\"n\":\"Critical Effect\"},{\"t\":3,\"p\":1,\"n\":\"Critical Effect List\"},{\"t\":3,\"p\":1,\"n\":\"Weapon Type\"},{\"t\":3,\"p\":1,\"n\":\"Projectile Type\"},{\"t\":3,\"p\":1,\"n\":\"Delivery Type\"},{\"t\":3,\"p\":1,\"n\":\"Run On\"},{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":3,\"p\":1,\"n\":\"Parameter #3\"}]},{\"t\":2,\"p\":1,\"n\":\"CIS1 - Parameter #1\"},{\"t\":2,\"p\":1,\"n\":\"CIS2 - Parameter #2\"}]}]}]},{\"t\":1,\"p\":1,\"n\":\"FLOR - Flora\",\"f\":1,\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"VMAD - Virtual Machine Adapter\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Version\"},{\"t\":3,\"p\":1,\"n\":\"Object Format\"},{\"t\":7,\"p\":1,\"n\":\"Scripts\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Script\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"scriptName\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":7,\"p\":1,\"n\":\"Properties\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Property\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"propertyName\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]},{\"t\":2,\"p\":1,\"n\":\"String\"},{\"t\":3,\"p\":1,\"n\":\"Int32\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":3,\"p\":1,\"n\":\"Bool\"},{\"t\":7,\"p\":1,\"n\":\"Array of Object\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]}]},{\"t\":7,\"p\":1,\"n\":\"Array of String\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Int32\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Float\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Bool\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]}]}]}]}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"X1\"},{\"t\":3,\"p\":1,\"n\":\"Y1\"},{\"t\":3,\"p\":1,\"n\":\"Z1\"},{\"t\":3,\"p\":1,\"n\":\"X2\"},{\"t\":3,\"p\":1,\"n\":\"Y2\"},{\"t\":3,\"p\":1,\"n\":\"Z2\"}]},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"MODT - Texture Files Hashes\"},{\"t\":7,\"p\":1,\"n\":\"MODS - Alternate Textures\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"3D Name\"},{\"t\":3,\"p\":1,\"n\":\"New Texture\"},{\"t\":3,\"p\":1,\"n\":\"3D Index\"}]}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Destructable\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"DEST - Header\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Health\"},{\"t\":3,\"p\":1,\"n\":\"DEST Count\"},{\"t\":3,\"p\":1,\"n\":\"VATS Targetable\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":8,\"p\":1,\"n\":\"Stages\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Stage\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"DSTD - Destruction Stage Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Health %\"},{\"t\":3,\"p\":1,\"n\":\"Index\"},{\"t\":3,\"p\":1,\"n\":\"Model Damage Stage\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":3,\"p\":1,\"n\":\"Self Damage per Second\"},{\"t\":3,\"p\":1,\"n\":\"Explosion\"},{\"t\":3,\"p\":1,\"n\":\"Debris\"},{\"t\":3,\"p\":1,\"n\":\"Debris Count\"}]},{\"t\":6,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"DMDL - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"DMDT - Texture Files Hashes\"},{\"t\":7,\"p\":1,\"n\":\"DMDS - Alternate Textures\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"3D Name\"},{\"t\":3,\"p\":1,\"n\":\"New Texture\"},{\"t\":3,\"p\":1,\"n\":\"3D Index\"}]}]}]},{\"p\":1,\"n\":\"DSTF - End Marker\"}]}]}]},{\"t\":3,\"n\":\"KSIZ - Keyword Count\"},{\"t\":7,\"p\":1,\"n\":\"KWDA - Keywords\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Keyword\"}]},{\"t\":11,\"n\":\"PNAM - Unknown\"},{\"t\":2,\"p\":1,\"n\":\"RNAM - Activate Text Override\"},{\"t\":11,\"n\":\"FNAM - Unknown\"},{\"t\":3,\"p\":1,\"n\":\"PFIG - Ingredient\"},{\"t\":3,\"p\":1,\"n\":\"SNAM - Sound\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"PFPC - Seasonal ingredient production\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Spring\"},{\"t\":3,\"p\":1,\"n\":\"Summer \"},{\"t\":3,\"p\":1,\"n\":\"Fall\"},{\"t\":3,\"p\":1,\"n\":\"Winter\"}]}]},{\"t\":1,\"p\":1,\"n\":\"FLST - FormID List\",\"f\":1,\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"FormIDs\",\"d\":1,\"c\":[{\"t\":3,\"p\":1,\"n\":\"LNAM - FormID\"}]}]},{\"t\":1,\"p\":1,\"n\":\"FSTP - Footstep\",\"f\":1,\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":3,\"p\":1,\"n\":\"DATA - Impact Data Set\"},{\"t\":2,\"p\":1,\"n\":\"ANAM - Tag\"}]},{\"t\":1,\"p\":1,\"n\":\"FSTS - Footstep Set\",\"f\":1,\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"XCNT - Count\",\"c\":[{\"t\":3,\"n\":\"Walk Forward Sets\"},{\"t\":3,\"n\":\"Run Forward Sets\"},{\"t\":3,\"n\":\"Walk Forward Alternate Sets\"},{\"t\":3,\"n\":\"Run Forward Alternate Sets\"},{\"t\":3,\"n\":\"Walk Forward Alternate 2 Sets\"}]},{\"t\":7,\"s\":1,\"p\":1,\"n\":\"DATA - Footstep Sets\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Footstep\"}]}]},{\"t\":1,\"p\":1,\"n\":\"FURN - Furniture\",\"f\":1,\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"VMAD - Virtual Machine Adapter\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Version\"},{\"t\":3,\"p\":1,\"n\":\"Object Format\"},{\"t\":7,\"p\":1,\"n\":\"Scripts\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Script\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"scriptName\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":7,\"p\":1,\"n\":\"Properties\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Property\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"propertyName\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]},{\"t\":2,\"p\":1,\"n\":\"String\"},{\"t\":3,\"p\":1,\"n\":\"Int32\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":3,\"p\":1,\"n\":\"Bool\"},{\"t\":7,\"p\":1,\"n\":\"Array of Object\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]}]},{\"t\":7,\"p\":1,\"n\":\"Array of String\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Int32\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Float\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Bool\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]}]}]}]}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"X1\"},{\"t\":3,\"p\":1,\"n\":\"Y1\"},{\"t\":3,\"p\":1,\"n\":\"Z1\"},{\"t\":3,\"p\":1,\"n\":\"X2\"},{\"t\":3,\"p\":1,\"n\":\"Y2\"},{\"t\":3,\"p\":1,\"n\":\"Z2\"}]},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"MODT - Texture Files Hashes\"},{\"t\":7,\"p\":1,\"n\":\"MODS - Alternate Textures\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"3D Name\"},{\"t\":3,\"p\":1,\"n\":\"New Texture\"},{\"t\":3,\"p\":1,\"n\":\"3D Index\"}]}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Destructable\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"DEST - Header\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Health\"},{\"t\":3,\"p\":1,\"n\":\"DEST Count\"},{\"t\":3,\"p\":1,\"n\":\"VATS Targetable\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":8,\"p\":1,\"n\":\"Stages\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Stage\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"DSTD - Destruction Stage Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Health %\"},{\"t\":3,\"p\":1,\"n\":\"Index\"},{\"t\":3,\"p\":1,\"n\":\"Model Damage Stage\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":3,\"p\":1,\"n\":\"Self Damage per Second\"},{\"t\":3,\"p\":1,\"n\":\"Explosion\"},{\"t\":3,\"p\":1,\"n\":\"Debris\"},{\"t\":3,\"p\":1,\"n\":\"Debris Count\"}]},{\"t\":6,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"DMDL - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"DMDT - Texture Files Hashes\"},{\"t\":7,\"p\":1,\"n\":\"DMDS - Alternate Textures\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"3D Name\"},{\"t\":3,\"p\":1,\"n\":\"New Texture\"},{\"t\":3,\"p\":1,\"n\":\"3D Index\"}]}]}]},{\"p\":1,\"n\":\"DSTF - End Marker\"}]}]}]},{\"t\":3,\"n\":\"KSIZ - Keyword Count\"},{\"t\":7,\"p\":1,\"n\":\"KWDA - Keywords\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Keyword\"}]},{\"t\":11,\"n\":\"PNAM - Unknown\"},{\"t\":3,\"p\":1,\"n\":\"FNAM - Flags\"},{\"t\":3,\"p\":1,\"n\":\"KNAM - Interaction Keyword\"},{\"t\":3,\"p\":1,\"n\":\"MNAM - Active Markers \\/ Flags\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"WBDT - Workbench Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Bench Type\"},{\"t\":3,\"p\":1,\"n\":\"Uses Skill\"}]},{\"t\":3,\"p\":1,\"n\":\"NAM1 - Associated Spell\"},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Markers\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Marker\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"ENAM - Marker Index\"},{\"t\":6,\"p\":1,\"n\":\"NAM0 - Disabled Entry Points\",\"c\":[{\"t\":11,\"n\":\"Unknown\"},{\"t\":3,\"p\":1,\"n\":\"Disabled Points\"}]},{\"t\":3,\"p\":1,\"n\":\"FNMK - Marker Keyword\"}]}]},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Marker Entry Points\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"FNPR - Marker\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Entry Points\"}]}]},{\"t\":2,\"p\":1,\"n\":\"XMRK - Model Filename\"}]},{\"t\":1,\"p\":1,\"n\":\"GLOB - Global\",\"f\":1,\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":3,\"p\":1,\"n\":\"FNAM - Type\"},{\"t\":5,\"p\":1,\"n\":\"FLTV - Value\"}]},{\"t\":1,\"p\":1,\"n\":\"GMST - Game Setting\",\"f\":1,\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"p\":1,\"n\":\"Name\"},{\"t\":3,\"p\":1,\"n\":\"Int\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":3,\"p\":1,\"n\":\"Bool\"}]},{\"t\":1,\"p\":1,\"n\":\"GRAS - Grass\",\"f\":1,\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"X1\"},{\"t\":3,\"p\":1,\"n\":\"Y1\"},{\"t\":3,\"p\":1,\"n\":\"Z1\"},{\"t\":3,\"p\":1,\"n\":\"X2\"},{\"t\":3,\"p\":1,\"n\":\"Y2\"},{\"t\":3,\"p\":1,\"n\":\"Z2\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"MODT - Texture Files Hashes\"},{\"t\":7,\"p\":1,\"n\":\"MODS - Alternate Textures\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"3D Name\"},{\"t\":3,\"p\":1,\"n\":\"New Texture\"},{\"t\":3,\"p\":1,\"n\":\"3D Index\"}]}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DATA - \",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Density\"},{\"t\":3,\"p\":1,\"n\":\"Min Slope\"},{\"t\":3,\"p\":1,\"n\":\"Max Slope\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":3,\"p\":1,\"n\":\"Units From Water\"},{\"t\":3,\"p\":1,\"n\":\"Units From Water Type\"},{\"t\":5,\"p\":1,\"n\":\"Position Range\"},{\"t\":5,\"p\":1,\"n\":\"Height Range\"},{\"t\":5,\"p\":1,\"n\":\"Color Range\"},{\"t\":5,\"p\":1,\"n\":\"Wave Period\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"}]}]},{\"t\":1,\"p\":1,\"n\":\"HAIR\",\"f\":1,\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"}]},{\"t\":1,\"p\":1,\"n\":\"HAZD - Hazard\",\"f\":1,\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"X1\"},{\"t\":3,\"p\":1,\"n\":\"Y1\"},{\"t\":3,\"p\":1,\"n\":\"Z1\"},{\"t\":3,\"p\":1,\"n\":\"X2\"},{\"t\":3,\"p\":1,\"n\":\"Y2\"},{\"t\":3,\"p\":1,\"n\":\"Z2\"}]},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"MODT - Texture Files Hashes\"},{\"t\":7,\"p\":1,\"n\":\"MODS - Alternate Textures\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"3D Name\"},{\"t\":3,\"p\":1,\"n\":\"New Texture\"},{\"t\":3,\"p\":1,\"n\":\"3D Index\"}]}]}]},{\"t\":3,\"p\":1,\"n\":\"MNAM - Image Space Modifier\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DATA - Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Limit\"},{\"t\":5,\"p\":1,\"n\":\"Radius\"},{\"t\":5,\"p\":1,\"n\":\"Lifetime\"},{\"t\":5,\"p\":1,\"n\":\"Image Space Radius\"},{\"t\":5,\"p\":1,\"n\":\"Target Interval\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":3,\"p\":1,\"n\":\"Spell\"},{\"t\":3,\"p\":1,\"n\":\"Light\"},{\"t\":3,\"p\":1,\"n\":\"Impact Data Set\"},{\"t\":3,\"p\":1,\"n\":\"Sound\"}]}]},{\"t\":1,\"p\":1,\"n\":\"HDPT - Head Part\",\"f\":1,\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"MODT - Texture Files Hashes\"},{\"t\":7,\"p\":1,\"n\":\"MODS - Alternate Textures\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"3D Name\"},{\"t\":3,\"p\":1,\"n\":\"New Texture\"},{\"t\":3,\"p\":1,\"n\":\"3D Index\"}]}]}]},{\"t\":3,\"p\":1,\"n\":\"DATA - Flags\"},{\"t\":3,\"p\":1,\"n\":\"PNAM - Type\"},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Extra Parts\",\"d\":1,\"c\":[{\"t\":3,\"p\":1,\"n\":\"HNAM - Part\"}]},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Parts\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Part\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"NAM0 - Part Type\"},{\"t\":2,\"p\":1,\"n\":\"NAM1 - Filename\"}]}]},{\"t\":3,\"p\":1,\"n\":\"TNAM - Texture Set\"},{\"t\":3,\"p\":1,\"n\":\"CNAM - Color\"},{\"t\":3,\"p\":1,\"n\":\"RNAM - Valid Races\"}]},{\"t\":1,\"n\":\"IDLE - Idle Animation\",\"c\":[{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":8,\"n\":\"Conditions\",\"c\":[{\"t\":6,\"n\":\"Condition\",\"c\":[{\"t\":6,\"n\":\"CTDA - \",\"c\":[{\"t\":3,\"n\":\"Type\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":5,\"n\":\"Comparison Value - Float\"},{\"t\":3,\"n\":\"Comparison Value - Global\"},{\"t\":3,\"n\":\"Function\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":11,\"n\":\"None\"},{\"t\":3,\"n\":\"Integer\"},{\"t\":5,\"n\":\"Float\"},{\"t\":11,\"n\":\"Variable Name (unused)\"},{\"t\":3,\"n\":\"Sex\"},{\"t\":3,\"n\":\"Actor Value\"},{\"t\":3,\"n\":\"Crime Type\"},{\"t\":3,\"n\":\"Axis\"},{\"t\":3,\"n\":\"Quest Stage (unused)\"},{\"t\":3,\"n\":\"Misc Stat\"},{\"t\":3,\"n\":\"Alignment\"},{\"t\":3,\"n\":\"Equip Type\"},{\"t\":3,\"n\":\"Form Type\"},{\"t\":3,\"n\":\"Critical Stage\"},{\"t\":3,\"n\":\"Object Reference\"},{\"t\":3,\"n\":\"Inventory Object\"},{\"t\":3,\"n\":\"Actor\"},{\"t\":3,\"n\":\"Voice Type\"},{\"t\":3,\"n\":\"Idle\"},{\"t\":3,\"n\":\"Form List\"},{\"t\":3,\"n\":\"Quest\"},{\"t\":3,\"n\":\"Faction\"},{\"t\":3,\"n\":\"Cell\"},{\"t\":3,\"n\":\"Class\"},{\"t\":3,\"n\":\"Race\"},{\"t\":3,\"n\":\"Actor Base\"},{\"t\":3,\"n\":\"Global\"},{\"t\":3,\"n\":\"Weather\"},{\"t\":3,\"n\":\"Package\"},{\"t\":3,\"n\":\"Encounter Zone\"},{\"t\":3,\"n\":\"Perk\"},{\"t\":3,\"n\":\"Owner\"},{\"t\":3,\"n\":\"Furniture\"},{\"t\":3,\"n\":\"Effect Item\"},{\"t\":3,\"n\":\"Base Effect\"},{\"t\":3,\"n\":\"Worldspace\"},{\"t\":3,\"n\":\"VATS Value Function\"},{\"t\":3,\"n\":\"VATS Value Param (INVALID)\"},{\"t\":3,\"n\":\"Referenceable Object\"},{\"t\":3,\"n\":\"Region\"},{\"t\":3,\"n\":\"Keyword\"},{\"t\":3,\"n\":\"Player Action\"},{\"t\":3,\"n\":\"Casting Type\"},{\"t\":3,\"n\":\"Shout\"},{\"t\":3,\"n\":\"Location\"},{\"t\":3,\"n\":\"Location Ref Type\"},{\"t\":3,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Packdata ID\"},{\"t\":3,\"n\":\"Association Type\"},{\"t\":3,\"n\":\"Furniture Anim\"},{\"t\":3,\"n\":\"Furniture Entry\"},{\"t\":3,\"n\":\"Scene\"},{\"t\":3,\"n\":\"Ward State\"},{\"t\":3,\"n\":\"Event\"},{\"t\":3,\"n\":\"Event Data\"},{\"t\":3,\"n\":\"Quest Stage\"},{\"t\":3,\"n\":\"Weapon\"},{\"t\":3,\"n\":\"Weapon List\"},{\"t\":3,\"n\":\"Target\"},{\"t\":3,\"n\":\"Target List\"},{\"t\":3,\"n\":\"Target Part\"},{\"t\":3,\"n\":\"VATS Action\"},{\"t\":3,\"n\":\"Critical Effect\"},{\"t\":3,\"n\":\"Critical Effect List\"},{\"t\":3,\"n\":\"Weapon Type\"},{\"t\":3,\"n\":\"Projectile Type\"},{\"t\":3,\"n\":\"Delivery Type\"},{\"t\":3,\"n\":\"Run On\"},{\"t\":3,\"n\":\"Reference\"},{\"t\":3,\"n\":\"Parameter #3\"}]},{\"t\":2,\"n\":\"CIS1 - Parameter #1\"},{\"t\":2,\"n\":\"CIS2 - Parameter #2\"}]}]},{\"t\":2,\"n\":\"DNAM - Filename\"},{\"t\":2,\"n\":\"ENAM - Animation Event\"},{\"t\":7,\"n\":\"ANAM - Related Idle Animations\",\"c\":[{\"t\":3,\"n\":\"Related Idle Animation\"}]},{\"t\":6,\"n\":\"DATA - Data (unused)\",\"c\":[{\"t\":6,\"n\":\"Looping seconds (both 255 forever)\",\"c\":[{\"t\":3,\"n\":\"Min\"},{\"t\":3,\"n\":\"Max\"}]},{\"t\":3,\"n\":\"Flags\"},{\"t\":3,\"n\":\"Animation Group Section\"},{\"t\":3,\"n\":\"Replay Delay\"}]}]},{\"t\":1,\"p\":1,\"n\":\"IDLM - Idle Marker\",\"f\":1,\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"X1\"},{\"t\":3,\"p\":1,\"n\":\"Y1\"},{\"t\":3,\"p\":1,\"n\":\"Z1\"},{\"t\":3,\"p\":1,\"n\":\"X2\"},{\"t\":3,\"p\":1,\"n\":\"Y2\"},{\"t\":3,\"p\":1,\"n\":\"Z2\"}]},{\"t\":3,\"p\":1,\"n\":\"IDLF - Flags\"},{\"t\":3,\"p\":1,\"n\":\"IDLC - Animation Count\"},{\"t\":5,\"p\":1,\"n\":\"IDLT - Idle Timer Setting\"},{\"t\":7,\"p\":1,\"n\":\"IDLA - Animations\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Animation\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"MODT - Texture Files Hashes\"},{\"t\":7,\"p\":1,\"n\":\"MODS - Alternate Textures\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"3D Name\"},{\"t\":3,\"p\":1,\"n\":\"New Texture\"},{\"t\":3,\"p\":1,\"n\":\"3D Index\"}]}]}]}]},{\"t\":1,\"p\":1,\"n\":\"IMAD - Image Space Adapter\",\"f\":1,\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DNAM - Data Count\",\"c\":[{\"t\":3,\"n\":\"Flags\"},{\"t\":5,\"n\":\"Duration\"},{\"t\":6,\"n\":\"HDR\",\"c\":[{\"t\":3,\"n\":\"Eye Adapt Speed Mult\"},{\"t\":3,\"n\":\"Eye Adapt Speed Add\"},{\"t\":3,\"n\":\"Bloom Blur Radius Mult\"},{\"t\":3,\"n\":\"Bloom Blur Radius Add\"},{\"t\":3,\"n\":\"Bloom Threshold Mult\"},{\"t\":3,\"n\":\"Bloom Threshold Add\"},{\"t\":3,\"n\":\"Bloom Scale Mult\"},{\"t\":3,\"n\":\"Bloom Scale Add\"},{\"t\":3,\"n\":\"Target Lum Min Mult\"},{\"t\":3,\"n\":\"Target Lum Min Add\"},{\"t\":3,\"n\":\"Target Lum Max Mult\"},{\"t\":3,\"n\":\"Target Lum Max Add\"},{\"t\":3,\"n\":\"Sunlight Scale Mult\"},{\"t\":3,\"n\":\"Sunlight Scale Add\"},{\"t\":3,\"n\":\"Sky Scale Mult\"},{\"t\":3,\"n\":\"Sky Scale Add\"}]},{\"t\":3,\"n\":\"Unknown08 Mult\"},{\"t\":3,\"n\":\"Unknown48 Add\"},{\"t\":3,\"n\":\"Unknown09 Mult\"},{\"t\":3,\"n\":\"Unknown49 Add\"},{\"t\":3,\"n\":\"Unknown0A Mult\"},{\"t\":3,\"n\":\"Unknown4A Add\"},{\"t\":3,\"n\":\"Unknown0B Mult\"},{\"t\":3,\"n\":\"Unknown4B Add\"},{\"t\":3,\"n\":\"Unknown0C Mult\"},{\"t\":3,\"n\":\"Unknown4C Add\"},{\"t\":3,\"n\":\"Unknown0D Mult\"},{\"t\":3,\"n\":\"Unknown4D Add\"},{\"t\":3,\"n\":\"Unknown0E Mult\"},{\"t\":3,\"n\":\"Unknown4E Add\"},{\"t\":3,\"n\":\"Unknown0F Mult\"},{\"t\":3,\"n\":\"Unknown4F Add\"},{\"t\":3,\"n\":\"Unknown10 Mult\"},{\"t\":3,\"n\":\"Unknown50 Add\"},{\"t\":6,\"n\":\"Cinematic\",\"c\":[{\"t\":3,\"n\":\"Saturation Mult\"},{\"t\":3,\"n\":\"Saturation Add\"},{\"t\":3,\"n\":\"Brightness Mult\"},{\"t\":3,\"n\":\"Brightness Add\"},{\"t\":3,\"n\":\"Contrast Mult\"},{\"t\":3,\"n\":\"Contrast Add\"}]},{\"t\":3,\"n\":\"Unknown14 Mult\"},{\"t\":3,\"n\":\"Unknown54 Add\"},{\"t\":3,\"n\":\"Tint Color\"},{\"t\":3,\"n\":\"Blur Radius\"},{\"t\":3,\"n\":\"Double Vision Strength\"},{\"t\":3,\"n\":\"Radial Blur Strength\"},{\"t\":3,\"n\":\"Radial Blur Ramp Up\"},{\"t\":3,\"n\":\"Radial Blur Start\"},{\"t\":3,\"n\":\"Radial Blur Flags\"},{\"t\":5,\"n\":\"Radial Blur Center X\"},{\"t\":5,\"n\":\"Radial Blur Center Y\"},{\"t\":3,\"n\":\"DoF Strength\"},{\"t\":3,\"n\":\"DoF Distance\"},{\"t\":3,\"n\":\"DoF Range\"},{\"t\":3,\"n\":\"DoF Flags\"},{\"t\":3,\"n\":\"Radial Blur Ramp Down\"},{\"t\":3,\"n\":\"Radial Blur Down Start\"},{\"t\":3,\"n\":\"Fade Color\"},{\"t\":3,\"n\":\"Motion Blur Strength\"}]},{\"t\":7,\"p\":1,\"n\":\"BNAM - Blur Radius\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Data\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Time\"},{\"t\":5,\"p\":1,\"n\":\"Value\"}]}]},{\"t\":7,\"p\":1,\"n\":\"VNAM - Double Vision Strength\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Data\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Time\"},{\"t\":5,\"p\":1,\"n\":\"Value\"}]}]},{\"t\":7,\"p\":1,\"n\":\"TNAM - Tint Color\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Data\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Time\"},{\"t\":5,\"p\":1,\"n\":\"Red\"},{\"t\":5,\"p\":1,\"n\":\"Green\"},{\"t\":5,\"p\":1,\"n\":\"Blue\"},{\"t\":5,\"p\":1,\"n\":\"Alpha\"}]}]},{\"t\":7,\"p\":1,\"n\":\"NAM3 - Fade Color\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Data\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Time\"},{\"t\":5,\"p\":1,\"n\":\"Red\"},{\"t\":5,\"p\":1,\"n\":\"Green\"},{\"t\":5,\"p\":1,\"n\":\"Blue\"},{\"t\":5,\"p\":1,\"n\":\"Alpha\"}]}]},{\"t\":7,\"p\":1,\"n\":\"RNAM - Radial Blur Strength\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Data\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Time\"},{\"t\":5,\"p\":1,\"n\":\"Value\"}]}]},{\"t\":7,\"p\":1,\"n\":\"SNAM - Radial Blur Ramp Up\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Data\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Time\"},{\"t\":5,\"p\":1,\"n\":\"Value\"}]}]},{\"t\":7,\"p\":1,\"n\":\"UNAM - Radial Blur Start\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Data\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Time\"},{\"t\":5,\"p\":1,\"n\":\"Value\"}]}]},{\"t\":7,\"p\":1,\"n\":\"NAM1 - Radial Blur Ramp Down\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Data\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Time\"},{\"t\":5,\"p\":1,\"n\":\"Value\"}]}]},{\"t\":7,\"p\":1,\"n\":\"NAM2 - Radial Blur Down Start\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Data\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Time\"},{\"t\":5,\"p\":1,\"n\":\"Value\"}]}]},{\"t\":7,\"p\":1,\"n\":\"WNAM - DoF Strength\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Data\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Time\"},{\"t\":5,\"p\":1,\"n\":\"Value\"}]}]},{\"t\":7,\"p\":1,\"n\":\"XNAM - DoF Distance\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Data\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Time\"},{\"t\":5,\"p\":1,\"n\":\"Value\"}]}]},{\"t\":7,\"p\":1,\"n\":\"YNAM - DoF Range\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Data\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Time\"},{\"t\":5,\"p\":1,\"n\":\"Value\"}]}]},{\"t\":7,\"p\":1,\"n\":\"NAM4 - Motion Blur Strength\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Data\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Time\"},{\"t\":5,\"p\":1,\"n\":\"Value\"}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"HDR\",\"c\":[{\"t\":7,\"p\":1,\"n\":\"aIAD - Eye Adapt Speed Mult\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Data\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Time\"},{\"t\":5,\"p\":1,\"n\":\"Value\"}]}]},{\"t\":7,\"p\":1,\"n\":\"@IAD - Eye Adapt Speed Add\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Data\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Time\"},{\"t\":5,\"p\":1,\"n\":\"Value\"}]}]},{\"t\":7,\"p\":1,\"n\":\"bIAD - Bloom Blur Radius Mult\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Data\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Time\"},{\"t\":5,\"p\":1,\"n\":\"Value\"}]}]},{\"t\":7,\"p\":1,\"n\":\"AIAD - Bloom Blur Radius Add\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Data\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Time\"},{\"t\":5,\"p\":1,\"n\":\"Value\"}]}]},{\"t\":7,\"p\":1,\"n\":\"cIAD - Bloom Threshold Mult\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Data\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Time\"},{\"t\":5,\"p\":1,\"n\":\"Value\"}]}]},{\"t\":7,\"p\":1,\"n\":\"BIAD - Bloom Threshold Add\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Data\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Time\"},{\"t\":5,\"p\":1,\"n\":\"Value\"}]}]},{\"t\":7,\"p\":1,\"n\":\"dIAD - Bloom Scale Mult\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Data\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Time\"},{\"t\":5,\"p\":1,\"n\":\"Value\"}]}]},{\"t\":7,\"p\":1,\"n\":\"CIAD - Bloom Scale Add\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Data\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Time\"},{\"t\":5,\"p\":1,\"n\":\"Value\"}]}]},{\"t\":7,\"p\":1,\"n\":\"eIAD - Target Lum Min Mult\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Data\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Time\"},{\"t\":5,\"p\":1,\"n\":\"Value\"}]}]},{\"t\":7,\"p\":1,\"n\":\"DIAD - Target Lum Min Add\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Data\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Time\"},{\"t\":5,\"p\":1,\"n\":\"Value\"}]}]},{\"t\":7,\"p\":1,\"n\":\"fIAD - Target Lum Max Mult\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Data\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Time\"},{\"t\":5,\"p\":1,\"n\":\"Value\"}]}]},{\"t\":7,\"p\":1,\"n\":\"EIAD - Target Lum Max Add\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Data\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Time\"},{\"t\":5,\"p\":1,\"n\":\"Value\"}]}]},{\"t\":7,\"p\":1,\"n\":\"gIAD - Sunlight Scale Mult\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Data\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Time\"},{\"t\":5,\"p\":1,\"n\":\"Value\"}]}]},{\"t\":7,\"p\":1,\"n\":\"FIAD - Sunlight Scale Add\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Data\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Time\"},{\"t\":5,\"p\":1,\"n\":\"Value\"}]}]},{\"t\":7,\"p\":1,\"n\":\"hIAD - Sky Scale Mult\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Data\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Time\"},{\"t\":5,\"p\":1,\"n\":\"Value\"}]}]},{\"t\":7,\"p\":1,\"n\":\"GIAD - Sky Scale Add\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Data\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Time\"},{\"t\":5,\"p\":1,\"n\":\"Value\"}]}]}]},{\"t\":11,\"n\":\"iIAD - Unknown\"},{\"t\":11,\"n\":\"HIAD - Unknown\"},{\"t\":11,\"n\":\"jIAD - Unknown\"},{\"t\":11,\"n\":\"IIAD - Unknown\"},{\"t\":11,\"n\":\"kIAD - Unknown\"},{\"t\":11,\"n\":\"JIAD - Unknown\"},{\"t\":11,\"n\":\"lIAD - Unknown\"},{\"t\":11,\"n\":\"KIAD - Unknown\"},{\"t\":11,\"n\":\"mIAD - Unknown\"},{\"t\":11,\"n\":\"LIAD - Unknown\"},{\"t\":11,\"n\":\"nIAD - Unknown\"},{\"t\":11,\"n\":\"MIAD - Unknown\"},{\"t\":11,\"n\":\"oIAD - Unknown\"},{\"t\":11,\"n\":\"NIAD - Unknown\"},{\"t\":11,\"n\":\"pIAD - Unknown\"},{\"t\":11,\"n\":\"OIAD - Unknown\"},{\"t\":11,\"n\":\"qIAD - Unknown\"},{\"t\":11,\"n\":\"PIAD - Unknown\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Cinematic\",\"c\":[{\"t\":7,\"p\":1,\"n\":\"rIAD - Saturation Mult\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Data\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Time\"},{\"t\":5,\"p\":1,\"n\":\"Value\"}]}]},{\"t\":7,\"p\":1,\"n\":\"QIAD - Saturation Add\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Data\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Time\"},{\"t\":5,\"p\":1,\"n\":\"Value\"}]}]},{\"t\":7,\"p\":1,\"n\":\"sIAD - Brightness Mult\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Data\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Time\"},{\"t\":5,\"p\":1,\"n\":\"Value\"}]}]},{\"t\":7,\"p\":1,\"n\":\"RIAD - Brightness Add\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Data\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Time\"},{\"t\":5,\"p\":1,\"n\":\"Value\"}]}]},{\"t\":7,\"p\":1,\"n\":\"tIAD - Contrast Mult\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Data\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Time\"},{\"t\":5,\"p\":1,\"n\":\"Value\"}]}]},{\"t\":7,\"p\":1,\"n\":\"SIAD - Contrast Add\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Data\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Time\"},{\"t\":5,\"p\":1,\"n\":\"Value\"}]}]}]},{\"t\":11,\"n\":\"uIAD - Unknown\"},{\"t\":11,\"n\":\"TIAD - Unknown\"}]},{\"t\":1,\"p\":1,\"n\":\"IMGS - Image Space\",\"f\":1,\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":11,\"n\":\"ENAM - Unknown\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"HNAM - HDR\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Eye Adapt Speed\"},{\"t\":5,\"p\":1,\"n\":\"Bloom Blur Radius\"},{\"t\":5,\"p\":1,\"n\":\"Bloom Threshold\"},{\"t\":5,\"p\":1,\"n\":\"Bloom Scale\"},{\"t\":5,\"p\":1,\"n\":\"Receive Bloom Threshold\"},{\"t\":5,\"p\":1,\"n\":\"White\"},{\"t\":5,\"p\":1,\"n\":\"Sunlight Scale\"},{\"t\":5,\"p\":1,\"n\":\"Sky Scale\"},{\"t\":5,\"p\":1,\"n\":\"Eye Adapt Strength\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"CNAM - Cinematic\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Saturation\"},{\"t\":5,\"p\":1,\"n\":\"Brightness\"},{\"t\":5,\"p\":1,\"n\":\"Contrast\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"TNAM - Tint\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Amount\"},{\"t\":6,\"p\":1,\"n\":\"Color\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Red\"},{\"t\":5,\"p\":1,\"n\":\"Green\"},{\"t\":5,\"p\":1,\"n\":\"Blue\"}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DNAM - Depth of Field\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Strength\"},{\"t\":5,\"p\":1,\"n\":\"Distance\"},{\"t\":5,\"p\":1,\"n\":\"Range\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":3,\"p\":1,\"n\":\"Sky \\/ Blur Radius\"}]}]},{\"t\":1,\"p\":1,\"n\":\"INFO - Dialog response\",\"f\":1,\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"VMAD - Virtual Machine Adapter\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Version\"},{\"t\":3,\"p\":1,\"n\":\"Object Format\"},{\"t\":7,\"p\":1,\"n\":\"Scripts\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Script\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"scriptName\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":7,\"p\":1,\"n\":\"Properties\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Property\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"propertyName\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]},{\"t\":2,\"p\":1,\"n\":\"String\"},{\"t\":3,\"p\":1,\"n\":\"Int32\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":3,\"p\":1,\"n\":\"Bool\"},{\"t\":7,\"p\":1,\"n\":\"Array of Object\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]}]},{\"t\":7,\"p\":1,\"n\":\"Array of String\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Int32\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Float\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Bool\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]}]}]}]}]},{\"t\":6,\"p\":1,\"n\":\"Script Fragments\",\"c\":[{\"t\":3,\"n\":\"Unknown\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":2,\"p\":1,\"n\":\"fileName\"},{\"t\":7,\"p\":1,\"n\":\"Fragments\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Fragment\",\"c\":[{\"t\":3,\"n\":\"Unknown\"},{\"t\":2,\"p\":1,\"n\":\"scriptName\"},{\"t\":2,\"p\":1,\"n\":\"fragmentName\"}]}]}]}]},{\"t\":11,\"n\":\"DATA - Unknown\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"ENAM - Response flags\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":3,\"p\":1,\"n\":\"Reset Hours\"}]},{\"t\":3,\"p\":1,\"n\":\"TPIC - Topic\"},{\"t\":3,\"p\":1,\"n\":\"PNAM - Previous INFO\"},{\"t\":3,\"p\":1,\"n\":\"CNAM - Favor Level\"},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Link To\",\"d\":1,\"c\":[{\"t\":3,\"p\":1,\"n\":\"TCLT - Response\"}]},{\"t\":3,\"p\":1,\"n\":\"DNAM - Response Data\"},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Responses\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Response\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"TRDT - Response Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Emotion Type\"},{\"t\":3,\"p\":1,\"n\":\"Emotion Value\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Response number\"},{\"t\":3,\"p\":1,\"n\":\"Sound\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"}]},{\"t\":2,\"p\":1,\"n\":\"NAM1 - Response Text\"},{\"t\":2,\"p\":1,\"n\":\"NAM2 - Script Notes\"},{\"t\":2,\"p\":1,\"n\":\"NAM3 - Edits\"},{\"t\":3,\"p\":1,\"n\":\"SNAM - Idle Animations: Speaker\"},{\"t\":3,\"p\":1,\"n\":\"LNAM - Idle Animations: Listener\"}]}]},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Conditions\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Condition\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"CTDA - \",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":5,\"p\":1,\"n\":\"Comparison Value - Float\"},{\"t\":3,\"p\":1,\"n\":\"Comparison Value - Global\"},{\"t\":3,\"p\":1,\"n\":\"Function\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":11,\"p\":1,\"n\":\"None\"},{\"t\":3,\"p\":1,\"n\":\"Integer\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":11,\"p\":1,\"n\":\"Variable Name (unused)\"},{\"t\":3,\"p\":1,\"n\":\"Sex\"},{\"t\":3,\"p\":1,\"n\":\"Actor Value\"},{\"t\":3,\"p\":1,\"n\":\"Crime Type\"},{\"t\":3,\"p\":1,\"n\":\"Axis\"},{\"t\":3,\"p\":1,\"n\":\"Quest Stage (unused)\"},{\"t\":3,\"p\":1,\"n\":\"Misc Stat\"},{\"t\":3,\"p\":1,\"n\":\"Alignment\"},{\"t\":3,\"p\":1,\"n\":\"Equip Type\"},{\"t\":3,\"p\":1,\"n\":\"Form Type\"},{\"t\":3,\"p\":1,\"n\":\"Critical Stage\"},{\"t\":3,\"p\":1,\"n\":\"Object Reference\"},{\"t\":3,\"p\":1,\"n\":\"Inventory Object\"},{\"t\":3,\"p\":1,\"n\":\"Actor\"},{\"t\":3,\"p\":1,\"n\":\"Voice Type\"},{\"t\":3,\"p\":1,\"n\":\"Idle\"},{\"t\":3,\"p\":1,\"n\":\"Form List\"},{\"t\":3,\"p\":1,\"n\":\"Quest\"},{\"t\":3,\"p\":1,\"n\":\"Faction\"},{\"t\":3,\"p\":1,\"n\":\"Cell\"},{\"t\":3,\"p\":1,\"n\":\"Class\"},{\"t\":3,\"p\":1,\"n\":\"Race\"},{\"t\":3,\"p\":1,\"n\":\"Actor Base\"},{\"t\":3,\"p\":1,\"n\":\"Global\"},{\"t\":3,\"p\":1,\"n\":\"Weather\"},{\"t\":3,\"p\":1,\"n\":\"Package\"},{\"t\":3,\"p\":1,\"n\":\"Encounter Zone\"},{\"t\":3,\"p\":1,\"n\":\"Perk\"},{\"t\":3,\"p\":1,\"n\":\"Owner\"},{\"t\":3,\"p\":1,\"n\":\"Furniture\"},{\"t\":3,\"p\":1,\"n\":\"Effect Item\"},{\"t\":3,\"p\":1,\"n\":\"Base Effect\"},{\"t\":3,\"p\":1,\"n\":\"Worldspace\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Function\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Param (INVALID)\"},{\"t\":3,\"p\":1,\"n\":\"Referenceable Object\"},{\"t\":3,\"p\":1,\"n\":\"Region\"},{\"t\":3,\"p\":1,\"n\":\"Keyword\"},{\"t\":3,\"p\":1,\"n\":\"Player Action\"},{\"t\":3,\"p\":1,\"n\":\"Casting Type\"},{\"t\":3,\"p\":1,\"n\":\"Shout\"},{\"t\":3,\"p\":1,\"n\":\"Location\"},{\"t\":3,\"p\":1,\"n\":\"Location Ref Type\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"Packdata ID\"},{\"t\":3,\"p\":1,\"n\":\"Association Type\"},{\"t\":3,\"p\":1,\"n\":\"Furniture Anim\"},{\"t\":3,\"p\":1,\"n\":\"Furniture Entry\"},{\"t\":3,\"p\":1,\"n\":\"Scene\"},{\"t\":3,\"p\":1,\"n\":\"Ward State\"},{\"t\":3,\"p\":1,\"n\":\"Event\"},{\"t\":3,\"p\":1,\"n\":\"Event Data\"},{\"t\":3,\"p\":1,\"n\":\"Quest Stage\"},{\"t\":3,\"p\":1,\"n\":\"Weapon\"},{\"t\":3,\"p\":1,\"n\":\"Weapon List\"},{\"t\":3,\"p\":1,\"n\":\"Target\"},{\"t\":3,\"p\":1,\"n\":\"Target List\"},{\"t\":3,\"p\":1,\"n\":\"Target Part\"},{\"t\":3,\"p\":1,\"n\":\"VATS Action\"},{\"t\":3,\"p\":1,\"n\":\"Critical Effect\"},{\"t\":3,\"p\":1,\"n\":\"Critical Effect List\"},{\"t\":3,\"p\":1,\"n\":\"Weapon Type\"},{\"t\":3,\"p\":1,\"n\":\"Projectile Type\"},{\"t\":3,\"p\":1,\"n\":\"Delivery Type\"},{\"t\":3,\"p\":1,\"n\":\"Run On\"},{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":3,\"p\":1,\"n\":\"Parameter #3\"}]},{\"t\":2,\"p\":1,\"n\":\"CIS1 - Parameter #1\"},{\"t\":2,\"p\":1,\"n\":\"CIS2 - Parameter #2\"}]}]},{\"t\":8,\"n\":\"Unknown\",\"c\":[{\"t\":6,\"n\":\"Unknown\",\"c\":[{\"t\":11,\"n\":\"SCHR - Unknown\"},{\"t\":3,\"n\":\"QNAM - Unknown\"},{\"n\":\"NEXT - Marker\"}]}]},{\"t\":2,\"p\":1,\"n\":\"RNAM - Prompt\"},{\"t\":3,\"p\":1,\"n\":\"ANAM - Speaker\"},{\"t\":3,\"p\":1,\"n\":\"TWAT - Walk Away Topic\"},{\"t\":3,\"p\":1,\"n\":\"ONAM - Audio Output Override\"}]},{\"t\":1,\"p\":1,\"n\":\"INGR - Ingredient\",\"f\":1,\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"VMAD - Virtual Machine Adapter\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Version\"},{\"t\":3,\"p\":1,\"n\":\"Object Format\"},{\"t\":7,\"p\":1,\"n\":\"Scripts\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Script\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"scriptName\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":7,\"p\":1,\"n\":\"Properties\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Property\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"propertyName\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]},{\"t\":2,\"p\":1,\"n\":\"String\"},{\"t\":3,\"p\":1,\"n\":\"Int32\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":3,\"p\":1,\"n\":\"Bool\"},{\"t\":7,\"p\":1,\"n\":\"Array of Object\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]}]},{\"t\":7,\"p\":1,\"n\":\"Array of String\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Int32\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Float\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Bool\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]}]}]}]}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"X1\"},{\"t\":3,\"p\":1,\"n\":\"Y1\"},{\"t\":3,\"p\":1,\"n\":\"Z1\"},{\"t\":3,\"p\":1,\"n\":\"X2\"},{\"t\":3,\"p\":1,\"n\":\"Y2\"},{\"t\":3,\"p\":1,\"n\":\"Z2\"}]},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":3,\"n\":\"KSIZ - Keyword Count\"},{\"t\":7,\"p\":1,\"n\":\"KWDA - Keywords\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Keyword\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"MODT - Texture Files Hashes\"},{\"t\":7,\"p\":1,\"n\":\"MODS - Alternate Textures\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"3D Name\"},{\"t\":3,\"p\":1,\"n\":\"New Texture\"},{\"t\":3,\"p\":1,\"n\":\"3D Index\"}]}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Icon\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"ICON - Large Icon filename\"},{\"t\":2,\"p\":1,\"n\":\"MICO - Small Icon filename\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Destructable\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"DEST - Header\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Health\"},{\"t\":3,\"p\":1,\"n\":\"DEST Count\"},{\"t\":3,\"p\":1,\"n\":\"VATS Targetable\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":8,\"p\":1,\"n\":\"Stages\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Stage\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"DSTD - Destruction Stage Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Health %\"},{\"t\":3,\"p\":1,\"n\":\"Index\"},{\"t\":3,\"p\":1,\"n\":\"Model Damage Stage\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":3,\"p\":1,\"n\":\"Self Damage per Second\"},{\"t\":3,\"p\":1,\"n\":\"Explosion\"},{\"t\":3,\"p\":1,\"n\":\"Debris\"},{\"t\":3,\"p\":1,\"n\":\"Debris Count\"}]},{\"t\":6,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"DMDL - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"DMDT - Texture Files Hashes\"},{\"t\":7,\"p\":1,\"n\":\"DMDS - Alternate Textures\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"3D Name\"},{\"t\":3,\"p\":1,\"n\":\"New Texture\"},{\"t\":3,\"p\":1,\"n\":\"3D Index\"}]}]}]},{\"p\":1,\"n\":\"DSTF - End Marker\"}]}]}]},{\"t\":3,\"p\":1,\"n\":\"ETYP - Equipment Type\"},{\"t\":3,\"p\":1,\"n\":\"YNAM - Sound - Pick Up\"},{\"t\":3,\"p\":1,\"n\":\"ZNAM - Sound - Put Down\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DATA - \",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Value\"},{\"t\":5,\"p\":1,\"n\":\"Weight\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"ENIT - Effect Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Ingredient Value\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"}]},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Effects\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Effect\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"EFID - Base Effect\"},{\"t\":6,\"p\":1,\"n\":\"EFIT - \",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Magnitude\"},{\"t\":3,\"p\":1,\"n\":\"Area\"},{\"t\":3,\"p\":1,\"n\":\"Duration\"}]},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Conditions\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Condition\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"CTDA - \",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":5,\"p\":1,\"n\":\"Comparison Value - Float\"},{\"t\":3,\"p\":1,\"n\":\"Comparison Value - Global\"},{\"t\":3,\"p\":1,\"n\":\"Function\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":11,\"p\":1,\"n\":\"None\"},{\"t\":3,\"p\":1,\"n\":\"Integer\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":11,\"p\":1,\"n\":\"Variable Name (unused)\"},{\"t\":3,\"p\":1,\"n\":\"Sex\"},{\"t\":3,\"p\":1,\"n\":\"Actor Value\"},{\"t\":3,\"p\":1,\"n\":\"Crime Type\"},{\"t\":3,\"p\":1,\"n\":\"Axis\"},{\"t\":3,\"p\":1,\"n\":\"Quest Stage (unused)\"},{\"t\":3,\"p\":1,\"n\":\"Misc Stat\"},{\"t\":3,\"p\":1,\"n\":\"Alignment\"},{\"t\":3,\"p\":1,\"n\":\"Equip Type\"},{\"t\":3,\"p\":1,\"n\":\"Form Type\"},{\"t\":3,\"p\":1,\"n\":\"Critical Stage\"},{\"t\":3,\"p\":1,\"n\":\"Object Reference\"},{\"t\":3,\"p\":1,\"n\":\"Inventory Object\"},{\"t\":3,\"p\":1,\"n\":\"Actor\"},{\"t\":3,\"p\":1,\"n\":\"Voice Type\"},{\"t\":3,\"p\":1,\"n\":\"Idle\"},{\"t\":3,\"p\":1,\"n\":\"Form List\"},{\"t\":3,\"p\":1,\"n\":\"Quest\"},{\"t\":3,\"p\":1,\"n\":\"Faction\"},{\"t\":3,\"p\":1,\"n\":\"Cell\"},{\"t\":3,\"p\":1,\"n\":\"Class\"},{\"t\":3,\"p\":1,\"n\":\"Race\"},{\"t\":3,\"p\":1,\"n\":\"Actor Base\"},{\"t\":3,\"p\":1,\"n\":\"Global\"},{\"t\":3,\"p\":1,\"n\":\"Weather\"},{\"t\":3,\"p\":1,\"n\":\"Package\"},{\"t\":3,\"p\":1,\"n\":\"Encounter Zone\"},{\"t\":3,\"p\":1,\"n\":\"Perk\"},{\"t\":3,\"p\":1,\"n\":\"Owner\"},{\"t\":3,\"p\":1,\"n\":\"Furniture\"},{\"t\":3,\"p\":1,\"n\":\"Effect Item\"},{\"t\":3,\"p\":1,\"n\":\"Base Effect\"},{\"t\":3,\"p\":1,\"n\":\"Worldspace\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Function\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Param (INVALID)\"},{\"t\":3,\"p\":1,\"n\":\"Referenceable Object\"},{\"t\":3,\"p\":1,\"n\":\"Region\"},{\"t\":3,\"p\":1,\"n\":\"Keyword\"},{\"t\":3,\"p\":1,\"n\":\"Player Action\"},{\"t\":3,\"p\":1,\"n\":\"Casting Type\"},{\"t\":3,\"p\":1,\"n\":\"Shout\"},{\"t\":3,\"p\":1,\"n\":\"Location\"},{\"t\":3,\"p\":1,\"n\":\"Location Ref Type\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"Packdata ID\"},{\"t\":3,\"p\":1,\"n\":\"Association Type\"},{\"t\":3,\"p\":1,\"n\":\"Furniture Anim\"},{\"t\":3,\"p\":1,\"n\":\"Furniture Entry\"},{\"t\":3,\"p\":1,\"n\":\"Scene\"},{\"t\":3,\"p\":1,\"n\":\"Ward State\"},{\"t\":3,\"p\":1,\"n\":\"Event\"},{\"t\":3,\"p\":1,\"n\":\"Event Data\"},{\"t\":3,\"p\":1,\"n\":\"Quest Stage\"},{\"t\":3,\"p\":1,\"n\":\"Weapon\"},{\"t\":3,\"p\":1,\"n\":\"Weapon List\"},{\"t\":3,\"p\":1,\"n\":\"Target\"},{\"t\":3,\"p\":1,\"n\":\"Target List\"},{\"t\":3,\"p\":1,\"n\":\"Target Part\"},{\"t\":3,\"p\":1,\"n\":\"VATS Action\"},{\"t\":3,\"p\":1,\"n\":\"Critical Effect\"},{\"t\":3,\"p\":1,\"n\":\"Critical Effect List\"},{\"t\":3,\"p\":1,\"n\":\"Weapon Type\"},{\"t\":3,\"p\":1,\"n\":\"Projectile Type\"},{\"t\":3,\"p\":1,\"n\":\"Delivery Type\"},{\"t\":3,\"p\":1,\"n\":\"Run On\"},{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":3,\"p\":1,\"n\":\"Parameter #3\"}]},{\"t\":2,\"p\":1,\"n\":\"CIS1 - Parameter #1\"},{\"t\":2,\"p\":1,\"n\":\"CIS2 - Parameter #2\"}]}]}]}]}]},{\"t\":1,\"p\":1,\"n\":\"IPCT - Impact\",\"f\":1,\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"MODT - Texture Files Hashes\"},{\"t\":7,\"p\":1,\"n\":\"MODS - Alternate Textures\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"3D Name\"},{\"t\":3,\"p\":1,\"n\":\"New Texture\"},{\"t\":3,\"p\":1,\"n\":\"3D Index\"}]}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DATA - \",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Effect - Duration\"},{\"t\":3,\"p\":1,\"n\":\"Effect - Orientation\"},{\"t\":5,\"p\":1,\"n\":\"Angle Threshold\"},{\"t\":5,\"p\":1,\"n\":\"Placement Radius\"},{\"t\":3,\"p\":1,\"n\":\"Sound Level\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":3,\"p\":1,\"n\":\"Impact Result\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DODT - Decal Data\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Min Width\"},{\"t\":5,\"p\":1,\"n\":\"Max Width\"},{\"t\":5,\"p\":1,\"n\":\"Min Height\"},{\"t\":5,\"p\":1,\"n\":\"Max Height\"},{\"t\":5,\"p\":1,\"n\":\"Depth\"},{\"t\":5,\"p\":1,\"n\":\"Shininess\"},{\"t\":6,\"p\":1,\"n\":\"Parallax\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Scale\"},{\"t\":3,\"p\":1,\"n\":\"Passes\"}]},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":6,\"p\":1,\"n\":\"Color\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]}]},{\"t\":3,\"p\":1,\"n\":\"DNAM - Texture Set\"},{\"t\":3,\"p\":1,\"n\":\"ENAM - Secondary Texture Set\"},{\"t\":3,\"p\":1,\"n\":\"SNAM - Sound 1\"},{\"t\":3,\"p\":1,\"n\":\"NAM1 - Sound 2\"},{\"t\":3,\"p\":1,\"n\":\"NAM2 - Hazard\"}]},{\"t\":1,\"p\":1,\"n\":\"IPDS - Impact Data Set\",\"f\":1,\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Data\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"PNAM - \",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Material\"},{\"t\":3,\"p\":1,\"n\":\"Impact\"}]}]}]},{\"t\":1,\"p\":1,\"n\":\"KEYM - Key\",\"f\":1,\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"VMAD - Virtual Machine Adapter\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Version\"},{\"t\":3,\"p\":1,\"n\":\"Object Format\"},{\"t\":7,\"p\":1,\"n\":\"Scripts\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Script\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"scriptName\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":7,\"p\":1,\"n\":\"Properties\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Property\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"propertyName\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]},{\"t\":2,\"p\":1,\"n\":\"String\"},{\"t\":3,\"p\":1,\"n\":\"Int32\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":3,\"p\":1,\"n\":\"Bool\"},{\"t\":7,\"p\":1,\"n\":\"Array of Object\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]}]},{\"t\":7,\"p\":1,\"n\":\"Array of String\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Int32\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Float\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Bool\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]}]}]}]}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"X1\"},{\"t\":3,\"p\":1,\"n\":\"Y1\"},{\"t\":3,\"p\":1,\"n\":\"Z1\"},{\"t\":3,\"p\":1,\"n\":\"X2\"},{\"t\":3,\"p\":1,\"n\":\"Y2\"},{\"t\":3,\"p\":1,\"n\":\"Z2\"}]},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"MODT - Texture Files Hashes\"},{\"t\":7,\"p\":1,\"n\":\"MODS - Alternate Textures\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"3D Name\"},{\"t\":3,\"p\":1,\"n\":\"New Texture\"},{\"t\":3,\"p\":1,\"n\":\"3D Index\"}]}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Icon\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"ICON - Large Icon filename\"},{\"t\":2,\"p\":1,\"n\":\"MICO - Small Icon filename\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Destructable\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"DEST - Header\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Health\"},{\"t\":3,\"p\":1,\"n\":\"DEST Count\"},{\"t\":3,\"p\":1,\"n\":\"VATS Targetable\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":8,\"p\":1,\"n\":\"Stages\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Stage\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"DSTD - Destruction Stage Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Health %\"},{\"t\":3,\"p\":1,\"n\":\"Index\"},{\"t\":3,\"p\":1,\"n\":\"Model Damage Stage\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":3,\"p\":1,\"n\":\"Self Damage per Second\"},{\"t\":3,\"p\":1,\"n\":\"Explosion\"},{\"t\":3,\"p\":1,\"n\":\"Debris\"},{\"t\":3,\"p\":1,\"n\":\"Debris Count\"}]},{\"t\":6,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"DMDL - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"DMDT - Texture Files Hashes\"},{\"t\":7,\"p\":1,\"n\":\"DMDS - Alternate Textures\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"3D Name\"},{\"t\":3,\"p\":1,\"n\":\"New Texture\"},{\"t\":3,\"p\":1,\"n\":\"3D Index\"}]}]}]},{\"p\":1,\"n\":\"DSTF - End Marker\"}]}]}]},{\"t\":3,\"p\":1,\"n\":\"YNAM - Sound - Pick Up\"},{\"t\":3,\"p\":1,\"n\":\"ZNAM - Sound - Put Down\"},{\"t\":3,\"n\":\"KSIZ - Keyword Count\"},{\"t\":7,\"p\":1,\"n\":\"KWDA - Keywords\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Keyword\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DATA - \",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Value\"},{\"t\":5,\"p\":1,\"n\":\"Weight\"}]}]},{\"t\":1,\"p\":1,\"n\":\"KYWD - Keyword\",\"f\":1,\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"CNAM - Color\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unknown\"}]}]},{\"t\":1,\"p\":1,\"n\":\"LAND - Landscape\",\"f\":1,\"d\":1,\"c\":[{\"t\":11,\"n\":\"DATA - Unknown\"},{\"t\":11,\"n\":\"VNML - Vertex Normals\"},{\"t\":11,\"n\":\"VHGT - Vertext Height Map\"},{\"t\":11,\"n\":\"VCLR - Vertex Colours\"},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Layers\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Base Layer\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"BTXT - Base Layer Header\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Texture\"},{\"t\":3,\"p\":1,\"n\":\"Quadrant\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":3,\"p\":1,\"n\":\"Layer\"}]}]},{\"t\":6,\"p\":1,\"n\":\"Alpha Layer\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"ATXT - Alpha Layer Header\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Texture\"},{\"t\":3,\"p\":1,\"n\":\"Quadrant\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":3,\"p\":1,\"n\":\"Layer\"}]},{\"t\":11,\"p\":1,\"n\":\"VTXT - Alpha Layer Data\"}]}]},{\"t\":7,\"p\":1,\"n\":\"VTEX - Textures\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Texture\"}]}]},{\"t\":1,\"p\":1,\"n\":\"LCRT - Location Reference Type\",\"f\":1,\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"CNAM - Color\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unknown\"}]}]},{\"t\":1,\"n\":\"LCTN - Location\",\"c\":[{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":7,\"n\":\"ACPR - Actor Cell Persistent Reference\",\"c\":[{\"t\":6,\"n\":\"\",\"c\":[{\"t\":3,\"n\":\"Actor\"},{\"t\":3,\"n\":\"Location\"},{\"t\":3,\"n\":\"Grid Y\"},{\"t\":3,\"n\":\"Grid X\"}]}]},{\"t\":7,\"n\":\"LCPR - Location Cell Persistent Reference\",\"c\":[{\"t\":6,\"n\":\"\",\"c\":[{\"t\":3,\"n\":\"Actor\"},{\"t\":3,\"n\":\"Location\"},{\"t\":3,\"n\":\"Grid Y\"},{\"t\":3,\"n\":\"Grid X\"}]}]},{\"t\":7,\"n\":\"RCPR - Reference Cell Persistent Reference\",\"c\":[{\"t\":3,\"n\":\"Ref\"}]},{\"t\":7,\"n\":\"ACUN - Actor Cell Unique\",\"c\":[{\"t\":6,\"n\":\"\",\"c\":[{\"t\":3,\"n\":\"Actor\"},{\"t\":3,\"n\":\"Ref\"},{\"t\":3,\"n\":\"Location\"}]}]},{\"t\":7,\"n\":\"LCUN - Location Cell Unique\",\"c\":[{\"t\":6,\"n\":\"\",\"c\":[{\"t\":3,\"n\":\"Actor\"},{\"t\":3,\"n\":\"Ref\"},{\"t\":3,\"n\":\"Location\"}]}]},{\"t\":7,\"n\":\"RCUN - Reference Cell Unique\",\"c\":[{\"t\":3,\"n\":\"Actor\"}]},{\"t\":7,\"n\":\"ACSR - Actor Cell Static Reference\",\"c\":[{\"t\":6,\"n\":\"\",\"c\":[{\"t\":3,\"n\":\"Loc Ref Type\"},{\"t\":3,\"n\":\"Marker\"},{\"t\":3,\"n\":\"Location\"},{\"t\":3,\"n\":\"Grid Y\"},{\"t\":3,\"n\":\"Grid X\"}]}]},{\"t\":7,\"n\":\"LCSR - Location Cell Static Reference\",\"c\":[{\"t\":6,\"n\":\"\",\"c\":[{\"t\":3,\"n\":\"Loc Ref Type\"},{\"t\":3,\"n\":\"Marker\"},{\"t\":3,\"n\":\"Location\"},{\"t\":3,\"n\":\"Grid Y\"},{\"t\":3,\"n\":\"Grid X\"}]}]},{\"t\":7,\"n\":\"RCSR - Reference Cell Static Reference\",\"c\":[{\"t\":3,\"n\":\"Ref\"}]},{\"t\":8,\"n\":\"Actor Cell Encounter Cell\",\"c\":[{\"t\":6,\"n\":\"ACEC - Unknown\",\"c\":[{\"t\":3,\"n\":\"Location\"},{\"t\":7,\"n\":\"Coordinates\",\"c\":[{\"t\":6,\"n\":\"\",\"c\":[{\"t\":3,\"n\":\"Grid Y\"},{\"t\":3,\"n\":\"Grid X\"}]}]}]}]},{\"t\":8,\"n\":\"Location Cell Encounter Cell\",\"c\":[{\"t\":6,\"n\":\"LCEC - Unknown\",\"c\":[{\"t\":3,\"n\":\"Location\"},{\"t\":7,\"n\":\"Coordinates\",\"c\":[{\"t\":6,\"n\":\"\",\"c\":[{\"t\":3,\"n\":\"Grid Y\"},{\"t\":3,\"n\":\"Grid X\"}]}]}]}]},{\"t\":8,\"n\":\"Reference Cell Encounter Cell\",\"c\":[{\"t\":6,\"n\":\"RCEC - Unknown\",\"c\":[{\"t\":3,\"n\":\"Location\"},{\"t\":7,\"n\":\"Coordinates\",\"c\":[{\"t\":6,\"n\":\"\",\"c\":[{\"t\":3,\"n\":\"Grid Y\"},{\"t\":3,\"n\":\"Grid X\"}]}]}]}]},{\"t\":7,\"n\":\"ACID - Actor Cell Marker Reference\",\"c\":[{\"t\":3,\"n\":\"Ref\"}]},{\"t\":7,\"n\":\"LCID - Location Cell Marker Reference\",\"c\":[{\"t\":3,\"n\":\"Ref\"}]},{\"t\":7,\"n\":\"ACEP - Actor Cell Enable Point\",\"c\":[{\"t\":6,\"n\":\"\",\"c\":[{\"t\":3,\"n\":\"Actor\"},{\"t\":3,\"n\":\"Ref\"},{\"t\":3,\"n\":\"Grid Y\"},{\"t\":3,\"n\":\"Grid X\"}]}]},{\"t\":7,\"n\":\"LCEP - Location Cell Enable Point\",\"c\":[{\"t\":6,\"n\":\"\",\"c\":[{\"t\":3,\"n\":\"Actor\"},{\"t\":3,\"n\":\"Ref\"},{\"t\":3,\"n\":\"Grid Y\"},{\"t\":3,\"n\":\"Grid X\"}]}]},{\"t\":2,\"n\":\"FULL - Name\"},{\"t\":3,\"n\":\"KSIZ - Keyword Count\"},{\"t\":7,\"n\":\"KWDA - Keywords\",\"c\":[{\"t\":3,\"n\":\"Keyword\"}]},{\"t\":3,\"n\":\"PNAM - Parent Location\"},{\"t\":3,\"n\":\"NAM1 - Music\"},{\"t\":3,\"n\":\"FNAM - Unreported Crime Faction\"},{\"t\":3,\"n\":\"MNAM - World Location Marker Ref\"},{\"t\":5,\"n\":\"RNAM - World Location Radius\"},{\"t\":3,\"n\":\"NAM0 - Horse Marker Ref\"},{\"t\":6,\"n\":\"CNAM - Color\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unknown\"}]}]},{\"t\":1,\"p\":1,\"n\":\"LENS - Lens Flare\",\"f\":1,\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":5,\"p\":1,\"n\":\"CNAM - Color Influence\"},{\"t\":5,\"p\":1,\"n\":\"DNAM - Fade Distance Radius Scale\"},{\"t\":3,\"n\":\"LFSP - Count\"},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Lens Flare Sprites\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Flare\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"DNAM - Lens Flare Sprite ID\"},{\"t\":2,\"p\":1,\"n\":\"FNAM - Texture\"},{\"t\":6,\"p\":1,\"n\":\"LFSD - Lens Flare Data\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Tint\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Red\"},{\"t\":5,\"p\":1,\"n\":\"Green\"},{\"t\":5,\"p\":1,\"n\":\"Blue\"}]},{\"t\":5,\"p\":1,\"n\":\"Width\"},{\"t\":5,\"p\":1,\"n\":\"Height\"},{\"t\":5,\"p\":1,\"n\":\"Position\"},{\"t\":5,\"p\":1,\"n\":\"Angular Fade\"},{\"t\":5,\"p\":1,\"n\":\"Opacity\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"}]}]}]}]},{\"t\":1,\"p\":1,\"n\":\"LGTM - Lighting Template\",\"f\":1,\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DATA - Lighting\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Ambient Color\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Directional Color\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Fog Color Near\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":5,\"p\":1,\"n\":\"Fog Near\"},{\"t\":5,\"p\":1,\"n\":\"Fog Far\"},{\"t\":3,\"p\":1,\"n\":\"Directional Rotation XY\"},{\"t\":3,\"p\":1,\"n\":\"Directional Rotation Z\"},{\"t\":5,\"p\":1,\"n\":\"Directional Fade\"},{\"t\":5,\"p\":1,\"n\":\"Fog Clip Dist\"},{\"t\":5,\"p\":1,\"n\":\"Fog Power\"},{\"t\":6,\"p\":1,\"n\":\"Ambient Colors\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Directional\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"X+\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"X-\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Y+\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Y-\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Z+\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Z-\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]}]},{\"t\":6,\"p\":1,\"n\":\"Specular\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":5,\"p\":1,\"n\":\"Scale\"}]},{\"t\":6,\"p\":1,\"n\":\"Fog Color Far\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":5,\"p\":1,\"n\":\"Fog Max\"},{\"t\":6,\"p\":1,\"n\":\"Light Fade Distances\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Start\"},{\"t\":5,\"p\":1,\"n\":\"End\"}]},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DALC - Directional Ambient Lighting Colors\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Directional\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"X+\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"X-\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Y+\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Y-\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Z+\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Z-\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]}]},{\"t\":6,\"p\":1,\"n\":\"Specular\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":5,\"p\":1,\"n\":\"Scale\"}]}]},{\"t\":1,\"p\":1,\"n\":\"LIGH - Light\",\"f\":1,\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"VMAD - Virtual Machine Adapter\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Version\"},{\"t\":3,\"p\":1,\"n\":\"Object Format\"},{\"t\":7,\"p\":1,\"n\":\"Scripts\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Script\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"scriptName\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":7,\"p\":1,\"n\":\"Properties\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Property\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"propertyName\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]},{\"t\":2,\"p\":1,\"n\":\"String\"},{\"t\":3,\"p\":1,\"n\":\"Int32\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":3,\"p\":1,\"n\":\"Bool\"},{\"t\":7,\"p\":1,\"n\":\"Array of Object\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]}]},{\"t\":7,\"p\":1,\"n\":\"Array of String\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Int32\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Float\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Bool\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]}]}]}]}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"X1\"},{\"t\":3,\"p\":1,\"n\":\"Y1\"},{\"t\":3,\"p\":1,\"n\":\"Z1\"},{\"t\":3,\"p\":1,\"n\":\"X2\"},{\"t\":3,\"p\":1,\"n\":\"Y2\"},{\"t\":3,\"p\":1,\"n\":\"Z2\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"MODT - Texture Files Hashes\"},{\"t\":7,\"p\":1,\"n\":\"MODS - Alternate Textures\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"3D Name\"},{\"t\":3,\"p\":1,\"n\":\"New Texture\"},{\"t\":3,\"p\":1,\"n\":\"3D Index\"}]}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Destructable\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"DEST - Header\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Health\"},{\"t\":3,\"p\":1,\"n\":\"DEST Count\"},{\"t\":3,\"p\":1,\"n\":\"VATS Targetable\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":8,\"p\":1,\"n\":\"Stages\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Stage\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"DSTD - Destruction Stage Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Health %\"},{\"t\":3,\"p\":1,\"n\":\"Index\"},{\"t\":3,\"p\":1,\"n\":\"Model Damage Stage\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":3,\"p\":1,\"n\":\"Self Damage per Second\"},{\"t\":3,\"p\":1,\"n\":\"Explosion\"},{\"t\":3,\"p\":1,\"n\":\"Debris\"},{\"t\":3,\"p\":1,\"n\":\"Debris Count\"}]},{\"t\":6,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"DMDL - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"DMDT - Texture Files Hashes\"},{\"t\":7,\"p\":1,\"n\":\"DMDS - Alternate Textures\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"3D Name\"},{\"t\":3,\"p\":1,\"n\":\"New Texture\"},{\"t\":3,\"p\":1,\"n\":\"3D Index\"}]}]}]},{\"p\":1,\"n\":\"DSTF - End Marker\"}]}]}]},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Icon\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"ICON - Large Icon filename\"},{\"t\":2,\"p\":1,\"n\":\"MICO - Small Icon filename\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DATA - \",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Time\"},{\"t\":3,\"p\":1,\"n\":\"Radius\"},{\"t\":6,\"p\":1,\"n\":\"Color\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":5,\"p\":1,\"n\":\"Falloff Exponent\"},{\"t\":5,\"p\":1,\"n\":\"FOV\"},{\"t\":5,\"p\":1,\"n\":\"Near Clip\"},{\"t\":6,\"p\":1,\"n\":\"Flicker Effect\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Period\"},{\"t\":5,\"p\":1,\"n\":\"Intensity Amplitude\"},{\"t\":5,\"p\":1,\"n\":\"Movement Amplitude\"}]},{\"t\":3,\"p\":1,\"n\":\"Value\"},{\"t\":5,\"p\":1,\"n\":\"Weight\"}]},{\"t\":5,\"p\":1,\"n\":\"FNAM - Fade value\"},{\"t\":3,\"p\":1,\"n\":\"SNAM - Sound\"}]},{\"t\":1,\"p\":1,\"n\":\"LSCR - Load Screen\",\"f\":1,\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Icon\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"ICON - Large Icon filename\"},{\"t\":2,\"p\":1,\"n\":\"MICO - Small Icon filename\"}]},{\"t\":2,\"p\":1,\"n\":\"DESC - Description\"},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Conditions\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Condition\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"CTDA - \",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":5,\"p\":1,\"n\":\"Comparison Value - Float\"},{\"t\":3,\"p\":1,\"n\":\"Comparison Value - Global\"},{\"t\":3,\"p\":1,\"n\":\"Function\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":11,\"p\":1,\"n\":\"None\"},{\"t\":3,\"p\":1,\"n\":\"Integer\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":11,\"p\":1,\"n\":\"Variable Name (unused)\"},{\"t\":3,\"p\":1,\"n\":\"Sex\"},{\"t\":3,\"p\":1,\"n\":\"Actor Value\"},{\"t\":3,\"p\":1,\"n\":\"Crime Type\"},{\"t\":3,\"p\":1,\"n\":\"Axis\"},{\"t\":3,\"p\":1,\"n\":\"Quest Stage (unused)\"},{\"t\":3,\"p\":1,\"n\":\"Misc Stat\"},{\"t\":3,\"p\":1,\"n\":\"Alignment\"},{\"t\":3,\"p\":1,\"n\":\"Equip Type\"},{\"t\":3,\"p\":1,\"n\":\"Form Type\"},{\"t\":3,\"p\":1,\"n\":\"Critical Stage\"},{\"t\":3,\"p\":1,\"n\":\"Object Reference\"},{\"t\":3,\"p\":1,\"n\":\"Inventory Object\"},{\"t\":3,\"p\":1,\"n\":\"Actor\"},{\"t\":3,\"p\":1,\"n\":\"Voice Type\"},{\"t\":3,\"p\":1,\"n\":\"Idle\"},{\"t\":3,\"p\":1,\"n\":\"Form List\"},{\"t\":3,\"p\":1,\"n\":\"Quest\"},{\"t\":3,\"p\":1,\"n\":\"Faction\"},{\"t\":3,\"p\":1,\"n\":\"Cell\"},{\"t\":3,\"p\":1,\"n\":\"Class\"},{\"t\":3,\"p\":1,\"n\":\"Race\"},{\"t\":3,\"p\":1,\"n\":\"Actor Base\"},{\"t\":3,\"p\":1,\"n\":\"Global\"},{\"t\":3,\"p\":1,\"n\":\"Weather\"},{\"t\":3,\"p\":1,\"n\":\"Package\"},{\"t\":3,\"p\":1,\"n\":\"Encounter Zone\"},{\"t\":3,\"p\":1,\"n\":\"Perk\"},{\"t\":3,\"p\":1,\"n\":\"Owner\"},{\"t\":3,\"p\":1,\"n\":\"Furniture\"},{\"t\":3,\"p\":1,\"n\":\"Effect Item\"},{\"t\":3,\"p\":1,\"n\":\"Base Effect\"},{\"t\":3,\"p\":1,\"n\":\"Worldspace\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Function\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Param (INVALID)\"},{\"t\":3,\"p\":1,\"n\":\"Referenceable Object\"},{\"t\":3,\"p\":1,\"n\":\"Region\"},{\"t\":3,\"p\":1,\"n\":\"Keyword\"},{\"t\":3,\"p\":1,\"n\":\"Player Action\"},{\"t\":3,\"p\":1,\"n\":\"Casting Type\"},{\"t\":3,\"p\":1,\"n\":\"Shout\"},{\"t\":3,\"p\":1,\"n\":\"Location\"},{\"t\":3,\"p\":1,\"n\":\"Location Ref Type\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"Packdata ID\"},{\"t\":3,\"p\":1,\"n\":\"Association Type\"},{\"t\":3,\"p\":1,\"n\":\"Furniture Anim\"},{\"t\":3,\"p\":1,\"n\":\"Furniture Entry\"},{\"t\":3,\"p\":1,\"n\":\"Scene\"},{\"t\":3,\"p\":1,\"n\":\"Ward State\"},{\"t\":3,\"p\":1,\"n\":\"Event\"},{\"t\":3,\"p\":1,\"n\":\"Event Data\"},{\"t\":3,\"p\":1,\"n\":\"Quest Stage\"},{\"t\":3,\"p\":1,\"n\":\"Weapon\"},{\"t\":3,\"p\":1,\"n\":\"Weapon List\"},{\"t\":3,\"p\":1,\"n\":\"Target\"},{\"t\":3,\"p\":1,\"n\":\"Target List\"},{\"t\":3,\"p\":1,\"n\":\"Target Part\"},{\"t\":3,\"p\":1,\"n\":\"VATS Action\"},{\"t\":3,\"p\":1,\"n\":\"Critical Effect\"},{\"t\":3,\"p\":1,\"n\":\"Critical Effect List\"},{\"t\":3,\"p\":1,\"n\":\"Weapon Type\"},{\"t\":3,\"p\":1,\"n\":\"Projectile Type\"},{\"t\":3,\"p\":1,\"n\":\"Delivery Type\"},{\"t\":3,\"p\":1,\"n\":\"Run On\"},{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":3,\"p\":1,\"n\":\"Parameter #3\"}]},{\"t\":2,\"p\":1,\"n\":\"CIS1 - Parameter #1\"},{\"t\":2,\"p\":1,\"n\":\"CIS2 - Parameter #2\"}]}]},{\"t\":3,\"p\":1,\"n\":\"NNAM - Loading Screen NIF\"},{\"t\":5,\"p\":1,\"n\":\"SNAM - Initial Scale\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"RNAM - Initial Rotation\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"X\"},{\"t\":3,\"p\":1,\"n\":\"Y\"},{\"t\":3,\"p\":1,\"n\":\"Z\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"ONAM - Rotation Offset Constraints\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Min\"},{\"t\":3,\"p\":1,\"n\":\"Max\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"XNAM - Initial Translation Offset\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"X\"},{\"t\":5,\"p\":1,\"n\":\"Y\"},{\"t\":5,\"p\":1,\"n\":\"Z\"}]},{\"t\":2,\"p\":1,\"n\":\"MOD2 - Camera Path\"}]},{\"t\":1,\"p\":1,\"n\":\"LTEX - Landscape Texture\",\"f\":1,\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":3,\"p\":1,\"n\":\"TNAM - Texture Set\"},{\"t\":3,\"p\":1,\"n\":\"MNAM - Material Type\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"HNAM - Havok Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Friction\"},{\"t\":3,\"p\":1,\"n\":\"Restitution\"}]},{\"t\":3,\"p\":1,\"n\":\"SNAM - Texture Specular Exponent\"},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Grasses\",\"d\":1,\"c\":[{\"t\":3,\"p\":1,\"n\":\"GNAM - Grass\"}]},{\"t\":3,\"n\":\"INAM - Unused\"}]},{\"t\":1,\"p\":1,\"n\":\"LVLI - Leveled Item\",\"f\":1,\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"X1\"},{\"t\":3,\"p\":1,\"n\":\"Y1\"},{\"t\":3,\"p\":1,\"n\":\"Z1\"},{\"t\":3,\"p\":1,\"n\":\"X2\"},{\"t\":3,\"p\":1,\"n\":\"Y2\"},{\"t\":3,\"p\":1,\"n\":\"Z2\"}]},{\"t\":3,\"p\":1,\"n\":\"LVLD - Chance None\"},{\"t\":3,\"p\":1,\"n\":\"LVLF - Flags\"},{\"t\":3,\"p\":1,\"n\":\"LVLG - Global\"},{\"t\":3,\"n\":\"LLCT - Count\"},{\"t\":10,\"p\":1,\"n\":\"Leveled List Entries\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Leveled List Entry\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"LVLO - Base Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Level\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":3,\"p\":1,\"n\":\"Count\"}]},{\"t\":6,\"p\":1,\"n\":\"COED - Extra Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Owner\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Global Variable\"},{\"t\":3,\"p\":1,\"n\":\"Required Rank\"},{\"t\":5,\"p\":1,\"n\":\"Item Condition\"}]}]}]}]},{\"t\":1,\"p\":1,\"n\":\"LVLN - Leveled NPC\",\"f\":1,\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"X1\"},{\"t\":3,\"p\":1,\"n\":\"Y1\"},{\"t\":3,\"p\":1,\"n\":\"Z1\"},{\"t\":3,\"p\":1,\"n\":\"X2\"},{\"t\":3,\"p\":1,\"n\":\"Y2\"},{\"t\":3,\"p\":1,\"n\":\"Z2\"}]},{\"t\":3,\"p\":1,\"n\":\"LVLD - Chance None\"},{\"t\":3,\"p\":1,\"n\":\"LVLF - Flags\"},{\"t\":3,\"p\":1,\"n\":\"LVLG - Global\"},{\"t\":3,\"n\":\"LLCT - Count\"},{\"t\":10,\"p\":1,\"n\":\"Leveled List Entries\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Leveled List Entry\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"LVLO - Base Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Level\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":3,\"p\":1,\"n\":\"Count\"}]},{\"t\":6,\"p\":1,\"n\":\"COED - Extra Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Owner\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Global Variable\"},{\"t\":3,\"p\":1,\"n\":\"Required Rank\"},{\"t\":5,\"p\":1,\"n\":\"Item Condition\"}]}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"MODT - Texture Files Hashes\"},{\"t\":7,\"p\":1,\"n\":\"MODS - Alternate Textures\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"3D Name\"},{\"t\":3,\"p\":1,\"n\":\"New Texture\"},{\"t\":3,\"p\":1,\"n\":\"3D Index\"}]}]}]}]},{\"t\":1,\"p\":1,\"n\":\"LVSP - Leveled Spell\",\"f\":1,\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"X1\"},{\"t\":3,\"p\":1,\"n\":\"Y1\"},{\"t\":3,\"p\":1,\"n\":\"Z1\"},{\"t\":3,\"p\":1,\"n\":\"X2\"},{\"t\":3,\"p\":1,\"n\":\"Y2\"},{\"t\":3,\"p\":1,\"n\":\"Z2\"}]},{\"t\":3,\"p\":1,\"n\":\"LVLD - Chance None\"},{\"t\":3,\"p\":1,\"n\":\"LVLF - Flags\"},{\"t\":3,\"n\":\"LLCT - Count\"},{\"t\":10,\"p\":1,\"n\":\"Leveled List Entries\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Leveled List Entry\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"LVLO - Base Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Level\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":3,\"p\":1,\"n\":\"Count\"}]}]}]}]},{\"t\":1,\"p\":1,\"n\":\"MATO - Material Object\",\"f\":1,\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"MODT - Texture Files Hashes\"},{\"t\":7,\"p\":1,\"n\":\"MODS - Alternate Textures\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"3D Name\"},{\"t\":3,\"p\":1,\"n\":\"New Texture\"},{\"t\":3,\"p\":1,\"n\":\"3D Index\"}]}]}]},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Property Data\",\"d\":1,\"c\":[{\"t\":11,\"p\":1,\"n\":\"DNAM - Data\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DATA - Directional Material Data\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Falloff Scale\"},{\"t\":5,\"p\":1,\"n\":\"Falloff Bias\"},{\"t\":5,\"p\":1,\"n\":\"Noise UV Scale\"},{\"t\":5,\"p\":1,\"n\":\"Material UV Scale\"},{\"t\":6,\"p\":1,\"n\":\"Projection Vector\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"X\"},{\"t\":5,\"p\":1,\"n\":\"Y\"},{\"t\":5,\"p\":1,\"n\":\"Z\"}]},{\"t\":5,\"p\":1,\"n\":\"Normal Dampener\"},{\"t\":6,\"p\":1,\"n\":\"Single Pass Color\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Red\"},{\"t\":5,\"p\":1,\"n\":\"Green\"},{\"t\":5,\"p\":1,\"n\":\"Blue\"}]},{\"t\":3,\"p\":1,\"n\":\"Flags\"}]}]},{\"t\":1,\"p\":1,\"n\":\"MATT - Material Type\",\"f\":1,\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":3,\"p\":1,\"n\":\"PNAM - Material Parent\"},{\"t\":2,\"p\":1,\"n\":\"MNAM - Material Name\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"CNAM - Havok Display Color\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Red\"},{\"t\":5,\"p\":1,\"n\":\"Green\"},{\"t\":5,\"p\":1,\"n\":\"Blue\"}]},{\"t\":5,\"p\":1,\"n\":\"BNAM - Buoyancy\"},{\"t\":3,\"p\":1,\"n\":\"FNAM - Flags\"},{\"t\":3,\"p\":1,\"n\":\"HNAM - Havok Impact Data Set\"}]},{\"t\":1,\"p\":1,\"n\":\"MESG - Message\",\"f\":1,\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"p\":1,\"n\":\"DESC - Description\"},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":3,\"p\":1,\"n\":\"INAM - Icon (unused)\"},{\"t\":3,\"p\":1,\"n\":\"QNAM - Owner Quest\"},{\"t\":3,\"p\":1,\"n\":\"DNAM - Flags\"},{\"t\":3,\"p\":1,\"n\":\"TNAM - Display Time\"},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Menu Buttons\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Menu Button\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"ITXT - Button Text\"},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Conditions\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Condition\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"CTDA - \",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":5,\"p\":1,\"n\":\"Comparison Value - Float\"},{\"t\":3,\"p\":1,\"n\":\"Comparison Value - Global\"},{\"t\":3,\"p\":1,\"n\":\"Function\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":11,\"p\":1,\"n\":\"None\"},{\"t\":3,\"p\":1,\"n\":\"Integer\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":11,\"p\":1,\"n\":\"Variable Name (unused)\"},{\"t\":3,\"p\":1,\"n\":\"Sex\"},{\"t\":3,\"p\":1,\"n\":\"Actor Value\"},{\"t\":3,\"p\":1,\"n\":\"Crime Type\"},{\"t\":3,\"p\":1,\"n\":\"Axis\"},{\"t\":3,\"p\":1,\"n\":\"Quest Stage (unused)\"},{\"t\":3,\"p\":1,\"n\":\"Misc Stat\"},{\"t\":3,\"p\":1,\"n\":\"Alignment\"},{\"t\":3,\"p\":1,\"n\":\"Equip Type\"},{\"t\":3,\"p\":1,\"n\":\"Form Type\"},{\"t\":3,\"p\":1,\"n\":\"Critical Stage\"},{\"t\":3,\"p\":1,\"n\":\"Object Reference\"},{\"t\":3,\"p\":1,\"n\":\"Inventory Object\"},{\"t\":3,\"p\":1,\"n\":\"Actor\"},{\"t\":3,\"p\":1,\"n\":\"Voice Type\"},{\"t\":3,\"p\":1,\"n\":\"Idle\"},{\"t\":3,\"p\":1,\"n\":\"Form List\"},{\"t\":3,\"p\":1,\"n\":\"Quest\"},{\"t\":3,\"p\":1,\"n\":\"Faction\"},{\"t\":3,\"p\":1,\"n\":\"Cell\"},{\"t\":3,\"p\":1,\"n\":\"Class\"},{\"t\":3,\"p\":1,\"n\":\"Race\"},{\"t\":3,\"p\":1,\"n\":\"Actor Base\"},{\"t\":3,\"p\":1,\"n\":\"Global\"},{\"t\":3,\"p\":1,\"n\":\"Weather\"},{\"t\":3,\"p\":1,\"n\":\"Package\"},{\"t\":3,\"p\":1,\"n\":\"Encounter Zone\"},{\"t\":3,\"p\":1,\"n\":\"Perk\"},{\"t\":3,\"p\":1,\"n\":\"Owner\"},{\"t\":3,\"p\":1,\"n\":\"Furniture\"},{\"t\":3,\"p\":1,\"n\":\"Effect Item\"},{\"t\":3,\"p\":1,\"n\":\"Base Effect\"},{\"t\":3,\"p\":1,\"n\":\"Worldspace\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Function\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Param (INVALID)\"},{\"t\":3,\"p\":1,\"n\":\"Referenceable Object\"},{\"t\":3,\"p\":1,\"n\":\"Region\"},{\"t\":3,\"p\":1,\"n\":\"Keyword\"},{\"t\":3,\"p\":1,\"n\":\"Player Action\"},{\"t\":3,\"p\":1,\"n\":\"Casting Type\"},{\"t\":3,\"p\":1,\"n\":\"Shout\"},{\"t\":3,\"p\":1,\"n\":\"Location\"},{\"t\":3,\"p\":1,\"n\":\"Location Ref Type\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"Packdata ID\"},{\"t\":3,\"p\":1,\"n\":\"Association Type\"},{\"t\":3,\"p\":1,\"n\":\"Furniture Anim\"},{\"t\":3,\"p\":1,\"n\":\"Furniture Entry\"},{\"t\":3,\"p\":1,\"n\":\"Scene\"},{\"t\":3,\"p\":1,\"n\":\"Ward State\"},{\"t\":3,\"p\":1,\"n\":\"Event\"},{\"t\":3,\"p\":1,\"n\":\"Event Data\"},{\"t\":3,\"p\":1,\"n\":\"Quest Stage\"},{\"t\":3,\"p\":1,\"n\":\"Weapon\"},{\"t\":3,\"p\":1,\"n\":\"Weapon List\"},{\"t\":3,\"p\":1,\"n\":\"Target\"},{\"t\":3,\"p\":1,\"n\":\"Target List\"},{\"t\":3,\"p\":1,\"n\":\"Target Part\"},{\"t\":3,\"p\":1,\"n\":\"VATS Action\"},{\"t\":3,\"p\":1,\"n\":\"Critical Effect\"},{\"t\":3,\"p\":1,\"n\":\"Critical Effect List\"},{\"t\":3,\"p\":1,\"n\":\"Weapon Type\"},{\"t\":3,\"p\":1,\"n\":\"Projectile Type\"},{\"t\":3,\"p\":1,\"n\":\"Delivery Type\"},{\"t\":3,\"p\":1,\"n\":\"Run On\"},{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":3,\"p\":1,\"n\":\"Parameter #3\"}]},{\"t\":2,\"p\":1,\"n\":\"CIS1 - Parameter #1\"},{\"t\":2,\"p\":1,\"n\":\"CIS2 - Parameter #2\"}]}]}]}]}]},{\"t\":1,\"p\":1,\"n\":\"MGEF - Magic Effect\",\"f\":1,\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"VMAD - Virtual Machine Adapter\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Version\"},{\"t\":3,\"p\":1,\"n\":\"Object Format\"},{\"t\":7,\"p\":1,\"n\":\"Scripts\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Script\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"scriptName\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":7,\"p\":1,\"n\":\"Properties\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Property\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"propertyName\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]},{\"t\":2,\"p\":1,\"n\":\"String\"},{\"t\":3,\"p\":1,\"n\":\"Int32\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":3,\"p\":1,\"n\":\"Bool\"},{\"t\":7,\"p\":1,\"n\":\"Array of Object\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]}]},{\"t\":7,\"p\":1,\"n\":\"Array of String\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Int32\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Float\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Bool\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]}]}]}]}]}]},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":3,\"p\":1,\"n\":\"MDOB - Menu Display Object\"},{\"t\":3,\"n\":\"KSIZ - Keyword Count\"},{\"t\":7,\"p\":1,\"n\":\"KWDA - Keywords\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Keyword\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Magic Effect Data\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"DATA - Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":5,\"p\":1,\"n\":\"Base Cost\"},{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Assoc. Item\"},{\"t\":3,\"p\":1,\"n\":\"Magic Skill\"},{\"t\":3,\"p\":1,\"n\":\"Resist Value\"},{\"t\":3,\"p\":1,\"n\":\"Counter Effect count\"},{\"t\":3,\"p\":1,\"n\":\"Casting Light\"},{\"t\":5,\"p\":1,\"n\":\"Taper Weight\"},{\"t\":3,\"p\":1,\"n\":\"Hit Shader\"},{\"t\":3,\"p\":1,\"n\":\"Enchant Shader\"},{\"t\":3,\"p\":1,\"n\":\"Minimum Skill Level\"},{\"t\":6,\"p\":1,\"n\":\"Spellmaking\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Area\"},{\"t\":5,\"p\":1,\"n\":\"Casting Time\"}]},{\"t\":5,\"p\":1,\"n\":\"Taper Curve\"},{\"t\":5,\"p\":1,\"n\":\"Taper Duration\"},{\"t\":5,\"p\":1,\"n\":\"Second AV Weight\"},{\"t\":3,\"p\":1,\"n\":\"Archtype\"},{\"t\":3,\"p\":1,\"n\":\"Actor Value\"},{\"t\":3,\"p\":1,\"n\":\"Projectile\"},{\"t\":3,\"p\":1,\"n\":\"Explosion\"},{\"t\":3,\"p\":1,\"n\":\"Casting Type\"},{\"t\":3,\"p\":1,\"n\":\"Delivery\"},{\"t\":3,\"p\":1,\"n\":\"Second Actor Value\"},{\"t\":3,\"p\":1,\"n\":\"Casting Art\"},{\"t\":3,\"p\":1,\"n\":\"Hit Effect Art\"},{\"t\":3,\"p\":1,\"n\":\"Impact Data\"},{\"t\":5,\"p\":1,\"n\":\"Skill Usage Multiplier\"},{\"t\":6,\"p\":1,\"n\":\"Dual Casting\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Art\"},{\"t\":5,\"p\":1,\"n\":\"Scale\"}]},{\"t\":3,\"p\":1,\"n\":\"Enchant Art\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":3,\"p\":1,\"n\":\"Equip Ability\"},{\"t\":3,\"p\":1,\"n\":\"Image Space Modifier\"},{\"t\":3,\"p\":1,\"n\":\"Perk to Apply\"},{\"t\":3,\"p\":1,\"n\":\"Casting Sound Level\"},{\"t\":6,\"p\":1,\"n\":\"Script Effect AI\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Score\"},{\"t\":5,\"p\":1,\"n\":\"Delay Time\"}]}]}]},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Counter Effects\",\"d\":1,\"c\":[{\"t\":3,\"n\":\"ESCE - Effect\"}]},{\"t\":7,\"p\":1,\"n\":\"SNDD - Sounds\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Sound\"}]}]},{\"t\":2,\"p\":1,\"n\":\"DNAM - Magic Item Description\"},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Conditions\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Condition\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"CTDA - \",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":5,\"p\":1,\"n\":\"Comparison Value - Float\"},{\"t\":3,\"p\":1,\"n\":\"Comparison Value - Global\"},{\"t\":3,\"p\":1,\"n\":\"Function\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":11,\"p\":1,\"n\":\"None\"},{\"t\":3,\"p\":1,\"n\":\"Integer\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":11,\"p\":1,\"n\":\"Variable Name (unused)\"},{\"t\":3,\"p\":1,\"n\":\"Sex\"},{\"t\":3,\"p\":1,\"n\":\"Actor Value\"},{\"t\":3,\"p\":1,\"n\":\"Crime Type\"},{\"t\":3,\"p\":1,\"n\":\"Axis\"},{\"t\":3,\"p\":1,\"n\":\"Quest Stage (unused)\"},{\"t\":3,\"p\":1,\"n\":\"Misc Stat\"},{\"t\":3,\"p\":1,\"n\":\"Alignment\"},{\"t\":3,\"p\":1,\"n\":\"Equip Type\"},{\"t\":3,\"p\":1,\"n\":\"Form Type\"},{\"t\":3,\"p\":1,\"n\":\"Critical Stage\"},{\"t\":3,\"p\":1,\"n\":\"Object Reference\"},{\"t\":3,\"p\":1,\"n\":\"Inventory Object\"},{\"t\":3,\"p\":1,\"n\":\"Actor\"},{\"t\":3,\"p\":1,\"n\":\"Voice Type\"},{\"t\":3,\"p\":1,\"n\":\"Idle\"},{\"t\":3,\"p\":1,\"n\":\"Form List\"},{\"t\":3,\"p\":1,\"n\":\"Quest\"},{\"t\":3,\"p\":1,\"n\":\"Faction\"},{\"t\":3,\"p\":1,\"n\":\"Cell\"},{\"t\":3,\"p\":1,\"n\":\"Class\"},{\"t\":3,\"p\":1,\"n\":\"Race\"},{\"t\":3,\"p\":1,\"n\":\"Actor Base\"},{\"t\":3,\"p\":1,\"n\":\"Global\"},{\"t\":3,\"p\":1,\"n\":\"Weather\"},{\"t\":3,\"p\":1,\"n\":\"Package\"},{\"t\":3,\"p\":1,\"n\":\"Encounter Zone\"},{\"t\":3,\"p\":1,\"n\":\"Perk\"},{\"t\":3,\"p\":1,\"n\":\"Owner\"},{\"t\":3,\"p\":1,\"n\":\"Furniture\"},{\"t\":3,\"p\":1,\"n\":\"Effect Item\"},{\"t\":3,\"p\":1,\"n\":\"Base Effect\"},{\"t\":3,\"p\":1,\"n\":\"Worldspace\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Function\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Param (INVALID)\"},{\"t\":3,\"p\":1,\"n\":\"Referenceable Object\"},{\"t\":3,\"p\":1,\"n\":\"Region\"},{\"t\":3,\"p\":1,\"n\":\"Keyword\"},{\"t\":3,\"p\":1,\"n\":\"Player Action\"},{\"t\":3,\"p\":1,\"n\":\"Casting Type\"},{\"t\":3,\"p\":1,\"n\":\"Shout\"},{\"t\":3,\"p\":1,\"n\":\"Location\"},{\"t\":3,\"p\":1,\"n\":\"Location Ref Type\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"Packdata ID\"},{\"t\":3,\"p\":1,\"n\":\"Association Type\"},{\"t\":3,\"p\":1,\"n\":\"Furniture Anim\"},{\"t\":3,\"p\":1,\"n\":\"Furniture Entry\"},{\"t\":3,\"p\":1,\"n\":\"Scene\"},{\"t\":3,\"p\":1,\"n\":\"Ward State\"},{\"t\":3,\"p\":1,\"n\":\"Event\"},{\"t\":3,\"p\":1,\"n\":\"Event Data\"},{\"t\":3,\"p\":1,\"n\":\"Quest Stage\"},{\"t\":3,\"p\":1,\"n\":\"Weapon\"},{\"t\":3,\"p\":1,\"n\":\"Weapon List\"},{\"t\":3,\"p\":1,\"n\":\"Target\"},{\"t\":3,\"p\":1,\"n\":\"Target List\"},{\"t\":3,\"p\":1,\"n\":\"Target Part\"},{\"t\":3,\"p\":1,\"n\":\"VATS Action\"},{\"t\":3,\"p\":1,\"n\":\"Critical Effect\"},{\"t\":3,\"p\":1,\"n\":\"Critical Effect List\"},{\"t\":3,\"p\":1,\"n\":\"Weapon Type\"},{\"t\":3,\"p\":1,\"n\":\"Projectile Type\"},{\"t\":3,\"p\":1,\"n\":\"Delivery Type\"},{\"t\":3,\"p\":1,\"n\":\"Run On\"},{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":3,\"p\":1,\"n\":\"Parameter #3\"}]},{\"t\":2,\"p\":1,\"n\":\"CIS1 - Parameter #1\"},{\"t\":2,\"p\":1,\"n\":\"CIS2 - Parameter #2\"}]}]}]},{\"t\":1,\"p\":1,\"n\":\"MISC - Misc. Item\",\"f\":1,\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"VMAD - Virtual Machine Adapter\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Version\"},{\"t\":3,\"p\":1,\"n\":\"Object Format\"},{\"t\":7,\"p\":1,\"n\":\"Scripts\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Script\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"scriptName\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":7,\"p\":1,\"n\":\"Properties\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Property\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"propertyName\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]},{\"t\":2,\"p\":1,\"n\":\"String\"},{\"t\":3,\"p\":1,\"n\":\"Int32\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":3,\"p\":1,\"n\":\"Bool\"},{\"t\":7,\"p\":1,\"n\":\"Array of Object\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]}]},{\"t\":7,\"p\":1,\"n\":\"Array of String\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Int32\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Float\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Bool\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]}]}]}]}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"X1\"},{\"t\":3,\"p\":1,\"n\":\"Y1\"},{\"t\":3,\"p\":1,\"n\":\"Z1\"},{\"t\":3,\"p\":1,\"n\":\"X2\"},{\"t\":3,\"p\":1,\"n\":\"Y2\"},{\"t\":3,\"p\":1,\"n\":\"Z2\"}]},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"MODT - Texture Files Hashes\"},{\"t\":7,\"p\":1,\"n\":\"MODS - Alternate Textures\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"3D Name\"},{\"t\":3,\"p\":1,\"n\":\"New Texture\"},{\"t\":3,\"p\":1,\"n\":\"3D Index\"}]}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Icon\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"ICON - Large Icon filename\"},{\"t\":2,\"p\":1,\"n\":\"MICO - Small Icon filename\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Destructable\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"DEST - Header\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Health\"},{\"t\":3,\"p\":1,\"n\":\"DEST Count\"},{\"t\":3,\"p\":1,\"n\":\"VATS Targetable\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":8,\"p\":1,\"n\":\"Stages\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Stage\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"DSTD - Destruction Stage Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Health %\"},{\"t\":3,\"p\":1,\"n\":\"Index\"},{\"t\":3,\"p\":1,\"n\":\"Model Damage Stage\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":3,\"p\":1,\"n\":\"Self Damage per Second\"},{\"t\":3,\"p\":1,\"n\":\"Explosion\"},{\"t\":3,\"p\":1,\"n\":\"Debris\"},{\"t\":3,\"p\":1,\"n\":\"Debris Count\"}]},{\"t\":6,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"DMDL - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"DMDT - Texture Files Hashes\"},{\"t\":7,\"p\":1,\"n\":\"DMDS - Alternate Textures\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"3D Name\"},{\"t\":3,\"p\":1,\"n\":\"New Texture\"},{\"t\":3,\"p\":1,\"n\":\"3D Index\"}]}]}]},{\"p\":1,\"n\":\"DSTF - End Marker\"}]}]}]},{\"t\":3,\"p\":1,\"n\":\"YNAM - Sound - Pick Up\"},{\"t\":3,\"p\":1,\"n\":\"ZNAM - Sound - Put Down\"},{\"t\":3,\"n\":\"KSIZ - Keyword Count\"},{\"t\":7,\"p\":1,\"n\":\"KWDA - Keywords\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Keyword\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DATA - Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Value\"},{\"t\":5,\"p\":1,\"n\":\"Weight\"}]}]},{\"t\":1,\"p\":1,\"n\":\"MOVT - Movement Type\",\"f\":1,\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"p\":1,\"n\":\"MNAM - Name\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"SPED - Default Data\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Left Walk\"},{\"t\":5,\"p\":1,\"n\":\"Left Run\"},{\"t\":5,\"p\":1,\"n\":\"Right Walk\"},{\"t\":5,\"p\":1,\"n\":\"Right Run\"},{\"t\":5,\"p\":1,\"n\":\"Forward Walk\"},{\"t\":5,\"p\":1,\"n\":\"Forward Run\"},{\"t\":5,\"p\":1,\"n\":\"Back Walk\"},{\"t\":5,\"p\":1,\"n\":\"Back Run\"},{\"t\":5,\"p\":1,\"n\":\"Rotate in Place Walk\"},{\"t\":5,\"p\":1,\"n\":\"Rotate in Place Run\"},{\"t\":5,\"p\":1,\"n\":\"Rotate while Moving Run\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"INAM - Anim Change Thresholds\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Directional\"},{\"t\":5,\"p\":1,\"n\":\"Movement Speed\"},{\"t\":5,\"p\":1,\"n\":\"Rotation Speed\"}]}]},{\"t\":1,\"p\":1,\"n\":\"MSTT - Moveable Static\",\"f\":1,\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"X1\"},{\"t\":3,\"p\":1,\"n\":\"Y1\"},{\"t\":3,\"p\":1,\"n\":\"Z1\"},{\"t\":3,\"p\":1,\"n\":\"X2\"},{\"t\":3,\"p\":1,\"n\":\"Y2\"},{\"t\":3,\"p\":1,\"n\":\"Z2\"}]},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"MODT - Texture Files Hashes\"},{\"t\":7,\"p\":1,\"n\":\"MODS - Alternate Textures\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"3D Name\"},{\"t\":3,\"p\":1,\"n\":\"New Texture\"},{\"t\":3,\"p\":1,\"n\":\"3D Index\"}]}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Destructable\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"DEST - Header\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Health\"},{\"t\":3,\"p\":1,\"n\":\"DEST Count\"},{\"t\":3,\"p\":1,\"n\":\"VATS Targetable\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":8,\"p\":1,\"n\":\"Stages\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Stage\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"DSTD - Destruction Stage Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Health %\"},{\"t\":3,\"p\":1,\"n\":\"Index\"},{\"t\":3,\"p\":1,\"n\":\"Model Damage Stage\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":3,\"p\":1,\"n\":\"Self Damage per Second\"},{\"t\":3,\"p\":1,\"n\":\"Explosion\"},{\"t\":3,\"p\":1,\"n\":\"Debris\"},{\"t\":3,\"p\":1,\"n\":\"Debris Count\"}]},{\"t\":6,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"DMDL - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"DMDT - Texture Files Hashes\"},{\"t\":7,\"p\":1,\"n\":\"DMDS - Alternate Textures\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"3D Name\"},{\"t\":3,\"p\":1,\"n\":\"New Texture\"},{\"t\":3,\"p\":1,\"n\":\"3D Index\"}]}]}]},{\"p\":1,\"n\":\"DSTF - End Marker\"}]}]}]},{\"t\":3,\"p\":1,\"n\":\"DATA - Flags\"},{\"t\":3,\"p\":1,\"n\":\"SNAM - Looping Sound\"}]},{\"t\":1,\"p\":1,\"n\":\"MUSC - Music Type\",\"f\":1,\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":3,\"p\":1,\"n\":\"FNAM - Flags\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"PNAM - Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Priority\"},{\"t\":3,\"p\":1,\"n\":\"Ducking (dB)\"}]},{\"t\":5,\"p\":1,\"n\":\"WNAM - Fade Duration\"},{\"t\":7,\"p\":1,\"n\":\"TNAM - Music Tracks\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Track\"}]}]},{\"t\":1,\"p\":1,\"n\":\"MUST - Music Track\",\"f\":1,\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":3,\"p\":1,\"n\":\"CNAM - Track Type\"},{\"t\":5,\"p\":1,\"n\":\"FLTV - Duration\"},{\"t\":5,\"p\":1,\"n\":\"DNAM - Fade-Out\"},{\"t\":2,\"p\":1,\"n\":\"ANAM - Track Filename\"},{\"t\":2,\"p\":1,\"n\":\"BNAM - Finale Filename\"},{\"t\":7,\"p\":1,\"n\":\"FNAM - Cue Points\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Point\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"LNAM - Loop Data\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Loop Begins\"},{\"t\":5,\"p\":1,\"n\":\"Loop Ends\"},{\"t\":3,\"p\":1,\"n\":\"Loop Count\"}]},{\"t\":3,\"n\":\"CITC - Condition Count\"},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Conditions\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Condition\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"CTDA - \",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":5,\"p\":1,\"n\":\"Comparison Value - Float\"},{\"t\":3,\"p\":1,\"n\":\"Comparison Value - Global\"},{\"t\":3,\"p\":1,\"n\":\"Function\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":11,\"p\":1,\"n\":\"None\"},{\"t\":3,\"p\":1,\"n\":\"Integer\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":11,\"p\":1,\"n\":\"Variable Name (unused)\"},{\"t\":3,\"p\":1,\"n\":\"Sex\"},{\"t\":3,\"p\":1,\"n\":\"Actor Value\"},{\"t\":3,\"p\":1,\"n\":\"Crime Type\"},{\"t\":3,\"p\":1,\"n\":\"Axis\"},{\"t\":3,\"p\":1,\"n\":\"Quest Stage (unused)\"},{\"t\":3,\"p\":1,\"n\":\"Misc Stat\"},{\"t\":3,\"p\":1,\"n\":\"Alignment\"},{\"t\":3,\"p\":1,\"n\":\"Equip Type\"},{\"t\":3,\"p\":1,\"n\":\"Form Type\"},{\"t\":3,\"p\":1,\"n\":\"Critical Stage\"},{\"t\":3,\"p\":1,\"n\":\"Object Reference\"},{\"t\":3,\"p\":1,\"n\":\"Inventory Object\"},{\"t\":3,\"p\":1,\"n\":\"Actor\"},{\"t\":3,\"p\":1,\"n\":\"Voice Type\"},{\"t\":3,\"p\":1,\"n\":\"Idle\"},{\"t\":3,\"p\":1,\"n\":\"Form List\"},{\"t\":3,\"p\":1,\"n\":\"Quest\"},{\"t\":3,\"p\":1,\"n\":\"Faction\"},{\"t\":3,\"p\":1,\"n\":\"Cell\"},{\"t\":3,\"p\":1,\"n\":\"Class\"},{\"t\":3,\"p\":1,\"n\":\"Race\"},{\"t\":3,\"p\":1,\"n\":\"Actor Base\"},{\"t\":3,\"p\":1,\"n\":\"Global\"},{\"t\":3,\"p\":1,\"n\":\"Weather\"},{\"t\":3,\"p\":1,\"n\":\"Package\"},{\"t\":3,\"p\":1,\"n\":\"Encounter Zone\"},{\"t\":3,\"p\":1,\"n\":\"Perk\"},{\"t\":3,\"p\":1,\"n\":\"Owner\"},{\"t\":3,\"p\":1,\"n\":\"Furniture\"},{\"t\":3,\"p\":1,\"n\":\"Effect Item\"},{\"t\":3,\"p\":1,\"n\":\"Base Effect\"},{\"t\":3,\"p\":1,\"n\":\"Worldspace\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Function\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Param (INVALID)\"},{\"t\":3,\"p\":1,\"n\":\"Referenceable Object\"},{\"t\":3,\"p\":1,\"n\":\"Region\"},{\"t\":3,\"p\":1,\"n\":\"Keyword\"},{\"t\":3,\"p\":1,\"n\":\"Player Action\"},{\"t\":3,\"p\":1,\"n\":\"Casting Type\"},{\"t\":3,\"p\":1,\"n\":\"Shout\"},{\"t\":3,\"p\":1,\"n\":\"Location\"},{\"t\":3,\"p\":1,\"n\":\"Location Ref Type\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"Packdata ID\"},{\"t\":3,\"p\":1,\"n\":\"Association Type\"},{\"t\":3,\"p\":1,\"n\":\"Furniture Anim\"},{\"t\":3,\"p\":1,\"n\":\"Furniture Entry\"},{\"t\":3,\"p\":1,\"n\":\"Scene\"},{\"t\":3,\"p\":1,\"n\":\"Ward State\"},{\"t\":3,\"p\":1,\"n\":\"Event\"},{\"t\":3,\"p\":1,\"n\":\"Event Data\"},{\"t\":3,\"p\":1,\"n\":\"Quest Stage\"},{\"t\":3,\"p\":1,\"n\":\"Weapon\"},{\"t\":3,\"p\":1,\"n\":\"Weapon List\"},{\"t\":3,\"p\":1,\"n\":\"Target\"},{\"t\":3,\"p\":1,\"n\":\"Target List\"},{\"t\":3,\"p\":1,\"n\":\"Target Part\"},{\"t\":3,\"p\":1,\"n\":\"VATS Action\"},{\"t\":3,\"p\":1,\"n\":\"Critical Effect\"},{\"t\":3,\"p\":1,\"n\":\"Critical Effect List\"},{\"t\":3,\"p\":1,\"n\":\"Weapon Type\"},{\"t\":3,\"p\":1,\"n\":\"Projectile Type\"},{\"t\":3,\"p\":1,\"n\":\"Delivery Type\"},{\"t\":3,\"p\":1,\"n\":\"Run On\"},{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":3,\"p\":1,\"n\":\"Parameter #3\"}]},{\"t\":2,\"p\":1,\"n\":\"CIS1 - Parameter #1\"},{\"t\":2,\"p\":1,\"n\":\"CIS2 - Parameter #2\"}]}]},{\"t\":7,\"p\":1,\"n\":\"SNAM - Tracks\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Track\"}]}]},{\"t\":1,\"n\":\"NAVI - Navigation Mesh Info Map\",\"c\":[{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":3,\"n\":\"NVER - Version\"},{\"t\":8,\"n\":\"Navigation Map Infos\",\"c\":[{\"t\":6,\"n\":\"NVMI - Navigation Map Info\",\"c\":[{\"t\":3,\"n\":\"Navigation Mesh\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":5,\"n\":\"X\"},{\"t\":5,\"n\":\"Y\"},{\"t\":5,\"n\":\"Z\"},{\"t\":3,\"n\":\"Preferred Merges Flag\"},{\"t\":7,\"n\":\"Merged To\",\"c\":[{\"t\":3,\"n\":\"Mesh\"}]},{\"t\":7,\"n\":\"Preferred Merges\",\"c\":[{\"t\":3,\"n\":\"Mesh\"}]},{\"t\":7,\"n\":\"Linked Doors\",\"c\":[{\"t\":6,\"n\":\"Door\",\"c\":[{\"t\":11,\"n\":\"Unknown\"},{\"t\":3,\"n\":\"Door Ref\"}]}]},{\"t\":3,\"n\":\"Is Island\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":6,\"n\":\"Island Data\",\"c\":[{\"t\":11,\"n\":\"Unknown\"},{\"t\":7,\"n\":\"Triangles\",\"c\":[{\"t\":11,\"n\":\"Triangle\"}]},{\"t\":7,\"n\":\"Vertices\",\"c\":[{\"t\":11,\"n\":\"Vertex\"}]}]},{\"t\":3,\"n\":\"Parent Worldspace\"},{\"t\":6,\"n\":\"Coordinates\",\"c\":[{\"t\":3,\"n\":\"Grid Y\"},{\"t\":3,\"n\":\"Grid X\"}]},{\"t\":3,\"n\":\"Parent Cell\"}]}]},{\"t\":6,\"n\":\"NVPP - Preferred Pathing\",\"c\":[{\"t\":7,\"n\":\"NavMeshes\",\"c\":[{\"t\":7,\"n\":\"Set\",\"c\":[{\"t\":3,\"n\":\"\"}]}]},{\"t\":7,\"n\":\"NavMesh Tree?\",\"c\":[{\"t\":6,\"n\":\"\",\"c\":[{\"t\":3,\"n\":\"NavMesh\"},{\"t\":3,\"n\":\"Index\\/Node\"}]}]}]},{\"t\":7,\"n\":\"NVSI - Unknown\",\"c\":[{\"t\":3,\"n\":\"Navigation Mesh\"}]}]},{\"t\":1,\"n\":\"NAVM - Navigation Mesh\",\"c\":[{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"n\":\"NVNM - Geometry\",\"c\":[{\"t\":11,\"n\":\"Unknown\"},{\"t\":3,\"n\":\"Parent Worldspace\"},{\"t\":6,\"n\":\"Coordinates\",\"c\":[{\"t\":3,\"n\":\"Grid Y\"},{\"t\":3,\"n\":\"Grid X\"}]},{\"t\":3,\"n\":\"Parent Cell\"},{\"t\":7,\"n\":\"Vertices\",\"c\":[{\"t\":11,\"n\":\"Vertex\"}]},{\"t\":7,\"n\":\"Triangles\",\"c\":[{\"t\":11,\"n\":\"Triangle\"}]},{\"t\":7,\"n\":\"External Connections\",\"c\":[{\"t\":6,\"n\":\"Connection\",\"c\":[{\"t\":11,\"n\":\"Unknown\"},{\"t\":3,\"n\":\"Mesh\"},{\"t\":3,\"n\":\"Triangle\"}]}]},{\"t\":7,\"n\":\"Door Triangles\",\"c\":[{\"t\":6,\"n\":\"Door Triangle\",\"c\":[{\"t\":3,\"n\":\"Triangle before door\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":3,\"n\":\"Door\"}]}]}]},{\"t\":11,\"n\":\"ONAM - Unknown\"},{\"t\":11,\"n\":\"PNAM - Unknown\"},{\"t\":11,\"n\":\"NNAM - Unknown\"}]},{\"t\":1,\"p\":1,\"n\":\"NPC_ - Non-Player Character (Actor)\",\"f\":1,\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"VMAD - Virtual Machine Adapter\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Version\"},{\"t\":3,\"p\":1,\"n\":\"Object Format\"},{\"t\":7,\"p\":1,\"n\":\"Scripts\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Script\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"scriptName\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":7,\"p\":1,\"n\":\"Properties\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Property\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"propertyName\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]},{\"t\":2,\"p\":1,\"n\":\"String\"},{\"t\":3,\"p\":1,\"n\":\"Int32\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":3,\"p\":1,\"n\":\"Bool\"},{\"t\":7,\"p\":1,\"n\":\"Array of Object\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]}]},{\"t\":7,\"p\":1,\"n\":\"Array of String\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Int32\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Float\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Bool\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]}]}]}]}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"X1\"},{\"t\":3,\"p\":1,\"n\":\"Y1\"},{\"t\":3,\"p\":1,\"n\":\"Z1\"},{\"t\":3,\"p\":1,\"n\":\"X2\"},{\"t\":3,\"p\":1,\"n\":\"Y2\"},{\"t\":3,\"p\":1,\"n\":\"Z2\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"ACBS - Configuration\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":3,\"p\":1,\"n\":\"Magicka Offset\"},{\"t\":3,\"p\":1,\"n\":\"Stamina Offset\"},{\"t\":3,\"p\":1,\"n\":\"Level\"},{\"t\":3,\"p\":1,\"n\":\"Level Mult\"},{\"t\":3,\"p\":1,\"n\":\"Calc min level\"},{\"t\":3,\"p\":1,\"n\":\"Calc max level\"},{\"t\":3,\"p\":1,\"n\":\"Speed Multiplier\"},{\"t\":3,\"p\":1,\"n\":\"Disposition Base (unused)\"},{\"t\":3,\"p\":1,\"n\":\"Template Flags\"},{\"t\":3,\"p\":1,\"n\":\"Health Offset\"},{\"t\":3,\"p\":1,\"n\":\"Bleedout Override\"}]},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Factions\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"SNAM - Faction\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Faction\"},{\"t\":3,\"p\":1,\"n\":\"Rank\"},{\"t\":11,\"n\":\"Unused\"}]}]},{\"t\":3,\"p\":1,\"n\":\"INAM - Death item\"},{\"t\":3,\"p\":1,\"n\":\"VTCK - Voice\"},{\"t\":3,\"p\":1,\"n\":\"TPLT - Template\"},{\"t\":3,\"p\":1,\"n\":\"RNAM - Race\",\"lt\":\"Head Parts\",\"lf\":\"Tint Layers\"},{\"t\":3,\"n\":\"SPCT - Count\"},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Actor Effects\",\"d\":1,\"c\":[{\"t\":3,\"p\":1,\"n\":\"SPLO - Actor Effect\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Destructable\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"DEST - Header\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Health\"},{\"t\":3,\"p\":1,\"n\":\"DEST Count\"},{\"t\":3,\"p\":1,\"n\":\"VATS Targetable\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":8,\"p\":1,\"n\":\"Stages\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Stage\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"DSTD - Destruction Stage Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Health %\"},{\"t\":3,\"p\":1,\"n\":\"Index\"},{\"t\":3,\"p\":1,\"n\":\"Model Damage Stage\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":3,\"p\":1,\"n\":\"Self Damage per Second\"},{\"t\":3,\"p\":1,\"n\":\"Explosion\"},{\"t\":3,\"p\":1,\"n\":\"Debris\"},{\"t\":3,\"p\":1,\"n\":\"Debris Count\"}]},{\"t\":6,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"DMDL - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"DMDT - Texture Files Hashes\"},{\"t\":7,\"p\":1,\"n\":\"DMDS - Alternate Textures\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"3D Name\"},{\"t\":3,\"p\":1,\"n\":\"New Texture\"},{\"t\":3,\"p\":1,\"n\":\"3D Index\"}]}]}]},{\"p\":1,\"n\":\"DSTF - End Marker\"}]}]}]},{\"t\":3,\"p\":1,\"n\":\"WNAM - Worn Armor\"},{\"t\":3,\"p\":1,\"n\":\"ANAM - Far away model\"},{\"t\":3,\"p\":1,\"n\":\"ATKR - Attack Race\"},{\"t\":10,\"p\":1,\"n\":\"Attacks\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Attack\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"ATKD - Attack Data\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Damage Mult\"},{\"t\":5,\"p\":1,\"n\":\"Attack Chance\"},{\"t\":3,\"p\":1,\"n\":\"Attack Spell\"},{\"t\":3,\"p\":1,\"n\":\"Attack Flags\"},{\"t\":5,\"p\":1,\"n\":\"Attack Angle\"},{\"t\":5,\"p\":1,\"n\":\"Strike Angle\"},{\"t\":5,\"p\":1,\"n\":\"Stagger\"},{\"t\":3,\"p\":1,\"n\":\"Attack Type\"},{\"t\":5,\"p\":1,\"n\":\"Knockdown\"},{\"t\":5,\"p\":1,\"n\":\"Recovery Time\"},{\"t\":5,\"p\":1,\"n\":\"Stamina Mult\"}]},{\"t\":2,\"p\":1,\"n\":\"ATKE - Attack Event\"}]}]},{\"t\":3,\"p\":1,\"n\":\"SPOR - Spectator override package list\"},{\"t\":3,\"p\":1,\"n\":\"OCOR - Observe dead body override package list\"},{\"t\":3,\"p\":1,\"n\":\"GWOR - Guard warn override package list\"},{\"t\":3,\"p\":1,\"n\":\"ECOR - Combat override package list\"},{\"t\":3,\"n\":\"PRKZ - Perk Count\"},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Perks\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"PRKR - Perk\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Perk\"},{\"t\":3,\"p\":1,\"n\":\"Rank\"},{\"t\":11,\"n\":\"Unused\"}]}]},{\"t\":3,\"n\":\"COCT - Count\"},{\"t\":10,\"p\":1,\"n\":\"Items\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Item\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"CNTO - Item\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Item\"},{\"t\":3,\"p\":1,\"n\":\"Count\"}]},{\"t\":6,\"p\":1,\"n\":\"COED - Extra Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Owner\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Global Variable\"},{\"t\":3,\"p\":1,\"n\":\"Required Rank\"},{\"t\":5,\"p\":1,\"n\":\"Item Condition\"}]}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"AIDT - AI Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Aggression\"},{\"t\":3,\"p\":1,\"n\":\"Confidence\"},{\"t\":3,\"p\":1,\"n\":\"Energy Level\"},{\"t\":3,\"p\":1,\"n\":\"Responsibility\"},{\"t\":3,\"p\":1,\"n\":\"Mood\"},{\"t\":3,\"p\":1,\"n\":\"Assistance\"},{\"t\":6,\"p\":1,\"n\":\"Aggro\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Aggro Radius Behavior\"},{\"t\":3,\"n\":\"Unknown\"},{\"t\":3,\"p\":1,\"n\":\"Warn\"},{\"t\":3,\"p\":1,\"n\":\"Warn\\/Attack\"},{\"t\":3,\"p\":1,\"n\":\"Attack\"}]}]},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Packages\",\"d\":1,\"c\":[{\"t\":3,\"p\":1,\"n\":\"PKID - Package\"}]},{\"t\":3,\"n\":\"KSIZ - Keyword Count\"},{\"t\":7,\"p\":1,\"n\":\"KWDA - Keywords\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Keyword\"}]},{\"t\":3,\"p\":1,\"n\":\"CNAM - Class\"},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":2,\"p\":1,\"n\":\"SHRT - Short Name\"},{\"t\":11,\"n\":\"DATA - Marker\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DNAM - Player Skills\",\"c\":[{\"t\":7,\"p\":1,\"n\":\"Skill Values\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Skill\"}]},{\"t\":7,\"p\":1,\"n\":\"Skill Offsets\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Skill\"}]},{\"t\":3,\"p\":1,\"n\":\"Health\"},{\"t\":3,\"p\":1,\"n\":\"Magicka\"},{\"t\":3,\"p\":1,\"n\":\"Stamina\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":5,\"p\":1,\"n\":\"Far away model distance\"},{\"t\":3,\"p\":1,\"n\":\"Geared up weapons\"}]},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Head Parts\",\"d\":1,\"c\":[{\"t\":3,\"p\":1,\"n\":\"PNAM - Head Part\"}],\"lt\":\"HCLF - Hair Color\",\"lf\":\"RNAM - Race\"},{\"t\":3,\"p\":1,\"n\":\"HCLF - Hair Color\",\"lt\":\"NAM6 - Height\",\"lf\":\"Head Parts\"},{\"t\":3,\"p\":1,\"n\":\"ZNAM - Combat Style\"},{\"t\":3,\"p\":1,\"n\":\"GNAM - Gift Filter\"},{\"t\":11,\"n\":\"NAM5 - Unknown\"},{\"t\":5,\"p\":1,\"n\":\"NAM6 - Height\",\"lt\":\"NAM7 - Weight\",\"lf\":\"HCLF - Hair Color\"},{\"t\":5,\"p\":1,\"n\":\"NAM7 - Weight\",\"lt\":\"FTST - Head texture\",\"lf\":\"NAM6 - Height\"},{\"t\":3,\"p\":1,\"n\":\"NAM8 - Sound Level\"},{\"t\":10,\"p\":1,\"n\":\"Sound Types\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Sound Type\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"CSDT - Type\"},{\"t\":10,\"p\":1,\"n\":\"Sounds\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Sound\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"CSDI - Sound\"},{\"t\":3,\"p\":1,\"n\":\"CSDC - Sound Chance\"}]}]}]}]},{\"t\":3,\"p\":1,\"n\":\"CSCR - Inherits Sounds From\"},{\"t\":3,\"p\":1,\"n\":\"DOFT - Default outfit\"},{\"t\":3,\"p\":1,\"n\":\"SOFT - Sleeping outfit\"},{\"t\":3,\"p\":1,\"n\":\"DPLT - Default Package List\"},{\"t\":3,\"p\":1,\"n\":\"CRIF - Crime faction\"},{\"t\":3,\"p\":1,\"n\":\"FTST - Head texture\",\"lt\":\"QNAM - Texture lighting\",\"lf\":\"NAM7 - Weight\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"QNAM - Texture lighting\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Red\"},{\"t\":5,\"p\":1,\"n\":\"Green\"},{\"t\":5,\"p\":1,\"n\":\"Blue\"}],\"lt\":\"NAM9 - Face morph\",\"lf\":\"FTST - Head texture\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"NAM9 - Face morph\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Nose Long\\/Short\"},{\"t\":5,\"p\":1,\"n\":\"Nose Up\\/Down\"},{\"t\":5,\"p\":1,\"n\":\"Jaw Up\\/Down\"},{\"t\":5,\"p\":1,\"n\":\"Jaw Narrow\\/Wide\"},{\"t\":5,\"p\":1,\"n\":\"Jaw Farward\\/Back\"},{\"t\":5,\"p\":1,\"n\":\"Cheeks Up\\/Down\"},{\"t\":5,\"p\":1,\"n\":\"Cheeks Farward\\/Back\"},{\"t\":5,\"p\":1,\"n\":\"Eyes Up\\/Down\"},{\"t\":5,\"p\":1,\"n\":\"Eyes In\\/Out\"},{\"t\":5,\"p\":1,\"n\":\"Brows Up\\/Down\"},{\"t\":5,\"p\":1,\"n\":\"Brows In\\/Out\"},{\"t\":5,\"p\":1,\"n\":\"Brows Farward\\/Back\"},{\"t\":5,\"p\":1,\"n\":\"Lips Up\\/Down\"},{\"t\":5,\"p\":1,\"n\":\"Lips In\\/Out\"},{\"t\":5,\"p\":1,\"n\":\"Chin Narrow\\/Wide\"},{\"t\":5,\"p\":1,\"n\":\"Chin Up\\/Down\"},{\"t\":5,\"p\":1,\"n\":\"Chin Underbite\\/Overbite\"},{\"t\":5,\"p\":1,\"n\":\"Eyes Farward\\/Back\"},{\"t\":5,\"n\":\"Unknown\"}],\"lt\":\"NAMA - Face parts\",\"lf\":\"QNAM - Texture lighting\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"NAMA - Face parts\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Nose\"},{\"t\":3,\"n\":\"Unknown\"},{\"t\":3,\"p\":1,\"n\":\"Eyes\"},{\"t\":3,\"p\":1,\"n\":\"Mouth\"}],\"lt\":\"Tint Layers\",\"lf\":\"NAM9 - Face morph\"},{\"t\":10,\"p\":1,\"n\":\"Tint Layers\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Layer\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"TINI - Tint Index\"},{\"t\":6,\"p\":1,\"n\":\"TINC - Tint Color\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":3,\"p\":1,\"n\":\"Alpha\"}]},{\"t\":3,\"p\":1,\"n\":\"TINV - Interpolation Value\"},{\"t\":3,\"p\":1,\"n\":\"TIAS - Preset\"}]}],\"lt\":\"RNAM - Race\",\"lf\":\"NAMA - Face parts\"}]},{\"t\":1,\"p\":1,\"n\":\"OTFT - Outfit\",\"f\":1,\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":7,\"s\":1,\"p\":1,\"n\":\"INAM - Items\",\"d\":1,\"c\":[{\"t\":3,\"p\":1,\"n\":\"Item\"}]}]},{\"t\":1,\"p\":1,\"n\":\"PACK - Package\",\"f\":1,\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"VMAD - Virtual Machine Adapter\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Version\"},{\"t\":3,\"p\":1,\"n\":\"Object Format\"},{\"t\":7,\"p\":1,\"n\":\"Scripts\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Script\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"scriptName\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":7,\"p\":1,\"n\":\"Properties\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Property\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"propertyName\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]},{\"t\":2,\"p\":1,\"n\":\"String\"},{\"t\":3,\"p\":1,\"n\":\"Int32\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":3,\"p\":1,\"n\":\"Bool\"},{\"t\":7,\"p\":1,\"n\":\"Array of Object\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]}]},{\"t\":7,\"p\":1,\"n\":\"Array of String\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Int32\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Float\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Bool\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]}]}]}]}]},{\"t\":6,\"p\":1,\"n\":\"Script Fragments\",\"c\":[{\"t\":3,\"n\":\"Unknown\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":2,\"p\":1,\"n\":\"fileName\"},{\"t\":7,\"p\":1,\"n\":\"Fragments\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Fragment\",\"c\":[{\"t\":3,\"n\":\"Unknown\"},{\"t\":2,\"p\":1,\"n\":\"scriptName\"},{\"t\":2,\"p\":1,\"n\":\"fragmentName\"}]}]}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"PKDT - Pack Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"General Flags\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Interrupt Override\"},{\"t\":3,\"p\":1,\"n\":\"Preferred Speed\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":3,\"p\":1,\"n\":\"Interrupt Flags\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"PSDT - Schedule\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Month\"},{\"t\":3,\"p\":1,\"n\":\"Day of week\"},{\"t\":3,\"p\":1,\"n\":\"Date\"},{\"t\":3,\"p\":1,\"n\":\"Hour\"},{\"t\":3,\"p\":1,\"n\":\"Minute\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Duration (minutes)\"}]},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Conditions\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Condition\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"CTDA - \",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":5,\"p\":1,\"n\":\"Comparison Value - Float\"},{\"t\":3,\"p\":1,\"n\":\"Comparison Value - Global\"},{\"t\":3,\"p\":1,\"n\":\"Function\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":11,\"p\":1,\"n\":\"None\"},{\"t\":3,\"p\":1,\"n\":\"Integer\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":11,\"p\":1,\"n\":\"Variable Name (unused)\"},{\"t\":3,\"p\":1,\"n\":\"Sex\"},{\"t\":3,\"p\":1,\"n\":\"Actor Value\"},{\"t\":3,\"p\":1,\"n\":\"Crime Type\"},{\"t\":3,\"p\":1,\"n\":\"Axis\"},{\"t\":3,\"p\":1,\"n\":\"Quest Stage (unused)\"},{\"t\":3,\"p\":1,\"n\":\"Misc Stat\"},{\"t\":3,\"p\":1,\"n\":\"Alignment\"},{\"t\":3,\"p\":1,\"n\":\"Equip Type\"},{\"t\":3,\"p\":1,\"n\":\"Form Type\"},{\"t\":3,\"p\":1,\"n\":\"Critical Stage\"},{\"t\":3,\"p\":1,\"n\":\"Object Reference\"},{\"t\":3,\"p\":1,\"n\":\"Inventory Object\"},{\"t\":3,\"p\":1,\"n\":\"Actor\"},{\"t\":3,\"p\":1,\"n\":\"Voice Type\"},{\"t\":3,\"p\":1,\"n\":\"Idle\"},{\"t\":3,\"p\":1,\"n\":\"Form List\"},{\"t\":3,\"p\":1,\"n\":\"Quest\"},{\"t\":3,\"p\":1,\"n\":\"Faction\"},{\"t\":3,\"p\":1,\"n\":\"Cell\"},{\"t\":3,\"p\":1,\"n\":\"Class\"},{\"t\":3,\"p\":1,\"n\":\"Race\"},{\"t\":3,\"p\":1,\"n\":\"Actor Base\"},{\"t\":3,\"p\":1,\"n\":\"Global\"},{\"t\":3,\"p\":1,\"n\":\"Weather\"},{\"t\":3,\"p\":1,\"n\":\"Package\"},{\"t\":3,\"p\":1,\"n\":\"Encounter Zone\"},{\"t\":3,\"p\":1,\"n\":\"Perk\"},{\"t\":3,\"p\":1,\"n\":\"Owner\"},{\"t\":3,\"p\":1,\"n\":\"Furniture\"},{\"t\":3,\"p\":1,\"n\":\"Effect Item\"},{\"t\":3,\"p\":1,\"n\":\"Base Effect\"},{\"t\":3,\"p\":1,\"n\":\"Worldspace\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Function\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Param (INVALID)\"},{\"t\":3,\"p\":1,\"n\":\"Referenceable Object\"},{\"t\":3,\"p\":1,\"n\":\"Region\"},{\"t\":3,\"p\":1,\"n\":\"Keyword\"},{\"t\":3,\"p\":1,\"n\":\"Player Action\"},{\"t\":3,\"p\":1,\"n\":\"Casting Type\"},{\"t\":3,\"p\":1,\"n\":\"Shout\"},{\"t\":3,\"p\":1,\"n\":\"Location\"},{\"t\":3,\"p\":1,\"n\":\"Location Ref Type\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"Packdata ID\"},{\"t\":3,\"p\":1,\"n\":\"Association Type\"},{\"t\":3,\"p\":1,\"n\":\"Furniture Anim\"},{\"t\":3,\"p\":1,\"n\":\"Furniture Entry\"},{\"t\":3,\"p\":1,\"n\":\"Scene\"},{\"t\":3,\"p\":1,\"n\":\"Ward State\"},{\"t\":3,\"p\":1,\"n\":\"Event\"},{\"t\":3,\"p\":1,\"n\":\"Event Data\"},{\"t\":3,\"p\":1,\"n\":\"Quest Stage\"},{\"t\":3,\"p\":1,\"n\":\"Weapon\"},{\"t\":3,\"p\":1,\"n\":\"Weapon List\"},{\"t\":3,\"p\":1,\"n\":\"Target\"},{\"t\":3,\"p\":1,\"n\":\"Target List\"},{\"t\":3,\"p\":1,\"n\":\"Target Part\"},{\"t\":3,\"p\":1,\"n\":\"VATS Action\"},{\"t\":3,\"p\":1,\"n\":\"Critical Effect\"},{\"t\":3,\"p\":1,\"n\":\"Critical Effect List\"},{\"t\":3,\"p\":1,\"n\":\"Weapon Type\"},{\"t\":3,\"p\":1,\"n\":\"Projectile Type\"},{\"t\":3,\"p\":1,\"n\":\"Delivery Type\"},{\"t\":3,\"p\":1,\"n\":\"Run On\"},{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":3,\"p\":1,\"n\":\"Parameter #3\"}]},{\"t\":2,\"p\":1,\"n\":\"CIS1 - Parameter #1\"},{\"t\":2,\"p\":1,\"n\":\"CIS2 - Parameter #2\"}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Idle Animations\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"IDLF - Flags\"},{\"t\":6,\"p\":1,\"n\":\"IDLC - \",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Animation Count\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":5,\"p\":1,\"n\":\"IDLT - Idle Timer Setting\"},{\"t\":7,\"p\":1,\"n\":\"IDLA - Animations\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Animation\"}]},{\"t\":11,\"n\":\"IDLB - Unknown\"}]},{\"t\":3,\"p\":1,\"n\":\"CNAM - Combat Style\"},{\"t\":3,\"p\":1,\"n\":\"QNAM - Owner Quest\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"PKCU - Counter\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Data Input Count\"},{\"t\":3,\"p\":1,\"n\":\"Package Template\"},{\"t\":3,\"p\":1,\"n\":\"Version Counter (autoincremented)\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Package Data\",\"c\":[{\"t\":8,\"p\":1,\"n\":\"Data Input Values\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Value\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"ANAM - Type\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":3,\"p\":1,\"n\":\"Bool\"},{\"t\":3,\"p\":1,\"n\":\"Integer\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":11,\"n\":\"BNAM - Unknown\"},{\"t\":8,\"p\":1,\"n\":\"Topic\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"PDTO - Topic Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Topic\"},{\"t\":2,\"p\":1,\"n\":\"Subtype\"}]}]},{\"t\":6,\"p\":1,\"n\":\"PLDT - Location\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":3,\"p\":1,\"n\":\"Cell\"},{\"t\":11,\"p\":1,\"n\":\"Near Package Start Location\"},{\"t\":11,\"p\":1,\"n\":\"Near Editor Location\"},{\"t\":3,\"p\":1,\"n\":\"Object ID\"},{\"t\":3,\"p\":1,\"n\":\"Object Type\"},{\"t\":3,\"p\":1,\"n\":\"Keyword\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":3,\"p\":1,\"n\":\"Radius\"}]},{\"t\":6,\"p\":1,\"n\":\"PTDA - Target\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Target Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":3,\"p\":1,\"n\":\"Object ID\"},{\"t\":3,\"p\":1,\"n\":\"Object Type\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":3,\"p\":1,\"n\":\"Count \\/ Distance\"}]}]},{\"t\":11,\"n\":\"TPIC - Unknown\"}]}]},{\"t\":8,\"p\":1,\"n\":\"Data Inputs\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Data Input\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"UNAM - Index\"},{\"t\":2,\"p\":1,\"n\":\"BNAM - Name\"},{\"t\":3,\"p\":1,\"n\":\"PNAM - Flags\"}]}]}]},{\"t\":11,\"n\":\"XNAM - Marker\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Procedure Tree\",\"c\":[{\"t\":8,\"p\":1,\"n\":\"Branches\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Branch\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"ANAM - Branch Type\"},{\"t\":3,\"p\":1,\"n\":\"CITC - Condition Count\"},{\"t\":8,\"p\":1,\"n\":\"Conditions\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Condition\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"CTDA - \",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":5,\"p\":1,\"n\":\"Comparison Value - Float\"},{\"t\":3,\"p\":1,\"n\":\"Comparison Value - Global\"},{\"t\":3,\"p\":1,\"n\":\"Function\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":11,\"p\":1,\"n\":\"None\"},{\"t\":3,\"p\":1,\"n\":\"Integer\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":11,\"p\":1,\"n\":\"Variable Name (unused)\"},{\"t\":3,\"p\":1,\"n\":\"Sex\"},{\"t\":3,\"p\":1,\"n\":\"Actor Value\"},{\"t\":3,\"p\":1,\"n\":\"Crime Type\"},{\"t\":3,\"p\":1,\"n\":\"Axis\"},{\"t\":3,\"p\":1,\"n\":\"Quest Stage (unused)\"},{\"t\":3,\"p\":1,\"n\":\"Misc Stat\"},{\"t\":3,\"p\":1,\"n\":\"Alignment\"},{\"t\":3,\"p\":1,\"n\":\"Equip Type\"},{\"t\":3,\"p\":1,\"n\":\"Form Type\"},{\"t\":3,\"p\":1,\"n\":\"Critical Stage\"},{\"t\":3,\"p\":1,\"n\":\"Object Reference\"},{\"t\":3,\"p\":1,\"n\":\"Inventory Object\"},{\"t\":3,\"p\":1,\"n\":\"Actor\"},{\"t\":3,\"p\":1,\"n\":\"Voice Type\"},{\"t\":3,\"p\":1,\"n\":\"Idle\"},{\"t\":3,\"p\":1,\"n\":\"Form List\"},{\"t\":3,\"p\":1,\"n\":\"Quest\"},{\"t\":3,\"p\":1,\"n\":\"Faction\"},{\"t\":3,\"p\":1,\"n\":\"Cell\"},{\"t\":3,\"p\":1,\"n\":\"Class\"},{\"t\":3,\"p\":1,\"n\":\"Race\"},{\"t\":3,\"p\":1,\"n\":\"Actor Base\"},{\"t\":3,\"p\":1,\"n\":\"Global\"},{\"t\":3,\"p\":1,\"n\":\"Weather\"},{\"t\":3,\"p\":1,\"n\":\"Package\"},{\"t\":3,\"p\":1,\"n\":\"Encounter Zone\"},{\"t\":3,\"p\":1,\"n\":\"Perk\"},{\"t\":3,\"p\":1,\"n\":\"Owner\"},{\"t\":3,\"p\":1,\"n\":\"Furniture\"},{\"t\":3,\"p\":1,\"n\":\"Effect Item\"},{\"t\":3,\"p\":1,\"n\":\"Base Effect\"},{\"t\":3,\"p\":1,\"n\":\"Worldspace\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Function\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Param (INVALID)\"},{\"t\":3,\"p\":1,\"n\":\"Referenceable Object\"},{\"t\":3,\"p\":1,\"n\":\"Region\"},{\"t\":3,\"p\":1,\"n\":\"Keyword\"},{\"t\":3,\"p\":1,\"n\":\"Player Action\"},{\"t\":3,\"p\":1,\"n\":\"Casting Type\"},{\"t\":3,\"p\":1,\"n\":\"Shout\"},{\"t\":3,\"p\":1,\"n\":\"Location\"},{\"t\":3,\"p\":1,\"n\":\"Location Ref Type\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"Packdata ID\"},{\"t\":3,\"p\":1,\"n\":\"Association Type\"},{\"t\":3,\"p\":1,\"n\":\"Furniture Anim\"},{\"t\":3,\"p\":1,\"n\":\"Furniture Entry\"},{\"t\":3,\"p\":1,\"n\":\"Scene\"},{\"t\":3,\"p\":1,\"n\":\"Ward State\"},{\"t\":3,\"p\":1,\"n\":\"Event\"},{\"t\":3,\"p\":1,\"n\":\"Event Data\"},{\"t\":3,\"p\":1,\"n\":\"Quest Stage\"},{\"t\":3,\"p\":1,\"n\":\"Weapon\"},{\"t\":3,\"p\":1,\"n\":\"Weapon List\"},{\"t\":3,\"p\":1,\"n\":\"Target\"},{\"t\":3,\"p\":1,\"n\":\"Target List\"},{\"t\":3,\"p\":1,\"n\":\"Target Part\"},{\"t\":3,\"p\":1,\"n\":\"VATS Action\"},{\"t\":3,\"p\":1,\"n\":\"Critical Effect\"},{\"t\":3,\"p\":1,\"n\":\"Critical Effect List\"},{\"t\":3,\"p\":1,\"n\":\"Weapon Type\"},{\"t\":3,\"p\":1,\"n\":\"Projectile Type\"},{\"t\":3,\"p\":1,\"n\":\"Delivery Type\"},{\"t\":3,\"p\":1,\"n\":\"Run On\"},{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":3,\"p\":1,\"n\":\"Parameter #3\"}]},{\"t\":2,\"p\":1,\"n\":\"CIS1 - Parameter #1\"},{\"t\":2,\"p\":1,\"n\":\"CIS2 - Parameter #2\"}]}]},{\"t\":6,\"p\":1,\"n\":\"PRCB - Root\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Branch Count\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"}]},{\"t\":2,\"p\":1,\"n\":\"PNAM - Procedure Type\"},{\"t\":3,\"p\":1,\"n\":\"FNAM - Flags\"},{\"t\":8,\"p\":1,\"n\":\"Data Input Indexes\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"PKC2 - Index\"}]},{\"t\":8,\"p\":1,\"n\":\"Flags Override\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"PFO2 - Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Set General Flags\"},{\"t\":3,\"p\":1,\"n\":\"Clear General Flags\"},{\"t\":3,\"p\":1,\"n\":\"Set Interrupt Flags\"},{\"t\":3,\"p\":1,\"n\":\"Clear Interrupt Flags\"},{\"t\":3,\"p\":1,\"n\":\"Preferred Speed Override\"},{\"t\":11,\"n\":\"Unknown\"}]}]},{\"t\":8,\"n\":\"Unknown\",\"c\":[{\"t\":11,\"n\":\"PFOR - Unknown\"}]}]}]}]},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Data Inputs\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Data Input\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"UNAM - Index\"},{\"t\":2,\"p\":1,\"n\":\"BNAM - Name\"},{\"t\":3,\"p\":1,\"n\":\"PNAM - Flags\"}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"OnBegin\",\"c\":[{\"p\":1,\"n\":\"POBA - OnBegin Marker\"},{\"t\":3,\"p\":1,\"n\":\"INAM - Idle\"},{\"t\":11,\"n\":\"SCHR - Unused\"},{\"t\":11,\"n\":\"SCTX - Unused\"},{\"t\":11,\"n\":\"QNAM - Unused\"},{\"t\":11,\"n\":\"TNAM - Unused\"},{\"t\":8,\"p\":1,\"n\":\"Topic\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"PDTO - Topic Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Topic\"},{\"t\":2,\"p\":1,\"n\":\"Subtype\"}]}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"OnEnd\",\"c\":[{\"p\":1,\"n\":\"POEA - OnEnd Marker\"},{\"t\":3,\"p\":1,\"n\":\"INAM - Idle\"},{\"t\":11,\"n\":\"SCHR - Unused\"},{\"t\":11,\"n\":\"SCTX - Unused\"},{\"t\":11,\"n\":\"QNAM - Unused\"},{\"t\":11,\"n\":\"TNAM - Unused\"},{\"t\":8,\"p\":1,\"n\":\"Topic\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"PDTO - Topic Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Topic\"},{\"t\":2,\"p\":1,\"n\":\"Subtype\"}]}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"OnChange\",\"c\":[{\"p\":1,\"n\":\"POCA - OnChange Marker\"},{\"t\":3,\"p\":1,\"n\":\"INAM - Idle\"},{\"t\":11,\"n\":\"SCHR - Unused\"},{\"t\":11,\"n\":\"SCDA - Unused\"},{\"t\":11,\"n\":\"SCTX - Unused\"},{\"t\":11,\"n\":\"QNAM - Unused\"},{\"t\":11,\"n\":\"TNAM - Unused\"},{\"t\":8,\"p\":1,\"n\":\"Topic\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"PDTO - Topic Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Topic\"},{\"t\":2,\"p\":1,\"n\":\"Subtype\"}]}]}]}]},{\"t\":1,\"p\":1,\"n\":\"PARW - Placed Arrow\",\"f\":1,\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"VMAD - Virtual Machine Adapter\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Version\"},{\"t\":3,\"p\":1,\"n\":\"Object Format\"},{\"t\":7,\"p\":1,\"n\":\"Scripts\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Script\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"scriptName\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":7,\"p\":1,\"n\":\"Properties\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Property\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"propertyName\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]},{\"t\":2,\"p\":1,\"n\":\"String\"},{\"t\":3,\"p\":1,\"n\":\"Int32\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":3,\"p\":1,\"n\":\"Bool\"},{\"t\":7,\"p\":1,\"n\":\"Array of Object\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]}]},{\"t\":7,\"p\":1,\"n\":\"Array of String\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Int32\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Float\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Bool\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]}]}]}]}]}]},{\"t\":3,\"p\":1,\"n\":\"NAME - Projectile\"},{\"t\":3,\"p\":1,\"n\":\"XEZN - Encounter Zone\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Ownership\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"XOWN - Owner\"},{\"t\":3,\"p\":1,\"n\":\"XRNK - Faction rank\"}]},{\"t\":5,\"p\":1,\"n\":\"XHTW - Head-Tracking Weight\"},{\"t\":5,\"p\":1,\"n\":\"XFVC - Favor Cost\"},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Reflected\\/Refracted By\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"XPWR - Water\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":3,\"p\":1,\"n\":\"Type\"}]}]},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Linked References\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"XLKR - Linked Reference\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Keyword\\/Ref\"},{\"t\":3,\"p\":1,\"n\":\"Ref\"}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Activate Parents\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"XAPD - Flags\"},{\"t\":8,\"p\":1,\"n\":\"Activate Parent Refs\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"XAPR - Activate Parent Ref\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":5,\"p\":1,\"n\":\"Delay\"}]}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"XESP - Enable Parent\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":3,\"p\":1,\"n\":\"XEMI - Emittance\"},{\"t\":3,\"p\":1,\"n\":\"XMBR - MultiBound Reference\"},{\"p\":1,\"n\":\"XIS2 - Ignored by Sandbox\"},{\"t\":7,\"p\":1,\"n\":\"XLRT - Location Ref Type\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Ref\"}]},{\"t\":3,\"p\":1,\"n\":\"XLRL - Location Reference\"},{\"t\":7,\"n\":\"XLOD - Distant LOD Data\",\"c\":[{\"t\":5,\"n\":\"Unknown\"}]},{\"t\":5,\"p\":1,\"n\":\"XSCL - Scale\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DATA - Position\\/Rotation\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Position\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"X\"},{\"t\":5,\"p\":1,\"n\":\"Y\"},{\"t\":5,\"p\":1,\"n\":\"Z\"}]},{\"t\":6,\"p\":1,\"n\":\"Rotation\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"X\"},{\"t\":5,\"p\":1,\"n\":\"Y\"},{\"t\":5,\"p\":1,\"n\":\"Z\"}]}]}]},{\"t\":1,\"p\":1,\"n\":\"PBAR - Placed Barrier\",\"f\":1,\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"VMAD - Virtual Machine Adapter\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Version\"},{\"t\":3,\"p\":1,\"n\":\"Object Format\"},{\"t\":7,\"p\":1,\"n\":\"Scripts\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Script\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"scriptName\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":7,\"p\":1,\"n\":\"Properties\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Property\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"propertyName\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]},{\"t\":2,\"p\":1,\"n\":\"String\"},{\"t\":3,\"p\":1,\"n\":\"Int32\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":3,\"p\":1,\"n\":\"Bool\"},{\"t\":7,\"p\":1,\"n\":\"Array of Object\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]}]},{\"t\":7,\"p\":1,\"n\":\"Array of String\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Int32\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Float\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Bool\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]}]}]}]}]}]},{\"t\":3,\"p\":1,\"n\":\"NAME - Projectile\"},{\"t\":3,\"p\":1,\"n\":\"XEZN - Encounter Zone\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Ownership\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"XOWN - Owner\"},{\"t\":3,\"p\":1,\"n\":\"XRNK - Faction rank\"}]},{\"t\":5,\"p\":1,\"n\":\"XHTW - Head-Tracking Weight\"},{\"t\":5,\"p\":1,\"n\":\"XFVC - Favor Cost\"},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Reflected\\/Refracted By\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"XPWR - Water\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":3,\"p\":1,\"n\":\"Type\"}]}]},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Linked References\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"XLKR - Linked Reference\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Keyword\\/Ref\"},{\"t\":3,\"p\":1,\"n\":\"Ref\"}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Activate Parents\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"XAPD - Flags\"},{\"t\":8,\"p\":1,\"n\":\"Activate Parent Refs\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"XAPR - Activate Parent Ref\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":5,\"p\":1,\"n\":\"Delay\"}]}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"XESP - Enable Parent\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":3,\"p\":1,\"n\":\"XEMI - Emittance\"},{\"t\":3,\"p\":1,\"n\":\"XMBR - MultiBound Reference\"},{\"p\":1,\"n\":\"XIS2 - Ignored by Sandbox\"},{\"t\":7,\"p\":1,\"n\":\"XLRT - Location Ref Type\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Ref\"}]},{\"t\":3,\"p\":1,\"n\":\"XLRL - Location Reference\"},{\"t\":7,\"n\":\"XLOD - Distant LOD Data\",\"c\":[{\"t\":5,\"n\":\"Unknown\"}]},{\"t\":5,\"p\":1,\"n\":\"XSCL - Scale\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DATA - Position\\/Rotation\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Position\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"X\"},{\"t\":5,\"p\":1,\"n\":\"Y\"},{\"t\":5,\"p\":1,\"n\":\"Z\"}]},{\"t\":6,\"p\":1,\"n\":\"Rotation\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"X\"},{\"t\":5,\"p\":1,\"n\":\"Y\"},{\"t\":5,\"p\":1,\"n\":\"Z\"}]}]}]},{\"t\":1,\"p\":1,\"n\":\"PBEA - Placed Beam\",\"f\":1,\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"VMAD - Virtual Machine Adapter\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Version\"},{\"t\":3,\"p\":1,\"n\":\"Object Format\"},{\"t\":7,\"p\":1,\"n\":\"Scripts\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Script\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"scriptName\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":7,\"p\":1,\"n\":\"Properties\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Property\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"propertyName\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]},{\"t\":2,\"p\":1,\"n\":\"String\"},{\"t\":3,\"p\":1,\"n\":\"Int32\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":3,\"p\":1,\"n\":\"Bool\"},{\"t\":7,\"p\":1,\"n\":\"Array of Object\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]}]},{\"t\":7,\"p\":1,\"n\":\"Array of String\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Int32\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Float\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Bool\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]}]}]}]}]}]},{\"t\":3,\"p\":1,\"n\":\"NAME - Projectile\"},{\"t\":3,\"p\":1,\"n\":\"XEZN - Encounter Zone\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Ownership\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"XOWN - Owner\"},{\"t\":3,\"p\":1,\"n\":\"XRNK - Faction rank\"}]},{\"t\":5,\"p\":1,\"n\":\"XHTW - Head-Tracking Weight\"},{\"t\":5,\"p\":1,\"n\":\"XFVC - Favor Cost\"},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Reflected\\/Refracted By\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"XPWR - Water\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":3,\"p\":1,\"n\":\"Type\"}]}]},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Linked References\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"XLKR - Linked Reference\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Keyword\\/Ref\"},{\"t\":3,\"p\":1,\"n\":\"Ref\"}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Activate Parents\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"XAPD - Flags\"},{\"t\":8,\"p\":1,\"n\":\"Activate Parent Refs\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"XAPR - Activate Parent Ref\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":5,\"p\":1,\"n\":\"Delay\"}]}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"XESP - Enable Parent\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":3,\"p\":1,\"n\":\"XEMI - Emittance\"},{\"t\":3,\"p\":1,\"n\":\"XMBR - MultiBound Reference\"},{\"p\":1,\"n\":\"XIS2 - Ignored by Sandbox\"},{\"t\":7,\"p\":1,\"n\":\"XLRT - Location Ref Type\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Ref\"}]},{\"t\":3,\"p\":1,\"n\":\"XLRL - Location Reference\"},{\"t\":7,\"n\":\"XLOD - Distant LOD Data\",\"c\":[{\"t\":5,\"n\":\"Unknown\"}]},{\"t\":5,\"p\":1,\"n\":\"XSCL - Scale\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DATA - Position\\/Rotation\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Position\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"X\"},{\"t\":5,\"p\":1,\"n\":\"Y\"},{\"t\":5,\"p\":1,\"n\":\"Z\"}]},{\"t\":6,\"p\":1,\"n\":\"Rotation\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"X\"},{\"t\":5,\"p\":1,\"n\":\"Y\"},{\"t\":5,\"p\":1,\"n\":\"Z\"}]}]}]},{\"t\":1,\"p\":1,\"n\":\"PCON - Placed Cone\\/Voice\",\"f\":1,\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"VMAD - Virtual Machine Adapter\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Version\"},{\"t\":3,\"p\":1,\"n\":\"Object Format\"},{\"t\":7,\"p\":1,\"n\":\"Scripts\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Script\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"scriptName\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":7,\"p\":1,\"n\":\"Properties\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Property\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"propertyName\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]},{\"t\":2,\"p\":1,\"n\":\"String\"},{\"t\":3,\"p\":1,\"n\":\"Int32\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":3,\"p\":1,\"n\":\"Bool\"},{\"t\":7,\"p\":1,\"n\":\"Array of Object\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]}]},{\"t\":7,\"p\":1,\"n\":\"Array of String\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Int32\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Float\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Bool\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]}]}]}]}]}]},{\"t\":3,\"p\":1,\"n\":\"NAME - Projectile\"},{\"t\":3,\"p\":1,\"n\":\"XEZN - Encounter Zone\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Ownership\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"XOWN - Owner\"},{\"t\":3,\"p\":1,\"n\":\"XRNK - Faction rank\"}]},{\"t\":5,\"p\":1,\"n\":\"XHTW - Head-Tracking Weight\"},{\"t\":5,\"p\":1,\"n\":\"XFVC - Favor Cost\"},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Reflected\\/Refracted By\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"XPWR - Water\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":3,\"p\":1,\"n\":\"Type\"}]}]},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Linked References\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"XLKR - Linked Reference\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Keyword\\/Ref\"},{\"t\":3,\"p\":1,\"n\":\"Ref\"}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Activate Parents\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"XAPD - Flags\"},{\"t\":8,\"p\":1,\"n\":\"Activate Parent Refs\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"XAPR - Activate Parent Ref\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":5,\"p\":1,\"n\":\"Delay\"}]}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"XESP - Enable Parent\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":3,\"p\":1,\"n\":\"XEMI - Emittance\"},{\"t\":3,\"p\":1,\"n\":\"XMBR - MultiBound Reference\"},{\"p\":1,\"n\":\"XIS2 - Ignored by Sandbox\"},{\"t\":7,\"p\":1,\"n\":\"XLRT - Location Ref Type\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Ref\"}]},{\"t\":3,\"p\":1,\"n\":\"XLRL - Location Reference\"},{\"t\":7,\"n\":\"XLOD - Distant LOD Data\",\"c\":[{\"t\":5,\"n\":\"Unknown\"}]},{\"t\":5,\"p\":1,\"n\":\"XSCL - Scale\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DATA - Position\\/Rotation\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Position\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"X\"},{\"t\":5,\"p\":1,\"n\":\"Y\"},{\"t\":5,\"p\":1,\"n\":\"Z\"}]},{\"t\":6,\"p\":1,\"n\":\"Rotation\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"X\"},{\"t\":5,\"p\":1,\"n\":\"Y\"},{\"t\":5,\"p\":1,\"n\":\"Z\"}]}]}]},{\"t\":1,\"p\":1,\"n\":\"PERK - Perk\",\"f\":1,\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"VMAD - Virtual Machine Adapter\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Version\"},{\"t\":3,\"p\":1,\"n\":\"Object Format\"},{\"t\":7,\"p\":1,\"n\":\"Scripts\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Script\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"scriptName\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":7,\"p\":1,\"n\":\"Properties\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Property\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"propertyName\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]},{\"t\":2,\"p\":1,\"n\":\"String\"},{\"t\":3,\"p\":1,\"n\":\"Int32\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":3,\"p\":1,\"n\":\"Bool\"},{\"t\":7,\"p\":1,\"n\":\"Array of Object\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]}]},{\"t\":7,\"p\":1,\"n\":\"Array of String\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Int32\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Float\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Bool\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]}]}]}]}]},{\"t\":6,\"p\":1,\"n\":\"Script Fragments\",\"c\":[{\"t\":3,\"n\":\"Unknown\"},{\"t\":2,\"p\":1,\"n\":\"fileName\"},{\"t\":7,\"p\":1,\"n\":\"Fragments\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Fragment\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Fragment Index\"},{\"t\":3,\"n\":\"Unknown\"},{\"t\":2,\"p\":1,\"n\":\"scriptName\"},{\"t\":2,\"p\":1,\"n\":\"fragmentName\"}]}]}]}]},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":2,\"p\":1,\"n\":\"DESC - Description\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Icon\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"ICON - Large Icon filename\"},{\"t\":2,\"p\":1,\"n\":\"MICO - Small Icon filename\"}]},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Conditions\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Condition\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"CTDA - \",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":5,\"p\":1,\"n\":\"Comparison Value - Float\"},{\"t\":3,\"p\":1,\"n\":\"Comparison Value - Global\"},{\"t\":3,\"p\":1,\"n\":\"Function\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":11,\"p\":1,\"n\":\"None\"},{\"t\":3,\"p\":1,\"n\":\"Integer\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":11,\"p\":1,\"n\":\"Variable Name (unused)\"},{\"t\":3,\"p\":1,\"n\":\"Sex\"},{\"t\":3,\"p\":1,\"n\":\"Actor Value\"},{\"t\":3,\"p\":1,\"n\":\"Crime Type\"},{\"t\":3,\"p\":1,\"n\":\"Axis\"},{\"t\":3,\"p\":1,\"n\":\"Quest Stage (unused)\"},{\"t\":3,\"p\":1,\"n\":\"Misc Stat\"},{\"t\":3,\"p\":1,\"n\":\"Alignment\"},{\"t\":3,\"p\":1,\"n\":\"Equip Type\"},{\"t\":3,\"p\":1,\"n\":\"Form Type\"},{\"t\":3,\"p\":1,\"n\":\"Critical Stage\"},{\"t\":3,\"p\":1,\"n\":\"Object Reference\"},{\"t\":3,\"p\":1,\"n\":\"Inventory Object\"},{\"t\":3,\"p\":1,\"n\":\"Actor\"},{\"t\":3,\"p\":1,\"n\":\"Voice Type\"},{\"t\":3,\"p\":1,\"n\":\"Idle\"},{\"t\":3,\"p\":1,\"n\":\"Form List\"},{\"t\":3,\"p\":1,\"n\":\"Quest\"},{\"t\":3,\"p\":1,\"n\":\"Faction\"},{\"t\":3,\"p\":1,\"n\":\"Cell\"},{\"t\":3,\"p\":1,\"n\":\"Class\"},{\"t\":3,\"p\":1,\"n\":\"Race\"},{\"t\":3,\"p\":1,\"n\":\"Actor Base\"},{\"t\":3,\"p\":1,\"n\":\"Global\"},{\"t\":3,\"p\":1,\"n\":\"Weather\"},{\"t\":3,\"p\":1,\"n\":\"Package\"},{\"t\":3,\"p\":1,\"n\":\"Encounter Zone\"},{\"t\":3,\"p\":1,\"n\":\"Perk\"},{\"t\":3,\"p\":1,\"n\":\"Owner\"},{\"t\":3,\"p\":1,\"n\":\"Furniture\"},{\"t\":3,\"p\":1,\"n\":\"Effect Item\"},{\"t\":3,\"p\":1,\"n\":\"Base Effect\"},{\"t\":3,\"p\":1,\"n\":\"Worldspace\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Function\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Param (INVALID)\"},{\"t\":3,\"p\":1,\"n\":\"Referenceable Object\"},{\"t\":3,\"p\":1,\"n\":\"Region\"},{\"t\":3,\"p\":1,\"n\":\"Keyword\"},{\"t\":3,\"p\":1,\"n\":\"Player Action\"},{\"t\":3,\"p\":1,\"n\":\"Casting Type\"},{\"t\":3,\"p\":1,\"n\":\"Shout\"},{\"t\":3,\"p\":1,\"n\":\"Location\"},{\"t\":3,\"p\":1,\"n\":\"Location Ref Type\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"Packdata ID\"},{\"t\":3,\"p\":1,\"n\":\"Association Type\"},{\"t\":3,\"p\":1,\"n\":\"Furniture Anim\"},{\"t\":3,\"p\":1,\"n\":\"Furniture Entry\"},{\"t\":3,\"p\":1,\"n\":\"Scene\"},{\"t\":3,\"p\":1,\"n\":\"Ward State\"},{\"t\":3,\"p\":1,\"n\":\"Event\"},{\"t\":3,\"p\":1,\"n\":\"Event Data\"},{\"t\":3,\"p\":1,\"n\":\"Quest Stage\"},{\"t\":3,\"p\":1,\"n\":\"Weapon\"},{\"t\":3,\"p\":1,\"n\":\"Weapon List\"},{\"t\":3,\"p\":1,\"n\":\"Target\"},{\"t\":3,\"p\":1,\"n\":\"Target List\"},{\"t\":3,\"p\":1,\"n\":\"Target Part\"},{\"t\":3,\"p\":1,\"n\":\"VATS Action\"},{\"t\":3,\"p\":1,\"n\":\"Critical Effect\"},{\"t\":3,\"p\":1,\"n\":\"Critical Effect List\"},{\"t\":3,\"p\":1,\"n\":\"Weapon Type\"},{\"t\":3,\"p\":1,\"n\":\"Projectile Type\"},{\"t\":3,\"p\":1,\"n\":\"Delivery Type\"},{\"t\":3,\"p\":1,\"n\":\"Run On\"},{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":3,\"p\":1,\"n\":\"Parameter #3\"}]},{\"t\":2,\"p\":1,\"n\":\"CIS1 - Parameter #1\"},{\"t\":2,\"p\":1,\"n\":\"CIS2 - Parameter #2\"}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DATA - Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Trait\"},{\"t\":3,\"p\":1,\"n\":\"Level\"},{\"t\":3,\"p\":1,\"n\":\"Num Ranks\"},{\"t\":3,\"p\":1,\"n\":\"Playable\"},{\"t\":3,\"p\":1,\"n\":\"Hidden\"}]},{\"t\":3,\"p\":1,\"n\":\"NNAM - Next Perk\"},{\"t\":10,\"p\":1,\"n\":\"Effects\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Effect\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"PRKE - Header\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Rank\"},{\"t\":3,\"p\":1,\"n\":\"Priority\"}]},{\"t\":6,\"p\":1,\"n\":\"Quest + Stage\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Quest\"},{\"t\":3,\"p\":1,\"n\":\"Quest Stage\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":3,\"p\":1,\"n\":\"Ability\"},{\"t\":6,\"p\":1,\"n\":\"Entry Point\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Entry Point\"},{\"t\":3,\"p\":1,\"n\":\"Function\"},{\"t\":3,\"p\":1,\"n\":\"Perk Condition Tab Count\"}]},{\"t\":10,\"p\":1,\"n\":\"Perk Conditions\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Perk Condition\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"PRKC - Run On (Tab Index)\"},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Conditions\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Condition\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"CTDA - \",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":5,\"p\":1,\"n\":\"Comparison Value - Float\"},{\"t\":3,\"p\":1,\"n\":\"Comparison Value - Global\"},{\"t\":3,\"p\":1,\"n\":\"Function\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":11,\"p\":1,\"n\":\"None\"},{\"t\":3,\"p\":1,\"n\":\"Integer\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":11,\"p\":1,\"n\":\"Variable Name (unused)\"},{\"t\":3,\"p\":1,\"n\":\"Sex\"},{\"t\":3,\"p\":1,\"n\":\"Actor Value\"},{\"t\":3,\"p\":1,\"n\":\"Crime Type\"},{\"t\":3,\"p\":1,\"n\":\"Axis\"},{\"t\":3,\"p\":1,\"n\":\"Quest Stage (unused)\"},{\"t\":3,\"p\":1,\"n\":\"Misc Stat\"},{\"t\":3,\"p\":1,\"n\":\"Alignment\"},{\"t\":3,\"p\":1,\"n\":\"Equip Type\"},{\"t\":3,\"p\":1,\"n\":\"Form Type\"},{\"t\":3,\"p\":1,\"n\":\"Critical Stage\"},{\"t\":3,\"p\":1,\"n\":\"Object Reference\"},{\"t\":3,\"p\":1,\"n\":\"Inventory Object\"},{\"t\":3,\"p\":1,\"n\":\"Actor\"},{\"t\":3,\"p\":1,\"n\":\"Voice Type\"},{\"t\":3,\"p\":1,\"n\":\"Idle\"},{\"t\":3,\"p\":1,\"n\":\"Form List\"},{\"t\":3,\"p\":1,\"n\":\"Quest\"},{\"t\":3,\"p\":1,\"n\":\"Faction\"},{\"t\":3,\"p\":1,\"n\":\"Cell\"},{\"t\":3,\"p\":1,\"n\":\"Class\"},{\"t\":3,\"p\":1,\"n\":\"Race\"},{\"t\":3,\"p\":1,\"n\":\"Actor Base\"},{\"t\":3,\"p\":1,\"n\":\"Global\"},{\"t\":3,\"p\":1,\"n\":\"Weather\"},{\"t\":3,\"p\":1,\"n\":\"Package\"},{\"t\":3,\"p\":1,\"n\":\"Encounter Zone\"},{\"t\":3,\"p\":1,\"n\":\"Perk\"},{\"t\":3,\"p\":1,\"n\":\"Owner\"},{\"t\":3,\"p\":1,\"n\":\"Furniture\"},{\"t\":3,\"p\":1,\"n\":\"Effect Item\"},{\"t\":3,\"p\":1,\"n\":\"Base Effect\"},{\"t\":3,\"p\":1,\"n\":\"Worldspace\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Function\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Param (INVALID)\"},{\"t\":3,\"p\":1,\"n\":\"Referenceable Object\"},{\"t\":3,\"p\":1,\"n\":\"Region\"},{\"t\":3,\"p\":1,\"n\":\"Keyword\"},{\"t\":3,\"p\":1,\"n\":\"Player Action\"},{\"t\":3,\"p\":1,\"n\":\"Casting Type\"},{\"t\":3,\"p\":1,\"n\":\"Shout\"},{\"t\":3,\"p\":1,\"n\":\"Location\"},{\"t\":3,\"p\":1,\"n\":\"Location Ref Type\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"Packdata ID\"},{\"t\":3,\"p\":1,\"n\":\"Association Type\"},{\"t\":3,\"p\":1,\"n\":\"Furniture Anim\"},{\"t\":3,\"p\":1,\"n\":\"Furniture Entry\"},{\"t\":3,\"p\":1,\"n\":\"Scene\"},{\"t\":3,\"p\":1,\"n\":\"Ward State\"},{\"t\":3,\"p\":1,\"n\":\"Event\"},{\"t\":3,\"p\":1,\"n\":\"Event Data\"},{\"t\":3,\"p\":1,\"n\":\"Quest Stage\"},{\"t\":3,\"p\":1,\"n\":\"Weapon\"},{\"t\":3,\"p\":1,\"n\":\"Weapon List\"},{\"t\":3,\"p\":1,\"n\":\"Target\"},{\"t\":3,\"p\":1,\"n\":\"Target List\"},{\"t\":3,\"p\":1,\"n\":\"Target Part\"},{\"t\":3,\"p\":1,\"n\":\"VATS Action\"},{\"t\":3,\"p\":1,\"n\":\"Critical Effect\"},{\"t\":3,\"p\":1,\"n\":\"Critical Effect List\"},{\"t\":3,\"p\":1,\"n\":\"Weapon Type\"},{\"t\":3,\"p\":1,\"n\":\"Projectile Type\"},{\"t\":3,\"p\":1,\"n\":\"Delivery Type\"},{\"t\":3,\"p\":1,\"n\":\"Run On\"},{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":3,\"p\":1,\"n\":\"Parameter #3\"}]},{\"t\":2,\"p\":1,\"n\":\"CIS1 - Parameter #1\"},{\"t\":2,\"p\":1,\"n\":\"CIS2 - Parameter #2\"}]}]}]}]},{\"t\":6,\"p\":1,\"n\":\"Function Parameters\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"EPFT - Type\"},{\"t\":2,\"p\":1,\"n\":\"EPF2 - Button Label\"},{\"t\":6,\"p\":1,\"n\":\"EPF3 - Script Flags\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Script Flags\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":11,\"n\":\"Unknown\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":6,\"p\":1,\"n\":\"Float, Float\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Float 1\"},{\"t\":5,\"p\":1,\"n\":\"Float 2\"}]},{\"t\":3,\"p\":1,\"n\":\"Leveled Item\"},{\"t\":3,\"p\":1,\"n\":\"Spell\"},{\"t\":2,\"p\":1,\"n\":\"Text\"},{\"t\":6,\"p\":1,\"n\":\"Actor Value, Float\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Actor Value\"},{\"t\":5,\"p\":1,\"n\":\"Float\"}]}]},{\"p\":1,\"n\":\"PRKF - End Marker\"}]}]}]},{\"t\":1,\"p\":1,\"n\":\"PFLA - Placed Flame\",\"f\":1,\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"VMAD - Virtual Machine Adapter\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Version\"},{\"t\":3,\"p\":1,\"n\":\"Object Format\"},{\"t\":7,\"p\":1,\"n\":\"Scripts\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Script\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"scriptName\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":7,\"p\":1,\"n\":\"Properties\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Property\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"propertyName\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]},{\"t\":2,\"p\":1,\"n\":\"String\"},{\"t\":3,\"p\":1,\"n\":\"Int32\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":3,\"p\":1,\"n\":\"Bool\"},{\"t\":7,\"p\":1,\"n\":\"Array of Object\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]}]},{\"t\":7,\"p\":1,\"n\":\"Array of String\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Int32\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Float\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Bool\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]}]}]}]}]}]},{\"t\":3,\"p\":1,\"n\":\"NAME - Projectile\"},{\"t\":3,\"p\":1,\"n\":\"XEZN - Encounter Zone\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Ownership\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"XOWN - Owner\"},{\"t\":3,\"p\":1,\"n\":\"XRNK - Faction rank\"}]},{\"t\":5,\"p\":1,\"n\":\"XHTW - Head-Tracking Weight\"},{\"t\":5,\"p\":1,\"n\":\"XFVC - Favor Cost\"},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Reflected\\/Refracted By\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"XPWR - Water\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":3,\"p\":1,\"n\":\"Type\"}]}]},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Linked References\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"XLKR - Linked Reference\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Keyword\\/Ref\"},{\"t\":3,\"p\":1,\"n\":\"Ref\"}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Activate Parents\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"XAPD - Flags\"},{\"t\":8,\"p\":1,\"n\":\"Activate Parent Refs\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"XAPR - Activate Parent Ref\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":5,\"p\":1,\"n\":\"Delay\"}]}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"XESP - Enable Parent\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":3,\"p\":1,\"n\":\"XEMI - Emittance\"},{\"t\":3,\"p\":1,\"n\":\"XMBR - MultiBound Reference\"},{\"p\":1,\"n\":\"XIS2 - Ignored by Sandbox\"},{\"t\":7,\"p\":1,\"n\":\"XLRT - Location Ref Type\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Ref\"}]},{\"t\":3,\"p\":1,\"n\":\"XLRL - Location Reference\"},{\"t\":7,\"n\":\"XLOD - Distant LOD Data\",\"c\":[{\"t\":5,\"n\":\"Unknown\"}]},{\"t\":5,\"p\":1,\"n\":\"XSCL - Scale\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DATA - Position\\/Rotation\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Position\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"X\"},{\"t\":5,\"p\":1,\"n\":\"Y\"},{\"t\":5,\"p\":1,\"n\":\"Z\"}]},{\"t\":6,\"p\":1,\"n\":\"Rotation\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"X\"},{\"t\":5,\"p\":1,\"n\":\"Y\"},{\"t\":5,\"p\":1,\"n\":\"Z\"}]}]}]},{\"t\":1,\"p\":1,\"n\":\"PGRE - Placed Projectile\",\"f\":1,\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"VMAD - Virtual Machine Adapter\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Version\"},{\"t\":3,\"p\":1,\"n\":\"Object Format\"},{\"t\":7,\"p\":1,\"n\":\"Scripts\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Script\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"scriptName\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":7,\"p\":1,\"n\":\"Properties\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Property\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"propertyName\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]},{\"t\":2,\"p\":1,\"n\":\"String\"},{\"t\":3,\"p\":1,\"n\":\"Int32\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":3,\"p\":1,\"n\":\"Bool\"},{\"t\":7,\"p\":1,\"n\":\"Array of Object\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]}]},{\"t\":7,\"p\":1,\"n\":\"Array of String\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Int32\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Float\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Bool\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]}]}]}]}]}]},{\"t\":3,\"p\":1,\"n\":\"NAME - Projectile\"},{\"t\":3,\"p\":1,\"n\":\"XEZN - Encounter Zone\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Ownership\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"XOWN - Owner\"},{\"t\":3,\"p\":1,\"n\":\"XRNK - Faction rank\"}]},{\"t\":5,\"p\":1,\"n\":\"XHTW - Head-Tracking Weight\"},{\"t\":5,\"p\":1,\"n\":\"XFVC - Favor Cost\"},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Reflected\\/Refracted By\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"XPWR - Water\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":3,\"p\":1,\"n\":\"Type\"}]}]},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Linked References\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"XLKR - Linked Reference\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Keyword\\/Ref\"},{\"t\":3,\"p\":1,\"n\":\"Ref\"}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Activate Parents\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"XAPD - Flags\"},{\"t\":8,\"p\":1,\"n\":\"Activate Parent Refs\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"XAPR - Activate Parent Ref\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":5,\"p\":1,\"n\":\"Delay\"}]}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"XESP - Enable Parent\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":3,\"p\":1,\"n\":\"XEMI - Emittance\"},{\"t\":3,\"p\":1,\"n\":\"XMBR - MultiBound Reference\"},{\"p\":1,\"n\":\"XIS2 - Ignored by Sandbox\"},{\"t\":7,\"p\":1,\"n\":\"XLRT - Location Ref Type\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Ref\"}]},{\"t\":3,\"p\":1,\"n\":\"XLRL - Location Reference\"},{\"t\":7,\"n\":\"XLOD - Distant LOD Data\",\"c\":[{\"t\":5,\"n\":\"Unknown\"}]},{\"t\":5,\"p\":1,\"n\":\"XSCL - Scale\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DATA - Position\\/Rotation\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Position\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"X\"},{\"t\":5,\"p\":1,\"n\":\"Y\"},{\"t\":5,\"p\":1,\"n\":\"Z\"}]},{\"t\":6,\"p\":1,\"n\":\"Rotation\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"X\"},{\"t\":5,\"p\":1,\"n\":\"Y\"},{\"t\":5,\"p\":1,\"n\":\"Z\"}]}]}]},{\"t\":1,\"p\":1,\"n\":\"PHZD - Placed Hazard\",\"f\":1,\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"VMAD - Virtual Machine Adapter\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Version\"},{\"t\":3,\"p\":1,\"n\":\"Object Format\"},{\"t\":7,\"p\":1,\"n\":\"Scripts\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Script\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"scriptName\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":7,\"p\":1,\"n\":\"Properties\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Property\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"propertyName\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]},{\"t\":2,\"p\":1,\"n\":\"String\"},{\"t\":3,\"p\":1,\"n\":\"Int32\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":3,\"p\":1,\"n\":\"Bool\"},{\"t\":7,\"p\":1,\"n\":\"Array of Object\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]}]},{\"t\":7,\"p\":1,\"n\":\"Array of String\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Int32\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Float\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Bool\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]}]}]}]}]}]},{\"t\":3,\"p\":1,\"n\":\"NAME - Projectile\"},{\"t\":3,\"p\":1,\"n\":\"XEZN - Encounter Zone\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Ownership\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"XOWN - Owner\"},{\"t\":3,\"p\":1,\"n\":\"XRNK - Faction rank\"}]},{\"t\":5,\"p\":1,\"n\":\"XHTW - Head-Tracking Weight\"},{\"t\":5,\"p\":1,\"n\":\"XFVC - Favor Cost\"},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Reflected\\/Refracted By\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"XPWR - Water\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":3,\"p\":1,\"n\":\"Type\"}]}]},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Linked References\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"XLKR - Linked Reference\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Keyword\\/Ref\"},{\"t\":3,\"p\":1,\"n\":\"Ref\"}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Activate Parents\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"XAPD - Flags\"},{\"t\":8,\"p\":1,\"n\":\"Activate Parent Refs\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"XAPR - Activate Parent Ref\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":5,\"p\":1,\"n\":\"Delay\"}]}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"XESP - Enable Parent\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":3,\"p\":1,\"n\":\"XEMI - Emittance\"},{\"t\":3,\"p\":1,\"n\":\"XMBR - MultiBound Reference\"},{\"p\":1,\"n\":\"XIS2 - Ignored by Sandbox\"},{\"t\":7,\"p\":1,\"n\":\"XLRT - Location Ref Type\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Ref\"}]},{\"t\":3,\"p\":1,\"n\":\"XLRL - Location Reference\"},{\"t\":7,\"n\":\"XLOD - Distant LOD Data\",\"c\":[{\"t\":5,\"n\":\"Unknown\"}]},{\"t\":5,\"p\":1,\"n\":\"XSCL - Scale\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DATA - Position\\/Rotation\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Position\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"X\"},{\"t\":5,\"p\":1,\"n\":\"Y\"},{\"t\":5,\"p\":1,\"n\":\"Z\"}]},{\"t\":6,\"p\":1,\"n\":\"Rotation\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"X\"},{\"t\":5,\"p\":1,\"n\":\"Y\"},{\"t\":5,\"p\":1,\"n\":\"Z\"}]}]}]},{\"t\":1,\"p\":1,\"n\":\"PMIS - Placed Missile\",\"f\":1,\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"VMAD - Virtual Machine Adapter\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Version\"},{\"t\":3,\"p\":1,\"n\":\"Object Format\"},{\"t\":7,\"p\":1,\"n\":\"Scripts\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Script\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"scriptName\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":7,\"p\":1,\"n\":\"Properties\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Property\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"propertyName\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]},{\"t\":2,\"p\":1,\"n\":\"String\"},{\"t\":3,\"p\":1,\"n\":\"Int32\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":3,\"p\":1,\"n\":\"Bool\"},{\"t\":7,\"p\":1,\"n\":\"Array of Object\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]}]},{\"t\":7,\"p\":1,\"n\":\"Array of String\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Int32\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Float\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Bool\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]}]}]}]}]}]},{\"t\":3,\"p\":1,\"n\":\"NAME - Projectile\"},{\"t\":3,\"p\":1,\"n\":\"XEZN - Encounter Zone\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Ownership\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"XOWN - Owner\"},{\"t\":3,\"p\":1,\"n\":\"XRNK - Faction rank\"}]},{\"t\":5,\"p\":1,\"n\":\"XHTW - Head-Tracking Weight\"},{\"t\":5,\"p\":1,\"n\":\"XFVC - Favor Cost\"},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Reflected\\/Refracted By\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"XPWR - Water\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":3,\"p\":1,\"n\":\"Type\"}]}]},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Linked References\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"XLKR - Linked Reference\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Keyword\\/Ref\"},{\"t\":3,\"p\":1,\"n\":\"Ref\"}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Activate Parents\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"XAPD - Flags\"},{\"t\":8,\"p\":1,\"n\":\"Activate Parent Refs\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"XAPR - Activate Parent Ref\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":5,\"p\":1,\"n\":\"Delay\"}]}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"XESP - Enable Parent\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":3,\"p\":1,\"n\":\"XEMI - Emittance\"},{\"t\":3,\"p\":1,\"n\":\"XMBR - MultiBound Reference\"},{\"p\":1,\"n\":\"XIS2 - Ignored by Sandbox\"},{\"t\":7,\"p\":1,\"n\":\"XLRT - Location Ref Type\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Ref\"}]},{\"t\":3,\"p\":1,\"n\":\"XLRL - Location Reference\"},{\"t\":7,\"n\":\"XLOD - Distant LOD Data\",\"c\":[{\"t\":5,\"n\":\"Unknown\"}]},{\"t\":5,\"p\":1,\"n\":\"XSCL - Scale\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DATA - Position\\/Rotation\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Position\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"X\"},{\"t\":5,\"p\":1,\"n\":\"Y\"},{\"t\":5,\"p\":1,\"n\":\"Z\"}]},{\"t\":6,\"p\":1,\"n\":\"Rotation\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"X\"},{\"t\":5,\"p\":1,\"n\":\"Y\"},{\"t\":5,\"p\":1,\"n\":\"Z\"}]}]}]},{\"t\":1,\"p\":1,\"n\":\"PROJ - Projectile\",\"f\":1,\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"X1\"},{\"t\":3,\"p\":1,\"n\":\"Y1\"},{\"t\":3,\"p\":1,\"n\":\"Z1\"},{\"t\":3,\"p\":1,\"n\":\"X2\"},{\"t\":3,\"p\":1,\"n\":\"Y2\"},{\"t\":3,\"p\":1,\"n\":\"Z2\"}]},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"MODT - Texture Files Hashes\"},{\"t\":7,\"p\":1,\"n\":\"MODS - Alternate Textures\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"3D Name\"},{\"t\":3,\"p\":1,\"n\":\"New Texture\"},{\"t\":3,\"p\":1,\"n\":\"3D Index\"}]}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Destructable\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"DEST - Header\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Health\"},{\"t\":3,\"p\":1,\"n\":\"DEST Count\"},{\"t\":3,\"p\":1,\"n\":\"VATS Targetable\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":8,\"p\":1,\"n\":\"Stages\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Stage\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"DSTD - Destruction Stage Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Health %\"},{\"t\":3,\"p\":1,\"n\":\"Index\"},{\"t\":3,\"p\":1,\"n\":\"Model Damage Stage\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":3,\"p\":1,\"n\":\"Self Damage per Second\"},{\"t\":3,\"p\":1,\"n\":\"Explosion\"},{\"t\":3,\"p\":1,\"n\":\"Debris\"},{\"t\":3,\"p\":1,\"n\":\"Debris Count\"}]},{\"t\":6,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"DMDL - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"DMDT - Texture Files Hashes\"},{\"t\":7,\"p\":1,\"n\":\"DMDS - Alternate Textures\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"3D Name\"},{\"t\":3,\"p\":1,\"n\":\"New Texture\"},{\"t\":3,\"p\":1,\"n\":\"3D Index\"}]}]}]},{\"p\":1,\"n\":\"DSTF - End Marker\"}]}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DATA - Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":5,\"p\":1,\"n\":\"Gravity\"},{\"t\":5,\"p\":1,\"n\":\"Speed\"},{\"t\":5,\"p\":1,\"n\":\"Range\"},{\"t\":3,\"p\":1,\"n\":\"Light\"},{\"t\":3,\"p\":1,\"n\":\"Muzzle Flash - Light\"},{\"t\":5,\"p\":1,\"n\":\"Tracer Chance\"},{\"t\":5,\"p\":1,\"n\":\"Explosion - Alt. Trigger - Proximity\"},{\"t\":5,\"p\":1,\"n\":\"Explosion - Alt. Trigger - Timer\"},{\"t\":3,\"p\":1,\"n\":\"Explosion\"},{\"t\":3,\"p\":1,\"n\":\"Sound\"},{\"t\":5,\"p\":1,\"n\":\"Muzzle Flash - Duration\"},{\"t\":5,\"p\":1,\"n\":\"Fade Duration\"},{\"t\":5,\"p\":1,\"n\":\"Impact Force\"},{\"t\":3,\"p\":1,\"n\":\"Sound - Countdown\"},{\"t\":3,\"p\":1,\"n\":\"Sound - Disable\"},{\"t\":3,\"p\":1,\"n\":\"Default Weapon Source\"},{\"t\":5,\"p\":1,\"n\":\"Cone Spread\"},{\"t\":5,\"p\":1,\"n\":\"Collision Radius\"},{\"t\":5,\"p\":1,\"n\":\"Lifetime\"},{\"t\":5,\"p\":1,\"n\":\"Relaunch Interval\"},{\"t\":3,\"p\":1,\"n\":\"Decal Data\"},{\"t\":3,\"p\":1,\"n\":\"Collision Layer\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Muzzle Flash Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"NAM1 - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"NAM2 - Texture Files Hashes\"}]},{\"t\":3,\"p\":1,\"n\":\"VNAM - Sound Level\"}]},{\"t\":1,\"p\":1,\"n\":\"PWAT\",\"f\":1,\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"}]},{\"t\":1,\"p\":1,\"n\":\"QUST - Quest\",\"f\":1,\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"VMAD - Virtual Machine Adapter\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Version\"},{\"t\":3,\"p\":1,\"n\":\"Object Format\"},{\"t\":7,\"p\":1,\"n\":\"Scripts\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Script\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"scriptName\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":7,\"p\":1,\"n\":\"Properties\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Property\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"propertyName\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]},{\"t\":2,\"p\":1,\"n\":\"String\"},{\"t\":3,\"p\":1,\"n\":\"Int32\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":3,\"p\":1,\"n\":\"Bool\"},{\"t\":7,\"p\":1,\"n\":\"Array of Object\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]}]},{\"t\":7,\"p\":1,\"n\":\"Array of String\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Int32\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Float\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Bool\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]}]}]}]}]},{\"t\":6,\"p\":1,\"n\":\"Script Fragments\",\"c\":[{\"t\":3,\"n\":\"Unknown\"},{\"t\":3,\"p\":1,\"n\":\"fragmentCount\"},{\"t\":2,\"p\":1,\"n\":\"fileName\"},{\"t\":7,\"p\":1,\"n\":\"Fragments\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Fragment\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Quest Stage\"},{\"t\":3,\"n\":\"Unknown\"},{\"t\":3,\"p\":1,\"n\":\"Quest Stage Index\"},{\"t\":2,\"p\":1,\"n\":\"scriptName\"},{\"t\":2,\"p\":1,\"n\":\"fragmentName\"}]}]}]},{\"t\":7,\"p\":1,\"n\":\"Aliases\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alias\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]},{\"t\":3,\"p\":1,\"n\":\"Version\"},{\"t\":3,\"p\":1,\"n\":\"Object Format\"},{\"t\":7,\"p\":1,\"n\":\"Alias Scripts\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Script\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"scriptName\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":7,\"p\":1,\"n\":\"Properties\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Property\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"propertyName\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]},{\"t\":2,\"p\":1,\"n\":\"String\"},{\"t\":3,\"p\":1,\"n\":\"Int32\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":3,\"p\":1,\"n\":\"Bool\"},{\"t\":7,\"p\":1,\"n\":\"Array of Object\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]}]},{\"t\":7,\"p\":1,\"n\":\"Array of String\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Int32\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Float\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Bool\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]}]}]}]}]}]}]}]},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DNAM - General\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":3,\"p\":1,\"n\":\"Priority\"},{\"t\":3,\"p\":1,\"n\":\"Form Version\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":3,\"p\":1,\"n\":\"Type\"}]},{\"t\":2,\"p\":1,\"n\":\"ENAM - Event\"},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Text Display Globals\",\"d\":1,\"c\":[{\"t\":3,\"p\":1,\"n\":\"QTGL - Global\"}]},{\"t\":2,\"p\":1,\"n\":\"FLTR - Object Window Filter\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Quest Dialogue Conditions\",\"c\":[{\"t\":8,\"p\":1,\"n\":\"Conditions\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Condition\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"CTDA - \",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":5,\"p\":1,\"n\":\"Comparison Value - Float\"},{\"t\":3,\"p\":1,\"n\":\"Comparison Value - Global\"},{\"t\":3,\"p\":1,\"n\":\"Function\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":11,\"p\":1,\"n\":\"None\"},{\"t\":3,\"p\":1,\"n\":\"Integer\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":11,\"p\":1,\"n\":\"Variable Name (unused)\"},{\"t\":3,\"p\":1,\"n\":\"Sex\"},{\"t\":3,\"p\":1,\"n\":\"Actor Value\"},{\"t\":3,\"p\":1,\"n\":\"Crime Type\"},{\"t\":3,\"p\":1,\"n\":\"Axis\"},{\"t\":3,\"p\":1,\"n\":\"Quest Stage (unused)\"},{\"t\":3,\"p\":1,\"n\":\"Misc Stat\"},{\"t\":3,\"p\":1,\"n\":\"Alignment\"},{\"t\":3,\"p\":1,\"n\":\"Equip Type\"},{\"t\":3,\"p\":1,\"n\":\"Form Type\"},{\"t\":3,\"p\":1,\"n\":\"Critical Stage\"},{\"t\":3,\"p\":1,\"n\":\"Object Reference\"},{\"t\":3,\"p\":1,\"n\":\"Inventory Object\"},{\"t\":3,\"p\":1,\"n\":\"Actor\"},{\"t\":3,\"p\":1,\"n\":\"Voice Type\"},{\"t\":3,\"p\":1,\"n\":\"Idle\"},{\"t\":3,\"p\":1,\"n\":\"Form List\"},{\"t\":3,\"p\":1,\"n\":\"Quest\"},{\"t\":3,\"p\":1,\"n\":\"Faction\"},{\"t\":3,\"p\":1,\"n\":\"Cell\"},{\"t\":3,\"p\":1,\"n\":\"Class\"},{\"t\":3,\"p\":1,\"n\":\"Race\"},{\"t\":3,\"p\":1,\"n\":\"Actor Base\"},{\"t\":3,\"p\":1,\"n\":\"Global\"},{\"t\":3,\"p\":1,\"n\":\"Weather\"},{\"t\":3,\"p\":1,\"n\":\"Package\"},{\"t\":3,\"p\":1,\"n\":\"Encounter Zone\"},{\"t\":3,\"p\":1,\"n\":\"Perk\"},{\"t\":3,\"p\":1,\"n\":\"Owner\"},{\"t\":3,\"p\":1,\"n\":\"Furniture\"},{\"t\":3,\"p\":1,\"n\":\"Effect Item\"},{\"t\":3,\"p\":1,\"n\":\"Base Effect\"},{\"t\":3,\"p\":1,\"n\":\"Worldspace\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Function\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Param (INVALID)\"},{\"t\":3,\"p\":1,\"n\":\"Referenceable Object\"},{\"t\":3,\"p\":1,\"n\":\"Region\"},{\"t\":3,\"p\":1,\"n\":\"Keyword\"},{\"t\":3,\"p\":1,\"n\":\"Player Action\"},{\"t\":3,\"p\":1,\"n\":\"Casting Type\"},{\"t\":3,\"p\":1,\"n\":\"Shout\"},{\"t\":3,\"p\":1,\"n\":\"Location\"},{\"t\":3,\"p\":1,\"n\":\"Location Ref Type\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"Packdata ID\"},{\"t\":3,\"p\":1,\"n\":\"Association Type\"},{\"t\":3,\"p\":1,\"n\":\"Furniture Anim\"},{\"t\":3,\"p\":1,\"n\":\"Furniture Entry\"},{\"t\":3,\"p\":1,\"n\":\"Scene\"},{\"t\":3,\"p\":1,\"n\":\"Ward State\"},{\"t\":3,\"p\":1,\"n\":\"Event\"},{\"t\":3,\"p\":1,\"n\":\"Event Data\"},{\"t\":3,\"p\":1,\"n\":\"Quest Stage\"},{\"t\":3,\"p\":1,\"n\":\"Weapon\"},{\"t\":3,\"p\":1,\"n\":\"Weapon List\"},{\"t\":3,\"p\":1,\"n\":\"Target\"},{\"t\":3,\"p\":1,\"n\":\"Target List\"},{\"t\":3,\"p\":1,\"n\":\"Target Part\"},{\"t\":3,\"p\":1,\"n\":\"VATS Action\"},{\"t\":3,\"p\":1,\"n\":\"Critical Effect\"},{\"t\":3,\"p\":1,\"n\":\"Critical Effect List\"},{\"t\":3,\"p\":1,\"n\":\"Weapon Type\"},{\"t\":3,\"p\":1,\"n\":\"Projectile Type\"},{\"t\":3,\"p\":1,\"n\":\"Delivery Type\"},{\"t\":3,\"p\":1,\"n\":\"Run On\"},{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":3,\"p\":1,\"n\":\"Parameter #3\"}]},{\"t\":2,\"p\":1,\"n\":\"CIS1 - Parameter #1\"},{\"t\":2,\"p\":1,\"n\":\"CIS2 - Parameter #2\"}]}]}]},{\"p\":1,\"n\":\"NEXT - Marker\"},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Conditions\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Condition\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"CTDA - \",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":5,\"p\":1,\"n\":\"Comparison Value - Float\"},{\"t\":3,\"p\":1,\"n\":\"Comparison Value - Global\"},{\"t\":3,\"p\":1,\"n\":\"Function\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":11,\"p\":1,\"n\":\"None\"},{\"t\":3,\"p\":1,\"n\":\"Integer\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":11,\"p\":1,\"n\":\"Variable Name (unused)\"},{\"t\":3,\"p\":1,\"n\":\"Sex\"},{\"t\":3,\"p\":1,\"n\":\"Actor Value\"},{\"t\":3,\"p\":1,\"n\":\"Crime Type\"},{\"t\":3,\"p\":1,\"n\":\"Axis\"},{\"t\":3,\"p\":1,\"n\":\"Quest Stage (unused)\"},{\"t\":3,\"p\":1,\"n\":\"Misc Stat\"},{\"t\":3,\"p\":1,\"n\":\"Alignment\"},{\"t\":3,\"p\":1,\"n\":\"Equip Type\"},{\"t\":3,\"p\":1,\"n\":\"Form Type\"},{\"t\":3,\"p\":1,\"n\":\"Critical Stage\"},{\"t\":3,\"p\":1,\"n\":\"Object Reference\"},{\"t\":3,\"p\":1,\"n\":\"Inventory Object\"},{\"t\":3,\"p\":1,\"n\":\"Actor\"},{\"t\":3,\"p\":1,\"n\":\"Voice Type\"},{\"t\":3,\"p\":1,\"n\":\"Idle\"},{\"t\":3,\"p\":1,\"n\":\"Form List\"},{\"t\":3,\"p\":1,\"n\":\"Quest\"},{\"t\":3,\"p\":1,\"n\":\"Faction\"},{\"t\":3,\"p\":1,\"n\":\"Cell\"},{\"t\":3,\"p\":1,\"n\":\"Class\"},{\"t\":3,\"p\":1,\"n\":\"Race\"},{\"t\":3,\"p\":1,\"n\":\"Actor Base\"},{\"t\":3,\"p\":1,\"n\":\"Global\"},{\"t\":3,\"p\":1,\"n\":\"Weather\"},{\"t\":3,\"p\":1,\"n\":\"Package\"},{\"t\":3,\"p\":1,\"n\":\"Encounter Zone\"},{\"t\":3,\"p\":1,\"n\":\"Perk\"},{\"t\":3,\"p\":1,\"n\":\"Owner\"},{\"t\":3,\"p\":1,\"n\":\"Furniture\"},{\"t\":3,\"p\":1,\"n\":\"Effect Item\"},{\"t\":3,\"p\":1,\"n\":\"Base Effect\"},{\"t\":3,\"p\":1,\"n\":\"Worldspace\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Function\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Param (INVALID)\"},{\"t\":3,\"p\":1,\"n\":\"Referenceable Object\"},{\"t\":3,\"p\":1,\"n\":\"Region\"},{\"t\":3,\"p\":1,\"n\":\"Keyword\"},{\"t\":3,\"p\":1,\"n\":\"Player Action\"},{\"t\":3,\"p\":1,\"n\":\"Casting Type\"},{\"t\":3,\"p\":1,\"n\":\"Shout\"},{\"t\":3,\"p\":1,\"n\":\"Location\"},{\"t\":3,\"p\":1,\"n\":\"Location Ref Type\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"Packdata ID\"},{\"t\":3,\"p\":1,\"n\":\"Association Type\"},{\"t\":3,\"p\":1,\"n\":\"Furniture Anim\"},{\"t\":3,\"p\":1,\"n\":\"Furniture Entry\"},{\"t\":3,\"p\":1,\"n\":\"Scene\"},{\"t\":3,\"p\":1,\"n\":\"Ward State\"},{\"t\":3,\"p\":1,\"n\":\"Event\"},{\"t\":3,\"p\":1,\"n\":\"Event Data\"},{\"t\":3,\"p\":1,\"n\":\"Quest Stage\"},{\"t\":3,\"p\":1,\"n\":\"Weapon\"},{\"t\":3,\"p\":1,\"n\":\"Weapon List\"},{\"t\":3,\"p\":1,\"n\":\"Target\"},{\"t\":3,\"p\":1,\"n\":\"Target List\"},{\"t\":3,\"p\":1,\"n\":\"Target Part\"},{\"t\":3,\"p\":1,\"n\":\"VATS Action\"},{\"t\":3,\"p\":1,\"n\":\"Critical Effect\"},{\"t\":3,\"p\":1,\"n\":\"Critical Effect List\"},{\"t\":3,\"p\":1,\"n\":\"Weapon Type\"},{\"t\":3,\"p\":1,\"n\":\"Projectile Type\"},{\"t\":3,\"p\":1,\"n\":\"Delivery Type\"},{\"t\":3,\"p\":1,\"n\":\"Run On\"},{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":3,\"p\":1,\"n\":\"Parameter #3\"}]},{\"t\":2,\"p\":1,\"n\":\"CIS1 - Parameter #1\"},{\"t\":2,\"p\":1,\"n\":\"CIS2 - Parameter #2\"}]}]},{\"t\":10,\"s\":1,\"p\":1,\"n\":\"Stages\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Stage\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"INDX - Stage Index\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Stage Index\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":3,\"n\":\"Unknown\"}]},{\"t\":8,\"p\":1,\"n\":\"Log Entries\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Log Entry\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"QSDT - Stage Flags\"},{\"t\":8,\"p\":1,\"n\":\"Conditions\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Condition\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"CTDA - \",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":5,\"p\":1,\"n\":\"Comparison Value - Float\"},{\"t\":3,\"p\":1,\"n\":\"Comparison Value - Global\"},{\"t\":3,\"p\":1,\"n\":\"Function\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":11,\"p\":1,\"n\":\"None\"},{\"t\":3,\"p\":1,\"n\":\"Integer\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":11,\"p\":1,\"n\":\"Variable Name (unused)\"},{\"t\":3,\"p\":1,\"n\":\"Sex\"},{\"t\":3,\"p\":1,\"n\":\"Actor Value\"},{\"t\":3,\"p\":1,\"n\":\"Crime Type\"},{\"t\":3,\"p\":1,\"n\":\"Axis\"},{\"t\":3,\"p\":1,\"n\":\"Quest Stage (unused)\"},{\"t\":3,\"p\":1,\"n\":\"Misc Stat\"},{\"t\":3,\"p\":1,\"n\":\"Alignment\"},{\"t\":3,\"p\":1,\"n\":\"Equip Type\"},{\"t\":3,\"p\":1,\"n\":\"Form Type\"},{\"t\":3,\"p\":1,\"n\":\"Critical Stage\"},{\"t\":3,\"p\":1,\"n\":\"Object Reference\"},{\"t\":3,\"p\":1,\"n\":\"Inventory Object\"},{\"t\":3,\"p\":1,\"n\":\"Actor\"},{\"t\":3,\"p\":1,\"n\":\"Voice Type\"},{\"t\":3,\"p\":1,\"n\":\"Idle\"},{\"t\":3,\"p\":1,\"n\":\"Form List\"},{\"t\":3,\"p\":1,\"n\":\"Quest\"},{\"t\":3,\"p\":1,\"n\":\"Faction\"},{\"t\":3,\"p\":1,\"n\":\"Cell\"},{\"t\":3,\"p\":1,\"n\":\"Class\"},{\"t\":3,\"p\":1,\"n\":\"Race\"},{\"t\":3,\"p\":1,\"n\":\"Actor Base\"},{\"t\":3,\"p\":1,\"n\":\"Global\"},{\"t\":3,\"p\":1,\"n\":\"Weather\"},{\"t\":3,\"p\":1,\"n\":\"Package\"},{\"t\":3,\"p\":1,\"n\":\"Encounter Zone\"},{\"t\":3,\"p\":1,\"n\":\"Perk\"},{\"t\":3,\"p\":1,\"n\":\"Owner\"},{\"t\":3,\"p\":1,\"n\":\"Furniture\"},{\"t\":3,\"p\":1,\"n\":\"Effect Item\"},{\"t\":3,\"p\":1,\"n\":\"Base Effect\"},{\"t\":3,\"p\":1,\"n\":\"Worldspace\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Function\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Param (INVALID)\"},{\"t\":3,\"p\":1,\"n\":\"Referenceable Object\"},{\"t\":3,\"p\":1,\"n\":\"Region\"},{\"t\":3,\"p\":1,\"n\":\"Keyword\"},{\"t\":3,\"p\":1,\"n\":\"Player Action\"},{\"t\":3,\"p\":1,\"n\":\"Casting Type\"},{\"t\":3,\"p\":1,\"n\":\"Shout\"},{\"t\":3,\"p\":1,\"n\":\"Location\"},{\"t\":3,\"p\":1,\"n\":\"Location Ref Type\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"Packdata ID\"},{\"t\":3,\"p\":1,\"n\":\"Association Type\"},{\"t\":3,\"p\":1,\"n\":\"Furniture Anim\"},{\"t\":3,\"p\":1,\"n\":\"Furniture Entry\"},{\"t\":3,\"p\":1,\"n\":\"Scene\"},{\"t\":3,\"p\":1,\"n\":\"Ward State\"},{\"t\":3,\"p\":1,\"n\":\"Event\"},{\"t\":3,\"p\":1,\"n\":\"Event Data\"},{\"t\":3,\"p\":1,\"n\":\"Quest Stage\"},{\"t\":3,\"p\":1,\"n\":\"Weapon\"},{\"t\":3,\"p\":1,\"n\":\"Weapon List\"},{\"t\":3,\"p\":1,\"n\":\"Target\"},{\"t\":3,\"p\":1,\"n\":\"Target List\"},{\"t\":3,\"p\":1,\"n\":\"Target Part\"},{\"t\":3,\"p\":1,\"n\":\"VATS Action\"},{\"t\":3,\"p\":1,\"n\":\"Critical Effect\"},{\"t\":3,\"p\":1,\"n\":\"Critical Effect List\"},{\"t\":3,\"p\":1,\"n\":\"Weapon Type\"},{\"t\":3,\"p\":1,\"n\":\"Projectile Type\"},{\"t\":3,\"p\":1,\"n\":\"Delivery Type\"},{\"t\":3,\"p\":1,\"n\":\"Run On\"},{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":3,\"p\":1,\"n\":\"Parameter #3\"}]},{\"t\":2,\"p\":1,\"n\":\"CIS1 - Parameter #1\"},{\"t\":2,\"p\":1,\"n\":\"CIS2 - Parameter #2\"}]}]},{\"t\":2,\"p\":1,\"n\":\"CNAM - Log Entry\"},{\"t\":3,\"p\":1,\"n\":\"NAM0 - Next Quest\"},{\"t\":11,\"n\":\"SCHR - Unused\"},{\"t\":11,\"n\":\"SCTX - Unused\"},{\"t\":11,\"n\":\"QNAM - Unused\"}]}]}]}]},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Objectives\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Objective\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"QOBJ - Objective Index\"},{\"t\":3,\"p\":1,\"n\":\"FNAM - Flags\"},{\"t\":2,\"p\":1,\"n\":\"NNAM - Display Text\"},{\"t\":8,\"p\":1,\"n\":\"Targets\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Target\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"QSTA - Target\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":8,\"p\":1,\"n\":\"Conditions\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Condition\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"CTDA - \",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":5,\"p\":1,\"n\":\"Comparison Value - Float\"},{\"t\":3,\"p\":1,\"n\":\"Comparison Value - Global\"},{\"t\":3,\"p\":1,\"n\":\"Function\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":11,\"p\":1,\"n\":\"None\"},{\"t\":3,\"p\":1,\"n\":\"Integer\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":11,\"p\":1,\"n\":\"Variable Name (unused)\"},{\"t\":3,\"p\":1,\"n\":\"Sex\"},{\"t\":3,\"p\":1,\"n\":\"Actor Value\"},{\"t\":3,\"p\":1,\"n\":\"Crime Type\"},{\"t\":3,\"p\":1,\"n\":\"Axis\"},{\"t\":3,\"p\":1,\"n\":\"Quest Stage (unused)\"},{\"t\":3,\"p\":1,\"n\":\"Misc Stat\"},{\"t\":3,\"p\":1,\"n\":\"Alignment\"},{\"t\":3,\"p\":1,\"n\":\"Equip Type\"},{\"t\":3,\"p\":1,\"n\":\"Form Type\"},{\"t\":3,\"p\":1,\"n\":\"Critical Stage\"},{\"t\":3,\"p\":1,\"n\":\"Object Reference\"},{\"t\":3,\"p\":1,\"n\":\"Inventory Object\"},{\"t\":3,\"p\":1,\"n\":\"Actor\"},{\"t\":3,\"p\":1,\"n\":\"Voice Type\"},{\"t\":3,\"p\":1,\"n\":\"Idle\"},{\"t\":3,\"p\":1,\"n\":\"Form List\"},{\"t\":3,\"p\":1,\"n\":\"Quest\"},{\"t\":3,\"p\":1,\"n\":\"Faction\"},{\"t\":3,\"p\":1,\"n\":\"Cell\"},{\"t\":3,\"p\":1,\"n\":\"Class\"},{\"t\":3,\"p\":1,\"n\":\"Race\"},{\"t\":3,\"p\":1,\"n\":\"Actor Base\"},{\"t\":3,\"p\":1,\"n\":\"Global\"},{\"t\":3,\"p\":1,\"n\":\"Weather\"},{\"t\":3,\"p\":1,\"n\":\"Package\"},{\"t\":3,\"p\":1,\"n\":\"Encounter Zone\"},{\"t\":3,\"p\":1,\"n\":\"Perk\"},{\"t\":3,\"p\":1,\"n\":\"Owner\"},{\"t\":3,\"p\":1,\"n\":\"Furniture\"},{\"t\":3,\"p\":1,\"n\":\"Effect Item\"},{\"t\":3,\"p\":1,\"n\":\"Base Effect\"},{\"t\":3,\"p\":1,\"n\":\"Worldspace\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Function\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Param (INVALID)\"},{\"t\":3,\"p\":1,\"n\":\"Referenceable Object\"},{\"t\":3,\"p\":1,\"n\":\"Region\"},{\"t\":3,\"p\":1,\"n\":\"Keyword\"},{\"t\":3,\"p\":1,\"n\":\"Player Action\"},{\"t\":3,\"p\":1,\"n\":\"Casting Type\"},{\"t\":3,\"p\":1,\"n\":\"Shout\"},{\"t\":3,\"p\":1,\"n\":\"Location\"},{\"t\":3,\"p\":1,\"n\":\"Location Ref Type\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"Packdata ID\"},{\"t\":3,\"p\":1,\"n\":\"Association Type\"},{\"t\":3,\"p\":1,\"n\":\"Furniture Anim\"},{\"t\":3,\"p\":1,\"n\":\"Furniture Entry\"},{\"t\":3,\"p\":1,\"n\":\"Scene\"},{\"t\":3,\"p\":1,\"n\":\"Ward State\"},{\"t\":3,\"p\":1,\"n\":\"Event\"},{\"t\":3,\"p\":1,\"n\":\"Event Data\"},{\"t\":3,\"p\":1,\"n\":\"Quest Stage\"},{\"t\":3,\"p\":1,\"n\":\"Weapon\"},{\"t\":3,\"p\":1,\"n\":\"Weapon List\"},{\"t\":3,\"p\":1,\"n\":\"Target\"},{\"t\":3,\"p\":1,\"n\":\"Target List\"},{\"t\":3,\"p\":1,\"n\":\"Target Part\"},{\"t\":3,\"p\":1,\"n\":\"VATS Action\"},{\"t\":3,\"p\":1,\"n\":\"Critical Effect\"},{\"t\":3,\"p\":1,\"n\":\"Critical Effect List\"},{\"t\":3,\"p\":1,\"n\":\"Weapon Type\"},{\"t\":3,\"p\":1,\"n\":\"Projectile Type\"},{\"t\":3,\"p\":1,\"n\":\"Delivery Type\"},{\"t\":3,\"p\":1,\"n\":\"Run On\"},{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":3,\"p\":1,\"n\":\"Parameter #3\"}]},{\"t\":2,\"p\":1,\"n\":\"CIS1 - Parameter #1\"},{\"t\":2,\"p\":1,\"n\":\"CIS2 - Parameter #2\"}]}]}]}]}]}]},{\"t\":11,\"n\":\"ANAM - Aliases Marker\"},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Aliases\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alias\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"ALST - Reference Alias ID\"},{\"t\":2,\"p\":1,\"n\":\"ALID - Alias Name\"},{\"t\":6,\"p\":1,\"n\":\"FNAM - Alias Flags\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":3,\"p\":1,\"n\":\"Additional Flags\"}]},{\"t\":3,\"p\":1,\"n\":\"ALFI - Force Into Alias When Filled\"},{\"t\":3,\"p\":1,\"n\":\"ALFL - Specific Location\"},{\"t\":3,\"p\":1,\"n\":\"ALFR - Forced Reference\"},{\"t\":3,\"p\":1,\"n\":\"ALUA - Unique Actor\"},{\"t\":6,\"p\":1,\"n\":\"Location Alias Reference\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"ALFA - Alias\"},{\"t\":3,\"p\":1,\"n\":\"KNAM - Keyword\"},{\"t\":3,\"p\":1,\"n\":\"ALRT - Ref Type\"}]},{\"t\":6,\"p\":1,\"n\":\"External Alias Reference\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"ALEQ - Quest\"},{\"t\":3,\"p\":1,\"n\":\"ALEA - Alias\"}]},{\"t\":6,\"p\":1,\"n\":\"Create Reference to Object\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"ALCO - Object\"},{\"t\":6,\"p\":1,\"n\":\"ALCA - Alias\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"Create\"}]},{\"t\":3,\"p\":1,\"n\":\"ALCL - Level\"}]},{\"t\":6,\"p\":1,\"n\":\"Find Matching Reference Near Alias\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"ALNA - Alias\"},{\"t\":3,\"p\":1,\"n\":\"ALNT - Type\"}]},{\"t\":6,\"p\":1,\"n\":\"Find Matching Reference From Event\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"ALFE - From Event\"},{\"t\":11,\"p\":1,\"n\":\"ALFD - Event Data\"}]},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Conditions\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Condition\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"CTDA - \",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":5,\"p\":1,\"n\":\"Comparison Value - Float\"},{\"t\":3,\"p\":1,\"n\":\"Comparison Value - Global\"},{\"t\":3,\"p\":1,\"n\":\"Function\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":11,\"p\":1,\"n\":\"None\"},{\"t\":3,\"p\":1,\"n\":\"Integer\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":11,\"p\":1,\"n\":\"Variable Name (unused)\"},{\"t\":3,\"p\":1,\"n\":\"Sex\"},{\"t\":3,\"p\":1,\"n\":\"Actor Value\"},{\"t\":3,\"p\":1,\"n\":\"Crime Type\"},{\"t\":3,\"p\":1,\"n\":\"Axis\"},{\"t\":3,\"p\":1,\"n\":\"Quest Stage (unused)\"},{\"t\":3,\"p\":1,\"n\":\"Misc Stat\"},{\"t\":3,\"p\":1,\"n\":\"Alignment\"},{\"t\":3,\"p\":1,\"n\":\"Equip Type\"},{\"t\":3,\"p\":1,\"n\":\"Form Type\"},{\"t\":3,\"p\":1,\"n\":\"Critical Stage\"},{\"t\":3,\"p\":1,\"n\":\"Object Reference\"},{\"t\":3,\"p\":1,\"n\":\"Inventory Object\"},{\"t\":3,\"p\":1,\"n\":\"Actor\"},{\"t\":3,\"p\":1,\"n\":\"Voice Type\"},{\"t\":3,\"p\":1,\"n\":\"Idle\"},{\"t\":3,\"p\":1,\"n\":\"Form List\"},{\"t\":3,\"p\":1,\"n\":\"Quest\"},{\"t\":3,\"p\":1,\"n\":\"Faction\"},{\"t\":3,\"p\":1,\"n\":\"Cell\"},{\"t\":3,\"p\":1,\"n\":\"Class\"},{\"t\":3,\"p\":1,\"n\":\"Race\"},{\"t\":3,\"p\":1,\"n\":\"Actor Base\"},{\"t\":3,\"p\":1,\"n\":\"Global\"},{\"t\":3,\"p\":1,\"n\":\"Weather\"},{\"t\":3,\"p\":1,\"n\":\"Package\"},{\"t\":3,\"p\":1,\"n\":\"Encounter Zone\"},{\"t\":3,\"p\":1,\"n\":\"Perk\"},{\"t\":3,\"p\":1,\"n\":\"Owner\"},{\"t\":3,\"p\":1,\"n\":\"Furniture\"},{\"t\":3,\"p\":1,\"n\":\"Effect Item\"},{\"t\":3,\"p\":1,\"n\":\"Base Effect\"},{\"t\":3,\"p\":1,\"n\":\"Worldspace\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Function\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Param (INVALID)\"},{\"t\":3,\"p\":1,\"n\":\"Referenceable Object\"},{\"t\":3,\"p\":1,\"n\":\"Region\"},{\"t\":3,\"p\":1,\"n\":\"Keyword\"},{\"t\":3,\"p\":1,\"n\":\"Player Action\"},{\"t\":3,\"p\":1,\"n\":\"Casting Type\"},{\"t\":3,\"p\":1,\"n\":\"Shout\"},{\"t\":3,\"p\":1,\"n\":\"Location\"},{\"t\":3,\"p\":1,\"n\":\"Location Ref Type\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"Packdata ID\"},{\"t\":3,\"p\":1,\"n\":\"Association Type\"},{\"t\":3,\"p\":1,\"n\":\"Furniture Anim\"},{\"t\":3,\"p\":1,\"n\":\"Furniture Entry\"},{\"t\":3,\"p\":1,\"n\":\"Scene\"},{\"t\":3,\"p\":1,\"n\":\"Ward State\"},{\"t\":3,\"p\":1,\"n\":\"Event\"},{\"t\":3,\"p\":1,\"n\":\"Event Data\"},{\"t\":3,\"p\":1,\"n\":\"Quest Stage\"},{\"t\":3,\"p\":1,\"n\":\"Weapon\"},{\"t\":3,\"p\":1,\"n\":\"Weapon List\"},{\"t\":3,\"p\":1,\"n\":\"Target\"},{\"t\":3,\"p\":1,\"n\":\"Target List\"},{\"t\":3,\"p\":1,\"n\":\"Target Part\"},{\"t\":3,\"p\":1,\"n\":\"VATS Action\"},{\"t\":3,\"p\":1,\"n\":\"Critical Effect\"},{\"t\":3,\"p\":1,\"n\":\"Critical Effect List\"},{\"t\":3,\"p\":1,\"n\":\"Weapon Type\"},{\"t\":3,\"p\":1,\"n\":\"Projectile Type\"},{\"t\":3,\"p\":1,\"n\":\"Delivery Type\"},{\"t\":3,\"p\":1,\"n\":\"Run On\"},{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":3,\"p\":1,\"n\":\"Parameter #3\"}]},{\"t\":2,\"p\":1,\"n\":\"CIS1 - Parameter #1\"},{\"t\":2,\"p\":1,\"n\":\"CIS2 - Parameter #2\"}]}]},{\"t\":3,\"p\":1,\"n\":\"KSIZ - Keyword Count\"},{\"t\":7,\"p\":1,\"n\":\"KWDA - Keywords\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Keyword\"}]},{\"t\":3,\"p\":1,\"n\":\"COCT - Count\"},{\"t\":10,\"p\":1,\"n\":\"Items\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Item\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"CNTO - Item\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Item\"},{\"t\":3,\"p\":1,\"n\":\"Count\"}]},{\"t\":6,\"p\":1,\"n\":\"COED - Extra Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Owner\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Global Variable\"},{\"t\":3,\"p\":1,\"n\":\"Required Rank\"},{\"t\":5,\"p\":1,\"n\":\"Item Condition\"}]}]}]},{\"t\":3,\"p\":1,\"n\":\"SPOR - Spectator override package list\"},{\"t\":3,\"p\":1,\"n\":\"OCOR - Observe dead body override package list\"},{\"t\":3,\"p\":1,\"n\":\"GWOR - Guard warn override package list\"},{\"t\":3,\"p\":1,\"n\":\"ECOR - Combat override package list\"},{\"t\":3,\"p\":1,\"n\":\"ALDN - Display Name\"},{\"t\":8,\"p\":1,\"n\":\"Alias Spells\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"ALSP - Spell\"}]},{\"t\":8,\"p\":1,\"n\":\"Alias Factions\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"ALFC - Faction\"}]},{\"t\":8,\"p\":1,\"n\":\"Alias Package Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"ALPC - Package\"}]},{\"t\":3,\"p\":1,\"n\":\"VTCK - Voice Types\"},{\"p\":1,\"n\":\"ALED - Alias End\"}]}]},{\"t\":2,\"p\":1,\"n\":\"NNAM - Description\"},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Targets\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Target\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"QSTA - Target\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Target\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Conditions\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Condition\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"CTDA - \",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":5,\"p\":1,\"n\":\"Comparison Value - Float\"},{\"t\":3,\"p\":1,\"n\":\"Comparison Value - Global\"},{\"t\":3,\"p\":1,\"n\":\"Function\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":11,\"p\":1,\"n\":\"None\"},{\"t\":3,\"p\":1,\"n\":\"Integer\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":11,\"p\":1,\"n\":\"Variable Name (unused)\"},{\"t\":3,\"p\":1,\"n\":\"Sex\"},{\"t\":3,\"p\":1,\"n\":\"Actor Value\"},{\"t\":3,\"p\":1,\"n\":\"Crime Type\"},{\"t\":3,\"p\":1,\"n\":\"Axis\"},{\"t\":3,\"p\":1,\"n\":\"Quest Stage (unused)\"},{\"t\":3,\"p\":1,\"n\":\"Misc Stat\"},{\"t\":3,\"p\":1,\"n\":\"Alignment\"},{\"t\":3,\"p\":1,\"n\":\"Equip Type\"},{\"t\":3,\"p\":1,\"n\":\"Form Type\"},{\"t\":3,\"p\":1,\"n\":\"Critical Stage\"},{\"t\":3,\"p\":1,\"n\":\"Object Reference\"},{\"t\":3,\"p\":1,\"n\":\"Inventory Object\"},{\"t\":3,\"p\":1,\"n\":\"Actor\"},{\"t\":3,\"p\":1,\"n\":\"Voice Type\"},{\"t\":3,\"p\":1,\"n\":\"Idle\"},{\"t\":3,\"p\":1,\"n\":\"Form List\"},{\"t\":3,\"p\":1,\"n\":\"Quest\"},{\"t\":3,\"p\":1,\"n\":\"Faction\"},{\"t\":3,\"p\":1,\"n\":\"Cell\"},{\"t\":3,\"p\":1,\"n\":\"Class\"},{\"t\":3,\"p\":1,\"n\":\"Race\"},{\"t\":3,\"p\":1,\"n\":\"Actor Base\"},{\"t\":3,\"p\":1,\"n\":\"Global\"},{\"t\":3,\"p\":1,\"n\":\"Weather\"},{\"t\":3,\"p\":1,\"n\":\"Package\"},{\"t\":3,\"p\":1,\"n\":\"Encounter Zone\"},{\"t\":3,\"p\":1,\"n\":\"Perk\"},{\"t\":3,\"p\":1,\"n\":\"Owner\"},{\"t\":3,\"p\":1,\"n\":\"Furniture\"},{\"t\":3,\"p\":1,\"n\":\"Effect Item\"},{\"t\":3,\"p\":1,\"n\":\"Base Effect\"},{\"t\":3,\"p\":1,\"n\":\"Worldspace\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Function\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Param (INVALID)\"},{\"t\":3,\"p\":1,\"n\":\"Referenceable Object\"},{\"t\":3,\"p\":1,\"n\":\"Region\"},{\"t\":3,\"p\":1,\"n\":\"Keyword\"},{\"t\":3,\"p\":1,\"n\":\"Player Action\"},{\"t\":3,\"p\":1,\"n\":\"Casting Type\"},{\"t\":3,\"p\":1,\"n\":\"Shout\"},{\"t\":3,\"p\":1,\"n\":\"Location\"},{\"t\":3,\"p\":1,\"n\":\"Location Ref Type\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"Packdata ID\"},{\"t\":3,\"p\":1,\"n\":\"Association Type\"},{\"t\":3,\"p\":1,\"n\":\"Furniture Anim\"},{\"t\":3,\"p\":1,\"n\":\"Furniture Entry\"},{\"t\":3,\"p\":1,\"n\":\"Scene\"},{\"t\":3,\"p\":1,\"n\":\"Ward State\"},{\"t\":3,\"p\":1,\"n\":\"Event\"},{\"t\":3,\"p\":1,\"n\":\"Event Data\"},{\"t\":3,\"p\":1,\"n\":\"Quest Stage\"},{\"t\":3,\"p\":1,\"n\":\"Weapon\"},{\"t\":3,\"p\":1,\"n\":\"Weapon List\"},{\"t\":3,\"p\":1,\"n\":\"Target\"},{\"t\":3,\"p\":1,\"n\":\"Target List\"},{\"t\":3,\"p\":1,\"n\":\"Target Part\"},{\"t\":3,\"p\":1,\"n\":\"VATS Action\"},{\"t\":3,\"p\":1,\"n\":\"Critical Effect\"},{\"t\":3,\"p\":1,\"n\":\"Critical Effect List\"},{\"t\":3,\"p\":1,\"n\":\"Weapon Type\"},{\"t\":3,\"p\":1,\"n\":\"Projectile Type\"},{\"t\":3,\"p\":1,\"n\":\"Delivery Type\"},{\"t\":3,\"p\":1,\"n\":\"Run On\"},{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":3,\"p\":1,\"n\":\"Parameter #3\"}]},{\"t\":2,\"p\":1,\"n\":\"CIS1 - Parameter #1\"},{\"t\":2,\"p\":1,\"n\":\"CIS2 - Parameter #2\"}]}]}]}]}]},{\"t\":1,\"p\":1,\"n\":\"RACE - Race\",\"f\":1,\"c\":[{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":2,\"p\":1,\"n\":\"DESC - Description\"},{\"t\":3,\"n\":\"SPCT - Count\"},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Actor Effects\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"SPLO - Actor Effect\"}]},{\"t\":3,\"p\":1,\"n\":\"WNAM - Skin\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"BOD2 - Biped Body Template\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"First Person Flags\"},{\"t\":3,\"p\":1,\"n\":\"General Flags\"},{\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Armor Type\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"BODT - Body Template\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"First Person Flags\"},{\"t\":3,\"p\":1,\"n\":\"General Flags\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Armor Type\"}]},{\"t\":3,\"n\":\"KSIZ - Keyword Count\"},{\"t\":7,\"p\":1,\"n\":\"KWDA - Keywords\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Keyword\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DATA - \",\"c\":[{\"t\":7,\"p\":1,\"n\":\"Skill Boosts\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Skill Boost\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Skill\"},{\"t\":3,\"p\":1,\"n\":\"Boost\"}]}]},{\"t\":11,\"n\":\"Unknown\"},{\"t\":5,\"p\":1,\"n\":\"Male Height\"},{\"t\":5,\"p\":1,\"n\":\"Female Height\"},{\"t\":5,\"p\":1,\"n\":\"Male Weight\"},{\"t\":5,\"p\":1,\"n\":\"Female Weight\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":5,\"p\":1,\"n\":\"Starting Health\"},{\"t\":5,\"p\":1,\"n\":\"Starting Magicka\"},{\"t\":5,\"p\":1,\"n\":\"Starting Stamina\"},{\"t\":5,\"p\":1,\"n\":\"Base Carry Weight\"},{\"t\":5,\"p\":1,\"n\":\"Base Mass\"},{\"t\":5,\"p\":1,\"n\":\"Acceleration rate\"},{\"t\":5,\"p\":1,\"n\":\"Deceleration rate\"},{\"t\":3,\"p\":1,\"n\":\"Size\"},{\"t\":3,\"p\":1,\"n\":\"Head Biped Object\"},{\"t\":3,\"p\":1,\"n\":\"Hair Biped Object\"},{\"t\":5,\"p\":1,\"n\":\"Injured Health Pct\"},{\"t\":3,\"p\":1,\"n\":\"Shield Biped Object\"},{\"t\":5,\"p\":1,\"n\":\"Health Regen\"},{\"t\":5,\"p\":1,\"n\":\"Magicka Regen\"},{\"t\":5,\"p\":1,\"n\":\"Stamina Regen\"},{\"t\":5,\"p\":1,\"n\":\"Unarmed Damage\"},{\"t\":5,\"p\":1,\"n\":\"Unarmed Reach\"},{\"t\":3,\"p\":1,\"n\":\"Body Biped Object\"},{\"t\":5,\"p\":1,\"n\":\"Aim Angle Tolerance\"},{\"t\":5,\"p\":1,\"n\":\"Flight Radius\"},{\"t\":5,\"p\":1,\"n\":\"Angular Acceleration Rate\"},{\"t\":5,\"p\":1,\"n\":\"Angular Tolerance\"},{\"t\":3,\"p\":1,\"n\":\"Flags 2\"},{\"t\":6,\"p\":1,\"n\":\"Mount Data\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Offset X\"},{\"t\":5,\"p\":1,\"n\":\"Offset Y\"},{\"t\":5,\"p\":1,\"n\":\"Unknown\"}]}]},{\"p\":1,\"n\":\"MNAM - Male Marker\"},{\"t\":2,\"p\":1,\"n\":\"ANAM - Male Skeletal Model\"},{\"t\":11,\"p\":1,\"n\":\"MODT - Texture Files Hashes\"},{\"p\":1,\"n\":\"FNAM - Female Marker\"},{\"t\":2,\"p\":1,\"n\":\"ANAM - Female Skeletal Model\"},{\"p\":1,\"n\":\"NAM2 - Marker NAM2 #1\"},{\"t\":8,\"p\":1,\"n\":\"Movement Type Names\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MTNM - Name\"}]},{\"t\":7,\"p\":1,\"n\":\"VTCK - Voices\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Voice\"}]},{\"t\":7,\"p\":1,\"n\":\"DNAM - Decapitate Armors\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Decapitate Armor\"}]},{\"t\":7,\"p\":1,\"n\":\"HCLF - Default Hair Colors\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Default Hair Color\"}]},{\"t\":3,\"n\":\"TINL - Total Number of Tints in List\"},{\"t\":5,\"p\":1,\"n\":\"PNAM - FaceGen - Main clamp\"},{\"t\":5,\"p\":1,\"n\":\"UNAM - FaceGen - Face clamp\"},{\"t\":3,\"p\":1,\"n\":\"ATKR - Attack Race\"},{\"t\":10,\"p\":1,\"n\":\"Attacks\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Attack\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"ATKD - Attack Data\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Damage Mult\"},{\"t\":5,\"p\":1,\"n\":\"Attack Chance\"},{\"t\":3,\"p\":1,\"n\":\"Attack Spell\"},{\"t\":3,\"p\":1,\"n\":\"Attack Flags\"},{\"t\":5,\"p\":1,\"n\":\"Attack Angle\"},{\"t\":5,\"p\":1,\"n\":\"Strike Angle\"},{\"t\":5,\"p\":1,\"n\":\"Stagger\"},{\"t\":3,\"p\":1,\"n\":\"Attack Type\"},{\"t\":5,\"p\":1,\"n\":\"Knockdown\"},{\"t\":5,\"p\":1,\"n\":\"Recovery Time\"},{\"t\":5,\"p\":1,\"n\":\"Stamina Mult\"}]},{\"t\":2,\"p\":1,\"n\":\"ATKE - Attack Event\"}]}]},{\"t\":6,\"p\":1,\"n\":\"Body Data\",\"c\":[{\"n\":\"NAM1 - Body Data Marker\"},{\"t\":6,\"p\":1,\"n\":\"Male Body Data\",\"c\":[{\"n\":\"MNAM - Male Data Marker\"},{\"t\":10,\"s\":1,\"p\":1,\"n\":\"Parts\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Part\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"INDX - Index\"},{\"t\":6,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"MODT - Texture Files Hashes\"},{\"t\":7,\"p\":1,\"n\":\"MODS - Alternate Textures\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"3D Name\"},{\"t\":3,\"p\":1,\"n\":\"New Texture\"},{\"t\":3,\"p\":1,\"n\":\"3D Index\"}]}]}]}]}]}]},{\"t\":6,\"p\":1,\"n\":\"Female Body Data\",\"c\":[{\"n\":\"FNAM - Female Data Marker\"},{\"t\":10,\"s\":1,\"p\":1,\"n\":\"Parts\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Part\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"INDX - Index\"},{\"t\":6,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"MODT - Texture Files Hashes\"},{\"t\":7,\"p\":1,\"n\":\"MODS - Alternate Textures\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"3D Name\"},{\"t\":3,\"p\":1,\"n\":\"New Texture\"},{\"t\":3,\"p\":1,\"n\":\"3D Index\"}]}]}]}]}]}]}]},{\"t\":7,\"p\":1,\"n\":\"HNAM - Hairs\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Hair\"}]},{\"t\":7,\"p\":1,\"n\":\"ENAM - Eyes\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Eye\"}]},{\"t\":3,\"p\":1,\"n\":\"GNAM - Body Part Data\"},{\"p\":1,\"n\":\"NAM2 - Marker NAM2 #2\"},{\"p\":1,\"n\":\"NAM3 - Marker NAM3 #3\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Male Behavior Graph\",\"c\":[{\"p\":1,\"n\":\"MNAM - Male Data Marker\"},{\"t\":6,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"MODT - Texture Files Hashes\"},{\"t\":7,\"p\":1,\"n\":\"MODS - Alternate Textures\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"3D Name\"},{\"t\":3,\"p\":1,\"n\":\"New Texture\"},{\"t\":3,\"p\":1,\"n\":\"3D Index\"}]}]}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Female Behavior Graph\",\"c\":[{\"p\":1,\"n\":\"FNAM - Female Data Marker\"},{\"t\":6,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"MODT - Texture Files Hashes\"},{\"t\":7,\"p\":1,\"n\":\"MODS - Alternate Textures\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"3D Name\"},{\"t\":3,\"p\":1,\"n\":\"New Texture\"},{\"t\":3,\"p\":1,\"n\":\"3D Index\"}]}]}]}]},{\"t\":3,\"p\":1,\"n\":\"NAM4 - Material Type\"},{\"t\":3,\"p\":1,\"n\":\"NAM5 - Impact Data Set\"},{\"t\":3,\"p\":1,\"n\":\"NAM7 - Decapitation FX\"},{\"t\":3,\"p\":1,\"n\":\"ONAM - Open Loot Sound\"},{\"t\":3,\"p\":1,\"n\":\"LNAM - Close Loot Sound\"},{\"t\":8,\"p\":1,\"n\":\"Biped Object Names\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"NAME - Name\"}]},{\"t\":10,\"n\":\"Movement Types\",\"c\":[{\"t\":6,\"n\":\"Movement Types\",\"c\":[{\"t\":3,\"n\":\"MTYP - Movement Type\"},{\"t\":6,\"n\":\"SPED - Override Values\",\"c\":[{\"t\":5,\"n\":\"Left - Walk\"},{\"t\":5,\"n\":\"Left - Run\"},{\"t\":5,\"n\":\"Right - Walk\"},{\"t\":5,\"n\":\"Right - Run\"},{\"t\":5,\"n\":\"Forward - Walk\"},{\"t\":5,\"n\":\"Forward - Run\"},{\"t\":5,\"n\":\"Back - Walk\"},{\"t\":5,\"n\":\"Back - Run\"},{\"t\":5,\"n\":\"Rotate - Walk\"},{\"t\":5,\"n\":\"Unknown\"}]}]}]},{\"t\":3,\"n\":\"VNAM - Equipment Flags\"},{\"t\":8,\"p\":1,\"n\":\"Equip Slots\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"QNAM - Equip Slot\"}]},{\"t\":3,\"n\":\"UNES - Unarmed Equip Slot\"},{\"t\":8,\"n\":\"Phoneme Target Names\",\"c\":[{\"t\":2,\"n\":\"PHTN - Name\"}]},{\"t\":6,\"n\":\"FaceFX Phonemes\",\"c\":[{\"t\":6,\"n\":\"IY\",\"c\":[{\"t\":6,\"n\":\"PHWT - Phoneme Target Weight\",\"c\":[{\"t\":5,\"n\":\"Aah \\/ LipBigAah\"},{\"t\":5,\"n\":\"BigAah \\/ LipDST\"},{\"t\":5,\"n\":\"BMP \\/ LipEee\"},{\"t\":5,\"n\":\"ChJsh \\/ LipFV\"},{\"t\":5,\"n\":\"DST \\/ LipK\"},{\"t\":5,\"n\":\"Eee \\/ LipL\"},{\"t\":5,\"n\":\"Eh \\/ LipR\"},{\"t\":5,\"n\":\"FV \\/ LipTh\"},{\"t\":5,\"n\":\"I\"},{\"t\":5,\"n\":\"K\"},{\"t\":5,\"n\":\"N\"},{\"t\":5,\"n\":\"Oh\"},{\"t\":5,\"n\":\"OohQ\"},{\"t\":5,\"n\":\"R\"},{\"t\":5,\"n\":\"TH\"},{\"t\":5,\"n\":\"W\"}]}]},{\"t\":6,\"n\":\"IH\",\"c\":[{\"t\":6,\"n\":\"PHWT - Phoneme Target Weight\",\"c\":[{\"t\":5,\"n\":\"Aah \\/ LipBigAah\"},{\"t\":5,\"n\":\"BigAah \\/ LipDST\"},{\"t\":5,\"n\":\"BMP \\/ LipEee\"},{\"t\":5,\"n\":\"ChJsh \\/ LipFV\"},{\"t\":5,\"n\":\"DST \\/ LipK\"},{\"t\":5,\"n\":\"Eee \\/ LipL\"},{\"t\":5,\"n\":\"Eh \\/ LipR\"},{\"t\":5,\"n\":\"FV \\/ LipTh\"},{\"t\":5,\"n\":\"I\"},{\"t\":5,\"n\":\"K\"},{\"t\":5,\"n\":\"N\"},{\"t\":5,\"n\":\"Oh\"},{\"t\":5,\"n\":\"OohQ\"},{\"t\":5,\"n\":\"R\"},{\"t\":5,\"n\":\"TH\"},{\"t\":5,\"n\":\"W\"}]}]},{\"t\":6,\"n\":\"EH\",\"c\":[{\"t\":6,\"n\":\"PHWT - Phoneme Target Weight\",\"c\":[{\"t\":5,\"n\":\"Aah \\/ LipBigAah\"},{\"t\":5,\"n\":\"BigAah \\/ LipDST\"},{\"t\":5,\"n\":\"BMP \\/ LipEee\"},{\"t\":5,\"n\":\"ChJsh \\/ LipFV\"},{\"t\":5,\"n\":\"DST \\/ LipK\"},{\"t\":5,\"n\":\"Eee \\/ LipL\"},{\"t\":5,\"n\":\"Eh \\/ LipR\"},{\"t\":5,\"n\":\"FV \\/ LipTh\"},{\"t\":5,\"n\":\"I\"},{\"t\":5,\"n\":\"K\"},{\"t\":5,\"n\":\"N\"},{\"t\":5,\"n\":\"Oh\"},{\"t\":5,\"n\":\"OohQ\"},{\"t\":5,\"n\":\"R\"},{\"t\":5,\"n\":\"TH\"},{\"t\":5,\"n\":\"W\"}]}]},{\"t\":6,\"n\":\"EY\",\"c\":[{\"t\":6,\"n\":\"PHWT - Phoneme Target Weight\",\"c\":[{\"t\":5,\"n\":\"Aah \\/ LipBigAah\"},{\"t\":5,\"n\":\"BigAah \\/ LipDST\"},{\"t\":5,\"n\":\"BMP \\/ LipEee\"},{\"t\":5,\"n\":\"ChJsh \\/ LipFV\"},{\"t\":5,\"n\":\"DST \\/ LipK\"},{\"t\":5,\"n\":\"Eee \\/ LipL\"},{\"t\":5,\"n\":\"Eh \\/ LipR\"},{\"t\":5,\"n\":\"FV \\/ LipTh\"},{\"t\":5,\"n\":\"I\"},{\"t\":5,\"n\":\"K\"},{\"t\":5,\"n\":\"N\"},{\"t\":5,\"n\":\"Oh\"},{\"t\":5,\"n\":\"OohQ\"},{\"t\":5,\"n\":\"R\"},{\"t\":5,\"n\":\"TH\"},{\"t\":5,\"n\":\"W\"}]}]},{\"t\":6,\"n\":\"AE\",\"c\":[{\"t\":6,\"n\":\"PHWT - Phoneme Target Weight\",\"c\":[{\"t\":5,\"n\":\"Aah \\/ LipBigAah\"},{\"t\":5,\"n\":\"BigAah \\/ LipDST\"},{\"t\":5,\"n\":\"BMP \\/ LipEee\"},{\"t\":5,\"n\":\"ChJsh \\/ LipFV\"},{\"t\":5,\"n\":\"DST \\/ LipK\"},{\"t\":5,\"n\":\"Eee \\/ LipL\"},{\"t\":5,\"n\":\"Eh \\/ LipR\"},{\"t\":5,\"n\":\"FV \\/ LipTh\"},{\"t\":5,\"n\":\"I\"},{\"t\":5,\"n\":\"K\"},{\"t\":5,\"n\":\"N\"},{\"t\":5,\"n\":\"Oh\"},{\"t\":5,\"n\":\"OohQ\"},{\"t\":5,\"n\":\"R\"},{\"t\":5,\"n\":\"TH\"},{\"t\":5,\"n\":\"W\"}]}]},{\"t\":6,\"n\":\"AA\",\"c\":[{\"t\":6,\"n\":\"PHWT - Phoneme Target Weight\",\"c\":[{\"t\":5,\"n\":\"Aah \\/ LipBigAah\"},{\"t\":5,\"n\":\"BigAah \\/ LipDST\"},{\"t\":5,\"n\":\"BMP \\/ LipEee\"},{\"t\":5,\"n\":\"ChJsh \\/ LipFV\"},{\"t\":5,\"n\":\"DST \\/ LipK\"},{\"t\":5,\"n\":\"Eee \\/ LipL\"},{\"t\":5,\"n\":\"Eh \\/ LipR\"},{\"t\":5,\"n\":\"FV \\/ LipTh\"},{\"t\":5,\"n\":\"I\"},{\"t\":5,\"n\":\"K\"},{\"t\":5,\"n\":\"N\"},{\"t\":5,\"n\":\"Oh\"},{\"t\":5,\"n\":\"OohQ\"},{\"t\":5,\"n\":\"R\"},{\"t\":5,\"n\":\"TH\"},{\"t\":5,\"n\":\"W\"}]}]},{\"t\":6,\"n\":\"AW\",\"c\":[{\"t\":6,\"n\":\"PHWT - Phoneme Target Weight\",\"c\":[{\"t\":5,\"n\":\"Aah \\/ LipBigAah\"},{\"t\":5,\"n\":\"BigAah \\/ LipDST\"},{\"t\":5,\"n\":\"BMP \\/ LipEee\"},{\"t\":5,\"n\":\"ChJsh \\/ LipFV\"},{\"t\":5,\"n\":\"DST \\/ LipK\"},{\"t\":5,\"n\":\"Eee \\/ LipL\"},{\"t\":5,\"n\":\"Eh \\/ LipR\"},{\"t\":5,\"n\":\"FV \\/ LipTh\"},{\"t\":5,\"n\":\"I\"},{\"t\":5,\"n\":\"K\"},{\"t\":5,\"n\":\"N\"},{\"t\":5,\"n\":\"Oh\"},{\"t\":5,\"n\":\"OohQ\"},{\"t\":5,\"n\":\"R\"},{\"t\":5,\"n\":\"TH\"},{\"t\":5,\"n\":\"W\"}]}]},{\"t\":6,\"n\":\"AY\",\"c\":[{\"t\":6,\"n\":\"PHWT - Phoneme Target Weight\",\"c\":[{\"t\":5,\"n\":\"Aah \\/ LipBigAah\"},{\"t\":5,\"n\":\"BigAah \\/ LipDST\"},{\"t\":5,\"n\":\"BMP \\/ LipEee\"},{\"t\":5,\"n\":\"ChJsh \\/ LipFV\"},{\"t\":5,\"n\":\"DST \\/ LipK\"},{\"t\":5,\"n\":\"Eee \\/ LipL\"},{\"t\":5,\"n\":\"Eh \\/ LipR\"},{\"t\":5,\"n\":\"FV \\/ LipTh\"},{\"t\":5,\"n\":\"I\"},{\"t\":5,\"n\":\"K\"},{\"t\":5,\"n\":\"N\"},{\"t\":5,\"n\":\"Oh\"},{\"t\":5,\"n\":\"OohQ\"},{\"t\":5,\"n\":\"R\"},{\"t\":5,\"n\":\"TH\"},{\"t\":5,\"n\":\"W\"}]}]},{\"t\":6,\"n\":\"AH\",\"c\":[{\"t\":6,\"n\":\"PHWT - Phoneme Target Weight\",\"c\":[{\"t\":5,\"n\":\"Aah \\/ LipBigAah\"},{\"t\":5,\"n\":\"BigAah \\/ LipDST\"},{\"t\":5,\"n\":\"BMP \\/ LipEee\"},{\"t\":5,\"n\":\"ChJsh \\/ LipFV\"},{\"t\":5,\"n\":\"DST \\/ LipK\"},{\"t\":5,\"n\":\"Eee \\/ LipL\"},{\"t\":5,\"n\":\"Eh \\/ LipR\"},{\"t\":5,\"n\":\"FV \\/ LipTh\"},{\"t\":5,\"n\":\"I\"},{\"t\":5,\"n\":\"K\"},{\"t\":5,\"n\":\"N\"},{\"t\":5,\"n\":\"Oh\"},{\"t\":5,\"n\":\"OohQ\"},{\"t\":5,\"n\":\"R\"},{\"t\":5,\"n\":\"TH\"},{\"t\":5,\"n\":\"W\"}]}]},{\"t\":6,\"n\":\"AO\",\"c\":[{\"t\":6,\"n\":\"PHWT - Phoneme Target Weight\",\"c\":[{\"t\":5,\"n\":\"Aah \\/ LipBigAah\"},{\"t\":5,\"n\":\"BigAah \\/ LipDST\"},{\"t\":5,\"n\":\"BMP \\/ LipEee\"},{\"t\":5,\"n\":\"ChJsh \\/ LipFV\"},{\"t\":5,\"n\":\"DST \\/ LipK\"},{\"t\":5,\"n\":\"Eee \\/ LipL\"},{\"t\":5,\"n\":\"Eh \\/ LipR\"},{\"t\":5,\"n\":\"FV \\/ LipTh\"},{\"t\":5,\"n\":\"I\"},{\"t\":5,\"n\":\"K\"},{\"t\":5,\"n\":\"N\"},{\"t\":5,\"n\":\"Oh\"},{\"t\":5,\"n\":\"OohQ\"},{\"t\":5,\"n\":\"R\"},{\"t\":5,\"n\":\"TH\"},{\"t\":5,\"n\":\"W\"}]}]},{\"t\":6,\"n\":\"OY\",\"c\":[{\"t\":6,\"n\":\"PHWT - Phoneme Target Weight\",\"c\":[{\"t\":5,\"n\":\"Aah \\/ LipBigAah\"},{\"t\":5,\"n\":\"BigAah \\/ LipDST\"},{\"t\":5,\"n\":\"BMP \\/ LipEee\"},{\"t\":5,\"n\":\"ChJsh \\/ LipFV\"},{\"t\":5,\"n\":\"DST \\/ LipK\"},{\"t\":5,\"n\":\"Eee \\/ LipL\"},{\"t\":5,\"n\":\"Eh \\/ LipR\"},{\"t\":5,\"n\":\"FV \\/ LipTh\"},{\"t\":5,\"n\":\"I\"},{\"t\":5,\"n\":\"K\"},{\"t\":5,\"n\":\"N\"},{\"t\":5,\"n\":\"Oh\"},{\"t\":5,\"n\":\"OohQ\"},{\"t\":5,\"n\":\"R\"},{\"t\":5,\"n\":\"TH\"},{\"t\":5,\"n\":\"W\"}]}]},{\"t\":6,\"n\":\"OW\",\"c\":[{\"t\":6,\"n\":\"PHWT - Phoneme Target Weight\",\"c\":[{\"t\":5,\"n\":\"Aah \\/ LipBigAah\"},{\"t\":5,\"n\":\"BigAah \\/ LipDST\"},{\"t\":5,\"n\":\"BMP \\/ LipEee\"},{\"t\":5,\"n\":\"ChJsh \\/ LipFV\"},{\"t\":5,\"n\":\"DST \\/ LipK\"},{\"t\":5,\"n\":\"Eee \\/ LipL\"},{\"t\":5,\"n\":\"Eh \\/ LipR\"},{\"t\":5,\"n\":\"FV \\/ LipTh\"},{\"t\":5,\"n\":\"I\"},{\"t\":5,\"n\":\"K\"},{\"t\":5,\"n\":\"N\"},{\"t\":5,\"n\":\"Oh\"},{\"t\":5,\"n\":\"OohQ\"},{\"t\":5,\"n\":\"R\"},{\"t\":5,\"n\":\"TH\"},{\"t\":5,\"n\":\"W\"}]}]},{\"t\":6,\"n\":\"UH\",\"c\":[{\"t\":6,\"n\":\"PHWT - Phoneme Target Weight\",\"c\":[{\"t\":5,\"n\":\"Aah \\/ LipBigAah\"},{\"t\":5,\"n\":\"BigAah \\/ LipDST\"},{\"t\":5,\"n\":\"BMP \\/ LipEee\"},{\"t\":5,\"n\":\"ChJsh \\/ LipFV\"},{\"t\":5,\"n\":\"DST \\/ LipK\"},{\"t\":5,\"n\":\"Eee \\/ LipL\"},{\"t\":5,\"n\":\"Eh \\/ LipR\"},{\"t\":5,\"n\":\"FV \\/ LipTh\"},{\"t\":5,\"n\":\"I\"},{\"t\":5,\"n\":\"K\"},{\"t\":5,\"n\":\"N\"},{\"t\":5,\"n\":\"Oh\"},{\"t\":5,\"n\":\"OohQ\"},{\"t\":5,\"n\":\"R\"},{\"t\":5,\"n\":\"TH\"},{\"t\":5,\"n\":\"W\"}]}]},{\"t\":6,\"n\":\"UW\",\"c\":[{\"t\":6,\"n\":\"PHWT - Phoneme Target Weight\",\"c\":[{\"t\":5,\"n\":\"Aah \\/ LipBigAah\"},{\"t\":5,\"n\":\"BigAah \\/ LipDST\"},{\"t\":5,\"n\":\"BMP \\/ LipEee\"},{\"t\":5,\"n\":\"ChJsh \\/ LipFV\"},{\"t\":5,\"n\":\"DST \\/ LipK\"},{\"t\":5,\"n\":\"Eee \\/ LipL\"},{\"t\":5,\"n\":\"Eh \\/ LipR\"},{\"t\":5,\"n\":\"FV \\/ LipTh\"},{\"t\":5,\"n\":\"I\"},{\"t\":5,\"n\":\"K\"},{\"t\":5,\"n\":\"N\"},{\"t\":5,\"n\":\"Oh\"},{\"t\":5,\"n\":\"OohQ\"},{\"t\":5,\"n\":\"R\"},{\"t\":5,\"n\":\"TH\"},{\"t\":5,\"n\":\"W\"}]}]},{\"t\":6,\"n\":\"ER\",\"c\":[{\"t\":6,\"n\":\"PHWT - Phoneme Target Weight\",\"c\":[{\"t\":5,\"n\":\"Aah \\/ LipBigAah\"},{\"t\":5,\"n\":\"BigAah \\/ LipDST\"},{\"t\":5,\"n\":\"BMP \\/ LipEee\"},{\"t\":5,\"n\":\"ChJsh \\/ LipFV\"},{\"t\":5,\"n\":\"DST \\/ LipK\"},{\"t\":5,\"n\":\"Eee \\/ LipL\"},{\"t\":5,\"n\":\"Eh \\/ LipR\"},{\"t\":5,\"n\":\"FV \\/ LipTh\"},{\"t\":5,\"n\":\"I\"},{\"t\":5,\"n\":\"K\"},{\"t\":5,\"n\":\"N\"},{\"t\":5,\"n\":\"Oh\"},{\"t\":5,\"n\":\"OohQ\"},{\"t\":5,\"n\":\"R\"},{\"t\":5,\"n\":\"TH\"},{\"t\":5,\"n\":\"W\"}]}]},{\"t\":6,\"n\":\"AX\",\"c\":[{\"t\":6,\"n\":\"PHWT - Phoneme Target Weight\",\"c\":[{\"t\":5,\"n\":\"Aah \\/ LipBigAah\"},{\"t\":5,\"n\":\"BigAah \\/ LipDST\"},{\"t\":5,\"n\":\"BMP \\/ LipEee\"},{\"t\":5,\"n\":\"ChJsh \\/ LipFV\"},{\"t\":5,\"n\":\"DST \\/ LipK\"},{\"t\":5,\"n\":\"Eee \\/ LipL\"},{\"t\":5,\"n\":\"Eh \\/ LipR\"},{\"t\":5,\"n\":\"FV \\/ LipTh\"},{\"t\":5,\"n\":\"I\"},{\"t\":5,\"n\":\"K\"},{\"t\":5,\"n\":\"N\"},{\"t\":5,\"n\":\"Oh\"},{\"t\":5,\"n\":\"OohQ\"},{\"t\":5,\"n\":\"R\"},{\"t\":5,\"n\":\"TH\"},{\"t\":5,\"n\":\"W\"}]}]},{\"t\":6,\"n\":\"S\",\"c\":[{\"t\":6,\"n\":\"PHWT - Phoneme Target Weight\",\"c\":[{\"t\":5,\"n\":\"Aah \\/ LipBigAah\"},{\"t\":5,\"n\":\"BigAah \\/ LipDST\"},{\"t\":5,\"n\":\"BMP \\/ LipEee\"},{\"t\":5,\"n\":\"ChJsh \\/ LipFV\"},{\"t\":5,\"n\":\"DST \\/ LipK\"},{\"t\":5,\"n\":\"Eee \\/ LipL\"},{\"t\":5,\"n\":\"Eh \\/ LipR\"},{\"t\":5,\"n\":\"FV \\/ LipTh\"},{\"t\":5,\"n\":\"I\"},{\"t\":5,\"n\":\"K\"},{\"t\":5,\"n\":\"N\"},{\"t\":5,\"n\":\"Oh\"},{\"t\":5,\"n\":\"OohQ\"},{\"t\":5,\"n\":\"R\"},{\"t\":5,\"n\":\"TH\"},{\"t\":5,\"n\":\"W\"}]}]},{\"t\":6,\"n\":\"SH\",\"c\":[{\"t\":6,\"n\":\"PHWT - Phoneme Target Weight\",\"c\":[{\"t\":5,\"n\":\"Aah \\/ LipBigAah\"},{\"t\":5,\"n\":\"BigAah \\/ LipDST\"},{\"t\":5,\"n\":\"BMP \\/ LipEee\"},{\"t\":5,\"n\":\"ChJsh \\/ LipFV\"},{\"t\":5,\"n\":\"DST \\/ LipK\"},{\"t\":5,\"n\":\"Eee \\/ LipL\"},{\"t\":5,\"n\":\"Eh \\/ LipR\"},{\"t\":5,\"n\":\"FV \\/ LipTh\"},{\"t\":5,\"n\":\"I\"},{\"t\":5,\"n\":\"K\"},{\"t\":5,\"n\":\"N\"},{\"t\":5,\"n\":\"Oh\"},{\"t\":5,\"n\":\"OohQ\"},{\"t\":5,\"n\":\"R\"},{\"t\":5,\"n\":\"TH\"},{\"t\":5,\"n\":\"W\"}]}]},{\"t\":6,\"n\":\"Z\",\"c\":[{\"t\":6,\"n\":\"PHWT - Phoneme Target Weight\",\"c\":[{\"t\":5,\"n\":\"Aah \\/ LipBigAah\"},{\"t\":5,\"n\":\"BigAah \\/ LipDST\"},{\"t\":5,\"n\":\"BMP \\/ LipEee\"},{\"t\":5,\"n\":\"ChJsh \\/ LipFV\"},{\"t\":5,\"n\":\"DST \\/ LipK\"},{\"t\":5,\"n\":\"Eee \\/ LipL\"},{\"t\":5,\"n\":\"Eh \\/ LipR\"},{\"t\":5,\"n\":\"FV \\/ LipTh\"},{\"t\":5,\"n\":\"I\"},{\"t\":5,\"n\":\"K\"},{\"t\":5,\"n\":\"N\"},{\"t\":5,\"n\":\"Oh\"},{\"t\":5,\"n\":\"OohQ\"},{\"t\":5,\"n\":\"R\"},{\"t\":5,\"n\":\"TH\"},{\"t\":5,\"n\":\"W\"}]}]},{\"t\":6,\"n\":\"ZH\",\"c\":[{\"t\":6,\"n\":\"PHWT - Phoneme Target Weight\",\"c\":[{\"t\":5,\"n\":\"Aah \\/ LipBigAah\"},{\"t\":5,\"n\":\"BigAah \\/ LipDST\"},{\"t\":5,\"n\":\"BMP \\/ LipEee\"},{\"t\":5,\"n\":\"ChJsh \\/ LipFV\"},{\"t\":5,\"n\":\"DST \\/ LipK\"},{\"t\":5,\"n\":\"Eee \\/ LipL\"},{\"t\":5,\"n\":\"Eh \\/ LipR\"},{\"t\":5,\"n\":\"FV \\/ LipTh\"},{\"t\":5,\"n\":\"I\"},{\"t\":5,\"n\":\"K\"},{\"t\":5,\"n\":\"N\"},{\"t\":5,\"n\":\"Oh\"},{\"t\":5,\"n\":\"OohQ\"},{\"t\":5,\"n\":\"R\"},{\"t\":5,\"n\":\"TH\"},{\"t\":5,\"n\":\"W\"}]}]},{\"t\":6,\"n\":\"F\",\"c\":[{\"t\":6,\"n\":\"PHWT - Phoneme Target Weight\",\"c\":[{\"t\":5,\"n\":\"Aah \\/ LipBigAah\"},{\"t\":5,\"n\":\"BigAah \\/ LipDST\"},{\"t\":5,\"n\":\"BMP \\/ LipEee\"},{\"t\":5,\"n\":\"ChJsh \\/ LipFV\"},{\"t\":5,\"n\":\"DST \\/ LipK\"},{\"t\":5,\"n\":\"Eee \\/ LipL\"},{\"t\":5,\"n\":\"Eh \\/ LipR\"},{\"t\":5,\"n\":\"FV \\/ LipTh\"},{\"t\":5,\"n\":\"I\"},{\"t\":5,\"n\":\"K\"},{\"t\":5,\"n\":\"N\"},{\"t\":5,\"n\":\"Oh\"},{\"t\":5,\"n\":\"OohQ\"},{\"t\":5,\"n\":\"R\"},{\"t\":5,\"n\":\"TH\"},{\"t\":5,\"n\":\"W\"}]}]},{\"t\":6,\"n\":\"TH\",\"c\":[{\"t\":6,\"n\":\"PHWT - Phoneme Target Weight\",\"c\":[{\"t\":5,\"n\":\"Aah \\/ LipBigAah\"},{\"t\":5,\"n\":\"BigAah \\/ LipDST\"},{\"t\":5,\"n\":\"BMP \\/ LipEee\"},{\"t\":5,\"n\":\"ChJsh \\/ LipFV\"},{\"t\":5,\"n\":\"DST \\/ LipK\"},{\"t\":5,\"n\":\"Eee \\/ LipL\"},{\"t\":5,\"n\":\"Eh \\/ LipR\"},{\"t\":5,\"n\":\"FV \\/ LipTh\"},{\"t\":5,\"n\":\"I\"},{\"t\":5,\"n\":\"K\"},{\"t\":5,\"n\":\"N\"},{\"t\":5,\"n\":\"Oh\"},{\"t\":5,\"n\":\"OohQ\"},{\"t\":5,\"n\":\"R\"},{\"t\":5,\"n\":\"TH\"},{\"t\":5,\"n\":\"W\"}]}]},{\"t\":6,\"n\":\"V\",\"c\":[{\"t\":6,\"n\":\"PHWT - Phoneme Target Weight\",\"c\":[{\"t\":5,\"n\":\"Aah \\/ LipBigAah\"},{\"t\":5,\"n\":\"BigAah \\/ LipDST\"},{\"t\":5,\"n\":\"BMP \\/ LipEee\"},{\"t\":5,\"n\":\"ChJsh \\/ LipFV\"},{\"t\":5,\"n\":\"DST \\/ LipK\"},{\"t\":5,\"n\":\"Eee \\/ LipL\"},{\"t\":5,\"n\":\"Eh \\/ LipR\"},{\"t\":5,\"n\":\"FV \\/ LipTh\"},{\"t\":5,\"n\":\"I\"},{\"t\":5,\"n\":\"K\"},{\"t\":5,\"n\":\"N\"},{\"t\":5,\"n\":\"Oh\"},{\"t\":5,\"n\":\"OohQ\"},{\"t\":5,\"n\":\"R\"},{\"t\":5,\"n\":\"TH\"},{\"t\":5,\"n\":\"W\"}]}]},{\"t\":6,\"n\":\"DH\",\"c\":[{\"t\":6,\"n\":\"PHWT - Phoneme Target Weight\",\"c\":[{\"t\":5,\"n\":\"Aah \\/ LipBigAah\"},{\"t\":5,\"n\":\"BigAah \\/ LipDST\"},{\"t\":5,\"n\":\"BMP \\/ LipEee\"},{\"t\":5,\"n\":\"ChJsh \\/ LipFV\"},{\"t\":5,\"n\":\"DST \\/ LipK\"},{\"t\":5,\"n\":\"Eee \\/ LipL\"},{\"t\":5,\"n\":\"Eh \\/ LipR\"},{\"t\":5,\"n\":\"FV \\/ LipTh\"},{\"t\":5,\"n\":\"I\"},{\"t\":5,\"n\":\"K\"},{\"t\":5,\"n\":\"N\"},{\"t\":5,\"n\":\"Oh\"},{\"t\":5,\"n\":\"OohQ\"},{\"t\":5,\"n\":\"R\"},{\"t\":5,\"n\":\"TH\"},{\"t\":5,\"n\":\"W\"}]}]},{\"t\":6,\"n\":\"M\",\"c\":[{\"t\":6,\"n\":\"PHWT - Phoneme Target Weight\",\"c\":[{\"t\":5,\"n\":\"Aah \\/ LipBigAah\"},{\"t\":5,\"n\":\"BigAah \\/ LipDST\"},{\"t\":5,\"n\":\"BMP \\/ LipEee\"},{\"t\":5,\"n\":\"ChJsh \\/ LipFV\"},{\"t\":5,\"n\":\"DST \\/ LipK\"},{\"t\":5,\"n\":\"Eee \\/ LipL\"},{\"t\":5,\"n\":\"Eh \\/ LipR\"},{\"t\":5,\"n\":\"FV \\/ LipTh\"},{\"t\":5,\"n\":\"I\"},{\"t\":5,\"n\":\"K\"},{\"t\":5,\"n\":\"N\"},{\"t\":5,\"n\":\"Oh\"},{\"t\":5,\"n\":\"OohQ\"},{\"t\":5,\"n\":\"R\"},{\"t\":5,\"n\":\"TH\"},{\"t\":5,\"n\":\"W\"}]}]},{\"t\":6,\"n\":\"N\",\"c\":[{\"t\":6,\"n\":\"PHWT - Phoneme Target Weight\",\"c\":[{\"t\":5,\"n\":\"Aah \\/ LipBigAah\"},{\"t\":5,\"n\":\"BigAah \\/ LipDST\"},{\"t\":5,\"n\":\"BMP \\/ LipEee\"},{\"t\":5,\"n\":\"ChJsh \\/ LipFV\"},{\"t\":5,\"n\":\"DST \\/ LipK\"},{\"t\":5,\"n\":\"Eee \\/ LipL\"},{\"t\":5,\"n\":\"Eh \\/ LipR\"},{\"t\":5,\"n\":\"FV \\/ LipTh\"},{\"t\":5,\"n\":\"I\"},{\"t\":5,\"n\":\"K\"},{\"t\":5,\"n\":\"N\"},{\"t\":5,\"n\":\"Oh\"},{\"t\":5,\"n\":\"OohQ\"},{\"t\":5,\"n\":\"R\"},{\"t\":5,\"n\":\"TH\"},{\"t\":5,\"n\":\"W\"}]}]},{\"t\":6,\"n\":\"NG\",\"c\":[{\"t\":6,\"n\":\"PHWT - Phoneme Target Weight\",\"c\":[{\"t\":5,\"n\":\"Aah \\/ LipBigAah\"},{\"t\":5,\"n\":\"BigAah \\/ LipDST\"},{\"t\":5,\"n\":\"BMP \\/ LipEee\"},{\"t\":5,\"n\":\"ChJsh \\/ LipFV\"},{\"t\":5,\"n\":\"DST \\/ LipK\"},{\"t\":5,\"n\":\"Eee \\/ LipL\"},{\"t\":5,\"n\":\"Eh \\/ LipR\"},{\"t\":5,\"n\":\"FV \\/ LipTh\"},{\"t\":5,\"n\":\"I\"},{\"t\":5,\"n\":\"K\"},{\"t\":5,\"n\":\"N\"},{\"t\":5,\"n\":\"Oh\"},{\"t\":5,\"n\":\"OohQ\"},{\"t\":5,\"n\":\"R\"},{\"t\":5,\"n\":\"TH\"},{\"t\":5,\"n\":\"W\"}]}]},{\"t\":6,\"n\":\"L\",\"c\":[{\"t\":6,\"n\":\"PHWT - Phoneme Target Weight\",\"c\":[{\"t\":5,\"n\":\"Aah \\/ LipBigAah\"},{\"t\":5,\"n\":\"BigAah \\/ LipDST\"},{\"t\":5,\"n\":\"BMP \\/ LipEee\"},{\"t\":5,\"n\":\"ChJsh \\/ LipFV\"},{\"t\":5,\"n\":\"DST \\/ LipK\"},{\"t\":5,\"n\":\"Eee \\/ LipL\"},{\"t\":5,\"n\":\"Eh \\/ LipR\"},{\"t\":5,\"n\":\"FV \\/ LipTh\"},{\"t\":5,\"n\":\"I\"},{\"t\":5,\"n\":\"K\"},{\"t\":5,\"n\":\"N\"},{\"t\":5,\"n\":\"Oh\"},{\"t\":5,\"n\":\"OohQ\"},{\"t\":5,\"n\":\"R\"},{\"t\":5,\"n\":\"TH\"},{\"t\":5,\"n\":\"W\"}]}]},{\"t\":6,\"n\":\"R\",\"c\":[{\"t\":6,\"n\":\"PHWT - Phoneme Target Weight\",\"c\":[{\"t\":5,\"n\":\"Aah \\/ LipBigAah\"},{\"t\":5,\"n\":\"BigAah \\/ LipDST\"},{\"t\":5,\"n\":\"BMP \\/ LipEee\"},{\"t\":5,\"n\":\"ChJsh \\/ LipFV\"},{\"t\":5,\"n\":\"DST \\/ LipK\"},{\"t\":5,\"n\":\"Eee \\/ LipL\"},{\"t\":5,\"n\":\"Eh \\/ LipR\"},{\"t\":5,\"n\":\"FV \\/ LipTh\"},{\"t\":5,\"n\":\"I\"},{\"t\":5,\"n\":\"K\"},{\"t\":5,\"n\":\"N\"},{\"t\":5,\"n\":\"Oh\"},{\"t\":5,\"n\":\"OohQ\"},{\"t\":5,\"n\":\"R\"},{\"t\":5,\"n\":\"TH\"},{\"t\":5,\"n\":\"W\"}]}]},{\"t\":6,\"n\":\"W\",\"c\":[{\"t\":6,\"n\":\"PHWT - Phoneme Target Weight\",\"c\":[{\"t\":5,\"n\":\"Aah \\/ LipBigAah\"},{\"t\":5,\"n\":\"BigAah \\/ LipDST\"},{\"t\":5,\"n\":\"BMP \\/ LipEee\"},{\"t\":5,\"n\":\"ChJsh \\/ LipFV\"},{\"t\":5,\"n\":\"DST \\/ LipK\"},{\"t\":5,\"n\":\"Eee \\/ LipL\"},{\"t\":5,\"n\":\"Eh \\/ LipR\"},{\"t\":5,\"n\":\"FV \\/ LipTh\"},{\"t\":5,\"n\":\"I\"},{\"t\":5,\"n\":\"K\"},{\"t\":5,\"n\":\"N\"},{\"t\":5,\"n\":\"Oh\"},{\"t\":5,\"n\":\"OohQ\"},{\"t\":5,\"n\":\"R\"},{\"t\":5,\"n\":\"TH\"},{\"t\":5,\"n\":\"W\"}]}]},{\"t\":6,\"n\":\"Y\",\"c\":[{\"t\":6,\"n\":\"PHWT - Phoneme Target Weight\",\"c\":[{\"t\":5,\"n\":\"Aah \\/ LipBigAah\"},{\"t\":5,\"n\":\"BigAah \\/ LipDST\"},{\"t\":5,\"n\":\"BMP \\/ LipEee\"},{\"t\":5,\"n\":\"ChJsh \\/ LipFV\"},{\"t\":5,\"n\":\"DST \\/ LipK\"},{\"t\":5,\"n\":\"Eee \\/ LipL\"},{\"t\":5,\"n\":\"Eh \\/ LipR\"},{\"t\":5,\"n\":\"FV \\/ LipTh\"},{\"t\":5,\"n\":\"I\"},{\"t\":5,\"n\":\"K\"},{\"t\":5,\"n\":\"N\"},{\"t\":5,\"n\":\"Oh\"},{\"t\":5,\"n\":\"OohQ\"},{\"t\":5,\"n\":\"R\"},{\"t\":5,\"n\":\"TH\"},{\"t\":5,\"n\":\"W\"}]}]},{\"t\":6,\"n\":\"HH\",\"c\":[{\"t\":6,\"n\":\"PHWT - Phoneme Target Weight\",\"c\":[{\"t\":5,\"n\":\"Aah \\/ LipBigAah\"},{\"t\":5,\"n\":\"BigAah \\/ LipDST\"},{\"t\":5,\"n\":\"BMP \\/ LipEee\"},{\"t\":5,\"n\":\"ChJsh \\/ LipFV\"},{\"t\":5,\"n\":\"DST \\/ LipK\"},{\"t\":5,\"n\":\"Eee \\/ LipL\"},{\"t\":5,\"n\":\"Eh \\/ LipR\"},{\"t\":5,\"n\":\"FV \\/ LipTh\"},{\"t\":5,\"n\":\"I\"},{\"t\":5,\"n\":\"K\"},{\"t\":5,\"n\":\"N\"},{\"t\":5,\"n\":\"Oh\"},{\"t\":5,\"n\":\"OohQ\"},{\"t\":5,\"n\":\"R\"},{\"t\":5,\"n\":\"TH\"},{\"t\":5,\"n\":\"W\"}]}]},{\"t\":6,\"n\":\"B\",\"c\":[{\"t\":6,\"n\":\"PHWT - Phoneme Target Weight\",\"c\":[{\"t\":5,\"n\":\"Aah \\/ LipBigAah\"},{\"t\":5,\"n\":\"BigAah \\/ LipDST\"},{\"t\":5,\"n\":\"BMP \\/ LipEee\"},{\"t\":5,\"n\":\"ChJsh \\/ LipFV\"},{\"t\":5,\"n\":\"DST \\/ LipK\"},{\"t\":5,\"n\":\"Eee \\/ LipL\"},{\"t\":5,\"n\":\"Eh \\/ LipR\"},{\"t\":5,\"n\":\"FV \\/ LipTh\"},{\"t\":5,\"n\":\"I\"},{\"t\":5,\"n\":\"K\"},{\"t\":5,\"n\":\"N\"},{\"t\":5,\"n\":\"Oh\"},{\"t\":5,\"n\":\"OohQ\"},{\"t\":5,\"n\":\"R\"},{\"t\":5,\"n\":\"TH\"},{\"t\":5,\"n\":\"W\"}]}]},{\"t\":6,\"n\":\"D\",\"c\":[{\"t\":6,\"n\":\"PHWT - Phoneme Target Weight\",\"c\":[{\"t\":5,\"n\":\"Aah \\/ LipBigAah\"},{\"t\":5,\"n\":\"BigAah \\/ LipDST\"},{\"t\":5,\"n\":\"BMP \\/ LipEee\"},{\"t\":5,\"n\":\"ChJsh \\/ LipFV\"},{\"t\":5,\"n\":\"DST \\/ LipK\"},{\"t\":5,\"n\":\"Eee \\/ LipL\"},{\"t\":5,\"n\":\"Eh \\/ LipR\"},{\"t\":5,\"n\":\"FV \\/ LipTh\"},{\"t\":5,\"n\":\"I\"},{\"t\":5,\"n\":\"K\"},{\"t\":5,\"n\":\"N\"},{\"t\":5,\"n\":\"Oh\"},{\"t\":5,\"n\":\"OohQ\"},{\"t\":5,\"n\":\"R\"},{\"t\":5,\"n\":\"TH\"},{\"t\":5,\"n\":\"W\"}]}]},{\"t\":6,\"n\":\"JH\",\"c\":[{\"t\":6,\"n\":\"PHWT - Phoneme Target Weight\",\"c\":[{\"t\":5,\"n\":\"Aah \\/ LipBigAah\"},{\"t\":5,\"n\":\"BigAah \\/ LipDST\"},{\"t\":5,\"n\":\"BMP \\/ LipEee\"},{\"t\":5,\"n\":\"ChJsh \\/ LipFV\"},{\"t\":5,\"n\":\"DST \\/ LipK\"},{\"t\":5,\"n\":\"Eee \\/ LipL\"},{\"t\":5,\"n\":\"Eh \\/ LipR\"},{\"t\":5,\"n\":\"FV \\/ LipTh\"},{\"t\":5,\"n\":\"I\"},{\"t\":5,\"n\":\"K\"},{\"t\":5,\"n\":\"N\"},{\"t\":5,\"n\":\"Oh\"},{\"t\":5,\"n\":\"OohQ\"},{\"t\":5,\"n\":\"R\"},{\"t\":5,\"n\":\"TH\"},{\"t\":5,\"n\":\"W\"}]}]},{\"t\":6,\"n\":\"G\",\"c\":[{\"t\":6,\"n\":\"PHWT - Phoneme Target Weight\",\"c\":[{\"t\":5,\"n\":\"Aah \\/ LipBigAah\"},{\"t\":5,\"n\":\"BigAah \\/ LipDST\"},{\"t\":5,\"n\":\"BMP \\/ LipEee\"},{\"t\":5,\"n\":\"ChJsh \\/ LipFV\"},{\"t\":5,\"n\":\"DST \\/ LipK\"},{\"t\":5,\"n\":\"Eee \\/ LipL\"},{\"t\":5,\"n\":\"Eh \\/ LipR\"},{\"t\":5,\"n\":\"FV \\/ LipTh\"},{\"t\":5,\"n\":\"I\"},{\"t\":5,\"n\":\"K\"},{\"t\":5,\"n\":\"N\"},{\"t\":5,\"n\":\"Oh\"},{\"t\":5,\"n\":\"OohQ\"},{\"t\":5,\"n\":\"R\"},{\"t\":5,\"n\":\"TH\"},{\"t\":5,\"n\":\"W\"}]}]},{\"t\":6,\"n\":\"P\",\"c\":[{\"t\":6,\"n\":\"PHWT - Phoneme Target Weight\",\"c\":[{\"t\":5,\"n\":\"Aah \\/ LipBigAah\"},{\"t\":5,\"n\":\"BigAah \\/ LipDST\"},{\"t\":5,\"n\":\"BMP \\/ LipEee\"},{\"t\":5,\"n\":\"ChJsh \\/ LipFV\"},{\"t\":5,\"n\":\"DST \\/ LipK\"},{\"t\":5,\"n\":\"Eee \\/ LipL\"},{\"t\":5,\"n\":\"Eh \\/ LipR\"},{\"t\":5,\"n\":\"FV \\/ LipTh\"},{\"t\":5,\"n\":\"I\"},{\"t\":5,\"n\":\"K\"},{\"t\":5,\"n\":\"N\"},{\"t\":5,\"n\":\"Oh\"},{\"t\":5,\"n\":\"OohQ\"},{\"t\":5,\"n\":\"R\"},{\"t\":5,\"n\":\"TH\"},{\"t\":5,\"n\":\"W\"}]}]},{\"t\":6,\"n\":\"T\",\"c\":[{\"t\":6,\"n\":\"PHWT - Phoneme Target Weight\",\"c\":[{\"t\":5,\"n\":\"Aah \\/ LipBigAah\"},{\"t\":5,\"n\":\"BigAah \\/ LipDST\"},{\"t\":5,\"n\":\"BMP \\/ LipEee\"},{\"t\":5,\"n\":\"ChJsh \\/ LipFV\"},{\"t\":5,\"n\":\"DST \\/ LipK\"},{\"t\":5,\"n\":\"Eee \\/ LipL\"},{\"t\":5,\"n\":\"Eh \\/ LipR\"},{\"t\":5,\"n\":\"FV \\/ LipTh\"},{\"t\":5,\"n\":\"I\"},{\"t\":5,\"n\":\"K\"},{\"t\":5,\"n\":\"N\"},{\"t\":5,\"n\":\"Oh\"},{\"t\":5,\"n\":\"OohQ\"},{\"t\":5,\"n\":\"R\"},{\"t\":5,\"n\":\"TH\"},{\"t\":5,\"n\":\"W\"}]}]},{\"t\":6,\"n\":\"K\",\"c\":[{\"t\":6,\"n\":\"PHWT - Phoneme Target Weight\",\"c\":[{\"t\":5,\"n\":\"Aah \\/ LipBigAah\"},{\"t\":5,\"n\":\"BigAah \\/ LipDST\"},{\"t\":5,\"n\":\"BMP \\/ LipEee\"},{\"t\":5,\"n\":\"ChJsh \\/ LipFV\"},{\"t\":5,\"n\":\"DST \\/ LipK\"},{\"t\":5,\"n\":\"Eee \\/ LipL\"},{\"t\":5,\"n\":\"Eh \\/ LipR\"},{\"t\":5,\"n\":\"FV \\/ LipTh\"},{\"t\":5,\"n\":\"I\"},{\"t\":5,\"n\":\"K\"},{\"t\":5,\"n\":\"N\"},{\"t\":5,\"n\":\"Oh\"},{\"t\":5,\"n\":\"OohQ\"},{\"t\":5,\"n\":\"R\"},{\"t\":5,\"n\":\"TH\"},{\"t\":5,\"n\":\"W\"}]}]},{\"t\":6,\"n\":\"CH\",\"c\":[{\"t\":6,\"n\":\"PHWT - Phoneme Target Weight\",\"c\":[{\"t\":5,\"n\":\"Aah \\/ LipBigAah\"},{\"t\":5,\"n\":\"BigAah \\/ LipDST\"},{\"t\":5,\"n\":\"BMP \\/ LipEee\"},{\"t\":5,\"n\":\"ChJsh \\/ LipFV\"},{\"t\":5,\"n\":\"DST \\/ LipK\"},{\"t\":5,\"n\":\"Eee \\/ LipL\"},{\"t\":5,\"n\":\"Eh \\/ LipR\"},{\"t\":5,\"n\":\"FV \\/ LipTh\"},{\"t\":5,\"n\":\"I\"},{\"t\":5,\"n\":\"K\"},{\"t\":5,\"n\":\"N\"},{\"t\":5,\"n\":\"Oh\"},{\"t\":5,\"n\":\"OohQ\"},{\"t\":5,\"n\":\"R\"},{\"t\":5,\"n\":\"TH\"},{\"t\":5,\"n\":\"W\"}]}]},{\"t\":6,\"n\":\"SIL\",\"c\":[{\"t\":6,\"n\":\"PHWT - Phoneme Target Weight\",\"c\":[{\"t\":5,\"n\":\"Aah \\/ LipBigAah\"},{\"t\":5,\"n\":\"BigAah \\/ LipDST\"},{\"t\":5,\"n\":\"BMP \\/ LipEee\"},{\"t\":5,\"n\":\"ChJsh \\/ LipFV\"},{\"t\":5,\"n\":\"DST \\/ LipK\"},{\"t\":5,\"n\":\"Eee \\/ LipL\"},{\"t\":5,\"n\":\"Eh \\/ LipR\"},{\"t\":5,\"n\":\"FV \\/ LipTh\"},{\"t\":5,\"n\":\"I\"},{\"t\":5,\"n\":\"K\"},{\"t\":5,\"n\":\"N\"},{\"t\":5,\"n\":\"Oh\"},{\"t\":5,\"n\":\"OohQ\"},{\"t\":5,\"n\":\"R\"},{\"t\":5,\"n\":\"TH\"},{\"t\":5,\"n\":\"W\"}]}]},{\"t\":6,\"n\":\"SHOTSIL\",\"c\":[{\"t\":6,\"n\":\"PHWT - Phoneme Target Weight\",\"c\":[{\"t\":5,\"n\":\"Aah \\/ LipBigAah\"},{\"t\":5,\"n\":\"BigAah \\/ LipDST\"},{\"t\":5,\"n\":\"BMP \\/ LipEee\"},{\"t\":5,\"n\":\"ChJsh \\/ LipFV\"},{\"t\":5,\"n\":\"DST \\/ LipK\"},{\"t\":5,\"n\":\"Eee \\/ LipL\"},{\"t\":5,\"n\":\"Eh \\/ LipR\"},{\"t\":5,\"n\":\"FV \\/ LipTh\"},{\"t\":5,\"n\":\"I\"},{\"t\":5,\"n\":\"K\"},{\"t\":5,\"n\":\"N\"},{\"t\":5,\"n\":\"Oh\"},{\"t\":5,\"n\":\"OohQ\"},{\"t\":5,\"n\":\"R\"},{\"t\":5,\"n\":\"TH\"},{\"t\":5,\"n\":\"W\"}]}]},{\"t\":6,\"n\":\"FLAP\",\"c\":[{\"t\":6,\"n\":\"PHWT - Phoneme Target Weight\",\"c\":[{\"t\":5,\"n\":\"Aah \\/ LipBigAah\"},{\"t\":5,\"n\":\"BigAah \\/ LipDST\"},{\"t\":5,\"n\":\"BMP \\/ LipEee\"},{\"t\":5,\"n\":\"ChJsh \\/ LipFV\"},{\"t\":5,\"n\":\"DST \\/ LipK\"},{\"t\":5,\"n\":\"Eee \\/ LipL\"},{\"t\":5,\"n\":\"Eh \\/ LipR\"},{\"t\":5,\"n\":\"FV \\/ LipTh\"},{\"t\":5,\"n\":\"I\"},{\"t\":5,\"n\":\"K\"},{\"t\":5,\"n\":\"N\"},{\"t\":5,\"n\":\"Oh\"},{\"t\":5,\"n\":\"OohQ\"},{\"t\":5,\"n\":\"R\"},{\"t\":5,\"n\":\"TH\"},{\"t\":5,\"n\":\"W\"}]}]}]},{\"t\":3,\"n\":\"WKMV - Base Movement Default - Walk\"},{\"t\":3,\"n\":\"RNMV - Base Movement Default - Run\"},{\"t\":3,\"n\":\"SWMV - Base Movement Default - Swim\"},{\"t\":3,\"n\":\"FLMV - Base Movement Default - Fly\"},{\"t\":3,\"n\":\"SNMV - Base Movement Default - Sneak\"},{\"t\":3,\"n\":\"SPMV - Base Movement Default - Sprint\"},{\"t\":6,\"p\":1,\"n\":\"Head Data\",\"c\":[{\"n\":\"NAM0 - Head Data Marker\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Male Head Data\",\"c\":[{\"p\":1,\"n\":\"MNAM - Male Data Marker\"},{\"t\":10,\"p\":1,\"n\":\"Head Parts\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Head Part\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"INDX - Head Part Number\"},{\"t\":3,\"p\":1,\"n\":\"HEAD - Head\"}]}]},{\"t\":6,\"n\":\"Available Morphs\",\"c\":[{\"t\":11,\"n\":\"MPAI - Unknown\"},{\"t\":6,\"n\":\"MPAV - Nose Variants\",\"c\":[{\"t\":3,\"n\":\"Nose Morph Flags\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":6,\"n\":\"MPAV - Brow Variants\",\"c\":[{\"t\":3,\"n\":\"Brow Morph Flags\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":6,\"n\":\"MPAV - Eye Variants\",\"c\":[{\"t\":3,\"n\":\"Eye Morph Flags 1\"},{\"t\":3,\"n\":\"Eye Morph Flags 2\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":6,\"n\":\"MPAV - Lip Variants\",\"c\":[{\"t\":3,\"n\":\"Lip Morph Flags\"},{\"t\":11,\"n\":\"Unknown\"}]}]},{\"t\":8,\"n\":\"Race Presets Male\",\"c\":[{\"t\":3,\"n\":\"RPRM - Preset NPC\"}]},{\"t\":8,\"n\":\"Available Hair Colors Male\",\"c\":[{\"t\":3,\"n\":\"AHCM - Hair Color\"}]},{\"t\":8,\"n\":\"Face Details Texture Set List Male\",\"c\":[{\"t\":3,\"n\":\"FTSM - Texture Set\"}]},{\"t\":3,\"n\":\"DFTM - Default Face Texture Male\"},{\"t\":8,\"p\":1,\"n\":\"Tint Masks\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Tint Assets\",\"c\":[{\"t\":8,\"p\":1,\"n\":\"Tint Layer\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Texture\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"TINI - Index\"},{\"t\":2,\"p\":1,\"n\":\"TINT - File Name\"},{\"t\":3,\"p\":1,\"n\":\"TINP - Mask Type\"},{\"t\":3,\"p\":1,\"n\":\"TIND - Preset Default\"}]}]},{\"t\":8,\"p\":1,\"n\":\"Presets\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Preset\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"TINC - Color\"},{\"t\":5,\"p\":1,\"n\":\"TINV - Default Value\"},{\"t\":3,\"p\":1,\"n\":\"TIRS - Index\"}]}]}]}]},{\"t\":6,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"MODT - Texture Files Hashes\"},{\"t\":7,\"p\":1,\"n\":\"MODS - Alternate Textures\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"3D Name\"},{\"t\":3,\"p\":1,\"n\":\"New Texture\"},{\"t\":3,\"p\":1,\"n\":\"3D Index\"}]}]}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Female Head Data\",\"c\":[{\"p\":1,\"n\":\"NAM0 - Head Data Marker\"},{\"p\":1,\"n\":\"FNAM - Female Data Marker\"},{\"t\":10,\"p\":1,\"n\":\"Head Parts\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Head Part\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"INDX - Head Part Number\"},{\"t\":3,\"p\":1,\"n\":\"HEAD - Head\"}]}]},{\"t\":6,\"n\":\"Available Morphs\",\"c\":[{\"t\":11,\"n\":\"MPAI - Unknown\"},{\"t\":6,\"n\":\"MPAV - Nose Variants\",\"c\":[{\"t\":3,\"n\":\"Nose Morph Flags\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":6,\"n\":\"MPAV - Brow Variants\",\"c\":[{\"t\":3,\"n\":\"Brow Morph Flags\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":6,\"n\":\"MPAV - Eye Variants\",\"c\":[{\"t\":3,\"n\":\"Eye Morph Flags 1\"},{\"t\":3,\"n\":\"Eye Morph Flags 2\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":6,\"n\":\"MPAV - Lip Variants\",\"c\":[{\"t\":3,\"n\":\"Lip Morph Flags\"},{\"t\":11,\"n\":\"Unknown\"}]}]},{\"t\":8,\"n\":\"Race Presets Female\",\"c\":[{\"t\":3,\"n\":\"RPRF - Preset NPC\"}]},{\"t\":8,\"n\":\"Available Hair Colors Female\",\"c\":[{\"t\":3,\"n\":\"AHCF - Hair Color\"}]},{\"t\":8,\"n\":\"Face Details Texture Set List Female\",\"c\":[{\"t\":3,\"n\":\"FTSF - Texture Set\"}]},{\"t\":3,\"n\":\"DFTF - Default Face Texture Female\"},{\"t\":8,\"p\":1,\"n\":\"Tint Masks\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Tint Assets\",\"c\":[{\"t\":8,\"p\":1,\"n\":\"Tint Layer\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Texture\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"TINI - Index\"},{\"t\":2,\"p\":1,\"n\":\"TINT - File Name\"},{\"t\":3,\"p\":1,\"n\":\"TINP - Mask Type\"},{\"t\":3,\"p\":1,\"n\":\"TIND - Preset Default\"}]}]},{\"t\":8,\"p\":1,\"n\":\"Presets\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Preset\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"TINC - Color\"},{\"t\":5,\"p\":1,\"n\":\"TINV - Default Value\"},{\"t\":3,\"p\":1,\"n\":\"TIRS - Index\"}]}]}]}]},{\"t\":6,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"MODT - Texture Files Hashes\"},{\"t\":7,\"p\":1,\"n\":\"MODS - Alternate Textures\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"3D Name\"},{\"t\":3,\"p\":1,\"n\":\"New Texture\"},{\"t\":3,\"p\":1,\"n\":\"3D Index\"}]}]}]}]}]},{\"t\":3,\"n\":\"NAM8 - Morph race\"},{\"t\":3,\"n\":\"RNAM - Armor race\"}]},{\"t\":1,\"p\":1,\"n\":\"REFR - Placed Object\",\"f\":1,\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"VMAD - Virtual Machine Adapter\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Version\"},{\"t\":3,\"p\":1,\"n\":\"Object Format\"},{\"t\":7,\"p\":1,\"n\":\"Scripts\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Script\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"scriptName\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":7,\"p\":1,\"n\":\"Properties\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Property\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"propertyName\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]},{\"t\":2,\"p\":1,\"n\":\"String\"},{\"t\":3,\"p\":1,\"n\":\"Int32\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":3,\"p\":1,\"n\":\"Bool\"},{\"t\":7,\"p\":1,\"n\":\"Array of Object\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]}]},{\"t\":7,\"p\":1,\"n\":\"Array of String\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Int32\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Float\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Bool\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]}]}]}]}]}]},{\"t\":3,\"p\":1,\"n\":\"NAME - Base\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"XMBO - Bound Half Extents\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"X\"},{\"t\":5,\"p\":1,\"n\":\"Y\"},{\"t\":5,\"p\":1,\"n\":\"Z\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"XPRM - Primitive\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Bounds\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"X\"},{\"t\":5,\"p\":1,\"n\":\"Y\"},{\"t\":5,\"p\":1,\"n\":\"Z\"}]},{\"t\":6,\"p\":1,\"n\":\"Color\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Red\"},{\"t\":5,\"p\":1,\"n\":\"Green\"},{\"t\":5,\"p\":1,\"n\":\"Blue\"}]},{\"t\":5,\"n\":\"Unknown\"},{\"t\":3,\"p\":1,\"n\":\"Type\"}]},{\"t\":11,\"n\":\"XORD - Unknown\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"XOCP - Occlusion Plane Data\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Size\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Width\"},{\"t\":5,\"p\":1,\"n\":\"Height\"}]},{\"t\":6,\"p\":1,\"n\":\"Position\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"X\"},{\"t\":5,\"p\":1,\"n\":\"Y\"},{\"t\":5,\"p\":1,\"n\":\"Z\"}]},{\"t\":6,\"p\":1,\"n\":\"Rotation (Quaternion?)\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"q1\"},{\"t\":5,\"p\":1,\"n\":\"q2\"},{\"t\":5,\"p\":1,\"n\":\"q3\"},{\"t\":5,\"p\":1,\"n\":\"q4\"}]}]},{\"t\":7,\"p\":1,\"n\":\"XPOD - Portal Data\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"References\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Origin\"},{\"t\":3,\"p\":1,\"n\":\"Destination\"}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"XPTL - Room Portal (unused)\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Size\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Width\"},{\"t\":5,\"p\":1,\"n\":\"Height\"}]},{\"t\":6,\"p\":1,\"n\":\"Position\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"X\"},{\"t\":5,\"p\":1,\"n\":\"Y\"},{\"t\":5,\"p\":1,\"n\":\"Z\"}]},{\"t\":6,\"p\":1,\"n\":\"Rotation (Quaternion?)\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"q1\"},{\"t\":5,\"p\":1,\"n\":\"q2\"},{\"t\":5,\"p\":1,\"n\":\"q3\"},{\"t\":5,\"p\":1,\"n\":\"q4\"}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Bound Data\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"XRMR - Header\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Linked Rooms Count\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":3,\"p\":1,\"n\":\"LNAM - Lighting Template\"},{\"t\":3,\"p\":1,\"n\":\"INAM - Image Space\"},{\"t\":8,\"p\":1,\"n\":\"Linked Rooms\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"XLRM - Linked Room\"}]}]},{\"p\":1,\"n\":\"XMBP - MultiBound Primitive Marker\"},{\"t\":11,\"n\":\"XRGD - Ragdoll Data\"},{\"t\":11,\"n\":\"XRGB - Ragdoll Biped Data\"},{\"t\":5,\"p\":1,\"n\":\"XRDS - Radius\"},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Reflected\\/Refracted By\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"XPWR - Water\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":3,\"p\":1,\"n\":\"Type\"}]}]},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Lit Water\",\"d\":1,\"c\":[{\"t\":3,\"p\":1,\"n\":\"XLTW - Water\"}]},{\"t\":3,\"p\":1,\"n\":\"XEMI - Emittance\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"XLIG - Light Data\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"FOV 90+\\/-\"},{\"t\":5,\"p\":1,\"n\":\"Fade 1.35+\\/-\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":5,\"p\":1,\"n\":\"Shadow Depth Bias\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"XALP - Alpha\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Cutoff\"},{\"t\":3,\"p\":1,\"n\":\"Base\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"XTEL - Teleport Destination\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Door\"},{\"t\":6,\"p\":1,\"n\":\"Position\\/Rotation\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Position\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"X\"},{\"t\":5,\"p\":1,\"n\":\"Y\"},{\"t\":5,\"p\":1,\"n\":\"Z\"}]},{\"t\":6,\"p\":1,\"n\":\"Rotation\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"X\"},{\"t\":5,\"p\":1,\"n\":\"Y\"},{\"t\":5,\"p\":1,\"n\":\"Z\"}]}]},{\"t\":3,\"p\":1,\"n\":\"Flags\"}]},{\"t\":3,\"p\":1,\"n\":\"XTNM - Teleport Message Box\"},{\"t\":3,\"p\":1,\"n\":\"XMBR - MultiBound Reference\"},{\"t\":11,\"n\":\"XWCN - Unknown\"},{\"t\":11,\"n\":\"XWCS - Unknown\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"XWCU - Water Velocity\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"X Offset\"},{\"t\":5,\"p\":1,\"n\":\"Y Offset\"},{\"t\":5,\"p\":1,\"n\":\"Z Offset\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":5,\"p\":1,\"n\":\"X Angle\"},{\"t\":5,\"p\":1,\"n\":\"Y Angle\"},{\"t\":5,\"p\":1,\"n\":\"Z Angle\"}]},{\"t\":6,\"n\":\"XCVL - Unknown\",\"c\":[{\"t\":11,\"n\":\"Unknown\"},{\"t\":5,\"n\":\"X Angle\"}]},{\"t\":3,\"n\":\"XCZR - Unknown\"},{\"t\":11,\"n\":\"XCZA - Unknown\"},{\"t\":3,\"n\":\"XCZC - Unknown\"},{\"t\":5,\"p\":1,\"n\":\"XSCL - Scale\"},{\"t\":3,\"p\":1,\"n\":\"XSPC - Spawn Container\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Activate Parents\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"XAPD - Flags\"},{\"t\":8,\"p\":1,\"n\":\"Activate Parent Refs\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"XAPR - Activate Parent Ref\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":5,\"p\":1,\"n\":\"Delay\"}]}]}]},{\"t\":3,\"p\":1,\"n\":\"XLIB - Leveled Item Base Object\"},{\"t\":3,\"p\":1,\"n\":\"XLCM - Level Modifier\"},{\"t\":3,\"p\":1,\"n\":\"XLCN - Persistent Location\"},{\"t\":3,\"p\":1,\"n\":\"XTRI - Collision Layer\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"XLOC - Lock Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Level\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Key\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"}]},{\"t\":3,\"p\":1,\"n\":\"XEZN - Encounter Zone\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"XNDP - Navigation Door Link\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Navigation Mesh\"},{\"t\":3,\"p\":1,\"n\":\"Teleport Marker Triangle\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":7,\"p\":1,\"n\":\"XLRT - Location Ref Type\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Ref\"}]},{\"p\":1,\"n\":\"XIS2 - Ignored by Sandbox\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Ownership\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"XOWN - Owner\"},{\"t\":3,\"p\":1,\"n\":\"XRNK - Faction rank\"}]},{\"t\":3,\"p\":1,\"n\":\"XCNT - Item Count\"},{\"t\":5,\"p\":1,\"n\":\"XCHG - Charge\"},{\"t\":3,\"p\":1,\"n\":\"XLRL - Location Reference\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"XESP - Enable Parent\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Linked References\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"XLKR - Linked Reference\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Keyword\\/Ref\"},{\"t\":3,\"p\":1,\"n\":\"Ref\"}]}]},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Patrol\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Data\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"XPRD - Idle Time\"},{\"p\":1,\"n\":\"XPPA - Patrol Script Marker\"},{\"t\":3,\"p\":1,\"n\":\"INAM - Idle\"},{\"t\":11,\"n\":\"SCHR - Unused\"},{\"t\":11,\"n\":\"SCTX - Unused\"},{\"t\":8,\"p\":1,\"n\":\"Topic\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"PDTO - Topic Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Topic\"},{\"t\":2,\"p\":1,\"n\":\"Subtype\"}]}]}]}]},{\"t\":3,\"p\":1,\"n\":\"XACT - Action Flag\"},{\"t\":5,\"p\":1,\"n\":\"XHTW - Head-Tracking Weight\"},{\"t\":5,\"p\":1,\"n\":\"XFVC - Favor Cost\"},{\"p\":1,\"n\":\"ONAM - Open by Default\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Map Marker\",\"c\":[{\"p\":1,\"n\":\"XMRK - Map Marker Data\"},{\"t\":3,\"p\":1,\"n\":\"FNAM - Map Flags\"},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":6,\"p\":1,\"n\":\"TNAM - \",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":11,\"n\":\"Unused\"}]}]},{\"t\":3,\"p\":1,\"n\":\"XATR - Attach Ref\"},{\"t\":7,\"n\":\"XLOD - Distant LOD Data\",\"c\":[{\"t\":5,\"n\":\"Unknown\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DATA - Position\\/Rotation\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Position\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"X\"},{\"t\":5,\"p\":1,\"n\":\"Y\"},{\"t\":5,\"p\":1,\"n\":\"Z\"}]},{\"t\":6,\"p\":1,\"n\":\"Rotation\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"X\"},{\"t\":5,\"p\":1,\"n\":\"Y\"},{\"t\":5,\"p\":1,\"n\":\"Z\"}]}]}]},{\"t\":1,\"p\":1,\"n\":\"REGN - Region\",\"f\":1,\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"RCLR - Map Color\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":3,\"p\":1,\"n\":\"WNAM - Worldspace\"},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Region Areas\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Region Area\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"RPLI - Edge Fall-off\"},{\"t\":7,\"p\":1,\"n\":\"RPLD - Region Point List Data\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Point\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"X\"},{\"t\":5,\"p\":1,\"n\":\"Y\"}]}]}]}]},{\"t\":10,\"p\":1,\"n\":\"Region Data Entries\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Region Data Entry\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"RDAT - Data Header\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":3,\"p\":1,\"n\":\"Priority\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":6,\"p\":1,\"n\":\"Icon\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"ICON - Large Icon filename\"},{\"t\":2,\"p\":1,\"n\":\"MICO - Small Icon filename\"}]},{\"t\":3,\"p\":1,\"n\":\"RDMO - Music\"},{\"t\":7,\"p\":1,\"n\":\"RDSA - Sounds\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Sound\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Sound\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":5,\"p\":1,\"n\":\"Chance\"}]}]},{\"t\":2,\"p\":1,\"n\":\"RDMP - Map Name\"},{\"t\":7,\"p\":1,\"n\":\"RDOT - Objects\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Object\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Object\"},{\"t\":3,\"p\":1,\"n\":\"Parent Index\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":5,\"p\":1,\"n\":\"Density\"},{\"t\":3,\"p\":1,\"n\":\"Clustering\"},{\"t\":3,\"p\":1,\"n\":\"Min Slope\"},{\"t\":3,\"p\":1,\"n\":\"Max Slope\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":3,\"p\":1,\"n\":\"Radius wrt Parent\"},{\"t\":3,\"p\":1,\"n\":\"Radius\"},{\"t\":5,\"p\":1,\"n\":\"Min Height\"},{\"t\":5,\"p\":1,\"n\":\"Max Height\"},{\"t\":5,\"p\":1,\"n\":\"Sink\"},{\"t\":5,\"p\":1,\"n\":\"Sink Variance\"},{\"t\":5,\"p\":1,\"n\":\"Size Variance\"},{\"t\":6,\"p\":1,\"n\":\"Angle Variance\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"X\"},{\"t\":3,\"p\":1,\"n\":\"Y\"},{\"t\":3,\"p\":1,\"n\":\"Z\"}]}]}]},{\"t\":7,\"p\":1,\"n\":\"RDGS - Grasses\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Grass\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Grass\"},{\"t\":11,\"n\":\"Unknown\"}]}]},{\"t\":7,\"p\":1,\"n\":\"RDWT - Weather Types\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Weather Type\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Weather\"},{\"t\":3,\"p\":1,\"n\":\"Chance\"},{\"t\":3,\"p\":1,\"n\":\"Global\"}]}]}]}]}]},{\"t\":1,\"p\":1,\"n\":\"RELA - Relationship\",\"f\":1,\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DATA - Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Parent\"},{\"t\":3,\"p\":1,\"n\":\"Child\"},{\"t\":3,\"p\":1,\"n\":\"Rank\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":3,\"p\":1,\"n\":\"Association Type\"}]}]},{\"t\":1,\"p\":1,\"n\":\"REVB - Reverb Parameters\",\"f\":1,\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DATA - Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Decay Time (ms)\"},{\"t\":3,\"p\":1,\"n\":\"HF Reference (Hz)\"},{\"t\":3,\"p\":1,\"n\":\"Room Filter\"},{\"t\":3,\"p\":1,\"n\":\"Room HF Filter\"},{\"t\":3,\"p\":1,\"n\":\"Reflections\"},{\"t\":3,\"p\":1,\"n\":\"Reverb Amp\"},{\"t\":3,\"p\":1,\"n\":\"Decay HF Ratio\"},{\"t\":3,\"p\":1,\"n\":\"Reflect Delay (ms), scaled\"},{\"t\":3,\"p\":1,\"n\":\"Reverb Delay (ms)\"},{\"t\":3,\"p\":1,\"n\":\"Diffusion %\"},{\"t\":3,\"p\":1,\"n\":\"Density %\"},{\"t\":3,\"n\":\"Unknown\"}]}]},{\"t\":1,\"p\":1,\"n\":\"RFCT - Visual Effect\",\"f\":1,\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DATA - Effect Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Effect Art\"},{\"t\":3,\"p\":1,\"n\":\"Shader\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"}]}]},{\"t\":1,\"p\":1,\"n\":\"RGDL\",\"f\":1,\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"}]},{\"t\":1,\"p\":1,\"n\":\"SCEN - Scene\",\"f\":1,\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"VMAD - Virtual Machine Adapter\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Version\"},{\"t\":3,\"p\":1,\"n\":\"Object Format\"},{\"t\":7,\"p\":1,\"n\":\"Scripts\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Script\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"scriptName\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":7,\"p\":1,\"n\":\"Properties\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Property\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"propertyName\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]},{\"t\":2,\"p\":1,\"n\":\"String\"},{\"t\":3,\"p\":1,\"n\":\"Int32\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":3,\"p\":1,\"n\":\"Bool\"},{\"t\":7,\"p\":1,\"n\":\"Array of Object\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]}]},{\"t\":7,\"p\":1,\"n\":\"Array of String\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Int32\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Float\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Bool\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]}]}]}]}]},{\"t\":6,\"p\":1,\"n\":\"Script Fragments\",\"c\":[{\"t\":3,\"n\":\"Unknown\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":2,\"p\":1,\"n\":\"fileName\"},{\"t\":7,\"p\":1,\"n\":\"Fragments\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Fragment\",\"c\":[{\"t\":3,\"n\":\"Unknown\"},{\"t\":2,\"p\":1,\"n\":\"scriptName\"},{\"t\":2,\"p\":1,\"n\":\"fragmentName\"}]}]},{\"t\":7,\"p\":1,\"n\":\"Phase Fragments\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Phase Fragment\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Phase Flag\"},{\"t\":3,\"p\":1,\"n\":\"Phase Index\"},{\"t\":3,\"n\":\"Unknown\"},{\"t\":2,\"p\":1,\"n\":\"scriptName\"},{\"t\":2,\"p\":1,\"n\":\"fragmentName\"}]}]}]}]},{\"t\":3,\"p\":1,\"n\":\"FNAM - Flags\"},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Phases\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Phase\",\"c\":[{\"p\":1,\"n\":\"HNAM - Marker Phase Start\"},{\"t\":2,\"p\":1,\"n\":\"NAM0 - Name\"},{\"t\":6,\"p\":1,\"n\":\"Start Conditions\",\"c\":[{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Conditions\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Condition\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"CTDA - \",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":5,\"p\":1,\"n\":\"Comparison Value - Float\"},{\"t\":3,\"p\":1,\"n\":\"Comparison Value - Global\"},{\"t\":3,\"p\":1,\"n\":\"Function\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":11,\"p\":1,\"n\":\"None\"},{\"t\":3,\"p\":1,\"n\":\"Integer\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":11,\"p\":1,\"n\":\"Variable Name (unused)\"},{\"t\":3,\"p\":1,\"n\":\"Sex\"},{\"t\":3,\"p\":1,\"n\":\"Actor Value\"},{\"t\":3,\"p\":1,\"n\":\"Crime Type\"},{\"t\":3,\"p\":1,\"n\":\"Axis\"},{\"t\":3,\"p\":1,\"n\":\"Quest Stage (unused)\"},{\"t\":3,\"p\":1,\"n\":\"Misc Stat\"},{\"t\":3,\"p\":1,\"n\":\"Alignment\"},{\"t\":3,\"p\":1,\"n\":\"Equip Type\"},{\"t\":3,\"p\":1,\"n\":\"Form Type\"},{\"t\":3,\"p\":1,\"n\":\"Critical Stage\"},{\"t\":3,\"p\":1,\"n\":\"Object Reference\"},{\"t\":3,\"p\":1,\"n\":\"Inventory Object\"},{\"t\":3,\"p\":1,\"n\":\"Actor\"},{\"t\":3,\"p\":1,\"n\":\"Voice Type\"},{\"t\":3,\"p\":1,\"n\":\"Idle\"},{\"t\":3,\"p\":1,\"n\":\"Form List\"},{\"t\":3,\"p\":1,\"n\":\"Quest\"},{\"t\":3,\"p\":1,\"n\":\"Faction\"},{\"t\":3,\"p\":1,\"n\":\"Cell\"},{\"t\":3,\"p\":1,\"n\":\"Class\"},{\"t\":3,\"p\":1,\"n\":\"Race\"},{\"t\":3,\"p\":1,\"n\":\"Actor Base\"},{\"t\":3,\"p\":1,\"n\":\"Global\"},{\"t\":3,\"p\":1,\"n\":\"Weather\"},{\"t\":3,\"p\":1,\"n\":\"Package\"},{\"t\":3,\"p\":1,\"n\":\"Encounter Zone\"},{\"t\":3,\"p\":1,\"n\":\"Perk\"},{\"t\":3,\"p\":1,\"n\":\"Owner\"},{\"t\":3,\"p\":1,\"n\":\"Furniture\"},{\"t\":3,\"p\":1,\"n\":\"Effect Item\"},{\"t\":3,\"p\":1,\"n\":\"Base Effect\"},{\"t\":3,\"p\":1,\"n\":\"Worldspace\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Function\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Param (INVALID)\"},{\"t\":3,\"p\":1,\"n\":\"Referenceable Object\"},{\"t\":3,\"p\":1,\"n\":\"Region\"},{\"t\":3,\"p\":1,\"n\":\"Keyword\"},{\"t\":3,\"p\":1,\"n\":\"Player Action\"},{\"t\":3,\"p\":1,\"n\":\"Casting Type\"},{\"t\":3,\"p\":1,\"n\":\"Shout\"},{\"t\":3,\"p\":1,\"n\":\"Location\"},{\"t\":3,\"p\":1,\"n\":\"Location Ref Type\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"Packdata ID\"},{\"t\":3,\"p\":1,\"n\":\"Association Type\"},{\"t\":3,\"p\":1,\"n\":\"Furniture Anim\"},{\"t\":3,\"p\":1,\"n\":\"Furniture Entry\"},{\"t\":3,\"p\":1,\"n\":\"Scene\"},{\"t\":3,\"p\":1,\"n\":\"Ward State\"},{\"t\":3,\"p\":1,\"n\":\"Event\"},{\"t\":3,\"p\":1,\"n\":\"Event Data\"},{\"t\":3,\"p\":1,\"n\":\"Quest Stage\"},{\"t\":3,\"p\":1,\"n\":\"Weapon\"},{\"t\":3,\"p\":1,\"n\":\"Weapon List\"},{\"t\":3,\"p\":1,\"n\":\"Target\"},{\"t\":3,\"p\":1,\"n\":\"Target List\"},{\"t\":3,\"p\":1,\"n\":\"Target Part\"},{\"t\":3,\"p\":1,\"n\":\"VATS Action\"},{\"t\":3,\"p\":1,\"n\":\"Critical Effect\"},{\"t\":3,\"p\":1,\"n\":\"Critical Effect List\"},{\"t\":3,\"p\":1,\"n\":\"Weapon Type\"},{\"t\":3,\"p\":1,\"n\":\"Projectile Type\"},{\"t\":3,\"p\":1,\"n\":\"Delivery Type\"},{\"t\":3,\"p\":1,\"n\":\"Run On\"},{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":3,\"p\":1,\"n\":\"Parameter #3\"}]},{\"t\":2,\"p\":1,\"n\":\"CIS1 - Parameter #1\"},{\"t\":2,\"p\":1,\"n\":\"CIS2 - Parameter #2\"}]}]}]},{\"p\":1,\"n\":\"NEXT - Marker\"},{\"t\":6,\"p\":1,\"n\":\"Completion Conditions\",\"c\":[{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Conditions\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Condition\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"CTDA - \",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":5,\"p\":1,\"n\":\"Comparison Value - Float\"},{\"t\":3,\"p\":1,\"n\":\"Comparison Value - Global\"},{\"t\":3,\"p\":1,\"n\":\"Function\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":11,\"p\":1,\"n\":\"None\"},{\"t\":3,\"p\":1,\"n\":\"Integer\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":11,\"p\":1,\"n\":\"Variable Name (unused)\"},{\"t\":3,\"p\":1,\"n\":\"Sex\"},{\"t\":3,\"p\":1,\"n\":\"Actor Value\"},{\"t\":3,\"p\":1,\"n\":\"Crime Type\"},{\"t\":3,\"p\":1,\"n\":\"Axis\"},{\"t\":3,\"p\":1,\"n\":\"Quest Stage (unused)\"},{\"t\":3,\"p\":1,\"n\":\"Misc Stat\"},{\"t\":3,\"p\":1,\"n\":\"Alignment\"},{\"t\":3,\"p\":1,\"n\":\"Equip Type\"},{\"t\":3,\"p\":1,\"n\":\"Form Type\"},{\"t\":3,\"p\":1,\"n\":\"Critical Stage\"},{\"t\":3,\"p\":1,\"n\":\"Object Reference\"},{\"t\":3,\"p\":1,\"n\":\"Inventory Object\"},{\"t\":3,\"p\":1,\"n\":\"Actor\"},{\"t\":3,\"p\":1,\"n\":\"Voice Type\"},{\"t\":3,\"p\":1,\"n\":\"Idle\"},{\"t\":3,\"p\":1,\"n\":\"Form List\"},{\"t\":3,\"p\":1,\"n\":\"Quest\"},{\"t\":3,\"p\":1,\"n\":\"Faction\"},{\"t\":3,\"p\":1,\"n\":\"Cell\"},{\"t\":3,\"p\":1,\"n\":\"Class\"},{\"t\":3,\"p\":1,\"n\":\"Race\"},{\"t\":3,\"p\":1,\"n\":\"Actor Base\"},{\"t\":3,\"p\":1,\"n\":\"Global\"},{\"t\":3,\"p\":1,\"n\":\"Weather\"},{\"t\":3,\"p\":1,\"n\":\"Package\"},{\"t\":3,\"p\":1,\"n\":\"Encounter Zone\"},{\"t\":3,\"p\":1,\"n\":\"Perk\"},{\"t\":3,\"p\":1,\"n\":\"Owner\"},{\"t\":3,\"p\":1,\"n\":\"Furniture\"},{\"t\":3,\"p\":1,\"n\":\"Effect Item\"},{\"t\":3,\"p\":1,\"n\":\"Base Effect\"},{\"t\":3,\"p\":1,\"n\":\"Worldspace\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Function\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Param (INVALID)\"},{\"t\":3,\"p\":1,\"n\":\"Referenceable Object\"},{\"t\":3,\"p\":1,\"n\":\"Region\"},{\"t\":3,\"p\":1,\"n\":\"Keyword\"},{\"t\":3,\"p\":1,\"n\":\"Player Action\"},{\"t\":3,\"p\":1,\"n\":\"Casting Type\"},{\"t\":3,\"p\":1,\"n\":\"Shout\"},{\"t\":3,\"p\":1,\"n\":\"Location\"},{\"t\":3,\"p\":1,\"n\":\"Location Ref Type\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"Packdata ID\"},{\"t\":3,\"p\":1,\"n\":\"Association Type\"},{\"t\":3,\"p\":1,\"n\":\"Furniture Anim\"},{\"t\":3,\"p\":1,\"n\":\"Furniture Entry\"},{\"t\":3,\"p\":1,\"n\":\"Scene\"},{\"t\":3,\"p\":1,\"n\":\"Ward State\"},{\"t\":3,\"p\":1,\"n\":\"Event\"},{\"t\":3,\"p\":1,\"n\":\"Event Data\"},{\"t\":3,\"p\":1,\"n\":\"Quest Stage\"},{\"t\":3,\"p\":1,\"n\":\"Weapon\"},{\"t\":3,\"p\":1,\"n\":\"Weapon List\"},{\"t\":3,\"p\":1,\"n\":\"Target\"},{\"t\":3,\"p\":1,\"n\":\"Target List\"},{\"t\":3,\"p\":1,\"n\":\"Target Part\"},{\"t\":3,\"p\":1,\"n\":\"VATS Action\"},{\"t\":3,\"p\":1,\"n\":\"Critical Effect\"},{\"t\":3,\"p\":1,\"n\":\"Critical Effect List\"},{\"t\":3,\"p\":1,\"n\":\"Weapon Type\"},{\"t\":3,\"p\":1,\"n\":\"Projectile Type\"},{\"t\":3,\"p\":1,\"n\":\"Delivery Type\"},{\"t\":3,\"p\":1,\"n\":\"Run On\"},{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":3,\"p\":1,\"n\":\"Parameter #3\"}]},{\"t\":2,\"p\":1,\"n\":\"CIS1 - Parameter #1\"},{\"t\":2,\"p\":1,\"n\":\"CIS2 - Parameter #2\"}]}]}]},{\"t\":6,\"n\":\"Unused\",\"c\":[{\"t\":11,\"n\":\"SCHR - Unknown\"},{\"t\":11,\"n\":\"SCDA - Unknown\"},{\"t\":11,\"n\":\"SCTX - Unknown\"},{\"t\":11,\"n\":\"QNAM - Unknown\"},{\"t\":11,\"n\":\"SCRO - Unknown\"}]},{\"t\":3,\"p\":1,\"n\":\"WNAM - Editor Width\"},{\"p\":1,\"n\":\"HNAM - Marker Phase End\"}]}]},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Actors\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Actor\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"ALID - Actor ID\"},{\"t\":3,\"p\":1,\"n\":\"LNAM - Flags\"},{\"t\":3,\"p\":1,\"n\":\"DNAM - Behaviour Flags\"}]}]},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Actions\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Action\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"ANAM - Type\"},{\"t\":2,\"p\":1,\"n\":\"NAM0 - Name\"},{\"t\":3,\"p\":1,\"n\":\"ALID - Actor ID\"},{\"t\":11,\"n\":\"LNAM - Unknown\"},{\"t\":3,\"p\":1,\"n\":\"INAM - Index\"},{\"t\":3,\"p\":1,\"n\":\"FNAM - Flags\"},{\"t\":3,\"p\":1,\"n\":\"SNAM - Start Phase\"},{\"t\":3,\"p\":1,\"n\":\"ENAM - End Phase\"},{\"t\":5,\"p\":1,\"n\":\"SNAM - Timer Seconds\"},{\"t\":8,\"p\":1,\"n\":\"Packages\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"PNAM - Package\"}]},{\"t\":3,\"p\":1,\"n\":\"DATA - Topic\"},{\"t\":3,\"p\":1,\"n\":\"HTID - Headtrack Actor ID\"},{\"t\":5,\"p\":1,\"n\":\"DMAX - Looping - Max\"},{\"t\":5,\"p\":1,\"n\":\"DMIN - Looping - Min\"},{\"t\":3,\"p\":1,\"n\":\"DEMO - Emotion Type\"},{\"t\":3,\"p\":1,\"n\":\"DEVA - Emotion Value\"},{\"t\":6,\"n\":\"Unused\",\"c\":[{\"t\":11,\"n\":\"SCHR - Unknown\"},{\"t\":11,\"n\":\"SCDA - Unknown\"},{\"t\":11,\"n\":\"SCTX - Unknown\"},{\"t\":11,\"n\":\"QNAM - Unknown\"},{\"t\":11,\"n\":\"SCRO - Unknown\"}]},{\"p\":1,\"n\":\"ANAM - End Marker\"}]}]},{\"t\":6,\"n\":\"Unused\",\"c\":[{\"t\":11,\"n\":\"SCHR - Unknown\"},{\"t\":11,\"n\":\"SCDA - Unknown\"},{\"t\":11,\"n\":\"SCTX - Unknown\"},{\"t\":11,\"n\":\"QNAM - Unknown\"},{\"t\":11,\"n\":\"SCRO - Unknown\"}]},{\"p\":1,\"n\":\"NEXT - Marker\"},{\"t\":3,\"p\":1,\"n\":\"PNAM - Quest\"},{\"t\":3,\"p\":1,\"n\":\"INAM - Last Action Index\"},{\"t\":11,\"n\":\"VNAM - Unknown\"},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Conditions\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Condition\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"CTDA - \",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":5,\"p\":1,\"n\":\"Comparison Value - Float\"},{\"t\":3,\"p\":1,\"n\":\"Comparison Value - Global\"},{\"t\":3,\"p\":1,\"n\":\"Function\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":11,\"p\":1,\"n\":\"None\"},{\"t\":3,\"p\":1,\"n\":\"Integer\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":11,\"p\":1,\"n\":\"Variable Name (unused)\"},{\"t\":3,\"p\":1,\"n\":\"Sex\"},{\"t\":3,\"p\":1,\"n\":\"Actor Value\"},{\"t\":3,\"p\":1,\"n\":\"Crime Type\"},{\"t\":3,\"p\":1,\"n\":\"Axis\"},{\"t\":3,\"p\":1,\"n\":\"Quest Stage (unused)\"},{\"t\":3,\"p\":1,\"n\":\"Misc Stat\"},{\"t\":3,\"p\":1,\"n\":\"Alignment\"},{\"t\":3,\"p\":1,\"n\":\"Equip Type\"},{\"t\":3,\"p\":1,\"n\":\"Form Type\"},{\"t\":3,\"p\":1,\"n\":\"Critical Stage\"},{\"t\":3,\"p\":1,\"n\":\"Object Reference\"},{\"t\":3,\"p\":1,\"n\":\"Inventory Object\"},{\"t\":3,\"p\":1,\"n\":\"Actor\"},{\"t\":3,\"p\":1,\"n\":\"Voice Type\"},{\"t\":3,\"p\":1,\"n\":\"Idle\"},{\"t\":3,\"p\":1,\"n\":\"Form List\"},{\"t\":3,\"p\":1,\"n\":\"Quest\"},{\"t\":3,\"p\":1,\"n\":\"Faction\"},{\"t\":3,\"p\":1,\"n\":\"Cell\"},{\"t\":3,\"p\":1,\"n\":\"Class\"},{\"t\":3,\"p\":1,\"n\":\"Race\"},{\"t\":3,\"p\":1,\"n\":\"Actor Base\"},{\"t\":3,\"p\":1,\"n\":\"Global\"},{\"t\":3,\"p\":1,\"n\":\"Weather\"},{\"t\":3,\"p\":1,\"n\":\"Package\"},{\"t\":3,\"p\":1,\"n\":\"Encounter Zone\"},{\"t\":3,\"p\":1,\"n\":\"Perk\"},{\"t\":3,\"p\":1,\"n\":\"Owner\"},{\"t\":3,\"p\":1,\"n\":\"Furniture\"},{\"t\":3,\"p\":1,\"n\":\"Effect Item\"},{\"t\":3,\"p\":1,\"n\":\"Base Effect\"},{\"t\":3,\"p\":1,\"n\":\"Worldspace\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Function\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Param (INVALID)\"},{\"t\":3,\"p\":1,\"n\":\"Referenceable Object\"},{\"t\":3,\"p\":1,\"n\":\"Region\"},{\"t\":3,\"p\":1,\"n\":\"Keyword\"},{\"t\":3,\"p\":1,\"n\":\"Player Action\"},{\"t\":3,\"p\":1,\"n\":\"Casting Type\"},{\"t\":3,\"p\":1,\"n\":\"Shout\"},{\"t\":3,\"p\":1,\"n\":\"Location\"},{\"t\":3,\"p\":1,\"n\":\"Location Ref Type\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"Packdata ID\"},{\"t\":3,\"p\":1,\"n\":\"Association Type\"},{\"t\":3,\"p\":1,\"n\":\"Furniture Anim\"},{\"t\":3,\"p\":1,\"n\":\"Furniture Entry\"},{\"t\":3,\"p\":1,\"n\":\"Scene\"},{\"t\":3,\"p\":1,\"n\":\"Ward State\"},{\"t\":3,\"p\":1,\"n\":\"Event\"},{\"t\":3,\"p\":1,\"n\":\"Event Data\"},{\"t\":3,\"p\":1,\"n\":\"Quest Stage\"},{\"t\":3,\"p\":1,\"n\":\"Weapon\"},{\"t\":3,\"p\":1,\"n\":\"Weapon List\"},{\"t\":3,\"p\":1,\"n\":\"Target\"},{\"t\":3,\"p\":1,\"n\":\"Target List\"},{\"t\":3,\"p\":1,\"n\":\"Target Part\"},{\"t\":3,\"p\":1,\"n\":\"VATS Action\"},{\"t\":3,\"p\":1,\"n\":\"Critical Effect\"},{\"t\":3,\"p\":1,\"n\":\"Critical Effect List\"},{\"t\":3,\"p\":1,\"n\":\"Weapon Type\"},{\"t\":3,\"p\":1,\"n\":\"Projectile Type\"},{\"t\":3,\"p\":1,\"n\":\"Delivery Type\"},{\"t\":3,\"p\":1,\"n\":\"Run On\"},{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":3,\"p\":1,\"n\":\"Parameter #3\"}]},{\"t\":2,\"p\":1,\"n\":\"CIS1 - Parameter #1\"},{\"t\":2,\"p\":1,\"n\":\"CIS2 - Parameter #2\"}]}]}]},{\"t\":1,\"p\":1,\"n\":\"SCOL\",\"f\":1,\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"}]},{\"t\":1,\"p\":1,\"n\":\"SCPT\",\"f\":1,\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"}]},{\"t\":1,\"p\":1,\"n\":\"SCRL - Scroll\",\"f\":1,\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"X1\"},{\"t\":3,\"p\":1,\"n\":\"Y1\"},{\"t\":3,\"p\":1,\"n\":\"Z1\"},{\"t\":3,\"p\":1,\"n\":\"X2\"},{\"t\":3,\"p\":1,\"n\":\"Y2\"},{\"t\":3,\"p\":1,\"n\":\"Z2\"}]},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":3,\"n\":\"KSIZ - Keyword Count\"},{\"t\":7,\"p\":1,\"n\":\"KWDA - Keywords\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Keyword\"}]},{\"t\":3,\"p\":1,\"n\":\"MDOB - Menu Display Object\"},{\"t\":3,\"p\":1,\"n\":\"ETYP - Equipment Type\"},{\"t\":2,\"p\":1,\"n\":\"DESC - Description\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"MODT - Texture Files Hashes\"},{\"t\":7,\"p\":1,\"n\":\"MODS - Alternate Textures\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"3D Name\"},{\"t\":3,\"p\":1,\"n\":\"New Texture\"},{\"t\":3,\"p\":1,\"n\":\"3D Index\"}]}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Destructable\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"DEST - Header\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Health\"},{\"t\":3,\"p\":1,\"n\":\"DEST Count\"},{\"t\":3,\"p\":1,\"n\":\"VATS Targetable\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":8,\"p\":1,\"n\":\"Stages\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Stage\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"DSTD - Destruction Stage Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Health %\"},{\"t\":3,\"p\":1,\"n\":\"Index\"},{\"t\":3,\"p\":1,\"n\":\"Model Damage Stage\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":3,\"p\":1,\"n\":\"Self Damage per Second\"},{\"t\":3,\"p\":1,\"n\":\"Explosion\"},{\"t\":3,\"p\":1,\"n\":\"Debris\"},{\"t\":3,\"p\":1,\"n\":\"Debris Count\"}]},{\"t\":6,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"DMDL - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"DMDT - Texture Files Hashes\"},{\"t\":7,\"p\":1,\"n\":\"DMDS - Alternate Textures\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"3D Name\"},{\"t\":3,\"p\":1,\"n\":\"New Texture\"},{\"t\":3,\"p\":1,\"n\":\"3D Index\"}]}]}]},{\"p\":1,\"n\":\"DSTF - End Marker\"}]}]}]},{\"t\":3,\"p\":1,\"n\":\"YNAM - Sound - Pick Up\"},{\"t\":3,\"p\":1,\"n\":\"ZNAM - Sound - Put Down\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DATA - Item\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Value\"},{\"t\":5,\"p\":1,\"n\":\"Weight\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"SPIT - Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Base Cost\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":5,\"p\":1,\"n\":\"Charge Time\"},{\"t\":3,\"p\":1,\"n\":\"Cast Type\"},{\"t\":3,\"p\":1,\"n\":\"Target Type\"},{\"t\":5,\"p\":1,\"n\":\"Cast Duration\"},{\"t\":5,\"p\":1,\"n\":\"Range\"},{\"t\":3,\"p\":1,\"n\":\"Half-cost Perk\"}]},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Effects\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Effect\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"EFID - Base Effect\"},{\"t\":6,\"p\":1,\"n\":\"EFIT - \",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Magnitude\"},{\"t\":3,\"p\":1,\"n\":\"Area\"},{\"t\":3,\"p\":1,\"n\":\"Duration\"}]},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Conditions\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Condition\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"CTDA - \",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":5,\"p\":1,\"n\":\"Comparison Value - Float\"},{\"t\":3,\"p\":1,\"n\":\"Comparison Value - Global\"},{\"t\":3,\"p\":1,\"n\":\"Function\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":11,\"p\":1,\"n\":\"None\"},{\"t\":3,\"p\":1,\"n\":\"Integer\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":11,\"p\":1,\"n\":\"Variable Name (unused)\"},{\"t\":3,\"p\":1,\"n\":\"Sex\"},{\"t\":3,\"p\":1,\"n\":\"Actor Value\"},{\"t\":3,\"p\":1,\"n\":\"Crime Type\"},{\"t\":3,\"p\":1,\"n\":\"Axis\"},{\"t\":3,\"p\":1,\"n\":\"Quest Stage (unused)\"},{\"t\":3,\"p\":1,\"n\":\"Misc Stat\"},{\"t\":3,\"p\":1,\"n\":\"Alignment\"},{\"t\":3,\"p\":1,\"n\":\"Equip Type\"},{\"t\":3,\"p\":1,\"n\":\"Form Type\"},{\"t\":3,\"p\":1,\"n\":\"Critical Stage\"},{\"t\":3,\"p\":1,\"n\":\"Object Reference\"},{\"t\":3,\"p\":1,\"n\":\"Inventory Object\"},{\"t\":3,\"p\":1,\"n\":\"Actor\"},{\"t\":3,\"p\":1,\"n\":\"Voice Type\"},{\"t\":3,\"p\":1,\"n\":\"Idle\"},{\"t\":3,\"p\":1,\"n\":\"Form List\"},{\"t\":3,\"p\":1,\"n\":\"Quest\"},{\"t\":3,\"p\":1,\"n\":\"Faction\"},{\"t\":3,\"p\":1,\"n\":\"Cell\"},{\"t\":3,\"p\":1,\"n\":\"Class\"},{\"t\":3,\"p\":1,\"n\":\"Race\"},{\"t\":3,\"p\":1,\"n\":\"Actor Base\"},{\"t\":3,\"p\":1,\"n\":\"Global\"},{\"t\":3,\"p\":1,\"n\":\"Weather\"},{\"t\":3,\"p\":1,\"n\":\"Package\"},{\"t\":3,\"p\":1,\"n\":\"Encounter Zone\"},{\"t\":3,\"p\":1,\"n\":\"Perk\"},{\"t\":3,\"p\":1,\"n\":\"Owner\"},{\"t\":3,\"p\":1,\"n\":\"Furniture\"},{\"t\":3,\"p\":1,\"n\":\"Effect Item\"},{\"t\":3,\"p\":1,\"n\":\"Base Effect\"},{\"t\":3,\"p\":1,\"n\":\"Worldspace\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Function\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Param (INVALID)\"},{\"t\":3,\"p\":1,\"n\":\"Referenceable Object\"},{\"t\":3,\"p\":1,\"n\":\"Region\"},{\"t\":3,\"p\":1,\"n\":\"Keyword\"},{\"t\":3,\"p\":1,\"n\":\"Player Action\"},{\"t\":3,\"p\":1,\"n\":\"Casting Type\"},{\"t\":3,\"p\":1,\"n\":\"Shout\"},{\"t\":3,\"p\":1,\"n\":\"Location\"},{\"t\":3,\"p\":1,\"n\":\"Location Ref Type\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"Packdata ID\"},{\"t\":3,\"p\":1,\"n\":\"Association Type\"},{\"t\":3,\"p\":1,\"n\":\"Furniture Anim\"},{\"t\":3,\"p\":1,\"n\":\"Furniture Entry\"},{\"t\":3,\"p\":1,\"n\":\"Scene\"},{\"t\":3,\"p\":1,\"n\":\"Ward State\"},{\"t\":3,\"p\":1,\"n\":\"Event\"},{\"t\":3,\"p\":1,\"n\":\"Event Data\"},{\"t\":3,\"p\":1,\"n\":\"Quest Stage\"},{\"t\":3,\"p\":1,\"n\":\"Weapon\"},{\"t\":3,\"p\":1,\"n\":\"Weapon List\"},{\"t\":3,\"p\":1,\"n\":\"Target\"},{\"t\":3,\"p\":1,\"n\":\"Target List\"},{\"t\":3,\"p\":1,\"n\":\"Target Part\"},{\"t\":3,\"p\":1,\"n\":\"VATS Action\"},{\"t\":3,\"p\":1,\"n\":\"Critical Effect\"},{\"t\":3,\"p\":1,\"n\":\"Critical Effect List\"},{\"t\":3,\"p\":1,\"n\":\"Weapon Type\"},{\"t\":3,\"p\":1,\"n\":\"Projectile Type\"},{\"t\":3,\"p\":1,\"n\":\"Delivery Type\"},{\"t\":3,\"p\":1,\"n\":\"Run On\"},{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":3,\"p\":1,\"n\":\"Parameter #3\"}]},{\"t\":2,\"p\":1,\"n\":\"CIS1 - Parameter #1\"},{\"t\":2,\"p\":1,\"n\":\"CIS2 - Parameter #2\"}]}]}]}]}]},{\"t\":1,\"p\":1,\"n\":\"SHOU - Shout\",\"f\":1,\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":3,\"p\":1,\"n\":\"MDOB - Menu Display Object\"},{\"t\":2,\"p\":1,\"n\":\"DESC - Description\"},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Words of Power\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"SNAM - \",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Word\"},{\"t\":3,\"p\":1,\"n\":\"Spell\"},{\"t\":5,\"p\":1,\"n\":\"Recovery Time\"}]}]}]},{\"t\":1,\"p\":1,\"n\":\"SLGM - Soul Gem\",\"f\":1,\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"X1\"},{\"t\":3,\"p\":1,\"n\":\"Y1\"},{\"t\":3,\"p\":1,\"n\":\"Z1\"},{\"t\":3,\"p\":1,\"n\":\"X2\"},{\"t\":3,\"p\":1,\"n\":\"Y2\"},{\"t\":3,\"p\":1,\"n\":\"Z2\"}]},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"MODT - Texture Files Hashes\"},{\"t\":7,\"p\":1,\"n\":\"MODS - Alternate Textures\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"3D Name\"},{\"t\":3,\"p\":1,\"n\":\"New Texture\"},{\"t\":3,\"p\":1,\"n\":\"3D Index\"}]}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Icon\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"ICON - Large Icon filename\"},{\"t\":2,\"p\":1,\"n\":\"MICO - Small Icon filename\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Destructable\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"DEST - Header\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Health\"},{\"t\":3,\"p\":1,\"n\":\"DEST Count\"},{\"t\":3,\"p\":1,\"n\":\"VATS Targetable\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":8,\"p\":1,\"n\":\"Stages\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Stage\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"DSTD - Destruction Stage Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Health %\"},{\"t\":3,\"p\":1,\"n\":\"Index\"},{\"t\":3,\"p\":1,\"n\":\"Model Damage Stage\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":3,\"p\":1,\"n\":\"Self Damage per Second\"},{\"t\":3,\"p\":1,\"n\":\"Explosion\"},{\"t\":3,\"p\":1,\"n\":\"Debris\"},{\"t\":3,\"p\":1,\"n\":\"Debris Count\"}]},{\"t\":6,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"DMDL - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"DMDT - Texture Files Hashes\"},{\"t\":7,\"p\":1,\"n\":\"DMDS - Alternate Textures\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"3D Name\"},{\"t\":3,\"p\":1,\"n\":\"New Texture\"},{\"t\":3,\"p\":1,\"n\":\"3D Index\"}]}]}]},{\"p\":1,\"n\":\"DSTF - End Marker\"}]}]}]},{\"t\":3,\"p\":1,\"n\":\"YNAM - Sound - Pick Up\"},{\"t\":3,\"p\":1,\"n\":\"ZNAM - Sound - Put Down\"},{\"t\":3,\"n\":\"KSIZ - Keyword Count\"},{\"t\":7,\"p\":1,\"n\":\"KWDA - Keywords\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Keyword\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DATA - \",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Value\"},{\"t\":5,\"p\":1,\"n\":\"Weight\"}]},{\"t\":3,\"p\":1,\"n\":\"SOUL - Contained Soul\"},{\"t\":3,\"p\":1,\"n\":\"SLCP - Maximum Capacity\"},{\"t\":3,\"p\":1,\"n\":\"NAM0 - Linked To\"}]},{\"t\":1,\"p\":1,\"n\":\"SMBN - Story Manager Branch Node\",\"f\":1,\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":3,\"p\":1,\"n\":\"PNAM - Parent \"},{\"t\":3,\"p\":1,\"n\":\"SNAM - Child \"},{\"t\":3,\"n\":\"CITC - Condition Count\"},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Conditions\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Condition\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"CTDA - \",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":5,\"p\":1,\"n\":\"Comparison Value - Float\"},{\"t\":3,\"p\":1,\"n\":\"Comparison Value - Global\"},{\"t\":3,\"p\":1,\"n\":\"Function\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":11,\"p\":1,\"n\":\"None\"},{\"t\":3,\"p\":1,\"n\":\"Integer\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":11,\"p\":1,\"n\":\"Variable Name (unused)\"},{\"t\":3,\"p\":1,\"n\":\"Sex\"},{\"t\":3,\"p\":1,\"n\":\"Actor Value\"},{\"t\":3,\"p\":1,\"n\":\"Crime Type\"},{\"t\":3,\"p\":1,\"n\":\"Axis\"},{\"t\":3,\"p\":1,\"n\":\"Quest Stage (unused)\"},{\"t\":3,\"p\":1,\"n\":\"Misc Stat\"},{\"t\":3,\"p\":1,\"n\":\"Alignment\"},{\"t\":3,\"p\":1,\"n\":\"Equip Type\"},{\"t\":3,\"p\":1,\"n\":\"Form Type\"},{\"t\":3,\"p\":1,\"n\":\"Critical Stage\"},{\"t\":3,\"p\":1,\"n\":\"Object Reference\"},{\"t\":3,\"p\":1,\"n\":\"Inventory Object\"},{\"t\":3,\"p\":1,\"n\":\"Actor\"},{\"t\":3,\"p\":1,\"n\":\"Voice Type\"},{\"t\":3,\"p\":1,\"n\":\"Idle\"},{\"t\":3,\"p\":1,\"n\":\"Form List\"},{\"t\":3,\"p\":1,\"n\":\"Quest\"},{\"t\":3,\"p\":1,\"n\":\"Faction\"},{\"t\":3,\"p\":1,\"n\":\"Cell\"},{\"t\":3,\"p\":1,\"n\":\"Class\"},{\"t\":3,\"p\":1,\"n\":\"Race\"},{\"t\":3,\"p\":1,\"n\":\"Actor Base\"},{\"t\":3,\"p\":1,\"n\":\"Global\"},{\"t\":3,\"p\":1,\"n\":\"Weather\"},{\"t\":3,\"p\":1,\"n\":\"Package\"},{\"t\":3,\"p\":1,\"n\":\"Encounter Zone\"},{\"t\":3,\"p\":1,\"n\":\"Perk\"},{\"t\":3,\"p\":1,\"n\":\"Owner\"},{\"t\":3,\"p\":1,\"n\":\"Furniture\"},{\"t\":3,\"p\":1,\"n\":\"Effect Item\"},{\"t\":3,\"p\":1,\"n\":\"Base Effect\"},{\"t\":3,\"p\":1,\"n\":\"Worldspace\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Function\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Param (INVALID)\"},{\"t\":3,\"p\":1,\"n\":\"Referenceable Object\"},{\"t\":3,\"p\":1,\"n\":\"Region\"},{\"t\":3,\"p\":1,\"n\":\"Keyword\"},{\"t\":3,\"p\":1,\"n\":\"Player Action\"},{\"t\":3,\"p\":1,\"n\":\"Casting Type\"},{\"t\":3,\"p\":1,\"n\":\"Shout\"},{\"t\":3,\"p\":1,\"n\":\"Location\"},{\"t\":3,\"p\":1,\"n\":\"Location Ref Type\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"Packdata ID\"},{\"t\":3,\"p\":1,\"n\":\"Association Type\"},{\"t\":3,\"p\":1,\"n\":\"Furniture Anim\"},{\"t\":3,\"p\":1,\"n\":\"Furniture Entry\"},{\"t\":3,\"p\":1,\"n\":\"Scene\"},{\"t\":3,\"p\":1,\"n\":\"Ward State\"},{\"t\":3,\"p\":1,\"n\":\"Event\"},{\"t\":3,\"p\":1,\"n\":\"Event Data\"},{\"t\":3,\"p\":1,\"n\":\"Quest Stage\"},{\"t\":3,\"p\":1,\"n\":\"Weapon\"},{\"t\":3,\"p\":1,\"n\":\"Weapon List\"},{\"t\":3,\"p\":1,\"n\":\"Target\"},{\"t\":3,\"p\":1,\"n\":\"Target List\"},{\"t\":3,\"p\":1,\"n\":\"Target Part\"},{\"t\":3,\"p\":1,\"n\":\"VATS Action\"},{\"t\":3,\"p\":1,\"n\":\"Critical Effect\"},{\"t\":3,\"p\":1,\"n\":\"Critical Effect List\"},{\"t\":3,\"p\":1,\"n\":\"Weapon Type\"},{\"t\":3,\"p\":1,\"n\":\"Projectile Type\"},{\"t\":3,\"p\":1,\"n\":\"Delivery Type\"},{\"t\":3,\"p\":1,\"n\":\"Run On\"},{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":3,\"p\":1,\"n\":\"Parameter #3\"}]},{\"t\":2,\"p\":1,\"n\":\"CIS1 - Parameter #1\"},{\"t\":2,\"p\":1,\"n\":\"CIS2 - Parameter #2\"}]}]},{\"t\":3,\"p\":1,\"n\":\"DNAM - Flags\"},{\"t\":11,\"n\":\"XNAM - Unknown\"}]},{\"t\":1,\"p\":1,\"n\":\"SMEN - Story Manager Event Node\",\"f\":1,\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":3,\"p\":1,\"n\":\"PNAM - Parent \"},{\"t\":3,\"p\":1,\"n\":\"SNAM - Child \"},{\"t\":3,\"n\":\"CITC - Condition Count\"},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Conditions\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Condition\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"CTDA - \",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":5,\"p\":1,\"n\":\"Comparison Value - Float\"},{\"t\":3,\"p\":1,\"n\":\"Comparison Value - Global\"},{\"t\":3,\"p\":1,\"n\":\"Function\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":11,\"p\":1,\"n\":\"None\"},{\"t\":3,\"p\":1,\"n\":\"Integer\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":11,\"p\":1,\"n\":\"Variable Name (unused)\"},{\"t\":3,\"p\":1,\"n\":\"Sex\"},{\"t\":3,\"p\":1,\"n\":\"Actor Value\"},{\"t\":3,\"p\":1,\"n\":\"Crime Type\"},{\"t\":3,\"p\":1,\"n\":\"Axis\"},{\"t\":3,\"p\":1,\"n\":\"Quest Stage (unused)\"},{\"t\":3,\"p\":1,\"n\":\"Misc Stat\"},{\"t\":3,\"p\":1,\"n\":\"Alignment\"},{\"t\":3,\"p\":1,\"n\":\"Equip Type\"},{\"t\":3,\"p\":1,\"n\":\"Form Type\"},{\"t\":3,\"p\":1,\"n\":\"Critical Stage\"},{\"t\":3,\"p\":1,\"n\":\"Object Reference\"},{\"t\":3,\"p\":1,\"n\":\"Inventory Object\"},{\"t\":3,\"p\":1,\"n\":\"Actor\"},{\"t\":3,\"p\":1,\"n\":\"Voice Type\"},{\"t\":3,\"p\":1,\"n\":\"Idle\"},{\"t\":3,\"p\":1,\"n\":\"Form List\"},{\"t\":3,\"p\":1,\"n\":\"Quest\"},{\"t\":3,\"p\":1,\"n\":\"Faction\"},{\"t\":3,\"p\":1,\"n\":\"Cell\"},{\"t\":3,\"p\":1,\"n\":\"Class\"},{\"t\":3,\"p\":1,\"n\":\"Race\"},{\"t\":3,\"p\":1,\"n\":\"Actor Base\"},{\"t\":3,\"p\":1,\"n\":\"Global\"},{\"t\":3,\"p\":1,\"n\":\"Weather\"},{\"t\":3,\"p\":1,\"n\":\"Package\"},{\"t\":3,\"p\":1,\"n\":\"Encounter Zone\"},{\"t\":3,\"p\":1,\"n\":\"Perk\"},{\"t\":3,\"p\":1,\"n\":\"Owner\"},{\"t\":3,\"p\":1,\"n\":\"Furniture\"},{\"t\":3,\"p\":1,\"n\":\"Effect Item\"},{\"t\":3,\"p\":1,\"n\":\"Base Effect\"},{\"t\":3,\"p\":1,\"n\":\"Worldspace\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Function\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Param (INVALID)\"},{\"t\":3,\"p\":1,\"n\":\"Referenceable Object\"},{\"t\":3,\"p\":1,\"n\":\"Region\"},{\"t\":3,\"p\":1,\"n\":\"Keyword\"},{\"t\":3,\"p\":1,\"n\":\"Player Action\"},{\"t\":3,\"p\":1,\"n\":\"Casting Type\"},{\"t\":3,\"p\":1,\"n\":\"Shout\"},{\"t\":3,\"p\":1,\"n\":\"Location\"},{\"t\":3,\"p\":1,\"n\":\"Location Ref Type\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"Packdata ID\"},{\"t\":3,\"p\":1,\"n\":\"Association Type\"},{\"t\":3,\"p\":1,\"n\":\"Furniture Anim\"},{\"t\":3,\"p\":1,\"n\":\"Furniture Entry\"},{\"t\":3,\"p\":1,\"n\":\"Scene\"},{\"t\":3,\"p\":1,\"n\":\"Ward State\"},{\"t\":3,\"p\":1,\"n\":\"Event\"},{\"t\":3,\"p\":1,\"n\":\"Event Data\"},{\"t\":3,\"p\":1,\"n\":\"Quest Stage\"},{\"t\":3,\"p\":1,\"n\":\"Weapon\"},{\"t\":3,\"p\":1,\"n\":\"Weapon List\"},{\"t\":3,\"p\":1,\"n\":\"Target\"},{\"t\":3,\"p\":1,\"n\":\"Target List\"},{\"t\":3,\"p\":1,\"n\":\"Target Part\"},{\"t\":3,\"p\":1,\"n\":\"VATS Action\"},{\"t\":3,\"p\":1,\"n\":\"Critical Effect\"},{\"t\":3,\"p\":1,\"n\":\"Critical Effect List\"},{\"t\":3,\"p\":1,\"n\":\"Weapon Type\"},{\"t\":3,\"p\":1,\"n\":\"Projectile Type\"},{\"t\":3,\"p\":1,\"n\":\"Delivery Type\"},{\"t\":3,\"p\":1,\"n\":\"Run On\"},{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":3,\"p\":1,\"n\":\"Parameter #3\"}]},{\"t\":2,\"p\":1,\"n\":\"CIS1 - Parameter #1\"},{\"t\":2,\"p\":1,\"n\":\"CIS2 - Parameter #2\"}]}]},{\"t\":3,\"p\":1,\"n\":\"DNAM - Flags\"},{\"t\":11,\"n\":\"XNAM - Unknown\"},{\"t\":2,\"p\":1,\"n\":\"ENAM - Type\"}]},{\"t\":1,\"p\":1,\"n\":\"SMQN - Story Manager Quest Node\",\"f\":1,\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":3,\"p\":1,\"n\":\"PNAM - Parent \"},{\"t\":3,\"p\":1,\"n\":\"SNAM - Child \"},{\"t\":3,\"n\":\"CITC - Condition Count\"},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Conditions\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Condition\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"CTDA - \",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":5,\"p\":1,\"n\":\"Comparison Value - Float\"},{\"t\":3,\"p\":1,\"n\":\"Comparison Value - Global\"},{\"t\":3,\"p\":1,\"n\":\"Function\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":11,\"p\":1,\"n\":\"None\"},{\"t\":3,\"p\":1,\"n\":\"Integer\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":11,\"p\":1,\"n\":\"Variable Name (unused)\"},{\"t\":3,\"p\":1,\"n\":\"Sex\"},{\"t\":3,\"p\":1,\"n\":\"Actor Value\"},{\"t\":3,\"p\":1,\"n\":\"Crime Type\"},{\"t\":3,\"p\":1,\"n\":\"Axis\"},{\"t\":3,\"p\":1,\"n\":\"Quest Stage (unused)\"},{\"t\":3,\"p\":1,\"n\":\"Misc Stat\"},{\"t\":3,\"p\":1,\"n\":\"Alignment\"},{\"t\":3,\"p\":1,\"n\":\"Equip Type\"},{\"t\":3,\"p\":1,\"n\":\"Form Type\"},{\"t\":3,\"p\":1,\"n\":\"Critical Stage\"},{\"t\":3,\"p\":1,\"n\":\"Object Reference\"},{\"t\":3,\"p\":1,\"n\":\"Inventory Object\"},{\"t\":3,\"p\":1,\"n\":\"Actor\"},{\"t\":3,\"p\":1,\"n\":\"Voice Type\"},{\"t\":3,\"p\":1,\"n\":\"Idle\"},{\"t\":3,\"p\":1,\"n\":\"Form List\"},{\"t\":3,\"p\":1,\"n\":\"Quest\"},{\"t\":3,\"p\":1,\"n\":\"Faction\"},{\"t\":3,\"p\":1,\"n\":\"Cell\"},{\"t\":3,\"p\":1,\"n\":\"Class\"},{\"t\":3,\"p\":1,\"n\":\"Race\"},{\"t\":3,\"p\":1,\"n\":\"Actor Base\"},{\"t\":3,\"p\":1,\"n\":\"Global\"},{\"t\":3,\"p\":1,\"n\":\"Weather\"},{\"t\":3,\"p\":1,\"n\":\"Package\"},{\"t\":3,\"p\":1,\"n\":\"Encounter Zone\"},{\"t\":3,\"p\":1,\"n\":\"Perk\"},{\"t\":3,\"p\":1,\"n\":\"Owner\"},{\"t\":3,\"p\":1,\"n\":\"Furniture\"},{\"t\":3,\"p\":1,\"n\":\"Effect Item\"},{\"t\":3,\"p\":1,\"n\":\"Base Effect\"},{\"t\":3,\"p\":1,\"n\":\"Worldspace\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Function\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Param (INVALID)\"},{\"t\":3,\"p\":1,\"n\":\"Referenceable Object\"},{\"t\":3,\"p\":1,\"n\":\"Region\"},{\"t\":3,\"p\":1,\"n\":\"Keyword\"},{\"t\":3,\"p\":1,\"n\":\"Player Action\"},{\"t\":3,\"p\":1,\"n\":\"Casting Type\"},{\"t\":3,\"p\":1,\"n\":\"Shout\"},{\"t\":3,\"p\":1,\"n\":\"Location\"},{\"t\":3,\"p\":1,\"n\":\"Location Ref Type\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"Packdata ID\"},{\"t\":3,\"p\":1,\"n\":\"Association Type\"},{\"t\":3,\"p\":1,\"n\":\"Furniture Anim\"},{\"t\":3,\"p\":1,\"n\":\"Furniture Entry\"},{\"t\":3,\"p\":1,\"n\":\"Scene\"},{\"t\":3,\"p\":1,\"n\":\"Ward State\"},{\"t\":3,\"p\":1,\"n\":\"Event\"},{\"t\":3,\"p\":1,\"n\":\"Event Data\"},{\"t\":3,\"p\":1,\"n\":\"Quest Stage\"},{\"t\":3,\"p\":1,\"n\":\"Weapon\"},{\"t\":3,\"p\":1,\"n\":\"Weapon List\"},{\"t\":3,\"p\":1,\"n\":\"Target\"},{\"t\":3,\"p\":1,\"n\":\"Target List\"},{\"t\":3,\"p\":1,\"n\":\"Target Part\"},{\"t\":3,\"p\":1,\"n\":\"VATS Action\"},{\"t\":3,\"p\":1,\"n\":\"Critical Effect\"},{\"t\":3,\"p\":1,\"n\":\"Critical Effect List\"},{\"t\":3,\"p\":1,\"n\":\"Weapon Type\"},{\"t\":3,\"p\":1,\"n\":\"Projectile Type\"},{\"t\":3,\"p\":1,\"n\":\"Delivery Type\"},{\"t\":3,\"p\":1,\"n\":\"Run On\"},{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":3,\"p\":1,\"n\":\"Parameter #3\"}]},{\"t\":2,\"p\":1,\"n\":\"CIS1 - Parameter #1\"},{\"t\":2,\"p\":1,\"n\":\"CIS2 - Parameter #2\"}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DNAM - Flags\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Node Flags\"},{\"t\":3,\"p\":1,\"n\":\"Quest Flags\"}]},{\"t\":3,\"p\":1,\"n\":\"XNAM - Max concurrent quests\"},{\"t\":3,\"p\":1,\"n\":\"MNAM - Num quests to run\"},{\"t\":3,\"n\":\"QNAM - Quest Count\"},{\"t\":10,\"p\":1,\"n\":\"Quests\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Quest\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"NNAM - Quest\"},{\"t\":11,\"n\":\"FNAM - Unknown\"},{\"t\":5,\"p\":1,\"n\":\"RNAM - Hours until reset\"}]}]}]},{\"t\":1,\"p\":1,\"n\":\"SNCT - Sound Category\",\"f\":1,\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":3,\"p\":1,\"n\":\"FNAM - Flags\"},{\"t\":3,\"p\":1,\"n\":\"PNAM - Parent\"},{\"t\":3,\"p\":1,\"n\":\"VNAM - Static Volume Multiplier\"},{\"t\":3,\"p\":1,\"n\":\"UNAM - Default Menu Value\"}]},{\"t\":1,\"p\":1,\"n\":\"SNDR - Sound Descriptor\",\"f\":1,\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":11,\"n\":\"CNAM - Unknown\"},{\"t\":3,\"p\":1,\"n\":\"GNAM - Category\"},{\"t\":3,\"p\":1,\"n\":\"SNAM - Alternate Sound For\"},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Sounds\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Sound Files\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"ANAM - File Name\"}]}]},{\"t\":3,\"p\":1,\"n\":\"ONAM - Output Model\"},{\"t\":2,\"p\":1,\"n\":\"FNAM - String\"},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Conditions\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Condition\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"CTDA - \",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":5,\"p\":1,\"n\":\"Comparison Value - Float\"},{\"t\":3,\"p\":1,\"n\":\"Comparison Value - Global\"},{\"t\":3,\"p\":1,\"n\":\"Function\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":11,\"p\":1,\"n\":\"None\"},{\"t\":3,\"p\":1,\"n\":\"Integer\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":11,\"p\":1,\"n\":\"Variable Name (unused)\"},{\"t\":3,\"p\":1,\"n\":\"Sex\"},{\"t\":3,\"p\":1,\"n\":\"Actor Value\"},{\"t\":3,\"p\":1,\"n\":\"Crime Type\"},{\"t\":3,\"p\":1,\"n\":\"Axis\"},{\"t\":3,\"p\":1,\"n\":\"Quest Stage (unused)\"},{\"t\":3,\"p\":1,\"n\":\"Misc Stat\"},{\"t\":3,\"p\":1,\"n\":\"Alignment\"},{\"t\":3,\"p\":1,\"n\":\"Equip Type\"},{\"t\":3,\"p\":1,\"n\":\"Form Type\"},{\"t\":3,\"p\":1,\"n\":\"Critical Stage\"},{\"t\":3,\"p\":1,\"n\":\"Object Reference\"},{\"t\":3,\"p\":1,\"n\":\"Inventory Object\"},{\"t\":3,\"p\":1,\"n\":\"Actor\"},{\"t\":3,\"p\":1,\"n\":\"Voice Type\"},{\"t\":3,\"p\":1,\"n\":\"Idle\"},{\"t\":3,\"p\":1,\"n\":\"Form List\"},{\"t\":3,\"p\":1,\"n\":\"Quest\"},{\"t\":3,\"p\":1,\"n\":\"Faction\"},{\"t\":3,\"p\":1,\"n\":\"Cell\"},{\"t\":3,\"p\":1,\"n\":\"Class\"},{\"t\":3,\"p\":1,\"n\":\"Race\"},{\"t\":3,\"p\":1,\"n\":\"Actor Base\"},{\"t\":3,\"p\":1,\"n\":\"Global\"},{\"t\":3,\"p\":1,\"n\":\"Weather\"},{\"t\":3,\"p\":1,\"n\":\"Package\"},{\"t\":3,\"p\":1,\"n\":\"Encounter Zone\"},{\"t\":3,\"p\":1,\"n\":\"Perk\"},{\"t\":3,\"p\":1,\"n\":\"Owner\"},{\"t\":3,\"p\":1,\"n\":\"Furniture\"},{\"t\":3,\"p\":1,\"n\":\"Effect Item\"},{\"t\":3,\"p\":1,\"n\":\"Base Effect\"},{\"t\":3,\"p\":1,\"n\":\"Worldspace\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Function\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Param (INVALID)\"},{\"t\":3,\"p\":1,\"n\":\"Referenceable Object\"},{\"t\":3,\"p\":1,\"n\":\"Region\"},{\"t\":3,\"p\":1,\"n\":\"Keyword\"},{\"t\":3,\"p\":1,\"n\":\"Player Action\"},{\"t\":3,\"p\":1,\"n\":\"Casting Type\"},{\"t\":3,\"p\":1,\"n\":\"Shout\"},{\"t\":3,\"p\":1,\"n\":\"Location\"},{\"t\":3,\"p\":1,\"n\":\"Location Ref Type\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"Packdata ID\"},{\"t\":3,\"p\":1,\"n\":\"Association Type\"},{\"t\":3,\"p\":1,\"n\":\"Furniture Anim\"},{\"t\":3,\"p\":1,\"n\":\"Furniture Entry\"},{\"t\":3,\"p\":1,\"n\":\"Scene\"},{\"t\":3,\"p\":1,\"n\":\"Ward State\"},{\"t\":3,\"p\":1,\"n\":\"Event\"},{\"t\":3,\"p\":1,\"n\":\"Event Data\"},{\"t\":3,\"p\":1,\"n\":\"Quest Stage\"},{\"t\":3,\"p\":1,\"n\":\"Weapon\"},{\"t\":3,\"p\":1,\"n\":\"Weapon List\"},{\"t\":3,\"p\":1,\"n\":\"Target\"},{\"t\":3,\"p\":1,\"n\":\"Target List\"},{\"t\":3,\"p\":1,\"n\":\"Target Part\"},{\"t\":3,\"p\":1,\"n\":\"VATS Action\"},{\"t\":3,\"p\":1,\"n\":\"Critical Effect\"},{\"t\":3,\"p\":1,\"n\":\"Critical Effect List\"},{\"t\":3,\"p\":1,\"n\":\"Weapon Type\"},{\"t\":3,\"p\":1,\"n\":\"Projectile Type\"},{\"t\":3,\"p\":1,\"n\":\"Delivery Type\"},{\"t\":3,\"p\":1,\"n\":\"Run On\"},{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":3,\"p\":1,\"n\":\"Parameter #3\"}]},{\"t\":2,\"p\":1,\"n\":\"CIS1 - Parameter #1\"},{\"t\":2,\"p\":1,\"n\":\"CIS2 - Parameter #2\"}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"LNAM - Values\",\"c\":[{\"t\":11,\"n\":\"Unknown\"},{\"t\":3,\"p\":1,\"n\":\"Looping\"},{\"t\":3,\"p\":1,\"n\":\"Rumble Send Value = (Small \\/ 7) + ((Big \\/ 7) * 16)\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"BNAM - Values\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"% Frequency Shift\"},{\"t\":3,\"p\":1,\"n\":\"% Frequency Variance\"},{\"t\":3,\"p\":1,\"n\":\"Priority\"},{\"t\":3,\"p\":1,\"n\":\"db Variance\"},{\"t\":3,\"p\":1,\"n\":\"Static Attenuation (db)\"}]}]},{\"t\":1,\"p\":1,\"n\":\"SOPM - Sound Output Model\",\"f\":1,\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"NAM1 - Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":3,\"p\":1,\"n\":\"Reverb Send %\"}]},{\"t\":11,\"n\":\"FNAM - Unknown\"},{\"t\":3,\"p\":1,\"n\":\"MNAM - Type\"},{\"t\":11,\"n\":\"CNAM - Unknown\"},{\"t\":11,\"n\":\"SNAM - Unknown\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"ONAM - Output Values\",\"c\":[{\"t\":7,\"p\":1,\"n\":\"Channels\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"L\"},{\"t\":3,\"p\":1,\"n\":\"R\"},{\"t\":3,\"p\":1,\"n\":\"C\"},{\"t\":3,\"p\":1,\"n\":\"LFE\"},{\"t\":3,\"p\":1,\"n\":\"RL\"},{\"t\":3,\"p\":1,\"n\":\"RR\"},{\"t\":3,\"p\":1,\"n\":\"BL\"},{\"t\":3,\"p\":1,\"n\":\"BR\"}]}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"ANAM - Attenuation Values\",\"c\":[{\"t\":11,\"n\":\"Unknown\"},{\"t\":5,\"p\":1,\"n\":\"Min Distance\"},{\"t\":5,\"p\":1,\"n\":\"Max Distance\"},{\"t\":7,\"p\":1,\"n\":\"Curve\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Value\"}]}]}]},{\"t\":1,\"p\":1,\"n\":\"SOUN - Sound Marker\",\"f\":1,\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"X1\"},{\"t\":3,\"p\":1,\"n\":\"Y1\"},{\"t\":3,\"p\":1,\"n\":\"Z1\"},{\"t\":3,\"p\":1,\"n\":\"X2\"},{\"t\":3,\"p\":1,\"n\":\"Y2\"},{\"t\":3,\"p\":1,\"n\":\"Z2\"}]},{\"t\":11,\"n\":\"FNAM - Unknown\"},{\"t\":11,\"n\":\"SNDD - Unknown\"},{\"t\":3,\"p\":1,\"n\":\"SDSC - Sound Descriptor\"}]},{\"t\":1,\"p\":1,\"n\":\"SPEL - Spell\",\"f\":1,\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"X1\"},{\"t\":3,\"p\":1,\"n\":\"Y1\"},{\"t\":3,\"p\":1,\"n\":\"Z1\"},{\"t\":3,\"p\":1,\"n\":\"X2\"},{\"t\":3,\"p\":1,\"n\":\"Y2\"},{\"t\":3,\"p\":1,\"n\":\"Z2\"}]},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":3,\"n\":\"KSIZ - Keyword Count\"},{\"t\":7,\"p\":1,\"n\":\"KWDA - Keywords\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Keyword\"}]},{\"t\":3,\"p\":1,\"n\":\"MDOB - Menu Display Object\"},{\"t\":3,\"p\":1,\"n\":\"ETYP - Equipment Type\"},{\"t\":2,\"p\":1,\"n\":\"DESC - Description\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"SPIT - Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Base Cost\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":5,\"p\":1,\"n\":\"Charge Time\"},{\"t\":3,\"p\":1,\"n\":\"Cast Type\"},{\"t\":3,\"p\":1,\"n\":\"Target Type\"},{\"t\":5,\"p\":1,\"n\":\"Cast Duration\"},{\"t\":5,\"p\":1,\"n\":\"Range\"},{\"t\":3,\"p\":1,\"n\":\"Half-cost Perk\"}]},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Effects\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Effect\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"EFID - Base Effect\"},{\"t\":6,\"p\":1,\"n\":\"EFIT - \",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Magnitude\"},{\"t\":3,\"p\":1,\"n\":\"Area\"},{\"t\":3,\"p\":1,\"n\":\"Duration\"}]},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Conditions\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Condition\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"CTDA - \",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":5,\"p\":1,\"n\":\"Comparison Value - Float\"},{\"t\":3,\"p\":1,\"n\":\"Comparison Value - Global\"},{\"t\":3,\"p\":1,\"n\":\"Function\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":11,\"p\":1,\"n\":\"None\"},{\"t\":3,\"p\":1,\"n\":\"Integer\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":11,\"p\":1,\"n\":\"Variable Name (unused)\"},{\"t\":3,\"p\":1,\"n\":\"Sex\"},{\"t\":3,\"p\":1,\"n\":\"Actor Value\"},{\"t\":3,\"p\":1,\"n\":\"Crime Type\"},{\"t\":3,\"p\":1,\"n\":\"Axis\"},{\"t\":3,\"p\":1,\"n\":\"Quest Stage (unused)\"},{\"t\":3,\"p\":1,\"n\":\"Misc Stat\"},{\"t\":3,\"p\":1,\"n\":\"Alignment\"},{\"t\":3,\"p\":1,\"n\":\"Equip Type\"},{\"t\":3,\"p\":1,\"n\":\"Form Type\"},{\"t\":3,\"p\":1,\"n\":\"Critical Stage\"},{\"t\":3,\"p\":1,\"n\":\"Object Reference\"},{\"t\":3,\"p\":1,\"n\":\"Inventory Object\"},{\"t\":3,\"p\":1,\"n\":\"Actor\"},{\"t\":3,\"p\":1,\"n\":\"Voice Type\"},{\"t\":3,\"p\":1,\"n\":\"Idle\"},{\"t\":3,\"p\":1,\"n\":\"Form List\"},{\"t\":3,\"p\":1,\"n\":\"Quest\"},{\"t\":3,\"p\":1,\"n\":\"Faction\"},{\"t\":3,\"p\":1,\"n\":\"Cell\"},{\"t\":3,\"p\":1,\"n\":\"Class\"},{\"t\":3,\"p\":1,\"n\":\"Race\"},{\"t\":3,\"p\":1,\"n\":\"Actor Base\"},{\"t\":3,\"p\":1,\"n\":\"Global\"},{\"t\":3,\"p\":1,\"n\":\"Weather\"},{\"t\":3,\"p\":1,\"n\":\"Package\"},{\"t\":3,\"p\":1,\"n\":\"Encounter Zone\"},{\"t\":3,\"p\":1,\"n\":\"Perk\"},{\"t\":3,\"p\":1,\"n\":\"Owner\"},{\"t\":3,\"p\":1,\"n\":\"Furniture\"},{\"t\":3,\"p\":1,\"n\":\"Effect Item\"},{\"t\":3,\"p\":1,\"n\":\"Base Effect\"},{\"t\":3,\"p\":1,\"n\":\"Worldspace\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Function\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Param (INVALID)\"},{\"t\":3,\"p\":1,\"n\":\"Referenceable Object\"},{\"t\":3,\"p\":1,\"n\":\"Region\"},{\"t\":3,\"p\":1,\"n\":\"Keyword\"},{\"t\":3,\"p\":1,\"n\":\"Player Action\"},{\"t\":3,\"p\":1,\"n\":\"Casting Type\"},{\"t\":3,\"p\":1,\"n\":\"Shout\"},{\"t\":3,\"p\":1,\"n\":\"Location\"},{\"t\":3,\"p\":1,\"n\":\"Location Ref Type\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"Packdata ID\"},{\"t\":3,\"p\":1,\"n\":\"Association Type\"},{\"t\":3,\"p\":1,\"n\":\"Furniture Anim\"},{\"t\":3,\"p\":1,\"n\":\"Furniture Entry\"},{\"t\":3,\"p\":1,\"n\":\"Scene\"},{\"t\":3,\"p\":1,\"n\":\"Ward State\"},{\"t\":3,\"p\":1,\"n\":\"Event\"},{\"t\":3,\"p\":1,\"n\":\"Event Data\"},{\"t\":3,\"p\":1,\"n\":\"Quest Stage\"},{\"t\":3,\"p\":1,\"n\":\"Weapon\"},{\"t\":3,\"p\":1,\"n\":\"Weapon List\"},{\"t\":3,\"p\":1,\"n\":\"Target\"},{\"t\":3,\"p\":1,\"n\":\"Target List\"},{\"t\":3,\"p\":1,\"n\":\"Target Part\"},{\"t\":3,\"p\":1,\"n\":\"VATS Action\"},{\"t\":3,\"p\":1,\"n\":\"Critical Effect\"},{\"t\":3,\"p\":1,\"n\":\"Critical Effect List\"},{\"t\":3,\"p\":1,\"n\":\"Weapon Type\"},{\"t\":3,\"p\":1,\"n\":\"Projectile Type\"},{\"t\":3,\"p\":1,\"n\":\"Delivery Type\"},{\"t\":3,\"p\":1,\"n\":\"Run On\"},{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":3,\"p\":1,\"n\":\"Parameter #3\"}]},{\"t\":2,\"p\":1,\"n\":\"CIS1 - Parameter #1\"},{\"t\":2,\"p\":1,\"n\":\"CIS2 - Parameter #2\"}]}]}]}]}]},{\"t\":1,\"p\":1,\"n\":\"SPGD - Shader Particle Geometry\",\"f\":1,\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Data\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Gravity Velocity\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":5,\"p\":1,\"n\":\"Rotation Velocity\"},{\"t\":5,\"p\":1,\"n\":\"Particle Size X\"},{\"t\":5,\"p\":1,\"n\":\"Center Offset Min\"},{\"t\":5,\"p\":1,\"n\":\"Particle Size Y\"},{\"t\":5,\"p\":1,\"n\":\"Center Offset Max\"},{\"t\":5,\"p\":1,\"n\":\"Initial Rotation\"},{\"t\":3,\"p\":1,\"n\":\"# of Subtextures X\"},{\"t\":3,\"p\":1,\"n\":\"# of Subtextures Y\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Box Size\"},{\"t\":5,\"p\":1,\"n\":\"Particle Density\"}]},{\"t\":2,\"p\":1,\"n\":\"ICON - Particle Texture\"}]},{\"t\":1,\"p\":1,\"n\":\"STAT - Static\",\"f\":1,\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"X1\"},{\"t\":3,\"p\":1,\"n\":\"Y1\"},{\"t\":3,\"p\":1,\"n\":\"Z1\"},{\"t\":3,\"p\":1,\"n\":\"X2\"},{\"t\":3,\"p\":1,\"n\":\"Y2\"},{\"t\":3,\"p\":1,\"n\":\"Z2\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"MODT - Texture Files Hashes\"},{\"t\":7,\"p\":1,\"n\":\"MODS - Alternate Textures\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"3D Name\"},{\"t\":3,\"p\":1,\"n\":\"New Texture\"},{\"t\":3,\"p\":1,\"n\":\"3D Index\"}]}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DNAM - Direction Material\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Max Angle (30-120)\"},{\"t\":3,\"p\":1,\"n\":\"Material\"}]},{\"t\":7,\"p\":1,\"n\":\"MNAM - Distant LOD\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"LOD\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"Mesh\"}]}]}]},{\"t\":1,\"p\":1,\"n\":\"TACT - Talking Activator\",\"f\":1,\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"VMAD - Virtual Machine Adapter\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Version\"},{\"t\":3,\"p\":1,\"n\":\"Object Format\"},{\"t\":7,\"p\":1,\"n\":\"Scripts\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Script\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"scriptName\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":7,\"p\":1,\"n\":\"Properties\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Property\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"propertyName\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]},{\"t\":2,\"p\":1,\"n\":\"String\"},{\"t\":3,\"p\":1,\"n\":\"Int32\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":3,\"p\":1,\"n\":\"Bool\"},{\"t\":7,\"p\":1,\"n\":\"Array of Object\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]}]},{\"t\":7,\"p\":1,\"n\":\"Array of String\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Int32\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Float\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Bool\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]}]}]}]}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"X1\"},{\"t\":3,\"p\":1,\"n\":\"Y1\"},{\"t\":3,\"p\":1,\"n\":\"Z1\"},{\"t\":3,\"p\":1,\"n\":\"X2\"},{\"t\":3,\"p\":1,\"n\":\"Y2\"},{\"t\":3,\"p\":1,\"n\":\"Z2\"}]},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"MODT - Texture Files Hashes\"},{\"t\":7,\"p\":1,\"n\":\"MODS - Alternate Textures\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"3D Name\"},{\"t\":3,\"p\":1,\"n\":\"New Texture\"},{\"t\":3,\"p\":1,\"n\":\"3D Index\"}]}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Destructable\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"DEST - Header\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Health\"},{\"t\":3,\"p\":1,\"n\":\"DEST Count\"},{\"t\":3,\"p\":1,\"n\":\"VATS Targetable\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":8,\"p\":1,\"n\":\"Stages\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Stage\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"DSTD - Destruction Stage Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Health %\"},{\"t\":3,\"p\":1,\"n\":\"Index\"},{\"t\":3,\"p\":1,\"n\":\"Model Damage Stage\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":3,\"p\":1,\"n\":\"Self Damage per Second\"},{\"t\":3,\"p\":1,\"n\":\"Explosion\"},{\"t\":3,\"p\":1,\"n\":\"Debris\"},{\"t\":3,\"p\":1,\"n\":\"Debris Count\"}]},{\"t\":6,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"DMDL - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"DMDT - Texture Files Hashes\"},{\"t\":7,\"p\":1,\"n\":\"DMDS - Alternate Textures\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"3D Name\"},{\"t\":3,\"p\":1,\"n\":\"New Texture\"},{\"t\":3,\"p\":1,\"n\":\"3D Index\"}]}]}]},{\"p\":1,\"n\":\"DSTF - End Marker\"}]}]}]},{\"t\":3,\"n\":\"KSIZ - Keyword Count\"},{\"t\":7,\"p\":1,\"n\":\"KWDA - Keywords\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Keyword\"}]},{\"t\":11,\"n\":\"PNAM - Unknown\"},{\"t\":3,\"p\":1,\"n\":\"SNAM - Looping Sound\"},{\"t\":11,\"n\":\"FNAM - Unknown\"},{\"t\":3,\"p\":1,\"n\":\"VNAM - Voice Type\"}]},{\"t\":1,\"p\":1,\"n\":\"TREE - Tree\",\"f\":1,\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"VMAD - Virtual Machine Adapter\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Version\"},{\"t\":3,\"p\":1,\"n\":\"Object Format\"},{\"t\":7,\"p\":1,\"n\":\"Scripts\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Script\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"scriptName\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":7,\"p\":1,\"n\":\"Properties\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Property\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"propertyName\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]},{\"t\":2,\"p\":1,\"n\":\"String\"},{\"t\":3,\"p\":1,\"n\":\"Int32\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":3,\"p\":1,\"n\":\"Bool\"},{\"t\":7,\"p\":1,\"n\":\"Array of Object\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]}]},{\"t\":7,\"p\":1,\"n\":\"Array of String\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Int32\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Float\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Bool\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]}]}]}]}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"X1\"},{\"t\":3,\"p\":1,\"n\":\"Y1\"},{\"t\":3,\"p\":1,\"n\":\"Z1\"},{\"t\":3,\"p\":1,\"n\":\"X2\"},{\"t\":3,\"p\":1,\"n\":\"Y2\"},{\"t\":3,\"p\":1,\"n\":\"Z2\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"MODT - Texture Files Hashes\"},{\"t\":7,\"p\":1,\"n\":\"MODS - Alternate Textures\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"3D Name\"},{\"t\":3,\"p\":1,\"n\":\"New Texture\"},{\"t\":3,\"p\":1,\"n\":\"3D Index\"}]}]}]},{\"t\":3,\"p\":1,\"n\":\"PFIG - Ingredient\"},{\"t\":3,\"p\":1,\"n\":\"SNAM - Harvest Sound\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"PFPC - Ingredient Production\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Spring\"},{\"t\":3,\"p\":1,\"n\":\"Summer\"},{\"t\":3,\"p\":1,\"n\":\"Fall\"},{\"t\":3,\"p\":1,\"n\":\"Winter\"}]},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"CNAM - Tree Data\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Trunk Flexibility\"},{\"t\":5,\"p\":1,\"n\":\"Branch Flexibility\"},{\"t\":5,\"n\":\"Unknown\"},{\"t\":5,\"p\":1,\"n\":\"Leaf Amplitude\"},{\"t\":5,\"p\":1,\"n\":\"Leaf Frequency\"}]}]},{\"t\":1,\"p\":1,\"n\":\"TXST - Texture Set\",\"f\":1,\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"X1\"},{\"t\":3,\"p\":1,\"n\":\"Y1\"},{\"t\":3,\"p\":1,\"n\":\"Z1\"},{\"t\":3,\"p\":1,\"n\":\"X2\"},{\"t\":3,\"p\":1,\"n\":\"Y2\"},{\"t\":3,\"p\":1,\"n\":\"Z2\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Textures (RGB\\/A)\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"TX00 - Difuse\"},{\"t\":2,\"p\":1,\"n\":\"TX01 - Normal\\/Gloss\"},{\"t\":2,\"p\":1,\"n\":\"TX02 - Environment Mask\\/Subsurface Tint\"},{\"t\":2,\"p\":1,\"n\":\"TX03 - Glow\\/Detail Map\"},{\"t\":2,\"p\":1,\"n\":\"TX04 - Height\"},{\"t\":2,\"p\":1,\"n\":\"TX05 - Environment\"},{\"t\":2,\"p\":1,\"n\":\"TX06 - Multilayer\"},{\"t\":2,\"p\":1,\"n\":\"TX07 - Backlight Mask\\/Specular\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DODT - Decal Data\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Min Width\"},{\"t\":5,\"p\":1,\"n\":\"Max Width\"},{\"t\":5,\"p\":1,\"n\":\"Min Height\"},{\"t\":5,\"p\":1,\"n\":\"Max Height\"},{\"t\":5,\"p\":1,\"n\":\"Depth\"},{\"t\":5,\"p\":1,\"n\":\"Shininess\"},{\"t\":6,\"p\":1,\"n\":\"Parallax\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Scale\"},{\"t\":3,\"p\":1,\"n\":\"Passes\"}]},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":6,\"p\":1,\"n\":\"Color\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]}]},{\"t\":3,\"p\":1,\"n\":\"DNAM - Flags\"}]},{\"t\":1,\"p\":1,\"n\":\"VOLI - Volumetric Lighting\",\"f\":1,\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":5,\"p\":1,\"n\":\"CNAM - Intensity\"},{\"t\":5,\"p\":1,\"n\":\"DNAM - Custom Color - Contribution\"},{\"t\":5,\"p\":1,\"n\":\"ENAM - Red\"},{\"t\":5,\"p\":1,\"n\":\"FNAM - Green\"},{\"t\":5,\"p\":1,\"n\":\"GNAM - Blue\"},{\"t\":5,\"p\":1,\"n\":\"HNAM - Density - Contribution\"},{\"t\":5,\"p\":1,\"n\":\"INAM - Density - Size\"},{\"t\":5,\"p\":1,\"n\":\"JNAM - Density - Wind Speed\"},{\"t\":5,\"p\":1,\"n\":\"KNAM - Density - Falling Speed\"},{\"t\":5,\"p\":1,\"n\":\"LNAM - Phase Function - Contribution\"},{\"t\":5,\"p\":1,\"n\":\"MNAM - Phase Function - Scattering\"},{\"t\":5,\"p\":1,\"n\":\"NNAM - Sampling Repartition - Range Factor\"}]},{\"t\":1,\"p\":1,\"n\":\"VTYP - Voice Type\",\"f\":1,\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":3,\"p\":1,\"n\":\"DNAM - Flags\"}]},{\"t\":1,\"p\":1,\"n\":\"WATR - Water\",\"f\":1,\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":8,\"n\":\"Unused\",\"c\":[{\"t\":2,\"n\":\"NNAM - Noise Map\"}]},{\"t\":3,\"p\":1,\"n\":\"ANAM - Opacity\"},{\"t\":3,\"p\":1,\"n\":\"FNAM - Flags\"},{\"t\":11,\"n\":\"MNAM - Unused\"},{\"t\":3,\"p\":1,\"n\":\"TNAM - Material\"},{\"t\":3,\"p\":1,\"n\":\"SNAM - Open Sound\"},{\"t\":3,\"p\":1,\"n\":\"XNAM - Spell\"},{\"t\":3,\"p\":1,\"n\":\"INAM - Image Space\"},{\"t\":3,\"p\":1,\"n\":\"DATA - Damage Per Second\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DNAM - Visual Data\",\"c\":[{\"t\":5,\"n\":\"Unknown\"},{\"t\":5,\"p\":1,\"n\":\"Specular Properties - Sun Specular Power\"},{\"t\":5,\"p\":1,\"n\":\"Water Properties - Reflectivity Amount\"},{\"t\":5,\"p\":1,\"n\":\"Water Properties - Fresnel Amount\"},{\"t\":5,\"p\":1,\"n\":\"Fog Properties - Above Water - Fog Distance - Near Plane\"},{\"t\":5,\"p\":1,\"n\":\"Fog Properties - Above Water - Fog Distance - Far Plane\"},{\"t\":6,\"p\":1,\"n\":\"Shallow Color\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Deep Color\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Reflection Color\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":5,\"p\":1,\"n\":\"Displacement Simulator - Starting Size\"},{\"t\":5,\"p\":1,\"n\":\"Displacement Simulator - Force\"},{\"t\":5,\"p\":1,\"n\":\"Displacement Simulator - Velocity\"},{\"t\":5,\"p\":1,\"n\":\"Displacement Simulator - Falloff\"},{\"t\":5,\"p\":1,\"n\":\"Displacement Simulator - Dampner\"},{\"t\":5,\"p\":1,\"n\":\"Noise Properties - Noise Falloff\"},{\"t\":5,\"p\":1,\"n\":\"Noise Properties - Layer One - Wind Direction\"},{\"t\":5,\"p\":1,\"n\":\"Noise Properties - Layer Two - Wind Direction\"},{\"t\":5,\"p\":1,\"n\":\"Noise Properties - Layer Three - Wind Direction\"},{\"t\":5,\"p\":1,\"n\":\"Noise Properties - Layer One - Wind Speed\"},{\"t\":5,\"p\":1,\"n\":\"Noise Properties - Layer Two - Wind Speed\"},{\"t\":5,\"p\":1,\"n\":\"Noise Properties - Layer Three - Wind Speed\"},{\"t\":5,\"p\":1,\"n\":\"Fog Properties - Above Water - Fog Amount\"},{\"t\":5,\"p\":1,\"n\":\"Fog Properties - Under Water - Fog Amount\"},{\"t\":5,\"p\":1,\"n\":\"Fog Properties - Under Water - Fog Distance - Near Plane\"},{\"t\":5,\"p\":1,\"n\":\"Fog Properties - Under Water - Fog Distance - Far Plane\"},{\"t\":5,\"p\":1,\"n\":\"Water Properties - Refraction Magnitude\"},{\"t\":5,\"p\":1,\"n\":\"Specular Properties - Specular Power\"},{\"t\":5,\"p\":1,\"n\":\"Specular Properties - Specular Radius\"},{\"t\":5,\"p\":1,\"n\":\"Specular Properties - Specular Brightness\"},{\"t\":5,\"p\":1,\"n\":\"Noise Properties - Layer One - UV Scale\"},{\"t\":5,\"p\":1,\"n\":\"Noise Properties - Layer Two - UV Scale\"},{\"t\":5,\"p\":1,\"n\":\"Noise Properties - Layer Three - UV Scale\"},{\"t\":5,\"p\":1,\"n\":\"Noise Properties - Layer One - Amplitude Scale\"},{\"t\":5,\"p\":1,\"n\":\"Noise Properties - Layer Two - Amplitude Scale\"},{\"t\":5,\"p\":1,\"n\":\"Noise Properties - Layer Three - Amplitude Scale\"},{\"t\":5,\"p\":1,\"n\":\"Water Properties - Reflection Magnitude\"},{\"t\":5,\"p\":1,\"n\":\"Specular Properties - Sun Sparkle Magnitude\"},{\"t\":5,\"p\":1,\"n\":\"Specular Properties - Sun Specular Magnitude\"},{\"t\":5,\"p\":1,\"n\":\"Depth Properties - Reflections\"},{\"t\":5,\"p\":1,\"n\":\"Depth Properties - Refraction\"},{\"t\":5,\"p\":1,\"n\":\"Depth Properties - Normals\"},{\"t\":5,\"p\":1,\"n\":\"Depth Properties - Specular Lighting\"},{\"t\":5,\"p\":1,\"n\":\"Specular Properties - Sun Sparkle Power\"}]},{\"t\":11,\"n\":\"GNAM - Unused\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"NAM0 - Linear Velocity\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"X\"},{\"t\":5,\"p\":1,\"n\":\"Y\"},{\"t\":5,\"p\":1,\"n\":\"Z\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"NAM1 - Angular Velocity\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"X\"},{\"t\":5,\"p\":1,\"n\":\"Y\"},{\"t\":5,\"p\":1,\"n\":\"Z\"}]},{\"t\":2,\"p\":1,\"n\":\"NAM2 - Noise Layer One - Noise Texture\"},{\"t\":2,\"p\":1,\"n\":\"NAM3 - Noise Layer Two - Noise Texture\"},{\"t\":2,\"p\":1,\"n\":\"NAM4 - Noise Layer Three - Noise Texture\"},{\"t\":2,\"p\":1,\"n\":\"NAM5 - Flow Normals - Noise Texture\"}]},{\"t\":1,\"p\":1,\"n\":\"WEAP - Weapon\",\"f\":1,\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"VMAD - Virtual Machine Adapter\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Version\"},{\"t\":3,\"p\":1,\"n\":\"Object Format\"},{\"t\":7,\"p\":1,\"n\":\"Scripts\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Script\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"scriptName\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":7,\"p\":1,\"n\":\"Properties\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Property\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"propertyName\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]},{\"t\":2,\"p\":1,\"n\":\"String\"},{\"t\":3,\"p\":1,\"n\":\"Int32\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":3,\"p\":1,\"n\":\"Bool\"},{\"t\":7,\"p\":1,\"n\":\"Array of Object\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]}]},{\"t\":7,\"p\":1,\"n\":\"Array of String\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Int32\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Float\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Bool\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]}]}]}]}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"X1\"},{\"t\":3,\"p\":1,\"n\":\"Y1\"},{\"t\":3,\"p\":1,\"n\":\"Z1\"},{\"t\":3,\"p\":1,\"n\":\"X2\"},{\"t\":3,\"p\":1,\"n\":\"Y2\"},{\"t\":3,\"p\":1,\"n\":\"Z2\"}]},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"MODT - Texture Files Hashes\"},{\"t\":7,\"p\":1,\"n\":\"MODS - Alternate Textures\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"3D Name\"},{\"t\":3,\"p\":1,\"n\":\"New Texture\"},{\"t\":3,\"p\":1,\"n\":\"3D Index\"}]}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Icon\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"ICON - Large Icon filename\"},{\"t\":2,\"p\":1,\"n\":\"MICO - Small Icon filename\"}]},{\"t\":3,\"p\":1,\"n\":\"EITM - Object Effect\"},{\"t\":3,\"p\":1,\"n\":\"EAMT - Enchantment Amount\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Destructable\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"DEST - Header\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Health\"},{\"t\":3,\"p\":1,\"n\":\"DEST Count\"},{\"t\":3,\"p\":1,\"n\":\"VATS Targetable\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":8,\"p\":1,\"n\":\"Stages\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Stage\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"DSTD - Destruction Stage Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Health %\"},{\"t\":3,\"p\":1,\"n\":\"Index\"},{\"t\":3,\"p\":1,\"n\":\"Model Damage Stage\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":3,\"p\":1,\"n\":\"Self Damage per Second\"},{\"t\":3,\"p\":1,\"n\":\"Explosion\"},{\"t\":3,\"p\":1,\"n\":\"Debris\"},{\"t\":3,\"p\":1,\"n\":\"Debris Count\"}]},{\"t\":6,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"DMDL - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"DMDT - Texture Files Hashes\"},{\"t\":7,\"p\":1,\"n\":\"DMDS - Alternate Textures\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"3D Name\"},{\"t\":3,\"p\":1,\"n\":\"New Texture\"},{\"t\":3,\"p\":1,\"n\":\"3D Index\"}]}]}]},{\"p\":1,\"n\":\"DSTF - End Marker\"}]}]}]},{\"t\":3,\"p\":1,\"n\":\"ETYP - Equipment Type\"},{\"t\":3,\"p\":1,\"n\":\"BIDS - Block Bash Impact Data Set\"},{\"t\":3,\"p\":1,\"n\":\"BAMT - Alternate Block Material\"},{\"t\":3,\"p\":1,\"n\":\"YNAM - Sound - Pick Up\"},{\"t\":3,\"p\":1,\"n\":\"ZNAM - Sound - Put Down\"},{\"t\":3,\"n\":\"KSIZ - Keyword Count\"},{\"t\":7,\"p\":1,\"n\":\"KWDA - Keywords\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Keyword\"}]},{\"t\":2,\"p\":1,\"n\":\"DESC - Description\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Has Scope\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MOD3 - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"MO3T - Texture Files Hashes\"},{\"t\":7,\"p\":1,\"n\":\"MO3S - Alternate Textures\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"3D Name\"},{\"t\":3,\"p\":1,\"n\":\"New Texture\"},{\"t\":3,\"p\":1,\"n\":\"3D Index\"}]}]}]},{\"t\":11,\"n\":\"NNAM - Unused\"},{\"t\":3,\"p\":1,\"n\":\"INAM - Impact Data Set\"},{\"t\":3,\"p\":1,\"n\":\"WNAM - 1st Person Model Object\"},{\"t\":3,\"p\":1,\"n\":\"SNAM - Attack Sound\"},{\"t\":3,\"p\":1,\"n\":\"XNAM - Attack Sound 2D\"},{\"t\":3,\"p\":1,\"n\":\"NAM7 - Attack Loop Sound\"},{\"t\":3,\"p\":1,\"n\":\"TNAM - Attack Fail Sound\"},{\"t\":3,\"p\":1,\"n\":\"UNAM - Idle Sound\"},{\"t\":3,\"p\":1,\"n\":\"NAM9 - Equip Sound\"},{\"t\":3,\"p\":1,\"n\":\"NAM8 - Unequip Sound\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DATA - Game Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Value\"},{\"t\":5,\"p\":1,\"n\":\"Weight\"},{\"t\":3,\"p\":1,\"n\":\"Damage\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DNAM - Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Animation Type\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":5,\"p\":1,\"n\":\"Speed\"},{\"t\":5,\"p\":1,\"n\":\"Reach\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":5,\"p\":1,\"n\":\"Sight FOV\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":3,\"p\":1,\"n\":\"Base VATS To-Hit Chance\"},{\"t\":3,\"p\":1,\"n\":\"Attack Animation\"},{\"t\":3,\"p\":1,\"n\":\"# Projectiles\"},{\"t\":3,\"p\":1,\"n\":\"Embedded Weapon AV (unused)\"},{\"t\":5,\"p\":1,\"n\":\"Range Min\"},{\"t\":5,\"p\":1,\"n\":\"Range Max\"},{\"t\":3,\"p\":1,\"n\":\"On Hit\"},{\"t\":3,\"p\":1,\"n\":\"Flags2\"},{\"t\":5,\"p\":1,\"n\":\"Animation Attack Mult\"},{\"t\":5,\"p\":1,\"n\":\"Rumble - Left Motor Strength\"},{\"t\":5,\"p\":1,\"n\":\"Rumble - Right Motor Strength\"},{\"t\":5,\"p\":1,\"n\":\"Rumble - Duration\"},{\"t\":3,\"p\":1,\"n\":\"Skill\"},{\"t\":3,\"p\":1,\"n\":\"Resist\"},{\"t\":5,\"p\":1,\"n\":\"Stagger\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"CRDT - Critical Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Damage\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":5,\"p\":1,\"n\":\"% Mult\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Effect\"}]},{\"t\":3,\"p\":1,\"n\":\"VNAM - Detection Sound Level\"},{\"t\":3,\"p\":1,\"n\":\"CNAM - Template\"}]},{\"t\":1,\"p\":1,\"n\":\"WOOP - Word of Power\",\"f\":1,\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":2,\"p\":1,\"n\":\"TNAM - Translation\"}]},{\"t\":1,\"p\":1,\"n\":\"WRLD - Worldspace\",\"f\":1,\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":8,\"n\":\"Unused RNAM\",\"c\":[{\"t\":6,\"n\":\"RNAM - Grid\",\"c\":[{\"t\":3,\"n\":\"Y\"},{\"t\":3,\"n\":\"X\"},{\"t\":7,\"n\":\"References\",\"c\":[{\"t\":6,\"n\":\"Reference\",\"c\":[{\"t\":3,\"n\":\"Ref\"},{\"t\":3,\"n\":\"Y\"},{\"t\":3,\"n\":\"X\"}]}]}]}]},{\"t\":11,\"n\":\"MHDT - Max Height Data\"},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"WCTR - Fixed Dimensions Center Cell\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"X\"},{\"t\":3,\"p\":1,\"n\":\"Y\"}]},{\"t\":3,\"p\":1,\"n\":\"LTMP - Interior Lighting\"},{\"t\":3,\"p\":1,\"n\":\"XEZN - Encounter Zone\"},{\"t\":3,\"p\":1,\"n\":\"XLCN - Location\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Parent\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"WNAM - Worldspace\"},{\"t\":6,\"p\":1,\"n\":\"PNAM - \",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unknown\"}]}]},{\"t\":3,\"p\":1,\"n\":\"CNAM - Climate\"},{\"t\":3,\"p\":1,\"n\":\"NAM2 - Water\"},{\"t\":3,\"p\":1,\"n\":\"NAM3 - LOD Water Type\"},{\"t\":5,\"p\":1,\"n\":\"NAM4 - LOD Water Height\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DNAM - Land Data\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Default Land Height\"},{\"t\":5,\"p\":1,\"n\":\"Default Water Height\"}]},{\"t\":2,\"p\":1,\"n\":\"ICON - Map Image\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Cloud Model\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"MODT - Texture Files Hashes\"},{\"t\":7,\"p\":1,\"n\":\"MODS - Alternate Textures\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"3D Name\"},{\"t\":3,\"p\":1,\"n\":\"New Texture\"},{\"t\":3,\"p\":1,\"n\":\"3D Index\"}]}]}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"MNAM - Map Data\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Usable Dimensions\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"X\"},{\"t\":3,\"p\":1,\"n\":\"Y\"}]},{\"t\":6,\"p\":1,\"n\":\"Cell Coordinates\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"NW Cell\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"X\"},{\"t\":3,\"p\":1,\"n\":\"Y\"}]},{\"t\":6,\"p\":1,\"n\":\"SE Cell\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"X\"},{\"t\":3,\"p\":1,\"n\":\"Y\"}]}]},{\"t\":6,\"p\":1,\"n\":\"Camera Data\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Min Height\"},{\"t\":5,\"p\":1,\"n\":\"Max Height\"},{\"t\":5,\"p\":1,\"n\":\"Initial Pitch\"}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"ONAM - World Map Offset Data\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"World Map Scale\"},{\"t\":5,\"p\":1,\"n\":\"Cell X Offset\"},{\"t\":5,\"p\":1,\"n\":\"Cell Y Offset\"},{\"t\":5,\"p\":1,\"n\":\"Cell Z Offset\"}]},{\"t\":5,\"p\":1,\"n\":\"NAMA - Distant LOD Multiplier\"},{\"t\":3,\"p\":1,\"n\":\"DATA - Flags\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Object Bounds\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"NAM0 - Min\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"X\"},{\"t\":5,\"p\":1,\"n\":\"Y\"}]},{\"t\":6,\"p\":1,\"n\":\"NAM9 - Max\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"X\"},{\"t\":5,\"p\":1,\"n\":\"Y\"}]}]},{\"t\":3,\"p\":1,\"n\":\"ZNAM - Music\"},{\"t\":2,\"p\":1,\"n\":\"NNAM - Canopy Shadow (unused)\"},{\"t\":2,\"p\":1,\"n\":\"XNAM - Water Noise Texture\"},{\"t\":2,\"p\":1,\"n\":\"TNAM - HD LOD Diffuse Texture\"},{\"t\":2,\"p\":1,\"n\":\"UNAM - HD LOD Normal Texture\"},{\"t\":2,\"p\":1,\"n\":\"XWEM - Water Environment Map (unused)\"},{\"t\":11,\"n\":\"OFST - Offset Data\"}]},{\"t\":1,\"p\":1,\"n\":\"WTHR - Weather\",\"f\":1,\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"p\":1,\"n\":\"00TX - Cloud Texture Layer #0\"},{\"t\":2,\"p\":1,\"n\":\"10TX - Cloud Texture Layer #1\"},{\"t\":2,\"p\":1,\"n\":\"20TX - Cloud Texture Layer #2\"},{\"t\":2,\"p\":1,\"n\":\"30TX - Cloud Texture Layer #3\"},{\"t\":2,\"p\":1,\"n\":\"40TX - Cloud Texture Layer #4\"},{\"t\":2,\"p\":1,\"n\":\"50TX - Cloud Texture Layer #5\"},{\"t\":2,\"p\":1,\"n\":\"60TX - Cloud Texture Layer #6\"},{\"t\":2,\"p\":1,\"n\":\"70TX - Cloud Texture Layer #7\"},{\"t\":2,\"p\":1,\"n\":\"80TX - Cloud Texture Layer #8\"},{\"t\":2,\"p\":1,\"n\":\"90TX - Cloud Texture Layer #9\"},{\"t\":2,\"p\":1,\"n\":\":0TX - Cloud Texture Layer #10\"},{\"t\":2,\"p\":1,\"n\":\";0TX - Cloud Texture Layer #11\"},{\"t\":2,\"p\":1,\"n\":\"<0TX - Cloud Texture Layer #12\"},{\"t\":2,\"p\":1,\"n\":\"=0TX - Cloud Texture Layer #13\"},{\"t\":2,\"p\":1,\"n\":\">0TX - Cloud Texture Layer #14\"},{\"t\":2,\"p\":1,\"n\":\"?0TX - Cloud Texture Layer #15\"},{\"t\":2,\"p\":1,\"n\":\"@0TX - Cloud Texture Layer #16\"},{\"t\":2,\"p\":1,\"n\":\"A0TX - Cloud Texture Layer #17\"},{\"t\":2,\"p\":1,\"n\":\"B0TX - Cloud Texture Layer #18\"},{\"t\":2,\"p\":1,\"n\":\"C0TX - Cloud Texture Layer #19\"},{\"t\":2,\"p\":1,\"n\":\"D0TX - Cloud Texture Layer #20\"},{\"t\":2,\"p\":1,\"n\":\"E0TX - Cloud Texture Layer #21\"},{\"t\":2,\"p\":1,\"n\":\"F0TX - Cloud Texture Layer #22\"},{\"t\":2,\"p\":1,\"n\":\"G0TX - Cloud Texture Layer #23\"},{\"t\":2,\"p\":1,\"n\":\"H0TX - Cloud Texture Layer #24\"},{\"t\":2,\"p\":1,\"n\":\"I0TX - Cloud Texture Layer #25\"},{\"t\":2,\"p\":1,\"n\":\"J0TX - Cloud Texture Layer #26\"},{\"t\":2,\"p\":1,\"n\":\"K0TX - Cloud Texture Layer #27\"},{\"t\":2,\"p\":1,\"n\":\"L0TX - Cloud Texture Layer #28\"},{\"t\":11,\"n\":\"DNAM - Unused\"},{\"t\":11,\"n\":\"CNAM - Unused\"},{\"t\":11,\"n\":\"ANAM - Unused\"},{\"t\":11,\"n\":\"BNAM - Unused\"},{\"t\":11,\"n\":\"LNAM - Unknown\"},{\"t\":3,\"p\":1,\"n\":\"MNAM - Precipitation Type\"},{\"t\":3,\"p\":1,\"n\":\"NNAM - Visual Effect\"},{\"t\":11,\"n\":\"ONAM - Unused\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Cloud Speed\",\"c\":[{\"t\":7,\"p\":1,\"n\":\"RNAM - Y Speed\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Layer\"}]},{\"t\":7,\"p\":1,\"n\":\"QNAM - X Speed\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Layer\"}]}]},{\"t\":7,\"s\":1,\"p\":1,\"n\":\"PNAM - Cloud Colors\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Layer\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Sunrise\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Day\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Sunset\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Night\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]}]}]},{\"t\":7,\"s\":1,\"p\":1,\"n\":\"JNAM - Cloud Alphas\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Layer\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Sunrise\"},{\"t\":5,\"p\":1,\"n\":\"Day\"},{\"t\":5,\"p\":1,\"n\":\"Sunset\"},{\"t\":5,\"p\":1,\"n\":\"Night\"}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"NAM0 - Weather Colors\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Sky-Upper\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Sunrise\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Day\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Sunset\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Night\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]}]},{\"t\":6,\"p\":1,\"n\":\"Fog Near\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Sunrise\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Day\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Sunset\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Night\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]}]},{\"t\":6,\"n\":\"Unknown\",\"c\":[{\"t\":6,\"n\":\"Sunrise\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"n\":\"Day\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"n\":\"Sunset\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"n\":\"Night\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]}]},{\"t\":6,\"p\":1,\"n\":\"Ambient\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Sunrise\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Day\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Sunset\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Night\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]}]},{\"t\":6,\"p\":1,\"n\":\"Sunlight\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Sunrise\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Day\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Sunset\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Night\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]}]},{\"t\":6,\"p\":1,\"n\":\"Sun\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Sunrise\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Day\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Sunset\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Night\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]}]},{\"t\":6,\"p\":1,\"n\":\"Stars\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Sunrise\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Day\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Sunset\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Night\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]}]},{\"t\":6,\"p\":1,\"n\":\"Sky-Lower\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Sunrise\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Day\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Sunset\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Night\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]}]},{\"t\":6,\"p\":1,\"n\":\"Horizon\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Sunrise\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Day\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Sunset\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Night\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]}]},{\"t\":6,\"p\":1,\"n\":\"Effect Lighting\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Sunrise\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Day\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Sunset\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Night\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]}]},{\"t\":6,\"p\":1,\"n\":\"Cloud LOD Diffuse\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Sunrise\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Day\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Sunset\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Night\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]}]},{\"t\":6,\"p\":1,\"n\":\"Cloud LOD Ambient\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Sunrise\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Day\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Sunset\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Night\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]}]},{\"t\":6,\"p\":1,\"n\":\"Fog Far\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Sunrise\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Day\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Sunset\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Night\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]}]},{\"t\":6,\"p\":1,\"n\":\"Sky Statics\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Sunrise\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Day\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Sunset\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Night\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]}]},{\"t\":6,\"p\":1,\"n\":\"Water Multiplier\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Sunrise\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Day\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Sunset\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Night\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]}]},{\"t\":6,\"p\":1,\"n\":\"Sun Glare\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Sunrise\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Day\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Sunset\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Night\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]}]},{\"t\":6,\"p\":1,\"n\":\"Moon Glare\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Sunrise\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Day\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Sunset\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Night\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"FNAM - Fog Distance\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Day - Near\"},{\"t\":5,\"p\":1,\"n\":\"Day - Far\"},{\"t\":5,\"p\":1,\"n\":\"Night - Near\"},{\"t\":5,\"p\":1,\"n\":\"Night - Far\"},{\"t\":5,\"p\":1,\"n\":\"Day - Power\"},{\"t\":5,\"p\":1,\"n\":\"Night - Power\"},{\"t\":5,\"p\":1,\"n\":\"Day - Max\"},{\"t\":5,\"p\":1,\"n\":\"Night - Max\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DATA - Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Wind Speed\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":3,\"p\":1,\"n\":\"Trans Delta\"},{\"t\":3,\"p\":1,\"n\":\"Sun Glare\"},{\"t\":3,\"p\":1,\"n\":\"Sun Damage\"},{\"t\":3,\"p\":1,\"n\":\"Precipitation - Begin Fade In\"},{\"t\":3,\"p\":1,\"n\":\"Precipitation - End Fade Out\"},{\"t\":3,\"p\":1,\"n\":\"Thunder\\/Lightning - Begin Fade In\"},{\"t\":3,\"p\":1,\"n\":\"Thunder\\/Lightning - End Fade Out\"},{\"t\":3,\"p\":1,\"n\":\"Thunder\\/Lightning - Frequency\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":6,\"p\":1,\"n\":\"Lightning Color\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"}]},{\"t\":3,\"p\":1,\"n\":\"Visual Effect - Begin\"},{\"t\":3,\"p\":1,\"n\":\"Visual Effect - End\"},{\"t\":3,\"p\":1,\"n\":\"Wind Direction\"},{\"t\":3,\"p\":1,\"n\":\"Wind Direction Range\"}]},{\"t\":3,\"p\":1,\"n\":\"NAM1 - Disabled Cloud Layers\"},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Sounds\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"SNAM - Sound\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Sound\"},{\"t\":3,\"p\":1,\"n\":\"Type\"}]}]},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Sky Statics\",\"d\":1,\"c\":[{\"t\":3,\"p\":1,\"n\":\"TNAM - Static\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"IMSP - Image Spaces\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Sunrise\"},{\"t\":3,\"p\":1,\"n\":\"Day\"},{\"t\":3,\"p\":1,\"n\":\"Sunset\"},{\"t\":3,\"p\":1,\"n\":\"Night\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"HNAM - Volumetric Lighting\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Sunrise\"},{\"t\":3,\"p\":1,\"n\":\"Day\"},{\"t\":3,\"p\":1,\"n\":\"Sunset\"},{\"t\":3,\"p\":1,\"n\":\"Night\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Directional Ambient Lighting Colors\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"DALC - Sunrise\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Directional\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"X+\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"X-\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Y+\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Y-\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Z+\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Z-\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]}]},{\"t\":6,\"p\":1,\"n\":\"Specular\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":5,\"p\":1,\"n\":\"Scale\"}]},{\"t\":6,\"p\":1,\"n\":\"DALC - Day\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Directional\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"X+\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"X-\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Y+\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Y-\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Z+\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Z-\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]}]},{\"t\":6,\"p\":1,\"n\":\"Specular\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":5,\"p\":1,\"n\":\"Scale\"}]},{\"t\":6,\"p\":1,\"n\":\"DALC - Sunset\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Directional\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"X+\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"X-\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Y+\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Y-\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Z+\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Z-\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]}]},{\"t\":6,\"p\":1,\"n\":\"Specular\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":5,\"p\":1,\"n\":\"Scale\"}]},{\"t\":6,\"p\":1,\"n\":\"DALC - Night\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Directional\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"X+\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"X-\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Y+\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Y-\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Z+\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Z-\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]}]},{\"t\":6,\"p\":1,\"n\":\"Specular\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":5,\"p\":1,\"n\":\"Scale\"}]}]},{\"t\":11,\"n\":\"NAM2 - Unused\"},{\"t\":11,\"n\":\"NAM3 - Unused\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Aurora\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"MODT - Texture Files Hashes\"},{\"t\":7,\"p\":1,\"n\":\"MODS - Alternate Textures\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"3D Name\"},{\"t\":3,\"p\":1,\"n\":\"New Texture\"},{\"t\":3,\"p\":1,\"n\":\"3D Index\"}]}]}]}]},{\"t\":3,\"p\":1,\"n\":\"GNAM - Sun Glare Lens Flare\"}]},{\"t\":1,\"p\":1,\"n\":\"ACHR - Placed NPC\",\"f\":1,\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"VMAD - Virtual Machine Adapter\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Version\"},{\"t\":3,\"p\":1,\"n\":\"Object Format\"},{\"t\":7,\"p\":1,\"n\":\"Scripts\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Script\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"scriptName\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":7,\"p\":1,\"n\":\"Properties\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Property\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"propertyName\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]},{\"t\":2,\"p\":1,\"n\":\"String\"},{\"t\":3,\"p\":1,\"n\":\"Int32\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":3,\"p\":1,\"n\":\"Bool\"},{\"t\":7,\"p\":1,\"n\":\"Array of Object\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]}]},{\"t\":7,\"p\":1,\"n\":\"Array of String\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Int32\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Float\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Bool\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]}]}]}]}]}]},{\"t\":3,\"p\":1,\"n\":\"NAME - Base\"},{\"t\":3,\"p\":1,\"n\":\"XEZN - Encounter Zone\"},{\"t\":11,\"n\":\"XRGD - Ragdoll Data\"},{\"t\":11,\"n\":\"XRGB - Ragdoll Biped Data\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Patrol Data\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"XPRD - Idle Time\"},{\"p\":1,\"n\":\"XPPA - Patrol Script Marker\"},{\"t\":3,\"p\":1,\"n\":\"INAM - Idle\"},{\"t\":6,\"n\":\"Unused\",\"c\":[{\"t\":11,\"n\":\"SCHR - Unknown\"},{\"t\":11,\"n\":\"SCDA - Unknown\"},{\"t\":11,\"n\":\"SCTX - Unknown\"},{\"t\":11,\"n\":\"QNAM - Unknown\"},{\"t\":11,\"n\":\"SCRO - Unknown\"}]},{\"t\":8,\"p\":1,\"n\":\"Topic\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"PDTO - Topic Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Topic\"},{\"t\":2,\"p\":1,\"n\":\"Subtype\"}]}]},{\"t\":3,\"p\":1,\"n\":\"TNAM - Topic\"}]},{\"t\":3,\"p\":1,\"n\":\"XLCM - Level Modifier\"},{\"t\":3,\"p\":1,\"n\":\"XMRC - Merchant Container\"},{\"t\":3,\"p\":1,\"n\":\"XCNT - Count\"},{\"t\":5,\"p\":1,\"n\":\"XRDS - Radius\"},{\"t\":5,\"p\":1,\"n\":\"XHLP - Health\"},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Linked References\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"XLKR - Linked Reference\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Keyword\\/Ref\"},{\"t\":3,\"p\":1,\"n\":\"Ref\"}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Activate Parents\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"XAPD - Flags\"},{\"t\":8,\"p\":1,\"n\":\"Activate Parent Refs\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"XAPR - Activate Parent Ref\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":5,\"p\":1,\"n\":\"Delay\"}]}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"XCLP - Linked Reference Color\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Link Start Color\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Link End Color\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]}]},{\"t\":3,\"p\":1,\"n\":\"XLCN - Persistent Location\"},{\"t\":3,\"p\":1,\"n\":\"XLRL - Location Reference\"},{\"p\":1,\"n\":\"XIS2 - Ignored by Sandbox\"},{\"t\":7,\"p\":1,\"n\":\"XLRT - Location Ref Type\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Ref\"}]},{\"t\":3,\"p\":1,\"n\":\"XHOR - Horse\"},{\"t\":5,\"p\":1,\"n\":\"XHTW - Head-Tracking Weight\"},{\"t\":5,\"p\":1,\"n\":\"XFVC - Favor Cost\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"XESP - Enable Parent\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Ownership\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"XOWN - Owner\"},{\"t\":3,\"p\":1,\"n\":\"XRNK - Faction rank\"}]},{\"t\":3,\"p\":1,\"n\":\"XEMI - Emittance\"},{\"t\":3,\"p\":1,\"n\":\"XMBR - MultiBound Reference\"},{\"p\":1,\"n\":\"XIBS - Ignored By Sandbox\"},{\"t\":5,\"p\":1,\"n\":\"XSCL - Scale\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DATA - Position\\/Rotation\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Position\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"X\"},{\"t\":5,\"p\":1,\"n\":\"Y\"},{\"t\":5,\"p\":1,\"n\":\"Z\"}]},{\"t\":6,\"p\":1,\"n\":\"Rotation\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"X\"},{\"t\":5,\"p\":1,\"n\":\"Y\"},{\"t\":5,\"p\":1,\"n\":\"Z\"}]}]}]}]},\"name\":\"Smash.ForceAll\",\"hash\":\"ADEDBA36\",\"color\":8388736}"
  },
  {
    "path": "frontend/settings/Skyrim/Smash.OverrideAll.json",
    "content": "{\"records\":\"AACT,ACTI,ADDN,ALCH,AMMO,ANIO,APPA,ARMA,ARMO,ARTO,ASPC,ASTP,AVIF,BOOK,BPTD,CAMS,CELL,CLAS,CLDC,CLFM,CLMT,COBJ,COLL,CONT,CPTH,CSTY,DEBR,DIAL,DLBR,DLVW,DOOR,DUAL,ECZN,EFSH,ENCH,EQUP,EXPL,EYES,FACT,FLOR,FLST,FSTP,FSTS,FURN,GLOB,GMST,GRAS,HAIR,HAZD,HDPT,IDLM,IMAD,IMGS,INFO,INGR,IPCT,IPDS,KEYM,KYWD,LAND,LCRT,LENS,LGTM,LIGH,LSCR,LTEX,LVLI,LVLN,LVSP,MATO,MATT,MESG,MGEF,MISC,MOVT,MSTT,MUSC,MUST,NPC_,OTFT,PACK,PARW,PBAR,PBEA,PCON,PERK,PFLA,PGRE,PHZD,PMIS,PROJ,PWAT,QUST,RACE,REFR,REGN,RELA,REVB,RFCT,RGDL,SCEN,SCOL,SCPT,SCRL,SHOU,SLGM,SMBN,SMEN,SMQN,SNCT,SNDR,SOPM,SOUN,SPEL,SPGD,STAT,TACT,TREE,TXST,VOLI,VTYP,WATR,WEAP,WOOP,WRLD,WTHR,ACHR\",\"description\":\"Smashes all the things and restores deletions in leveled lists.\\r\\n\\r\\nLast updated 05\\/02\\/2018.\",\"tree\":{\"records\":[{\"t\":1,\"p\":1,\"n\":\"AACT - Action\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"CNAM - Color\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unknown\"}]}]},{\"t\":1,\"p\":1,\"n\":\"ACTI - Activator\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"VMAD - Virtual Machine Adapter\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Version\"},{\"t\":3,\"p\":1,\"n\":\"Object Format\"},{\"t\":7,\"p\":1,\"n\":\"Scripts\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Script\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"scriptName\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":7,\"p\":1,\"n\":\"Properties\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Property\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"propertyName\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]},{\"t\":2,\"p\":1,\"n\":\"String\"},{\"t\":3,\"p\":1,\"n\":\"Int32\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":3,\"p\":1,\"n\":\"Bool\"},{\"t\":7,\"p\":1,\"n\":\"Array of Object\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]}]},{\"t\":7,\"p\":1,\"n\":\"Array of String\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Int32\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Float\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Bool\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]}]}]}]}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"X1\"},{\"t\":3,\"p\":1,\"n\":\"Y1\"},{\"t\":3,\"p\":1,\"n\":\"Z1\"},{\"t\":3,\"p\":1,\"n\":\"X2\"},{\"t\":3,\"p\":1,\"n\":\"Y2\"},{\"t\":3,\"p\":1,\"n\":\"Z2\"}]},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"MODT - Texture Files Hashes\"},{\"t\":7,\"p\":1,\"n\":\"MODS - Alternate Textures\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"3D Name\"},{\"t\":3,\"p\":1,\"n\":\"New Texture\"},{\"t\":3,\"p\":1,\"n\":\"3D Index\"}]}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Destructable\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"DEST - Header\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Health\"},{\"t\":3,\"p\":1,\"n\":\"DEST Count\"},{\"t\":3,\"p\":1,\"n\":\"VATS Targetable\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":8,\"p\":1,\"n\":\"Stages\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Stage\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"DSTD - Destruction Stage Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Health %\"},{\"t\":3,\"p\":1,\"n\":\"Index\"},{\"t\":3,\"p\":1,\"n\":\"Model Damage Stage\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":3,\"p\":1,\"n\":\"Self Damage per Second\"},{\"t\":3,\"p\":1,\"n\":\"Explosion\"},{\"t\":3,\"p\":1,\"n\":\"Debris\"},{\"t\":3,\"p\":1,\"n\":\"Debris Count\"}]},{\"t\":6,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"DMDL - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"DMDT - Texture Files Hashes\"},{\"t\":7,\"p\":1,\"n\":\"DMDS - Alternate Textures\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"3D Name\"},{\"t\":3,\"p\":1,\"n\":\"New Texture\"},{\"t\":3,\"p\":1,\"n\":\"3D Index\"}]}]}]},{\"p\":1,\"n\":\"DSTF - End Marker\"}]}]}]},{\"t\":3,\"n\":\"KSIZ - Keyword Count\"},{\"t\":7,\"p\":1,\"n\":\"KWDA - Keywords\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Keyword\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"PNAM - Marker Color\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":3,\"n\":\"Unused\"}]},{\"t\":3,\"p\":1,\"n\":\"SNAM - Sound - Looping\"},{\"t\":3,\"p\":1,\"n\":\"VNAM - Sound - Activation\"},{\"t\":3,\"p\":1,\"n\":\"WNAM - Water Type\"},{\"t\":2,\"p\":1,\"n\":\"RNAM - Activate Text Override\"},{\"t\":3,\"p\":1,\"n\":\"FNAM - Flags\"},{\"t\":3,\"p\":1,\"n\":\"KNAM - Interaction Keyword\"}]},{\"t\":1,\"p\":1,\"n\":\"ADDN - Addon Node\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"X1\"},{\"t\":3,\"p\":1,\"n\":\"Y1\"},{\"t\":3,\"p\":1,\"n\":\"Z1\"},{\"t\":3,\"p\":1,\"n\":\"X2\"},{\"t\":3,\"p\":1,\"n\":\"Y2\"},{\"t\":3,\"p\":1,\"n\":\"Z2\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"MODT - Texture Files Hashes\"},{\"t\":7,\"p\":1,\"n\":\"MODS - Alternate Textures\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"3D Name\"},{\"t\":3,\"p\":1,\"n\":\"New Texture\"},{\"t\":3,\"p\":1,\"n\":\"3D Index\"}]}]}]},{\"t\":3,\"p\":1,\"n\":\"DATA - Node Index\"},{\"t\":3,\"p\":1,\"n\":\"SNAM - Sound\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DNAM - Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Master Particle System Cap\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"}]}]},{\"t\":1,\"p\":1,\"n\":\"ALCH - Ingestible\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"X1\"},{\"t\":3,\"p\":1,\"n\":\"Y1\"},{\"t\":3,\"p\":1,\"n\":\"Z1\"},{\"t\":3,\"p\":1,\"n\":\"X2\"},{\"t\":3,\"p\":1,\"n\":\"Y2\"},{\"t\":3,\"p\":1,\"n\":\"Z2\"}]},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":3,\"n\":\"KSIZ - Keyword Count\"},{\"t\":7,\"p\":1,\"n\":\"KWDA - Keywords\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Keyword\"}]},{\"t\":2,\"p\":1,\"n\":\"DESC - Description\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"MODT - Texture Files Hashes\"},{\"t\":7,\"p\":1,\"n\":\"MODS - Alternate Textures\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"3D Name\"},{\"t\":3,\"p\":1,\"n\":\"New Texture\"},{\"t\":3,\"p\":1,\"n\":\"3D Index\"}]}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Destructable\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"DEST - Header\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Health\"},{\"t\":3,\"p\":1,\"n\":\"DEST Count\"},{\"t\":3,\"p\":1,\"n\":\"VATS Targetable\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":8,\"p\":1,\"n\":\"Stages\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Stage\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"DSTD - Destruction Stage Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Health %\"},{\"t\":3,\"p\":1,\"n\":\"Index\"},{\"t\":3,\"p\":1,\"n\":\"Model Damage Stage\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":3,\"p\":1,\"n\":\"Self Damage per Second\"},{\"t\":3,\"p\":1,\"n\":\"Explosion\"},{\"t\":3,\"p\":1,\"n\":\"Debris\"},{\"t\":3,\"p\":1,\"n\":\"Debris Count\"}]},{\"t\":6,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"DMDL - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"DMDT - Texture Files Hashes\"},{\"t\":7,\"p\":1,\"n\":\"DMDS - Alternate Textures\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"3D Name\"},{\"t\":3,\"p\":1,\"n\":\"New Texture\"},{\"t\":3,\"p\":1,\"n\":\"3D Index\"}]}]}]},{\"p\":1,\"n\":\"DSTF - End Marker\"}]}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Icon\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"ICON - Large Icon filename\"},{\"t\":2,\"p\":1,\"n\":\"MICO - Small Icon filename\"}]},{\"t\":3,\"p\":1,\"n\":\"YNAM - Sound - Pick Up\"},{\"t\":3,\"p\":1,\"n\":\"ZNAM - Sound - Put Down\"},{\"t\":3,\"p\":1,\"n\":\"ETYP - Equipment Type\"},{\"t\":5,\"p\":1,\"n\":\"DATA - Weight\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"ENIT - Effect Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Value\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":3,\"p\":1,\"n\":\"Addiction\"},{\"t\":5,\"p\":1,\"n\":\"Addiction Chance\"},{\"t\":3,\"p\":1,\"n\":\"Sound - Consume\"}]},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Effects\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Effect\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"EFID - Base Effect\"},{\"t\":6,\"p\":1,\"n\":\"EFIT - \",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Magnitude\"},{\"t\":3,\"p\":1,\"n\":\"Area\"},{\"t\":3,\"p\":1,\"n\":\"Duration\"}]},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Conditions\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Condition\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"CTDA - \",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":5,\"p\":1,\"n\":\"Comparison Value - Float\"},{\"t\":3,\"p\":1,\"n\":\"Comparison Value - Global\"},{\"t\":3,\"p\":1,\"n\":\"Function\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":11,\"p\":1,\"n\":\"None\"},{\"t\":3,\"p\":1,\"n\":\"Integer\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":11,\"p\":1,\"n\":\"Variable Name (unused)\"},{\"t\":3,\"p\":1,\"n\":\"Sex\"},{\"t\":3,\"p\":1,\"n\":\"Actor Value\"},{\"t\":3,\"p\":1,\"n\":\"Crime Type\"},{\"t\":3,\"p\":1,\"n\":\"Axis\"},{\"t\":3,\"p\":1,\"n\":\"Quest Stage (unused)\"},{\"t\":3,\"p\":1,\"n\":\"Misc Stat\"},{\"t\":3,\"p\":1,\"n\":\"Alignment\"},{\"t\":3,\"p\":1,\"n\":\"Equip Type\"},{\"t\":3,\"p\":1,\"n\":\"Form Type\"},{\"t\":3,\"p\":1,\"n\":\"Critical Stage\"},{\"t\":3,\"p\":1,\"n\":\"Object Reference\"},{\"t\":3,\"p\":1,\"n\":\"Inventory Object\"},{\"t\":3,\"p\":1,\"n\":\"Actor\"},{\"t\":3,\"p\":1,\"n\":\"Voice Type\"},{\"t\":3,\"p\":1,\"n\":\"Idle\"},{\"t\":3,\"p\":1,\"n\":\"Form List\"},{\"t\":3,\"p\":1,\"n\":\"Quest\"},{\"t\":3,\"p\":1,\"n\":\"Faction\"},{\"t\":3,\"p\":1,\"n\":\"Cell\"},{\"t\":3,\"p\":1,\"n\":\"Class\"},{\"t\":3,\"p\":1,\"n\":\"Race\"},{\"t\":3,\"p\":1,\"n\":\"Actor Base\"},{\"t\":3,\"p\":1,\"n\":\"Global\"},{\"t\":3,\"p\":1,\"n\":\"Weather\"},{\"t\":3,\"p\":1,\"n\":\"Package\"},{\"t\":3,\"p\":1,\"n\":\"Encounter Zone\"},{\"t\":3,\"p\":1,\"n\":\"Perk\"},{\"t\":3,\"p\":1,\"n\":\"Owner\"},{\"t\":3,\"p\":1,\"n\":\"Furniture\"},{\"t\":3,\"p\":1,\"n\":\"Effect Item\"},{\"t\":3,\"p\":1,\"n\":\"Base Effect\"},{\"t\":3,\"p\":1,\"n\":\"Worldspace\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Function\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Param (INVALID)\"},{\"t\":3,\"p\":1,\"n\":\"Referenceable Object\"},{\"t\":3,\"p\":1,\"n\":\"Region\"},{\"t\":3,\"p\":1,\"n\":\"Keyword\"},{\"t\":3,\"p\":1,\"n\":\"Player Action\"},{\"t\":3,\"p\":1,\"n\":\"Casting Type\"},{\"t\":3,\"p\":1,\"n\":\"Shout\"},{\"t\":3,\"p\":1,\"n\":\"Location\"},{\"t\":3,\"p\":1,\"n\":\"Location Ref Type\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"Packdata ID\"},{\"t\":3,\"p\":1,\"n\":\"Association Type\"},{\"t\":3,\"p\":1,\"n\":\"Furniture Anim\"},{\"t\":3,\"p\":1,\"n\":\"Furniture Entry\"},{\"t\":3,\"p\":1,\"n\":\"Scene\"},{\"t\":3,\"p\":1,\"n\":\"Ward State\"},{\"t\":3,\"p\":1,\"n\":\"Event\"},{\"t\":3,\"p\":1,\"n\":\"Event Data\"},{\"t\":3,\"p\":1,\"n\":\"Quest Stage\"},{\"t\":3,\"p\":1,\"n\":\"Weapon\"},{\"t\":3,\"p\":1,\"n\":\"Weapon List\"},{\"t\":3,\"p\":1,\"n\":\"Target\"},{\"t\":3,\"p\":1,\"n\":\"Target List\"},{\"t\":3,\"p\":1,\"n\":\"Target Part\"},{\"t\":3,\"p\":1,\"n\":\"VATS Action\"},{\"t\":3,\"p\":1,\"n\":\"Critical Effect\"},{\"t\":3,\"p\":1,\"n\":\"Critical Effect List\"},{\"t\":3,\"p\":1,\"n\":\"Weapon Type\"},{\"t\":3,\"p\":1,\"n\":\"Projectile Type\"},{\"t\":3,\"p\":1,\"n\":\"Delivery Type\"},{\"t\":3,\"p\":1,\"n\":\"Run On\"},{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":3,\"p\":1,\"n\":\"Parameter #3\"}]},{\"t\":2,\"p\":1,\"n\":\"CIS1 - Parameter #1\"},{\"t\":2,\"p\":1,\"n\":\"CIS2 - Parameter #2\"}]}]}]}]}]},{\"t\":1,\"p\":1,\"n\":\"AMMO - Ammunition\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"X1\"},{\"t\":3,\"p\":1,\"n\":\"Y1\"},{\"t\":3,\"p\":1,\"n\":\"Z1\"},{\"t\":3,\"p\":1,\"n\":\"X2\"},{\"t\":3,\"p\":1,\"n\":\"Y2\"},{\"t\":3,\"p\":1,\"n\":\"Z2\"}]},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"MODT - Texture Files Hashes\"},{\"t\":7,\"p\":1,\"n\":\"MODS - Alternate Textures\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"3D Name\"},{\"t\":3,\"p\":1,\"n\":\"New Texture\"},{\"t\":3,\"p\":1,\"n\":\"3D Index\"}]}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Icon\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"ICON - Large Icon filename\"},{\"t\":2,\"p\":1,\"n\":\"MICO - Small Icon filename\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Destructable\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"DEST - Header\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Health\"},{\"t\":3,\"p\":1,\"n\":\"DEST Count\"},{\"t\":3,\"p\":1,\"n\":\"VATS Targetable\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":8,\"p\":1,\"n\":\"Stages\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Stage\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"DSTD - Destruction Stage Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Health %\"},{\"t\":3,\"p\":1,\"n\":\"Index\"},{\"t\":3,\"p\":1,\"n\":\"Model Damage Stage\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":3,\"p\":1,\"n\":\"Self Damage per Second\"},{\"t\":3,\"p\":1,\"n\":\"Explosion\"},{\"t\":3,\"p\":1,\"n\":\"Debris\"},{\"t\":3,\"p\":1,\"n\":\"Debris Count\"}]},{\"t\":6,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"DMDL - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"DMDT - Texture Files Hashes\"},{\"t\":7,\"p\":1,\"n\":\"DMDS - Alternate Textures\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"3D Name\"},{\"t\":3,\"p\":1,\"n\":\"New Texture\"},{\"t\":3,\"p\":1,\"n\":\"3D Index\"}]}]}]},{\"p\":1,\"n\":\"DSTF - End Marker\"}]}]}]},{\"t\":3,\"p\":1,\"n\":\"YNAM - Sound - Pick Up\"},{\"t\":3,\"p\":1,\"n\":\"ZNAM - Sound - Put Down\"},{\"t\":2,\"p\":1,\"n\":\"DESC - Description\"},{\"t\":3,\"n\":\"KSIZ - Keyword Count\"},{\"t\":7,\"p\":1,\"n\":\"KWDA - Keywords\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Keyword\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DATA - Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Projectile\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":5,\"p\":1,\"n\":\"Damage\"},{\"t\":3,\"p\":1,\"n\":\"Value\"}]},{\"t\":2,\"p\":1,\"n\":\"ONAM - Short Name\"}]},{\"t\":1,\"p\":1,\"n\":\"ANIO - Animated Object\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"MODT - Texture Files Hashes\"},{\"t\":7,\"p\":1,\"n\":\"MODS - Alternate Textures\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"3D Name\"},{\"t\":3,\"p\":1,\"n\":\"New Texture\"},{\"t\":3,\"p\":1,\"n\":\"3D Index\"}]}]}]},{\"t\":2,\"p\":1,\"n\":\"BNAM - Unload Event\"}]},{\"t\":1,\"p\":1,\"n\":\"APPA - Alchemical Apparatus\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"VMAD - Virtual Machine Adapter\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Version\"},{\"t\":3,\"p\":1,\"n\":\"Object Format\"},{\"t\":7,\"p\":1,\"n\":\"Scripts\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Script\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"scriptName\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":7,\"p\":1,\"n\":\"Properties\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Property\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"propertyName\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]},{\"t\":2,\"p\":1,\"n\":\"String\"},{\"t\":3,\"p\":1,\"n\":\"Int32\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":3,\"p\":1,\"n\":\"Bool\"},{\"t\":7,\"p\":1,\"n\":\"Array of Object\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]}]},{\"t\":7,\"p\":1,\"n\":\"Array of String\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Int32\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Float\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Bool\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]}]}]}]}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"X1\"},{\"t\":3,\"p\":1,\"n\":\"Y1\"},{\"t\":3,\"p\":1,\"n\":\"Z1\"},{\"t\":3,\"p\":1,\"n\":\"X2\"},{\"t\":3,\"p\":1,\"n\":\"Y2\"},{\"t\":3,\"p\":1,\"n\":\"Z2\"}]},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"MODT - Texture Files Hashes\"},{\"t\":7,\"p\":1,\"n\":\"MODS - Alternate Textures\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"3D Name\"},{\"t\":3,\"p\":1,\"n\":\"New Texture\"},{\"t\":3,\"p\":1,\"n\":\"3D Index\"}]}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Icon\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"ICON - Large Icon filename\"},{\"t\":2,\"p\":1,\"n\":\"MICO - Small Icon filename\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Destructable\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"DEST - Header\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Health\"},{\"t\":3,\"p\":1,\"n\":\"DEST Count\"},{\"t\":3,\"p\":1,\"n\":\"VATS Targetable\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":8,\"p\":1,\"n\":\"Stages\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Stage\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"DSTD - Destruction Stage Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Health %\"},{\"t\":3,\"p\":1,\"n\":\"Index\"},{\"t\":3,\"p\":1,\"n\":\"Model Damage Stage\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":3,\"p\":1,\"n\":\"Self Damage per Second\"},{\"t\":3,\"p\":1,\"n\":\"Explosion\"},{\"t\":3,\"p\":1,\"n\":\"Debris\"},{\"t\":3,\"p\":1,\"n\":\"Debris Count\"}]},{\"t\":6,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"DMDL - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"DMDT - Texture Files Hashes\"},{\"t\":7,\"p\":1,\"n\":\"DMDS - Alternate Textures\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"3D Name\"},{\"t\":3,\"p\":1,\"n\":\"New Texture\"},{\"t\":3,\"p\":1,\"n\":\"3D Index\"}]}]}]},{\"p\":1,\"n\":\"DSTF - End Marker\"}]}]}]},{\"t\":3,\"p\":1,\"n\":\"YNAM - Sound - Pick Up\"},{\"t\":3,\"p\":1,\"n\":\"ZNAM - Sound - Put Down\"},{\"t\":3,\"p\":1,\"n\":\"QUAL - Quality\"},{\"t\":2,\"p\":1,\"n\":\"DESC - Description\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DATA - Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Value\"},{\"t\":5,\"p\":1,\"n\":\"Weight\"}]}]},{\"t\":1,\"p\":1,\"n\":\"ARMA - Armor Addon\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"BOD2 - Biped Body Template\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"First Person Flags\"},{\"t\":3,\"p\":1,\"n\":\"General Flags\"},{\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Armor Type\"}],\"lt\":\"BODT - Body Template\",\"lf\":\"BODT - Body Template\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"BODT - Body Template\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"First Person Flags\"},{\"t\":3,\"p\":1,\"n\":\"General Flags\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Armor Type\"}],\"lt\":\"BOD2 - Biped Body Template\",\"lf\":\"BOD2 - Biped Body Template\"},{\"t\":3,\"p\":1,\"n\":\"RNAM - Race\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DNAM - Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Male Priority\"},{\"t\":3,\"p\":1,\"n\":\"Female Priority\"},{\"t\":3,\"p\":1,\"n\":\"Weight slider - Male\"},{\"t\":3,\"p\":1,\"n\":\"Weight slider - Female\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":3,\"p\":1,\"n\":\"Detection Sound Value\"},{\"t\":5,\"p\":1,\"n\":\"Weapon Adjust\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Male world model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MOD2 - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"MO2T - Texture Files Hashes\"},{\"t\":7,\"p\":1,\"n\":\"MO2S - Alternate Textures\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"3D Name\"},{\"t\":3,\"p\":1,\"n\":\"New Texture\"},{\"t\":3,\"p\":1,\"n\":\"3D Index\"}]}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Female world model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MOD3 - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"MO3T - Texture Files Hashes\"},{\"t\":7,\"p\":1,\"n\":\"MO3S - Alternate Textures\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"3D Name\"},{\"t\":3,\"p\":1,\"n\":\"New Texture\"},{\"t\":3,\"p\":1,\"n\":\"3D Index\"}]}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Male 1st Person\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MOD4 - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"MO4T - Texture Files Hashes\"},{\"t\":7,\"p\":1,\"n\":\"MO4S - Alternate Textures\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"3D Name\"},{\"t\":3,\"p\":1,\"n\":\"New Texture\"},{\"t\":3,\"p\":1,\"n\":\"3D Index\"}]}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Female 1st Person\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MOD5 - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"MO5T - Texture Files Hashes\"},{\"t\":7,\"p\":1,\"n\":\"MO5S - Alternate Textures\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"3D Name\"},{\"t\":3,\"p\":1,\"n\":\"New Texture\"},{\"t\":3,\"p\":1,\"n\":\"3D Index\"}]}]}]},{\"t\":3,\"p\":1,\"n\":\"NAM0 - Male Skin Texture\"},{\"t\":3,\"p\":1,\"n\":\"NAM1 - Female Skin texture\"},{\"t\":3,\"p\":1,\"n\":\"NAM2 - Male Skin Texture Swap List\"},{\"t\":3,\"p\":1,\"n\":\"NAM3 - Female Skin Texture Swap List\"},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Additional Races\",\"d\":1,\"c\":[{\"t\":3,\"p\":1,\"n\":\"MODL - Race\"}]},{\"t\":3,\"p\":1,\"n\":\"SNDD - Footstep Sound\"},{\"t\":3,\"p\":1,\"n\":\"ONAM - Art Object\"}]},{\"t\":1,\"p\":1,\"n\":\"ARMO - Armor\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"VMAD - Virtual Machine Adapter\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Version\"},{\"t\":3,\"p\":1,\"n\":\"Object Format\"},{\"t\":7,\"p\":1,\"n\":\"Scripts\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Script\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"scriptName\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":7,\"p\":1,\"n\":\"Properties\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Property\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"propertyName\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]},{\"t\":2,\"p\":1,\"n\":\"String\"},{\"t\":3,\"p\":1,\"n\":\"Int32\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":3,\"p\":1,\"n\":\"Bool\"},{\"t\":7,\"p\":1,\"n\":\"Array of Object\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]}]},{\"t\":7,\"p\":1,\"n\":\"Array of String\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Int32\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Float\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Bool\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]}]}]}]}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"X1\"},{\"t\":3,\"p\":1,\"n\":\"Y1\"},{\"t\":3,\"p\":1,\"n\":\"Z1\"},{\"t\":3,\"p\":1,\"n\":\"X2\"},{\"t\":3,\"p\":1,\"n\":\"Y2\"},{\"t\":3,\"p\":1,\"n\":\"Z2\"}]},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":3,\"p\":1,\"n\":\"EITM - Object Effect\"},{\"t\":3,\"p\":1,\"n\":\"EAMT - Enchantment Amount\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Male world model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MOD2 - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"MO2T - Texture Files Hashes\"},{\"t\":7,\"p\":1,\"n\":\"MO2S - Alternate Textures\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"3D Name\"},{\"t\":3,\"p\":1,\"n\":\"New Texture\"},{\"t\":3,\"p\":1,\"n\":\"3D Index\"}]}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Icon\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"ICON - Large Icon filename\"},{\"t\":2,\"p\":1,\"n\":\"MICO - Small Icon filename\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Female world model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MOD4 - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"MO4T - Texture Files Hashes\"},{\"t\":7,\"p\":1,\"n\":\"MO4S - Alternate Textures\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"3D Name\"},{\"t\":3,\"p\":1,\"n\":\"New Texture\"},{\"t\":3,\"p\":1,\"n\":\"3D Index\"}]}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Icon 2 (female)\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"ICO2 - Large Icon filename\"},{\"t\":2,\"p\":1,\"n\":\"MIC2 - Small Icon filename\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"BOD2 - Biped Body Template\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"First Person Flags\"},{\"t\":3,\"p\":1,\"n\":\"General Flags\"},{\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Armor Type\"}],\"lt\":\"BODT - Body Template\",\"lf\":\"BODT - Body Template\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"BODT - Body Template\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"First Person Flags\"},{\"t\":3,\"p\":1,\"n\":\"General Flags\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Armor Type\"}],\"lt\":\"BOD2 - Biped Body Template\",\"lf\":\"BOD2 - Biped Body Template\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Destructable\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"DEST - Header\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Health\"},{\"t\":3,\"p\":1,\"n\":\"DEST Count\"},{\"t\":3,\"p\":1,\"n\":\"VATS Targetable\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":8,\"p\":1,\"n\":\"Stages\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Stage\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"DSTD - Destruction Stage Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Health %\"},{\"t\":3,\"p\":1,\"n\":\"Index\"},{\"t\":3,\"p\":1,\"n\":\"Model Damage Stage\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":3,\"p\":1,\"n\":\"Self Damage per Second\"},{\"t\":3,\"p\":1,\"n\":\"Explosion\"},{\"t\":3,\"p\":1,\"n\":\"Debris\"},{\"t\":3,\"p\":1,\"n\":\"Debris Count\"}]},{\"t\":6,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"DMDL - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"DMDT - Texture Files Hashes\"},{\"t\":7,\"p\":1,\"n\":\"DMDS - Alternate Textures\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"3D Name\"},{\"t\":3,\"p\":1,\"n\":\"New Texture\"},{\"t\":3,\"p\":1,\"n\":\"3D Index\"}]}]}]},{\"p\":1,\"n\":\"DSTF - End Marker\"}]}]}]},{\"t\":3,\"p\":1,\"n\":\"YNAM - Sound - Pick Up\"},{\"t\":3,\"p\":1,\"n\":\"ZNAM - Sound - Put Down\"},{\"t\":2,\"p\":1,\"n\":\"BMCT - Ragdoll Constraint Template\"},{\"t\":3,\"p\":1,\"n\":\"ETYP - Equipment Type\"},{\"t\":3,\"p\":1,\"n\":\"BIDS - Bash Impact Data Set\"},{\"t\":3,\"p\":1,\"n\":\"BAMT - Alternate Block Material\"},{\"t\":3,\"p\":1,\"n\":\"RNAM - Race\"},{\"t\":3,\"n\":\"KSIZ - Keyword Count\"},{\"t\":7,\"p\":1,\"n\":\"KWDA - Keywords\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Keyword\"}]},{\"t\":2,\"p\":1,\"n\":\"DESC - Description\"},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Armature\",\"d\":1,\"c\":[{\"t\":3,\"p\":1,\"n\":\"MODL - Model Filename\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DATA - Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Value\"},{\"t\":5,\"p\":1,\"n\":\"Weight\"}]},{\"t\":3,\"p\":1,\"n\":\"DNAM - Armor Rating\"},{\"t\":3,\"p\":1,\"n\":\"TNAM - Template Armor\"}]},{\"t\":1,\"p\":1,\"n\":\"ARTO - Art Object\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"X1\"},{\"t\":3,\"p\":1,\"n\":\"Y1\"},{\"t\":3,\"p\":1,\"n\":\"Z1\"},{\"t\":3,\"p\":1,\"n\":\"X2\"},{\"t\":3,\"p\":1,\"n\":\"Y2\"},{\"t\":3,\"p\":1,\"n\":\"Z2\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"MODT - Texture Files Hashes\"},{\"t\":7,\"p\":1,\"n\":\"MODS - Alternate Textures\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"3D Name\"},{\"t\":3,\"p\":1,\"n\":\"New Texture\"},{\"t\":3,\"p\":1,\"n\":\"3D Index\"}]}]}]},{\"t\":3,\"p\":1,\"n\":\"DNAM - Art Type\"}]},{\"t\":1,\"p\":1,\"n\":\"ASPC - Acoustic Space\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"X1\"},{\"t\":3,\"p\":1,\"n\":\"Y1\"},{\"t\":3,\"p\":1,\"n\":\"Z1\"},{\"t\":3,\"p\":1,\"n\":\"X2\"},{\"t\":3,\"p\":1,\"n\":\"Y2\"},{\"t\":3,\"p\":1,\"n\":\"Z2\"}]},{\"t\":3,\"p\":1,\"n\":\"SNAM - Ambient Sound\"},{\"t\":3,\"p\":1,\"n\":\"RDAT - Use Sound from Region (Interiors Only)\"},{\"t\":3,\"p\":1,\"n\":\"BNAM - Environment Type (reverb)\"}]},{\"t\":1,\"p\":1,\"n\":\"ASTP - Association Type\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"p\":1,\"n\":\"MPRT - Male Parent Title\"},{\"t\":2,\"p\":1,\"n\":\"FPRT - Female Parent Title\"},{\"t\":2,\"p\":1,\"n\":\"MCHT - Male Child Title\"},{\"t\":2,\"p\":1,\"n\":\"FCHT - Female Child Title\"},{\"t\":3,\"p\":1,\"n\":\"DATA - Flags\"}]},{\"t\":1,\"p\":1,\"n\":\"AVIF - Actor Value Information\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":2,\"p\":1,\"n\":\"DESC - Description\"},{\"t\":2,\"p\":1,\"n\":\"ANAM - Abbreviation\"},{\"t\":11,\"n\":\"CNAM - Unknown\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"AVSK - Skill\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Skill Use Mult\"},{\"t\":5,\"p\":1,\"n\":\"Skill Offset Mult\"},{\"t\":5,\"p\":1,\"n\":\"Skill Improve Mult\"},{\"t\":5,\"p\":1,\"n\":\"Skill Improve Offset\"}]},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Perk Tree\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Node\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"PNAM - Perk\"},{\"t\":11,\"n\":\"FNAM - Unknown\"},{\"t\":3,\"p\":1,\"n\":\"XNAM - Perk-Grid X\"},{\"t\":3,\"p\":1,\"n\":\"YNAM - Perk-Grid Y\"},{\"t\":5,\"p\":1,\"n\":\"HNAM - Horizontal Position\"},{\"t\":5,\"p\":1,\"n\":\"VNAM - Vertical Position\"},{\"t\":3,\"p\":1,\"n\":\"SNAM - Associated Skill\"},{\"t\":8,\"p\":1,\"n\":\"Connections\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"CNAM - Line to Index\"}]},{\"t\":3,\"p\":1,\"n\":\"INAM - Index\"}]}]}]},{\"t\":1,\"p\":1,\"n\":\"BOOK - Book\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"VMAD - Virtual Machine Adapter\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Version\"},{\"t\":3,\"p\":1,\"n\":\"Object Format\"},{\"t\":7,\"p\":1,\"n\":\"Scripts\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Script\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"scriptName\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":7,\"p\":1,\"n\":\"Properties\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Property\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"propertyName\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]},{\"t\":2,\"p\":1,\"n\":\"String\"},{\"t\":3,\"p\":1,\"n\":\"Int32\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":3,\"p\":1,\"n\":\"Bool\"},{\"t\":7,\"p\":1,\"n\":\"Array of Object\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]}]},{\"t\":7,\"p\":1,\"n\":\"Array of String\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Int32\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Float\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Bool\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]}]}]}]}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"X1\"},{\"t\":3,\"p\":1,\"n\":\"Y1\"},{\"t\":3,\"p\":1,\"n\":\"Z1\"},{\"t\":3,\"p\":1,\"n\":\"X2\"},{\"t\":3,\"p\":1,\"n\":\"Y2\"},{\"t\":3,\"p\":1,\"n\":\"Z2\"}]},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"MODT - Texture Files Hashes\"},{\"t\":7,\"p\":1,\"n\":\"MODS - Alternate Textures\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"3D Name\"},{\"t\":3,\"p\":1,\"n\":\"New Texture\"},{\"t\":3,\"p\":1,\"n\":\"3D Index\"}]}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Icon\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"ICON - Large Icon filename\"},{\"t\":2,\"p\":1,\"n\":\"MICO - Small Icon filename\"}]},{\"t\":2,\"p\":1,\"n\":\"DESC - Book Text\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Destructable\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"DEST - Header\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Health\"},{\"t\":3,\"p\":1,\"n\":\"DEST Count\"},{\"t\":3,\"p\":1,\"n\":\"VATS Targetable\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":8,\"p\":1,\"n\":\"Stages\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Stage\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"DSTD - Destruction Stage Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Health %\"},{\"t\":3,\"p\":1,\"n\":\"Index\"},{\"t\":3,\"p\":1,\"n\":\"Model Damage Stage\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":3,\"p\":1,\"n\":\"Self Damage per Second\"},{\"t\":3,\"p\":1,\"n\":\"Explosion\"},{\"t\":3,\"p\":1,\"n\":\"Debris\"},{\"t\":3,\"p\":1,\"n\":\"Debris Count\"}]},{\"t\":6,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"DMDL - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"DMDT - Texture Files Hashes\"},{\"t\":7,\"p\":1,\"n\":\"DMDS - Alternate Textures\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"3D Name\"},{\"t\":3,\"p\":1,\"n\":\"New Texture\"},{\"t\":3,\"p\":1,\"n\":\"3D Index\"}]}]}]},{\"p\":1,\"n\":\"DSTF - End Marker\"}]}]}]},{\"t\":3,\"p\":1,\"n\":\"YNAM - Sound - Pick Up\"},{\"t\":3,\"p\":1,\"n\":\"ZNAM - Sound - Put Down\"},{\"t\":3,\"n\":\"KSIZ - Keyword Count\"},{\"t\":7,\"p\":1,\"n\":\"KWDA - Keywords\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Keyword\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DATA - Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Skill\"},{\"t\":3,\"p\":1,\"n\":\"Spell\"},{\"t\":3,\"p\":1,\"n\":\"Value\"},{\"t\":5,\"p\":1,\"n\":\"Weight\"}]},{\"t\":3,\"p\":1,\"n\":\"INAM - Inventory Art\"},{\"t\":2,\"p\":1,\"n\":\"CNAM - Description\"}]},{\"t\":1,\"p\":1,\"n\":\"BPTD - Body Part Data\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"MODT - Texture Files Hashes\"},{\"t\":7,\"p\":1,\"n\":\"MODS - Alternate Textures\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"3D Name\"},{\"t\":3,\"p\":1,\"n\":\"New Texture\"},{\"t\":3,\"p\":1,\"n\":\"3D Index\"}]}]}]},{\"t\":10,\"p\":1,\"n\":\"Body Parts\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Body Part\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"BPTN - Part Name\"},{\"t\":2,\"p\":1,\"n\":\"PNAM - Pose Matching\"},{\"t\":2,\"p\":1,\"n\":\"BPNN - Part Node\"},{\"t\":2,\"p\":1,\"n\":\"BPNT - VATS Target\"},{\"t\":2,\"p\":1,\"n\":\"BPNI - IK Data - Start Node\"},{\"t\":6,\"p\":1,\"n\":\"BPND - \",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Damage Mult\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":3,\"p\":1,\"n\":\"Part Type\"},{\"t\":3,\"p\":1,\"n\":\"Health Percent\"},{\"t\":3,\"p\":1,\"n\":\"Actor Value\"},{\"t\":3,\"p\":1,\"n\":\"To Hit Chance\"},{\"t\":3,\"p\":1,\"n\":\"Explodable - Explosion Chance %\"},{\"t\":3,\"p\":1,\"n\":\"Explodable - Debris Count\"},{\"t\":3,\"p\":1,\"n\":\"Explodable - Debris\"},{\"t\":3,\"p\":1,\"n\":\"Explodable - Explosion\"},{\"t\":5,\"p\":1,\"n\":\"Tracking Max Angle\"},{\"t\":5,\"p\":1,\"n\":\"Explodable - Debris Scale\"},{\"t\":3,\"p\":1,\"n\":\"Severable - Debris Count\"},{\"t\":3,\"p\":1,\"n\":\"Severable - Debris\"},{\"t\":3,\"p\":1,\"n\":\"Severable - Explosion\"},{\"t\":5,\"p\":1,\"n\":\"Severable - Debris Scale\"},{\"t\":6,\"p\":1,\"n\":\"Gore Effects Positioning\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Translate\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"X\"},{\"t\":5,\"p\":1,\"n\":\"Y\"},{\"t\":5,\"p\":1,\"n\":\"Z\"}]},{\"t\":6,\"p\":1,\"n\":\"Rotation\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"X\"},{\"t\":5,\"p\":1,\"n\":\"Y\"},{\"t\":5,\"p\":1,\"n\":\"Z\"}]}]},{\"t\":3,\"p\":1,\"n\":\"Severable - Impact DataSet\"},{\"t\":3,\"p\":1,\"n\":\"Explodable - Impact DataSet\"},{\"t\":3,\"p\":1,\"n\":\"Severable - Decal Count\"},{\"t\":3,\"p\":1,\"n\":\"Explodable - Decal Count\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":5,\"p\":1,\"n\":\"Limb Replacement Scale\"}]},{\"t\":2,\"p\":1,\"n\":\"NAM1 - Limb Replacement Model\"},{\"t\":2,\"p\":1,\"n\":\"NAM4 - Gore Effects - Target Bone\"},{\"t\":11,\"p\":1,\"n\":\"NAM5 - Texture Files Hashes\"}]}]}]},{\"t\":1,\"p\":1,\"n\":\"CAMS - Camera Shot\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"MODT - Texture Files Hashes\"},{\"t\":7,\"p\":1,\"n\":\"MODS - Alternate Textures\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"3D Name\"},{\"t\":3,\"p\":1,\"n\":\"New Texture\"},{\"t\":3,\"p\":1,\"n\":\"3D Index\"}]}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DATA - Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Action\"},{\"t\":3,\"p\":1,\"n\":\"Location\"},{\"t\":3,\"p\":1,\"n\":\"Target\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":6,\"p\":1,\"n\":\"Time Multipliers\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Player\"},{\"t\":5,\"p\":1,\"n\":\"Target\"},{\"t\":5,\"p\":1,\"n\":\"Global\"}]},{\"t\":5,\"p\":1,\"n\":\"Max Time\"},{\"t\":5,\"p\":1,\"n\":\"Min Time\"},{\"t\":5,\"p\":1,\"n\":\"Target % Between Actors\"},{\"t\":5,\"p\":1,\"n\":\"Near Target Distance\"}]},{\"t\":3,\"p\":1,\"n\":\"MNAM - Image Space Modifier\"}]},{\"t\":1,\"p\":1,\"n\":\"CELL - Cell\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":3,\"p\":1,\"n\":\"DATA - Flags\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"XCLC - Grid\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"X\"},{\"t\":3,\"p\":1,\"n\":\"Y\"},{\"t\":3,\"p\":1,\"n\":\"Force Hide Land\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"XCLL - Lighting\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Ambient Color\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Directional Color\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Fog Color Near\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":5,\"p\":1,\"n\":\"Fog Near\"},{\"t\":5,\"p\":1,\"n\":\"Fog Far\"},{\"t\":3,\"p\":1,\"n\":\"Directional Rotation XY\"},{\"t\":3,\"p\":1,\"n\":\"Directional Rotation Z\"},{\"t\":5,\"p\":1,\"n\":\"Directional Fade\"},{\"t\":5,\"p\":1,\"n\":\"Fog Clip Distance\"},{\"t\":5,\"p\":1,\"n\":\"Fog Power\"},{\"t\":6,\"p\":1,\"n\":\"Ambient Colors\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Directional\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"X+\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"X-\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Y+\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Y-\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Z+\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Z-\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]}]},{\"t\":6,\"p\":1,\"n\":\"Specular\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":5,\"p\":1,\"n\":\"Scale\"}]},{\"t\":6,\"p\":1,\"n\":\"Fog Color Far\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":5,\"p\":1,\"n\":\"Fog Max\"},{\"t\":5,\"p\":1,\"n\":\"Light Fade Begin\"},{\"t\":5,\"p\":1,\"n\":\"Light Fade End\"},{\"t\":3,\"p\":1,\"n\":\"Inherits\"}]},{\"t\":11,\"n\":\"TVDT - Occlusion Data\"},{\"t\":11,\"n\":\"MHDT - Max Height Data\"},{\"t\":3,\"p\":1,\"n\":\"LTMP - Lighting Template\"},{\"t\":11,\"n\":\"LNAM - Unknown\"},{\"t\":5,\"p\":1,\"n\":\"XCLW - Water Height\"},{\"t\":2,\"p\":1,\"n\":\"XNAM - Water Noise Texture\"},{\"t\":7,\"p\":1,\"n\":\"XCLR - Regions\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Region\"}]},{\"t\":3,\"p\":1,\"n\":\"XLCN - Location\"},{\"t\":11,\"n\":\"XWCN - Unknown\"},{\"t\":11,\"n\":\"XWCS - Unknown\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"XWCU - Water Velocity\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"X Offset\"},{\"t\":5,\"p\":1,\"n\":\"Y Offset\"},{\"t\":5,\"p\":1,\"n\":\"Z Offset\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":5,\"p\":1,\"n\":\"X Angle\"},{\"t\":5,\"p\":1,\"n\":\"Y Angle\"},{\"t\":5,\"p\":1,\"n\":\"Z Angle\"}]},{\"t\":3,\"p\":1,\"n\":\"XCWT - Water\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Ownership\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"XOWN - Owner\"},{\"t\":3,\"p\":1,\"n\":\"XRNK - Faction rank\"}]},{\"t\":3,\"p\":1,\"n\":\"XILL - Lock List\"},{\"t\":2,\"p\":1,\"n\":\"XWEM - Water Environment Map\"},{\"t\":3,\"p\":1,\"n\":\"XCCM - Sky\\/Weather from Region\"},{\"t\":3,\"p\":1,\"n\":\"XCAS - Acoustic Space\"},{\"t\":3,\"p\":1,\"n\":\"XEZN - Encounter Zone\"},{\"t\":3,\"p\":1,\"n\":\"XCMO - Music Type\"},{\"t\":3,\"p\":1,\"n\":\"XCIM - Image Space\"}]},{\"t\":1,\"p\":1,\"n\":\"CLAS - Class\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":2,\"p\":1,\"n\":\"DESC - Description\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Icon\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"ICON - Large Icon filename\"},{\"t\":2,\"p\":1,\"n\":\"MICO - Small Icon filename\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DATA - \",\"c\":[{\"t\":11,\"n\":\"Unknown\"},{\"t\":3,\"p\":1,\"n\":\"Teaches\"},{\"t\":3,\"p\":1,\"n\":\"Maximum training level\"},{\"t\":7,\"p\":1,\"n\":\"Skill Weights\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Weight\"}]},{\"t\":5,\"p\":1,\"n\":\"Bleedout Default\"},{\"t\":3,\"p\":1,\"n\":\"Voice Points\"},{\"t\":7,\"p\":1,\"n\":\"Attribute Weights\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Weight\"}]}]}]},{\"t\":1,\"p\":1,\"n\":\"CLDC\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"}]},{\"t\":1,\"p\":1,\"n\":\"CLFM - Color\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"CNAM - Color\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":3,\"p\":1,\"n\":\"FNAM - Playable\"}]},{\"t\":1,\"p\":1,\"n\":\"CLMT - Climate\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":7,\"p\":1,\"n\":\"WLST - Weather Types\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Weather Type\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Weather\"},{\"t\":3,\"p\":1,\"n\":\"Chance\"},{\"t\":3,\"p\":1,\"n\":\"Global\"}]}]},{\"t\":2,\"p\":1,\"n\":\"FNAM - Sun Texture\"},{\"t\":2,\"p\":1,\"n\":\"GNAM - Sun Glare Texture\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"MODT - Texture Files Hashes\"},{\"t\":7,\"p\":1,\"n\":\"MODS - Alternate Textures\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"3D Name\"},{\"t\":3,\"p\":1,\"n\":\"New Texture\"},{\"t\":3,\"p\":1,\"n\":\"3D Index\"}]}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"TNAM - Timing\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Sunrise\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Begin\"},{\"t\":3,\"p\":1,\"n\":\"End\"}]},{\"t\":6,\"p\":1,\"n\":\"Sunset\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Begin\"},{\"t\":3,\"p\":1,\"n\":\"End\"}]},{\"t\":3,\"p\":1,\"n\":\"Volatility\"},{\"t\":3,\"p\":1,\"n\":\"Moons \\/ Phase Length\"}]}]},{\"t\":1,\"p\":1,\"n\":\"COBJ - Constructible Object\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":3,\"n\":\"COCT - Count\"},{\"t\":10,\"p\":1,\"n\":\"Items\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Item\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"CNTO - Item\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Item\"},{\"t\":3,\"p\":1,\"n\":\"Count\"}]},{\"t\":6,\"p\":1,\"n\":\"COED - Extra Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Owner\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Global Variable\"},{\"t\":3,\"p\":1,\"n\":\"Required Rank\"},{\"t\":5,\"p\":1,\"n\":\"Item Condition\"}]}]}]},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Conditions\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Condition\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"CTDA - \",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":5,\"p\":1,\"n\":\"Comparison Value - Float\"},{\"t\":3,\"p\":1,\"n\":\"Comparison Value - Global\"},{\"t\":3,\"p\":1,\"n\":\"Function\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":11,\"p\":1,\"n\":\"None\"},{\"t\":3,\"p\":1,\"n\":\"Integer\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":11,\"p\":1,\"n\":\"Variable Name (unused)\"},{\"t\":3,\"p\":1,\"n\":\"Sex\"},{\"t\":3,\"p\":1,\"n\":\"Actor Value\"},{\"t\":3,\"p\":1,\"n\":\"Crime Type\"},{\"t\":3,\"p\":1,\"n\":\"Axis\"},{\"t\":3,\"p\":1,\"n\":\"Quest Stage (unused)\"},{\"t\":3,\"p\":1,\"n\":\"Misc Stat\"},{\"t\":3,\"p\":1,\"n\":\"Alignment\"},{\"t\":3,\"p\":1,\"n\":\"Equip Type\"},{\"t\":3,\"p\":1,\"n\":\"Form Type\"},{\"t\":3,\"p\":1,\"n\":\"Critical Stage\"},{\"t\":3,\"p\":1,\"n\":\"Object Reference\"},{\"t\":3,\"p\":1,\"n\":\"Inventory Object\"},{\"t\":3,\"p\":1,\"n\":\"Actor\"},{\"t\":3,\"p\":1,\"n\":\"Voice Type\"},{\"t\":3,\"p\":1,\"n\":\"Idle\"},{\"t\":3,\"p\":1,\"n\":\"Form List\"},{\"t\":3,\"p\":1,\"n\":\"Quest\"},{\"t\":3,\"p\":1,\"n\":\"Faction\"},{\"t\":3,\"p\":1,\"n\":\"Cell\"},{\"t\":3,\"p\":1,\"n\":\"Class\"},{\"t\":3,\"p\":1,\"n\":\"Race\"},{\"t\":3,\"p\":1,\"n\":\"Actor Base\"},{\"t\":3,\"p\":1,\"n\":\"Global\"},{\"t\":3,\"p\":1,\"n\":\"Weather\"},{\"t\":3,\"p\":1,\"n\":\"Package\"},{\"t\":3,\"p\":1,\"n\":\"Encounter Zone\"},{\"t\":3,\"p\":1,\"n\":\"Perk\"},{\"t\":3,\"p\":1,\"n\":\"Owner\"},{\"t\":3,\"p\":1,\"n\":\"Furniture\"},{\"t\":3,\"p\":1,\"n\":\"Effect Item\"},{\"t\":3,\"p\":1,\"n\":\"Base Effect\"},{\"t\":3,\"p\":1,\"n\":\"Worldspace\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Function\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Param (INVALID)\"},{\"t\":3,\"p\":1,\"n\":\"Referenceable Object\"},{\"t\":3,\"p\":1,\"n\":\"Region\"},{\"t\":3,\"p\":1,\"n\":\"Keyword\"},{\"t\":3,\"p\":1,\"n\":\"Player Action\"},{\"t\":3,\"p\":1,\"n\":\"Casting Type\"},{\"t\":3,\"p\":1,\"n\":\"Shout\"},{\"t\":3,\"p\":1,\"n\":\"Location\"},{\"t\":3,\"p\":1,\"n\":\"Location Ref Type\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"Packdata ID\"},{\"t\":3,\"p\":1,\"n\":\"Association Type\"},{\"t\":3,\"p\":1,\"n\":\"Furniture Anim\"},{\"t\":3,\"p\":1,\"n\":\"Furniture Entry\"},{\"t\":3,\"p\":1,\"n\":\"Scene\"},{\"t\":3,\"p\":1,\"n\":\"Ward State\"},{\"t\":3,\"p\":1,\"n\":\"Event\"},{\"t\":3,\"p\":1,\"n\":\"Event Data\"},{\"t\":3,\"p\":1,\"n\":\"Quest Stage\"},{\"t\":3,\"p\":1,\"n\":\"Weapon\"},{\"t\":3,\"p\":1,\"n\":\"Weapon List\"},{\"t\":3,\"p\":1,\"n\":\"Target\"},{\"t\":3,\"p\":1,\"n\":\"Target List\"},{\"t\":3,\"p\":1,\"n\":\"Target Part\"},{\"t\":3,\"p\":1,\"n\":\"VATS Action\"},{\"t\":3,\"p\":1,\"n\":\"Critical Effect\"},{\"t\":3,\"p\":1,\"n\":\"Critical Effect List\"},{\"t\":3,\"p\":1,\"n\":\"Weapon Type\"},{\"t\":3,\"p\":1,\"n\":\"Projectile Type\"},{\"t\":3,\"p\":1,\"n\":\"Delivery Type\"},{\"t\":3,\"p\":1,\"n\":\"Run On\"},{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":3,\"p\":1,\"n\":\"Parameter #3\"}]},{\"t\":2,\"p\":1,\"n\":\"CIS1 - Parameter #1\"},{\"t\":2,\"p\":1,\"n\":\"CIS2 - Parameter #2\"}]}]},{\"t\":3,\"p\":1,\"n\":\"CNAM - Created Object\"},{\"t\":3,\"p\":1,\"n\":\"BNAM - Workbench Keyword\"},{\"t\":3,\"p\":1,\"n\":\"NAM1 - Created Object Count\"}]},{\"t\":1,\"p\":1,\"n\":\"COLL - Collision Layer\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"p\":1,\"n\":\"DESC - Description\"},{\"t\":3,\"p\":1,\"n\":\"BNAM - Index\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"FNAM - Debug Color\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":3,\"n\":\"Unused\"}]},{\"t\":3,\"p\":1,\"n\":\"GNAM - Flags\"},{\"t\":2,\"p\":1,\"n\":\"MNAM - Name\"},{\"t\":3,\"n\":\"INTV - Interactables Count\"},{\"t\":7,\"p\":1,\"n\":\"CNAM - Collides With\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Forms\"}]}]},{\"t\":1,\"p\":1,\"n\":\"CONT - Container\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"VMAD - Virtual Machine Adapter\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Version\"},{\"t\":3,\"p\":1,\"n\":\"Object Format\"},{\"t\":7,\"p\":1,\"n\":\"Scripts\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Script\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"scriptName\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":7,\"p\":1,\"n\":\"Properties\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Property\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"propertyName\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]},{\"t\":2,\"p\":1,\"n\":\"String\"},{\"t\":3,\"p\":1,\"n\":\"Int32\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":3,\"p\":1,\"n\":\"Bool\"},{\"t\":7,\"p\":1,\"n\":\"Array of Object\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]}]},{\"t\":7,\"p\":1,\"n\":\"Array of String\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Int32\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Float\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Bool\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]}]}]}]}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"X1\"},{\"t\":3,\"p\":1,\"n\":\"Y1\"},{\"t\":3,\"p\":1,\"n\":\"Z1\"},{\"t\":3,\"p\":1,\"n\":\"X2\"},{\"t\":3,\"p\":1,\"n\":\"Y2\"},{\"t\":3,\"p\":1,\"n\":\"Z2\"}]},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"MODT - Texture Files Hashes\"},{\"t\":7,\"p\":1,\"n\":\"MODS - Alternate Textures\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"3D Name\"},{\"t\":3,\"p\":1,\"n\":\"New Texture\"},{\"t\":3,\"p\":1,\"n\":\"3D Index\"}]}]}]},{\"t\":3,\"n\":\"COCT - Count\"},{\"t\":10,\"p\":1,\"n\":\"Items\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Item\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"CNTO - Item\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Item\"},{\"t\":3,\"p\":1,\"n\":\"Count\"}]},{\"t\":6,\"p\":1,\"n\":\"COED - Extra Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Owner\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Global Variable\"},{\"t\":3,\"p\":1,\"n\":\"Required Rank\"},{\"t\":5,\"p\":1,\"n\":\"Item Condition\"}]}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Destructable\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"DEST - Header\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Health\"},{\"t\":3,\"p\":1,\"n\":\"DEST Count\"},{\"t\":3,\"p\":1,\"n\":\"VATS Targetable\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":8,\"p\":1,\"n\":\"Stages\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Stage\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"DSTD - Destruction Stage Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Health %\"},{\"t\":3,\"p\":1,\"n\":\"Index\"},{\"t\":3,\"p\":1,\"n\":\"Model Damage Stage\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":3,\"p\":1,\"n\":\"Self Damage per Second\"},{\"t\":3,\"p\":1,\"n\":\"Explosion\"},{\"t\":3,\"p\":1,\"n\":\"Debris\"},{\"t\":3,\"p\":1,\"n\":\"Debris Count\"}]},{\"t\":6,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"DMDL - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"DMDT - Texture Files Hashes\"},{\"t\":7,\"p\":1,\"n\":\"DMDS - Alternate Textures\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"3D Name\"},{\"t\":3,\"p\":1,\"n\":\"New Texture\"},{\"t\":3,\"p\":1,\"n\":\"3D Index\"}]}]}]},{\"p\":1,\"n\":\"DSTF - End Marker\"}]}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DATA - \",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":5,\"p\":1,\"n\":\"Weight\"}]},{\"t\":3,\"p\":1,\"n\":\"SNAM - Sound - Open\"},{\"t\":3,\"p\":1,\"n\":\"QNAM - Sound - Close\"}]},{\"t\":1,\"p\":1,\"n\":\"CPTH - Camera Path\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Conditions\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Condition\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"CTDA - \",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":5,\"p\":1,\"n\":\"Comparison Value - Float\"},{\"t\":3,\"p\":1,\"n\":\"Comparison Value - Global\"},{\"t\":3,\"p\":1,\"n\":\"Function\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":11,\"p\":1,\"n\":\"None\"},{\"t\":3,\"p\":1,\"n\":\"Integer\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":11,\"p\":1,\"n\":\"Variable Name (unused)\"},{\"t\":3,\"p\":1,\"n\":\"Sex\"},{\"t\":3,\"p\":1,\"n\":\"Actor Value\"},{\"t\":3,\"p\":1,\"n\":\"Crime Type\"},{\"t\":3,\"p\":1,\"n\":\"Axis\"},{\"t\":3,\"p\":1,\"n\":\"Quest Stage (unused)\"},{\"t\":3,\"p\":1,\"n\":\"Misc Stat\"},{\"t\":3,\"p\":1,\"n\":\"Alignment\"},{\"t\":3,\"p\":1,\"n\":\"Equip Type\"},{\"t\":3,\"p\":1,\"n\":\"Form Type\"},{\"t\":3,\"p\":1,\"n\":\"Critical Stage\"},{\"t\":3,\"p\":1,\"n\":\"Object Reference\"},{\"t\":3,\"p\":1,\"n\":\"Inventory Object\"},{\"t\":3,\"p\":1,\"n\":\"Actor\"},{\"t\":3,\"p\":1,\"n\":\"Voice Type\"},{\"t\":3,\"p\":1,\"n\":\"Idle\"},{\"t\":3,\"p\":1,\"n\":\"Form List\"},{\"t\":3,\"p\":1,\"n\":\"Quest\"},{\"t\":3,\"p\":1,\"n\":\"Faction\"},{\"t\":3,\"p\":1,\"n\":\"Cell\"},{\"t\":3,\"p\":1,\"n\":\"Class\"},{\"t\":3,\"p\":1,\"n\":\"Race\"},{\"t\":3,\"p\":1,\"n\":\"Actor Base\"},{\"t\":3,\"p\":1,\"n\":\"Global\"},{\"t\":3,\"p\":1,\"n\":\"Weather\"},{\"t\":3,\"p\":1,\"n\":\"Package\"},{\"t\":3,\"p\":1,\"n\":\"Encounter Zone\"},{\"t\":3,\"p\":1,\"n\":\"Perk\"},{\"t\":3,\"p\":1,\"n\":\"Owner\"},{\"t\":3,\"p\":1,\"n\":\"Furniture\"},{\"t\":3,\"p\":1,\"n\":\"Effect Item\"},{\"t\":3,\"p\":1,\"n\":\"Base Effect\"},{\"t\":3,\"p\":1,\"n\":\"Worldspace\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Function\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Param (INVALID)\"},{\"t\":3,\"p\":1,\"n\":\"Referenceable Object\"},{\"t\":3,\"p\":1,\"n\":\"Region\"},{\"t\":3,\"p\":1,\"n\":\"Keyword\"},{\"t\":3,\"p\":1,\"n\":\"Player Action\"},{\"t\":3,\"p\":1,\"n\":\"Casting Type\"},{\"t\":3,\"p\":1,\"n\":\"Shout\"},{\"t\":3,\"p\":1,\"n\":\"Location\"},{\"t\":3,\"p\":1,\"n\":\"Location Ref Type\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"Packdata ID\"},{\"t\":3,\"p\":1,\"n\":\"Association Type\"},{\"t\":3,\"p\":1,\"n\":\"Furniture Anim\"},{\"t\":3,\"p\":1,\"n\":\"Furniture Entry\"},{\"t\":3,\"p\":1,\"n\":\"Scene\"},{\"t\":3,\"p\":1,\"n\":\"Ward State\"},{\"t\":3,\"p\":1,\"n\":\"Event\"},{\"t\":3,\"p\":1,\"n\":\"Event Data\"},{\"t\":3,\"p\":1,\"n\":\"Quest Stage\"},{\"t\":3,\"p\":1,\"n\":\"Weapon\"},{\"t\":3,\"p\":1,\"n\":\"Weapon List\"},{\"t\":3,\"p\":1,\"n\":\"Target\"},{\"t\":3,\"p\":1,\"n\":\"Target List\"},{\"t\":3,\"p\":1,\"n\":\"Target Part\"},{\"t\":3,\"p\":1,\"n\":\"VATS Action\"},{\"t\":3,\"p\":1,\"n\":\"Critical Effect\"},{\"t\":3,\"p\":1,\"n\":\"Critical Effect List\"},{\"t\":3,\"p\":1,\"n\":\"Weapon Type\"},{\"t\":3,\"p\":1,\"n\":\"Projectile Type\"},{\"t\":3,\"p\":1,\"n\":\"Delivery Type\"},{\"t\":3,\"p\":1,\"n\":\"Run On\"},{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":3,\"p\":1,\"n\":\"Parameter #3\"}]},{\"t\":2,\"p\":1,\"n\":\"CIS1 - Parameter #1\"},{\"t\":2,\"p\":1,\"n\":\"CIS2 - Parameter #2\"}]}]},{\"t\":7,\"p\":1,\"n\":\"ANAM - Related Camera Paths\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Related Camera Path\"}]},{\"t\":3,\"p\":1,\"n\":\"DATA - Camera Zoom\"},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Camera Shots\",\"d\":1,\"c\":[{\"t\":3,\"p\":1,\"n\":\"SNAM - Camera Shot\"}]}]},{\"t\":1,\"p\":1,\"n\":\"CSTY - Combat Style\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"CSGD - General\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Offensive Mult\"},{\"t\":5,\"p\":1,\"n\":\"Defensive Mult\"},{\"t\":5,\"p\":1,\"n\":\"Group Offensive Mult\"},{\"t\":5,\"p\":1,\"n\":\"Equipment Score Mult - Melee\"},{\"t\":5,\"p\":1,\"n\":\"Equipment Score Mult - Magic\"},{\"t\":5,\"p\":1,\"n\":\"Equipment Score Mult - Ranged\"},{\"t\":5,\"p\":1,\"n\":\"Equipment Score Mult - Shout\"},{\"t\":5,\"p\":1,\"n\":\"Equipment Score Mult - Unarmed\"},{\"t\":5,\"p\":1,\"n\":\"Equipment Score Mult - Staff\"},{\"t\":5,\"p\":1,\"n\":\"Avoid Threat Chance\"}]},{\"t\":11,\"n\":\"CSMD - Unknown\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"CSME - Melee\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Attack Staggered Mult\"},{\"t\":5,\"p\":1,\"n\":\"Power Attack Staggered Mult\"},{\"t\":5,\"p\":1,\"n\":\"Power Attack Blocking Mult\"},{\"t\":5,\"p\":1,\"n\":\"Bash Mult\"},{\"t\":5,\"p\":1,\"n\":\"Bash Recoil Mult\"},{\"t\":5,\"p\":1,\"n\":\"Bash Attack Mult\"},{\"t\":5,\"p\":1,\"n\":\"Bash Power Attack Mult\"},{\"t\":5,\"p\":1,\"n\":\"Special Attack Mult\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"CSCR - Close Range\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Circle Mult\"},{\"t\":5,\"p\":1,\"n\":\"Fallback Mult\"},{\"t\":5,\"p\":1,\"n\":\"Flank Distance\"},{\"t\":5,\"p\":1,\"n\":\"Stalk Time\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"CSLR - Long Range\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Strafe Mult\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"CSFL - Flight\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Hover Chance\"},{\"t\":5,\"p\":1,\"n\":\"Dive Bomb Chance\"},{\"t\":5,\"p\":1,\"n\":\"Ground Attack Chance\"},{\"t\":5,\"p\":1,\"n\":\"Hover Time\"},{\"t\":5,\"p\":1,\"n\":\"Ground Attack Time\"},{\"t\":5,\"p\":1,\"n\":\"Perch Attack Chance\"},{\"t\":5,\"p\":1,\"n\":\"Perch Attack Time\"},{\"t\":5,\"p\":1,\"n\":\"Flying Attack Chance\"}]},{\"t\":3,\"p\":1,\"n\":\"DATA - Flags\"}]},{\"t\":1,\"p\":1,\"n\":\"DEBR - Debris\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Models\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"DATA - Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Percentage\"},{\"t\":2,\"p\":1,\"n\":\"Model Filename\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"}]},{\"t\":11,\"p\":1,\"n\":\"MODT - Texture Files Hashes\"}]}]}]},{\"t\":1,\"p\":1,\"n\":\"DIAL - Dialog Topic\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":5,\"p\":1,\"n\":\"PNAM - Priority\"},{\"t\":3,\"p\":1,\"n\":\"BNAM - Branch\"},{\"t\":3,\"p\":1,\"n\":\"QNAM - Quest\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DATA - Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Topic Flags\"},{\"t\":3,\"p\":1,\"n\":\"Category\"},{\"t\":3,\"p\":1,\"n\":\"Subtype\"}]},{\"t\":2,\"p\":1,\"n\":\"SNAM - Subtype Name\"},{\"t\":3,\"p\":1,\"n\":\"TIFC - Info Count\"}]},{\"t\":1,\"p\":1,\"n\":\"DLBR - Dialog Branch\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":3,\"p\":1,\"n\":\"QNAM - Quest\"},{\"t\":3,\"n\":\"TNAM - Unknown\"},{\"t\":3,\"p\":1,\"n\":\"DNAM - Flags\"},{\"t\":3,\"p\":1,\"n\":\"SNAM - Starting Topic\"}]},{\"t\":1,\"p\":1,\"n\":\"DLVW - Dialog View\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":3,\"p\":1,\"n\":\"QNAM - Quest\"},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Branches\",\"d\":1,\"c\":[{\"t\":3,\"p\":1,\"n\":\"BNAM - Branch\"}]},{\"t\":8,\"n\":\"Unknown TNAM\",\"c\":[{\"t\":6,\"n\":\"Unknown\",\"c\":[{\"t\":11,\"n\":\"TNAM - Unknown\"}]}]},{\"t\":11,\"n\":\"ENAM - Unknown\"},{\"t\":11,\"n\":\"DNAM - Unknown\"}]},{\"t\":1,\"n\":\"DOBJ - Default Object Manager\",\"c\":[{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":7,\"n\":\"DNAM - Objects\",\"c\":[{\"t\":6,\"n\":\"Object\",\"c\":[{\"t\":3,\"n\":\"Use\"},{\"t\":3,\"n\":\"Object ID\"}]}]}]},{\"t\":1,\"p\":1,\"n\":\"DOOR - Door\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"VMAD - Virtual Machine Adapter\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Version\"},{\"t\":3,\"p\":1,\"n\":\"Object Format\"},{\"t\":7,\"p\":1,\"n\":\"Scripts\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Script\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"scriptName\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":7,\"p\":1,\"n\":\"Properties\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Property\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"propertyName\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]},{\"t\":2,\"p\":1,\"n\":\"String\"},{\"t\":3,\"p\":1,\"n\":\"Int32\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":3,\"p\":1,\"n\":\"Bool\"},{\"t\":7,\"p\":1,\"n\":\"Array of Object\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]}]},{\"t\":7,\"p\":1,\"n\":\"Array of String\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Int32\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Float\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Bool\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]}]}]}]}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"X1\"},{\"t\":3,\"p\":1,\"n\":\"Y1\"},{\"t\":3,\"p\":1,\"n\":\"Z1\"},{\"t\":3,\"p\":1,\"n\":\"X2\"},{\"t\":3,\"p\":1,\"n\":\"Y2\"},{\"t\":3,\"p\":1,\"n\":\"Z2\"}]},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"MODT - Texture Files Hashes\"},{\"t\":7,\"p\":1,\"n\":\"MODS - Alternate Textures\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"3D Name\"},{\"t\":3,\"p\":1,\"n\":\"New Texture\"},{\"t\":3,\"p\":1,\"n\":\"3D Index\"}]}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Destructable\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"DEST - Header\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Health\"},{\"t\":3,\"p\":1,\"n\":\"DEST Count\"},{\"t\":3,\"p\":1,\"n\":\"VATS Targetable\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":8,\"p\":1,\"n\":\"Stages\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Stage\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"DSTD - Destruction Stage Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Health %\"},{\"t\":3,\"p\":1,\"n\":\"Index\"},{\"t\":3,\"p\":1,\"n\":\"Model Damage Stage\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":3,\"p\":1,\"n\":\"Self Damage per Second\"},{\"t\":3,\"p\":1,\"n\":\"Explosion\"},{\"t\":3,\"p\":1,\"n\":\"Debris\"},{\"t\":3,\"p\":1,\"n\":\"Debris Count\"}]},{\"t\":6,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"DMDL - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"DMDT - Texture Files Hashes\"},{\"t\":7,\"p\":1,\"n\":\"DMDS - Alternate Textures\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"3D Name\"},{\"t\":3,\"p\":1,\"n\":\"New Texture\"},{\"t\":3,\"p\":1,\"n\":\"3D Index\"}]}]}]},{\"p\":1,\"n\":\"DSTF - End Marker\"}]}]}]},{\"t\":3,\"p\":1,\"n\":\"SNAM - Sound - Open\"},{\"t\":3,\"p\":1,\"n\":\"ANAM - Sound - Close\"},{\"t\":3,\"p\":1,\"n\":\"BNAM - Sound - Loop\"},{\"t\":3,\"p\":1,\"n\":\"FNAM - Flags\"}]},{\"t\":1,\"p\":1,\"n\":\"DUAL - Dual Cast Data\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"X1\"},{\"t\":3,\"p\":1,\"n\":\"Y1\"},{\"t\":3,\"p\":1,\"n\":\"Z1\"},{\"t\":3,\"p\":1,\"n\":\"X2\"},{\"t\":3,\"p\":1,\"n\":\"Y2\"},{\"t\":3,\"p\":1,\"n\":\"Z2\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DATA - Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Projectile\"},{\"t\":3,\"p\":1,\"n\":\"Explosion\"},{\"t\":3,\"p\":1,\"n\":\"Effect Shader\"},{\"t\":3,\"p\":1,\"n\":\"Hit Effect Art\"},{\"t\":3,\"p\":1,\"n\":\"Impact Data Set\"},{\"t\":3,\"p\":1,\"n\":\"Inherit Scale\"}]}]},{\"t\":1,\"p\":1,\"n\":\"ECZN - Encounter Zone\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"p\":1,\"n\":\"DATA - \",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Owner\"},{\"t\":3,\"p\":1,\"n\":\"Location\"},{\"t\":3,\"p\":1,\"n\":\"Rank\"},{\"t\":3,\"p\":1,\"n\":\"Min Level\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":3,\"p\":1,\"n\":\"Max Level\"}]}]},{\"t\":1,\"p\":1,\"n\":\"EFSH - Effect Shader\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"p\":1,\"n\":\"ICON - Fill Texture\"},{\"t\":2,\"p\":1,\"n\":\"ICO2 - Particle Shader Texture\"},{\"t\":2,\"p\":1,\"n\":\"NAM7 - Holes Texture\"},{\"t\":2,\"p\":1,\"n\":\"NAM8 - Membrane Palette Texture\"},{\"t\":2,\"p\":1,\"n\":\"NAM9 - Particle Palette Texture\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DATA - \",\"c\":[{\"t\":11,\"n\":\"Unknown\"},{\"t\":3,\"p\":1,\"n\":\"Membrane Shader - Source Blend Mode\"},{\"t\":3,\"p\":1,\"n\":\"Membrane Shader - Blend Operation\"},{\"t\":3,\"p\":1,\"n\":\"Membrane Shader - Z Test Function\"},{\"t\":6,\"p\":1,\"n\":\"Fill\\/Texture Effect - Color Key 1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":5,\"p\":1,\"n\":\"Fill\\/Texture Effect - Alpha Fade In Time\"},{\"t\":5,\"p\":1,\"n\":\"Fill\\/Texture Effect - Full Alpha Time\"},{\"t\":5,\"p\":1,\"n\":\"Fill\\/Texture Effect - Alpha Fade Out Time\"},{\"t\":5,\"p\":1,\"n\":\"Fill\\/Texture Effect - Presistent Alpha Ratio\"},{\"t\":5,\"p\":1,\"n\":\"Fill\\/Texture Effect - Alpha Pulse Amplitude\"},{\"t\":5,\"p\":1,\"n\":\"Fill\\/Texture Effect - Alpha Pulse Frequency\"},{\"t\":5,\"p\":1,\"n\":\"Fill\\/Texture Effect - Texture Animation Speed (U)\"},{\"t\":5,\"p\":1,\"n\":\"Fill\\/Texture Effect - Texture Animation Speed (V)\"},{\"t\":5,\"p\":1,\"n\":\"Edge Effect - Fall Off\"},{\"t\":6,\"p\":1,\"n\":\"Edge Effect - Color\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":5,\"p\":1,\"n\":\"Edge Effect - Alpha Fade In Time\"},{\"t\":5,\"p\":1,\"n\":\"Edge Effect - Full Alpha Time\"},{\"t\":5,\"p\":1,\"n\":\"Edge Effect - Alpha Fade Out Time\"},{\"t\":5,\"p\":1,\"n\":\"Edge Effect - Persistent Alpha Ratio\"},{\"t\":5,\"p\":1,\"n\":\"Edge Effect - Alpha Pulse Amplitude\"},{\"t\":5,\"p\":1,\"n\":\"Edge Effect - Alpha Pulse Frequency\"},{\"t\":5,\"p\":1,\"n\":\"Fill\\/Texture Effect - Full Alpha Ratio\"},{\"t\":5,\"p\":1,\"n\":\"Edge Effect - Full Alpha Ratio\"},{\"t\":3,\"p\":1,\"n\":\"Membrane Shader - Dest Blend Mode\"},{\"t\":3,\"p\":1,\"n\":\"Particle Shader - Source Blend Mode\"},{\"t\":3,\"p\":1,\"n\":\"Particle Shader - Blend Operation\"},{\"t\":3,\"p\":1,\"n\":\"Particle Shader - Z Test Function\"},{\"t\":3,\"p\":1,\"n\":\"Particle Shader - Dest Blend Mode\"},{\"t\":5,\"p\":1,\"n\":\"Particle Shader - Particle Birth Ramp Up Time\"},{\"t\":5,\"p\":1,\"n\":\"Particle Shader - Full Particle Birth Time\"},{\"t\":5,\"p\":1,\"n\":\"Particle Shader - Particle Birth Ramp Down Time\"},{\"t\":5,\"p\":1,\"n\":\"Particle Shader - Full Particle Birth Ratio\"},{\"t\":5,\"p\":1,\"n\":\"Particle Shader - Persistant Particle Count\"},{\"t\":5,\"p\":1,\"n\":\"Particle Shader - Particle Lifetime\"},{\"t\":5,\"p\":1,\"n\":\"Particle Shader - Particle Lifetime +\\/-\"},{\"t\":5,\"p\":1,\"n\":\"Particle Shader - Initial Speed Along Normal\"},{\"t\":5,\"p\":1,\"n\":\"Particle Shader - Acceleration Along Normal\"},{\"t\":5,\"p\":1,\"n\":\"Particle Shader - Initial Velocity #1\"},{\"t\":5,\"p\":1,\"n\":\"Particle Shader - Initial Velocity #2\"},{\"t\":5,\"p\":1,\"n\":\"Particle Shader - Initial Velocity #3\"},{\"t\":5,\"p\":1,\"n\":\"Particle Shader - Acceleration #1\"},{\"t\":5,\"p\":1,\"n\":\"Particle Shader - Acceleration #2\"},{\"t\":5,\"p\":1,\"n\":\"Particle Shader - Acceleration #3\"},{\"t\":5,\"p\":1,\"n\":\"Particle Shader - Scale Key 1\"},{\"t\":5,\"p\":1,\"n\":\"Particle Shader - Scale Key 2\"},{\"t\":5,\"p\":1,\"n\":\"Particle Shader - Scale Key 1 Time\"},{\"t\":5,\"p\":1,\"n\":\"Particle Shader - Scale Key 2 Time\"},{\"t\":6,\"p\":1,\"n\":\"Color Key 1 - Color\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Color Key 2 - Color\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Color Key 3 - Color\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":5,\"p\":1,\"n\":\"Color Key 1 - Color Alpha\"},{\"t\":5,\"p\":1,\"n\":\"Color Key 2 - Color Alpha\"},{\"t\":5,\"p\":1,\"n\":\"Color Key 3 - Color Alpha\"},{\"t\":5,\"p\":1,\"n\":\"Color Key 1 - Color Key Time\"},{\"t\":5,\"p\":1,\"n\":\"Color Key 2 - Color Key Time\"},{\"t\":5,\"p\":1,\"n\":\"Color Key 3 - Color Key Time\"},{\"t\":5,\"p\":1,\"n\":\"Particle Shader - Initial Speed Along Normal +\\/-\"},{\"t\":5,\"p\":1,\"n\":\"Particle Shader - Initial Rotation (deg)\"},{\"t\":5,\"p\":1,\"n\":\"Particle Shader - Initial Rotation (deg) +\\/-\"},{\"t\":5,\"p\":1,\"n\":\"Particle Shader - Rotation Speed (deg\\/sec)\"},{\"t\":5,\"p\":1,\"n\":\"Particle Shader - Rotation Speed (deg\\/sec) +\\/-\"},{\"t\":3,\"p\":1,\"n\":\"Addon Models\"},{\"t\":5,\"p\":1,\"n\":\"Holes - Start Time\"},{\"t\":5,\"p\":1,\"n\":\"Holes - End Time\"},{\"t\":5,\"p\":1,\"n\":\"Holes - Start Val\"},{\"t\":5,\"p\":1,\"n\":\"Holes - End Val\"},{\"t\":5,\"p\":1,\"n\":\"Edge Width (alpha units)\"},{\"t\":6,\"p\":1,\"n\":\"Edge Color\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":5,\"p\":1,\"n\":\"Explosion Wind Speed\"},{\"t\":3,\"p\":1,\"n\":\"Texture Count U\"},{\"t\":3,\"p\":1,\"n\":\"Texture Count V\"},{\"t\":5,\"p\":1,\"n\":\"Addon Models - Fade In Time\"},{\"t\":5,\"p\":1,\"n\":\"Addon Models - Fade Out Time\"},{\"t\":5,\"p\":1,\"n\":\"Addon Models - Scale Start\"},{\"t\":5,\"p\":1,\"n\":\"Addon Models - Scale End\"},{\"t\":5,\"p\":1,\"n\":\"Addon Models - Scale In Time\"},{\"t\":5,\"p\":1,\"n\":\"Addon Models - Scale Out Time\"},{\"t\":3,\"p\":1,\"n\":\"Ambient Sound\"},{\"t\":6,\"p\":1,\"n\":\"Fill\\/Texture Effect - Color Key 2\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Fill\\/Texture Effect - Color Key 3\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Fill\\/Texture Effect - Color Key Scale\\/Time\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Color Key 1 - Scale\"},{\"t\":5,\"p\":1,\"n\":\"Color Key 2 - Scale\"},{\"t\":5,\"p\":1,\"n\":\"Color Key 3 - Scale\"},{\"t\":5,\"p\":1,\"n\":\"Color Key 1 - Time\"},{\"t\":5,\"p\":1,\"n\":\"Color Key 2 - Time\"},{\"t\":5,\"p\":1,\"n\":\"Color Key 3 - Time\"}]},{\"t\":5,\"p\":1,\"n\":\"Color Scale\"},{\"t\":5,\"p\":1,\"n\":\"Birth Position Offset\"},{\"t\":5,\"p\":1,\"n\":\"Birth Position Offset Range +\\/-\"},{\"t\":6,\"p\":1,\"n\":\"Particle Shader Animated\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Start Frame\"},{\"t\":3,\"p\":1,\"n\":\"Start Frame Variation\"},{\"t\":3,\"p\":1,\"n\":\"End Frame\"},{\"t\":3,\"p\":1,\"n\":\"Loop Start Frame\"},{\"t\":3,\"p\":1,\"n\":\"Loop Start Variation\"},{\"t\":3,\"p\":1,\"n\":\"Frame Count\"},{\"t\":3,\"p\":1,\"n\":\"Frame Count Variation\"}]},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":5,\"p\":1,\"n\":\"Fill\\/Texture Effect - Texture Scale (U)\"},{\"t\":5,\"p\":1,\"n\":\"Fill\\/Texture Effect - Texture Scale (V)\"},{\"t\":3,\"p\":1,\"n\":\"Scene Graph Emit Depth Limit (unused)\"}]}]},{\"t\":1,\"p\":1,\"n\":\"ENCH - Object Effect\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"X1\"},{\"t\":3,\"p\":1,\"n\":\"Y1\"},{\"t\":3,\"p\":1,\"n\":\"Z1\"},{\"t\":3,\"p\":1,\"n\":\"X2\"},{\"t\":3,\"p\":1,\"n\":\"Y2\"},{\"t\":3,\"p\":1,\"n\":\"Z2\"}]},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"ENIT - Effect Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Enchantment Cost\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":3,\"p\":1,\"n\":\"Cast Type\"},{\"t\":3,\"p\":1,\"n\":\"Enchantment Amount\"},{\"t\":3,\"p\":1,\"n\":\"Target Type\"},{\"t\":3,\"p\":1,\"n\":\"Enchant Type\"},{\"t\":5,\"p\":1,\"n\":\"Charge Time\"},{\"t\":3,\"p\":1,\"n\":\"Base Enchantment\"},{\"t\":3,\"p\":1,\"n\":\"Worn Restrictions\"}]},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Effects\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Effect\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"EFID - Base Effect\"},{\"t\":6,\"p\":1,\"n\":\"EFIT - \",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Magnitude\"},{\"t\":3,\"p\":1,\"n\":\"Area\"},{\"t\":3,\"p\":1,\"n\":\"Duration\"}]},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Conditions\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Condition\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"CTDA - \",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":5,\"p\":1,\"n\":\"Comparison Value - Float\"},{\"t\":3,\"p\":1,\"n\":\"Comparison Value - Global\"},{\"t\":3,\"p\":1,\"n\":\"Function\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":11,\"p\":1,\"n\":\"None\"},{\"t\":3,\"p\":1,\"n\":\"Integer\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":11,\"p\":1,\"n\":\"Variable Name (unused)\"},{\"t\":3,\"p\":1,\"n\":\"Sex\"},{\"t\":3,\"p\":1,\"n\":\"Actor Value\"},{\"t\":3,\"p\":1,\"n\":\"Crime Type\"},{\"t\":3,\"p\":1,\"n\":\"Axis\"},{\"t\":3,\"p\":1,\"n\":\"Quest Stage (unused)\"},{\"t\":3,\"p\":1,\"n\":\"Misc Stat\"},{\"t\":3,\"p\":1,\"n\":\"Alignment\"},{\"t\":3,\"p\":1,\"n\":\"Equip Type\"},{\"t\":3,\"p\":1,\"n\":\"Form Type\"},{\"t\":3,\"p\":1,\"n\":\"Critical Stage\"},{\"t\":3,\"p\":1,\"n\":\"Object Reference\"},{\"t\":3,\"p\":1,\"n\":\"Inventory Object\"},{\"t\":3,\"p\":1,\"n\":\"Actor\"},{\"t\":3,\"p\":1,\"n\":\"Voice Type\"},{\"t\":3,\"p\":1,\"n\":\"Idle\"},{\"t\":3,\"p\":1,\"n\":\"Form List\"},{\"t\":3,\"p\":1,\"n\":\"Quest\"},{\"t\":3,\"p\":1,\"n\":\"Faction\"},{\"t\":3,\"p\":1,\"n\":\"Cell\"},{\"t\":3,\"p\":1,\"n\":\"Class\"},{\"t\":3,\"p\":1,\"n\":\"Race\"},{\"t\":3,\"p\":1,\"n\":\"Actor Base\"},{\"t\":3,\"p\":1,\"n\":\"Global\"},{\"t\":3,\"p\":1,\"n\":\"Weather\"},{\"t\":3,\"p\":1,\"n\":\"Package\"},{\"t\":3,\"p\":1,\"n\":\"Encounter Zone\"},{\"t\":3,\"p\":1,\"n\":\"Perk\"},{\"t\":3,\"p\":1,\"n\":\"Owner\"},{\"t\":3,\"p\":1,\"n\":\"Furniture\"},{\"t\":3,\"p\":1,\"n\":\"Effect Item\"},{\"t\":3,\"p\":1,\"n\":\"Base Effect\"},{\"t\":3,\"p\":1,\"n\":\"Worldspace\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Function\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Param (INVALID)\"},{\"t\":3,\"p\":1,\"n\":\"Referenceable Object\"},{\"t\":3,\"p\":1,\"n\":\"Region\"},{\"t\":3,\"p\":1,\"n\":\"Keyword\"},{\"t\":3,\"p\":1,\"n\":\"Player Action\"},{\"t\":3,\"p\":1,\"n\":\"Casting Type\"},{\"t\":3,\"p\":1,\"n\":\"Shout\"},{\"t\":3,\"p\":1,\"n\":\"Location\"},{\"t\":3,\"p\":1,\"n\":\"Location Ref Type\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"Packdata ID\"},{\"t\":3,\"p\":1,\"n\":\"Association Type\"},{\"t\":3,\"p\":1,\"n\":\"Furniture Anim\"},{\"t\":3,\"p\":1,\"n\":\"Furniture Entry\"},{\"t\":3,\"p\":1,\"n\":\"Scene\"},{\"t\":3,\"p\":1,\"n\":\"Ward State\"},{\"t\":3,\"p\":1,\"n\":\"Event\"},{\"t\":3,\"p\":1,\"n\":\"Event Data\"},{\"t\":3,\"p\":1,\"n\":\"Quest Stage\"},{\"t\":3,\"p\":1,\"n\":\"Weapon\"},{\"t\":3,\"p\":1,\"n\":\"Weapon List\"},{\"t\":3,\"p\":1,\"n\":\"Target\"},{\"t\":3,\"p\":1,\"n\":\"Target List\"},{\"t\":3,\"p\":1,\"n\":\"Target Part\"},{\"t\":3,\"p\":1,\"n\":\"VATS Action\"},{\"t\":3,\"p\":1,\"n\":\"Critical Effect\"},{\"t\":3,\"p\":1,\"n\":\"Critical Effect List\"},{\"t\":3,\"p\":1,\"n\":\"Weapon Type\"},{\"t\":3,\"p\":1,\"n\":\"Projectile Type\"},{\"t\":3,\"p\":1,\"n\":\"Delivery Type\"},{\"t\":3,\"p\":1,\"n\":\"Run On\"},{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":3,\"p\":1,\"n\":\"Parameter #3\"}]},{\"t\":2,\"p\":1,\"n\":\"CIS1 - Parameter #1\"},{\"t\":2,\"p\":1,\"n\":\"CIS2 - Parameter #2\"}]}]}]}]}]},{\"t\":1,\"p\":1,\"n\":\"EQUP - Equip Type\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":7,\"p\":1,\"n\":\"PNAM - Slot Parents\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Can Be Equipped\"}]},{\"t\":3,\"p\":1,\"n\":\"DATA - Use All Parents\"}]},{\"t\":1,\"p\":1,\"n\":\"EXPL - Explosion\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"VMAD - Virtual Machine Adapter\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Version\"},{\"t\":3,\"p\":1,\"n\":\"Object Format\"},{\"t\":7,\"p\":1,\"n\":\"Scripts\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Script\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"scriptName\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":7,\"p\":1,\"n\":\"Properties\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Property\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"propertyName\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]},{\"t\":2,\"p\":1,\"n\":\"String\"},{\"t\":3,\"p\":1,\"n\":\"Int32\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":3,\"p\":1,\"n\":\"Bool\"},{\"t\":7,\"p\":1,\"n\":\"Array of Object\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]}]},{\"t\":7,\"p\":1,\"n\":\"Array of String\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Int32\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Float\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Bool\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]}]}]}]}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"X1\"},{\"t\":3,\"p\":1,\"n\":\"Y1\"},{\"t\":3,\"p\":1,\"n\":\"Z1\"},{\"t\":3,\"p\":1,\"n\":\"X2\"},{\"t\":3,\"p\":1,\"n\":\"Y2\"},{\"t\":3,\"p\":1,\"n\":\"Z2\"}]},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"MODT - Texture Files Hashes\"},{\"t\":7,\"p\":1,\"n\":\"MODS - Alternate Textures\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"3D Name\"},{\"t\":3,\"p\":1,\"n\":\"New Texture\"},{\"t\":3,\"p\":1,\"n\":\"3D Index\"}]}]}]},{\"t\":3,\"p\":1,\"n\":\"EITM - Object Effect\"},{\"t\":3,\"p\":1,\"n\":\"MNAM - Image Space Modifier\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DATA - Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Light\"},{\"t\":3,\"p\":1,\"n\":\"Sound 1\"},{\"t\":3,\"p\":1,\"n\":\"Sound 2\"},{\"t\":3,\"p\":1,\"n\":\"Impact Data Set\"},{\"t\":3,\"p\":1,\"n\":\"Placed Object\"},{\"t\":3,\"p\":1,\"n\":\"Spawn Projectile\"},{\"t\":5,\"p\":1,\"n\":\"Force\"},{\"t\":5,\"p\":1,\"n\":\"Damage\"},{\"t\":5,\"p\":1,\"n\":\"Radius\"},{\"t\":5,\"p\":1,\"n\":\"IS Radius\"},{\"t\":5,\"p\":1,\"n\":\"Vertical Offset Mult\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":3,\"p\":1,\"n\":\"Sound Level\"}]}]},{\"t\":1,\"p\":1,\"n\":\"EYES - Eyes\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":2,\"p\":1,\"n\":\"ICON - Texture\"},{\"t\":3,\"p\":1,\"n\":\"DATA - Flags\"}]},{\"t\":1,\"p\":1,\"n\":\"FACT - Faction\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Relations\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"XNAM - Relation\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Faction\"},{\"t\":3,\"p\":1,\"n\":\"Modifier\"},{\"t\":3,\"p\":1,\"n\":\"Group Combat Reaction\"}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DATA - Flags\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Flags\"}]},{\"t\":3,\"p\":1,\"n\":\"JAIL - Exterior Jail Marker\"},{\"t\":3,\"p\":1,\"n\":\"WAIT - Follower Wait Marker\"},{\"t\":3,\"p\":1,\"n\":\"STOL - Stolen Goods Container\"},{\"t\":3,\"p\":1,\"n\":\"PLCN - Player Inventory Container\"},{\"t\":3,\"p\":1,\"n\":\"CRGR - Shared Crime Faction List\"},{\"t\":3,\"p\":1,\"n\":\"JOUT - Jail Outfit\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"CRVA - Crime Values\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Arrest\"},{\"t\":3,\"p\":1,\"n\":\"Attack On Sight\"},{\"t\":3,\"p\":1,\"n\":\"Murder\"},{\"t\":3,\"p\":1,\"n\":\"Assault\"},{\"t\":3,\"p\":1,\"n\":\"Trespass\"},{\"t\":3,\"p\":1,\"n\":\"Pickpocket\"},{\"t\":3,\"n\":\"Unknown\"},{\"t\":5,\"p\":1,\"n\":\"Steal Multiplier\"},{\"t\":3,\"p\":1,\"n\":\"Escape\"},{\"t\":3,\"p\":1,\"n\":\"Werewolf\"}]},{\"t\":10,\"p\":1,\"n\":\"Ranks\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Rank\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"RNAM - Rank#\"},{\"t\":2,\"p\":1,\"n\":\"MNAM - Male Title\"},{\"t\":2,\"p\":1,\"n\":\"FNAM - Female Title\"},{\"t\":2,\"n\":\"INAM - Insignia Unused\"}]}]},{\"t\":3,\"p\":1,\"n\":\"VEND - Vendor Buy\\/Sell List\"},{\"t\":3,\"p\":1,\"n\":\"VENC - Merchant Container\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"VENV - Vendor Values\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Start Hour\"},{\"t\":3,\"p\":1,\"n\":\"End Hour\"},{\"t\":3,\"p\":1,\"n\":\"Radius\"},{\"t\":11,\"n\":\"Unknown 1\"},{\"t\":3,\"p\":1,\"n\":\"Only Buys Stolen Items\"},{\"t\":3,\"p\":1,\"n\":\"Not\\/Sell Buy\"},{\"t\":11,\"n\":\"Unknown 2\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"PLVD - Location\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":3,\"p\":1,\"n\":\"Cell\"},{\"t\":11,\"p\":1,\"n\":\"Near Package Start Location\"},{\"t\":11,\"p\":1,\"n\":\"Near Editor Location\"},{\"t\":3,\"p\":1,\"n\":\"Object ID\"},{\"t\":3,\"p\":1,\"n\":\"Object Type\"},{\"t\":3,\"p\":1,\"n\":\"Keyword\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":3,\"p\":1,\"n\":\"Radius\"}]},{\"t\":3,\"n\":\"CITC - Condition Count\"},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Conditions\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Condition\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"CTDA - \",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":5,\"p\":1,\"n\":\"Comparison Value - Float\"},{\"t\":3,\"p\":1,\"n\":\"Comparison Value - Global\"},{\"t\":3,\"p\":1,\"n\":\"Function\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":11,\"p\":1,\"n\":\"None\"},{\"t\":3,\"p\":1,\"n\":\"Integer\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":11,\"p\":1,\"n\":\"Variable Name (unused)\"},{\"t\":3,\"p\":1,\"n\":\"Sex\"},{\"t\":3,\"p\":1,\"n\":\"Actor Value\"},{\"t\":3,\"p\":1,\"n\":\"Crime Type\"},{\"t\":3,\"p\":1,\"n\":\"Axis\"},{\"t\":3,\"p\":1,\"n\":\"Quest Stage (unused)\"},{\"t\":3,\"p\":1,\"n\":\"Misc Stat\"},{\"t\":3,\"p\":1,\"n\":\"Alignment\"},{\"t\":3,\"p\":1,\"n\":\"Equip Type\"},{\"t\":3,\"p\":1,\"n\":\"Form Type\"},{\"t\":3,\"p\":1,\"n\":\"Critical Stage\"},{\"t\":3,\"p\":1,\"n\":\"Object Reference\"},{\"t\":3,\"p\":1,\"n\":\"Inventory Object\"},{\"t\":3,\"p\":1,\"n\":\"Actor\"},{\"t\":3,\"p\":1,\"n\":\"Voice Type\"},{\"t\":3,\"p\":1,\"n\":\"Idle\"},{\"t\":3,\"p\":1,\"n\":\"Form List\"},{\"t\":3,\"p\":1,\"n\":\"Quest\"},{\"t\":3,\"p\":1,\"n\":\"Faction\"},{\"t\":3,\"p\":1,\"n\":\"Cell\"},{\"t\":3,\"p\":1,\"n\":\"Class\"},{\"t\":3,\"p\":1,\"n\":\"Race\"},{\"t\":3,\"p\":1,\"n\":\"Actor Base\"},{\"t\":3,\"p\":1,\"n\":\"Global\"},{\"t\":3,\"p\":1,\"n\":\"Weather\"},{\"t\":3,\"p\":1,\"n\":\"Package\"},{\"t\":3,\"p\":1,\"n\":\"Encounter Zone\"},{\"t\":3,\"p\":1,\"n\":\"Perk\"},{\"t\":3,\"p\":1,\"n\":\"Owner\"},{\"t\":3,\"p\":1,\"n\":\"Furniture\"},{\"t\":3,\"p\":1,\"n\":\"Effect Item\"},{\"t\":3,\"p\":1,\"n\":\"Base Effect\"},{\"t\":3,\"p\":1,\"n\":\"Worldspace\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Function\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Param (INVALID)\"},{\"t\":3,\"p\":1,\"n\":\"Referenceable Object\"},{\"t\":3,\"p\":1,\"n\":\"Region\"},{\"t\":3,\"p\":1,\"n\":\"Keyword\"},{\"t\":3,\"p\":1,\"n\":\"Player Action\"},{\"t\":3,\"p\":1,\"n\":\"Casting Type\"},{\"t\":3,\"p\":1,\"n\":\"Shout\"},{\"t\":3,\"p\":1,\"n\":\"Location\"},{\"t\":3,\"p\":1,\"n\":\"Location Ref Type\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"Packdata ID\"},{\"t\":3,\"p\":1,\"n\":\"Association Type\"},{\"t\":3,\"p\":1,\"n\":\"Furniture Anim\"},{\"t\":3,\"p\":1,\"n\":\"Furniture Entry\"},{\"t\":3,\"p\":1,\"n\":\"Scene\"},{\"t\":3,\"p\":1,\"n\":\"Ward State\"},{\"t\":3,\"p\":1,\"n\":\"Event\"},{\"t\":3,\"p\":1,\"n\":\"Event Data\"},{\"t\":3,\"p\":1,\"n\":\"Quest Stage\"},{\"t\":3,\"p\":1,\"n\":\"Weapon\"},{\"t\":3,\"p\":1,\"n\":\"Weapon List\"},{\"t\":3,\"p\":1,\"n\":\"Target\"},{\"t\":3,\"p\":1,\"n\":\"Target List\"},{\"t\":3,\"p\":1,\"n\":\"Target Part\"},{\"t\":3,\"p\":1,\"n\":\"VATS Action\"},{\"t\":3,\"p\":1,\"n\":\"Critical Effect\"},{\"t\":3,\"p\":1,\"n\":\"Critical Effect List\"},{\"t\":3,\"p\":1,\"n\":\"Weapon Type\"},{\"t\":3,\"p\":1,\"n\":\"Projectile Type\"},{\"t\":3,\"p\":1,\"n\":\"Delivery Type\"},{\"t\":3,\"p\":1,\"n\":\"Run On\"},{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":3,\"p\":1,\"n\":\"Parameter #3\"}]},{\"t\":2,\"p\":1,\"n\":\"CIS1 - Parameter #1\"},{\"t\":2,\"p\":1,\"n\":\"CIS2 - Parameter #2\"}]}]}]},{\"t\":1,\"p\":1,\"n\":\"FLOR - Flora\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"VMAD - Virtual Machine Adapter\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Version\"},{\"t\":3,\"p\":1,\"n\":\"Object Format\"},{\"t\":7,\"p\":1,\"n\":\"Scripts\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Script\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"scriptName\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":7,\"p\":1,\"n\":\"Properties\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Property\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"propertyName\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]},{\"t\":2,\"p\":1,\"n\":\"String\"},{\"t\":3,\"p\":1,\"n\":\"Int32\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":3,\"p\":1,\"n\":\"Bool\"},{\"t\":7,\"p\":1,\"n\":\"Array of Object\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]}]},{\"t\":7,\"p\":1,\"n\":\"Array of String\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Int32\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Float\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Bool\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]}]}]}]}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"X1\"},{\"t\":3,\"p\":1,\"n\":\"Y1\"},{\"t\":3,\"p\":1,\"n\":\"Z1\"},{\"t\":3,\"p\":1,\"n\":\"X2\"},{\"t\":3,\"p\":1,\"n\":\"Y2\"},{\"t\":3,\"p\":1,\"n\":\"Z2\"}]},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"MODT - Texture Files Hashes\"},{\"t\":7,\"p\":1,\"n\":\"MODS - Alternate Textures\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"3D Name\"},{\"t\":3,\"p\":1,\"n\":\"New Texture\"},{\"t\":3,\"p\":1,\"n\":\"3D Index\"}]}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Destructable\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"DEST - Header\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Health\"},{\"t\":3,\"p\":1,\"n\":\"DEST Count\"},{\"t\":3,\"p\":1,\"n\":\"VATS Targetable\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":8,\"p\":1,\"n\":\"Stages\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Stage\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"DSTD - Destruction Stage Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Health %\"},{\"t\":3,\"p\":1,\"n\":\"Index\"},{\"t\":3,\"p\":1,\"n\":\"Model Damage Stage\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":3,\"p\":1,\"n\":\"Self Damage per Second\"},{\"t\":3,\"p\":1,\"n\":\"Explosion\"},{\"t\":3,\"p\":1,\"n\":\"Debris\"},{\"t\":3,\"p\":1,\"n\":\"Debris Count\"}]},{\"t\":6,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"DMDL - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"DMDT - Texture Files Hashes\"},{\"t\":7,\"p\":1,\"n\":\"DMDS - Alternate Textures\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"3D Name\"},{\"t\":3,\"p\":1,\"n\":\"New Texture\"},{\"t\":3,\"p\":1,\"n\":\"3D Index\"}]}]}]},{\"p\":1,\"n\":\"DSTF - End Marker\"}]}]}]},{\"t\":3,\"n\":\"KSIZ - Keyword Count\"},{\"t\":7,\"p\":1,\"n\":\"KWDA - Keywords\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Keyword\"}]},{\"t\":11,\"n\":\"PNAM - Unknown\"},{\"t\":2,\"p\":1,\"n\":\"RNAM - Activate Text Override\"},{\"t\":11,\"n\":\"FNAM - Unknown\"},{\"t\":3,\"p\":1,\"n\":\"PFIG - Ingredient\"},{\"t\":3,\"p\":1,\"n\":\"SNAM - Sound\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"PFPC - Seasonal ingredient production\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Spring\"},{\"t\":3,\"p\":1,\"n\":\"Summer \"},{\"t\":3,\"p\":1,\"n\":\"Fall\"},{\"t\":3,\"p\":1,\"n\":\"Winter\"}]}]},{\"t\":1,\"p\":1,\"n\":\"FLST - FormID List\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"FormIDs\",\"d\":1,\"c\":[{\"t\":3,\"p\":1,\"n\":\"LNAM - FormID\"}]}]},{\"t\":1,\"p\":1,\"n\":\"FSTP - Footstep\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":3,\"p\":1,\"n\":\"DATA - Impact Data Set\"},{\"t\":2,\"p\":1,\"n\":\"ANAM - Tag\"}]},{\"t\":1,\"p\":1,\"n\":\"FSTS - Footstep Set\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"XCNT - Count\",\"c\":[{\"t\":3,\"n\":\"Walk Forward Sets\"},{\"t\":3,\"n\":\"Run Forward Sets\"},{\"t\":3,\"n\":\"Walk Forward Alternate Sets\"},{\"t\":3,\"n\":\"Run Forward Alternate Sets\"},{\"t\":3,\"n\":\"Walk Forward Alternate 2 Sets\"}]},{\"t\":7,\"s\":1,\"p\":1,\"n\":\"DATA - Footstep Sets\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Footstep\"}]}]},{\"t\":1,\"p\":1,\"n\":\"FURN - Furniture\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"VMAD - Virtual Machine Adapter\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Version\"},{\"t\":3,\"p\":1,\"n\":\"Object Format\"},{\"t\":7,\"p\":1,\"n\":\"Scripts\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Script\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"scriptName\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":7,\"p\":1,\"n\":\"Properties\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Property\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"propertyName\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]},{\"t\":2,\"p\":1,\"n\":\"String\"},{\"t\":3,\"p\":1,\"n\":\"Int32\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":3,\"p\":1,\"n\":\"Bool\"},{\"t\":7,\"p\":1,\"n\":\"Array of Object\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]}]},{\"t\":7,\"p\":1,\"n\":\"Array of String\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Int32\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Float\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Bool\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]}]}]}]}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"X1\"},{\"t\":3,\"p\":1,\"n\":\"Y1\"},{\"t\":3,\"p\":1,\"n\":\"Z1\"},{\"t\":3,\"p\":1,\"n\":\"X2\"},{\"t\":3,\"p\":1,\"n\":\"Y2\"},{\"t\":3,\"p\":1,\"n\":\"Z2\"}]},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"MODT - Texture Files Hashes\"},{\"t\":7,\"p\":1,\"n\":\"MODS - Alternate Textures\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"3D Name\"},{\"t\":3,\"p\":1,\"n\":\"New Texture\"},{\"t\":3,\"p\":1,\"n\":\"3D Index\"}]}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Destructable\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"DEST - Header\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Health\"},{\"t\":3,\"p\":1,\"n\":\"DEST Count\"},{\"t\":3,\"p\":1,\"n\":\"VATS Targetable\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":8,\"p\":1,\"n\":\"Stages\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Stage\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"DSTD - Destruction Stage Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Health %\"},{\"t\":3,\"p\":1,\"n\":\"Index\"},{\"t\":3,\"p\":1,\"n\":\"Model Damage Stage\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":3,\"p\":1,\"n\":\"Self Damage per Second\"},{\"t\":3,\"p\":1,\"n\":\"Explosion\"},{\"t\":3,\"p\":1,\"n\":\"Debris\"},{\"t\":3,\"p\":1,\"n\":\"Debris Count\"}]},{\"t\":6,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"DMDL - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"DMDT - Texture Files Hashes\"},{\"t\":7,\"p\":1,\"n\":\"DMDS - Alternate Textures\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"3D Name\"},{\"t\":3,\"p\":1,\"n\":\"New Texture\"},{\"t\":3,\"p\":1,\"n\":\"3D Index\"}]}]}]},{\"p\":1,\"n\":\"DSTF - End Marker\"}]}]}]},{\"t\":3,\"n\":\"KSIZ - Keyword Count\"},{\"t\":7,\"p\":1,\"n\":\"KWDA - Keywords\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Keyword\"}]},{\"t\":11,\"n\":\"PNAM - Unknown\"},{\"t\":3,\"p\":1,\"n\":\"FNAM - Flags\"},{\"t\":3,\"p\":1,\"n\":\"KNAM - Interaction Keyword\"},{\"t\":3,\"p\":1,\"n\":\"MNAM - Active Markers \\/ Flags\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"WBDT - Workbench Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Bench Type\"},{\"t\":3,\"p\":1,\"n\":\"Uses Skill\"}]},{\"t\":3,\"p\":1,\"n\":\"NAM1 - Associated Spell\"},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Markers\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Marker\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"ENAM - Marker Index\"},{\"t\":6,\"p\":1,\"n\":\"NAM0 - Disabled Entry Points\",\"c\":[{\"t\":11,\"n\":\"Unknown\"},{\"t\":3,\"p\":1,\"n\":\"Disabled Points\"}]},{\"t\":3,\"p\":1,\"n\":\"FNMK - Marker Keyword\"}]}]},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Marker Entry Points\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"FNPR - Marker\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Entry Points\"}]}]},{\"t\":2,\"p\":1,\"n\":\"XMRK - Model Filename\"}]},{\"t\":1,\"p\":1,\"n\":\"GLOB - Global\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":3,\"p\":1,\"n\":\"FNAM - Type\"},{\"t\":5,\"p\":1,\"n\":\"FLTV - Value\"}]},{\"t\":1,\"p\":1,\"n\":\"GMST - Game Setting\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"p\":1,\"n\":\"Name\"},{\"t\":3,\"p\":1,\"n\":\"Int\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":3,\"p\":1,\"n\":\"Bool\"}]},{\"t\":1,\"p\":1,\"n\":\"GRAS - Grass\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"X1\"},{\"t\":3,\"p\":1,\"n\":\"Y1\"},{\"t\":3,\"p\":1,\"n\":\"Z1\"},{\"t\":3,\"p\":1,\"n\":\"X2\"},{\"t\":3,\"p\":1,\"n\":\"Y2\"},{\"t\":3,\"p\":1,\"n\":\"Z2\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"MODT - Texture Files Hashes\"},{\"t\":7,\"p\":1,\"n\":\"MODS - Alternate Textures\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"3D Name\"},{\"t\":3,\"p\":1,\"n\":\"New Texture\"},{\"t\":3,\"p\":1,\"n\":\"3D Index\"}]}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DATA - \",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Density\"},{\"t\":3,\"p\":1,\"n\":\"Min Slope\"},{\"t\":3,\"p\":1,\"n\":\"Max Slope\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":3,\"p\":1,\"n\":\"Units From Water\"},{\"t\":3,\"p\":1,\"n\":\"Units From Water Type\"},{\"t\":5,\"p\":1,\"n\":\"Position Range\"},{\"t\":5,\"p\":1,\"n\":\"Height Range\"},{\"t\":5,\"p\":1,\"n\":\"Color Range\"},{\"t\":5,\"p\":1,\"n\":\"Wave Period\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"}]}]},{\"t\":1,\"p\":1,\"n\":\"HAIR\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"}]},{\"t\":1,\"p\":1,\"n\":\"HAZD - Hazard\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"X1\"},{\"t\":3,\"p\":1,\"n\":\"Y1\"},{\"t\":3,\"p\":1,\"n\":\"Z1\"},{\"t\":3,\"p\":1,\"n\":\"X2\"},{\"t\":3,\"p\":1,\"n\":\"Y2\"},{\"t\":3,\"p\":1,\"n\":\"Z2\"}]},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"MODT - Texture Files Hashes\"},{\"t\":7,\"p\":1,\"n\":\"MODS - Alternate Textures\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"3D Name\"},{\"t\":3,\"p\":1,\"n\":\"New Texture\"},{\"t\":3,\"p\":1,\"n\":\"3D Index\"}]}]}]},{\"t\":3,\"p\":1,\"n\":\"MNAM - Image Space Modifier\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DATA - Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Limit\"},{\"t\":5,\"p\":1,\"n\":\"Radius\"},{\"t\":5,\"p\":1,\"n\":\"Lifetime\"},{\"t\":5,\"p\":1,\"n\":\"Image Space Radius\"},{\"t\":5,\"p\":1,\"n\":\"Target Interval\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":3,\"p\":1,\"n\":\"Spell\"},{\"t\":3,\"p\":1,\"n\":\"Light\"},{\"t\":3,\"p\":1,\"n\":\"Impact Data Set\"},{\"t\":3,\"p\":1,\"n\":\"Sound\"}]}]},{\"t\":1,\"p\":1,\"n\":\"HDPT - Head Part\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"MODT - Texture Files Hashes\"},{\"t\":7,\"p\":1,\"n\":\"MODS - Alternate Textures\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"3D Name\"},{\"t\":3,\"p\":1,\"n\":\"New Texture\"},{\"t\":3,\"p\":1,\"n\":\"3D Index\"}]}]}]},{\"t\":3,\"p\":1,\"n\":\"DATA - Flags\"},{\"t\":3,\"p\":1,\"n\":\"PNAM - Type\"},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Extra Parts\",\"d\":1,\"c\":[{\"t\":3,\"p\":1,\"n\":\"HNAM - Part\"}]},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Parts\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Part\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"NAM0 - Part Type\"},{\"t\":2,\"p\":1,\"n\":\"NAM1 - Filename\"}]}]},{\"t\":3,\"p\":1,\"n\":\"TNAM - Texture Set\"},{\"t\":3,\"p\":1,\"n\":\"CNAM - Color\"},{\"t\":3,\"p\":1,\"n\":\"RNAM - Valid Races\"}]},{\"t\":1,\"n\":\"IDLE - Idle Animation\",\"c\":[{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":8,\"n\":\"Conditions\",\"c\":[{\"t\":6,\"n\":\"Condition\",\"c\":[{\"t\":6,\"n\":\"CTDA - \",\"c\":[{\"t\":3,\"n\":\"Type\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":5,\"n\":\"Comparison Value - Float\"},{\"t\":3,\"n\":\"Comparison Value - Global\"},{\"t\":3,\"n\":\"Function\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":11,\"n\":\"None\"},{\"t\":3,\"n\":\"Integer\"},{\"t\":5,\"n\":\"Float\"},{\"t\":11,\"n\":\"Variable Name (unused)\"},{\"t\":3,\"n\":\"Sex\"},{\"t\":3,\"n\":\"Actor Value\"},{\"t\":3,\"n\":\"Crime Type\"},{\"t\":3,\"n\":\"Axis\"},{\"t\":3,\"n\":\"Quest Stage (unused)\"},{\"t\":3,\"n\":\"Misc Stat\"},{\"t\":3,\"n\":\"Alignment\"},{\"t\":3,\"n\":\"Equip Type\"},{\"t\":3,\"n\":\"Form Type\"},{\"t\":3,\"n\":\"Critical Stage\"},{\"t\":3,\"n\":\"Object Reference\"},{\"t\":3,\"n\":\"Inventory Object\"},{\"t\":3,\"n\":\"Actor\"},{\"t\":3,\"n\":\"Voice Type\"},{\"t\":3,\"n\":\"Idle\"},{\"t\":3,\"n\":\"Form List\"},{\"t\":3,\"n\":\"Quest\"},{\"t\":3,\"n\":\"Faction\"},{\"t\":3,\"n\":\"Cell\"},{\"t\":3,\"n\":\"Class\"},{\"t\":3,\"n\":\"Race\"},{\"t\":3,\"n\":\"Actor Base\"},{\"t\":3,\"n\":\"Global\"},{\"t\":3,\"n\":\"Weather\"},{\"t\":3,\"n\":\"Package\"},{\"t\":3,\"n\":\"Encounter Zone\"},{\"t\":3,\"n\":\"Perk\"},{\"t\":3,\"n\":\"Owner\"},{\"t\":3,\"n\":\"Furniture\"},{\"t\":3,\"n\":\"Effect Item\"},{\"t\":3,\"n\":\"Base Effect\"},{\"t\":3,\"n\":\"Worldspace\"},{\"t\":3,\"n\":\"VATS Value Function\"},{\"t\":3,\"n\":\"VATS Value Param (INVALID)\"},{\"t\":3,\"n\":\"Referenceable Object\"},{\"t\":3,\"n\":\"Region\"},{\"t\":3,\"n\":\"Keyword\"},{\"t\":3,\"n\":\"Player Action\"},{\"t\":3,\"n\":\"Casting Type\"},{\"t\":3,\"n\":\"Shout\"},{\"t\":3,\"n\":\"Location\"},{\"t\":3,\"n\":\"Location Ref Type\"},{\"t\":3,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Packdata ID\"},{\"t\":3,\"n\":\"Association Type\"},{\"t\":3,\"n\":\"Furniture Anim\"},{\"t\":3,\"n\":\"Furniture Entry\"},{\"t\":3,\"n\":\"Scene\"},{\"t\":3,\"n\":\"Ward State\"},{\"t\":3,\"n\":\"Event\"},{\"t\":3,\"n\":\"Event Data\"},{\"t\":3,\"n\":\"Quest Stage\"},{\"t\":3,\"n\":\"Weapon\"},{\"t\":3,\"n\":\"Weapon List\"},{\"t\":3,\"n\":\"Target\"},{\"t\":3,\"n\":\"Target List\"},{\"t\":3,\"n\":\"Target Part\"},{\"t\":3,\"n\":\"VATS Action\"},{\"t\":3,\"n\":\"Critical Effect\"},{\"t\":3,\"n\":\"Critical Effect List\"},{\"t\":3,\"n\":\"Weapon Type\"},{\"t\":3,\"n\":\"Projectile Type\"},{\"t\":3,\"n\":\"Delivery Type\"},{\"t\":3,\"n\":\"Run On\"},{\"t\":3,\"n\":\"Reference\"},{\"t\":3,\"n\":\"Parameter #3\"}]},{\"t\":2,\"n\":\"CIS1 - Parameter #1\"},{\"t\":2,\"n\":\"CIS2 - Parameter #2\"}]}]},{\"t\":2,\"n\":\"DNAM - Filename\"},{\"t\":2,\"n\":\"ENAM - Animation Event\"},{\"t\":7,\"n\":\"ANAM - Related Idle Animations\",\"c\":[{\"t\":3,\"n\":\"Related Idle Animation\"}]},{\"t\":6,\"n\":\"DATA - Data (unused)\",\"c\":[{\"t\":6,\"n\":\"Looping seconds (both 255 forever)\",\"c\":[{\"t\":3,\"n\":\"Min\"},{\"t\":3,\"n\":\"Max\"}]},{\"t\":3,\"n\":\"Flags\"},{\"t\":3,\"n\":\"Animation Group Section\"},{\"t\":3,\"n\":\"Replay Delay\"}]}]},{\"t\":1,\"p\":1,\"n\":\"IDLM - Idle Marker\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"X1\"},{\"t\":3,\"p\":1,\"n\":\"Y1\"},{\"t\":3,\"p\":1,\"n\":\"Z1\"},{\"t\":3,\"p\":1,\"n\":\"X2\"},{\"t\":3,\"p\":1,\"n\":\"Y2\"},{\"t\":3,\"p\":1,\"n\":\"Z2\"}]},{\"t\":3,\"p\":1,\"n\":\"IDLF - Flags\"},{\"t\":3,\"p\":1,\"n\":\"IDLC - Animation Count\"},{\"t\":5,\"p\":1,\"n\":\"IDLT - Idle Timer Setting\"},{\"t\":7,\"p\":1,\"n\":\"IDLA - Animations\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Animation\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"MODT - Texture Files Hashes\"},{\"t\":7,\"p\":1,\"n\":\"MODS - Alternate Textures\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"3D Name\"},{\"t\":3,\"p\":1,\"n\":\"New Texture\"},{\"t\":3,\"p\":1,\"n\":\"3D Index\"}]}]}]}]},{\"t\":1,\"p\":1,\"n\":\"IMAD - Image Space Adapter\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DNAM - Data Count\",\"c\":[{\"t\":3,\"n\":\"Flags\"},{\"t\":5,\"n\":\"Duration\"},{\"t\":6,\"n\":\"HDR\",\"c\":[{\"t\":3,\"n\":\"Eye Adapt Speed Mult\"},{\"t\":3,\"n\":\"Eye Adapt Speed Add\"},{\"t\":3,\"n\":\"Bloom Blur Radius Mult\"},{\"t\":3,\"n\":\"Bloom Blur Radius Add\"},{\"t\":3,\"n\":\"Bloom Threshold Mult\"},{\"t\":3,\"n\":\"Bloom Threshold Add\"},{\"t\":3,\"n\":\"Bloom Scale Mult\"},{\"t\":3,\"n\":\"Bloom Scale Add\"},{\"t\":3,\"n\":\"Target Lum Min Mult\"},{\"t\":3,\"n\":\"Target Lum Min Add\"},{\"t\":3,\"n\":\"Target Lum Max Mult\"},{\"t\":3,\"n\":\"Target Lum Max Add\"},{\"t\":3,\"n\":\"Sunlight Scale Mult\"},{\"t\":3,\"n\":\"Sunlight Scale Add\"},{\"t\":3,\"n\":\"Sky Scale Mult\"},{\"t\":3,\"n\":\"Sky Scale Add\"}]},{\"t\":3,\"n\":\"Unknown08 Mult\"},{\"t\":3,\"n\":\"Unknown48 Add\"},{\"t\":3,\"n\":\"Unknown09 Mult\"},{\"t\":3,\"n\":\"Unknown49 Add\"},{\"t\":3,\"n\":\"Unknown0A Mult\"},{\"t\":3,\"n\":\"Unknown4A Add\"},{\"t\":3,\"n\":\"Unknown0B Mult\"},{\"t\":3,\"n\":\"Unknown4B Add\"},{\"t\":3,\"n\":\"Unknown0C Mult\"},{\"t\":3,\"n\":\"Unknown4C Add\"},{\"t\":3,\"n\":\"Unknown0D Mult\"},{\"t\":3,\"n\":\"Unknown4D Add\"},{\"t\":3,\"n\":\"Unknown0E Mult\"},{\"t\":3,\"n\":\"Unknown4E Add\"},{\"t\":3,\"n\":\"Unknown0F Mult\"},{\"t\":3,\"n\":\"Unknown4F Add\"},{\"t\":3,\"n\":\"Unknown10 Mult\"},{\"t\":3,\"n\":\"Unknown50 Add\"},{\"t\":6,\"n\":\"Cinematic\",\"c\":[{\"t\":3,\"n\":\"Saturation Mult\"},{\"t\":3,\"n\":\"Saturation Add\"},{\"t\":3,\"n\":\"Brightness Mult\"},{\"t\":3,\"n\":\"Brightness Add\"},{\"t\":3,\"n\":\"Contrast Mult\"},{\"t\":3,\"n\":\"Contrast Add\"}]},{\"t\":3,\"n\":\"Unknown14 Mult\"},{\"t\":3,\"n\":\"Unknown54 Add\"},{\"t\":3,\"n\":\"Tint Color\"},{\"t\":3,\"n\":\"Blur Radius\"},{\"t\":3,\"n\":\"Double Vision Strength\"},{\"t\":3,\"n\":\"Radial Blur Strength\"},{\"t\":3,\"n\":\"Radial Blur Ramp Up\"},{\"t\":3,\"n\":\"Radial Blur Start\"},{\"t\":3,\"n\":\"Radial Blur Flags\"},{\"t\":5,\"n\":\"Radial Blur Center X\"},{\"t\":5,\"n\":\"Radial Blur Center Y\"},{\"t\":3,\"n\":\"DoF Strength\"},{\"t\":3,\"n\":\"DoF Distance\"},{\"t\":3,\"n\":\"DoF Range\"},{\"t\":3,\"n\":\"DoF Flags\"},{\"t\":3,\"n\":\"Radial Blur Ramp Down\"},{\"t\":3,\"n\":\"Radial Blur Down Start\"},{\"t\":3,\"n\":\"Fade Color\"},{\"t\":3,\"n\":\"Motion Blur Strength\"}]},{\"t\":7,\"p\":1,\"n\":\"BNAM - Blur Radius\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Data\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Time\"},{\"t\":5,\"p\":1,\"n\":\"Value\"}]}]},{\"t\":7,\"p\":1,\"n\":\"VNAM - Double Vision Strength\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Data\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Time\"},{\"t\":5,\"p\":1,\"n\":\"Value\"}]}]},{\"t\":7,\"p\":1,\"n\":\"TNAM - Tint Color\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Data\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Time\"},{\"t\":5,\"p\":1,\"n\":\"Red\"},{\"t\":5,\"p\":1,\"n\":\"Green\"},{\"t\":5,\"p\":1,\"n\":\"Blue\"},{\"t\":5,\"p\":1,\"n\":\"Alpha\"}]}]},{\"t\":7,\"p\":1,\"n\":\"NAM3 - Fade Color\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Data\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Time\"},{\"t\":5,\"p\":1,\"n\":\"Red\"},{\"t\":5,\"p\":1,\"n\":\"Green\"},{\"t\":5,\"p\":1,\"n\":\"Blue\"},{\"t\":5,\"p\":1,\"n\":\"Alpha\"}]}]},{\"t\":7,\"p\":1,\"n\":\"RNAM - Radial Blur Strength\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Data\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Time\"},{\"t\":5,\"p\":1,\"n\":\"Value\"}]}]},{\"t\":7,\"p\":1,\"n\":\"SNAM - Radial Blur Ramp Up\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Data\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Time\"},{\"t\":5,\"p\":1,\"n\":\"Value\"}]}]},{\"t\":7,\"p\":1,\"n\":\"UNAM - Radial Blur Start\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Data\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Time\"},{\"t\":5,\"p\":1,\"n\":\"Value\"}]}]},{\"t\":7,\"p\":1,\"n\":\"NAM1 - Radial Blur Ramp Down\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Data\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Time\"},{\"t\":5,\"p\":1,\"n\":\"Value\"}]}]},{\"t\":7,\"p\":1,\"n\":\"NAM2 - Radial Blur Down Start\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Data\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Time\"},{\"t\":5,\"p\":1,\"n\":\"Value\"}]}]},{\"t\":7,\"p\":1,\"n\":\"WNAM - DoF Strength\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Data\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Time\"},{\"t\":5,\"p\":1,\"n\":\"Value\"}]}]},{\"t\":7,\"p\":1,\"n\":\"XNAM - DoF Distance\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Data\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Time\"},{\"t\":5,\"p\":1,\"n\":\"Value\"}]}]},{\"t\":7,\"p\":1,\"n\":\"YNAM - DoF Range\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Data\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Time\"},{\"t\":5,\"p\":1,\"n\":\"Value\"}]}]},{\"t\":7,\"p\":1,\"n\":\"NAM4 - Motion Blur Strength\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Data\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Time\"},{\"t\":5,\"p\":1,\"n\":\"Value\"}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"HDR\",\"c\":[{\"t\":7,\"p\":1,\"n\":\"aIAD - Eye Adapt Speed Mult\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Data\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Time\"},{\"t\":5,\"p\":1,\"n\":\"Value\"}]}]},{\"t\":7,\"p\":1,\"n\":\"@IAD - Eye Adapt Speed Add\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Data\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Time\"},{\"t\":5,\"p\":1,\"n\":\"Value\"}]}]},{\"t\":7,\"p\":1,\"n\":\"bIAD - Bloom Blur Radius Mult\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Data\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Time\"},{\"t\":5,\"p\":1,\"n\":\"Value\"}]}]},{\"t\":7,\"p\":1,\"n\":\"AIAD - Bloom Blur Radius Add\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Data\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Time\"},{\"t\":5,\"p\":1,\"n\":\"Value\"}]}]},{\"t\":7,\"p\":1,\"n\":\"cIAD - Bloom Threshold Mult\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Data\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Time\"},{\"t\":5,\"p\":1,\"n\":\"Value\"}]}]},{\"t\":7,\"p\":1,\"n\":\"BIAD - Bloom Threshold Add\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Data\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Time\"},{\"t\":5,\"p\":1,\"n\":\"Value\"}]}]},{\"t\":7,\"p\":1,\"n\":\"dIAD - Bloom Scale Mult\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Data\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Time\"},{\"t\":5,\"p\":1,\"n\":\"Value\"}]}]},{\"t\":7,\"p\":1,\"n\":\"CIAD - Bloom Scale Add\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Data\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Time\"},{\"t\":5,\"p\":1,\"n\":\"Value\"}]}]},{\"t\":7,\"p\":1,\"n\":\"eIAD - Target Lum Min Mult\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Data\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Time\"},{\"t\":5,\"p\":1,\"n\":\"Value\"}]}]},{\"t\":7,\"p\":1,\"n\":\"DIAD - Target Lum Min Add\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Data\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Time\"},{\"t\":5,\"p\":1,\"n\":\"Value\"}]}]},{\"t\":7,\"p\":1,\"n\":\"fIAD - Target Lum Max Mult\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Data\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Time\"},{\"t\":5,\"p\":1,\"n\":\"Value\"}]}]},{\"t\":7,\"p\":1,\"n\":\"EIAD - Target Lum Max Add\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Data\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Time\"},{\"t\":5,\"p\":1,\"n\":\"Value\"}]}]},{\"t\":7,\"p\":1,\"n\":\"gIAD - Sunlight Scale Mult\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Data\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Time\"},{\"t\":5,\"p\":1,\"n\":\"Value\"}]}]},{\"t\":7,\"p\":1,\"n\":\"FIAD - Sunlight Scale Add\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Data\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Time\"},{\"t\":5,\"p\":1,\"n\":\"Value\"}]}]},{\"t\":7,\"p\":1,\"n\":\"hIAD - Sky Scale Mult\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Data\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Time\"},{\"t\":5,\"p\":1,\"n\":\"Value\"}]}]},{\"t\":7,\"p\":1,\"n\":\"GIAD - Sky Scale Add\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Data\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Time\"},{\"t\":5,\"p\":1,\"n\":\"Value\"}]}]}]},{\"t\":11,\"n\":\"iIAD - Unknown\"},{\"t\":11,\"n\":\"HIAD - Unknown\"},{\"t\":11,\"n\":\"jIAD - Unknown\"},{\"t\":11,\"n\":\"IIAD - Unknown\"},{\"t\":11,\"n\":\"kIAD - Unknown\"},{\"t\":11,\"n\":\"JIAD - Unknown\"},{\"t\":11,\"n\":\"lIAD - Unknown\"},{\"t\":11,\"n\":\"KIAD - Unknown\"},{\"t\":11,\"n\":\"mIAD - Unknown\"},{\"t\":11,\"n\":\"LIAD - Unknown\"},{\"t\":11,\"n\":\"nIAD - Unknown\"},{\"t\":11,\"n\":\"MIAD - Unknown\"},{\"t\":11,\"n\":\"oIAD - Unknown\"},{\"t\":11,\"n\":\"NIAD - Unknown\"},{\"t\":11,\"n\":\"pIAD - Unknown\"},{\"t\":11,\"n\":\"OIAD - Unknown\"},{\"t\":11,\"n\":\"qIAD - Unknown\"},{\"t\":11,\"n\":\"PIAD - Unknown\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Cinematic\",\"c\":[{\"t\":7,\"p\":1,\"n\":\"rIAD - Saturation Mult\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Data\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Time\"},{\"t\":5,\"p\":1,\"n\":\"Value\"}]}]},{\"t\":7,\"p\":1,\"n\":\"QIAD - Saturation Add\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Data\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Time\"},{\"t\":5,\"p\":1,\"n\":\"Value\"}]}]},{\"t\":7,\"p\":1,\"n\":\"sIAD - Brightness Mult\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Data\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Time\"},{\"t\":5,\"p\":1,\"n\":\"Value\"}]}]},{\"t\":7,\"p\":1,\"n\":\"RIAD - Brightness Add\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Data\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Time\"},{\"t\":5,\"p\":1,\"n\":\"Value\"}]}]},{\"t\":7,\"p\":1,\"n\":\"tIAD - Contrast Mult\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Data\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Time\"},{\"t\":5,\"p\":1,\"n\":\"Value\"}]}]},{\"t\":7,\"p\":1,\"n\":\"SIAD - Contrast Add\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Data\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Time\"},{\"t\":5,\"p\":1,\"n\":\"Value\"}]}]}]},{\"t\":11,\"n\":\"uIAD - Unknown\"},{\"t\":11,\"n\":\"TIAD - Unknown\"}]},{\"t\":1,\"p\":1,\"n\":\"IMGS - Image Space\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":11,\"n\":\"ENAM - Unknown\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"HNAM - HDR\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Eye Adapt Speed\"},{\"t\":5,\"p\":1,\"n\":\"Bloom Blur Radius\"},{\"t\":5,\"p\":1,\"n\":\"Bloom Threshold\"},{\"t\":5,\"p\":1,\"n\":\"Bloom Scale\"},{\"t\":5,\"p\":1,\"n\":\"Receive Bloom Threshold\"},{\"t\":5,\"p\":1,\"n\":\"White\"},{\"t\":5,\"p\":1,\"n\":\"Sunlight Scale\"},{\"t\":5,\"p\":1,\"n\":\"Sky Scale\"},{\"t\":5,\"p\":1,\"n\":\"Eye Adapt Strength\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"CNAM - Cinematic\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Saturation\"},{\"t\":5,\"p\":1,\"n\":\"Brightness\"},{\"t\":5,\"p\":1,\"n\":\"Contrast\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"TNAM - Tint\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Amount\"},{\"t\":6,\"p\":1,\"n\":\"Color\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Red\"},{\"t\":5,\"p\":1,\"n\":\"Green\"},{\"t\":5,\"p\":1,\"n\":\"Blue\"}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DNAM - Depth of Field\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Strength\"},{\"t\":5,\"p\":1,\"n\":\"Distance\"},{\"t\":5,\"p\":1,\"n\":\"Range\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":3,\"p\":1,\"n\":\"Sky \\/ Blur Radius\"}]}]},{\"t\":1,\"p\":1,\"n\":\"INFO - Dialog response\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"VMAD - Virtual Machine Adapter\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Version\"},{\"t\":3,\"p\":1,\"n\":\"Object Format\"},{\"t\":7,\"p\":1,\"n\":\"Scripts\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Script\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"scriptName\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":7,\"p\":1,\"n\":\"Properties\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Property\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"propertyName\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]},{\"t\":2,\"p\":1,\"n\":\"String\"},{\"t\":3,\"p\":1,\"n\":\"Int32\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":3,\"p\":1,\"n\":\"Bool\"},{\"t\":7,\"p\":1,\"n\":\"Array of Object\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]}]},{\"t\":7,\"p\":1,\"n\":\"Array of String\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Int32\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Float\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Bool\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]}]}]}]}]},{\"t\":6,\"p\":1,\"n\":\"Script Fragments\",\"c\":[{\"t\":3,\"n\":\"Unknown\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":2,\"p\":1,\"n\":\"fileName\"},{\"t\":7,\"p\":1,\"n\":\"Fragments\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Fragment\",\"c\":[{\"t\":3,\"n\":\"Unknown\"},{\"t\":2,\"p\":1,\"n\":\"scriptName\"},{\"t\":2,\"p\":1,\"n\":\"fragmentName\"}]}]}]}]},{\"t\":11,\"n\":\"DATA - Unknown\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"ENAM - Response flags\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":3,\"p\":1,\"n\":\"Reset Hours\"}]},{\"t\":3,\"p\":1,\"n\":\"TPIC - Topic\"},{\"t\":3,\"p\":1,\"n\":\"PNAM - Previous INFO\"},{\"t\":3,\"p\":1,\"n\":\"CNAM - Favor Level\"},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Link To\",\"d\":1,\"c\":[{\"t\":3,\"p\":1,\"n\":\"TCLT - Response\"}]},{\"t\":3,\"p\":1,\"n\":\"DNAM - Response Data\"},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Responses\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Response\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"TRDT - Response Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Emotion Type\"},{\"t\":3,\"p\":1,\"n\":\"Emotion Value\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Response number\"},{\"t\":3,\"p\":1,\"n\":\"Sound\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"}]},{\"t\":2,\"p\":1,\"n\":\"NAM1 - Response Text\"},{\"t\":2,\"p\":1,\"n\":\"NAM2 - Script Notes\"},{\"t\":2,\"p\":1,\"n\":\"NAM3 - Edits\"},{\"t\":3,\"p\":1,\"n\":\"SNAM - Idle Animations: Speaker\"},{\"t\":3,\"p\":1,\"n\":\"LNAM - Idle Animations: Listener\"}]}]},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Conditions\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Condition\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"CTDA - \",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":5,\"p\":1,\"n\":\"Comparison Value - Float\"},{\"t\":3,\"p\":1,\"n\":\"Comparison Value - Global\"},{\"t\":3,\"p\":1,\"n\":\"Function\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":11,\"p\":1,\"n\":\"None\"},{\"t\":3,\"p\":1,\"n\":\"Integer\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":11,\"p\":1,\"n\":\"Variable Name (unused)\"},{\"t\":3,\"p\":1,\"n\":\"Sex\"},{\"t\":3,\"p\":1,\"n\":\"Actor Value\"},{\"t\":3,\"p\":1,\"n\":\"Crime Type\"},{\"t\":3,\"p\":1,\"n\":\"Axis\"},{\"t\":3,\"p\":1,\"n\":\"Quest Stage (unused)\"},{\"t\":3,\"p\":1,\"n\":\"Misc Stat\"},{\"t\":3,\"p\":1,\"n\":\"Alignment\"},{\"t\":3,\"p\":1,\"n\":\"Equip Type\"},{\"t\":3,\"p\":1,\"n\":\"Form Type\"},{\"t\":3,\"p\":1,\"n\":\"Critical Stage\"},{\"t\":3,\"p\":1,\"n\":\"Object Reference\"},{\"t\":3,\"p\":1,\"n\":\"Inventory Object\"},{\"t\":3,\"p\":1,\"n\":\"Actor\"},{\"t\":3,\"p\":1,\"n\":\"Voice Type\"},{\"t\":3,\"p\":1,\"n\":\"Idle\"},{\"t\":3,\"p\":1,\"n\":\"Form List\"},{\"t\":3,\"p\":1,\"n\":\"Quest\"},{\"t\":3,\"p\":1,\"n\":\"Faction\"},{\"t\":3,\"p\":1,\"n\":\"Cell\"},{\"t\":3,\"p\":1,\"n\":\"Class\"},{\"t\":3,\"p\":1,\"n\":\"Race\"},{\"t\":3,\"p\":1,\"n\":\"Actor Base\"},{\"t\":3,\"p\":1,\"n\":\"Global\"},{\"t\":3,\"p\":1,\"n\":\"Weather\"},{\"t\":3,\"p\":1,\"n\":\"Package\"},{\"t\":3,\"p\":1,\"n\":\"Encounter Zone\"},{\"t\":3,\"p\":1,\"n\":\"Perk\"},{\"t\":3,\"p\":1,\"n\":\"Owner\"},{\"t\":3,\"p\":1,\"n\":\"Furniture\"},{\"t\":3,\"p\":1,\"n\":\"Effect Item\"},{\"t\":3,\"p\":1,\"n\":\"Base Effect\"},{\"t\":3,\"p\":1,\"n\":\"Worldspace\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Function\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Param (INVALID)\"},{\"t\":3,\"p\":1,\"n\":\"Referenceable Object\"},{\"t\":3,\"p\":1,\"n\":\"Region\"},{\"t\":3,\"p\":1,\"n\":\"Keyword\"},{\"t\":3,\"p\":1,\"n\":\"Player Action\"},{\"t\":3,\"p\":1,\"n\":\"Casting Type\"},{\"t\":3,\"p\":1,\"n\":\"Shout\"},{\"t\":3,\"p\":1,\"n\":\"Location\"},{\"t\":3,\"p\":1,\"n\":\"Location Ref Type\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"Packdata ID\"},{\"t\":3,\"p\":1,\"n\":\"Association Type\"},{\"t\":3,\"p\":1,\"n\":\"Furniture Anim\"},{\"t\":3,\"p\":1,\"n\":\"Furniture Entry\"},{\"t\":3,\"p\":1,\"n\":\"Scene\"},{\"t\":3,\"p\":1,\"n\":\"Ward State\"},{\"t\":3,\"p\":1,\"n\":\"Event\"},{\"t\":3,\"p\":1,\"n\":\"Event Data\"},{\"t\":3,\"p\":1,\"n\":\"Quest Stage\"},{\"t\":3,\"p\":1,\"n\":\"Weapon\"},{\"t\":3,\"p\":1,\"n\":\"Weapon List\"},{\"t\":3,\"p\":1,\"n\":\"Target\"},{\"t\":3,\"p\":1,\"n\":\"Target List\"},{\"t\":3,\"p\":1,\"n\":\"Target Part\"},{\"t\":3,\"p\":1,\"n\":\"VATS Action\"},{\"t\":3,\"p\":1,\"n\":\"Critical Effect\"},{\"t\":3,\"p\":1,\"n\":\"Critical Effect List\"},{\"t\":3,\"p\":1,\"n\":\"Weapon Type\"},{\"t\":3,\"p\":1,\"n\":\"Projectile Type\"},{\"t\":3,\"p\":1,\"n\":\"Delivery Type\"},{\"t\":3,\"p\":1,\"n\":\"Run On\"},{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":3,\"p\":1,\"n\":\"Parameter #3\"}]},{\"t\":2,\"p\":1,\"n\":\"CIS1 - Parameter #1\"},{\"t\":2,\"p\":1,\"n\":\"CIS2 - Parameter #2\"}]}]},{\"t\":8,\"n\":\"Unknown\",\"c\":[{\"t\":6,\"n\":\"Unknown\",\"c\":[{\"t\":11,\"n\":\"SCHR - Unknown\"},{\"t\":3,\"n\":\"QNAM - Unknown\"},{\"n\":\"NEXT - Marker\"}]}]},{\"t\":2,\"p\":1,\"n\":\"RNAM - Prompt\"},{\"t\":3,\"p\":1,\"n\":\"ANAM - Speaker\"},{\"t\":3,\"p\":1,\"n\":\"TWAT - Walk Away Topic\"},{\"t\":3,\"p\":1,\"n\":\"ONAM - Audio Output Override\"}]},{\"t\":1,\"p\":1,\"n\":\"INGR - Ingredient\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"VMAD - Virtual Machine Adapter\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Version\"},{\"t\":3,\"p\":1,\"n\":\"Object Format\"},{\"t\":7,\"p\":1,\"n\":\"Scripts\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Script\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"scriptName\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":7,\"p\":1,\"n\":\"Properties\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Property\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"propertyName\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]},{\"t\":2,\"p\":1,\"n\":\"String\"},{\"t\":3,\"p\":1,\"n\":\"Int32\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":3,\"p\":1,\"n\":\"Bool\"},{\"t\":7,\"p\":1,\"n\":\"Array of Object\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]}]},{\"t\":7,\"p\":1,\"n\":\"Array of String\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Int32\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Float\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Bool\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]}]}]}]}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"X1\"},{\"t\":3,\"p\":1,\"n\":\"Y1\"},{\"t\":3,\"p\":1,\"n\":\"Z1\"},{\"t\":3,\"p\":1,\"n\":\"X2\"},{\"t\":3,\"p\":1,\"n\":\"Y2\"},{\"t\":3,\"p\":1,\"n\":\"Z2\"}]},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":3,\"n\":\"KSIZ - Keyword Count\"},{\"t\":7,\"p\":1,\"n\":\"KWDA - Keywords\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Keyword\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"MODT - Texture Files Hashes\"},{\"t\":7,\"p\":1,\"n\":\"MODS - Alternate Textures\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"3D Name\"},{\"t\":3,\"p\":1,\"n\":\"New Texture\"},{\"t\":3,\"p\":1,\"n\":\"3D Index\"}]}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Icon\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"ICON - Large Icon filename\"},{\"t\":2,\"p\":1,\"n\":\"MICO - Small Icon filename\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Destructable\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"DEST - Header\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Health\"},{\"t\":3,\"p\":1,\"n\":\"DEST Count\"},{\"t\":3,\"p\":1,\"n\":\"VATS Targetable\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":8,\"p\":1,\"n\":\"Stages\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Stage\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"DSTD - Destruction Stage Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Health %\"},{\"t\":3,\"p\":1,\"n\":\"Index\"},{\"t\":3,\"p\":1,\"n\":\"Model Damage Stage\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":3,\"p\":1,\"n\":\"Self Damage per Second\"},{\"t\":3,\"p\":1,\"n\":\"Explosion\"},{\"t\":3,\"p\":1,\"n\":\"Debris\"},{\"t\":3,\"p\":1,\"n\":\"Debris Count\"}]},{\"t\":6,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"DMDL - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"DMDT - Texture Files Hashes\"},{\"t\":7,\"p\":1,\"n\":\"DMDS - Alternate Textures\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"3D Name\"},{\"t\":3,\"p\":1,\"n\":\"New Texture\"},{\"t\":3,\"p\":1,\"n\":\"3D Index\"}]}]}]},{\"p\":1,\"n\":\"DSTF - End Marker\"}]}]}]},{\"t\":3,\"p\":1,\"n\":\"ETYP - Equipment Type\"},{\"t\":3,\"p\":1,\"n\":\"YNAM - Sound - Pick Up\"},{\"t\":3,\"p\":1,\"n\":\"ZNAM - Sound - Put Down\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DATA - \",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Value\"},{\"t\":5,\"p\":1,\"n\":\"Weight\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"ENIT - Effect Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Ingredient Value\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"}]},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Effects\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Effect\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"EFID - Base Effect\"},{\"t\":6,\"p\":1,\"n\":\"EFIT - \",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Magnitude\"},{\"t\":3,\"p\":1,\"n\":\"Area\"},{\"t\":3,\"p\":1,\"n\":\"Duration\"}]},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Conditions\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Condition\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"CTDA - \",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":5,\"p\":1,\"n\":\"Comparison Value - Float\"},{\"t\":3,\"p\":1,\"n\":\"Comparison Value - Global\"},{\"t\":3,\"p\":1,\"n\":\"Function\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":11,\"p\":1,\"n\":\"None\"},{\"t\":3,\"p\":1,\"n\":\"Integer\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":11,\"p\":1,\"n\":\"Variable Name (unused)\"},{\"t\":3,\"p\":1,\"n\":\"Sex\"},{\"t\":3,\"p\":1,\"n\":\"Actor Value\"},{\"t\":3,\"p\":1,\"n\":\"Crime Type\"},{\"t\":3,\"p\":1,\"n\":\"Axis\"},{\"t\":3,\"p\":1,\"n\":\"Quest Stage (unused)\"},{\"t\":3,\"p\":1,\"n\":\"Misc Stat\"},{\"t\":3,\"p\":1,\"n\":\"Alignment\"},{\"t\":3,\"p\":1,\"n\":\"Equip Type\"},{\"t\":3,\"p\":1,\"n\":\"Form Type\"},{\"t\":3,\"p\":1,\"n\":\"Critical Stage\"},{\"t\":3,\"p\":1,\"n\":\"Object Reference\"},{\"t\":3,\"p\":1,\"n\":\"Inventory Object\"},{\"t\":3,\"p\":1,\"n\":\"Actor\"},{\"t\":3,\"p\":1,\"n\":\"Voice Type\"},{\"t\":3,\"p\":1,\"n\":\"Idle\"},{\"t\":3,\"p\":1,\"n\":\"Form List\"},{\"t\":3,\"p\":1,\"n\":\"Quest\"},{\"t\":3,\"p\":1,\"n\":\"Faction\"},{\"t\":3,\"p\":1,\"n\":\"Cell\"},{\"t\":3,\"p\":1,\"n\":\"Class\"},{\"t\":3,\"p\":1,\"n\":\"Race\"},{\"t\":3,\"p\":1,\"n\":\"Actor Base\"},{\"t\":3,\"p\":1,\"n\":\"Global\"},{\"t\":3,\"p\":1,\"n\":\"Weather\"},{\"t\":3,\"p\":1,\"n\":\"Package\"},{\"t\":3,\"p\":1,\"n\":\"Encounter Zone\"},{\"t\":3,\"p\":1,\"n\":\"Perk\"},{\"t\":3,\"p\":1,\"n\":\"Owner\"},{\"t\":3,\"p\":1,\"n\":\"Furniture\"},{\"t\":3,\"p\":1,\"n\":\"Effect Item\"},{\"t\":3,\"p\":1,\"n\":\"Base Effect\"},{\"t\":3,\"p\":1,\"n\":\"Worldspace\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Function\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Param (INVALID)\"},{\"t\":3,\"p\":1,\"n\":\"Referenceable Object\"},{\"t\":3,\"p\":1,\"n\":\"Region\"},{\"t\":3,\"p\":1,\"n\":\"Keyword\"},{\"t\":3,\"p\":1,\"n\":\"Player Action\"},{\"t\":3,\"p\":1,\"n\":\"Casting Type\"},{\"t\":3,\"p\":1,\"n\":\"Shout\"},{\"t\":3,\"p\":1,\"n\":\"Location\"},{\"t\":3,\"p\":1,\"n\":\"Location Ref Type\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"Packdata ID\"},{\"t\":3,\"p\":1,\"n\":\"Association Type\"},{\"t\":3,\"p\":1,\"n\":\"Furniture Anim\"},{\"t\":3,\"p\":1,\"n\":\"Furniture Entry\"},{\"t\":3,\"p\":1,\"n\":\"Scene\"},{\"t\":3,\"p\":1,\"n\":\"Ward State\"},{\"t\":3,\"p\":1,\"n\":\"Event\"},{\"t\":3,\"p\":1,\"n\":\"Event Data\"},{\"t\":3,\"p\":1,\"n\":\"Quest Stage\"},{\"t\":3,\"p\":1,\"n\":\"Weapon\"},{\"t\":3,\"p\":1,\"n\":\"Weapon List\"},{\"t\":3,\"p\":1,\"n\":\"Target\"},{\"t\":3,\"p\":1,\"n\":\"Target List\"},{\"t\":3,\"p\":1,\"n\":\"Target Part\"},{\"t\":3,\"p\":1,\"n\":\"VATS Action\"},{\"t\":3,\"p\":1,\"n\":\"Critical Effect\"},{\"t\":3,\"p\":1,\"n\":\"Critical Effect List\"},{\"t\":3,\"p\":1,\"n\":\"Weapon Type\"},{\"t\":3,\"p\":1,\"n\":\"Projectile Type\"},{\"t\":3,\"p\":1,\"n\":\"Delivery Type\"},{\"t\":3,\"p\":1,\"n\":\"Run On\"},{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":3,\"p\":1,\"n\":\"Parameter #3\"}]},{\"t\":2,\"p\":1,\"n\":\"CIS1 - Parameter #1\"},{\"t\":2,\"p\":1,\"n\":\"CIS2 - Parameter #2\"}]}]}]}]}]},{\"t\":1,\"p\":1,\"n\":\"IPCT - Impact\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"MODT - Texture Files Hashes\"},{\"t\":7,\"p\":1,\"n\":\"MODS - Alternate Textures\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"3D Name\"},{\"t\":3,\"p\":1,\"n\":\"New Texture\"},{\"t\":3,\"p\":1,\"n\":\"3D Index\"}]}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DATA - \",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Effect - Duration\"},{\"t\":3,\"p\":1,\"n\":\"Effect - Orientation\"},{\"t\":5,\"p\":1,\"n\":\"Angle Threshold\"},{\"t\":5,\"p\":1,\"n\":\"Placement Radius\"},{\"t\":3,\"p\":1,\"n\":\"Sound Level\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":3,\"p\":1,\"n\":\"Impact Result\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DODT - Decal Data\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Min Width\"},{\"t\":5,\"p\":1,\"n\":\"Max Width\"},{\"t\":5,\"p\":1,\"n\":\"Min Height\"},{\"t\":5,\"p\":1,\"n\":\"Max Height\"},{\"t\":5,\"p\":1,\"n\":\"Depth\"},{\"t\":5,\"p\":1,\"n\":\"Shininess\"},{\"t\":6,\"p\":1,\"n\":\"Parallax\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Scale\"},{\"t\":3,\"p\":1,\"n\":\"Passes\"}]},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":6,\"p\":1,\"n\":\"Color\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]}]},{\"t\":3,\"p\":1,\"n\":\"DNAM - Texture Set\"},{\"t\":3,\"p\":1,\"n\":\"ENAM - Secondary Texture Set\"},{\"t\":3,\"p\":1,\"n\":\"SNAM - Sound 1\"},{\"t\":3,\"p\":1,\"n\":\"NAM1 - Sound 2\"},{\"t\":3,\"p\":1,\"n\":\"NAM2 - Hazard\"}]},{\"t\":1,\"p\":1,\"n\":\"IPDS - Impact Data Set\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Data\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"PNAM - \",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Material\"},{\"t\":3,\"p\":1,\"n\":\"Impact\"}]}]}]},{\"t\":1,\"p\":1,\"n\":\"KEYM - Key\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"VMAD - Virtual Machine Adapter\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Version\"},{\"t\":3,\"p\":1,\"n\":\"Object Format\"},{\"t\":7,\"p\":1,\"n\":\"Scripts\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Script\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"scriptName\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":7,\"p\":1,\"n\":\"Properties\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Property\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"propertyName\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]},{\"t\":2,\"p\":1,\"n\":\"String\"},{\"t\":3,\"p\":1,\"n\":\"Int32\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":3,\"p\":1,\"n\":\"Bool\"},{\"t\":7,\"p\":1,\"n\":\"Array of Object\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]}]},{\"t\":7,\"p\":1,\"n\":\"Array of String\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Int32\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Float\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Bool\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]}]}]}]}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"X1\"},{\"t\":3,\"p\":1,\"n\":\"Y1\"},{\"t\":3,\"p\":1,\"n\":\"Z1\"},{\"t\":3,\"p\":1,\"n\":\"X2\"},{\"t\":3,\"p\":1,\"n\":\"Y2\"},{\"t\":3,\"p\":1,\"n\":\"Z2\"}]},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"MODT - Texture Files Hashes\"},{\"t\":7,\"p\":1,\"n\":\"MODS - Alternate Textures\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"3D Name\"},{\"t\":3,\"p\":1,\"n\":\"New Texture\"},{\"t\":3,\"p\":1,\"n\":\"3D Index\"}]}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Icon\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"ICON - Large Icon filename\"},{\"t\":2,\"p\":1,\"n\":\"MICO - Small Icon filename\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Destructable\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"DEST - Header\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Health\"},{\"t\":3,\"p\":1,\"n\":\"DEST Count\"},{\"t\":3,\"p\":1,\"n\":\"VATS Targetable\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":8,\"p\":1,\"n\":\"Stages\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Stage\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"DSTD - Destruction Stage Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Health %\"},{\"t\":3,\"p\":1,\"n\":\"Index\"},{\"t\":3,\"p\":1,\"n\":\"Model Damage Stage\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":3,\"p\":1,\"n\":\"Self Damage per Second\"},{\"t\":3,\"p\":1,\"n\":\"Explosion\"},{\"t\":3,\"p\":1,\"n\":\"Debris\"},{\"t\":3,\"p\":1,\"n\":\"Debris Count\"}]},{\"t\":6,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"DMDL - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"DMDT - Texture Files Hashes\"},{\"t\":7,\"p\":1,\"n\":\"DMDS - Alternate Textures\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"3D Name\"},{\"t\":3,\"p\":1,\"n\":\"New Texture\"},{\"t\":3,\"p\":1,\"n\":\"3D Index\"}]}]}]},{\"p\":1,\"n\":\"DSTF - End Marker\"}]}]}]},{\"t\":3,\"p\":1,\"n\":\"YNAM - Sound - Pick Up\"},{\"t\":3,\"p\":1,\"n\":\"ZNAM - Sound - Put Down\"},{\"t\":3,\"n\":\"KSIZ - Keyword Count\"},{\"t\":7,\"p\":1,\"n\":\"KWDA - Keywords\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Keyword\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DATA - \",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Value\"},{\"t\":5,\"p\":1,\"n\":\"Weight\"}]}]},{\"t\":1,\"p\":1,\"n\":\"KYWD - Keyword\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"CNAM - Color\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unknown\"}]}]},{\"t\":1,\"p\":1,\"n\":\"LAND - Landscape\",\"d\":1,\"c\":[{\"t\":11,\"n\":\"DATA - Unknown\"},{\"t\":11,\"n\":\"VNML - Vertex Normals\"},{\"t\":11,\"n\":\"VHGT - Vertext Height Map\"},{\"t\":11,\"n\":\"VCLR - Vertex Colours\"},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Layers\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Base Layer\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"BTXT - Base Layer Header\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Texture\"},{\"t\":3,\"p\":1,\"n\":\"Quadrant\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":3,\"p\":1,\"n\":\"Layer\"}]}]},{\"t\":6,\"p\":1,\"n\":\"Alpha Layer\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"ATXT - Alpha Layer Header\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Texture\"},{\"t\":3,\"p\":1,\"n\":\"Quadrant\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":3,\"p\":1,\"n\":\"Layer\"}]},{\"t\":11,\"p\":1,\"n\":\"VTXT - Alpha Layer Data\"}]}]},{\"t\":7,\"p\":1,\"n\":\"VTEX - Textures\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Texture\"}]}]},{\"t\":1,\"p\":1,\"n\":\"LCRT - Location Reference Type\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"CNAM - Color\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unknown\"}]}]},{\"t\":1,\"n\":\"LCTN - Location\",\"c\":[{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":7,\"n\":\"ACPR - Actor Cell Persistent Reference\",\"c\":[{\"t\":6,\"n\":\"\",\"c\":[{\"t\":3,\"n\":\"Actor\"},{\"t\":3,\"n\":\"Location\"},{\"t\":3,\"n\":\"Grid Y\"},{\"t\":3,\"n\":\"Grid X\"}]}]},{\"t\":7,\"n\":\"LCPR - Location Cell Persistent Reference\",\"c\":[{\"t\":6,\"n\":\"\",\"c\":[{\"t\":3,\"n\":\"Actor\"},{\"t\":3,\"n\":\"Location\"},{\"t\":3,\"n\":\"Grid Y\"},{\"t\":3,\"n\":\"Grid X\"}]}]},{\"t\":7,\"n\":\"RCPR - Reference Cell Persistent Reference\",\"c\":[{\"t\":3,\"n\":\"Ref\"}]},{\"t\":7,\"n\":\"ACUN - Actor Cell Unique\",\"c\":[{\"t\":6,\"n\":\"\",\"c\":[{\"t\":3,\"n\":\"Actor\"},{\"t\":3,\"n\":\"Ref\"},{\"t\":3,\"n\":\"Location\"}]}]},{\"t\":7,\"n\":\"LCUN - Location Cell Unique\",\"c\":[{\"t\":6,\"n\":\"\",\"c\":[{\"t\":3,\"n\":\"Actor\"},{\"t\":3,\"n\":\"Ref\"},{\"t\":3,\"n\":\"Location\"}]}]},{\"t\":7,\"n\":\"RCUN - Reference Cell Unique\",\"c\":[{\"t\":3,\"n\":\"Actor\"}]},{\"t\":7,\"n\":\"ACSR - Actor Cell Static Reference\",\"c\":[{\"t\":6,\"n\":\"\",\"c\":[{\"t\":3,\"n\":\"Loc Ref Type\"},{\"t\":3,\"n\":\"Marker\"},{\"t\":3,\"n\":\"Location\"},{\"t\":3,\"n\":\"Grid Y\"},{\"t\":3,\"n\":\"Grid X\"}]}]},{\"t\":7,\"n\":\"LCSR - Location Cell Static Reference\",\"c\":[{\"t\":6,\"n\":\"\",\"c\":[{\"t\":3,\"n\":\"Loc Ref Type\"},{\"t\":3,\"n\":\"Marker\"},{\"t\":3,\"n\":\"Location\"},{\"t\":3,\"n\":\"Grid Y\"},{\"t\":3,\"n\":\"Grid X\"}]}]},{\"t\":7,\"n\":\"RCSR - Reference Cell Static Reference\",\"c\":[{\"t\":3,\"n\":\"Ref\"}]},{\"t\":8,\"n\":\"Actor Cell Encounter Cell\",\"c\":[{\"t\":6,\"n\":\"ACEC - Unknown\",\"c\":[{\"t\":3,\"n\":\"Location\"},{\"t\":7,\"n\":\"Coordinates\",\"c\":[{\"t\":6,\"n\":\"\",\"c\":[{\"t\":3,\"n\":\"Grid Y\"},{\"t\":3,\"n\":\"Grid X\"}]}]}]}]},{\"t\":8,\"n\":\"Location Cell Encounter Cell\",\"c\":[{\"t\":6,\"n\":\"LCEC - Unknown\",\"c\":[{\"t\":3,\"n\":\"Location\"},{\"t\":7,\"n\":\"Coordinates\",\"c\":[{\"t\":6,\"n\":\"\",\"c\":[{\"t\":3,\"n\":\"Grid Y\"},{\"t\":3,\"n\":\"Grid X\"}]}]}]}]},{\"t\":8,\"n\":\"Reference Cell Encounter Cell\",\"c\":[{\"t\":6,\"n\":\"RCEC - Unknown\",\"c\":[{\"t\":3,\"n\":\"Location\"},{\"t\":7,\"n\":\"Coordinates\",\"c\":[{\"t\":6,\"n\":\"\",\"c\":[{\"t\":3,\"n\":\"Grid Y\"},{\"t\":3,\"n\":\"Grid X\"}]}]}]}]},{\"t\":7,\"n\":\"ACID - Actor Cell Marker Reference\",\"c\":[{\"t\":3,\"n\":\"Ref\"}]},{\"t\":7,\"n\":\"LCID - Location Cell Marker Reference\",\"c\":[{\"t\":3,\"n\":\"Ref\"}]},{\"t\":7,\"n\":\"ACEP - Actor Cell Enable Point\",\"c\":[{\"t\":6,\"n\":\"\",\"c\":[{\"t\":3,\"n\":\"Actor\"},{\"t\":3,\"n\":\"Ref\"},{\"t\":3,\"n\":\"Grid Y\"},{\"t\":3,\"n\":\"Grid X\"}]}]},{\"t\":7,\"n\":\"LCEP - Location Cell Enable Point\",\"c\":[{\"t\":6,\"n\":\"\",\"c\":[{\"t\":3,\"n\":\"Actor\"},{\"t\":3,\"n\":\"Ref\"},{\"t\":3,\"n\":\"Grid Y\"},{\"t\":3,\"n\":\"Grid X\"}]}]},{\"t\":2,\"n\":\"FULL - Name\"},{\"t\":3,\"n\":\"KSIZ - Keyword Count\"},{\"t\":7,\"n\":\"KWDA - Keywords\",\"c\":[{\"t\":3,\"n\":\"Keyword\"}]},{\"t\":3,\"n\":\"PNAM - Parent Location\"},{\"t\":3,\"n\":\"NAM1 - Music\"},{\"t\":3,\"n\":\"FNAM - Unreported Crime Faction\"},{\"t\":3,\"n\":\"MNAM - World Location Marker Ref\"},{\"t\":5,\"n\":\"RNAM - World Location Radius\"},{\"t\":3,\"n\":\"NAM0 - Horse Marker Ref\"},{\"t\":6,\"n\":\"CNAM - Color\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unknown\"}]}]},{\"t\":1,\"p\":1,\"n\":\"LENS - Lens Flare\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":5,\"p\":1,\"n\":\"CNAM - Color Influence\"},{\"t\":5,\"p\":1,\"n\":\"DNAM - Fade Distance Radius Scale\"},{\"t\":3,\"n\":\"LFSP - Count\"},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Lens Flare Sprites\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Flare\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"DNAM - Lens Flare Sprite ID\"},{\"t\":2,\"p\":1,\"n\":\"FNAM - Texture\"},{\"t\":6,\"p\":1,\"n\":\"LFSD - Lens Flare Data\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Tint\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Red\"},{\"t\":5,\"p\":1,\"n\":\"Green\"},{\"t\":5,\"p\":1,\"n\":\"Blue\"}]},{\"t\":5,\"p\":1,\"n\":\"Width\"},{\"t\":5,\"p\":1,\"n\":\"Height\"},{\"t\":5,\"p\":1,\"n\":\"Position\"},{\"t\":5,\"p\":1,\"n\":\"Angular Fade\"},{\"t\":5,\"p\":1,\"n\":\"Opacity\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"}]}]}]}]},{\"t\":1,\"p\":1,\"n\":\"LGTM - Lighting Template\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DATA - Lighting\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Ambient Color\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Directional Color\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Fog Color Near\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":5,\"p\":1,\"n\":\"Fog Near\"},{\"t\":5,\"p\":1,\"n\":\"Fog Far\"},{\"t\":3,\"p\":1,\"n\":\"Directional Rotation XY\"},{\"t\":3,\"p\":1,\"n\":\"Directional Rotation Z\"},{\"t\":5,\"p\":1,\"n\":\"Directional Fade\"},{\"t\":5,\"p\":1,\"n\":\"Fog Clip Dist\"},{\"t\":5,\"p\":1,\"n\":\"Fog Power\"},{\"t\":6,\"p\":1,\"n\":\"Ambient Colors\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Directional\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"X+\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"X-\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Y+\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Y-\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Z+\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Z-\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]}]},{\"t\":6,\"p\":1,\"n\":\"Specular\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":5,\"p\":1,\"n\":\"Scale\"}]},{\"t\":6,\"p\":1,\"n\":\"Fog Color Far\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":5,\"p\":1,\"n\":\"Fog Max\"},{\"t\":6,\"p\":1,\"n\":\"Light Fade Distances\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Start\"},{\"t\":5,\"p\":1,\"n\":\"End\"}]},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DALC - Directional Ambient Lighting Colors\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Directional\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"X+\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"X-\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Y+\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Y-\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Z+\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Z-\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]}]},{\"t\":6,\"p\":1,\"n\":\"Specular\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":5,\"p\":1,\"n\":\"Scale\"}]}]},{\"t\":1,\"p\":1,\"n\":\"LIGH - Light\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"VMAD - Virtual Machine Adapter\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Version\"},{\"t\":3,\"p\":1,\"n\":\"Object Format\"},{\"t\":7,\"p\":1,\"n\":\"Scripts\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Script\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"scriptName\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":7,\"p\":1,\"n\":\"Properties\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Property\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"propertyName\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]},{\"t\":2,\"p\":1,\"n\":\"String\"},{\"t\":3,\"p\":1,\"n\":\"Int32\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":3,\"p\":1,\"n\":\"Bool\"},{\"t\":7,\"p\":1,\"n\":\"Array of Object\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]}]},{\"t\":7,\"p\":1,\"n\":\"Array of String\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Int32\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Float\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Bool\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]}]}]}]}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"X1\"},{\"t\":3,\"p\":1,\"n\":\"Y1\"},{\"t\":3,\"p\":1,\"n\":\"Z1\"},{\"t\":3,\"p\":1,\"n\":\"X2\"},{\"t\":3,\"p\":1,\"n\":\"Y2\"},{\"t\":3,\"p\":1,\"n\":\"Z2\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"MODT - Texture Files Hashes\"},{\"t\":7,\"p\":1,\"n\":\"MODS - Alternate Textures\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"3D Name\"},{\"t\":3,\"p\":1,\"n\":\"New Texture\"},{\"t\":3,\"p\":1,\"n\":\"3D Index\"}]}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Destructable\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"DEST - Header\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Health\"},{\"t\":3,\"p\":1,\"n\":\"DEST Count\"},{\"t\":3,\"p\":1,\"n\":\"VATS Targetable\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":8,\"p\":1,\"n\":\"Stages\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Stage\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"DSTD - Destruction Stage Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Health %\"},{\"t\":3,\"p\":1,\"n\":\"Index\"},{\"t\":3,\"p\":1,\"n\":\"Model Damage Stage\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":3,\"p\":1,\"n\":\"Self Damage per Second\"},{\"t\":3,\"p\":1,\"n\":\"Explosion\"},{\"t\":3,\"p\":1,\"n\":\"Debris\"},{\"t\":3,\"p\":1,\"n\":\"Debris Count\"}]},{\"t\":6,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"DMDL - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"DMDT - Texture Files Hashes\"},{\"t\":7,\"p\":1,\"n\":\"DMDS - Alternate Textures\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"3D Name\"},{\"t\":3,\"p\":1,\"n\":\"New Texture\"},{\"t\":3,\"p\":1,\"n\":\"3D Index\"}]}]}]},{\"p\":1,\"n\":\"DSTF - End Marker\"}]}]}]},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Icon\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"ICON - Large Icon filename\"},{\"t\":2,\"p\":1,\"n\":\"MICO - Small Icon filename\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DATA - \",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Time\"},{\"t\":3,\"p\":1,\"n\":\"Radius\"},{\"t\":6,\"p\":1,\"n\":\"Color\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":5,\"p\":1,\"n\":\"Falloff Exponent\"},{\"t\":5,\"p\":1,\"n\":\"FOV\"},{\"t\":5,\"p\":1,\"n\":\"Near Clip\"},{\"t\":6,\"p\":1,\"n\":\"Flicker Effect\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Period\"},{\"t\":5,\"p\":1,\"n\":\"Intensity Amplitude\"},{\"t\":5,\"p\":1,\"n\":\"Movement Amplitude\"}]},{\"t\":3,\"p\":1,\"n\":\"Value\"},{\"t\":5,\"p\":1,\"n\":\"Weight\"}]},{\"t\":5,\"p\":1,\"n\":\"FNAM - Fade value\"},{\"t\":3,\"p\":1,\"n\":\"SNAM - Sound\"}]},{\"t\":1,\"p\":1,\"n\":\"LSCR - Load Screen\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Icon\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"ICON - Large Icon filename\"},{\"t\":2,\"p\":1,\"n\":\"MICO - Small Icon filename\"}]},{\"t\":2,\"p\":1,\"n\":\"DESC - Description\"},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Conditions\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Condition\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"CTDA - \",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":5,\"p\":1,\"n\":\"Comparison Value - Float\"},{\"t\":3,\"p\":1,\"n\":\"Comparison Value - Global\"},{\"t\":3,\"p\":1,\"n\":\"Function\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":11,\"p\":1,\"n\":\"None\"},{\"t\":3,\"p\":1,\"n\":\"Integer\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":11,\"p\":1,\"n\":\"Variable Name (unused)\"},{\"t\":3,\"p\":1,\"n\":\"Sex\"},{\"t\":3,\"p\":1,\"n\":\"Actor Value\"},{\"t\":3,\"p\":1,\"n\":\"Crime Type\"},{\"t\":3,\"p\":1,\"n\":\"Axis\"},{\"t\":3,\"p\":1,\"n\":\"Quest Stage (unused)\"},{\"t\":3,\"p\":1,\"n\":\"Misc Stat\"},{\"t\":3,\"p\":1,\"n\":\"Alignment\"},{\"t\":3,\"p\":1,\"n\":\"Equip Type\"},{\"t\":3,\"p\":1,\"n\":\"Form Type\"},{\"t\":3,\"p\":1,\"n\":\"Critical Stage\"},{\"t\":3,\"p\":1,\"n\":\"Object Reference\"},{\"t\":3,\"p\":1,\"n\":\"Inventory Object\"},{\"t\":3,\"p\":1,\"n\":\"Actor\"},{\"t\":3,\"p\":1,\"n\":\"Voice Type\"},{\"t\":3,\"p\":1,\"n\":\"Idle\"},{\"t\":3,\"p\":1,\"n\":\"Form List\"},{\"t\":3,\"p\":1,\"n\":\"Quest\"},{\"t\":3,\"p\":1,\"n\":\"Faction\"},{\"t\":3,\"p\":1,\"n\":\"Cell\"},{\"t\":3,\"p\":1,\"n\":\"Class\"},{\"t\":3,\"p\":1,\"n\":\"Race\"},{\"t\":3,\"p\":1,\"n\":\"Actor Base\"},{\"t\":3,\"p\":1,\"n\":\"Global\"},{\"t\":3,\"p\":1,\"n\":\"Weather\"},{\"t\":3,\"p\":1,\"n\":\"Package\"},{\"t\":3,\"p\":1,\"n\":\"Encounter Zone\"},{\"t\":3,\"p\":1,\"n\":\"Perk\"},{\"t\":3,\"p\":1,\"n\":\"Owner\"},{\"t\":3,\"p\":1,\"n\":\"Furniture\"},{\"t\":3,\"p\":1,\"n\":\"Effect Item\"},{\"t\":3,\"p\":1,\"n\":\"Base Effect\"},{\"t\":3,\"p\":1,\"n\":\"Worldspace\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Function\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Param (INVALID)\"},{\"t\":3,\"p\":1,\"n\":\"Referenceable Object\"},{\"t\":3,\"p\":1,\"n\":\"Region\"},{\"t\":3,\"p\":1,\"n\":\"Keyword\"},{\"t\":3,\"p\":1,\"n\":\"Player Action\"},{\"t\":3,\"p\":1,\"n\":\"Casting Type\"},{\"t\":3,\"p\":1,\"n\":\"Shout\"},{\"t\":3,\"p\":1,\"n\":\"Location\"},{\"t\":3,\"p\":1,\"n\":\"Location Ref Type\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"Packdata ID\"},{\"t\":3,\"p\":1,\"n\":\"Association Type\"},{\"t\":3,\"p\":1,\"n\":\"Furniture Anim\"},{\"t\":3,\"p\":1,\"n\":\"Furniture Entry\"},{\"t\":3,\"p\":1,\"n\":\"Scene\"},{\"t\":3,\"p\":1,\"n\":\"Ward State\"},{\"t\":3,\"p\":1,\"n\":\"Event\"},{\"t\":3,\"p\":1,\"n\":\"Event Data\"},{\"t\":3,\"p\":1,\"n\":\"Quest Stage\"},{\"t\":3,\"p\":1,\"n\":\"Weapon\"},{\"t\":3,\"p\":1,\"n\":\"Weapon List\"},{\"t\":3,\"p\":1,\"n\":\"Target\"},{\"t\":3,\"p\":1,\"n\":\"Target List\"},{\"t\":3,\"p\":1,\"n\":\"Target Part\"},{\"t\":3,\"p\":1,\"n\":\"VATS Action\"},{\"t\":3,\"p\":1,\"n\":\"Critical Effect\"},{\"t\":3,\"p\":1,\"n\":\"Critical Effect List\"},{\"t\":3,\"p\":1,\"n\":\"Weapon Type\"},{\"t\":3,\"p\":1,\"n\":\"Projectile Type\"},{\"t\":3,\"p\":1,\"n\":\"Delivery Type\"},{\"t\":3,\"p\":1,\"n\":\"Run On\"},{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":3,\"p\":1,\"n\":\"Parameter #3\"}]},{\"t\":2,\"p\":1,\"n\":\"CIS1 - Parameter #1\"},{\"t\":2,\"p\":1,\"n\":\"CIS2 - Parameter #2\"}]}]},{\"t\":3,\"p\":1,\"n\":\"NNAM - Loading Screen NIF\"},{\"t\":5,\"p\":1,\"n\":\"SNAM - Initial Scale\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"RNAM - Initial Rotation\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"X\"},{\"t\":3,\"p\":1,\"n\":\"Y\"},{\"t\":3,\"p\":1,\"n\":\"Z\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"ONAM - Rotation Offset Constraints\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Min\"},{\"t\":3,\"p\":1,\"n\":\"Max\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"XNAM - Initial Translation Offset\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"X\"},{\"t\":5,\"p\":1,\"n\":\"Y\"},{\"t\":5,\"p\":1,\"n\":\"Z\"}]},{\"t\":2,\"p\":1,\"n\":\"MOD2 - Camera Path\"}]},{\"t\":1,\"p\":1,\"n\":\"LTEX - Landscape Texture\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":3,\"p\":1,\"n\":\"TNAM - Texture Set\"},{\"t\":3,\"p\":1,\"n\":\"MNAM - Material Type\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"HNAM - Havok Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Friction\"},{\"t\":3,\"p\":1,\"n\":\"Restitution\"}]},{\"t\":3,\"p\":1,\"n\":\"SNAM - Texture Specular Exponent\"},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Grasses\",\"d\":1,\"c\":[{\"t\":3,\"p\":1,\"n\":\"GNAM - Grass\"}]},{\"t\":3,\"n\":\"INAM - Unused\"}]},{\"t\":1,\"p\":1,\"n\":\"LVLI - Leveled Item\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"X1\"},{\"t\":3,\"p\":1,\"n\":\"Y1\"},{\"t\":3,\"p\":1,\"n\":\"Z1\"},{\"t\":3,\"p\":1,\"n\":\"X2\"},{\"t\":3,\"p\":1,\"n\":\"Y2\"},{\"t\":3,\"p\":1,\"n\":\"Z2\"}]},{\"t\":3,\"p\":1,\"n\":\"LVLD - Chance None\"},{\"t\":3,\"p\":1,\"n\":\"LVLF - Flags\"},{\"t\":3,\"p\":1,\"n\":\"LVLG - Global\"},{\"t\":3,\"n\":\"LLCT - Count\"},{\"t\":10,\"p\":1,\"o\":1,\"n\":\"Leveled List Entries\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Leveled List Entry\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"LVLO - Base Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Level\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":3,\"p\":1,\"n\":\"Count\"}]},{\"t\":6,\"p\":1,\"n\":\"COED - Extra Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Owner\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Global Variable\"},{\"t\":3,\"p\":1,\"n\":\"Required Rank\"},{\"t\":5,\"p\":1,\"n\":\"Item Condition\"}]}]}]}]},{\"t\":1,\"p\":1,\"n\":\"LVLN - Leveled NPC\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"X1\"},{\"t\":3,\"p\":1,\"n\":\"Y1\"},{\"t\":3,\"p\":1,\"n\":\"Z1\"},{\"t\":3,\"p\":1,\"n\":\"X2\"},{\"t\":3,\"p\":1,\"n\":\"Y2\"},{\"t\":3,\"p\":1,\"n\":\"Z2\"}]},{\"t\":3,\"p\":1,\"n\":\"LVLD - Chance None\"},{\"t\":3,\"p\":1,\"n\":\"LVLF - Flags\"},{\"t\":3,\"p\":1,\"n\":\"LVLG - Global\"},{\"t\":3,\"n\":\"LLCT - Count\"},{\"t\":10,\"p\":1,\"o\":1,\"n\":\"Leveled List Entries\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Leveled List Entry\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"LVLO - Base Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Level\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":3,\"p\":1,\"n\":\"Count\"}]},{\"t\":6,\"p\":1,\"n\":\"COED - Extra Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Owner\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Global Variable\"},{\"t\":3,\"p\":1,\"n\":\"Required Rank\"},{\"t\":5,\"p\":1,\"n\":\"Item Condition\"}]}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"MODT - Texture Files Hashes\"},{\"t\":7,\"p\":1,\"n\":\"MODS - Alternate Textures\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"3D Name\"},{\"t\":3,\"p\":1,\"n\":\"New Texture\"},{\"t\":3,\"p\":1,\"n\":\"3D Index\"}]}]}]}]},{\"t\":1,\"p\":1,\"n\":\"LVSP - Leveled Spell\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"X1\"},{\"t\":3,\"p\":1,\"n\":\"Y1\"},{\"t\":3,\"p\":1,\"n\":\"Z1\"},{\"t\":3,\"p\":1,\"n\":\"X2\"},{\"t\":3,\"p\":1,\"n\":\"Y2\"},{\"t\":3,\"p\":1,\"n\":\"Z2\"}]},{\"t\":3,\"p\":1,\"n\":\"LVLD - Chance None\"},{\"t\":3,\"p\":1,\"n\":\"LVLF - Flags\"},{\"t\":3,\"n\":\"LLCT - Count\"},{\"t\":10,\"p\":1,\"o\":1,\"n\":\"Leveled List Entries\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Leveled List Entry\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"LVLO - Base Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Level\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":3,\"p\":1,\"n\":\"Count\"}]}]}]}]},{\"t\":1,\"p\":1,\"n\":\"MATO - Material Object\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"MODT - Texture Files Hashes\"},{\"t\":7,\"p\":1,\"n\":\"MODS - Alternate Textures\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"3D Name\"},{\"t\":3,\"p\":1,\"n\":\"New Texture\"},{\"t\":3,\"p\":1,\"n\":\"3D Index\"}]}]}]},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Property Data\",\"d\":1,\"c\":[{\"t\":11,\"p\":1,\"n\":\"DNAM - Data\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DATA - Directional Material Data\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Falloff Scale\"},{\"t\":5,\"p\":1,\"n\":\"Falloff Bias\"},{\"t\":5,\"p\":1,\"n\":\"Noise UV Scale\"},{\"t\":5,\"p\":1,\"n\":\"Material UV Scale\"},{\"t\":6,\"p\":1,\"n\":\"Projection Vector\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"X\"},{\"t\":5,\"p\":1,\"n\":\"Y\"},{\"t\":5,\"p\":1,\"n\":\"Z\"}]},{\"t\":5,\"p\":1,\"n\":\"Normal Dampener\"},{\"t\":6,\"p\":1,\"n\":\"Single Pass Color\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Red\"},{\"t\":5,\"p\":1,\"n\":\"Green\"},{\"t\":5,\"p\":1,\"n\":\"Blue\"}]},{\"t\":3,\"p\":1,\"n\":\"Flags\"}]}]},{\"t\":1,\"p\":1,\"n\":\"MATT - Material Type\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":3,\"p\":1,\"n\":\"PNAM - Material Parent\"},{\"t\":2,\"p\":1,\"n\":\"MNAM - Material Name\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"CNAM - Havok Display Color\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Red\"},{\"t\":5,\"p\":1,\"n\":\"Green\"},{\"t\":5,\"p\":1,\"n\":\"Blue\"}]},{\"t\":5,\"p\":1,\"n\":\"BNAM - Buoyancy\"},{\"t\":3,\"p\":1,\"n\":\"FNAM - Flags\"},{\"t\":3,\"p\":1,\"n\":\"HNAM - Havok Impact Data Set\"}]},{\"t\":1,\"p\":1,\"n\":\"MESG - Message\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"p\":1,\"n\":\"DESC - Description\"},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":3,\"p\":1,\"n\":\"INAM - Icon (unused)\"},{\"t\":3,\"p\":1,\"n\":\"QNAM - Owner Quest\"},{\"t\":3,\"p\":1,\"n\":\"DNAM - Flags\"},{\"t\":3,\"p\":1,\"n\":\"TNAM - Display Time\"},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Menu Buttons\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Menu Button\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"ITXT - Button Text\"},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Conditions\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Condition\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"CTDA - \",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":5,\"p\":1,\"n\":\"Comparison Value - Float\"},{\"t\":3,\"p\":1,\"n\":\"Comparison Value - Global\"},{\"t\":3,\"p\":1,\"n\":\"Function\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":11,\"p\":1,\"n\":\"None\"},{\"t\":3,\"p\":1,\"n\":\"Integer\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":11,\"p\":1,\"n\":\"Variable Name (unused)\"},{\"t\":3,\"p\":1,\"n\":\"Sex\"},{\"t\":3,\"p\":1,\"n\":\"Actor Value\"},{\"t\":3,\"p\":1,\"n\":\"Crime Type\"},{\"t\":3,\"p\":1,\"n\":\"Axis\"},{\"t\":3,\"p\":1,\"n\":\"Quest Stage (unused)\"},{\"t\":3,\"p\":1,\"n\":\"Misc Stat\"},{\"t\":3,\"p\":1,\"n\":\"Alignment\"},{\"t\":3,\"p\":1,\"n\":\"Equip Type\"},{\"t\":3,\"p\":1,\"n\":\"Form Type\"},{\"t\":3,\"p\":1,\"n\":\"Critical Stage\"},{\"t\":3,\"p\":1,\"n\":\"Object Reference\"},{\"t\":3,\"p\":1,\"n\":\"Inventory Object\"},{\"t\":3,\"p\":1,\"n\":\"Actor\"},{\"t\":3,\"p\":1,\"n\":\"Voice Type\"},{\"t\":3,\"p\":1,\"n\":\"Idle\"},{\"t\":3,\"p\":1,\"n\":\"Form List\"},{\"t\":3,\"p\":1,\"n\":\"Quest\"},{\"t\":3,\"p\":1,\"n\":\"Faction\"},{\"t\":3,\"p\":1,\"n\":\"Cell\"},{\"t\":3,\"p\":1,\"n\":\"Class\"},{\"t\":3,\"p\":1,\"n\":\"Race\"},{\"t\":3,\"p\":1,\"n\":\"Actor Base\"},{\"t\":3,\"p\":1,\"n\":\"Global\"},{\"t\":3,\"p\":1,\"n\":\"Weather\"},{\"t\":3,\"p\":1,\"n\":\"Package\"},{\"t\":3,\"p\":1,\"n\":\"Encounter Zone\"},{\"t\":3,\"p\":1,\"n\":\"Perk\"},{\"t\":3,\"p\":1,\"n\":\"Owner\"},{\"t\":3,\"p\":1,\"n\":\"Furniture\"},{\"t\":3,\"p\":1,\"n\":\"Effect Item\"},{\"t\":3,\"p\":1,\"n\":\"Base Effect\"},{\"t\":3,\"p\":1,\"n\":\"Worldspace\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Function\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Param (INVALID)\"},{\"t\":3,\"p\":1,\"n\":\"Referenceable Object\"},{\"t\":3,\"p\":1,\"n\":\"Region\"},{\"t\":3,\"p\":1,\"n\":\"Keyword\"},{\"t\":3,\"p\":1,\"n\":\"Player Action\"},{\"t\":3,\"p\":1,\"n\":\"Casting Type\"},{\"t\":3,\"p\":1,\"n\":\"Shout\"},{\"t\":3,\"p\":1,\"n\":\"Location\"},{\"t\":3,\"p\":1,\"n\":\"Location Ref Type\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"Packdata ID\"},{\"t\":3,\"p\":1,\"n\":\"Association Type\"},{\"t\":3,\"p\":1,\"n\":\"Furniture Anim\"},{\"t\":3,\"p\":1,\"n\":\"Furniture Entry\"},{\"t\":3,\"p\":1,\"n\":\"Scene\"},{\"t\":3,\"p\":1,\"n\":\"Ward State\"},{\"t\":3,\"p\":1,\"n\":\"Event\"},{\"t\":3,\"p\":1,\"n\":\"Event Data\"},{\"t\":3,\"p\":1,\"n\":\"Quest Stage\"},{\"t\":3,\"p\":1,\"n\":\"Weapon\"},{\"t\":3,\"p\":1,\"n\":\"Weapon List\"},{\"t\":3,\"p\":1,\"n\":\"Target\"},{\"t\":3,\"p\":1,\"n\":\"Target List\"},{\"t\":3,\"p\":1,\"n\":\"Target Part\"},{\"t\":3,\"p\":1,\"n\":\"VATS Action\"},{\"t\":3,\"p\":1,\"n\":\"Critical Effect\"},{\"t\":3,\"p\":1,\"n\":\"Critical Effect List\"},{\"t\":3,\"p\":1,\"n\":\"Weapon Type\"},{\"t\":3,\"p\":1,\"n\":\"Projectile Type\"},{\"t\":3,\"p\":1,\"n\":\"Delivery Type\"},{\"t\":3,\"p\":1,\"n\":\"Run On\"},{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":3,\"p\":1,\"n\":\"Parameter #3\"}]},{\"t\":2,\"p\":1,\"n\":\"CIS1 - Parameter #1\"},{\"t\":2,\"p\":1,\"n\":\"CIS2 - Parameter #2\"}]}]}]}]}]},{\"t\":1,\"p\":1,\"n\":\"MGEF - Magic Effect\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"VMAD - Virtual Machine Adapter\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Version\"},{\"t\":3,\"p\":1,\"n\":\"Object Format\"},{\"t\":7,\"p\":1,\"n\":\"Scripts\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Script\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"scriptName\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":7,\"p\":1,\"n\":\"Properties\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Property\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"propertyName\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]},{\"t\":2,\"p\":1,\"n\":\"String\"},{\"t\":3,\"p\":1,\"n\":\"Int32\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":3,\"p\":1,\"n\":\"Bool\"},{\"t\":7,\"p\":1,\"n\":\"Array of Object\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]}]},{\"t\":7,\"p\":1,\"n\":\"Array of String\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Int32\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Float\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Bool\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]}]}]}]}]}]},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":3,\"p\":1,\"n\":\"MDOB - Menu Display Object\"},{\"t\":3,\"n\":\"KSIZ - Keyword Count\"},{\"t\":7,\"p\":1,\"n\":\"KWDA - Keywords\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Keyword\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Magic Effect Data\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"DATA - Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":5,\"p\":1,\"n\":\"Base Cost\"},{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Assoc. Item\"},{\"t\":3,\"p\":1,\"n\":\"Magic Skill\"},{\"t\":3,\"p\":1,\"n\":\"Resist Value\"},{\"t\":3,\"p\":1,\"n\":\"Counter Effect count\"},{\"t\":3,\"p\":1,\"n\":\"Casting Light\"},{\"t\":5,\"p\":1,\"n\":\"Taper Weight\"},{\"t\":3,\"p\":1,\"n\":\"Hit Shader\"},{\"t\":3,\"p\":1,\"n\":\"Enchant Shader\"},{\"t\":3,\"p\":1,\"n\":\"Minimum Skill Level\"},{\"t\":6,\"p\":1,\"n\":\"Spellmaking\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Area\"},{\"t\":5,\"p\":1,\"n\":\"Casting Time\"}]},{\"t\":5,\"p\":1,\"n\":\"Taper Curve\"},{\"t\":5,\"p\":1,\"n\":\"Taper Duration\"},{\"t\":5,\"p\":1,\"n\":\"Second AV Weight\"},{\"t\":3,\"p\":1,\"n\":\"Archtype\"},{\"t\":3,\"p\":1,\"n\":\"Actor Value\"},{\"t\":3,\"p\":1,\"n\":\"Projectile\"},{\"t\":3,\"p\":1,\"n\":\"Explosion\"},{\"t\":3,\"p\":1,\"n\":\"Casting Type\"},{\"t\":3,\"p\":1,\"n\":\"Delivery\"},{\"t\":3,\"p\":1,\"n\":\"Second Actor Value\"},{\"t\":3,\"p\":1,\"n\":\"Casting Art\"},{\"t\":3,\"p\":1,\"n\":\"Hit Effect Art\"},{\"t\":3,\"p\":1,\"n\":\"Impact Data\"},{\"t\":5,\"p\":1,\"n\":\"Skill Usage Multiplier\"},{\"t\":6,\"p\":1,\"n\":\"Dual Casting\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Art\"},{\"t\":5,\"p\":1,\"n\":\"Scale\"}]},{\"t\":3,\"p\":1,\"n\":\"Enchant Art\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":3,\"p\":1,\"n\":\"Equip Ability\"},{\"t\":3,\"p\":1,\"n\":\"Image Space Modifier\"},{\"t\":3,\"p\":1,\"n\":\"Perk to Apply\"},{\"t\":3,\"p\":1,\"n\":\"Casting Sound Level\"},{\"t\":6,\"p\":1,\"n\":\"Script Effect AI\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Score\"},{\"t\":5,\"p\":1,\"n\":\"Delay Time\"}]}]}]},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Counter Effects\",\"d\":1,\"c\":[{\"t\":3,\"n\":\"ESCE - Effect\"}]},{\"t\":7,\"p\":1,\"n\":\"SNDD - Sounds\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Sound\"}]}]},{\"t\":2,\"p\":1,\"n\":\"DNAM - Magic Item Description\"},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Conditions\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Condition\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"CTDA - \",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":5,\"p\":1,\"n\":\"Comparison Value - Float\"},{\"t\":3,\"p\":1,\"n\":\"Comparison Value - Global\"},{\"t\":3,\"p\":1,\"n\":\"Function\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":11,\"p\":1,\"n\":\"None\"},{\"t\":3,\"p\":1,\"n\":\"Integer\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":11,\"p\":1,\"n\":\"Variable Name (unused)\"},{\"t\":3,\"p\":1,\"n\":\"Sex\"},{\"t\":3,\"p\":1,\"n\":\"Actor Value\"},{\"t\":3,\"p\":1,\"n\":\"Crime Type\"},{\"t\":3,\"p\":1,\"n\":\"Axis\"},{\"t\":3,\"p\":1,\"n\":\"Quest Stage (unused)\"},{\"t\":3,\"p\":1,\"n\":\"Misc Stat\"},{\"t\":3,\"p\":1,\"n\":\"Alignment\"},{\"t\":3,\"p\":1,\"n\":\"Equip Type\"},{\"t\":3,\"p\":1,\"n\":\"Form Type\"},{\"t\":3,\"p\":1,\"n\":\"Critical Stage\"},{\"t\":3,\"p\":1,\"n\":\"Object Reference\"},{\"t\":3,\"p\":1,\"n\":\"Inventory Object\"},{\"t\":3,\"p\":1,\"n\":\"Actor\"},{\"t\":3,\"p\":1,\"n\":\"Voice Type\"},{\"t\":3,\"p\":1,\"n\":\"Idle\"},{\"t\":3,\"p\":1,\"n\":\"Form List\"},{\"t\":3,\"p\":1,\"n\":\"Quest\"},{\"t\":3,\"p\":1,\"n\":\"Faction\"},{\"t\":3,\"p\":1,\"n\":\"Cell\"},{\"t\":3,\"p\":1,\"n\":\"Class\"},{\"t\":3,\"p\":1,\"n\":\"Race\"},{\"t\":3,\"p\":1,\"n\":\"Actor Base\"},{\"t\":3,\"p\":1,\"n\":\"Global\"},{\"t\":3,\"p\":1,\"n\":\"Weather\"},{\"t\":3,\"p\":1,\"n\":\"Package\"},{\"t\":3,\"p\":1,\"n\":\"Encounter Zone\"},{\"t\":3,\"p\":1,\"n\":\"Perk\"},{\"t\":3,\"p\":1,\"n\":\"Owner\"},{\"t\":3,\"p\":1,\"n\":\"Furniture\"},{\"t\":3,\"p\":1,\"n\":\"Effect Item\"},{\"t\":3,\"p\":1,\"n\":\"Base Effect\"},{\"t\":3,\"p\":1,\"n\":\"Worldspace\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Function\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Param (INVALID)\"},{\"t\":3,\"p\":1,\"n\":\"Referenceable Object\"},{\"t\":3,\"p\":1,\"n\":\"Region\"},{\"t\":3,\"p\":1,\"n\":\"Keyword\"},{\"t\":3,\"p\":1,\"n\":\"Player Action\"},{\"t\":3,\"p\":1,\"n\":\"Casting Type\"},{\"t\":3,\"p\":1,\"n\":\"Shout\"},{\"t\":3,\"p\":1,\"n\":\"Location\"},{\"t\":3,\"p\":1,\"n\":\"Location Ref Type\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"Packdata ID\"},{\"t\":3,\"p\":1,\"n\":\"Association Type\"},{\"t\":3,\"p\":1,\"n\":\"Furniture Anim\"},{\"t\":3,\"p\":1,\"n\":\"Furniture Entry\"},{\"t\":3,\"p\":1,\"n\":\"Scene\"},{\"t\":3,\"p\":1,\"n\":\"Ward State\"},{\"t\":3,\"p\":1,\"n\":\"Event\"},{\"t\":3,\"p\":1,\"n\":\"Event Data\"},{\"t\":3,\"p\":1,\"n\":\"Quest Stage\"},{\"t\":3,\"p\":1,\"n\":\"Weapon\"},{\"t\":3,\"p\":1,\"n\":\"Weapon List\"},{\"t\":3,\"p\":1,\"n\":\"Target\"},{\"t\":3,\"p\":1,\"n\":\"Target List\"},{\"t\":3,\"p\":1,\"n\":\"Target Part\"},{\"t\":3,\"p\":1,\"n\":\"VATS Action\"},{\"t\":3,\"p\":1,\"n\":\"Critical Effect\"},{\"t\":3,\"p\":1,\"n\":\"Critical Effect List\"},{\"t\":3,\"p\":1,\"n\":\"Weapon Type\"},{\"t\":3,\"p\":1,\"n\":\"Projectile Type\"},{\"t\":3,\"p\":1,\"n\":\"Delivery Type\"},{\"t\":3,\"p\":1,\"n\":\"Run On\"},{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":3,\"p\":1,\"n\":\"Parameter #3\"}]},{\"t\":2,\"p\":1,\"n\":\"CIS1 - Parameter #1\"},{\"t\":2,\"p\":1,\"n\":\"CIS2 - Parameter #2\"}]}]}]},{\"t\":1,\"p\":1,\"n\":\"MISC - Misc. Item\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"VMAD - Virtual Machine Adapter\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Version\"},{\"t\":3,\"p\":1,\"n\":\"Object Format\"},{\"t\":7,\"p\":1,\"n\":\"Scripts\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Script\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"scriptName\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":7,\"p\":1,\"n\":\"Properties\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Property\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"propertyName\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]},{\"t\":2,\"p\":1,\"n\":\"String\"},{\"t\":3,\"p\":1,\"n\":\"Int32\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":3,\"p\":1,\"n\":\"Bool\"},{\"t\":7,\"p\":1,\"n\":\"Array of Object\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]}]},{\"t\":7,\"p\":1,\"n\":\"Array of String\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Int32\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Float\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Bool\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]}]}]}]}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"X1\"},{\"t\":3,\"p\":1,\"n\":\"Y1\"},{\"t\":3,\"p\":1,\"n\":\"Z1\"},{\"t\":3,\"p\":1,\"n\":\"X2\"},{\"t\":3,\"p\":1,\"n\":\"Y2\"},{\"t\":3,\"p\":1,\"n\":\"Z2\"}]},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"MODT - Texture Files Hashes\"},{\"t\":7,\"p\":1,\"n\":\"MODS - Alternate Textures\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"3D Name\"},{\"t\":3,\"p\":1,\"n\":\"New Texture\"},{\"t\":3,\"p\":1,\"n\":\"3D Index\"}]}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Icon\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"ICON - Large Icon filename\"},{\"t\":2,\"p\":1,\"n\":\"MICO - Small Icon filename\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Destructable\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"DEST - Header\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Health\"},{\"t\":3,\"p\":1,\"n\":\"DEST Count\"},{\"t\":3,\"p\":1,\"n\":\"VATS Targetable\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":8,\"p\":1,\"n\":\"Stages\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Stage\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"DSTD - Destruction Stage Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Health %\"},{\"t\":3,\"p\":1,\"n\":\"Index\"},{\"t\":3,\"p\":1,\"n\":\"Model Damage Stage\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":3,\"p\":1,\"n\":\"Self Damage per Second\"},{\"t\":3,\"p\":1,\"n\":\"Explosion\"},{\"t\":3,\"p\":1,\"n\":\"Debris\"},{\"t\":3,\"p\":1,\"n\":\"Debris Count\"}]},{\"t\":6,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"DMDL - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"DMDT - Texture Files Hashes\"},{\"t\":7,\"p\":1,\"n\":\"DMDS - Alternate Textures\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"3D Name\"},{\"t\":3,\"p\":1,\"n\":\"New Texture\"},{\"t\":3,\"p\":1,\"n\":\"3D Index\"}]}]}]},{\"p\":1,\"n\":\"DSTF - End Marker\"}]}]}]},{\"t\":3,\"p\":1,\"n\":\"YNAM - Sound - Pick Up\"},{\"t\":3,\"p\":1,\"n\":\"ZNAM - Sound - Put Down\"},{\"t\":3,\"n\":\"KSIZ - Keyword Count\"},{\"t\":7,\"p\":1,\"n\":\"KWDA - Keywords\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Keyword\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DATA - Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Value\"},{\"t\":5,\"p\":1,\"n\":\"Weight\"}]}]},{\"t\":1,\"p\":1,\"n\":\"MOVT - Movement Type\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"p\":1,\"n\":\"MNAM - Name\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"SPED - Default Data\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Left Walk\"},{\"t\":5,\"p\":1,\"n\":\"Left Run\"},{\"t\":5,\"p\":1,\"n\":\"Right Walk\"},{\"t\":5,\"p\":1,\"n\":\"Right Run\"},{\"t\":5,\"p\":1,\"n\":\"Forward Walk\"},{\"t\":5,\"p\":1,\"n\":\"Forward Run\"},{\"t\":5,\"p\":1,\"n\":\"Back Walk\"},{\"t\":5,\"p\":1,\"n\":\"Back Run\"},{\"t\":5,\"p\":1,\"n\":\"Rotate in Place Walk\"},{\"t\":5,\"p\":1,\"n\":\"Rotate in Place Run\"},{\"t\":5,\"p\":1,\"n\":\"Rotate while Moving Run\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"INAM - Anim Change Thresholds\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Directional\"},{\"t\":5,\"p\":1,\"n\":\"Movement Speed\"},{\"t\":5,\"p\":1,\"n\":\"Rotation Speed\"}]}]},{\"t\":1,\"p\":1,\"n\":\"MSTT - Moveable Static\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"X1\"},{\"t\":3,\"p\":1,\"n\":\"Y1\"},{\"t\":3,\"p\":1,\"n\":\"Z1\"},{\"t\":3,\"p\":1,\"n\":\"X2\"},{\"t\":3,\"p\":1,\"n\":\"Y2\"},{\"t\":3,\"p\":1,\"n\":\"Z2\"}]},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"MODT - Texture Files Hashes\"},{\"t\":7,\"p\":1,\"n\":\"MODS - Alternate Textures\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"3D Name\"},{\"t\":3,\"p\":1,\"n\":\"New Texture\"},{\"t\":3,\"p\":1,\"n\":\"3D Index\"}]}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Destructable\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"DEST - Header\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Health\"},{\"t\":3,\"p\":1,\"n\":\"DEST Count\"},{\"t\":3,\"p\":1,\"n\":\"VATS Targetable\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":8,\"p\":1,\"n\":\"Stages\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Stage\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"DSTD - Destruction Stage Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Health %\"},{\"t\":3,\"p\":1,\"n\":\"Index\"},{\"t\":3,\"p\":1,\"n\":\"Model Damage Stage\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":3,\"p\":1,\"n\":\"Self Damage per Second\"},{\"t\":3,\"p\":1,\"n\":\"Explosion\"},{\"t\":3,\"p\":1,\"n\":\"Debris\"},{\"t\":3,\"p\":1,\"n\":\"Debris Count\"}]},{\"t\":6,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"DMDL - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"DMDT - Texture Files Hashes\"},{\"t\":7,\"p\":1,\"n\":\"DMDS - Alternate Textures\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"3D Name\"},{\"t\":3,\"p\":1,\"n\":\"New Texture\"},{\"t\":3,\"p\":1,\"n\":\"3D Index\"}]}]}]},{\"p\":1,\"n\":\"DSTF - End Marker\"}]}]}]},{\"t\":3,\"p\":1,\"n\":\"DATA - Flags\"},{\"t\":3,\"p\":1,\"n\":\"SNAM - Looping Sound\"}]},{\"t\":1,\"p\":1,\"n\":\"MUSC - Music Type\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":3,\"p\":1,\"n\":\"FNAM - Flags\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"PNAM - Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Priority\"},{\"t\":3,\"p\":1,\"n\":\"Ducking (dB)\"}]},{\"t\":5,\"p\":1,\"n\":\"WNAM - Fade Duration\"},{\"t\":7,\"p\":1,\"n\":\"TNAM - Music Tracks\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Track\"}]}]},{\"t\":1,\"p\":1,\"n\":\"MUST - Music Track\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":3,\"p\":1,\"n\":\"CNAM - Track Type\"},{\"t\":5,\"p\":1,\"n\":\"FLTV - Duration\"},{\"t\":5,\"p\":1,\"n\":\"DNAM - Fade-Out\"},{\"t\":2,\"p\":1,\"n\":\"ANAM - Track Filename\"},{\"t\":2,\"p\":1,\"n\":\"BNAM - Finale Filename\"},{\"t\":7,\"p\":1,\"n\":\"FNAM - Cue Points\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Point\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"LNAM - Loop Data\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Loop Begins\"},{\"t\":5,\"p\":1,\"n\":\"Loop Ends\"},{\"t\":3,\"p\":1,\"n\":\"Loop Count\"}]},{\"t\":3,\"n\":\"CITC - Condition Count\"},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Conditions\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Condition\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"CTDA - \",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":5,\"p\":1,\"n\":\"Comparison Value - Float\"},{\"t\":3,\"p\":1,\"n\":\"Comparison Value - Global\"},{\"t\":3,\"p\":1,\"n\":\"Function\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":11,\"p\":1,\"n\":\"None\"},{\"t\":3,\"p\":1,\"n\":\"Integer\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":11,\"p\":1,\"n\":\"Variable Name (unused)\"},{\"t\":3,\"p\":1,\"n\":\"Sex\"},{\"t\":3,\"p\":1,\"n\":\"Actor Value\"},{\"t\":3,\"p\":1,\"n\":\"Crime Type\"},{\"t\":3,\"p\":1,\"n\":\"Axis\"},{\"t\":3,\"p\":1,\"n\":\"Quest Stage (unused)\"},{\"t\":3,\"p\":1,\"n\":\"Misc Stat\"},{\"t\":3,\"p\":1,\"n\":\"Alignment\"},{\"t\":3,\"p\":1,\"n\":\"Equip Type\"},{\"t\":3,\"p\":1,\"n\":\"Form Type\"},{\"t\":3,\"p\":1,\"n\":\"Critical Stage\"},{\"t\":3,\"p\":1,\"n\":\"Object Reference\"},{\"t\":3,\"p\":1,\"n\":\"Inventory Object\"},{\"t\":3,\"p\":1,\"n\":\"Actor\"},{\"t\":3,\"p\":1,\"n\":\"Voice Type\"},{\"t\":3,\"p\":1,\"n\":\"Idle\"},{\"t\":3,\"p\":1,\"n\":\"Form List\"},{\"t\":3,\"p\":1,\"n\":\"Quest\"},{\"t\":3,\"p\":1,\"n\":\"Faction\"},{\"t\":3,\"p\":1,\"n\":\"Cell\"},{\"t\":3,\"p\":1,\"n\":\"Class\"},{\"t\":3,\"p\":1,\"n\":\"Race\"},{\"t\":3,\"p\":1,\"n\":\"Actor Base\"},{\"t\":3,\"p\":1,\"n\":\"Global\"},{\"t\":3,\"p\":1,\"n\":\"Weather\"},{\"t\":3,\"p\":1,\"n\":\"Package\"},{\"t\":3,\"p\":1,\"n\":\"Encounter Zone\"},{\"t\":3,\"p\":1,\"n\":\"Perk\"},{\"t\":3,\"p\":1,\"n\":\"Owner\"},{\"t\":3,\"p\":1,\"n\":\"Furniture\"},{\"t\":3,\"p\":1,\"n\":\"Effect Item\"},{\"t\":3,\"p\":1,\"n\":\"Base Effect\"},{\"t\":3,\"p\":1,\"n\":\"Worldspace\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Function\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Param (INVALID)\"},{\"t\":3,\"p\":1,\"n\":\"Referenceable Object\"},{\"t\":3,\"p\":1,\"n\":\"Region\"},{\"t\":3,\"p\":1,\"n\":\"Keyword\"},{\"t\":3,\"p\":1,\"n\":\"Player Action\"},{\"t\":3,\"p\":1,\"n\":\"Casting Type\"},{\"t\":3,\"p\":1,\"n\":\"Shout\"},{\"t\":3,\"p\":1,\"n\":\"Location\"},{\"t\":3,\"p\":1,\"n\":\"Location Ref Type\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"Packdata ID\"},{\"t\":3,\"p\":1,\"n\":\"Association Type\"},{\"t\":3,\"p\":1,\"n\":\"Furniture Anim\"},{\"t\":3,\"p\":1,\"n\":\"Furniture Entry\"},{\"t\":3,\"p\":1,\"n\":\"Scene\"},{\"t\":3,\"p\":1,\"n\":\"Ward State\"},{\"t\":3,\"p\":1,\"n\":\"Event\"},{\"t\":3,\"p\":1,\"n\":\"Event Data\"},{\"t\":3,\"p\":1,\"n\":\"Quest Stage\"},{\"t\":3,\"p\":1,\"n\":\"Weapon\"},{\"t\":3,\"p\":1,\"n\":\"Weapon List\"},{\"t\":3,\"p\":1,\"n\":\"Target\"},{\"t\":3,\"p\":1,\"n\":\"Target List\"},{\"t\":3,\"p\":1,\"n\":\"Target Part\"},{\"t\":3,\"p\":1,\"n\":\"VATS Action\"},{\"t\":3,\"p\":1,\"n\":\"Critical Effect\"},{\"t\":3,\"p\":1,\"n\":\"Critical Effect List\"},{\"t\":3,\"p\":1,\"n\":\"Weapon Type\"},{\"t\":3,\"p\":1,\"n\":\"Projectile Type\"},{\"t\":3,\"p\":1,\"n\":\"Delivery Type\"},{\"t\":3,\"p\":1,\"n\":\"Run On\"},{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":3,\"p\":1,\"n\":\"Parameter #3\"}]},{\"t\":2,\"p\":1,\"n\":\"CIS1 - Parameter #1\"},{\"t\":2,\"p\":1,\"n\":\"CIS2 - Parameter #2\"}]}]},{\"t\":7,\"p\":1,\"n\":\"SNAM - Tracks\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Track\"}]}]},{\"t\":1,\"n\":\"NAVI - Navigation Mesh Info Map\",\"c\":[{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":3,\"n\":\"NVER - Version\"},{\"t\":8,\"n\":\"Navigation Map Infos\",\"c\":[{\"t\":6,\"n\":\"NVMI - Navigation Map Info\",\"c\":[{\"t\":3,\"n\":\"Navigation Mesh\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":5,\"n\":\"X\"},{\"t\":5,\"n\":\"Y\"},{\"t\":5,\"n\":\"Z\"},{\"t\":3,\"n\":\"Preferred Merges Flag\"},{\"t\":7,\"n\":\"Merged To\",\"c\":[{\"t\":3,\"n\":\"Mesh\"}]},{\"t\":7,\"n\":\"Preferred Merges\",\"c\":[{\"t\":3,\"n\":\"Mesh\"}]},{\"t\":7,\"n\":\"Linked Doors\",\"c\":[{\"t\":6,\"n\":\"Door\",\"c\":[{\"t\":11,\"n\":\"Unknown\"},{\"t\":3,\"n\":\"Door Ref\"}]}]},{\"t\":3,\"n\":\"Is Island\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":6,\"n\":\"Island Data\",\"c\":[{\"t\":11,\"n\":\"Unknown\"},{\"t\":7,\"n\":\"Triangles\",\"c\":[{\"t\":11,\"n\":\"Triangle\"}]},{\"t\":7,\"n\":\"Vertices\",\"c\":[{\"t\":11,\"n\":\"Vertex\"}]}]},{\"t\":3,\"n\":\"Parent Worldspace\"},{\"t\":6,\"n\":\"Coordinates\",\"c\":[{\"t\":3,\"n\":\"Grid Y\"},{\"t\":3,\"n\":\"Grid X\"}]},{\"t\":3,\"n\":\"Parent Cell\"}]}]},{\"t\":6,\"n\":\"NVPP - Preferred Pathing\",\"c\":[{\"t\":7,\"n\":\"NavMeshes\",\"c\":[{\"t\":7,\"n\":\"Set\",\"c\":[{\"t\":3,\"n\":\"\"}]}]},{\"t\":7,\"n\":\"NavMesh Tree?\",\"c\":[{\"t\":6,\"n\":\"\",\"c\":[{\"t\":3,\"n\":\"NavMesh\"},{\"t\":3,\"n\":\"Index\\/Node\"}]}]}]},{\"t\":7,\"n\":\"NVSI - Unknown\",\"c\":[{\"t\":3,\"n\":\"Navigation Mesh\"}]}]},{\"t\":1,\"n\":\"NAVM - Navigation Mesh\",\"c\":[{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"n\":\"NVNM - Geometry\",\"c\":[{\"t\":11,\"n\":\"Unknown\"},{\"t\":3,\"n\":\"Parent Worldspace\"},{\"t\":6,\"n\":\"Coordinates\",\"c\":[{\"t\":3,\"n\":\"Grid Y\"},{\"t\":3,\"n\":\"Grid X\"}]},{\"t\":3,\"n\":\"Parent Cell\"},{\"t\":7,\"n\":\"Vertices\",\"c\":[{\"t\":11,\"n\":\"Vertex\"}]},{\"t\":7,\"n\":\"Triangles\",\"c\":[{\"t\":11,\"n\":\"Triangle\"}]},{\"t\":7,\"n\":\"External Connections\",\"c\":[{\"t\":6,\"n\":\"Connection\",\"c\":[{\"t\":11,\"n\":\"Unknown\"},{\"t\":3,\"n\":\"Mesh\"},{\"t\":3,\"n\":\"Triangle\"}]}]},{\"t\":7,\"n\":\"Door Triangles\",\"c\":[{\"t\":6,\"n\":\"Door Triangle\",\"c\":[{\"t\":3,\"n\":\"Triangle before door\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":3,\"n\":\"Door\"}]}]}]},{\"t\":11,\"n\":\"ONAM - Unknown\"},{\"t\":11,\"n\":\"PNAM - Unknown\"},{\"t\":11,\"n\":\"NNAM - Unknown\"}]},{\"t\":1,\"p\":1,\"n\":\"NPC_ - Non-Player Character (Actor)\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"VMAD - Virtual Machine Adapter\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Version\"},{\"t\":3,\"p\":1,\"n\":\"Object Format\"},{\"t\":7,\"p\":1,\"n\":\"Scripts\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Script\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"scriptName\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":7,\"p\":1,\"n\":\"Properties\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Property\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"propertyName\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]},{\"t\":2,\"p\":1,\"n\":\"String\"},{\"t\":3,\"p\":1,\"n\":\"Int32\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":3,\"p\":1,\"n\":\"Bool\"},{\"t\":7,\"p\":1,\"n\":\"Array of Object\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]}]},{\"t\":7,\"p\":1,\"n\":\"Array of String\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Int32\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Float\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Bool\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]}]}]}]}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"X1\"},{\"t\":3,\"p\":1,\"n\":\"Y1\"},{\"t\":3,\"p\":1,\"n\":\"Z1\"},{\"t\":3,\"p\":1,\"n\":\"X2\"},{\"t\":3,\"p\":1,\"n\":\"Y2\"},{\"t\":3,\"p\":1,\"n\":\"Z2\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"ACBS - Configuration\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":3,\"p\":1,\"n\":\"Magicka Offset\"},{\"t\":3,\"p\":1,\"n\":\"Stamina Offset\"},{\"t\":3,\"p\":1,\"n\":\"Level\"},{\"t\":3,\"p\":1,\"n\":\"Level Mult\"},{\"t\":3,\"p\":1,\"n\":\"Calc min level\"},{\"t\":3,\"p\":1,\"n\":\"Calc max level\"},{\"t\":3,\"p\":1,\"n\":\"Speed Multiplier\"},{\"t\":3,\"p\":1,\"n\":\"Disposition Base (unused)\"},{\"t\":3,\"p\":1,\"n\":\"Template Flags\"},{\"t\":3,\"p\":1,\"n\":\"Health Offset\"},{\"t\":3,\"p\":1,\"n\":\"Bleedout Override\"}]},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Factions\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"SNAM - Faction\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Faction\"},{\"t\":3,\"p\":1,\"n\":\"Rank\"},{\"t\":11,\"n\":\"Unused\"}]}]},{\"t\":3,\"p\":1,\"n\":\"INAM - Death item\"},{\"t\":3,\"p\":1,\"n\":\"VTCK - Voice\"},{\"t\":3,\"p\":1,\"n\":\"TPLT - Template\"},{\"t\":3,\"p\":1,\"n\":\"RNAM - Race\",\"lt\":\"NAMA - Face parts\",\"lf\":\"NAM6 - Height\"},{\"t\":3,\"n\":\"SPCT - Count\"},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Actor Effects\",\"d\":1,\"c\":[{\"t\":3,\"p\":1,\"n\":\"SPLO - Actor Effect\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Destructable\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"DEST - Header\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Health\"},{\"t\":3,\"p\":1,\"n\":\"DEST Count\"},{\"t\":3,\"p\":1,\"n\":\"VATS Targetable\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":8,\"p\":1,\"n\":\"Stages\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Stage\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"DSTD - Destruction Stage Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Health %\"},{\"t\":3,\"p\":1,\"n\":\"Index\"},{\"t\":3,\"p\":1,\"n\":\"Model Damage Stage\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":3,\"p\":1,\"n\":\"Self Damage per Second\"},{\"t\":3,\"p\":1,\"n\":\"Explosion\"},{\"t\":3,\"p\":1,\"n\":\"Debris\"},{\"t\":3,\"p\":1,\"n\":\"Debris Count\"}]},{\"t\":6,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"DMDL - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"DMDT - Texture Files Hashes\"},{\"t\":7,\"p\":1,\"n\":\"DMDS - Alternate Textures\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"3D Name\"},{\"t\":3,\"p\":1,\"n\":\"New Texture\"},{\"t\":3,\"p\":1,\"n\":\"3D Index\"}]}]}]},{\"p\":1,\"n\":\"DSTF - End Marker\"}]}]}]},{\"t\":3,\"p\":1,\"n\":\"WNAM - Worn Armor\"},{\"t\":3,\"p\":1,\"n\":\"ANAM - Far away model\"},{\"t\":3,\"p\":1,\"n\":\"ATKR - Attack Race\"},{\"t\":10,\"p\":1,\"n\":\"Attacks\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Attack\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"ATKD - Attack Data\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Damage Mult\"},{\"t\":5,\"p\":1,\"n\":\"Attack Chance\"},{\"t\":3,\"p\":1,\"n\":\"Attack Spell\"},{\"t\":3,\"p\":1,\"n\":\"Attack Flags\"},{\"t\":5,\"p\":1,\"n\":\"Attack Angle\"},{\"t\":5,\"p\":1,\"n\":\"Strike Angle\"},{\"t\":5,\"p\":1,\"n\":\"Stagger\"},{\"t\":3,\"p\":1,\"n\":\"Attack Type\"},{\"t\":5,\"p\":1,\"n\":\"Knockdown\"},{\"t\":5,\"p\":1,\"n\":\"Recovery Time\"},{\"t\":5,\"p\":1,\"n\":\"Stamina Mult\"}]},{\"t\":2,\"p\":1,\"n\":\"ATKE - Attack Event\"}]}]},{\"t\":3,\"p\":1,\"n\":\"SPOR - Spectator override package list\"},{\"t\":3,\"p\":1,\"n\":\"OCOR - Observe dead body override package list\"},{\"t\":3,\"p\":1,\"n\":\"GWOR - Guard warn override package list\"},{\"t\":3,\"p\":1,\"n\":\"ECOR - Combat override package list\"},{\"t\":3,\"n\":\"PRKZ - Perk Count\"},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Perks\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"PRKR - Perk\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Perk\"},{\"t\":3,\"p\":1,\"n\":\"Rank\"},{\"t\":11,\"n\":\"Unused\"}]}]},{\"t\":3,\"n\":\"COCT - Count\"},{\"t\":10,\"p\":1,\"n\":\"Items\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Item\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"CNTO - Item\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Item\"},{\"t\":3,\"p\":1,\"n\":\"Count\"}]},{\"t\":6,\"p\":1,\"n\":\"COED - Extra Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Owner\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Global Variable\"},{\"t\":3,\"p\":1,\"n\":\"Required Rank\"},{\"t\":5,\"p\":1,\"n\":\"Item Condition\"}]}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"AIDT - AI Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Aggression\"},{\"t\":3,\"p\":1,\"n\":\"Confidence\"},{\"t\":3,\"p\":1,\"n\":\"Energy Level\"},{\"t\":3,\"p\":1,\"n\":\"Responsibility\"},{\"t\":3,\"p\":1,\"n\":\"Mood\"},{\"t\":3,\"p\":1,\"n\":\"Assistance\"},{\"t\":6,\"p\":1,\"n\":\"Aggro\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Aggro Radius Behavior\"},{\"t\":3,\"n\":\"Unknown\"},{\"t\":3,\"p\":1,\"n\":\"Warn\"},{\"t\":3,\"p\":1,\"n\":\"Warn\\/Attack\"},{\"t\":3,\"p\":1,\"n\":\"Attack\"}]}]},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Packages\",\"d\":1,\"c\":[{\"t\":3,\"p\":1,\"n\":\"PKID - Package\"}]},{\"t\":3,\"n\":\"KSIZ - Keyword Count\"},{\"t\":7,\"p\":1,\"n\":\"KWDA - Keywords\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Keyword\"}]},{\"t\":3,\"p\":1,\"n\":\"CNAM - Class\"},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":2,\"p\":1,\"n\":\"SHRT - Short Name\"},{\"t\":11,\"n\":\"DATA - Marker\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DNAM - Player Skills\",\"c\":[{\"t\":7,\"p\":1,\"n\":\"Skill Values\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Skill\"}]},{\"t\":7,\"p\":1,\"n\":\"Skill Offsets\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Skill\"}]},{\"t\":3,\"p\":1,\"n\":\"Health\"},{\"t\":3,\"p\":1,\"n\":\"Magicka\"},{\"t\":3,\"p\":1,\"n\":\"Stamina\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":5,\"p\":1,\"n\":\"Far away model distance\"},{\"t\":3,\"p\":1,\"n\":\"Geared up weapons\"}]},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Head Parts\",\"d\":1,\"c\":[{\"t\":3,\"p\":1,\"n\":\"PNAM - Head Part\"}],\"lt\":\"NAM7 - Weight\",\"lf\":\"HCLF - Hair Color\"},{\"t\":3,\"p\":1,\"n\":\"HCLF - Hair Color\",\"lt\":\"Head Parts\",\"lf\":\"FTST - Head texture\"},{\"t\":3,\"p\":1,\"n\":\"ZNAM - Combat Style\"},{\"t\":3,\"p\":1,\"n\":\"GNAM - Gift Filter\"},{\"t\":11,\"n\":\"NAM5 - Unknown\"},{\"t\":5,\"p\":1,\"n\":\"NAM6 - Height\",\"lt\":\"RNAM - Race\",\"lf\":\"NAM7 - Weight\"},{\"t\":5,\"p\":1,\"n\":\"NAM7 - Weight\",\"lt\":\"NAM6 - Height\",\"lf\":\"Head Parts\"},{\"t\":3,\"p\":1,\"n\":\"NAM8 - Sound Level\"},{\"t\":10,\"p\":1,\"n\":\"Sound Types\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Sound Type\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"CSDT - Type\"},{\"t\":10,\"p\":1,\"n\":\"Sounds\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Sound\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"CSDI - Sound\"},{\"t\":3,\"p\":1,\"n\":\"CSDC - Sound Chance\"}]}]}]}]},{\"t\":3,\"p\":1,\"n\":\"CSCR - Inherits Sounds From\"},{\"t\":3,\"p\":1,\"n\":\"DOFT - Default outfit\"},{\"t\":3,\"p\":1,\"n\":\"SOFT - Sleeping outfit\"},{\"t\":3,\"p\":1,\"n\":\"DPLT - Default Package List\"},{\"t\":3,\"p\":1,\"n\":\"CRIF - Crime faction\"},{\"t\":3,\"p\":1,\"n\":\"FTST - Head texture\",\"lt\":\"HCLF - Hair Color\",\"lf\":\"QNAM - Texture lighting\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"QNAM - Texture lighting\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Red\"},{\"t\":5,\"p\":1,\"n\":\"Green\"},{\"t\":5,\"p\":1,\"n\":\"Blue\"}],\"lt\":\"FTST - Head texture\",\"lf\":\"NAM9 - Face morph\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"NAM9 - Face morph\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Nose Long\\/Short\"},{\"t\":5,\"p\":1,\"n\":\"Nose Up\\/Down\"},{\"t\":5,\"p\":1,\"n\":\"Jaw Up\\/Down\"},{\"t\":5,\"p\":1,\"n\":\"Jaw Narrow\\/Wide\"},{\"t\":5,\"p\":1,\"n\":\"Jaw Farward\\/Back\"},{\"t\":5,\"p\":1,\"n\":\"Cheeks Up\\/Down\"},{\"t\":5,\"p\":1,\"n\":\"Cheeks Farward\\/Back\"},{\"t\":5,\"p\":1,\"n\":\"Eyes Up\\/Down\"},{\"t\":5,\"p\":1,\"n\":\"Eyes In\\/Out\"},{\"t\":5,\"p\":1,\"n\":\"Brows Up\\/Down\"},{\"t\":5,\"p\":1,\"n\":\"Brows In\\/Out\"},{\"t\":5,\"p\":1,\"n\":\"Brows Farward\\/Back\"},{\"t\":5,\"p\":1,\"n\":\"Lips Up\\/Down\"},{\"t\":5,\"p\":1,\"n\":\"Lips In\\/Out\"},{\"t\":5,\"p\":1,\"n\":\"Chin Narrow\\/Wide\"},{\"t\":5,\"p\":1,\"n\":\"Chin Up\\/Down\"},{\"t\":5,\"p\":1,\"n\":\"Chin Underbite\\/Overbite\"},{\"t\":5,\"p\":1,\"n\":\"Eyes Farward\\/Back\"},{\"t\":5,\"n\":\"Unknown\"}],\"lt\":\"QNAM - Texture lighting\",\"lf\":\"Tint Layers\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"NAMA - Face parts\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Nose\"},{\"t\":3,\"n\":\"Unknown\"},{\"t\":3,\"p\":1,\"n\":\"Eyes\"},{\"t\":3,\"p\":1,\"n\":\"Mouth\"}],\"lt\":\"Tint Layers\",\"lf\":\"RNAM - Race\"},{\"t\":10,\"p\":1,\"n\":\"Tint Layers\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Layer\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"TINI - Tint Index\"},{\"t\":6,\"p\":1,\"n\":\"TINC - Tint Color\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":3,\"p\":1,\"n\":\"Alpha\"}]},{\"t\":3,\"p\":1,\"n\":\"TINV - Interpolation Value\"},{\"t\":3,\"p\":1,\"n\":\"TIAS - Preset\"}]}],\"lt\":\"NAM9 - Face morph\",\"lf\":\"NAMA - Face parts\"}]},{\"t\":1,\"p\":1,\"n\":\"OTFT - Outfit\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":7,\"s\":1,\"p\":1,\"n\":\"INAM - Items\",\"d\":1,\"c\":[{\"t\":3,\"p\":1,\"n\":\"Item\"}]}]},{\"t\":1,\"p\":1,\"n\":\"PACK - Package\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"VMAD - Virtual Machine Adapter\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Version\"},{\"t\":3,\"p\":1,\"n\":\"Object Format\"},{\"t\":7,\"p\":1,\"n\":\"Scripts\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Script\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"scriptName\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":7,\"p\":1,\"n\":\"Properties\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Property\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"propertyName\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]},{\"t\":2,\"p\":1,\"n\":\"String\"},{\"t\":3,\"p\":1,\"n\":\"Int32\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":3,\"p\":1,\"n\":\"Bool\"},{\"t\":7,\"p\":1,\"n\":\"Array of Object\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]}]},{\"t\":7,\"p\":1,\"n\":\"Array of String\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Int32\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Float\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Bool\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]}]}]}]}]},{\"t\":6,\"p\":1,\"n\":\"Script Fragments\",\"c\":[{\"t\":3,\"n\":\"Unknown\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":2,\"p\":1,\"n\":\"fileName\"},{\"t\":7,\"p\":1,\"n\":\"Fragments\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Fragment\",\"c\":[{\"t\":3,\"n\":\"Unknown\"},{\"t\":2,\"p\":1,\"n\":\"scriptName\"},{\"t\":2,\"p\":1,\"n\":\"fragmentName\"}]}]}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"PKDT - Pack Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"General Flags\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Interrupt Override\"},{\"t\":3,\"p\":1,\"n\":\"Preferred Speed\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":3,\"p\":1,\"n\":\"Interrupt Flags\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"PSDT - Schedule\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Month\"},{\"t\":3,\"p\":1,\"n\":\"Day of week\"},{\"t\":3,\"p\":1,\"n\":\"Date\"},{\"t\":3,\"p\":1,\"n\":\"Hour\"},{\"t\":3,\"p\":1,\"n\":\"Minute\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Duration (minutes)\"}]},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Conditions\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Condition\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"CTDA - \",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":5,\"p\":1,\"n\":\"Comparison Value - Float\"},{\"t\":3,\"p\":1,\"n\":\"Comparison Value - Global\"},{\"t\":3,\"p\":1,\"n\":\"Function\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":11,\"p\":1,\"n\":\"None\"},{\"t\":3,\"p\":1,\"n\":\"Integer\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":11,\"p\":1,\"n\":\"Variable Name (unused)\"},{\"t\":3,\"p\":1,\"n\":\"Sex\"},{\"t\":3,\"p\":1,\"n\":\"Actor Value\"},{\"t\":3,\"p\":1,\"n\":\"Crime Type\"},{\"t\":3,\"p\":1,\"n\":\"Axis\"},{\"t\":3,\"p\":1,\"n\":\"Quest Stage (unused)\"},{\"t\":3,\"p\":1,\"n\":\"Misc Stat\"},{\"t\":3,\"p\":1,\"n\":\"Alignment\"},{\"t\":3,\"p\":1,\"n\":\"Equip Type\"},{\"t\":3,\"p\":1,\"n\":\"Form Type\"},{\"t\":3,\"p\":1,\"n\":\"Critical Stage\"},{\"t\":3,\"p\":1,\"n\":\"Object Reference\"},{\"t\":3,\"p\":1,\"n\":\"Inventory Object\"},{\"t\":3,\"p\":1,\"n\":\"Actor\"},{\"t\":3,\"p\":1,\"n\":\"Voice Type\"},{\"t\":3,\"p\":1,\"n\":\"Idle\"},{\"t\":3,\"p\":1,\"n\":\"Form List\"},{\"t\":3,\"p\":1,\"n\":\"Quest\"},{\"t\":3,\"p\":1,\"n\":\"Faction\"},{\"t\":3,\"p\":1,\"n\":\"Cell\"},{\"t\":3,\"p\":1,\"n\":\"Class\"},{\"t\":3,\"p\":1,\"n\":\"Race\"},{\"t\":3,\"p\":1,\"n\":\"Actor Base\"},{\"t\":3,\"p\":1,\"n\":\"Global\"},{\"t\":3,\"p\":1,\"n\":\"Weather\"},{\"t\":3,\"p\":1,\"n\":\"Package\"},{\"t\":3,\"p\":1,\"n\":\"Encounter Zone\"},{\"t\":3,\"p\":1,\"n\":\"Perk\"},{\"t\":3,\"p\":1,\"n\":\"Owner\"},{\"t\":3,\"p\":1,\"n\":\"Furniture\"},{\"t\":3,\"p\":1,\"n\":\"Effect Item\"},{\"t\":3,\"p\":1,\"n\":\"Base Effect\"},{\"t\":3,\"p\":1,\"n\":\"Worldspace\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Function\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Param (INVALID)\"},{\"t\":3,\"p\":1,\"n\":\"Referenceable Object\"},{\"t\":3,\"p\":1,\"n\":\"Region\"},{\"t\":3,\"p\":1,\"n\":\"Keyword\"},{\"t\":3,\"p\":1,\"n\":\"Player Action\"},{\"t\":3,\"p\":1,\"n\":\"Casting Type\"},{\"t\":3,\"p\":1,\"n\":\"Shout\"},{\"t\":3,\"p\":1,\"n\":\"Location\"},{\"t\":3,\"p\":1,\"n\":\"Location Ref Type\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"Packdata ID\"},{\"t\":3,\"p\":1,\"n\":\"Association Type\"},{\"t\":3,\"p\":1,\"n\":\"Furniture Anim\"},{\"t\":3,\"p\":1,\"n\":\"Furniture Entry\"},{\"t\":3,\"p\":1,\"n\":\"Scene\"},{\"t\":3,\"p\":1,\"n\":\"Ward State\"},{\"t\":3,\"p\":1,\"n\":\"Event\"},{\"t\":3,\"p\":1,\"n\":\"Event Data\"},{\"t\":3,\"p\":1,\"n\":\"Quest Stage\"},{\"t\":3,\"p\":1,\"n\":\"Weapon\"},{\"t\":3,\"p\":1,\"n\":\"Weapon List\"},{\"t\":3,\"p\":1,\"n\":\"Target\"},{\"t\":3,\"p\":1,\"n\":\"Target List\"},{\"t\":3,\"p\":1,\"n\":\"Target Part\"},{\"t\":3,\"p\":1,\"n\":\"VATS Action\"},{\"t\":3,\"p\":1,\"n\":\"Critical Effect\"},{\"t\":3,\"p\":1,\"n\":\"Critical Effect List\"},{\"t\":3,\"p\":1,\"n\":\"Weapon Type\"},{\"t\":3,\"p\":1,\"n\":\"Projectile Type\"},{\"t\":3,\"p\":1,\"n\":\"Delivery Type\"},{\"t\":3,\"p\":1,\"n\":\"Run On\"},{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":3,\"p\":1,\"n\":\"Parameter #3\"}]},{\"t\":2,\"p\":1,\"n\":\"CIS1 - Parameter #1\"},{\"t\":2,\"p\":1,\"n\":\"CIS2 - Parameter #2\"}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Idle Animations\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"IDLF - Flags\"},{\"t\":6,\"p\":1,\"n\":\"IDLC - \",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Animation Count\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":5,\"p\":1,\"n\":\"IDLT - Idle Timer Setting\"},{\"t\":7,\"p\":1,\"n\":\"IDLA - Animations\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Animation\"}]},{\"t\":11,\"n\":\"IDLB - Unknown\"}]},{\"t\":3,\"p\":1,\"n\":\"CNAM - Combat Style\"},{\"t\":3,\"p\":1,\"n\":\"QNAM - Owner Quest\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"PKCU - Counter\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Data Input Count\"},{\"t\":3,\"p\":1,\"n\":\"Package Template\"},{\"t\":3,\"p\":1,\"n\":\"Version Counter (autoincremented)\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Package Data\",\"c\":[{\"t\":8,\"p\":1,\"n\":\"Data Input Values\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Value\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"ANAM - Type\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":3,\"p\":1,\"n\":\"Bool\"},{\"t\":3,\"p\":1,\"n\":\"Integer\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":11,\"n\":\"BNAM - Unknown\"},{\"t\":8,\"p\":1,\"n\":\"Topic\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"PDTO - Topic Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Topic\"},{\"t\":2,\"p\":1,\"n\":\"Subtype\"}]}]},{\"t\":6,\"p\":1,\"n\":\"PLDT - Location\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":3,\"p\":1,\"n\":\"Cell\"},{\"t\":11,\"p\":1,\"n\":\"Near Package Start Location\"},{\"t\":11,\"p\":1,\"n\":\"Near Editor Location\"},{\"t\":3,\"p\":1,\"n\":\"Object ID\"},{\"t\":3,\"p\":1,\"n\":\"Object Type\"},{\"t\":3,\"p\":1,\"n\":\"Keyword\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":3,\"p\":1,\"n\":\"Radius\"}]},{\"t\":6,\"p\":1,\"n\":\"PTDA - Target\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Target Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":3,\"p\":1,\"n\":\"Object ID\"},{\"t\":3,\"p\":1,\"n\":\"Object Type\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":3,\"p\":1,\"n\":\"Count \\/ Distance\"}]}]},{\"t\":11,\"n\":\"TPIC - Unknown\"}]}]},{\"t\":8,\"p\":1,\"n\":\"Data Inputs\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Data Input\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"UNAM - Index\"},{\"t\":2,\"p\":1,\"n\":\"BNAM - Name\"},{\"t\":3,\"p\":1,\"n\":\"PNAM - Flags\"}]}]}]},{\"t\":11,\"n\":\"XNAM - Marker\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Procedure Tree\",\"c\":[{\"t\":8,\"p\":1,\"n\":\"Branches\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Branch\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"ANAM - Branch Type\"},{\"t\":3,\"p\":1,\"n\":\"CITC - Condition Count\"},{\"t\":8,\"p\":1,\"n\":\"Conditions\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Condition\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"CTDA - \",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":5,\"p\":1,\"n\":\"Comparison Value - Float\"},{\"t\":3,\"p\":1,\"n\":\"Comparison Value - Global\"},{\"t\":3,\"p\":1,\"n\":\"Function\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":11,\"p\":1,\"n\":\"None\"},{\"t\":3,\"p\":1,\"n\":\"Integer\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":11,\"p\":1,\"n\":\"Variable Name (unused)\"},{\"t\":3,\"p\":1,\"n\":\"Sex\"},{\"t\":3,\"p\":1,\"n\":\"Actor Value\"},{\"t\":3,\"p\":1,\"n\":\"Crime Type\"},{\"t\":3,\"p\":1,\"n\":\"Axis\"},{\"t\":3,\"p\":1,\"n\":\"Quest Stage (unused)\"},{\"t\":3,\"p\":1,\"n\":\"Misc Stat\"},{\"t\":3,\"p\":1,\"n\":\"Alignment\"},{\"t\":3,\"p\":1,\"n\":\"Equip Type\"},{\"t\":3,\"p\":1,\"n\":\"Form Type\"},{\"t\":3,\"p\":1,\"n\":\"Critical Stage\"},{\"t\":3,\"p\":1,\"n\":\"Object Reference\"},{\"t\":3,\"p\":1,\"n\":\"Inventory Object\"},{\"t\":3,\"p\":1,\"n\":\"Actor\"},{\"t\":3,\"p\":1,\"n\":\"Voice Type\"},{\"t\":3,\"p\":1,\"n\":\"Idle\"},{\"t\":3,\"p\":1,\"n\":\"Form List\"},{\"t\":3,\"p\":1,\"n\":\"Quest\"},{\"t\":3,\"p\":1,\"n\":\"Faction\"},{\"t\":3,\"p\":1,\"n\":\"Cell\"},{\"t\":3,\"p\":1,\"n\":\"Class\"},{\"t\":3,\"p\":1,\"n\":\"Race\"},{\"t\":3,\"p\":1,\"n\":\"Actor Base\"},{\"t\":3,\"p\":1,\"n\":\"Global\"},{\"t\":3,\"p\":1,\"n\":\"Weather\"},{\"t\":3,\"p\":1,\"n\":\"Package\"},{\"t\":3,\"p\":1,\"n\":\"Encounter Zone\"},{\"t\":3,\"p\":1,\"n\":\"Perk\"},{\"t\":3,\"p\":1,\"n\":\"Owner\"},{\"t\":3,\"p\":1,\"n\":\"Furniture\"},{\"t\":3,\"p\":1,\"n\":\"Effect Item\"},{\"t\":3,\"p\":1,\"n\":\"Base Effect\"},{\"t\":3,\"p\":1,\"n\":\"Worldspace\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Function\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Param (INVALID)\"},{\"t\":3,\"p\":1,\"n\":\"Referenceable Object\"},{\"t\":3,\"p\":1,\"n\":\"Region\"},{\"t\":3,\"p\":1,\"n\":\"Keyword\"},{\"t\":3,\"p\":1,\"n\":\"Player Action\"},{\"t\":3,\"p\":1,\"n\":\"Casting Type\"},{\"t\":3,\"p\":1,\"n\":\"Shout\"},{\"t\":3,\"p\":1,\"n\":\"Location\"},{\"t\":3,\"p\":1,\"n\":\"Location Ref Type\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"Packdata ID\"},{\"t\":3,\"p\":1,\"n\":\"Association Type\"},{\"t\":3,\"p\":1,\"n\":\"Furniture Anim\"},{\"t\":3,\"p\":1,\"n\":\"Furniture Entry\"},{\"t\":3,\"p\":1,\"n\":\"Scene\"},{\"t\":3,\"p\":1,\"n\":\"Ward State\"},{\"t\":3,\"p\":1,\"n\":\"Event\"},{\"t\":3,\"p\":1,\"n\":\"Event Data\"},{\"t\":3,\"p\":1,\"n\":\"Quest Stage\"},{\"t\":3,\"p\":1,\"n\":\"Weapon\"},{\"t\":3,\"p\":1,\"n\":\"Weapon List\"},{\"t\":3,\"p\":1,\"n\":\"Target\"},{\"t\":3,\"p\":1,\"n\":\"Target List\"},{\"t\":3,\"p\":1,\"n\":\"Target Part\"},{\"t\":3,\"p\":1,\"n\":\"VATS Action\"},{\"t\":3,\"p\":1,\"n\":\"Critical Effect\"},{\"t\":3,\"p\":1,\"n\":\"Critical Effect List\"},{\"t\":3,\"p\":1,\"n\":\"Weapon Type\"},{\"t\":3,\"p\":1,\"n\":\"Projectile Type\"},{\"t\":3,\"p\":1,\"n\":\"Delivery Type\"},{\"t\":3,\"p\":1,\"n\":\"Run On\"},{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":3,\"p\":1,\"n\":\"Parameter #3\"}]},{\"t\":2,\"p\":1,\"n\":\"CIS1 - Parameter #1\"},{\"t\":2,\"p\":1,\"n\":\"CIS2 - Parameter #2\"}]}]},{\"t\":6,\"p\":1,\"n\":\"PRCB - Root\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Branch Count\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"}]},{\"t\":2,\"p\":1,\"n\":\"PNAM - Procedure Type\"},{\"t\":3,\"p\":1,\"n\":\"FNAM - Flags\"},{\"t\":8,\"p\":1,\"n\":\"Data Input Indexes\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"PKC2 - Index\"}]},{\"t\":8,\"p\":1,\"n\":\"Flags Override\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"PFO2 - Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Set General Flags\"},{\"t\":3,\"p\":1,\"n\":\"Clear General Flags\"},{\"t\":3,\"p\":1,\"n\":\"Set Interrupt Flags\"},{\"t\":3,\"p\":1,\"n\":\"Clear Interrupt Flags\"},{\"t\":3,\"p\":1,\"n\":\"Preferred Speed Override\"},{\"t\":11,\"n\":\"Unknown\"}]}]},{\"t\":8,\"n\":\"Unknown\",\"c\":[{\"t\":11,\"n\":\"PFOR - Unknown\"}]}]}]}]},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Data Inputs\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Data Input\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"UNAM - Index\"},{\"t\":2,\"p\":1,\"n\":\"BNAM - Name\"},{\"t\":3,\"p\":1,\"n\":\"PNAM - Flags\"}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"OnBegin\",\"c\":[{\"p\":1,\"n\":\"POBA - OnBegin Marker\"},{\"t\":3,\"p\":1,\"n\":\"INAM - Idle\"},{\"t\":11,\"n\":\"SCHR - Unused\"},{\"t\":11,\"n\":\"SCTX - Unused\"},{\"t\":11,\"n\":\"QNAM - Unused\"},{\"t\":11,\"n\":\"TNAM - Unused\"},{\"t\":8,\"p\":1,\"n\":\"Topic\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"PDTO - Topic Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Topic\"},{\"t\":2,\"p\":1,\"n\":\"Subtype\"}]}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"OnEnd\",\"c\":[{\"p\":1,\"n\":\"POEA - OnEnd Marker\"},{\"t\":3,\"p\":1,\"n\":\"INAM - Idle\"},{\"t\":11,\"n\":\"SCHR - Unused\"},{\"t\":11,\"n\":\"SCTX - Unused\"},{\"t\":11,\"n\":\"QNAM - Unused\"},{\"t\":11,\"n\":\"TNAM - Unused\"},{\"t\":8,\"p\":1,\"n\":\"Topic\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"PDTO - Topic Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Topic\"},{\"t\":2,\"p\":1,\"n\":\"Subtype\"}]}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"OnChange\",\"c\":[{\"p\":1,\"n\":\"POCA - OnChange Marker\"},{\"t\":3,\"p\":1,\"n\":\"INAM - Idle\"},{\"t\":11,\"n\":\"SCHR - Unused\"},{\"t\":11,\"n\":\"SCDA - Unused\"},{\"t\":11,\"n\":\"SCTX - Unused\"},{\"t\":11,\"n\":\"QNAM - Unused\"},{\"t\":11,\"n\":\"TNAM - Unused\"},{\"t\":8,\"p\":1,\"n\":\"Topic\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"PDTO - Topic Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Topic\"},{\"t\":2,\"p\":1,\"n\":\"Subtype\"}]}]}]}]},{\"t\":1,\"p\":1,\"n\":\"PARW - Placed Arrow\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"VMAD - Virtual Machine Adapter\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Version\"},{\"t\":3,\"p\":1,\"n\":\"Object Format\"},{\"t\":7,\"p\":1,\"n\":\"Scripts\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Script\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"scriptName\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":7,\"p\":1,\"n\":\"Properties\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Property\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"propertyName\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]},{\"t\":2,\"p\":1,\"n\":\"String\"},{\"t\":3,\"p\":1,\"n\":\"Int32\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":3,\"p\":1,\"n\":\"Bool\"},{\"t\":7,\"p\":1,\"n\":\"Array of Object\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]}]},{\"t\":7,\"p\":1,\"n\":\"Array of String\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Int32\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Float\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Bool\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]}]}]}]}]}]},{\"t\":3,\"p\":1,\"n\":\"NAME - Projectile\"},{\"t\":3,\"p\":1,\"n\":\"XEZN - Encounter Zone\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Ownership\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"XOWN - Owner\"},{\"t\":3,\"p\":1,\"n\":\"XRNK - Faction rank\"}]},{\"t\":5,\"p\":1,\"n\":\"XHTW - Head-Tracking Weight\"},{\"t\":5,\"p\":1,\"n\":\"XFVC - Favor Cost\"},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Reflected\\/Refracted By\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"XPWR - Water\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":3,\"p\":1,\"n\":\"Type\"}]}]},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Linked References\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"XLKR - Linked Reference\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Keyword\\/Ref\"},{\"t\":3,\"p\":1,\"n\":\"Ref\"}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Activate Parents\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"XAPD - Flags\"},{\"t\":8,\"p\":1,\"n\":\"Activate Parent Refs\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"XAPR - Activate Parent Ref\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":5,\"p\":1,\"n\":\"Delay\"}]}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"XESP - Enable Parent\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":3,\"p\":1,\"n\":\"XEMI - Emittance\"},{\"t\":3,\"p\":1,\"n\":\"XMBR - MultiBound Reference\"},{\"p\":1,\"n\":\"XIS2 - Ignored by Sandbox\"},{\"t\":7,\"p\":1,\"n\":\"XLRT - Location Ref Type\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Ref\"}]},{\"t\":3,\"p\":1,\"n\":\"XLRL - Location Reference\"},{\"t\":7,\"n\":\"XLOD - Distant LOD Data\",\"c\":[{\"t\":5,\"n\":\"Unknown\"}]},{\"t\":5,\"p\":1,\"n\":\"XSCL - Scale\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DATA - Position\\/Rotation\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Position\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"X\"},{\"t\":5,\"p\":1,\"n\":\"Y\"},{\"t\":5,\"p\":1,\"n\":\"Z\"}]},{\"t\":6,\"p\":1,\"n\":\"Rotation\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"X\"},{\"t\":5,\"p\":1,\"n\":\"Y\"},{\"t\":5,\"p\":1,\"n\":\"Z\"}]}]}]},{\"t\":1,\"p\":1,\"n\":\"PBAR - Placed Barrier\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"VMAD - Virtual Machine Adapter\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Version\"},{\"t\":3,\"p\":1,\"n\":\"Object Format\"},{\"t\":7,\"p\":1,\"n\":\"Scripts\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Script\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"scriptName\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":7,\"p\":1,\"n\":\"Properties\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Property\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"propertyName\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]},{\"t\":2,\"p\":1,\"n\":\"String\"},{\"t\":3,\"p\":1,\"n\":\"Int32\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":3,\"p\":1,\"n\":\"Bool\"},{\"t\":7,\"p\":1,\"n\":\"Array of Object\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]}]},{\"t\":7,\"p\":1,\"n\":\"Array of String\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Int32\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Float\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Bool\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]}]}]}]}]}]},{\"t\":3,\"p\":1,\"n\":\"NAME - Projectile\"},{\"t\":3,\"p\":1,\"n\":\"XEZN - Encounter Zone\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Ownership\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"XOWN - Owner\"},{\"t\":3,\"p\":1,\"n\":\"XRNK - Faction rank\"}]},{\"t\":5,\"p\":1,\"n\":\"XHTW - Head-Tracking Weight\"},{\"t\":5,\"p\":1,\"n\":\"XFVC - Favor Cost\"},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Reflected\\/Refracted By\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"XPWR - Water\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":3,\"p\":1,\"n\":\"Type\"}]}]},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Linked References\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"XLKR - Linked Reference\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Keyword\\/Ref\"},{\"t\":3,\"p\":1,\"n\":\"Ref\"}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Activate Parents\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"XAPD - Flags\"},{\"t\":8,\"p\":1,\"n\":\"Activate Parent Refs\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"XAPR - Activate Parent Ref\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":5,\"p\":1,\"n\":\"Delay\"}]}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"XESP - Enable Parent\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":3,\"p\":1,\"n\":\"XEMI - Emittance\"},{\"t\":3,\"p\":1,\"n\":\"XMBR - MultiBound Reference\"},{\"p\":1,\"n\":\"XIS2 - Ignored by Sandbox\"},{\"t\":7,\"p\":1,\"n\":\"XLRT - Location Ref Type\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Ref\"}]},{\"t\":3,\"p\":1,\"n\":\"XLRL - Location Reference\"},{\"t\":7,\"n\":\"XLOD - Distant LOD Data\",\"c\":[{\"t\":5,\"n\":\"Unknown\"}]},{\"t\":5,\"p\":1,\"n\":\"XSCL - Scale\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DATA - Position\\/Rotation\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Position\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"X\"},{\"t\":5,\"p\":1,\"n\":\"Y\"},{\"t\":5,\"p\":1,\"n\":\"Z\"}]},{\"t\":6,\"p\":1,\"n\":\"Rotation\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"X\"},{\"t\":5,\"p\":1,\"n\":\"Y\"},{\"t\":5,\"p\":1,\"n\":\"Z\"}]}]}]},{\"t\":1,\"p\":1,\"n\":\"PBEA - Placed Beam\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"VMAD - Virtual Machine Adapter\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Version\"},{\"t\":3,\"p\":1,\"n\":\"Object Format\"},{\"t\":7,\"p\":1,\"n\":\"Scripts\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Script\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"scriptName\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":7,\"p\":1,\"n\":\"Properties\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Property\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"propertyName\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]},{\"t\":2,\"p\":1,\"n\":\"String\"},{\"t\":3,\"p\":1,\"n\":\"Int32\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":3,\"p\":1,\"n\":\"Bool\"},{\"t\":7,\"p\":1,\"n\":\"Array of Object\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]}]},{\"t\":7,\"p\":1,\"n\":\"Array of String\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Int32\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Float\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Bool\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]}]}]}]}]}]},{\"t\":3,\"p\":1,\"n\":\"NAME - Projectile\"},{\"t\":3,\"p\":1,\"n\":\"XEZN - Encounter Zone\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Ownership\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"XOWN - Owner\"},{\"t\":3,\"p\":1,\"n\":\"XRNK - Faction rank\"}]},{\"t\":5,\"p\":1,\"n\":\"XHTW - Head-Tracking Weight\"},{\"t\":5,\"p\":1,\"n\":\"XFVC - Favor Cost\"},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Reflected\\/Refracted By\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"XPWR - Water\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":3,\"p\":1,\"n\":\"Type\"}]}]},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Linked References\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"XLKR - Linked Reference\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Keyword\\/Ref\"},{\"t\":3,\"p\":1,\"n\":\"Ref\"}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Activate Parents\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"XAPD - Flags\"},{\"t\":8,\"p\":1,\"n\":\"Activate Parent Refs\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"XAPR - Activate Parent Ref\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":5,\"p\":1,\"n\":\"Delay\"}]}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"XESP - Enable Parent\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":3,\"p\":1,\"n\":\"XEMI - Emittance\"},{\"t\":3,\"p\":1,\"n\":\"XMBR - MultiBound Reference\"},{\"p\":1,\"n\":\"XIS2 - Ignored by Sandbox\"},{\"t\":7,\"p\":1,\"n\":\"XLRT - Location Ref Type\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Ref\"}]},{\"t\":3,\"p\":1,\"n\":\"XLRL - Location Reference\"},{\"t\":7,\"n\":\"XLOD - Distant LOD Data\",\"c\":[{\"t\":5,\"n\":\"Unknown\"}]},{\"t\":5,\"p\":1,\"n\":\"XSCL - Scale\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DATA - Position\\/Rotation\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Position\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"X\"},{\"t\":5,\"p\":1,\"n\":\"Y\"},{\"t\":5,\"p\":1,\"n\":\"Z\"}]},{\"t\":6,\"p\":1,\"n\":\"Rotation\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"X\"},{\"t\":5,\"p\":1,\"n\":\"Y\"},{\"t\":5,\"p\":1,\"n\":\"Z\"}]}]}]},{\"t\":1,\"p\":1,\"n\":\"PCON - Placed Cone\\/Voice\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"VMAD - Virtual Machine Adapter\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Version\"},{\"t\":3,\"p\":1,\"n\":\"Object Format\"},{\"t\":7,\"p\":1,\"n\":\"Scripts\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Script\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"scriptName\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":7,\"p\":1,\"n\":\"Properties\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Property\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"propertyName\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]},{\"t\":2,\"p\":1,\"n\":\"String\"},{\"t\":3,\"p\":1,\"n\":\"Int32\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":3,\"p\":1,\"n\":\"Bool\"},{\"t\":7,\"p\":1,\"n\":\"Array of Object\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]}]},{\"t\":7,\"p\":1,\"n\":\"Array of String\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Int32\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Float\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Bool\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]}]}]}]}]}]},{\"t\":3,\"p\":1,\"n\":\"NAME - Projectile\"},{\"t\":3,\"p\":1,\"n\":\"XEZN - Encounter Zone\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Ownership\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"XOWN - Owner\"},{\"t\":3,\"p\":1,\"n\":\"XRNK - Faction rank\"}]},{\"t\":5,\"p\":1,\"n\":\"XHTW - Head-Tracking Weight\"},{\"t\":5,\"p\":1,\"n\":\"XFVC - Favor Cost\"},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Reflected\\/Refracted By\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"XPWR - Water\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":3,\"p\":1,\"n\":\"Type\"}]}]},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Linked References\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"XLKR - Linked Reference\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Keyword\\/Ref\"},{\"t\":3,\"p\":1,\"n\":\"Ref\"}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Activate Parents\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"XAPD - Flags\"},{\"t\":8,\"p\":1,\"n\":\"Activate Parent Refs\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"XAPR - Activate Parent Ref\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":5,\"p\":1,\"n\":\"Delay\"}]}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"XESP - Enable Parent\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":3,\"p\":1,\"n\":\"XEMI - Emittance\"},{\"t\":3,\"p\":1,\"n\":\"XMBR - MultiBound Reference\"},{\"p\":1,\"n\":\"XIS2 - Ignored by Sandbox\"},{\"t\":7,\"p\":1,\"n\":\"XLRT - Location Ref Type\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Ref\"}]},{\"t\":3,\"p\":1,\"n\":\"XLRL - Location Reference\"},{\"t\":7,\"n\":\"XLOD - Distant LOD Data\",\"c\":[{\"t\":5,\"n\":\"Unknown\"}]},{\"t\":5,\"p\":1,\"n\":\"XSCL - Scale\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DATA - Position\\/Rotation\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Position\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"X\"},{\"t\":5,\"p\":1,\"n\":\"Y\"},{\"t\":5,\"p\":1,\"n\":\"Z\"}]},{\"t\":6,\"p\":1,\"n\":\"Rotation\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"X\"},{\"t\":5,\"p\":1,\"n\":\"Y\"},{\"t\":5,\"p\":1,\"n\":\"Z\"}]}]}]},{\"t\":1,\"p\":1,\"n\":\"PERK - Perk\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"VMAD - Virtual Machine Adapter\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Version\"},{\"t\":3,\"p\":1,\"n\":\"Object Format\"},{\"t\":7,\"p\":1,\"n\":\"Scripts\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Script\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"scriptName\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":7,\"p\":1,\"n\":\"Properties\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Property\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"propertyName\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]},{\"t\":2,\"p\":1,\"n\":\"String\"},{\"t\":3,\"p\":1,\"n\":\"Int32\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":3,\"p\":1,\"n\":\"Bool\"},{\"t\":7,\"p\":1,\"n\":\"Array of Object\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]}]},{\"t\":7,\"p\":1,\"n\":\"Array of String\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Int32\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Float\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Bool\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]}]}]}]}]},{\"t\":6,\"p\":1,\"n\":\"Script Fragments\",\"c\":[{\"t\":3,\"n\":\"Unknown\"},{\"t\":2,\"p\":1,\"n\":\"fileName\"},{\"t\":7,\"p\":1,\"n\":\"Fragments\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Fragment\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Fragment Index\"},{\"t\":3,\"n\":\"Unknown\"},{\"t\":2,\"p\":1,\"n\":\"scriptName\"},{\"t\":2,\"p\":1,\"n\":\"fragmentName\"}]}]}]}]},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":2,\"p\":1,\"n\":\"DESC - Description\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Icon\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"ICON - Large Icon filename\"},{\"t\":2,\"p\":1,\"n\":\"MICO - Small Icon filename\"}]},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Conditions\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Condition\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"CTDA - \",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":5,\"p\":1,\"n\":\"Comparison Value - Float\"},{\"t\":3,\"p\":1,\"n\":\"Comparison Value - Global\"},{\"t\":3,\"p\":1,\"n\":\"Function\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":11,\"p\":1,\"n\":\"None\"},{\"t\":3,\"p\":1,\"n\":\"Integer\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":11,\"p\":1,\"n\":\"Variable Name (unused)\"},{\"t\":3,\"p\":1,\"n\":\"Sex\"},{\"t\":3,\"p\":1,\"n\":\"Actor Value\"},{\"t\":3,\"p\":1,\"n\":\"Crime Type\"},{\"t\":3,\"p\":1,\"n\":\"Axis\"},{\"t\":3,\"p\":1,\"n\":\"Quest Stage (unused)\"},{\"t\":3,\"p\":1,\"n\":\"Misc Stat\"},{\"t\":3,\"p\":1,\"n\":\"Alignment\"},{\"t\":3,\"p\":1,\"n\":\"Equip Type\"},{\"t\":3,\"p\":1,\"n\":\"Form Type\"},{\"t\":3,\"p\":1,\"n\":\"Critical Stage\"},{\"t\":3,\"p\":1,\"n\":\"Object Reference\"},{\"t\":3,\"p\":1,\"n\":\"Inventory Object\"},{\"t\":3,\"p\":1,\"n\":\"Actor\"},{\"t\":3,\"p\":1,\"n\":\"Voice Type\"},{\"t\":3,\"p\":1,\"n\":\"Idle\"},{\"t\":3,\"p\":1,\"n\":\"Form List\"},{\"t\":3,\"p\":1,\"n\":\"Quest\"},{\"t\":3,\"p\":1,\"n\":\"Faction\"},{\"t\":3,\"p\":1,\"n\":\"Cell\"},{\"t\":3,\"p\":1,\"n\":\"Class\"},{\"t\":3,\"p\":1,\"n\":\"Race\"},{\"t\":3,\"p\":1,\"n\":\"Actor Base\"},{\"t\":3,\"p\":1,\"n\":\"Global\"},{\"t\":3,\"p\":1,\"n\":\"Weather\"},{\"t\":3,\"p\":1,\"n\":\"Package\"},{\"t\":3,\"p\":1,\"n\":\"Encounter Zone\"},{\"t\":3,\"p\":1,\"n\":\"Perk\"},{\"t\":3,\"p\":1,\"n\":\"Owner\"},{\"t\":3,\"p\":1,\"n\":\"Furniture\"},{\"t\":3,\"p\":1,\"n\":\"Effect Item\"},{\"t\":3,\"p\":1,\"n\":\"Base Effect\"},{\"t\":3,\"p\":1,\"n\":\"Worldspace\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Function\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Param (INVALID)\"},{\"t\":3,\"p\":1,\"n\":\"Referenceable Object\"},{\"t\":3,\"p\":1,\"n\":\"Region\"},{\"t\":3,\"p\":1,\"n\":\"Keyword\"},{\"t\":3,\"p\":1,\"n\":\"Player Action\"},{\"t\":3,\"p\":1,\"n\":\"Casting Type\"},{\"t\":3,\"p\":1,\"n\":\"Shout\"},{\"t\":3,\"p\":1,\"n\":\"Location\"},{\"t\":3,\"p\":1,\"n\":\"Location Ref Type\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"Packdata ID\"},{\"t\":3,\"p\":1,\"n\":\"Association Type\"},{\"t\":3,\"p\":1,\"n\":\"Furniture Anim\"},{\"t\":3,\"p\":1,\"n\":\"Furniture Entry\"},{\"t\":3,\"p\":1,\"n\":\"Scene\"},{\"t\":3,\"p\":1,\"n\":\"Ward State\"},{\"t\":3,\"p\":1,\"n\":\"Event\"},{\"t\":3,\"p\":1,\"n\":\"Event Data\"},{\"t\":3,\"p\":1,\"n\":\"Quest Stage\"},{\"t\":3,\"p\":1,\"n\":\"Weapon\"},{\"t\":3,\"p\":1,\"n\":\"Weapon List\"},{\"t\":3,\"p\":1,\"n\":\"Target\"},{\"t\":3,\"p\":1,\"n\":\"Target List\"},{\"t\":3,\"p\":1,\"n\":\"Target Part\"},{\"t\":3,\"p\":1,\"n\":\"VATS Action\"},{\"t\":3,\"p\":1,\"n\":\"Critical Effect\"},{\"t\":3,\"p\":1,\"n\":\"Critical Effect List\"},{\"t\":3,\"p\":1,\"n\":\"Weapon Type\"},{\"t\":3,\"p\":1,\"n\":\"Projectile Type\"},{\"t\":3,\"p\":1,\"n\":\"Delivery Type\"},{\"t\":3,\"p\":1,\"n\":\"Run On\"},{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":3,\"p\":1,\"n\":\"Parameter #3\"}]},{\"t\":2,\"p\":1,\"n\":\"CIS1 - Parameter #1\"},{\"t\":2,\"p\":1,\"n\":\"CIS2 - Parameter #2\"}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DATA - Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Trait\"},{\"t\":3,\"p\":1,\"n\":\"Level\"},{\"t\":3,\"p\":1,\"n\":\"Num Ranks\"},{\"t\":3,\"p\":1,\"n\":\"Playable\"},{\"t\":3,\"p\":1,\"n\":\"Hidden\"}]},{\"t\":3,\"p\":1,\"n\":\"NNAM - Next Perk\"},{\"t\":10,\"p\":1,\"n\":\"Effects\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Effect\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"PRKE - Header\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Rank\"},{\"t\":3,\"p\":1,\"n\":\"Priority\"}]},{\"t\":6,\"p\":1,\"n\":\"Quest + Stage\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Quest\"},{\"t\":3,\"p\":1,\"n\":\"Quest Stage\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":3,\"p\":1,\"n\":\"Ability\"},{\"t\":6,\"p\":1,\"n\":\"Entry Point\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Entry Point\"},{\"t\":3,\"p\":1,\"n\":\"Function\"},{\"t\":3,\"p\":1,\"n\":\"Perk Condition Tab Count\"}]},{\"t\":10,\"p\":1,\"n\":\"Perk Conditions\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Perk Condition\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"PRKC - Run On (Tab Index)\"},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Conditions\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Condition\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"CTDA - \",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":11,\"p\":1,\"n\":\"Unused\"},{\"t\":5,\"p\":1,\"n\":\"Comparison Value - Float\"},{\"t\":3,\"p\":1,\"n\":\"Comparison Value - Global\"},{\"t\":3,\"p\":1,\"n\":\"Function\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":11,\"p\":1,\"n\":\"None\"},{\"t\":3,\"p\":1,\"n\":\"Integer\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":11,\"p\":1,\"n\":\"Variable Name (unused)\"},{\"t\":3,\"p\":1,\"n\":\"Sex\"},{\"t\":3,\"p\":1,\"n\":\"Actor Value\"},{\"t\":3,\"p\":1,\"n\":\"Crime Type\"},{\"t\":3,\"p\":1,\"n\":\"Axis\"},{\"t\":3,\"p\":1,\"n\":\"Quest Stage (unused)\"},{\"t\":3,\"p\":1,\"n\":\"Misc Stat\"},{\"t\":3,\"p\":1,\"n\":\"Alignment\"},{\"t\":3,\"p\":1,\"n\":\"Equip Type\"},{\"t\":3,\"p\":1,\"n\":\"Form Type\"},{\"t\":3,\"p\":1,\"n\":\"Critical Stage\"},{\"t\":3,\"p\":1,\"n\":\"Object Reference\"},{\"t\":3,\"p\":1,\"n\":\"Inventory Object\"},{\"t\":3,\"p\":1,\"n\":\"Actor\"},{\"t\":3,\"p\":1,\"n\":\"Voice Type\"},{\"t\":3,\"p\":1,\"n\":\"Idle\"},{\"t\":3,\"p\":1,\"n\":\"Form List\"},{\"t\":3,\"p\":1,\"n\":\"Quest\"},{\"t\":3,\"p\":1,\"n\":\"Faction\"},{\"t\":3,\"p\":1,\"n\":\"Cell\"},{\"t\":3,\"p\":1,\"n\":\"Class\"},{\"t\":3,\"p\":1,\"n\":\"Race\"},{\"t\":3,\"p\":1,\"n\":\"Actor Base\"},{\"t\":3,\"p\":1,\"n\":\"Global\"},{\"t\":3,\"p\":1,\"n\":\"Weather\"},{\"t\":3,\"p\":1,\"n\":\"Package\"},{\"t\":3,\"p\":1,\"n\":\"Encounter Zone\"},{\"t\":3,\"p\":1,\"n\":\"Perk\"},{\"t\":3,\"p\":1,\"n\":\"Owner\"},{\"t\":3,\"p\":1,\"n\":\"Furniture\"},{\"t\":3,\"p\":1,\"n\":\"Effect Item\"},{\"t\":3,\"p\":1,\"n\":\"Base Effect\"},{\"t\":3,\"p\":1,\"n\":\"Worldspace\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Function\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Param (INVALID)\"},{\"t\":3,\"p\":1,\"n\":\"Referenceable Object\"},{\"t\":3,\"p\":1,\"n\":\"Region\"},{\"t\":3,\"p\":1,\"n\":\"Keyword\"},{\"t\":3,\"p\":1,\"n\":\"Player Action\"},{\"t\":3,\"p\":1,\"n\":\"Casting Type\"},{\"t\":3,\"p\":1,\"n\":\"Shout\"},{\"t\":3,\"p\":1,\"n\":\"Location\"},{\"t\":3,\"p\":1,\"n\":\"Location Ref Type\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"Packdata ID\"},{\"t\":3,\"p\":1,\"n\":\"Association Type\"},{\"t\":3,\"p\":1,\"n\":\"Furniture Anim\"},{\"t\":3,\"p\":1,\"n\":\"Furniture Entry\"},{\"t\":3,\"p\":1,\"n\":\"Scene\"},{\"t\":3,\"p\":1,\"n\":\"Ward State\"},{\"t\":3,\"p\":1,\"n\":\"Event\"},{\"t\":3,\"p\":1,\"n\":\"Event Data\"},{\"t\":3,\"p\":1,\"n\":\"Quest Stage\"},{\"t\":3,\"p\":1,\"n\":\"Weapon\"},{\"t\":3,\"p\":1,\"n\":\"Weapon List\"},{\"t\":3,\"p\":1,\"n\":\"Target\"},{\"t\":3,\"p\":1,\"n\":\"Target List\"},{\"t\":3,\"p\":1,\"n\":\"Target Part\"},{\"t\":3,\"p\":1,\"n\":\"VATS Action\"},{\"t\":3,\"p\":1,\"n\":\"Critical Effect\"},{\"t\":3,\"p\":1,\"n\":\"Critical Effect List\"},{\"t\":3,\"p\":1,\"n\":\"Weapon Type\"},{\"t\":3,\"p\":1,\"n\":\"Projectile Type\"},{\"t\":3,\"p\":1,\"n\":\"Delivery Type\"},{\"t\":3,\"p\":1,\"n\":\"Run On\"},{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":3,\"p\":1,\"n\":\"Parameter #3\"}]},{\"t\":2,\"p\":1,\"n\":\"CIS1 - Parameter #1\"},{\"t\":2,\"p\":1,\"n\":\"CIS2 - Parameter #2\"}]}]}]}]},{\"t\":6,\"p\":1,\"n\":\"Function Parameters\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"EPFT - Type\"},{\"t\":2,\"p\":1,\"n\":\"EPF2 - Button Label\"},{\"t\":6,\"p\":1,\"n\":\"EPF3 - Script Flags\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Script Flags\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":11,\"n\":\"Unknown\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":6,\"p\":1,\"n\":\"Float, Float\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Float 1\"},{\"t\":5,\"p\":1,\"n\":\"Float 2\"}]},{\"t\":3,\"p\":1,\"n\":\"Leveled Item\"},{\"t\":3,\"p\":1,\"n\":\"Spell\"},{\"t\":2,\"p\":1,\"n\":\"Text\"},{\"t\":6,\"p\":1,\"n\":\"Actor Value, Float\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Actor Value\"},{\"t\":5,\"p\":1,\"n\":\"Float\"}]}]},{\"p\":1,\"n\":\"PRKF - End Marker\"}]}]}]},{\"t\":1,\"p\":1,\"n\":\"PFLA - Placed Flame\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"VMAD - Virtual Machine Adapter\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Version\"},{\"t\":3,\"p\":1,\"n\":\"Object Format\"},{\"t\":7,\"p\":1,\"n\":\"Scripts\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Script\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"scriptName\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":7,\"p\":1,\"n\":\"Properties\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Property\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"propertyName\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]},{\"t\":2,\"p\":1,\"n\":\"String\"},{\"t\":3,\"p\":1,\"n\":\"Int32\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":3,\"p\":1,\"n\":\"Bool\"},{\"t\":7,\"p\":1,\"n\":\"Array of Object\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]}]},{\"t\":7,\"p\":1,\"n\":\"Array of String\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Int32\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Float\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Bool\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]}]}]}]}]}]},{\"t\":3,\"p\":1,\"n\":\"NAME - Projectile\"},{\"t\":3,\"p\":1,\"n\":\"XEZN - Encounter Zone\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Ownership\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"XOWN - Owner\"},{\"t\":3,\"p\":1,\"n\":\"XRNK - Faction rank\"}]},{\"t\":5,\"p\":1,\"n\":\"XHTW - Head-Tracking Weight\"},{\"t\":5,\"p\":1,\"n\":\"XFVC - Favor Cost\"},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Reflected\\/Refracted By\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"XPWR - Water\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":3,\"p\":1,\"n\":\"Type\"}]}]},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Linked References\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"XLKR - Linked Reference\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Keyword\\/Ref\"},{\"t\":3,\"p\":1,\"n\":\"Ref\"}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Activate Parents\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"XAPD - Flags\"},{\"t\":8,\"p\":1,\"n\":\"Activate Parent Refs\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"XAPR - Activate Parent Ref\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":5,\"p\":1,\"n\":\"Delay\"}]}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"XESP - Enable Parent\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":3,\"p\":1,\"n\":\"XEMI - Emittance\"},{\"t\":3,\"p\":1,\"n\":\"XMBR - MultiBound Reference\"},{\"p\":1,\"n\":\"XIS2 - Ignored by Sandbox\"},{\"t\":7,\"p\":1,\"n\":\"XLRT - Location Ref Type\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Ref\"}]},{\"t\":3,\"p\":1,\"n\":\"XLRL - Location Reference\"},{\"t\":7,\"n\":\"XLOD - Distant LOD Data\",\"c\":[{\"t\":5,\"n\":\"Unknown\"}]},{\"t\":5,\"p\":1,\"n\":\"XSCL - Scale\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DATA - Position\\/Rotation\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Position\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"X\"},{\"t\":5,\"p\":1,\"n\":\"Y\"},{\"t\":5,\"p\":1,\"n\":\"Z\"}]},{\"t\":6,\"p\":1,\"n\":\"Rotation\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"X\"},{\"t\":5,\"p\":1,\"n\":\"Y\"},{\"t\":5,\"p\":1,\"n\":\"Z\"}]}]}]},{\"t\":1,\"p\":1,\"n\":\"PGRE - Placed Projectile\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"VMAD - Virtual Machine Adapter\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Version\"},{\"t\":3,\"p\":1,\"n\":\"Object Format\"},{\"t\":7,\"p\":1,\"n\":\"Scripts\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Script\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"scriptName\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":7,\"p\":1,\"n\":\"Properties\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Property\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"propertyName\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]},{\"t\":2,\"p\":1,\"n\":\"String\"},{\"t\":3,\"p\":1,\"n\":\"Int32\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":3,\"p\":1,\"n\":\"Bool\"},{\"t\":7,\"p\":1,\"n\":\"Array of Object\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]}]},{\"t\":7,\"p\":1,\"n\":\"Array of String\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Int32\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Float\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Bool\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]}]}]}]}]}]},{\"t\":3,\"p\":1,\"n\":\"NAME - Projectile\"},{\"t\":3,\"p\":1,\"n\":\"XEZN - Encounter Zone\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Ownership\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"XOWN - Owner\"},{\"t\":3,\"p\":1,\"n\":\"XRNK - Faction rank\"}]},{\"t\":5,\"p\":1,\"n\":\"XHTW - Head-Tracking Weight\"},{\"t\":5,\"p\":1,\"n\":\"XFVC - Favor Cost\"},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Reflected\\/Refracted By\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"XPWR - Water\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":3,\"p\":1,\"n\":\"Type\"}]}]},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Linked References\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"XLKR - Linked Reference\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Keyword\\/Ref\"},{\"t\":3,\"p\":1,\"n\":\"Ref\"}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Activate Parents\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"XAPD - Flags\"},{\"t\":8,\"p\":1,\"n\":\"Activate Parent Refs\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"XAPR - Activate Parent Ref\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":5,\"p\":1,\"n\":\"Delay\"}]}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"XESP - Enable Parent\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":3,\"p\":1,\"n\":\"XEMI - Emittance\"},{\"t\":3,\"p\":1,\"n\":\"XMBR - MultiBound Reference\"},{\"p\":1,\"n\":\"XIS2 - Ignored by Sandbox\"},{\"t\":7,\"p\":1,\"n\":\"XLRT - Location Ref Type\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Ref\"}]},{\"t\":3,\"p\":1,\"n\":\"XLRL - Location Reference\"},{\"t\":7,\"n\":\"XLOD - Distant LOD Data\",\"c\":[{\"t\":5,\"n\":\"Unknown\"}]},{\"t\":5,\"p\":1,\"n\":\"XSCL - Scale\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DATA - Position\\/Rotation\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Position\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"X\"},{\"t\":5,\"p\":1,\"n\":\"Y\"},{\"t\":5,\"p\":1,\"n\":\"Z\"}]},{\"t\":6,\"p\":1,\"n\":\"Rotation\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"X\"},{\"t\":5,\"p\":1,\"n\":\"Y\"},{\"t\":5,\"p\":1,\"n\":\"Z\"}]}]}]},{\"t\":1,\"p\":1,\"n\":\"PHZD - Placed Hazard\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"VMAD - Virtual Machine Adapter\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Version\"},{\"t\":3,\"p\":1,\"n\":\"Object Format\"},{\"t\":7,\"p\":1,\"n\":\"Scripts\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Script\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"scriptName\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":7,\"p\":1,\"n\":\"Properties\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Property\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"propertyName\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]},{\"t\":2,\"p\":1,\"n\":\"String\"},{\"t\":3,\"p\":1,\"n\":\"Int32\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":3,\"p\":1,\"n\":\"Bool\"},{\"t\":7,\"p\":1,\"n\":\"Array of Object\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]}]},{\"t\":7,\"p\":1,\"n\":\"Array of String\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Int32\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Float\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Bool\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]}]}]}]}]}]},{\"t\":3,\"p\":1,\"n\":\"NAME - Projectile\"},{\"t\":3,\"p\":1,\"n\":\"XEZN - Encounter Zone\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Ownership\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"XOWN - Owner\"},{\"t\":3,\"p\":1,\"n\":\"XRNK - Faction rank\"}]},{\"t\":5,\"p\":1,\"n\":\"XHTW - Head-Tracking Weight\"},{\"t\":5,\"p\":1,\"n\":\"XFVC - Favor Cost\"},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Reflected\\/Refracted By\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"XPWR - Water\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":3,\"p\":1,\"n\":\"Type\"}]}]},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Linked References\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"XLKR - Linked Reference\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Keyword\\/Ref\"},{\"t\":3,\"p\":1,\"n\":\"Ref\"}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Activate Parents\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"XAPD - Flags\"},{\"t\":8,\"p\":1,\"n\":\"Activate Parent Refs\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"XAPR - Activate Parent Ref\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":5,\"p\":1,\"n\":\"Delay\"}]}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"XESP - Enable Parent\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":3,\"p\":1,\"n\":\"XEMI - Emittance\"},{\"t\":3,\"p\":1,\"n\":\"XMBR - MultiBound Reference\"},{\"p\":1,\"n\":\"XIS2 - Ignored by Sandbox\"},{\"t\":7,\"p\":1,\"n\":\"XLRT - Location Ref Type\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Ref\"}]},{\"t\":3,\"p\":1,\"n\":\"XLRL - Location Reference\"},{\"t\":7,\"n\":\"XLOD - Distant LOD Data\",\"c\":[{\"t\":5,\"n\":\"Unknown\"}]},{\"t\":5,\"p\":1,\"n\":\"XSCL - Scale\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DATA - Position\\/Rotation\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Position\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"X\"},{\"t\":5,\"p\":1,\"n\":\"Y\"},{\"t\":5,\"p\":1,\"n\":\"Z\"}]},{\"t\":6,\"p\":1,\"n\":\"Rotation\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"X\"},{\"t\":5,\"p\":1,\"n\":\"Y\"},{\"t\":5,\"p\":1,\"n\":\"Z\"}]}]}]},{\"t\":1,\"p\":1,\"n\":\"PMIS - Placed Missile\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"VMAD - Virtual Machine Adapter\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Version\"},{\"t\":3,\"p\":1,\"n\":\"Object Format\"},{\"t\":7,\"p\":1,\"n\":\"Scripts\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Script\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"scriptName\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":7,\"p\":1,\"n\":\"Properties\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Property\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"propertyName\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]},{\"t\":2,\"p\":1,\"n\":\"String\"},{\"t\":3,\"p\":1,\"n\":\"Int32\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":3,\"p\":1,\"n\":\"Bool\"},{\"t\":7,\"p\":1,\"n\":\"Array of Object\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]}]},{\"t\":7,\"p\":1,\"n\":\"Array of String\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Int32\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Float\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Bool\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]}]}]}]}]}]},{\"t\":3,\"p\":1,\"n\":\"NAME - Projectile\"},{\"t\":3,\"p\":1,\"n\":\"XEZN - Encounter Zone\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Ownership\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"XOWN - Owner\"},{\"t\":3,\"p\":1,\"n\":\"XRNK - Faction rank\"}]},{\"t\":5,\"p\":1,\"n\":\"XHTW - Head-Tracking Weight\"},{\"t\":5,\"p\":1,\"n\":\"XFVC - Favor Cost\"},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Reflected\\/Refracted By\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"XPWR - Water\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":3,\"p\":1,\"n\":\"Type\"}]}]},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Linked References\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"XLKR - Linked Reference\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Keyword\\/Ref\"},{\"t\":3,\"p\":1,\"n\":\"Ref\"}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Activate Parents\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"XAPD - Flags\"},{\"t\":8,\"p\":1,\"n\":\"Activate Parent Refs\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"XAPR - Activate Parent Ref\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":5,\"p\":1,\"n\":\"Delay\"}]}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"XESP - Enable Parent\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":3,\"p\":1,\"n\":\"XEMI - Emittance\"},{\"t\":3,\"p\":1,\"n\":\"XMBR - MultiBound Reference\"},{\"p\":1,\"n\":\"XIS2 - Ignored by Sandbox\"},{\"t\":7,\"p\":1,\"n\":\"XLRT - Location Ref Type\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Ref\"}]},{\"t\":3,\"p\":1,\"n\":\"XLRL - Location Reference\"},{\"t\":7,\"n\":\"XLOD - Distant LOD Data\",\"c\":[{\"t\":5,\"n\":\"Unknown\"}]},{\"t\":5,\"p\":1,\"n\":\"XSCL - Scale\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DATA - Position\\/Rotation\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Position\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"X\"},{\"t\":5,\"p\":1,\"n\":\"Y\"},{\"t\":5,\"p\":1,\"n\":\"Z\"}]},{\"t\":6,\"p\":1,\"n\":\"Rotation\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"X\"},{\"t\":5,\"p\":1,\"n\":\"Y\"},{\"t\":5,\"p\":1,\"n\":\"Z\"}]}]}]},{\"t\":1,\"p\":1,\"n\":\"PROJ - Projectile\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"X1\"},{\"t\":3,\"p\":1,\"n\":\"Y1\"},{\"t\":3,\"p\":1,\"n\":\"Z1\"},{\"t\":3,\"p\":1,\"n\":\"X2\"},{\"t\":3,\"p\":1,\"n\":\"Y2\"},{\"t\":3,\"p\":1,\"n\":\"Z2\"}]},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"MODT - Texture Files Hashes\"},{\"t\":7,\"p\":1,\"n\":\"MODS - Alternate Textures\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"3D Name\"},{\"t\":3,\"p\":1,\"n\":\"New Texture\"},{\"t\":3,\"p\":1,\"n\":\"3D Index\"}]}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Destructable\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"DEST - Header\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Health\"},{\"t\":3,\"p\":1,\"n\":\"DEST Count\"},{\"t\":3,\"p\":1,\"n\":\"VATS Targetable\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":8,\"p\":1,\"n\":\"Stages\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Stage\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"DSTD - Destruction Stage Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Health %\"},{\"t\":3,\"p\":1,\"n\":\"Index\"},{\"t\":3,\"p\":1,\"n\":\"Model Damage Stage\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":3,\"p\":1,\"n\":\"Self Damage per Second\"},{\"t\":3,\"p\":1,\"n\":\"Explosion\"},{\"t\":3,\"p\":1,\"n\":\"Debris\"},{\"t\":3,\"p\":1,\"n\":\"Debris Count\"}]},{\"t\":6,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"DMDL - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"DMDT - Texture Files Hashes\"},{\"t\":7,\"p\":1,\"n\":\"DMDS - Alternate Textures\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"3D Name\"},{\"t\":3,\"p\":1,\"n\":\"New Texture\"},{\"t\":3,\"p\":1,\"n\":\"3D Index\"}]}]}]},{\"p\":1,\"n\":\"DSTF - End Marker\"}]}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DATA - Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":5,\"p\":1,\"n\":\"Gravity\"},{\"t\":5,\"p\":1,\"n\":\"Speed\"},{\"t\":5,\"p\":1,\"n\":\"Range\"},{\"t\":3,\"p\":1,\"n\":\"Light\"},{\"t\":3,\"p\":1,\"n\":\"Muzzle Flash - Light\"},{\"t\":5,\"p\":1,\"n\":\"Tracer Chance\"},{\"t\":5,\"p\":1,\"n\":\"Explosion - Alt. Trigger - Proximity\"},{\"t\":5,\"p\":1,\"n\":\"Explosion - Alt. Trigger - Timer\"},{\"t\":3,\"p\":1,\"n\":\"Explosion\"},{\"t\":3,\"p\":1,\"n\":\"Sound\"},{\"t\":5,\"p\":1,\"n\":\"Muzzle Flash - Duration\"},{\"t\":5,\"p\":1,\"n\":\"Fade Duration\"},{\"t\":5,\"p\":1,\"n\":\"Impact Force\"},{\"t\":3,\"p\":1,\"n\":\"Sound - Countdown\"},{\"t\":3,\"p\":1,\"n\":\"Sound - Disable\"},{\"t\":3,\"p\":1,\"n\":\"Default Weapon Source\"},{\"t\":5,\"p\":1,\"n\":\"Cone Spread\"},{\"t\":5,\"p\":1,\"n\":\"Collision Radius\"},{\"t\":5,\"p\":1,\"n\":\"Lifetime\"},{\"t\":5,\"p\":1,\"n\":\"Relaunch Interval\"},{\"t\":3,\"p\":1,\"n\":\"Decal Data\"},{\"t\":3,\"p\":1,\"n\":\"Collision Layer\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Muzzle Flash Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"NAM1 - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"NAM2 - Texture Files Hashes\"}]},{\"t\":3,\"p\":1,\"n\":\"VNAM - Sound Level\"}]},{\"t\":1,\"p\":1,\"n\":\"PWAT\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"}]},{\"t\":1,\"p\":1,\"n\":\"QUST - Quest\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"VMAD - Virtual Machine Adapter\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Version\"},{\"t\":3,\"p\":1,\"n\":\"Object Format\"},{\"t\":7,\"p\":1,\"n\":\"Scripts\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Script\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"scriptName\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":7,\"p\":1,\"n\":\"Properties\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Property\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"propertyName\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]},{\"t\":2,\"p\":1,\"n\":\"String\"},{\"t\":3,\"p\":1,\"n\":\"Int32\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":3,\"p\":1,\"n\":\"Bool\"},{\"t\":7,\"p\":1,\"n\":\"Array of Object\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]}]},{\"t\":7,\"p\":1,\"n\":\"Array of String\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Int32\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Float\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Bool\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]}]}]}]}]},{\"t\":6,\"p\":1,\"n\":\"Script Fragments\",\"c\":[{\"t\":3,\"n\":\"Unknown\"},{\"t\":3,\"p\":1,\"n\":\"fragmentCount\"},{\"t\":2,\"p\":1,\"n\":\"fileName\"},{\"t\":7,\"p\":1,\"n\":\"Fragments\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Fragment\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Quest Stage\"},{\"t\":3,\"n\":\"Unknown\"},{\"t\":3,\"p\":1,\"n\":\"Quest Stage Index\"},{\"t\":2,\"p\":1,\"n\":\"scriptName\"},{\"t\":2,\"p\":1,\"n\":\"fragmentName\"}]}]}]},{\"t\":7,\"p\":1,\"n\":\"Aliases\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alias\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]},{\"t\":3,\"p\":1,\"n\":\"Version\"},{\"t\":3,\"p\":1,\"n\":\"Object Format\"},{\"t\":7,\"p\":1,\"n\":\"Alias Scripts\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Script\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"scriptName\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":7,\"p\":1,\"n\":\"Properties\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Property\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"propertyName\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]},{\"t\":2,\"p\":1,\"n\":\"String\"},{\"t\":3,\"p\":1,\"n\":\"Int32\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":3,\"p\":1,\"n\":\"Bool\"},{\"t\":7,\"p\":1,\"n\":\"Array of Object\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]}]},{\"t\":7,\"p\":1,\"n\":\"Array of String\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Int32\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Float\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Bool\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]}]}]}]}]}]}]}]},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DNAM - General\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":3,\"p\":1,\"n\":\"Priority\"},{\"t\":3,\"p\":1,\"n\":\"Form Version\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":3,\"p\":1,\"n\":\"Type\"}]},{\"t\":2,\"p\":1,\"n\":\"ENAM - Event\"},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Text Display Globals\",\"d\":1,\"c\":[{\"t\":3,\"p\":1,\"n\":\"QTGL - Global\"}]},{\"t\":2,\"p\":1,\"n\":\"FLTR - Object Window Filter\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Quest Dialogue Conditions\",\"c\":[{\"t\":8,\"p\":1,\"n\":\"Conditions\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Condition\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"CTDA - \",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":5,\"p\":1,\"n\":\"Comparison Value - Float\"},{\"t\":3,\"p\":1,\"n\":\"Comparison Value - Global\"},{\"t\":3,\"p\":1,\"n\":\"Function\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":11,\"p\":1,\"n\":\"None\"},{\"t\":3,\"p\":1,\"n\":\"Integer\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":11,\"p\":1,\"n\":\"Variable Name (unused)\"},{\"t\":3,\"p\":1,\"n\":\"Sex\"},{\"t\":3,\"p\":1,\"n\":\"Actor Value\"},{\"t\":3,\"p\":1,\"n\":\"Crime Type\"},{\"t\":3,\"p\":1,\"n\":\"Axis\"},{\"t\":3,\"p\":1,\"n\":\"Quest Stage (unused)\"},{\"t\":3,\"p\":1,\"n\":\"Misc Stat\"},{\"t\":3,\"p\":1,\"n\":\"Alignment\"},{\"t\":3,\"p\":1,\"n\":\"Equip Type\"},{\"t\":3,\"p\":1,\"n\":\"Form Type\"},{\"t\":3,\"p\":1,\"n\":\"Critical Stage\"},{\"t\":3,\"p\":1,\"n\":\"Object Reference\"},{\"t\":3,\"p\":1,\"n\":\"Inventory Object\"},{\"t\":3,\"p\":1,\"n\":\"Actor\"},{\"t\":3,\"p\":1,\"n\":\"Voice Type\"},{\"t\":3,\"p\":1,\"n\":\"Idle\"},{\"t\":3,\"p\":1,\"n\":\"Form List\"},{\"t\":3,\"p\":1,\"n\":\"Quest\"},{\"t\":3,\"p\":1,\"n\":\"Faction\"},{\"t\":3,\"p\":1,\"n\":\"Cell\"},{\"t\":3,\"p\":1,\"n\":\"Class\"},{\"t\":3,\"p\":1,\"n\":\"Race\"},{\"t\":3,\"p\":1,\"n\":\"Actor Base\"},{\"t\":3,\"p\":1,\"n\":\"Global\"},{\"t\":3,\"p\":1,\"n\":\"Weather\"},{\"t\":3,\"p\":1,\"n\":\"Package\"},{\"t\":3,\"p\":1,\"n\":\"Encounter Zone\"},{\"t\":3,\"p\":1,\"n\":\"Perk\"},{\"t\":3,\"p\":1,\"n\":\"Owner\"},{\"t\":3,\"p\":1,\"n\":\"Furniture\"},{\"t\":3,\"p\":1,\"n\":\"Effect Item\"},{\"t\":3,\"p\":1,\"n\":\"Base Effect\"},{\"t\":3,\"p\":1,\"n\":\"Worldspace\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Function\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Param (INVALID)\"},{\"t\":3,\"p\":1,\"n\":\"Referenceable Object\"},{\"t\":3,\"p\":1,\"n\":\"Region\"},{\"t\":3,\"p\":1,\"n\":\"Keyword\"},{\"t\":3,\"p\":1,\"n\":\"Player Action\"},{\"t\":3,\"p\":1,\"n\":\"Casting Type\"},{\"t\":3,\"p\":1,\"n\":\"Shout\"},{\"t\":3,\"p\":1,\"n\":\"Location\"},{\"t\":3,\"p\":1,\"n\":\"Location Ref Type\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"Packdata ID\"},{\"t\":3,\"p\":1,\"n\":\"Association Type\"},{\"t\":3,\"p\":1,\"n\":\"Furniture Anim\"},{\"t\":3,\"p\":1,\"n\":\"Furniture Entry\"},{\"t\":3,\"p\":1,\"n\":\"Scene\"},{\"t\":3,\"p\":1,\"n\":\"Ward State\"},{\"t\":3,\"p\":1,\"n\":\"Event\"},{\"t\":3,\"p\":1,\"n\":\"Event Data\"},{\"t\":3,\"p\":1,\"n\":\"Quest Stage\"},{\"t\":3,\"p\":1,\"n\":\"Weapon\"},{\"t\":3,\"p\":1,\"n\":\"Weapon List\"},{\"t\":3,\"p\":1,\"n\":\"Target\"},{\"t\":3,\"p\":1,\"n\":\"Target List\"},{\"t\":3,\"p\":1,\"n\":\"Target Part\"},{\"t\":3,\"p\":1,\"n\":\"VATS Action\"},{\"t\":3,\"p\":1,\"n\":\"Critical Effect\"},{\"t\":3,\"p\":1,\"n\":\"Critical Effect List\"},{\"t\":3,\"p\":1,\"n\":\"Weapon Type\"},{\"t\":3,\"p\":1,\"n\":\"Projectile Type\"},{\"t\":3,\"p\":1,\"n\":\"Delivery Type\"},{\"t\":3,\"p\":1,\"n\":\"Run On\"},{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":3,\"p\":1,\"n\":\"Parameter #3\"}]},{\"t\":2,\"p\":1,\"n\":\"CIS1 - Parameter #1\"},{\"t\":2,\"p\":1,\"n\":\"CIS2 - Parameter #2\"}]}]}]},{\"p\":1,\"n\":\"NEXT - Marker\"},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Conditions\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Condition\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"CTDA - \",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":5,\"p\":1,\"n\":\"Comparison Value - Float\"},{\"t\":3,\"p\":1,\"n\":\"Comparison Value - Global\"},{\"t\":3,\"p\":1,\"n\":\"Function\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":11,\"p\":1,\"n\":\"None\"},{\"t\":3,\"p\":1,\"n\":\"Integer\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":11,\"p\":1,\"n\":\"Variable Name (unused)\"},{\"t\":3,\"p\":1,\"n\":\"Sex\"},{\"t\":3,\"p\":1,\"n\":\"Actor Value\"},{\"t\":3,\"p\":1,\"n\":\"Crime Type\"},{\"t\":3,\"p\":1,\"n\":\"Axis\"},{\"t\":3,\"p\":1,\"n\":\"Quest Stage (unused)\"},{\"t\":3,\"p\":1,\"n\":\"Misc Stat\"},{\"t\":3,\"p\":1,\"n\":\"Alignment\"},{\"t\":3,\"p\":1,\"n\":\"Equip Type\"},{\"t\":3,\"p\":1,\"n\":\"Form Type\"},{\"t\":3,\"p\":1,\"n\":\"Critical Stage\"},{\"t\":3,\"p\":1,\"n\":\"Object Reference\"},{\"t\":3,\"p\":1,\"n\":\"Inventory Object\"},{\"t\":3,\"p\":1,\"n\":\"Actor\"},{\"t\":3,\"p\":1,\"n\":\"Voice Type\"},{\"t\":3,\"p\":1,\"n\":\"Idle\"},{\"t\":3,\"p\":1,\"n\":\"Form List\"},{\"t\":3,\"p\":1,\"n\":\"Quest\"},{\"t\":3,\"p\":1,\"n\":\"Faction\"},{\"t\":3,\"p\":1,\"n\":\"Cell\"},{\"t\":3,\"p\":1,\"n\":\"Class\"},{\"t\":3,\"p\":1,\"n\":\"Race\"},{\"t\":3,\"p\":1,\"n\":\"Actor Base\"},{\"t\":3,\"p\":1,\"n\":\"Global\"},{\"t\":3,\"p\":1,\"n\":\"Weather\"},{\"t\":3,\"p\":1,\"n\":\"Package\"},{\"t\":3,\"p\":1,\"n\":\"Encounter Zone\"},{\"t\":3,\"p\":1,\"n\":\"Perk\"},{\"t\":3,\"p\":1,\"n\":\"Owner\"},{\"t\":3,\"p\":1,\"n\":\"Furniture\"},{\"t\":3,\"p\":1,\"n\":\"Effect Item\"},{\"t\":3,\"p\":1,\"n\":\"Base Effect\"},{\"t\":3,\"p\":1,\"n\":\"Worldspace\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Function\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Param (INVALID)\"},{\"t\":3,\"p\":1,\"n\":\"Referenceable Object\"},{\"t\":3,\"p\":1,\"n\":\"Region\"},{\"t\":3,\"p\":1,\"n\":\"Keyword\"},{\"t\":3,\"p\":1,\"n\":\"Player Action\"},{\"t\":3,\"p\":1,\"n\":\"Casting Type\"},{\"t\":3,\"p\":1,\"n\":\"Shout\"},{\"t\":3,\"p\":1,\"n\":\"Location\"},{\"t\":3,\"p\":1,\"n\":\"Location Ref Type\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"Packdata ID\"},{\"t\":3,\"p\":1,\"n\":\"Association Type\"},{\"t\":3,\"p\":1,\"n\":\"Furniture Anim\"},{\"t\":3,\"p\":1,\"n\":\"Furniture Entry\"},{\"t\":3,\"p\":1,\"n\":\"Scene\"},{\"t\":3,\"p\":1,\"n\":\"Ward State\"},{\"t\":3,\"p\":1,\"n\":\"Event\"},{\"t\":3,\"p\":1,\"n\":\"Event Data\"},{\"t\":3,\"p\":1,\"n\":\"Quest Stage\"},{\"t\":3,\"p\":1,\"n\":\"Weapon\"},{\"t\":3,\"p\":1,\"n\":\"Weapon List\"},{\"t\":3,\"p\":1,\"n\":\"Target\"},{\"t\":3,\"p\":1,\"n\":\"Target List\"},{\"t\":3,\"p\":1,\"n\":\"Target Part\"},{\"t\":3,\"p\":1,\"n\":\"VATS Action\"},{\"t\":3,\"p\":1,\"n\":\"Critical Effect\"},{\"t\":3,\"p\":1,\"n\":\"Critical Effect List\"},{\"t\":3,\"p\":1,\"n\":\"Weapon Type\"},{\"t\":3,\"p\":1,\"n\":\"Projectile Type\"},{\"t\":3,\"p\":1,\"n\":\"Delivery Type\"},{\"t\":3,\"p\":1,\"n\":\"Run On\"},{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":3,\"p\":1,\"n\":\"Parameter #3\"}]},{\"t\":2,\"p\":1,\"n\":\"CIS1 - Parameter #1\"},{\"t\":2,\"p\":1,\"n\":\"CIS2 - Parameter #2\"}]}]},{\"t\":10,\"s\":1,\"p\":1,\"n\":\"Stages\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Stage\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"INDX - Stage Index\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Stage Index\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":3,\"n\":\"Unknown\"}]},{\"t\":8,\"p\":1,\"n\":\"Log Entries\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Log Entry\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"QSDT - Stage Flags\"},{\"t\":8,\"p\":1,\"n\":\"Conditions\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Condition\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"CTDA - \",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":5,\"p\":1,\"n\":\"Comparison Value - Float\"},{\"t\":3,\"p\":1,\"n\":\"Comparison Value - Global\"},{\"t\":3,\"p\":1,\"n\":\"Function\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":11,\"p\":1,\"n\":\"None\"},{\"t\":3,\"p\":1,\"n\":\"Integer\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":11,\"p\":1,\"n\":\"Variable Name (unused)\"},{\"t\":3,\"p\":1,\"n\":\"Sex\"},{\"t\":3,\"p\":1,\"n\":\"Actor Value\"},{\"t\":3,\"p\":1,\"n\":\"Crime Type\"},{\"t\":3,\"p\":1,\"n\":\"Axis\"},{\"t\":3,\"p\":1,\"n\":\"Quest Stage (unused)\"},{\"t\":3,\"p\":1,\"n\":\"Misc Stat\"},{\"t\":3,\"p\":1,\"n\":\"Alignment\"},{\"t\":3,\"p\":1,\"n\":\"Equip Type\"},{\"t\":3,\"p\":1,\"n\":\"Form Type\"},{\"t\":3,\"p\":1,\"n\":\"Critical Stage\"},{\"t\":3,\"p\":1,\"n\":\"Object Reference\"},{\"t\":3,\"p\":1,\"n\":\"Inventory Object\"},{\"t\":3,\"p\":1,\"n\":\"Actor\"},{\"t\":3,\"p\":1,\"n\":\"Voice Type\"},{\"t\":3,\"p\":1,\"n\":\"Idle\"},{\"t\":3,\"p\":1,\"n\":\"Form List\"},{\"t\":3,\"p\":1,\"n\":\"Quest\"},{\"t\":3,\"p\":1,\"n\":\"Faction\"},{\"t\":3,\"p\":1,\"n\":\"Cell\"},{\"t\":3,\"p\":1,\"n\":\"Class\"},{\"t\":3,\"p\":1,\"n\":\"Race\"},{\"t\":3,\"p\":1,\"n\":\"Actor Base\"},{\"t\":3,\"p\":1,\"n\":\"Global\"},{\"t\":3,\"p\":1,\"n\":\"Weather\"},{\"t\":3,\"p\":1,\"n\":\"Package\"},{\"t\":3,\"p\":1,\"n\":\"Encounter Zone\"},{\"t\":3,\"p\":1,\"n\":\"Perk\"},{\"t\":3,\"p\":1,\"n\":\"Owner\"},{\"t\":3,\"p\":1,\"n\":\"Furniture\"},{\"t\":3,\"p\":1,\"n\":\"Effect Item\"},{\"t\":3,\"p\":1,\"n\":\"Base Effect\"},{\"t\":3,\"p\":1,\"n\":\"Worldspace\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Function\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Param (INVALID)\"},{\"t\":3,\"p\":1,\"n\":\"Referenceable Object\"},{\"t\":3,\"p\":1,\"n\":\"Region\"},{\"t\":3,\"p\":1,\"n\":\"Keyword\"},{\"t\":3,\"p\":1,\"n\":\"Player Action\"},{\"t\":3,\"p\":1,\"n\":\"Casting Type\"},{\"t\":3,\"p\":1,\"n\":\"Shout\"},{\"t\":3,\"p\":1,\"n\":\"Location\"},{\"t\":3,\"p\":1,\"n\":\"Location Ref Type\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"Packdata ID\"},{\"t\":3,\"p\":1,\"n\":\"Association Type\"},{\"t\":3,\"p\":1,\"n\":\"Furniture Anim\"},{\"t\":3,\"p\":1,\"n\":\"Furniture Entry\"},{\"t\":3,\"p\":1,\"n\":\"Scene\"},{\"t\":3,\"p\":1,\"n\":\"Ward State\"},{\"t\":3,\"p\":1,\"n\":\"Event\"},{\"t\":3,\"p\":1,\"n\":\"Event Data\"},{\"t\":3,\"p\":1,\"n\":\"Quest Stage\"},{\"t\":3,\"p\":1,\"n\":\"Weapon\"},{\"t\":3,\"p\":1,\"n\":\"Weapon List\"},{\"t\":3,\"p\":1,\"n\":\"Target\"},{\"t\":3,\"p\":1,\"n\":\"Target List\"},{\"t\":3,\"p\":1,\"n\":\"Target Part\"},{\"t\":3,\"p\":1,\"n\":\"VATS Action\"},{\"t\":3,\"p\":1,\"n\":\"Critical Effect\"},{\"t\":3,\"p\":1,\"n\":\"Critical Effect List\"},{\"t\":3,\"p\":1,\"n\":\"Weapon Type\"},{\"t\":3,\"p\":1,\"n\":\"Projectile Type\"},{\"t\":3,\"p\":1,\"n\":\"Delivery Type\"},{\"t\":3,\"p\":1,\"n\":\"Run On\"},{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":3,\"p\":1,\"n\":\"Parameter #3\"}]},{\"t\":2,\"p\":1,\"n\":\"CIS1 - Parameter #1\"},{\"t\":2,\"p\":1,\"n\":\"CIS2 - Parameter #2\"}]}]},{\"t\":2,\"p\":1,\"n\":\"CNAM - Log Entry\"},{\"t\":3,\"p\":1,\"n\":\"NAM0 - Next Quest\"},{\"t\":11,\"n\":\"SCHR - Unused\"},{\"t\":11,\"n\":\"SCTX - Unused\"},{\"t\":11,\"n\":\"QNAM - Unused\"}]}]}]}]},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Objectives\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Objective\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"QOBJ - Objective Index\"},{\"t\":3,\"p\":1,\"n\":\"FNAM - Flags\"},{\"t\":2,\"p\":1,\"n\":\"NNAM - Display Text\"},{\"t\":8,\"p\":1,\"n\":\"Targets\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Target\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"QSTA - Target\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":8,\"p\":1,\"n\":\"Conditions\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Condition\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"CTDA - \",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":5,\"p\":1,\"n\":\"Comparison Value - Float\"},{\"t\":3,\"p\":1,\"n\":\"Comparison Value - Global\"},{\"t\":3,\"p\":1,\"n\":\"Function\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":11,\"p\":1,\"n\":\"None\"},{\"t\":3,\"p\":1,\"n\":\"Integer\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":11,\"p\":1,\"n\":\"Variable Name (unused)\"},{\"t\":3,\"p\":1,\"n\":\"Sex\"},{\"t\":3,\"p\":1,\"n\":\"Actor Value\"},{\"t\":3,\"p\":1,\"n\":\"Crime Type\"},{\"t\":3,\"p\":1,\"n\":\"Axis\"},{\"t\":3,\"p\":1,\"n\":\"Quest Stage (unused)\"},{\"t\":3,\"p\":1,\"n\":\"Misc Stat\"},{\"t\":3,\"p\":1,\"n\":\"Alignment\"},{\"t\":3,\"p\":1,\"n\":\"Equip Type\"},{\"t\":3,\"p\":1,\"n\":\"Form Type\"},{\"t\":3,\"p\":1,\"n\":\"Critical Stage\"},{\"t\":3,\"p\":1,\"n\":\"Object Reference\"},{\"t\":3,\"p\":1,\"n\":\"Inventory Object\"},{\"t\":3,\"p\":1,\"n\":\"Actor\"},{\"t\":3,\"p\":1,\"n\":\"Voice Type\"},{\"t\":3,\"p\":1,\"n\":\"Idle\"},{\"t\":3,\"p\":1,\"n\":\"Form List\"},{\"t\":3,\"p\":1,\"n\":\"Quest\"},{\"t\":3,\"p\":1,\"n\":\"Faction\"},{\"t\":3,\"p\":1,\"n\":\"Cell\"},{\"t\":3,\"p\":1,\"n\":\"Class\"},{\"t\":3,\"p\":1,\"n\":\"Race\"},{\"t\":3,\"p\":1,\"n\":\"Actor Base\"},{\"t\":3,\"p\":1,\"n\":\"Global\"},{\"t\":3,\"p\":1,\"n\":\"Weather\"},{\"t\":3,\"p\":1,\"n\":\"Package\"},{\"t\":3,\"p\":1,\"n\":\"Encounter Zone\"},{\"t\":3,\"p\":1,\"n\":\"Perk\"},{\"t\":3,\"p\":1,\"n\":\"Owner\"},{\"t\":3,\"p\":1,\"n\":\"Furniture\"},{\"t\":3,\"p\":1,\"n\":\"Effect Item\"},{\"t\":3,\"p\":1,\"n\":\"Base Effect\"},{\"t\":3,\"p\":1,\"n\":\"Worldspace\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Function\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Param (INVALID)\"},{\"t\":3,\"p\":1,\"n\":\"Referenceable Object\"},{\"t\":3,\"p\":1,\"n\":\"Region\"},{\"t\":3,\"p\":1,\"n\":\"Keyword\"},{\"t\":3,\"p\":1,\"n\":\"Player Action\"},{\"t\":3,\"p\":1,\"n\":\"Casting Type\"},{\"t\":3,\"p\":1,\"n\":\"Shout\"},{\"t\":3,\"p\":1,\"n\":\"Location\"},{\"t\":3,\"p\":1,\"n\":\"Location Ref Type\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"Packdata ID\"},{\"t\":3,\"p\":1,\"n\":\"Association Type\"},{\"t\":3,\"p\":1,\"n\":\"Furniture Anim\"},{\"t\":3,\"p\":1,\"n\":\"Furniture Entry\"},{\"t\":3,\"p\":1,\"n\":\"Scene\"},{\"t\":3,\"p\":1,\"n\":\"Ward State\"},{\"t\":3,\"p\":1,\"n\":\"Event\"},{\"t\":3,\"p\":1,\"n\":\"Event Data\"},{\"t\":3,\"p\":1,\"n\":\"Quest Stage\"},{\"t\":3,\"p\":1,\"n\":\"Weapon\"},{\"t\":3,\"p\":1,\"n\":\"Weapon List\"},{\"t\":3,\"p\":1,\"n\":\"Target\"},{\"t\":3,\"p\":1,\"n\":\"Target List\"},{\"t\":3,\"p\":1,\"n\":\"Target Part\"},{\"t\":3,\"p\":1,\"n\":\"VATS Action\"},{\"t\":3,\"p\":1,\"n\":\"Critical Effect\"},{\"t\":3,\"p\":1,\"n\":\"Critical Effect List\"},{\"t\":3,\"p\":1,\"n\":\"Weapon Type\"},{\"t\":3,\"p\":1,\"n\":\"Projectile Type\"},{\"t\":3,\"p\":1,\"n\":\"Delivery Type\"},{\"t\":3,\"p\":1,\"n\":\"Run On\"},{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":3,\"p\":1,\"n\":\"Parameter #3\"}]},{\"t\":2,\"p\":1,\"n\":\"CIS1 - Parameter #1\"},{\"t\":2,\"p\":1,\"n\":\"CIS2 - Parameter #2\"}]}]}]}]}]}]},{\"t\":11,\"n\":\"ANAM - Aliases Marker\"},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Aliases\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alias\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"ALST - Reference Alias ID\"},{\"t\":2,\"p\":1,\"n\":\"ALID - Alias Name\"},{\"t\":6,\"p\":1,\"n\":\"FNAM - Alias Flags\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":3,\"p\":1,\"n\":\"Additional Flags\"}]},{\"t\":3,\"p\":1,\"n\":\"ALFI - Force Into Alias When Filled\"},{\"t\":3,\"p\":1,\"n\":\"ALFL - Specific Location\"},{\"t\":3,\"p\":1,\"n\":\"ALFR - Forced Reference\"},{\"t\":3,\"p\":1,\"n\":\"ALUA - Unique Actor\"},{\"t\":6,\"p\":1,\"n\":\"Location Alias Reference\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"ALFA - Alias\"},{\"t\":3,\"p\":1,\"n\":\"KNAM - Keyword\"},{\"t\":3,\"p\":1,\"n\":\"ALRT - Ref Type\"}]},{\"t\":6,\"p\":1,\"n\":\"External Alias Reference\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"ALEQ - Quest\"},{\"t\":3,\"p\":1,\"n\":\"ALEA - Alias\"}]},{\"t\":6,\"p\":1,\"n\":\"Create Reference to Object\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"ALCO - Object\"},{\"t\":6,\"p\":1,\"n\":\"ALCA - Alias\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"Create\"}]},{\"t\":3,\"p\":1,\"n\":\"ALCL - Level\"}]},{\"t\":6,\"p\":1,\"n\":\"Find Matching Reference Near Alias\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"ALNA - Alias\"},{\"t\":3,\"p\":1,\"n\":\"ALNT - Type\"}]},{\"t\":6,\"p\":1,\"n\":\"Find Matching Reference From Event\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"ALFE - From Event\"},{\"t\":11,\"p\":1,\"n\":\"ALFD - Event Data\"}]},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Conditions\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Condition\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"CTDA - \",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":5,\"p\":1,\"n\":\"Comparison Value - Float\"},{\"t\":3,\"p\":1,\"n\":\"Comparison Value - Global\"},{\"t\":3,\"p\":1,\"n\":\"Function\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":11,\"p\":1,\"n\":\"None\"},{\"t\":3,\"p\":1,\"n\":\"Integer\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":11,\"p\":1,\"n\":\"Variable Name (unused)\"},{\"t\":3,\"p\":1,\"n\":\"Sex\"},{\"t\":3,\"p\":1,\"n\":\"Actor Value\"},{\"t\":3,\"p\":1,\"n\":\"Crime Type\"},{\"t\":3,\"p\":1,\"n\":\"Axis\"},{\"t\":3,\"p\":1,\"n\":\"Quest Stage (unused)\"},{\"t\":3,\"p\":1,\"n\":\"Misc Stat\"},{\"t\":3,\"p\":1,\"n\":\"Alignment\"},{\"t\":3,\"p\":1,\"n\":\"Equip Type\"},{\"t\":3,\"p\":1,\"n\":\"Form Type\"},{\"t\":3,\"p\":1,\"n\":\"Critical Stage\"},{\"t\":3,\"p\":1,\"n\":\"Object Reference\"},{\"t\":3,\"p\":1,\"n\":\"Inventory Object\"},{\"t\":3,\"p\":1,\"n\":\"Actor\"},{\"t\":3,\"p\":1,\"n\":\"Voice Type\"},{\"t\":3,\"p\":1,\"n\":\"Idle\"},{\"t\":3,\"p\":1,\"n\":\"Form List\"},{\"t\":3,\"p\":1,\"n\":\"Quest\"},{\"t\":3,\"p\":1,\"n\":\"Faction\"},{\"t\":3,\"p\":1,\"n\":\"Cell\"},{\"t\":3,\"p\":1,\"n\":\"Class\"},{\"t\":3,\"p\":1,\"n\":\"Race\"},{\"t\":3,\"p\":1,\"n\":\"Actor Base\"},{\"t\":3,\"p\":1,\"n\":\"Global\"},{\"t\":3,\"p\":1,\"n\":\"Weather\"},{\"t\":3,\"p\":1,\"n\":\"Package\"},{\"t\":3,\"p\":1,\"n\":\"Encounter Zone\"},{\"t\":3,\"p\":1,\"n\":\"Perk\"},{\"t\":3,\"p\":1,\"n\":\"Owner\"},{\"t\":3,\"p\":1,\"n\":\"Furniture\"},{\"t\":3,\"p\":1,\"n\":\"Effect Item\"},{\"t\":3,\"p\":1,\"n\":\"Base Effect\"},{\"t\":3,\"p\":1,\"n\":\"Worldspace\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Function\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Param (INVALID)\"},{\"t\":3,\"p\":1,\"n\":\"Referenceable Object\"},{\"t\":3,\"p\":1,\"n\":\"Region\"},{\"t\":3,\"p\":1,\"n\":\"Keyword\"},{\"t\":3,\"p\":1,\"n\":\"Player Action\"},{\"t\":3,\"p\":1,\"n\":\"Casting Type\"},{\"t\":3,\"p\":1,\"n\":\"Shout\"},{\"t\":3,\"p\":1,\"n\":\"Location\"},{\"t\":3,\"p\":1,\"n\":\"Location Ref Type\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"Packdata ID\"},{\"t\":3,\"p\":1,\"n\":\"Association Type\"},{\"t\":3,\"p\":1,\"n\":\"Furniture Anim\"},{\"t\":3,\"p\":1,\"n\":\"Furniture Entry\"},{\"t\":3,\"p\":1,\"n\":\"Scene\"},{\"t\":3,\"p\":1,\"n\":\"Ward State\"},{\"t\":3,\"p\":1,\"n\":\"Event\"},{\"t\":3,\"p\":1,\"n\":\"Event Data\"},{\"t\":3,\"p\":1,\"n\":\"Quest Stage\"},{\"t\":3,\"p\":1,\"n\":\"Weapon\"},{\"t\":3,\"p\":1,\"n\":\"Weapon List\"},{\"t\":3,\"p\":1,\"n\":\"Target\"},{\"t\":3,\"p\":1,\"n\":\"Target List\"},{\"t\":3,\"p\":1,\"n\":\"Target Part\"},{\"t\":3,\"p\":1,\"n\":\"VATS Action\"},{\"t\":3,\"p\":1,\"n\":\"Critical Effect\"},{\"t\":3,\"p\":1,\"n\":\"Critical Effect List\"},{\"t\":3,\"p\":1,\"n\":\"Weapon Type\"},{\"t\":3,\"p\":1,\"n\":\"Projectile Type\"},{\"t\":3,\"p\":1,\"n\":\"Delivery Type\"},{\"t\":3,\"p\":1,\"n\":\"Run On\"},{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":3,\"p\":1,\"n\":\"Parameter #3\"}]},{\"t\":2,\"p\":1,\"n\":\"CIS1 - Parameter #1\"},{\"t\":2,\"p\":1,\"n\":\"CIS2 - Parameter #2\"}]}]},{\"t\":3,\"p\":1,\"n\":\"KSIZ - Keyword Count\"},{\"t\":7,\"p\":1,\"n\":\"KWDA - Keywords\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Keyword\"}]},{\"t\":3,\"p\":1,\"n\":\"COCT - Count\"},{\"t\":10,\"p\":1,\"n\":\"Items\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Item\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"CNTO - Item\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Item\"},{\"t\":3,\"p\":1,\"n\":\"Count\"}]},{\"t\":6,\"p\":1,\"n\":\"COED - Extra Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Owner\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Global Variable\"},{\"t\":3,\"p\":1,\"n\":\"Required Rank\"},{\"t\":5,\"p\":1,\"n\":\"Item Condition\"}]}]}]},{\"t\":3,\"p\":1,\"n\":\"SPOR - Spectator override package list\"},{\"t\":3,\"p\":1,\"n\":\"OCOR - Observe dead body override package list\"},{\"t\":3,\"p\":1,\"n\":\"GWOR - Guard warn override package list\"},{\"t\":3,\"p\":1,\"n\":\"ECOR - Combat override package list\"},{\"t\":3,\"p\":1,\"n\":\"ALDN - Display Name\"},{\"t\":8,\"p\":1,\"n\":\"Alias Spells\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"ALSP - Spell\"}]},{\"t\":8,\"p\":1,\"n\":\"Alias Factions\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"ALFC - Faction\"}]},{\"t\":8,\"p\":1,\"n\":\"Alias Package Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"ALPC - Package\"}]},{\"t\":3,\"p\":1,\"n\":\"VTCK - Voice Types\"},{\"p\":1,\"n\":\"ALED - Alias End\"}]}]},{\"t\":2,\"p\":1,\"n\":\"NNAM - Description\"},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Targets\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Target\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"QSTA - Target\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Target\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Conditions\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Condition\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"CTDA - \",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":5,\"p\":1,\"n\":\"Comparison Value - Float\"},{\"t\":3,\"p\":1,\"n\":\"Comparison Value - Global\"},{\"t\":3,\"p\":1,\"n\":\"Function\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":11,\"p\":1,\"n\":\"None\"},{\"t\":3,\"p\":1,\"n\":\"Integer\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":11,\"p\":1,\"n\":\"Variable Name (unused)\"},{\"t\":3,\"p\":1,\"n\":\"Sex\"},{\"t\":3,\"p\":1,\"n\":\"Actor Value\"},{\"t\":3,\"p\":1,\"n\":\"Crime Type\"},{\"t\":3,\"p\":1,\"n\":\"Axis\"},{\"t\":3,\"p\":1,\"n\":\"Quest Stage (unused)\"},{\"t\":3,\"p\":1,\"n\":\"Misc Stat\"},{\"t\":3,\"p\":1,\"n\":\"Alignment\"},{\"t\":3,\"p\":1,\"n\":\"Equip Type\"},{\"t\":3,\"p\":1,\"n\":\"Form Type\"},{\"t\":3,\"p\":1,\"n\":\"Critical Stage\"},{\"t\":3,\"p\":1,\"n\":\"Object Reference\"},{\"t\":3,\"p\":1,\"n\":\"Inventory Object\"},{\"t\":3,\"p\":1,\"n\":\"Actor\"},{\"t\":3,\"p\":1,\"n\":\"Voice Type\"},{\"t\":3,\"p\":1,\"n\":\"Idle\"},{\"t\":3,\"p\":1,\"n\":\"Form List\"},{\"t\":3,\"p\":1,\"n\":\"Quest\"},{\"t\":3,\"p\":1,\"n\":\"Faction\"},{\"t\":3,\"p\":1,\"n\":\"Cell\"},{\"t\":3,\"p\":1,\"n\":\"Class\"},{\"t\":3,\"p\":1,\"n\":\"Race\"},{\"t\":3,\"p\":1,\"n\":\"Actor Base\"},{\"t\":3,\"p\":1,\"n\":\"Global\"},{\"t\":3,\"p\":1,\"n\":\"Weather\"},{\"t\":3,\"p\":1,\"n\":\"Package\"},{\"t\":3,\"p\":1,\"n\":\"Encounter Zone\"},{\"t\":3,\"p\":1,\"n\":\"Perk\"},{\"t\":3,\"p\":1,\"n\":\"Owner\"},{\"t\":3,\"p\":1,\"n\":\"Furniture\"},{\"t\":3,\"p\":1,\"n\":\"Effect Item\"},{\"t\":3,\"p\":1,\"n\":\"Base Effect\"},{\"t\":3,\"p\":1,\"n\":\"Worldspace\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Function\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Param (INVALID)\"},{\"t\":3,\"p\":1,\"n\":\"Referenceable Object\"},{\"t\":3,\"p\":1,\"n\":\"Region\"},{\"t\":3,\"p\":1,\"n\":\"Keyword\"},{\"t\":3,\"p\":1,\"n\":\"Player Action\"},{\"t\":3,\"p\":1,\"n\":\"Casting Type\"},{\"t\":3,\"p\":1,\"n\":\"Shout\"},{\"t\":3,\"p\":1,\"n\":\"Location\"},{\"t\":3,\"p\":1,\"n\":\"Location Ref Type\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"Packdata ID\"},{\"t\":3,\"p\":1,\"n\":\"Association Type\"},{\"t\":3,\"p\":1,\"n\":\"Furniture Anim\"},{\"t\":3,\"p\":1,\"n\":\"Furniture Entry\"},{\"t\":3,\"p\":1,\"n\":\"Scene\"},{\"t\":3,\"p\":1,\"n\":\"Ward State\"},{\"t\":3,\"p\":1,\"n\":\"Event\"},{\"t\":3,\"p\":1,\"n\":\"Event Data\"},{\"t\":3,\"p\":1,\"n\":\"Quest Stage\"},{\"t\":3,\"p\":1,\"n\":\"Weapon\"},{\"t\":3,\"p\":1,\"n\":\"Weapon List\"},{\"t\":3,\"p\":1,\"n\":\"Target\"},{\"t\":3,\"p\":1,\"n\":\"Target List\"},{\"t\":3,\"p\":1,\"n\":\"Target Part\"},{\"t\":3,\"p\":1,\"n\":\"VATS Action\"},{\"t\":3,\"p\":1,\"n\":\"Critical Effect\"},{\"t\":3,\"p\":1,\"n\":\"Critical Effect List\"},{\"t\":3,\"p\":1,\"n\":\"Weapon Type\"},{\"t\":3,\"p\":1,\"n\":\"Projectile Type\"},{\"t\":3,\"p\":1,\"n\":\"Delivery Type\"},{\"t\":3,\"p\":1,\"n\":\"Run On\"},{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":3,\"p\":1,\"n\":\"Parameter #3\"}]},{\"t\":2,\"p\":1,\"n\":\"CIS1 - Parameter #1\"},{\"t\":2,\"p\":1,\"n\":\"CIS2 - Parameter #2\"}]}]}]}]}]},{\"t\":1,\"p\":1,\"n\":\"RACE - Race\",\"c\":[{\"t\":2,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":2,\"p\":1,\"n\":\"DESC - Description\"},{\"t\":3,\"n\":\"SPCT - Count\"},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Actor Effects\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"SPLO - Actor Effect\"}]},{\"t\":3,\"p\":1,\"n\":\"WNAM - Skin\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"BOD2 - Biped Body Template\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"First Person Flags\"},{\"t\":3,\"p\":1,\"n\":\"General Flags\"},{\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Armor Type\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"BODT - Body Template\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"First Person Flags\"},{\"t\":3,\"p\":1,\"n\":\"General Flags\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Armor Type\"}]},{\"t\":3,\"n\":\"KSIZ - Keyword Count\"},{\"t\":7,\"p\":1,\"n\":\"KWDA - Keywords\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Keyword\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DATA - \",\"c\":[{\"t\":7,\"p\":1,\"n\":\"Skill Boosts\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Skill Boost\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Skill\"},{\"t\":3,\"p\":1,\"n\":\"Boost\"}]}]},{\"t\":11,\"n\":\"Unknown\"},{\"t\":5,\"p\":1,\"n\":\"Male Height\"},{\"t\":5,\"p\":1,\"n\":\"Female Height\"},{\"t\":5,\"p\":1,\"n\":\"Male Weight\"},{\"t\":5,\"p\":1,\"n\":\"Female Weight\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":5,\"p\":1,\"n\":\"Starting Health\"},{\"t\":5,\"p\":1,\"n\":\"Starting Magicka\"},{\"t\":5,\"p\":1,\"n\":\"Starting Stamina\"},{\"t\":5,\"p\":1,\"n\":\"Base Carry Weight\"},{\"t\":5,\"p\":1,\"n\":\"Base Mass\"},{\"t\":5,\"p\":1,\"n\":\"Acceleration rate\"},{\"t\":5,\"p\":1,\"n\":\"Deceleration rate\"},{\"t\":3,\"p\":1,\"n\":\"Size\"},{\"t\":3,\"p\":1,\"n\":\"Head Biped Object\"},{\"t\":3,\"p\":1,\"n\":\"Hair Biped Object\"},{\"t\":5,\"p\":1,\"n\":\"Injured Health Pct\"},{\"t\":3,\"p\":1,\"n\":\"Shield Biped Object\"},{\"t\":5,\"p\":1,\"n\":\"Health Regen\"},{\"t\":5,\"p\":1,\"n\":\"Magicka Regen\"},{\"t\":5,\"p\":1,\"n\":\"Stamina Regen\"},{\"t\":5,\"p\":1,\"n\":\"Unarmed Damage\"},{\"t\":5,\"p\":1,\"n\":\"Unarmed Reach\"},{\"t\":3,\"p\":1,\"n\":\"Body Biped Object\"},{\"t\":5,\"p\":1,\"n\":\"Aim Angle Tolerance\"},{\"t\":5,\"p\":1,\"n\":\"Flight Radius\"},{\"t\":5,\"p\":1,\"n\":\"Angular Acceleration Rate\"},{\"t\":5,\"p\":1,\"n\":\"Angular Tolerance\"},{\"t\":3,\"p\":1,\"n\":\"Flags 2\"},{\"t\":6,\"p\":1,\"n\":\"Mount Data\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Offset X\"},{\"t\":5,\"p\":1,\"n\":\"Offset Y\"},{\"t\":5,\"p\":1,\"n\":\"Unknown\"}]}]},{\"p\":1,\"n\":\"MNAM - Male Marker\"},{\"t\":2,\"p\":1,\"n\":\"ANAM - Male Skeletal Model\"},{\"t\":11,\"p\":1,\"n\":\"MODT - Texture Files Hashes\"},{\"p\":1,\"n\":\"FNAM - Female Marker\"},{\"t\":2,\"p\":1,\"n\":\"ANAM - Female Skeletal Model\"},{\"p\":1,\"n\":\"NAM2 - Marker NAM2 #1\"},{\"t\":8,\"p\":1,\"n\":\"Movement Type Names\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MTNM - Name\"}]},{\"t\":7,\"p\":1,\"n\":\"VTCK - Voices\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Voice\"}]},{\"t\":7,\"p\":1,\"n\":\"DNAM - Decapitate Armors\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Decapitate Armor\"}]},{\"t\":7,\"p\":1,\"n\":\"HCLF - Default Hair Colors\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Default Hair Color\"}]},{\"t\":3,\"n\":\"TINL - Total Number of Tints in List\"},{\"t\":5,\"p\":1,\"n\":\"PNAM - FaceGen - Main clamp\"},{\"t\":5,\"p\":1,\"n\":\"UNAM - FaceGen - Face clamp\"},{\"t\":3,\"p\":1,\"n\":\"ATKR - Attack Race\"},{\"t\":10,\"p\":1,\"n\":\"Attacks\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Attack\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"ATKD - Attack Data\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Damage Mult\"},{\"t\":5,\"p\":1,\"n\":\"Attack Chance\"},{\"t\":3,\"p\":1,\"n\":\"Attack Spell\"},{\"t\":3,\"p\":1,\"n\":\"Attack Flags\"},{\"t\":5,\"p\":1,\"n\":\"Attack Angle\"},{\"t\":5,\"p\":1,\"n\":\"Strike Angle\"},{\"t\":5,\"p\":1,\"n\":\"Stagger\"},{\"t\":3,\"p\":1,\"n\":\"Attack Type\"},{\"t\":5,\"p\":1,\"n\":\"Knockdown\"},{\"t\":5,\"p\":1,\"n\":\"Recovery Time\"},{\"t\":5,\"p\":1,\"n\":\"Stamina Mult\"}]},{\"t\":2,\"p\":1,\"n\":\"ATKE - Attack Event\"}]}]},{\"t\":6,\"p\":1,\"n\":\"Body Data\",\"c\":[{\"n\":\"NAM1 - Body Data Marker\"},{\"t\":6,\"p\":1,\"n\":\"Male Body Data\",\"c\":[{\"n\":\"MNAM - Male Data Marker\"},{\"t\":10,\"s\":1,\"p\":1,\"n\":\"Parts\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Part\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"INDX - Index\"},{\"t\":6,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"MODT - Texture Files Hashes\"},{\"t\":7,\"p\":1,\"n\":\"MODS - Alternate Textures\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"3D Name\"},{\"t\":3,\"p\":1,\"n\":\"New Texture\"},{\"t\":3,\"p\":1,\"n\":\"3D Index\"}]}]}]}]}]}]},{\"t\":6,\"p\":1,\"n\":\"Female Body Data\",\"c\":[{\"n\":\"FNAM - Female Data Marker\"},{\"t\":10,\"s\":1,\"p\":1,\"n\":\"Parts\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Part\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"INDX - Index\"},{\"t\":6,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"MODT - Texture Files Hashes\"},{\"t\":7,\"p\":1,\"n\":\"MODS - Alternate Textures\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"3D Name\"},{\"t\":3,\"p\":1,\"n\":\"New Texture\"},{\"t\":3,\"p\":1,\"n\":\"3D Index\"}]}]}]}]}]}]}]},{\"t\":7,\"p\":1,\"n\":\"HNAM - Hairs\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Hair\"}]},{\"t\":7,\"p\":1,\"n\":\"ENAM - Eyes\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Eye\"}]},{\"t\":3,\"p\":1,\"n\":\"GNAM - Body Part Data\"},{\"p\":1,\"n\":\"NAM2 - Marker NAM2 #2\"},{\"p\":1,\"n\":\"NAM3 - Marker NAM3 #3\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Male Behavior Graph\",\"c\":[{\"p\":1,\"n\":\"MNAM - Male Data Marker\"},{\"t\":6,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"MODT - Texture Files Hashes\"},{\"t\":7,\"p\":1,\"n\":\"MODS - Alternate Textures\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"3D Name\"},{\"t\":3,\"p\":1,\"n\":\"New Texture\"},{\"t\":3,\"p\":1,\"n\":\"3D Index\"}]}]}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Female Behavior Graph\",\"c\":[{\"p\":1,\"n\":\"FNAM - Female Data Marker\"},{\"t\":6,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"MODT - Texture Files Hashes\"},{\"t\":7,\"p\":1,\"n\":\"MODS - Alternate Textures\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"3D Name\"},{\"t\":3,\"p\":1,\"n\":\"New Texture\"},{\"t\":3,\"p\":1,\"n\":\"3D Index\"}]}]}]}]},{\"t\":3,\"p\":1,\"n\":\"NAM4 - Material Type\"},{\"t\":3,\"p\":1,\"n\":\"NAM5 - Impact Data Set\"},{\"t\":3,\"p\":1,\"n\":\"NAM7 - Decapitation FX\"},{\"t\":3,\"p\":1,\"n\":\"ONAM - Open Loot Sound\"},{\"t\":3,\"p\":1,\"n\":\"LNAM - Close Loot Sound\"},{\"t\":8,\"p\":1,\"n\":\"Biped Object Names\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"NAME - Name\"}]},{\"t\":10,\"n\":\"Movement Types\",\"c\":[{\"t\":6,\"n\":\"Movement Types\",\"c\":[{\"t\":3,\"n\":\"MTYP - Movement Type\"},{\"t\":6,\"n\":\"SPED - Override Values\",\"c\":[{\"t\":5,\"n\":\"Left - Walk\"},{\"t\":5,\"n\":\"Left - Run\"},{\"t\":5,\"n\":\"Right - Walk\"},{\"t\":5,\"n\":\"Right - Run\"},{\"t\":5,\"n\":\"Forward - Walk\"},{\"t\":5,\"n\":\"Forward - Run\"},{\"t\":5,\"n\":\"Back - Walk\"},{\"t\":5,\"n\":\"Back - Run\"},{\"t\":5,\"n\":\"Rotate - Walk\"},{\"t\":5,\"n\":\"Unknown\"}]}]}]},{\"t\":3,\"n\":\"VNAM - Equipment Flags\"},{\"t\":8,\"p\":1,\"n\":\"Equip Slots\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"QNAM - Equip Slot\"}]},{\"t\":3,\"n\":\"UNES - Unarmed Equip Slot\"},{\"t\":8,\"n\":\"Phoneme Target Names\",\"c\":[{\"t\":2,\"n\":\"PHTN - Name\"}]},{\"t\":6,\"n\":\"FaceFX Phonemes\",\"c\":[{\"t\":6,\"n\":\"IY\",\"c\":[{\"t\":6,\"n\":\"PHWT - Phoneme Target Weight\",\"c\":[{\"t\":5,\"n\":\"Aah \\/ LipBigAah\"},{\"t\":5,\"n\":\"BigAah \\/ LipDST\"},{\"t\":5,\"n\":\"BMP \\/ LipEee\"},{\"t\":5,\"n\":\"ChJsh \\/ LipFV\"},{\"t\":5,\"n\":\"DST \\/ LipK\"},{\"t\":5,\"n\":\"Eee \\/ LipL\"},{\"t\":5,\"n\":\"Eh \\/ LipR\"},{\"t\":5,\"n\":\"FV \\/ LipTh\"},{\"t\":5,\"n\":\"I\"},{\"t\":5,\"n\":\"K\"},{\"t\":5,\"n\":\"N\"},{\"t\":5,\"n\":\"Oh\"},{\"t\":5,\"n\":\"OohQ\"},{\"t\":5,\"n\":\"R\"},{\"t\":5,\"n\":\"TH\"},{\"t\":5,\"n\":\"W\"}]}]},{\"t\":6,\"n\":\"IH\",\"c\":[{\"t\":6,\"n\":\"PHWT - Phoneme Target Weight\",\"c\":[{\"t\":5,\"n\":\"Aah \\/ LipBigAah\"},{\"t\":5,\"n\":\"BigAah \\/ LipDST\"},{\"t\":5,\"n\":\"BMP \\/ LipEee\"},{\"t\":5,\"n\":\"ChJsh \\/ LipFV\"},{\"t\":5,\"n\":\"DST \\/ LipK\"},{\"t\":5,\"n\":\"Eee \\/ LipL\"},{\"t\":5,\"n\":\"Eh \\/ LipR\"},{\"t\":5,\"n\":\"FV \\/ LipTh\"},{\"t\":5,\"n\":\"I\"},{\"t\":5,\"n\":\"K\"},{\"t\":5,\"n\":\"N\"},{\"t\":5,\"n\":\"Oh\"},{\"t\":5,\"n\":\"OohQ\"},{\"t\":5,\"n\":\"R\"},{\"t\":5,\"n\":\"TH\"},{\"t\":5,\"n\":\"W\"}]}]},{\"t\":6,\"n\":\"EH\",\"c\":[{\"t\":6,\"n\":\"PHWT - Phoneme Target Weight\",\"c\":[{\"t\":5,\"n\":\"Aah \\/ LipBigAah\"},{\"t\":5,\"n\":\"BigAah \\/ LipDST\"},{\"t\":5,\"n\":\"BMP \\/ LipEee\"},{\"t\":5,\"n\":\"ChJsh \\/ LipFV\"},{\"t\":5,\"n\":\"DST \\/ LipK\"},{\"t\":5,\"n\":\"Eee \\/ LipL\"},{\"t\":5,\"n\":\"Eh \\/ LipR\"},{\"t\":5,\"n\":\"FV \\/ LipTh\"},{\"t\":5,\"n\":\"I\"},{\"t\":5,\"n\":\"K\"},{\"t\":5,\"n\":\"N\"},{\"t\":5,\"n\":\"Oh\"},{\"t\":5,\"n\":\"OohQ\"},{\"t\":5,\"n\":\"R\"},{\"t\":5,\"n\":\"TH\"},{\"t\":5,\"n\":\"W\"}]}]},{\"t\":6,\"n\":\"EY\",\"c\":[{\"t\":6,\"n\":\"PHWT - Phoneme Target Weight\",\"c\":[{\"t\":5,\"n\":\"Aah \\/ LipBigAah\"},{\"t\":5,\"n\":\"BigAah \\/ LipDST\"},{\"t\":5,\"n\":\"BMP \\/ LipEee\"},{\"t\":5,\"n\":\"ChJsh \\/ LipFV\"},{\"t\":5,\"n\":\"DST \\/ LipK\"},{\"t\":5,\"n\":\"Eee \\/ LipL\"},{\"t\":5,\"n\":\"Eh \\/ LipR\"},{\"t\":5,\"n\":\"FV \\/ LipTh\"},{\"t\":5,\"n\":\"I\"},{\"t\":5,\"n\":\"K\"},{\"t\":5,\"n\":\"N\"},{\"t\":5,\"n\":\"Oh\"},{\"t\":5,\"n\":\"OohQ\"},{\"t\":5,\"n\":\"R\"},{\"t\":5,\"n\":\"TH\"},{\"t\":5,\"n\":\"W\"}]}]},{\"t\":6,\"n\":\"AE\",\"c\":[{\"t\":6,\"n\":\"PHWT - Phoneme Target Weight\",\"c\":[{\"t\":5,\"n\":\"Aah \\/ LipBigAah\"},{\"t\":5,\"n\":\"BigAah \\/ LipDST\"},{\"t\":5,\"n\":\"BMP \\/ LipEee\"},{\"t\":5,\"n\":\"ChJsh \\/ LipFV\"},{\"t\":5,\"n\":\"DST \\/ LipK\"},{\"t\":5,\"n\":\"Eee \\/ LipL\"},{\"t\":5,\"n\":\"Eh \\/ LipR\"},{\"t\":5,\"n\":\"FV \\/ LipTh\"},{\"t\":5,\"n\":\"I\"},{\"t\":5,\"n\":\"K\"},{\"t\":5,\"n\":\"N\"},{\"t\":5,\"n\":\"Oh\"},{\"t\":5,\"n\":\"OohQ\"},{\"t\":5,\"n\":\"R\"},{\"t\":5,\"n\":\"TH\"},{\"t\":5,\"n\":\"W\"}]}]},{\"t\":6,\"n\":\"AA\",\"c\":[{\"t\":6,\"n\":\"PHWT - Phoneme Target Weight\",\"c\":[{\"t\":5,\"n\":\"Aah \\/ LipBigAah\"},{\"t\":5,\"n\":\"BigAah \\/ LipDST\"},{\"t\":5,\"n\":\"BMP \\/ LipEee\"},{\"t\":5,\"n\":\"ChJsh \\/ LipFV\"},{\"t\":5,\"n\":\"DST \\/ LipK\"},{\"t\":5,\"n\":\"Eee \\/ LipL\"},{\"t\":5,\"n\":\"Eh \\/ LipR\"},{\"t\":5,\"n\":\"FV \\/ LipTh\"},{\"t\":5,\"n\":\"I\"},{\"t\":5,\"n\":\"K\"},{\"t\":5,\"n\":\"N\"},{\"t\":5,\"n\":\"Oh\"},{\"t\":5,\"n\":\"OohQ\"},{\"t\":5,\"n\":\"R\"},{\"t\":5,\"n\":\"TH\"},{\"t\":5,\"n\":\"W\"}]}]},{\"t\":6,\"n\":\"AW\",\"c\":[{\"t\":6,\"n\":\"PHWT - Phoneme Target Weight\",\"c\":[{\"t\":5,\"n\":\"Aah \\/ LipBigAah\"},{\"t\":5,\"n\":\"BigAah \\/ LipDST\"},{\"t\":5,\"n\":\"BMP \\/ LipEee\"},{\"t\":5,\"n\":\"ChJsh \\/ LipFV\"},{\"t\":5,\"n\":\"DST \\/ LipK\"},{\"t\":5,\"n\":\"Eee \\/ LipL\"},{\"t\":5,\"n\":\"Eh \\/ LipR\"},{\"t\":5,\"n\":\"FV \\/ LipTh\"},{\"t\":5,\"n\":\"I\"},{\"t\":5,\"n\":\"K\"},{\"t\":5,\"n\":\"N\"},{\"t\":5,\"n\":\"Oh\"},{\"t\":5,\"n\":\"OohQ\"},{\"t\":5,\"n\":\"R\"},{\"t\":5,\"n\":\"TH\"},{\"t\":5,\"n\":\"W\"}]}]},{\"t\":6,\"n\":\"AY\",\"c\":[{\"t\":6,\"n\":\"PHWT - Phoneme Target Weight\",\"c\":[{\"t\":5,\"n\":\"Aah \\/ LipBigAah\"},{\"t\":5,\"n\":\"BigAah \\/ LipDST\"},{\"t\":5,\"n\":\"BMP \\/ LipEee\"},{\"t\":5,\"n\":\"ChJsh \\/ LipFV\"},{\"t\":5,\"n\":\"DST \\/ LipK\"},{\"t\":5,\"n\":\"Eee \\/ LipL\"},{\"t\":5,\"n\":\"Eh \\/ LipR\"},{\"t\":5,\"n\":\"FV \\/ LipTh\"},{\"t\":5,\"n\":\"I\"},{\"t\":5,\"n\":\"K\"},{\"t\":5,\"n\":\"N\"},{\"t\":5,\"n\":\"Oh\"},{\"t\":5,\"n\":\"OohQ\"},{\"t\":5,\"n\":\"R\"},{\"t\":5,\"n\":\"TH\"},{\"t\":5,\"n\":\"W\"}]}]},{\"t\":6,\"n\":\"AH\",\"c\":[{\"t\":6,\"n\":\"PHWT - Phoneme Target Weight\",\"c\":[{\"t\":5,\"n\":\"Aah \\/ LipBigAah\"},{\"t\":5,\"n\":\"BigAah \\/ LipDST\"},{\"t\":5,\"n\":\"BMP \\/ LipEee\"},{\"t\":5,\"n\":\"ChJsh \\/ LipFV\"},{\"t\":5,\"n\":\"DST \\/ LipK\"},{\"t\":5,\"n\":\"Eee \\/ LipL\"},{\"t\":5,\"n\":\"Eh \\/ LipR\"},{\"t\":5,\"n\":\"FV \\/ LipTh\"},{\"t\":5,\"n\":\"I\"},{\"t\":5,\"n\":\"K\"},{\"t\":5,\"n\":\"N\"},{\"t\":5,\"n\":\"Oh\"},{\"t\":5,\"n\":\"OohQ\"},{\"t\":5,\"n\":\"R\"},{\"t\":5,\"n\":\"TH\"},{\"t\":5,\"n\":\"W\"}]}]},{\"t\":6,\"n\":\"AO\",\"c\":[{\"t\":6,\"n\":\"PHWT - Phoneme Target Weight\",\"c\":[{\"t\":5,\"n\":\"Aah \\/ LipBigAah\"},{\"t\":5,\"n\":\"BigAah \\/ LipDST\"},{\"t\":5,\"n\":\"BMP \\/ LipEee\"},{\"t\":5,\"n\":\"ChJsh \\/ LipFV\"},{\"t\":5,\"n\":\"DST \\/ LipK\"},{\"t\":5,\"n\":\"Eee \\/ LipL\"},{\"t\":5,\"n\":\"Eh \\/ LipR\"},{\"t\":5,\"n\":\"FV \\/ LipTh\"},{\"t\":5,\"n\":\"I\"},{\"t\":5,\"n\":\"K\"},{\"t\":5,\"n\":\"N\"},{\"t\":5,\"n\":\"Oh\"},{\"t\":5,\"n\":\"OohQ\"},{\"t\":5,\"n\":\"R\"},{\"t\":5,\"n\":\"TH\"},{\"t\":5,\"n\":\"W\"}]}]},{\"t\":6,\"n\":\"OY\",\"c\":[{\"t\":6,\"n\":\"PHWT - Phoneme Target Weight\",\"c\":[{\"t\":5,\"n\":\"Aah \\/ LipBigAah\"},{\"t\":5,\"n\":\"BigAah \\/ LipDST\"},{\"t\":5,\"n\":\"BMP \\/ LipEee\"},{\"t\":5,\"n\":\"ChJsh \\/ LipFV\"},{\"t\":5,\"n\":\"DST \\/ LipK\"},{\"t\":5,\"n\":\"Eee \\/ LipL\"},{\"t\":5,\"n\":\"Eh \\/ LipR\"},{\"t\":5,\"n\":\"FV \\/ LipTh\"},{\"t\":5,\"n\":\"I\"},{\"t\":5,\"n\":\"K\"},{\"t\":5,\"n\":\"N\"},{\"t\":5,\"n\":\"Oh\"},{\"t\":5,\"n\":\"OohQ\"},{\"t\":5,\"n\":\"R\"},{\"t\":5,\"n\":\"TH\"},{\"t\":5,\"n\":\"W\"}]}]},{\"t\":6,\"n\":\"OW\",\"c\":[{\"t\":6,\"n\":\"PHWT - Phoneme Target Weight\",\"c\":[{\"t\":5,\"n\":\"Aah \\/ LipBigAah\"},{\"t\":5,\"n\":\"BigAah \\/ LipDST\"},{\"t\":5,\"n\":\"BMP \\/ LipEee\"},{\"t\":5,\"n\":\"ChJsh \\/ LipFV\"},{\"t\":5,\"n\":\"DST \\/ LipK\"},{\"t\":5,\"n\":\"Eee \\/ LipL\"},{\"t\":5,\"n\":\"Eh \\/ LipR\"},{\"t\":5,\"n\":\"FV \\/ LipTh\"},{\"t\":5,\"n\":\"I\"},{\"t\":5,\"n\":\"K\"},{\"t\":5,\"n\":\"N\"},{\"t\":5,\"n\":\"Oh\"},{\"t\":5,\"n\":\"OohQ\"},{\"t\":5,\"n\":\"R\"},{\"t\":5,\"n\":\"TH\"},{\"t\":5,\"n\":\"W\"}]}]},{\"t\":6,\"n\":\"UH\",\"c\":[{\"t\":6,\"n\":\"PHWT - Phoneme Target Weight\",\"c\":[{\"t\":5,\"n\":\"Aah \\/ LipBigAah\"},{\"t\":5,\"n\":\"BigAah \\/ LipDST\"},{\"t\":5,\"n\":\"BMP \\/ LipEee\"},{\"t\":5,\"n\":\"ChJsh \\/ LipFV\"},{\"t\":5,\"n\":\"DST \\/ LipK\"},{\"t\":5,\"n\":\"Eee \\/ LipL\"},{\"t\":5,\"n\":\"Eh \\/ LipR\"},{\"t\":5,\"n\":\"FV \\/ LipTh\"},{\"t\":5,\"n\":\"I\"},{\"t\":5,\"n\":\"K\"},{\"t\":5,\"n\":\"N\"},{\"t\":5,\"n\":\"Oh\"},{\"t\":5,\"n\":\"OohQ\"},{\"t\":5,\"n\":\"R\"},{\"t\":5,\"n\":\"TH\"},{\"t\":5,\"n\":\"W\"}]}]},{\"t\":6,\"n\":\"UW\",\"c\":[{\"t\":6,\"n\":\"PHWT - Phoneme Target Weight\",\"c\":[{\"t\":5,\"n\":\"Aah \\/ LipBigAah\"},{\"t\":5,\"n\":\"BigAah \\/ LipDST\"},{\"t\":5,\"n\":\"BMP \\/ LipEee\"},{\"t\":5,\"n\":\"ChJsh \\/ LipFV\"},{\"t\":5,\"n\":\"DST \\/ LipK\"},{\"t\":5,\"n\":\"Eee \\/ LipL\"},{\"t\":5,\"n\":\"Eh \\/ LipR\"},{\"t\":5,\"n\":\"FV \\/ LipTh\"},{\"t\":5,\"n\":\"I\"},{\"t\":5,\"n\":\"K\"},{\"t\":5,\"n\":\"N\"},{\"t\":5,\"n\":\"Oh\"},{\"t\":5,\"n\":\"OohQ\"},{\"t\":5,\"n\":\"R\"},{\"t\":5,\"n\":\"TH\"},{\"t\":5,\"n\":\"W\"}]}]},{\"t\":6,\"n\":\"ER\",\"c\":[{\"t\":6,\"n\":\"PHWT - Phoneme Target Weight\",\"c\":[{\"t\":5,\"n\":\"Aah \\/ LipBigAah\"},{\"t\":5,\"n\":\"BigAah \\/ LipDST\"},{\"t\":5,\"n\":\"BMP \\/ LipEee\"},{\"t\":5,\"n\":\"ChJsh \\/ LipFV\"},{\"t\":5,\"n\":\"DST \\/ LipK\"},{\"t\":5,\"n\":\"Eee \\/ LipL\"},{\"t\":5,\"n\":\"Eh \\/ LipR\"},{\"t\":5,\"n\":\"FV \\/ LipTh\"},{\"t\":5,\"n\":\"I\"},{\"t\":5,\"n\":\"K\"},{\"t\":5,\"n\":\"N\"},{\"t\":5,\"n\":\"Oh\"},{\"t\":5,\"n\":\"OohQ\"},{\"t\":5,\"n\":\"R\"},{\"t\":5,\"n\":\"TH\"},{\"t\":5,\"n\":\"W\"}]}]},{\"t\":6,\"n\":\"AX\",\"c\":[{\"t\":6,\"n\":\"PHWT - Phoneme Target Weight\",\"c\":[{\"t\":5,\"n\":\"Aah \\/ LipBigAah\"},{\"t\":5,\"n\":\"BigAah \\/ LipDST\"},{\"t\":5,\"n\":\"BMP \\/ LipEee\"},{\"t\":5,\"n\":\"ChJsh \\/ LipFV\"},{\"t\":5,\"n\":\"DST \\/ LipK\"},{\"t\":5,\"n\":\"Eee \\/ LipL\"},{\"t\":5,\"n\":\"Eh \\/ LipR\"},{\"t\":5,\"n\":\"FV \\/ LipTh\"},{\"t\":5,\"n\":\"I\"},{\"t\":5,\"n\":\"K\"},{\"t\":5,\"n\":\"N\"},{\"t\":5,\"n\":\"Oh\"},{\"t\":5,\"n\":\"OohQ\"},{\"t\":5,\"n\":\"R\"},{\"t\":5,\"n\":\"TH\"},{\"t\":5,\"n\":\"W\"}]}]},{\"t\":6,\"n\":\"S\",\"c\":[{\"t\":6,\"n\":\"PHWT - Phoneme Target Weight\",\"c\":[{\"t\":5,\"n\":\"Aah \\/ LipBigAah\"},{\"t\":5,\"n\":\"BigAah \\/ LipDST\"},{\"t\":5,\"n\":\"BMP \\/ LipEee\"},{\"t\":5,\"n\":\"ChJsh \\/ LipFV\"},{\"t\":5,\"n\":\"DST \\/ LipK\"},{\"t\":5,\"n\":\"Eee \\/ LipL\"},{\"t\":5,\"n\":\"Eh \\/ LipR\"},{\"t\":5,\"n\":\"FV \\/ LipTh\"},{\"t\":5,\"n\":\"I\"},{\"t\":5,\"n\":\"K\"},{\"t\":5,\"n\":\"N\"},{\"t\":5,\"n\":\"Oh\"},{\"t\":5,\"n\":\"OohQ\"},{\"t\":5,\"n\":\"R\"},{\"t\":5,\"n\":\"TH\"},{\"t\":5,\"n\":\"W\"}]}]},{\"t\":6,\"n\":\"SH\",\"c\":[{\"t\":6,\"n\":\"PHWT - Phoneme Target Weight\",\"c\":[{\"t\":5,\"n\":\"Aah \\/ LipBigAah\"},{\"t\":5,\"n\":\"BigAah \\/ LipDST\"},{\"t\":5,\"n\":\"BMP \\/ LipEee\"},{\"t\":5,\"n\":\"ChJsh \\/ LipFV\"},{\"t\":5,\"n\":\"DST \\/ LipK\"},{\"t\":5,\"n\":\"Eee \\/ LipL\"},{\"t\":5,\"n\":\"Eh \\/ LipR\"},{\"t\":5,\"n\":\"FV \\/ LipTh\"},{\"t\":5,\"n\":\"I\"},{\"t\":5,\"n\":\"K\"},{\"t\":5,\"n\":\"N\"},{\"t\":5,\"n\":\"Oh\"},{\"t\":5,\"n\":\"OohQ\"},{\"t\":5,\"n\":\"R\"},{\"t\":5,\"n\":\"TH\"},{\"t\":5,\"n\":\"W\"}]}]},{\"t\":6,\"n\":\"Z\",\"c\":[{\"t\":6,\"n\":\"PHWT - Phoneme Target Weight\",\"c\":[{\"t\":5,\"n\":\"Aah \\/ LipBigAah\"},{\"t\":5,\"n\":\"BigAah \\/ LipDST\"},{\"t\":5,\"n\":\"BMP \\/ LipEee\"},{\"t\":5,\"n\":\"ChJsh \\/ LipFV\"},{\"t\":5,\"n\":\"DST \\/ LipK\"},{\"t\":5,\"n\":\"Eee \\/ LipL\"},{\"t\":5,\"n\":\"Eh \\/ LipR\"},{\"t\":5,\"n\":\"FV \\/ LipTh\"},{\"t\":5,\"n\":\"I\"},{\"t\":5,\"n\":\"K\"},{\"t\":5,\"n\":\"N\"},{\"t\":5,\"n\":\"Oh\"},{\"t\":5,\"n\":\"OohQ\"},{\"t\":5,\"n\":\"R\"},{\"t\":5,\"n\":\"TH\"},{\"t\":5,\"n\":\"W\"}]}]},{\"t\":6,\"n\":\"ZH\",\"c\":[{\"t\":6,\"n\":\"PHWT - Phoneme Target Weight\",\"c\":[{\"t\":5,\"n\":\"Aah \\/ LipBigAah\"},{\"t\":5,\"n\":\"BigAah \\/ LipDST\"},{\"t\":5,\"n\":\"BMP \\/ LipEee\"},{\"t\":5,\"n\":\"ChJsh \\/ LipFV\"},{\"t\":5,\"n\":\"DST \\/ LipK\"},{\"t\":5,\"n\":\"Eee \\/ LipL\"},{\"t\":5,\"n\":\"Eh \\/ LipR\"},{\"t\":5,\"n\":\"FV \\/ LipTh\"},{\"t\":5,\"n\":\"I\"},{\"t\":5,\"n\":\"K\"},{\"t\":5,\"n\":\"N\"},{\"t\":5,\"n\":\"Oh\"},{\"t\":5,\"n\":\"OohQ\"},{\"t\":5,\"n\":\"R\"},{\"t\":5,\"n\":\"TH\"},{\"t\":5,\"n\":\"W\"}]}]},{\"t\":6,\"n\":\"F\",\"c\":[{\"t\":6,\"n\":\"PHWT - Phoneme Target Weight\",\"c\":[{\"t\":5,\"n\":\"Aah \\/ LipBigAah\"},{\"t\":5,\"n\":\"BigAah \\/ LipDST\"},{\"t\":5,\"n\":\"BMP \\/ LipEee\"},{\"t\":5,\"n\":\"ChJsh \\/ LipFV\"},{\"t\":5,\"n\":\"DST \\/ LipK\"},{\"t\":5,\"n\":\"Eee \\/ LipL\"},{\"t\":5,\"n\":\"Eh \\/ LipR\"},{\"t\":5,\"n\":\"FV \\/ LipTh\"},{\"t\":5,\"n\":\"I\"},{\"t\":5,\"n\":\"K\"},{\"t\":5,\"n\":\"N\"},{\"t\":5,\"n\":\"Oh\"},{\"t\":5,\"n\":\"OohQ\"},{\"t\":5,\"n\":\"R\"},{\"t\":5,\"n\":\"TH\"},{\"t\":5,\"n\":\"W\"}]}]},{\"t\":6,\"n\":\"TH\",\"c\":[{\"t\":6,\"n\":\"PHWT - Phoneme Target Weight\",\"c\":[{\"t\":5,\"n\":\"Aah \\/ LipBigAah\"},{\"t\":5,\"n\":\"BigAah \\/ LipDST\"},{\"t\":5,\"n\":\"BMP \\/ LipEee\"},{\"t\":5,\"n\":\"ChJsh \\/ LipFV\"},{\"t\":5,\"n\":\"DST \\/ LipK\"},{\"t\":5,\"n\":\"Eee \\/ LipL\"},{\"t\":5,\"n\":\"Eh \\/ LipR\"},{\"t\":5,\"n\":\"FV \\/ LipTh\"},{\"t\":5,\"n\":\"I\"},{\"t\":5,\"n\":\"K\"},{\"t\":5,\"n\":\"N\"},{\"t\":5,\"n\":\"Oh\"},{\"t\":5,\"n\":\"OohQ\"},{\"t\":5,\"n\":\"R\"},{\"t\":5,\"n\":\"TH\"},{\"t\":5,\"n\":\"W\"}]}]},{\"t\":6,\"n\":\"V\",\"c\":[{\"t\":6,\"n\":\"PHWT - Phoneme Target Weight\",\"c\":[{\"t\":5,\"n\":\"Aah \\/ LipBigAah\"},{\"t\":5,\"n\":\"BigAah \\/ LipDST\"},{\"t\":5,\"n\":\"BMP \\/ LipEee\"},{\"t\":5,\"n\":\"ChJsh \\/ LipFV\"},{\"t\":5,\"n\":\"DST \\/ LipK\"},{\"t\":5,\"n\":\"Eee \\/ LipL\"},{\"t\":5,\"n\":\"Eh \\/ LipR\"},{\"t\":5,\"n\":\"FV \\/ LipTh\"},{\"t\":5,\"n\":\"I\"},{\"t\":5,\"n\":\"K\"},{\"t\":5,\"n\":\"N\"},{\"t\":5,\"n\":\"Oh\"},{\"t\":5,\"n\":\"OohQ\"},{\"t\":5,\"n\":\"R\"},{\"t\":5,\"n\":\"TH\"},{\"t\":5,\"n\":\"W\"}]}]},{\"t\":6,\"n\":\"DH\",\"c\":[{\"t\":6,\"n\":\"PHWT - Phoneme Target Weight\",\"c\":[{\"t\":5,\"n\":\"Aah \\/ LipBigAah\"},{\"t\":5,\"n\":\"BigAah \\/ LipDST\"},{\"t\":5,\"n\":\"BMP \\/ LipEee\"},{\"t\":5,\"n\":\"ChJsh \\/ LipFV\"},{\"t\":5,\"n\":\"DST \\/ LipK\"},{\"t\":5,\"n\":\"Eee \\/ LipL\"},{\"t\":5,\"n\":\"Eh \\/ LipR\"},{\"t\":5,\"n\":\"FV \\/ LipTh\"},{\"t\":5,\"n\":\"I\"},{\"t\":5,\"n\":\"K\"},{\"t\":5,\"n\":\"N\"},{\"t\":5,\"n\":\"Oh\"},{\"t\":5,\"n\":\"OohQ\"},{\"t\":5,\"n\":\"R\"},{\"t\":5,\"n\":\"TH\"},{\"t\":5,\"n\":\"W\"}]}]},{\"t\":6,\"n\":\"M\",\"c\":[{\"t\":6,\"n\":\"PHWT - Phoneme Target Weight\",\"c\":[{\"t\":5,\"n\":\"Aah \\/ LipBigAah\"},{\"t\":5,\"n\":\"BigAah \\/ LipDST\"},{\"t\":5,\"n\":\"BMP \\/ LipEee\"},{\"t\":5,\"n\":\"ChJsh \\/ LipFV\"},{\"t\":5,\"n\":\"DST \\/ LipK\"},{\"t\":5,\"n\":\"Eee \\/ LipL\"},{\"t\":5,\"n\":\"Eh \\/ LipR\"},{\"t\":5,\"n\":\"FV \\/ LipTh\"},{\"t\":5,\"n\":\"I\"},{\"t\":5,\"n\":\"K\"},{\"t\":5,\"n\":\"N\"},{\"t\":5,\"n\":\"Oh\"},{\"t\":5,\"n\":\"OohQ\"},{\"t\":5,\"n\":\"R\"},{\"t\":5,\"n\":\"TH\"},{\"t\":5,\"n\":\"W\"}]}]},{\"t\":6,\"n\":\"N\",\"c\":[{\"t\":6,\"n\":\"PHWT - Phoneme Target Weight\",\"c\":[{\"t\":5,\"n\":\"Aah \\/ LipBigAah\"},{\"t\":5,\"n\":\"BigAah \\/ LipDST\"},{\"t\":5,\"n\":\"BMP \\/ LipEee\"},{\"t\":5,\"n\":\"ChJsh \\/ LipFV\"},{\"t\":5,\"n\":\"DST \\/ LipK\"},{\"t\":5,\"n\":\"Eee \\/ LipL\"},{\"t\":5,\"n\":\"Eh \\/ LipR\"},{\"t\":5,\"n\":\"FV \\/ LipTh\"},{\"t\":5,\"n\":\"I\"},{\"t\":5,\"n\":\"K\"},{\"t\":5,\"n\":\"N\"},{\"t\":5,\"n\":\"Oh\"},{\"t\":5,\"n\":\"OohQ\"},{\"t\":5,\"n\":\"R\"},{\"t\":5,\"n\":\"TH\"},{\"t\":5,\"n\":\"W\"}]}]},{\"t\":6,\"n\":\"NG\",\"c\":[{\"t\":6,\"n\":\"PHWT - Phoneme Target Weight\",\"c\":[{\"t\":5,\"n\":\"Aah \\/ LipBigAah\"},{\"t\":5,\"n\":\"BigAah \\/ LipDST\"},{\"t\":5,\"n\":\"BMP \\/ LipEee\"},{\"t\":5,\"n\":\"ChJsh \\/ LipFV\"},{\"t\":5,\"n\":\"DST \\/ LipK\"},{\"t\":5,\"n\":\"Eee \\/ LipL\"},{\"t\":5,\"n\":\"Eh \\/ LipR\"},{\"t\":5,\"n\":\"FV \\/ LipTh\"},{\"t\":5,\"n\":\"I\"},{\"t\":5,\"n\":\"K\"},{\"t\":5,\"n\":\"N\"},{\"t\":5,\"n\":\"Oh\"},{\"t\":5,\"n\":\"OohQ\"},{\"t\":5,\"n\":\"R\"},{\"t\":5,\"n\":\"TH\"},{\"t\":5,\"n\":\"W\"}]}]},{\"t\":6,\"n\":\"L\",\"c\":[{\"t\":6,\"n\":\"PHWT - Phoneme Target Weight\",\"c\":[{\"t\":5,\"n\":\"Aah \\/ LipBigAah\"},{\"t\":5,\"n\":\"BigAah \\/ LipDST\"},{\"t\":5,\"n\":\"BMP \\/ LipEee\"},{\"t\":5,\"n\":\"ChJsh \\/ LipFV\"},{\"t\":5,\"n\":\"DST \\/ LipK\"},{\"t\":5,\"n\":\"Eee \\/ LipL\"},{\"t\":5,\"n\":\"Eh \\/ LipR\"},{\"t\":5,\"n\":\"FV \\/ LipTh\"},{\"t\":5,\"n\":\"I\"},{\"t\":5,\"n\":\"K\"},{\"t\":5,\"n\":\"N\"},{\"t\":5,\"n\":\"Oh\"},{\"t\":5,\"n\":\"OohQ\"},{\"t\":5,\"n\":\"R\"},{\"t\":5,\"n\":\"TH\"},{\"t\":5,\"n\":\"W\"}]}]},{\"t\":6,\"n\":\"R\",\"c\":[{\"t\":6,\"n\":\"PHWT - Phoneme Target Weight\",\"c\":[{\"t\":5,\"n\":\"Aah \\/ LipBigAah\"},{\"t\":5,\"n\":\"BigAah \\/ LipDST\"},{\"t\":5,\"n\":\"BMP \\/ LipEee\"},{\"t\":5,\"n\":\"ChJsh \\/ LipFV\"},{\"t\":5,\"n\":\"DST \\/ LipK\"},{\"t\":5,\"n\":\"Eee \\/ LipL\"},{\"t\":5,\"n\":\"Eh \\/ LipR\"},{\"t\":5,\"n\":\"FV \\/ LipTh\"},{\"t\":5,\"n\":\"I\"},{\"t\":5,\"n\":\"K\"},{\"t\":5,\"n\":\"N\"},{\"t\":5,\"n\":\"Oh\"},{\"t\":5,\"n\":\"OohQ\"},{\"t\":5,\"n\":\"R\"},{\"t\":5,\"n\":\"TH\"},{\"t\":5,\"n\":\"W\"}]}]},{\"t\":6,\"n\":\"W\",\"c\":[{\"t\":6,\"n\":\"PHWT - Phoneme Target Weight\",\"c\":[{\"t\":5,\"n\":\"Aah \\/ LipBigAah\"},{\"t\":5,\"n\":\"BigAah \\/ LipDST\"},{\"t\":5,\"n\":\"BMP \\/ LipEee\"},{\"t\":5,\"n\":\"ChJsh \\/ LipFV\"},{\"t\":5,\"n\":\"DST \\/ LipK\"},{\"t\":5,\"n\":\"Eee \\/ LipL\"},{\"t\":5,\"n\":\"Eh \\/ LipR\"},{\"t\":5,\"n\":\"FV \\/ LipTh\"},{\"t\":5,\"n\":\"I\"},{\"t\":5,\"n\":\"K\"},{\"t\":5,\"n\":\"N\"},{\"t\":5,\"n\":\"Oh\"},{\"t\":5,\"n\":\"OohQ\"},{\"t\":5,\"n\":\"R\"},{\"t\":5,\"n\":\"TH\"},{\"t\":5,\"n\":\"W\"}]}]},{\"t\":6,\"n\":\"Y\",\"c\":[{\"t\":6,\"n\":\"PHWT - Phoneme Target Weight\",\"c\":[{\"t\":5,\"n\":\"Aah \\/ LipBigAah\"},{\"t\":5,\"n\":\"BigAah \\/ LipDST\"},{\"t\":5,\"n\":\"BMP \\/ LipEee\"},{\"t\":5,\"n\":\"ChJsh \\/ LipFV\"},{\"t\":5,\"n\":\"DST \\/ LipK\"},{\"t\":5,\"n\":\"Eee \\/ LipL\"},{\"t\":5,\"n\":\"Eh \\/ LipR\"},{\"t\":5,\"n\":\"FV \\/ LipTh\"},{\"t\":5,\"n\":\"I\"},{\"t\":5,\"n\":\"K\"},{\"t\":5,\"n\":\"N\"},{\"t\":5,\"n\":\"Oh\"},{\"t\":5,\"n\":\"OohQ\"},{\"t\":5,\"n\":\"R\"},{\"t\":5,\"n\":\"TH\"},{\"t\":5,\"n\":\"W\"}]}]},{\"t\":6,\"n\":\"HH\",\"c\":[{\"t\":6,\"n\":\"PHWT - Phoneme Target Weight\",\"c\":[{\"t\":5,\"n\":\"Aah \\/ LipBigAah\"},{\"t\":5,\"n\":\"BigAah \\/ LipDST\"},{\"t\":5,\"n\":\"BMP \\/ LipEee\"},{\"t\":5,\"n\":\"ChJsh \\/ LipFV\"},{\"t\":5,\"n\":\"DST \\/ LipK\"},{\"t\":5,\"n\":\"Eee \\/ LipL\"},{\"t\":5,\"n\":\"Eh \\/ LipR\"},{\"t\":5,\"n\":\"FV \\/ LipTh\"},{\"t\":5,\"n\":\"I\"},{\"t\":5,\"n\":\"K\"},{\"t\":5,\"n\":\"N\"},{\"t\":5,\"n\":\"Oh\"},{\"t\":5,\"n\":\"OohQ\"},{\"t\":5,\"n\":\"R\"},{\"t\":5,\"n\":\"TH\"},{\"t\":5,\"n\":\"W\"}]}]},{\"t\":6,\"n\":\"B\",\"c\":[{\"t\":6,\"n\":\"PHWT - Phoneme Target Weight\",\"c\":[{\"t\":5,\"n\":\"Aah \\/ LipBigAah\"},{\"t\":5,\"n\":\"BigAah \\/ LipDST\"},{\"t\":5,\"n\":\"BMP \\/ LipEee\"},{\"t\":5,\"n\":\"ChJsh \\/ LipFV\"},{\"t\":5,\"n\":\"DST \\/ LipK\"},{\"t\":5,\"n\":\"Eee \\/ LipL\"},{\"t\":5,\"n\":\"Eh \\/ LipR\"},{\"t\":5,\"n\":\"FV \\/ LipTh\"},{\"t\":5,\"n\":\"I\"},{\"t\":5,\"n\":\"K\"},{\"t\":5,\"n\":\"N\"},{\"t\":5,\"n\":\"Oh\"},{\"t\":5,\"n\":\"OohQ\"},{\"t\":5,\"n\":\"R\"},{\"t\":5,\"n\":\"TH\"},{\"t\":5,\"n\":\"W\"}]}]},{\"t\":6,\"n\":\"D\",\"c\":[{\"t\":6,\"n\":\"PHWT - Phoneme Target Weight\",\"c\":[{\"t\":5,\"n\":\"Aah \\/ LipBigAah\"},{\"t\":5,\"n\":\"BigAah \\/ LipDST\"},{\"t\":5,\"n\":\"BMP \\/ LipEee\"},{\"t\":5,\"n\":\"ChJsh \\/ LipFV\"},{\"t\":5,\"n\":\"DST \\/ LipK\"},{\"t\":5,\"n\":\"Eee \\/ LipL\"},{\"t\":5,\"n\":\"Eh \\/ LipR\"},{\"t\":5,\"n\":\"FV \\/ LipTh\"},{\"t\":5,\"n\":\"I\"},{\"t\":5,\"n\":\"K\"},{\"t\":5,\"n\":\"N\"},{\"t\":5,\"n\":\"Oh\"},{\"t\":5,\"n\":\"OohQ\"},{\"t\":5,\"n\":\"R\"},{\"t\":5,\"n\":\"TH\"},{\"t\":5,\"n\":\"W\"}]}]},{\"t\":6,\"n\":\"JH\",\"c\":[{\"t\":6,\"n\":\"PHWT - Phoneme Target Weight\",\"c\":[{\"t\":5,\"n\":\"Aah \\/ LipBigAah\"},{\"t\":5,\"n\":\"BigAah \\/ LipDST\"},{\"t\":5,\"n\":\"BMP \\/ LipEee\"},{\"t\":5,\"n\":\"ChJsh \\/ LipFV\"},{\"t\":5,\"n\":\"DST \\/ LipK\"},{\"t\":5,\"n\":\"Eee \\/ LipL\"},{\"t\":5,\"n\":\"Eh \\/ LipR\"},{\"t\":5,\"n\":\"FV \\/ LipTh\"},{\"t\":5,\"n\":\"I\"},{\"t\":5,\"n\":\"K\"},{\"t\":5,\"n\":\"N\"},{\"t\":5,\"n\":\"Oh\"},{\"t\":5,\"n\":\"OohQ\"},{\"t\":5,\"n\":\"R\"},{\"t\":5,\"n\":\"TH\"},{\"t\":5,\"n\":\"W\"}]}]},{\"t\":6,\"n\":\"G\",\"c\":[{\"t\":6,\"n\":\"PHWT - Phoneme Target Weight\",\"c\":[{\"t\":5,\"n\":\"Aah \\/ LipBigAah\"},{\"t\":5,\"n\":\"BigAah \\/ LipDST\"},{\"t\":5,\"n\":\"BMP \\/ LipEee\"},{\"t\":5,\"n\":\"ChJsh \\/ LipFV\"},{\"t\":5,\"n\":\"DST \\/ LipK\"},{\"t\":5,\"n\":\"Eee \\/ LipL\"},{\"t\":5,\"n\":\"Eh \\/ LipR\"},{\"t\":5,\"n\":\"FV \\/ LipTh\"},{\"t\":5,\"n\":\"I\"},{\"t\":5,\"n\":\"K\"},{\"t\":5,\"n\":\"N\"},{\"t\":5,\"n\":\"Oh\"},{\"t\":5,\"n\":\"OohQ\"},{\"t\":5,\"n\":\"R\"},{\"t\":5,\"n\":\"TH\"},{\"t\":5,\"n\":\"W\"}]}]},{\"t\":6,\"n\":\"P\",\"c\":[{\"t\":6,\"n\":\"PHWT - Phoneme Target Weight\",\"c\":[{\"t\":5,\"n\":\"Aah \\/ LipBigAah\"},{\"t\":5,\"n\":\"BigAah \\/ LipDST\"},{\"t\":5,\"n\":\"BMP \\/ LipEee\"},{\"t\":5,\"n\":\"ChJsh \\/ LipFV\"},{\"t\":5,\"n\":\"DST \\/ LipK\"},{\"t\":5,\"n\":\"Eee \\/ LipL\"},{\"t\":5,\"n\":\"Eh \\/ LipR\"},{\"t\":5,\"n\":\"FV \\/ LipTh\"},{\"t\":5,\"n\":\"I\"},{\"t\":5,\"n\":\"K\"},{\"t\":5,\"n\":\"N\"},{\"t\":5,\"n\":\"Oh\"},{\"t\":5,\"n\":\"OohQ\"},{\"t\":5,\"n\":\"R\"},{\"t\":5,\"n\":\"TH\"},{\"t\":5,\"n\":\"W\"}]}]},{\"t\":6,\"n\":\"T\",\"c\":[{\"t\":6,\"n\":\"PHWT - Phoneme Target Weight\",\"c\":[{\"t\":5,\"n\":\"Aah \\/ LipBigAah\"},{\"t\":5,\"n\":\"BigAah \\/ LipDST\"},{\"t\":5,\"n\":\"BMP \\/ LipEee\"},{\"t\":5,\"n\":\"ChJsh \\/ LipFV\"},{\"t\":5,\"n\":\"DST \\/ LipK\"},{\"t\":5,\"n\":\"Eee \\/ LipL\"},{\"t\":5,\"n\":\"Eh \\/ LipR\"},{\"t\":5,\"n\":\"FV \\/ LipTh\"},{\"t\":5,\"n\":\"I\"},{\"t\":5,\"n\":\"K\"},{\"t\":5,\"n\":\"N\"},{\"t\":5,\"n\":\"Oh\"},{\"t\":5,\"n\":\"OohQ\"},{\"t\":5,\"n\":\"R\"},{\"t\":5,\"n\":\"TH\"},{\"t\":5,\"n\":\"W\"}]}]},{\"t\":6,\"n\":\"K\",\"c\":[{\"t\":6,\"n\":\"PHWT - Phoneme Target Weight\",\"c\":[{\"t\":5,\"n\":\"Aah \\/ LipBigAah\"},{\"t\":5,\"n\":\"BigAah \\/ LipDST\"},{\"t\":5,\"n\":\"BMP \\/ LipEee\"},{\"t\":5,\"n\":\"ChJsh \\/ LipFV\"},{\"t\":5,\"n\":\"DST \\/ LipK\"},{\"t\":5,\"n\":\"Eee \\/ LipL\"},{\"t\":5,\"n\":\"Eh \\/ LipR\"},{\"t\":5,\"n\":\"FV \\/ LipTh\"},{\"t\":5,\"n\":\"I\"},{\"t\":5,\"n\":\"K\"},{\"t\":5,\"n\":\"N\"},{\"t\":5,\"n\":\"Oh\"},{\"t\":5,\"n\":\"OohQ\"},{\"t\":5,\"n\":\"R\"},{\"t\":5,\"n\":\"TH\"},{\"t\":5,\"n\":\"W\"}]}]},{\"t\":6,\"n\":\"CH\",\"c\":[{\"t\":6,\"n\":\"PHWT - Phoneme Target Weight\",\"c\":[{\"t\":5,\"n\":\"Aah \\/ LipBigAah\"},{\"t\":5,\"n\":\"BigAah \\/ LipDST\"},{\"t\":5,\"n\":\"BMP \\/ LipEee\"},{\"t\":5,\"n\":\"ChJsh \\/ LipFV\"},{\"t\":5,\"n\":\"DST \\/ LipK\"},{\"t\":5,\"n\":\"Eee \\/ LipL\"},{\"t\":5,\"n\":\"Eh \\/ LipR\"},{\"t\":5,\"n\":\"FV \\/ LipTh\"},{\"t\":5,\"n\":\"I\"},{\"t\":5,\"n\":\"K\"},{\"t\":5,\"n\":\"N\"},{\"t\":5,\"n\":\"Oh\"},{\"t\":5,\"n\":\"OohQ\"},{\"t\":5,\"n\":\"R\"},{\"t\":5,\"n\":\"TH\"},{\"t\":5,\"n\":\"W\"}]}]},{\"t\":6,\"n\":\"SIL\",\"c\":[{\"t\":6,\"n\":\"PHWT - Phoneme Target Weight\",\"c\":[{\"t\":5,\"n\":\"Aah \\/ LipBigAah\"},{\"t\":5,\"n\":\"BigAah \\/ LipDST\"},{\"t\":5,\"n\":\"BMP \\/ LipEee\"},{\"t\":5,\"n\":\"ChJsh \\/ LipFV\"},{\"t\":5,\"n\":\"DST \\/ LipK\"},{\"t\":5,\"n\":\"Eee \\/ LipL\"},{\"t\":5,\"n\":\"Eh \\/ LipR\"},{\"t\":5,\"n\":\"FV \\/ LipTh\"},{\"t\":5,\"n\":\"I\"},{\"t\":5,\"n\":\"K\"},{\"t\":5,\"n\":\"N\"},{\"t\":5,\"n\":\"Oh\"},{\"t\":5,\"n\":\"OohQ\"},{\"t\":5,\"n\":\"R\"},{\"t\":5,\"n\":\"TH\"},{\"t\":5,\"n\":\"W\"}]}]},{\"t\":6,\"n\":\"SHOTSIL\",\"c\":[{\"t\":6,\"n\":\"PHWT - Phoneme Target Weight\",\"c\":[{\"t\":5,\"n\":\"Aah \\/ LipBigAah\"},{\"t\":5,\"n\":\"BigAah \\/ LipDST\"},{\"t\":5,\"n\":\"BMP \\/ LipEee\"},{\"t\":5,\"n\":\"ChJsh \\/ LipFV\"},{\"t\":5,\"n\":\"DST \\/ LipK\"},{\"t\":5,\"n\":\"Eee \\/ LipL\"},{\"t\":5,\"n\":\"Eh \\/ LipR\"},{\"t\":5,\"n\":\"FV \\/ LipTh\"},{\"t\":5,\"n\":\"I\"},{\"t\":5,\"n\":\"K\"},{\"t\":5,\"n\":\"N\"},{\"t\":5,\"n\":\"Oh\"},{\"t\":5,\"n\":\"OohQ\"},{\"t\":5,\"n\":\"R\"},{\"t\":5,\"n\":\"TH\"},{\"t\":5,\"n\":\"W\"}]}]},{\"t\":6,\"n\":\"FLAP\",\"c\":[{\"t\":6,\"n\":\"PHWT - Phoneme Target Weight\",\"c\":[{\"t\":5,\"n\":\"Aah \\/ LipBigAah\"},{\"t\":5,\"n\":\"BigAah \\/ LipDST\"},{\"t\":5,\"n\":\"BMP \\/ LipEee\"},{\"t\":5,\"n\":\"ChJsh \\/ LipFV\"},{\"t\":5,\"n\":\"DST \\/ LipK\"},{\"t\":5,\"n\":\"Eee \\/ LipL\"},{\"t\":5,\"n\":\"Eh \\/ LipR\"},{\"t\":5,\"n\":\"FV \\/ LipTh\"},{\"t\":5,\"n\":\"I\"},{\"t\":5,\"n\":\"K\"},{\"t\":5,\"n\":\"N\"},{\"t\":5,\"n\":\"Oh\"},{\"t\":5,\"n\":\"OohQ\"},{\"t\":5,\"n\":\"R\"},{\"t\":5,\"n\":\"TH\"},{\"t\":5,\"n\":\"W\"}]}]}]},{\"t\":3,\"n\":\"WKMV - Base Movement Default - Walk\"},{\"t\":3,\"n\":\"RNMV - Base Movement Default - Run\"},{\"t\":3,\"n\":\"SWMV - Base Movement Default - Swim\"},{\"t\":3,\"n\":\"FLMV - Base Movement Default - Fly\"},{\"t\":3,\"n\":\"SNMV - Base Movement Default - Sneak\"},{\"t\":3,\"n\":\"SPMV - Base Movement Default - Sprint\"},{\"t\":6,\"p\":1,\"n\":\"Head Data\",\"c\":[{\"n\":\"NAM0 - Head Data Marker\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Male Head Data\",\"c\":[{\"p\":1,\"n\":\"MNAM - Male Data Marker\"},{\"t\":10,\"p\":1,\"n\":\"Head Parts\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Head Part\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"INDX - Head Part Number\"},{\"t\":3,\"p\":1,\"n\":\"HEAD - Head\"}]}]},{\"t\":6,\"n\":\"Available Morphs\",\"c\":[{\"t\":11,\"n\":\"MPAI - Unknown\"},{\"t\":6,\"n\":\"MPAV - Nose Variants\",\"c\":[{\"t\":3,\"n\":\"Nose Morph Flags\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":6,\"n\":\"MPAV - Brow Variants\",\"c\":[{\"t\":3,\"n\":\"Brow Morph Flags\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":6,\"n\":\"MPAV - Eye Variants\",\"c\":[{\"t\":3,\"n\":\"Eye Morph Flags 1\"},{\"t\":3,\"n\":\"Eye Morph Flags 2\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":6,\"n\":\"MPAV - Lip Variants\",\"c\":[{\"t\":3,\"n\":\"Lip Morph Flags\"},{\"t\":11,\"n\":\"Unknown\"}]}]},{\"t\":8,\"n\":\"Race Presets Male\",\"c\":[{\"t\":3,\"n\":\"RPRM - Preset NPC\"}]},{\"t\":8,\"n\":\"Available Hair Colors Male\",\"c\":[{\"t\":3,\"n\":\"AHCM - Hair Color\"}]},{\"t\":8,\"n\":\"Face Details Texture Set List Male\",\"c\":[{\"t\":3,\"n\":\"FTSM - Texture Set\"}]},{\"t\":3,\"n\":\"DFTM - Default Face Texture Male\"},{\"t\":8,\"p\":1,\"n\":\"Tint Masks\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Tint Assets\",\"c\":[{\"t\":8,\"p\":1,\"n\":\"Tint Layer\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Texture\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"TINI - Index\"},{\"t\":2,\"p\":1,\"n\":\"TINT - File Name\"},{\"t\":3,\"p\":1,\"n\":\"TINP - Mask Type\"},{\"t\":3,\"p\":1,\"n\":\"TIND - Preset Default\"}]}]},{\"t\":8,\"p\":1,\"n\":\"Presets\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Preset\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"TINC - Color\"},{\"t\":5,\"p\":1,\"n\":\"TINV - Default Value\"},{\"t\":3,\"p\":1,\"n\":\"TIRS - Index\"}]}]}]}]},{\"t\":6,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"MODT - Texture Files Hashes\"},{\"t\":7,\"p\":1,\"n\":\"MODS - Alternate Textures\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"3D Name\"},{\"t\":3,\"p\":1,\"n\":\"New Texture\"},{\"t\":3,\"p\":1,\"n\":\"3D Index\"}]}]}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Female Head Data\",\"c\":[{\"p\":1,\"n\":\"NAM0 - Head Data Marker\"},{\"p\":1,\"n\":\"FNAM - Female Data Marker\"},{\"t\":10,\"p\":1,\"n\":\"Head Parts\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Head Part\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"INDX - Head Part Number\"},{\"t\":3,\"p\":1,\"n\":\"HEAD - Head\"}]}]},{\"t\":6,\"n\":\"Available Morphs\",\"c\":[{\"t\":11,\"n\":\"MPAI - Unknown\"},{\"t\":6,\"n\":\"MPAV - Nose Variants\",\"c\":[{\"t\":3,\"n\":\"Nose Morph Flags\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":6,\"n\":\"MPAV - Brow Variants\",\"c\":[{\"t\":3,\"n\":\"Brow Morph Flags\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":6,\"n\":\"MPAV - Eye Variants\",\"c\":[{\"t\":3,\"n\":\"Eye Morph Flags 1\"},{\"t\":3,\"n\":\"Eye Morph Flags 2\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":6,\"n\":\"MPAV - Lip Variants\",\"c\":[{\"t\":3,\"n\":\"Lip Morph Flags\"},{\"t\":11,\"n\":\"Unknown\"}]}]},{\"t\":8,\"n\":\"Race Presets Female\",\"c\":[{\"t\":3,\"n\":\"RPRF - Preset NPC\"}]},{\"t\":8,\"n\":\"Available Hair Colors Female\",\"c\":[{\"t\":3,\"n\":\"AHCF - Hair Color\"}]},{\"t\":8,\"n\":\"Face Details Texture Set List Female\",\"c\":[{\"t\":3,\"n\":\"FTSF - Texture Set\"}]},{\"t\":3,\"n\":\"DFTF - Default Face Texture Female\"},{\"t\":8,\"p\":1,\"n\":\"Tint Masks\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Tint Assets\",\"c\":[{\"t\":8,\"p\":1,\"n\":\"Tint Layer\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Texture\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"TINI - Index\"},{\"t\":2,\"p\":1,\"n\":\"TINT - File Name\"},{\"t\":3,\"p\":1,\"n\":\"TINP - Mask Type\"},{\"t\":3,\"p\":1,\"n\":\"TIND - Preset Default\"}]}]},{\"t\":8,\"p\":1,\"n\":\"Presets\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Preset\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"TINC - Color\"},{\"t\":5,\"p\":1,\"n\":\"TINV - Default Value\"},{\"t\":3,\"p\":1,\"n\":\"TIRS - Index\"}]}]}]}]},{\"t\":6,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"MODT - Texture Files Hashes\"},{\"t\":7,\"p\":1,\"n\":\"MODS - Alternate Textures\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"3D Name\"},{\"t\":3,\"p\":1,\"n\":\"New Texture\"},{\"t\":3,\"p\":1,\"n\":\"3D Index\"}]}]}]}]}]},{\"t\":3,\"n\":\"NAM8 - Morph race\"},{\"t\":3,\"n\":\"RNAM - Armor race\"}]},{\"t\":1,\"p\":1,\"n\":\"REFR - Placed Object\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"VMAD - Virtual Machine Adapter\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Version\"},{\"t\":3,\"p\":1,\"n\":\"Object Format\"},{\"t\":7,\"p\":1,\"n\":\"Scripts\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Script\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"scriptName\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":7,\"p\":1,\"n\":\"Properties\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Property\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"propertyName\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]},{\"t\":2,\"p\":1,\"n\":\"String\"},{\"t\":3,\"p\":1,\"n\":\"Int32\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":3,\"p\":1,\"n\":\"Bool\"},{\"t\":7,\"p\":1,\"n\":\"Array of Object\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]}]},{\"t\":7,\"p\":1,\"n\":\"Array of String\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Int32\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Float\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Bool\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]}]}]}]}]}]},{\"t\":3,\"p\":1,\"n\":\"NAME - Base\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"XMBO - Bound Half Extents\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"X\"},{\"t\":5,\"p\":1,\"n\":\"Y\"},{\"t\":5,\"p\":1,\"n\":\"Z\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"XPRM - Primitive\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Bounds\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"X\"},{\"t\":5,\"p\":1,\"n\":\"Y\"},{\"t\":5,\"p\":1,\"n\":\"Z\"}]},{\"t\":6,\"p\":1,\"n\":\"Color\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Red\"},{\"t\":5,\"p\":1,\"n\":\"Green\"},{\"t\":5,\"p\":1,\"n\":\"Blue\"}]},{\"t\":5,\"n\":\"Unknown\"},{\"t\":3,\"p\":1,\"n\":\"Type\"}]},{\"t\":11,\"n\":\"XORD - Unknown\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"XOCP - Occlusion Plane Data\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Size\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Width\"},{\"t\":5,\"p\":1,\"n\":\"Height\"}]},{\"t\":6,\"p\":1,\"n\":\"Position\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"X\"},{\"t\":5,\"p\":1,\"n\":\"Y\"},{\"t\":5,\"p\":1,\"n\":\"Z\"}]},{\"t\":6,\"p\":1,\"n\":\"Rotation (Quaternion?)\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"q1\"},{\"t\":5,\"p\":1,\"n\":\"q2\"},{\"t\":5,\"p\":1,\"n\":\"q3\"},{\"t\":5,\"p\":1,\"n\":\"q4\"}]}]},{\"t\":7,\"p\":1,\"n\":\"XPOD - Portal Data\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"References\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Origin\"},{\"t\":3,\"p\":1,\"n\":\"Destination\"}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"XPTL - Room Portal (unused)\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Size\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Width\"},{\"t\":5,\"p\":1,\"n\":\"Height\"}]},{\"t\":6,\"p\":1,\"n\":\"Position\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"X\"},{\"t\":5,\"p\":1,\"n\":\"Y\"},{\"t\":5,\"p\":1,\"n\":\"Z\"}]},{\"t\":6,\"p\":1,\"n\":\"Rotation (Quaternion?)\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"q1\"},{\"t\":5,\"p\":1,\"n\":\"q2\"},{\"t\":5,\"p\":1,\"n\":\"q3\"},{\"t\":5,\"p\":1,\"n\":\"q4\"}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Bound Data\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"XRMR - Header\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Linked Rooms Count\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":3,\"p\":1,\"n\":\"LNAM - Lighting Template\"},{\"t\":3,\"p\":1,\"n\":\"INAM - Image Space\"},{\"t\":8,\"p\":1,\"n\":\"Linked Rooms\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"XLRM - Linked Room\"}]}]},{\"p\":1,\"n\":\"XMBP - MultiBound Primitive Marker\"},{\"t\":11,\"n\":\"XRGD - Ragdoll Data\"},{\"t\":11,\"n\":\"XRGB - Ragdoll Biped Data\"},{\"t\":5,\"p\":1,\"n\":\"XRDS - Radius\"},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Reflected\\/Refracted By\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"XPWR - Water\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":3,\"p\":1,\"n\":\"Type\"}]}]},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Lit Water\",\"d\":1,\"c\":[{\"t\":3,\"p\":1,\"n\":\"XLTW - Water\"}]},{\"t\":3,\"p\":1,\"n\":\"XEMI - Emittance\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"XLIG - Light Data\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"FOV 90+\\/-\"},{\"t\":5,\"p\":1,\"n\":\"Fade 1.35+\\/-\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":5,\"p\":1,\"n\":\"Shadow Depth Bias\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"XALP - Alpha\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Cutoff\"},{\"t\":3,\"p\":1,\"n\":\"Base\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"XTEL - Teleport Destination\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Door\"},{\"t\":6,\"p\":1,\"n\":\"Position\\/Rotation\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Position\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"X\"},{\"t\":5,\"p\":1,\"n\":\"Y\"},{\"t\":5,\"p\":1,\"n\":\"Z\"}]},{\"t\":6,\"p\":1,\"n\":\"Rotation\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"X\"},{\"t\":5,\"p\":1,\"n\":\"Y\"},{\"t\":5,\"p\":1,\"n\":\"Z\"}]}]},{\"t\":3,\"p\":1,\"n\":\"Flags\"}]},{\"t\":3,\"p\":1,\"n\":\"XTNM - Teleport Message Box\"},{\"t\":3,\"p\":1,\"n\":\"XMBR - MultiBound Reference\"},{\"t\":11,\"n\":\"XWCN - Unknown\"},{\"t\":11,\"n\":\"XWCS - Unknown\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"XWCU - Water Velocity\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"X Offset\"},{\"t\":5,\"p\":1,\"n\":\"Y Offset\"},{\"t\":5,\"p\":1,\"n\":\"Z Offset\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":5,\"p\":1,\"n\":\"X Angle\"},{\"t\":5,\"p\":1,\"n\":\"Y Angle\"},{\"t\":5,\"p\":1,\"n\":\"Z Angle\"}]},{\"t\":6,\"n\":\"XCVL - Unknown\",\"c\":[{\"t\":11,\"n\":\"Unknown\"},{\"t\":5,\"n\":\"X Angle\"}]},{\"t\":3,\"n\":\"XCZR - Unknown\"},{\"t\":11,\"n\":\"XCZA - Unknown\"},{\"t\":3,\"n\":\"XCZC - Unknown\"},{\"t\":5,\"p\":1,\"n\":\"XSCL - Scale\"},{\"t\":3,\"p\":1,\"n\":\"XSPC - Spawn Container\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Activate Parents\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"XAPD - Flags\"},{\"t\":8,\"p\":1,\"n\":\"Activate Parent Refs\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"XAPR - Activate Parent Ref\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":5,\"p\":1,\"n\":\"Delay\"}]}]}]},{\"t\":3,\"p\":1,\"n\":\"XLIB - Leveled Item Base Object\"},{\"t\":3,\"p\":1,\"n\":\"XLCM - Level Modifier\"},{\"t\":3,\"p\":1,\"n\":\"XLCN - Persistent Location\"},{\"t\":3,\"p\":1,\"n\":\"XTRI - Collision Layer\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"XLOC - Lock Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Level\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Key\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"}]},{\"t\":3,\"p\":1,\"n\":\"XEZN - Encounter Zone\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"XNDP - Navigation Door Link\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Navigation Mesh\"},{\"t\":3,\"p\":1,\"n\":\"Teleport Marker Triangle\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":7,\"p\":1,\"n\":\"XLRT - Location Ref Type\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Ref\"}]},{\"p\":1,\"n\":\"XIS2 - Ignored by Sandbox\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Ownership\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"XOWN - Owner\"},{\"t\":3,\"p\":1,\"n\":\"XRNK - Faction rank\"}]},{\"t\":3,\"p\":1,\"n\":\"XCNT - Item Count\"},{\"t\":5,\"p\":1,\"n\":\"XCHG - Charge\"},{\"t\":3,\"p\":1,\"n\":\"XLRL - Location Reference\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"XESP - Enable Parent\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Linked References\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"XLKR - Linked Reference\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Keyword\\/Ref\"},{\"t\":3,\"p\":1,\"n\":\"Ref\"}]}]},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Patrol\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Data\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"XPRD - Idle Time\"},{\"p\":1,\"n\":\"XPPA - Patrol Script Marker\"},{\"t\":3,\"p\":1,\"n\":\"INAM - Idle\"},{\"t\":11,\"n\":\"SCHR - Unused\"},{\"t\":11,\"n\":\"SCTX - Unused\"},{\"t\":8,\"p\":1,\"n\":\"Topic\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"PDTO - Topic Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Topic\"},{\"t\":2,\"p\":1,\"n\":\"Subtype\"}]}]}]}]},{\"t\":3,\"p\":1,\"n\":\"XACT - Action Flag\"},{\"t\":5,\"p\":1,\"n\":\"XHTW - Head-Tracking Weight\"},{\"t\":5,\"p\":1,\"n\":\"XFVC - Favor Cost\"},{\"p\":1,\"n\":\"ONAM - Open by Default\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Map Marker\",\"c\":[{\"p\":1,\"n\":\"XMRK - Map Marker Data\"},{\"t\":3,\"p\":1,\"n\":\"FNAM - Map Flags\"},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":6,\"p\":1,\"n\":\"TNAM - \",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":11,\"n\":\"Unused\"}]}]},{\"t\":3,\"p\":1,\"n\":\"XATR - Attach Ref\"},{\"t\":7,\"n\":\"XLOD - Distant LOD Data\",\"c\":[{\"t\":5,\"n\":\"Unknown\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DATA - Position\\/Rotation\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Position\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"X\"},{\"t\":5,\"p\":1,\"n\":\"Y\"},{\"t\":5,\"p\":1,\"n\":\"Z\"}]},{\"t\":6,\"p\":1,\"n\":\"Rotation\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"X\"},{\"t\":5,\"p\":1,\"n\":\"Y\"},{\"t\":5,\"p\":1,\"n\":\"Z\"}]}]}]},{\"t\":1,\"p\":1,\"n\":\"REGN - Region\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"RCLR - Map Color\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":3,\"p\":1,\"n\":\"WNAM - Worldspace\"},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Region Areas\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Region Area\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"RPLI - Edge Fall-off\"},{\"t\":7,\"p\":1,\"n\":\"RPLD - Region Point List Data\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Point\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"X\"},{\"t\":5,\"p\":1,\"n\":\"Y\"}]}]}]}]},{\"t\":10,\"p\":1,\"n\":\"Region Data Entries\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Region Data Entry\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"RDAT - Data Header\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":3,\"p\":1,\"n\":\"Priority\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":6,\"p\":1,\"n\":\"Icon\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"ICON - Large Icon filename\"},{\"t\":2,\"p\":1,\"n\":\"MICO - Small Icon filename\"}]},{\"t\":3,\"p\":1,\"n\":\"RDMO - Music\"},{\"t\":7,\"p\":1,\"n\":\"RDSA - Sounds\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Sound\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Sound\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":5,\"p\":1,\"n\":\"Chance\"}]}]},{\"t\":2,\"p\":1,\"n\":\"RDMP - Map Name\"},{\"t\":7,\"p\":1,\"n\":\"RDOT - Objects\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Object\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Object\"},{\"t\":3,\"p\":1,\"n\":\"Parent Index\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":5,\"p\":1,\"n\":\"Density\"},{\"t\":3,\"p\":1,\"n\":\"Clustering\"},{\"t\":3,\"p\":1,\"n\":\"Min Slope\"},{\"t\":3,\"p\":1,\"n\":\"Max Slope\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":3,\"p\":1,\"n\":\"Radius wrt Parent\"},{\"t\":3,\"p\":1,\"n\":\"Radius\"},{\"t\":5,\"p\":1,\"n\":\"Min Height\"},{\"t\":5,\"p\":1,\"n\":\"Max Height\"},{\"t\":5,\"p\":1,\"n\":\"Sink\"},{\"t\":5,\"p\":1,\"n\":\"Sink Variance\"},{\"t\":5,\"p\":1,\"n\":\"Size Variance\"},{\"t\":6,\"p\":1,\"n\":\"Angle Variance\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"X\"},{\"t\":3,\"p\":1,\"n\":\"Y\"},{\"t\":3,\"p\":1,\"n\":\"Z\"}]}]}]},{\"t\":7,\"p\":1,\"n\":\"RDGS - Grasses\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Grass\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Grass\"},{\"t\":11,\"n\":\"Unknown\"}]}]},{\"t\":7,\"p\":1,\"n\":\"RDWT - Weather Types\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Weather Type\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Weather\"},{\"t\":3,\"p\":1,\"n\":\"Chance\"},{\"t\":3,\"p\":1,\"n\":\"Global\"}]}]}]}]}]},{\"t\":1,\"p\":1,\"n\":\"RELA - Relationship\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DATA - Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Parent\"},{\"t\":3,\"p\":1,\"n\":\"Child\"},{\"t\":3,\"p\":1,\"n\":\"Rank\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":3,\"p\":1,\"n\":\"Association Type\"}]}]},{\"t\":1,\"p\":1,\"n\":\"REVB - Reverb Parameters\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DATA - Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Decay Time (ms)\"},{\"t\":3,\"p\":1,\"n\":\"HF Reference (Hz)\"},{\"t\":3,\"p\":1,\"n\":\"Room Filter\"},{\"t\":3,\"p\":1,\"n\":\"Room HF Filter\"},{\"t\":3,\"p\":1,\"n\":\"Reflections\"},{\"t\":3,\"p\":1,\"n\":\"Reverb Amp\"},{\"t\":3,\"p\":1,\"n\":\"Decay HF Ratio\"},{\"t\":3,\"p\":1,\"n\":\"Reflect Delay (ms), scaled\"},{\"t\":3,\"p\":1,\"n\":\"Reverb Delay (ms)\"},{\"t\":3,\"p\":1,\"n\":\"Diffusion %\"},{\"t\":3,\"p\":1,\"n\":\"Density %\"},{\"t\":3,\"n\":\"Unknown\"}]}]},{\"t\":1,\"p\":1,\"n\":\"RFCT - Visual Effect\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DATA - Effect Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Effect Art\"},{\"t\":3,\"p\":1,\"n\":\"Shader\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"}]}]},{\"t\":1,\"p\":1,\"n\":\"RGDL\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"}]},{\"t\":1,\"p\":1,\"n\":\"SCEN - Scene\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"VMAD - Virtual Machine Adapter\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Version\"},{\"t\":3,\"p\":1,\"n\":\"Object Format\"},{\"t\":7,\"p\":1,\"n\":\"Scripts\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Script\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"scriptName\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":7,\"p\":1,\"n\":\"Properties\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Property\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"propertyName\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]},{\"t\":2,\"p\":1,\"n\":\"String\"},{\"t\":3,\"p\":1,\"n\":\"Int32\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":3,\"p\":1,\"n\":\"Bool\"},{\"t\":7,\"p\":1,\"n\":\"Array of Object\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]}]},{\"t\":7,\"p\":1,\"n\":\"Array of String\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Int32\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Float\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Bool\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]}]}]}]}]},{\"t\":6,\"p\":1,\"n\":\"Script Fragments\",\"c\":[{\"t\":3,\"n\":\"Unknown\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":2,\"p\":1,\"n\":\"fileName\"},{\"t\":7,\"p\":1,\"n\":\"Fragments\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Fragment\",\"c\":[{\"t\":3,\"n\":\"Unknown\"},{\"t\":2,\"p\":1,\"n\":\"scriptName\"},{\"t\":2,\"p\":1,\"n\":\"fragmentName\"}]}]},{\"t\":7,\"p\":1,\"n\":\"Phase Fragments\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Phase Fragment\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Phase Flag\"},{\"t\":3,\"p\":1,\"n\":\"Phase Index\"},{\"t\":3,\"n\":\"Unknown\"},{\"t\":2,\"p\":1,\"n\":\"scriptName\"},{\"t\":2,\"p\":1,\"n\":\"fragmentName\"}]}]}]}]},{\"t\":3,\"p\":1,\"n\":\"FNAM - Flags\"},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Phases\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Phase\",\"c\":[{\"p\":1,\"n\":\"HNAM - Marker Phase Start\"},{\"t\":2,\"p\":1,\"n\":\"NAM0 - Name\"},{\"t\":6,\"p\":1,\"n\":\"Start Conditions\",\"c\":[{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Conditions\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Condition\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"CTDA - \",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":5,\"p\":1,\"n\":\"Comparison Value - Float\"},{\"t\":3,\"p\":1,\"n\":\"Comparison Value - Global\"},{\"t\":3,\"p\":1,\"n\":\"Function\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":11,\"p\":1,\"n\":\"None\"},{\"t\":3,\"p\":1,\"n\":\"Integer\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":11,\"p\":1,\"n\":\"Variable Name (unused)\"},{\"t\":3,\"p\":1,\"n\":\"Sex\"},{\"t\":3,\"p\":1,\"n\":\"Actor Value\"},{\"t\":3,\"p\":1,\"n\":\"Crime Type\"},{\"t\":3,\"p\":1,\"n\":\"Axis\"},{\"t\":3,\"p\":1,\"n\":\"Quest Stage (unused)\"},{\"t\":3,\"p\":1,\"n\":\"Misc Stat\"},{\"t\":3,\"p\":1,\"n\":\"Alignment\"},{\"t\":3,\"p\":1,\"n\":\"Equip Type\"},{\"t\":3,\"p\":1,\"n\":\"Form Type\"},{\"t\":3,\"p\":1,\"n\":\"Critical Stage\"},{\"t\":3,\"p\":1,\"n\":\"Object Reference\"},{\"t\":3,\"p\":1,\"n\":\"Inventory Object\"},{\"t\":3,\"p\":1,\"n\":\"Actor\"},{\"t\":3,\"p\":1,\"n\":\"Voice Type\"},{\"t\":3,\"p\":1,\"n\":\"Idle\"},{\"t\":3,\"p\":1,\"n\":\"Form List\"},{\"t\":3,\"p\":1,\"n\":\"Quest\"},{\"t\":3,\"p\":1,\"n\":\"Faction\"},{\"t\":3,\"p\":1,\"n\":\"Cell\"},{\"t\":3,\"p\":1,\"n\":\"Class\"},{\"t\":3,\"p\":1,\"n\":\"Race\"},{\"t\":3,\"p\":1,\"n\":\"Actor Base\"},{\"t\":3,\"p\":1,\"n\":\"Global\"},{\"t\":3,\"p\":1,\"n\":\"Weather\"},{\"t\":3,\"p\":1,\"n\":\"Package\"},{\"t\":3,\"p\":1,\"n\":\"Encounter Zone\"},{\"t\":3,\"p\":1,\"n\":\"Perk\"},{\"t\":3,\"p\":1,\"n\":\"Owner\"},{\"t\":3,\"p\":1,\"n\":\"Furniture\"},{\"t\":3,\"p\":1,\"n\":\"Effect Item\"},{\"t\":3,\"p\":1,\"n\":\"Base Effect\"},{\"t\":3,\"p\":1,\"n\":\"Worldspace\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Function\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Param (INVALID)\"},{\"t\":3,\"p\":1,\"n\":\"Referenceable Object\"},{\"t\":3,\"p\":1,\"n\":\"Region\"},{\"t\":3,\"p\":1,\"n\":\"Keyword\"},{\"t\":3,\"p\":1,\"n\":\"Player Action\"},{\"t\":3,\"p\":1,\"n\":\"Casting Type\"},{\"t\":3,\"p\":1,\"n\":\"Shout\"},{\"t\":3,\"p\":1,\"n\":\"Location\"},{\"t\":3,\"p\":1,\"n\":\"Location Ref Type\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"Packdata ID\"},{\"t\":3,\"p\":1,\"n\":\"Association Type\"},{\"t\":3,\"p\":1,\"n\":\"Furniture Anim\"},{\"t\":3,\"p\":1,\"n\":\"Furniture Entry\"},{\"t\":3,\"p\":1,\"n\":\"Scene\"},{\"t\":3,\"p\":1,\"n\":\"Ward State\"},{\"t\":3,\"p\":1,\"n\":\"Event\"},{\"t\":3,\"p\":1,\"n\":\"Event Data\"},{\"t\":3,\"p\":1,\"n\":\"Quest Stage\"},{\"t\":3,\"p\":1,\"n\":\"Weapon\"},{\"t\":3,\"p\":1,\"n\":\"Weapon List\"},{\"t\":3,\"p\":1,\"n\":\"Target\"},{\"t\":3,\"p\":1,\"n\":\"Target List\"},{\"t\":3,\"p\":1,\"n\":\"Target Part\"},{\"t\":3,\"p\":1,\"n\":\"VATS Action\"},{\"t\":3,\"p\":1,\"n\":\"Critical Effect\"},{\"t\":3,\"p\":1,\"n\":\"Critical Effect List\"},{\"t\":3,\"p\":1,\"n\":\"Weapon Type\"},{\"t\":3,\"p\":1,\"n\":\"Projectile Type\"},{\"t\":3,\"p\":1,\"n\":\"Delivery Type\"},{\"t\":3,\"p\":1,\"n\":\"Run On\"},{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":3,\"p\":1,\"n\":\"Parameter #3\"}]},{\"t\":2,\"p\":1,\"n\":\"CIS1 - Parameter #1\"},{\"t\":2,\"p\":1,\"n\":\"CIS2 - Parameter #2\"}]}]}]},{\"p\":1,\"n\":\"NEXT - Marker\"},{\"t\":6,\"p\":1,\"n\":\"Completion Conditions\",\"c\":[{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Conditions\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Condition\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"CTDA - \",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":5,\"p\":1,\"n\":\"Comparison Value - Float\"},{\"t\":3,\"p\":1,\"n\":\"Comparison Value - Global\"},{\"t\":3,\"p\":1,\"n\":\"Function\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":11,\"p\":1,\"n\":\"None\"},{\"t\":3,\"p\":1,\"n\":\"Integer\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":11,\"p\":1,\"n\":\"Variable Name (unused)\"},{\"t\":3,\"p\":1,\"n\":\"Sex\"},{\"t\":3,\"p\":1,\"n\":\"Actor Value\"},{\"t\":3,\"p\":1,\"n\":\"Crime Type\"},{\"t\":3,\"p\":1,\"n\":\"Axis\"},{\"t\":3,\"p\":1,\"n\":\"Quest Stage (unused)\"},{\"t\":3,\"p\":1,\"n\":\"Misc Stat\"},{\"t\":3,\"p\":1,\"n\":\"Alignment\"},{\"t\":3,\"p\":1,\"n\":\"Equip Type\"},{\"t\":3,\"p\":1,\"n\":\"Form Type\"},{\"t\":3,\"p\":1,\"n\":\"Critical Stage\"},{\"t\":3,\"p\":1,\"n\":\"Object Reference\"},{\"t\":3,\"p\":1,\"n\":\"Inventory Object\"},{\"t\":3,\"p\":1,\"n\":\"Actor\"},{\"t\":3,\"p\":1,\"n\":\"Voice Type\"},{\"t\":3,\"p\":1,\"n\":\"Idle\"},{\"t\":3,\"p\":1,\"n\":\"Form List\"},{\"t\":3,\"p\":1,\"n\":\"Quest\"},{\"t\":3,\"p\":1,\"n\":\"Faction\"},{\"t\":3,\"p\":1,\"n\":\"Cell\"},{\"t\":3,\"p\":1,\"n\":\"Class\"},{\"t\":3,\"p\":1,\"n\":\"Race\"},{\"t\":3,\"p\":1,\"n\":\"Actor Base\"},{\"t\":3,\"p\":1,\"n\":\"Global\"},{\"t\":3,\"p\":1,\"n\":\"Weather\"},{\"t\":3,\"p\":1,\"n\":\"Package\"},{\"t\":3,\"p\":1,\"n\":\"Encounter Zone\"},{\"t\":3,\"p\":1,\"n\":\"Perk\"},{\"t\":3,\"p\":1,\"n\":\"Owner\"},{\"t\":3,\"p\":1,\"n\":\"Furniture\"},{\"t\":3,\"p\":1,\"n\":\"Effect Item\"},{\"t\":3,\"p\":1,\"n\":\"Base Effect\"},{\"t\":3,\"p\":1,\"n\":\"Worldspace\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Function\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Param (INVALID)\"},{\"t\":3,\"p\":1,\"n\":\"Referenceable Object\"},{\"t\":3,\"p\":1,\"n\":\"Region\"},{\"t\":3,\"p\":1,\"n\":\"Keyword\"},{\"t\":3,\"p\":1,\"n\":\"Player Action\"},{\"t\":3,\"p\":1,\"n\":\"Casting Type\"},{\"t\":3,\"p\":1,\"n\":\"Shout\"},{\"t\":3,\"p\":1,\"n\":\"Location\"},{\"t\":3,\"p\":1,\"n\":\"Location Ref Type\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"Packdata ID\"},{\"t\":3,\"p\":1,\"n\":\"Association Type\"},{\"t\":3,\"p\":1,\"n\":\"Furniture Anim\"},{\"t\":3,\"p\":1,\"n\":\"Furniture Entry\"},{\"t\":3,\"p\":1,\"n\":\"Scene\"},{\"t\":3,\"p\":1,\"n\":\"Ward State\"},{\"t\":3,\"p\":1,\"n\":\"Event\"},{\"t\":3,\"p\":1,\"n\":\"Event Data\"},{\"t\":3,\"p\":1,\"n\":\"Quest Stage\"},{\"t\":3,\"p\":1,\"n\":\"Weapon\"},{\"t\":3,\"p\":1,\"n\":\"Weapon List\"},{\"t\":3,\"p\":1,\"n\":\"Target\"},{\"t\":3,\"p\":1,\"n\":\"Target List\"},{\"t\":3,\"p\":1,\"n\":\"Target Part\"},{\"t\":3,\"p\":1,\"n\":\"VATS Action\"},{\"t\":3,\"p\":1,\"n\":\"Critical Effect\"},{\"t\":3,\"p\":1,\"n\":\"Critical Effect List\"},{\"t\":3,\"p\":1,\"n\":\"Weapon Type\"},{\"t\":3,\"p\":1,\"n\":\"Projectile Type\"},{\"t\":3,\"p\":1,\"n\":\"Delivery Type\"},{\"t\":3,\"p\":1,\"n\":\"Run On\"},{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":3,\"p\":1,\"n\":\"Parameter #3\"}]},{\"t\":2,\"p\":1,\"n\":\"CIS1 - Parameter #1\"},{\"t\":2,\"p\":1,\"n\":\"CIS2 - Parameter #2\"}]}]}]},{\"t\":6,\"n\":\"Unused\",\"c\":[{\"t\":11,\"n\":\"SCHR - Unknown\"},{\"t\":11,\"n\":\"SCDA - Unknown\"},{\"t\":11,\"n\":\"SCTX - Unknown\"},{\"t\":11,\"n\":\"QNAM - Unknown\"},{\"t\":11,\"n\":\"SCRO - Unknown\"}]},{\"t\":3,\"p\":1,\"n\":\"WNAM - Editor Width\"},{\"p\":1,\"n\":\"HNAM - Marker Phase End\"}]}]},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Actors\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Actor\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"ALID - Actor ID\"},{\"t\":3,\"p\":1,\"n\":\"LNAM - Flags\"},{\"t\":3,\"p\":1,\"n\":\"DNAM - Behaviour Flags\"}]}]},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Actions\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Action\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"ANAM - Type\"},{\"t\":2,\"p\":1,\"n\":\"NAM0 - Name\"},{\"t\":3,\"p\":1,\"n\":\"ALID - Actor ID\"},{\"t\":11,\"n\":\"LNAM - Unknown\"},{\"t\":3,\"p\":1,\"n\":\"INAM - Index\"},{\"t\":3,\"p\":1,\"n\":\"FNAM - Flags\"},{\"t\":3,\"p\":1,\"n\":\"SNAM - Start Phase\"},{\"t\":3,\"p\":1,\"n\":\"ENAM - End Phase\"},{\"t\":5,\"p\":1,\"n\":\"SNAM - Timer Seconds\"},{\"t\":8,\"p\":1,\"n\":\"Packages\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"PNAM - Package\"}]},{\"t\":3,\"p\":1,\"n\":\"DATA - Topic\"},{\"t\":3,\"p\":1,\"n\":\"HTID - Headtrack Actor ID\"},{\"t\":5,\"p\":1,\"n\":\"DMAX - Looping - Max\"},{\"t\":5,\"p\":1,\"n\":\"DMIN - Looping - Min\"},{\"t\":3,\"p\":1,\"n\":\"DEMO - Emotion Type\"},{\"t\":3,\"p\":1,\"n\":\"DEVA - Emotion Value\"},{\"t\":6,\"n\":\"Unused\",\"c\":[{\"t\":11,\"n\":\"SCHR - Unknown\"},{\"t\":11,\"n\":\"SCDA - Unknown\"},{\"t\":11,\"n\":\"SCTX - Unknown\"},{\"t\":11,\"n\":\"QNAM - Unknown\"},{\"t\":11,\"n\":\"SCRO - Unknown\"}]},{\"p\":1,\"n\":\"ANAM - End Marker\"}]}]},{\"t\":6,\"n\":\"Unused\",\"c\":[{\"t\":11,\"n\":\"SCHR - Unknown\"},{\"t\":11,\"n\":\"SCDA - Unknown\"},{\"t\":11,\"n\":\"SCTX - Unknown\"},{\"t\":11,\"n\":\"QNAM - Unknown\"},{\"t\":11,\"n\":\"SCRO - Unknown\"}]},{\"p\":1,\"n\":\"NEXT - Marker\"},{\"t\":3,\"p\":1,\"n\":\"PNAM - Quest\"},{\"t\":3,\"p\":1,\"n\":\"INAM - Last Action Index\"},{\"t\":11,\"n\":\"VNAM - Unknown\"},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Conditions\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Condition\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"CTDA - \",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":5,\"p\":1,\"n\":\"Comparison Value - Float\"},{\"t\":3,\"p\":1,\"n\":\"Comparison Value - Global\"},{\"t\":3,\"p\":1,\"n\":\"Function\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":11,\"p\":1,\"n\":\"None\"},{\"t\":3,\"p\":1,\"n\":\"Integer\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":11,\"p\":1,\"n\":\"Variable Name (unused)\"},{\"t\":3,\"p\":1,\"n\":\"Sex\"},{\"t\":3,\"p\":1,\"n\":\"Actor Value\"},{\"t\":3,\"p\":1,\"n\":\"Crime Type\"},{\"t\":3,\"p\":1,\"n\":\"Axis\"},{\"t\":3,\"p\":1,\"n\":\"Quest Stage (unused)\"},{\"t\":3,\"p\":1,\"n\":\"Misc Stat\"},{\"t\":3,\"p\":1,\"n\":\"Alignment\"},{\"t\":3,\"p\":1,\"n\":\"Equip Type\"},{\"t\":3,\"p\":1,\"n\":\"Form Type\"},{\"t\":3,\"p\":1,\"n\":\"Critical Stage\"},{\"t\":3,\"p\":1,\"n\":\"Object Reference\"},{\"t\":3,\"p\":1,\"n\":\"Inventory Object\"},{\"t\":3,\"p\":1,\"n\":\"Actor\"},{\"t\":3,\"p\":1,\"n\":\"Voice Type\"},{\"t\":3,\"p\":1,\"n\":\"Idle\"},{\"t\":3,\"p\":1,\"n\":\"Form List\"},{\"t\":3,\"p\":1,\"n\":\"Quest\"},{\"t\":3,\"p\":1,\"n\":\"Faction\"},{\"t\":3,\"p\":1,\"n\":\"Cell\"},{\"t\":3,\"p\":1,\"n\":\"Class\"},{\"t\":3,\"p\":1,\"n\":\"Race\"},{\"t\":3,\"p\":1,\"n\":\"Actor Base\"},{\"t\":3,\"p\":1,\"n\":\"Global\"},{\"t\":3,\"p\":1,\"n\":\"Weather\"},{\"t\":3,\"p\":1,\"n\":\"Package\"},{\"t\":3,\"p\":1,\"n\":\"Encounter Zone\"},{\"t\":3,\"p\":1,\"n\":\"Perk\"},{\"t\":3,\"p\":1,\"n\":\"Owner\"},{\"t\":3,\"p\":1,\"n\":\"Furniture\"},{\"t\":3,\"p\":1,\"n\":\"Effect Item\"},{\"t\":3,\"p\":1,\"n\":\"Base Effect\"},{\"t\":3,\"p\":1,\"n\":\"Worldspace\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Function\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Param (INVALID)\"},{\"t\":3,\"p\":1,\"n\":\"Referenceable Object\"},{\"t\":3,\"p\":1,\"n\":\"Region\"},{\"t\":3,\"p\":1,\"n\":\"Keyword\"},{\"t\":3,\"p\":1,\"n\":\"Player Action\"},{\"t\":3,\"p\":1,\"n\":\"Casting Type\"},{\"t\":3,\"p\":1,\"n\":\"Shout\"},{\"t\":3,\"p\":1,\"n\":\"Location\"},{\"t\":3,\"p\":1,\"n\":\"Location Ref Type\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"Packdata ID\"},{\"t\":3,\"p\":1,\"n\":\"Association Type\"},{\"t\":3,\"p\":1,\"n\":\"Furniture Anim\"},{\"t\":3,\"p\":1,\"n\":\"Furniture Entry\"},{\"t\":3,\"p\":1,\"n\":\"Scene\"},{\"t\":3,\"p\":1,\"n\":\"Ward State\"},{\"t\":3,\"p\":1,\"n\":\"Event\"},{\"t\":3,\"p\":1,\"n\":\"Event Data\"},{\"t\":3,\"p\":1,\"n\":\"Quest Stage\"},{\"t\":3,\"p\":1,\"n\":\"Weapon\"},{\"t\":3,\"p\":1,\"n\":\"Weapon List\"},{\"t\":3,\"p\":1,\"n\":\"Target\"},{\"t\":3,\"p\":1,\"n\":\"Target List\"},{\"t\":3,\"p\":1,\"n\":\"Target Part\"},{\"t\":3,\"p\":1,\"n\":\"VATS Action\"},{\"t\":3,\"p\":1,\"n\":\"Critical Effect\"},{\"t\":3,\"p\":1,\"n\":\"Critical Effect List\"},{\"t\":3,\"p\":1,\"n\":\"Weapon Type\"},{\"t\":3,\"p\":1,\"n\":\"Projectile Type\"},{\"t\":3,\"p\":1,\"n\":\"Delivery Type\"},{\"t\":3,\"p\":1,\"n\":\"Run On\"},{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":3,\"p\":1,\"n\":\"Parameter #3\"}]},{\"t\":2,\"p\":1,\"n\":\"CIS1 - Parameter #1\"},{\"t\":2,\"p\":1,\"n\":\"CIS2 - Parameter #2\"}]}]}]},{\"t\":1,\"p\":1,\"n\":\"SCOL\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"}]},{\"t\":1,\"p\":1,\"n\":\"SCPT\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"}]},{\"t\":1,\"p\":1,\"n\":\"SCRL - Scroll\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"X1\"},{\"t\":3,\"p\":1,\"n\":\"Y1\"},{\"t\":3,\"p\":1,\"n\":\"Z1\"},{\"t\":3,\"p\":1,\"n\":\"X2\"},{\"t\":3,\"p\":1,\"n\":\"Y2\"},{\"t\":3,\"p\":1,\"n\":\"Z2\"}]},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":3,\"n\":\"KSIZ - Keyword Count\"},{\"t\":7,\"p\":1,\"n\":\"KWDA - Keywords\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Keyword\"}]},{\"t\":3,\"p\":1,\"n\":\"MDOB - Menu Display Object\"},{\"t\":3,\"p\":1,\"n\":\"ETYP - Equipment Type\"},{\"t\":2,\"p\":1,\"n\":\"DESC - Description\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"MODT - Texture Files Hashes\"},{\"t\":7,\"p\":1,\"n\":\"MODS - Alternate Textures\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"3D Name\"},{\"t\":3,\"p\":1,\"n\":\"New Texture\"},{\"t\":3,\"p\":1,\"n\":\"3D Index\"}]}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Destructable\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"DEST - Header\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Health\"},{\"t\":3,\"p\":1,\"n\":\"DEST Count\"},{\"t\":3,\"p\":1,\"n\":\"VATS Targetable\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":8,\"p\":1,\"n\":\"Stages\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Stage\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"DSTD - Destruction Stage Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Health %\"},{\"t\":3,\"p\":1,\"n\":\"Index\"},{\"t\":3,\"p\":1,\"n\":\"Model Damage Stage\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":3,\"p\":1,\"n\":\"Self Damage per Second\"},{\"t\":3,\"p\":1,\"n\":\"Explosion\"},{\"t\":3,\"p\":1,\"n\":\"Debris\"},{\"t\":3,\"p\":1,\"n\":\"Debris Count\"}]},{\"t\":6,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"DMDL - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"DMDT - Texture Files Hashes\"},{\"t\":7,\"p\":1,\"n\":\"DMDS - Alternate Textures\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"3D Name\"},{\"t\":3,\"p\":1,\"n\":\"New Texture\"},{\"t\":3,\"p\":1,\"n\":\"3D Index\"}]}]}]},{\"p\":1,\"n\":\"DSTF - End Marker\"}]}]}]},{\"t\":3,\"p\":1,\"n\":\"YNAM - Sound - Pick Up\"},{\"t\":3,\"p\":1,\"n\":\"ZNAM - Sound - Put Down\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DATA - Item\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Value\"},{\"t\":5,\"p\":1,\"n\":\"Weight\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"SPIT - Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Base Cost\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":5,\"p\":1,\"n\":\"Charge Time\"},{\"t\":3,\"p\":1,\"n\":\"Cast Type\"},{\"t\":3,\"p\":1,\"n\":\"Target Type\"},{\"t\":5,\"p\":1,\"n\":\"Cast Duration\"},{\"t\":5,\"p\":1,\"n\":\"Range\"},{\"t\":3,\"p\":1,\"n\":\"Half-cost Perk\"}]},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Effects\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Effect\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"EFID - Base Effect\"},{\"t\":6,\"p\":1,\"n\":\"EFIT - \",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Magnitude\"},{\"t\":3,\"p\":1,\"n\":\"Area\"},{\"t\":3,\"p\":1,\"n\":\"Duration\"}]},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Conditions\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Condition\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"CTDA - \",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":5,\"p\":1,\"n\":\"Comparison Value - Float\"},{\"t\":3,\"p\":1,\"n\":\"Comparison Value - Global\"},{\"t\":3,\"p\":1,\"n\":\"Function\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":11,\"p\":1,\"n\":\"None\"},{\"t\":3,\"p\":1,\"n\":\"Integer\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":11,\"p\":1,\"n\":\"Variable Name (unused)\"},{\"t\":3,\"p\":1,\"n\":\"Sex\"},{\"t\":3,\"p\":1,\"n\":\"Actor Value\"},{\"t\":3,\"p\":1,\"n\":\"Crime Type\"},{\"t\":3,\"p\":1,\"n\":\"Axis\"},{\"t\":3,\"p\":1,\"n\":\"Quest Stage (unused)\"},{\"t\":3,\"p\":1,\"n\":\"Misc Stat\"},{\"t\":3,\"p\":1,\"n\":\"Alignment\"},{\"t\":3,\"p\":1,\"n\":\"Equip Type\"},{\"t\":3,\"p\":1,\"n\":\"Form Type\"},{\"t\":3,\"p\":1,\"n\":\"Critical Stage\"},{\"t\":3,\"p\":1,\"n\":\"Object Reference\"},{\"t\":3,\"p\":1,\"n\":\"Inventory Object\"},{\"t\":3,\"p\":1,\"n\":\"Actor\"},{\"t\":3,\"p\":1,\"n\":\"Voice Type\"},{\"t\":3,\"p\":1,\"n\":\"Idle\"},{\"t\":3,\"p\":1,\"n\":\"Form List\"},{\"t\":3,\"p\":1,\"n\":\"Quest\"},{\"t\":3,\"p\":1,\"n\":\"Faction\"},{\"t\":3,\"p\":1,\"n\":\"Cell\"},{\"t\":3,\"p\":1,\"n\":\"Class\"},{\"t\":3,\"p\":1,\"n\":\"Race\"},{\"t\":3,\"p\":1,\"n\":\"Actor Base\"},{\"t\":3,\"p\":1,\"n\":\"Global\"},{\"t\":3,\"p\":1,\"n\":\"Weather\"},{\"t\":3,\"p\":1,\"n\":\"Package\"},{\"t\":3,\"p\":1,\"n\":\"Encounter Zone\"},{\"t\":3,\"p\":1,\"n\":\"Perk\"},{\"t\":3,\"p\":1,\"n\":\"Owner\"},{\"t\":3,\"p\":1,\"n\":\"Furniture\"},{\"t\":3,\"p\":1,\"n\":\"Effect Item\"},{\"t\":3,\"p\":1,\"n\":\"Base Effect\"},{\"t\":3,\"p\":1,\"n\":\"Worldspace\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Function\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Param (INVALID)\"},{\"t\":3,\"p\":1,\"n\":\"Referenceable Object\"},{\"t\":3,\"p\":1,\"n\":\"Region\"},{\"t\":3,\"p\":1,\"n\":\"Keyword\"},{\"t\":3,\"p\":1,\"n\":\"Player Action\"},{\"t\":3,\"p\":1,\"n\":\"Casting Type\"},{\"t\":3,\"p\":1,\"n\":\"Shout\"},{\"t\":3,\"p\":1,\"n\":\"Location\"},{\"t\":3,\"p\":1,\"n\":\"Location Ref Type\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"Packdata ID\"},{\"t\":3,\"p\":1,\"n\":\"Association Type\"},{\"t\":3,\"p\":1,\"n\":\"Furniture Anim\"},{\"t\":3,\"p\":1,\"n\":\"Furniture Entry\"},{\"t\":3,\"p\":1,\"n\":\"Scene\"},{\"t\":3,\"p\":1,\"n\":\"Ward State\"},{\"t\":3,\"p\":1,\"n\":\"Event\"},{\"t\":3,\"p\":1,\"n\":\"Event Data\"},{\"t\":3,\"p\":1,\"n\":\"Quest Stage\"},{\"t\":3,\"p\":1,\"n\":\"Weapon\"},{\"t\":3,\"p\":1,\"n\":\"Weapon List\"},{\"t\":3,\"p\":1,\"n\":\"Target\"},{\"t\":3,\"p\":1,\"n\":\"Target List\"},{\"t\":3,\"p\":1,\"n\":\"Target Part\"},{\"t\":3,\"p\":1,\"n\":\"VATS Action\"},{\"t\":3,\"p\":1,\"n\":\"Critical Effect\"},{\"t\":3,\"p\":1,\"n\":\"Critical Effect List\"},{\"t\":3,\"p\":1,\"n\":\"Weapon Type\"},{\"t\":3,\"p\":1,\"n\":\"Projectile Type\"},{\"t\":3,\"p\":1,\"n\":\"Delivery Type\"},{\"t\":3,\"p\":1,\"n\":\"Run On\"},{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":3,\"p\":1,\"n\":\"Parameter #3\"}]},{\"t\":2,\"p\":1,\"n\":\"CIS1 - Parameter #1\"},{\"t\":2,\"p\":1,\"n\":\"CIS2 - Parameter #2\"}]}]}]}]}]},{\"t\":1,\"p\":1,\"n\":\"SHOU - Shout\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":3,\"p\":1,\"n\":\"MDOB - Menu Display Object\"},{\"t\":2,\"p\":1,\"n\":\"DESC - Description\"},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Words of Power\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"SNAM - \",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Word\"},{\"t\":3,\"p\":1,\"n\":\"Spell\"},{\"t\":5,\"p\":1,\"n\":\"Recovery Time\"}]}]}]},{\"t\":1,\"p\":1,\"n\":\"SLGM - Soul Gem\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"X1\"},{\"t\":3,\"p\":1,\"n\":\"Y1\"},{\"t\":3,\"p\":1,\"n\":\"Z1\"},{\"t\":3,\"p\":1,\"n\":\"X2\"},{\"t\":3,\"p\":1,\"n\":\"Y2\"},{\"t\":3,\"p\":1,\"n\":\"Z2\"}]},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"MODT - Texture Files Hashes\"},{\"t\":7,\"p\":1,\"n\":\"MODS - Alternate Textures\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"3D Name\"},{\"t\":3,\"p\":1,\"n\":\"New Texture\"},{\"t\":3,\"p\":1,\"n\":\"3D Index\"}]}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Icon\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"ICON - Large Icon filename\"},{\"t\":2,\"p\":1,\"n\":\"MICO - Small Icon filename\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Destructable\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"DEST - Header\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Health\"},{\"t\":3,\"p\":1,\"n\":\"DEST Count\"},{\"t\":3,\"p\":1,\"n\":\"VATS Targetable\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":8,\"p\":1,\"n\":\"Stages\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Stage\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"DSTD - Destruction Stage Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Health %\"},{\"t\":3,\"p\":1,\"n\":\"Index\"},{\"t\":3,\"p\":1,\"n\":\"Model Damage Stage\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":3,\"p\":1,\"n\":\"Self Damage per Second\"},{\"t\":3,\"p\":1,\"n\":\"Explosion\"},{\"t\":3,\"p\":1,\"n\":\"Debris\"},{\"t\":3,\"p\":1,\"n\":\"Debris Count\"}]},{\"t\":6,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"DMDL - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"DMDT - Texture Files Hashes\"},{\"t\":7,\"p\":1,\"n\":\"DMDS - Alternate Textures\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"3D Name\"},{\"t\":3,\"p\":1,\"n\":\"New Texture\"},{\"t\":3,\"p\":1,\"n\":\"3D Index\"}]}]}]},{\"p\":1,\"n\":\"DSTF - End Marker\"}]}]}]},{\"t\":3,\"p\":1,\"n\":\"YNAM - Sound - Pick Up\"},{\"t\":3,\"p\":1,\"n\":\"ZNAM - Sound - Put Down\"},{\"t\":3,\"n\":\"KSIZ - Keyword Count\"},{\"t\":7,\"p\":1,\"n\":\"KWDA - Keywords\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Keyword\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DATA - \",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Value\"},{\"t\":5,\"p\":1,\"n\":\"Weight\"}]},{\"t\":3,\"p\":1,\"n\":\"SOUL - Contained Soul\"},{\"t\":3,\"p\":1,\"n\":\"SLCP - Maximum Capacity\"},{\"t\":3,\"p\":1,\"n\":\"NAM0 - Linked To\"}]},{\"t\":1,\"p\":1,\"n\":\"SMBN - Story Manager Branch Node\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":3,\"p\":1,\"n\":\"PNAM - Parent \"},{\"t\":3,\"p\":1,\"n\":\"SNAM - Child \"},{\"t\":3,\"n\":\"CITC - Condition Count\"},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Conditions\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Condition\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"CTDA - \",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":5,\"p\":1,\"n\":\"Comparison Value - Float\"},{\"t\":3,\"p\":1,\"n\":\"Comparison Value - Global\"},{\"t\":3,\"p\":1,\"n\":\"Function\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":11,\"p\":1,\"n\":\"None\"},{\"t\":3,\"p\":1,\"n\":\"Integer\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":11,\"p\":1,\"n\":\"Variable Name (unused)\"},{\"t\":3,\"p\":1,\"n\":\"Sex\"},{\"t\":3,\"p\":1,\"n\":\"Actor Value\"},{\"t\":3,\"p\":1,\"n\":\"Crime Type\"},{\"t\":3,\"p\":1,\"n\":\"Axis\"},{\"t\":3,\"p\":1,\"n\":\"Quest Stage (unused)\"},{\"t\":3,\"p\":1,\"n\":\"Misc Stat\"},{\"t\":3,\"p\":1,\"n\":\"Alignment\"},{\"t\":3,\"p\":1,\"n\":\"Equip Type\"},{\"t\":3,\"p\":1,\"n\":\"Form Type\"},{\"t\":3,\"p\":1,\"n\":\"Critical Stage\"},{\"t\":3,\"p\":1,\"n\":\"Object Reference\"},{\"t\":3,\"p\":1,\"n\":\"Inventory Object\"},{\"t\":3,\"p\":1,\"n\":\"Actor\"},{\"t\":3,\"p\":1,\"n\":\"Voice Type\"},{\"t\":3,\"p\":1,\"n\":\"Idle\"},{\"t\":3,\"p\":1,\"n\":\"Form List\"},{\"t\":3,\"p\":1,\"n\":\"Quest\"},{\"t\":3,\"p\":1,\"n\":\"Faction\"},{\"t\":3,\"p\":1,\"n\":\"Cell\"},{\"t\":3,\"p\":1,\"n\":\"Class\"},{\"t\":3,\"p\":1,\"n\":\"Race\"},{\"t\":3,\"p\":1,\"n\":\"Actor Base\"},{\"t\":3,\"p\":1,\"n\":\"Global\"},{\"t\":3,\"p\":1,\"n\":\"Weather\"},{\"t\":3,\"p\":1,\"n\":\"Package\"},{\"t\":3,\"p\":1,\"n\":\"Encounter Zone\"},{\"t\":3,\"p\":1,\"n\":\"Perk\"},{\"t\":3,\"p\":1,\"n\":\"Owner\"},{\"t\":3,\"p\":1,\"n\":\"Furniture\"},{\"t\":3,\"p\":1,\"n\":\"Effect Item\"},{\"t\":3,\"p\":1,\"n\":\"Base Effect\"},{\"t\":3,\"p\":1,\"n\":\"Worldspace\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Function\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Param (INVALID)\"},{\"t\":3,\"p\":1,\"n\":\"Referenceable Object\"},{\"t\":3,\"p\":1,\"n\":\"Region\"},{\"t\":3,\"p\":1,\"n\":\"Keyword\"},{\"t\":3,\"p\":1,\"n\":\"Player Action\"},{\"t\":3,\"p\":1,\"n\":\"Casting Type\"},{\"t\":3,\"p\":1,\"n\":\"Shout\"},{\"t\":3,\"p\":1,\"n\":\"Location\"},{\"t\":3,\"p\":1,\"n\":\"Location Ref Type\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"Packdata ID\"},{\"t\":3,\"p\":1,\"n\":\"Association Type\"},{\"t\":3,\"p\":1,\"n\":\"Furniture Anim\"},{\"t\":3,\"p\":1,\"n\":\"Furniture Entry\"},{\"t\":3,\"p\":1,\"n\":\"Scene\"},{\"t\":3,\"p\":1,\"n\":\"Ward State\"},{\"t\":3,\"p\":1,\"n\":\"Event\"},{\"t\":3,\"p\":1,\"n\":\"Event Data\"},{\"t\":3,\"p\":1,\"n\":\"Quest Stage\"},{\"t\":3,\"p\":1,\"n\":\"Weapon\"},{\"t\":3,\"p\":1,\"n\":\"Weapon List\"},{\"t\":3,\"p\":1,\"n\":\"Target\"},{\"t\":3,\"p\":1,\"n\":\"Target List\"},{\"t\":3,\"p\":1,\"n\":\"Target Part\"},{\"t\":3,\"p\":1,\"n\":\"VATS Action\"},{\"t\":3,\"p\":1,\"n\":\"Critical Effect\"},{\"t\":3,\"p\":1,\"n\":\"Critical Effect List\"},{\"t\":3,\"p\":1,\"n\":\"Weapon Type\"},{\"t\":3,\"p\":1,\"n\":\"Projectile Type\"},{\"t\":3,\"p\":1,\"n\":\"Delivery Type\"},{\"t\":3,\"p\":1,\"n\":\"Run On\"},{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":3,\"p\":1,\"n\":\"Parameter #3\"}]},{\"t\":2,\"p\":1,\"n\":\"CIS1 - Parameter #1\"},{\"t\":2,\"p\":1,\"n\":\"CIS2 - Parameter #2\"}]}]},{\"t\":3,\"p\":1,\"n\":\"DNAM - Flags\"},{\"t\":11,\"n\":\"XNAM - Unknown\"}]},{\"t\":1,\"p\":1,\"n\":\"SMEN - Story Manager Event Node\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":3,\"p\":1,\"n\":\"PNAM - Parent \"},{\"t\":3,\"p\":1,\"n\":\"SNAM - Child \"},{\"t\":3,\"n\":\"CITC - Condition Count\"},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Conditions\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Condition\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"CTDA - \",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":5,\"p\":1,\"n\":\"Comparison Value - Float\"},{\"t\":3,\"p\":1,\"n\":\"Comparison Value - Global\"},{\"t\":3,\"p\":1,\"n\":\"Function\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":11,\"p\":1,\"n\":\"None\"},{\"t\":3,\"p\":1,\"n\":\"Integer\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":11,\"p\":1,\"n\":\"Variable Name (unused)\"},{\"t\":3,\"p\":1,\"n\":\"Sex\"},{\"t\":3,\"p\":1,\"n\":\"Actor Value\"},{\"t\":3,\"p\":1,\"n\":\"Crime Type\"},{\"t\":3,\"p\":1,\"n\":\"Axis\"},{\"t\":3,\"p\":1,\"n\":\"Quest Stage (unused)\"},{\"t\":3,\"p\":1,\"n\":\"Misc Stat\"},{\"t\":3,\"p\":1,\"n\":\"Alignment\"},{\"t\":3,\"p\":1,\"n\":\"Equip Type\"},{\"t\":3,\"p\":1,\"n\":\"Form Type\"},{\"t\":3,\"p\":1,\"n\":\"Critical Stage\"},{\"t\":3,\"p\":1,\"n\":\"Object Reference\"},{\"t\":3,\"p\":1,\"n\":\"Inventory Object\"},{\"t\":3,\"p\":1,\"n\":\"Actor\"},{\"t\":3,\"p\":1,\"n\":\"Voice Type\"},{\"t\":3,\"p\":1,\"n\":\"Idle\"},{\"t\":3,\"p\":1,\"n\":\"Form List\"},{\"t\":3,\"p\":1,\"n\":\"Quest\"},{\"t\":3,\"p\":1,\"n\":\"Faction\"},{\"t\":3,\"p\":1,\"n\":\"Cell\"},{\"t\":3,\"p\":1,\"n\":\"Class\"},{\"t\":3,\"p\":1,\"n\":\"Race\"},{\"t\":3,\"p\":1,\"n\":\"Actor Base\"},{\"t\":3,\"p\":1,\"n\":\"Global\"},{\"t\":3,\"p\":1,\"n\":\"Weather\"},{\"t\":3,\"p\":1,\"n\":\"Package\"},{\"t\":3,\"p\":1,\"n\":\"Encounter Zone\"},{\"t\":3,\"p\":1,\"n\":\"Perk\"},{\"t\":3,\"p\":1,\"n\":\"Owner\"},{\"t\":3,\"p\":1,\"n\":\"Furniture\"},{\"t\":3,\"p\":1,\"n\":\"Effect Item\"},{\"t\":3,\"p\":1,\"n\":\"Base Effect\"},{\"t\":3,\"p\":1,\"n\":\"Worldspace\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Function\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Param (INVALID)\"},{\"t\":3,\"p\":1,\"n\":\"Referenceable Object\"},{\"t\":3,\"p\":1,\"n\":\"Region\"},{\"t\":3,\"p\":1,\"n\":\"Keyword\"},{\"t\":3,\"p\":1,\"n\":\"Player Action\"},{\"t\":3,\"p\":1,\"n\":\"Casting Type\"},{\"t\":3,\"p\":1,\"n\":\"Shout\"},{\"t\":3,\"p\":1,\"n\":\"Location\"},{\"t\":3,\"p\":1,\"n\":\"Location Ref Type\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"Packdata ID\"},{\"t\":3,\"p\":1,\"n\":\"Association Type\"},{\"t\":3,\"p\":1,\"n\":\"Furniture Anim\"},{\"t\":3,\"p\":1,\"n\":\"Furniture Entry\"},{\"t\":3,\"p\":1,\"n\":\"Scene\"},{\"t\":3,\"p\":1,\"n\":\"Ward State\"},{\"t\":3,\"p\":1,\"n\":\"Event\"},{\"t\":3,\"p\":1,\"n\":\"Event Data\"},{\"t\":3,\"p\":1,\"n\":\"Quest Stage\"},{\"t\":3,\"p\":1,\"n\":\"Weapon\"},{\"t\":3,\"p\":1,\"n\":\"Weapon List\"},{\"t\":3,\"p\":1,\"n\":\"Target\"},{\"t\":3,\"p\":1,\"n\":\"Target List\"},{\"t\":3,\"p\":1,\"n\":\"Target Part\"},{\"t\":3,\"p\":1,\"n\":\"VATS Action\"},{\"t\":3,\"p\":1,\"n\":\"Critical Effect\"},{\"t\":3,\"p\":1,\"n\":\"Critical Effect List\"},{\"t\":3,\"p\":1,\"n\":\"Weapon Type\"},{\"t\":3,\"p\":1,\"n\":\"Projectile Type\"},{\"t\":3,\"p\":1,\"n\":\"Delivery Type\"},{\"t\":3,\"p\":1,\"n\":\"Run On\"},{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":3,\"p\":1,\"n\":\"Parameter #3\"}]},{\"t\":2,\"p\":1,\"n\":\"CIS1 - Parameter #1\"},{\"t\":2,\"p\":1,\"n\":\"CIS2 - Parameter #2\"}]}]},{\"t\":3,\"p\":1,\"n\":\"DNAM - Flags\"},{\"t\":11,\"n\":\"XNAM - Unknown\"},{\"t\":2,\"p\":1,\"n\":\"ENAM - Type\"}]},{\"t\":1,\"p\":1,\"n\":\"SMQN - Story Manager Quest Node\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":3,\"p\":1,\"n\":\"PNAM - Parent \"},{\"t\":3,\"p\":1,\"n\":\"SNAM - Child \"},{\"t\":3,\"n\":\"CITC - Condition Count\"},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Conditions\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Condition\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"CTDA - \",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":5,\"p\":1,\"n\":\"Comparison Value - Float\"},{\"t\":3,\"p\":1,\"n\":\"Comparison Value - Global\"},{\"t\":3,\"p\":1,\"n\":\"Function\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":11,\"p\":1,\"n\":\"None\"},{\"t\":3,\"p\":1,\"n\":\"Integer\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":11,\"p\":1,\"n\":\"Variable Name (unused)\"},{\"t\":3,\"p\":1,\"n\":\"Sex\"},{\"t\":3,\"p\":1,\"n\":\"Actor Value\"},{\"t\":3,\"p\":1,\"n\":\"Crime Type\"},{\"t\":3,\"p\":1,\"n\":\"Axis\"},{\"t\":3,\"p\":1,\"n\":\"Quest Stage (unused)\"},{\"t\":3,\"p\":1,\"n\":\"Misc Stat\"},{\"t\":3,\"p\":1,\"n\":\"Alignment\"},{\"t\":3,\"p\":1,\"n\":\"Equip Type\"},{\"t\":3,\"p\":1,\"n\":\"Form Type\"},{\"t\":3,\"p\":1,\"n\":\"Critical Stage\"},{\"t\":3,\"p\":1,\"n\":\"Object Reference\"},{\"t\":3,\"p\":1,\"n\":\"Inventory Object\"},{\"t\":3,\"p\":1,\"n\":\"Actor\"},{\"t\":3,\"p\":1,\"n\":\"Voice Type\"},{\"t\":3,\"p\":1,\"n\":\"Idle\"},{\"t\":3,\"p\":1,\"n\":\"Form List\"},{\"t\":3,\"p\":1,\"n\":\"Quest\"},{\"t\":3,\"p\":1,\"n\":\"Faction\"},{\"t\":3,\"p\":1,\"n\":\"Cell\"},{\"t\":3,\"p\":1,\"n\":\"Class\"},{\"t\":3,\"p\":1,\"n\":\"Race\"},{\"t\":3,\"p\":1,\"n\":\"Actor Base\"},{\"t\":3,\"p\":1,\"n\":\"Global\"},{\"t\":3,\"p\":1,\"n\":\"Weather\"},{\"t\":3,\"p\":1,\"n\":\"Package\"},{\"t\":3,\"p\":1,\"n\":\"Encounter Zone\"},{\"t\":3,\"p\":1,\"n\":\"Perk\"},{\"t\":3,\"p\":1,\"n\":\"Owner\"},{\"t\":3,\"p\":1,\"n\":\"Furniture\"},{\"t\":3,\"p\":1,\"n\":\"Effect Item\"},{\"t\":3,\"p\":1,\"n\":\"Base Effect\"},{\"t\":3,\"p\":1,\"n\":\"Worldspace\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Function\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Param (INVALID)\"},{\"t\":3,\"p\":1,\"n\":\"Referenceable Object\"},{\"t\":3,\"p\":1,\"n\":\"Region\"},{\"t\":3,\"p\":1,\"n\":\"Keyword\"},{\"t\":3,\"p\":1,\"n\":\"Player Action\"},{\"t\":3,\"p\":1,\"n\":\"Casting Type\"},{\"t\":3,\"p\":1,\"n\":\"Shout\"},{\"t\":3,\"p\":1,\"n\":\"Location\"},{\"t\":3,\"p\":1,\"n\":\"Location Ref Type\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"Packdata ID\"},{\"t\":3,\"p\":1,\"n\":\"Association Type\"},{\"t\":3,\"p\":1,\"n\":\"Furniture Anim\"},{\"t\":3,\"p\":1,\"n\":\"Furniture Entry\"},{\"t\":3,\"p\":1,\"n\":\"Scene\"},{\"t\":3,\"p\":1,\"n\":\"Ward State\"},{\"t\":3,\"p\":1,\"n\":\"Event\"},{\"t\":3,\"p\":1,\"n\":\"Event Data\"},{\"t\":3,\"p\":1,\"n\":\"Quest Stage\"},{\"t\":3,\"p\":1,\"n\":\"Weapon\"},{\"t\":3,\"p\":1,\"n\":\"Weapon List\"},{\"t\":3,\"p\":1,\"n\":\"Target\"},{\"t\":3,\"p\":1,\"n\":\"Target List\"},{\"t\":3,\"p\":1,\"n\":\"Target Part\"},{\"t\":3,\"p\":1,\"n\":\"VATS Action\"},{\"t\":3,\"p\":1,\"n\":\"Critical Effect\"},{\"t\":3,\"p\":1,\"n\":\"Critical Effect List\"},{\"t\":3,\"p\":1,\"n\":\"Weapon Type\"},{\"t\":3,\"p\":1,\"n\":\"Projectile Type\"},{\"t\":3,\"p\":1,\"n\":\"Delivery Type\"},{\"t\":3,\"p\":1,\"n\":\"Run On\"},{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":3,\"p\":1,\"n\":\"Parameter #3\"}]},{\"t\":2,\"p\":1,\"n\":\"CIS1 - Parameter #1\"},{\"t\":2,\"p\":1,\"n\":\"CIS2 - Parameter #2\"}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DNAM - Flags\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Node Flags\"},{\"t\":3,\"p\":1,\"n\":\"Quest Flags\"}]},{\"t\":3,\"p\":1,\"n\":\"XNAM - Max concurrent quests\"},{\"t\":3,\"p\":1,\"n\":\"MNAM - Num quests to run\"},{\"t\":3,\"n\":\"QNAM - Quest Count\"},{\"t\":10,\"p\":1,\"n\":\"Quests\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Quest\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"NNAM - Quest\"},{\"t\":11,\"n\":\"FNAM - Unknown\"},{\"t\":5,\"p\":1,\"n\":\"RNAM - Hours until reset\"}]}]}]},{\"t\":1,\"p\":1,\"n\":\"SNCT - Sound Category\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":3,\"p\":1,\"n\":\"FNAM - Flags\"},{\"t\":3,\"p\":1,\"n\":\"PNAM - Parent\"},{\"t\":3,\"p\":1,\"n\":\"VNAM - Static Volume Multiplier\"},{\"t\":3,\"p\":1,\"n\":\"UNAM - Default Menu Value\"}]},{\"t\":1,\"p\":1,\"n\":\"SNDR - Sound Descriptor\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":11,\"n\":\"CNAM - Unknown\"},{\"t\":3,\"p\":1,\"n\":\"GNAM - Category\"},{\"t\":3,\"p\":1,\"n\":\"SNAM - Alternate Sound For\"},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Sounds\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Sound Files\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"ANAM - File Name\"}]}]},{\"t\":3,\"p\":1,\"n\":\"ONAM - Output Model\"},{\"t\":2,\"p\":1,\"n\":\"FNAM - String\"},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Conditions\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Condition\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"CTDA - \",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":5,\"p\":1,\"n\":\"Comparison Value - Float\"},{\"t\":3,\"p\":1,\"n\":\"Comparison Value - Global\"},{\"t\":3,\"p\":1,\"n\":\"Function\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":11,\"p\":1,\"n\":\"None\"},{\"t\":3,\"p\":1,\"n\":\"Integer\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":11,\"p\":1,\"n\":\"Variable Name (unused)\"},{\"t\":3,\"p\":1,\"n\":\"Sex\"},{\"t\":3,\"p\":1,\"n\":\"Actor Value\"},{\"t\":3,\"p\":1,\"n\":\"Crime Type\"},{\"t\":3,\"p\":1,\"n\":\"Axis\"},{\"t\":3,\"p\":1,\"n\":\"Quest Stage (unused)\"},{\"t\":3,\"p\":1,\"n\":\"Misc Stat\"},{\"t\":3,\"p\":1,\"n\":\"Alignment\"},{\"t\":3,\"p\":1,\"n\":\"Equip Type\"},{\"t\":3,\"p\":1,\"n\":\"Form Type\"},{\"t\":3,\"p\":1,\"n\":\"Critical Stage\"},{\"t\":3,\"p\":1,\"n\":\"Object Reference\"},{\"t\":3,\"p\":1,\"n\":\"Inventory Object\"},{\"t\":3,\"p\":1,\"n\":\"Actor\"},{\"t\":3,\"p\":1,\"n\":\"Voice Type\"},{\"t\":3,\"p\":1,\"n\":\"Idle\"},{\"t\":3,\"p\":1,\"n\":\"Form List\"},{\"t\":3,\"p\":1,\"n\":\"Quest\"},{\"t\":3,\"p\":1,\"n\":\"Faction\"},{\"t\":3,\"p\":1,\"n\":\"Cell\"},{\"t\":3,\"p\":1,\"n\":\"Class\"},{\"t\":3,\"p\":1,\"n\":\"Race\"},{\"t\":3,\"p\":1,\"n\":\"Actor Base\"},{\"t\":3,\"p\":1,\"n\":\"Global\"},{\"t\":3,\"p\":1,\"n\":\"Weather\"},{\"t\":3,\"p\":1,\"n\":\"Package\"},{\"t\":3,\"p\":1,\"n\":\"Encounter Zone\"},{\"t\":3,\"p\":1,\"n\":\"Perk\"},{\"t\":3,\"p\":1,\"n\":\"Owner\"},{\"t\":3,\"p\":1,\"n\":\"Furniture\"},{\"t\":3,\"p\":1,\"n\":\"Effect Item\"},{\"t\":3,\"p\":1,\"n\":\"Base Effect\"},{\"t\":3,\"p\":1,\"n\":\"Worldspace\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Function\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Param (INVALID)\"},{\"t\":3,\"p\":1,\"n\":\"Referenceable Object\"},{\"t\":3,\"p\":1,\"n\":\"Region\"},{\"t\":3,\"p\":1,\"n\":\"Keyword\"},{\"t\":3,\"p\":1,\"n\":\"Player Action\"},{\"t\":3,\"p\":1,\"n\":\"Casting Type\"},{\"t\":3,\"p\":1,\"n\":\"Shout\"},{\"t\":3,\"p\":1,\"n\":\"Location\"},{\"t\":3,\"p\":1,\"n\":\"Location Ref Type\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"Packdata ID\"},{\"t\":3,\"p\":1,\"n\":\"Association Type\"},{\"t\":3,\"p\":1,\"n\":\"Furniture Anim\"},{\"t\":3,\"p\":1,\"n\":\"Furniture Entry\"},{\"t\":3,\"p\":1,\"n\":\"Scene\"},{\"t\":3,\"p\":1,\"n\":\"Ward State\"},{\"t\":3,\"p\":1,\"n\":\"Event\"},{\"t\":3,\"p\":1,\"n\":\"Event Data\"},{\"t\":3,\"p\":1,\"n\":\"Quest Stage\"},{\"t\":3,\"p\":1,\"n\":\"Weapon\"},{\"t\":3,\"p\":1,\"n\":\"Weapon List\"},{\"t\":3,\"p\":1,\"n\":\"Target\"},{\"t\":3,\"p\":1,\"n\":\"Target List\"},{\"t\":3,\"p\":1,\"n\":\"Target Part\"},{\"t\":3,\"p\":1,\"n\":\"VATS Action\"},{\"t\":3,\"p\":1,\"n\":\"Critical Effect\"},{\"t\":3,\"p\":1,\"n\":\"Critical Effect List\"},{\"t\":3,\"p\":1,\"n\":\"Weapon Type\"},{\"t\":3,\"p\":1,\"n\":\"Projectile Type\"},{\"t\":3,\"p\":1,\"n\":\"Delivery Type\"},{\"t\":3,\"p\":1,\"n\":\"Run On\"},{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":3,\"p\":1,\"n\":\"Parameter #3\"}]},{\"t\":2,\"p\":1,\"n\":\"CIS1 - Parameter #1\"},{\"t\":2,\"p\":1,\"n\":\"CIS2 - Parameter #2\"}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"LNAM - Values\",\"c\":[{\"t\":11,\"n\":\"Unknown\"},{\"t\":3,\"p\":1,\"n\":\"Looping\"},{\"t\":3,\"p\":1,\"n\":\"Rumble Send Value = (Small \\/ 7) + ((Big \\/ 7) * 16)\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"BNAM - Values\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"% Frequency Shift\"},{\"t\":3,\"p\":1,\"n\":\"% Frequency Variance\"},{\"t\":3,\"p\":1,\"n\":\"Priority\"},{\"t\":3,\"p\":1,\"n\":\"db Variance\"},{\"t\":3,\"p\":1,\"n\":\"Static Attenuation (db)\"}]}]},{\"t\":1,\"p\":1,\"n\":\"SOPM - Sound Output Model\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"NAM1 - Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":3,\"p\":1,\"n\":\"Reverb Send %\"}]},{\"t\":11,\"n\":\"FNAM - Unknown\"},{\"t\":3,\"p\":1,\"n\":\"MNAM - Type\"},{\"t\":11,\"n\":\"CNAM - Unknown\"},{\"t\":11,\"n\":\"SNAM - Unknown\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"ONAM - Output Values\",\"c\":[{\"t\":7,\"p\":1,\"n\":\"Channels\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"L\"},{\"t\":3,\"p\":1,\"n\":\"R\"},{\"t\":3,\"p\":1,\"n\":\"C\"},{\"t\":3,\"p\":1,\"n\":\"LFE\"},{\"t\":3,\"p\":1,\"n\":\"RL\"},{\"t\":3,\"p\":1,\"n\":\"RR\"},{\"t\":3,\"p\":1,\"n\":\"BL\"},{\"t\":3,\"p\":1,\"n\":\"BR\"}]}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"ANAM - Attenuation Values\",\"c\":[{\"t\":11,\"n\":\"Unknown\"},{\"t\":5,\"p\":1,\"n\":\"Min Distance\"},{\"t\":5,\"p\":1,\"n\":\"Max Distance\"},{\"t\":7,\"p\":1,\"n\":\"Curve\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Value\"}]}]}]},{\"t\":1,\"p\":1,\"n\":\"SOUN - Sound Marker\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"X1\"},{\"t\":3,\"p\":1,\"n\":\"Y1\"},{\"t\":3,\"p\":1,\"n\":\"Z1\"},{\"t\":3,\"p\":1,\"n\":\"X2\"},{\"t\":3,\"p\":1,\"n\":\"Y2\"},{\"t\":3,\"p\":1,\"n\":\"Z2\"}]},{\"t\":11,\"n\":\"FNAM - Unknown\"},{\"t\":11,\"n\":\"SNDD - Unknown\"},{\"t\":3,\"p\":1,\"n\":\"SDSC - Sound Descriptor\"}]},{\"t\":1,\"p\":1,\"n\":\"SPEL - Spell\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"X1\"},{\"t\":3,\"p\":1,\"n\":\"Y1\"},{\"t\":3,\"p\":1,\"n\":\"Z1\"},{\"t\":3,\"p\":1,\"n\":\"X2\"},{\"t\":3,\"p\":1,\"n\":\"Y2\"},{\"t\":3,\"p\":1,\"n\":\"Z2\"}]},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":3,\"n\":\"KSIZ - Keyword Count\"},{\"t\":7,\"p\":1,\"n\":\"KWDA - Keywords\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Keyword\"}]},{\"t\":3,\"p\":1,\"n\":\"MDOB - Menu Display Object\"},{\"t\":3,\"p\":1,\"n\":\"ETYP - Equipment Type\"},{\"t\":2,\"p\":1,\"n\":\"DESC - Description\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"SPIT - Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Base Cost\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":5,\"p\":1,\"n\":\"Charge Time\"},{\"t\":3,\"p\":1,\"n\":\"Cast Type\"},{\"t\":3,\"p\":1,\"n\":\"Target Type\"},{\"t\":5,\"p\":1,\"n\":\"Cast Duration\"},{\"t\":5,\"p\":1,\"n\":\"Range\"},{\"t\":3,\"p\":1,\"n\":\"Half-cost Perk\"}]},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Effects\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"Effect\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"EFID - Base Effect\"},{\"t\":6,\"p\":1,\"n\":\"EFIT - \",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Magnitude\"},{\"t\":3,\"p\":1,\"n\":\"Area\"},{\"t\":3,\"p\":1,\"n\":\"Duration\"}]},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Conditions\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Condition\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"CTDA - \",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":5,\"p\":1,\"n\":\"Comparison Value - Float\"},{\"t\":3,\"p\":1,\"n\":\"Comparison Value - Global\"},{\"t\":3,\"p\":1,\"n\":\"Function\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":11,\"p\":1,\"n\":\"None\"},{\"t\":3,\"p\":1,\"n\":\"Integer\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":11,\"p\":1,\"n\":\"Variable Name (unused)\"},{\"t\":3,\"p\":1,\"n\":\"Sex\"},{\"t\":3,\"p\":1,\"n\":\"Actor Value\"},{\"t\":3,\"p\":1,\"n\":\"Crime Type\"},{\"t\":3,\"p\":1,\"n\":\"Axis\"},{\"t\":3,\"p\":1,\"n\":\"Quest Stage (unused)\"},{\"t\":3,\"p\":1,\"n\":\"Misc Stat\"},{\"t\":3,\"p\":1,\"n\":\"Alignment\"},{\"t\":3,\"p\":1,\"n\":\"Equip Type\"},{\"t\":3,\"p\":1,\"n\":\"Form Type\"},{\"t\":3,\"p\":1,\"n\":\"Critical Stage\"},{\"t\":3,\"p\":1,\"n\":\"Object Reference\"},{\"t\":3,\"p\":1,\"n\":\"Inventory Object\"},{\"t\":3,\"p\":1,\"n\":\"Actor\"},{\"t\":3,\"p\":1,\"n\":\"Voice Type\"},{\"t\":3,\"p\":1,\"n\":\"Idle\"},{\"t\":3,\"p\":1,\"n\":\"Form List\"},{\"t\":3,\"p\":1,\"n\":\"Quest\"},{\"t\":3,\"p\":1,\"n\":\"Faction\"},{\"t\":3,\"p\":1,\"n\":\"Cell\"},{\"t\":3,\"p\":1,\"n\":\"Class\"},{\"t\":3,\"p\":1,\"n\":\"Race\"},{\"t\":3,\"p\":1,\"n\":\"Actor Base\"},{\"t\":3,\"p\":1,\"n\":\"Global\"},{\"t\":3,\"p\":1,\"n\":\"Weather\"},{\"t\":3,\"p\":1,\"n\":\"Package\"},{\"t\":3,\"p\":1,\"n\":\"Encounter Zone\"},{\"t\":3,\"p\":1,\"n\":\"Perk\"},{\"t\":3,\"p\":1,\"n\":\"Owner\"},{\"t\":3,\"p\":1,\"n\":\"Furniture\"},{\"t\":3,\"p\":1,\"n\":\"Effect Item\"},{\"t\":3,\"p\":1,\"n\":\"Base Effect\"},{\"t\":3,\"p\":1,\"n\":\"Worldspace\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Function\"},{\"t\":3,\"p\":1,\"n\":\"VATS Value Param (INVALID)\"},{\"t\":3,\"p\":1,\"n\":\"Referenceable Object\"},{\"t\":3,\"p\":1,\"n\":\"Region\"},{\"t\":3,\"p\":1,\"n\":\"Keyword\"},{\"t\":3,\"p\":1,\"n\":\"Player Action\"},{\"t\":3,\"p\":1,\"n\":\"Casting Type\"},{\"t\":3,\"p\":1,\"n\":\"Shout\"},{\"t\":3,\"p\":1,\"n\":\"Location\"},{\"t\":3,\"p\":1,\"n\":\"Location Ref Type\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"Packdata ID\"},{\"t\":3,\"p\":1,\"n\":\"Association Type\"},{\"t\":3,\"p\":1,\"n\":\"Furniture Anim\"},{\"t\":3,\"p\":1,\"n\":\"Furniture Entry\"},{\"t\":3,\"p\":1,\"n\":\"Scene\"},{\"t\":3,\"p\":1,\"n\":\"Ward State\"},{\"t\":3,\"p\":1,\"n\":\"Event\"},{\"t\":3,\"p\":1,\"n\":\"Event Data\"},{\"t\":3,\"p\":1,\"n\":\"Quest Stage\"},{\"t\":3,\"p\":1,\"n\":\"Weapon\"},{\"t\":3,\"p\":1,\"n\":\"Weapon List\"},{\"t\":3,\"p\":1,\"n\":\"Target\"},{\"t\":3,\"p\":1,\"n\":\"Target List\"},{\"t\":3,\"p\":1,\"n\":\"Target Part\"},{\"t\":3,\"p\":1,\"n\":\"VATS Action\"},{\"t\":3,\"p\":1,\"n\":\"Critical Effect\"},{\"t\":3,\"p\":1,\"n\":\"Critical Effect List\"},{\"t\":3,\"p\":1,\"n\":\"Weapon Type\"},{\"t\":3,\"p\":1,\"n\":\"Projectile Type\"},{\"t\":3,\"p\":1,\"n\":\"Delivery Type\"},{\"t\":3,\"p\":1,\"n\":\"Run On\"},{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":3,\"p\":1,\"n\":\"Parameter #3\"}]},{\"t\":2,\"p\":1,\"n\":\"CIS1 - Parameter #1\"},{\"t\":2,\"p\":1,\"n\":\"CIS2 - Parameter #2\"}]}]}]}]}]},{\"t\":1,\"p\":1,\"n\":\"SPGD - Shader Particle Geometry\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Data\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Gravity Velocity\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":5,\"p\":1,\"n\":\"Rotation Velocity\"},{\"t\":5,\"p\":1,\"n\":\"Particle Size X\"},{\"t\":5,\"p\":1,\"n\":\"Center Offset Min\"},{\"t\":5,\"p\":1,\"n\":\"Particle Size Y\"},{\"t\":5,\"p\":1,\"n\":\"Center Offset Max\"},{\"t\":5,\"p\":1,\"n\":\"Initial Rotation\"},{\"t\":3,\"p\":1,\"n\":\"# of Subtextures X\"},{\"t\":3,\"p\":1,\"n\":\"# of Subtextures Y\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Box Size\"},{\"t\":5,\"p\":1,\"n\":\"Particle Density\"}]},{\"t\":2,\"p\":1,\"n\":\"ICON - Particle Texture\"}]},{\"t\":1,\"p\":1,\"n\":\"STAT - Static\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"X1\"},{\"t\":3,\"p\":1,\"n\":\"Y1\"},{\"t\":3,\"p\":1,\"n\":\"Z1\"},{\"t\":3,\"p\":1,\"n\":\"X2\"},{\"t\":3,\"p\":1,\"n\":\"Y2\"},{\"t\":3,\"p\":1,\"n\":\"Z2\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"MODT - Texture Files Hashes\"},{\"t\":7,\"p\":1,\"n\":\"MODS - Alternate Textures\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"3D Name\"},{\"t\":3,\"p\":1,\"n\":\"New Texture\"},{\"t\":3,\"p\":1,\"n\":\"3D Index\"}]}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DNAM - Direction Material\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Max Angle (30-120)\"},{\"t\":3,\"p\":1,\"n\":\"Material\"}]},{\"t\":7,\"p\":1,\"n\":\"MNAM - Distant LOD\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"LOD\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"Mesh\"}]}]}]},{\"t\":1,\"p\":1,\"n\":\"TACT - Talking Activator\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"VMAD - Virtual Machine Adapter\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Version\"},{\"t\":3,\"p\":1,\"n\":\"Object Format\"},{\"t\":7,\"p\":1,\"n\":\"Scripts\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Script\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"scriptName\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":7,\"p\":1,\"n\":\"Properties\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Property\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"propertyName\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]},{\"t\":2,\"p\":1,\"n\":\"String\"},{\"t\":3,\"p\":1,\"n\":\"Int32\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":3,\"p\":1,\"n\":\"Bool\"},{\"t\":7,\"p\":1,\"n\":\"Array of Object\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]}]},{\"t\":7,\"p\":1,\"n\":\"Array of String\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Int32\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Float\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Bool\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]}]}]}]}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"X1\"},{\"t\":3,\"p\":1,\"n\":\"Y1\"},{\"t\":3,\"p\":1,\"n\":\"Z1\"},{\"t\":3,\"p\":1,\"n\":\"X2\"},{\"t\":3,\"p\":1,\"n\":\"Y2\"},{\"t\":3,\"p\":1,\"n\":\"Z2\"}]},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"MODT - Texture Files Hashes\"},{\"t\":7,\"p\":1,\"n\":\"MODS - Alternate Textures\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"3D Name\"},{\"t\":3,\"p\":1,\"n\":\"New Texture\"},{\"t\":3,\"p\":1,\"n\":\"3D Index\"}]}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Destructable\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"DEST - Header\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Health\"},{\"t\":3,\"p\":1,\"n\":\"DEST Count\"},{\"t\":3,\"p\":1,\"n\":\"VATS Targetable\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":8,\"p\":1,\"n\":\"Stages\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Stage\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"DSTD - Destruction Stage Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Health %\"},{\"t\":3,\"p\":1,\"n\":\"Index\"},{\"t\":3,\"p\":1,\"n\":\"Model Damage Stage\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":3,\"p\":1,\"n\":\"Self Damage per Second\"},{\"t\":3,\"p\":1,\"n\":\"Explosion\"},{\"t\":3,\"p\":1,\"n\":\"Debris\"},{\"t\":3,\"p\":1,\"n\":\"Debris Count\"}]},{\"t\":6,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"DMDL - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"DMDT - Texture Files Hashes\"},{\"t\":7,\"p\":1,\"n\":\"DMDS - Alternate Textures\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"3D Name\"},{\"t\":3,\"p\":1,\"n\":\"New Texture\"},{\"t\":3,\"p\":1,\"n\":\"3D Index\"}]}]}]},{\"p\":1,\"n\":\"DSTF - End Marker\"}]}]}]},{\"t\":3,\"n\":\"KSIZ - Keyword Count\"},{\"t\":7,\"p\":1,\"n\":\"KWDA - Keywords\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Keyword\"}]},{\"t\":11,\"n\":\"PNAM - Unknown\"},{\"t\":3,\"p\":1,\"n\":\"SNAM - Looping Sound\"},{\"t\":11,\"n\":\"FNAM - Unknown\"},{\"t\":3,\"p\":1,\"n\":\"VNAM - Voice Type\"}]},{\"t\":1,\"p\":1,\"n\":\"TREE - Tree\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"VMAD - Virtual Machine Adapter\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Version\"},{\"t\":3,\"p\":1,\"n\":\"Object Format\"},{\"t\":7,\"p\":1,\"n\":\"Scripts\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Script\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"scriptName\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":7,\"p\":1,\"n\":\"Properties\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Property\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"propertyName\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]},{\"t\":2,\"p\":1,\"n\":\"String\"},{\"t\":3,\"p\":1,\"n\":\"Int32\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":3,\"p\":1,\"n\":\"Bool\"},{\"t\":7,\"p\":1,\"n\":\"Array of Object\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]}]},{\"t\":7,\"p\":1,\"n\":\"Array of String\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Int32\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Float\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Bool\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]}]}]}]}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"X1\"},{\"t\":3,\"p\":1,\"n\":\"Y1\"},{\"t\":3,\"p\":1,\"n\":\"Z1\"},{\"t\":3,\"p\":1,\"n\":\"X2\"},{\"t\":3,\"p\":1,\"n\":\"Y2\"},{\"t\":3,\"p\":1,\"n\":\"Z2\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"MODT - Texture Files Hashes\"},{\"t\":7,\"p\":1,\"n\":\"MODS - Alternate Textures\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"3D Name\"},{\"t\":3,\"p\":1,\"n\":\"New Texture\"},{\"t\":3,\"p\":1,\"n\":\"3D Index\"}]}]}]},{\"t\":3,\"p\":1,\"n\":\"PFIG - Ingredient\"},{\"t\":3,\"p\":1,\"n\":\"SNAM - Harvest Sound\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"PFPC - Ingredient Production\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Spring\"},{\"t\":3,\"p\":1,\"n\":\"Summer\"},{\"t\":3,\"p\":1,\"n\":\"Fall\"},{\"t\":3,\"p\":1,\"n\":\"Winter\"}]},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"CNAM - Tree Data\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Trunk Flexibility\"},{\"t\":5,\"p\":1,\"n\":\"Branch Flexibility\"},{\"t\":5,\"n\":\"Unknown\"},{\"t\":5,\"p\":1,\"n\":\"Leaf Amplitude\"},{\"t\":5,\"p\":1,\"n\":\"Leaf Frequency\"}]}]},{\"t\":1,\"p\":1,\"n\":\"TXST - Texture Set\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"X1\"},{\"t\":3,\"p\":1,\"n\":\"Y1\"},{\"t\":3,\"p\":1,\"n\":\"Z1\"},{\"t\":3,\"p\":1,\"n\":\"X2\"},{\"t\":3,\"p\":1,\"n\":\"Y2\"},{\"t\":3,\"p\":1,\"n\":\"Z2\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Textures (RGB\\/A)\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"TX00 - Difuse\"},{\"t\":2,\"p\":1,\"n\":\"TX01 - Normal\\/Gloss\"},{\"t\":2,\"p\":1,\"n\":\"TX02 - Environment Mask\\/Subsurface Tint\"},{\"t\":2,\"p\":1,\"n\":\"TX03 - Glow\\/Detail Map\"},{\"t\":2,\"p\":1,\"n\":\"TX04 - Height\"},{\"t\":2,\"p\":1,\"n\":\"TX05 - Environment\"},{\"t\":2,\"p\":1,\"n\":\"TX06 - Multilayer\"},{\"t\":2,\"p\":1,\"n\":\"TX07 - Backlight Mask\\/Specular\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DODT - Decal Data\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Min Width\"},{\"t\":5,\"p\":1,\"n\":\"Max Width\"},{\"t\":5,\"p\":1,\"n\":\"Min Height\"},{\"t\":5,\"p\":1,\"n\":\"Max Height\"},{\"t\":5,\"p\":1,\"n\":\"Depth\"},{\"t\":5,\"p\":1,\"n\":\"Shininess\"},{\"t\":6,\"p\":1,\"n\":\"Parallax\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Scale\"},{\"t\":3,\"p\":1,\"n\":\"Passes\"}]},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":6,\"p\":1,\"n\":\"Color\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]}]},{\"t\":3,\"p\":1,\"n\":\"DNAM - Flags\"}]},{\"t\":1,\"p\":1,\"n\":\"VOLI - Volumetric Lighting\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":5,\"p\":1,\"n\":\"CNAM - Intensity\"},{\"t\":5,\"p\":1,\"n\":\"DNAM - Custom Color - Contribution\"},{\"t\":5,\"p\":1,\"n\":\"ENAM - Red\"},{\"t\":5,\"p\":1,\"n\":\"FNAM - Green\"},{\"t\":5,\"p\":1,\"n\":\"GNAM - Blue\"},{\"t\":5,\"p\":1,\"n\":\"HNAM - Density - Contribution\"},{\"t\":5,\"p\":1,\"n\":\"INAM - Density - Size\"},{\"t\":5,\"p\":1,\"n\":\"JNAM - Density - Wind Speed\"},{\"t\":5,\"p\":1,\"n\":\"KNAM - Density - Falling Speed\"},{\"t\":5,\"p\":1,\"n\":\"LNAM - Phase Function - Contribution\"},{\"t\":5,\"p\":1,\"n\":\"MNAM - Phase Function - Scattering\"},{\"t\":5,\"p\":1,\"n\":\"NNAM - Sampling Repartition - Range Factor\"}]},{\"t\":1,\"p\":1,\"n\":\"VTYP - Voice Type\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":3,\"p\":1,\"n\":\"DNAM - Flags\"}]},{\"t\":1,\"p\":1,\"n\":\"WATR - Water\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":8,\"n\":\"Unused\",\"c\":[{\"t\":2,\"n\":\"NNAM - Noise Map\"}]},{\"t\":3,\"p\":1,\"n\":\"ANAM - Opacity\"},{\"t\":3,\"p\":1,\"n\":\"FNAM - Flags\"},{\"t\":11,\"n\":\"MNAM - Unused\"},{\"t\":3,\"p\":1,\"n\":\"TNAM - Material\"},{\"t\":3,\"p\":1,\"n\":\"SNAM - Open Sound\"},{\"t\":3,\"p\":1,\"n\":\"XNAM - Spell\"},{\"t\":3,\"p\":1,\"n\":\"INAM - Image Space\"},{\"t\":3,\"p\":1,\"n\":\"DATA - Damage Per Second\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DNAM - Visual Data\",\"c\":[{\"t\":5,\"n\":\"Unknown\"},{\"t\":5,\"p\":1,\"n\":\"Specular Properties - Sun Specular Power\"},{\"t\":5,\"p\":1,\"n\":\"Water Properties - Reflectivity Amount\"},{\"t\":5,\"p\":1,\"n\":\"Water Properties - Fresnel Amount\"},{\"t\":5,\"p\":1,\"n\":\"Fog Properties - Above Water - Fog Distance - Near Plane\"},{\"t\":5,\"p\":1,\"n\":\"Fog Properties - Above Water - Fog Distance - Far Plane\"},{\"t\":6,\"p\":1,\"n\":\"Shallow Color\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Deep Color\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Reflection Color\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":5,\"p\":1,\"n\":\"Displacement Simulator - Starting Size\"},{\"t\":5,\"p\":1,\"n\":\"Displacement Simulator - Force\"},{\"t\":5,\"p\":1,\"n\":\"Displacement Simulator - Velocity\"},{\"t\":5,\"p\":1,\"n\":\"Displacement Simulator - Falloff\"},{\"t\":5,\"p\":1,\"n\":\"Displacement Simulator - Dampner\"},{\"t\":5,\"p\":1,\"n\":\"Noise Properties - Noise Falloff\"},{\"t\":5,\"p\":1,\"n\":\"Noise Properties - Layer One - Wind Direction\"},{\"t\":5,\"p\":1,\"n\":\"Noise Properties - Layer Two - Wind Direction\"},{\"t\":5,\"p\":1,\"n\":\"Noise Properties - Layer Three - Wind Direction\"},{\"t\":5,\"p\":1,\"n\":\"Noise Properties - Layer One - Wind Speed\"},{\"t\":5,\"p\":1,\"n\":\"Noise Properties - Layer Two - Wind Speed\"},{\"t\":5,\"p\":1,\"n\":\"Noise Properties - Layer Three - Wind Speed\"},{\"t\":5,\"p\":1,\"n\":\"Fog Properties - Above Water - Fog Amount\"},{\"t\":5,\"p\":1,\"n\":\"Fog Properties - Under Water - Fog Amount\"},{\"t\":5,\"p\":1,\"n\":\"Fog Properties - Under Water - Fog Distance - Near Plane\"},{\"t\":5,\"p\":1,\"n\":\"Fog Properties - Under Water - Fog Distance - Far Plane\"},{\"t\":5,\"p\":1,\"n\":\"Water Properties - Refraction Magnitude\"},{\"t\":5,\"p\":1,\"n\":\"Specular Properties - Specular Power\"},{\"t\":5,\"p\":1,\"n\":\"Specular Properties - Specular Radius\"},{\"t\":5,\"p\":1,\"n\":\"Specular Properties - Specular Brightness\"},{\"t\":5,\"p\":1,\"n\":\"Noise Properties - Layer One - UV Scale\"},{\"t\":5,\"p\":1,\"n\":\"Noise Properties - Layer Two - UV Scale\"},{\"t\":5,\"p\":1,\"n\":\"Noise Properties - Layer Three - UV Scale\"},{\"t\":5,\"p\":1,\"n\":\"Noise Properties - Layer One - Amplitude Scale\"},{\"t\":5,\"p\":1,\"n\":\"Noise Properties - Layer Two - Amplitude Scale\"},{\"t\":5,\"p\":1,\"n\":\"Noise Properties - Layer Three - Amplitude Scale\"},{\"t\":5,\"p\":1,\"n\":\"Water Properties - Reflection Magnitude\"},{\"t\":5,\"p\":1,\"n\":\"Specular Properties - Sun Sparkle Magnitude\"},{\"t\":5,\"p\":1,\"n\":\"Specular Properties - Sun Specular Magnitude\"},{\"t\":5,\"p\":1,\"n\":\"Depth Properties - Reflections\"},{\"t\":5,\"p\":1,\"n\":\"Depth Properties - Refraction\"},{\"t\":5,\"p\":1,\"n\":\"Depth Properties - Normals\"},{\"t\":5,\"p\":1,\"n\":\"Depth Properties - Specular Lighting\"},{\"t\":5,\"p\":1,\"n\":\"Specular Properties - Sun Sparkle Power\"}]},{\"t\":11,\"n\":\"GNAM - Unused\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"NAM0 - Linear Velocity\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"X\"},{\"t\":5,\"p\":1,\"n\":\"Y\"},{\"t\":5,\"p\":1,\"n\":\"Z\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"NAM1 - Angular Velocity\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"X\"},{\"t\":5,\"p\":1,\"n\":\"Y\"},{\"t\":5,\"p\":1,\"n\":\"Z\"}]},{\"t\":2,\"p\":1,\"n\":\"NAM2 - Noise Layer One - Noise Texture\"},{\"t\":2,\"p\":1,\"n\":\"NAM3 - Noise Layer Two - Noise Texture\"},{\"t\":2,\"p\":1,\"n\":\"NAM4 - Noise Layer Three - Noise Texture\"},{\"t\":2,\"p\":1,\"n\":\"NAM5 - Flow Normals - Noise Texture\"}]},{\"t\":1,\"p\":1,\"n\":\"WEAP - Weapon\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"VMAD - Virtual Machine Adapter\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Version\"},{\"t\":3,\"p\":1,\"n\":\"Object Format\"},{\"t\":7,\"p\":1,\"n\":\"Scripts\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Script\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"scriptName\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":7,\"p\":1,\"n\":\"Properties\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Property\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"propertyName\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]},{\"t\":2,\"p\":1,\"n\":\"String\"},{\"t\":3,\"p\":1,\"n\":\"Int32\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":3,\"p\":1,\"n\":\"Bool\"},{\"t\":7,\"p\":1,\"n\":\"Array of Object\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]}]},{\"t\":7,\"p\":1,\"n\":\"Array of String\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Int32\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Float\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Bool\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]}]}]}]}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"OBND - Object Bounds\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"X1\"},{\"t\":3,\"p\":1,\"n\":\"Y1\"},{\"t\":3,\"p\":1,\"n\":\"Z1\"},{\"t\":3,\"p\":1,\"n\":\"X2\"},{\"t\":3,\"p\":1,\"n\":\"Y2\"},{\"t\":3,\"p\":1,\"n\":\"Z2\"}]},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"MODT - Texture Files Hashes\"},{\"t\":7,\"p\":1,\"n\":\"MODS - Alternate Textures\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"3D Name\"},{\"t\":3,\"p\":1,\"n\":\"New Texture\"},{\"t\":3,\"p\":1,\"n\":\"3D Index\"}]}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Icon\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"ICON - Large Icon filename\"},{\"t\":2,\"p\":1,\"n\":\"MICO - Small Icon filename\"}]},{\"t\":3,\"p\":1,\"n\":\"EITM - Object Effect\"},{\"t\":3,\"p\":1,\"n\":\"EAMT - Enchantment Amount\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Destructable\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"DEST - Header\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Health\"},{\"t\":3,\"p\":1,\"n\":\"DEST Count\"},{\"t\":3,\"p\":1,\"n\":\"VATS Targetable\"},{\"t\":11,\"n\":\"Unknown\"}]},{\"t\":8,\"p\":1,\"n\":\"Stages\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Stage\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"DSTD - Destruction Stage Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Health %\"},{\"t\":3,\"p\":1,\"n\":\"Index\"},{\"t\":3,\"p\":1,\"n\":\"Model Damage Stage\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":3,\"p\":1,\"n\":\"Self Damage per Second\"},{\"t\":3,\"p\":1,\"n\":\"Explosion\"},{\"t\":3,\"p\":1,\"n\":\"Debris\"},{\"t\":3,\"p\":1,\"n\":\"Debris Count\"}]},{\"t\":6,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"DMDL - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"DMDT - Texture Files Hashes\"},{\"t\":7,\"p\":1,\"n\":\"DMDS - Alternate Textures\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"3D Name\"},{\"t\":3,\"p\":1,\"n\":\"New Texture\"},{\"t\":3,\"p\":1,\"n\":\"3D Index\"}]}]}]},{\"p\":1,\"n\":\"DSTF - End Marker\"}]}]}]},{\"t\":3,\"p\":1,\"n\":\"ETYP - Equipment Type\"},{\"t\":3,\"p\":1,\"n\":\"BIDS - Block Bash Impact Data Set\"},{\"t\":3,\"p\":1,\"n\":\"BAMT - Alternate Block Material\"},{\"t\":3,\"p\":1,\"n\":\"YNAM - Sound - Pick Up\"},{\"t\":3,\"p\":1,\"n\":\"ZNAM - Sound - Put Down\"},{\"t\":3,\"n\":\"KSIZ - Keyword Count\"},{\"t\":7,\"p\":1,\"n\":\"KWDA - Keywords\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Keyword\"}]},{\"t\":2,\"p\":1,\"n\":\"DESC - Description\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Has Scope\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MOD3 - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"MO3T - Texture Files Hashes\"},{\"t\":7,\"p\":1,\"n\":\"MO3S - Alternate Textures\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"3D Name\"},{\"t\":3,\"p\":1,\"n\":\"New Texture\"},{\"t\":3,\"p\":1,\"n\":\"3D Index\"}]}]}]},{\"t\":11,\"n\":\"NNAM - Unused\"},{\"t\":3,\"p\":1,\"n\":\"INAM - Impact Data Set\"},{\"t\":3,\"p\":1,\"n\":\"WNAM - 1st Person Model Object\"},{\"t\":3,\"p\":1,\"n\":\"SNAM - Attack Sound\"},{\"t\":3,\"p\":1,\"n\":\"XNAM - Attack Sound 2D\"},{\"t\":3,\"p\":1,\"n\":\"NAM7 - Attack Loop Sound\"},{\"t\":3,\"p\":1,\"n\":\"TNAM - Attack Fail Sound\"},{\"t\":3,\"p\":1,\"n\":\"UNAM - Idle Sound\"},{\"t\":3,\"p\":1,\"n\":\"NAM9 - Equip Sound\"},{\"t\":3,\"p\":1,\"n\":\"NAM8 - Unequip Sound\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DATA - Game Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Value\"},{\"t\":5,\"p\":1,\"n\":\"Weight\"},{\"t\":3,\"p\":1,\"n\":\"Damage\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DNAM - Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Animation Type\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":5,\"p\":1,\"n\":\"Speed\"},{\"t\":5,\"p\":1,\"n\":\"Reach\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":5,\"p\":1,\"n\":\"Sight FOV\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":3,\"p\":1,\"n\":\"Base VATS To-Hit Chance\"},{\"t\":3,\"p\":1,\"n\":\"Attack Animation\"},{\"t\":3,\"p\":1,\"n\":\"# Projectiles\"},{\"t\":3,\"p\":1,\"n\":\"Embedded Weapon AV (unused)\"},{\"t\":5,\"p\":1,\"n\":\"Range Min\"},{\"t\":5,\"p\":1,\"n\":\"Range Max\"},{\"t\":3,\"p\":1,\"n\":\"On Hit\"},{\"t\":3,\"p\":1,\"n\":\"Flags2\"},{\"t\":5,\"p\":1,\"n\":\"Animation Attack Mult\"},{\"t\":5,\"p\":1,\"n\":\"Rumble - Left Motor Strength\"},{\"t\":5,\"p\":1,\"n\":\"Rumble - Right Motor Strength\"},{\"t\":5,\"p\":1,\"n\":\"Rumble - Duration\"},{\"t\":3,\"p\":1,\"n\":\"Skill\"},{\"t\":3,\"p\":1,\"n\":\"Resist\"},{\"t\":5,\"p\":1,\"n\":\"Stagger\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"CRDT - Critical Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Damage\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":5,\"p\":1,\"n\":\"% Mult\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Effect\"}]},{\"t\":3,\"p\":1,\"n\":\"VNAM - Detection Sound Level\"},{\"t\":3,\"p\":1,\"n\":\"CNAM - Template\"}]},{\"t\":1,\"p\":1,\"n\":\"WOOP - Word of Power\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":2,\"p\":1,\"n\":\"TNAM - Translation\"}]},{\"t\":1,\"p\":1,\"n\":\"WRLD - Worldspace\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":8,\"n\":\"Unused RNAM\",\"c\":[{\"t\":6,\"n\":\"RNAM - Grid\",\"c\":[{\"t\":3,\"n\":\"Y\"},{\"t\":3,\"n\":\"X\"},{\"t\":7,\"n\":\"References\",\"c\":[{\"t\":6,\"n\":\"Reference\",\"c\":[{\"t\":3,\"n\":\"Ref\"},{\"t\":3,\"n\":\"Y\"},{\"t\":3,\"n\":\"X\"}]}]}]}]},{\"t\":11,\"n\":\"MHDT - Max Height Data\"},{\"t\":2,\"p\":1,\"n\":\"FULL - Name\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"WCTR - Fixed Dimensions Center Cell\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"X\"},{\"t\":3,\"p\":1,\"n\":\"Y\"}]},{\"t\":3,\"p\":1,\"n\":\"LTMP - Interior Lighting\"},{\"t\":3,\"p\":1,\"n\":\"XEZN - Encounter Zone\"},{\"t\":3,\"p\":1,\"n\":\"XLCN - Location\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Parent\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"WNAM - Worldspace\"},{\"t\":6,\"p\":1,\"n\":\"PNAM - \",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unknown\"}]}]},{\"t\":3,\"p\":1,\"n\":\"CNAM - Climate\"},{\"t\":3,\"p\":1,\"n\":\"NAM2 - Water\"},{\"t\":3,\"p\":1,\"n\":\"NAM3 - LOD Water Type\"},{\"t\":5,\"p\":1,\"n\":\"NAM4 - LOD Water Height\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DNAM - Land Data\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Default Land Height\"},{\"t\":5,\"p\":1,\"n\":\"Default Water Height\"}]},{\"t\":2,\"p\":1,\"n\":\"ICON - Map Image\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Cloud Model\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"MODT - Texture Files Hashes\"},{\"t\":7,\"p\":1,\"n\":\"MODS - Alternate Textures\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"3D Name\"},{\"t\":3,\"p\":1,\"n\":\"New Texture\"},{\"t\":3,\"p\":1,\"n\":\"3D Index\"}]}]}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"MNAM - Map Data\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Usable Dimensions\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"X\"},{\"t\":3,\"p\":1,\"n\":\"Y\"}]},{\"t\":6,\"p\":1,\"n\":\"Cell Coordinates\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"NW Cell\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"X\"},{\"t\":3,\"p\":1,\"n\":\"Y\"}]},{\"t\":6,\"p\":1,\"n\":\"SE Cell\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"X\"},{\"t\":3,\"p\":1,\"n\":\"Y\"}]}]},{\"t\":6,\"p\":1,\"n\":\"Camera Data\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Min Height\"},{\"t\":5,\"p\":1,\"n\":\"Max Height\"},{\"t\":5,\"p\":1,\"n\":\"Initial Pitch\"}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"ONAM - World Map Offset Data\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"World Map Scale\"},{\"t\":5,\"p\":1,\"n\":\"Cell X Offset\"},{\"t\":5,\"p\":1,\"n\":\"Cell Y Offset\"},{\"t\":5,\"p\":1,\"n\":\"Cell Z Offset\"}]},{\"t\":5,\"p\":1,\"n\":\"NAMA - Distant LOD Multiplier\"},{\"t\":3,\"p\":1,\"n\":\"DATA - Flags\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Object Bounds\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"NAM0 - Min\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"X\"},{\"t\":5,\"p\":1,\"n\":\"Y\"}]},{\"t\":6,\"p\":1,\"n\":\"NAM9 - Max\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"X\"},{\"t\":5,\"p\":1,\"n\":\"Y\"}]}]},{\"t\":3,\"p\":1,\"n\":\"ZNAM - Music\"},{\"t\":2,\"p\":1,\"n\":\"NNAM - Canopy Shadow (unused)\"},{\"t\":2,\"p\":1,\"n\":\"XNAM - Water Noise Texture\"},{\"t\":2,\"p\":1,\"n\":\"TNAM - HD LOD Diffuse Texture\"},{\"t\":2,\"p\":1,\"n\":\"UNAM - HD LOD Normal Texture\"},{\"t\":2,\"p\":1,\"n\":\"XWEM - Water Environment Map (unused)\"},{\"t\":11,\"n\":\"OFST - Offset Data\"}]},{\"t\":1,\"p\":1,\"n\":\"WTHR - Weather\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":2,\"p\":1,\"n\":\"00TX - Cloud Texture Layer #0\"},{\"t\":2,\"p\":1,\"n\":\"10TX - Cloud Texture Layer #1\"},{\"t\":2,\"p\":1,\"n\":\"20TX - Cloud Texture Layer #2\"},{\"t\":2,\"p\":1,\"n\":\"30TX - Cloud Texture Layer #3\"},{\"t\":2,\"p\":1,\"n\":\"40TX - Cloud Texture Layer #4\"},{\"t\":2,\"p\":1,\"n\":\"50TX - Cloud Texture Layer #5\"},{\"t\":2,\"p\":1,\"n\":\"60TX - Cloud Texture Layer #6\"},{\"t\":2,\"p\":1,\"n\":\"70TX - Cloud Texture Layer #7\"},{\"t\":2,\"p\":1,\"n\":\"80TX - Cloud Texture Layer #8\"},{\"t\":2,\"p\":1,\"n\":\"90TX - Cloud Texture Layer #9\"},{\"t\":2,\"p\":1,\"n\":\":0TX - Cloud Texture Layer #10\"},{\"t\":2,\"p\":1,\"n\":\";0TX - Cloud Texture Layer #11\"},{\"t\":2,\"p\":1,\"n\":\"<0TX - Cloud Texture Layer #12\"},{\"t\":2,\"p\":1,\"n\":\"=0TX - Cloud Texture Layer #13\"},{\"t\":2,\"p\":1,\"n\":\">0TX - Cloud Texture Layer #14\"},{\"t\":2,\"p\":1,\"n\":\"?0TX - Cloud Texture Layer #15\"},{\"t\":2,\"p\":1,\"n\":\"@0TX - Cloud Texture Layer #16\"},{\"t\":2,\"p\":1,\"n\":\"A0TX - Cloud Texture Layer #17\"},{\"t\":2,\"p\":1,\"n\":\"B0TX - Cloud Texture Layer #18\"},{\"t\":2,\"p\":1,\"n\":\"C0TX - Cloud Texture Layer #19\"},{\"t\":2,\"p\":1,\"n\":\"D0TX - Cloud Texture Layer #20\"},{\"t\":2,\"p\":1,\"n\":\"E0TX - Cloud Texture Layer #21\"},{\"t\":2,\"p\":1,\"n\":\"F0TX - Cloud Texture Layer #22\"},{\"t\":2,\"p\":1,\"n\":\"G0TX - Cloud Texture Layer #23\"},{\"t\":2,\"p\":1,\"n\":\"H0TX - Cloud Texture Layer #24\"},{\"t\":2,\"p\":1,\"n\":\"I0TX - Cloud Texture Layer #25\"},{\"t\":2,\"p\":1,\"n\":\"J0TX - Cloud Texture Layer #26\"},{\"t\":2,\"p\":1,\"n\":\"K0TX - Cloud Texture Layer #27\"},{\"t\":2,\"p\":1,\"n\":\"L0TX - Cloud Texture Layer #28\"},{\"t\":11,\"n\":\"DNAM - Unused\"},{\"t\":11,\"n\":\"CNAM - Unused\"},{\"t\":11,\"n\":\"ANAM - Unused\"},{\"t\":11,\"n\":\"BNAM - Unused\"},{\"t\":11,\"n\":\"LNAM - Unknown\"},{\"t\":3,\"p\":1,\"n\":\"MNAM - Precipitation Type\"},{\"t\":3,\"p\":1,\"n\":\"NNAM - Visual Effect\"},{\"t\":11,\"n\":\"ONAM - Unused\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Cloud Speed\",\"c\":[{\"t\":7,\"p\":1,\"n\":\"RNAM - Y Speed\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Layer\"}]},{\"t\":7,\"p\":1,\"n\":\"QNAM - X Speed\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Layer\"}]}]},{\"t\":7,\"s\":1,\"p\":1,\"n\":\"PNAM - Cloud Colors\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Layer\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Sunrise\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Day\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Sunset\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Night\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]}]}]},{\"t\":7,\"s\":1,\"p\":1,\"n\":\"JNAM - Cloud Alphas\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Layer\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Sunrise\"},{\"t\":5,\"p\":1,\"n\":\"Day\"},{\"t\":5,\"p\":1,\"n\":\"Sunset\"},{\"t\":5,\"p\":1,\"n\":\"Night\"}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"NAM0 - Weather Colors\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Sky-Upper\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Sunrise\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Day\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Sunset\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Night\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]}]},{\"t\":6,\"p\":1,\"n\":\"Fog Near\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Sunrise\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Day\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Sunset\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Night\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]}]},{\"t\":6,\"n\":\"Unknown\",\"c\":[{\"t\":6,\"n\":\"Sunrise\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"n\":\"Day\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"n\":\"Sunset\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"n\":\"Night\",\"c\":[{\"t\":3,\"n\":\"Red\"},{\"t\":3,\"n\":\"Green\"},{\"t\":3,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]}]},{\"t\":6,\"p\":1,\"n\":\"Ambient\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Sunrise\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Day\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Sunset\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Night\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]}]},{\"t\":6,\"p\":1,\"n\":\"Sunlight\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Sunrise\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Day\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Sunset\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Night\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]}]},{\"t\":6,\"p\":1,\"n\":\"Sun\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Sunrise\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Day\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Sunset\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Night\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]}]},{\"t\":6,\"p\":1,\"n\":\"Stars\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Sunrise\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Day\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Sunset\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Night\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]}]},{\"t\":6,\"p\":1,\"n\":\"Sky-Lower\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Sunrise\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Day\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Sunset\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Night\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]}]},{\"t\":6,\"p\":1,\"n\":\"Horizon\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Sunrise\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Day\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Sunset\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Night\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]}]},{\"t\":6,\"p\":1,\"n\":\"Effect Lighting\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Sunrise\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Day\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Sunset\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Night\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]}]},{\"t\":6,\"p\":1,\"n\":\"Cloud LOD Diffuse\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Sunrise\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Day\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Sunset\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Night\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]}]},{\"t\":6,\"p\":1,\"n\":\"Cloud LOD Ambient\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Sunrise\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Day\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Sunset\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Night\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]}]},{\"t\":6,\"p\":1,\"n\":\"Fog Far\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Sunrise\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Day\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Sunset\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Night\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]}]},{\"t\":6,\"p\":1,\"n\":\"Sky Statics\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Sunrise\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Day\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Sunset\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Night\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]}]},{\"t\":6,\"p\":1,\"n\":\"Water Multiplier\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Sunrise\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Day\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Sunset\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Night\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]}]},{\"t\":6,\"p\":1,\"n\":\"Sun Glare\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Sunrise\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Day\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Sunset\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Night\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]}]},{\"t\":6,\"p\":1,\"n\":\"Moon Glare\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Sunrise\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Day\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Sunset\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Night\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"FNAM - Fog Distance\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Day - Near\"},{\"t\":5,\"p\":1,\"n\":\"Day - Far\"},{\"t\":5,\"p\":1,\"n\":\"Night - Near\"},{\"t\":5,\"p\":1,\"n\":\"Night - Far\"},{\"t\":5,\"p\":1,\"n\":\"Day - Power\"},{\"t\":5,\"p\":1,\"n\":\"Night - Power\"},{\"t\":5,\"p\":1,\"n\":\"Day - Max\"},{\"t\":5,\"p\":1,\"n\":\"Night - Max\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DATA - Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Wind Speed\"},{\"t\":11,\"n\":\"Unknown\"},{\"t\":3,\"p\":1,\"n\":\"Trans Delta\"},{\"t\":3,\"p\":1,\"n\":\"Sun Glare\"},{\"t\":3,\"p\":1,\"n\":\"Sun Damage\"},{\"t\":3,\"p\":1,\"n\":\"Precipitation - Begin Fade In\"},{\"t\":3,\"p\":1,\"n\":\"Precipitation - End Fade Out\"},{\"t\":3,\"p\":1,\"n\":\"Thunder\\/Lightning - Begin Fade In\"},{\"t\":3,\"p\":1,\"n\":\"Thunder\\/Lightning - End Fade Out\"},{\"t\":3,\"p\":1,\"n\":\"Thunder\\/Lightning - Frequency\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":6,\"p\":1,\"n\":\"Lightning Color\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"}]},{\"t\":3,\"p\":1,\"n\":\"Visual Effect - Begin\"},{\"t\":3,\"p\":1,\"n\":\"Visual Effect - End\"},{\"t\":3,\"p\":1,\"n\":\"Wind Direction\"},{\"t\":3,\"p\":1,\"n\":\"Wind Direction Range\"}]},{\"t\":3,\"p\":1,\"n\":\"NAM1 - Disabled Cloud Layers\"},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Sounds\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"SNAM - Sound\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Sound\"},{\"t\":3,\"p\":1,\"n\":\"Type\"}]}]},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Sky Statics\",\"d\":1,\"c\":[{\"t\":3,\"p\":1,\"n\":\"TNAM - Static\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"IMSP - Image Spaces\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Sunrise\"},{\"t\":3,\"p\":1,\"n\":\"Day\"},{\"t\":3,\"p\":1,\"n\":\"Sunset\"},{\"t\":3,\"p\":1,\"n\":\"Night\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"HNAM - Volumetric Lighting\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Sunrise\"},{\"t\":3,\"p\":1,\"n\":\"Day\"},{\"t\":3,\"p\":1,\"n\":\"Sunset\"},{\"t\":3,\"p\":1,\"n\":\"Night\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Directional Ambient Lighting Colors\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"DALC - Sunrise\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Directional\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"X+\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"X-\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Y+\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Y-\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Z+\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Z-\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]}]},{\"t\":6,\"p\":1,\"n\":\"Specular\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":5,\"p\":1,\"n\":\"Scale\"}]},{\"t\":6,\"p\":1,\"n\":\"DALC - Day\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Directional\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"X+\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"X-\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Y+\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Y-\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Z+\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Z-\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]}]},{\"t\":6,\"p\":1,\"n\":\"Specular\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":5,\"p\":1,\"n\":\"Scale\"}]},{\"t\":6,\"p\":1,\"n\":\"DALC - Sunset\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Directional\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"X+\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"X-\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Y+\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Y-\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Z+\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Z-\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]}]},{\"t\":6,\"p\":1,\"n\":\"Specular\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":5,\"p\":1,\"n\":\"Scale\"}]},{\"t\":6,\"p\":1,\"n\":\"DALC - Night\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Directional\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"X+\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"X-\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Y+\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Y-\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Z+\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Z-\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]}]},{\"t\":6,\"p\":1,\"n\":\"Specular\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":5,\"p\":1,\"n\":\"Scale\"}]}]},{\"t\":11,\"n\":\"NAM2 - Unused\"},{\"t\":11,\"n\":\"NAM3 - Unused\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Aurora\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Model\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"MODL - Model Filename\"},{\"t\":11,\"p\":1,\"n\":\"MODT - Texture Files Hashes\"},{\"t\":7,\"p\":1,\"n\":\"MODS - Alternate Textures\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Alternate Texture\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"3D Name\"},{\"t\":3,\"p\":1,\"n\":\"New Texture\"},{\"t\":3,\"p\":1,\"n\":\"3D Index\"}]}]}]}]},{\"t\":3,\"p\":1,\"n\":\"GNAM - Sun Glare Lens Flare\"}]},{\"t\":1,\"p\":1,\"n\":\"ACHR - Placed NPC\",\"d\":1,\"c\":[{\"t\":2,\"p\":1,\"n\":\"EDID - Editor ID\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"VMAD - Virtual Machine Adapter\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Version\"},{\"t\":3,\"p\":1,\"n\":\"Object Format\"},{\"t\":7,\"p\":1,\"n\":\"Scripts\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Script\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"scriptName\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":7,\"p\":1,\"n\":\"Properties\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Property\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"propertyName\"},{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"},{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]},{\"t\":2,\"p\":1,\"n\":\"String\"},{\"t\":3,\"p\":1,\"n\":\"Int32\"},{\"t\":5,\"p\":1,\"n\":\"Float\"},{\"t\":3,\"p\":1,\"n\":\"Bool\"},{\"t\":7,\"p\":1,\"n\":\"Array of Object\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Object v2\",\"c\":[{\"t\":3,\"n\":\"Unused\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"p\":1,\"n\":\"FormID\"}]},{\"t\":6,\"p\":1,\"n\":\"Object v1\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"FormID\"},{\"t\":3,\"p\":1,\"n\":\"Alias\"},{\"t\":3,\"n\":\"Unused\"}]}]},{\"t\":7,\"p\":1,\"n\":\"Array of String\",\"c\":[{\"t\":2,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Int32\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Float\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"Element\"}]},{\"t\":7,\"p\":1,\"n\":\"Array of Bool\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Element\"}]}]}]}]}]}]},{\"t\":3,\"p\":1,\"n\":\"NAME - Base\"},{\"t\":3,\"p\":1,\"n\":\"XEZN - Encounter Zone\"},{\"t\":11,\"n\":\"XRGD - Ragdoll Data\"},{\"t\":11,\"n\":\"XRGB - Ragdoll Biped Data\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Patrol Data\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"XPRD - Idle Time\"},{\"p\":1,\"n\":\"XPPA - Patrol Script Marker\"},{\"t\":3,\"p\":1,\"n\":\"INAM - Idle\"},{\"t\":6,\"n\":\"Unused\",\"c\":[{\"t\":11,\"n\":\"SCHR - Unknown\"},{\"t\":11,\"n\":\"SCDA - Unknown\"},{\"t\":11,\"n\":\"SCTX - Unknown\"},{\"t\":11,\"n\":\"QNAM - Unknown\"},{\"t\":11,\"n\":\"SCRO - Unknown\"}]},{\"t\":8,\"p\":1,\"n\":\"Topic\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"PDTO - Topic Data\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Type\"},{\"t\":3,\"p\":1,\"n\":\"Topic\"},{\"t\":2,\"p\":1,\"n\":\"Subtype\"}]}]},{\"t\":3,\"p\":1,\"n\":\"TNAM - Topic\"}]},{\"t\":3,\"p\":1,\"n\":\"XLCM - Level Modifier\"},{\"t\":3,\"p\":1,\"n\":\"XMRC - Merchant Container\"},{\"t\":3,\"p\":1,\"n\":\"XCNT - Count\"},{\"t\":5,\"p\":1,\"n\":\"XRDS - Radius\"},{\"t\":5,\"p\":1,\"n\":\"XHLP - Health\"},{\"t\":8,\"s\":1,\"p\":1,\"n\":\"Linked References\",\"d\":1,\"c\":[{\"t\":6,\"p\":1,\"n\":\"XLKR - Linked Reference\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Keyword\\/Ref\"},{\"t\":3,\"p\":1,\"n\":\"Ref\"}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Activate Parents\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"XAPD - Flags\"},{\"t\":8,\"p\":1,\"n\":\"Activate Parent Refs\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"XAPR - Activate Parent Ref\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":5,\"p\":1,\"n\":\"Delay\"}]}]}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"XCLP - Linked Reference Color\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Link Start Color\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"p\":1,\"n\":\"Link End Color\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Red\"},{\"t\":3,\"p\":1,\"n\":\"Green\"},{\"t\":3,\"p\":1,\"n\":\"Blue\"},{\"t\":11,\"n\":\"Unused\"}]}]},{\"t\":3,\"p\":1,\"n\":\"XLCN - Persistent Location\"},{\"t\":3,\"p\":1,\"n\":\"XLRL - Location Reference\"},{\"p\":1,\"n\":\"XIS2 - Ignored by Sandbox\"},{\"t\":7,\"p\":1,\"n\":\"XLRT - Location Ref Type\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Ref\"}]},{\"t\":3,\"p\":1,\"n\":\"XHOR - Horse\"},{\"t\":5,\"p\":1,\"n\":\"XHTW - Head-Tracking Weight\"},{\"t\":5,\"p\":1,\"n\":\"XFVC - Favor Cost\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"XESP - Enable Parent\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"Reference\"},{\"t\":3,\"p\":1,\"n\":\"Flags\"},{\"t\":11,\"n\":\"Unused\"}]},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"Ownership\",\"c\":[{\"t\":3,\"p\":1,\"n\":\"XOWN - Owner\"},{\"t\":3,\"p\":1,\"n\":\"XRNK - Faction rank\"}]},{\"t\":3,\"p\":1,\"n\":\"XEMI - Emittance\"},{\"t\":3,\"p\":1,\"n\":\"XMBR - MultiBound Reference\"},{\"p\":1,\"n\":\"XIBS - Ignored By Sandbox\"},{\"t\":5,\"p\":1,\"n\":\"XSCL - Scale\"},{\"t\":6,\"s\":1,\"p\":1,\"n\":\"DATA - Position\\/Rotation\",\"c\":[{\"t\":6,\"p\":1,\"n\":\"Position\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"X\"},{\"t\":5,\"p\":1,\"n\":\"Y\"},{\"t\":5,\"p\":1,\"n\":\"Z\"}]},{\"t\":6,\"p\":1,\"n\":\"Rotation\",\"c\":[{\"t\":5,\"p\":1,\"n\":\"X\"},{\"t\":5,\"p\":1,\"n\":\"Y\"},{\"t\":5,\"p\":1,\"n\":\"Z\"}]}]}]}]},\"name\":\"Smash.OverrideAll\",\"hash\":\"36B6DC28\",\"color\":32768}"
  },
  {
    "path": "frontend/smash.rc",
    "content": "SMASH WAV \".\\Resources\\smash.wav\""
  },
  {
    "path": "lib/Imaging/Imaging.pas",
    "content": "{\n  Vampyre Imaging Library\n  by Marek Mauder \n  http://imaginglib.sourceforge.net\n\n  The contents of this file are used with permission, subject to the Mozilla\n  Public License Version 1.1 (the \"License\"); you may not use this file except\n  in compliance with the License. You may obtain a copy of the License at\n  http://www.mozilla.org/MPL/MPL-1.1.html\n\n  Software distributed under the License is distributed on an \"AS IS\" basis,\n  WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for\n  the specific language governing rights and limitations under the License.\n\n  Alternatively, the contents of this file may be used under the terms of the\n  GNU Lesser General Public License (the  \"LGPL License\"), in which case the\n  provisions of the LGPL License are applicable instead of those above.\n  If you wish to allow use of your version of this file only under the terms\n  of the LGPL License and not to allow others to use your version of this file\n  under the MPL, indicate your decision by deleting  the provisions above and\n  replace  them with the notice and other provisions required by the LGPL\n  License.  If you do not delete the provisions above, a recipient may use\n  your version of this file under either the MPL or the LGPL License.\n\n  For more information about the LGPL: http://www.gnu.org/copyleft/lesser.html\n}\n\n{ This unit is heart of Imaging library. It contains basic functions for\n  manipulating image data as well as various image file format support.}\nunit Imaging;\n\n{$I ImagingOptions.inc}\n\ninterface\n\nuses\n  SysUtils, Classes, Types, ImagingTypes;\n\ntype\n  { Default Imaging excepton class }\n  EImagingError = class(Exception);\n  { Raised when function receives bad image (not passed TestImage).}\n  EImagingBadImage = class(Exception)\n  public\n    constructor Create;\n  end;\n\n  { Dynamic array of TImageData records }\n  TDynImageDataArray = array of TImageData;\n\n\n{ ------------------------------------------------------------------------\n                       Low Level Interface Functions\n  ------------------------------------------------------------------------}\n\n{ General Functions }\n\n{ Initializes image (all is set to zeroes). Call this for each image\n  before using it (before calling every other function) to be sure there\n  are no random-filled bytes (which would cause errors later).}\nprocedure InitImage(var Image: TImageData);\n{ Creates empty image of given dimensions and format. Image is filled with\n  transparent black color (A=0, R=0, G=0, B=0).}\nfunction NewImage(Width, Height: LongInt; Format: TImageFormat;\n  var Image: TImageData): Boolean;\n{ Returns True if given TImageData record is valid.}\nfunction TestImage(const Image: TImageData): Boolean;\n{ Frees given image data. Ater this call image is in the same state\n  as after calling InitImage. If image is not valid (dost not pass TestImage\n  test) it is only zeroed by calling InitImage.}\nprocedure FreeImage(var Image: TImageData);\n{ Call FreeImage() on all images in given dynamic array and sets its\n  length to zero.}\nprocedure FreeImagesInArray(var Images: TDynImageDataArray);\n{ Returns True if all TImageData records in given array are valid. Returns False\n  if at least one is invalid or if array is empty.}\nfunction TestImagesInArray(const Images: TDynImageDataArray): Boolean;\n{ Checks given file for every supported image file format and if\n  the file is in one of them returns its string identifier\n  (which can be used in LoadFromStream/LoadFromMem type functions).\n  If file is not in any of the supported formats empty string is returned.}\nfunction DetermineFileFormat(const FileName: string): string;\n{ Checks given stream for every supported image file format and if\n  the stream is in one of them returns its string identifier\n  (which can be used in LoadFromStream/LoadFromMem type functions).\n  If stream is not in any of the supported formats empty string is returned.}\nfunction DetermineStreamFormat(Stream: TStream): string;\n{ Checks given memory for every supported image file format and if\n  the memory is in one of them returns its string identifier\n  (which can be used in LoadFromStream/LoadFromMem type functions).\n  If memory is not in any of the supported formats empty string is returned.}\nfunction DetermineMemoryFormat(Data: Pointer; Size: LongInt): string;\n{ Checks that an apropriate file format is supported purely from inspecting\n  the given file name's extension (not contents of the file itself).\n  The file need not exist.}\nfunction IsFileFormatSupported(const FileName: string): Boolean;\n{ Enumerates all registered image file formats. Descriptive name,\n  default extension, masks (like '*.jpg,*.jfif') and some capabilities\n  of each format are returned. To enumerate all formats start with Index at 0 and\n  call EnumFileFormats with given Index in loop until it returns False (Index is\n  automatically increased by 1 in function's body on successful call).}\nfunction EnumFileFormats(var Index: LongInt; var Name, DefaultExt, Masks: string;\n  var CanSaveImages, IsMultiImageFormat: Boolean): Boolean;\n\n{ Loading Functions }\n\n{ Loads single image from given file.}\nfunction LoadImageFromFile(const FileName: string; var Image: TImageData): Boolean;\n{ Loads single image from given stream. If function fails stream position\n  is not changed.}\nfunction LoadImageFromStream(Stream: TStream; var Image: TImageData): Boolean;\n{ Loads single image from given memory location.}\nfunction LoadImageFromMemory(Data: Pointer; Size: LongInt; var Image: TImageData): Boolean;\n{ Loads multiple images from given file.}\nfunction LoadMultiImageFromFile(const FileName: string;\n  var Images: TDynImageDataArray): Boolean;\n{ Loads multiple images from given stream. If function fails stream position\n  is not changed.}\nfunction LoadMultiImageFromStream(Stream: TStream;\n  var Images: TDynImageDataArray): Boolean;\n{ Loads multiple images from given memory location.}\nfunction LoadMultiImageFromMemory(Data: Pointer; Size: LongInt;\n  var Images: TDynImageDataArray): Boolean;\n\n{ Saving Functions }\n\n{ Saves single image to given file.}\nfunction SaveImageToFile(const FileName: string; const Image: TImageData): Boolean;\n{ Saves single image to given stream. If function fails stream position\n  is not changed. Ext identifies desired image file format (jpg, png, dds, ...).}\nfunction SaveImageToStream(const Ext: string; Stream: TStream;\n  const Image: TImageData): Boolean;\n{ Saves single image to given memory location. Memory must be allocated and its\n  size is passed in Size parameter in which number of written bytes is returned.\n  Ext identifies desired image file format (jpg, png, dds, ...).}\nfunction SaveImageToMemory(const Ext: string; Data: Pointer; var Size: LongInt;\n  const Image: TImageData): Boolean;\n{ Saves multiple images to given file. If format supports\n  only single level images and there are multiple images to be saved,\n  they are saved as sequence of files img000.jpg, img001.jpg ....).}\nfunction SaveMultiImageToFile(const FileName: string;\n  const Images: TDynImageDataArray): Boolean;\n{ Saves multiple images to given stream. If format supports\n  only single level images and there are multiple images to be saved,\n  they are saved one after another to the stream. If function fails stream\n  position is not changed. Ext identifies desired image file format (jpg, png, dds, ...).}\nfunction SaveMultiImageToStream(const Ext: string; Stream: TStream;\n  const Images: TDynImageDataArray): Boolean;\n{ Saves multiple images to given memory location. If format supports\n  only single level images and there are multiple images to be saved,\n  they are saved one after another to the memory. Memory must be allocated and\n  its size is passed in Size parameter in which number of written bytes is returned.\n  Ext identifies desired image file format (jpg, png, dds, ...).}\nfunction SaveMultiImageToMemory(const Ext: string; Data: Pointer;\n  var Size: LongInt; const Images: TDynImageDataArray): Boolean;\n\n{ Manipulation Functions }\n\n{ Creates identical copy of image data. Clone should be initialized\n  by InitImage or it should be vaild image which will be freed by CloneImage.}\nfunction CloneImage(const Image: TImageData; var Clone: TImageData): Boolean;\n{ Converts image to the given format.}\nfunction ConvertImage(var Image: TImageData; DestFormat: TImageFormat): Boolean;\n{ Flips given image. Reverses the image along its horizontal axis - the top\n  becomes the bottom and vice versa.}\nfunction FlipImage(var Image: TImageData): Boolean;\n{ Mirrors given image. Reverses the image along its vertical axis  the left\n  side becomes the right and vice versa.}\nfunction MirrorImage(var Image: TImageData): Boolean;\n{ Resizes given image to new dimensions. Nearest, bilinear, or bicubic filtering\n  can be used. Input Image must already be created - use NewImage to create new images.}\nfunction ResizeImage(var Image: TImageData; NewWidth, NewHeight: LongInt;\n  Filter: TResizeFilter): Boolean;\n{ Swaps SrcChannel and DstChannel color or alpha channels of image.\n  Use ChannelRed, ChannelBlue, ChannelGreen, ChannelAlpha constants to\n  identify channels.}\nfunction SwapChannels(var Image: TImageData; SrcChannel, DstChannel: LongInt): Boolean;\n{ Reduces the number of colors of the Image. Currently MaxColors must be in\n  range <2, 4096>. Color reduction works also for alpha channel. Note that for\n  large images and big number of colors it can be very slow.\n  Output format of the image is the same as input format.}\nfunction ReduceColors(var Image: TImageData; MaxColors: LongInt): Boolean;\n{ Generates mipmaps for image. Levels is the number of desired mipmaps levels\n  with zero (or some invalid number) meaning all possible levels.}\nfunction GenerateMipMaps(const Image: TImageData; Levels: LongInt;\n  var MipMaps: TDynImageDataArray): Boolean;\n{ Maps image to existing palette producing image in ifIndex8 format.\n  Pal must be allocated to at least Entries * SizeOf(TColor32Rec) bytes.\n  As resulting image is in 8bit indexed format Entries must be lower or\n  equal to 256.}\nfunction MapImageToPalette(var Image: TImageData; Pal: PPalette32;\n  Entries: LongInt): Boolean;\n{ Splits image into XChunks x YChunks subimages. Default size of each chunk is\n  ChunkWidth x ChunkHeight. If PreserveSize si True chunks at the edges of\n  the image are also ChunkWidth x ChunkHeight sized and empty space is filled\n  with optional Fill pixels. After calling this function XChunks contains number of\n  chunks along x axis and YChunks along y axis. To access chunk [X, Y] use this\n  index: Chunks[Y * XChunks + X].}\nfunction SplitImage(var Image: TImageData; var Chunks: TDynImageDataArray;\n  ChunkWidth, ChunkHeight: LongInt; var XChunks, YChunks: LongInt;\n  PreserveSize: Boolean; Fill: Pointer = nil): Boolean;\n{ Creates palette with MaxColors based on the colors of images in Images array.\n  Use it when you want to convert several images to indexed format using\n  single palette for all of them. If ConvertImages is True images in array\n  are converted to indexed format using resulting palette. if it is False\n  images are left intact and only resulting palatte is returned in Pal.\n  Pal must be allocated to have at least MaxColors entries.}\nfunction MakePaletteForImages(var Images: TDynImageDataArray; Pal: PPalette32;\n  MaxColors: LongInt; ConvertImages: Boolean): Boolean;\n{ Rotates image by Angle degrees counterclockwise. All angles are allowed.}\nprocedure RotateImage(var Image: TImageData; Angle: Single);\n\n{ Drawing/Pixel functions }\n\n{ Copies rectangular part of SrcImage to DstImage. No blending is performed -\n  alpha is simply copied to destination image. Operates also with\n  negative X and Y coordinates.\n  Note that copying is fastest for images in the same data format\n  (and slowest for images in special formats).}\nfunction CopyRect(const SrcImage: TImageData; SrcX, SrcY, Width, Height: LongInt;\n  var DstImage: TImageData; DstX, DstY: LongInt): Boolean;\n{ Fills given rectangle of image with given pixel fill data. Fill should point\n  to the pixel in the same format as the given image is in.}\nfunction FillRect(var Image: TImageData; X, Y, Width, Height: LongInt; FillColor: Pointer): Boolean;\n{ Replaces pixels with OldPixel in the given rectangle by NewPixel.\n  OldPixel and NewPixel should point to the pixels in the same format\n  as the given image is in.}\nfunction ReplaceColor(var Image: TImageData; X, Y, Width, Height: LongInt;\n  OldColor, NewColor: Pointer): Boolean;\n{ Stretches the contents of the source rectangle to the destination rectangle\n  with optional resampling. No blending is performed - alpha is\n  simply copied/resampled to destination image. Note that stretching is\n  fastest for images in the same data format (and slowest for\n  images in special formats).}\nfunction StretchRect(const SrcImage: TImageData; SrcX, SrcY, SrcWidth,\n  SrcHeight: LongInt; var DstImage: TImageData; DstX, DstY, DstWidth,\n  DstHeight: LongInt; Filter: TResizeFilter): Boolean;\n{ Copies pixel of Image at [X, Y] to memory pointed at by Pixel. Doesn't\n  work with special formats.}\nprocedure GetPixelDirect(const Image: TImageData; X, Y: LongInt; Pixel: Pointer);\n{ Copies pixel from memory pointed at by Pixel to Image at position [X, Y].\n  Doesn't work with special formats.}\nprocedure SetPixelDirect(const Image: TImageData; X, Y: LongInt; Pixel: Pointer);\n{ Function for getting pixel colors. Native pixel is read from Image and\n  then translated to 32 bit ARGB. Works for all image formats (except special)\n  so it is not very fast.}\nfunction GetPixel32(const Image: TImageData; X, Y: LongInt): TColor32Rec;\n{ Procedure for setting pixel colors. Input 32 bit ARGB color is translated to\n  native format and then written to Image. Works for all image formats (except special)\n  so it is not very fast.}\nprocedure SetPixel32(const Image: TImageData; X, Y: LongInt; const Color: TColor32Rec);\n{ Function for getting pixel colors. Native pixel is read from Image and\n  then translated to FP ARGB. Works for all image formats (except special)\n  so it is not very fast.}\nfunction GetPixelFP(const Image: TImageData; X, Y: LongInt): TColorFPRec;\n{ Procedure for setting pixel colors. Input FP ARGB color is translated to\n  native format and then written to Image. Works for all image formats (except special)\n  so it is not very fast.}\nprocedure SetPixelFP(const Image: TImageData; X, Y: LongInt; const Color: TColorFPRec); \n\n{ Palette Functions }\n\n{ Allocates new palette with Entries ARGB color entries.}\nprocedure NewPalette(Entries: LongInt; var Pal: PPalette32);\n{ Frees given palette.}\nprocedure FreePalette(var Pal: PPalette32);\n{ Copies Count palette entries from SrcPal starting at index SrcIdx to\n  DstPal at index DstPal.}\nprocedure CopyPalette(SrcPal, DstPal: PPalette32; SrcIdx, DstIdx, Count: LongInt);\n{ Returns index of color in palette or index of nearest color if exact match\n  is not found. Pal must have at least Entries color entries.}\nfunction FindColor(Pal: PPalette32; Entries: LongInt; Color: TColor32): LongInt;\n{ Creates grayscale palette where each color channel has the same value.\n  Pal must have at least Entries color entries.}\nprocedure FillGrayscalePalette(Pal: PPalette32; Entries: LongInt);\n{ Creates palette with given bitcount for each channel.\n  2^(RBits + GBits + BBits) should be equl to Entries. Examples:\n  (3, 3, 2) will create palette with all possible colors of R3G3B2 format\n  and (8, 0, 0) will create palette with 256 shades of red.\n  Pal must be allocated to at least Entries * SizeOf(TColor32Rec) bytes.}\nprocedure FillCustomPalette(Pal: PPalette32; Entries: LongInt; RBits, GBits,\n  BBits: Byte; Alpha: Byte = $FF);\n{ Swaps SrcChannel and DstChannel color or alpha channels of palette.\n  Use ChannelRed, ChannelBlue, ChannelGreen, ChannelAlpha constants to\n  identify channels. Pal must be allocated to at least\n  Entries * SizeOf(TColor32Rec) bytes.}\nprocedure SwapChannelsOfPalette(Pal: PPalette32; Entries, SrcChannel,\n  DstChannel: LongInt);\n\n{ Options Functions }\n\n{ Sets value of integer option specified by OptionId parameter.\n  Option Ids are constans starting ImagingXXX.}\nfunction SetOption(OptionId, Value: LongInt): Boolean;\n{ Returns value of integer option specified by OptionId parameter. If OptionId is\n  invalid, InvalidOption is returned. Option Ids are constans\n  starting ImagingXXX.}\nfunction GetOption(OptionId: LongInt): LongInt;\n{ Pushes current values of all options on the stack. Returns True\n  if successfull (max stack depth is 8 now). }\nfunction PushOptions: Boolean;\n{ Pops back values of all options from the top of the stack. Returns True\n  if successfull (max stack depth is 8 now). }\nfunction PopOptions: Boolean;\n\n{ Image Format Functions }\n\n{ Returns short information about given image format.}\nfunction GetImageFormatInfo(Format: TImageFormat; out Info: TImageFormatInfo): Boolean;\n{ Returns size in bytes of Width x Height area of pixels. Works for all formats.}\nfunction GetPixelsSize(Format: TImageFormat; Width, Height: LongInt): LongInt;\n\n{ IO Functions }\n\n{ User can set his own file IO functions used when loading from/saving to\n  files by this function.}\nprocedure SetUserFileIO(OpenProc: TOpenProc; CloseProc: TCloseProc; EofProc: TEofProc; SeekProc:\n  TSeekProc; TellProc: TTellProc; ReadProc: TReadProc; WriteProc: TWriteProc);\n{ Sets file IO functions to Imaging default.}\nprocedure ResetFileIO;\n\n{ Raw Image IO Functions }\n\nprocedure ReadRawImageFromFile(const FileName: string; Width, Height: Integer;\n  Format: TImageFormat; var Image: TImageData; Offset: Integer = 0; RowLength: Integer = 0);\nprocedure ReadRawImageFromStream(Stream: TStream; Width, Height: Integer;\n  Format: TImageFormat; var Image: TImageData; Offset: Integer = 0; RowLength: Integer = 0);\nprocedure ReadRawImageFromMemory(Data: Pointer; DataSize: Integer; Width, Height: Integer;\n  Format: TImageFormat; var Image: TImageData; Offset: Integer = 0; RowLength: Integer = 0);\nprocedure ReadRawImageRect(Data: Pointer; Left, Top, Width, Height: Integer;\n  var Image: TImageData; Offset: Integer = 0; RowLength: Integer = 0);\n\nprocedure WriteRawImageToFile(const FileName: string; const Image: TImageData;\n  Offset: Integer = 0; RowLength: Integer = 0);\nprocedure WriteRawImageToStream(Stream: TStream; const Image: TImageData;\n  Offset: Integer = 0; RowLength: Integer = 0);\nprocedure WriteRawImageToMemory(Data: Pointer; DataSize: Integer; const Image: TImageData;\n  Offset: Integer = 0; RowLength: Integer = 0);\nprocedure WriteRawImageRect(Data: Pointer; Left, Top, Width, Height: Integer;\n  const Image: TImageData; Offset: Integer = 0; RowLength: Integer = 0);\n\n{ Convenience/helper Functions }\n\nprocedure ResizeImageToFit(const SrcImage: TImageData; FitWidth, FitHeight: Integer;\n  Filter: TResizeFilter; var DestImage: TImageData);\n\n\n{ ------------------------------------------------------------------------\n                           Other Imaging Stuff\n  ------------------------------------------------------------------------}\n\ntype\n  { Set of TImageFormat enum.}\n  TImageFormats = set of TImageFormat;\n\n  { Record containg set of IO functions internaly used by image loaders/savers.}\n  TIOFunctions = record\n    Open: TOpenProc;\n    Close: TCloseProc;\n    Eof: TEofProc;\n    Seek: TSeekProc;\n    Tell: TTellProc;\n    Read: TReadProc;\n    Write: TWriteProc;\n  end;\n  PIOFunctions = ^TIOFunctions;\n\ntype\n  TFileFormatFeature = (\n    ffLoad,\n    ffSave,\n    ffMultiImage,\n    ffReadOnSave,\n    ffProgress,\n    ffReadScanlines);\n\n  TFileFormatFeatures = set of TFileFormatFeature;\n\n  TMetadata = class;\n\n  { Base class for various image file format loaders/savers which\n    descend from this class. If you want to add support for new image file\n    format the best way is probably to look at TImageFileFormat descendants'\n    implementations that are already part of Imaging.}\n{$TYPEINFO ON}\n  TImageFileFormat = class\n  private\n    FExtensions: TStringList;\n    FMasks: TStringList;\n    function GetCanLoad: Boolean;\n    function GetCanSave: Boolean;\n    function GetIsMultiImageFormat: Boolean;\n    { Does various checks and actions before LoadData method is called.}\n    function PrepareLoad(Handle: TImagingHandle; var Images: TDynImageDataArray;\n      OnlyFirstFrame: Boolean): Boolean;\n    { Processes some actions according to result of LoadData.}\n    function PostLoadCheck(var Images: TDynImageDataArray; LoadResult: Boolean): Boolean;\n    { Helper function to be called in SaveData methods of descendants (ensures proper\n      index and sets FFirstIdx and FLastIdx for multi-images).}\n    function PrepareSave(Handle: TImagingHandle; const Images: TDynImageDataArray;\n      var Index: LongInt): Boolean;\n    { Returns file open mode used for saving images. Depends on defined Features.}\n    function GetSaveOpenMode: TOpenMode;\n  protected\n    FName: string;\n    FFeatures: TFileFormatFeatures;\n    FSupportedFormats: TImageFormats;\n    FFirstIdx, FLastIdx: LongInt;\n    FMetadata: TMetadata;\n    { Descendants must override this method and define file format name and\n      capabilities.}\n    procedure Define; virtual;\n    { Defines filename masks for this image file format. AMasks should be\n      in format '*.ext1,*.ext2,umajo.*'.}\n    procedure AddMasks(const AMasks: string);\n    function GetFormatInfo(Format: TImageFormat): TImageFormatInfo;\n    { Returns set of TImageData formats that can be saved in this file format\n      without need for conversion.}\n    function GetSupportedFormats: TImageFormats; virtual;\n    { Method which must be overrided in descendants if they' are be capable\n      of loading images. Images are already freed and length is set to zero\n      whenever this method gets called. Also Handle is assured to be valid\n      and contains data that passed TestFormat method's check.}\n    function LoadData(Handle: TImagingHandle; var Images: TDynImageDataArray;\n      OnlyFirstFrame: Boolean): Boolean; virtual;\n    { Method which must be overriden in descendants if they are be capable\n      of saving images. Images are checked to have length >0 and\n      that they contain valid images. For single-image file formats\n      Index contain valid index to Images array (to image which should be saved).\n      Multi-image formats should use FFirstIdx and FLastIdx fields to\n      to get all images that are to be saved.}\n    function SaveData(Handle: TImagingHandle; const Images: TDynImageDataArray;\n      Index: LongInt): Boolean; virtual;\n    { This method is called internaly by MakeCompatible when input image\n      is in format not supported by this file format. Image is clone of\n      MakeCompatible's input and Info is its extended format info.}\n    procedure ConvertToSupported(var Image: TImageData;\n      const Info: TImageFormatInfo); virtual;\n    { Returns True if given image is supported for saving by this file format.\n      Most file formats don't need to override this method. It checks\n      (in this base class) if Image's format is in SupportedFromats set.\n      But you may override it if you want further checks\n      (proper widht and height for example).}\n    function IsSupported(const Image: TImageData): Boolean; virtual;\n  public\n    constructor Create(AMetadata: TMetadata = nil); virtual;\n    destructor Destroy; override;\n\n    { Loads images from file source.}\n    function LoadFromFile(const FileName: string; var Images: TDynImageDataArray;\n      OnlyFirstLevel: Boolean = False): Boolean;\n    { Loads images from stream source.}\n    function LoadFromStream(Stream: TStream; var Images: TDynImageDataArray;\n      OnlyFirstLevel: Boolean = False): Boolean;\n    { Loads images from memory source.}\n    function LoadFromMemory(Data: Pointer; Size: LongInt;\n      var Images: TDynImageDataArray; OnlyFirstLevel: Boolean = False): Boolean;\n\n    { Saves images to file. If format supports only single level images and\n      there are multiple images to be saved, they are saved as sequence of\n      independent images (for example SaveToFile saves sequence of\n      files img000.jpg, img001.jpg ....).}\n    function SaveToFile(const FileName: string; const Images: TDynImageDataArray;\n      OnlyFirstLevel: Boolean = False): Boolean;\n    { Saves images to stream. If format supports only single level images and\n      there are multiple images to be saved, they are saved as sequence of\n      independent images.}\n    function SaveToStream(Stream: TStream; const Images: TDynImageDataArray;\n      OnlyFirstLevel: Boolean = False): Boolean;\n    { Saves images to memory. If format supports only single level images and\n      there are multiple images to be saved, they are saved as sequence of\n      independent images. Data must be already allocated and their size passed\n      as Size parameter, number of written bytes is then returned in the same\n      parameter.}\n    function SaveToMemory(Data: Pointer; var Size: LongInt;\n      const Images: TDynImageDataArray; OnlyFirstLevel: Boolean = False): Boolean;\n\n    { Makes Image compatible with this file format (that means it is in one\n      of data formats in Supported formats set). If input is already\n      in supported format then Compatible just use value from input\n      (Compatible := Image) so must not free it after you are done with it\n      (image bits pointer points to input image's bits).\n      If input is not in supported format then it is cloned to Compatible\n      and concerted to one of supported formats (which one dependeds on\n      this file format). If image is cloned MustBeFreed is set to True\n      to indicated that you must free Compatible after you are done with it.}\n    function MakeCompatible(const Image: TImageData; var Compatible: TImageData;\n      out MustBeFreed: Boolean): Boolean;\n    { Returns True if data located in source identified by Handle\n      represent valid image in current format.}\n    function TestFormat(Handle: TImagingHandle): Boolean; virtual;\n    { Resturns True if the given FileName matches filter for this file format.\n      For most formats it just checks filename extensions.\n      It uses filename masks in from Masks property so it can recognize\n      filenames like this 'umajoXXXumajo.j0j' if one of themasks is\n      'umajo*umajo.j?j'.}\n    function TestFileName(const FileName: string): Boolean;\n    { Descendants use this method to check if their options (registered with\n      constant Ids for SetOption/GetOption interface or accessible as properties\n      of descendants) have valid values and make necessary changes.}\n    procedure CheckOptionsValidity; virtual;\n\n    { Description of this format.}\n    property Name: string read FName;\n    { Indicates whether images in this format can be loaded.}\n    property CanLoad: Boolean read GetCanLoad;\n    { Indicates whether images in this format can be saved.}\n    property CanSave: Boolean read GetCanSave;\n    { Indicates whether images in this format can contain multiple image levels.}\n    property IsMultiImageFormat: Boolean read GetIsMultiImageFormat;\n    { List of filename extensions for this format.}\n    property Extensions: TStringList read FExtensions;\n    { List of filename masks that are used to associate filenames\n      with TImageFileFormat descendants. Typical mask looks like\n      '*.bmp' or 'texture.*' (supports file formats which use filename instead\n      of extension to identify image files).}\n    property Masks: TStringList read FMasks;\n    { Set of TImageFormats supported by saving functions of this format. Images\n      can be saved only in one those formats.}\n    property SupportedFormats: TImageFormats read GetSupportedFormats;\n  end;\n{$TYPEINFO OFF}\n\n  { Class reference for TImageFileFormat class}\n  TImageFileFormatClass = class of TImageFileFormat;\n\n  { Physical resolution unit.}\n  TResolutionUnit = (\n    ruSizeInMicroMeters, // value is pixel size in micrometers\n    ruDpi,               // value is pixels/dots per inch\n    ruDpm,               // value is pixels/dots per meter\n    ruDpcm               // value is pixels/dots per centimeter\n  );\n\n  { Class for storage of single metadata item.}\n  TMetadataItem = class\n  public\n    Id: string;\n    ImageIndex: Integer;\n    Value: Variant;\n  end;\n\n  { Metadata manager class.}\n  TMetadata = class\n  private\n    FLoadMetaItems: TStringList;\n    FSaveMetaItems: TStringList;\n    procedure AddMetaToList(List: TStringList; const Id: string; const Value: Variant; ImageIndex: Integer);\n    procedure ClearMetaList(List: TStringList);\n    function GetMetaById(const Id: string): Variant;\n    function GetMetaByIdMulti(const Id: string; ImageIndex: Integer): Variant;\n    function GetMetaCount: Integer;\n    function GetMetaByIdx(Index: Integer): TMetadataItem;\n    function GetSaveMetaById(const Id: string): Variant;\n    function GetSaveMetaByIdMulti(const Id: string; ImageIndex: Integer): Variant;\n    procedure TranslateUnits(ResolutionUnit: TResolutionUnit; var XRes, YRes: Single);\n  public\n    constructor Create;\n    destructor Destroy; override;\n\n    procedure SetMetaItem(const Id: string; const Value: Variant; ImageIndex: Integer = 0);\n    procedure SetMetaItemForSaving(const Id: string; const Value: Variant; ImageIndex: Integer = 0);\n    function HasMetaItem(const Id: string; ImageIndex: Integer = 0): Boolean;\n    function HasMetaItemForSaving(const Id: string; ImageIndex: Integer = 0): Boolean;\n\n    procedure ClearMetaItems;\n    procedure ClearMetaItemsForSaving;\n    function GetMetaItemName(const Id: string; ImageIndex: Integer): string;\n    { Copies loaded meta items to items-for-save stack. Use this when you want to\n      save metadata that have been just loaded (e.g. resaving image in\n      different file format but keeping the metadata).}\n    procedure CopyLoadedMetaItemsForSaving;\n\n    function GetPhysicalPixelSize(ResUnit: TResolutionUnit; var XSize,\n      YSize: Single; MetaForSave: Boolean = False; ImageIndex: Integer = 0): Boolean;\n    procedure SetPhysicalPixelSize(ResUnit: TResolutionUnit; XSize, YSize: Single;\n      MetaForSave: Boolean = False; ImageIndex: Integer = 0);\n\n    property MetaItems[const Id: string]: Variant read GetMetaById;\n    property MetaItemsMulti[const Id: string; ImageIndex: Integer]: Variant read GetMetaByIdMulti;\n    { Number of loaded metadata items.}\n    property MetaItemCount: Integer read GetMetaCount;\n    property MetaItemsByIdx[Index: Integer]: TMetadataItem read GetMetaByIdx;\n    property MetaItemsForSaving[const Id: string]: Variant read GetSaveMetaById;\n    property MetaItemsForSavingMulti[const Id: string; ImageIndex: Integer]: Variant read GetSaveMetaByIdMulti;\n  end;\n\nconst\n  { Metadata item id constants }\n\n  { Physical size of one pixel in micrometers. Type of value is Float.}\n  SMetaPhysicalPixelSizeX = 'PhysicalPixelSizeX';\n  SMetaPhysicalPixelSizeY = 'PhysicalPixelSizeY';\n  { Delay for frame of animation (how long it should stay visible) in milliseconds.\n    Type of value is Integer.}\n  SMetaFrameDelay = 'FrameDelay';\n  { Number of times animation should be looped (0 = infinite looping). Type is Int. }\n  SMetaAnimationLoops = 'AnimationLoops';\n  { Gamma correction value. Type is Float.}\n  SMetaGamma = 'Gamma';\n  { Exposure value for HDR etc. Type is Float.}\n  SMetaExposure = 'Exposure';\n  { EXIF image metadata raw blob.}\n  SMetaExifBlob = 'ExifBlob';\n  { XMP image metadata raw blob.}\n  SMetaXmpBlob  = 'XmpBlob';\n  { IPTC image metadata raw blob.}\n  SMetaIptcBlob = 'IptcBlob';\n\nvar\n  GlobalMetadata: TMetadata;\n\n{ Returns symbolic name of given format.}\nfunction GetFormatName(Format: TImageFormat): string;\n{ Returns string with information about given Image.}\nfunction ImageToStr(const Image: TImageData): string;\n{ Returns Imaging version string in format 'Major.Minor.Patch'.}\nfunction GetVersionStr: string;\n{ If Condition is True then TruePart is retured, otherwise FalsePart is returned.}\nfunction IffFormat(Condition: Boolean; const TruePart, FalsePart: TImageFormat): TImageFormat;\n\n{ Registers new option so it can be used by SetOption and GetOption functions.\n  Returns True if registration was succesful - that is Id is valid and is\n  not already taken by another option.}\nfunction RegisterOption(OptionId: LongInt; Variable: PLongInt): Boolean;\n\n{ Registers new image loader/saver so it can be used by LoadFrom/SaveTo\n  functions.}\nprocedure RegisterImageFileFormat(AClass: TImageFileFormatClass);\n{ Returns image format loader/saver according to given extension\n  or nil if not found.}\nfunction FindImageFileFormatByExt(const Ext: string): TImageFileFormat;\n{ Returns image format loader/saver according to given filename\n  or nil if not found.}\nfunction FindImageFileFormatByName(const FileName: string): TImageFileFormat;\n{ Returns image format loader/saver based on its class\n  or nil if not found or not registered.}\nfunction FindImageFileFormatByClass(AClass: TImageFileFormatClass): TImageFileFormat;\n{ Returns number of registered image file format loaders/saver.}\nfunction GetFileFormatCount: LongInt;\n{ Returns image file format loader/saver at given index. Index must be\n  in range [0..GetFileFormatCount - 1] otherwise nil is returned.}\nfunction GetFileFormatAtIndex(Index: LongInt): TImageFileFormat;\n{ Returns filter string for usage with open and save picture dialogs\n  which contains all registered image file formats.\n  Set OpenFileFilter to True if you want filter for open dialog\n  and to False if you want save dialog filter (formats that cannot save to files\n  are not added then).\n  For open dialog filter for all known graphic files\n  (like All(*.jpg;*.png;....) is added too at the first index.}\nfunction GetImageFileFormatsFilter(OpenFileFilter: Boolean): string;\n{ Returns file extension (without dot) of image format selected\n  by given filter index. Used filter string is defined by GetImageFileFormatsFilter\n  function. This function can be used with save dialogs (with filters created\n  by GetImageFileFormatsFilter) to get the extension of file format selected\n  in dialog quickly. Index is in range 1..N (as FilterIndex property\n  of TOpenDialog/TSaveDialog)}\nfunction GetFilterIndexExtension(Index: LongInt; OpenFileFilter: Boolean): string;\n{ Returns filter index of image file format of file specified by FileName. Used filter\n  string is defined by GetImageFileFormatsFilter function.\n  Returned index is in range 1..N (as FilterIndex property of TOpenDialog/TSaveDialog)}\nfunction GetFileNameFilterIndex(const FileName: string; OpenFileFilter: Boolean): LongInt;\n\n{ Returns current IO functions.}\nfunction GetIO: TIOFunctions;\n{ Raises EImagingError with given message.}\nprocedure RaiseImaging(const Msg: string; const Args: array of const); overload;\nprocedure RaiseImaging(const Msg: string); overload; {$IFDEF USE_INLINE}inline;{$ENDIF}\n\nconst\n  SImagingLibTitle = 'Vampyre Imaging Library';\n\nimplementation\n\nuses\n{$IFNDEF DONT_LINK_BITMAP}\n  ImagingBitmap,\n{$ENDIF}\n{$IFNDEF DONT_LINK_JPEG}\n  ImagingJpeg,\n{$ENDIF}\n{$IF not Defined(DONT_LINK_PNG) or not Defined(DONT_LINK_MNG) or not Defined(DONT_LINK_JNG)}\n  ImagingNetworkGraphics,\n{$IFEND}\n{$IFNDEF DONT_LINK_GIF}\n  ImagingGif,\n{$ENDIF}\n{$IFNDEF DONT_LINK_DDS}\n  ImagingDds,\n{$ENDIF}\n{$IFNDEF DONT_LINK_TARGA}\n  ImagingTarga,\n{$ENDIF}\n{$IFNDEF DONT_LINK_PNM}\n  ImagingPortableMaps,\n{$ENDIF}\n{$IFNDEF DONT_LINK_RADHDR}\n  ImagingRadiance,\n{$ENDIF}\n{$IFNDEF DONT_LINK_EXTRAS}\n  ImagingExtras,\n{$ENDIF}\n  //ImagingDebug,\n  ImagingFormats, ImagingUtility, ImagingIO, Variants;\n\nresourcestring\n  SExceptMsg = 'Exception Message';\n  SAllFilter = 'All Images';\n  SUnknownFormat = 'Unknown and unsupported format';\n\n  SErrorFreeImage = 'Error while freeing image. %s';\n  SErrorCloneImage = 'Error while cloning image. %s';\n  SErrorFlipImage = 'Error while flipping image. %s';\n  SErrorMirrorImage = 'Error while mirroring image. %s';\n  SErrorResizeImage = 'Error while resizing image.  %s';\n  SErrorSwapImage = 'Error while swapping channels of image. %s';\n  SFileFormatCanNotLoad = 'Image Format \"%s\" does not support loading images.';\n  SFileFormatCanNotSave = 'Image Format \"%s\" does not support saving images.';\n  SErrorNewImage = 'Error while creating image data with params: Width=%d ' +\n    'Height=%d Format=%s.';\n  SErrorConvertImage = 'Error while converting image to format \"%s\". %s';\n  SImageInfo = 'Image @%p info: Width = %dpx, Height = %dpx, ' +\n    'Format = %s, Size = %.0n %s, Bits @%p, Palette @%p.';\n  SImageInfoInvalid = 'Access violation encountered when getting info on ' +\n    'image at address %p.';\n  SFileNotValid = 'File \"%s\" is not valid image in \"%s\" format.';\n  SStreamNotValid = 'Stream %p does not contain valid image in \"%s\" format.';\n  SMemoryNotValid = 'Memory %p (%d Bytes) does not contain valid image ' +\n    'in \"%s\" format.';\n  SErrorLoadingFile = 'Error while loading images from file \"%s\" (file format: %s).';\n  SErrorLoadingStream = 'Error while loading images from stream %p (file format: %s).';\n  SErrorLoadingMemory = 'Error while loading images from memory %p (%d Bytes) (file format: %s).';\n  SErrorSavingFile = 'Error while saving images to file \"%s\" (file format: %s).';\n  SErrorSavingStream = 'Error while saving images to stream %p (file format: %s).';\n  SErrorSavingMemory = 'Error while saving images to memory %p (%d Bytes) (file format: %s).';\n  SErrorFindColor = 'Error while finding color in palette @%p with %d entries.';\n  SErrorGrayscalePalette = 'Error while filling grayscale palette @%p with %d entries.';\n  SErrorCustomPalette = 'Error while filling custom palette @%p with %d entries.';\n  SErrorSwapPalette = 'Error while swapping channels of palette @%p with %d entries.';\n  SErrorReduceColors = 'Error while reducing number of colors of image to %d. %s';\n  SErrorGenerateMipMaps = 'Error while generating %d mipmap levels for image %s';\n  SImagesNotValid = 'One or more images are not valid.';\n  SErrorCopyRect = 'Error while copying rect from image %s to image %s.';\n  SErrorMapImage = 'Error while mapping image %s to palette.';\n  SErrorFillRect = 'Error while filling rectangle X:%d Y:%d W:%d H:%d in image %s';\n  SErrorSplitImage = 'Error while splitting image %s to %dx%d sized chunks.';\n  SErrorMakePaletteForImages = 'Error while making %d color palette for %d images.';\n  SErrorNewPalette = 'Error while creating new palette with %d entries';\n  SErrorFreePalette = 'Error while freeing palette @%p';\n  SErrorCopyPalette = 'Error while copying %d entries from palette @%p to @%p';\n  SErrorReplaceColor = 'Error while replacing colors in rectangle X:%d Y:%d W:%d H:%d of image %s';\n  SErrorRotateImage = 'Error while rotating image %s by %.2n degrees';\n  SErrorStretchRect = 'Error while stretching rect from image %s to image %s.';\n  SErrorEmptyStream = 'Input stream has no data. Check Position property.';\n  SErrorInvalidInputImage = 'Invalid input image.';\n\n  SErrorBadImage = 'Bad image detected.';\n\nconst\n  // Initial size of array with options information\n  InitialOptions = 256;\n  // Max depth of the option stack\n  OptionStackDepth = 8;\n  // Do not change the default format now, its too late\n  DefaultImageFormat: TImageFormat = ifA8R8G8B8;\n  // Format used to create metadata IDs for frames loaded form multiimages.\n  SMetaIdForSubImage = '%s/%d';\n\ntype\n  TOptionArray = array of PLongInt;\n  TOptionValueArray = array of LongInt;\n\n  TOptionStack = class(TObject)\n  private\n    FStack: array[0..OptionStackDepth - 1] of TOptionValueArray;\n    FPosition: LongInt;\n  public\n    constructor Create;\n    destructor Destroy; override;\n    function Push: Boolean;\n    function Pop: Boolean;\n  end;\n\nvar\n  // Currently set IO functions\n  IO: TIOFunctions;\n  // List with all registered TImageFileFormat classes\n  ImageFileFormats: TList = nil;\n  // Aarray with registered options (pointers to their values)\n  Options: TOptionArray = nil;\n  // Array containing addional infomation about every image format\n  ImageFormatInfos: TImageFormatInfoArray;\n  // Stack used by PushOptions/PopOtions functions\n  OptionStack: TOptionStack = nil;\nvar\n  // Variable for ImagingColorReduction option\n  ColorReductionMask: LongInt = $FF;\n  // Variable for ImagingLoadOverrideFormat option\n  LoadOverrideFormat: TImageFormat = ifUnknown;\n  // Variable for ImagingSaveOverrideFormat option\n  SaveOverrideFormat: TImageFormat = ifUnknown;\n  // Variable for ImagingSaveOverrideFormat option\n  MipMapFilter: TSamplingFilter = sfLinear;\n  // Variable for ImagingBinaryTreshold option\n  BinaryTreshold: Integer = 128;\n\n{ Exceptions }\n\nconstructor EImagingBadImage.Create;\nbegin\n  inherited Create(SErrorBadImage);\nend;\n\n{ Internal unit functions }\n\n{ Modifies option value to be in the allowed range. Works only\n  for options registered in this unit.}\nfunction CheckOptionValue(OptionId, Value: LongInt): LongInt; forward;\n{ Sets IO functions to file IO.}\nprocedure SetFileIO; forward;\n{ Sets IO functions to stream IO.}\nprocedure SetStreamIO; forward;\n{ Sets IO functions to memory IO.}\nprocedure SetMemoryIO; forward;\n{ Inits image format infos array.}\nprocedure InitImageFormats; forward;\n{ Freew image format infos array.}\nprocedure FreeImageFileFormats; forward;\n{ Creates options array and stack.}\nprocedure InitOptions; forward;\n{ Frees options array and stack.}\nprocedure FreeOptions; forward;\n\nfunction UpdateExceptMessage(E: Exception; const MsgToPrepend: string; const Args: array of const): Exception;\nbegin\n  Result := E;\n  E.Message := Format(MsgToPrepend, Args) +  ' ' + SExceptMsg + ': ' + E.Message\nend;\n\n{ ------------------------------------------------------------------------\n                       Low Level Interface Functions\n  ------------------------------------------------------------------------}\n\n{ General Functions }\n\nprocedure InitImage(var Image: TImageData);\nbegin\n  FillChar(Image, SizeOf(Image), 0);\nend;\n\nfunction NewImage(Width, Height: LongInt; Format: TImageFormat; var Image:\n  TImageData): Boolean;\nvar\n  FInfo: PImageFormatInfo;\nbegin\n  Assert((Width > 0) and (Height >0));\n  Assert(IsImageFormatValid(Format));\n  Result := False;\n  FreeImage(Image);\n  try\n    Image.Width := Width;\n    Image.Height := Height;\n    // Select default data format if selected\n    if (Format = ifDefault)  then\n      Image.Format := DefaultImageFormat\n    else\n      Image.Format := Format;\n    // Get extended format info\n    FInfo := ImageFormatInfos[Image.Format];\n    if FInfo = nil then\n    begin\n      InitImage(Image);\n      Exit;\n    end;\n    // Check image dimensions and calculate its size in bytes\n    FInfo.CheckDimensions(FInfo.Format, Image.Width, Image.Height);\n    Image.Size := FInfo.GetPixelsSize(FInfo.Format, Image.Width, Image.Height);\n    if Image.Size = 0 then\n    begin\n      InitImage(Image);\n      Exit;\n    end;\n    // Image bits are allocated and set to zeroes\n    GetMem(Image.Bits, Image.Size);\n    FillChar(Image.Bits^, Image.Size, 0);\n    // Palette is allocated and set to zeroes\n    if FInfo.PaletteEntries > 0 then\n    begin\n      GetMem(Image.Palette, FInfo.PaletteEntries * SizeOf(TColor32Rec));\n      FillChar(Image.Palette^, FInfo.PaletteEntries * SizeOf(TColor32Rec), 0);\n    end;\n    Result := TestImage(Image);\n  except\n    on E: Exception do\n    begin\n      FreeMem(Image.Bits);\n      FreeMem(Image.Palette);\n      InitImage(Image);\n      raise UpdateExceptMessage(E, SErrorNewImage, [Width, Height, GetFormatName(Format)]);\n    end;\n  end;\nend;\n\nfunction TestImage(const Image: TImageData): Boolean;\nbegin\n  try\n    Result := (LongInt(Image.Format) >= LongInt(Low(TImageFormat))) and\n      (LongInt(Image.Format) <= LongInt(High(TImageFormat))) and\n      (ImageFormatInfos[Image.Format] <> nil) and\n      (Assigned(ImageFormatInfos[Image.Format].GetPixelsSize) and\n      (ImageFormatInfos[Image.Format].GetPixelsSize(Image.Format,\n      Image.Width, Image.Height) = Image.Size));\n  except\n    // Possible int overflows or other errors\n    Result := False;\n  end;\nend;\n\nprocedure FreeImage(var Image: TImageData);\nbegin\n  try\n    if TestImage(Image) then\n    begin\n      FreeMemNil(Image.Bits);\n      FreeMemNil(Image.Palette);\n    end;\n    InitImage(Image);\n  except\n    raise UpdateExceptMessage(GetExceptObject, SErrorFreeImage, [ImageToStr(Image)]);\n  end;\nend;\n\nprocedure FreeImagesInArray(var Images: TDynImageDataArray);\nvar\n  I: LongInt;\nbegin\n  if Length(Images) > 0 then\n  begin\n    for I := 0 to Length(Images) - 1 do\n      FreeImage(Images[I]);\n    SetLength(Images, 0);\n  end;\nend;\n\nfunction TestImagesInArray(const Images: TDynImageDataArray): Boolean;\nvar\n  I: LongInt;\nbegin\n  if Length(Images) > 0 then\n  begin\n    Result := True;\n    for I := 0 to Length(Images) - 1 do\n    begin\n      Result := Result and TestImage(Images[I]);\n      if not Result then\n        Break;\n    end;\n  end\n  else\n    Result := False;\nend;\n\nfunction DetermineFileFormat(const FileName: string): string;\nvar\n  I: LongInt;\n  Fmt: TImageFileFormat;\n  Handle: TImagingHandle;\nbegin\n  Assert(FileName <> '');\n  Result := '';\n  SetFileIO;\n  Handle := IO.Open(PChar(FileName), omReadOnly);\n  try\n    // First file format according to FileName and test if the data in\n    // file is really in that format\n    for I := 0 to ImageFileFormats.Count - 1 do\n    begin\n      Fmt := TImageFileFormat(ImageFileFormats[I]);\n      if Fmt.TestFileName(FileName) and Fmt.TestFormat(Handle) then\n      begin\n        Result := Fmt.Extensions[0];\n        Exit;\n      end;\n    end;\n    // No file format was found with filename search so try data-based search\n    for I := 0 to ImageFileFormats.Count - 1 do\n    begin\n      Fmt := TImageFileFormat(ImageFileFormats[I]);\n      if Fmt.TestFormat(Handle) then\n      begin\n        Result := Fmt.Extensions[0];\n        Exit;\n      end;\n    end;\n  finally\n    IO.Close(Handle);\n  end;\nend;\n\nfunction DetermineStreamFormat(Stream: TStream): string;\nvar\n  I: LongInt;\n  Fmt: TImageFileFormat;\n  Handle: TImagingHandle;\nbegin\n  Assert(Stream <> nil);\n  Result := '';\n  SetStreamIO;\n  Handle := IO.Open(Pointer(Stream), omReadOnly);\n  try\n    for I := 0 to ImageFileFormats.Count - 1 do\n    begin\n      Fmt := TImageFileFormat(ImageFileFormats[I]);\n      if Fmt.TestFormat(Handle) then\n      begin\n        Result := Fmt.Extensions[0];\n        Exit;\n      end;\n    end;\n  finally\n    IO.Close(Handle);\n  end;\nend;\n\nfunction DetermineMemoryFormat(Data: Pointer; Size: LongInt): string;\nvar\n  I: LongInt;\n  Fmt: TImageFileFormat;\n  Handle: TImagingHandle;\n  IORec: TMemoryIORec;\nbegin\n  Assert((Data <> nil) and (Size > 0));\n  Result := '';\n  SetMemoryIO;\n  IORec.Data := Data;\n  IORec.Position := 0;\n  IORec.Size := Size;\n  Handle := IO.Open(@IORec, omReadOnly);\n  try\n    for I := 0 to ImageFileFormats.Count - 1 do\n    begin\n      Fmt := TImageFileFormat(ImageFileFormats[I]);\n      if Fmt.TestFormat(Handle) then\n      begin\n        Result := Fmt.Extensions[0];\n        Exit;\n      end;\n    end;\n  finally\n    IO.Close(Handle);\n  end;\nend;\n\nfunction IsFileFormatSupported(const FileName: string): Boolean;\nbegin\n  Result := FindImageFileFormatByName(FileName) <> nil;\nend;\n\nfunction EnumFileFormats(var Index: LongInt; var Name, DefaultExt, Masks: string;\n  var CanSaveImages, IsMultiImageFormat: Boolean): Boolean;\nvar\n  FileFmt: TImageFileFormat;\nbegin\n  FileFmt := GetFileFormatAtIndex(Index);\n  Result := FileFmt <> nil;\n  if Result then\n  begin\n    Name := FileFmt.Name;\n    DefaultExt := FileFmt.Extensions[0];\n    Masks := FileFmt.Masks.DelimitedText; \n    CanSaveImages := FileFmt.CanSave;\n    IsMultiImageFormat := FileFmt.IsMultiImageFormat;\n    Inc(Index);\n  end\n  else\n  begin\n    Name := '';\n    DefaultExt := '';\n    Masks := '';\n    CanSaveImages := False;\n    IsMultiImageFormat := False;\n  end;\nend;\n\n{ Loading Functions }\n\nfunction LoadImageFromFile(const FileName: string; var Image: TImageData):\n  Boolean;\nvar\n  Format: TImageFileFormat;\n  IArray: TDynImageDataArray;\n  I: LongInt;\nbegin\n  Assert(FileName <> '');\n  Result := False;\n  Format := FindImageFileFormatByExt(DetermineFileFormat(FileName));\n  if Format <> nil then\n  begin\n    FreeImage(Image);\n    Result := Format.LoadFromFile(FileName, IArray, True);\n    if Result and (Length(IArray) > 0) then\n    begin\n      Image := IArray[0];\n      for I := 1 to Length(IArray) - 1 do\n        FreeImage(IArray[I]);\n    end\n    else\n      Result := False;\n  end;\nend;\n\nfunction LoadImageFromStream(Stream: TStream; var Image: TImageData): Boolean;\nvar\n  Format: TImageFileFormat;\n  IArray: TDynImageDataArray;\n  I: LongInt;\nbegin\n  Assert(Stream <> nil);\n  if Stream.Size - Stream.Position = 0 then\n    RaiseImaging(SErrorEmptyStream, []);\n  Result := False;\n  Format := FindImageFileFormatByExt(DetermineStreamFormat(Stream));\n  if Format <> nil then\n  begin\n    FreeImage(Image);\n    Result := Format.LoadFromStream(Stream, IArray, True);\n    if Result and (Length(IArray) > 0) then\n    begin\n      Image := IArray[0];\n      for I := 1 to Length(IArray) - 1 do\n        FreeImage(IArray[I]);\n    end\n    else\n      Result := False;\n  end;\nend;\n\nfunction LoadImageFromMemory(Data: Pointer; Size: LongInt; var Image: TImageData): Boolean;\nvar\n  Format: TImageFileFormat;\n  IArray: TDynImageDataArray;\n  I: LongInt;\nbegin\n  Assert((Data <> nil) and (Size > 0));\n  Result := False;\n  Format := FindImageFileFormatByExt(DetermineMemoryFormat(Data, Size));\n  if Format <> nil then\n  begin\n    FreeImage(Image);\n    Result := Format.LoadFromMemory(Data, Size, IArray, True);\n    if Result and (Length(IArray) > 0) then\n    begin\n      Image := IArray[0];\n      for I := 1 to Length(IArray) - 1 do\n        FreeImage(IArray[I]);\n    end\n    else\n      Result := False;\n  end;\nend;\n\nfunction LoadMultiImageFromFile(const FileName: string; var Images:\n  TDynImageDataArray): Boolean;\nvar\n  Format: TImageFileFormat;\nbegin\n  Assert(FileName <> '');\n  Result := False;\n  Format := FindImageFileFormatByExt(DetermineFileFormat(FileName));\n  if Format <> nil then\n  begin\n    FreeImagesInArray(Images);\n    Result := Format.LoadFromFile(FileName, Images);\n  end;\nend;\n\nfunction LoadMultiImageFromStream(Stream: TStream; var Images: TDynImageDataArray): Boolean;\nvar\n  Format: TImageFileFormat;\nbegin\n  Assert(Stream <> nil);\n  if Stream.Size - Stream.Position = 0 then\n    RaiseImaging(SErrorEmptyStream, []);\n  Result := False;\n  Format := FindImageFileFormatByExt(DetermineStreamFormat(Stream));\n  if Format <> nil then\n  begin\n    FreeImagesInArray(Images);\n    Result := Format.LoadFromStream(Stream, Images);\n  end;\nend;\n\nfunction LoadMultiImageFromMemory(Data: Pointer; Size: LongInt;\n  var Images: TDynImageDataArray): Boolean;\nvar\n  Format: TImageFileFormat;\nbegin\n  Assert((Data <> nil) and (Size > 0));\n  Result := False;\n  Format := FindImageFileFormatByExt(DetermineMemoryFormat(Data, Size));\n  if Format <> nil then\n  begin\n    FreeImagesInArray(Images);\n    Result := Format.LoadFromMemory(Data, Size, Images);\n  end;\nend;\n\n{ Saving Functions }\n\nfunction SaveImageToFile(const FileName: string; const Image: TImageData): Boolean;\nvar\n  Format: TImageFileFormat;\n  IArray: TDynImageDataArray;\nbegin\n  Assert(FileName <> '');\n  Result := False;\n  Format := FindImageFileFormatByName(FileName);\n  if Format <> nil then\n  begin\n    SetLength(IArray, 1);\n    IArray[0] := Image;\n    Result := Format.SaveToFile(FileName, IArray, True);\n  end;\nend;\n\nfunction SaveImageToStream(const Ext: string; Stream: TStream;\n  const Image: TImageData): Boolean;\nvar\n  Format: TImageFileFormat;\n  IArray: TDynImageDataArray;\nbegin\n  Assert((Ext <> '') and (Stream <> nil));\n  Result := False;\n  Format := FindImageFileFormatByExt(Ext);\n  if Format <> nil then\n  begin\n    SetLength(IArray, 1);\n    IArray[0] := Image;\n    Result := Format.SaveToStream(Stream, IArray, True);\n  end;\nend;\n\nfunction SaveImageToMemory(const Ext: string; Data: Pointer; var Size: LongInt;\n  const Image: TImageData): Boolean;\nvar\n  Format: TImageFileFormat;\n  IArray: TDynImageDataArray;\nbegin\n  Assert((Ext <> '') and (Data <> nil) and (Size > 0));\n  Result := False;\n  Format := FindImageFileFormatByExt(Ext);\n  if Format <> nil then\n  begin\n    SetLength(IArray, 1);\n    IArray[0] := Image;\n    Result := Format.SaveToMemory(Data, Size, IArray, True);\n  end;\nend;\n\nfunction SaveMultiImageToFile(const FileName: string;\n  const Images: TDynImageDataArray): Boolean;\nvar\n  Format: TImageFileFormat;\nbegin\n  Assert(FileName <> '');\n  Result := False;\n  Format := FindImageFileFormatByName(FileName);\n  if Format <> nil then\n    Result := Format.SaveToFile(FileName, Images);\nend;\n\nfunction SaveMultiImageToStream(const Ext: string; Stream: TStream;\n  const Images: TDynImageDataArray): Boolean;\nvar\n  Format: TImageFileFormat;\nbegin\n  Assert((Ext <> '') and (Stream <> nil));\n  Result := False;\n  Format := FindImageFileFormatByExt(Ext);\n  if Format <> nil then\n    Result := Format.SaveToStream(Stream, Images);\nend;\n\nfunction SaveMultiImageToMemory(const Ext: string; Data: Pointer;\n  var Size: LongInt; const Images: TDynImageDataArray): Boolean;\nvar\n  Format: TImageFileFormat;\nbegin\n  Assert((Ext <> '') and (Data <> nil) and (Size > 0));\n  Result := False;\n  Format := FindImageFileFormatByExt(Ext);\n  if Format <> nil then\n    Result := Format.SaveToMemory(Data, Size, Images);\nend;\n\n{ Manipulation Functions }\n\nfunction CloneImage(const Image: TImageData; var Clone: TImageData): Boolean;\nvar\n  Info: PImageFormatInfo;\nbegin\n  Result := False;\n  if TestImage(Image) then\n  try\n    if TestImage(Clone) and (Image.Bits <> Clone.Bits) then\n      FreeImage(Clone)\n    else\n      InitImage(Clone);\n\n    Info := ImageFormatInfos[Image.Format];\n    Clone.Width := Image.Width;\n    Clone.Height := Image.Height;\n    Clone.Format := Image.Format;\n    Clone.Size := Image.Size;\n\n    if Info.PaletteEntries > 0 then\n    begin\n      GetMem(Clone.Palette, Info.PaletteEntries * SizeOf(TColor32Rec));\n      Move(Image.Palette^, Clone.Palette^, Info.PaletteEntries *\n        SizeOf(TColor32Rec));\n    end;\n\n    GetMem(Clone.Bits, Clone.Size);\n    Move(Image.Bits^, Clone.Bits^, Clone.Size);\n    Result := True;\n  except\n    raise UpdateExceptMessage(GetExceptObject, SErrorCloneImage, [ImageToStr(Image)]);\n  end;\nend;\n\nfunction ConvertImage(var Image: TImageData; DestFormat: TImageFormat): Boolean;\nvar\n  NewData: Pointer;\n  NewPal: PPalette32;\n  NewSize, NumPixels: LongInt;\n  SrcInfo, DstInfo: PImageFormatInfo;\nbegin\n  Assert(IsImageFormatValid(DestFormat));\n  Result := False;\n  if TestImage(Image) then\n  with Image do\n  try\n    // If default format is set we use DefaultImageFormat\n    if DestFormat = ifDefault then\n      DestFormat := DefaultImageFormat;\n    SrcInfo := ImageFormatInfos[Format];\n    DstInfo := ImageFormatInfos[DestFormat];\n    if SrcInfo = DstInfo then\n    begin\n      // There is nothing to convert - src is alredy in dest format\n      Result := True;\n      Exit;\n    end;\n    // Exit Src or Dest format is invalid \n    if (SrcInfo = nil) or (DstInfo = nil) then Exit;\n    // If dest format is just src with swapped channels we call\n    // SwapChannels instead\n    if (SrcInfo.RBSwapFormat = DestFormat) and\n      (DstInfo.RBSwapFormat = SrcInfo.Format) then\n    begin\n      Result := SwapChannels(Image, ChannelRed, ChannelBlue);\n      Image.Format := SrcInfo.RBSwapFormat;\n      Exit;\n    end;\n\n    if (not SrcInfo.IsSpecial) and (not DstInfo.IsSpecial) then\n    begin\n      NumPixels := Width * Height;\n      NewSize := NumPixels * DstInfo.BytesPerPixel;\n      GetMem(NewData, NewSize);\n      FillChar(NewData^, NewSize, 0);\n      GetMem(NewPal, DstInfo.PaletteEntries * SizeOf(TColor32Rec));\n      FillChar(NewPal^, DstInfo.PaletteEntries * SizeOf(TColor32Rec), 0);\n\n      if SrcInfo.IsIndexed then\n      begin\n        // Source: indexed format\n        if DstInfo.IsIndexed then\n          IndexToIndex(NumPixels, Bits, NewData, SrcInfo, DstInfo, Palette, NewPal)\n        else if DstInfo.HasGrayChannel then\n          IndexToGray(NumPixels, Bits, NewData, SrcInfo, DstInfo, Palette)\n        else if DstInfo.IsFloatingPoint then\n          IndexToFloat(NumPixels, Bits, NewData, SrcInfo, DstInfo, Palette)\n        else\n          IndexToChannel(NumPixels, Bits, NewData, SrcInfo, DstInfo, Palette);\n      end\n      else if SrcInfo.HasGrayChannel then\n      begin\n        // Source: grayscale format\n        if DstInfo.IsIndexed then\n          GrayToIndex(NumPixels, Bits, NewData, SrcInfo, DstInfo, NewPal)\n        else if DstInfo.HasGrayChannel then\n          GrayToGray(NumPixels, Bits, NewData, SrcInfo, DstInfo)\n        else if DstInfo.IsFloatingPoint then\n          GrayToFloat(NumPixels, Bits, NewData, SrcInfo, DstInfo)\n        else\n          GrayToChannel(NumPixels, Bits, NewData, SrcInfo, DstInfo);\n      end\n      else if SrcInfo.IsFloatingPoint then\n      begin\n        // Source: floating point format\n        if DstInfo.IsIndexed then\n          FloatToIndex(NumPixels, Bits, NewData, SrcInfo, DstInfo, NewPal)\n        else if DstInfo.HasGrayChannel then\n          FloatToGray(NumPixels, Bits, NewData, SrcInfo, DstInfo)\n        else if DstInfo.IsFloatingPoint then\n          FloatToFloat(NumPixels, Bits, NewData, SrcInfo, DstInfo)\n        else\n          FloatToChannel(NumPixels, Bits, NewData, SrcInfo, DstInfo);\n      end\n      else\n      begin\n        // Source: standard multi channel image\n        if DstInfo.IsIndexed then\n          ChannelToIndex(NumPixels, Bits, NewData, SrcInfo, DstInfo, NewPal)\n        else if DstInfo.HasGrayChannel then\n          ChannelToGray(NumPixels, Bits, NewData, SrcInfo, DstInfo)\n        else if DstInfo.IsFloatingPoint then\n          ChannelToFloat(NumPixels, Bits, NewData, SrcInfo, DstInfo)\n        else\n          ChannelToChannel(NumPixels, Bits, NewData, SrcInfo, DstInfo);\n      end;\n\n      FreeMemNil(Bits);\n      FreeMemNil(Palette);\n      Format := DestFormat;\n      Bits := NewData;\n      Size := NewSize;\n      Palette := NewPal;\n    end\n    else\n      ConvertSpecial(Image, SrcInfo, DstInfo);\n\n    Assert(SrcInfo.Format <> Image.Format);\n\n    Result := True;\n  except\n    raise UpdateExceptMessage(GetExceptObject, SErrorConvertImage, [GetFormatName(DestFormat), ImageToStr(Image)]);\n  end;\nend;\n\nfunction FlipImage(var Image: TImageData): Boolean;\nvar\n  P1, P2, Buff: Pointer;\n  WidthBytes, I: LongInt;\n  OldFmt: TImageFormat;\nbegin\n  Result := False;\n  OldFmt := Image.Format;\n  if TestImage(Image) then\n  with Image do\n  try\n    if ImageFormatInfos[OldFmt].IsSpecial then\n      ConvertImage(Image, ifDefault);\n\n    WidthBytes := Width * ImageFormatInfos[Format].BytesPerPixel;\n    GetMem(Buff, WidthBytes);\n    try\n      // Swap all scanlines of image\n      for I := 0 to Height div 2 - 1 do\n      begin\n        P1 := @PByteArray(Bits)[I * WidthBytes];\n        P2 := @PByteArray(Bits)[(Height - I - 1) * WidthBytes];\n        Move(P1^, Buff^, WidthBytes);\n        Move(P2^, P1^, WidthBytes);\n        Move(Buff^, P2^, WidthBytes);\n      end;\n    finally\n      FreeMemNil(Buff);\n    end;\n\n    if OldFmt <> Format then\n      ConvertImage(Image, OldFmt);\n\n    Result := True;\n  except\n    RaiseImaging(SErrorFlipImage, [ImageToStr(Image)]);\n  end;\nend;\n\nfunction MirrorImage(var Image: TImageData): Boolean;\nvar\n  Scanline: PByte;\n  Buff: TColorFPRec;\n  Bpp, Y, X, WidthDiv2, WidthBytes, XLeft, XRight: LongInt;\n  OldFmt: TImageFormat;\nbegin\n  Result := False;\n  OldFmt := Image.Format;\n  if TestImage(Image) then\n  with Image do\n  try\n    if ImageFormatInfos[OldFmt].IsSpecial then\n      ConvertImage(Image, ifDefault);\n\n    Bpp := ImageFormatInfos[Format].BytesPerPixel;\n    WidthDiv2 := Width div 2;\n    WidthBytes := Width * Bpp;\n    // Mirror all pixels on each scanline of image\n    for Y := 0 to Height - 1 do\n    begin\n      Scanline := @PByteArray(Bits)[Y * WidthBytes];\n      XLeft := 0;\n      XRight := (Width - 1) * Bpp;\n      for X := 0 to WidthDiv2 - 1 do\n      begin\n        CopyPixel(@PByteArray(Scanline)[XLeft], @Buff, Bpp);\n        CopyPixel(@PByteArray(Scanline)[XRight],\n          @PByteArray(Scanline)[XLeft], Bpp);\n        CopyPixel(@Buff, @PByteArray(Scanline)[XRight], Bpp);\n        Inc(XLeft, Bpp);\n        Dec(XRight, Bpp);\n      end;\n    end;\n\n    if OldFmt <> Format then\n      ConvertImage(Image, OldFmt);\n\n    Result := True;\n  except\n    RaiseImaging(SErrorMirrorImage, [ImageToStr(Image)]);\n  end;\nend;\n\nfunction ResizeImage(var Image: TImageData; NewWidth, NewHeight: LongInt;\n  Filter: TResizeFilter): Boolean;\nvar\n  WorkImage: TImageData;\nbegin\n  Assert((NewWidth > 0) and (NewHeight > 0), 'New width or height is zero.');\n  Result := False;\n  if TestImage(Image) and ((Image.Width <> NewWidth) or (Image.Height <> NewHeight)) then\n  try\n    InitImage(WorkImage);\n    // Create new image with desired dimensions\n    NewImage(NewWidth, NewHeight, Image.Format, WorkImage);\n    // Stretch pixels from old image to new one\n    StretchRect(Image, 0, 0, Image.Width, Image.Height,\n      WorkImage, 0, 0, WorkImage.Width, WorkImage.Height, Filter);\n    // Free old image and assign new image to it\n    FreeMemNil(Image.Bits);\n    if Image.Palette <> nil then\n    begin\n      FreeMem(WorkImage.Palette);\n      WorkImage.Palette := Image.Palette;\n    end;\n    Image := WorkImage;\n    Result := True;\n  except\n    raise UpdateExceptMessage(GetExceptObject, SErrorResizeImage, [ImageToStr(Image)]);\n  end;\nend;\n\nfunction SwapChannels(var Image: TImageData; SrcChannel, DstChannel: LongInt): Boolean;\nvar\n  I, NumPixels: LongInt;\n  Info: PImageFormatInfo;\n  Swap, Alpha: Word;\n  Data: PByte;\n  Pix64: TColor64Rec;\n  PixF: TColorFPRec;\n  SwapF: Single;\nbegin\n  Assert((SrcChannel in [0..3]) and (DstChannel in [0..3]));\n  Result := False;\n  if TestImage(Image) and (SrcChannel <> DstChannel) then\n  with Image do\n  try\n    NumPixels := Width * Height;\n    Info := ImageFormatInfos[Format];\n    Data := Bits;\n\n    if (Info.Format = ifR8G8B8) or ((Info.Format = ifA8R8G8B8) and\n       (SrcChannel <> ChannelAlpha) and (DstChannel <> ChannelAlpha)) then\n    begin\n      // Swap channels of most common formats R8G8B8 and A8R8G8B8 (no alpha)\n      for I := 0 to NumPixels - 1 do\n      with PColor24Rec(Data)^ do\n      begin\n        Swap := Channels[SrcChannel];\n        Channels[SrcChannel] := Channels[DstChannel];\n        Channels[DstChannel] := Swap;\n        Inc(Data, Info.BytesPerPixel);\n      end;\n    end\n    else if Info.IsIndexed then\n    begin\n      // Swap palette channels of indexed images\n      SwapChannelsOfPalette(Palette, Info.PaletteEntries, SrcChannel, DstChannel)\n    end\n    else if Info.IsFloatingPoint then\n    begin\n      // Swap channels of floating point images\n      for I := 0 to NumPixels - 1 do\n      begin\n        FloatGetSrcPixel(Data, Info, PixF);\n        with PixF do\n        begin\n          SwapF := Channels[SrcChannel];\n          Channels[SrcChannel] := Channels[DstChannel];\n          Channels[DstChannel] := SwapF;\n        end;\n        FloatSetDstPixel(Data, Info, PixF);\n        Inc(Data, Info.BytesPerPixel);\n      end;\n    end\n    else if Info.IsSpecial then\n    begin\n      // Swap channels of special format images\n      ConvertImage(Image, ifDefault);\n      SwapChannels(Image, SrcChannel, DstChannel);\n      ConvertImage(Image, Info.Format);\n    end\n    else if Info.HasGrayChannel and Info.HasAlphaChannel and\n      ((SrcChannel = ChannelAlpha) or (DstChannel = ChannelAlpha)) then\n    begin\n      for I := 0 to NumPixels - 1 do\n      begin\n        // If we have grayscale image with alpha and alpha is channel\n        // to be swapped, we swap it. No other alternative for gray images,\n        // just alpha and something\n        GrayGetSrcPixel(Data, Info, Pix64, Alpha);\n        Swap := Alpha;\n        Alpha := Pix64.A;\n        Pix64.A := Swap;\n        GraySetDstPixel(Data, Info, Pix64, Alpha);\n        Inc(Data, Info.BytesPerPixel);\n      end;\n    end\n    else\n    begin\n      // Then do general swap on other channel image formats\n      for I := 0 to NumPixels - 1 do\n      begin\n        ChannelGetSrcPixel(Data, Info, Pix64);\n        with Pix64 do\n        begin\n          Swap := Channels[SrcChannel];\n          Channels[SrcChannel] := Channels[DstChannel];\n          Channels[DstChannel] := Swap;\n        end;\n        ChannelSetDstPixel(Data, Info, Pix64);\n        Inc(Data, Info.BytesPerPixel);\n      end;\n    end;\n\n    Result := True;\n  except\n    RaiseImaging(SErrorSwapImage, [ImageToStr(Image)]);\n  end;\nend;\n\nfunction ReduceColors(var Image: TImageData; MaxColors: LongInt): Boolean;\nvar\n  TmpInfo: TImageFormatInfo;\n  Data, Index: PWord;\n  I, NumPixels: LongInt;\n  Pal: PPalette32;\n  Col:PColor32Rec;\n  OldFmt: TImageFormat;\nbegin\n  Result := False;\n  if TestImage(Image) then\n  with Image do\n  try\n    // First create temp image info and allocate output bits and palette\n    MaxColors := ClampInt(MaxColors, 2, High(Word));\n    OldFmt := Format;\n    FillChar(TmpInfo, SizeOf(TmpInfo), 0);\n    TmpInfo.PaletteEntries := MaxColors;\n    TmpInfo.BytesPerPixel := 2;\n    NumPixels := Width * Height;\n    GetMem(Data, NumPixels * TmpInfo.BytesPerPixel);\n    GetMem(Pal, MaxColors * SizeOf(TColor32Rec));\n    ConvertImage(Image, ifA8R8G8B8);\n    // We use median cut algorithm to create reduced palette and to\n    // fill Data with indices to this palette\n    ReduceColorsMedianCut(NumPixels, Bits, PByte(Data),\n      ImageFormatInfos[Format], @TmpInfo, MaxColors, ColorReductionMask, Pal);\n    Col := Bits;\n    Index := Data;\n    // Then we write reduced colors to the input image\n    for I := 0 to NumPixels - 1 do\n    begin\n      Col.Color := Pal[Index^].Color;\n      Inc(Col);\n      Inc(Index);\n    end;\n    FreeMemNil(Data);\n    FreeMemNil(Pal);\n    // And convert it to its original format\n    ConvertImage(Image, OldFmt);\n    Result := True;\n  except\n    RaiseImaging(SErrorReduceColors, [MaxColors, ImageToStr(Image)]);\n  end;\nend;\n\nfunction GenerateMipMaps(const Image: TImageData; Levels: LongInt;\n  var MipMaps: TDynImageDataArray): Boolean;\nvar\n  Width, Height, I, Count: LongInt;\n  Info: TImageFormatInfo;\n  CompatibleCopy: TImageData;\nbegin\n  Result := False;\n  if TestImage(Image) then\n  try\n    Width := Image.Width;\n    Height := Image.Height;\n    // We compute number of possible mipmap levels and if\n    // the given levels are invalid or zero we use this value\n    Count := GetNumMipMapLevels(Width, Height);\n    if (Levels <= 0) or (Levels > Count) then\n      Levels := Count;\n\n    // If we have special format image we create copy to allow pixel access.\n    // This is also done in FillMipMapLevel which is called for each level\n    // but then the main big image would be converted to compatible\n    // for every level.\n    GetImageFormatInfo(Image.Format, Info);\n    if Info.IsSpecial then\n    begin\n      InitImage(CompatibleCopy);\n      CloneImage(Image, CompatibleCopy);\n      ConvertImage(CompatibleCopy, ifDefault);\n    end\n    else\n      CompatibleCopy := Image;\n\n    FreeImagesInArray(MipMaps);\n    SetLength(MipMaps, Levels);\n    CloneImage(Image, MipMaps[0]);\n\n    for I := 1 to Levels - 1 do\n    begin\n      Width := Width shr 1;\n      Height := Height shr 1;\n      if Width < 1 then Width := 1;\n      if Height < 1 then Height := 1;\n      FillMipMapLevel(CompatibleCopy, Width, Height, MipMaps[I]);\n    end;\n\n    if CompatibleCopy.Format <> MipMaps[0].Format then\n    begin\n      // Must convert smaller levels to proper format\n      for I := 1 to High(MipMaps) do\n        ConvertImage(MipMaps[I], MipMaps[0].Format);\n      FreeImage(CompatibleCopy);\n    end;\n\n    Result := True;\n  except\n    RaiseImaging(SErrorGenerateMipMaps, [Levels, ImageToStr(Image)]);\n  end;\nend;\n\nfunction MapImageToPalette(var Image: TImageData; Pal: PPalette32;\n  Entries: LongInt): Boolean;\n\n  function FindNearestColor(Pal: PPalette32; Entries: LongInt; Col: TColor32Rec): LongInt;\n  var\n    I, MinDif, Dif: LongInt;\n  begin\n    Result := 0;\n    MinDif := 1020;\n    for I := 0 to Entries - 1 do\n    with Pal[I] do\n    begin\n      Dif := Abs(R - Col.R);\n      if Dif > MinDif then Continue;\n      Dif := Dif + Abs(G - Col.G);\n      if Dif > MinDif then Continue;\n      Dif := Dif + Abs(B - Col.B);\n      if Dif > MinDif then Continue;\n      Dif := Dif + Abs(A - Col.A);\n      if Dif < MinDif then\n      begin\n        MinDif := Dif;\n        Result := I;\n      end;\n    end;\n  end;\n\nvar\n  I, MaxEntries: LongInt;\n  PIndex: PByte;\n  PColor: PColor32Rec;\n  CloneARGB: TImageData;\n  Info: PImageFormatInfo;\nbegin\n  Assert((Entries >= 2) and (Entries <= 256));\n  Result := False;\n\n  if TestImage(Image) then\n  try\n    // We create clone of source image in A8R8G8B8 and\n    // then recreate source image in ifIndex8 format\n    // with palette taken from Pal parameter\n    InitImage(CloneARGB);\n    CloneImage(Image, CloneARGB);\n    ConvertImage(CloneARGB, ifA8R8G8B8);\n    FreeImage(Image);\n    NewImage(CloneARGB.Width, CloneARGB.Height, ifIndex8, Image);\n\n    Info := ImageFormatInfos[Image.Format];\n    MaxEntries := Min(Info.PaletteEntries, Entries);\n    Move(Pal^, Image.Palette^, MaxEntries * SizeOf(TColor32Rec));\n    PIndex := Image.Bits;\n    PColor := CloneARGB.Bits;\n\n    // For every pixel of ARGB clone we find closest color in\n    // given palette and assign its index to resulting image's pixel\n    // procedure used here is very slow but simple and memory usage friendly\n    // (contrary to other methods)\n    for I := 0 to Image.Width * Image.Height - 1 do\n    begin\n      PIndex^ := Byte(FindNearestColor(Image.Palette, MaxEntries, PColor^));\n      Inc(PIndex);\n      Inc(PColor);\n    end;\n\n    FreeImage(CloneARGB);\n    Result := True;\n  except\n    raise UpdateExceptMessage(GetExceptObject, SErrorMapImage, [ImageToStr(Image)]);\n  end;\nend;\n\nfunction SplitImage(var Image: TImageData; var Chunks: TDynImageDataArray;\n  ChunkWidth, ChunkHeight: LongInt; var XChunks, YChunks: LongInt;\n  PreserveSize: Boolean; Fill: Pointer): Boolean;\nvar\n  X, Y, XTrunc, YTrunc: LongInt;\n  NotOnEdge: Boolean;\n  Info: PImageFormatInfo;\n  OldFmt: TImageFormat;\nbegin\n  Assert((ChunkWidth > 0) and (ChunkHeight > 0));\n  Result := False;\n  OldFmt := Image.Format;\n  FreeImagesInArray(Chunks);\n\n  if TestImage(Image) then\n  try\n    Info := ImageFormatInfos[Image.Format];\n    if Info.IsSpecial then\n      ConvertImage(Image, ifDefault);\n\n    // We compute make sure that chunks are not larger than source image or negative\n    ChunkWidth := ClampInt(ChunkWidth, 0, Image.Width);\n    ChunkHeight := ClampInt(ChunkHeight, 0, Image.Height);\n    // Number of chunks along X and Y axes is computed\n    XChunks := Trunc(Ceil(Image.Width / ChunkWidth));\n    YChunks := Trunc(Ceil(Image.Height / ChunkHeight));\n    SetLength(Chunks, XChunks * YChunks);\n\n    // For every chunk we create new image and copy a portion of\n    // the source image to it. If chunk is on the edge of the source image\n    // we fill enpty space with Fill pixel data if PreserveSize is set or\n    // make the chunk smaller if it is not set\n    for Y := 0 to YChunks - 1 do\n      for X := 0 to XChunks - 1 do\n      begin\n        // Determine if current chunk is on the edge of original image\n        NotOnEdge := ((X < XChunks - 1) and (Y < YChunks - 1)) or\n          ((Image.Width mod ChunkWidth = 0) and (Image.Height mod ChunkHeight = 0));\n\n        if PreserveSize or NotOnEdge then\n        begin\n          // We should preserve chunk sizes or we are somewhere inside original image\n          NewImage(ChunkWidth, ChunkHeight, Image.Format, Chunks[Y * XChunks + X]);\n          if (not NotOnEdge) and (Fill <> nil) then\n            FillRect(Chunks[Y * XChunks + X], 0, 0, ChunkWidth, ChunkHeight, Fill);\n          CopyRect(Image, X * ChunkWidth, Y * ChunkHeight, ChunkWidth, ChunkHeight,\n            Chunks[Y * XChunks + X], 0, 0);\n        end\n        else\n        begin\n          // Create smaller edge chunk\n          XTrunc := Image.Width - X * ChunkWidth;\n          YTrunc := Image.Height - Y * ChunkHeight;\n          NewImage(XTrunc, YTrunc, Image.Format, Chunks[Y * XChunks + X]);\n          CopyRect(Image, X * ChunkWidth, Y * ChunkHeight, XTrunc, YTrunc,\n            Chunks[Y * XChunks + X], 0, 0);\n        end;\n        \n        // If source image is in indexed format we copy its palette to chunk\n        if Info.IsIndexed then\n        begin\n          Move(Image.Palette^, Chunks[Y * XChunks + X].Palette^,\n            Info.PaletteEntries * SizeOf(TColor32Rec));\n        end;\n      end;\n\n    if OldFmt <> Image.Format then\n    begin\n      ConvertImage(Image, OldFmt);\n      for X := 0 to Length(Chunks) - 1 do\n        ConvertImage(Chunks[X], OldFmt);\n    end;\n\n    Result := True;\n  except\n    raise UpdateExceptMessage(GetExceptObject, SErrorSplitImage,\n      [ImageToStr(Image), ChunkWidth, ChunkHeight]);\n  end;\nend;\n\nfunction MakePaletteForImages(var Images: TDynImageDataArray; Pal: PPalette32;\n  MaxColors: LongInt; ConvertImages: Boolean): Boolean;\nvar\n  I: Integer;\n  SrcInfo, DstInfo: PImageFormatInfo;\n  Target, TempImage: TImageData;\n  DstFormat: TImageFormat;\nbegin\n  Assert((Pal <> nil) and (MaxColors > 0));\n  Result := False;\n  InitImage(TempImage);\n\n  if TestImagesInArray(Images) then\n  try\n    // Null the color histogram\n    ReduceColorsMedianCut(0, nil, nil, nil, nil, 0, 0, nil, [raCreateHistogram]);\n    for I := 0 to Length(Images) - 1 do\n    begin\n      SrcInfo := ImageFormatInfos[Images[I].Format];\n      if SrcInfo.IsIndexed or SrcInfo.IsSpecial then\n      begin\n        // create temp image in supported format for updating histogram\n        CloneImage(Images[I], TempImage);\n        ConvertImage(TempImage, ifA8R8G8B8);\n        SrcInfo := ImageFormatInfos[TempImage.Format];\n      end\n      else\n        TempImage := Images[I];\n\n      // Update histogram with colors of each input image\n      ReduceColorsMedianCut(TempImage.Width * TempImage.Height, TempImage.Bits,\n        nil, SrcInfo, nil, MaxColors, ColorReductionMask, nil, [raUpdateHistogram]);\n\n      if Images[I].Bits <> TempImage.Bits then\n        FreeImage(TempImage);\n    end;\n    // Construct reduced color map from the histogram\n    ReduceColorsMedianCut(0, nil, nil, nil, nil, MaxColors, ColorReductionMask,\n      Pal, [raMakeColorMap]);\n\n    if ConvertImages then\n    begin\n      DstFormat := ifIndex8;\n      DstInfo := ImageFormatInfos[DstFormat];\n      MaxColors := Min(DstInfo.PaletteEntries, MaxColors);\n\n      for I := 0 to Length(Images) - 1 do\n      begin\n        SrcInfo := ImageFormatInfos[Images[I].Format];\n        if SrcInfo.IsIndexed or SrcInfo.IsSpecial then\n        begin\n          // If source image is in format not supported by ReduceColorsMedianCut\n          // we convert it\n          ConvertImage(Images[I], ifA8R8G8B8);\n          SrcInfo := ImageFormatInfos[Images[I].Format];\n        end;\n\n        InitImage(Target);\n        NewImage(Images[I].Width, Images[I].Height, DstFormat, Target);\n        // We map each input image to reduced palette and replace\n        // image in array with mapped image\n        ReduceColorsMedianCut(Images[I].Width * Images[I].Height, Images[I].Bits,\n          Target.Bits, SrcInfo, DstInfo, MaxColors, 0, nil, [raMapImage]);\n        Move(Pal^, Target.Palette^, MaxColors * SizeOf(TColor32Rec));\n\n        FreeImage(Images[I]);\n        Images[I] := Target;\n      end;\n    end;\n    Result := True;\n  except\n    RaiseImaging(SErrorMakePaletteForImages, [MaxColors, Length(Images)]);\n  end;\nend;\n\nprocedure RotateImage(var Image: TImageData; Angle: Single);\nvar\n  OldFmt: TImageFormat;\n\n  procedure XShear(var Src, Dst: TImageData; Row, Offset, Weight, Bpp: Integer);\n  var\n    I, J, XPos: Integer;\n    PixSrc, PixLeft, PixOldLeft: TColor32Rec;\n    LineDst: PByteArray;\n    SrcPtr: PColor32;\n  begin\n    SrcPtr := @PByteArray(Src.Bits)[Row * Src.Width * Bpp];\n    LineDst := @PByteArray(Dst.Bits)[Row * Dst.Width * Bpp];\n    PixOldLeft.Color := 0;\n\n    for I := 0 to Src.Width - 1 do\n    begin\n      CopyPixel(SrcPtr, @PixSrc, Bpp);\n      for J := 0 to Bpp - 1 do\n        PixLeft.Channels[J] := MulDiv(PixSrc.Channels[J], Weight, 256);\n\n      XPos := I + Offset;\n      if (XPos >= 0) and (XPos < Dst.Width) then\n      begin\n        for J := 0 to Bpp - 1 do\n          PixSrc.Channels[J] := ClampToByte(PixSrc.Channels[J] - (PixLeft.Channels[J] - PixOldLeft.Channels[J]));\n        CopyPixel(@PixSrc, @LineDst[XPos * Bpp], Bpp);\n      end;\n      PixOldLeft := PixLeft;\n      Inc(PByte(SrcPtr), Bpp);\n    end;\n\n    XPos := Src.Width + Offset;\n    if XPos < Dst.Width then\n      CopyPixel(@PixOldLeft, @LineDst[XPos * Bpp], Bpp);\n  end;\n\n  procedure YShear(var Src, Dst: TImageData; Col, Offset, Weight, Bpp: Integer);\n  var\n    I, J, YPos: Integer;\n    PixSrc, PixLeft, PixOldLeft: TColor32Rec;\n    SrcPtr: PByte;\n  begin\n    SrcPtr := @PByteArray(Src.Bits)[Col * Bpp];\n    PixOldLeft.Color := 0;\n\n    for I := 0 to Src.Height - 1 do\n    begin\n      CopyPixel(SrcPtr, @PixSrc, Bpp);\n      for J := 0 to Bpp - 1 do\n        PixLeft.Channels[J] := MulDiv(PixSrc.Channels[J], Weight, 256);\n\n      YPos := I + Offset;\n      if (YPos >= 0) and (YPos < Dst.Height) then\n      begin\n        for J := 0 to Bpp - 1 do\n          PixSrc.Channels[J] := ClampToByte(PixSrc.Channels[J] - (PixLeft.Channels[J] - PixOldLeft.Channels[J]));\n        CopyPixel(@PixSrc, @PByteArray(Dst.Bits)[(YPos * Dst.Width + Col) * Bpp], Bpp);\n      end;\n      PixOldLeft := PixLeft;\n      Inc(SrcPtr, Src.Width * Bpp);\n    end;\n\n    YPos := Src.Height + Offset;\n    if YPos < Dst.Height then\n      CopyPixel(@PixOldLeft, @PByteArray(Dst.Bits)[(YPos * Dst.Width + Col) * Bpp], Bpp);\n  end;\n\n  procedure Rotate45(var Image: TImageData; Angle: Single);\n  var\n    TempImage1, TempImage2: TImageData;\n    AngleRad, AngleTan, AngleSin, AngleCos, Shear: Single;\n    I, DstWidth, DstHeight, SrcWidth, SrcHeight, Bpp: Integer;\n    SrcFmt, TempFormat: TImageFormat;\n    Info: TImageFormatInfo;\n  begin\n    AngleRad := Angle * Pi / 180;\n    AngleSin := Sin(AngleRad);\n    AngleCos := Cos(AngleRad);\n    AngleTan := Sin(AngleRad / 2) / Cos(AngleRad / 2);\n    SrcWidth := Image.Width;\n    SrcHeight := Image.Height;\n    SrcFmt := Image.Format;\n\n    if not (SrcFmt in [ifR8G8B8..ifX8R8G8B8, ifGray8..ifGray32, ifA16Gray16]) then\n      ConvertImage(Image, ifA8R8G8B8);\n\n    TempFormat := Image.Format;\n    GetImageFormatInfo(TempFormat, Info);\n    Bpp := Info.BytesPerPixel;\n\n    // 1st shear (horizontal)\n    DstWidth := Trunc(SrcWidth + SrcHeight * Abs(AngleTan) + 0.5);\n    DstHeight := SrcHeight;\n    InitImage(TempImage1);\n    NewImage(DstWidth, DstHeight, TempFormat, TempImage1);\n\n    for I := 0 to DstHeight - 1 do\n    begin\n      if AngleTan >= 0 then\n        Shear := (I + 0.5) * AngleTan\n      else\n        Shear := (I - DstHeight + 0.5) * AngleTan;\n      XShear(Image, TempImage1, I, Floor(Shear), Trunc(255 * (Shear - Floor(Shear)) + 1), Bpp);\n    end;\n\n    // 2nd shear (vertical)\n    FreeImage(Image);\n    DstHeight := Trunc(SrcWidth * Abs(AngleSin) + SrcHeight * AngleCos + 0.5) + 1;\n    InitImage(TempImage2);\n    NewImage(DstWidth, DstHeight, TempFormat, TempImage2);\n\n    if AngleSin >= 0 then\n      Shear := (SrcWidth - 1) * AngleSin\n    else\n      Shear := (SrcWidth - DstWidth) * -AngleSin;\n\n    for I := 0 to DstWidth - 1 do\n    begin\n      YShear(TempImage1, TempImage2, I, Floor(Shear), Trunc(255 * (Shear - Floor(Shear)) + 1), Bpp);\n      Shear := Shear - AngleSin;\n    end;\n\n    // 3rd shear (horizontal)\n    FreeImage(TempImage1);\n    DstWidth := Trunc(SrcHeight * Abs(AngleSin) + SrcWidth * AngleCos + 0.5) + 1;\n    NewImage(DstWidth, DstHeight, TempFormat, Image);\n\n    if AngleSin >= 0 then\n      Shear := (SrcWidth - 1) * AngleSin * -AngleTan\n    else\n      Shear := ((SrcWidth - 1) * -AngleSin + (1 - DstHeight)) * AngleTan;\n\n    for I := 0 to DstHeight - 1 do\n    begin\n      XShear(TempImage2, Image, I, Floor(Shear), Trunc(255 * (Shear - Floor(Shear)) + 1), Bpp);\n      Shear := Shear + AngleTan;\n    end;\n\n    FreeImage(TempImage2);\n    if Image.Format <> SrcFmt then\n      ConvertImage(Image, SrcFmt);\n  end;\n\n  procedure RotateMul90(var Image: TImageData; Angle: Integer);\n  var\n    RotImage: TImageData;\n    X, Y, BytesPerPixel: Integer;\n    RotPix, Pix: PByte;\n  begin\n    InitImage(RotImage);\n    BytesPerPixel := ImageFormatInfos[Image.Format].BytesPerPixel;\n\n    if ((Angle = 90) or (Angle = 270)) and (Image.Width <> Image.Height) then\n      NewImage(Image.Height, Image.Width, Image.Format, RotImage)\n    else\n      NewImage(Image.Width, Image.Height, Image.Format, RotImage);\n\n    RotPix := RotImage.Bits;\n    case Angle of\n      90:\n        begin\n          for Y := 0 to RotImage.Height - 1 do\n          begin\n            Pix := @PByteArray(Image.Bits)[(Image.Width - Y - 1) * BytesPerPixel];\n            for X := 0 to RotImage.Width - 1 do\n            begin\n              CopyPixel(Pix, RotPix, BytesPerPixel);\n              Inc(RotPix, BytesPerPixel);\n              Inc(Pix, Image.Width * BytesPerPixel);\n            end;\n          end;\n        end;\n      180:\n        begin\n          Pix := @PByteArray(Image.Bits)[((Image.Height - 1) * Image.Width +\n            (Image.Width - 1)) * BytesPerPixel];\n          for Y := 0 to RotImage.Height - 1 do\n            for X := 0 to RotImage.Width - 1 do\n            begin\n              CopyPixel(Pix, RotPix, BytesPerPixel);\n              Inc(RotPix, BytesPerPixel);\n              Dec(Pix, BytesPerPixel);\n            end;\n        end;\n      270:\n        begin\n          for Y := 0 to RotImage.Height - 1 do\n          begin\n            Pix := @PByteArray(Image.Bits)[((Image.Height - 1) * Image.Width + Y) * BytesPerPixel];\n            for X := 0 to RotImage.Width - 1 do\n            begin\n              CopyPixel(Pix, RotPix, BytesPerPixel);\n              Inc(RotPix, BytesPerPixel);\n              Dec(Pix, Image.Width * BytesPerPixel);\n            end;\n          end;\n        end;\n    end;\n\n    FreeMemNil(Image.Bits);\n    RotImage.Palette := Image.Palette;\n    Image := RotImage;\n  end;\n\nbegin\n  if TestImage(Image) then\n  try\n    while Angle >= 360 do\n      Angle := Angle - 360;\n    while Angle < 0 do\n      Angle := Angle + 360;\n\n    if (Angle = 0) or (Abs(Angle) = 360) then\n      Exit;\n\n    OldFmt := Image.Format;\n    if ImageFormatInfos[Image.Format].IsSpecial then\n      ConvertImage(Image, ifDefault);\n\n    if (Angle > 45) and (Angle <= 135) then\n    begin\n      RotateMul90(Image, 90);\n      Angle := Angle - 90;\n    end\n    else if (Angle > 135) and (Angle <= 225) then\n    begin\n      RotateMul90(Image, 180);\n      Angle := Angle - 180;\n    end\n    else if (Angle > 225) and (Angle <= 315) then\n    begin\n      RotateMul90(Image, 270);\n      Angle := Angle - 270;\n    end;\n\n    if Angle <> 0 then\n      Rotate45(Image, Angle);\n\n    if OldFmt <> Image.Format then\n      ConvertImage(Image, OldFmt);\n\n  except\n    raise UpdateExceptMessage(GetExceptObject, SErrorRotateImage, [ImageToStr(Image), Angle]);\n  end;\nend;\n\n{ Drawing/Pixel functions }\n\nfunction CopyRect(const SrcImage: TImageData; SrcX, SrcY, Width, Height: LongInt;\n  var DstImage: TImageData; DstX, DstY: LongInt): Boolean;\nvar\n  Info: PImageFormatInfo;\n  I, SrcWidthBytes, DstWidthBytes, MoveBytes: LongInt;\n  SrcPointer, DstPointer: PByte;\n  WorkImage: TImageData;\n  OldFormat: TImageFormat;\nbegin\n  Result := False;\n  OldFormat := ifUnknown;\n  if TestImage(SrcImage) and TestImage(DstImage) then\n  try\n    // Make sure we are still copying image to image, not invalid pointer to protected memory\n    ClipCopyBounds(SrcX, SrcY, Width, Height, DstX, DstY, SrcImage.Width, SrcImage.Height,\n      Rect(0, 0, DstImage.Width, DstImage.Height));\n\n    if (Width > 0) and (Height > 0) then\n    begin\n      Info := ImageFormatInfos[DstImage.Format];\n      if Info.IsSpecial then\n      begin\n        // If dest image is in special format we convert it to default\n        OldFormat := Info.Format;\n        ConvertImage(DstImage, ifDefault);\n        Info := ImageFormatInfos[DstImage.Format];\n      end;\n      if SrcImage.Format <> DstImage.Format then\n      begin\n        // If images are in different format source is converted to dest's format\n        InitImage(WorkImage);\n        CloneImage(SrcImage, WorkImage);\n        ConvertImage(WorkImage, DstImage.Format);\n      end\n      else\n        WorkImage := SrcImage;\n\n      MoveBytes := Width * Info.BytesPerPixel;\n      DstWidthBytes := DstImage.Width * Info.BytesPerPixel;\n      DstPointer := @PByteArray(DstImage.Bits)[DstY * DstWidthBytes +\n        DstX * Info.BytesPerPixel];\n      SrcWidthBytes := WorkImage.Width * Info.BytesPerPixel;\n      SrcPointer := @PByteArray(WorkImage.Bits)[SrcY * SrcWidthBytes +\n        SrcX * Info.BytesPerPixel];\n\n      for I := 0 to Height - 1 do\n      begin\n        Move(SrcPointer^, DstPointer^, MoveBytes);\n        Inc(SrcPointer, SrcWidthBytes);\n        Inc(DstPointer, DstWidthBytes);\n      end;\n      // If dest image was in special format we convert it back\n      if OldFormat <> ifUnknown then\n        ConvertImage(DstImage, OldFormat);\n      // Working image must be freed if it is not the same as source image\n      if WorkImage.Bits <> SrcImage.Bits then\n        FreeImage(WorkImage);\n\n      Result := True;\n    end;\n  except\n    RaiseImaging(SErrorCopyRect, [ImageToStr(SrcImage), ImageToStr(DstImage)]);\n  end;\nend;\n\nfunction FillRect(var Image: TImageData; X, Y, Width, Height: LongInt;\n  FillColor: Pointer): Boolean;\nvar\n  Info: PImageFormatInfo;\n  I, J, ImageWidthBytes, RectWidthBytes, Bpp: Longint;\n  LinePointer, PixPointer: PByte;\n  OldFmt: TImageFormat;\nbegin\n  Result := False;\n  if TestImage(Image) then\n  try\n    ClipRectBounds(X, Y, Width, Height, Rect(0, 0, Image.Width, Image.Height));\n\n    if (Width > 0) and (Height > 0) then\n    begin\n      OldFmt := Image.Format;\n      if ImageFormatInfos[OldFmt].IsSpecial then\n        ConvertImage(Image, ifDefault);\n\n      Info := ImageFormatInfos[Image.Format];\n      Bpp := Info.BytesPerPixel;\n      ImageWidthBytes := Image.Width * Bpp;\n      RectWidthBytes := Width * Bpp;\n      LinePointer := @PByteArray(Image.Bits)[Y * ImageWidthBytes + X * Bpp];\n\n      for I := 0 to Height - 1 do\n      begin\n        case Bpp of\n          1: FillMemoryByte(LinePointer, RectWidthBytes, PByte(FillColor)^);\n          2: FillMemoryWord(LinePointer, RectWidthBytes, PWord(FillColor)^);\n          4: FillMemoryLongWord(LinePointer, RectWidthBytes, PLongWord(FillColor)^);\n        else\n          PixPointer := LinePointer;\n          for J := 0 to Width - 1 do\n          begin\n            CopyPixel(FillColor, PixPointer, Bpp);\n            Inc(PixPointer, Bpp);\n          end;\n        end;\n        Inc(LinePointer, ImageWidthBytes);\n      end;\n\n      if OldFmt <> Image.Format then\n        ConvertImage(Image, OldFmt);\n    end;\n\n    Result := True;\n  except\n    RaiseImaging(SErrorFillRect, [X, Y, Width, Height, ImageToStr(Image)]);\n  end;\nend;\n\nfunction ReplaceColor(var Image: TImageData; X, Y, Width, Height: LongInt;\n  OldColor, NewColor: Pointer): Boolean;\nvar\n  Info: PImageFormatInfo;\n  I, J, WidthBytes, Bpp: Longint;\n  LinePointer, PixPointer: PByte;\n  OldFmt: TImageFormat;\nbegin\n  Assert((OldColor <> nil) and (NewColor <> nil));\n  Result := False;\n  if TestImage(Image) then\n  try\n    ClipRectBounds(X, Y, Width, Height, Rect(0, 0, Image.Width, Image.Height));\n\n    if (Width > 0) and (Height > 0) then\n    begin\n      OldFmt := Image.Format;\n      if ImageFormatInfos[OldFmt].IsSpecial then\n        ConvertImage(Image, ifDefault);\n\n      Info := ImageFormatInfos[Image.Format];\n      Bpp := Info.BytesPerPixel;\n      WidthBytes := Image.Width * Bpp;\n      LinePointer := @PByteArray(Image.Bits)[Y * WidthBytes + X * Bpp];\n\n      for I := 0 to Height - 1 do\n      begin\n        PixPointer := LinePointer;\n        for J := 0 to Width - 1 do\n        begin\n          if ComparePixels(PixPointer, OldColor, Bpp) then\n            CopyPixel(NewColor, PixPointer, Bpp);\n          Inc(PixPointer, Bpp);\n        end;\n        Inc(LinePointer, WidthBytes);\n      end;\n\n      if OldFmt <> Image.Format then\n        ConvertImage(Image, OldFmt);\n    end;\n\n    Result := True;\n  except\n    RaiseImaging(SErrorReplaceColor, [X, Y, Width, Height, ImageToStr(Image)]);\n  end;\nend;\n\nfunction StretchRect(const SrcImage: TImageData; SrcX, SrcY, SrcWidth,\n  SrcHeight: LongInt; var DstImage: TImageData; DstX, DstY, DstWidth,\n  DstHeight: LongInt; Filter: TResizeFilter): Boolean;\nvar\n  Info: PImageFormatInfo;\n  WorkImage: TImageData;\n  OldFormat: TImageFormat;\n  Resampling: TSamplingFilter;\nbegin\n  Result := False;\n  OldFormat := ifUnknown;\n  if TestImage(SrcImage) and TestImage(DstImage) then\n  try\n    // Make sure we are still copying image to image, not invalid pointer to protected memory\n    ClipStretchBounds(SrcX, SrcY, SrcWidth, SrcHeight, DstX, DstY, DstWidth, DstHeight,\n      SrcImage.Width, SrcImage.Height, Rect(0, 0, DstImage.Width, DstImage.Height));\n\n    if (SrcWidth = DstWidth) and (SrcHeight = DstHeight) then\n    begin\n      // If source and dest rectangles have the same size call CopyRect\n      Result := CopyRect(SrcImage, SrcX, SrcY, SrcWidth, SrcHeight, DstImage, DstX, DstY);\n    end\n    else if (SrcWidth > 0) and (SrcHeight > 0) and (DstWidth > 0) and (DstHeight > 0) then\n    begin\n      // If source and dest rectangles don't have the same size we do stretch\n      Info := ImageFormatInfos[DstImage.Format];\n\n      if Info.IsSpecial then\n      begin\n        // If dest image is in special format we convert it to default\n        OldFormat := Info.Format;\n        ConvertImage(DstImage, ifDefault);\n        Info := ImageFormatInfos[DstImage.Format];\n      end;\n\n      if SrcImage.Format <> DstImage.Format then\n      begin\n        // If images are in different format source is converted to dest's format\n        InitImage(WorkImage);\n        CloneImage(SrcImage, WorkImage);\n        ConvertImage(WorkImage, DstImage.Format);\n      end\n      else\n        WorkImage := SrcImage;\n\n      // Only pixel resize is supported for indexed images\n      if Info.IsIndexed then\n        Filter := rfNearest;\n\n      if Filter = rfNearest then\n      begin\n        StretchNearest(WorkImage, SrcX, SrcY, SrcWidth, SrcHeight,\n          DstImage, DstX, DstY, DstWidth, DstHeight);\n      end\n      else\n      begin\n        Resampling := sfNearest;\n        case Filter of\n          rfBilinear: Resampling := sfLinear;\n          rfBicubic:  Resampling := DefaultCubicFilter;\n          rfLanczos:  Resampling := sfLanczos;\n        end;\n        StretchResample(WorkImage, SrcX, SrcY, SrcWidth, SrcHeight,\n          DstImage, DstX, DstY, DstWidth, DstHeight, Resampling);\n      end;\n\n      // If dest image was in special format we convert it back\n      if OldFormat <> ifUnknown then\n        ConvertImage(DstImage, OldFormat);\n      // Working image must be freed if it is not the same as source image\n      if WorkImage.Bits <> SrcImage.Bits then\n        FreeImage(WorkImage);\n\n      Result := True;\n    end;\n  except\n    RaiseImaging(SErrorStretchRect, [ImageToStr(SrcImage), ImageToStr(DstImage)]);\n  end;\nend;\n\nprocedure GetPixelDirect(const Image: TImageData; X, Y: LongInt; Pixel: Pointer);\nvar\n  BytesPerPixel: LongInt;\nbegin\n  Assert(Pixel <> nil);\n  BytesPerPixel := ImageFormatInfos[Image.Format].BytesPerPixel;\n  CopyPixel(@PByteArray(Image.Bits)[(Y * Image.Width + X) * BytesPerPixel],\n    Pixel, BytesPerPixel);\nend;\n\nprocedure SetPixelDirect(const Image: TImageData; X, Y: LongInt; Pixel: Pointer);\nvar\n  BytesPerPixel: LongInt;\nbegin\n  Assert(Pixel <> nil);\n  BytesPerPixel := ImageFormatInfos[Image.Format].BytesPerPixel;\n  CopyPixel(Pixel, @PByteArray(Image.Bits)[(Y * Image.Width + X) * BytesPerPixel],\n    BytesPerPixel);\nend;\n\nfunction GetPixel32(const Image: TImageData; X, Y: LongInt): TColor32Rec;\nvar\n  Info: PImageFormatInfo;\n  Data: PByte;\nbegin\n  Info := ImageFormatInfos[Image.Format];\n  Data := @PByteArray(Image.Bits)[(Y * Image.Width + X) * Info.BytesPerPixel];\n  Result := GetPixel32Generic(Data, Info, Image.Palette);\nend;\n\nprocedure SetPixel32(const Image: TImageData; X, Y: LongInt; const Color: TColor32Rec);\nvar\n  Info: PImageFormatInfo;\n  Data: PByte;\nbegin\n  Info := ImageFormatInfos[Image.Format];\n  Data := @PByteArray(Image.Bits)[(Y * Image.Width + X) * Info.BytesPerPixel];\n  SetPixel32Generic(Data, Info, Image.Palette, Color);\nend;\n\nfunction GetPixelFP(const Image: TImageData; X, Y: LongInt): TColorFPRec;\nvar\n  Info: PImageFormatInfo;\n  Data: PByte;\nbegin\n  Info := ImageFormatInfos[Image.Format];\n  Data := @PByteArray(Image.Bits)[(Y * Image.Width + X) * Info.BytesPerPixel];\n  Result := GetPixelFPGeneric(Data, Info, Image.Palette);\nend;\n\nprocedure SetPixelFP(const Image: TImageData; X, Y: LongInt; const Color: TColorFPRec);\nvar\n  Info: PImageFormatInfo;\n  Data: PByte;\nbegin\n  Info := ImageFormatInfos[Image.Format];\n  Data := @PByteArray(Image.Bits)[(Y * Image.Width + X) * Info.BytesPerPixel];\n  SetPixelFPGeneric(Data, Info, Image.Palette, Color);\nend;\n\n{ Palette Functions }\n\nprocedure NewPalette(Entries: LongInt; var Pal: PPalette32);\nbegin\n  Assert((Entries > 2) and (Entries <= 65535));\n  try\n    GetMem(Pal, Entries * SizeOf(TColor32Rec));\n    FillChar(Pal^, Entries * SizeOf(TColor32Rec), $FF);\n  except\n    RaiseImaging(SErrorNewPalette, [Entries]);\n  end;\nend;\n\nprocedure FreePalette(var Pal: PPalette32);\nbegin\n  try\n    FreeMemNil(Pal);\n  except\n    RaiseImaging(SErrorFreePalette, [Pal]);\n  end;\nend;\n\nprocedure CopyPalette(SrcPal, DstPal: PPalette32; SrcIdx, DstIdx, Count: LongInt);\nbegin\n  Assert((SrcPal <> nil) and (DstPal <> nil));\n  Assert((SrcIdx >= 0) and (DstIdx >= 0) and (Count >= 0));\n  try\n    Move(SrcPal[SrcIdx], DstPal[DstIdx], Count * SizeOf(TColor32Rec));\n  except\n    RaiseImaging(SErrorCopyPalette, [Count, SrcPal, DstPal]);\n  end;\nend;\n\nfunction FindColor(Pal: PPalette32; Entries: LongInt; Color: TColor32):\n  LongInt;\nvar\n  Col: TColor32Rec;\n  I, MinDif, Dif: LongInt;\nbegin\n  Assert(Pal <> nil);\n  Result := -1;\n  Col.Color := Color;\n  try\n    // First try to find exact match\n    for I := 0 to Entries - 1 do\n    with Pal[I] do\n    begin\n      if (A = Col.A) and (R = Col.R) and\n        (G = Col.G) and (B = Col.B) then\n      begin\n        Result := I;\n        Exit;\n      end;\n    end;\n\n    // If exact match was not found, find nearest color\n    MinDif := 1020;\n    for I := 0 to Entries - 1 do\n    with Pal[I] do\n    begin\n      Dif := Abs(R - Col.R);\n      if Dif > MinDif then Continue;\n      Dif := Dif + Abs(G - Col.G);\n      if Dif > MinDif then Continue;\n      Dif := Dif + Abs(B - Col.B);\n      if Dif > MinDif then Continue;\n      Dif := Dif + Abs(A - Col.A);\n      if Dif < MinDif then\n      begin\n        MinDif := Dif;\n        Result := I;\n      end;\n    end;\n  except\n    RaiseImaging(SErrorFindColor, [Pal, Entries]);\n  end;\nend;\n\nprocedure FillGrayscalePalette(Pal: PPalette32; Entries: LongInt);\nvar\n  I: LongInt;\nbegin\n  Assert(Pal <> nil);\n  try\n    for I := 0 to Entries - 1 do\n    with Pal[I] do\n    begin\n      A := $FF;\n      R := Byte(I);\n      G := Byte(I);\n      B := Byte(I);\n    end;\n  except\n    RaiseImaging(SErrorGrayscalePalette, [Pal, Entries]);\n  end;\nend;\n\nprocedure FillCustomPalette(Pal: PPalette32; Entries: LongInt; RBits, GBits,\n  BBits: Byte; Alpha: Byte = $FF);\nvar\n  I, TotalBits, MaxEntries: LongInt;\nbegin\n  Assert(Pal <> nil);\n  TotalBits := RBits + GBits + BBits;\n  MaxEntries := Min(Pow2Int(TotalBits), Entries);\n  FillChar(Pal^, Entries * SizeOf(TColor32Rec), 0);\n  try\n    for I := 0 to MaxEntries - 1 do\n    with Pal[I] do\n    begin\n      A := Alpha;\n      if RBits > 0 then\n        R := ((I shr Max(0, GBits + BBits - 1)) and (1 shl RBits - 1)) * 255 div (1 shl RBits - 1);\n      if GBits > 0 then\n        G := ((I shr Max(0, BBits - 1)) and (1 shl GBits - 1)) * 255 div (1 shl GBits - 1);\n      if BBits > 0 then\n        B := ((I shr 0) and (1 shl BBits - 1)) * 255 div (1 shl BBits - 1);\n    end;\n  except\n    RaiseImaging(SErrorCustomPalette, [Pal, Entries]);\n  end;\nend;\n\nprocedure SwapChannelsOfPalette(Pal: PPalette32; Entries, SrcChannel,\n  DstChannel: LongInt);\nvar\n  I: LongInt;\n  Swap: Byte;\nbegin\n  Assert(Pal <> nil);\n  Assert((SrcChannel in [0..3]) and (DstChannel in [0..3]));\n  try\n    for I := 0 to Entries - 1 do\n    with Pal[I] do\n    begin\n      Swap := Channels[SrcChannel];\n      Channels[SrcChannel] := Channels[DstChannel];\n      Channels[DstChannel] := Swap;\n    end;\n  except\n    RaiseImaging(SErrorSwapPalette, [Pal, Entries]);\n  end;\nend;\n\n{ Options Functions }\n\nfunction SetOption(OptionId, Value: LongInt): Boolean;\nbegin\n  Result := False;\n  if (OptionId >= 0) and (OptionId < Length(Options)) and\n    (Options[OptionID] <> nil) then\n  begin\n    Options[OptionID]^ := CheckOptionValue(OptionId, Value);\n    Result := True;\n  end;\nend;\n\nfunction GetOption(OptionId: LongInt): LongInt;\nbegin\n  Result := InvalidOption;\n  if (OptionId >= 0) and (OptionId < Length(Options)) and\n    (Options[OptionID] <> nil) then\n  begin\n    Result := Options[OptionID]^;\n  end;\nend;\n\nfunction PushOptions: Boolean;\nbegin\n  Result := OptionStack.Push;\nend;\n\nfunction PopOptions: Boolean;\nbegin\n  Result := OptionStack.Pop;\nend;\n\n{ Image Format Functions }\n\nfunction GetImageFormatInfo(Format: TImageFormat; out Info: TImageFormatInfo): Boolean;\nbegin\n  FillChar(Info, SizeOf(Info), 0);\n  if ImageFormatInfos[Format] <> nil then\n  begin\n    Info := ImageFormatInfos[Format]^;\n    Result := True;\n  end\n  else\n    Result := False;\nend;\n\nfunction GetPixelsSize(Format: TImageFormat; Width, Height: LongInt): LongInt;\nbegin\n  if ImageFormatInfos[Format] <> nil then\n    Result := ImageFormatInfos[Format].GetPixelsSize(Format, Width, Height)\n  else\n    Result := 0;\nend;\n\n{ IO Functions }\n\nprocedure SetUserFileIO(OpenProc: TOpenProc;\n  CloseProc: TCloseProc; EofProc: TEofProc; SeekProc: TSeekProc; TellProc:\n  TTellProc; ReadProc: TReadProc; WriteProc: TWriteProc);\nbegin\n  FileIO.Open := OpenProc;\n  FileIO.Close := CloseProc;\n  FileIO.Eof := EofProc;\n  FileIO.Seek := SeekProc;\n  FileIO.Tell := TellProc;\n  FileIO.Read := ReadProc;\n  FileIO.Write := WriteProc;\nend;\n\nprocedure ResetFileIO;\nbegin\n  FileIO := OriginalFileIO;\nend;\n\n{ Raw Image IO Functions }\n\nprocedure ReadRawImage(Handle: TImagingHandle;  Width, Height: Integer;\n  Format: TImageFormat; out Image: TImageData; Offset, RowLength: Integer);\nvar\n  WidthBytes, I: Integer;\n  Info: PImageFormatInfo;\nbegin\n  Info := ImageFormatInfos[Format];\n  // Calc scanline size\n  WidthBytes := Info.GetPixelsSize(Format, Width, 1);\n  if RowLength = 0 then\n    RowLength := WidthBytes;\n  // Create new image if needed - don't need to allocate new one if there is already\n  // one with desired size and format\n  if (Image.Width <> Width) or (Image.Height <> Height) or (Image.Format <> Format) then\n    NewImage(Width, Height, Format, Image);\n  // Move past the header\n  IO.Seek(Handle, Offset, smFromCurrent);\n  // Read scanlines from input\n  for I := 0 to Height - 1 do\n  begin\n    IO.Read(Handle, @PByteArray(Image.Bits)[I * WidthBytes], WidthBytes);\n    IO.Seek(Handle, RowLength - WidthBytes, smFromCurrent);\n  end;\nend;\n\nprocedure ReadRawImageFromFile(const FileName: string; Width, Height: Integer;\n  Format: TImageFormat; var Image: TImageData; Offset, RowLength: Integer);\nvar\n  Handle: TImagingHandle;\nbegin\n  Assert(FileName <> '');\n  // Set IO ops to file ops and open given file\n  SetFileIO;\n  Handle := IO.Open(PChar(FileName), omReadOnly);\n  try\n    ReadRawImage(Handle, Width, Height, Format, Image, Offset, RowLength);\n  finally\n    IO.Close(Handle);\n  end;\nend;\n\nprocedure ReadRawImageFromStream(Stream: TStream; Width, Height: Integer;\n  Format: TImageFormat; var Image: TImageData; Offset, RowLength: Integer);\nvar\n  Handle: TImagingHandle;\nbegin\n  Assert(Stream <> nil);\n  if Stream.Size - Stream.Position = 0 then\n    RaiseImaging(SErrorEmptyStream, []);\n  // Set IO ops to stream ops and open given stream\n  SetStreamIO;\n  Handle := IO.Open(Pointer(Stream), omReadOnly);\n  try\n    ReadRawImage(Handle, Width, Height, Format, Image, Offset, RowLength);\n  finally\n    IO.Close(Handle);\n  end;\nend;\n\nprocedure ReadRawImageFromMemory(Data: Pointer; DataSize: Integer; Width, Height: Integer;\n  Format: TImageFormat; var Image: TImageData; Offset, RowLength: Integer);\nvar\n  Handle: TImagingHandle;\n  MemRec: TMemoryIORec;\nbegin\n  Assert((Data <> nil) and (DataSize > 0));\n  // Set IO ops to memory ops and open given stream\n  SetMemoryIO;\n  MemRec := PrepareMemIO(Data, DataSize);\n  Handle := IO.Open(@MemRec, omReadOnly);\n  try\n    ReadRawImage(Handle, Width, Height, Format, Image, Offset, RowLength);\n  finally\n    IO.Close(Handle);\n  end;\nend;\n\nprocedure ReadRawImageRect(Data: Pointer; Left, Top, Width, Height: Integer;\n  var Image: TImageData; Offset, RowLength: Integer);\nvar\n  DestScanBytes, RectBytes, I: Integer;\n  Info: PImageFormatInfo;\n  Src, Dest: PByte;\nbegin\n  Assert(Data <> nil);\n  Assert((Left + Width <= Image.Width) and (Top + Height <= Image.Height));\n  Info := ImageFormatInfos[Image.Format];\n\n  // Calc scanline size\n  DestScanBytes := Info.GetPixelsSize(Info.Format, Image.Width, 1);\n  RectBytes := Info.GetPixelsSize(Info.Format, Width, 1);\n  if RowLength = 0 then\n    RowLength := RectBytes;\n\n  Src := Data;\n  Dest := @PByteArray(Image.Bits)[Top * DestScanBytes + Info.GetPixelsSize(Info.Format, Left, 1)];\n  // Move past the header\n  Inc(Src, Offset);\n\n  // Read lines into rect in the existing image\n  for I := 0 to Height - 1 do\n  begin\n    Move(Src^, Dest^, RectBytes);\n    Inc(Src, RowLength);\n    Inc(Dest, DestScanBytes);\n  end;\nend;\n\nprocedure WriteRawImage(Handle: TImagingHandle; const Image: TImageData;\n  Offset, RowLength: Integer);\nvar\n  WidthBytes, I: Integer;\n  Info: PImageFormatInfo;\nbegin\n  Info := ImageFormatInfos[Image.Format];\n  // Calc scanline size\n  WidthBytes := Info.GetPixelsSize(Image.Format, Image.Width, 1);\n  if RowLength = 0 then\n    RowLength := WidthBytes;\n  // Move past the header\n  IO.Seek(Handle, Offset, smFromCurrent);\n  // Write scanlines to output\n  for I := 0 to Image.Height - 1 do\n  begin\n    IO.Write(Handle, @PByteArray(Image.Bits)[I * WidthBytes], WidthBytes);\n    IO.Seek(Handle, RowLength - WidthBytes, smFromCurrent);\n  end;\nend;\n\nprocedure WriteRawImageToFile(const FileName: string; const Image: TImageData;\n  Offset, RowLength: Integer);\nvar\n  Handle: TImagingHandle;\nbegin\n  Assert(FileName <> '');\n  // Set IO ops to file ops and open given file\n  SetFileIO;\n  Handle := IO.Open(PChar(FileName), omCreate);\n  try\n    WriteRawImage(Handle, Image, Offset, RowLength);\n  finally\n    IO.Close(Handle);\n  end;\nend;\n\nprocedure WriteRawImageToStream(Stream: TStream; const Image: TImageData;\n  Offset, RowLength: Integer);\nvar\n  Handle: TImagingHandle;\nbegin\n  Assert(Stream <> nil);\n  // Set IO ops to stream ops and open given stream\n  SetStreamIO;\n  Handle := IO.Open(Pointer(Stream), omCreate);\n  try\n    WriteRawImage(Handle, Image, Offset, RowLength);\n  finally\n    IO.Close(Handle);\n  end;\nend;\n\nprocedure WriteRawImageToMemory(Data: Pointer; DataSize: Integer; const Image: TImageData;\n  Offset, RowLength: Integer);\nvar\n  Handle: TImagingHandle;\n  MemRec: TMemoryIORec;\nbegin\n  Assert((Data <> nil) and (DataSize > 0));\n  // Set IO ops to memory ops and open given stream\n  SetMemoryIO;\n  MemRec := PrepareMemIO(Data, DataSize);\n  Handle := IO.Open(@MemRec, omCreate);\n  try\n    WriteRawImage(Handle, Image, Offset, RowLength);\n  finally\n    IO.Close(Handle);\n  end;\nend;\n\nprocedure WriteRawImageRect(Data: Pointer; Left, Top, Width, Height: Integer;\n  const Image: TImageData; Offset, RowLength: Integer);\nvar\n  SrcScanBytes, RectBytes, I: Integer;\n  Info: PImageFormatInfo;\n  Src, Dest: PByte;\nbegin\n  Assert(Data <> nil);\n  Assert((Left + Width <= Image.Width) and (Top + Height <= Image.Height));\n  Info := ImageFormatInfos[Image.Format];\n\n  // Calc scanline size\n  SrcScanBytes := Info.GetPixelsSize(Info.Format, Image.Width, 1);\n  RectBytes := Info.GetPixelsSize(Info.Format, Width, 1);\n  if RowLength = 0 then\n    RowLength := RectBytes;\n\n  Src := @PByteArray(Image.Bits)[Top * SrcScanBytes + Info.GetPixelsSize(Info.Format, Left, 1)];\n  Dest := Data;\n  // Move past the header\n  Inc(Dest, Offset);\n\n  // Write lines from rect of the existing image\n  for I := 0 to Height - 1 do\n  begin\n    Move(Src^, Dest^, RectBytes);\n    Inc(Dest, RowLength);\n    Inc(Src, SrcScanBytes);\n  end;\nend;\n\n{ Convenience/helper Functions }\n\nprocedure ResizeImageToFit(const SrcImage: TImageData; FitWidth, FitHeight: Integer;\n  Filter: TResizeFilter; var DestImage: TImageData);\nvar\n  CurSize, FitSize, DestSize: TSize;\nbegin\n  if not TestImage(SrcImage) then\n    raise EImagingError.Create(SErrorInvalidInputImage);\n\n  FitSize.CX := FitWidth;\n  FitSize.CY := FitHeight;\n  CurSize.CX := SrcImage.Width;\n  CurSize.CY := SrcImage.Height;\n  DestSize := ImagingUtility.ScaleSizeToFit(CurSize, FitSize);\n\n  NewImage(Max(DestSize.CX, 1), Max(DestSize.CY, 1), SrcImage.Format, DestImage);\n  if SrcImage.Palette <> nil then\n    CopyPalette(SrcImage.Palette, DestImage.Palette, 0, 0, ImageFormatInfos[SrcImage.Format].PaletteEntries);\n\n  StretchRect(SrcImage, 0, 0, CurSize.CX, CurSize.CY, DestImage, 0, 0,\n    DestSize.CX, DestSize.CY, Filter);\nend;\n\n{ ------------------------------------------------------------------------\n                           Other Imaging Stuff\n  ------------------------------------------------------------------------}\n\nfunction GetFormatName(Format: TImageFormat): string;\nbegin\n  if ImageFormatInfos[Format] <> nil then\n    Result := ImageFormatInfos[Format].Name\n  else\n    Result := SUnknownFormat;\nend;\n\nfunction ImageToStr(const Image: TImageData): string;\nvar\n  ImgSize: Integer;\nbegin\n  if TestImage(Image) then\n  with Image do\n  begin\n    ImgSize := Size;\n    if ImgSize > 8192 then\n      ImgSize := ImgSize div 1024;\n    Result := SysUtils.Format(SImageInfo, [@Image, Width, Height,\n      GetFormatName(Format), ImgSize + 0.0, Iff(ImgSize = Size, 'B', 'KiB'), Bits,\n      Palette]);\n  end\n  else\n    Result := SysUtils.Format(SImageInfoInvalid, [@Image]);\nend;\n\nfunction GetVersionStr: string;\nbegin\n  Result := Format('%.1d.%.2d.%.1d', [ImagingVersionMajor,\n    ImagingVersionMinor, ImagingVersionPatch]);\nend;\n\nfunction IffFormat(Condition: Boolean; const TruePart, FalsePart: TImageFormat): TImageFormat;\nbegin\n  if Condition then\n    Result := TruePart\n  else\n    Result := FalsePart;\nend;\n\nprocedure RegisterImageFileFormat(AClass: TImageFileFormatClass);\nbegin\n  Assert(AClass <> nil);\n  if ImageFileFormats = nil then\n    ImageFileFormats := TList.Create;\n  if GlobalMetadata = nil then\n    GlobalMetadata := TMetadata.Create;\n  if ImageFileFormats <> nil then\n    ImageFileFormats.Add(AClass.Create);\nend;\n\nfunction RegisterOption(OptionId: LongInt; Variable: PLongInt): Boolean;\nbegin\n  Result := False;\n  if Options = nil then\n    InitOptions;\n\n  Assert(Variable <> nil);\n\n  if OptionId >= Length(Options) then\n    SetLength(Options, OptionId + InitialOptions);\n  if (OptionId >= 0) and (OptionId < Length(Options)) {and (Options[OptionId] = nil) - must be able to override existing } then\n  begin\n    Options[OptionId] := Variable;\n    Result := True;\n  end;\nend;\n\nfunction FindImageFileFormatByExt(const Ext: string): TImageFileFormat;\nvar\n  I: LongInt;\nbegin\n  Result := nil;\n  for I := ImageFileFormats.Count - 1 downto 0 do\n    if TImageFileFormat(ImageFileFormats[I]).Extensions.IndexOf(Ext) >= 0 then\n    begin\n      Result := TImageFileFormat(ImageFileFormats[I]);\n      Exit;\n    end;\nend;\n\nfunction FindImageFileFormatByName(const FileName: string): TImageFileFormat;\nvar\n  I: LongInt;\nbegin\n  Result := nil;\n  for I := ImageFileFormats.Count - 1 downto 0 do\n    if TImageFileFormat(ImageFileFormats[I]).TestFileName(FileName) then\n    begin\n      Result := TImageFileFormat(ImageFileFormats[I]);\n      Exit;\n    end;\nend;\n\nfunction FindImageFileFormatByClass(AClass: TImageFileFormatClass): TImageFileFormat;\nvar\n  I: LongInt;\nbegin\n  Result := nil;\n  for I := 0 to ImageFileFormats.Count - 1 do\n    if TImageFileFormat(ImageFileFormats[I]) is AClass then\n    begin\n      Result := TObject(ImageFileFormats[I]) as TImageFileFormat;\n      Break;\n    end;\nend;\n\nfunction GetFileFormatCount: LongInt;\nbegin\n  Result := ImageFileFormats.Count;\nend;\n\nfunction GetFileFormatAtIndex(Index: LongInt): TImageFileFormat;\nbegin\n  if (Index >= 0) and (Index < ImageFileFormats.Count) then\n    Result := TImageFileFormat(ImageFileFormats[Index])\n  else\n    Result := nil;\nend;\n\nfunction GetImageFileFormatsFilter(OpenFileFilter: Boolean): string;\nvar\n  I, J, Count: LongInt;\n  Descriptions: string;\n  Filters, CurFilter: string;\n  FileFormat: TImageFileFormat;\nbegin\n  Descriptions := '';\n  Filters := '';\n  Count := 0;\n\n  for I := 0 to ImageFileFormats.Count - 1 do\n  begin\n    FileFormat := TObject(ImageFileFormats[I]) as TImageFileFormat;\n\n    // If we are creating filter for save dialog and this format cannot save\n    // files the we skip it\n    if not OpenFileFilter and not FileFormat.CanSave then\n      Continue;\n\n    CurFilter := '';\n    for J := 0 to FileFormat.Masks.Count - 1 do\n    begin\n      CurFilter := CurFilter + FileFormat.Masks[J];\n      if J < FileFormat.Masks.Count - 1 then\n        CurFilter := CurFilter + ';';\n    end;\n\n    FmtStr(Descriptions, '%s%s (%s)|%2:s', [Descriptions, FileFormat.Name, CurFilter]);\n    if Filters <> '' then\n      FmtStr(Filters, '%s;%s', [Filters, CurFilter])\n    else\n      Filters := CurFilter;\n\n    if I < ImageFileFormats.Count - 1 then\n        Descriptions := Descriptions + '|';\n\n    Inc(Count);\n  end;\n\n  if (Count > 1) and OpenFileFilter then\n    FmtStr(Descriptions, '%s (%s)|%1:s|%s', [SAllFilter, Filters, Descriptions]);\n\n  Result := Descriptions;\nend;\n\nfunction GetFilterIndexExtension(Index: LongInt; OpenFileFilter: Boolean): string;\nvar\n  I, Count: LongInt;\n  FileFormat: TImageFileFormat;\nbegin\n  // -1 because filter indices are in 1..n range\n  Index := Index - 1;\n  Result := '';\n  if OpenFileFilter then\n  begin\n    if Index > 0 then\n      Index := Index - 1;\n  end;\n\n  if (Index >= 0) and (Index < ImageFileFormats.Count) then\n  begin\n    Count := 0;\n    for I := 0 to ImageFileFormats.Count - 1 do\n    begin\n      FileFormat := TObject(ImageFileFormats[I]) as TImageFileFormat;\n      if not OpenFileFilter and not FileFormat.CanSave then\n        Continue;\n      if Index = Count then\n      begin\n        if FileFormat.Extensions.Count > 0 then\n          Result := FileFormat.Extensions[0];\n        Exit;\n      end;\n      Inc(Count);\n    end;\n  end;\nend;\n\nfunction GetFileNameFilterIndex(const FileName: string; OpenFileFilter: Boolean): LongInt;\nvar\n  I: LongInt;\n  FileFormat: TImageFileFormat;\nbegin\n  Result := 0;\n  for I := 0 to ImageFileFormats.Count - 1 do\n  begin\n    FileFormat := TObject(ImageFileFormats[I]) as TImageFileFormat;\n    if not OpenFileFilter and not FileFormat.CanSave then\n      Continue;\n    if FileFormat.TestFileName(FileName) then\n    begin\n      // +1 because filter indices are in 1..n range\n      Inc(Result);\n      if OpenFileFilter then\n        Inc(Result);\n      Exit;\n    end;\n    Inc(Result);\n  end;\n  Result := -1;\nend;\n\nfunction GetIO: TIOFunctions;\nbegin\n  Result := IO;\nend;\n\nprocedure RaiseImaging(const Msg: string; const Args: array of const);\nvar\n  WholeMsg: string;\nbegin\n  WholeMsg := Msg;\n  if GetExceptObject <> nil then\n  begin\n    WholeMsg := WholeMsg + ' ' + SExceptMsg + ': ' +\n      GetExceptObject.Message;\n  end;\n  raise EImagingError.CreateFmt(WholeMsg, Args);\nend;\n\nprocedure RaiseImaging(const Msg: string);\nbegin\n  RaiseImaging(Msg, []);\nend;\n\n{ Internal unit functions }\n\nfunction CheckOptionValue(OptionId, Value: LongInt): LongInt;\nbegin\n  case OptionId of\n    ImagingColorReductionMask:\n      Result := ClampInt(Value, 0, $FF);\n    ImagingLoadOverrideFormat, ImagingSaveOverrideFormat:\n      Result := Iff(ImagingFormats.IsImageFormatValid(TImageFormat(Value)),\n        Value, LongInt(ifUnknown));\n    ImagingMipMapFilter: Result := ClampInt(Value, Ord(Low(TSamplingFilter)),\n        Ord(High(TSamplingFilter)));\n  else\n    Result := Value;\n  end;\nend;\n\nprocedure SetFileIO;\nbegin\n  IO := FileIO;\nend;\n\nprocedure SetStreamIO;\nbegin\n  IO := StreamIO;\nend;\n\nprocedure SetMemoryIO;\nbegin\n  IO := MemoryIO;\nend;\n\nprocedure InitImageFormats;\nbegin\n  ImagingFormats.InitImageFormats(ImageFormatInfos);\nend;\n\nprocedure FreeImageFileFormats;\nvar\n  I: LongInt;\nbegin\n  if ImageFileFormats <> nil then\n    for I := 0 to ImageFileFormats.Count - 1 do\n      TImageFileFormat(ImageFileFormats[I]).Free;\n  FreeAndNil(ImageFileFormats);\nend;\n\nprocedure InitOptions;\nbegin\n  SetLength(Options, InitialOptions);\n  OptionStack := TOptionStack.Create;\nend;\n\nprocedure FreeOptions;\nbegin\n  SetLength(Options, 0);\n  FreeAndNil(OptionStack);\nend;\n\n{\n  TImageFileFormat class implementation\n}\n\nconstructor TImageFileFormat.Create(AMetadata: TMetadata);\nbegin\n  inherited Create;\n  FName := SUnknownFormat;\n  FExtensions := TStringList.Create;\n  FMasks := TStringList.Create;\n  if AMetadata = nil then\n    FMetadata := GlobalMetadata\n  else\n    FMetadata := AMetadata;\n  Define;\nend;\n\ndestructor TImageFileFormat.Destroy;\nbegin\n  FExtensions.Free;\n  FMasks.Free;\n  inherited Destroy;\nend;\n\nprocedure TImageFileFormat.Define;\nbegin\nend;\n\nfunction TImageFileFormat.PrepareLoad(Handle: TImagingHandle;\n  var Images: TDynImageDataArray; OnlyFirstFrame: Boolean): Boolean;\nbegin\n  FMetadata.ClearMetaItems; // Clear old metadata\n  FreeImagesInArray(Images);\n  SetLength(Images, 0);\n  Result := Handle <> nil;\nend;\n\nfunction TImageFileFormat.PostLoadCheck(var Images: TDynImageDataArray;\n  LoadResult: Boolean): Boolean;\nvar\n  I: LongInt;\nbegin\n  if not LoadResult then\n  begin\n    FreeImagesInArray(Images);\n    SetLength(Images, 0);\n    Result := False;\n  end\n  else\n  begin\n    Result := (Length(Images) > 0) and TestImagesInArray(Images);\n\n    if Result then\n    begin\n      // Convert to overriden format if it is set\n      if LoadOverrideFormat <> ifUnknown then\n        for I := Low(Images) to High(Images) do\n          ConvertImage(Images[I], LoadOverrideFormat);\n    end;\n  end;\nend;\n\nfunction TImageFileFormat.PrepareSave(Handle: TImagingHandle;\n  const Images: TDynImageDataArray; var Index: Integer): Boolean;\nvar\n  Len, I: LongInt;\nbegin\n  CheckOptionsValidity;\n  Result := False;\n  if CanSave then\n  begin\n    Len := Length(Images);\n    Assert(Len > 0);\n\n    // If there are no images to be saved exit\n    if Len = 0 then Exit;\n\n    // Check index of image to be saved (-1 as index means save all images)\n    if IsMultiImageFormat then\n    begin\n      if (Index >= Len) then\n        Index := 0;\n\n      if Index < 0 then\n      begin\n        Index := 0;\n        FFirstIdx := 0;\n        FLastIdx := Len - 1;\n      end\n      else\n      begin\n        FFirstIdx := Index;\n        FLastIdx := Index;\n      end;\n\n      for I := FFirstIdx to FLastIdx - 1 do\n      begin\n        if not TestImage(Images[I]) then\n          Exit;\n      end;\n    end\n    else\n    begin\n      if (Index >= Len) or (Index < 0) then\n        Index := 0;\n      if not TestImage(Images[Index]) then\n        Exit;\n    end;\n\n    Result := True;\n  end;\nend;\n\nprocedure TImageFileFormat.AddMasks(const AMasks: string);\nvar\n  I: LongInt;\n  Ext: string;\nbegin\n  FExtensions.Clear;\n  FMasks.CommaText := AMasks;\n  FMasks.Delimiter := ';';\n\n  for I := 0 to FMasks.Count - 1 do\n  begin\n    FMasks[I] := Trim(FMasks[I]);\n    Ext := GetFileExt(FMasks[I]);\n    if (Ext <> '') and (Ext <> '*') then\n      FExtensions.Add(Ext);\n  end;\nend;\n\nfunction TImageFileFormat.GetFormatInfo(Format: TImageFormat): TImageFormatInfo;\nbegin\n  Result := ImageFormatInfos[Format]^;\nend;\n\nfunction TImageFileFormat.GetSupportedFormats: TImageFormats;\nbegin\n  Result := FSupportedFormats;\nend;\n\nfunction TImageFileFormat.LoadData(Handle: TImagingHandle;\n  var Images: TDynImageDataArray; OnlyFirstFrame: Boolean): Boolean;\nbegin\n  Result := False;\n  RaiseImaging(SFileFormatCanNotLoad, [FName]);\nend;\n\nfunction TImageFileFormat.SaveData(Handle: TImagingHandle;\n  const Images: TDynImageDataArray; Index: LongInt): Boolean;\nbegin\n  Result := False;\n  RaiseImaging(SFileFormatCanNotSave, [FName]);\nend;\n\nprocedure TImageFileFormat.ConvertToSupported(var Image: TImageData;\n  const Info: TImageFormatInfo);\nbegin\nend;\n\nfunction TImageFileFormat.IsSupported(const Image: TImageData): Boolean;\nbegin\n  Result := Image.Format in GetSupportedFormats;\nend;\n\nfunction TImageFileFormat.LoadFromFile(const FileName: string;\n  var Images: TDynImageDataArray; OnlyFirstLevel: Boolean): Boolean;\nvar\n  Handle: TImagingHandle;\nbegin\n  Result := False;\n  if CanLoad then\n  try\n    // Set IO ops to file ops and open given file\n    SetFileIO;\n    Handle := IO.Open(PChar(FileName), omReadOnly);\n    try\n      // Test if file contains valid image and if so then load it\n      if TestFormat(Handle) then\n      begin\n        Result := PrepareLoad(Handle, Images, OnlyFirstLevel) and\n          LoadData(Handle, Images, OnlyFirstlevel);\n        Result := PostLoadCheck(Images, Result);\n      end\n      else\n        RaiseImaging(SFileNotValid, [FileName, Name]);\n    finally\n      IO.Close(Handle);\n    end;\n  except\n    RaiseImaging(SErrorLoadingFile, [FileName, FExtensions[0]]);\n  end;\nend;\n\nfunction TImageFileFormat.LoadFromStream(Stream: TStream;\n  var Images: TDynImageDataArray; OnlyFirstLevel: Boolean): Boolean;\nvar\n  Handle: TImagingHandle;\n  OldPosition: Int64;\nbegin\n  Result := False;\n  OldPosition := Stream.Position;\n  if CanLoad then\n  try\n    // Set IO ops to stream ops and \"open\" given memory\n    SetStreamIO;\n    Handle := IO.Open(Pointer(Stream), omReadOnly);\n    try\n      // Test if stream contains valid image and if so then load it\n      if TestFormat(Handle) then\n      begin\n        Result := PrepareLoad(Handle, Images, OnlyFirstLevel) and\n          LoadData(Handle, Images, OnlyFirstlevel);\n        Result := PostLoadCheck(Images, Result);\n      end\n      else\n        RaiseImaging(SStreamNotValid, [@Stream, Name]);\n    finally\n      IO.Close(Handle);\n    end;\n  except\n    Stream.Position := OldPosition;\n    FreeImagesInArray(Images);\n    RaiseImaging(SErrorLoadingStream, [@Stream, FExtensions[0]]);\n  end;\nend;\n\nfunction TImageFileFormat.LoadFromMemory(Data: Pointer; Size: LongInt; var\n  Images: TDynImageDataArray; OnlyFirstLevel: Boolean): Boolean;\nvar\n  Handle: TImagingHandle;\n  IORec: TMemoryIORec;\nbegin\n  Result := False;\n  if CanLoad then\n  try\n    // Set IO ops to memory ops and \"open\" given memory\n    SetMemoryIO;\n    IORec := PrepareMemIO(Data, Size);\n    Handle := IO.Open(@IORec,omReadOnly);\n    try\n      // Test if memory contains valid image and if so then load it\n      if TestFormat(Handle) then\n      begin\n        Result := PrepareLoad(Handle, Images, OnlyFirstLevel) and\n          LoadData(Handle, Images, OnlyFirstlevel);\n        Result := PostLoadCheck(Images, Result);\n      end\n      else\n        RaiseImaging(SMemoryNotValid, [Data, Size, Name]);\n    finally\n      IO.Close(Handle);\n    end;\n  except\n    RaiseImaging(SErrorLoadingMemory, [Data, Size, FExtensions[0]]);\n  end;\nend;\n\nfunction TImageFileFormat.SaveToFile(const FileName: string;\n  const Images: TDynImageDataArray; OnlyFirstLevel: Boolean): Boolean;\nvar\n  Handle: TImagingHandle;\n  Len, Index, I: LongInt;\n  Ext, FName: string;\nbegin\n  Result := False;\n  if CanSave and TestImagesInArray(Images) then\n  try\n    SetFileIO;\n    Len := Length(Images);\n    if IsMultiImageFormat or\n      (not IsMultiImageFormat and (OnlyFirstLevel or (Len = 1))) then\n    begin\n      Handle := IO.Open(PChar(FileName), GetSaveOpenMode);\n      try\n        if OnlyFirstLevel then\n          Index := 0\n        else\n          Index := -1;\n        // Write multi image to one file\n        Result := PrepareSave(Handle, Images, Index) and SaveData(Handle, Images, Index);\n      finally\n        IO.Close(Handle);\n      end;\n    end\n    else\n    begin\n      // Write multi image to file sequence\n      Ext := ExtractFileExt(FileName);\n      FName := ChangeFileExt(FileName, '');\n      Result := True;\n      for I := 0 to Len - 1 do\n      begin\n        Handle := IO.Open(PChar(Format(FName + '%.3d' + Ext, [I])), GetSaveOpenMode);\n        try\n          Index := I;\n          Result := Result and PrepareSave(Handle, Images, Index) and\n            SaveData(Handle, Images, Index);\n          if not Result then\n            Break;\n        finally\n          IO.Close(Handle);\n        end;\n      end;\n    end;\n  except\n    raise UpdateExceptMessage(GetExceptObject, SErrorSavingFile, [FileName, FExtensions[0]]);\n  end;\nend;\n\nfunction TImageFileFormat.SaveToStream(Stream: TStream;\n  const Images: TDynImageDataArray; OnlyFirstLevel: Boolean): Boolean;\nvar\n  Handle: TImagingHandle;\n  Len, Index, I: LongInt;\n  OldPosition: Int64;\nbegin\n  Result := False;\n  OldPosition := Stream.Position;\n  if CanSave and TestImagesInArray(Images) then\n  try\n    SetStreamIO;\n    Handle := IO.Open(PChar(Stream), GetSaveOpenMode);\n    try\n      if IsMultiImageFormat or OnlyFirstLevel then\n      begin\n        if OnlyFirstLevel then\n          Index := 0\n        else\n          Index := -1;\n        // Write multi image in one run\n        Result := PrepareSave(Handle, Images, Index) and SaveData(Handle, Images, Index);\n      end\n      else\n      begin\n        // Write multi image to sequence\n        Result := True;\n        Len := Length(Images);\n        for I := 0 to Len - 1 do\n        begin\n          Index := I;\n          Result := Result and PrepareSave(Handle, Images, Index) and\n            SaveData(Handle, Images, Index);\n          if not Result then\n            Break;\n        end;\n      end;\n    finally\n      IO.Close(Handle);\n    end;\n  except\n    Stream.Position := OldPosition;\n    raise UpdateExceptMessage(GetExceptObject, SErrorSavingStream, [@Stream, FExtensions[0]]);\n  end;\nend;\n\nfunction TImageFileFormat.SaveToMemory(Data: Pointer; var Size: LongInt;\n  const Images: TDynImageDataArray; OnlyFirstLevel: Boolean): Boolean;\nvar\n  Handle: TImagingHandle;\n  Len, Index, I: LongInt;\n  IORec: TMemoryIORec;\nbegin\n  Result := False;\n  if CanSave and TestImagesInArray(Images) then\n  try\n    SetMemoryIO;\n    IORec := PrepareMemIO(Data, Size);\n    Handle := IO.Open(PChar(@IORec), GetSaveOpenMode);\n    try\n      if IsMultiImageFormat or OnlyFirstLevel then\n      begin\n        if OnlyFirstLevel then\n          Index := 0\n        else\n          Index := -1;\n        // Write multi image in one run\n        Result := PrepareSave(Handle, Images, Index) and SaveData(Handle, Images, Index);\n      end\n      else\n      begin\n        // Write multi image to sequence\n        Result := True;\n        Len := Length(Images);\n        for I := 0 to Len - 1 do\n        begin\n          Index := I;\n          Result := Result and PrepareSave(Handle, Images, Index) and\n            SaveData(Handle, Images, Index);\n          if not Result then\n            Break;\n        end;\n      end;\n      Size := IORec.Position;\n    finally\n      IO.Close(Handle);\n    end;\n  except\n    raise UpdateExceptMessage(GetExceptObject, SErrorSavingMemory, [Data, Size, FExtensions[0]]);\n  end;\nend;\n\nfunction TImageFileFormat.MakeCompatible(const Image: TImageData;\n  var Compatible: TImageData; out MustBeFreed: Boolean): Boolean;\nbegin\n  InitImage(Compatible);\n\n  if SaveOverrideFormat <> ifUnknown then\n  begin\n    // Save format override is active. Clone input and convert it to override format.\n    CloneImage(Image, Compatible);\n    ConvertImage(Compatible, SaveOverrideFormat);\n    // Now check if override format is supported by file format. If it is not\n    // then file format specific conversion (virtual method) is called.\n    Result := IsSupported(Compatible);\n    if not Result then\n    begin\n      ConvertToSupported(Compatible, GetFormatInfo(Compatible.Format));\n      Result := IsSupported(Compatible);\n    end;\n  end     // Add IsCompatible function! not only checking by Format\n  else if IsSupported(Image) then\n  begin\n    // No save format override and input is in format supported by this\n    // file format. Just copy Image's fields to Compatible\n    Compatible := Image;\n    Result := True;\n  end\n  else\n  begin\n    // No override and input's format is not compatible with file format.\n    // Clone it and the call file format specific conversion (virtual method).\n    CloneImage(Image, Compatible);\n    ConvertToSupported(Compatible, GetFormatInfo(Compatible.Format));\n    Result := IsSupported(Compatible);\n  end;\n  // Tell the user that he must free Compatible after he's done with it\n  // (if necessary).\n  MustBeFreed := Image.Bits <> Compatible.Bits;\nend;\n\nfunction TImageFileFormat.TestFormat(Handle: TImagingHandle): Boolean;\nbegin\n  Result := False;\nend;\n\nfunction TImageFileFormat.TestFileName(const FileName: string): Boolean;\nvar\n  I: LongInt;\n  OnlyName: string;\nbegin\n  OnlyName := ExtractFileName(FileName);\n  // For each mask test if filename matches it \n  for I := 0 to FMasks.Count - 1 do\n    if StrMaskMatch(OnlyName, FMasks[I], False) then\n    begin\n      Result := True;\n      Exit;\n    end;\n  Result := False;\nend;\n\nprocedure TImageFileFormat.CheckOptionsValidity;\nbegin\nend;\n\nfunction TImageFileFormat.GetCanLoad: Boolean;\nbegin\n  Result := ffLoad in FFeatures;\nend;\n\nfunction TImageFileFormat.GetCanSave: Boolean;\nbegin\n  Result := ffSave in FFeatures;\nend;\n\nfunction TImageFileFormat.GetIsMultiImageFormat: Boolean;\nbegin\n  Result := ffMultiImage in FFeatures;\nend;\n\nfunction TImageFileFormat.GetSaveOpenMode: TOpenMode;\nbegin\n  // TODO: fix\n  //if ffReadOnSave in FFeatures then\n  //  Result := omReadWrite\n  //else\n    Result := omCreate;\nend;\n\n{ TOptionStack  class implementation }\n\nconstructor TOptionStack.Create;\nbegin\n  inherited Create;\n  FPosition := -1;\nend;\n\ndestructor TOptionStack.Destroy;\nvar\n  I: LongInt;\nbegin\n  for I := 0 to OptionStackDepth - 1 do\n    SetLength(FStack[I], 0);\n  inherited Destroy;\nend;\n\nfunction TOptionStack.Pop: Boolean;\nvar\n  I: LongInt;\nbegin\n  Result := False;\n  if FPosition >= 0  then\n  begin\n    SetLength(Options, Length(FStack[FPosition]));\n    for I := 0 to Length(FStack[FPosition]) - 1 do\n      if Options[I] <> nil then\n        Options[I]^ := FStack[FPosition, I];\n    Dec(FPosition);\n    Result := True;\n  end;\nend;\n\nfunction TOptionStack.Push: Boolean;\nvar\n  I: LongInt;\nbegin\n  Result := False;\n  if FPosition < OptionStackDepth - 1 then\n  begin\n    Inc(FPosition);\n    SetLength(FStack[FPosition], Length(Options));\n    for I := 0 to Length(Options) - 1 do\n      if Options[I] <> nil then\n        FStack[FPosition, I] := Options[I]^;\n    Result := True;\n  end;\nend;\n\n{ TMetadata }\n\nprocedure TMetadata.SetMetaItem(const Id: string; const Value: Variant;\n  ImageIndex: Integer);\nbegin\n  AddMetaToList(FLoadMetaItems, Id, Value, ImageIndex);\nend;\n\nprocedure TMetadata.SetMetaItemForSaving(const Id: string; const Value: Variant;\n  ImageIndex: Integer);\nbegin\n  AddMetaToList(FSaveMetaItems, Id, Value, ImageIndex);\nend;\n\nprocedure TMetadata.AddMetaToList(List: TStringList; const Id: string;\n  const Value: Variant; ImageIndex: Integer);\nvar\n  Item: TMetadataItem;\n  Idx: Integer;\n  FullId: string;\nbegin\n  FullId := GetMetaItemName(Id, ImageIndex);\n  if List.Find(FullId, Idx) then\n    (List.Objects[Idx] as TMetadataItem).Value := Value\n  else\n  begin\n    Item := TMetadataItem.Create;\n    Item.Id := Id;\n    Item.ImageIndex := ImageIndex;\n    Item.Value := Value;\n    List.AddObject(FullId, Item);\n  end;\nend;\n\nprocedure TMetadata.ClearMetaItems;\nbegin\n  ClearMetaList(FLoadMetaItems);\nend;\n\nprocedure TMetadata.ClearMetaItemsForSaving;\nbegin\n  ClearMetaList(FSaveMetaItems);\nend;\n\nprocedure TMetadata.ClearMetaList(List: TStringList);\nvar\n  I: Integer;\nbegin\n  for I := 0 to List.Count - 1 do\n    List.Objects[I].Free;\n  List.Clear;\nend;\n\nprocedure TMetadata.CopyLoadedMetaItemsForSaving;\nvar\n  I: Integer;\n  Copy, Orig: TMetadataItem;\nbegin\n  ClearMetaItemsForSaving;\n  for I := 0 to FLoadMetaItems.Count - 1 do\n  begin\n    Orig := TMetadataItem(FLoadMetaItems.Objects[I]);\n    Copy := TMetadataItem.Create;\n    Copy.Id := Orig.Id;\n    Copy.ImageIndex := Orig.ImageIndex;\n    Copy.Value := Orig.Value;\n    FSaveMetaItems.AddObject(GetMetaItemName(Copy.Id, Copy.ImageIndex), Copy);\n  end;\nend;\n\nconstructor TMetadata.Create;\nbegin\n  inherited;\n  FLoadMetaItems := TStringList.Create;\n  FLoadMetaItems.Sorted := True;\n  FSaveMetaItems := TStringList.Create;\n  FSaveMetaItems.Sorted := True;\nend;\n\ndestructor TMetadata.Destroy;\nbegin\n  ClearMetaItems;\n  ClearMetaItemsForSaving;\n  FLoadMetaItems.Free;\n  FSaveMetaItems.Free;\n  inherited;\nend;\n\nfunction TMetadata.GetMetaById(const Id: string): Variant;\nvar\n  Idx: Integer;\nbegin\n  if FLoadMetaItems.Find(Id, Idx) then\n    Result := (FLoadMetaItems.Objects[Idx] as TMetadataItem).Value\n  else\n    Result := Variants.Null;\nend;\n\nfunction TMetadata.GetMetaByIdMulti(const Id: string; ImageIndex: Integer): Variant;\nbegin\n  Result := GetMetaById(GetMetaItemName(Id, ImageIndex));\nend;\n\nfunction TMetadata.GetSaveMetaById(const Id: string): Variant;\nvar\n  Idx: Integer;\nbegin\n  if FSaveMetaItems.Find(Id, Idx) then\n    Result := (FSaveMetaItems.Objects[Idx] as TMetadataItem).Value\n  else\n    Result := Variants.Null;\nend;\n\nfunction TMetadata.GetSaveMetaByIdMulti(const Id: string;\n  ImageIndex: Integer): Variant;\nbegin\n  Result := GetSaveMetaById(GetMetaItemName(Id, ImageIndex));\nend;\n\nfunction TMetadata.GetMetaByIdx(Index: Integer): TMetadataItem;\nbegin\n  Result := FLoadMetaItems.Objects[Index] as TMetadataItem;\nend;\n\nfunction TMetadata.GetMetaCount: Integer;\nbegin\n  Result := FLoadMetaItems.Count;\nend;\n\nfunction TMetadata.GetMetaItemName(const Id: string;\n  ImageIndex: Integer): string;\nbegin\n  Result := Iff(ImageIndex = 0, Id, Format(SMetaIdForSubImage, [Id, ImageIndex]));\nend;\n\nfunction TMetadata.GetPhysicalPixelSize(ResUnit: TResolutionUnit; var XSize,\n  YSize: Single; MetaForSave: Boolean; ImageIndex: Integer): Boolean;\ntype\n  TGetter = function(const Id: string; ImageIndex: Integer): Variant of object;\nvar\n  Getter: TGetter;\n  XMeta, YMeta: Variant;\nbegin\n  if MetaForSave then\n    Getter := GetSaveMetaByIdMulti\n  else\n    Getter := GetMetaByIdMulti;\n\n  XMeta := Getter(SMetaPhysicalPixelSizeX, ImageIndex);\n  YMeta := Getter(SMetaPhysicalPixelSizeY, ImageIndex);\n  XSize := -1;\n  YSize := -1;\n\n  Result := not VarIsNull(XMeta) or not VarIsNull(YMeta);\n\n  if not Result then\n    Exit;\n\n  if not VarIsNull(XMeta) then\n    XSize := XMeta;\n  if not VarIsNull(YMeta) then\n    YSize := YMeta;\n\n  if XSize < 0 then\n    XSize := YSize;\n  if YSize < 0 then\n    YSize := XSize;\n\n  TranslateUnits(ResUnit, XSize, YSize);\nend;\n\nprocedure TMetadata.SetPhysicalPixelSize(ResUnit: TResolutionUnit; XSize,\n  YSize: Single; MetaForSave: Boolean; ImageIndex: Integer);\ntype\n  TAdder = procedure(const Id: string; const Value: Variant; ImageIndex: Integer) of object;\nvar\n  Adder: TAdder;\nbegin\n  TranslateUnits(ResUnit, XSize, YSize);\n\n  if MetaForSave then\n    Adder := SetMetaItemForSaving\n  else\n    Adder := SetMetaItem;\n\n  Adder(SMetaPhysicalPixelSizeX, XSize, ImageIndex);\n  Adder(SMetaPhysicalPixelSizeY, YSize, ImageIndex);\nend;\n\nprocedure TMetadata.TranslateUnits(ResolutionUnit: TResolutionUnit; var XRes,\n  YRes: Single);\nvar\n  UnitSize: Single;\nbegin\n  case ResolutionUnit of\n    ruDpi: UnitSize := 25400;\n    ruDpm: UnitSize := 1e06;\n    ruDpcm: UnitSize := 1e04;\n  else\n    UnitSize := 1;\n  end;\n  if ResolutionUnit <> ruSizeInMicroMeters then\n  begin\n    XRes := UnitSize / XRes;\n    YRes := UnitSize / YRes;\n  end;\nend;\n\nfunction TMetadata.HasMetaItem(const Id: string; ImageIndex: Integer): Boolean;\nbegin\n  Result := GetMetaByIdMulti(Id, ImageIndex) <> Variants.Null;\nend;\n\nfunction TMetadata.HasMetaItemForSaving(const Id: string; ImageIndex: Integer): Boolean;\nbegin\n  Result := GetSaveMetaByIdMulti(Id, ImageIndex) <> Variants.Null;\nend;\n\ninitialization\n{$IFDEF MEMCHECK}\n  {$IF CompilerVersion >= 18}\n    System.ReportMemoryLeaksOnShutdown := True;\n  {$IFEND}\n{$ENDIF}\n  if GlobalMetadata = nil then\n    GlobalMetadata := TMetadata.Create;\n  if ImageFileFormats = nil then\n    ImageFileFormats := TList.Create;\n  InitImageFormats;\n  RegisterOption(ImagingColorReductionMask, @ColorReductionMask);\n  RegisterOption(ImagingLoadOverrideFormat, @LoadOverrideFormat);\n  RegisterOption(ImagingSaveOverrideFormat, @SaveOverrideFormat);\n  RegisterOption(ImagingMipMapFilter, @MipMapFilter);\n  RegisterOption(ImagingBinaryTreshold, @BinaryTreshold);\nfinalization\n  FreeOptions;\n  FreeImageFileFormats;\n  GlobalMetadata.Free;\n\n{\n  File Notes:\n\n  -- TODOS ----------------------------------------------------\n    - nothing now\n\n  -- 0.77.1 ---------------------------------------------------\n    - Updated IO Open functions according to changes in ImagingTypes.\n    - Fixed bug in SplitImage that could cause wrong size of edge chunks.\n    - Metadata support fixes and extensions (frame delays, animation loops).\n\n  -- 0.26.5 Changes/Bug Fixes ---------------------------------\n    - Started reworking exception raising to keep the original class type\n      (e.g. in NewImage EOutOfMemory could be raised but was hidden\n      by EImagingError raised afterwards in NewImage try/except).\n    - Fixed possible AV in Rotate45 subproc of RotateImage.\n    - Added ReadRawXXX and WriteRawXXX functions for raw image bits IO.\n    - Implemented ImagingBinaryTreshold option.\n    - Added support for simple image metadata loading/saving.\n    - Moved file format definition (name, exts, caps, ...) from\n      constructor to new Define method.\n    - Fixed some memory leaks caused by failures during image loading.\n\n  -- 0.26.3 Changes/Bug Fixes ---------------------------------\n    - Extended RotateImage to allow arbitrary angle rotations.\n    - Reversed the order file formats list is searched so\n      if you register a new one it will be found sooner than\n      built in formats.\n    - Fixed memory leak in ResizeImage ocurring when resizing\n      indexed images.\n\n  -- 0.26.1 Changes/Bug Fixes ---------------------------------\n    - Added position/size checks to LoadFromStream functions.\n    - Changed conditional compilation in impl. uses section to reflect changes\n      in LINK symbols.\n\n  -- 0.24.3 Changes/Bug Fixes ---------------------------------\n    - GenerateMipMaps now generates all smaller levels from\n      original big image (better results when using more advanced filters).\n      Also conversion to compatible image format is now done here not\n      in FillMipMapLevel (that is called for every mipmap level).\n\n  -- 0.23 Changes/Bug Fixes -----------------------------------\n    - MakePaletteForImages now works correctly for indexed and special format images\n    - Fixed bug in StretchRect: Image was not properly stretched if\n      src and dst dimensions differed only in height.\n    - ConvertImage now fills new image with zeroes to avoid random data in\n      some conversions (RGB->XRGB)\n    - Changed RegisterOption procedure to function\n    - Changed bunch of palette functions from low level interface to procedure\n      (there was no reason for them to be functions).\n    - Changed FreeImage and FreeImagesInArray functions to procedures.\n    - Added many assertions, come try-finally, other checks, and small code\n      and doc changes.\n\n  -- 0.21 Changes/Bug Fixes -----------------------------------\n    - GenerateMipMaps threw failed assertion when input was indexed or special,\n      fixed.\n    - Added CheckOptionsValidity to TImageFileFormat and its decendants.\n    - Unit ImagingExtras which registers file formats in Extras package\n      is now automatically added to uses clause if LINK_EXTRAS symbol is\n      defined in ImagingOptions.inc file.\n    - Added EnumFileFormats function to low level interface.\n    - Fixed bug in SwapChannels which could cause AV when swapping alpha\n      channel of A8R8G8B8 images.\n    - Converting loaded images to ImagingOverrideFormat is now done\n      in PostLoadCheck method to avoid code duplicity.\n    - Added GetFileFormatCount and GetFileFormatAtIndex functions\n    - Bug in ConvertImage: if some format was converted to similar format\n      only with swapped channels (R16G16B16<>B16G16R16) then channels were\n      swapped correctly but new data format (swapped one) was not set.\n    - Made TImageFileFormat.MakeCompatible public non-virtual method\n      (and modified its function). Created new virtual\n      ConvertToSupported which should be overriden by descendants.\n      Main reason for doint this is to avoid duplicate code that was in all\n      TImageFileFormat's descendants.\n    - Changed TImageFileFormat.GetFormatInfo's result type to TImageFormatInfo.\n    - Split overloaded FindImageFileFormat functions to\n      FindImageFileFormatByClass and FindImageFileFormatByExt and created new\n      FindImageFileFormatByName which operates on whole filenames.\n    - Function GetExtensionFilterIndex renamed to GetFileNameFilterIndex\n      (because it now works with filenames not extensions).\n    - DetermineFileFormat now first searches by filename and if not found\n      then by data.\n    - Added TestFileName method to TImageFileFormat.\n    - Updated GetImageFileFormatsFilter to uses Masks instead of Extensions\n      property of TImageFileFormat. Also you can now request\n      OpenDialog and SaveDialog type filters\n    - Added Masks property and AddMasks method to TImageFileFormat.\n      AddMasks replaces AddExtensions, it uses filename masks instead\n      of sime filename extensions to identify supported files.\n    - Changed TImageFileFormat.LoadData procedure to function and\n      moved varios duplicate code from its descandats (check index,...)\n      here to TImageFileFormat helper methods.\n    - Changed TImageFileFormat.SaveData procedure to function and\n      moved varios duplicate code from its descandats (check index,...)\n      here to TImageFileFormat helper methods.\n    - Removed RAISE_EXCEPTIONS define, exceptions are now raised everytime\n    - Added MustBeFreed parameter to TImageFileFormat.MakeComptible method\n      that indicates that compatible image returned by this method must be\n      freed after its usage.\n\n  -- 0.19 Changes/Bug Fixes -----------------------------------\n    - fixed bug in NewImage: if given format was ifDefault it wasn't\n      replaced with DefaultImageFormat constant which caused problems later\n      in other units \n    - fixed bug in RotateImage which caused that rotated special format\n      images were whole black\n    - LoadImageFromXXX and LoadMultiImageFromXXX now use DetermineXXXFormat\n      when choosing proper loader, this eliminated need for Ext parameter\n      in stream and memory loading functions\n    - added GetVersionStr function\n    - fixed bug in ResizeImage which caued indexed images to lose their\n      palette during process resulting in whole black image\n    - Clipping in ...Rect functions now uses clipping procs from ImagingUtility,\n      it also works better\n    - FillRect optimization for 8, 16, and 32 bit formats\n    - added pixel set/get functions to low level interface:\n      GetPixelDirect, SetPixelDirect, GetPixel32, SetPixel32,\n      GetPixelFP, SetPixelFP\n    - removed GetPixelBytes low level intf function - redundant\n      (same data can be obtained by GetImageFormatInfo)\n    - made small changes in many parts of library to compile\n      on AMD64 CPU (Linux with FPC)\n    - changed InitImage to procedure (function was pointless)\n    - Method TestFormat of TImageFileFormat class made public\n      (was protected)\n    - added function IsFileFormatSupported to low level interface\n      (contributed by Paul Michell)\n    - fixed some missing format arguments from error strings\n      which caused Format function to raise exception\n    - removed forgotten debug code that disabled filtered resizing of images with\n      channel bitcounts > 8\n\n  -- 0.17 Changes/Bug Fixes -----------------------------------\n    - changed order of parameters of CopyRect function\n    - GenerateMipMaps now filters mipmap levels\n    - ResizeImage functions was extended to allow bilinear and bicubic filtering\n    - added StretchRect function to low level interface\n    - added functions GetImageFileFormatsFilter, GetFilterIndexExtension,\n      and GetExtensionFilterIndex\n\n  -- 0.15 Changes/Bug Fixes -----------------------------------\n    - added function RotateImage to low level interface\n    - moved TImageFormatInfo record and types required by it to\n      ImagingTypes unit, changed GetImageFormatInfo low level\n      interface function to return TImageFormatInfo instead of short info\n    - added checking of options values validity before they are used\n    - fixed possible memory leak in CloneImage\n    - added ReplaceColor function to low level interface\n    - new function FindImageFileFormat by class added\n\n  -- 0.13 Changes/Bug Fixes -----------------------------------\n    - added DetermineFileFormat, DetermineStreamFormat, DetermineMemoryFormat,\n      GetPixelsSize functions to low level interface\n    - added NewPalette, CopyPalette, FreePalette functions\n      to low level interface\n    - added MapImageToPalette, FillRect, SplitImage, MakePaletteForImages\n      functions to low level interface\n    - fixed buggy FillCustomPalette function (possible div by zero and others)\n    - added CopyRect function to low level interface\n    - Member functions of TImageFormatInfo record implemented for all formats\n    - before saving images TestImagesInArray is called now\n    - added TestImagesInArray function to low level interface\n    - added GenerateMipMaps function to low level interface\n    - stream position in load/save from/to stream is now set to position before\n      function was called if error occurs\n    - when error occured during load/save from/to file file handle\n      was not released\n    - CloneImage returned always False\n\n}\nend.\n\n"
  },
  {
    "path": "lib/Imaging/ImagingBitmap.pas",
    "content": "{\n  Vampyre Imaging Library\n  by Marek Mauder \n  http://imaginglib.sourceforge.net\n\n  The contents of this file are used with permission, subject to the Mozilla\n  Public License Version 1.1 (the \"License\"); you may not use this file except\n  in compliance with the License. You may obtain a copy of the License at\n  http://www.mozilla.org/MPL/MPL-1.1.html\n\n  Software distributed under the License is distributed on an \"AS IS\" basis,\n  WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for\n  the specific language governing rights and limitations under the License.\n\n  Alternatively, the contents of this file may be used under the terms of the\n  GNU Lesser General Public License (the  \"LGPL License\"), in which case the\n  provisions of the LGPL License are applicable instead of those above.\n  If you wish to allow use of your version of this file only under the terms\n  of the LGPL License and not to allow others to use your version of this file\n  under the MPL, indicate your decision by deleting  the provisions above and\n  replace  them with the notice and other provisions required by the LGPL\n  License.  If you do not delete the provisions above, a recipient may use\n  your version of this file under either the MPL or the LGPL License.\n\n  For more information about the LGPL: http://www.gnu.org/copyleft/lesser.html\n}\n\n{\n  This unit contains image format loader/saver for Windows Bitmap images.\n}\nunit ImagingBitmap;\n\n{$I ImagingOptions.inc}\n\ninterface\n\nuses\n  ImagingTypes, Imaging, ImagingUtility, ImagingFormats, ImagingIO;\n\ntype\n  { Class for loading and saving Windows Bitmap images.\n    It can load/save 8bit indexed, 16, 24, 32 bit RGB or ARGB\n    images with or without RLE compression. It can also load 1/4 bit\n    indexed images and OS2 bitmaps.}\n  TBitmapFileFormat = class(TImageFileFormat)\n  protected\n    FUseRLE: LongBool;\n    procedure Define; override;\n    function LoadData(Handle: TImagingHandle; var Images: TDynImageDataArray;\n      OnlyFirstLevel: Boolean): Boolean; override;\n    function SaveData(Handle: TImagingHandle; const Images: TDynImageDataArray;\n      Index: LongInt): Boolean; override;\n    procedure ConvertToSupported(var Image: TImageData;\n      const Info: TImageFormatInfo); override;\n  public\n    function TestFormat(Handle: TImagingHandle): Boolean; override;\n  published\n    { Controls that RLE compression is used during saving. Accessible trough\n      ImagingBitmapRLE option.}\n    property UseRLE: LongBool read FUseRLE write FUseRLE;\n  end;\n\nimplementation\n\nconst\n  SBitmapFormatName = 'Windows Bitmap Image';\n  SBitmapMasks =      '*.bmp,*.dib';\n  BitmapSupportedFormats: TImageFormats = [ifIndex8, ifA1R5G5B5, ifA4R4G4B4,\n    ifR5G6B5, ifR8G8B8, ifA8R8G8B8, ifX1R5G5B5, ifX4R4G4B4, ifX8R8G8B8];\n  BitmapDefaultRLE = True;  \n\nconst\n  { Bitmap file identifier 'BM'.}\n  BMMagic: Word = 19778;\n\n  { Constants for the TBitmapInfoHeader.Compression field.}\n  BI_RGB = 0;\n  BI_RLE8 = 1;\n  BI_RLE4 = 2;\n  BI_BITFIELDS = 3;\n\n  V3InfoHeaderSize = 40;\n  V4InfoHeaderSize = 108; \n\ntype\n  { File Header for Windows/OS2 bitmap file.}\n  TBitmapFileHeader = packed record\n    ID: Word;           // Is always 19778 : 'BM'\n    Size: LongWord;     // Filesize\n    Reserved1: Word;\n    Reserved2: Word;\n    Offset: LongWord;   // Offset from start pos to beginning of image bits\n  end;\n\n  { Info Header for Windows bitmap file version 4.}\n  TBitmapInfoHeader = packed record\n    Size: LongWord;\n    Width: LongInt;\n    Height: LongInt;\n    Planes: Word;\n    BitCount: Word;\n    Compression: LongWord;\n    SizeImage: LongWord;\n    XPelsPerMeter: LongInt;\n    YPelsPerMeter: LongInt;\n    ClrUsed: LongInt;\n    ClrImportant: LongInt;\n    RedMask: LongWord;\n    GreenMask: LongWord;\n    BlueMask: LongWord;\n    AlphaMask: LongWord;\n    CSType: LongWord;\n    EndPoints: array[0..8] of LongWord;\n    GammaRed: LongWord;\n    GammaGreen: LongWord;\n    GammaBlue: LongWord;\n  end;\n\n  { Info Header for OS2 bitmaps.}\n  TBitmapCoreHeader = packed record\n    Size: LongWord;\n    Width: Word;\n    Height: Word;\n    Planes: Word;\n    BitCount: Word;\n  end;\n\n  { Used in RLE encoding and decoding.} \n  TRLEOpcode = packed record\n    Count: Byte;\n    Command: Byte;\n  end;\n  PRLEOpcode = ^TRLEOpcode;\n\n{ TBitmapFileFormat class implementation }\n\nprocedure TBitmapFileFormat.Define;\nbegin\n  inherited;\n  FName := SBitmapFormatName;\n  FFeatures := [ffLoad, ffSave];\n  FSupportedFormats := BitmapSupportedFormats;\n\n  FUseRLE := BitmapDefaultRLE;\n\n  AddMasks(SBitmapMasks);\n  RegisterOption(ImagingBitmapRLE, @FUseRLE);\nend;\n\nfunction TBitmapFileFormat.LoadData(Handle: TImagingHandle;\n  var Images: TDynImageDataArray; OnlyFirstLevel: Boolean): Boolean;\nvar\n  BF: TBitmapFileHeader;\n  BI: TBitmapInfoHeader;\n  BC: TBitmapCoreHeader;\n  IsOS2: Boolean;\n  PalRGB: PPalette24;\n  I, FPalSize, AlignedSize, StartPos, HeaderSize, AlignedWidthBytes, WidthBytes: LongInt;\n  Info: TImageFormatInfo;\n  Data: Pointer;\n\n  procedure LoadRGB;\n  var\n    I: LongInt;\n    LineBuffer: PByte;\n  begin\n    with Images[0], GetIO do\n    begin\n      // If BI.Height is < 0 then image data are stored non-flipped\n      // but default in windows is flipped so if Height is positive we must\n      // flip it\n\n      if BI.BitCount < 8 then\n      begin\n        // For 1 and 4 bit images load aligned data, they will be converted to\n        // 8 bit and unaligned later\n        GetMem(Data, AlignedSize);\n\n        if BI.Height < 0 then\n          Read(Handle, Data, AlignedSize)\n        else\n          for I := Height - 1 downto 0 do\n            Read(Handle, @PByteArray(Data)[I * AlignedWidthBytes], AlignedWidthBytes);\n      end\n      else\n      begin\n        // Images with pixels of size >= 1 Byte are read line by line and\n        // copied to image bits without padding bytes\n        GetMem(LineBuffer, AlignedWidthBytes);\n        try\n          if BI.Height < 0 then\n            for I := 0 to Height - 1 do\n            begin\n              Read(Handle, LineBuffer, AlignedWidthBytes);\n              Move(LineBuffer^, PByteArray(Bits)[I * WidthBytes], WidthBytes);\n            end\n          else\n            for I := Height - 1 downto 0 do\n            begin\n              Read(Handle, LineBuffer, AlignedWidthBytes);\n              Move(LineBuffer^, PByteArray(Bits)[I * WidthBytes], WidthBytes);\n            end;\n        finally\n          FreeMemNil(LineBuffer);\n        end;\n      end;\n    end;\n  end;\n\n  procedure LoadRLE4;\n  var\n    RLESrc: PByteArray;\n    Row, Col, WriteRow, I: LongInt;\n    SrcPos: LongWord;\n    DeltaX, DeltaY, Low, High: Byte;\n    Pixels: PByteArray;\n    OpCode: TRLEOpcode;\n    NegHeightBitmap: Boolean;\n  begin\n    GetMem(RLESrc, BI.SizeImage);\n    GetIO.Read(Handle, RLESrc, BI.SizeImage);\n    with Images[0] do\n    try\n      Low := 0;\n      Pixels := Bits;\n      SrcPos := 0;\n      NegHeightBitmap := BI.Height < 0;\n      Row := 0; // Current row in dest image\n      Col := 0; // Current column in dest image\n      // Row in dest image where actuall writting will be done\n      WriteRow := Iff(NegHeightBitmap, Row, Height - 1 - Row);\n      while (Row < Height) and (SrcPos < BI.SizeImage) do\n      begin\n        // Read RLE op-code\n        OpCode := PRLEOpcode(@RLESrc[SrcPos])^;\n        Inc(SrcPos, SizeOf(OpCode));\n        if OpCode.Count = 0 then\n        begin\n          // A byte Count of zero means that this is a special\n          // instruction.\n          case OpCode.Command of\n            0:\n              begin\n                // Move to next row\n                Inc(Row);\n                WriteRow := Iff(NegHeightBitmap, Row, Height - 1 - Row);\n                Col := 0;\n              end ;\n            1: Break; // Image is finished\n            2:\n              begin\n                // Move to a new relative position\n                DeltaX := RLESrc[SrcPos];\n                DeltaY := RLESrc[SrcPos + 1];\n                Inc(SrcPos, 2);\n                Inc(Col, DeltaX);\n                Inc(Row, DeltaY);\n              end\n          else\n            // Do not read data after EOF\n            if SrcPos + OpCode.Command > BI.SizeImage then\n              OpCode.Command := BI.SizeImage - SrcPos;\n            // Take padding bytes and nibbles into account\n            if Col + OpCode.Command > Width then\n              OpCode.Command := Width - Col;\n            // Store absolute data. Command code is the\n            // number of absolute bytes to store\n            for I := 0 to OpCode.Command - 1 do\n            begin\n              if (I and 1) = 0 then\n              begin\n                High := RLESrc[SrcPos] shr 4;\n                Low := RLESrc[SrcPos] and $F;\n                Pixels[WriteRow * Width + Col] := High;\n                Inc(SrcPos);\n              end\n              else\n                Pixels[WriteRow * Width + Col] := Low;\n              Inc(Col);\n            end;\n            // Odd number of bytes is followed by a pad byte\n            if (OpCode.Command mod 4) in [1, 2] then\n              Inc(SrcPos);\n          end;\n        end\n        else\n        begin\n          // Take padding bytes and nibbles into account\n          if Col + OpCode.Count > Width then\n            OpCode.Count := Width - Col;\n          // Store a run of the same color value\n          for I := 0 to OpCode.Count - 1 do\n          begin\n            if (I and 1) = 0 then\n              Pixels[WriteRow * Width + Col] := OpCode.Command shr 4\n            else\n              Pixels[WriteRow * Width + Col] := OpCode.Command and $F;\n            Inc(Col);\n          end;\n        end;\n      end;\n    finally\n      FreeMem(RLESrc);\n    end;\n  end;\n\n  procedure LoadRLE8;\n  var\n    RLESrc: PByteArray;\n    SrcCount, Row, Col, WriteRow: LongInt;\n    SrcPos: LongWord;\n    DeltaX, DeltaY: Byte;\n    Pixels: PByteArray;\n    OpCode: TRLEOpcode;\n    NegHeightBitmap: Boolean;\n  begin\n    GetMem(RLESrc, BI.SizeImage);\n    GetIO.Read(Handle, RLESrc, BI.SizeImage);\n    with Images[0] do\n    try\n      Pixels := Bits;\n      SrcPos := 0;\n      NegHeightBitmap := BI.Height < 0;\n      Row := 0; // Current row in dest image\n      Col := 0; // Current column in dest image\n      // Row in dest image where actuall writting will be done\n      WriteRow := Iff(NegHeightBitmap, Row, Height - 1 - Row);\n      while (Row < Height) and (SrcPos < BI.SizeImage) do\n      begin\n        // Read RLE op-code\n        OpCode := PRLEOpcode(@RLESrc[SrcPos])^;\n        Inc(SrcPos, SizeOf(OpCode));\n        if OpCode.Count = 0 then\n        begin\n          // A byte Count of zero means that this is a special\n          // instruction.\n          case OpCode.Command of\n            0:\n              begin\n                // Move to next row\n                Inc(Row);\n                WriteRow := Iff(NegHeightBitmap, Row, Height - 1 - Row);\n                Col := 0;\n              end ;\n            1: Break; // Image is finished\n            2:\n              begin\n                // Move to a new relative position\n                DeltaX := RLESrc[SrcPos];\n                DeltaY := RLESrc[SrcPos + 1];\n                Inc(SrcPos, 2);\n                Inc(Col, DeltaX);\n                Inc(Row, DeltaY);\n              end\n          else\n            SrcCount := OpCode.Command;\n            // Do not read data after EOF\n            if SrcPos + OpCode.Command > BI.SizeImage then\n              OpCode.Command := BI.SizeImage - SrcPos;\n            // Take padding bytes into account\n            if Col + OpCode.Command > Width then\n              OpCode.Command := Width - Col;\n            // Store absolute data. Command code is the\n            // number of absolute bytes to store\n            Move(RLESrc[SrcPos], Pixels[WriteRow * Width + Col], OpCode.Command);\n            Inc(SrcPos, SrcCount);\n            Inc(Col, OpCode.Command);\n            // Odd number of bytes is followed by a pad byte\n            if (SrcCount mod 2) = 1 then\n              Inc(SrcPos);\n          end;\n        end\n        else\n        begin\n          // Take padding bytes into account\n          if Col + OpCode.Count > Width then\n            OpCode.Count := Width - Col;\n          // Store a run of the same color value. Count is number of bytes to store\n          FillChar(Pixels [WriteRow * Width + Col], OpCode.Count, OpCode.Command);\n          Inc(Col, OpCode.Count);\n        end;\n      end;\n    finally\n      FreeMem(RLESrc);\n    end;\n  end;\n\nbegin\n  Data := nil;\n  SetLength(Images, 1);\n  with GetIO, Images[0] do\n  try\n    FillChar(BI, SizeOf(BI), 0);\n    StartPos := Tell(Handle);\n    Read(Handle, @BF, SizeOf(BF));\n    Read(Handle, @BI.Size, SizeOf(BI.Size));\n    IsOS2 := BI.Size = SizeOf(TBitmapCoreHeader);\n\n    // Bitmap Info reading\n    if IsOS2 then\n    begin\n      // OS/2 type bitmap, reads info header without 4 already read bytes\n      Read(Handle, @PByteArray(@BC)[SizeOf(BI.Size)],\n        SizeOf(TBitmapCoreHeader) - SizeOf(BI.Size));\n      with BI do\n      begin\n        ClrUsed := 0;\n        Compression := BI_RGB;\n        BitCount := BC.BitCount;\n        Height := BC.Height;\n        Width := BC.Width;\n      end;\n    end\n    else\n    begin\n      // Windows type bitmap\n      HeaderSize := Min(BI.Size - SizeOf(BI.Size), SizeOf(BI) - SizeOf(BI.Size)); // do not read more than size of BI!\n      Read(Handle, @PByteArray(@BI)[SizeOf(BI.Size)], HeaderSize);\n      // SizeImage can be 0 for BI_RGB images, but it is here because of:\n      // I saved 8bit bitmap in Paint Shop Pro 8 as OS2 RLE compressed.\n      // It wrote strange 64 Byte Info header with SizeImage set to 0\n      // Some progs were able to open it, some were not.\n      if BI.SizeImage = 0 then\n        BI.SizeImage := BF.Size - BF.Offset;\n    end;\n    // Bit mask reading. Only read it if there is V3 header, V4 header has\n    // masks laoded already (only masks for RGB in V3).\n    if (BI.Compression = BI_BITFIELDS) and (BI.Size = V3InfoHeaderSize) then\n      Read(Handle, @BI.RedMask, SizeOf(BI.RedMask) * 3);\n\n    case BI.BitCount of\n      1, 4, 8: Format := ifIndex8;\n      16:\n        if BI.RedMask = $0F00 then\n          // Set XRGB4 or ARGB4 according to value of alpha mask\n          Format := IffFormat(BI.AlphaMask = 0, ifX4R4G4B4, ifA4R4G4B4)\n        else if BI.RedMask = $F800 then\n          Format := ifR5G6B5\n        else\n          // R5G5B5 is default 16bit format (with Compression = BI_RGB or masks).\n          // We set it to A1.. and later there is a check if there are any alpha values\n          // and if not it is changed to X1R5G5B5\n          Format := ifA1R5G5B5;\n      24: Format := ifR8G8B8;\n      32: Format := ifA8R8G8B8; // As with R5G5B5 there is alpha check later \n    end;\n\n    NewImage(BI.Width, Abs(BI.Height), Format, Images[0]);\n    Info := GetFormatInfo(Format);\n    WidthBytes := Width * Info.BytesPerPixel;\n    AlignedWidthBytes := (((Width * BI.BitCount) + 31) shr 5) * 4;\n    AlignedSize := Height * LongInt(AlignedWidthBytes);\n\n    // Palette settings and reading\n    if BI.BitCount <= 8 then\n    begin\n      // Seek to the begining of palette\n      Seek(Handle, StartPos + SizeOf(TBitmapFileHeader) + LongInt(BI.Size),\n        smFromBeginning);\n      if IsOS2 then\n      begin\n        // OS/2 type\n        FPalSize := 1 shl BI.BitCount;\n        GetMem(PalRGB, FPalSize * SizeOf(TColor24Rec));\n        try\n          Read(Handle, PalRGB, FPalSize * SizeOf(TColor24Rec));\n          for I := 0 to FPalSize - 1 do\n          with PalRGB[I] do\n          begin\n            Palette[I].R := R;\n            Palette[I].G := G;\n            Palette[I].B := B;\n          end;\n        finally\n          FreeMemNil(PalRGB);\n        end;\n      end\n      else\n      begin\n        // Windows type\n        FPalSize := BI.ClrUsed;\n        if FPalSize = 0 then\n          FPalSize := 1 shl BI.BitCount;\n        Read(Handle, Palette, FPalSize * SizeOf(TColor32Rec));\n      end;\n      for I := 0 to Info.PaletteEntries - 1 do\n        Palette[I].A := $FF;\n    end;\n\n    // Seek to the beginning of image bits\n    Seek(Handle, StartPos + LongInt(BF.Offset), smFromBeginning);\n\n    case BI.Compression of\n      BI_RGB: LoadRGB;\n      BI_RLE4: LoadRLE4;\n      BI_RLE8: LoadRLE8;\n      BI_BITFIELDS: LoadRGB;\n    end;\n\n    if BI.AlphaMask = 0 then\n    begin\n      // Alpha mask is not stored in file (V3) or not defined.\n      // Check alpha channels of loaded images if they might contain them.\n      if Format = ifA1R5G5B5 then\n      begin\n        // Check if there is alpha channel present in A1R5GB5 images, if it is not\n        // change format to X1R5G5B5\n        if not Has16BitImageAlpha(Width * Height, Bits) then\n          Format := ifX1R5G5B5;\n      end\n      else if Format = ifA8R8G8B8 then\n      begin\n        // Check if there is alpha channel present in A8R8G8B8 images, if it is not\n        // change format to X8R8G8B8\n        if not Has32BitImageAlpha(Width * Height, Bits) then\n          Format := ifX8R8G8B8;\n      end;\n    end;\n\n    if BI.BitCount < 8 then\n    begin\n      // 1 and 4 bpp images are supported only for loading which is now\n      // so we now convert them to 8bpp (and unalign scanlines).\n      case BI.BitCount of\n        1: Convert1To8(Data, Bits, Width, Height, AlignedWidthBytes, False);\n        4:\n          begin\n            // RLE4 bitmaps are translated to 8bit during RLE decoding\n            if BI.Compression <> BI_RLE4 then\n               Convert4To8(Data, Bits, Width, Height, AlignedWidthBytes, False);\n          end;\n      end;\n      // Enlarge palette\n      ReallocMem(Palette, Info.PaletteEntries * SizeOf(TColor32Rec));\n    end;\n\n    Result := True;\n  finally\n    FreeMemNil(Data);\n  end;\nend;\n\nfunction TBitmapFileFormat.SaveData(Handle: TImagingHandle;\n  const Images: TDynImageDataArray; Index: LongInt): Boolean;\nvar\n  StartPos, EndPos, I, Pad, PadSize, WidthBytes: LongInt;\n  BF: TBitmapFileHeader;\n  BI: TBitmapInfoHeader;\n  Info: TImageFormatInfo;\n  ImageToSave: TImageData;\n  MustBeFreed: Boolean;\n\n  procedure SaveRLE8;\n  const\n    BufferSize = 8 * 1024;\n  var\n    X, Y, I, SrcPos: LongInt;\n    DiffCount, SameCount: Byte;\n    Pixels: PByteArray;\n    Buffer: array[0..BufferSize - 1] of Byte;\n    BufferPos: LongInt;\n\n    procedure WriteByte(ByteToWrite: Byte);\n    begin\n      if BufferPos = BufferSize then\n      begin\n        // Flush buffer if necessary\n        GetIO.Write(Handle, @Buffer, BufferPos);\n        BufferPos := 0;\n      end;\n      Buffer[BufferPos] := ByteToWrite;\n      Inc(BufferPos);\n    end;\n\n  begin\n    BufferPos := 0;\n    with GetIO, ImageToSave do\n    begin\n      for Y := Height - 1 downto 0 do\n      begin\n        X := 0;\n        SrcPos := 0;\n        Pixels := @PByteArray(Bits)[Y * Width];\n\n        while X < Width do\n        begin\n          SameCount := 1;\n          DiffCount := 0;\n          // Determine run length\n          while X + SameCount < Width do\n          begin\n            // If we reach max run length or byte with different value\n            // we end this run\n            if (SameCount = 255) or (Pixels[SrcPos + SameCount] <> Pixels[SrcPos]) then\n              Break;\n            Inc(SameCount);\n          end;\n\n          if SameCount = 1 then\n          begin\n            // If there are not some bytes with the same value we\n            // compute how many different bytes are there\n            while X + DiffCount < Width do\n            begin\n              // Stop diff byte counting if there two bytes with the same value\n              // or DiffCount is too big\n              if (DiffCount = 255) or (Pixels[SrcPos + DiffCount + 1] =\n                Pixels[SrcPos + DiffCount]) then\n                Break;\n              Inc(DiffCount);\n            end;\n          end;\n\n          // Now store absolute data (direct copy image->file) or\n          // store RLE code only (number of repeats + byte to be repeated)\n          if DiffCount > 2 then\n          begin\n            // Save 'Absolute Data' (0 + number of bytes) but only\n            // if number is >2 because (0+1) and (0+2) are other special commands\n            WriteByte(0);\n            WriteByte(DiffCount);\n            // Write absolute data to buffer\n            for I := 0 to DiffCount - 1 do\n              WriteByte(Pixels[SrcPos + I]);\n            Inc(X, DiffCount);\n            Inc(SrcPos, DiffCount);\n            // Odd number of bytes must be padded\n            if (DiffCount mod 2) = 1 then\n              WriteByte(0);\n          end\n          else\n          begin\n            // Save number of repeats and byte that should be repeated\n            WriteByte(SameCount);\n            WriteByte(Pixels[SrcPos]);\n            Inc(X, SameCount);\n            Inc(SrcPos, SameCount);\n          end;\n        end;\n        // Save 'End Of Line' command\n        WriteByte(0);\n        WriteByte(0);\n      end;\n      // Save 'End Of Bitmap' command\n      WriteByte(0);\n      WriteByte(1);\n      // Flush buffer\n      GetIO.Write(Handle, @Buffer, BufferPos);\n    end;\n  end;\n\nbegin\n  Result := False;\n  if MakeCompatible(Images[Index], ImageToSave, MustBeFreed) then\n  with GetIO, ImageToSave do\n  try\n    Info := GetFormatInfo(Format);\n    StartPos := Tell(Handle);\n    FillChar(BF, SizeOf(BF), 0);\n    FillChar(BI, SizeOf(BI), 0);\n    // Other fields will be filled later - we don't know all values now\n    BF.ID := BMMagic;\n    Write(Handle, @BF, SizeOf(BF));\n    if Info.HasAlphaChannel and (Info.BytesPerPixel = 2){V4 temp hack} then\n      // Save images with alpha in V4 format\n      BI.Size := V4InfoHeaderSize\n    else\n      // Save images without alpha in V3 format - for better compatibility\n      BI.Size := V3InfoHeaderSize;\n    BI.Width := Width;\n    BI.Height := Height;\n    BI.Planes := 1;\n    BI.BitCount := Info.BytesPerPixel * 8;\n    BI.XPelsPerMeter := 2835; // 72 dpi\n    BI.YPelsPerMeter := 2835; // 72 dpi\n    // Set compression\n    if (Info.BytesPerPixel = 1) and FUseRLE then\n      BI.Compression := BI_RLE8\n    else if (Info.HasAlphaChannel or\n      ((BI.BitCount = 16) and (Format <> ifX1R5G5B5))) and (Info.BytesPerPixel = 2){V4 temp hack} then\n      BI.Compression := BI_BITFIELDS\n    else\n      BI.Compression := BI_RGB;\n    // Write header (first time)\n    Write(Handle, @BI, BI.Size);\n\n    // Write mask info\n    if BI.Compression = BI_BITFIELDS then\n    begin\n      if BI.BitCount = 16 then\n      with Info.PixelFormat^ do\n      begin\n        BI.RedMask   := RBitMask;\n        BI.GreenMask := GBitMask;\n        BI.BlueMask  := BBitMask;\n        BI.AlphaMask := ABitMask;\n      end\n      else\n      begin\n        // Set masks for A8R8G8B8\n        BI.RedMask   := $00FF0000;\n        BI.GreenMask := $0000FF00;\n        BI.BlueMask  := $000000FF;\n        BI.AlphaMask := $FF000000;\n      end;\n      // If V3 header is used RGB masks must be written to file separately.\n      // V4 header has embedded masks (V4 is default for formats with alpha).\n      if BI.Size = V3InfoHeaderSize then\n        Write(Handle, @BI.RedMask, SizeOf(BI.RedMask) * 3);\n    end;\n    // Write palette\n    if Palette <> nil then\n      Write(Handle, Palette, Info.PaletteEntries * SizeOf(TColor32Rec));\n\n    BF.Offset := Tell(Handle) - StartPos;\n\n    if BI.Compression <> BI_RLE8 then\n    begin\n      // Save uncompressed data, scanlines must be filled with pad bytes\n      // to be multiples of 4, save as bottom-up (Windows native) bitmap\n      Pad := 0;\n      WidthBytes := Width * Info.BytesPerPixel;\n      PadSize := ((Width * BI.BitCount + 31) div 32) * 4 - WidthBytes;\n\n      for I := Height - 1 downto 0 do\n      begin\n        Write(Handle, @PByteArray(Bits)[I * WidthBytes], WidthBytes);\n        if PadSize > 0 then\n          Write(Handle, @Pad, PadSize);\n      end;\n    end\n    else\n    begin\n      // Save data with RLE8 compression\n      SaveRLE8;\n    end;\n\n    EndPos := Tell(Handle);\n    Seek(Handle, StartPos, smFromBeginning);\n    // Rewrite header with new values\n    BF.Size := EndPos - StartPos;\n    BI.SizeImage := BF.Size - BF.Offset;\n    Write(Handle, @BF, SizeOf(BF));\n    Write(Handle, @BI, BI.Size);\n    Seek(Handle, EndPos, smFromBeginning);\n\n    Result := True;\n  finally\n    if MustBeFreed then\n      FreeImage(ImageToSave);\n  end;\nend;\n\nprocedure TBitmapFileFormat.ConvertToSupported(var Image: TImageData;\n  const Info: TImageFormatInfo);\nvar\n  ConvFormat: TImageFormat;\nbegin\n  if Info.IsFloatingPoint then\n    // Convert FP image to RGB/ARGB according to presence of alpha channel\n    ConvFormat := IffFormat(Info.HasAlphaChannel, ifA8R8G8B8, ifR8G8B8)\n  else if Info.HasGrayChannel or Info.IsIndexed then\n    // Convert all grayscale and indexed images to Index8 unless they have alpha\n    // (preserve it)\n    ConvFormat := IffFormat(Info.HasAlphaChannel, ifA8R8G8B8, ifIndex8)\n  else if Info.HasAlphaChannel then\n    // Convert images with alpha channel to A8R8G8B8\n    ConvFormat := ifA8R8G8B8\n  else if Info.UsePixelFormat then\n    // Convert 16bit RGB images (no alpha) to X1R5G5B5\n    ConvFormat := ifX1R5G5B5\n  else\n    // Convert all other formats to R8G8B8\n    ConvFormat := ifR8G8B8;\n\n  ConvertImage(Image, ConvFormat);\nend;\n\nfunction TBitmapFileFormat.TestFormat(Handle: TImagingHandle): Boolean;\nvar\n  Hdr: TBitmapFileHeader;\n  ReadCount: LongInt;\nbegin\n  Result := False;\n  if Handle <> nil then\n  with GetIO do\n  begin\n    ReadCount := Read(Handle, @Hdr, SizeOf(Hdr));\n    Seek(Handle, -ReadCount, smFromCurrent);\n    Result := (Hdr.ID = BMMagic) and (ReadCount = SizeOf(Hdr));\n  end;\nend;\n\ninitialization\n  RegisterImageFileFormat(TBitmapFileFormat);\n\n{\n  File Notes:\n\n  -- TODOS ----------------------------------------------------\n    - nothing now\n    - Add option to choose to save V3 or V4 headers. \n\n  -- 0.25.0 Changes/Bug Fixes ---------------------------------\n    - Fixed problem with indexed BMP loading - some pal entries\n      could end up with alpha=0. \n\n  -- 0.23 Changes/Bug Fixes -----------------------------------\n    - Now saves bitmaps as bottom-up for better compatibility\n      (mainly Lazarus' TImage!).\n    - Fixed crash when loading bitmaps with headers larger than V4.\n    - Temp hacks to disable V4 headers for 32bit images (compatibility with\n      other soft).\n\n  -- 0.21 Changes/Bug Fixes -----------------------------------\n    - Removed temporary data allocation for image with aligned scanlines.\n      They are now directly written to output so memory requirements are\n      much lower now.\n    - Now uses and recognizes BITMAPINFOHEADERV4 when loading/saving.\n      Mainly for formats with alpha channels.\n    - Added ifR5G6B5 to supported formats, changed converting to supported\n      formats little bit.\n    - Rewritten SaveRLE8 nested procedure. Old code was long and\n      mysterious - new is short and much more readable.\n    - MakeCompatible method moved to base class, put ConvertToSupported here.\n      GetSupportedFormats removed, it is now set in constructor.\n    - Rewritten LoadRLE4 and LoadRLE8 nested procedures.\n      Should be less buggy an more readable (load inspired by Colosseum Builders' code).\n    - Made public properties for options registered to SetOption/GetOption\n      functions. \n    - Addded alpha check to 32b bitmap loading too (teh same as in 16b\n      bitmap loading).\n    - Moved Convert1To8 and Convert4To8 to ImagingFormats\n    - Changed extensions to filename masks.\n    - Changed SaveData, LoadData, and MakeCompatible methods according\n      to changes in base class in Imaging unit.\n\n  -- 0.19 Changes/Bug Fixes -----------------------------------\n    - fixed wrong const that caused A4R4G4B4 BMPs to load as A1R5G5B5\n    - fixed the bug that caused 8bit RLE compressed bitmaps to load as\n      whole black\n\n  -- 0.17 Changes/Bug Fixes -----------------------------------\n    - 16 bit images are usually without alpha but some has alpha\n      channel and there is no indication of it - so I have added\n      a check: if all pixels of image are with alpha = 0 image is treated\n      as X1R5G5B5 otherwise as A1R5G5B5\n\n  -- 0.13 Changes/Bug Fixes -----------------------------------\n    - when loading 1/4 bit images with dword aligned dimensions\n      there was ugly memory rewritting bug causing image corruption\n\n}\n\nend.\n\n"
  },
  {
    "path": "lib/Imaging/ImagingCanvases.pas",
    "content": "{\n  Vampyre Imaging Library\n  by Marek Mauder\n  http://imaginglib.sourceforge.net\n\n  The contents of this file are used with permission, subject to the Mozilla\n  Public License Version 1.1 (the \"License\"); you may not use this file except\n  in compliance with the License. You may obtain a copy of the License at\n  http://www.mozilla.org/MPL/MPL-1.1.html\n\n  Software distributed under the License is distributed on an \"AS IS\" basis,\n  WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for\n  the specific language governing rights and limitations under the License.\n\n  Alternatively, the contents of this file may be used under the terms of the\n  GNU Lesser General Public License (the  \"LGPL License\"), in which case the\n  provisions of the LGPL License are applicable instead of those above.\n  If you wish to allow use of your version of this file only under the terms\n  of the LGPL License and not to allow others to use your version of this file\n  under the MPL, indicate your decision by deleting  the provisions above and\n  replace  them with the notice and other provisions required by the LGPL\n  License.  If you do not delete the provisions above, a recipient may use\n  your version of this file under either the MPL or the LGPL License.\n\n  For more information about the LGPL: http://www.gnu.org/copyleft/lesser.html\n}\n\n{ This unit contains canvas classes for drawing and applying effects.}\nunit ImagingCanvases;\n\n{$I ImagingOptions.inc}\n\ninterface\n\nuses\n  SysUtils, Types, Classes, ImagingTypes, Imaging, ImagingClasses,\n  ImagingFormats, ImagingUtility;\n\nconst\n  { Color constants in ifA8R8G8B8 format.}\n  pcClear   = $00000000;\n  pcBlack   = $FF000000;\n  pcWhite   = $FFFFFFFF;\n  pcMaroon  = $FF800000;\n  pcGreen   = $FF008000;\n  pcOlive   = $FF808000;\n  pcNavy    = $FF000080;\n  pcPurple  = $FF800080;\n  pcTeal    = $FF008080;\n  pcGray    = $FF808080;\n  pcSilver  = $FFC0C0C0;\n  pcRed     = $FFFF0000;\n  pcLime    = $FF00FF00;\n  pcYellow  = $FFFFFF00;\n  pcBlue    = $FF0000FF;\n  pcFuchsia = $FFFF00FF;\n  pcAqua    = $FF00FFFF;\n  pcLtGray  = $FFC0C0C0;\n  pcDkGray  = $FF808080;\n\n  MaxPenWidth = 256;\n\ntype\n  EImagingCanvasError = class(EImagingError);\n  EImagingCanvasBlendingError = class(EImagingError);\n\n  { Fill mode used when drawing filled objects on canvas.}\n  TFillMode = (\n    fmSolid,  // Solid fill using current fill color\n    fmClear   // No filling done\n  );\n\n  { Pen mode used when drawing lines, object outlines, and similar on canvas.}\n  TPenMode = (\n    pmSolid,  // Draws solid lines using current pen color.\n    pmClear   // No drawing done\n  );\n\n  { Source and destination blending factors for drawing functions with blending.\n    Blending formula: SrcColor * SrcFactor + DestColor * DestFactor }\n  TBlendingFactor = (\n    bfIgnore,           // Don't care\n    bfZero,             // For Src and Dest, Factor = (0, 0, 0, 0)\n    bfOne,              // For Src and Dest, Factor = (1, 1, 1, 1)\n    bfSrcAlpha,         // For Src and Dest, Factor = (Src.A, Src.A, Src.A, Src.A)\n    bfOneMinusSrcAlpha, // For Src and Dest, Factor = (1 - Src.A, 1 - Src.A, 1 - Src.A, 1 - Src.A)\n    bfDstAlpha,         // For Src and Dest, Factor = (Dest.A, Dest.A, Dest.A, Dest.A)\n    bfOneMinusDstAlpha, // For Src and Dest, Factor = (1 - Dest.A, 1 - Dest.A, 1 - Dest.A, 1 - Dest.A)\n    bfSrcColor,         // For Dest,         Factor = (Src.R, Src.R, Src.B, Src.A)\n    bfOneMinusSrcColor, // For Dest,         Factor = (1 - Src.R, 1 - Src.G, 1 - Src.B, 1 - Src.A)\n    bfDstColor,         // For Src,          Factor = (Dest.R, Dest.G, Dest.B, Dest.A)\n    bfOneMinusDstColor  // For Src,          Factor = (1 - Dest.R, 1 - Dest.G, 1 - Dest.B, 1 - Dest.A)\n  );\n\n  { Procedure for custom pixel write modes with blending.}\n  TPixelWriteProc = procedure(const SrcPix: TColorFPRec; DestPtr: PByte;\n    DestInfo: PImageFormatInfo; SrcFactor, DestFactor: TBlendingFactor);\n\n  { Represents 3x3 convolution filter kernel.}\n  TConvolutionFilter3x3 = record\n    Kernel: array[0..2, 0..2] of LongInt;\n    Divisor: LongInt;\n    Bias: Single;\n  end;\n\n  { Represents 5x5 convolution filter kernel.}\n  TConvolutionFilter5x5 = record\n    Kernel: array[0..4, 0..4] of LongInt;\n    Divisor: LongInt;\n    Bias: Single;\n  end;\n\n  TPointTransformFunction = function(const Pixel: TColorFPRec;\n    Param1, Param2, Param3: Single): TColorFPRec;\n\n  TDynFPPixelArray = array of TColorFPRec;\n\n  THistogramArray = array[Byte] of Integer;\n\n  TSelectPixelFunction = function(var Pixels: TDynFPPixelArray): TColorFPRec;\n\n  { Base canvas class for drawing objects, applying effects, and other.\n    Constructor takes TBaseImage (or pointer to TImageData). Source image\n    bits are not copied but referenced so all canvas functions affect\n    source image and vice versa. When you change format or resolution of\n    source image you must call UpdateCanvasState method (so canvas could\n    recompute some data size related stuff).\n\n    TImagingCanvas works for all image data formats except special ones\n    (compressed). Because of this its methods are quite slow (they usually work\n    with colors in ifA32R32G32B32F format). If you want fast drawing you\n    can use one of fast canvas clases. These descendants of TImagingCanvas\n    work only for few select formats (or only one) but they are optimized thus\n    much faster.\n  }\n  TImagingCanvas = class(TObject)\n  private\n    FDataSizeOnUpdate: LongInt;\n    FLineRecursion: Boolean;\n    function GetPixel32(X, Y: LongInt): TColor32; virtual;\n    function GetPixelFP(X, Y: LongInt): TColorFPRec; virtual;\n    function GetValid: Boolean; {$IFDEF USE_INLINE}inline;{$ENDIF}\n    procedure SetPixel32(X, Y: LongInt; const Value: TColor32); virtual;\n    procedure SetPixelFP(X, Y: LongInt; const Value: TColorFPRec); virtual;\n    procedure SetPenColor32(const Value: TColor32); {$IFDEF USE_INLINE}inline;{$ENDIF}\n    procedure SetPenColorFP(const Value: TColorFPRec); {$IFDEF USE_INLINE}inline;{$ENDIF}\n    procedure SetPenWidth(const Value: LongInt); {$IFDEF USE_INLINE}inline;{$ENDIF}\n    procedure SetFillColor32(const Value: TColor32); {$IFDEF USE_INLINE}inline;{$ENDIF}\n    procedure SetFillColorFP(const Value: TColorFPRec); {$IFDEF USE_INLINE}inline;{$ENDIF}\n    procedure SetClipRect(const Value: TRect);\n    procedure CheckBeforeBlending(SrcFactor, DestFactor: TBlendingFactor; DestCanvas: TImagingCanvas);\n  protected\n    FPData: PImageData;\n    FClipRect: TRect;\n    FPenColorFP: TColorFPRec;\n    FPenColor32: TColor32;\n    FPenMode: TPenMode;\n    FPenWidth: LongInt;\n    FFillColorFP: TColorFPRec;\n    FFillColor32: TColor32;\n    FFillMode: TFillMode;\n    FNativeColor: TColorFPRec;\n    FFormatInfo: TImageFormatInfo;\n\n    { Returns pointer to pixel at given position.}\n    function GetPixelPointer(X, Y: LongInt): Pointer; {$IFDEF USE_INLINE}inline;{$ENDIF}\n    { Translates given FP color to native format of canvas and stores it\n      in FNativeColor field (its bit copy) or user pointer (in overloaded method).}\n    procedure TranslateFPToNative(const Color: TColorFPRec); overload; {$IFDEF USE_INLINE}inline;{$ENDIF}\n    procedure TranslateFPToNative(const Color: TColorFPRec; Native: Pointer); overload; {$IFDEF USE_INLINE}inline;{$ENDIF}\n    { Clipping function used by horizontal and vertical line drawing functions.}\n    function ClipAxisParallelLine(var A1, A2, B: LongInt;\n      AStart, AStop, BStart, BStop: LongInt): Boolean;\n    { Internal horizontal line drawer used mainly for filling inside of objects\n      like ellipses and circles.}\n    procedure HorzLineInternal(X1, X2, Y: LongInt; Color: Pointer; Bpp: LongInt); virtual;\n    procedure CopyPixelInternal(X, Y: LongInt; Pixel: Pointer; Bpp: LongInt); {$IFDEF USE_INLINE}inline;{$ENDIF}\n    procedure DrawInternal(const SrcRect: TRect; DestCanvas: TImagingCanvas;\n      DestX, DestY: Integer; SrcFactor, DestFactor: TBlendingFactor; PixelWriteProc: TPixelWriteProc);\n    procedure StretchDrawInternal(const SrcRect: TRect; DestCanvas: TImagingCanvas;\n      const DestRect: TRect; SrcFactor, DestFactor: TBlendingFactor;\n      Filter: TResizeFilter; PixelWriteProc: TPixelWriteProc);\n  public\n    constructor CreateForData(ImageDataPointer: PImageData);\n    constructor CreateForImage(Image: TBaseImage);\n    destructor Destroy; override;\n\n    { Call this method when you change size or format of image this canvas\n      operates on (like calling ResizeImage, ConvertImage, or changing Format\n      property of TBaseImage descendants).}\n    procedure UpdateCanvasState; virtual;\n    { Resets clipping rectangle to Rect(0, 0, ImageWidth, ImageHeight).}\n    procedure ResetClipRect;\n\n    { Clears entire canvas with current fill color (ignores clipping rectangle\n      and always uses fmSolid fill mode).}\n    procedure Clear;\n\n    { Draws horizontal line with current pen settings.}\n    procedure HorzLine(X1, X2, Y: LongInt); virtual;\n    { Draws vertical line with current pen settings.}\n    procedure VertLine(X, Y1, Y2: LongInt); virtual;\n    { Draws line from [X1, Y1] to [X2, Y2] with current pen settings.}\n    procedure Line(X1, Y1, X2, Y2: LongInt); virtual;\n    { Draws a rectangle using current pen settings.}\n    procedure FrameRect(const Rect: TRect);\n    { Fills given rectangle with current fill settings.}\n    procedure FillRect(const Rect: TRect); virtual;\n    { Fills given rectangle with current fill settings and pixel blending.}\n    procedure FillRectBlend(const Rect: TRect; SrcFactor, DestFactor: TBlendingFactor);\n    { Draws rectangle which is outlined by using the current pen settings and\n      filled by using the current fill settings.}\n    procedure Rectangle(const Rect: TRect);\n    { Draws ellipse which is outlined by using the current pen settings and\n      filled by using the current fill settings. Rect specifies bounding rectangle\n      of ellipse to be drawn.}\n    procedure Ellipse(const Rect: TRect);\n    { Fills area of canvas with current fill color starting at point [X, Y] and\n      coloring its neighbors. Default flood fill mode changes color of all\n      neighbors with the same color as pixel [X, Y]. With BoundaryFillMode\n      set to True neighbors are recolored regardless of their old color,\n      but area which will be recolored has boundary (specified by current pen color).}\n    procedure FloodFill(X, Y: Integer; BoundaryFillMode: Boolean = False);         \n\n    { Draws contents of this canvas onto another canvas with pixel blending.\n      Blending factors are chosen using TBlendingFactor parameters.\n      Resulting destination pixel color is:\n        SrcColor * SrcFactor +  DstColor * DstFactor}\n    procedure DrawBlend(const SrcRect: TRect; DestCanvas: TImagingCanvas;\n      DestX, DestY: Integer; SrcFactor, DestFactor: TBlendingFactor);\n    { Draws contents of this canvas onto another one with typical alpha\n      blending (Src 'over' Dest, factors are bfSrcAlpha and bfOneMinusSrcAlpha.)}\n    procedure DrawAlpha(const SrcRect: TRect; DestCanvas: TImagingCanvas; DestX, DestY: Integer); virtual;\n    { Draws contents of this canvas onto another one using additive blending\n      (source and dest factors are bfOne).}\n    procedure DrawAdd(const SrcRect: TRect; DestCanvas: TImagingCanvas; DestX, DestY: Integer);\n    { Draws stretched and filtered contents of this canvas onto another canvas\n      with pixel blending. Blending factors are chosen using TBlendingFactor parameters.\n      Resulting destination pixel color is:\n        SrcColor * SrcFactor +  DstColor * DstFactor}\n    procedure StretchDrawBlend(const SrcRect: TRect; DestCanvas: TImagingCanvas;\n      const DestRect: TRect; SrcFactor, DestFactor: TBlendingFactor;\n      Filter: TResizeFilter = rfBilinear);\n    { Draws contents of this canvas onto another one with typical alpha\n      blending (Src 'over' Dest, factors are bfSrcAlpha and bfOneMinusSrcAlpha.)}\n    procedure StretchDrawAlpha(const SrcRect: TRect; DestCanvas: TImagingCanvas;\n      const DestRect: TRect; Filter: TResizeFilter = rfBilinear); virtual;\n    { Draws contents of this canvas onto another one using additive blending\n      (source and dest factors are bfOne).}\n    procedure StretchDrawAdd(const SrcRect: TRect; DestCanvas: TImagingCanvas;\n      const DestRect: TRect; Filter: TResizeFilter = rfBilinear);\n\n    { Convolves canvas' image with given 3x3 filter kernel. You can use\n      predefined filter kernels or define your own.}\n    procedure ApplyConvolution3x3(const Filter: TConvolutionFilter3x3);\n    { Convolves canvas' image with given 5x5 filter kernel. You can use\n      predefined filter kernels or define your own.}\n    procedure ApplyConvolution5x5(const Filter: TConvolutionFilter5x5);\n    { Computes 2D convolution of canvas' image and given filter kernel.\n      Kernel is in row format and KernelSize must be odd number >= 3. Divisor\n      is normalizing value based on Kernel (usually sum of all kernel's cells).\n      The Bias number shifts each color value by a fixed amount (color values\n      are usually in range [0, 1] during processing). If ClampChannels\n      is True all output color values are clamped to [0, 1]. You can use\n      predefined filter kernels or define your own.}\n    procedure ApplyConvolution(Kernel: PLongInt; KernelSize, Divisor: LongInt;\n      Bias: Single = 0.0; ClampChannels: Boolean = True); virtual;\n\n    { Applies custom non-linear filter. Filter size is diameter of pixel\n      neighborhood. Typical values are 3, 5, or 7. }\n    procedure ApplyNonLinearFilter(FilterSize: Integer; SelectFunc: TSelectPixelFunction);\n    { Applies median non-linear filter with user defined pixel neighborhood.\n      Selects median pixel from the neighborhood as new pixel\n      (current implementation is quite slow).}\n    procedure ApplyMedianFilter(FilterSize: Integer);\n    { Applies min non-linear filter with user defined pixel neighborhood.\n      Selects min pixel from the neighborhood as new pixel.}\n    procedure ApplyMinFilter(FilterSize: Integer);\n    { Applies max non-linear filter with user defined pixel neighborhood.\n      Selects max pixel from the neighborhood as new pixel.}\n    procedure ApplyMaxFilter(FilterSize: Integer);\n\n    { Transforms pixels one by one by given function. Pixel neighbors are\n      not taken into account. Param 1-3 are optional parameters\n      for transform function.}\n    procedure PointTransform(Transform: TPointTransformFunction;\n      Param1, Param2, Param3: Single);\n    { Modifies image contrast and brightness. Parameters should be\n      in range <-100; 100>.}\n    procedure ModifyContrastBrightness(Contrast, Brightness: Single);\n    { Gamma correction of individual color channels. Range is (0, +inf),\n      1.0 means no change.}\n    procedure GammaCorection(Red, Green, Blue: Single);\n    { Inverts colors of all image pixels, makes negative image. Ignores alpha channel.}\n    procedure InvertColors; virtual;\n    { Simple single level thresholding with threshold level (in range [0, 1])\n      for each color channel.}\n    procedure Threshold(Red, Green, Blue: Single);\n    { Adjusts the color levels of the image by scaling the\n      colors falling between specified white and black points to full [0, 1] range.\n      The black point specifies the darkest color in the image, white point\n      specifies the lightest color, and mid point is gamma aplied to image.\n      Black and white point must be in range [0, 1].}\n    procedure AdjustColorLevels(BlackPoint, WhitePoint: Single; MidPoint: Single = 1.0);\n    { Premultiplies color channel values by alpha. Needed for some platforms/APIs\n      to display images with alpha properly.}\n    procedure PremultiplyAlpha;\n    { Reverses PremultiplyAlpha operation.}\n    procedure UnPremultiplyAlpha;\n\n    { Calculates image histogram for each channel and also gray values. Each\n      channel has 256 values available. Channel values of data formats with higher\n      precision are scaled and rounded. Example: Red[126] specifies number of pixels\n      in image with red channel = 126.}\n    procedure GetHistogram(out Red, Green, Blue, Alpha, Gray: THistogramArray);\n    { Fills image channel with given value leaving other channels intact.\n      Use ChannelAlpha, ChannelRed, etc. constants from ImagingTypes as\n      channel identifier.}\n    procedure FillChannel(ChannelId: Integer; NewChannelValue: Byte); overload;\n    { Fills image channel with given value leaving other channels intact.\n      Use ChannelAlpha, ChannelRed, etc. constants from ImagingTypes as\n      channel identifier.}\n    procedure FillChannelFP(ChannelId: Integer; NewChannelValue: Single); overload;\n\n    { Color used when drawing lines, frames, and outlines of objects.}\n    property PenColor32: TColor32 read FPenColor32 write SetPenColor32;\n    { Color used when drawing lines, frames, and outlines of objects.}\n    property PenColorFP: TColorFPRec read FPenColorFP write SetPenColorFP;\n    { Pen mode used when drawing lines, object outlines, and similar on canvas.}\n    property PenMode: TPenMode read FPenMode write FPenMode;\n    { Width with which objects like lines, frames, etc. (everything which uses\n      PenColor) are drawn.}\n    property PenWidth: LongInt read FPenWidth write SetPenWidth;\n    { Color used for filling when drawing various objects.}\n    property FillColor32: TColor32 read FFillColor32 write SetFillColor32;\n    { Color used for filling when drawing various objects.}\n    property FillColorFP: TColorFPRec read FFillColorFP write SetFillColorFP;\n    { Fill mode used when drawing filled objects on canvas.}\n    property FillMode: TFillMode read FFillMode write FFillMode;\n    { Specifies the current color of the pixels of canvas. Native pixel is\n      read from canvas and then translated to 32bit ARGB. Reverse operation\n      is made when setting pixel color.}\n    property Pixels32[X, Y: LongInt]: TColor32 read GetPixel32 write SetPixel32;\n    { Specifies the current color of the pixels of canvas. Native pixel is\n      read from canvas and then translated to FP ARGB. Reverse operation\n      is made when setting pixel color.}\n    property PixelsFP[X, Y: LongInt]: TColorFPRec read GetPixelFP write SetPixelFP;\n    { Clipping rectangle of this canvas. No pixels outside this rectangle are\n      altered by canvas methods if Clipping property is True. Clip rect gets\n      reseted when UpdateCanvasState is called.}\n    property ClipRect: TRect read FClipRect write SetClipRect;\n    { Extended format information.}\n    property FormatInfo: TImageFormatInfo read FFormatInfo;\n    { Indicates that this canvas is in valid state. If False canvas oprations\n      may crash.}\n    property Valid: Boolean read GetValid;\n\n    { Returns all formats supported by this canvas class.}\n    class function GetSupportedFormats: TImageFormats; virtual;\n  end;\n\n  TImagingCanvasClass = class of TImagingCanvas;\n\n  TScanlineArray = array[0..MaxInt div SizeOf(Pointer) - 1] of PColor32RecArray;\n  PScanlineArray = ^TScanlineArray;\n\n  { Fast canvas class for ifA8R8G8B8 format images.}\n  TFastARGB32Canvas = class(TImagingCanvas)\n  protected\n    FScanlines: PScanlineArray;\n    procedure AlphaBlendPixels(SrcPix, DestPix: PColor32Rec); {$IFDEF USE_INLINE}inline;{$ENDIF}\n    function GetPixel32(X, Y: LongInt): TColor32; override;\n    procedure SetPixel32(X, Y: LongInt; const Value: TColor32); override;\n  public\n    destructor Destroy; override;\n\n    procedure UpdateCanvasState; override;\n\n    procedure DrawAlpha(const SrcRect: TRect; DestCanvas: TImagingCanvas; DestX, DestY: Integer); override;\n    procedure StretchDrawAlpha(const SrcRect: TRect; DestCanvas: TImagingCanvas;\n      const DestRect: TRect; Filter: TResizeFilter = rfBilinear); override;\n    procedure InvertColors; override;\n\n    property Scanlines: PScanlineArray read FScanlines;\n\n    class function GetSupportedFormats: TImageFormats; override;\n  end;\n\nconst\n  { Kernel for 3x3 average smoothing filter.}\n  FilterAverage3x3: TConvolutionFilter3x3 = (\n    Kernel: ((1, 1, 1),\n             (1, 1, 1),\n             (1, 1, 1));\n    Divisor: 9);\n\n  { Kernel for 5x5 average smoothing filter.}\n  FilterAverage5x5: TConvolutionFilter5x5 = (\n    Kernel: ((1, 1, 1, 1, 1),\n             (1, 1, 1, 1, 1),\n             (1, 1, 1, 1, 1),\n             (1, 1, 1, 1, 1),\n             (1, 1, 1, 1, 1));\n    Divisor: 25);\n\n  { Kernel for 3x3 Gaussian smoothing filter.}\n  FilterGaussian3x3: TConvolutionFilter3x3 = (\n    Kernel: ((1, 2, 1),\n             (2, 4, 2),\n             (1, 2, 1));\n    Divisor: 16);\n\n  { Kernel for 5x5 Gaussian smoothing filter.}\n  FilterGaussian5x5: TConvolutionFilter5x5 = (\n    Kernel: ((1,  4,  6,  4, 1),\n             (4, 16, 24, 16, 4),\n             (6, 24, 36, 24, 6),\n             (4, 16, 24, 16, 4),\n             (1,  4,  6,  4, 1));\n    Divisor: 256);\n\n  { Kernel for 3x3 Sobel horizontal edge detection filter (1st derivative approximation).}\n  FilterSobelHorz3x3: TConvolutionFilter3x3 = (\n    Kernel: (( 1,  2,  1),\n             ( 0,  0,  0),\n             (-1, -2, -1));\n    Divisor: 1);\n\n  { Kernel for 3x3 Sobel vertical edge detection filter (1st derivative approximation).}\n  FilterSobelVert3x3: TConvolutionFilter3x3 = (\n    Kernel: ((-1, 0, 1),\n             (-2, 0, 2),\n             (-1, 0, 1));\n    Divisor: 1);\n\n  { Kernel for 3x3 Prewitt horizontal edge detection filter.}\n  FilterPrewittHorz3x3: TConvolutionFilter3x3 = (\n    Kernel: (( 1,  1,  1),\n             ( 0,  0,  0),\n             (-1, -1, -1));\n    Divisor: 1);\n\n  { Kernel for 3x3 Prewitt vertical edge detection filter.}\n  FilterPrewittVert3x3: TConvolutionFilter3x3 = (\n    Kernel: ((-1, 0, 1),\n             (-1, 0, 1),\n             (-1, 0, 1));\n    Divisor: 1);\n\n  { Kernel for 3x3 Kirsh horizontal edge detection filter.}\n  FilterKirshHorz3x3: TConvolutionFilter3x3 = (\n    Kernel: (( 5,  5,  5),\n             (-3,  0, -3),\n             (-3, -3, -3));\n    Divisor: 1);\n\n  { Kernel for 3x3 Kirsh vertical edge detection filter.}\n  FilterKirshVert3x3: TConvolutionFilter3x3 = (\n    Kernel: ((5, -3, -3),\n             (5,  0, -3),\n             (5, -3, -3));\n    Divisor: 1);\n\n  { Kernel for 3x3 Laplace omni-directional edge detection filter\n    (2nd derivative approximation).}\n  FilterLaplace3x3: TConvolutionFilter3x3 = (\n    Kernel: ((-1, -1, -1),\n             (-1,  8, -1),\n             (-1, -1, -1));\n    Divisor: 1);\n\n  { Kernel for 5x5 Laplace omni-directional edge detection filter\n    (2nd derivative approximation).}\n  FilterLaplace5x5: TConvolutionFilter5x5 = (\n    Kernel: ((-1, -1, -1, -1, -1),\n             (-1, -1, -1, -1, -1),\n             (-1, -1, 24, -1, -1),\n             (-1, -1, -1, -1, -1),\n             (-1, -1, -1, -1, -1));\n    Divisor: 1);\n\n  { Kernel for 3x3 spharpening filter (Laplacian + original color).}\n  FilterSharpen3x3: TConvolutionFilter3x3 = (\n    Kernel: ((-1, -1, -1),\n             (-1,  9, -1),\n             (-1, -1, -1));\n    Divisor: 1);\n\n  { Kernel for 5x5 spharpening filter (Laplacian + original color).}\n  FilterSharpen5x5: TConvolutionFilter5x5 = (\n    Kernel: ((-1, -1, -1, -1, -1),\n             (-1, -1, -1, -1, -1),\n             (-1, -1, 25, -1, -1),\n             (-1, -1, -1, -1, -1),\n             (-1, -1, -1, -1, -1));\n    Divisor: 1);\n\n  { Kernel for 5x5 glow filter.}\n  FilterGlow5x5: TConvolutionFilter5x5 = (\n    Kernel: (( 1, 2,   2, 2, 1),\n             ( 2, 0,   0, 0, 2),\n             ( 2, 0, -20, 0, 2),\n             ( 2, 0,   0, 0, 2),\n             ( 1, 2,   2, 2, 1));\n    Divisor: 8);\n\n  { Kernel for 3x3 edge enhancement filter.}\n  FilterEdgeEnhance3x3: TConvolutionFilter3x3 = (\n    Kernel: ((-1, -2, -1),\n             (-2, 16, -2),\n             (-1, -2, -1));\n    Divisor: 4);\n\n  { Kernel for 3x3 contour enhancement filter.}\n  FilterTraceControur3x3: TConvolutionFilter3x3 = (\n    Kernel: ((-6, -6, -2),\n             (-1, 32, -1),\n             (-6, -2, -6));\n    Divisor: 4;\n    Bias:    240/255);\n\n  { Kernel for filter that negates all images pixels.}\n  FilterNegative3x3: TConvolutionFilter3x3 = (\n    Kernel: ((0,  0, 0),\n             (0, -1, 0),\n             (0,  0, 0));\n    Divisor: 1;\n    Bias:    1);\n\n  { Kernel for 3x3 horz/vert embossing filter.}\n  FilterEmboss3x3: TConvolutionFilter3x3 = (\n    Kernel: ((2,  0,  0),\n             (0, -1,  0),\n             (0,  0, -1));\n    Divisor: 1;\n    Bias:    0.5);\n\n\n{ You can register your own canvas class. List of registered canvases is used\n  by FindBestCanvasForImage functions to find best canvas for given image.\n  If two different canvases which support the same image data format are\n  registered then the one that was registered later is returned (so you can\n  override builtin Imaging canvases).}\nprocedure RegisterCanvas(CanvasClass: TImagingCanvasClass);\n{ Returns best canvas for given TImageFormat.}\nfunction FindBestCanvasForImage(ImageFormat: TImageFormat): TImagingCanvasClass; overload;\n{ Returns best canvas for given TImageData.}\nfunction FindBestCanvasForImage(const ImageData: TImageData): TImagingCanvasClass; overload;\n{ Returns best canvas for given TBaseImage.}\nfunction FindBestCanvasForImage(Image: TBaseImage): TImagingCanvasClass; overload;\n\nimplementation\n\nresourcestring\n  SConstructorInvalidPointer = 'Invalid pointer (%p) to TImageData passed to TImagingCanvas constructor.';\n  SConstructorInvalidImage = 'Invalid image data passed to TImagingCanvas constructor (%s).';\n  SConstructorUnsupportedFormat = 'Image passed to TImagingCanvas constructor is in unsupported format (%s)';\n\nvar\n  // list with all registered TImagingCanvas classes\n  CanvasClasses: TList = nil;\n\nprocedure RegisterCanvas(CanvasClass: TImagingCanvasClass);\nbegin\n  Assert(CanvasClass <> nil);\n  if CanvasClasses = nil then\n    CanvasClasses := TList.Create;\n  if CanvasClasses.IndexOf(CanvasClass) < 0 then\n    CanvasClasses.Add(CanvasClass);\nend;\n\nfunction FindBestCanvasForImage(ImageFormat: TImageFormat): TImagingCanvasClass; overload;\nvar\n  I: LongInt;\nbegin\n  for I := CanvasClasses.Count - 1 downto 0 do\n  begin\n    if ImageFormat in TImagingCanvasClass(CanvasClasses[I]).GetSupportedFormats then\n    begin\n      Result := TImagingCanvasClass(CanvasClasses[I]);\n      Exit;\n    end;\n  end;\n  Result := TImagingCanvas;\nend;\n\nfunction FindBestCanvasForImage(const ImageData: TImageData): TImagingCanvasClass;\nbegin\n  Result := FindBestCanvasForImage(ImageData.Format);\nend;\n\nfunction FindBestCanvasForImage(Image: TBaseImage): TImagingCanvasClass;\nbegin\n  Result := FindBestCanvasForImage(Image.Format);\nend;\n\n{ Canvas helper functions }\n\nprocedure PixelBlendProc(const SrcPix: TColorFPRec; DestPtr: PByte;\n  DestInfo: PImageFormatInfo; SrcFactor, DestFactor: TBlendingFactor);\nvar\n  DestPix, FSrc, FDst: TColorFPRec;\nbegin\n  // Get set pixel color\n  DestPix := DestInfo.GetPixelFP(DestPtr, DestInfo, nil);\n  // Determine current blending factors\n  case SrcFactor of\n    bfZero:             FSrc := ColorFP(0, 0, 0, 0);\n    bfOne:              FSrc := ColorFP(1, 1, 1, 1);\n    bfSrcAlpha:         FSrc := ColorFP(SrcPix.A, SrcPix.A, SrcPix.A, SrcPix.A);\n    bfOneMinusSrcAlpha: FSrc := ColorFP(1 - SrcPix.A, 1 - SrcPix.A, 1 - SrcPix.A, 1 - SrcPix.A);\n    bfDstAlpha:         FSrc := ColorFP(DestPix.A, DestPix.A, DestPix.A, DestPix.A);\n    bfOneMinusDstAlpha: FSrc := ColorFP(1 - DestPix.A, 1 - DestPix.A, 1 - DestPix.A, 1 - DestPix.A);\n    bfDstColor:         FSrc := ColorFP(DestPix.A, DestPix.R, DestPix.G, DestPix.B);\n    bfOneMinusDstColor: FSrc := ColorFP(1 - DestPix.A, 1 - DestPix.R, 1 - DestPix.G, 1 - DestPix.B);\n  end;\n  case DestFactor of\n    bfZero:             FDst := ColorFP(0, 0, 0, 0);\n    bfOne:              FDst := ColorFP(1, 1, 1, 1);\n    bfSrcAlpha:         FDst := ColorFP(SrcPix.A, SrcPix.A, SrcPix.A, SrcPix.A);\n    bfOneMinusSrcAlpha: FDst := ColorFP(1 - SrcPix.A, 1 - SrcPix.A, 1 - SrcPix.A, 1 - SrcPix.A);\n    bfDstAlpha:         FDst := ColorFP(DestPix.A, DestPix.A, DestPix.A, DestPix.A);\n    bfOneMinusDstAlpha: FDst := ColorFP(1 - DestPix.A, 1 - DestPix.A, 1 - DestPix.A, 1 - DestPix.A);\n    bfSrcColor:         FDst := ColorFP(SrcPix.A, SrcPix.R, SrcPix.G, SrcPix.B);\n    bfOneMinusSrcColor: FDst := ColorFP(1 - SrcPix.A, 1 - SrcPix.R, 1 - SrcPix.G, 1 - SrcPix.B);\n  end;\n  // Compute blending formula\n  DestPix.R := SrcPix.R * FSrc.R + DestPix.R * FDst.R;\n  DestPix.G := SrcPix.G * FSrc.G + DestPix.G * FDst.G;\n  DestPix.B := SrcPix.B * FSrc.B + DestPix.B * FDst.B;\n  DestPix.A := SrcPix.A * FSrc.A + DestPix.A * FDst.A;\n  // Write blended pixel\n  DestInfo.SetPixelFP(DestPtr, DestInfo, nil, DestPix);\nend;\n\nprocedure PixelAlphaProc(const SrcPix: TColorFPRec; DestPtr: PByte;\n  DestInfo: PImageFormatInfo; SrcFactor, DestFactor: TBlendingFactor);\nvar\n  DestPix: TColorFPRec;\n  SrcAlpha, DestAlpha: Single;\nbegin\n  DestPix := DestInfo.GetPixelFP(DestPtr, DestInfo, nil);\n  // Blend the two pixels (Src 'over' Dest alpha composition operation)\n  DestPix.A := SrcPix.A + DestPix.A - SrcPix.A * DestPix.A;\n  if DestPix.A = 0 then\n    SrcAlpha := 0\n  else\n    SrcAlpha := SrcPix.A / DestPix.A;\n  DestAlpha := 1.0 - SrcAlpha;\n  DestPix.R := SrcPix.R * SrcAlpha + DestPix.R * DestAlpha;\n  DestPix.G := SrcPix.G * SrcAlpha + DestPix.G * DestAlpha;\n  DestPix.B := SrcPix.B * SrcAlpha + DestPix.B * DestAlpha;\n  // Write blended pixel\n  DestInfo.SetPixelFP(DestPtr, DestInfo, nil, DestPix);\nend;\n\nprocedure PixelAddProc(const SrcPix: TColorFPRec; DestPtr: PByte;\n  DestInfo: PImageFormatInfo; SrcFactor, DestFactor: TBlendingFactor);\nvar\n  DestPix: TColorFPRec;\nbegin\n  // Just add Src and Dest\n  DestPix := DestInfo.GetPixelFP(DestPtr, DestInfo, nil);\n  DestPix.R := SrcPix.R + DestPix.R;\n  DestPix.G := SrcPix.G + DestPix.G;\n  DestPix.B := SrcPix.B + DestPix.B;\n  DestPix.A := SrcPix.A + DestPix.A;\n  DestInfo.SetPixelFP(DestPtr, DestInfo, nil, DestPix);\nend;\n\nfunction CompareColors(const C1, C2: TColorFPRec): Single; {$IFDEF USE_INLINE}inline;{$ENDIF}\nbegin\n  Result := (C1.R * GrayConv.R + C1.G * GrayConv.G + C1.B * GrayConv.B) -\n    (C2.R * GrayConv.R + C2.G * GrayConv.G + C2.B * GrayConv.B);\nend;\n\nfunction MedianSelect(var Pixels: TDynFPPixelArray): TColorFPRec;\n\n  procedure QuickSort(L, R: Integer);\n  var\n    I, J: Integer;\n    P, Temp: TColorFPRec;\n  begin\n    repeat\n      I := L;\n      J := R;\n      P := Pixels[(L + R) shr 1];\n      repeat\n        while CompareColors(Pixels[I], P) < 0 do Inc(I);\n        while CompareColors(Pixels[J], P) > 0 do Dec(J);\n        if I <= J then\n        begin\n          Temp := Pixels[I];\n          Pixels[I] := Pixels[J];\n          Pixels[J] := Temp;\n          Inc(I);\n          Dec(J);\n        end;\n      until I > J;\n      if L < J then\n        QuickSort(L, J);\n      L := I;\n    until I >= R;\n  end;\n\nbegin\n  // First sort pixels\n  QuickSort(0, High(Pixels));\n  // Select middle pixel\n  Result := Pixels[Length(Pixels) div 2];\nend;\n\nfunction MinSelect(var Pixels: TDynFPPixelArray): TColorFPRec;\nvar\n  I: Integer;\nbegin\n  Result := Pixels[0];\n  for I := 1 to High(Pixels) do\n  begin\n    if CompareColors(Pixels[I], Result) < 0 then\n      Result := Pixels[I];\n  end;\nend;\n\nfunction MaxSelect(var Pixels: TDynFPPixelArray): TColorFPRec;\nvar\n  I: Integer;\nbegin\n  Result := Pixels[0];\n  for I := 1 to High(Pixels) do\n  begin\n    if CompareColors(Pixels[I], Result) > 0 then\n      Result := Pixels[I];\n  end;\nend;\n\nfunction TransformContrastBrightness(const Pixel: TColorFPRec; C, B, P3: Single): TColorFPRec;\nbegin\n  Result.A := Pixel.A;\n  Result.R := Pixel.R * C + B;\n  Result.G := Pixel.G * C + B;\n  Result.B := Pixel.B * C + B;\nend;\n\nfunction TransformGamma(const Pixel: TColorFPRec; R, G, B: Single): TColorFPRec;\nbegin\n  Result.A := Pixel.A;\n  Result.R := Power(Pixel.R, 1.0 / R);\n  Result.G := Power(Pixel.G, 1.0 / G);\n  Result.B := Power(Pixel.B, 1.0 / B);\nend;\n\nfunction TransformInvert(const Pixel: TColorFPRec; P1, P2, P3: Single): TColorFPRec;\nbegin\n  Result.A := Pixel.A;\n  Result.R := 1.0 - Pixel.R;\n  Result.G := 1.0 - Pixel.G;\n  Result.B := 1.0 - Pixel.B;\nend;\n\nfunction TransformThreshold(const Pixel: TColorFPRec; R, G, B: Single): TColorFPRec;\nbegin\n  Result.A := Pixel.A;\n  Result.R := IffFloat(Pixel.R >= R, 1.0, 0.0);\n  Result.G := IffFloat(Pixel.G >= G, 1.0, 0.0);\n  Result.B := IffFloat(Pixel.B >= B, 1.0, 0.0);\nend;\n\nfunction TransformLevels(const Pixel: TColorFPRec; BlackPoint, WhitePoint, Exp: Single): TColorFPRec;\nbegin\n  Result.A := Pixel.A;\n  if Pixel.R > BlackPoint then\n    Result.R := Power((Pixel.R - BlackPoint) / (WhitePoint - BlackPoint), Exp)\n  else\n    Result.R := 0.0;\n  if Pixel.G > BlackPoint then\n    Result.G := Power((Pixel.G - BlackPoint) / (WhitePoint - BlackPoint), Exp)\n  else\n    Result.G := 0.0;\n  if Pixel.B > BlackPoint then\n    Result.B := Power((Pixel.B - BlackPoint) / (WhitePoint - BlackPoint), Exp)\n  else\n    Result.B := 0.0;\nend;\n\nfunction TransformPremultiplyAlpha(const Pixel: TColorFPRec; P1, P2, P3: Single): TColorFPRec;\nbegin\n  Result.A := Pixel.A;\n  Result.R := Result.R * Pixel.A;\n  Result.G := Result.G * Pixel.A;\n  Result.B := Result.B * Pixel.A;\nend;\n\nfunction TransformUnPremultiplyAlpha(const Pixel: TColorFPRec; P1, P2, P3: Single): TColorFPRec;\nbegin\n  Result.A := Pixel.A;\n  if Pixel.A <> 0.0 then\n  begin\n    Result.R := Result.R / Pixel.A;\n    Result.G := Result.G / Pixel.A;\n    Result.B := Result.B / Pixel.A;\n  end\n  else\n  begin\n    Result.R := 0;\n    Result.G := 0;\n    Result.B := 0;\n  end;\nend;\n\n\n{ TImagingCanvas class implementation }\n\nconstructor TImagingCanvas.CreateForData(ImageDataPointer: PImageData);\nbegin\n  if ImageDataPointer = nil then\n    raise EImagingCanvasError.CreateFmt(SConstructorInvalidPointer, [ImageDataPointer]);\n\n  if not TestImage(ImageDataPointer^) then\n    raise EImagingCanvasError.CreateFmt(SConstructorInvalidImage, [Imaging.ImageToStr(ImageDataPointer^)]);\n\n  if not (ImageDataPointer.Format in GetSupportedFormats) then\n    raise EImagingCanvasError.CreateFmt(SConstructorUnsupportedFormat, [Imaging.ImageToStr(ImageDataPointer^)]);\n\n  FPData := ImageDataPointer;\n  FPenWidth := 1;\n  SetPenColor32(pcWhite);\n  SetFillColor32(pcBlack);\n  FFillMode := fmSolid;\n\n  UpdateCanvasState;\nend;\n\nconstructor TImagingCanvas.CreateForImage(Image: TBaseImage);\nbegin\n  CreateForData(Image.ImageDataPointer);\nend;\n\ndestructor TImagingCanvas.Destroy;\nbegin\n  inherited Destroy;\nend;\n\nfunction TImagingCanvas.GetPixel32(X, Y: LongInt): TColor32;\nbegin\n  Result := Imaging.GetPixel32(FPData^, X, Y).Color;\nend;\n\nfunction TImagingCanvas.GetPixelFP(X, Y: LongInt): TColorFPRec;\nbegin\n  Result := Imaging.GetPixelFP(FPData^, X, Y);\nend;\n\nfunction TImagingCanvas.GetValid: Boolean;\nbegin\n  Result := (FPData <> nil) and (FDataSizeOnUpdate = FPData.Size);\nend;\n\nprocedure TImagingCanvas.SetPixel32(X, Y: LongInt; const Value: TColor32);\nbegin\n  if (X >= FClipRect.Left) and (Y >= FClipRect.Top) and\n    (X < FClipRect.Right) and (Y < FClipRect.Bottom) then\n  begin\n    Imaging.SetPixel32(FPData^, X, Y, TColor32Rec(Value));\n  end;\nend;\n\nprocedure TImagingCanvas.SetPixelFP(X, Y: LongInt; const Value: TColorFPRec);\nbegin\n  if (X >= FClipRect.Left) and (Y >= FClipRect.Top) and\n    (X < FClipRect.Right) and (Y < FClipRect.Bottom) then\n  begin\n    Imaging.SetPixelFP(FPData^, X, Y, TColorFPRec(Value));\n  end;\nend;\n\nprocedure TImagingCanvas.SetPenColor32(const Value: TColor32);\nbegin\n  FPenColor32 := Value;\n  TranslatePixel(@FPenColor32, @FPenColorFP, ifA8R8G8B8, ifA32R32G32B32F, nil, nil);\nend;\n\nprocedure TImagingCanvas.SetPenColorFP(const Value: TColorFPRec);\nbegin\n  FPenColorFP := Value;\n  TranslatePixel(@FPenColorFP, @FPenColor32, ifA32R32G32B32F, ifA8R8G8B8, nil, nil);\nend;\n\nprocedure TImagingCanvas.SetPenWidth(const Value: LongInt);\nbegin\n  FPenWidth := ClampInt(Value, 0, MaxPenWidth);\nend;\n\nprocedure TImagingCanvas.SetFillColor32(const Value: TColor32);\nbegin\n  FFillColor32 := Value;\n  TranslatePixel(@FFillColor32, @FFillColorFP, ifA8R8G8B8, ifA32R32G32B32F, nil, nil);\nend;\n\nprocedure TImagingCanvas.SetFillColorFP(const Value: TColorFPRec);\nbegin\n  FFillColorFP := Value;\n  TranslatePixel(@FFillColorFP, @FFillColor32, ifA32R32G32B32F, ifA8R8G8B8, nil, nil);\nend;\n\nprocedure TImagingCanvas.SetClipRect(const Value: TRect);\nbegin\n  FClipRect := Value;\n  SwapMin(FClipRect.Left, FClipRect.Right);\n  SwapMin(FClipRect.Top, FClipRect.Bottom);\n  IntersectRect(FClipRect, FClipRect, Rect(0, 0, FPData.Width, FPData.Height));\nend;\n\nprocedure TImagingCanvas.CheckBeforeBlending(SrcFactor,\n  DestFactor: TBlendingFactor; DestCanvas: TImagingCanvas);\nbegin\n  if SrcFactor in [bfSrcColor, bfOneMinusSrcColor] then\n    raise EImagingCanvasBlendingError.Create('Invalid source blending factor. Check the documentation for TBlendingFactor.');\n  if DestFactor in [bfDstColor, bfOneMinusDstColor] then\n    raise EImagingCanvasBlendingError.Create('Invalid destination blending factor. Check the documentation for TBlendingFactor.');\n  if DestCanvas.FormatInfo.IsIndexed then\n    raise EImagingCanvasBlendingError.Create('Blending destination canvas cannot be in indexed mode.');\nend;\n\nfunction TImagingCanvas.GetPixelPointer(X, Y: LongInt): Pointer;\nbegin\n  Result := @PByteArray(FPData.Bits)[(Y * FPData.Width + X) * FFormatInfo.BytesPerPixel]\nend;\n\nprocedure TImagingCanvas.TranslateFPToNative(const Color: TColorFPRec);\nbegin\n  TranslateFPToNative(Color, @FNativeColor);\nend;\n\nprocedure TImagingCanvas.TranslateFPToNative(const Color: TColorFPRec;\n  Native: Pointer);\nbegin\n  ImagingFormats.TranslatePixel(@Color, Native, ifA32R32G32B32F,\n    FPData.Format, nil, FPData.Palette);\nend;\n\nprocedure TImagingCanvas.UpdateCanvasState;\nbegin\n  FDataSizeOnUpdate := FPData.Size;\n  ResetClipRect;\n  Imaging.GetImageFormatInfo(FPData.Format, FFormatInfo)\nend;\n\nprocedure TImagingCanvas.ResetClipRect;\nbegin\n  FClipRect := Rect(0, 0, FPData.Width, FPData.Height)\nend;\n\nprocedure TImagingCanvas.Clear;\nbegin\n  TranslateFPToNative(FFillColorFP);\n  Imaging.FillRect(FPData^, 0, 0, FPData.Width, FPData.Height, @FNativeColor);\nend;\n\nfunction TImagingCanvas.ClipAxisParallelLine(var A1, A2, B: LongInt;\n  AStart, AStop, BStart, BStop: LongInt): Boolean;\nbegin\n  if (B >= BStart) and (B < BStop) then\n  begin\n    SwapMin(A1, A2);\n    if A1 < AStart then A1 := AStart;\n    if A2 >= AStop then A2 := AStop - 1;\n    Result := True;\n  end\n  else\n    Result := False;\nend;\n\nprocedure TImagingCanvas.HorzLineInternal(X1, X2, Y: LongInt; Color: Pointer;\n  Bpp: LongInt);\nvar\n  I, WidthBytes: LongInt;\n  PixelPtr: PByte;\nbegin\n  if (Y >= FClipRect.Top) and (Y < FClipRect.Bottom) then\n  begin\n    SwapMin(X1, X2);\n    X1 := Max(X1, FClipRect.Left);\n    X2 := Min(X2, FClipRect.Right);\n    PixelPtr := GetPixelPointer(X1, Y);\n    WidthBytes := (X2 - X1) * Bpp;\n    case Bpp of\n      1: FillMemoryByte(PixelPtr, WidthBytes, PByte(Color)^);\n      2: FillMemoryWord(PixelPtr, WidthBytes, PWord(Color)^);\n      4: FillMemoryLongWord(PixelPtr, WidthBytes, PLongWord(Color)^);\n    else\n      for I := X1 to X2 do\n      begin\n        ImagingFormats.CopyPixel(Color, PixelPtr, Bpp);\n        Inc(PixelPtr, Bpp);\n       end;\n    end;\n  end;\nend;\n\nprocedure TImagingCanvas.CopyPixelInternal(X, Y: LongInt; Pixel: Pointer;\n  Bpp: LongInt);\nbegin\n  if (X >= FClipRect.Left) and (Y >= FClipRect.Top) and\n    (X < FClipRect.Right) and (Y < FClipRect.Bottom) then\n  begin\n    ImagingFormats.CopyPixel(Pixel, GetPixelPointer(X, Y), Bpp);\n  end;\nend;\n\nprocedure TImagingCanvas.HorzLine(X1, X2, Y: LongInt);\nvar\n  DstRect: TRect;\nbegin\n  if FPenMode = pmClear then Exit;\n  SwapMin(X1, X2);\n  if IntersectRect(DstRect, Rect(X1, Y - FPenWidth div 2, X2,\n    Y + FPenWidth div 2 + FPenWidth mod 2), FClipRect) then\n  begin\n    TranslateFPToNative(FPenColorFP);\n    Imaging.FillRect(FPData^, DstRect.Left, DstRect.Top, DstRect.Right - DstRect.Left,\n      DstRect.Bottom - DstRect.Top, @FNativeColor);\n  end;\nend;\n\nprocedure TImagingCanvas.VertLine(X, Y1, Y2: LongInt);\nvar\n  DstRect: TRect;\nbegin\n  if FPenMode = pmClear then Exit;\n  SwapMin(Y1, Y2);\n  if IntersectRect(DstRect, Rect(X - FPenWidth div 2, Y1,\n    X + FPenWidth div 2 + FPenWidth mod 2, Y2), FClipRect) then\n  begin\n    TranslateFPToNative(FPenColorFP);\n    Imaging.FillRect(FPData^, DstRect.Left, DstRect.Top, DstRect.Right - DstRect.Left,\n      DstRect.Bottom - DstRect.Top, @FNativeColor);\n  end;\nend;\n\nprocedure TImagingCanvas.Line(X1, Y1, X2, Y2: LongInt);\nvar\n  Steep: Boolean;\n  Error, YStep, DeltaX, DeltaY, X, Y, I, Bpp, W1, W2, Code1, Code2: LongInt;\nbegin\n  if FPenMode = pmClear then Exit;\n\n  // If line is vertical or horizontal just call appropriate method\n  if X2 = X1 then\n  begin\n    VertLine(X1, Y1, Y2);\n    Exit;\n  end;\n  if Y2 = Y1 then\n  begin\n    HorzLine(X1, X2, Y1);\n    Exit;\n  end;\n\n  // Determine if line is steep (angle with X-axis > 45 degrees)\n  Steep := Abs(Y2 - Y1) > Abs(X2 - X1);\n\n  // If we need to draw thick line we just draw more 1 pixel lines around\n  // the one we already drawn. Setting FLineRecursion assures that we\n  // won't be doing recursions till the end of the world.\n  if (FPenWidth > 1) and not FLineRecursion then\n  begin\n    FLineRecursion := True;\n    W1 := FPenWidth div 2;\n    W2 := W1;\n    if FPenWidth mod 2 = 0 then\n      Dec(W1);\n    if Steep then\n    begin\n      // Add lines left/right\n      for I := 1 to W1 do\n        Line(X1, Y1 - I, X2, Y2 - I);\n      for I := 1 to W2 do\n        Line(X1, Y1 + I, X2, Y2 + I);\n    end\n    else\n    begin\n      // Add lines above/under\n      for I := 1 to W1 do\n        Line(X1 - I, Y1, X2 - I, Y2);\n      for I := 1 to W2 do\n        Line(X1 + I, Y1, X2 + I, Y2);\n    end;\n    FLineRecursion := False;\n  end;\n\n  with FClipRect do\n  begin\n    // Use part of Cohen-Sutherland line clipping to determine if any part of line\n    // is in ClipRect\n    Code1 := Ord(X1 < Left) + Ord(X1 > Right) shl 1 + Ord(Y1 < Top) shl 2 + Ord(Y1 > Bottom) shl 3;\n    Code2 := Ord(X2 < Left) + Ord(X2 > Right) shl 1 + Ord(Y2 < Top) shl 2 + Ord(Y2 > Bottom) shl 3;\n  end;\n\n  if (Code1 and Code2) = 0 then\n  begin\n    TranslateFPToNative(FPenColorFP);\n    Bpp := FFormatInfo.BytesPerPixel;\n\n    // If line is steep swap X and Y coordinates so later we just have one loop\n    // of two (where only one is used according to steepness).\n    if Steep then\n    begin\n      SwapValues(X1, Y1);\n      SwapValues(X2, Y2);\n    end;\n    if X1 > X2 then\n    begin\n      SwapValues(X1, X2);\n      SwapValues(Y1, Y2);\n    end;\n\n    DeltaX := X2 - X1;\n    DeltaY := Abs(Y2 - Y1);\n    YStep := Iff(Y2 > Y1, 1, -1);\n    Error := 0;\n    Y := Y1;\n\n    // Draw line using Bresenham algorithm. No real line clipping here,\n    // just don't draw pixels outsize clip rect.\n    for X := X1 to X2 do\n    begin\n      if Steep then\n        CopyPixelInternal(Y, X, @FNativeColor, Bpp)\n      else\n        CopyPixelInternal(X, Y, @FNativeColor, Bpp);\n      Error := Error + DeltaY;\n      if Error * 2 >= DeltaX then\n      begin\n        Inc(Y, YStep);\n        Dec(Error, DeltaX);\n      end;\n    end;\n  end;\nend;\n\nprocedure TImagingCanvas.FrameRect(const Rect: TRect);\nvar\n  HalfPen, PenMod: LongInt;\nbegin\n  if FPenMode = pmClear then Exit;\n  HalfPen := FPenWidth div 2;\n  PenMod := FPenWidth mod 2;\n  HorzLine(Rect.Left - HalfPen, Rect.Right + HalfPen + PenMod - 1, Rect.Top);\n  HorzLine(Rect.Left - HalfPen, Rect.Right + HalfPen + PenMod - 1, Rect.Bottom - 1);\n  VertLine(Rect.Left, Rect.Top, Rect.Bottom);\n  VertLine(Rect.Right - 1, Rect.Top, Rect.Bottom);\nend;\n\nprocedure TImagingCanvas.FillRect(const Rect: TRect);\nvar\n  DstRect: TRect;\nbegin\n  if (FFillMode <> fmClear) and IntersectRect(DstRect, Rect, FClipRect) then\n  begin\n    TranslateFPToNative(FFillColorFP);\n    Imaging.FillRect(FPData^, DstRect.Left, DstRect.Top, DstRect.Right - DstRect.Left,\n      DstRect.Bottom - DstRect.Top, @FNativeColor);\n  end;\nend;\n\nprocedure TImagingCanvas.FillRectBlend(const Rect: TRect; SrcFactor,\n  DestFactor: TBlendingFactor);\nvar\n  DstRect: TRect;\n  X, Y: Integer;\n  Line: PByte;\nbegin\n  if (FFillMode <> fmClear) and IntersectRect(DstRect, Rect, FClipRect) then\n  begin\n    CheckBeforeBlending(SrcFactor, DestFactor, Self);\n    for Y := DstRect.Top to DstRect.Bottom - 1 do\n    begin\n      Line := @PByteArray(FPData.Bits)[(Y * FPData.Width + DstRect.Left) * FFormatInfo.BytesPerPixel];\n      for X := DstRect.Left to DstRect.Right - 1 do\n      begin\n        PixelBlendProc(FFillColorFP, Line, @FFormatInfo, SrcFactor, DestFactor);\n        Inc(Line, FFormatInfo.BytesPerPixel);\n      end;\n    end;\n  end;\nend;\n\nprocedure TImagingCanvas.Rectangle(const Rect: TRect);\nbegin\n  FillRect(Rect);\n  FrameRect(Rect);\nend;\n\nprocedure TImagingCanvas.Ellipse(const Rect: TRect);\nvar\n RadX, RadY, DeltaX, DeltaY, R, RX, RY: LongInt;\n X1, X2, Y1, Y2, Bpp, OldY: LongInt;\n Fill, Pen: TColorFPRec;\nbegin\n  // TODO: Use PenWidth\n  X1 := Rect.Left;\n  X2 := Rect.Right;\n  Y1 := Rect.Top;\n  Y2 := Rect.Bottom;\n\n  TranslateFPToNative(FPenColorFP, @Pen);\n  TranslateFPToNative(FFillColorFP, @Fill);\n  Bpp := FFormatInfo.BytesPerPixel;\n\n  SwapMin(X1, X2);\n  SwapMin(Y1, Y2);\n\n  RadX := (X2 - X1) div 2;\n  RadY := (Y2 - Y1) div 2;\n\n  Y1 := Y1 + RadY;\n  Y2 := Y1;\n  OldY := Y1;\n\n  DeltaX := (RadX * RadX);\n  DeltaY := (RadY * RadY);\n  R  := RadX * RadY * RadY;\n  RX := R;\n  RY := 0;\n\n  if (FFillMode <> fmClear) then\n    HorzLineInternal(X1, X2, Y1, @Fill, Bpp);\n  CopyPixelInternal(X1, Y1, @Pen, Bpp);\n  CopyPixelInternal(X2, Y1, @Pen, Bpp);\n\n  while RadX > 0 do\n  begin\n    if R > 0 then\n    begin\n      Inc(Y1);\n      Dec(Y2);\n      Inc(RY, DeltaX);\n      Dec(R, RY);\n    end;\n    if R <= 0 then\n    begin\n      Dec(RadX);\n      Inc(X1);\n      Dec(X2);\n      Dec(RX, DeltaY);\n      Inc(R, RX);\n    end;\n\n    if (OldY <> Y1) and (FFillMode <> fmClear) then\n    begin\n      HorzLineInternal(X1, X2, Y1, @Fill, Bpp);\n      HorzLineInternal(X1, X2, Y2, @Fill, Bpp);\n    end;\n    OldY := Y1;\n\n    CopyPixelInternal(X1, Y1, @Pen, Bpp);\n    CopyPixelInternal(X2, Y1, @Pen, Bpp);\n    CopyPixelInternal(X1, Y2, @Pen, Bpp);\n    CopyPixelInternal(X2, Y2, @Pen, Bpp);\n  end;\nend;\n\nprocedure TImagingCanvas.FloodFill(X, Y: Integer; BoundaryFillMode: Boolean);\nvar\n  Stack: array of TPoint;\n  StackPos, Y1: Integer;\n  OldColor: TColor32;\n  SpanLeft, SpanRight: Boolean;\n\n  procedure Push(AX, AY: Integer);\n  begin\n    if StackPos < High(Stack) then\n    begin\n      Inc(StackPos);\n      Stack[StackPos].X := AX;\n      Stack[StackPos].Y := AY;\n    end\n    else\n    begin\n      SetLength(Stack, Length(Stack) + FPData.Width);\n      Push(AX, AY);\n    end;\n  end;\n\n  function Pop(out AX, AY: Integer): Boolean;\n  begin\n    if StackPos > 0 then\n    begin\n      AX := Stack[StackPos].X;\n      AY := Stack[StackPos].Y;\n      Dec(StackPos);\n      Result := True;\n    end\n    else\n      Result := False;\n  end;\n\n  function Compare(AX, AY: Integer): Boolean;\n  var\n    Color: TColor32;\n  begin\n    Color := GetPixel32(AX, AY);\n    if BoundaryFillMode then\n      Result := (Color <> FFillColor32) and (Color <> FPenColor32)\n    else\n      Result := Color = OldColor;\n  end;\n\nbegin\n  // Scanline Floodfill Algorithm With Stack\n  // http://student.kuleuven.be/~m0216922/CG/floodfill.html\n\n  if not PtInRect(FClipRect, Point(X, Y)) then Exit;\n\n  SetLength(Stack, FPData.Width * 4);\n  StackPos := 0;\n\n  OldColor := GetPixel32(X, Y);\n\n  Push(X, Y);\n\n  while Pop(X, Y) do\n  begin\n    Y1 := Y;\n    while (Y1 >= FClipRect.Top) and Compare(X, Y1) do\n      Dec(Y1);\n\n    Inc(Y1);\n    SpanLeft := False;\n    SpanRight := False;\n\n    while (Y1 < FClipRect.Bottom) and Compare(X, Y1) do\n    begin\n      SetPixel32(X, Y1, FFillColor32);\n      if not SpanLeft and (X > FClipRect.Left) and Compare(X - 1, Y1) then\n      begin\n        Push(X - 1, Y1);\n        SpanLeft := True;\n      end\n      else if SpanLeft and (X > FClipRect.Left) and not Compare(X - 1, Y1) then\n        SpanLeft := False\n      else if not SpanRight and (X < FClipRect.Right - 1) and Compare(X + 1, Y1)then\n      begin\n        Push(X + 1, Y1);\n        SpanRight := True;\n      end\n      else if SpanRight and (X < FClipRect.Right - 1) and not Compare(X + 1, Y1) then\n        SpanRight := False;\n\n      Inc(Y1);\n    end;\n  end;\nend;\n\nprocedure TImagingCanvas.DrawInternal(const SrcRect: TRect;\n  DestCanvas: TImagingCanvas; DestX, DestY: Integer; SrcFactor,\n  DestFactor: TBlendingFactor; PixelWriteProc: TPixelWriteProc);\nvar\n  X, Y, SrcX, SrcY, Width, Height, SrcBpp, DestBpp: Integer;\n  PSrc: TColorFPRec;\n  SrcPointer, DestPointer: PByte;\nbegin\n  CheckBeforeBlending(SrcFactor, DestFactor, DestCanvas);\n  SrcX := SrcRect.Left;\n  SrcY := SrcRect.Top;\n  Width := SrcRect.Right - SrcRect.Left;\n  Height := SrcRect.Bottom - SrcRect.Top;\n  SrcBpp := FFormatInfo.BytesPerPixel;\n  DestBpp := DestCanvas.FFormatInfo.BytesPerPixel;\n  // Clip src and dst rects\n  ClipCopyBounds(SrcX, SrcY, Width, Height, DestX, DestY,\n    FPData.Width, FPData.Height, DestCanvas.ClipRect);\n\n  for Y := 0 to Height - 1 do\n  begin\n    // Get src and dst scanlines\n    SrcPointer := @PByteArray(FPData.Bits)[((SrcY + Y) * FPData.Width + SrcX) * SrcBpp];\n    DestPointer := @PByteArray(DestCanvas.FPData.Bits)[((DestY + Y) * DestCanvas.FPData.Width + DestX) * DestBpp];\n\n    for X := 0 to Width - 1 do\n    begin\n      PSrc := FFormatInfo.GetPixelFP(SrcPointer, @FFormatInfo, FPData.Palette);\n      // Call pixel writer procedure - combine source and dest pixels\n      PixelWriteProc(PSrc, DestPointer, @DestCanvas.FFormatInfo, SrcFactor, DestFactor);\n      // Increment pixel pointers\n      Inc(SrcPointer, SrcBpp);\n      Inc(DestPointer, DestBpp);\n    end;\n  end;\nend;\n\nprocedure TImagingCanvas.DrawBlend(const SrcRect: TRect; DestCanvas: TImagingCanvas;\n  DestX, DestY: Integer; SrcFactor, DestFactor: TBlendingFactor);\nbegin\n  DrawInternal(SrcRect, DestCanvas, DestX, DestY, SrcFactor, DestFactor, PixelBlendProc);\nend;\n\nprocedure TImagingCanvas.DrawAlpha(const SrcRect: TRect; DestCanvas: TImagingCanvas;\n  DestX, DestY: Integer);\nbegin\n  DrawInternal(SrcRect, DestCanvas, DestX, DestY, bfIgnore, bfIgnore, PixelAlphaProc);\nend;\n\nprocedure TImagingCanvas.DrawAdd(const SrcRect: TRect;\n  DestCanvas: TImagingCanvas; DestX, DestY: Integer);\nbegin\n  DrawInternal(SrcRect, DestCanvas, DestX, DestY, bfIgnore, bfIgnore, PixelAddProc);\nend;\n\nprocedure TImagingCanvas.StretchDrawInternal(const SrcRect: TRect;\n  DestCanvas: TImagingCanvas; const DestRect: TRect;\n  SrcFactor, DestFactor: TBlendingFactor; Filter: TResizeFilter;\n  PixelWriteProc: TPixelWriteProc);\nconst\n  FilterMapping: array[TResizeFilter] of TSamplingFilter =\n    (sfNearest, sfLinear, DefaultCubicFilter, sfLanczos);\nvar\n  X, Y, I, J, SrcX, SrcY, SrcWidth, SrcHeight: Integer;\n  DestX, DestY, DestWidth, DestHeight, SrcBpp, DestBpp: Integer;\n  SrcPix: TColorFPRec;\n  MapX, MapY: TMappingTable;\n  XMinimum, XMaximum: Integer;\n  LineBuffer: array of TColorFPRec;\n  ClusterX, ClusterY: TCluster;\n  Weight, AccumA, AccumR, AccumG, AccumB: Single;\n  DestLine: PByte;\n  FilterFunction: TFilterFunction;\n  Radius: Single;\nbegin\n  CheckBeforeBlending(SrcFactor, DestFactor, DestCanvas);\n  SrcX := SrcRect.Left;\n  SrcY := SrcRect.Top;\n  SrcWidth := SrcRect.Right - SrcRect.Left;\n  SrcHeight := SrcRect.Bottom - SrcRect.Top;\n  DestX := DestRect.Left;\n  DestY := DestRect.Top;\n  DestWidth := DestRect.Right - DestRect.Left;\n  DestHeight := DestRect.Bottom - DestRect.Top;\n  SrcBpp := FFormatInfo.BytesPerPixel;\n  DestBpp := DestCanvas.FFormatInfo.BytesPerPixel;\n  // Get actual resampling filter and radius\n  FilterFunction := SamplingFilterFunctions[FilterMapping[Filter]];\n  Radius := SamplingFilterRadii[FilterMapping[Filter]];\n  // Clip src and dst rects\n  ClipStretchBounds(SrcX, SrcY, SrcWidth, SrcHeight, DestX, DestY, DestWidth, DestHeight,\n      FPData.Width, FPData.Height, DestCanvas.ClipRect);\n  // Generate mapping tables\n  MapX := BuildMappingTable(DestX, DestX + DestWidth, SrcX, SrcX + SrcWidth,\n    FPData.Width, FilterFunction, Radius, False);\n  MapY := BuildMappingTable(DestY, DestY + DestHeight, SrcY, SrcY + SrcHeight,\n    FPData.Height, FilterFunction, Radius, False);\n  FindExtremes(MapX, XMinimum, XMaximum);\n  SetLength(LineBuffer, XMaximum - XMinimum + 1);\n\n  for J := 0 to DestHeight - 1 do\n  begin\n    ClusterY := MapY[J];\n    for X := XMinimum to XMaximum do\n    begin\n      AccumA := 0.0;\n      AccumR := 0.0;\n      AccumG := 0.0;\n      AccumB := 0.0;\n      for Y := 0 to Length(ClusterY) - 1 do\n      begin\n        Weight := ClusterY[Y].Weight;\n        SrcPix := FFormatInfo.GetPixelFP(@PByteArray(FPData.Bits)[(ClusterY[Y].Pos * FPData.Width + X) * SrcBpp],\n          @FFormatInfo, FPData.Palette);\n        AccumB := AccumB + SrcPix.B * Weight;\n        AccumG := AccumG + SrcPix.G * Weight;\n        AccumR := AccumR + SrcPix.R * Weight;\n        AccumA := AccumA + SrcPix.A * Weight;\n      end;\n      with LineBuffer[X - XMinimum] do\n      begin\n        A := AccumA;\n        R := AccumR;\n        G := AccumG;\n        B := AccumB;\n      end;\n    end;\n\n    DestLine := @PByteArray(DestCanvas.FPData.Bits)[((J + DestY) * DestCanvas.FPData.Width + DestX) * DestBpp];\n\n    for I := 0 to DestWidth - 1 do\n    begin\n      ClusterX := MapX[I];\n      AccumA := 0.0;\n      AccumR := 0.0;\n      AccumG := 0.0;\n      AccumB := 0.0;\n      for X := 0 to Length(ClusterX) - 1 do\n      begin\n        Weight := ClusterX[X].Weight;\n        with LineBuffer[ClusterX[X].Pos - XMinimum] do\n        begin\n          AccumB := AccumB + B * Weight;\n          AccumG := AccumG + G * Weight;\n          AccumR := AccumR + R * Weight;\n          AccumA := AccumA + A * Weight;\n        end;\n      end;\n\n      SrcPix.A := AccumA;\n      SrcPix.R := AccumR;\n      SrcPix.G := AccumG;\n      SrcPix.B := AccumB;\n\n      // Write resulting blended pixel\n      PixelWriteProc(SrcPix, DestLine, @DestCanvas.FFormatInfo, SrcFactor, DestFactor);\n      Inc(DestLine, DestBpp);\n    end;\n  end;\nend;\n\nprocedure TImagingCanvas.StretchDrawBlend(const SrcRect: TRect;\n  DestCanvas: TImagingCanvas; const DestRect: TRect;\n  SrcFactor, DestFactor: TBlendingFactor; Filter: TResizeFilter);\nbegin\n  StretchDrawInternal(SrcRect, DestCanvas, DestRect, SrcFactor, DestFactor, Filter, PixelBlendProc);\nend;\n\nprocedure TImagingCanvas.StretchDrawAlpha(const SrcRect: TRect;\n  DestCanvas: TImagingCanvas; const DestRect: TRect; Filter: TResizeFilter);\nbegin\n  StretchDrawInternal(SrcRect, DestCanvas, DestRect, bfIgnore, bfIgnore, Filter, PixelAlphaProc);\nend;\n\nprocedure TImagingCanvas.StretchDrawAdd(const SrcRect: TRect;\n  DestCanvas: TImagingCanvas; const DestRect: TRect; Filter: TResizeFilter);\nbegin\n  StretchDrawInternal(SrcRect, DestCanvas, DestRect, bfIgnore, bfIgnore, Filter, PixelAddProc);\nend;\n\nprocedure TImagingCanvas.ApplyConvolution(Kernel: PLongInt; KernelSize,\n  Divisor: LongInt; Bias: Single; ClampChannels: Boolean);\nvar\n  X, Y, I, J, PosY, PosX, SizeDiv2, KernelValue, WidthBytes, Bpp: LongInt;\n  R, G, B, DivFloat: Single;\n  Pixel: TColorFPRec;\n  TempImage: TImageData;\n  DstPointer, SrcPointer: PByte;\nbegin\n  SizeDiv2 := KernelSize div 2;\n  DivFloat := IffFloat(Divisor > 1, 1.0 / Divisor, 1.0);\n  Bpp := FFormatInfo.BytesPerPixel;\n  WidthBytes := FPData.Width * Bpp;\n\n  InitImage(TempImage);\n  CloneImage(FPData^, TempImage);\n\n  try\n    // For every pixel in clip rect\n    for Y := FClipRect.Top to FClipRect.Bottom - 1 do\n    begin\n      DstPointer := @PByteArray(FPData.Bits)[Y * WidthBytes + FClipRect.Left * Bpp];\n\n      for X := FClipRect.Left to FClipRect.Right - 1 do\n      begin\n        // Reset accumulators\n        R := 0.0;\n        G := 0.0;\n        B := 0.0;\n\n        for J := 0 to KernelSize - 1 do\n        begin\n          PosY := ClampInt(Y + J - SizeDiv2, FClipRect.Top, FClipRect.Bottom - 1);\n\n          for I := 0 to KernelSize - 1 do\n          begin\n            PosX := ClampInt(X + I - SizeDiv2, FClipRect.Left, FClipRect.Right - 1);\n            SrcPointer := @PByteArray(TempImage.Bits)[PosY * WidthBytes + PosX * Bpp];\n\n            // Get pixels from neighbourhood of current pixel and add their\n            // colors to accumulators weighted by filter kernel values\n            Pixel := FFormatInfo.GetPixelFP(SrcPointer, @FFormatInfo, TempImage.Palette);\n            KernelValue := PLongIntArray(Kernel)[J * KernelSize + I];\n\n            R := R + Pixel.R * KernelValue;\n            G := G + Pixel.G * KernelValue;\n            B := B + Pixel.B * KernelValue;\n          end;\n        end;\n\n        Pixel := FFormatInfo.GetPixelFP(DstPointer, @FFormatInfo, FPData.Palette);\n\n        Pixel.R := R * DivFloat + Bias;\n        Pixel.G := G * DivFloat + Bias;\n        Pixel.B := B * DivFloat + Bias;\n\n        if ClampChannels then\n          ClampFloatPixel(Pixel);\n\n        // Set resulting pixel color\n        FFormatInfo.SetPixelFP(DstPointer, @FFormatInfo, FPData.Palette, Pixel);\n\n        Inc(DstPointer, Bpp);\n      end;\n    end;\n\n  finally\n    FreeImage(TempImage);\n  end;\nend;\n\nprocedure TImagingCanvas.ApplyConvolution3x3(const Filter: TConvolutionFilter3x3);\nbegin\n  ApplyConvolution(@Filter.Kernel, 3, Filter.Divisor, Filter.Bias, True);\nend;\n\nprocedure TImagingCanvas.ApplyConvolution5x5(const Filter: TConvolutionFilter5x5);\nbegin\n  ApplyConvolution(@Filter.Kernel, 5, Filter.Divisor, Filter.Bias, True);\nend;\n\nprocedure TImagingCanvas.ApplyNonLinearFilter(FilterSize: Integer; SelectFunc: TSelectPixelFunction);\nvar\n  X, Y, I, J, PosY, PosX, SizeDiv2, WidthBytes, Bpp: LongInt;\n  Pixel: TColorFPRec;\n  TempImage: TImageData;\n  DstPointer, SrcPointer: PByte;\n  NeighPixels: TDynFPPixelArray;\nbegin\n  SizeDiv2 := FilterSize div 2;\n  Bpp := FFormatInfo.BytesPerPixel;\n  WidthBytes := FPData.Width * Bpp;\n  SetLength(NeighPixels, FilterSize * FilterSize);\n\n  InitImage(TempImage);\n  CloneImage(FPData^, TempImage);\n\n  try\n    // For every pixel in clip rect\n    for Y := FClipRect.Top to FClipRect.Bottom - 1 do\n    begin\n      DstPointer := @PByteArray(FPData.Bits)[Y * WidthBytes + FClipRect.Left * Bpp];\n\n      for X := FClipRect.Left to FClipRect.Right - 1 do\n      begin\n        for J := 0 to FilterSize - 1 do\n        begin\n          PosY := ClampInt(Y + J - SizeDiv2, FClipRect.Top, FClipRect.Bottom - 1);\n\n          for I := 0 to FilterSize - 1 do\n          begin\n            PosX := ClampInt(X + I - SizeDiv2, FClipRect.Left, FClipRect.Right - 1);\n            SrcPointer := @PByteArray(TempImage.Bits)[PosY * WidthBytes + PosX * Bpp];\n\n            // Get pixels from neighbourhood of current pixel and store them\n            Pixel := FFormatInfo.GetPixelFP(SrcPointer, @FFormatInfo, TempImage.Palette);\n            NeighPixels[J * FilterSize + I] := Pixel;\n          end;\n        end;\n\n        // Choose pixel using custom function\n        Pixel := SelectFunc(NeighPixels);\n        // Set resulting pixel color\n        FFormatInfo.SetPixelFP(DstPointer, @FFormatInfo, FPData.Palette, Pixel);\n\n        Inc(DstPointer, Bpp);\n      end;\n    end;\n\n  finally\n    FreeImage(TempImage);\n  end;\nend;\n\nprocedure TImagingCanvas.ApplyMedianFilter(FilterSize: Integer);\nbegin\n  ApplyNonLinearFilter(FilterSize, MedianSelect);\nend;\n\nprocedure TImagingCanvas.ApplyMinFilter(FilterSize: Integer);\nbegin\n  ApplyNonLinearFilter(FilterSize, MinSelect);\nend;\n\nprocedure TImagingCanvas.ApplyMaxFilter(FilterSize: Integer);\nbegin\n  ApplyNonLinearFilter(FilterSize, MaxSelect);\nend;\n\nprocedure TImagingCanvas.PointTransform(Transform: TPointTransformFunction;\n  Param1, Param2, Param3: Single);\nvar\n  X, Y, Bpp, WidthBytes: Integer;\n  PixPointer: PByte;\n  Pixel: TColorFPRec;\nbegin\n  Bpp := FFormatInfo.BytesPerPixel;\n  WidthBytes := FPData.Width * Bpp;\n\n  // For every pixel in clip rect\n  for Y := FClipRect.Top to FClipRect.Bottom - 1 do\n  begin\n    PixPointer := @PByteArray(FPData.Bits)[Y * WidthBytes + FClipRect.Left * Bpp];\n    for X := FClipRect.Left to FClipRect.Right - 1 do\n    begin\n      Pixel := FFormatInfo.GetPixelFP(PixPointer, @FFormatInfo, FPData.Palette);\n\n      FFormatInfo.SetPixelFP(PixPointer, @FFormatInfo, FPData.Palette,\n        Transform(Pixel, Param1, Param2, Param3));\n\n      Inc(PixPointer, Bpp);\n    end;\n  end;\nend;\n\nprocedure TImagingCanvas.ModifyContrastBrightness(Contrast, Brightness: Single);\nbegin\n  PointTransform(TransformContrastBrightness, 1.0 + Contrast / 100,\n    Brightness / 100, 0);\nend;\n\nprocedure TImagingCanvas.GammaCorection(Red, Green, Blue: Single);\nbegin\n  PointTransform(TransformGamma, Red, Green, Blue);\nend;\n\nprocedure TImagingCanvas.InvertColors;\nbegin\n  PointTransform(TransformInvert, 0, 0, 0);\nend;\n\nprocedure TImagingCanvas.Threshold(Red, Green, Blue: Single);\nbegin\n  PointTransform(TransformThreshold, Red, Green, Blue);\nend;\n\nprocedure TImagingCanvas.AdjustColorLevels(BlackPoint, WhitePoint, MidPoint: Single);\nbegin\n  PointTransform(TransformLevels, BlackPoint, WhitePoint, 1.0 / MidPoint);\nend;\n\nprocedure TImagingCanvas.PremultiplyAlpha;\nbegin\n  PointTransform(TransformPremultiplyAlpha, 0, 0, 0);\nend;\n\nprocedure TImagingCanvas.UnPremultiplyAlpha;\nbegin\n  PointTransform(TransformUnPremultiplyAlpha, 0, 0, 0);\nend;\n\nprocedure TImagingCanvas.GetHistogram(out Red, Green, Blue, Alpha,\n  Gray: THistogramArray);\nvar\n  X, Y, Bpp: Integer;\n  PixPointer: PByte;\n  Color32: TColor32Rec;\nbegin\n  FillChar(Red,   SizeOf(Red), 0);\n  FillChar(Green, SizeOf(Green), 0);\n  FillChar(Blue,  SizeOf(Blue), 0);\n  FillChar(Alpha, SizeOf(Alpha), 0);\n  FillChar(Gray,  SizeOf(Gray), 0);\n\n  Bpp := FFormatInfo.BytesPerPixel;\n\n  for Y := FClipRect.Top to FClipRect.Bottom - 1 do\n  begin\n    PixPointer := @PByteArray(FPData.Bits)[Y * FPData.Width * Bpp + FClipRect.Left * Bpp];\n    for X := FClipRect.Left to FClipRect.Right - 1 do\n    begin\n      Color32 := FFormatInfo.GetPixel32(PixPointer, @FFormatInfo, FPData.Palette);\n\n      Inc(Red[Color32.R]);\n      Inc(Green[Color32.G]);\n      Inc(Blue[Color32.B]);\n      Inc(Alpha[Color32.A]);\n      Inc(Gray[Round(GrayConv.R * Color32.R + GrayConv.G * Color32.G + GrayConv.B * Color32.B)]);\n\n      Inc(PixPointer, Bpp);\n    end;\n  end;\nend;\n\nprocedure TImagingCanvas.FillChannel(ChannelId: Integer; NewChannelValue: Byte);\nvar\n  X, Y, Bpp: Integer;\n  PixPointer: PByte;\n  Color32: TColor32Rec;\nbegin\n  Bpp := FFormatInfo.BytesPerPixel;\n\n  for Y := FClipRect.Top to FClipRect.Bottom - 1 do\n  begin\n    PixPointer := @PByteArray(FPData.Bits)[Y * FPData.Width * Bpp + FClipRect.Left * Bpp];\n    for X := FClipRect.Left to FClipRect.Right - 1 do\n    begin\n      Color32 := FFormatInfo.GetPixel32(PixPointer, @FFormatInfo, FPData.Palette);\n      Color32.Channels[ChannelId] := NewChannelValue;\n      FFormatInfo.SetPixel32(PixPointer, @FFormatInfo, FPData.Palette, Color32);\n\n      Inc(PixPointer, Bpp);\n    end;\n  end;\nend;\n\nprocedure TImagingCanvas.FillChannelFP(ChannelId: Integer; NewChannelValue: Single);\nvar\n  X, Y, Bpp: Integer;\n  PixPointer: PByte;\n  ColorFP: TColorFPRec;\nbegin\n  Bpp := FFormatInfo.BytesPerPixel;\n\n  for Y := FClipRect.Top to FClipRect.Bottom - 1 do\n  begin\n    PixPointer := @PByteArray(FPData.Bits)[Y * FPData.Width * Bpp + FClipRect.Left * Bpp];\n    for X := FClipRect.Left to FClipRect.Right - 1 do\n    begin\n      ColorFP := FFormatInfo.GetPixelFP(PixPointer, @FFormatInfo, FPData.Palette);\n      ColorFP.Channels[ChannelId] := NewChannelValue;\n      FFormatInfo.SetPixelFP(PixPointer, @FFormatInfo, FPData.Palette, ColorFP);\n\n      Inc(PixPointer, Bpp);\n    end;\n  end;\nend;\n\nclass function TImagingCanvas.GetSupportedFormats: TImageFormats;\nbegin\n  Result := [ifIndex8..Pred(ifDXT1)];\nend;\n\n{ TFastARGB32Canvas }\n\ndestructor TFastARGB32Canvas.Destroy;\nbegin\n  FreeMem(FScanlines);\n  inherited Destroy;\nend;\n\nprocedure TFastARGB32Canvas.AlphaBlendPixels(SrcPix, DestPix: PColor32Rec);\nvar\n  SrcAlpha, DestAlpha, FinalAlpha: Integer;\nbegin\n  FinalAlpha := SrcPix.A + 1 + (DestPix.A * (256 - SrcPix.A)) shr 8;\n  if FinalAlpha = 0 then\n    SrcAlpha := 0\n  else\n    SrcAlpha := (SrcPix.A shl 8) div FinalAlpha;\n  DestAlpha := 256 - SrcAlpha;\n\n  DestPix.A := ClampToByte(FinalAlpha);\n  DestPix.R := (SrcPix.R * SrcAlpha + DestPix.R * DestAlpha) shr 8;\n  DestPix.G := (SrcPix.G * SrcAlpha + DestPix.G * DestAlpha) shr 8;\n  DestPix.B := (SrcPix.B * SrcAlpha + DestPix.B * DestAlpha) shr 8;\nend;\n\nprocedure TFastARGB32Canvas.DrawAlpha(const SrcRect: TRect;\n  DestCanvas: TImagingCanvas; DestX, DestY: Integer);\nvar\n  X, Y, SrcX, SrcY, Width, Height: Integer;\n  SrcPix, DestPix: PColor32Rec;\nbegin\n  if DestCanvas.ClassType <> Self.ClassType then\n  begin\n    inherited;\n    Exit;\n  end;\n\n  SrcX := SrcRect.Left;\n  SrcY := SrcRect.Top;\n  Width := SrcRect.Right - SrcRect.Left;\n  Height := SrcRect.Bottom - SrcRect.Top;\n  ClipCopyBounds(SrcX, SrcY, Width, Height, DestX, DestY,\n    FPData.Width, FPData.Height, DestCanvas.ClipRect);\n\n  for Y := 0 to Height - 1 do\n  begin\n    SrcPix := @FScanlines[SrcY + Y, SrcX];\n    DestPix := @TFastARGB32Canvas(DestCanvas).FScanlines[DestY + Y, DestX];\n    for X := 0 to Width - 1 do\n    begin\n      AlphaBlendPixels(SrcPix, DestPix);\n      Inc(SrcPix);\n      Inc(DestPix);\n    end;\n  end;\nend;\n\nfunction TFastARGB32Canvas.GetPixel32(X, Y: LongInt): TColor32;\nbegin\n  Result := FScanlines[Y, X].Color;\nend;\n\nprocedure TFastARGB32Canvas.SetPixel32(X, Y: LongInt; const Value: TColor32);\nbegin\n  if (X >= FClipRect.Left) and (Y >= FClipRect.Top) and\n    (X < FClipRect.Right) and (Y < FClipRect.Bottom) then\n  begin\n    FScanlines[Y, X].Color := Value;\n  end;\nend;\n\nprocedure TFastARGB32Canvas.StretchDrawAlpha(const SrcRect: TRect;\n  DestCanvas: TImagingCanvas; const DestRect: TRect; Filter: TResizeFilter);\nvar\n  X, Y, ScaleX, ScaleY, Yp, Xp, Weight1, Weight2, Weight3, Weight4, InvFracY, T1, T2: Integer;\n  FracX, FracY: Cardinal;\n  SrcX, SrcY, SrcWidth, SrcHeight: Integer;\n  DestX, DestY, DestWidth, DestHeight: Integer;\n  SrcLine, SrcLine2: PColor32RecArray;\n  DestPix: PColor32Rec;\n  Accum: TColor32Rec;\nbegin\n  if (Filter = rfBicubic) or (DestCanvas.ClassType <> Self.ClassType) then\n  begin\n    inherited;\n    Exit;\n  end;\n\n  SrcX := SrcRect.Left;\n  SrcY := SrcRect.Top;\n  SrcWidth := SrcRect.Right - SrcRect.Left;\n  SrcHeight := SrcRect.Bottom - SrcRect.Top;\n  DestX := DestRect.Left;\n  DestY := DestRect.Top;\n  DestWidth := DestRect.Right - DestRect.Left;\n  DestHeight := DestRect.Bottom - DestRect.Top;\n  // Clip src and dst rects\n  ClipStretchBounds(SrcX, SrcY, SrcWidth, SrcHeight, DestX, DestY, DestWidth, DestHeight,\n      FPData.Width, FPData.Height, DestCanvas.ClipRect);\n  ScaleX := (SrcWidth shl 16) div DestWidth;\n  ScaleY := (SrcHeight shl 16) div DestHeight;\n\n  // Nearest and linear filtering using fixed point math\n\n  if Filter = rfNearest then\n  begin\n    Yp := 0;\n    for Y := DestY to DestY + DestHeight - 1 do\n    begin\n      Xp := 0;\n      SrcLine := @FScanlines[SrcY + Yp shr 16, SrcX];\n      DestPix := @TFastARGB32Canvas(DestCanvas).FScanlines[Y, DestX];\n      for X := 0 to DestWidth - 1 do\n      begin\n        AlphaBlendPixels(@SrcLine[Xp shr 16], DestPix);\n        Inc(DestPix);\n        Inc(Xp, ScaleX);\n      end;\n      Inc(Yp, ScaleY);\n    end;\n  end\n  else\n  begin\n    Yp := (ScaleY shr 1) - $8000;\n    for Y := DestY to DestY + DestHeight - 1 do\n    begin\n      DestPix := @TFastARGB32Canvas(DestCanvas).FScanlines[Y, DestX];\n      if Yp < 0 then\n      begin\n        T1 := 0;\n        FracY := 0;\n        InvFracY := $10000;\n      end\n      else\n      begin\n        T1 := Yp shr 16;\n        FracY := Yp and $FFFF;\n        InvFracY := (not Yp and $FFFF) + 1;\n      end;\n\n      T2 := Iff(T1 < SrcHeight - 1, T1 + 1, T1);\n      SrcLine :=  @Scanlines[T1 + SrcY, SrcX];\n      SrcLine2 := @Scanlines[T2 + SrcY, SrcX];\n      Xp := (ScaleX shr 1) - $8000;\n\n      for X := 0 to DestWidth - 1 do\n      begin\n        if Xp < 0 then\n        begin\n          T1 := 0;\n          FracX := 0;\n        end\n        else\n        begin\n          T1 := Xp shr 16;\n          FracX := Xp and $FFFF;\n        end;\n\n        T2 := Iff(T1 < SrcWidth - 1, T1 + 1, T1);\n        Weight2:= Integer((Cardinal(InvFracY) * FracX) shr 16); // cast to Card, Int can overflow here\n        Weight1:= InvFracY - Weight2;\n        Weight4:= Integer((Cardinal(FracY) * FracX) shr 16);\n        Weight3:= FracY - Weight4;\n\n        Accum.B := (SrcLine[T1].B * Weight1 + SrcLine[T2].B * Weight2 +\n          SrcLine2[T1].B * Weight3 + SrcLine2[T2].B * Weight4 + $8000) shr 16;\n        Accum.G := (SrcLine[T1].G * Weight1 + SrcLine[T2].G * Weight2 +\n          SrcLine2[T1].G * Weight3 + SrcLine2[T2].G * Weight4 + $8000) shr 16;\n        Accum.R := (SrcLine[T1].R * Weight1 + SrcLine[T2].R * Weight2 +\n          SrcLine2[T1].R * Weight3 + SrcLine2[T2].R * Weight4 + $8000) shr 16;\n        Accum.A := (SrcLine[T1].A * Weight1 + SrcLine[T2].A * Weight2 +\n          SrcLine2[T1].A * Weight3 + SrcLine2[T2].A * Weight4 + $8000) shr 16;\n\n        AlphaBlendPixels(@Accum, DestPix);\n\n        Inc(Xp, ScaleX);\n        Inc(DestPix);\n      end;\n      Inc(Yp, ScaleY);\n     end;\n  end;\nend;\n\nprocedure TFastARGB32Canvas.UpdateCanvasState;\nvar\n  I: LongInt;\n  ScanPos: PLongWord;\nbegin\n  inherited UpdateCanvasState;\n\n  // Realloc and update scanline array\n  ReallocMem(FScanlines, FPData.Height * SizeOf(PColor32RecArray));\n  ScanPos := FPData.Bits;\n\n  for I := 0 to FPData.Height - 1 do\n  begin\n    FScanlines[I] := PColor32RecArray(ScanPos);\n    Inc(ScanPos, FPData.Width);\n  end;\nend;\n\nclass function TFastARGB32Canvas.GetSupportedFormats: TImageFormats;\nbegin\n  Result := [ifA8R8G8B8];\nend;\n\nprocedure TFastARGB32Canvas.InvertColors;\nvar\n  X, Y: Integer;\n  PixPtr: PColor32Rec;\nbegin\n  for Y := FClipRect.Top to FClipRect.Bottom - 1 do\n  begin\n    PixPtr := @FScanlines[Y, FClipRect.Left];\n    for X := FClipRect.Left to FClipRect.Right - 1 do\n    begin\n      PixPtr.R := not PixPtr.R;\n      PixPtr.G := not PixPtr.G;\n      PixPtr.B := not PixPtr.B;\n      Inc(PixPtr);\n    end;\n  end;\nend;\n\ninitialization\n  RegisterCanvas(TFastARGB32Canvas);\n\nfinalization\n  FreeAndNil(CanvasClasses);\n\n{\n  File Notes:\n\n  -- TODOS ----------------------------------------------------\n    - more more more ...\n    - implement pen width everywhere\n    - more objects (arc, polygon)\n\n  -- 0.26.5 Changes/Bug Fixes ---------------------------------\n    - Fixed bug that could raise floating point error in DrawAlpha\n      and StretchDrawAlpha.\n    - Fixed bug in TImagingCanvas.Line that caused not drawing\n      of horz or vert lines.\n\n  -- 0.26.3 Changes/Bug Fixes ---------------------------------\n    - Added some methods to TFastARGB32Canvas (InvertColors, DrawAlpha/StretchDrawAlpha)\n    - Fixed DrawAlpha/StretchDrawAlpha destination alpha calculation.\n    - Added PremultiplyAlpha and UnPremultiplyAlpha methods.\n\n  -- 0.26.1 Changes/Bug Fixes ---------------------------------\n    - Added FillChannel methods.\n    - Added FloodFill method.\n    - Added GetHistogram method.\n    - Fixed \"Invalid FP operation\" in AdjustColorLevels in FPC compiled exes\n      (thanks to Carlos Gonzlez).\n    - Added TImagingCanvas.AdjustColorLevels method.\n\n  -- 0.25.0 Changes/Bug Fixes ---------------------------------\n    - Fixed error that could cause AV in linear and nonlinear filters.\n    - Added blended rect filling function FillRectBlend.\n    - Added drawing function with blending (DrawAlpha, StretchDrawAlpha,\n        StretchDrawAdd, DrawBlend, StretchDrawBlend, ...)\n    - Added non-linear filters (min, max, median).\n    - Added point transforms (invert, contrast, gamma, brightness).\n\n  -- 0.21 Changes/Bug Fixes -----------------------------------\n    - Added some new filter kernels for convolution.\n    - Added FillMode and PenMode properties.\n    - Added FrameRect, Rectangle, Ellipse, and Line methods.\n    - Removed HorzLine and VertLine from TFastARGB32Canvas - new versions\n      in general canvas is now as fast as those in TFastARGB32Canvas\n      (only in case of A8R8G8B8 images of course). \n    - Added PenWidth property, updated HorzLine and VertLine to use it.\n\n  -- 0.19 Changes/Bug Fixes -----------------------------------\n    - added TFastARGB32Canvas\n    - added convolutions, hline, vline\n    - unit created, intial stuff added\n\n}\n\nend.\n\n"
  },
  {
    "path": "lib/Imaging/ImagingClasses.pas",
    "content": "{\n  Vampyre Imaging Library\n  by Marek Mauder \n  http://imaginglib.sourceforge.net\n\n  The contents of this file are used with permission, subject to the Mozilla\n  Public License Version 1.1 (the \"License\"); you may not use this file except\n  in compliance with the License. You may obtain a copy of the License at\n  http://www.mozilla.org/MPL/MPL-1.1.html\n\n  Software distributed under the License is distributed on an \"AS IS\" basis,\n  WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for\n  the specific language governing rights and limitations under the License.\n\n  Alternatively, the contents of this file may be used under the terms of the\n  GNU Lesser General Public License (the  \"LGPL License\"), in which case the\n  provisions of the LGPL License are applicable instead of those above.\n  If you wish to allow use of your version of this file only under the terms\n  of the LGPL License and not to allow others to use your version of this file\n  under the MPL, indicate your decision by deleting  the provisions above and\n  replace  them with the notice and other provisions required by the LGPL\n  License.  If you do not delete the provisions above, a recipient may use\n  your version of this file under either the MPL or the LGPL License.\n\n  For more information about the LGPL: http://www.gnu.org/copyleft/lesser.html\n}\n\n{ This unit contains class based wrapper to Imaging library.}\nunit ImagingClasses;\n\n{$I ImagingOptions.inc}\n\ninterface\n\nuses\n  Types, Classes, ImagingTypes, Imaging, ImagingFormats, ImagingUtility;\n\ntype\n  { Base abstract high level class wrapper to low level Imaging structures and\n    functions.}\n  TBaseImage = class(TPersistent)\n  private\n    function GetEmpty: Boolean;\n  protected\n    FPData: PImageData;\n    FOnDataSizeChanged: TNotifyEvent;\n    FOnPixelsChanged: TNotifyEvent;\n    function GetFormat: TImageFormat; {$IFDEF USE_INLINE}inline;{$ENDIF}\n    function GetHeight: Integer; {$IFDEF USE_INLINE}inline;{$ENDIF}\n    function GetSize: Integer; {$IFDEF USE_INLINE}inline;{$ENDIF}\n    function GetWidth: Integer; {$IFDEF USE_INLINE}inline;{$ENDIF}\n    function GetBits: Pointer; {$IFDEF USE_INLINE}inline;{$ENDIF}\n    function GetPalette: PPalette32; {$IFDEF USE_INLINE}inline;{$ENDIF}\n    function GetPaletteEntries: Integer; {$IFDEF USE_INLINE}inline;{$ENDIF}\n    function GetScanline(Index: Integer): Pointer;\n    function GetPixelPointer(X, Y: Integer): Pointer; {$IFDEF USE_INLINE}inline;{$ENDIF}\n    function GetScanlineSize: Integer; {$IFDEF USE_INLINE}inline;{$ENDIF}\n    function GetFormatInfo: TImageFormatInfo; {$IFDEF USE_INLINE}inline;{$ENDIF}\n    function GetValid: Boolean; {$IFDEF USE_INLINE}inline;{$ENDIF}\n    function GetBoundsRect: TRect;\n    procedure SetFormat(const Value: TImageFormat); {$IFDEF USE_INLINE}inline;{$ENDIF}\n    procedure SetHeight(const Value: Integer); {$IFDEF USE_INLINE}inline;{$ENDIF}\n    procedure SetWidth(const Value: Integer); {$IFDEF USE_INLINE}inline;{$ENDIF}\n    procedure SetPointer; virtual; abstract;\n    procedure DoDataSizeChanged; virtual;\n    procedure DoPixelsChanged; virtual;\n  public\n    constructor Create; virtual;\n    constructor CreateFromImage(AImage: TBaseImage);\n    destructor Destroy; override;\n    { Returns info about current image.}\n    function ToString: string; {$IF Defined(DCC) and (CompilerVersion >= 20.0)}override;{$IFEND}\n\n    { Creates a new image data with the given size and format. Old image\n      data is lost. Works only for the current image of TMultiImage.}\n    procedure RecreateImageData(AWidth, AHeight: Integer; AFormat: TImageFormat);\n    { Maps underlying image data to given TImageData record. Both TBaseImage and\n      TImageData now share some image memory (bits). So don't call FreeImage\n      on TImageData afterwards since this TBaseImage would get really broken.}\n    procedure MapImageData(const ImageData: TImageData);\n    { Deletes current image.}\n    procedure Clear;\n\n    { Resizes current image with optional resampling.}\n    procedure Resize(NewWidth, NewHeight: Integer; Filter: TResizeFilter);\n\n    procedure ResizeToFit(FitWidth, FitHeight: Integer; Filter: TResizeFilter; DstImage: TBaseImage);\n    { Flips current image. Reverses the image along its horizontal axis the top\n      becomes the bottom and vice versa.}\n    procedure Flip;\n    { Mirrors current image. Reverses the image along its vertical axis the left\n      side becomes the right and vice versa.}\n    procedure Mirror;\n    { Rotates image by Angle degrees counterclockwise.}\n    procedure Rotate(Angle: Single);\n    { Copies rectangular part of SrcImage to DstImage. No blending is performed -\n      alpha is simply copied to destination image. Operates also with\n      negative X and Y coordinates.\n      Note that copying is fastest for images in the same data format\n      (and slowest for images in special formats).}\n    procedure CopyTo(SrcX, SrcY, Width, Height: Integer; DstImage: TBaseImage; DstX, DstY: Integer);\n    { Stretches the contents of the source rectangle to the destination rectangle\n      with optional resampling. No blending is performed - alpha is\n      simply copied/resampled to destination image. Note that stretching is\n      fastest for images in the same data format (and slowest for\n      images in special formats).}\n    procedure StretchTo(SrcX, SrcY, SrcWidth, SrcHeight: Integer; DstImage: TBaseImage; DstX, DstY, DstWidth, DstHeight: Integer; Filter: TResizeFilter);\n    { Replaces pixels with OldPixel in the given rectangle by NewPixel.\n      OldPixel and NewPixel should point to the pixels in the same format\n      as the given image is in.}\n    procedure ReplaceColor(X, Y, Width, Height: Integer; OldColor, NewColor: Pointer);\n    { Swaps SrcChannel and DstChannel color or alpha channels of image.\n      Use ChannelRed, ChannelBlue, ChannelGreen, ChannelAlpha constants to\n      identify channels.}\n    procedure SwapChannels(SrcChannel, DstChannel: Integer);\n\n    { Loads current image data from file.}\n    procedure LoadFromFile(const FileName: string); virtual;\n    { Loads current image data from stream.}\n    procedure LoadFromStream(Stream: TStream); virtual;\n\n    { Saves current image data to file.}\n    procedure SaveToFile(const FileName: string);\n    { Saves current image data to stream. Ext identifies desired image file\n      format (jpg, png, dds, ...)}\n    procedure SaveToStream(const Ext: string; Stream: TStream);\n\n    { Width of current image in pixels.}\n    property Width: Integer read GetWidth write SetWidth;\n    { Height of current image in pixels.}\n    property Height: Integer read GetHeight write SetHeight;\n    { Image data format of current image.}\n    property Format: TImageFormat read GetFormat write SetFormat;\n    { Size in bytes of current image's data.}\n    property Size: Integer read GetSize;\n    { Pointer to memory containing image bits.}\n    property Bits: Pointer read GetBits;\n    { Pointer to palette for indexed format images. It is nil for others.\n      Max palette entry is at index [PaletteEntries - 1].}\n    property Palette: PPalette32 read GetPalette;\n    { Number of entries in image's palette}\n    property PaletteEntries: Integer read GetPaletteEntries;\n    { Provides indexed access to each line of pixels. Does not work with special\n      format images (like DXT).}\n    property Scanline[Index: Integer]: Pointer read GetScanline;\n    { Returns pointer to image pixel at [X, Y] coordinates.}\n    property PixelPointer[X, Y: Integer]: Pointer read GetPixelPointer;\n    { Size/length of one image scanline in bytes.}\n    property ScanlineSize: Integer read GetScanlineSize;\n    { Extended image format information.}\n    property FormatInfo: TImageFormatInfo read GetFormatInfo;\n    { This gives complete access to underlying TImageData record.\n      It can be used in functions that take TImageData as parameter\n      (for example: ReduceColors(SingleImageInstance.ImageData^, 64)).}\n    property ImageDataPointer: PImageData read FPData;\n    { Indicates whether the current image is valid (proper format,\n      allowed dimensions, right size, ...).}\n    property Valid: Boolean read GetValid;\n    { Indicates whether image containst any data (size in bytes > 0).}\n    property Empty: Boolean read GetEmpty;\n    { Specifies the bounding rectangle of the image.}\n    property BoundsRect: TRect read GetBoundsRect;\n    { This event occurs when the image data size has just changed. That means\n      image width, height, or format has been changed.}\n    property OnDataSizeChanged: TNotifyEvent read FOnDataSizeChanged write FOnDataSizeChanged;\n    { This event occurs when some pixels of the image have just changed.}\n    property OnPixelsChanged: TNotifyEvent read FOnPixelsChanged write FOnPixelsChanged;\n  end;\n\n  { Extension of TBaseImage which uses single TImageData record to\n    store image. All methods inherited from TBaseImage work with this record.}\n  TSingleImage = class(TBaseImage)\n  protected\n    FImageData: TImageData;\n    procedure SetPointer; override;\n  public\n    constructor Create; override;\n    constructor CreateFromParams(AWidth, AHeight: Integer; AFormat: TImageFormat = ifDefault);\n    constructor CreateFromData(const AData: TImageData);\n    constructor CreateFromFile(const FileName: string);\n    constructor CreateFromStream(Stream: TStream);\n    destructor Destroy; override;\n    { Assigns single image from another single image or multi image.}\n    procedure Assign(Source: TPersistent); override;\n    { Assigns single image from image data record.}\n    procedure AssignFromImageData(const AImageData: TImageData);\n  end;\n\n  { Extension of TBaseImage which uses array of TImageData records to\n    store multiple images. Images are independent on each other and they don't\n    share any common characteristic. Each can have different size, format, and\n    palette. All methods inherited from TBaseImage work only with\n    active image (it could represent mipmap level, animation frame, or whatever).\n    Methods whose names contain word 'Multi' work with all images in array\n    (as well as other methods with obvious names).}\n  TMultiImage = class(TBaseImage)\n  protected\n    FDataArray: TDynImageDataArray;\n    FActiveImage: Integer;\n    procedure SetActiveImage(Value: Integer); {$IFDEF USE_INLINE}inline;{$ENDIF}\n    function GetImageCount: Integer; {$IFDEF USE_INLINE}inline;{$ENDIF}\n    procedure SetImageCount(Value: Integer);\n    function GetAllImagesValid: Boolean; {$IFDEF USE_INLINE}inline;{$ENDIF}\n    function GetImage(Index: Integer): TImageData; {$IFDEF USE_INLINE}inline;{$ENDIF}\n    procedure SetImage(Index: Integer; Value: TImageData); {$IFDEF USE_INLINE}inline;{$ENDIF}\n    procedure SetPointer; override;\n    function PrepareInsert(Index, Count: Integer): Boolean;\n    procedure DoInsertImages(Index: Integer; const Images: TDynImageDataArray);\n    procedure DoInsertNew(Index: Integer; AWidth, AHeight: Integer; AFormat: TImageFormat);\n  public\n    constructor Create; override;\n    constructor CreateFromParams(AWidth, AHeight: Integer; AFormat: TImageFormat; ImageCount: Integer);\n    constructor CreateFromArray(const ADataArray: TDynImageDataArray);\n    constructor CreateFromFile(const FileName: string);\n    constructor CreateFromStream(Stream: TStream);\n    destructor Destroy; override;\n    { Assigns multi image from another multi image or single image.}\n    procedure Assign(Source: TPersistent); override;\n    { Assigns multi image from array of image data records.}\n    procedure AssignFromArray(const ADataArray: TDynImageDataArray);\n\n    { Adds new image at the end of the image array. }\n    function AddImage(AWidth, AHeight: Integer; AFormat: TImageFormat = ifDefault): Integer; overload;\n    { Adds existing image at the end of the image array. }\n    function AddImage(const Image: TImageData): Integer; overload;\n    { Adds existing image (Active image of a TmultiImage)\n      at the end of the image array. }\n    function AddImage(Image: TBaseImage): Integer; overload;\n    { Adds existing image array ((all images of a multi image))\n      at the end of the image array. }\n    procedure AddImages(const Images: TDynImageDataArray); overload;\n    { Adds existing MultiImage images at the end of the image array. }\n    procedure AddImages(Images: TMultiImage); overload;\n\n    { Inserts new image image at the given position in the image array. }\n    procedure InsertImage(Index, AWidth, AHeight: Integer; AFormat: TImageFormat = ifDefault); overload;\n    { Inserts existing image at the given position in the image array. }\n    procedure InsertImage(Index: Integer; const Image: TImageData); overload;\n    { Inserts existing image (Active image of a TmultiImage)\n      at the given position in the image array. }\n    procedure InsertImage(Index: Integer; Image: TBaseImage); overload;\n    { Inserts existing image at the given position in the image array. }\n    procedure InsertImages(Index: Integer; const Images: TDynImageDataArray); overload;\n    { Inserts existing images (all images of a TmultiImage) at\n      the given position in the image array. }\n    procedure InsertImages(Index: Integer; Images: TMultiImage); overload;\n\n    { Exchanges two images at the given positions in the image array. }\n    procedure ExchangeImages(Index1, Index2: Integer);\n    { Deletes image at the given position in the image array.}\n    procedure DeleteImage(Index: Integer);\n    { Rearranges images so that the first image will become last and vice versa.}\n    procedure ReverseImages;\n    { Deletes all images.}\n    procedure ClearAll;\n\n    { Converts all images to another image data format.}\n    procedure ConvertImages(Format: TImageFormat);\n    { Resizes all images.}\n    procedure ResizeImages(NewWidth, NewHeight: Integer; Filter: TResizeFilter);\n\n    { Overloaded loading method that will add new image to multiimage if\n      image array is empty bero loading. }\n    procedure LoadFromFile(const FileName: string); override;\n    { Overloaded loading method that will add new image to multiimage if\n      image array is empty bero loading. }\n    procedure LoadFromStream(Stream: TStream); override;\n\n    { Loads whole multi image from file.}\n    procedure LoadMultiFromFile(const FileName: string);\n    { Loads whole multi image from stream.}\n    procedure LoadMultiFromStream(Stream: TStream);\n    { Saves whole multi image to file.}\n    procedure SaveMultiToFile(const FileName: string);\n    { Saves whole multi image to stream. Ext identifies desired\n      image file format (jpg, png, dds, ...).}\n    procedure SaveMultiToStream(const Ext: string; Stream: TStream);\n\n    { Indicates active image of this multi image. All methods inherited\n      from TBaseImage operate on this image only.}\n    property ActiveImage: Integer read FActiveImage write SetActiveImage;\n    { Number of images of this multi image.}\n    property ImageCount: Integer read GetImageCount write SetImageCount;\n    { This value is True if all images of this TMultiImage are valid.}\n    property AllImagesValid: Boolean read GetAllImagesValid;\n    { This gives complete access to underlying TDynImageDataArray.\n      It can be used in functions that take TDynImageDataArray\n      as parameter.}\n    property DataArray: TDynImageDataArray read FDataArray;\n    { Array property for accessing individual images of TMultiImage. When you\n      set image at given index the old image is freed and the source is cloned.}\n    property Images[Index: Integer]: TImageData read GetImage write SetImage; default;\n  end;\n\nimplementation\n\nconst\n  DefaultWidth = 16;\n  Defaultheight = 16;\n\nfunction GetArrayFromImageData(const ImageData: TImageData): TDynImageDataArray;\nbegin\n  SetLength(Result, 1);\n  Result[0] := ImageData;\nend;\n\n{ TBaseImage class implementation }\n\nconstructor TBaseImage.Create;\nbegin\n  SetPointer;\nend;\n\nconstructor TBaseImage.CreateFromImage(AImage: TBaseImage);\nbegin\n  Create;\n  Assign(AImage);\nend;\n\ndestructor TBaseImage.Destroy;\nbegin\n  inherited Destroy;\nend;\n\nfunction TBaseImage.GetWidth: Integer;\nbegin\n  if Valid then\n    Result := FPData.Width\n  else\n    Result := 0;\nend;\n\nfunction TBaseImage.GetHeight: Integer;\nbegin\n  if Valid then\n    Result := FPData.Height\n  else\n    Result := 0;\nend;\n\nfunction TBaseImage.GetFormat: TImageFormat;\nbegin\n  if Valid then\n    Result := FPData.Format\n  else\n    Result := ifUnknown;\nend;\n\nfunction TBaseImage.GetScanline(Index: Integer): Pointer;\nvar\n  Info: TImageFormatInfo;\nbegin\n  if Valid then\n  begin\n    Info := GetFormatInfo;\n    if not Info.IsSpecial then\n      Result := ImagingFormats.GetScanLine(FPData.Bits, Info, FPData.Width, Index)\n    else\n      Result := FPData.Bits;\n  end\n  else\n    Result := nil;\nend;\n\nfunction TBaseImage.GetScanlineSize: Integer;\nbegin\n  if Valid then\n    Result := FormatInfo.GetPixelsSize(Format, Width, 1)\n  else\n    Result := 0;\nend;\n\nfunction TBaseImage.GetPixelPointer(X, Y: Integer): Pointer;\nbegin\n  if Valid then\n    Result := @PByteArray(FPData.Bits)[(Y * FPData.Width + X) * GetFormatInfo.BytesPerPixel]\n  else\n    Result := nil;\nend;\n\nfunction TBaseImage.GetSize: Integer;\nbegin\n  if Valid then\n    Result := FPData.Size\n  else\n    Result := 0;\nend;\n\nfunction TBaseImage.GetBits: Pointer;\nbegin\n  if Valid then\n    Result := FPData.Bits\n  else\n    Result := nil;\nend;\n\nfunction TBaseImage.GetPalette: PPalette32;\nbegin\n  if Valid then\n    Result := FPData.Palette\n  else\n    Result := nil;\nend;\n\nfunction TBaseImage.GetPaletteEntries: Integer;\nbegin\n  Result := GetFormatInfo.PaletteEntries;\nend;\n\nfunction TBaseImage.GetFormatInfo: TImageFormatInfo;\nbegin\n  if Valid then\n    Imaging.GetImageFormatInfo(FPData.Format, Result)\n  else\n    FillChar(Result, SizeOf(Result), 0);\nend;\n\nfunction TBaseImage.GetValid: Boolean;\nbegin\n  Result := Assigned(FPData) and Imaging.TestImage(FPData^);\nend;\n\nfunction TBaseImage.GetBoundsRect: TRect;\nbegin\n  Result := Rect(0, 0, GetWidth, GetHeight);\nend;\n\nfunction TBaseImage.GetEmpty: Boolean;\nbegin\n  Result := FPData.Size = 0;\nend;\n\nprocedure TBaseImage.SetWidth(const Value: Integer);\nbegin\n  Resize(Value, GetHeight, rfNearest);\nend;\n\nprocedure TBaseImage.SetHeight(const Value: Integer);\nbegin\n  Resize(GetWidth, Value, rfNearest);\nend;\n\nprocedure TBaseImage.SetFormat(const Value: TImageFormat);\nbegin\n  if Valid and Imaging.ConvertImage(FPData^, Value) then\n    DoDataSizeChanged;\nend;\n\nprocedure TBaseImage.DoDataSizeChanged;\nbegin\n  if Assigned(FOnDataSizeChanged) then\n    FOnDataSizeChanged(Self);\n  DoPixelsChanged;\nend;\n\nprocedure TBaseImage.DoPixelsChanged;\nbegin\n  if Assigned(FOnPixelsChanged) then\n    FOnPixelsChanged(Self);\nend;\n\nprocedure TBaseImage.RecreateImageData(AWidth, AHeight: Integer; AFormat: TImageFormat);\nbegin\n  if Assigned(FPData) and Imaging.NewImage(AWidth, AHeight, AFormat, FPData^) then\n    DoDataSizeChanged;\nend;\n\nprocedure TBaseImage.MapImageData(const ImageData: TImageData);\nbegin\n  Clear;\n  FPData.Width := ImageData.Width;\n  FPData.Height := ImageData.Height;\n  FPData.Format := ImageData.Format;\n  FPData.Size := ImageData.Size;\n  FPData.Bits := ImageData.Bits;\n  FPData.Palette := ImageData.Palette;\nend;\n\nprocedure TBaseImage.Clear;\nbegin\n  FreeImage(FPData^);\nend;\n\nprocedure TBaseImage.Resize(NewWidth, NewHeight: Integer; Filter: TResizeFilter);\nbegin\n  if Valid and Imaging.ResizeImage(FPData^, NewWidth, NewHeight, Filter) then\n    DoDataSizeChanged;\nend;\n\nprocedure TBaseImage.ResizeToFit(FitWidth, FitHeight: Integer;\n  Filter: TResizeFilter; DstImage: TBaseImage);\nbegin\n  if Valid and Assigned(DstImage) then\n  begin\n    Imaging.ResizeImageToFit(FPData^, FitWidth, FitHeight, Filter,\n      DstImage.FPData^);\n    DstImage.DoDataSizeChanged;\n  end;\nend;\n\nprocedure TBaseImage.Flip;\nbegin\n  if Valid and Imaging.FlipImage(FPData^) then\n    DoPixelsChanged;\nend;\n\nprocedure TBaseImage.Mirror;\nbegin\n  if Valid and Imaging.MirrorImage(FPData^) then\n    DoPixelsChanged;\nend;\n\nprocedure TBaseImage.Rotate(Angle: Single);\nbegin\n  if Valid then\n  begin\n    Imaging.RotateImage(FPData^, Angle);\n    DoPixelsChanged;\n  end;\nend;\n\nprocedure TBaseImage.CopyTo(SrcX, SrcY, Width, Height: Integer;\n  DstImage: TBaseImage; DstX, DstY: Integer);\nbegin\n  if Valid and Assigned(DstImage) and DstImage.Valid then\n  begin\n    Imaging.CopyRect(FPData^, SrcX, SrcY, Width, Height, DstImage.FPData^, DstX, DstY);\n    DstImage.DoPixelsChanged;\n  end;\nend;\n\nprocedure TBaseImage.StretchTo(SrcX, SrcY, SrcWidth, SrcHeight: Integer;\n  DstImage: TBaseImage; DstX, DstY, DstWidth, DstHeight: Integer; Filter: TResizeFilter);\nbegin\n  if Valid and Assigned(DstImage) and DstImage.Valid then\n  begin\n    Imaging.StretchRect(FPData^, SrcX, SrcY, SrcWidth, SrcHeight,\n      DstImage.FPData^, DstX, DstY, DstWidth, DstHeight, Filter);\n    DstImage.DoPixelsChanged;\n  end;\nend;\n\nprocedure TBaseImage.ReplaceColor(X, Y, Width, Height: Integer; OldColor,\n  NewColor: Pointer);\nbegin\n  if Valid then\n  begin\n    Imaging.ReplaceColor(FPData^, X, Y, Width, Height, OldColor, NewColor);\n    DoPixelsChanged;\n  end;\nend;\n\nprocedure TBaseImage.SwapChannels(SrcChannel, DstChannel: Integer);\nbegin\n  if Valid then\n  begin\n    Imaging.SwapChannels(FPData^, SrcChannel, DstChannel);\n    DoPixelsChanged;\n  end;\nend;\n\nfunction TBaseImage.ToString: string;\nbegin\n  Result := Iff(Valid, Imaging.ImageToStr(FPData^), 'empty image');\nend;\n\nprocedure TBaseImage.LoadFromFile(const FileName: string);\nbegin\n  if Assigned(FPData) and Imaging.LoadImageFromFile(FileName, FPData^) then\n    DoDataSizeChanged;\nend;\n\nprocedure TBaseImage.LoadFromStream(Stream: TStream);\nbegin\n  if Assigned(FPData) and Imaging.LoadImageFromStream(Stream, FPData^) then\n    DoDataSizeChanged;\nend;\n\nprocedure TBaseImage.SaveToFile(const FileName: string);\nbegin\n  if Valid then\n    Imaging.SaveImageToFile(FileName, FPData^);\nend;\n\nprocedure TBaseImage.SaveToStream(const Ext: string; Stream: TStream);\nbegin\n  if Valid then\n    Imaging.SaveImageToStream(Ext, Stream, FPData^);\nend;\n\n\n{ TSingleImage class implementation }\n\nconstructor TSingleImage.Create;\nbegin\n  inherited Create;\n  Clear;\nend;\n\nconstructor TSingleImage.CreateFromParams(AWidth, AHeight: Integer; AFormat: TImageFormat);\nbegin\n  inherited Create;\n  RecreateImageData(AWidth, AHeight, AFormat);\nend;\n\nconstructor TSingleImage.CreateFromData(const AData: TImageData);\nbegin\n  inherited Create;\n  AssignFromImageData(AData);\nend;\n\nconstructor TSingleImage.CreateFromFile(const FileName: string);\nbegin\n  inherited Create;\n  LoadFromFile(FileName);\nend;\n\nconstructor TSingleImage.CreateFromStream(Stream: TStream);\nbegin\n  inherited Create;\n  LoadFromStream(Stream);\nend;\n\ndestructor TSingleImage.Destroy;\nbegin\n  Imaging.FreeImage(FImageData);\n  inherited Destroy;\nend;\n\nprocedure TSingleImage.SetPointer;\nbegin\n  FPData := @FImageData;\nend;\n\nprocedure TSingleImage.Assign(Source: TPersistent);\nbegin\n  if Source = nil then\n  begin\n    Clear;\n  end\n  else if Source is TSingleImage then\n  begin\n    AssignFromImageData(TSingleImage(Source).FImageData);\n  end\n  else if Source is TMultiImage then\n  begin\n    if TMultiImage(Source).Valid then\n      AssignFromImageData(TMultiImage(Source).FPData^)\n    else\n      Clear;\n  end\n  else\n    inherited Assign(Source);\nend;\n\nprocedure TSingleImage.AssignFromImageData(const AImageData: TImageData);\nbegin\n  if Imaging.TestImage(AImageData) then\n  begin\n    Imaging.CloneImage(AImageData, FImageData);\n    DoDataSizeChanged;\n  end\n  else\n    Clear;\nend;\n\n{ TMultiImage class implementation }\n\nconstructor TMultiImage.Create;\nbegin\n  inherited Create;\nend;\n\nconstructor TMultiImage.CreateFromParams(AWidth, AHeight: Integer;\n  AFormat: TImageFormat; ImageCount: Integer);\nvar\n  I: Integer;\nbegin\n  Imaging.FreeImagesInArray(FDataArray);\n  SetLength(FDataArray, ImageCount);\n  for I := 0 to GetImageCount - 1 do\n    Imaging.NewImage(AWidth, AHeight, AFormat, FDataArray[I]);\n  if GetImageCount > 0 then\n    SetActiveImage(0);\nend;\n\nconstructor TMultiImage.CreateFromArray(const ADataArray: TDynImageDataArray);\nbegin\n  AssignFromArray(ADataArray);\nend;\n\nconstructor TMultiImage.CreateFromFile(const FileName: string);\nbegin\n  LoadMultiFromFile(FileName);\nend;\n\nconstructor TMultiImage.CreateFromStream(Stream: TStream);\nbegin\n  LoadMultiFromStream(Stream);\nend;\n\ndestructor TMultiImage.Destroy;\nbegin\n  Imaging.FreeImagesInArray(FDataArray);\n  inherited Destroy;\nend;\n\nprocedure TMultiImage.SetActiveImage(Value: Integer);\nbegin\n  FActiveImage := Value;\n  SetPointer;\nend;\n\nfunction TMultiImage.GetImageCount: Integer;\nbegin\n  Result := Length(FDataArray);\nend;\n\nprocedure TMultiImage.SetImageCount(Value: Integer);\nvar\n  I, OldCount: Integer;\nbegin\n  if Value > GetImageCount then\n  begin\n    // Create new empty images if array will be enlarged\n    OldCount := GetImageCount;\n    SetLength(FDataArray, Value);\n    for I := OldCount to Value - 1 do\n      Imaging.NewImage(DefaultWidth, DefaultHeight, ifDefault, FDataArray[I]);\n  end\n  else\n  begin\n    // Free images that exceed desired count and shrink array\n    for I := Value to GetImageCount - 1 do\n      Imaging.FreeImage(FDataArray[I]);\n    SetLength(FDataArray, Value);\n  end;\n  SetPointer;\nend;\n\nfunction TMultiImage.GetAllImagesValid: Boolean;\nbegin\n  Result := (GetImageCount > 0) and TestImagesInArray(FDataArray);\nend;\n\nfunction TMultiImage.GetImage(Index: Integer): TImageData;\nbegin\n  if (Index >= 0) and (Index < GetImageCount) then\n    Result := FDataArray[Index];\nend;\n\nprocedure TMultiImage.SetImage(Index: Integer; Value: TImageData);\nbegin\n  if (Index >= 0) and (Index < GetImageCount) then\n    Imaging.CloneImage(Value, FDataArray[Index]);\nend;\n\nprocedure TMultiImage.SetPointer;\nbegin\n  if GetImageCount > 0 then\n  begin\n    FActiveImage := ClampInt(FActiveImage, 0, GetImageCount - 1);\n    FPData := @FDataArray[FActiveImage];\n  end\n  else\n  begin\n    FActiveImage := -1;\n    FPData := nil\n  end;\nend;\n\nfunction TMultiImage.PrepareInsert(Index, Count: Integer): Boolean;\nvar\n  I: Integer;\nbegin\n  // Inserting to empty image will add image at index 0\n  if GetImageCount = 0 then\n    Index := 0;\n\n  if (Index >= 0) and (Index <= GetImageCount) and (Count > 0) then\n  begin\n    SetLength(FDataArray, GetImageCount + Count);\n    if Index < GetImageCount - 1 then\n    begin\n      // Move imges to new position\n      System.Move(FDataArray[Index], FDataArray[Index + Count],\n        (GetImageCount - Count - Index) * SizeOf(TImageData));\n      // Null old images, not free them!\n      for I := Index to Index + Count - 1 do\n        InitImage(FDataArray[I]);\n    end;\n    Result := True;\n  end\n  else\n    Result := False;\nend;\n\nprocedure TMultiImage.DoInsertImages(Index: Integer; const Images: TDynImageDataArray);\nvar\n  I, Len: Integer;\nbegin\n  Len := Length(Images);\n  if PrepareInsert(Index, Len) then\n  begin\n    for I := 0 to Len - 1 do\n      Imaging.CloneImage(Images[I], FDataArray[Index + I]);\n  end;\nend;\n\nprocedure TMultiImage.DoInsertNew(Index, AWidth, AHeight: Integer;\n  AFormat: TImageFormat);\nbegin\n  if PrepareInsert(Index, 1) then\n    Imaging.NewImage(AWidth, AHeight, AFormat, FDataArray[Index]);\nend;\n\nprocedure TMultiImage.Assign(Source: TPersistent);\nvar\n  Arr: TDynImageDataArray;\nbegin\n  if Source = nil then\n  begin\n    ClearAll;\n  end\n  else if Source is TMultiImage then\n  begin\n    AssignFromArray(TMultiImage(Source).FDataArray);\n    SetActiveImage(TMultiImage(Source).ActiveImage);\n  end\n  else if Source is TSingleImage then\n  begin\n    SetLength(Arr, 1);\n    Arr[0] := TSingleImage(Source).FImageData;\n    AssignFromArray(Arr);\n  end\n  else\n    inherited Assign(Source);\nend;\n\nprocedure TMultiImage.AssignFromArray(const ADataArray: TDynImageDataArray);\nvar\n  I: Integer;\nbegin\n  Imaging.FreeImagesInArray(FDataArray);\n  SetLength(FDataArray, Length(ADataArray));\n  for I := 0 to GetImageCount - 1 do\n  begin\n    // Clone only valid images\n    if Imaging.TestImage(ADataArray[I]) then\n      Imaging.CloneImage(ADataArray[I], FDataArray[I])\n    else\n      Imaging.NewImage(DefaultWidth, DefaultHeight, ifDefault, FDataArray[I]);\n  end;\n  if GetImageCount > 0 then\n    SetActiveImage(0);\nend;\n\nfunction TMultiImage.AddImage(AWidth, AHeight: Integer; AFormat: TImageFormat): Integer;\nbegin\n  Result := GetImageCount;\n  DoInsertNew(Result, AWidth, AHeight, AFormat);\nend;\n\nfunction TMultiImage.AddImage(const Image: TImageData): Integer;\nbegin\n  Result := GetImageCount;\n  DoInsertImages(Result, GetArrayFromImageData(Image));\nend;\n\nfunction TMultiImage.AddImage(Image: TBaseImage): Integer;\nbegin\n  if Assigned(Image) and Image.Valid then\n  begin\n    Result := GetImageCount;\n    DoInsertImages(Result, GetArrayFromImageData(Image.FPData^));\n  end\n  else\n    Result := -1;\nend;\n\nprocedure TMultiImage.AddImages(const Images: TDynImageDataArray);\nbegin\n  DoInsertImages(GetImageCount, Images);\nend;\n\nprocedure TMultiImage.AddImages(Images: TMultiImage);\nbegin\n  DoInsertImages(GetImageCount, Images.FDataArray);\nend;\n\nprocedure TMultiImage.InsertImage(Index, AWidth, AHeight: Integer;\n  AFormat: TImageFormat);\nbegin\n  DoInsertNew(Index, AWidth, AHeight, AFormat);\nend;\n\nprocedure TMultiImage.InsertImage(Index: Integer; const Image: TImageData);\nbegin\n  DoInsertImages(Index, GetArrayFromImageData(Image));\nend;\n\nprocedure TMultiImage.InsertImage(Index: Integer; Image: TBaseImage);\nbegin\n  if Assigned(Image) and Image.Valid then\n    DoInsertImages(Index, GetArrayFromImageData(Image.FPData^));\nend;\n\nprocedure TMultiImage.InsertImages(Index: Integer;\n  const Images: TDynImageDataArray);\nbegin\n  DoInsertImages(Index, FDataArray);\nend;\n\nprocedure TMultiImage.InsertImages(Index: Integer; Images: TMultiImage);\nbegin\n  DoInsertImages(Index, Images.FDataArray);\nend;\n\nprocedure TMultiImage.ExchangeImages(Index1, Index2: Integer);\nvar\n  TempData: TImageData;\nbegin\n  if (Index1 >= 0) and (Index1 < GetImageCount) and\n     (Index2 >= 0) and (Index2 < GetImageCount) then\n  begin\n    TempData := FDataArray[Index1];\n    FDataArray[Index1] := FDataArray[Index2];\n    FDataArray[Index2] := TempData;\n  end;\nend;\n\nprocedure TMultiImage.DeleteImage(Index: Integer);\nvar\n  I: Integer;\nbegin\n  if (Index >= 0) and (Index < GetImageCount) then\n  begin\n    // Free image at index to be deleted\n    Imaging.FreeImage(FDataArray[Index]);\n    if Index < GetImageCount - 1 then\n    begin\n      // Move images to new indices if necessary\n      for I := Index to GetImageCount - 2 do\n        FDataArray[I] := FDataArray[I + 1];\n    end;\n    // Set new array length and update pointer to active image\n    SetLength(FDataArray, GetImageCount - 1);\n    SetPointer;\n  end;\nend;\n\nprocedure TMultiImage.ClearAll;\nbegin\n  ImageCount := 0;\nend;\n\nprocedure TMultiImage.ConvertImages(Format: TImageFormat);\nvar\n  I: Integer;\nbegin\n  for I := 0 to GetImageCount - 1 do\n    Imaging.ConvertImage(FDataArray[I], Format);\nend;\n\nprocedure TMultiImage.ResizeImages(NewWidth, NewHeight: Integer;\n  Filter: TResizeFilter);\nvar\n  I: Integer;\nbegin\n  for I := 0 to GetImageCount - 1 do\n    Imaging.ResizeImage(FDataArray[I], NewWidth, NewHeight, Filter);\nend;\n\nprocedure TMultiImage.ReverseImages;\nvar\n  I: Integer;\nbegin\n  for I := 0 to GetImageCount div 2 do\n    ExchangeImages(I, GetImageCount - 1 - I);\nend;\n\nprocedure TMultiImage.LoadFromFile(const FileName: string);\nbegin\n  if GetImageCount = 0 then\n    ImageCount := 1;\n  inherited LoadFromFile(FileName);\nend;\n\nprocedure TMultiImage.LoadFromStream(Stream: TStream);\nbegin\n  if GetImageCount = 0 then\n    ImageCount := 1;\n  inherited LoadFromStream(Stream);\nend;\n\nprocedure TMultiImage.LoadMultiFromFile(const FileName: string);\nbegin\n  Imaging.LoadMultiImageFromFile(FileName, FDataArray);\n  SetActiveImage(0);\nend;\n\nprocedure TMultiImage.LoadMultiFromStream(Stream: TStream);\nbegin\n  Imaging.LoadMultiImageFromStream(Stream, FDataArray);\n  SetActiveImage(0);\nend;\n\nprocedure TMultiImage.SaveMultiToFile(const FileName: string);\nbegin\n  Imaging.SaveMultiImageToFile(FileName, FDataArray);\nend;\n\nprocedure TMultiImage.SaveMultiToStream(const Ext: string; Stream: TStream);\nbegin\n  Imaging.SaveMultiImageToStream(Ext, Stream, FDataArray);\nend;\n\n{\n  File Notes:\n\n  -- TODOS ----------------------------------------------------\n    - nothing now\n\n  -- 0.77.1 ---------------------------------------------------\n    - Added TSingleImage.AssignFromData and TMultiImage.AssigntFromArray\n      as a replacement for constructors used as methods (that is\n      compiler error in Delphi XE3).\n    - Added TBaseImage.ResizeToFit method.\n    - Changed TMultiImage to have default state with no images.\n    - TMultiImage.AddImage now returns index of newly added image.\n    - Fixed img index bug in TMultiImage.ResizeImages\n\n  -- 0.26.5 Changes/Bug Fixes ---------------------------------\n    - Added MapImageData method to TBaseImage\n    - Added Empty property to TBaseImage.\n    - Added Clear method to TBaseImage.\n    - Added ScanlineSize property to TBaseImage.\n\n  -- 0.24.3 Changes/Bug Fixes ---------------------------------\n    - Added TMultiImage.ReverseImages method.\n\n  -- 0.23 Changes/Bug Fixes -----------------------------------\n    - Added SwapChannels method to TBaseImage.\n    - Added ReplaceColor method to TBaseImage.\n    - Added ToString method to TBaseImage.\n\n  -- 0.21 Changes/Bug Fixes -----------------------------------\n    - Inserting images to empty MultiImage will act as Add method.\n    - MultiImages with empty arrays will now create one image when\n      LoadFromFile or LoadFromStream is called.\n    - Fixed bug that caused AVs when getting props like Width, Height, asn Size\n      and when inlining was off. There was call to Iff but with inlining disabled\n      params like FPData.Size were evaluated and when FPData was nil => AV.\n    - Added many FPData validity checks to many methods. There were AVs\n      when calling most methods on empty TMultiImage.\n    - Added AllImagesValid property to TMultiImage.\n    - Fixed memory leak in TMultiImage.CreateFromParams.\n\n  -- 0.19 Changes/Bug Fixes -----------------------------------\n    - added ResizeImages method to TMultiImage\n    - removed Ext parameter from various LoadFromStream methods, no\n      longer needed\n    - fixed various issues concerning ActiveImage of TMultiImage\n      (it pointed to invalid location after some operations)   \n    - most of property set/get methods are now inline\n    - added PixelPointers property to TBaseImage\n    - added Images default array property to TMultiImage\n    - renamed methods in TMultiImage to contain 'Image' instead of 'Level'\n    - added canvas support\n    - added OnDataSizeChanged and OnPixelsChanged event to TBaseImage\n    - renamed TSingleImage.NewImage to RecreateImageData, made public, and\n      moved to TBaseImage\n\n  -- 0.17 Changes/Bug Fixes -----------------------------------\n    - added props PaletteEntries and ScanLine to TBaseImage\n    - aded new constructor to TBaseImage that take TBaseImage source\n    - TMultiImage levels adding and inserting rewritten internally\n    - added some new functions to TMultiImage: AddLevels, InsertLevels\n    - added some new functions to TBaseImage: Flip, Mirror, Rotate,\n      CopyRect, StretchRect\n    - TBasicImage.Resize has now filter parameter\n    - new stuff added to TMultiImage (DataArray prop, ConvertLevels)\n\n  -- 0.13 Changes/Bug Fixes -----------------------------------\n    - added AddLevel, InsertLevel, ExchangeLevels and DeleteLevel\n      methods to TMultiImage\n    - added TBaseImage, TSingleImage and TMultiImage with initial\n      members\n}\n\nend.\n\n"
  },
  {
    "path": "lib/Imaging/ImagingColors.pas",
    "content": "{\n  Vampyre Imaging Library\n  by Marek Mauder \n  http://imaginglib.sourceforge.net\n\n  The contents of this file are used with permission, subject to the Mozilla\n  Public License Version 1.1 (the \"License\"); you may not use this file except\n  in compliance with the License. You may obtain a copy of the License at\n  http://www.mozilla.org/MPL/MPL-1.1.html\n\n  Software distributed under the License is distributed on an \"AS IS\" basis,\n  WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for\n  the specific language governing rights and limitations under the License.\n\n  Alternatively, the contents of this file may be used under the terms of the\n  GNU Lesser General Public License (the  \"LGPL License\"), in which case the\n  provisions of the LGPL License are applicable instead of those above.\n  If you wish to allow use of your version of this file only under the terms\n  of the LGPL License and not to allow others to use your version of this file\n  under the MPL, indicate your decision by deleting  the provisions above and\n  replace  them with the notice and other provisions required by the LGPL\n  License.  If you do not delete the provisions above, a recipient may use\n  your version of this file under either the MPL or the LGPL License.\n\n  For more information about the LGPL: http://www.gnu.org/copyleft/lesser.html\n}\n\n{ This unit contains functions for manipulating and converting color values.}\nunit ImagingColors;\n\ninterface\n\n{$I ImagingOptions.inc}\n\nuses\n  SysUtils, ImagingTypes, ImagingUtility;\n\n{ Converts RGB color to YUV.}\nprocedure RGBToYUV(R, G, B: Byte; var Y, U, V: Byte);\n{ Converts YIV to RGB color.}\nprocedure YUVToRGB(Y, U, V: Byte; var R, G, B: Byte);\n\n{ Converts RGB color to YCbCr as used in JPEG.}\nprocedure RGBToYCbCr(R, G, B: Byte; var Y, Cb, Cr: Byte);\n{ Converts YCbCr as used in JPEG to RGB color.}\nprocedure YCbCrToRGB(Y, Cb, Cr: Byte; var R, G, B: Byte);\n{ Converts RGB color to YCbCr as used in JPEG.}\nprocedure RGBToYCbCr16(R, G, B: Word; var Y, Cb, Cr: Word);\n{ Converts YCbCr as used in JPEG to RGB color.}\nprocedure YCbCrToRGB16(Y, Cb, Cr: Word; var R, G, B: Word);\n\n{ Converts RGB color to CMY.}\nprocedure RGBToCMY(R, G, B: Byte; var C, M, Y: Byte);\n{ Converts CMY to RGB color.}\nprocedure CMYToRGB(C, M, Y: Byte; var R, G, B: Byte);\n{ Converts RGB color to CMY.}\nprocedure RGBToCMY16(R, G, B: Word; var C, M, Y: Word);\n{ Converts CMY to RGB color.}\nprocedure CMYToRGB16(C, M, Y: Word; var R, G, B: Word);\n\n{ Converts RGB color to CMYK.}\nprocedure RGBToCMYK(R, G, B: Byte; var C, M, Y, K: Byte);\n{ Converts CMYK to RGB color.}\nprocedure CMYKToRGB(C, M, Y, K: Byte; var R, G, B: Byte);\n{ Converts RGB color to CMYK.}\nprocedure RGBToCMYK16(R, G, B: Word; var C, M, Y, K: Word);\n{ Converts CMYK to RGB color.}\nprocedure CMYKToRGB16(C, M, Y, K: Word; var R, G, B: Word);\n\n{ Converts RGB color to YCoCg.}\nprocedure RGBToYCoCg(R, G, B: Byte; var Y, Co, Cg: Byte);\n{ Converts YCoCg to RGB color.}\nprocedure YCoCgToRGB(Y, Co, Cg: Byte; var R, G, B: Byte);\n\n//procedure RGBToHSL(R, G, B: Byte; var H, S, L: Byte);\n//procedure HSLToRGB(H, S, L: Byte; var R, G, B: Byte);\n\nimplementation\n\nprocedure RGBToYUV(R, G, B: Byte; var Y, U, V: Byte);\nbegin\n  Y := ClampToByte(Round( 0.257 * R + 0.504 * G + 0.098 * B) + 16);\n  V := ClampToByte(Round( 0.439 * R - 0.368 * G - 0.071 * B) + 128);\n  U := ClampToByte(Round(-0.148 * R - 0.291 * G + 0.439 * B) + 128);\nend;\n\nprocedure YUVToRGB(Y, U, V: Byte; var R, G, B: Byte);\nvar\n  CY, CU, CV: LongInt;\nbegin\n  CY := Y - 16;\n  CU := U - 128;\n  CV := V - 128;\n  R := ClampToByte(Round(1.164 * CY - 0.002 * CU + 1.596 * CV));\n  G := ClampToByte(Round(1.164 * CY - 0.391 * CU - 0.813 * CV));\n  B := ClampToByte(Round(1.164 * CY + 2.018 * CU - 0.001 * CV));\nend;\n\nprocedure RGBToYCbCr(R, G, B: Byte; var Y, Cb, Cr: Byte);\nbegin\n  Y  := ClampToByte(Round( 0.29900 * R + 0.58700 * G + 0.11400 * B));\n  Cb := ClampToByte(Round(-0.16874 * R - 0.33126 * G + 0.50000 * B  + 128));\n  Cr := ClampToByte(Round( 0.50000 * R - 0.41869 * G - 0.08131 * B  + 128));\nend;\n\nprocedure YCbCrToRGB(Y, Cb, Cr: Byte; var R, G, B: Byte);\nbegin\n  R := ClampToByte(Round(Y                        + 1.40200 * (Cr - 128)));\n  G := ClampToByte(Round(Y - 0.34414 * (Cb - 128) - 0.71414 * (Cr - 128)));\n  B := ClampToByte(Round(Y + 1.77200 * (Cb - 128)));\nend;\n\nprocedure RGBToYCbCr16(R, G, B: Word; var Y, Cb, Cr: Word);\nbegin\n  Y  := ClampToWord(Round( 0.29900 * R + 0.58700 * G + 0.11400 * B));\n  Cb := ClampToWord(Round(-0.16874 * R - 0.33126 * G + 0.50000 * B  + 32768));\n  Cr := ClampToWord(Round( 0.50000 * R - 0.41869 * G - 0.08131 * B  + 32768));\nend;\n\nprocedure YCbCrToRGB16(Y, Cb, Cr: Word; var R, G, B: Word);\nbegin\n  R := ClampToWord(Round(Y                          + 1.40200 * (Cr - 32768)));\n  G := ClampToWord(Round(Y - 0.34414 * (Cb - 32768) - 0.71414 * (Cr - 32768)));\n  B := ClampToWord(Round(Y + 1.77200 * (Cb - 32768)));\nend;\n\nprocedure RGBToCMY(R, G, B: Byte; var C, M, Y: Byte);\nbegin\n  C := 255 - R;\n  M := 255 - G;\n  Y := 255 - B;\nend;\n\nprocedure CMYToRGB(C, M, Y: Byte; var R, G, B: Byte);\nbegin\n  R := 255 - C;\n  G := 255 - M;\n  B := 255 - Y;\nend;\n\nprocedure RGBToCMY16(R, G, B: Word; var C, M, Y: Word);\nbegin\n  C := 65535 - R;\n  M := 65535 - G;\n  Y := 65535 - B;\nend;\n\nprocedure CMYToRGB16(C, M, Y: Word; var R, G, B: Word);\nbegin\n  R := 65535 - C;\n  G := 65535 - M;\n  B := 65535 - Y;\nend;\n\nprocedure RGBToCMYK(R, G, B: Byte; var C, M, Y, K: Byte);\nbegin\n  RGBToCMY(R, G, B, C, M, Y);\n  K := Min(C, Min(M, Y));\n  if K = 255 then\n  begin\n    C := 0;\n    M := 0;\n    Y := 0;\n  end\n  else\n  begin\n    C := ClampToByte(Round((C - K) / (255 - K) * 255));\n    M := ClampToByte(Round((M - K) / (255 - K) * 255));\n    Y := ClampToByte(Round((Y - K) / (255 - K) * 255));\n  end;\nend;\n\nprocedure CMYKToRGB(C, M, Y, K: Byte; var R, G, B: Byte);\nbegin\n   R := (255 - (C - MulDiv(C, K, 255) + K));\n   G := (255 - (M - MulDiv(M, K, 255) + K));\n   B := (255 - (Y - MulDiv(Y, K, 255) + K));\nend;\n\nprocedure RGBToCMYK16(R, G, B: Word; var C, M, Y, K: Word);\nbegin\n  RGBToCMY16(R, G, B, C, M, Y);\n  K := Min(C, Min(M, Y));\n  if K = 65535 then\n  begin\n    C := 0;\n    M := 0;\n    Y := 0;\n  end\n  else\n  begin\n    C := ClampToWord(Round((C - K) / (65535 - K) * 65535));\n    M := ClampToWord(Round((M - K) / (65535 - K) * 65535));\n    Y := ClampToWord(Round((Y - K) / (65535 - K) * 65535));\n  end;\nend;\n\nprocedure CMYKToRGB16(C, M, Y, K: Word; var R, G, B: Word);\nbegin\n  R := 65535 - (C - MulDiv(C, K, 65535) + K);\n  G := 65535 - (M - MulDiv(M, K, 65535) + K);\n  B := 65535 - (Y - MulDiv(Y, K, 65535) + K);\nend;\n\nprocedure RGBToYCoCg(R, G, B: Byte; var Y, Co, Cg: Byte);\nbegin\n  // C and Delphi's SHR behaviour differs for negative numbers, use div instead.\n  Y  := ClampToByte(( R +     G shl 1 + B       + 2) div 4);\n  Co := ClampToByte(( R shl 1         - B shl 1 + 2) div 4 + 128);\n  Cg := ClampToByte((-R +     G shl 1 - B       + 2) div 4 + 128);\nend;\n\nprocedure YCoCgToRGB(Y, Co, Cg: Byte; var R, G, B: Byte);\nvar\n  CoInt, CgInt: Integer;\nbegin\n  CoInt := Co - 128;\n  CgInt := Cg - 128;\n  R := ClampToByte(Y + CoInt - CgInt);\n  G := ClampToByte(Y + CgInt);\n  B := ClampToByte(Y - CoInt - CgInt);\nend;\n\n{\n  File Notes:\n\n  -- TODOS ----------------------------------------------------\n    - nothing now\n\n  -- 0.26.3 Changes/Bug Fixes ---------------------------------\n    - Added RGB<>YCoCg conversion functions.\n    - Fixed RGB>>CMYK conversions.\n\n  -- 0.23 Changes/Bug Fixes -----------------------------------\n    - Added RGB<>CMY(K) converion functions for 16 bit channels\n      (needed by PSD loading code).\n\n  -- 0.21 Changes/Bug Fixes -----------------------------------\n    - Added some color space conversion functions and LUTs\n      (RGB/YUV/YCrCb/CMY/CMYK).\n\n  -- 0.17 Changes/Bug Fixes -----------------------------------\n    - unit created (empty!)\n}\n\nend.\n"
  },
  {
    "path": "lib/Imaging/ImagingComponents.pas",
    "content": "{\n  Vampyre Imaging Library\n  by Marek Mauder \n  http://imaginglib.sourceforge.net\n\n  The contents of this file are used with permission, subject to the Mozilla\n  Public License Version 1.1 (the \"License\"); you may not use this file except\n  in compliance with the License. You may obtain a copy of the License at\n  http://www.mozilla.org/MPL/MPL-1.1.html\n\n  Software distributed under the License is distributed on an \"AS IS\" basis,\n  WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for\n  the specific language governing rights and limitations under the License.\n\n  Alternatively, the contents of this file may be used under the terms of the\n  GNU Lesser General Public License (the  \"LGPL License\"), in which case the\n  provisions of the LGPL License are applicable instead of those above.\n  If you wish to allow use of your version of this file only under the terms\n  of the LGPL License and not to allow others to use your version of this file\n  under the MPL, indicate your decision by deleting  the provisions above and\n  replace  them with the notice and other provisions required by the LGPL\n  License.  If you do not delete the provisions above, a recipient may use\n  your version of this file under either the MPL or the LGPL License.\n\n  For more information about the LGPL: http://www.gnu.org/copyleft/lesser.html\n}\n\n{ This unit contains VCL/LCL TGraphic descendant which uses Imaging library\n  for saving and loading.}\nunit ImagingComponents;\n\n{$I ImagingOptions.inc}\n\ninterface\n\n{$IFDEF LCL}\n  {$DEFINE COMPONENT_SET_LCL}\n  {$UNDEF COMPONENT_SET_VCL}\n{$ENDIF}\n\n{$IF not Defined(COMPONENT_SET_LCL) and not Defined(COMPONENT_SET_VCL)}\n// If no component sets should be used just include empty unit.\n//DOC-IGNORE-BEGIN\nimplementation\n//DOC-IGNORE-END\n{$ELSE}\n\nuses\n  SysUtils, Types, Classes,\n{$IFDEF MSWINDOWS}\n  Windows,\n{$ENDIF}\n{$IFDEF COMPONENT_SET_VCL}\n  Graphics,\n{$ENDIF}\n{$IFDEF COMPONENT_SET_LCL}\n  InterfaceBase,\n  GraphType,\n  Graphics,\n  LCLType,\n  LCLIntf,\n{$ENDIF}\n  ImagingTypes, Imaging, ImagingClasses;\n\ntype\n  { Graphic class which uses Imaging to load images.\n    It has standard TBitmap class as ancestor and it can\n    Assign also to/from TImageData structres and TBaseImage\n    classes. For saving is uses inherited TBitmap methods.\n    This class is automatically registered to TPicture for all\n    file extensions supported by Imaging (useful only for loading).\n    If you just want to load images in various formats you can use this\n    class or simply use  TPicture.LoadFromXXX which will create this class\n    automatically. For TGraphic class that saves with Imaging look\n    at TImagingGraphicForSave class.}\n  TImagingGraphic = class(TBitmap)\n  protected\n    procedure ReadDataFromStream(Stream: TStream); virtual;\n    procedure AssignTo(Dest: TPersistent); override;\n  public\n    constructor Create; override;\n\n    { Loads new image from the stream. It can load all image\n      file formats supported by Imaging (and enabled of course)\n      even though it is called by descendant class capable of\n      saving only one file format.}\n    procedure LoadFromStream(Stream: TStream); override;\n    { Copies the image contained in Source to this graphic object.\n      Supports also TBaseImage descendants from ImagingClasses unit. }\n    procedure Assign(Source: TPersistent); override;\n    { Copies the image contained in TBaseImage to this graphic object.}\n    procedure AssignFromImage(Image: TBaseImage);\n    { Copies the current image to TBaseImage object.}\n    procedure AssignToImage(Image: TBaseImage);\n    { Copies the image contained in TImageData structure to this graphic object.}\n    procedure AssignFromImageData(const ImageData: TImageData);\n    { Copies the current image to TImageData structure.}\n    procedure AssignToImageData(var ImageData: TImageData);\n  end;\n\n  TImagingGraphicClass = class of TImagingGraphic;\n\n  { Base class for file format specific TGraphic classes that use\n    Imaging for saving. Each descendant class can load all file formats\n    supported by Imaging but save only one format (TImagingBitmap\n    for *.bmp, TImagingJpeg for *.jpg). Format specific classes also\n    allow easy access to Imaging options that affect saving of files\n    (they are properties here).}\n  TImagingGraphicForSave = class(TImagingGraphic)\n  protected\n    FDefaultFileExt: string;\n    FSavingFormat: TImageFormat;\n    procedure WriteDataToStream(Stream: TStream); virtual;\n  public\n    constructor Create; override;\n    { Saves the current image to the stream. It is saved in the\n      file format according to the DefaultFileExt property.\n      So each descendant class can save some other file format.}\n    procedure SaveToStream(Stream: TStream); override;\n    { Returns TImageFileFormat descendant for this graphic class.}\n    class function GetFileFormat: TImageFileFormat; virtual; abstract;\n  {$IFDEF COMPONENT_SET_LCL}\n    { Returns file extensions of this graphic class.}\n    class function GetFileExtensions: string; override;\n    { Returns default MIME type of this graphic class.}\n    function GetMimeType: string; override;\n  {$ENDIF}\n    { Default (the most common) file extension of this graphic class.}\n    property DefaultFileExt: string read FDefaultFileExt;\n  end;\n\n  TImagingGraphicForSaveClass = class of TImagingGraphicForSave;\n\n{$IFNDEF DONT_LINK_BITMAP}\n  { TImagingGraphic descendant for loading/saving Windows bitmaps.\n    VCL/CLX/LCL all have native support for bitmaps so you might\n    want to disable this class (although you can save bitmaps with\n    RLE compression with this class).}\n  TImagingBitmap = class(TImagingGraphicForSave)\n  protected\n    FUseRLE: Boolean;\n  public\n    constructor Create; override;\n    procedure SaveToStream(Stream: TStream); override;\n    class function GetFileFormat: TImageFileFormat; override;\n    { See ImagingBitmapRLE option for details.}\n    property UseRLE: Boolean read FUseRLE write FUseRLE;\n  end;\n{$ENDIF}\n\n{$IFNDEF DONT_LINK_JPEG}\n  { TImagingGraphic descendant for loading/saving JPEG images.}\n  TImagingJpeg = class(TImagingGraphicForSave)\n  protected\n    FQuality: LongInt;\n    FProgressive: Boolean;\n  public\n    constructor Create; override;\n    procedure SaveToStream(Stream: TStream); override;\n    class function GetFileFormat: TImageFileFormat; override;\n  {$IFDEF COMPONENT_SET_LCL}\n    function GetMimeType: string; override;\n  {$ENDIF}\n    { See ImagingJpegQuality option for details.}\n    property Quality: LongInt read FQuality write FQuality;\n    { See ImagingJpegProgressive option for details.}\n    property Progressive: Boolean read FProgressive write FProgressive;\n  end;\n{$ENDIF}\n\n{$IFNDEF DONT_LINK_PNG}\n  { TImagingGraphic descendant for loading/saving PNG images.}\n  TImagingPNG = class(TImagingGraphicForSave)\n  protected\n    FPreFilter: LongInt;\n    FCompressLevel: LongInt;\n  public\n    constructor Create; override;\n    procedure SaveToStream(Stream: TStream); override;\n    class function GetFileFormat: TImageFileFormat; override;\n    { See ImagingPNGPreFilter option for details.}\n    property PreFilter: LongInt read FPreFilter write FPreFilter;\n    { See ImagingPNGCompressLevel option for details.}\n    property CompressLevel: LongInt read FCompressLevel write FCompressLevel;\n  end;\n{$ENDIF}\n\n{$IFNDEF DONT_LINK_GIF}\n  { TImagingGraphic descendant for loading/saving GIF images.}\n  TImagingGIF = class(TImagingGraphicForSave)\n  public\n    class function GetFileFormat: TImageFileFormat; override;\n  end;\n{$ENDIF}\n\n{$IFNDEF DONT_LINK_TARGA}\n  { TImagingGraphic descendant for loading/saving Targa images.}\n  TImagingTarga = class(TImagingGraphicForSave)\n  protected\n    FUseRLE: Boolean;\n  public\n    constructor Create; override;\n    procedure SaveToStream(Stream: TStream); override;\n    class function GetFileFormat: TImageFileFormat; override;\n    { See ImagingTargaRLE option for details.}\n    property UseRLE: Boolean read FUseRLE write FUseRLE;\n  end;\n{$ENDIF}\n\n{$IFNDEF DONT_LINK_DDS}\n  { Compresssion type used when saving DDS files by TImagingDds.}\n  TDDSCompresion = (dcNone, dcDXT1, dcDXT3, dcDXT5);\n\n  { TImagingGraphic descendant for loading/saving DDS images.}\n  TImagingDDS = class(TImagingGraphicForSave)\n  protected\n    FCompression: TDDSCompresion;\n  public\n    constructor Create; override;\n    procedure SaveToStream(Stream: TStream); override;\n    class function GetFileFormat: TImageFileFormat; override;\n    { You can choose compression type used when saving DDS file.\n      dcNone means that file will be saved in the current bitmaps pixel format.}\n    property Compression: TDDSCompresion read FCompression write FCompression;\n  end;\n{$ENDIF}\n\n{$IFNDEF DONT_LINK_MNG}\n  { TImagingGraphic descendant for loading/saving MNG images.}\n  TImagingMNG = class(TImagingGraphicForSave)\n  protected\n    FLossyCompression: Boolean;\n    FLossyAlpha: Boolean;\n    FPreFilter: LongInt;\n    FCompressLevel: LongInt;\n    FQuality: LongInt;\n    FProgressive: Boolean;\n  public\n    constructor Create; override;\n    procedure SaveToStream(Stream: TStream); override;\n    class function GetFileFormat: TImageFileFormat; override;\n  {$IFDEF COMPONENT_SET_LCL}\n    function GetMimeType: string; override;\n  {$ENDIF}\n    { See ImagingMNGLossyCompression option for details.}\n    property LossyCompression: Boolean read FLossyCompression write FLossyCompression;\n    { See ImagingMNGLossyAlpha option for details.}\n    property LossyAlpha: Boolean read FLossyAlpha write FLossyAlpha;\n    { See ImagingMNGPreFilter option for details.}\n    property PreFilter: LongInt read FPreFilter write FPreFilter;\n    { See ImagingMNGCompressLevel option for details.}\n    property CompressLevel: LongInt read FCompressLevel write FCompressLevel;\n    { See ImagingMNGQuality option for details.}\n    property Quality: LongInt read FQuality write FQuality;\n    { See ImagingMNGProgressive option for details.}\n    property Progressive: Boolean read FProgressive write FProgressive;\n  end;\n{$ENDIF}\n\n{$IFNDEF DONT_LINK_JNG}\n  { TImagingGraphic descendant for loading/saving JNG images.}\n  TImagingJNG = class(TImagingGraphicForSave)\n  protected\n    FLossyAlpha: Boolean;\n    FAlphaPreFilter: LongInt;\n    FAlphaCompressLevel: LongInt;\n    FQuality: LongInt;\n    FProgressive: Boolean;\n  public\n    constructor Create; override;\n    procedure SaveToStream(Stream: TStream); override;\n    class function GetFileFormat: TImageFileFormat; override;\n    { See ImagingJNGLossyAlpha option for details.}\n    property LossyAlpha: Boolean read FLossyAlpha write FLossyAlpha;\n    { See ImagingJNGPreFilter option for details.}\n    property AlphaPreFilter: LongInt read FAlphaPreFilter write FAlphaPreFilter;\n    { See ImagingJNGCompressLevel option for details.}\n    property AlphaCompressLevel: LongInt read FAlphaCompressLevel write FAlphaCompressLevel;\n    { See ImagingJNGQuality option for details.}\n    property Quality: LongInt read FQuality write FQuality;\n    { See ImagingJNGProgressive option for details.}\n    property Progressive: Boolean read FProgressive write FProgressive;\n  end;\n{$ENDIF}\n\n{ Returns bitmap pixel format with the closest match with given data format.}\nfunction DataFormatToPixelFormat(Format: TImageFormat): TPixelFormat;\n{ Returns data format with closest match with given bitmap pixel format.}\nfunction PixelFormatToDataFormat(Format: TPixelFormat): TImageFormat;\n\n{ Converts TImageData structure to VCL/CLX/LCL bitmap.}\nprocedure ConvertDataToBitmap(const Data: TImageData; Bitmap: TBitmap);\n{ Converts VCL/CLX/LCL bitmap to TImageData structure.}\nprocedure ConvertBitmapToData(Bitmap: TBitmap; var Data: TImageData);\n{ Converts TBaseImage instance to VCL/CLX/LCL bitmap.}\nprocedure ConvertImageToBitmap(Image: TBaseImage; Bitmap: TBitmap);\n{ Converts VCL/CLX/LCL bitmap to TBaseImage. Image must exist before\n  procedure is called. It overwrites its current image data.\n  When Image is TMultiImage only the current image level is overwritten.}\nprocedure ConvertBitmapToImage(Bitmap: TBitmap; Image: TBaseImage);\n\n{ Displays image stored in TImageData structure onto TCanvas. This procedure\n  draws image without converting from Imaging format to TBitmap.\n  Only [ifA8R8G8B8, ifX8R8G8B8] image formats are supported. Use this\n  when you want displaying images that change frequently (because converting to\n  TBitmap by ConvertImageDataToBitmap is generally slow). Dest and Src\n  rectangles represent coordinates in the form (X1, Y1, X2, Y2).}\nprocedure DisplayImageData(DstCanvas: TCanvas; const DstRect: TRect; const ImageData: TImageData; const SrcRect: TRect);\n{ Displays image onto TCanvas at position [DstX, DstY]. This procedure\n  draws image without converting from Imaging format to TBitmap.\n  Only [ifA8R8G8B8, ifX8R8G8B8] image formats are supported. Use this\n  when you want displaying images that change frequently (because converting to\n  TBitmap by ConvertImageDataToBitmap is generally slow).}\nprocedure DisplayImage(DstCanvas: TCanvas; DstX, DstY: LongInt; Image: TBaseImage); overload;\n{ Displays image onto TCanvas to rectangle DstRect. This procedure\n  draws image without converting from Imaging format to TBitmap.\n  Only [ifA8R8G8B8, ifX8R8G8B8] image formats are supported. Use this\n  when you want displaying images that change frequently (because converting to\n  TBitmap by ConvertImageDataToBitmap is generally slow).}\nprocedure DisplayImage(DstCanvas: TCanvas; const DstRect: TRect; Image: TBaseImage); overload;\n{ Displays part of the image specified by SrcRect onto TCanvas to rectangle DstRect.\n  This procedure draws image without converting from Imaging format to TBitmap.\n  Only [ifA8R8G8B8, ifX8R8G8B8] image formats are supported. Use this\n  when you want displaying images that change frequently (because converting to\n  TBitmap by ConvertImageDataToBitmap is generally slow).}\nprocedure DisplayImage(DstCanvas: TCanvas; const DstRect: TRect; Image: TBaseImage; const SrcRect: TRect); overload;\n\n{$IFDEF MSWINDOWS}\n{ Displays image stored in TImageData structure onto Windows device context.\n  Behaviour is the same as of DisplayImageData.}\nprocedure DisplayImageDataOnDC(DC: HDC; const DstRect: TRect; const ImageData: TImageData; const SrcRect: TRect);\n{$ENDIF}\n\nimplementation\n\nuses\n{$IF Defined(LCL)}\n  {$IF Defined(LCLGTK2)}\n    GLib2, GDK2, GTK2, GTK2Def, GTK2Proc,\n  {$IFEND}\n{$IFEND}\n{$IFNDEF DONT_LINK_BITMAP}\n  ImagingBitmap,\n{$ENDIF}\n{$IFNDEF DONT_LINK_JPEG}\n  ImagingJpeg,\n{$ENDIF}\n{$IFNDEF DONT_LINK_GIF}\n  ImagingGif,\n{$ENDIF}\n{$IFNDEF DONT_LINK_TARGA}\n  ImagingTarga,\n{$ENDIF}\n{$IFNDEF DONT_LINK_DDS}\n  ImagingDds,\n{$ENDIF}\n{$IF not Defined(DONT_LINK_PNG) or not Defined(DONT_LINK_MNG) or not Defined(DONT_LINK_JNG)}\n  ImagingNetworkGraphics,\n{$IFEND}\n  ImagingFormats, ImagingUtility;\n\nresourcestring\n  SBadFormatDataToBitmap = 'Cannot find compatible bitmap format for image %s';\n  SBadFormatBitmapToData = 'Cannot find compatible data format for bitmap %p';\n  SBadFormatDisplay = 'Unsupported image format passed';\n  SUnsupportedLCLWidgetSet = 'This function is not implemented for current LCL widget set';\n  SImagingGraphicName = 'Imaging Graphic AllInOne';\n\n{ Registers types to VCL/LCL.}\nprocedure RegisterTypes;\nvar\n  I: LongInt;\n\n  procedure RegisterFileFormatAllInOne(Format: TImageFileFormat);\n  var\n    I: LongInt;\n  begin\n    for I := 0 to Format.Extensions.Count - 1 do\n      TPicture.RegisterFileFormat(Format.Extensions[I], SImagingGraphicName,\n        TImagingGraphic);\n  end;\n\n  procedure RegisterFileFormat(AClass: TImagingGraphicForSaveClass);\n  var\n    I: LongInt;\n  begin\n    for I := 0 to AClass.GetFileFormat.Extensions.Count - 1 do\n      TPicture.RegisterFileFormat(AClass.GetFileFormat.Extensions[I],\n        AClass.GetFileFormat.Name, AClass);\n  end;\n\nbegin\n  for I := Imaging.GetFileFormatCount - 1 downto 0 do\n    RegisterFileFormatAllInOne(Imaging.GetFileFormatAtIndex(I));\n  Classes.RegisterClass(TImagingGraphic);\n\n{$IFNDEF DONT_LINK_TARGA}\n  RegisterFileFormat(TImagingTarga);\n  Classes.RegisterClass(TImagingTarga);\n{$ENDIF}\n{$IFNDEF DONT_LINK_DDS}\n  RegisterFileFormat(TImagingDDS);\n  Classes.RegisterClass(TImagingDDS);\n{$ENDIF}\n{$IFNDEF DONT_LINK_JNG}\n  RegisterFileFormat(TImagingJNG);\n  Classes.RegisterClass(TImagingJNG);\n{$ENDIF}\n{$IFNDEF DONT_LINK_MNG}\n  RegisterFileFormat(TImagingMNG);\n  Classes.RegisterClass(TImagingMNG);\n{$ENDIF}\n{$IFNDEF DONT_LINK_GIF}\n  RegisterFileFormat(TImagingGIF);\n  Classes.RegisterClass(TImagingGIF);\n{$ENDIF}\n{$IFNDEF DONT_LINK_PNG}\n  {$IFDEF COMPONENT_SET_LCL}\n    // Unregister Lazarus default PNG loader which crashes on some PNG files\n    TPicture.UnregisterGraphicClass(TPortableNetworkGraphic);\n  {$ENDIF}\n  RegisterFileFormat(TImagingPNG);\n  Classes.RegisterClass(TImagingPNG);\n{$ENDIF}\n{$IFNDEF DONT_LINK_JPEG}\n  RegisterFileFormat(TImagingJpeg);\n  Classes.RegisterClass(TImagingJpeg);\n{$ENDIF}\n{$IFNDEF DONT_LINK_BITMAP}\n  RegisterFileFormat(TImagingBitmap);\n  Classes.RegisterClass(TImagingBitmap);\n{$ENDIF}   \nend;\n\n{ Unregisters types from VCL/LCL.}\nprocedure UnRegisterTypes;\nbegin\n{$IFNDEF DONT_LINK_BITMAP}\n  TPicture.UnregisterGraphicClass(TImagingBitmap);\n  Classes.UnRegisterClass(TImagingBitmap);\n{$ENDIF}\n{$IFNDEF DONT_LINK_JPEG}\n  TPicture.UnregisterGraphicClass(TImagingJpeg);\n  Classes.UnRegisterClass(TImagingJpeg);\n{$ENDIF}\n{$IFNDEF DONT_LINK_PNG}\n  TPicture.UnregisterGraphicClass(TImagingPNG);\n  Classes.UnRegisterClass(TImagingPNG);\n{$ENDIF}\n{$IFNDEF DONT_LINK_GIF}\n  TPicture.UnregisterGraphicClass(TImagingGIF);\n  Classes.UnRegisterClass(TImagingGIF);\n{$ENDIF}\n{$IFNDEF DONT_LINK_TARGA}\n  TPicture.UnregisterGraphicClass(TImagingTarga);\n  Classes.UnRegisterClass(TImagingTarga);\n{$ENDIF}\n{$IFNDEF DONT_LINK_DDS}\n  TPicture.UnregisterGraphicClass(TImagingDDS);\n  Classes.UnRegisterClass(TImagingDDS);\n{$ENDIF}\n  TPicture.UnregisterGraphicClass(TImagingGraphic);\n  Classes.UnRegisterClass(TImagingGraphic);\nend;\n\nfunction DataFormatToPixelFormat(Format: TImageFormat): TPixelFormat;\nbegin\n  case Format of\n{$IFDEF COMPONENT_SET_VCL}\n    ifIndex8: Result := pf8bit;\n    ifR5G6B5: Result := pf16bit;\n    ifR8G8B8: Result := pf24bit;\n{$ENDIF}\n    ifA8R8G8B8,\n    ifX8R8G8B8: Result := pf32bit;\n  else\n    Result := pfCustom;\n  end;\nend;\n\nfunction PixelFormatToDataFormat(Format: TPixelFormat): TImageFormat;\nbegin\n  case Format of\n    pf8bit: Result := ifIndex8;\n    pf15bit: Result := ifA1R5G5B5;\n    pf16bit: Result := ifR5G6B5;\n    pf24bit: Result := ifR8G8B8;\n    pf32bit: Result := ifA8R8G8B8;\n  else\n    Result := ifUnknown;\n  end;\nend;\n\nprocedure ConvertDataToBitmap(const Data: TImageData; Bitmap: TBitmap);\nvar\n  I, LineBytes: LongInt;\n  PF: TPixelFormat;\n  Info: TImageFormatInfo;\n  WorkData: TImageData;\n{$IFDEF COMPONENT_SET_VCL}\n  LogPalette: TMaxLogPalette;\n{$ENDIF}\n{$IFDEF COMPONENT_SET_LCL}\n  RawImage: TRawImage;\n  ImgHandle, ImgMaskHandle: HBitmap;\n{$ENDIF}\nbegin\n  PF := DataFormatToPixelFormat(Data.Format);\n  GetImageFormatInfo(Data.Format, Info);\n\n  if (PF = pf8bit) and PaletteHasAlpha(Data.Palette, Info.PaletteEntries) then\n  begin\n    // Some indexed images may have valid alpha data, dont lose it!\n    // (e.g. transparent 8bit PNG or GIF images)\n    PF := pfCustom;\n  end;\n\n  if PF = pfCustom then\n  begin\n    // Convert from formats not supported by Graphics unit\n    Imaging.InitImage(WorkData);\n    Imaging.CloneImage(Data, WorkData);\n    if Info.IsFloatingPoint or Info.HasAlphaChannel or Info.IsSpecial then\n      Imaging.ConvertImage(WorkData, ifA8R8G8B8)\n    else\n    begin\n{$IFDEF COMPONENT_SET_VCL}\n      if Info.IsIndexed or Info.HasGrayChannel then\n        Imaging.ConvertImage(WorkData, ifIndex8)\n      else if Info.UsePixelFormat then\n        Imaging.ConvertImage(WorkData, ifR5G6B5)\n      else\n        Imaging.ConvertImage(WorkData, ifR8G8B8);\n{$ELSE}\n        Imaging.ConvertImage(WorkData, ifA8R8G8B8);\n{$ENDIF}\n    end;\n\n    PF := DataFormatToPixelFormat(WorkData.Format);\n    GetImageFormatInfo(WorkData.Format, Info);\n  end\n  else\n    WorkData := Data;\n    \n  if PF = pfCustom then\n    RaiseImaging(SBadFormatDataToBitmap, [ImageToStr(WorkData)]);\n      \n  LineBytes := WorkData.Width * Info.BytesPerPixel;\n\n{$IFDEF COMPONENT_SET_VCL}\n  Bitmap.Width := WorkData.Width;\n  Bitmap.Height := WorkData.Height;\n  Bitmap.PixelFormat := PF;\n\n  if (PF = pf8bit) and (WorkData.Palette <> nil) then\n  begin\n    // Copy palette, this must be done before copying bits\n    FillChar(LogPalette, SizeOf(LogPalette), 0);\n    LogPalette.palVersion := $300;\n    LogPalette.palNumEntries := Info.PaletteEntries;\n    for I := 0 to Info.PaletteEntries - 1 do\n    with LogPalette do\n    begin\n      palPalEntry[I].peRed := WorkData.Palette[I].R;\n      palPalEntry[I].peGreen := WorkData.Palette[I].G;\n      palPalEntry[I].peBlue := WorkData.Palette[I].B;\n    end;\n    Bitmap.Palette := CreatePalette(PLogPalette(@LogPalette)^);\n  end;\n  // Copy scanlines\n  for I := 0 to WorkData.Height - 1 do\n    Move(PByteArray(WorkData.Bits)[I * LineBytes], Bitmap.Scanline[I]^, LineBytes);\n\n  // Delphi 2009 and newer support alpha transparency fro TBitmap\n{$IF Defined(DELPHI) and (CompilerVersion >= 20.0)}\n  if Bitmap.PixelFormat = pf32bit then\n    Bitmap.AlphaFormat := afDefined;\n{$IFEND}\n\n{$ENDIF}\n{$IFDEF COMPONENT_SET_LCL}\n  // Create 32bit raw image from image data\n  FillChar(RawImage, SizeOf(RawImage), 0);\n  with RawImage.Description do\n  begin\n    Width := WorkData.Width;\n    Height := WorkData.Height;\n    BitsPerPixel := 32;\n    Format := ricfRGBA;\n    LineEnd := rileDWordBoundary;\n    BitOrder := riboBitsInOrder;\n    ByteOrder := riboLSBFirst;\n    LineOrder := riloTopToBottom;\n    AlphaPrec := 8;\n    RedPrec := 8;\n    GreenPrec := 8;\n    BluePrec := 8;\n    AlphaShift := 24;\n    RedShift := 16;\n    GreenShift := 8;\n    BlueShift := 0;\n    Depth := 32; // Must be 32 for alpha blending (and for working in MacOSX Carbon)\n  end;\n  RawImage.Data := WorkData.Bits;\n  RawImage.DataSize := WorkData.Size;\n\n  // Create bitmap from raw image\n  if RawImage_CreateBitmaps(RawImage, ImgHandle, ImgMaskHandle) then\n  begin\n    Bitmap.Handle := ImgHandle;\n    Bitmap.MaskHandle := ImgMaskHandle;\n  end;\n{$ENDIF}\n  if WorkData.Bits <> Data.Bits then\n    Imaging.FreeImage(WorkData);\nend;\n\nprocedure ConvertBitmapToData(Bitmap: TBitmap; var Data: TImageData);\nvar\n  I, LineBytes: LongInt;\n  Format: TImageFormat;\n  Info: TImageFormatInfo;\n{$IFDEF COMPONENT_SET_VCL}\n  Colors: Word;\n  LogPalette: TMaxLogPalette;\n{$ENDIF}\n{$IFDEF COMPONENT_SET_LCL}\n  RawImage: TRawImage;\n  LineLazBytes: LongInt;\n{$ENDIF}\nbegin\n{$IFDEF COMPONENT_SET_LCL}\n  // In the current Lazarus 0.9.10 Bitmap.PixelFormat property is useless.\n  // We cannot change bitmap's format by changing it (it will just release\n  // old image but not convert it to new format) nor we can determine bitmaps's\n  // current format (it is usually set to pfDevice). So bitmap's format is obtained\n  // trough RawImage api and cannot be changed to mirror some Imaging format\n  // (so formats with no coresponding Imaging format cannot be saved now).\n\n  if RawImage_DescriptionFromBitmap(Bitmap.Handle, RawImage.Description) then\n    case RawImage.Description.BitsPerPixel of\n      8: Format := ifIndex8;\n      16:\n        if RawImage.Description.Depth = 15 then\n          Format := ifA1R5G5B5\n        else\n          Format := ifR5G6B5;\n      24: Format := ifR8G8B8;\n      32: Format := ifA8R8G8B8;\n      48: Format := ifR16G16B16;\n      64: Format := ifA16R16G16B16;\n    else\n      Format := ifUnknown;\n    end;\n{$ELSE}\n  Format := PixelFormatToDataFormat(Bitmap.PixelFormat);\n  if Format = ifUnknown then\n  begin\n    // Convert from formats not supported by Imaging (1/4 bit)\n    if Bitmap.PixelFormat < pf8bit then\n       Bitmap.PixelFormat := pf8bit\n    else\n      Bitmap.PixelFormat := pf32bit;\n    Format := PixelFormatToDataFormat(Bitmap.PixelFormat);\n  end;\n{$ENDIF}\n\n  if Format = ifUnknown then\n    RaiseImaging(SBadFormatBitmapToData, []);\n\n  Imaging.NewImage(Bitmap.Width, Bitmap.Height, Format, Data);\n  GetImageFormatInfo(Data.Format, Info);\n  LineBytes := Data.Width * Info.BytesPerPixel;\n\n{$IFDEF COMPONENT_SET_VCL}\n  if (Format = ifIndex8) and (GetObject(Bitmap.Palette, SizeOf(Colors),\n    @Colors) <> 0) then\n  begin\n    // Copy palette\n    GetPaletteEntries(Bitmap.Palette, 0, Colors, LogPalette.palPalEntry);\n    if Colors > Info.PaletteEntries  then\n      Colors := Info.PaletteEntries;\n    for I := 0 to Colors - 1 do\n    with LogPalette do\n    begin\n      Data.Palette[I].A := $FF;\n      Data.Palette[I].R := palPalEntry[I].peRed;\n      Data.Palette[I].G := palPalEntry[I].peGreen;\n      Data.Palette[I].B := palPalEntry[I].peBlue;\n    end;\n  end;\n  // Copy scanlines\n  for I := 0 to Data.Height - 1 do\n    Move(Bitmap.ScanLine[I]^, PByteArray(Data.Bits)[I * LineBytes], LineBytes);\n{$ENDIF}\n{$IFDEF COMPONENT_SET_LCL}\n  // Get raw image from bitmap (mask handle must be 0 or expect violations)\n  if RawImage_FromBitmap(RawImage, Bitmap.Handle, 0, nil) then\n  begin\n    LineLazBytes := GetBytesPerLine(Data.Width, RawImage.Description.BitsPerPixel,\n      RawImage.Description.LineEnd);\n    // Copy scanlines\n    for I := 0 to Data.Height - 1 do\n    begin\n      Move(PByteArray(RawImage.Data)[I * LineLazBytes],\n        PByteArray(Data.Bits)[I * LineBytes], LineBytes);\n    end;\n    // May need to swap RB order, depends on wifget set\n    if RawImage.Description.BlueShift > RawImage.Description.RedShift then\n      SwapChannels(Data, ChannelRed, ChannelBlue);\n\n    RawImage.FreeData;\n  end;\n{$ENDIF}\nend;\n\nprocedure ConvertImageToBitmap(Image: TBaseImage; Bitmap: TBitmap);\nbegin\n  ConvertDataToBitmap(Image.ImageDataPointer^, Bitmap);\nend;\n\nprocedure ConvertBitmapToImage(Bitmap: TBitmap; Image: TBaseImage);\nbegin\n  ConvertBitmapToData(Bitmap, Image.ImageDataPointer^);\nend;\n\n{$IFDEF MSWINDOWS}\nprocedure DisplayImageDataOnDC(DC: HDC; const DstRect: TRect; const ImageData: TImageData; const SrcRect: TRect);\nvar\n  OldMode: Integer;\n  BitmapInfo: Windows.TBitmapInfo;\n  Bmp: TBitmap;\nbegin\n  if TestImage(ImageData) then\n  begin\n    Assert(ImageData.Format in [ifA8R8G8B8, ifX8R8G8B8], SBadFormatDisplay);\n    OldMode := Windows.SetStretchBltMode(DC, COLORONCOLOR);\n\n    FillChar(BitmapInfo, SizeOf(BitmapInfo), 0);\n    with BitmapInfo.bmiHeader do\n    begin\n      biSize := SizeOf(TBitmapInfoHeader);\n      biPlanes := 1;\n      biBitCount := 32;\n      biCompression := BI_RGB;\n      biWidth := ImageData.Width;\n      biHeight := -ImageData.Height;\n      biSizeImage := ImageData.Size;\n      biXPelsPerMeter := 0;\n      biYPelsPerMeter := 0;\n      biClrUsed := 0;\n      biClrImportant := 0;\n    end;\n\n    try\n       with SrcRect, ImageData do\n        if Windows.StretchDIBits(DC, DstRect.Left, DstRect.Top,\n          DstRect.Right - DstRect.Left, DstRect.Bottom - DstRect.Top, Left,\n          Top, Right - Left, Bottom - Top, Bits, BitmapInfo, DIB_RGB_COLORS, SRCCOPY) <> Height then\n        begin\n          // StretchDIBits may fail on some ocassions (error 487, http://support.microsoft.com/kb/269585).\n          // This fallback is slow but works every time. Thanks to Sergey Galezdinov for the fix.\n          Bmp := TBitmap.Create;\n          try\n            ConvertDataToBitmap(ImageData, Bmp);\n            StretchBlt(DC, DstRect.Left, DstRect.Top, DstRect.Right - DstRect.Left, DstRect.Bottom - DstRect.Top,\n              Bmp.Canvas.Handle, 0, 0, Width, Height, SRCCOPY);\n          finally\n            Bmp.Free;\n          end;\n        end;\n    finally\n      Windows.SetStretchBltMode(DC, OldMode);\n    end;\n  end;\nend;\n{$ENDIF}\n\nprocedure DisplayImageData(DstCanvas: TCanvas; const DstRect: TRect; const ImageData: TImageData; const SrcRect: TRect);\n{$IF Defined(DCC) or Defined(LCLWIN32)} // Delphi or LCL Win32\nbegin\n  DisplayImageDataOnDC(DstCanvas.Handle, DstRect, ImageData, SrcRect);\nend;\n{$ELSEIF Defined(LCLGTK2)}\n  type\n    TDeviceContext = TGtk2DeviceContext;\n\n  procedure GDKDrawBitmap(Dest: HDC; DstX, DstY: Integer; SrcX, SrcY,\n    SrcWidth, SrcHeight: Integer; ImageData: TImageData);\n  var\n    P: TPoint;\n  begin\n    P := TDeviceContext(Dest).Offset;\n    Inc(DstX, P.X);\n    Inc(DstY, P.Y);\n    gdk_draw_rgb_32_image(TDeviceContext(Dest).Drawable, TDeviceContext(Dest).GC,\n      DstX, DstY, SrcWidth, SrcHeight, GDK_RGB_DITHER_NONE,\n      @PLongWordArray(ImageData.Bits)[SrcY * ImageData.Width + SrcX], ImageData.Width * 4);\n  end;\n  \nvar\n  DisplayImage: TImageData;\n  NewWidth, NewHeight: Integer;\n  SrcBounds, DstBounds, DstClip: TRect;\nbegin\n  if TestImage(ImageData) then\n  begin\n    Assert(ImageData.Format in [ifA8R8G8B8, ifX8R8G8B8], SBadFormatDisplay);\n    InitImage(DisplayImage);\n\n    SrcBounds := RectToBounds(SrcRect);\n    DstBounds := RectToBounds(DstRect);\n    WidgetSet.GetClipBox(DstCanvas.Handle, @DstClip);\n\n    ClipStretchBounds(SrcBounds.Left, SrcBounds.Top, SrcBounds.Right, SrcBounds.Bottom,\n      DstBounds.Left, DstBounds.Top, DstBounds.Right, DstBounds.Bottom, ImageData.Width,\n      ImageData.Height, DstClip);\n\n    NewWidth := DstBounds.Right;\n    NewHeight := DstBounds.Bottom;\n\n    if (NewWidth > 0) and (NewHeight > 0) then\n    begin\n      if (SrcBounds.Right = NewWidth) and (SrcBounds.Bottom = NewHeight) then\n      try\n        CloneImage(ImageData, DisplayImage);\n        // Swap R-B channels for GTK display compatability!\n        SwapChannels(DisplayImage, ChannelRed, ChannelBlue);\n        GDKDrawBitmap(DstCanvas.Handle, DstBounds.Left, DstBounds.Top,\n          SrcBounds.Left, SrcBounds.Top, NewWidth, NewHeight, DisplayImage);\n      finally\n        FreeImage(DisplayImage);\n      end\n      else\n      try\n        // Create new image with desired dimensions\n        NewImage(NewWidth, NewHeight, ImageData.Format, DisplayImage);\n        // Stretch pixels from old image to new one  TResizeFilter = (rfNearest, rfBilinear, rfBicubic);\n        StretchRect(ImageData, SrcBounds.Left, SrcBounds.Top, SrcBounds.Right,\n          SrcBounds.Bottom, DisplayImage, 0, 0, NewWidth, NewHeight, rfNearest);\n        // Swap R-B channels for GTK display compatability!\n        SwapChannels(DisplayImage, ChannelRed, ChannelBlue);\n        GDKDrawBitmap(DstCanvas.Handle, DstBounds.Left, DstBounds.Top, 0, 0,\n          NewWidth, NewHeight, DisplayImage);\n       finally\n        FreeImage(DisplayImage);\n      end\n    end;\n  end;\nend;\n{$ELSE}\nbegin\n  raise Exception.Create(SUnsupportedLCLWidgetSet);\nend;\n{$IFEND}\n\nprocedure DisplayImage(DstCanvas: TCanvas; DstX, DstY: LongInt; Image: TBaseImage);\nbegin\n  DisplayImageData(DstCanvas, BoundsToRect(DstX, DstY, Image.Width, Image.Height),\n    Image.ImageDataPointer^, Image.BoundsRect);\nend;\n\nprocedure DisplayImage(DstCanvas: TCanvas; const DstRect: TRect; Image: TBaseImage);\nbegin\n  DisplayImageData(DstCanvas, DstRect, Image.ImageDataPointer^, Image.BoundsRect);\nend;\n\nprocedure DisplayImage(DstCanvas: TCanvas; const DstRect: TRect; Image: TBaseImage; const SrcRect: TRect);\nbegin\n  DisplayImageData(DstCanvas, DstRect, Image.ImageDataPointer^, SrcRect);\nend;\n\n\n{ TImagingGraphic class implementation }\n\nconstructor TImagingGraphic.Create;\nbegin\n  inherited Create;\n  PixelFormat := pf24Bit;\nend;\n\nprocedure TImagingGraphic.LoadFromStream(Stream: TStream);\nbegin\n  ReadDataFromStream(Stream);\nend;\n\nprocedure TImagingGraphic.ReadDataFromStream(Stream: TStream);\nvar\n  Image: TSingleImage;\nbegin\n  Image := TSingleImage.Create;\n  try\n    Image.LoadFromStream(Stream);\n    Assign(Image);\n  finally\n    Image.Free;\n  end;\nend;\n\nprocedure TImagingGraphic.AssignTo(Dest: TPersistent);\nvar\n  Arr: TDynImageDataArray;\nbegin\n  if Dest is TSingleImage then\n  begin\n    AssignToImage(TSingleImage(Dest))\n  end\n  else if Dest is TMultiImage then\n  begin\n    SetLength(Arr, 1);\n    AssignToImageData(Arr[0]);\n    TMultiImage(Dest).CreateFromArray(Arr);\n    Imaging.FreeImagesInArray(Arr);\n  end\n  else\n    inherited AssignTo(Dest);\nend;\n\nprocedure TImagingGraphic.Assign(Source: TPersistent);\nbegin\n  if Source is TBaseImage then\n    AssignFromImage(TBaseImage(Source))\n  else\n    inherited Assign(Source);\nend;\n\nprocedure TImagingGraphic.AssignFromImage(Image: TBaseImage);\nbegin\n  if (Image <> nil) and Image.Valid then\n    AssignFromImageData(Image.ImageDataPointer^);\nend;\n\nprocedure TImagingGraphic.AssignToImage(Image: TBaseImage);\nbegin\n  if (Image <> nil) and (Image.ImageDataPointer <> nil) then\n    AssignToImageData(Image.ImageDataPointer^);\nend;\n\nprocedure TImagingGraphic.AssignFromImageData(const ImageData: TImageData);\nbegin\n  if Imaging.TestImage(ImageData) then\n    ConvertDataToBitmap(ImageData, Self);\nend;\n\nprocedure TImagingGraphic.AssignToImageData(var ImageData: TImageData);\nbegin\n  Imaging.FreeImage(ImageData);\n  ConvertBitmapToData(Self, ImageData);\nend;\n\n\n{ TImagingGraphicForSave class implementation }\n\nconstructor TImagingGraphicForSave.Create;\nbegin\n  inherited Create;\n  FDefaultFileExt := GetFileFormat.Extensions[0];\n  FSavingFormat := ifUnknown;\n  GetFileFormat.CheckOptionsValidity;\nend;\n\nprocedure TImagingGraphicForSave.WriteDataToStream(Stream: TStream);\nvar\n  Image: TSingleImage;\nbegin\n  if FDefaultFileExt <> '' then\n  begin\n    Image := TSingleImage.Create;\n    try\n      Image.Assign(Self);\n      if FSavingFormat <> ifUnknown then\n        Image.Format := FSavingFormat;\n      Image.SaveToStream(FDefaultFileExt, Stream);\n    finally\n      Image.Free;\n    end;\n  end;\nend;\n\nprocedure TImagingGraphicForSave.SaveToStream(Stream: TStream);\nbegin\n  WriteDataToStream(Stream);\nend;\n\n{$IFDEF COMPONENT_SET_LCL}\nclass function TImagingGraphicForSave.GetFileExtensions: string;\nbegin\n  Result := StringReplace(GetFileFormat.Extensions.CommaText, ',', ';', [rfReplaceAll]);\nend;\n\nfunction TImagingGraphicForSave.GetMimeType: string;\nbegin\n  Result := 'image/' + FDefaultFileExt;\nend;\n{$ENDIF}\n\n{$IFNDEF DONT_LINK_BITMAP}\n\n{ TImagingBitmap class implementation }\n\nconstructor TImagingBitmap.Create;\nbegin\n  inherited Create;\n  FUseRLE := (GetFileFormat as TBitmapFileFormat).UseRLE;\nend;\n\nclass function TImagingBitmap.GetFileFormat: TImageFileFormat;\nbegin\n  Result := FindImageFileFormatByClass(TBitmapFileFormat);\nend;\n\nprocedure TImagingBitmap.SaveToStream(Stream: TStream);\nbegin\n  Imaging.PushOptions;\n  Imaging.SetOption(ImagingBitmapRLE, Ord(FUseRLE));\n  inherited SaveToStream(Stream);\n  Imaging.PopOptions;\nend;\n{$ENDIF}\n\n{$IFNDEF DONT_LINK_JPEG}\n\n{ TImagingJpeg class implementation }\n\nconstructor TImagingJpeg.Create;\nbegin\n  inherited Create;\n  FQuality := (GetFileFormat as TJpegFileFormat).Quality;\n  FProgressive := (GetFileFormat as TJpegFileFormat).Progressive;\nend;\n\nclass function TImagingJpeg.GetFileFormat: TImageFileFormat;\nbegin\n  Result := FindImageFileFormatByClass(TJpegFileFormat);\nend;\n\n{$IFDEF COMPONENT_SET_LCL}\nfunction TImagingJpeg.GetMimeType: string;\nbegin\n  Result := 'image/jpeg';\nend;\n{$ENDIF}\n\nprocedure TImagingJpeg.SaveToStream(Stream: TStream);\nbegin\n  Imaging.PushOptions;\n  Imaging.SetOption(ImagingJpegQuality, FQuality);\n  Imaging.SetOption(ImagingJpegProgressive, Ord(FProgressive));\n  inherited SaveToStream(Stream);\n  Imaging.PopOptions;\nend;\n\n{$ENDIF}\n\n{$IFNDEF DONT_LINK_PNG}\n\n{ TImagingPNG class implementation }\n\nconstructor TImagingPNG.Create;\nbegin\n  inherited Create;\n  FPreFilter := (GetFileFormat as TPNGFileFormat).PreFilter;\n  FCompressLevel := (GetFileFormat as TPNGFileFormat).CompressLevel;\nend;\n\nclass function TImagingPNG.GetFileFormat: TImageFileFormat;\nbegin\n  Result := FindImageFileFormatByClass(TPNGFileFormat);\nend;\n\nprocedure TImagingPNG.SaveToStream(Stream: TStream);\nbegin\n  Imaging.PushOptions;\n  Imaging.SetOption(ImagingPNGPreFilter, FPreFilter);\n  Imaging.SetOption(ImagingPNGCompressLevel, FCompressLevel);\n  inherited SaveToStream(Stream);\n  Imaging.PopOptions;\nend;\n{$ENDIF}\n\n{$IFNDEF DONT_LINK_GIF}\n\n{ TImagingGIF class implementation}\n\nclass function TImagingGIF.GetFileFormat: TImageFileFormat;\nbegin\n  Result := FindImageFileFormatByClass(TGIFFileFormat);\nend;\n\n{$ENDIF}\n\n{$IFNDEF DONT_LINK_TARGA}\n\n{ TImagingTarga class implementation }\n\nconstructor TImagingTarga.Create;\nbegin\n  inherited Create;\n  FUseRLE := (GetFileFormat as TTargaFileFormat).UseRLE;\nend;\n\nclass function TImagingTarga.GetFileFormat: TImageFileFormat;\nbegin\n  Result := FindImageFileFormatByClass(TTargaFileFormat);\nend;\n\nprocedure TImagingTarga.SaveToStream(Stream: TStream);\nbegin\n  Imaging.PushOptions;\n  Imaging.SetOption(ImagingTargaRLE, Ord(FUseRLE));\n  inherited SaveToStream(Stream);\n  Imaging.PopOptions;\nend;\n{$ENDIF}\n\n{$IFNDEF DONT_LINK_DDS}\n\n{ TImagingDDS class implementation }\n\nconstructor TImagingDDS.Create;\nbegin\n  inherited Create;\n  FCompression := dcNone;\nend;\n\nclass function TImagingDDS.GetFileFormat: TImageFileFormat;\nbegin\n  Result := FindImageFileFormatByClass(TDDSFileFormat);\nend;\n\nprocedure TImagingDDS.SaveToStream(Stream: TStream);\nbegin\n  case FCompression of\n    dcNone: FSavingFormat := ifUnknown;\n    dcDXT1: FSavingFormat := ifDXT1;\n    dcDXT3: FSavingFormat := ifDXT3;\n    dcDXT5: FSavingFormat := ifDXT5;\n  end;\n  Imaging.PushOptions;\n  Imaging.SetOption(ImagingDDSSaveCubeMap, Ord(False));\n  Imaging.SetOption(ImagingDDSSaveVolume, Ord(False));\n  Imaging.SetOption(ImagingDDSSaveMipMapCount, 1);\n  Imaging.SetOption(ImagingDDSSaveDepth, 1);\n  inherited SaveToStream(Stream);\n  Imaging.PopOptions;\nend;\n{$ENDIF}\n\n{$IFNDEF DONT_LINK_MNG}\n\n{ TImagingMNG class implementation }\n\nconstructor TImagingMNG.Create;\nbegin\n  inherited Create;\n  FLossyCompression := (GetFileFormat as TMNGFileFormat).LossyCompression;\n  FLossyAlpha := (GetFileFormat as TMNGFileFormat).LossyAlpha;\n  FPreFilter := (GetFileFormat as TMNGFileFormat).PreFilter;\n  FCompressLevel := (GetFileFormat as TMNGFileFormat).CompressLevel;\n  FQuality := (GetFileFormat as TMNGFileFormat).Quality;\n  FProgressive := (GetFileFormat as TMNGFileFormat).Progressive;\nend;\n\nclass function TImagingMNG.GetFileFormat: TImageFileFormat;\nbegin\n  Result := FindImageFileFormatByClass(TMNGFileFormat);\nend;\n\n{$IFDEF COMPONENT_SET_LCL}\nfunction TImagingMNG.GetMimeType: string;\nbegin\n  Result := 'video/mng';\nend;\n{$ENDIF}\n\nprocedure TImagingMNG.SaveToStream(Stream: TStream);\nbegin\n  Imaging.PushOptions;\n  Imaging.SetOption(ImagingMNGLossyCompression, Ord(FLossyCompression));\n  Imaging.SetOption(ImagingMNGLossyAlpha, Ord(FLossyAlpha));\n  Imaging.SetOption(ImagingMNGPreFilter, FPreFilter);\n  Imaging.SetOption(ImagingMNGCompressLevel, FCompressLevel);\n  Imaging.SetOption(ImagingMNGQuality, FQuality);\n  Imaging.SetOption(ImagingMNGProgressive, Ord(FProgressive));\n  inherited SaveToStream(Stream);\n  Imaging.PopOptions;\nend;\n{$ENDIF}\n\n{$IFNDEF DONT_LINK_JNG}\n\n{ TImagingJNG class implementation }\n\nconstructor TImagingJNG.Create;\nbegin\n  inherited Create;\n  FLossyAlpha := (GetFileFormat as TJNGFileFormat).LossyAlpha;\n  FAlphaPreFilter := (GetFileFormat as TJNGFileFormat).PreFilter;\n  FAlphaCompressLevel := (GetFileFormat as TJNGFileFormat).CompressLevel;\n  FQuality := (GetFileFormat as TJNGFileFormat).Quality;\n  FProgressive := (GetFileFormat as TJNGFileFormat).Progressive;\nend;\n\nclass function TImagingJNG.GetFileFormat: TImageFileFormat;\nbegin\n  Result := FindImageFileFormatByClass(TJNGFileFormat);\nend;\n\nprocedure TImagingJNG.SaveToStream(Stream: TStream);\nbegin\n  Imaging.PushOptions;\n  Imaging.SetOption(ImagingJNGLossyALpha, Ord(FLossyAlpha));\n  Imaging.SetOption(ImagingJNGAlphaPreFilter, FAlphaPreFilter);\n  Imaging.SetOption(ImagingJNGAlphaCompressLevel, FAlphaCompressLevel);\n  Imaging.SetOption(ImagingJNGQuality, FQuality);\n  Imaging.SetOption(ImagingJNGProgressive, Ord(FProgressive));\n  inherited SaveToStream(Stream);\n  Imaging.PopOptions;\nend;\n{$ENDIF}\n\ninitialization\n  RegisterTypes;\nfinalization\n  UnRegisterTypes;\n\n{$IFEND} // {$IF not Defined(COMPONENT_SET_LCL) and not Defined(COMPONENT_SET_VCL)}\n\n{\n  File Notes:\n\n  -- TODOS ----------------------------------------------------\n    - nothing now\n\n  -- 0.77.1 ---------------------------------------------------\n    - Fixed bug in ConvertBitmapToData causing images from GTK2 bitmaps\n      to have swapped RB channels.\n    - LCL: Removed GTK1 support (deprecated).\n\n  -- 0.26.3 Changes/Bug Fixes ---------------------------------\n    - Transparency of 8bit images (like loaded from 8bit PNG or GIF) is\n      kept intact during conversion to TBitmap in ConvertDataToBitmap\n      (32bit bitmap is created).\n\n  -- 0.26.3 Changes/Bug Fixes ---------------------------------\n    - Setting AlphaFormat property of TBitmap in ConvertDataToBitmap\n      when using Delphi 2009+.\n    - Fixed garbled LCL TBitmaps created by ConvertDataToBitmap\n      in Mac OS X (Carbon).\n\n  -- 0.26.1 Changes/Bug Fixes ---------------------------------\n    - Added some more IFDEFs for Lazarus widget sets.\n    - Removed CLX code.\n    - GTK version of Unix DisplayImageData only used with LCL GTK so the\n      the rest of the unit can be used with Qt or other LCL interfaces. \n    - Fallback mechanism for DisplayImageDataOnDC, it may fail on occasions.\n    - Changed file format conditional compilation to reflect changes\n      in LINK symbols.\n    - Lazarus 0.9.26 compatibility changes.\n\n  -- 0.24.1 Changes/Bug Fixes ---------------------------------\n    - Fixed wrong IFDEF causing that Imaging wouldn't compile in Lazarus\n      with GTK2 target.\n    - Added commnets with code for Lazarus rev. 11861+ regarding\n      RawImage interface. Replace current code with that in comments\n      if you use Lazarus from SVN. New RawImage interface will be used by\n      default after next Lazarus release. \n\n  -- 0.23 Changes/Bug Fixes -----------------------------------\n    - Added TImagingGIF. \n\n  -- 0.21 Changes/Bug Fixes -----------------------------------\n    - Uses only high level interface now (except for saving options).\n    - Slightly changed class hierarchy. TImagingGraphic is now only for loading\n      and base class for savers is new TImagingGraphicForSave. Also\n      TImagingGraphic is now registered with all supported file formats\n      by TPicture's format support.\n\n  -- 0.19 Changes/Bug Fixes -----------------------------------\n    - added DisplayImage procedures (thanks to Paul Michell, modified)\n    - removed RegisterTypes and UnRegisterTypes from interface section,\n      they are called automatically\n    - added procedures: ConvertImageToBitmap and ConvertBitmapToImage\n\n  -- 0.17 Changes/Bug Fixes -----------------------------------\n    - LCL data to bitmap conversion didnt work in Linux, fixed\n    - added MNG file format\n    - added JNG file format\n\n  -- 0.15 Changes/Bug Fixes -----------------------------------\n    - made it LCL compatible\n    - made it CLX compatible\n    - added all initial stuff\n}\n\nend.\n\n"
  },
  {
    "path": "lib/Imaging/ImagingDds.pas",
    "content": "{\n  Vampyre Imaging Library\n  by Marek Mauder\n  http://imaginglib.sourceforge.net\n\n  The contents of this file are used with permission, subject to the Mozilla\n  Public License Version 1.1 (the \"License\"); you may not use this file except\n  in compliance with the License. You may obtain a copy of the License at\n  http://www.mozilla.org/MPL/MPL-1.1.html\n\n  Software distributed under the License is distributed on an \"AS IS\" basis,\n  WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for\n  the specific language governing rights and limitations under the License.\n\n  Alternatively, the contents of this file may be used under the terms of the\n  GNU Lesser General Public License (the  \"LGPL License\"), in which case the\n  provisions of the LGPL License are applicable instead of those above.\n  If you wish to allow use of your version of this file only under the terms\n  of the LGPL License and not to allow others to use your version of this file\n  under the MPL, indicate your decision by deleting  the provisions above and\n  replace  them with the notice and other provisions required by the LGPL\n  License.  If you do not delete the provisions above, a recipient may use\n  your version of this file under either the MPL or the LGPL License.\n\n  For more information about the LGPL: http://www.gnu.org/copyleft/lesser.html\n}\n\n{ This unit contains image format loader/saver for DirectDraw Surface images.}\nunit ImagingDds;\n\n{$I ImagingOptions.inc}\n\ninterface\n\nuses\n  ImagingTypes, Imaging, ImagingUtility, ImagingFormats;\n\ntype\n  { Class for loading and saving Microsoft DirectDraw surfaces.\n    It can load/save all D3D formats which have coresponding\n    TImageFormat. It supports plain textures, cube textures and\n    volume textures, all of these can have mipmaps. It can also\n    load some formats which have no exact TImageFormat, but can be easily\n    converted to one (bump map formats, etc.).\n    You can get some information about last loaded DDS file by calling\n    GetOption with ImagingDDSLoadedXXX options and you can set some\n    saving options by calling SetOption with ImagingDDSSaveXXX or you can\n    simply use properties of this class.\n    Note that when saving cube maps and volumes input image array must contain\n    at least number of images to build cube/volume based on current\n    Depth and MipMapCount settings.}\n  TDDSFileFormat = class(TImageFileFormat)\n  private\n    FLoadedCubeMap: LongBool;\n    FLoadedVolume: LongBool;\n    FLoadedMipMapCount: LongInt;\n    FLoadedDepth: LongInt;\n    FSaveCubeMap: LongBool;\n    FSaveVolume: LongBool;\n    FSaveMipMapCount: LongInt;\n    FSaveDepth: LongInt;\n    procedure ComputeSubDimensions(Idx, Width, Height, MipMaps, Depth: LongInt;\n      IsCubeMap, IsVolume: Boolean; var CurWidth, CurHeight: LongInt);\n  protected\n    procedure Define; override;\n    function LoadData(Handle: TImagingHandle; var Images: TDynImageDataArray;\n      OnlyFirstLevel: Boolean): Boolean; override;\n    function SaveData(Handle: TImagingHandle; const Images: TDynImageDataArray;\n      Index: LongInt): Boolean; override;\n    procedure ConvertToSupported(var Image: TImageData;\n      const Info: TImageFormatInfo); override;\n  public\n    function TestFormat(Handle: TImagingHandle): Boolean; override;\n    procedure CheckOptionsValidity; override;\n  published\n    { True if last loaded DDS file was cube map.}\n    property LoadedCubeMap: LongBool read FLoadedCubeMap write FLoadedCubeMap;\n    { True if last loaded DDS file was volume texture.}\n    property LoadedVolume: LongBool read FLoadedVolume write FLoadedVolume;\n    { Number of mipmap levels of last loaded DDS image.}\n    property LoadedMipMapCount: LongInt read FLoadedMipMapCount write FLoadedMipMapCount;\n    { Depth (slices of volume texture or faces of cube map) of last loaded DDS image.}\n    property LoadedDepth: LongInt read FLoadedDepth write FLoadedDepth;\n    { True if next DDS file to be saved should be stored as cube map.}\n    property SaveCubeMap: LongBool read FSaveCubeMap write FSaveCubeMap;\n    { True if next DDS file to be saved should be stored as volume texture.}\n    property SaveVolume: LongBool read FSaveVolume write FSaveVolume;\n    { Sets the number of mipmaps which should be stored in the next saved DDS file.\n      Only applies to cube maps and volumes, ordinary 2D textures save all\n      levels present in input.}\n    property SaveMipMapCount: LongInt read FSaveMipMapCount write FSaveMipMapCount;\n    { Sets the depth (slices of volume texture or faces of cube map)\n      of the next saved DDS file.}\n    property SaveDepth: LongInt read FSaveDepth write FSaveDepth;\n  end;\n\nconst\n  { DDS related metadata Ids }\n\n  { DXGI format of textures stored in DDS files with DX10 extension. Type is\n    Enum (value corresponding to DXGI_FORMAT enum from DX SDK).}\n  SMetaDdsDxgiFormat = 'DdsDxgiFormat';\n  { Number of mipmaps for each main image in DDS file.}\n  SMetaDdsMipMapCount = 'DdsMipMapCount';\n  { Texture array size stored in DDS file (DX10 extension).}\n  SMetaDdsArraySize = 'DdsArraySize';\n\nconst\n  SDDSFormatName = 'DirectDraw Surface';\n  SDDSMasks      = '*.dds';\n  DDSSupportedFormats: TImageFormats = [ifR8G8B8, ifA8R8G8B8, ifX8R8G8B8,\n    ifA1R5G5B5, ifA4R4G4B4, ifX1R5G5B5, ifX4R4G4B4, ifR5G6B5, ifA16B16G16R16,\n    ifR32F, ifA32B32G32R32F, ifR16F, ifA16B16G16R16F, ifR3G3B2, ifGray8, ifA8Gray8,\n    ifGray16, ifDXT1, ifDXT3, ifDXT5, ifATI1N, ifATI2N];\n\nconst\n  { Four character codes.}\n  DDSMagic    = LongWord(Byte('D') or (Byte('D') shl 8) or (Byte('S') shl 16) or\n    (Byte(' ') shl 24));\n  FOURCC_DXT1 = LongWord(Byte('D') or (Byte('X') shl 8) or (Byte('T') shl 16) or\n    (Byte('1') shl 24));\n  FOURCC_DXT3 = LongWord(Byte('D') or (Byte('X') shl 8) or (Byte('T') shl 16) or\n    (Byte('3') shl 24));\n  FOURCC_DXT5 = LongWord(Byte('D') or (Byte('X') shl 8) or (Byte('T') shl 16) or\n    (Byte('5') shl 24));\n  FOURCC_ATI1 = LongWord(Byte('A') or (Byte('T') shl 8) or (Byte('I') shl 16) or\n    (Byte('1') shl 24));\n  FOURCC_ATI2 = LongWord(Byte('A') or (Byte('T') shl 8) or (Byte('I') shl 16) or\n    (Byte('2') shl 24));\n  FOURCC_DX10 = LongWord(Byte('D') or (Byte('X') shl 8) or (Byte('1') shl 16) or\n    (Byte('0') shl 24));\n\n  { Some D3DFORMAT values used in DDS files as FourCC value.}\n  D3DFMT_A16B16G16R16  = 36;\n  D3DFMT_R32F          = 114;\n  D3DFMT_A32B32G32R32F = 116;\n  D3DFMT_R16F          = 111;\n  D3DFMT_A16B16G16R16F = 113;\n\n  { Constans used by TDDSurfaceDesc2.Flags.}\n  DDSD_CAPS            = $00000001;\n  DDSD_HEIGHT          = $00000002;\n  DDSD_WIDTH           = $00000004;\n  DDSD_PITCH           = $00000008;\n  DDSD_PIXELFORMAT     = $00001000;\n  DDSD_MIPMAPCOUNT     = $00020000;\n  DDSD_LINEARSIZE      = $00080000;\n  DDSD_DEPTH           = $00800000;\n\n  { Constans used by TDDSPixelFormat.Flags.}\n  DDPF_ALPHAPIXELS     = $00000001;    // used by formats which contain alpha\n  DDPF_FOURCC          = $00000004;    // used by DXT and large ARGB formats\n  DDPF_RGB             = $00000040;    // used by RGB formats\n  DDPF_LUMINANCE       = $00020000;    // used by formats like D3DFMT_L16\n  DDPF_BUMPLUMINANCE   = $00040000;    // used by mixed signed-unsigned formats\n  DDPF_BUMPDUDV        = $00080000;    // used by signed formats\n\n  { Constans used by TDDSCaps.Caps1.}\n  DDSCAPS_COMPLEX      = $00000008;\n  DDSCAPS_TEXTURE      = $00001000;\n  DDSCAPS_MIPMAP       = $00400000;\n\n  { Constans used by TDDSCaps.Caps2.}\n  DDSCAPS2_CUBEMAP     = $00000200;\n  DDSCAPS2_POSITIVEX   = $00000400;\n  DDSCAPS2_NEGATIVEX   = $00000800;\n  DDSCAPS2_POSITIVEY   = $00001000;\n  DDSCAPS2_NEGATIVEY   = $00002000;\n  DDSCAPS2_POSITIVEZ   = $00004000;\n  DDSCAPS2_NEGATIVEZ   = $00008000;\n  DDSCAPS2_VOLUME      = $00200000;\n\n  { Flags for TDDSurfaceDesc2.Flags used when saving DDS file.}\n  DDS_SAVE_FLAGS = DDSD_CAPS or DDSD_PIXELFORMAT or DDSD_WIDTH or\n    DDSD_HEIGHT or DDSD_LINEARSIZE;\n\ntype\n  { Stores the pixel format information.}\n  TDDPixelFormat = packed record\n    Size: LongWord;       // Size of the structure = 32 bytes\n    Flags: LongWord;      // Flags to indicate valid fields\n    FourCC: LongWord;     // Four-char code for compressed textures (DXT)\n    BitCount: LongWord;   // Bits per pixel if uncomp. usually 16,24 or 32\n    RedMask: LongWord;    // Bit mask for the Red component\n    GreenMask: LongWord;  // Bit mask for the Green component\n    BlueMask: LongWord;   // Bit mask for the Blue component\n    AlphaMask: LongWord;  // Bit mask for the Alpha component\n  end;\n\n  { Specifies capabilities of surface.}\n  TDDSCaps = packed record\n    Caps1: LongWord;      // Should always include DDSCAPS_TEXTURE\n    Caps2: LongWord;      // For cubic environment maps\n    Reserved: array[0..1] of LongWord; // Reserved\n  end;\n\n  { Record describing DDS file contents.}\n  TDDSurfaceDesc2 = packed record\n    Size: LongWord;       // Size of the structure = 124 Bytes\n    Flags: LongWord;      // Flags to indicate valid fields\n    Height: LongWord;     // Height of the main image in pixels\n    Width: LongWord;      // Width of the main image in pixels\n    PitchOrLinearSize: LongWord; // For uncomp formats number of bytes per\n                          // scanline. For comp it is the size in\n                          // bytes of the main image\n    Depth: LongWord;      // Only for volume text depth of the volume\n    MipMaps: LongInt;     // Total number of levels in the mipmap chain\n    Reserved1: array[0..10] of LongWord; // Reserved\n    PixelFormat: TDDPixelFormat; // Format of the pixel data\n    Caps: TDDSCaps;       // Capabilities\n    Reserved2: LongWord;  // Reserved\n  end;\n\n  { DDS file header.}\n  TDDSFileHeader = packed record\n    Magic: LongWord;       // File format magic\n    Desc: TDDSurfaceDesc2; // Surface description\n  end;\n\n  { Resoirce types for D3D 10+ }\n  TD3D10ResourceDimension = (\n    D3D10_RESOURCE_DIMENSION_UNKNOWN   = 0,\n    D3D10_RESOURCE_DIMENSION_BUFFER    = 1,\n    D3D10_RESOURCE_DIMENSION_TEXTURE1D = 2,\n    D3D10_RESOURCE_DIMENSION_TEXTURE2D = 3,\n    D3D10_RESOURCE_DIMENSION_TEXTURE3D = 4\n  );\n\n  { Texture formats for D3D 10+ }\n  TDXGIFormat = (\n    DXGI_FORMAT_UNKNOWN                      = 0,\n    DXGI_FORMAT_R32G32B32A32_TYPELESS        = 1,\n    DXGI_FORMAT_R32G32B32A32_FLOAT           = 2,\n    DXGI_FORMAT_R32G32B32A32_UINT            = 3,\n    DXGI_FORMAT_R32G32B32A32_SINT            = 4,\n    DXGI_FORMAT_R32G32B32_TYPELESS           = 5,\n    DXGI_FORMAT_R32G32B32_FLOAT              = 6,\n    DXGI_FORMAT_R32G32B32_UINT               = 7,\n    DXGI_FORMAT_R32G32B32_SINT               = 8,\n    DXGI_FORMAT_R16G16B16A16_TYPELESS        = 9,\n    DXGI_FORMAT_R16G16B16A16_FLOAT           = 10,\n    DXGI_FORMAT_R16G16B16A16_UNORM           = 11,\n    DXGI_FORMAT_R16G16B16A16_UINT            = 12,\n    DXGI_FORMAT_R16G16B16A16_SNORM           = 13,\n    DXGI_FORMAT_R16G16B16A16_SINT            = 14,\n    DXGI_FORMAT_R32G32_TYPELESS              = 15,\n    DXGI_FORMAT_R32G32_FLOAT                 = 16,\n    DXGI_FORMAT_R32G32_UINT                  = 17,\n    DXGI_FORMAT_R32G32_SINT                  = 18,\n    DXGI_FORMAT_R32G8X24_TYPELESS            = 19,\n    DXGI_FORMAT_D32_FLOAT_S8X24_UINT         = 20,\n    DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS     = 21,\n    DXGI_FORMAT_X32_TYPELESS_G8X24_UINT      = 22,\n    DXGI_FORMAT_R10G10B10A2_TYPELESS         = 23,\n    DXGI_FORMAT_R10G10B10A2_UNORM            = 24,\n    DXGI_FORMAT_R10G10B10A2_UINT             = 25,\n    DXGI_FORMAT_R11G11B10_FLOAT              = 26,\n    DXGI_FORMAT_R8G8B8A8_TYPELESS            = 27,\n    DXGI_FORMAT_R8G8B8A8_UNORM               = 28,\n    DXGI_FORMAT_R8G8B8A8_UNORM_SRGB          = 29,\n    DXGI_FORMAT_R8G8B8A8_UINT                = 30,\n    DXGI_FORMAT_R8G8B8A8_SNORM               = 31,\n    DXGI_FORMAT_R8G8B8A8_SINT                = 32,\n    DXGI_FORMAT_R16G16_TYPELESS              = 33,\n    DXGI_FORMAT_R16G16_FLOAT                 = 34,\n    DXGI_FORMAT_R16G16_UNORM                 = 35,\n    DXGI_FORMAT_R16G16_UINT                  = 36,\n    DXGI_FORMAT_R16G16_SNORM                 = 37,\n    DXGI_FORMAT_R16G16_SINT                  = 38,\n    DXGI_FORMAT_R32_TYPELESS                 = 39,\n    DXGI_FORMAT_D32_FLOAT                    = 40,\n    DXGI_FORMAT_R32_FLOAT                    = 41,\n    DXGI_FORMAT_R32_UINT                     = 42,\n    DXGI_FORMAT_R32_SINT                     = 43,\n    DXGI_FORMAT_R24G8_TYPELESS               = 44,\n    DXGI_FORMAT_D24_UNORM_S8_UINT            = 45,\n    DXGI_FORMAT_R24_UNORM_X8_TYPELESS        = 46,\n    DXGI_FORMAT_X24_TYPELESS_G8_UINT         = 47,\n    DXGI_FORMAT_R8G8_TYPELESS                = 48,\n    DXGI_FORMAT_R8G8_UNORM                   = 49,\n    DXGI_FORMAT_R8G8_UINT                    = 50,\n    DXGI_FORMAT_R8G8_SNORM                   = 51,\n    DXGI_FORMAT_R8G8_SINT                    = 52,\n    DXGI_FORMAT_R16_TYPELESS                 = 53,\n    DXGI_FORMAT_R16_FLOAT                    = 54,\n    DXGI_FORMAT_D16_UNORM                    = 55,\n    DXGI_FORMAT_R16_UNORM                    = 56,\n    DXGI_FORMAT_R16_UINT                     = 57,\n    DXGI_FORMAT_R16_SNORM                    = 58,\n    DXGI_FORMAT_R16_SINT                     = 59,\n    DXGI_FORMAT_R8_TYPELESS                  = 60,\n    DXGI_FORMAT_R8_UNORM                     = 61,\n    DXGI_FORMAT_R8_UINT                      = 62,\n    DXGI_FORMAT_R8_SNORM                     = 63,\n    DXGI_FORMAT_R8_SINT                      = 64,\n    DXGI_FORMAT_A8_UNORM                     = 65,\n    DXGI_FORMAT_R1_UNORM                     = 66,\n    DXGI_FORMAT_R9G9B9E5_SHAREDEXP           = 67,\n    DXGI_FORMAT_R8G8_B8G8_UNORM              = 68,\n    DXGI_FORMAT_G8R8_G8B8_UNORM              = 69,\n    DXGI_FORMAT_BC1_TYPELESS                 = 70,\n    DXGI_FORMAT_BC1_UNORM                    = 71,\n    DXGI_FORMAT_BC1_UNORM_SRGB               = 72,\n    DXGI_FORMAT_BC2_TYPELESS                 = 73,\n    DXGI_FORMAT_BC2_UNORM                    = 74,\n    DXGI_FORMAT_BC2_UNORM_SRGB               = 75,\n    DXGI_FORMAT_BC3_TYPELESS                 = 76,\n    DXGI_FORMAT_BC3_UNORM                    = 77,\n    DXGI_FORMAT_BC3_UNORM_SRGB               = 78,\n    DXGI_FORMAT_BC4_TYPELESS                 = 79,\n    DXGI_FORMAT_BC4_UNORM                    = 80,\n    DXGI_FORMAT_BC4_SNORM                    = 81,\n    DXGI_FORMAT_BC5_TYPELESS                 = 82,\n    DXGI_FORMAT_BC5_UNORM                    = 83,\n    DXGI_FORMAT_BC5_SNORM                    = 84,\n    DXGI_FORMAT_B5G6R5_UNORM                 = 85,\n    DXGI_FORMAT_B5G5R5A1_UNORM               = 86,\n    DXGI_FORMAT_B8G8R8A8_UNORM               = 87,\n    DXGI_FORMAT_B8G8R8X8_UNORM               = 88,\n    DXGI_FORMAT_R10G10B10_XR_BIAS_A2_UNORM   = 89,\n    DXGI_FORMAT_B8G8R8A8_TYPELESS            = 90,\n    DXGI_FORMAT_B8G8R8A8_UNORM_SRGB          = 91,\n    DXGI_FORMAT_B8G8R8X8_TYPELESS            = 92,\n    DXGI_FORMAT_B8G8R8X8_UNORM_SRGB          = 93,\n    DXGI_FORMAT_BC6H_TYPELESS                = 94,\n    DXGI_FORMAT_BC6H_UF16                    = 95,\n    DXGI_FORMAT_BC6H_SF16                    = 96,\n    DXGI_FORMAT_BC7_TYPELESS                 = 97,\n    DXGI_FORMAT_BC7_UNORM                    = 98,\n    DXGI_FORMAT_BC7_UNORM_SRGB               = 99,\n    DXGI_FORMAT_AYUV                         = 100,\n    DXGI_FORMAT_Y410                         = 101,\n    DXGI_FORMAT_Y416                         = 102,\n    DXGI_FORMAT_NV12                         = 103,\n    DXGI_FORMAT_P010                         = 104,\n    DXGI_FORMAT_P016                         = 105,\n    DXGI_FORMAT_420_OPAQUE                   = 106,\n    DXGI_FORMAT_YUY2                         = 107,\n    DXGI_FORMAT_Y210                         = 108,\n    DXGI_FORMAT_Y216                         = 109,\n    DXGI_FORMAT_NV11                         = 110,\n    DXGI_FORMAT_AI44                         = 111,\n    DXGI_FORMAT_IA44                         = 112,\n    DXGI_FORMAT_P8                           = 113,\n    DXGI_FORMAT_A8P8                         = 114,\n    DXGI_FORMAT_B4G4R4A4_UNORM               = 115\n  );\n\n  { DX10 extension header for DDS file format }\n  TDX10Header = packed record\n    DXGIFormat: TDXGIFormat;\n    ResourceDimension: TD3D10ResourceDimension;\n    MiscFlags: LongWord;\n    ArraySize: LongWord;\n    Reserved: LongWord;\n  end;\n\nimplementation\n\n{ TDDSFileFormat class implementation }\n\nprocedure TDDSFileFormat.Define;\nbegin\n  inherited;\n  FName := SDDSFormatName;\n  FFeatures := [ffLoad, ffSave, ffMultiImage];\n  FSupportedFormats := DDSSupportedFormats;\n\n  FSaveCubeMap := False;\n  FSaveVolume := False;\n  FSaveMipMapCount := 1;\n  FSaveDepth := 1;\n\n  AddMasks(SDDSMasks);\n\n  RegisterOption(ImagingDDSLoadedCubeMap, @FLoadedCubeMap);\n  RegisterOption(ImagingDDSLoadedVolume, @FLoadedVolume);\n  RegisterOption(ImagingDDSLoadedMipMapCount, @FLoadedMipMapCount);\n  RegisterOption(ImagingDDSLoadedDepth, @FLoadedDepth);\n  RegisterOption(ImagingDDSSaveCubeMap, @FSaveCubeMap);\n  RegisterOption(ImagingDDSSaveVolume, @FSaveVolume);\n  RegisterOption(ImagingDDSSaveMipMapCount, @FSaveMipMapCount);\n  RegisterOption(ImagingDDSSaveDepth, @FSaveDepth);\nend;\n\nprocedure TDDSFileFormat.CheckOptionsValidity;\nbegin\n  if FSaveCubeMap then\n    FSaveVolume := False;\n  if FSaveVolume then\n    FSaveCubeMap := False;\n  if FSaveDepth < 1 then\n    FSaveDepth := 1;\n  if FSaveMipMapCount < 1 then\n    FSaveMipMapCount := 1;\nend;\n\nprocedure TDDSFileFormat.ComputeSubDimensions(Idx, Width, Height, MipMaps, Depth: LongInt;\n  IsCubeMap, IsVolume: Boolean; var CurWidth, CurHeight: LongInt);\nvar\n  I, Last, Shift: LongInt;\nbegin\n  CurWidth := Width;\n  CurHeight := Height;\n  if MipMaps > 1 then\n  begin\n    if not IsVolume then\n    begin\n      if IsCubeMap then\n      begin\n        // Cube maps are stored like this\n        // Face 0 mimap 0\n        // Face 0 mipmap 1\n        // ...\n        // Face 1 mipmap 0\n        // Face 1 mipmap 1\n        // ...\n\n        // Modify index so later in for loop we iterate less times\n        Idx := Idx - ((Idx div MipMaps) * MipMaps);\n      end;\n      for I := 0 to Idx - 1 do\n      begin\n        CurWidth := ClampInt(CurWidth shr 1, 1, CurWidth);\n        CurHeight := ClampInt(CurHeight shr 1, 1, CurHeight);\n      end;\n    end\n    else\n    begin\n      // Volume textures are stored in DDS files like this:\n      // Slice 0 mipmap 0\n      // Slice 1 mipmap 0\n      // Slice 2 mipmap 0\n      // Slice 3 mipmap 0\n      // Slice 0 mipmap 1\n      // Slice 1 mipmap 1\n      // Slice 0 mipmap 2\n      // Slice 0 mipmap 3 ...\n      Shift := 0;\n      Last := Depth;\n      while Idx > Last - 1 do\n      begin\n        CurWidth := ClampInt(CurWidth shr 1, 1, CurWidth);\n        CurHeight := ClampInt(CurHeight shr 1, 1, CurHeight);\n        if (CurWidth = 1) and (CurHeight = 1) then\n          Break;\n        Inc(Shift);\n        Inc(Last, ClampInt(Depth shr Shift, 1, Depth));\n      end;\n    end;\n  end;\nend;\n\nfunction TDDSFileFormat.LoadData(Handle: TImagingHandle;\n  var Images: TDynImageDataArray; OnlyFirstLevel: Boolean): Boolean;\nvar\n  Hdr: TDDSFileHeader;\n  HdrDX10: TDX10Header;\n  SrcFormat: TImageFormat;\n  FmtInfo: TImageFormatInfo;\n  NeedsSwapChannels: Boolean;\n  CurrentWidth, CurrentHeight, ImageCount, LoadSize, I,\n    PitchOrLinear, MainImageLinearSize: Integer;\n  Data: PByte;\n  UseAsPitch: Boolean;\n  UseAsLinear: Boolean;\n\n  function MasksEqual(const DDPF: TDDPixelFormat; PF: PPixelFormatInfo): Boolean;\n  begin\n    Result := (DDPF.AlphaMask = PF.ABitMask) and\n      (DDPF.RedMask = PF.RBitMask) and (DDPF.GreenMask = PF.GBitMask) and\n      (DDPF.BlueMask = PF.BBitMask);\n  end;\n\n  function FindFourCCFormat(FourCC: LongWord): TImageFormat;\n  begin\n    // Handle FourCC and large ARGB formats\n    case FourCC of\n      D3DFMT_A16B16G16R16: Result := ifA16B16G16R16;\n      D3DFMT_R32F: Result := ifR32F;\n      D3DFMT_A32B32G32R32F: Result := ifA32B32G32R32F;\n      D3DFMT_R16F: Result := ifR16F;\n      D3DFMT_A16B16G16R16F: Result := ifA16B16G16R16F;\n      FOURCC_DXT1: Result := ifDXT1;\n      FOURCC_DXT3: Result := ifDXT3;\n      FOURCC_DXT5: Result := ifDXT5;\n      FOURCC_ATI1: Result := ifATI1N;\n      FOURCC_ATI2: Result := ifATI2N;\n    else\n      Result := ifUnknown;\n    end;\n  end;\n\n  function FindDX10Format(DXGIFormat: TDXGIFormat; var NeedsSwapChannels: Boolean): TImageFormat;\n  begin\n    Result := ifUnknown;\n    NeedsSwapChannels := False;\n\n    case DXGIFormat of\n      DXGI_FORMAT_UNKNOWN: ;\n      DXGI_FORMAT_R32G32B32A32_TYPELESS, DXGI_FORMAT_R32G32B32A32_FLOAT:\n        Result := ifA32B32G32R32F;\n      DXGI_FORMAT_R32G32B32A32_UINT: ;\n      DXGI_FORMAT_R32G32B32A32_SINT: ;\n      DXGI_FORMAT_R32G32B32_TYPELESS, DXGI_FORMAT_R32G32B32_FLOAT:\n        Result := ifB32G32R32F;\n      DXGI_FORMAT_R32G32B32_UINT: ;\n      DXGI_FORMAT_R32G32B32_SINT: ;\n      DXGI_FORMAT_R16G16B16A16_FLOAT:\n        Result := ifA16B16G16R16F;\n      DXGI_FORMAT_R16G16B16A16_TYPELESS, DXGI_FORMAT_R16G16B16A16_UNORM,\n      DXGI_FORMAT_R16G16B16A16_UINT, DXGI_FORMAT_R16G16B16A16_SNORM,\n      DXGI_FORMAT_R16G16B16A16_SINT:\n        Result := ifA16B16G16R16;\n      DXGI_FORMAT_R32G32_TYPELESS: ;\n      DXGI_FORMAT_R32G32_FLOAT: ;\n      DXGI_FORMAT_R32G32_UINT: ;\n      DXGI_FORMAT_R32G32_SINT: ;\n      DXGI_FORMAT_R32G8X24_TYPELESS: ;\n      DXGI_FORMAT_D32_FLOAT_S8X24_UINT: ;\n      DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS: ;\n      DXGI_FORMAT_X32_TYPELESS_G8X24_UINT: ;\n      DXGI_FORMAT_R10G10B10A2_TYPELESS: ;\n      DXGI_FORMAT_R10G10B10A2_UNORM: ;\n      DXGI_FORMAT_R10G10B10A2_UINT: ;\n      DXGI_FORMAT_R11G11B10_FLOAT: ;\n      DXGI_FORMAT_R8G8B8A8_TYPELESS, DXGI_FORMAT_R8G8B8A8_UNORM,\n      DXGI_FORMAT_R8G8B8A8_UINT, DXGI_FORMAT_R8G8B8A8_SNORM,DXGI_FORMAT_R8G8B8A8_SINT,\n      DXGI_FORMAT_R8G8B8A8_UNORM_SRGB:\n        begin\n          Result := ifA8R8G8B8;\n          NeedsSwapChannels := True;\n        end;\n      DXGI_FORMAT_R16G16_TYPELESS: ;\n      DXGI_FORMAT_R16G16_FLOAT: ;\n      DXGI_FORMAT_R16G16_UNORM: ;\n      DXGI_FORMAT_R16G16_UINT: ;\n      DXGI_FORMAT_R16G16_SNORM: ;\n      DXGI_FORMAT_R16G16_SINT: ;\n      DXGI_FORMAT_R32_TYPELESS, DXGI_FORMAT_R32_UINT, DXGI_FORMAT_R32_SINT:\n        Result := ifGray32;\n      DXGI_FORMAT_D32_FLOAT, DXGI_FORMAT_R32_FLOAT:\n        Result := ifR32F;\n      DXGI_FORMAT_R24G8_TYPELESS: ;\n      DXGI_FORMAT_D24_UNORM_S8_UINT: ;\n      DXGI_FORMAT_R24_UNORM_X8_TYPELESS: ;\n      DXGI_FORMAT_X24_TYPELESS_G8_UINT: ;\n      DXGI_FORMAT_R8G8_TYPELESS, DXGI_FORMAT_R8G8_UNORM, DXGI_FORMAT_R8G8_UINT,\n      DXGI_FORMAT_R8G8_SNORM, DXGI_FORMAT_R8G8_SINT:\n        Result := ifA8Gray8;\n      DXGI_FORMAT_R16_TYPELESS, DXGI_FORMAT_D16_UNORM, DXGI_FORMAT_R16_UNORM,\n      DXGI_FORMAT_R16_UINT, DXGI_FORMAT_R16_SNORM, DXGI_FORMAT_R16_SINT:\n        Result := ifGray16;\n      DXGI_FORMAT_R16_FLOAT:\n        Result := ifR16F;\n      DXGI_FORMAT_R8_TYPELESS, DXGI_FORMAT_R8_UNORM, DXGI_FORMAT_R8_UINT,\n      DXGI_FORMAT_R8_SNORM, DXGI_FORMAT_R8_SINT, DXGI_FORMAT_A8_UNORM:\n        Result := ifGray8;\n      DXGI_FORMAT_R1_UNORM: ;\n      DXGI_FORMAT_R9G9B9E5_SHAREDEXP: ;\n      DXGI_FORMAT_R8G8_B8G8_UNORM: ;\n      DXGI_FORMAT_G8R8_G8B8_UNORM: ;\n      DXGI_FORMAT_BC1_TYPELESS, DXGI_FORMAT_BC1_UNORM, DXGI_FORMAT_BC1_UNORM_SRGB:\n        Result := ifDXT1;\n      DXGI_FORMAT_BC2_TYPELESS, DXGI_FORMAT_BC2_UNORM, DXGI_FORMAT_BC2_UNORM_SRGB:\n        Result := ifDXT3;\n      DXGI_FORMAT_BC3_TYPELESS, DXGI_FORMAT_BC3_UNORM, DXGI_FORMAT_BC3_UNORM_SRGB:\n        Result := ifDXT5;\n      DXGI_FORMAT_BC4_TYPELESS, DXGI_FORMAT_BC4_UNORM, DXGI_FORMAT_BC4_SNORM:\n        Result := ifATI1N;\n      DXGI_FORMAT_BC5_TYPELESS, DXGI_FORMAT_BC5_UNORM, DXGI_FORMAT_BC5_SNORM:\n        Result := ifATI2N;\n      DXGI_FORMAT_B5G6R5_UNORM:\n        Result := ifR5G6B5;\n      DXGI_FORMAT_B5G5R5A1_UNORM:\n        Result := ifA1R5G5B5;\n      DXGI_FORMAT_B8G8R8A8_UNORM, DXGI_FORMAT_B8G8R8A8_TYPELESS:\n        Result := ifA8R8G8B8;\n      DXGI_FORMAT_B8G8R8X8_UNORM, DXGI_FORMAT_B8G8R8X8_TYPELESS:\n        Result := ifX8R8G8B8;\n      DXGI_FORMAT_R10G10B10_XR_BIAS_A2_UNORM: ;\n      DXGI_FORMAT_B8G8R8A8_UNORM_SRGB: ;\n      DXGI_FORMAT_B8G8R8X8_UNORM_SRGB: ;\n      DXGI_FORMAT_BC6H_TYPELESS: ;\n      DXGI_FORMAT_BC6H_UF16: ;\n      DXGI_FORMAT_BC6H_SF16: ;\n      DXGI_FORMAT_BC7_TYPELESS: ;\n      DXGI_FORMAT_BC7_UNORM: ;\n      DXGI_FORMAT_BC7_UNORM_SRGB: ;\n      DXGI_FORMAT_P8: ;\n      DXGI_FORMAT_A8P8: ;\n      DXGI_FORMAT_B4G4R4A4_UNORM:\n        Result := ifA4R4G4B4;\n    end;\n  end;\n\nbegin\n  Result := False;\n  ImageCount := 1;\n  FLoadedMipMapCount := 1;\n  FLoadedDepth := 1;\n  FLoadedVolume := False;\n  FLoadedCubeMap := False;\n  ZeroMemory(@HdrDX10, SizeOf(HdrDX10));\n\n  with GetIO, Hdr, Hdr.Desc.PixelFormat do\n  begin\n    Read(Handle, @Hdr, SizeOf(Hdr));\n\n    SrcFormat := ifUnknown;\n    NeedsSwapChannels := False;\n\n    // Get image data format\n    if (Flags and DDPF_FOURCC) = DDPF_FOURCC then\n    begin\n      if FourCC = FOURCC_DX10 then\n      begin\n        Read(Handle, @HdrDX10, SizeOf(HdrDX10));\n        SrcFormat := FindDX10Format(HdrDX10.DXGIFormat, NeedsSwapChannels);\n        FMetadata.SetMetaItem(SMetaDdsDxgiFormat, HdrDX10.DXGIFormat);\n        FMetadata.SetMetaItem(SMetaDdsArraySize, HdrDX10.ArraySize);\n      end\n      else\n        SrcFormat := FindFourCCFormat(FourCC);\n    end\n    else if (Flags and DDPF_RGB) = DDPF_RGB then\n    begin\n      // Handle RGB formats\n      if (Flags and DDPF_ALPHAPIXELS) = DDPF_ALPHAPIXELS then\n      begin\n        // Handle RGB with alpha formats\n        case BitCount of\n          16:\n            begin\n              if MasksEqual(Desc.PixelFormat, GetFormatInfo(ifA4R4G4B4).PixelFormat) then\n                SrcFormat := ifA4R4G4B4;\n              if MasksEqual(Desc.PixelFormat, GetFormatInfo(ifA1R5G5B5).PixelFormat) then\n                SrcFormat := ifA1R5G5B5;\n            end;\n          32:\n            begin\n              SrcFormat := ifA8R8G8B8;\n              if BlueMask = $00FF0000 then\n                NeedsSwapChannels := True;\n            end;\n        end;\n      end\n      else\n      begin\n        // Handle RGB without alpha formats\n        case BitCount of\n          8:\n            if MasksEqual(Desc.PixelFormat,\n              GetFormatInfo(ifR3G3B2).PixelFormat) then\n              SrcFormat := ifR3G3B2;\n          16:\n            begin\n              if MasksEqual(Desc.PixelFormat,\n                GetFormatInfo(ifX4R4G4B4).PixelFormat) then\n                SrcFormat := ifX4R4G4B4;\n              if MasksEqual(Desc.PixelFormat,\n                GetFormatInfo(ifX1R5G5B5).PixelFormat) then\n                SrcFormat := ifX1R5G5B5;\n              if MasksEqual(Desc.PixelFormat,\n                GetFormatInfo(ifR5G6B5).PixelFormat) then\n                SrcFormat := ifR5G6B5;\n            end;\n          24: SrcFormat := ifR8G8B8;\n          32:\n            begin\n              SrcFormat := ifX8R8G8B8;\n              if BlueMask = $00FF0000 then\n                NeedsSwapChannels := True;\n            end;\n        end;\n      end;\n    end\n    else if (Flags and DDPF_LUMINANCE) = DDPF_LUMINANCE then\n    begin\n      // Handle luminance formats\n      if (Flags and DDPF_ALPHAPIXELS) = DDPF_ALPHAPIXELS then\n      begin\n        // Handle luminance with alpha formats\n        if BitCount = 16 then\n          SrcFormat := ifA8Gray8;\n      end\n      else\n      begin\n        // Handle luminance without alpha formats\n        case BitCount of\n          8: SrcFormat := ifGray8;\n          16: SrcFormat := ifGray16;\n        end;\n      end;\n    end\n    else if (Flags and DDPF_BUMPLUMINANCE) = DDPF_BUMPLUMINANCE then\n    begin\n      // Handle mixed bump-luminance formats like D3DFMT_X8L8V8U8\n      case BitCount of\n        32:\n          if BlueMask = $00FF0000 then\n          begin\n            SrcFormat := ifX8R8G8B8; // D3DFMT_X8L8V8U8\n            NeedsSwapChannels := True;\n          end;\n      end;\n    end\n    else if (Flags and DDPF_BUMPDUDV) = DDPF_BUMPDUDV then\n    begin\n      // Handle bumpmap formats like D3DFMT_Q8W8V8U8\n      case BitCount of\n        16: SrcFormat := ifA8Gray8; // D3DFMT_V8U8\n        32:\n          if AlphaMask = $FF000000 then\n          begin\n            SrcFormat := ifA8R8G8B8; // D3DFMT_Q8W8V8U8\n            NeedsSwapChannels := True;\n          end;\n        64: SrcFormat := ifA16B16G16R16; // D3DFMT_Q16W16V16U16\n      end;\n    end;\n\n    // If DDS format is not supported we will exit\n    if SrcFormat = ifUnknown then\n      Exit;\n\n    // File contains mipmaps for each subimage.\n    { Some DDS writers ignore setting proper Caps and Flags so\n      this check is not usable:\n    if ((Desc.Caps.Caps1 and DDSCAPS_MIPMAP) = DDSCAPS_MIPMAP) and\n      ((Desc.Flags and DDSD_MIPMAPCOUNT) = DDSD_MIPMAPCOUNT) then}\n    if Desc.MipMaps > 1 then\n    begin\n      FLoadedMipMapCount := Desc.MipMaps;\n      FMetadata.SetMetaItem(SMetaDdsMipMapCount, Desc.MipMaps);\n      ImageCount := Desc.MipMaps;\n    end;\n\n    // File stores volume texture\n    if ((Desc.Caps.Caps2 and DDSCAPS2_VOLUME) = DDSCAPS2_VOLUME) and\n      ((Desc.Flags and DDSD_DEPTH) = DDSD_DEPTH) then\n    begin\n      FLoadedVolume := True;\n      FLoadedDepth := Desc.Depth;\n      ImageCount := GetVolumeLevelCount(Desc.Depth, ImageCount);\n    end;\n\n    // File stores cube texture\n    if (Desc.Caps.Caps2 and DDSCAPS2_CUBEMAP) = DDSCAPS2_CUBEMAP then\n    begin\n      FLoadedCubeMap := True;\n      I := 0;\n      if (Desc.Caps.Caps2 and DDSCAPS2_POSITIVEX) = DDSCAPS2_POSITIVEX then Inc(I);\n      if (Desc.Caps.Caps2 and DDSCAPS2_POSITIVEY) = DDSCAPS2_POSITIVEY then Inc(I);\n      if (Desc.Caps.Caps2 and DDSCAPS2_POSITIVEZ) = DDSCAPS2_POSITIVEZ then Inc(I);\n      if (Desc.Caps.Caps2 and DDSCAPS2_NEGATIVEX) = DDSCAPS2_NEGATIVEX then Inc(I);\n      if (Desc.Caps.Caps2 and DDSCAPS2_NEGATIVEY) = DDSCAPS2_NEGATIVEY then Inc(I);\n      if (Desc.Caps.Caps2 and DDSCAPS2_NEGATIVEZ) = DDSCAPS2_NEGATIVEZ then Inc(I);\n      FLoadedDepth := I;\n      ImageCount := ImageCount * I;\n    end;\n\n    // Allocate and load all images in file\n    FmtInfo := GetFormatInfo(SrcFormat);\n    SetLength(Images, ImageCount);\n\n    // Compute the pitch or get if from file if present\n    UseAsPitch := (Desc.Flags and DDSD_PITCH) = DDSD_PITCH;\n    UseAsLinear := (Desc.Flags and DDSD_LINEARSIZE) = DDSD_LINEARSIZE;\n    // Use linear as default if none is set\n    if not UseAsPitch and not UseAsLinear then\n      UseAsLinear := True;\n    // Main image pitch or linear size\n    PitchOrLinear := Desc.PitchOrLinearSize;\n\n    // Check: some writers just write garbage to pitch/linear size fields and flags\n    MainImageLinearSize := FmtInfo.GetPixelsSize(SrcFormat, Desc.Width, Desc.Height);\n    if UseAsLinear and ((PitchOrLinear < MainImageLinearSize) or\n      (PitchOrLinear * Integer(Desc.Height) = MainImageLinearSize)) then\n    begin\n      // Explicitly set linear size\n      PitchOrLinear := MainImageLinearSize;\n    end;\n\n    for I := 0 to ImageCount - 1 do\n    begin\n      // Compute dimensions of surrent subimage based on texture type and\n      // number of mipmaps\n      ComputeSubDimensions(I, Desc.Width, Desc.Height, Desc.MipMaps, Desc.Depth,\n        FLoadedCubeMap, FLoadedVolume, CurrentWidth, CurrentHeight);\n      NewImage(CurrentWidth, CurrentHeight, SrcFormat, Images[I]);\n\n      if (I > 0) or (PitchOrLinear = 0) then\n      begin\n        // Compute pitch or linear size for mipmap levels, or even for main image\n        // since some formats do not fill pitch nor size\n        if UseAsLinear then\n          PitchOrLinear := FmtInfo.GetPixelsSize(SrcFormat, CurrentWidth, CurrentHeight)\n        else\n          PitchOrLinear := (CurrentWidth * FmtInfo.BytesPerPixel + 3) div 4 * 4; // must be DWORD aligned\n      end;\n\n      if UseAsLinear then\n        LoadSize := PitchOrLinear\n      else\n        LoadSize := CurrentHeight * PitchOrLinear;\n\n      if UseAsLinear or (LoadSize = Images[I].Size) then\n      begin\n        // If DDS does not use Pitch we can simply copy data\n        Read(Handle, Images[I].Bits, LoadSize)\n      end\n      else\n      begin\n        // If DDS uses Pitch we must load aligned scanlines\n        // and then remove padding\n        GetMem(Data, LoadSize);\n        try\n          Read(Handle, Data, LoadSize);\n          RemovePadBytes(Data, Images[I].Bits, CurrentWidth, CurrentHeight,\n            FmtInfo.BytesPerPixel, PitchOrLinear);\n       finally\n          FreeMem(Data);\n        end;\n      end;\n\n      if NeedsSwapChannels then\n        SwapChannels(Images[I], ChannelRed, ChannelBlue);\n    end;\n    Result := True;\n  end;\nend;\n\nfunction TDDSFileFormat.SaveData(Handle: TImagingHandle;\n  const Images: TDynImageDataArray; Index: LongInt): Boolean;\nvar\n  Hdr: TDDSFileHeader;\n  MainImage, ImageToSave: TImageData;\n  I, MainIdx, Len, ImageCount: LongInt;\n  J: LongWord;\n  FmtInfo: TImageFormatInfo;\n  MustBeFreed: Boolean;\n  Is2DTexture, IsCubeMap, IsVolume: Boolean;\n  MipMapCount, CurrentWidth, CurrentHeight: LongInt;\n  NeedsResize: Boolean;\n  NeedsConvert: Boolean;\nbegin\n  Result := False;\n  FillChar(Hdr, Sizeof(Hdr), 0);\n\n  MainIdx := FFirstIdx;\n  Len := FLastIdx - MainIdx + 1;\n  // Some DDS saving rules:\n  //   2D textures: Len is used as mipmap count (FSaveMipMapCount not used!).\n  //   Cube maps:   FSaveDepth * FSaveMipMapCount images are used, if Len is\n  //                smaller than this file is saved as regular 2D texture.\n  //   Volume maps: GetVolumeLevelCount(FSaveDepth, FSaveMipMapCount) images are\n  //                used, if Len is smaller than this file is\n  //                saved as regular 2D texture.\n\n  IsCubeMap := FSaveCubeMap;\n  IsVolume := FSaveVolume;\n  MipMapCount := FSaveMipMapCount;\n\n  if IsCubeMap then\n  begin\n    // Check if we have enough images on Input to save cube map\n    if Len < FSaveDepth * FSaveMipMapCount then\n      IsCubeMap := False;\n  end\n  else if IsVolume then\n  begin\n    // Check if we have enough images on Input to save volume texture\n    if Len < GetVolumeLevelCount(FSaveDepth, FSaveMipMapCount) then\n      IsVolume := False;\n  end;\n\n  Is2DTexture := not IsCubeMap and not IsVolume;\n  if Is2DTexture then\n  begin\n    // Get number of mipmaps used with 2D texture\n    MipMapCount := Min(Len, GetNumMipMapLevels(Images[MainIdx].Width, Images[MainIdx].Height));\n  end;\n\n  // we create compatible main image and fill headers\n  if MakeCompatible(Images[MainIdx], MainImage, MustBeFreed) then\n  with GetIO, MainImage, Hdr do\n  try\n    FmtInfo := GetFormatInfo(Format);\n    Magic := DDSMagic;\n    Desc.Size := SizeOf(Desc);\n    Desc.Width := Width;\n    Desc.Height := Height;\n    Desc.Flags := DDS_SAVE_FLAGS;\n    Desc.Caps.Caps1 := DDSCAPS_TEXTURE;\n    Desc.PixelFormat.Size := SizeOf(Desc.PixelFormat);\n    Desc.PitchOrLinearSize := MainImage.Size;\n    ImageCount := MipMapCount;\n\n    if MipMapCount > 1 then\n    begin\n      // Set proper flags if we have some mipmaps to be saved\n      Desc.Flags := Desc.Flags or DDSD_MIPMAPCOUNT;\n      Desc.Caps.Caps1 := Desc.Caps.Caps1 or DDSCAPS_MIPMAP or DDSCAPS_COMPLEX;\n      Desc.MipMaps := MipMapCount;\n    end;\n\n    if IsCubeMap then\n    begin\n      // Set proper cube map flags - number of stored faces is taken\n      // from FSaveDepth\n      Desc.Caps.Caps1 := Desc.Caps.Caps1 or DDSCAPS_COMPLEX;\n      Desc.Caps.Caps2 := Desc.Caps.Caps2 or DDSCAPS2_CUBEMAP;\n      J := DDSCAPS2_POSITIVEX;\n      for I := 0 to FSaveDepth - 1 do\n      begin\n        Desc.Caps.Caps2 := Desc.Caps.Caps2 or J;\n        J := J shl 1;\n      end;\n      ImageCount := FSaveDepth * FSaveMipMapCount;\n    end\n    else if IsVolume then\n    begin\n      // Set proper flags for volume texture\n      Desc.Flags := Desc.Flags or DDSD_DEPTH;\n      Desc.Caps.Caps1 := Desc.Caps.Caps1 or DDSCAPS_COMPLEX;\n      Desc.Caps.Caps2 := Desc.Caps.Caps2 or DDSCAPS2_VOLUME;\n      Desc.Depth := FSaveDepth;\n      ImageCount := GetVolumeLevelCount(FSaveDepth, FSaveMipMapCount);\n    end;\n\n    // Now we set DDS pixel format for main image\n    if FmtInfo.IsSpecial or FmtInfo.IsFloatingPoint or\n      (FmtInfo.BytesPerPixel > 4) then\n    begin\n      Desc.PixelFormat.Flags := DDPF_FOURCC;\n      case Format of\n        ifA16B16G16R16:  Desc.PixelFormat.FourCC := D3DFMT_A16B16G16R16;\n        ifR32F:          Desc.PixelFormat.FourCC := D3DFMT_R32F;\n        ifA32B32G32R32F: Desc.PixelFormat.FourCC := D3DFMT_A32B32G32R32F;\n        ifR16F:          Desc.PixelFormat.FourCC := D3DFMT_R16F;\n        ifA16B16G16R16F: Desc.PixelFormat.FourCC := D3DFMT_A16B16G16R16F;\n        ifDXT1:          Desc.PixelFormat.FourCC := FOURCC_DXT1;\n        ifDXT3:          Desc.PixelFormat.FourCC := FOURCC_DXT3;\n        ifDXT5:          Desc.PixelFormat.FourCC := FOURCC_DXT5;\n        ifATI1N:         Desc.PixelFormat.FourCC := FOURCC_ATI1;\n        ifATI2N:         Desc.PixelFormat.FourCC := FOURCC_ATI2;\n      end;\n    end\n    else if FmtInfo.HasGrayChannel then\n    begin\n      Desc.PixelFormat.Flags := DDPF_LUMINANCE;\n      Desc.PixelFormat.BitCount := FmtInfo.BytesPerPixel * 8;\n      case Format of\n        ifGray8:  Desc.PixelFormat.RedMask := 255;\n        ifGray16: Desc.PixelFormat.RedMask := 65535;\n        ifA8Gray8:\n          begin\n            Desc.PixelFormat.Flags := Desc.PixelFormat.Flags or DDPF_ALPHAPIXELS;\n            Desc.PixelFormat.RedMask := 255;\n            Desc.PixelFormat.AlphaMask := 65280;\n          end;\n      end;\n    end\n    else\n    begin\n      Desc.PixelFormat.Flags := DDPF_RGB;\n      Desc.PixelFormat.BitCount := FmtInfo.BytesPerPixel * 8;\n      if FmtInfo.HasAlphaChannel then\n      begin\n        Desc.PixelFormat.Flags := Desc.PixelFormat.Flags or DDPF_ALPHAPIXELS;\n        Desc.PixelFormat.AlphaMask := $FF000000;\n      end;\n      if FmtInfo.BytesPerPixel > 2 then\n      begin\n        Desc.PixelFormat.RedMask :=   $00FF0000;\n        Desc.PixelFormat.GreenMask := $0000FF00;\n        Desc.PixelFormat.BlueMask :=  $000000FF;\n      end\n      else\n      begin\n        Desc.PixelFormat.AlphaMask := FmtInfo.PixelFormat.ABitMask;\n        Desc.PixelFormat.RedMask := FmtInfo.PixelFormat.RBitMask;\n        Desc.PixelFormat.GreenMask := FmtInfo.PixelFormat.GBitMask;\n        Desc.PixelFormat.BlueMask := FmtInfo.PixelFormat.BBitMask;\n      end;\n    end;\n\n    // Header and main image are written to output\n    Write(Handle, @Hdr, SizeOf(Hdr));\n    Write(Handle, MainImage.Bits, MainImage.Size);\n\n    // Write the rest of the images and convert them to\n    // the same format as main image if necessary and ensure proper mipmap\n    // simensions too.\n    for I := MainIdx + 1 to MainIdx + ImageCount - 1 do\n    begin\n      // Get proper dimensions for this level\n      ComputeSubDimensions(I, Desc.Width, Desc.Height, Desc.MipMaps, Desc.Depth,\n        IsCubeMap, IsVolume, CurrentWidth, CurrentHeight);\n\n      // Check if input image for this level has the right size and format\n      NeedsResize := not ((Images[I].Width = CurrentWidth) and (Images[I].Height = CurrentHeight));\n      NeedsConvert := not (Images[I].Format = Format);\n\n      if NeedsResize or NeedsConvert then\n      begin\n        // Input image must be resized or converted to different format\n        // to become valid mipmap level\n        InitImage(ImageToSave);\n        CloneImage(Images[I], ImageToSave);\n        if NeedsConvert then\n          ConvertImage(ImageToSave, Format);\n        if NeedsResize then\n          ResizeImage(ImageToSave, CurrentWidth, CurrentHeight, rfBilinear);\n      end\n      else\n        // Input image can be used without any changes\n        ImageToSave := Images[I];\n\n      // Write level data and release temp image if necessary\n      Write(Handle, ImageToSave.Bits, ImageToSave.Size);\n      if Images[I].Bits <> ImageToSave.Bits then\n        FreeImage(ImageToSave);\n    end;\n\n    Result := True;\n  finally\n    if MustBeFreed then\n      FreeImage(MainImage);\n  end;\nend;\n\nprocedure TDDSFileFormat.ConvertToSupported(var Image: TImageData;\n  const Info: TImageFormatInfo);\nvar\n  ConvFormat: TImageFormat;\nbegin\n  if Info.IsIndexed or Info.IsSpecial then\n    // convert indexed and unsupported special formatd to A8R8G8B8\n    ConvFormat := ifA8R8G8B8\n  else if Info.IsFloatingPoint then\n  begin\n    if Info.Format = ifA16R16G16B16F then\n      // only swap channels here\n      ConvFormat := ifA16B16G16R16F\n    else\n      // convert other floating point formats to A32B32G32R32F\n      ConvFormat := ifA32B32G32R32F\n  end\n  else if Info.HasGrayChannel then\n  begin\n    if Info.HasAlphaChannel then\n      // convert grayscale with alpha to A8Gray8\n      ConvFormat := ifA8Gray8\n    else if Info.BytesPerPixel = 1 then\n      // convert 8bit grayscale to Gray8\n      ConvFormat := ifGray8\n    else\n      // convert 16-64bit grayscales to Gray16\n      ConvFormat := ifGray16;\n  end\n  else if Info.BytesPerPixel > 4 then\n    ConvFormat := ifA16B16G16R16\n  else if Info.HasAlphaChannel then\n    // convert the other images with alpha channel to A8R8G8B8\n    ConvFormat := ifA8R8G8B8\n  else\n    // convert the other formats to X8R8G8B8\n    ConvFormat := ifX8R8G8B8;\n\n  ConvertImage(Image, ConvFormat);\nend;\n\nfunction TDDSFileFormat.TestFormat(Handle: TImagingHandle): Boolean;\nvar\n  Hdr: TDDSFileHeader;\n  ReadCount: LongInt;\nbegin\n  Result := False;\n  if Handle <> nil then\n    with GetIO do\n    begin\n      ReadCount := Read(Handle, @Hdr, SizeOf(Hdr));\n      Seek(Handle, -ReadCount, smFromCurrent);\n      Result := (Hdr.Magic = DDSMagic) and (ReadCount = SizeOf(Hdr)) and\n        ((Hdr.Desc.Caps.Caps1 and DDSCAPS_TEXTURE) = DDSCAPS_TEXTURE);\n    end;\nend;\n\ninitialization\n  RegisterImageFileFormat(TDDSFileFormat);\n\n{\n  File Notes:\n\n  -- TODOS ----------------------------------------------------\n    - nothing now\n\n  -- 0.77.1 ----------------------------------------------------\n    - Texture and D3D specific info stored in DDS is now available as metadata\n      (loading).\n    - Added support for loading DDS files with DX10 extension\n      (http://msdn.microsoft.com/en-us/library/windows/desktop/bb943991(v=vs.85).aspx)\n      and few compatibility fixes.\n\n  -- 0.25.0 Changes/Bug Fixes ---------------------------------\n    - Added support for 3Dc ATI1/2 formats.\n\n  -- 0.23 Changes/Bug Fixes -----------------------------------\n    - Saved DDS with mipmaps now correctly defineds COMPLEX flag.\n    - Fixed loading of RGB DDS files that use pitch and have mipmaps -\n      mipmaps were loaded wrongly.\n\n  -- 0.21 Changes/Bug Fixes -----------------------------------\n    - Changed saving behaviour a bit: mipmaps are inlcuded automatically for\n      2D textures if input image array has more than 1 image (no need to\n      set SaveMipMapCount manually).\n    - Mipmap levels are now saved with proper dimensions when saving DDS files.\n    - Made some changes to not be so strict when loading DDS files.\n      Many programs seem to save them in non-standard format\n      (by MS DDS File Reference).\n    - Added missing ifX8R8G8B8 to SupportedFormats, MakeCompatible failed\n      when image was converted to this format (inside).\n    - MakeCompatible method moved to base class, put ConvertToSupported here.\n      GetSupportedFormats removed, it is now set in constructor.\n    - Fixed bug that sometimes saved non-standard DDS files and another\n      one that caused crash when these files were loaded.\n    - Changed extensions to filename masks.\n    - Changed SaveData, LoadData, and MakeCompatible methods according\n      to changes in base class in Imaging unit.\n\n  -- 0.19 Changes/Bug Fixes -----------------------------------\n    - added support for half-float image formats\n    - change in LoadData to allow support for more images\n      in one stream loading\n\n  -- 0.17 Changes/Bug Fixes -----------------------------------\n    - fixed bug in TestFormat which does not recognize many DDS files\n    - changed pitch/linearsize handling in DDS loading code to\n      load DDS files produced by NVidia's Photoshop plugin\n}\n\nend.\n\n"
  },
  {
    "path": "lib/Imaging/ImagingFormats.pas",
    "content": "{\n  Vampyre Imaging Library\n  by Marek Mauder \n  http://imaginglib.sourceforge.net\n\n  The contents of this file are used with permission, subject to the Mozilla\n  Public License Version 1.1 (the \"License\"); you may not use this file except\n  in compliance with the License. You may obtain a copy of the License at\n  http://www.mozilla.org/MPL/MPL-1.1.html\n\n  Software distributed under the License is distributed on an \"AS IS\" basis,\n  WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for\n  the specific language governing rights and limitations under the License.\n\n  Alternatively, the contents of this file may be used under the terms of the\n  GNU Lesser General Public License (the  \"LGPL License\"), in which case the\n  provisions of the LGPL License are applicable instead of those above.\n  If you wish to allow use of your version of this file only under the terms\n  of the LGPL License and not to allow others to use your version of this file\n  under the MPL, indicate your decision by deleting  the provisions above and\n  replace  them with the notice and other provisions required by the LGPL\n  License.  If you do not delete the provisions above, a recipient may use\n  your version of this file under either the MPL or the LGPL License.\n\n  For more information about the LGPL: http://www.gnu.org/copyleft/lesser.html\n}\n\n{ This unit manages information about all image data formats and contains\n  low level format conversion, manipulation, and other related functions.}\nunit ImagingFormats;\n\n{$I ImagingOptions.inc}\n\ninterface\n\nuses\n  ImagingTypes, Imaging, ImagingUtility;\n\ntype\n  TImageFormatInfoArray = array[TImageFormat] of PImageFormatInfo;\n  PImageFormatInfoArray = ^TImageFormatInfoArray;\n\n\n{ Additional image manipulation functions (usually used internally by Imaging unit) }\n\ntype\n  { Color reduction operations.}\n  TReduceColorsAction = (raCreateHistogram, raUpdateHistogram, raMakeColorMap,\n    raMapImage);\n  TReduceColorsActions = set of TReduceColorsAction;\nconst\n  AllReduceColorsActions = [raCreateHistogram, raUpdateHistogram,\n    raMakeColorMap, raMapImage];\n{ Reduces the number of colors of source. Src is bits of source image\n  (ARGB or floating point) and Dst is in some indexed format. MaxColors\n  is the number of colors to which reduce and DstPal is palette to which\n  the resulting colors are written and it must be allocated to at least\n  MaxColors entries. ChannelMask is 'anded' with every pixel's channel value\n  when creating color histogram. If $FF is used all 8bits of color channels\n  are used which can be slow for large images with many colors so you can\n  use  lower masks to speed it up.}\nprocedure ReduceColorsMedianCut(NumPixels: LongInt; Src, Dst: PByte; SrcInfo,\n  DstInfo: PImageFormatInfo; MaxColors: LongInt; ChannelMask: Byte;\n  DstPal: PPalette32; Actions: TReduceColorsActions = AllReduceColorsActions);\n{ Stretches rectangle in source image to rectangle in destination image\n  using nearest neighbor filtering. It is fast but results look blocky\n  because there is no interpolation used. SrcImage and DstImage must be\n  in the same data format. Works for all data formats except special formats.}\nprocedure StretchNearest(const SrcImage: TImageData; SrcX, SrcY, SrcWidth,\n  SrcHeight: LongInt; var DstImage: TImageData; DstX, DstY, DstWidth,\n  DstHeight: LongInt);\ntype\n  { Built-in sampling filters.}\n  TSamplingFilter = (sfNearest, sfLinear, sfCosine, sfHermite, sfQuadratic,\n    sfGaussian, sfSpline, sfLanczos, sfMitchell, sfCatmullRom);\n  { Type of custom sampling function}\n  TFilterFunction = function(Value: Single): Single;\nconst\n  { Default resampling filter used for bicubic resizing.}\n  DefaultCubicFilter = sfCatmullRom;\nvar\n  { Built-in filter functions.}\n  SamplingFilterFunctions: array[TSamplingFilter] of TFilterFunction;\n  { Default radii of built-in filter functions.}\n  SamplingFilterRadii: array[TSamplingFilter] of Single;\n\n{ Stretches rectangle in source image to rectangle in destination image\n  with resampling. One of built-in resampling filters defined by\n  Filter is used. Set WrapEdges to True for seamlessly tileable images.\n  SrcImage and DstImage must be in the same data format.\n  Works for all data formats except special and indexed formats.}\nprocedure StretchResample(const SrcImage: TImageData; SrcX, SrcY, SrcWidth,\n  SrcHeight: LongInt; var DstImage: TImageData; DstX, DstY, DstWidth,\n  DstHeight: LongInt; Filter: TSamplingFilter; WrapEdges: Boolean = False); overload;\n{ Stretches rectangle in source image to rectangle in destination image\n  with resampling. You can use custom sampling function and filter radius.\n  Set WrapEdges to True for seamlessly tileable images. SrcImage and DstImage\n  must be in the same data format.\n  Works for all data formats except special and indexed formats.}\nprocedure StretchResample(const SrcImage: TImageData; SrcX, SrcY, SrcWidth,\n  SrcHeight: LongInt; var DstImage: TImageData; DstX, DstY, DstWidth,\n  DstHeight: LongInt; Filter: TFilterFunction; Radius: Single;\n  WrapEdges: Boolean = False); overload;\n{ Helper for functions that create mipmap levels. BiggerLevel is\n  valid image and SmallerLevel is empty zeroed image. SmallerLevel is created\n  with Width and Height dimensions and it is filled with pixels of BiggerLevel\n  using resampling filter specified by ImagingMipMapFilter option.\n  Uses StretchNearest and StretchResample internally so the same image data format\n  limitations apply.}\nprocedure FillMipMapLevel(const BiggerLevel: TImageData; Width, Height: LongInt;\n  var SmallerLevel: TImageData);\n\n\n{ Various helper & support functions }\n\n{ Copies Src pixel to Dest pixel. It is faster than System.Move procedure.}\nprocedure CopyPixel(Src, Dest: Pointer; BytesPerPixel: LongInt); {$IFDEF USE_INLINE}inline;{$ENDIF}\n{ Compares Src pixel and Dest pixel. It is faster than SysUtils.CompareMem function.}\nfunction ComparePixels(PixelA, PixelB: Pointer; BytesPerPixel: LongInt): Boolean; {$IFDEF USE_INLINE}inline;{$ENDIF}\n{ Translates pixel color in SrcFormat to DstFormat.}\nprocedure TranslatePixel(SrcPixel, DstPixel: Pointer; SrcFormat,\n  DstFormat: TImageFormat; SrcPalette, DstPalette: PPalette32);\n{ Clamps floating point pixel channel values to [0.0, 1.0] range.}\nprocedure ClampFloatPixel(var PixF: TColorFPRec); {$IFDEF USE_INLINE}inline;{$ENDIF}\n{ Helper function that converts pixel in any format to 32bit ARGB pixel.\n  For common formats it's faster than calling GetPixel32 etc.}\nprocedure ConvertToPixel32(SrcPix: PByte; DestPix: PColor32Rec;\n  const SrcInfo: TImageFormatInfo; SrcPalette: PPalette32 = nil); {$IFDEF USE_INLINE}inline;{$ENDIF}\n\n{ Adds padding bytes at the ends of scanlines. Bpp is the number of bytes per\n  pixel of source and WidthBytes is the number of bytes per scanlines of dest.}\nprocedure AddPadBytes(DataIn: Pointer; DataOut: Pointer; Width, Height,\n  Bpp, WidthBytes: LongInt);\n{ Removes padding from image with scanlines that have aligned sizes. Bpp is\n  the number of bytes per pixel of dest and WidthBytes is the number of bytes\n  per scanlines of source.}\nprocedure RemovePadBytes(DataIn: Pointer; DataOut: Pointer; Width, Height,\n  Bpp, WidthBytes: LongInt);\n\n{ Converts 1bit image data to 8bit. Used mostly by file loaders for formats\n  supporting 1bit images. Scaling of pixel values to 8bits is optional\n  (indexed formats don't need this).}\nprocedure Convert1To8(DataIn, DataOut: PByte; Width, Height,\n  WidthBytes: LongInt; ScaleTo8Bits: Boolean);\n{ Converts 2bit image data to 8bit. Used mostly by file loaders for formats\n  supporting 2bit images. Scaling of pixel values to 8bits is optional\n  (indexed formats don't need this).}\nprocedure Convert2To8(DataIn, DataOut: PByte; Width, Height,\n  WidthBytes: LongInt; ScaleTo8Bits: Boolean);\n{ Converts 4bit image data to 8bit. Used mostly by file loaders for formats\n  supporting 4bit images. Scaling of pixel values to 8bits is optional\n  (indexed formats don't need this).}\nprocedure Convert4To8(DataIn, DataOut: PByte; Width, Height,\n  WidthBytes: LongInt; ScaleTo8Bits: Boolean);\n\n{ Helper function for image file loaders. Some 15 bit images (targas, bitmaps)\n  may contain 1 bit alpha but there is no indication of it. This function checks\n  all 16 bit(should be X1R5G5B5 or A1R5G5B5 format) pixels and some of them have\n  alpha bit set it returns True, otherwise False.}\nfunction Has16BitImageAlpha(NumPixels: LongInt; Data: PWord): Boolean;\n{ Helper function for image file loaders. This function checks is similar\n  to Has16BitImageAlpha but works with A8R8G8B8/X8R8G8B8 format.}\nfunction Has32BitImageAlpha(NumPixels: LongInt; Data: PLongWord): Boolean;\n{ Checks if there is any relevant alpha data (any entry has alpha <> 255)\n  in the given palette.}\nfunction PaletteHasAlpha(Palette: PPalette32; PaletteEntries: Integer): Boolean;\n\n{ Provides indexed access to each line of pixels. Does not work with special\n  format images.}\nfunction GetScanLine(ImageBits: Pointer; const FormatInfo: TImageFormatInfo;\n  LineWidth, Index: LongInt): Pointer; {$IFDEF USE_INLINE}inline;{$ENDIF}\n{ Returns True if Format is valid image data format identifier.}\nfunction IsImageFormatValid(Format: TImageFormat): Boolean;\n\n{ Converts 16bit half floating point value to 32bit Single.}\nfunction HalfToFloat(Half: THalfFloat): Single;\n{ Converts 32bit Single to 16bit half floating point.}\nfunction FloatToHalf(Float: Single): THalfFloat;\n\n{ Converts half float color value to single-precision floating point color.}\nfunction ColorHalfToFloat(ColorHF: TColorHFRec): TColorFPRec; {$IFDEF USE_INLINE}inline;{$ENDIF}\n{ Converts single-precision floating point color to half float color.}\nfunction ColorFloatToHalf(ColorFP: TColorFPRec): TColorHFRec; {$IFDEF USE_INLINE}inline;{$ENDIF}\n\n{ Makes image PalEntries x 1 big where each pixel has color of one pal entry.}\nprocedure VisualizePalette(Pal: PPalette32; Entries: Integer; out PalImage: TImageData);\n\ntype\n  TPointRec = record\n    Pos: LongInt;\n    Weight: Single;\n  end;\n  TCluster = array of TPointRec;\n  TMappingTable = array of TCluster;\n\n{ Helper function for resampling.}\nfunction BuildMappingTable(DstLow, DstHigh, SrcLow, SrcHigh, SrcImageWidth: LongInt;\n  Filter: TFilterFunction; Radius: Single; WrapEdges: Boolean): TMappingTable;\n{ Helper function for resampling.}\nprocedure FindExtremes(const Map: TMappingTable; var MinPos, MaxPos: LongInt);\n\n\n{ Pixel readers/writers for different image formats }\n\n{ Returns pixel of image in any ARGB format. Channel values are scaled to 16 bits.}\nprocedure ChannelGetSrcPixel(Src: PByte; SrcInfo: PImageFormatInfo;\n  var Pix: TColor64Rec);\n{ Sets pixel of image in any ARGB format. Channel values must be scaled to 16 bits.}\nprocedure ChannelSetDstPixel(Dst: PByte; DstInfo: PImageFormatInfo;\n  const Pix: TColor64Rec);\n\n{ Returns pixel of image in any grayscale format. Gray value is scaled to 64 bits\n  and alpha to 16 bits.}\nprocedure GrayGetSrcPixel(Src: PByte; SrcInfo: PImageFormatInfo;\n  var Gray: TColor64Rec; var Alpha: Word);\n{ Sets pixel of image in any grayscale format. Gray value must be scaled to 64 bits\n  and alpha to 16 bits.}\nprocedure GraySetDstPixel(Dst: PByte; DstInfo: PImageFormatInfo;\n  const Gray: TColor64Rec; Alpha: Word);\n\n{ Returns pixel of image in any floating point format. Channel values are\n  in range <0.0, 1.0>.}\nprocedure FloatGetSrcPixel(Src: PByte; SrcInfo: PImageFormatInfo;\n  var Pix: TColorFPRec);\n{ Sets pixel of image in any floating point format. Channel values must be\n  in range <0.0, 1.0>.}\nprocedure FloatSetDstPixel(Dst: PByte; DstInfo: PImageFormatInfo;\n  const Pix: TColorFPRec);\n\n{ Returns pixel of image in any indexed format. Returned value is index to\n  the palette.}\nprocedure IndexGetSrcPixel(Src: PByte; SrcInfo: PImageFormatInfo;\n  var Index: LongWord);\n{ Sets pixel of image in any indexed format. Index is index to the palette.}\nprocedure IndexSetDstPixel(Dst: PByte; DstInfo: PImageFormatInfo;\n  Index: LongWord);\n\n\n{ Pixel readers/writers for 32bit and FP colors}\n\n{ Function for getting pixel colors. Native pixel is read from Image and\n  then translated to 32 bit ARGB.}\nfunction GetPixel32Generic(Bits: Pointer; Info: PImageFormatInfo;\n  Palette: PPalette32): TColor32Rec;\n{ Procedure for setting pixel colors. Input 32 bit ARGB color is translated to\n    native format and then written to Image.}\nprocedure SetPixel32Generic(Bits: Pointer; Info: PImageFormatInfo;\n  Palette: PPalette32; const Color: TColor32Rec);\n{ Function for getting pixel colors. Native pixel is read from Image and\n  then translated to FP ARGB.}\nfunction GetPixelFPGeneric(Bits: Pointer; Info: PImageFormatInfo;\n  Palette: PPalette32): TColorFPRec;\n{ Procedure for setting pixel colors. Input FP ARGB color is translated to\n    native format and then written to Image.}\nprocedure SetPixelFPGeneric(Bits: Pointer; Info: PImageFormatInfo;\n  Palette: PPalette32; const Color: TColorFPRec);\n\n\n{ Image format conversion functions }\n\n{ Converts any ARGB format to any ARGB format.}\nprocedure ChannelToChannel(NumPixels: LongInt; Src, Dst: PByte; SrcInfo,\n  DstInfo: PImageFormatInfo);\n{ Converts any ARGB format to any grayscale format.}\nprocedure ChannelToGray(NumPixels: LongInt; Src, Dst: PByte; SrcInfo,\n  DstInfo: PImageFormatInfo);\n{ Converts any ARGB format to any floating point format.}\nprocedure ChannelToFloat(NumPixels: LongInt; Src, Dst: PByte; SrcInfo,\n  DstInfo: PImageFormatInfo);\n{ Converts any ARGB format to any indexed format.}\nprocedure ChannelToIndex(NumPixels: LongInt; Src, Dst: PByte; SrcInfo,\n  DstInfo: PImageFormatInfo; DstPal: PPalette32);\n\n{ Converts any grayscale format to any grayscale format.}\nprocedure GrayToGray(NumPixels: LongInt; Src, Dst: PByte; SrcInfo,\n  DstInfo: PImageFormatInfo);\n{ Converts any grayscale format to any ARGB format.}\nprocedure GrayToChannel(NumPixels: LongInt; Src, Dst: PByte; SrcInfo,\n  DstInfo: PImageFormatInfo);\n{ Converts any grayscale format to any floating point format.}\nprocedure GrayToFloat(NumPixels: LongInt; Src, Dst: PByte; SrcInfo,\n  DstInfo: PImageFormatInfo);\n{ Converts any grayscale format to any indexed format.}\nprocedure GrayToIndex(NumPixels: LongInt; Src, Dst: PByte; SrcInfo,\n  DstInfo: PImageFormatInfo; DstPal: PPalette32);\n\n{ Converts any floating point format to any floating point format.}\nprocedure FloatToFloat(NumPixels: LongInt; Src, Dst: PByte; SrcInfo,\n  DstInfo: PImageFormatInfo);\n{ Converts any floating point format to any ARGB format.}\nprocedure FloatToChannel(NumPixels: LongInt; Src, Dst: PByte; SrcInfo,\n  DstInfo: PImageFormatInfo);\n{ Converts any floating point format to any grayscale format.}\nprocedure FloatToGray(NumPixels: LongInt; Src, Dst: PByte; SrcInfo,\n  DstInfo: PImageFormatInfo);\n{ Converts any floating point format to any indexed format.}\nprocedure FloatToIndex(NumPixels: LongInt; Src, Dst: PByte; SrcInfo,\n  DstInfo: PImageFormatInfo; DstPal: PPalette32);\n\n{ Converts any indexed format to any indexed format.}\nprocedure IndexToIndex(NumPixels: LongInt; Src, Dst: PByte; SrcInfo,\n  DstInfo: PImageFormatInfo; SrcPal, DstPal: PPalette32);\n{ Converts any indexed format to any ARGB format.}\nprocedure IndexToChannel(NumPixels: LongInt; Src, Dst: PByte; SrcInfo,\n  DstInfo: PImageFormatInfo; SrcPal: PPalette32);\n{ Converts any indexed format to any grayscale format.}\nprocedure IndexToGray(NumPixels: LongInt; Src, Dst: PByte; SrcInfo,\n  DstInfo: PImageFormatInfo; SrcPal: PPalette32);\n{ Converts any indexed format to any floating point  format.}\nprocedure IndexToFloat(NumPixels: LongInt; Src, Dst: PByte; SrcInfo,\n  DstInfo: PImageFormatInfo; SrcPal: PPalette32);\n\n\n{ Color constructor functions }\n\n{ Constructs TColor24Rec color.}\nfunction Color24(R, G, B: Byte): TColor24Rec; {$IFDEF USE_INLINE}inline;{$ENDIF}\n{ Constructs TColor32Rec color.}\nfunction Color32(A, R, G, B: Byte): TColor32Rec; {$IFDEF USE_INLINE}inline;{$ENDIF}\n{ Constructs TColor48Rec color.}\nfunction Color48(R, G, B: Word): TColor48Rec; {$IFDEF USE_INLINE}inline;{$ENDIF}\n{ Constructs TColor64Rec color.}\nfunction Color64(A, R, G, B: Word): TColor64Rec; {$IFDEF USE_INLINE}inline;{$ENDIF}\n{ Constructs TColorFPRec color.}\nfunction ColorFP(A, R, G, B: Single): TColorFPRec; {$IFDEF USE_INLINE}inline;{$ENDIF}\n{ Constructs TColorHFRec color.}\nfunction ColorHF(A, R, G, B: THalfFloat): TColorHFRec; {$IFDEF USE_INLINE}inline;{$ENDIF}\n\n\n{ Special formats conversion functions }\n\n{ Converts image to/from/between special image formats (dxtc, ...).}\nprocedure ConvertSpecial(var Image: TImageData; SrcInfo,\n  DstInfo: PImageFormatInfo);\n\n\n{ Inits all image format information. Called internally on startup.}\nprocedure InitImageFormats(var Infos: TImageFormatInfoArray);\n\nconst\n  // Grayscale conversion channel weights\n  GrayConv: TColorFPRec = (B: 0.114; G: 0.587; R: 0.299; A: 0.0);\n\n  // Contants for converting integer colors to floating point\n  OneDiv8Bit: Single = 1.0 / 255.0;\n  OneDiv16Bit: Single = 1.0 / 65535.0;\n\nimplementation\n\n{ TImageFormatInfo member functions }\n\n{ Returns size in bytes of image in given standard format where\n  Size = Width * Height * Bpp.}\nfunction GetStdPixelsSize(Format: TImageFormat; Width, Height: LongInt): LongInt; forward;\n{ Checks if Width and Height are valid for given standard format.}\nprocedure CheckStdDimensions(Format: TImageFormat; var Width, Height: LongInt); forward;\n{ Returns size in bytes of image in given DXT format.}\nfunction GetDXTPixelsSize(Format: TImageFormat; Width, Height: LongInt): LongInt; forward;\n{ Checks if Width and Height are valid for given DXT format. If they are\n  not valid, they are changed to pass the check.}\nprocedure CheckDXTDimensions(Format: TImageFormat; var Width, Height: LongInt); forward;\n{ Returns size in bytes of image in BTC format.}\nfunction GetBTCPixelsSize(Format: TImageFormat; Width, Height: LongInt): LongInt; forward;\n{ Returns size in bytes of image in binary format (1bit image).}\nfunction GetBinaryPixelsSize(Format: TImageFormat; Width, Height: LongInt): LongInt; forward;\n\n{ Optimized pixel readers/writers for 32bit and FP colors to be stored in TImageFormatInfo }\n\nfunction GetPixel32ifA8R8G8B8(Bits: Pointer; Info: PImageFormatInfo; Palette: PPalette32): TColor32Rec; forward;\nprocedure SetPixel32ifA8R8G8B8(Bits: Pointer; Info: PImageFormatInfo; Palette: PPalette32; const Color: TColor32Rec); forward;\nfunction GetPixelFPifA8R8G8B8(Bits: Pointer; Info: PImageFormatInfo; Palette: PPalette32): TColorFPRec; forward;\nprocedure SetPixelFPifA8R8G8B8(Bits: Pointer; Info: PImageFormatInfo; Palette: PPalette32; const Color: TColorFPRec); forward;\n\nfunction GetPixel32Channel8Bit(Bits: Pointer; Info: PImageFormatInfo; Palette: PPalette32): TColor32Rec; forward;\nprocedure SetPixel32Channel8Bit(Bits: Pointer; Info: PImageFormatInfo; Palette: PPalette32; const Color: TColor32Rec); forward;\nfunction GetPixelFPChannel8Bit(Bits: Pointer; Info: PImageFormatInfo; Palette: PPalette32): TColorFPRec; forward;\nprocedure SetPixelFPChannel8Bit(Bits: Pointer; Info: PImageFormatInfo; Palette: PPalette32; const Color: TColorFPRec); forward;\n\nfunction GetPixelFPFloat32(Bits: Pointer; Info: PImageFormatInfo; Palette: PPalette32): TColorFPRec; forward;\nprocedure SetPixelFPFloat32(Bits: Pointer; Info: PImageFormatInfo; Palette: PPalette32; const Color: TColorFPRec); forward;\n\nvar\n  PFR3G3B2: TPixelFormatInfo;\n  PFX5R1G1B1: TPixelFormatInfo;\n  PFR5G6B5: TPixelFormatInfo;\n  PFA1R5G5B5: TPixelFormatInfo;\n  PFA4R4G4B4: TPixelFormatInfo;\n  PFX1R5G5B5: TPixelFormatInfo;\n  PFX4R4G4B4: TPixelFormatInfo;\n  FInfos: PImageFormatInfoArray;\n\nvar\n  // Free Pascal generates hundreds of warnings here\n{$WARNINGS OFF}\n\n  // indexed formats\n  Index8Info: TImageFormatInfo = (\n    Format: ifIndex8;\n    Name: 'Index8';\n    BytesPerPixel: 1;\n    ChannelCount: 1;\n    PaletteEntries: 256;\n    HasAlphaChannel: True;\n    IsIndexed: True;\n    GetPixelsSize: GetStdPixelsSize;\n    CheckDimensions: CheckStdDimensions;\n    GetPixel32: GetPixel32Generic;\n    GetPixelFP: GetPixelFPGeneric;\n    SetPixel32: SetPixel32Generic;\n    SetPixelFP: SetPixelFPGeneric);\n\n  // grayscale formats\n  Gray8Info: TImageFormatInfo = (\n    Format: ifGray8;\n    Name: 'Gray8';\n    BytesPerPixel: 1;\n    ChannelCount: 1;\n    HasGrayChannel: True;\n    GetPixelsSize: GetStdPixelsSize;\n    CheckDimensions: CheckStdDimensions;\n    GetPixel32: GetPixel32Channel8Bit;\n    GetPixelFP: GetPixelFPChannel8Bit;\n    SetPixel32: SetPixel32Channel8Bit;\n    SetPixelFP: SetPixelFPChannel8Bit);\n\n  A8Gray8Info: TImageFormatInfo = (\n    Format: ifA8Gray8;\n    Name: 'A8Gray8';\n    BytesPerPixel: 2;\n    ChannelCount: 2;\n    HasGrayChannel: True;\n    HasAlphaChannel: True;\n    GetPixelsSize: GetStdPixelsSize;\n    CheckDimensions: CheckStdDimensions;\n    GetPixel32: GetPixel32Channel8Bit;\n    GetPixelFP: GetPixelFPChannel8Bit;\n    SetPixel32: SetPixel32Channel8Bit;\n    SetPixelFP: SetPixelFPChannel8Bit);\n\n  Gray16Info: TImageFormatInfo = (\n    Format: ifGray16;\n    Name: 'Gray16';\n    BytesPerPixel: 2;\n    ChannelCount: 1;\n    HasGrayChannel: True;\n    GetPixelsSize: GetStdPixelsSize;\n    CheckDimensions: CheckStdDimensions;\n    GetPixel32: GetPixel32Generic;\n    GetPixelFP: GetPixelFPGeneric;\n    SetPixel32: SetPixel32Generic;\n    SetPixelFP: SetPixelFPGeneric);\n\n  Gray32Info: TImageFormatInfo = (\n    Format: ifGray32;\n    Name: 'Gray32';\n    BytesPerPixel: 4;\n    ChannelCount: 1;\n    HasGrayChannel: True;\n    GetPixelsSize: GetStdPixelsSize;\n    CheckDimensions: CheckStdDimensions;\n    GetPixel32: GetPixel32Generic;\n    GetPixelFP: GetPixelFPGeneric;\n    SetPixel32: SetPixel32Generic;\n    SetPixelFP: SetPixelFPGeneric);\n\n  Gray64Info: TImageFormatInfo = (\n    Format: ifGray64;\n    Name: 'Gray64';\n    BytesPerPixel: 8;\n    ChannelCount: 1;\n    HasGrayChannel: True;\n    GetPixelsSize: GetStdPixelsSize;\n    CheckDimensions: CheckStdDimensions;\n    GetPixel32: GetPixel32Generic;\n    GetPixelFP: GetPixelFPGeneric;\n    SetPixel32: SetPixel32Generic;\n    SetPixelFP: SetPixelFPGeneric);\n\n  A16Gray16Info: TImageFormatInfo = (\n    Format: ifA16Gray16;\n    Name: 'A16Gray16';\n    BytesPerPixel: 4;\n    ChannelCount: 2;\n    HasGrayChannel: True;\n    HasAlphaChannel: True;\n    GetPixelsSize: GetStdPixelsSize;\n    CheckDimensions: CheckStdDimensions;\n    GetPixel32: GetPixel32Generic;\n    GetPixelFP: GetPixelFPGeneric;\n    SetPixel32: SetPixel32Generic;\n    SetPixelFP: SetPixelFPGeneric);\n\n  // ARGB formats\n  X5R1G1B1Info: TImageFormatInfo = (\n    Format: ifX5R1G1B1;\n    Name: 'X5R1G1B1';\n    BytesPerPixel: 1;\n    ChannelCount: 3;\n    UsePixelFormat: True;\n    PixelFormat: @PFX5R1G1B1;\n    GetPixelsSize: GetStdPixelsSize;\n    CheckDimensions: CheckStdDimensions;\n    GetPixel32: GetPixel32Generic;\n    GetPixelFP: GetPixelFPGeneric;\n    SetPixel32: SetPixel32Generic;\n    SetPixelFP: SetPixelFPGeneric);\n\n  R3G3B2Info: TImageFormatInfo = (\n    Format: ifR3G3B2;\n    Name: 'R3G3B2';\n    BytesPerPixel: 1;\n    ChannelCount: 3;\n    UsePixelFormat: True;\n    PixelFormat: @PFR3G3B2;\n    GetPixelsSize: GetStdPixelsSize;\n    CheckDimensions: CheckStdDimensions;\n    GetPixel32: GetPixel32Generic;\n    GetPixelFP: GetPixelFPGeneric;\n    SetPixel32: SetPixel32Generic;\n    SetPixelFP: SetPixelFPGeneric);\n\n  R5G6B5Info: TImageFormatInfo = (\n    Format: ifR5G6B5;\n    Name: 'R5G6B5';\n    BytesPerPixel: 2;\n    ChannelCount: 3;\n    UsePixelFormat: True;\n    PixelFormat: @PFR5G6B5;\n    GetPixelsSize: GetStdPixelsSize;\n    CheckDimensions: CheckStdDimensions;\n    GetPixel32: GetPixel32Generic;\n    GetPixelFP: GetPixelFPGeneric;\n    SetPixel32: SetPixel32Generic;\n    SetPixelFP: SetPixelFPGeneric);\n\n  A1R5G5B5Info: TImageFormatInfo = (\n    Format: ifA1R5G5B5;\n    Name: 'A1R5G5B5';\n    BytesPerPixel: 2;\n    ChannelCount: 4;\n    HasAlphaChannel: True;\n    UsePixelFormat: True;\n    PixelFormat: @PFA1R5G5B5;\n    GetPixelsSize: GetStdPixelsSize;\n    CheckDimensions: CheckStdDimensions;\n    GetPixel32: GetPixel32Generic;\n    GetPixelFP: GetPixelFPGeneric;\n    SetPixel32: SetPixel32Generic;\n    SetPixelFP: SetPixelFPGeneric);\n\n  A4R4G4B4Info: TImageFormatInfo = (\n    Format: ifA4R4G4B4;\n    Name: 'A4R4G4B4';\n    BytesPerPixel: 2;\n    ChannelCount: 4;\n    HasAlphaChannel: True;\n    UsePixelFormat: True;\n    PixelFormat: @PFA4R4G4B4;\n    GetPixelsSize: GetStdPixelsSize;\n    CheckDimensions: CheckStdDimensions;\n    GetPixel32: GetPixel32Generic;\n    GetPixelFP: GetPixelFPGeneric;\n    SetPixel32: SetPixel32Generic;\n    SetPixelFP: SetPixelFPGeneric);\n\n  X1R5G5B5Info: TImageFormatInfo = (\n    Format: ifX1R5G5B5;\n    Name: 'X1R5G5B5';\n    BytesPerPixel: 2;\n    ChannelCount: 3;\n    UsePixelFormat: True;\n    PixelFormat: @PFX1R5G5B5;\n    GetPixelsSize: GetStdPixelsSize;\n    CheckDimensions: CheckStdDimensions;\n    GetPixel32: GetPixel32Generic;\n    GetPixelFP: GetPixelFPGeneric;\n    SetPixel32: SetPixel32Generic;\n    SetPixelFP: SetPixelFPGeneric);\n\n  X4R4G4B4Info: TImageFormatInfo = (\n    Format: ifX4R4G4B4;\n    Name: 'X4R4G4B4';\n    BytesPerPixel: 2;\n    ChannelCount: 3;\n    UsePixelFormat: True;\n    PixelFormat: @PFX4R4G4B4;\n    GetPixelsSize: GetStdPixelsSize;\n    CheckDimensions: CheckStdDimensions;\n    GetPixel32: GetPixel32Generic;\n    GetPixelFP: GetPixelFPGeneric;\n    SetPixel32: SetPixel32Generic;\n    SetPixelFP: SetPixelFPGeneric);\n\n  R8G8B8Info: TImageFormatInfo = (\n    Format: ifR8G8B8;\n    Name: 'R8G8B8';\n    BytesPerPixel: 3;\n    ChannelCount: 3;\n    GetPixelsSize: GetStdPixelsSize;\n    CheckDimensions: CheckStdDimensions;\n    GetPixel32: GetPixel32Channel8Bit;\n    GetPixelFP: GetPixelFPChannel8Bit;\n    SetPixel32: SetPixel32Channel8Bit;\n    SetPixelFP: SetPixelFPChannel8Bit);\n\n  A8R8G8B8Info: TImageFormatInfo = (\n    Format: ifA8R8G8B8;\n    Name: 'A8R8G8B8';\n    BytesPerPixel: 4;\n    ChannelCount: 4;\n    HasAlphaChannel: True;\n    GetPixelsSize: GetStdPixelsSize;\n    CheckDimensions: CheckStdDimensions;\n    GetPixel32: GetPixel32ifA8R8G8B8;\n    GetPixelFP: GetPixelFPifA8R8G8B8;\n    SetPixel32: SetPixel32ifA8R8G8B8;\n    SetPixelFP: SetPixelFPifA8R8G8B8);\n\n  X8R8G8B8Info: TImageFormatInfo = (\n    Format: ifX8R8G8B8;\n    Name: 'X8R8G8B8';\n    BytesPerPixel: 4;\n    ChannelCount: 3;\n    GetPixelsSize: GetStdPixelsSize;\n    CheckDimensions: CheckStdDimensions;\n    GetPixel32: GetPixel32Channel8Bit;\n    GetPixelFP: GetPixelFPChannel8Bit;\n    SetPixel32: SetPixel32Channel8Bit;\n    SetPixelFP: SetPixelFPChannel8Bit);\n\n  R16G16B16Info: TImageFormatInfo = (\n    Format: ifR16G16B16;\n    Name: 'R16G16B16';\n    BytesPerPixel: 6;\n    ChannelCount: 3;\n    RBSwapFormat: ifB16G16R16;\n    GetPixelsSize: GetStdPixelsSize;\n    CheckDimensions: CheckStdDimensions;\n    GetPixel32: GetPixel32Generic;\n    GetPixelFP: GetPixelFPGeneric;\n    SetPixel32: SetPixel32Generic;\n    SetPixelFP: SetPixelFPGeneric);\n\n  A16R16G16B16Info: TImageFormatInfo = (\n    Format: ifA16R16G16B16;\n    Name: 'A16R16G16B16';\n    BytesPerPixel: 8;\n    ChannelCount: 4;\n    HasAlphaChannel: True;\n    RBSwapFormat: ifA16B16G16R16;\n    GetPixelsSize: GetStdPixelsSize;\n    CheckDimensions: CheckStdDimensions;\n    GetPixel32: GetPixel32Generic;\n    GetPixelFP: GetPixelFPGeneric;\n    SetPixel32: SetPixel32Generic;\n    SetPixelFP: SetPixelFPGeneric);\n\n  B16G16R16Info: TImageFormatInfo = (\n    Format: ifB16G16R16;\n    Name: 'B16G16R16';\n    BytesPerPixel: 6;\n    ChannelCount: 3;\n    IsRBSwapped: True;\n    RBSwapFormat: ifR16G16B16;\n    GetPixelsSize: GetStdPixelsSize;\n    CheckDimensions: CheckStdDimensions;\n    GetPixel32: GetPixel32Generic;\n    GetPixelFP: GetPixelFPGeneric;\n    SetPixel32: SetPixel32Generic;\n    SetPixelFP: SetPixelFPGeneric);\n\n  A16B16G16R16Info: TImageFormatInfo = (\n    Format: ifA16B16G16R16;\n    Name: 'A16B16G16R16';\n    BytesPerPixel: 8;\n    ChannelCount: 4;\n    HasAlphaChannel: True;\n    IsRBSwapped: True;\n    RBSwapFormat: ifA16R16G16B16;\n    GetPixelsSize: GetStdPixelsSize;\n    CheckDimensions: CheckStdDimensions;\n    GetPixel32: GetPixel32Generic;\n    GetPixelFP: GetPixelFPGeneric;\n    SetPixel32: SetPixel32Generic;\n    SetPixelFP: SetPixelFPGeneric);\n\n  // floating point formats\n  R32FInfo: TImageFormatInfo = (\n    Format: ifR32F;\n    Name: 'R32F';\n    BytesPerPixel: 4;\n    ChannelCount: 1;\n    IsFloatingPoint: True;\n    GetPixelsSize: GetStdPixelsSize;\n    CheckDimensions: CheckStdDimensions;\n    GetPixel32: GetPixel32Generic;\n    GetPixelFP: GetPixelFPFloat32;\n    SetPixel32: SetPixel32Generic;\n    SetPixelFP: SetPixelFPFloat32);\n\n A32R32G32B32FInfo: TImageFormatInfo = (\n    Format: ifA32R32G32B32F;\n    Name: 'A32R32G32B32F';\n    BytesPerPixel: 16;\n    ChannelCount: 4;\n    HasAlphaChannel: True;\n    IsFloatingPoint: True;\n    RBSwapFormat: ifA32B32G32R32F;\n    GetPixelsSize: GetStdPixelsSize;\n    CheckDimensions: CheckStdDimensions;\n    GetPixel32: GetPixel32Generic;\n    GetPixelFP: GetPixelFPFloat32;\n    SetPixel32: SetPixel32Generic;\n    SetPixelFP: SetPixelFPFloat32);\n\n  A32B32G32R32FInfo: TImageFormatInfo = (\n    Format: ifA32B32G32R32F;\n    Name: 'A32B32G32R32F';\n    BytesPerPixel: 16;\n    ChannelCount: 4;\n    HasAlphaChannel: True;\n    IsFloatingPoint: True;\n    IsRBSwapped: True;\n    RBSwapFormat: ifA32R32G32B32F;\n    GetPixelsSize: GetStdPixelsSize;\n    CheckDimensions: CheckStdDimensions;\n    GetPixel32: GetPixel32Generic;\n    GetPixelFP: GetPixelFPFloat32;\n    SetPixel32: SetPixel32Generic;\n    SetPixelFP: SetPixelFPFloat32);\n\n  R16FInfo: TImageFormatInfo = (\n    Format: ifR16F;\n    Name: 'R16F';\n    BytesPerPixel: 2;\n    ChannelCount: 1;\n    IsFloatingPoint: True;\n    GetPixelsSize: GetStdPixelsSize;\n    CheckDimensions: CheckStdDimensions;\n    GetPixel32: GetPixel32Generic;\n    GetPixelFP: GetPixelFPGeneric;\n    SetPixel32: SetPixel32Generic;\n    SetPixelFP: SetPixelFPGeneric);\n\n A16R16G16B16FInfo: TImageFormatInfo = (\n    Format: ifA16R16G16B16F;\n    Name: 'A16R16G16B16F';\n    BytesPerPixel: 8;\n    ChannelCount: 4;\n    HasAlphaChannel: True;\n    IsFloatingPoint: True;\n    RBSwapFormat: ifA16B16G16R16F;\n    GetPixelsSize: GetStdPixelsSize;\n    CheckDimensions: CheckStdDimensions;\n    GetPixel32: GetPixel32Generic;\n    GetPixelFP: GetPixelFPGeneric;\n    SetPixel32: SetPixel32Generic;\n    SetPixelFP: SetPixelFPGeneric);\n\n  A16B16G16R16FInfo: TImageFormatInfo = (\n    Format: ifA16B16G16R16F;\n    Name: 'A16B16G16R16F';\n    BytesPerPixel: 8;\n    ChannelCount: 4;\n    HasAlphaChannel: True;\n    IsFloatingPoint: True;\n    IsRBSwapped: True;\n    RBSwapFormat: ifA16R16G16B16F;\n    GetPixelsSize: GetStdPixelsSize;\n    CheckDimensions: CheckStdDimensions;\n    GetPixel32: GetPixel32Generic;\n    GetPixelFP: GetPixelFPGeneric;\n    SetPixel32: SetPixel32Generic;\n    SetPixelFP: SetPixelFPGeneric);\n\n  R32G32B32FInfo: TImageFormatInfo = (\n    Format: ifR32G32B32F;\n    Name: 'R32G32B32F';\n    BytesPerPixel: 12;\n    ChannelCount: 3;\n    IsFloatingPoint: True;\n    RBSwapFormat: ifB32G32R32F;\n    GetPixelsSize: GetStdPixelsSize;\n    CheckDimensions: CheckStdDimensions;\n    GetPixel32: GetPixel32Generic;\n    GetPixelFP: GetPixelFPFloat32;\n    SetPixel32: SetPixel32Generic;\n    SetPixelFP: SetPixelFPFloat32);\n\n  B32G32R32FInfo: TImageFormatInfo = (\n    Format: ifB32G32R32F;\n    Name: 'B32G32R32F';\n    BytesPerPixel: 12;\n    ChannelCount: 3;\n    IsFloatingPoint: True;\n    IsRBSwapped: True;\n    RBSwapFormat: ifR32G32B32F;\n    GetPixelsSize: GetStdPixelsSize;\n    CheckDimensions: CheckStdDimensions;\n    GetPixel32: GetPixel32Generic;\n    GetPixelFP: GetPixelFPFloat32;\n    SetPixel32: SetPixel32Generic;\n    SetPixelFP: SetPixelFPFloat32);\n\n  // special formats\n  DXT1Info: TImageFormatInfo = (\n    Format: ifDXT1;\n    Name: 'DXT1';\n    ChannelCount: 4;\n    HasAlphaChannel: True;\n    IsSpecial: True;\n    GetPixelsSize: GetDXTPixelsSize;\n    CheckDimensions: CheckDXTDimensions;\n    SpecialNearestFormat: ifA8R8G8B8);\n\n  DXT3Info: TImageFormatInfo = (\n    Format: ifDXT3;\n    Name: 'DXT3';\n    ChannelCount: 4;\n    HasAlphaChannel: True;\n    IsSpecial: True;\n    GetPixelsSize: GetDXTPixelsSize;\n    CheckDimensions: CheckDXTDimensions;\n    SpecialNearestFormat: ifA8R8G8B8);\n\n  DXT5Info: TImageFormatInfo = (\n    Format: ifDXT5;\n    Name: 'DXT5';\n    ChannelCount: 4;\n    HasAlphaChannel: True;\n    IsSpecial: True;\n    GetPixelsSize: GetDXTPixelsSize;\n    CheckDimensions: CheckDXTDimensions;\n    SpecialNearestFormat: ifA8R8G8B8);\n\n  BTCInfo: TImageFormatInfo = (\n    Format: ifBTC;\n    Name: 'BTC';\n    ChannelCount: 1;\n    HasAlphaChannel: False;\n    IsSpecial: True;\n    GetPixelsSize: GetBTCPixelsSize;\n    CheckDimensions: CheckDXTDimensions;\n    SpecialNearestFormat: ifGray8);\n\n  ATI1NInfo: TImageFormatInfo = (\n    Format: ifATI1N;\n    Name: 'ATI1N';\n    ChannelCount: 1;\n    HasAlphaChannel: False;\n    IsSpecial: True;\n    GetPixelsSize: GetDXTPixelsSize;\n    CheckDimensions: CheckDXTDimensions;\n    SpecialNearestFormat: ifGray8);\n\n  ATI2NInfo: TImageFormatInfo = (\n    Format: ifATI2N;\n    Name: 'ATI2N';\n    ChannelCount: 2;\n    HasAlphaChannel: False;\n    IsSpecial: True;\n    GetPixelsSize: GetDXTPixelsSize;\n    CheckDimensions: CheckDXTDimensions;\n    SpecialNearestFormat: ifA8R8G8B8);\n\n  BinaryInfo: TImageFormatInfo = (\n    Format: ifBinary;\n    Name: 'Binary';\n    ChannelCount: 1;\n    HasAlphaChannel: False;\n    IsSpecial: True;\n    GetPixelsSize: GetBinaryPixelsSize;\n    CheckDimensions: CheckStdDimensions;\n    SpecialNearestFormat: ifGray8);\n\n{$WARNINGS ON}\n\nfunction PixelFormat(ABitCount, RBitCount, GBitCount, BBitCount: Byte): TPixelFormatInfo; forward;\n\nprocedure InitImageFormats(var Infos: TImageFormatInfoArray);\nbegin\n  FInfos := @Infos;\n\n  Infos[ifDefault] := @A8R8G8B8Info;\n  // indexed formats\n  Infos[ifIndex8] := @Index8Info;\n  // grayscale formats\n  Infos[ifGray8] := @Gray8Info;\n  Infos[ifA8Gray8] := @A8Gray8Info;\n  Infos[ifGray16] := @Gray16Info;\n  Infos[ifGray32] := @Gray32Info;\n  Infos[ifGray64] := @Gray64Info;\n  Infos[ifA16Gray16] := @A16Gray16Info;\n  // ARGB formats\n  Infos[ifX5R1G1B1] := @X5R1G1B1Info;\n  Infos[ifR3G3B2] := @R3G3B2Info;\n  Infos[ifR5G6B5] := @R5G6B5Info;\n  Infos[ifA1R5G5B5] := @A1R5G5B5Info;\n  Infos[ifA4R4G4B4] := @A4R4G4B4Info;\n  Infos[ifX1R5G5B5] := @X1R5G5B5Info;\n  Infos[ifX4R4G4B4] := @X4R4G4B4Info;\n  Infos[ifR8G8B8] := @R8G8B8Info;\n  Infos[ifA8R8G8B8] := @A8R8G8B8Info;\n  Infos[ifX8R8G8B8] := @X8R8G8B8Info;\n  Infos[ifR16G16B16] := @R16G16B16Info;\n  Infos[ifA16R16G16B16] := @A16R16G16B16Info;\n  Infos[ifB16G16R16] := @B16G16R16Info;\n  Infos[ifA16B16G16R16] := @A16B16G16R16Info;\n  // floating point formats\n  Infos[ifR32F] := @R32FInfo;\n  Infos[ifA32R32G32B32F] := @A32R32G32B32FInfo;\n  Infos[ifA32B32G32R32F] := @A32B32G32R32FInfo;\n  Infos[ifR16F] := @R16FInfo;\n  Infos[ifA16R16G16B16F] := @A16R16G16B16FInfo;\n  Infos[ifA16B16G16R16F] := @A16B16G16R16FInfo;\n  Infos[ifR32G32B32F] := @R32G32B32FInfo;\n  Infos[ifB32G32R32F] := @B32G32R32FInfo;\n  // special formats\n  Infos[ifDXT1] := @DXT1Info;\n  Infos[ifDXT3] := @DXT3Info;\n  Infos[ifDXT5] := @DXT5Info;\n  Infos[ifBTC] :=  @BTCInfo;\n  Infos[ifATI1N] := @ATI1NInfo;\n  Infos[ifATI2N] := @ATI2NInfo;\n  Infos[ifBinary] := @BinaryInfo;\n\n  PFR3G3B2 := PixelFormat(0, 3, 3, 2);\n  PFX5R1G1B1 := PixelFormat(0, 1, 1, 1);\n  PFR5G6B5 := PixelFormat(0, 5, 6, 5);\n  PFA1R5G5B5 := PixelFormat(1, 5, 5, 5);\n  PFA4R4G4B4 := PixelFormat(4, 4, 4, 4);\n  PFX1R5G5B5 := PixelFormat(0, 5, 5, 5);\n  PFX4R4G4B4 := PixelFormat(0, 4, 4, 4);\nend;\n\n\n{ Internal unit helper functions }\n\nfunction PixelFormat(ABitCount, RBitCount, GBitCount, BBitCount: Byte): TPixelFormatInfo;\nbegin\n  Result.ABitMask := ((1 shl ABitCount) - 1) shl (RBitCount + GBitCount +\n    BBitCount);\n  Result.RBitMask := ((1 shl RBitCount) - 1) shl (GBitCount + BBitCount);\n  Result.GBitMask := ((1 shl GBitCount) - 1) shl (BBitCount);\n  Result.BBitMask := (1 shl BBitCount) - 1;\n  Result.ABitCount := ABitCount;\n  Result.RBitCount := RBitCount;\n  Result.GBitCount := GBitCount;\n  Result.BBitCount := BBitCount;\n  Result.AShift := RBitCount + GBitCount + BBitCount;\n  Result.RShift := GBitCount + BBitCount;\n  Result.GShift := BBitCount;\n  Result.BShift := 0;\n  Result.ARecDiv := Max(1, Pow2Int(Result.ABitCount) - 1);\n  Result.RRecDiv := Max(1, Pow2Int(Result.RBitCount) - 1);\n  Result.GRecDiv := Max(1, Pow2Int(Result.GBitCount) - 1);\n  Result.BRecDiv := Max(1, Pow2Int(Result.BBitCount) - 1);\nend;\n\nfunction PixelFormatMask(ABitMask, RBitMask, GBitMask, BBitMask: LongWord): TPixelFormatInfo;\n\n  function GetBitCount(B: LongWord): LongWord;\n  var\n    I: LongWord;\n  begin\n    I := 0;\n    while (I < 31) and (((1 shl I) and B) = 0) do\n      Inc(I);\n    Result := 0;\n    while ((1 shl I) and B) <> 0 do\n    begin\n      Inc(I);\n      Inc(Result);\n    end;\n  end;\n\nbegin\n  Result := PixelFormat(GetBitCount(ABitMask), GetBitCount(RBitMask),\n    GetBitCount(GBitMask), GetBitCount(BBitMask));\nend;\n\nfunction PFSetARGB(const PF: TPixelFormatInfo; A, R, G, B: Byte): TColor32;\n{$IFDEF USE_INLINE}inline;{$ENDIF}\nbegin\n  with PF do\n    Result :=\n      (A shl ABitCount shr 8 shl AShift) or\n      (R shl RBitCount shr 8 shl RShift) or\n      (G shl GBitCount shr 8 shl GShift) or\n      (B shl BBitCount shr 8 shl BShift);\nend;\n\nprocedure PFGetARGB(const PF: TPixelFormatInfo; Color: LongWord;\n  var A, R, G, B: Byte); {$IFDEF USE_INLINE}inline;{$ENDIF}\nbegin\n  with PF do\n  begin\n    A := (Color and ABitMask shr AShift) * 255 div ARecDiv;\n    R := (Color and RBitMask shr RShift) * 255 div RRecDiv;\n    G := (Color and GBitMask shr GShift) * 255 div GRecDiv;\n    B := (Color and BBitMask shl BShift) * 255 div BRecDiv;\n  end;\nend;\n\nfunction PFSetColor(const PF: TPixelFormatInfo; ARGB: TColor32): LongWord;\n{$IFDEF USE_INLINE}inline;{$ENDIF}\nbegin\n  with PF do\n    Result :=\n      (Byte(ARGB shr 24) shl ABitCount shr 8 shl AShift) or\n      (Byte(ARGB shr 16) shl RBitCount shr 8 shl RShift) or\n      (Byte(ARGB shr 8) shl GBitCount shr 8 shl GShift) or\n      (Byte(ARGB) shl BBitCount shr 8 shl BShift);\nend;\n\nfunction PFGetColor(const PF: TPixelFormatInfo; Color: LongWord): TColor32;\n{$IFDEF USE_INLINE}inline;{$ENDIF}\nbegin\n  with PF, TColor32Rec(Result) do\n  begin\n    A := (Color and ABitMask shr AShift) * 255 div ARecDiv;\n    R := (Color and RBitMask shr RShift) * 255 div RRecDiv;\n    G := (Color and GBitMask shr GShift) * 255 div GRecDiv;\n    B := (Color and BBitMask shl BShift) * 255 div BRecDiv;\n  end;\nend;\n\n\n{ Color constructor functions }\n\n\nfunction Color24(R, G, B: Byte): TColor24Rec;\nbegin\n  Result.R := R;\n  Result.G := G;\n  Result.B := B;\nend;\n\nfunction Color32(A, R, G, B: Byte): TColor32Rec;\nbegin\n  Result.A := A;\n  Result.R := R;\n  Result.G := G;\n  Result.B := B;\nend;\n\nfunction Color48(R, G, B: Word): TColor48Rec;\nbegin\n  Result.R := R;\n  Result.G := G;\n  Result.B := B;\nend;\n\nfunction Color64(A, R, G, B: Word): TColor64Rec;\nbegin\n  Result.A := A;\n  Result.R := R;\n  Result.G := G;\n  Result.B := B;\nend;\n\nfunction ColorFP(A, R, G, B: Single): TColorFPRec;\nbegin\n  Result.A := A;\n  Result.R := R;\n  Result.G := G;\n  Result.B := B;\nend;\n\nfunction ColorHF(A, R, G, B: THalfFloat): TColorHFRec;\nbegin\n  Result.A := A;\n  Result.R := R;\n  Result.G := G;\n  Result.B := B;\nend;\n\n\n{ Additional image manipulation functions (usually used internally by Imaging unit) }\n\nconst\n  MaxPossibleColors = 4096;\n  HashSize = 32768;\n  AlphaWeight = 1024;\n  RedWeight = 612;\n  GreenWeight = 1202;\n  BlueWeight = 234;\n\ntype\n  PColorBin = ^TColorBin;\n  TColorBin = record\n    Color: TColor32Rec;\n    Number: LongInt;\n    Next: PColorBin;\n  end;\n\n  THashTable = array[0..HashSize - 1] of PColorBin;\n\n  TColorBox = record\n    AMin, AMax,\n    RMin, RMax,\n    GMin, GMax,\n    BMin, BMax: LongInt;\n    Total: LongInt;\n    Represented: TColor32Rec;\n    List: PColorBin;\n  end;\n\nvar\n  Table: THashTable;\n  Box: array[0..MaxPossibleColors - 1] of TColorBox;\n  Boxes: LongInt;\n  BoxesCreated: Boolean = False;\n\nprocedure ReduceColorsMedianCut(NumPixels: LongInt; Src, Dst: PByte; SrcInfo,\n  DstInfo: PImageFormatInfo; MaxColors: LongInt; ChannelMask: Byte;\n  DstPal: PPalette32; Actions: TReduceColorsActions);\n\n  procedure CreateHistogram (Src: PByte; SrcInfo: PImageFormatInfo;\n    ChannelMask: Byte);\n  var\n    A, R, G, B: Byte;\n    I, Addr: LongInt;\n    PC: PColorBin;\n    Col: TColor32Rec;\n  begin\n    for I := 0 to NumPixels - 1 do\n    begin\n      Col := GetPixel32Generic(Src, SrcInfo, nil);\n      A := Col.A and ChannelMask;\n      R := Col.R and ChannelMask;\n      G := Col.G and ChannelMask;\n      B := Col.B and ChannelMask;\n\n      Addr := (A + 11 * B + 59 * R + 119 * G) mod HashSize;\n      PC := Table[Addr];\n\n      while (PC <> nil) and ((PC.Color.R <> R) or (PC.Color.G <> G) or\n        (PC.Color.B <> B) or (PC.Color.A <> A)) do\n        PC := PC.Next;\n\n      if PC = nil then\n      begin\n        New(PC);\n        PC.Color.R := R;\n        PC.Color.G := G;\n        PC.Color.B := B;\n        PC.Color.A := A;\n        PC.Number := 1;\n        PC.Next := Table[Addr];\n        Table[Addr] := PC;\n      end\n      else\n        Inc(PC^.Number);\n      Inc(Src, SrcInfo.BytesPerPixel);\n    end;\n  end;\n\n  procedure InitBox (var Box : TColorBox);\n  begin\n    Box.AMin := 256;\n    Box.RMin := 256;\n    Box.GMin := 256;\n    Box.BMin := 256;\n    Box.AMax := -1;\n    Box.RMax := -1;\n    Box.GMax := -1;\n    Box.BMax := -1;\n    Box.Total := 0;\n    Box.List := nil;\n  end;\n\n  procedure ChangeBox (var Box: TColorBox; const C: TColorBin);\n  begin\n    with C.Color do\n    begin\n      if A < Box.AMin then Box.AMin := A;\n      if A > Box.AMax then Box.AMax := A;\n      if B < Box.BMin then Box.BMin := B;\n      if B > Box.BMax then Box.BMax := B;\n      if G < Box.GMin then Box.GMin := G;\n      if G > Box.GMax then Box.GMax := G;\n      if R < Box.RMin then Box.RMin := R;\n      if R > Box.RMax then Box.RMax := R;\n    end;\n    Inc(Box.Total, C.Number);\n  end;\n\n  procedure MakeColormap;\n  var\n    I, J: LongInt;\n    CP, Pom: PColorBin;\n    Cut, LargestIdx, Largest, Size, S: LongInt;\n    CutA, CutR, CutG, CutB: Boolean;\n    SumA, SumR, SumG, SumB: LongInt;\n    Temp: TColorBox;\n  begin\n    I := 0;\n    Boxes := 1;\n    LargestIdx := 0;\n    while (I < HashSize) and (Table[I] = nil) do\n      Inc(i);\n    if I < HashSize then\n    begin\n      // put all colors into Box[0]\n      InitBox(Box[0]);\n      repeat\n        CP := Table[I];\n        while CP.Next <> nil do\n        begin\n          ChangeBox(Box[0], CP^);\n          CP := CP.Next;\n        end;\n        ChangeBox(Box[0], CP^);\n        CP.Next := Box[0].List;\n        Box[0].List := Table[I];\n        Table[I] := nil;\n        repeat\n          Inc(I)\n        until (I = HashSize) or (Table[I] <> nil);\n      until I = HashSize;\n      // now all colors are in Box[0]\n      repeat\n        // cut one color box\n        Largest := 0;\n        for I := 0 to Boxes - 1 do\n          with Box[I] do\n          begin\n            Size := (AMax - AMin) * AlphaWeight;\n            S := (RMax - RMin) * RedWeight;\n            if S > Size then\n              Size := S;\n            S := (GMax - GMin) * GreenWeight;\n            if S > Size then\n              Size := S;\n            S := (BMax - BMin) * BlueWeight;\n            if S > Size then\n              Size := S;\n            if Size > Largest then\n            begin\n              Largest := Size;\n              LargestIdx := I;\n            end;\n          end;\n        if Largest > 0 then\n        begin\n          // cutting Box[LargestIdx] into Box[LargestIdx] and Box[Boxes]\n          CutR := False;\n          CutG := False;\n          CutB := False;\n          CutA := False;\n          with Box[LargestIdx] do\n          begin\n            if (AMax - AMin) * AlphaWeight = Largest then\n            begin\n              Cut := (AMax + AMin) shr 1;\n              CutA := True;\n            end\n            else\n              if (RMax - RMin) * RedWeight = Largest then\n              begin\n                Cut := (RMax + RMin) shr 1;\n                CutR := True;\n              end\n              else\n                if (GMax - GMin) * GreenWeight = Largest then\n                begin\n                  Cut := (GMax + GMin) shr 1;\n                  CutG := True;\n                end\n                else\n                begin\n                  Cut := (BMax + BMin) shr 1;\n                  CutB := True;\n                end;\n            CP := List;\n          end;\n          InitBox(Box[LargestIdx]);\n          InitBox(Box[Boxes]);\n          repeat\n            // distribute one color\n            Pom := CP.Next;\n            with CP.Color do\n            begin\n              if (CutA and (A <= Cut)) or (CutR and (R <= Cut)) or\n                (CutG and (G <= Cut)) or (CutB and (B <= Cut)) then\n                I := LargestIdx\n              else\n                I := Boxes;\n            end;\n            CP.Next := Box[i].List;\n            Box[i].List := CP;\n            ChangeBox(Box[i], CP^);\n            CP := Pom;\n          until CP = nil;\n          Inc(Boxes);\n        end;\n      until (Boxes = MaxColors) or (Largest = 0);\n      // compute box representation\n      for I := 0 to Boxes - 1 do\n      begin\n        SumR := 0;\n        SumG := 0;\n        SumB := 0;\n        SumA := 0;\n        repeat\n          CP := Box[I].List;\n          Inc(SumR, CP.Color.R * CP.Number);\n          Inc(SumG, CP.Color.G * CP.Number);\n          Inc(SumB, CP.Color.B * CP.Number);\n          Inc(SumA, CP.Color.A * CP.Number);\n          Box[I].List := CP.Next;\n          Dispose(CP);\n        until Box[I].List = nil;\n        with Box[I] do\n        begin\n          Represented.A := SumA div Total;\n          Represented.R := SumR div Total;\n          Represented.G := SumG div Total;\n          Represented.B := SumB div Total;\n          AMin := AMin and ChannelMask;\n          RMin := RMin and ChannelMask;\n          GMin := GMin and ChannelMask;\n          BMin := BMin and ChannelMask;\n          AMax := (AMax and ChannelMask) + (not ChannelMask);\n          RMax := (RMax and ChannelMask) + (not ChannelMask);\n          GMax := (GMax and ChannelMask) + (not ChannelMask);\n          BMax := (BMax and ChannelMask) + (not ChannelMask);\n        end;\n      end;\n      // sort color boxes\n      for I := 0 to Boxes - 2 do\n      begin\n        Largest := 0;\n        for J := I to Boxes - 1 do\n          if Box[J].Total > Largest then\n          begin\n            Largest := Box[J].Total;\n            LargestIdx := J;\n          end;\n        if LargestIdx <> I then\n        begin\n          Temp := Box[I];\n          Box[I] := Box[LargestIdx];\n          Box[LargestIdx] := Temp;\n        end;\n      end;\n    end;\n  end;\n\n  procedure FillOutputPalette;\n  var\n    I: LongInt;\n  begin\n    FillChar(DstPal^, SizeOf(TColor32Rec) * MaxColors, $FF);\n    for I := 0 to MaxColors - 1 do\n    begin\n      if I < Boxes then\n      with Box[I].Represented do\n      begin\n        DstPal[I].A := A;\n        DstPal[I].R := R;\n        DstPal[I].G := G;\n        DstPal[I].B := B;\n      end\n      else\n        DstPal[I].Color := $FF000000;\n    end;\n  end;\n\n  function MapColor(const Col: TColor32Rec) : LongInt;\n  var\n    I: LongInt;\n  begin\n    I := 0;\n    with Col do\n      while (I < Boxes) and ((Box[I].AMin > A) or (Box[I].AMax < A) or\n        (Box[I].RMin > R) or (Box[I].RMax < R) or (Box[I].GMin > G) or\n        (Box[I].GMax < G) or (Box[I].BMin > B) or (Box[I].BMax < B)) do\n        Inc(I);\n    if I = Boxes then\n      MapColor := 0\n    else\n      MapColor := I;\n  end;\n\n  procedure MapImage(Src, Dst: PByte; SrcInfo, DstInfo: PImageFormatInfo);\n  var\n    I: LongInt;\n    Col: TColor32Rec;\n  begin\n    for I := 0 to NumPixels - 1 do\n    begin\n      Col := GetPixel32Generic(Src, SrcInfo, nil);\n      IndexSetDstPixel(Dst, DstInfo, MapColor(Col));\n      Inc(Src, SrcInfo.BytesPerPixel);\n      Inc(Dst, DstInfo.BytesPerPixel);\n    end;\n  end;\n\nbegin\n  MaxColors := ClampInt(MaxColors, 2, MaxPossibleColors);\n\n  if (raUpdateHistogram in Actions) or (raMapImage in Actions) then\n  begin\n    Assert(not SrcInfo.IsSpecial);\n    Assert(not SrcInfo.IsIndexed);\n  end;\n\n  if raCreateHistogram in Actions then\n    FillChar(Table, SizeOf(Table), 0);\n\n  if raUpdateHistogram in Actions then\n    CreateHistogram(Src, SrcInfo, ChannelMask);\n\n  if raMakeColorMap in Actions then\n  begin\n    MakeColorMap;\n    FillOutputPalette;\n  end;\n\n  if raMapImage in Actions then\n    MapImage(Src, Dst, SrcInfo, DstInfo);\nend;\n\nprocedure StretchNearest(const SrcImage: TImageData; SrcX, SrcY, SrcWidth,\n  SrcHeight: LongInt; var DstImage: TImageData; DstX, DstY, DstWidth,\n  DstHeight: LongInt);\nvar\n  Info: TImageFormatInfo;\n  ScaleX, ScaleY, X, Y, Xp, Yp: LongInt;\n  DstPixel, SrcLine: PByte;\nbegin\n  GetImageFormatInfo(SrcImage.Format, Info);\n  Assert(SrcImage.Format = DstImage.Format);\n  Assert(not Info.IsSpecial);\n  // Use integers instead of floats for source image pixel coords\n  // Xp and Yp coords must be shifted right to get read source image coords\n  ScaleX := (SrcWidth shl 16) div DstWidth;\n  ScaleY := (SrcHeight shl 16) div DstHeight;\n  Yp := 0;\n  for Y := 0 to DstHeight - 1 do\n  begin\n    Xp := 0;\n    SrcLine := @PByteArray(SrcImage.Bits)[((SrcY + Yp shr 16) * SrcImage.Width + SrcX) * Info.BytesPerPixel];\n    DstPixel := @PByteArray(DstImage.Bits)[((DstY + Y) * DstImage.Width + DstX) * Info.BytesPerPixel];\n    for X := 0 to DstWidth - 1 do\n    begin\n      case Info.BytesPerPixel of\n        1: PByte(DstPixel)^ := PByteArray(SrcLine)[Xp shr 16];\n        2: PWord(DstPixel)^ := PWordArray(SrcLine)[Xp shr 16];\n        3: PColor24Rec(DstPixel)^ := PPalette24(SrcLine)[Xp shr 16];\n        4: PColor32(DstPixel)^ := PLongWordArray(SrcLine)[Xp shr 16];\n        6: PColor48Rec(DstPixel)^ := PColor48RecArray(SrcLine)[Xp shr 16];\n        8: PColor64(DstPixel)^ := PInt64Array(SrcLine)[Xp shr 16];\n        16: PColorFPRec(DstPixel)^ := PColorFPRecArray(SrcLine)[Xp shr 16];\n      end;\n      Inc(DstPixel, Info.BytesPerPixel);\n      Inc(Xp, ScaleX);\n    end;\n    Inc(Yp, ScaleY);\n  end;\nend;\n\n{ Filter function for nearest filtering. Also known as box filter.}\nfunction FilterNearest(Value: Single): Single;\nbegin\n  if (Value > -0.5) and (Value <= 0.5) then\n    Result := 1\n  else\n    Result := 0;\nend;\n\n{ Filter function for linear filtering. Also known as triangle or Bartlett filter.}\nfunction FilterLinear(Value: Single): Single;\nbegin\n  if Value < 0.0 then\n    Value := -Value;\n  if Value < 1.0 then\n    Result := 1.0 - Value\n  else\n    Result := 0.0;\nend;\n\n{ Cosine filter.}\nfunction FilterCosine(Value: Single): Single;\nbegin\n  Result := 0;\n  if Abs(Value) < 1 then\n    Result := (Cos(Value * Pi) + 1) / 2;\nend;\n\n{ f(t) = 2|t|^3 - 3|t|^2 + 1, -1 <= t <= 1 }\nfunction FilterHermite(Value: Single): Single;\nbegin\n  if Value < 0.0 then\n    Value := -Value;\n  if Value < 1 then\n    Result := (2 * Value - 3) * Sqr(Value) + 1\n  else\n    Result := 0;\nend;\n\n{ Quadratic filter. Also known as Bell.}\nfunction FilterQuadratic(Value: Single): Single;\nbegin\n  if Value < 0.0 then\n    Value := -Value;\n  if Value < 0.5 then\n    Result := 0.75 - Sqr(Value)\n  else\n  if Value < 1.5 then\n  begin\n    Value := Value - 1.5;\n    Result := 0.5 * Sqr(Value);\n  end\n  else\n    Result := 0.0;\nend;\n\n{ Gaussian filter.}\nfunction FilterGaussian(Value: Single): Single;\nbegin\n  Result := Exp(-2.0 * Sqr(Value)) * Sqrt(2.0 / Pi);\nend;\n\n{ 4th order (cubic) b-spline filter.}\nfunction FilterSpline(Value: Single): Single;\nvar\n  Temp: Single;\nbegin\n  if Value < 0.0 then\n    Value := -Value;\n  if Value < 1.0 then\n  begin\n    Temp := Sqr(Value);\n    Result := 0.5 * Temp * Value - Temp + 2.0 / 3.0;\n  end\n  else\n  if Value < 2.0 then\n  begin\n    Value := 2.0 - Value;\n    Result := Sqr(Value) * Value / 6.0;\n  end\n  else\n    Result := 0.0;\nend;\n\n{ Lanczos-windowed sinc filter.}\nfunction FilterLanczos(Value: Single): Single;\n\n  function SinC(Value: Single): Single;\n  begin\n    if Value <> 0.0 then\n    begin\n      Value := Value * Pi;\n      Result := Sin(Value) / Value;\n    end\n    else\n      Result := 1.0;\n  end;\n\nbegin\n  if Value < 0.0 then\n    Value := -Value;\n  if Value < 3.0 then\n    Result := SinC(Value) * SinC(Value / 3.0)\n  else\n    Result := 0.0;\nend;\n\n{ Micthell cubic filter.}\nfunction FilterMitchell(Value: Single): Single;\nconst\n  B = 1.0 / 3.0;\n  C = 1.0 / 3.0;\nvar\n  Temp: Single;\nbegin\n  if Value < 0.0 then\n    Value := -Value;\n  Temp := Sqr(Value);\n  if Value < 1.0 then\n  begin\n    Value := (((12.0 - 9.0 * B - 6.0 * C) * (Value * Temp)) +\n      ((-18.0 + 12.0 * B + 6.0 * C) * Temp) +\n      (6.0 - 2.0 * B));\n    Result := Value / 6.0;\n  end\n  else\n  if Value < 2.0 then\n  begin\n    Value := (((-B - 6.0 * C) * (Value * Temp)) +\n      ((6.0 * B + 30.0 * C) * Temp) +\n      ((-12.0 * B - 48.0 * C) * Value) +\n      (8.0 * B + 24.0 * C));\n    Result := Value / 6.0;\n  end\n  else\n    Result := 0.0;\nend;\n\n{ CatmullRom spline filter.}\nfunction FilterCatmullRom(Value: Single): Single;\nbegin\n  if Value < 0.0 then\n    Value := -Value;\n  if Value < 1.0 then\n    Result := 0.5 * (2.0 + Sqr(Value) * (-5.0 + 3.0 * Value))\n  else\n  if Value < 2.0 then\n    Result := 0.5 * (4.0 + Value * (-8.0 + Value * (5.0 - Value)))\n  else\n    Result := 0.0;\nend;\n\nprocedure StretchResample(const SrcImage: TImageData; SrcX, SrcY, SrcWidth,\n  SrcHeight: LongInt; var DstImage: TImageData; DstX, DstY, DstWidth,\n  DstHeight: LongInt; Filter: TSamplingFilter; WrapEdges: Boolean);\nbegin\n  // Calls the other function with filter function and radius defined by Filter\n  StretchResample(SrcImage, SrcX, SrcY, SrcWidth, SrcHeight, DstImage, DstX, DstY,\n    DstWidth, DstHeight, SamplingFilterFunctions[Filter], SamplingFilterRadii[Filter],\n    WrapEdges);\nend;\n\nvar\n  FullEdge: Boolean = True;\n\n{ The following resampling code is modified and extended code from Graphics32\n  library by Alex A. Denisov.}\nfunction BuildMappingTable(DstLow, DstHigh, SrcLow, SrcHigh, SrcImageWidth: LongInt;\n  Filter: TFilterFunction; Radius: Single; WrapEdges: Boolean): TMappingTable;\nvar\n  I, J, K, N: LongInt;\n  Left, Right, SrcWidth, DstWidth: LongInt;\n  Weight, Scale, Center, Count: Single;\nbegin\n  Result := nil;\n  K := 0;\n  SrcWidth := SrcHigh - SrcLow;\n  DstWidth := DstHigh - DstLow;\n\n  // Check some special cases\n  if SrcWidth = 1 then\n  begin\n    SetLength(Result, DstWidth);\n    for I := 0 to DstWidth - 1 do\n    begin\n      SetLength(Result[I], 1);\n      Result[I][0].Pos := 0;\n      Result[I][0].Weight := 1.0;\n    end;\n    Exit;\n  end\n  else\n  if (SrcWidth = 0) or (DstWidth = 0) then\n    Exit;\n\n  if FullEdge then\n    Scale := DstWidth / SrcWidth\n  else\n    Scale := (DstWidth - 1) / (SrcWidth - 1);\n\n  SetLength(Result, DstWidth);\n\n  // Pre-calculate filter contributions for a row or column\n  if Scale = 0.0 then\n  begin\n    Assert(Length(Result) = 1);\n    SetLength(Result[0], 1);\n    Result[0][0].Pos := (SrcLow + SrcHigh) div 2;\n    Result[0][0].Weight := 1.0;\n  end\n  else if Scale < 1.0 then\n  begin\n    // Sub-sampling - scales from bigger to smaller \n    Radius := Radius / Scale;\n    for I := 0 to DstWidth - 1 do\n    begin\n      if FullEdge then\n        Center := SrcLow - 0.5 + (I + 0.5) / Scale\n      else\n        Center := SrcLow + I / Scale;\n      Left := Floor(Center - Radius);\n      Right := Ceil(Center + Radius);\n      Count := -1.0;\n      for J := Left to Right do\n      begin\n        Weight := Filter((Center - J) * Scale) * Scale;\n        if Weight <> 0.0 then\n        begin\n          Count := Count + Weight;\n          K := Length(Result[I]);\n          SetLength(Result[I], K + 1);\n          Result[I][K].Pos := ClampInt(J, SrcLow, SrcHigh - 1);\n          Result[I][K].Weight := Weight;\n        end;\n      end;\n      if Length(Result[I]) = 0 then\n      begin\n        SetLength(Result[I], 1);\n        Result[I][0].Pos := Floor(Center);\n        Result[I][0].Weight := 1.0;\n      end\n      else if Count <> 0.0 then\n        Result[I][K div 2].Weight := Result[I][K div 2].Weight - Count;\n    end;\n  end\n  else // if Scale > 1.0 then\n  begin\n    // Super-sampling - scales from smaller to bigger\n    Scale := 1.0 / Scale;\n    for I := 0 to DstWidth - 1 do\n    begin\n      if FullEdge then\n        Center := SrcLow - 0.5 + (I + 0.5) * Scale\n      else\n        Center := SrcLow + I * Scale;\n      Left := Floor(Center - Radius);\n      Right := Ceil(Center + Radius);\n      Count := -1.0;\n      for J := Left to Right do\n      begin\n        Weight := Filter(Center - J);\n        if Weight <> 0.0 then\n        begin\n          Count := Count + Weight;\n          K := Length(Result[I]);\n          SetLength(Result[I], K + 1);\n\n          if WrapEdges then\n          begin\n            if J < 0 then\n              N := SrcImageWidth + J\n            else if J >= SrcImageWidth then\n              N := J - SrcImageWidth\n            else\n              N := ClampInt(J, SrcLow, SrcHigh - 1);\n          end\n          else\n            N := ClampInt(J, SrcLow, SrcHigh - 1);\n\n          Result[I][K].Pos := N;\n          Result[I][K].Weight := Weight;\n        end;\n      end;\n      if Count <> 0.0 then\n        Result[I][K div 2].Weight := Result[I][K div 2].Weight - Count;\n    end;\n  end;\nend;\n\nprocedure FindExtremes(const Map: TMappingTable; var MinPos, MaxPos: LongInt);\nvar\n  I, J: LongInt;\nbegin\n  if Length(Map) > 0 then\n  begin\n    MinPos := Map[0][0].Pos;\n    MaxPos := MinPos;\n    for I := 0 to Length(Map) - 1 do\n      for J := 0 to Length(Map[I]) - 1 do\n      begin\n        if MinPos > Map[I][J].Pos then\n          MinPos := Map[I][J].Pos;\n        if MaxPos < Map[I][J].Pos then\n          MaxPos := Map[I][J].Pos;\n      end;\n  end;\nend;\n\nprocedure StretchResample(const SrcImage: TImageData; SrcX, SrcY, SrcWidth,\n  SrcHeight: LongInt; var DstImage: TImageData; DstX, DstY, DstWidth,\n  DstHeight: LongInt; Filter: TFilterFunction; Radius: Single; WrapEdges: Boolean);\nconst\n  Channel8BitMax: Single = 255.0;\nvar\n  MapX, MapY: TMappingTable;\n  I, J, X, Y: LongInt;\n  XMinimum, XMaximum: LongInt;\n  LineBufferFP: array of TColorFPRec;\n  ClusterX, ClusterY: TCluster;\n  Weight, AccumA, AccumR, AccumG, AccumB: Single;\n  DstLine: PByte;\n  SrcFloat: TColorFPRec;\n  Info: TImageFormatInfo;\n  BytesPerChannel: LongInt;\nbegin\n  GetImageFormatInfo(SrcImage.Format, Info);\n  Assert(SrcImage.Format = DstImage.Format);\n  Assert(not Info.IsSpecial and not Info.IsIndexed);\n  BytesPerChannel := Info.BytesPerPixel div Info.ChannelCount;\n\n  // Create horizontal and vertical mapping tables\n  MapX := BuildMappingTable(DstX, DstX + DstWidth, SrcX, SrcX + SrcWidth,\n    SrcImage.Width, Filter, Radius, WrapEdges);\n  MapY := BuildMappingTable(DstY, DstY + DstHeight, SrcY, SrcY + SrcHeight,\n    SrcImage.Height, Filter, Radius, WrapEdges);\n\n  if (MapX = nil) or (MapY = nil) then\n    Exit;\n\n  ClusterX := nil;\n  ClusterY := nil;\n\n  try\n    // Find min and max X coords of pixels that will contribute to target image\n    FindExtremes(MapX, XMinimum, XMaximum);\n\n    SetLength(LineBufferFP, XMaximum - XMinimum + 1);\n    // Following code works for the rest of data formats\n    for J := 0 to DstHeight - 1 do\n    begin\n      // First for each pixel in the current line sample vertically\n      // and store results in LineBuffer. Then sample horizontally\n      // using values in LineBuffer.\n      ClusterY := MapY[J];\n      for X := XMinimum to XMaximum do\n      begin\n        // Clear accumulators\n        AccumA := 0;\n        AccumR := 0;\n        AccumG := 0;\n        AccumB := 0;\n        // For each pixel in line compute weighted sum of pixels\n        // in source column that will contribute to this pixel\n        for Y := 0 to Length(ClusterY) - 1 do\n        begin\n          // Accumulate this pixel's weighted value\n          Weight := ClusterY[Y].Weight;\n          SrcFloat := Info.GetPixelFP(@PByteArray(SrcImage.Bits)[(ClusterY[Y].Pos * SrcImage.Width + X) * Info.BytesPerPixel], @Info, nil);\n          AccumB := AccumB + SrcFloat.B * Weight;\n          AccumG := AccumG + SrcFloat.G * Weight;\n          AccumR := AccumR + SrcFloat.R * Weight;\n          AccumA := AccumA + SrcFloat.A * Weight;\n        end;\n        // Store accumulated value for this pixel in buffer\n        with LineBufferFP[X - XMinimum] do\n        begin\n          A := AccumA;\n          R := AccumR;\n          G := AccumG;\n          B := AccumB;\n        end;\n      end;\n\n      DstLine := @PByteArray(DstImage.Bits)[((J + DstY) * DstImage.Width + DstX) * Info.BytesPerPixel];\n      // Now compute final colors for targte pixels in the current row\n      // by sampling horizontally\n      for I := 0 to DstWidth - 1 do\n      begin\n        ClusterX := MapX[I];\n        // Clear accumulator\n        AccumA := 0;\n        AccumR := 0;\n        AccumG := 0;\n        AccumB := 0;\n        // Compute weighted sum of values (which are already\n        // computed weighted sums of pixels in source columns stored in LineBuffer)\n        // that will contribute to the current target pixel\n        for X := 0 to Length(ClusterX) - 1 do\n        begin\n          Weight := ClusterX[X].Weight;\n          with LineBufferFP[ClusterX[X].Pos - XMinimum] do\n          begin\n            AccumB := AccumB + B * Weight;\n            AccumG := AccumG + G * Weight;\n            AccumR := AccumR + R * Weight;\n            AccumA := AccumA + A * Weight;\n          end;\n        end;\n\n        // Now compute final color to be written to dest image\n        SrcFloat.A := AccumA;\n        SrcFloat.R := AccumR;\n        SrcFloat.G := AccumG;\n        SrcFloat.B := AccumB;\n\n        Info.SetPixelFP(DstLine, @Info, nil, SrcFloat);\n        Inc(DstLine, Info.BytesPerPixel);\n      end;\n    end;\n\n  finally\n    MapX := nil;\n    MapY := nil;\n  end;\nend;\n\nprocedure FillMipMapLevel(const BiggerLevel: TImageData; Width, Height: LongInt;\n  var SmallerLevel: TImageData);\nvar\n  Filter: TSamplingFilter;\n  Info: TImageFormatInfo;\n  CompatibleCopy: TImageData;\nbegin\n  Assert(TestImage(BiggerLevel));\n  Filter := TSamplingFilter(GetOption(ImagingMipMapFilter));\n\n  // If we have special format image we must create copy to allow pixel access\n  GetImageFormatInfo(BiggerLevel.Format, Info);\n  if Info.IsSpecial then\n  begin\n    InitImage(CompatibleCopy);\n    CloneImage(BiggerLevel, CompatibleCopy);\n    ConvertImage(CompatibleCopy, ifDefault);\n  end\n  else\n    CompatibleCopy := BiggerLevel;\n\n  // Create new smaller image\n  NewImage(Width, Height, CompatibleCopy.Format, SmallerLevel);\n  GetImageFormatInfo(CompatibleCopy.Format, Info);\n  // If input is indexed we must copy its palette\n  if Info.IsIndexed then\n    CopyPalette(CompatibleCopy.Palette, SmallerLevel.Palette, 0, 0, Info.PaletteEntries);\n\n  if (Filter = sfNearest) or Info.IsIndexed then\n  begin\n    StretchNearest(CompatibleCopy, 0, 0, CompatibleCopy.Width, CompatibleCopy.Height,\n      SmallerLevel, 0, 0, Width, Height);\n  end\n  else\n  begin\n    StretchResample(CompatibleCopy, 0, 0, CompatibleCopy.Width, CompatibleCopy.Height,\n      SmallerLevel, 0, 0, Width, Height, Filter);\n  end;\n\n  // Free copy and convert result to special format if necessary\n  if CompatibleCopy.Format <> BiggerLevel.Format then\n  begin\n    ConvertImage(SmallerLevel, BiggerLevel.Format);\n    FreeImage(CompatibleCopy);\n  end;\nend;\n\n\n{ Various format support functions }\n\nprocedure CopyPixel(Src, Dest: Pointer; BytesPerPixel: LongInt);\nbegin\n  case BytesPerPixel of\n    1: PByte(Dest)^ := PByte(Src)^;\n    2: PWord(Dest)^ := PWord(Src)^;\n    3: PColor24Rec(Dest)^ := PColor24Rec(Src)^;\n    4: PLongWord(Dest)^ := PLongWord(Src)^;\n    6: PColor48Rec(Dest)^ := PColor48Rec(Src)^;\n    8: PInt64(Dest)^ := PInt64(Src)^;\n    12: PColor96FPRec(Dest)^ := PColor96FPRec(Src)^;\n    16: PColorFPRec(Dest)^ := PColorFPRec(Src)^;\n  end;\nend;\n\nfunction ComparePixels(PixelA, PixelB: Pointer; BytesPerPixel: LongInt): Boolean;\nbegin\n  case BytesPerPixel of\n    1: Result := PByte(PixelA)^ = PByte(PixelB)^;\n    2: Result := PWord(PixelA)^ = PWord(PixelB)^;\n    3: Result := (PWord(PixelA)^ = PWord(PixelB)^) and (PColor24Rec(PixelA).R = PColor24Rec(PixelB).R);\n    4: Result := PLongWord(PixelA)^ = PLongWord(PixelB)^;\n    6: Result := (PLongWord(PixelA)^ = PLongWord(PixelB)^) and (PColor48Rec(PixelA).R = PColor48Rec(PixelB).R);\n    8: Result := PInt64(PixelA)^ = PInt64(PixelB)^;\n    12: Result := (PFloatHelper(PixelA).Data = PFloatHelper(PixelB).Data) and\n          (PFloatHelper(PixelA).Data32 = PFloatHelper(PixelB).Data32);\n    16: Result := (PFloatHelper(PixelA).Data = PFloatHelper(PixelB).Data) and\n          (PFloatHelper(PixelA).Data64 = PFloatHelper(PixelB).Data64);\n  else\n    Result := False;\n  end;\nend;\n\nprocedure TranslatePixel(SrcPixel, DstPixel: Pointer; SrcFormat,\n  DstFormat: TImageFormat; SrcPalette, DstPalette: PPalette32);\nvar\n  SrcInfo, DstInfo: PImageFormatInfo;\n  PixFP: TColorFPRec;\nbegin\n  SrcInfo := FInfos[SrcFormat];\n  DstInfo := FInfos[DstFormat];\n\n  PixFP := GetPixelFPGeneric(SrcPixel, SrcInfo, SrcPalette);\n  SetPixelFPGeneric(DstPixel, DstInfo, DstPalette, PixFP);\nend;\n\nprocedure ClampFloatPixel(var PixF: TColorFPRec);\nbegin\n  if PixF.A > 1.0 then\n    PixF.A := 1.0;\n  if PixF.R > 1.0 then\n    PixF.R := 1.0;\n  if PixF.G > 1.0 then\n    PixF.G := 1.0;\n  if PixF.B > 1.0 then\n    PixF.B := 1.0;\n\n  if PixF.A < 0.0 then\n    PixF.A := 0.0;\n  if PixF.R < 0.0 then\n    PixF.R := 0.0;\n  if PixF.G < 0.0 then\n    PixF.G := 0.0;\n  if PixF.B < 0.0 then\n    PixF.B := 0.0;\nend;\n\nprocedure ConvertToPixel32(SrcPix: PByte; DestPix: PColor32Rec;\n  const SrcInfo: TImageFormatInfo; SrcPalette: PPalette32);\nbegin\n  case SrcInfo.Format of\n    ifIndex8:\n      begin\n        DestPix^ := SrcPalette[SrcPix^];\n      end;\n    ifGray8:\n      begin\n        DestPix.R := SrcPix^;\n        DestPix.G := SrcPix^;\n        DestPix.B := SrcPix^;\n        DestPix.A := 255;\n      end;\n    ifA8Gray8:\n      begin\n        DestPix.R := SrcPix^;\n        DestPix.G := SrcPix^;\n        DestPix.B := SrcPix^;\n        DestPix.A := PWordRec(SrcPix).High;\n      end;\n    ifGray16:\n      begin\n        DestPix.R := PWord(SrcPix)^ shr 8;\n        DestPix.G := DestPix.R;\n        DestPix.B := DestPix.R;\n        DestPix.A := 255;\n      end;\n    ifR8G8B8:\n      begin\n        DestPix.Color24Rec := PColor24Rec(SrcPix)^;\n        DestPix.A := 255;\n      end;\n    ifA8R8G8B8:\n      begin\n        DestPix^ := PColor32Rec(SrcPix)^;\n      end;\n    ifR16G16B16:\n      begin\n        DestPix.R := PColor48Rec(SrcPix).R shr 8;\n        DestPix.G := PColor48Rec(SrcPix).G shr 8;\n        DestPix.B := PColor48Rec(SrcPix).B shr 8;\n        DestPix.A := 255;\n      end;\n    ifA16R16G16B16:\n      begin\n        DestPix.R := PColor64Rec(SrcPix).R shr 8;\n        DestPix.G := PColor64Rec(SrcPix).G shr 8;\n        DestPix.B := PColor64Rec(SrcPix).B shr 8;\n        DestPix.A := PColor64Rec(SrcPix).A shr 8;\n      end;\n  else\n    DestPix^ := SrcInfo.GetPixel32(SrcPix, @SrcInfo, SrcPalette);\n  end;\nend;\n\nprocedure AddPadBytes(DataIn: Pointer; DataOut: Pointer; Width, Height,\n  Bpp, WidthBytes: LongInt);\nvar\n  I, W: LongInt;\nbegin\n  W := Width * Bpp;\n  for I := 0 to Height - 1 do\n    Move(PByteArray(DataIn)[I * W], PByteArray(DataOut)[I * WidthBytes], W);\nend;\n\nprocedure RemovePadBytes(DataIn: Pointer; DataOut: Pointer; Width, Height,\n  Bpp, WidthBytes: LongInt);\nvar\n  I, W: LongInt;\nbegin\n  W := Width * Bpp;\n  for I := 0 to Height - 1 do\n    Move(PByteArray(DataIn)[I * WidthBytes], PByteArray(DataOut)[I * W], W);\nend;\n\nprocedure Convert1To8(DataIn, DataOut: PByte; Width, Height,\n  WidthBytes: LongInt; ScaleTo8Bits: Boolean);\nconst\n  Mask1: array[0..7] of Byte = ($80, $40, $20, $10, $08, $04, $02, $01);\n  Shift1: array[0..7] of Byte = (7, 6, 5, 4, 3, 2, 1, 0);\n  Scaling: Byte = 255;\nvar\n  X, Y: LongInt;\n  InArray: PByteArray absolute DataIn;\nbegin\n  for Y := 0 to Height - 1 do\n    for X := 0 to Width - 1 do\n    begin\n      DataOut^ := (InArray[Y * WidthBytes + X shr 3] and Mask1[X and 7]) shr Shift1[X and 7];\n      if ScaleTo8Bits then\n        DataOut^ := DataOut^ * Scaling;\n      Inc(DataOut);\n    end;\nend;\n\nprocedure Convert2To8(DataIn, DataOut: PByte; Width, Height,\n  WidthBytes: LongInt; ScaleTo8Bits: Boolean);\nconst\n  Mask2: array[0..3] of Byte = ($C0, $30, $0C, $03);\n  Shift2: array[0..3] of Byte = (6, 4, 2, 0);\n  Scaling: Byte = 85;\nvar\n  X, Y: LongInt;\n  InArray: PByteArray absolute DataIn;\nbegin\n  for Y := 0 to Height - 1 do\n    for X := 0 to Width - 1 do\n    begin\n      DataOut^ := (InArray[Y * WidthBytes + X shr 2] and Mask2[X and 3]) shr Shift2[X and 3];\n      if ScaleTo8Bits then\n        DataOut^ := DataOut^ * Scaling;\n      Inc(DataOut);\n    end;\nend;\n\nprocedure Convert4To8(DataIn, DataOut: PByte; Width, Height,\n  WidthBytes: LongInt; ScaleTo8Bits: Boolean);\nconst\n  Mask4: array[0..1] of Byte = ($F0, $0F);\n  Shift4: array[0..1] of Byte = (4, 0);\n  Scaling: Byte = 17;\nvar\n  X, Y: LongInt;\n  InArray: PByteArray absolute DataIn;\nbegin\n  for Y := 0 to Height - 1 do\n    for X := 0 to Width - 1 do\n    begin\n      DataOut^ := (InArray[Y * WidthBytes + X shr 1] and  Mask4[X and 1]) shr Shift4[X and 1];\n      if ScaleTo8Bits then\n        DataOut^ := DataOut^ * Scaling;\n      Inc(DataOut);\n    end;\nend;\n\nfunction Has16BitImageAlpha(NumPixels: LongInt; Data: PWord): Boolean;\nvar\n  I: LongInt;\nbegin\n  Result := False;\n  for I := 0 to NumPixels - 1 do\n  begin\n    if Data^ >= 1 shl 15 then\n    begin\n      Result := True;\n      Exit;\n    end;\n    Inc(Data);\n  end;\nend;\n\nfunction Has32BitImageAlpha(NumPixels: LongInt; Data: PLongWord): Boolean;\nvar\n  I: LongInt;\nbegin\n  Result := False;\n  for I := 0 to NumPixels - 1 do\n  begin\n    if Data^ >= 1 shl 24 then\n    begin\n      Result := True;\n      Exit;\n    end;\n    Inc(Data);\n  end;\nend;\n\nfunction PaletteHasAlpha(Palette: PPalette32; PaletteEntries: Integer): Boolean;\nvar\n  I: Integer;\nbegin\n  for I := 0 to PaletteEntries - 1 do\n  begin\n    if Palette[I].A <> 255 then\n    begin\n      Result := True;\n      Exit;\n    end;\n  end;\n  Result := False;\nend;\n\nfunction GetScanLine(ImageBits: Pointer; const FormatInfo: TImageFormatInfo;\n  LineWidth, Index: LongInt): Pointer;\nvar\n  LineBytes: LongInt;\nbegin\n  Assert(not FormatInfo.IsSpecial);\n  LineBytes := FormatInfo.GetPixelsSize(FormatInfo.Format, LineWidth, 1);\n  Result := @PByteArray(ImageBits)[Index * LineBytes];\nend;\n\nfunction IsImageFormatValid(Format: TImageFormat): Boolean;\nbegin\n  Result := FInfos[Format] <> nil;\nend;\n\nconst\n  HalfMin:     Single = 5.96046448e-08; // Smallest positive half\n  HalfMinNorm: Single = 6.10351562e-05; // Smallest positive normalized half\n  HalfMax:     Single = 65504.0;        // Largest positive half\n  HalfEpsilon: Single = 0.00097656;     // Smallest positive e for which half (1.0 + e) != half (1.0)\n  HalfNaN:     THalfFloat = 65535;\n  HalfPosInf:  THalfFloat = 31744;\n  HalfNegInf:  THalfFloat = 64512;\n\n\n{\n  Half/Float conversions inspired by half class from OpenEXR library.\n\n  Float (Pascal Single type) is an IEEE 754 single-precision\n  floating point number.\n\n  Bit layout of Single:\n\n    31 (msb)\n    |\n    | 30     23\n    | |      |\n    | |      | 22                    0 (lsb)\n    | |      | |                     |\n    X XXXXXXXX XXXXXXXXXXXXXXXXXXXXXXX\n    s e        m\n\n  Bit layout of half:\n\n    15 (msb)\n    |\n    | 14  10\n    | |   |\n    | |   | 9        0 (lsb)\n    | |   | |        |\n    X XXXXX XXXXXXXXXX\n    s e     m\n\n  S is the sign-bit, e is the exponent and m is the significand (mantissa).\n}\n\nfunction HalfToFloat(Half: THalfFloat): Single;\nvar\n  Dst, Sign, Mantissa: LongWord;\n  Exp: LongInt;\nbegin\n  // Extract sign, exponent, and mantissa from half number\n  Sign := Half shr 15;\n  Exp := (Half and $7C00) shr 10;\n  Mantissa := Half and 1023;\n\n  if (Exp > 0) and (Exp < 31) then\n  begin\n    // Common normalized number\n    Exp := Exp + (127 - 15);\n    Mantissa := Mantissa shl 13;\n    Dst := (Sign shl 31) or (LongWord(Exp) shl 23) or Mantissa;\n    // Result := Power(-1, Sign) * Power(2, Exp - 15) * (1 + Mantissa / 1024);\n  end\n  else if (Exp = 0) and (Mantissa = 0) then\n  begin\n    // Zero - preserve sign\n    Dst := Sign shl 31;\n  end\n  else if (Exp = 0) and (Mantissa <> 0) then\n  begin\n    // Denormalized number - renormalize it\n    while (Mantissa and $00000400) = 0 do\n    begin\n      Mantissa := Mantissa shl 1;\n      Dec(Exp);\n    end;\n    Inc(Exp);\n    Mantissa := Mantissa and not $00000400;\n    // Now assemble normalized number\n    Exp := Exp + (127 - 15);\n    Mantissa := Mantissa shl 13;\n    Dst := (Sign shl 31) or (LongWord(Exp) shl 23) or Mantissa;\n    // Result := Power(-1, Sign) * Power(2, -14) * (Mantissa / 1024);\n  end\n  else if (Exp = 31) and (Mantissa = 0) then\n  begin\n    // +/- infinity\n    Dst := (Sign shl 31) or $7F800000;\n  end\n  else //if (Exp = 31) and (Mantisa <> 0) then\n  begin\n    // Not a number - preserve sign and mantissa\n    Dst := (Sign shl 31) or $7F800000 or (Mantissa shl 13);\n  end;\n\n  // Reinterpret LongWord as Single\n  Result := PSingle(@Dst)^;\nend;\n\nfunction FloatToHalf(Float: Single): THalfFloat;\nvar\n  Src: LongWord;\n  Sign, Exp, Mantissa: LongInt;\nbegin\n  Src := PLongWord(@Float)^;\n  // Extract sign, exponent, and mantissa from Single number\n  Sign := Src shr 31;\n  Exp := LongInt((Src and $7F800000) shr 23) - 127 + 15;\n  Mantissa := Src and $007FFFFF;\n\n  if (Exp > 0) and (Exp < 30) then\n  begin\n    // Simple case - round the significand and combine it with the sign and exponent\n    Result := (Sign shl 15) or (Exp shl 10) or ((Mantissa + $00001000) shr 13);\n  end\n  else if Src = 0 then\n  begin\n    // Input float is zero - return zero\n    Result := 0;\n  end\n  else\n  begin\n    // Difficult case - lengthy conversion\n    if Exp <= 0 then\n    begin\n      if Exp < -10 then\n      begin\n        // Input float's value is less than HalfMin, return zero\n        Result := 0;\n      end\n      else\n      begin\n        // Float is a normalized Single whose magnitude is less than HalfNormMin.\n        // We convert it to denormalized half.\n        Mantissa := (Mantissa or $00800000) shr (1 - Exp);\n        // Round to nearest\n        if (Mantissa and $00001000) > 0 then\n          Mantissa := Mantissa + $00002000;\n        // Assemble Sign and Mantissa (Exp is zero to get denormalized number)\n        Result := (Sign shl 15) or (Mantissa shr 13);\n      end;\n    end\n    else if Exp = 255 - 127 + 15 then\n    begin\n      if Mantissa = 0 then\n      begin\n        // Input float is infinity, create infinity half with original sign\n        Result := (Sign shl 15) or $7C00;\n      end\n      else\n      begin\n        // Input float is NaN, create half NaN with original sign and mantissa\n        Result := (Sign shl 15) or $7C00 or (Mantissa shr 13);\n      end;\n    end\n    else\n    begin\n      // Exp is > 0 so input float is normalized Single\n\n      // Round to nearest\n      if (Mantissa and $00001000) > 0 then\n      begin\n        Mantissa := Mantissa + $00002000;\n        if (Mantissa and $00800000) > 0 then\n        begin\n          Mantissa := 0;\n          Exp := Exp + 1;\n        end;\n      end;\n\n      if Exp > 30 then\n      begin\n        // Exponent overflow - return infinity half\n        Result := (Sign shl 15) or $7C00;\n      end\n      else\n        // Assemble normalized half\n        Result := (Sign shl 15) or (Exp shl 10) or (Mantissa shr 13);\n    end;\n  end;\nend;\n\nfunction ColorHalfToFloat(ColorHF: TColorHFRec): TColorFPRec;\nbegin\n  Result.A := HalfToFloat(ColorHF.A);\n  Result.R := HalfToFloat(ColorHF.R);\n  Result.G := HalfToFloat(ColorHF.G);\n  Result.B := HalfToFloat(ColorHF.B);\nend;\n\nfunction ColorFloatToHalf(ColorFP: TColorFPRec): TColorHFRec;\nbegin\n  Result.A := FloatToHalf(ColorFP.A);\n  Result.R := FloatToHalf(ColorFP.R);\n  Result.G := FloatToHalf(ColorFP.G);\n  Result.B := FloatToHalf(ColorFP.B);\nend;\n\nprocedure VisualizePalette(Pal: PPalette32; Entries: Integer; out PalImage: TImageData);\nvar\n  I: Integer;\n  Pix: PColor32;\nbegin\n  InitImage(PalImage);\n  NewImage(Entries, 1, ifA8R8G8B8, PalImage);\n  Pix := PalImage.Bits;\n  for I := 0 to Entries - 1 do\n  begin\n    Pix^ := Pal[I].Color;\n    Inc(Pix);\n  end;       \nend;\n\n\n{ Pixel readers/writers for different image formats }\n\nprocedure ChannelGetSrcPixel(Src: PByte; SrcInfo: PImageFormatInfo;\n  var Pix: TColor64Rec);\nvar\n  A, R, G, B: Byte;\nbegin\n  FillChar(Pix, SizeOf(Pix), 0);\n  // returns 64 bit color value with 16 bits for each channel\n  case SrcInfo.BytesPerPixel of\n    1:\n      begin\n        PFGetARGB(SrcInfo.PixelFormat^, Src^, A, R, G, B);\n        Pix.A := A shl 8;\n        Pix.R := R shl 8;\n        Pix.G := G shl 8;\n        Pix.B := B shl 8;\n      end;\n    2:\n      begin\n        PFGetARGB(SrcInfo.PixelFormat^, PWord(Src)^, A, R, G, B);\n        Pix.A := A shl 8;\n        Pix.R := R shl 8;\n        Pix.G := G shl 8;\n        Pix.B := B shl 8;\n      end;\n    3:\n      with Pix do\n      begin\n        R := MulDiv(PColor24Rec(Src).R, 65535, 255);\n        G := MulDiv(PColor24Rec(Src).G, 65535, 255);\n        B := MulDiv(PColor24Rec(Src).B, 65535, 255);\n      end;\n    4:\n      with Pix do\n      begin\n        A := MulDiv(PColor32Rec(Src).A, 65535, 255);\n        R := MulDiv(PColor32Rec(Src).R, 65535, 255);\n        G := MulDiv(PColor32Rec(Src).G, 65535, 255);\n        B := MulDiv(PColor32Rec(Src).B, 65535, 255);\n      end;\n    6:\n      with Pix do\n      begin\n        R := PColor48Rec(Src).R;\n        G := PColor48Rec(Src).G;\n        B := PColor48Rec(Src).B;\n      end;\n    8: Pix.Color := PColor64(Src)^;\n  end;\n  // if src has no alpha, we set it to max (otherwise we would have to\n  // test if dest has alpha or not in each ChannelToXXX function)\n  if not SrcInfo.HasAlphaChannel then\n    Pix.A := 65535;\n\n  if SrcInfo.IsRBSwapped then\n    SwapValues(Pix.R, Pix.B);\nend;\n\nprocedure ChannelSetDstPixel(Dst: PByte; DstInfo: PImageFormatInfo;\n  const Pix: TColor64Rec);\nvar\n  PixW: TColor64Rec;\nbegin\n  PixW := Pix;\n  if DstInfo.IsRBSwapped then\n    SwapValues(PixW.R, PixW.B);\n  // Pix contains 64 bit color value with 16 bit for each channel\n  case DstInfo.BytesPerPixel of\n    1: Dst^ := PFSetARGB(DstInfo.PixelFormat^, PixW.A shr 8,\n        PixW.R shr 8, PixW.G shr 8, PixW.B shr 8);\n    2: PWord(Dst)^ := PFSetARGB(DstInfo.PixelFormat^, PixW.A shr 8,\n        PixW.R shr 8, PixW.G shr 8, PixW.B shr 8);\n    3:\n      with PColor24Rec(Dst)^ do\n      begin\n        R := MulDiv(PixW.R, 255, 65535);\n        G := MulDiv(PixW.G, 255, 65535);\n        B := MulDiv(PixW.B, 255, 65535);\n      end;\n    4:\n      with PColor32Rec(Dst)^ do\n      begin\n        A := MulDiv(PixW.A, 255, 65535);\n        R := MulDiv(PixW.R, 255, 65535);\n        G := MulDiv(PixW.G, 255, 65535);\n        B := MulDiv(PixW.B, 255, 65535);\n      end;\n    6:\n      with PColor48Rec(Dst)^ do\n      begin\n        R := PixW.R;\n        G := PixW.G;\n        B := PixW.B;\n      end;\n    8: PColor64(Dst)^ := PixW.Color;\n  end;\nend;\n\nprocedure GrayGetSrcPixel(Src: PByte; SrcInfo: PImageFormatInfo;\n  var Gray: TColor64Rec; var Alpha: Word);\nbegin\n  FillChar(Gray, SizeOf(Gray), 0);\n  // Source alpha is scaled to 16 bits and stored in Alpha,\n  // grayscale value is scaled to 64 bits and stored in Gray\n  case SrcInfo.BytesPerPixel of\n    1: Gray.A := MulDiv(Src^, 65535, 255);\n    2:\n      if SrcInfo.HasAlphaChannel then\n        with PWordRec(Src)^ do\n        begin\n          Alpha := MulDiv(High, 65535, 255);\n          Gray.A := MulDiv(Low, 65535, 255);\n        end\n      else\n        Gray.A := PWord(Src)^;\n    4:\n      if SrcInfo.HasAlphaChannel then\n        with PLongWordRec(Src)^ do\n        begin\n          Alpha := High;\n          Gray.A := Low;\n        end\n      else\n        with PLongWordRec(Src)^ do\n        begin\n          Gray.A := High;\n          Gray.R := Low;\n        end;\n    8: Gray.Color := PColor64(Src)^;\n  end;\n  // if src has no alpha, we set it to max (otherwise we would have to\n  // test if dest has alpha or not in each GrayToXXX function)\n  if not SrcInfo.HasAlphaChannel then\n    Alpha := 65535;\nend;\n\nprocedure GraySetDstPixel(Dst: PByte; DstInfo: PImageFormatInfo;\n  const Gray: TColor64Rec; Alpha: Word);\nbegin\n  // Gray contains grayscale value scaled to 64 bits, Alpha contains\n  // alpha value scaled to 16 bits\n  case DstInfo.BytesPerPixel of\n    1: Dst^ := MulDiv(Gray.A, 255, 65535);\n    2:\n      if DstInfo.HasAlphaChannel then\n        with PWordRec(Dst)^ do\n        begin\n          High := MulDiv(Alpha, 255, 65535);\n          Low := MulDiv(Gray.A, 255, 65535);\n        end\n      else\n        PWord(Dst)^ := Gray.A;\n    4:\n      if DstInfo.HasAlphaChannel then\n        with PLongWordRec(Dst)^ do\n        begin\n          High := Alpha;\n          Low := Gray.A;\n        end\n      else\n        with PLongWordRec(Dst)^ do\n        begin\n          High := Gray.A;\n          Low := Gray.R;\n        end;\n    8: PColor64(Dst)^ := Gray.Color;\n  end;\nend;\n\nprocedure FloatGetSrcPixel(Src: PByte; SrcInfo: PImageFormatInfo;\n  var Pix: TColorFPRec);\nvar\n  PixHF: TColorHFRec;\nbegin\n  Assert(SrcInfo.BytesPerPixel in [2, 4, 8, 12, 16]);\n\n  if SrcInfo.BytesPerPixel in [4, 12, 16] then\n  begin\n    // IEEE 754 single-precision channels\n    FillChar(Pix, SizeOf(Pix), 0);\n    case SrcInfo.BytesPerPixel of\n      4: Pix.R := PSingle(Src)^;\n      12: Pix.Color96Rec := PColor96FPRec(Src)^;\n      16: Pix := PColorFPRec(Src)^;\n    end;\n  end\n  else\n  begin\n    // Half float channels\n    FillChar(PixHF, SizeOf(PixHF), 0);\n    case SrcInfo.BytesPerPixel of\n      2: PixHF.R := PHalfFloat(Src)^;\n      8: PixHF := PColorHFRec(Src)^;\n    end;\n    Pix := ColorHalfToFloat(PixHF);\n  end;\n\n  // If src has no alpha, we set it to max (otherwise we would have to\n  // test if dest has alpha or not in each FloatToXXX function)\n  if not SrcInfo.HasAlphaChannel then\n    Pix.A := 1.0;\n  if SrcInfo.IsRBSwapped then\n    SwapValues(Pix.R, Pix.B);\nend;\n\nprocedure FloatSetDstPixel(Dst: PByte; DstInfo: PImageFormatInfo;\n  const Pix: TColorFPRec);\nvar\n  PixW: TColorFPRec;\n  PixHF: TColorHFRec;\nbegin\n  Assert(DstInfo.BytesPerPixel in [2, 4, 8, 12, 16]);\n\n  PixW := Pix;\n  if DstInfo.IsRBSwapped then\n    SwapValues(PixW.R, PixW.B);\n\n  if DstInfo.BytesPerPixel in [4, 12, 16] then\n  begin\n    case DstInfo.BytesPerPixel of\n      4:  PSingle(Dst)^ := PixW.R;\n      12: PColor96FPRec(Dst)^:= PixW.Color96Rec;\n      16: PColorFPRec(Dst)^ := PixW;\n    end;\n  end\n  else\n  begin\n    PixHF := ColorFloatToHalf(PixW);\n    case DstInfo.BytesPerPixel of\n      2: PHalfFloat(Dst)^ := PixHF.R;\n      8: PColorHFRec(Dst)^ := PixHF;\n    end;\n  end;\nend;\n\nprocedure IndexGetSrcPixel(Src: PByte; SrcInfo: PImageFormatInfo;\n  var Index: LongWord);\nbegin\n  case SrcInfo.BytesPerPixel of\n    1: Index := Src^;\n  end;\nend;\n\nprocedure IndexSetDstPixel(Dst: PByte; DstInfo: PImageFormatInfo;\n  Index: LongWord);\nbegin\n  case DstInfo.BytesPerPixel of\n    1: Dst^ := Byte(Index);\n    2: PWord(Dst)^ := Word(Index);\n    4: PLongWord(Dst)^ := Index;\n  end;\nend;\n\n\n{ Pixel readers/writers for 32bit and FP colors}\n\nfunction GetPixel32Generic(Bits: Pointer; Info: PImageFormatInfo; Palette: PPalette32): TColor32Rec;\nvar\n  Pix64: TColor64Rec;\n  PixF: TColorFPRec;\n  Alpha: Word;\n  Index: LongWord;\nbegin\n  if Info.Format = ifA8R8G8B8 then\n  begin\n    Result := PColor32Rec(Bits)^\n  end\n  else if Info.Format = ifR8G8B8 then\n  begin\n    PColor24Rec(@Result)^ := PColor24Rec(Bits)^;\n    Result.A := $FF;\n  end\n  else if Info.IsFloatingPoint then\n  begin\n    FloatGetSrcPixel(Bits, Info, PixF);\n    Result.A := ClampToByte(Round(PixF.A * 255.0));\n    Result.R := ClampToByte(Round(PixF.R * 255.0));\n    Result.G := ClampToByte(Round(PixF.G * 255.0));\n    Result.B := ClampToByte(Round(PixF.B * 255.0));\n  end\n  else if Info.HasGrayChannel then\n  begin\n    GrayGetSrcPixel(Bits, Info, Pix64, Alpha);\n    Result.A := MulDiv(Alpha, 255, 65535);\n    Result.R := MulDiv(Pix64.A, 255, 65535);\n    Result.G := MulDiv(Pix64.A, 255, 65535);\n    Result.B := MulDiv(Pix64.A, 255, 65535);\n  end\n  else if Info.IsIndexed then\n  begin\n    IndexGetSrcPixel(Bits, Info, Index);\n    Result := Palette[Index];\n  end\n  else\n  begin\n    ChannelGetSrcPixel(Bits, Info, Pix64);\n    Result.A := MulDiv(Pix64.A, 255, 65535);\n    Result.R := MulDiv(Pix64.R, 255, 65535);\n    Result.G := MulDiv(Pix64.G, 255, 65535);\n    Result.B := MulDiv(Pix64.B, 255, 65535);\n  end;\nend;\n\nprocedure SetPixel32Generic(Bits: Pointer; Info: PImageFormatInfo; Palette: PPalette32; const Color: TColor32Rec);\nvar\n  Pix64: TColor64Rec;\n  PixF: TColorFPRec;\n  Alpha: Word;\n  Index: LongWord;\nbegin\n  if Info.Format = ifA8R8G8B8 then\n  begin\n    PColor32Rec(Bits)^ := Color\n  end\n  else if Info.Format = ifR8G8B8 then\n  begin\n    PColor24Rec(Bits)^ := Color.Color24Rec;\n  end\n  else if Info.IsFloatingPoint then\n  begin\n    PixF.A := Color.A * OneDiv8Bit;\n    PixF.R := Color.R * OneDiv8Bit;\n    PixF.G := Color.G * OneDiv8Bit;\n    PixF.B := Color.B * OneDiv8Bit;\n    FloatSetDstPixel(Bits, Info, PixF);\n  end\n  else if Info.HasGrayChannel then\n  begin\n    Alpha := MulDiv(Color.A, 65535, 255);\n    Pix64.Color := 0;\n    Pix64.A := MulDiv(Round(GrayConv.R * Color.R + GrayConv.G * Color.G +\n      GrayConv.B * Color.B), 65535, 255);\n    GraySetDstPixel(Bits, Info, Pix64, Alpha);\n  end\n  else if Info.IsIndexed then\n  begin\n    Index := FindColor(Palette, Info.PaletteEntries, Color.Color);\n    IndexSetDstPixel(Bits, Info, Index);\n  end\n  else\n  begin\n    Pix64.A := MulDiv(Color.A, 65535, 255);\n    Pix64.R := MulDiv(Color.R, 65535, 255);\n    Pix64.G := MulDiv(Color.G, 65535, 255);\n    Pix64.B := MulDiv(Color.B, 65535, 255);\n    ChannelSetDstPixel(Bits, Info, Pix64);\n  end;\nend;\n\nfunction GetPixelFPGeneric(Bits: Pointer; Info: PImageFormatInfo; Palette: PPalette32): TColorFPRec;\nvar\n  Pix32: TColor32Rec;\n  Pix64: TColor64Rec;\n  Alpha: Word;\n  Index: LongWord;\nbegin\n  if Info.IsFloatingPoint then\n  begin\n    FloatGetSrcPixel(Bits, Info, Result);\n  end\n  else if Info.HasGrayChannel then\n  begin\n    GrayGetSrcPixel(Bits, Info, Pix64, Alpha);\n    Result.A := Alpha * OneDiv16Bit;\n    Result.R := Pix64.A * OneDiv16Bit;\n    Result.G := Pix64.A * OneDiv16Bit;\n    Result.B := Pix64.A * OneDiv16Bit;\n  end\n  else if Info.IsIndexed then\n  begin\n    IndexGetSrcPixel(Bits, Info, Index);\n    Pix32 := Palette[Index];\n    Result.A := Pix32.A * OneDiv8Bit;\n    Result.R := Pix32.R * OneDiv8Bit;\n    Result.G := Pix32.G * OneDiv8Bit;\n    Result.B := Pix32.B * OneDiv8Bit;\n  end\n  else\n  begin\n    ChannelGetSrcPixel(Bits, Info, Pix64);\n    Result.A := Pix64.A * OneDiv16Bit;\n    Result.R := Pix64.R * OneDiv16Bit;\n    Result.G := Pix64.G * OneDiv16Bit;\n    Result.B := Pix64.B * OneDiv16Bit;\n  end;\nend;\n\nprocedure SetPixelFPGeneric(Bits: Pointer; Info: PImageFormatInfo; Palette: PPalette32; const Color: TColorFPRec);\nvar\n  Pix32: TColor32Rec;\n  Pix64: TColor64Rec;\n  Alpha: Word;\n  Index: LongWord;\nbegin\n  if Info.IsFloatingPoint then\n  begin\n    FloatSetDstPixel(Bits, Info, Color);\n  end\n  else if Info.HasGrayChannel then\n  begin\n    Alpha := ClampToWord(Round(Color.A * 65535.0));\n    Pix64.Color := 0;\n    Pix64.A := ClampToWord(Round((GrayConv.R * Color.R + GrayConv.G * Color.G +\n      GrayConv.B * Color.B) * 65535.0));\n    GraySetDstPixel(Bits, Info, Pix64, Alpha);\n  end\n  else if Info.IsIndexed then\n  begin\n    Pix32.A := ClampToByte(Round(Color.A * 255.0));\n    Pix32.R := ClampToByte(Round(Color.R * 255.0));\n    Pix32.G := ClampToByte(Round(Color.G * 255.0));\n    Pix32.B := ClampToByte(Round(Color.B * 255.0));\n    Index := FindColor(Palette, Info.PaletteEntries, Pix32.Color);\n    IndexSetDstPixel(Bits, Info, Index);\n  end\n  else\n  begin\n    Pix64.A := ClampToWord(Round(Color.A * 65535.0));\n    Pix64.R := ClampToWord(Round(Color.R * 65535.0));\n    Pix64.G := ClampToWord(Round(Color.G * 65535.0));\n    Pix64.B := ClampToWord(Round(Color.B * 65535.0));\n    ChannelSetDstPixel(Bits, Info, Pix64);\n  end;\nend;\n\n\n{ Image format conversion functions }\n\nprocedure ChannelToChannel(NumPixels: LongInt; Src, Dst: PByte; SrcInfo,\n  DstInfo: PImageFormatInfo);\nvar\n  I: LongInt;\n  Pix64: TColor64Rec;\nbegin\n  // two most common conversions (RGB->ARGB and ARGB->RGB for 24/32 bit\n  // images) are made separately from general ARGB conversion to\n  // make them faster\n  if (SrcInfo.BytesPerPixel = 3) and (DstInfo.BytesPerPixel = 4) then\n  for I := 0 to NumPixels - 1 do\n    begin\n      PColor24Rec(Dst)^ := PColor24Rec(Src)^;\n      if DstInfo.HasAlphaChannel then\n        PColor32Rec(Dst).A := 255;\n      Inc(Src, SrcInfo.BytesPerPixel);\n      Inc(Dst, DstInfo.BytesPerPixel);\n    end\n  else\n  if (SrcInfo.BytesPerPixel = 4) and (DstInfo.BytesPerPixel = 3) then\n    for I := 0 to NumPixels - 1 do\n    begin\n      PColor24Rec(Dst)^ := PColor24Rec(Src)^;\n      Inc(Src, SrcInfo.BytesPerPixel);\n      Inc(Dst, DstInfo.BytesPerPixel);\n    end\n  else\n    for I := 0 to NumPixels - 1 do\n    begin\n      // general ARGB conversion\n      ChannelGetSrcPixel(Src, SrcInfo, Pix64);\n      ChannelSetDstPixel(Dst, DstInfo, Pix64);\n      Inc(Src, SrcInfo.BytesPerPixel);\n      Inc(Dst, DstInfo.BytesPerPixel);\n    end;\nend;\n\nprocedure ChannelToGray(NumPixels: LongInt; Src, Dst: PByte; SrcInfo,\n  DstInfo: PImageFormatInfo);\nvar\n  I: LongInt;\n  Pix64: TColor64Rec;\n  Alpha: Word;\nbegin\n  // two most common conversions (R8G8B8->Gray8 nad A8R8G8B8->Gray8)\n  // are made separately from general conversions to make them faster\n  if (SrcInfo.BytesPerPixel in [3, 4]) and (DstInfo.Format = ifGray8) then\n    for I := 0 to NumPixels - 1 do\n    begin\n      Dst^ := Round(GrayConv.R * PColor24Rec(Src).R + GrayConv.G * PColor24Rec(Src).G +\n        GrayConv.B * PColor24Rec(Src).B);\n      Inc(Src, SrcInfo.BytesPerPixel);\n      Inc(Dst, DstInfo.BytesPerPixel);\n    end\n  else\n    for I := 0 to NumPixels - 1 do\n    begin\n      ChannelGetSrcPixel(Src, SrcInfo, Pix64);\n\n      // alpha is saved from source pixel to Alpha,\n      // Gray value is computed and set to highest word of Pix64 so\n      // Pix64.Color contains grayscale value scaled to 64 bits\n      Alpha := Pix64.A;\n      with GrayConv do\n        Pix64.A := Round(R * Pix64.R + G * Pix64.G + B * Pix64.B);\n\n      GraySetDstPixel(Dst, DstInfo, Pix64, Alpha);\n      Inc(Src, SrcInfo.BytesPerPixel);\n      Inc(Dst, DstInfo.BytesPerPixel);\n    end;\nend;\n\nprocedure ChannelToFloat(NumPixels: LongInt; Src, Dst: PByte; SrcInfo,\n  DstInfo: PImageFormatInfo);\nvar\n  I: LongInt;\n  Pix64: TColor64Rec;\n  PixF: TColorFPRec;\nbegin\n  for I := 0 to NumPixels - 1 do\n  begin\n    ChannelGetSrcPixel(Src, SrcInfo, Pix64);\n\n    // floating point channel values are scaled to 1.0\n    PixF.A := Pix64.A * OneDiv16Bit;\n    PixF.R := Pix64.R * OneDiv16Bit;\n    PixF.G := Pix64.G * OneDiv16Bit;\n    PixF.B := Pix64.B * OneDiv16Bit;\n\n    FloatSetDstPixel(Dst, DstInfo, PixF);\n    Inc(Src, SrcInfo.BytesPerPixel);\n    Inc(Dst, DstInfo.BytesPerPixel);\n  end;\nend;\n\nprocedure ChannelToIndex(NumPixels: LongInt; Src, Dst: PByte; SrcInfo,\n  DstInfo: PImageFormatInfo; DstPal: PPalette32);\nbegin\n  ReduceColorsMedianCut(NumPixels, Src, Dst, SrcInfo, DstInfo, DstInfo.PaletteEntries,\n    GetOption(ImagingColorReductionMask), DstPal);\nend;\n\nprocedure GrayToGray(NumPixels: LongInt; Src, Dst: PByte; SrcInfo,\n  DstInfo: PImageFormatInfo);\nvar\n  I: LongInt;\n  Gray: TColor64Rec;\n  Alpha: Word;\nbegin\n  // two most common conversions (Gray8->Gray16 nad Gray16->Gray8)\n  // are made separately from general conversions to make them faster\n  if (SrcInfo.Format = ifGray8) and (DstInfo.Format = ifGray16) then\n  begin\n    for I := 0 to NumPixels - 1 do\n      PWordArray(Dst)[I] := PByteArray(Src)[I] shl 8;\n  end\n  else\n  begin\n    if (DstInfo.Format = ifGray8) and (SrcInfo.Format = ifGray16) then\n    begin\n      for I := 0 to NumPixels - 1 do\n        PByteArray(Dst)[I] := PWordArray(Src)[I] shr 8;\n    end\n    else\n      for I := 0 to NumPixels - 1 do\n      begin\n        // general grayscale conversion\n        GrayGetSrcPixel(Src, SrcInfo, Gray, Alpha);\n        GraySetDstPixel(Dst, DstInfo, Gray, Alpha);\n        Inc(Src, SrcInfo.BytesPerPixel);\n        Inc(Dst, DstInfo.BytesPerPixel);\n      end;\n  end;\nend;\n\nprocedure GrayToChannel(NumPixels: LongInt; Src, Dst: PByte; SrcInfo,\n  DstInfo: PImageFormatInfo);\nvar\n  I: LongInt;\n  Pix64: TColor64Rec;\n  Alpha: Word;\nbegin\n  // two most common conversions (Gray8->R8G8B8 nad Gray8->A8R8G8B8)\n  // are made separately from general conversions to make them faster\n  if (DstInfo.BytesPerPixel in [3, 4]) and (SrcInfo.Format = ifGray8) then\n    for I := 0 to NumPixels - 1 do\n    begin\n      PColor24Rec(Dst).R := Src^;\n      PColor24Rec(Dst).G := Src^;\n      PColor24Rec(Dst).B := Src^;\n      if DstInfo.HasAlphaChannel then\n        PColor32Rec(Dst).A := $FF;\n      Inc(Src, SrcInfo.BytesPerPixel);\n      Inc(Dst, DstInfo.BytesPerPixel);\n    end\n  else\n    for I := 0 to NumPixels - 1 do\n    begin\n      GrayGetSrcPixel(Src, SrcInfo, Pix64, Alpha);\n\n      // most significant word of grayscale value is used for\n      // each channel and alpha channel is set to Alpha\n      Pix64.R := Pix64.A;\n      Pix64.G := Pix64.A;\n      Pix64.B := Pix64.A;\n      Pix64.A := Alpha;\n\n      ChannelSetDstPixel(Dst, DstInfo, Pix64);\n      Inc(Src, SrcInfo.BytesPerPixel);\n      Inc(Dst, DstInfo.BytesPerPixel);\n    end;\nend;\n\nprocedure GrayToFloat(NumPixels: LongInt; Src, Dst: PByte; SrcInfo,\n  DstInfo: PImageFormatInfo);\nvar\n  I: LongInt;\n  Gray: TColor64Rec;\n  PixF: TColorFPRec;\n  Alpha: Word;\nbegin\n  for I := 0 to NumPixels - 1 do\n  begin\n    GrayGetSrcPixel(Src, SrcInfo, Gray, Alpha);\n    // most significant word of grayscale value is used for\n    // each channel and alpha channel is set to Alpha\n    // then all is scaled to 0..1\n    PixF.R := Gray.A * OneDiv16Bit;\n    PixF.G := Gray.A * OneDiv16Bit;\n    PixF.B := Gray.A * OneDiv16Bit;\n    PixF.A := Alpha * OneDiv16Bit;\n\n    FloatSetDstPixel(Dst, DstInfo, PixF);\n    Inc(Src, SrcInfo.BytesPerPixel);\n    Inc(Dst, DstInfo.BytesPerPixel);\n  end;\nend;\n\nprocedure GrayToIndex(NumPixels: LongInt; Src, Dst: PByte; SrcInfo,\n  DstInfo: PImageFormatInfo; DstPal: PPalette32);\nvar\n  I: LongInt;\n  Idx: LongWord;\n  Gray: TColor64Rec;\n  Alpha, Shift: Word;\nbegin\n  FillGrayscalePalette(DstPal, DstInfo.PaletteEntries);\n  Shift := Log2Int(DstInfo.PaletteEntries);\n  // most common conversion (Gray8->Index8)\n  // is made separately from general conversions to make it faster\n  if (SrcInfo.Format = ifGray8) and (DstInfo.Format = ifIndex8) then\n    for I := 0 to NumPixels - 1 do\n    begin\n      Dst^ := Src^;\n      Inc(Src, SrcInfo.BytesPerPixel);\n      Inc(Dst, DstInfo.BytesPerPixel);\n    end\n  else\n    for I := 0 to NumPixels - 1 do\n    begin\n      // gray value is read from src and index to precomputed\n      // grayscale palette is computed and written to dst\n      // (we assume here that there will be no more than 65536 palette\n      // entries in dst format, gray value is shifted so the highest\n      // gray value match the highest possible index in palette)\n      GrayGetSrcPixel(Src, SrcInfo, Gray, Alpha);\n      Idx := Gray.A shr (16 - Shift);\n      IndexSetDstPixel(Dst, DstInfo, Idx);\n      Inc(Src, SrcInfo.BytesPerPixel);\n      Inc(Dst, DstInfo.BytesPerPixel);\n    end;\nend;\n\nprocedure FloatToFloat(NumPixels: LongInt; Src, Dst: PByte; SrcInfo,\n  DstInfo: PImageFormatInfo);\nvar\n  I: LongInt;\n  PixF: TColorFPRec;\nbegin\n  for I := 0 to NumPixels - 1 do\n  begin\n    // general floating point conversion\n    FloatGetSrcPixel(Src, SrcInfo, PixF);\n    FloatSetDstPixel(Dst, DstInfo, PixF);\n    Inc(Src, SrcInfo.BytesPerPixel);\n    Inc(Dst, DstInfo.BytesPerPixel);\n  end;\nend;\n\nprocedure FloatToChannel(NumPixels: LongInt; Src, Dst: PByte; SrcInfo,\n  DstInfo: PImageFormatInfo);\nvar\n  I: LongInt;\n  Pix64: TColor64Rec;\n  PixF: TColorFPRec;\nbegin\n  for I := 0 to NumPixels - 1 do\n  begin\n    FloatGetSrcPixel(Src, SrcInfo, PixF);\n    ClampFloatPixel(PixF);\n\n    // floating point channel values are scaled to 1.0\n    Pix64.A := ClampToWord(Round(PixF.A * 65535));\n    Pix64.R := ClampToWord(Round(PixF.R * 65535));\n    Pix64.G := ClampToWord(Round(PixF.G * 65535));\n    Pix64.B := ClampToWord(Round(PixF.B * 65535));\n\n    ChannelSetDstPixel(Dst, DstInfo, Pix64);\n    Inc(Src, SrcInfo.BytesPerPixel);\n    Inc(Dst, DstInfo.BytesPerPixel);\n  end;\nend;\n\nprocedure FloatToGray(NumPixels: LongInt; Src, Dst: PByte; SrcInfo,\n  DstInfo: PImageFormatInfo);\nvar\n  I: LongInt;\n  PixF: TColorFPRec;\n  Gray: TColor64Rec;\n  Alpha: Word;\nbegin\n  for I := 0 to NumPixels - 1 do\n  begin\n    FloatGetSrcPixel(Src, SrcInfo, PixF);\n    ClampFloatPixel(PixF);\n\n    // alpha is saved from source pixel to Alpha,\n    // Gray value is computed and set to highest word of Pix64 so\n    // Pix64.Color contains grayscale value scaled to 64 bits\n    Alpha := ClampToWord(Round(PixF.A * 65535.0));\n    Gray.A := ClampToWord(Round((GrayConv.R * PixF.R + GrayConv.G * PixF.G +\n      GrayConv.B * PixF.B) * 65535.0));\n\n    GraySetDstPixel(Dst, DstInfo, Gray, Alpha);\n    Inc(Src, SrcInfo.BytesPerPixel);\n    Inc(Dst, DstInfo.BytesPerPixel);\n  end;\nend;\n\nprocedure FloatToIndex(NumPixels: LongInt; Src, Dst: PByte; SrcInfo,\n  DstInfo: PImageFormatInfo; DstPal: PPalette32);\nbegin\n  ReduceColorsMedianCut(NumPixels, Src, Dst, SrcInfo, DstInfo, DstInfo.PaletteEntries,\n    GetOption(ImagingColorReductionMask), DstPal);\nend;\n\nprocedure IndexToIndex(NumPixels: LongInt; Src, Dst: PByte; SrcInfo,\n  DstInfo: PImageFormatInfo; SrcPal, DstPal: PPalette32);\nvar\n  I: LongInt;\nbegin\n  // there is only one indexed format now, so it is just a copy\n  for I := 0 to NumPixels - 1 do\n  begin\n    Dst^ := Src^;\n    Inc(Src, SrcInfo.BytesPerPixel);\n    Inc(Dst, DstInfo.BytesPerPixel);\n  end;\n  for I := 0 to SrcInfo.PaletteEntries - 1 do\n    DstPal[I] := SrcPal[I];\nend;\n\nprocedure IndexToChannel(NumPixels: LongInt; Src, Dst: PByte; SrcInfo,\n  DstInfo: PImageFormatInfo; SrcPal: PPalette32);\nvar\n  I: LongInt;\n  Pix64: TColor64Rec;\n  Idx: LongWord;\nbegin\n  // two most common conversions (Index8->R8G8B8 nad Index8->A8R8G8B8)\n  // are made separately from general conversions to make them faster\n  if (SrcInfo.Format = ifIndex8) and (DstInfo.Format in [ifR8G8B8, ifA8R8G8B8]) then\n    for I := 0 to NumPixels - 1 do\n    begin\n      with PColor24Rec(Dst)^ do\n      begin\n        R := SrcPal[Src^].R;\n        G := SrcPal[Src^].G;\n        B := SrcPal[Src^].B;\n      end;\n      if DstInfo.Format = ifA8R8G8B8 then\n        PColor32Rec(Dst).A := SrcPal[Src^].A;\n      Inc(Src, SrcInfo.BytesPerPixel);\n      Inc(Dst, DstInfo.BytesPerPixel);\n    end\n  else\n    for I := 0 to NumPixels - 1 do\n    begin\n      // index to palette is read from source and color\n      // is retrieved from palette entry. Color is then\n      // scaled to 16bits and written to dest\n      IndexGetSrcPixel(Src, SrcInfo, Idx);\n      with Pix64 do\n      begin\n        A := SrcPal[Idx].A shl 8;\n        R := SrcPal[Idx].R shl 8;\n        G := SrcPal[Idx].G shl 8;\n        B := SrcPal[Idx].B shl 8;\n      end;\n      ChannelSetDstPixel(Dst, DstInfo, Pix64);\n      Inc(Src, SrcInfo.BytesPerPixel);\n      Inc(Dst, DstInfo.BytesPerPixel);\n    end;\nend;\n\nprocedure IndexToGray(NumPixels: LongInt; Src, Dst: PByte; SrcInfo,\n  DstInfo: PImageFormatInfo; SrcPal: PPalette32);\nvar\n  I: LongInt;\n  Gray: TColor64Rec;\n  Alpha: Word;\n  Idx: LongWord;\nbegin\n  // most common conversion (Index8->Gray8)\n  // is made separately from general conversions to make it faster\n  if (SrcInfo.Format = ifIndex8) and (DstInfo.Format = ifGray8) then\n  begin\n    for I := 0 to NumPixels - 1 do\n    begin\n      Dst^ := Round(GrayConv.R * SrcPal[Src^].R + GrayConv.G * SrcPal[Src^].G +\n        GrayConv.B * SrcPal[Src^].B);\n      Inc(Src, SrcInfo.BytesPerPixel);\n      Inc(Dst, DstInfo.BytesPerPixel);\n    end\n  end\n  else\n    for I := 0 to NumPixels - 1 do\n    begin\n      // index to palette is read from source and color\n      // is retrieved from palette entry. Color is then\n      // transformed to grayscale and assigned to the highest\n      // byte of Gray value\n      IndexGetSrcPixel(Src, SrcInfo, Idx);\n      Alpha := SrcPal[Idx].A shl 8;\n      Gray.A := MulDiv(Round(GrayConv.R * SrcPal[Idx].R + GrayConv.G * SrcPal[Idx].G +\n        GrayConv.B * SrcPal[Idx].B), 65535, 255);\n      GraySetDstPixel(Dst, DstInfo, Gray, Alpha);\n      Inc(Src, SrcInfo.BytesPerPixel);\n      Inc(Dst, DstInfo.BytesPerPixel);\n    end;\nend;\n\nprocedure IndexToFloat(NumPixels: LongInt; Src, Dst: PByte; SrcInfo,\n  DstInfo: PImageFormatInfo; SrcPal: PPalette32);\nvar\n  I: LongInt;\n  Idx: LongWord;\n  PixF: TColorFPRec;\nbegin\n  for I := 0 to NumPixels - 1 do\n  begin\n    // index to palette is read from source and color\n    // is retrieved from palette entry. Color is then\n    // scaled to 0..1 and written to dest\n    IndexGetSrcPixel(Src, SrcInfo, Idx);\n    with PixF do\n    begin\n      A := SrcPal[Idx].A * OneDiv8Bit;\n      R := SrcPal[Idx].R * OneDiv8Bit;\n      G := SrcPal[Idx].G * OneDiv8Bit;\n      B := SrcPal[Idx].B * OneDiv8Bit;\n    end;\n    FloatSetDstPixel(Dst, DstInfo, PixF);\n    Inc(Src, SrcInfo.BytesPerPixel);\n    Inc(Dst, DstInfo.BytesPerPixel);\n  end;\nend;\n\n\n{ Special formats conversion functions }\n\ntype\n  // DXT RGB color block\n  TDXTColorBlock = packed record\n    Color0, Color1: Word;\n    Mask: LongWord;\n  end;\n  PDXTColorBlock = ^TDXTColorBlock;\n\n  // DXT explicit alpha for a block\n  TDXTAlphaBlockExp = packed record\n    Alphas: array[0..3] of Word;\n  end;\n  PDXTAlphaBlockExp = ^TDXTAlphaBlockExp;\n\n  // DXT interpolated alpha for a block\n  TDXTAlphaBlockInt = packed record\n    Alphas: array[0..7] of Byte;\n  end;\n  PDXTAlphaBlockInt = ^TDXTAlphaBlockInt;\n\n  TPixelInfo = record\n    Color: Word;\n    Alpha: Byte;\n    Orig: TColor32Rec;\n  end;\n\n  TPixelBlock = array[0..15] of TPixelInfo;\n\nfunction DecodeCol(Color: Word): TColor32Rec;\n{$IFDEF USE_INLINE} inline; {$ENDIF}\nbegin\n  Result.A := $FF;\n{  Result.R := ((Color and $F800) shr 11) shl 3;\n  Result.G := ((Color and $07E0) shr 5) shl 2;\n  Result.B := (Color and $001F) shl 3;}\n  // this color expansion is slower but gives better results\n  Result.R := (Color shr 11) * 255 div 31;\n  Result.G := ((Color shr 5) and $3F) * 255 div 63;\n  Result.B := (Color and $1F) * 255 div 31;\nend;\n\nprocedure DecodeDXT1(SrcBits, DestBits: PByte; Width, Height: LongInt);\nvar\n  Sel, X, Y, I, J, K: LongInt;\n  Block: TDXTColorBlock;\n  Colors: array[0..3] of TColor32Rec;\nbegin\n  for Y := 0 to Height div 4 - 1 do\n    for X := 0 to Width div 4 - 1 do\n    begin\n      Block := PDXTColorBlock(SrcBits)^;\n      Inc(SrcBits, SizeOf(Block));\n      // we read and decode endpoint colors\n      Colors[0] := DecodeCol(Block.Color0);\n      Colors[1] := DecodeCol(Block.Color1);\n      // and interpolate between them\n      if Block.Color0 > Block.Color1 then\n      begin\n        // interpolation for block without alpha\n        Colors[2].A := $FF;\n        Colors[2].R := (Colors[0].R shl 1 + Colors[1].R + 1) div 3;\n        Colors[2].G := (Colors[0].G shl 1 + Colors[1].G + 1) div 3;\n        Colors[2].B := (Colors[0].B shl 1 + Colors[1].B + 1) div 3;\n        Colors[3].A := $FF;\n        Colors[3].R := (Colors[0].R + Colors[1].R shl 1 + 1) div 3;\n        Colors[3].G := (Colors[0].G + Colors[1].G shl 1 + 1) div 3;\n        Colors[3].B := (Colors[0].B + Colors[1].B shl 1 + 1) div 3;\n      end\n      else\n      begin\n        // interpolation for block with alpha\n        Colors[2].A := $FF;\n        Colors[2].R := (Colors[0].R + Colors[1].R) shr 1;\n        Colors[2].G := (Colors[0].G + Colors[1].G) shr 1;\n        Colors[2].B := (Colors[0].B + Colors[1].B) shr 1;\n        Colors[3].A := 0;\n        Colors[3].R := (Colors[0].R + Colors[1].R shl 1 + 1) div 3;\n        Colors[3].G := (Colors[0].G + Colors[1].G shl 1 + 1) div 3;\n        Colors[3].B := (Colors[0].B + Colors[1].B shl 1 + 1) div 3;\n      end;\n\n      // we distribute the dxt block colors across the 4x4 block of the\n      // destination image accroding to the dxt block mask\n      K := 0;\n      for J := 0 to 3 do\n        for I := 0 to 3 do\n        begin\n          Sel := (Block.Mask and (3 shl (K shl 1))) shr (K shl 1);\n          if ((X shl 2 + I) < Width) and ((Y shl 2 + J) < Height) then\n            PPalette32(DestBits)[(Y shl 2 + J) * Width + X shl 2 + I] :=\n              Colors[Sel];\n          Inc(K);\n        end;\n  end;\nend;\n\nprocedure DecodeDXT3(SrcBits, DestBits: PByte; Width, Height: LongInt);\nvar\n  Sel, X, Y, I, J, K: LongInt;\n  Block: TDXTColorBlock;\n  AlphaBlock: TDXTAlphaBlockExp;\n  Colors: array[0..3] of TColor32Rec;\n  AWord: Word;\nbegin\n  for Y := 0 to Height div 4 - 1 do\n    for X := 0 to Width div 4 - 1 do\n    begin\n      AlphaBlock := PDXTAlphaBlockExp(SrcBits)^;\n      Inc(SrcBits, SizeOf(AlphaBlock));\n      Block := PDXTColorBlock(SrcBits)^;\n      Inc(SrcBits, SizeOf(Block));\n      // we read and decode endpoint colors\n      Colors[0] := DecodeCol(Block.Color0);\n      Colors[1] := DecodeCol(Block.Color1);\n      // and interpolate between them\n      Colors[2].R := (Colors[0].R shl 1 + Colors[1].R + 1) div 3;\n      Colors[2].G := (Colors[0].G shl 1 + Colors[1].G + 1) div 3;\n      Colors[2].B := (Colors[0].B shl 1 + Colors[1].B + 1) div 3;\n      Colors[3].R := (Colors[0].R + Colors[1].R shl 1 + 1) div 3;\n      Colors[3].G := (Colors[0].G + Colors[1].G shl 1 + 1) div 3;\n      Colors[3].B := (Colors[0].B + Colors[1].B shl 1 + 1) div 3;\n\n      // we distribute the dxt block colors and alphas\n      // across the 4x4 block of the destination image\n      // accroding to the dxt block mask and alpha block\n      K := 0;\n      for J := 0 to 3 do\n      begin\n        AWord := AlphaBlock.Alphas[J];\n        for I := 0 to 3 do\n        begin\n          Sel := (Block.Mask and (3 shl (K shl 1))) shr (K shl 1);\n          if (X shl 2 + I < Width) and (Y shl 2 + J < Height) then\n          begin\n            Colors[Sel].A := AWord and $0F;\n            Colors[Sel].A := Colors[Sel].A or (Colors[Sel].A shl 4);\n            PPalette32(DestBits)[(Y shl 2 + J) * Width + X shl 2 + I] :=\n              Colors[Sel];\n          end;\n          Inc(K);\n          AWord := AWord shr 4;\n        end;\n      end;\n  end;\nend;\n\nprocedure GetInterpolatedAlphas(var AlphaBlock: TDXTAlphaBlockInt);\nbegin\n  with AlphaBlock do\n  if Alphas[0] > Alphas[1] then\n  begin\n    // Interpolation of six alphas\n    Alphas[2] := (6 * Alphas[0] + 1 * Alphas[1] + 3) div 7;\n    Alphas[3] := (5 * Alphas[0] + 2 * Alphas[1] + 3) div 7;\n    Alphas[4] := (4 * Alphas[0] + 3 * Alphas[1] + 3) div 7;\n    Alphas[5] := (3 * Alphas[0] + 4 * Alphas[1] + 3) div 7;\n    Alphas[6] := (2 * Alphas[0] + 5 * Alphas[1] + 3) div 7;\n    Alphas[7] := (1 * Alphas[0] + 6 * Alphas[1] + 3) div 7;\n  end\n  else\n  begin\n    // Interpolation of four alphas, two alphas are set directly\n    Alphas[2] := (4 * Alphas[0] + 1 * Alphas[1] + 2) div 5;\n    Alphas[3] := (3 * Alphas[0] + 2 * Alphas[1] + 2) div 5;\n    Alphas[4] := (2 * Alphas[0] + 3 * Alphas[1] + 2) div 5;\n    Alphas[5] := (1 * Alphas[0] + 4 * Alphas[1] + 2) div 5;\n    Alphas[6] := 0;\n    Alphas[7] := $FF;\n  end;\nend;\n\nprocedure DecodeDXT5(SrcBits, DestBits: PByte; Width, Height: LongInt);\nvar\n  Sel, X, Y, I, J, K: LongInt;\n  Block: TDXTColorBlock;\n  AlphaBlock: TDXTAlphaBlockInt;\n  Colors: array[0..3] of TColor32Rec;\n  AMask: array[0..1] of LongWord;\nbegin\n  for Y := 0 to Height div 4 - 1 do\n    for X := 0 to Width div 4 - 1 do\n    begin\n      AlphaBlock := PDXTAlphaBlockInt(SrcBits)^;\n      Inc(SrcBits, SizeOf(AlphaBlock));\n      Block := PDXTColorBlock(SrcBits)^;\n      Inc(SrcBits, SizeOf(Block));\n      // we read and decode endpoint colors\n      Colors[0] := DecodeCol(Block.Color0);\n      Colors[1] := DecodeCol(Block.Color1);\n      // and interpolate between them\n      Colors[2].R := (Colors[0].R shl 1 + Colors[1].R + 1) div 3;\n      Colors[2].G := (Colors[0].G shl 1 + Colors[1].G + 1) div 3;\n      Colors[2].B := (Colors[0].B shl 1 + Colors[1].B + 1) div 3;\n      Colors[3].R := (Colors[0].R + Colors[1].R shl 1 + 1) div 3;\n      Colors[3].G := (Colors[0].G + Colors[1].G shl 1 + 1) div 3;\n      Colors[3].B := (Colors[0].B + Colors[1].B shl 1 + 1) div 3;\n      // 6 bit alpha mask is copied into two long words for\n      // easier usage\n      AMask[0] := PLongWord(@AlphaBlock.Alphas[2])^ and $00FFFFFF;\n      AMask[1] := PLongWord(@AlphaBlock.Alphas[5])^ and $00FFFFFF;\n      // alpha interpolation between two endpoint alphas\n      GetInterpolatedAlphas(AlphaBlock);\n\n      // we distribute the dxt block colors and alphas\n      // across the 4x4 block of the destination image\n      // accroding to the dxt block mask and alpha block mask\n      K := 0;\n      for J := 0 to 3 do\n        for I := 0 to 3 do\n        begin\n          Sel := (Block.Mask and (3 shl (K shl 1))) shr (K shl 1);\n          if ((X shl 2 + I) < Width) and ((Y shl 2 + J) < Height) then\n          begin\n            Colors[Sel].A := AlphaBlock.Alphas[AMask[J shr 1] and 7];\n            PPalette32(DestBits)[(Y shl 2 + J) * Width + (X shl 2 + I)] :=\n              Colors[Sel];\n          end;\n          Inc(K);\n          AMask[J shr 1] := AMask[J shr 1] shr 3;\n        end;\n  end;\nend;\n\nprocedure GetBlock(var Block: TPixelBlock; SrcBits: Pointer; XPos, YPos,\n  Width, Height: LongInt);\nvar\n  X, Y, I: LongInt;\n  Src: PColor32Rec;\nbegin\n  I := 0;\n  // 4x4 pixel block is filled with information about every\n  // pixel in the block: alpha, original color, 565 color\n  for Y := 0 to 3 do\n    for X := 0 to 3 do\n    begin\n      Src := @PPalette32(SrcBits)[(YPos shl 2 + Y) * Width + XPos shl 2 + X];\n      Block[I].Color := ((Src.R shr 3) shl 11) or ((Src.G shr 2) shl 5) or\n        (Src.B shr 3);\n      Block[I].Alpha := Src.A;\n      Block[I].Orig := Src^;\n      Inc(I);\n    end;\nend;\n\nfunction ColorDistance(const C1, C2: TColor32Rec): LongInt;\n{$IFDEF USE_INLINE} inline;{$ENDIF}\nbegin\n  Result := (C1.R - C2.R) * (C1.R - C2.R) +\n    (C1.G - C2.G) * (C1.G - C2.G) + (C1.B - C2.B) * (C1.B - C2.B);\nend;\n\nprocedure GetEndpoints(const Block: TPixelBlock; var Ep0, Ep1: Word);\nvar\n  I, J, Farthest, Dist: LongInt;\n  Colors: array[0..15] of TColor32Rec;\nbegin\n  // we choose two colors from the pixel block which has the\n  // largest distance between them\n  for I := 0 to 15 do\n    Colors[I] := Block[I].Orig;\n  Farthest := -1;\n  for I := 0 to 15 do\n    for J := I + 1 to 15 do\n    begin\n      Dist := ColorDistance(Colors[I], Colors[J]);\n      if Dist > Farthest then\n      begin\n        Farthest := Dist;\n        Ep0 := Block[I].Color;\n        Ep1 := Block[J].Color;\n      end;\n    end;\nend;\n\nprocedure GetAlphaEndpoints(const Block: TPixelBlock; var Min, Max: Byte);\nvar\n  I: LongInt;\nbegin\n  Min := 255;\n  Max := 0;\n  // we choose the lowest and the highest alpha values\n  for I := 0 to 15 do\n  begin\n    if Block[I].Alpha < Min then\n      Min := Block[I].Alpha;\n    if Block[I].Alpha > Max then\n      Max := Block[I].Alpha;\n  end;\nend;\n\nprocedure FixEndpoints(var Ep0, Ep1: Word; HasAlpha: Boolean); \nvar\n  Temp: Word;\nbegin\n  // if dxt block has alpha information, Ep0 must be smaller\n  // than Ep1, if the  block has no alpha Ep1 must be smaller\n  if HasAlpha then\n  begin\n    if Ep0 > Ep1 then\n    begin\n      Temp := Ep0;\n      Ep0 := Ep1;\n      Ep1 := Temp;\n    end;\n  end\n  else\n    if Ep0 < Ep1 then\n    begin\n      Temp := Ep0;\n      Ep0 := Ep1;\n      Ep1 := Temp;\n    end;\nend;\n\nfunction GetColorMask(Ep0, Ep1: Word; NumCols: LongInt;\n  const Block: TPixelBlock): LongWord;\nvar\n  I, J, Closest, Dist: LongInt;\n  Colors: array[0..3] of TColor32Rec;\n  Mask: array[0..15] of Byte;\nbegin\n  // we decode endpoint colors\n  Colors[0] := DecodeCol(Ep0);\n  Colors[1] := DecodeCol(Ep1);\n  // and interpolate colors between (3 for DXT1 with alpha, 4 for the others)\n  if NumCols = 3 then\n  begin\n    Colors[2].R := (Colors[0].R + Colors[1].R) shr 1;\n    Colors[2].G := (Colors[0].G + Colors[1].G) shr 1;\n    Colors[2].B := (Colors[0].B + Colors[1].B) shr 1;\n    Colors[3].R := (Colors[0].R + Colors[1].R) shr 1;\n    Colors[3].G := (Colors[0].G + Colors[1].G) shr 1;\n    Colors[3].B := (Colors[0].B + Colors[1].B) shr 1;\n  end\n  else\n  begin\n    Colors[2].R := (Colors[0].R shl 1 + Colors[1].R + 1) div 3;\n    Colors[2].G := (Colors[0].G shl 1 + Colors[1].G + 1) div 3;\n    Colors[2].B := (Colors[0].B shl 1 + Colors[1].B + 1) div 3;\n    Colors[3].R := (Colors[0].R + Colors[1].R shl 1 + 1) div 3;\n    Colors[3].G := (Colors[0].G + Colors[1].G shl 1 + 1) div 3;\n    Colors[3].B := (Colors[0].B + Colors[1].B shl 1 + 1) div 3;\n  end;\n\n  for I := 0 to 15 do\n  begin\n    // this is only for DXT1 with alpha\n    if (Block[I].Alpha < 128) and (NumCols = 3) then\n    begin\n      Mask[I] := 3;\n      Continue;\n    end;\n    // for each of the 16 input pixels the nearest color in the\n    // 4 dxt colors is found\n    Closest := MaxInt;\n    for J := 0 to NumCols - 1 do\n    begin\n      Dist := ColorDistance(Block[I].Orig, Colors[J]);\n      if Dist < Closest then\n      begin\n        Closest := Dist;\n        Mask[I] := J;\n      end;\n    end;\n  end;\n\n  Result := 0;\n  for I := 0 to 15 do\n    Result := Result or (Mask[I] shl (I shl 1));\nend;\n\nprocedure GetAlphaMask(Ep0, Ep1: Byte; var Block: TPixelBlock; Mask: PByteArray);\nvar\n  Alphas: array[0..7] of Byte;\n  M: array[0..15] of Byte;\n  I, J, Closest, Dist: LongInt;\nbegin\n  Alphas[0] := Ep0;\n  Alphas[1] := Ep1;\n  // interpolation between two given alpha endpoints\n  // (I use 6 interpolated values mode)\n  Alphas[2] := (6 * Alphas[0] + 1 * Alphas[1] + 3) div 7;\n  Alphas[3] := (5 * Alphas[0] + 2 * Alphas[1] + 3) div 7;\n  Alphas[4] := (4 * Alphas[0] + 3 * Alphas[1] + 3) div 7;\n  Alphas[5] := (3 * Alphas[0] + 4 * Alphas[1] + 3) div 7;\n  Alphas[6] := (2 * Alphas[0] + 5 * Alphas[1] + 3) div 7;\n  Alphas[7] := (1 * Alphas[0] + 6 * Alphas[1] + 3) div 7;\n\n  // the closest interpolated values for each of the input alpha\n  // is found\n  for I := 0 to 15 do\n  begin\n    Closest := MaxInt;\n    for J := 0 to 7 do\n    begin\n      Dist := Abs(Alphas[J] - Block[I].Alpha);\n      if Dist < Closest then\n      begin\n        Closest := Dist;\n        M[I] := J;\n      end;\n    end;\n  end;\n\n  Mask[0] := M[0] or (M[1] shl 3) or ((M[2] and 3) shl 6);\n  Mask[1] := ((M[2] and 4) shr 2) or (M[3] shl 1) or (M[4] shl 4) or\n    ((M[5] and 1) shl 7);\n  Mask[2] := ((M[5] and 6) shr 1) or (M[6] shl 2) or (M[7] shl 5);\n  Mask[3] := M[8] or (M[9] shl 3) or ((M[10] and 3) shl 6);\n  Mask[4] := ((M[10] and 4) shr 2) or (M[11] shl 1) or (M[12] shl 4) or\n   ((M[13] and 1) shl 7);\n  Mask[5] := ((M[13] and 6) shr 1) or (M[14] shl 2) or (M[15] shl 5);\nend;\n\n\nprocedure EncodeDXT1(SrcBits: PByte; DestBits: PByte; Width, Height: LongInt);\nvar\n  X, Y, I: LongInt;\n  HasAlpha: Boolean;\n  Block: TDXTColorBlock;\n  Pixels: TPixelBlock;\nbegin\n  for Y := 0 to Height div 4 - 1 do\n    for X := 0 to Width div 4 - 1 do\n    begin\n      GetBlock(Pixels, SrcBits, X, Y, Width, Height);\n      HasAlpha := False;\n      for I := 0 to 15 do\n        if Pixels[I].Alpha < 128 then\n        begin\n          HasAlpha := True;\n          Break;\n        end;\n      GetEndpoints(Pixels, Block.Color0, Block.Color1);\n      FixEndpoints(Block.Color0, Block.Color1, HasAlpha);\n      if HasAlpha then\n        Block.Mask := GetColorMask(Block.Color0, Block.Color1, 3, Pixels)\n      else\n        Block.Mask := GetColorMask(Block.Color0, Block.Color1, 4, Pixels);\n      PDXTColorBlock(DestBits)^ := Block;\n      Inc(DestBits, SizeOf(Block));\n    end;\nend;\n\nprocedure EncodeDXT3(SrcBits: Pointer; DestBits: PByte; Width, Height: LongInt);\nvar\n  X, Y, I: LongInt;\n  Block: TDXTColorBlock;\n  AlphaBlock: TDXTAlphaBlockExp;\n  Pixels: TPixelBlock;\nbegin\n  for Y := 0 to Height div 4 - 1 do\n    for X := 0 to Width div 4 - 1 do\n    begin\n      GetBlock(Pixels, SrcBits, X, Y, Width, Height);\n      for I := 0 to 7 do\n        PByteArray(@AlphaBlock.Alphas)[I] :=\n          (Pixels[I shl 1].Alpha shr 4) or ((Pixels[I shl 1 + 1].Alpha shr 4) shl 4);\n      GetEndpoints(Pixels, Block.Color0, Block.Color1);\n      FixEndpoints(Block.Color0, Block.Color1, False);\n      Block.Mask := GetColorMask(Block.Color0, Block.Color1, 4, Pixels);\n      PDXTAlphaBlockExp(DestBits)^ := AlphaBlock;\n      Inc(DestBits, SizeOf(AlphaBlock));\n      PDXTColorBlock(DestBits)^ := Block;\n      Inc(DestBits, SizeOf(Block));\n    end;\nend;\n\nprocedure EncodeDXT5(SrcBits: Pointer; DestBits: PByte; Width, Height: LongInt);\nvar\n  X, Y: LongInt;\n  Block: TDXTColorBlock;\n  AlphaBlock: TDXTAlphaBlockInt;\n  Pixels: TPixelBlock;\nbegin\n  for Y := 0 to Height div 4 - 1 do\n    for X := 0 to Width div 4 - 1 do\n    begin\n      GetBlock(Pixels, SrcBits, X, Y, Width, Height);\n      GetEndpoints(Pixels, Block.Color0, Block.Color1);\n      FixEndpoints(Block.Color0, Block.Color1, False);\n      Block.Mask := GetColorMask(Block.Color0, Block.Color1, 4, Pixels);\n      GetAlphaEndPoints(Pixels, AlphaBlock.Alphas[1], AlphaBlock.Alphas[0]);\n      GetAlphaMask(AlphaBlock.Alphas[0], AlphaBlock.Alphas[1], Pixels,\n        PByteArray(@AlphaBlock.Alphas[2]));\n      PDXTAlphaBlockInt(DestBits)^ := AlphaBlock;\n      Inc(DestBits, SizeOf(AlphaBlock));\n      PDXTColorBlock(DestBits)^ := Block;\n      Inc(DestBits, SizeOf(Block));\n    end;\nend;\n\ntype\n  TBTCBlock = packed record\n    MLower, MUpper: Byte;\n    BitField: Word;\n  end;\n  PBTCBlock = ^TBTCBlock;\n\nprocedure EncodeBTC(SrcBits: Pointer; DestBits: PByte; Width, Height: Integer);\nvar\n  X, Y, I, J: Integer;\n  Block: TBTCBlock;\n  M, MLower, MUpper, K: Integer;\n  Pixels: array[0..15] of Byte;\nbegin\n  for Y := 0 to Height div 4 - 1 do\n    for X := 0 to Width div 4 - 1 do\n    begin\n      M := 0;\n      MLower := 0;\n      MUpper := 0;\n      FillChar(Block, SizeOf(Block), 0);\n      K := 0;\n\n      // Store 4x4 pixels and compute average, lower, and upper intensity levels\n      for I := 0 to 3 do\n        for J := 0 to 3 do\n        begin\n          Pixels[K] := PByteArray(SrcBits)[(Y shl 2 + I) * Width + X shl 2 + J];\n          Inc(M, Pixels[K]);\n          Inc(K);\n        end;\n\n      M := M div 16;\n      K := 0;\n\n      // Now compute upper and lower levels, number of upper pixels,\n      // and update bit field (1 when pixel is above avg. level M)\n      for I := 0 to 15 do\n      begin\n        if Pixels[I] > M then\n        begin\n          Inc(MUpper, Pixels[I]);\n          Inc(K);\n          Block.BitField := Block.BitField or (1 shl I);\n        end\n        else\n          Inc(MLower, Pixels[I]);\n      end;\n\n      // Scale levels and save them to block\n      if K > 0 then\n        Block.MUpper := ClampToByte(MUpper div K)\n      else\n        Block.MUpper := 0;\n      Block.MLower := ClampToByte(MLower div (16 - K));\n\n      // Finally save block to dest data\n      PBTCBlock(DestBits)^ := Block;\n      Inc(DestBits, SizeOf(Block));\n    end;\nend;\n\nprocedure GetOneChannelBlock(var Block: TPixelBlock; SrcBits: Pointer; XPos, YPos,\n  Width, Height, BytesPP, ChannelIdx: Integer);\nvar\n  X, Y, I: Integer;\n  Src: PByte;\nbegin\n  I := 0;\n  // 4x4 pixel block is filled with information about every pixel in the block,\n  // but only one channel value is stored in Alpha field\n  for Y := 0 to 3 do\n    for X := 0 to 3 do\n    begin\n      Src := @PByteArray(SrcBits)[(YPos * 4 + Y) * Width * BytesPP +\n        (XPos * 4 + X) * BytesPP + ChannelIdx];\n      Block[I].Alpha := Src^;\n      Inc(I);\n    end;\nend;\n\nprocedure EncodeATI1N(SrcBits: Pointer; DestBits: PByte; Width, Height: Integer);\nvar\n  X, Y: Integer;\n  AlphaBlock: TDXTAlphaBlockInt;\n  Pixels: TPixelBlock;\nbegin\n  for Y := 0 to Height div 4 - 1 do\n    for X := 0 to Width div 4 - 1 do\n    begin\n      // Encode one channel\n      GetOneChannelBlock(Pixels, SrcBits, X, Y, Width, Height, 1, 0);\n      GetAlphaEndPoints(Pixels, AlphaBlock.Alphas[1], AlphaBlock.Alphas[0]);\n      GetAlphaMask(AlphaBlock.Alphas[0], AlphaBlock.Alphas[1], Pixels,\n        PByteArray(@AlphaBlock.Alphas[2]));\n      PDXTAlphaBlockInt(DestBits)^ := AlphaBlock;\n      Inc(DestBits, SizeOf(AlphaBlock));\n    end;\nend;\n\nprocedure EncodeATI2N(SrcBits: Pointer; DestBits: PByte; Width, Height: Integer);\nvar\n  X, Y: Integer;\n  AlphaBlock: TDXTAlphaBlockInt;\n  Pixels: TPixelBlock;\nbegin\n  for Y := 0 to Height div 4 - 1 do\n    for X := 0 to Width div 4 - 1 do\n    begin\n      // Encode Red/X channel\n      GetOneChannelBlock(Pixels, SrcBits, X, Y, Width, Height, 4, ChannelRed);\n      GetAlphaEndPoints(Pixels, AlphaBlock.Alphas[1], AlphaBlock.Alphas[0]);\n      GetAlphaMask(AlphaBlock.Alphas[0], AlphaBlock.Alphas[1], Pixels,\n        PByteArray(@AlphaBlock.Alphas[2]));\n      PDXTAlphaBlockInt(DestBits)^ := AlphaBlock;\n      Inc(DestBits, SizeOf(AlphaBlock));\n      // Encode Green/Y channel\n      GetOneChannelBlock(Pixels, SrcBits, X, Y, Width, Height, 4, ChannelGreen);\n      GetAlphaEndPoints(Pixels, AlphaBlock.Alphas[1], AlphaBlock.Alphas[0]);\n      GetAlphaMask(AlphaBlock.Alphas[0], AlphaBlock.Alphas[1], Pixels,\n        PByteArray(@AlphaBlock.Alphas[2]));\n      PDXTAlphaBlockInt(DestBits)^ := AlphaBlock;\n      Inc(DestBits, SizeOf(AlphaBlock));\n    end;\nend;\n\nprocedure EncodeBinary(SrcBits: Pointer; DestBits: PByte; Width, Height: Integer);\nvar\n  Src: PByte absolute SrcBits;\n  Bitmap: PByteArray absolute DestBits;\n  X, Y, WidthBytes: Integer;\n  PixelTresholded, Treshold: Byte;\nbegin\n  Treshold := ClampToByte(GetOption(ImagingBinaryTreshold));\n  WidthBytes := (Width + 7) div 8;\n\n  for Y := 0 to Height - 1 do\n    for X := 0 to Width - 1 do\n    begin\n      if Src^ > Treshold then\n        PixelTresholded := 255\n      else\n        PixelTresholded := 0;\n\n      Bitmap[Y * WidthBytes + X div 8] := Bitmap[Y * WidthBytes + X div 8] or // OR current value of byte with following:\n        (PixelTresholded and 1)  // To make 1 from 255, 0 remains 0\n        shl (7 - (X mod 8));  // Put current bit to proper place in byte\n\n      Inc(Src);\n    end;\nend;\n\nprocedure DecodeBTC(SrcBits, DestBits: PByte; Width, Height: Integer);\nvar\n  X, Y, I, J, K: Integer;\n  Block: TBTCBlock;\n  Dest: PByte;\nbegin\n  for Y := 0 to Height div 4 - 1 do\n    for X := 0 to Width div 4 - 1 do\n    begin\n      Block := PBTCBlock(SrcBits)^;\n      Inc(SrcBits, SizeOf(Block));\n      K := 0;\n\n      // Just write MUpper when there is '1' in bit field and MLower\n      // when there is '0'\n      for I := 0 to 3 do\n        for J := 0 to 3 do\n        begin\n          Dest := @PByteArray(DestBits)[(Y shl 2 + I) * Width + X shl 2 + J];\n          if Block.BitField and (1 shl K) <> 0 then\n            Dest^ := Block.MUpper\n          else\n            Dest^ := Block.MLower;\n          Inc(K);\n        end;\n    end;\nend;\n\nprocedure DecodeATI1N(SrcBits, DestBits: PByte; Width, Height: Integer);\nvar\n  X, Y, I, J: Integer;\n  AlphaBlock: TDXTAlphaBlockInt;\n  AMask: array[0..1] of LongWord;\nbegin\n  for Y := 0 to Height div 4 - 1 do\n    for X := 0 to Width div 4 - 1 do\n    begin\n      AlphaBlock := PDXTAlphaBlockInt(SrcBits)^;\n      Inc(SrcBits, SizeOf(AlphaBlock));\n      // 6 bit alpha mask is copied into two long words for\n      // easier usage\n      AMask[0] := PLongWord(@AlphaBlock.Alphas[2])^ and $00FFFFFF;\n      AMask[1] := PLongWord(@AlphaBlock.Alphas[5])^ and $00FFFFFF;\n      // alpha interpolation between two endpoint alphas\n      GetInterpolatedAlphas(AlphaBlock);\n\n      // we distribute the dxt block alphas\n      // across the 4x4 block of the destination image\n      for J := 0 to 3 do\n       for I := 0 to 3 do\n       begin\n         PByteArray(DestBits)[(Y shl 2 + J) * Width + (X shl 2 + I)] :=\n           AlphaBlock.Alphas[AMask[J shr 1] and 7];\n         AMask[J shr 1] := AMask[J shr 1] shr 3;\n       end;\n  end;\nend;\n\nprocedure DecodeATI2N(SrcBits, DestBits: PByte; Width, Height: Integer);\nvar\n  X, Y, I, J: Integer;\n  Color: TColor32Rec;\n  AlphaBlock1, AlphaBlock2: TDXTAlphaBlockInt;\n  AMask1: array[0..1] of LongWord;\n  AMask2: array[0..1] of LongWord;\nbegin\n  for Y := 0 to Height div 4 - 1 do\n    for X := 0 to Width div 4 - 1 do\n    begin\n      // Read the first alpha block and get masks\n      AlphaBlock1 := PDXTAlphaBlockInt(SrcBits)^;\n      Inc(SrcBits, SizeOf(AlphaBlock1));\n      AMask1[0] := PLongWord(@AlphaBlock1.Alphas[2])^ and $00FFFFFF;\n      AMask1[1] := PLongWord(@AlphaBlock1.Alphas[5])^ and $00FFFFFF;\n      // Read the secind alpha block and get masks\n      AlphaBlock2 := PDXTAlphaBlockInt(SrcBits)^;\n      Inc(SrcBits, SizeOf(AlphaBlock2));\n      AMask2[0] := PLongWord(@AlphaBlock2.Alphas[2])^ and $00FFFFFF;\n      AMask2[1] := PLongWord(@AlphaBlock2.Alphas[5])^ and $00FFFFFF;\n      // alpha interpolation between two endpoint alphas\n      GetInterpolatedAlphas(AlphaBlock1);\n      GetInterpolatedAlphas(AlphaBlock2);\n\n      Color.A := $FF;\n      Color.B := 0;\n\n      // Distribute alpha block values across 4x4 pixel block,\n      // first alpha block represents Red channel, second is Green. \n      for J := 0 to 3 do\n       for I := 0 to 3 do\n       begin\n         Color.R := AlphaBlock1.Alphas[AMask1[J shr 1] and 7];\n         Color.G := AlphaBlock2.Alphas[AMask2[J shr 1] and 7];\n         PColor32RecArray(DestBits)[(Y shl 2 + J) * Width + (X shl 2 + I)] := Color;\n         AMask1[J shr 1] := AMask1[J shr 1] shr 3;\n         AMask2[J shr 1] := AMask2[J shr 1] shr 3;\n       end;\n  end;\nend;\n\nprocedure DecodeBinary(SrcBits, DestBits: PByte; Width, Height: Integer); {$IFDEF USE_INLINE}inline;{$ENDIF}\nbegin\n  Convert1To8(SrcBits, DestBits, Width, Height, (Width + 7) div 8, True);\nend;\n\nprocedure SpecialToUnSpecial(const SrcImage: TImageData; DestBits: Pointer;\n  SpecialFormat: TImageFormat);\nbegin\n  case SpecialFormat of\n    ifDXT1: DecodeDXT1(SrcImage.Bits, DestBits, SrcImage.Width, SrcImage.Height);\n    ifDXT3: DecodeDXT3(SrcImage.Bits, DestBits, SrcImage.Width, SrcImage.Height);\n    ifDXT5: DecodeDXT5(SrcImage.Bits, DestBits, SrcImage.Width, SrcImage.Height);\n    ifBTC:  DecodeBTC (SrcImage.Bits, DestBits, SrcImage.Width, SrcImage.Height);\n    ifATI1N: DecodeATI1N(SrcImage.Bits, DestBits, SrcImage.Width, SrcImage.Height);\n    ifATI2N: DecodeATI2N(SrcImage.Bits, DestBits, SrcImage.Width, SrcImage.Height);\n    ifBinary: DecodeBinary(SrcImage.Bits, DestBits, SrcImage.Width, SrcImage.Height);\n  end;\nend;\n\nprocedure UnSpecialToSpecial(SrcBits: Pointer; const DestImage: TImageData;\n  SpecialFormat: TImageFormat);\nbegin\n  case SpecialFormat of\n    ifDXT1: EncodeDXT1(SrcBits, DestImage.Bits, DestImage.Width, DestImage.Height);\n    ifDXT3: EncodeDXT3(SrcBits, DestImage.Bits, DestImage.Width, DestImage.Height);\n    ifDXT5: EncodeDXT5(SrcBits, DestImage.Bits, DestImage.Width, DestImage.Height);\n    ifBTC:  EncodeBTC (SrcBits, DestImage.Bits, DestImage.Width, DestImage.Height);\n    ifATI1N: EncodeATI1N(SrcBits, DestImage.Bits, DestImage.Width, DestImage.Height);\n    ifATI2N: EncodeATI2N(SrcBits, DestImage.Bits, DestImage.Width, DestImage.Height);\n    ifBinary: EncodeBinary(SrcBits, DestImage.Bits, DestImage.Width, DestImage.Height);\n  end;\nend;\n\nprocedure ConvertSpecial(var Image: TImageData;\n  SrcInfo, DstInfo: PImageFormatInfo);\nvar\n  WorkImage: TImageData;\n\n  procedure CheckSize(var Img: TImageData; Info: PImageFormatInfo);\n  var\n    Width, Height: Integer;\n  begin\n    Width := Img.Width;\n    Height := Img.Height;\n    DstInfo.CheckDimensions(Info.Format, Width, Height);\n    ResizeImage(Img, Width, Height, rfNearest);\n  end;\n\nbegin\n  if SrcInfo.IsSpecial and DstInfo.IsSpecial then\n  begin\n    // Convert source to nearest 'normal' format\n    InitImage(WorkImage);\n    NewImage(Image.Width, Image.Height, SrcInfo.SpecialNearestFormat, WorkImage);\n    SpecialToUnSpecial(Image, WorkImage.Bits, SrcInfo.Format);\n    FreeImage(Image);\n    // Make sure output of SpecialToUnSpecial is the same as input of\n    // UnSpecialToSpecial\n    if SrcInfo.SpecialNearestFormat <> DstInfo.SpecialNearestFormat then\n      ConvertImage(WorkImage, DstInfo.SpecialNearestFormat);\n    // Convert work image to dest special format\n    CheckSize(WorkImage, DstInfo);\n    NewImage(WorkImage.Width, WorkImage.Height, DstInfo.Format, Image);\n    UnSpecialToSpecial(WorkImage.Bits, Image, DstInfo.Format);\n    FreeImage(WorkImage);\n  end\n  else if SrcInfo.IsSpecial and not DstInfo.IsSpecial then\n  begin\n    // Convert source to nearest 'normal' format\n    InitImage(WorkImage);\n    NewImage(Image.Width, Image.Height, SrcInfo.SpecialNearestFormat, WorkImage);\n    SpecialToUnSpecial(Image, WorkImage.Bits, SrcInfo.Format);\n    FreeImage(Image);\n    // Now convert to dest format\n    ConvertImage(WorkImage, DstInfo.Format);\n    Image := WorkImage;\n  end\n  else if not SrcInfo.IsSpecial and DstInfo.IsSpecial then\n  begin\n    // Convert source to nearest format\n    WorkImage := Image;\n    ConvertImage(WorkImage, DstInfo.SpecialNearestFormat);\n    // Now convert from nearest to dest\n    CheckSize(WorkImage, DstInfo);\n    InitImage(Image);\n    NewImage(WorkImage.Width, WorkImage.Height, DstInfo.Format, Image);\n    UnSpecialToSpecial(WorkImage.Bits, Image, DstInfo.Format);\n    FreeImage(WorkImage);\n  end;\nend;\n\nfunction GetStdPixelsSize(Format: TImageFormat; Width, Height: LongInt): LongInt;\nbegin\n  if FInfos[Format] <> nil then\n    Result := Width * Height * FInfos[Format].BytesPerPixel\n  else\n    Result := 0;\nend;\n\nprocedure CheckStdDimensions(Format: TImageFormat; var Width, Height: LongInt);\nbegin\nend;\n\nfunction GetDXTPixelsSize(Format: TImageFormat; Width, Height: LongInt): LongInt;\nbegin\n  // DXT can be used only for images with dimensions that are\n  // multiples of four\n  CheckDXTDimensions(Format, Width, Height);\n  Result := Width * Height;\n  if Format in [ifDXT1, ifATI1N] then\n    Result := Result div 2;\nend;\n\nprocedure CheckDXTDimensions(Format: TImageFormat; var Width, Height: LongInt);\nbegin\n  // DXT image dimensions must be multiples of four\n  Width := (Width + 3) and not 3; // div 4 * 4;\n  Height := (Height + 3) and not 3; // div 4 * 4;\nend;\n\nfunction GetBTCPixelsSize(Format: TImageFormat; Width, Height: LongInt): LongInt;\nbegin\n  // BTC can be used only for images with dimensions that are\n  // multiples of four\n  CheckDXTDimensions(Format, Width, Height);\n  Result := Width * Height div 4; // 2bits/pixel\nend;\n\nfunction GetBinaryPixelsSize(Format: TImageFormat; Width, Height: LongInt): LongInt;\nbegin\n  // Binary images are aligned on BYTE boundary\n  Result := ((Width + 7) div 8) * Height; // 1bit/pixel\nend;\n\n{ Optimized pixel readers/writers for 32bit and FP colors to be stored in TImageFormatInfo }\n\nfunction GetPixel32ifA8R8G8B8(Bits: Pointer; Info: PImageFormatInfo; Palette: PPalette32): TColor32Rec;\nbegin\n  Result.Color := PLongWord(Bits)^;\nend;\n\nprocedure SetPixel32ifA8R8G8B8(Bits: Pointer; Info: PImageFormatInfo; Palette: PPalette32; const Color: TColor32Rec);\nbegin\n  PLongWord(Bits)^ := Color.Color;\nend;\n\nfunction GetPixelFPifA8R8G8B8(Bits: Pointer; Info: PImageFormatInfo; Palette: PPalette32): TColorFPRec;\nbegin\n  Result.A := PColor32Rec(Bits).A * OneDiv8Bit;\n  Result.R := PColor32Rec(Bits).R * OneDiv8Bit;\n  Result.G := PColor32Rec(Bits).G * OneDiv8Bit;\n  Result.B := PColor32Rec(Bits).B * OneDiv8Bit;\nend;\n\nprocedure SetPixelFPifA8R8G8B8(Bits: Pointer; Info: PImageFormatInfo; Palette: PPalette32; const Color: TColorFPRec);\nbegin\n  PColor32Rec(Bits).A := ClampToByte(Round(Color.A * 255.0));\n  PColor32Rec(Bits).R := ClampToByte(Round(Color.R * 255.0));\n  PColor32Rec(Bits).G := ClampToByte(Round(Color.G * 255.0));\n  PColor32Rec(Bits).B := ClampToByte(Round(Color.B * 255.0));\nend;\n\nfunction GetPixel32Channel8Bit(Bits: Pointer; Info: PImageFormatInfo; Palette: PPalette32): TColor32Rec;\nbegin\n  case Info.Format of\n    ifR8G8B8, ifX8R8G8B8:\n      begin\n        Result.A := $FF;\n        PColor24Rec(@Result)^ := PColor24Rec(Bits)^;\n      end;\n    ifGray8, ifA8Gray8:\n      begin\n        if Info.HasAlphaChannel then\n          Result.A := PWordRec(Bits).High\n        else\n          Result.A := $FF;\n        Result.R := PWordRec(Bits).Low;\n        Result.G := PWordRec(Bits).Low;\n        Result.B := PWordRec(Bits).Low;\n      end;\n  end;\nend;\n\nprocedure SetPixel32Channel8Bit(Bits: Pointer; Info: PImageFormatInfo; Palette: PPalette32; const Color: TColor32Rec);\nbegin\n  case Info.Format of\n    ifR8G8B8, ifX8R8G8B8:\n      begin\n        PColor24Rec(Bits)^ := PColor24Rec(@Color)^;\n      end;\n    ifGray8, ifA8Gray8:\n      begin\n        if Info.HasAlphaChannel then\n          PWordRec(Bits).High := Color.A;\n        PWordRec(Bits).Low := Round(GrayConv.R * Color.R + GrayConv.G * Color.G +\n          GrayConv.B * Color.B);\n      end;\n  end;\nend;\n\nfunction GetPixelFPChannel8Bit(Bits: Pointer; Info: PImageFormatInfo; Palette: PPalette32): TColorFPRec;\nbegin\n  case Info.Format of\n    ifR8G8B8, ifX8R8G8B8:\n      begin\n        Result.A := 1.0;\n        Result.R := PColor24Rec(Bits).R * OneDiv8Bit;\n        Result.G := PColor24Rec(Bits).G * OneDiv8Bit;\n        Result.B := PColor24Rec(Bits).B * OneDiv8Bit;\n      end;\n    ifGray8, ifA8Gray8:\n      begin\n        if Info.HasAlphaChannel then\n          Result.A := PWordRec(Bits).High * OneDiv8Bit\n        else\n          Result.A := 1.0;\n        Result.R := PWordRec(Bits).Low * OneDiv8Bit;\n        Result.G := PWordRec(Bits).Low * OneDiv8Bit;\n        Result.B := PWordRec(Bits).Low * OneDiv8Bit;\n      end;\n  end;\nend;\n\nprocedure SetPixelFPChannel8Bit(Bits: Pointer; Info: PImageFormatInfo; Palette: PPalette32; const Color: TColorFPRec);\nbegin\n  case Info.Format of\n    ifR8G8B8, ifX8R8G8B8:\n      begin\n        PColor24Rec(Bits).R := ClampToByte(Round(Color.R * 255.0));\n        PColor24Rec(Bits).G := ClampToByte(Round(Color.G * 255.0));\n        PColor24Rec(Bits).B := ClampToByte(Round(Color.B * 255.0));\n      end;\n    ifGray8, ifA8Gray8:\n      begin\n        if Info.HasAlphaChannel then\n          PWordRec(Bits).High := ClampToByte(Round(Color.A * 255.0));\n        PWordRec(Bits).Low := ClampToByte(Round((GrayConv.R * Color.R + GrayConv.G * Color.G +\n          GrayConv.B * Color.B) * 255.0));\n      end;\n  end;\nend;\n\nfunction GetPixelFPFloat32(Bits: Pointer; Info: PImageFormatInfo; Palette: PPalette32): TColorFPRec;\nbegin\n  case Info.Format of\n    ifA32R32G32B32F, ifA32B32G32R32F:\n      begin\n        Result := PColorFPRec(Bits)^;\n      end;\n    ifR32G32B32F, ifB32G32R32F:\n      begin\n        Result.A := 1.0;\n        Result.Color96Rec := PColor96FPRec(Bits)^;\n      end;\n    ifR32F:\n      begin\n        Result.A := 1.0;\n        Result.R := PSingle(Bits)^;\n        Result.G := 0.0;\n        Result.B := 0.0;\n      end;\n  end;\n  if Info.IsRBSwapped then\n    SwapValues(Result.R, Result.B);\nend;\n\nprocedure SetPixelFPFloat32(Bits: Pointer; Info: PImageFormatInfo; Palette: PPalette32; const Color: TColorFPRec);\nbegin\n  case Info.Format of\n    ifA32R32G32B32F, ifA32B32G32R32F:\n      begin\n        PColorFPRec(Bits)^ := Color;\n      end;\n    ifR32G32B32F, ifB32G32R32F:\n      begin\n        PColor96FPRec(Bits)^ := Color.Color96Rec;\n      end;\n    ifR32F:\n      begin\n        PSingle(Bits)^ := Color.R;\n      end;\n  end;\n  if Info.IsRBSwapped then\n    SwapValues(PColor96FPRec(Bits).R, PColor96FPRec(Bits).B);\nend;\n\ninitialization\n  // Initialize default sampling filter function pointers and radii\n  SamplingFilterFunctions[sfNearest]    := FilterNearest;\n  SamplingFilterFunctions[sfLinear]     := FilterLinear;\n  SamplingFilterFunctions[sfCosine]     := FilterCosine;\n  SamplingFilterFunctions[sfHermite]    := FilterHermite;\n  SamplingFilterFunctions[sfQuadratic]  := FilterQuadratic;\n  SamplingFilterFunctions[sfGaussian]   := FilterGaussian;\n  SamplingFilterFunctions[sfSpline]     := FilterSpline;\n  SamplingFilterFunctions[sfLanczos]    := FilterLanczos;\n  SamplingFilterFunctions[sfMitchell]   := FilterMitchell;\n  SamplingFilterFunctions[sfCatmullRom] := FilterCatmullRom;\n  SamplingFilterRadii[sfNearest]    := 1.0;\n  SamplingFilterRadii[sfLinear]     := 1.0;\n  SamplingFilterRadii[sfCosine]     := 1.0;\n  SamplingFilterRadii[sfHermite]    := 1.0;\n  SamplingFilterRadii[sfQuadratic]  := 1.5;\n  SamplingFilterRadii[sfGaussian]   := 1.25;\n  SamplingFilterRadii[sfSpline]     := 2.0;\n  SamplingFilterRadii[sfLanczos]    := 3.0;\n  SamplingFilterRadii[sfMitchell]   := 2.0;\n  SamplingFilterRadii[sfCatmullRom] := 2.0;\n\n{\n  File Notes:\n\n  -- TODOS ----------------------------------------------------\n    - nothing now\n\n  -- 0.77 Changes/Bug Fixes -------------------------------------\n    - Added ConvertToPixel32 helper function.\n\n  -- 0.26.5 Changes/Bug Fixes -----------------------------------\n    - Removed optimized codepatch for few data formats from StretchResample\n      function. It was quite buggy and not so much faster anyway.\n    - Added PaletteHasAlpha function.\n    - Added support functions for ifBinary data format.\n    - Added optional pixel scaling to Convert1To8, Convert2To8,\n      abd Convert4To8 functions.\n\n  -- 0.26.3 Changes/Bug Fixes -----------------------------------\n    - Filtered resampling ~10% faster now.\n    - Fixed DXT3 alpha encoding.\n    - ifIndex8 format now has HasAlphaChannel=True.\n\n  -- 0.25.0 Changes/Bug Fixes -----------------------------------\n    - Made some resampling stuff public so that it can be used in canvas class.\n    - Added some color constructors.\n    - Added VisualizePalette helper function.\n    - Fixed ConvertSpecial, not very readable before and error when\n      converting special->special.\n\n  -- 0.24.3 Changes/Bug Fixes -----------------------------------\n    - Some refactorings a changes to DXT based formats.\n    - Added ifATI1N and ifATI2N image data formats support structures and functions.\n\n  -- 0.23 Changes/Bug Fixes -----------------------------------\n    - Added ifBTC image format support structures and functions.\n\n  -- 0.21 Changes/Bug Fixes -----------------------------------\n    - FillMipMapLevel now works well with indexed and special formats too.\n    - Moved Convert1To8 and Convert4To8 functions from ImagingBitmaps here\n     and created new Convert2To8 function. They are now used by more than one\n     file format loader. \n\n  -- 0.19 Changes/Bug Fixes -----------------------------------\n    - StretchResample now uses pixel get/set functions stored in\n      TImageFormatInfo so it is  much faster for formats that override\n      them with optimized ones\n    - added pixel set/get functions optimized for various image formats\n      (to be stored in TImageFormatInfo)\n    - bug in ConvertSpecial caused problems when converting DXTC images\n      to bitmaps in ImagingCoponents\n    - bug in StretchRect caused that it didn't work with ifR32F and\n      ifR16F formats\n    - removed leftover code in FillMipMapLevel which disabled\n      filtered resizing of images witch ChannelSize <> 8bits\n    - added half float converting functions and support for half based\n      image formats where needed\n    - added TranslatePixel and IsImageFormatValid functions\n    - fixed possible range overflows when converting from FP to integer images\n    - added pixel set/get functions: GetPixel32Generic, GetPixelFPGeneric,\n      SetPixel32Generic, SetPixelFPGeneric\n    - fixed occasional range overflows in StretchResample\n\n  -- 0.17 Changes/Bug Fixes -----------------------------------\n    - added StretchNearest, StretchResample and some sampling functions\n    - added ChannelCount values to TImageFormatInfo constants\n    - added resolution validity check to GetDXTPixelsSize\n\n  -- 0.15 Changes/Bug Fixes -----------------------------------\n    - added RBSwapFormat values to some TImageFromatInfo definitions\n    - fixed bug in ConvertSpecial (causing DXT images to convert only to 32bit)\n    - added CopyPixel, ComparePixels helper functions\n\n  -- 0.13 Changes/Bug Fixes -----------------------------------\n    - replaced pixel format conversions for colors not to be\n      darkened when converting from low bit counts\n    - ReduceColorsMedianCut was updated to support creating one\n      optimal palette for more images and it is somewhat faster\n      now too\n    - there was ugly bug in DXTC dimensions checking\n}\n\nend.\n\n"
  },
  {
    "path": "lib/Imaging/ImagingIO.pas",
    "content": "{\n  Vampyre Imaging Library\n  by Marek Mauder \n  http://imaginglib.sourceforge.net\n\n  The contents of this file are used with permission, subject to the Mozilla\n  Public License Version 1.1 (the \"License\"); you may not use this file except\n  in compliance with the License. You may obtain a copy of the License at\n  http://www.mozilla.org/MPL/MPL-1.1.html\n\n  Software distributed under the License is distributed on an \"AS IS\" basis,\n  WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for\n  the specific language governing rights and limitations under the License.\n\n  Alternatively, the contents of this file may be used under the terms of the\n  GNU Lesser General Public License (the  \"LGPL License\"), in which case the\n  provisions of the LGPL License are applicable instead of those above.\n  If you wish to allow use of your version of this file only under the terms\n  of the LGPL License and not to allow others to use your version of this file\n  under the MPL, indicate your decision by deleting  the provisions above and\n  replace  them with the notice and other provisions required by the LGPL\n  License.  If you do not delete the provisions above, a recipient may use\n  your version of this file under either the MPL or the LGPL License.\n\n  For more information about the LGPL: http://www.gnu.org/copyleft/lesser.html\n}\n\n{ This unit contains default IO functions for reading from/writting to\n  files, streams and memory.}\nunit ImagingIO;\n\n{$I ImagingOptions.inc}\n\ninterface\n\nuses\n  SysUtils, Classes, ImagingTypes, Imaging, ImagingUtility;\n\ntype\n  TMemoryIORec = record\n    Data: ImagingUtility.PByteArray;\n    Position: LongInt;\n    Size: LongInt;\n  end;\n  PMemoryIORec = ^TMemoryIORec;\n\nvar\n  OriginalFileIO: TIOFunctions;\n  FileIO: TIOFunctions;\n  StreamIO: TIOFunctions;\n  MemoryIO: TIOFunctions;\n\n{ Helper function that returns size of input (from current position to the end)\n  represented by Handle (and opened and operated on by members of IOFunctions).}\nfunction GetInputSize(IOFunctions: TIOFunctions; Handle: TImagingHandle): LongInt;\n{ Helper function that initializes TMemoryIORec with given params.}\nfunction PrepareMemIO(Data: Pointer; Size: LongInt): TMemoryIORec;\n{ Reads one text line from input (CR+LF, CR, or LF as line delimiter).}\nfunction ReadLine(IOFunctions: TIOFunctions; Handle: TImagingHandle;\n  out Line: AnsiString; FailOnControlChars: Boolean = False): Boolean;\n{ Writes one text line to input with optional line delimiter.}\nprocedure WriteLine(IOFunctions: TIOFunctions; Handle: TImagingHandle;\n  const Line: AnsiString; const LineEnding: AnsiString = sLineBreak);\n\nimplementation\n\nconst\n  DefaultBufferSize = 16 * 1024;\n\ntype\n  { Based on TaaBufferedStream\n    Copyright (c) Julian M Bucknall 1997, 1999 }\n  TBufferedStream = class\n  private\n    FBuffer: PByteArray;\n    FBufSize: Integer;\n    FBufStart: Integer;\n    FBufPos: Integer;\n    FBytesInBuf: Integer;\n    FSize: Integer;\n    FDirty: Boolean;\n    FStream: TStream;\n    function GetPosition: Integer;\n    function GetSize: Integer;\n    procedure ReadBuffer;\n    procedure WriteBuffer;\n    procedure SetPosition(const Value: Integer);\n  public\n    constructor Create(AStream: TStream);\n    destructor Destroy; override;\n    function Read(var Buffer; Count: Integer): Integer;\n    function Write(const Buffer; Count: Integer): Integer;\n    function Seek(Offset: Integer; Origin: Word): Integer;\n    procedure Commit;\n    property Stream: TStream read FStream;\n    property Position: Integer read GetPosition write SetPosition;\n    property Size: Integer read GetSize;\n  end;\n\nconstructor TBufferedStream.Create(AStream: TStream);\nbegin\n  inherited Create;\n  FStream := AStream;\n  FBufSize := DefaultBufferSize;\n  GetMem(FBuffer, FBufSize);\n  FBufPos := 0;\n  FBytesInBuf := 0;\n  FBufStart := 0;\n  FDirty := False;\n  FSize := AStream.Size;\nend;\n\ndestructor TBufferedStream.Destroy;\nbegin\n  if FBuffer <> nil then\n  begin\n    Commit;\n    FreeMem(FBuffer);\n  end;\n  FStream.Position := Position; // Make sure source stream has right position\n  inherited Destroy;\nend;\n\nfunction TBufferedStream.GetPosition: Integer;\nbegin\n  Result := FBufStart + FBufPos;\nend;\n\nprocedure TBufferedStream.SetPosition(const Value: Integer);\nbegin\n  Seek(Value, soFromCurrent);\nend;\n\nfunction TBufferedStream.GetSize: Integer;\nbegin\n  Result := FSize;\nend;\n\nprocedure TBufferedStream.ReadBuffer;\nvar\n  SeekResult: Integer;\nbegin\n  SeekResult := FStream.Seek(FBufStart, 0);\n  if SeekResult = -1 then\n    raise Exception.Create('TBufferedStream.ReadBuffer: seek failed');\n  FBytesInBuf := FStream.Read(FBuffer^, FBufSize);\n  if FBytesInBuf <= 0 then\n    raise Exception.Create('TBufferedStream.ReadBuffer: read failed');\nend;\n\nprocedure TBufferedStream.WriteBuffer;\nvar\n  SeekResult: Integer;\n  BytesWritten: Integer;\nbegin\n  SeekResult := FStream.Seek(FBufStart, 0);\n  if SeekResult = -1 then\n    raise Exception.Create('TBufferedStream.WriteBuffer: seek failed');\n  BytesWritten := FStream.Write(FBuffer^, FBytesInBuf);\n  if BytesWritten <> FBytesInBuf then\n    raise Exception.Create('TBufferedStream.WriteBuffer: write failed');\nend;\n\nprocedure TBufferedStream.Commit;\nbegin\n  if FDirty then\n  begin\n    WriteBuffer;\n    FDirty := False;\n  end;\nend;\n\nfunction TBufferedStream.Read(var Buffer; Count: Integer): Integer;\nvar\n  BufAsBytes  : TByteArray absolute Buffer;\n  BufIdx, BytesToGo, BytesToRead: Integer;\nbegin\n  // Calculate the actual number of bytes we can read - this depends on\n  // the current position and size of the stream as well as the number\n  // of bytes requested.\n  BytesToGo := Count;\n  if FSize < (FBufStart + FBufPos + Count) then\n    BytesToGo := FSize - (FBufStart + FBufPos);\n\n  if BytesToGo <= 0 then\n  begin\n    Result := 0;\n    Exit;\n  end;\n  // Remember to return the result of our calculation\n  Result := BytesToGo;\n\n  BufIdx := 0;\n  if FBytesInBuf = 0 then\n    ReadBuffer;\n  // Calculate the number of bytes we can read prior to the loop\n  BytesToRead := FBytesInBuf - FBufPos;\n  if BytesToRead > BytesToGo then\n    BytesToRead := BytesToGo;\n  // Copy from the stream buffer to the caller's buffer\n  Move(FBuffer^[FBufPos], BufAsBytes[BufIdx], BytesToRead);\n  // Calculate the number of bytes still to read}\n  Dec(BytesToGo, BytesToRead);\n\n  // while we have bytes to read, read them\n  while BytesToGo > 0 do\n  begin\n    Inc(BufIdx, BytesToRead);\n    // As we've exhausted this buffer-full, advance to the next, check\n    //  to see whether we need to write the buffer out first\n    if FDirty then\n    begin\n      WriteBuffer;\n      FDirty := false;\n    end;\n    Inc(FBufStart, FBufSize);\n    FBufPos := 0;\n    ReadBuffer;\n    // Calculate the number of bytes we can read in this cycle\n    BytesToRead := FBytesInBuf;\n    if BytesToRead > BytesToGo then\n      BytesToRead := BytesToGo;\n    // Ccopy from the stream buffer to the caller's buffer\n    Move(FBuffer^, BufAsBytes[BufIdx], BytesToRead);\n    // Calculate the number of bytes still to read\n    Dec(BytesToGo, BytesToRead);\n  end;\n  // Remember our new position\n  Inc(FBufPos, BytesToRead);\n  if FBufPos = FBufSize then\n  begin\n    Inc(FBufStart, FBufSize);\n    FBufPos := 0;\n    FBytesInBuf := 0;\n  end;\nend;\n\nfunction TBufferedStream.Seek(Offset: Integer; Origin: Word): Integer;\nvar\n  NewBufStart, NewPos: Integer;\nbegin\n  // Calculate the new position\n  case Origin of\n    soFromBeginning : NewPos := Offset;\n    soFromCurrent   : NewPos := FBufStart + FBufPos + Offset;\n    soFromEnd       : NewPos := FSize + Offset;\n  else\n    raise Exception.Create('TBufferedStream.Seek: invalid origin');\n  end;\n\n  if (NewPos < 0) or (NewPos > FSize) then\n  begin\n    //NewPos := ClampInt(NewPos, 0, FSize); don't do this - for writing\n  end;\n  // Calculate which page of the file we need to be at\n  NewBufStart := NewPos and not Pred(FBufSize);\n  // If the new page is different than the old, mark the buffer as being\n  // ready to be replenished, and if need be write out any dirty data\n  if NewBufStart <> FBufStart then\n  begin\n    if FDirty then\n    begin\n      WriteBuffer;\n      FDirty := False;\n    end;\n    FBufStart := NewBufStart;\n    FBytesInBuf := 0;\n  end;\n  // Save the new position\n  FBufPos := NewPos - NewBufStart;\n  Result := NewPos;\nend;\n\nfunction TBufferedStream.Write(const Buffer; Count: Integer): Integer;\nvar\n  BufAsBytes: TByteArray absolute Buffer;\n  BufIdx, BytesToGo, BytesToWrite: Integer;\nbegin\n  // When we write to this stream we always assume that we can write the\n  // requested number of bytes: if we can't (eg, the disk is full) we'll\n  // get an exception somewhere eventually.\n  BytesToGo := Count;\n  // Remember to return the result of our calculation\n  Result := BytesToGo;\n\n  BufIdx := 0;\n  if (FBytesInBuf = 0) and (FSize > FBufStart) then\n    ReadBuffer;\n  // Calculate the number of bytes we can write prior to the loop\n  BytesToWrite := FBufSize - FBufPos;\n  if BytesToWrite > BytesToGo then\n    BytesToWrite := BytesToGo;\n  // Copy from the caller's buffer to the stream buffer\n  Move(BufAsBytes[BufIdx], FBuffer^[FBufPos], BytesToWrite);\n  // Mark our stream buffer as requiring a save to the actual stream,\n  // note that this will suffice for the rest of the routine as well: no\n  // inner routine will turn off the dirty flag.\n  FDirty := True;\n  // Calculate the number of bytes still to write\n  Dec(BytesToGo, BytesToWrite);\n\n  // While we have bytes to write, write them\n  while BytesToGo > 0 do\n  begin\n    Inc(BufIdx, BytesToWrite);\n    // As we've filled this buffer, write it out to the actual stream\n    // and advance to the next buffer, reading it if required\n    FBytesInBuf := FBufSize;\n    WriteBuffer;\n    Inc(FBufStart, FBufSize);\n    FBufPos := 0;\n    FBytesInBuf := 0;\n    if FSize > FBufStart then\n      ReadBuffer;\n    // Calculate the number of bytes we can write in this cycle\n    BytesToWrite := FBufSize;\n    if BytesToWrite > BytesToGo then\n      BytesToWrite := BytesToGo;\n    // Copy from the caller's buffer to our buffer\n    Move(BufAsBytes[BufIdx], FBuffer^, BytesToWrite);\n    // Calculate the number of bytes still to write\n    Dec(BytesToGo, BytesToWrite);\n  end;\n  // Remember our new position\n  Inc(FBufPos, BytesToWrite);\n  // Make sure the count of valid bytes is correct\n  if FBytesInBuf < FBufPos then\n    FBytesInBuf := FBufPos;\n  // Make sure the stream size is correct\n  if FSize < (FBufStart + FBytesInBuf) then\n    FSize := FBufStart + FBytesInBuf;\n  // If we're at the end of the buffer, write it out and advance to the\n  // start of the next page\n  if FBufPos = FBufSize then\n  begin\n    WriteBuffer;\n    FDirty := False;\n    Inc(FBufStart, FBufSize);\n    FBufPos := 0;\n    FBytesInBuf := 0;\n  end;\nend;\n\n{ File IO functions }\n\nfunction FileOpen(FileName: PChar; Mode: TOpenMode): TImagingHandle; cdecl;\nvar\n  Stream: TStream;\nbegin\n  Stream := nil;\n\n  case Mode of\n    omReadOnly:  Stream := TFileStream.Create(FileName, fmOpenRead or fmShareDenyWrite);\n    omCreate:    Stream := TFileStream.Create(FileName, fmCreate);\n    omReadWrite:\n      begin\n        if FileExists(FileName) then\n          Stream := TFileStream.Create(FileName, fmOpenReadWrite or fmShareExclusive)\n        else\n          Stream := TFileStream.Create(FileName, fmCreate);\n      end;\n  end;\n\n  Assert(Stream <> nil);\n  Result := TBufferedStream.Create(Stream);\nend;\n\nprocedure FileClose(Handle: TImagingHandle); cdecl;\nvar\n  Stream: TStream;\nbegin\n  Stream := TBufferedStream(Handle).Stream;\n  TBufferedStream(Handle).Free;\n  Stream.Free;\nend;\n\nfunction FileEof(Handle: TImagingHandle): Boolean; cdecl;\nbegin\n  Result := TBufferedStream(Handle).Position = TBufferedStream(Handle).Size;\nend;\n\nfunction FileSeek(Handle: TImagingHandle; Offset: LongInt; Mode: TSeekMode):\n  LongInt; cdecl;\nbegin\n  Result := TBufferedStream(Handle).Seek(Offset, LongInt(Mode));\nend;\n\nfunction FileTell(Handle: TImagingHandle): LongInt; cdecl;\nbegin\n  Result := TBufferedStream(Handle).Position;\nend;\n\nfunction FileRead(Handle: TImagingHandle; Buffer: Pointer; Count: LongInt):\n  LongInt; cdecl;\nbegin\n  Result := TBufferedStream(Handle).Read(Buffer^, Count);\nend;\n\nfunction FileWrite(Handle: TImagingHandle; Buffer: Pointer; Count: LongInt):\n  LongInt; cdecl;\nbegin\n  Result := TBufferedStream(Handle).Write(Buffer^, Count);\nend;\n\n{ Stream IO functions }\n\nfunction StreamOpen(FileName: PChar; Mode: TOpenMode): TImagingHandle; cdecl;\nbegin\n  Result := FileName;\nend;\n\nprocedure StreamClose(Handle: TImagingHandle); cdecl;\nbegin\nend;\n\nfunction StreamEof(Handle: TImagingHandle): Boolean; cdecl;\nbegin\n  Result := TStream(Handle).Position = TStream(Handle).Size;\nend;\n\nfunction StreamSeek(Handle: TImagingHandle; Offset: LongInt; Mode: TSeekMode):\n  LongInt; cdecl;\nbegin\n  Result := TStream(Handle).Seek(Offset, LongInt(Mode));\nend;\n\nfunction StreamTell(Handle: TImagingHandle): LongInt; cdecl;\nbegin\n  Result := TStream(Handle).Position;\nend;\n\nfunction StreamRead(Handle: TImagingHandle; Buffer: Pointer; Count: LongInt):\n  LongInt; cdecl;\nbegin\n  Result := TStream(Handle).Read(Buffer^, Count);\nend;\n\nfunction StreamWrite(Handle: TImagingHandle; Buffer: Pointer; Count: LongInt):\n  LongInt; cdecl;\nbegin\n  Result := TStream(Handle).Write(Buffer^, Count);\nend;\n\n{ Memory IO functions }\n\nfunction MemoryOpen(FileName: PChar; Mode: TOpenMode): TImagingHandle; cdecl;\nbegin\n  Result := FileName;\nend;\n\nprocedure MemoryClose(Handle: TImagingHandle); cdecl;\nbegin\nend;\n\nfunction MemoryEof(Handle: TImagingHandle): Boolean; cdecl;\nbegin\n  Result := PMemoryIORec(Handle).Position = PMemoryIORec(Handle).Size;\nend;\n\nfunction MemorySeek(Handle: TImagingHandle; Offset: LongInt; Mode: TSeekMode):\n  LongInt; cdecl;\nbegin\n  Result := PMemoryIORec(Handle).Position;\n  case Mode of\n    smFromBeginning: Result := Offset;\n    smFromCurrent:   Result := PMemoryIORec(Handle).Position + Offset;\n    smFromEnd:       Result := PMemoryIORec(Handle).Size + Offset;\n  end;\n  //Result := ClampInt(Result, 0, PMemoryIORec(Handle).Size); don't do this - some file formats use it\n  PMemoryIORec(Handle).Position := Result;\nend;\n\nfunction MemoryTell(Handle: TImagingHandle): LongInt; cdecl;\nbegin\n  Result := PMemoryIORec(Handle).Position;\nend;\n\nfunction MemoryRead(Handle: TImagingHandle; Buffer: Pointer; Count: LongInt):\n  LongInt; cdecl;\nvar\n  Rec: PMemoryIORec;\nbegin\n  Rec := PMemoryIORec(Handle);\n  Result := Count;\n  if Rec.Position + Count > Rec.Size then\n    Result := Rec.Size - Rec.Position;\n  Move(Rec.Data[Rec.Position], Buffer^, Result);\n  Rec.Position := Rec.Position + Result;\nend;\n\nfunction MemoryWrite(Handle: TImagingHandle; Buffer: Pointer; Count: LongInt):\n  LongInt; cdecl;\nvar\n  Rec: PMemoryIORec;\nbegin\n  Rec := PMemoryIORec(Handle);\n  Result := Count;\n  if Rec.Position + Count > Rec.Size then\n    Result := Rec.Size - Rec.Position;\n  Move(Buffer^, Rec.Data[Rec.Position], Result);\n  Rec.Position := Rec.Position + Result;\nend;\n\n{ Helper IO functions }\n\nfunction GetInputSize(IOFunctions: TIOFunctions; Handle: TImagingHandle): LongInt;\nvar\n  OldPos: Int64;\nbegin\n  OldPos := IOFunctions.Tell(Handle);\n  IOFunctions.Seek(Handle, 0, smFromEnd);\n  Result := IOFunctions.Tell(Handle);\n  IOFunctions.Seek(Handle, OldPos, smFromBeginning);\nend;\n\nfunction PrepareMemIO(Data: Pointer; Size: LongInt): TMemoryIORec;\nbegin\n  Result.Data := Data;\n  Result.Position := 0;\n  Result.Size := Size;\nend;\n\nfunction ReadLine(IOFunctions: TIOFunctions; Handle: TImagingHandle;\n  out Line: AnsiString; FailOnControlChars: Boolean): Boolean;\nconst\n  MaxLine = 1024;\nvar\n  EolPos, Pos: Integer;\n  C: AnsiChar;\n  EolReached: Boolean;\n  Endings: set of AnsiChar;\nbegin\n  Line := '';\n  Pos := 0;\n  EolPos := 0;\n  EolReached := False;\n  Endings := [#10, #13];\n  Result := True;\n\n  while not IOFunctions.Eof(Handle) do\n  begin\n    IOFunctions.Read(Handle, @C, SizeOf(C));\n\n    if FailOnControlChars and (Byte(C) < $20) then\n    begin\n      Break;\n    end;\n\n    if not (C in Endings) then\n    begin\n      if EolReached then\n      begin\n        IOFunctions.Seek(Handle, EolPos, smFromBeginning);\n        Exit;\n      end\n      else\n      begin\n        SetLength(Line, Length(Line) + 1);\n        Line[Length(Line)] := C;\n      end;\n    end\n    else if not EolReached then\n    begin\n      EolReached := True;\n      EolPos := IOFunctions.Tell(Handle);\n    end;\n\n    Inc(Pos);\n    if Pos >= MaxLine then\n    begin\n      Break;\n    end;\n  end;\n\n  Result := False;\n  IOFunctions.Seek(Handle, -Pos, smFromCurrent);\nend;\n\nprocedure WriteLine(IOFunctions: TIOFunctions; Handle: TImagingHandle;\n  const Line: AnsiString; const LineEnding: AnsiString);\nvar\n  ToWrite: AnsiString;\nbegin\n  ToWrite := Line + LineEnding;\n  IOFunctions.Write(Handle, @ToWrite[1], Length(ToWrite));\nend;\n\ninitialization\n  OriginalFileIO.Open := FileOpen;\n  OriginalFileIO.Close := FileClose;\n  OriginalFileIO.Eof := FileEof;\n  OriginalFileIO.Seek := FileSeek;\n  OriginalFileIO.Tell := FileTell;\n  OriginalFileIO.Read := FileRead;\n  OriginalFileIO.Write := FileWrite;\n\n  StreamIO.Open := StreamOpen;\n  StreamIO.Close := StreamClose;\n  StreamIO.Eof := StreamEof;\n  StreamIO.Seek := StreamSeek;\n  StreamIO.Tell := StreamTell;\n  StreamIO.Read := StreamRead;\n  StreamIO.Write := StreamWrite;\n\n  MemoryIO.Open := MemoryOpen;\n  MemoryIO.Close := MemoryClose;\n  MemoryIO.Eof := MemoryEof;\n  MemoryIO.Seek := MemorySeek;\n  MemoryIO.Tell := MemoryTell;\n  MemoryIO.Read := MemoryRead;\n  MemoryIO.Write := MemoryWrite;\n\n  ResetFileIO;\n\n{\n  File Notes:\n\n  -- TODOS ----------------------------------------------------\n    - nothing now\n\n  -- 0.77.1 ---------------------------------------------------\n   - Updated IO Open functions according to changes in ImagingTypes.\n   - Added ReadLine and WriteLine functions.\n\n  -- 0.23 Changes/Bug Fixes -----------------------------------\n    - Added merge between buffered read-only and write-only file\n      stream adapters - TIFF saving needed both reading and writing.\n    - Fixed bug causing wrong value of TBufferedWriteFile.Size\n      (needed to add buffer pos to size).\n\n  -- 0.21 Changes/Bug Fixes -----------------------------------\n    - Removed TMemoryIORec.Written, use Position to get proper memory\n      position (Written didn't take Seeks into account).\n    - Added TBufferedReadFile and TBufferedWriteFile classes for\n      buffered file reading/writting. File IO functions now use these\n      classes resulting in performance increase mainly in file formats\n      that read/write many small chunks. \n    - Added fmShareDenyWrite to FileOpenRead. You can now read\n      files opened for reading by Imaging from other apps.\n    - Added GetInputSize and PrepareMemIO helper functions.\n\n  -- 0.19 Changes/Bug Fixes -----------------------------------\n    - changed behaviour of MemorySeek to act as TStream\n      based Seeks\n}\nend.\n\n"
  },
  {
    "path": "lib/Imaging/ImagingNetworkGraphics.pas",
    "content": "{\n  Vampyre Imaging Library\n  by Marek Mauder \n  http://imaginglib.sourceforge.net\n\n  The contents of this file are used with permission, subject to the Mozilla\n  Public License Version 1.1 (the \"License\"); you may not use this file except\n  in compliance with the License. You may obtain a copy of the License at\n  http://www.mozilla.org/MPL/MPL-1.1.html\n\n  Software distributed under the License is distributed on an \"AS IS\" basis,\n  WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for\n  the specific language governing rights and limitations under the License.\n\n  Alternatively, the contents of this file may be used under the terms of the\n  GNU Lesser General Public License (the  \"LGPL License\"), in which case the\n  provisions of the LGPL License are applicable instead of those above.\n  If you wish to allow use of your version of this file only under the terms\n  of the LGPL License and not to allow others to use your version of this file\n  under the MPL, indicate your decision by deleting  the provisions above and\n  replace  them with the notice and other provisions required by the LGPL\n  License.  If you do not delete the provisions above, a recipient may use\n  your version of this file under either the MPL or the LGPL License.\n\n  For more information about the LGPL: http://www.gnu.org/copyleft/lesser.html\n}\n\n{ This unit contains image format loaders/savers for Network Graphics image\n  file formats PNG, MNG, and JNG.}\nunit ImagingNetworkGraphics;\n        \ninterface\n\n{$I ImagingOptions.inc}\n\n{ If MNG support is enabled we must make sure PNG and JNG are enabled too.}\n{$IFNDEF DONT_LINK_MNG}\n  {$UNDEF DONT_LINK_PNG}\n  {$UNDEF DONT_LINK_JNG}\n{$ENDIF}\n\nuses\n  Types, SysUtils, Classes, ImagingTypes, Imaging, ImagingUtility, ImagingFormats, dzlib;\n\ntype\n  { Basic class for Network Graphics file formats loaders/savers.}\n  TNetworkGraphicsFileFormat = class(TImageFileFormat)\n  protected\n    FSignature: TChar8;\n    FPreFilter: LongInt;\n    FCompressLevel: LongInt;\n    FLossyCompression: LongBool;\n    FLossyAlpha: LongBool;\n    FQuality: LongInt;\n    FProgressive: LongBool;\n    FZLibStategy: Integer;\n    function GetSupportedFormats: TImageFormats; override;\n    procedure ConvertToSupported(var Image: TImageData;\n      const Info: TImageFormatInfo); override;\n    procedure Define; override;\n  public\n    function TestFormat(Handle: TImagingHandle): Boolean; override;\n    procedure CheckOptionsValidity; override;\n  published\n    { Sets precompression filter used when saving images with lossless compression.\n      Allowed values are: 0 (none), 1 (sub), 2 (up), 3 (average), 4 (paeth),\n      5 (use 0 for indexed/gray images and 4 for RGB/ARGB images),\n      6 (adaptive filtering - use best filter for each scanline - very slow).\n      Note that filters 3 and 4 are much slower than filters 1 and 2.\n      Default value is 5.}\n    property PreFilter: LongInt read FPreFilter write FPreFilter;\n    { Sets ZLib compression level used when saving images with lossless compression.\n      Allowed values are in range 0 (no compresstion) to 9 (best compression).\n      Default value is 5.}\n    property CompressLevel: LongInt read FCompressLevel write FCompressLevel;\n    { Specifies whether MNG animation frames are saved with lossy or lossless\n      compression. Lossless frames are saved as PNG images and lossy frames are\n      saved as JNG images. Allowed values are 0 (False) and 1 (True).\n      Default value is 0.}\n    property LossyCompression: LongBool read FLossyCompression write FLossyCompression;\n    { Defines whether alpha channel of lossy MNG frames or JNG images\n      is lossy compressed too. Allowed values are 0 (False) and 1 (True).\n      Default value is 0.}\n    property LossyAlpha: LongBool read FLossyAlpha write FLossyAlpha;\n    { Specifies compression quality used when saving lossy MNG frames or JNG images.\n      For details look at ImagingJpegQuality option.}\n    property Quality: LongInt read FQuality write FQuality;\n    { Specifies whether images are saved in progressive format when saving lossy\n      MNG frames or JNG images. For details look at ImagingJpegProgressive.}\n    property Progressive: LongBool read FProgressive write FProgressive;\n  end;\n\n  { Class for loading Portable Network Graphics Images.\n    Loads all types of this image format (all images in png test suite)\n    and saves all types with bitcount >= 8 (non-interlaced only).\n    Compression level and  filtering can be set by options interface.\n\n    Supported ancillary chunks (loading):\n    tRNS, bKGD\n    (for indexed images transparency contains alpha values for palette,\n    RGB/Gray images with transparency are converted to formats with alpha\n    and pixels with transparent color are replaced with background color\n    with alpha = 0).}\n  TPNGFileFormat = class(TNetworkGraphicsFileFormat)\n  private\n    FLoadAnimated: LongBool;\n  protected\n    procedure Define; override;\n    function LoadData(Handle: TImagingHandle; var Images: TDynImageDataArray;\n      OnlyFirstLevel: Boolean): Boolean; override;\n    function SaveData(Handle: TImagingHandle; const Images: TDynImageDataArray;\n      Index: LongInt): Boolean; override;\n  published\n    property LoadAnimated: LongBool read FLoadAnimated write FLoadAnimated;\n  end;\n\n{$IFNDEF DONT_LINK_MNG}\n  { Class for loading Multiple Network Graphics files.\n    This format has complex animation capabilities but Imaging only\n    extracts frames. Individual frames are stored as standard PNG or JNG\n    images. Loads all types of these frames stored in IHDR-IEND and\n    JHDR-IEND streams (Note that there are MNG chunks\n    like BASI which define images but does not contain image data itself,\n    those are ignored).\n    Imaging saves MNG files as MNG-VLC (very low complexity) so it is basicaly\n    an array of image frames without MNG animation chunks. Frames can be saved\n    as lossless PNG or lossy JNG images (look at TPNGFileFormat and\n    TJNGFileFormat for info). Every frame can be in different data format.\n    \n    Many frame compression settings can be modified by options interface.}\n  TMNGFileFormat = class(TNetworkGraphicsFileFormat)\n  protected\n    procedure Define; override;\n    function LoadData(Handle: TImagingHandle; var Images: TDynImageDataArray;\n      OnlyFirstLevel: Boolean): Boolean; override;\n    function SaveData(Handle: TImagingHandle; const Images: TDynImageDataArray;\n      Index: LongInt): Boolean; override;\n  end;\n{$ENDIF}  \n\n{$IFNDEF DONT_LINK_JNG}\n  { Class for loading JPEG Network Graphics Images.\n    Loads all types of this image format (all images in jng test suite)\n    and saves all types except 12 bit JPEGs.\n    Alpha channel in JNG images is stored separately from color/gray data and\n    can be lossy (as JPEG image) or lossless (as PNG image) compressed.\n    Type of alpha compression, compression level and quality,\n    and filtering can be set by options interface.\n\n    Supported ancillary chunks (loading):\n    tRNS, bKGD\n    (Images with transparency are converted to formats with alpha\n    and pixels with transparent color are replaced with background color\n    with alpha = 0).}\n  TJNGFileFormat = class(TNetworkGraphicsFileFormat)\n  protected\n    procedure Define; override;\n    function LoadData(Handle: TImagingHandle; var Images: TDynImageDataArray;\n      OnlyFirstLevel: Boolean): Boolean; override;\n    function SaveData(Handle: TImagingHandle; const Images: TDynImageDataArray;\n      Index: LongInt): Boolean; override;\n  end;\n{$ENDIF}\n\n\nimplementation\n\nuses\n{$IFNDEF DONT_LINK_JNG}\n  ImagingJpeg, ImagingIO,\n{$ENDIF}\n  ImagingCanvases;\n\nconst\n  NGDefaultPreFilter = 5;\n  NGDefaultCompressLevel = 5;\n  NGDefaultLossyAlpha = False;\n  NGDefaultLossyCompression = False;\n  NGDefaultProgressive = False;\n  NGDefaultQuality = 90;\n  NGLosslessFormats: TImageFormats = [ifIndex8, ifGray8, ifA8Gray8, ifGray16,\n    ifA16Gray16, ifR8G8B8, ifA8R8G8B8, ifR16G16B16, ifA16R16G16B16, ifB16G16R16,\n    ifA16B16G16R16, ifBinary];\n  NGLossyFormats: TImageFormats = [ifGray8, ifA8Gray8, ifR8G8B8, ifA8R8G8B8];\n  PNGDefaultLoadAnimated = True;\n  NGDefaultZLibStartegy = 1; // Z_FILTERED\n\n  SPNGFormatName = 'Portable Network Graphics';\n  SPNGMasks      = '*.png';\n  SMNGFormatName = 'Multiple Network Graphics';\n  SMNGMasks      = '*.mng';\n  SJNGFormatName = 'JPEG Network Graphics';\n  SJNGMasks      = '*.jng';\n\nresourcestring\n  SErrorLoadingChunk = 'Error when reading %s chunk data. File may be corrupted.';\n\ntype\n  { Chunk header.}\n  TChunkHeader = packed record\n    DataSize: LongWord;\n    ChunkID: TChar4;\n  end;\n\n  { IHDR chunk format - PNG header.}\n  TIHDR = packed record\n    Width: LongWord;              // Image width\n    Height: LongWord;             // Image height\n    BitDepth: Byte;               // Bits per pixel or bits per sample (for truecolor)\n    ColorType: Byte;              // 0 = grayscale, 2 = truecolor, 3 = palette,\n                                  // 4 = gray + alpha, 6 = truecolor + alpha\n    Compression: Byte;            // Compression type:  0 = ZLib\n    Filter: Byte;                 // Used precompress filter\n    Interlacing: Byte;            // Used interlacing: 0 = no int, 1 = Adam7\n  end;\n  PIHDR = ^TIHDR;\n\n  { MHDR chunk format - MNG header.}\n  TMHDR = packed record\n    FrameWidth: LongWord;         // Frame width\n    FrameHeight: LongWord;        // Frame height\n    TicksPerSecond: LongWord;     // FPS of animation\n    NominalLayerCount: LongWord;  // Number of layers in file\n    NominalFrameCount: LongWord;  // Number of frames in file\n    NominalPlayTime: LongWord;    // Play time of animation in ticks\n    SimplicityProfile: LongWord;  // Defines which MNG features are used in this file\n  end;\n  PMHDR = ^TMHDR;\n\n  { JHDR chunk format - JNG header.}\n  TJHDR = packed record\n    Width: LongWord;              // Image width\n    Height: LongWord;             // Image height\n    ColorType: Byte;              // 8 = grayscale (Y), 10 = color (YCbCr),\n                                  // 12 = gray + alpha (Y-alpha), 14 = color + alpha (YCbCr-alpha)\n    SampleDepth: Byte;            // 8, 12 or 20 (8 and 12 samples together) bit\n    Compression: Byte;            // Compression type:  8 = Huffman coding\n    Interlacing: Byte;            // 0 = single scan, 8 = progressive\n    AlphaSampleDepth: Byte;       // 0, 1, 2, 4, 8, 16 if alpha compression is 0 (PNG)\n                                  // 8 if alpha compression is 8 (JNG)\n    AlphaCompression: Byte;       // 0 = PNG graysscale IDAT, 8 = grayscale 8-bit JPEG\n    AlphaFilter: Byte;            // 0 = PNG filter or no filter (JPEG)\n    AlphaInterlacing: Byte;       // 0 = non interlaced\n  end;\n  PJHDR = ^TJHDR;\n\n  { acTL chunk format - APNG animation control.}\n  TacTL = packed record\n    NumFrames: LongWord;          // Number of frames\n    NumPlay: LongWord;            // Number of times to loop the animation (0 = inf)\n  end;\n  PacTL =^TacTL;\n\n  { fcTL chunk format - APNG frame control.}\n  TfcTL = packed record\n    SeqNumber: LongWord;          // Sequence number of the animation chunk, starting from 0\n    Width: LongWord;              // Width of the following frame\n    Height: LongWord;             // Height of the following frame\n    XOffset: LongWord;            // X position at which to render the following frame\n    YOffset: LongWord;            // Y position at which to render the following frame\n    DelayNumer: Word;             // Frame delay fraction numerator\n    DelayDenom: Word;             // Frame delay fraction denominator\n    DisposeOp: Byte;              // Type of frame area disposal to be done after rendering this frame\n    BlendOp: Byte;                // Type of frame area rendering for this frame\n  end;\n  PfcTL = ^TfcTL;\n\n  { pHYs chunk format - encodes the absolute or relative dimensions of pixels.}\n  TpHYs = packed record\n    PixelsPerUnitX: LongWord;\n    PixelsPerUnitY: LongWord;\n    UnitSpecifier: Byte;\n  end;\n  PpHYs = ^TpHYs;\n\nconst\n  { PNG file identifier.}\n  PNGSignature: TChar8 = #$89'PNG'#$0D#$0A#$1A#$0A;\n  { MNG file identifier.}\n  MNGSignature: TChar8 = #$8A'MNG'#$0D#$0A#$1A#$0A;\n  { JNG file identifier.}\n  JNGSignature: TChar8 = #$8B'JNG'#$0D#$0A#$1A#$0A;\n\n  { Constants for chunk identifiers and signature identifiers.\n    They are in big-endian format.}\n  IHDRChunk: TChar4 = 'IHDR';\n  IENDChunk: TChar4 = 'IEND';\n  MHDRChunk: TChar4 = 'MHDR';\n  MENDChunk: TChar4 = 'MEND';\n  JHDRChunk: TChar4 = 'JHDR';\n  IDATChunk: TChar4 = 'IDAT';\n  JDATChunk: TChar4 = 'JDAT';\n  JDAAChunk: TChar4 = 'JDAA';\n  JSEPChunk: TChar4 = 'JSEP';\n  PLTEChunk: TChar4 = 'PLTE';\n  BACKChunk: TChar4 = 'BACK';\n  DEFIChunk: TChar4 = 'DEFI';\n  TERMChunk: TChar4 = 'TERM';\n  tRNSChunk: TChar4 = 'tRNS';\n  bKGDChunk: TChar4 = 'bKGD';\n  gAMAChunk: TChar4 = 'gAMA';\n  acTLChunk: TChar4 = 'acTL';\n  fcTLChunk: TChar4 = 'fcTL';\n  fdATChunk: TChar4 = 'fdAT';\n  pHYsChunk: TChar4 = 'pHYs';\n\n  { APNG frame dispose operations.}\n  DisposeOpNone       = 0;\n  DisposeOpBackground = 1;\n  DisposeOpPrevious   = 2;\n\n  { APNG frame blending modes}\n  BlendOpSource = 0;\n  BlendOpOver   = 1;\n\n  { Interlace start and offsets.}\n  RowStart: array[0..6] of LongInt = (0, 0, 4, 0, 2, 0, 1);\n  ColumnStart: array[0..6] of LongInt = (0, 4, 0, 2, 0, 1, 0);\n  RowIncrement: array[0..6] of LongInt = (8, 8, 8, 4, 4, 2, 2);\n  ColumnIncrement: array[0..6] of LongInt = (8, 8, 4, 4, 2, 2, 1);\n\ntype\n  { Helper class that holds information about MNG frame in PNG or JNG format.}\n  TFrameInfo = class\n  public\n    Index: Integer;\n    FrameWidth, FrameHeight: LongInt;\n    IsJpegFrame: Boolean;\n    IHDR: TIHDR;\n    JHDR: TJHDR;\n    fcTL: TfcTL;\n    pHYs: TpHYs;\n    Palette: PPalette24;\n    PaletteEntries: LongInt;\n    Transparency: Pointer;\n    TransparencySize: LongInt;\n    Background: Pointer;\n    BackgroundSize: LongInt;\n    IDATMemory: TMemoryStream;\n    JDATMemory: TMemoryStream;\n    JDAAMemory: TMemoryStream;\n    constructor Create(AIndex: Integer);\n    destructor Destroy; override;\n    procedure AssignSharedProps(Source: TFrameInfo);\n  end;\n\n  { Defines type of Network Graphics file.}\n  TNGFileType = (ngPNG, ngAPNG, ngMNG, ngJNG);\n\n  TNGFileHandler = class\n  public\n    FileFormat: TNetworkGraphicsFileFormat;\n    FileType: TNGFileType;\n    Frames: array of TFrameInfo;\n    MHDR: TMHDR; // Main header for MNG files\n    acTL: TacTL; // Global anim control for APNG files\n    GlobalPalette: PPalette24;\n    GlobalPaletteEntries: LongInt;\n    GlobalTransparency: Pointer;\n    GlobalTransparencySize: LongInt;\n    constructor Create(AFileFormat: TNetworkGraphicsFileFormat);\n    destructor Destroy; override;\n    procedure Clear;\n    function GetLastFrame: TFrameInfo;\n    function AddFrameInfo: TFrameInfo;\n    procedure LoadMetaData;\n  end;\n\n  { Network Graphics file parser and frame converter.}\n  TNGFileLoader = class(TNGFileHandler)\n  public\n    function LoadFile(Handle: TImagingHandle): Boolean;\n    procedure LoadImageFromPNGFrame(FrameWidth, FrameHeight: LongInt; const IHDR: TIHDR; IDATStream: TMemoryStream; var Image: TImageData);\n{$IFNDEF DONT_LINK_JNG}\n    procedure LoadImageFromJNGFrame(FrameWidth, FrameHeight: LongInt; const JHDR: TJHDR; IDATStream, JDATStream, JDAAStream: TMemoryStream; var Image: TImageData);\n{$ENDIF}\n    procedure ApplyFrameSettings(Frame: TFrameInfo; var Image: TImageData);\n  end;\n\n  TNGFileSaver = class(TNGFileHandler)\n  public\n    PreFilter: LongInt;\n    CompressLevel: LongInt;\n    LossyAlpha: Boolean;\n    Quality: LongInt;\n    Progressive: Boolean;\n    ZLibStrategy: Integer;\n    function SaveFile(Handle: TImagingHandle): Boolean;\n    procedure AddFrame(const Image: TImageData; IsJpegFrame: Boolean);\n    procedure StoreImageToPNGFrame(const IHDR: TIHDR; Bits: Pointer; FmtInfo: TImageFormatInfo; IDATStream: TMemoryStream);\n{$IFNDEF DONT_LINK_JNG}\n    procedure StoreImageToJNGFrame(const JHDR: TJHDR; const Image: TImageData; IDATStream, JDATStream, JDAAStream: TMemoryStream);\n{$ENDIF}\n    procedure SetFileOptions;\n  end;\n\n{$IFNDEF DONT_LINK_JNG}\n  TCustomIOJpegFileFormat = class(TJpegFileFormat)\n  protected\n    FCustomIO: TIOFunctions;\n    procedure SetJpegIO(const JpegIO: TIOFunctions); override;\n    procedure SetCustomIO(const CustomIO: TIOFunctions);\n  end;\n{$ENDIF}\n\n  TAPNGAnimator = class\n  public\n    class procedure Animate(var Images: TDynImageDataArray; const acTL: TacTL; const SrcFrames: array of TFrameInfo);\n  end;\n\n{ Helper routines }\n\nfunction PaethPredictor(A, B, C: LongInt): LongInt; {$IFDEF USE_INLINE}inline;{$ENDIF}\nvar\n  P, PA, PB, PC: LongInt;\nbegin\n  P := A + B - C;\n  PA := Abs(P - A);\n  PB := Abs(P - B);\n  PC := Abs(P - C);\n  if (PA <= PB) and (PA <= PC) then\n    Result := A\n  else\n    if PB <= PC then\n      Result := B\n    else\n      Result := C;\nend;\n\nprocedure SwapRGB(Line: PByte; Width, SampleDepth, BytesPerPixel: LongInt);\nvar\n  I: LongInt;\n  Tmp: Word;\nbegin\n  case SampleDepth of\n    8:\n      for I := 0 to Width - 1 do\n      with PColor24Rec(Line)^ do\n      begin\n        Tmp := R;\n        R := B;\n        B := Tmp;\n        Inc(Line, BytesPerPixel);\n      end;\n    16:\n      for I := 0 to Width - 1 do\n      with PColor48Rec(Line)^ do\n      begin\n        Tmp := R;\n        R := B;\n        B := Tmp;\n        Inc(Line, BytesPerPixel);\n      end;\n    end;\n end;\n\n{$IFNDEF DONT_LINK_JNG}\n\n{ TCustomIOJpegFileFormat class implementation }\n\nprocedure TCustomIOJpegFileFormat.SetCustomIO(const CustomIO: TIOFunctions);\nbegin\n  FCustomIO := CustomIO;\nend;\n\nprocedure TCustomIOJpegFileFormat.SetJpegIO(const JpegIO: TIOFunctions);\nbegin\n  inherited SetJpegIO(FCustomIO);\nend;\n\n{$ENDIF}\n\n{ TFrameInfo class implementation }\n\nconstructor TFrameInfo.Create(AIndex: Integer);\nbegin\n  Index := AIndex;\n  IDATMemory := TMemoryStream.Create;\n  JDATMemory := TMemoryStream.Create;\n  JDAAMemory := TMemoryStream.Create;\nend;\n\ndestructor TFrameInfo.Destroy;\nbegin\n  FreeMem(Palette);\n  FreeMem(Transparency);\n  FreeMem(Background);\n  IDATMemory.Free;\n  JDATMemory.Free;\n  JDAAMemory.Free;\n  inherited Destroy;\nend;\n\nprocedure TFrameInfo.AssignSharedProps(Source: TFrameInfo);\nbegin\n  IHDR := Source.IHDR;\n  JHDR := Source.JHDR;\n  PaletteEntries := Source.PaletteEntries;\n  GetMem(Palette, PaletteEntries * SizeOf(TColor24Rec));\n  Move(Source.Palette^, Palette^, PaletteEntries * SizeOf(TColor24Rec));\n  TransparencySize := Source.TransparencySize;\n  GetMem(Transparency, TransparencySize);\n  Move(Source.Transparency^, Transparency^, TransparencySize);\nend;\n\n{ TNGFileHandler class implementation}\n\ndestructor TNGFileHandler.Destroy;\nbegin\n  Clear;\n  inherited Destroy;\nend;\n\nprocedure TNGFileHandler.Clear;\nvar\n  I: LongInt;\nbegin\n  for I := 0 to Length(Frames) - 1 do\n    Frames[I].Free;\n  SetLength(Frames, 0);\n  FreeMemNil(GlobalPalette);\n  GlobalPaletteEntries := 0;\n  FreeMemNil(GlobalTransparency);\n  GlobalTransparencySize := 0;\nend;\n\nconstructor TNGFileHandler.Create(AFileFormat: TNetworkGraphicsFileFormat);\nbegin\n  FileFormat := AFileFormat;\nend;\n\nfunction TNGFileHandler.GetLastFrame: TFrameInfo;\nvar\n  Len: LongInt;\nbegin\n  Len := Length(Frames);\n  if Len > 0 then\n    Result := Frames[Len - 1]\n  else\n    Result := nil;\nend;\n\nprocedure TNGFileHandler.LoadMetaData;\nvar\n  I: Integer;\n  Delay, Denom: Integer;\nbegin\n  if FileType = ngAPNG then\n  begin\n    // Num plays of APNG animation\n    FileFormat.FMetadata.SetMetaItem(SMetaAnimationLoops, acTL.NumPlay);\n  end;\n\n  for I := 0 to High(Frames) do\n  begin\n    if Frames[I].pHYs.UnitSpecifier = 1 then\n    begin\n      // Store physical pixel dimensions, in PNG stored as pixels per meter DPM\n      FileFormat.FMetadata.SetPhysicalPixelSize(ruDpm, Frames[I].pHYs.PixelsPerUnitX,\n        Frames[I].pHYs.PixelsPerUnitY);\n    end;\n    if FileType = ngAPNG then\n    begin\n      // Store frame delay of APNG file frame\n      Denom := Frames[I].fcTL.DelayDenom;\n      if Denom = 0 then\n        Denom := 100;\n      Delay := Round(1000 * (Frames[I].fcTL.DelayNumer / Denom));\n      FileFormat.FMetadata.SetMetaItem(SMetaFrameDelay, Delay, I);\n    end;\n  end;\nend;\n\nfunction TNGFileHandler.AddFrameInfo: TFrameInfo;\nvar\n  Len: LongInt;\nbegin\n  Len := Length(Frames);\n  SetLength(Frames, Len + 1);\n  Result := TFrameInfo.Create(Len);\n  Frames[Len] := Result;\nend;\n\n{ TNGFileLoader class implementation}\n\nfunction TNGFileLoader.LoadFile(Handle: TImagingHandle): Boolean;\nvar\n  Sig: TChar8;\n  Chunk: TChunkHeader;\n  ChunkData: Pointer;\n  ChunkCrc: LongWord;\n\n  procedure ReadChunk;\n  begin\n    GetIO.Read(Handle, @Chunk, SizeOf(Chunk));\n    Chunk.DataSize := SwapEndianLongWord(Chunk.DataSize);\n  end;\n\n  procedure ReadChunkData;\n  var\n    ReadBytes: LongWord;\n  begin\n    FreeMemNil(ChunkData);\n    GetMem(ChunkData, Chunk.DataSize);\n    ReadBytes := GetIO.Read(Handle, ChunkData, Chunk.DataSize);\n    GetIO.Read(Handle, @ChunkCrc, SizeOf(ChunkCrc));\n    if ReadBytes <> Chunk.DataSize then\n      RaiseImaging(SErrorLoadingChunk, [string(Chunk.ChunkID)]);\n  end;\n\n  procedure SkipChunkData;\n  begin\n    GetIO.Seek(Handle, Chunk.DataSize + SizeOf(ChunkCrc), smFromCurrent);\n  end;\n\n  procedure StartNewPNGImage;\n  var\n    Frame: TFrameInfo;\n  begin\n    ReadChunkData;\n\n    if Chunk.ChunkID = fcTLChunk then\n    begin\n      if (Length(Frames) = 1) and (Frames[0].IDATMemory.Size = 0) then\n      begin\n        // First fcTL chunk maybe for first IDAT frame which is alredy created\n        Frame := Frames[0];\n      end\n      else\n      begin\n        // Subsequent APNG frames with data in fdAT\n        Frame := AddFrameInfo;\n        // Copy some shared props from first frame (IHDR is the same for all APNG frames, palette etc)\n        Frame.AssignSharedProps(Frames[0]);\n      end;\n      Frame.fcTL := PfcTL(ChunkData)^;\n      SwapEndianLongWord(@Frame.fcTL, 5);\n      Frame.fcTL.DelayNumer := SwapEndianWord(Frame.fcTL.DelayNumer);\n      Frame.fcTL.DelayDenom := SwapEndianWord(Frame.fcTL.DelayDenom);\n      Frame.FrameWidth := Frame.fcTL.Width;\n      Frame.FrameHeight := Frame.fcTL.Height;\n    end\n    else\n    begin\n      // This is frame defined by IHDR chunk\n      Frame := AddFrameInfo;\n      Frame.IHDR := PIHDR(ChunkData)^;\n      SwapEndianLongWord(@Frame.IHDR, 2);\n      Frame.FrameWidth := Frame.IHDR.Width;\n      Frame.FrameHeight := Frame.IHDR.Height;\n    end;\n    Frame.IsJpegFrame := False;\n  end;\n\n  procedure StartNewJNGImage;\n  var\n    Frame: TFrameInfo;\n  begin\n    ReadChunkData;\n    Frame := AddFrameInfo;\n    Frame.IsJpegFrame := True;\n    Frame.JHDR := PJHDR(ChunkData)^;\n    SwapEndianLongWord(@Frame.JHDR, 2);\n    Frame.FrameWidth := Frame.JHDR.Width;\n    Frame.FrameHeight := Frame.JHDR.Height;\n  end;\n\n  procedure AppendIDAT;\n  begin\n    ReadChunkData;\n    // Append current IDAT/fdAT chunk to storage stream\n    if Chunk.ChunkID = IDATChunk then\n      GetLastFrame.IDATMemory.Write(ChunkData^, Chunk.DataSize)\n    else if Chunk.ChunkID = fdATChunk then\n      GetLastFrame.IDATMemory.Write(PByteArray(ChunkData)[4], Chunk.DataSize - SizeOf(LongWord));\n  end;\n\n  procedure AppendJDAT;\n  begin\n    ReadChunkData;\n    // Append current JDAT chunk to storage stream\n    GetLastFrame.JDATMemory.Write(ChunkData^, Chunk.DataSize);\n  end;\n\n  procedure AppendJDAA;\n  begin\n    ReadChunkData;\n    // Append current JDAA chunk to storage stream\n    GetLastFrame.JDAAMemory.Write(ChunkData^, Chunk.DataSize);\n  end;\n\n  procedure LoadPLTE;\n  begin\n    ReadChunkData;\n    if GetLastFrame = nil then\n    begin\n      // Load global palette\n      GetMem(GlobalPalette, Chunk.DataSize);\n      Move(ChunkData^, GlobalPalette^, Chunk.DataSize);\n      GlobalPaletteEntries := Chunk.DataSize div 3;\n    end\n    else if GetLastFrame.Palette = nil then\n    begin\n      if (Chunk.DataSize = 0) and (GlobalPalette <> nil) then\n      begin\n        // Use global palette\n        GetMem(GetLastFrame.Palette, GlobalPaletteEntries * SizeOf(TColor24Rec));\n        Move(GlobalPalette^, GetLastFrame.Palette^, GlobalPaletteEntries * SizeOf(TColor24Rec));\n        GetLastFrame.PaletteEntries := GlobalPaletteEntries;\n      end\n      else\n      begin\n        // Load pal from PLTE chunk\n        GetMem(GetLastFrame.Palette, Chunk.DataSize);\n        Move(ChunkData^, GetLastFrame.Palette^, Chunk.DataSize);\n        GetLastFrame.PaletteEntries := Chunk.DataSize div 3;\n      end;\n    end;\n  end;\n\n  procedure LoadtRNS;\n  begin\n    ReadChunkData;\n    if GetLastFrame = nil then\n    begin\n      // Load global transparency\n      GetMem(GlobalTransparency, Chunk.DataSize);\n      Move(ChunkData^, GlobalTransparency^, Chunk.DataSize);\n      GlobalTransparencySize := Chunk.DataSize;\n    end\n    else if GetLastFrame.Transparency = nil then\n    begin\n      if (Chunk.DataSize = 0) and (GlobalTransparency <> nil) then\n      begin\n        // Use global transparency\n        GetMem(GetLastFrame.Transparency, GlobalTransparencySize);\n        Move(GlobalTransparency^, GetLastFrame.Transparency^, Chunk.DataSize);\n        GetLastFrame.TransparencySize := GlobalTransparencySize;\n      end\n      else\n      begin\n        // Load pal from tRNS chunk\n        GetMem(GetLastFrame.Transparency, Chunk.DataSize);\n        Move(ChunkData^, GetLastFrame.Transparency^, Chunk.DataSize);\n        GetLastFrame.TransparencySize := Chunk.DataSize;\n      end;\n    end;\n  end;\n\n  procedure LoadbKGD;\n  begin\n    ReadChunkData;\n    if GetLastFrame.Background = nil then\n    begin\n      GetMem(GetLastFrame.Background, Chunk.DataSize);\n      Move(ChunkData^, GetLastFrame.Background^, Chunk.DataSize);\n      GetLastFrame.BackgroundSize := Chunk.DataSize;\n    end;\n  end;\n\n  procedure HandleacTL;\n  begin\n    FileType := ngAPNG;\n    ReadChunkData;\n    acTL := PacTL(ChunkData)^;\n    SwapEndianLongWord(@acTL, SizeOf(acTL) div SizeOf(LongWord));\n  end;\n\n  procedure LoadpHYs;\n  begin\n    ReadChunkData;\n    with GetLastFrame do\n    begin\n      pHYs := PpHYs(ChunkData)^;\n      SwapEndianLongWord(@pHYs, SizeOf(pHYs) div SizeOf(LongWord));\n    end;\n  end;\n\nbegin\n  Result := False;\n  Clear;\n  ChunkData := nil;\n  with GetIO do\n  try\n    Read(Handle, @Sig, SizeOf(Sig));\n    // Set file type according to the signature\n    if Sig = PNGSignature then FileType := ngPNG\n    else if Sig = MNGSignature then FileType := ngMNG\n    else if Sig = JNGSignature then FileType := ngJNG\n    else Exit;\n\n    if FileType = ngMNG then\n    begin\n      // Store MNG header if present\n      ReadChunk;\n      ReadChunkData;\n      MHDR := PMHDR(ChunkData)^;\n      SwapEndianLongWord(@MHDR, SizeOf(MHDR) div SizeOf(LongWord));\n    end;\n\n    // Read chunks until ending chunk or EOF is reached\n    repeat\n      ReadChunk;\n      if (Chunk.ChunkID = IHDRChunk) or (Chunk.ChunkID = fcTLChunk) then StartNewPNGImage\n      else if Chunk.ChunkID = JHDRChunk then StartNewJNGImage\n      else if (Chunk.ChunkID = IDATChunk) or (Chunk.ChunkID = fdATChunk) then AppendIDAT\n      else if Chunk.ChunkID = JDATChunk then AppendJDAT\n      else if Chunk.ChunkID = JDAAChunk then AppendJDAA\n      else if Chunk.ChunkID = PLTEChunk then LoadPLTE\n      else if Chunk.ChunkID = tRNSChunk then LoadtRNS\n      else if Chunk.ChunkID = bKGDChunk then LoadbKGD\n      else if Chunk.ChunkID = acTLChunk then HandleacTL\n      else if Chunk.ChunkID = pHYsChunk then LoadpHYs\n      else SkipChunkData;\n    until Eof(Handle) or (Chunk.ChunkID = MENDChunk) or\n      ((FileType <> ngMNG) and (Chunk.ChunkID = IENDChunk));\n\n    Result := True;\n  finally\n    FreeMemNil(ChunkData);\n  end;\nend;\n\nprocedure TNGFileLoader.LoadImageFromPNGFrame(FrameWidth, FrameHeight: LongInt; const IHDR: TIHDR;\n  IDATStream: TMemoryStream; var Image: TImageData);\ntype\n  TGetPixelFunc = function(Line: PByteArray; X: LongInt): Byte;\nvar\n  LineBuffer: array[Boolean] of PByteArray;\n  ActLine: Boolean;\n  Data, TotalBuffer, ZeroLine, PrevLine: Pointer;\n  BitCount, TotalSize, TotalPos, BytesPerPixel, I, Pass,\n  SrcDataSize, BytesPerLine, InterlaceLineBytes, InterlaceWidth: LongInt;\n  Info: TImageFormatInfo;\n\n  procedure DecodeAdam7;\n  const\n    BitTable: array[1..8] of LongInt = ($1, $3, 0, $F, 0, 0, 0, $FF);\n    StartBit: array[1..8] of LongInt = (7, 6, 0, 4, 0, 0, 0, 0);\n  var\n    Src, Dst, Dst2: PByte;\n    CurBit, Col: LongInt;\n  begin\n    Src := @LineBuffer[ActLine][1];\n    Col := ColumnStart[Pass];\n    with Image do\n      case BitCount of\n        1, 2, 4:\n          begin\n            Dst := @PByteArray(Data)[I * BytesPerLine];\n            repeat\n              CurBit := StartBit[BitCount];\n              repeat\n                Dst2 := @PByteArray(Dst)[(BitCount * Col) shr 3];\n                Dst2^ := Dst2^ or ((Src^ shr CurBit) and BitTable[BitCount])\n                  shl (StartBit[BitCount] - (Col * BitCount mod 8));\n                Inc(Col, ColumnIncrement[Pass]);\n                Dec(CurBit, BitCount);\n              until CurBit < 0;\n              Inc(Src);\n            until Col >= Width;\n          end;\n        else\n        begin\n          Dst := @PByteArray(Data)[I * BytesPerLine + Col * BytesPerPixel];\n          repeat\n            CopyPixel(Src, Dst, BytesPerPixel);\n            Inc(Dst, BytesPerPixel);\n            Inc(Src, BytesPerPixel);\n            Inc(Dst, ColumnIncrement[Pass] * BytesPerPixel - BytesPerPixel);\n            Inc(Col, ColumnIncrement[Pass]);\n          until Col >= Width;\n        end;\n      end;\n  end;\n\n  procedure FilterScanline(Filter: Byte; BytesPerPixel: LongInt; Line, PrevLine, Target: PByteArray;\n    BytesPerLine: LongInt);\n  var\n    I: LongInt;\n  begin\n    case Filter of\n      0:\n        begin\n          // No filter\n          Move(Line^, Target^, BytesPerLine);\n        end;\n      1:\n        begin\n          // Sub filter\n          Move(Line^, Target^, BytesPerPixel);\n          for I := BytesPerPixel to BytesPerLine - 1 do\n            Target[I] := (Line[I] + Target[I - BytesPerPixel]) and $FF;\n        end;\n      2:\n        begin\n          // Up filter\n          for I := 0 to BytesPerLine - 1 do\n            Target[I] := (Line[I] + PrevLine[I]) and $FF;\n        end;\n      3:\n        begin\n          // Average filter\n          for I := 0 to BytesPerPixel - 1 do\n            Target[I] := (Line[I] + PrevLine[I] shr 1) and $FF;\n          for I := BytesPerPixel to BytesPerLine - 1 do\n            Target[I] := (Line[I] + (Target[I - BytesPerPixel] + PrevLine[I]) shr 1) and $FF;\n        end;\n      4:\n        begin\n          // Paeth filter\n          for I := 0 to BytesPerPixel - 1 do\n            Target[I] := (Line[I] + PaethPredictor(0, PrevLine[I], 0)) and $FF;\n          for I := BytesPerPixel to BytesPerLine - 1 do\n            Target[I] := (Line[I] + PaethPredictor(Target[I - BytesPerPixel], PrevLine[I], PrevLine[I - BytesPerPixel])) and $FF;\n        end;\n    end;\n  end;\n\n  procedure TransformLOCOToRGB(Data: PByte; NumPixels, BytesPerPixel: LongInt);\n  var\n    I: LongInt;\n  begin\n    for I := 0 to NumPixels - 1 do\n    begin\n      if IHDR.BitDepth = 8 then\n      begin\n        PColor32Rec(Data).R := Byte(PColor32Rec(Data).R + PColor32Rec(Data).G);\n        PColor32Rec(Data).B := Byte(PColor32Rec(Data).B + PColor32Rec(Data).G);\n      end\n      else\n      begin\n        PColor64Rec(Data).R := Word(PColor64Rec(Data).R + PColor64Rec(Data).G);\n        PColor64Rec(Data).B := Word(PColor64Rec(Data).B + PColor64Rec(Data).G);\n      end;\n      Inc(Data, BytesPerPixel);\n    end;\n  end;\n\n  function CheckBinaryPalette: Boolean;\n  begin\n    with GetLastFrame do\n      Result := (PaletteEntries = 2) and\n        (Palette[0].R = 0) and (Palette[0].G = 0) and (Palette[0].B = 0) and\n        (Palette[1].R = 255) and (Palette[1].G = 255) and (Palette[1].B = 255);\n  end;\n\nbegin\n  Image.Width := FrameWidth;\n  Image.Height := FrameHeight;\n  Image.Format := ifUnknown;\n\n  case IHDR.ColorType of\n    0:\n      begin\n        // Gray scale image\n        case IHDR.BitDepth of\n          1:       Image.Format := ifBinary;\n          2, 4, 8: Image.Format := ifGray8;\n          16:      Image.Format := ifGray16;\n        end;\n        BitCount := IHDR.BitDepth;\n      end;\n    2:\n      begin\n        // RGB image\n        case IHDR.BitDepth of\n          8:  Image.Format := ifR8G8B8;\n          16: Image.Format := ifR16G16B16;\n        end;\n        BitCount := IHDR.BitDepth * 3;\n      end;\n    3:\n      begin\n        // Indexed image\n        if (IHDR.BitDepth = 1) and CheckBinaryPalette  then\n          Image.Format := ifBinary\n        else\n          Image.Format := ifIndex8;\n        BitCount := IHDR.BitDepth;\n      end;\n    4:\n      begin\n        // Grayscale + alpha image\n        case IHDR.BitDepth of\n          8: Image.Format := ifA8Gray8;\n          16: Image.Format := ifA16Gray16;\n        end;\n        BitCount := IHDR.BitDepth * 2;\n      end;\n    6:\n      begin\n        // ARGB image\n        case IHDR.BitDepth of\n          8: Image.Format := ifA8R8G8B8;\n          16: Image.Format := ifA16R16G16B16;\n        end;\n        BitCount := IHDR.BitDepth * 4;\n      end;\n  end;\n\n  GetImageFormatInfo(Image.Format, Info);\n  BytesPerPixel := (BitCount + 7) div 8;\n\n  LineBuffer[True] := nil;\n  LineBuffer[False] := nil;\n  TotalBuffer := nil;\n  ZeroLine := nil;\n  ActLine := True;\n\n  // Start decoding\n  with Image do\n  try\n    BytesPerLine := (Width * BitCount + 7) div 8;\n    SrcDataSize := Height * BytesPerLine;\n    GetMem(Data, SrcDataSize);\n    FillChar(Data^, SrcDataSize, 0);\n    GetMem(ZeroLine, BytesPerLine);\n    FillChar(ZeroLine^, BytesPerLine, 0);\n\n    if IHDR.Interlacing = 1 then\n    begin\n      // Decode interlaced images\n      TotalPos := 0;\n      DecompressBuf(IDATStream.Memory, IDATStream.Size, 0,\n        Pointer(TotalBuffer), TotalSize);\n      GetMem(LineBuffer[True], BytesPerLine + 1);\n      GetMem(LineBuffer[False], BytesPerLine + 1);\n      for Pass := 0 to 6 do\n      begin\n        // Prepare next interlace run\n        if Width <= ColumnStart[Pass] then\n          Continue;\n        InterlaceWidth := (Width + ColumnIncrement[Pass] - 1 -\n          ColumnStart[Pass]) div ColumnIncrement[Pass];\n        InterlaceLineBytes := (InterlaceWidth * BitCount + 7) shr 3;\n        I := RowStart[Pass];\n        FillChar(LineBuffer[True][0], BytesPerLine + 1, 0);\n        FillChar(LineBuffer[False][0], BytesPerLine + 1, 0);\n        while I < Height do\n        begin\n          // Copy line from decompressed data to working buffer\n          Move(PByteArray(TotalBuffer)[TotalPos],\n            LineBuffer[ActLine][0], InterlaceLineBytes + 1);\n          Inc(TotalPos, InterlaceLineBytes + 1);\n          // Swap red and blue channels if necessary\n          if (IHDR.ColorType in [2, 6]) then\n            SwapRGB(@LineBuffer[ActLine][1], InterlaceWidth, IHDR.BitDepth, BytesPerPixel);\n          // Reverse-filter current scanline\n          FilterScanline(LineBuffer[ActLine][0], BytesPerPixel,\n            @LineBuffer[ActLine][1], @LineBuffer[not ActLine][1],\n            @LineBuffer[ActLine][1], InterlaceLineBytes);\n          // Decode Adam7 interlacing\n          DecodeAdam7;\n          ActLine := not ActLine;\n          // Continue with next row in interlaced order\n          Inc(I, RowIncrement[Pass]);\n        end;\n      end;\n    end\n    else\n    begin\n      // Decode non-interlaced images\n      PrevLine := ZeroLine;\n      DecompressBuf(IDATStream.Memory, IDATStream.Size, SrcDataSize + Height,\n        Pointer(TotalBuffer), TotalSize);\n      for I := 0 to Height - 1 do\n      begin\n        // Swap red and blue channels if necessary\n        if IHDR.ColorType in [2, 6] then\n          SwapRGB(@PByteArray(TotalBuffer)[I * (BytesPerLine + 1) + 1], Width,\n           IHDR.BitDepth, BytesPerPixel);\n        // reverse-filter current scanline\n        FilterScanline(PByteArray(TotalBuffer)[I * (BytesPerLine + 1)],\n          BytesPerPixel, @PByteArray(TotalBuffer)[I * (BytesPerLine + 1) + 1],\n          PrevLine, @PByteArray(Data)[I * BytesPerLine], BytesPerLine);\n        PrevLine := @PByteArray(Data)[I * BytesPerLine];\n      end;\n    end;\n\n    Size := Info.GetPixelsSize(Info.Format, Width, Height);\n\n    if Size <> SrcDataSize then\n    begin\n      // If source data size is different from size of image in assigned\n      // format we must convert it (it is in 1/2/4 bit count)\n      GetMem(Bits, Size);\n      case IHDR.BitDepth of\n        1:\n          begin\n            // Convert only indexed, keep black and white in ifBinary\n            if IHDR.ColorType <> 0 then\n              Convert1To8(Data, Bits, Width, Height, BytesPerLine, False);\n          end;\n        2: Convert2To8(Data, Bits, Width, Height, BytesPerLine, IHDR.ColorType = 0);\n        4: Convert4To8(Data, Bits, Width, Height, BytesPerLine, IHDR.ColorType = 0);\n      end;\n      FreeMem(Data);\n    end\n    else\n    begin\n      // If source data size is the same as size of\n      // image Bits in assigned format we simply copy pointer reference\n      Bits := Data;\n    end;\n\n    // LOCO transformation was used too (only for color types 2 and 6)\n    if (IHDR.Filter = 64) and (IHDR.ColorType in [2, 6]) then\n      TransformLOCOToRGB(Bits, Width * Height, BytesPerPixel);\n\n    // Images with 16 bit channels must be swapped because of PNG's big endianity\n    if IHDR.BitDepth = 16 then\n      SwapEndianWord(Bits, Width * Height * BytesPerPixel div SizeOf(Word));\n  finally\n    FreeMem(LineBuffer[True]);\n    FreeMem(LineBuffer[False]);\n    FreeMem(TotalBuffer);\n    FreeMem(ZeroLine);\n  end;\nend;\n\n{$IFNDEF DONT_LINK_JNG}\n\nprocedure TNGFileLoader.LoadImageFromJNGFrame(FrameWidth, FrameHeight: LongInt; const JHDR: TJHDR; IDATStream,\n  JDATStream, JDAAStream: TMemoryStream; var Image: TImageData);\nvar\n  AlphaImage: TImageData;\n  FakeIHDR: TIHDR;\n  FmtInfo: TImageFormatInfo;\n  I: LongInt;\n  AlphaPtr: PByte;\n  GrayPtr: PWordRec;\n  ColorPtr: PColor32Rec;\n\n  procedure LoadJpegFromStream(Stream: TStream; var DestImage: TImageData);\n  var\n    JpegFormat: TCustomIOJpegFileFormat;\n    Handle: TImagingHandle;\n    DynImages: TDynImageDataArray;\n  begin\n    if JHDR.SampleDepth <> 12 then\n    begin\n      JpegFormat := TCustomIOJpegFileFormat.Create;\n      JpegFormat.SetCustomIO(StreamIO);\n      Stream.Position := 0;\n      Handle := StreamIO.Open(Pointer(Stream), omReadOnly);\n      try\n        JpegFormat.LoadData(Handle, DynImages, True);\n        DestImage := DynImages[0];\n      finally\n        StreamIO.Close(Handle);\n        JpegFormat.Free;\n        SetLength(DynImages, 0);\n      end;\n    end\n    else\n      NewImage(FrameWidth, FrameHeight, ifR8G8B8, DestImage);\n  end;\n\nbegin\n  LoadJpegFromStream(JDATStream, Image);\n\n  // If present separate alpha channel is processed\n  if (JHDR.ColorType in [12, 14]) and (Image.Format in [ifGray8, ifR8G8B8]) then\n  begin\n    InitImage(AlphaImage);\n    if JHDR.AlphaCompression = 0 then\n    begin\n      // Alpha channel is PNG compressed\n      FakeIHDR.Width := JHDR.Width;\n      FakeIHDR.Height := JHDR.Height;\n      FakeIHDR.ColorType := 0;\n      FakeIHDR.BitDepth := JHDR.AlphaSampleDepth;\n      FakeIHDR.Filter := JHDR.AlphaFilter;\n      FakeIHDR.Interlacing := JHDR.AlphaInterlacing;\n\n      LoadImageFromPNGFrame(FrameWidth, FrameHeight, FakeIHDR, IDATStream, AlphaImage);\n    end\n    else\n    begin\n      // Alpha channel is JPEG compressed\n      LoadJpegFromStream(JDAAStream, AlphaImage);\n    end;\n\n    // Check if alpha channel is the same size as image\n    if (Image.Width <> AlphaImage.Width) and (Image.Height <> AlphaImage.Height) then\n      ResizeImage(AlphaImage, Image.Width, Image.Height, rfNearest);\n\n    // Check alpha channels data format\n    GetImageFormatInfo(AlphaImage.Format, FmtInfo);\n    if (FmtInfo.BytesPerPixel > 1) or (not FmtInfo.HasGrayChannel) then\n      ConvertImage(AlphaImage, ifGray8);\n\n    // Convert image to fromat with alpha channel\n    if Image.Format = ifGray8 then\n      ConvertImage(Image, ifA8Gray8)\n    else\n      ConvertImage(Image, ifA8R8G8B8);\n\n    // Combine alpha channel with image\n    AlphaPtr := AlphaImage.Bits;\n    if Image.Format = ifA8Gray8 then\n    begin\n      GrayPtr := Image.Bits;\n      for I := 0 to Image.Width * Image.Height - 1 do\n      begin\n        GrayPtr.High := AlphaPtr^;\n        Inc(GrayPtr);\n        Inc(AlphaPtr);\n      end;\n    end\n    else\n    begin\n      ColorPtr := Image.Bits;\n      for I := 0 to Image.Width * Image.Height - 1 do\n      begin\n        ColorPtr.A := AlphaPtr^;\n        Inc(ColorPtr);\n        Inc(AlphaPtr);\n      end;\n    end;\n\n    FreeImage(AlphaImage);\n  end;\nend;\n\n{$ENDIF}\n\nprocedure TNGFileLoader.ApplyFrameSettings(Frame: TFrameInfo; var Image: TImageData);\nvar\n  FmtInfo: TImageFormatInfo;\n  BackGroundColor: TColor64Rec;\n  ColorKey: TColor64Rec;\n  Alphas: PByteArray;\n  AlphasSize: LongInt;\n  IsColorKeyPresent: Boolean;\n  IsBackGroundPresent: Boolean;\n  IsColorFormat: Boolean;\n\n  procedure ConverttRNS;\n  begin\n    if FmtInfo.IsIndexed then\n    begin\n      if Alphas = nil then\n      begin\n        GetMem(Alphas, Frame.TransparencySize);\n        Move(Frame.Transparency^, Alphas^, Frame.TransparencySize);\n        AlphasSize := Frame.TransparencySize;\n      end;\n    end\n    else if not FmtInfo.HasAlphaChannel then\n    begin\n      FillChar(ColorKey, SizeOf(ColorKey), 0);\n      Move(Frame.Transparency^, ColorKey, Min(Frame.TransparencySize, SizeOf(ColorKey)));\n      if IsColorFormat then\n        SwapValues(ColorKey.R, ColorKey.B);\n      SwapEndianWord(@ColorKey, 3);\n      // 1/2/4 bit images were converted to 8 bit so we must convert color key too\n      if (not Frame.IsJpegFrame) and (Frame.IHDR.ColorType in [0, 4]) then\n        case Frame.IHDR.BitDepth of\n          1: ColorKey.B := Word(ColorKey.B * 255);\n          2: ColorKey.B := Word(ColorKey.B * 85);\n          4: ColorKey.B := Word(ColorKey.B * 17);\n        end;\n      IsColorKeyPresent := True;\n    end;\n  end;\n\n  procedure ConvertbKGD;\n  begin\n    FillChar(BackGroundColor, SizeOf(BackGroundColor), 0);\n    Move(Frame.Background^, BackGroundColor, Min(Frame.BackgroundSize, SizeOf(BackGroundColor)));\n    if IsColorFormat then\n      SwapValues(BackGroundColor.R, BackGroundColor.B);\n    SwapEndianWord(@BackGroundColor, 3);\n    // 1/2/4 bit images were converted to 8 bit so we must convert back color too\n    if (not Frame.IsJpegFrame) and (Frame.IHDR.ColorType in [0, 4]) then\n      case Frame.IHDR.BitDepth of\n        1: BackGroundColor.B := Word(BackGroundColor.B * 255);\n        2: BackGroundColor.B := Word(BackGroundColor.B * 85);\n        4: BackGroundColor.B := Word(BackGroundColor.B * 17);\n      end;\n    IsBackGroundPresent := True;\n  end;\n\n  procedure ReconstructPalette;\n  var\n    I: LongInt;\n  begin\n    with Image do\n    begin\n      GetMem(Palette, FmtInfo.PaletteEntries * SizeOf(TColor32Rec));\n      FillChar(Palette^, FmtInfo.PaletteEntries * SizeOf(TColor32Rec), $FF);\n      // if RGB palette was loaded from file then use it\n      if Frame.Palette <> nil then\n        for I := 0 to Min(Frame.PaletteEntries, FmtInfo.PaletteEntries) - 1 do\n        with Palette[I] do\n        begin\n          R := Frame.Palette[I].B;\n          G := Frame.Palette[I].G;\n          B := Frame.Palette[I].R;\n        end;\n      // if palette alphas were loaded from file then use them\n      if Alphas <> nil then\n      begin\n        for I := 0 to Min(AlphasSize, FmtInfo.PaletteEntries) - 1 do\n          Palette[I].A := Alphas[I];\n      end;\n    end;\n  end;\n\n  procedure ApplyColorKey;\n  var\n    DestFmt: TImageFormat;\n    Col32, Bkg32: TColor32Rec;\n    OldPixel, NewPixel: Pointer;\n  begin\n    case Image.Format of\n      ifGray8: DestFmt := ifA8Gray8;\n      ifGray16: DestFmt := ifA16Gray16;\n      ifR8G8B8: DestFmt := ifA8R8G8B8;\n      ifR16G16B16: DestFmt := ifA16R16G16B16;\n    else\n      DestFmt := ifUnknown;\n    end;\n\n    if DestFmt <> ifUnknown then\n    begin\n      if not IsBackGroundPresent then\n        BackGroundColor := ColorKey;\n      ConvertImage(Image, DestFmt);\n\n      // Now back color and color key must be converted to image's data format, looks ugly\n      case Image.Format of\n        ifA8Gray8:\n          begin\n            Col32 := Color32(0, 0, $FF, Byte(ColorKey.B));\n            Bkg32 := Color32(0, 0, 0, Byte(BackGroundColor.B));\n          end;\n        ifA16Gray16:\n          begin\n            ColorKey.G := $FFFF;\n          end;\n        ifA8R8G8B8:\n          begin\n            Col32 := Color32($FF, Byte(ColorKey.R), Byte(ColorKey.G), Byte(ColorKey.B));\n            Bkg32 := Color32(0, Byte(BackGroundColor.R), Byte(BackGroundColor.G), Byte(BackGroundColor.B));\n          end;\n        ifA16R16G16B16:\n          begin\n            ColorKey.A := $FFFF;\n          end;\n      end;\n\n      if Image.Format in [ifA8Gray8, ifA8R8G8B8] then\n      begin\n        OldPixel := @Col32;\n        NewPixel := @Bkg32;\n      end\n      else\n      begin\n        OldPixel := @ColorKey;\n        NewPixel := @BackGroundColor;\n      end;\n\n      ReplaceColor(Image, 0, 0, Image.Width, Image.Height, OldPixel, NewPixel);\n    end;\n  end;\n\nbegin\n  Alphas := nil;\n  IsColorKeyPresent := False;\n  IsBackGroundPresent := False;\n  GetImageFormatInfo(Image.Format, FmtInfo);\n\n  IsColorFormat := (Frame.IsJpegFrame and (Frame.JHDR.ColorType in [10, 14])) or\n    (not Frame.IsJpegFrame and (Frame.IHDR.ColorType in [2, 6]));\n\n  // Convert some chunk data to useful format\n  if Frame.TransparencySize > 0 then\n    ConverttRNS;\n  if Frame.BackgroundSize > 0 then\n    ConvertbKGD;\n\n  // Build palette for indexed images\n  if FmtInfo.IsIndexed then\n    ReconstructPalette;\n\n  // Apply color keying\n  if IsColorKeyPresent and not FmtInfo.HasAlphaChannel then\n    ApplyColorKey;\n\n  FreeMemNil(Alphas);\nend;\n\n{ TNGFileSaver class implementation }\n\nprocedure TNGFileSaver.StoreImageToPNGFrame(const IHDR: TIHDR; Bits: Pointer;\n  FmtInfo: TImageFormatInfo; IDATStream: TMemoryStream);\nvar\n  TotalBuffer, CompBuffer, ZeroLine, PrevLine: Pointer;\n  FilterLines: array[0..4] of PByteArray;\n  TotalSize, CompSize, I, BytesPerLine, BytesPerPixel: LongInt;\n  Filter: Byte;\n  Adaptive: Boolean;\n\n  procedure FilterScanline(Filter: Byte; BytesPerPixel: LongInt; Line, PrevLine, Target: PByteArray);\n  var\n    I: LongInt;\n  begin\n    case Filter of\n      0:\n        begin\n          // No filter\n          Move(Line^, Target^, BytesPerLine);\n        end;\n      1:\n        begin\n          // Sub filter\n          Move(Line^, Target^, BytesPerPixel);\n          for I := BytesPerPixel to BytesPerLine - 1 do\n            Target[I] := (Line[I] - Line[I - BytesPerPixel]) and $FF;\n        end;\n      2:\n        begin\n          // Up filter\n          for I := 0 to BytesPerLine - 1 do\n            Target[I] := (Line[I] - PrevLine[I]) and $FF;\n        end;\n      3:\n        begin\n          // Average filter\n          for I := 0 to BytesPerPixel - 1 do\n            Target[I] := (Line[I] - PrevLine[I] shr 1) and $FF;\n          for I := BytesPerPixel to BytesPerLine - 1 do\n            Target[I] := (Line[I] - (Line[I - BytesPerPixel] + PrevLine[I]) shr 1) and $FF;\n        end;\n      4:\n        begin\n          // Paeth filter\n          for I := 0 to BytesPerPixel - 1 do\n            Target[I] := (Line[I] - PaethPredictor(0, PrevLine[I], 0)) and $FF;\n          for I := BytesPerPixel to BytesPerLine - 1 do\n            Target[I] := (Line[I] - PaethPredictor(Line[I - BytesPerPixel], PrevLine[I], PrevLine[I - BytesPerPixel])) and $FF;\n        end;\n    end;\n  end;\n\n  procedure AdaptiveFilter(var Filter: Byte; BytesPerPixel: LongInt; Line, PrevLine, Target: PByteArray);\n  var\n    I, J, BestTest: LongInt;\n    Sums: array[0..4] of LongInt;\n  begin\n    // Compute the output scanline using all five filters,\n    // and select the filter that gives the smallest sum of\n    // absolute values of outputs\n    FillChar(Sums, SizeOf(Sums), 0);\n    BestTest := MaxInt;\n    for I := 0 to 4 do\n    begin\n      FilterScanline(I, BytesPerPixel, Line, PrevLine, FilterLines[I]);\n      for J := 0 to BytesPerLine - 1 do\n        Sums[I] := Sums[I] + Abs(ShortInt(FilterLines[I][J]));\n      if Sums[I] < BestTest then\n      begin\n        Filter := I;\n        BestTest := Sums[I];\n      end;\n    end;\n    Move(FilterLines[Filter]^, Target^, BytesPerLine);\n  end;\n  \nbegin\n  // Select precompression filter and compression level\n  Adaptive := False;\n  Filter := 0;\n  case PreFilter of\n    6:\n      if not ((IHDR.BitDepth < 8) or (IHDR.ColorType = 3)) then\n        Adaptive := True;\n    0..4: Filter := PreFilter;\n  else\n    if IHDR.ColorType in [2, 6] then\n      Filter := 4\n  end;\n\n  // Prepare data for compression\n  CompBuffer := nil;\n  FillChar(FilterLines, SizeOf(FilterLines), 0);\n  BytesPerPixel := Max(1, FmtInfo.BytesPerPixel);\n  BytesPerLine := FmtInfo.GetPixelsSize(FmtInfo.Format, LongInt(IHDR.Width), 1);\n  TotalSize := (BytesPerLine + 1) * LongInt(IHDR.Height);\n  GetMem(TotalBuffer, TotalSize);\n  GetMem(ZeroLine, BytesPerLine);\n  FillChar(ZeroLine^, BytesPerLine, 0);\n  PrevLine := ZeroLine;\n\n  if Adaptive then\n  begin\n    for I := 0 to 4 do\n      GetMem(FilterLines[I], BytesPerLine);\n  end;\n\n  try\n    // Process next scanlines\n    for I := 0 to IHDR.Height - 1 do\n    begin\n      // Filter scanline\n      if Adaptive then\n      begin\n        AdaptiveFilter(Filter, BytesPerPixel, @PByteArray(Bits)[I * BytesPerLine],\n          PrevLine, @PByteArray(TotalBuffer)[I * (BytesPerLine + 1) + 1]);\n      end\n      else\n      begin\n        FilterScanline(Filter, BytesPerPixel, @PByteArray(Bits)[I * BytesPerLine],\n          PrevLine, @PByteArray(TotalBuffer)[I * (BytesPerLine + 1) + 1]);\n      end;\n      PrevLine := @PByteArray(Bits)[I * BytesPerLine];\n      // Swap red and blue if necessary\n      if (IHDR.ColorType in [2, 6]) and not FmtInfo.IsRBSwapped then\n      begin\n        SwapRGB(@PByteArray(TotalBuffer)[I * (BytesPerLine + 1) + 1],\n          IHDR.Width, IHDR.BitDepth, BytesPerPixel);\n      end;\n      // Images with 16 bit channels must be swapped because of PNG's big endianess\n      if IHDR.BitDepth = 16 then\n      begin\n        SwapEndianWord(@PByteArray(TotalBuffer)[I * (BytesPerLine + 1) + 1],\n          BytesPerLine div SizeOf(Word));\n      end;\n      // Set filter used for this scanline\n      PByteArray(TotalBuffer)[I * (BytesPerLine + 1)] := Filter;\n    end;\n    // Compress IDAT data\n    CompressBuf(TotalBuffer, TotalSize, CompBuffer, CompSize,\n      CompressLevel, ZLibStrategy);\n    // Write IDAT data to stream\n    IDATStream.WriteBuffer(CompBuffer^, CompSize);\n  finally\n    FreeMem(TotalBuffer);\n    FreeMem(CompBuffer);\n    FreeMem(ZeroLine);\n    if Adaptive then\n      for I := 0 to 4 do\n        FreeMem(FilterLines[I]);\n  end;\nend;\n\n{$IFNDEF DONT_LINK_JNG}\n\nprocedure TNGFileSaver.StoreImageToJNGFrame(const JHDR: TJHDR;\n  const Image: TImageData; IDATStream, JDATStream,\n  JDAAStream: TMemoryStream);\nvar\n  ColorImage, AlphaImage: TImageData;\n  FmtInfo: TImageFormatInfo;\n  AlphaPtr: PByte;\n  GrayPtr: PWordRec;\n  ColorPtr: PColor32Rec;\n  I: LongInt;\n  FakeIHDR: TIHDR;\n\n  procedure SaveJpegToStream(Stream: TStream; const Image: TImageData);\n  var\n    JpegFormat: TCustomIOJpegFileFormat;\n    Handle: TImagingHandle;\n    DynImages: TDynImageDataArray;\n  begin\n    JpegFormat := TCustomIOJpegFileFormat.Create;\n    JpegFormat.SetCustomIO(StreamIO);\n    // Only JDAT stream can be saved progressive\n    if Stream = JDATStream then\n      JpegFormat.FProgressive := Progressive\n    else\n      JpegFormat.FProgressive := False;\n    JpegFormat.FQuality := Quality;\n    SetLength(DynImages, 1);\n    DynImages[0] := Image;\n    Handle := StreamIO.Open(Pointer(Stream), omCreate);\n    try\n      JpegFormat.SaveData(Handle, DynImages, 0);\n    finally\n      StreamIO.Close(Handle);\n      SetLength(DynImages, 0);\n      JpegFormat.Free;\n    end;\n  end;\n\nbegin\n  GetImageFormatInfo(Image.Format, FmtInfo);\n  InitImage(ColorImage);\n  InitImage(AlphaImage);\n\n  if FmtInfo.HasAlphaChannel then\n  begin\n    // Create new image for alpha channel and color image without alpha\n    CloneImage(Image, ColorImage);\n    NewImage(Image.Width, Image.Height, ifGray8, AlphaImage);\n    case Image.Format of\n      ifA8Gray8:  ConvertImage(ColorImage, ifGray8);\n      ifA8R8G8B8: ConvertImage(ColorImage, ifR8G8B8);\n    end;\n\n    // Store source image's alpha to separate image\n    AlphaPtr := AlphaImage.Bits;\n    if Image.Format = ifA8Gray8 then\n    begin\n      GrayPtr := Image.Bits;\n      for I := 0 to Image.Width * Image.Height - 1 do\n      begin\n        AlphaPtr^ := GrayPtr.High;\n        Inc(GrayPtr);\n        Inc(AlphaPtr);\n      end;\n    end\n    else\n    begin\n      ColorPtr := Image.Bits;\n      for I := 0 to Image.Width * Image.Height - 1 do\n      begin\n        AlphaPtr^ := ColorPtr.A;\n        Inc(ColorPtr);\n        Inc(AlphaPtr);\n      end;\n    end;\n\n    // Write color image to stream as JPEG\n    SaveJpegToStream(JDATStream, ColorImage);\n\n    if LossyAlpha then\n    begin\n      // Write alpha image to stream as JPEG\n      SaveJpegToStream(JDAAStream, AlphaImage);\n    end\n    else\n    begin\n      // Alpha channel is PNG compressed\n      FakeIHDR.Width := JHDR.Width;\n      FakeIHDR.Height := JHDR.Height;\n      FakeIHDR.ColorType := 0;\n      FakeIHDR.BitDepth := JHDR.AlphaSampleDepth;\n      FakeIHDR.Filter := JHDR.AlphaFilter;\n      FakeIHDR.Interlacing := JHDR.AlphaInterlacing;\n\n      GetImageFormatInfo(AlphaImage.Format, FmtInfo);\n      StoreImageToPNGFrame(FakeIHDR, AlphaImage.Bits, FmtInfo, IDATStream);\n    end;\n\n    FreeImage(ColorImage);\n    FreeImage(AlphaImage);\n  end\n  else\n  begin\n    // Simply write JPEG to stream\n    SaveJpegToStream(JDATStream, Image);\n  end;\nend;\n\n{$ENDIF}\n\nprocedure TNGFileSaver.AddFrame(const Image: TImageData; IsJpegFrame: Boolean);\nvar\n  Frame: TFrameInfo;\n  FmtInfo: TImageFormatInfo;\n  Index: Integer;\n\n  procedure StorePalette;\n  var\n    Pal: PPalette24;\n    Alphas: PByteArray;\n    I, PalBytes: LongInt;\n    AlphasDiffer: Boolean;\n  begin\n    // Fill and save RGB part of palette to PLTE chunk\n    PalBytes := FmtInfo.PaletteEntries * SizeOf(TColor24Rec);\n    GetMem(Pal, PalBytes);\n    AlphasDiffer := False;\n    for I := 0 to FmtInfo.PaletteEntries - 1 do\n    begin\n      Pal[I].B := Image.Palette[I].R;\n      Pal[I].G := Image.Palette[I].G;\n      Pal[I].R := Image.Palette[I].B;\n      if Image.Palette[I].A < 255 then\n        AlphasDiffer := True;\n    end;\n    Frame.Palette := Pal;\n    Frame.PaletteEntries := FmtInfo.PaletteEntries;\n    // Fill and save alpha part (if there are any alphas < 255) of palette to tRNS chunk\n    if AlphasDiffer then\n    begin\n      PalBytes := FmtInfo.PaletteEntries * SizeOf(Byte);\n      GetMem(Alphas, PalBytes);\n      for I := 0 to FmtInfo.PaletteEntries - 1 do\n        Alphas[I] := Image.Palette[I].A;\n      Frame.Transparency := Alphas;\n      Frame.TransparencySize := PalBytes;\n    end;\n  end;\n\n  procedure FillFrameControlChunk(const IHDR: TIHDR; var fcTL: TfcTL);\n  var\n    Delay: Integer;\n  begin\n    fcTL.SeqNumber := 0; // Decided when writing to file\n    fcTL.Width := IHDR.Width;\n    fcTL.Height := IHDR.Height;\n    fcTL.XOffset := 0;\n    fcTL.YOffset := 0;\n    fcTL.DelayNumer := 1;\n    fcTL.DelayDenom := 3;\n    if FileFormat.FMetadata.HasMetaItemForSaving(SMetaFrameDelay, Index) then\n    begin\n      // Metadata contains frame delay information in milliseconds\n      Delay := FileFormat.FMetadata.MetaItemsForSavingMulti[SMetaFrameDelay, Index];\n      fcTL.DelayNumer := Delay;\n      fcTL.DelayDenom := 1000;\n    end;\n    fcTL.DisposeOp := DisposeOpNone;\n    fcTL.BlendOp := BlendOpSource;\n    SwapEndianLongWord(@fcTL, 5);\n    fcTL.DelayNumer := SwapEndianWord(fcTL.DelayNumer);\n    fcTL.DelayDenom := SwapEndianWord(fcTL.DelayDenom);\n  end;\n\nbegin\n  // Add new frame\n  Frame := AddFrameInfo;\n  Frame.IsJpegFrame := IsJpegFrame;\n  Index := Length(Frames) - 1;\n\n  with Frame do\n  begin\n    GetImageFormatInfo(Image.Format, FmtInfo);\n\n    if IsJpegFrame then\n    begin\n{$IFNDEF DONT_LINK_JNG}\n      // Fill JNG header\n      JHDR.Width := Image.Width;\n      JHDR.Height := Image.Height;\n      case Image.Format of\n        ifGray8:    JHDR.ColorType := 8;\n        ifR8G8B8:   JHDR.ColorType := 10;\n        ifA8Gray8:  JHDR.ColorType := 12;\n        ifA8R8G8B8: JHDR.ColorType := 14;\n      end;\n      JHDR.SampleDepth := 8; // 8-bit samples and quantization tables\n      JHDR.Compression := 8; // Huffman coding\n      JHDR.Interlacing := Iff(Progressive, 8, 0);\n      JHDR.AlphaSampleDepth := Iff(FmtInfo.HasAlphaChannel, 8, 0);\n      JHDR.AlphaCompression := Iff(LossyAlpha, 8, 0);\n      JHDR.AlphaFilter := 0;\n      JHDR.AlphaInterlacing := 0;\n\n      StoreImageToJNGFrame(JHDR, Image, IDATMemory, JDATMemory, JDAAMemory);\n\n      // Finally swap endian\n      SwapEndianLongWord(@JHDR, 2);\n{$ENDIF}\n    end\n    else\n    begin\n      // Fill PNG header\n      IHDR.Width := Image.Width;\n      IHDR.Height := Image.Height;\n      IHDR.Compression := 0;\n      IHDR.Filter := 0;\n      IHDR.Interlacing := 0;\n      IHDR.BitDepth := FmtInfo.BytesPerPixel * 8;\n\n      // Select appropiate PNG color type and modify bitdepth\n      if FmtInfo.HasGrayChannel then\n      begin\n        IHDR.ColorType := 0;\n        if FmtInfo.HasAlphaChannel then\n        begin\n          IHDR.ColorType := 4;\n          IHDR.BitDepth := IHDR.BitDepth div 2;\n        end;\n      end\n      else if FmtInfo.Format = ifBinary then\n      begin\n        IHDR.ColorType := 0;\n        IHDR.BitDepth := 1;\n      end\n      else if FmtInfo.IsIndexed then\n        IHDR.ColorType := 3\n      else if FmtInfo.HasAlphaChannel then\n      begin\n        IHDR.ColorType := 6;\n        IHDR.BitDepth := IHDR.BitDepth div 4;\n      end\n      else\n      begin\n        IHDR.ColorType := 2;\n        IHDR.BitDepth := IHDR.BitDepth div 3;\n      end;\n\n      if FileType = ngAPNG then\n      begin\n        // Fill fcTL chunk of APNG file\n        FillFrameControlChunk(IHDR, fcTL);\n      end;\n\n      // Compress PNG image and store it to stream\n      StoreImageToPNGFrame(IHDR, Image.Bits, FmtInfo, IDATMemory);\n      // Store palette if necesary\n      if FmtInfo.IsIndexed then\n        StorePalette;\n\n      // Finally swap endian\n      SwapEndianLongWord(@IHDR, 2);\n    end;\n  end;\nend;\n\nfunction TNGFileSaver.SaveFile(Handle: TImagingHandle): Boolean;\nvar\n  I: LongInt;\n  Chunk: TChunkHeader;\n  SeqNo: LongWord;\n\n  function GetNextSeqNo: LongWord;\n  begin\n    // Seq numbers of fcTL and fdAT are \"interleaved\" as they share the counter.\n    // Example: first fcTL for IDAT has seq=0, next is fcTL for seond frame with\n    // seq=1, then first fdAT with seq=2, fcTL seq=3, fdAT=4, ...\n    Result := SwapEndianLongWord(SeqNo);\n    Inc(SeqNo);\n  end;\n\n  function CalcChunkCrc(const ChunkHdr: TChunkHeader; Data: Pointer;\n    Size: LongInt): LongWord;\n  begin\n    Result := $FFFFFFFF;\n    CalcCrc32(Result, @ChunkHdr.ChunkID, SizeOf(ChunkHdr.ChunkID));\n    CalcCrc32(Result, Data, Size);\n    Result := SwapEndianLongWord(Result xor $FFFFFFFF);\n  end;\n\n  procedure WriteChunk(var Chunk: TChunkHeader; ChunkData: Pointer);\n  var\n    ChunkCrc: LongWord;\n    SizeToWrite: LongInt;\n  begin\n    SizeToWrite := Chunk.DataSize;\n    Chunk.DataSize := SwapEndianLongWord(Chunk.DataSize);\n    ChunkCrc := CalcChunkCrc(Chunk, ChunkData, SizeToWrite);\n    GetIO.Write(Handle, @Chunk, SizeOf(Chunk));\n    if SizeToWrite <> 0 then\n      GetIO.Write(Handle, ChunkData, SizeToWrite);\n    GetIO.Write(Handle, @ChunkCrc, SizeOf(ChunkCrc));\n  end;\n\n  procedure WritefdAT(Frame: TFrameInfo);\n  var\n    ChunkCrc: LongWord;\n    ChunkSeqNo: LongWord;\n  begin\n    Chunk.ChunkID := fdATChunk;\n    ChunkSeqNo := GetNextSeqNo;\n    // fdAT saves seq number LongWord before compressed pixels\n    Chunk.DataSize := Frame.IDATMemory.Size + SizeOf(LongWord);\n    Chunk.DataSize := SwapEndianLongWord(Chunk.DataSize);\n    // Calc CRC\n    ChunkCrc := $FFFFFFFF;\n    CalcCrc32(ChunkCrc, @Chunk.ChunkID, SizeOf(Chunk.ChunkID));\n    CalcCrc32(ChunkCrc, @ChunkSeqNo, SizeOf(ChunkSeqNo));\n    CalcCrc32(ChunkCrc, Frame.IDATMemory.Memory, Frame.IDATMemory.Size);\n    ChunkCrc := SwapEndianLongWord(ChunkCrc xor $FFFFFFFF);\n    // Write out all fdAT data\n    GetIO.Write(Handle, @Chunk, SizeOf(Chunk));\n    GetIO.Write(Handle, @ChunkSeqNo, SizeOf(ChunkSeqNo));\n    GetIO.Write(Handle, Frame.IDATMemory.Memory, Frame.IDATMemory.Size);\n    GetIO.Write(Handle, @ChunkCrc, SizeOf(ChunkCrc));\n  end;\n\n  procedure WriteGlobalMetaDataChunks(Frame: TFrameInfo);\n  var\n    XRes, YRes: Single;\n  begin\n    if FileFormat.FMetadata.GetPhysicalPixelSize(ruDpm, XRes, YRes, True) then\n    begin\n      // Save pHYs chunk\n      Frame.pHYs.UnitSpecifier := 1;\n      // PNG stores physical resolution as dots per meter\n      Frame.pHYs.PixelsPerUnitX := Round(XRes);\n      Frame.pHYs.PixelsPerUnitY := Round(YRes);\n\n      Chunk.DataSize := SizeOf(Frame.pHYs);\n      Chunk.ChunkID := pHYsChunk;\n      SwapEndianLongWord(@Frame.pHYs, SizeOf(Frame.pHYs) div SizeOf(LongWord));\n      WriteChunk(Chunk, @Frame.pHYs);\n    end;\n  end;\n\n  procedure WritePNGMainImageChunks(Frame: TFrameInfo);\n  begin\n    with Frame do\n    begin\n      // Write IHDR chunk\n      Chunk.DataSize := SizeOf(IHDR);\n      Chunk.ChunkID := IHDRChunk;\n      WriteChunk(Chunk, @IHDR);\n      // Write PLTE chunk if data is present\n      if Palette <> nil then\n      begin\n        Chunk.DataSize := PaletteEntries * SizeOf(TColor24Rec);\n        Chunk.ChunkID := PLTEChunk;\n        WriteChunk(Chunk, Palette);\n      end;\n      // Write tRNS chunk if data is present\n      if Transparency <> nil then\n      begin\n        Chunk.DataSize := TransparencySize;\n        Chunk.ChunkID := tRNSChunk;\n        WriteChunk(Chunk, Transparency);\n      end;\n    end;\n    // Write metadata related chunks\n    WriteGlobalMetaDataChunks(Frame);\n  end;\n\nbegin\n  Result := False;\n  SeqNo := 0;\n\n  case FileType of\n    ngPNG, ngAPNG: GetIO.Write(Handle, @PNGSignature, SizeOf(TChar8));\n    ngMNG: GetIO.Write(Handle, @MNGSignature, SizeOf(TChar8));\n    ngJNG: GetIO.Write(Handle, @JNGSignature, SizeOf(TChar8));\n  end;\n\n  if FileType = ngMNG then\n  begin\n    // MNG - main header before frames\n    SwapEndianLongWord(@MHDR, SizeOf(MHDR) div SizeOf(LongWord));\n    Chunk.DataSize := SizeOf(MHDR);\n    Chunk.ChunkID := MHDRChunk;\n    WriteChunk(Chunk, @MHDR);\n  end\n  else if FileType = ngAPNG then\n  begin\n    // APNG - IHDR and global chunks for all frames, then acTL chunk, then frames\n    // (fcTL+IDAT, fcTL+fdAT, fcTL+fdAT, fcTL+fdAT, ....)\n    WritePNGMainImageChunks(Frames[0]);\n\n    // Animation control chunk\n    acTL.NumFrames := Length(Frames);\n    if FileFormat.FMetadata.HasMetaItemForSaving(SMetaAnimationLoops) then\n    begin\n      // Number of plays of APNG animation\n      acTL.NumPlay:= FileFormat.FMetadata.MetaItemsForSaving[SMetaAnimationLoops];\n    end\n    else\n      acTL.NumPlay := 0;\n    SwapEndianLongWord(@acTL, SizeOf(acTL) div SizeOf(LongWord));\n\n    Chunk.DataSize := SizeOf(acTL);\n    Chunk.ChunkID := acTLChunk;\n    WriteChunk(Chunk, @acTL);\n  end;\n\n  for I := 0 to Length(Frames) - 1 do\n  with Frames[I] do\n  begin\n    if IsJpegFrame then\n    begin\n      // Write JHDR chunk\n      Chunk.DataSize := SizeOf(JHDR);\n      Chunk.ChunkID := JHDRChunk;\n      WriteChunk(Chunk, @JHDR);\n      // Write metadata related chunks\n      WriteGlobalMetaDataChunks(Frames[I]);\n      // Write JNG image data\n      Chunk.DataSize := JDATMemory.Size;\n      Chunk.ChunkID := JDATChunk;\n      WriteChunk(Chunk, JDATMemory.Memory);\n      // Write alpha channel if present\n      if JHDR.AlphaSampleDepth > 0 then\n      begin\n        if JHDR.AlphaCompression = 0 then\n        begin\n          // Alpha is PNG compressed\n          Chunk.DataSize := IDATMemory.Size;\n          Chunk.ChunkID := IDATChunk;\n          WriteChunk(Chunk, IDATMemory.Memory);\n        end\n        else\n        begin\n          // Alpha is JNG compressed\n          Chunk.DataSize := JDAAMemory.Size;\n          Chunk.ChunkID := JDAAChunk;\n          WriteChunk(Chunk, JDAAMemory.Memory);\n        end;\n      end;\n      // Write image end\n      Chunk.DataSize := 0;\n      Chunk.ChunkID := IENDChunk;\n      WriteChunk(Chunk, nil);\n    end\n    else if FileType <> ngAPNG then\n    begin\n      // Regular PNG frame (single PNG image or MNG frame)\n      WritePNGMainImageChunks(Frames[I]);\n      // Write PNG image data\n      Chunk.DataSize := IDATMemory.Size;\n      Chunk.ChunkID := IDATChunk;\n      WriteChunk(Chunk, IDATMemory.Memory);\n      // Write image end\n      Chunk.DataSize := 0;\n      Chunk.ChunkID := IENDChunk;\n      WriteChunk(Chunk, nil);\n    end\n    else if FileType = ngAPNG then\n    begin\n      // APNG frame - Write fcTL before frame data\n      Chunk.DataSize := SizeOf(fcTL);\n      Chunk.ChunkID := fcTLChunk;\n      fcTl.SeqNumber := GetNextSeqNo;\n      WriteChunk(Chunk, @fcTL);\n      // Write data - IDAT for first frame and fdAT for following ones\n      if I = 0 then\n      begin\n        Chunk.DataSize := IDATMemory.Size;\n        Chunk.ChunkID := IDATChunk;\n        WriteChunk(Chunk, IDATMemory.Memory);\n      end\n      else\n        WritefdAT(Frames[I]);\n      // Write image end after last frame\n      if I = Length(Frames) - 1 then\n      begin\n        Chunk.DataSize := 0;\n        Chunk.ChunkID := IENDChunk;\n        WriteChunk(Chunk, nil);\n      end;\n    end;\n  end;\n\n  if FileType = ngMNG then\n  begin\n    Chunk.DataSize := 0;\n    Chunk.ChunkID := MENDChunk;\n    WriteChunk(Chunk, nil);\n  end;\nend;\n\nprocedure TNGFileSaver.SetFileOptions;\nbegin\n  PreFilter := FileFormat.FPreFilter;\n  CompressLevel := FileFormat.FCompressLevel;\n  LossyAlpha := FileFormat.FLossyAlpha;\n  Quality := FileFormat.FQuality;\n  Progressive := FileFormat.FProgressive;\n  ZLibStrategy := FileFormat.FZLibStategy;\nend;\n\n{ TAPNGAnimator class implementation }\n\nclass procedure TAPNGAnimator.Animate(var Images: TDynImageDataArray;\n  const acTL: TacTL; const SrcFrames: array of TFrameInfo);\nvar\n  I, SrcIdx, Offset, Len: Integer;\n  DestFrames: TDynImageDataArray;\n  SrcCanvas, DestCanvas: TImagingCanvas;\n  PreviousCache: TImageData;\n\n  function AnimatingNeeded: Boolean;\n  var\n    I: Integer;\n  begin\n    Result := False;\n    for I := 0 to Len - 1 do\n    with SrcFrames[I] do\n    begin\n      if (FrameWidth <> Integer(IHDR.Width)) or (FrameHeight <> Integer(IHDR.Height)) or (Len <> Integer(acTL.NumFrames)) or\n        (not ((fcTL.DisposeOp = DisposeOpNone) and (fcTL.BlendOp = BlendOpSource)) and\n        not ((fcTL.DisposeOp = DisposeOpBackground) and (fcTL.BlendOp = BlendOpSource)) and\n        not ((fcTL.DisposeOp = DisposeOpBackground) and (fcTL.BlendOp = BlendOpOver))) then\n      begin\n        Result := True;\n        Exit;\n      end;\n    end;\n  end;\n\nbegin\n  Len := Length(SrcFrames);\n  if (Len = 0) or not AnimatingNeeded then\n    Exit;\n\n  if (Len = Integer(acTL.NumFrames) + 1) and (SrcFrames[0].fcTL.Width = 0) then\n  begin\n    // If default image (stored in IDAT chunk) isn't part of animation we ignore it\n    Offset := 1;\n    Len := Len - 1;\n  end\n  else\n    Offset := 0;\n\n  SetLength(DestFrames, Len);\n  DestCanvas := ImagingCanvases.FindBestCanvasForImage(Images[0]).Create;\n  SrcCanvas := ImagingCanvases.FindBestCanvasForImage(Images[0]).Create;\n  InitImage(PreviousCache);\n  NewImage(SrcFrames[0].IHDR.Width, SrcFrames[0].IHDR.Height, Images[0].Format, PreviousCache);\n\n  for I := 0 to Len - 1 do\n  begin\n    SrcIdx := I + Offset;\n    NewImage(SrcFrames[SrcIdx].IHDR.Width, SrcFrames[SrcIdx].IHDR.Height,\n      Images[SrcIdx].Format, DestFrames[I]);\n    if DestFrames[I].Format = ifIndex8 then\n      Move(Images[SrcIdx].Palette^, DestFrames[I].Palette^, 256 * SizeOf(TColor32));\n    DestCanvas.CreateForData(@DestFrames[I]);\n\n    if (SrcFrames[SrcIdx].fcTL.DisposeOp = DisposeOpPrevious) and (SrcFrames[SrcIdx - 1].fcTL.DisposeOp <> DisposeOpPrevious) then\n    begin\n      // Cache current output buffer so we may return to it later (previous dispose op)\n      CopyRect(DestFrames[I - 1], 0, 0, DestFrames[I - 1].Width, DestFrames[I - 1].Height,\n        PreviousCache, 0, 0);\n    end;\n\n    if (I = 0) or (SrcIdx = 0) then\n    begin\n      // Clear whole frame with transparent black color (default for first frame)\n      DestCanvas.FillColor32 := pcClear;\n      DestCanvas.Clear;\n    end\n    else if SrcFrames[SrcIdx - 1].fcTL.DisposeOp = DisposeOpBackground then\n    begin\n      // Restore background color (clear) on previous frame's area and leave previous content outside of it\n      CopyRect(DestFrames[I - 1], 0, 0, DestFrames[I - 1].Width, DestFrames[I - 1].Height,\n        DestFrames[I], 0, 0);\n      DestCanvas.FillColor32 := pcClear;\n      DestCanvas.FillRect(BoundsToRect(SrcFrames[SrcIdx - 1].fcTL.XOffset, SrcFrames[SrcIdx - 1].fcTL.YOffset,\n        SrcFrames[SrcIdx - 1].FrameWidth, SrcFrames[SrcIdx - 1].FrameHeight));\n    end\n    else if SrcFrames[SrcIdx - 1].fcTL.DisposeOp = DisposeOpNone then\n    begin\n      // Clone previous frame - no change to output buffer\n      CopyRect(DestFrames[I - 1], 0, 0, DestFrames[I - 1].Width, DestFrames[I - 1].Height,\n        DestFrames[I], 0, 0);\n    end\n    else if SrcFrames[SrcIdx - 1].fcTL.DisposeOp = DisposeOpPrevious then\n    begin\n      // Revert to previous frame (cached, can't just restore DestFrames[I - 2])\n      CopyRect(PreviousCache, 0, 0, PreviousCache.Width, PreviousCache.Height,\n        DestFrames[I], 0, 0);\n    end;\n\n    // Copy pixels or alpha blend them over\n    if SrcFrames[SrcIdx].fcTL.BlendOp = BlendOpSource then\n    begin\n      CopyRect(Images[SrcIdx], 0, 0, Images[SrcIdx].Width, Images[SrcIdx].Height,\n        DestFrames[I], SrcFrames[SrcIdx].fcTL.XOffset, SrcFrames[SrcIdx].fcTL.YOffset);\n    end\n    else if SrcFrames[SrcIdx].fcTL.BlendOp = BlendOpOver then\n    begin\n      SrcCanvas.CreateForData(@Images[SrcIdx]);\n      SrcCanvas.DrawAlpha(SrcCanvas.ClipRect, DestCanvas,\n        SrcFrames[SrcIdx].fcTL.XOffset, SrcFrames[SrcIdx].fcTL.YOffset);\n    end;\n\n    FreeImage(Images[SrcIdx]);\n  end;\n\n  DestCanvas.Free;\n  SrcCanvas.Free;\n  FreeImage(PreviousCache);\n\n  // Assign dest frames to final output images\n  Images := DestFrames;\nend;\n\n{ TNetworkGraphicsFileFormat class implementation }\n\nprocedure TNetworkGraphicsFileFormat.Define;\nbegin\n  inherited;\n  FFeatures := [ffLoad, ffSave];\n\n  FPreFilter := NGDefaultPreFilter;\n  FCompressLevel := NGDefaultCompressLevel;\n  FLossyAlpha := NGDefaultLossyAlpha;\n  FLossyCompression := NGDefaultLossyCompression;\n  FQuality := NGDefaultQuality;\n  FProgressive := NGDefaultProgressive;\n  FZLibStategy := NGDefaultZLibStartegy;\nend;\n\nprocedure TNetworkGraphicsFileFormat.CheckOptionsValidity;\nbegin\n  // Just check if save options has valid values\n  if not (FPreFilter in [0..6]) then\n    FPreFilter := NGDefaultPreFilter;\n  if not (FCompressLevel in [0..9]) then\n    FCompressLevel := NGDefaultCompressLevel;\n  if not (FQuality in [1..100]) then\n    FQuality := NGDefaultQuality;\nend;\n\nfunction TNetworkGraphicsFileFormat.GetSupportedFormats: TImageFormats;\nbegin\n  if FLossyCompression then\n    Result := NGLossyFormats\n  else\n    Result := NGLosslessFormats;\nend;\n\nprocedure TNetworkGraphicsFileFormat.ConvertToSupported(var Image: TImageData;\n  const Info: TImageFormatInfo);\nvar\n  ConvFormat: TImageFormat;\nbegin\n  if not FLossyCompression then\n  begin\n    // Convert formats for lossless compression\n    if Info.HasGrayChannel then\n    begin\n      if Info.HasAlphaChannel then\n      begin\n        if Info.BytesPerPixel <= 2 then\n          // Convert <= 16bit grayscale images with alpha to ifA8Gray8\n          ConvFormat := ifA8Gray8\n        else\n          // Convert > 16bit grayscale images with alpha to ifA16Gray16\n          ConvFormat := ifA16Gray16\n      end\n      else\n        // Convert grayscale images without alpha to ifGray16\n        ConvFormat := ifGray16;\n    end\n    else\n      if Info.IsFloatingPoint then\n        // Convert floating point images to 64 bit ARGB (or RGB if no alpha)\n        ConvFormat := IffFormat(Info.HasAlphaChannel, ifA16B16G16R16, ifB16G16R16)\n      else if Info.HasAlphaChannel or Info.IsSpecial then\n        // Convert all other images with alpha or special images to A8R8G8B8\n        ConvFormat := ifA8R8G8B8\n      else\n        // Convert images without alpha to R8G8B8\n        ConvFormat := ifR8G8B8;\n  end\n  else\n  begin\n    // Convert formats for lossy compression\n    if Info.HasGrayChannel then\n      ConvFormat := IffFormat(Info.HasAlphaChannel, ifA8Gray8, ifGray8)\n    else\n      ConvFormat := IffFormat(Info.HasAlphaChannel, ifA8R8G8B8, ifR8G8B8);\n  end;\n\n  ConvertImage(Image, ConvFormat);\nend;\n\nfunction TNetworkGraphicsFileFormat.TestFormat(Handle: TImagingHandle): Boolean;\nvar\n  ReadCount: LongInt;\n  Sig: TChar8;\nbegin\n  Result := False;\n  if Handle <> nil then\n    with GetIO do\n    begin\n      FillChar(Sig, SizeOf(Sig), 0);\n      ReadCount := Read(Handle, @Sig, SizeOf(Sig));\n      Seek(Handle, -ReadCount, smFromCurrent);\n      Result := (ReadCount = SizeOf(Sig)) and (Sig = FSignature);\n    end;\nend;\n\n{ TPNGFileFormat class implementation }\n\nprocedure TPNGFileFormat.Define;\nbegin\n  inherited;\n  FName := SPNGFormatName;\n  FFeatures := FFeatures + [ffMultiImage];\n  FLoadAnimated := PNGDefaultLoadAnimated;\n  AddMasks(SPNGMasks);\n\n  FSignature := PNGSignature;\n\n  RegisterOption(ImagingPNGPreFilter, @FPreFilter);\n  RegisterOption(ImagingPNGCompressLevel, @FCompressLevel);\n  RegisterOption(ImagingPNGLoadAnimated, @FLoadAnimated);\n  RegisterOption(ImagingPNGZLibStrategy, @FZLibStategy);\nend;\n\nfunction TPNGFileFormat.LoadData(Handle: TImagingHandle;\n  var Images: TDynImageDataArray; OnlyFirstLevel: Boolean): Boolean;\nvar\n  I, Len: LongInt;\n  NGFileLoader: TNGFileLoader;\nbegin\n  Result := False;\n  NGFileLoader := TNGFileLoader.Create(Self);\n  try\n    // Use NG file parser to load file\n    if NGFileLoader.LoadFile(Handle) and (Length(NGFileLoader.Frames) > 0) then\n    begin\n      Len := Length(NGFileLoader.Frames);\n      SetLength(Images, Len);\n      for I := 0 to Len - 1 do\n      with NGFileLoader.Frames[I] do\n      begin\n        // Build actual image bits\n        if not IsJpegFrame then\n          NGFileLoader.LoadImageFromPNGFrame(FrameWidth, FrameHeight, IHDR, IDATMemory, Images[I]);\n        // Build palette, aply color key or background\n\n        NGFileLoader.ApplyFrameSettings(NGFileLoader.Frames[I], Images[I]);\n        Result := True;\n      end;\n      // Animate APNG images\n      if (NGFileLoader.FileType = ngAPNG) and FLoadAnimated then\n        TAPNGAnimator.Animate(Images, NGFileLoader.acTL, NGFileLoader.Frames);\n    end;\n  finally\n    NGFileLoader.LoadMetaData; // Store metadata\n    NGFileLoader.Free;\n  end;\nend;\n\nfunction TPNGFileFormat.SaveData(Handle: TImagingHandle;\n  const Images: TDynImageDataArray; Index: LongInt): Boolean;\nvar\n  I: Integer;\n  ImageToSave: TImageData;\n  MustBeFreed: Boolean;\n  NGFileSaver: TNGFileSaver;\n  DefaultFormat: TImageFormat;\n  Screen: TImageData;\n  AnimWidth, AnimHeight: Integer;\nbegin\n  Result := False;\n  DefaultFormat := ifDefault;\n  AnimWidth := 0;\n  AnimHeight := 0;\n  NGFileSaver := TNGFileSaver.Create(Self);\n\n  // Save images with more frames as APNG format\n  if Length(Images) > 1 then\n  begin\n    NGFileSaver.FileType := ngAPNG;\n    // Get max dimensions of frames\n    AnimWidth := Images[FFirstIdx].Width;\n    AnimHeight := Images[FFirstIdx].Height;\n    for I := FFirstIdx + 1 to FLastIdx do\n    begin\n      AnimWidth := Max(AnimWidth, Images[I].Width);\n      AnimHeight := Max(AnimHeight, Images[I].Height);\n    end;\n  end\n  else\n    NGFileSaver.FileType := ngPNG;\n\n  NGFileSaver.SetFileOptions;\n\n  with NGFileSaver do\n  try\n    // Store all frames to be saved frames file saver\n    for I := FFirstIdx to FLastIdx do\n    begin\n      if MakeCompatible(Images[I], ImageToSave, MustBeFreed) then\n      try\n        if FileType = ngAPNG then\n        begin\n          // IHDR chunk is shared for all frames so all frames must have the\n          // same data format as the first image.\n          if I = FFirstIdx then\n          begin\n            DefaultFormat := ImageToSave.Format;\n            // Subsequenet frames may be bigger than the first one.\n            // APNG doens't support this - max allowed size is what's written in\n            // IHDR - size of main/default/first image. If some frame is\n            // bigger than the first one we need to resize (create empty bigger\n            // image and copy) the first frame so all following frames could fit to\n            // its area.\n            if (ImageToSave.Width <> AnimWidth) or (ImageToSave.Height <> AnimHeight) then\n            begin\n              InitImage(Screen);\n              NewImage(AnimWidth, AnimHeight, ImageToSave.Format, Screen);\n              CopyRect(ImageToSave, 0, 0, ImageToSave.Width, ImageToSave.Height, Screen, 0, 0);\n              if MustBeFreed then\n                FreeImage(ImageToSave);\n              ImageToSave := Screen;\n            end;\n          end\n          else if ImageToSave.Format <> DefaultFormat then\n          begin\n            if MustBeFreed then\n              ConvertImage(ImageToSave, DefaultFormat)\n            else\n            begin\n              CloneImage(Images[I], ImageToSave);\n              ConvertImage(ImageToSave, DefaultFormat);\n              MustBeFreed := True;\n            end;\n          end;\n        end;\n\n        // Add image as PNG frame\n        AddFrame(ImageToSave, False);\n      finally\n        if MustBeFreed then\n          FreeImage(ImageToSave);\n      end\n      else\n        Exit;\n    end;\n\n    // Finally save PNG file\n    SaveFile(Handle);\n    Result := True;\n  finally\n    NGFileSaver.Free;\n  end;\nend;\n\n{$IFNDEF DONT_LINK_MNG}\n\n{ TMNGFileFormat class implementation }\n\nprocedure TMNGFileFormat.Define;\nbegin\n  inherited;\n  FName := SMNGFormatName;\n  FFeatures := FFeatures + [ffMultiImage];\n  AddMasks(SMNGMasks);\n\n  FSignature := MNGSignature;\n\n  RegisterOption(ImagingMNGLossyCompression, @FLossyCompression);\n  RegisterOption(ImagingMNGLossyAlpha, @FLossyAlpha);\n  RegisterOption(ImagingMNGPreFilter, @FPreFilter);\n  RegisterOption(ImagingMNGCompressLevel, @FCompressLevel);\n  RegisterOption(ImagingMNGQuality, @FQuality);\n  RegisterOption(ImagingMNGProgressive, @FProgressive);\nend;\n\nfunction TMNGFileFormat.LoadData(Handle: TImagingHandle;\n  var Images: TDynImageDataArray; OnlyFirstLevel: Boolean): Boolean;\nvar\n  NGFileLoader: TNGFileLoader;\n  I, Len: LongInt;\nbegin\n  Result := False;\n  NGFileLoader := TNGFileLoader.Create(Self);\n  try\n    // Use NG file parser to load file\n    if NGFileLoader.LoadFile(Handle) then\n    begin\n      Len := Length(NGFileLoader.Frames);\n      if Len > 0 then\n      begin\n        SetLength(Images, Len);\n        for I := 0 to Len - 1 do\n        with NGFileLoader.Frames[I] do\n        begin\n          // Build actual image bits\n          if IsJpegFrame then\n            NGFileLoader.LoadImageFromJNGFrame(FrameWidth, FrameHeight, JHDR, IDATMemory, JDATMemory, JDAAMemory, Images[I])\n          else\n            NGFileLoader.LoadImageFromPNGFrame(FrameWidth, FrameHeight, IHDR, IDATMemory, Images[I]);\n          // Build palette, aply color key or background\n          NGFileLoader.ApplyFrameSettings(NGFileLoader.Frames[I], Images[I]);\n        end;\n      end\n      else\n      begin\n        // Some MNG files (with BASI-IEND streams) dont have actual pixel data\n        SetLength(Images, 1);\n        NewImage(NGFileLoader.MHDR.FrameWidth, NGFileLoader.MHDR.FrameWidth, ifDefault, Images[0]);\n      end;\n      Result := True;\n    end;\n  finally\n    NGFileLoader.LoadMetaData; // Store metadata\n    NGFileLoader.Free;\n  end;\nend;\n\nfunction TMNGFileFormat.SaveData(Handle: TImagingHandle;\n  const Images: TDynImageDataArray; Index: LongInt): Boolean;\nvar\n  NGFileSaver: TNGFileSaver;\n  I, LargestWidth, LargestHeight: LongInt;\n  ImageToSave: TImageData;\n  MustBeFreed: Boolean;\nbegin\n  Result := False;\n  LargestWidth := 0;\n  LargestHeight := 0;\n\n  NGFileSaver := TNGFileSaver.Create(Self);\n  NGFileSaver.FileType := ngMNG;\n  NGFileSaver.SetFileOptions;\n\n  with NGFileSaver do\n  try\n    // Store all frames to be saved frames file saver\n    for I := FFirstIdx to FLastIdx do\n    begin\n      if MakeCompatible(Images[I], ImageToSave, MustBeFreed) then\n      try\n        // Add image as PNG or JNG frame\n        AddFrame(ImageToSave, FLossyCompression);\n        // Remember largest frame width and height\n        LargestWidth := Iff(LargestWidth < ImageToSave.Width, ImageToSave.Width, LargestWidth);\n        LargestHeight := Iff(LargestHeight < ImageToSave.Height, ImageToSave.Height, LargestHeight);\n      finally\n        if MustBeFreed then\n          FreeImage(ImageToSave);\n      end\n      else\n        Exit;\n    end;\n\n    // Fill MNG header\n    MHDR.FrameWidth := LargestWidth;\n    MHDR.FrameHeight := LargestHeight;\n    MHDR.TicksPerSecond := 0;\n    MHDR.NominalLayerCount := 0;\n    MHDR.NominalFrameCount := Length(Frames);\n    MHDR.NominalPlayTime := 0;\n    MHDR.SimplicityProfile := 473; // 111011001 binary, defines MNG-VLC with transparency and JNG support\n\n    // Finally save MNG file\n    SaveFile(Handle);\n    Result := True;\n  finally\n    NGFileSaver.Free;\n  end;\nend;\n\n{$ENDIF}\n\n{$IFNDEF DONT_LINK_JNG}\n\n{ TJNGFileFormat class implementation }\n\nprocedure TJNGFileFormat.Define;\nbegin\n  inherited;\n  FName := SJNGFormatName;\n  AddMasks(SJNGMasks);\n\n  FSignature := JNGSignature;\n  FLossyCompression := True;\n\n  RegisterOption(ImagingJNGLossyAlpha, @FLossyAlpha);\n  RegisterOption(ImagingJNGAlphaPreFilter, @FPreFilter);\n  RegisterOption(ImagingJNGAlphaCompressLevel, @FCompressLevel);\n  RegisterOption(ImagingJNGQuality, @FQuality);\n  RegisterOption(ImagingJNGProgressive, @FProgressive);\n\nend;\n\nfunction TJNGFileFormat.LoadData(Handle: TImagingHandle;\n  var Images: TDynImageDataArray; OnlyFirstLevel: Boolean): Boolean;\nvar\n  NGFileLoader: TNGFileLoader;\nbegin\n  Result := False;\n  NGFileLoader := TNGFileLoader.Create(Self);\n  try\n    // Use NG file parser to load file\n    if NGFileLoader.LoadFile(Handle) and (Length(NGFileLoader.Frames) > 0) then\n    with NGFileLoader.Frames[0] do\n    begin\n      SetLength(Images, 1);\n      // Build actual image bits\n      if IsJpegFrame then\n        NGFileLoader.LoadImageFromJNGFrame(FrameWidth, FrameHeight, JHDR, IDATMemory, JDATMemory, JDAAMemory, Images[0]);\n      // Build palette, aply color key or background\n      NGFileLoader.ApplyFrameSettings(NGFileLoader.Frames[0], Images[0]);\n      Result := True;\n    end;\n  finally\n    NGFileLoader.LoadMetaData; // Store metadata\n    NGFileLoader.Free;\n  end;\nend;\n\nfunction TJNGFileFormat.SaveData(Handle: TImagingHandle;\n  const Images: TDynImageDataArray; Index: LongInt): Boolean;\nvar\n  NGFileSaver: TNGFileSaver;\n  ImageToSave: TImageData;\n  MustBeFreed: Boolean;\nbegin\n  // Make image JNG compatible, store it in saver, and save it to file\n  Result := MakeCompatible(Images[Index], ImageToSave, MustBeFreed);\n  if Result then\n  begin\n    NGFileSaver := TNGFileSaver.Create(Self);\n    with NGFileSaver do\n    try\n      FileType := ngJNG;\n      SetFileOptions;\n      AddFrame(ImageToSave, True);\n      SaveFile(Handle);\n    finally\n      // Free NG saver and compatible image\n      NGFileSaver.Free;\n      if MustBeFreed then\n        FreeImage(ImageToSave);\n    end;\n  end;\nend;\n\n{$ENDIF}\n\ninitialization\n  RegisterImageFileFormat(TPNGFileFormat);\n{$IFNDEF DONT_LINK_MNG}\n  RegisterImageFileFormat(TMNGFileFormat);\n{$ENDIF}\n{$IFNDEF DONT_LINK_JNG}\n  RegisterImageFileFormat(TJNGFileFormat);\n{$ENDIF}\nfinalization\n\n{\n  File Notes:\n\n  -- TODOS ----------------------------------------------------\n    - nothing now\n\n  -- 0.77 Changes/Bug Fixes -----------------------------------\n    - Reads and writes APNG animation loop count metadata.\n    - Writes frame delays of APNG from metadata.\n    - Fixed color keys in 8bit depth PNG/MNG loading.\n    - Fixed needless (and sometimes buggy) conversion to format with alpha\n      channel in FPC (GetMem(0) <> nil!).\n    - Added support for optional ZLib compression strategy.\n    - Added loading and saving of ifBinary (1bit black and white)\n      format images. During loading grayscale 1bpp and indexed 1bpp\n      (with only black and white colors in palette) are treated as ifBinary.\n      ifBinary are saved as 1bpp grayscale PNGs.\n\n  -- 0.26.5 Changes/Bug Fixes ---------------------------------\n    - Reads frame delays from APNG files into metadata.\n    - Added loading and saving of metadata from these chunks: pHYs.\n    - Simplified decoding of 1/2/4 bit images a bit (less code).\n\n  -- 0.26.3 Changes/Bug Fixes ---------------------------------\n    - Added APNG saving support.\n    - Added APNG support to NG loader and animating to PNG loader.\n\n  -- 0.26.1 Changes/Bug Fixes ---------------------------------\n    - Changed file format conditional compilation to reflect changes\n      in LINK symbols.\n\n  -- 0.24.3 Changes/Bug Fixes ---------------------------------\n    - Changes for better thread safety.\n\n  -- 0.23 Changes/Bug Fixes -----------------------------------\n    - Added loading of global palettes and transparencies in MNG files\n      (and by doing so fixed crash when loading images with global PLTE or tRNS).\n\n  -- 0.21 Changes/Bug Fixes -----------------------------------\n    - Small changes in converting to supported formats.\n    - MakeCompatible method moved to base class, put ConvertToSupported here.\n      GetSupportedFormats removed, it is now set in constructor.\n    - Made public properties for options registered to SetOption/GetOption\n      functions.\n    - Changed extensions to filename masks.\n    - Changed SaveData, LoadData, and MakeCompatible methods according\n      to changes in base class in Imaging unit.\n\n  -- 0.17 Changes/Bug Fixes -----------------------------------\n    - MNG and JNG support added, PNG support redesigned to support NG file handlers\n    - added classes for working with NG file formats\n    - stuff from old ImagingPng unit added and that unit was deleted\n    - unit created and initial stuff added\n    \n  -- 0.15 Changes/Bug Fixes -----------------------------------\n    - when saving indexed images save alpha to tRNS?\n    - added some defines and ifdefs to dzlib unit to allow choosing\n      impaszlib, fpc's paszlib, zlibex or other zlib implementation\n    - added colorkeying support\n    - fixed 16bit channel image handling - pixels were not swapped\n    - fixed arithmetic overflow (in paeth filter) in FPC\n    - data of unknown chunks are skipped and not needlesly loaded\n\n  -- 0.13 Changes/Bug Fixes -----------------------------------\n    - adaptive filtering added to PNG saving\n    - TPNGFileFormat class added\n}\n\nend.\n"
  },
  {
    "path": "lib/Imaging/ImagingOptions.inc",
    "content": "{\n  User Options\n  Following defines and options can be changed by user.\n}\n\n{ Source options }\n\n{$DEFINE USE_INLINE}          // Use function inlining for some functions\n                              // works in Free Pascal and Delphi 9+.\n{$DEFINE USE_ASM}             // Ff defined, assembler versions of some\n                              // functions will be used (only for x86).\n\n                              // Debug options: If none of these two are defined\n                              // your project settings are used.\n{ $DEFINE IMAGING_DEBUG}      // If defined, debug info, range/IO/overflow\n                              // checking, stack frames, assertions, and\n                              // other debugging options will be turned on.\n{ $DEFINE IMAGING_RELEASE}    // If defined, all debug info is off.\n\n\n\n(* File format support linking options.\n  Define formats which you don't want to be registred automatically.\n  Default: all formats are registered = no symbols defined.\n  Example: If you want to disable JPEG support just uncomment //{$DEFINE DONT_LINK_JPEG} line\n*)\n\n{$DEFINE DONT_LINK_JPEG}        // link support for Jpeg images\n//{$DEFINE DONT_LINK_PNG}         // link support for PNG images\n//{$DEFINE DONT_LINK_TARGA}       // link support for Targa images\n//{$DEFINE DONT_LINK_BITMAP}      // link support for Windows Bitmap images\n//{$DEFINE DONT_LINK_DDS}         // link support for DDS images\n{$DEFINE DONT_LINK_GIF}         // link support for GIF images\n{$DEFINE DONT_LINK_MNG}         // link support for MNG images\n{$DEFINE DONT_LINK_JNG}         // link support for JNG images\n{$DEFINE DONT_LINK_PNM}         // link support for PortableMap images (PBM, PGM, PPM, PAM, PFM)\n{$DEFINE DONT_LINK_RADHDR}      // link support for Radiance HDR/RGBE file format\n\n{$DEFINE DONT_LINK_EXTRAS}  // link support for file formats defined in\n                             // Extras package. Exactly which formats will be\n                             // registered depends on settings in\n                             // ImagingExtras.pas unit.\n\n{ Component set used in ImagignComponents.pas unit. You usually don't need\n  to be concerned with this - proper component library is selected automatically\n  according to your compiler. }\n\n{$DEFINE COMPONENT_SET_VCL}   // use Delphi VCL\n{ $DEFINE COMPONENT_SET_LCL}  // use Lazarus LCL (set automatically when compiling with FPC)\n\n{\n  Auto Options\n  Following options and defines are set automatically and some\n  are required for Imaging to compile successfully. Do not change\n  anything here if you don't know what you are doing.\n}\n\n{ Compiler options }\n\n{$ALIGN ON}               // Field alignment: 8 Bytes (in D6+)\n{$BOOLEVAL OFF}           // Boolean eval: off\n{$EXTENDEDSYNTAX ON}      // Extended syntax: on\n{$LONGSTRINGS ON}         // string = AnsiString: on\n{$MINENUMSIZE 4}          // Min enum size: 4 B\n{$TYPEDADDRESS OFF}       // Typed pointers: off\n{$WRITEABLECONST OFF}     // Writeable constants: off\n\n{$IFNDEF FPC}\n  {$DEFINE DCC}           // if not using FPC then DCC compiler is used (Delphi/BCB)\n                          // others are not supported\n{$ENDIF}\n\n{$IFDEF DCC}\n  {$DEFINE DELPHI}\n{$ENDIF}\n\n{$IF (Defined(DCC) and (CompilerVersion >= 18.5))}\n  {$IFDEF RELEASE}\n    {$UNDEF DEBUG} // If we are using Delphi 2007+ where you can set\n                   // DEBUG/RELEASE mode in project options and RELEASE\n                   // is currently set we undef DEBUG mode\n  {$ENDIF}\n{$IFEND}\n\n{$IF Defined(IMAGING_DEBUG)}\n  {$ASSERTIONS ON}\n  {$DEBUGINFO ON}\n  {$RANGECHECKS ON}\n  {$IOCHECKS ON}\n  {$OVERFLOWCHECKS ON}\n  {$IFDEF DCC}\n    {$OPTIMIZATION OFF}\n    {$STACKFRAMES ON}\n    {$LOCALSYMBOLS ON}\n    {$DEFINE MEMCHECK}\n  {$ENDIF}\n  {$IFDEF FPC}\n    {$S+}\n    {$CHECKPOINTER ON}\n  {$ENDIF}\n{$ELSEIF Defined(IMAGING_RELEASE)}\n  {$ASSERTIONS OFF}\n  {$DEBUGINFO OFF}\n  {$RANGECHECKS OFF}\n  {$IOCHECKS OFF}\n  {$OVERFLOWCHECKS OFF}\n  {$IFDEF DCC}\n    {$OPTIMIZATION ON}\n    {$STACKFRAMES OFF}\n    {$LOCALSYMBOLS OFF}\n  {$ENDIF}\n  {$IFDEF FPC}\n    {$S-}\n  {$ENDIF}\n{$IFEND}\n\n{$IF Defined (CPU86) and not Defined(CPUX86)}\n  {$DEFINE CPUX86} // Compatibility with Delphi\n{$IFEND}\n\n{$IF Defined (CPUX86_64) and not Defined(CPUX64)}\n  {$DEFINE CPUX64} // Compatibility with Delphi\n{$IFEND}\n\n{$IF Defined (DARWIN) and not Defined(MACOSX)}\n  {$DEFINE MACOS} // Compatibility with Delphi\n{$IFEND}\n\n{$IF Defined(DCC) and (CompilerVersion < 23)}\n  {$DEFINE CPUX86} // Compatibility with older Delphi\n{$IFEND}\n\n{ Compiler capabilities }\n\n// Define if compiler supports inlining of functions and procedures\n{$IF (Defined(DCC) and (CompilerVersion >= 17)) or Defined(FPC)}\n  {$DEFINE HAS_INLINE}\n{$IFEND}\n\n// Define if compiler supports advanced records with methods\n{$IF (Defined(DCC) and (CompilerVersion >= 18)) or\n  (Defined(FPC) and (FPC_FULLVERSION >= 20600))}\n  {$DEFINE HAS_ADVANCED_RECORDS}\n{$IFEND}\n\n// Define if compiler supports operator overloading\n// (unfortunately Delphi and FPC operator overloading is not compatible).\n// FPC supports Delphi compatible operator overloads since 2.6.0\n{$IF (Defined(DCC) and (CompilerVersion >= 18)) or\n  (Defined(FPC) and (FPC_FULLVERSION >= 20600))}\n  {$DEFINE HAS_OPERATOR_OVERLOADING}\n{$IFEND}\n\n// Anonymous methods\n{$IF Defined(DCC) and (CompilerVersion >= 20) }\n  {$DEFINE HAS_ANON_METHODS}\n{$IFEND}\n\n// Generic types (Delphi and FPC implementations incompatible).\n// Update: FPC supports Delphi compatible generics since 2.6.0\n{$IF (Defined(DCC) and (CompilerVersion >= 20)) or\n  (Defined(FPC) and (FPC_FULLVERSION >= 20600))}\n  {$DEFINE HAS_GENERICS}\n{$IFEND}\n\n{ Imaging options check}\n\n{$IFNDEF HAS_INLINE}\n  {$UNDEF USE_INLINE}\n{$ENDIF}\n\n{$IF not Defined(CPUX86)}\n  {$UNDEF USE_ASM}\n{$IFEND}\n\n{$IFDEF FPC}\n  {$DEFINE COMPONENT_SET_LCL}\n  {$UNDEF COMPONENT_SET_VCL}\n{$ENDIF}\n\n{$IFDEF DELPHI}\n  {$UNDEF COMPONENT_SET_LCL}\n  {$DEFINE COMPONENT_SET_VCL}\n{$ENDIF}\n\n{ Platform options }\n\n{$IF Defined(WIN32) or Defined(WIN64)}\n  {$DEFINE MSWINDOWS}\n{$IFEND}\n\n{$IFDEF LINUX}\n  {$DEFINE UNIX}\n{$ENDIF}\n\n{ More compiler options }\n\n{$IFDEF FPC}               // Free Pascal options - some options set above (like min enum size)\n                           // are reset to defaults by setting {$MODE} so they are\n                           // redeclared here \n  {$MODE DELPHI}           // compatible with delphi\n  {$GOTO ON}               // alow goto\n  {$PACKRECORDS 8}         // same as ALING 8 for Delphi\n  {$PACKENUM 4}            // Min enum size: 4 B\n  {$IFDEF CPU86}\n    {$ASMMODE INTEL}       // intel assembler mode\n  {$ENDIF}\n{$ENDIF}\n\n{$IFDEF HAS_INLINE}        \n  {$INLINE ON}             // turns inlining on for compilers that support it\n{$ENDIF}\n\n\n"
  },
  {
    "path": "lib/Imaging/ImagingTarga.pas",
    "content": "{\n  Vampyre Imaging Library\n  by Marek Mauder \n  http://imaginglib.sourceforge.net\n\n  The contents of this file are used with permission, subject to the Mozilla\n  Public License Version 1.1 (the \"License\"); you may not use this file except\n  in compliance with the License. You may obtain a copy of the License at\n  http://www.mozilla.org/MPL/MPL-1.1.html\n\n  Software distributed under the License is distributed on an \"AS IS\" basis,\n  WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for\n  the specific language governing rights and limitations under the License.\n\n  Alternatively, the contents of this file may be used under the terms of the\n  GNU Lesser General Public License (the  \"LGPL License\"), in which case the\n  provisions of the LGPL License are applicable instead of those above.\n  If you wish to allow use of your version of this file only under the terms\n  of the LGPL License and not to allow others to use your version of this file\n  under the MPL, indicate your decision by deleting  the provisions above and\n  replace  them with the notice and other provisions required by the LGPL\n  License.  If you do not delete the provisions above, a recipient may use\n  your version of this file under either the MPL or the LGPL License.\n\n  For more information about the LGPL: http://www.gnu.org/copyleft/lesser.html\n}\n\n{ This unit contains image format loader/saver for Targa images.}\nunit ImagingTarga;\n\n{$I ImagingOptions.inc}\n\ninterface\n\nuses\n  ImagingTypes, Imaging, ImagingFormats, ImagingUtility;\n\ntype\n  { Class for loading and saving Truevision Targa images.\n    It can load/save 8bit indexed or grayscale, 16 bit RGB or grayscale,\n    24 bit RGB and 32 bit ARGB images with or without RLE compression.}\n  TTargaFileFormat = class(TImageFileFormat)\n  protected\n    FUseRLE: LongBool;\n    procedure Define; override;\n    function LoadData(Handle: TImagingHandle; var Images: TDynImageDataArray;\n      OnlyFirstLevel: Boolean): Boolean; override;\n    function SaveData(Handle: TImagingHandle; const Images: TDynImageDataArray;\n      Index: LongInt): Boolean; override;\n    procedure ConvertToSupported(var Image: TImageData;\n      const Info: TImageFormatInfo); override;\n  public\n    function TestFormat(Handle: TImagingHandle): Boolean; override;\n  published\n    { Controls that RLE compression is used during saving. Accessible trough\n      ImagingTargaRLE option.}\n    property UseRLE: LongBool read FUseRLE write FUseRLE;\n  end;\n\nimplementation\n\nconst\n  STargaFormatName = 'Truevision Targa Image';\n  STargaMasks      = '*.tga';\n  TargaSupportedFormats: TImageFormats = [ifIndex8, ifGray8, ifA1R5G5B5,\n    ifR8G8B8, ifA8R8G8B8];\n  TargaDefaultRLE = False;  \n\nconst\n  STargaSignature = 'TRUEVISION-XFILE';\n\ntype\n  { Targa file header.}\n  TTargaHeader = packed record\n    IDLength: Byte;\n    ColorMapType: Byte;\n    ImageType: Byte;\n    ColorMapOff: Word;\n    ColorMapLength: Word;\n    ColorEntrySize: Byte;\n    XOrg: SmallInt;\n    YOrg: SmallInt;\n    Width: SmallInt;\n    Height: SmallInt;\n    PixelSize: Byte;\n    Desc: Byte;\n  end;\n\n  { Footer at the end of TGA file.}\n  TTargaFooter = packed record\n    ExtOff: LongWord;             // Extension Area Offset\n    DevDirOff: LongWord;          // Developer Directory Offset\n    Signature: TChar16;           // TRUEVISION-XFILE\n    Reserved: Byte;               // ASCII period '.'\n    NullChar: Byte;               // 0\n  end;\n\n\n{ TTargaFileFormat class implementation }\n\nprocedure TTargaFileFormat.Define;\nbegin\n  inherited;\n  FName := STargaFormatName;\n  FFeatures := [ffLoad, ffSave];\n  FSupportedFormats := TargaSupportedFormats;\n\n  FUseRLE := TargaDefaultRLE;\n\n  AddMasks(STargaMasks);\n  RegisterOption(ImagingTargaRLE, @FUseRLE);\nend;\n\nfunction TTargaFileFormat.LoadData(Handle: TImagingHandle;\n  var Images: TDynImageDataArray; OnlyFirstLevel: Boolean): Boolean;\nvar\n  Hdr: TTargaHeader;\n  Foo: TTargaFooter;\n  FooterFound, ExtFound: Boolean;\n  I, PSize, PalSize: LongWord;\n  Pal: Pointer;\n  FmtInfo: TImageFormatInfo;\n  WordValue: Word;\n\n  procedure LoadRLE;\n  var\n    I, CPixel, Cnt: LongInt;\n    Bpp, Rle: Byte;\n    Buffer, Dest, Src: PByte;\n    BufSize: LongInt;\n  begin\n    with GetIO, Images[0] do\n    begin\n      // Alocates buffer large enough to hold the worst case\n      // RLE compressed data and reads then from input\n      BufSize := Width * Height * FmtInfo.BytesPerPixel;\n      BufSize := BufSize + BufSize div 2 + 1;\n      GetMem(Buffer, BufSize);\n      Src := Buffer;\n      Dest := Bits;\n      BufSize := Read(Handle, Buffer, BufSize);\n\n      Cnt := Width * Height;\n      Bpp := FmtInfo.BytesPerPixel;\n      CPixel := 0;\n      while CPixel < Cnt do\n      begin\n        Rle := Src^;\n        Inc(Src);\n        if Rle < 128 then\n        begin\n          // Process uncompressed pixel\n          Rle := Rle + 1;\n          CPixel := CPixel + Rle;\n          for I := 0 to Rle - 1 do\n          begin\n            // Copy pixel from src to dest\n            case Bpp of\n              1: Dest^ := Src^;\n              2: PWord(Dest)^ := PWord(Src)^;\n              3: PColor24Rec(Dest)^ := PColor24Rec(Src)^;\n              4: PLongWord(Dest)^ := PLongWord(Src)^;\n            end;\n            Inc(Src, Bpp);\n            Inc(Dest, Bpp);\n          end;\n        end\n        else\n        begin\n          // Process compressed pixels\n          Rle := Rle - 127;\n          CPixel := CPixel + Rle;\n          // Copy one pixel from src to dest (many times there)\n          for I := 0 to Rle - 1 do\n          begin\n            case Bpp of\n              1: Dest^ := Src^;\n              2: PWord(Dest)^ := PWord(Src)^;\n              3: PColor24Rec(Dest)^ := PColor24Rec(Src)^;\n              4: PLongWord(Dest)^ := PLongWord(Src)^;\n            end;\n            Inc(Dest, Bpp);\n          end;\n          Inc(Src, Bpp);\n        end;\n      end;\n      // set position in source to real end of compressed data\n      Seek(Handle, -(BufSize - LongInt(LongWord(Src) - LongWord(Buffer))),\n        smFromCurrent);\n      FreeMem(Buffer);\n    end;\n  end;\n\nbegin\n  SetLength(Images, 1);\n  with GetIO, Images[0] do\n  begin\n    // Read targa header\n    Read(Handle, @Hdr, SizeOf(Hdr));\n    // Skip image ID info\n    Seek(Handle, Hdr.IDLength, smFromCurrent);\n    // Determine image format\n    Format := ifUnknown;\n    case Hdr.ImageType of\n      1, 9: Format := ifIndex8;\n      2, 10: case Hdr.PixelSize of\n          15: Format := ifX1R5G5B5;\n          16: Format := ifA1R5G5B5;\n          24: Format := ifR8G8B8;\n          32: Format := ifA8R8G8B8;\n        end;\n      3, 11: Format := ifGray8;\n    end;\n    // Format was not assigned by previous testing (it should be in\n    // well formed targas), so formats which reflects bit dept are selected\n    if Format = ifUnknown then\n      case Hdr.PixelSize of\n        8: Format := ifGray8;\n        15: Format := ifX1R5G5B5;\n        16: Format := ifA1R5G5B5;\n        24: Format := ifR8G8B8;\n        32: Format := ifA8R8G8B8;\n      end;\n    NewImage(Hdr.Width, Hdr.Height, Format, Images[0]);\n    FmtInfo := GetFormatInfo(Format);\n\n    if (Hdr.ColorMapType = 1) and (Hdr.ImageType in [1, 9]) then\n    begin\n      // Read palette\n      PSize := Hdr.ColorMapLength * (Hdr.ColorEntrySize shr 3);\n      GetMem(Pal, PSize);\n      try\n        Read(Handle, Pal, PSize);\n        // Process palette\n        PalSize := Iff(Hdr.ColorMapLength > FmtInfo.PaletteEntries,\n          FmtInfo.PaletteEntries, Hdr.ColorMapLength);\n        for I := 0 to PalSize - 1 do\n          case Hdr.ColorEntrySize of\n            24:\n              with Palette[I] do\n              begin\n                A := $FF;\n                R := PPalette24(Pal)[I].R;\n                G := PPalette24(Pal)[I].G;\n                B := PPalette24(Pal)[I].B;\n              end;\n            // I've never seen tga with these palettes so they are untested\n            16:\n              with Palette[I] do\n              begin\n                A := (PWordArray(Pal)[I] and $8000) shr 12;\n                R := (PWordArray(Pal)[I] and $FC00) shr 7;\n                G := (PWordArray(Pal)[I] and $03E0) shr 2;\n                B := (PWordArray(Pal)[I] and $001F) shl 3;\n              end;\n            32:\n              with Palette[I] do\n              begin\n                A := PPalette32(Pal)[I].A;\n                R := PPalette32(Pal)[I].R;\n                G := PPalette32(Pal)[I].G;\n                B := PPalette32(Pal)[I].B;\n              end;\n          end;\n      finally\n        FreeMemNil(Pal);\n      end;\n    end;\n\n    case Hdr.ImageType of\n      0, 1, 2, 3:\n        // Load uncompressed mode images\n        Read(Handle, Bits, Size);\n      9, 10, 11:\n        // Load RLE compressed mode images\n        LoadRLE;\n    end;\n\n    // Check if there is alpha channel present in A1R5GB5 images, if it is not\n    // change format to X1R5G5B5\n    if Format = ifA1R5G5B5 then\n    begin\n      if not Has16BitImageAlpha(Width * Height, Bits) then\n        Format := ifX1R5G5B5;\n    end;\n\n    // We must find true end of file and set input' position to it\n    // paint programs appends extra info at the end of Targas\n    // some of them multiple times (PSP Pro 8)\n    repeat\n      ExtFound := False;\n      FooterFound := False;\n\n      if Read(Handle, @WordValue, 2) = 2 then\n      begin\n        // 495 = size of Extension Area\n        if WordValue = 495 then\n        begin\n          Seek(Handle, 493, smFromCurrent);\n          ExtFound := True;\n        end\n        else\n          Seek(Handle, -2, smFromCurrent);\n      end;\n\n      if Read(Handle, @Foo, SizeOf(Foo)) = SizeOf(Foo) then\n      begin\n        if Foo.Signature = STargaSignature then\n          FooterFound := True\n        else\n          Seek(Handle, -SizeOf(Foo), smFromCurrent);\n      end;\n    until (not ExtFound) and (not FooterFound);\n\n    // Some editors save targas flipped\n    if Hdr.Desc < 31 then\n      FlipImage(Images[0]);\n\n    Result := True;\n  end;\nend;\n\nfunction TTargaFileFormat.SaveData(Handle: TImagingHandle;\n  const Images: TDynImageDataArray; Index: LongInt): Boolean;\nvar\n  I: LongInt;\n  Hdr: TTargaHeader;\n  FmtInfo: TImageFormatInfo;\n  Pal: PPalette24;\n  ImageToSave: TImageData;\n  MustBeFreed: Boolean;\n\n  procedure SaveRLE;\n  var\n    Dest: PByte;\n    WidthBytes, Written, I, Total, DestSize: LongInt;\n\n    function CountDiff(Data: PByte; Bpp, PixelCount: Longint): LongInt;\n    var\n      Pixel: LongWord;\n      NextPixel: LongWord;\n      N: LongInt;\n    begin\n      N := 0;\n      Pixel := 0;\n      NextPixel := 0;\n      if PixelCount = 1 then\n      begin\n        Result := PixelCount;\n        Exit;\n      end;\n      case Bpp of\n        1: Pixel := Data^;\n        2: Pixel := PWord(Data)^;\n        3: PColor24Rec(@Pixel)^ := PColor24Rec(Data)^;\n        4: Pixel := PLongWord(Data)^;\n      end;\n      while PixelCount > 1 do\n      begin\n        Inc(Data, Bpp);\n        case Bpp of\n          1: NextPixel := Data^;\n          2: NextPixel := PWord(Data)^;\n          3: PColor24Rec(@NextPixel)^ := PColor24Rec(Data)^;\n          4: NextPixel := PLongWord(Data)^;\n        end;\n        if NextPixel = Pixel then\n          Break;\n        Pixel := NextPixel;\n        N := N + 1;\n        PixelCount := PixelCount - 1;\n      end;\n      if NextPixel = Pixel then\n        Result := N\n      else\n        Result := N + 1;\n    end;\n\n    function CountSame(Data: PByte; Bpp, PixelCount: LongInt): LongInt;\n    var\n      Pixel: LongWord;\n      NextPixel: LongWord;\n      N: LongInt;\n    begin\n      N := 1;\n      Pixel := 0;\n      NextPixel := 0;\n      case Bpp of\n        1: Pixel := Data^;\n        2: Pixel := PWord(Data)^;\n        3: PColor24Rec(@Pixel)^ := PColor24Rec(Data)^;\n        4: Pixel := PLongWord(Data)^;\n      end;\n      PixelCount := PixelCount - 1;\n      while PixelCount > 0 do\n      begin\n        Inc(Data, Bpp);\n        case Bpp of\n          1: NextPixel := Data^;\n          2: NextPixel := PWord(Data)^;\n          3: PColor24Rec(@NextPixel)^ := PColor24Rec(Data)^;\n          4: NextPixel := PLongWord(Data)^;\n        end;\n        if NextPixel <> Pixel then\n          Break;\n        N := N + 1;\n        PixelCount := PixelCount - 1;\n      end;\n      Result := N;\n    end;\n\n    procedure RleCompressLine(Data: PByte; PixelCount, Bpp: LongInt; Dest:\n      PByte; var Written: LongInt);\n    const\n      MaxRun = 128;\n    var\n      DiffCount: LongInt;\n      SameCount: LongInt;\n      RleBufSize: LongInt;\n    begin\n      RleBufSize := 0;\n      while PixelCount > 0 do\n      begin\n        DiffCount := CountDiff(Data, Bpp, PixelCount);\n        SameCount := CountSame(Data, Bpp, PixelCount);\n        if (DiffCount > MaxRun) then\n          DiffCount := MaxRun;\n        if (SameCount > MaxRun) then\n          SameCount := MaxRun;\n        if (DiffCount > 0) then\n        begin\n          Dest^ := Byte(DiffCount - 1);\n          Inc(Dest);\n          PixelCount := PixelCount - DiffCount;\n          RleBufSize := RleBufSize + (DiffCount * Bpp) + 1;\n          Move(Data^, Dest^, DiffCount * Bpp);\n          Inc(Data, DiffCount * Bpp);\n          Inc(Dest, DiffCount * Bpp);\n        end;\n        if SameCount > 1 then\n        begin\n          Dest^ := Byte((SameCount - 1) or $80);\n          Inc(Dest);\n          PixelCount := PixelCount - SameCount;\n          RleBufSize := RleBufSize + Bpp + 1;\n          Inc(Data, (SameCount - 1) * Bpp);\n          case Bpp of\n            1: Dest^ := Data^;\n            2: PWord(Dest)^ := PWord(Data)^;\n            3: PColor24Rec(Dest)^ := PColor24Rec(Data)^;\n            4: PLongWord(Dest)^ := PLongWord(Data)^;\n          end;\n          Inc(Data, Bpp);\n          Inc(Dest, Bpp);\n        end;\n      end;\n      Written := RleBufSize;\n    end;\n\n  begin\n    with ImageToSave do\n    begin\n      // Allocate enough space to hold the worst case compression\n      // result and then compress source's scanlines\n      WidthBytes := Width * FmtInfo.BytesPerPixel;\n      DestSize := WidthBytes * Height;\n      DestSize := DestSize + DestSize div 2 + 1;\n      GetMem(Dest, DestSize);\n      Total := 0;\n      try\n        for I := 0 to Height - 1 do\n        begin\n          RleCompressLine(@PByteArray(Bits)[I * WidthBytes], Width,\n            FmtInfo.BytesPerPixel, @PByteArray(Dest)[Total], Written);\n          Total := Total + Written;\n        end;\n        GetIO.Write(Handle, Dest, Total);\n      finally\n        FreeMem(Dest);\n      end;\n    end;\n  end;\n\nbegin\n  Result := False;\n  if MakeCompatible(Images[Index], ImageToSave, MustBeFreed) then\n  with GetIO, ImageToSave do\n  try\n    FmtInfo := GetFormatInfo(Format);\n    // Fill targa header\n    FillChar(Hdr, SizeOf(Hdr), 0);\n    Hdr.IDLength := 0;\n    Hdr.ColorMapType := Iff(FmtInfo.PaletteEntries > 0, 1, 0);\n    Hdr.Width := Width;\n    Hdr.Height := Height;\n    Hdr.PixelSize := FmtInfo.BytesPerPixel * 8;\n    Hdr.ColorMapLength := FmtInfo.PaletteEntries;\n    Hdr.ColorEntrySize := Iff(FmtInfo.PaletteEntries > 0, 24, 0);\n    Hdr.ColorMapOff := 0;\n    // This indicates that targa is stored in top-left format\n    // as our images -> no flipping is needed.\n    Hdr.Desc := 32;\n    // Set alpha channel size in descriptor (mostly ignored by other software though)\n    if Format = ifA8R8G8B8 then\n      Hdr.Desc := Hdr.Desc or 8\n    else if Format = ifA1R5G5B5 then\n      Hdr.Desc := Hdr.Desc or 1;\n\n    // Choose image type\n    if FmtInfo.IsIndexed then\n      Hdr.ImageType := Iff(FUseRLE, 9, 1)\n    else\n      if FmtInfo.HasGrayChannel then\n        Hdr.ImageType := Iff(FUseRLE, 11, 3)\n      else\n        Hdr.ImageType := Iff(FUseRLE, 10, 2);\n\n    Write(Handle, @Hdr, SizeOf(Hdr));\n\n    // Write palette\n    if FmtInfo.PaletteEntries > 0 then\n    begin\n      GetMem(Pal, FmtInfo.PaletteEntries * SizeOf(TColor24Rec));\n      try\n        for I := 0 to FmtInfo.PaletteEntries - 1 do\n          with Pal[I] do\n          begin\n            R := Palette[I].R;\n            G := Palette[I].G;\n            B := Palette[I].B;\n          end;\n        Write(Handle, Pal, FmtInfo.PaletteEntries * SizeOf(TColor24Rec));\n      finally\n        FreeMemNil(Pal);\n      end;\n    end;\n\n    if FUseRLE then\n      // Save rle compressed mode images\n      SaveRLE\n    else\n      // Save uncompressed mode images\n      Write(Handle, Bits, Size);\n\n    Result := True;\n  finally\n    if MustBeFreed then\n      FreeImage(ImageToSave);\n  end;\nend;\n\nprocedure TTargaFileFormat.ConvertToSupported(var Image: TImageData;\n  const Info: TImageFormatInfo);\nvar\n  ConvFormat: TImageFormat;\nbegin\n  if Info.HasGrayChannel then\n    // Convert all grayscale images to Gray8 (preserve alpha of AxGrayx formats)\n    ConvFormat := IffFormat(not Info.HasAlphaChannel, ifGray8, ifA8R8G8B8)\n  else if Info.IsIndexed then\n    // Convert all indexed images to Index8\n    ConvFormat := ifIndex8\n  else if Info.HasAlphaChannel then\n    // Convert images with alpha channel to A8R8G8B8\n    ConvFormat := ifA8R8G8B8\n  else if Info.UsePixelFormat then\n    // Convert 16bit images (without alpha channel) to A1R5G5B5\n    ConvFormat := ifA1R5G5B5\n  else\n    // Convert all other formats to R8G8B8\n    ConvFormat := ifR8G8B8;\n\n  ConvertImage(Image, ConvFormat);\nend;\n\nfunction TTargaFileFormat.TestFormat(Handle: TImagingHandle): Boolean;\nvar\n  Hdr: TTargaHeader;\n  ReadCount: LongInt;\nbegin\n  Result := False;\n  if Handle <> nil then\n  begin\n    ReadCount := GetIO.Read(Handle, @Hdr, SizeOf(Hdr));\n    GetIO.Seek(Handle, -ReadCount, smFromCurrent);\n    Result := (ReadCount >= SizeOf(Hdr)) and\n      (Hdr.ImageType in [0, 1, 2, 3, 9, 10, 11]) and\n      (Hdr.PixelSize in [1, 8, 15, 16, 24, 32]) and\n      (Hdr.ColorEntrySize in [0, 16, 24, 32]);\n  end;\nend;\n\ninitialization\n  RegisterImageFileFormat(TTargaFileFormat);\n\n{\n  File Notes:\n\n -- TODOS ----------------------------------------------------\n    - nothing now\n\n  -- 0.21 Changes/Bug Fixes -----------------------------------\n    - MakeCompatible method moved to base class, put ConvertToSupported here.\n      GetSupportedFormats removed, it is now set in constructor.\n    - Made public properties for options registered to SetOption/GetOption\n      functions.\n    - Changed extensions to filename masks.\n    - Changed SaveData, LoadData, and MakeCompatible methods according\n      to changes in base class in Imaging unit.\n\n  -- 0.17 Changes/Bug Fixes -----------------------------------\n    - 16 bit images are usually without alpha but some has alpha\n      channel and there is no indication of it - so I have added\n      a check: if all pixels of image are with alpha = 0 image is treated\n      as X1R5G5B5 otherwise as A1R5G5B5\n    - fixed problems with some nonstandard 15 bit images\n}\n\nend.\n\n"
  },
  {
    "path": "lib/Imaging/ImagingTypes.pas",
    "content": "{\n  Vampyre Imaging Library\n  by Marek Mauder \n  http://imaginglib.sourceforge.net\n\n  The contents of this file are used with permission, subject to the Mozilla\n  Public License Version 1.1 (the \"License\"); you may not use this file except\n  in compliance with the License. You may obtain a copy of the License at\n  http://www.mozilla.org/MPL/MPL-1.1.html\n\n  Software distributed under the License is distributed on an \"AS IS\" basis,\n  WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for\n  the specific language governing rights and limitations under the License.\n\n  Alternatively, the contents of this file may be used under the terms of the\n  GNU Lesser General Public License (the  \"LGPL License\"), in which case the\n  provisions of the LGPL License are applicable instead of those above.\n  If you wish to allow use of your version of this file only under the terms\n  of the LGPL License and not to allow others to use your version of this file\n  under the MPL, indicate your decision by deleting  the provisions above and\n  replace  them with the notice and other provisions required by the LGPL\n  License.  If you do not delete the provisions above, a recipient may use\n  your version of this file under either the MPL or the LGPL License.\n\n  For more information about the LGPL: http://www.gnu.org/copyleft/lesser.html\n}\n\n{ This unit contains basic types and constants used by Imaging library.}\nunit ImagingTypes;\n\n{$I ImagingOptions.inc}\n\ninterface\n\nconst\n  { Current Major version of Imaging.}\n  ImagingVersionMajor = 0;\n  { Current Minor version of Imaging.}\n  ImagingVersionMinor = 77;\n  { Current patch of Imaging.}\n  ImagingVersionPatch = 1;\n\n  { Imaging Option Ids whose values can be set/get by SetOption/\n    GetOption functions.}\n\n  { Defines Jpeg compression quality, ranges from 1 (ugly/small) to 100 (nice/large).\n    Default value is 90.}\n  ImagingJpegQuality           = 10;\n  { Specifies whether Jpeg images are saved in progressive format,\n    can be 0 or 1. Default value is 0.}\n  ImagingJpegProgressive       = 11;\n\n  { Specifies whether Windows Bitmaps are saved using RLE compression\n    (only for 1/4/8 bit images), can be 0 or 1. Default value is 1.}\n  ImagingBitmapRLE             = 12;\n\n  { Specifies whether Targa images are saved using RLE compression,\n    can be 0 or 1. Default value is 0.}\n  ImagingTargaRLE              = 13;\n\n  { Value of this option is non-zero if last loaded DDS file was cube map.}\n  ImagingDDSLoadedCubeMap      = 14;\n  { Value of this option is non-zero if last loaded DDS file was volume texture.}\n  ImagingDDSLoadedVolume       = 15;\n  { Value of this option is number of mipmap levels of last loaded DDS image.}\n  ImagingDDSLoadedMipMapCount  = 16;\n  { Value of this option is depth (slices of volume texture or faces of\n    cube map) of last loaded DDS image.}\n  ImagingDDSLoadedDepth        = 17;\n  { If it is non-zero next saved DDS file should be stored as cube map.}\n  ImagingDDSSaveCubeMap        = 18;\n  { If it is non-zero next saved DDS file should be stored as volume texture.}\n  ImagingDDSSaveVolume         = 19;\n  { Sets the number of mipmaps which should be stored in the next saved DDS file.\n    Only applies to cube maps and volumes, ordinary 2D textures save all\n    levels present in input.}\n  ImagingDDSSaveMipMapCount    = 20;\n  { Sets the depth (slices of volume texture or faces of cube map)\n    of the next saved DDS file.}\n  ImagingDDSSaveDepth          = 21;\n\n  { Sets precompression filter used when saving PNG images. Allowed values\n    are: 0 (none), 1 (sub), 2 (up), 3 (average), 4 (paeth),\n    5 (use 0 for indexed/gray images and 4 for RGB/ARGB images),\n    6 (adaptive filtering - use best filter for each scanline - very slow).\n    Note that filters 3 and 4 are much slower than filters 1 and 2.\n    Default value is 5.}\n  ImagingPNGPreFilter          = 25;\n  { Sets ZLib compression level used when saving PNG images.\n    Allowed values are in range 0 (no compresstion) to 9 (best compression).\n    Default value is 5.}\n  ImagingPNGCompressLevel      = 26;\n  { Boolean option that specifies whether PNG images with more frames (APNG format)\n    are animated by Imaging (according to frame disposal/blend methods) or just\n    raw frames are loaded and sent to user (if you want to animate APNG yourself).\n    Default value is 1.}\n  ImagingPNGLoadAnimated       = 27;\n  { Sets ZLib compression strategy used when saving PNG files (see deflateInit2()\n    in ZLib for details). Allowed values are: 0 (default), 1 (filtered),\n    2 (huffman only). Default value is 0.}\n  ImagingPNGZLibStrategy       = 28;\n\n  { Specifies whether MNG animation frames are saved with lossy or lossless\n    compression. Lossless frames are saved as PNG images and lossy frames are\n    saved as JNG images. Allowed values are 0 (False) and 1 (True).\n    Default value is 0.}\n  ImagingMNGLossyCompression   = 32;\n  { Defines whether alpha channel of lossy compressed MNG frames\n    (when ImagingMNGLossyCompression is 1) is lossy compressed too.\n    Allowed values are 0 (False) and 1 (True). Default value is 0.}\n  ImagingMNGLossyAlpha         = 33;\n  { Sets precompression filter used when saving MNG frames as PNG images.\n    For details look at ImagingPNGPreFilter.}\n  ImagingMNGPreFilter          = 34;\n  { Sets ZLib compression level used when saving MNG frames as PNG images.\n    For details look at ImagingPNGCompressLevel.}\n  ImagingMNGCompressLevel      = 35;\n  { Specifies compression quality used when saving MNG frames as JNG images.\n    For details look at ImagingJpegQuality.}\n  ImagingMNGQuality            = 36;\n  { Specifies whether images are saved in progressive format when saving MNG\n    frames as JNG images. For details look at ImagingJpegProgressive.}\n  ImagingMNGProgressive        = 37;\n\n  { Specifies whether alpha channels of JNG images are lossy compressed.\n    Allowed values are 0 (False) and 1 (True). Default value is 0.}\n  ImagingJNGLossyAlpha         = 40;\n  { Sets precompression filter used when saving lossless alpha channels.\n    For details look at ImagingPNGPreFilter.}\n  ImagingJNGAlphaPreFilter     = 41;\n  { Sets ZLib compression level used when saving lossless alpha channels.\n    For details look at ImagingPNGCompressLevel.}\n  ImagingJNGAlphaCompressLevel = 42;\n  { Defines compression quality used when saving JNG images (and lossy alpha channels).\n    For details look at ImagingJpegQuality.}\n  ImagingJNGQuality            = 43;\n  { Specifies whether JNG images are saved in progressive format.\n    For details look at ImagingJpegProgressive.}\n  ImagingJNGProgressive        = 44;\n\n  { Specifies whether PGM files are stored in text or in binary format.\n    Allowed values are 0 (store as text - very! large files) and 1 (save binary).\n    Default value is 1.}\n  ImagingPGMSaveBinary         = 50;\n\n  { Specifies whether PPM files are stored in text or in binary format.\n    Allowed values are 0 (store as text - very! large files) and 1 (save binary).\n    Default value is 1.}\n  ImagingPPMSaveBinary         = 51;\n\n  { Boolean option that specifies whether GIF images with more frames\n    are animated by Imaging (according to frame disposal methods) or just\n    raw frames are loaded and sent to user (if you want to animate GIF yourself).\n    Default value is 1.\n    Raw frames are 256 color indexed images (ifIndex8), whereas\n    animated frames are always in 32bit ifA8R8G8B8 format (simplifies animating).}\n  ImagingGIFLoadAnimated       = 56;\n\n  { This option is used when reducing number of colors used in\n    image (mainly when converting from ARGB image to indexed\n    format). Mask is 'anded' (bitwise AND) with every pixel's\n    channel value when creating color histogram. If $FF is used\n    all 8bits of color channels are used which can result in very\n    slow proccessing of large images with many colors so you can\n    use lower masks to speed it up (FC, F8 and F0 are good\n    choices). Allowed values are in range <0, $FF> and default is\n    $FE.                                                          }\n  ImagingColorReductionMask   = 128;\n  { This option can be used to override image data format during image\n    loading. If set to format different from ifUnknown all loaded images\n    are automaticaly converted to this format. Useful when you have\n    many files in various formats but you want them all in one format for\n    further proccessing. Allowed values are in\n    range <Ord(Low(TImageFormat)), Ord(High(TImageFormat))> and\n    default value is ifUnknown.}\n  ImagingLoadOverrideFormat   = 129;\n  { This option can be used to override image data format during image\n    saving. If set to format different from ifUnknown all images\n    to be saved are automaticaly internaly converted to this format.\n    Note that image file formats support only a subset of Imaging data formats\n    so final saved file may in different format than this override.\n    Allowed values are in range <Ord(Low(TImageFormat)), Ord(High(TImageFormat))>\n    and default value is ifUnknown.}\n  ImagingSaveOverrideFormat   = 130;\n  { Specifies resampling filter used when generating mipmaps. It is used\n    in GenerateMipMaps low level function and Direct3D and OpenGL extensions.\n    Allowed values are in range\n    <Ord(Low(ImagingFormats.TSamplingFilter)), Ord(High(ImagingFormats.TSamplingFilter))>\n    and default value is 1 (linear filter).}\n  ImagingMipMapFilter         = 131;\n  { Specifies treshold value used when automatically converting images to\n    ifBinary format. For adaptive tresholding see ImagingBinary.pas unit.\n    Default value is 128 and allowed range is 0..255.}\n  ImagingBinaryTreshold       = 132;\n\n  { Returned by GetOption if given Option Id is invalid.}\n  InvalidOption = -$7FFFFFFF;\n\n  { Indices that can be used to access channel values in array parts\n    of structures like TColor32Rec. Note that this order can be\n    used only for ARGB images. For ABGR image you must swap Red and Blue.}\n  ChannelBlue  = 0;\n  ChannelGreen = 1;\n  ChannelRed   = 2;\n  ChannelAlpha = 3;\n\ntype\n  { Enum defining image data format. In formats with more channels,\n    first channel after \"if\" is stored in the most significant bits and channel\n    before end is stored in the least significant.}\n  TImageFormat = (\n    ifUnknown        = 0,\n    ifDefault        = 1,\n    { Indexed formats using palette }\n    ifIndex8         = 10,\n    { Grayscale/Luminance formats }\n    ifGray8          = 40,\n    ifA8Gray8        = 41,\n    ifGray16         = 42,\n    ifGray32         = 43,\n    ifGray64         = 44,\n    ifA16Gray16      = 45,\n    { ARGB formats }\n    ifX5R1G1B1       = 80,\n    ifR3G3B2         = 81,\n    ifR5G6B5         = 82,\n    ifA1R5G5B5       = 83,\n    ifA4R4G4B4       = 84,\n    ifX1R5G5B5       = 85,\n    ifX4R4G4B4       = 86,\n    ifR8G8B8         = 87,\n    ifA8R8G8B8       = 88,\n    ifX8R8G8B8       = 89,\n    ifR16G16B16      = 90,\n    ifA16R16G16B16   = 91,\n    ifB16G16R16      = 92,\n    ifA16B16G16R16   = 93,\n    { Floating point formats }\n    ifR32F           = 160,\n    ifA32R32G32B32F  = 161,\n    ifA32B32G32R32F  = 162,\n    ifR16F           = 163,\n    ifA16R16G16B16F  = 164,\n    ifA16B16G16R16F  = 165,\n    ifR32G32B32F     = 166,\n    ifB32G32R32F     = 167,\n    { Special formats }\n    ifDXT1           = 200,\n    ifDXT3           = 201,\n    ifDXT5           = 202,\n    ifBTC            = 203,\n    ifATI1N          = 204,\n    ifATI2N          = 205,\n    ifBinary         = 206,\n    { Passtrough formats }\n    ifETC1           = 220,\n    ifETC2RGB        = 221,\n    ifETC2RGBA       = 222,\n    ifETC2PA         = 223,\n    ifDXBC6          = 224,\n    ifDXBC7          = 225\n  );\n\n  { Color value for 32 bit images.}\n  TColor32 = LongWord;\n  PColor32 = ^TColor32;\n\n  { Color value for 64 bit images.}\n  TColor64 = type Int64;\n  PColor64 = ^TColor64;\n\n  { Color record for 24 bit images, which allows access to individual color\n    channels.}\n  TColor24Rec = packed record\n    case LongInt of\n      0: (B, G, R: Byte);\n      1: (Channels: array[0..2] of Byte);\n  end;\n  PColor24Rec = ^TColor24Rec;\n  TColor24RecArray = array[0..MaxInt div SizeOf(TColor24Rec) - 1] of TColor24Rec;\n  PColor24RecArray = ^TColor24RecArray;\n\n  { Color record for 32 bit images, which allows access to individual color\n    channels.}\n  TColor32Rec = packed record\n    case LongInt of\n      0: (Color: TColor32);\n      1: (B, G, R, A: Byte);\n      2: (Channels: array[0..3] of Byte);\n      3: (Color24Rec: TColor24Rec);\n  end;\n  PColor32Rec = ^TColor32Rec;\n  TColor32RecArray = array[0..MaxInt div SizeOf(TColor32Rec) - 1] of TColor32Rec;\n  PColor32RecArray = ^TColor32RecArray;\n\n  { Color record for 48 bit images, which allows access to individual color\n    channels.}\n  TColor48Rec = packed record\n    case LongInt of\n      0: (B, G, R: Word);\n      1: (Channels: array[0..2] of Word);\n  end;\n  PColor48Rec = ^TColor48Rec;\n  TColor48RecArray = array[0..MaxInt div SizeOf(TColor48Rec) - 1] of TColor48Rec;\n  PColor48RecArray = ^TColor48RecArray;\n\n  { Color record for 64 bit images, which allows access to individual color\n    channels.}\n  TColor64Rec = packed record\n    case LongInt of\n      0: (Color: TColor64);\n      1: (B, G, R, A: Word);\n      2: (Channels: array[0..3] of Word);\n      3: (Color48Rec: TColor48Rec);\n  end;\n  PColor64Rec = ^TColor64Rec;\n  TColor64RecArray = array[0..MaxInt div SizeOf(TColor64Rec) - 1] of TColor64Rec;\n  PColor64RecArray = ^TColor64RecArray;\n\n  { Color record for 96 bit floating point images, which allows access to\n    individual color channels.}\n  TColor96FPRec = packed record\n    case Integer of\n      0: (B, G, R: Single);\n      1: (Channels: array[0..2] of Single);\n  end;\n  PColor96FPRec = ^TColor96FPRec;\n  TColor96FPRecArray = array[0..MaxInt div SizeOf(TColor96FPRec) - 1] of TColor96FPRec;\n  PColor96FPRecArray = ^TColor96FPRecArray;\n\n  { Color record for 128 bit floating point images, which allows access to\n    individual color channels.}\n  TColorFPRec = packed record\n    case LongInt of\n      0: (B, G, R, A: Single);\n      1: (Channels: array[0..3] of Single);\n      2: (Color96Rec: TColor96FPRec);\n  end;\n  PColorFPRec = ^TColorFPRec;\n  TColorFPRecArray = array[0..MaxInt div SizeOf(TColorFPRec) - 1] of TColorFPRec;\n  PColorFPRecArray = ^TColorFPRecArray;\n\n  { 16 bit floating-point value. It has 1 sign bit, 5 exponent bits,\n    and 10 mantissa bits.}\n  THalfFloat = type Word;\n  PHalfFloat = ^THalfFloat;\n\n  { Color record for 64 bit floating point images, which allows access to\n    individual color channels.}\n  TColorHFRec = packed record\n    case LongInt of\n      0: (B, G, R, A: THalfFloat);\n      1: (Channels: array[0..3] of THalfFloat);\n  end;\n  PColorHFRec = ^TColorHFRec;\n  TColorHFRecArray = array[0..MaxInt div SizeOf(TColorHFRec) - 1] of TColorHFRec;\n  PColorHFRecArray = ^TColorHFRecArray;\n\n  { Palette for indexed mode images with 32 bit colors.}\n  TPalette32 = TColor32RecArray;\n  TPalette32Size256 = array[0..255] of TColor32Rec;\n  PPalette32 = ^TPalette32;\n\n  { Palette for indexd mode images with 24 bit colors.}\n  TPalette24 = TColor24RecArray;\n  TPalette24Size256 = array[0..255] of TColor24Rec;\n  PPalette24 = ^TPalette24;\n\n  { Record that stores single image data and information describing it.}\n  TImageData = packed record\n    Width: LongInt;       // Width of image in pixels\n    Height: LongInt;      // Height of image in pixels\n    Format: TImageFormat; // Data format of image\n    Size: LongInt;        // Size of image bits in Bytes\n    Bits: Pointer;        // Pointer to memory containing image bits\n    Palette: PPalette32;  // Image palette for indexed images\n    Tag: Pointer;         // User data\n  end;\n  PImageData = ^TImageData;\n\n  { Pixel format information used in conversions to/from 16 and 8 bit ARGB\n    image formats.}\n  TPixelFormatInfo = packed record\n    ABitCount, RBitCount, GBitCount, BBitCount: Byte;\n    ABitMask, RBitMask, GBitMask, BBitMask: LongWord;\n    AShift, RShift, GShift, BShift: Byte;\n    ARecDiv, RRecDiv, GRecDiv, BRecDiv: Byte;\n  end;\n  PPixelFormatInfo = ^TPixelFormatInfo;\n\n  PImageFormatInfo = ^TImageFormatInfo;\n\n  { Look at TImageFormatInfo.GetPixelsSize for details.}\n  TFormatGetPixelsSizeFunc = function(Format: TImageFormat; Width,\n    Height: LongInt): LongInt;\n  { Look at TImageFormatInfo.CheckDimensions for details.}\n  TFormatCheckDimensionsProc = procedure(Format: TImageFormat; var Width,\n    Height: LongInt);\n  { Function for getting pixel colors. Native pixel is read from Image and\n    then translated to 32 bit ARGB.}\n  TGetPixel32Func = function(Bits: Pointer; Info: PImageFormatInfo;\n    Palette: PPalette32): TColor32Rec;\n  { Function for getting pixel colors. Native pixel is read from Image and\n    then translated to FP ARGB.}\n  TGetPixelFPFunc = function(Bits: Pointer; Info: PImageFormatInfo;\n    Palette: PPalette32): TColorFPRec;\n  { Procedure for setting pixel colors. Input 32 bit ARGB color is translated to\n    native format and then written to Image.}\n  TSetPixel32Proc = procedure(Bits: Pointer; Info: PImageFormatInfo;\n    Palette: PPalette32;const Color: TColor32Rec);\n  { Procedure for setting pixel colors. Input FP ARGB color is translated to\n    native format and then written to Image.}\n  TSetPixelFPProc = procedure(Bits: Pointer; Info: PImageFormatInfo;\n    Palette: PPalette32; const Color: TColorFPRec);\n\n  { Additional information for each TImageFormat value.}\n  TImageFormatInfo = packed record\n    Format: TImageFormat;             // Format described by this record\n    Name: array[0..15] of Char;       // Symbolic name of format\n    BytesPerPixel: LongInt;           // Number of bytes per pixel (note: it is\n                                      // 0 for formats where BitsPerPixel < 8 (e.g. DXT).\n                                      // Use GetPixelsSize function to get size of\n                                      // image data.\n    ChannelCount: LongInt;            // Number of image channels (R, G, B, A, Gray)\n    PaletteEntries: LongInt;          // Number of palette entries\n    HasGrayChannel: Boolean;          // True if image has grayscale channel\n    HasAlphaChannel: Boolean;         // True if image has alpha channel\n    IsFloatingPoint: Boolean;         // True if image has floating point pixels\n    UsePixelFormat: Boolean;          // True if image uses pixel format\n    IsRBSwapped: Boolean;             // True if Red and Blue channels are swapped\n                                      // e.g. A16B16G16R16 has IsRBSwapped True\n    RBSwapFormat: TImageFormat;       // Indicates supported format with swapped\n                                      // Red and Blue channels, ifUnknown if such\n                                      // format does not exist\n    IsIndexed: Boolean;               // True if image uses palette\n    IsSpecial: Boolean;               // True if image is in special format\n    IsPasstrough: Boolean;            // True if image is in passtrough program (Imaging\n                                      // iself doesn't know how to decode and encode it -\n                                      // complex texture compressions etc.)\n    PixelFormat: PPixelFormatInfo;    // Pixel format structure\n    GetPixelsSize: TFormatGetPixelsSizeFunc; // Returns size in bytes of\n                                      // Width * Height pixels of image\n    CheckDimensions: TFormatCheckDimensionsProc; // some formats have limited\n                                      // values of Width and Height. This\n                                      // procedure checks and changes dimensions\n                                      // to be valid for given format.\n    GetPixel32: TGetPixel32Func;      // 32bit ARGB pixel get function\n    GetPixelFP: TGetPixelFPFunc;      // FP ARGB pixel get function\n    SetPixel32: TSetPixel32Proc;      // 32bit ARGB pixel set procedure\n    SetPixelFP: TSetPixelFPProc;      // FP ARGB pixel set procedure\n    SpecialNearestFormat: TImageFormat; // Regular image format used when\n                                      // compressing/decompressing special images\n                                      // as source/target\n  end;\n\n  { Handle to list of image data records.}\n  TImageDataList = Pointer;\n  PImageDataList = ^TImageDataList;\n\n  { Handle to input/output.}\n  TImagingHandle = Pointer;\n\n  { Filters used in functions that resize images or their portions.}\n  TResizeFilter = (\n    rfNearest  = 0,\n    rfBilinear = 1,\n    rfBicubic  = 2,\n    rfLanczos  = 3);\n\n  { Seek origin mode for IO function Seek.}\n  TSeekMode = (\n   smFromBeginning = 0,\n   smFromCurrent   = 1,\n   smFromEnd       = 2);\n\n  TOpenMode = (\n    omReadOnly  = 0, // Opens file for reading only\n    omCreate    = 1, // Creates new file (overwriting any existing) and opens it for writing\n    omReadWrite = 2  // Opens for reading and writing. Non existing file is created.\n  );\n\n  { IO functions used for reading and writing images from/to input/output.}\n  TOpenProc = function(Source: PChar; Mode: TOpenMode): TImagingHandle; cdecl;\n  TCloseProc = procedure(Handle: TImagingHandle); cdecl;\n  TEofProc = function(Handle: TImagingHandle): Boolean; cdecl;\n  TSeekProc = function(Handle: TImagingHandle; Offset: LongInt; Mode: TSeekMode): LongInt; cdecl;\n  TTellProc = function(Handle: TImagingHandle): LongInt; cdecl;\n  TReadProc = function(Handle: TImagingHandle; Buffer: Pointer; Count: LongInt): LongInt; cdecl;\n  TWriteProc = function(Handle: TImagingHandle; Buffer: Pointer; Count: LongInt): LongInt; cdecl;\n       \n{$IFNDEF FPC}\ntype\n{$IF CompilerVersion <= 18.5}\n  PtrUInt = LongWord;\n{$ELSE}\n  PtrUInt = NativeUInt;\n{$IFEND}\n{$ENDIF}\n\nimplementation\n\n{\n  File Notes:\n\n  -- TODOS ----------------------------------------------------\n    - add lookup tables to pixel formats for fast conversions\n\n  -- 0.77.1 ---------------------------------------------------\n    - Added \"Passtrough\" image data formats.\n    - Added Tag to TImageData for storing user data.\n    - Added ImagingPNGZLibStrategy option.\n    - Changed IO functions. Merged open functions to one\n      and added third open mode R/W (for TIFF append etc.).\n    - Added new image data formats and related structures:\n      ifR32G32B32F, ifB32G32G32F.\n\n  -- 0.26.5 Changes/Bug Fixes ---------------------------------\n    - Added ifBinary image format and ImagingBinaryTreshold option.\n    - Lanczos filter added to TResizeFilter enum.\n\n  -- 0.24.3 Changes/Bug Fixes ---------------------------------\n    - Added ifATI1N and ifATI2N image data formats.\n\n  -- 0.23 Changes/Bug Fixes -----------------------------------\n    - Added ifBTC image format and SpecialNearestFormat field\n      to TImageFormatInfo.\n\n  -- 0.21 Changes/Bug Fixes -----------------------------------\n    - Added option constants for PGM and PPM file formats.\n    - Added TPalette32Size256 and TPalette24Size256 types.\n\n  -- 0.19 Changes/Bug Fixes -----------------------------------\n    - added ImagingVersionPatch constant so bug fix only releases\n      can be distinguished from ordinary major/minor releases\n    - renamed TPixelFormat to TPixelFormatInfo to avoid name collisions\n      with Graphics.TPixelFormat\n    - added new image data formats:  ifR16F, ifA16R16G16B16F,\n      ifA16B16G16R16F\n    - added pixel get/set function pointers to TImageFormatInfo\n    - added 16bit half float type and color record\n    - renamed TColorFRec to TColorFPRec (and related types too)\n\n  -- 0.17 Changes/Bug Fixes -----------------------------------\n    - added option ImagingMipMapFilter which now controls resampling filter\n      used when generating mipmaps\n    - added TResizeFilter type\n    - added ChannelCount to TImageFormatInfo\n    - added new option constants for MNG and JNG images\n\n  -- 0.15 Changes/Bug Fixes -----------------------------------\n    - added RBSwapFormat to TImageFormatInfo for faster conversions\n      between swapped formats (it just calls SwapChannels now if\n      RBSwapFormat is not ifUnknown)\n    - moved TImageFormatInfo and required types from Imaging unit\n      here, removed TImageFormatShortInfo\n    - added new options: ImagingLoadOverrideFormat, ImagingSaveOverrideFormat\n\n  -- 0.13 Changes/Bug Fixes -----------------------------------\n    - new ImagingColorReductionMask option added\n    - new image format added: ifA16Gray16\n\n}\n\nend.\n"
  },
  {
    "path": "lib/Imaging/ImagingUtility.pas",
    "content": "{\n  Vampyre Imaging Library\n  by Marek Mauder \n  http://imaginglib.sourceforge.net\n\n  The contents of this file are used with permission, subject to the Mozilla\n  Public License Version 1.1 (the \"License\"); you may not use this file except\n  in compliance with the License. You may obtain a copy of the License at\n  http://www.mozilla.org/MPL/MPL-1.1.html\n\n  Software distributed under the License is distributed on an \"AS IS\" basis,\n  WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for\n  the specific language governing rights and limitations under the License.\n\n  Alternatively, the contents of this file may be used under the terms of the\n  GNU Lesser General Public License (the  \"LGPL License\"), in which case the\n  provisions of the LGPL License are applicable instead of those above.\n  If you wish to allow use of your version of this file only under the terms\n  of the LGPL License and not to allow others to use your version of this file\n  under the MPL, indicate your decision by deleting  the provisions above and\n  replace  them with the notice and other provisions required by the LGPL\n  License.  If you do not delete the provisions above, a recipient may use\n  your version of this file under either the MPL or the LGPL License.\n\n  For more information about the LGPL: http://www.gnu.org/copyleft/lesser.html\n}\n\n{ This unit contains utility functions and types for Imaging library.}\nunit ImagingUtility;\n\n{$I ImagingOptions.inc}\n\ninterface\n\nuses\n  SysUtils, Classes, Types;\n\nconst\n  STrue = 'True';\n  SFalse = 'False';\n\ntype\n  TByteArray = array[0..MaxInt - 1] of Byte;\n  PByteArray = ^TByteArray;\n  TWordArray = array[0..MaxInt div 2 - 1] of Word;\n  PWordArray = ^TWordArray;\n  TLongIntArray = array[0..MaxInt div 4 - 1] of LongInt;\n  PLongIntArray = ^TLongIntArray;\n  TLongWordArray = array[0..MaxInt div 4 - 1] of LongWord;\n  PLongWordArray = ^TLongWordArray;\n  TInt64Array = array[0..MaxInt div 8 - 1] of Int64;\n  PInt64Array = ^TInt64Array;\n  TSingleArray = array[0..MaxInt div 4 - 1] of Single;\n  PSingleArray = ^TSingleArray;\n  TBooleanArray = array[0..MaxInt - 1] of Boolean;\n  PBooleanArray = ^TBooleanArray;\n\n  TDynByteArray = array of Byte;\n  TDynIntegerArray = array of Integer;\n  TDynBooleanArray = array of Boolean;\n  TDynStringArray = array of string;\n  \n  TWordRec = packed record\n    case Integer of\n      0: (WordValue: Word);\n      1: (Low, High: Byte);\n  end;\n  PWordRec = ^TWordRec;\n  TWordRecArray = array[0..MaxInt div 2 - 1] of TWordRec;\n  PWordRecArray = ^TWordRecArray;\n\n  TLongWordRec = packed record\n    case Integer of\n      0: (LongWordValue: LongWord);\n      1: (Low, High: Word);\n      { Array variants - Index 0 means lowest significant byte (word, ...).}\n      2: (Words: array[0..1] of Word);\n      3: (Bytes: array[0..3] of Byte);\n  end;\n  PLongWordRec = ^TLongWordRec;\n  TLongWordRecArray = array[0..MaxInt div 4 - 1] of TLongWordRec;\n  PLongWordRecArray = ^TLongWordRecArray;\n\n  TInt64Rec = packed record\n    case Integer of\n      0: (Int64Value: Int64);\n      1: (Low, High: LongWord);\n      { Array variants - Index 0 means lowest significant byte (word, ...).}\n      2: (Words: array[0..3] of Word);\n      3: (Bytes: array[0..7] of Byte);\n  end;\n  PInt64Rec = ^TInt64Rec;\n  TInt64RecArray = array[0..MaxInt div 8 - 1] of TInt64Rec;\n  PInt64RecArray = ^TInt64RecArray;\n\n  TFloatHelper = record\n    Data: Int64;\n    case Integer of\n      0: (Data64: Int64);\n      1: (Data32: LongWord);\n  end;\n  PFloatHelper = ^TFloatHelper;\n\n  TFloatRect = record\n    Left, Top, Right, Bottom: Single;\n  end;\n\n  TChar2 = array[0..1] of AnsiChar;\n  TChar3 = array[0..2] of AnsiChar;\n  TChar4 = array[0..3] of AnsiChar;\n  TChar8 = array[0..7] of AnsiChar;\n  TChar16 = array[0..15] of AnsiChar;\n  TAnsiCharSet = set of AnsiChar;\n\n  ENotImplemented = class(Exception)\n  public\n    constructor Create;\n  end;\n\n  { Options for BuildFileList function:\n    flFullNames - file names in result will have full path names\n                (ExtractFileDir(Path) + FileName)\n    flRelNames  - file names in result will have names relative to\n                ExtractFileDir(Path) dir\n    flRecursive - adds files in subdirectories found in Path.}\n  TFileListOption = (flFullNames, flRelNames, flRecursive);\n  TFileListOptions = set of TFileListOption;\n\n\n{ Frees class instance and sets its reference to nil.}\nprocedure FreeAndNil(var Obj);\n{ Frees pointer and sets it to nil.}\nprocedure FreeMemNil(var P); {$IFDEF USE_INLINE}inline;{$ENDIF}\n{ Replacement of standard System.FreeMem procedure which checks if P is nil\n  (this is only needed for Free Pascal, Delphi makes checks in its FreeMem).}\nprocedure FreeMem(P: Pointer); {$IFDEF USE_INLINE}inline;{$ENDIF}\n{ Returns current exception object. Do not call outside exception handler.}\nfunction GetExceptObject: Exception; {$IFDEF USE_INLINE}inline;{$ENDIF}\n{ Returns time value with microsecond resolution.}\nfunction GetTimeMicroseconds: Int64;\n{ Returns time value with milisecond resolution.}\nfunction GetTimeMilliseconds: Int64;\n\n{ Returns file extension (without \".\" dot)}\nfunction GetFileExt(const FileName: string): string;\n{ Returns file name of application's executable.}\nfunction GetAppExe: string;\n{ Returns directory where application's exceutable is located without\n  path delimiter at the end.}\nfunction GetAppDir: string;\n{ Works like SysUtils.ExtractFileName but supports '/' and '\\' dir delimiters\n  at the same time (whereas ExtractFileName supports on default delimiter on current platform).}\nfunction GetFileName(const FileName: string): string;\n{ Works like SysUtils.ExtractFileDir but supports '/' and '\\' dir delimiters\n  at the same time (whereas ExtractFileDir supports on default delimiter on current platform).}\nfunction GetFileDir(const FileName: string): string;\n{ Returns True if Subject matches given Mask with optional case sensitivity.\n  Mask can contain ? and * special characters: ? matches\n  one character, * matches zero or more characters.}\nfunction StrMaskMatch(const Subject, Mask: string; CaseSensitive: Boolean = False): Boolean;\n{ This function fills Files string list with names of files found\n  with FindFirst/FindNext functions (See details on Path/Atrr here).\n  - BuildFileList('c:\\*.*', faAnyFile, List, [flRecursive]) returns\n    list of all files (only name.ext - no path) on C drive\n  - BuildFileList('d:\\*.*', faDirectory, List, [flFullNames]) returns\n    list of all directories (d:\\dirxxx) in root of D drive.}\nfunction BuildFileList(Path: string; Attr: LongInt; Files: TStrings;\n  Options: TFileListOptions = []): Boolean;\n{ Similar to RTL's Pos function but with optional Offset where search will start.\n  This function is in the RTL StrUtils unit but }\nfunction PosEx(const SubStr, S: string; Offset: LongInt = 1): LongInt;\n{ Same as PosEx but without case sensitivity.}\nfunction PosNoCase(const SubStr, S: string; Offset: LongInt = 1): LongInt; {$IFDEF USE_INLINE}inline;{$ENDIF}\n{ Returns a sub-string from S which is followed by\n  Sep separator and deletes the sub-string from S including the separator.}\nfunction StrToken(var S: string; Sep: Char): string;\n{ Same as StrToken but searches from the end of S string.}\nfunction StrTokenEnd(var S: string; Sep: Char): string;\n{ Fills instance of TStrings with tokens from string S where tokens are separated by\n  one of Seps characters.}\nprocedure StrTokensToList(const S: string; Sep: Char; Tokens: TStrings);\n{ Returns string representation of integer number (with digit grouping).\n  Uses current locale.}\nfunction IntToStrFmt(const I: Int64): string; {$IFDEF USE_INLINE}inline;{$ENDIF}\n{ Returns string representation of float number (with digit grouping).\n  Uses current locale.}\nfunction FloatToStrFmt(const F: Double; Precision: Integer = 2): string; {$IFDEF USE_INLINE}inline;{$ENDIF}\n{ Returns format settings for parsing floats (dot as decimal separator).\n  Useful when fomatting/parsing floats etc.}\nfunction GetFormatSettingsForFloats: TFormatSettings;\n{ Returns True if S contains at least one of the substrings in SubStrs array. Case sensitive.}\nfunction ContainsAnySubStr(const S: string; const SubStrs: array of string): Boolean;\n{ Extracts substring starting at IdxStart ending at IdxEnd.\n  S[IdxEnd] is not included in the result.}\nfunction SubString(const S: string; IdxStart, IdxEnd: Integer): string; {$IFDEF USE_INLINE}inline;{$ENDIF}\n\n{ Clamps integer value to range <Min, Max>}\nfunction ClampInt(Number: LongInt; Min, Max: LongInt): LongInt; {$IFDEF USE_INLINE}inline;{$ENDIF}\n{ Clamps float value to range <Min, Max>}\nfunction ClampFloat(Number: Single; Min, Max: Single): Single; {$IFDEF USE_INLINE}inline;{$ENDIF}\n{ Clamps integer value to Byte boundaries.}\nfunction ClampToByte(Value: LongInt): LongInt; {$IFDEF USE_INLINE}inline;{$ENDIF}\n{ Clamps integer value to Word boundaries.}\nfunction ClampToWord(Value: LongInt): LongInt; {$IFDEF USE_INLINE}inline;{$ENDIF}\n{ Returns True if Num is power of 2.}\nfunction IsPow2(Num: LongInt): Boolean; {$IFDEF USE_INLINE}inline;{$ENDIF}\n{ Returns next power of 2 greater than or equal to Num\n  (if Num itself is power of 2 then it retuns Num).}\nfunction NextPow2(Num: LongInt): LongInt; {$IFDEF USE_INLINE}inline;{$ENDIF}\n{ Raises 2 to the given integer power (in range [0, 30]).}\nfunction Pow2Int(Exponent: LongInt): LongInt; {$IFDEF USE_INLINE}inline;{$ENDIF}\n{ Raises Base to any power.}\nfunction Power(const Base, Exponent: Single): Single;\n{ Returns log base 2 of integer X (max 2^30) or -1 if X is not power of 2.}\nfunction Log2Int(X: LongInt): LongInt; {$IFDEF USE_INLINE}inline;{$ENDIF}\n{ Returns log base 2 of X.}\nfunction Log2(X: Single): Single;\n{ Returns log base 10 of X.}\nfunction Log10(X: Single): Single;\n{ Returns largest integer <= Val (for 5.9 returns 5).}\nfunction Floor(Value: Single): LongInt; {$IFDEF USE_INLINE}inline;{$ENDIF}\n{ Returns smallest integer >= Val (for 5.1 returns 6).}\nfunction Ceil(Value: Single): LongInt; {$IFDEF USE_INLINE}inline;{$ENDIF}\n{ Returns lesser of two integer numbers.}\nfunction Min(A, B: LongInt): LongInt; {$IFDEF USE_INLINE}inline;{$ENDIF}\n{ Returns lesser of two float numbers.}\nfunction MinFloat(A, B: Single): Single; {$IFDEF USE_INLINE}inline;{$ENDIF}\n{ Returns greater of two integer numbers.}\nfunction Max(A, B: LongInt): LongInt; {$IFDEF USE_INLINE}inline;{$ENDIF}\n{ Returns greater of two float numbers.}\nfunction MaxFloat(A, B: Single): Single; {$IFDEF USE_INLINE}inline;{$ENDIF}\n{ Returns result from multiplying Number by Numerator and then dividing by Denominator.\n  Denominator must be greater than 0.}\nfunction MulDiv(Number, Numerator, Denominator: Word): Word; {$IFDEF USE_INLINE}inline;{$ENDIF}\n\n{ Switches Boolean value.}\nprocedure Switch(var Value: Boolean); {$IFDEF USE_INLINE}inline;{$ENDIF}\n{ If Condition is True then TruePart is retured, otherwise\n  FalsePart is returned.}\nfunction Iff(Condition: Boolean; TruePart, FalsePart: LongInt): LongInt; overload; {$IFDEF USE_INLINE}inline;{$ENDIF}\n{ If Condition is True then TruePart is retured, otherwise\n  FalsePart is returned.}\nfunction IffUnsigned(Condition: Boolean; TruePart, FalsePart: LongWord): LongWord; overload; {$IFDEF USE_INLINE}inline;{$ENDIF}\n{ If Condition is True then TruePart is retured, otherwise\n  FalsePart is returned.}\nfunction Iff(Condition, TruePart, FalsePart: Boolean): Boolean; overload; {$IFDEF USE_INLINE}inline;{$ENDIF}\n{ If Condition is True then TruePart is retured, otherwise\n  FalsePart is returned.}\nfunction Iff(Condition: Boolean; const TruePart, FalsePart: string): string; overload; {$IFDEF USE_INLINE}inline;{$ENDIF}\n{ If Condition is True then TruePart is retured, otherwise\n  FalsePart is returned.}\nfunction Iff(Condition: Boolean; TruePart, FalsePart: Char): Char; overload; {$IFDEF USE_INLINE}inline;{$ENDIF}\n{ If Condition is True then TruePart is retured, otherwise\n  FalsePart is returned.}\nfunction Iff(Condition: Boolean; TruePart, FalsePart: Pointer): Pointer; overload; {$IFDEF USE_INLINE}inline;{$ENDIF}\n{ If Condition is True then TruePart is retured, otherwise\n  FalsePart is returned.}\nfunction Iff(Condition: Boolean; const TruePart, FalsePart: Int64): Int64; overload; {$IFDEF USE_INLINE}inline;{$ENDIF}\n{ If Condition is True then TruePart is retured, otherwise\n  FalsePart is returned.}\nfunction IffFloat(Condition: Boolean; TruePart, FalsePart: Single): Single; {$IFDEF USE_INLINE}inline;{$ENDIF}\n{ Swaps two Boolean values}\nprocedure SwapValues(var A, B: Boolean); overload;\n{ Swaps two Byte values}\nprocedure SwapValues(var A, B: Byte); overload;\n{ Swaps two Word values}\nprocedure SwapValues(var A, B: Word); overload;\n{ Swaps two LongInt values}\nprocedure SwapValues(var A, B: LongInt); overload;\n{ Swaps two Single values}\nprocedure SwapValues(var A, B: Single); overload;\n{ Swaps two LongInt values if necessary to ensure that Min <= Max.}\nprocedure SwapMin(var Min, Max: LongInt); {$IFDEF USE_INLINE}inline;{$ENDIF}\n{ This function returns True if running on little endian machine.}\nfunction IsLittleEndian: Boolean; {$IFDEF USE_INLINE}inline;{$ENDIF}\n{ Swaps byte order of Word value.}\nfunction SwapEndianWord(Value: Word): Word; overload; {$IFDEF USE_INLINE}inline;{$ENDIF}\n{ Swaps byte order of multiple Word values.}\nprocedure SwapEndianWord(P: PWordArray; Count: LongInt); overload;\n{ Swaps byte order of LongWord value.}\nfunction SwapEndianLongWord(Value: LongWord): LongWord; overload; {$IFDEF USE_INLINE}inline;{$ENDIF}\n{ Swaps byte order of multiple LongWord values.}\nprocedure SwapEndianLongWord(P: PLongWord; Count: LongInt); overload;\n\n{ Calculates CRC32 for the given data.}\nprocedure CalcCrc32(var Crc: LongWord; Data: Pointer; Size: LongInt);\n{ Fills given memory with given Byte value. Size is size of buffer in bytes.}\nprocedure FillMemoryByte(Data: Pointer; Size: LongInt; Value: Byte);\n{ Fills given memory with given Word value. Size is size of buffer in bytes.}\nprocedure FillMemoryWord(Data: Pointer; Size: LongInt; Value: Word);\n{ Fills given memory with given LongWord value. Size is size of buffer in bytes.}\nprocedure FillMemoryLongWord(Data: Pointer; Size: LongInt; Value: LongWord);\n{ Fills given memory zeroes.}\n{$EXTERNALSYM ZeroMemory} // Conflicts with WinAPI ZeroMemory in C++ Builder\nprocedure ZeroMemory(Data: Pointer; Size: Integer); {$IFDEF USE_INLINE}inline;{$ENDIF}\n\n{ Returns how many mipmap levels can be created for image of given size.}\nfunction GetNumMipMapLevels(Width, Height: LongInt): LongInt;\n{ Returns total number of levels of volume texture with given depth and\n  mipmap count (this is not depth * mipmaps!).}\nfunction GetVolumeLevelCount(Depth, MipMaps: LongInt): LongInt;\n{ Returns rectangle (X, Y, X + Width, Y + Height).}\nfunction BoundsToRect(X, Y, Width, Height: LongInt): TRect; overload; {$IFDEF USE_INLINE}inline;{$ENDIF}\n{ Returns rectangle (R.Left, R.Top, R.Left + R.Right, R.Top + R.Bottom).}\nfunction BoundsToRect(const R: TRect): TRect; overload; {$IFDEF USE_INLINE}inline;{$ENDIF}\n{ Returns rectangle (R.Left, R.Top, R.Right - R.Left, R.Bottom - R.Top).}\nfunction RectToBounds(const R: TRect): TRect; overload; {$IFDEF USE_INLINE}inline;{$ENDIF}\n{ Clips given bounds to Clip rectangle.}\nprocedure ClipRectBounds(var X, Y, Width, Height: LongInt; const Clip: TRect);\n{ Clips given source bounds and dest position. It is used by various CopyRect\n  functions that copy rect from one image to another. It handles clipping the same way\n  as Win32 BitBlt function. }\nprocedure ClipCopyBounds(var SrcX, SrcY, Width, Height, DstX, DstY: LongInt;\n  SrcImageWidth, SrcImageHeight: LongInt; const DstClip: TRect);\n{ Clips given source bounds and dest bounds. It is used by various StretchRect\n  functions that stretch rectangle of pixels from one image to another.\n  It handles clipping the same way as Win32 StretchBlt function. }\nprocedure ClipStretchBounds(var SrcX, SrcY, SrcWidth, SrcHeight, DstX, DstY,\n  DstWidth, DstHeight: LongInt; SrcImageWidth, SrcImageHeight: LongInt; const DstClip: TRect);\n{ Scales one rectangle to fit into another. Proportions are preserved so\n  it could be used for 'Stretch To Fit Window' image drawing for instance.}\nfunction ScaleRectToRect(const SourceRect, TargetRect: TRect): TRect;\n{ Scales given size to fit into max size while keeping the original ascpect ration.\n  Useful for calculating thumbnail dimensions etc.}\nfunction ScaleSizeToFit(const CurrentSize, MaxSize: TSize): TSize;\n{ Returns width of given rect. Part of RTL in newer Delphi.}\nfunction RectWidth(const Rect: TRect): Integer;\n{ Returns height of given rect. Part of RTL in newer Delphi.}\nfunction RectHeight(const Rect: TRect): Integer;\n{ Returns True if R1 fits into R2.}\nfunction RectInRect(const R1, R2: TRect): Boolean;\n{ Returns True if R1 and R2 intersects.}\nfunction RectIntersects(const R1, R2: TRect): Boolean;\n\n{ Converts pixel size in micrometers to corrensponding DPI.}\nfunction PixelSizeToDpi(SizeInMicroMeters: Single): Single;\n{ Converts DPI to corrensponding pixel size in micrometers.}\nfunction DpiToPixelSize(Dpi: Single): Single;\n\nfunction FloatRect(ALeft, ATop, ARight, ABottom: Single): TFloatRect;\nfunction FloatRectWidth(const R: TFloatRect): Single;\nfunction FloatRectHeight(const R: TFloatRect): Single;\n\n{ Formats given message for usage in Exception.Create(..). Use only\n  in except block - returned message contains message of last raised exception.}\nfunction FormatExceptMsg(const Msg: string; const Args: array of const): string;\n{ Outputs debug message - shows message dialog in Windows and writes to console\n  in Linux/Unix.}\nprocedure DebugMsg(const Msg: string; const Args: array of const);\n\nimplementation\n\nuses\n{$IF Defined(MSWINDOWS)}\n  Windows;\n{$ELSEIF Defined(FPC)}\n  Dos, BaseUnix, Unix;\n{$ELSEIF Defined(DELPHI)}\n  Posix.SysTime;\n{$IFEND}\n\nvar\n  FloatFormatSettings: TFormatSettings;\n\nconstructor ENotImplemented.Create;\nbegin\n  inherited Create('Not implemented');\nend;\n\nprocedure FreeAndNil(var Obj);\nvar\n  Temp: TObject;\nbegin\n  Temp := TObject(Obj);\n  Pointer(Obj) := nil;\n  Temp.Free;\nend;\n\nprocedure FreeMemNil(var P);\nbegin\n  FreeMem(Pointer(P));\n  Pointer(P) := nil;\nend;\n\nprocedure FreeMem(P: Pointer);\nbegin\n  if P <> nil then\n    System.FreeMem(P);\nend;\n\nfunction GetExceptObject: Exception;\nbegin\n  Result := Exception(ExceptObject);\nend;\n\n{$IF Defined(MSWINDOWS)}\nvar\n  PerfFrequency: Int64;\n  InvPerfFrequency: Single;\n\nfunction GetTimeMicroseconds: Int64;\nvar\n  Time: Int64;\nbegin\n  QueryPerformanceCounter(Time);\n  Result := Round(1000000 * InvPerfFrequency * Time);\nend;\n{$ELSEIF Defined(DELPHI)}\nfunction GetTimeMicroseconds: Int64;\nvar\n  Time: TimeVal;\nbegin\n  Posix.SysTime.GetTimeOfDay(Time, nil);\n  Result := Int64(Time.tv_sec) * 1000000 + Time.tv_usec;\nend;\n{$ELSEIF Defined(FPC)}\nfunction GetTimeMicroseconds: Int64;\nvar\n  TimeVal: TTimeVal;\nbegin\n  fpGetTimeOfDay(@TimeVal, nil);\n  Result := Int64(TimeVal.tv_sec) * 1000000 + TimeVal.tv_usec;\nend;\n{$IFEND}\n\nfunction GetTimeMilliseconds: Int64;\nbegin\n  Result := GetTimeMicroseconds div 1000;\nend;\n\nfunction GetFileExt(const FileName: string): string;\nbegin\n  Result := ExtractFileExt(FileName);\n  if Length(Result) > 1 then\n    Delete(Result, 1, 1);\nend;\n\nfunction GetAppExe: string;\n{$IF Defined(MSWINDOWS)}\nvar\n  FileName: array[0..MAX_PATH] of Char;\nbegin\n  SetString(Result, FileName,\n    Windows.GetModuleFileName(MainInstance, FileName, SizeOf(FileName)));\n{$ELSEIF Defined(DELPHI)} // Delphi non Win targets\nvar\n  FileName: array[0..1024] of Char;\nbegin\n  SetString(Result, FileName,\n    System.GetModuleFileName(MainInstance, FileName, SizeOf(FileName)));\n{$ELSE}\nbegin\n  Result := ParamStr(0);\n{$IFEND}\nend;\n\nfunction GetAppDir: string;\nbegin\n  Result := ExtractFileDir(GetAppExe);\nend;\n\nfunction GetFileName(const FileName: string): string;\nvar\n  I: Integer;\nbegin\n  I := LastDelimiter('\\/' + DriveDelim, FileName);\n  Result := Copy(FileName, I + 1, MaxInt);\nend;\n\nfunction GetFileDir(const FileName: string): string;\nconst\n  Delims = '\\/' + DriveDelim;\nvar\n  I: Integer;\nbegin\n  I := LastDelimiter(Delims, Filename);\n  if (I > 1) and\n    ((FileName[I] = Delims[1]) or (FileName[I] = Delims[2])) and\n    (not IsDelimiter(Delims, FileName, I - 1)) then Dec(I);\n  Result := Copy(FileName, 1, I);\nend;\n\nfunction StrMaskMatch(const Subject, Mask: string; CaseSensitive: Boolean): Boolean;\nvar\n  MaskLen, KeyLen : LongInt;\n\n  function CharMatch(A, B: Char): Boolean;\n  begin\n    if CaseSensitive then\n      Result := A = B\n    else\n      Result := AnsiUpperCase (A) = AnsiUpperCase (B);\n  end;\n\n  function MatchAt(MaskPos, KeyPos: LongInt): Boolean;\n  begin\n    while (MaskPos <= MaskLen) and (KeyPos <= KeyLen) do\n    begin\n      case Mask[MaskPos] of\n        '?' :\n          begin\n            Inc(MaskPos);\n            Inc(KeyPos);\n          end;\n        '*' :\n          begin\n            while (MaskPos <= MaskLen) and (Mask[MaskPos] = '*') do\n              Inc(MaskPos);\n            if MaskPos > MaskLen then\n            begin\n              Result := True;\n              Exit;\n            end;\n            repeat\n              if MatchAt(MaskPos, KeyPos) then\n              begin\n                Result := True;\n                Exit;\n              end;\n              Inc(KeyPos);\n            until KeyPos > KeyLen;\n            Result := False;\n            Exit;\n          end;\n        else\n          if not CharMatch(Mask[MaskPos], Subject[KeyPos]) then\n          begin\n            Result := False;\n            Exit;\n          end\n          else\n          begin\n            Inc(MaskPos);\n            Inc(KeyPos);\n          end;\n      end;\n    end;  \n\n    while (MaskPos <= MaskLen) and (AnsiChar(Mask[MaskPos]) in ['?', '*']) do\n      Inc(MaskPos);\n    if (MaskPos <= MaskLen) or (KeyPos <= KeyLen) then\n    begin\n      Result := False;\n      Exit;\n    end;\n\n    Result := True;\n  end;\n\nbegin\n  MaskLen := Length(Mask);\n  KeyLen := Length(Subject);\n  if MaskLen = 0 then\n  begin\n    Result := True;\n    Exit;\n  end;\n  Result := MatchAt(1, 1);\nend;\n\nfunction BuildFileList(Path: string; Attr: LongInt;\n  Files: TStrings; Options: TFileListOptions): Boolean;\nvar\n  FileMask: string;\n  RootDir: string;\n  Folders: TStringList;\n  CurrentItem: LongInt;\n  Counter: LongInt;\n  LocAttr: LongInt;\n\n  procedure BuildFolderList;\n  var\n    FindInfo: TSearchRec;\n    Rslt: LongInt;\n  begin\n    Counter := Folders.Count - 1;\n    CurrentItem := 0;\n    while CurrentItem <= Counter do\n    begin\n      // Searching for subfolders\n      Rslt := SysUtils.FindFirst(Folders[CurrentItem] + '*', faDirectory, FindInfo);\n      try\n        while Rslt = 0 do\n        begin\n          if (FindInfo.Name <> '.') and (FindInfo.Name <> '..') and\n            (FindInfo.Attr and faDirectory = faDirectory) then\n            Folders.Add(Folders[CurrentItem] + FindInfo.Name + PathDelim);\n          Rslt := SysUtils.FindNext(FindInfo);\n        end;\n      finally\n        SysUtils.FindClose(FindInfo);\n      end;\n      Counter := Folders.Count - 1;\n      Inc(CurrentItem);\n    end;\n  end;\n\n  procedure FillFileList(CurrentCounter: LongInt);\n  var\n    FindInfo: TSearchRec;\n    Res: LongInt;\n    CurrentFolder: string;\n  begin\n    CurrentFolder := Folders[CurrentCounter];\n    Res := SysUtils.FindFirst(CurrentFolder + FileMask, LocAttr, FindInfo);\n    if flRelNames in Options then\n      CurrentFolder := ExtractRelativePath(RootDir, CurrentFolder);\n    try\n      while Res = 0 do\n      begin\n        if (FindInfo.Name <> '.') and (FindInfo.Name <> '..') then\n        begin\n          if (flFullNames in Options) or (flRelNames in Options) then\n            Files.Add(CurrentFolder + FindInfo.Name)\n          else\n            Files.Add(FindInfo.Name);\n        end;\n        Res := SysUtils.FindNext(FindInfo);\n      end;\n    finally\n      SysUtils.FindClose(FindInfo);\n    end;\n  end;\n\nbegin\n  FileMask := ExtractFileName(Path);\n  RootDir := ExtractFilePath(Path);\n  Folders := TStringList.Create;\n  Folders.Add(RootDir);\n  Files.Clear;\n{$IFDEF DCC}\n  {$WARN SYMBOL_PLATFORM OFF}\n{$ENDIF}\n  if Attr = faAnyFile then\n    LocAttr := faSysFile or faHidden or faArchive or faReadOnly\n  else\n    LocAttr := Attr;\n{$IFDEF DCC}\n  {$WARN SYMBOL_PLATFORM ON}\n{$ENDIF}\n  // Here's the recursive search for nested folders\n  if flRecursive in Options then\n    BuildFolderList;\n  if Attr <> faDirectory then\n    for Counter := 0 to Folders.Count - 1 do\n      FillFileList(Counter)\n  else\n    Files.AddStrings(Folders);\n  Folders.Free;\n  Result := True;\nend;\n\nfunction PosEx(const SubStr, S: string; Offset: LongInt = 1): LongInt;\nvar\n  I, X: LongInt;\n  Len, LenSubStr: LongInt;\nbegin\n  I := Offset;\n  LenSubStr := Length(SubStr);\n  Len := Length(S) - LenSubStr + 1;\n  while I <= Len do\n  begin\n    if S[I] = SubStr[1] then\n    begin\n      X := 1;\n      while (X < LenSubStr) and (S[I + X] = SubStr[X + 1]) do\n        Inc(X);\n      if (X = LenSubStr) then\n      begin\n        Result := I;\n        Exit;\n      end;\n    end;\n    Inc(I);\n  end;\n  Result := 0;\nend;\n\nfunction PosNoCase(const SubStr, S: string; Offset: LongInt): LongInt;\nbegin\n  Result := PosEx(AnsiLowerCase(SubStr), AnsiLowerCase(S), Offset);\nend;\n\nfunction StrToken(var S: string; Sep: Char): string;\nvar\n  I: LongInt;\nbegin\n  I := Pos(Sep, S);\n  if I <> 0 then\n  begin\n    Result := Copy(S, 1, I - 1);\n    Delete(S, 1, I);\n  end\n  else\n  begin\n    Result := S;\n    S := '';\n  end;\nend;\n\nfunction StrTokenEnd(var S: string; Sep: Char): string;\nvar\n  I, J: LongInt;\nbegin\n  J := 0;\n  I := Pos(Sep, S);\n  while I <> 0 do\n  begin\n    J := I;\n    I := PosEx(Sep, S, J + 1);\n  end;\n  if J <> 0 then\n  begin\n    Result := Copy(S, J + 1, MaxInt);\n    Delete(S, J, MaxInt);\n  end\n  else\n  begin\n    Result := S;\n    S := '';\n  end;\nend;\n\nprocedure StrTokensToList(const S: string; Sep: Char; Tokens: TStrings);\nvar\n  Token, Str: string;\nbegin\n  Tokens.Clear;\n  Str := S;\n  while Str <> '' do\n  begin\n    Token := StrToken(Str, Sep);\n    Tokens.Add(Token);\n  end;\nend;\n\nfunction IntToStrFmt(const I: Int64): string;\nbegin\n  Result := Format('%.0n', [I * 1.0]);\nend;\n\nfunction FloatToStrFmt(const F: Double; Precision: Integer): string;\nbegin\n  Result := Format('%.' + IntToStr(Precision) + 'n', [F]);\nend;\n\nfunction GetFormatSettingsForFloats: TFormatSettings;\nbegin\n  Result := FloatFormatSettings;\nend;\n\nfunction ContainsAnySubStr(const S: string; const SubStrs: array of string): Boolean;\nvar\n  I: Integer;\nbegin\n  Result := False;\n  for I := 0 to High(SubStrs) do\n  begin\n    Result := Pos(SubStrs[I], S) > 0;\n    if Result then\n      Exit;\n  end;\nend;\n\nfunction SubString(const S: string; IdxStart, IdxEnd: Integer): string;\nbegin\n  Result := Copy(S, IdxStart, IdxEnd - IdxStart);\nend;\n\nfunction ClampInt(Number: LongInt; Min, Max: LongInt): LongInt;\nbegin\n  Result := Number;\n  if Result < Min then\n    Result := Min\n  else if Result > Max then\n    Result := Max;\nend;\n\nfunction ClampFloat(Number: Single; Min, Max: Single): Single;\nbegin\n  Result := Number;\n  if Result < Min then\n    Result := Min\n  else if Result > Max then\n    Result := Max;\nend;\n\nfunction ClampToByte(Value: LongInt): LongInt;\nbegin\n  Result := Value;\n  if Result > 255 then\n    Result := 255\n  else if Result < 0 then\n    Result := 0;\nend;\n\nfunction ClampToWord(Value: LongInt): LongInt;\nbegin\n  Result := Value;\n  if Result > 65535 then\n    Result := 65535\n  else if Result < 0 then\n    Result := 0;\nend;\n\nfunction IsPow2(Num: LongInt): Boolean;\nbegin\n  Result := (Num and -Num) = Num;\nend;\n\nfunction NextPow2(Num: LongInt): LongInt;\nbegin\n  Result := Num and -Num;\n  while Result < Num do\n    Result := Result shl 1;\nend;\n\nfunction Pow2Int(Exponent: LongInt): LongInt;\nbegin\n  Result := 1 shl Exponent;\nend;\n\nfunction Power(const Base, Exponent: Single): Single;\nbegin\n  if Exponent = 0.0 then\n    Result := 1.0\n  else if (Base = 0.0) and (Exponent > 0.0) then\n    Result := 0.0\n  else\n    Result := Exp(Exponent * Ln(Base));\nend;\n\nfunction Log2Int(X: LongInt): LongInt;\nbegin\n  case X of\n    1: Result := 0;\n    2: Result := 1;\n    4: Result := 2;\n    8: Result := 3;\n    16: Result := 4;\n    32: Result := 5;\n    64: Result := 6;\n    128: Result := 7;\n    256: Result := 8;\n    512: Result := 9;\n    1024: Result := 10;\n    2048: Result := 11;\n    4096: Result := 12;\n    8192: Result := 13;\n    16384: Result := 14;\n    32768: Result := 15;\n    65536: Result := 16;\n    131072: Result := 17;\n    262144: Result := 18;\n    524288: Result := 19;\n    1048576: Result := 20;\n    2097152: Result := 21;\n    4194304: Result := 22;\n    8388608: Result := 23;\n    16777216: Result := 24;\n    33554432: Result := 25;\n    67108864: Result := 26;\n    134217728: Result := 27;\n    268435456: Result := 28;\n    536870912: Result := 29;\n    1073741824: Result := 30;\n  else\n    Result := -1;\n  end;\nend;\n\nfunction Log2(X: Single): Single;\n{$IFDEF USE_ASM}\nasm\n  FLD1\n  FLD     X\n  FYL2X\n  FWAIT\nend;\n{$ELSE}\nconst\n  Ln2: Single = 0.6931471;\nbegin\n  Result := Ln(X) / Ln2;\nend;\n{$ENDIF}\n\nfunction Log10(X: Single): Single;\n{$IFDEF USE_ASM}\nasm\n  FLDLG2\n  FLD     X\n  FYL2X\n  FWAIT\nend;\n{$ELSE}\nconst\n  Ln10: Single = 2.30258509299405;\nbegin\n  Result := Ln(X) / Ln10;\nend;\n{$ENDIF}\n\nfunction Floor(Value: Single): LongInt;\nbegin\n  Result := Trunc(Value);\n  if Frac(Value) < 0.0 then\n    Dec(Result);\nend;\n\nfunction Ceil(Value: Single): LongInt;\nbegin\n  Result := Trunc(Value);\n  if Frac(Value) > 0.0 then\n    Inc(Result);\nend;\n\nprocedure Switch(var Value: Boolean);\nbegin\n  Value := not Value;\nend;\n\nfunction Iff(Condition: Boolean; TruePart, FalsePart: LongInt): LongInt;\nbegin\n  if Condition then\n    Result := TruePart\n  else\n    Result := FalsePart;\nend;\n\nfunction IffUnsigned(Condition: Boolean; TruePart, FalsePart: LongWord): LongWord;\nbegin\n  if Condition then\n    Result := TruePart\n  else\n    Result := FalsePart;\nend;\n\nfunction Iff(Condition, TruePart, FalsePart: Boolean): Boolean;\nbegin\n  if Condition then\n    Result := TruePart\n  else\n    Result := FalsePart;\nend;\n\nfunction Iff(Condition: Boolean; const TruePart, FalsePart: string): string;\nbegin\n  if Condition then\n    Result := TruePart\n  else\n    Result := FalsePart;\nend;\n\nfunction Iff(Condition: Boolean; TruePart, FalsePart: Char): Char;\nbegin\n  if Condition then\n    Result := TruePart\n  else\n    Result := FalsePart;\nend;\n\nfunction Iff(Condition: Boolean; TruePart, FalsePart: Pointer): Pointer;\nbegin\n  if Condition then\n    Result := TruePart\n  else\n    Result := FalsePart;\nend;\n\nfunction Iff(Condition: Boolean; const TruePart, FalsePart: Int64): Int64;\nbegin\n  if Condition then\n    Result := TruePart\n  else\n    Result := FalsePart;\nend;\n\nfunction IffFloat(Condition: Boolean; TruePart, FalsePart: Single): Single;\nbegin\n  if Condition then\n    Result := TruePart\n  else\n    Result := FalsePart;\nend;\n\nprocedure SwapValues(var A, B: Boolean);\nvar\n  Tmp: Boolean;\nbegin\n  Tmp := A;\n  A := B;\n  B := Tmp;\nend;\n\nprocedure SwapValues(var A, B: Byte);\nvar\n  Tmp: Byte;\nbegin\n  Tmp := A;\n  A := B;\n  B := Tmp;\nend;\n\nprocedure SwapValues(var A, B: Word);\nvar\n  Tmp: Word;\nbegin\n  Tmp := A;\n  A := B;\n  B := Tmp;\nend;\n\nprocedure SwapValues(var A, B: LongInt);\nvar\n  Tmp: LongInt;\nbegin\n  Tmp := A;\n  A := B;\n  B := Tmp;\nend;\n\nprocedure SwapValues(var A, B: Single);\nvar\n  Tmp: Single;\nbegin\n  Tmp := A;\n  A := B;\n  B := Tmp;\nend;\n\nprocedure SwapMin(var Min, Max: LongInt);\nvar\n  Tmp: LongInt;\nbegin\n  if Min > Max then\n  begin\n    Tmp := Min;\n    Min := Max;\n    Max := Tmp;\n  end;\nend;\n\nfunction Min(A, B: LongInt): LongInt;\nbegin\n  if A < B then\n    Result := A\n  else\n    Result := B;\nend;\n\nfunction MinFloat(A, B: Single): Single;\nbegin\n  if A < B then\n    Result := A\n  else\n    Result := B;\nend;\n\nfunction Max(A, B: LongInt): LongInt;\nbegin\n  if A > B then\n    Result := A\n  else\n    Result := B;\nend;\n\nfunction MaxFloat(A, B: Single): Single;\nbegin\n  if A > B then\n    Result := A\n  else\n    Result := B;\nend;\n\nfunction MulDiv(Number, Numerator, Denominator: Word): Word;\n{$IF Defined(USE_ASM) and (not Defined(USE_INLINE))}\nasm\n         MUL DX\n         DIV CX\nend;\n{$ELSE}\nbegin\n  Result := Number * Numerator div Denominator;\nend;\n{$IFEND}\n\nfunction IsLittleEndian: Boolean;\nvar\n  W: Word;\nbegin\n  W := $00FF;\n  Result := PByte(@W)^ = $FF;\nend;\n\nfunction SwapEndianWord(Value: Word): Word;\n{$IF Defined(USE_ASM) and (not Defined(USE_INLINE))}\nasm\n  XCHG   AH, AL\nend;\n{$ELSE}\nbegin\n  TWordRec(Result).Low := TWordRec(Value).High;\n  TWordRec(Result).High := TWordRec(Value).Low;\nend;\n{$IFEND}\n\nprocedure SwapEndianWord(P: PWordArray; Count: LongInt);\n{$IFDEF USE_ASM}\nasm\n@Loop:\n  MOV    CX, [EAX]\n  XCHG   CH, CL\n  MOV    [EAX], CX\n  ADD    EAX, 2\n  DEC    EDX\n  JNZ    @Loop\nend;\n{$ELSE}\nvar\n  I: LongInt;\n  Temp: Word;\nbegin\n  for I := 0 to Count - 1 do\n  begin\n    Temp := P[I];\n    TWordRec(P[I]).Low := TWordRec(Temp).High;\n    TWordRec(P[I]).High := TWordRec(Temp).Low;\n  end;\nend;\n{$ENDIF}\n\nfunction SwapEndianLongWord(Value: LongWord): LongWord;\n{$IF Defined(USE_ASM) and (not Defined(USE_INLINE))}\nasm\n  BSWAP   EAX\nend;\n{$ELSE}\nbegin\n  TLongWordRec(Result).Bytes[0] := TLongWordRec(Value).Bytes[3];\n  TLongWordRec(Result).Bytes[1] := TLongWordRec(Value).Bytes[2];\n  TLongWordRec(Result).Bytes[2] := TLongWordRec(Value).Bytes[1];\n  TLongWordRec(Result).Bytes[3] := TLongWordRec(Value).Bytes[0];\nend;\n{$IFEND}\n\nprocedure SwapEndianLongWord(P: PLongWord; Count: LongInt);\n{$IFDEF USE_ASM}\nasm\n@Loop:\n  MOV    ECX, [EAX]\n  BSWAP  ECX\n  MOV    [EAX], ECX\n  ADD    EAX, 4\n  DEC    EDX\n  JNZ    @Loop\nend;\n{$ELSE}\nvar\n  I: LongInt;\n  Temp: LongWord;\nbegin\n  for I := 0 to Count - 1 do\n  begin\n    Temp := PLongWordArray(P)[I];\n    TLongWordRec(PLongWordArray(P)[I]).Bytes[0] := TLongWordRec(Temp).Bytes[3];\n    TLongWordRec(PLongWordArray(P)[I]).Bytes[1] := TLongWordRec(Temp).Bytes[2];\n    TLongWordRec(PLongWordArray(P)[I]).Bytes[2] := TLongWordRec(Temp).Bytes[1];\n    TLongWordRec(PLongWordArray(P)[I]).Bytes[3] := TLongWordRec(Temp).Bytes[0];\n  end;\nend;\n{$ENDIF}\n\ntype\n  TCrcTable = array[Byte] of LongWord;\nvar\n  CrcTable: TCrcTable;\n\nprocedure InitCrcTable;\nconst\n  Polynom = $EDB88320;\nvar\n  I, J: LongInt;\n  C: LongWord;\nbegin\n  for I := 0 to 255 do\n  begin\n    C := I;\n    for J := 0 to 7 do\n    begin\n      if (C and $01) <> 0 then\n        C := Polynom xor (C shr 1)\n      else\n        C := C shr 1;\n    end;\n    CrcTable[I] := C;\n  end;\nend;\n\nprocedure CalcCrc32(var Crc: LongWord; Data: Pointer; Size: LongInt);\nvar\n  I: LongInt;\n  B: PByte;\nbegin\n  B := Data;\n  for I := 0 to Size - 1 do\n  begin\n    Crc := (Crc shr 8) xor CrcTable[B^ xor Byte(Crc)];\n    Inc(B);\n  end\nend;\n\nprocedure FillMemoryByte(Data: Pointer; Size: LongInt; Value: Byte);\n{$IFDEF USE_ASM}\nasm\n  PUSH   EDI\n  MOV    EDI, EAX\n  MOV    EAX, ECX\n  MOV    AH, AL\n  MOV    CX, AX\n  SHL    EAX, 16\n  MOV    AX, CX\n  MOV    ECX, EDX\n  SAR    ECX, 2\n  JS     @Exit\n  REP    STOSD\n  MOV    ECX, EDX\n  AND    ECX, 3\n  REP    STOSB\n  POP    EDI\n@Exit:\nend;\n{$ELSE}\nbegin\n  FillChar(Data^, Size, Value);\nend;\n{$ENDIF}\n\nprocedure FillMemoryWord(Data: Pointer; Size: LongInt; Value: Word);\n{$IFDEF USE_ASM}\nasm\n  PUSH   EDI\n  PUSH   EBX\n  MOV    EBX, EDX\n  MOV    EDI, EAX\n  MOV    EAX, ECX\n  MOV    CX, AX\n  SHL    EAX, 16\n  MOV    AX, CX\n  MOV    ECX, EDX\n  SHR    ECX, 2\n  JZ     @Word\n  REP    STOSD\n@Word:\n  MOV    ECX, EBX\n  AND    ECX, 2\n  JZ     @Byte\n  MOV    [EDI], AX\n  ADD    EDI, 2\n@Byte:\n  MOV    ECX, EBX\n  AND    ECX, 1\n  JZ     @Exit\n  MOV    [EDI], AL\n@Exit:\n  POP    EBX\n  POP    EDI\nend;\n{$ELSE}\nvar\n  I, V: LongWord;\nbegin\n  V := Value * $10000 + Value;\n  for I := 0 to Size div 4 - 1 do\n    PLongWordArray(Data)[I] := V;\n  case Size mod 4 of\n    1: PByteArray(Data)[Size - 1] := Lo(Value);\n    2: PWordArray(Data)[Size div 2] := Value;\n    3:\n      begin\n        PWordArray(Data)[Size  div 2 - 1] := Value;\n        PByteArray(Data)[Size - 1] := Lo(Value);\n      end;\n  end;\nend;\n{$ENDIF}\n\nprocedure FillMemoryLongWord(Data: Pointer; Size: LongInt; Value: LongWord);\n{$IFDEF USE_ASM}\nasm\n  PUSH   EDI\n  PUSH   EBX\n  MOV    EBX, EDX\n  MOV    EDI, EAX\n  MOV    EAX, ECX\n  MOV    ECX, EDX\n  SHR    ECX, 2\n  JZ     @Word\n  REP    STOSD\n@Word:\n  MOV    ECX, EBX\n  AND    ECX, 2\n  JZ     @Byte\n  MOV    [EDI], AX\n  ADD    EDI, 2\n@Byte:\n  MOV    ECX, EBX\n  AND    ECX, 1\n  JZ     @Exit\n  MOV    [EDI], AL\n@Exit:\n  POP    EBX\n  POP    EDI\nend;\n{$ELSE}\nvar\n  I: LongInt;\nbegin\n  for I := 0 to Size div 4 - 1 do\n    PLongWordArray(Data)[I] := Value;\n  case Size mod 4 of\n    1: PByteArray(Data)[Size - 1] := TLongWordRec(Value).Bytes[0];\n    2: PWordArray(Data)[Size div 2] := TLongWordRec(Value).Words[0];\n    3:\n      begin\n        PWordArray(Data)[Size div 2 - 1] := TLongWordRec(Value).Words[0];\n        PByteArray(Data)[Size - 1] := TLongWordRec(Value).Bytes[0];\n      end;\n  end;\nend;\n{$ENDIF}\n\nprocedure ZeroMemory(Data: Pointer; Size: Integer);\nbegin\n  FillMemoryByte(Data, Size, 0);\nend;\n\nfunction GetNumMipMapLevels(Width, Height: LongInt): LongInt;\nbegin\n  Result := 0;\n  if (Width > 0) and (Height > 0) then\n  begin\n    Result := 1;\n    while (Width <> 1) or (Height <> 1) do\n    begin\n      Width := Width div 2;\n      Height := Height div 2;\n      if Width < 1 then Width := 1;\n      if Height < 1 then Height := 1;\n      Inc(Result);\n    end;\n  end;\nend;\n\nfunction GetVolumeLevelCount(Depth, MipMaps: LongInt): LongInt;\nvar\n  I: LongInt;\nbegin\n  Result := Depth;\n  for I := 1 to MipMaps - 1 do\n    Inc(Result, ClampInt(Depth shr I, 1, Depth));\nend;\n\nfunction BoundsToRect(X, Y, Width, Height: LongInt): TRect;\nbegin\n  Result.Left := X;\n  Result.Top := Y;\n  Result.Right := X + Width;\n  Result.Bottom := Y + Height;\nend;\n\nfunction BoundsToRect(const R: TRect): TRect;\nbegin\n  Result.Left := R.Left;\n  Result.Top := R.Top;\n  Result.Right := R.Left + R.Right;\n  Result.Bottom := R.Top + R.Bottom;\nend;\n\nfunction RectToBounds(const R: TRect): TRect;\nbegin\n  Result.Left := R.Left;\n  Result.Top := R.Top;\n  Result.Right := R.Right - R.Left;\n  Result.Bottom := R.Bottom - R.Top;\nend;\n\nprocedure ClipRectBounds(var X, Y, Width, Height: LongInt; const Clip: TRect);\n\n  procedure ClipDim(var AStart, ALength: LongInt; ClipMin, ClipMax: LongInt);\n  begin\n    if AStart < ClipMin then\n    begin\n      ALength := ALength - (ClipMin - AStart);\n      AStart := ClipMin;\n    end;\n    if AStart + ALength > ClipMax then ALength := Max(0, ClipMax - AStart);\n  end;\n\nbegin\n  ClipDim(X, Width, Clip.Left, Clip.Right);\n  ClipDim(Y, Height, Clip.Top, Clip.Bottom);\nend;\n\nprocedure ClipCopyBounds(var SrcX, SrcY, Width, Height, DstX, DstY: LongInt; SrcImageWidth, SrcImageHeight: LongInt; const DstClip: TRect);\n\n  procedure ClipDim(var SrcPos, DstPos, Size: LongInt; SrcClipMax,\n    DstClipMin, DstClipMax: LongInt);\n  var\n    OldDstPos: LongInt;\n    Diff: LongInt;\n  begin\n    OldDstPos := Iff(DstPos < 0, DstPos, 0);\n    if DstPos < DstClipMin then\n    begin\n      Diff := DstClipMin - DstPos;\n      Size := Size - Diff;\n      SrcPos := SrcPos + Diff;\n      DstPos := DstClipMin;\n    end;\n    if SrcPos < 0 then\n    begin\n      Size := Size + SrcPos - OldDstPos;\n      DstPos := DstPos - SrcPos + OldDstPos;\n      SrcPos := 0;\n    end;\n    if SrcPos + Size > SrcClipMax then Size := SrcClipMax - SrcPos;\n    if DstPos + Size > DstClipMax then Size := DstClipMax - DstPos;\n  end;\n\nbegin\n  ClipDim(SrcX, DstX, Width, SrcImageWidth, DstClip.Left, DstClip.Right);\n  ClipDim(SrcY, DstY, Height, SrcImageHeight, DstClip.Top, DstClip.Bottom);\nend;\n\nprocedure ClipStretchBounds(var SrcX, SrcY, SrcWidth, SrcHeight, DstX, DstY,\n  DstWidth, DstHeight: LongInt; SrcImageWidth, SrcImageHeight: LongInt; const DstClip: TRect);\n\n  procedure ClipDim(var SrcPos, DstPos, SrcSize, DstSize: LongInt; SrcClipMax,\n    DstClipMin, DstClipMax: LongInt);\n  var\n    OldSize: LongInt;\n    Diff: LongInt;\n    Scale: Single;\n  begin\n    Scale := DstSize / SrcSize;\n    if DstPos < DstClipMin then\n    begin\n      Diff := DstClipMin - DstPos;\n      DstSize := DstSize - Diff;\n      SrcPos := SrcPos + Round(Diff / Scale);\n      SrcSize := SrcSize - Round(Diff / Scale);\n      DstPos := DstClipMin;\n    end;\n    if SrcPos < 0 then\n    begin\n      SrcSize := SrcSize + SrcPos;\n      DstPos := DstPos - Round(SrcPos * Scale);\n      DstSize := DstSize + Round(SrcPos * Scale);\n      SrcPos := 0;\n    end;\n    if SrcPos + SrcSize > SrcClipMax then\n    begin\n      OldSize := SrcSize;\n      SrcSize := SrcClipMax - SrcPos;\n      DstSize := Round(DstSize * (SrcSize / OldSize));\n    end;\n    if DstPos + DstSize > DstClipMax then\n    begin\n      OldSize := DstSize;\n      DstSize := DstClipMax - DstPos;\n      SrcSize := Round(SrcSize * (DstSize / OldSize));\n    end;\n  end;\n\nbegin\n  ClipDim(SrcX, DstX, SrcWidth, DstWidth, SrcImageWidth, DstClip.Left, DstClip.Right);\n  ClipDim(SrcY, DstY, SrcHeight, DstHeight, SrcImageHeight, DstClip.Top, DstClip.Bottom);\nend;\n\nfunction ScaleRectToRect(const SourceRect, TargetRect: TRect): TRect;\nvar\n  SourceWidth: LongInt;\n  SourceHeight: LongInt;\n  TargetWidth: LongInt;\n  TargetHeight: LongInt;\n  ScaledWidth: LongInt;\n  ScaledHeight: LongInt;\nbegin\n  SourceWidth := SourceRect.Right - SourceRect.Left;\n  SourceHeight := SourceRect.Bottom - SourceRect.Top;\n  TargetWidth := TargetRect.Right - TargetRect.Left;\n  TargetHeight := TargetRect.Bottom - TargetRect.Top;\n\n  if SourceWidth * TargetHeight < SourceHeight * TargetWidth then\n  begin\n    ScaledWidth := (SourceWidth * TargetHeight) div SourceHeight;\n    Result := BoundsToRect(TargetRect.Left + ((TargetWidth - ScaledWidth) div 2),\n      TargetRect.Top, ScaledWidth, TargetHeight);\n  end\n  else\n  begin\n    ScaledHeight := (SourceHeight * TargetWidth) div SourceWidth;\n    Result := BoundsToRect(TargetRect.Left, TargetRect.Top + ((TargetHeight - ScaledHeight) div 2),\n      TargetWidth, ScaledHeight);\n  end;\nend;\n\nfunction ScaleSizeToFit(const CurrentSize, MaxSize: Types.TSize): Types.TSize;\nvar\n  SR, TR, ScaledRect: TRect;\nbegin\n  SR := Types.Rect(0, 0, CurrentSize.CX, CurrentSize.CY);\n  TR := Types.Rect(0, 0, MaxSize.CX, MaxSize.CY);\n  ScaledRect := ScaleRectToRect(SR, TR);\n  Result.CX := ScaledRect.Right - ScaledRect.Left;\n  Result.CY := ScaledRect.Bottom - ScaledRect.Top;\nend;\n\nfunction RectWidth(const Rect: TRect): Integer;\nbegin\n  Result := Rect.Right - Rect.Left;\nend;\n\nfunction RectHeight(const Rect: TRect): Integer;\nbegin\n  Result := Rect.Bottom - Rect.Top;\nend;\n\nfunction RectInRect(const R1, R2: TRect): Boolean;\nbegin\n  Result:=\n    (R1.Left >= R2.Left) and\n    (R1.Top >= R2.Top) and\n    (R1.Right <= R2.Right) and\n    (R1.Bottom <= R2.Bottom);\nend;\n\nfunction RectIntersects(const R1, R2: TRect): Boolean;\nbegin\n  Result :=\n    not (R1.Left > R2.Right) and\n    not (R1.Top > R2.Bottom) and\n    not (R1.Right < R2.Left) and\n    not (R1.Bottom < R2.Top);\nend;\n\nfunction PixelSizeToDpi(SizeInMicroMeters: Single): Single;\nbegin\n  Result := 25400 / SizeInMicroMeters;\nend;\n\nfunction DpiToPixelSize(Dpi: Single): Single;\nbegin\n  Result := 1e03 / (Dpi / 25.4);\nend;\n\nfunction FloatRect(ALeft, ATop, ARight, ABottom: Single): TFloatRect;\nbegin\n  with Result do\n  begin\n    Left := ALeft;\n    Top := ATop;\n    Right := ARight;\n    Bottom := ABottom;\n  end;\nend;\n\nfunction FloatRectWidth(const R: TFloatRect): Single;\nbegin\n  Result := R.Right - R.Left;\nend;\n\nfunction FloatRectHeight(const R: TFloatRect): Single;\nbegin\n  Result := R.Bottom - R.Top;\nend;\n\nfunction FormatExceptMsg(const Msg: string; const Args: array of const): string;\nbegin\n  Result := Format(Msg + SLineBreak + 'Message: ' + GetExceptObject.Message, Args);\nend;\n\nprocedure DebugMsg(const Msg: string; const Args: array of const);\nvar\n  FmtMsg: string;\nbegin\n  FmtMsg := Format(Msg, Args);\n{$IFDEF MSWINDOWS}\n  if IsConsole then\n    WriteLn('DebugMsg: ' + FmtMsg)\n  else\n    MessageBox(GetActiveWindow, PChar(FmtMsg), 'DebugMsg', MB_OK);\n{$ENDIF}\n{$IFDEF UNIX}\n  WriteLn('DebugMsg: ' + FmtMsg);\n{$ENDIF}\n{$IFDEF MSDOS}\n  WriteLn('DebugMsg: ' + FmtMsg);\n{$ENDIF}\nend;\n\ninitialization\n  InitCrcTable;\n{$IFDEF MSWINDOWS}\n  QueryPerformanceFrequency(PerfFrequency);\n  InvPerfFrequency := 1.0 / PerfFrequency;\n{$ENDIF}\n\n{$IF Defined(DELPHI)}\n  {$IF CompilerVersion >= 23}\n  FloatFormatSettings := TFormatSettings.Create('en-US');\n  {$ELSE}\n  GetLocaleFormatSettings(1033, FloatFormatSettings);\n  {$IFEND}\n{$ELSE FPC}\n  FloatFormatSettings := DefaultFormatSettings;\n  FloatFormatSettings.DecimalSeparator := '.';\n{$IFEND}\n\n{\n  File Notes:\n\n  -- TODOS ----------------------------------------------------\n    - nothing now\n\n  -- 0.77.1 ----------------------------------------------------\n    - Added GetFileName, GetFileDir, RectWidth, RectHeight function.\n    - Added ScaleSizeToFit function.\n    - Added ZeroMemory and SwapValues for Booleans.\n    - Added Substring function.\n    - Renamed MatchFileNameMask to StrMaskMatch (it's for general use not\n      just filenames).\n    - Delphi XE2 new targets (Win64, OSX32) compatibility changes.\n    - Added GetFormatSettingsForFloats function.\n\n  -- 0.26.5 Changes/Bug Fixes -----------------------------------\n    - Added Log10 function.\n    - Added TFloatRect type and helper functions FloatRect, FloatRectWidth,\n      FloatRectHeight.\n    - Added string function ContainsAnySubStr.\n    - Added functions PixelSizeToDpi, DpiToPixelSize.\n\n  -- 0.26.1 Changes/Bug Fixes -----------------------------------\n    - Some formatting changes.\n    - Changed some string functions to work with localized strings.\n    - ASM version of PosEx had bugs, removed it.\n    - Added StrTokensToList function.\n\n  -- 0.25.0 Changes/Bug Fixes -----------------------------------\n    - Fixed error in ClipCopyBounds which was causing ... bad clipping!\n\n  -- 0.24.3 Changes/Bug Fixes -----------------------------------\n    - Added GetTimeMilliseconds function.\n    - Added IntToStrFmt and FloatToStrFmt helper functions.\n    \n  -- 0.23 Changes/Bug Fixes -----------------------------------\n    - Added RectInRect and RectIntersects functions\n    - Added some string utils: StrToken, StrTokenEnd, PosEx, PosNoCase.\n    - Moved BuildFileList here from DemoUtils.\n\n  -- 0.21 Changes/Bug Fixes -----------------------------------\n    - Moved GetVolumeLevelCount from ImagingDds here.\n    - Renamed FillMemory to FillMemoryByte to avoid name collision in C++ Builder.\n    - Added Iff function for Char, Pointer, and Int64 types.\n    - Added IsLittleEndian function.\n    - Added array types for TWordRec, TLongWordRec, and TInt64Rec.\n    - Added MatchFileNameMask function.\n\n  -- 0.19 Changes/Bug Fixes -----------------------------------\n    - added ScaleRectToRect (thanks to Paul Michell)\n    - added BoundsToRect, ClipBounds, ClipCopyBounds, ClipStretchBounds functions\n    - added MulDiv function\n    - FreeAndNil is not inline anymore - caused AV in one program\n    \n  -- 0.17 Changes/Bug Fixes -----------------------------------\n\n    - GetAppExe didn't return absolute path in FreeBSD, fixed\n    - added debug message output\n    - fixed Unix compatibility issues (thanks to Ales Katona).\n      Imaging now compiles in FreeBSD and maybe in other Unixes as well.\n\n  -- 0.15 Changes/Bug Fixes -----------------------------------\n    - added some new utility functions\n\n  -- 0.13 Changes/Bug Fixes -----------------------------------\n    - added many new utility functions\n    - minor change in SwapEndian to avoid range check error\n\n}\nend.\n\n\n"
  },
  {
    "path": "lib/Imaging/ZLib/dzlib.pas",
    "content": "{*******************************************************}\n{                                                       }\n{       Delphi Supplemental Components                  }\n{       ZLIB Data Compression Interface Unit            }\n{                                                       }\n{       Copyright (c) 1997 Borland International        }\n{       Copyright (c) 1998 Jacques Nomssi Nzali         }\n{                                                       }\n{*******************************************************}\n\n{\n  Modified for \n  Vampyre Imaging Library\n  by Marek Mauder \n  http://imaginglib.sourceforge.net\n\n  You can choose which pascal zlib implementation will be\n  used. IMPASZLIB and FPCPASZLIB are translations of zlib\n  to pascal so they don't need any *.obj files.\n  The others are interfaces to *.obj files (Windows) or\n  *.so libraries (Linux).\n    Default implementation is IMPASZLIB because it can be compiled\n  by all supported compilers and works on all supported platforms.\n  I usually use implementation with the fastest decompression\n  when building release Win32 binaries.\n    FPCPASZLIB is useful for Lazarus applications. FPC's zlib is linked\n  to exe by default so there is no need to link additional (and almost identical)\n  IMPASZLIB.\n\n  There is a small speed comparison table of some of the\n  supported implementations (TGA image 28311570 bytes, compression level = 6,\n  Delphi 9, Win32, Athlon XP 1900).\n\n                 ZLib version Decompression  Compression   Comp. Size\n  IMPASZLIB     |   1.1.2   |    824 ms    |  4 280 ms  |  18 760 133 B\n  ZLIBEX        |   1.2.2   |    710 ms    |  1 590 ms* |  19 056 621 B\n  DELPHIZLIB    |   1.0.4   |    976 ms    |  9 190 ms  |  18 365 562 B\n  ZLIBPAS       |   1.2.3   |    680 ms    |  3 790  ms |  18 365 387 B\n    * obj files are compiled with compression level hardcoded to 1 (fastest)\n}\n\nunit dzlib;\n\n{$I ImagingOptions.inc}\n\ninterface\n\n{$DEFINE IMPASZLIB}\n{ $DEFINE ZLIBPAS}\n{ $DEFINE FPCPASZLIB}\n{ $DEFINE ZLIBEX}\n{ $DEFINE DELPHIZLIB}\n\n{ Automatically use FPC's PasZLib when compiling with FPC.}\n\n{$IFDEF FPC}\n  {$UNDEF IMPASZLIB}\n  {$DEFINE FPCPASZLIB}\n{$ENDIF}\n\nuses\n{$IF Defined(IMPASZLIB)}\n  { Use paszlib modified by me for Delphi and FPC }\n  imzdeflate, imzinflate, impaszlib,\n{$ELSEIF Defined(FPCPASZLIB)}\n  { Use FPC's paszlib }\n  zbase, paszlib,\n{$ELSEIF Defined(ZLIBPAS)}\n  { Pascal interface to ZLib shipped with ZLib C source }\n  zlibpas,\n{$ELSEIF Defined(ZLIBEX)}\n  { Use ZlibEx unit }\n  ZLibEx,\n{$ELSEIF Defined(DELPHIZLIB)}\n  { Use ZLib unit shipped with Delphi }\n  ZLib,\n{$IFEND}\n  ImagingTypes, SysUtils, Classes;\n\n{$IF Defined(IMPASZLIB) or Defined(FPCPASZLIB) or Defined(ZLIBPAS)}\ntype\n  TZStreamRec = z_stream;\n{$IFEND}\n\nconst\n  Z_NO_FLUSH      = 0;\n  Z_PARTIAL_FLUSH = 1;\n  Z_SYNC_FLUSH    = 2;\n  Z_FULL_FLUSH    = 3;\n  Z_FINISH        = 4;\n\n  Z_OK            =  0;\n  Z_STREAM_END    =  1;\n  Z_NEED_DICT     =  2;\n  Z_ERRNO         = -1;\n  Z_STREAM_ERROR  = -2;\n  Z_DATA_ERROR    = -3;\n  Z_MEM_ERROR     = -4;\n  Z_BUF_ERROR     = -5;\n  Z_VERSION_ERROR = -6;\n\n  Z_NO_COMPRESSION       =  0;\n  Z_BEST_SPEED           =  1;\n  Z_BEST_COMPRESSION     =  9;\n  Z_DEFAULT_COMPRESSION  = -1;\n\n  Z_FILTERED            = 1;\n  Z_HUFFMAN_ONLY        = 2;\n  Z_RLE                 = 3;\n  Z_DEFAULT_STRATEGY    = 0;\n\n  Z_BINARY   = 0;\n  Z_ASCII    = 1;\n  Z_UNKNOWN  = 2;\n\n  Z_DEFLATED = 8;\n\ntype\n  { Abstract ancestor class }\n  TCustomZlibStream = class(TStream)\n  private\n    FStrm: TStream;\n    FStrmPos: Integer;\n    FOnProgress: TNotifyEvent;\n    FZRec: TZStreamRec;\n    FBuffer: array [Word] of Byte;\n  protected\n    procedure Progress(Sender: TObject); dynamic;\n    property OnProgress: TNotifyEvent read FOnProgress write FOnProgress;\n    constructor Create(Strm: TStream);\n  end;\n\n{ TCompressionStream compresses data on the fly as data is written to it, and\n  stores the compressed data to another stream.\n\n  TCompressionStream is write-only and strictly sequential. Reading from the\n  stream will raise an exception. Using Seek to move the stream pointer\n  will raise an exception.\n\n  Output data is cached internally, written to the output stream only when\n  the internal output buffer is full.  All pending output data is flushed\n  when the stream is destroyed.\n\n  The Position property returns the number of uncompressed bytes of\n  data that have been written to the stream so far.\n\n  CompressionRate returns the on-the-fly percentage by which the original\n  data has been compressed:  (1 - (CompressedBytes / UncompressedBytes)) * 100\n  If raw data size = 100 and compressed data size = 25, the CompressionRate\n  is 75%\n\n  The OnProgress event is called each time the output buffer is filled and\n  written to the output stream.  This is useful for updating a progress\n  indicator when you are writing a large chunk of data to the compression\n  stream in a single call.}\n\n\n  TCompressionLevel = (clNone, clFastest, clDefault, clMax);\n\n  TCompressionStream = class(TCustomZlibStream)\n  private\n    function GetCompressionRate: Single;\n  public\n    constructor Create(CompressionLevel: TCompressionLevel; Dest: TStream);\n    destructor Destroy; override;\n    function Read(var Buffer; Count: Longint): Longint; override;\n    function Write(const Buffer; Count: Longint): Longint; override;\n    function Seek(Offset: Longint; Origin: Word): Longint; override;\n    property CompressionRate: Single read GetCompressionRate;\n    property OnProgress;\n  end;\n\n{ TDecompressionStream decompresses data on the fly as data is read from it.\n\n  Compressed data comes from a separate source stream.  TDecompressionStream\n  is read-only and unidirectional; you can seek forward in the stream, but not\n  backwards.  The special case of setting the stream position to zero is\n  allowed.  Seeking forward decompresses data until the requested position in\n  the uncompressed data has been reached.  Seeking backwards, seeking relative\n  to the end of the stream, requesting the size of the stream, and writing to\n  the stream will raise an exception.\n\n  The Position property returns the number of bytes of uncompressed data that\n  have been read from the stream so far.\n\n  The OnProgress event is called each time the internal input buffer of\n  compressed data is exhausted and the next block is read from the input stream.\n  This is useful for updating a progress indicator when you are reading a\n  large chunk of data from the decompression stream in a single call.}\n\n  TDecompressionStream = class(TCustomZlibStream)\n  public\n    constructor Create(Source: TStream);\n    destructor Destroy; override;\n    function Read(var Buffer; Count: Longint): Longint; override;\n    function Write(const Buffer; Count: Longint): Longint; override;\n    function Seek(Offset: Longint; Origin: Word): Longint; override;\n    property OnProgress;\n  end;\n\n\n\n{ CompressBuf compresses data, buffer to buffer, in one call.\n   In: InBuf = ptr to compressed data\n       InBytes = number of bytes in InBuf\n  Out: OutBuf = ptr to newly allocated buffer containing decompressed data\n       OutBytes = number of bytes in OutBuf   }\nprocedure CompressBuf(const InBuf: Pointer; InBytes: Integer;\n  var OutBuf: Pointer; var OutBytes: Integer;\n  CompressLevel: Integer = Z_DEFAULT_COMPRESSION;\n  CompressStrategy: Integer = Z_DEFAULT_STRATEGY);\n\n{ DecompressBuf decompresses data, buffer to buffer, in one call.\n   In: InBuf = ptr to compressed data\n       InBytes = number of bytes in InBuf\n       OutEstimate = zero, or est. size of the decompressed data\n  Out: OutBuf = ptr to newly allocated buffer containing decompressed data\n       OutBytes = number of bytes in OutBuf   }\nprocedure DecompressBuf(const InBuf: Pointer; InBytes: Integer;\n OutEstimate: Integer; var OutBuf: Pointer; var OutBytes: Integer);\n\n\ntype\n  EZlibError = class(Exception);\n  ECompressionError = class(EZlibError);\n  EDecompressionError = class(EZlibError);\n\nimplementation\n\nconst\n  ZErrorMessages: array[0..9] of PAnsiChar = (\n    'need dictionary',        // Z_NEED_DICT      (2)\n    'stream end',             // Z_STREAM_END     (1)\n    '',                       // Z_OK             (0)\n    'file error',             // Z_ERRNO          (-1)\n    'stream error',           // Z_STREAM_ERROR   (-2)\n    'data error',             // Z_DATA_ERROR     (-3)\n    'insufficient memory',    // Z_MEM_ERROR      (-4)\n    'buffer error',           // Z_BUF_ERROR      (-5)\n    'incompatible version',   // Z_VERSION_ERROR  (-6)\n    '');\n\nfunction zlibAllocMem(AppData: Pointer; Items, Size: Cardinal): Pointer;\nbegin\n  GetMem(Result, Items*Size);\nend;\n\nprocedure zlibFreeMem(AppData, Block: Pointer);\nbegin\n  FreeMem(Block);\nend;\n\nfunction CCheck(code: Integer): Integer;\nbegin\n  Result := code;\n  if code < 0 then\n    raise ECompressionError.Create('zlib: ' + ZErrorMessages[2 - code]);\nend;\n\nfunction DCheck(code: Integer): Integer;\nbegin\n  Result := code;\n  if code < 0 then\n    raise EDecompressionError.Create('zlib: ' + ZErrorMessages[2 - code]);\nend;\n\nprocedure CompressBuf(const InBuf: Pointer; InBytes: Integer;\n  var OutBuf: Pointer; var OutBytes: Integer;\n  CompressLevel, CompressStrategy: Integer);\nvar\n  strm: TZStreamRec;\n  P: Pointer;\nbegin\n  FillChar(strm, sizeof(strm), 0);\n{$IFNDEF FPCPASZLIB}\n  strm.zalloc := @zlibAllocMem;\n  strm.zfree := @zlibFreeMem;\n{$ENDIF}\n  OutBytes := ((InBytes + (InBytes div 10) + 12) + 255) and not 255;\n  GetMem(OutBuf, OutBytes);\n  try\n    strm.next_in := InBuf;\n    strm.avail_in := InBytes;\n    strm.next_out := OutBuf;\n    strm.avail_out := OutBytes;\n\n    CCheck(deflateInit2(strm, CompressLevel, Z_DEFLATED, MAX_WBITS,\n      DEF_MEM_LEVEL, CompressStrategy));\n\n    try\n      while CCheck(deflate(strm, Z_FINISH)) <> Z_STREAM_END do\n      begin\n        P := OutBuf;\n        Inc(OutBytes, 256);\n        ReallocMem(OutBuf, OutBytes);\n        strm.next_out := Pointer(PtrUInt(OutBuf) + (PtrUInt(strm.next_out) - PtrUInt(P)));\n        strm.avail_out := 256;\n      end;\n    finally\n      CCheck(deflateEnd(strm));\n    end;\n    ReallocMem(OutBuf, strm.total_out);\n    OutBytes := strm.total_out;\n  except\n    zlibFreeMem(nil, OutBuf);\n    raise\n  end;\nend;\n\nprocedure DecompressBuf(const InBuf: Pointer; InBytes: Integer;\n OutEstimate: Integer; var OutBuf: Pointer; var OutBytes: Integer);\nvar\n  strm: TZStreamRec;\n  P: Pointer;\n  BufInc: Integer;\nbegin\n  FillChar(strm, sizeof(strm), 0);\n{$IFNDEF FPCPASZLIB}\n  strm.zalloc := @zlibAllocMem;\n  strm.zfree := @zlibFreeMem;\n{$ENDIF}\n  BufInc := (InBytes + 255) and not 255;\n  if OutEstimate = 0 then\n    OutBytes := BufInc\n  else\n    OutBytes := OutEstimate;\n  GetMem(OutBuf, OutBytes);\n  try\n    strm.next_in := InBuf;\n    strm.avail_in := InBytes;\n    strm.next_out := OutBuf;\n    strm.avail_out := OutBytes;\n    DCheck(inflateInit_(strm, zlib_version, sizeof(strm)));\n    try\n      while DCheck(inflate(strm, Z_NO_FLUSH)) <> Z_STREAM_END do\n      begin\n        P := OutBuf;\n        Inc(OutBytes, BufInc);\n        ReallocMem(OutBuf, OutBytes);\n        strm.next_out := Pointer(PtrUInt(OutBuf) + (PtrUInt(strm.next_out) - PtrUInt(P)));\n        strm.avail_out := BufInc;\n      end;\n    finally\n      DCheck(inflateEnd(strm));\n    end;\n    ReallocMem(OutBuf, strm.total_out);\n    OutBytes := strm.total_out;\n  except\n    zlibFreeMem(nil, OutBuf);\n    raise\n  end;\nend;\n\n\n{ TCustomZlibStream }\n\nconstructor TCustomZLibStream.Create(Strm: TStream);\nbegin\n  inherited Create;\n  FStrm := Strm;\n  FStrmPos := Strm.Position;\n{$IFNDEF FPCPASZLIB}\n  FZRec.zalloc := @zlibAllocMem;\n  FZRec.zfree := @zlibFreeMem;\n{$ENDIF}\nend;\n\nprocedure TCustomZLibStream.Progress(Sender: TObject);\nbegin\n  if Assigned(FOnProgress) then FOnProgress(Sender);\nend;\n\n{ TCompressionStream }\n\nconstructor TCompressionStream.Create(CompressionLevel: TCompressionLevel;\n  Dest: TStream);\nconst\n  Levels: array [TCompressionLevel] of ShortInt =\n    (Z_NO_COMPRESSION, Z_BEST_SPEED, Z_DEFAULT_COMPRESSION, Z_BEST_COMPRESSION);\nbegin\n  inherited Create(Dest);\n  FZRec.next_out := @FBuffer;\n  FZRec.avail_out := sizeof(FBuffer);\n  CCheck(deflateInit_(FZRec, Levels[CompressionLevel], zlib_version, sizeof(FZRec)));\nend;\n\ndestructor TCompressionStream.Destroy;\nbegin\n  FZRec.next_in := nil;\n  FZRec.avail_in := 0;\n  try\n    if FStrm.Position <> FStrmPos then FStrm.Position := FStrmPos;\n    while (CCheck(deflate(FZRec, Z_FINISH)) <> Z_STREAM_END)\n      and (FZRec.avail_out = 0) do\n    begin\n      FStrm.WriteBuffer(FBuffer, sizeof(FBuffer));\n      FZRec.next_out := @FBuffer;\n      FZRec.avail_out := sizeof(FBuffer);\n    end;\n    if FZRec.avail_out < sizeof(FBuffer) then\n      FStrm.WriteBuffer(FBuffer, sizeof(FBuffer) - FZRec.avail_out);\n  finally\n    deflateEnd(FZRec);\n  end;\n  inherited Destroy;\nend;\n\nfunction TCompressionStream.Read(var Buffer; Count: Longint): Longint;\nbegin\n  raise ECompressionError.Create('Invalid stream operation');\nend;\n\nfunction TCompressionStream.Write(const Buffer; Count: Longint): Longint;\nbegin\n  FZRec.next_in := @Buffer;\n  FZRec.avail_in := Count;\n  if FStrm.Position <> FStrmPos then FStrm.Position := FStrmPos;\n  while (FZRec.avail_in > 0) do\n  begin\n    CCheck(deflate(FZRec, 0));\n    if FZRec.avail_out = 0 then\n    begin\n      FStrm.WriteBuffer(FBuffer, sizeof(FBuffer));\n      FZRec.next_out := @FBuffer;\n      FZRec.avail_out := sizeof(FBuffer);\n      FStrmPos := FStrm.Position;\n      Progress(Self);\n    end;\n  end;\n  Result := Count;\nend;\n\nfunction TCompressionStream.Seek(Offset: Longint; Origin: Word): Longint;\nbegin\n  if (Offset = 0) and (Origin = soFromCurrent) then\n    Result := FZRec.total_in\n  else\n    raise ECompressionError.Create('Invalid stream operation');\nend;\n\nfunction TCompressionStream.GetCompressionRate: Single;\nbegin\n  if FZRec.total_in = 0 then\n    Result := 0\n  else\n    Result := (1.0 - (FZRec.total_out / FZRec.total_in)) * 100.0;\nend;\n\n{ TDecompressionStream }\n\nconstructor TDecompressionStream.Create(Source: TStream);\nbegin\n  inherited Create(Source);\n  FZRec.next_in := @FBuffer;\n  FZRec.avail_in := 0;\n  DCheck(inflateInit_(FZRec, zlib_version, sizeof(FZRec)));\nend;\n\ndestructor TDecompressionStream.Destroy;\nbegin\n  inflateEnd(FZRec);\n  inherited Destroy;\nend;\n\nfunction TDecompressionStream.Read(var Buffer; Count: Longint): Longint;\nbegin\n  FZRec.next_out := @Buffer;\n  FZRec.avail_out := Count;\n  if FStrm.Position <> FStrmPos then FStrm.Position := FStrmPos;\n  while (FZRec.avail_out > 0) do\n  begin\n    if FZRec.avail_in = 0 then\n    begin\n      FZRec.avail_in := FStrm.Read(FBuffer, sizeof(FBuffer));\n      if FZRec.avail_in = 0 then\n        begin\n          Result := Count - Integer(FZRec.avail_out);\n          Exit;\n        end;\n      FZRec.next_in := @FBuffer;\n      FStrmPos := FStrm.Position;\n      Progress(Self);\n    end;\n    CCheck(inflate(FZRec, 0));\n  end;\n  Result := Count;\nend;\n\nfunction TDecompressionStream.Write(const Buffer; Count: Longint): Longint;\nbegin\n  raise EDecompressionError.Create('Invalid stream operation');\nend;\n\nfunction TDecompressionStream.Seek(Offset: Longint; Origin: Word): Longint;\nvar\n  I: Integer;\n  Buf: array [0..4095] of Byte;\nbegin\n  if (Offset = 0) and (Origin = soFromBeginning) then\n  begin\n    DCheck(inflateReset(FZRec));\n    FZRec.next_in := @FBuffer;\n    FZRec.avail_in := 0;\n    FStrm.Position := 0;\n    FStrmPos := 0;\n  end\n  else if ( (Offset >= 0) and (Origin = soFromCurrent)) or\n          ( ((Offset - Integer(FZRec.total_out)) > 0) and (Origin = soFromBeginning)) then\n  begin\n    if Origin = soFromBeginning then Dec(Offset, FZRec.total_out);\n    if Offset > 0 then\n    begin\n      for I := 1 to Offset div sizeof(Buf) do\n        ReadBuffer(Buf, sizeof(Buf));\n      ReadBuffer(Buf, Offset mod sizeof(Buf));\n    end;\n  end\n  else\n    raise EDecompressionError.Create('Invalid stream operation');\n  Result := FZRec.total_out;\nend;\n\nend.\n"
  },
  {
    "path": "lib/Imaging/ZLib/imadler.pas",
    "content": "Unit imadler;\n\n{\n  adler32.c -- compute the Adler-32 checksum of a data stream\n  Copyright (C) 1995-1998 Mark Adler\n\n  Pascal tranlastion\n  Copyright (C) 1998 by Jacques Nomssi Nzali\n  For conditions of distribution and use, see copyright notice in readme.txt\n}\n\ninterface\n\n{$I imzconf.inc}\n\nuses\n  imzutil;\n\nfunction adler32(adler : uLong; buf : pBytef; len : uInt) : uLong;\n\n{    Update a running Adler-32 checksum with the bytes buf[0..len-1] and\n   return the updated checksum. If buf is NIL, this function returns\n   the required initial value for the checksum.\n   An Adler-32 checksum is almost as reliable as a CRC32 but can be computed\n   much faster. Usage example:\n\n   var\n     adler : uLong;\n   begin\n     adler := adler32(0, Z_NULL, 0);\n\n     while (read_buffer(buffer, length) <> EOF) do\n       adler := adler32(adler, buffer, length);\n\n     if (adler <> original_adler) then\n       error();\n   end;\n}\n\nimplementation\n\nconst\n  BASE = uLong(65521); { largest prime smaller than 65536 }\n  {NMAX = 5552; original code with unsigned 32 bit integer }\n  { NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 }\n  NMAX = 3854;        { code with signed 32 bit integer }\n  { NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^31-1 }\n  { The penalty is the time loss in the extra MOD-calls. }\n\n\n{ ========================================================================= }\n\nfunction adler32(adler : uLong; buf : pBytef; len : uInt) : uLong;\nvar\n  s1, s2 : uLong;\n  k : int;\nbegin\n  s1 := adler and $ffff;\n  s2 := (adler shr 16) and $ffff;\n\n  if not Assigned(buf) then\n  begin\n    adler32 := uLong(1);\n    exit;\n  end;\n\n  while (len > 0) do\n  begin\n    if len < NMAX then\n      k := len\n    else\n      k := NMAX;\n    Dec(len, k);\n    {\n    while (k >= 16) do\n    begin\n      DO16(buf);\n      Inc(buf, 16);\n      Dec(k, 16);\n    end;\n    if (k <> 0) then\n    repeat\n      Inc(s1, buf^);\n      Inc(puf);\n      Inc(s2, s1);\n      Dec(k);\n    until (k = 0);\n    }\n    while (k > 0) do\n    begin\n      Inc(s1, buf^);\n      Inc(s2, s1);\n      Inc(buf);\n      Dec(k);\n    end;\n    s1 := s1 mod BASE;\n    s2 := s2 mod BASE;\n  end;\n  adler32 := (s2 shl 16) or s1;\nend;\n\n{\n#define DO1(buf,i)\n  begin\n    Inc(s1, buf[i]);\n    Inc(s2, s1);\n  end;\n#define DO2(buf,i)  DO1(buf,i); DO1(buf,i+1);\n#define DO4(buf,i)  DO2(buf,i); DO2(buf,i+2);\n#define DO8(buf,i)  DO4(buf,i); DO4(buf,i+4);\n#define DO16(buf)   DO8(buf,0); DO8(buf,8);\n}\nend.\n\n"
  },
  {
    "path": "lib/Imaging/ZLib/iminfblock.pas",
    "content": "Unit iminfblock;\n\n{ infblock.h and\n  infblock.c -- interpret and process block types to last block\n  Copyright (C) 1995-1998 Mark Adler\n\n  Pascal tranlastion\n  Copyright (C) 1998 by Jacques Nomssi Nzali\n  For conditions of distribution and use, see copyright notice in readme.txt\n}\n\ninterface\n\n{$I imzconf.inc}\n\nuses\n  {$IFDEF DEBUG}\n  SysUtils, strutils,\n  {$ENDIF}\n  imzutil, impaszlib;\n\nfunction inflate_blocks_new(var z : z_stream;\n                            c : check_func;  { check function }\n                            w : uInt     { window size }\n                            ) : pInflate_blocks_state;\n\nfunction inflate_blocks (var s : inflate_blocks_state;\n                         var z : z_stream;\n                         r : int             { initial return code }\n                         ) : int;\n\nprocedure inflate_blocks_reset (var s : inflate_blocks_state;\n                                var z : z_stream;\n                                c : puLong); { check value on output }\n\n\nfunction inflate_blocks_free(s : pInflate_blocks_state;\n                             var z : z_stream) : int;\n\nprocedure inflate_set_dictionary(var s : inflate_blocks_state;\n                                 const d : array of byte;  { dictionary }\n                                 n : uInt);         { dictionary length }\n\nfunction inflate_blocks_sync_point(var s : inflate_blocks_state) : int;\n\nimplementation\n\nuses\n  iminfcodes, iminftrees, iminfutil;\n\n{ Tables for deflate from PKZIP's appnote.txt. }\nConst\n  border : Array [0..18] Of Word  { Order of the bit length code lengths }\n    = (16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15);\n\n{ Notes beyond the 1.93a appnote.txt:\n\n   1. Distance pointers never point before the beginning of the output\n      stream.\n   2. Distance pointers can point back across blocks, up to 32k away.\n   3. There is an implied maximum of 7 bits for the bit length table and\n      15 bits for the actual data.\n   4. If only one code exists, then it is encoded using one bit.  (Zero\n      would be more efficient, but perhaps a little confusing.)  If two\n      codes exist, they are coded using one bit each (0 and 1).\n   5. There is no way of sending zero distance codes--a dummy must be\n      sent if there are none.  (History: a pre 2.0 version of PKZIP would\n      store blocks with no distance codes, but this was discovered to be\n      too harsh a criterion.)  Valid only for 1.93a.  2.04c does allow\n      zero distance codes, which is sent as one code of zero bits in\n      length.\n   6. There are up to 286 literal/length codes.  Code 256 represents the\n      end-of-block.  Note however that the static length tree defines\n      288 codes just to fill out the Huffman codes.  Codes 286 and 287\n      cannot be used though, since there is no length base or extra bits\n      defined for them.  Similarily, there are up to 30 distance codes.\n      However, static trees define 32 codes (all 5 bits) to fill out the\n      Huffman codes, but the last two had better not show up in the data.\n   7. Unzip can check dynamic Huffman blocks for complete code sets.\n      The exception is that a single code would not be complete (see #4).\n   8. The five bits following the block type is really the number of\n      literal codes sent minus 257.\n   9. Length codes 8,16,16 are interpreted as 13 length codes of 8 bits\n      (1+6+6).  Therefore, to output three times the length, you output\n      three codes (1+1+1), whereas to output four times the same length,\n      you only need two codes (1+3).  Hmm.\n  10. In the tree reconstruction algorithm, Code = Code + Increment\n      only if BitLength(i) is not zero.  (Pretty obvious.)\n  11. Correction: 4 Bits: # of Bit Length codes - 4     (4 - 19)\n  12. Note: length code 284 can represent 227-258, but length code 285\n      really is 258.  The last length deserves its own, short code\n      since it gets used a lot in very redundant files.  The length\n      258 is special since 258 - 3 (the min match length) is 255.\n  13. The literal/length and distance code bit lengths are read as a\n      single stream of lengths.  It is possible (and advantageous) for\n      a repeat code (16, 17, or 18) to go across the boundary between\n      the two sets of lengths. }\n\n\nprocedure inflate_blocks_reset (var s : inflate_blocks_state;\n                                var z : z_stream;\n                                c : puLong); { check value on output }\nbegin\n  if (c <> Z_NULL) then\n    c^ := s.check;\n  if (s.mode = BTREE) or (s.mode = DTREE) then\n    ZFREE(z, s.sub.trees.blens);\n  if (s.mode = CODES) then\n    inflate_codes_free(s.sub.decode.codes, z);\n\n  s.mode := ZTYPE;\n  s.bitk := 0;\n  s.bitb := 0;\n\n  s.write := s.window;\n  s.read := s.window;\n  if Assigned(s.checkfn) then\n  begin\n    s.check := s.checkfn(uLong(0), pBytef(NIL), 0);\n    z.adler := s.check;\n  end;\n  {$IFDEF DEBUG}\n  Tracev('inflate:   blocks reset');\n  {$ENDIF}\nend;\n\n\nfunction inflate_blocks_new(var z : z_stream;\n                            c : check_func;  { check function }\n                            w : uInt         { window size }\n                            ) : pInflate_blocks_state;\nvar\n  s : pInflate_blocks_state;\nbegin\n  s := pInflate_blocks_state( ZALLOC(z,1, sizeof(inflate_blocks_state)) );\n  if (s = Z_NULL) then\n  begin\n    inflate_blocks_new := s;\n    exit;\n  end;\n  s^.hufts := huft_ptr( ZALLOC(z, sizeof(inflate_huft), MANY) );\n\n  if (s^.hufts = Z_NULL) then\n  begin\n    ZFREE(z, s);\n    inflate_blocks_new := Z_NULL;\n    exit;\n  end;\n\n  s^.window := pBytef( ZALLOC(z, 1, w) );\n  if (s^.window = Z_NULL) then\n  begin\n    ZFREE(z, s^.hufts);\n    ZFREE(z, s);\n    inflate_blocks_new := Z_NULL;\n    exit;\n  end;\n  s^.zend := s^.window;\n  Inc(s^.zend, w);\n  s^.checkfn := c;\n  s^.mode := ZTYPE;\n  {$IFDEF DEBUG}  \n  Tracev('inflate:   blocks allocated');\n  {$ENDIF}\n  inflate_blocks_reset(s^, z, Z_NULL);\n  inflate_blocks_new := s;\nend;\n\n\nfunction inflate_blocks (var s : inflate_blocks_state;\n                         var z : z_stream;\n                         r : int) : int;           { initial return code }\nlabel\n  start_btree, start_dtree,\n  start_blkdone, start_dry,\n  start_codes;\n\nvar\n  t : uInt;               { temporary storage }\n  b : uLong;              { bit buffer }\n  k : uInt;               { bits in bit buffer }\n  p : pBytef;             { input data pointer }\n  n : uInt;               { bytes available there }\n  q : pBytef;             { output window write pointer }\n  m : uInt;               { bytes to end of window or read pointer }\n{ fixed code blocks }\nvar\n  bl, bd : uInt;\n  tl, td : pInflate_huft;\nvar\n  h : pInflate_huft;\n  i, j, c : uInt;\nvar\n  cs : pInflate_codes_state;\nbegin\n  { copy input/output information to locals }\n  p := z.next_in;\n  n := z.avail_in;\n  b := s.bitb;\n  k := s.bitk;\n  q := s.write;\n  if ptr2int(q) < ptr2int(s.read) then\n    m := uInt(ptr2int(s.read)-ptr2int(q)-1)\n  else\n    m := uInt(ptr2int(s.zend)-ptr2int(q));\n\n{ decompress an inflated block }\n\n\n  { process input based on current state }\n  while True do\n  Case s.mode of\n    ZTYPE:\n      begin\n        {NEEDBITS(3);}\n        while (k < 3) do\n        begin\n          {NEEDBYTE;}\n          if (n <> 0) then\n            r :=Z_OK\n          else\n          begin\n            {UPDATE}\n            s.bitb := b;\n            s.bitk := k;\n            z.avail_in := n;\n            Inc(z.total_in, ptr2int(p)-ptr2int(z.next_in));\n            z.next_in := p;\n            s.write := q;\n            inflate_blocks := inflate_flush(s,z,r);\n            exit;\n          end;\n          Dec(n);\n          b := b or (uLong(p^) shl k);\n          Inc(p);\n          Inc(k, 8);\n        end;\n\n        t := uInt(b) and 7;\n        s.last := boolean(t and 1);\n        case (t shr 1) of\n          0:                         { stored }\n            begin\n              {$IFDEF DEBUG}\n              if s.last then\n                Tracev('inflate:     stored block (last)')\n              else\n                Tracev('inflate:     stored block');\n              {$ENDIF}\n              {DUMPBITS(3);}\n              b := b shr 3;\n              Dec(k, 3);\n\n              t := k and 7;                  { go to byte boundary }\n              {DUMPBITS(t);}\n              b := b shr t;\n              Dec(k, t);\n\n              s.mode := LENS;                { get length of stored block }\n            end;\n          1:                         { fixed }\n            begin\n              begin\n                {$IFDEF DEBUG}\n                if s.last then\n                  Tracev('inflate:     fixed codes blocks (last)')\n                else\n                  Tracev('inflate:     fixed codes blocks');\n                {$ENDIF}\n                inflate_trees_fixed(bl, bd, tl, td, z);\n                s.sub.decode.codes := inflate_codes_new(bl, bd, tl, td, z);\n                if (s.sub.decode.codes = Z_NULL) then\n                begin\n                  r := Z_MEM_ERROR;\n                  { update pointers and return }\n                  s.bitb := b;\n                  s.bitk := k;\n                  z.avail_in := n;\n                  Inc(z.total_in, ptr2int(p) - ptr2int(z.next_in));\n                  z.next_in := p;\n                  s.write := q;\n                  inflate_blocks := inflate_flush(s,z,r);\n                  exit;\n                end;\n              end;\n              {DUMPBITS(3);}\n              b := b shr 3;\n              Dec(k, 3);\n\n              s.mode := CODES;\n            end;\n          2:                         { dynamic }\n            begin\n              {$IFDEF DEBUG}\n              if s.last then\n                Tracev('inflate:     dynamic codes block (last)')\n              else\n                Tracev('inflate:     dynamic codes block');\n              {$ENDIF}                \n              {DUMPBITS(3);}\n              b := b shr 3;\n              Dec(k, 3);\n\n              s.mode := TABLE;\n            end;\n          3:\n            begin                   { illegal }\n              {DUMPBITS(3);}\n              b := b shr 3;\n              Dec(k, 3);\n\n              s.mode := BLKBAD;\n              z.msg := 'invalid block type';\n              r := Z_DATA_ERROR;\n              { update pointers and return }\n              s.bitb := b;\n              s.bitk := k;\n              z.avail_in := n;\n              Inc(z.total_in, ptr2int(p) - ptr2int(z.next_in));\n              z.next_in := p;\n              s.write := q;\n              inflate_blocks := inflate_flush(s,z,r);\n              exit;\n            end;\n        end;\n      end;\n    LENS:\n      begin\n        {NEEDBITS(32);}\n        while (k < 32) do\n        begin\n          {NEEDBYTE;}\n          if (n <> 0) then\n            r :=Z_OK\n          else\n          begin\n            {UPDATE}\n            s.bitb := b;\n            s.bitk := k;\n            z.avail_in := n;\n            Inc(z.total_in, ptr2int(p)-ptr2int(z.next_in));\n            z.next_in := p;\n            s.write := q;\n            inflate_blocks := inflate_flush(s,z,r);\n            exit;\n          end;\n          Dec(n);\n          b := b or (uLong(p^) shl k);\n          Inc(p);\n          Inc(k, 8);\n        end;\n\n        if (((not b) shr 16) and $ffff) <> (b and $ffff) then\n        begin\n          s.mode := BLKBAD;\n          z.msg := 'invalid stored block lengths';\n          r := Z_DATA_ERROR;\n          { update pointers and return }\n          s.bitb := b;\n          s.bitk := k;\n          z.avail_in := n;\n          Inc(z.total_in, ptr2int(p) - ptr2int(z.next_in));\n          z.next_in := p;\n          s.write := q;\n          inflate_blocks := inflate_flush(s,z,r);\n          exit;\n        end;\n        s.sub.left := uInt(b) and $ffff;\n        k := 0;\n        b := 0;                      { dump bits }\n        {$IFDEF DEBUG}\n        Tracev('inflate:       stored length '+IntToStr(s.sub.left));\n        {$ENDIF}\n        if s.sub.left <> 0 then\n          s.mode := STORED\n        else\n          if s.last then\n            s.mode := DRY\n          else\n            s.mode := ZTYPE;\n      end;\n    STORED:\n      begin\n        if (n = 0) then\n        begin\n          { update pointers and return }\n          s.bitb := b;\n          s.bitk := k;\n          z.avail_in := n;\n          Inc(z.total_in, ptr2int(p) - ptr2int(z.next_in));\n          z.next_in := p;\n          s.write := q;\n          inflate_blocks := inflate_flush(s,z,r);\n          exit;\n        end;\n        {NEEDOUT}\n        if (m = 0) then\n        begin\n          {WRAP}\n          if (q = s.zend) and (s.read <> s.window) then\n          begin\n            q := s.window;\n            if ptr2int(q) < ptr2int(s.read) then\n              m := uInt(ptr2int(s.read)-ptr2int(q)-1)\n            else\n              m := uInt(ptr2int(s.zend)-ptr2int(q));\n          end;\n\n          if (m = 0) then\n          begin\n            {FLUSH}\n            s.write := q;\n            r := inflate_flush(s,z,r);\n            q := s.write;\n            if ptr2int(q) < ptr2int(s.read) then\n              m := uInt(ptr2int(s.read)-ptr2int(q)-1)\n            else\n              m := uInt(ptr2int(s.zend)-ptr2int(q));\n\n            {WRAP}\n            if (q = s.zend) and (s.read <> s.window) then\n            begin\n              q := s.window;\n              if ptr2int(q) < ptr2int(s.read) then\n                m := uInt(ptr2int(s.read)-ptr2int(q)-1)\n              else\n                m := uInt(ptr2int(s.zend)-ptr2int(q));\n            end;\n\n            if (m = 0) then\n            begin\n              {UPDATE}\n              s.bitb := b;\n              s.bitk := k;\n              z.avail_in := n;\n              Inc(z.total_in, ptr2int(p)-ptr2int(z.next_in));\n              z.next_in := p;\n              s.write := q;\n              inflate_blocks := inflate_flush(s,z,r);\n              exit;\n            end;\n          end;\n        end;\n        r := Z_OK;\n\n        t := s.sub.left;\n        if (t > n) then\n          t := n;\n        if (t > m) then\n          t := m;\n        zmemcpy(q, p, t);\n        Inc(p, t);  Dec(n, t);\n        Inc(q, t);  Dec(m, t);\n        Dec(s.sub.left, t);\n        if (s.sub.left = 0) then\n        begin\n          {$IFDEF DEBUG}\n          if (ptr2int(q) >= ptr2int(s.read)) then\n            Tracev('inflate:       stored end '+\n                IntToStr(z.total_out + ptr2int(q) - ptr2int(s.read)) + ' total out')\n          else\n            Tracev('inflate:       stored end '+\n                    IntToStr(z.total_out + ptr2int(s.zend) - ptr2int(s.read) +\n                    ptr2int(q) - ptr2int(s.window)) +  ' total out');\n          {$ENDIF}\n          if s.last then\n            s.mode := DRY\n          else\n            s.mode := ZTYPE;\n        end;\n      end;\n    TABLE:\n      begin\n        {NEEDBITS(14);}\n        while (k < 14) do\n        begin\n          {NEEDBYTE;}\n          if (n <> 0) then\n            r :=Z_OK\n          else\n          begin\n            {UPDATE}\n            s.bitb := b;\n            s.bitk := k;\n            z.avail_in := n;\n            Inc(z.total_in, ptr2int(p)-ptr2int(z.next_in));\n            z.next_in := p;\n            s.write := q;\n            inflate_blocks := inflate_flush(s,z,r);\n            exit;\n          end;\n          Dec(n);\n          b := b or (uLong(p^) shl k);\n          Inc(p);\n          Inc(k, 8);\n        end;\n\n        t := uInt(b) and $3fff;\n        s.sub.trees.table := t;\n  {$ifndef PKZIP_BUG_WORKAROUND}\n        if ((t and $1f) > 29) or (((t shr 5) and $1f) > 29) then\n        begin\n          s.mode := BLKBAD;\n          z.msg := 'too many length or distance symbols';\n          r := Z_DATA_ERROR;\n          { update pointers and return }\n          s.bitb := b;\n          s.bitk := k;\n          z.avail_in := n;\n          Inc(z.total_in, ptr2int(p) - ptr2int(z.next_in));\n          z.next_in := p;\n          s.write := q;\n          inflate_blocks := inflate_flush(s,z,r);\n          exit;\n        end;\n  {$endif}\n        t := 258 + (t and $1f) + ((t shr 5) and $1f);\n        s.sub.trees.blens := puIntArray( ZALLOC(z, t, sizeof(uInt)) );\n        if (s.sub.trees.blens = Z_NULL) then\n        begin\n          r := Z_MEM_ERROR;\n          { update pointers and return }\n          s.bitb := b;\n          s.bitk := k;\n          z.avail_in := n;\n          Inc(z.total_in, ptr2int(p) - ptr2int(z.next_in));\n          z.next_in := p;\n          s.write := q;\n          inflate_blocks := inflate_flush(s,z,r);\n          exit;\n        end;\n        {DUMPBITS(14);}\n        b := b shr 14;\n        Dec(k, 14);\n\n        s.sub.trees.index := 0;\n        {$IFDEF DEBUG}\n        Tracev('inflate:       table sizes ok');\n        {$ENDIF}\n        s.mode := BTREE;\n        { fall trough case is handled by the while }\n        { try GOTO for speed - Nomssi }\n        goto start_btree;\n      end;\n    BTREE:\n      begin\n        start_btree:\n        while (s.sub.trees.index < 4 + (s.sub.trees.table shr 10)) do\n        begin\n          {NEEDBITS(3);}\n          while (k < 3) do\n          begin\n            {NEEDBYTE;}\n            if (n <> 0) then\n              r :=Z_OK\n            else\n            begin\n              {UPDATE}\n              s.bitb := b;\n              s.bitk := k;\n              z.avail_in := n;\n              Inc(z.total_in, ptr2int(p)-ptr2int(z.next_in));\n              z.next_in := p;\n              s.write := q;\n              inflate_blocks := inflate_flush(s,z,r);\n              exit;\n            end;\n            Dec(n);\n            b := b or (uLong(p^) shl k);\n            Inc(p);\n            Inc(k, 8);\n          end;\n\n          s.sub.trees.blens^[border[s.sub.trees.index]] := uInt(b) and 7;\n          Inc(s.sub.trees.index);\n          {DUMPBITS(3);}\n          b := b shr 3;\n          Dec(k, 3);\n        end;\n        while (s.sub.trees.index < 19) do\n        begin\n          s.sub.trees.blens^[border[s.sub.trees.index]] := 0;\n          Inc(s.sub.trees.index);\n        end;\n        s.sub.trees.bb := 7;\n        t := inflate_trees_bits(s.sub.trees.blens^, s.sub.trees.bb,\n                                s.sub.trees.tb, s.hufts^, z);\n        if (t <> Z_OK) then\n        begin\n          ZFREE(z, s.sub.trees.blens);\n          r := t;\n          if (r = Z_DATA_ERROR) then\n            s.mode := BLKBAD;\n          { update pointers and return }\n          s.bitb := b;\n          s.bitk := k;\n          z.avail_in := n;\n          Inc(z.total_in, ptr2int(p) - ptr2int(z.next_in));\n          z.next_in := p;\n          s.write := q;\n          inflate_blocks := inflate_flush(s,z,r);\n          exit;\n        end;\n        s.sub.trees.index := 0;\n        {$IFDEF DEBUG}\n        Tracev('inflate:       bits tree ok');\n        {$ENDIF}\n        s.mode := DTREE;\n        { fall through again }\n        goto start_dtree;\n      end;\n    DTREE:\n      begin\n        start_dtree:\n        while TRUE do\n        begin\n          t := s.sub.trees.table;\n          if not (s.sub.trees.index < 258 +\n                                     (t and $1f) + ((t shr 5) and $1f)) then\n            break;\n          t := s.sub.trees.bb;\n          {NEEDBITS(t);}\n          while (k < t) do\n          begin\n            {NEEDBYTE;}\n            if (n <> 0) then\n              r :=Z_OK\n            else\n            begin\n              {UPDATE}\n              s.bitb := b;\n              s.bitk := k;\n              z.avail_in := n;\n              Inc(z.total_in, ptr2int(p)-ptr2int(z.next_in));\n              z.next_in := p;\n              s.write := q;\n              inflate_blocks := inflate_flush(s,z,r);\n              exit;\n            end;\n            Dec(n);\n            b := b or (uLong(p^) shl k);\n            Inc(p);\n            Inc(k, 8);\n          end;\n\n          h := s.sub.trees.tb;\n          Inc(h, uInt(b) and inflate_mask[t]);\n          t := h^.Bits;\n          c := h^.Base;\n\n          if (c < 16) then\n          begin\n            {DUMPBITS(t);}\n            b := b shr t;\n            Dec(k, t);\n\n            s.sub.trees.blens^[s.sub.trees.index] := c;\n            Inc(s.sub.trees.index);\n          end\n          else { c = 16..18 }\n          begin\n            if c = 18 then\n            begin\n              i := 7;\n              j := 11;\n            end\n            else\n            begin\n              i := c - 14;\n              j := 3;\n            end;\n            {NEEDBITS(t + i);}\n            while (k < t + i) do\n            begin\n              {NEEDBYTE;}\n              if (n <> 0) then\n                r :=Z_OK\n              else\n              begin\n                {UPDATE}\n                s.bitb := b;\n                s.bitk := k;\n                z.avail_in := n;\n                Inc(z.total_in, ptr2int(p)-ptr2int(z.next_in));\n                z.next_in := p;\n                s.write := q;\n                inflate_blocks := inflate_flush(s,z,r);\n                exit;\n              end;\n              Dec(n);\n              b := b or (uLong(p^) shl k);\n              Inc(p);\n              Inc(k, 8);\n            end;\n\n            {DUMPBITS(t);}\n            b := b shr t;\n            Dec(k, t);\n\n            Inc(j, uInt(b) and inflate_mask[i]);\n            {DUMPBITS(i);}\n            b := b shr i;\n            Dec(k, i);\n\n            i := s.sub.trees.index;\n            t := s.sub.trees.table;\n            if (i + j > 258 + (t and $1f) + ((t shr 5) and $1f)) or\n               ((c = 16) and (i < 1)) then\n            begin\n              ZFREE(z, s.sub.trees.blens);\n              s.mode := BLKBAD;\n              z.msg := 'invalid bit length repeat';\n              r := Z_DATA_ERROR;\n              { update pointers and return }\n              s.bitb := b;\n              s.bitk := k;\n              z.avail_in := n;\n              Inc(z.total_in, ptr2int(p) - ptr2int(z.next_in));\n              z.next_in := p;\n              s.write := q;\n              inflate_blocks := inflate_flush(s,z,r);\n              exit;\n            end;\n            if c = 16 then\n              c := s.sub.trees.blens^[i - 1]\n            else\n              c := 0;\n            repeat\n              s.sub.trees.blens^[i] := c;\n              Inc(i);\n              Dec(j);\n            until (j=0);\n            s.sub.trees.index := i;\n          end;\n        end; { while }\n        s.sub.trees.tb := Z_NULL;\n        begin\n          bl := 9;         { must be <= 9 for lookahead assumptions }\n          bd := 6;         { must be <= 9 for lookahead assumptions }\n          t := s.sub.trees.table;\n          t := inflate_trees_dynamic(257 + (t and $1f),\n                  1 + ((t shr 5) and $1f),\n                  s.sub.trees.blens^, bl, bd, tl, td, s.hufts^, z);\n          ZFREE(z, s.sub.trees.blens);\n          if (t <> Z_OK) then\n          begin\n            if (t = uInt(Z_DATA_ERROR)) then\n              s.mode := BLKBAD;\n            r := t;\n            { update pointers and return }\n            s.bitb := b;\n            s.bitk := k;\n            z.avail_in := n;\n            Inc(z.total_in, ptr2int(p) - ptr2int(z.next_in));\n            z.next_in := p;\n            s.write := q;\n            inflate_blocks := inflate_flush(s,z,r);\n            exit;\n          end;\n          {$IFDEF DEBUG}\n          Tracev('inflate:       trees ok');\n          {$ENDIF}          \n          { c renamed to cs }\n          cs := inflate_codes_new(bl, bd, tl, td, z);\n          if (cs = Z_NULL) then\n          begin\n            r := Z_MEM_ERROR;\n            { update pointers and return }\n            s.bitb := b;\n            s.bitk := k;\n            z.avail_in := n;\n            Inc(z.total_in, ptr2int(p) - ptr2int(z.next_in));\n            z.next_in := p;\n            s.write := q;\n            inflate_blocks := inflate_flush(s,z,r);\n            exit;\n          end;\n          s.sub.decode.codes := cs;\n        end;\n        s.mode := CODES;\n        { yet another falltrough }\n        goto start_codes;\n      end;\n    CODES:\n      begin\n        start_codes:\n        { update pointers }\n        s.bitb := b;\n        s.bitk := k;\n        z.avail_in := n;\n        Inc(z.total_in, ptr2int(p) - ptr2int(z.next_in));\n        z.next_in := p;\n        s.write := q;\n\n        r := inflate_codes(s, z, r);\n        if (r <> Z_STREAM_END) then\n        begin\n          inflate_blocks := inflate_flush(s, z, r);\n          exit;\n        end;\n        r := Z_OK;\n        inflate_codes_free(s.sub.decode.codes, z);\n        { load local pointers }\n        p := z.next_in;\n        n := z.avail_in;\n        b := s.bitb;\n        k := s.bitk;\n        q := s.write;\n        if ptr2int(q) < ptr2int(s.read) then\n          m := uInt(ptr2int(s.read)-ptr2int(q)-1)\n        else\n          m := uInt(ptr2int(s.zend)-ptr2int(q));\n        {$IFDEF DEBUG}\n        if (ptr2int(q) >= ptr2int(s.read)) then\n          Tracev('inflate:       codes end '+\n              IntToStr(z.total_out + ptr2int(q) - ptr2int(s.read)) + ' total out')\n        else\n          Tracev('inflate:       codes end '+\n                  IntToStr(z.total_out + ptr2int(s.zend) - ptr2int(s.read) +\n                  ptr2int(q) - ptr2int(s.window)) +  ' total out');\n        {$ENDIF}\n        if (not s.last) then\n        begin\n          s.mode := ZTYPE;\n          continue; { break for switch statement in C-code }\n        end;\n        {$ifndef patch112}\n        if (k > 7) then           { return unused byte, if any }\n        begin\n          {$IFDEF DEBUG}\n          Assert(k < 16, 'inflate_codes grabbed too many bytes');\n          {$ENDIF}\n          Dec(k, 8);\n          Inc(n);\n          Dec(p);                    { can always return one }\n        end;\n        {$endif}\n        s.mode := DRY;\n        { another falltrough }\n        goto start_dry;\n      end;\n    DRY:\n      begin\n        start_dry:\n        {FLUSH}\n        s.write := q;\n        r := inflate_flush(s,z,r);\n        q := s.write;\n\n        { not needed anymore, we are done:\n        if ptr2int(q) < ptr2int(s.read) then\n          m := uInt(ptr2int(s.read)-ptr2int(q)-1)\n        else\n          m := uInt(ptr2int(s.zend)-ptr2int(q));\n        }\n\n        if (s.read <> s.write) then\n        begin\n          { update pointers and return }\n          s.bitb := b;\n          s.bitk := k;\n          z.avail_in := n;\n          Inc(z.total_in, ptr2int(p) - ptr2int(z.next_in));\n          z.next_in := p;\n          s.write := q;\n          inflate_blocks := inflate_flush(s,z,r);\n          exit;\n        end;\n        s.mode := BLKDONE;\n        goto start_blkdone;\n      end;\n    BLKDONE:\n      begin\n        start_blkdone:\n        r := Z_STREAM_END;\n        { update pointers and return }\n        s.bitb := b;\n        s.bitk := k;\n        z.avail_in := n;\n        Inc(z.total_in, ptr2int(p) - ptr2int(z.next_in));\n        z.next_in := p;\n        s.write := q;\n        inflate_blocks := inflate_flush(s,z,r);\n        exit;\n      end;\n    BLKBAD:\n      begin\n        r := Z_DATA_ERROR;\n        { update pointers and return }\n        s.bitb := b;\n        s.bitk := k;\n        z.avail_in := n;\n        Inc(z.total_in, ptr2int(p) - ptr2int(z.next_in));\n        z.next_in := p;\n        s.write := q;\n        inflate_blocks := inflate_flush(s,z,r);\n        exit;\n      end;\n    else\n    begin\n      r := Z_STREAM_ERROR;\n      { update pointers and return }\n      s.bitb := b;\n      s.bitk := k;\n      z.avail_in := n;\n      Inc(z.total_in, ptr2int(p) - ptr2int(z.next_in));\n      z.next_in := p;\n      s.write := q;\n      inflate_blocks := inflate_flush(s,z,r);\n      exit;\n    end;\n  end; { Case s.mode of }\n\nend;\n\n\nfunction inflate_blocks_free(s : pInflate_blocks_state;\n                             var z : z_stream) : int;\nbegin\n  inflate_blocks_reset(s^, z, Z_NULL);\n  ZFREE(z, s^.window);\n  ZFREE(z, s^.hufts);\n  ZFREE(z, s);\n  {$IFDEF DEBUG}\n  Trace('inflate:   blocks freed');\n  {$ENDIF}  \n  inflate_blocks_free := Z_OK;\nend;\n\n\nprocedure inflate_set_dictionary(var s : inflate_blocks_state;\n                                 const d : array of byte; { dictionary }\n                                 n : uInt);         { dictionary length }\nbegin\n  zmemcpy(s.window, pBytef(@d), n);\n  s.write := s.window;\n  Inc(s.write, n);\n  s.read := s.write;\nend;\n\n\n{ Returns true if inflate is currently at the end of a block generated\n  by Z_SYNC_FLUSH or Z_FULL_FLUSH.\n  IN assertion: s <> Z_NULL }\n\nfunction inflate_blocks_sync_point(var s : inflate_blocks_state) : int;\nbegin\n  inflate_blocks_sync_point := int(s.mode = LENS);\nend;\n\nend.\n"
  },
  {
    "path": "lib/Imaging/ZLib/iminfcodes.pas",
    "content": "Unit iminfcodes;\n\n{ infcodes.c -- process literals and length/distance pairs\n  Copyright (C) 1995-1998 Mark Adler\n\n  Pascal tranlastion\n  Copyright (C) 1998 by Jacques Nomssi Nzali\n  For conditions of distribution and use, see copyright notice in readme.txt\n}\n\ninterface\n\n{$I imzconf.inc}\n\nuses\n  {$IFDEF DEBUG}\n  SysUtils, strutils,\n  {$ENDIF}\n  imzutil, impaszlib;\n\nfunction inflate_codes_new (bl : uInt;\n                            bd : uInt;\n                            tl : pInflate_huft;\n                            td : pInflate_huft;\n                            var z : z_stream): pInflate_codes_state;\n\nfunction inflate_codes(var s : inflate_blocks_state;\n                       var z : z_stream;\n                       r : int) : int;\n\nprocedure inflate_codes_free(c : pInflate_codes_state;\n                             var z : z_stream);\n\nimplementation\n\nuses\n  iminfutil, iminffast;\n\n\nfunction inflate_codes_new (bl : uInt;\n                            bd : uInt;\n                            tl : pInflate_huft;\n                            td : pInflate_huft;\n                            var z : z_stream): pInflate_codes_state;\nvar\n c : pInflate_codes_state;\nbegin\n  c := pInflate_codes_state( ZALLOC(z,1,sizeof(inflate_codes_state)) );\n  if (c <> Z_NULL) then\n  begin\n    c^.mode := START;\n    c^.lbits := Byte(bl);\n    c^.dbits := Byte(bd);\n    c^.ltree := tl;\n    c^.dtree := td;\n    {$IFDEF DEBUG}\n    Tracev('inflate:       codes new');\n    {$ENDIF}\n  end;\n  inflate_codes_new := c;\nend;\n\n\nfunction inflate_codes(var s : inflate_blocks_state;\n                       var z : z_stream;\n                       r : int) : int;\nvar\n  j : uInt;               { temporary storage }\n  t : pInflate_huft;      { temporary pointer }\n  e : uInt;               { extra bits or operation }\n  b : uLong;              { bit buffer }\n  k : uInt;               { bits in bit buffer }\n  p : pBytef;             { input data pointer }\n  n : uInt;               { bytes available there }\n  q : pBytef;             { output window write pointer }\n  m : uInt;               { bytes to end of window or read pointer }\n  f : pBytef;             { pointer to copy strings from }\nvar\n  c : pInflate_codes_state;\nbegin\n  c := s.sub.decode.codes;  { codes state }\n\n  { copy input/output information to locals }\n  p := z.next_in;\n  n := z.avail_in;\n  b := s.bitb;\n  k := s.bitk;\n  q := s.write;\n  if ptr2int(q) < ptr2int(s.read) then\n    m := uInt(ptr2int(s.read)-ptr2int(q)-1)\n  else\n    m := uInt(ptr2int(s.zend)-ptr2int(q));\n\n  { process input and output based on current state }\n  while True do\n  case (c^.mode) of\n    { waiting for \"i:\"=input, \"o:\"=output, \"x:\"=nothing }\n  START:         { x: set up for LEN }\n    begin\n{$ifndef SLOW}\n      if (m >= 258) and (n >= 10) then\n      begin\n        {UPDATE}\n        s.bitb := b;\n        s.bitk := k;\n        z.avail_in := n;\n        Inc(z.total_in, ptr2int(p)-ptr2int(z.next_in));\n        z.next_in := p;\n        s.write := q;\n\n        r := inflate_fast(c^.lbits, c^.dbits, c^.ltree, c^.dtree, s, z);\n        {LOAD}\n        p := z.next_in;\n        n := z.avail_in;\n        b := s.bitb;\n        k := s.bitk;\n        q := s.write;\n        if ptr2int(q) < ptr2int(s.read) then\n          m := uInt(ptr2int(s.read)-ptr2int(q)-1)\n        else\n          m := uInt(ptr2int(s.zend)-ptr2int(q));\n\n        if (r <> Z_OK) then\n        begin\n          if (r = Z_STREAM_END) then\n            c^.mode := WASH\n          else\n            c^.mode := BADCODE;\n          continue;    { break for switch-statement in C }\n        end;\n      end;\n{$endif} { not SLOW }\n      c^.sub.code.need := c^.lbits;\n      c^.sub.code.tree := c^.ltree;\n      c^.mode := LEN;  { falltrough }\n    end;\n  LEN:           { i: get length/literal/eob next }\n    begin\n      j := c^.sub.code.need;\n      {NEEDBITS(j);}\n      while (k < j) do\n      begin\n        {NEEDBYTE;}\n        if (n <> 0) then\n          r :=Z_OK\n        else\n        begin\n          {UPDATE}\n          s.bitb := b;\n          s.bitk := k;\n          z.avail_in := n;\n          Inc(z.total_in, ptr2int(p)-ptr2int(z.next_in));\n          z.next_in := p;\n          s.write := q;\n          inflate_codes := inflate_flush(s,z,r);\n          exit;\n        end;\n        Dec(n);\n        b := b or (uLong(p^) shl k);\n        Inc(p);\n        Inc(k, 8);\n      end;\n      t := c^.sub.code.tree;\n      Inc(t, uInt(b) and inflate_mask[j]);\n      {DUMPBITS(t^.bits);}\n      b := b shr t^.bits;\n      Dec(k, t^.bits);\n\n      e := uInt(t^.exop);\n      if (e = 0) then            { literal }\n      begin\n        c^.sub.lit := t^.base;\n       {$IFDEF DEBUG}\n        if (t^.base >= $20) and (t^.base < $7f) then\n          Tracevv('inflate:         literal '+AnsiChar(t^.base))\n        else\n          Tracevv('inflate:         literal '+IntToStr(t^.base));\n        {$ENDIF}          \n        c^.mode := LIT;\n        continue;  { break switch statement }\n      end;\n      if (e and 16 <> 0) then            { length }\n      begin\n        c^.sub.copy.get := e and 15;\n        c^.len := t^.base;\n        c^.mode := LENEXT;\n        continue;         { break C-switch statement }\n      end;\n      if (e and 64 = 0) then             { next table }\n      begin\n        c^.sub.code.need := e;\n        c^.sub.code.tree := @huft_ptr(t)^[t^.base];\n        continue;         { break C-switch statement }\n      end;\n      if (e and 32 <> 0) then            { end of block }\n      begin\n        {$IFDEF DEBUG}\n        Tracevv('inflate:         end of block');\n        {$ENDIF}        \n        c^.mode := WASH;\n        continue;         { break C-switch statement }\n      end;\n      c^.mode := BADCODE;        { invalid code }\n      z.msg := 'invalid literal/length code';\n      r := Z_DATA_ERROR;\n      {UPDATE}\n      s.bitb := b;\n      s.bitk := k;\n      z.avail_in := n;\n      Inc(z.total_in, ptr2int(p)-ptr2int(z.next_in));\n      z.next_in := p;\n      s.write := q;\n      inflate_codes := inflate_flush(s,z,r);\n      exit;\n    end;\n  LENEXT:        { i: getting length extra (have base) }\n    begin\n      j := c^.sub.copy.get;\n      {NEEDBITS(j);}\n      while (k < j) do\n      begin\n        {NEEDBYTE;}\n        if (n <> 0) then\n          r :=Z_OK\n        else\n        begin\n          {UPDATE}\n          s.bitb := b;\n          s.bitk := k;\n          z.avail_in := n;\n          Inc(z.total_in, ptr2int(p)-ptr2int(z.next_in));\n          z.next_in := p;\n          s.write := q;\n          inflate_codes := inflate_flush(s,z,r);\n          exit;\n        end;\n        Dec(n);\n        b := b or (uLong(p^) shl k);\n        Inc(p);\n        Inc(k, 8);\n      end;\n      Inc(c^.len, uInt(b and inflate_mask[j]));\n      {DUMPBITS(j);}\n      b := b shr j;\n      Dec(k, j);\n\n      c^.sub.code.need := c^.dbits;\n      c^.sub.code.tree := c^.dtree;\n      {$IFDEF DEBUG}\n      Tracevv('inflate:         length '+IntToStr(c^.len));\n      {$ENDIF}\n      c^.mode := DIST;\n      { falltrough }\n    end;\n  DIST:          { i: get distance next }\n    begin\n      j := c^.sub.code.need;\n      {NEEDBITS(j);}\n      while (k < j) do\n      begin\n        {NEEDBYTE;}\n        if (n <> 0) then\n          r :=Z_OK\n        else\n        begin\n          {UPDATE}\n          s.bitb := b;\n          s.bitk := k;\n          z.avail_in := n;\n          Inc(z.total_in, ptr2int(p)-ptr2int(z.next_in));\n          z.next_in := p;\n          s.write := q;\n          inflate_codes := inflate_flush(s,z,r);\n          exit;\n        end;\n        Dec(n);\n        b := b or (uLong(p^) shl k);\n        Inc(p);\n        Inc(k, 8);\n      end;\n      t := @huft_ptr(c^.sub.code.tree)^[uInt(b) and inflate_mask[j]];\n      {DUMPBITS(t^.bits);}\n      b := b shr t^.bits;\n      Dec(k, t^.bits);\n\n      e := uInt(t^.exop);\n      if (e and 16 <> 0) then            { distance }\n      begin\n        c^.sub.copy.get := e and 15;\n        c^.sub.copy.dist := t^.base;\n        c^.mode := DISTEXT;\n        continue;     { break C-switch statement }\n      end;\n      if (e and 64 = 0) then     { next table }\n      begin\n        c^.sub.code.need := e;\n        c^.sub.code.tree := @huft_ptr(t)^[t^.base];\n        continue;     { break C-switch statement }\n      end;\n      c^.mode := BADCODE;        { invalid code }\n      z.msg := 'invalid distance code';\n      r := Z_DATA_ERROR;\n      {UPDATE}\n      s.bitb := b;\n      s.bitk := k;\n      z.avail_in := n;\n      Inc(z.total_in, ptr2int(p)-ptr2int(z.next_in));\n      z.next_in := p;\n      s.write := q;\n      inflate_codes := inflate_flush(s,z,r);\n      exit;\n    end;\n  DISTEXT:       { i: getting distance extra }\n    begin\n      j := c^.sub.copy.get;\n      {NEEDBITS(j);}\n      while (k < j) do\n      begin\n        {NEEDBYTE;}\n        if (n <> 0) then\n          r :=Z_OK\n        else\n        begin\n          {UPDATE}\n          s.bitb := b;\n          s.bitk := k;\n          z.avail_in := n;\n          Inc(z.total_in, ptr2int(p)-ptr2int(z.next_in));\n          z.next_in := p;\n          s.write := q;\n          inflate_codes := inflate_flush(s,z,r);\n          exit;\n        end;\n        Dec(n);\n        b := b or (uLong(p^) shl k);\n        Inc(p);\n        Inc(k, 8);\n      end;\n      Inc(c^.sub.copy.dist, uInt(b) and inflate_mask[j]);\n      {DUMPBITS(j);}\n      b := b shr j;\n      Dec(k, j);\n      {$IFDEF DEBUG}\n      Tracevv('inflate:         distance '+ IntToStr(c^.sub.copy.dist));\n      {$ENDIF}\n      c^.mode := COPY;\n      { falltrough }\n    end;\n  COPY:          { o: copying bytes in window, waiting for space }\n    begin\n      f := q;\n      Dec(f, c^.sub.copy.dist);\n      if (uInt(ptr2int(q) - ptr2int(s.window)) < c^.sub.copy.dist) then\n      begin\n        f := s.zend;\n        Dec(f, c^.sub.copy.dist - uInt(ptr2int(q) - ptr2int(s.window)));\n      end;\n\n      while (c^.len <> 0) do\n      begin\n        {NEEDOUT}\n        if (m = 0) then\n        begin\n          {WRAP}\n          if (q = s.zend) and (s.read <> s.window) then\n          begin\n            q := s.window;\n            if ptr2int(q) < ptr2int(s.read) then\n              m := uInt(ptr2int(s.read)-ptr2int(q)-1)\n            else\n              m := uInt(ptr2int(s.zend)-ptr2int(q));\n          end;\n\n          if (m = 0) then\n          begin\n            {FLUSH}\n            s.write := q;\n            r := inflate_flush(s,z,r);\n            q := s.write;\n            if ptr2int(q) < ptr2int(s.read) then\n              m := uInt(ptr2int(s.read)-ptr2int(q)-1)\n            else\n              m := uInt(ptr2int(s.zend)-ptr2int(q));\n\n            {WRAP}\n            if (q = s.zend) and (s.read <> s.window) then\n            begin\n              q := s.window;\n              if ptr2int(q) < ptr2int(s.read) then\n                m := uInt(ptr2int(s.read)-ptr2int(q)-1)\n              else\n                m := uInt(ptr2int(s.zend)-ptr2int(q));\n            end;\n\n            if (m = 0) then\n            begin\n              {UPDATE}\n              s.bitb := b;\n              s.bitk := k;\n              z.avail_in := n;\n              Inc(z.total_in, ptr2int(p)-ptr2int(z.next_in));\n              z.next_in := p;\n              s.write := q;\n              inflate_codes := inflate_flush(s,z,r);\n              exit;\n            end;\n          end;\n        end;\n        r := Z_OK;\n\n        {OUTBYTE( *f++)}\n        q^ := f^;\n        Inc(q);\n        Inc(f);\n        Dec(m);\n\n        if (f = s.zend) then\n          f := s.window;\n        Dec(c^.len);\n      end;\n      c^.mode := START;\n      { C-switch break; not needed }\n    end;\n  LIT:           { o: got literal, waiting for output space }\n    begin\n      {NEEDOUT}\n      if (m = 0) then\n      begin\n        {WRAP}\n        if (q = s.zend) and (s.read <> s.window) then\n        begin\n          q := s.window;\n          if ptr2int(q) < ptr2int(s.read) then\n            m := uInt(ptr2int(s.read)-ptr2int(q)-1)\n          else\n            m := uInt(ptr2int(s.zend)-ptr2int(q));\n        end;\n\n        if (m = 0) then\n        begin\n          {FLUSH}\n          s.write := q;\n          r := inflate_flush(s,z,r);\n          q := s.write;\n          if ptr2int(q) < ptr2int(s.read) then\n            m := uInt(ptr2int(s.read)-ptr2int(q)-1)\n          else\n            m := uInt(ptr2int(s.zend)-ptr2int(q));\n\n          {WRAP}\n          if (q = s.zend) and (s.read <> s.window) then\n          begin\n            q := s.window;\n            if ptr2int(q) < ptr2int(s.read) then\n              m := uInt(ptr2int(s.read)-ptr2int(q)-1)\n            else\n              m := uInt(ptr2int(s.zend)-ptr2int(q));\n          end;\n\n          if (m = 0) then\n          begin\n            {UPDATE}\n            s.bitb := b;\n            s.bitk := k;\n            z.avail_in := n;\n            Inc(z.total_in, ptr2int(p)-ptr2int(z.next_in));\n            z.next_in := p;\n            s.write := q;\n            inflate_codes := inflate_flush(s,z,r);\n            exit;\n          end;\n        end;\n      end;\n      r := Z_OK;\n\n      {OUTBYTE(c^.sub.lit);}\n      q^ := c^.sub.lit;\n      Inc(q);\n      Dec(m);\n\n      c^.mode := START;\n      {break;}\n    end;\n  WASH:          { o: got eob, possibly more output }\n    begin\n      {$ifdef patch112}\n      if (k > 7) then           { return unused byte, if any }\n      begin\n        {$IFDEF DEBUG}\n        Assert(k < 16, 'inflate_codes grabbed too many bytes');\n        {$ENDIF}\n        Dec(k, 8);\n        Inc(n);\n        Dec(p);                    { can always return one }\n      end;\n      {$endif}\n      {FLUSH}\n      s.write := q;\n      r := inflate_flush(s,z,r);\n      q := s.write;\n      if ptr2int(q) < ptr2int(s.read) then\n        m := uInt(ptr2int(s.read)-ptr2int(q)-1)\n      else\n        m := uInt(ptr2int(s.zend)-ptr2int(q));\n\n      if (s.read <> s.write) then\n      begin\n        {UPDATE}\n        s.bitb := b;\n        s.bitk := k;\n        z.avail_in := n;\n        Inc(z.total_in, ptr2int(p)-ptr2int(z.next_in));\n        z.next_in := p;\n        s.write := q;\n        inflate_codes := inflate_flush(s,z,r);\n        exit;\n      end;\n      c^.mode := ZEND;\n      { falltrough }\n    end;\n\n  ZEND:\n    begin\n      r := Z_STREAM_END;\n      {UPDATE}\n      s.bitb := b;\n      s.bitk := k;\n      z.avail_in := n;\n      Inc(z.total_in, ptr2int(p)-ptr2int(z.next_in));\n      z.next_in := p;\n      s.write := q;\n      inflate_codes := inflate_flush(s,z,r);\n      exit;\n    end;\n  BADCODE:       { x: got error }\n    begin\n      r := Z_DATA_ERROR;\n      {UPDATE}\n      s.bitb := b;\n      s.bitk := k;\n      z.avail_in := n;\n      Inc(z.total_in, ptr2int(p)-ptr2int(z.next_in));\n      z.next_in := p;\n      s.write := q;\n      inflate_codes := inflate_flush(s,z,r);\n      exit;\n    end;\n  else\n    begin\n      r := Z_STREAM_ERROR;\n      {UPDATE}\n      s.bitb := b;\n      s.bitk := k;\n      z.avail_in := n;\n      Inc(z.total_in, ptr2int(p)-ptr2int(z.next_in));\n      z.next_in := p;\n      s.write := q;\n      inflate_codes := inflate_flush(s,z,r);\n      exit;\n    end;\n  end;\n{NEED_DUMMY_RETURN - Delphi2+ dumb compilers complain without this }\n  inflate_codes := Z_STREAM_ERROR;\nend;\n\n\nprocedure inflate_codes_free(c : pInflate_codes_state;\n                             var z : z_stream);\nbegin\n  ZFREE(z, c);\n  {$IFDEF DEBUG}  \n  Tracev('inflate:       codes free');\n  {$ENDIF}\nend;\n\nend.\n"
  },
  {
    "path": "lib/Imaging/ZLib/iminffast.pas",
    "content": "Unit iminffast;\n\n{\n  inffast.h and\n  inffast.c -- process literals and length/distance pairs fast\n  Copyright (C) 1995-1998 Mark Adler\n\n  Pascal tranlastion\n  Copyright (C) 1998 by Jacques Nomssi Nzali\n  For conditions of distribution and use, see copyright notice in readme.txt\n}\n\n\ninterface\n\n{$I imzconf.inc}\n\nuses\n  {$ifdef DEBUG}\n  SysUtils, strutils,\n  {$ENDIF}\n  imzutil, impaszlib;\n\nfunction inflate_fast( bl : uInt;\n                       bd : uInt;\n                       tl : pInflate_huft;\n                       td : pInflate_huft;\n                      var s : inflate_blocks_state;\n                      var z : z_stream) : int;\n\n\nimplementation\n\nuses\n  iminfutil;\n\n\n{ Called with number of bytes left to write in window at least 258\n  (the maximum string length) and number of input bytes available\n  at least ten.  The ten bytes are six bytes for the longest length/\n  distance pair plus four bytes for overloading the bit buffer. }\n\nfunction inflate_fast( bl : uInt;\n                       bd : uInt;\n                       tl : pInflate_huft;\n                       td : pInflate_huft;\n                      var s : inflate_blocks_state;\n                      var z : z_stream) : int;\n\nvar\n  t : pInflate_huft;      { temporary pointer }\n  e : uInt;               { extra bits or operation }\n  b : uLong;              { bit buffer }\n  k : uInt;               { bits in bit buffer }\n  p : pBytef;             { input data pointer }\n  n : uInt;               { bytes available there }\n  q : pBytef;             { output window write pointer }\n  m : uInt;               { bytes to end of window or read pointer }\n  ml : uInt;              { mask for literal/length tree }\n  md : uInt;              { mask for distance tree }\n  c : uInt;               { bytes to copy }\n  d : uInt;               { distance back to copy from }\n  r : pBytef;             { copy source pointer }\nbegin\n  { load input, output, bit values (macro LOAD) }\n  p := z.next_in;\n  n := z.avail_in;\n  b := s.bitb;\n  k := s.bitk;\n  q := s.write;\n  if ptr2int(q) < ptr2int(s.read) then\n    m := uInt(ptr2int(s.read)-ptr2int(q)-1)\n  else\n    m := uInt(ptr2int(s.zend)-ptr2int(q));\n\n  { initialize masks }\n  ml := inflate_mask[bl];\n  md := inflate_mask[bd];\n\n  { do until not enough input or output space for fast loop }\n  repeat                      { assume called with (m >= 258) and (n >= 10) }\n    { get literal/length code }\n    {GRABBITS(20);}             { max bits for literal/length code }\n    while (k < 20) do\n    begin\n      Dec(n);\n      b := b or (uLong(p^) shl k);\n      Inc(p);\n      Inc(k, 8);\n    end;\n\n    t := @(huft_ptr(tl)^[uInt(b) and ml]);\n\n    e := t^.exop;\n    if (e = 0) then\n    begin\n      {DUMPBITS(t^.bits);}\n      b := b shr t^.bits;\n      Dec(k, t^.bits);\n     {$IFDEF DEBUG}\n      if (t^.base >= $20) and (t^.base < $7f) then\n        Tracevv('inflate:         * literal '+AnsiChar(t^.base))\n      else\n        Tracevv('inflate:         * literal '+ IntToStr(t^.base));\n      {$ENDIF}\n      q^ := Byte(t^.base);\n      Inc(q);\n      Dec(m);\n      continue;\n    end;\n    repeat\n      {DUMPBITS(t^.bits);}\n      b := b shr t^.bits;\n      Dec(k, t^.bits);\n\n      if (e and 16 <> 0) then\n      begin\n        { get extra bits for length }\n        e := e and 15;\n        c := t^.base + (uInt(b) and inflate_mask[e]);\n        {DUMPBITS(e);}\n        b := b shr e;\n        Dec(k, e);\n        {$IFDEF DEBUG}\n        Tracevv('inflate:         * length ' + IntToStr(c));\n        {$ENDIF}\n        { decode distance base of block to copy }\n        {GRABBITS(15);}           { max bits for distance code }\n        while (k < 15) do\n        begin\n          Dec(n);\n          b := b or (uLong(p^) shl k);\n          Inc(p);\n          Inc(k, 8);\n        end;\n\n        t := @huft_ptr(td)^[uInt(b) and md];\n        e := t^.exop;\n        repeat\n          {DUMPBITS(t^.bits);}\n          b := b shr t^.bits;\n          Dec(k, t^.bits);\n\n          if (e and 16 <> 0) then\n          begin\n            { get extra bits to add to distance base }\n            e := e and 15;\n            {GRABBITS(e);}         { get extra bits (up to 13) }\n            while (k < e) do\n            begin\n              Dec(n);\n              b := b or (uLong(p^) shl k);\n              Inc(p);\n              Inc(k, 8);\n            end;\n\n            d := t^.base + (uInt(b) and inflate_mask[e]);\n            {DUMPBITS(e);}\n            b := b shr e;\n            Dec(k, e);\n\n            {$IFDEF DEBUG}\n            Tracevv('inflate:         * distance '+IntToStr(d));\n            {$ENDIF}\n            { do the copy }\n            Dec(m, c);\n            if (uInt(ptr2int(q) - ptr2int(s.window)) >= d) then     { offset before dest }\n            begin                                  {  just copy }\n              r := q;\n              Dec(r, d);\n              q^ := r^;  Inc(q); Inc(r); Dec(c); { minimum count is three, }\n              q^ := r^;  Inc(q); Inc(r); Dec(c); { so unroll loop a little }\n            end\n            else                        { else offset after destination }\n            begin\n              e := d - uInt(ptr2int(q) - ptr2int(s.window)); { bytes from offset to end }\n              r := s.zend;\n              Dec(r, e);                  { pointer to offset }\n              if (c > e) then             { if source crosses, }\n              begin\n                Dec(c, e);                { copy to end of window }\n                repeat\n                  q^ := r^;\n                  Inc(q);\n                  Inc(r);\n                  Dec(e);\n                until (e=0);\n                r := s.window;           { copy rest from start of window }\n              end;\n            end;\n            repeat                       { copy all or what's left }\n              q^ := r^;\n              Inc(q);\n              Inc(r);\n              Dec(c);\n            until (c = 0);\n            break;\n          end\n          else\n            if (e and 64 = 0) then\n            begin\n              Inc(t, t^.base + (uInt(b) and inflate_mask[e]));\n              e := t^.exop;\n            end\n          else\n          begin\n            z.msg := 'invalid distance code';\n            {UNGRAB}\n            c := z.avail_in-n;\n            if (k shr 3) < c then\n              c := k shr 3;\n            Inc(n, c);\n            Dec(p, c);\n            Dec(k, c shl 3);\n            {UPDATE}\n            s.bitb := b;\n            s.bitk := k;\n            z.avail_in := n;\n            Inc(z.total_in, ptr2int(p)-ptr2int(z.next_in));\n            z.next_in := p;\n            s.write := q;\n\n            inflate_fast := Z_DATA_ERROR;\n            exit;\n          end;\n        until FALSE;\n        break;\n      end;\n      if (e and 64 = 0) then\n      begin\n         {t += t->base;\n          e = (t += ((uInt)b & inflate_mask[e]))->exop;}\n\n        Inc(t, t^.base + (uInt(b) and inflate_mask[e]));\n        e := t^.exop;\n        if (e = 0) then\n        begin\n          {DUMPBITS(t^.bits);}\n          b := b shr t^.bits;\n          Dec(k, t^.bits);\n\n         {$IFDEF DEBUG}\n          if (t^.base >= $20) and (t^.base < $7f) then\n            Tracevv('inflate:         * literal '+AnsiChar(t^.base))\n          else\n            Tracevv('inflate:         * literal '+IntToStr(t^.base));\n          {$ENDIF}            \n          q^ := Byte(t^.base);\n          Inc(q);\n          Dec(m);\n          break;\n        end;\n      end\n      else\n        if (e and 32 <> 0) then\n        begin\n          {$IFDEF DEBUG}\n          Tracevv('inflate:         * end of block');\n          {$ENDIF}\n          {UNGRAB}\n          c := z.avail_in-n;\n          if (k shr 3) < c then\n            c := k shr 3;\n          Inc(n, c);\n          Dec(p, c);\n          Dec(k, c shl 3);\n          {UPDATE}\n          s.bitb := b;\n          s.bitk := k;\n          z.avail_in := n;\n          Inc(z.total_in, ptr2int(p)-ptr2int(z.next_in));\n          z.next_in := p;\n          s.write := q;\n          inflate_fast := Z_STREAM_END;\n          exit;\n        end\n        else\n        begin\n          z.msg := 'invalid literal/length code';\n          {UNGRAB}\n          c := z.avail_in-n;\n          if (k shr 3) < c then\n            c := k shr 3;\n          Inc(n, c);\n          Dec(p, c);\n          Dec(k, c shl 3);\n          {UPDATE}\n          s.bitb := b;\n          s.bitk := k;\n          z.avail_in := n;\n          Inc(z.total_in, ptr2int(p)-ptr2int(z.next_in));\n          z.next_in := p;\n          s.write := q;\n          inflate_fast := Z_DATA_ERROR;\n          exit;\n        end;\n    until FALSE;\n  until (m < 258) or (n < 10);\n\n  { not enough input or output--restore pointers and return }\n  {UNGRAB}\n  c := z.avail_in-n;\n  if (k shr 3) < c then\n    c := k shr 3;\n  Inc(n, c);\n  Dec(p, c);\n  Dec(k, c shl 3);\n  {UPDATE}\n  s.bitb := b;\n  s.bitk := k;\n  z.avail_in := n;\n  Inc(z.total_in, ptr2int(p)-ptr2int(z.next_in));\n  z.next_in := p;\n  s.write := q;\n  inflate_fast := Z_OK;\nend;\n\nend.\n"
  },
  {
    "path": "lib/Imaging/ZLib/iminftrees.pas",
    "content": "Unit iminftrees;\n\n{ inftrees.h -- header to use inftrees.c\n  inftrees.c -- generate Huffman trees for efficient decoding\n  Copyright (C) 1995-1998 Mark Adler\n\n  WARNING: this file should *not* be used by applications. It is\n   part of the implementation of the compression library and is\n   subject to change.\n\n  Pascal tranlastion\n  Copyright (C) 1998 by Jacques Nomssi Nzali\n  For conditions of distribution and use, see copyright notice in readme.txt\n}\n\nInterface\n\n{$I imzconf.inc}\n\nuses\n  imzutil, impaszlib;\n\n\n{ Maximum size of dynamic tree.  The maximum found in a long but non-\n  exhaustive search was 1004 huft structures (850 for length/literals\n  and 154 for distances, the latter actually the result of an\n  exhaustive search).  The actual maximum is not known, but the\n  value below is more than safe. }\nconst\n  MANY = 1440;\n\n\n{$ifdef DEBUG}\nvar\n  inflate_hufts : uInt;\n{$endif}\n\nfunction inflate_trees_bits(\n  var c : array of uIntf;  { 19 code lengths }\n  var bb : uIntf;          { bits tree desired/actual depth }\n  var tb : pinflate_huft;  { bits tree result }\n  var hp : array of Inflate_huft;      { space for trees }\n  var z : z_stream         { for messages }\n    ) : int;\n\nfunction inflate_trees_dynamic(\n    nl : uInt;                    { number of literal/length codes }\n    nd : uInt;                    { number of distance codes }\n    var c : Array of uIntf;           { that many (total) code lengths }\n    var bl : uIntf;               { literal desired/actual bit depth }\n    var bd : uIntf;               { distance desired/actual bit depth }\nvar tl : pInflate_huft;           { literal/length tree result }\nvar td : pInflate_huft;           { distance tree result }\nvar hp : array of Inflate_huft;   { space for trees }\nvar z : z_stream                  { for messages }\n     ) : int;\n\nfunction inflate_trees_fixed (\n    var bl : uInt;                { literal desired/actual bit depth }\n    var bd : uInt;                { distance desired/actual bit depth }\n    var tl : pInflate_huft;       { literal/length tree result }\n    var td : pInflate_huft;       { distance tree result }\n    var z : z_stream              { for memory allocation }\n     ) : int;\n\n\nimplementation\n\nconst\n inflate_copyright = 'inflate 1.1.2 Copyright 1995-1998 Mark Adler';\n\n{\n  If you use the zlib library in a product, an acknowledgment is welcome\n  in the documentation of your product. If for some reason you cannot\n  include such an acknowledgment, I would appreciate that you keep this\n  copyright string in the executable of your product.\n}\n\n\nconst\n{ Tables for deflate from PKZIP's appnote.txt. }\n  cplens : Array [0..30] Of uInt  { Copy lengths for literal codes 257..285 }\n     = (3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31,\n        35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0);\n        { actually lengths - 2; also see note #13 above about 258 }\n\n  invalid_code = 112;\n\n  cplext : Array [0..30] Of uInt  { Extra bits for literal codes 257..285 }\n     = (0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2,\n        3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0, invalid_code, invalid_code);\n\n  cpdist : Array [0..29] Of uInt { Copy offsets for distance codes 0..29 }\n     = (1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193,\n        257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145,\n        8193, 12289, 16385, 24577);\n\n  cpdext : Array [0..29] Of uInt { Extra bits for distance codes }\n     = (0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6,\n        7, 7, 8, 8, 9, 9, 10, 10, 11, 11,\n        12, 12, 13, 13);\n\n{  Huffman code decoding is performed using a multi-level table lookup.\n   The fastest way to decode is to simply build a lookup table whose\n   size is determined by the longest code.  However, the time it takes\n   to build this table can also be a factor if the data being decoded\n   is not very long.  The most common codes are necessarily the\n   shortest codes, so those codes dominate the decoding time, and hence\n   the speed.  The idea is you can have a shorter table that decodes the\n   shorter, more probable codes, and then point to subsidiary tables for\n   the longer codes.  The time it costs to decode the longer codes is\n   then traded against the time it takes to make longer tables.\n\n   This results of this trade are in the variables lbits and dbits\n   below.  lbits is the number of bits the first level table for literal/\n   length codes can decode in one step, and dbits is the same thing for\n   the distance codes.  Subsequent tables are also less than or equal to\n   those sizes.  These values may be adjusted either when all of the\n   codes are shorter than that, in which case the longest code length in\n   bits is used, or when the shortest code is *longer* than the requested\n   table size, in which case the length of the shortest code in bits is\n   used.\n\n   There are two different values for the two tables, since they code a\n   different number of possibilities each.  The literal/length table\n   codes 286 possible values, or in a flat code, a little over eight\n   bits.  The distance table codes 30 possible values, or a little less\n   than five bits, flat.  The optimum values for speed end up being\n   about one bit more than those, so lbits is 8+1 and dbits is 5+1.\n   The optimum values may differ though from machine to machine, and\n   possibly even between compilers.  Your mileage may vary. }\n\n\n{ If BMAX needs to be larger than 16, then h and x[] should be uLong. }\nconst\n  BMAX = 15;         { maximum bit length of any code }\n\n{$DEFINE USE_PTR}\n\nfunction huft_build(\nvar b : array of uIntf;    { code lengths in bits (all assumed <= BMAX) }\n    n : uInt;              { number of codes (assumed <= N_MAX) }\n    s : uInt;              { number of simple-valued codes (0..s-1) }\nconst d : array of uIntf;  { list of base values for non-simple codes }\n{ array of word }\nconst e : array of uIntf;  { list of extra bits for non-simple codes }\n{ array of byte }\n  t : ppInflate_huft;     { result: starting table }\nvar m : uIntf;             { maximum lookup bits, returns actual }\nvar hp : array of inflate_huft;  { space for trees }\nvar hn : uInt;             { hufts used in space }\nvar v : array of uIntf     { working area: values in order of bit length }\n   ) : int;\n{ Given a list of code lengths and a maximum table size, make a set of\n  tables to decode that set of codes.  Return Z_OK on success, Z_BUF_ERROR\n  if the given code set is incomplete (the tables are still built in this\n  case), Z_DATA_ERROR if the input is invalid (an over-subscribed set of\n  lengths), or Z_MEM_ERROR if not enough memory. }\nVar\n  a : uInt;                     { counter for codes of length k }\n  c : Array [0..BMAX] Of uInt;  { bit length count table }\n  f : uInt;                     { i repeats in table every f entries }\n  g : int;                      { maximum code length }\n  h : int;                      { table level }\n  i : uInt;  {register}         { counter, current code }\n  j : uInt;  {register}         { counter }\n  k : Int;   {register}         { number of bits in current code }\n  l : int;\t\t\t{ bits per table (returned in m) }\n  mask : uInt;                  { (1 shl w) - 1, to avoid cc -O bug on HP }\n  p : ^uIntf; {register}        { pointer into c[], b[], or v[] }\n  q : pInflate_huft;            { points to current table }\n  r : inflate_huft;             { table entry for structure assignment }\n  u : Array [0..BMAX-1] Of pInflate_huft; { table stack }\n  w : int;   {register}         { bits before this table = (l*h) }\n  x : Array [0..BMAX] Of uInt;  { bit offsets, then code stack }\n  {$IFDEF USE_PTR}\n  xp : puIntf;                  { pointer into x }\n  {$ELSE}\n  xp : uInt;\n  {$ENDIF}\n  y : int;                      { number of dummy codes added }\n  z : uInt;                     { number of entries in current table }\nBegin\n  { Generate counts for each bit length }\n  FillChar(c,SizeOf(c),0) ;     { clear c[] }\n\n  for i := 0 to n-1 do\n    Inc (c[b[i]]);              { assume all entries <= BMAX }\n\n  If (c[0] = n) Then            { null input--all zero length codes }\n  Begin\n    t^ := pInflate_huft(NIL);\n    m := 0 ;\n    huft_build := Z_OK ;\n    Exit;\n  End ;\n\n  { Find minimum and maximum length, bound [m] by those }\n  l := m;\n  for j:=1 To BMAX do\n    if (c[j] <> 0) then\n      break;\n  k := j ;                      { minimum code length }\n  if (uInt(l) < j) then\n    l := j;\n  for i := BMAX downto 1 do\n    if (c[i] <> 0) then\n      break ;\n  g := i ;                      { maximum code length }\n  if (uInt(l) > i) then\n     l := i;\n  m := l;\n\n  { Adjust last length count to fill out codes, if needed }\n  y := 1 shl j ;\n  while (j < i) do\n  begin\n    Dec(y, c[j]) ;\n    if (y < 0) then\n    begin\n      huft_build := Z_DATA_ERROR;   { bad input: more codes than bits }\n      exit;\n    end ;\n    Inc(j) ;\n    y := y shl 1\n  end;\n  Dec (y, c[i]) ;\n  if (y < 0) then\n  begin\n    huft_build := Z_DATA_ERROR;     { bad input: more codes than bits }\n    exit;\n  end;\n  Inc(c[i], y);\n\n  { Generate starting offsets into the value table FOR each length }\n  {$IFDEF USE_PTR}\n  x[1] := 0;\n  j := 0;\n\n  p := @c[1];\n  xp := @x[2];\n\n  dec(i);               { note that i = g from above }\n  WHILE (i > 0) DO\n  BEGIN\n    inc(j, p^);\n    xp^ := j;\n    inc(p);\n    inc(xp);\n    dec(i);\n  END;\n  {$ELSE}\n  x[1] := 0;\n  j := 0 ;\n  for i := 1 to g do\n  begin\n    x[i] := j;\n    Inc(j, c[i]);\n  end;\n  {$ENDIF}\n\n  { Make a table of values in order of bit lengths }\n  for i := 0 to n-1 do\n  begin\n    j := b[i];\n    if (j <> 0) then\n    begin\n      v[ x[j] ] := i;\n      Inc(x[j]);\n    end;\n  end;\n  n := x[g];                     { set n to length of v }\n\n  { Generate the Huffman codes and for each, make the table entries }\n  i := 0 ;\n  x[0] := 0 ;                   { first Huffman code is zero }\n  p := Addr(v) ;                { grab values in bit order }\n  h := -1 ;                     { no tables yet--level -1 }\n  w := -l ;                     { bits decoded = (l*h) }\n\n  u[0] := pInflate_huft(NIL);   { just to keep compilers happy }\n  q := pInflate_huft(NIL);      { ditto }\n  z := 0 ;                      { ditto }\n\n  { go through the bit lengths (k already is bits in shortest code) }\n  while (k <= g) Do\n  begin\n    a := c[k] ;\n    while (a<>0) Do\n    begin\n      Dec (a) ;\n      { here i is the Huffman code of length k bits for value p^ }\n      { make tables up to required level }\n      while (k > w + l) do\n      begin\n\n        Inc (h) ;\n        Inc (w, l);              { add bits already decoded }\n                                 { previous table always l bits }\n        { compute minimum size table less than or equal to l bits }\n\n        { table size upper limit }\n        z := g - w;\n        If (z > uInt(l)) Then\n          z := l;\n\n        { try a k-w bit table }\n        j := k - w;\n        f := 1 shl j;\n        if (f > a+1) Then        { too few codes for k-w bit table }\n        begin\n          Dec(f, a+1);           { deduct codes from patterns left }\n          {$IFDEF USE_PTR}\n          xp := Addr(c[k]);\n\n          if (j < z) then\n          begin\n            Inc(j);\n            while (j < z) do\n            begin                { try smaller tables up to z bits }\n              f := f shl 1;\n              Inc (xp) ;\n              If (f <= xp^) Then\n                break;           { enough codes to use up j bits }\n              Dec(f, xp^);       { else deduct codes from patterns }\n              Inc(j);\n            end;\n          end;\n          {$ELSE}\n          xp := k;\n\n          if (j < z) then\n          begin\n            Inc (j) ;\n            While (j < z) Do\n            begin                 { try smaller tables up to z bits }\n              f := f * 2;\n              Inc (xp) ;\n              if (f <= c[xp]) then\n                Break ;           { enough codes to use up j bits }\n              Dec (f, c[xp]) ;      { else deduct codes from patterns }\n              Inc (j);\n            end;\n          end;\n          {$ENDIF}\n        end;\n\n        z := 1 shl j;            { table entries for j-bit table }\n\n        { allocate new table }\n        if (hn + z > MANY) then { (note: doesn't matter for fixed) }\n        begin\n          huft_build := Z_MEM_ERROR;     { not enough memory }\n          exit;\n        end;\n\n        q := @hp[hn];\n        u[h] := q;\n        Inc(hn, z);\n\n        { connect to last table, if there is one }\n        if (h <> 0) then\n        begin\n          x[h] := i;             { save pattern for backing up }\n          r.bits := Byte(l);     { bits to dump before this table }\n          r.exop := Byte(j);     { bits in this table }\n          j := i shr (w - l);\n          {r.base := uInt( q - u[h-1] -j);}   { offset to this table }\n          r.base := (ptr2int(q) - ptr2int(u[h-1]) ) div sizeof(q^) - j;\n          huft_Ptr(u[h-1])^[j] := r;  { connect to last table }\n        end\n        else\n          t^ := q;               { first table is returned result }\n      end;\n\n      { set up table entry in r }\n      r.bits := Byte(k - w);\n\n      { C-code: if (p >= v + n) - see ZUTIL.PAS for comments }\n\n      if ptr2int(p)>=ptr2int(@(v[n])) then  { also works under DPMI ?? }\n        r.exop := 128 + 64                  { out of values--invalid code }\n      else\n        if (p^ < s) then\n        begin\n          if (p^ < 256) then     { 256 is end-of-block code }\n            r.exop := 0\n          Else\n            r.exop := 32 + 64;   { EOB_code; }\n          r.base := p^;          { simple code is just the value }\n          Inc(p);\n        end\n        Else\n        begin\n          r.exop := Byte(e[p^-s] + 16 + 64);  { non-simple--look up in lists }\n          r.base := d[p^-s];\n          Inc (p);\n        end ;\n\n      { fill code-like entries with r }\n      f := 1 shl (k - w);\n      j := i shr w;\n      while (j < z) do\n      begin\n        huft_Ptr(q)^[j] := r;\n        Inc(j, f);\n      end;\n\n      { backwards increment the k-bit code i }\n      j := 1 shl (k-1) ;\n      while (i and j) <> 0 do\n      begin\n        i := i xor j;         { bitwise exclusive or }\n        j := j shr 1\n      end ;\n      i := i xor j;\n\n      { backup over finished tables }\n      mask := (1 shl w) - 1;   { needed on HP, cc -O bug }\n      while ((i and mask) <> x[h]) do\n      begin\n        Dec(h);                { don't need to update q }\n        Dec(w, l);\n        mask := (1 shl w) - 1;\n      end;\n\n    end;\n\n    Inc(k);\n  end;\n\n  { Return Z_BUF_ERROR if we were given an incomplete table }\n  if (y <> 0) And (g <> 1) then\n    huft_build := Z_BUF_ERROR\n  else\n    huft_build := Z_OK;\nend; { huft_build}\n\n\nfunction inflate_trees_bits(\n  var c : array of uIntf;  { 19 code lengths }\n  var bb : uIntf;          { bits tree desired/actual depth }\n  var tb : pinflate_huft;  { bits tree result }\n  var hp : array of Inflate_huft;      { space for trees }\n  var z : z_stream         { for messages }\n    ) : int;\nvar\n  r : int;\n  hn : uInt;          { hufts used in space }\n  v : PuIntArray;     { work area for huft_build }\nbegin\n  hn := 0;\n  v := PuIntArray( ZALLOC(z, 19, sizeof(uInt)) );\n  if (v = Z_NULL) then\n  begin\n    inflate_trees_bits := Z_MEM_ERROR;\n    exit;\n  end;\n\n  r := huft_build(c, 19, 19, cplens, cplext,\n                             {puIntf(Z_NULL), puIntf(Z_NULL),}\n                  @tb, bb, hp, hn, v^);\n  if (r = Z_DATA_ERROR) then\n    z.msg := 'oversubscribed dynamic bit lengths tree'\n  else\n    if (r = Z_BUF_ERROR) or (bb = 0) then\n    begin\n      z.msg := 'incomplete dynamic bit lengths tree';\n      r := Z_DATA_ERROR;\n    end;\n  ZFREE(z, v);\n  inflate_trees_bits := r;\nend;\n\n\nfunction inflate_trees_dynamic(\n    nl : uInt;                    { number of literal/length codes }\n    nd : uInt;                    { number of distance codes }\n    var c : Array of uIntf;           { that many (total) code lengths }\n    var bl : uIntf;          { literal desired/actual bit depth }\n    var bd : uIntf;          { distance desired/actual bit depth }\nvar tl : pInflate_huft;           { literal/length tree result }\nvar td : pInflate_huft;           { distance tree result }\nvar hp : array of Inflate_huft;   { space for trees }\nvar z : z_stream                  { for messages }\n     ) : int;\nvar\n  r : int;\n  hn : uInt;          { hufts used in space }\n  v : PuIntArray;     { work area for huft_build }\nbegin\n  hn := 0;\n  { allocate work area }\n  v := PuIntArray( ZALLOC(z, 288, sizeof(uInt)) );\n  if (v = Z_NULL) then\n  begin\n    inflate_trees_dynamic := Z_MEM_ERROR;\n    exit;\n  end;\n\n  { build literal/length tree }\n  r := huft_build(c, nl, 257, cplens, cplext, @tl, bl, hp, hn, v^);\n  if (r <> Z_OK) or (bl = 0) then\n  begin\n    if (r = Z_DATA_ERROR) then\n      z.msg := 'oversubscribed literal/length tree'\n    else\n      if (r <> Z_MEM_ERROR) then\n      begin\n        z.msg := 'incomplete literal/length tree';\n        r := Z_DATA_ERROR;\n      end;\n\n    ZFREE(z, v);\n    inflate_trees_dynamic := r;\n    exit;\n  end;\n\n  { build distance tree }\n  r := huft_build(puIntArray(@c[nl])^, nd, 0,\n                  cpdist, cpdext, @td, bd, hp, hn, v^);\n  if (r <> Z_OK) or ((bd = 0) and (nl > 257)) then\n  begin\n    if (r = Z_DATA_ERROR) then\n      z.msg := 'oversubscribed literal/length tree'\n    else\n      if (r = Z_BUF_ERROR) then\n      begin\n{$ifdef PKZIP_BUG_WORKAROUND}\n        r := Z_OK;\n      end;\n{$else}\n        z.msg := 'incomplete literal/length tree';\n        r := Z_DATA_ERROR;\n      end\n      else\n        if (r <> Z_MEM_ERROR) then\n        begin\n          z.msg := 'empty distance tree with lengths';\n          r := Z_DATA_ERROR;\n        end;\n    ZFREE(z, v);\n    inflate_trees_dynamic := r;\n    exit;\n{$endif}\n  end;\n\n  { done }\n  ZFREE(z, v);\n  inflate_trees_dynamic := Z_OK;\nend;\n\n{$UNDEF BUILDFIXED}\n\n{ build fixed tables only once--keep them here }\n{$IFNDEF BUILDFIXED}\n{ locals }\nvar\n  fixed_built : Boolean = false;\nconst\n  FIXEDH = 544;      { number of hufts used by fixed tables }\nvar\n  fixed_mem : array[0..FIXEDH-1] of inflate_huft;\n  fixed_bl : uInt;\n  fixed_bd : uInt;\n  fixed_tl : pInflate_huft;\n  fixed_td : pInflate_huft;\n\n{$ELSE}\n\n{ inffixed.h -- table for decoding fixed codes }\n\n{local}\nconst\n  fixed_bl = uInt(9);\n{local}\nconst\n  fixed_bd = uInt(5);\n{local}\nconst\n  fixed_tl : array [0..288-1] of inflate_huft = (\n    Exop,             { number of extra bits or operation }\n    bits : Byte;      { number of bits in this code or subcode }\n    {pad : uInt;}       { pad structure to a power of 2 (4 bytes for }\n                      {  16-bit, 8 bytes for 32-bit int's) }\n    base : uInt;      { literal, length base, or distance base }\n                      { or table offset }\n\n    ((96,7),256), ((0,8),80), ((0,8),16), ((84,8),115), ((82,7),31),\n    ((0,8),112), ((0,8),48), ((0,9),192), ((80,7),10), ((0,8),96),\n    ((0,8),32), ((0,9),160), ((0,8),0), ((0,8),128), ((0,8),64),\n    ((0,9),224), ((80,7),6), ((0,8),88), ((0,8),24), ((0,9),144),\n    ((83,7),59), ((0,8),120), ((0,8),56), ((0,9),208), ((81,7),17),\n    ((0,8),104), ((0,8),40), ((0,9),176), ((0,8),8), ((0,8),136),\n    ((0,8),72), ((0,9),240), ((80,7),4), ((0,8),84), ((0,8),20),\n    ((85,8),227), ((83,7),43), ((0,8),116), ((0,8),52), ((0,9),200),\n    ((81,7),13), ((0,8),100), ((0,8),36), ((0,9),168), ((0,8),4),\n    ((0,8),132), ((0,8),68), ((0,9),232), ((80,7),8), ((0,8),92),\n    ((0,8),28), ((0,9),152), ((84,7),83), ((0,8),124), ((0,8),60),\n    ((0,9),216), ((82,7),23), ((0,8),108), ((0,8),44), ((0,9),184),\n    ((0,8),12), ((0,8),140), ((0,8),76), ((0,9),248), ((80,7),3),\n    ((0,8),82), ((0,8),18), ((85,8),163), ((83,7),35), ((0,8),114),\n    ((0,8),50), ((0,9),196), ((81,7),11), ((0,8),98), ((0,8),34),\n    ((0,9),164), ((0,8),2), ((0,8),130), ((0,8),66), ((0,9),228),\n    ((80,7),7), ((0,8),90), ((0,8),26), ((0,9),148), ((84,7),67),\n    ((0,8),122), ((0,8),58), ((0,9),212), ((82,7),19), ((0,8),106),\n    ((0,8),42), ((0,9),180), ((0,8),10), ((0,8),138), ((0,8),74),\n    ((0,9),244), ((80,7),5), ((0,8),86), ((0,8),22), ((192,8),0),\n    ((83,7),51), ((0,8),118), ((0,8),54), ((0,9),204), ((81,7),15),\n    ((0,8),102), ((0,8),38), ((0,9),172), ((0,8),6), ((0,8),134),\n    ((0,8),70), ((0,9),236), ((80,7),9), ((0,8),94), ((0,8),30),\n    ((0,9),156), ((84,7),99), ((0,8),126), ((0,8),62), ((0,9),220),\n    ((82,7),27), ((0,8),110), ((0,8),46), ((0,9),188), ((0,8),14),\n    ((0,8),142), ((0,8),78), ((0,9),252), ((96,7),256), ((0,8),81),\n    ((0,8),17), ((85,8),131), ((82,7),31), ((0,8),113), ((0,8),49),\n    ((0,9),194), ((80,7),10), ((0,8),97), ((0,8),33), ((0,9),162),\n    ((0,8),1), ((0,8),129), ((0,8),65), ((0,9),226), ((80,7),6),\n    ((0,8),89), ((0,8),25), ((0,9),146), ((83,7),59), ((0,8),121),\n    ((0,8),57), ((0,9),210), ((81,7),17), ((0,8),105), ((0,8),41),\n    ((0,9),178), ((0,8),9), ((0,8),137), ((0,8),73), ((0,9),242),\n    ((80,7),4), ((0,8),85), ((0,8),21), ((80,8),258), ((83,7),43),\n    ((0,8),117), ((0,8),53), ((0,9),202), ((81,7),13), ((0,8),101),\n    ((0,8),37), ((0,9),170), ((0,8),5), ((0,8),133), ((0,8),69),\n    ((0,9),234), ((80,7),8), ((0,8),93), ((0,8),29), ((0,9),154),\n    ((84,7),83), ((0,8),125), ((0,8),61), ((0,9),218), ((82,7),23),\n    ((0,8),109), ((0,8),45), ((0,9),186), ((0,8),13), ((0,8),141),\n    ((0,8),77), ((0,9),250), ((80,7),3), ((0,8),83), ((0,8),19),\n    ((85,8),195), ((83,7),35), ((0,8),115), ((0,8),51), ((0,9),198),\n    ((81,7),11), ((0,8),99), ((0,8),35), ((0,9),166), ((0,8),3),\n    ((0,8),131), ((0,8),67), ((0,9),230), ((80,7),7), ((0,8),91),\n    ((0,8),27), ((0,9),150), ((84,7),67), ((0,8),123), ((0,8),59),\n    ((0,9),214), ((82,7),19), ((0,8),107), ((0,8),43), ((0,9),182),\n    ((0,8),11), ((0,8),139), ((0,8),75), ((0,9),246), ((80,7),5),\n    ((0,8),87), ((0,8),23), ((192,8),0), ((83,7),51), ((0,8),119),\n    ((0,8),55), ((0,9),206), ((81,7),15), ((0,8),103), ((0,8),39),\n    ((0,9),174), ((0,8),7), ((0,8),135), ((0,8),71), ((0,9),238),\n    ((80,7),9), ((0,8),95), ((0,8),31), ((0,9),158), ((84,7),99),\n    ((0,8),127), ((0,8),63), ((0,9),222), ((82,7),27), ((0,8),111),\n    ((0,8),47), ((0,9),190), ((0,8),15), ((0,8),143), ((0,8),79),\n    ((0,9),254), ((96,7),256), ((0,8),80), ((0,8),16), ((84,8),115),\n    ((82,7),31), ((0,8),112), ((0,8),48), ((0,9),193), ((80,7),10),\n    ((0,8),96), ((0,8),32), ((0,9),161), ((0,8),0), ((0,8),128),\n    ((0,8),64), ((0,9),225), ((80,7),6), ((0,8),88), ((0,8),24),\n    ((0,9),145), ((83,7),59), ((0,8),120), ((0,8),56), ((0,9),209),\n    ((81,7),17), ((0,8),104), ((0,8),40), ((0,9),177), ((0,8),8),\n    ((0,8),136), ((0,8),72), ((0,9),241), ((80,7),4), ((0,8),84),\n    ((0,8),20), ((85,8),227), ((83,7),43), ((0,8),116), ((0,8),52),\n    ((0,9),201), ((81,7),13), ((0,8),100), ((0,8),36), ((0,9),169),\n    ((0,8),4), ((0,8),132), ((0,8),68), ((0,9),233), ((80,7),8),\n    ((0,8),92), ((0,8),28), ((0,9),153), ((84,7),83), ((0,8),124),\n    ((0,8),60), ((0,9),217), ((82,7),23), ((0,8),108), ((0,8),44),\n    ((0,9),185), ((0,8),12), ((0,8),140), ((0,8),76), ((0,9),249),\n    ((80,7),3), ((0,8),82), ((0,8),18), ((85,8),163), ((83,7),35),\n    ((0,8),114), ((0,8),50), ((0,9),197), ((81,7),11), ((0,8),98),\n    ((0,8),34), ((0,9),165), ((0,8),2), ((0,8),130), ((0,8),66),\n    ((0,9),229), ((80,7),7), ((0,8),90), ((0,8),26), ((0,9),149),\n    ((84,7),67), ((0,8),122), ((0,8),58), ((0,9),213), ((82,7),19),\n    ((0,8),106), ((0,8),42), ((0,9),181), ((0,8),10), ((0,8),138),\n    ((0,8),74), ((0,9),245), ((80,7),5), ((0,8),86), ((0,8),22),\n    ((192,8),0), ((83,7),51), ((0,8),118), ((0,8),54), ((0,9),205),\n    ((81,7),15), ((0,8),102), ((0,8),38), ((0,9),173), ((0,8),6),\n    ((0,8),134), ((0,8),70), ((0,9),237), ((80,7),9), ((0,8),94),\n    ((0,8),30), ((0,9),157), ((84,7),99), ((0,8),126), ((0,8),62),\n    ((0,9),221), ((82,7),27), ((0,8),110), ((0,8),46), ((0,9),189),\n    ((0,8),14), ((0,8),142), ((0,8),78), ((0,9),253), ((96,7),256),\n    ((0,8),81), ((0,8),17), ((85,8),131), ((82,7),31), ((0,8),113),\n    ((0,8),49), ((0,9),195), ((80,7),10), ((0,8),97), ((0,8),33),\n    ((0,9),163), ((0,8),1), ((0,8),129), ((0,8),65), ((0,9),227),\n    ((80,7),6), ((0,8),89), ((0,8),25), ((0,9),147), ((83,7),59),\n    ((0,8),121), ((0,8),57), ((0,9),211), ((81,7),17), ((0,8),105),\n    ((0,8),41), ((0,9),179), ((0,8),9), ((0,8),137), ((0,8),73),\n    ((0,9),243), ((80,7),4), ((0,8),85), ((0,8),21), ((80,8),258),\n    ((83,7),43), ((0,8),117), ((0,8),53), ((0,9),203), ((81,7),13),\n    ((0,8),101), ((0,8),37), ((0,9),171), ((0,8),5), ((0,8),133),\n    ((0,8),69), ((0,9),235), ((80,7),8), ((0,8),93), ((0,8),29),\n    ((0,9),155), ((84,7),83), ((0,8),125), ((0,8),61), ((0,9),219),\n    ((82,7),23), ((0,8),109), ((0,8),45), ((0,9),187), ((0,8),13),\n    ((0,8),141), ((0,8),77), ((0,9),251), ((80,7),3), ((0,8),83),\n    ((0,8),19), ((85,8),195), ((83,7),35), ((0,8),115), ((0,8),51),\n    ((0,9),199), ((81,7),11), ((0,8),99), ((0,8),35), ((0,9),167),\n    ((0,8),3), ((0,8),131), ((0,8),67), ((0,9),231), ((80,7),7),\n    ((0,8),91), ((0,8),27), ((0,9),151), ((84,7),67), ((0,8),123),\n    ((0,8),59), ((0,9),215), ((82,7),19), ((0,8),107), ((0,8),43),\n    ((0,9),183), ((0,8),11), ((0,8),139), ((0,8),75), ((0,9),247),\n    ((80,7),5), ((0,8),87), ((0,8),23), ((192,8),0), ((83,7),51),\n    ((0,8),119), ((0,8),55), ((0,9),207), ((81,7),15), ((0,8),103),\n    ((0,8),39), ((0,9),175), ((0,8),7), ((0,8),135), ((0,8),71),\n    ((0,9),239), ((80,7),9), ((0,8),95), ((0,8),31), ((0,9),159),\n    ((84,7),99), ((0,8),127), ((0,8),63), ((0,9),223), ((82,7),27),\n    ((0,8),111), ((0,8),47), ((0,9),191), ((0,8),15), ((0,8),143),\n    ((0,8),79), ((0,9),255)\n  );\n\n{local}\nconst\n  fixed_td : array[0..32-1] of inflate_huft = (\n(Exop:80;bits:5;base:1),      (Exop:87;bits:5;base:257),   (Exop:83;bits:5;base:17),\n(Exop:91;bits:5;base:4097),   (Exop:81;bits:5;base),       (Exop:89;bits:5;base:1025),\n(Exop:85;bits:5;base:65),     (Exop:93;bits:5;base:16385), (Exop:80;bits:5;base:3),\n(Exop:88;bits:5;base:513),    (Exop:84;bits:5;base:33),    (Exop:92;bits:5;base:8193),\n(Exop:82;bits:5;base:9),      (Exop:90;bits:5;base:2049),  (Exop:86;bits:5;base:129),\n(Exop:192;bits:5;base:24577), (Exop:80;bits:5;base:2),     (Exop:87;bits:5;base:385),\n(Exop:83;bits:5;base:25),     (Exop:91;bits:5;base:6145),  (Exop:81;bits:5;base:7),\n(Exop:89;bits:5;base:1537),   (Exop:85;bits:5;base:97),    (Exop:93;bits:5;base:24577),\n(Exop:80;bits:5;base:4),      (Exop:88;bits:5;base:769),   (Exop:84;bits:5;base:49),\n(Exop:92;bits:5;base:12289),  (Exop:82;bits:5;base:13),    (Exop:90;bits:5;base:3073),\n(Exop:86;bits:5;base:193),    (Exop:192;bits:5;base:24577)\n  );\n{$ENDIF}\n\nfunction inflate_trees_fixed(\nvar bl : uInt;               { literal desired/actual bit depth }\nvar bd : uInt;               { distance desired/actual bit depth }\nvar tl : pInflate_huft;      { literal/length tree result }\nvar td : pInflate_huft;      { distance tree result }\nvar  z : z_stream            { for memory allocation }\n      ) : int;\ntype\n  pFixed_table = ^fixed_table;\n  fixed_table = array[0..288-1] of uIntf;\nvar\n  k : int;                   { temporary variable }\n  c : pFixed_table;          { length list for huft_build }\n  v : PuIntArray;            { work area for huft_build }\nvar\n  f : uInt;                  { number of hufts used in fixed_mem }\nbegin\n  { build fixed tables if not already (multiple overlapped executions ok) }\n  if not fixed_built then\n  begin\n    f := 0;\n\n    { allocate memory }\n    c := pFixed_table( ZALLOC(z, 288, sizeof(uInt)) );\n    if (c = Z_NULL) then\n    begin\n      inflate_trees_fixed := Z_MEM_ERROR;\n      exit;\n    end;\n    v := PuIntArray( ZALLOC(z, 288, sizeof(uInt)) );\n    if (v = Z_NULL) then\n    begin\n      ZFREE(z, c);\n      inflate_trees_fixed := Z_MEM_ERROR;\n      exit;\n    end;\n\n    { literal table }\n    for k := 0 to Pred(144) do\n      c^[k] := 8;\n    for k := 144 to Pred(256) do\n      c^[k] := 9;\n    for k := 256 to Pred(280) do\n      c^[k] := 7;\n    for k := 280 to Pred(288) do\n      c^[k] := 8;\n    fixed_bl := 9;\n    huft_build(c^, 288, 257, cplens, cplext, @fixed_tl, fixed_bl,\n               fixed_mem, f, v^);\n\n    { distance table }\n    for k := 0 to Pred(30) do\n      c^[k] := 5;\n    fixed_bd := 5;\n    huft_build(c^, 30, 0, cpdist, cpdext, @fixed_td, fixed_bd,\n               fixed_mem, f, v^);\n\n    { done }\n    ZFREE(z, v);\n    ZFREE(z, c);\n    fixed_built := True;\n  end;\n  bl := fixed_bl;\n  bd := fixed_bd;\n  tl := fixed_tl;\n  td := fixed_td;\n  inflate_trees_fixed := Z_OK;\nend; { inflate_trees_fixed }\n\n\nend."
  },
  {
    "path": "lib/Imaging/ZLib/iminfutil.pas",
    "content": "Unit iminfutil;\n\n{ types and macros common to blocks and codes\n  Copyright (C) 1995-1998 Mark Adler\n\n   WARNING: this file should *not* be used by applications. It is\n   part of the implementation of the compression library and is\n   subject to change.\n\n  Pascal tranlastion\n  Copyright (C) 1998 by Jacques Nomssi Nzali\n  For conditions of distribution and use, see copyright notice in readme.txt\n}\n\ninterface\n\n{$I imzconf.inc}\n\nuses\n  imzutil, impaszlib;\n\n{ copy as much as possible from the sliding window to the output area }\nfunction inflate_flush(var s : inflate_blocks_state;\n                       var z : z_stream;\n                       r : int) : int;\n\n{ And'ing with mask[n] masks the lower n bits }\nconst\n  inflate_mask : array[0..17-1] of uInt = (\n    $0000,\n    $0001, $0003, $0007, $000f, $001f, $003f, $007f, $00ff,\n    $01ff, $03ff, $07ff, $0fff, $1fff, $3fff, $7fff, $ffff);\n\n{procedure GRABBITS(j : int);}\n{procedure DUMPBITS(j : int);}\n{procedure NEEDBITS(j : int);}\n\nimplementation\n\n{ macros for bit input with no checking and for returning unused bytes }\nprocedure GRABBITS(j : int);\nbegin\n  {while (k < j) do\n  begin\n    Dec(z^.avail_in);\n    Inc(z^.total_in);\n    b := b or (uLong(z^.next_in^) shl k);\n    Inc(z^.next_in);\n    Inc(k, 8);\n  end;}\nend;\n\nprocedure DUMPBITS(j : int);\nbegin\n  {b := b shr j;\n  Dec(k, j);}\nend;\n\nprocedure NEEDBITS(j : int);\nbegin\n (*\n          while (k < j) do\n          begin\n            {NEEDBYTE;}\n            if (n <> 0) then\n              r :=Z_OK\n            else\n            begin\n              {UPDATE}\n              s.bitb := b;\n              s.bitk := k;\n              z.avail_in := n;\n              Inc(z.total_in, LongInt(p)-LongInt(z.next_in));\n              z.next_in := p;\n              s.write := q;\n              result := inflate_flush(s,z,r);\n              exit;\n            end;\n            Dec(n);\n            b := b or (uLong(p^) shl k);\n            Inc(p);\n            Inc(k, 8);\n          end;\n *)\nend;\n\nprocedure NEEDOUT;\nbegin\n (*\n  if (m = 0) then\n  begin\n    {WRAP}\n    if (q = s.zend) and (s.read <> s.window) then\n    begin\n      q := s.window;\n      if LongInt(q) < LongInt(s.read) then\n        m := uInt(LongInt(s.read)-LongInt(q)-1)\n      else\n        m := uInt(LongInt(s.zend)-LongInt(q));\n    end;\n\n    if (m = 0) then\n    begin\n      {FLUSH}\n      s.write := q;\n      r := inflate_flush(s,z,r);\n      q := s.write;\n      if LongInt(q) < LongInt(s.read) then\n        m := uInt(LongInt(s.read)-LongInt(q)-1)\n      else\n        m := uInt(LongInt(s.zend)-LongInt(q));\n\n      {WRAP}\n      if (q = s.zend) and (s.read <> s.window) then\n      begin\n        q := s.window;\n        if LongInt(q) < LongInt(s.read) then\n          m := uInt(LongInt(s.read)-LongInt(q)-1)\n        else\n          m := uInt(LongInt(s.zend)-LongInt(q));\n      end;\n\n      if (m = 0) then\n      begin\n        {UPDATE}\n        s.bitb := b;\n        s.bitk := k;\n        z.avail_in := n;\n        Inc(z.total_in, LongInt(p)-LongInt(z.next_in));\n        z.next_in := p;\n        s.write := q;\n        result := inflate_flush(s,z,r);\n        exit;\n      end;\n    end;\n  end;\n  r := Z_OK;\n *)\nend;\n\n{ copy as much as possible from the sliding window to the output area }\nfunction inflate_flush(var s : inflate_blocks_state;\n                       var z : z_stream;\n                       r : int) : int;\nvar\n  n : uInt;\n  p : pBytef;\n  q : pBytef;\nbegin\n  { local copies of source and destination pointers }\n  p := z.next_out;\n  q := s.read;\n\n  { compute number of bytes to copy as far as end of window }\n  if ptr2int(q) <= ptr2int(s.write) then\n    n := uInt(ptr2int(s.write) - ptr2int(q))\n  else\n    n := uInt(ptr2int(s.zend) - ptr2int(q));\n  if (n > z.avail_out) then\n    n := z.avail_out;\n  if (n <> 0) and (r = Z_BUF_ERROR) then\n    r := Z_OK;\n\n  { update counters }\n  Dec(z.avail_out, n);\n  Inc(z.total_out, n);\n\n\n  { update check information }\n  if Assigned(s.checkfn) then\n  begin\n    s.check := s.checkfn(s.check, q, n);\n    z.adler := s.check;\n  end;\n\n  { copy as far as end of window }\n  zmemcpy(p, q, n);\n  Inc(p, n);\n  Inc(q, n);\n\n  { see if more to copy at beginning of window }\n  if (q = s.zend) then\n  begin\n    { wrap pointers }\n    q := s.window;\n    if (s.write = s.zend) then\n      s.write := s.window;\n\n    { compute bytes to copy }\n    n := uInt(ptr2int(s.write) - ptr2int(q));\n    if (n > z.avail_out) then\n      n := z.avail_out;\n    if (n <> 0) and (r = Z_BUF_ERROR) then\n      r := Z_OK;\n\n    { update counters }\n    Dec( z.avail_out, n);\n    Inc( z.total_out, n);\n\n    { update check information }\n    if Assigned(s.checkfn) then\n    begin\n      s.check := s.checkfn(s.check, q, n);\n      z.adler := s.check;\n    end;\n\n    { copy }\n    zmemcpy(p, q, n);\n    Inc(p, n);\n    Inc(q, n);\n  end;\n\n\n  { update pointers }\n  z.next_out := p;\n  s.read := q;\n\n  { done }\n  inflate_flush := r;\nend;\n\nend.\n"
  },
  {
    "path": "lib/Imaging/ZLib/impaszlib.pas",
    "content": "Unit impaszlib;\n\n\n{ Original:\n   zlib.h -- interface of the 'zlib' general purpose compression library\n  version 1.1.0, Feb 24th, 1998\n\n  Copyright (C) 1995-1998 Jean-loup Gailly and Mark Adler\n\n  This software is provided 'as-is', without any express or implied\n  warranty.  In no event will the authors be held liable for any damages\n  arising from the use of this software.\n\n  Permission is granted to anyone to use this software for any purpose,\n  including commercial applications, and to alter it and redistribute it\n  freely, subject to the following restrictions:\n\n  1. The origin of this software must not be misrepresented; you must not\n     claim that you wrote the original software. If you use this software\n     in a product, an acknowledgment in the product documentation would be\n     appreciated but is not required.\n  2. Altered source versions must be plainly marked as such, and must not be\n     misrepresented as being the original software.\n  3. This notice may not be removed or altered from any source distribution.\n\n  Jean-loup Gailly        Mark Adler\n  jloup@gzip.org          madler@alumni.caltech.edu\n\n\n  The data format used by the zlib library is described by RFCs (Request for\n  Comments) 1950 to 1952 in the files ftp://ds.internic.net/rfc/rfc1950.txt\n  (zlib format), rfc1951.txt (deflate format) and rfc1952.txt (gzip format).\n\n\n  Pascal tranlastion\n  Copyright (C) 1998 by Jacques Nomssi Nzali\n  For conditions of distribution and use, see copyright notice in readme.txt\n}\n\ninterface\n\n{$I imzconf.inc}\n\nuses\n  imzutil;\n\n{ zconf.h -- configuration of the zlib compression library }\n{ zutil.c -- target dependent utility functions for the compression library }\n\n{ The 'zlib' compression library provides in-memory compression and\n  decompression functions, including integrity checks of the uncompressed\n  data.  This version of the library supports only one compression method\n  (deflation) but other algorithms will be added later and will have the same\n  stream interface.\n\n     Compression can be done in a single step if the buffers are large\n  enough (for example if an input file is mmap'ed), or can be done by\n  repeated calls of the compression function.  In the latter case, the\n  application must provide more input and/or consume the output\n  (providing more output space) before each call.\n\n     The library also supports reading and writing files in gzip (.gz) format\n  with an interface similar to that of stdio.\n\n     The library does not install any signal handler. The decoder checks\n  the consistency of the compressed data, so the library should never\n  crash even in case of corrupted input. }\n\n\n\n{ Compile with -DMAXSEG_64K if the alloc function cannot allocate more\n  than 64k bytes at a time (needed on systems with 16-bit int). }\n\n{ Maximum value for memLevel in deflateInit2 }\nconst\n  MAX_MEM_LEVEL = 9;\n  DEF_MEM_LEVEL = 8; { if MAX_MEM_LEVEL > 8 }\n\n{ Maximum value for windowBits in deflateInit2 and inflateInit2 }\nconst\n  MAX_WBITS = 15; { 32K LZ77 window }\n\n{ default windowBits for decompression. MAX_WBITS is for compression only }\nconst\n  DEF_WBITS = MAX_WBITS;\n\n{ The memory requirements for deflate are (in bytes):\n            1 shl (windowBits+2)   +  1 shl (memLevel+9)\n that is: 128K for windowBits=15  +  128K for memLevel = 8  (default values)\n plus a few kilobytes for small objects. For example, if you want to reduce\n the default memory requirements from 256K to 128K, compile with\n     DMAX_WBITS=14 DMAX_MEM_LEVEL=7\n Of course this will generally degrade compression (there's no free lunch).\n\n The memory requirements for inflate are (in bytes) 1 shl windowBits\n that is, 32K for windowBits=15 (default value) plus a few kilobytes\n for small objects. }\n\n\n{ Huffman code lookup table entry--this entry is four bytes for machines\n  that have 16-bit pointers (e.g. PC's in the small or medium model). }\n\ntype\n  pInflate_huft = ^inflate_huft;\n  inflate_huft = Record\n    Exop,             { number of extra bits or operation }\n    bits : Byte;      { number of bits in this code or subcode }\n    {pad : uInt;}       { pad structure to a power of 2 (4 bytes for }\n                      {  16-bit, 8 bytes for 32-bit int's) }\n    base : uInt;      { literal, length base, or distance base }\n                      { or table offset }\n  End;\n\ntype\n  huft_field = Array[0..(MaxInt div SizeOf(inflate_huft))-1] of inflate_huft;\n  huft_ptr = ^huft_field;\ntype\n  ppInflate_huft = ^pInflate_huft;\n\ntype\n  inflate_codes_mode = ( { waiting for \"i:\"=input, \"o:\"=output, \"x:\"=nothing }\n        START,    { x: set up for LEN }\n        LEN,      { i: get length/literal/eob next }\n        LENEXT,   { i: getting length extra (have base) }\n        DIST,     { i: get distance next }\n        DISTEXT,  { i: getting distance extra }\n        COPY,     { o: copying bytes in window, waiting for space }\n        LIT,      { o: got literal, waiting for output space }\n        WASH,     { o: got eob, possibly still output waiting }\n        ZEND,     { x: got eob and all data flushed }\n        BADCODE); { x: got error }\n\n{ inflate codes private state }\ntype\n  pInflate_codes_state = ^inflate_codes_state;\n  inflate_codes_state = record\n\n    mode : inflate_codes_mode;        { current inflate_codes mode }\n\n    { mode dependent information }\n    len : uInt;\n    sub : record                      { submode }\n      Case Byte of\n      0:(code : record                { if LEN or DIST, where in tree }\n          tree : pInflate_huft;       { pointer into tree }\n          need : uInt;                { bits needed }\n         end);\n      1:(lit : uInt);                 { if LIT, literal }\n      2:(copy: record                 { if EXT or COPY, where and how much }\n           get : uInt;                { bits to get for extra }\n           dist : uInt;               { distance back to copy from }\n         end);\n    end;\n\n    { mode independent information }\n    lbits : Byte;                     { ltree bits decoded per branch }\n    dbits : Byte;                     { dtree bits decoder per branch }\n    ltree : pInflate_huft;            { literal/length/eob tree }\n    dtree : pInflate_huft;            { distance tree }\n  end;\n\ntype\n  check_func = function(check : uLong;\n                        buf : pBytef;\n                        {const buf : array of byte;}\n\t                len : uInt) : uLong;\ntype\n  inflate_block_mode =\n     (ZTYPE,    { get type bits (3, including end bit) }\n      LENS,     { get lengths for stored }\n      STORED,   { processing stored block }\n      TABLE,    { get table lengths }\n      BTREE,    { get bit lengths tree for a dynamic block }\n      DTREE,    { get length, distance trees for a dynamic block }\n      CODES,    { processing fixed or dynamic block }\n      DRY,      { output remaining window bytes }\n      BLKDONE,  { finished last block, done }\n      BLKBAD);  { got a data error--stuck here }\n\ntype\n  pInflate_blocks_state = ^inflate_blocks_state;\n\n{ inflate blocks semi-private state }\n  inflate_blocks_state = record\n\n    mode : inflate_block_mode;     { current inflate_block mode }\n\n    { mode dependent information }\n    sub : record                  { submode }\n    case Byte of\n    0:(left : uInt);              { if STORED, bytes left to copy }\n    1:(trees : record             { if DTREE, decoding info for trees }\n        table : uInt;               { table lengths (14 bits) }\n        index : uInt;               { index into blens (or border) }\n        blens : PuIntArray;         { bit lengths of codes }\n        bb : uInt;                  { bit length tree depth }\n        tb : pInflate_huft;         { bit length decoding tree }\n      end);\n    2:(decode : record            { if CODES, current state }\n        tl : pInflate_huft;\n        td : pInflate_huft;         { trees to free }\n        codes : pInflate_codes_state;\n      end);\n    end;\n    last : boolean;               { true if this block is the last block }\n\n    { mode independent information }\n    bitk : uInt;            { bits in bit buffer }\n    bitb : uLong;           { bit buffer }\n    hufts : huft_ptr; {pInflate_huft;}  { single malloc for tree space }\n    window : pBytef;        { sliding window }\n    zend : pBytef;          { one byte after sliding window }\n    read : pBytef;          { window read pointer }\n    write : pBytef;         { window write pointer }\n    checkfn : check_func;   { check function }\n    check : uLong;          { check on output }\n  end;\n\ntype\n  inflate_mode = (\n      METHOD,   { waiting for method byte }\n      FLAG,     { waiting for flag byte }\n      DICT4,    { four dictionary check bytes to go }\n      DICT3,    { three dictionary check bytes to go }\n      DICT2,    { two dictionary check bytes to go }\n      DICT1,    { one dictionary check byte to go }\n      DICT0,    { waiting for inflateSetDictionary }\n      BLOCKS,   { decompressing blocks }\n      CHECK4,   { four check bytes to go }\n      CHECK3,   { three check bytes to go }\n      CHECK2,   { two check bytes to go }\n      CHECK1,   { one check byte to go }\n      DONE,     { finished check, done }\n      BAD);     { got an error--stay here }\n\n{ inflate private state }\ntype\n  pInternal_state = ^internal_state; { or point to a deflate_state record }\n  internal_state = record\n\n     mode : inflate_mode;  { current inflate mode }\n\n     { mode dependent information }\n     sub : record          { submode }\n       case byte of\n       0:(method : uInt);  { if FLAGS, method byte }\n       1:(check : record   { if CHECK, check values to compare }\n           was : uLong;        { computed check value }\n           need : uLong;       { stream check value }\n          end);\n       2:(marker : uInt);  { if BAD, inflateSync's marker bytes count }\n     end;\n\n     { mode independent information }\n     nowrap : boolean;      { flag for no wrapper }\n     wbits : uInt;          { log2(window size)  (8..15, defaults to 15) }\n     blocks : pInflate_blocks_state;    { current inflate_blocks state }\n   end;\n\ntype\n  alloc_func = function(opaque : voidpf; items : uInt; size : uInt) : voidpf;\n  free_func = procedure(opaque : voidpf; address : voidpf);\n\ntype\n  z_streamp = ^z_stream;\n  z_stream = record\n    next_in : pBytef;     { next input byte }\n    avail_in : uInt;      { number of bytes available at next_in }\n    total_in : uLong;     { total nb of input bytes read so far }\n\n    next_out : pBytef;    { next output byte should be put there }\n    avail_out : uInt;     { remaining free space at next_out }\n    total_out : uLong;    { total nb of bytes output so far }\n\n    msg : string[255];         { last error message, '' if no error }\n    state : pInternal_state; { not visible by applications }\n\n    zalloc : alloc_func;  { used to allocate the internal state }\n    zfree : free_func;    { used to free the internal state }\n    opaque : voidpf;      { private data object passed to zalloc and zfree }\n\n    data_type : int;      { best guess about the data type: ascii or binary }\n    adler : uLong;        { adler32 value of the uncompressed data }\n    reserved : uLong;     { reserved for future use }\n  end;\n\n\n{  The application must update next_in and avail_in when avail_in has\n   dropped to zero. It must update next_out and avail_out when avail_out\n   has dropped to zero. The application must initialize zalloc, zfree and\n   opaque before calling the init function. All other fields are set by the\n   compression library and must not be updated by the application.\n\n   The opaque value provided by the application will be passed as the first\n   parameter for calls of zalloc and zfree. This can be useful for custom\n   memory management. The compression library attaches no meaning to the\n   opaque value.\n\n   zalloc must return Z_NULL if there is not enough memory for the object.\n   On 16-bit systems, the functions zalloc and zfree must be able to allocate\n   exactly 65536 bytes, but will not be required to allocate more than this\n   if the symbol MAXSEG_64K is defined (see zconf.h). WARNING: On MSDOS,\n   pointers returned by zalloc for objects of exactly 65536 bytes *must*\n   have their offset normalized to zero. The default allocation function\n   provided by this library ensures this (see zutil.c). To reduce memory\n   requirements and avoid any allocation of 64K objects, at the expense of\n   compression ratio, compile the library with -DMAX_WBITS=14 (see zconf.h).\n\n   The fields total_in and total_out can be used for statistics or\n   progress reports. After compression, total_in holds the total size of\n   the uncompressed data and may be saved for use in the decompressor\n   (particularly if the decompressor wants to decompress everything in\n   a single step). }\n\nconst  { constants }\n   Z_NO_FLUSH      = 0;\n   Z_PARTIAL_FLUSH = 1;\n   Z_SYNC_FLUSH    = 2;\n   Z_FULL_FLUSH    = 3;\n   Z_FINISH        = 4;\n{ Allowed flush values; see deflate() below for details }\n\n   Z_OK            = 0;\n   Z_STREAM_END    = 1;\n   Z_NEED_DICT     = 2;\n   Z_ERRNO         = (-1);\n   Z_STREAM_ERROR  = (-2);\n   Z_DATA_ERROR    = (-3);\n   Z_MEM_ERROR     = (-4);\n   Z_BUF_ERROR     = (-5);\n   Z_VERSION_ERROR = (-6);\n{ Return codes for the compression/decompression functions. Negative\n  values are errors, positive values are used for special but normal events.}\n\n   Z_NO_COMPRESSION         = 0;\n   Z_BEST_SPEED             = 1;\n   Z_BEST_COMPRESSION       = 9;\n   Z_DEFAULT_COMPRESSION    = (-1);\n{ compression levels }\n\n   Z_FILTERED            = 1;\n   Z_HUFFMAN_ONLY        = 2;\n   Z_DEFAULT_STRATEGY    = 0;\n{ compression strategy; see deflateInit2() below for details }\n\n   Z_BINARY   = 0;\n   Z_ASCII    = 1;\n   Z_UNKNOWN  = 2;\n{ Possible values of the data_type field }\n\n   Z_DEFLATED   = 8;\n{ The deflate compression method (the only one supported in this version) }\n\n   Z_NULL  = NIL;  { for initializing zalloc, zfree, opaque }\n\n  {$IFDEF GZIO}\nvar\n  errno : int;\n  {$ENDIF}\n\n        { common constants }\n\n\n{ The three kinds of block type }\nconst\n  STORED_BLOCK = 0;\n  STATIC_TREES = 1;\n  DYN_TREES = 2;\n{ The minimum and maximum match lengths }\nconst\n  MIN_MATCH = 3;\n  MAX_MATCH = 258;\n\nconst\n  PRESET_DICT = $20; { preset dictionary flag in zlib header }\n\n\n  {$IFDEF DEBUG}\n  procedure Assert(cond : boolean; msg : AnsiString);\n  {$ENDIF}\n\n  procedure Trace(x : AnsiString);\n  procedure Tracev(x : AnsiString);\n  procedure Tracevv(x : AnsiString);\n  procedure Tracevvv(x : AnsiString);\n  procedure Tracec(c : boolean; x : AnsiString);\n  procedure Tracecv(c : boolean; x : AnsiString);\n\nfunction zlibVersion : AnsiString;\n{ The application can compare zlibVersion and ZLIB_VERSION for consistency.\n  If the first character differs, the library code actually used is\n  not compatible with the zlib.h header file used by the application.\n  This check is automatically made by deflateInit and inflateInit. }\n\nfunction zError(err : int) : AnsiString;\nfunction ZALLOC (var strm : z_stream; items : uInt; size : uInt) : voidpf;\nprocedure ZFREE (var strm : z_stream; ptr : voidpf);\nprocedure TRY_FREE (var strm : z_stream; ptr : voidpf);\n\nconst\n  ZLIB_VERSION : string[10] = '1.1.2';\n\nconst\n  z_errbase = Z_NEED_DICT;\n  z_errmsg : Array[0..9] of string[21] = { indexed by 2-zlib_error }\n           ('need dictionary',     { Z_NEED_DICT       2  }\n            'stream end',          { Z_STREAM_END      1  }\n            '',                    { Z_OK              0  }\n            'file error',          { Z_ERRNO         (-1) }\n            'stream error',        { Z_STREAM_ERROR  (-2) }\n            'data error',          { Z_DATA_ERROR    (-3) }\n            'insufficient memory', { Z_MEM_ERROR     (-4) }\n            'buffer error',        { Z_BUF_ERROR     (-5) }\n            'incompatible version',{ Z_VERSION_ERROR (-6) }\n            '');\nconst\n  z_verbose : int = 1;\n\nfunction deflateInit_(var Stream: z_stream; Level: LongInt; const Version: AnsiString;\n  Stream_size: LongInt): LongInt;\nfunction inflateInit_(var Stream: z_stream; const Version: AnsiString;\n  Stream_size: Longint): LongInt;\n  \n{$IFDEF DEBUG}\nprocedure z_error (m : string);\n{$ENDIF}\n\nimplementation\n\nuses\n  imzdeflate, imzinflate;\n\nfunction deflateInit_(var Stream: z_stream; Level: LongInt; const Version: AnsiString;\n  Stream_size: LongInt): LongInt;\nbegin\n  Result := imzdeflate.deflateInit_(@Stream, Level, Version, Stream_size);\nend;\n\nfunction inflateInit_(var Stream: z_stream; const Version: AnsiString;\n  Stream_size: Longint): LongInt;\nbegin\n  Result := imzinflate.inflateInit_(@Stream, Version, Stream_size);\nend;\n\nfunction zError(err : int) : AnsiString;\nbegin\n  zError := z_errmsg[Z_NEED_DICT-err];\nend;\n\nfunction zlibVersion : AnsiString;\nbegin\n  zlibVersion := ZLIB_VERSION;\nend;\n\nprocedure z_error (m : AnsiString);\nbegin\n  WriteLn(output, m);\n  Write('Zlib - Halt...');\n  ReadLn;\n  Halt(1);\nend;\n\nprocedure Assert(cond : boolean; msg : AnsiString);\nbegin\n  if not cond then\n    z_error(msg);\nend;\n\nprocedure Trace(x : AnsiString);\nbegin\n  WriteLn(x);\nend;\n\nprocedure Tracev(x : AnsiString);\nbegin\n if (z_verbose>0) then\n   WriteLn(x);\nend;\n\nprocedure Tracevv(x : AnsiString);\nbegin\n  if (z_verbose>1) then\n    WriteLn(x);\nend;\n\nprocedure Tracevvv(x : AnsiString);\nbegin\n  if (z_verbose>2) then\n    WriteLn(x);\nend;\n\nprocedure Tracec(c : boolean; x : AnsiString);\nbegin\n  if (z_verbose>0) and (c) then\n    WriteLn(x);\nend;\n\nprocedure Tracecv(c : boolean; x : AnsiString);\nbegin\n  if (z_verbose>1) and c then\n    WriteLn(x);\nend;\n\nfunction ZALLOC (var strm : z_stream; items : uInt; size : uInt) : voidpf;\nbegin\n  ZALLOC := strm.zalloc(strm.opaque, items, size);\nend;\n\nprocedure ZFREE (var strm : z_stream; ptr : voidpf);\nbegin\n  strm.zfree(strm.opaque, ptr);\nend;\n\nprocedure TRY_FREE (var strm : z_stream; ptr : voidpf);\nbegin\n  {if @strm <> Z_NULL then}\n    strm.zfree(strm.opaque, ptr);\nend;\n\nend.\n"
  },
  {
    "path": "lib/Imaging/ZLib/imtrees.pas",
    "content": "Unit imtrees;\n\n{$T-}\n{$define ORG_DEBUG}\n{\n  trees.c -- output deflated data using Huffman coding\n  Copyright (C) 1995-1998 Jean-loup Gailly\n\n  Pascal tranlastion\n  Copyright (C) 1998 by Jacques Nomssi Nzali\n  For conditions of distribution and use, see copyright notice in readme.txt\n}\n\n{\n *  ALGORITHM\n *\n *      The \"deflation\" process uses several Huffman trees. The more\n *      common source values are represented by shorter bit sequences.\n *\n *      Each code tree is stored in a compressed form which is itself\n * a Huffman encoding of the lengths of all the code strings (in\n * ascending order by source values).  The actual code strings are\n * reconstructed from the lengths in the inflate process, as described\n * in the deflate specification.\n *\n *  REFERENCES\n *\n *      Deutsch, L.P.,\"'Deflate' Compressed Data Format Specification\".\n *      Available in ftp.uu.net:/pub/archiving/zip/doc/deflate-1.1.doc\n *\n *      Storer, James A.\n *          Data Compression:  Methods and Theory, pp. 49-50.\n *          Computer Science Press, 1988.  ISBN 0-7167-8156-5.\n *\n *      Sedgewick, R.\n *          Algorithms, p290.\n *          Addison-Wesley, 1983. ISBN 0-201-06672-6.\n }\n\ninterface\n\n{$I imzconf.inc}\n\nuses\n  {$ifdef DEBUG}\n  SysUtils, strutils,\n  {$ENDIF}\n  imzutil, impaszlib;\n\n{ ===========================================================================\n  Internal compression state. }\n\nconst\n  LENGTH_CODES = 29;\n{ number of length codes, not counting the special END_BLOCK code }\n\n  LITERALS = 256;\n{ number of literal bytes 0..255 }\n\n  L_CODES = (LITERALS+1+LENGTH_CODES);\n{ number of Literal or Length codes, including the END_BLOCK code }\n\n  D_CODES = 30;\n{ number of distance codes }\n\n  BL_CODES = 19;\n{ number of codes used to transfer the bit lengths }\n\n  HEAP_SIZE = (2*L_CODES+1);\n{ maximum heap size }\n\n  MAX_BITS = 15;\n{ All codes must not exceed MAX_BITS bits }\n\nconst\n  INIT_STATE =  42;\n  BUSY_STATE =  113;\n  FINISH_STATE = 666;\n{ Stream status }\n\n\n{ Data structure describing a single value and its code string. }\ntype\n  ct_data_ptr = ^ct_data;\n  ct_data = record\n    fc : record\n      case byte of\n      0:(freq : ush);       { frequency count }\n      1:(code : ush);       { bit string }\n    end;\n    dl : record\n      case byte of\n      0:(dad : ush);        { father node in Huffman tree }\n      1:(len : ush);        { length of bit string }\n    end;\n  end;\n\n{ Freq = fc.freq\n Code = fc.code\n Dad = dl.dad\n Len = dl.len }\n\ntype\n  ltree_type = array[0..HEAP_SIZE-1] of ct_data;    { literal and length tree }\n  dtree_type = array[0..2*D_CODES+1-1] of ct_data;  { distance tree }\n  htree_type = array[0..2*BL_CODES+1-1] of ct_data;  { Huffman tree for bit lengths }\n  { generic tree type }\n  tree_type = array[0..(MaxInt div SizeOf(ct_data))-1] of ct_data;\n\n  tree_ptr = ^tree_type;\n  ltree_ptr = ^ltree_type;\n  dtree_ptr = ^dtree_type;\n  htree_ptr = ^htree_type;\n\n\ntype\n  static_tree_desc_ptr = ^static_tree_desc;\n  static_tree_desc =\n         record\n    {const} static_tree : tree_ptr;     { static tree or NIL }\n    {const} extra_bits : pzIntfArray;   { extra bits for each code or NIL }\n            extra_base : int;           { base index for extra_bits }\n            elems : int;                { max number of elements in the tree }\n            max_length : int;           { max bit length for the codes }\n          end;\n\n  tree_desc_ptr = ^tree_desc;\n  tree_desc = record\n    dyn_tree : tree_ptr;    { the dynamic tree }\n    max_code : int;            { largest code with non zero frequency }\n    stat_desc : static_tree_desc_ptr; { the corresponding static tree }\n  end;\n\ntype\n  Pos = ush;\n  Posf = Pos; {FAR}\n  IPos = uInt;\n\n  pPosf = ^Posf;\n\n  zPosfArray = array[0..(MaxInt div SizeOf(Posf))-1] of Posf;\n  pzPosfArray = ^zPosfArray;\n\n{ A Pos is an index in the character window. We use short instead of int to\n  save space in the various tables. IPos is used only for parameter passing.}\n\ntype\n  deflate_state_ptr = ^deflate_state;\n  deflate_state = record\n    strm : z_streamp;          { pointer back to this zlib stream }\n    status : int;              { as the name implies }\n    pending_buf : pzByteArray; { output still pending }\n    pending_buf_size : ulg;    { size of pending_buf }\n    pending_out : pBytef;      { next pending byte to output to the stream }\n    pending : int;             { nb of bytes in the pending buffer }\n    noheader : int;            { suppress zlib header and adler32 }\n    data_type : Byte;          { UNKNOWN, BINARY or ASCII }\n    method : Byte;             { STORED (for zip only) or DEFLATED }\n    last_flush : int;          { value of flush param for previous deflate call }\n\n                { used by deflate.pas: }\n\n    w_size : uInt;             { LZ77 window size (32K by default) }\n    w_bits : uInt;             { log2(w_size)  (8..16) }\n    w_mask : uInt;             { w_size - 1 }\n\n    window : pzByteArray;\n    { Sliding window. Input bytes are read into the second half of the window,\n      and move to the first half later to keep a dictionary of at least wSize\n      bytes. With this organization, matches are limited to a distance of\n      wSize-MAX_MATCH bytes, but this ensures that IO is always\n      performed with a length multiple of the block size. Also, it limits\n      the window size to 64K, which is quite useful on MSDOS.\n      To do: use the user input buffer as sliding window. }\n\n    window_size : ulg;\n    { Actual size of window: 2*wSize, except when the user input buffer\n      is directly used as sliding window. }\n\n    prev : pzPosfArray;\n    { Link to older string with same hash index. To limit the size of this\n      array to 64K, this link is maintained only for the last 32K strings.\n      An index in this array is thus a window index modulo 32K. }\n\n    head : pzPosfArray;    { Heads of the hash chains or NIL. }\n\n    ins_h : uInt;          { hash index of string to be inserted }\n    hash_size : uInt;      { number of elements in hash table }\n    hash_bits : uInt;      { log2(hash_size) }\n    hash_mask : uInt;      { hash_size-1 }\n\n    hash_shift : uInt;\n    { Number of bits by which ins_h must be shifted at each input\n      step. It must be such that after MIN_MATCH steps, the oldest\n      byte no longer takes part in the hash key, that is:\n        hash_shift * MIN_MATCH >= hash_bits     }\n\n    block_start : long;\n    { Window position at the beginning of the current output block. Gets\n      negative when the window is moved backwards. }\n\n    match_length : uInt;           { length of best match }\n    prev_match : IPos;             { previous match }\n    match_available : boolean;     { set if previous match exists }\n    strstart : uInt;               { start of string to insert }\n    match_start : uInt;            { start of matching string }\n    lookahead : uInt;              { number of valid bytes ahead in window }\n\n    prev_length : uInt;\n    { Length of the best match at previous step. Matches not greater than this\n      are discarded. This is used in the lazy match evaluation. }\n\n    max_chain_length : uInt;\n    { To speed up deflation, hash chains are never searched beyond this\n      length.  A higher limit improves compression ratio but degrades the\n      speed. }\n\n    { moved to the end because Borland Pascal won't accept the following:\n    max_lazy_match : uInt;\n    max_insert_length : uInt absolute max_lazy_match;\n    }\n\n    level : int;    { compression level (1..9) }\n    strategy : int; { favor or force Huffman coding}\n\n    good_match : uInt;\n    { Use a faster search when the previous match is longer than this }\n\n    nice_match : int; { Stop searching when current match exceeds this }\n\n                { used by trees.pas: }\n    { Didn't use ct_data typedef below to supress compiler warning }\n    dyn_ltree : ltree_type;    { literal and length tree }\n    dyn_dtree : dtree_type;  { distance tree }\n    bl_tree : htree_type;   { Huffman tree for bit lengths }\n\n    l_desc : tree_desc;                { desc. for literal tree }\n    d_desc : tree_desc;                { desc. for distance tree }\n    bl_desc : tree_desc;               { desc. for bit length tree }\n\n    bl_count : array[0..MAX_BITS+1-1] of ush;\n    { number of codes at each bit length for an optimal tree }\n\n    heap : array[0..2*L_CODES+1-1] of int; { heap used to build the Huffman trees }\n    heap_len : int;                   { number of elements in the heap }\n    heap_max : int;                   { element of largest frequency }\n    { The sons of heap[n] are heap[2*n] and heap[2*n+1]. heap[0] is not used.\n      The same heap array is used to build all trees. }\n\n    depth : array[0..2*L_CODES+1-1] of uch;\n    { Depth of each subtree used as tie breaker for trees of equal frequency }\n\n\n    l_buf : puchfArray;       { buffer for literals or lengths }\n\n    lit_bufsize : uInt;\n    { Size of match buffer for literals/lengths.  There are 4 reasons for\n      limiting lit_bufsize to 64K:\n        - frequencies can be kept in 16 bit counters\n        - if compression is not successful for the first block, all input\n          data is still in the window so we can still emit a stored block even\n          when input comes from standard input.  (This can also be done for\n          all blocks if lit_bufsize is not greater than 32K.)\n        - if compression is not successful for a file smaller than 64K, we can\n          even emit a stored file instead of a stored block (saving 5 bytes).\n          This is applicable only for zip (not gzip or zlib).\n        - creating new Huffman trees less frequently may not provide fast\n          adaptation to changes in the input data statistics. (Take for\n          example a binary file with poorly compressible code followed by\n          a highly compressible string table.) Smaller buffer sizes give\n          fast adaptation but have of course the overhead of transmitting\n          trees more frequently.\n        - I can't count above 4 }\n\n\n    last_lit : uInt;      { running index in l_buf }\n\n    d_buf : pushfArray;\n    { Buffer for distances. To simplify the code, d_buf and l_buf have\n      the same number of elements. To use different lengths, an extra flag\n      array would be necessary. }\n\n    opt_len : ulg;        { bit length of current block with optimal trees }\n    static_len : ulg;     { bit length of current block with static trees }\n    compressed_len : ulg; { total bit length of compressed file }\n    matches : uInt;       { number of string matches in current block }\n    last_eob_len : int;   { bit length of EOB code for last block }\n\n{$ifdef DEBUG}\n    bits_sent : ulg;    { bit length of the compressed data }\n{$endif}\n\n    bi_buf : ush;\n    { Output buffer. bits are inserted starting at the bottom (least\n      significant bits). }\n\n    bi_valid : int;\n    { Number of valid bits in bi_buf.  All bits above the last valid bit\n      are always zero. }\n\n    case byte of\n    0:(max_lazy_match : uInt);\n    { Attempt to find a better match only when the current match is strictly\n      smaller than this value. This mechanism is used only for compression\n      levels >= 4. }\n\n    1:(max_insert_length : uInt);\n    { Insert new strings in the hash table only if the match length is not\n      greater than this length. This saves time but degrades compression.\n      max_insert_length is used only for compression levels <= 3. }\n  end;\n\nprocedure _tr_init (var s : deflate_state);\n\nfunction _tr_tally (var s : deflate_state;\n                    dist : unsigned;\n                    lc : unsigned) : boolean;\n\nfunction _tr_flush_block (var s : deflate_state;\n                          buf : pcharf;\n                          stored_len : ulg;\n\t\t\t  eof : boolean) : ulg;\n\nprocedure _tr_align(var s : deflate_state);\n\nprocedure _tr_stored_block(var s : deflate_state;\n                           buf : pcharf;\n                           stored_len : ulg;\n                           eof : boolean);\n\nimplementation\n\n{ #define GEN_TREES_H }\n\n{$ifndef GEN_TREES_H}\n{ header created automatically with -DGEN_TREES_H }\n\nconst\n  DIST_CODE_LEN = 512; { see definition of array dist_code below }\n\n{ The static literal tree. Since the bit lengths are imposed, there is no\n  need for the L_CODES extra codes used during heap construction. However\n  The codes 286 and 287 are needed to build a canonical tree (see _tr_init\n  below). }\nvar\n  static_ltree : array[0..L_CODES+2-1] of ct_data = (\n{ fc:(freq, code) dl:(dad,len) }\n(fc:(freq: 12);dl:(len: 8)), (fc:(freq:140);dl:(len: 8)), (fc:(freq: 76);dl:(len: 8)),\n(fc:(freq:204);dl:(len: 8)), (fc:(freq: 44);dl:(len: 8)), (fc:(freq:172);dl:(len: 8)),\n(fc:(freq:108);dl:(len: 8)), (fc:(freq:236);dl:(len: 8)), (fc:(freq: 28);dl:(len: 8)),\n(fc:(freq:156);dl:(len: 8)), (fc:(freq: 92);dl:(len: 8)), (fc:(freq:220);dl:(len: 8)),\n(fc:(freq: 60);dl:(len: 8)), (fc:(freq:188);dl:(len: 8)), (fc:(freq:124);dl:(len: 8)),\n(fc:(freq:252);dl:(len: 8)), (fc:(freq:  2);dl:(len: 8)), (fc:(freq:130);dl:(len: 8)),\n(fc:(freq: 66);dl:(len: 8)), (fc:(freq:194);dl:(len: 8)), (fc:(freq: 34);dl:(len: 8)),\n(fc:(freq:162);dl:(len: 8)), (fc:(freq: 98);dl:(len: 8)), (fc:(freq:226);dl:(len: 8)),\n(fc:(freq: 18);dl:(len: 8)), (fc:(freq:146);dl:(len: 8)), (fc:(freq: 82);dl:(len: 8)),\n(fc:(freq:210);dl:(len: 8)), (fc:(freq: 50);dl:(len: 8)), (fc:(freq:178);dl:(len: 8)),\n(fc:(freq:114);dl:(len: 8)), (fc:(freq:242);dl:(len: 8)), (fc:(freq: 10);dl:(len: 8)),\n(fc:(freq:138);dl:(len: 8)), (fc:(freq: 74);dl:(len: 8)), (fc:(freq:202);dl:(len: 8)),\n(fc:(freq: 42);dl:(len: 8)), (fc:(freq:170);dl:(len: 8)), (fc:(freq:106);dl:(len: 8)),\n(fc:(freq:234);dl:(len: 8)), (fc:(freq: 26);dl:(len: 8)), (fc:(freq:154);dl:(len: 8)),\n(fc:(freq: 90);dl:(len: 8)), (fc:(freq:218);dl:(len: 8)), (fc:(freq: 58);dl:(len: 8)),\n(fc:(freq:186);dl:(len: 8)), (fc:(freq:122);dl:(len: 8)), (fc:(freq:250);dl:(len: 8)),\n(fc:(freq:  6);dl:(len: 8)), (fc:(freq:134);dl:(len: 8)), (fc:(freq: 70);dl:(len: 8)),\n(fc:(freq:198);dl:(len: 8)), (fc:(freq: 38);dl:(len: 8)), (fc:(freq:166);dl:(len: 8)),\n(fc:(freq:102);dl:(len: 8)), (fc:(freq:230);dl:(len: 8)), (fc:(freq: 22);dl:(len: 8)),\n(fc:(freq:150);dl:(len: 8)), (fc:(freq: 86);dl:(len: 8)), (fc:(freq:214);dl:(len: 8)),\n(fc:(freq: 54);dl:(len: 8)), (fc:(freq:182);dl:(len: 8)), (fc:(freq:118);dl:(len: 8)),\n(fc:(freq:246);dl:(len: 8)), (fc:(freq: 14);dl:(len: 8)), (fc:(freq:142);dl:(len: 8)),\n(fc:(freq: 78);dl:(len: 8)), (fc:(freq:206);dl:(len: 8)), (fc:(freq: 46);dl:(len: 8)),\n(fc:(freq:174);dl:(len: 8)), (fc:(freq:110);dl:(len: 8)), (fc:(freq:238);dl:(len: 8)),\n(fc:(freq: 30);dl:(len: 8)), (fc:(freq:158);dl:(len: 8)), (fc:(freq: 94);dl:(len: 8)),\n(fc:(freq:222);dl:(len: 8)), (fc:(freq: 62);dl:(len: 8)), (fc:(freq:190);dl:(len: 8)),\n(fc:(freq:126);dl:(len: 8)), (fc:(freq:254);dl:(len: 8)), (fc:(freq:  1);dl:(len: 8)),\n(fc:(freq:129);dl:(len: 8)), (fc:(freq: 65);dl:(len: 8)), (fc:(freq:193);dl:(len: 8)),\n(fc:(freq: 33);dl:(len: 8)), (fc:(freq:161);dl:(len: 8)), (fc:(freq: 97);dl:(len: 8)),\n(fc:(freq:225);dl:(len: 8)), (fc:(freq: 17);dl:(len: 8)), (fc:(freq:145);dl:(len: 8)),\n(fc:(freq: 81);dl:(len: 8)), (fc:(freq:209);dl:(len: 8)), (fc:(freq: 49);dl:(len: 8)),\n(fc:(freq:177);dl:(len: 8)), (fc:(freq:113);dl:(len: 8)), (fc:(freq:241);dl:(len: 8)),\n(fc:(freq:  9);dl:(len: 8)), (fc:(freq:137);dl:(len: 8)), (fc:(freq: 73);dl:(len: 8)),\n(fc:(freq:201);dl:(len: 8)), (fc:(freq: 41);dl:(len: 8)), (fc:(freq:169);dl:(len: 8)),\n(fc:(freq:105);dl:(len: 8)), (fc:(freq:233);dl:(len: 8)), (fc:(freq: 25);dl:(len: 8)),\n(fc:(freq:153);dl:(len: 8)), (fc:(freq: 89);dl:(len: 8)), (fc:(freq:217);dl:(len: 8)),\n(fc:(freq: 57);dl:(len: 8)), (fc:(freq:185);dl:(len: 8)), (fc:(freq:121);dl:(len: 8)),\n(fc:(freq:249);dl:(len: 8)), (fc:(freq:  5);dl:(len: 8)), (fc:(freq:133);dl:(len: 8)),\n(fc:(freq: 69);dl:(len: 8)), (fc:(freq:197);dl:(len: 8)), (fc:(freq: 37);dl:(len: 8)),\n(fc:(freq:165);dl:(len: 8)), (fc:(freq:101);dl:(len: 8)), (fc:(freq:229);dl:(len: 8)),\n(fc:(freq: 21);dl:(len: 8)), (fc:(freq:149);dl:(len: 8)), (fc:(freq: 85);dl:(len: 8)),\n(fc:(freq:213);dl:(len: 8)), (fc:(freq: 53);dl:(len: 8)), (fc:(freq:181);dl:(len: 8)),\n(fc:(freq:117);dl:(len: 8)), (fc:(freq:245);dl:(len: 8)), (fc:(freq: 13);dl:(len: 8)),\n(fc:(freq:141);dl:(len: 8)), (fc:(freq: 77);dl:(len: 8)), (fc:(freq:205);dl:(len: 8)),\n(fc:(freq: 45);dl:(len: 8)), (fc:(freq:173);dl:(len: 8)), (fc:(freq:109);dl:(len: 8)),\n(fc:(freq:237);dl:(len: 8)), (fc:(freq: 29);dl:(len: 8)), (fc:(freq:157);dl:(len: 8)),\n(fc:(freq: 93);dl:(len: 8)), (fc:(freq:221);dl:(len: 8)), (fc:(freq: 61);dl:(len: 8)),\n(fc:(freq:189);dl:(len: 8)), (fc:(freq:125);dl:(len: 8)), (fc:(freq:253);dl:(len: 8)),\n(fc:(freq: 19);dl:(len: 9)), (fc:(freq:275);dl:(len: 9)), (fc:(freq:147);dl:(len: 9)),\n(fc:(freq:403);dl:(len: 9)), (fc:(freq: 83);dl:(len: 9)), (fc:(freq:339);dl:(len: 9)),\n(fc:(freq:211);dl:(len: 9)), (fc:(freq:467);dl:(len: 9)), (fc:(freq: 51);dl:(len: 9)),\n(fc:(freq:307);dl:(len: 9)), (fc:(freq:179);dl:(len: 9)), (fc:(freq:435);dl:(len: 9)),\n(fc:(freq:115);dl:(len: 9)), (fc:(freq:371);dl:(len: 9)), (fc:(freq:243);dl:(len: 9)),\n(fc:(freq:499);dl:(len: 9)), (fc:(freq: 11);dl:(len: 9)), (fc:(freq:267);dl:(len: 9)),\n(fc:(freq:139);dl:(len: 9)), (fc:(freq:395);dl:(len: 9)), (fc:(freq: 75);dl:(len: 9)),\n(fc:(freq:331);dl:(len: 9)), (fc:(freq:203);dl:(len: 9)), (fc:(freq:459);dl:(len: 9)),\n(fc:(freq: 43);dl:(len: 9)), (fc:(freq:299);dl:(len: 9)), (fc:(freq:171);dl:(len: 9)),\n(fc:(freq:427);dl:(len: 9)), (fc:(freq:107);dl:(len: 9)), (fc:(freq:363);dl:(len: 9)),\n(fc:(freq:235);dl:(len: 9)), (fc:(freq:491);dl:(len: 9)), (fc:(freq: 27);dl:(len: 9)),\n(fc:(freq:283);dl:(len: 9)), (fc:(freq:155);dl:(len: 9)), (fc:(freq:411);dl:(len: 9)),\n(fc:(freq: 91);dl:(len: 9)), (fc:(freq:347);dl:(len: 9)), (fc:(freq:219);dl:(len: 9)),\n(fc:(freq:475);dl:(len: 9)), (fc:(freq: 59);dl:(len: 9)), (fc:(freq:315);dl:(len: 9)),\n(fc:(freq:187);dl:(len: 9)), (fc:(freq:443);dl:(len: 9)), (fc:(freq:123);dl:(len: 9)),\n(fc:(freq:379);dl:(len: 9)), (fc:(freq:251);dl:(len: 9)), (fc:(freq:507);dl:(len: 9)),\n(fc:(freq:  7);dl:(len: 9)), (fc:(freq:263);dl:(len: 9)), (fc:(freq:135);dl:(len: 9)),\n(fc:(freq:391);dl:(len: 9)), (fc:(freq: 71);dl:(len: 9)), (fc:(freq:327);dl:(len: 9)),\n(fc:(freq:199);dl:(len: 9)), (fc:(freq:455);dl:(len: 9)), (fc:(freq: 39);dl:(len: 9)),\n(fc:(freq:295);dl:(len: 9)), (fc:(freq:167);dl:(len: 9)), (fc:(freq:423);dl:(len: 9)),\n(fc:(freq:103);dl:(len: 9)), (fc:(freq:359);dl:(len: 9)), (fc:(freq:231);dl:(len: 9)),\n(fc:(freq:487);dl:(len: 9)), (fc:(freq: 23);dl:(len: 9)), (fc:(freq:279);dl:(len: 9)),\n(fc:(freq:151);dl:(len: 9)), (fc:(freq:407);dl:(len: 9)), (fc:(freq: 87);dl:(len: 9)),\n(fc:(freq:343);dl:(len: 9)), (fc:(freq:215);dl:(len: 9)), (fc:(freq:471);dl:(len: 9)),\n(fc:(freq: 55);dl:(len: 9)), (fc:(freq:311);dl:(len: 9)), (fc:(freq:183);dl:(len: 9)),\n(fc:(freq:439);dl:(len: 9)), (fc:(freq:119);dl:(len: 9)), (fc:(freq:375);dl:(len: 9)),\n(fc:(freq:247);dl:(len: 9)), (fc:(freq:503);dl:(len: 9)), (fc:(freq: 15);dl:(len: 9)),\n(fc:(freq:271);dl:(len: 9)), (fc:(freq:143);dl:(len: 9)), (fc:(freq:399);dl:(len: 9)),\n(fc:(freq: 79);dl:(len: 9)), (fc:(freq:335);dl:(len: 9)), (fc:(freq:207);dl:(len: 9)),\n(fc:(freq:463);dl:(len: 9)), (fc:(freq: 47);dl:(len: 9)), (fc:(freq:303);dl:(len: 9)),\n(fc:(freq:175);dl:(len: 9)), (fc:(freq:431);dl:(len: 9)), (fc:(freq:111);dl:(len: 9)),\n(fc:(freq:367);dl:(len: 9)), (fc:(freq:239);dl:(len: 9)), (fc:(freq:495);dl:(len: 9)),\n(fc:(freq: 31);dl:(len: 9)), (fc:(freq:287);dl:(len: 9)), (fc:(freq:159);dl:(len: 9)),\n(fc:(freq:415);dl:(len: 9)), (fc:(freq: 95);dl:(len: 9)), (fc:(freq:351);dl:(len: 9)),\n(fc:(freq:223);dl:(len: 9)), (fc:(freq:479);dl:(len: 9)), (fc:(freq: 63);dl:(len: 9)),\n(fc:(freq:319);dl:(len: 9)), (fc:(freq:191);dl:(len: 9)), (fc:(freq:447);dl:(len: 9)),\n(fc:(freq:127);dl:(len: 9)), (fc:(freq:383);dl:(len: 9)), (fc:(freq:255);dl:(len: 9)),\n(fc:(freq:511);dl:(len: 9)), (fc:(freq:  0);dl:(len: 7)), (fc:(freq: 64);dl:(len: 7)),\n(fc:(freq: 32);dl:(len: 7)), (fc:(freq: 96);dl:(len: 7)), (fc:(freq: 16);dl:(len: 7)),\n(fc:(freq: 80);dl:(len: 7)), (fc:(freq: 48);dl:(len: 7)), (fc:(freq:112);dl:(len: 7)),\n(fc:(freq:  8);dl:(len: 7)), (fc:(freq: 72);dl:(len: 7)), (fc:(freq: 40);dl:(len: 7)),\n(fc:(freq:104);dl:(len: 7)), (fc:(freq: 24);dl:(len: 7)), (fc:(freq: 88);dl:(len: 7)),\n(fc:(freq: 56);dl:(len: 7)), (fc:(freq:120);dl:(len: 7)), (fc:(freq:  4);dl:(len: 7)),\n(fc:(freq: 68);dl:(len: 7)), (fc:(freq: 36);dl:(len: 7)), (fc:(freq:100);dl:(len: 7)),\n(fc:(freq: 20);dl:(len: 7)), (fc:(freq: 84);dl:(len: 7)), (fc:(freq: 52);dl:(len: 7)),\n(fc:(freq:116);dl:(len: 7)), (fc:(freq:  3);dl:(len: 8)), (fc:(freq:131);dl:(len: 8)),\n(fc:(freq: 67);dl:(len: 8)), (fc:(freq:195);dl:(len: 8)), (fc:(freq: 35);dl:(len: 8)),\n(fc:(freq:163);dl:(len: 8)), (fc:(freq: 99);dl:(len: 8)), (fc:(freq:227);dl:(len: 8))\n);\n\n\n{ The static distance tree. (Actually a trivial tree since all lens use\n  5 bits.) }\n  static_dtree : array[0..D_CODES-1] of ct_data = (\n(fc:(freq: 0); dl:(len:5)), (fc:(freq:16); dl:(len:5)), (fc:(freq: 8); dl:(len:5)),\n(fc:(freq:24); dl:(len:5)), (fc:(freq: 4); dl:(len:5)), (fc:(freq:20); dl:(len:5)),\n(fc:(freq:12); dl:(len:5)), (fc:(freq:28); dl:(len:5)), (fc:(freq: 2); dl:(len:5)),\n(fc:(freq:18); dl:(len:5)), (fc:(freq:10); dl:(len:5)), (fc:(freq:26); dl:(len:5)),\n(fc:(freq: 6); dl:(len:5)), (fc:(freq:22); dl:(len:5)), (fc:(freq:14); dl:(len:5)),\n(fc:(freq:30); dl:(len:5)), (fc:(freq: 1); dl:(len:5)), (fc:(freq:17); dl:(len:5)),\n(fc:(freq: 9); dl:(len:5)), (fc:(freq:25); dl:(len:5)), (fc:(freq: 5); dl:(len:5)),\n(fc:(freq:21); dl:(len:5)), (fc:(freq:13); dl:(len:5)), (fc:(freq:29); dl:(len:5)),\n(fc:(freq: 3); dl:(len:5)), (fc:(freq:19); dl:(len:5)), (fc:(freq:11); dl:(len:5)),\n(fc:(freq:27); dl:(len:5)), (fc:(freq: 7); dl:(len:5)), (fc:(freq:23); dl:(len:5))\n);\n\n{ Distance codes. The first 256 values correspond to the distances\n  3 .. 258, the last 256 values correspond to the top 8 bits of\n  the 15 bit distances. }\n  _dist_code : array[0..DIST_CODE_LEN-1] of uch = (\n 0,  1,  2,  3,  4,  4,  5,  5,  6,  6,  6,  6,  7,  7,  7,  7,  8,  8,  8,  8,\n 8,  8,  8,  8,  9,  9,  9,  9,  9,  9,  9,  9, 10, 10, 10, 10, 10, 10, 10, 10,\n10, 10, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,\n11, 11, 11, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,\n12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 13, 13, 13, 13,\n13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,\n13, 13, 13, 13, 13, 13, 13, 13, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,\n14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,\n14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,\n14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 15, 15, 15, 15, 15, 15, 15, 15,\n15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,\n15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,\n15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,  0,  0, 16, 17,\n18, 18, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 22, 22, 22, 22, 22, 22, 22, 22,\n23, 23, 23, 23, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,\n24, 24, 24, 24, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,\n26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26,\n26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27,\n27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,\n27, 27, 27, 27, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28,\n28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28,\n28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28,\n28, 28, 28, 28, 28, 28, 28, 28, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,\n29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,\n29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,\n29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29\n);\n\n{ length code for each normalized match length (0 == MIN_MATCH) }\n  _length_code : array[0..MAX_MATCH-MIN_MATCH+1-1] of uch = (\n 0,  1,  2,  3,  4,  5,  6,  7,  8,  8,  9,  9, 10, 10, 11, 11, 12, 12, 12, 12,\n13, 13, 13, 13, 14, 14, 14, 14, 15, 15, 15, 15, 16, 16, 16, 16, 16, 16, 16, 16,\n17, 17, 17, 17, 17, 17, 17, 17, 18, 18, 18, 18, 18, 18, 18, 18, 19, 19, 19, 19,\n19, 19, 19, 19, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,\n21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 22, 22, 22, 22,\n22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 23, 23, 23, 23, 23, 23, 23, 23,\n23, 23, 23, 23, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,\n24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,\n25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,\n25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 26, 26, 26, 26, 26, 26, 26, 26,\n26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26,\n26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,\n27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 28\n);\n\n  \n{ First normalized length for each code (0 = MIN_MATCH) }\n  base_length : array[0..LENGTH_CODES-1] of int = (\n0, 1, 2, 3, 4, 5, 6, 7, 8, 10, 12, 14, 16, 20, 24, 28, 32, 40, 48, 56,\n64, 80, 96, 112, 128, 160, 192, 224, 0\n);\n\n\n{ First normalized distance for each code (0 = distance of 1) }\n  base_dist : array[0..D_CODES-1] of int = (\n    0,     1,     2,     3,     4,     6,     8,    12,    16,    24,\n   32,    48,    64,    96,   128,   192,   256,   384,   512,   768,\n 1024,  1536,  2048,  3072,  4096,  6144,  8192, 12288, 16384, 24576\n);\n{$endif}\n\n{ Output a byte on the stream.\n  IN assertion: there is enough room in pending_buf.\nmacro put_byte(s, c)\nbegin\n  s^.pending_buf^[s^.pending] := (c);\n  Inc(s^.pending);\nend\n}\n\nconst\n  MIN_LOOKAHEAD = (MAX_MATCH+MIN_MATCH+1);\n{ Minimum amount of lookahead, except at the end of the input file.\n  See deflate.c for comments about the MIN_MATCH+1. }\n\n{macro d_code(dist)\n   if (dist) < 256 then\n     := _dist_code[dist]\n   else\n     := _dist_code[256+((dist) shr 7)]);\n  Mapping from a distance to a distance code. dist is the distance - 1 and\n  must not have side effects. _dist_code[256] and _dist_code[257] are never\n  used. }\n\n{$ifndef ORG_DEBUG}\n{ Inline versions of _tr_tally for speed: }\n\n#if defined(GEN_TREES_H) || !defined(STDC)\n  extern uch _length_code[];\n  extern uch _dist_code[];\n#else\n  extern const uch _length_code[];\n  extern const uch _dist_code[];\n#endif\n\nmacro _tr_tally_lit(s, c, flush)\nvar\n  cc : uch;\nbegin\n    cc := (c);\n    s^.d_buf[s^.last_lit] := 0;\n    s^.l_buf[s^.last_lit] := cc;\n    Inc(s^.last_lit);\n    Inc(s^.dyn_ltree[cc].fc.Freq);\n    flush := (s^.last_lit = s^.lit_bufsize-1);\nend;\n\nmacro _tr_tally_dist(s, distance, length, flush) \\\nvar\n  len : uch;\n  dist : ush;\nbegin\n    len := (length);\n    dist := (distance);\n    s^.d_buf[s^.last_lit] := dist;\n    s^.l_buf[s^.last_lit] = len;\n    Inc(s^.last_lit);\n    Dec(dist);\n    Inc(s^.dyn_ltree[_length_code[len]+LITERALS+1].fc.Freq);\n    Inc(s^.dyn_dtree[d_code(dist)].Freq);\n    flush := (s^.last_lit = s^.lit_bufsize-1);\nend;\n\n{$endif}\n\n{ ===========================================================================\n  Constants }\n\nconst\n  MAX_BL_BITS = 7;\n{ Bit length codes must not exceed MAX_BL_BITS bits }\n\nconst\n  END_BLOCK = 256;\n{ end of block literal code }\n\nconst\n  REP_3_6 = 16;\n{ repeat previous bit length 3-6 times (2 bits of repeat count) }\n\nconst\n  REPZ_3_10 = 17;\n{ repeat a zero length 3-10 times  (3 bits of repeat count) }\n\nconst\n  REPZ_11_138 = 18;\n{ repeat a zero length 11-138 times  (7 bits of repeat count) }\n\n{local}\nconst\n  extra_lbits : array[0..LENGTH_CODES-1] of int\n    { extra bits for each length code }\n   = (0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0);\n\n{local}\nconst\n  extra_dbits : array[0..D_CODES-1] of int\n    { extra bits for each distance code }\n   = (0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13);\n\n{local}\nconst\n  extra_blbits : array[0..BL_CODES-1] of int { extra bits for each bit length code }\n   = (0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,3,7);\n\n{local}\nconst\n  bl_order : array[0..BL_CODES-1] of uch\n   = (16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15);\n{ The lengths of the bit length codes are sent in order of decreasing\n  probability, to avoid transmitting the lengths for unused bit length codes.\n }\n\nconst\n  Buf_size = (8 * 2*sizeof(uch));\n{ Number of bits used within bi_buf. (bi_buf might be implemented on\n  more than 16 bits on some systems.) }\n\n{ ===========================================================================\n  Local data. These are initialized only once. }\n\n\n{$ifdef GEN_TREES_H)}\n{ non ANSI compilers may not accept trees.h }\n\nconst\n  DIST_CODE_LEN = 512; { see definition of array dist_code below }\n\n{local}\nvar\n  static_ltree : array[0..L_CODES+2-1] of ct_data;\n{ The static literal tree. Since the bit lengths are imposed, there is no\n  need for the L_CODES extra codes used during heap construction. However\n  The codes 286 and 287 are needed to build a canonical tree (see _tr_init\n  below). }\n\n{local}\n  static_dtree : array[0..D_CODES-1] of ct_data;\n{ The static distance tree. (Actually a trivial tree since all codes use\n  5 bits.) }\n\n  _dist_code : array[0..DIST_CODE_LEN-1] of uch;\n{ Distance codes. The first 256 values correspond to the distances\n  3 .. 258, the last 256 values correspond to the top 8 bits of\n  the 15 bit distances. }\n\n  _length_code : array[0..MAX_MATCH-MIN_MATCH+1-1] of uch;\n{ length code for each normalized match length (0 == MIN_MATCH) }\n\n{local}\n  base_length : array[0..LENGTH_CODES-1] of int;\n{ First normalized length for each code (0 = MIN_MATCH) }\n\n{local}\n  base_dist : array[0..D_CODES-1] of int;\n{ First normalized distance for each code (0 = distance of 1) }\n\n{$endif} { GEN_TREES_H }\n\n{local}\nconst\n  static_l_desc :  static_tree_desc  =\n      (static_tree: {tree_ptr}(@(static_ltree));  { pointer to array of ct_data }\n       extra_bits: {pzIntfArray}(@(extra_lbits)); { pointer to array of int }\n       extra_base: LITERALS+1;\n       elems: L_CODES;\n       max_length: MAX_BITS);\n\n{local}\nconst\n  static_d_desc : static_tree_desc  =\n      (static_tree: {tree_ptr}(@(static_dtree));\n       extra_bits: {pzIntfArray}(@(extra_dbits));\n       extra_base : 0;\n       elems: D_CODES;\n       max_length: MAX_BITS);\n\n{local}\nconst\n  static_bl_desc : static_tree_desc =\n      (static_tree: {tree_ptr}(NIL);\n       extra_bits: {pzIntfArray}@(extra_blbits);\n       extra_base : 0;\n       elems: BL_CODES;\n       max_length: MAX_BL_BITS);\n\n(* ===========================================================================\n  Local (static) routines in this file. }\n\nprocedure tr_static_init;\nprocedure init_block(var deflate_state);\nprocedure pqdownheap(var s : deflate_state;\n                     var tree : ct_data;\n                     k : int);\nprocedure gen_bitlen(var s : deflate_state;\n                     var desc : tree_desc);\nprocedure gen_codes(var tree : ct_data;\n                    max_code : int;\n                    bl_count : pushf);\nprocedure build_tree(var s : deflate_state;\n                     var desc : tree_desc);\nprocedure scan_tree(var s : deflate_state;\n                    var tree : ct_data;\n                    max_code : int);\nprocedure send_tree(var s : deflate_state;\n                    var tree : ct_data;\n                    max_code : int);\nfunction build_bl_tree(var deflate_state) : int;\nprocedure send_all_trees(var deflate_state;\n                         lcodes : int;\n                         dcodes : int;\n                         blcodes : int);\nprocedure compress_block(var s : deflate_state;\n                         var ltree : ct_data;\n                         var dtree : ct_data);\nprocedure set_data_type(var s : deflate_state);\nfunction bi_reverse(value : unsigned;\n                    length : int) : unsigned;\nprocedure bi_windup(var deflate_state);\nprocedure bi_flush(var deflate_state);\nprocedure copy_block(var deflate_state;\n                     buf : pcharf;\n                     len : unsigned;\n                     header : int);\n*)\n\n{$ifdef GEN_TREES_H}\n{local}\nprocedure gen_trees_header;\n{$endif}\n\n(*\n{ ===========================================================================\n  Output a short LSB first on the stream.\n  IN assertion: there is enough room in pendingBuf. }\n\nmacro put_short(s, w)\nbegin\n    {put_byte(s, (uch)((w) & 0xff));}\n    s.pending_buf^[s.pending] := uch((w) and $ff);\n    Inc(s.pending);\n\n    {put_byte(s, (uch)((ush)(w) >> 8));}\n    s.pending_buf^[s.pending] := uch(ush(w) shr 8);;\n    Inc(s.pending);\nend\n*)\n\n{ ===========================================================================\n  Send a value on a given number of bits.\n  IN assertion: length <= 16 and value fits in length bits. }\n\n{$ifdef ORG_DEBUG}\n\n{local}\nprocedure send_bits(var s : deflate_state;\n                    value : int;   { value to send }\n                    length : int); { number of bits }\nbegin\n  {$ifdef DEBUG}\n  Tracevv(' l '+IntToStr(length)+ ' v '+IntToStr(value));\n  Assert((length > 0) and (length <= 15), 'invalid length');\n  Inc(s.bits_sent, ulg(length));\n  {$ENDIF}\n\n  { If not enough room in bi_buf, use (valid) bits from bi_buf and\n    (16 - bi_valid) bits from value, leaving (width - (16-bi_valid))\n    unused bits in value. }\n  {$IFOPT Q+} {$Q-} {$DEFINE NoOverflowCheck} {$ENDIF}\n  {$IFOPT R+} {$R-} {$DEFINE NoRangeCheck} {$ENDIF}\n  if (s.bi_valid > int(Buf_size) - length) then\n  begin\n    s.bi_buf := s.bi_buf or int(value shl s.bi_valid);\n    {put_short(s, s.bi_buf);}\n    s.pending_buf^[s.pending] := uch(s.bi_buf and $ff);\n    Inc(s.pending);\n    s.pending_buf^[s.pending] := uch(ush(s.bi_buf) shr 8);;\n    Inc(s.pending);\n\n    s.bi_buf := ush(value) shr (Buf_size - s.bi_valid);\n    Inc(s.bi_valid, length - Buf_size);\n  end\n  else\n  begin\n    s.bi_buf := s.bi_buf or int(value shl s.bi_valid);\n    Inc(s.bi_valid, length);\n  end;\n  {$IFDEF NoOverflowCheck} {$Q+} {$UNDEF NoOverflowCheck} {$ENDIF}\n  {$IFDEF NoRangeCheck} {$Q+} {$UNDEF NoRangeCheck} {$ENDIF}\nend;\n\n{$else} { !DEBUG }\n\n\nmacro send_code(s, c, tree)\nbegin\n  send_bits(s, tree[c].Code, tree[c].Len);\n  { Send a code of the given tree. c and tree must not have side effects }\nend\n\nmacro send_bits(s, value, length) \\\nbegin int len := length;\\\n  if (s^.bi_valid > (int)Buf_size - len) begin\\\n    int val := value;\\\n    s^.bi_buf |= (val << s^.bi_valid);\\\n    {put_short(s, s.bi_buf);}\n    s.pending_buf^[s.pending] := uch(s.bi_buf and $ff);\n    Inc(s.pending);\n    s.pending_buf^[s.pending] := uch(ush(s.bi_buf) shr 8);;\n    Inc(s.pending);\n\n    s^.bi_buf := (ush)val >> (Buf_size - s^.bi_valid);\\\n    s^.bi_valid += len - Buf_size;\\\n  end else begin\\\n    s^.bi_buf |= (value) << s^.bi_valid;\\\n    s^.bi_valid += len;\\\n  end\\\nend;\n{$endif} { DEBUG }\n\n{ ===========================================================================\n  Reverse the first len bits of a code, using straightforward code (a faster\n  method would use a table)\n  IN assertion: 1 <= len <= 15 }\n\n{local}\nfunction bi_reverse(code : unsigned;         { the value to invert }\n                    len : int) : unsigned;   { its bit length }\n\nvar\n  res : unsigned; {register}\nbegin\n  res := 0;\n  repeat\n    res := res or (code and 1);\n    code := code shr 1;\n    res := res shl 1;\n    Dec(len);\n  until (len <= 0);\n  bi_reverse := res shr 1;\nend;\n\n{ ===========================================================================\n  Generate the codes for a given tree and bit counts (which need not be\n  optimal).\n  IN assertion: the array bl_count contains the bit length statistics for\n  the given tree and the field len is set for all tree elements.\n  OUT assertion: the field code is set for all tree elements of non\n      zero code length. }\n\n{local}\nprocedure gen_codes(tree : tree_ptr;  { the tree to decorate }\n                    max_code : int;   { largest code with non zero frequency }\n                    var bl_count : array of ushf);  { number of codes at each bit length }\n\nvar\n  next_code : array[0..MAX_BITS+1-1] of ush; { next code value for each bit length }\n  code : ush;              { running code value }\n  bits : int;                  { bit index }\n  n : int;                     { code index }\nvar\n  len : int;\nbegin\n  code := 0;\n\n  { The distribution counts are first used to generate the code values\n    without bit reversal. }\n\n  for bits := 1 to MAX_BITS do\n  begin\n    code := ((code + bl_count[bits-1]) shl 1);\n    next_code[bits] := code;\n  end;\n  { Check that the bit counts in bl_count are consistent. The last code\n    must be all ones. }\n\n  {$IFDEF DEBUG}\n  Assert (code + bl_count[MAX_BITS]-1 = (1 shl MAX_BITS)-1,\n          'inconsistent bit counts');\n  Tracev(#13'gen_codes: max_code '+IntToStr(max_code));\n  {$ENDIF}\n\n  for n := 0 to max_code do\n  begin\n    len := tree^[n].dl.Len;\n    if (len = 0) then\n      continue;\n    { Now reverse the bits }\n    tree^[n].fc.Code := bi_reverse(next_code[len], len);\n    Inc(next_code[len]);\n    {$ifdef DEBUG}\n    if (n>31) and (n<128) then\n      Tracecv(tree <> tree_ptr(@static_ltree),\n       (^M'n #'+IntToStr(n)+' '+AnsiChar(n)+' l '+IntToStr(len)+' c '+\n         IntToStr(tree^[n].fc.Code)+' ('+IntToStr(next_code[len]-1)+')'))\n    else\n      Tracecv(tree <> tree_ptr(@static_ltree),\n      (^M'n #'+IntToStr(n)+'   l '+IntToStr(len)+' c '+\n         IntToStr(tree^[n].fc.Code)+' ('+IntToStr(next_code[len]-1)+')'));\n    {$ENDIF}\n  end;\nend;\n\n{ ===========================================================================\n  Genererate the file trees.h describing the static trees. }\n{$ifdef GEN_TREES_H}\n\nmacro SEPARATOR(i, last, width)\n  if (i) = (last) then\n    ( ^M');'^M^M\n  else    \\\n    if (i) mod (width) = (width)-1 then\n       ','^M\n     else\n       ', '\n\nprocedure gen_trees_header;\nvar\n  header : system.text;\n  i : int;\nbegin\n  system.assign(header, 'trees.inc');\n  {$I-}\n  ReWrite(header);\n  {$I+}\n  Assert (IOresult <> 0, 'Can''t open trees.h');\n  WriteLn(header,\n    '{ header created automatically with -DGEN_TREES_H }'^M);\n\n  WriteLn(header, 'local const ct_data static_ltree[L_CODES+2] := (');\n  for i := 0 to L_CODES+2-1 do\n  begin\n    WriteLn(header, '((%3u),(%3u))%s', static_ltree[i].Code,\n\t\tstatic_ltree[i].Len, SEPARATOR(i, L_CODES+1, 5));\n  end;\n\n  WriteLn(header, 'local const ct_data static_dtree[D_CODES] := (');\n  for i := 0 to D_CODES-1 do\n  begin\n    WriteLn(header, '((%2u),(%2u))%s', static_dtree[i].Code,\n\t\tstatic_dtree[i].Len, SEPARATOR(i, D_CODES-1, 5));\n  end;\n\n  WriteLn(header, 'const uch _dist_code[DIST_CODE_LEN] := (');\n  for i := 0 to DIST_CODE_LEN-1 do\n  begin\n    WriteLn(header, '%2u%s', _dist_code[i],\n\t\tSEPARATOR(i, DIST_CODE_LEN-1, 20));\n  end;\n\n  WriteLn(header, 'const uch _length_code[MAX_MATCH-MIN_MATCH+1]= (');\n  for i := 0 to MAX_MATCH-MIN_MATCH+1-1 do\n  begin\n    WriteLn(header, '%2u%s', _length_code[i],\n\t\tSEPARATOR(i, MAX_MATCH-MIN_MATCH, 20));\n  end;\n\n  WriteLn(header, 'local const int base_length[LENGTH_CODES] := (');\n  for i := 0 to LENGTH_CODES-1 do\n  begin\n    WriteLn(header, '%1u%s', base_length[i],\n\t\tSEPARATOR(i, LENGTH_CODES-1, 20));\n  end;\n\n  WriteLn(header, 'local const int base_dist[D_CODES] := (');\n  for i := 0 to D_CODES-1 do\n  begin\n    WriteLn(header, '%5u%s', base_dist[i],\n\t\tSEPARATOR(i, D_CODES-1, 10));\n  end;\n\n  close(header);\nend;\n{$endif} { GEN_TREES_H }\n\n\n{ ===========================================================================\n  Initialize the various 'constant' tables. }\n\n{local}\nprocedure tr_static_init;\n\n{$ifdef GEN_TREES_H}\nconst\n  static_init_done : boolean = FALSE;\nvar\n  n : int;        { iterates over tree elements }\n  bits : int;     { bit counter }\n  length : int;   { length value }\n  code : int;     { code value }\n  dist : int;     { distance index }\n  bl_count : array[0..MAX_BITS+1-1] of ush;\n    { number of codes at each bit length for an optimal tree }\nbegin\n    if (static_init_done) then\n      exit;\n\n    { Initialize the mapping length (0..255) -> length code (0..28) }\n    length := 0;\n    for code := 0 to LENGTH_CODES-1-1 do\n    begin\n      base_length[code] := length;\n      for n := 0 to (1 shl extra_lbits[code])-1 do\n      begin\n        _length_code[length] := uch(code);\n        Inc(length);\n      end;\n    end;\n    Assert (length = 256, 'tr_static_init: length <> 256');\n    { Note that the length 255 (match length 258) can be represented\n      in two different ways: code 284 + 5 bits or code 285, so we\n      overwrite length_code[255] to use the best encoding: }\n\n    _length_code[length-1] := uch(code);\n\n    { Initialize the mapping dist (0..32K) -> dist code (0..29) }\n    dist := 0;\n    for code := 0 to 16-1 do\n    begin\n      base_dist[code] := dist;\n      for n := 0 to (1 shl extra_dbits[code])-1 do\n      begin\n        _dist_code[dist] := uch(code);\n        Inc(dist);\n      end;\n    end;\n    Assert (dist = 256, 'tr_static_init: dist <> 256');\n    dist := dist shr 7; { from now on, all distances are divided by 128 }\n    for code := 16 to D_CODES-1 do\n    begin\n      base_dist[code] := dist shl 7;\n      for n := 0 to (1 shl (extra_dbits[code]-7))-1 do\n      begin\n        _dist_code[256 + dist] := uch(code);\n        Inc(dist);\n      end;\n    end;\n    Assert (dist = 256, 'tr_static_init: 256+dist <> 512');\n\n    { Construct the codes of the static literal tree }\n    for bits := 0 to MAX_BITS do\n      bl_count[bits] := 0;\n    n := 0;\n    while (n <= 143) do\n    begin\n      static_ltree[n].dl.Len := 8;\n      Inc(n);\n      Inc(bl_count[8]);\n    end;\n    while (n <= 255) do\n    begin\n      static_ltree[n].dl.Len := 9;\n      Inc(n);\n      Inc(bl_count[9]);\n    end;\n    while (n <= 279) do\n    begin\n      static_ltree[n].dl.Len := 7;\n      Inc(n);\n      Inc(bl_count[7]);\n    end;\n    while (n <= 287) do\n    begin\n      static_ltree[n].dl.Len := 8;\n      Inc(n);\n      Inc(bl_count[8]);\n    end;\n\n    { Codes 286 and 287 do not exist, but we must include them in the\n      tree construction to get a canonical Huffman tree (longest code\n      all ones)  }\n\n    gen_codes(tree_ptr(@static_ltree), L_CODES+1, bl_count);\n\n    { The static distance tree is trivial: }\n    for n := 0 to D_CODES-1 do\n    begin\n      static_dtree[n].dl.Len := 5;\n      static_dtree[n].fc.Code := bi_reverse(unsigned(n), 5);\n    end;\n    static_init_done := TRUE;\n\n    gen_trees_header;  { save to include file }\n{$else}\nbegin\n{$endif} { GEN_TREES_H) }\nend;\n\n{ ===========================================================================\n  Initialize a new block. }\n{local}\n\nprocedure init_block(var s : deflate_state);\nvar\n  n : int; { iterates over tree elements }\nbegin\n  { Initialize the trees. }\n  for n := 0 to L_CODES-1 do\n    s.dyn_ltree[n].fc.Freq := 0;\n  for n := 0 to D_CODES-1 do\n    s.dyn_dtree[n].fc.Freq := 0;\n  for n := 0 to BL_CODES-1 do\n    s.bl_tree[n].fc.Freq := 0;\n\n  s.dyn_ltree[END_BLOCK].fc.Freq := 1;\n  s.static_len := Long(0);\n  s.opt_len := Long(0);\n  s.matches := 0;\n  s.last_lit := 0;\nend;\n\nconst\n  SMALLEST = 1;\n{ Index within the heap array of least frequent node in the Huffman tree }\n\n{ ===========================================================================\n  Initialize the tree data structures for a new zlib stream. }\nprocedure _tr_init(var s : deflate_state);\nbegin\n  tr_static_init;\n\n  s.compressed_len := Long(0);\n\n  s.l_desc.dyn_tree := tree_ptr(@s.dyn_ltree);\n  s.l_desc.stat_desc := @static_l_desc;\n\n  s.d_desc.dyn_tree := tree_ptr(@s.dyn_dtree);\n  s.d_desc.stat_desc := @static_d_desc;\n\n  s.bl_desc.dyn_tree := tree_ptr(@s.bl_tree);\n  s.bl_desc.stat_desc := @static_bl_desc;\n\n  s.bi_buf := 0;\n  s.bi_valid := 0;\n  s.last_eob_len := 8; { enough lookahead for inflate }\n{$ifdef DEBUG}\n  s.bits_sent := Long(0);\n{$endif}\n\n  { Initialize the first block of the first file: }\n  init_block(s);\nend;\n\n{ ===========================================================================\n  Remove the smallest element from the heap and recreate the heap with\n  one less element. Updates heap and heap_len.\n\nmacro pqremove(s, tree, top)\nbegin\n    top := s.heap[SMALLEST];\n    s.heap[SMALLEST] := s.heap[s.heap_len];\n    Dec(s.heap_len);\n    pqdownheap(s, tree, SMALLEST);\nend\n}\n\n{ ===========================================================================\n  Compares to subtrees, using the tree depth as tie breaker when\n  the subtrees have equal frequency. This minimizes the worst case length.\n\nmacro smaller(tree, n, m, depth)\n   ( (tree[n].Freq < tree[m].Freq) or\n     ((tree[n].Freq = tree[m].Freq) and (depth[n] <= depth[m])) )\n}\n\n{ ===========================================================================\n  Restore the heap property by moving down the tree starting at node k,\n  exchanging a node with the smallest of its two sons if necessary, stopping\n  when the heap property is re-established (each father smaller than its\n  two sons). }\n{local}\n\nprocedure pqdownheap(var s : deflate_state;\n                     var tree : tree_type;   { the tree to restore }\n                     k : int);          { node to move down }\nvar\n  v : int;\n  j : int;\nbegin\n  v := s.heap[k];\n  j := k shl 1;  { left son of k }\n  while (j <= s.heap_len) do\n  begin\n    { Set j to the smallest of the two sons: }\n    if (j < s.heap_len) and\n       {smaller(tree, s.heap[j+1], s.heap[j], s.depth)}\n      ( (tree[s.heap[j+1]].fc.Freq < tree[s.heap[j]].fc.Freq) or\n        ((tree[s.heap[j+1]].fc.Freq = tree[s.heap[j]].fc.Freq) and\n         (s.depth[s.heap[j+1]] <= s.depth[s.heap[j]])) ) then\n    begin\n      Inc(j);\n    end;\n    { Exit if v is smaller than both sons }\n    if {(smaller(tree, v, s.heap[j], s.depth))}\n     ( (tree[v].fc.Freq < tree[s.heap[j]].fc.Freq) or\n       ((tree[v].fc.Freq = tree[s.heap[j]].fc.Freq) and\n        (s.depth[v] <= s.depth[s.heap[j]])) ) then\n      break;\n    { Exchange v with the smallest son }\n    s.heap[k] := s.heap[j];\n    k := j;\n\n    { And continue down the tree, setting j to the left son of k }\n    j := j shl 1;\n  end;\n  s.heap[k] := v;\nend;\n\n{ ===========================================================================\n  Compute the optimal bit lengths for a tree and update the total bit length\n  for the current block.\n  IN assertion: the fields freq and dad are set, heap[heap_max] and\n     above are the tree nodes sorted by increasing frequency.\n  OUT assertions: the field len is set to the optimal bit length, the\n      array bl_count contains the frequencies for each bit length.\n      The length opt_len is updated; static_len is also updated if stree is\n      not null. }\n\n{local}\nprocedure gen_bitlen(var s : deflate_state;\n                     var desc : tree_desc);   { the tree descriptor }\nvar\n  tree : tree_ptr;\n  max_code : int;\n  stree : tree_ptr; {const}\n  extra : pzIntfArray; {const}\n  base : int;\n  max_length : int;\n  h : int;              { heap index }\n  n, m : int;           { iterate over the tree elements }\n  bits : int;           { bit length }\n  xbits : int;          { extra bits }\n  f : ush;              { frequency }\n  overflow : int;   { number of elements with bit length too large }\nbegin\n  tree := desc.dyn_tree;\n  max_code := desc.max_code;\n  stree := desc.stat_desc^.static_tree;\n  extra := desc.stat_desc^.extra_bits;\n  base := desc.stat_desc^.extra_base;\n  max_length := desc.stat_desc^.max_length;\n  overflow := 0;\n\n  for bits := 0 to MAX_BITS do\n    s.bl_count[bits] := 0;\n\n  { In a first pass, compute the optimal bit lengths (which may\n    overflow in the case of the bit length tree). }\n\n  tree^[s.heap[s.heap_max]].dl.Len := 0; { root of the heap }\n\n  for h := s.heap_max+1 to HEAP_SIZE-1 do\n  begin\n    n := s.heap[h];\n    bits := tree^[tree^[n].dl.Dad].dl.Len + 1;\n    if (bits > max_length) then\n    begin\n      bits := max_length;\n      Inc(overflow);\n    end;\n    tree^[n].dl.Len := ush(bits);\n    { We overwrite tree[n].dl.Dad which is no longer needed }\n\n    if (n > max_code) then\n      continue; { not a leaf node }\n\n    Inc(s.bl_count[bits]);\n    xbits := 0;\n    if (n >= base) then\n      xbits := extra^[n-base];\n    f := tree^[n].fc.Freq;\n    Inc(s.opt_len, ulg(f) * (bits + xbits));\n    if (stree <> NIL) then\n      Inc(s.static_len, ulg(f) * (stree^[n].dl.Len + xbits));\n  end;\n  if (overflow = 0) then\n    exit;\n  {$ifdef DEBUG}\n  Tracev(^M'bit length overflow');\n  {$endif}\n  { This happens for example on obj2 and pic of the Calgary corpus }\n\n  { Find the first bit length which could increase: }\n  repeat\n    bits := max_length-1;\n    while (s.bl_count[bits] = 0) do\n      Dec(bits);\n    Dec(s.bl_count[bits]);      { move one leaf down the tree }\n    Inc(s.bl_count[bits+1], 2); { move one overflow item as its brother }\n    Dec(s.bl_count[max_length]);\n    { The brother of the overflow item also moves one step up,\n      but this does not affect bl_count[max_length] }\n\n    Dec(overflow, 2);\n  until (overflow <= 0);\n\n  { Now recompute all bit lengths, scanning in increasing frequency.\n    h is still equal to HEAP_SIZE. (It is simpler to reconstruct all\n    lengths instead of fixing only the wrong ones. This idea is taken\n    from 'ar' written by Haruhiko Okumura.) }\n  h := HEAP_SIZE;  { Delphi3: compiler warning w/o this }\n  for bits := max_length downto 1 do\n  begin\n    n := s.bl_count[bits];\n    while (n <> 0) do\n    begin\n      Dec(h);\n      m := s.heap[h];\n      if (m > max_code) then\n        continue;\n      if (tree^[m].dl.Len <> unsigned(bits)) then\n      begin\n        {$ifdef DEBUG}\n        Trace('code '+IntToStr(m)+' bits '+IntToStr(tree^[m].dl.Len)\n              +'.'+IntToStr(bits));\n        {$ENDIF}\n        Inc(s.opt_len, (long(bits) - long(tree^[m].dl.Len))\n                        * long(tree^[m].fc.Freq) );\n        tree^[m].dl.Len := ush(bits);\n      end;\n      Dec(n);\n    end;\n  end;\nend;\n\n{ ===========================================================================\n  Construct one Huffman tree and assigns the code bit strings and lengths.\n  Update the total bit length for the current block.\n  IN assertion: the field freq is set for all tree elements.\n  OUT assertions: the fields len and code are set to the optimal bit length\n      and corresponding code. The length opt_len is updated; static_len is\n      also updated if stree is not null. The field max_code is set. }\n\n{local}\nprocedure build_tree(var s : deflate_state;\n                     var desc : tree_desc); { the tree descriptor }\n\nvar\n  tree : tree_ptr;\n  stree : tree_ptr; {const}\n  elems : int;\n  n, m : int;          { iterate over heap elements }\n  max_code : int;      { largest code with non zero frequency }\n  node : int;          { new node being created }\nbegin\n  tree := desc.dyn_tree;\n  stree := desc.stat_desc^.static_tree;\n  elems := desc.stat_desc^.elems;\n  max_code := -1;\n\n  { Construct the initial heap, with least frequent element in\n    heap[SMALLEST]. The sons of heap[n] are heap[2*n] and heap[2*n+1].\n    heap[0] is not used. }\n  s.heap_len := 0;\n  s.heap_max := HEAP_SIZE;\n\n  for n := 0 to elems-1 do\n  begin\n    if (tree^[n].fc.Freq <> 0) then\n    begin\n      max_code := n;\n      Inc(s.heap_len);\n      s.heap[s.heap_len] := n;\n      s.depth[n] := 0;\n    end\n    else\n    begin\n      tree^[n].dl.Len := 0;\n    end;\n  end;\n\n  { The pkzip format requires that at least one distance code exists,\n    and that at least one bit should be sent even if there is only one\n    possible code. So to avoid special checks later on we force at least\n    two codes of non zero frequency. }\n\n  while (s.heap_len < 2) do\n  begin\n    Inc(s.heap_len);\n    if (max_code < 2) then\n    begin\n      Inc(max_code);\n      s.heap[s.heap_len] := max_code;\n      node := max_code;\n    end\n    else\n    begin\n      s.heap[s.heap_len] := 0;\n      node := 0;\n    end;\n    tree^[node].fc.Freq := 1;\n    s.depth[node] := 0;\n    Dec(s.opt_len);\n    if (stree <> NIL) then\n      Dec(s.static_len, stree^[node].dl.Len);\n    { node is 0 or 1 so it does not have extra bits }\n  end;\n  desc.max_code := max_code;\n\n  { The elements heap[heap_len/2+1 .. heap_len] are leaves of the tree,\n    establish sub-heaps of increasing lengths: }\n\n  for n := s.heap_len div 2 downto 1 do\n    pqdownheap(s, tree^, n);\n\n  { Construct the Huffman tree by repeatedly combining the least two\n    frequent nodes. }\n\n  node := elems;              { next internal node of the tree }\n  repeat\n    {pqremove(s, tree, n);}  { n := node of least frequency }\n    n := s.heap[SMALLEST];\n    s.heap[SMALLEST] := s.heap[s.heap_len];\n    Dec(s.heap_len);\n    pqdownheap(s, tree^, SMALLEST);\n\n    m := s.heap[SMALLEST]; { m := node of next least frequency }\n\n    Dec(s.heap_max);\n    s.heap[s.heap_max] := n; { keep the nodes sorted by frequency }\n    Dec(s.heap_max);\n    s.heap[s.heap_max] := m;\n\n    { Create a new node father of n and m }\n    tree^[node].fc.Freq := tree^[n].fc.Freq + tree^[m].fc.Freq;\n    { maximum }\n    if (s.depth[n] >= s.depth[m]) then\n      s.depth[node] := uch (s.depth[n] + 1)\n    else\n      s.depth[node] := uch (s.depth[m] + 1);\n\n    tree^[m].dl.Dad := ush(node);\n    tree^[n].dl.Dad := ush(node);\n{$ifdef DUMP_BL_TREE}\n    if (tree = tree_ptr(@s.bl_tree)) then\n    begin\n      WriteLn(#13'node ',node,'(',tree^[node].fc.Freq,') sons ',n,\n              '(',tree^[n].fc.Freq,') ', m, '(',tree^[m].fc.Freq,')');\n    end;\n{$endif}\n    { and insert the new node in the heap }\n    s.heap[SMALLEST] := node;\n    Inc(node);\n    pqdownheap(s, tree^, SMALLEST);\n\n  until (s.heap_len < 2);\n\n  Dec(s.heap_max);\n  s.heap[s.heap_max] := s.heap[SMALLEST];\n\n  { At this point, the fields freq and dad are set. We can now\n    generate the bit lengths. }\n\n  gen_bitlen(s, desc);\n\n  { The field len is now set, we can generate the bit codes }\n  gen_codes (tree, max_code, s.bl_count);\nend;\n\n{ ===========================================================================\n  Scan a literal or distance tree to determine the frequencies of the codes\n  in the bit length tree. }\n\n{local}\nprocedure scan_tree(var s : deflate_state;\n                    var tree : array of ct_data;    { the tree to be scanned }\n                    max_code : int);    { and its largest code of non zero frequency }\nvar\n  n : int;                 { iterates over all tree elements }\n  prevlen : int;           { last emitted length }\n  curlen : int;            { length of current code }\n  nextlen : int;           { length of next code }\n  count : int;             { repeat count of the current code }\n  max_count : int;         { max repeat count }\n  min_count : int;         { min repeat count }\nbegin\n  prevlen := -1;\n  nextlen := tree[0].dl.Len;\n  count := 0;\n  max_count := 7;\n  min_count := 4;\n\n  if (nextlen = 0) then\n  begin\n    max_count := 138;\n    min_count := 3;\n  end;\n  tree[max_code+1].dl.Len := ush($ffff); { guard }\n\n  for n := 0 to max_code do\n  begin\n    curlen := nextlen;\n    nextlen := tree[n+1].dl.Len;\n    Inc(count);\n    if (count < max_count) and (curlen = nextlen) then\n      continue\n    else\n      if (count < min_count) then\n        Inc(s.bl_tree[curlen].fc.Freq, count)\n      else\n        if (curlen <> 0) then\n        begin\n          if (curlen <> prevlen) then\n            Inc(s.bl_tree[curlen].fc.Freq);\n          Inc(s.bl_tree[REP_3_6].fc.Freq);\n        end\n        else\n          if (count <= 10) then\n            Inc(s.bl_tree[REPZ_3_10].fc.Freq)\n          else\n            Inc(s.bl_tree[REPZ_11_138].fc.Freq);\n\n    count := 0;\n    prevlen := curlen;\n    if (nextlen = 0) then\n    begin\n      max_count := 138;\n      min_count := 3;\n    end\n    else\n      if (curlen = nextlen) then\n      begin\n        max_count := 6;\n        min_count := 3;\n      end\n      else\n      begin\n        max_count := 7;\n        min_count := 4;\n      end;\n  end;\nend;\n\n{ ===========================================================================\n  Send a literal or distance tree in compressed form, using the codes in\n  bl_tree. }\n\n{local}\nprocedure send_tree(var s : deflate_state;\n                    var tree : array of ct_data;    { the tree to be scanned }\n                    max_code : int);    { and its largest code of non zero frequency }\n\nvar\n  n : int;                { iterates over all tree elements }\n  prevlen : int;          { last emitted length }\n  curlen : int;           { length of current code }\n  nextlen : int;          { length of next code }\n  count : int;            { repeat count of the current code }\n  max_count : int;        { max repeat count }\n  min_count : int;        { min repeat count }\nbegin\n  prevlen := -1;\n  nextlen := tree[0].dl.Len;\n  count := 0;\n  max_count := 7;\n  min_count := 4;\n\n  { tree[max_code+1].dl.Len := -1; }  { guard already set }\n  if (nextlen = 0) then\n  begin\n    max_count := 138;\n    min_count := 3;\n  end;\n\n  for n := 0 to max_code do\n  begin\n    curlen := nextlen;\n    nextlen := tree[n+1].dl.Len;\n    Inc(count);\n    if (count < max_count) and (curlen = nextlen) then\n      continue\n    else\n      if (count < min_count) then\n      begin\n        repeat\n          {$ifdef DEBUG}\n          Tracevvv(#13'cd '+IntToStr(curlen));\n          {$ENDIF}\n          send_bits(s, s.bl_tree[curlen].fc.Code, s.bl_tree[curlen].dl.Len);\n          Dec(count);\n        until (count = 0);\n      end\n      else\n        if (curlen <> 0) then\n        begin\n          if (curlen <> prevlen) then\n          begin\n            {$ifdef DEBUG}\n            Tracevvv(#13'cd '+IntToStr(curlen));\n            {$ENDIF}\n            send_bits(s, s.bl_tree[curlen].fc.Code, s.bl_tree[curlen].dl.Len);\n            Dec(count);\n          end;\n          {$IFDEF DEBUG}\n          Assert((count >= 3) and (count <= 6), ' 3_6?');\n          {$ENDIF}\n          {$ifdef DEBUG}\n          Tracevvv(#13'cd '+IntToStr(REP_3_6));\n          {$ENDIF}\n          send_bits(s, s.bl_tree[REP_3_6].fc.Code, s.bl_tree[REP_3_6].dl.Len);\n          send_bits(s, count-3, 2);\n        end\n        else\n          if (count <= 10) then\n          begin\n            {$ifdef DEBUG}\n            Tracevvv(#13'cd '+IntToStr(REPZ_3_10));\n            {$ENDIF}\n            send_bits(s, s.bl_tree[REPZ_3_10].fc.Code, s.bl_tree[REPZ_3_10].dl.Len);\n            send_bits(s, count-3, 3);\n          end\n          else\n          begin\n            {$ifdef DEBUG}\n            Tracevvv(#13'cd '+IntToStr(REPZ_11_138));\n            {$ENDIF}\n            send_bits(s, s.bl_tree[REPZ_11_138].fc.Code, s.bl_tree[REPZ_11_138].dl.Len);\n            send_bits(s, count-11, 7);\n          end;\n    count := 0;\n    prevlen := curlen;\n    if (nextlen = 0) then\n    begin\n      max_count := 138;\n      min_count := 3;\n    end\n    else\n      if (curlen = nextlen) then\n      begin\n        max_count := 6;\n        min_count := 3;\n      end\n      else\n      begin\n        max_count := 7;\n        min_count := 4;\n      end;\n  end;\nend;\n\n{ ===========================================================================\n  Construct the Huffman tree for the bit lengths and return the index in\n  bl_order of the last bit length code to send. }\n\n{local}\nfunction build_bl_tree(var s : deflate_state) : int;\nvar\n  max_blindex : int;  { index of last bit length code of non zero freq }\nbegin\n  { Determine the bit length frequencies for literal and distance trees }\n  scan_tree(s, s.dyn_ltree, s.l_desc.max_code);\n  scan_tree(s, s.dyn_dtree, s.d_desc.max_code);\n\n  { Build the bit length tree: }\n  build_tree(s, s.bl_desc);\n  { opt_len now includes the length of the tree representations, except\n    the lengths of the bit lengths codes and the 5+5+4 bits for the counts. }\n\n  { Determine the number of bit length codes to send. The pkzip format\n    requires that at least 4 bit length codes be sent. (appnote.txt says\n    3 but the actual value used is 4.) }\n\n  for max_blindex := BL_CODES-1 downto 3 do\n  begin\n    if (s.bl_tree[bl_order[max_blindex]].dl.Len <> 0) then\n      break;\n  end;\n  { Update opt_len to include the bit length tree and counts }\n  Inc(s.opt_len, 3*(max_blindex+1) + 5+5+4);\n  {$ifdef DEBUG}\n  Tracev(^M'dyn trees: dyn %ld, stat %ld {s.opt_len, s.static_len}');\n  {$ENDIF}\n\n  build_bl_tree := max_blindex;\nend;\n\n{ ===========================================================================\n  Send the header for a block using dynamic Huffman trees: the counts, the\n  lengths of the bit length codes, the literal tree and the distance tree.\n  IN assertion: lcodes >= 257, dcodes >= 1, blcodes >= 4. }\n\n{local}\nprocedure send_all_trees(var s : deflate_state;\n                         lcodes : int;\n                         dcodes : int;\n                         blcodes : int); { number of codes for each tree }\nvar\n  rank : int;                    { index in bl_order }\nbegin\n  {$IFDEF DEBUG}\n  Assert ((lcodes >= 257) and (dcodes >= 1) and (blcodes >= 4),\n          'not enough codes');\n  Assert ((lcodes <= L_CODES) and (dcodes <= D_CODES)\n          and (blcodes <= BL_CODES), 'too many codes');\n  Tracev(^M'bl counts: ');\n  {$ENDIF}\n  send_bits(s, lcodes-257, 5); { not +255 as stated in appnote.txt }\n  send_bits(s, dcodes-1,   5);\n  send_bits(s, blcodes-4,  4); { not -3 as stated in appnote.txt }\n  for rank := 0 to blcodes-1 do\n  begin\n    {$ifdef DEBUG}\n    Tracev(^M'bl code '+IntToStr(bl_order[rank]));\n    {$ENDIF}\n    send_bits(s, s.bl_tree[bl_order[rank]].dl.Len, 3);\n  end;\n  {$ifdef DEBUG}\n  Tracev(^M'bl tree: sent '+IntToStr(s.bits_sent));\n  {$ENDIF}\n\n  send_tree(s, s.dyn_ltree, lcodes-1); { literal tree }\n  {$ifdef DEBUG}\n  Tracev(^M'lit tree: sent '+IntToStr(s.bits_sent));\n  {$ENDIF}\n\n  send_tree(s, s.dyn_dtree, dcodes-1); { distance tree }\n  {$ifdef DEBUG}\n  Tracev(^M'dist tree: sent '+IntToStr(s.bits_sent));\n  {$ENDIF}\nend;\n\n{ ===========================================================================\n  Flush the bit buffer and align the output on a byte boundary }\n\n{local}\nprocedure bi_windup(var s : deflate_state);\nbegin\n  if (s.bi_valid > 8) then\n  begin\n    {put_short(s, s.bi_buf);}\n    s.pending_buf^[s.pending] := uch(s.bi_buf and $ff);\n    Inc(s.pending);\n    s.pending_buf^[s.pending] := uch(ush(s.bi_buf) shr 8);;\n    Inc(s.pending);\n  end\n  else\n    if (s.bi_valid > 0) then\n    begin\n      {put_byte(s, (Byte)s^.bi_buf);}\n      s.pending_buf^[s.pending] := Byte(s.bi_buf);\n      Inc(s.pending);\n    end;\n  s.bi_buf := 0;\n  s.bi_valid := 0;\n{$ifdef DEBUG}\n  s.bits_sent := (s.bits_sent+7) and (not 7);\n{$endif}\nend;\n\n{ ===========================================================================\n  Copy a stored block, storing first the length and its\n  one's complement if requested. }\n\n{local}\nprocedure copy_block(var s : deflate_state;\n                     buf : pcharf;      { the input data }\n                     len : unsigned;    { its length }\n                     header : boolean); { true if block header must be written }\nbegin\n  bi_windup(s);        { align on byte boundary }\n  s.last_eob_len := 8; { enough lookahead for inflate }\n\n  if (header) then\n  begin\n    {put_short(s, (ush)len);}\n    s.pending_buf^[s.pending] := uch(ush(len) and $ff);\n    Inc(s.pending);\n    s.pending_buf^[s.pending] := uch(ush(len) shr 8);;\n    Inc(s.pending);\n    {put_short(s, (ush)~len);}\n    s.pending_buf^[s.pending] := uch(ush(not len) and $ff);\n    Inc(s.pending);\n    s.pending_buf^[s.pending] := uch(ush(not len) shr 8);;\n    Inc(s.pending);\n\n{$ifdef DEBUG}\n    Inc(s.bits_sent, 2*16);\n{$endif}\n  end;\n{$ifdef DEBUG}\n  Inc(s.bits_sent, ulg(len shl 3));\n{$endif}\n  while (len <> 0) do\n  begin\n    Dec(len);\n    {put_byte(s, *buf++);}\n    s.pending_buf^[s.pending] := buf^;\n    Inc(buf);\n    Inc(s.pending);\n  end;\nend;\n\n\n{ ===========================================================================\n  Send a stored block }\n\nprocedure _tr_stored_block(var s : deflate_state;\n                           buf : pcharf;     { input block }\n                           stored_len : ulg; { length of input block }\n                           eof : boolean);   { true if this is the last block for a file }\n\nbegin\n  send_bits(s, (STORED_BLOCK shl 1)+ord(eof), 3);  { send block type }\n  s.compressed_len := (s.compressed_len + 3 + 7) and ulg(not Long(7));\n  Inc(s.compressed_len, (stored_len + 4) shl 3);\n\n  copy_block(s, buf, unsigned(stored_len), TRUE); { with header }\nend;\n\n{ ===========================================================================\n  Flush the bit buffer, keeping at most 7 bits in it. }\n\n{local}\nprocedure bi_flush(var s : deflate_state);\nbegin\n  if (s.bi_valid = 16) then\n  begin\n    {put_short(s, s.bi_buf);}\n    s.pending_buf^[s.pending] := uch(s.bi_buf and $ff);\n    Inc(s.pending);\n    s.pending_buf^[s.pending] := uch(ush(s.bi_buf) shr 8);;\n    Inc(s.pending);\n\n    s.bi_buf := 0;\n    s.bi_valid := 0;\n  end\n  else\n   if (s.bi_valid >= 8) then\n   begin\n     {put_byte(s, (Byte)s^.bi_buf);}\n     s.pending_buf^[s.pending] := Byte(s.bi_buf);\n     Inc(s.pending);\n\n     s.bi_buf := s.bi_buf shr 8;\n     Dec(s.bi_valid, 8);\n   end;\nend;\n\n\n{ ===========================================================================\n  Send one empty static block to give enough lookahead for inflate.\n  This takes 10 bits, of which 7 may remain in the bit buffer.\n  The current inflate code requires 9 bits of lookahead. If the\n  last two codes for the previous block (real code plus EOB) were coded\n  on 5 bits or less, inflate may have only 5+3 bits of lookahead to decode\n  the last real code. In this case we send two empty static blocks instead\n  of one. (There are no problems if the previous block is stored or fixed.)\n  To simplify the code, we assume the worst case of last real code encoded\n  on one bit only. }\n\nprocedure _tr_align(var s : deflate_state);\nbegin\n  send_bits(s, STATIC_TREES shl 1, 3);\n  {$ifdef DEBUG}\n  Tracevvv(#13'cd '+IntToStr(END_BLOCK));\n  {$ENDIF}\n  send_bits(s, static_ltree[END_BLOCK].fc.Code, static_ltree[END_BLOCK].dl.Len);\n  Inc(s.compressed_len, Long(10)); { 3 for block type, 7 for EOB }\n  bi_flush(s);\n  { Of the 10 bits for the empty block, we have already sent\n    (10 - bi_valid) bits. The lookahead for the last real code (before\n    the EOB of the previous block) was thus at least one plus the length\n    of the EOB plus what we have just sent of the empty static block. }\n  if (1 + s.last_eob_len + 10 - s.bi_valid < 9) then\n  begin\n    send_bits(s, STATIC_TREES shl 1, 3);\n    {$ifdef DEBUG}\n    Tracevvv(#13'cd '+IntToStr(END_BLOCK));\n    {$ENDIF}\n    send_bits(s, static_ltree[END_BLOCK].fc.Code, static_ltree[END_BLOCK].dl.Len);\n    Inc(s.compressed_len, Long(10));\n    bi_flush(s);\n  end;\n  s.last_eob_len := 7;\nend;\n\n{ ===========================================================================\n  Set the data type to ASCII or BINARY, using a crude approximation:\n  binary if more than 20% of the bytes are <= 6 or >= 128, ascii otherwise.\n  IN assertion: the fields freq of dyn_ltree are set and the total of all\n  frequencies does not exceed 64K (to fit in an int on 16 bit machines). }\n\n{local}\nprocedure set_data_type(var s : deflate_state);\nvar\n  n : int;\n  ascii_freq : unsigned;\n  bin_freq : unsigned;\nbegin\n  n := 0;\n  ascii_freq := 0;\n  bin_freq := 0;\n\n  while (n < 7) do\n  begin\n    Inc(bin_freq, s.dyn_ltree[n].fc.Freq);\n    Inc(n);\n  end;\n  while (n < 128) do\n  begin\n    Inc(ascii_freq, s.dyn_ltree[n].fc.Freq);\n    Inc(n);\n  end;\n  while (n < LITERALS) do\n  begin\n    Inc(bin_freq, s.dyn_ltree[n].fc.Freq);\n    Inc(n);\n  end;\n  if (bin_freq > (ascii_freq shr 2)) then\n    s.data_type := Byte(Z_BINARY)\n  else\n    s.data_type := Byte(Z_ASCII);\nend;\n\n{ ===========================================================================\n  Send the block data compressed using the given Huffman trees }\n\n{local}\nprocedure compress_block(var s : deflate_state;\n                         var ltree : array of ct_data;   { literal tree }\n                         var dtree : array of ct_data);  { distance tree }\nvar\n  dist : unsigned;      { distance of matched string }\n  lc : int;             { match length or unmatched char (if dist == 0) }\n  lx : unsigned;        { running index in l_buf }\n  code : unsigned;      { the code to send }\n  extra : int;          { number of extra bits to send }\nbegin\n  lx := 0;\n  if (s.last_lit <> 0) then\n  repeat\n    dist := s.d_buf^[lx];\n    lc := s.l_buf^[lx];\n    Inc(lx);\n    if (dist = 0) then\n    begin\n      { send a literal byte }\n      {$ifdef DEBUG}\n      Tracevvv(#13'cd '+IntToStr(lc));\n      Tracecv((lc > 31) and (lc < 128), ' '+AnsiChar(lc)+' ');\n      {$ENDIF}\n      send_bits(s, ltree[lc].fc.Code, ltree[lc].dl.Len);\n    end\n    else\n    begin\n      { Here, lc is the match length - MIN_MATCH }\n      code := _length_code[lc];\n      { send the length code }\n      {$ifdef DEBUG}\n      Tracevvv(#13'cd '+IntToStr(code+LITERALS+1));\n      {$ENDIF}\n      send_bits(s, ltree[code+LITERALS+1].fc.Code, ltree[code+LITERALS+1].dl.Len);\n      extra := extra_lbits[code];\n      if (extra <> 0) then\n      begin\n        Dec(lc, base_length[code]);\n        send_bits(s, lc, extra);       { send the extra length bits }\n      end;\n      Dec(dist); { dist is now the match distance - 1 }\n      {code := d_code(dist);}\n      if (dist < 256) then\n        code := _dist_code[dist]\n      else\n        code := _dist_code[256+(dist shr 7)];\n\n      {$IFDEF DEBUG}\n      Assert (code < D_CODES, 'bad d_code');\n      {$ENDIF}\n\n      { send the distance code }\n      {$ifdef DEBUG}\n      Tracevvv(#13'cd '+IntToStr(code));\n      {$ENDIF}\n      send_bits(s, dtree[code].fc.Code, dtree[code].dl.Len);\n      extra := extra_dbits[code];\n      if (extra <> 0) then\n      begin\n        Dec(dist, base_dist[code]);\n        send_bits(s, dist, extra);   { send the extra distance bits }\n      end;\n    end; { literal or match pair ? }\n\n    { Check that the overlay between pending_buf and d_buf+l_buf is ok: }\n    {$IFDEF DEBUG}\n    Assert(s.pending < s.lit_bufsize + 2*lx, 'pendingBuf overflow');\n    {$ENDIF}\n  until (lx >= s.last_lit);\n\n  {$ifdef DEBUG}\n  Tracevvv(#13'cd '+IntToStr(END_BLOCK));\n  {$ENDIF}\n  send_bits(s, ltree[END_BLOCK].fc.Code, ltree[END_BLOCK].dl.Len);\n  s.last_eob_len := ltree[END_BLOCK].dl.Len;\nend;\n\n\n{ ===========================================================================\n  Determine the best encoding for the current block: dynamic trees, static\n  trees or store, and output the encoded block to the zip file. This function\n  returns the total compressed length for the file so far. }\n\nfunction _tr_flush_block (var s : deflate_state;\n         buf : pcharf;         { input block, or NULL if too old }\n         stored_len : ulg;     { length of input block }\n         eof : boolean) : ulg; { true if this is the last block for a file }\nvar\n  opt_lenb, static_lenb : ulg; { opt_len and static_len in bytes }\n  max_blindex : int;  { index of last bit length code of non zero freq }\nbegin\n  max_blindex := 0;\n\n  { Build the Huffman trees unless a stored block is forced }\n  if (s.level > 0) then\n  begin\n    { Check if the file is ascii or binary }\n    if (s.data_type = Z_UNKNOWN) then\n      set_data_type(s);\n\n    { Construct the literal and distance trees }\n    build_tree(s, s.l_desc);\n    {$ifdef DEBUG}\n    Tracev(^M'lit data: dyn %ld, stat %ld {s.opt_len, s.static_len}');\n    {$ENDIF}\n\n    build_tree(s, s.d_desc);\n    {$ifdef DEBUG}\n    Tracev(^M'dist data: dyn %ld, stat %ld {s.opt_len, s.static_len}');\n    {$ENDIF}\n    { At this point, opt_len and static_len are the total bit lengths of\n      the compressed block data, excluding the tree representations. }\n\n    { Build the bit length tree for the above two trees, and get the index\n      in bl_order of the last bit length code to send. }\n    max_blindex := build_bl_tree(s);\n\n    { Determine the best encoding. Compute first the block length in bytes}\n    opt_lenb := (s.opt_len+3+7) shr 3;\n    static_lenb := (s.static_len+3+7) shr 3;\n\n    {$ifdef DEBUG}\n    Tracev(^M'opt %lu(%lu) stat %lu(%lu) stored %lu lit %u '+\n\t    '{opt_lenb, s.opt_len, static_lenb, s.static_len, stored_len,'+\n\t    's.last_lit}');\n    {$ENDIF}\n\n    if (static_lenb <= opt_lenb) then\n      opt_lenb := static_lenb;\n\n  end\n  else\n  begin\n    {$IFDEF DEBUG}\n    Assert(buf <> pcharf(NIL), 'lost buf');\n    {$ENDIF}\n    static_lenb := stored_len + 5;\n    opt_lenb := static_lenb;        { force a stored block }\n  end;\n\n  { If compression failed and this is the first and last block,\n    and if the .zip file can be seeked (to rewrite the local header),\n    the whole file is transformed into a stored file:  }\n\n{$ifdef STORED_FILE_OK}\n{$ifdef FORCE_STORED_FILE}\n  if eof and (s.compressed_len = Long(0)) then\n  begin { force stored file }\n{$else}\n  if (stored_len <= opt_lenb) and eof and (s.compressed_len=Long(0))\n     and seekable()) do\n  begin\n{$endif}\n    { Since LIT_BUFSIZE <= 2*WSIZE, the input data must be there: }\n    if (buf = pcharf(0)) then\n      error ('block vanished');\n\n    copy_block(buf, unsigned(stored_len), 0); { without header }\n    s.compressed_len := stored_len shl 3;\n    s.method := STORED;\n  end\n  else\n{$endif} { STORED_FILE_OK }\n\n{$ifdef FORCE_STORED}\n  if (buf <> pcharf(0)) then\n  begin { force stored block }\n{$else}\n  if (stored_len+4 <= opt_lenb) and (buf <> pcharf(0)) then\n  begin\n                     { 4: two words for the lengths }\n{$endif}\n    { The test buf <> NULL is only necessary if LIT_BUFSIZE > WSIZE.\n      Otherwise we can't have processed more than WSIZE input bytes since\n      the last block flush, because compression would have been\n      successful. If LIT_BUFSIZE <= WSIZE, it is never too late to\n      transform a block into a stored block. }\n\n    _tr_stored_block(s, buf, stored_len, eof);\n\n{$ifdef FORCE_STATIC}\n  end\n  else\n    if (static_lenb >= 0) then\n    begin { force static trees }\n{$else}\n  end\n  else\n    if (static_lenb = opt_lenb) then\n    begin\n{$endif}\n      send_bits(s, (STATIC_TREES shl 1)+ord(eof), 3);\n      compress_block(s, static_ltree, static_dtree);\n      Inc(s.compressed_len, 3 + s.static_len);\n    end\n    else\n    begin\n      send_bits(s, (DYN_TREES shl 1)+ord(eof), 3);\n      send_all_trees(s, s.l_desc.max_code+1, s.d_desc.max_code+1,\n                     max_blindex+1);\n      compress_block(s, s.dyn_ltree, s.dyn_dtree);\n      Inc(s.compressed_len, 3 + s.opt_len);\n    end;\n  {$ifdef DEBUG}\n  Assert (s.compressed_len = s.bits_sent, 'bad compressed size');\n  {$ENDIF}\n  init_block(s);\n\n  if (eof) then\n  begin\n    bi_windup(s);\n    Inc(s.compressed_len, 7);  { align on byte boundary }\n  end;\n  {$ifdef DEBUG}\n  Tracev(#13'comprlen %lu(%lu) {s.compressed_len shr 3,'+\n         's.compressed_len-7*ord(eof)}');\n  {$ENDIF}\n\n  _tr_flush_block := s.compressed_len shr 3;\nend;\n\n\n{ ===========================================================================\n  Save the match info and tally the frequency counts. Return true if\n  the current block must be flushed. }\n\nfunction _tr_tally (var s : deflate_state;\n   dist : unsigned;          { distance of matched string }\n   lc : unsigned) : boolean; { match length-MIN_MATCH or unmatched char (if dist=0) }\nvar\n  {$IFDEF DEBUG}\n  MAX_DIST : ush;\n  {$ENDIF}\n  code : ush;\n{$ifdef TRUNCATE_BLOCK}\nvar\n  out_length : ulg;\n  in_length : ulg;\n  dcode : int;\n{$endif}\nbegin\n  s.d_buf^[s.last_lit] := ush(dist);\n  s.l_buf^[s.last_lit] := uch(lc);\n  Inc(s.last_lit);\n  if (dist = 0) then\n  begin\n    { lc is the unmatched char }\n    Inc(s.dyn_ltree[lc].fc.Freq);\n  end\n  else\n  begin\n    Inc(s.matches);\n    { Here, lc is the match length - MIN_MATCH }\n    Dec(dist);             { dist := match distance - 1 }\n\n    {macro d_code(dist)}\n    if (dist) < 256 then\n      code := _dist_code[dist]\n    else\n      code := _dist_code[256+(dist shr 7)];\n    {$IFDEF DEBUG}\n{macro  MAX_DIST(s) <=> ((s)^.w_size-MIN_LOOKAHEAD)\n   In order to simplify the code, particularly on 16 bit machines, match\n   distances are limited to MAX_DIST instead of WSIZE. }\n    MAX_DIST := ush(s.w_size-MIN_LOOKAHEAD);\n    Assert((dist < ush(MAX_DIST)) and\n           (ush(lc) <= ush(MAX_MATCH-MIN_MATCH)) and\n           (ush(code) < ush(D_CODES)),  '_tr_tally: bad match');\n    {$ENDIF}\n    Inc(s.dyn_ltree[_length_code[lc]+LITERALS+1].fc.Freq);\n    {s.dyn_dtree[d_code(dist)].Freq++;}\n    Inc(s.dyn_dtree[code].fc.Freq);\n  end;\n\n{$ifdef TRUNCATE_BLOCK}\n  { Try to guess if it is profitable to stop the current block here }\n  if (s.last_lit and $1fff = 0) and (s.level > 2) then\n  begin\n    { Compute an upper bound for the compressed length }\n    out_length := ulg(s.last_lit)*Long(8);\n    in_length := ulg(long(s.strstart) - s.block_start);\n    for dcode := 0 to D_CODES-1 do\n    begin\n      Inc(out_length, ulg(s.dyn_dtree[dcode].fc.Freq *\n            (Long(5)+extra_dbits[dcode])) );\n    end;\n    out_length := out_length shr 3;\n    {$ifdef DEBUG}\n    Tracev(^M'last_lit %u, in %ld, out ~%ld(%ld%%) ');\n          { s.last_lit, in_length, out_length,\n           Long(100) - out_length*Long(100) div in_length)); }\n    {$ENDIF}\n    if (s.matches < s.last_lit div 2) and (out_length < in_length div 2) then\n    begin\n      _tr_tally := TRUE;\n      exit;\n    end;\n  end;\n{$endif}\n  _tr_tally := (s.last_lit = s.lit_bufsize-1);\n  { We avoid equality with lit_bufsize because of wraparound at 64K\n    on 16 bit machines and because stored blocks are restricted to\n    64K-1 bytes. }\nend;\n\nend."
  },
  {
    "path": "lib/Imaging/ZLib/imzconf.inc",
    "content": "{ -------------------------------------------------------------------- }\n\n{$DEFINE MAX_MATCH_IS_258}\n\n{ Compile with -DMAXSEG_64K if the alloc function cannot allocate more\n  than 64k bytes at a time (needed on systems with 16-bit int). }\n\n{$UNDEF MAXSEG_64K}\n{$DEFINE UNALIGNED_OK}    { requires SizeOf(ush) = 2 ! }\n{$UNDEF DYNAMIC_CRC_TABLE}\n{$UNDEF FASTEST}\n{$DEFINE Use32}\n{$DEFINE patch112}        { apply patch from the zlib home page }\n\n{$IFDEF FPC}\n  {$MODE DELPHI}\n{$ENDIF}\n\n{$UNDEF DEBUG} // for Delphi 2007 in DEBUG mode\n\n{$RANGECHECKS OFF}\n{$OVERFLOWCHECKS OFF}\n{ -------------------------------------------------------------------- }\n\n\n"
  },
  {
    "path": "lib/Imaging/ZLib/imzdeflate.pas",
    "content": "Unit imzdeflate;\n\n{ Orginal: deflate.h -- internal compression state\n           deflate.c -- compress data using the deflation algorithm\n  Copyright (C) 1995-1996 Jean-loup Gailly.\n\n  Pascal tranlastion\n  Copyright (C) 1998 by Jacques Nomssi Nzali\n  For conditions of distribution and use, see copyright notice in readme.txt\n}\n\n\n{  ALGORITHM\n\n       The \"deflation\" process depends on being able to identify portions\n       of the input text which are identical to earlier input (within a\n       sliding window trailing behind the input currently being processed).\n\n       The most straightforward technique turns out to be the fastest for\n       most input files: try all possible matches and select the longest.\n       The key feature of this algorithm is that insertions into the string\n       dictionary are very simple and thus fast, and deletions are avoided\n       completely. Insertions are performed at each input character, whereas\n       string matches are performed only when the previous match ends. So it\n       is preferable to spend more time in matches to allow very fast string\n       insertions and avoid deletions. The matching algorithm for small\n       strings is inspired from that of Rabin & Karp. A brute force approach\n       is used to find longer strings when a small match has been found.\n       A similar algorithm is used in comic (by Jan-Mark Wams) and freeze\n       (by Leonid Broukhis).\n          A previous version of this file used a more sophisticated algorithm\n       (by Fiala and Greene) which is guaranteed to run in linear amortized\n       time, but has a larger average cost, uses more memory and is patented.\n       However the F&G algorithm may be faster for some highly redundant\n       files if the parameter max_chain_length (described below) is too large.\n\n   ACKNOWLEDGEMENTS\n\n       The idea of lazy evaluation of matches is due to Jan-Mark Wams, and\n       I found it in 'freeze' written by Leonid Broukhis.\n       Thanks to many people for bug reports and testing.\n\n   REFERENCES\n\n       Deutsch, L.P.,\"'Deflate' Compressed Data Format Specification\".\n       Available in ftp.uu.net:/pub/archiving/zip/doc/deflate-1.1.doc\n\n       A description of the Rabin and Karp algorithm is given in the book\n          \"Algorithms\" by R. Sedgewick, Addison-Wesley, p252.\n\n       Fiala,E.R., and Greene,D.H.\n          Data Compression with Finite Windows, Comm.ACM, 32,4 (1989) 490-595}\n\ninterface\n\n{$I imzconf.inc}\n\nuses\n  imzutil, impaszlib;\n\n\nfunction deflateInit_(strm : z_streamp;\n                      level : int;\n                      const version : AnsiString;\n                      stream_size : int) : int;\n\n\nfunction deflateInit (var strm : z_stream; level : int) : int;\n\n{  Initializes the internal stream state for compression. The fields\n   zalloc, zfree and opaque must be initialized before by the caller.\n   If zalloc and zfree are set to Z_NULL, deflateInit updates them to\n   use default allocation functions.\n\n     The compression level must be Z_DEFAULT_COMPRESSION, or between 0 and 9:\n   1 gives best speed, 9 gives best compression, 0 gives no compression at\n   all (the input data is simply copied a block at a time).\n   Z_DEFAULT_COMPRESSION requests a default compromise between speed and\n   compression (currently equivalent to level 6).\n\n     deflateInit returns Z_OK if success, Z_MEM_ERROR if there was not\n   enough memory, Z_STREAM_ERROR if level is not a valid compression level,\n   Z_VERSION_ERROR if the zlib library version (zlib_version) is incompatible\n   with the version assumed by the caller (ZLIB_VERSION).\n   msg is set to null if there is no error message.  deflateInit does not\n   perform any compression: this will be done by deflate(). }\n\n\n{EXPORT}\nfunction deflate (var strm : z_stream; flush : int) : int;\n\n{ Performs one or both of the following actions:\n\n  - Compress more input starting at next_in and update next_in and avail_in\n    accordingly. If not all input can be processed (because there is not\n    enough room in the output buffer), next_in and avail_in are updated and\n    processing will resume at this point for the next call of deflate().\n\n  - Provide more output starting at next_out and update next_out and avail_out\n    accordingly. This action is forced if the parameter flush is non zero.\n    Forcing flush frequently degrades the compression ratio, so this parameter\n    should be set only when necessary (in interactive applications).\n    Some output may be provided even if flush is not set.\n\n  Before the call of deflate(), the application should ensure that at least\n  one of the actions is possible, by providing more input and/or consuming\n  more output, and updating avail_in or avail_out accordingly; avail_out\n  should never be zero before the call. The application can consume the\n  compressed output when it wants, for example when the output buffer is full\n  (avail_out == 0), or after each call of deflate(). If deflate returns Z_OK\n  and with zero avail_out, it must be called again after making room in the\n  output buffer because there might be more output pending.\n\n    If the parameter flush is set to Z_PARTIAL_FLUSH, the current compression\n  block is terminated and flushed to the output buffer so that the\n  decompressor can get all input data available so far. For method 9, a future\n  variant on method 8, the current block will be flushed but not terminated.\n  Z_SYNC_FLUSH has the same effect as partial flush except that the compressed\n  output is byte aligned (the compressor can clear its internal bit buffer)\n  and the current block is always terminated; this can be useful if the\n  compressor has to be restarted from scratch after an interruption (in which\n  case the internal state of the compressor may be lost).\n    If flush is set to Z_FULL_FLUSH, the compression block is terminated, a\n  special marker is output and the compression dictionary is discarded; this\n  is useful to allow the decompressor to synchronize if one compressed block\n  has been damaged (see inflateSync below).  Flushing degrades compression and\n  so should be used only when necessary.  Using Z_FULL_FLUSH too often can\n  seriously degrade the compression. If deflate returns with avail_out == 0,\n  this function must be called again with the same value of the flush\n  parameter and more output space (updated avail_out), until the flush is\n  complete (deflate returns with non-zero avail_out).\n\n    If the parameter flush is set to Z_FINISH, all pending input is processed,\n  all pending output is flushed and deflate returns with Z_STREAM_END if there\n  was enough output space; if deflate returns with Z_OK, this function must be\n  called again with Z_FINISH and more output space (updated avail_out) but no\n  more input data, until it returns with Z_STREAM_END or an error. After\n  deflate has returned Z_STREAM_END, the only possible operations on the\n  stream are deflateReset or deflateEnd.\n\n    Z_FINISH can be used immediately after deflateInit if all the compression\n  is to be done in a single step. In this case, avail_out must be at least\n  0.1% larger than avail_in plus 12 bytes.  If deflate does not return\n  Z_STREAM_END, then it must be called again as described above.\n\n    deflate() may update data_type if it can make a good guess about\n  the input data type (Z_ASCII or Z_BINARY). In doubt, the data is considered\n  binary. This field is only for information purposes and does not affect\n  the compression algorithm in any manner.\n\n    deflate() returns Z_OK if some progress has been made (more input\n  processed or more output produced), Z_STREAM_END if all input has been\n  consumed and all output has been produced (only when flush is set to\n  Z_FINISH), Z_STREAM_ERROR if the stream state was inconsistent (for example\n  if next_in or next_out was NULL), Z_BUF_ERROR if no progress is possible. }\n\n\nfunction deflateEnd (var strm : z_stream) : int;\n\n{     All dynamically allocated data structures for this stream are freed.\n   This function discards any unprocessed input and does not flush any\n   pending output.\n\n     deflateEnd returns Z_OK if success, Z_STREAM_ERROR if the\n   stream state was inconsistent, Z_DATA_ERROR if the stream was freed\n   prematurely (some input or output was discarded). In the error case,\n   msg may be set but then points to a static string (which must not be\n   deallocated). }\n\n\n\n\n                        { Advanced functions }\n\n{ The following functions are needed only in some special applications. }\n\n\n{EXPORT}\nfunction deflateInit2 (var strm : z_stream;\n                       level : int;\n                       method : int;\n                       windowBits : int;\n                       memLevel : int;\n                       strategy : int) : int;\n\n{  This is another version of deflateInit with more compression options. The\n   fields next_in, zalloc, zfree and opaque must be initialized before by\n   the caller.\n\n     The method parameter is the compression method. It must be Z_DEFLATED in\n   this version of the library. (Method 9 will allow a 64K history buffer and\n   partial block flushes.)\n\n     The windowBits parameter is the base two logarithm of the window size\n   (the size of the history buffer).  It should be in the range 8..15 for this\n   version of the library (the value 16 will be allowed for method 9). Larger\n   values of this parameter result in better compression at the expense of\n   memory usage. The default value is 15 if deflateInit is used instead.\n\n     The memLevel parameter specifies how much memory should be allocated\n   for the internal compression state. memLevel=1 uses minimum memory but\n   is slow and reduces compression ratio; memLevel=9 uses maximum memory\n   for optimal speed. The default value is 8. See zconf.h for total memory\n   usage as a function of windowBits and memLevel.\n\n     The strategy parameter is used to tune the compression algorithm. Use the\n   value Z_DEFAULT_STRATEGY for normal data, Z_FILTERED for data produced by a\n   filter (or predictor), or Z_HUFFMAN_ONLY to force Huffman encoding only (no\n   string match).  Filtered data consists mostly of small values with a\n   somewhat random distribution. In this case, the compression algorithm is\n   tuned to compress them better. The effect of Z_FILTERED is to force more\n   Huffman coding and less string matching; it is somewhat intermediate\n   between Z_DEFAULT and Z_HUFFMAN_ONLY. The strategy parameter only affects\n   the compression ratio but not the correctness of the compressed output even\n   if it is not set appropriately.\n\n     If next_in is not null, the library will use this buffer to hold also\n   some history information; the buffer must either hold the entire input\n   data, or have at least 1<<(windowBits+1) bytes and be writable. If next_in\n   is null, the library will allocate its own history buffer (and leave next_in\n   null). next_out need not be provided here but must be provided by the\n   application for the next call of deflate().\n\n     If the history buffer is provided by the application, next_in must\n   must never be changed by the application since the compressor maintains\n   information inside this buffer from call to call; the application\n   must provide more input only by increasing avail_in. next_in is always\n   reset by the library in this case.\n\n      deflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was\n   not enough memory, Z_STREAM_ERROR if a parameter is invalid (such as\n   an invalid method). msg is set to null if there is no error message.\n   deflateInit2 does not perform any compression: this will be done by\n   deflate(). }\n\n\n{EXPORT}\nfunction deflateSetDictionary (var strm : z_stream;\n                               dictionary : pBytef; {const bytes}\n\t\t\t       dictLength : uint) : int;\n\n{    Initializes the compression dictionary (history buffer) from the given\n   byte sequence without producing any compressed output. This function must\n   be called immediately after deflateInit or deflateInit2, before any call\n   of deflate. The compressor and decompressor must use exactly the same\n   dictionary (see inflateSetDictionary).\n     The dictionary should consist of strings (byte sequences) that are likely\n   to be encountered later in the data to be compressed, with the most commonly\n   used strings preferably put towards the end of the dictionary. Using a\n   dictionary is most useful when the data to be compressed is short and\n   can be predicted with good accuracy; the data can then be compressed better\n   than with the default empty dictionary. In this version of the library,\n   only the last 32K bytes of the dictionary are used.\n     Upon return of this function, strm->adler is set to the Adler32 value\n   of the dictionary; the decompressor may later use this value to determine\n   which dictionary has been used by the compressor. (The Adler32 value\n   applies to the whole dictionary even if only a subset of the dictionary is\n   actually used by the compressor.)\n\n     deflateSetDictionary returns Z_OK if success, or Z_STREAM_ERROR if a\n   parameter is invalid (such as NULL dictionary) or the stream state\n   is inconsistent (for example if deflate has already been called for this\n   stream). deflateSetDictionary does not perform any compression: this will\n   be done by deflate(). }\n\n{EXPORT}\nfunction deflateCopy (dest : z_streamp;\n                      source : z_streamp) : int;\n\n{  Sets the destination stream as a complete copy of the source stream.  If\n   the source stream is using an application-supplied history buffer, a new\n   buffer is allocated for the destination stream.  The compressed output\n   buffer is always application-supplied. It's the responsibility of the\n   application to provide the correct values of next_out and avail_out for the\n   next call of deflate.\n\n     This function can be useful when several compression strategies will be\n   tried, for example when there are several ways of pre-processing the input\n   data with a filter. The streams that will be discarded should then be freed\n   by calling deflateEnd.  Note that deflateCopy duplicates the internal\n   compression state which can be quite large, so this strategy is slow and\n   can consume lots of memory.\n\n     deflateCopy returns Z_OK if success, Z_MEM_ERROR if there was not\n   enough memory, Z_STREAM_ERROR if the source stream state was inconsistent\n   (such as zalloc being NULL). msg is left unchanged in both source and\n   destination. }\n\n{EXPORT}\nfunction deflateReset (var strm : z_stream) : int;\n\n{   This function is equivalent to deflateEnd followed by deflateInit,\n   but does not free and reallocate all the internal compression state.\n   The stream will keep the same compression level and any other attributes\n   that may have been set by deflateInit2.\n\n      deflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source\n   stream state was inconsistent (such as zalloc or state being NIL). }\n\n\n{EXPORT}\nfunction deflateParams (var strm : z_stream; level : int; strategy : int) : int;\n\n{    Dynamically update the compression level and compression strategy.\n   This can be used to switch between compression and straight copy of\n   the input data, or to switch to a different kind of input data requiring\n   a different strategy. If the compression level is changed, the input\n   available so far is compressed with the old level (and may be flushed);\n   the new level will take effect only at the next call of deflate().\n\n     Before the call of deflateParams, the stream state must be set as for\n   a call of deflate(), since the currently available input may have to\n   be compressed and flushed. In particular, strm->avail_out must be non-zero.\n\n     deflateParams returns Z_OK if success, Z_STREAM_ERROR if the source\n   stream state was inconsistent or if a parameter was invalid, Z_BUF_ERROR\n   if strm->avail_out was zero. }\n\n\nconst\n   deflate_copyright : string = ' deflate 1.1.2 Copyright 1995-1998 Jean-loup Gailly ';\n\n{ If you use the zlib library in a product, an acknowledgment is welcome\n  in the documentation of your product. If for some reason you cannot\n  include such an acknowledgment, I would appreciate that you keep this\n  copyright string in the executable of your product. }\n\nimplementation\n\nuses\n  imtrees, imadler;\n\n{  ===========================================================================\n   Function prototypes. }\n\ntype\n   block_state = (\n    need_more,      { block not completed, need more input or more output }\n    block_done,     { block flush performed }\n    finish_started, { finish started, need only more output at next deflate }\n    finish_done);   { finish done, accept no more input or output }\n\n{ Compression function. Returns the block state after the call. }\ntype\n  compress_func = function(var s : deflate_state; flush : int) : block_state;\n\n{local}\nprocedure fill_window(var s : deflate_state); forward;\n{local}\nfunction deflate_stored(var s : deflate_state; flush : int) : block_state;   forward;\n{local}\nfunction deflate_fast(var s : deflate_state; flush : int) : block_state;   forward;\n{local}\nfunction deflate_slow(var s : deflate_state; flush : int) : block_state;   forward;\n{local}\nprocedure lm_init(var s : deflate_state); forward;\n\n{local}\nprocedure putShortMSB(var s : deflate_state; b : uInt); forward;\n{local}\nprocedure  flush_pending (var strm : z_stream); forward;\n{local}\nfunction read_buf(strm : z_streamp;\n                  buf : pBytef;\n                  size : unsigned) : int; forward;\n{$ifdef ASMV}\nprocedure match_init; { asm code initialization }\nfunction longest_match(var deflate_state; cur_match : IPos) : uInt; forward;\n{$else}\n{local}\nfunction longest_match(var s : deflate_state; cur_match : IPos) : uInt;\n  forward;\n{$endif}\n\n{$ifdef DEBUG}\n{local}\nprocedure check_match(var s : deflate_state;\n                      start, match : IPos;\n                      length : int); forward;\n{$endif}\n\n{  ==========================================================================\n  local data }\n\nconst\n  ZNIL = 0;\n{ Tail of hash chains }\n\nconst\n  TOO_FAR = 4096;\n{ Matches of length 3 are discarded if their distance exceeds TOO_FAR }\n\nconst\n  MIN_LOOKAHEAD = (MAX_MATCH+MIN_MATCH+1);\n{ Minimum amount of lookahead, except at the end of the input file.\n  See deflate.c for comments about the MIN_MATCH+1. }\n\n{macro MAX_DIST(var s : deflate_state) : uInt;\nbegin\n  MAX_DIST := (s.w_size - MIN_LOOKAHEAD);\nend;\n  In order to simplify the code, particularly on 16 bit machines, match\n  distances are limited to MAX_DIST instead of WSIZE. }\n\n\n{ Values for max_lazy_match, good_match and max_chain_length, depending on\n  the desired pack level (0..9). The values given below have been tuned to\n  exclude worst case performance for pathological files. Better values may be\n  found for specific files. }\n\ntype\n  config = record\n   good_length : ush; { reduce lazy search above this match length }\n   max_lazy : ush;    { do not perform lazy search above this match length }\n   nice_length : ush; { quit search above this match length }\n   max_chain : ush;\n   func : compress_func;\n  end;\n\n{local}\nconst\n  configuration_table : array[0..10-1] of config = (\n{      good lazy nice chain }\n{0} (good_length:0;  max_lazy:0;   nice_length:0;   max_chain:0;    func:deflate_stored),  { store only }\n{1} (good_length:4;  max_lazy:4;   nice_length:8;   max_chain:4;    func:deflate_fast), { maximum speed, no lazy matches }\n{2} (good_length:4;  max_lazy:5;   nice_length:16;  max_chain:8;    func:deflate_fast),\n{3} (good_length:4;  max_lazy:6;   nice_length:32;  max_chain:32;   func:deflate_fast),\n\n{4} (good_length:4;  max_lazy:4;   nice_length:16;  max_chain:16;   func:deflate_slow),  { lazy matches }\n{5} (good_length:8;  max_lazy:16;  nice_length:32;  max_chain:32;   func:deflate_slow),\n{6} (good_length:8;  max_lazy:16;  nice_length:128; max_chain:128;  func:deflate_slow),\n{7} (good_length:8;  max_lazy:32;  nice_length:128; max_chain:256;  func:deflate_slow),\n{8} (good_length:32; max_lazy:128; nice_length:258; max_chain:1024; func:deflate_slow),\n{9} (good_length:32; max_lazy:258; nice_length:258; max_chain:4096; func:deflate_slow)); { maximum compression }\n\n{ Note: the deflate() code requires max_lazy >= MIN_MATCH and max_chain >= 4\n  For deflate_fast() (levels <= 3) good is ignored and lazy has a different\n  meaning. }\n\nconst\n  EQUAL = 0;\n{ result of memcmp for equal strings }\n\n{ ==========================================================================\n  Update a hash value with the given input byte\n  IN  assertion: all calls to to UPDATE_HASH are made with consecutive\n     input characters, so that a running hash key can be computed from the\n     previous key instead of complete recalculation each time.\n\nmacro UPDATE_HASH(s,h,c)\n   h := (( (h) shl s^.hash_shift) xor (c)) and s^.hash_mask;\n}\n\n{ ===========================================================================\n  Insert string str in the dictionary and set match_head to the previous head\n  of the hash chain (the most recent string with same hash key). Return\n  the previous length of the hash chain.\n  If this file is compiled with -DFASTEST, the compression level is forced\n  to 1, and no hash chains are maintained.\n  IN  assertion: all calls to to INSERT_STRING are made with consecutive\n     input characters and the first MIN_MATCH bytes of str are valid\n     (except for the last MIN_MATCH-1 bytes of the input file). }\n\nprocedure INSERT_STRING(var s : deflate_state;\n                        str : uInt;\n                        var match_head : IPos);\nbegin\n{$ifdef FASTEST}\n   {UPDATE_HASH(s, s.ins_h, s.window[(str) + (MIN_MATCH-1)])}\n    s.ins_h := ((s.ins_h shl s.hash_shift) xor\n                 (s.window^[(str) + (MIN_MATCH-1)])) and s.hash_mask;\n    match_head := s.head[s.ins_h]\n    s.head[s.ins_h] := Pos(str);\n{$else}\n   {UPDATE_HASH(s, s.ins_h, s.window[(str) + (MIN_MATCH-1)])}\n    s.ins_h := ((s.ins_h shl s.hash_shift) xor\n                 (s.window^[(str) + (MIN_MATCH-1)])) and s.hash_mask;\n\n    match_head := s.head^[s.ins_h];\n    s.prev^[(str) and s.w_mask] := match_head;\n    s.head^[s.ins_h] := Pos(str);\n{$endif}\nend;\n\n{  =========================================================================\n  Initialize the hash table (avoiding 64K overflow for 16 bit systems).\n  prev[] will be initialized on the fly.\n\nmacro CLEAR_HASH(s)\n    s^.head[s^.hash_size-1] := ZNIL;\n    zmemzero(pBytef(s^.head), unsigned(s^.hash_size-1)*sizeof(s^.head^[0]));\n}\n\n{  ======================================================================== }\n\nfunction deflateInit2_(var strm : z_stream;\n                       level : int;\n                       method : int;\n                       windowBits : int;\n                       memLevel : int;\n                       strategy : int;\n                       const version : AnsiString;\n                       stream_size : int) : int;\nvar\n  s : deflate_state_ptr;\n  noheader : int;\n\n  overlay : pushfArray;\n  { We overlay pending_buf and d_buf+l_buf. This works since the average\n    output size for (length,distance) codes is <= 24 bits. }\nbegin\n  noheader := 0;\n  if (version  =  '') or (version[1] <> ZLIB_VERSION[1]) or\n     (stream_size <> sizeof(z_stream)) then\n  begin\n    deflateInit2_ := Z_VERSION_ERROR;\n    exit;\n  end;\n  {\n  if (strm = Z_NULL) then\n  begin\n    deflateInit2_ := Z_STREAM_ERROR;\n    exit;\n  end;\n  }\n  { SetLength(strm.msg, 255); }\n  strm.msg := '';\n  if not Assigned(strm.zalloc) then\n  begin\n    {$IFDEF FPC}  strm.zalloc := @zcalloc;  {$ELSE}\n    strm.zalloc := zcalloc;\n    {$ENDIF}\n    strm.opaque := voidpf(0);\n  end;\n  if not Assigned(strm.zfree) then\n    {$IFDEF FPC}  strm.zfree := @zcfree;  {$ELSE}\n    strm.zfree := zcfree;\n    {$ENDIF}\n\n  if (level  =  Z_DEFAULT_COMPRESSION) then\n    level := 6;\n{$ifdef FASTEST}\n    level := 1;\n{$endif}\n\n  if (windowBits < 0) then { undocumented feature: suppress zlib header }\n  begin\n    noheader := 1;\n    windowBits := -windowBits;\n  end;\n  if (memLevel < 1) or (memLevel > MAX_MEM_LEVEL) or (method <> Z_DEFLATED)\n    or (windowBits < 8) or (windowBits > 15) or (level < 0)\n    or (level > 9) or (strategy < 0) or (strategy > Z_HUFFMAN_ONLY) then\n  begin\n    deflateInit2_ := Z_STREAM_ERROR;\n    exit;\n  end;\n\n  s := deflate_state_ptr (ZALLOC(strm, 1, sizeof(deflate_state)));\n  if (s = Z_NULL) then\n  begin\n    deflateInit2_ := Z_MEM_ERROR;\n    exit;\n  end;\n  strm.state := pInternal_state(s);\n  s^.strm := @strm;\n\n  s^.noheader := noheader;\n  s^.w_bits := windowBits;\n  s^.w_size := 1 shl s^.w_bits;\n  s^.w_mask := s^.w_size - 1;\n\n  s^.hash_bits := memLevel + 7;\n  s^.hash_size := 1 shl s^.hash_bits;\n  s^.hash_mask := s^.hash_size - 1;\n  s^.hash_shift :=  ((s^.hash_bits+MIN_MATCH-1) div MIN_MATCH);\n\n  s^.window := pzByteArray (ZALLOC(strm, s^.w_size, 2*sizeof(Byte)));\n  s^.prev   := pzPosfArray (ZALLOC(strm, s^.w_size, sizeof(Pos)));\n  s^.head   := pzPosfArray (ZALLOC(strm, s^.hash_size, sizeof(Pos)));\n\n  s^.lit_bufsize := 1 shl (memLevel + 6); { 16K elements by default }\n\n  overlay := pushfArray (ZALLOC(strm, s^.lit_bufsize, sizeof(ush)+2));\n  s^.pending_buf := pzByteArray (overlay);\n  s^.pending_buf_size := ulg(s^.lit_bufsize) * (sizeof(ush)+Long(2));\n\n  if (s^.window = Z_NULL) or (s^.prev = Z_NULL) or (s^.head = Z_NULL)\n   or (s^.pending_buf = Z_NULL) then\n  begin\n    {ERR_MSG(Z_MEM_ERROR);}\n    strm.msg := z_errmsg[z_errbase-Z_MEM_ERROR];\n    deflateEnd (strm);\n    deflateInit2_ := Z_MEM_ERROR;\n    exit;\n  end;\n  s^.d_buf := pushfArray( @overlay^[s^.lit_bufsize div sizeof(ush)] );\n  s^.l_buf := puchfArray( @s^.pending_buf^[(1+sizeof(ush))*s^.lit_bufsize] );\n\n  s^.level := level;\n  s^.strategy := strategy;\n  s^.method := Byte(method);\n\n  deflateInit2_ := deflateReset(strm);\nend;\n\n{  ========================================================================= }\n\nfunction deflateInit2(var strm : z_stream;\n                      level : int;\n                      method : int;\n                      windowBits : int;\n                      memLevel : int;\n                      strategy : int) : int;\n{ a macro }\nbegin\n  deflateInit2 := deflateInit2_(strm, level, method, windowBits,\n                   memLevel, strategy, ZLIB_VERSION, sizeof(z_stream));\nend;\n\n{  ========================================================================= }\n\nfunction deflateInit_(strm : z_streamp;\n                      level : int;\n                      const version : AnsiString;\n                      stream_size : int) : int;\nbegin\n  if (strm = Z_NULL) then\n    deflateInit_ := Z_STREAM_ERROR\n  else\n    deflateInit_ := deflateInit2_(strm^, level, Z_DEFLATED, MAX_WBITS,\n                   DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY, version, stream_size);\n  { To do: ignore strm^.next_in if we use it as window }\nend;\n\n{  ========================================================================= }\n\nfunction deflateInit(var strm : z_stream; level : int) : int;\n{ deflateInit is a macro to allow checking the zlib version\n  and the compiler's view of z_stream: }\nbegin\n  deflateInit := deflateInit2_(strm, level, Z_DEFLATED, MAX_WBITS,\n         DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY, ZLIB_VERSION, sizeof(z_stream));\nend;\n\n{  ======================================================================== }\nfunction deflateSetDictionary (var strm : z_stream;\n                               dictionary : pBytef;\n                               dictLength : uInt) : int;\nvar\n  s : deflate_state_ptr;\n  length : uInt;\n  n : uInt;\n  hash_head : IPos;\nvar\n  MAX_DIST : uInt;  {macro}\nbegin\n  length := dictLength;\n  hash_head := 0;\n\n  if {(@strm  =  Z_NULL) or}\n     (strm.state  =  Z_NULL) or (dictionary  =  Z_NULL)\n    or (deflate_state_ptr(strm.state)^.status <> INIT_STATE) then\n  begin\n    deflateSetDictionary := Z_STREAM_ERROR;\n    exit;\n  end;\n\n  s := deflate_state_ptr(strm.state);\n  strm.adler := adler32(strm.adler, dictionary, dictLength);\n\n  if (length < MIN_MATCH) then\n  begin\n    deflateSetDictionary := Z_OK;\n    exit;\n  end;\n  MAX_DIST := (s^.w_size - MIN_LOOKAHEAD);\n  if (length > MAX_DIST) then\n  begin\n    length := MAX_DIST;\n{$ifndef USE_DICT_HEAD}\n    Inc(dictionary, dictLength - length);  { use the tail of the dictionary }\n{$endif}\n  end;\n\n  zmemcpy( pBytef(s^.window), dictionary, length);\n  s^.strstart := length;\n  s^.block_start := long(length);\n\n  { Insert all strings in the hash table (except for the last two bytes).\n    s^.lookahead stays null, so s^.ins_h will be recomputed at the next\n    call of fill_window. }\n\n  s^.ins_h := s^.window^[0];\n  {UPDATE_HASH(s, s^.ins_h, s^.window[1]);}\n  s^.ins_h := ((s^.ins_h shl s^.hash_shift) xor (s^.window^[1]))\n              and s^.hash_mask;\n\n  for n := 0 to length - MIN_MATCH do\n  begin\n    INSERT_STRING(s^, n, hash_head);\n  end;\n  {if (hash_head <> 0) then\n    hash_head := 0;  - to make compiler happy }\n  deflateSetDictionary := Z_OK;\nend;\n\n{  ======================================================================== }\nfunction deflateReset (var strm : z_stream) : int;\nvar\n  s : deflate_state_ptr;\nbegin\n  if {(@strm = Z_NULL) or}\n   (strm.state = Z_NULL)\n   or (not Assigned(strm.zalloc)) or (not Assigned(strm.zfree)) then\n  begin\n    deflateReset := Z_STREAM_ERROR;\n    exit;\n  end;\n\n  strm.total_out := 0;\n  strm.total_in := 0;\n  strm.msg := '';      { use zfree if we ever allocate msg dynamically }\n  strm.data_type := Z_UNKNOWN;\n\n  s := deflate_state_ptr(strm.state);\n  s^.pending := 0;\n  s^.pending_out := pBytef(s^.pending_buf);\n\n  if (s^.noheader < 0) then\n  begin\n    s^.noheader := 0; { was set to -1 by deflate(..., Z_FINISH); }\n  end;\n  if s^.noheader <> 0 then\n    s^.status := BUSY_STATE\n  else\n    s^.status := INIT_STATE;\n  strm.adler := 1;\n  s^.last_flush := Z_NO_FLUSH;\n\n  _tr_init(s^);\n  lm_init(s^);\n\n  deflateReset := Z_OK;\nend;\n\n{  ======================================================================== }\nfunction deflateParams(var strm : z_stream;\n                       level : int;\n                       strategy : int) : int;\nvar\n  s : deflate_state_ptr;\n  func : compress_func;\n  err : int;\nbegin\n  err := Z_OK;\n  if {(@strm  =  Z_NULL) or} (strm.state  =  Z_NULL) then\n  begin\n    deflateParams := Z_STREAM_ERROR;\n    exit;\n  end;\n\n  s := deflate_state_ptr(strm.state);\n\n  if (level = Z_DEFAULT_COMPRESSION) then\n  begin\n    level := 6;\n  end;\n  if (level < 0) or (level > 9) or (strategy < 0)\n  or (strategy > Z_HUFFMAN_ONLY) then\n  begin\n    deflateParams := Z_STREAM_ERROR;\n    exit;\n  end;\n  func := configuration_table[s^.level].func;\n\n  if (@func <> @configuration_table[level].func)\n    and (strm.total_in <> 0) then\n  begin\n      { Flush the last buffer: }\n      err := deflate(strm, Z_PARTIAL_FLUSH);\n  end;\n  if (s^.level <> level) then\n  begin\n    s^.level := level;\n    s^.max_lazy_match   := configuration_table[level].max_lazy;\n    s^.good_match       := configuration_table[level].good_length;\n    s^.nice_match       := configuration_table[level].nice_length;\n    s^.max_chain_length := configuration_table[level].max_chain;\n  end;\n  s^.strategy := strategy;\n  deflateParams := err;\nend;\n\n{ =========================================================================\n  Put a short in the pending buffer. The 16-bit value is put in MSB order.\n  IN assertion: the stream state is correct and there is enough room in\n  pending_buf. }\n\n{local}\nprocedure putShortMSB (var s : deflate_state; b : uInt);\nbegin\n  s.pending_buf^[s.pending] := Byte(b shr 8);\n  Inc(s.pending);\n  s.pending_buf^[s.pending] := Byte(b and $ff);\n  Inc(s.pending);\nend;\n\n{ =========================================================================\n  Flush as much pending output as possible. All deflate() output goes\n  through this function so some applications may wish to modify it\n  to avoid allocating a large strm^.next_out buffer and copying into it.\n  (See also read_buf()). }\n\n{local}\nprocedure flush_pending(var strm : z_stream);\nvar\n  len : unsigned;\n  s : deflate_state_ptr;\nbegin\n  s := deflate_state_ptr(strm.state);\n  len := s^.pending;\n\n  if (len > strm.avail_out) then\n    len := strm.avail_out;\n  if (len = 0) then\n    exit;\n\n  zmemcpy(strm.next_out, s^.pending_out, len);\n  Inc(strm.next_out, len);\n  Inc(s^.pending_out, len);\n  Inc(strm.total_out, len);\n  Dec(strm.avail_out, len);\n  Dec(s^.pending, len);\n  if (s^.pending = 0) then\n  begin\n    s^.pending_out := pBytef(s^.pending_buf);\n  end;\nend;\n\n{ ========================================================================= }\nfunction deflate (var strm : z_stream; flush : int) : int;\nvar\n  old_flush : int; { value of flush param for previous deflate call }\n  s : deflate_state_ptr;\nvar\n  header : uInt;\n  level_flags : uInt;\nvar\n  bstate : block_state;\nbegin\n  if {(@strm = Z_NULL) or} (strm.state = Z_NULL)\n    or (flush > Z_FINISH) or (flush < 0) then\n  begin\n    deflate := Z_STREAM_ERROR;\n    exit;\n  end;\n  s := deflate_state_ptr(strm.state);\n\n  if (strm.next_out = Z_NULL) or\n     ((strm.next_in = Z_NULL) and (strm.avail_in <> 0)) or\n     ((s^.status = FINISH_STATE) and (flush <> Z_FINISH)) then\n  begin\n    {ERR_RETURN(strm^, Z_STREAM_ERROR);}\n    strm.msg := z_errmsg[z_errbase - Z_STREAM_ERROR];\n    deflate := Z_STREAM_ERROR;\n    exit;\n  end;\n  if (strm.avail_out = 0) then\n  begin\n    {ERR_RETURN(strm^, Z_BUF_ERROR);}\n    strm.msg := z_errmsg[z_errbase - Z_BUF_ERROR];\n    deflate := Z_BUF_ERROR;\n    exit;\n  end;\n\n  s^.strm := @strm; { just in case }\n  old_flush := s^.last_flush;\n  s^.last_flush := flush;\n\n  { Write the zlib header }\n  if (s^.status = INIT_STATE) then\n  begin\n\n    header := (Z_DEFLATED + ((s^.w_bits-8) shl 4)) shl 8;\n    level_flags := (s^.level-1) shr 1;\n\n    if (level_flags > 3) then\n      level_flags := 3;\n    header := header or (level_flags shl 6);\n    if (s^.strstart <> 0) then\n      header := header or PRESET_DICT;\n    Inc(header, 31 - (header mod 31));\n\n    s^.status := BUSY_STATE;\n    putShortMSB(s^, header);\n\n    { Save the adler32 of the preset dictionary: }\n    if (s^.strstart <> 0) then\n    begin\n      putShortMSB(s^, uInt(strm.adler shr 16));\n      putShortMSB(s^, uInt(strm.adler and $ffff));\n    end;\n    strm.adler := long(1);\n  end;\n\n  { Flush as much pending output as possible }\n  if (s^.pending <> 0) then\n  begin\n    flush_pending(strm);\n    if (strm.avail_out = 0) then\n    begin\n      { Since avail_out is 0, deflate will be called again with\n\tmore output space, but possibly with both pending and\n\tavail_in equal to zero. There won't be anything to do,\n\tbut this is not an error situation so make sure we\n\treturn OK instead of BUF_ERROR at next call of deflate: }\n\n      s^.last_flush := -1;\n      deflate := Z_OK;\n      exit;\n    end;\n\n  { Make sure there is something to do and avoid duplicate consecutive\n    flushes. For repeated and useless calls with Z_FINISH, we keep\n    returning Z_STREAM_END instead of Z_BUFF_ERROR. }\n\n  end\n  else\n    if (strm.avail_in = 0) and (flush <= old_flush)\n      and (flush <> Z_FINISH) then\n    begin\n      {ERR_RETURN(strm^, Z_BUF_ERROR);}\n      strm.msg := z_errmsg[z_errbase - Z_BUF_ERROR];\n      deflate := Z_BUF_ERROR;\n      exit;\n    end;\n\n  { User must not provide more input after the first FINISH: }\n  if (s^.status = FINISH_STATE) and (strm.avail_in <> 0) then\n  begin\n    {ERR_RETURN(strm^, Z_BUF_ERROR);}\n    strm.msg := z_errmsg[z_errbase - Z_BUF_ERROR];\n    deflate := Z_BUF_ERROR;\n    exit;\n  end;\n\n  { Start a new block or continue the current one. }\n  if (strm.avail_in <> 0) or (s^.lookahead <> 0)\n    or ((flush <> Z_NO_FLUSH) and (s^.status <> FINISH_STATE)) then\n  begin\n    bstate := configuration_table[s^.level].func(s^, flush);\n\n    if (bstate = finish_started) or (bstate = finish_done) then\n      s^.status := FINISH_STATE;\n\n    if (bstate = need_more) or (bstate = finish_started) then\n    begin\n      if (strm.avail_out = 0) then\n        s^.last_flush := -1; { avoid BUF_ERROR next call, see above }\n\n      deflate := Z_OK;\n      exit;\n      { If flush != Z_NO_FLUSH && avail_out == 0, the next call\n\tof deflate should use the same flush parameter to make sure\n\tthat the flush is complete. So we don't have to output an\n\tempty block here, this will be done at next call. This also\n\tensures that for a very small output buffer, we emit at most\n\t one empty block. }\n    end;\n    if (bstate = block_done) then\n    begin\n      if (flush = Z_PARTIAL_FLUSH) then\n        _tr_align(s^)\n      else\n      begin  { FULL_FLUSH or SYNC_FLUSH }\n        _tr_stored_block(s^, pcharf(NIL), Long(0), FALSE);\n        { For a full flush, this empty block will be recognized\n          as a special marker by inflate_sync(). }\n\n        if (flush = Z_FULL_FLUSH) then\n        begin\n          {macro CLEAR_HASH(s);}             { forget history }\n          s^.head^[s^.hash_size-1] := ZNIL;\n          zmemzero(pBytef(s^.head), unsigned(s^.hash_size-1)*sizeof(s^.head^[0]));\n        end;\n      end;\n\n      flush_pending(strm);\n      if (strm.avail_out = 0) then\n      begin\n        s^.last_flush := -1; { avoid BUF_ERROR at next call, see above }\n\tdeflate := Z_OK;\n        exit;\n      end;\n\n    end;\n  end;\n  {$IFDEF DEBUG}\n  Assert(strm.avail_out > 0, 'bug2');\n  {$ENDIF}\n  if (flush <> Z_FINISH) then\n  begin\n    deflate := Z_OK;\n    exit;\n  end;\n\n  if (s^.noheader <> 0) then\n  begin\n    deflate := Z_STREAM_END;\n    exit;\n  end;\n\n  { Write the zlib trailer (adler32) }\n  putShortMSB(s^, uInt(strm.adler shr 16));\n  putShortMSB(s^, uInt(strm.adler and $ffff));\n  flush_pending(strm);\n  { If avail_out is zero, the application will call deflate again\n    to flush the rest. }\n\n  s^.noheader := -1; { write the trailer only once! }\n  if s^.pending <> 0 then\n    deflate := Z_OK\n  else\n    deflate := Z_STREAM_END;\nend;\n\n{ ========================================================================= }\nfunction deflateEnd (var strm : z_stream) : int;\nvar\n  status : int;\n  s : deflate_state_ptr;\nbegin\n  if {(@strm = Z_NULL) or} (strm.state = Z_NULL) then\n  begin\n    deflateEnd := Z_STREAM_ERROR;\n    exit;\n  end;\n\n  s := deflate_state_ptr(strm.state);\n  status := s^.status;\n  if (status <> INIT_STATE) and (status <> BUSY_STATE) and\n     (status <> FINISH_STATE) then\n  begin\n    deflateEnd := Z_STREAM_ERROR;\n    exit;\n  end;\n\n  { Deallocate in reverse order of allocations: }\n  TRY_FREE(strm, s^.pending_buf);\n  TRY_FREE(strm, s^.head);\n  TRY_FREE(strm, s^.prev);\n  TRY_FREE(strm, s^.window);\n\n  ZFREE(strm, s);\n  strm.state := Z_NULL;\n\n  if status = BUSY_STATE then\n    deflateEnd := Z_DATA_ERROR\n  else\n    deflateEnd := Z_OK;\nend;\n\n{ =========================================================================\n  Copy the source state to the destination state.\n  To simplify the source, this is not supported for 16-bit MSDOS (which\n  doesn't have enough memory anyway to duplicate compression states). }\n\n\n{ ========================================================================= }\nfunction deflateCopy (dest, source : z_streamp) : int;\n{$ifndef MAXSEG_64K}\nvar\n  ds : deflate_state_ptr;\n  ss : deflate_state_ptr;\n  overlay : pushfArray;\n{$endif}\nbegin\n{$ifdef MAXSEG_64K}\n  deflateCopy := Z_STREAM_ERROR;\n  exit;\n{$else}\n\n  if (source = Z_NULL) or (dest = Z_NULL) or (source^.state = Z_NULL) then\n  begin\n    deflateCopy := Z_STREAM_ERROR;\n    exit;\n  end;\n  ss := deflate_state_ptr(source^.state);\n  dest^ := source^;\n\n  ds := deflate_state_ptr( ZALLOC(dest^, 1, sizeof(deflate_state)) );\n  if (ds = Z_NULL) then\n  begin\n    deflateCopy := Z_MEM_ERROR;\n    exit;\n  end;\n  dest^.state := pInternal_state(ds);\n  ds^ := ss^;\n  ds^.strm := dest;\n\n  ds^.window := pzByteArray ( ZALLOC(dest^, ds^.w_size, 2*sizeof(Byte)) );\n  ds^.prev   := pzPosfArray ( ZALLOC(dest^, ds^.w_size, sizeof(Pos)) );\n  ds^.head   := pzPosfArray ( ZALLOC(dest^, ds^.hash_size, sizeof(Pos)) );\n  overlay := pushfArray ( ZALLOC(dest^, ds^.lit_bufsize, sizeof(ush)+2) );\n  ds^.pending_buf := pzByteArray ( overlay );\n\n  if (ds^.window = Z_NULL) or (ds^.prev = Z_NULL) or (ds^.head = Z_NULL)\n     or (ds^.pending_buf = Z_NULL) then\n  begin\n    deflateEnd (dest^);\n    deflateCopy := Z_MEM_ERROR;\n    exit;\n  end;\n  { following zmemcpy do not work for 16-bit MSDOS }\n  zmemcpy(pBytef(ds^.window), pBytef(ss^.window), ds^.w_size * 2 * sizeof(Byte));\n  zmemcpy(pBytef(ds^.prev), pBytef(ss^.prev), ds^.w_size * sizeof(Pos));\n  zmemcpy(pBytef(ds^.head), pBytef(ss^.head), ds^.hash_size * sizeof(Pos));\n  zmemcpy(pBytef(ds^.pending_buf), pBytef(ss^.pending_buf), uInt(ds^.pending_buf_size));\n\n  ds^.pending_out := @ds^.pending_buf^[ptr2int(ss^.pending_out) - ptr2int(ss^.pending_buf)];\n  ds^.d_buf := pushfArray (@overlay^[ds^.lit_bufsize div sizeof(ush)] );\n  ds^.l_buf := puchfArray (@ds^.pending_buf^[(1+sizeof(ush))*ds^.lit_bufsize]);\n\n  ds^.l_desc.dyn_tree := tree_ptr(@ds^.dyn_ltree);\n  ds^.d_desc.dyn_tree := tree_ptr(@ds^.dyn_dtree);\n  ds^.bl_desc.dyn_tree := tree_ptr(@ds^.bl_tree);\n\n  deflateCopy := Z_OK;\n{$endif}\nend;\n\n\n{ ===========================================================================\n  Read a new buffer from the current input stream, update the adler32\n  and total number of bytes read.  All deflate() input goes through\n  this function so some applications may wish to modify it to avoid\n  allocating a large strm^.next_in buffer and copying from it.\n  (See also flush_pending()). }\n\n{local}\nfunction read_buf(strm : z_streamp; buf : pBytef; size : unsigned) : int;\nvar\n  len : unsigned;\nbegin\n  len := strm^.avail_in;\n\n  if (len > size) then\n    len := size;\n  if (len = 0) then\n  begin\n    read_buf := 0;\n    exit;\n  end;\n\n  Dec(strm^.avail_in, len);\n\n  if deflate_state_ptr(strm^.state)^.noheader = 0 then\n  begin\n    strm^.adler := adler32(strm^.adler, strm^.next_in, len);\n  end;\n  zmemcpy(buf, strm^.next_in, len);\n  Inc(strm^.next_in, len);\n  Inc(strm^.total_in, len);\n\n  read_buf := int(len);\nend;\n\n{ ===========================================================================\n  Initialize the \"longest match\" routines for a new zlib stream }\n\n{local}\nprocedure lm_init (var s : deflate_state);\nbegin\n  s.window_size := ulg( uLong(2)*s.w_size);\n\n  {macro CLEAR_HASH(s);}\n  s.head^[s.hash_size-1] := ZNIL;\n  zmemzero(pBytef(s.head), unsigned(s.hash_size-1)*sizeof(s.head^[0]));\n\n  { Set the default configuration parameters: }\n\n  s.max_lazy_match   := configuration_table[s.level].max_lazy;\n  s.good_match       := configuration_table[s.level].good_length;\n  s.nice_match       := configuration_table[s.level].nice_length;\n  s.max_chain_length := configuration_table[s.level].max_chain;\n\n  s.strstart := 0;\n  s.block_start := long(0);\n  s.lookahead := 0;\n  s.prev_length := MIN_MATCH-1;\n  s.match_length := MIN_MATCH-1;\n  s.match_available := FALSE;\n  s.ins_h := 0;\n{$ifdef ASMV}\n  match_init; { initialize the asm code }\n{$endif}\nend;\n\n{ ===========================================================================\n  Set match_start to the longest match starting at the given string and\n  return its length. Matches shorter or equal to prev_length are discarded,\n  in which case the result is equal to prev_length and match_start is\n  garbage.\n  IN assertions: cur_match is the head of the hash chain for the current\n    string (strstart) and its distance is <= MAX_DIST, and prev_length >= 1\n  OUT assertion: the match length is not greater than s^.lookahead. }\n\n\n{$ifndef ASMV}\n{ For 80x86 and 680x0, an optimized version will be provided in match.asm or\n  match.S. The code will be functionally equivalent. }\n\n{$ifndef FASTEST}\n\n{local}\nfunction longest_match(var s : deflate_state;\n                       cur_match : IPos  { current match }\n                       ) : uInt;\nlabel\n  nextstep;\nvar\n  chain_length : unsigned;    { max hash chain length }\n  {register} scan : pBytef;   { current string }\n  {register} match : pBytef;  { matched string }\n  {register} len : int;       { length of current match }\n  best_len : int;             { best match length so far }\n  nice_match : int;           { stop if match long enough }\n  limit : IPos;\n\n  prev : pzPosfArray;\n  wmask : uInt;\n{$ifdef UNALIGNED_OK}\n  {register} strend : pBytef;\n  {register} scan_start : ush;\n  {register} scan_end : ush;\n{$else}\n  {register} strend : pBytef;\n  {register} scan_end1 : Byte;\n  {register} scan_end : Byte;\n{$endif}\nvar\n  MAX_DIST : uInt;\nbegin\n  chain_length := s.max_chain_length; { max hash chain length }\n  scan := @(s.window^[s.strstart]);\n  best_len := s.prev_length;              { best match length so far }\n  nice_match := s.nice_match;             { stop if match long enough }\n\n\n  MAX_DIST := s.w_size - MIN_LOOKAHEAD;\n{In order to simplify the code, particularly on 16 bit machines, match\ndistances are limited to MAX_DIST instead of WSIZE. }\n\n  if s.strstart > IPos(MAX_DIST) then\n    limit := s.strstart - IPos(MAX_DIST)\n  else\n    limit := ZNIL;\n  { Stop when cur_match becomes <= limit. To simplify the code,\n    we prevent matches with the string of window index 0. }\n\n  prev := s.prev;\n  wmask := s.w_mask;\n\n{$ifdef UNALIGNED_OK}\n  { Compare two bytes at a time. Note: this is not always beneficial.\n    Try with and without -DUNALIGNED_OK to check. }\n\n  strend := pBytef(@(s.window^[s.strstart + MAX_MATCH - 1]));\n  scan_start := pushf(scan)^;\n  scan_end   := pushfArray(scan)^[best_len-1];   { fix }\n{$else}\n  strend := pBytef(@(s.window^[s.strstart + MAX_MATCH]));\n  {$IFOPT R+} {$R-} {$DEFINE NoRangeCheck} {$ENDIF}\n  scan_end1  := pzByteArray(scan)^[best_len-1];\n  {$IFDEF NoRangeCheck} {$R+} {$UNDEF NoRangeCheck} {$ENDIF}\n  scan_end   := pzByteArray(scan)^[best_len];\n{$endif}\n\n    { The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16.\n      It is easy to get rid of this optimization if necessary. }\n    {$IFDEF DEBUG}\n    Assert((s.hash_bits >= 8) and (MAX_MATCH = 258), 'Code too clever');\n    {$ENDIF}\n    { Do not waste too much time if we already have a good match: }\n    if (s.prev_length >= s.good_match) then\n    begin\n      chain_length := chain_length shr 2;\n    end;\n\n    { Do not look for matches beyond the end of the input. This is necessary\n      to make deflate deterministic. }\n\n    if (uInt(nice_match) > s.lookahead) then\n      nice_match := s.lookahead;\n    {$IFDEF DEBUG}\n    Assert(ulg(s.strstart) <= s.window_size-MIN_LOOKAHEAD, 'need lookahead');\n    {$ENDIF}\n    repeat\n        {$IFDEF DEBUG}\n        Assert(cur_match < s.strstart, 'no future');\n        {$ENDIF}\n        match := @(s.window^[cur_match]);\n\n        { Skip to next match if the match length cannot increase\n          or if the match length is less than 2: }\n\n{$undef DO_UNALIGNED_OK}\n{$ifdef UNALIGNED_OK}\n  {$ifdef MAX_MATCH_IS_258}\n    {$define DO_UNALIGNED_OK}\n  {$endif}\n{$endif}\n\n{$ifdef DO_UNALIGNED_OK}\n        { This code assumes sizeof(unsigned short) = 2. Do not use\n          UNALIGNED_OK if your compiler uses a different size. }\n  {$IFOPT R+} {$R-} {$DEFINE NoRangeCheck} {$ENDIF}\n        if (pushfArray(match)^[best_len-1] <> scan_end) or\n           (pushf(match)^ <> scan_start) then\n          goto nextstep; {continue;}\n  {$IFDEF NoRangeCheck} {$R+} {$UNDEF NoRangeCheck} {$ENDIF}\n\n        { It is not necessary to compare scan[2] and match[2] since they are\n          always equal when the other bytes match, given that the hash keys\n          are equal and that HASH_BITS >= 8. Compare 2 bytes at a time at\n          strstart+3, +5, ... up to strstart+257. We check for insufficient\n          lookahead only every 4th comparison; the 128th check will be made\n          at strstart+257. If MAX_MATCH-2 is not a multiple of 8, it is\n          necessary to put more guard bytes at the end of the window, or\n          to check more often for insufficient lookahead. }\n        {$IFDEF DEBUG}\n        Assert(pzByteArray(scan)^[2] = pzByteArray(match)^[2], 'scan[2]?');\n        {$ENDIF}\n        Inc(scan);\n        Inc(match);\n\n        repeat\n          Inc(scan,2); Inc(match,2); if (pushf(scan)^<>pushf(match)^) then break;\n          Inc(scan,2); Inc(match,2); if (pushf(scan)^<>pushf(match)^) then break;\n          Inc(scan,2); Inc(match,2); if (pushf(scan)^<>pushf(match)^) then break;\n          Inc(scan,2); Inc(match,2); if (pushf(scan)^<>pushf(match)^) then break;\n        until (ptr2int(scan) >= ptr2int(strend));\n        { The funny \"do while\" generates better code on most compilers }\n\n        { Here, scan <= window+strstart+257 }\n        {$IFDEF DEBUG}\n        {$ifopt R+} {$define RangeCheck} {$endif} {$R-}\n        Assert(ptr2int(scan) <=\n               ptr2int(@(s.window^[unsigned(s.window_size-1)])),\n               'wild scan');\n        {$ifdef RangeCheck} {$R+} {$undef RangeCheck} {$endif}\n        {$ENDIF}\n        if (scan^ = match^) then\n          Inc(scan);\n\n        len := (MAX_MATCH - 1) - int(ptr2int(strend)) + int(ptr2int(scan));\n        scan := strend;\n        Dec(scan, (MAX_MATCH-1));\n\n{$else} { UNALIGNED_OK }\n\n  {$IFOPT R+} {$R-} {$DEFINE NoRangeCheck} {$ENDIF}\n        if (pzByteArray(match)^[best_len]   <> scan_end) or\n           (pzByteArray(match)^[best_len-1] <> scan_end1) or\n           (match^ <> scan^) then\n          goto nextstep; {continue;}\n  {$IFDEF NoRangeCheck} {$R+} {$UNDEF NoRangeCheck} {$ENDIF}\n        Inc(match);\n        if (match^ <> pzByteArray(scan)^[1]) then\n          goto nextstep; {continue;}\n\n        { The check at best_len-1 can be removed because it will be made\n          again later. (This heuristic is not always a win.)\n          It is not necessary to compare scan[2] and match[2] since they\n          are always equal when the other bytes match, given that\n          the hash keys are equal and that HASH_BITS >= 8. }\n\n        Inc(scan, 2);\n        Inc(match);\n        {$IFDEF DEBUG}\n        Assert( scan^ = match^, 'match[2]?');\n        {$ENDIF}\n        { We check for insufficient lookahead only every 8th comparison;\n          the 256th check will be made at strstart+258. }\n\n        repeat\n          Inc(scan); Inc(match); if (scan^ <> match^) then break;\n          Inc(scan); Inc(match); if (scan^ <> match^) then break;\n          Inc(scan); Inc(match); if (scan^ <> match^) then break;\n          Inc(scan); Inc(match); if (scan^ <> match^) then break;\n          Inc(scan); Inc(match); if (scan^ <> match^) then break;\n          Inc(scan); Inc(match); if (scan^ <> match^) then break;\n          Inc(scan); Inc(match); if (scan^ <> match^) then break;\n          Inc(scan); Inc(match); if (scan^ <> match^) then break;\n        until (ptr2int(scan) >= ptr2int(strend));\n\n        {$IFDEF DEBUG}\n        Assert(ptr2int(scan) <=\n               ptr2int(@(s.window^[unsigned(s.window_size-1)])),\n               'wild scan');\n        {$ENDIF}\n\n        len := MAX_MATCH - int(ptr2int(strend) - ptr2int(scan));\n        scan := strend;\n        Dec(scan, MAX_MATCH);\n\n{$endif} { UNALIGNED_OK }\n\n        if (len > best_len) then\n        begin\n            s.match_start := cur_match;\n            best_len := len;\n            if (len >= nice_match) then\n              break;\n  {$IFOPT R+} {$R-} {$DEFINE NoRangeCheck} {$ENDIF}\n{$ifdef UNALIGNED_OK}\n            scan_end   := pzByteArray(scan)^[best_len-1];\n{$else}\n            scan_end1  := pzByteArray(scan)^[best_len-1];\n            scan_end   := pzByteArray(scan)^[best_len];\n{$endif}\n  {$IFDEF NoRangeCheck} {$R+} {$UNDEF NoRangeCheck} {$ENDIF}\n        end;\n    nextstep:\n      cur_match := prev^[cur_match and wmask];\n      Dec(chain_length);\n    until (cur_match <= limit) or (chain_length = 0);\n\n    if (uInt(best_len) <= s.lookahead) then\n      longest_match := uInt(best_len)\n    else\n      longest_match := s.lookahead;\nend;\n{$endif} { ASMV }\n\n{$else} { FASTEST }\n{ ---------------------------------------------------------------------------\n  Optimized version for level = 1 only }\n\n{local}\nfunction longest_match(var s : deflate_state;\n                       cur_match : IPos  { current match }\n                       ) : uInt;\nvar\n  {register} scan : pBytef;   { current string }\n  {register} match : pBytef;  { matched string }\n  {register} len : int;       { length of current match }\n  {register} strend : pBytef;\nbegin\n  scan := @s.window^[s.strstart];\n  strend := @s.window^[s.strstart + MAX_MATCH];\n\n\n    { The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16.\n      It is easy to get rid of this optimization if necessary. }\n    {$IFDEF DEBUG}\n    Assert((s.hash_bits >= 8) and (MAX_MATCH = 258), 'Code too clever');\n\n    Assert(ulg(s.strstart) <= s.window_size-MIN_LOOKAHEAD, 'need lookahead');\n\n    Assert(cur_match < s.strstart, 'no future');\n    {$ENDIF}\n    match := s.window + cur_match;\n\n    { Return failure if the match length is less than 2: }\n\n    if (match[0] <> scan[0]) or (match[1] <> scan[1]) then\n    begin\n      longest_match := MIN_MATCH-1;\n      exit;\n    end;\n\n    { The check at best_len-1 can be removed because it will be made\n      again later. (This heuristic is not always a win.)\n      It is not necessary to compare scan[2] and match[2] since they\n      are always equal when the other bytes match, given that\n      the hash keys are equal and that HASH_BITS >= 8. }\n\n    scan += 2, match += 2;\n    Assert(scan^ = match^, 'match[2]?');\n\n    { We check for insufficient lookahead only every 8th comparison;\n      the 256th check will be made at strstart+258. }\n\n    repeat\n      Inc(scan); Inc(match); if scan^<>match^ then break;\n      Inc(scan); Inc(match); if scan^<>match^ then break;\n      Inc(scan); Inc(match); if scan^<>match^ then break;\n      Inc(scan); Inc(match); if scan^<>match^ then break;\n      Inc(scan); Inc(match); if scan^<>match^ then break;\n      Inc(scan); Inc(match); if scan^<>match^ then break;\n      Inc(scan); Inc(match); if scan^<>match^ then break;\n      Inc(scan); Inc(match); if scan^<>match^ then break;\n    until (ptr2int(scan) >= ptr2int(strend));\n\n    Assert(scan <= s.window+unsigned(s.window_size-1), 'wild scan');\n\n    len := MAX_MATCH - int(strend - scan);\n\n    if (len < MIN_MATCH) then\n    begin\n      return := MIN_MATCH - 1;\n      exit;\n    end;\n\n    s.match_start := cur_match;\n    if len <= s.lookahead then\n      longest_match := len\n    else\n      longest_match := s.lookahead;\nend;\n{$endif} { FASTEST }\n\n{$ifdef DEBUG}\n{ ===========================================================================\n  Check that the match at match_start is indeed a match. }\n\n{local}\nprocedure check_match(var s : deflate_state;\n                      start, match : IPos;\n                      length : int);\nbegin\n  exit;\n  { check that the match is indeed a match }\n  if (zmemcmp(pBytef(@s.window^[match]),\n              pBytef(@s.window^[start]), length) <> EQUAL) then\n  begin\n    WriteLn(' start ',start,', match ',match ,' length ', length);\n    repeat\n      Write(AnsiChar(s.window^[match]), AnsiChar(s.window^[start]));\n      Inc(match);\n      Inc(start);\n      Dec(length);\n    Until (length = 0);\n    z_error('invalid match');\n  end;\n  if (z_verbose > 1) then\n  begin\n    Write('\\\\[',start-match,',',length,']');\n    repeat\n       Write(AnsiChar(s.window^[start]));\n       Inc(start);\n       Dec(length);\n    Until (length = 0);\n  end;\nend;\n{$endif}\n\n{ ===========================================================================\n  Fill the window when the lookahead becomes insufficient.\n  Updates strstart and lookahead.\n\n  IN assertion: lookahead < MIN_LOOKAHEAD\n  OUT assertions: strstart <= window_size-MIN_LOOKAHEAD\n     At least one byte has been read, or avail_in = 0; reads are\n     performed for at least two bytes (required for the zip translate_eol\n     option -- not supported here). }\n\n{local}\nprocedure fill_window(var s : deflate_state);\nvar\n  {register} n, m : unsigned;\n  {register} p : pPosf;\n  more : unsigned;    { Amount of free space at the end of the window. }\n  wsize : uInt;\nbegin\n   wsize := s.w_size;\n   repeat\n     more := unsigned(s.window_size -ulg(s.lookahead) -ulg(s.strstart));\n\n     { Deal with !@#$% 64K limit: }\n     if (more = 0) and (s.strstart = 0) and (s.lookahead = 0) then\n       more := wsize\n     else\n     if (more = unsigned(-1)) then\n     begin\n       { Very unlikely, but possible on 16 bit machine if strstart = 0\n         and lookahead = 1 (input done one byte at time) }\n       Dec(more);\n\n       { If the window is almost full and there is insufficient lookahead,\n         move the upper half to the lower one to make room in the upper half.}\n     end\n     else\n       if (s.strstart >= wsize+ {MAX_DIST}(wsize-MIN_LOOKAHEAD)) then\n       begin\n         zmemcpy( pBytef(s.window), pBytef(@(s.window^[wsize])),\n                 unsigned(wsize));\n         Dec(s.match_start, wsize);\n         Dec(s.strstart, wsize); { we now have strstart >= MAX_DIST }\n         Dec(s.block_start, long(wsize));\n\n         { Slide the hash table (could be avoided with 32 bit values\n           at the expense of memory usage). We slide even when level = 0\n           to keep the hash table consistent if we switch back to level > 0\n           later. (Using level 0 permanently is not an optimal usage of\n           zlib, so we don't care about this pathological case.) }\n\n         n := s.hash_size;\n         p := @s.head^[n];\n         repeat\n           Dec(p);\n           m := p^;\n           if (m >= wsize) then\n             p^ := Pos(m-wsize)\n           else\n             p^ := Pos(ZNIL);\n           Dec(n);\n         Until (n=0);\n\n         n := wsize;\n{$ifndef FASTEST}\n         p := @s.prev^[n];\n         repeat\n           Dec(p);\n           m := p^;\n           if (m >= wsize) then\n             p^ := Pos(m-wsize)\n           else\n             p^:= Pos(ZNIL);\n             { If n is not on any hash chain, prev^[n] is garbage but\n               its value will never be used. }\n           Dec(n);\n         Until (n=0);\n{$endif}\n         Inc(more, wsize);\n     end;\n     if (s.strm^.avail_in = 0) then\n       exit;\n\n     {* If there was no sliding:\n      *    strstart <= WSIZE+MAX_DIST-1 && lookahead <= MIN_LOOKAHEAD - 1 &&\n      *    more == window_size - lookahead - strstart\n      * => more >= window_size - (MIN_LOOKAHEAD-1 + WSIZE + MAX_DIST-1)\n      * => more >= window_size - 2*WSIZE + 2\n      * In the BIG_MEM or MMAP case (not yet supported),\n      *   window_size == input_size + MIN_LOOKAHEAD  &&\n      *   strstart + s->lookahead <= input_size => more >= MIN_LOOKAHEAD.\n      * Otherwise, window_size == 2*WSIZE so more >= 2.\n      * If there was sliding, more >= WSIZE. So in all cases, more >= 2. }\n\n     {$IFDEF DEBUG}\n     Assert(more >= 2, 'more < 2');\n     {$ENDIF}\n\n     n := read_buf(s.strm, pBytef(@(s.window^[s.strstart + s.lookahead])),\n                  more);\n     Inc(s.lookahead, n);\n\n     { Initialize the hash value now that we have some input: }\n     if (s.lookahead >= MIN_MATCH) then\n     begin\n       s.ins_h := s.window^[s.strstart];\n       {UPDATE_HASH(s, s.ins_h, s.window[s.strstart+1]);}\n       s.ins_h := ((s.ins_h shl s.hash_shift) xor s.window^[s.strstart+1])\n                     and s.hash_mask;\n{$ifdef MIN_MATCH <> 3}\n       Call UPDATE_HASH() MIN_MATCH-3 more times\n{$endif}\n     end;\n     { If the whole input has less than MIN_MATCH bytes, ins_h is garbage,\n       but this is not important since only literal bytes will be emitted. }\n\n   until (s.lookahead >= MIN_LOOKAHEAD) or (s.strm^.avail_in = 0);\nend;\n\n{ ===========================================================================\n  Flush the current block, with given end-of-file flag.\n  IN assertion: strstart is set to the end of the current match. }\n\nprocedure FLUSH_BLOCK_ONLY(var s : deflate_state; eof : boolean); {macro}\nbegin\n  if (s.block_start >= Long(0)) then\n    _tr_flush_block(s, pcharf(@s.window^[unsigned(s.block_start)]),\n                    ulg(long(s.strstart) - s.block_start), eof)\n  else\n    _tr_flush_block(s, pcharf(Z_NULL),\n                    ulg(long(s.strstart) - s.block_start), eof);\n\n  s.block_start := s.strstart;\n  flush_pending(s.strm^);\n  {$IFDEF DEBUG}\n  Tracev('[FLUSH]');\n  {$ENDIF}\nend;\n\n{ Same but force premature exit if necessary.\nmacro FLUSH_BLOCK(var s : deflate_state; eof : boolean) : boolean;\nvar\n  result : block_state;\nbegin\n FLUSH_BLOCK_ONLY(s, eof);\n if (s.strm^.avail_out = 0) then\n begin\n   if eof then\n     result := finish_started\n   else\n     result := need_more;\n   exit;\n end;\nend;\n}\n\n{ ===========================================================================\n  Copy without compression as much as possible from the input stream, return\n  the current block state.\n  This function does not insert new strings in the dictionary since\n  uncompressible data is probably not useful. This function is used\n  only for the level=0 compression option.\n  NOTE: this function should be optimized to avoid extra copying from\n  window to pending_buf. }\n\n\n{local}\nfunction deflate_stored(var s : deflate_state; flush : int) : block_state;\n{ Stored blocks are limited to 0xffff bytes, pending_buf is limited\n  to pending_buf_size, and each stored block has a 5 byte header: }\nvar\n  max_block_size : ulg;\n  max_start : ulg;\nbegin\n  max_block_size := $ffff;\n  if (max_block_size > s.pending_buf_size - 5) then\n    max_block_size := s.pending_buf_size - 5;\n\n  { Copy as much as possible from input to output: }\n  while TRUE do\n  begin\n    { Fill the window as much as possible: }\n    if (s.lookahead <= 1) then\n    begin\n      {$IFDEF DEBUG}\n      Assert( (s.strstart < s.w_size + {MAX_DIST}s.w_size-MIN_LOOKAHEAD) or\n              (s.block_start >= long(s.w_size)), 'slide too late');\n      {$ENDIF}\n      fill_window(s);\n      if (s.lookahead = 0) and (flush = Z_NO_FLUSH) then\n      begin\n        deflate_stored := need_more;\n        exit;\n      end;\n\n      if (s.lookahead = 0) then\n        break; { flush the current block }\n    end;\n    {$IFDEF DEBUG}\n    Assert(s.block_start >= long(0), 'block gone');\n    {$ENDIF}\n    Inc(s.strstart, s.lookahead);\n    s.lookahead := 0;\n\n    { Emit a stored block if pending_buf will be full: }\n    max_start := s.block_start + max_block_size;\n    if (s.strstart = 0) or (ulg(s.strstart) >= max_start) then\n    begin\n      { strstart = 0 is possible when wraparound on 16-bit machine }\n      s.lookahead := s.strstart - uInt(max_start);\n      s.strstart := uInt(max_start);\n      {FLUSH_BLOCK(s, FALSE);}\n      FLUSH_BLOCK_ONLY(s, FALSE);\n      if (s.strm^.avail_out = 0) then\n      begin\n        deflate_stored := need_more;\n        exit;\n      end;\n    end;\n\n    { Flush if we may have to slide, otherwise block_start may become\n      negative and the data will be gone: }\n\n    if (s.strstart - uInt(s.block_start) >= {MAX_DIST}\n        s.w_size-MIN_LOOKAHEAD) then\n    begin\n      {FLUSH_BLOCK(s, FALSE);}\n      FLUSH_BLOCK_ONLY(s, FALSE);\n      if (s.strm^.avail_out = 0) then\n      begin\n        deflate_stored := need_more;\n        exit;\n      end;\n    end;\n  end;\n\n  {FLUSH_BLOCK(s, flush = Z_FINISH);}\n  FLUSH_BLOCK_ONLY(s, flush = Z_FINISH);\n  if (s.strm^.avail_out = 0) then\n  begin\n    if flush = Z_FINISH then\n      deflate_stored := finish_started\n    else\n      deflate_stored := need_more;\n    exit;\n  end;\n\n  if flush = Z_FINISH then\n    deflate_stored := finish_done\n  else\n    deflate_stored := block_done;\nend;\n\n{ ===========================================================================\n  Compress as much as possible from the input stream, return the current\n  block state.\n  This function does not perform lazy evaluation of matches and inserts\n  new strings in the dictionary only for unmatched strings or for short\n  matches. It is used only for the fast compression options. }\n\n{local}\nfunction deflate_fast(var s : deflate_state; flush : int) : block_state;\nvar\n  hash_head : IPos;     { head of the hash chain }\n  bflush : boolean;     { set if current block must be flushed }\nbegin\n  hash_head := ZNIL;\n  while TRUE do\n  begin\n  { Make sure that we always have enough lookahead, except\n    at the end of the input file. We need MAX_MATCH bytes\n    for the next match, plus MIN_MATCH bytes to insert the\n    string following the next match. }\n\n    if (s.lookahead < MIN_LOOKAHEAD) then\n    begin\n      fill_window(s);\n      if (s.lookahead < MIN_LOOKAHEAD) and (flush = Z_NO_FLUSH) then\n      begin\n        deflate_fast := need_more;\n        exit;\n      end;\n\n      if (s.lookahead = 0) then\n        break; { flush the current block }\n    end;\n\n\n    { Insert the string window[strstart .. strstart+2] in the\n      dictionary, and set hash_head to the head of the hash chain: }\n\n    if (s.lookahead >= MIN_MATCH) then\n    begin\n      INSERT_STRING(s, s.strstart, hash_head);\n    end;\n\n    { Find the longest match, discarding those <= prev_length.\n      At this point we have always match_length < MIN_MATCH }\n    if (hash_head <> ZNIL) and\n       (s.strstart - hash_head <= (s.w_size-MIN_LOOKAHEAD){MAX_DIST}) then\n    begin\n      { To simplify the code, we prevent matches with the string\n        of window index 0 (in particular we have to avoid a match\n        of the string with itself at the start of the input file). }\n      if (s.strategy <> Z_HUFFMAN_ONLY) then\n      begin\n        s.match_length := longest_match (s, hash_head);\n      end;\n      { longest_match() sets match_start }\n    end;\n    if (s.match_length >= MIN_MATCH) then\n    begin\n      {$IFDEF DEBUG}\n      check_match(s, s.strstart, s.match_start, s.match_length);\n      {$ENDIF}\n\n      {_tr_tally_dist(s, s.strstart - s.match_start,\n                        s.match_length - MIN_MATCH, bflush);}\n      bflush := _tr_tally(s, s.strstart - s.match_start,\n                        s.match_length - MIN_MATCH);\n\n      Dec(s.lookahead, s.match_length);\n\n      { Insert new strings in the hash table only if the match length\n        is not too large. This saves time but degrades compression. }\n\n{$ifndef FASTEST}\n      if (s.match_length <= s.max_insert_length)\n       and (s.lookahead >= MIN_MATCH) then\n      begin\n        Dec(s.match_length); { string at strstart already in hash table }\n        repeat\n          Inc(s.strstart);\n          INSERT_STRING(s, s.strstart, hash_head);\n          { strstart never exceeds WSIZE-MAX_MATCH, so there are\n            always MIN_MATCH bytes ahead. }\n          Dec(s.match_length);\n        until (s.match_length = 0);\n        Inc(s.strstart);\n      end\n      else\n{$endif}\n\n      begin\n        Inc(s.strstart, s.match_length);\n        s.match_length := 0;\n        s.ins_h := s.window^[s.strstart];\n        {UPDATE_HASH(s, s.ins_h, s.window[s.strstart+1]);}\n        s.ins_h := (( s.ins_h shl s.hash_shift) xor\n                     s.window^[s.strstart+1]) and s.hash_mask;\nif MIN_MATCH <> 3 then   { the linker removes this }\nbegin\n          {Call UPDATE_HASH() MIN_MATCH-3 more times}\nend;\n\n        { If lookahead < MIN_MATCH, ins_h is garbage, but it does not\n          matter since it will be recomputed at next deflate call. }\n\n      end;\n    end\n    else\n    begin\n      { No match, output a literal byte }\n      {$IFDEF DEBUG}\n      Tracevv(AnsiChar(s.window^[s.strstart]));\n      {$ENDIF}\n      {_tr_tally_lit (s, 0, s.window^[s.strstart], bflush);}\n      bflush := _tr_tally (s, 0, s.window^[s.strstart]);\n\n      Dec(s.lookahead);\n      Inc(s.strstart);\n    end;\n    if bflush then\n    begin  {FLUSH_BLOCK(s, FALSE);}\n      FLUSH_BLOCK_ONLY(s, FALSE);\n      if (s.strm^.avail_out = 0) then\n      begin\n        deflate_fast := need_more;\n        exit;\n      end;\n    end;\n  end;\n  {FLUSH_BLOCK(s, flush = Z_FINISH);}\n  FLUSH_BLOCK_ONLY(s, flush = Z_FINISH);\n  if (s.strm^.avail_out = 0) then\n  begin\n    if flush = Z_FINISH then\n      deflate_fast := finish_started\n    else\n      deflate_fast := need_more;\n    exit;\n  end;\n\n  if flush = Z_FINISH then\n    deflate_fast := finish_done\n  else\n    deflate_fast := block_done;\nend;\n\n{ ===========================================================================\n  Same as above, but achieves better compression. We use a lazy\n  evaluation for matches: a match is finally adopted only if there is\n  no better match at the next window position. }\n\n{local}\nfunction deflate_slow(var s : deflate_state; flush : int) : block_state;\nvar\n  hash_head : IPos;       { head of hash chain }\n  bflush : boolean;       { set if current block must be flushed }\nvar\n  max_insert : uInt;\nbegin\n  hash_head := ZNIL;\n\n  { Process the input block. }\n  while TRUE do\n  begin\n    { Make sure that we always have enough lookahead, except\n      at the end of the input file. We need MAX_MATCH bytes\n      for the next match, plus MIN_MATCH bytes to insert the\n      string following the next match. }\n\n    if (s.lookahead < MIN_LOOKAHEAD) then\n    begin\n      fill_window(s);\n      if (s.lookahead < MIN_LOOKAHEAD) and (flush = Z_NO_FLUSH) then\n      begin\n        deflate_slow := need_more;\n        exit;\n      end;\n\n      if (s.lookahead = 0) then\n        break; { flush the current block }\n    end;\n\n    { Insert the string window[strstart .. strstart+2] in the\n      dictionary, and set hash_head to the head of the hash chain: }\n\n    if (s.lookahead >= MIN_MATCH) then\n    begin\n      INSERT_STRING(s, s.strstart, hash_head);\n    end;\n\n    { Find the longest match, discarding those <= prev_length. }\n\n    s.prev_length := s.match_length;\n    s.prev_match := s.match_start;\n    s.match_length := MIN_MATCH-1;\n\n    if (hash_head <> ZNIL) and (s.prev_length < s.max_lazy_match) and\n       (s.strstart - hash_head <= {MAX_DIST}(s.w_size-MIN_LOOKAHEAD)) then\n    begin\n        { To simplify the code, we prevent matches with the string\n          of window index 0 (in particular we have to avoid a match\n          of the string with itself at the start of the input file). }\n\n        if (s.strategy <> Z_HUFFMAN_ONLY) then\n        begin\n          s.match_length := longest_match (s, hash_head);\n        end;\n        { longest_match() sets match_start }\n\n        if (s.match_length <= 5) and ((s.strategy = Z_FILTERED) or\n             ((s.match_length = MIN_MATCH) and\n              (s.strstart - s.match_start > TOO_FAR))) then\n        begin\n            { If prev_match is also MIN_MATCH, match_start is garbage\n              but we will ignore the current match anyway. }\n\n            s.match_length := MIN_MATCH-1;\n        end;\n    end;\n    { If there was a match at the previous step and the current\n      match is not better, output the previous match: }\n\n    if (s.prev_length >= MIN_MATCH)\n      and (s.match_length <= s.prev_length) then\n    begin\n      max_insert := s.strstart + s.lookahead - MIN_MATCH;\n      { Do not insert strings in hash table beyond this. }\n      {$ifdef DEBUG}\n      check_match(s, s.strstart-1, s.prev_match, s.prev_length);\n      {$endif}\n\n      {_tr_tally_dist(s, s->strstart -1 - s->prev_match,\n\t                s->prev_length - MIN_MATCH, bflush);}\n      bflush := _tr_tally(s, s.strstart -1 - s.prev_match,\n                           s.prev_length - MIN_MATCH);\n\n      { Insert in hash table all strings up to the end of the match.\n        strstart-1 and strstart are already inserted. If there is not\n        enough lookahead, the last two strings are not inserted in\n        the hash table. }\n\n      Dec(s.lookahead, s.prev_length-1);\n      Dec(s.prev_length, 2);\n      repeat\n        Inc(s.strstart);\n        if (s.strstart <= max_insert) then\n        begin\n          INSERT_STRING(s, s.strstart, hash_head);\n        end;\n        Dec(s.prev_length);\n      until (s.prev_length = 0);\n      s.match_available := FALSE;\n      s.match_length := MIN_MATCH-1;\n      Inc(s.strstart);\n\n      if (bflush) then  {FLUSH_BLOCK(s, FALSE);}\n      begin\n        FLUSH_BLOCK_ONLY(s, FALSE);\n        if (s.strm^.avail_out = 0) then\n        begin\n          deflate_slow := need_more;\n          exit;\n        end;\n      end;\n    end\n    else\n      if (s.match_available) then\n      begin\n        { If there was no match at the previous position, output a\n          single literal. If there was a match but the current match\n          is longer, truncate the previous match to a single literal. }\n        {$IFDEF DEBUG}\n        Tracevv(AnsiChar(s.window^[s.strstart-1]));\n        {$ENDIF}\n        bflush := _tr_tally (s, 0, s.window^[s.strstart-1]);\n\n        if bflush then\n        begin\n          FLUSH_BLOCK_ONLY(s, FALSE);\n        end;\n        Inc(s.strstart);\n        Dec(s.lookahead);\n        if (s.strm^.avail_out = 0) then\n        begin\n          deflate_slow := need_more;\n          exit;\n        end;\n      end\n      else\n      begin\n        { There is no previous match to compare with, wait for\n          the next step to decide. }\n\n        s.match_available := TRUE;\n        Inc(s.strstart);\n        Dec(s.lookahead);\n      end;\n  end;\n\n  {$IFDEF DEBUG}\n  Assert (flush <> Z_NO_FLUSH, 'no flush?');\n  {$ENDIF}\n  if (s.match_available) then\n  begin\n    {$IFDEF DEBUG}\n    Tracevv(AnsiChar(s.window^[s.strstart-1]));\n    bflush :=\n    {$ENDIF}\n      _tr_tally (s, 0, s.window^[s.strstart-1]);\n    s.match_available := FALSE;\n  end;\n  {FLUSH_BLOCK(s, flush = Z_FINISH);}\n  FLUSH_BLOCK_ONLY(s, flush = Z_FINISH);\n  if (s.strm^.avail_out = 0) then\n  begin\n    if flush = Z_FINISH then\n      deflate_slow := finish_started\n    else\n      deflate_slow := need_more;\n    exit;\n  end;\n  if flush = Z_FINISH then\n    deflate_slow := finish_done\n  else\n    deflate_slow := block_done;\nend;\n\nend.\n"
  },
  {
    "path": "lib/Imaging/ZLib/imzinflate.pas",
    "content": "Unit  imzinflate;\n\n{  inflate.c -- zlib interface to inflate modules\n   Copyright (C) 1995-1998 Mark Adler\n\n  Pascal tranlastion\n  Copyright (C) 1998 by Jacques Nomssi Nzali\n  For conditions of distribution and use, see copyright notice in readme.txt\n}\n\ninterface\n\n{$I imzconf.inc}\n\nuses\n  imzutil, impaszlib, iminfblock, iminfutil;\n\nfunction inflateInit(var z : z_stream) : int;\n\n{    Initializes the internal stream state for decompression. The fields\n   zalloc, zfree and opaque must be initialized before by the caller.  If\n   zalloc and zfree are set to Z_NULL, inflateInit updates them to use default\n   allocation functions.\n\n     inflateInit returns Z_OK if success, Z_MEM_ERROR if there was not\n   enough memory, Z_VERSION_ERROR if the zlib library version is incompatible\n   with the version assumed by the caller.  msg is set to null if there is no\n   error message. inflateInit does not perform any decompression: this will be\n   done by inflate(). }\n\n\n\nfunction inflateInit_(z : z_streamp;\n                      const version : AnsiString;\n                      stream_size : int) : int; \n\n\nfunction inflateInit2_(var z: z_stream;\n                       w : int;\n                       const version : AnsiString;\n                       stream_size : int) : int;\n\nfunction inflateInit2(var z: z_stream;\n                       windowBits : int) : int;\n\n{\n     This is another version of inflateInit with an extra parameter. The\n   fields next_in, avail_in, zalloc, zfree and opaque must be initialized\n   before by the caller.\n\n     The windowBits parameter is the base two logarithm of the maximum window\n   size (the size of the history buffer).  It should be in the range 8..15 for\n   this version of the library. The default value is 15 if inflateInit is used\n   instead. If a compressed stream with a larger window size is given as\n   input, inflate() will return with the error code Z_DATA_ERROR instead of\n   trying to allocate a larger window.\n\n      inflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough\n   memory, Z_STREAM_ERROR if a parameter is invalid (such as a negative\n   memLevel). msg is set to null if there is no error message.  inflateInit2\n   does not perform any decompression apart from reading the zlib header if\n   present: this will be done by inflate(). (So next_in and avail_in may be\n   modified, but next_out and avail_out are unchanged.)\n}\n\n\n\nfunction inflateEnd(var z : z_stream) : int;\n\n{\n   All dynamically allocated data structures for this stream are freed.\n   This function discards any unprocessed input and does not flush any\n   pending output.\n\n     inflateEnd returns Z_OK if success, Z_STREAM_ERROR if the stream state\n   was inconsistent. In the error case, msg may be set but then points to a\n   static string (which must not be deallocated).\n}\n\nfunction inflateReset(var z : z_stream) : int;\n\n{\n   This function is equivalent to inflateEnd followed by inflateInit,\n   but does not free and reallocate all the internal decompression state.\n   The stream will keep attributes that may have been set by inflateInit2.\n\n      inflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source\n   stream state was inconsistent (such as zalloc or state being NULL).\n}\n\n\nfunction inflate(var z : z_stream;\n                 f : int) : int;\n{\n  inflate decompresses as much data as possible, and stops when the input\n  buffer becomes empty or the output buffer becomes full. It may introduce\n  some output latency (reading input without producing any output)\n  except when forced to flush.\n\n  The detailed semantics are as follows. inflate performs one or both of the\n  following actions:\n\n  - Decompress more input starting at next_in and update next_in and avail_in\n    accordingly. If not all input can be processed (because there is not\n    enough room in the output buffer), next_in is updated and processing\n    will resume at this point for the next call of inflate().\n\n  - Provide more output starting at next_out and update next_out and avail_out\n    accordingly.  inflate() provides as much output as possible, until there\n    is no more input data or no more space in the output buffer (see below\n    about the flush parameter).\n\n  Before the call of inflate(), the application should ensure that at least\n  one of the actions is possible, by providing more input and/or consuming\n  more output, and updating the next_* and avail_* values accordingly.\n  The application can consume the uncompressed output when it wants, for\n  example when the output buffer is full (avail_out == 0), or after each\n  call of inflate(). If inflate returns Z_OK and with zero avail_out, it\n  must be called again after making room in the output buffer because there\n  might be more output pending.\n\n    If the parameter flush is set to Z_SYNC_FLUSH, inflate flushes as much\n  output as possible to the output buffer. The flushing behavior of inflate is\n  not specified for values of the flush parameter other than Z_SYNC_FLUSH\n  and Z_FINISH, but the current implementation actually flushes as much output\n  as possible anyway.\n\n    inflate() should normally be called until it returns Z_STREAM_END or an\n  error. However if all decompression is to be performed in a single step\n  (a single call of inflate), the parameter flush should be set to\n  Z_FINISH. In this case all pending input is processed and all pending\n  output is flushed; avail_out must be large enough to hold all the\n  uncompressed data. (The size of the uncompressed data may have been saved\n  by the compressor for this purpose.) The next operation on this stream must\n  be inflateEnd to deallocate the decompression state. The use of Z_FINISH\n  is never required, but can be used to inform inflate that a faster routine\n  may be used for the single inflate() call.\n\n     If a preset dictionary is needed at this point (see inflateSetDictionary\n  below), inflate sets strm-adler to the adler32 checksum of the\n  dictionary chosen by the compressor and returns Z_NEED_DICT; otherwise \n  it sets strm->adler to the adler32 checksum of all output produced\n  so far (that is, total_out bytes) and returns Z_OK, Z_STREAM_END or\n  an error code as described below. At the end of the stream, inflate()\n  checks that its computed adler32 checksum is equal to that saved by the\n  compressor and returns Z_STREAM_END only if the checksum is correct.\n\n    inflate() returns Z_OK if some progress has been made (more input processed\n  or more output produced), Z_STREAM_END if the end of the compressed data has\n  been reached and all uncompressed output has been produced, Z_NEED_DICT if a\n  preset dictionary is needed at this point, Z_DATA_ERROR if the input data was\n  corrupted (input stream not conforming to the zlib format or incorrect\n  adler32 checksum), Z_STREAM_ERROR if the stream structure was inconsistent\n  (for example if next_in or next_out was NULL), Z_MEM_ERROR if there was not\n  enough memory, Z_BUF_ERROR if no progress is possible or if there was not\n  enough room in the output buffer when Z_FINISH is used. In the Z_DATA_ERROR\n  case, the application may then call inflateSync to look for a good\n  compression block.\n}\n\n\nfunction inflateSetDictionary(var z : z_stream;\n                              dictionary : pBytef; {const array of byte}\n                              dictLength : uInt) : int;\n\n{\n     Initializes the decompression dictionary from the given uncompressed byte\n   sequence. This function must be called immediately after a call of inflate\n   if this call returned Z_NEED_DICT. The dictionary chosen by the compressor\n   can be determined from the Adler32 value returned by this call of\n   inflate. The compressor and decompressor must use exactly the same\n   dictionary (see deflateSetDictionary).\n\n     inflateSetDictionary returns Z_OK if success, Z_STREAM_ERROR if a\n   parameter is invalid (such as NULL dictionary) or the stream state is\n   inconsistent, Z_DATA_ERROR if the given dictionary doesn't match the\n   expected one (incorrect Adler32 value). inflateSetDictionary does not\n   perform any decompression: this will be done by subsequent calls of\n   inflate().\n}\n\nfunction inflateSync(var z : z_stream) : int;\n\n{\n  Skips invalid compressed data until a full flush point (see above the\n  description of deflate with Z_FULL_FLUSH) can be found, or until all\n  available input is skipped. No output is provided.\n\n    inflateSync returns Z_OK if a full flush point has been found, Z_BUF_ERROR\n  if no more input was provided, Z_DATA_ERROR if no flush point has been found,\n  or Z_STREAM_ERROR if the stream structure was inconsistent. In the success\n  case, the application may save the current current value of total_in which\n  indicates where valid compressed data was found. In the error case, the\n  application may repeatedly call inflateSync, providing more input each time,\n  until success or end of the input data.\n}\n\n\nfunction inflateSyncPoint(var z : z_stream) : int;\n\n\nimplementation\n\nuses\n  imadler;\n\nfunction inflateReset(var z : z_stream) : int;\nbegin\n  if (z.state = Z_NULL) then\n  begin\n    inflateReset :=  Z_STREAM_ERROR;\n    exit;\n  end;\n  z.total_out := 0;\n  z.total_in := 0;\n  z.msg := '';\n  if z.state^.nowrap then\n    z.state^.mode := BLOCKS\n  else\n    z.state^.mode := METHOD;\n  inflate_blocks_reset(z.state^.blocks^, z, Z_NULL);\n  {$IFDEF DEBUG}\n  Tracev('inflate: reset');\n  {$ENDIF}\n  inflateReset :=  Z_OK;\nend;\n\n\nfunction inflateEnd(var z : z_stream) : int;\nbegin\n  if (z.state = Z_NULL) or not Assigned(z.zfree) then\n  begin\n    inflateEnd :=  Z_STREAM_ERROR;\n    exit;\n  end;\n  if (z.state^.blocks <> Z_NULL) then\n    inflate_blocks_free(z.state^.blocks, z);\n  ZFREE(z, z.state);\n  z.state := Z_NULL;\n  {$IFDEF DEBUG}\n  Tracev('inflate: end');\n  {$ENDIF}\n  inflateEnd :=  Z_OK;\nend;\n\n\nfunction inflateInit2_(var z: z_stream;\n                       w : int;\n                       const version : AnsiString;\n                       stream_size : int) : int;\nbegin\n  if (version = '') or (version[1] <> ZLIB_VERSION[1]) or\n      (stream_size <> sizeof(z_stream)) then\n  begin\n    inflateInit2_ := Z_VERSION_ERROR;\n    exit;\n  end;\n  { initialize state }\n  { SetLength(strm.msg, 255); }\n  z.msg := '';\n  if not Assigned(z.zalloc) then\n  begin\n    {$IFDEF FPC}  z.zalloc := @zcalloc;  {$ELSE}\n    z.zalloc := zcalloc;\n    {$endif}\n    z.opaque := voidpf(0);\n  end;\n  if not Assigned(z.zfree) then\n    {$IFDEF FPC}  z.zfree := @zcfree;  {$ELSE}\n    z.zfree := zcfree;\n    {$ENDIF}\n\n  z.state := pInternal_state( ZALLOC(z,1,sizeof(internal_state)) );\n  if (z.state = Z_NULL) then\n  begin\n    inflateInit2_ := Z_MEM_ERROR;\n    exit;\n  end;\n\n  z.state^.blocks := Z_NULL;\n\n  { handle undocumented nowrap option (no zlib header or check) }\n  z.state^.nowrap := FALSE;\n  if (w < 0) then\n  begin\n    w := - w;\n    z.state^.nowrap := TRUE;\n  end;\n\n  { set window size }\n  if (w < 8) or (w > 15) then\n  begin\n    inflateEnd(z);\n    inflateInit2_ := Z_STREAM_ERROR;\n    exit;\n  end;\n  z.state^.wbits := uInt(w);\n\n  { create inflate_blocks state }\n  if z.state^.nowrap then\n    z.state^.blocks := inflate_blocks_new(z, NIL, uInt(1) shl w)\n  else\n  {$IFDEF FPC}\n    z.state^.blocks := inflate_blocks_new(z, @adler32, uInt(1) shl w);\n  {$ELSE}\n    z.state^.blocks := inflate_blocks_new(z, adler32, uInt(1) shl w);\n  {$ENDIF}\n  if (z.state^.blocks = Z_NULL) then\n  begin\n    inflateEnd(z);\n    inflateInit2_ := Z_MEM_ERROR;\n    exit;\n  end;\n  {$IFDEF DEBUG}\n  Tracev('inflate: allocated');\n  {$ENDIF}\n  { reset state }\n  inflateReset(z);\n  inflateInit2_ :=  Z_OK;\nend;\n\nfunction inflateInit2(var z: z_stream; windowBits : int) : int;\nbegin\n  inflateInit2 := inflateInit2_(z, windowBits, ZLIB_VERSION, sizeof(z_stream));\nend;\n\n\nfunction inflateInit(var z : z_stream) : int;\n{ inflateInit is a macro to allow checking the zlib version\n  and the compiler's view of z_stream:  }\nbegin\n  inflateInit := inflateInit2_(z, DEF_WBITS, ZLIB_VERSION, sizeof(z_stream));\nend;\n\nfunction inflateInit_(z : z_streamp;\n                      const version : AnsiString;\n                      stream_size : int) : int;\nbegin\n  { initialize state }\n  if (z = Z_NULL) then\n    inflateInit_ := Z_STREAM_ERROR\n  else\n    inflateInit_ := inflateInit2_(z^, DEF_WBITS, version, stream_size);\nend;\n\nfunction inflate(var z : z_stream;\n                 f : int) : int;\nvar\n  r : int;\n  b : uInt;\nbegin\n  if (z.state = Z_NULL) or (z.next_in = Z_NULL) then\n  begin\n    inflate := Z_STREAM_ERROR;\n    exit;\n  end;\n  if f = Z_FINISH then\n    f := Z_BUF_ERROR\n  else\n    f := Z_OK;\n  r := Z_BUF_ERROR;\n  while True do\n  case (z.state^.mode) of\n    BLOCKS:\n      begin\n        r := inflate_blocks(z.state^.blocks^, z, r);\n        if (r = Z_DATA_ERROR) then\n        begin\n          z.state^.mode := BAD;\n          z.state^.sub.marker := 0;       { can try inflateSync }\n          continue;            { break C-switch }\n        end;\n        if (r = Z_OK) then\n          r := f;\n        if (r <> Z_STREAM_END) then\n        begin\n          inflate := r;\n          exit;\n        end;\n        r := f;\n        inflate_blocks_reset(z.state^.blocks^, z, @z.state^.sub.check.was);\n        if (z.state^.nowrap) then\n        begin\n          z.state^.mode := DONE;\n          continue;            { break C-switch }\n        end;\n        z.state^.mode := CHECK4;  { falltrough }\n      end;\n    CHECK4:\n      begin\n        {NEEDBYTE}\n        if (z.avail_in = 0) then\n        begin\n          inflate := r;\n          exit;\n        end;\n        r := f;\n\n        {z.state^.sub.check.need := uLong(NEXTBYTE(z)) shl 24;}\n        Dec(z.avail_in);\n        Inc(z.total_in);\n        z.state^.sub.check.need := uLong(z.next_in^) shl 24;\n        Inc(z.next_in);\n\n        z.state^.mode := CHECK3;   { falltrough }\n      end;\n    CHECK3:\n      begin\n        {NEEDBYTE}\n        if (z.avail_in = 0) then\n        begin\n          inflate := r;\n          exit;\n        end;\n        r := f;\n        {Inc( z.state^.sub.check.need, uLong(NEXTBYTE(z)) shl 16);}\n        Dec(z.avail_in);\n        Inc(z.total_in);\n        Inc(z.state^.sub.check.need, uLong(z.next_in^) shl 16);\n        Inc(z.next_in);\n\n        z.state^.mode := CHECK2;   { falltrough }\n      end;\n    CHECK2:\n      begin\n        {NEEDBYTE}\n        if (z.avail_in = 0) then\n        begin\n          inflate := r;\n          exit;\n        end;\n        r := f;\n\n        {Inc( z.state^.sub.check.need, uLong(NEXTBYTE(z)) shl 8);}\n        Dec(z.avail_in);\n        Inc(z.total_in);\n        Inc(z.state^.sub.check.need, uLong(z.next_in^) shl 8);\n        Inc(z.next_in);\n\n        z.state^.mode := CHECK1;   { falltrough }\n      end;\n    CHECK1:\n      begin\n        {NEEDBYTE}\n        if (z.avail_in = 0) then\n        begin\n          inflate := r;\n          exit;\n        end;\n        r := f;\n        {Inc( z.state^.sub.check.need, uLong(NEXTBYTE(z)) );}\n        Dec(z.avail_in);\n        Inc(z.total_in);\n        Inc(z.state^.sub.check.need, uLong(z.next_in^) );\n        Inc(z.next_in);\n\n\n        if (z.state^.sub.check.was <> z.state^.sub.check.need) then\n        begin\n          z.state^.mode := BAD;\n          z.msg := 'incorrect data check';\n          z.state^.sub.marker := 5;       { can't try inflateSync }\n          continue;           { break C-switch }\n        end;\n        {$IFDEF DEBUG}\n        Tracev('inflate: zlib check ok');\n        {$ENDIF}\n        z.state^.mode := DONE; { falltrough }\n      end;\n    DONE:\n      begin\n        inflate := Z_STREAM_END;\n        exit;\n      end;\n    METHOD:\n      begin\n        {NEEDBYTE}\n        if (z.avail_in = 0) then\n        begin\n          inflate := r;\n          exit;\n        end;\n        r := f; {}\n\n        {z.state^.sub.method := NEXTBYTE(z);}\n        Dec(z.avail_in);\n        Inc(z.total_in);\n        z.state^.sub.method := z.next_in^;\n        Inc(z.next_in);\n\n        if ((z.state^.sub.method and $0f) <> Z_DEFLATED) then\n        begin\n          z.state^.mode := BAD;\n          z.msg := 'unknown compression method';\n          z.state^.sub.marker := 5;       { can't try inflateSync }\n          continue;  { break C-switch }\n        end;\n        if ((z.state^.sub.method shr 4) + 8 > z.state^.wbits) then\n        begin\n          z.state^.mode := BAD;\n          z.msg := 'invalid window size';\n          z.state^.sub.marker := 5;       { can't try inflateSync }\n          continue; { break C-switch }\n        end;\n        z.state^.mode := FLAG;\n        { fall trough }\n      end;\n    FLAG:\n      begin\n        {NEEDBYTE}\n        if (z.avail_in = 0) then\n        begin\n          inflate := r;\n          exit;\n        end;\n        r := f; {}\n        {b := NEXTBYTE(z);}\n        Dec(z.avail_in);\n        Inc(z.total_in);\n        b := z.next_in^;\n        Inc(z.next_in);\n\n        if (((z.state^.sub.method shl 8) + b) mod 31) <> 0 then {% mod ?}\n        begin\n          z.state^.mode := BAD;\n          z.msg := 'incorrect header check';\n          z.state^.sub.marker := 5;       { can't try inflateSync }\n          continue;      { break C-switch }\n        end;\n        {$IFDEF DEBUG}\n        Tracev('inflate: zlib header ok');\n        {$ENDIF}\n        if ((b and PRESET_DICT) = 0) then\n        begin\n          z.state^.mode := BLOCKS;\n\t  continue;      { break C-switch }\n        end;\n        z.state^.mode := DICT4;\n        { falltrough }\n      end;\n    DICT4:\n      begin\n        if (z.avail_in = 0) then\n        begin\n          inflate := r;\n          exit;\n        end;\n        r := f;\n\n        {z.state^.sub.check.need := uLong(NEXTBYTE(z)) shl 24;}\n        Dec(z.avail_in);\n        Inc(z.total_in);\n        z.state^.sub.check.need :=  uLong(z.next_in^) shl 24;\n        Inc(z.next_in);\n\n        z.state^.mode := DICT3;        { falltrough }\n      end;\n    DICT3:\n      begin\n        if (z.avail_in = 0) then\n        begin\n          inflate := r;\n          exit;\n        end;\n        r := f;\n        {Inc(z.state^.sub.check.need, uLong(NEXTBYTE(z)) shl 16);}\n        Dec(z.avail_in);\n        Inc(z.total_in);\n        Inc(z.state^.sub.check.need, uLong(z.next_in^) shl 16);\n        Inc(z.next_in);\n\n        z.state^.mode := DICT2;        { falltrough }\n      end;\n    DICT2:\n      begin\n        if (z.avail_in = 0) then\n        begin\n          inflate := r;\n          exit;\n        end;\n        r := f;\n\n        {Inc(z.state^.sub.check.need, uLong(NEXTBYTE(z)) shl 8);}\n        Dec(z.avail_in);\n        Inc(z.total_in);\n        Inc(z.state^.sub.check.need, uLong(z.next_in^) shl 8);\n        Inc(z.next_in);\n\n        z.state^.mode := DICT1;        { falltrough }\n      end;\n    DICT1:\n      begin\n        if (z.avail_in = 0) then\n        begin\n          inflate := r;\n          exit;\n        end;\n        { r := f;    ---  wird niemals benutzt }\n        {Inc(z.state^.sub.check.need, uLong(NEXTBYTE(z)) );}\n        Dec(z.avail_in);\n        Inc(z.total_in);\n        Inc(z.state^.sub.check.need, uLong(z.next_in^) );\n        Inc(z.next_in);\n\n        z.adler := z.state^.sub.check.need;\n        z.state^.mode := DICT0;\n        inflate := Z_NEED_DICT;\n        exit;\n      end;\n    DICT0:\n      begin\n        z.state^.mode := BAD;\n        z.msg := 'need dictionary';\n        z.state^.sub.marker := 0;         { can try inflateSync }\n        inflate := Z_STREAM_ERROR;\n        exit;\n      end;\n    BAD:\n      begin\n        inflate := Z_DATA_ERROR;\n        exit;\n      end;\n    else\n      begin\n        inflate := Z_STREAM_ERROR;\n        exit;\n      end;\n  end;\n{$ifdef NEED_DUMMY_result}\n  result := Z_STREAM_ERROR;  { Some dumb compilers complain without this }\n{$endif}\nend;\n\nfunction inflateSetDictionary(var z : z_stream;\n                              dictionary : pBytef; {const array of byte}\n                              dictLength : uInt) : int;\nvar\n  length : uInt;\nbegin\n  length := dictLength;\n\n  if (z.state = Z_NULL) or (z.state^.mode <> DICT0) then\n  begin\n    inflateSetDictionary := Z_STREAM_ERROR;\n    exit;\n  end;\n  if (adler32(Long(1), dictionary, dictLength) <> z.adler) then\n  begin\n    inflateSetDictionary := Z_DATA_ERROR;\n    exit;\n  end;\n  z.adler := Long(1);\n\n  if (length >= (uInt(1) shl z.state^.wbits)) then\n  begin\n    length := (1 shl z.state^.wbits)-1;\n    Inc( dictionary, dictLength - length);\n  end;\n  inflate_set_dictionary(z.state^.blocks^, dictionary^, length);\n  z.state^.mode := BLOCKS;\n  inflateSetDictionary := Z_OK;\nend;\n\n\nfunction inflateSync(var z : z_stream) : int;\nconst\n  mark : packed array[0..3] of byte = (0, 0, $ff, $ff);\nvar\n  n : uInt;       { number of bytes to look at }\n  p : pBytef;     { pointer to bytes }\n  m : uInt;       { number of marker bytes found in a row }\n  r, w : uLong;   { temporaries to save total_in and total_out }\nbegin\n  { set up }\n  if (z.state = Z_NULL) then\n  begin\n    inflateSync := Z_STREAM_ERROR;\n    exit;\n  end;\n  if (z.state^.mode <> BAD) then\n  begin\n    z.state^.mode := BAD;\n    z.state^.sub.marker := 0;\n  end;\n  n := z.avail_in;\n  if (n = 0) then\n  begin\n    inflateSync := Z_BUF_ERROR;\n    exit;\n  end;\n  p := z.next_in;\n  m := z.state^.sub.marker;\n\n  { search }\n  while (n <> 0) and (m < 4) do\n  begin\n    if (p^ = mark[m]) then\n      Inc(m)\n    else\n      if (p^ <> 0) then\n        m := 0\n      else\n        m := 4 - m;\n    Inc(p);\n    Dec(n);\n  end;\n\n  { restore }\n  Inc(z.total_in, ptr2int(p) - ptr2int(z.next_in));\n  z.next_in := p;\n  z.avail_in := n;\n  z.state^.sub.marker := m;\n\n\n  { return no joy or set up to restart on a new block }\n  if (m <> 4) then\n  begin\n    inflateSync := Z_DATA_ERROR;\n    exit;\n  end;\n  r := z.total_in;\n  w := z.total_out;\n  inflateReset(z);\n  z.total_in := r;\n  z.total_out := w;\n  z.state^.mode := BLOCKS;\n  inflateSync := Z_OK;\nend;\n\n\n{\n  returns true if inflate is currently at the end of a block generated\n  by Z_SYNC_FLUSH or Z_FULL_FLUSH. This function is used by one PPP\n  implementation to provide an additional safety check. PPP uses Z_SYNC_FLUSH\n  but removes the length bytes of the resulting empty stored block. When\n  decompressing, PPP checks that at the end of input packet, inflate is\n  waiting for these length bytes.\n}\n\nfunction inflateSyncPoint(var z : z_stream) : int;\nbegin\n  if (z.state = Z_NULL) or (z.state^.blocks = Z_NULL) then\n  begin\n    inflateSyncPoint := Z_STREAM_ERROR;\n    exit;\n  end;\n  inflateSyncPoint := inflate_blocks_sync_point(z.state^.blocks^);\nend;\n\nend.\n"
  },
  {
    "path": "lib/Imaging/ZLib/imzutil.pas",
    "content": "Unit imzutil;\n\n{\n  Copyright (C) 1998 by Jacques Nomssi Nzali\n  For conditions of distribution and use, see copyright notice in readme.txt\n}\n\ninterface\n\n{$I imzconf.inc}\n\n{ Type declarations }\n\ntype\n  {Byte   = usigned char;  8 bits}\n  Bytef  = byte;\n  charf  = byte;\n\n  int    = longint;\n  intf   = int;\n  uInt   = cardinal;     { 16 bits or more }\n  uIntf  = uInt;\n\n  Long   = longint;\n  uLong  = Cardinal;\n  uLongf = uLong;\n\n  voidp  = pointer;\n  voidpf = voidp;\n  pBytef = ^Bytef;\n  pIntf  = ^intf;\n  puIntf = ^uIntf;\n  puLong = ^uLongf;\n\n  ptr2int = uInt;\n{ a pointer to integer casting is used to do pointer arithmetic.\n  ptr2int must be an integer type and sizeof(ptr2int) must be less\n  than sizeof(pointer) - Nomssi }\n\ntype\n  zByteArray = array[0..(MaxInt div SizeOf(Bytef))-1] of Bytef;\n  pzByteArray = ^zByteArray;\ntype\n  zIntfArray = array[0..(MaxInt div SizeOf(Intf))-1] of Intf;\n  pzIntfArray = ^zIntfArray;\ntype\n  zuIntArray = array[0..(MaxInt div SizeOf(uInt))-1] of uInt;\n  PuIntArray = ^zuIntArray;\n\n{ Type declarations - only for deflate }\n\ntype\n  uch  = Byte;\n  uchf = uch; { FAR }\n  ush  = Word;\n  ushf = ush;\n  ulg  = LongInt;\n\n  unsigned = uInt;\n\n  pcharf = ^charf;\n  puchf = ^uchf;\n  pushf = ^ushf;\n\ntype\n  zuchfArray = zByteArray;\n  puchfArray = ^zuchfArray;\ntype\n  zushfArray = array[0..(MaxInt div SizeOf(ushf))-1] of ushf;\n  pushfArray = ^zushfArray;\n\nprocedure zmemcpy(destp : pBytef; sourcep : pBytef; len : uInt);\nfunction zmemcmp(s1p, s2p : pBytef; len : uInt) : int;\nprocedure zmemzero(destp : pBytef; len : uInt);\nprocedure zcfree(opaque : voidpf; ptr : voidpf);\nfunction zcalloc (opaque : voidpf; items : uInt; size : uInt) : voidpf;\n\nimplementation\n\nprocedure zmemcpy(destp : pBytef; sourcep : pBytef; len : uInt);\nbegin\n  Move(sourcep^, destp^, len);\nend;\n\nfunction zmemcmp(s1p, s2p : pBytef; len : uInt) : int;\nvar\n  j : uInt;\n  source,\n  dest : pBytef;\nbegin\n  source := s1p;\n  dest := s2p;\n  for j := 0 to pred(len) do\n  begin\n    if (source^ <> dest^) then\n    begin\n      zmemcmp := 2*Ord(source^ > dest^)-1;\n      exit;\n    end;\n    Inc(source);\n    Inc(dest);\n  end;\n  zmemcmp := 0;\nend;\n\nprocedure zmemzero(destp : pBytef; len : uInt);\nbegin\n  FillChar(destp^, len, 0);\nend;\n\nprocedure zcfree(opaque : voidpf; ptr : voidpf);\n{$ifdef Delphi16}\nvar\n  Handle : THandle;\n{$endif}\n{$IFDEF FPC}\nvar\n  memsize : uint;\n{$ENDIF}\nbegin\n  (*\n  {$IFDEF DPMI}\n  {h :=} GlobalFreePtr(ptr);\n  {$ELSE}\n    {$IFDEF CALL_DOS}\n    dosFree(ptr);\n    {$ELSE}\n      {$ifdef HugeMem}\n      FreeMemHuge(ptr);\n      {$else}\n        {$ifdef Delphi16}\n        Handle := GlobalHandle(LH(ptr).H); { HiWord(LongInt(ptr)) }\n        GlobalUnLock(Handle);\n        GlobalFree(Handle);\n        {$else}\n          {$IFDEF FPC}\n          Dec(puIntf(ptr));\n          memsize := puIntf(ptr)^;\n          FreeMem(ptr, memsize+SizeOf(uInt));\n          {$ELSE}\n          FreeMem(ptr);  { Delphi 2,3,4 }\n          {$ENDIF}\n        {$endif}\n      {$endif}\n    {$ENDIF}\n  {$ENDIF}\n  *)\n  FreeMem(ptr);\nend;\n\nfunction zcalloc (opaque : voidpf; items : uInt; size : uInt) : voidpf;\nvar\n  p : voidpf;\n  memsize : uLong;\n{$ifdef Delphi16}\n  handle : THandle;\n{$endif}\nbegin\n  memsize := uLong(items) * size;\n  (*\n  { $IFDEF DPMI}\n  p := GlobalAllocPtr(gmem_moveable, memsize);\n  { $ELSE}\n    { $IFDEF CALLDOS}\n    p := dosAlloc(memsize);\n    { $ELSE}\n      {$ifdef HugeMem}\n      GetMemHuge(p, memsize);\n      { $else}\n        { $ifdef Delphi16}\n        Handle := GlobalAlloc(HeapAllocFlags, memsize);\n        p := GlobalLock(Handle);\n        { $else}\n          { $IFDEF FPC}\n          GetMem(p, memsize+SizeOf(uInt));\n          puIntf(p)^:= memsize;\n          Inc(puIntf(p));\n          { $ELSE}\n          GetMem(p, memsize);  { Delphi: p := AllocMem(memsize); }\n          { $ENDIF}\n        { $endif}\n      { $endif}\n    { $ENDIF}\n  { $ENDIF}\n  *)\n  GetMem(p, memsize);\n  zcalloc := p;\nend;\n\nend.\n\n"
  },
  {
    "path": "lib/Imaging/ZLib/readme.txt",
    "content": "_____________________________________________________________________________\n\nPASZLIB 1.0                                                   May 11th, 1998\n\nBased on the zlib 1.1.2, a general purpose data compression library.\n\nCopyright (C) 1998,1999,2000 by NOMSSI NZALI Jacques H. C. \n[kn&n DES]         See \"Legal issues\" for conditions of distribution and use.\n_____________________________________________________________________________\n\n\nIntroduction\n============\n\nThe 'zlib' compression library provides in-memory compression and\ndecompression functions, including integrity checks of the uncompressed\ndata.  This version of the library supports only one compression method\n(deflation) but other algorithms will be added later and will have the same\nstream interface.\n\nCompression can be done in a single step if the buffers are large\nenough (for example if an input file is mmap'ed), or can be done by\nrepeated calls of the compression function.  In the latter case, the\napplication must provide more input and/or consume the output\n(providing more output space) before each call.\n\nThe default memory requirements for deflate are 256K plus a few kilobytes\nfor small objects. The default memory requirements for inflate are 32K\nplus a few kilobytes for small objects.\n\nChange Log\n==========\n\nMarch 24th 2000 - minizip code by Gilles Vollant ported to Pascal. \n                  z_stream.msg defined as string[255] to avoid problems\n                  with Delphi 2+ dynamic string handling.\n                  changes to silence Delphi 5 compiler warning. If you\n                  have Delphi 5, defines Delphi5 in zconf.inc\n                              \nMay 7th 1999    - Some changes for FPC\n                  deflateCopy() has new parameters\n                  trees.pas - record constant definition\nJune 17th 1998  - Applied official 1.1.2 patch. \n\t          Memcheck turned off by default.\n                  zutil.pas patch for Delphi 1 memory allocation corrected.\n                  dzlib.txt file added.\n                  compress2() is now exported\n\nJune 25th 1998 -  fixed a conversion bug: in inftrees.pas, ZFREE(z, v) was\n                  missing in line 574;\n\nFile list\n=========\n\nHere is a road map to the files in the Paszlib distribution.\n\nreadme.txt      Introduction, Documentation\ndzlib.txt       Changes to Delphi sources for Paszlib stream classes \n\ninclude file\n\nzconf.inc       Configuration declarations.\n\nPascal source code files:\n\nadler.pas      compute the Adler-32 checksum of a data stream\ncrc.pas        compute the CRC-32 of a data stream\ngzio.pas       IO on .gz files\ninfblock.pas   interpret and process block types to last block\ninfcodes.pas   process literals and length/distance pairs\ninffast.pas    process literals and length/distance pairs fast\ninftrees.pas   generate Huffman trees for efficient decoding\ninfutil.pas    types and macros common to blocks and codes\nstrutils.pas   string utilities\ntrees.pas      output deflated data using Huffman coding\nzcompres.pas   compress a memory buffer\nzdeflate.pas   compress data using the deflation algorithm\nzinflate.pas   zlib interface to inflate modules\nzlib.pas       zlib data structures. read the comments there!\nzuncompr.pas   decompress a memory buffer\nzutil.pas\n\nminizip/ziputils.pas data structure and IO on .zip file \nminizip/unzip.pas  \nminizip/zip.pas\n      \nTest applications\n\nexample.pas    usage example of the zlib compression library\nminigzip.pas   simulate gzip using the zlib compression library\nminizip/miniunz.pas  simulates unzip using the zlib compression library\nminizip/minizip.pas  simulates zip using the zlib compression library\n\nLegal issues\n============\n\nCopyright (C) 1998,1999,2000 by Jacques Nomssi Nzali\n\n  This software is provided 'as-is', without any express or implied\n  warranty.  In no event will the author be held liable for any damages\n  arising from the use of this software.\n\n  Permission is granted to anyone to use this software for any purpose,\n  including commercial applications, and to alter it and redistribute it\n  freely, subject to the following restrictions:\n\n  1. The origin of this software must not be misrepresented; you must not\n     claim that you wrote the original software. If you use this software\n     in a product, an acknowledgment in the product documentation would be\n     appreciated but is not required.\n  2. Altered source versions must be plainly marked as such, and must not be\n     misrepresented as being the original software.\n  3. This notice may not be removed or altered from any source distribution.\n\n\nArchive Locations:\n==================\n\nCheck the Paszlib home page with links\n\n      http://www.tu-chemnitz.de/~nomssi/paszlib.html\n\nThe data format used by the zlib library is described by RFCs (Request for\nComments) 1950 to 1952 in the files ftp://ds.internic.net/rfc/rfc1950.txt\n(zlib format), rfc1951.txt (deflate format) and rfc1952.txt (gzip format).\nThese documents are also available in other formats from\nftp://ftp.uu.net/graphics/png/documents/zlib/zdoc-index.html.\n____________________________________________________________________________\nJacques Nomssi Nzali <mailto:nomssi@physik.tu-chemnitz.de> March 24th, 2000"
  },
  {
    "path": "lib/abbrevia/MPL-1_1.txt",
    "content": "                          MOZILLA PUBLIC LICENSE\n                                Version 1.1\n\n                              ---------------\n\n1. Definitions.\n\n     1.0.1. \"Commercial Use\" means distribution or otherwise making the\n     Covered Code available to a third party.\n\n     1.1. \"Contributor\" means each entity that creates or contributes to\n     the creation of Modifications.\n\n     1.2. \"Contributor Version\" means the combination of the Original\n     Code, prior Modifications used by a Contributor, and the Modifications\n     made by that particular Contributor.\n\n     1.3. \"Covered Code\" means the Original Code or Modifications or the\n     combination of the Original Code and Modifications, in each case\n     including portions thereof.\n\n     1.4. \"Electronic Distribution Mechanism\" means a mechanism generally\n     accepted in the software development community for the electronic\n     transfer of data.\n\n     1.5. \"Executable\" means Covered Code in any form other than Source\n     Code.\n\n     1.6. \"Initial Developer\" means the individual or entity identified\n     as the Initial Developer in the Source Code notice required by Exhibit\n     A.\n\n     1.7. \"Larger Work\" means a work which combines Covered Code or\n     portions thereof with code not governed by the terms of this License.\n\n     1.8. \"License\" means this document.\n\n     1.8.1. \"Licensable\" means having the right to grant, to the maximum\n     extent possible, whether at the time of the initial grant or\n     subsequently acquired, any and all of the rights conveyed herein.\n\n     1.9. \"Modifications\" means any addition to or deletion from the\n     substance or structure of either the Original Code or any previous\n     Modifications. When Covered Code is released as a series of files, a\n     Modification is:\n          A. Any addition to or deletion from the contents of a file\n          containing Original Code or previous Modifications.\n\n          B. Any new file that contains any part of the Original Code or\n          previous Modifications.\n\n     1.10. \"Original Code\" means Source Code of computer software code\n     which is described in the Source Code notice required by Exhibit A as\n     Original Code, and which, at the time of its release under this\n     License is not already Covered Code governed by this License.\n\n     1.10.1. \"Patent Claims\" means any patent claim(s), now owned or\n     hereafter acquired, including without limitation,  method, process,\n     and apparatus claims, in any patent Licensable by grantor.\n\n     1.11. \"Source Code\" means the preferred form of the Covered Code for\n     making modifications to it, including all modules it contains, plus\n     any associated interface definition files, scripts used to control\n     compilation and installation of an Executable, or source code\n     differential comparisons against either the Original Code or another\n     well known, available Covered Code of the Contributor's choice. The\n     Source Code can be in a compressed or archival form, provided the\n     appropriate decompression or de-archiving software is widely available\n     for no charge.\n\n     1.12. \"You\" (or \"Your\")  means an individual or a legal entity\n     exercising rights under, and complying with all of the terms of, this\n     License or a future version of this License issued under Section 6.1.\n     For legal entities, \"You\" includes any entity which controls, is\n     controlled by, or is under common control with You. For purposes of\n     this definition, \"control\" means (a) the power, direct or indirect,\n     to cause the direction or management of such entity, whether by\n     contract or otherwise, or (b) ownership of more than fifty percent\n     (50%) of the outstanding shares or beneficial ownership of such\n     entity.\n\n2. Source Code License.\n\n     2.1. The Initial Developer Grant.\n     The Initial Developer hereby grants You a world-wide, royalty-free,\n     non-exclusive license, subject to third party intellectual property\n     claims:\n          (a)  under intellectual property rights (other than patent or\n          trademark) Licensable by Initial Developer to use, reproduce,\n          modify, display, perform, sublicense and distribute the Original\n          Code (or portions thereof) with or without Modifications, and/or\n          as part of a Larger Work; and\n\n          (b) under Patents Claims infringed by the making, using or\n          selling of Original Code, to make, have made, use, practice,\n          sell, and offer for sale, and/or otherwise dispose of the\n          Original Code (or portions thereof).\n\n          (c) the licenses granted in this Section 2.1(a) and (b) are\n          effective on the date Initial Developer first distributes\n          Original Code under the terms of this License.\n\n          (d) Notwithstanding Section 2.1(b) above, no patent license is\n          granted: 1) for code that You delete from the Original Code; 2)\n          separate from the Original Code;  or 3) for infringements caused\n          by: i) the modification of the Original Code or ii) the\n          combination of the Original Code with other software or devices.\n\n     2.2. Contributor Grant.\n     Subject to third party intellectual property claims, each Contributor\n     hereby grants You a world-wide, royalty-free, non-exclusive license\n\n          (a)  under intellectual property rights (other than patent or\n          trademark) Licensable by Contributor, to use, reproduce, modify,\n          display, perform, sublicense and distribute the Modifications\n          created by such Contributor (or portions thereof) either on an\n          unmodified basis, with other Modifications, as Covered Code\n          and/or as part of a Larger Work; and\n\n          (b) under Patent Claims infringed by the making, using, or\n          selling of  Modifications made by that Contributor either alone\n          and/or in combination with its Contributor Version (or portions\n          of such combination), to make, use, sell, offer for sale, have\n          made, and/or otherwise dispose of: 1) Modifications made by that\n          Contributor (or portions thereof); and 2) the combination of\n          Modifications made by that Contributor with its Contributor\n          Version (or portions of such combination).\n\n          (c) the licenses granted in Sections 2.2(a) and 2.2(b) are\n          effective on the date Contributor first makes Commercial Use of\n          the Covered Code.\n\n          (d)    Notwithstanding Section 2.2(b) above, no patent license is\n          granted: 1) for any code that Contributor has deleted from the\n          Contributor Version; 2)  separate from the Contributor Version;\n          3)  for infringements caused by: i) third party modifications of\n          Contributor Version or ii)  the combination of Modifications made\n          by that Contributor with other software  (except as part of the\n          Contributor Version) or other devices; or 4) under Patent Claims\n          infringed by Covered Code in the absence of Modifications made by\n          that Contributor.\n\n3. Distribution Obligations.\n\n     3.1. Application of License.\n     The Modifications which You create or to which You contribute are\n     governed by the terms of this License, including without limitation\n     Section 2.2. The Source Code version of Covered Code may be\n     distributed only under the terms of this License or a future version\n     of this License released under Section 6.1, and You must include a\n     copy of this License with every copy of the Source Code You\n     distribute. You may not offer or impose any terms on any Source Code\n     version that alters or restricts the applicable version of this\n     License or the recipients' rights hereunder. However, You may include\n     an additional document offering the additional rights described in\n     Section 3.5.\n\n     3.2. Availability of Source Code.\n     Any Modification which You create or to which You contribute must be\n     made available in Source Code form under the terms of this License\n     either on the same media as an Executable version or via an accepted\n     Electronic Distribution Mechanism to anyone to whom you made an\n     Executable version available; and if made available via Electronic\n     Distribution Mechanism, must remain available for at least twelve (12)\n     months after the date it initially became available, or at least six\n     (6) months after a subsequent version of that particular Modification\n     has been made available to such recipients. You are responsible for\n     ensuring that the Source Code version remains available even if the\n     Electronic Distribution Mechanism is maintained by a third party.\n\n     3.3. Description of Modifications.\n     You must cause all Covered Code to which You contribute to contain a\n     file documenting the changes You made to create that Covered Code and\n     the date of any change. You must include a prominent statement that\n     the Modification is derived, directly or indirectly, from Original\n     Code provided by the Initial Developer and including the name of the\n     Initial Developer in (a) the Source Code, and (b) in any notice in an\n     Executable version or related documentation in which You describe the\n     origin or ownership of the Covered Code.\n\n     3.4. Intellectual Property Matters\n          (a) Third Party Claims.\n          If Contributor has knowledge that a license under a third party's\n          intellectual property rights is required to exercise the rights\n          granted by such Contributor under Sections 2.1 or 2.2,\n          Contributor must include a text file with the Source Code\n          distribution titled \"LEGAL\" which describes the claim and the\n          party making the claim in sufficient detail that a recipient will\n          know whom to contact. If Contributor obtains such knowledge after\n          the Modification is made available as described in Section 3.2,\n          Contributor shall promptly modify the LEGAL file in all copies\n          Contributor makes available thereafter and shall take other steps\n          (such as notifying appropriate mailing lists or newsgroups)\n          reasonably calculated to inform those who received the Covered\n          Code that new knowledge has been obtained.\n\n          (b) Contributor APIs.\n          If Contributor's Modifications include an application programming\n          interface and Contributor has knowledge of patent licenses which\n          are reasonably necessary to implement that API, Contributor must\n          also include this information in the LEGAL file.\n\n               (c)    Representations.\n          Contributor represents that, except as disclosed pursuant to\n          Section 3.4(a) above, Contributor believes that Contributor's\n          Modifications are Contributor's original creation(s) and/or\n          Contributor has sufficient rights to grant the rights conveyed by\n          this License.\n\n     3.5. Required Notices.\n     You must duplicate the notice in Exhibit A in each file of the Source\n     Code.  If it is not possible to put such notice in a particular Source\n     Code file due to its structure, then You must include such notice in a\n     location (such as a relevant directory) where a user would be likely\n     to look for such a notice.  If You created one or more Modification(s)\n     You may add your name as a Contributor to the notice described in\n     Exhibit A.  You must also duplicate this License in any documentation\n     for the Source Code where You describe recipients' rights or ownership\n     rights relating to Covered Code.  You may choose to offer, and to\n     charge a fee for, warranty, support, indemnity or liability\n     obligations to one or more recipients of Covered Code. However, You\n     may do so only on Your own behalf, and not on behalf of the Initial\n     Developer or any Contributor. You must make it absolutely clear than\n     any such warranty, support, indemnity or liability obligation is\n     offered by You alone, and You hereby agree to indemnify the Initial\n     Developer and every Contributor for any liability incurred by the\n     Initial Developer or such Contributor as a result of warranty,\n     support, indemnity or liability terms You offer.\n\n     3.6. Distribution of Executable Versions.\n     You may distribute Covered Code in Executable form only if the\n     requirements of Section 3.1-3.5 have been met for that Covered Code,\n     and if You include a notice stating that the Source Code version of\n     the Covered Code is available under the terms of this License,\n     including a description of how and where You have fulfilled the\n     obligations of Section 3.2. The notice must be conspicuously included\n     in any notice in an Executable version, related documentation or\n     collateral in which You describe recipients' rights relating to the\n     Covered Code. You may distribute the Executable version of Covered\n     Code or ownership rights under a license of Your choice, which may\n     contain terms different from this License, provided that You are in\n     compliance with the terms of this License and that the license for the\n     Executable version does not attempt to limit or alter the recipient's\n     rights in the Source Code version from the rights set forth in this\n     License. If You distribute the Executable version under a different\n     license You must make it absolutely clear that any terms which differ\n     from this License are offered by You alone, not by the Initial\n     Developer or any Contributor. You hereby agree to indemnify the\n     Initial Developer and every Contributor for any liability incurred by\n     the Initial Developer or such Contributor as a result of any such\n     terms You offer.\n\n     3.7. Larger Works.\n     You may create a Larger Work by combining Covered Code with other code\n     not governed by the terms of this License and distribute the Larger\n     Work as a single product. In such a case, You must make sure the\n     requirements of this License are fulfilled for the Covered Code.\n\n4. Inability to Comply Due to Statute or Regulation.\n\n     If it is impossible for You to comply with any of the terms of this\n     License with respect to some or all of the Covered Code due to\n     statute, judicial order, or regulation then You must: (a) comply with\n     the terms of this License to the maximum extent possible; and (b)\n     describe the limitations and the code they affect. Such description\n     must be included in the LEGAL file described in Section 3.4 and must\n     be included with all distributions of the Source Code. Except to the\n     extent prohibited by statute or regulation, such description must be\n     sufficiently detailed for a recipient of ordinary skill to be able to\n     understand it.\n\n5. Application of this License.\n\n     This License applies to code to which the Initial Developer has\n     attached the notice in Exhibit A and to related Covered Code.\n\n6. Versions of the License.\n\n     6.1. New Versions.\n     Netscape Communications Corporation (\"Netscape\") may publish revised\n     and/or new versions of the License from time to time. Each version\n     will be given a distinguishing version number.\n\n     6.2. Effect of New Versions.\n     Once Covered Code has been published under a particular version of the\n     License, You may always continue to use it under the terms of that\n     version. You may also choose to use such Covered Code under the terms\n     of any subsequent version of the License published by Netscape. No one\n     other than Netscape has the right to modify the terms applicable to\n     Covered Code created under this License.\n\n     6.3. Derivative Works.\n     If You create or use a modified version of this License (which you may\n     only do in order to apply it to code which is not already Covered Code\n     governed by this License), You must (a) rename Your license so that\n     the phrases \"Mozilla\", \"MOZILLAPL\", \"MOZPL\", \"Netscape\",\n     \"MPL\", \"NPL\" or any confusingly similar phrase do not appear in your\n     license (except to note that your license differs from this License)\n     and (b) otherwise make it clear that Your version of the license\n     contains terms which differ from the Mozilla Public License and\n     Netscape Public License. (Filling in the name of the Initial\n     Developer, Original Code or Contributor in the notice described in\n     Exhibit A shall not of themselves be deemed to be modifications of\n     this License.)\n\n7. DISCLAIMER OF WARRANTY.\n\n     COVERED CODE IS PROVIDED UNDER THIS LICENSE ON AN \"AS IS\" BASIS,\n     WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,\n     WITHOUT LIMITATION, WARRANTIES THAT THE COVERED CODE IS FREE OF\n     DEFECTS, MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE OR NON-INFRINGING.\n     THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE COVERED CODE\n     IS WITH YOU. SHOULD ANY COVERED CODE PROVE DEFECTIVE IN ANY RESPECT,\n     YOU (NOT THE INITIAL DEVELOPER OR ANY OTHER CONTRIBUTOR) ASSUME THE\n     COST OF ANY NECESSARY SERVICING, REPAIR OR CORRECTION. THIS DISCLAIMER\n     OF WARRANTY CONSTITUTES AN ESSENTIAL PART OF THIS LICENSE. NO USE OF\n     ANY COVERED CODE IS AUTHORIZED HEREUNDER EXCEPT UNDER THIS DISCLAIMER.\n\n8. TERMINATION.\n\n     8.1.  This License and the rights granted hereunder will terminate\n     automatically if You fail to comply with terms herein and fail to cure\n     such breach within 30 days of becoming aware of the breach. All\n     sublicenses to the Covered Code which are properly granted shall\n     survive any termination of this License. Provisions which, by their\n     nature, must remain in effect beyond the termination of this License\n     shall survive.\n\n     8.2.  If You initiate litigation by asserting a patent infringement\n     claim (excluding declatory judgment actions) against Initial Developer\n     or a Contributor (the Initial Developer or Contributor against whom\n     You file such action is referred to as \"Participant\")  alleging that:\n\n     (a)  such Participant's Contributor Version directly or indirectly\n     infringes any patent, then any and all rights granted by such\n     Participant to You under Sections 2.1 and/or 2.2 of this License\n     shall, upon 60 days notice from Participant terminate prospectively,\n     unless if within 60 days after receipt of notice You either: (i)\n     agree in writing to pay Participant a mutually agreeable reasonable\n     royalty for Your past and future use of Modifications made by such\n     Participant, or (ii) withdraw Your litigation claim with respect to\n     the Contributor Version against such Participant.  If within 60 days\n     of notice, a reasonable royalty and payment arrangement are not\n     mutually agreed upon in writing by the parties or the litigation claim\n     is not withdrawn, the rights granted by Participant to You under\n     Sections 2.1 and/or 2.2 automatically terminate at the expiration of\n     the 60 day notice period specified above.\n\n     (b)  any software, hardware, or device, other than such Participant's\n     Contributor Version, directly or indirectly infringes any patent, then\n     any rights granted to You by such Participant under Sections 2.1(b)\n     and 2.2(b) are revoked effective as of the date You first made, used,\n     sold, distributed, or had made, Modifications made by that\n     Participant.\n\n     8.3.  If You assert a patent infringement claim against Participant\n     alleging that such Participant's Contributor Version directly or\n     indirectly infringes any patent where such claim is resolved (such as\n     by license or settlement) prior to the initiation of patent\n     infringement litigation, then the reasonable value of the licenses\n     granted by such Participant under Sections 2.1 or 2.2 shall be taken\n     into account in determining the amount or value of any payment or\n     license.\n\n     8.4.  In the event of termination under Sections 8.1 or 8.2 above,\n     all end user license agreements (excluding distributors and resellers)\n     which have been validly granted by You or any distributor hereunder\n     prior to termination shall survive termination.\n\n9. LIMITATION OF LIABILITY.\n\n     UNDER NO CIRCUMSTANCES AND UNDER NO LEGAL THEORY, WHETHER TORT\n     (INCLUDING NEGLIGENCE), CONTRACT, OR OTHERWISE, SHALL YOU, THE INITIAL\n     DEVELOPER, ANY OTHER CONTRIBUTOR, OR ANY DISTRIBUTOR OF COVERED CODE,\n     OR ANY SUPPLIER OF ANY OF SUCH PARTIES, BE LIABLE TO ANY PERSON FOR\n     ANY INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES OF ANY\n     CHARACTER INCLUDING, WITHOUT LIMITATION, DAMAGES FOR LOSS OF GOODWILL,\n     WORK STOPPAGE, COMPUTER FAILURE OR MALFUNCTION, OR ANY AND ALL OTHER\n     COMMERCIAL DAMAGES OR LOSSES, EVEN IF SUCH PARTY SHALL HAVE BEEN\n     INFORMED OF THE POSSIBILITY OF SUCH DAMAGES. THIS LIMITATION OF\n     LIABILITY SHALL NOT APPLY TO LIABILITY FOR DEATH OR PERSONAL INJURY\n     RESULTING FROM SUCH PARTY'S NEGLIGENCE TO THE EXTENT APPLICABLE LAW\n     PROHIBITS SUCH LIMITATION. SOME JURISDICTIONS DO NOT ALLOW THE\n     EXCLUSION OR LIMITATION OF INCIDENTAL OR CONSEQUENTIAL DAMAGES, SO\n     THIS EXCLUSION AND LIMITATION MAY NOT APPLY TO YOU.\n\n10. U.S. GOVERNMENT END USERS.\n\n     The Covered Code is a \"commercial item,\" as that term is defined in\n     48 C.F.R. 2.101 (Oct. 1995), consisting of \"commercial computer\n     software\" and \"commercial computer software documentation,\" as such\n     terms are used in 48 C.F.R. 12.212 (Sept. 1995). Consistent with 48\n     C.F.R. 12.212 and 48 C.F.R. 227.7202-1 through 227.7202-4 (June 1995),\n     all U.S. Government End Users acquire Covered Code with only those\n     rights set forth herein.\n\n11. MISCELLANEOUS.\n\n     This License represents the complete agreement concerning subject\n     matter hereof. If any provision of this License is held to be\n     unenforceable, such provision shall be reformed only to the extent\n     necessary to make it enforceable. This License shall be governed by\n     California law provisions (except to the extent applicable law, if\n     any, provides otherwise), excluding its conflict-of-law provisions.\n     With respect to disputes in which at least one party is a citizen of,\n     or an entity chartered or registered to do business in the United\n     States of America, any litigation relating to this License shall be\n     subject to the jurisdiction of the Federal Courts of the Northern\n     District of California, with venue lying in Santa Clara County,\n     California, with the losing party responsible for costs, including\n     without limitation, court costs and reasonable attorneys' fees and\n     expenses. The application of the United Nations Convention on\n     Contracts for the International Sale of Goods is expressly excluded.\n     Any law or regulation which provides that the language of a contract\n     shall be construed against the drafter shall not apply to this\n     License.\n\n12. RESPONSIBILITY FOR CLAIMS.\n\n     As between Initial Developer and the Contributors, each party is\n     responsible for claims and damages arising, directly or indirectly,\n     out of its utilization of rights under this License and You agree to\n     work with Initial Developer and Contributors to distribute such\n     responsibility on an equitable basis. Nothing herein is intended or\n     shall be deemed to constitute any admission of liability.\n\n13. MULTIPLE-LICENSED CODE.\n\n     Initial Developer may designate portions of the Covered Code as\n     \"Multiple-Licensed\".  \"Multiple-Licensed\" means that the Initial\n     Developer permits you to utilize portions of the Covered Code under\n     Your choice of the NPL or the alternative licenses, if any, specified\n     by the Initial Developer in the file described in Exhibit A.\n\nEXHIBIT A -Mozilla Public License.\n\n     ``The contents of this file are subject to the Mozilla Public License\n     Version 1.1 (the \"License\"); you may not use this file except in\n     compliance with the License. You may obtain a copy of the License at\n     http://www.mozilla.org/MPL/\n\n     Software distributed under the License is distributed on an \"AS IS\"\n     basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the\n     License for the specific language governing rights and limitations\n     under the License.\n\n     The Original Code is ______________________________________.\n\n     The Initial Developer of the Original Code is ________________________.\n     Portions created by ______________________ are Copyright (C) ______\n     _______________________. All Rights Reserved.\n\n     Contributor(s): ______________________________________.\n\n     Alternatively, the contents of this file may be used under the terms\n     of the _____ license (the  \"[___] License\"), in which case the\n     provisions of [______] License are applicable instead of those\n     above.  If you wish to allow use of your version of this file only\n     under the terms of the [____] License and not to allow others to use\n     your version of this file under the MPL, indicate your decision by\n     deleting  the provisions above and replace  them with the notice and\n     other provisions required by the [___] License.  If you do not delete\n     the provisions above, a recipient may use your version of this file\n     under either the MPL or the [___] License.\"\n\n     [NOTE: The text of this Exhibit A may differ slightly from the text of\n     the notices in the Source Code files of the Original Code. You should\n     use the text of this Exhibit A rather than the text found in the\n     Original Code Source Code for Your Modifications.]\n\n"
  },
  {
    "path": "lib/abbrevia/Readme.html",
    "content": "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\">\n<html lang=\"en-us\">\n<head>\n  <title>Abbrevia v5.0</title>\n  <meta content=\"text/html;charset=ISO-8859-1\" http-equiv=\"Content-Type\">\n  <style type=\"text/css\">\n    a:link {color: #03f; text-decoration: none;}\n    a:visited {color: #03f; text-decoration: none;}\n    a:hover {text-decoration: underline;}\n    h3 > a:hover {text-decoration: none;}\n    body {font-family: 'Verdana', 'Arial', Sans-Serif; font-size: 10pt;}\n    li {margin-bottom: .3em;}\n  </style>\n</head>\n\n<body>\n\n<h1>Abbrevia</h1>\n\n<p>Version 5.0<br>\nDecember 6, 2011<br>\n<a href=\"http://tpabbrevia.sourceforge.net/\">Home Page</a></p>\n\n<hr>\n\n<h3>Table of contents</h3>\n\n<ul>\n  <li><a href=\"#intro\">Introduction</a></li>\n  <li><a href=\"#packages\">Packages</a></li>\n  <li><a href=\"#install\">Installation</a></li>\n  <li><a href=\"#support\">Support and feedback</a></li>\n  <li><a href=\"#devel\">Development sources</a></li>\n  <li><a href=\"#contribute\">Getting involved</a></li>\n  <li><a href=\"#license\">License</a></li>\n  <li><a href=\"#changes\">Changes from 4.0</a></li>\n</ul>\n\n\n<!--====================--><hr>\n\n\n<h3><a name=\"intro\">Introduction</a></h3>\n\n<p>Abbrevia is a compression toolkit for Embarcadero Delphi, C++ Builder, and Kylix, and FreePascal. It supports PKZip, Microsoft CAB, tar, gzip, bzip2 and zlib compression formats, and the creation of self-extracting executables.  It includes several visual components that simplify displaying zip files.</p>\n\n<p>Abbrevia 5.0 adds a number of new features and support for more platforms:</p>\n\n<ul>\n  <li>RAD Studio XE2 support, including both 64-bit Windows and OS X</li>\n  <li>FreePascal support on Windows, OS X, and Linux</li>\n  <li>TAbTreeView and TAbListView VCL controls that provide an Explorer/WinZip-like interface</li>\n  <li>ZIP64 support, for archives larger than 2GB</li>\n  <li>Improved split/spanned zip support</li>\n  <li>Expanded LZMA support</li>\n  <li>Unicode filenames in tar and gzip archives</li>\n</ul>\n\n<p>This is a source-only release. It includes design-time and run-time packages for Delphi 6 through Delphi XE2, C++Builder 2009 through XE2, and Kylix 3.  FreePascal is supported, but runtime/design time packages are not included.  The LZMA, PPMd, and WavPack algorithms are only supported on Delphi/C++Builder for Windows (32 and 64-bit).</p>\n\n\n<!--====================--><hr>\n\n\n<h3><a name=\"packages\">Packages</a></h3>\n\n<p>Abbrevia includes the following packages:</p>\n\n<ul>\n  <li><b>Abbrevia.bpl</b>: Runtime non-visual components.  <code>TAbZipBrowse</code>, <code>TAbZipKit</code>, <code>TAbMakeCab</code>, etc.</li>\n  <li><b>AbbreviaVCL.bpl</b>: Runtime visual components.  <code>TAbTreeView</code>, <code>TAbListView</code>, <code>TAbProgressBar</code>.</li>\n  <li><b>AbbreviaVCLDesign.bpl</b>: Designtime support.</li>\n  <li><b>AbbreviaCLX.bpl</b>, <b>AbbreviaCLXDesign.bpl</b> (Delphi 6/7): CLX visual components.</li>\n</ul>\n\n<p><code>$LIBSUFFIX</code> is used, so each .bpl/.bpi will have a version number after it corresponding to the compiler version (e.g. 160 for Delphi XE2).</p>\n\n<p>The Kylix 3 <code>AbbreviaCLX</code> package includes all of the non-visual runtime units, and the <code>Abbrevia</code> package is not included separately.</p>\n\n\n<!--====================--><hr>\n\n\n<h3><a name=\"install\">Installation</a></h3>\n\n<p>To install TurboPower Abbrevia into your IDE:</p>\n\n<ol>\n  <li>Unzip the release files into a directory (e.g., d:\\abbrevia).</li>\n  <li>Start Delphi or C++Builder.</li>\n  <li>Add the source subdirectory (e.g. d:\\abbrevia\\source) to the Delphi Library path.  When using XE2 or later, add it to all platforms.</li>\n  <li>If using C++Builder, add the source subdirectory to C++Builder's Include and Library paths.</li>\n  <li>Open the project group in the packages directory that corresponds to the IDE being used (e.g. \"Delphi XE2.groupproj\").</li>\n  <li>Start at the top of the project group and compile each package in turn.  If using C++Builder, install each one after compiling.</li>\n  <li>Select the \"AbbreviaVCLDesign\" package and install it.  The IDE should notify you that the components have been installed.  If you are using Delphi 7 you can install \"AbbreviaCLXDesign\" as well to get CLX designtime support.</li>\n  <li>Make sure the PATH environmental variable contains the directory in which the compiled packages (i.e. BPL or DPL files) were placed.</li>\n</ol>\n\n\n<!--====================--><hr>\n\n\n<h3><a name=\"support\">Support and feedback</a></h3>\n\n<p><a href=\"https://sourceforge.net/projects/tpabbrevia/forums\">Support forums</a> are available on the SourceForge project site.</p>\n\n<p>Bug reports can be entered in the <a href=\"http://sourceforge.net/tracker/?atid=529778&group_id=71001&func=browse\">bug tracker</a>. If possible please include a small test case that reproduces the issue. Sample files can be attached to the bug report, and confidential data can be emailed to the project administrator.</p>\n\n<p>If you have something you would like to see in the product feel free to add a <a href=\"http://sourceforge.net/tracker/?atid=529781&group_id=71001&func=browse\">feature request</a>.</p>\n\n\n<!--====================--><hr>\n\n\n<h3><a name=\"devel\">Development sources</a></h3>\n\n<p>The current source code is available in the Subversion <a href=\"https://sourceforge.net/scm/?type=svn&group_id=71001\">repository</a>. The code here may not be as stable or tested as the official releases, but may include bug fixes or new features not yet included in the downloadable releases.</p>\n\n<p>The repository also includes <a href=\"http://dunit.sourceforge.net/\">DUnit</a> tests, the source code to the third-party libraries, and the Help source code.</p>\n\n\n<!--====================--><hr>\n\n\n<h3><a name=\"contribute\">Getting involved</a></h3>\n\n<p>If you want to help make Abbrevia better, there are several ways to get involved. We welcome help with features and bug fixes. Just look in the issue tracker to see what's needed. We're also looking for help for:</p>\n\n<ul>\n  <li>C++Builder maintainer</li>\n  <li>FreePascal maintainer</li>\n  <li>Webmaster</li>\n  <li>Documentation</li>\n  <li>Examples</li>\n</ul>\n\n\n<!--====================--><hr>\n\n\n<h3><a name=\"license\">License</a></h3>\n\n<p>Abbrevia is licensed under the <a href=\"http://www.mozilla.org/MPL/MPL-1.1.html\">Mozilla Public License</a>, version 1.1. It can be used in commercial and closed-source applications provided any changes to Abbrevia units are made available electronically.</p>\n\n<p>The <a href=\"http://www.wavpack.com/\">WavPack</a> library used for zipx decompression has its own license, included as \"WavPack License.txt\". Redistribution requires a copyright notice in your documentation or elsewhere in your distribution. WavPack support can be removed by disabling the <b>UnzipZipxSupport</b> or <b>UnzipWavPackSupport</b> conditional define in <b>AbDefine.inc</b>.</p> \n\n\n<!--====================--><hr>\n\n\n<h3><a name=\"changes\">Changes from 4.0</a></h3>\n\n<p>These are the most significant features, fixes and changes made since v4.0. Information on earlier versions is available in the full <a href=\"http://tpabbrevia.sourceforge.net/Changelog\">changelog</a>.</p>\n\n<h4>Features</h4>\n\n<ul>\n  <li>Added support for Delphi/C++Builder XE2, including the 64-bit Windows and OS X platforms.</li>\n  <li>Added support for FreePascal 2.4/2.6 on Windows, OS X, and Linux.</li>\n  <li>Added <b>TAbTreeView</b> and <b>TAbListView</b> VCL controls that provide an Explorer/WinZip-like interface, and ComCtrlsDemo Delphi example to demonstrate their usage.</li>\n  <li>Added ZIP64 support (reading/writing zip archives larger than 2GB, containing files larger than 2GB, or containing more than 65K files).</li>\n  <li>Significantly improved split/spanned zip support.</li>\n  <li>Added LZMA buffer-to-buffer compression/decompression (<b>LzmaEncodeBuffer</b> and <b>LzmaDecodeBuffer</b>) and compression/decompression stream descendants (<b>TAbLZMACompressionStream</b> and <b>TAbLZMADecompressionStream</b>).  Thanks to Pierre le Riche.</li>\n  <li>Added support for tar and gzip archives containing filenames encoded in the system ANSI and OEM codepage and UTF-8.  New archives are written using UTF-8.</li>\n  <li>Added icon/text to RAD Studio's splash screen and about box.  Thanks to Lance Rasmussen.</li>\n  <li>Added VCL TAbProgressBar control that can replace TAbMeter.</li>\n  <li>Added 64-bit COM dll and support for per-user registration.</li>\n</ul>\n\n<h4>API Changes</h4>\n\n<ul>\n  <li>Renamed <code>LzEncode/LzDecode</code> to <code>LzmaEncodeStream/LzmaDecodeStream</code>.</li>\n  <li>Renamed <code>LzmaDecode</code> to <code>LzmaDecodeStream</code>.</li>\n  <li>Various changes due to split/spanned zip changes (see below).</li>\n</ul>\n\n<h4>Bug Fixes</h4>\n\n<ul>\n  <li>Fixed support for opening paths with a \"\\\\?\\\" prefix.</li>\n  <li>Fixed buffer overflow in AbUtils.pas.</li>\n  <li>Fixed freshening/replacing items using absolute paths.</li>\n  <li>Fixed CAB files created with Delphi 2009 and later incorrectly including the \"has next volume\" flag.</li>\n  <li>Fixed Delphi 6 support. Thanks to Peter Luijer.</li>\n  <li>Fixed <code>AbFindFiles</code> so it finds system and hidden folders if the SearchAttr parameter includes them [3372355].</li>\n  <li>Fixed hang when trying to extract files that cross CAB boundaries when the next cab is not available [3370538].</li>\n  <li>Fixed extracting CAB archives so OnProcessItemFailure isn't called after a successful extraction.</li>\n  <li>Fixed LZMA support for streams larger than 2GB.</li>\n  <li>Fixed <code>AbGetDriveFreeSpace</code> buffer overflow and fixed support for free space larger than 2GB.</li>\n  <li>Fixed support for modifying SFX zips with non-native stubs (Linux on Windows and vice versa).</li>\n  <li>Fixed <code>TAbBitBucketStream</code> so it doesn't fault on writes larger than the buffer size, and supports sizes over 2GB.</li>\n  <li>Zip local file headers are now preserved when copying unmodified files to a new archive.</li>\n  <li>Local file headers are no longer copies of the central directory headers, since many of the defined extra data fields have different values in the two locations.</li>\n  <li>Fixed IZipKit (COM) support for enumerations (for each).</li>\n</ul>\n\n<h4>Split/Spanned Zip Changes</h4>\n\n<ul>\n  <li>\n    <h5>Bug Fixes</h5>\n    <ul>\n      <li>Added support for reading/writing unequally sized spans.</li>\n      <li>Split/spanned zips are now written to the final location as they're compressed, rather than writing everything to a virtual memory stream first.</li>\n      <li>Fixed writing headers that can't be spanned so they trigger a new span if necessary.</li>\n    </ul>\n  </li>\n  <li>\n    <h5>API Changes</h5>\n    <ul>\n      <li>Converting from an unspanned archive to a spanned one is no longer supported.</li>\n      <li><code>OnRequestImage</code>'s span numbers are now 1-based instead of 0-based to match <code>OnRequestNthDisk</code>.</li>\n      <li><code>OnArchiveSaveProgress</code> is now called at the same time as <code>OnArchiveProgress</code>, since there isn't a lengthy copy after a spanned archive is written.</li>\n      <li><code>TAbSpanStream</code> has been replaced by <code>TAbSpanReadStream</code> and <code>TAbSpanWriteStream</code>.</li>\n    </ul>\n  </li>\n</ul>\n\n</body>\n</html>"
  },
  {
    "path": "lib/abbrevia/WavPack License.txt",
    "content": "               Copyright (c) 1998 - 2009 Conifer Software\n                          All rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n    * Redistributions of source code must retain the above copyright notice,\n      this list of conditions and the following disclaimer.\n    * Redistributions in binary form must reproduce the above copyright notice,\n      this list of conditions and the following disclaimer in the\n      documentation and/or other materials provided with the distribution.\n    * Neither the name of Conifer Software nor the names of its contributors\n      may be used to endorse or promote products derived from this software\n      without specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\nAND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\nIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\nARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR\nANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\nDAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR\nSERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER\nCAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,\nOR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\nOF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n"
  },
  {
    "path": "lib/abbrevia/examples/Delphi/Abbrexam.dpr",
    "content": "(* ***** BEGIN LICENSE BLOCK *****\n * Version: MPL 1.1\n *\n * The contents of this file are subject to the Mozilla Public License Version\n * 1.1 (the \"License\"); you may not use this file except in compliance with\n * the License. You may obtain a copy of the License at\n * http://www.mozilla.org/MPL/\n *\n * Software distributed under the License is distributed on an \"AS IS\" basis,\n * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License\n * for the specific language governing rights and limitations under the\n * License.\n *\n * The Original Code is TurboPower Abbrevia\n *\n * The Initial Developer of the Original Code is\n * TurboPower Software\n *\n * Portions created by the Initial Developer are Copyright (C) 1997-2002\n * the Initial Developer. All Rights Reserved.\n *\n * Contributor(s):\n *\n * ***** END LICENSE BLOCK ***** *)\n\n{*********************************************************}\n{* ABBREVIA: ABBREXAM.DPR                                *}\n{*********************************************************}\n{* ABBREVIA Example program file                         *}\n{*********************************************************}\n\nprogram Abbrexam;\n\n{$R *.res}\n\nuses\n  Forms,\n  udemodlg in 'udemodlg.pas' {DemoDlg},\n  uexample in 'Uexample.pas' {Form1};\n\nbegin\n  Application.CreateForm(TForm1, Form1);\n  Application.CreateForm(TForm1, Form1);\n  Application.CreateForm(TDemoDlg, DemoDlg);\n  Application.Run;\nend.\n"
  },
  {
    "path": "lib/abbrevia/examples/Delphi/BaseDlgu.pas",
    "content": "(* ***** BEGIN LICENSE BLOCK *****\n * Version: MPL 1.1\n *\n * The contents of this file are subject to the Mozilla Public License Version\n * 1.1 (the \"License\"); you may not use this file except in compliance with\n * the License. You may obtain a copy of the License at\n * http://www.mozilla.org/MPL/\n *\n * Software distributed under the License is distributed on an \"AS IS\" basis,\n * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License\n * for the specific language governing rights and limitations under the\n * License.\n *\n * The Original Code is TurboPower Abbrevia\n *\n * The Initial Developer of the Original Code is\n * TurboPower Software\n *\n * Portions created by the Initial Developer are Copyright (C) 1997-2002\n * the Initial Developer. All Rights Reserved.\n *\n * Contributor(s):\n *\n * ***** END LICENSE BLOCK ***** *)\n\nunit Basedlgu;\n\ninterface\n\nuses WinTypes, WinProcs, Classes, Graphics, Forms, Controls, Buttons,\n  StdCtrls, FileCtrl, ExtCtrls;\n\ntype\n  TBaseDlg = class(TForm)\n    Bevel1: TBevel;\n    DirectoryListBox1: TDirectoryListBox;\n    CancelBtn: TButton;\n    OkBtn: TButton;\n    procedure DirectoryListBox1Change(Sender: TObject);\n    procedure FormShow(Sender: TObject);\n  private\n    { Private declarations }\n  public\n    BaseDirectory : string;\n  end;\n\nvar\n  BaseDlg: TBaseDlg;\n\nimplementation\n\n{$R *.DFM}\n\n\nprocedure TBaseDlg.DirectoryListBox1Change(Sender: TObject);\nbegin\n  BaseDirectory := DirectoryListBox1.Directory;\nend;\n\nprocedure TBaseDlg.FormShow(Sender: TObject);\nbegin\n  DirectoryListBox1.Directory := BaseDirectory;\nend;\n\nend.\n"
  },
  {
    "path": "lib/abbrevia/examples/Delphi/CabExt.dpr",
    "content": "(* ***** BEGIN LICENSE BLOCK *****\n * Version: MPL 1.1\n *\n * The contents of this file are subject to the Mozilla Public License Version\n * 1.1 (the \"License\"); you may not use this file except in compliance with\n * the License. You may obtain a copy of the License at\n * http://www.mozilla.org/MPL/\n *\n * Software distributed under the License is distributed on an \"AS IS\" basis,\n * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License\n * for the specific language governing rights and limitations under the\n * License.\n *\n * The Original Code is TurboPower Abbrevia\n *\n * The Initial Developer of the Original Code is\n * TurboPower Software\n *\n * Portions created by the Initial Developer are Copyright (C) 1997-2002\n * the Initial Developer. All Rights Reserved.\n *\n * Contributor(s):\n *\n * ***** END LICENSE BLOCK ***** *)\n\n{*********************************************************}\n{* ABBREVIA: UNZIP.DPR                                   *}\n{*********************************************************}\n{* ABBREVIA Example program file                         *}\n{*********************************************************}\n\nprogram CabExt;\n\nuses\n  Forms,\n  CabExt1 in 'CabExt1.pas' {Form1};\n\nbegin\n  Application.CreateForm(TForm1, Form1);\n  Application.CreateForm(TForm1, Form1);\n  Application.Run;\nend.\n"
  },
  {
    "path": "lib/abbrevia/examples/Delphi/CabExt1.pas",
    "content": "(* ***** BEGIN LICENSE BLOCK *****\n * Version: MPL 1.1\n *\n * The contents of this file are subject to the Mozilla Public License Version\n * 1.1 (the \"License\"); you may not use this file except in compliance with\n * the License. You may obtain a copy of the License at\n * http://www.mozilla.org/MPL/\n *\n * Software distributed under the License is distributed on an \"AS IS\" basis,\n * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License\n * for the specific language governing rights and limitations under the\n * License.\n *\n * The Original Code is TurboPower Abbrevia\n *\n * The Initial Developer of the Original Code is\n * TurboPower Software\n *\n * Portions created by the Initial Developer are Copyright (C) 1997-2002\n * the Initial Developer. All Rights Reserved.\n *\n * Contributor(s):\n *\n * ***** END LICENSE BLOCK ***** *)\n\n{*********************************************************}\n{* ABBREVIA: EXTCAB.PAS                                  *}\n{* Copyright (c) TurboPower Software Co 1997             *}\n{* All rights reserved.                                  *}\n{*********************************************************}\n{* ABBREVIA Example program file                         *}\n{*********************************************************}\n\nunit CabExt1;\n\ninterface\n\nuses\n  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls,\n\n  AbArcTyp, AbCBrows, ComCtrls, AbCabExt, AbCabTyp, AbBase, AbBrowse, AbMeter, AbUtils;\n\ntype\n  TForm1 = class(TForm)\n    Button1: TButton;\n    OpenDialog1: TOpenDialog;\n    Memo1: TMemo;\n    Label1: TLabel;\n    Button2: TButton;\n    AbMeter1: TAbMeter;\n    AbCabExtractor1: TAbCabExtractor;\n    procedure Button1Click(Sender: TObject);\n    procedure AbCabExtractor1ConfirmProcessItem(Sender: TObject;\n      Item: TAbArchiveItem; ProcessType: TAbProcessType;\n      var Confirm: Boolean);\n    procedure Button2Click(Sender: TObject);\n    procedure FormClose(Sender: TObject; var Action: TCloseAction);\n  private\n    { Private declarations }\n  public\n    { Public declarations }\n  end;\n\nvar\n  Form1: TForm1;\n\nimplementation\n\n{$R *.DFM}\n\nconst\n  MainCaption = 'Cabinet Extractor';\n\nvar\n  AbortFlag : Boolean;\n\nprocedure TForm1.Button1Click(Sender: TObject);\nbegin\n  if OpenDialog1.Execute then begin\n    with AbCabExtractor1 do begin\n      FileName := OpenDialog1.FileName;\n      BaseDirectory := ExtractFilePath(FileName);\n      Cursor := crHourglass;\n      try\n        ExtractFiles('*.*');\n      except  {swallow exception if aborted}\n      end;\n      Cursor := crDefault;\n    end;\n  end;\n  Caption := MainCaption;\n  AbortFlag := False;\nend;\n\nprocedure TForm1.AbCabExtractor1ConfirmProcessItem(Sender: TObject;\n  Item: TAbArchiveItem; ProcessType: TAbProcessType; var Confirm: Boolean);\nbegin\n  Caption := 'Extracting ' + Item.Filename;\n  Confirm := not AbortFlag;\nend;\n\nprocedure TForm1.Button2Click(Sender: TObject);\nbegin\n  AbortFlag := True;\nend;\n\nprocedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);\nbegin\n  AbCabExtractor1.FileName := '';\nend;\n\nend.\n"
  },
  {
    "path": "lib/abbrevia/examples/Delphi/CabFind.dpr",
    "content": "(* ***** BEGIN LICENSE BLOCK *****\n * Version: MPL 1.1\n *\n * The contents of this file are subject to the Mozilla Public License Version\n * 1.1 (the \"License\"); you may not use this file except in compliance with\n * the License. You may obtain a copy of the License at\n * http://www.mozilla.org/MPL/\n *\n * Software distributed under the License is distributed on an \"AS IS\" basis,\n * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License\n * for the specific language governing rights and limitations under the\n * License.\n *\n * The Original Code is TurboPower Abbrevia\n *\n * The Initial Developer of the Original Code is\n * TurboPower Software\n *\n * Portions created by the Initial Developer are Copyright (C) 1997-2002\n * the Initial Developer. All Rights Reserved.\n *\n * Contributor(s):\n *\n * ***** END LICENSE BLOCK ***** *)\n\n{*********************************************************}\n{* ABBREVIA: FINDER.DPR                                  *}\n{*********************************************************}\n{* ABBREVIA Example program file                         *}\n{*********************************************************}\n\nprogram CabFind;\n\nuses\n  Forms,\n  CabFind1 in 'CabFind1.pas' {Form1};\n\nbegin\n\n  Application.CreateForm(TForm1, Form1);\n  Application.Run;\nend.\n"
  },
  {
    "path": "lib/abbrevia/examples/Delphi/CabFind1.pas",
    "content": "(* ***** BEGIN LICENSE BLOCK *****\n * Version: MPL 1.1\n *\n * The contents of this file are subject to the Mozilla Public License Version\n * 1.1 (the \"License\"); you may not use this file except in compliance with\n * the License. You may obtain a copy of the License at\n * http://www.mozilla.org/MPL/\n *\n * Software distributed under the License is distributed on an \"AS IS\" basis,\n * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License\n * for the specific language governing rights and limitations under the\n * License.\n *\n * The Original Code is TurboPower Abbrevia\n *\n * The Initial Developer of the Original Code is\n * TurboPower Software\n *\n * Portions created by the Initial Developer are Copyright (C) 1997-2002\n * the Initial Developer. All Rights Reserved.\n *\n * Contributor(s):\n *\n * ***** END LICENSE BLOCK ***** *)\n\n{*********************************************************}\n{* ABBREVIA: CABFIND1.PAS                                *}\n{* Copyright (c) TurboPower Software Co 1997             *}\n{* All rights reserved.                                  *}\n{*********************************************************}\n{* ABBREVIA Example program file                         *}\n{*********************************************************}\n\nunit CabFind1;\n\ninterface\n\nuses\n  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,\n  StdCtrls, FileCtrl, Buttons, ExtCtrls,\n\n  AbArcTyp, AbBrowse, AbCBrows, AbBase;\n\ntype\n  TForm1 = class(TForm)\n    Edit1: TEdit;\n    Label1: TLabel;\n    Memo1: TMemo;\n    DriveComboBox1: TDriveComboBox;\n    DirectoryListBox1: TDirectoryListBox;\n    FileListBox1: TFileListBox;\n    Memo2: TMemo;\n    Label2: TLabel;\n    AbCabBrowser1: TAbCabBrowser;\n    Button1: TButton;\n    Button2: TButton;\n    procedure FormClose(Sender: TObject; var Action: TCloseAction);\n    procedure Edit1Change(Sender: TObject);\n    procedure Button1Click(Sender: TObject);\n    procedure Button2Click(Sender: TObject);\n  private\n    { Private declarations }\n    Aborted: Boolean;\n  public\n    { Public declarations }\n  end;\n\nvar\n  Form1: TForm1;\n\nimplementation\n\n{$R *.DFM}\n\nprocedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);\nbegin\n  Aborted := True;\nend;\n\nprocedure TForm1.Edit1Change(Sender: TObject);\nbegin\n  Button1.Enabled := Length( Edit1.Text ) > 0;\nend;\n\nprocedure TForm1.Button1Click(Sender: TObject);\nvar\n  i : Integer;\n  CurFile : string;\nbegin\n  Button1.Enabled := False;\n  Memo1.Clear;\n  try\n    Button2.Enabled := True;\n    Aborted := False;\n    {look in the file list box for the file}\n    for i := 0 to pred( FileListBox1.Items.Count ) do begin\n      Application.ProcessMessages;\n      if Aborted then\n        break;\n      if CompareText( Edit1.Text, FileListBox1.Items[i] ) = 0 then begin\n        Memo1.Lines.Add( 'Found in ' + FileListBox1.Directory );\n        break;\n      end;\n      {now add search of zip and self extracting files}\n      CurFile := UpperCase( FileListBox1.Items[i] );\n      if ( Pos( '.CAB', CurFile ) > 0 ) then begin\n        try\n          AbCabBrowser1.FileName := FileListBox1.Items[i];\n          if AbCabBrowser1.FindFile(Edit1.Text) >= 0 then\n            Memo1.Lines.Add( 'Found in ' + FileListBox1.Items[i] );\n        except\n        end;\n      end;\n    end;\n  finally\n    Memo1.Lines.Add( 'Done!' );\n    Edit1.Enabled := True;\n    Button1.Enabled := True;\n    Button2.Enabled := False;\n  end;\nend;\n\nprocedure TForm1.Button2Click(Sender: TObject);\nbegin\n  Aborted := True;\nend;\n\nend.\n"
  },
  {
    "path": "lib/abbrevia/examples/Delphi/CabView.dpr",
    "content": "(* ***** BEGIN LICENSE BLOCK *****\n * Version: MPL 1.1\n *\n * The contents of this file are subject to the Mozilla Public License Version\n * 1.1 (the \"License\"); you may not use this file except in compliance with\n * the License. You may obtain a copy of the License at\n * http://www.mozilla.org/MPL/\n *\n * Software distributed under the License is distributed on an \"AS IS\" basis,\n * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License\n * for the specific language governing rights and limitations under the\n * License.\n *\n * The Original Code is TurboPower Abbrevia\n *\n * The Initial Developer of the Original Code is\n * TurboPower Software\n *\n * Portions created by the Initial Developer are Copyright (C) 1997-2002\n * the Initial Developer. All Rights Reserved.\n *\n * Contributor(s):\n *\n * ***** END LICENSE BLOCK ***** *)\n\nprogram CabView;\n\nuses\n  Forms,\n  CabView1 in 'CabView1.PAS' {Form1};\n\nbegin\n  Application.Initialize;\n  Application.CreateForm(TForm1, Form1);\n  Application.Run;\nend.\n"
  },
  {
    "path": "lib/abbrevia/examples/Delphi/CabView1.pas",
    "content": "(* ***** BEGIN LICENSE BLOCK *****\n * Version: MPL 1.1\n *\n * The contents of this file are subject to the Mozilla Public License Version\n * 1.1 (the \"License\"); you may not use this file except in compliance with\n * the License. You may obtain a copy of the License at\n * http://www.mozilla.org/MPL/\n *\n * Software distributed under the License is distributed on an \"AS IS\" basis,\n * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License\n * for the specific language governing rights and limitations under the\n * License.\n *\n * The Original Code is TurboPower Abbrevia\n *\n * The Initial Developer of the Original Code is\n * TurboPower Software\n *\n * Portions created by the Initial Developer are Copyright (C) 1997-2002\n * the Initial Developer. All Rights Reserved.\n *\n * Contributor(s):\n *\n * ***** END LICENSE BLOCK ***** *)\n\n{*********************************************************}\n{* ABBREVIA: CABVIEW1.PAS                                *}\n{* Copyright (c) TurboPower Software Co 1997             *}\n{* All rights reserved.                                  *}\n{*********************************************************}\n{* ABBREVIA Example program file                         *}\n{*********************************************************}\n\nunit CabView1;\n\ninterface\n\nuses\n  SysUtils, WinTypes, WinProcs, Messages, Classes, Graphics, Controls,\n  Forms, Dialogs, Grids, StdCtrls, ExtCtrls, Menus, FileCtrl,\n\n  AbArcTyp, AbCabTyp, AbMeter, AbDlgDir, AbView, AbCView, AbCBrows,\n  AbBrowse, AbCabMak, AbCabKit, AbBase, AbUtils;\n\ntype\n  TForm1 = class(TForm)\n    OpenDialog1: TOpenDialog;\n    Panel1: TPanel;\n    FontDialog1: TFontDialog;\n    MainMenu1: TMainMenu;\n    File1: TMenuItem;\n    Open1: TMenuItem;\n    Close1: TMenuItem;\n    N1: TMenuItem;\n    Print1: TMenuItem;\n    Exit1: TMenuItem;\n    ColorDialog1: TColorDialog;\n    CabView1: TMenuItem;\n    Attributes1: TMenuItem;\n    Itemname1: TMenuItem;\n    Packed1: TMenuItem;\n    Method1: TMenuItem;\n    Ratio1: TMenuItem;\n    CRC1: TMenuItem;\n    Fileattributes1: TMenuItem;\n    Filetype1: TMenuItem;\n    Encryption1: TMenuItem;\n    Timestamp1: TMenuItem;\n    Filesize1: TMenuItem;\n    Versionmade1: TMenuItem;\n    Versionneeded1: TMenuItem;\n    Path1: TMenuItem;\n    Display1: TMenuItem;\n    Columnlines1: TMenuItem;\n    Columnmoving1: TMenuItem;\n    Columnresizing1: TMenuItem;\n    MultiSelect1: TMenuItem;\n    Rowlines1: TMenuItem;\n    Thumbtracking1: TMenuItem;\n    Trackactiverow1: TMenuItem;\n    Sort1: TMenuItem;\n    Itemname2: TMenuItem;\n    Packed2: TMenuItem;\n    Ratio2: TMenuItem;\n    Timestamp2: TMenuItem;\n    Filesize2: TMenuItem;\n    Select1: TMenuItem;\n    SelectAll1: TMenuItem;\n    ClearSelections1: TMenuItem;\n    Rows1: TMenuItem;\n    Rowheight1: TMenuItem;\n    Headerheight1: TMenuItem;\n    Font1: TMenuItem;\n    Alternatecolors1: TMenuItem;\n    Action1: TMenuItem;\n    Extract1: TMenuItem;\n    ShowIcons1: TMenuItem;\n    Colors1: TMenuItem;\n    Selectedcolor: TMenuItem;\n    Selectedtextcolor: TMenuItem;\n    Alternatecolor1: TMenuItem;\n    Alternatetextcolor1: TMenuItem;\n    Panel2: TPanel;\n    AbMeter1: TAbMeter;\n    Label1: TLabel;\n    Label2: TLabel;\n    PopupMenu1: TPopupMenu;\n    Extract2: TMenuItem;\n    AbMeter2: TAbMeter;\n    AbCabView1: TAbCabView;\n    Extractoptions1: TMenuItem;\n    CreateDirs1: TMenuItem;\n    RestorePath1: TMenuItem;\n    AbCabKit1: TAbCabKit;\n    Additems1: TMenuItem;\n    procedure AbCabView1Click(Sender: TObject);\n    procedure AttributeClick(Sender: TObject);\n    procedure DisplayOptionClick(Sender: TObject);\n    procedure SortAttributeClick(Sender: TObject);\n    procedure SetAttribute(Attr : TAbViewAttribute; Value : Boolean);\n    procedure SetDisplayOption(Option : TAbDisplayOption; Value : Boolean);\n    procedure SetExtractOption(Option : TAbExtractOption; Value : Boolean);\n    procedure SetSortAttribute(Option : TAbSortAttribute; Value : Boolean);\n    procedure Open1Click(Sender: TObject);\n    procedure Close1Click(Sender: TObject);\n    procedure SelectAll1Click(Sender: TObject);\n    procedure ClearSelections1Click(Sender: TObject);\n    procedure Font1Click(Sender: TObject);\n    procedure Exit1Click(Sender: TObject);\n    procedure ExtractOptionClick(Sender: TObject);\n    procedure FormCreate(Sender: TObject);\n    procedure Selected1Click(Sender: TObject);\n    procedure Selectedtext1Click(Sender: TObject);\n    procedure Rowheight1Click(Sender: TObject);\n    procedure Headerheight1Click(Sender: TObject);\n    procedure Extract1Click(Sender: TObject);\n    procedure AbCabKit1ConfirmProcessItem(Sender: TObject;\n      Item: TAbArchiveItem; ProcessType: TAbProcessType;\n      var Confirm: Boolean);\n    procedure AbCabView1Change(Sender: TObject);\n    procedure Alternatecolor1Click(Sender: TObject);\n    procedure Alternatetextcolor1Click(Sender: TObject);\n    procedure AbCabKit1Save(Sender: TObject);\n    procedure Additems1Click(Sender: TObject);\n  private\n    { Private declarations }\n  public\n    { Public declarations }\n  end;\n\nvar\n  Form1: TForm1;\n\nimplementation\n\n{$R *.DFM}\n\nconst\n  MainCaption = ' TAbCabView example';\n\n\n{ -------------------------------------------------------------------------- }\nprocedure TForm1.SetAttribute(Attr : TAbViewAttribute; Value : Boolean);\n  procedure SetMenu(Item : TMenuItem);\n  begin\n    Item.Checked := Value;\n    if Item.Checked then\n      AbCabView1.Attributes := AbCabView1.Attributes + [Attr]\n    else\n      AbCabView1.Attributes := AbCabView1.Attributes - [Attr];\n  end;\nbegin\n  case Attr of\n    vaItemName       : SetMenu(ItemName1);\n    vaPacked         : SetMenu(Packed1);\n    vaMethod         : SetMenu(Method1);\n    vaRatio          : SetMenu(Ratio1);\n    vaCRC            : SetMenu(CRC1);\n    vaFileAttributes : SetMenu(FileAttributes1);\n    vaFileType       : SetMenu(FileType1);\n    vaEncryption     : SetMenu(Encryption1);\n    vaTimeStamp      : SetMenu(TimeStamp1);\n    vaFileSize       : SetMenu(FileSize1);\n    vaVersionMade    : SetMenu(VersionMade1);\n    vaVersionNeeded  : SetMenu(VersionNeeded1);\n    vaPath           : SetMenu(Path1);\n  end;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TForm1.SetDisplayOption(Option : TAbDisplayOption; Value : Boolean);\n  procedure SetMenu(Item : TMenuItem);\n  begin\n    Item.Checked := Value;\n    if Item.Checked then\n      AbCabView1.DisplayOptions := AbCabView1.DisplayOptions + [Option]\n    else\n      AbCabView1.DisplayOptions := AbCabView1.DisplayOptions - [Option]\n  end;\nbegin\n  case Option of\n    doAlternateColors : SetMenu(AlternateColors1);\n    doColLines        : SetMenu(ColumnLines1);\n    doColMove         : SetMenu(ColumnMoving1);\n    doColSizing       : SetMenu(ColumnResizing1);\n    doMultiSelect     : SetMenu(MultiSelect1);\n    doRowLines        : SetMenu(RowLines1);\n    doShowIcons       : SetMenu(ShowIcons1);\n    doThumbTrack      : SetMenu(ThumbTracking1);\n    doTrackActiveRow  : SetMenu(TrackActiveRow1);\n  end;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TForm1.SetExtractOption(Option : TAbExtractOption; Value : Boolean);\n  procedure SetMenu(Item : TMenuItem);\n  begin\n    Item.Checked := Value;\n    if Item.Checked then\n      AbCabKit1.ExtractOptions := AbCabKit1.ExtractOptions + [Option]\n    else\n      AbCabKit1.ExtractOptions := AbCabKit1.ExtractOptions - [Option]\n  end;\nbegin\n  case Option of\n    eoCreateDirs : SetMenu(CreateDirs1);\n    eoRestorePath : SetMenu(RestorePath1);\n  end;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TForm1.SetSortAttribute(Option : TAbSortAttribute; Value : Boolean);\n  procedure SetMenu(Item : TMenuItem);\n  begin\n    Item.Checked := Value;\n    if Item.Checked then\n      AbCabView1.SortAttributes := AbCabView1.SortAttributes + [Option]\n    else\n      AbCabView1.SortAttributes := AbCabView1.SortAttributes - [Option];\n  end;\nbegin\n  case Option of\n    saItemName  : SetMenu(ItemName2);\n    saPacked    : SetMenu(Packed2);\n    saRatio     : SetMenu(Ratio2);\n    saTimeStamp : SetMenu(TimeStamp2);\n    saFileSize  : SetMenu(FileSize2);\n  end;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TForm1.AbCabView1Click(Sender: TObject);\nbegin\n  Panel1.Caption := AbCabView1.Items[AbCabView1.ActiveRow].Filename;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TForm1.Open1Click(Sender: TObject);\nbegin\n  OpenDialog1.Filename := '*.cab';\n  if OpenDialog1.Execute then begin\n    AbCabKit1.Filename := OpenDialog1.Filename;\n{    AbCabKit1.BaseDirectory := ExtractFilePath(AbCabKit1.Filename);}\n    Caption := AbCabKit1.Filename +\n      '   ' + IntToStr(AbCabView1.Count) + ' items';\n    Action1.Enabled := True;\n  end;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TForm1.Close1Click(Sender: TObject);\nbegin\n  AbCabKit1.Filename := '';\n  Caption := MainCaption;\n  Panel1.Caption := '';\n  Action1.Enabled := False;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TForm1.AttributeClick(Sender: TObject);\nbegin\n  with TMenuItem(Sender) do\n    SetAttribute(TAbViewAttribute(Tag), not Checked);\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TForm1.DisplayOptionClick(Sender: TObject);\nbegin\n  with TMenuItem(Sender) do\n    SetDisplayOption(TAbDisplayOption(Tag), not Checked);\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TForm1.SortAttributeClick(Sender: TObject);\nbegin\n  with TMenuItem(Sender) do\n    SetSortAttribute(TAbSortAttribute(Tag), not Checked);\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TForm1.SelectAll1Click(Sender: TObject);\nbegin\n  AbCabView1.SelectAll;\n  AbCabView1Click(nil);\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TForm1.ClearSelections1Click(Sender: TObject);\nbegin\n  AbCabView1.ClearSelections;\n  AbCabView1Click(nil);\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TForm1.ExtractOptionClick(Sender: TObject);\nbegin\n  with TMenuItem(Sender) do\n    SetExtractOption(TAbExtractOption(Tag), not Checked);\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TForm1.Font1Click(Sender: TObject);\nbegin\n  FontDialog1.Font := AbCabView1.Font;\n  if FontDialog1.Execute then\n    AbCabView1.Font := FontDialog1.Font;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TForm1.Exit1Click(Sender: TObject);\nbegin\n  Close;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TForm1.FormCreate(Sender: TObject);\nvar\n  i : TAbViewAttribute;\n  j : TAbDisplayOption;\n  k : TAbSortAttribute;\n  m : TAbExtractOption;\nbegin\n  for i := Low(TAbViewAttribute) to High(TAbViewAttribute) do\n    SetAttribute(i, i in AbCabView1.Attributes);\n  for j := Low(TAbDisplayOption) to High(TAbDisplayOption) do\n    SetDisplayOption(j, j in AbCabView1.DisplayOptions);\n  for k := Low(TAbSortAttribute) to High(TAbSortAttribute) do\n    SetSortAttribute(k, k in AbCabView1.SortAttributes);\n  for m := Low(TAbExtractOption) to High(TAbExtractOption) do\n    SetExtractOption(m, m in AbCabKit1.ExtractOptions);\n  Caption := MainCaption;\n  Action1.Enabled := AbCabKit1.FileName <> '';\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TForm1.Selected1Click(Sender: TObject);\nbegin\n  if ColorDialog1.Execute then\n    AbCabView1.Colors.Selected := ColorDialog1.Color;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TForm1.Selectedtext1Click(Sender: TObject);\nbegin\n  if ColorDialog1.Execute then\n    AbCabView1.Colors.SelectedText := ColorDialog1.Color;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TForm1.Rowheight1Click(Sender: TObject);\nvar\n  s : string;\nbegin\n  s := IntToStr(AbCabView1.DefaultRowHeight);\n  if InputQuery(MainCaption, 'Row Height', s) then\n    AbCabView1.DefaultRowHeight := StrToIntDef(s, 18);\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TForm1.Headerheight1Click(Sender: TObject);\nvar\n  s : string;\nbegin\n  s := IntToStr(AbCabView1.HeaderRowHeight);\n  if InputQuery(MainCaption, 'Header Height', s) then\n    AbCabView1.HeaderRowHeight := StrToIntDef(s, 18);\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TForm1.Extract1Click(Sender: TObject);\nvar\n  i : Longint;\n  Continue : Boolean;\nbegin\n  with TAbDirDlg.Create(Self) do begin\n    Caption := 'Directory';\n    AdditionalText := 'Select folder to extract into';\n    Continue := Execute;\n    if Continue then\n      AbCabKit1.BaseDirectory := SelectedFolder;\n    Free;\n  end;\n  if not Continue then\n    Exit;\n  Panel1.Caption := '';\n  with AbCabView1 do\n    for i := 0 to Pred(Count) do\n      Items[i].Tagged := Selected[i];\n  AbCabKit1.ExtractTaggedItems;\n  AbCabView1.ClearSelections;\n  Panel1.Caption := '';\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TForm1.AbCabKit1ConfirmProcessItem(Sender: TObject;\n  Item: TAbArchiveItem; ProcessType: TAbProcessType; var Confirm: Boolean);\nvar\n  s : string;\nbegin\n  if (ProcessType = ptExtract) then\n    s := 'Extracting '\n  else\n    s := '??? ';\n  Panel1.Caption := s + Item.Filename;\n  Confirm := True;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TForm1.AbCabView1Change(Sender: TObject);\nbegin\n    Caption := AbCabKit1.Filename +\n      '   ' + IntToStr(AbCabView1.Count) + ' items';\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TForm1.Alternatecolor1Click(Sender: TObject);\nbegin\n  if ColorDialog1.Execute then\n    AbCabView1.Colors.Alternate := ColorDialog1.Color;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TForm1.Alternatetextcolor1Click(Sender: TObject);\nbegin\n  if ColorDialog1.Execute then\n    AbCabView1.Colors.AlternateText := ColorDialog1.Color;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TForm1.AbCabKit1Save(Sender: TObject);\nbegin\n  Panel1.Caption := 'Saving ' + AbCabKit1.Filename;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TForm1.Additems1Click(Sender: TObject);\nvar\n  i : Integer;\nbegin\n  with OpenDialog1 do begin\n    FileName := '*.*';\n    Title := 'Select files to add';\n    if Execute then\n      if (Files.Count > 0) then\n        for i := 0 to Pred(Files.Count) do\n          AbCabKit1.AddFiles(Files[i], 0);\n  end;\nend;\n\nend.\n"
  },
  {
    "path": "lib/abbrevia/examples/Delphi/ComCtrlsDemo.dpr",
    "content": "program ComCtrlsDemo;\n\nuses\n  Forms,\n  ComCtrlsMain in 'ComCtrlsMain.pas' {frmComCtrls};\n\n{$R *.res}\n\nbegin\n  Application.Initialize;\n  Application.MainFormOnTaskbar := True;\n  Application.CreateForm(TfrmComCtrls, frmComCtrls);\n  Application.Run;\nend.\n"
  },
  {
    "path": "lib/abbrevia/examples/Delphi/ComCtrlsMain.dfm",
    "content": "object frmComCtrls: TfrmComCtrls\n  Left = 0\n  Top = 0\n  Caption = 'AbComCtrls Example'\n  ClientHeight = 524\n  ClientWidth = 699\n  Color = clBtnFace\n  Font.Charset = DEFAULT_CHARSET\n  Font.Color = clWindowText\n  Font.Height = -11\n  Font.Name = 'Tahoma'\n  Font.Style = []\n  Menu = MainMenu\n  OldCreateOrder = False\n  PixelsPerInch = 96\n  TextHeight = 13\n  object Splitter1: TSplitter\n    Left = 153\n    Top = 0\n    Height = 524\n    ExplicitLeft = 360\n    ExplicitTop = 240\n    ExplicitHeight = 100\n  end\n  object AbTreeView: TAbTreeView\n    Left = 0\n    Top = 0\n    Width = 153\n    Height = 524\n    Align = alLeft\n    Indent = 19\n    TabOrder = 0\n    Items.NodeData = {\n      0301000000200000000000000000000000FFFFFFFFFFFFFFFF00000000000000\n      000000000001015C00}\n    Archive = AbUnZipper\n    ListView = AbListView\n  end\n  object Panel1: TPanel\n    Left = 156\n    Top = 0\n    Width = 543\n    Height = 524\n    Align = alClient\n    Caption = 'Panel1'\n    TabOrder = 1\n    ExplicitLeft = 264\n    ExplicitTop = 272\n    ExplicitWidth = 185\n    ExplicitHeight = 41\n    object Splitter2: TSplitter\n      Left = 1\n      Top = 335\n      Width = 541\n      Height = 3\n      Cursor = crVSplit\n      Align = alBottom\n      ExplicitLeft = 539\n      ExplicitTop = 1\n      ExplicitWidth = 337\n    end\n    object Memo1: TMemo\n      Left = 1\n      Top = 338\n      Width = 541\n      Height = 185\n      Align = alBottom\n      Lines.Strings = (\n        'Memo1')\n      TabOrder = 0\n      ExplicitLeft = 354\n      ExplicitTop = 1\n      ExplicitWidth = 522\n    end\n    object AbListView: TAbListView\n      Left = 1\n      Top = 1\n      Width = 541\n      Height = 334\n      Align = alClient\n      Archive = AbUnZipper\n      TabOrder = 1\n      TreeView = AbTreeView\n      OnSelectItem = ListViewSelectItem\n      ExplicitLeft = 328\n      ExplicitTop = 112\n      ExplicitWidth = 250\n      ExplicitHeight = 150\n    end\n  end\n  object AbUnZipper: TAbUnZipper\n    Left = 96\n    Top = 24\n  end\n  object MainMenu: TMainMenu\n    Left = 16\n    Top = 24\n    object mnuFile: TMenuItem\n      Caption = 'File'\n      object mnuOpenArchive: TMenuItem\n        Caption = 'Open...'\n        OnClick = OpenArchiveClick\n      end\n    end\n    object mnuView: TMenuItem\n      Caption = 'View'\n      object mnuAllFiles: TMenuItem\n        AutoCheck = True\n        Caption = 'All Files (WinZip Style)'\n        GroupIndex = 1\n        RadioItem = True\n        OnClick = FolderStyleClick\n      end\n      object mnuFilesByFolder: TMenuItem\n        AutoCheck = True\n        Caption = 'Files By Folder (Explorer Style)'\n        Checked = True\n        GroupIndex = 1\n        RadioItem = True\n        OnClick = FolderStyleClick\n      end\n      object N1: TMenuItem\n        Caption = '-'\n        GroupIndex = 1\n      end\n      object mnuIcons: TMenuItem\n        AutoCheck = True\n        Caption = 'Icons'\n        Checked = True\n        GroupIndex = 2\n        RadioItem = True\n        OnClick = ViewStyleClick\n      end\n      object mnuList: TMenuItem\n        AutoCheck = True\n        Caption = 'List'\n        GroupIndex = 2\n        RadioItem = True\n        OnClick = ViewStyleClick\n      end\n      object mnuDetails: TMenuItem\n        AutoCheck = True\n        Caption = 'Details'\n        GroupIndex = 2\n        RadioItem = True\n        OnClick = ViewStyleClick\n      end\n    end\n  end\n  object OpenDialog: TOpenDialog\n    Filter = 'Archive Files|*.zip;*.tar;*.gz;*.tgz;*.bz2;*.tbz'\n    Options = [ofEnableSizing]\n    Left = 56\n    Top = 24\n  end\nend\n"
  },
  {
    "path": "lib/abbrevia/examples/Delphi/ComCtrlsMain.pas",
    "content": "(* ***** BEGIN LICENSE BLOCK *****\n * Version: MPL 1.1\n *\n * The contents of this file are subject to the Mozilla Public License Version\n * 1.1 (the \"License\"); you may not use this file except in compliance with\n * the License. You may obtain a copy of the License at\n * http://www.mozilla.org/MPL/\n *\n * Software distributed under the License is distributed on an \"AS IS\" basis,\n * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License\n * for the specific language governing rights and limitations under the\n * License.\n *\n * The Original Code is TurboPower Abbrevia\n *\n * The Initial Developer of the Original Code is\n * Craig Peterson <capeterson@users.sourceforge.net>\n *\n * Portions created by the Initial Developer are Copyright (C) 2011\n * the Initial Developer. All Rights Reserved.\n *\n * Contributor(s):\n *\n * ***** END LICENSE BLOCK ***** *)\n\n{*********************************************************}\n{* This demonstrates the TAbTreeView and TAbListView     *}\n{* components.  By setting references to each other and  *}\n{* a shared TAbBaseBrowser descendant (e.g., TAbZipKit   *}\n{* you can have a WinZip/Explorer-like interface without *}\n{* any code.                                             *}\n{*********************************************************}\n\nunit ComCtrlsMain;\n\ninterface\n\nuses\n  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,\n  Dialogs, StdCtrls, ExtCtrls, Menus, ComCtrls, AbComCtrls, AbBase, AbBrowse,\n  AbZBrows, AbUnzper;\n\ntype\n  TfrmComCtrls = class(TForm)\n    AbUnZipper: TAbUnZipper;\n    AbTreeView: TAbTreeView;\n    AbListView: TAbListView;\n    MainMenu: TMainMenu;\n    mnuFile: TMenuItem;\n    mnuOpenArchive: TMenuItem;\n    Splitter1: TSplitter;\n    Splitter2: TSplitter;\n    Memo1: TMemo;\n    OpenDialog: TOpenDialog;\n    mnuView: TMenuItem;\n    mnuAllFiles: TMenuItem;\n    mnuFilesByFolder: TMenuItem;\n    N1: TMenuItem;\n    mnuIcons: TMenuItem;\n    mnuList: TMenuItem;\n    mnuDetails: TMenuItem;\n    Panel1: TPanel;\n\tprocedure FolderStyleClick(Sender: TObject);\n\tprocedure ListViewSelectItem(Sender: TObject; Item: TListItem;\n\t  Selected: Boolean);\n\tprocedure OpenArchiveClick(Sender: TObject);\n\tprocedure ViewStyleClick(Sender: TObject);\n  private\n    { Private declarations }\n  public\n    { Public declarations }\n  end;\n\nvar\n  frmComCtrls: TfrmComCtrls;\n\nimplementation\n\n{$R *.dfm}\n\nprocedure TfrmComCtrls.FolderStyleClick(Sender: TObject);\nbegin\n  AbTreeView.Visible := mnuFilesByFolder.Checked;\n  Splitter1.Visible := mnuFilesByFolder.Checked;\n  AbListView.FlatList := mnuAllFiles.Checked;\nend;\n\nprocedure TfrmComCtrls.ListViewSelectItem(Sender: TObject; Item: TListItem;\n  Selected: Boolean);\nvar\n  Stream: TMemoryStream;\nbegin\n  if TAbListItem(Item).IsDirectory then\n\tMemo1.Clear\n  else begin\n\tStream := TMemoryStream.Create;\n\ttry\n\t  AbUnZipper.ExtractToStream(TAbListItem(Item).ArchiveItem.FileName, Stream);\n\t  Stream.Position := 0;\n\t  Memo1.Lines.LoadFromStream(Stream);\n\tfinally\n\t  Stream.Free;\n\tend;\n  end;\nend;\n\nprocedure TfrmComCtrls.OpenArchiveClick(Sender: TObject);\nbegin\n  if OpenDialog.Execute then\n\tAbUnZipper.FileName := OpenDialog.FileName;\nend;\n\nprocedure TfrmComCtrls.ViewStyleClick(Sender: TObject);\nbegin\n  if mnuIcons.Checked then\n\tAbListView.ViewStyle := vsIcon\n  else if mnuList.Checked then\n\tAbListView.ViewStyle := vsList\n  else\n\tAbListView.ViewStyle := vsReport;\nend;\n\nend.\n"
  },
  {
    "path": "lib/abbrevia/examples/Delphi/CompPad.dpr",
    "content": "(* ***** BEGIN LICENSE BLOCK *****\n * Version: MPL 1.1\n *\n * The contents of this file are subject to the Mozilla Public License Version\n * 1.1 (the \"License\"); you may not use this file except in compliance with\n * the License. You may obtain a copy of the License at\n * http://www.mozilla.org/MPL/\n *\n * Software distributed under the License is distributed on an \"AS IS\" basis,\n * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License\n * for the specific language governing rights and limitations under the\n * License.\n *\n * The Original Code is TurboPower Abbrevia\n *\n * The Initial Developer of the Original Code is\n * TurboPower Software\n *\n * Portions created by the Initial Developer are Copyright (C) 1997-2002\n * the Initial Developer. All Rights Reserved.\n *\n * Contributor(s):\n *\n * ***** END LICENSE BLOCK ***** *)\n\n{*********************************************************}\n{* ABBREVIA: COMPPAD.DPR                                 *}\n{*********************************************************}\n{* ABBREVIA Example program file                         *}\n{*********************************************************}\n\nprogram CompPad;\n\nuses\n  Forms,\n  ucomppad in 'UCOMPPAD.PAS' {Form1};\n\nbegin\n  Application.Initialize;\n  Application.CreateForm(TForm1, Form1);\n  Application.Run;\nend.\n"
  },
  {
    "path": "lib/abbrevia/examples/Delphi/Contents.dpr",
    "content": "(* ***** BEGIN LICENSE BLOCK *****\n * Version: MPL 1.1\n *\n * The contents of this file are subject to the Mozilla Public License Version\n * 1.1 (the \"License\"); you may not use this file except in compliance with\n * the License. You may obtain a copy of the License at\n * http://www.mozilla.org/MPL/\n *\n * Software distributed under the License is distributed on an \"AS IS\" basis,\n * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License\n * for the specific language governing rights and limitations under the\n * License.\n *\n * The Original Code is TurboPower Abbrevia\n *\n * The Initial Developer of the Original Code is\n * TurboPower Software\n *\n * Portions created by the Initial Developer are Copyright (C) 1997-2002\n * the Initial Developer. All Rights Reserved.\n *\n * Contributor(s):\n *\n * ***** END LICENSE BLOCK ***** *)\n\n{*********************************************************}\n{* ABBREVIA: CONTENTS.DPR                                *}\n{*********************************************************}\n{* ABBREVIA Example program file                         *}\n{*********************************************************}\n\nprogram Contents;\n\nuses\n  Forms,\n  UContent in 'UCONTENT.PAS' {Form1};\n\nbegin\n  Application.CreateForm(TForm1, Form1);\n  Application.Run;\nend.\n"
  },
  {
    "path": "lib/abbrevia/examples/Delphi/ExCBrows.dpr",
    "content": "(* ***** BEGIN LICENSE BLOCK *****\n * Version: MPL 1.1\n *\n * The contents of this file are subject to the Mozilla Public License Version\n * 1.1 (the \"License\"); you may not use this file except in compliance with\n * the License. You may obtain a copy of the License at\n * http://www.mozilla.org/MPL/\n *\n * Software distributed under the License is distributed on an \"AS IS\" basis,\n * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License\n * for the specific language governing rights and limitations under the\n * License.\n *\n * The Original Code is TurboPower Abbrevia\n *\n * The Initial Developer of the Original Code is\n * TurboPower Software\n *\n * Portions created by the Initial Developer are Copyright (C) 1997-2002\n * the Initial Developer. All Rights Reserved.\n *\n * Contributor(s):\n *\n * ***** END LICENSE BLOCK ***** *)\n\n{*********************************************************}\n{* ABBREVIA: CONTENTS.DPR                                *}\n{*********************************************************}\n{* ABBREVIA Example program file                         *}\n{*********************************************************}\n\nprogram ExCBrows;\n\nuses\n  Forms,\n  ExCBrowu in 'ExCBrowu.pas' {Form1};\n\nbegin\n  Application.CreateForm(TForm1, Form1);\n  Application.Run;\nend.\n"
  },
  {
    "path": "lib/abbrevia/examples/Delphi/ExCBrowu.pas",
    "content": "(* ***** BEGIN LICENSE BLOCK *****\n * Version: MPL 1.1\n *\n * The contents of this file are subject to the Mozilla Public License Version\n * 1.1 (the \"License\"); you may not use this file except in compliance with\n * the License. You may obtain a copy of the License at\n * http://www.mozilla.org/MPL/\n *\n * Software distributed under the License is distributed on an \"AS IS\" basis,\n * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License\n * for the specific language governing rights and limitations under the\n * License.\n *\n * The Original Code is TurboPower Abbrevia\n *\n * The Initial Developer of the Original Code is\n * TurboPower Software\n *\n * Portions created by the Initial Developer are Copyright (C) 1997-2002\n * the Initial Developer. All Rights Reserved.\n *\n * Contributor(s):\n *\n * ***** END LICENSE BLOCK ***** *)\n\n{*********************************************************}\n{* ABBREVIA: UCONTENT.PAS                                *}\n{* Copyright (c) TurboPower Software Co 1997             *}\n{* All rights reserved.                                  *}\n{*********************************************************}\n{* ABBREVIA Example program file                         *}\n{*********************************************************}\n\nunit ExCBrowu;\n\ninterface\n\nuses\n  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,\n  StdCtrls, ExtCtrls,\n\n  AbArcTyp, AbCBrows, AbMeter, AbBrowse, AbBase;\n\ntype\n  TForm1 = class(TForm)\n    OpenDialog1: TOpenDialog;\n    AbCabBrowser1: TAbCabBrowser;\n    Memo1: TMemo;\n    Panel1: TPanel;\n    Button1: TButton;\n    Button2: TButton;\n    Label1: TLabel;\n    Panel2: TPanel;\n    AbMeter1: TAbMeter;\n    AbMeter2: TAbMeter;\n    Label2: TLabel;\n    Label3: TLabel;\n    procedure Button1Click(Sender: TObject);\n    procedure Button2Click(Sender: TObject);\n    procedure AbCabBrowser1Load(Sender: TObject);\n  private\n    { Private declarations }\n  public\n    { Public declarations }\n  end;\n\nvar\n  Form1: TForm1;\n\nimplementation\n\n{$R *.DFM}\n\nconst\n  BoolToStr : array[Boolean] of string = ('No', 'Yes');\n\nprocedure TForm1.Button1Click(Sender: TObject);\nbegin\n  if OpenDialog1.Execute then\n    AbCabBrowser1.FileName := OpenDialog1.FileName;\nend;\n\nprocedure TForm1.Button2Click(Sender: TObject);\nbegin\n  AbCabBrowser1.Filename := '';\n  Memo1.Clear;\nend;\n\nprocedure TForm1.AbCabBrowser1Load(Sender: TObject);\nvar\n  i : Integer;\n  LI : Longint;\n  DT : TDateTime;\n  s : string;\nbegin\n  Memo1.Clear;\n  with AbCabBrowser1 do begin\n    Memo1.Lines.Add(Filename);\n    Memo1.Lines.Add('----------------------------------------------');\n    Memo1.Lines.Add('  Size: ' + #9 + #9 + IntToStr(CabSize));\n    Memo1.Lines.Add('  Folders: ' + #9 + #9 + IntToStr(FolderCount));\n    Memo1.Lines.Add('  Files: ' + #9 + #9 + IntToStr(Count));\n    Memo1.Lines.Add('  SetID: ' + #9 + #9 + IntToStr(SetID));\n    Memo1.Lines.Add('  Cab #: ' + #9 + #9 + IntToStr(CurrentCab));\n    Memo1.Lines.Add('  hasPrev: ' + #9 + BoolToStr[HasPrev]);\n    Memo1.Lines.Add('  hasNext: ' + #9 + BoolToStr[HasNext]);\n    Memo1.Lines.Add('  ');\n\n    if (Count > 0) then begin\n      Memo1.Lines.Add('Files' + #9 + #9 + 'Size' +\n        #9 + 'Timestamp' + #9 + #9 + 'Attributes' + #9 +'Partial File');\n      Memo1.Lines.Add('--------------------------------------------' +\n                      '--------------------------------------------' +\n                      '--------------------------------------------');\n      for i := 0 to Pred(Count) do begin\n        LI := LongInt(Items[i].LastModFileDate) shl 16 +\n          Items[i].LastModFileTime;\n        DT := FileDateToDateTime(LI);\n        s := Items[i].FileName + #9 +\n          IntToStr(Items[i].UnCompressedSize) + #9 +\n          DateTimeToStr(DT) + #9 +\n          IntToStr(Items[i].ExternalFileAttributes) + #9 +\n          BoolToStr[Items[i].PartialFile];\n        Memo1.Lines.Add(s);\n      end;\n    end;\n  end;\nend;\n\nend.\n"
  },
  {
    "path": "lib/abbrevia/examples/Delphi/ExCf.dpr",
    "content": "(* ***** BEGIN LICENSE BLOCK *****\n * Version: MPL 1.1\n *\n * The contents of this file are subject to the Mozilla Public License Version\n * 1.1 (the \"License\"); you may not use this file except in compliance with\n * the License. You may obtain a copy of the License at\n * http://www.mozilla.org/MPL/\n *\n * Software distributed under the License is distributed on an \"AS IS\" basis,\n * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License\n * for the specific language governing rights and limitations under the\n * License.\n *\n * The Original Code is TurboPower Abbrevia\n *\n * The Initial Developer of the Original Code is\n * TurboPower Software\n *\n * Portions created by the Initial Developer are Copyright (C) 1997-2002\n * the Initial Developer. All Rights Reserved.\n *\n * Contributor(s):\n *\n * ***** END LICENSE BLOCK ***** *)\n\nprogram ExCf;\n\nuses\n  Forms,\n  uCfMain in 'uCfMain.pas' {fmCfMain},\n  uCfGenDg in 'uCfGenDg.pas' {frmCfGenDlg},\n  uCfNewDg in 'uCfNewDg.pas' {frmCfNewDlg};\n\n{$R *.RES}\n\nbegin\n  Application.Initialize;\n  Application.CreateForm(TfmCfMain, fmCfMain);\n  Application.CreateForm(TfrmCfGenDlg, frmCfGenDlg);\n  Application.CreateForm(TfrmCfNewDlg, frmCfNewDlg);\n  Application.Run;\nend.\n"
  },
  {
    "path": "lib/abbrevia/examples/Delphi/ExFilter.dpr",
    "content": "(* ***** BEGIN LICENSE BLOCK *****\n * Version: MPL 1.1\n *\n * The contents of this file are subject to the Mozilla Public License Version\n * 1.1 (the \"License\"); you may not use this file except in compliance with\n * the License. You may obtain a copy of the License at\n * http://www.mozilla.org/MPL/\n *\n * Software distributed under the License is distributed on an \"AS IS\" basis,\n * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License\n * for the specific language governing rights and limitations under the\n * License.\n *\n * The Original Code is TurboPower Abbrevia\n *\n * The Initial Developer of the Original Code is\n * TurboPower Software\n *\n * Portions created by the Initial Developer are Copyright (C) 1997-2002\n * the Initial Developer. All Rights Reserved.\n *\n * Contributor(s):\n *\n * ***** END LICENSE BLOCK ***** *)\n\n{*********************************************************}\n{* ABBREVIA: EXFILTER.DPR                                *}\n{*********************************************************}\n{* ABBREVIA Example program file                         *}\n{*********************************************************}\n\nprogram Exfilter;\n\nuses\n  Forms,\n  Exfiltru in 'EXFILTRU.PAS' {Form1};\n\nbegin\n  Application.CreateForm(TForm1, Form1);\n  Application.Run;\nend.\n"
  },
  {
    "path": "lib/abbrevia/examples/Delphi/ExFiltru.pas",
    "content": "(* ***** BEGIN LICENSE BLOCK *****\n * Version: MPL 1.1\n *\n * The contents of this file are subject to the Mozilla Public License Version\n * 1.1 (the \"License\"); you may not use this file except in compliance with\n * the License. You may obtain a copy of the License at\n * http://www.mozilla.org/MPL/\n *\n * Software distributed under the License is distributed on an \"AS IS\" basis,\n * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License\n * for the specific language governing rights and limitations under the\n * License.\n *\n * The Original Code is TurboPower Abbrevia\n *\n * The Initial Developer of the Original Code is\n * TurboPower Software\n *\n * Portions created by the Initial Developer are Copyright (C) 1997-2002\n * the Initial Developer. All Rights Reserved.\n *\n * Contributor(s):\n *\n * ***** END LICENSE BLOCK ***** *)\n\n{*********************************************************}\n{* ABBREVIA: EXFILTRU.PAS                                *}\n{* Copyright (c) TurboPower Software Co 1997             *}\n{* All rights reserved.                                  *}\n{*********************************************************}\n{* ABBREVIA Example program file                         *}\n{*********************************************************}\n\nunit Exfiltru;\n\ninterface\n\nuses\n  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,\n  StdCtrls, Gauges, Grids, ExtCtrls, FileCtrl,\n\n  AbZipper, AbArcTyp, AbZBrows, AbMeter, AbZipKit, AbView, AbZView, AbBrowse,\n  AbBase, AbUtils;\ntype\n  TForm1 = class(TForm)\n    OpenDialog1: TOpenDialog;\n    OpenBtn: TButton;\n    AbZipView1: TAbZipView;\n    CloseBtn: TButton;\n    AddGroup: TGroupBox;\n    Label1: TLabel;\n    FileMask1: TEdit;\n    Label2: TLabel;\n    FilterMask1: TEdit;\n    AddBtn: TButton;\n    Label3: TLabel;\n    DirectoryListBox1: TDirectoryListBox;\n    Bevel1: TBevel;\n    Label4: TLabel;\n    DeleteGroup: TGroupBox;\n    Label5: TLabel;\n    FileMask2: TEdit;\n    Label6: TLabel;\n    FilterMask2: TEdit;\n    DeleteBtn: TButton;\n    Bevel2: TBevel;\n    AbortBtn: TButton;\n    ExitBtn: TButton;\n    ExtractGroup: TGroupBox;\n    Label7: TLabel;\n    Label8: TLabel;\n    Label9: TLabel;\n    Bevel3: TBevel;\n    FileMask3: TEdit;\n    FilterMask3: TEdit;\n    ExtractBtn: TButton;\n    DirectoryListBox2: TDirectoryListBox;\n    AbZipKit1: TAbZipKit;\n    AbMeter1: TAbMeter;\n    procedure AddBtnClick(Sender: TObject);\n    procedure OpenBtnClick(Sender: TObject);\n    procedure DeleteBtnClick(Sender: TObject);\n    procedure CloseBtnClick(Sender: TObject);\n    procedure AbortBtnClick(Sender: TObject);\n    procedure ExitBtnClick(Sender: TObject);\n    procedure FormCreate(Sender: TObject);\n    procedure ExtractBtnClick(Sender: TObject);\n    procedure AbZipKit1ConfirmProcessItem(Sender: TObject;\n      Item: TAbArchiveItem; ProcessType: TAbProcessType;\n      var Confirm: Boolean);\n  private\n    { Private declarations }\n  public\n    { Public declarations }\n  end;\n\nvar\n  Form1: TForm1;\n\nimplementation\n\n{$R *.DFM}\n\nconst\n  MainCaption = ' ExFilter : Exception list example';\n  AddCaption  = ' Add files to zip archive ';\n  DeleteCaption = ' Delete files from zip archive ';\n  ExtractCaption = ' Extract files from zip archive ';\n\nvar\n  AbortFlag : Boolean;\n\nprocedure TForm1.OpenBtnClick(Sender: TObject);\nbegin\n  AbZipKit1.Filename := '';\n  AddBtn.Enabled := False;\n  DeleteBtn.Enabled := False;\n  OpenDialog1.Filename := '*.zip';\n  if OpenDialog1.Execute then begin\n    AbZipKit1.Filename := OpenDialog1.Filename;\n    OpenBtn.Enabled := False;\n    CloseBtn.Enabled := True;\n    AddBtn.Enabled := True;\n    DeleteBtn.Enabled := True;\n    ExtractBtn.Enabled := True;\n    AbZipView1.Enabled := True;\n    Caption := ' ' + AbZipKit1.Filename;\n  end;\nend;\n\nprocedure TForm1.CloseBtnClick(Sender: TObject);\nbegin\n  Screen.Cursor := crHourglass;\n  Caption := 'Saving ' + AbZipKit1.Filename;\n  AbZipKit1.CloseArchive;\n  Screen.Cursor := crDefault;\n  OpenBtn.Enabled := True;\n  CloseBtn.Enabled := False;\n  AddBtn.Enabled := False;\n  DeleteBtn.Enabled := False;\n  ExtractBtn.Enabled := False;\n  AbZipView1.Enabled := False;\n  Caption := MainCaption;\nend;\n\nprocedure TForm1.AddBtnClick(Sender: TObject);\nvar\n  SavedColor : TColor;\nbegin\n  AbortFlag := False;\n  AbZipKit1.BaseDirectory := DirectoryListBox1.Directory;\n  SavedColor := AddGroup.Font.Color;\n  AddGroup.Font.Color := clRed;\n  try\n    AbZipKit1.AddFilesEx(FileMask1.Text, FilterMask1.Text, 0 );\n    AbZipKit1.Save;\n  finally\n    AddGroup.Font.Color := SavedColor;\n    AddGroup.Caption := AddCaption;\n  end;\nend;\n\nprocedure TForm1.DeleteBtnClick(Sender: TObject);\nvar\n  SavedColor : TColor;\nbegin\n  AbortFlag := False;\n  SavedColor := DeleteGroup.Font.Color;\n  DeleteGroup.Font.Color := clRed;\n  try\n    AbZipKit1.DeleteFilesEx(FileMask2.Text, FilterMask2.Text);\n    AbZipKit1.Save;\n  finally\n    DeleteGroup.Font.Color := SavedColor;\n    DeleteGroup.Caption := DeleteCaption;\n  end;\nend;\n\nprocedure TForm1.ExtractBtnClick(Sender: TObject);\nvar\n  SavedColor : TColor;\nbegin\n  AbortFlag := False;\n  AbZipKit1.BaseDirectory := DirectoryListBox2.Directory;\n  SavedColor := ExtractGroup.Font.Color;\n  ExtractGroup.Font.Color := clRed;\n  try\n    AbZipKit1.ExtractFilesEx(FileMask3.Text, FilterMask3.Text);\n  finally\n    ExtractGroup.Font.Color := SavedColor;\n    ExtractGroup.Caption := ExtractCaption;\n  end;\nend;\n\nprocedure TForm1.AbortBtnClick(Sender: TObject);\nbegin\n  AbortFlag := True;\nend;\n\nprocedure TForm1.ExitBtnClick(Sender: TObject);\nbegin\n  AbZipKit1.CloseArchive;\n  Close;\nend;\n\nprocedure TForm1.FormCreate(Sender: TObject);\nbegin\n  Caption := MainCaption;\n  AddGroup.Caption := AddCaption;\n  DeleteGroup.Caption := DeleteCaption;\n  ExtractGroup.Caption := ExtractCaption;\nend;\n\nprocedure TForm1.AbZipKit1ConfirmProcessItem(Sender: TObject;\n  Item: TAbArchiveItem; ProcessType: TAbProcessType; var Confirm: Boolean);\nbegin\n  case ProcessType of\n    ptAdd    : AddGroup.Caption := ' Adding ' + Item.Filename + ' ';\n    ptDelete : DeleteGroup.Caption := ' Deleting ' + Item.Filename + ' ';\n    ptExtract : ExtractGroup.Caption := ' Extracting ' + Item.Filename + ' ';\n  end;\n  Confirm := not AbortFlag;\nend;\n\nend.\n"
  },
  {
    "path": "lib/abbrevia/examples/Delphi/ExZipper.dpr",
    "content": "(* ***** BEGIN LICENSE BLOCK *****\n * Version: MPL 1.1\n *\n * The contents of this file are subject to the Mozilla Public License Version\n * 1.1 (the \"License\"); you may not use this file except in compliance with\n * the License. You may obtain a copy of the License at\n * http://www.mozilla.org/MPL/\n *\n * Software distributed under the License is distributed on an \"AS IS\" basis,\n * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License\n * for the specific language governing rights and limitations under the\n * License.\n *\n * The Original Code is TurboPower Abbrevia\n *\n * The Initial Developer of the Original Code is\n * TurboPower Software\n *\n * Portions created by the Initial Developer are Copyright (C) 1997-2002\n * the Initial Developer. All Rights Reserved.\n *\n * Contributor(s):\n *\n * ***** END LICENSE BLOCK ***** *)\n\nprogram ExZipper;\n\nuses\n  Forms,\n  Exzippru in 'EXZIPPRU.PAS' {Form1};\n\nbegin\n  Application.CreateForm(TForm1, Form1);\n  Application.Run;\nend.\n"
  },
  {
    "path": "lib/abbrevia/examples/Delphi/ExZippru.pas",
    "content": "(* ***** BEGIN LICENSE BLOCK *****\n * Version: MPL 1.1\n *\n * The contents of this file are subject to the Mozilla Public License Version\n * 1.1 (the \"License\"); you may not use this file except in compliance with\n * the License. You may obtain a copy of the License at\n * http://www.mozilla.org/MPL/\n *\n * Software distributed under the License is distributed on an \"AS IS\" basis,\n * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License\n * for the specific language governing rights and limitations under the\n * License.\n *\n * The Original Code is TurboPower Abbrevia\n *\n * The Initial Developer of the Original Code is\n * TurboPower Software\n *\n * Portions created by the Initial Developer are Copyright (C) 1997-2002\n * the Initial Developer. All Rights Reserved.\n *\n * Contributor(s):\n *\n * ***** END LICENSE BLOCK ***** *)\n\n{*********************************************************}\n{* ABBREVIA: EXZIPPRU.PAS                                *}\n{* Copyright (c) TurboPower Software Co 1997             *}\n{* All rights reserved.                                  *}\n{*********************************************************}\n{* ABBREVIA Example program file                         *}\n{*********************************************************}\n\nunit ExZippru;\n\ninterface\n\nuses\n  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,\n  StdCtrls, FileCtrl,\n\n  AbArcTyp, AbZipOut, AbZBrows, AbZipper, AbBrowse, AbBase, AbMeter, AbUtils;\n\ntype\n  TForm1 = class(TForm)\n    Button1: TButton;\n    Button2: TButton;\n    OpenDialog1: TOpenDialog;\n    DirectoryListBox1: TDirectoryListBox;\n    DriveComboBox1: TDriveComboBox;\n    Label1: TLabel;\n    AbZipper1: TAbZipper;\n    Button3: TButton;\n    AbMeter1: TAbMeter;\n    procedure Button1Click(Sender: TObject);\n    procedure DirectoryListBox1Change(Sender: TObject);\n    procedure FormCreate(Sender: TObject);\n    procedure Button2Click(Sender: TObject);\n    procedure AbZipper1ConfirmProcessItem(Sender: TObject;\n      Item: TAbArchiveItem; ProcessType: TAbProcessType;\n      var Confirm: Boolean);\n    procedure Button3Click(Sender: TObject);\n  private\n    { Private declarations }\n  public\n    { Public declarations }\n  end;\n\nvar\n  Form1: TForm1;\n\nimplementation\n\n{$R *.DFM}\n\nprocedure TForm1.FormCreate(Sender: TObject);\nbegin\n  DirectoryListBox1Change(nil);\n  AbZipper1.LogFile := ExtractFilePath(Application.ExeName) + 'Log.txt';\nend;\n\nprocedure TForm1.DirectoryListBox1Change(Sender: TObject);\nbegin\n  AbZipper1.BaseDirectory := DirectoryListBox1.Directory;\nend;\n\nprocedure TForm1.Button1Click(Sender: TObject);\nbegin\n  OpenDialog1.Filename := '*.zip';\n  OpenDialog1.InitialDir := DirectoryListBox1.Directory;\n  if OpenDialog1.Execute then\n    AbZipper1.Filename := OpenDialog1.Filename;\nend;\n\nprocedure TForm1.Button2Click(Sender: TObject);\nbegin\n  AbZipper1.AddFiles('*.*', 0);\n  Caption := 'ExZipper';\nend;\n\nprocedure TForm1.AbZipper1ConfirmProcessItem(Sender: TObject;\n  Item: TAbArchiveItem; ProcessType: TAbProcessType; var Confirm: Boolean);\nbegin\n  Caption := 'adding ' + Item.Filename;\nend;\n\nprocedure TForm1.Button3Click(Sender: TObject);\nbegin\n  Cursor := crHourGlass;\n  AbZipper1.CloseArchive;\n  Cursor := crDefault;\nend;\n\nend.\n\n\n"
  },
  {
    "path": "lib/abbrevia/examples/Delphi/FCITest1.pas",
    "content": "(* ***** BEGIN LICENSE BLOCK *****\n * Version: MPL 1.1\n *\n * The contents of this file are subject to the Mozilla Public License Version\n * 1.1 (the \"License\"); you may not use this file except in compliance with\n * the License. You may obtain a copy of the License at\n * http://www.mozilla.org/MPL/\n *\n * Software distributed under the License is distributed on an \"AS IS\" basis,\n * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License\n * for the specific language governing rights and limitations under the\n * License.\n *\n * The Original Code is TurboPower Abbrevia\n *\n * The Initial Developer of the Original Code is\n * TurboPower Software\n *\n * Portions created by the Initial Developer are Copyright (C) 1997-2002\n * the Initial Developer. All Rights Reserved.\n *\n * Contributor(s):\n *\n * ***** END LICENSE BLOCK ***** *)\n\nunit FCITest1;\n\ninterface\n\nuses\n  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,\n  StdCtrls, AbCabKit{, TestCab};\n\ntype\n  TForm1 = class(TForm)\n    Button1: TButton;\n    Button2: TButton;\n    Button3: TButton;\n    OpenDialog1: TOpenDialog;\n    Memo1: TMemo;\n    procedure Button1Click(Sender: TObject);\n    procedure Button2Click(Sender: TObject);\n    procedure Button3Click(Sender: TObject);\n  private\n    { Private declarations }\n  public\n  end;\n\nvar\n  Form1: TForm1;\n\nimplementation\n\n{$R *.DFM}\n\nprocedure TForm1.Button1Click(Sender: TObject);\nbegin\n  OpenDialog1.Filename := '*.cab';\n  if OpenDialog1.Execute then begin\n    Memo1.Clear;\n    MakeCab(OpenDialog1.Filename);\n    Memo1.Lines.Assign(TestCab.AuditTrail);\n  end;\nend;\n\nprocedure TForm1.Button2Click(Sender: TObject);\nvar\n  i : Integer;\nbegin\n  OpenDialog1.Filename := '*.*';\n  if OpenDialog1.Execute then\n    if OpenDialog1.Files.Count > 0 then\n      for i := 0 to Pred(OpenDialog1.Files.Count) do begin\n        try\n          AddFile(OpenDialog1.Files[i]);\n        finally\n        end;\n      end;\n  Memo1.Lines.Assign(TestCab.AuditTrail);\nend;\n\nprocedure TForm1.Button3Click(Sender: TObject);\nbegin\n  CloseArchive;\n  Memo1.Lines.Assign(TestCab.AuditTrail);\nend;\n\nend.\n"
  },
  {
    "path": "lib/abbrevia/examples/Delphi/Finder.dpr",
    "content": "(* ***** BEGIN LICENSE BLOCK *****\n * Version: MPL 1.1\n *\n * The contents of this file are subject to the Mozilla Public License Version\n * 1.1 (the \"License\"); you may not use this file except in compliance with\n * the License. You may obtain a copy of the License at\n * http://www.mozilla.org/MPL/\n *\n * Software distributed under the License is distributed on an \"AS IS\" basis,\n * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License\n * for the specific language governing rights and limitations under the\n * License.\n *\n * The Original Code is TurboPower Abbrevia\n *\n * The Initial Developer of the Original Code is\n * TurboPower Software\n *\n * Portions created by the Initial Developer are Copyright (C) 1997-2002\n * the Initial Developer. All Rights Reserved.\n *\n * Contributor(s):\n *\n * ***** END LICENSE BLOCK ***** *)\n\n{*********************************************************}\n{* ABBREVIA: FINDER.DPR                                  *}\n{*********************************************************}\n{* ABBREVIA Example program file                         *}\n{*********************************************************}\n\nprogram finder;\n\nuses\n  Forms,\n  ufinder in 'ufinder.pas' {Form1};\n\nbegin\n  Application.CreateForm(TForm1, Form1);\n  Application.Run;\nend.\n"
  },
  {
    "path": "lib/abbrevia/examples/Delphi/MakeCab.dpr",
    "content": "(* ***** BEGIN LICENSE BLOCK *****\n * Version: MPL 1.1\n *\n * The contents of this file are subject to the Mozilla Public License Version\n * 1.1 (the \"License\"); you may not use this file except in compliance with\n * the License. You may obtain a copy of the License at\n * http://www.mozilla.org/MPL/\n *\n * Software distributed under the License is distributed on an \"AS IS\" basis,\n * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License\n * for the specific language governing rights and limitations under the\n * License.\n *\n * The Original Code is TurboPower Abbrevia\n *\n * The Initial Developer of the Original Code is\n * TurboPower Software\n *\n * Portions created by the Initial Developer are Copyright (C) 1997-2002\n * the Initial Developer. All Rights Reserved.\n *\n * Contributor(s):\n *\n * ***** END LICENSE BLOCK ***** *)\n\n{*********************************************************}\n{* ABBREVIA: MAKECAB.DPR                                 *}\n{*********************************************************}\n{* ABBREVIA Example program file                         *}\n{*********************************************************}\n\nprogram MakeCab;\n\nuses\n  Forms,\n  MakeCab1 in 'MakeCab1.pas' {Form1};\n\nbegin\n  Application.CreateForm(TForm1, Form1);\n  Application.Run;\nend.\n"
  },
  {
    "path": "lib/abbrevia/examples/Delphi/MakeCab1.pas",
    "content": "(* ***** BEGIN LICENSE BLOCK *****\n * Version: MPL 1.1\n *\n * The contents of this file are subject to the Mozilla Public License Version\n * 1.1 (the \"License\"); you may not use this file except in compliance with\n * the License. You may obtain a copy of the License at\n * http://www.mozilla.org/MPL/\n *\n * Software distributed under the License is distributed on an \"AS IS\" basis,\n * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License\n * for the specific language governing rights and limitations under the\n * License.\n *\n * The Original Code is TurboPower Abbrevia\n *\n * The Initial Developer of the Original Code is\n * TurboPower Software\n *\n * Portions created by the Initial Developer are Copyright (C) 1997-2002\n * the Initial Developer. All Rights Reserved.\n *\n * Contributor(s):\n *\n * ***** END LICENSE BLOCK ***** *)\n\n{*********************************************************}\n{* ABBREVIA: MAKECAB1.PAS                                *}\n{* Copyright (c) TurboPower Software Co 1997             *}\n{* All rights reserved.                                  *}\n{*********************************************************}\n{* ABBREVIA Example program file                         *}\n{*********************************************************}\n\nunit MakeCab1;\n\ninterface\n\nuses\n  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,\n  StdCtrls, Gauges, ExtCtrls, ComCtrls,\n\n  AbArcTyp, AbCBrows, AbCabMak, AbCabTyp, AbMeter, AbBrowse, AbBase;\n\ntype\n  TForm1 = class(TForm)\n    AddBtn: TButton;\n    OpenDialog1: TOpenDialog;\n    Label1: TLabel;\n    CreateBtn: TButton;\n    CloseBtn: TButton;\n    Panel1: TPanel;\n    NewFolderBtn: TButton;\n    Label2: TLabel;\n    NewCabBtn: TButton;\n    AbMeter1: TAbMeter;\n    AbMakeCab1: TAbMakeCab;\n    procedure AddBtnClick(Sender: TObject);\n    procedure CreateBtnClick(Sender: TObject);\n    procedure CloseBtnClick(Sender: TObject);\n    procedure NewFolderBtnClick(Sender: TObject);\n    procedure NewCabBtnClick(Sender: TObject);\n    procedure AbMakeCab1ArchiveItemProgress(Sender: TObject;\n      Item: TAbArchiveItem; Progress: Byte; var Abort: Boolean);\n  private\n    { Private declarations }\n  public\n    { Public declarations }\n  end;\n\nvar\n  Form1: TForm1;\n\nimplementation\n\n{$R *.DFM}\n\nconst\n  MainCaption = 'Make Cabinet Archive';\n\nprocedure TForm1.CreateBtnClick(Sender: TObject);\nbegin\n  OpenDialog1.Filename := '*.Cab';\n  OpenDialog1.Title := 'Name of 1st cabinet';\n  if OpenDialog1.Execute then begin\n    Panel1.Caption := 'Creating ' + OpenDialog1.FileName;\n    AbMakeCab1.OpenArchive(OpenDialog1.FileName);\n    Caption := AbMakeCab1.FileName;\n    Panel1.Caption := 'Idle';\n  end;\nend;\n\nprocedure TForm1.AddBtnClick(Sender: TObject);\nvar\n  i : Integer;\n  SC : TCursor;\n  FileList : TStringList;\n\nbegin\n  OpenDialog1.Filename := '*.*';\n  OpenDialog1.Title := 'Add files to cabinet';\n  if OpenDialog1.Execute then\n    if (OpenDialog1.Files.Count > 0) then begin\n      SC := Cursor;\n      Cursor := crHourglass;\n      FileList := TStringList.Create;\n      try\n        FileList.Assign(OpenDialog1.Files);\n        for i := 0 to Pred(FileList.Count) do\n          AbMakeCab1.AddFiles(FileList.Strings[i], 0);\n      finally\n        FileList.Free;\n      end;\n      Cursor := SC;\n      Panel1.Caption := 'Idle';\n    end;\nend;\n\nprocedure TForm1.CloseBtnClick(Sender: TObject);\nbegin\n  Panel1.Caption := 'Closing ' + AbMakeCab1.FileName;\n  AbMakeCab1.CloseArchive;\n  Caption := MainCaption;\n  Panel1.Caption := 'Idle';\nend;\n\nprocedure TForm1.NewFolderBtnClick(Sender: TObject);\nbegin\n  AbMakeCab1.StartNewFolder;\nend;\n\nprocedure TForm1.NewCabBtnClick(Sender: TObject);\nbegin\n  AbMakeCab1.StartNewCabinet;\nend;\n\nprocedure TForm1.AbMakeCab1ArchiveItemProgress(Sender: TObject;\n  Item: TAbArchiveItem; Progress: Byte; var Abort: Boolean);\nbegin\n  Panel1.Caption := 'Adding ' + ExtractFilename(Item.Filename);\n  Abort := False;\nend;\n\nend.\n"
  },
  {
    "path": "lib/abbrevia/examples/Delphi/SelfStbv.dpr",
    "content": "(* ***** BEGIN LICENSE BLOCK *****\n * Version: MPL 1.1\n *\n * The contents of this file are subject to the Mozilla Public License Version\n * 1.1 (the \"License\"); you may not use this file except in compliance with\n * the License. You may obtain a copy of the License at\n * http://www.mozilla.org/MPL/\n *\n * Software distributed under the License is distributed on an \"AS IS\" basis,\n * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License\n * for the specific language governing rights and limitations under the\n * License.\n *\n * The Original Code is TurboPower Abbrevia\n *\n * The Initial Developer of the Original Code is\n * TurboPower Software\n *\n * Portions created by the Initial Developer are Copyright (C) 1997-2002\n * the Initial Developer. All Rights Reserved.\n *\n * Contributor(s):\n *\n * ***** END LICENSE BLOCK ***** *)\n\n{*********************************************************}\n{* ABBREVIA: SELFEXV.DPR                                 *}\n{*********************************************************}\n{* ABBREVIA Example program file                         *}\n{*********************************************************}\n\nprogram Selfstbv;\n\nuses\n  Forms,\n  Slfstbv1 in 'SLFSTBV1.PAS' {Form1};\n\nbegin\n  Application.CreateForm(TForm1, Form1);\n  Application.Run;\nend.\n"
  },
  {
    "path": "lib/abbrevia/examples/Delphi/SelfStub.dpr",
    "content": "(* ***** BEGIN LICENSE BLOCK *****\n * Version: MPL 1.1\n *\n * The contents of this file are subject to the Mozilla Public License Version\n * 1.1 (the \"License\"); you may not use this file except in compliance with\n * the License. You may obtain a copy of the License at\n * http://www.mozilla.org/MPL/\n *\n * Software distributed under the License is distributed on an \"AS IS\" basis,\n * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License\n * for the specific language governing rights and limitations under the\n * License.\n *\n * The Original Code is TurboPower Abbrevia\n *\n * The Initial Developer of the Original Code is\n * TurboPower Software\n *\n * Portions created by the Initial Developer are Copyright (C) 1997-2002\n * the Initial Developer. All Rights Reserved.\n *\n * Contributor(s):\n *\n * ***** END LICENSE BLOCK ***** *)\n\n{*********************************************************}\n{* ABBREVIA: SELFSTUB.DPR                                *}\n{*********************************************************}\n{* ABBREVIA Example program file                         *}\n{*********************************************************}\n\n(* This program creates a ZIP stub called SELFEX.EXE. This\nstub can then be used to create self-extracting ZIP files.\nFor more information on self-extracting ZIPs and ZIP stubs see\npage 112 in the Abbrevia manual. *)\n\nprogram Selfstub;\n\n{$APPTYPE CONSOLE}\n\nuses\n  AbArcTyp,\n  AbUnzPrc,\n  AbUtils,\n  AbZipTyp,\n  SysUtils;\n\ntype\n  THelper = class\n  public\n    procedure UnzipProc(Sender : TObject;\n                        Item : TAbArchiveItem;\n                        const NewName : string);\n  end;\n\nprocedure THelper.UnzipProc(Sender : TObject;\n                            Item : TAbArchiveItem;\n                            const NewName : string);\nbegin\n  AbUnzip(Sender, TAbZipItem(Item), NewName);\nend;\n\n{Build this app using the Define \"BuildingStub\", to keep it smaller!}\n\nvar\n  ZipArchive : TAbZipArchive;\n  Helper : THelper;\nbegin\n  WriteLn( 'Abbrevia Self Extracting Archive' );\n  ZipArchive := TAbZipArchive.Create(ParamStr(0),\n                                     fmOpenRead or fmShareDenyNone);\n  ChDir( ExtractFilePath(ParamStr(0)));\n  Helper := THelper.Create;\n  try\n    ZipArchive.Load;\n    ZipArchive.ExtractHelper := Helper.UnzipProc;\n    ZipArchive.ExtractFiles('*.*');\n  finally\n    Helper.Free;\n    ZipArchive.Free;\n  end;\nend.\n"
  },
  {
    "path": "lib/abbrevia/examples/Delphi/SlfStbv1.pas",
    "content": "(* ***** BEGIN LICENSE BLOCK *****\n * Version: MPL 1.1\n *\n * The contents of this file are subject to the Mozilla Public License Version\n * 1.1 (the \"License\"); you may not use this file except in compliance with\n * the License. You may obtain a copy of the License at\n * http://www.mozilla.org/MPL/\n *\n * Software distributed under the License is distributed on an \"AS IS\" basis,\n * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License\n * for the specific language governing rights and limitations under the\n * License.\n *\n * The Original Code is TurboPower Abbrevia\n *\n * The Initial Developer of the Original Code is\n * TurboPower Software\n *\n * Portions created by the Initial Developer are Copyright (C) 1997-2002\n * the Initial Developer. All Rights Reserved.\n *\n * Contributor(s):\n *\n * ***** END LICENSE BLOCK ***** *)\n\n{*********************************************************}\n{* ABBREVIA: SLFSTBV1.PAS                                *}\n{* Copyright (c) TurboPower Software Co 1997             *}\n{* All rights reserved.                                  *}\n{*********************************************************}\n{* ABBREVIA Example program file                         *}\n{*********************************************************}\n\nunit Slfstbv1;\n\ninterface\n\nuses\n  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, \n\n  AbZBrows, AbUnZper, AbArcTyp, AbBrowse, AbBase, AbUtils;\n\ntype\n  TForm1 = class(TForm)\n    Button1: TButton;\n    AbUnZipper1: TAbUnZipper;\n    Memo1: TMemo;\n    procedure Button1Click(Sender: TObject);\n  private\n    { Private declarations }\n  public\n    { Public declarations }\n  end;\n\nvar\n  Form1: TForm1;\n\nimplementation\n\n{$R *.DFM}\n\nprocedure TForm1.Button1Click(Sender: TObject);\nbegin\n  AbUnzipper1.FileName := ExtractFilePath(Application.ExeName) + 'abtest.exe';\n  AbUnzipper1.ArchiveType := atSelfExtZip;\n\n  AbUnzipper1.ExtractFiles( '*.*' );\nend;\n\nend.\n"
  },
  {
    "path": "lib/abbrevia/examples/Delphi/Streams.dpr",
    "content": "(* ***** BEGIN LICENSE BLOCK *****\n * Version: MPL 1.1\n *\n * The contents of this file are subject to the Mozilla Public License Version\n * 1.1 (the \"License\"); you may not use this file except in compliance with\n * the License. You may obtain a copy of the License at\n * http://www.mozilla.org/MPL/\n *\n * Software distributed under the License is distributed on an \"AS IS\" basis,\n * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License\n * for the specific language governing rights and limitations under the\n * License.\n *\n * The Original Code is TurboPower Abbrevia\n *\n * The Initial Developer of the Original Code is\n * TurboPower Software\n *\n * Portions created by the Initial Developer are Copyright (C) 1997-2002\n * the Initial Developer. All Rights Reserved.\n *\n * Contributor(s):\n *\n * ***** END LICENSE BLOCK ***** *)\n\n{*********************************************************}\n{* ABBREVIA: STREAMS.DPR                                 *}\n{*********************************************************}\n{* ABBREVIA Example program file                         *}\n{*********************************************************}\n\nprogram Streams;\n\nuses\n  Forms,\n  Streams1 in 'Streams1.pas' {Form1};\n\nbegin\n  Application.CreateForm(TForm1, Form1);\n  Application.Run;\nend.\n"
  },
  {
    "path": "lib/abbrevia/examples/Delphi/Streams1.pas",
    "content": "(* ***** BEGIN LICENSE BLOCK *****\n * Version: MPL 1.1\n *\n * The contents of this file are subject to the Mozilla Public License Version\n * 1.1 (the \"License\"); you may not use this file except in compliance with\n * the License. You may obtain a copy of the License at\n * http://www.mozilla.org/MPL/\n *\n * Software distributed under the License is distributed on an \"AS IS\" basis,\n * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License\n * for the specific language governing rights and limitations under the\n * License.\n *\n * The Original Code is TurboPower Abbrevia\n *\n * The Initial Developer of the Original Code is\n * TurboPower Software\n *\n * Portions created by the Initial Developer are Copyright (C) 1997-2002\n * the Initial Developer. All Rights Reserved.\n *\n * Contributor(s):\n *\n * ***** END LICENSE BLOCK ***** *)\n\n{*********************************************************}\n{* ABBREVIA: STREAMS1.PAS                                *}\n{* Copyright (c) TurboPower Software Co 1997             *}\n{* All rights reserved.                                  *}\n{*********************************************************}\n{* ABBREVIA Example program file                         *}\n{*********************************************************}\n\nunit Streams1;\n\ninterface\n\nuses\n  Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,\n  StdCtrls, Grids,\n\n  AbView, AbZView, Menus, AbArcTyp, AbZBrows, AbUnZper,\n  AbZipper, AbZipKit, AbBrowse, AbBase;\n\ntype\n  TForm1 = class(TForm)\n    MainMenu1: TMainMenu;\n    File1: TMenuItem;\n    Open1: TMenuItem;\n    Exit1: TMenuItem;\n    Action1: TMenuItem;\n    Extract1: TMenuItem;\n    AbZipView1: TAbZipView;\n    Memo1: TMemo;\n    OpenDialog1: TOpenDialog;\n    Close1: TMenuItem;\n    N1: TMenuItem;\n    Add1: TMenuItem;\n    AbZipKit1: TAbZipKit;\n    Clearmemo1: TMenuItem;\n    procedure Open1Click(Sender: TObject);\n    procedure Extract1Click(Sender: TObject);\n    procedure Close1Click(Sender: TObject);\n    procedure Exit1Click(Sender: TObject);\n    procedure AbZipView1DblClick(Sender: TObject);\n    procedure Clearmemo1Click(Sender: TObject);\n    procedure Add1Click(Sender: TObject);\n  private\n    { Private declarations }\n  public\n    { Public declarations }\n  end;\n\nvar\n  Form1: TForm1;\n\nimplementation\n\n{$R *.DFM}\n\nconst\n  MainCaption = ' Compressed Memo';\n\nprocedure TForm1.Open1Click(Sender: TObject);\nbegin\n  OpenDialog1.Filename := '*.zip';\n  if OpenDialog1.Execute then\n    AbZipKit1.OpenArchive(OpenDialog1.Filename);\nend;\n\nprocedure TForm1.Extract1Click(Sender: TObject);\nvar\n  ToStream : TMemoryStream;\n  Item : TAbArchiveItem;\nbegin\n  Memo1.Clear;\n  ToStream := TMemoryStream.Create;\n  try\n    Item := AbZipView1.Items[AbZipView1.ActiveRow];\n    Caption := Item.Filename;\n    AbZipKit1.ExtractToStream(Item.FileName, ToStream);\n    ToStream.Position := 0;\n    Memo1.Lines.LoadFromStream(ToStream);\n  finally\n    ToStream.Free;\n  end;\nend;\n\nprocedure TForm1.Close1Click(Sender: TObject);\nbegin\n  AbZipKit1.CloseArchive;\n  Caption := MainCaption;\nend;\n\nprocedure TForm1.Exit1Click(Sender: TObject);\nbegin\n  Close1Click(nil);\n  Close;\nend;\n\nprocedure TForm1.AbZipView1DblClick(Sender: TObject);\nbegin\n  Extract1Click(nil);\nend;\n\nprocedure TForm1.Clearmemo1Click(Sender: TObject);\nbegin\n  Memo1.Clear;\nend;\n\nprocedure TForm1.Add1Click(Sender: TObject);\nvar\n  FromStream : TMemoryStream;\n  FN : string;\nbegin\n  FromStream := TMemoryStream.Create;\n  try\n    Memo1.Lines.SaveToStream(FromStream);\n    if InputQuery('Streams', 'Give it a filename', FN) then begin\n      Caption := FN;\n      AbZipKit1.AddFromStream(FN, FromStream);\n    end;\n  finally\n    FromStream.Free;\n  end;\nend;\n\nend.\n"
  },
  {
    "path": "lib/abbrevia/examples/Delphi/StrmBmp.dpr",
    "content": "(* ***** BEGIN LICENSE BLOCK *****\n * Version: MPL 1.1\n *\n * The contents of this file are subject to the Mozilla Public License Version\n * 1.1 (the \"License\"); you may not use this file except in compliance with\n * the License. You may obtain a copy of the License at\n * http://www.mozilla.org/MPL/\n *\n * Software distributed under the License is distributed on an \"AS IS\" basis,\n * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License\n * for the specific language governing rights and limitations under the\n * License.\n *\n * The Original Code is TurboPower Abbrevia\n *\n * The Initial Developer of the Original Code is\n * TurboPower Software\n *\n * Portions created by the Initial Developer are Copyright (C) 1997-2002\n * the Initial Developer. All Rights Reserved.\n *\n * Contributor(s):\n *\n * ***** END LICENSE BLOCK ***** *)\n\n{*********************************************************}\n{* ABBREVIA: STRMBMP.DPR                                 *}\n{*********************************************************}\n{* ABBREVIA Example program file                         *}\n{*********************************************************}\n\nprogram StrmBmp;\n\nuses\n  Forms,\n  StrmBmpU in 'StrmBmpU.pas' {Form1};\n\nbegin\n  Application.CreateForm(TForm1, Form1);\n  Application.Run;\nend.\n"
  },
  {
    "path": "lib/abbrevia/examples/Delphi/StrmBmpU.pas",
    "content": "(* ***** BEGIN LICENSE BLOCK *****\n * Version: MPL 1.1\n *\n * The contents of this file are subject to the Mozilla Public License Version\n * 1.1 (the \"License\"); you may not use this file except in compliance with\n * the License. You may obtain a copy of the License at\n * http://www.mozilla.org/MPL/\n *\n * Software distributed under the License is distributed on an \"AS IS\" basis,\n * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License\n * for the specific language governing rights and limitations under the\n * License.\n *\n * The Original Code is TurboPower Abbrevia\n *\n * The Initial Developer of the Original Code is\n * TurboPower Software\n *\n * Portions created by the Initial Developer are Copyright (C) 1997-2002\n * the Initial Developer. All Rights Reserved.\n *\n * Contributor(s):\n *\n * ***** END LICENSE BLOCK ***** *)\n\n{*********************************************************}\n{* ABBREVIA: STRMBMPU.DPR                                *}\n{* Copyright (c) TurboPower Software Co 1997             *}\n{* All rights reserved.                                  *}\n{*********************************************************}\n{* ABBREVIA Example program file                         *}\n{*********************************************************}\n\nunit StrmBmpU;\n\ninterface\n\nuses\n  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,\n  StdCtrls, ExtCtrls;\n\ntype\n  TForm1 = class(TForm)\n    Image1: TImage;\n    Button1: TButton;\n    Memo1: TMemo;\n    procedure Button1Click(Sender: TObject);\n  private\n    { Private declarations }\n  public\n    { Public declarations }\n  end;\n\nvar\n  Form1: TForm1;\n\nimplementation\n\nuses\n  AbUnzPrc,\n  AbZipPrc;\n\n{$R *.DFM}\n\nprocedure TForm1.Button1Click(Sender: TObject);\nvar\n  UStrm  : TMemoryStream;\n  CStrm  : TMemoryStream;\n  Image2 : TImage;\nbegin\n  { Create the compressed stream and the uncompressed stream. }\n  UStrm := TMemoryStream.Create;\n  CStrm := TMemoryStream.Create;\n\n  { Copy the bitmap image to the memory stream. }\n  Image1.Picture.Bitmap.SaveToStream(UStrm);\n\n  { Set the stream position to the beginning. }\n  UStrm.Position := 0;\n\n  { Compress the stream. }\n  DeflateStream(UStrm, CStrm);\n\n  { Remove all data from the uncompressed stream. }\n  UStrm.Clear;\n\n  { Reset the compressed stream back to the beginning. }\n  CStrm.Position := 0;\n\n  { Decompress the stream back to the original uncompressed }\n  { stream and then reset the stream position back to 0.    }\n  InflateStream(CStrm, UStrm);\n  UStrm.Position := 0;\n\n  { Now create a new TImage. Make it the same size as the }\n  { original image but move it down and to the left.      }\n  Image2 := TImage.Create(Self);\n  Image2.Top := Image1.Top + 20;\n  Image2.Left := Image1.Left + 20;\n  Image2.Width := Image1.Width;\n  Image2.Height := Image1.Height;\n  Image2.Parent := Self;\n\n  { Delete the original TImage. }\n  Image1.Free;\n\n  { Load the new bitmap with the data from the stream }\n  { that contains the decompressed image. }\n  Image2.Picture.Bitmap.LoadFromStream(UStrm);\n\n  { Free the memory streams. }\n  UStrm.Free;\n  CStrm.Free;\nend;\n\nend.\n"
  },
  {
    "path": "lib/abbrevia/examples/Delphi/StrmPad.dpr",
    "content": "(* ***** BEGIN LICENSE BLOCK *****\n * Version: MPL 1.1\n *\n * The contents of this file are subject to the Mozilla Public License Version\n * 1.1 (the \"License\"); you may not use this file except in compliance with\n * the License. You may obtain a copy of the License at\n * http://www.mozilla.org/MPL/\n *\n * Software distributed under the License is distributed on an \"AS IS\" basis,\n * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License\n * for the specific language governing rights and limitations under the\n * License.\n *\n * The Original Code is TurboPower Abbrevia\n *\n * The Initial Developer of the Original Code is\n * TurboPower Software\n *\n * Portions created by the Initial Developer are Copyright (C) 1997-2002\n * the Initial Developer. All Rights Reserved.\n *\n * Contributor(s):\n *\n * ***** END LICENSE BLOCK ***** *)\n\n{*********************************************************}\n{* ABBREVIA: STRMPAD.DPR                                 *}\n{*********************************************************}\n{* ABBREVIA Example program file                         *}\n{*********************************************************}\n\nprogram StrmPad;\n\nuses\n  Forms,\n  Ustrpad in 'Ustrpad.pas' {Form1};\n\nbegin\n  Application.CreateForm(TForm1, Form1);\n  Application.Run;\nend.\n"
  },
  {
    "path": "lib/abbrevia/examples/Delphi/TpZip.RC",
    "content": ";{*********************************************************}\n;{* ABBREVIA: TPZIP.RC                                    *}\n;{* Copyright (c) TurboPower Software Co 1997             *}\n;{* All rights reserved.                                  *}\n;{*********************************************************}\n;{* ABBREVIA Example program file                         *}\n;{*********************************************************}\n\nMAINICON ICON \"tpzip.ico\"\n\n"
  },
  {
    "path": "lib/abbrevia/examples/Delphi/TpZip.dpr",
    "content": "(* ***** BEGIN LICENSE BLOCK *****\n * Version: MPL 1.1\n *\n * The contents of this file are subject to the Mozilla Public License Version\n * 1.1 (the \"License\"); you may not use this file except in compliance with\n * the License. You may obtain a copy of the License at\n * http://www.mozilla.org/MPL/\n *\n * Software distributed under the License is distributed on an \"AS IS\" basis,\n * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License\n * for the specific language governing rights and limitations under the\n * License.\n *\n * The Original Code is TurboPower Abbrevia\n *\n * The Initial Developer of the Original Code is\n * TurboPower Software\n *\n * Portions created by the Initial Developer are Copyright (C) 1997-2002\n * the Initial Developer. All Rights Reserved.\n *\n * Contributor(s):\n *\n * ***** END LICENSE BLOCK ***** *)\n\n{*********************************************************}\n{* ABBREVIA: TPZIP.DPR                                   *}\n{*********************************************************}\n{* ABBREVIA Example program file                         *}\n{*********************************************************}\n\nprogram TPZip;\n\nuses\n  Forms,\n  ubasedlg in 'UBASEDLG.PAS' {BaseDirDlg},\n  udemodlg in 'UDEMODLG.PAS' {DemoDlg},\n  dgAbout in 'DGABOUT.PAS' {dlgAboutBox},\n  usplash in 'USPLASH.PAS' {Splash},\n  UMain in 'Umain.pas' {Form1};\n\n{$R *.R32}\n\nbegin\n  Application.Title := 'TP Zip';\n  Application.HelpFile := 'Tpzip31.hlp';\n  Application.CreateForm(TForm1, Form1);\n  Splash := TSplash.Create( Application );\n  Splash.Show;\n  Splash.Refresh;\n  Application.Run;\nend.\n"
  },
  {
    "path": "lib/abbrevia/examples/Delphi/UContent.pas",
    "content": "(* ***** BEGIN LICENSE BLOCK *****\n * Version: MPL 1.1\n *\n * The contents of this file are subject to the Mozilla Public License Version\n * 1.1 (the \"License\"); you may not use this file except in compliance with\n * the License. You may obtain a copy of the License at\n * http://www.mozilla.org/MPL/\n *\n * Software distributed under the License is distributed on an \"AS IS\" basis,\n * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License\n * for the specific language governing rights and limitations under the\n * License.\n *\n * The Original Code is TurboPower Abbrevia\n *\n * The Initial Developer of the Original Code is\n * TurboPower Software\n *\n * Portions created by the Initial Developer are Copyright (C) 1997-2002\n * the Initial Developer. All Rights Reserved.\n *\n * Contributor(s):\n *\n * ***** END LICENSE BLOCK ***** *)\n\n{*********************************************************}\n{* ABBREVIA: UCONTENT.PAS                                *}\n{* Copyright (c) TurboPower Software Co 1997             *}\n{* All rights reserved.                                  *}\n{*********************************************************}\n{* ABBREVIA Example program file                         *}\n{*********************************************************}\n\nunit UContent;\n\n\n\ninterface\n\nuses\n  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls,\n\n  AbZBrows, AbArcTyp, AbBrowse, AbBase;\n\ntype\n  TForm1 = class(TForm)\n    ListBox1: TListBox;\n    Button1: TButton;\n    OpenDialog1: TOpenDialog;\n    AbZipBrowser1: TAbZipBrowser;\n    Label1: TLabel;\n    procedure Button1Click(Sender: TObject);\n  private\n    { Private declarations }\n  public\n    { Public declarations }\n  end;\n\nvar\n  Form1: TForm1;\n\nimplementation\n\n{$R *.DFM}\n\nprocedure TForm1.Button1Click(Sender: TObject);\nvar\n  i : Integer;\nbegin\n  ListBox1.Clear;\n  if OpenDialog1.Execute then begin\n    try\n      with AbZipBrowser1 do begin\n        FileName := OpenDialog1.FileName;\n        if Count > 0 then\n          for i := 0 to pred( Count ) do\n            ListBox1.Items.Add( Items[i].FileName );\n      end;\n    except\n      ListBox1.Items.Add( OpenDialog1.FileName + ' is not a valid archive.' );\n    end;\n  end;\nend;\n\nend.\n"
  },
  {
    "path": "lib/abbrevia/examples/Delphi/UMain.pas",
    "content": "(* ***** BEGIN LICENSE BLOCK *****\n * Version: MPL 1.1\n *\n * The contents of this file are subject to the Mozilla Public License Version\n * 1.1 (the \"License\"); you may not use this file except in compliance with\n * the License. You may obtain a copy of the License at\n * http://www.mozilla.org/MPL/\n *\n * Software distributed under the License is distributed on an \"AS IS\" basis,\n * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License\n * for the specific language governing rights and limitations under the\n * License.\n *\n * The Original Code is TurboPower Abbrevia\n *\n * The Initial Developer of the Original Code is\n * TurboPower Software\n *\n * Portions created by the Initial Developer are Copyright (C) 1997-2002\n * the Initial Developer. All Rights Reserved.\n *\n * Contributor(s):\n *\n * ***** END LICENSE BLOCK ***** *)\n\n{*********************************************************}\n{* ABBREVIA: UMAIN.PAS                                   *}\n{* Copyright (c) TurboPower Software Co 1997             *}\n{* All rights reserved.                                  *}\n{*********************************************************}\n{* ABBREVIA: TPZip                                       *}\n{*********************************************************}\n\n{$I AbDefine.inc}\n\nunit UMain;\n\ninterface\n\nuses\n  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,\n  Menus, ExtCtrls, FileCtrl, StdCtrls, Gauges, Buttons, \n\n  AbArcTyp, AbUtils, AbZipOut, AbMeter, AbBase, AbBrowse;\n\ntype\n  TForm1 = class(TForm)\n    MainMenu1: TMainMenu;\n    File1: TMenuItem;\n    Open1: TMenuItem;\n    Save1: TMenuItem;\n    N1: TMenuItem;\n    Exit1: TMenuItem;\n    Items1: TMenuItem;\n    Help1: TMenuItem;\n    Contents1: TMenuItem;\n    N2: TMenuItem;\n    About1: TMenuItem;\n    Preferences1: TMenuItem;\n    View1: TMenuItem;\n    Attributes1: TMenuItem;\n    za0: TMenuItem;\n    za1: TMenuItem;\n    za8: TMenuItem;\n    Hierarchy1: TMenuItem;\n    Style1: TMenuItem;\n    Panel1: TPanel;\n    Panel2: TPanel;\n    za2: TMenuItem;\n    za3: TMenuItem;\n    za4: TMenuItem;\n    za5: TMenuItem;\n    za6: TMenuItem;\n    za7: TMenuItem;\n    za9: TMenuItem;\n    za10: TMenuItem;\n    N3: TMenuItem;\n    None1: TMenuItem;\n    All1: TMenuItem;\n    Panel3: TPanel;\n    Panel4: TPanel;\n    DriveComboBox1: TDriveComboBox;\n    FilterComboBox1: TFilterComboBox;\n    DirectoryListBox1: TDirectoryListBox;\n    FileListBox1: TFileListBox;\n    Panel5: TPanel;\n    FontDialog1: TFontDialog;\n    Font1: TMenuItem;\n    Panel6: TPanel;\n    OpenDialog1: TOpenDialog;\n    CompressionMethodToUse1: TMenuItem;\n    Store1: TMenuItem;\n    Deflate1: TMenuItem;\n    Best1: TMenuItem;\n    DeflationOption1: TMenuItem;\n    Maximum1: TMenuItem;\n    Normal1: TMenuItem;\n    Fast1: TMenuItem;\n    SuperFast1: TMenuItem;\n    ExtractOptions1: TMenuItem;\n    CreateDirs1: TMenuItem;\n    RestorePath1: TMenuItem;\n    Password1: TMenuItem;\n    StoreOptions1: TMenuItem;\n    RemoveDots1: TMenuItem;\n    RecurseTree1: TMenuItem;\n    StripPath1: TMenuItem;\n    AddFiles1: TMenuItem;\n    DeleteFiles1: TMenuItem;\n    ExtractFiles1: TMenuItem;\n    FreshenFiles1: TMenuItem;\n    PopupMenu1: TPopupMenu;\n    Delete1: TMenuItem;\n    Run1: TMenuItem;\n    Move1: TMenuItem;\n    Freshen1: TMenuItem;\n    Extract1: TMenuItem;\n    Confirmations1: TMenuItem;\n    Close1: TMenuItem;\n    Convert1: TMenuItem;\n    N4: TMenuItem;\n    Default1: TMenuItem;\n    Panel8: TPanel;\n    SpeedButton1: TSpeedButton;\n    SpeedButton2: TSpeedButton;\n    SpeedButton3: TSpeedButton;\n    SpeedButton4: TSpeedButton;\n    SpeedButton5: TSpeedButton;\n    SpeedButton7: TSpeedButton;\n    SpeedButton8: TSpeedButton;\n    SpeedButton9: TSpeedButton;\n    SpeedButton10: TSpeedButton;\n    SpeedButton11: TSpeedButton;\n    SpeedButton12: TSpeedButton;\n    SpeedButton13: TSpeedButton;\n    SpeedButton14: TSpeedButton;\n    Image1: TImage;\n    ArchiveLabel: TLabel;\n    Label1: TLabel;\n    Label2: TLabel;\n    FileComment1: TMenuItem;\n    sbNone: TSpeedButton;\n    sbAll: TSpeedButton;\n    sbDef: TSpeedButton;\n    Edit1: TEdit;\n    Label3: TLabel;\n    N5: TMenuItem;\n    OS3: TMenuItem;\n    OS4: TMenuItem;\n    OS2: TMenuItem;\n    OS1: TMenuItem;\n    OS6: TMenuItem;\n    OS5: TMenuItem;\n    AbbreviaontheWeb1: TMenuItem;\n    AbMeter1: TAbMeter;\n    AbMeter2: TAbMeter;\n    ShowEmptyfolders1: TMenuItem;\n    TempDirectory1: TMenuItem;\n    Logging1: TMenuItem;\n    AbZipOutline1: TAbZipOutline;\n\n    procedure AbZipOutline1Change(Sender: TObject);\n    procedure AbZipOutline1ConfirmSave(Sender: TObject;\n      var Confirm: Boolean);\n    procedure AbZipOutline1DblClick(Sender: TObject);\n    procedure AbZipOutline1DragDrop(Sender, Source: TObject; X,\n      Y: Integer);\n    procedure AbZipOutline1DragOver(Sender, Source: TObject; X, Y: Integer;\n      State: TDragState; var Accept: Boolean);\n    procedure AbZipOutline1MouseDown(Sender: TObject; Button: TMouseButton;\n      Shift: TShiftState; X, Y: Integer);\n    procedure AbZipOutline1WindowsDrop(Sender: TObject;\n      FileName: string);\n    procedure All1Click(Sender: TObject);\n    procedure Best1Click(Sender: TObject);\n    procedure Confirmations1Click(Sender: TObject);\n    procedure CreateDirs1Click(Sender: TObject);\n    procedure Exit1Click(Sender: TObject);\n    procedure FileListBox1DragDrop(Sender, Source: TObject; X, Y: Integer);\n    procedure FileListBox1DragOver(Sender, Source: TObject; X, Y: Integer;\n      State: TDragState; var Accept: Boolean);\n    procedure Font1Click(Sender: TObject);\n    procedure FormCreate(Sender: TObject);\n    procedure Hierarchy1Click(Sender: TObject);\n    procedure None1Click(Sender: TObject);\n    procedure Open1Click(Sender: TObject);\n    procedure RestorePath1Click(Sender: TObject);\n    procedure Save1Click(Sender: TObject);\n    procedure StripPath1Click(Sender: TObject);\n    procedure SuperFast1Click(Sender: TObject);\n    procedure za10Click(Sender: TObject);\n\n    procedure Delete1Click(Sender: TObject);\n    procedure Extract1Click(Sender: TObject);\n    procedure Freshen1Click(Sender: TObject);\n    procedure Move1Click(Sender: TObject);\n    procedure Password1Click(Sender: TObject);\n    procedure AddFiles1Click(Sender: TObject);\n    procedure FreshenFiles1Click(Sender: TObject);\n    procedure SelectBaseDirectory1Click(Sender: TObject);\n    procedure AbZipOutline1ArchiveItemProgress(Sender: TObject;\n      Item: TAbArchiveItem; Progress: Byte; var Abort: Boolean);\n    procedure AbZipOutline1NeedPassword(Sender: TObject;\n      var NewPassword: AnsiString);\n    procedure DeleteFiles1Click(Sender: TObject);\n    procedure ExtractFiles1Click(Sender: TObject);\n    procedure FormDestroy(Sender: TObject);\n    procedure Close1Click(Sender: TObject);\n    procedure AbZipOutline1Load(Sender: TObject);\n    procedure Convert1Click(Sender: TObject);\n    procedure AbZipOutline1ConfirmOverwrite(var Name: string;\n      var Confirm: Boolean);\n    procedure Default1Click(Sender: TObject);\n    procedure Contents1Click(Sender: TObject);\n    procedure About1Click(Sender: TObject);\n    procedure FileListBox1DblClick(Sender: TObject);\n    procedure AbZipOutline1EndDrag(Sender, Target: TObject; X, Y: Integer);\n    procedure FileListBox1MouseDown(Sender: TObject; Button: TMouseButton;\n      Shift: TShiftState; X, Y: Integer);\n    procedure FileListBox1MouseMove(Sender: TObject; Shift: TShiftState; X,\n      Y: Integer);\n    procedure AbZipOutline1MouseMove(Sender: TObject; Shift: TShiftState;\n      X, Y: Integer);\n    procedure Edit1Exit(Sender: TObject);\n    procedure FormKeyPress(Sender: TObject; var Key: Char);\n    procedure OS5Click(Sender: TObject);\n    procedure AbZipOutline1ConfirmProcessItem(Sender: TObject;\n      Item: TAbArchiveItem; ProcessType: TAbProcessType;\n      var Confirm: Boolean);\n    procedure AbZipOutline1ProcessItemFailure(Sender: TObject;\n      Item: TAbArchiveItem; const ProcessType: TAbProcessType;\n      ErrorClass: TAbErrorClass; ErrorCode: Integer);\n    procedure TurboPowerontheWeb1Click(Sender: TObject);\n    procedure AbbreviaontheWeb1Click(Sender: TObject);\n    procedure TempDirectory1Click(Sender: TObject);\n    procedure Logging1Click(Sender: TObject);\n  private\n    { Private declarations }\n    OutlineX, OutlineY, FileX, FileY : Integer;\n    StubName : string;\n    IgnoreDuplicateWarning : Boolean;\n    procedure ReadIniSettings;\n    procedure SaveIniSettings;\n    procedure SetCaption;\n    procedure UpdateMenu;\n    procedure DoConfirm( Sender : TObject; Item : TAbArchiveItem;\n                       var Confirm : Boolean; Caption : string );\n    procedure GetMinMaxInfo( var Msg: TWMGetMinMaxInfo );\n              message WM_GETMINMAXINFO;\n  public\n    { Public declarations }\n  end;\n\nvar\n  Form1: TForm1;\n\nimplementation\n\n{$R *.DFM}\n\nuses\n  AbConst,\n  AbDlgDir,\n  AbDlgPwd,\n  AbZBrows,\n  AbZipTyp,\n  dgAbout,\n  IniFiles,\n  Outline,\n  ShellAPI,\n  UBaseDlg,\n  UDemoDlg,\n  uSplash;\n\nprocedure TForm1.All1Click(Sender: TObject);\nvar\n  i : Integer;\nbegin\n  for i := 0 to Ord( High( TAbZipAttribute ) ) do\n    Attributes1.Items[i].Checked := True;\n  AbZipOutline1.Attributes := [zaCompressedSize, zaCompressionMethod,\n                      zaCompressionRatio, zaCRC, zaExternalFileAttributes,\n                      zaInternalFileAttributes, zaEncryption, zaTimeStamp,\n                      zaUncompressedSize, zaVersionMade, zaVersionNeeded,\n                      zaComment];\n  AbZipOutline1.Update;\nend;\n\nprocedure TForm1.Exit1Click(Sender: TObject);\nbegin\n  Close;\nend;\n\nprocedure TForm1.FormCreate(Sender: TObject);\nbegin\n  ReadIniSettings;\n  SetCaption;\n  UpdateMenu;\n  if ParamCount > 0 then\n    try\n      AbZipOutline1.FileName := ParamStr( 1 );\n    except\n    end;\n\nend;\n\nprocedure TForm1.Hierarchy1Click(Sender: TObject);\nbegin\n  Hierarchy1.Checked := not Hierarchy1.Checked;\n  AbZipOutline1.Hierarchy := Hierarchy1.Checked;\nend;\n\nprocedure TForm1.None1Click(Sender: TObject);\nvar\n  i : Integer;\nbegin\n  for i := 0 to pred( Attributes1.Count ) do\n    Attributes1.Items[i].Checked := False;\n  AbZipOutline1.Attributes := [];\n  AbZipOutline1.Update;\nend;\n\nprocedure TForm1.Save1Click(Sender: TObject);\nbegin\n  AbZipOutline1.Save;\nend;\n\nprocedure TForm1.SetCaption;\nbegin\n  Caption := 'TPZip ' + AbZipOutline1.Version + ' - ' +\n             AbZipOutline1.FileName;\nend;\n\nprocedure TForm1.UpdateMenu;\nvar\n  i : TAbZipAttribute;\nbegin\n  with AbZipOutline1 do begin\n    i := Low( TAbZipAttribute );\n    while i <> High( TAbZipAttribute ) do begin\n      Attributes1.Items[Ord(i)].Checked := i in Attributes;\n      i := succ( i );\n    end;\n    Hierarchy1.Checked := Hierarchy;\n//    OS1.Checked := Ord( OutlineStyle ) = 0;\n//    OS2.Checked := Ord( OutlineStyle ) = 1;\n//    OS3.Checked := Ord( OutlineStyle ) = 2;\n//    OS4.Checked := Ord( OutlineStyle ) = 3;\n//    OS5.Checked := Ord( OutlineStyle ) = 4;\n//    OS6.Checked := Ord( OutlineStyle ) = 5;\n\n    Best1.Checked := CompressionMethodToUse = smBestMethod;\n    Deflate1.Checked := CompressionMethodToUse = smDeflated;\n    Store1.Checked := CompressionMethodToUse = smStored;\n    {deflation options}\n    Normal1.Checked := DeflationOption = doNormal;\n    Maximum1.Checked := DeflationOption = doMaximum;\n    Fast1.Checked := DeflationOption = doFast;\n    SuperFast1.Checked := DeflationOption = doSuperFast;\n    {extractOptions}\n    CreateDirs1.Checked := eoCreateDirs in ExtractOptions;\n    RestorePath1.Checked := eoRestorePath in ExtractOptions;\n    {StoreOptions}\n    RecurseTree1.Checked := soRecurse in StoreOptions;\n    StripPath1.Checked := soStripPath in StoreOptions;\n    RemoveDots1.Checked := soRemoveDots in StoreOptions;\n  end;\nend;\n\nprocedure TForm1.za10Click(Sender: TObject);\nvar\n  Item : TMenuItem;\nbegin\n  Item := (Sender as TMenuItem);\n  Item.Checked := not Item.Checked;\n  with AbZipOutline1 do\n    if Item.Checked then\n      Attributes := Attributes + [TAbZipAttribute( Item.Tag )]\n    else\n      Attributes := Attributes - [TAbZipAttribute( Item.Tag )];\n  AbZipOutline1.Update;\nend;\n\nprocedure TForm1.Font1Click(Sender: TObject);\nbegin\n  if FontDialog1.Execute then\n    with FontDialog1 do begin\n      AbZipOutline1.Font := Font;\n      DirectoryListBox1.Font := Font;\n      FileListBox1.Font := Font;\n      DriveComboBox1.Font := Font;\n      FilterComboBox1.Font := Font;\n    end;\nend;\n\nprocedure TForm1.Open1Click(Sender: TObject);\nbegin\n  if OpenDialog1.Execute then begin\n    AbZipOutline1.FileName := OpenDialog1.FileName;\n  end;\nend;\n\nprocedure TForm1.AbZipOutline1DragOver(Sender, Source: TObject; X,\n  Y: Integer; State: TDragState; var Accept: Boolean);\nbegin\n  Accept := Source is TFileListBox;\nend;\n\nprocedure TForm1.AbZipOutline1DragDrop(Sender, Source: TObject; X,\n  Y: Integer);\nvar\n  i, j : Integer;\n  ZB : TAbZipBrowser;\n  IsZip : Boolean;\n  ZipName : string;\nbegin\n  if Source is TFileListBox then\n    with (Source as TFileListBox ) do\n      if SelCount = 1 then begin\n        for i := 0 to pred( Items.Count ) do\n          if FileListBox1.Selected[i] then begin\n            IsZip := False;\n            ZB := TAbZipBrowser.Create( Self );\n            try\n              try\n                ZB.FileName := Directory + '\\' + Items[i];\n                IsZip := True;\n              except\n              end;\n            finally\n              ZB.Free;\n            end;\n            if IsZip then\n              {only one file, and it is a zip file}\n              AbZipOutline1.FileName := Directory + '\\' + Items[i]\n            else if AbZipOutline1.FileName <> '' then\n              {only one file, and it's not a zip file}\n              AbZipOutline1.AddFiles( Directory + '\\' + Items[i], 0 )\n            else begin\n              if OpenDialog1.Execute then begin\n                AbZipOutline1.FileName := OpenDialog1.FileName;\n                AbZipOutline1.AddFiles( Directory + '\\' + Items[i], 0 );\n              end;\n            end;\n            break;\n          end;\n      end\n      else begin\n        {multiple files dropped...}\n        IsZip := False;\n        ZB := TAbZipBrowser.Create( Self );\n        try\n          for i := 0 to pred( Items.Count ) do\n            if FileListBox1.Selected[i] then begin\n              try\n                ZB.FileName := Directory + '\\' + Items[i];\n                IsZip := True;\n                ZipName := ZB.FileName;\n                break;\n              except\n              end;\n            end;\n        finally\n          ZB.Free;\n        end;\n        if IsZip and ( Application.MessageBox( \n                     'One of the dropped files is a Zip Archive. Open it?',\n                     'Open or Add Files?',\n                     MB_YESNO ) = IDYES ) then\n            AbZipOutline1.FileName := ZipName\n        else begin\n          if AbZipOutline1.FileName <> '' then begin\n            for i := 0 to pred( Items.Count ) do\n              if FileListBox1.Selected[i] then\n                AbZipOutline1.AddFiles( Directory + '\\' + Items[i], 0 );\n          end\n          else begin\n            if OpenDialog1.Execute then begin\n              AbZipOutline1.FileName := OpenDialog1.FileName;\n              for j := 0 to pred( Items.Count ) do\n                if FileListBox1.Selected[j] then\n                  AbZipOutline1.AddFiles( Directory + '\\' + Items[j], 0 )\n            end;\n          end;\n        end;\n      end;\nend;\n\nprocedure TForm1.AbZipOutline1DblClick(Sender: TObject);\nvar\n  Restoring : Boolean;\n  zFileName : array[0..79] of Char;\n  TempDir, SaveDir : string;\n  TempPath : array [0..255] of Char;\n  TempName : string;\nbegin\n  GetTempPath( sizeof( TempPath ), TempPath );\n  SaveDir := StrPas( TempPath );\n  if SaveDir[Length(SaveDir)] = '\\' then\n    Delete( SaveDir, Length(SaveDir), 1 );\n  StrPCopy( TempPath, SaveDir );\n\n  with AbZipOutline1 do begin\n    if SelectedZipItem <> nil then begin\n      TempDir := BaseDirectory;\n      Restoring := eoRestorePath in ExtractOptions;\n      ExtractOptions := ExtractOptions - [eoRestorePath];\n      BaseDirectory := SaveDir;\n      try\n        ExtractFiles( SelectedZipItem.FileName );\n        TempName := SelectedZipItem.FileName;\n        AbUnfixName( TempName );\n        ShellExecute( Application.MainForm.Handle, nil,\n                      StrPCopy( zFileName, ExtractFileName( TempName ) ),\n                      '', TempPath, SW_SHOWNORMAL );\n      finally\n        BaseDirectory := TempDir;\n        if Restoring then\n          ExtractOptions := ExtractOptions + [eoRestorePath];\n      end;\n    end;\n  end;\nend;\n\nprocedure TForm1.AbZipOutline1MouseDown(Sender: TObject;\n  Button: TMouseButton; Shift: TShiftState; X, Y: Integer);\nvar\n  i : Integer;\n  PS, PC : TPoint;\nbegin\n  if Button = mbLeft then begin\n    OutlineX := X;\n    OutlineY := Y;\n  end\n  else if Button = mbRight then begin\n    {enable appropriate popup menu items.}\n    {prepare popup menu}\n    if AbZipOutline1.Count > 0 then begin\n      {there are items in the outline - select the item under the mouse}\n      i := AbZipOutline1.GetOutlineItem( X, Y );\n      if i <> -1 then\n        AbZipOutline1.SelectedItem := i;\n    end;\n    if AbZipOutline1.SelectedZipItem <> nil then begin\n      PC.X := X;\n      PC.Y := Y;\n      PS := AbZipOutline1.ClientToScreen( PC );\n      AbZipOutline1.PopupMenu.Popup( PS.X, PS.Y );\n    end;\n  end;\nend;\n\nprocedure TForm1.FileListBox1DragOver(Sender, Source: TObject; X,\n  Y: Integer; State: TDragState; var Accept: Boolean);\nbegin\n  Accept := Source is TAbZipOutline;\nend;\n\nprocedure TForm1.FileListBox1DragDrop(Sender, Source: TObject; X,\n  Y: Integer);\nvar\n  TempDir : string;\nbegin\n  if Source is TAbZipOutline then\n    with (Source as TAbZipOutline ) do begin\n      TempDir := BaseDirectory;\n      BaseDirectory := FileListBox1.Directory;\n      try\n        ExtractFiles( SelectedZipItem.FileName );\n        FileListBox1.Update;\n      finally\n        BaseDirectory := TempDir;\n      end;\n    end;\nend;\n\nprocedure TForm1.AbZipOutline1WindowsDrop(Sender: TObject;\n  FileName: string);\nvar\n  ZB : TAbZipBrowser;\n  IsZip : Boolean;\nbegin\n  IsZip := False;\n  ZB := TAbZipBrowser.Create( Self );\n  try\n    try\n      ZB.FileName := FileName;\n      IsZip := True;\n    except\n    end;\n  finally\n    ZB.Free;\n  end;\n\n  if IsZip and ( AbZipOutline1.FileName = '' ) then\n    AbZipOutline1.FileName := FileName\n  else if AbZipOutline1.FileName = '' then begin\n    if OpenDialog1.Execute then begin\n      AbZipOutline1.FileName := OpenDialog1.FileName;\n      AbZipOutline1.AddFiles( FileName, 0 );\n    end;\n  end\n  else begin\n    {This is a Zip file, but there's already an open archive}\n    if Application.MessageBox( 'Open this file as an archive?',\n                   'Open or Add File', MB_YESNO ) = IDYES then\n      AbZipOutline1.FileName := FileName\n    else\n      AbZipOutline1.AddFiles( FileName, 0 );\n  end;\nend;\n\nprocedure TForm1.Best1Click(Sender: TObject);\nvar\n  Item : TMenuItem;\nbegin\n  Store1.Checked := False;\n  Deflate1.Checked := False;\n  Best1.Checked := False;\n  Item := (Sender as TMenuItem);\n  Item.Checked := True;\n  AbZipOutline1.CompressionMethodToUse := TAbZipSupportedMethod( Item.Tag );\nend;\n\nprocedure TForm1.SuperFast1Click(Sender: TObject);\nvar\n  Item : TMenuItem;\nbegin\n  Normal1.Checked := False;\n  Maximum1.Checked := False;\n  Fast1.Checked := False;\n  SuperFast1.Checked := False;\n  Item := (Sender as TMenuItem);\n  Item.Checked := True;\n  AbZipOutline1.DeflationOption := TAbZipDeflationOption( Item.Tag );\nend;\n\nprocedure TForm1.CreateDirs1Click(Sender: TObject);\nvar\n  Item : TMenuItem;\nbegin\n  Item := Sender as TMenuItem;\n  Item.Checked := not Item.Checked;\n  if Item.Checked then\n    AbZipOutline1.ExtractOptions := AbZipOutline1.ExtractOptions +\n                                    [eoCreateDirs]\n  else\n    AbZipOutline1.ExtractOptions := AbZipOutline1.ExtractOptions -\n                                    [eoCreateDirs];\nend;\n\nprocedure TForm1.RestorePath1Click(Sender: TObject);\nvar\n  Item : TMenuItem;\nbegin\n  Item := Sender as TMenuItem;\n  Item.Checked := not Item.Checked;\n  if Item.Checked then\n    AbZipOutline1.ExtractOptions := AbZipOutline1.ExtractOptions +\n                                    [eoRestorePath]\n  else\n    AbZipOutline1.ExtractOptions := AbZipOutline1.ExtractOptions -\n                                    [eoRestorePath];\nend;\n\nprocedure TForm1.StripPath1Click(Sender: TObject);\nvar\n  Item : TMenuItem;\nbegin\n  Item := Sender as TMenuItem;\n  Item.Checked := not Item.Checked;\n  if Item.Checked then\n    AbZipOutline1.StoreOptions := AbZipOutline1.StoreOptions +\n                                  [TAbStoreOption(Item.Tag)]\n  else\n    AbZipOutline1.StoreOptions := AbZipOutline1.StoreOptions -\n                                  [TAbStoreOption(Item.Tag)];\nend;\n\nprocedure TForm1.AbZipOutline1Change(Sender: TObject);\nbegin\n  if AbZipOutline1.FileName <> '' then\n    ArchiveLabel.Caption := Format( 'Archive %s contains %d items.',\n                              [AbZipOutline1.FileName, AbZipOutline1.Count] )\n  else\n    ArchiveLabel.Caption := 'No Archive Open';\nend;\n\nprocedure TForm1.Confirmations1Click(Sender: TObject);\nbegin\n  Confirmations1.Checked := not Confirmations1.Checked;\n  SpeedButton7.Down := Confirmations1.Checked;\nend;\n\nprocedure TForm1.DoConfirm( Sender : TObject; Item : TAbArchiveItem;\n                            var Confirm : Boolean; Caption : string );\nvar\n  pMessage : array [0..255] of Char;\n  pCaption : array [0..80] of Char;\nbegin\n  if Confirmations1.Checked then\n    Confirm :=  MessageBox( 0,\n                            StrPCopy( pMessage,\n                                      Format( '%s %s?',\n                                      [Caption, Item.FileName] ) ),\n                            StrPCopy( pCaption, 'Confirmation' ),\n                            MB_ICONQUESTION or MB_OKCANCEL ) = IDOK;\nend;\n\nprocedure TForm1.AbZipOutline1ConfirmSave(Sender: TObject;\n  var Confirm: Boolean);\nvar\n  pMessage : array [0..255] of Char;\n  pCaption : array [0..80] of Char;\nbegin\n  if Confirmations1.Checked then\n    Confirm :=  MessageBox( 0,\n                            StrPCopy( pMessage,\n                                      Format( 'Save %s?',\n                                      [TAbZipOutline(Sender).FileName] ) ),\n                            StrPCopy( pCaption, 'Confirmation' ),\n                            MB_ICONQUESTION or MB_OKCANCEL ) = IDOK;\nend;\n\nprocedure TForm1.Delete1Click(Sender: TObject);\nbegin\n  if AbZipOutline1.SelectedZipItem <> nil then\n    with AbZipOutline1 do begin\n      AbZipOutline1.ClearTags;\n      SelectedZipItem.Tagged := True;\n      try\n        DeleteTaggedItems;\n      finally\n        ClearTags;\n      end;\n    end;\nend;\n\nprocedure TForm1.Extract1Click(Sender: TObject);\nbegin\n  if AbZipOutline1.SelectedZipItem <> nil then begin\n    BaseDirDlg := TBaseDirDlg.Create( Application );\n    try\n      with BaseDirDlg, AbZipOutline1 do begin\n        Caption := 'Extract Selected File';\n        Edit1.Text := SelectedZipItem.FileName;\n        Edit1.Enabled := False;\n        ActionLabel.Caption := 'Target Directory:';\n        if BaseDirectory <> '' then\n          DLB.Directory := BaseDirectory;\n        CheckBox1.Caption := 'Restore Path';\n        CheckBox1.Checked := eoRestorePath in ExtractOptions;\n        CheckBox2.Caption := 'Create Directories';\n        CheckBox2.Checked := eoCreateDirs in ExtractOptions;\n        ShowModal;\n        if ModalResult = mrOK then begin\n          BaseDirectory := DirLabel.Caption;\n          if CheckBox1.Checked then\n            ExtractOptions := ExtractOptions + [eoRestorePath]\n          else\n            ExtractOptions := ExtractOptions - [eoRestorePath];\n          if CheckBox2.Checked then\n            ExtractOptions := ExtractOptions + [eoCreateDirs]\n          else\n            ExtractOptions := ExtractOptions - [eoCreateDirs];\n          ClearTags;\n          SelectedZipItem.Tagged := True;\n          try\n            ExtractTaggedItems;\n          finally\n            ClearTags;\n          end;\n          FileListBox1.Update;\n        end;\n      end;\n    finally\n      BaseDirDlg.Free;\n    end;\n  end;\nend;\n\nprocedure TForm1.Freshen1Click(Sender: TObject);\nbegin\n  if AbZipOutline1.SelectedZipItem <> nil then begin\n    BaseDirDlg := TBaseDirDlg.Create( Application );\n    try\n      with BaseDirDlg, AbZipOutline1 do begin\n        Caption := 'Freshen Selected File';\n        Edit1.Text := SelectedZipItem.FileName;\n        Edit1.Enabled := False;\n        ActionLabel.Caption := 'Source Directory:';\n        if BaseDirectory <> '' then\n          DLB.Directory := BaseDirectory;\n        CheckBox1.Caption := 'Recurse';\n        CheckBox1.Checked := soRecurse in StoreOptions;\n        CheckBox2.Caption := 'Strip Path';\n        CheckBox2.Checked := soStripPath in StoreOptions;\n\n        ShowModal;\n        if ModalResult = mrOK then begin\n          if CheckBox1.Checked then\n            StoreOptions := StoreOptions + [soRecurse]\n          else\n            StoreOptions := StoreOptions - [soRecurse];\n          if CheckBox2.Checked then\n            StoreOptions := StoreOptions + [soStripPath]\n          else\n            StoreOptions := StoreOptions - [soStripPath];\n          BaseDirectory := DirLabel.Caption;\n\n          ClearTags;\n          SelectedZipItem.Tagged := True;\n          try\n            FreshenTaggedItems;\n          finally\n            ClearTags;\n          end;\n          FileListBox1.Update;\n        end;\n      end;\n    finally\n      BaseDirDlg.Free;\n    end;\n  end;\nend;\n\nprocedure TForm1.Move1Click(Sender: TObject);\nbegin\n  DemoDlg := TDemoDlg.Create( Application );\n  try\n    with DemoDlg do begin\n      Caption := 'Move File to New Path';\n      Edit1.Text := AbZipOutline1.SelectedZipItem.FileName;\n      ShowModal;\n      if ModalResult = mrOK then\n        AbZipOutline1.Move( AbZipOutline1.SelectedZipItem, Edit1.Text );\n    end;\n  finally\n    DemoDlg.Free;\n  end;\nend;\n\nprocedure TForm1.Password1Click(Sender: TObject);\nvar\n  Dlg : TPassWordDlg;\nbegin\n  Dlg := TPassWordDlg.Create( Application );\n  try\n    Dlg.Edit1.Text := string(AbZipOutline1.Password);\n    Dlg.ShowModal;\n    if Dlg.ModalResult = mrOK then\n      AbZipOutline1.Password := AnsiString(Dlg.Edit1.Text);\n  finally\n    Dlg.Free;\n  end;\n  if Length( AbZipOutline1.Password ) > 0 then\n    Image1.Visible := True\n  else\n    Image1.Visible := False;\nend;\n\nprocedure TForm1.AddFiles1Click(Sender: TObject);\nbegin\n  BaseDirDlg := TBaseDirDlg.Create( Application );\n  try\n    with BaseDirDlg, AbZipOutline1 do begin\n      Caption := 'Add Files with FileMask';\n      Edit1.Text := '*.*';\n      ActionLabel.Caption := 'Source Directory';\n      CheckBox1.Caption := 'Recurse';\n      CheckBox1.Checked := soRecurse in StoreOptions;\n      CheckBox2.Caption := 'Strip Path';\n      CheckBox2.Checked := soStripPath in StoreOptions;\n\n      if BaseDirectory <> '' then\n        DLB.Directory := BaseDirectory;\n\n      ShowModal;\n      if ModalResult = mrOK then begin\n        if CheckBox1.Checked then\n          StoreOptions := StoreOptions + [soRecurse]\n        else\n          StoreOptions := StoreOptions - [soRecurse];\n        if CheckBox2.Checked then\n          StoreOptions := StoreOptions + [soStripPath]\n        else\n          StoreOptions := StoreOptions - [soStripPath];\n        BaseDirectory := DirLabel.Caption;\n        AddFiles( Edit1.Text, 0 );\n      end;\n    end;\n  finally\n    BaseDirDlg.Free;\n  end;\nend;\n\nprocedure TForm1.FreshenFiles1Click(Sender: TObject);\nbegin\n  BaseDirDlg := TBaseDirDlg.Create( Application );\n  try\n    with BaseDirDlg, AbZipOutline1 do begin\n      Caption := 'Freshen Files with FileMask';\n      Edit1.Text := '*.*';\n      ActionLabel.Caption := 'Source Directory';\n      CheckBox1.Caption := 'Recurse';\n      CheckBox1.Checked := soRecurse in StoreOptions;\n      CheckBox2.Caption := 'Strip Path';\n      CheckBox2.Checked := soStripPath in StoreOptions;\n      if BaseDirectory <> '' then\n        DLB.Directory := BaseDirectory;\n\n      ShowModal;\n      if ModalResult = mrOK then begin\n        if CheckBox1.Checked then\n          StoreOptions := StoreOptions + [soRecurse]\n        else\n          StoreOptions := StoreOptions - [soRecurse];\n        if CheckBox2.Checked then\n          StoreOptions := StoreOptions + [soStripPath]\n        else\n          StoreOptions := StoreOptions - [soStripPath];\n        BaseDirectory := DirLabel.Caption;\n        FreshenFiles( Edit1.Text );\n      end;\n    end;\n  finally\n    BaseDirDlg.Free;\n  end;\nend;\n\nprocedure TForm1.SelectBaseDirectory1Click(Sender: TObject);\nbegin\n  with TAbDirDlg.Create(Self) do begin\n    Caption := 'Directory';\n    AdditionalText := 'Select folder to extract into';\n    if Execute then\n      AbZipOutline1.BaseDirectory := SelectedFolder;\n    Free;\n  end;\nend;\n\nprocedure TForm1.AbZipOutline1ArchiveItemProgress(Sender: TObject;\n  Item: TAbArchiveItem; Progress: Byte; var Abort: Boolean);\nvar\n  ActionString : string;\nbegin\n  case Item.Action of\n    aaAdd : ActionString := 'Adding  ';\n    aaFreshen : ActionString := 'Freshening  ';\n  else\n    ActionString :='Extracting  ';\n  end;\n  Panel5.Caption := ActionString + Item.FileName + '   ';\n  if Progress = 100 then begin\n    Panel5.Caption := 'Finished   ';\n  end;\nend;\n\nprocedure TForm1.AbZipOutline1NeedPassword(Sender: TObject;\n  var NewPassword: AnsiString);\nvar\n  Dlg : TPassWordDlg;\nbegin\n  Dlg := TPassWordDlg.Create( Application );\n  try\n    Dlg.ShowModal;\n    if Dlg.ModalResult = mrOK then\n      NewPassword := AnsiString(Dlg.Edit1.Text);\n  finally\n    Dlg.Free;\n  end;\n  if Length( NewPassword ) > 0 then\n    Image1.Visible := True;\nend;\n\nprocedure TForm1.DeleteFiles1Click(Sender: TObject);\nbegin\n  DemoDlg := TDemoDlg.Create( Application );\n  try\n    with DemoDlg do begin\n      Caption := 'Delete Files with FileMask';\n      Edit1.Text := '*.*';\n      ShowModal;\n      if ModalResult = mrOK then\n        AbZipOutline1.DeleteFiles( Edit1.Text );\n    end;\n  finally\n    DemoDlg.Free;\n  end;\nend;\n\nprocedure TForm1.ExtractFiles1Click(Sender: TObject);\nbegin\n  BaseDirDlg := TBaseDirDlg.Create( Application );\n  try\n    with BaseDirDlg, AbZipOutline1 do begin\n      Caption := 'Extract Files with FileMask';\n      Edit1.Text := '*.*';\n      ActionLabel.Caption := 'Target Directory:';\n      if BaseDirectory <> '' then\n        DLB.Directory := BaseDirectory;\n      CheckBox1.Caption := 'Restore Path';\n      CheckBox1.Checked := eoRestorePath in ExtractOptions;\n      CheckBox2.Caption := 'Create Directories';\n      CheckBox2.Checked := eoCreateDirs in ExtractOptions;\n      ShowModal;\n      if ModalResult = mrOK then begin\n        BaseDirectory := BaseDirDlg.DLB.Directory;\n        if CheckBox1.Checked then\n          ExtractOptions := ExtractOptions + [eoRestorePath]\n        else\n          ExtractOptions := ExtractOptions - [eoRestorePath];\n        if CheckBox2.Checked then\n          ExtractOptions := ExtractOptions + [eoCreateDirs]\n        else\n          ExtractOptions := ExtractOptions - [eoCreateDirs];\n        ExtractFiles( Edit1.Text );\n        FileListBox1.Update;\n      end;\n    end;\n  finally\n    BaseDirDlg.Free;\n  end;\nend;\n\nprocedure TForm1.FormDestroy(Sender: TObject);\nbegin\n  AbZipOutline1.Save;\n  SaveIniSettings;\nend;\n\nprocedure TForm1.ReadIniSettings;\nvar\n  Value : Integer;\n  Exists : Boolean;\nbegin\n  with TIniFile.Create( ChangeFileExt( Application.ExeName, '.INI' ) ) do begin\n    try\n      {view menu}\n      Exists := ReadBool( 'General', 'Exists', False );\n      if Exists then begin\n        AbZipOutline1.Attributes := [];\n        if ReadBool( 'View', 'CSize', False ) then\n          AbZipOutline1.Attributes := AbZipOutline1.Attributes +\n                                      [zaCompressedSize];\n        if ReadBool( 'View', 'CMethod', False ) then\n          AbZipOutline1.Attributes := AbZipOutline1.Attributes +\n                                      [zaCompressionMethod];\n        if ReadBool( 'View', 'CRatio', False ) then\n          AbZipOutline1.Attributes := AbZipOutline1.Attributes +\n                                      [zaCompressionRatio];\n        if ReadBool( 'View', 'CRC', False ) then\n          AbZipOutline1.Attributes := AbZipOutline1.Attributes +\n                                      [zaCRC];\n        if ReadBool( 'View', 'EFA', False ) then\n          AbZipOutline1.Attributes := AbZipOutline1.Attributes +\n                                      [zaExternalFileAttributes];\n        if ReadBool( 'View', 'IFA', False ) then\n          AbZipOutline1.Attributes := AbZipOutline1.Attributes +\n                                      [zaInternalFileAttributes];\n        if ReadBool( 'View', 'Encryption', False ) then\n          AbZipOutline1.Attributes := AbZipOutline1.Attributes +\n                                      [zaEncryption];\n        if ReadBool( 'View', 'TimeStamp', False ) then\n          AbZipOutline1.Attributes := AbZipOutline1.Attributes +\n                                      [zaTimeStamp];\n        if ReadBool( 'View', 'USize', False ) then\n          AbZipOutline1.Attributes := AbZipOutline1.Attributes +\n                                      [zaUnCompressedSize];\n        if ReadBool( 'View', 'MadeBy', False ) then\n          AbZipOutline1.Attributes := AbZipOutline1.Attributes +\n                                      [zaVersionMade];\n        if ReadBool( 'View', 'Needed', False ) then\n          AbZipOutline1.Attributes := AbZipOutline1.Attributes +\n                                      [zaVersionNeeded];\n        if ReadBool( 'View', 'Comment', False ) then\n          AbZipOutline1.Attributes := AbZipOutline1.Attributes +\n                                      [zaComment];\n\n        AbZipOutline1.Hierarchy := ReadBool( 'View', 'Hierarchy', True );\n\n//        Value := ReadInteger( 'View', 'OutlineStyle', -1 );\n//        if Value <> -1 then\n//          AbZipOutline1.OutlineStyle := TOutlineStyle( Value );\n        {preferences menu}\n        AbZipOutline1.BaseDirectory := ReadString( 'Preferences',\n                                       'BaseDirectory',\n                                       ExtractFilePath( Application.ExeName ) );\n        if not DirectoryExists( AbZipOutline1.BaseDirectory ) then\n          AbZipOutline1.BaseDirectory := ExtractFilePath( Application.ExeName );\n        Confirmations1.Checked := ReadBool( 'Preferences',\n                                            'Confirmations', False );\n        SpeedButton7.Down := Confirmations1.Checked;\n        Value := ReadInteger( 'Preferences',\n                              'CompressionMethodToUse',\n                              Ord( smBestMethod ) );\n        AbZipOutline1.CompressionMethodToUse := TAbZipSupportedMethod( Value );\n        Value := ReadInteger( 'Preferences', 'DeflationOption', Ord( doNormal));\n        AbZipOutline1.DeflationOption := TAbZipDeflationOption( Value );\n        AbZipOutline1.ExtractOptions := [];\n        if ReadBool( 'Preferences', 'CreateDirs', False ) then\n          AbZipOutline1.ExtractOptions := AbZipOutline1.ExtractOptions +\n                                          [eoCreateDirs];\n        if ReadBool( 'Preferences', 'RestorePath', False ) then\n          AbZipOutline1.ExtractOptions := AbZipOutline1.ExtractOptions +\n                                          [eoRestorePath];\n        AbZipOutline1.StoreOptions := [];\n        if ReadBool( 'Preferences', 'StripPath', False ) then\n          AbZipOutline1.StoreOptions := AbZipOutline1.StoreOptions +\n                                        [soStripPath];\n        if ReadBool( 'Preferences', 'RemoveDots', False ) then\n          AbZipOutline1.StoreOptions := AbZipOutline1.StoreOptions +\n                                        [soRemoveDots];\n        if ReadBool( 'Preferences', 'Recurse', False ) then\n          AbZipOutline1.StoreOptions := AbZipOutline1.StoreOptions +\n                                        [soRecurse];\n        StubName := ReadString( 'Self Extracting', 'StubName', 'selfex.exe' );\n        FilterComboBox1.Filter := ReadString( 'Navigator', 'Filter',\n        'All files (*.*)|*.*|Zip Files (*.ZIP)|*.ZIP|' +\n        'Executable Files (*.EXE)|*.EXE|Text files (*.TXT)|*.TXT|' +\n        'Pascal files (*.PAS)|*.PAS' );\n      end;\n    finally\n      Free;\n    end;\n  end;\nend;\n\nprocedure TForm1.SaveIniSettings;\nbegin\n  with TIniFile.Create( ChangeFileExt( Application.ExeName, '.INI' ) ) do begin\n    try\n      {view menu}\n      WriteBool( 'General', 'Exists', True );\n      with AbZipOutline1 do begin\n        WriteBool( 'View', 'CSize', zaCompressedSize in Attributes );\n        WriteBool( 'View', 'CMethod', zaCompressionMethod in Attributes );\n        WriteBool( 'View', 'CRatio', zaCompressionRatio in Attributes );\n        WriteBool( 'View', 'CRC', zaCRC in Attributes );\n        WriteBool( 'View', 'EFA', zaExternalFileAttributes in Attributes );\n        WriteBool( 'View', 'IFA', zaInternalFileAttributes in Attributes );\n        WriteBool( 'View', 'Encryption', zaEncryption in Attributes );\n        WriteBool( 'View', 'TimeStamp', zaTimeStamp in Attributes );\n        WriteBool( 'View', 'USize', zaUnCompressedSize in Attributes );\n        WriteBool( 'View', 'MadeBy', zaVersionMade in Attributes );\n        WriteBool( 'View', 'Needed', zaVersionNeeded in Attributes );\n        WriteBool( 'View', 'Comment', zaComment in Attributes );\n\n        WriteBool( 'View', 'Hierarchy', Hierarchy );\n//        WriteInteger( 'View', 'OutlineStyle', Ord( OutlineStyle ) );\n        {preferences menu}\n        WriteString( 'Preferences', 'BaseDirectory', BaseDirectory );\n        WriteBool( 'Preferences', 'Confirmations', Confirmations1.Checked );\n        WriteInteger( 'Preferences', 'CompressionMethodToUse',\n                      Ord( CompressionMethodToUse ) );\n        WriteInteger( 'Preferences', 'DeflationOption',\n                      Ord( DeflationOption ));\n\n        WriteBool( 'Preferences', 'CreateDirs',\n                   eoCreateDirs in ExtractOptions );\n        WriteBool( 'Preferences', 'RestorePath',\n                   eoRestorePath in ExtractOptions );\n        WriteBool( 'Preferences', 'StripPath', soStripPath in StoreOptions );\n        WriteBool( 'Preferences', 'RemoveDots', soRemoveDots in StoreOptions );\n        WriteBool( 'Preferences', 'Recurse', soRecurse in StoreOptions );\n      end;\n    finally\n      Free;\n    end;\n  end;\nend;\n\nprocedure TForm1.Close1Click(Sender: TObject);\nbegin\n  AbZipOutline1.FileName := '';\n  AbZipOutline1.Color := clBtnFace;\nend;\n\nprocedure TForm1.AbZipOutline1Load(Sender: TObject);\nbegin\n  IgnoreDuplicateWarning := False;\n  AbZipOutline1.Color := clWindow;\n  SetCaption;\nend;\n\nprocedure TForm1.Convert1Click(Sender: TObject);\nvar\n  ZipName : string;\n  ExeName : string;\n  StubSpec : string;\n  StubStream, ZipStream, SelfExtractingStream : TStream;\nbegin\n  AbZipOutline1.Save;\n  ZipName := ExpandFileName( AbZipOutline1.FileName );\n  AbZipOutline1.FileName := '';\n\n  ExeName := ChangeFileExt( ZipName, '.exe' );\n  StubSpec := ExtractFilePath( Application.ExeName ) + StubName;\n\n  StubStream := TFileStream.Create( StubSpec, fmOpenRead or fmShareDenyWrite );\n  ZipStream := TFileStream.Create( ZipName , fmOpenRead or fmShareDenyWrite );\n  SelfExtractingStream := TFileStream.Create( ExeName,\n                                              fmCreate or fmShareExclusive );\n  try\n    MakeSelfExtracting( StubStream, ZipStream, SelfExtractingStream );\n  finally\n    SelfExtractingStream.Free;\n    StubStream.Free;\n    ZipStream.Free;\n  end;\n  {and reload...}\n  AbZipOutline1.FileName := ExeName;\nend;\n\nprocedure TForm1.GetMinMaxInfo( var Msg: TWMGetMinMaxInfo );\nbegin\n  with Msg.MinMaxInfo^ do begin\n    ptMinTrackSize := Point( 700, 400 );\n    ptMaxTrackSize := Point( 1600, 1200 );\n  end;\nend;\n\nprocedure TForm1.AbZipOutline1ConfirmOverwrite(var Name: string;\n  var Confirm: Boolean);\nvar\n  pMessage : array [0..255] of Char;\n  pCaption : array [0..80] of Char;\nbegin\n  Confirm :=  MessageBox( 0,\n                          StrPCopy( pMessage,\n                                    Format( 'Overwrite %s?',\n                                    [Name] ) ),\n                          StrPCopy( pCaption, 'Confirmation' ),\n                          MB_ICONQUESTION or MB_OKCANCEL ) = IDOK;\nend;\n\nprocedure TForm1.Default1Click(Sender: TObject);\nvar\n  i : Integer;\nbegin\n  AbZipOutline1.Attributes := AbDefZipAttributes;\n  for i := 0 to Ord( High( TAbZipAttribute ) ) do\n    Attributes1.Items[i].Checked := TAbZipAttribute(i) in AbDefZipAttributes;\n  AbZipOutline1.Update;\nend;\n\nprocedure TForm1.Contents1Click(Sender: TObject);\nbegin\n  Application.HelpCommand(HELP_CONTENTS, 0);\nend;\n\nprocedure TForm1.About1Click(Sender: TObject);\nbegin\n  dlgAboutBox := TDlgAboutBox.Create( Self );\n  try\n    dlgAboutBox.ShowModal;\n  finally\n    dlgAboutBox.Free;\n  end;\nend;\n\nprocedure TForm1.FileListBox1DblClick(Sender: TObject);\nvar\n  Browser : TAbZipBrowser;\n  Filename : string;\n  OK : Boolean;\nbegin\n  Filename := IncludeTrailingPathDelimiter(DirectoryListBox1.Directory) +\n    FileListBox1.Items[FileListBox1.ItemIndex];\n  if AbZipOutline1.FileName = '' then\n    try\n      AbZipOutline1.FileName := Filename;\n    except\n      AbZipOutline1.FileName := '';\n    end\n  else begin\n    Browser := TAbZipBrowser.Create( Self );\n    OK := True;\n    try\n      try\n        Browser.FileName := Filename;\n      except\n        OK := False;\n      end;\n    finally\n      Browser.Free;\n    end;\n    if OK then\n      AbZipOutline1.FileName := Filename;\n  end;\nend;\n\nprocedure TForm1.AbZipOutline1EndDrag(Sender, Target: TObject; X,\n  Y: Integer);\nbegin\n  FileListBox1.Update;\nend;\n\nprocedure TForm1.FileListBox1MouseDown(Sender: TObject;\n  Button: TMouseButton; Shift: TShiftState; X, Y: Integer);\nbegin\n  if Button = mbLeft then begin\n    FileX := X;\n    FileY := Y;\n  end;\nend;\n\nprocedure TForm1.FileListBox1MouseMove(Sender: TObject; Shift: TShiftState;\n  X, Y: Integer);\nbegin\n  if ssLeft in Shift then\n    if ( ( X - FileX ) * ( X - FileX ) +\n         ( Y - FileY ) * ( Y - FileY ) > 100 ) then\n      if FileListBox1.SelCount > 0 then\n        if ( not FileListBox1.Dragging ) then\n          FileListBox1.BeginDrag( True );\nend;\n\nprocedure TForm1.AbZipOutline1MouseMove(Sender: TObject;\n  Shift: TShiftState; X, Y: Integer);\nbegin\n  if ssLeft in Shift then\n    if ( ( X - OutlineX ) * ( X - OutlineX ) +\n         ( Y - OutlineY ) * ( Y - OutlineY ) > 100 ) then\n      if AbZipOutline1.SelectedZipItem <> nil then\n        if ( not FileListBox1.Dragging ) then\n          AbZipOutline1.BeginDrag( True );\nend;\n\nprocedure TForm1.Edit1Exit(Sender: TObject);\nbegin\n  FileListBox1.ApplyFilePath(Edit1.Text);\nend;\n\nprocedure TForm1.FormKeyPress(Sender: TObject; var Key: Char);\nbegin\n  if Key = #13 then\n    Edit1Exit( Self );\nend;\n\nprocedure TForm1.OS5Click(Sender: TObject);\nvar\n  Item : TMenuItem;\nbegin\n  OS1.Checked := False;\n  OS2.Checked := False;\n  OS3.Checked := False;\n  OS4.Checked := False;\n  OS5.Checked := False;\n  OS6.Checked := False;\n\n  Item := (Sender as TMenuItem);\n  Item.Checked := True;\n//  AbZipOutline1.OutlineStyle := TOutlineStyle( Item.Tag );\nend;\n\nprocedure TForm1.AbZipOutline1ConfirmProcessItem(Sender: TObject;\n  Item: TAbArchiveItem; ProcessType: TAbProcessType;\n  var Confirm: Boolean);\nvar\n  Process : string;\nbegin\n  Confirm := True;\n  case ProcessType of\n    ptAdd : Process := 'Add';\n    ptDelete : Process := 'Delete';\n    ptExtract : Process := 'Extract';\n    ptFreshen : Process := 'Freshen';\n    ptMove : Process := 'Move';\n  end;\n  DoConfirm( Sender, Item, Confirm, Process );\nend;\n\nprocedure TForm1.AbZipOutline1ProcessItemFailure(Sender: TObject;\n  Item: TAbArchiveItem; const ProcessType: TAbProcessType;\n  ErrorClass: TAbErrorClass; ErrorCode: Integer);\nvar\n  S : string;\n  pMessage : array [0..128] of Char;\nbegin\n  if ( ErrorClass = ecAbbrevia ) and\n     ( ErrorCode = AbDuplicateName ) then begin\n    if not IgnoreDuplicateWarning then begin\n      if ProcessType = ptAdd then\n        s := 'Cannot add '\n      else\n        s := 'Cannot move ';\n      s := s + Item.FileName +\n           '. Would create a duplicate name. Ignore future warnings?';\n      if (Application.MessageBox( StrPCopy( pMessage, s ), 'Warning',\n         MB_YESNO ) = IDYES ) then\n        IgnoreDuplicateWarning := True;\n    end;\n    Exit;\n  end;\n\n  case ProcessType of\n    ptAdd :\n      ShowMessage( 'Cannot add ' + Item.FileName + ' to ' +\n                   TAbZipOutline(Sender).FileName );\n    ptExtract :\n      ShowMessage( 'Cannot extract ' + Item.FileName + ' from ' +\n                   TAbZipOutline(Sender).FileName );\n    ptFreshen :\n      ShowMessage( 'Cannot freshen ' + Item.FileName + ' in ' +\n                   TAbZipOutline(Sender).FileName );\n    ptMove :\n      ShowMessage( 'Cannot move ' + Item.FileName + ' to ' +\n                   TAbZipOutline(Sender).FileName );\n  end;\n  if ErrorClass = ecAbbrevia then\n    ShowMessage( AbStrRes(ErrorCode) );\nend;\n\nprocedure TForm1.TurboPowerontheWeb1Click(Sender: TObject);\nbegin\n  if ShellExecute(0, 'open', 'http://www.turbopower.com', '', '', SW_SHOWNORMAL) <= 32 then\n    ShowMessage('Unable to start web browser. Make sure you have it properly set-up on your system.');\nend;\n\nprocedure TForm1.AbbreviaontheWeb1Click(Sender: TObject);\nbegin\n  if ShellExecute(0, 'open', 'http://sf.net/projects/tpabbrevia', '', '', SW_SHOWNORMAL) <= 32 then\n    ShowMessage('Unable to start web browser. Make sure you have it properly set-up on your system.');\nend;\n\nprocedure TForm1.TempDirectory1Click(Sender: TObject);\nbegin\n  with TAbDirDlg.Create(Self) do begin\n    Caption := 'Directory';\n    AdditionalText := 'Select temporary directory';\n    if Execute then\n      AbZipOutline1.TempDirectory := SelectedFolder;\n    Free;\n  end;\nend;\n\nprocedure TForm1.Logging1Click(Sender: TObject);\nvar\n  E, F : string;\nbegin\n  AbZipOutline1.Logging := False;\n  Logging1.Checked := not Logging1.Checked;\n  if Logging1.Checked then with OpenDialog1 do begin\n    Title := 'Select Text File for Logging';\n    E := DefaultExt;\n    DefaultExt := '';\n    F := Filter;\n    Filter := '';\n    Filename := AbZipOutline1.LogFile;\n    if Execute then begin\n      AbZipOutline1.LogFile := Filename;\n      AbZipOutline1.Logging := True;\n    end;\n    DefaultExt := E;\n    Filter := F;\n  end;\n  Logging1.Checked := AbZipOutline1.Logging;\nend;\n\nend.\n"
  },
  {
    "path": "lib/abbrevia/examples/Delphi/Uexample.pas",
    "content": "(* ***** BEGIN LICENSE BLOCK *****\n * Version: MPL 1.1\n *\n * The contents of this file are subject to the Mozilla Public License Version\n * 1.1 (the \"License\"); you may not use this file except in compliance with\n * the License. You may obtain a copy of the License at\n * http://www.mozilla.org/MPL/\n *\n * Software distributed under the License is distributed on an \"AS IS\" basis,\n * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License\n * for the specific language governing rights and limitations under the\n * License.\n *\n * The Original Code is TurboPower Abbrevia\n *\n * The Initial Developer of the Original Code is\n * TurboPower Software\n *\n * Portions created by the Initial Developer are Copyright (C) 1997-2002\n * the Initial Developer. All Rights Reserved.\n *\n * Contributor(s):\n *\n * ***** END LICENSE BLOCK ***** *)\n\n{*********************************************************}\n{* ABBREVIA: UEXAMPLE.PAS                                *}\n{* Copyright (c) TurboPower Software Co 1997             *}\n{* All rights reserved.                                  *}\n{*********************************************************}\n{* ABBREVIA Example program file                         *}\n{*********************************************************}\n\nunit uexample;\n\ninterface\n\nuses\n  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,\n  Menus, ExtCtrls, Gauges, StdCtrls,\n\n  AbZipOut, AbArcTyp, AbMeter, AbBase, AbUtils;\n\ntype\n  TForm1 = class(TForm)\n    BottomStatus: TPanel;\n    MainMenu1: TMainMenu;\n    File1: TMenuItem;\n    Open1: TMenuItem;\n    N1: TMenuItem;\n    Exit1: TMenuItem;\n    OpenDialog1: TOpenDialog;\n    TopStatus: TPanel;\n    PopupMenu1: TPopupMenu;\n    Add1: TMenuItem;\n    Delete1: TMenuItem;\n    Extract1: TMenuItem;\n    Freshen1: TMenuItem;\n    Move1: TMenuItem;\n    Panel1: TPanel;\n    Memo1: TMemo;\n    AbMeter1: TAbMeter;\n    AbMeter2: TAbMeter;\n    Label1: TLabel;\n    Label2: TLabel;\n    AbZipOutline1: TAbZipOutline;\n    procedure Open1Click(Sender: TObject);\n    procedure Exit1Click(Sender: TObject);\n    procedure AbZipOutline1Load(Sender: TObject);\n    procedure AbZipOutline1MouseDown(Sender: TObject; Button: TMouseButton;\n      Shift: TShiftState; X, Y: Integer);\n    procedure Delete1Click(Sender: TObject);\n    procedure Extract1Click(Sender: TObject);\n    procedure Freshen1Click(Sender: TObject);\n    procedure Add1Click(Sender: TObject);\n    procedure Move1Click(Sender: TObject);\n    procedure FormCreate(Sender: TObject);\n    procedure AbZipOutline1ProcessItemFailure(Sender: TObject;\n      Item: TAbArchiveItem; ProcessType: TAbProcessType;\n      ErrorClass: TAbErrorClass; ErrorCode: Integer);\n  private\n    { Private declarations }\n  public\n    { Public declarations }\n  end;\n\nvar\n  Form1: TForm1;\n\nimplementation\n\nuses udemodlg;\n\n{$R *.DFM}\n\nprocedure TForm1.Open1Click(Sender: TObject);\nbegin\n  if OpenDialog1.Execute then begin\n    AbZipOutline1.OpenArchive(OpenDialog1.FileName);\n  end;\nend;\n\nprocedure TForm1.Exit1Click(Sender: TObject);\nbegin\n  Close;\nend;\n\nprocedure TForm1.AbZipOutline1Load(Sender: TObject);\nbegin\n  TopStatus.Caption := '  ' + AbZipOutline1.FileName;\nend;\n\n\nprocedure TForm1.AbZipOutline1MouseDown(Sender: TObject;\n  Button: TMouseButton; Shift: TShiftState; X, Y: Integer);\nvar\n  i : LongInt;\nbegin\n  if Button = mbRight then begin\n    {prepare popup menu}\n    if AbZipOutline1.Count > 0 then begin\n      {there are items in the outline - select the item under the mouse}\n      i := AbZipOutline1.GetOutlineItem( X, Y );\n      if i <> -1 then\n        AbZipOutline1.SelectedItem := i;\n    end;\n    if AbZipOutline1.FileName <> '' then\n      Add1.Enabled := True\n    else\n      {archive has to be initialized before we can add to it}\n      Add1.Enabled := False;\n    if AbZipOutline1.SelectedZipItem <> nil then begin\n      {pointing at a file - allow file operations}\n      Delete1.Enabled := True;\n      Extract1.Enabled := True;\n      Freshen1.Enabled := True;\n      Move1.Enabled := True;\n    end\n    else begin\n      {pointing at a directory - don't allow file operations}\n      Delete1.Enabled := False;\n      Extract1.Enabled := False;\n      Freshen1.Enabled := False;\n      Move1.Enabled := False;\n    end;\n  end;\nend;\n\nprocedure TForm1.Delete1Click(Sender: TObject);\nbegin\n  AbZipOutline1.DeleteFiles(AbZipOutline1.SelectedZipItem.FileName);\nend;\n\nprocedure TForm1.Extract1Click(Sender: TObject);\nbegin\n  AbZipOutline1.ExtractFiles(AbZipOutline1.SelectedZipItem.FileName);\nend;\n\nprocedure TForm1.Freshen1Click(Sender: TObject);\nbegin\n  AbZipOutline1.FreshenFiles(AbZipOutline1.SelectedZipItem.FileName);\nend;\n\nprocedure TForm1.Add1Click(Sender: TObject);\nbegin\n  DemoDlg.Caption := 'Add Files with FileMask';\n  DemoDlg.Edit1.Text := '*.*';\n  DemoDlg.ShowModal;\n  if DemoDlg.ModalResult = mrOK then\n    AbZipOutline1.AddFiles(DemoDlg.Edit1.Text, 0);\nend;\n\nprocedure TForm1.Move1Click(Sender: TObject);\nbegin\n  DemoDlg.Caption := 'Move File to New Name';\n  DemoDlg.Edit1.Text := AbZipOutline1.SelectedZipItem.FileName;\n  DemoDlg.ShowModal;\n  if DemoDlg.ModalResult = mrOK then\n    AbZipOutline1.Move(AbZipOutline1.SelectedZipItem, DemoDlg.Edit1.Text);\nend;\n\nprocedure TForm1.FormCreate(Sender: TObject);\nbegin\n  AbZipOutline1.BaseDirectory := ExtractFilePath( Application.ExeName );\nend;\n\nprocedure TForm1.AbZipOutline1ProcessItemFailure(Sender: TObject;\n  Item: TAbArchiveItem; ProcessType: TAbProcessType;\n  ErrorClass: TAbErrorClass; ErrorCode: Integer);\nbegin\n  case ProcessType of\n    ptAdd : ShowMessage( 'Failed to add ' + Item.Filename );\n    ptExtract : ShowMessage('Failed to extract ' + Item.Filename);\n    ptFreshen : ShowMessage('Failed to freshen ' + Item.Filename);\n  end;\nend;\n\n\nend.\n"
  },
  {
    "path": "lib/abbrevia/examples/Delphi/Unzip.dpr",
    "content": "(* ***** BEGIN LICENSE BLOCK *****\n * Version: MPL 1.1\n *\n * The contents of this file are subject to the Mozilla Public License Version\n * 1.1 (the \"License\"); you may not use this file except in compliance with\n * the License. You may obtain a copy of the License at\n * http://www.mozilla.org/MPL/\n *\n * Software distributed under the License is distributed on an \"AS IS\" basis,\n * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License\n * for the specific language governing rights and limitations under the\n * License.\n *\n * The Original Code is TurboPower Abbrevia\n *\n * The Initial Developer of the Original Code is\n * TurboPower Software\n *\n * Portions created by the Initial Developer are Copyright (C) 1997-2002\n * the Initial Developer. All Rights Reserved.\n *\n * Contributor(s):\n *\n * ***** END LICENSE BLOCK ***** *)\n\n{*********************************************************}\n{* ABBREVIA: UNZIP.DPR                                   *}\n{*********************************************************}\n{* ABBREVIA Example program file                         *}\n{*********************************************************}\n\nprogram Unzip;\n\nuses\n  Forms,\n  Uunzip in 'Uunzip.pas' {Form1};\n\nbegin\n  Application.CreateForm(TForm1, Form1);\n  Application.Run;\nend.\n"
  },
  {
    "path": "lib/abbrevia/examples/Delphi/Unzip.dproj",
    "content": "﻿\t<Project xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n\t\t<PropertyGroup>\n\t\t\t<ProjectGuid>{4193EA89-8316-4EA6-824B-CD35E8A098C8}</ProjectGuid>\n\t\t\t<MainSource>Unzip.dpr</MainSource>\n\t\t\t<Base>True</Base>\n\t\t\t<Config Condition=\"'$(Config)'==''\">Debug</Config>\n\t\t\t<Platform>Win32</Platform>\n\t\t\t<AppType>Application</AppType>\n\t\t\t<FrameworkType>VCL</FrameworkType>\n\t\t\t<DCC_DCCCompiler>DCC32</DCC_DCCCompiler>\n\t\t\t<ProjectVersion>12.3</ProjectVersion>\n\t\t</PropertyGroup>\n\t\t<PropertyGroup Condition=\"'$(Config)'=='Base' or '$(Base)'!=''\">\n\t\t\t<Base>true</Base>\n\t\t</PropertyGroup>\n\t\t<PropertyGroup Condition=\"'$(Config)'=='Release' or '$(Cfg_1)'!=''\">\n\t\t\t<Cfg_1>true</Cfg_1>\n\t\t\t<CfgParent>Base</CfgParent>\n\t\t\t<Base>true</Base>\n\t\t</PropertyGroup>\n\t\t<PropertyGroup Condition=\"'$(Config)'=='Debug' or '$(Cfg_2)'!=''\">\n\t\t\t<Cfg_2>true</Cfg_2>\n\t\t\t<CfgParent>Base</CfgParent>\n\t\t\t<Base>true</Base>\n\t\t</PropertyGroup>\n\t\t<PropertyGroup Condition=\"'$(Base)'!=''\">\n\t\t\t<DCC_E>false</DCC_E>\n\t\t\t<DCC_ImageBase>00400000</DCC_ImageBase>\n\t\t\t<DCC_UnitAlias>WinTypes=Windows;WinProcs=Windows;DbiTypes=BDE;DbiProcs=BDE;DbiErrs=BDE;$(DCC_UnitAlias)</DCC_UnitAlias>\n\t\t\t<DCC_F>false</DCC_F>\n\t\t\t<DCC_S>false</DCC_S>\n\t\t\t<DCC_N>false</DCC_N>\n\t\t\t<DCC_K>false</DCC_K>\n\t\t</PropertyGroup>\n\t\t<PropertyGroup Condition=\"'$(Cfg_1)'!=''\">\n\t\t\t<DCC_LocalDebugSymbols>false</DCC_LocalDebugSymbols>\n\t\t\t<DCC_Define>RELEASE;$(DCC_Define)</DCC_Define>\n\t\t\t<DCC_SymbolReferenceInfo>0</DCC_SymbolReferenceInfo>\n\t\t\t<DCC_DebugInformation>false</DCC_DebugInformation>\n\t\t</PropertyGroup>\n\t\t<PropertyGroup Condition=\"'$(Cfg_2)'!=''\">\n\t\t\t<DCC_Define>DEBUG;$(DCC_Define)</DCC_Define>\n\t\t\t<DCC_Optimize>false</DCC_Optimize>\n\t\t\t<DCC_GenerateStackFrames>true</DCC_GenerateStackFrames>\n\t\t</PropertyGroup>\n\t\t<ItemGroup>\n\t\t\t<DelphiCompile Include=\"Unzip.dpr\">\n\t\t\t\t<MainSource>MainSource</MainSource>\n\t\t\t</DelphiCompile>\n\t\t\t<DCCReference Include=\"Uunzip.pas\">\n\t\t\t\t<Form>Form1</Form>\n\t\t\t</DCCReference>\n\t\t\t<BuildConfiguration Include=\"Debug\">\n\t\t\t\t<Key>Cfg_2</Key>\n\t\t\t\t<CfgParent>Base</CfgParent>\n\t\t\t</BuildConfiguration>\n\t\t\t<BuildConfiguration Include=\"Base\">\n\t\t\t\t<Key>Base</Key>\n\t\t\t</BuildConfiguration>\n\t\t\t<BuildConfiguration Include=\"Release\">\n\t\t\t\t<Key>Cfg_1</Key>\n\t\t\t\t<CfgParent>Base</CfgParent>\n\t\t\t</BuildConfiguration>\n\t\t</ItemGroup>\n\t\t<Import Condition=\"Exists('$(BDS)\\Bin\\CodeGear.Delphi.Targets')\" Project=\"$(BDS)\\Bin\\CodeGear.Delphi.Targets\"/>\n\t\t<Import Condition=\"Exists('$(APPDATA)\\Embarcadero\\$(BDSAPPDATABASEDIR)\\$(PRODUCTVERSION)\\UserTools.proj')\" Project=\"$(APPDATA)\\Embarcadero\\$(BDSAPPDATABASEDIR)\\$(PRODUCTVERSION)\\UserTools.proj\"/>\n\t\t<ProjectExtensions>\n\t\t\t<Borland.Personality>Delphi.Personality.12</Borland.Personality>\n\t\t\t<Borland.ProjectType>VCLApplication</Borland.ProjectType>\n\t\t\t<BorlandProject>\n\t\t\t\t<Delphi.Personality>\n\t\t\t\t\t<Source>\n\t\t\t\t\t\t<Source Name=\"MainSource\">Unzip.dpr</Source>\n\t\t\t\t\t</Source>\n\t\t\t\t\t<VersionInfo>\n\t\t\t\t\t\t<VersionInfo Name=\"IncludeVerInfo\">False</VersionInfo>\n\t\t\t\t\t\t<VersionInfo Name=\"AutoIncBuild\">False</VersionInfo>\n\t\t\t\t\t\t<VersionInfo Name=\"MajorVer\">1</VersionInfo>\n\t\t\t\t\t\t<VersionInfo Name=\"MinorVer\">0</VersionInfo>\n\t\t\t\t\t\t<VersionInfo Name=\"Release\">0</VersionInfo>\n\t\t\t\t\t\t<VersionInfo Name=\"Build\">0</VersionInfo>\n\t\t\t\t\t\t<VersionInfo Name=\"Debug\">False</VersionInfo>\n\t\t\t\t\t\t<VersionInfo Name=\"PreRelease\">False</VersionInfo>\n\t\t\t\t\t\t<VersionInfo Name=\"Special\">False</VersionInfo>\n\t\t\t\t\t\t<VersionInfo Name=\"Private\">False</VersionInfo>\n\t\t\t\t\t\t<VersionInfo Name=\"DLL\">False</VersionInfo>\n\t\t\t\t\t\t<VersionInfo Name=\"Locale\">1033</VersionInfo>\n\t\t\t\t\t\t<VersionInfo Name=\"CodePage\">1252</VersionInfo>\n\t\t\t\t\t</VersionInfo>\n\t\t\t\t\t<VersionInfoKeys>\n\t\t\t\t\t\t<VersionInfoKeys Name=\"CompanyName\"/>\n\t\t\t\t\t\t<VersionInfoKeys Name=\"FileDescription\"/>\n\t\t\t\t\t\t<VersionInfoKeys Name=\"FileVersion\">1.0.0.0</VersionInfoKeys>\n\t\t\t\t\t\t<VersionInfoKeys Name=\"InternalName\"/>\n\t\t\t\t\t\t<VersionInfoKeys Name=\"LegalCopyright\"/>\n\t\t\t\t\t\t<VersionInfoKeys Name=\"LegalTrademarks\"/>\n\t\t\t\t\t\t<VersionInfoKeys Name=\"OriginalFilename\"/>\n\t\t\t\t\t\t<VersionInfoKeys Name=\"ProductName\"/>\n\t\t\t\t\t\t<VersionInfoKeys Name=\"ProductVersion\">1.0.0.0</VersionInfoKeys>\n\t\t\t\t\t\t<VersionInfoKeys Name=\"Comments\"/>\n\t\t\t\t\t</VersionInfoKeys>\n\t\t\t\t</Delphi.Personality>\n\t\t\t\t<Platforms>\n\t\t\t\t\t<Platform value=\"Win32\">True</Platform>\n\t\t\t\t</Platforms>\n\t\t\t</BorlandProject>\n\t\t\t<ProjectFileVersion>12</ProjectFileVersion>\n\t\t</ProjectExtensions>\n\t</Project>\n"
  },
  {
    "path": "lib/abbrevia/examples/Delphi/Unzip.dproj.2007",
    "content": "﻿\t<Project xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n\t\t<PropertyGroup>\n\t\t\t<ProjectGuid>{4193EA89-8316-4EA6-824B-CD35E8A098C8}</ProjectGuid>\n\t\t\t<MainSource>Unzip.dpr</MainSource>\n\t\t\t<Base>True</Base>\n\t\t\t<Config Condition=\"'$(Config)'==''\">Debug</Config>\n\t\t\t<Platform>Win32</Platform>\n\t\t\t<AppType>Application</AppType>\n\t\t\t<FrameworkType>VCL</FrameworkType>\n\t\t\t<DCC_DCCCompiler>DCC32</DCC_DCCCompiler>\n\t\t</PropertyGroup>\n\t\t<PropertyGroup Condition=\"'$(Config)'=='Base' or '$(Base)'!=''\">\n\t\t\t<Base>true</Base>\n\t\t</PropertyGroup>\n\t\t<PropertyGroup Condition=\"'$(Config)'=='Release' or '$(Cfg_1)'!=''\">\n\t\t\t<Cfg_1>true</Cfg_1>\n\t\t\t<CfgParent>Base</CfgParent>\n\t\t\t<Base>true</Base>\n\t\t</PropertyGroup>\n\t\t<PropertyGroup Condition=\"'$(Config)'=='Debug' or '$(Cfg_2)'!=''\">\n\t\t\t<Cfg_2>true</Cfg_2>\n\t\t\t<CfgParent>Base</CfgParent>\n\t\t\t<Base>true</Base>\n\t\t</PropertyGroup>\n\t\t<PropertyGroup Condition=\"'$(Base)'!=''\">\n\t\t\t<DCC_F>false</DCC_F>\n\t\t\t<DCC_E>false</DCC_E>\n\t\t\t<DCC_ImageBase>00400000</DCC_ImageBase>\n\t\t\t<DCC_S>false</DCC_S>\n\t\t\t<DCC_N>false</DCC_N>\n\t\t\t<DCC_K>false</DCC_K>\n\t\t</PropertyGroup>\n\t\t<PropertyGroup Condition=\"'$(Cfg_1)'!=''\">\n\t\t\t<DCC_LocalDebugSymbols>false</DCC_LocalDebugSymbols>\n\t\t\t<DCC_Define>RELEASE;$(DCC_Define)</DCC_Define>\n\t\t\t<DCC_SymbolReferenceInfo>0</DCC_SymbolReferenceInfo>\n\t\t\t<DCC_DebugInformation>false</DCC_DebugInformation>\n\t\t</PropertyGroup>\n\t\t<PropertyGroup Condition=\"'$(Cfg_2)'!=''\">\n\t\t\t<DCC_Define>DEBUG;$(DCC_Define)</DCC_Define>\n\t\t\t<DCC_Optimize>false</DCC_Optimize>\n\t\t\t<DCC_GenerateStackFrames>true</DCC_GenerateStackFrames>\n\t\t</PropertyGroup>\n\t\t<ItemGroup>\n\t\t\t<DelphiCompile Include=\"Unzip.dpr\">\n\t\t\t\t<MainSource>MainSource</MainSource>\n\t\t\t</DelphiCompile>\n\t\t\t<DCCReference Include=\"Uunzip.pas\">\n\t\t\t\t<Form>Form1</Form>\n\t\t\t</DCCReference>\n\t\t\t<BuildConfiguration Include=\"Debug\">\n\t\t\t\t<Key>Cfg_2</Key>\n\t\t\t\t<CfgParent>Base</CfgParent>\n\t\t\t</BuildConfiguration>\n\t\t\t<BuildConfiguration Include=\"Base\">\n\t\t\t\t<Key>Base</Key>\n\t\t\t</BuildConfiguration>\n\t\t\t<BuildConfiguration Include=\"Release\">\n\t\t\t\t<Key>Cfg_1</Key>\n\t\t\t\t<CfgParent>Base</CfgParent>\n\t\t\t</BuildConfiguration>\n\t\t</ItemGroup>\n\t\t<Import Condition=\"Exists('$(BDS)\\Bin\\CodeGear.Delphi.Targets')\" Project=\"$(BDS)\\Bin\\CodeGear.Delphi.Targets\"/>\n\t\t<Import Condition=\"Exists('$(APPDATA)\\Embarcadero\\$(BDSAPPDATABASEDIR)\\$(PRODUCTVERSION)\\UserTools.proj')\" Project=\"$(APPDATA)\\Embarcadero\\$(BDSAPPDATABASEDIR)\\$(PRODUCTVERSION)\\UserTools.proj\"/>\n\t\t<ProjectExtensions>\n\t\t\t<Borland.Personality>Delphi.Personality.12</Borland.Personality>\n\t\t\t<Borland.ProjectType>VCLApplication</Borland.ProjectType>\n\t\t\t<BorlandProject>\n\t\t\t\t<Delphi.Personality>\n\t\t\t\t\t<Source>\n\t\t\t\t\t\t<Source Name=\"MainSource\">Unzip.dpr</Source>\n\t\t\t\t\t</Source>\n\t\t\t\t\t<VersionInfo>\n\t\t\t\t\t\t<VersionInfo Name=\"IncludeVerInfo\">False</VersionInfo>\n\t\t\t\t\t\t<VersionInfo Name=\"AutoIncBuild\">False</VersionInfo>\n\t\t\t\t\t\t<VersionInfo Name=\"MajorVer\">1</VersionInfo>\n\t\t\t\t\t\t<VersionInfo Name=\"MinorVer\">0</VersionInfo>\n\t\t\t\t\t\t<VersionInfo Name=\"Release\">0</VersionInfo>\n\t\t\t\t\t\t<VersionInfo Name=\"Build\">0</VersionInfo>\n\t\t\t\t\t\t<VersionInfo Name=\"Debug\">False</VersionInfo>\n\t\t\t\t\t\t<VersionInfo Name=\"PreRelease\">False</VersionInfo>\n\t\t\t\t\t\t<VersionInfo Name=\"Special\">False</VersionInfo>\n\t\t\t\t\t\t<VersionInfo Name=\"Private\">False</VersionInfo>\n\t\t\t\t\t\t<VersionInfo Name=\"DLL\">False</VersionInfo>\n\t\t\t\t\t\t<VersionInfo Name=\"Locale\">1033</VersionInfo>\n\t\t\t\t\t\t<VersionInfo Name=\"CodePage\">1252</VersionInfo>\n\t\t\t\t\t</VersionInfo>\n\t\t\t\t\t<VersionInfoKeys>\n\t\t\t\t\t\t<VersionInfoKeys Name=\"CompanyName\"/>\n\t\t\t\t\t\t<VersionInfoKeys Name=\"FileDescription\"/>\n\t\t\t\t\t\t<VersionInfoKeys Name=\"FileVersion\">1.0.0.0</VersionInfoKeys>\n\t\t\t\t\t\t<VersionInfoKeys Name=\"InternalName\"/>\n\t\t\t\t\t\t<VersionInfoKeys Name=\"LegalCopyright\"/>\n\t\t\t\t\t\t<VersionInfoKeys Name=\"LegalTrademarks\"/>\n\t\t\t\t\t\t<VersionInfoKeys Name=\"OriginalFilename\"/>\n\t\t\t\t\t\t<VersionInfoKeys Name=\"ProductName\"/>\n\t\t\t\t\t\t<VersionInfoKeys Name=\"ProductVersion\">1.0.0.0</VersionInfoKeys>\n\t\t\t\t\t\t<VersionInfoKeys Name=\"Comments\"/>\n\t\t\t\t\t</VersionInfoKeys>\n\t\t\t\t</Delphi.Personality>\n\t\t\t\t<Platforms>\n\t\t\t\t\t<Platform value=\"Win32\">True</Platform>\n\t\t\t\t</Platforms>\n\t\t\t</BorlandProject>\n\t\t\t<ProjectFileVersion>12</ProjectFileVersion>\n\t\t</ProjectExtensions>\n\t</Project>\n"
  },
  {
    "path": "lib/abbrevia/examples/Delphi/UsingApi.dpr",
    "content": "(* ***** BEGIN LICENSE BLOCK *****\n * Version: MPL 1.1\n *\n * The contents of this file are subject to the Mozilla Public License Version\n * 1.1 (the \"License\"); you may not use this file except in compliance with\n * the License. You may obtain a copy of the License at\n * http://www.mozilla.org/MPL/\n *\n * Software distributed under the License is distributed on an \"AS IS\" basis,\n * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License\n * for the specific language governing rights and limitations under the\n * License.\n *\n * The Original Code is TurboPower Abbrevia\n *\n * The Initial Developer of the Original Code is\n * TurboPower Software\n *\n * Portions created by the Initial Developer are Copyright (C) 1997-2002\n * the Initial Developer. All Rights Reserved.\n *\n * Contributor(s):\n *\n * ***** END LICENSE BLOCK ***** *)\n\n{*********************************************************}\n{* ABBREVIA: USINGAPI.DPR                                *}\n{*********************************************************}\n{* ABBREVIA Example program file                         *}\n{*********************************************************}\n\n{$APPTYPE CONSOLE}\n\nprogram UsingAPI;\n\n{Build this app using the Define \"BuildingStub\", to keep it smaller!}\n\nuses\n  AbArcTyp, AbZipTyp, AbZipPrc, AbUnzPrc, Classes, SysUtils, AbUtils;\n\ntype\n  THelper = class\n  public\n    procedure UnzipProc( Sender : TObject; Item : TAbArchiveItem;\n                         const NewName : string );\n    procedure ZipProc( Sender : TObject; Item : TAbArchiveItem;\n                       OutStream : TStream );\n    procedure ArchiveItemProgress( Sender: TObject;\n                                   Item: TAbArchiveItem;\n                                   Progress: Byte;\n                                   var Abort: Boolean);\n  end;\n\nprocedure THelper.ArchiveItemProgress( Sender: TObject;\n  Item: TAbArchiveItem; Progress: Byte; var Abort: Boolean);\ntype\n  TMethodStrings = array [ cmStored..cmDCLImploded ] of string;\nconst\n  MethodStrings : TMethodStrings = ('UnStoring', 'UnShrinking', 'UnReducing',\n                                    'UnReducing', 'UnReducing', 'UnReducing',\n                                    'Exploding', 'DeTokenizing', 'Inflating',\n                                    'Enhanced Inflating', 'DCL Exploding');\nvar\n  ActionString : string;\n  CompMethod: TAbZipCompressionMethod;\nbegin\n  case Item.Action of\n\n    aaAdd : ActionString := 'Adding  ';\n    aaFreshen : ActionString := 'Freshening  ';\n    else begin\n      CompMethod := (Item as TAbZipItem).CompressionMethod;\n      if CompMethod in [cmStored..cmDCLImploded] then\n        ActionString := MethodStrings[(Item as TAbZipItem).CompressionMethod] +\n          '  '\n      else\n        ActionString := 'Decompressing  ';\n    end;\n  end;\n  WriteLn( ActionString + Item.FileName );\nend;\n\nprocedure THelper.UnzipProc( Sender : TObject; Item : TAbArchiveItem;\n                             const NewName : string );\nbegin\n  AbUnzip( Sender, TAbZipItem(Item), NewName );\nend;\n\nprocedure THelper.ZipProc( Sender : TObject; Item : TAbArchiveItem;\n                           OutStream : TStream );\nbegin\n  AbZip( TAbZipArchive(Sender), TAbZipItem(Item), OutStream );\nend;\n\n\nvar\n  ZipFileName : string;\n  OutDirectory : string;\n  InDirectory : string;\n  Mask : string;\n  Archive : TAbZipArchive;\n  Helper : THelper;\nbegin\n  WriteLn;\n  {usage: UsingAPI ZipFileName InDirectory Mask OutDirectory}\n  if (ParamCount < 4) or\n     ((ParamCount > 0) and (Pos('?', ParamStr(1))>0)) then begin\n    WriteLn;\n    WriteLn( '  Syntax: UsingAPI ZipFileName InDirectory Mask OutDirectory');\n    Halt;\n  end;\n\n  ZipFileName := ParamStr(1);\n  InDirectory := ParamStr(2);\n  Mask := ParamStr(3);\n  OutDirectory := ParamStr(4);\n  {open the file}\n  if FileExists( ZipFileName ) then begin\n    Archive := TAbZipArchive.Create( ZipFileName,\n                                     fmOpenReadWrite or fmShareDenyWrite );\n    Archive.Load;\n  end\n  else\n    Archive := TAbZipArchive.Create( ZipFileName,\n                                     fmCreate or fmShareDenyNone );\n  try\n    Helper := THelper.Create;\n    try\n      {set the event handlers}\n      Archive.InsertHelper := Helper.ZipProc;\n      Archive.ExtractHelper := Helper.UnzipProc;\n      Archive.OnArchiveItemProgress := Helper.ArchiveItemProgress;\n      {set the BaseDirectory for input files}\n      Archive.BaseDirectory := InDirectory;\n      {add all the files in the BaseDirectory to the archive}\n      Archive.AddFiles( Mask, 0 );\n      {save the files to the zipfile}\n      Archive.Save;\n      {now, change the base directory to the output}\n      Archive.BaseDirectory := OutDirectory;\n      Archive.ExtractFiles( Mask );\n    finally\n      Helper.Free;\n    end;\n  finally\n    Archive.Free;\n  end;\nend.\n"
  },
  {
    "path": "lib/abbrevia/examples/Delphi/Ustrpad.pas",
    "content": "(* ***** BEGIN LICENSE BLOCK *****\n * Version: MPL 1.1\n *\n * The contents of this file are subject to the Mozilla Public License Version\n * 1.1 (the \"License\"); you may not use this file except in compliance with\n * the License. You may obtain a copy of the License at\n * http://www.mozilla.org/MPL/\n *\n * Software distributed under the License is distributed on an \"AS IS\" basis,\n * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License\n * for the specific language governing rights and limitations under the\n * License.\n *\n * The Original Code is TurboPower Abbrevia\n *\n * The Initial Developer of the Original Code is\n * TurboPower Software\n *\n * Portions created by the Initial Developer are Copyright (C) 1997-2002\n * the Initial Developer. All Rights Reserved.\n *\n * Contributor(s):\n *\n * ***** END LICENSE BLOCK ***** *)\n\n{*********************************************************}\n{* ABBREVIA: USTRPAD.PAS                                 *}\n{* Copyright (c) TurboPower Software Co 1997             *}\n{* All rights reserved.                                  *}\n{*********************************************************}\n{* ABBREVIA Example program file                         *}\n{*********************************************************}\n\nunit Ustrpad;\n\ninterface\n\nuses\n  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,\n  StdCtrls, ExtCtrls;\n\ntype\n  TForm1 = class(TForm)\n    Memo1: TMemo;\n    Panel1: TPanel;\n    Memo2: TMemo;\n    procedure FormCreate(Sender: TObject);\n    procedure FormDestroy(Sender: TObject);\n  private\n    { Private declarations }\n    ZnfName : string;\n    TxtName : string;\n    ZnfStream : TFileStream;\n    TxtStream : TStream;\n  public\n    { Public declarations }\n  end;\n\nvar\n  Form1: TForm1;\n\nimplementation\n\nuses\n  AbUnzPrc,\n  AbZipPrc;\n\n{$R *.DFM}\n\nprocedure TForm1.FormCreate(Sender: TObject);\nbegin\n  ZnfName := ChangeFileExt(Application.ExeName, '.zst');\n  TxtName := ExtractFileName( ChangeFileExt(Application.ExeName, '.pad') );\n  ChDir( ExtractFilePath( Application.ExeName ) );\n  if FileExists( ZnfName ) then begin\n    TxtStream := TMemoryStream.Create;\n    try\n      ZnfStream := TFileStream.Create( ZnfName,\n                                       fmOpenRead or fmShareExclusive );\n      try\n        InflateStream( ZnfStream, TxtStream );\n      finally\n        ZnfStream.Free;\n      end;\n      TxtStream.Position := 0;\n      Memo1.Lines.LoadFromStream( TxtStream );\n    finally\n      TxtStream.Free;\n    end;\n  end;\nend;\n\nprocedure TForm1.FormDestroy(Sender: TObject);\nbegin\n  TxtStream := TMemoryStream.Create;\n  try\n    Memo1.Lines.SaveToStream( TxtStream );\n    TxtStream.Position := 0;\n    if FileExists( ZnfName ) then\n      ZnfStream := TFileStream.Create( ZnfName,\n                                       fmOpenWrite or fmShareExclusive )\n    else\n      ZnfStream := TFileStream.Create( ZnfName,\n                                       fmCreate or fmShareExclusive );\n    try\n      DeflateStream( TxtStream, ZnfStream );\n    finally\n      ZnfStream.Free;\n    end;\n  finally\n    TxtStream.Free;\n  end;\nend;\n\nend.\n"
  },
  {
    "path": "lib/abbrevia/examples/Delphi/Uunzip.pas",
    "content": "(* ***** BEGIN LICENSE BLOCK *****\n * Version: MPL 1.1\n *\n * The contents of this file are subject to the Mozilla Public License Version\n * 1.1 (the \"License\"); you may not use this file except in compliance with\n * the License. You may obtain a copy of the License at\n * http://www.mozilla.org/MPL/\n *\n * Software distributed under the License is distributed on an \"AS IS\" basis,\n * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License\n * for the specific language governing rights and limitations under the\n * License.\n *\n * The Original Code is TurboPower Abbrevia\n *\n * The Initial Developer of the Original Code is\n * TurboPower Software\n *\n * Portions created by the Initial Developer are Copyright (C) 1997-2002\n * the Initial Developer. All Rights Reserved.\n *\n * Contributor(s):\n *\n * ***** END LICENSE BLOCK ***** *)\n\n{*********************************************************}\n{* ABBREVIA: UUNZIP.PAS                                  *}\n{* Copyright (c) TurboPower Software Co 1997             *}\n{* All rights reserved.                                  *}\n{*********************************************************}\n{* ABBREVIA Example program file                         *}\n{*********************************************************}\n\nunit Uunzip;\n\ninterface\n\nuses\n  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls,\n\n  AbZBrows, AbUnZper, AbArcTyp, AbMeter, AbBrowse, AbBase;\n\ntype\n  TForm1 = class(TForm)\n    Button1: TButton;\n    OpenDialog1: TOpenDialog;\n    AbUnZipper1: TAbUnZipper;\n    Memo1: TMemo;\n    AbMeter1: TAbMeter;\n    AbMeter2: TAbMeter;\n    Label1: TLabel;\n    Label2: TLabel;\n    procedure Button1Click(Sender: TObject);\n  private\n    { Private declarations }\n  public\n    { Public declarations }\n  end;\n\nvar\n  Form1: TForm1;\n\nimplementation\n\n{$R *.DFM}\n\nprocedure TForm1.Button1Click(Sender: TObject);\nbegin\n  if OpenDialog1.Execute then begin\n    with AbUnzipper1 do begin\n      FileName := OpenDialog1.FileName;\n      BaseDirectory := ExtractFilePath( FileName );\n      ExtractFiles( '*.*' );\n    end;\n  end;\nend;\n\nend.\n"
  },
  {
    "path": "lib/abbrevia/examples/Delphi/Uzip.pas",
    "content": "(* ***** BEGIN LICENSE BLOCK *****\n * Version: MPL 1.1\n *\n * The contents of this file are subject to the Mozilla Public License Version\n * 1.1 (the \"License\"); you may not use this file except in compliance with\n * the License. You may obtain a copy of the License at\n * http://www.mozilla.org/MPL/\n *\n * Software distributed under the License is distributed on an \"AS IS\" basis,\n * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License\n * for the specific language governing rights and limitations under the\n * License.\n *\n * The Original Code is TurboPower Abbrevia\n *\n * The Initial Developer of the Original Code is\n * TurboPower Software\n *\n * Portions created by the Initial Developer are Copyright (C) 1997-2002\n * the Initial Developer. All Rights Reserved.\n *\n * Contributor(s):\n *\n * ***** END LICENSE BLOCK ***** *)\n\n{*********************************************************}\n{* ABBREVIA: UZIP.PAS                                    *}\n{* Copyright (c) TurboPower Software Co 1997             *}\n{* All rights reserved.                                  *}\n{*********************************************************}\n{* ABBREVIA Example program file                         *}\n{*********************************************************}\n\nunit Uzip;\n\ninterface\n\nuses\n  Windows,  Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,\n  StdCtrls, Gauges, \n\n  AbZipper, AbArcTyp, AbZBrows, AbMeter, AbBrowse, AbBase;\n\ntype\n  TForm1 = class(TForm)\n    AbZipper1: TAbZipper;\n    Button1: TButton;\n    OpenDialog1: TOpenDialog;\n    Memo1: TMemo;\n    AbMeter1: TAbMeter;\n    AbMeter2: TAbMeter;\n    Label1: TLabel;\n    Label2: TLabel;\n    procedure Button1Click(Sender: TObject);\n  private\n    { Private declarations }\n  public\n    { Public declarations }\n  end;\n\nvar\n  Form1: TForm1;\n\nimplementation\n\n{$R *.DFM}\n\nprocedure TForm1.Button1Click(Sender: TObject);\nbegin\n  if OpenDialog1.Execute then\n    AbZipper1.AddFiles( OpenDialog1.FileName, 0 );\nend;\n\nend.\n"
  },
  {
    "path": "lib/abbrevia/examples/Delphi/ZipReg.dpr",
    "content": "(* ***** BEGIN LICENSE BLOCK *****\n * Version: MPL 1.1\n *\n * The contents of this file are subject to the Mozilla Public License Version\n * 1.1 (the \"License\"); you may not use this file except in compliance with\n * the License. You may obtain a copy of the License at\n * http://www.mozilla.org/MPL/\n *\n * Software distributed under the License is distributed on an \"AS IS\" basis,\n * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License\n * for the specific language governing rights and limitations under the\n * License.\n *\n * The Original Code is TurboPower Abbrevia\n *\n * The Initial Developer of the Original Code is\n * TurboPower Software\n *\n * Portions created by the Initial Developer are Copyright (C) 1997-2002\n * the Initial Developer. All Rights Reserved.\n *\n * Contributor(s):\n *\n * ***** END LICENSE BLOCK ***** *)\n\n{*********************************************************}\n{* ABBREVIA: ZIPREG.DPR                                  *}\n{*********************************************************}\n{* ABBREVIA Example program file                         *}\n{*********************************************************}\n\nprogram ZipReg;\n\nuses\n  Forms,\n  ZipReg1 in 'ZipReg1.pas' {ExZipAssociation};\n\nbegin\n  Application.CreateForm(TExZipAssociation, ExZipAssociation);\n  Application.Run;\nend.\n"
  },
  {
    "path": "lib/abbrevia/examples/Delphi/ZipReg.dproj",
    "content": "﻿\t<Project xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n\t\t<PropertyGroup>\n\t\t\t<ProjectGuid>{623B6B04-BBC3-4044-85BC-8C225B160F0E}</ProjectGuid>\n\t\t\t<MainSource>ZipReg.dpr</MainSource>\n\t\t\t<Base>True</Base>\n\t\t\t<Config Condition=\"'$(Config)'==''\">Debug</Config>\n\t\t\t<Platform>Win32</Platform>\n\t\t\t<AppType>Application</AppType>\n\t\t\t<FrameworkType>VCL</FrameworkType>\n\t\t\t<DCC_DCCCompiler>DCC32</DCC_DCCCompiler>\n\t\t\t<ProjectVersion>12.3</ProjectVersion>\n\t\t</PropertyGroup>\n\t\t<PropertyGroup Condition=\"'$(Config)'=='Base' or '$(Base)'!=''\">\n\t\t\t<Base>true</Base>\n\t\t</PropertyGroup>\n\t\t<PropertyGroup Condition=\"'$(Config)'=='Release' or '$(Cfg_1)'!=''\">\n\t\t\t<Cfg_1>true</Cfg_1>\n\t\t\t<CfgParent>Base</CfgParent>\n\t\t\t<Base>true</Base>\n\t\t</PropertyGroup>\n\t\t<PropertyGroup Condition=\"'$(Config)'=='Debug' or '$(Cfg_2)'!=''\">\n\t\t\t<Cfg_2>true</Cfg_2>\n\t\t\t<CfgParent>Base</CfgParent>\n\t\t\t<Base>true</Base>\n\t\t</PropertyGroup>\n\t\t<PropertyGroup Condition=\"'$(Base)'!=''\">\n\t\t\t<DCC_E>false</DCC_E>\n\t\t\t<DCC_ImageBase>00400000</DCC_ImageBase>\n\t\t\t<DCC_UnitAlias>WinTypes=Windows;WinProcs=Windows;DbiTypes=BDE;DbiProcs=BDE;DbiErrs=BDE;$(DCC_UnitAlias)</DCC_UnitAlias>\n\t\t\t<DCC_F>false</DCC_F>\n\t\t\t<DCC_S>false</DCC_S>\n\t\t\t<DCC_N>false</DCC_N>\n\t\t\t<DCC_K>false</DCC_K>\n\t\t</PropertyGroup>\n\t\t<PropertyGroup Condition=\"'$(Cfg_1)'!=''\">\n\t\t\t<DCC_LocalDebugSymbols>false</DCC_LocalDebugSymbols>\n\t\t\t<DCC_Define>RELEASE;$(DCC_Define)</DCC_Define>\n\t\t\t<DCC_SymbolReferenceInfo>0</DCC_SymbolReferenceInfo>\n\t\t\t<DCC_DebugInformation>false</DCC_DebugInformation>\n\t\t</PropertyGroup>\n\t\t<PropertyGroup Condition=\"'$(Cfg_2)'!=''\">\n\t\t\t<DCC_Define>DEBUG;$(DCC_Define)</DCC_Define>\n\t\t\t<DCC_Optimize>false</DCC_Optimize>\n\t\t\t<DCC_GenerateStackFrames>true</DCC_GenerateStackFrames>\n\t\t</PropertyGroup>\n\t\t<ItemGroup>\n\t\t\t<DelphiCompile Include=\"ZipReg.dpr\">\n\t\t\t\t<MainSource>MainSource</MainSource>\n\t\t\t</DelphiCompile>\n\t\t\t<DCCReference Include=\"ZipReg1.pas\">\n\t\t\t\t<Form>ExZipAssociation</Form>\n\t\t\t</DCCReference>\n\t\t\t<BuildConfiguration Include=\"Debug\">\n\t\t\t\t<Key>Cfg_2</Key>\n\t\t\t\t<CfgParent>Base</CfgParent>\n\t\t\t</BuildConfiguration>\n\t\t\t<BuildConfiguration Include=\"Base\">\n\t\t\t\t<Key>Base</Key>\n\t\t\t</BuildConfiguration>\n\t\t\t<BuildConfiguration Include=\"Release\">\n\t\t\t\t<Key>Cfg_1</Key>\n\t\t\t\t<CfgParent>Base</CfgParent>\n\t\t\t</BuildConfiguration>\n\t\t</ItemGroup>\n\t\t<Import Condition=\"Exists('$(BDS)\\Bin\\CodeGear.Delphi.Targets')\" Project=\"$(BDS)\\Bin\\CodeGear.Delphi.Targets\"/>\n\t\t<Import Condition=\"Exists('$(APPDATA)\\Embarcadero\\$(BDSAPPDATABASEDIR)\\$(PRODUCTVERSION)\\UserTools.proj')\" Project=\"$(APPDATA)\\Embarcadero\\$(BDSAPPDATABASEDIR)\\$(PRODUCTVERSION)\\UserTools.proj\"/>\n\t\t<ProjectExtensions>\n\t\t\t<Borland.Personality>Delphi.Personality.12</Borland.Personality>\n\t\t\t<Borland.ProjectType>VCLApplication</Borland.ProjectType>\n\t\t\t<BorlandProject>\n\t\t\t\t<Delphi.Personality>\n\t\t\t\t\t<Source>\n\t\t\t\t\t\t<Source Name=\"MainSource\">ZipReg.dpr</Source>\n\t\t\t\t\t</Source>\n\t\t\t\t\t<VersionInfo>\n\t\t\t\t\t\t<VersionInfo Name=\"IncludeVerInfo\">False</VersionInfo>\n\t\t\t\t\t\t<VersionInfo Name=\"AutoIncBuild\">False</VersionInfo>\n\t\t\t\t\t\t<VersionInfo Name=\"MajorVer\">1</VersionInfo>\n\t\t\t\t\t\t<VersionInfo Name=\"MinorVer\">0</VersionInfo>\n\t\t\t\t\t\t<VersionInfo Name=\"Release\">0</VersionInfo>\n\t\t\t\t\t\t<VersionInfo Name=\"Build\">0</VersionInfo>\n\t\t\t\t\t\t<VersionInfo Name=\"Debug\">False</VersionInfo>\n\t\t\t\t\t\t<VersionInfo Name=\"PreRelease\">False</VersionInfo>\n\t\t\t\t\t\t<VersionInfo Name=\"Special\">False</VersionInfo>\n\t\t\t\t\t\t<VersionInfo Name=\"Private\">False</VersionInfo>\n\t\t\t\t\t\t<VersionInfo Name=\"DLL\">False</VersionInfo>\n\t\t\t\t\t\t<VersionInfo Name=\"Locale\">1033</VersionInfo>\n\t\t\t\t\t\t<VersionInfo Name=\"CodePage\">1252</VersionInfo>\n\t\t\t\t\t</VersionInfo>\n\t\t\t\t\t<VersionInfoKeys>\n\t\t\t\t\t\t<VersionInfoKeys Name=\"CompanyName\"/>\n\t\t\t\t\t\t<VersionInfoKeys Name=\"FileDescription\"/>\n\t\t\t\t\t\t<VersionInfoKeys Name=\"FileVersion\">1.0.0.0</VersionInfoKeys>\n\t\t\t\t\t\t<VersionInfoKeys Name=\"InternalName\"/>\n\t\t\t\t\t\t<VersionInfoKeys Name=\"LegalCopyright\"/>\n\t\t\t\t\t\t<VersionInfoKeys Name=\"LegalTrademarks\"/>\n\t\t\t\t\t\t<VersionInfoKeys Name=\"OriginalFilename\"/>\n\t\t\t\t\t\t<VersionInfoKeys Name=\"ProductName\"/>\n\t\t\t\t\t\t<VersionInfoKeys Name=\"ProductVersion\">1.0.0.0</VersionInfoKeys>\n\t\t\t\t\t\t<VersionInfoKeys Name=\"Comments\"/>\n\t\t\t\t\t</VersionInfoKeys>\n\t\t\t\t</Delphi.Personality>\n\t\t\t\t<Platforms>\n\t\t\t\t\t<Platform value=\"Win32\">True</Platform>\n\t\t\t\t</Platforms>\n\t\t\t</BorlandProject>\n\t\t\t<ProjectFileVersion>12</ProjectFileVersion>\n\t\t</ProjectExtensions>\n\t</Project>\n"
  },
  {
    "path": "lib/abbrevia/examples/Delphi/ZipReg.dproj.2007",
    "content": "﻿\t<Project xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n\t\t<PropertyGroup>\n\t\t\t<ProjectGuid>{623B6B04-BBC3-4044-85BC-8C225B160F0E}</ProjectGuid>\n\t\t\t<MainSource>ZipReg.dpr</MainSource>\n\t\t\t<Base>True</Base>\n\t\t\t<Config Condition=\"'$(Config)'==''\">Debug</Config>\n\t\t\t<Platform>Win32</Platform>\n\t\t\t<AppType>Application</AppType>\n\t\t\t<FrameworkType>VCL</FrameworkType>\n\t\t\t<DCC_DCCCompiler>DCC32</DCC_DCCCompiler>\n\t\t</PropertyGroup>\n\t\t<PropertyGroup Condition=\"'$(Config)'=='Base' or '$(Base)'!=''\">\n\t\t\t<Base>true</Base>\n\t\t</PropertyGroup>\n\t\t<PropertyGroup Condition=\"'$(Config)'=='Release' or '$(Cfg_1)'!=''\">\n\t\t\t<Cfg_1>true</Cfg_1>\n\t\t\t<CfgParent>Base</CfgParent>\n\t\t\t<Base>true</Base>\n\t\t</PropertyGroup>\n\t\t<PropertyGroup Condition=\"'$(Config)'=='Debug' or '$(Cfg_2)'!=''\">\n\t\t\t<Cfg_2>true</Cfg_2>\n\t\t\t<CfgParent>Base</CfgParent>\n\t\t\t<Base>true</Base>\n\t\t</PropertyGroup>\n\t\t<PropertyGroup Condition=\"'$(Base)'!=''\">\n\t\t\t<DCC_F>false</DCC_F>\n\t\t\t<DCC_E>false</DCC_E>\n\t\t\t<DCC_ImageBase>00400000</DCC_ImageBase>\n\t\t\t<DCC_S>false</DCC_S>\n\t\t\t<DCC_N>false</DCC_N>\n\t\t\t<DCC_K>false</DCC_K>\n\t\t</PropertyGroup>\n\t\t<PropertyGroup Condition=\"'$(Cfg_1)'!=''\">\n\t\t\t<DCC_LocalDebugSymbols>false</DCC_LocalDebugSymbols>\n\t\t\t<DCC_Define>RELEASE;$(DCC_Define)</DCC_Define>\n\t\t\t<DCC_SymbolReferenceInfo>0</DCC_SymbolReferenceInfo>\n\t\t\t<DCC_DebugInformation>false</DCC_DebugInformation>\n\t\t</PropertyGroup>\n\t\t<PropertyGroup Condition=\"'$(Cfg_2)'!=''\">\n\t\t\t<DCC_Define>DEBUG;$(DCC_Define)</DCC_Define>\n\t\t\t<DCC_Optimize>false</DCC_Optimize>\n\t\t\t<DCC_GenerateStackFrames>true</DCC_GenerateStackFrames>\n\t\t</PropertyGroup>\n\t\t<ItemGroup>\n\t\t\t<DelphiCompile Include=\"ZipReg.dpr\">\n\t\t\t\t<MainSource>MainSource</MainSource>\n\t\t\t</DelphiCompile>\n\t\t\t<DCCReference Include=\"ZipReg1.pas\">\n\t\t\t\t<Form>ExZipAssociation</Form>\n\t\t\t</DCCReference>\n\t\t\t<BuildConfiguration Include=\"Debug\">\n\t\t\t\t<Key>Cfg_2</Key>\n\t\t\t\t<CfgParent>Base</CfgParent>\n\t\t\t</BuildConfiguration>\n\t\t\t<BuildConfiguration Include=\"Base\">\n\t\t\t\t<Key>Base</Key>\n\t\t\t</BuildConfiguration>\n\t\t\t<BuildConfiguration Include=\"Release\">\n\t\t\t\t<Key>Cfg_1</Key>\n\t\t\t\t<CfgParent>Base</CfgParent>\n\t\t\t</BuildConfiguration>\n\t\t</ItemGroup>\n\t\t<Import Condition=\"Exists('$(BDS)\\Bin\\CodeGear.Delphi.Targets')\" Project=\"$(BDS)\\Bin\\CodeGear.Delphi.Targets\"/>\n\t\t<Import Condition=\"Exists('$(APPDATA)\\Embarcadero\\$(BDSAPPDATABASEDIR)\\$(PRODUCTVERSION)\\UserTools.proj')\" Project=\"$(APPDATA)\\Embarcadero\\$(BDSAPPDATABASEDIR)\\$(PRODUCTVERSION)\\UserTools.proj\"/>\n\t\t<ProjectExtensions>\n\t\t\t<Borland.Personality>Delphi.Personality.12</Borland.Personality>\n\t\t\t<Borland.ProjectType>VCLApplication</Borland.ProjectType>\n\t\t\t<BorlandProject>\n\t\t\t\t<Delphi.Personality>\n\t\t\t\t\t<Source>\n\t\t\t\t\t\t<Source Name=\"MainSource\">ZipReg.dpr</Source>\n\t\t\t\t\t</Source>\n\t\t\t\t\t<VersionInfo>\n\t\t\t\t\t\t<VersionInfo Name=\"IncludeVerInfo\">False</VersionInfo>\n\t\t\t\t\t\t<VersionInfo Name=\"AutoIncBuild\">False</VersionInfo>\n\t\t\t\t\t\t<VersionInfo Name=\"MajorVer\">1</VersionInfo>\n\t\t\t\t\t\t<VersionInfo Name=\"MinorVer\">0</VersionInfo>\n\t\t\t\t\t\t<VersionInfo Name=\"Release\">0</VersionInfo>\n\t\t\t\t\t\t<VersionInfo Name=\"Build\">0</VersionInfo>\n\t\t\t\t\t\t<VersionInfo Name=\"Debug\">False</VersionInfo>\n\t\t\t\t\t\t<VersionInfo Name=\"PreRelease\">False</VersionInfo>\n\t\t\t\t\t\t<VersionInfo Name=\"Special\">False</VersionInfo>\n\t\t\t\t\t\t<VersionInfo Name=\"Private\">False</VersionInfo>\n\t\t\t\t\t\t<VersionInfo Name=\"DLL\">False</VersionInfo>\n\t\t\t\t\t\t<VersionInfo Name=\"Locale\">1033</VersionInfo>\n\t\t\t\t\t\t<VersionInfo Name=\"CodePage\">1252</VersionInfo>\n\t\t\t\t\t</VersionInfo>\n\t\t\t\t\t<VersionInfoKeys>\n\t\t\t\t\t\t<VersionInfoKeys Name=\"CompanyName\"/>\n\t\t\t\t\t\t<VersionInfoKeys Name=\"FileDescription\"/>\n\t\t\t\t\t\t<VersionInfoKeys Name=\"FileVersion\">1.0.0.0</VersionInfoKeys>\n\t\t\t\t\t\t<VersionInfoKeys Name=\"InternalName\"/>\n\t\t\t\t\t\t<VersionInfoKeys Name=\"LegalCopyright\"/>\n\t\t\t\t\t\t<VersionInfoKeys Name=\"LegalTrademarks\"/>\n\t\t\t\t\t\t<VersionInfoKeys Name=\"OriginalFilename\"/>\n\t\t\t\t\t\t<VersionInfoKeys Name=\"ProductName\"/>\n\t\t\t\t\t\t<VersionInfoKeys Name=\"ProductVersion\">1.0.0.0</VersionInfoKeys>\n\t\t\t\t\t\t<VersionInfoKeys Name=\"Comments\"/>\n\t\t\t\t\t</VersionInfoKeys>\n\t\t\t\t</Delphi.Personality>\n\t\t\t\t<Platforms>\n\t\t\t\t\t<Platform value=\"Win32\">True</Platform>\n\t\t\t\t</Platforms>\n\t\t\t</BorlandProject>\n\t\t\t<ProjectFileVersion>12</ProjectFileVersion>\n\t\t</ProjectExtensions>\n\t</Project>\n"
  },
  {
    "path": "lib/abbrevia/examples/Delphi/ZipReg1.pas",
    "content": "(* ***** BEGIN LICENSE BLOCK *****\n * Version: MPL 1.1\n *\n * The contents of this file are subject to the Mozilla Public License Version\n * 1.1 (the \"License\"); you may not use this file except in compliance with\n * the License. You may obtain a copy of the License at\n * http://www.mozilla.org/MPL/\n *\n * Software distributed under the License is distributed on an \"AS IS\" basis,\n * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License\n * for the specific language governing rights and limitations under the\n * License.\n *\n * The Original Code is TurboPower Abbrevia\n *\n * The Initial Developer of the Original Code is\n * TurboPower Software\n *\n * Portions created by the Initial Developer are Copyright (C) 1997-2002\n * the Initial Developer. All Rights Reserved.\n *\n * Contributor(s):\n *\n * ***** END LICENSE BLOCK ***** *)\n\n{*********************************************************}\n{* ABBREVIA: ZIPREG1.PAS                                 *}\n{* Copyright (c) TurboPower Software Co 1997             *}\n{* All rights reserved.                                  *}\n{*********************************************************}\n{* ABBREVIA Example program file                         *}\n{*********************************************************}\n\nunit ZipReg1;\n\ninterface\n\nuses\n  Windows, Messages, SysUtils, Classes, Graphics, Controls,\n  Forms, Dialogs, StdCtrls, ExtCtrls, Buttons;\n\ntype\n  TExZipAssociation = class(TForm)\n    CheckZipReg: TButton;\n    RegZipExt: TButton;\n    Replace: TCheckBox;\n    ExitBtn: TButton;\n    GroupBox1: TGroupBox;\n    Label1: TLabel;\n    Label2: TLabel;\n    Label3: TLabel;\n    Label4: TLabel;\n    Icon1: TImage;\n    ID1: TEdit;\n    FileType1: TEdit;\n    App1: TEdit;\n    Browse1: TSpeedButton;\n    OpenDialog1: TOpenDialog;\n    procedure CheckZipRegClick(Sender: TObject);\n    procedure RegZipExtClick(Sender: TObject);\n    procedure ExitBtnClick(Sender: TObject);\n    procedure Browse1Click(Sender: TObject);\n  private\n    { Private declarations }\n  public\n    { Public declarations }\n  end;\n\nvar\n  ExZipAssociation: TExZipAssociation;\n\nimplementation\n\n{$R *.DFM}\n\nuses\n  AbZipExt, ShellApi;\n\nvar\n  App, ID, FileType : string;\n  FN  : array[0..255] of char;\n  IconIndex : Word;\n\n\nprocedure TExZipAssociation.CheckZipRegClick(Sender: TObject);\nbegin\n  App := '';\n  ID := '';\n  FileType := '';\n  if AbGetZipAssociation(App, ID, FileType) then begin\n    GroupBox1.Caption := ' ''zip'' is currently registered ';\n    StrPCopy(FN, App);\n    {$IFNDEF Win32}\n    Icon1.Picture.Icon.Handle := ExtractIcon(HInstance, FN, 0);\n    {$ELSE}\n    Icon1.Picture.Icon.Handle := ExtractAssociatedIcon(HInstance, FN, IconIndex);\n    {$ENDIF}\n  end else begin\n    GroupBox1.Caption := ' ''zip'' is not registered ';\n    Icon1.Picture.Icon.Handle := 0;\n  end;\n  ID1.Text := ID;\n  FileType1.Text := FileType;\n  App1.Text := App;\nend;\n\nprocedure TExZipAssociation.RegZipExtClick(Sender: TObject);\nbegin\n  if (AbExistingZipAssociation and not Replace.Checked) then\n    CheckZipRegClick(nil)\n  else begin\n    App := App1.Text;\n    FileType := FileType1.Text;\n    ID := ID1.Text;\n    if AbRegisterZipExtension(App, ID, FileType, Replace.Checked) then\n      CheckZipRegClick(nil)\n    else begin\n      GroupBox1.Caption := ' Error occurred during registration ';\n      Icon1.Picture.Icon.Handle := 0;\n    end;\n  end;\nend;\n\nprocedure TExZipAssociation.ExitBtnClick(Sender: TObject);\nbegin\n  Close;\nend;\n\nprocedure TExZipAssociation.Browse1Click(Sender: TObject);\nbegin\n  OpenDialog1.Title := 'Select application to associate with ''zip'' files';\n  OpenDialog1.Filename := '*.exe';\n  if OpenDialog1.Execute then begin\n    App := OpenDialog1.Filename;\n    App1.Text := App;\n  end;\nend;\n\nend.\n"
  },
  {
    "path": "lib/abbrevia/examples/Delphi/ZipView.dpr",
    "content": "(* ***** BEGIN LICENSE BLOCK *****\n * Version: MPL 1.1\n *\n * The contents of this file are subject to the Mozilla Public License Version\n * 1.1 (the \"License\"); you may not use this file except in compliance with\n * the License. You may obtain a copy of the License at\n * http://www.mozilla.org/MPL/\n *\n * Software distributed under the License is distributed on an \"AS IS\" basis,\n * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License\n * for the specific language governing rights and limitations under the\n * License.\n *\n * The Original Code is TurboPower Abbrevia\n *\n * The Initial Developer of the Original Code is\n * TurboPower Software\n *\n * Portions created by the Initial Developer are Copyright (C) 1997-2002\n * the Initial Developer. All Rights Reserved.\n *\n * Contributor(s):\n *\n * ***** END LICENSE BLOCK ***** *)\n\n{*********************************************************}\n{* ABBREVIA: ZIPVIEW.DPR                                 *}\n{*********************************************************}\n{* ABBREVIA Example program file                         *}\n{*********************************************************}\n\nprogram ZipView;\n\nuses\n  Forms,\n  ZipView1 in 'ZipView1.PAS' {Form1};\n\nbegin\n  Application.CreateForm(TForm1, Form1);\n  Application.Run;\nend.\n"
  },
  {
    "path": "lib/abbrevia/examples/Delphi/ZipView1.pas",
    "content": "(* ***** BEGIN LICENSE BLOCK *****\n * Version: MPL 1.1\n *\n * The contents of this file are subject to the Mozilla Public License Version\n * 1.1 (the \"License\"); you may not use this file except in compliance with\n * the License. You may obtain a copy of the License at\n * http://www.mozilla.org/MPL/\n *\n * Software distributed under the License is distributed on an \"AS IS\" basis,\n * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License\n * for the specific language governing rights and limitations under the\n * License.\n *\n * The Original Code is TurboPower Abbrevia\n *\n * The Initial Developer of the Original Code is\n * TurboPower Software\n *\n * Portions created by the Initial Developer are Copyright (C) 1997-2002\n * the Initial Developer. All Rights Reserved.\n *\n * Contributor(s):\n *\n * ***** END LICENSE BLOCK ***** *)\n\n{*********************************************************}\n{* ABBREVIA: ZIPVIEW1.PAS                                *}\n{* Copyright (c) TurboPower Software Co 1997             *}\n{* All rights reserved.                                  *}\n{*********************************************************}\n{* ABBREVIA Example program file                         *}\n{*********************************************************}\n\nunit ZipView1;\n\ninterface\n\nuses\n  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,\n  Grids, StdCtrls, ExtCtrls, Menus, FileCtrl, Gauges, ComCtrls,\n\n  AbArcTyp, AbUtils, AbZipper, AbZipKit, AbZipTyp, AbZBrows, AbMeter,\n  AbDlgDir, AbView, AbZView, AbBrowse, AbBase;\n\ntype\n  TForm1 = class(TForm)\n    OpenDialog1: TOpenDialog;\n    Panel1: TPanel;\n    FontDialog1: TFontDialog;\n    MainMenu1: TMainMenu;\n    File1: TMenuItem;\n    Open1: TMenuItem;\n    Close1: TMenuItem;\n    N1: TMenuItem;\n    Print1: TMenuItem;\n    Exit1: TMenuItem;\n    ColorDialog1: TColorDialog;\n    ZipView1: TMenuItem;\n    Attributes1: TMenuItem;\n    Itemname1: TMenuItem;\n    Packed1: TMenuItem;\n    Method1: TMenuItem;\n    Ratio1: TMenuItem;\n    CRC1: TMenuItem;\n    Fileattributes1: TMenuItem;\n    Filetype1: TMenuItem;\n    Encryption1: TMenuItem;\n    Timestamp1: TMenuItem;\n    Filesize1: TMenuItem;\n    Versionmade1: TMenuItem;\n    Versionneeded1: TMenuItem;\n    Path1: TMenuItem;\n    Display1: TMenuItem;\n    Columnlines1: TMenuItem;\n    Columnmoving1: TMenuItem;\n    Columnresizing1: TMenuItem;\n    MultiSelect1: TMenuItem;\n    Rowlines1: TMenuItem;\n    Thumbtracking1: TMenuItem;\n    Trackactiverow1: TMenuItem;\n    Sort1: TMenuItem;\n    Itemname2: TMenuItem;\n    Packed2: TMenuItem;\n    Ratio2: TMenuItem;\n    Timestamp2: TMenuItem;\n    Filesize2: TMenuItem;\n    Select1: TMenuItem;\n    SelectAll1: TMenuItem;\n    ClearSelections1: TMenuItem;\n    Rows1: TMenuItem;\n    Rowheight1: TMenuItem;\n    Headerheight1: TMenuItem;\n    Font1: TMenuItem;\n    Alternatecolors1: TMenuItem;\n    Action1: TMenuItem;\n    Add1: TMenuItem;\n    Delete1: TMenuItem;\n    Extract1: TMenuItem;\n    Freshen1: TMenuItem;\n    AbZipView1: TAbZipView;\n    AbZipKit1: TAbZipKit;\n    ZipKit1: TMenuItem;\n    Compress1: TMenuItem;\n    N2: TMenuItem;\n    Store1: TMenuItem;\n    Stored1: TMenuItem;\n    Deflated1: TMenuItem;\n    Best1: TMenuItem;\n    Deflation1: TMenuItem;\n    Normal1: TMenuItem;\n    Maximum1: TMenuItem;\n    Fast1: TMenuItem;\n    SuperFast1: TMenuItem;\n    CreateDirs1: TMenuItem;\n    RestorePath1: TMenuItem;\n    StripPath1: TMenuItem;\n    RemoveDots1: TMenuItem;\n    Recurse1: TMenuItem;\n    ShowIcons1: TMenuItem;\n    Colors1: TMenuItem;\n    Selectedcolor: TMenuItem;\n    Selectedtextcolor: TMenuItem;\n    AlternateColor1: TMenuItem;\n    AlternateTextColor1: TMenuItem;\n    Freshen2: TMenuItem;\n    Panel2: TPanel;\n    AbMeter1: TAbMeter;\n    Label1: TLabel;\n    Label2: TLabel;\n    Moveselecteditem1: TMenuItem;\n    Replace1: TMenuItem;\n    PopupMenu1: TPopupMenu;\n    Delete2: TMenuItem;\n    Extract2: TMenuItem;\n    Freshen3: TMenuItem;\n    Move1: TMenuItem;\n    AbMeter2: TAbMeter;\n    Save1: TMenuItem;\n    Testselecteditems1: TMenuItem;\n    Logging1: TMenuItem;\n    DeletedColor1: TMenuItem;\n    DeletedTextColor1: TMenuItem;\n    procedure AbZipView1Click(Sender: TObject);\n    procedure AttributeClick(Sender: TObject);\n    procedure DisplayOptionClick(Sender: TObject);\n    procedure SortAttributeClick(Sender: TObject);\n    procedure Open1Click(Sender: TObject);\n    procedure Close1Click(Sender: TObject);\n    procedure SelectAll1Click(Sender: TObject);\n    procedure ClearSelections1Click(Sender: TObject);\n    procedure Font1Click(Sender: TObject);\n    procedure Exit1Click(Sender: TObject);\n    procedure Selected1Click(Sender: TObject);\n    procedure Selectedtext1Click(Sender: TObject);\n    procedure Rowheight1Click(Sender: TObject);\n    procedure Headerheight1Click(Sender: TObject);\n    procedure Add1Click(Sender: TObject);\n    procedure Delete1Click(Sender: TObject);\n    procedure Extract1Click(Sender: TObject);\n    procedure ExtractOptionClick(Sender: TObject);\n    procedure StoreOptionClick(Sender: TObject);\n    procedure MethodClick(Sender: TObject);\n    procedure DeflationOptionClick(Sender: TObject);\n    procedure AbZipKit1ConfirmProcessItem(Sender: TObject;\n      Item: TAbArchiveItem; ProcessType: TAbProcessType;\n      var Confirm: Boolean);\n    procedure AbZipView1Change(Sender: TObject);\n    procedure AlternateColor1Click(Sender: TObject);\n    procedure AlternateTextColor1Click(Sender: TObject);\n    procedure Freshen1Click(Sender: TObject);\n    procedure Moveselecteditem1Click(Sender: TObject);\n    procedure AbZipKit1Save(Sender: TObject);\n    procedure Save1Click(Sender: TObject);\n    procedure Testselecteditems1Click(Sender: TObject);\n    procedure Logging1Click(Sender: TObject);\n    procedure DeletedColor1Click(Sender: TObject);\n    procedure DeletedTextColor1Click(Sender: TObject);\n  private\n    { Private declarations }\n  public\n    { Public declarations }\n  end;\n\nvar\n  Form1: TForm1;\n\nimplementation\n\n{$R *.DFM}\n\nconst\n  MainCaption = ' TAbZipView example';\n\n{ -------------------------------------------------------------------------- }\nprocedure TForm1.AbZipView1Click(Sender: TObject);\nbegin\n  Panel1.Caption := AbZipView1.Items[AbZipView1.ActiveRow].Filename;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TForm1.Open1Click(Sender: TObject);\nbegin\n  OpenDialog1.Filename := '*.zip';\n  if OpenDialog1.Execute then begin\n    AbZipView1.BeginUpdate;\n//    AbZipKit1.FileName := '';\n    AbZipKit1.Filename := OpenDialog1.Filename;\n    Caption := AbZipKit1.Filename +\n      '   ' + IntToStr(AbZipView1.Count) + ' items';\n    Action1.Enabled := True;\n    AbZipView1.EndUpdate;\n  end;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TForm1.Close1Click(Sender: TObject);\nbegin\n  AbZipKit1.Filename := '';\n  Caption := MainCaption;\n  Panel1.Caption := '';\n  Action1.Enabled := False;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TForm1.AttributeClick(Sender: TObject);\nbegin\n  with TMenuItem(Sender) do begin\n    Checked := not Checked;\n   if Checked then\n      AbZipView1.Attributes := AbZipView1.Attributes + [TAbViewAttribute(Tag)]\n    else\n      AbZipView1.Attributes := AbZipView1.Attributes - [TAbViewAttribute(Tag)];\n  end;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TForm1.DisplayOptionClick(Sender: TObject);\nbegin\n  with TMenuItem(Sender) do begin\n    Checked := not Checked;\n   if Checked then\n      AbZipView1.DisplayOptions := AbZipView1.DisplayOptions +\n        [TAbDisplayOption(Tag)]\n    else\n      AbZipView1.DisplayOptions := AbZipView1.DisplayOptions -\n        [TAbDisplayOption(Tag)]\n  end;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TForm1.SortAttributeClick(Sender: TObject);\nbegin\n  with TMenuItem(Sender) do begin\n    Checked := not Checked;\n   if Checked then\n      AbZipView1.SortAttributes := AbZipView1.SortAttributes +\n        [TAbSortAttribute(Tag)]\n    else\n      AbZipView1.SortAttributes := AbZipView1.SortAttributes -\n        [TAbSortAttribute(Tag)]\n  end;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TForm1.StoreOptionClick(Sender: TObject);\nbegin\n  with TMenuItem(Sender) do begin\n    Checked := not Checked;\n   if Checked then\n      AbZipKit1.StoreOptions := AbZipKit1.StoreOptions +\n        [TAbStoreOption(Tag)]\n    else\n      AbZipKit1.StoreOptions := AbZipKit1.StoreOptions -\n        [TAbStoreOption(Tag)]\n  end;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TForm1.ExtractOptionClick(Sender: TObject);\nbegin\n  with TMenuItem(Sender) do begin\n    Checked := not Checked;\n   if Checked then\n      AbZipKit1.ExtractOptions := AbZipKit1.ExtractOptions +\n        [TAbExtractOption(Tag)]\n    else\n      AbZipKit1.ExtractOptions := AbZipKit1.ExtractOptions -\n        [TAbExtractOption(Tag)]\n  end;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TForm1.MethodClick(Sender: TObject);\nbegin\n  with TMenuItem(Sender) do begin\n    Checked := true;\n    AbZipKit1.CompressionMethodToUse := TAbZipSupportedMethod(Tag);\n  end;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TForm1.DeflationOptionClick(Sender: TObject);\nbegin\n  with TMenuItem(Sender) do begin\n    Checked := true;\n    AbZipKit1.DeflationOption := TAbZipDeflationOption(Tag);\n  end;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TForm1.SelectAll1Click(Sender: TObject);\nbegin\n  AbZipView1.SelectAll;\n  AbZipView1Click(nil);\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TForm1.ClearSelections1Click(Sender: TObject);\nbegin\n  AbZipView1.ClearSelections;\n  AbZipView1Click(nil);\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TForm1.Font1Click(Sender: TObject);\nbegin\n  FontDialog1.Font := AbZipView1.Font;\n  if FontDialog1.Execute then\n    AbZipView1.Font := FontDialog1.Font;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TForm1.Exit1Click(Sender: TObject);\nbegin\n  Close;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TForm1.DeletedColor1Click(Sender: TObject);\nbegin\n  if ColorDialog1.Execute then\n    AbZipView1.Colors.Deleted := ColorDialog1.Color;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TForm1.DeletedTextColor1Click(Sender: TObject);\nbegin\n  if ColorDialog1.Execute then\n    AbZipView1.Colors.DeletedText := ColorDialog1.Color;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TForm1.Selected1Click(Sender: TObject);\nbegin\n  if ColorDialog1.Execute then\n    AbZipView1.Colors.Selected := ColorDialog1.Color;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TForm1.Selectedtext1Click(Sender: TObject);\nbegin\n  if ColorDialog1.Execute then\n    AbZipView1.Colors.SelectedText := ColorDialog1.Color;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TForm1.Rowheight1Click(Sender: TObject);\nvar\n  s : string;\nbegin\n  s := IntToStr(AbZipView1.DefaultRowHeight);\n  if InputQuery(MainCaption, 'Row Height', s) then\n    AbZipView1.DefaultRowHeight := StrToIntDef(s, 18);\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TForm1.Headerheight1Click(Sender: TObject);\nvar\n  s : string;\nbegin\n  s := IntToStr(AbZipView1.HeaderRowHeight);\n  if InputQuery(MainCaption, 'Header Height', s) then\n    AbZipView1.HeaderRowHeight := StrToIntDef(s, 18);\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TForm1.Add1Click(Sender: TObject);\nvar\n  i : Integer;\nbegin\n  with OpenDialog1 do begin\n    Filename := '*.*';\n    Options := Options + [ofAllowMultiSelect];\n    AbZipView1.BeginUpdate;\n    if Execute then for i := 0 to Pred(Files.Count) do\n      AbZipKit1.AddFiles(Files[i], 0);\n    AbZipView1.EndUpdate;\n    Panel1.Caption := '';\n    Options := Options - [ofAllowMultiSelect];\n  end;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TForm1.Delete1Click(Sender: TObject);\nvar\n  i : Longint;\nbegin\n  Panel1.Caption := '';\n  with AbZipView1 do\n    for i := 0 to Pred(Count) do\n      Items[i].Tagged := Selected[i];\n  AbZipKit1.DeleteTaggedItems;\n  Panel1.Caption := '';\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TForm1.Extract1Click(Sender: TObject);\nvar\n  i : Longint;\n  Continue : Boolean;\nbegin\n{$IFDEF Win32}\n  with TAbDirDlg.Create(Self) do begin\n    Caption := 'Directory';\n    AdditionalText := 'Select folder to extract into';\n    SelectedFolder := AbZipKit1.BaseDirectory;\n    Continue := Execute;\n    if Continue then\n      AbZipKit1.BaseDirectory := SelectedFolder;\n{$ELSE}\n  with TDirDlg.Create(Self) do begin\n    SelectedFolder := AbZipKit1.BaseDirectory;\n    Continue := (ShowModal = mrOK);\n    if Continue then\n      AbZipKit1.BaseDirectory := SelectedFolder;\n{$ENDIF}\n    Free;\n  end;\n  if not Continue then\n    Exit;\n  Panel1.Caption := '';\n  with AbZipView1 do\n    for i := 0 to Pred(Count) do\n      Items[i].Tagged := Selected[i];\n  AbZipKit1.ExtractTaggedItems;\n  AbZipView1.ClearSelections;\n  Panel1.Caption := '';\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TForm1.Freshen1Click(Sender: TObject);\nvar\n  i : Longint;\nbegin\n  Panel1.Caption := '';\n  with AbZipView1 do\n    for i := 0 to Pred(Count) do\n      Items[i].Tagged := Selected[i];\n  AbZipKit1.FreshenTaggedItems;\n  AbZipKit1.Save;\n  AbZipView1.ClearSelections;\n  Panel1.Caption := '';\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TForm1.TestSelecteditems1Click(Sender: TObject);\nvar\n  i : Longint;\nbegin\n  Panel1.Caption := '';\n  with AbZipView1 do\n    for i := 0 to Pred(Count) do\n      Items[i].Tagged := Selected[i];\n  AbZipKit1.TestTaggedItems;\n  AbZipView1.ClearSelections;\n  Panel1.Caption := '';\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TForm1.AbZipKit1ConfirmProcessItem(Sender: TObject;\n  Item: TAbArchiveItem; ProcessType: TAbProcessType; var Confirm: Boolean);\nvar\n  s : string;\nbegin\n  case ProcessType of\n    ptAdd : s := 'Adding ';\n    ptDelete : s := 'Deleting ';\n    ptExtract : s := 'Extracting ';\n    ptFreshen : s := 'Freshening ';\n  else\n    s := '??? ';\n  end;\n  Panel1.Caption := s + Item.Filename;\n  Confirm := True;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TForm1.AbZipView1Change(Sender: TObject);\nbegin\n    Caption := AbZipKit1.Filename +\n      '   ' + IntToStr(AbZipView1.Count) + ' items';\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TForm1.AlternateColor1Click(Sender: TObject);\nbegin\n  if ColorDialog1.Execute then\n    AbZipView1.Colors.Alternate := ColorDialog1.Color;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TForm1.AlternateTextColor1Click(Sender: TObject);\nbegin\n  if ColorDialog1.Execute then\n    AbZipView1.Colors.AlternateText := ColorDialog1.Color;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TForm1.Moveselecteditem1Click(Sender: TObject);\nvar\n  i : Longint;\n  s : string;\nbegin\n  with AbZipView1 do\n    if (SelCount > 0) then begin\n      for i := 0 to Pred(Count) do\n        if Selected[i] then begin\n          s := Items[i].Filename;\n          if InputQuery(MainCaption, 'Rename file', s) then\n            AbZipKit1.Move(Items[i], s);\n        end;\n      AbZipKit1.Save;\n      AbZipView1.ClearSelections;\n      Panel1.Caption := '';\n    end;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TForm1.AbZipKit1Save(Sender: TObject);\nbegin\n  Panel1.Caption := 'Saving ' + AbZipKit1.Filename;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TForm1.Save1Click(Sender: TObject);\nbegin\n  if (AbZipKit1.Filename <> '') then\n    AbZipKit1.Save;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TForm1.Logging1Click(Sender: TObject);\nbegin\n  Logging1.Checked := not Logging1.Checked;\n  if Logging1.Checked then begin\n    OpenDialog1.Title := 'Select log file';\n    if AbZipKit1.LogFile = '' then\n      OpenDialog1.Filename := '*.txt'\n    else\n      OpenDialog1.Filename := AbZipKit1.LogFile;\n    Logging1.Checked := OpenDialog1.Execute;\n    if Logging1.Checked then\n      AbZipKit1.LogFile := OpenDialog1.Filename;\n  end;\n  AbZipKit1.Logging := Logging1.Checked;\nend;\n\nend.\n"
  },
  {
    "path": "lib/abbrevia/examples/Delphi/Zipper.dpr",
    "content": "(* ***** BEGIN LICENSE BLOCK *****\n * Version: MPL 1.1\n *\n * The contents of this file are subject to the Mozilla Public License Version\n * 1.1 (the \"License\"); you may not use this file except in compliance with\n * the License. You may obtain a copy of the License at\n * http://www.mozilla.org/MPL/\n *\n * Software distributed under the License is distributed on an \"AS IS\" basis,\n * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License\n * for the specific language governing rights and limitations under the\n * License.\n *\n * The Original Code is TurboPower Abbrevia\n *\n * The Initial Developer of the Original Code is\n * TurboPower Software\n *\n * Portions created by the Initial Developer are Copyright (C) 1997-2002\n * the Initial Developer. All Rights Reserved.\n *\n * Contributor(s):\n *\n * ***** END LICENSE BLOCK ***** *)\n\n{*********************************************************}\n{* ABBREVIA: ZIPPER.DPR                                  *}\n{*********************************************************}\n{* ABBREVIA Example program file                         *}\n{*********************************************************}\n\nprogram zipper;\n\nuses\n  Forms,\n  Uzip in 'Uzip.pas' {Form1};\n\nbegin\n  Application.CreateForm(TForm1, Form1);\n  Application.Run;\nend.\n"
  },
  {
    "path": "lib/abbrevia/examples/Delphi/Zipper.dproj",
    "content": "﻿\t<Project xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n\t\t<PropertyGroup>\n\t\t\t<ProjectGuid>{3B87EA3D-333F-41D2-A7EE-A559DF4E7347}</ProjectGuid>\n\t\t\t<MainSource>Zipper.dpr</MainSource>\n\t\t\t<Base>True</Base>\n\t\t\t<Config Condition=\"'$(Config)'==''\">Debug</Config>\n\t\t\t<Platform>Win32</Platform>\n\t\t\t<AppType>Application</AppType>\n\t\t\t<FrameworkType>VCL</FrameworkType>\n\t\t\t<DCC_DCCCompiler>DCC32</DCC_DCCCompiler>\n\t\t\t<ProjectVersion>12.3</ProjectVersion>\n\t\t</PropertyGroup>\n\t\t<PropertyGroup Condition=\"'$(Config)'=='Base' or '$(Base)'!=''\">\n\t\t\t<Base>true</Base>\n\t\t</PropertyGroup>\n\t\t<PropertyGroup Condition=\"'$(Config)'=='Release' or '$(Cfg_1)'!=''\">\n\t\t\t<Cfg_1>true</Cfg_1>\n\t\t\t<CfgParent>Base</CfgParent>\n\t\t\t<Base>true</Base>\n\t\t</PropertyGroup>\n\t\t<PropertyGroup Condition=\"'$(Config)'=='Debug' or '$(Cfg_2)'!=''\">\n\t\t\t<Cfg_2>true</Cfg_2>\n\t\t\t<CfgParent>Base</CfgParent>\n\t\t\t<Base>true</Base>\n\t\t</PropertyGroup>\n\t\t<PropertyGroup Condition=\"'$(Base)'!=''\">\n\t\t\t<DCC_E>false</DCC_E>\n\t\t\t<DCC_ImageBase>00400000</DCC_ImageBase>\n\t\t\t<DCC_UnitAlias>WinTypes=Windows;WinProcs=Windows;DbiTypes=BDE;DbiProcs=BDE;DbiErrs=BDE;$(DCC_UnitAlias)</DCC_UnitAlias>\n\t\t\t<DCC_F>false</DCC_F>\n\t\t\t<DCC_S>false</DCC_S>\n\t\t\t<DCC_N>false</DCC_N>\n\t\t\t<DCC_K>false</DCC_K>\n\t\t</PropertyGroup>\n\t\t<PropertyGroup Condition=\"'$(Cfg_1)'!=''\">\n\t\t\t<DCC_LocalDebugSymbols>false</DCC_LocalDebugSymbols>\n\t\t\t<DCC_Define>RELEASE;$(DCC_Define)</DCC_Define>\n\t\t\t<DCC_SymbolReferenceInfo>0</DCC_SymbolReferenceInfo>\n\t\t\t<DCC_DebugInformation>false</DCC_DebugInformation>\n\t\t</PropertyGroup>\n\t\t<PropertyGroup Condition=\"'$(Cfg_2)'!=''\">\n\t\t\t<DCC_Define>DEBUG;$(DCC_Define)</DCC_Define>\n\t\t\t<DCC_Optimize>false</DCC_Optimize>\n\t\t\t<DCC_GenerateStackFrames>true</DCC_GenerateStackFrames>\n\t\t</PropertyGroup>\n\t\t<ItemGroup>\n\t\t\t<DelphiCompile Include=\"Zipper.dpr\">\n\t\t\t\t<MainSource>MainSource</MainSource>\n\t\t\t</DelphiCompile>\n\t\t\t<DCCReference Include=\"Uzip.pas\">\n\t\t\t\t<Form>Form1</Form>\n\t\t\t</DCCReference>\n\t\t\t<BuildConfiguration Include=\"Debug\">\n\t\t\t\t<Key>Cfg_2</Key>\n\t\t\t\t<CfgParent>Base</CfgParent>\n\t\t\t</BuildConfiguration>\n\t\t\t<BuildConfiguration Include=\"Base\">\n\t\t\t\t<Key>Base</Key>\n\t\t\t</BuildConfiguration>\n\t\t\t<BuildConfiguration Include=\"Release\">\n\t\t\t\t<Key>Cfg_1</Key>\n\t\t\t\t<CfgParent>Base</CfgParent>\n\t\t\t</BuildConfiguration>\n\t\t</ItemGroup>\n\t\t<Import Condition=\"Exists('$(BDS)\\Bin\\CodeGear.Delphi.Targets')\" Project=\"$(BDS)\\Bin\\CodeGear.Delphi.Targets\"/>\n\t\t<Import Condition=\"Exists('$(APPDATA)\\Embarcadero\\$(BDSAPPDATABASEDIR)\\$(PRODUCTVERSION)\\UserTools.proj')\" Project=\"$(APPDATA)\\Embarcadero\\$(BDSAPPDATABASEDIR)\\$(PRODUCTVERSION)\\UserTools.proj\"/>\n\t\t<ProjectExtensions>\n\t\t\t<Borland.Personality>Delphi.Personality.12</Borland.Personality>\n\t\t\t<Borland.ProjectType>VCLApplication</Borland.ProjectType>\n\t\t\t<BorlandProject>\n\t\t\t\t<Delphi.Personality>\n\t\t\t\t\t<Source>\n\t\t\t\t\t\t<Source Name=\"MainSource\">Zipper.dpr</Source>\n\t\t\t\t\t</Source>\n\t\t\t\t\t<VersionInfo>\n\t\t\t\t\t\t<VersionInfo Name=\"IncludeVerInfo\">False</VersionInfo>\n\t\t\t\t\t\t<VersionInfo Name=\"AutoIncBuild\">False</VersionInfo>\n\t\t\t\t\t\t<VersionInfo Name=\"MajorVer\">1</VersionInfo>\n\t\t\t\t\t\t<VersionInfo Name=\"MinorVer\">0</VersionInfo>\n\t\t\t\t\t\t<VersionInfo Name=\"Release\">0</VersionInfo>\n\t\t\t\t\t\t<VersionInfo Name=\"Build\">0</VersionInfo>\n\t\t\t\t\t\t<VersionInfo Name=\"Debug\">False</VersionInfo>\n\t\t\t\t\t\t<VersionInfo Name=\"PreRelease\">False</VersionInfo>\n\t\t\t\t\t\t<VersionInfo Name=\"Special\">False</VersionInfo>\n\t\t\t\t\t\t<VersionInfo Name=\"Private\">False</VersionInfo>\n\t\t\t\t\t\t<VersionInfo Name=\"DLL\">False</VersionInfo>\n\t\t\t\t\t\t<VersionInfo Name=\"Locale\">1033</VersionInfo>\n\t\t\t\t\t\t<VersionInfo Name=\"CodePage\">1252</VersionInfo>\n\t\t\t\t\t</VersionInfo>\n\t\t\t\t\t<VersionInfoKeys>\n\t\t\t\t\t\t<VersionInfoKeys Name=\"CompanyName\"/>\n\t\t\t\t\t\t<VersionInfoKeys Name=\"FileDescription\"/>\n\t\t\t\t\t\t<VersionInfoKeys Name=\"FileVersion\">1.0.0.0</VersionInfoKeys>\n\t\t\t\t\t\t<VersionInfoKeys Name=\"InternalName\"/>\n\t\t\t\t\t\t<VersionInfoKeys Name=\"LegalCopyright\"/>\n\t\t\t\t\t\t<VersionInfoKeys Name=\"LegalTrademarks\"/>\n\t\t\t\t\t\t<VersionInfoKeys Name=\"OriginalFilename\"/>\n\t\t\t\t\t\t<VersionInfoKeys Name=\"ProductName\"/>\n\t\t\t\t\t\t<VersionInfoKeys Name=\"ProductVersion\">1.0.0.0</VersionInfoKeys>\n\t\t\t\t\t\t<VersionInfoKeys Name=\"Comments\"/>\n\t\t\t\t\t</VersionInfoKeys>\n\t\t\t\t</Delphi.Personality>\n\t\t\t\t<Platforms>\n\t\t\t\t\t<Platform value=\"Win32\">True</Platform>\n\t\t\t\t</Platforms>\n\t\t\t</BorlandProject>\n\t\t\t<ProjectFileVersion>12</ProjectFileVersion>\n\t\t</ProjectExtensions>\n\t</Project>\n"
  },
  {
    "path": "lib/abbrevia/examples/Delphi/Zipper.dproj.2007",
    "content": "﻿\t<Project xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n\t\t<PropertyGroup>\n\t\t\t<ProjectGuid>{3B87EA3D-333F-41D2-A7EE-A559DF4E7347}</ProjectGuid>\n\t\t\t<MainSource>Zipper.dpr</MainSource>\n\t\t\t<Base>True</Base>\n\t\t\t<Config Condition=\"'$(Config)'==''\">Debug</Config>\n\t\t\t<Platform>Win32</Platform>\n\t\t\t<AppType>Application</AppType>\n\t\t\t<FrameworkType>VCL</FrameworkType>\n\t\t\t<DCC_DCCCompiler>DCC32</DCC_DCCCompiler>\n\t\t</PropertyGroup>\n\t\t<PropertyGroup Condition=\"'$(Config)'=='Base' or '$(Base)'!=''\">\n\t\t\t<Base>true</Base>\n\t\t</PropertyGroup>\n\t\t<PropertyGroup Condition=\"'$(Config)'=='Release' or '$(Cfg_1)'!=''\">\n\t\t\t<Cfg_1>true</Cfg_1>\n\t\t\t<CfgParent>Base</CfgParent>\n\t\t\t<Base>true</Base>\n\t\t</PropertyGroup>\n\t\t<PropertyGroup Condition=\"'$(Config)'=='Debug' or '$(Cfg_2)'!=''\">\n\t\t\t<Cfg_2>true</Cfg_2>\n\t\t\t<CfgParent>Base</CfgParent>\n\t\t\t<Base>true</Base>\n\t\t</PropertyGroup>\n\t\t<PropertyGroup Condition=\"'$(Base)'!=''\">\n\t\t\t<DCC_F>false</DCC_F>\n\t\t\t<DCC_E>false</DCC_E>\n\t\t\t<DCC_ImageBase>00400000</DCC_ImageBase>\n\t\t\t<DCC_S>false</DCC_S>\n\t\t\t<DCC_N>false</DCC_N>\n\t\t\t<DCC_K>false</DCC_K>\n\t\t</PropertyGroup>\n\t\t<PropertyGroup Condition=\"'$(Cfg_1)'!=''\">\n\t\t\t<DCC_LocalDebugSymbols>false</DCC_LocalDebugSymbols>\n\t\t\t<DCC_Define>RELEASE;$(DCC_Define)</DCC_Define>\n\t\t\t<DCC_SymbolReferenceInfo>0</DCC_SymbolReferenceInfo>\n\t\t\t<DCC_DebugInformation>false</DCC_DebugInformation>\n\t\t</PropertyGroup>\n\t\t<PropertyGroup Condition=\"'$(Cfg_2)'!=''\">\n\t\t\t<DCC_Define>DEBUG;$(DCC_Define)</DCC_Define>\n\t\t\t<DCC_Optimize>false</DCC_Optimize>\n\t\t\t<DCC_GenerateStackFrames>true</DCC_GenerateStackFrames>\n\t\t</PropertyGroup>\n\t\t<ItemGroup>\n\t\t\t<DelphiCompile Include=\"Zipper.dpr\">\n\t\t\t\t<MainSource>MainSource</MainSource>\n\t\t\t</DelphiCompile>\n\t\t\t<DCCReference Include=\"Uzip.pas\">\n\t\t\t\t<Form>Form1</Form>\n\t\t\t</DCCReference>\n\t\t\t<BuildConfiguration Include=\"Debug\">\n\t\t\t\t<Key>Cfg_2</Key>\n\t\t\t\t<CfgParent>Base</CfgParent>\n\t\t\t</BuildConfiguration>\n\t\t\t<BuildConfiguration Include=\"Base\">\n\t\t\t\t<Key>Base</Key>\n\t\t\t</BuildConfiguration>\n\t\t\t<BuildConfiguration Include=\"Release\">\n\t\t\t\t<Key>Cfg_1</Key>\n\t\t\t\t<CfgParent>Base</CfgParent>\n\t\t\t</BuildConfiguration>\n\t\t</ItemGroup>\n\t\t<Import Condition=\"Exists('$(BDS)\\Bin\\CodeGear.Delphi.Targets')\" Project=\"$(BDS)\\Bin\\CodeGear.Delphi.Targets\"/>\n\t\t<Import Condition=\"Exists('$(APPDATA)\\Embarcadero\\$(BDSAPPDATABASEDIR)\\$(PRODUCTVERSION)\\UserTools.proj')\" Project=\"$(APPDATA)\\Embarcadero\\$(BDSAPPDATABASEDIR)\\$(PRODUCTVERSION)\\UserTools.proj\"/>\n\t\t<ProjectExtensions>\n\t\t\t<Borland.Personality>Delphi.Personality.12</Borland.Personality>\n\t\t\t<Borland.ProjectType>VCLApplication</Borland.ProjectType>\n\t\t\t<BorlandProject>\n\t\t\t\t<Delphi.Personality>\n\t\t\t\t\t<Source>\n\t\t\t\t\t\t<Source Name=\"MainSource\">Zipper.dpr</Source>\n\t\t\t\t\t</Source>\n\t\t\t\t\t<VersionInfo>\n\t\t\t\t\t\t<VersionInfo Name=\"IncludeVerInfo\">False</VersionInfo>\n\t\t\t\t\t\t<VersionInfo Name=\"AutoIncBuild\">False</VersionInfo>\n\t\t\t\t\t\t<VersionInfo Name=\"MajorVer\">1</VersionInfo>\n\t\t\t\t\t\t<VersionInfo Name=\"MinorVer\">0</VersionInfo>\n\t\t\t\t\t\t<VersionInfo Name=\"Release\">0</VersionInfo>\n\t\t\t\t\t\t<VersionInfo Name=\"Build\">0</VersionInfo>\n\t\t\t\t\t\t<VersionInfo Name=\"Debug\">False</VersionInfo>\n\t\t\t\t\t\t<VersionInfo Name=\"PreRelease\">False</VersionInfo>\n\t\t\t\t\t\t<VersionInfo Name=\"Special\">False</VersionInfo>\n\t\t\t\t\t\t<VersionInfo Name=\"Private\">False</VersionInfo>\n\t\t\t\t\t\t<VersionInfo Name=\"DLL\">False</VersionInfo>\n\t\t\t\t\t\t<VersionInfo Name=\"Locale\">1033</VersionInfo>\n\t\t\t\t\t\t<VersionInfo Name=\"CodePage\">1252</VersionInfo>\n\t\t\t\t\t</VersionInfo>\n\t\t\t\t\t<VersionInfoKeys>\n\t\t\t\t\t\t<VersionInfoKeys Name=\"CompanyName\"/>\n\t\t\t\t\t\t<VersionInfoKeys Name=\"FileDescription\"/>\n\t\t\t\t\t\t<VersionInfoKeys Name=\"FileVersion\">1.0.0.0</VersionInfoKeys>\n\t\t\t\t\t\t<VersionInfoKeys Name=\"InternalName\"/>\n\t\t\t\t\t\t<VersionInfoKeys Name=\"LegalCopyright\"/>\n\t\t\t\t\t\t<VersionInfoKeys Name=\"LegalTrademarks\"/>\n\t\t\t\t\t\t<VersionInfoKeys Name=\"OriginalFilename\"/>\n\t\t\t\t\t\t<VersionInfoKeys Name=\"ProductName\"/>\n\t\t\t\t\t\t<VersionInfoKeys Name=\"ProductVersion\">1.0.0.0</VersionInfoKeys>\n\t\t\t\t\t\t<VersionInfoKeys Name=\"Comments\"/>\n\t\t\t\t\t</VersionInfoKeys>\n\t\t\t\t</Delphi.Personality>\n\t\t\t\t<Platforms>\n\t\t\t\t\t<Platform value=\"Win32\">True</Platform>\n\t\t\t\t</Platforms>\n\t\t\t</BorlandProject>\n\t\t\t<ProjectFileVersion>12</ProjectFileVersion>\n\t\t</ProjectExtensions>\n\t</Project>\n"
  },
  {
    "path": "lib/abbrevia/examples/Delphi/dgAbout.pas",
    "content": "(* ***** BEGIN LICENSE BLOCK *****\n * Version: MPL 1.1\n *\n * The contents of this file are subject to the Mozilla Public License Version\n * 1.1 (the \"License\"); you may not use this file except in compliance with\n * the License. You may obtain a copy of the License at\n * http://www.mozilla.org/MPL/\n *\n * Software distributed under the License is distributed on an \"AS IS\" basis,\n * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License\n * for the specific language governing rights and limitations under the\n * License.\n *\n * The Original Code is TurboPower Abbrevia\n *\n * The Initial Developer of the Original Code is\n * TurboPower Software\n *\n * Portions created by the Initial Developer are Copyright (C) 1997-2002\n * the Initial Developer. All Rights Reserved.\n *\n * Contributor(s):\n *\n * ***** END LICENSE BLOCK ***** *)\n\n{*********************************************************}\n{* ABBREVIA: DGABOUT.PAS                                 *}\n{* Copyright (c) TurboPower Software Co 1997             *}\n{* All rights reserved.                                  *}\n{*********************************************************}\n{* ABBREVIA Example program file                         *}\n{*********************************************************}\n\nunit dgAbout;\n\ninterface\n\nuses\n  Windows, Classes, Graphics, Forms, Controls, StdCtrls,\n  Buttons, ExtCtrls;\n\ntype\n  TdlgAboutBox = class(TForm)\n    Panel1: TPanel;\n    ProgramIcon: TImage;\n    Label7: TLabel;\n    Label8: TLabel;\n    Panel2: TPanel;\n    lnTitleShadow: TLabel;\n    lblTitle: TLabel;\n    Label5: TLabel;\n    OKButton: TButton;\n    Version: TLabel;\n    Label1: TLabel;\n    Label2: TLabel;\n    Label3: TLabel;\n    Label4: TLabel;\n    Label6: TLabel;\n    procedure FormCreate(Sender: TObject);\n  private\n    { Private declarations }\n  public\n    { Public declarations }\n  end;\n\nvar\n  dlgAboutBox: TdlgAboutBox;\n\nimplementation\n\n{$R *.DFM}\n\nuses\n  AbConst;\n\nprocedure TdlgAboutBox.FormCreate(Sender: TObject);\nbegin\n  Version.Caption := 'Abbrevia ' + AbVersionS;\nend;\n\n\n\n\n\nend.\n\n"
  },
  {
    "path": "lib/abbrevia/examples/Delphi/makesfx.dpr",
    "content": "(* ***** BEGIN LICENSE BLOCK *****\n * Version: MPL 1.1\n *\n * The contents of this file are subject to the Mozilla Public License Version\n * 1.1 (the \"License\"); you may not use this file except in compliance with\n * the License. You may obtain a copy of the License at\n * http://www.mozilla.org/MPL/\n *\n * Software distributed under the License is distributed on an \"AS IS\" basis,\n * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License\n * for the specific language governing rights and limitations under the\n * License.\n *\n * The Original Code is TurboPower Abbrevia\n *\n * The Initial Developer of the Original Code is\n * TurboPower Software\n *\n * Portions created by the Initial Developer are Copyright (C) 1997-2002\n * the Initial Developer. All Rights Reserved.\n *\n * Contributor(s):\n *\n * ***** END LICENSE BLOCK ***** *)\n\n{*********************************************************}\n{* ABBREVIA: MAKESFX.DPR                                 *}\n{*********************************************************}\n{* ABBREVIA Example program file                         *}\n{*********************************************************}\n\nprogram makesfx;\n\nuses\n  Forms,\n  umakesfx in 'umakesfx.pas' {Form1};\n\nbegin\n  Application.CreateForm(TForm1, Form1);\n  Application.Run;\nend.\n"
  },
  {
    "path": "lib/abbrevia/examples/Delphi/spntst0.pas",
    "content": "(* ***** BEGIN LICENSE BLOCK *****\n * Version: MPL 1.1\n *\n * The contents of this file are subject to the Mozilla Public License Version\n * 1.1 (the \"License\"); you may not use this file except in compliance with\n * the License. You may obtain a copy of the License at\n * http://www.mozilla.org/MPL/\n *\n * Software distributed under the License is distributed on an \"AS IS\" basis,\n * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License\n * for the specific language governing rights and limitations under the\n * License.\n *\n * The Original Code is TurboPower Abbrevia\n *\n * The Initial Developer of the Original Code is\n * TurboPower Software\n *\n * Portions created by the Initial Developer are Copyright (C) 1997-2002\n * the Initial Developer. All Rights Reserved.\n *\n * Contributor(s):\n *\n * ***** END LICENSE BLOCK ***** *)\n\nunit spntst0;\n\ninterface\n\nuses\n  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls,\n\n  {IpStrms,}\n  {StStrms,}\n\n  AbBufStm, AbBase, AbBrowse, AbZBrows, AbZipper, AbZipKit,\n  AbSpanSt, ExtCtrls;\n\ntype\n  TForm1 = class(TForm)\n    AbZipKit1: TAbZipKit;\n    Button1: TButton;\n    OpenDialog1: TOpenDialog;\n    Button3: TButton;\n    Bevel1: TBevel;\n    SaveDialog1: TSaveDialog;\n    procedure Button1Click(Sender: TObject);\n    procedure Button3Click(Sender: TObject);\n    procedure DoRequestImage(Sender: TObject; ImageNumber: Integer;\n      var ImageName: String; var Abort: Boolean);\n  private\n    { Private declarations }\n  public\n    { Public declarations }\n  end;\n\nvar\n  Form1: TForm1;\n\nimplementation\n\n{$R *.DFM}\n\nprocedure TForm1.Button1Click(Sender: TObject);\nvar\n  Span: TAbSpanStream;\n  SrcFile : TFileStream;\n  Src, Dest : string;\nbegin\n  OpenDialog1.FileName := '*.*';\n  OpenDialog1.Title := 'Select Source File';\n  if OpenDialog1.Execute then begin\n    Src := OpenDialog1.FileName;\n\n    OpenDialog1.Title := 'Specify Destination File';\n    if OpenDialog1.Execute then begin\n      Dest := OpenDialog1.FileName;\n      Span := TAbSpanStream.Create(Dest, fmCreate);\n      SrcFile := TFileStream.Create(Src, fmOpenRead);\n\n      Span.CopyFrom(SrcFile, SrcFile.Size);\n\n      Span.Free;\n      SrcFile.Free;\n\n    end;\n  end;\nend;\n\nprocedure TForm1.Button3Click(Sender: TObject);\nvar\n  Span: TAbSpanStream;\n  DestFile : TFileStream;\n  Src, Dest : string;\nbegin\n  OpenDialog1.FileName := '*.*';\n  OpenDialog1.Title := 'Select Source File';\n  if OpenDialog1.Execute then begin\n    Src := OpenDialog1.FileName;\n\n    SaveDialog1.Title := 'Specify Destination File';\n    if SaveDialog1.Execute then begin\n      Dest := SaveDialog1.FileName;\n      Span := TAbSpanStream.Create(Src, fmOpenRead);\n      Span.SpanType := stLocal;\n\n      Span.OnRequestImage := DoRequestImage;\n      DestFile := TFileStream.Create(Dest, fmCreate);\n\n      DestFile.CopyFrom(Span, 3145728{Span.Size});\n\n      Span.Free;\n      DestFile.Free;\n    end;\n  end;\nend;\n\nprocedure TForm1.DoRequestImage(Sender: TObject;\n  ImageNumber: Integer; var ImageName: String; var Abort: Boolean);\nbegin\n  Abort := not OpenDialog1.Execute;\n  if not Abort then\n    ImageName := OpenDialog1.FileName;\nend;\n\nend.\n"
  },
  {
    "path": "lib/abbrevia/examples/Delphi/uCfGenDg.pas",
    "content": "(* ***** BEGIN LICENSE BLOCK *****\n * Version: MPL 1.1\n *\n * The contents of this file are subject to the Mozilla Public License Version\n * 1.1 (the \"License\"); you may not use this file except in compliance with\n * the License. You may obtain a copy of the License at\n * http://www.mozilla.org/MPL/\n *\n * Software distributed under the License is distributed on an \"AS IS\" basis,\n * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License\n * for the specific language governing rights and limitations under the\n * License.\n *\n * The Original Code is TurboPower Abbrevia\n *\n * The Initial Developer of the Original Code is\n * TurboPower Software\n *\n * Portions created by the Initial Developer are Copyright (C) 1997-2002\n * the Initial Developer. All Rights Reserved.\n *\n * Contributor(s):\n *\n * ***** END LICENSE BLOCK ***** *)\n\nunit uCfGenDg;\n\ninterface\n\nuses\n  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,\n  StdCtrls;\n\ntype\n  TfrmCfGenDlg = class(TForm)\n    Label1: TLabel;\n    Edit1: TEdit;\n    btnCancel: TButton;\n    btnOK: TButton;\n    procedure btnOKClick(Sender: TObject);\n    procedure FormShow(Sender: TObject);\n  private\n    { Private declarations }\n  public\n    { Public declarations }\n  end;\n\nvar\n  frmCfGenDlg: TfrmCfGenDlg;\n\nimplementation\n\n{$R *.DFM}\n\nprocedure TfrmCfGenDlg.btnOKClick(Sender: TObject);\nbegin\n  if Edit1.Text <> '' then\n    ModalResult := mrOK;\nend;\n\nprocedure TfrmCfGenDlg.FormShow(Sender: TObject);\nbegin\n  Edit1.Text := '';\n  Edit1.SetFocus;\nend;\n\nend.\n"
  },
  {
    "path": "lib/abbrevia/examples/Delphi/uCfMain.pas",
    "content": "(* ***** BEGIN LICENSE BLOCK *****\n * Version: MPL 1.1\n *\n * The contents of this file are subject to the Mozilla Public License Version\n * 1.1 (the \"License\"); you may not use this file except in compliance with\n * the License. You may obtain a copy of the License at\n * http://www.mozilla.org/MPL/\n *\n * Software distributed under the License is distributed on an \"AS IS\" basis,\n * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License\n * for the specific language governing rights and limitations under the\n * License.\n *\n * The Original Code is TurboPower Abbrevia\n *\n * The Initial Developer of the Original Code is\n * TurboPower Software\n *\n * Portions created by the Initial Developer are Copyright (C) 1997-2002\n * the Initial Developer. All Rights Reserved.\n *\n * Contributor(s):\n *\n * ***** END LICENSE BLOCK ***** *)\n\n{*********************************************************}\n{* ABBREVIA: UCFMAIN.PAS                                 *}\n{* Copyright (c) TurboPower Software Co 1997             *}\n{* All rights reserved.                                  *}\n{*********************************************************}\n{* ABBREVIA Example program file                         *}\n{*********************************************************}\n\nunit uCfMain;\n\ninterface\n\nuses\n  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,\n  ExtCtrls, Menus, ImgList, ComCtrls,\n\n  AbHexVw, AbCompnd;\n\ntype\n  TfmCfMain = class(TForm)\n    StatusBar1: TStatusBar;\n    tvDirectory: TTreeView;\n    tvImages: TImageList;\n    OpenDialog1: TOpenDialog;\n    mnuMain: TMainMenu;\n    mnuFile: TMenuItem;\n    mnuFileNew: TMenuItem;\n    mnuFileOpen: TMenuItem;\n    N6: TMenuItem;\n    mnuFileExit: TMenuItem;\n    mnuEdit: TMenuItem;\n    mnuEditAddFile: TMenuItem;\n    mnuEditAddFolder: TMenuItem;\n    mnuEditDelete: TMenuItem;\n    N1: TMenuItem;\n    mnuEditChangeDir: TMenuItem;\n    mnuPopupMenu: TPopupMenu;\n    puAddFile: TMenuItem;\n    puAddFolder: TMenuItem;\n    puViewFile: TMenuItem;\n    puChangeDir: TMenuItem;\n    puViewCompoundFile: TMenuItem;\n    puDelete: TMenuItem;\n    Rename1: TMenuItem;\n    SaveDialog1: TSaveDialog;\n    OpenDialog2: TOpenDialog;\n    pnlHexView: TPanel;\n    procedure mnuFileNewClick(Sender: TObject);\n    procedure mnuFileOpenClick(Sender: TObject);\n    procedure mnuFileExitClick(Sender: TObject);\n    procedure mnuEditAddFileClick(Sender: TObject);\n    procedure mnuEditAddFolderClick(Sender: TObject);\n    procedure mnuEditDeleteClick(Sender: TObject);\n    procedure mnuEditChangeDirClick(Sender: TObject);\n    procedure puViewFileClick(Sender: TObject);\n    procedure puViewCompoundFileClick(Sender: TObject);\n    procedure Rename1Click(Sender: TObject);\n    procedure tvDirectoryClick(Sender: TObject);\n    procedure FormDestroy(Sender: TObject);\n  private\n    { Private declarations }\n  public\n    { Public declarations }\n  end;\n\nvar\n  fmCfMain: TfmCfMain;\n  AbCompoundFile1 : TAbCompoundFile;\n  HexV : THexView;\n\nimplementation\n\nuses uCfNewDg, uCfGenDg;\n\n{$R *.DFM}\n\nprocedure TfmCfMain.mnuFileNewClick(Sender: TObject);\nvar\n  AllocSize : Integer;\nbegin\n  if SaveDialog1.Execute then begin\n    if frmCfNewDlg.ShowModal = mrOK then begin\n      if AbCompoundFile1 <> nil then\n        AbCompoundFile1.Free;\n      AllocSize := StrToInt(frmCfNewDlg.lbAllocSize.\n                            Items[frmCfNewDlg.lbAllocSize.ItemIndex]);\n      AbCompoundFile1 := TAbCompoundFile.Create(SaveDialog1.FileName,\n                                         frmCfNewDlg.edtVolLbl.Text, AllocSize);\n      Caption := 'Abbrevia 3 Compound File Example (' + SaveDialog1.FileName + ')';\n      HexV := THexView.Create(Self);\n      HexV.BlockSize := AllocSize;\n      HexV.Parent := pnlHexView;\n      HexV.Align := alClient;\n      HexV.Stream := AbCompoundFile1.Stream;\n      AbCompoundFile1.PopulateTreeView(tvDirectory);\n    end;\n  end;\nend;\n\nprocedure TfmCfMain.mnuFileOpenClick(Sender: TObject);\nbegin\n  {OpenExisting compound file}\n  if OpenDialog1.Execute then begin\n    if AbCompoundFile1 <> nil then\n      AbCompoundFile1.Free;\n    AbCompoundFile1 := TAbCompoundFile.Create('', '', 512);\n    AbCompoundFile1.Open(OpenDialog1.FileName);\n    Caption := 'Abbrevia 3 Compound File Example (' + OpenDialog1.FileName + ')';\n    HexV := THexView.Create(Self);\n    HexV.BlockSize := AbCompoundFile1.AllocationSize;\n    HexV.Parent := pnlHexView;\n    HexV.Align := alClient;\n    HexV.Stream := AbCompoundFile1.Stream;\n    AbCompoundFile1.PopulateTreeView(tvDirectory);\n  end;\nend;\n\nprocedure TfmCfMain.mnuFileExitClick(Sender: TObject);\nbegin\n  Application.Terminate;\nend;\n\nprocedure TfmCfMain.mnuEditAddFileClick(Sender: TObject);\nvar\n  i : Integer;\n  Strm : TFileStream;\nbegin\n  if OpenDialog2.Execute then begin\n    Strm := TFileStream.Create(OpenDialog2.FileName, fmOpenRead\n                               or fmShareDenyNone);\n    AbCompoundFile1.AddFile(OpenDialog2.FileName, Strm, Strm.Size);\n    Strm.Free;\n    AbCompoundFile1.PopulateTreeView(tvDirectory);\n    for i := 0 to tvDirectory.Items.Count - 1 do\n      tvDirectory.Items.Item[i].Expand(True);\n    HexV.Stream := AbCompoundFile1.Stream;\n  end;\nend;\n\nprocedure TfmCfMain.mnuEditAddFolderClick(Sender: TObject);\nvar\n  i : Integer;\nbegin\n  if frmCfGenDlg.ShowModal = mrOK then begin\n    AbCompoundFile1.AddFolder(frmCfGenDlg.Edit1.Text);\n    AbCompoundFile1.PopulateTreeView(tvDirectory);\n    for i := 0 to tvDirectory.Items.Count - 1 do\n      tvDirectory.Items.Item[i].Expand(True);\n  end;\n  HexV.Stream := AbCompoundFile1.Stream;\nend;\n\nprocedure TfmCfMain.mnuEditDeleteClick(Sender: TObject);\nvar\n  i : Integer;\nbegin\n  if tvDirectory.Selected.ImageIndex = 0 then\n    AbCompoundFile1.DeleteFolder(tvDirectory.Selected.Text)\n  else\n    AbCompoundFile1.DeleteFile(tvDirectory.Selected.Text);\n  HexV.Stream := AbCompoundFile1.Stream;\n  AbCompoundFile1.PopulateTreeView(tvDirectory);\n\n  for i := 0 to tvDirectory.Items.Count - 1 do\n    tvDirectory.Items.Item[i].Expand(True);\nend;\n\nprocedure TfmCfMain.mnuEditChangeDirClick(Sender: TObject);\nbegin\n  frmCfGenDlg.Caption := AbCompoundFile1.CurrentDirectory;\n  if frmCfGenDlg.ShowModal = mrOK then begin\n    AbCompoundFile1.CurrentDirectory := frmCfGenDlg.Edit1.Text;\n    StatusBar1.SimpleText := '  Current Directory: ' + AbCompoundFile1.CurrentDirectory;\n  end;\nend;\n\nprocedure TfmCfMain.puViewFileClick(Sender: TObject);\nvar\n  Strm : TStream;\nbegin\n  Strm := TMemoryStream.Create;\n  AbCompoundFile1.OpenFile(tvDirectory.Selected.Text, Strm);\n  Hexv.SetStream(Strm);\n  Strm.Free;\nend;\n\nprocedure TfmCfMain.puViewCompoundFileClick(Sender: TObject);\nbegin\n  HexV.Stream := AbCompoundFile1.Stream;\nend;\n\nprocedure TfmCfMain.Rename1Click(Sender: TObject);\nbegin\n  frmCfGenDlg.Caption := 'Rename';\n  frmCfGenDlg.Label1.Caption := 'New Name';\n  if frmCfGenDlg.ShowModal = mrOK then begin\n    if tvDirectory.Selected.ImageIndex = 0 then\n      AbCompoundFile1.RenameFolder(tvDirectory.Selected.Text, frmCfGenDlg.Edit1.Text)\n    else\n      AbCompoundFile1.RenameFile(tvDirectory.Selected.Text, frmCfGenDlg.Edit1.Text);\n  end;\n  frmCfGenDlg.Caption := 'Change Directory';\n  frmCfGenDlg.Label1.Caption := 'New Directory';\nend;\n\nprocedure TfmCfMain.tvDirectoryClick(Sender: TObject);\nbegin\n  if not Assigned(tvDirectory.Selected) then\n    tvDirectory.Selected := tvDirectory.TopItem;\n  if (tvDirectory.Selected.ImageIndex = 0) then begin\n    AbCompoundFile1.CurrentDirectory := tvDirectory.Selected.Text;\n    StatusBar1.SimpleText := '  Current Directory: ' + AbCompoundFile1.CurrentDirectory;\n  end;  \nend;\n\nprocedure TfmCfMain.FormDestroy(Sender: TObject);\nbegin\n  if AbCompoundFile1 <> nil then\n    AbCompoundFile1.Free;\nend;\n\nend.\n"
  },
  {
    "path": "lib/abbrevia/examples/Delphi/uCfNewDg.pas",
    "content": "(* ***** BEGIN LICENSE BLOCK *****\n * Version: MPL 1.1\n *\n * The contents of this file are subject to the Mozilla Public License Version\n * 1.1 (the \"License\"); you may not use this file except in compliance with\n * the License. You may obtain a copy of the License at\n * http://www.mozilla.org/MPL/\n *\n * Software distributed under the License is distributed on an \"AS IS\" basis,\n * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License\n * for the specific language governing rights and limitations under the\n * License.\n *\n * The Original Code is TurboPower Abbrevia\n *\n * The Initial Developer of the Original Code is\n * TurboPower Software\n *\n * Portions created by the Initial Developer are Copyright (C) 1997-2002\n * the Initial Developer. All Rights Reserved.\n *\n * Contributor(s):\n *\n * ***** END LICENSE BLOCK ***** *)\n\nunit uCfNewDg;\n\ninterface\n\nuses\n  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,\n  StdCtrls;\n\ntype\n  TfrmCfNewDlg = class(TForm)\n    Label1: TLabel;\n    edtVolLbl: TEdit;\n    Label2: TLabel;\n    lbAllocSize: TListBox;\n    btnCancel: TButton;\n    btnOK: TButton;\n    procedure FormShow(Sender: TObject);\n    procedure btnOKClick(Sender: TObject);\n  private\n    { Private declarations }\n  public\n    { Public declarations }\n  end;\n\nvar\n  frmCfNewDlg: TfrmCfNewDlg;\n\nimplementation\n\n{$R *.DFM}\n\nprocedure TfrmCfNewDlg.FormShow(Sender: TObject);\nbegin\n  lbAllocSize.ItemIndex := 2;\n  edtVolLbl.SetFocus;  \nend;\n\nprocedure TfrmCfNewDlg.btnOKClick(Sender: TObject);\nbegin\n  if edtVolLbl.Text = '' then begin\n    ShowMessage('Volume label required');\n    edtVolLbl.SetFocus;\n  end else\n    ModalResult := mrOK;\nend;\n\nend.\n"
  },
  {
    "path": "lib/abbrevia/examples/Delphi/ubasedlg.pas",
    "content": "(* ***** BEGIN LICENSE BLOCK *****\n * Version: MPL 1.1\n *\n * The contents of this file are subject to the Mozilla Public License Version\n * 1.1 (the \"License\"); you may not use this file except in compliance with\n * the License. You may obtain a copy of the License at\n * http://www.mozilla.org/MPL/\n *\n * Software distributed under the License is distributed on an \"AS IS\" basis,\n * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License\n * for the specific language governing rights and limitations under the\n * License.\n *\n * The Original Code is TurboPower Abbrevia\n *\n * The Initial Developer of the Original Code is\n * TurboPower Software\n *\n * Portions created by the Initial Developer are Copyright (C) 1997-2002\n * the Initial Developer. All Rights Reserved.\n *\n * Contributor(s):\n *\n * ***** END LICENSE BLOCK ***** *)\n\n{*********************************************************}\n{* ABBREVIA: UBASEDLG.PAS                                *}\n{* Copyright (c) TurboPower Software Co 1997             *}\n{* All rights reserved.                                  *}\n{*********************************************************}\n{* ABBREVIA Example program file                         *}\n{*********************************************************}\n\nunit ubasedlg;\n\ninterface\n\nuses\n  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,\n  StdCtrls, FileCtrl;\n\ntype\n  TBaseDirDlg = class(TForm)\n    Button1: TButton;\n    Button2: TButton;\n    Edit1: TEdit;\n    DriveComboBox1: TDriveComboBox;\n    DLB: TDirectoryListBox;\n    DirLabel: TLabel;\n    ActionLabel: TLabel;\n    CheckBox2: TCheckBox;\n    CheckBox1: TCheckBox;\n    Button3: TButton;\n    procedure Button3Click(Sender: TObject);\n  private\n    { Private declarations }\n  public\n    { Public declarations }\n  end;\n\nvar\n  BaseDirDlg: TBaseDirDlg;\n\nimplementation\n\n{$R *.DFM}\n\nuses\n  AbUtils,\n  uDemoDlg;\n\nprocedure TBaseDirDlg.Button3Click(Sender: TObject);\nbegin\n  DemoDlg := TDemoDlg.Create( Self );\n  try\n    DemoDlg.Caption := 'Create Subdirectory';\n    DemoDlg.Edit1.Text := '';\n    DemoDlg.ShowModal;\n    if ( DemoDlg.ModalResult = mrOK ) and ( DemoDlg.Edit1.Text <> '' ) then\n      AbCreateDirectory( DLB.Directory + '\\' + DemoDlg.Edit1.Text );\n    DLB.Update;\n  finally\n    DemoDlg.Free;\n  end;\nend;\n\nend.\n"
  },
  {
    "path": "lib/abbrevia/examples/Delphi/ucomppad.pas",
    "content": "(* ***** BEGIN LICENSE BLOCK *****\n * Version: MPL 1.1\n *\n * The contents of this file are subject to the Mozilla Public License Version\n * 1.1 (the \"License\"); you may not use this file except in compliance with\n * the License. You may obtain a copy of the License at\n * http://www.mozilla.org/MPL/\n *\n * Software distributed under the License is distributed on an \"AS IS\" basis,\n * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License\n * for the specific language governing rights and limitations under the\n * License.\n *\n * The Original Code is TurboPower Abbrevia\n *\n * The Initial Developer of the Original Code is\n * TurboPower Software\n *\n * Portions created by the Initial Developer are Copyright (C) 1997-2002\n * the Initial Developer. All Rights Reserved.\n *\n * Contributor(s):\n *\n * ***** END LICENSE BLOCK ***** *)\n\n{*********************************************************}\n{* ABBREVIA: UCOMPPAD.PAS                                *}\n{* Copyright (c) TurboPower Software Co 1997             *}\n{* All rights reserved.                                  *}\n{*********************************************************}\n{* ABBREVIA Example program file                         *}\n{*********************************************************}\n\nunit ucomppad;\n\ninterface\n\nuses\n  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,\n  StdCtrls, Menus, ExtCtrls,\n\n  AbZBrows, AbZipper, AbZipKit, AbArcTyp, AbBrowse, AbBase;\n\ntype\n  TForm1 = class(TForm)\n    Memo1: TMemo;\n    AbZipKit1: TAbZipKit;\n    Panel1: TPanel;\n    Memo2: TMemo;\n    procedure FormCreate(Sender: TObject);\n    procedure FormDestroy(Sender: TObject);\n  private\n    { Private declarations }\n    ZnfName : string;\n    TxtName : string;\n  public\n    { Public declarations }\n  end;\n\nvar\n  Form1: TForm1;\n\nimplementation\n\n{$R *.DFM}\n\nprocedure TForm1.FormCreate(Sender: TObject);\nbegin\n  ZnfName := ChangeFileExt(Application.ExeName, '.zip');\n  TxtName := ExtractFileName( ChangeFileExt(Application.ExeName, '.txt') );\n  with AbZipKit1 do begin\n    BaseDirectory := ExtractFilePath( Application.ExeName );\n    ChDir( BaseDirectory );\n    FileName := ZnfName;\n    if Count > 0 then begin\n      ExtractFiles( TxtName );\n      Memo1.Lines.LoadFromFile( TxtName );\n    end;\n  end;\nend;\n\nprocedure TForm1.FormDestroy(Sender: TObject);\nbegin\n  Memo1.Lines.SaveToFile( TxtName );\n  with AbZipKit1 do begin\n    if Count = 0 then\n      AddFiles( TxtName, 0 )\n    else\n      FreshenFiles( TxtName );\n    Save;\n  end;\n  DeleteFile( TxtName );\nend;\n\nend.\n"
  },
  {
    "path": "lib/abbrevia/examples/Delphi/udemodlg.pas",
    "content": "(* ***** BEGIN LICENSE BLOCK *****\n * Version: MPL 1.1\n *\n * The contents of this file are subject to the Mozilla Public License Version\n * 1.1 (the \"License\"); you may not use this file except in compliance with\n * the License. You may obtain a copy of the License at\n * http://www.mozilla.org/MPL/\n *\n * Software distributed under the License is distributed on an \"AS IS\" basis,\n * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License\n * for the specific language governing rights and limitations under the\n * License.\n *\n * The Original Code is TurboPower Abbrevia\n *\n * The Initial Developer of the Original Code is\n * TurboPower Software\n *\n * Portions created by the Initial Developer are Copyright (C) 1997-2002\n * the Initial Developer. All Rights Reserved.\n *\n * Contributor(s):\n *\n * ***** END LICENSE BLOCK ***** *)\n\n{*********************************************************}\n{* ABBREVIA: UDEMODLG.PAS                                *}\n{* Copyright (c) TurboPower Software Co 1997             *}\n{* All rights reserved.                                  *}\n{*********************************************************}\n{* ABBREVIA Example program file                         *}\n{*********************************************************}\n\nunit udemodlg;\n\ninterface\n\nuses\n  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,\n  StdCtrls;\n\ntype\n  TDemoDlg = class(TForm)\n    Button1: TButton;\n    Button2: TButton;\n    Edit1: TEdit;\n  private\n    { Private declarations }\n  public\n    { Public declarations }\n  end;\n\nvar\n  DemoDlg: TDemoDlg;\n\nimplementation\n\n{$R *.DFM}\n\nend.\n"
  },
  {
    "path": "lib/abbrevia/examples/Delphi/ufinder.pas",
    "content": "(* ***** BEGIN LICENSE BLOCK *****\n * Version: MPL 1.1\n *\n * The contents of this file are subject to the Mozilla Public License Version\n * 1.1 (the \"License\"); you may not use this file except in compliance with\n * the License. You may obtain a copy of the License at\n * http://www.mozilla.org/MPL/\n *\n * Software distributed under the License is distributed on an \"AS IS\" basis,\n * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License\n * for the specific language governing rights and limitations under the\n * License.\n *\n * The Original Code is TurboPower Abbrevia\n *\n * The Initial Developer of the Original Code is\n * TurboPower Software\n *\n * Portions created by the Initial Developer are Copyright (C) 1997-2002\n * the Initial Developer. All Rights Reserved.\n *\n * Contributor(s):\n *\n * ***** END LICENSE BLOCK ***** *)\n\n{*********************************************************}\n{* ABBREVIA: UFINDER.PAS                                 *}\n{* Copyright (c) TurboPower Software Co 1997             *}\n{* All rights reserved.                                  *}\n{*********************************************************}\n{* ABBREVIA Example program file                         *}\n{*********************************************************}\n\nunit ufinder;\n\ninterface\n\nuses\n  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,\n  StdCtrls, FileCtrl, Buttons, ExtCtrls,\n\n  AbZBrows, AbArcTyp, AbBrowse, AbBase;\n\ntype\n  TForm1 = class(TForm)\n    Edit1: TEdit;\n    Label1: TLabel;\n    Memo1: TMemo;\n    DriveComboBox1: TDriveComboBox;\n    DirectoryListBox1: TDirectoryListBox;\n    AbZipBrowser1: TAbZipBrowser;\n    Memo2: TMemo;\n    Label2: TLabel;\n    Button1: TButton;\n    Button2: TButton;\n    FileListBox1: TFileListBox;\n    procedure FormClose(Sender: TObject; var Action: TCloseAction);\n    procedure Edit1Change(Sender: TObject);\n    procedure Button1Click(Sender: TObject);\n    procedure Button2Click(Sender: TObject);\n  private\n    { Private declarations }\n    Aborted: Boolean;\n  public\n    { Public declarations }\n  end;\n\nvar\n  Form1: TForm1;\n\nimplementation\n\n{$R *.DFM}\n\nprocedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);\nbegin\n  Aborted := True;\nend;\n\nprocedure TForm1.Edit1Change(Sender: TObject);\nbegin\n  Button1.Enabled := Length( Edit1.Text ) > 0;\nend;\n\nprocedure TForm1.Button1Click(Sender: TObject);\nvar\n  i, j : Integer;\n  CurFile : string;\nbegin\n  Button1.Enabled := False;\n  Memo1.Clear;\n  try\n    Button2.Enabled := True;\n    Aborted := False;\n    {look in the file list box for the file}\n    for i := 0 to pred( FileListBox1.Items.Count ) do begin\n      Application.ProcessMessages;\n      if Aborted then\n        Break;\n      {now add search of zip and self extracting files}\n      try\n        AbZipBrowser1.FileName := FileListBox1.Directory + '\\' + FileListBox1.Items[i];\n        for j := 0 to AbZipBrowser1.Count - 1 do\n          if AbZipBrowser1[j].MatchesStoredName(Edit1.Text) then begin\n            Memo1.Lines.Add( 'Found in ' + FileListBox1.Items[i] );\n            Break;\n          end;\n      except\n      end;\n    end;\n  finally\n    Memo1.Lines.Add( 'Done!' );\n    Edit1.Enabled := True;\n    Button1.Enabled := True;\n    Button2.Enabled := False;\n  end;\nend;\n\nprocedure TForm1.Button2Click(Sender: TObject);\nbegin\n  Aborted := True;\nend;\n\nend.\n"
  },
  {
    "path": "lib/abbrevia/examples/Delphi/umakesfx.pas",
    "content": "(* ***** BEGIN LICENSE BLOCK *****\n * Version: MPL 1.1\n *\n * The contents of this file are subject to the Mozilla Public License Version\n * 1.1 (the \"License\"); you may not use this file except in compliance with\n * the License. You may obtain a copy of the License at\n * http://www.mozilla.org/MPL/\n *\n * Software distributed under the License is distributed on an \"AS IS\" basis,\n * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License\n * for the specific language governing rights and limitations under the\n * License.\n *\n * The Original Code is TurboPower Abbrevia\n *\n * The Initial Developer of the Original Code is\n * TurboPower Software\n *\n * Portions created by the Initial Developer are Copyright (C) 1997-2002\n * the Initial Developer. All Rights Reserved.\n *\n * Contributor(s):\n *\n * ***** END LICENSE BLOCK ***** *)\n\n{*********************************************************}\n{* ABBREVIA: UMAKESFX.PAS                                *}\n{* Copyright (c) TurboPower Software Co 1997             *}\n{* All rights reserved.                                  *}\n{*********************************************************}\n{* ABBREVIA Example program file                         *}\n{*********************************************************}\n\nunit umakesfx;\n\ninterface\n\nuses\n  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls,\n\n  AbArcTyp, AbSelfEx, AbBase;\n\ntype\n  TForm1 = class(TForm)\n    Memo1: TMemo;\n    Button1: TButton;\n    AbMakeSelfExe1: TAbMakeSelfExe;\n    OpenDialog1: TOpenDialog;\n    procedure Button1Click(Sender: TObject);\n    procedure AbMakeSelfExe1GetStubExe(Sender: TObject;\n      var aFilename: string; var Abort: Boolean);\n    procedure AbMakeSelfExe1GetZipFile(Sender: TObject;\n      var aFilename: string; var Abort: Boolean);\n  private\n    { Private declarations }\n  public\n    { Public declarations }\n  end;\n\nvar\n  Form1: TForm1;\n\nimplementation\n\n{$R *.DFM}\nuses\n  AbZipTyp;\n\nprocedure TForm1.Button1Click(Sender: TObject);\nbegin\n if AbMakeSelfExe1.Execute then\n   ShowMessage(AbMakeSelfExe1.SelfExe + ' has been created');\nend;\n\nprocedure TForm1.AbMakeSelfExe1GetStubExe(Sender: TObject;\n  var aFilename: string; var Abort: Boolean);\nbegin\n  OpenDialog1.Title := 'Select executable stub';\n  OpenDialog1.Filename := '';\n  OpenDialog1.Filter := 'Exe files|*.exe';\n  Abort := not OpenDialog1.Execute;\n  if not Abort then\n    aFileName := OpenDialog1.Filename;\nend;\n\nprocedure TForm1.AbMakeSelfExe1GetZipFile(Sender: TObject;\n  var aFilename: string; var Abort: Boolean);\nbegin\n  OpenDialog1.Title := 'Select Zip File';\n  OpenDialog1.Filename := '';\n  OpenDialog1.Filter := 'Zip files|*.zip';\n  Abort := not OpenDialog1.Execute;\n  if not Abort then\n    aFileName := OpenDialog1.Filename;\nend;\n\nend.\n"
  },
  {
    "path": "lib/abbrevia/examples/Delphi/usplash.pas",
    "content": "(* ***** BEGIN LICENSE BLOCK *****\n * Version: MPL 1.1\n *\n * The contents of this file are subject to the Mozilla Public License Version\n * 1.1 (the \"License\"); you may not use this file except in compliance with\n * the License. You may obtain a copy of the License at\n * http://www.mozilla.org/MPL/\n *\n * Software distributed under the License is distributed on an \"AS IS\" basis,\n * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License\n * for the specific language governing rights and limitations under the\n * License.\n *\n * The Original Code is TurboPower Abbrevia\n *\n * The Initial Developer of the Original Code is\n * TurboPower Software\n *\n * Portions created by the Initial Developer are Copyright (C) 1997-2002\n * the Initial Developer. All Rights Reserved.\n *\n * Contributor(s):\n *\n * ***** END LICENSE BLOCK ***** *)\n\n{*********************************************************}\n{* ABBREVIA: USPLASH.PAS                                 *}\n{* Copyright (c) TurboPower Software Co 1997             *}\n{* All rights reserved.                                  *}\n{*********************************************************}\n{* ABBREVIA Example program file                         *}\n{*********************************************************}\n\nunit usplash;\n\ninterface\n\nuses\n  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,\n  ExtCtrls;\n\ntype\n  TSplash = class(TForm)\n    Image1: TImage;\n    Timer1: TTimer;\n    procedure Timer1Timer(Sender: TObject);\n  private\n    { Private declarations }\n  public\n    { Public declarations }\n  end;\n\nvar\n  Splash: TSplash;\n\nimplementation\n\n{$R *.DFM}\n\nprocedure TSplash.Timer1Timer(Sender: TObject);\nbegin\n  Close;\nend;\n\nend.\n"
  },
  {
    "path": "lib/abbrevia/localization/AbResString.pas.afr",
    "content": "(* ***** BEGIN LICENSE BLOCK *****\n * Version: MPL 1.1\n *\n * The contents of this file are subject to the Mozilla Public License Version\n * 1.1 (the \"License\"); you may not use this file except in compliance with\n * the License. You may obtain a copy of the License at\n * http://www.mozilla.org/MPL/\n *\n * Software distributed under the License is distributed on an \"AS IS\" basis,\n * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License\n * for the specific language governing rights and limitations under the\n * License.\n *\n * The Original Code is TurboPower Abbrevia\n *\n * The Initial Developer of the Original Code is\n * TurboPower Software\n *\n * Portions created by the Initial Developer are Copyright (C) 1997-2002\n * the Initial Developer. All Rights Reserved.\n *\n * Contributor(s):\n * Henri Hakl, Roman Kassebaum\n *\n * ***** END LICENSE BLOCK ***** *)\n\n{*********************************************************}\n{* Abbrevia: AbResString.pas                             *}\n{*********************************************************}\n{* Abbrevia: Resource strings, Africaans localization    *}\n{*********************************************************}\nunit AbResString;\n\ninterface\n\nresourcestring\n  AbErrZipInvalidS = 'Ongeldig - geen PKZIP bestaan nie';\n  AbZipVersionNeededS = 'Ler kannie ontpak word nie - kry nuwer weergawe van PKZIP';\n  AbUnknownCompressionMethodS = 'Ler kannie ontpak word nie - onbekende kompressiemetode'; \n  AbNoExtractionMethodS = 'Ler kannie ontpak word nie - geen ondersteunende metode'; \n  AbInvalidPasswordS = 'Ler kannie ontpak word nie - ongeldige paswoord'; \n  AbNoInsertionMethodS = 'Ler kannie bygevoeg word nie - byvoeging is nie ondersteun nie'; \n  AbInvalidFactorS = 'Ongeldige reduksiefaktoor'; \n  AbDuplicateNameS = 'Ler kannie bygevoeg word nie - tweevoud by name gevind'; \n  AbUnsupportedCompressionMethodS = 'Ler kannie bygevoeg word nie - nie ondersteunde kompressiemetode'; \n  AbUserAbortS = 'Proses is deur gebruiker onderbreek';\n  AbArchiveBusyS = 'Argief is besig - kan nuwe aanvrag nie bewerk nie'; \n  AbLastDiskRequestS = 'Benodig laaste skyf van gedeelde argief'; \n  AbDiskRequestS = 'Benodig skyf'; \n  AbImageRequestS = 'Benodig naam';\n  AbBadSpanStreamS = 'Gedeelde argief moet als bestandsstroom geopen word'; \n  AbDiskNumRequestS = 'Benodig skyf %d van gedeelde argief'; \n  AbImageNumRequestS = 'Benodig segment %d van gedeelde argief';\n  AbNoOverwriteSpanStreamS = 'Kannie bestaande gedeelde argief verander nie'; \n  AbNoSpannedSelfExtractS = 'Kannie selfontpakkende gedeelde argief maak nie'; \n  AbBlankDiskS = 'Benodig le skyf'; \n  AbStreamFullS = 'Stroom skryffout'; \n  AbNoSuchDirectoryS = 'Gids bestaan nie'; \n  AbInflateBlockErrorS = 'Kannie blok ontpak nie'; \n  AbBadStreamTypeS = 'Ongeldige stroom';\n  AbTruncateErrorS = 'Daar bestaan in afknottings fout in zip-ler'; \n  AbZipBadCRCS = 'CRC kontroole his misluk'; \n  AbZipBadStubS = 'Stomp moet uitvoerbaar wees'; \n  AbFileNotFoundS = 'Ler nie gevind nie'; \n  AbInvalidLFHS = 'Ongeldige lokaale ler obskrif element';\n  AbNoArchiveS = 'Argief bestaan nie'; \n  AbReadErrorS = 'Leesfout in argief'; \n  AbInvalidIndexS = 'Ongeldige indeks van argiefelement'; \n  AbInvalidThresholdS = 'Ongeldige drempel van argiefgroote';\n  AbUnhandledFileTypeS = 'Onbekende argieftype'; \n  AbSpanningNotSupportedS = 'Argief deeling is nie ondersteun nie'; \n  AbLogCreateErrorS = 'Fout gedurende protokol skepping'; \n  AbMoveFileErrorS = 'Fout gedurende verplasing van ler van %s na %s'; \n  AbFileSizeTooBigS = 'Ler is te groot vir argieftype'; \n\n  AbNoCabinetDllErrorS = 'Kannie ler cabinet.dll laai nie'; \n  AbFCIFileOpenErrorS = 'FCI kannie ler oopmaak nie'; \n  AbFCIFileReadErrorS = 'FCI kannie ler lees nie'; \n  AbFCIFileWriteErrorS = 'FCI kannie ler skryf nie'; \n  AbFCIFileCloseErrorS = 'FCI kannie ler toemaak nie'; \n  AbFCIFileSeekErrorS = 'FCI kannie posisie verander nie'; \n  AbFCIFileDeleteErrorS = 'FCI kannie ler verwyder nie'; \n  AbFCIAddFileErrorS = 'FCI kannie ler byvoeg nie'; \n  AbFCICreateErrorS = 'FCI kannie conteks skep nie'; \n  AbFCIFlushCabinetErrorS = 'FCI kannie kabinet spoel nie'; \n  AbFCIFlushFolderErrorS = 'FCI kannie gids spoel nie'; \n  AbFDICopyErrorS = 'FDI kannie ler opsom nie'; \n  AbFDICreateErrorS = 'FDI kannie konteks skep nie'; \n  AbInvalidCabTemplateS = 'Ongeldige kabinet sjabloon'; \n  AbInvalidCabFileS = 'Ongeldiger ler - geen kabinet bestaan nie'; \n\n  AbZipStored = 'Opgeslagen';\n  AbZipShrunk = 'Gekrimp'; \n  AbZipReduced = 'Verminder'; \n  AbZipImploded = 'Gemplodeerd';\n  AbZipTokenized = 'In simboole gepak'; \n  AbZipDeflated = 'Gedeflationeerd';\n  AbZipDeflate64 = 'Uitgebreid gedeflationeerd';\n  AbZipDCLImploded = 'DCL gemplodeerd';\n  AbZipBzip2 = 'Bzip2';\n  AbZipLZMA = 'LZMA';\n  AbZipIBMTerse = 'IBM Terse';\n  AbZipLZ77 = 'IBM LZ77';\n  AbZipJPEG = 'JPEG';\n  AbZipWavPack = 'WavPack';\n  AbZipPPMd = 'PPMd';\n  AbZipUnknown = 'Onbekend (%d)';\n  AbZipBestMethod = 'Beste metode'; \n\n  AbVersionFormatS = 'Weergawe'; \n  AbCompressedSizeFormatS = 'Gekomprimeerde groote: %d'; \n  AbUncompressedSizeFormatS = 'Ongekomprimeerde groote: %d'; \n  AbCompressionMethodFormatS = 'Kompressie metode: %s'; \n  AbCompressionRatioFormatS = 'Kompressieverhouding: %2.0f%%'; \n  AbCRCFormatS = 'CRC: %x';\n  AbReadOnlyS = 'r';\n  AbHiddenS = 'h';\n  AbSystemS = 's';\n  AbArchivedS = 'a';\n  AbEFAFormatS = 'Eksterne lerattribute: %s';\n  AbIFAFormatS = 'Lertype'; \n  AbTextS = 'Teks'; \n  AbBinaryS = 'Binre'; \n  AbEncryptionFormatS = 'Versleuteling: %s';\n  AbEncryptedS = 'Versleuteld';\n  AbNotEncryptedS = 'Nie versleuteld nie'; \n  AbUnknownS = 'Onbekend';\n  AbTimeStampFormatS = 'Tydstempel: %s'; \n  AbMadeByFormatS = 'Gemaak met weergawe: %f'; \n  AbNeededFormatS = 'Weergawe benodig vir ontpakking: %f'; \n  AbCommentFormatS = 'Opmerking: %s';\n  AbDefaultExtS = '*.zip';\n  AbFilterS = 'PKZIP argief (*.zip)|*.zip|Selfontpakkende Argief (*.exe)|*.exe|Alle Lers (*.*)|*.*'; \n  AbFileNameTitleS = 'Kies lernaam';\n\n  AbOKS = 'OK';\n  AbCancelS = 'Verlaat'; \n  AbSelectDirectoryS = 'Kies ler'; \n\n  AbEnterPasswordS = 'Voeg paswoord in'; \n  AbPasswordS = '&Paswoord';\n  AbVerifyS = '&Verifiseer'; \n\n  AbCabExtS = '*.cab';\n  AbCabFilterS = 'Kabinetsargiewe (*.cab)|*.CAB|Alle Lers (*.*)|*.*'; \n  AbLogExtS = '*.txt';\n  AbLogFilterS = 'Tekslers (*.cab)|*.CAB|Alle Lers (*.*)|*.*'; \n  AbExeExtS = '*.exe';\n  AbExeFilterS = 'Selfontpakkende Zip Lers (*.cab)|*.CAB|Alle Lers (*.*)|*.*';\n\n  AbVMSReadTooManyBytesS = 'VMS: Te veel byte gelees';\n  AbVMSInvalidOriginS = 'VMS: Ongeldige oorsprong %d, moet 0, 1 or 2 wees';\n  AbVMSErrorOpenSwapS = 'VMS: Kannie wisseller oopmaak nie'; \n  AbVMSSeekFailS = 'VMS: Kannie wisseller posisie verander nie'; \n  AbVMSReadFailS = 'VMS: Kan %d byte in wisseller nie lees nie'; \n  AbVMSWriteFailS = 'VMS: Kan %d byte in wisseller nie skryf nie'; \n  AbVMSWriteTooManyBytesS = 'VMS: Aanvraag om te veel byte [%d] te skryf'; \n\n  AbBBSReadTooManyBytesS = 'BBS: Aanvraag om te veel byte [%d] te lees'; \n  AbBBSSeekOutsideBufferS = 'BBS: Nuwe posisie is buite die buffer'; \n  AbBBSInvalidOriginS = 'BBS: Ongeldige oorsprongswaarde'; \n  AbBBSWriteTooManyBytesS = 'BBS: Aanvrag om te veel byte [%d] te skryf'; \n\n  AbSWSNotEndofStreamS = 'TabSlidingWindowStream.Write: Nie by stroom einde nie'; \n  AbSWSSeekFailedS = 'TabSlidingWindowStream.bsWriteChunk: Posisioneering misluk'; \n  AbSWSWriteFailedS = 'TabSlidingWindowStream.bsWriteCunk: Skryf misluk'; \n  AbSWSInvalidOriginS = 'TabSlidingWindowStream.Seek: Ongeldige oorsprong'; \n  AbSWSInvalidNewOriginS = 'TabSlidingWindowStream.Seek: Ongeldige nuwe posisie'; \n\n  AbItemNameHeadingS = 'Naam';\n  AbPackedHeadingS = 'Gepak'; \n  AbMethodHeadingS = 'Metode';\n  AbRatioHeadingS ='Besparing (%)';\n  AbCRCHeadingS = 'CRC32';\n  AbFileAttrHeadingS = 'Attribuut';\n  AbFileFormatHeadingS = 'Formaat';\n  AbEncryptionHeadingS = 'Versleuteld';\n  AbTimeStampHeadingS = 'Tydstempel';\n  AbFileSizeHeadingS = 'Groote'; \n  AbVersionMadeHeadingS = 'Gebruikte weergawe'; \n  AbVersionNeededHeadingS = 'Benodigde weergawe'; \n  AbPathHeadingS = 'Pad';\n  AbPartialHeadingS = 'Partieel';\n  AbExecutableHeadingS = 'Uitvoerbaar';\n\n  AbCabMethod0S = 'Geen';\n  AbCabMethod1S = 'MSZip';\n\n  AbLtAddS = ' toegevoegd ';\n  AbLtDeleteS = ' gewist ';\n  AbLtExtractS = ' ontpakt ';\n  AbLtFreshenS = ' geaktualiseerd '; \n  AbLtMoveS = ' verplaas '; \n  AbLtReplaceS = ' vervang '; \n  AbLtStartS = ' geprotocoleerd ';\n\n  AbGzipInvalidS                   = 'Ongeldige Gzip';\n  AbGzipBadCRCS                    = 'Ongeldige CRC';\n  AbGzipBadFileSizeS               = 'Ongeldige bestaandsgroote'; \n\n  AbTarInvalidS                    = 'Tar ongeldig';\n  AbTarBadFileNameS                = 'Ler naam te lang';\n  AbTarBadLinkNameS                = 'Skakel naam te lang';\n  AbTarBadOpS                      = 'Operasie nie ondersteun nie';\n  \n  AbUnhandledEntityS               = 'Nie behandelde entiteit'; \n\n  { pre-defined \"operating system\" (really more FILE system) identifiers for the\n    Gzip header }\n  AbGzOsFat         = 'FAT Lersisteem (MS-DOS, OS/2, NT/Win32)';\n  AbGzOsAmiga       = 'Amiga';\n  AbGzOsVMS         = 'VMS (of OpenVMS)';\n  AbGzOsUnix        = 'Unix';\n  AbGzOsVM_CMS      = 'VM/CMS';\n  AbGzOsAtari       = 'Atari TOS';\n  AbGzOsHPFS        = 'HPFS Lersisteem (OS/2, NT)';\n  AbGzOsMacintosh   = 'Macintosh';\n  AbGzOsZ_System    = 'Z-System';\n  AbGzOsCP_M        = 'CP/M';\n  AbGzOsTOPS_20     = 'TOPS-20';\n  AbGzOsNTFS        = 'NTFS Lersisteem (NT)';\n  AbGzOsQDOS        = 'QDOS';\n  AbGzOsAcornRISCOS = 'Acorn RISCOS';\n  AbGzOsVFAT        = 'VFAT Lersisteem (Win95, NT)';\n  AbGzOsMVS         = 'MVS';\n  AbGzOsBeOS        = 'BeOS (BeBox of PowerMac)';\n  AbGzOsTandem      = 'Tandem/NSK';\n  AbGzOsTHEOS       = 'THEOS';\n  AbGzOsunknown     = 'onbekend';\n  AbGzOsUndefined   = 'ID is Gzip nie bekend nie';\n\n{!!.03 - Moved from AbCompnd.inc }\n{ Compound File specific error messages }\nresourcestring\n  AbCmpndIndexOutOfBounds   = 'Indeks buite toegelate bereik'; \n  AbCmpndBusyUpdating       = 'Saamgestelde ler word geaktualiseer'; \n  AbCmpndInvalidFile        = 'Ongeldige saamgestelde ler'; \n  AbCmpndFileNotFound       = 'Ler/gids nie gevind nie'; \n  AbCmpndFolderNotEmpty     = 'Gids nie leeg nie'; \n  AbCmpndExceedsMaxFileSize = 'Lergroote oorskryf toegelate maksimum'; \n{!!.03 - End Moved }\n\n\n\nimplementation\n\nend.\n"
  },
  {
    "path": "lib/abbrevia/localization/AbResString.pas.de",
    "content": "(* ***** BEGIN LICENSE BLOCK *****\n * Version: MPL 1.1\n *\n * The contents of this file are subject to the Mozilla Public License Version\n * 1.1 (the \"License\"); you may not use this file except in compliance with\n * the License. You may obtain a copy of the License at\n * http://www.mozilla.org/MPL/\n *\n * Software distributed under the License is distributed on an \"AS IS\" basis,\n * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License\n * for the specific language governing rights and limitations under the\n * License.\n *\n * The Original Code is TurboPower Abbrevia\n *\n * The Initial Developer of the Original Code is\n * TurboPower Software\n *\n * Portions created by the Initial Developer are Copyright (C) 1997-2002\n * the Initial Developer. All Rights Reserved.\n *\n * Contributor(s):\n * Roman Kassebaum\n *\n * ***** END LICENSE BLOCK ***** *)\n\n{*********************************************************}\n{* Abbrevia: AbResString.pas                             *}\n{*********************************************************}\n{* Abbrevia: Resource strings, German localization       *}\n{*********************************************************}\nunit AbResString;\n\ninterface\n\nresourcestring\n  AbErrZipInvalidS = 'Ungltige Datei - keine PKZip Datei';\n  AbZipVersionNeededS = 'Kann die Datei nicht entpacken - neuere Version bentigt';\n  AbUnknownCompressionMethodS = 'Kann die Datei nicht entpacken - nicht untersttzte Kommpressionsmethode';\n  AbNoExtractionMethodS = 'Kann die Datei nicht entpacken - keine Entpackuntersttzung angeboten';\n  AbInvalidPasswordS = 'Kann die Datei nicht entpacken - ungltiges Passwort';\n  AbNoInsertionMethodS = 'Kann die Datei nicht entpacken - keine Einfgeuntersttzung angeboten';\n  AbInvalidFactorS = 'Ungltiger Reduzierungsfaktor';\n  AbDuplicateNameS = 'Kann die Datei nicht einfgen - doppelter gespeicherter Name';\n  AbUnsupportedCompressionMethodS = 'Kann die Datei nicht einfgen - nicht untersttzt Kompressionsmethode';\n  AbUserAbortS = 'Prozess wurde durch den Benutzer abgebrochen';\n  AbArchiveBusyS = 'Das Archiv ist beschftigt - kann nicht die neue Anforderung bearbeiten';\n  AbLastDiskRequestS = 'Legen Sie die letzte Diskette ein';\n  AbDiskRequestS = 'Diskette einlegen ';\n  AbImageRequestS = 'Name des Abbildes';\n  AbBadSpanStreamS = 'Segmentierte Archive mssen als Datei-Strom geffnet werden';\n  AbDiskNumRequestS = 'Legen Sie die Diskette %d des segmentierten Archivs ein';\n  AbImageNumRequestS = 'Legen Sie das Segment %d des segmentierten Archivs ein';\n  AbNoOverwriteSpanStreamS = 'Kann kein existierendes segmentiertes Archiv verndern';\n  AbNoSpannedSelfExtractS = 'Kann kein selbstentpackendes segmentiertes Archiv erstellen';\n  AbBlankDiskS = 'Legen Sie eine leere Diskette ein';\n  AbStreamFullS = 'Strom Schreibfehler';\n  AbNoSuchDirectoryS = 'Verzeichnis existiert nicht';\n  AbInflateBlockErrorS = 'Kann den Bereich nicht entpacken';\n  AbBadStreamTypeS = 'Ungltiger Strom';\n  AbTruncateErrorS = 'Fehler beim Abschneiden der zip Datei';\n  AbZipBadCRCS = 'Fehlgeschalgene CRC berprfung';\n  AbZipBadStubS = 'Der Stamm muss ausfhrbar sein';\n  AbFileNotFoundS = 'Datei nicht gefunden';\n  AbInvalidLFHS = 'Ungltiger lokaler Dateianfang';\n  AbNoArchiveS = 'Das Archiv existiert nicht- leerer Dateinahme';\n  AbReadErrorS = 'Fehler beim Lesen des Archivse';\n  AbInvalidIndexS = 'Ungltiger Archiv Element Eintrag';\n  AbInvalidThresholdS = 'Ungltige Archivgren Schwelle';\n  AbUnhandledFileTypeS = 'Unbekannter Archiv';\n  AbSpanningNotSupportedS = 'Aufteilen wird bei diesem Archivtyp nicht untersttzt';\n  AbLogCreateErrorS = 'Fehler beim Erzeugen der Protokolldatei';\n  AbMoveFileErrorS = 'Fehler beim Verschieben der Datei %s nach %s';\n  AbFileSizeTooBigS = 'Datei ist zu gro fr diesen Archivtypen';\n\n  AbNoCabinetDllErrorS = 'Kann die Datei cabinet.dll nicht laden';\n  AbFCIFileOpenErrorS = 'FCI kann die Datei nicht ffnen';\n  AbFCIFileReadErrorS = 'FCI kann die Datei nicht lesen';\n  AbFCIFileWriteErrorS = 'FCI kann die Datei nicht schreiben';\n  AbFCIFileCloseErrorS = 'FCI Fehler beim Schlieen der Datei';\n  AbFCIFileSeekErrorS = 'FCI Fehler beim Durchsuchen der Datei';\n  AbFCIFileDeleteErrorS = 'FCI Fehler beim Lschen der Datei';\n  AbFCIAddFileErrorS = 'FCI kann die Datei  nicht hinzufgen';\n  AbFCICreateErrorS = 'FCI kann den Zusammenhang nicht erstellen';\n  AbFCIFlushCabinetErrorS = 'FCI kann das Cabinet-Archiv nicht leeren';\n  AbFCIFlushFolderErrorS = 'FCI kann das Verzeichnis nicht leeren';\n  AbFDICopyErrorS = 'FDI kann die Dateien nicht aufzhlen';\n  AbFDICreateErrorS = 'FDI kann den Zusammenhang nicht herstellen';\n  AbInvalidCabTemplateS = 'Ungltige Vorlage fr eine Cabinet-Datei';\n  AbInvalidCabFileS = 'Ungltige Datei - keine Kabinett Datei';\n\n  AbZipStored = 'Gespeichert';\n  AbZipShrunk = 'Geschrumpft';\n  AbZipReduced = 'Reduziert';\n  AbZipImploded = 'Implodiert';\n  AbZipTokenized = 'In Merkmale aufgeteilt';\n  AbZipDeflated = 'Gepackt';\n  AbZipDeflate64 = 'Strker gepackt';\n  AbZipDCLImploded = 'DCL Implodiert';\n  AbZipBzip2 = 'Bzip2';\n  AbZipLZMA = 'LZMA';\n  AbZipIBMTerse = 'IBM Terse';\n  AbZipLZ77 = 'IBM LZ77';\n  AbZipJPEG = 'JPEG';\n  AbZipWavPack = 'WavPack';\n  AbZipPPMd = 'PPMd';\n  AbZipUnknown = 'Unbekannt (%d)';\n  AbZipBestMethod = 'Beste Methode';\n\n  AbVersionFormatS = 'Version %s';\n  AbCompressedSizeFormatS = 'Komprimierte Gre: %d';\n  AbUncompressedSizeFormatS = 'Komprimierte Gre: %d';\n  AbCompressionMethodFormatS = 'Kompressions-Methode: %s';\n  AbCompressionRatioFormatS = 'Kompressions-Verhltnis: %2.0f%%';\n  AbCRCFormatS = 'CRC: %x';\n  AbReadOnlyS = 'r';\n  AbHiddenS = 'h';\n  AbSystemS = 's';\n  AbArchivedS = 'a';\n  AbEFAFormatS = 'Externe Datei Attribute: %s';\n  AbIFAFormatS = 'Dateityp: %s';\n  AbTextS = 'Text';\n  AbBinaryS = 'Binr';\n  AbEncryptionFormatS = 'Verschlsselung: %s';\n  AbEncryptedS = 'Verschlsselt';\n  AbNotEncryptedS = 'Nicht verschlsselt';\n  AbUnknownS = 'Unbekannt';\n  AbTimeStampFormatS = 'Zeitstemple: %s';\n  AbMadeByFormatS = 'Erzeugt mit der Version: %f';\n  AbNeededFormatS = 'Version bentigt zum Extrahieren: %f';\n  AbCommentFormatS = 'Kommentar: %s';\n  AbDefaultExtS = '*.zip';\n  AbFilterS = 'PKZip Archive (*.zip)|*.zip|Selbstentpackende Archive (*.exe)|*.exe|Alle Dateien (*.*)|*.*';\n  AbFileNameTitleS = 'Dateinamen auswhlen';\n\n  AbOKS = 'OK';\n  AbCancelS = 'Abbrechen';\n  AbSelectDirectoryS = 'Verzeichnis auswhlen';\n\n  AbEnterPasswordS = 'Passwort eingeben';\n  AbPasswordS = '&Passwort';\n  AbVerifyS = '&berprfen';\n\n  AbCabExtS = '*.cab';\n  AbCabFilterS = 'Cabinet Archive (*.cab)|*.CAB|Alle Dateien (*.*)|*.*';\n  AbLogExtS = '*.txt';\n  AbLogFilterS = 'Text Dateien (*.txt)|*.TXT|Alle Dateien (*.*)|*.*';\n  AbExeExtS = '*.exe';\n  AbExeFilterS = 'Selbstentpackende Zip Dateien (*.exe)|*.EXE|Alle Dateien (*.*)|*.*';\n\n  AbVMSReadTooManyBytesS = 'VMS: Anforderung, zu viele Bytes [%d] zu lesen';\n  AbVMSInvalidOriginS = 'VMS: Ungltiger Ursprung %d, sollte 0, 1, 2 sein';\n  AbVMSErrorOpenSwapS = 'VMS: Kann die Auslagerungsdatei %s nicht ffnen';\n  AbVMSSeekFailS = 'VMS: Konnte nicht in der Auslagerungsdatei %s suchen';\n  AbVMSReadFailS = 'VMS: Konnte nicht %d Bytes in der Auslagerungsdatei %s lesen';\n  AbVMSWriteFailS = 'VMS: Konnte nicht %d Bytes in die Auslagerungsdatei %s schreiben';\n  AbVMSWriteTooManyBytesS = 'VMS: Anforderung, zu viele Bytes [%d] zu schreiben';\n\n  AbBBSReadTooManyBytesS = 'BBS: Anforderung, zu viele Bytes [%d] zu lesen';\n  AbBBSSeekOutsideBufferS = 'BBS: Die neue Position ist auerhalb des Puffers';\n  AbBBSInvalidOriginS = 'BBS: Ungltiger Ursprungswert';\n  AbBBSWriteTooManyBytesS = 'BBS: Anforderung, zu viele Bytes [%d] zu schreiben';\n\n  AbSWSNotEndofStreamS = 'TabSlidingWindowStream.Write: Nicht am Ende des Datenstroms';\n  AbSWSSeekFailedS = 'TabSlidingWindowStream.bsWriteChunk: Suche fehlgeschlagen';\n  AbSWSWriteFailedS = 'TabSlidingWindowStream.bsWriteChunk: Schreiben fehlgeschlagen';\n  AbSWSInvalidOriginS = 'TabSlidingWindowStream.Seek: Ungltiger Ursprung';\n  AbSWSInvalidNewOriginS = 'TabSlidingWindowStream.Seek: Ungltige neue Position';\n\n  AbItemNameHeadingS = 'Name';\n  AbPackedHeadingS = 'Gepacked';\n  AbMethodHeadingS = 'Methode';\n  AbRatioHeadingS = 'Einsparung (%)';\n  AbCRCHeadingS = 'CRC32';\n  AbFileAttrHeadingS = 'Attribute';\n  AbFileFormatHeadingS = 'Format';\n  AbEncryptionHeadingS = 'Verschlsselt';\n  AbTimeStampHeadingS = 'Zeitstempel';\n  AbFileSizeHeadingS = 'Gre';\n  AbVersionMadeHeadingS = 'Version genutzt';\n  AbVersionNeededHeadingS = 'Version bentigt';\n  AbPathHeadingS = 'Pfad';\n  AbPartialHeadingS = 'Teilweise';\n  AbExecutableHeadingS = 'Ausfhrbar';\n  AbFileTypeHeadingS = 'Typ';\n  AbLastModifiedHeadingS = 'Modifiziert';\n\n  AbCabMethod0S = 'Keine';\n  AbCabMethod1S = 'MSZip';\n\n  AbLtAddS = ' hinzugefgt ';\n  AbLtDeleteS = ' gelscht ';\n  AbLtExtractS = ' extrahiert ';\n  AbLtFreshenS = ' aktualisiert ';\n  AbLtMoveS = ' verschoben ';\n  AbLtReplaceS = ' ersetzt ';\n  AbLtStartS = ' protokolliert ';\n\n  AbGzipInvalidS                   = 'Ungltiges Gzip';\n  AbGzipBadCRCS                    = 'Ungltiger CRC';\n  AbGzipBadFileSizeS               = 'Ungltige Datei Gre';\n\n  AbTarInvalidS                    = 'Ungltiges Tar';\n  AbTarBadFileNameS                = 'Dateiname zu lang';\n  AbTarBadLinkNameS                = 'Linkname zu lang';\n  AbTarBadOpS                      = 'Nicht untersttzte Operation';\n\n  AbUnhandledEntityS               = 'Nicht behandelte Entitt';\n\n  { pre-defined \"operating system\" (really more FILE system) identifiers for the\n    Gzip header }\n  AbGzOsFat         = 'FAT Datei-System (MS-DOS, OS/2, NT/Win32)';\n  AbGzOsAmiga       = 'Amiga';\n  AbGzOsVMS         = 'VMS (oder OpenVMS)';\n  AbGzOsUnix        = 'Unix';\n  AbGzOsVM_CMS      = 'VM/CMS';\n  AbGzOsAtari       = 'Atari TOS';\n  AbGzOsHPFS        = 'HPFS Datei-System (OS/2, NT)';\n  AbGzOsMacintosh   = 'Macintosh';\n  AbGzOsZ_System    = 'Z-System';\n  AbGzOsCP_M        = 'CP/M';\n  AbGzOsTOPS_20     = 'TOPS-20';\n  AbGzOsNTFS        = 'NTFS Datei-System (NT)';\n  AbGzOsQDOS        = 'QDOS';\n  AbGzOsAcornRISCOS = 'Acorn RISCOS';\n  AbGzOsVFAT        = 'VFAT Datei-System (Win95, NT)';\n  AbGzOsMVS         = 'MVS';\n  AbGzOsBeOS        = 'BeOS (BeBox oder PowerMac)';\n  AbGzOsTandem      = 'Tandem/NSK';\n  AbGzOsTHEOS       = 'THEOS';\n  AbGzOsunknown     = 'unkekannt';\n  AbGzOsUndefined   = 'ID ist Gzip nicht bekannt';\n\n{!!.03 - Moved from AbCompnd.inc }\n{ Compound File specific error messages }\nresourcestring\n  AbCmpndIndexOutOfBounds   = 'Index auerhalb des zulssigen Bereichs';\n  AbCmpndBusyUpdating       = 'Verbindungsdatei wird aktualisiert';\n  AbCmpndInvalidFile        = 'Ungltige Verbindungsdatei';\n  AbCmpndFileNotFound       = 'Datei/Verzeichnis nicht gefunden';\n  AbCmpndFolderNotEmpty     = 'Verzeichnis ist nicht leer';\n  AbCmpndExceedsMaxFileSize = 'Dateigre berschreitet das erlaubte Maximum';\n{!!.03 - End Moved }\n\n\n\nimplementation\n\nend.\n"
  },
  {
    "path": "lib/abbrevia/localization/AbResString.pas.fr",
    "content": "(* ***** BEGIN LICENSE BLOCK *****\n * Version: MPL 1.1\n *\n * The contents of this file are subject to the Mozilla Public License Version\n * 1.1 (the \"License\"); you may not use this file except in compliance with\n * the License. You may obtain a copy of the License at\n * http://www.mozilla.org/MPL/\n *\n * Software distributed under the License is distributed on an \"AS IS\" basis,\n * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License\n * for the specific language governing rights and limitations under the\n * License.\n *\n * The Original Code is TurboPower Abbrevia\n *\n * The Initial Developer of the Original Code is\n * TurboPower Software\n *\n * Portions created by the Initial Developer are Copyright (C) 1997-2002\n * the Initial Developer. All Rights Reserved.\n *\n * Contributor(s):\n * Hichem BOUKSANI, John Riche, Roman Kassebaum\n *\n * ***** END LICENSE BLOCK ***** *)\n\n{*********************************************************}\n{* Abbrevia: AbResString.pas                             *}\n{*********************************************************}\n{* Abbrevia: Resource strings                            *}\n{*********************************************************}\nunit AbResString;\n\ninterface\n\nresourcestring\n  AbErrZipInvalidS = 'Fichier non valide - N''est pas un fichier PKZip';\n  AbZipVersionNeededS = 'Impossible d''extraire le fichier - nouvelle version requise';\n  AbUnknownCompressionMethodS = 'Impossible d''extraire le fichier - mthode de compression non supporte';\n  AbNoExtractionMethodS = 'Impossible d''extraire le fichier - aucun support d''extraction fourni';\n  AbInvalidPasswordS = 'Impossible d''extraire le fichier - Mot de passe incorrect';\n  AbNoInsertionMethodS = 'Imossible d''insrer le fichier - aucun support d''insertion fourni';\n  AbInvalidFactorS = 'Facteur de rduction Invalide';\n  AbDuplicateNameS = 'Impossible d''insrer le fichier - Nom du fichier existe en double';\n  AbUnsupportedCompressionMethodS = 'Impossible d''insrer le fichier - mthode de compression non suppote';\n  AbUserAbortS = 'Processus abandonn par l''utilisateur';\n  AbArchiveBusyS = 'Archivage en cours - ne peut traiter de nouvelles demandes'; \n  AbLastDiskRequestS = 'Insrer la dernire disquette du jeu multi-disquettes';\n  AbDiskRequestS = 'Insrer une disquette'; \n  AbImageRequestS = 'Nom du fichier image';\n  AbBadSpanStreamS = 'Archives multi-disquettes doivent tre ouvertes comme fichiers de flux';\n  AbDiskNumRequestS = 'Insrer la disquette %d du jeu multi-disquettes';\n  AbImageNumRequestS = 'Insrer la disquette %d du jeu multi-disquettes';  \n  AbNoOverwriteSpanStreamS = 'Impossible de mettre  jour un jeu multi-disquettes existant';\n  AbNoSpannedSelfExtractS = 'Impossible de crer un fichier auto-extractible  partir d''une archive multi-disquettes';\n  AbBlankDiskS = 'Insrer une disquette vierge';\n  AbStreamFullS = 'Erreur d''criture du flux';\n  AbNoSuchDirectoryS = 'Dossier inexistant';\n  AbInflateBlockErrorS = 'Dcompression du bloc impossible';\n  AbBadStreamTypeS = 'Flux Invalide';\n  AbTruncateErrorS = 'Erreur de troncage du fichier ZIP';\n  AbZipBadCRCS = 'Echec du contrle CRC';\n  AbZipBadStubS = 'La souche doit tre un executable';\n  AbFileNotFoundS = 'Fichier inexistant';\n  AbInvalidLFHS = 'Entre de l''entte du fichier local invalide'; \n  AbNoArchiveS = 'L''archive n''existe pas - Nom de fichier non spcifi';\n  AbReadErrorS = 'Erreur de l''ecture de l''archive';\n  AbInvalidIndexS = 'L''indice de l''lment de l''archive est invalide'; \n  AbInvalidThresholdS = 'Le seuil de la taille de l''archive est invalide'; \n  AbUnhandledFileTypeS = 'Type d''archive non support'; \n  AbSpanningNotSupportedS = 'Multi-disquette non support par ce type d''archive'; \n  AbLogCreateErrorS = 'Erreur de cration du fichier log';\n  AbMoveFileErrorS = 'Erreur de dplacement du fichier %s vers %s';\n  AbFileSizeTooBigS = 'Taille du fichier trop grande pour le type d''archive'; \n\n  AbNoCabinetDllErrorS = 'Impossible de charger cabinet.dll';\n  AbFCIFileOpenErrorS = 'FCI impossible d''ouvrir le fichier';\n  AbFCIFileReadErrorS = 'FCI impossible de lire le fichier';\n  AbFCIFileWriteErrorS = 'FCI Ecriture impossible sur le fichier';\n  AbFCIFileCloseErrorS = 'FCI erreur de fermeture du fichier';\n  AbFCIFileSeekErrorS = 'FCI Erreur de recherche de fichier'; \n  AbFCIFileDeleteErrorS = 'FCI erreur de suppression du fichier';\n  AbFCIAddFileErrorS = 'FCI impossible d''ajouter le fichier';\n  AbFCICreateErrorS = 'FCI impossible de crer le contexte';\n  AbFCIFlushCabinetErrorS = 'FCI impossible de vider le cabinet';\n  AbFCIFlushFolderErrorS = 'FCI Impossible de vider le dossier';\n  AbFDICopyErrorS = 'FDI impossible d''enumrer les fichiers'; \n  AbFDICreateErrorS = 'FDI impossible de crer le contexte';\n  AbInvalidCabTemplateS = 'Modle du fichier CAB invalide';\n  AbInvalidCabFileS = 'Fichier invalide - n''est pas un fichier cabinet';\n\n  AbZipStored = 'Stock';\n  AbZipShrunk = 'Compact'; \n  AbZipReduced = 'Rduit';\n  AbZipImploded = 'Implos';\n  AbZipTokenized = 'Divis en plusieurs parties';\n  AbZipDeflated = 'Dflation'; \n  AbZipDeflate64 = 'Dflation amliore';\n  AbZipDCLImploded = 'DCL Implos'; \n  AbZipBzip2 = 'Bzip2';\n  AbZipLZMA = 'LZMA';\n  AbZipIBMTerse = 'IBM Terse';\n  AbZipLZ77 = 'IBM LZ77';\n  AbZipJPEG = 'JPEG';\n  AbZipWavPack = 'WavPack';\n  AbZipPPMd = 'PPMd';\n  AbZipUnknown = 'Inconnu (%d)';\n  AbZipBestMethod = 'Meilleure Mthode';\n\n  AbVersionFormatS = 'Version %s';\n  AbCompressedSizeFormatS = 'Taille compresse: %d';\n  AbUncompressedSizeFormatS = 'Taille non compresse: %d';\n  AbCompressionMethodFormatS = 'Mthode de compression: %s';\n  AbCompressionRatioFormatS = 'Ratio de compression: %2.0f%%';\n  AbCRCFormatS = 'CRC: %x';\n  AbReadOnlyS = 'r';\n  AbHiddenS = 'h';\n  AbSystemS = 's';\n  AbArchivedS = 'a';\n  AbEFAFormatS = 'Attribut du fichier externe: %s';\n  AbIFAFormatS = 'Type du fichier: %s';\n  AbTextS = 'Text';\n  AbBinaryS = 'Binaire';\n  AbEncryptionFormatS = 'Crypt: %s';\n  AbEncryptedS = 'Crypt';\n  AbNotEncryptedS = 'Non crypt';\n  AbUnknownS = 'Inconnu';\n  AbTimeStampFormatS = 'Heure: %s';\n  AbMadeByFormatS = 'Version utilise: %f'; \n  AbNeededFormatS = 'Version d''extraction: %f'; \n  AbCommentFormatS = 'Commentaire: %s';\n  AbDefaultExtS = '*.zip';\n  AbFilterS = 'Archives PKZip (*.zip)|*.zip|Archives Auto extractibles (*.exe)|*.exe|Tous les fichiers (*.*)|*.*';\n  AbFileNameTitleS = 'Slectionner un fichier';\n\n  AbOKS = 'OK';\n  AbCancelS = 'Annuler';\n  AbSelectDirectoryS = 'Slectionner un Dossier';\n\n  AbEnterPasswordS = 'Saisir Mot de passe';\n  AbPasswordS = '&Mot de passe';\n  AbVerifyS = '&Vrifier';\n\n  AbCabExtS = '*.cab';\n  AbCabFilterS = 'Archives Cabinet (*.cab)|*.CAB|Tous les fichiers (*.*)|*.*';\n  AbLogExtS = '*.txt';\n  AbLogFilterS = 'Fichiers Text (*.txt)|*.TXT|Tous les fichiers (*.*)|*.*';\n  AbExeExtS = '*.exe';\n  AbExeFilterS = 'Fichiers Zip auto-extractibles (*.exe)|*.EXE|Tous les fichiers (*.*)|*.*';\n\n  AbVMSReadTooManyBytesS = VMS: Tentative de l''ecture de trop d''octets [%d]';\n  AbVMSInvalidOriginS = 'VMS: Origine invalide %d, doit tre 0, 1, 2';\n  AbVMSErrorOpenSwapS = 'VMS: Impossible d''ouvrir le fichier d''change %s';\n  AbVMSSeekFailS = 'VMS: Impossible de se dplacer dans le fichier d''change %s';\n  AbVMSReadFailS = 'VMS: impossible de lire %d octets du fichier d''change %s';\n  AbVMSWriteFailS = 'VMS: impossible d''crire %d octets dans le fichier d''change %s'; \n  AbVMSWriteTooManyBytesS = 'VMS: tentative d''crire trop d''octets [%d]';\n\n  AbBBSReadTooManyBytesS = 'BBS: tentative de lecture de trop d''octets [%d]';\n  AbBBSSeekOutsideBufferS = 'BBS: la nouvelle position est en dehors du buffer';\n  AbBBSInvalidOriginS = 'BBS: Valeur d''origine invalide';\n  AbBBSWriteTooManyBytesS = 'BBS: tentative d''crire de trop d''octets [%d]';\n\n  AbSWSNotEndofStreamS = 'TabSlidingWindowStream.Write: Pas  la fin du flux';\n  AbSWSSeekFailedS = 'TabSlidingWindowStream.bsWriteChunk: chec de recherche';\n  AbSWSWriteFailedS = 'TabSlidingWindowStream.bsWriteChunk: chec d''criture';\n  AbSWSInvalidOriginS = 'TabSlidingWindowStream.Seek: Origine incorrecte';\n  AbSWSInvalidNewOriginS = 'TabSlidingWindowStream.Seek: Nouvelle position incorrecte';\n\n  AbItemNameHeadingS = 'Nom';\n  AbPackedHeadingS = 'Compress';\n  AbMethodHeadingS = 'Mthode';\n  AbRatioHeadingS = 'Ratio (%)';\n  AbCRCHeadingS = 'CRC32';\n  AbFileAttrHeadingS = 'Attribut';\n  AbFileFormatHeadingS = 'Format';\n  AbEncryptionHeadingS = 'Crypt';\n  AbTimeStampHeadingS = 'Heure';\n  AbFileSizeHeadingS = 'Taille';\n  AbVersionMadeHeadingS = 'Version Utilise';\n  AbVersionNeededHeadingS = 'Version ncessaire';\n  AbPathHeadingS = 'Chemin';\n  AbPartialHeadingS = 'Partiel';\n  AbExecutableHeadingS = 'Excutable';\n\n  AbCabMethod0S = 'Aucune';\n  AbCabMethod1S = 'MSZip';\n\n  AbLtAddS = ' Ajout ';\n  AbLtDeleteS = ' Supprim ';\n  AbLtExtractS = ' Extrait ';\n  AbLtFreshenS = ' Rafraichir ';\n  AbLtMoveS = ' Dplac ';\n  AbLtReplaceS = ' Remplac ';\n  AbLtStartS = ' Connexion ';\n\n  AbGzipInvalidS                   = 'Gzip Invalide';\n  AbGzipBadCRCS                    = 'Mauvais CRC'; \n  AbGzipBadFileSizeS               = 'Taille du fichier errone'; \n\n  AbTarInvalidS                    = 'Tar invalide';\n  AbTarBadFileNameS                = 'Nom de fichier trop long';\n  AbTarBadLinkNameS                = 'Chemin du lien symbolique trop long';\n  AbTarBadOpS                      = 'Opration non supporte';\n  \n  AbUnhandledEntityS             = 'Entit non prise en charge';\n\n  { pre-defined \"operating system\" (really more FILE system) identifiers for the\n    Gzip header }\n  AbGzOsFat         = 'Systme de fichier FAT (MS-DOS, OS/2, NT/Win32)';\n  AbGzOsAmiga       = 'Amiga';\n  AbGzOsVMS         = 'VMS (ou OpenVMS)';\n  AbGzOsUnix        = 'Unix';\n  AbGzOsVM_CMS      = 'VM/CMS';\n  AbGzOsAtari       = 'Atari TOS';\n  AbGzOsHPFS        = 'Systme de fichier HPFS (OS/2, NT)';\n  AbGzOsMacintosh   = 'Macintosh';\n  AbGzOsZ_System    = 'Z-System';\n  AbGzOsCP_M        = 'CP/M';\n  AbGzOsTOPS_20     = 'TOPS-20';\n  AbGzOsNTFS        = 'Systme de fichier NTFS (NT)';\n  AbGzOsQDOS        = 'QDOS';\n  AbGzOsAcornRISCOS = 'Acorn RISCOS';\n  AbGzOsVFAT        = 'Systme de fichier VFAT (Win95, NT)';\n  AbGzOsMVS         = 'MVS';\n  AbGzOsBeOS        = 'BeOS (BeBox ou PowerMac)';\n  AbGzOsTandem      = 'Tandem/NSK';\n  AbGzOsTHEOS       = 'THEOS';\n  AbGzOsunknown     = 'Inconnu';\n  AbGzOsUndefined   = 'ID non dfini par gzip'; \n\n{!!.03 - Moved from AbCompnd.inc }\n{ Compound File specific error messages }\nresourcestring\n  AbCmpndIndexOutOfBounds   = 'Indice hors limite';\n  AbCmpndBusyUpdating       = 'Fichier compos est occup par la mise  jour';\n  AbCmpndInvalidFile        = 'Fichier compos invalide';\n  AbCmpndFileNotFound       = 'Fichier/Dossier introuvable';\n  AbCmpndFolderNotEmpty     = 'Dossier n''est pas vide';\n  AbCmpndExceedsMaxFileSize = 'Taille du fichier dpasse la limite maximale'; \n{!!.03 - End Moved }\n\n\n\nimplementation\n\nend.\n"
  },
  {
    "path": "lib/abbrevia/localization/AbResString.pas.nl",
    "content": "(* ***** BEGIN LICENSE BLOCK *****\n * Version: MPL 1.1\n *\n * The contents of this file are subject to the Mozilla Public License Version\n * 1.1 (the \"License\"); you may not use this file except in compliance with\n * the License. You may obtain a copy of the License at\n * http://www.mozilla.org/MPL/\n *\n * Software distributed under the License is distributed on an \"AS IS\" basis,\n * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License\n * for the specific language governing rights and limitations under the\n * License.\n *\n * The Original Code is TurboPower Abbrevia\n *\n * The Initial Developer of the Original Code is\n * TurboPower Software\n *\n * Portions created by the Initial Developer are Copyright (C) 1997-2002\n * the Initial Developer. All Rights Reserved.\n *\n * Contributor(s):\n * Rudy Velthuis\n *\n * ***** END LICENSE BLOCK ***** *)\n\n{*********************************************************}\n{* Abbrevia: AbResString.pas 3.05                        *}\n{*********************************************************}\n{* Abbrevia: Resource strings, Dutch localization        *}\n{*********************************************************}\nunit AbResString;\n\ninterface\n\nresourcestring\n  AbErrZipInvalidS = 'Ongeldig bestand - geen PKZip bestand';\n  AbZipVersionNeededS = 'Kan bestand niet ontpakken - nieuwere versie nodig';\n  AbUnknownCompressionMethodS = 'Kan bestand niet ontpakken - niet ondersteunde compressiemethode';\n  AbNoExtractionMethodS = 'Kan bestand niet ontpakken - ontpakken wordt niet ondersteund';\n  AbInvalidPasswordS = 'Kan bestand niet ontpakken - ongeldig paswoord';\n  AbNoInsertionMethodS = 'Kan bestand niet invoegen - invoegen wordt niet ondersteund';\n  AbInvalidFactorS = 'Ongeldige reductiefactor';\n  AbDuplicateNameS = 'Kan het bestand niet invoegen - dupliceert opgeslagen naam';\n  AbUnsupportedCompressionMethodS = 'Kan het bestand niet invoegen - niet ondersteunde compressiemethode';\n  AbUserAbortS = 'Proces werd door gebruiker afgebroken';\n  AbArchiveBusyS = 'Archief is bezig - kan nieuwe aanvraag niet bewerken';\n  AbLastDiskRequestS = 'Plaats laatste diskette van opgesplitst archief';\n  AbDiskRequestS = 'Plaats diskette';\n  AbImageRequestS = 'Bestandsnaam afbeelding';\n  AbBadSpanStreamS = 'Opgesplitste archieven moeten als bestandsstroom geopend worden';\n  AbDiskNumRequestS = 'Plaats diskette %d van opgesplitst archief';\n  AbImageNumRequestS = 'Plaats segment %d van opgesplitst archief';\n  AbNoOverwriteSpanStreamS = 'Kan bestaand opgesplitst archief niet veranderen';\n  AbNoSpannedSelfExtractS = 'Kan geen zelfontpakkend opgesplitst archief aanmaken';\n  AbBlankDiskS = 'Plaats een lege diskette';\n  AbStreamFullS = 'Schrijffout stroom';\n  AbNoSuchDirectoryS = 'Directory bestaat niet';\n  AbInflateBlockErrorS = 'Kan blok niet ontpakken';\n  AbBadStreamTypeS = 'Ongeldige stroom';\n  AbTruncateErrorS = 'Fout bij het afknotten van het zip bestand';\n  AbZipBadCRCS = 'Mislukte CRC controle';\n  AbZipBadStubS = 'Stomp moet uitvoerbaar bestand zijn';\n  AbFileNotFoundS = 'Bestand niet gevonden';\n  AbInvalidLFHS = 'Ongeldig Local File Header element';\n  AbNoArchiveS = 'Archief bestaat niet - lege bestandsnaam';\n  AbReadErrorS = 'Fout tijdens lezen van archief';\n  AbInvalidIndexS = 'Ongeldige index van archiefelement';\n  AbInvalidThresholdS = 'Ongeldige drempel van archiefgrootte';\n  AbUnhandledFileTypeS = 'Onbekend archieftype';\n  AbSpanningNotSupportedS = 'Opsplitsen wordt voor dit archieftype niet ondersteund';\n  AbLogCreateErrorS = 'Fout tijdens aanmaken van protocolbestand';\n  AbMoveFileErrorS = 'Fout tijdens het verplaatsen van bestand %s naar %s';\n  AbFileSizeTooBigS = 'Bestand is te groot voor dit archieftype';\n\n  AbNoCabinetDllErrorS = 'Kan bestand cabinet.dll niet laden';\n  AbFCIFileOpenErrorS = 'FCI kan bestand niet openen';\n  AbFCIFileReadErrorS = 'FCI kan bestand niet lezen';\n  AbFCIFileWriteErrorS = 'FCI kan bestand niet schrijven';\n  AbFCIFileCloseErrorS = 'FCI fout tijdens sluiten van bestand';\n  AbFCIFileSeekErrorS = 'FCI fout tijdens positioneren in bestand';\n  AbFCIFileDeleteErrorS = 'FCI fout tijdens wissen van bestand';\n  AbFCIAddFileErrorS = 'FCI kan bestand niet toevoegen';\n  AbFCICreateErrorS = 'FCI kan context niet aanmaken';\n  AbFCIFlushCabinetErrorS = 'FCI kan cabinet niet legen';\n  AbFCIFlushFolderErrorS = 'FCI kan folder niet legen';\n  AbFDICopyErrorS = 'FDI kann bestanden niet opsommen';\n  AbFDICreateErrorS = 'FDI kan context niet aanmaken';\n  AbInvalidCabTemplateS = 'Ongeldige sjabloon voor cabinetsbestand';\n  AbInvalidCabFileS = 'Ongeldig bestand - geen cabinetsbestand';\n\n  AbZipStored = 'Opgeslagen';\n  AbZipShrunk = 'Gekrompen';\n  AbZipReduced = 'Gereduceerd';\n  AbZipImploded = 'Gemplodeerd';\n  AbZipTokenized = 'In symbolen gepakt';\n  AbZipDeflated = 'Gedeflationeerd';\n  AbZipDeflate64 = 'Uitgebreid gedeflationeerd';\n  AbZipDCLImploded = 'DCL gemplodeerd';\n  AbZipBzip2 = 'Bzip2';\n  AbZipLZMA = 'LZMA';\n  AbZipIBMTerse = 'IBM Terse';\n  AbZipLZ77 = 'IBM LZ77';\n  AbZipJPEG = 'JPEG';\n  AbZipWavPack = 'WavPack';\n  AbZipPPMd = 'PPMd';\n  AbZipUnknown = 'Onbekend (%d)';\n  AbZipBestMethod = 'Beste methode';\n\n  AbVersionFormatS = 'Versie %s';\n  AbCompressedSizeFormatS = 'Gecomprimeerde grootte: %d';\n  AbUncompressedSizeFormatS = 'Ongecomprimeerde grootte: %d';\n  AbCompressionMethodFormatS = 'Compressiemethode: %s';\n  AbCompressionRatioFormatS = 'Compressieverhouding: %2.0f%%';\n  AbCRCFormatS = 'CRC: %x';\n  AbReadOnlyS = 'r';\n  AbHiddenS = 'h';\n  AbSystemS = 's';\n  AbArchivedS = 'a';\n  AbEFAFormatS = 'Externe bestandsattributen: %s';\n  AbIFAFormatS = 'Bestandstype: %s';\n  AbTextS = 'Tekst';\n  AbBinaryS = 'Binair';\n  AbEncryptionFormatS = 'Versleuteling: %s';\n  AbEncryptedS = 'Versleuteld';\n  AbNotEncryptedS = 'Niet versleuteld';\n  AbUnknownS = 'Onbekend';\n  AbTimeStampFormatS = 'Tijdstempel: %s';\n  AbMadeByFormatS = 'Gemaakt met versie: %f';\n  AbNeededFormatS = 'Versie benodigd voor ontpakken: %f';\n  AbCommentFormatS = 'Opmerking: %s';\n  AbDefaultExtS = '*.zip';\n  AbFilterS = 'PKZip Archieven (*.zip)|*.zip|Zelfontpakkende Archieven (*.exe)|*.exe|Alle Bestanden (*.*)|*.*';\n  AbFileNameTitleS = 'Bestandsnaam Kiezen';\n\n  AbOKS = 'OK';\n  AbCancelS = 'Verlaten';\n  AbSelectDirectoryS = 'Bestand kiezen';\n\n  AbEnterPasswordS = 'Paswoord ingeven';\n  AbPasswordS = '&Paswoord';\n  AbVerifyS = '&Verificeren';\n\n  AbCabExtS = '*.cab';\n  AbCabFilterS = 'Cabinetsarchieven (*.cab)|*.CAB|Alle Bestanden (*.*)|*.*';\n  AbLogExtS = '*.txt';\n  AbLogFilterS = 'Tekstbestanden (*.txt)|*.TXT|Alle Bestanden (*.*)|*.*';\n  AbExeExtS = '*.exe';\n  AbExeFilterS = 'Zelfontpakkende Zip Bestanden (*.exe)|*.EXE|Alle Bestanden (*.*)|*.*';\n\n  AbVMSReadTooManyBytesS = 'VMS: Anvraag om te veel byte [%d] te lezen';\n  AbVMSInvalidOriginS = 'VMS: Ongeldige oorsprong %d, moet 0, 1 of 2 zijn';\n  AbVMSErrorOpenSwapS = 'VMS: Kan wisselbestand %s niet openen';\n  AbVMSSeekFailS = 'VMS: Kon niet in wisselbestand %s positioneren';\n  AbVMSReadFailS = 'VMS: Kon %d byte in wisselbestand %s niet lezen';\n  AbVMSWriteFailS = 'VMS: Kon %d byte niet in wisselbestand %s schrijven';\n  AbVMSWriteTooManyBytesS = 'VMS: Anvraag om te veel byte [%d] te schrijven';\n\n  AbBBSReadTooManyBytesS = 'BBS: Anvraag om te veel byte [%d] te lezen';\n  AbBBSSeekOutsideBufferS = 'BBS: Nieuwe positie is buiten de buffer';\n  AbBBSInvalidOriginS = 'BBS: Ongeldige oorsprongswaarde';\n  AbBBSWriteTooManyBytesS = 'BBS: Anvraag om te veel byte [%d] te schrijven';\n\n  AbSWSNotEndofStreamS = 'TabSlidingWindowStream.Write: Niet aan eind van stroom';\n  AbSWSSeekFailedS = 'TabSlidingWindowStream.bsWriteChunk: Positioneren mislukt';\n  AbSWSWriteFailedS = 'TabSlidingWindowStream.bsWriteChunk: Schrijven mislukt';\n  AbSWSInvalidOriginS = 'TabSlidingWindowStream.Seek: Ongeldige oorsprong';\n  AbSWSInvalidNewOriginS = 'TabSlidingWindowStream.Seek: Ongeldige nieuwe positie';\n\n  AbItemNameHeadingS = 'Naam';\n  AbPackedHeadingS = 'Gepakt';\n  AbMethodHeadingS = 'Methode';\n  AbRatioHeadingS = 'Besparing (%)';\n  AbCRCHeadingS = 'CRC32';\n  AbFileAttrHeadingS = 'Attribuut';\n  AbFileFormatHeadingS = 'Formaat';\n  AbEncryptionHeadingS = 'Versleuteld';\n  AbTimeStampHeadingS = 'Tijdstempel';\n  AbFileSizeHeadingS = 'Grootte';\n  AbVersionMadeHeadingS = 'Gebruikte versie';\n  AbVersionNeededHeadingS = 'Benodigde versie';\n  AbPathHeadingS = 'Pad';\n  AbPartialHeadingS = 'Partieel';\n  AbExecutableHeadingS = 'Uitvoerbaar';\n\n  AbCabMethod0S = 'Geen';\n  AbCabMethod1S = 'MSZip';\n\n  AbLtAddS = ' toegevoegd ';\n  AbLtDeleteS = ' gewist ';\n  AbLtExtractS = ' ontpakt ';\n  AbLtFreshenS = ' geactualiseerd ';\n  AbLtMoveS = ' verplaatst ';\n  AbLtReplaceS = ' vervangen ';\n  AbLtStartS = ' geprotocolleerd ';\n\n  AbGzipInvalidS                   = 'Ongeldige Gzip';\n  AbGzipBadCRCS                    = 'Ongeldige CRC';\n  AbGzipBadFileSizeS               = 'Ongeldige bestandsgrootte';\n\n  AbTarInvalidS                    = 'Ongeldige Tar';\n  \n  AbTarBadFileNameS                = 'Bestandsnaam te lang';\n  \n  AbTarBadLinkNameS                = 'Link naam te lang';\n  \n  AbTarBadOpS                      = 'Niet ondersteunde functie';\n\n  \n\n  AbUnhandledEntityS               = 'Niet behandelde entiteit';\n\n  { pre-defined \"operating system\" (really more FILE system) identifiers for the\n    Gzip header }\n  AbGzOsFat         = 'FAT Bestandssysteem (MS-DOS, OS/2, NT/Win32)';\n  AbGzOsAmiga       = 'Amiga';\n  AbGzOsVMS         = 'VMS (oder OpenVMS)';\n  AbGzOsUnix        = 'Unix';\n  AbGzOsVM_CMS      = 'VM/CMS';\n  AbGzOsAtari       = 'Atari TOS';\n  AbGzOsHPFS        = 'HPFS Bestandssysteem (OS/2, NT)';\n  AbGzOsMacintosh   = 'Macintosh';\n  AbGzOsZ_System    = 'Z-System';\n  AbGzOsCP_M        = 'CP/M';\n  AbGzOsTOPS_20     = 'TOPS-20';\n  AbGzOsNTFS        = 'NTFS Bestandssysteem (NT)';\n  AbGzOsQDOS        = 'QDOS';\n  AbGzOsAcornRISCOS = 'Acorn RISC OS';\n  AbGzOsVFAT        = 'VFAT Bestandssysteem (Win95, NT)';\n  AbGzOsMVS         = 'MVS';\n  AbGzOsBeOS        = 'BeOS (BeBox of PowerMac)';\n  AbGzOsTandem      = 'Tandem/NSK';\n  AbGzOsTHEOS       = 'THEOS';\n  AbGzOsunknown     = 'onbekend';\n  AbGzOsUndefined   = 'ID is Gzip niet bekend';\n\n{!!.03 - Moved from AbCompnd.inc }\n{ Compound File specific error messages }\nresourcestring\n  AbCmpndIndexOutOfBounds   = 'Index niet in toegelaten bereik';\n  AbCmpndBusyUpdating       = 'Samengesteld bestand wordt geactualiseerd';\n  AbCmpndInvalidFile        = 'Ongeldig samengesteld bestand ';\n  AbCmpndFileNotFound       = 'Bestand/directory niet gevonden';\n  AbCmpndFolderNotEmpty     = 'Directory is niet leeg';\n  AbCmpndExceedsMaxFileSize = 'Bestandsgrootte overschrijdt toegelaten maximum';\n{!!.03 - End Moved }\n\n\n\nimplementation\n\nend.\n"
  },
  {
    "path": "lib/abbrevia/localization/AbResString.pas.ru",
    "content": "﻿(* ***** BEGIN LICENSE BLOCK *****\n * Version: MPL 1.1\n *\n * The contents of this file are subject to the Mozilla Public License Version\n * 1.1 (the \"License\"); you may not use this file except in compliance with\n * the License. You may obtain a copy of the License at\n * http://www.mozilla.org/MPL/\n *\n * Software distributed under the License is distributed on an \"AS IS\" basis,\n * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License\n * for the specific language governing rights and limitations under the\n * License.\n *\n * The Original Code is TurboPower Abbrevia\n *\n * The Initial Developer of the Original Code is\n * TurboPower Software\n *\n * Portions created by the Initial Developer are Copyright (C) 1997-2002\n * the Initial Developer. All Rights Reserved.\n *\n * Contributor(s):\n * Pavel Koptev, Roman Kassebaum\n *\n * ***** END LICENSE BLOCK ***** *)\n\n{*********************************************************}\n{* Abbrevia: AbResString.pas                             *}\n{*********************************************************}\n{* Abbrevia: Resource strings, Russian localization      *}\n{*********************************************************}\n{* Warning: This file is UTF-8 encoded                   *}\n{*********************************************************}\n{* You need D2009 or higher to compile this unit         *}\n{*********************************************************}\nunit AbResString;\n\ninterface\n\nresourcestring\n  AbErrZipInvalidS = 'Формат архива не соответствует PKZip-формату';\n  AbZipVersionNeededS = 'Действие невозможно. Файл запакован более новой версией программы';\n  AbUnknownCompressionMethodS = 'Действие невозможно. Нераспознанный метод сжатия';\n  AbNoExtractionMethodS = 'Действие невозможно. Не доступен метод распаковки архива';\n  AbInvalidPasswordS = 'Действие невозможно. Неверный пароль';\n  AbNoInsertionMethodS = 'Действие невозможно. Архивом не поддерживается добавление новых файлов';\n  AbInvalidFactorS = 'Недействительный фактор сжатия';\n  AbDuplicateNameS = 'Действие невозможно. Файл с таким именем в архиве уже присутствует';\n  AbUnsupportedCompressionMethodS = 'Действие невозможно. Неподдерживаемый метод сжатия';\n  AbUserAbortS = 'Действие отменено пользователем';\n  AbArchiveBusyS = 'Действие невозможно. Архив поврежден';\n  AbLastDiskRequestS = 'Вставьте последнюю дискету в дисковод';\n  AbDiskRequestS = 'Вставьте дискету в дисковод';\n  AbImageRequestS = 'Имя образа';\n  AbBadSpanStreamS = 'Многотомные архивы открываются как файловый поток';\n  AbDiskNumRequestS = 'Вставьте %d дискету в дисковод';\n  AbImageNumRequestS = 'Укажите расположение %d тома архива';\n  AbNoOverwriteSpanStreamS = 'Невозможно изменить существующий многотомный архив';\n  AbNoSpannedSelfExtractS = 'Невозможно создать многотомный SFX-Архив';\n  AbBlankDiskS = 'Вставьте чистую дискету в дисковод';\n  AbStreamFullS = 'Ошибка записи в память';\n  AbNoSuchDirectoryS = 'Папка не существует';\n  AbInflateBlockErrorS = 'Блок данных не может быть распакован';\n  AbBadStreamTypeS = 'Недействительный поток';\n  AbTruncateErrorS = 'Ошибка при разделении Zip-Файла';\n  AbZipBadCRCS = 'Не верная контрольная сумма';\n  AbZipBadStubS = 'Корневой элемент архива должен быть исполняемым файлом';\n  AbFileNotFoundS = 'Файл не найден';\n  AbInvalidLFHS = 'Неверное начало файла';\n  AbNoArchiveS = 'Архив не существует';\n  AbReadErrorS = 'Ошибка чтения архива';\n  AbInvalidIndexS = 'Неверный индекс елемента архива';\n  AbInvalidThresholdS = 'Неверный размер частей архива';\n  AbUnhandledFileTypeS = 'Неизвестный архив';\n  AbSpanningNotSupportedS = 'Многотомность не поддерживается этим типом архивов';\n  AbLogCreateErrorS = 'Ошибка при создании файла протокола';\n  AbMoveFileErrorS = 'Ошибка при перемещении файла %s в %s';\n  AbFileSizeTooBigS = 'Файл слишком велик для выбранного типа архива';\n\n  AbNoCabinetDllErrorS = 'Библиотека cabinet.dll не может быть загружена';\n  AbFCIFileOpenErrorS = 'FCI невозможно открыть файл';\n  AbFCIFileReadErrorS = 'FCI невозможно прочитать файл';\n  AbFCIFileWriteErrorS = 'FCI невозможно записать файл';\n  AbFCIFileCloseErrorS = 'FCI ошибка при закрытии файла';\n  AbFCIFileSeekErrorS = 'FCI ошибка при поиске в файле';\n  AbFCIFileDeleteErrorS = 'FCI ошибка при удалении файла';\n  AbFCIAddFileErrorS = 'FCI невозможно добавить файл';\n  AbFCICreateErrorS = 'FCI ошибка создания';\n  AbFCIFlushCabinetErrorS = 'FCI Cabinet-архив не может быть создан';\n  AbFCIFlushFolderErrorS = 'FCI невозможно удалить все файлы из папки';\n  AbFDICopyErrorS = 'FDI невозможно пересчитать файлы';\n  AbFDICreateErrorS = 'FDI ошибка создания';\n  AbInvalidCabTemplateS = 'Неверный шаблон Cabinet-файла';\n  AbInvalidCabFileS = ' Неверный Cabinet-файл';\n\n  AbZipStored = 'Сохранено';\n  AbZipShrunk = 'Сжато';\n  AbZipReduced = 'Сжато';\n  AbZipImploded = 'Сжато';\n  AbZipTokenized = 'Разделен на части';\n  AbZipDeflated = 'Сжато';\n  AbZipDeflate64 = 'Лучшее сжатие';\n  AbZipDCLImploded = 'DCL Сжато';\n  AbZipBzip2 = 'Bzip2';\n  AbZipLZMA = 'LZMA';\n  AbZipIBMTerse = 'IBM Terse';\n  AbZipLZ77 = 'IBM LZ77';\n  AbZipJPEG = 'JPEG';\n  AbZipWavPack = 'WavPack';\n  AbZipPPMd = 'PPMd';\n  AbZipUnknown = 'Неизвестно (%d)';\n  AbZipBestMethod = 'Лучший метод';\n\n  AbVersionFormatS = 'Версия %s';\n  AbCompressedSizeFormatS = 'Размер в архиве: %d';\n  AbUncompressedSizeFormatS = 'Размер: %d';\n  AbCompressionMethodFormatS = 'Метод сжатия: %s';\n  AbCompressionRatioFormatS = 'Степень сжатия: %2.0f%%';\n  AbCRCFormatS = 'CRC: %x';\n  AbReadOnlyS = 'r';\n  AbHiddenS = 'h';\n  AbSystemS = 's';\n  AbArchivedS = 'a';\n  AbEFAFormatS = 'Внешние атрибуты файла: %s';\n  AbIFAFormatS = 'Тип файла: %s';\n  AbTextS = 'Текст';\n  AbBinaryS = 'Двоичный';\n  AbEncryptionFormatS = 'Шифрование: %s';\n  AbEncryptedS = 'Зашифрован';\n  AbNotEncryptedS = 'Не зашифрован';\n  AbUnknownS = 'Неизвестно';\n  AbTimeStampFormatS = 'Формат времени: %s';\n  AbMadeByFormatS = 'Версия программы создания: %f';\n  AbNeededFormatS = 'Для распаковки требуется версия: %f';\n  AbCommentFormatS = 'Комментарии: %s';\n  AbDefaultExtS = '*.zip';\n  AbFilterS = 'PKZip-архив (*.zip)|*.zip|SFX-Архив (*.exe)|*.exe|Все файлы (*.*)|*.*';\n  AbFileNameTitleS = 'Выберите имя файла';\n\n  AbOKS = 'OK';\n  AbCancelS = 'Отмена';\n  AbSelectDirectoryS = 'Выберете папку';\n\n  AbEnterPasswordS = 'Введите пароль';\n  AbPasswordS = '&Пароль';\n  AbVerifyS = '&Проверка';\n\n  AbCabExtS = '*.cab';\n  AbCabFilterS = 'Cabinet-архив (*.cab)|*.CAB|Все файлы (*.*)|*.*';\n  AbLogExtS = '*.txt';\n  AbLogFilterS = 'Текстовые файлы (*.txt)|*.TXT|Все файлы (*.*)|*.*';\n  AbExeExtS = '*.exe';\n  AbExeFilterS = 'SFX-архивы (*.exe)|*.EXE|Все файлы (*.*)|*.*';\n\n  AbVMSReadTooManyBytesS = 'VMS: попытка чтения слишком большого числа байт [%d]';\n  AbVMSInvalidOriginS = 'VMS: недействительный источник %d, разрешены 0, 1, 2';\n  AbVMSErrorOpenSwapS = 'VMS: Невозможно открыть файл %s';\n  AbVMSSeekFailS = 'VMS: Невозможно осуществить поиск в файле %s';\n  AbVMSReadFailS = 'VMS: Невозможно прочитать файл %s';\n  AbVMSWriteFailS = 'VMS: Невозможно %d байт записать в файл %s';\n  AbVMSWriteTooManyBytesS = 'VMS: попытка записи слишком большого числа байт [%d]';\n\n  AbBBSReadTooManyBytesS = 'BBS: попытка чтения слишком большого числа байт [%d]';\n  AbBBSSeekOutsideBufferS = 'BBS: позиция находится вне буфера';\n  AbBBSInvalidOriginS = 'BBS: недействительно предыдущее значение';\n  AbBBSWriteTooManyBytesS = 'BBS: попытка записи слишком большого числа байт [%d]';\n\n  AbSWSNotEndofStreamS = 'TabSlidingWindowStream.Write: попытка записи данных не в конец потока';\n  AbSWSSeekFailedS = 'TabSlidingWindowStream.bsWriteChunk: поиск не удался';\n  AbSWSWriteFailedS = 'TabSlidingWindowStream.bsWriteChunk: запись не удалась';\n  AbSWSInvalidOriginS = 'TabSlidingWindowStream.Seek: Недействительный источник';\n  AbSWSInvalidNewOriginS = 'TabSlidingWindowStream.Seek: недействительная новая позиция';\n\n  AbItemNameHeadingS = 'Имя';\n  AbPackedHeadingS = 'Сжато';\n  AbMethodHeadingS = 'Метод';\n  AbRatioHeadingS = 'Коэффициент сжатия (%)';\n  AbCRCHeadingS = 'CRC32';\n  AbFileAttrHeadingS = 'Атрибуты';\n  AbFileFormatHeadingS = 'Формат';\n  AbEncryptionHeadingS = 'Шифрование';\n  AbTimeStampHeadingS = 'Время';\n  AbFileSizeHeadingS = 'Размер';\n  AbVersionMadeHeadingS = 'Использована версия';\n  AbVersionNeededHeadingS = 'Необходима версия';\n  AbPathHeadingS = 'Путь';\n  AbPartialHeadingS = 'Частично';\n  AbExecutableHeadingS = 'Выполнимо';\n\n  AbCabMethod0S = 'нет';\n  AbCabMethod1S = 'MSZip';\n\n  AbLtAddS = ' вставлен ';\n  AbLtDeleteS = ' удален ';\n  AbLtExtractS = ' распакован ';\n  AbLtFreshenS = ' обновлен ';\n  AbLtMoveS = ' перемещен ';\n  AbLtReplaceS = ' заменено ';\n  AbLtStartS = ' запротоколировано ';\n\n  AbGzipInvalidS                   = 'Недействительный Gzip';\n  AbGzipBadCRCS                    = 'Недействительная контрольная сумма';\n  AbGzipBadFileSizeS               = 'Недействительный размер файла';\n\n  AbTarInvalidS                    = 'Недествительный Tar-архив'; \n  AbTarBadFileNameS                = 'Слишком длинное имя файла';\n  AbTarBadLinkNameS                = 'Слишком длинная ссылка';\n  AbTarBadOpS                      = 'Неподдерживаемая операция';\n  \n  AbUnhandledEntityS             = 'Необрабатываемый объект';\n\n  { pre-defined \"operating system\" (really more FILE system) identifiers for the\n    Gzip header }\n  AbGzOsFat         = 'FAT файловая система (MS-DOS, OS/2, NT/Win32)';\n  AbGzOsAmiga       = 'Amiga';\n  AbGzOsVMS         = 'VMS (или OpenVMS)';\n  AbGzOsUnix        = 'Unix';\n  AbGzOsVM_CMS      = 'VM/CMS';\n  AbGzOsAtari       = 'Atari TOS';\n  AbGzOsHPFS        = 'HPFS файловая система (OS/2, NT)';\n  AbGzOsMacintosh   = 'Macintosh';\n  AbGzOsZ_System    = 'Z-System';\n  AbGzOsCP_M        = 'CP/M';\n  AbGzOsTOPS_20     = 'TOPS-20';\n  AbGzOsNTFS        = 'NTFS файловая система (NT)';\n  AbGzOsQDOS        = 'QDOS';\n  AbGzOsAcornRISCOS = 'Acorn RISCOS';\n  AbGzOsVFAT        = 'VFAT файловая система (Win95, NT)';\n  AbGzOsMVS         = 'MVS';\n  AbGzOsBeOS        = 'BeOS (BeBox или PowerMac)';\n  AbGzOsTandem      = 'Tandem/NSK';\n  AbGzOsTHEOS       = 'THEOS';\n  AbGzOsunknown     = 'неизвестно';\n  AbGzOsUndefined   = 'Идентификационный номер для Gzip не известен';\n\n{!!.03 - Moved from AbCompnd.inc }\n{ Compound File specific error messages }\nresourcestring\n  AbCmpndIndexOutOfBounds   = 'Индекс выходит за пределы допустимого диапазона';\n  AbCmpndBusyUpdating       = 'Обновляется файл связок';\n  AbCmpndInvalidFile        = 'Недействительный файл связок';\n  AbCmpndFileNotFound       = 'Файл или папка не найдены';\n  AbCmpndFolderNotEmpty     = 'Папка не пуста';\n  AbCmpndExceedsMaxFileSize = 'Допустимый размер файла был превышен';\n{!!.03 - End Moved }\n\n\n\nimplementation\n\nend.\n"
  },
  {
    "path": "lib/abbrevia/localization/AbResString.pas.tr",
    "content": "(* ***** BEGIN LICENSE BLOCK *****\n * Version: MPL 1.1\n *\n * The contents of this file are subject to the Mozilla Public License Version\n * 1.1 (the \"License\"); you may not use this file except in compliance with\n * the License. You may obtain a copy of the License at\n * http://www.mozilla.org/MPL/\n *\n * Software distributed under the License is distributed on an \"AS IS\" basis,\n * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License\n * for the specific language governing rights and limitations under the\n * License.\n *\n * The Original Code is TurboPower Abbrevia\n *\n * The Initial Developer of the Original Code is\n * TurboPower Software\n *\n * Portions created by the Initial Developer are Copyright (C) 1997-2002\n * the Initial Developer. All Rights Reserved.\n *\n * Contributor(s):\n * Durali Kiraz 2014-05-06\n *\n * ***** END LICENSE BLOCK ***** *)\n\n{*********************************************************}\n{* Abbrevia: AbResString.pas                             *}\n{*********************************************************}\n{* Abbrevia: Resource strings, Turkish localization      *}\n{*********************************************************}\n{* Encoded in Code Page 1252 (Windows Latin 5 Turkish)   *}\n{*********************************************************}\nunit AbResString;\n\n{$I AbDefine.inc}\n\ninterface\n\nresourcestring\n  AbErrZipInvalidS = 'Geersiz dosya - bir PKZip dosyas deil';\n  AbZipVersionNeededS = 'Dosya Ayklanamyor - daha yeni bir srm gerekli.';\n  AbUnknownCompressionMethodS = 'Dosya Ayklanamyor - desteklenmeyen sktrma yntemi';\n  AbNoExtractionMethodS = 'Dosya Ayklanamyor - salanan bir karma destei yok';\n  AbInvalidPasswordS = 'Dosya Ayklanamyor - geersiz ifre';\n  AbNoInsertionMethodS = 'Dosya Eklenemiyor - salanan bir ekleme destei yok';\n  AbInvalidFactorS = 'Geersiz Faktr azaltn';\n  AbDuplicateNameS = 'Dosya Eklenemiyor - saklanan dosya ad ift';\n  AbUnsupportedCompressionMethodS = 'Dosya Eklenemiyor - desteklenmeyen sktrma yntemi';\n  AbUserAbortS = 'Sre kullanc tarafndan iptal edildi';\n  AbArchiveBusyS = 'Ariv megul - yeni istekleri ileyemiyor';\n  AbLastDiskRequestS = 'Yaylm disk setinde son diski yerletirin';\n  AbDiskRequestS = 'Disket takn';\n  AbImageRequestS = 'Kalp dosya ad';\n  AbBadSpanStreamS = 'Yaylm arivler dosya akkanlar gibi almaldr';\n  AbDiskNumRequestS = 'Yaylm disk setinin %d numaral diskini ekleyin';\n  AbImageNumRequestS = 'Yaylm dosya setinin aralkl %d numaral dosyasn ekleyin ';\n  AbNoOverwriteSpanStreamS = 'Varolan Yaylm disk seti gncelleme yaplamaz';\n  AbNoSpannedSelfExtractS = 'Bir kendi kendini ayklayan(exe dosyas) disk seti yaplamaz';\n  AbBlankDiskS = 'Bo bir disket ekle';\n  AbStreamFullS = 'Akkan yazma hatas';\n  AbNoSuchDirectoryS = 'Klasr mevcut deil';\n  AbInflateBlockErrorS = 'Blou iiremezsin (connot inflate)';\n  AbBadStreamTypeS = 'Geersiz Akkan';\n  AbTruncateErrorS = 'Zip dosyas hata ile kesiliyor';\n  AbZipBadCRCS = 'Baarsz CRC kontrol';\n  AbZipBadStubS = 'Stub bir altrlabilir(exe) olmal';\n  AbFileNotFoundS = 'Dosya bulunamad';\n  AbInvalidLFHS = 'Geersiz Yerel Dosya Bal giri';\n  AbNoArchiveS = 'Ariv mevcut deil - Dosyaad bo';\n  AbReadErrorS = 'Okuma hatas arivi';\n  AbInvalidIndexS = 'Geersiz ariv e Endeksi';\n  AbInvalidThresholdS = 'Geersiz ariv boyutu eii';\n  AbUnhandledFileTypeS = 'lenmeyen Ariv Tr';\n  AbSpanningNotSupportedS = 'Yaylma bu Ariv tr tarafndan desteklenmiyor ';\n  AbLogCreateErrorS = 'Gnlk Dosyas olutururken hata';\n  AbMoveFileErrorS = '%s kaynandan %s hedefine Dosya Tamada Hata';\n  AbFileSizeTooBigS = 'Dosya boyutu ariv tr iin ok byk';\n\n  AbNoCabinetDllErrorS = 'cabinet.dll yklenemedi';\n  AbFCIFileOpenErrorS = 'FCI dosya alamad';\n  AbFCIFileReadErrorS = 'FCI dosya okunmad';\n  AbFCIFileWriteErrorS = 'FCI dosya yazlamad';\n  AbFCIFileCloseErrorS = 'FCI dosya kapatmada hata';\n  AbFCIFileSeekErrorS = 'FCI dosya konumlanma hatas';\n  AbFCIFileDeleteErrorS = 'FCI dosya silme hatas';\n  AbFCIAddFileErrorS = 'FCI dosya eklenemedi';\n  AbFCICreateErrorS = 'FCI ierii oluturulamyor';\n  AbFCIFlushCabinetErrorS = 'FCI kabini flush yaplamyor';\n  AbFCIFlushFolderErrorS = 'FCI klasr flush yaplamyor';\n  AbFDICopyErrorS = 'FDI dosyalar numaralandrma yaplamyor';\n  AbFDICreateErrorS = 'FDI ierii oluturulamyor';\n  AbInvalidCabTemplateS = 'Geersiz cab dosya ablonu';\n  AbInvalidCabFileS = 'Geersiz Dosya - bir kabin dosyas deil';\n\n  AbZipStored = 'Depoland';\n  AbZipShrunk = 'Bzlm';\n  AbZipReduced = 'Azaltlm';\n  AbZipImploded = 'ine kt';\n  AbZipTokenized = 'Simgeletirilmi';\n  AbZipDeflated = 'nik';\n  AbZipDeflate64 = 'Gelitirilmi niklik';\n  AbZipDCLImploded = 'DCL Bzlm';\n  AbZipBzip2 = 'Bzip2';\n  AbZipLZMA = 'LZMA';\n  AbZipIBMTerse = 'IBM Terse';\n  AbZipLZ77 = 'IBM LZ77';\n  AbZipJPEG = 'JPEG';\n  AbZipWavPack = 'WavPack';\n  AbZipPPMd = 'PPMd';\n  AbZipUnknown = 'Bilinmeyen (%d)';\n  AbZipBestMethod = 'En yi Yntem';\n\n  AbVersionFormatS = 'Srm %s';\n  AbCompressedSizeFormatS = 'Sktrlm uzunluk: %d';\n  AbUncompressedSizeFormatS = 'Sktrlmam uzunluk: %d';\n  AbCompressionMethodFormatS = 'Sktrma Yntemi: %s';\n  AbCompressionRatioFormatS = 'Sktrma Oran: %2.0f%%';\n  AbCRCFormatS = 'CRC: %x';\n  AbReadOnlyS = 'r';\n  AbHiddenS = 'h';\n  AbSystemS = 's';\n  AbArchivedS = 'a';\n  AbEFAFormatS = 'Harici Dosya zellikleri: %s';\n  AbIFAFormatS = 'Dosya Tr: %s';\n  AbTextS = 'Text';\n  AbBinaryS = 'Binary';\n  AbEncryptionFormatS = 'ifreleme: %s';\n  AbEncryptedS = 'ifrelenmi';\n  AbNotEncryptedS = 'ifreli Deil';\n  AbUnknownS = 'Bilinmiyor';\n  AbTimeStampFormatS = 'Zaman Damgas: %s';\n  AbMadeByFormatS = 'Srm Yapan: %f';\n  AbNeededFormatS = 'Ayklamaya Gerekli Srm: %f';\n  AbCommentFormatS = 'Aklama: %s';\n  AbDefaultExtS = '*.zip';\n  AbFilterS = 'PKZip Arivleri (*.zip)|*.zip|Kendinden Ayklanabilen Arivler (*.exe)|*.exe|Tm Dosyalar (*.*)|*.*';\n  AbFileNameTitleS = 'Dosya Ad Se';\n\n  AbOKS = 'Tamam';\n  AbCancelS = 'Vazge';\n  AbSelectDirectoryS = 'Klasr Se';\n\n  AbEnterPasswordS = 'ifre Gir';\n  AbPasswordS = 'i&fre';\n  AbVerifyS = '&Dorula';\n\n  AbCabExtS = '*.cab';\n  AbCabFilterS = 'Kabin Arivleri (*.cab)|*.CAB|Tm Dosyalar (*.*)|*.*';\n  AbLogExtS = '*.txt';\n  AbLogFilterS = 'Metin Dosyalar (*.txt)|*.TXT|Tm Dosyalar (*.*)|*.*';\n  AbExeExtS = '*.exe';\n  AbExeFilterS = 'Kendinden-Ayklanabilen Zip Dosyalar (*.exe)|*.EXE|Tm Dosyalar (*.*)|*.*';\n\n  AbVMSReadTooManyBytesS = 'VMS: ok bayt okuma istei [%d]';\n  AbVMSInvalidOriginS = 'VMS: %d kkeni geersiz. Geerli deerler 0, 1, 2 olmaldr';\n  AbVMSErrorOpenSwapS = 'VMS: %s takas dosyas alamyor';\n  AbVMSSeekFailS = 'VMS: %s takas dosyasnda arama baarsz oldu';\n  AbVMSReadFailS = 'VMS: %d bayt %s takas dosyasndan okunurken baarsz oldu';\n  AbVMSWriteFailS = 'VMS: %d bayt %s takas dosyasndan yazlrken baarsz oldu';\n  AbVMSWriteTooManyBytesS = 'VMS: ok fazla bayt yazma istei [%d]';\n\n  AbBBSReadTooManyBytesS = 'BBS: ok fazla bayt okuma istei [%d]';\n  AbBBSSeekOutsideBufferS = 'BBS: Yeni konum arabellek dndadr';\n  AbBBSInvalidOriginS = 'BBS: Geersiz Kken deeri';\n  AbBBSWriteTooManyBytesS = 'BBS: ok fazla bayt yazma istei [%d]';\n\n  AbSWSNotEndofStreamS = 'TabSlidingWindowStream.Write: Akn sonunda deil';\n  AbSWSSeekFailedS = 'TabSlidingWindowStream.bsWriteChunk: Arama baarsz oldu';\n  AbSWSWriteFailedS = 'TabSlidingWindowStream.bsWriteChunk: Yazma baarsz oldu';\n  AbSWSInvalidOriginS = 'TabSlidingWindowStream.Seek: Geersiz kken';\n  AbSWSInvalidNewOriginS = 'TabSlidingWindowStream.Seek: Geersiz yeni konum';\n\n  AbItemNameHeadingS = 'Ad';\n  AbPackedHeadingS = 'Paketli';\n  AbMethodHeadingS = 'Yntemi';\n  AbRatioHeadingS = 'Oran (%)';\n  AbCRCHeadingS = 'CRC32';\n  AbFileAttrHeadingS = 'Nitelikler';\n  AbFileFormatHeadingS = 'Biim';\n  AbEncryptionHeadingS = 'ifrelenmi';\n  AbTimeStampHeadingS = 'Zaman Damgas';\n  AbFileSizeHeadingS = 'Uzunluk';\n  AbVersionMadeHeadingS = 'Srm Yapm';\n  AbVersionNeededHeadingS = 'Srm Gerekli';\n  AbPathHeadingS = 'Yolu';\n  AbPartialHeadingS = 'Ksmi';\n  AbExecutableHeadingS = 'altrlabilir';\n  AbFileTypeHeadingS = 'Tr';\n  AbLastModifiedHeadingS = 'Deitirilmi';\n\n  AbCabMethod0S = 'None';\n  AbCabMethod1S = 'MSZip';\n\n  AbLtAddS = ' eklendi ';\n  AbLtDeleteS = ' silindi ';\n  AbLtExtractS = ' aykland ';\n  AbLtFreshenS = ' tazelendi ';\n  AbLtMoveS = ' tand ';\n  AbLtReplaceS = ' deitirildi ';\n  AbLtStartS = ' gnlklendi ';\n\n  AbGzipInvalidS = 'Geersiz Gzip';\n  AbGzipBadCRCS = 'Bozuk CRC';\n  AbGzipBadFileSizeS = 'Bozuk Dosya Uzunluu';\n\n  AbTarInvalidS = 'Geersiz Tar';\n  AbTarBadFileNameS = 'Dosya ad ok uzun';\n  AbTarBadLinkNameS = 'ok uzun sembolik balant yolu';\n  AbTarBadOpS = 'Desteklenmeyen Operasyon';\n\n  AbUnhandledEntityS = 'lenmeyen Varlk';\n\n  { pre-defined \"operating system\" (really more FILE system) identifiers for the\n    Gzip header }\n  AbGzOsFat = 'FAT Dosya Sistemi (MS-DOS, OS/2, NT/Win32)';\n  AbGzOsAmiga = 'Amiga';\n  AbGzOsVMS = 'VMS (veya OpenVMS)';\n  AbGzOsUnix = 'Unix';\n  AbGzOsVM_CMS = 'VM/CMS';\n  AbGzOsAtari = 'Atari TOS';\n  AbGzOsHPFS = 'HPFS Dosya Sistemi (OS/2, NT)';\n  AbGzOsMacintosh = 'Macintosh';\n  AbGzOsZ_System = 'Z-System';\n  AbGzOsCP_M = 'CP/M';\n  AbGzOsTOPS_20 = 'TOPS-20';\n  AbGzOsNTFS = 'NTFS Dosya Sistemi (NT)';\n  AbGzOsQDOS = 'QDOS';\n  AbGzOsAcornRISCOS = 'Acorn RISCOS';\n  AbGzOsVFAT = 'VFAT Dosya Sistemi (Win95, NT)';\n  AbGzOsMVS = 'MVS';\n  AbGzOsBeOS = 'BeOS (BeBox veya PowerMac)';\n  AbGzOsTandem = 'Tandem/NSK';\n  AbGzOsTHEOS = 'THEOS';\n  AbGzOsunknown = 'bilinmeyen';\n  AbGzOsUndefined = 'gzip tarafndan tanmsz ID';\n\n{ Compound File specific error messages }\nresourcestring\n  AbCmpndIndexOutOfBounds = 'Endeks araln dndadr';\n  AbCmpndBusyUpdating = 'Bileik dosya gncelleme ile megul';\n  AbCmpndInvalidFile = 'Geersiz bileik dosya';\n  AbCmpndFileNotFound = 'Dosya/Klasr bulunamad';\n  AbCmpndFolderNotEmpty = 'Klasr bo deil';\n  AbCmpndExceedsMaxFileSize = 'Dosya boyutu izin verilen Azami deeri ayor';\n\nimplementation\n\nend."
  },
  {
    "path": "lib/abbrevia/packages/Delphi XE/Abbrevia.dpk",
    "content": "(* ***** BEGIN LICENSE BLOCK *****\n * Version: MPL 1.1\n *\n * The contents of this file are subject to the Mozilla Public License Version\n * 1.1 (the \"License\"); you may not use this file except in compliance with\n * the License. You may obtain a copy of the License at\n * http://www.mozilla.org/MPL/\n *\n * Software distributed under the License is distributed on an \"AS IS\" basis,\n * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License\n * for the specific language governing rights and limitations under the\n * License.\n *\n * The Original Code is TurboPower Abbrevia\n *\n * The Initial Developer of the Original Code is\n * TurboPower Software\n *\n * Portions created by the Initial Developer are Copyright (C) 1997-2002\n * the Initial Developer. All Rights Reserved.\n *\n * Contributor(s):\n *\n * ***** END LICENSE BLOCK ***** *)\n\npackage Abbrevia;\n\n{$R *.res}\n{$ALIGN 8}\n{$ASSERTIONS ON}\n{$BOOLEVAL OFF}\n{$DEBUGINFO OFF}\n{$EXTENDEDSYNTAX ON}\n{$IMPORTEDDATA ON}\n{$IOCHECKS ON}\n{$LOCALSYMBOLS OFF}\n{$LONGSTRINGS ON}\n{$OPENSTRINGS ON}\n{$OPTIMIZATION ON}\n{$OVERFLOWCHECKS OFF}\n{$RANGECHECKS OFF}\n{$REFERENCEINFO OFF}\n{$SAFEDIVIDE OFF}\n{$STACKFRAMES OFF}\n{$TYPEDADDRESS OFF}\n{$VARSTRINGCHECKS ON}\n{$WRITEABLECONST ON}\n{$MINENUMSIZE 1}\n{$IMAGEBASE $400000}\n{$DESCRIPTION 'Abbrevia Run-time package - RTL XE'}\n{$LIBSUFFIX '150'}\n{$RUNONLY}\n{$IMPLICITBUILD OFF}\n\nrequires\n  rtl;\n\ncontains\n  AbArcTyp in '..\\..\\source\\AbArcTyp.pas',\n  AbBase in '..\\..\\source\\AbBase.pas',\n  AbBitBkt in '..\\..\\source\\AbBitBkt.pas',\n  AbBrowse in '..\\..\\source\\AbBrowse.pas',\n  AbBzip2 in '..\\..\\source\\AbBzip2.pas',\n  AbBzip2Typ in '..\\..\\source\\AbBzip2Typ.pas',\n  AbCabExt in '..\\..\\source\\AbCabExt.pas',\n  AbCabKit in '..\\..\\source\\AbCabKit.pas',\n  AbCabMak in '..\\..\\source\\AbCabMak.pas',\n  AbCabTyp in '..\\..\\source\\AbCabTyp.pas',\n  AbCBrows in '..\\..\\source\\AbCBrows.pas',\n  AbCharset in '..\\..\\source\\AbCharset.pas',\n  AbConst in '..\\..\\source\\AbConst.pas',\n  AbCrtl in '..\\..\\source\\AbCrtl.pas',\n  AbDfBase in '..\\..\\source\\AbDfBase.pas',\n  AbDfCryS in '..\\..\\source\\AbDfCryS.pas',\n  AbDfDec in '..\\..\\source\\AbDfDec.pas',\n  AbDfEnc in '..\\..\\source\\AbDfEnc.pas',\n  AbDfHufD in '..\\..\\source\\AbDfHufD.pas',\n  AbDfInW in '..\\..\\source\\AbDfInW.pas',\n  AbDfOutW in '..\\..\\source\\AbDfOutW.pas',\n  AbDfPkMg in '..\\..\\source\\AbDfPkMg.pas',\n  AbDfStrm in '..\\..\\source\\AbDfStrm.pas',\n  AbDfXlat in '..\\..\\source\\AbDfXlat.pas',\n  AbExcept in '..\\..\\source\\AbExcept.pas',\n  AbFciFdi in '..\\..\\source\\AbFciFdi.pas',\n  AbGzTyp in '..\\..\\source\\AbGzTyp.pas',\n  AbLzma in '..\\..\\source\\AbLzma.pas',\n  AbPPMd in '..\\..\\source\\AbPPMd.pas',\n  AbResString in '..\\..\\source\\AbResString.pas',\n  AbSelfEx in '..\\..\\source\\AbSelfEx.pas',\n  AbSpanSt in '..\\..\\source\\AbSpanSt.pas',\n  AbSWStm in '..\\..\\source\\AbSWStm.pas',\n  AbTarTyp in '..\\..\\source\\AbTarTyp.pas',\n  AbUnzOutStm in '..\\..\\source\\AbUnzOutStm.pas',\n  AbUnzper in '..\\..\\source\\AbUnzper.pas',\n  AbUnzPrc in '..\\..\\source\\AbUnzPrc.pas',\n  AbUtils in '..\\..\\source\\AbUtils.pas',\n  AbVMStrm in '..\\..\\source\\AbVMStrm.pas',\n  AbWavPack in '..\\..\\source\\AbWavPack.pas',\n  AbZBrows in '..\\..\\source\\AbZBrows.pas',\n  AbZipExt in '..\\..\\source\\AbZipExt.pas',\n  AbZipKit in '..\\..\\source\\AbZipKit.pas',\n  AbZipper in '..\\..\\source\\AbZipper.pas',\n  AbZipPrc in '..\\..\\source\\AbZipPrc.pas',\n  AbZipTyp in '..\\..\\source\\AbZipTyp.pas',\n  AbZLTyp in '..\\..\\source\\AbZLTyp.pas';\n\nend.\n"
  },
  {
    "path": "lib/abbrevia/packages/Delphi XE/Abbrevia.dproj",
    "content": "﻿\t<Project xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n\t\t<PropertyGroup>\n\t\t\t<ProjectGuid>{F41FD54F-C677-468D-B2F6-F7DEE8EEF36C}</ProjectGuid>\n\t\t\t<MainSource>Abbrevia.dpk</MainSource>\n\t\t\t<Config Condition=\"'$(Config)'==''\">Debug</Config>\n\t\t\t<DCC_DCCCompiler>DCC32</DCC_DCCCompiler>\n\t\t\t<ProjectVersion>12.2</ProjectVersion>\n\t\t\t<Base>True</Base>\n\t\t\t<Platform Condition=\"'$(Platform)'==''\">Win32</Platform>\n\t\t\t<AppType>Package</AppType>\n\t\t\t<FrameworkType>None</FrameworkType>\n\t\t\t<Platform>Win32</Platform>\n\t\t</PropertyGroup>\n\t\t<PropertyGroup Condition=\"'$(Config)'=='Base' or '$(Base)'!=''\">\n\t\t\t<Base>true</Base>\n\t\t</PropertyGroup>\n\t\t<PropertyGroup Condition=\"'$(Config)'=='Release' or '$(Cfg_1)'!=''\">\n\t\t\t<Cfg_1>true</Cfg_1>\n\t\t\t<CfgParent>Base</CfgParent>\n\t\t\t<Base>true</Base>\n\t\t</PropertyGroup>\n\t\t<PropertyGroup Condition=\"'$(Config)'=='Debug' or '$(Cfg_2)'!=''\">\n\t\t\t<Cfg_2>true</Cfg_2>\n\t\t\t<CfgParent>Base</CfgParent>\n\t\t\t<Base>true</Base>\n\t\t</PropertyGroup>\n\t\t<PropertyGroup Condition=\"'$(Base)'!=''\">\n\t\t\t<DCC_BplOutput>$(BDSCOMMONDIR)\\Bpl</DCC_BplOutput>\n\t\t\t<DCC_DependencyCheckOutputName>Abbrevia.bpl</DCC_DependencyCheckOutputName>\n\t\t\t<DCC_UnitAlias>WinTypes=Windows;WinProcs=Windows;DbiTypes=BDE;DbiProcs=BDE;DbiErrs=BDE;$(DCC_UnitAlias)</DCC_UnitAlias>\n\t\t\t<RuntimeOnlyPackage>true</RuntimeOnlyPackage>\n\t\t\t<DCC_LocalDebugSymbols>false</DCC_LocalDebugSymbols>\n\t\t\t<DCC_Description>Abbrevia Run-time package - RTL XE</DCC_Description>\n\t\t\t<DCC_WriteableConstants>true</DCC_WriteableConstants>\n\t\t\t<DCC_OutputNeverBuildDcps>true</DCC_OutputNeverBuildDcps>\n\t\t\t<GenDll>true</GenDll>\n\t\t\t<GenPackage>true</GenPackage>\n\t\t\t<DllSuffix>150</DllSuffix>\n\t\t\t<DCC_DebugInformation>false</DCC_DebugInformation>\n\t\t\t<DCC_SymbolReferenceInfo>0</DCC_SymbolReferenceInfo>\n\t\t\t<DCC_ImageBase>00400000</DCC_ImageBase>\n\t\t\t<DCC_Platform>x86</DCC_Platform>\n\t\t</PropertyGroup>\n\t\t<PropertyGroup Condition=\"'$(Cfg_1)'!=''\">\n\t\t\t<DCC_LocalDebugSymbols>false</DCC_LocalDebugSymbols>\n\t\t\t<DCC_Define>RELEASE;$(DCC_Define)</DCC_Define>\n\t\t\t<DCC_SymbolReferenceInfo>0</DCC_SymbolReferenceInfo>\n\t\t\t<DCC_DebugInformation>false</DCC_DebugInformation>\n\t\t</PropertyGroup>\n\t\t<PropertyGroup Condition=\"'$(Cfg_2)'!=''\">\n\t\t\t<DCC_Define>DEBUG;$(DCC_Define)</DCC_Define>\n\t\t</PropertyGroup>\n\t\t<ItemGroup>\n\t\t\t<DelphiCompile Include=\"Abbrevia.dpk\">\n\t\t\t\t<MainSource>MainSource</MainSource>\n\t\t\t</DelphiCompile>\n\t\t\t<DCCReference Include=\"rtl.dcp\"/>\n\t\t\t<BuildConfiguration Include=\"Debug\">\n\t\t\t\t<Key>Cfg_2</Key>\n\t\t\t\t<CfgParent>Base</CfgParent>\n\t\t\t</BuildConfiguration>\n\t\t\t<BuildConfiguration Include=\"Base\">\n\t\t\t\t<Key>Base</Key>\n\t\t\t</BuildConfiguration>\n\t\t\t<BuildConfiguration Include=\"Release\">\n\t\t\t\t<Key>Cfg_1</Key>\n\t\t\t\t<CfgParent>Base</CfgParent>\n\t\t\t</BuildConfiguration>\n\t\t</ItemGroup>\n\t\t<Import Condition=\"Exists('$(BDS)\\Bin\\CodeGear.Delphi.Targets')\" Project=\"$(BDS)\\Bin\\CodeGear.Delphi.Targets\"/>\n\t\t<Import Condition=\"Exists('$(APPDATA)\\Embarcadero\\$(BDSAPPDATABASEDIR)\\8.0\\UserTools.proj')\" Project=\"$(APPDATA)\\Embarcadero\\$(BDSAPPDATABASEDIR)\\8.0\\UserTools.proj\"/>\n\t\t<ProjectExtensions>\n\t\t\t<Borland.Personality>Delphi.Personality.12</Borland.Personality>\n\t\t\t<Borland.ProjectType>Package</Borland.ProjectType>\n\t\t\t<BorlandProject>\n\t\t\t\t<Delphi.Personality>\n\t\t\t\t\t<Source>\n\t\t\t\t\t\t<Source Name=\"MainSource\">Abbrevia.dpk</Source>\n\t\t\t\t\t</Source>\n\t\t\t\t\t<Parameters/>\n\t\t\t\t\t<VersionInfo>\n\t\t\t\t\t\t<VersionInfo Name=\"IncludeVerInfo\">True</VersionInfo>\n\t\t\t\t\t\t<VersionInfo Name=\"AutoIncBuild\">False</VersionInfo>\n\t\t\t\t\t\t<VersionInfo Name=\"MajorVer\">4</VersionInfo>\n\t\t\t\t\t\t<VersionInfo Name=\"MinorVer\">0</VersionInfo>\n\t\t\t\t\t\t<VersionInfo Name=\"Release\">0</VersionInfo>\n\t\t\t\t\t\t<VersionInfo Name=\"Build\">0</VersionInfo>\n\t\t\t\t\t\t<VersionInfo Name=\"Debug\">False</VersionInfo>\n\t\t\t\t\t\t<VersionInfo Name=\"PreRelease\">False</VersionInfo>\n\t\t\t\t\t\t<VersionInfo Name=\"Special\">False</VersionInfo>\n\t\t\t\t\t\t<VersionInfo Name=\"Private\">False</VersionInfo>\n\t\t\t\t\t\t<VersionInfo Name=\"DLL\">False</VersionInfo>\n\t\t\t\t\t\t<VersionInfo Name=\"Locale\">1033</VersionInfo>\n\t\t\t\t\t\t<VersionInfo Name=\"CodePage\">1252</VersionInfo>\n\t\t\t\t\t</VersionInfo>\n\t\t\t\t\t<VersionInfoKeys>\n\t\t\t\t\t\t<VersionInfoKeys Name=\"CompanyName\"/>\n\t\t\t\t\t\t<VersionInfoKeys Name=\"FileDescription\">Abbrevia Components</VersionInfoKeys>\n\t\t\t\t\t\t<VersionInfoKeys Name=\"FileVersion\">5.0.0.0</VersionInfoKeys>\n\t\t\t\t\t\t<VersionInfoKeys Name=\"InternalName\"/>\n\t\t\t\t\t\t<VersionInfoKeys Name=\"LegalCopyright\">Copyright (c) Abbrevia Group 2011</VersionInfoKeys>\n\t\t\t\t\t\t<VersionInfoKeys Name=\"LegalTrademarks\"/>\n\t\t\t\t\t\t<VersionInfoKeys Name=\"OriginalFilename\"/>\n\t\t\t\t\t\t<VersionInfoKeys Name=\"ProductName\">Abbrevia</VersionInfoKeys>\n\t\t\t\t\t\t<VersionInfoKeys Name=\"ProductVersion\">5.0</VersionInfoKeys>\n\t\t\t\t\t\t<VersionInfoKeys Name=\"Comments\"/>\n\t\t\t\t\t</VersionInfoKeys>\n\t\t\t\t\t<Excluded_Packages>\n\t\t\t\t\t\t<Excluded_Packages Name=\"$(BDSBIN)\\dcloffice2k140.bpl\">Microsoft Office 2000 Sample Automation Server Wrapper Components</Excluded_Packages>\n\t\t\t\t\t\t<Excluded_Packages Name=\"$(BDSBIN)\\dclofficexp140.bpl\">Microsoft Office XP Sample Automation Server Wrapper Components</Excluded_Packages>\n\t\t\t\t\t</Excluded_Packages>\n\t\t\t\t</Delphi.Personality>\n\t\t\t\t<Platforms>\n\t\t\t\t\t<Platform value=\"Win32\">True</Platform>\n\t\t\t\t</Platforms>\n\t\t\t</BorlandProject>\n\t\t\t<ProjectFileVersion>12</ProjectFileVersion>\n\t\t</ProjectExtensions>\n\t</Project>\n"
  },
  {
    "path": "lib/abbrevia/packages/Delphi XE/AbbreviaVCL.dpk",
    "content": "(* ***** BEGIN LICENSE BLOCK *****\n * Version: MPL 1.1\n *\n * The contents of this file are subject to the Mozilla Public License Version\n * 1.1 (the \"License\"); you may not use this file except in compliance with\n * the License. You may obtain a copy of the License at\n * http://www.mozilla.org/MPL/\n *\n * Software distributed under the License is distributed on an \"AS IS\" basis,\n * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License\n * for the specific language governing rights and limitations under the\n * License.\n *\n * The Original Code is TurboPower Abbrevia\n *\n * The Initial Developer of the Original Code is\n * TurboPower Software\n *\n * Portions created by the Initial Developer are Copyright (C) 1997-2002\n * the Initial Developer. All Rights Reserved.\n *\n * Contributor(s):\n *\n * ***** END LICENSE BLOCK ***** *)\n\npackage AbbreviaVCL;\n\n{$R *.res}\n{$ALIGN 8}\n{$ASSERTIONS ON}\n{$BOOLEVAL OFF}\n{$DEBUGINFO OFF}\n{$EXTENDEDSYNTAX ON}\n{$IMPORTEDDATA ON}\n{$IOCHECKS ON}\n{$LOCALSYMBOLS OFF}\n{$LONGSTRINGS ON}\n{$OPENSTRINGS ON}\n{$OPTIMIZATION ON}\n{$OVERFLOWCHECKS OFF}\n{$RANGECHECKS OFF}\n{$REFERENCEINFO OFF}\n{$SAFEDIVIDE OFF}\n{$STACKFRAMES OFF}\n{$TYPEDADDRESS OFF}\n{$VARSTRINGCHECKS ON}\n{$WRITEABLECONST ON}\n{$MINENUMSIZE 1}\n{$IMAGEBASE $400000}\n{$DESCRIPTION 'Abbrevia Run-time package - VCLXE'}\n{$LIBSUFFIX '150'}\n{$RUNONLY}\n{$IMPLICITBUILD OFF}\n\nrequires\n  rtl,\n  vcl,\n  vclx,\n  Abbrevia;\n\ncontains\n  AbBseVCL in '..\\..\\source\\AbBseVCL.pas',\n  AbMeter in '..\\..\\source\\AbMeter.pas',\n  AbView in '..\\..\\source\\AbView.pas',\n  AbZipOut in '..\\..\\source\\AbZipOut.pas',\n  AbCView in '..\\..\\source\\AbCView.pas',\n  AbZView in '..\\..\\source\\AbZView.pas',\n  AbCompnd in '..\\..\\source\\AbCompnd.pas',\n  AbHexVw in '..\\..\\source\\AbHexVw.pas',\n  AbComCtrls in '..\\..\\source\\AbComCtrls.pas';\n\nend.\n"
  },
  {
    "path": "lib/abbrevia/packages/Delphi XE/AbbreviaVCL.dproj",
    "content": "﻿\t<Project xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n\t\t<PropertyGroup>\n\t\t\t<ProjectGuid>{8F5900DA-6C2D-4EFA-96A5-D5AD0C68D886}</ProjectGuid>\n\t\t\t<MainSource>AbbreviaVCL.dpk</MainSource>\n\t\t\t<Config Condition=\"'$(Config)'==''\">Debug</Config>\n\t\t\t<DCC_DCCCompiler>DCC32</DCC_DCCCompiler>\n\t\t\t<ProjectVersion>12.2</ProjectVersion>\n\t\t\t<Base>True</Base>\n\t\t\t<Platform Condition=\"'$(Platform)'==''\">Win32</Platform>\n\t\t\t<AppType>Package</AppType>\n\t\t\t<FrameworkType>VCL</FrameworkType>\n\t\t\t<Platform>Win32</Platform>\n\t\t</PropertyGroup>\n\t\t<PropertyGroup Condition=\"'$(Config)'=='Base' or '$(Base)'!=''\">\n\t\t\t<Base>true</Base>\n\t\t</PropertyGroup>\n\t\t<PropertyGroup Condition=\"'$(Config)'=='Release' or '$(Cfg_1)'!=''\">\n\t\t\t<Cfg_1>true</Cfg_1>\n\t\t\t<CfgParent>Base</CfgParent>\n\t\t\t<Base>true</Base>\n\t\t</PropertyGroup>\n\t\t<PropertyGroup Condition=\"'$(Config)'=='Debug' or '$(Cfg_2)'!=''\">\n\t\t\t<Cfg_2>true</Cfg_2>\n\t\t\t<CfgParent>Base</CfgParent>\n\t\t\t<Base>true</Base>\n\t\t</PropertyGroup>\n\t\t<PropertyGroup Condition=\"'$(Base)'!=''\">\n\t\t\t<DCC_DependencyCheckOutputName>C:\\Users\\Public\\Documents\\RAD Studio\\7.0\\Bpl\\B305vr2010.bpl</DCC_DependencyCheckOutputName>\n\t\t\t<DCC_UnitAlias>WinTypes=Windows;WinProcs=Windows;DbiTypes=BDE;DbiProcs=BDE;DbiErrs=BDE;$(DCC_UnitAlias)</DCC_UnitAlias>\n\t\t\t<RuntimeOnlyPackage>true</RuntimeOnlyPackage>\n\t\t\t<DCC_LocalDebugSymbols>false</DCC_LocalDebugSymbols>\n\t\t\t<DCC_Description>Abbrevia Run-time package - VCLXE</DCC_Description>\n\t\t\t<DCC_WriteableConstants>true</DCC_WriteableConstants>\n\t\t\t<DCC_OutputNeverBuildDcps>true</DCC_OutputNeverBuildDcps>\n\t\t\t<GenDll>true</GenDll>\n\t\t\t<GenPackage>true</GenPackage>\n\t\t\t<DllSuffix>150</DllSuffix>\n\t\t\t<DCC_DebugInformation>false</DCC_DebugInformation>\n\t\t\t<DCC_SymbolReferenceInfo>0</DCC_SymbolReferenceInfo>\n\t\t\t<DCC_ImageBase>00400000</DCC_ImageBase>\n\t\t\t<DCC_Platform>x86</DCC_Platform>\n\t\t</PropertyGroup>\n\t\t<PropertyGroup Condition=\"'$(Cfg_1)'!=''\">\n\t\t\t<DCC_LocalDebugSymbols>false</DCC_LocalDebugSymbols>\n\t\t\t<DCC_Define>RELEASE;$(DCC_Define)</DCC_Define>\n\t\t\t<DCC_SymbolReferenceInfo>0</DCC_SymbolReferenceInfo>\n\t\t\t<DCC_DebugInformation>false</DCC_DebugInformation>\n\t\t</PropertyGroup>\n\t\t<PropertyGroup Condition=\"'$(Cfg_2)'!=''\">\n\t\t\t<DCC_Define>DEBUG;$(DCC_Define)</DCC_Define>\n\t\t</PropertyGroup>\n\t\t<ItemGroup>\n\t\t\t<DelphiCompile Include=\"AbbreviaVCL.dpk\">\n\t\t\t\t<MainSource>MainSource</MainSource>\n\t\t\t</DelphiCompile>\n\t\t\t<DCCReference Include=\"rtl.dcp\"/>\n\t\t\t<DCCReference Include=\"vcl.dcp\"/>\n\t\t\t<DCCReference Include=\"vclx.dcp\"/>\n\t\t\t<DCCReference Include=\"Abbrevia.dcp\"/>\n\t\t\t<DCCReference Include=\"..\\..\\source\\AbBseVCL.pas\"/>\n\t\t\t<DCCReference Include=\"..\\..\\source\\AbMeter.pas\"/>\n\t\t\t<DCCReference Include=\"..\\..\\source\\AbView.pas\"/>\n\t\t\t<DCCReference Include=\"..\\..\\source\\AbZipOut.pas\"/>\n\t\t\t<DCCReference Include=\"..\\..\\source\\AbCView.pas\"/>\n\t\t\t<DCCReference Include=\"..\\..\\source\\AbZView.pas\"/>\n\t\t\t<DCCReference Include=\"..\\..\\source\\AbCompnd.pas\"/>\n\t\t\t<DCCReference Include=\"..\\..\\source\\AbHexVw.pas\"/>\n\t\t\t<DCCReference Include=\"..\\..\\source\\AbComCtrls.pas\"/>\n\t\t\t<BuildConfiguration Include=\"Debug\">\n\t\t\t\t<Key>Cfg_2</Key>\n\t\t\t\t<CfgParent>Base</CfgParent>\n\t\t\t</BuildConfiguration>\n\t\t\t<BuildConfiguration Include=\"Base\">\n\t\t\t\t<Key>Base</Key>\n\t\t\t</BuildConfiguration>\n\t\t\t<BuildConfiguration Include=\"Release\">\n\t\t\t\t<Key>Cfg_1</Key>\n\t\t\t\t<CfgParent>Base</CfgParent>\n\t\t\t</BuildConfiguration>\n\t\t</ItemGroup>\n\t\t<Import Condition=\"Exists('$(BDS)\\Bin\\CodeGear.Delphi.Targets')\" Project=\"$(BDS)\\Bin\\CodeGear.Delphi.Targets\"/>\n\t\t<Import Condition=\"Exists('$(APPDATA)\\Embarcadero\\$(BDSAPPDATABASEDIR)\\8.0\\UserTools.proj')\" Project=\"$(APPDATA)\\Embarcadero\\$(BDSAPPDATABASEDIR)\\8.0\\UserTools.proj\"/>\n\t\t<ProjectExtensions>\n\t\t\t<Borland.Personality>Delphi.Personality.12</Borland.Personality>\n\t\t\t<Borland.ProjectType>Package</Borland.ProjectType>\n\t\t\t<BorlandProject>\n\t\t\t\t<Delphi.Personality>\n\t\t\t\t\t<Source>\n\t\t\t\t\t\t<Source Name=\"MainSource\">AbbreviaVCL.dpk</Source>\n\t\t\t\t\t</Source>\n\t\t\t\t\t<Parameters/>\n\t\t\t\t\t<VersionInfo>\n\t\t\t\t\t\t<VersionInfo Name=\"IncludeVerInfo\">True</VersionInfo>\n\t\t\t\t\t\t<VersionInfo Name=\"AutoIncBuild\">False</VersionInfo>\n\t\t\t\t\t\t<VersionInfo Name=\"MajorVer\">4</VersionInfo>\n\t\t\t\t\t\t<VersionInfo Name=\"MinorVer\">0</VersionInfo>\n\t\t\t\t\t\t<VersionInfo Name=\"Release\">0</VersionInfo>\n\t\t\t\t\t\t<VersionInfo Name=\"Build\">0</VersionInfo>\n\t\t\t\t\t\t<VersionInfo Name=\"Debug\">False</VersionInfo>\n\t\t\t\t\t\t<VersionInfo Name=\"PreRelease\">False</VersionInfo>\n\t\t\t\t\t\t<VersionInfo Name=\"Special\">False</VersionInfo>\n\t\t\t\t\t\t<VersionInfo Name=\"Private\">False</VersionInfo>\n\t\t\t\t\t\t<VersionInfo Name=\"DLL\">False</VersionInfo>\n\t\t\t\t\t\t<VersionInfo Name=\"Locale\">1033</VersionInfo>\n\t\t\t\t\t\t<VersionInfo Name=\"CodePage\">1252</VersionInfo>\n\t\t\t\t\t</VersionInfo>\n\t\t\t\t\t<VersionInfoKeys>\n\t\t\t\t\t\t<VersionInfoKeys Name=\"CompanyName\"/>\n\t\t\t\t\t\t<VersionInfoKeys Name=\"FileDescription\">Abbrevia Components</VersionInfoKeys>\n\t\t\t\t\t\t<VersionInfoKeys Name=\"FileVersion\">5.0.0.0</VersionInfoKeys>\n\t\t\t\t\t\t<VersionInfoKeys Name=\"InternalName\"/>\n\t\t\t\t\t\t<VersionInfoKeys Name=\"LegalCopyright\">Copyright (c) Abbrevia Group</VersionInfoKeys>\n\t\t\t\t\t\t<VersionInfoKeys Name=\"LegalTrademarks\"/>\n\t\t\t\t\t\t<VersionInfoKeys Name=\"OriginalFilename\"/>\n\t\t\t\t\t\t<VersionInfoKeys Name=\"ProductName\">Abbrevia</VersionInfoKeys>\n\t\t\t\t\t\t<VersionInfoKeys Name=\"ProductVersion\">5.0</VersionInfoKeys>\n\t\t\t\t\t\t<VersionInfoKeys Name=\"Comments\"/>\n\t\t\t\t\t</VersionInfoKeys>\n\t\t\t\t</Delphi.Personality>\n\t\t\t\t<Platforms>\n\t\t\t\t\t<Platform value=\"Win32\">True</Platform>\n\t\t\t\t</Platforms>\n\t\t\t</BorlandProject>\n\t\t\t<ProjectFileVersion>12</ProjectFileVersion>\n\t\t</ProjectExtensions>\n\t</Project>\n"
  },
  {
    "path": "lib/abbrevia/packages/Delphi XE/AbbreviaVCLDesign.dpk",
    "content": "(* ***** BEGIN LICENSE BLOCK *****\n * Version: MPL 1.1\n *\n * The contents of this file are subject to the Mozilla Public License Version\n * 1.1 (the \"License\"); you may not use this file except in compliance with\n * the License. You may obtain a copy of the License at\n * http://www.mozilla.org/MPL/\n *\n * Software distributed under the License is distributed on an \"AS IS\" basis,\n * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License\n * for the specific language governing rights and limitations under the\n * License.\n *\n * The Original Code is TurboPower Abbrevia\n *\n * The Initial Developer of the Original Code is\n * TurboPower Software\n *\n * Portions created by the Initial Developer are Copyright (C) 1997-2002\n * the Initial Developer. All Rights Reserved.\n *\n * Contributor(s):\n *\n * ***** END LICENSE BLOCK ***** *)\n\npackage AbbreviaVCLDesign;\n\n{$R *.res}\n{$ALIGN 8}\n{$ASSERTIONS ON}\n{$BOOLEVAL OFF}\n{$DEBUGINFO OFF}\n{$EXTENDEDSYNTAX ON}\n{$IMPORTEDDATA ON}\n{$IOCHECKS ON}\n{$LOCALSYMBOLS OFF}\n{$LONGSTRINGS ON}\n{$OPENSTRINGS ON}\n{$OPTIMIZATION ON}\n{$OVERFLOWCHECKS OFF}\n{$RANGECHECKS OFF}\n{$REFERENCEINFO OFF}\n{$SAFEDIVIDE OFF}\n{$STACKFRAMES OFF}\n{$TYPEDADDRESS OFF}\n{$VARSTRINGCHECKS ON}\n{$WRITEABLECONST ON}\n{$MINENUMSIZE 1}\n{$IMAGEBASE $400000}\n{$DESCRIPTION 'Abbrevia Design-time package - VCLXE'}\n{$LIBSUFFIX '150'}\n{$DESIGNONLY}\n{$IMPLICITBUILD OFF}\n\nrequires\n  designide,\n  AbbreviaVCL;\n\ncontains\n  AbPeCol in '..\\..\\source\\AbPeCol.pas',\n  AbPeDir in '..\\..\\source\\AbPeDir.pas',\n  AbPeFn in '..\\..\\source\\AbPeFn.pas',\n  AbPePass in '..\\..\\source\\AbPePass.pas',\n  AbPeVer in '..\\..\\source\\AbPeVer.pas',\n  AbRegVcl in '..\\..\\source\\AbRegVcl.pas',\n  AbDlgDir in '..\\..\\source\\AbDlgDir.pas' {DirDlg},\n  AbDlgPwd in '..\\..\\source\\AbDlgPwd.pas' {PassWordDlg};\n\nend.\n"
  },
  {
    "path": "lib/abbrevia/packages/Delphi XE/AbbreviaVCLDesign.dproj",
    "content": "﻿\t<Project xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n\t\t<PropertyGroup>\n\t\t\t<ProjectGuid>{24BE4180-8AB3-4667-927F-163D8C1A0D54}</ProjectGuid>\n\t\t\t<MainSource>AbbreviaVCLDesign.dpk</MainSource>\n\t\t\t<Config Condition=\"'$(Config)'==''\">Debug</Config>\n\t\t\t<DCC_DCCCompiler>DCC32</DCC_DCCCompiler>\n\t\t\t<ProjectVersion>12.2</ProjectVersion>\n\t\t\t<Base>True</Base>\n\t\t\t<Platform Condition=\"'$(Platform)'==''\">Win32</Platform>\n\t\t\t<AppType>Package</AppType>\n\t\t\t<FrameworkType>None</FrameworkType>\n\t\t\t<Platform>Win32</Platform>\n\t\t</PropertyGroup>\n\t\t<PropertyGroup Condition=\"'$(Config)'=='Base' or '$(Base)'!=''\">\n\t\t\t<Base>true</Base>\n\t\t</PropertyGroup>\n\t\t<PropertyGroup Condition=\"'$(Config)'=='Release' or '$(Cfg_1)'!=''\">\n\t\t\t<Cfg_1>true</Cfg_1>\n\t\t\t<CfgParent>Base</CfgParent>\n\t\t\t<Base>true</Base>\n\t\t</PropertyGroup>\n\t\t<PropertyGroup Condition=\"'$(Config)'=='Debug' or '$(Cfg_2)'!=''\">\n\t\t\t<Cfg_2>true</Cfg_2>\n\t\t\t<CfgParent>Base</CfgParent>\n\t\t\t<Base>true</Base>\n\t\t</PropertyGroup>\n\t\t<PropertyGroup Condition=\"'$(Base)'!=''\">\n\t\t\t<DCC_DependencyCheckOutputName>..\\..\\..\\..\\..\\..\\Public\\Documents\\RAD Studio\\7.0\\Bpl\\B305vd2010.bpl</DCC_DependencyCheckOutputName>\n\t\t\t<DesignOnlyPackage>true</DesignOnlyPackage>\n\t\t\t<DCC_Description>Abbrevia Design-time package - VCLXE</DCC_Description>\n\t\t\t<DCC_UnitAlias>WinTypes=Windows;WinProcs=Windows;DbiTypes=BDE;DbiProcs=BDE;DbiErrs=BDE;$(DCC_UnitAlias)</DCC_UnitAlias>\n\t\t\t<DCC_LocalDebugSymbols>false</DCC_LocalDebugSymbols>\n\t\t\t<DCC_WriteableConstants>true</DCC_WriteableConstants>\n\t\t\t<DllSuffix>150</DllSuffix>\n\t\t\t<GenPackage>true</GenPackage>\n\t\t\t<DCC_OutputNeverBuildDcps>true</DCC_OutputNeverBuildDcps>\n\t\t\t<GenDll>true</GenDll>\n\t\t\t<DCC_DebugInformation>false</DCC_DebugInformation>\n\t\t\t<DCC_SymbolReferenceInfo>0</DCC_SymbolReferenceInfo>\n\t\t\t<DCC_ImageBase>00400000</DCC_ImageBase>\n\t\t\t<DCC_Platform>x86</DCC_Platform>\n\t\t</PropertyGroup>\n\t\t<PropertyGroup Condition=\"'$(Cfg_1)'!=''\">\n\t\t\t<DCC_LocalDebugSymbols>false</DCC_LocalDebugSymbols>\n\t\t\t<DCC_Define>RELEASE;$(DCC_Define)</DCC_Define>\n\t\t\t<DCC_SymbolReferenceInfo>0</DCC_SymbolReferenceInfo>\n\t\t\t<DCC_DebugInformation>false</DCC_DebugInformation>\n\t\t</PropertyGroup>\n\t\t<PropertyGroup Condition=\"'$(Cfg_2)'!=''\">\n\t\t\t<DCC_Define>DEBUG;$(DCC_Define)</DCC_Define>\n\t\t</PropertyGroup>\n\t\t<ItemGroup>\n\t\t\t<DelphiCompile Include=\"AbbreviaVCLDesign.dpk\">\n\t\t\t\t<MainSource>MainSource</MainSource>\n\t\t\t</DelphiCompile>\n\t\t\t<DCCReference Include=\"designide.dcp\"/>\n\t\t\t<DCCReference Include=\"AbbreviaVCL.dcp\"/>\n\t\t\t<DCCReference Include=\"..\\..\\source\\AbPeCol.pas\"/>\n\t\t\t<DCCReference Include=\"..\\..\\source\\AbPeDir.pas\"/>\n\t\t\t<DCCReference Include=\"..\\..\\source\\AbPeFn.pas\"/>\n\t\t\t<DCCReference Include=\"..\\..\\source\\AbPePass.pas\"/>\n\t\t\t<DCCReference Include=\"..\\..\\source\\AbPeVer.pas\"/>\n\t\t\t<DCCReference Include=\"..\\..\\source\\AbRegVcl.pas\"/>\n\t\t\t<DCCReference Include=\"..\\..\\source\\AbDlgDir.pas\">\n\t\t\t\t<Form>DirDlg</Form>\n\t\t\t</DCCReference>\n\t\t\t<DCCReference Include=\"..\\..\\source\\AbDlgPwd.pas\">\n\t\t\t\t<Form>PassWordDlg</Form>\n\t\t\t</DCCReference>\n\t\t\t<BuildConfiguration Include=\"Debug\">\n\t\t\t\t<Key>Cfg_2</Key>\n\t\t\t\t<CfgParent>Base</CfgParent>\n\t\t\t</BuildConfiguration>\n\t\t\t<BuildConfiguration Include=\"Base\">\n\t\t\t\t<Key>Base</Key>\n\t\t\t</BuildConfiguration>\n\t\t\t<BuildConfiguration Include=\"Release\">\n\t\t\t\t<Key>Cfg_1</Key>\n\t\t\t\t<CfgParent>Base</CfgParent>\n\t\t\t</BuildConfiguration>\n\t\t</ItemGroup>\n\t\t<Import Condition=\"Exists('$(BDS)\\Bin\\CodeGear.Delphi.Targets')\" Project=\"$(BDS)\\Bin\\CodeGear.Delphi.Targets\"/>\n\t\t<Import Condition=\"Exists('$(APPDATA)\\Embarcadero\\$(BDSAPPDATABASEDIR)\\8.0\\UserTools.proj')\" Project=\"$(APPDATA)\\Embarcadero\\$(BDSAPPDATABASEDIR)\\8.0\\UserTools.proj\"/>\n\t\t<ProjectExtensions>\n\t\t\t<Borland.Personality>Delphi.Personality.12</Borland.Personality>\n\t\t\t<Borland.ProjectType>Package</Borland.ProjectType>\n\t\t\t<BorlandProject>\n\t\t\t\t<Delphi.Personality>\n\t\t\t\t\t<Source>\n\t\t\t\t\t\t<Source Name=\"MainSource\">AbbreviaVCLDesign.dpk</Source>\n\t\t\t\t\t</Source>\n\t\t\t\t\t<Parameters/>\n\t\t\t\t\t<VersionInfo>\n\t\t\t\t\t\t<VersionInfo Name=\"IncludeVerInfo\">True</VersionInfo>\n\t\t\t\t\t\t<VersionInfo Name=\"AutoIncBuild\">False</VersionInfo>\n\t\t\t\t\t\t<VersionInfo Name=\"MajorVer\">4</VersionInfo>\n\t\t\t\t\t\t<VersionInfo Name=\"MinorVer\">0</VersionInfo>\n\t\t\t\t\t\t<VersionInfo Name=\"Release\">0</VersionInfo>\n\t\t\t\t\t\t<VersionInfo Name=\"Build\">0</VersionInfo>\n\t\t\t\t\t\t<VersionInfo Name=\"Debug\">False</VersionInfo>\n\t\t\t\t\t\t<VersionInfo Name=\"PreRelease\">False</VersionInfo>\n\t\t\t\t\t\t<VersionInfo Name=\"Special\">False</VersionInfo>\n\t\t\t\t\t\t<VersionInfo Name=\"Private\">False</VersionInfo>\n\t\t\t\t\t\t<VersionInfo Name=\"DLL\">False</VersionInfo>\n\t\t\t\t\t\t<VersionInfo Name=\"Locale\">1033</VersionInfo>\n\t\t\t\t\t\t<VersionInfo Name=\"CodePage\">1252</VersionInfo>\n\t\t\t\t\t</VersionInfo>\n\t\t\t\t\t<VersionInfoKeys>\n\t\t\t\t\t\t<VersionInfoKeys Name=\"CompanyName\"/>\n\t\t\t\t\t\t<VersionInfoKeys Name=\"FileDescription\">Abbrevia Components</VersionInfoKeys>\n\t\t\t\t\t\t<VersionInfoKeys Name=\"FileVersion\">5.0.0.0</VersionInfoKeys>\n\t\t\t\t\t\t<VersionInfoKeys Name=\"InternalName\"/>\n\t\t\t\t\t\t<VersionInfoKeys Name=\"LegalCopyright\">Copyright (c) Abbrevia Group</VersionInfoKeys>\n\t\t\t\t\t\t<VersionInfoKeys Name=\"LegalTrademarks\"/>\n\t\t\t\t\t\t<VersionInfoKeys Name=\"OriginalFilename\"/>\n\t\t\t\t\t\t<VersionInfoKeys Name=\"ProductName\">Abbrevia</VersionInfoKeys>\n\t\t\t\t\t\t<VersionInfoKeys Name=\"ProductVersion\">5.0</VersionInfoKeys>\n\t\t\t\t\t\t<VersionInfoKeys Name=\"Comments\"/>\n\t\t\t\t\t</VersionInfoKeys>\n\t\t\t\t</Delphi.Personality>\n\t\t\t\t<Platforms>\n\t\t\t\t\t<Platform value=\"Win32\">True</Platform>\n\t\t\t\t</Platforms>\n\t\t\t</BorlandProject>\n\t\t\t<ProjectFileVersion>12</ProjectFileVersion>\n\t\t</ProjectExtensions>\n\t</Project>\n"
  },
  {
    "path": "lib/abbrevia/packages/Delphi XE.groupproj",
    "content": "﻿\t<Project xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n\t\t<PropertyGroup>\n\t\t\t<ProjectGuid>{3FC8294C-9FE8-49B9-9FF0-C33C59C18002}</ProjectGuid>\n\t\t</PropertyGroup>\n\t\t<ItemGroup>\n\t\t\t<Projects Include=\"Delphi XE\\Abbrevia.dproj\">\n\t\t\t\t<Dependencies/>\n\t\t\t</Projects>\n\t\t\t<Projects Include=\"Delphi XE\\AbbreviaVCL.dproj\">\n\t\t\t\t<Dependencies/>\n\t\t\t</Projects>\n\t\t\t<Projects Include=\"Delphi XE\\AbbreviaVCLDesign.dproj\">\n\t\t\t\t<Dependencies/>\n\t\t\t</Projects>\n\t\t</ItemGroup>\n\t\t<ProjectExtensions>\n\t\t\t<Borland.Personality>Default.Personality.12</Borland.Personality>\n\t\t\t<Borland.ProjectType/>\n\t\t\t<BorlandProject>\n\t\t\t\t<Default.Personality/>\n\t\t\t</BorlandProject>\n\t\t</ProjectExtensions>\n\t\t<Target Name=\"Abbrevia\">\n\t\t\t<MSBuild Projects=\"Delphi XE\\Abbrevia.dproj\"/>\n\t\t</Target>\n\t\t<Target Name=\"Abbrevia:Clean\">\n\t\t\t<MSBuild Targets=\"Clean\" Projects=\"Delphi XE\\Abbrevia.dproj\"/>\n\t\t</Target>\n\t\t<Target Name=\"Abbrevia:Make\">\n\t\t\t<MSBuild Targets=\"Make\" Projects=\"Delphi XE\\Abbrevia.dproj\"/>\n\t\t</Target>\n\t\t<Target Name=\"AbbreviaVCL\">\n\t\t\t<MSBuild Projects=\"Delphi XE\\AbbreviaVCL.dproj\"/>\n\t\t</Target>\n\t\t<Target Name=\"AbbreviaVCL:Clean\">\n\t\t\t<MSBuild Targets=\"Clean\" Projects=\"Delphi XE\\AbbreviaVCL.dproj\"/>\n\t\t</Target>\n\t\t<Target Name=\"AbbreviaVCL:Make\">\n\t\t\t<MSBuild Targets=\"Make\" Projects=\"Delphi XE\\AbbreviaVCL.dproj\"/>\n\t\t</Target>\n\t\t<Target Name=\"AbbreviaVCLDesign\">\n\t\t\t<MSBuild Projects=\"Delphi XE\\AbbreviaVCLDesign.dproj\"/>\n\t\t</Target>\n\t\t<Target Name=\"AbbreviaVCLDesign:Clean\">\n\t\t\t<MSBuild Targets=\"Clean\" Projects=\"Delphi XE\\AbbreviaVCLDesign.dproj\"/>\n\t\t</Target>\n\t\t<Target Name=\"AbbreviaVCLDesign:Make\">\n\t\t\t<MSBuild Targets=\"Make\" Projects=\"Delphi XE\\AbbreviaVCLDesign.dproj\"/>\n\t\t</Target>\n\t\t<Target Name=\"Build\">\n\t\t\t<CallTarget Targets=\"Abbrevia;AbbreviaVCL;AbbreviaVCLDesign\"/>\n\t\t</Target>\n\t\t<Target Name=\"Clean\">\n\t\t\t<CallTarget Targets=\"Abbrevia:Clean;AbbreviaVCL:Clean;AbbreviaVCLDesign:Clean\"/>\n\t\t</Target>\n\t\t<Target Name=\"Make\">\n\t\t\t<CallTarget Targets=\"Abbrevia:Make;AbbreviaVCL:Make;AbbreviaVCLDesign:Make\"/>\n\t\t</Target>\n\t\t<Import Condition=\"Exists('$(BDS)\\Bin\\CodeGear.Group.Targets')\" Project=\"$(BDS)\\Bin\\CodeGear.Group.Targets\"/>\n\t</Project>\n"
  },
  {
    "path": "lib/abbrevia/source/AbArcTyp.pas",
    "content": "(* ***** BEGIN LICENSE BLOCK *****\n * Version: MPL 1.1\n *\n * The contents of this file are subject to the Mozilla Public License Version\n * 1.1 (the \"License\"); you may not use this file except in compliance with\n * the License. You may obtain a copy of the License at\n * http://www.mozilla.org/MPL/\n *\n * Software distributed under the License is distributed on an \"AS IS\" basis,\n * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License\n * for the specific language governing rights and limitations under the\n * License.\n *\n * The Original Code is TurboPower Abbrevia\n *\n * The Initial Developer of the Original Code is\n * TurboPower Software\n *\n * Portions created by the Initial Developer are Copyright (C) 1997-2002\n * the Initial Developer. All Rights Reserved.\n *\n * Contributor(s):\n *\n * ***** END LICENSE BLOCK ***** *)\n\n{*********************************************************}\n{* ABBREVIA: AbArcTyp.pas                                *}\n{*********************************************************}\n{* ABBREVIA: TABArchive, TABArchiveItem classes          *}\n{*********************************************************}\n\nunit AbArcTyp;\n\n{$I AbDefine.inc}\n\ninterface\n\nuses\n  {$IFDEF MSWINDOWS}\n  Windows,\n  {$ENDIF MSWINDOWS}\n  Classes,\n  Types,\n  AbUtils;\n\n{ ===== TAbArchiveItem ====================================================== }\ntype\n  TAbArchiveItem = class(TObject)\n  protected {private}\n    NextItem          : TAbArchiveItem;\n    FAction           : TAbArchiveAction;\n    FCompressedSize   : Int64;\n    FCRC32            : Longint;\n    FDiskFileName     : string;\n    FExternalFileAttributes : LongWord;\n    FFileName         : string;\n    FIsEncrypted      : Boolean;\n    FLastModFileTime  : Word;\n    FLastModFileDate  : Word;\n    FTagged           : Boolean;\n    FUncompressedSize : Int64;\n\n  protected {property methods}\n    function GetCompressedSize : Int64; virtual;\n    function GetCRC32 : Longint; virtual;\n    function GetDiskPath : string;\n    function GetExternalFileAttributes : LongWord; virtual;\n    function GetFileName : string; virtual;\n    function GetIsDirectory: Boolean; virtual;\n    function GetIsEncrypted : Boolean; virtual;\n    function GetLastModFileDate : Word; virtual;\n    function GetLastModFileTime : Word; virtual;\n    function GetNativeFileAttributes : LongInt; virtual;\n    function GetStoredPath : string;\n    function GetUncompressedSize : Int64; virtual;\n    procedure SetCompressedSize(const Value : Int64); virtual;\n    procedure SetCRC32(const Value : Longint); virtual;\n    procedure SetExternalFileAttributes( Value : LongWord ); virtual;\n    procedure SetFileName(const Value : string); virtual;\n    procedure SetIsEncrypted(Value : Boolean); virtual;\n    procedure SetLastModFileDate(const Value : Word); virtual;\n    procedure SetLastModFileTime(const Value : Word); virtual;\n    procedure SetUncompressedSize(const Value : Int64); virtual;\n    function GetLastModTimeAsDateTime: TDateTime; virtual;\n    procedure SetLastModTimeAsDateTime(const Value: TDateTime); virtual;\n\n  public {methods}\n    constructor Create;\n    destructor Destroy; override;\n    function MatchesDiskName(const FileMask : string) : Boolean;\n    function MatchesStoredName(const FileMask : string) : Boolean;\n    function MatchesStoredNameEx(const FileMask : string) : Boolean;\n\n\n  public {properties}\n    property Action : TAbArchiveAction\n      read FAction\n      write FAction;\n    property CompressedSize : Int64\n      read GetCompressedSize\n      write SetCompressedSize;\n    property CRC32 : Longint\n      read GetCRC32\n      write SetCRC32;\n    property DiskFileName : string\n      read FDiskFileName\n      write FDiskFileName;\n    property DiskPath : string\n      read GetDiskPath;\n    property ExternalFileAttributes : LongWord\n      read GetExternalFileAttributes\n      write SetExternalFileAttributes;\n    property FileName : string\n      read GetFileName\n      write SetFileName;\n    property IsDirectory: Boolean\n      read GetIsDirectory;\n    property IsEncrypted : Boolean\n      read GetIsEncrypted\n      write SetIsEncrypted;\n    property LastModFileDate : Word\n      read GetLastModFileDate\n      write SetLastModFileDate;\n    property LastModFileTime : Word\n      read GetLastModFileTime\n      write SetLastModFileTime;\n    property NativeFileAttributes : LongInt\n      read GetNativeFileAttributes;\n    property StoredPath : string\n      read GetStoredPath;\n    property Tagged : Boolean\n      read FTagged\n      write FTagged;\n    property UncompressedSize : Int64\n      read GetUncompressedSize\n      write SetUncompressedSize;\n\n    property LastModTimeAsDateTime : TDateTime\n      read GetLastModTimeAsDateTime\n      write SetLastModTimeAsDateTime;\n  end;\n\n\n{ ===== TAbArchiveListEnumerator ============================================ }\ntype\n  TAbArchiveList = class;\n  TAbArchiveListEnumerator = class\n  private\n    FIndex: Integer;\n    FList: TAbArchiveList;\n  public\n    constructor Create(aList: TAbArchiveList);\n    function GetCurrent: TAbArchiveItem;\n    function MoveNext: Boolean;\n    property Current: TAbArchiveItem read GetCurrent;\n  end;\n\n\n{ ===== TAbArchiveList ====================================================== }\n\n  TAbArchiveList = class\n  protected {private}\n    FList     : TList;\n    FOwnsItems: Boolean;\n    HashTable : array[0..1020] of TAbArchiveItem;\n  protected {methods}\n    function GenerateHash(const S : string) : LongInt;\n    function GetCount : Integer;\n    function Get(Index : Integer) : TAbArchiveItem;\n    procedure Put(Index : Integer; Item : TAbArchiveItem);\n    procedure UpdateHash(aItem: TAbArchiveItem; const aOldFileName: string);\n  public {methods}\n    constructor Create(AOwnsItems: Boolean);\n    destructor Destroy; override;\n    function Add(aItem : TAbArchiveItem): Integer;\n    procedure Clear;\n    procedure Delete(Index : Integer);\n    function Find(const FN : string) : Integer;\n    function GetEnumerator: TAbArchiveListEnumerator;\n    function IsActiveDupe(const FN : string) : Boolean;\n  public {properties}\n    property Count : Integer\n      read GetCount;\n    property Items[Index : Integer] : TAbArchiveItem\n      read Get\n      write Put; default;\n  end;\n\n\n{ ===== TAbArchive specific types =========================================== }\ntype\n  TAbStoreOption =\n    (soStripDrive, soStripPath, soRemoveDots, soRecurse, soFreshen, soReplace);\n  TAbStoreOptions =\n    set of TAbStoreOption;\n\n  TAbExtractOption =\n    (eoCreateDirs, eoRestorePath);\n  TAbExtractOptions =\n    set of TAbExtractOption;\n\n  TAbArchiveStatus =\n    (asInvalid, asIdle, asBusy);\n\n  TAbArchiveEvent =\n    procedure(Sender : TObject) of object;\n  TAbArchiveConfirmEvent =\n    procedure (Sender : TObject; var Confirm : Boolean) of object;\n  TAbArchiveProgressEvent =\n    procedure(Sender : TObject; Progress : Byte; var Abort : Boolean) of object;\n  TAbArchiveItemEvent =\n    procedure(Sender : TObject; Item : TAbArchiveItem) of object;\n  TAbArchiveItemConfirmEvent =\n    procedure(Sender : TObject; Item : TAbArchiveItem;\n      ProcessType : TAbProcessType; var Confirm : Boolean) of object;\n  TAbConfirmOverwriteEvent =\n    procedure(var Name : string; var Confirm : Boolean) of object;\n  TAbArchiveItemFailureEvent =\n    procedure(Sender : TObject; Item : TAbArchiveItem;\n      ProcessType : TAbProcessType; ErrorClass : TAbErrorClass;\n      ErrorCode : Integer) of object;\n  TAbArchiveItemExtractEvent =\n    procedure(Sender : TObject; Item : TAbArchiveItem;\n      const NewName : string) of object;\n  TAbArchiveItemExtractToStreamEvent =\n    procedure(Sender : TObject; Item : TAbArchiveItem;\n      OutStream : TStream) of object;\n  TAbArchiveItemTestEvent =\n    procedure(Sender : TObject; Item : TAbArchiveItem) of object;\n  TAbArchiveItemInsertEvent =\n    procedure(Sender : TObject; Item : TAbArchiveItem;\n      OutStream : TStream) of object;\n  TAbArchiveItemInsertFromStreamEvent =\n    procedure(Sender : TObject; Item : TAbArchiveItem;\n      OutStream, InStream : TStream) of object;\n  TAbArchiveItemProgressEvent =\n    procedure(Sender : TObject; Item : TAbArchiveItem; Progress : Byte;\n      var Abort : Boolean) of object;\n  TAbProgressEvent =\n    procedure(Progress : Byte; var Abort : Boolean) of object;\n  TAbRequestDiskEvent =\n    procedure(Sender : TObject; var Abort : Boolean) of object;\n  TAbRequestImageEvent =\n    procedure(Sender : TObject; ImageNumber : Integer;\n      var ImageName : string; var Abort : Boolean) of object;\n  TAbRequestNthDiskEvent =\n    procedure(Sender : TObject; DiskNumber : Byte; var Abort : Boolean) of object;\n\n\ntype\n  TAbArchiveStreamHelper = class\n  protected\n    FStream : TStream;\n  public\n    constructor Create(AStream : TStream);\n    procedure ExtractItemData(AStream : TStream); virtual; abstract;\n    function FindFirstItem : Boolean; virtual; abstract;\n    function FindNextItem : Boolean; virtual; abstract;\n    procedure ReadHeader; virtual; abstract;\n    procedure ReadTail; virtual; abstract;\n    function SeekItem(Index : Integer): Boolean; virtual; abstract;\n    procedure WriteArchiveHeader; virtual; abstract;\n    procedure WriteArchiveItem(AStream : TStream); virtual; abstract;\n    procedure WriteArchiveTail; virtual; abstract;\n    function GetItemCount : Integer; virtual; abstract;\n  end;\n\n\n{ ===== TAbArchive ========================================================== }\ntype\n  TAbArchive = class(TObject)\n  public\n    FStream         : TStream;\n    FStatus         : TAbArchiveStatus;\n\n  protected {property variables}    //These break Encapsulation\n    FArchiveName    : string;\n    FAutoSave       : Boolean;\n    FBaseDirectory  : string;\n    FCurrentItem    : TAbArchiveItem;\n    FDOSMode        : Boolean;\n    FExtractOptions : TAbExtractOptions;\n    FImageNumber    : Word;\n    FInStream       : TStream;\n    FIsDirty        : Boolean;\n    FSpanningThreshold      : Int64;\n    FItemList       : TAbArchiveList;\n    FLogFile        : string;\n    FLogging        : Boolean;\n    FLogStream      : TFileStream;\n    FMode           : Word;\n    FOwnsStream     : Boolean;\n    FSpanned        : Boolean;\n    FStoreOptions   : TAbStoreOptions;\n    FTempDir        : string;\n\n  protected {event variables}\n    FOnProcessItemFailure  : TAbArchiveItemFailureEvent;\n    FOnArchiveProgress     : TAbArchiveProgressEvent;\n    FOnArchiveSaveProgress : TAbArchiveProgressEvent;\n    FOnArchiveItemProgress : TAbArchiveItemProgressEvent;\n    FOnConfirmProcessItem  : TAbArchiveItemConfirmEvent;\n    FOnConfirmOverwrite    : TAbConfirmOverwriteEvent;\n    FOnConfirmSave         : TAbArchiveConfirmEvent;\n    FOnLoad                : TAbArchiveEvent;\n    FOnProgress            : TAbProgressEvent;\n    FOnRequestImage        : TAbRequestImageEvent;\n    FOnSave                : TAbArchiveEvent;\n\n  protected {methods}\n    constructor CreateInit;\n    procedure CheckValid;\n    function  ConfirmPath(Item : TAbArchiveItem; const NewName : string;\n      out UseName : string) : Boolean;\n    procedure FreshenAt(Index : Integer);\n    function  FreshenRequired(Item : TAbArchiveItem) : Boolean;\n    procedure GetFreshenTarget(Item : TAbArchiveItem);\n    function  GetItemCount : Integer;\n    procedure MakeLogEntry(const FN: string; LT : TAbLogType);\n    procedure ReplaceAt(Index : Integer);\n    procedure SaveIfNeeded(aItem : TAbArchiveItem);\n    procedure SetBaseDirectory(Value : string);\n    procedure SetLogFile(const Value : string);\n    procedure SetLogging(Value : Boolean);\n\n  protected {abstract methods}\n    function CreateItem(const FileSpec : string): TAbArchiveItem;\n      virtual; abstract;\n    procedure ExtractItemAt(Index : Integer; const UseName : string);\n      virtual; abstract;\n    procedure ExtractItemToStreamAt(Index : Integer; aStream : TStream);\n      virtual; abstract;\n    procedure LoadArchive;\n      virtual; abstract;\n    procedure SaveArchive;\n      virtual; abstract;\n    procedure TestItemAt(Index : Integer);\n      virtual; abstract;\n\n  protected {virtual methods}\n    procedure DoProcessItemFailure(Item : TAbArchiveItem;\n      ProcessType : TAbProcessType; ErrorClass : TAbErrorClass;\n      ErrorCode : Integer);\n      virtual;\n    procedure DoArchiveSaveProgress(Progress : Byte; var Abort : Boolean);\n      virtual;\n    procedure DoArchiveProgress(Progress : Byte; var Abort : Boolean);\n      virtual;\n    procedure DoArchiveItemProgress(Item : TAbArchiveItem; Progress : Byte;\n      var Abort : Boolean);\n      virtual;\n    procedure DoConfirmOverwrite(var FileName : string; var Confirm : Boolean);\n      virtual;\n    procedure DoConfirmProcessItem(Item : TAbArchiveItem;\n      const ProcessType : TAbProcessType; var Confirm : Boolean);\n      virtual;\n    procedure DoConfirmSave(var Confirm : Boolean);\n      virtual;\n\n    procedure DoLoad;\n      virtual;\n    procedure DoProgress(Progress : Byte; var Abort : Boolean);\n      virtual;\n    procedure DoSave;\n      virtual;\n    function FixName(const Value : string) : string;\n      virtual;\n    function GetSpanningThreshold : Int64;\n      virtual;\n    function GetSupportsEmptyFolders : Boolean;\n      virtual;\n    procedure SetSpanningThreshold( Value : Int64 );\n      virtual;\n\n  protected {properties and events}\n    property InStream : TStream\n      read FInStream;\n\n  public {methods}\n    constructor Create(const FileName : string; Mode : Word);\n      virtual;\n    constructor CreateFromStream(aStream : TStream; const aArchiveName : string);\n      virtual;\n    destructor  Destroy;\n      override;\n    procedure Add(aItem : TAbArchiveItem);\n      virtual;\n    procedure AddFiles(const FileMask : string; SearchAttr : Integer);\n    procedure AddFilesEx(const FileMask, ExclusionMask : string;\n      SearchAttr : Integer);\n    procedure AddFromStream(const NewName : string; aStream : TStream);\n    procedure ClearTags;\n    procedure Delete(aItem : TAbArchiveItem);\n    procedure DeleteAt(Index : Integer);\n    procedure DeleteFiles(const FileMask : string);\n    procedure DeleteFilesEx(const FileMask, ExclusionMask : string);\n    procedure DeleteTaggedItems;\n    procedure Extract(aItem : TAbArchiveItem; const NewName : string);\n    procedure ExtractAt(Index : Integer; const NewName : string);\n    procedure ExtractFiles(const FileMask : string);\n    procedure ExtractFilesEx(const FileMask, ExclusionMask : string);\n    procedure ExtractTaggedItems;\n    procedure ExtractToStream(const aFileName : string; aStream : TStream);\n    function  FindFile(const aFileName : string): Integer;\n    function  FindItem(aItem : TAbArchiveItem): Integer;\n    procedure Freshen(aItem : TAbArchiveItem);\n    procedure FreshenFiles(const FileMask : string);\n    procedure FreshenFilesEx(const FileMask, ExclusionMask : string);\n    procedure FreshenTaggedItems;\n    procedure Load; virtual;\n    procedure Move(aItem : TAbArchiveItem; const NewStoredPath : string);\n      virtual;\n    procedure Replace(aItem : TAbArchiveItem);\n    procedure Save;\n      virtual;\n    procedure TagItems(const FileMask : string);\n    procedure TestTaggedItems;\n    procedure UnTagItems(const FileMask : string);\n\n\n    procedure DoDeflateProgress(aPercentDone : integer);\n      virtual;\n    procedure DoInflateProgress(aPercentDone : integer);\n      virtual;\n    procedure DoSpanningMediaRequest(Sender : TObject; ImageNumber : Integer;\n      var ImageName : string; var Abort : Boolean); virtual;\n  public {properties}\n    property OnProgress : TAbProgressEvent\n      read FOnProgress write FOnProgress;\n    property ArchiveName : string\n      read FArchiveName;\n    property AutoSave : Boolean\n      read FAutoSave\n      write FAutoSave;\n    property BaseDirectory : string\n      read FBaseDirectory\n      write SetBaseDirectory;\n    property Count : Integer\n      read GetItemCount;\n    property DOSMode : Boolean\n      read FDOSMode\n      write FDOSMode;\n    property ExtractOptions : TAbExtractOptions\n      read FExtractOptions\n      write FExtractOptions;\n    property IsDirty : Boolean\n      read FIsDirty\n      write FIsDirty;\n    property ItemList : TAbArchiveList\n      read FItemList;\n    property LogFile : string\n      read FLogFile\n      write SetLogFile;\n    property Logging : Boolean\n      read FLogging\n      write SetLogging;\n    property Mode : Word\n      read FMode;\n    property Spanned : Boolean\n      read FSpanned;\n    property SpanningThreshold : Int64\n      read  GetSpanningThreshold\n      write SetSpanningThreshold;\n    property Status : TAbArchiveStatus\n      read FStatus;\n    property StoreOptions : TAbStoreOptions\n      read FStoreOptions\n      write FStoreOptions;\n    property SupportsEmptyFolders :  Boolean\n      read GetSupportsEmptyFolders;\n    property TempDirectory : string\n      read FTempDir\n      write FTempDir;\n\n  public {events}\n    property OnProcessItemFailure : TAbArchiveItemFailureEvent\n      read FOnProcessItemFailure\n      write FOnProcessItemFailure;\n    property OnArchiveProgress : TAbArchiveProgressEvent\n      read FOnArchiveProgress\n      write FOnArchiveProgress;\n    property OnArchiveSaveProgress : TAbArchiveProgressEvent\n      read FOnArchiveSaveProgress\n      write FOnArchiveSaveProgress;\n    property OnArchiveItemProgress : TAbArchiveItemProgressEvent\n      read FOnArchiveItemProgress\n      write FOnArchiveItemProgress;\n    property OnConfirmProcessItem : TAbArchiveItemConfirmEvent\n      read FOnConfirmProcessItem\n      write FOnConfirmProcessItem;\n    property OnConfirmOverwrite : TAbConfirmOverwriteEvent\n      read FOnConfirmOverwrite\n      write FOnConfirmOverwrite;\n    property OnConfirmSave : TAbArchiveConfirmEvent\n      read FOnConfirmSave\n      write FOnConfirmSave;\n    property OnLoad : TAbArchiveEvent\n      read FOnLoad\n      write FOnLoad;\n    property OnRequestImage : TAbRequestImageEvent\n      read FOnRequestImage\n      write FOnRequestImage;\n    property OnSave : TAbArchiveEvent\n      read FOnSave\n      write FOnSave;\n  end;\n\n\n{ ===== TAbExtraField ======================================================= }\ntype\n  PAbExtraSubField = ^TAbExtraSubField;\n  TAbExtraSubField = packed record\n    ID : Word;\n    Len : Word;\n    Data : record end;\n  end;\n\n  TAbExtraField = class\n  private {fields}\n    FBuffer : TByteDynArray;\n  private {methods}\n    procedure DeleteField(aSubField : PAbExtraSubField);\n    function FindField(aID : Word; out aSubField : PAbExtraSubField) : Boolean;\n    function FindNext(var aCurField : PAbExtraSubField) : Boolean;\n    function GetCount : Integer;\n    function GetID(aIndex : Integer): Word;\n    procedure SetBuffer(const aValue : TByteDynArray);\n  protected {methods}\n    procedure Changed; virtual;\n  public {methods}\n    procedure Assign(aSource : TAbExtraField);\n    procedure Clear;\n    procedure CloneFrom(aSource : TAbExtraField; aID : Word);\n    procedure Delete(aID : Word);\n    function Get(aID : Word; out aData : Pointer; out aDataSize : Word) : Boolean;\n    function GetStream(aID : Word; out aStream : TStream): Boolean;\n    function Has(aID : Word): Boolean;\n    procedure LoadFromStream(aStream : TStream; aSize : Word);\n    procedure Put(aID : Word; const aData; aDataSize : Word);\n  public {properties}\n    property Count : Integer\n      read GetCount;\n    property Buffer : TByteDynArray\n      read FBuffer\n      write SetBuffer;\n    property IDs[aIndex : Integer]: Word\n      read GetID;\n  end;\n\n\nconst\n  AbDefAutoSave = False;\n  AbDefExtractOptions = [eoCreateDirs];\n  AbDefStoreOptions = [soStripDrive, soRemoveDots];\n  AbBufferSize = 32768;\n  AbLastDisk = -1;\n  AbLastImage = -1;\n\nimplementation\n\n{.$R ABRES.R32}\n\nuses\n  RTLConsts,\n  SysUtils,\n  AbExcept,\n  AbDfBase,\n  AbConst,\n  AbResString;\n\n\n{ TAbArchiveItem implementation ============================================ }\n{ TAbArchiveItem }\nconstructor TAbArchiveItem.Create;\nbegin\n  inherited Create;\n  FCompressedSize := 0;\n  FUncompressedSize := 0;\n  FFileName := '';\n  FAction := aaNone;\n  FLastModFileTime := 0;\n  FLastModFileDate := 0;\nend;\n{ -------------------------------------------------------------------------- }\ndestructor TAbArchiveItem.Destroy;\nbegin\n  inherited Destroy;\nend;\n{ -------------------------------------------------------------------------- }\nfunction TAbArchiveItem.GetCompressedSize : Int64;\nbegin\n  Result := FCompressedSize;\nend;\n{ -------------------------------------------------------------------------- }\nfunction TAbArchiveItem.GetCRC32 : LongInt;\nbegin\n  Result := FCRC32;\nend;\n{ -------------------------------------------------------------------------- }\nfunction TAbArchiveItem.GetDiskPath : string;\nbegin\n  Result := ExtractFilePath(DiskFileName);\nend;\n{ -------------------------------------------------------------------------- }\nfunction TAbArchiveItem.GetExternalFileAttributes : LongWord;\nbegin\n  Result := FExternalFileAttributes;\nend;\n{ -------------------------------------------------------------------------- }\nfunction TAbArchiveItem.GetFileName : string;\nbegin\n  Result := FFileName;\nend;\n{ -------------------------------------------------------------------------- }\nfunction TAbArchiveItem.GetIsDirectory: Boolean;\nbegin\n  Result := False;\nend;\n{ -------------------------------------------------------------------------- }\nfunction TAbArchiveItem.GetIsEncrypted : Boolean;\nbegin\n  Result := FIsEncrypted;\nend;\n{ -------------------------------------------------------------------------- }\nfunction TAbArchiveItem.GetLastModFileTime : Word;\nbegin\n  Result := FLastModFileTime;\nend;\n{ -------------------------------------------------------------------------- }\nfunction TAbArchiveItem.GetLastModFileDate : Word;\nbegin\n  Result := FLastModFileDate;\nend;\n{ -------------------------------------------------------------------------- }\nfunction TAbArchiveItem.GetNativeFileAttributes : LongInt;\nbegin\n  {$IFDEF MSWINDOWS}\n  if IsDirectory then\n    Result := faDirectory\n  else\n    Result := 0;\n  {$ENDIF}\n  {$IFDEF UNIX}\n  if IsDirectory then\n    Result := AB_FPERMISSION_GENERIC or AB_FPERMISSION_OWNEREXECUTE\n  else\n    Result := AB_FPERMISSION_GENERIC;\n  {$ENDIF}\nend;\n{ -------------------------------------------------------------------------- }\nfunction TAbArchiveItem.GetStoredPath : string;\nbegin\n  Result := ExtractFilePath(DiskFileName);\nend;\n{ -------------------------------------------------------------------------- }\nfunction TAbArchiveItem.GetUnCompressedSize : Int64;\nbegin\n  Result := FUnCompressedSize;\nend;\n{ -------------------------------------------------------------------------- }\nfunction TAbArchiveItem.MatchesDiskName(const FileMask : string) : Boolean;\nvar\n  DiskName, Mask : string;\nbegin\n  DiskName := DiskFileName;\n  AbUnfixName(DiskName);\n  Mask := FileMask;\n  AbUnfixName(Mask);\n  Result := AbFileMatch(DiskName, Mask);\nend;\n{ -------------------------------------------------------------------------- }\nfunction TAbArchiveItem.MatchesStoredName(const FileMask : string) : Boolean;\nvar\n  Value : string;\n  Drive, Dir, Name : string;\nbegin\n  Value := FileMask;\n  AbUnfixName(Value);\n  AbParseFileName(Value, Drive, Dir, Name);\n  Value := Dir + Name;\n  Name := FileName;\n  AbUnfixName(Name);\n  if IsDirectory then\n    Name := ExcludeTrailingPathDelimiter(Name);\n  Result := AbFileMatch(Name, Value);\nend;\n{ -------------------------------------------------------------------------- }\nfunction TAbArchiveItem.MatchesStoredNameEx(const FileMask : string) : Boolean;\nvar\n  I, J: Integer;\n  MaskPart: string;\nbegin\n  Result := True;\n  I := 1;\n  while I <= Length(FileMask) do begin\n    J := I;\n    while (I <= Length(FileMask)) and (FileMask[I] <> PathSep {';'}) do Inc(I);\n    MaskPart := Trim(Copy(FileMask, J, I - J));\n    if (I <= Length(FileMask)) and (FileMask[I] = PathSep {';'}) then Inc(I);\n\n    if MatchesStoredName(MaskPart) then Exit;\n  end;\n  Result := False;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbArchiveItem.SetCompressedSize(const Value : Int64);\nbegin\n  FCompressedSize := Value;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbArchiveItem.SetCRC32(const Value : LongInt);\nbegin\n  FCRC32 := Value;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbArchiveItem.SetExternalFileAttributes( Value : LongWord );\nbegin\n  FExternalFileAttributes := Value;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbArchiveItem.SetFileName(const Value : string);\nbegin\n  FFileName := Value;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbArchiveItem.SetIsEncrypted(Value : Boolean);\nbegin\n  FIsEncrypted := Value;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbArchiveItem.SetLastModFileDate(const Value : Word);\nbegin\n  FLastModFileDate := Value;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbArchiveItem.SetLastModFileTime(const Value : Word);\nbegin\n  FLastModFileTime := Value;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbArchiveItem.SetUnCompressedSize(const Value : Int64);\nbegin\n  FUnCompressedSize := Value;\nend;\n{ -------------------------------------------------------------------------- }\nfunction TAbArchiveItem.GetLastModTimeAsDateTime: TDateTime;\nbegin\n  Result := AbDosFileDateToDateTime(LastModFileDate, LastModFileTime);\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbArchiveItem.SetLastModTimeAsDateTime(const Value: TDateTime);\nvar\n  FileDate : Integer;\nbegin\n  FileDate := AbDateTimeToDosFileDate(Value);\n  LastModFileTime := LongRec(FileDate).Lo;\n  LastModFileDate := LongRec(FileDate).Hi;\nend;\n{ -------------------------------------------------------------------------- }\n\n{ TAbArchiveEnumeratorList implementation ================================== }\n{ TAbArchiveEnumeratorList }\nconstructor TAbArchiveListEnumerator.Create(aList: TAbArchiveList);\nbegin\n  inherited Create;\n  FIndex := -1;\n  FList := aList;\nend;\n{ -------------------------------------------------------------------------- }\nfunction TAbArchiveListEnumerator.GetCurrent: TAbArchiveItem;\nbegin\n  Result := FList[FIndex];\nend;\n{ -------------------------------------------------------------------------- }\nfunction TAbArchiveListEnumerator.MoveNext: Boolean;\nbegin\n  Result := FIndex < FList.Count - 1;\n  if Result then\n    Inc(FIndex);\nend;\n{ -------------------------------------------------------------------------- }\n\n{ TAbArchiveList implementation ============================================ }\n\n{ TAbArchiveList }\nconstructor TAbArchiveList.Create(AOwnsItems: Boolean);\nbegin\n  inherited Create;\n  FList := TList.Create;\n  FOwnsItems := AOwnsItems;\nend;\n{ -------------------------------------------------------------------------- }\ndestructor TAbArchiveList.Destroy;\nbegin\n  Clear;\n  FList.Free;\n  inherited Destroy;\nend;\n{ -------------------------------------------------------------------------- }\nfunction TAbArchiveList.Add(aItem : TAbArchiveItem) : Integer;\nvar\n  H : LongInt;\nbegin\n  if FOwnsItems then begin\n    H := GenerateHash(aItem.FileName);\n    aItem.NextItem := HashTable[H];\n    HashTable[H] := aItem;\n  end;\n  Result := FList.Add(aItem);\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbArchiveList.Clear;\nvar\n  i : Integer;\nbegin\n  if FOwnsItems then\n    for i := 0 to Count - 1 do\n      TObject(FList[i]).Free;\n  FList.Clear;\n  FillChar(HashTable, SizeOf(HashTable), #0);\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbArchiveList.Delete(Index: Integer);\nvar\n  Look : TAbArchiveItem;\n  Last : ^TAbArchiveItem;\n  FN : string;\nbegin\n  if FOwnsItems then begin\n    FN := TAbArchiveItem(FList[Index]).FileName;\n    Last := @HashTable[GenerateHash(FN)];\n    Look := Last^;\n    while Look <> nil do begin\n      if CompareText(Look.FileName, FN) = 0 then begin\n        Last^ := Look.NextItem;\n        Break;\n      end;\n      Last := @Look.NextItem;\n      Look := Last^;\n    end;\n    TObject(FList[Index]).Free;\n  end;\n  FList.Delete(Index);\nend;\n{ -------------------------------------------------------------------------- }\nfunction TAbArchiveList.Find(const FN : string) : Integer;\nvar\n  Look : TAbArchiveItem;\n  I : Integer;\nbegin\n  if FOwnsItems then begin\n    Look := HashTable[GenerateHash(FN)];\n    while Look <> nil do begin\n      if CompareText(Look.FileName, FN) = 0 then begin\n        Result := FList.IndexOf(Look);\n        Exit;\n      end;\n      Look := Look.NextItem;\n    end;\n  end\n  else begin\n    for I := 0 to FList.Count - 1 do\n      if CompareText(Items[I].FileName, FN) = 0 then begin\n        Result := I;\n        Exit;\n      end;\n  end;\n  Result := -1;\nend;\n{ -------------------------------------------------------------------------- }\n{$IFOPT Q+}{$DEFINE OVERFLOW_CHECKS_ON}{$Q-}{$ENDIF}\nfunction TAbArchiveList.GenerateHash(const S : string) : LongInt;\nvar\n  G : LongInt;\n  I : Integer;\n  U : string;\nbegin\n  Result := 0;\n  U := AnsiUpperCase(S);\n  for I := 1 to Length(U) do begin\n    Result := (Result shl 4) + Ord(U[I]);\n    G := LongInt(Result and $F0000000);\n    if (G <> 0) then\n      Result := Result xor (G shr 24);\n    Result := Result and (not G);\n  end;\n  Result := Result mod 1021;\nend;\n{$IFDEF OVERFLOW_CHECKS_ON}{$Q+}{$ENDIF}\n{ -------------------------------------------------------------------------- }\nfunction TAbArchiveList.Get(Index : Integer): TAbArchiveItem;\nbegin\n  Result := TAbArchiveItem(FList[Index]);\nend;\n{ -------------------------------------------------------------------------- }\nfunction TAbArchiveList.GetCount : Integer;\nbegin\n  Result := FList.Count;\nend;\n{ -------------------------------------------------------------------------- }\nfunction TAbArchiveList.GetEnumerator: TAbArchiveListEnumerator;\nbegin\n  Result := TAbArchiveListEnumerator.Create(Self);\nend;\n{ -------------------------------------------------------------------------- }\nfunction TAbArchiveList.IsActiveDupe(const FN : string) : Boolean;\nvar\n  Look : TAbArchiveItem;\n  I : Integer;\nbegin\n  if FOwnsItems then begin\n    Look := HashTable[GenerateHash(FN)];\n    while Look <> nil do begin\n      if (CompareText(Look.FileName, FN) = 0) and\n         (Look.Action <> aaDelete) then begin\n        Result := True;\n        Exit;\n      end;\n      Look := Look.NextItem;\n    end;\n  end\n  else begin\n    for I := 0 to Count - 1 do\n      if (CompareText(Items[I].FileName, FN) = 0) and\n         (Items[I].Action <> aaDelete) then begin\n        Result := True;\n        Exit;\n      end;\n  end;\n  Result := False;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbArchiveList.Put(Index : Integer; Item : TAbArchiveItem);\nvar\n  H : LongInt;\n  Look : TAbArchiveItem;\n  Last : ^TAbArchiveItem;\n  FN : string;\nbegin\n  if FOwnsItems then begin\n    FN := TAbArchiveItem(FList[Index]).FileName;\n    Last := @HashTable[GenerateHash(FN)];\n    Look := Last^;\n    { Delete old index }\n    while Look <> nil do begin\n      if CompareText(Look.FileName, FN) = 0 then begin\n        Last^ := Look.NextItem;\n        Break;\n      end;\n      Last := @Look.NextItem;\n      Look := Last^;\n    end;\n    { Free old instance }\n    TObject(FList[Index]).Free;\n    { Add new index }\n    H := GenerateHash(Item.FileName);\n    Item.NextItem := HashTable[H];\n    HashTable[H] := Item;\n  end;\n  { Replace pointer }\n  FList[Index] := Item;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbArchiveList.UpdateHash(aItem: TAbArchiveItem;\n  const aOldFileName: string);\nvar\n  H : LongInt;\n  Last : ^TAbArchiveItem;\n  Look : TAbArchiveItem;\nbegin\n  if FOwnsItems then begin\n    { Remove from old hash position }\n    Last := @HashTable[GenerateHash(aOldFileName)];\n    Look := Last^;\n    while Look <> nil do begin\n      if Look = aItem then begin\n        Last^ := Look.NextItem;\n        Break\n      end;\n      Last := @Look.NextItem;\n      Look := Last^\n    end;\n    { Add to new hash position }\n    H := GenerateHash(aItem.FileName);\n    aItem.NextItem := HashTable[H];\n    HashTable[H] := aItem\n  end;\nend;\n\n\n{ TAbArchive implementation ================================================ }\n{ TAbArchive }\nconstructor TAbArchive.CreateInit;\nbegin\n  inherited Create;\n  FIsDirty := False;\n  FAutoSave := False;\n  FItemList := TAbArchiveList.Create(True);\n  StoreOptions := [];\n  ExtractOptions := [];\n  FStatus := asIdle;\n  FOnProgress := DoProgress;\n  BaseDirectory := ExtractFilePath(ParamStr(0));\nend;\n{ -------------------------------------------------------------------------- }\nconstructor TAbArchive.Create(const FileName : string; Mode : Word);\n  {create an archive by opening a filestream on filename with the given mode}\nbegin\n  FOwnsStream := True;\n  CreateFromStream(TFileStream.Create(FileName, Mode), FileName);\n  FMode := Mode;\nend;\n{ -------------------------------------------------------------------------- }\nconstructor TAbArchive.CreateFromStream(aStream : TStream; const aArchiveName : string);\n  {create an archive based on an existing stream}\nbegin\n  CreateInit;\n  FArchiveName := aArchiveName;\n  FStream := aStream;\nend;\n{ -------------------------------------------------------------------------- }\ndestructor TAbArchive.Destroy;\nbegin\n  FItemList.Free;\n  if FOwnsStream then\n    FStream.Free;\n  FLogStream.Free;\n  inherited Destroy;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbArchive.Add(aItem : TAbArchiveItem);\nvar\n  Confirm, ItemAdded : Boolean;\nbegin\n  ItemAdded := False;\n  try\n    CheckValid;\n    if FItemList.IsActiveDupe(aItem.FileName) then begin\n      if (soFreshen in StoreOptions) then\n        Freshen(aItem)\n      else if (soReplace in StoreOptions) then\n        Replace(aItem)\n      else\n        DoProcessItemFailure(aItem, ptAdd, ecAbbrevia, AbDuplicateName);\n      Exit;\n    end;\n    DoConfirmProcessItem(aItem, ptAdd, Confirm);\n    if not Confirm then\n      Exit;\n    aItem.Action := aaAdd;\n    FItemList.Add(aItem);\n    ItemAdded := True;\n    FIsDirty := True;\n    if AutoSave then\n      Save;\n  finally\n    if not ItemAdded then\n      aItem.Free;\n  end;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbArchive.AddFiles(const FileMask : string; SearchAttr : Integer);\n  {Add files to the archive where the disk filespec matches}\nbegin\n  AddFilesEx(FileMask, '', SearchAttr);\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbArchive.AddFilesEx(const FileMask, ExclusionMask : string;\n  SearchAttr : Integer);\n  {Add files matching Filemask except those matching ExclusionMask}\nvar\n  PathType : TAbPathType;\n  IsWild : Boolean;\n  SaveDir : string;\n  Mask : string;\n  MaskF : string;\n\n  procedure CreateItems(Wild, Recursing : Boolean);\n  var\n    i : Integer;\n    Files : TStrings;\n    FilterList : TStringList;\n    Item : TAbArchiveItem;\n  begin\n    FilterList := TStringList.Create;\n    try\n      if (MaskF <> '') then\n        AbFindFilesEx(MaskF, SearchAttr, FilterList, Recursing);\n\n        Files := TStringList.Create;\n        try\n\n          AbFindFilesEx(Mask, SearchAttr, Files, Recursing);\n          if (Files.Count > 0) then\n            for i := 0 to pred(Files.Count) do\n              if FilterList.IndexOf(Files[i]) < 0 then\n                if not Wild then begin\n                  if (Files[i] <> FArchiveName) then begin\n                    Item := CreateItem(Files[i]);\n                    Add(Item);\n                  end;\n                end else begin\n                  if (AbAddBackSlash(FBaseDirectory) + Files[i]) <> FArchiveName\n                    then begin\n                      Item := CreateItem(Files[i]);\n                      Add(Item);\n                    end;\n                end;\n        finally\n          Files.Free;\n        end;\n\n    finally\n      FilterList.Free;\n    end;\n  end;\n\nbegin\n   if not SupportsEmptyFolders then\n    SearchAttr := SearchAttr and not faDirectory;\n\n  CheckValid;\n  IsWild := (Pos('*', FileMask) > 0) or (Pos('?', FileMask) > 0);\n  PathType := AbGetPathType(FileMask);\n\n  Mask := FileMask;\n  AbUnfixName(Mask);\n  MaskF := ExclusionMask;\n  AbUnfixName(MaskF);\n\n  case PathType of\n    ptNone, ptRelative :\n      begin\n        GetDir(0, SaveDir);\n        if BaseDirectory <> '' then\n          ChDir(BaseDirectory);\n        try\n          CreateItems(IsWild, soRecurse in StoreOptions);\n        finally\n          if BaseDirectory <> '' then\n            ChDir(SaveDir);\n        end;\n      end;\n    ptAbsolute :\n      begin\n        CreateItems(IsWild, soRecurse in StoreOptions);\n      end;\n  end;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbArchive.AddFromStream(const NewName : string; aStream : TStream);\n  {Add an item to the archive directly from a TStream descendant}\nvar\n  Confirm : Boolean;\n  Item : TAbArchiveItem;\n  PT : TAbProcessType;                                               \nbegin\n  Item := CreateItem(NewName);\n  CheckValid;\n\n  PT := ptAdd;\n  if FItemList.IsActiveDupe(NewName) then begin\n    if ((soFreshen in StoreOptions) or (soReplace in StoreOptions)) then begin\n      Item.Free;\n      Item := FItemList[FItemList.Find(NewName)];\n      PT := ptReplace;\n    end else begin\n      DoProcessItemFailure(Item, ptAdd, ecAbbrevia, AbDuplicateName);\n      Item.Free;\n      Exit;\n    end;\n  end;\n  DoConfirmProcessItem(Item, PT, Confirm);\n\n  if not Confirm then\n    Exit;\n\n  FInStream := aStream;\n  Item.Action := aaStreamAdd;\n  if (PT = ptAdd) then\n    FItemList.Add(Item);\n  FIsDirty := True;\n  Save;\n  FInStream := nil;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbArchive.CheckValid;\nbegin\n  if Status = asInvalid then\n    raise EAbNoArchive.Create;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbArchive.ClearTags;\n  {Clear all tags from the archive}\nvar\n  i : Integer;\nbegin\n  if Count > 0 then\n    for i := 0 to pred(Count) do\n      TAbArchiveItem(FItemList[i]).Tagged := False;\nend;\n{ -------------------------------------------------------------------------- }\nfunction TAbArchive.ConfirmPath(Item : TAbArchiveItem; const NewName : string;\n  out UseName : string) : Boolean;\nvar\n  Path : string;\nbegin\n  if Item.IsDirectory and not (ExtractOptions >= [eoRestorePath, eoCreateDirs]) then begin\n    Result := False;\n    Exit;\n  end;\n  if (NewName = '') then begin\n    UseName := Item.FileName;\n    AbUnfixName(UseName);\n    if Item.IsDirectory then\n      UseName := ExcludeTrailingPathDelimiter(UseName);\n    if (not (eoRestorePath in ExtractOptions)) then\n      UseName := ExtractFileName(UseName);\n  end\n  else\n    UseName := NewName;\n  if (AbGetPathType(UseName) <> ptAbsolute) then\n    UseName := AbAddBackSlash(BaseDirectory) + UseName;\n\n  Path := ExtractFileDir(UseName);\n  if (Path <> '') and not DirectoryExists(Path) then\n    if (eoCreateDirs in ExtractOptions) then\n      AbCreateDirectory(Path)\n    else\n      raise EAbNoSuchDirectory.Create;\n\n  Result := True;\n  if not Item.IsDirectory and FileExists(UseName) then\n    DoConfirmOverwrite(UseName, Result);\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbArchive.Delete(aItem : TAbArchiveItem);\n  {delete an item from the archive}\nvar\n  Index : Integer;\nbegin\n  CheckValid;\n  Index := FindItem(aItem);\n  if Index <> -1 then\n    DeleteAt(Index);\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbArchive.DeleteAt(Index : Integer);\n  {delete the item at the index from the archive}\nvar\n  Confirm : Boolean;\nbegin\n  CheckValid;\n  SaveIfNeeded(FItemList[Index]);\n  DoConfirmProcessItem(FItemList[Index], ptDelete, Confirm);\n  if not Confirm then\n    Exit;\n\n  TAbArchiveItem(FItemList[Index]).Action := aaDelete;\n  FIsDirty := True;\n  if AutoSave then\n    Save;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbArchive.DeleteFiles(const FileMask : string);\n  {delete all files from the archive that match the file mask}\nbegin\n  DeleteFilesEx(FileMask, '');\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbArchive.DeleteFilesEx(const FileMask, ExclusionMask : string);\n  {Delete files matching Filemask except those matching ExclusionMask}\nvar\n  i : Integer;\nbegin\n  CheckValid;\n  if Count > 0 then begin\n    for i := pred(Count) downto 0 do begin\n      with TAbArchiveItem(FItemList[i]) do\n        if MatchesStoredNameEx(FileMask) then\n          if not MatchesStoredNameEx(ExclusionMask) then\n            DeleteAt(i);\n    end;\n  end;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbArchive.DeleteTaggedItems;\n  {delete all tagged items from the archive}\nvar\n  i : Integer;\nbegin\n  CheckValid;\n  if Count > 0 then begin\n    for i := pred(Count) downto 0 do begin\n      with TAbArchiveItem(FItemList[i]) do\n        if Tagged then\n          DeleteAt(i);\n    end;\n  end;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbArchive.DoProcessItemFailure(Item : TAbArchiveItem;\n  ProcessType : TAbProcessType; ErrorClass : TAbErrorClass;\n  ErrorCode : Integer);\nbegin\n  if Assigned(FOnProcessItemFailure) then\n    FOnProcessItemFailure(Self, Item, ProcessType, ErrorClass, ErrorCode);\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbArchive.DoArchiveSaveProgress(Progress : Byte; var Abort : Boolean);\nbegin\n  Abort := False;\n  if Assigned(FOnArchiveSaveProgress) then\n    FOnArchiveSaveProgress(Self, Progress, Abort);\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbArchive.DoArchiveProgress(Progress : Byte; var Abort : Boolean);\nbegin\n  Abort := False;\n  if Assigned(FOnArchiveProgress) then\n    FOnArchiveProgress(Self, Progress, Abort);\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbArchive.DoArchiveItemProgress(Item : TAbArchiveItem;\n  Progress : Byte; var Abort : Boolean);\nbegin\n  Abort := False;\n  if Assigned(FOnArchiveItemProgress) then\n    FOnArchiveItemProgress(Self, Item, Progress, Abort);\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbArchive.DoConfirmOverwrite(var FileName : string; var Confirm : Boolean);\nbegin\n  Confirm := True;\n  if Assigned(FOnConfirmOverwrite) then\n    FOnConfirmOverwrite(FileName, Confirm);\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbArchive.DoConfirmProcessItem(Item : TAbArchiveItem;\n  const ProcessType : TAbProcessType; var Confirm : Boolean);\nconst\n  ProcessTypeToLogType : array[TAbProcessType] of TAbLogType =\n    (ltAdd, ltDelete, ltExtract, ltFreshen, ltMove, ltReplace, ltFoundUnhandled);\nbegin\n  Confirm := True;\n  if Assigned(FOnConfirmProcessItem) then\n    FOnConfirmProcessItem(Self, Item, ProcessType, Confirm);\n  if (Confirm and FLogging) then\n    MakeLogEntry(Item.Filename, ProcessTypeToLogType[ProcessType]);\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbArchive.DoConfirmSave(var Confirm : Boolean);\nbegin\n  Confirm := True;\n  if Assigned(FOnConfirmSave) then\n    FOnConfirmSave(Self, Confirm);\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbArchive.DoDeflateProgress(aPercentDone: integer);\nvar\n  Abort : Boolean;\nbegin\n  DoProgress(aPercentDone, Abort);\n  if Abort then\n    raise EAbAbortProgress.Create(AbUserAbortS);\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbArchive.DoInflateProgress(aPercentDone: integer);\nvar\n  Abort : Boolean;\nbegin\n  DoProgress(aPercentDone, Abort);\n  if Abort then\n    raise EAbAbortProgress.Create(AbUserAbortS);\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbArchive.DoLoad;\nbegin\n  if Assigned(FOnLoad) then\n    FOnLoad(Self);\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbArchive.DoProgress(Progress : Byte; var Abort : Boolean);\nbegin\n  Abort := False;                                                      \n  DoArchiveItemProgress(FCurrentItem, Progress, Abort);\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbArchive.DoSave;\nbegin\n  if Assigned(FOnSave) then\n    FOnSave(Self);\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbArchive.Extract(aItem : TAbArchiveItem; const NewName : string);\n  {extract an item from the archive}\nvar\n  Index : Integer;\nbegin\n  CheckValid;\n  Index := FindItem(aItem);\n  if Index <> -1 then\n    ExtractAt(Index, NewName);\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbArchive.ExtractAt(Index : Integer; const NewName : string);\n  {extract an item from the archive at Index}\nvar\n  Confirm : Boolean;\n  ErrorClass : TAbErrorClass;\n  ErrorCode : Integer;\n  UseName : string;\nbegin\n  CheckValid;\n  SaveIfNeeded(FItemList[Index]);\n  DoConfirmProcessItem(FItemList[Index], ptExtract, Confirm);\n  if not Confirm then\n    Exit;\n\n  if not ConfirmPath(FItemList[Index], NewName, UseName) then\n    Exit;\n\n  try\n    FCurrentItem := FItemList[Index];\n    ExtractItemAt(Index, UseName);\n  except\n    on E : Exception do begin\n      AbConvertException(E, ErrorClass, ErrorCode);\n      DoProcessItemFailure(FItemList[Index], ptExtract, ErrorClass, ErrorCode);\n    end;\n  end;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbArchive.ExtractToStream(const aFileName : string;\n                                     aStream : TStream);\n  {extract an item from the archive at Index directly to a stream}\nvar\n  Confirm : Boolean;\n  ErrorClass : TAbErrorClass;\n  ErrorCode : Integer;\n  Index : Integer;\nbegin\n  CheckValid;\n  Index := FindFile(aFileName);\n  if (Index = -1) then\n    Exit;\n\n  SaveIfNeeded(FItemList[Index]);\n\n  DoConfirmProcessItem(FItemList[Index], ptExtract, Confirm);\n  if not Confirm then\n    Exit;\n  FCurrentItem := FItemList[Index];\n  try\n    ExtractItemToStreamAt(Index, aStream);\n  except\n    on E : Exception do begin\n      AbConvertException(E, ErrorClass, ErrorCode);\n      DoProcessItemFailure(FItemList[Index], ptExtract, ErrorClass, ErrorCode);\n    end;\n  end;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbArchive.ExtractFiles(const FileMask : string);\n  {extract all files from the archive that match the mask}\nbegin\n  ExtractFilesEx(FileMask, '');\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbArchive.ExtractFilesEx(const FileMask, ExclusionMask : string);\n  {Extract files matching Filemask except those matching ExclusionMask}\nvar\n  i : Integer;\n  Abort : Boolean;\nbegin\n  CheckValid;\n  if Count > 0 then begin\n    for i := 0 to pred(Count) do begin\n      with TAbArchiveItem(FItemList[i]) do\n        if MatchesStoredNameEx(FileMask) and\n           not MatchesStoredNameEx(ExclusionMask) and\n           ((eoCreateDirs in ExtractOptions) or not IsDirectory) then\n          ExtractAt(i, '');\n      DoArchiveProgress(AbPercentage(succ(i), Count), Abort);\n      if Abort then\n        raise EAbUserAbort.Create;\n    end;\n    DoArchiveProgress(100, Abort);\n  end;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbArchive.ExtractTaggedItems;\n  {extract all tagged items from the archive}\nvar\n  i : Integer;\n  Abort : Boolean;\nbegin\n  CheckValid;\n  if Count > 0 then begin\n    for i := 0 to pred(Count) do begin\n      with TAbArchiveItem(FItemList[i]) do\n        if Tagged then\n          ExtractAt(i, '');\n      DoArchiveProgress(AbPercentage(succ(i), Count), Abort);\n      if Abort then\n        raise EAbUserAbort.Create;\n    end;\n    DoArchiveProgress(100, Abort);\n  end;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbArchive.TestTaggedItems;\n  {test all tagged items in the archive}\nvar\n  i : Integer;\n  Abort : Boolean;\nbegin\n  CheckValid;\n  if Count > 0 then begin\n    for i := 0 to pred(Count) do begin\n      with TAbArchiveItem(FItemList[i]) do\n        if Tagged then begin\n          FCurrentItem := FItemList[i];\n          TestItemAt(i);\n        end;\n      DoArchiveProgress(AbPercentage(succ(i), Count), Abort);\n      if Abort then\n        raise EAbUserAbort.Create;\n    end;\n    DoArchiveProgress(100, Abort);\n  end;\nend;\n{ -------------------------------------------------------------------------- }\nfunction TAbArchive.FindFile(const aFileName : string): Integer;\n  {find the index of the specified file}\nbegin\n  Result := FItemList.Find(aFileName);\nend;\n{ -------------------------------------------------------------------------- }\nfunction TAbArchive.FindItem(aItem : TAbArchiveItem): Integer;\n  {find the index of the specified item}\nbegin\n  Result := FItemList.Find(aItem.FileName);\nend;\n{ -------------------------------------------------------------------------- }\nfunction TAbArchive.FixName(const Value : string) : string;\nvar\n  lValue: string;\nbegin\n  lValue := Value;\n  {$IFDEF MSWINDOWS}\n  if DOSMode then begin\n    {Add the base directory to the filename before converting }\n    {the file spec to the short filespec format. }\n    if BaseDirectory <> '' then begin\n      {Does the filename contain a drive or a leading backslash? }\n      if not ((Pos(':', lValue) = 2) or (Pos(AbPathDelim, lValue) = 1)) then\n        {If not, add the BaseDirectory to the filename.}\n        lValue := AbAddBackSlash(BaseDirectory) + lValue;\n    end;\n    lValue := AbGetShortFileSpec(lValue);\n  end;\n  {$ENDIF}\n\n  {strip drive stuff}\n  if soStripDrive in StoreOptions then\n    AbStripDrive(lValue);\n\n  {check for a leading backslash}\n  if lValue[1] = AbPathDelim then\n    System.Delete(lValue, 1, 1);\n\n  if soStripPath in StoreOptions then begin\n    lValue := ExtractFileName(lValue);\n  end;\n\n  if soRemoveDots in StoreOptions then\n    AbStripDots(lValue);\n\n  Result := lValue;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbArchive.Freshen(aItem : TAbArchiveItem);\n  {freshen the item}\nvar\n  Index : Integer;\nbegin\n  CheckValid;\n  Index := FindItem(aItem);\n  if Index <> -1 then begin\n    {point existing item at the new file}\n    if AbGetPathType(aItem.DiskFileName) = ptAbsolute then\n      FItemList[Index].DiskFileName := aItem.DiskFileName;\n    FreshenAt(Index);\n  end;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbArchive.FreshenAt(Index : Integer);\n  {freshen item at index}\nvar\n  Confirm : Boolean;\n  FR : Boolean;\n  ErrorClass : TAbErrorClass;\n  ErrorCode : Integer;\nbegin\n  CheckValid;\n  SaveIfNeeded(FItemList[Index]);\n\n  GetFreshenTarget(FItemList[Index]);\n  FR := False;\n  try\n    FR := FreshenRequired(FItemList[Index]);\n  except\n    on E : Exception do begin\n      AbConvertException(E, ErrorClass, ErrorCode);\n      DoProcessItemFailure(FItemList[Index], ptFreshen, ErrorClass, ErrorCode);\n    end;\n  end;\n  if not FR then\n    Exit;\n  DoConfirmProcessItem(FItemList[Index], ptFreshen, Confirm);\n  if not Confirm then\n    Exit;\n\n  TAbArchiveItem(FItemList[Index]).Action := aaFreshen;\n  FIsDirty := True;\n  if AutoSave then\n    Save;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbArchive.FreshenFiles(const FileMask : string);\n  {freshen all items that match the file mask}\nbegin\n  FreshenFilesEx(FileMask, '');\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbArchive.FreshenFilesEx(const FileMask, ExclusionMask : string);\n  {freshen all items that match the file mask}\nvar\n  i : Integer;\nbegin\n  CheckValid;\n  if Count > 0 then begin\n    for i := pred(Count) downto 0 do begin\n      with TAbArchiveItem(FItemList[i]) do\n        if MatchesStoredNameEx(FileMask) then\n          if not MatchesStoredNameEx(ExclusionMask) then\n            FreshenAt(i);\n    end;\n  end;\nend;\n{ -------------------------------------------------------------------------- }\nfunction TAbArchive.FreshenRequired(Item : TAbArchiveItem) : Boolean;\nvar\n  FS : TFileStream;\n  DateTime : LongInt;\n  FileTime : Word;\n  FileDate : Word;\n  Matched : Boolean;\n  SaveDir : string;\nbegin\n  GetDir(0, SaveDir);\n  if BaseDirectory <> '' then\n    ChDir(BaseDirectory);\n  try\n    FS := TFileStream.Create(Item.DiskFileName,\n                              fmOpenRead or fmShareDenyWrite);\n    try\n      DateTime := FileGetDate(FS.Handle);\n      FileTime := LongRec(DateTime).Lo;\n      FileDate := LongRec(DateTime).Hi;\n      Matched := (Item.LastModFileDate = FileDate) and\n                 (Item.LastModFileTime = FileTime) and\n                 (Item.UncompressedSize = FS.Size);\n      Result := not Matched;\n    finally\n      FS.Free;\n    end;\n  finally\n    if BaseDirectory <> '' then\n      ChDir(SaveDir);\n  end;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbArchive.FreshenTaggedItems;\n  {freshen all tagged items}\nvar\n  i : Integer;\nbegin\n  CheckValid;\n  if Count > 0 then begin\n    for i := pred(Count) downto 0 do begin\n      with TAbArchiveItem(FItemList[i]) do\n        if Tagged then\n          FreshenAt(i);\n    end;\n  end;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbArchive.GetFreshenTarget(Item : TAbArchiveItem);\nvar\n  PathType : TAbPathType;\n  Files : TStrings;\n  SaveDir : string;\n  DName : string;\nbegin\n  PathType := AbGetPathType(Item.DiskFileName);\n  if (soRecurse in StoreOptions) and (PathType = ptNone) then begin\n    GetDir(0, SaveDir);\n    if BaseDirectory <> '' then\n      ChDir(BaseDirectory);\n    try\n      Files := TStringList.Create;\n      try\n        // even if archive supports empty folder we don't have to\n        // freshen it because there is no data, although, the timestamp\n        // can be update since the folder was added\n        AbFindFiles(Item.FileName, faAnyFile and not faDirectory, Files,\n                     True);\n        if Files.Count > 0 then begin\n          DName := AbAddBackSlash(BaseDirectory) + Files[0];\n          AbUnfixName(DName);\n          Item.DiskFileName := DName;\n        end\n        else\n          Item.DiskFileName := '';\n      finally\n        Files.Free;\n      end;\n    finally\n      if BaseDirectory <> '' then\n        ChDir(SaveDir);\n    end;\n  end\n  else begin\n    if (BaseDirectory <> '') then\n      DName := AbAddBackSlash(BaseDirectory) + Item.FileName\n    else\n      if AbGetPathType(Item.DiskFileName) = ptAbsolute then\n        DName := Item.DiskFileName\n      else\n        DName := Item.FileName;\n    AbUnfixName(DName);\n    Item.DiskFileName := DName;\n  end;\nend;\n{ -------------------------------------------------------------------------- }\nfunction TAbArchive.GetSpanningThreshold : Int64;\nbegin\n  Result := FSpanningThreshold;\nend;\n{ -------------------------------------------------------------------------- }\nfunction TAbArchive.GetSupportsEmptyFolders : Boolean;\nbegin\n  Result := False;\nend;\n{ -------------------------------------------------------------------------- }\nfunction TAbArchive.GetItemCount : Integer;\nbegin\n  if Assigned(FItemList) then\n    Result := FItemList.Count\n  else\n    Result := 0;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbArchive.Load;\n  {load the archive}\nbegin\n  try\n    LoadArchive;\n    FStatus := asIdle;\n  finally\n    DoLoad;\n  end;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbArchive.MakeLogEntry(const FN: string; LT : TAbLogType);\nconst\n  LogTypeRes : array[TAbLogType] of string =\n    (AbLtAddS, AbLtDeleteS, AbLtExtractS, AbLtFreshenS, AbLtMoveS, AbLtReplaceS,\n     AbLtStartS, AbUnhandledEntityS);\nvar\n  Buf : string;\nbegin\n  if Assigned(FLogStream) then begin\n    Buf := FN + LogTypeRes[LT] + DateTimeToStr(Now) + sLineBreak;\n    FLogStream.Write(Buf[1], Length(Buf) * SizeOf(Char));\n  end;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbArchive.Move(aItem : TAbArchiveItem; const NewStoredPath : string);\nvar\n  Confirm : Boolean;\n  Found : Boolean;\n  i : Integer;\n  FixedPath, OldFileName: string;\nbegin\n  CheckValid;\n  FixedPath := FixName(NewStoredPath);\n  Found := False;\n  if Count > 0 then\n    for i := 0 to pred(Count) do\n      if (ItemList[i] <> aItem) and SameText(FixedPath, ItemList[i].FileName) and\n         (ItemList[i].Action <> aaDelete) then begin\n        Found := True;\n        Break;\n      end;\n  if Found then begin\n    DoProcessItemFailure(aItem, ptMove, ecAbbrevia, AbDuplicateName);\n    {even if something gets done in the AddItemFailure, we don't\n     want to continue...}\n    Exit;\n  end;\n\n  SaveIfNeeded(aItem);\n\n  DoConfirmProcessItem(aItem, ptMove, Confirm);\n  if not Confirm then\n    Exit;\n\n  OldFileName := aItem.FileName;\n  aItem.FileName := FixedPath;\n  aItem.Action := aaMove;\n  ItemList.UpdateHash(aItem, OldFileName);\n\n  FIsDirty := True;\n  if AutoSave then\n    Save;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbArchive.Replace(aItem : TAbArchiveItem);\n  {replace the item}\nvar\n  Index : Integer;\nbegin\n  CheckValid;\n  Index := FindItem(aItem);\n  if Index <> -1 then begin\n    {point existing item at the new file}\n    if AbGetPathType(aItem.DiskFileName) = ptAbsolute then\n      FItemList[Index].DiskFileName := aItem.DiskFileName;\n    ReplaceAt(Index);\n  end;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbArchive.ReplaceAt(Index : Integer);\n  {replace item at Index}\nvar\n  Confirm : Boolean;\nbegin\n  CheckValid;\n  SaveIfNeeded(FItemList[Index]);\n\n  GetFreshenTarget(FItemList[Index]);\n  DoConfirmProcessItem(FItemList[Index], ptReplace, Confirm);\n  if not Confirm then\n    Exit;\n\n  TAbArchiveItem(FItemList[Index]).Action := aaReplace;\n  FIsDirty := True;\n  if AutoSave then\n    Save;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbArchive.Save;\n  {save the archive}\nvar\n  Confirm : Boolean;\nbegin\n  if Status = asInvalid then\n    Exit;\n  if (not FIsDirty) and (Count > 0) then\n    Exit;\n\n  DoConfirmSave(Confirm);\n  if not Confirm then\n    Exit;\n\n  SaveArchive;\n  FIsDirty := False;\n  DoSave;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbArchive.SaveIfNeeded(aItem : TAbArchiveItem);\nbegin\n  if (aItem.Action <> aaNone) then\n    Save;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbArchive.SetBaseDirectory(Value : string);\nbegin\n  if (Value <> '') then\n    if Value[Length(Value)] = AbPathDelim then\n      if (Length(Value) > 1) and (Value[Length(Value) - 1] <> ':') then\n        System.Delete(Value, Length(Value), 1);\n  if (Length(Value) = 0) or DirectoryExists(Value) then\n    FBaseDirectory := Value\n  else\n    raise EAbNoSuchDirectory.Create;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbArchive.SetSpanningThreshold( Value : Int64 );\nbegin\n  FSpanningThreshold := Value;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbArchive.SetLogFile(const Value : string);\nbegin\n  FLogFile := Value;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbArchive.SetLogging(Value : Boolean);\nbegin\n  FLogging := Value;\n  if Assigned(FLogStream) then begin\n    FLogStream.Free;\n    FLogStream := nil;\n  end;\n  if FLogging and (FLogFile <> '') then begin\n    try\n      FLogStream := TFileStream.Create(FLogFile, fmCreate or fmOpenWrite);\n      MakeLogEntry(FArchiveName, ltStart);\n    except\n      raise EAbException.Create(AbLogCreateErrorS);\n    end;\n  end;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbArchive.TagItems(const FileMask : string);\n  {tag all items that match the mask}\nvar\n  i : Integer;\nbegin\n  if Count > 0 then\n    for i := 0 to pred(Count) do\n      with TAbArchiveItem(FItemList[i]) do begin\n        if MatchesStoredNameEx(FileMask) then                            \n          Tagged := True;\n      end;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbArchive.UnTagItems(const FileMask : string);\n  {clear tags for all items that match the mask}\nvar\n  i : Integer;\nbegin\n  if Count > 0 then\n    for i := 0 to pred(Count) do\n      with TAbArchiveItem(FItemList[i]) do begin\n        if MatchesStoredNameEx(FileMask) then\n          Tagged := False;\n      end;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbArchive.DoSpanningMediaRequest(Sender: TObject;\n  ImageNumber: Integer; var ImageName: string; var Abort: Boolean);\nbegin\n  raise EAbSpanningNotSupported.Create;\nend;\n{ -------------------------------------------------------------------------- }\n\n{ TAbExtraField implementation ============================================= }\nprocedure TAbExtraField.Assign(aSource : TAbExtraField);\nbegin\n  SetBuffer(aSource.Buffer);\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbExtraField.Changed;\nbegin\n  // No-op\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbExtraField.Clear;\nbegin\n  FBuffer := nil;\n  Changed;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbExtraField.CloneFrom(aSource : TAbExtraField; aID : Word);\nvar\n  Data : Pointer;\n  DataSize : Word;\nbegin\n  if aSource.Get(aID, Data, DataSize) then\n    Put(aID, Data, DataSize)\n  else Delete(aID);\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbExtraField.Delete(aID : Word);\nvar\n  SubField : PAbExtraSubField;\nbegin\n  if FindField(aID, SubField) then begin\n    DeleteField(SubField);\n    Changed;\n  end;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbExtraField.DeleteField(aSubField : PAbExtraSubField);\nvar\n  Len, Offset : Integer;\nbegin\n  Len := SizeOf(TAbExtraSubField) + aSubField.Len;\n  Offset := PtrInt(aSubField) - PtrInt(Pointer(FBuffer));\n  if Offset + Len < Length(FBuffer) then\n    Move(FBuffer[Offset + Len], aSubField^, Length(FBuffer) - Offset - Len);\n  SetLength(FBuffer, Length(FBuffer) - Len);\nend;\n{ -------------------------------------------------------------------------- }\nfunction TAbExtraField.FindField(aID : Word;\n  out aSubField : PAbExtraSubField) : Boolean;\nbegin\n  Result := False;\n  aSubField := nil;\n  while FindNext(aSubField) do\n    if aSubField.ID = aID then begin\n      Result := True;\n      Break;\n    end;\nend;\n{ -------------------------------------------------------------------------- }\nfunction TAbExtraField.FindNext(var aCurField : PAbExtraSubField) : Boolean;\nvar\n  BytesLeft : Integer;\nbegin\n  if aCurField = nil then begin\n    aCurField := PAbExtraSubField(FBuffer);\n    BytesLeft := Length(FBuffer);\n  end\n  else begin\n    BytesLeft := Length(FBuffer) -\n      Integer(PtrInt(aCurField) - PtrInt(Pointer(FBuffer))) -\n      SizeOf(TAbExtraSubField) - aCurField.Len;\n    aCurField := Pointer(PtrInt(aCurField) + aCurField.Len + SizeOf(TAbExtraSubField));\n  end;\n  Result := (BytesLeft >= SizeOf(TAbExtraSubField));\n  if Result and (BytesLeft < SizeOf(TAbExtraSubField) + aCurField.Len) then\n    aCurField.Len := BytesLeft - SizeOf(TAbExtraSubField);\nend;\n{ -------------------------------------------------------------------------- }\nfunction TAbExtraField.Get(aID : Word; out aData : Pointer;\n  out aDataSize : Word) : Boolean;\nvar\n  SubField : PAbExtraSubField;\nbegin\n  Result := FindField(aID, SubField);\n  if Result then begin\n    aData := @SubField.Data;\n    aDataSize := SubField.Len;\n  end\n  else begin\n    aData := nil;\n    aDataSize := 0;\n  end;\nend;\n{ -------------------------------------------------------------------------- }\nfunction TAbExtraField.GetCount : Integer;\nvar\n  SubField : PAbExtraSubField;\nbegin\n  Result := 0;\n  SubField := nil;\n  while FindNext(SubField) do\n    Inc(Result);\nend;\n{ -------------------------------------------------------------------------- }\nfunction TAbExtraField.GetID(aIndex : Integer): Word;\nvar\n  i: Integer;\n  SubField : PAbExtraSubField;\nbegin\n  i := 0;\n  SubField := nil;\n  while FindNext(SubField) do\n    if i = aIndex then begin\n      Result := SubField.ID;\n      Exit;\n    end\n    else\n      Inc(i);\n  raise EListError.CreateFmt(SListIndexError, [aIndex]);\nend;\n{ -------------------------------------------------------------------------- }\nfunction TAbExtraField.GetStream(aID : Word; out aStream : TStream): Boolean;\nvar\n  Data: Pointer;\n  DataSize: Word;\nbegin\n  Result := Get(aID, Data, DataSize);\n  if Result then begin\n    aStream := TMemoryStream.Create;\n    aStream.WriteBuffer(Data^, DataSize);\n    aStream.Position := 0;\n  end;\nend;\n{ -------------------------------------------------------------------------- }\nfunction TAbExtraField.Has(aID : Word): Boolean;\nvar\n  SubField : PAbExtraSubField;\nbegin\n  Result := FindField(aID, SubField);\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbExtraField.LoadFromStream(aStream : TStream; aSize : Word);\nbegin\n  SetLength(FBuffer, aSize);\n  if aSize > 0 then\n    aStream.ReadBuffer( FBuffer[0], aSize);\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbExtraField.Put(aID : Word; const aData; aDataSize : Word);\nvar\n  Offset : Cardinal;\n  SubField : PAbExtraSubField;\nbegin\n  if FindField(aID, SubField) then begin\n    if SubField.Len = aDataSize then begin\n      Move(aData, SubField.Data, aDataSize);\n      Changed;\n      Exit;\n    end\n    else DeleteField(SubField);\n  end;\n  Offset := Length(FBuffer);\n  SetLength(FBuffer, Length(FBuffer) + SizeOf(TAbExtraSubField) + aDataSize);\n  SubField := PAbExtraSubField(@FBuffer[Offset]);\n  SubField.ID := aID;\n  SubField.Len := aDataSize;\n  Move(aData, SubField.Data, aDataSize);\n  Changed;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbExtraField.SetBuffer(const aValue : TByteDynArray);\nbegin\n  SetLength(FBuffer, Length(aValue));\n  if Length(FBuffer) > 0 then\n    Move(aValue[0], FBuffer[0], Length(FBuffer));\n  Changed;\nend;\n{ -------------------------------------------------------------------------- }\n\n{ ========================================================================== }\n{ TAbArchiveStreamHelper }\n\nconstructor TAbArchiveStreamHelper.Create(AStream: TStream);\nbegin\n  if Assigned(AStream) then\n    FStream := AStream\n  else\n    raise Exception.Create('nil stream');\nend;\n\nend.\n"
  },
  {
    "path": "lib/abbrevia/source/AbBase.pas",
    "content": "(* ***** BEGIN LICENSE BLOCK *****\n * Version: MPL 1.1\n *\n * The contents of this file are subject to the Mozilla Public License Version\n * 1.1 (the \"License\"); you may not use this file except in compliance with\n * the License. You may obtain a copy of the License at\n * http://www.mozilla.org/MPL/\n *\n * Software distributed under the License is distributed on an \"AS IS\" basis,\n * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License\n * for the specific language governing rights and limitations under the\n * License.\n *\n * The Original Code is TurboPower Abbrevia\n *\n * The Initial Developer of the Original Code is\n * TurboPower Software\n *\n * Portions created by the Initial Developer are Copyright (C) 1997-2002\n * the Initial Developer. All Rights Reserved.\n *\n * Contributor(s):\n *\n * ***** END LICENSE BLOCK ***** *)\n\n{*********************************************************}\n{* ABBREVIA: AbBase.pas                                  *}\n{*********************************************************}\n{* ABBREVIA: Base component class                        *}\n{*********************************************************}\n\nunit AbBase;\n\n{$I AbDefine.inc}\n\ninterface\n\nuses\n  Classes;\n\ntype\n  TAbBaseComponent = class(TComponent)\n  protected {methods}\n    function  GetVersion : string;\n    procedure SetVersion(const Value : string);\n\n  protected {properties}\n    property Version : string\n      read  GetVersion\n      write SetVersion\n      stored False;\n  end;\n\nimplementation\n\nuses\n  AbConst;\n\n{ -------------------------------------------------------------------------- }\nfunction TAbBaseComponent.GetVersion : string;\nbegin\n  Result := AbVersionS;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbBaseComponent.SetVersion(const Value : string);\nbegin\n  {NOP}\nend;\n\nend.\n"
  },
  {
    "path": "lib/abbrevia/source/AbBitBkt.pas",
    "content": "(* ***** BEGIN LICENSE BLOCK *****\n * Version: MPL 1.1\n *\n * The contents of this file are subject to the Mozilla Public License Version\n * 1.1 (the \"License\"); you may not use this file except in compliance with\n * the License. You may obtain a copy of the License at\n * http://www.mozilla.org/MPL/\n *\n * Software distributed under the License is distributed on an \"AS IS\" basis,\n * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License\n * for the specific language governing rights and limitations under the\n * License.\n *\n * The Original Code is TurboPower Abbrevia\n *\n * The Initial Developer of the Original Code is\n * TurboPower Software\n *\n * Portions created by the Initial Developer are Copyright (C) 1997-2002\n * the Initial Developer. All Rights Reserved.\n *\n * Contributor(s):\n *\n * ***** END LICENSE BLOCK ***** *)\n\n{*********************************************************}\n{* ABBREVIA: AbBitBkt.pas                                *}\n{*********************************************************}\n{* ABBREVIA: Bit bucket memory stream class              *}\n{*********************************************************}\n\nunit AbBitBkt;\n\n{$I AbDefine.inc}\n\ninterface\n\nuses\n  Classes,\n  AbUtils;\n\ntype\n  TAbBitBucketStream = class(TStream)\n    private\n      FBuffer  : {$IFDEF UNICODE}PByte{$ELSE}PAnsiChar{$ENDIF};\n      FBufSize : longint;\n      FBufPosn : longint;\n      FPosn    : Int64;\n      FSize    : Int64;\n      FTail    : longint;\n    protected\n    public\n      constructor Create(aBufSize : cardinal);\n      destructor Destroy; override;\n      function Read(var Buffer; Count : Longint) : Longint; override;\n      function Write(const Buffer; Count : Longint) : Longint; override;\n      function Seek(const Offset : Int64; Origin : TSeekOrigin) : Int64; override;\n\n      procedure ForceSize(aSize : Int64);\n  end;\n\nimplementation\n\nuses\n  Math, SysUtils, AbExcept;\n\n{Notes: The buffer is a circular queue without a head pointer; FTail\n        is where data is next going to be written and it wraps\n        indescriminately. The buffer can never be empty--it is always\n        full (initially it is full of binary zeros.\n        The class is designed to act as a bit bucket for the test\n        feature of Abbrevia's zip code; it is not intended as a\n        complete class with many possible applications. It is designed\n        to be written to in a steady progression with some reading\n        back in the recently written stream (the buffer size details\n        how far back the Seek method will work). Seeking outside this\n        buffer will result in exceptions being generated.\n        For testing deflated files, the buffer size should be 32KB,\n        for imploded files, either 8KB or 4KB. The Create constructor\n        limits the buffer size to these values.}\n\n{===TAbBitBucketStream===============================================}\nconstructor TAbBitBucketStream.Create(aBufSize : cardinal);\nbegin\n  inherited Create;\n  if (aBufSize <> 4096) and\n     (aBufSize <> 8192) and\n     (aBufSize <> 32768) then\n    FBufSize := 32768\n  else\n    FBufSize := aBufSize;\n  {add a 1KB leeway}\n  inc(FBufSize, 1024);\n  GetMem(FBuffer, FBufSize);\nend;\n{--------}\ndestructor TAbBitBucketStream.Destroy;\nbegin\n  if (FBuffer <> nil) then\n    FreeMem(FBuffer, FBufSize);\n  inherited Destroy;\nend;\n{--------}\nprocedure TAbBitBucketStream.ForceSize(aSize : Int64);\nbegin\n  FSize := aSize;\nend;\n{--------}\nfunction TAbBitBucketStream.Read(var Buffer; Count : Longint) : Longint;\nvar\n  Chunk2Size : longint;\n  Chunk1Size : longint;\n  OutBuffer  : PByte;\nbegin\n  OutBuffer := @Buffer;\n  {we cannot read more bytes than there is buffer}\n  if (Count > FBufSize) then\n    raise EAbBBSReadTooManyBytes.Create(Count);\n  {calculate the size of the chunks}\n  if (FBufPosn <= FTail) then begin\n    Chunk1Size := FTail - FBufPosn;\n    if (Chunk1Size > Count) then\n      Chunk1Size := Count;\n    Chunk2Size := 0;\n  end\n  else begin\n    Chunk1Size := FBufSize - FBufPosn;\n    if (Chunk1Size > Count) then begin\n      Chunk1Size := Count;\n      Chunk2Size := 0;\n    end\n    else begin\n      Chunk2Size := FTail;\n      if (Chunk2Size > (Count - Chunk1Size)) then\n        Chunk2Size := Count - Chunk1Size;\n    end\n  end;\n  {we cannot read more bytes than there are available}\n  if (Count > (Chunk1Size + Chunk2Size)) then\n    raise EAbBBSReadTooManyBytes.Create(Count);\n  {perform the read}\n  if (Chunk1Size > 0) then begin\n    Move(FBuffer[FBufPosn], OutBuffer^, Chunk1Size);\n    inc(FBufPosn, Chunk1Size);\n    inc(FPosn, Chunk1Size);\n  end;\n  if (Chunk2Size > 0) then begin\n    {we've wrapped}\n    Move(FBuffer[0], PByte(PtrInt(OutBuffer) + PtrInt(Chunk1Size))^, Chunk2Size);\n    FBufPosn := Chunk2Size;\n    inc(FPosn, Chunk2Size);\n  end;\n  Result := Count;\nend;\n{--------}\nfunction TAbBitBucketStream.Write(const Buffer; Count : Longint) : Longint;\nvar\n  Chunk2Size : longint;\n  Chunk1Size : longint;\n  InBuffer   : PByte;\n  Overage    : longint;\nbegin\n  Result := Count;\n  InBuffer := @Buffer;\n  {we cannot write more bytes than there is buffer}\n  while Count > FBufSize do begin\n    Overage := Min(FBufSize, Count - FBufSize);\n    Write(InBuffer^, Overage);\n    Inc(PtrInt(InBuffer), Overage);\n    Dec(Count, Overage);\n  end;\n  {calculate the size of the chunks}\n  Chunk1Size := FBufSize - FTail;\n  if (Chunk1Size > Count) then begin\n    Chunk1Size := Count;\n    Chunk2Size := 0;\n  end\n  else begin\n    Chunk2Size := Count - Chunk1Size;\n  end;\n  {write the first chunk}\n  if (Chunk1Size > 0) then begin\n    Move(InBuffer^, FBuffer[FTail], Chunk1Size);\n    inc(FTail, Chunk1Size);\n  end;\n  {if the second chunk size is not zero, write the second chunk; note\n   that we have wrapped}\n  if (Chunk2Size > 0) then begin\n    Move(PByte(PtrInt(InBuffer) + PtrInt(Chunk1Size))^, FBuffer[0], Chunk2Size);\n    FTail := Chunk2Size;\n  end;\n  {the stream size and position have changed}\n  inc(FSize, Count);\n  FPosn := FSize;\n  FBufPosn := FTail;\nend;\n{--------}\nfunction TAbBitBucketStream.Seek(const Offset : Int64; Origin : TSeekOrigin): Int64;\nvar\n  Posn : Int64;\n  BytesBack : longint;\nbegin\n  {calculate the new position}\n  case Origin of\n    soBeginning :\n      Posn := Offset;\n    soCurrent   :\n      Posn := FPosn + Offset;\n    soEnd       :\n      if (Offset = 0) then begin\n        {special case: position at end of stream}\n        FBufPosn := FTail;\n        FPosn := FSize;\n        Result := FSize;\n        Exit;\n      end\n      else begin\n        Posn := FSize + Offset;\n      end;\n  else\n    raise EAbBBSInvalidOrigin.Create;\n  end;\n  {calculate whether the new position is within the buffer; if not,\n   raise exception}\n  if (Posn > FSize) or\n     (Posn <= (FSize - FBufSize)) then\n    raise EAbBBSSeekOutsideBuffer.Create;\n  {set the internal fields for the new position}\n  FPosn := Posn;\n  BytesBack := FSize - Posn;\n  if (BytesBack <= FTail) then\n    FBufPosn := FTail - BytesBack\n  else\n    FBufPosn := longint(FTail) + FBufSize - BytesBack;\n  {return the new position}\n  Result := Posn;\nend;\n{====================================================================}\n\n\nend.\n"
  },
  {
    "path": "lib/abbrevia/source/AbBrowse.pas",
    "content": "(* ***** BEGIN LICENSE BLOCK *****\n * Version: MPL 1.1\n *\n * The contents of this file are subject to the Mozilla Public License Version\n * 1.1 (the \"License\"); you may not use this file except in compliance with\n * the License. You may obtain a copy of the License at\n * http://www.mozilla.org/MPL/\n *\n * Software distributed under the License is distributed on an \"AS IS\" basis,\n * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License\n * for the specific language governing rights and limitations under the\n * License.\n *\n * The Original Code is TurboPower Abbrevia\n *\n * The Initial Developer of the Original Code is\n * TurboPower Software\n *\n * Portions created by the Initial Developer are Copyright (C) 1997-2002\n * the Initial Developer. All Rights Reserved.\n *\n * Contributor(s):\n *\n * ***** END LICENSE BLOCK ***** *)\n\n{*********************************************************}\n{* ABBREVIA: AbBrowse.pas                                *}\n{*********************************************************}\n{* ABBREVIA: Base Browser Component                      *}\n{*********************************************************}\n\nunit AbBrowse;\n\n{$I AbDefine.inc}\n\ninterface\n\nuses\n  Classes,\n  AbBase,\n  AbUtils,\n  AbArcTyp;\n\ntype\n  IAbProgressMeter = interface\n    ['{4B766704-FD20-40BF-BA40-2EC2DD77B178}']\n    procedure DoProgress(Progress : Byte);\n    procedure Reset;\n  end;\n\n  TAbBaseBrowser = class(TAbBaseComponent)\n  public\n    FArchive : TAbArchive;\n  protected {private}\n    FSpanningThreshold : Longint;\n    FItemProgressMeter : IAbProgressMeter;\n    FArchiveProgressMeter : IAbProgressMeter;\n    FBaseDirectory : string;\n    FFileName : string;\n    FLogFile : string;\n    FLogging : Boolean;\n    FOnArchiveProgress : TAbArchiveProgressEvent;\n    FOnArchiveItemProgress : TAbArchiveItemProgressEvent;\n    FOnChange : TNotifyEvent;\n    FOnConfirmProcessItem : TAbArchiveItemConfirmEvent;\n    FOnLoad : TAbArchiveEvent;\n    FOnProcessItemFailure : TAbArchiveItemFailureEvent;\n    FOnRequestImage : TAbRequestImageEvent;\n    FTempDirectory : string;\n\n    { detected compression type }\n    FArchiveType       : TAbArchiveType;\n    FForceType             : Boolean;\n\n  protected {private methods}\n    function  GetCount : Integer;\n    function  GetItem(Value : Longint) : TAbArchiveItem;\n    function  GetSpanned : Boolean;\n    function  GetStatus : TAbArchiveStatus;\n    procedure ResetMeters; virtual;\n    procedure SetArchiveProgressMeter(const Value: IAbProgressMeter);\n    procedure SetCompressionType(const Value: TAbArchiveType);\n    procedure SetBaseDirectory(const Value : string);\n    procedure SetItemProgressMeter(const Value: IAbProgressMeter);\n    procedure SetSpanningThreshold(Value : Longint);\n    procedure SetLogFile(const Value : string);\n    procedure SetLogging(Value : Boolean);\n    procedure SetTempDirectory(const Value : string);\n\n    procedure Loaded; override;\n    procedure Notification(Component: TComponent;\n                           Operation: TOperation); override;\n\n  protected {virtual methods}\n    procedure DoArchiveItemProgress(Sender : TObject;\n                                    Item : TAbArchiveItem;\n                                    Progress : Byte;\n                                    var Abort : Boolean); virtual;\n    procedure DoArchiveProgress(Sender : TObject;\n                                Progress : Byte;\n                                var Abort : Boolean); virtual;\n    procedure DoChange; virtual;\n    procedure DoConfirmProcessItem(Sender : TObject;\n                                   Item : TAbArchiveItem;\n                                   ProcessType : TAbProcessType;\n                                   var Confirm : Boolean); virtual;\n    procedure DoLoad(Sender : TObject); virtual;\n    procedure DoProcessItemFailure(Sender : TObject;\n                                    Item : TAbArchiveItem;\n                                    ProcessType : TAbProcessType;\n                                    ErrorClass : TAbErrorClass;\n                                    ErrorCode : Integer); virtual;\n    procedure SetOnRequestImage(Value : TAbRequestImageEvent); virtual;\n    procedure InitArchive; virtual;\n\n    {This method must be defined in descendent classes}\n    procedure SetFileName(const aFileName : string); virtual; abstract;\n\n\n  protected {properties}\n    property Archive : TAbArchive\n      read FArchive;\n    property ArchiveProgressMeter : IAbProgressMeter\n      read  FArchiveProgressMeter\n      write SetArchiveProgressMeter;\n    property BaseDirectory : string\n      read  FBaseDirectory\n      write SetBaseDirectory;\n    property FileName : string\n      read  FFileName\n      write SetFileName;\n    property SpanningThreshold : Longint\n      read  FSpanningThreshold\n      write SetSpanningThreshold\n      default 0;\n    property ItemProgressMeter : IAbProgressMeter\n      read  FItemProgressMeter\n      write SetItemProgressMeter;\n    property LogFile : string\n      read  FLogFile\n      write SetLogFile;\n    property Logging : Boolean\n      read  FLogging\n      write SetLogging\n      default False;\n    property Spanned : Boolean\n      read GetSpanned;\n    property TempDirectory : string\n      read  FTempDirectory\n      write SetTempDirectory;\n\n\n\n  protected {events}\n    property OnArchiveProgress : TAbArchiveProgressEvent\n      read FOnArchiveProgress\n      write FOnArchiveProgress;\n    property OnArchiveItemProgress : TAbArchiveItemProgressEvent\n      read FOnArchiveItemProgress\n      write FOnArchiveItemProgress;\n    property OnConfirmProcessItem : TAbArchiveItemConfirmEvent\n      read FOnConfirmProcessItem\n      write FOnConfirmProcessItem;\n    property OnProcessItemFailure : TAbArchiveItemFailureEvent\n      read FOnProcessItemFailure\n      write FOnProcessItemFailure;\n    property OnRequestImage : TAbRequestImageEvent\n      read FOnRequestImage\n      write SetOnRequestImage;\n\n  public {methods}\n    constructor Create(AOwner : TComponent); override;\n    destructor Destroy; override;\n\n    procedure ClearTags;\n      {Clear all tags from the archive}\n    function FindItem(aItem : TAbArchiveItem) : Integer;\n    function FindFile(const aFileName : string) : Integer;\n    procedure TagItems(const FileMask : string);\n      {tag all items that match the mask}\n    procedure UnTagItems(const FileMask : string);\n      {clear tags for all items that match the mask}\n    procedure CloseArchive;\n      {closes the archive by setting FileName to ''}\n    procedure OpenArchive(const aFileName : string);\n      {opens the archive}\n\n  public {properties}\n    property Count : Integer\n      read GetCount;\n    property Items[Index : Integer] : TAbArchiveItem\n      read GetItem; default;\n    property Status : TAbArchiveStatus\n      read GetStatus;\n\n    property ArchiveType : TAbArchiveType\n      read FArchiveType\n      write SetCompressionType\n      default atUnknown;\n\n    property ForceType : Boolean\n      read FForceType\n      write FForceType\n      default False;\n\n  public {events}\n    property OnChange : TNotifyEvent\n      read FOnChange\n      write FOnChange;\n    property OnLoad : TAbArchiveEvent\n      read FOnLoad\n      write FOnLoad;\n  end;\n\nfunction AbDetermineArcType(const FN : string; AssertType : TAbArchiveType) : TAbArchiveType; overload;\nfunction AbDetermineArcType(aStream: TStream) : TAbArchiveType; overload;\n\nimplementation\n\nuses\n  SysUtils,\n  AbExcept,\n{$IFDEF MSWINDOWS}\n  AbCabTyp,\n{$ENDIF}\n  AbZipTyp,\n  AbTarTyp,\n  AbGzTyp,\n  AbBzip2Typ;\n\n{ TAbBaseBrowser implementation ======================================= }\n\n{ -------------------------------------------------------------------------- }\nconstructor TAbBaseBrowser.Create(AOwner : TComponent);\nbegin\n  inherited Create(AOwner);\n  FLogFile := '';\n  FLogging := False;\n  FSpanningThreshold := 0;\n\n  FArchiveType := atUnknown;\n  FForceType       := False;\nend;\n{ -------------------------------------------------------------------------- }\ndestructor TAbBaseBrowser.Destroy;\nbegin\n  FArchive.Free;\n  FArchive := nil;\n  inherited Destroy;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbBaseBrowser.ClearTags;\n  {Clear all tags from the archive}\nbegin\n  if Assigned(FArchive) then\n    FArchive.ClearTags\n  else\n    raise EAbNoArchive.Create;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbBaseBrowser.CloseArchive;\n  {closes the archive by setting FileName to ''}\nbegin\n  if FFileName <> '' then\n    FileName := '';\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbBaseBrowser.DoArchiveItemProgress(Sender : TObject;\n                                               Item : TAbArchiveItem;\n                                               Progress : Byte;\n                                               var Abort : Boolean);\nbegin\n  Abort := False;\n  if Assigned(FItemProgressMeter) then\n    FItemProgressMeter.DoProgress(Progress);\n  if Assigned(FOnArchiveItemProgress) then\n    FOnArchiveItemProgress(Self, Item, Progress, Abort);\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbBaseBrowser.DoArchiveProgress(Sender : TObject;\n                                           Progress : Byte;\n                                           var Abort : Boolean);\nbegin\n  Abort := False;\n  if Assigned(FArchiveProgressMeter) then\n    FArchiveProgressMeter.DoProgress(Progress);\n  if Assigned(FOnArchiveProgress) then\n    FOnArchiveProgress(Self, Progress, Abort);\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbBaseBrowser.DoChange;                                \nbegin\n  if Assigned(FOnChange) then begin\n    FOnChange(Self);\n  end;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbBaseBrowser.DoConfirmProcessItem(Sender : TObject;\n                                              Item : TAbArchiveItem;\n                                              ProcessType : TAbProcessType;\n                                              var Confirm : Boolean);\nbegin\n  Confirm := True;\n  if Assigned(FItemProgressMeter) then\n    FItemProgressMeter.Reset;\n  if Assigned(FOnConfirmProcessItem) then\n    FOnConfirmProcessItem(Self, Item, ProcessType, Confirm);\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbBaseBrowser.DoLoad(Sender : TObject);\nbegin\n  if Assigned(FOnLoad) then\n    FOnLoad(Self);\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbBaseBrowser.DoProcessItemFailure(Sender : TObject;\n                                              Item : TAbArchiveItem;\n                                              ProcessType : TAbProcessType;\n                                              ErrorClass : TAbErrorClass;\n                                              ErrorCode : Integer);\nbegin\n  if Assigned(FOnProcessItemFailure) then\n    FOnProcessItemFailure(Self, Item, ProcessType, ErrorClass, ErrorCode);\nend;\n{ -------------------------------------------------------------------------- }\nfunction TAbBaseBrowser.FindItem(aItem : TAbArchiveItem) : Integer;\nbegin\n  if Assigned(FArchive) then\n    Result := FArchive.FindItem(aItem)\n  else\n    Result := -1;\nend;\n{ -------------------------------------------------------------------------- }\nfunction TAbBaseBrowser.FindFile(const aFileName : string) : Integer;\nbegin\n  if Assigned(FArchive) then\n    Result := FArchive.FindFile(aFileName)\n  else\n    Result := -1;\nend;\n{ -------------------------------------------------------------------------- }\nfunction TAbBaseBrowser.GetSpanned : Boolean;\nbegin\n  if Assigned(FArchive) then\n    Result := FArchive.Spanned\n  else\n    Result := False;\nend;\n{ -------------------------------------------------------------------------- }\nfunction TAbBaseBrowser.GetStatus : TAbArchiveStatus;\nbegin\n  if Assigned(FArchive) then\n    Result := FArchive.Status\n  else\n    Result := asInvalid;\nend;\n{ -------------------------------------------------------------------------- }\nfunction TAbBaseBrowser.GetCount : Integer;\nbegin\n  if Assigned(FArchive) then\n    Result := FArchive.Count\n  else\n    Result := 0;\nend;\n{ -------------------------------------------------------------------------- }\nfunction TAbBaseBrowser.GetItem(Value : Longint) : TAbArchiveItem;\nbegin\n  if Assigned(FArchive) then\n    Result := FArchive.ItemList[Value]\n  else\n    raise EAbNoArchive.Create;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbBaseBrowser.InitArchive;\nbegin\n  ResetMeters;\n  if Assigned(FArchive) then begin\n    {properties}\n    FArchive.SpanningThreshold     := FSpanningThreshold;\n    FArchive.LogFile               := FLogFile;\n    FArchive.Logging               := FLogging;\n    FArchive.TempDirectory         := FTempDirectory;\n    SetBaseDirectory(FBaseDirectory);\n    {events}\n    FArchive.OnArchiveProgress     := DoArchiveProgress;\n    FArchive.OnArchiveItemProgress := DoArchiveItemProgress;\n    FArchive.OnConfirmProcessItem  := DoConfirmProcessItem;\n    FArchive.OnLoad                := DoLoad;\n    FArchive.OnProcessItemFailure  := DoProcessItemFailure;\n    FArchive.OnRequestImage        := FOnRequestImage;\n  end;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbBaseBrowser.Loaded;\nbegin\n  inherited Loaded;\n  DoChange;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbBaseBrowser.Notification(Component: TComponent;\n                                      Operation: TOperation);\nbegin\n  inherited Notification(Component, Operation);\n  if (Operation = opRemove) then begin\n    if Assigned(ItemProgressMeter) and Component.IsImplementorOf(ItemProgressMeter) then\n      ItemProgressMeter := nil;\n    if Assigned(ArchiveProgressMeter) and Component.IsImplementorOf(ArchiveProgressMeter) then\n      ArchiveProgressMeter := nil;\n  end;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbBaseBrowser.OpenArchive(const aFileName : string);\n  {opens the archive}\nbegin\n  FileName := AFileName;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbBaseBrowser.ResetMeters;\nbegin\n  if Assigned(FArchiveProgressMeter) then\n    FArchiveProgressMeter.Reset;\n  if Assigned(FItemProgressMeter) then\n    FItemProgressMeter.Reset;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbBaseBrowser.SetBaseDirectory(const Value : string);\nbegin\n  if Assigned(FArchive) then begin\n    FArchive.BaseDirectory := Value;\n    FBaseDirectory := FArchive.BaseDirectory;\n  end else\n    FBaseDirectory := Value;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbBaseBrowser.SetSpanningThreshold(Value : Longint);\nbegin\n  FSpanningThreshold := Value;\n  if Assigned(FArchive) then\n    FArchive.SpanningThreshold := Value;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbBaseBrowser.SetLogFile(const Value : string);\nbegin\n  FLogFile := Value;\n  if (csDesigning in ComponentState) then\n    Exit;\n  if Assigned(FArchive) then\n    FArchive.LogFile := Value;\n  SetLogging(Value <> '');\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbBaseBrowser.SetLogging(Value : Boolean);\nbegin\n  FLogging := Value;\n  if (csDesigning in ComponentState) then\n    Exit;\n  if Assigned(FArchive) then\n    FArchive.Logging:= Value;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbBaseBrowser.SetOnRequestImage(Value : TAbRequestImageEvent);\nbegin\n  FOnRequestImage := Value;\n  if Assigned(FArchive) then\n    FArchive.OnRequestImage := Value;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbBaseBrowser.SetTempDirectory(const Value : string);\nbegin\n  FTempDirectory := Value;\n  if Assigned(FArchive) then\n    FArchive.TempDirectory := Value;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbBaseBrowser.TagItems(const FileMask : string);\n  {tag all items that match the mask}\nbegin\n  if Assigned(FArchive) then\n    FArchive.TagItems(FileMask)\n  else\n    raise EAbNoArchive.Create;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbBaseBrowser.UnTagItems(const FileMask : string);\n  {clear tags for all items that match the mask}\nbegin\n  if Assigned(FArchive) then\n    FArchive.UnTagItems(FileMask)\n  else\n    raise EAbNoArchive.Create;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbBaseBrowser.SetCompressionType(const Value: TAbArchiveType);\nbegin\n  if not Assigned(FArchive) or (Status <> asInvalid) then\n    FArchiveType := Value\n  else\n    raise EAbArchiveBusy.Create;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbBaseBrowser.SetArchiveProgressMeter(const Value: IAbProgressMeter);\nbegin\n  ReferenceInterface(FArchiveProgressMeter, opRemove);\n  FArchiveProgressMeter := Value;\n  ReferenceInterface(FArchiveProgressMeter, opInsert);\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbBaseBrowser.SetItemProgressMeter(const Value: IAbProgressMeter);\nbegin\n  ReferenceInterface(FItemProgressMeter, opRemove);\n  FItemProgressMeter := Value;\n  ReferenceInterface(FItemProgressMeter, opInsert);\nend;\n{ -------------------------------------------------------------------------- }\nfunction AbDetermineArcType(const FN : string; AssertType : TAbArchiveType) : TAbArchiveType;\nvar\n  Ext : string;\n  FS : TFileStream;\nbegin\n  Result := AssertType;\n  if Result = atUnknown then begin\n    { Guess archive type based on it's extension }\n    Ext := UpperCase(ExtractFileExt(FN));\n    if (Ext = '.ZIP') or (Ext = '.JAR') then\n      Result := atZip;\n    if (Ext = '.EXE') then\n      Result := atSelfExtZip;\n    if (Ext = '.TAR') then\n      Result := atTar;\n    if (Ext = '.GZ') then\n      Result := atGzip;\n    if (Ext = '.TGZ') then\n      Result := atGzippedTar;\n    if (Ext = '.CAB') then\n      Result := atCab;\n    if (Ext = '.BZ2') then\n      Result := atBzip2;\n    if (Ext = '.TBZ') then\n      Result := atBzippedTar;\n  end;\n  {$IFNDEF MSWINDOWS}\n  if Result = atCab then\n    Result := atUnknown;\n  {$ENDIF}\n  if FileExists(FN) and (AbFileGetSize(FN) > 0) then begin\n    { If the file doesn't exist (or is empty) presume to make one, otherwise\n      guess or verify the contents }\n    FS := TFileStream.Create(FN, fmOpenRead or fmShareDenyNone);\n    try\n      if Result = atUnknown then\n        Result := AbDetermineArcType(FS)\n      else begin\n        case Result of\n          atZip : begin\n            Result := VerifyZip(FS);\n          end;\n          atSelfExtZip : begin\n            Result := VerifySelfExtracting(FS);\n          end;\n          atTar : begin\n            Result := VerifyTar(FS);\n          end;\n          atGzip, atGzippedTar: begin\n            Result := VerifyGzip(FS);\n          end;\n          {$IFDEF MSWINDOWS}\n          atCab : begin\n            Result := VerifyCab(FS);\n          end;\n          {$ENDIF}\n          atBzip2, atBzippedTar: begin\n            Result := VerifyBzip2(FS);\n          end;\n        end;\n      end;\n    finally\n      FS.Free;\n    end;\n  end;\nend;\n{ -------------------------------------------------------------------------- }\nfunction AbDetermineArcType(aStream: TStream): TAbArchiveType;\nbegin\n  { VerifyZip returns true for self-extracting zips too, so test those first }\n  Result := VerifySelfExtracting(aStream);\n  if Result = atUnknown then\n    Result := VerifyZip(aStream);\n  if Result = atUnknown then\n    Result := VerifyTar(aStream);\n  if Result = atUnknown then\n    Result := VerifyGzip(aStream);\n  if Result = atUnknown then\n    Result := VerifyBzip2(aStream);\n  {$IFDEF MSWINDOWS}\n  if Result = atUnknown then\n    Result := VerifyCab(aStream);\n  {$ENDIF}\nend;\n{ -------------------------------------------------------------------------- }\n\n\nend.\n"
  },
  {
    "path": "lib/abbrevia/source/AbBseCLX.pas",
    "content": "(* ***** BEGIN LICENSE BLOCK *****\n * Version: MPL 1.1\n *\n * The contents of this file are subject to the Mozilla Public License Version\n * 1.1 (the \"License\"); you may not use this file except in compliance with\n * the License. You may obtain a copy of the License at\n * http://www.mozilla.org/MPL/\n *\n * Software distributed under the License is distributed on an \"AS IS\" basis,\n * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License\n * for the specific language governing rights and limitations under the\n * License.\n *\n * The Original Code is TurboPower Abbrevia\n *\n * The Initial Developer of the Original Code is\n * TurboPower Software\n *\n * Portions created by the Initial Developer are Copyright (C) 1997-2002\n * the Initial Developer. All Rights Reserved.\n *\n * Contributor(s):\n *\n * ***** END LICENSE BLOCK ***** *)\n\n{*********************************************************}\n{* ABBREVIA: AbBaseCLX.pas                               *}\n{*********************************************************}\n{* ABBREVIA: Base component class (CLX)                  *}\n{*********************************************************}\n\nunit AbBseCLX;\n\n{$I AbDefine.inc}\n\ninterface\n\nuses\n  Classes,\n  {$IFNDEF BuildingStub}\n  QControls,\n  {$ENDIF BuildingStub}\n  AbConst,\n  AbBase;\n\n\n{$IFNDEF BuildingStub}\ntype\n  TAbBaseWinControl = class(TWidgetControl);\n{$ENDIF BuildingStub}\n\nimplementation\n\nend.\n"
  },
  {
    "path": "lib/abbrevia/source/AbBseVCL.pas",
    "content": "(* ***** BEGIN LICENSE BLOCK *****\n * Version: MPL 1.1\n *\n * The contents of this file are subject to the Mozilla Public License Version\n * 1.1 (the \"License\"); you may not use this file except in compliance with\n * the License. You may obtain a copy of the License at\n * http://www.mozilla.org/MPL/\n *\n * Software distributed under the License is distributed on an \"AS IS\" basis,\n * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License\n * for the specific language governing rights and limitations under the\n * License.\n *\n * The Original Code is TurboPower Abbrevia\n *\n * The Initial Developer of the Original Code is\n * TurboPower Software\n *\n * Portions created by the Initial Developer are Copyright (C) 1997-2002\n * the Initial Developer. All Rights Reserved.\n *\n * Contributor(s):\n *\n * ***** END LICENSE BLOCK ***** *)\n\n{*********************************************************}\n{* ABBREVIA: AbBaseVCL.pas                               *}\n{*********************************************************}\n{* ABBREVIA: Base component class (VCL)                  *}\n{*********************************************************}\n\nunit AbBseVCL;\n\n{$I AbDefine.inc}\n\ninterface\n\nuses\n  Classes\n  {$IFNDEF BuildingStub}\n  , Controls\n  {$ENDIF BuildingStub}\n  ;\n\n\n{$IFNDEF BuildingStub}\ntype\n  TAbBaseWinControl = class(TWinControl);\n{$ENDIF BuildingStub}\n\nimplementation\n\nend.\n"
  },
  {
    "path": "lib/abbrevia/source/AbBzip2.pas",
    "content": "(* ***** BEGIN LICENSE BLOCK *****\n * This program, \"bzip2\", the associated library \"libbzip2\", and all\n * documentation, are copyright (C) 1996-2007 Julian R Seward.  All\n * rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n *\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n *\n * 2. The origin of this software must not be misrepresented; you must\n *    not claim that you wrote the original software.  If you use this\n *    software in a product, an acknowledgment in the product\n *    documentation would be appreciated but is not required.\n *\n * 3. Altered source versions must be plainly marked as such, and must\n *    not be misrepresented as being the original software.\n *\n * 4. The name of the author may not be used to endorse or promote\n *    products derived from this software without specific prior written\n *    permission.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS\n * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\n * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY\n * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE\n * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\n * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,\n * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\n * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\n * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n *\n * Julian Seward, jseward@bzip.org\n * bzip2/libbzip2 version 1.0.5 of 10 December 2007\n *\n * Pascal wrapper created by Edison Mera, version 1.04\n * http://edisonlife.homelinux.com/\n *\n * Dynamic and runtime linking and Win64/OS X/Linux support by Craig Peterson\n * http://tpabbrevia.sourceforge.net/\n * ***** END LICENSE BLOCK ***** *)\n\nunit AbBzip2;\n\n{$I AbDefine.inc}\n\ninterface\n\nuses\n  SysUtils, Classes;\n\ntype\n  TAlloc = function(opaque: Pointer; Items, Size: Integer): Pointer; cdecl;\n  TFree = procedure(opaque, Block: Pointer); cdecl;\n\n  // Internal structure.  Ignore.\n  TBZStreamRec = record\n    next_in: PByte; // next input byte\n    avail_in: Integer; // number of bytes available at next_in\n    total_in_lo32: Integer; // total nb of input bytes read so far\n    total_in_hi32: Integer;\n\n    next_out: PByte; // next output byte should be put here\n    avail_out: Integer; // remaining free space at next_out\n    total_out_lo32: Integer; // total nb of bytes output so far\n    total_out_hi32: Integer;\n\n    state: Pointer;\n\n    bzalloc: TAlloc; // used to allocate the internal state\n    bzfree: TFree; // used to free the internal state\n    opaque: Pointer;\n  end;\n\n  // Abstract ancestor class\n  TCustomBZip2Stream = class(TStream)\n  private\n    FStrm: TStream;\n    FStrmPos: Int64;\n    FOnProgress: TNotifyEvent;\n    FBZRec: TBZStreamRec;\n    FBuffer: array[Word] of Byte;\n  protected\n    procedure Progress(Sender: TObject); dynamic;\n    property OnProgress: TNotifyEvent read FOnProgress write FOnProgress;\n    constructor Create(Strm: TStream);\n  end;\n\n{ TBZCompressionStream compresses data on the fly as data is written to it, and\n  stores the compressed data to another stream.\n\n  TBZCompressionStream is write-only and strictly sequential. Reading from the\n  stream will raise an exception. Using Seek to move the stream pointer\n  will raise an exception.\n\n  Output data is cached internally, written to the output stream only when\n  the internal output buffer is full.  All pending output data is flushed\n  when the stream is destroyed.\n\n  The Position property returns the number of uncompressed bytes of\n  data that have been written to the stream so far.\n\n  CompressionRate returns the on-the-fly percentage by which the original\n  data has been compressed:  (1 - (CompressedBytes / UncompressedBytes)) * 100\n  If raw data size = 100 and compressed data size = 25, the CompressionRate\n  is 75%\n\n  The OnProgress event is called each time the output buffer is filled and\n  written to the output stream.  This is useful for updating a progress\n  indicator when you are writing a large chunk of data to the compression\n  stream in a single call.}\n\n\n  TBlockSize100k = (bs1, bs2, bs3, bs4, bs5, bs6, bs7, bs8, bs9);\n\n  TBZCompressionStream = class(TCustomBZip2Stream)\n  private\n    function GetCompressionRate: Single;\n  public\n    constructor Create(BlockSize100k: TBlockSize100k; Dest: TStream);\n    destructor Destroy; override;\n    function Read(var Buffer; Count: Longint): Longint; override;\n    function Write(const Buffer; Count: Longint): Longint; override;\n    function Seek(const Offset: Int64; Origin: TSeekOrigin): Int64; override;\n    property CompressionRate: Single read GetCompressionRate;\n    property OnProgress;\n  end;\n\n{ TDecompressionStream decompresses data on the fly as data is read from it.\n\n  Compressed data comes from a separate source stream.  TDecompressionStream\n  is read-only and unidirectional; you can seek forward in the stream, but not\n  backwards.  The special case of setting the stream position to zero is\n  allowed.  Seeking forward decompresses data until the requested position in\n  the uncompressed data has been reached.  Seeking backwards, seeking relative\n  to the end of the stream, requesting the size of the stream, and writing to\n  the stream will raise an exception.\n\n  The Position property returns the number of bytes of uncompressed data that\n  have been read from the stream so far.\n\n  The OnProgress event is called each time the internal input buffer of\n  compressed data is exhausted and the next block is read from the input stream.\n  This is useful for updating a progress indicator when you are reading a\n  large chunk of data from the decompression stream in a single call.}\n\n  TBZDecompressionStream = class(TCustomBZip2Stream)\n  public\n    constructor Create(Source: TStream);\n    destructor Destroy; override;\n    function Read(var Buffer; Count: Longint): Longint; override;\n    function Write(const Buffer; Count: Longint): Longint; override;\n    function Seek(const Offset: Int64; Origin: TSeekOrigin): Int64; override;\n    property OnProgress;\n  end;\n\n{ CompressBuf compresses data, buffer to buffer, in one call.\n   In: InBuf = ptr to compressed data\n       InBytes = number of bytes in InBuf\n  Out: OutBuf = ptr to newly allocated buffer containing decompressed data\n       OutBytes = number of bytes in OutBuf   }\nprocedure BZCompressBuf(const InBuf: Pointer; InBytes: Integer;\n  out OutBuf: Pointer; out OutBytes: Integer);\n\n\n{ DecompressBuf decompresses data, buffer to buffer, in one call.\n   In: InBuf = ptr to compressed data\n       InBytes = number of bytes in InBuf\n       OutEstimate = zero, or est. size of the decompressed data\n  Out: OutBuf = ptr to newly allocated buffer containing decompressed data\n       OutBytes = number of bytes in OutBuf   }\nprocedure BZDecompressBuf(const InBuf: Pointer; InBytes: Integer;\n  OutEstimate: Integer; out OutBuf: Pointer; out OutBytes: Integer);\n\n\ntype\n  EBZip2Error = class(Exception);\n  EBZCompressionError = class(EBZip2Error);\n  EBZDecompressionError = class(EBZip2Error);\n\nimplementation\n\n// Compile for Win64 using MSVC\n//   <Path To MSVC>\\bin\\x86_amd64\\cl.exe -c -nologo -GS- -Z7 -wd4086 -Gs32768\n//      -DBZ_NO_STDIO blocksort.c huffman.c compress.c decompress.c bzlib.c\n\nuses\n{$IFDEF Bzip2Runtime}\n{$IF DEFINED(FPC)}\n  dynlibs,\n{$ELSEIF DEFINED(MSWINDOWS)}\n  Windows,\n{$IFEND}\n{$ENDIF}\n  AbUtils;\n\n{$IFDEF Bzip2Static}\n{$IF DEFINED(WIN32)}\n  {$L Win32\\blocksort.obj}\n  {$L Win32\\huffman.obj}\n  {$L Win32\\compress.obj}\n  {$L Win32\\decompress.obj}\n  {$L Win32\\bzlib.obj}\n{$ELSEIF DEFINED(WIN64)}\n  {$L Win64\\blocksort.obj}\n  {$L Win64\\huffman.obj}\n  {$L Win64\\compress.obj}\n  {$L Win64\\decompress.obj}\n  {$L Win64\\bzlib.obj}\n{$IFEND}\n\nprocedure BZ2_hbMakeCodeLengths; external;\nprocedure BZ2_blockSort; external;\nprocedure BZ2_hbCreateDecodeTables; external;\nprocedure BZ2_hbAssignCodes; external;\nprocedure BZ2_compressBlock; external;\nprocedure BZ2_decompress; external;\n{$ENDIF}\n\ntype\n  TLargeInteger = record\n    case Integer of\n    0: (\n      LowPart: LongWord;\n      HighPart: LongWord);\n    1: (\n      QuadPart: Int64);\n  end;\n\nconst\n  BZ_RUN = 0;\n  BZ_FLUSH = 1;\n  BZ_FINISH = 2;\n  BZ_OK = 0;\n  BZ_RUN_OK = 1;\n  BZ_FLUSH_OK = 2;\n  BZ_FINISH_OK = 3;\n  BZ_STREAM_END = 4;\n  BZ_SEQUENCE_ERROR = (-1);\n  BZ_PARAM_ERROR = (-2);\n  BZ_MEM_ERROR = (-3);\n  BZ_DATA_ERROR = (-4);\n  BZ_DATA_ERROR_MAGIC = (-5);\n  BZ_IO_ERROR = (-6);\n  BZ_UNEXPECTED_EOF = (-7);\n  BZ_OUTBUFF_FULL = (-8);\n\n  BZ_BLOCK_SIZE_100K = 9;\n\n{$IFDEF Bzip2Static}\n  BZ2_rNums: array[0..511] of Longint = (\n    619, 720, 127, 481, 931, 816, 813, 233, 566, 247,\n    985, 724, 205, 454, 863, 491, 741, 242, 949, 214,\n    733, 859, 335, 708, 621, 574, 73, 654, 730, 472,\n    419, 436, 278, 496, 867, 210, 399, 680, 480, 51,\n    878, 465, 811, 169, 869, 675, 611, 697, 867, 561,\n    862, 687, 507, 283, 482, 129, 807, 591, 733, 623,\n    150, 238, 59, 379, 684, 877, 625, 169, 643, 105,\n    170, 607, 520, 932, 727, 476, 693, 425, 174, 647,\n    73, 122, 335, 530, 442, 853, 695, 249, 445, 515,\n    909, 545, 703, 919, 874, 474, 882, 500, 594, 612,\n    641, 801, 220, 162, 819, 984, 589, 513, 495, 799,\n    161, 604, 958, 533, 221, 400, 386, 867, 600, 782,\n    382, 596, 414, 171, 516, 375, 682, 485, 911, 276,\n    98, 553, 163, 354, 666, 933, 424, 341, 533, 870,\n    227, 730, 475, 186, 263, 647, 537, 686, 600, 224,\n    469, 68, 770, 919, 190, 373, 294, 822, 808, 206,\n    184, 943, 795, 384, 383, 461, 404, 758, 839, 887,\n    715, 67, 618, 276, 204, 918, 873, 777, 604, 560,\n    951, 160, 578, 722, 79, 804, 96, 409, 713, 940,\n    652, 934, 970, 447, 318, 353, 859, 672, 112, 785,\n    645, 863, 803, 350, 139, 93, 354, 99, 820, 908,\n    609, 772, 154, 274, 580, 184, 79, 626, 630, 742,\n    653, 282, 762, 623, 680, 81, 927, 626, 789, 125,\n    411, 521, 938, 300, 821, 78, 343, 175, 128, 250,\n    170, 774, 972, 275, 999, 639, 495, 78, 352, 126,\n    857, 956, 358, 619, 580, 124, 737, 594, 701, 612,\n    669, 112, 134, 694, 363, 992, 809, 743, 168, 974,\n    944, 375, 748, 52, 600, 747, 642, 182, 862, 81,\n    344, 805, 988, 739, 511, 655, 814, 334, 249, 515,\n    897, 955, 664, 981, 649, 113, 974, 459, 893, 228,\n    433, 837, 553, 268, 926, 240, 102, 654, 459, 51,\n    686, 754, 806, 760, 493, 403, 415, 394, 687, 700,\n    946, 670, 656, 610, 738, 392, 760, 799, 887, 653,\n    978, 321, 576, 617, 626, 502, 894, 679, 243, 440,\n    680, 879, 194, 572, 640, 724, 926, 56, 204, 700,\n    707, 151, 457, 449, 797, 195, 791, 558, 945, 679,\n    297, 59, 87, 824, 713, 663, 412, 693, 342, 606,\n    134, 108, 571, 364, 631, 212, 174, 643, 304, 329,\n    343, 97, 430, 751, 497, 314, 983, 374, 822, 928,\n    140, 206, 73, 263, 980, 736, 876, 478, 430, 305,\n    170, 514, 364, 692, 829, 82, 855, 953, 676, 246,\n    369, 970, 294, 750, 807, 827, 150, 790, 288, 923,\n    804, 378, 215, 828, 592, 281, 565, 555, 710, 82,\n    896, 831, 547, 261, 524, 462, 293, 465, 502, 56,\n    661, 821, 976, 991, 658, 869, 905, 758, 745, 193,\n    768, 550, 608, 933, 378, 286, 215, 979, 792, 961,\n    61, 688, 793, 644, 986, 403, 106, 366, 905, 644,\n    372, 567, 466, 434, 645, 210, 389, 550, 919, 135,\n    780, 773, 635, 389, 707, 100, 626, 958, 165, 504,\n    920, 176, 193, 713, 857, 265, 203, 50, 668, 108,\n    645, 990, 626, 197, 510, 357, 358, 850, 858, 364,\n    936, 638\n    );\n\n  BZ2_crc32Table: array[0..255] of Longint = (\n    $00000000, $04C11DB7, $09823B6E, $0D4326D9,\n    $130476DC, $17C56B6B, $1A864DB2, $1E475005,\n    $2608EDB8, $22C9F00F, $2F8AD6D6, $2B4BCB61,\n    $350C9B64, $31CD86D3, $3C8EA00A, $384FBDBD,\n    $4C11DB70, $48D0C6C7, $4593E01E, $4152FDA9,\n    $5F15ADAC, $5BD4B01B, $569796C2, $52568B75,\n    $6A1936C8, $6ED82B7F, $639B0DA6, $675A1011,\n    $791D4014, $7DDC5DA3, $709F7B7A, $745E66CD,\n    -$67DC4920, -$631D54A9, -$6E5E7272, -$6A9F6FC7,\n    -$74D83FC4, -$70192275, -$7D5A04AE, -$799B191B,\n    -$41D4A4A8, -$4515B911, -$48569FCA, -$4C97827F,\n    -$52D0D27C, -$5611CFCD, -$5B52E916, -$5F93F4A3,\n    -$2BCD9270, -$2F0C8FD9, -$224FA902, -$268EB4B7,\n    -$38C9E4B4, -$3C08F905, -$314BDFDE, -$358AC26B,\n    -$0DC57FD8, -$09046261, -$044744BA, -$0086590F,\n    -$1EC1090C, -$1A0014BD, -$17433266, -$13822FD3,\n    $34867077, $30476DC0, $3D044B19, $39C556AE,\n    $278206AB, $23431B1C, $2E003DC5, $2AC12072,\n    $128E9DCF, $164F8078, $1B0CA6A1, $1FCDBB16,\n    $018AEB13, $054BF6A4, $0808D07D, $0CC9CDCA,\n    $7897AB07, $7C56B6B0, $71159069, $75D48DDE,\n    $6B93DDDB, $6F52C06C, $6211E6B5, $66D0FB02,\n    $5E9F46BF, $5A5E5B08, $571D7DD1, $53DC6066,\n    $4D9B3063, $495A2DD4, $44190B0D, $40D816BA,\n    -$535A3969, -$579B24E0, -$5AD80207, -$5E191FB2,\n    -$405E4FB5, -$449F5204, -$49DC74DB, -$4D1D696E,\n    -$7552D4D1, -$7193C968, -$7CD0EFBF, -$7811F20A,\n    -$6656A20D, -$6297BFBC, -$6FD49963, -$6B1584D6,\n    -$1F4BE219, -$1B8AFFB0, -$16C9D977, -$1208C4C2,\n    -$0C4F94C5, -$088E8974, -$05CDAFAB, -$010CB21E,\n    -$39430FA1, -$3D821218, -$30C134CF, -$3400297A,\n    -$2A47797D, -$2E8664CC, -$23C54213, -$27045FA6,\n    $690CE0EE, $6DCDFD59, $608EDB80, $644FC637,\n    $7A089632, $7EC98B85, $738AAD5C, $774BB0EB,\n    $4F040D56, $4BC510E1, $46863638, $42472B8F,\n    $5C007B8A, $58C1663D, $558240E4, $51435D53,\n    $251D3B9E, $21DC2629, $2C9F00F0, $285E1D47,\n    $36194D42, $32D850F5, $3F9B762C, $3B5A6B9B,\n    $0315D626, $07D4CB91, $0A97ED48, $0E56F0FF,\n    $1011A0FA, $14D0BD4D, $19939B94, $1D528623,\n    -$0ED0A9F2, -$0A11B447, -$075292A0, -$03938F29,\n    -$1DD4DF2E, -$1915C29B, -$1456E444, -$1097F9F5,\n    -$28D8444A, -$2C1959FF, -$215A7F28, -$259B6291,\n    -$3BDC3296, -$3F1D2F23, -$325E09FC, -$369F144D,\n    -$42C17282, -$46006F37, -$4B4349F0, -$4F825459,\n    -$51C5045E, -$550419EB, -$58473F34, -$5C862285,\n    -$64C99F3A, -$6008828F, -$6D4BA458, -$698AB9E1,\n    -$77CDE9E6, -$730CF453, -$7E4FD28C, -$7A8ECF3D,\n    $5D8A9099, $594B8D2E, $5408ABF7, $50C9B640,\n    $4E8EE645, $4A4FFBF2, $470CDD2B, $43CDC09C,\n    $7B827D21, $7F436096, $7200464F, $76C15BF8,\n    $68860BFD, $6C47164A, $61043093, $65C52D24,\n    $119B4BE9, $155A565E, $18197087, $1CD86D30,\n    $029F3D35, $065E2082, $0B1D065B, $0FDC1BEC,\n    $3793A651, $3352BBE6, $3E119D3F, $3AD08088,\n    $2497D08D, $2056CD3A, $2D15EBE3, $29D4F654,\n    -$3A56D987, -$3E97C432, -$33D4E2E9, -$3715FF60,\n    -$2952AF5B, -$2D93B2EE, -$20D09435, -$24118984,\n    -$1C5E343F, -$189F298A, -$15DC0F51, -$111D12E8,\n    -$0F5A42E3, -$0B9B5F56, -$06D8798D, -$0219643C,\n    -$764702F7, -$72861F42, -$7FC53999, -$7B042430,\n    -$6543742B, -$6182699E, -$6CC14F45, -$680052F4,\n    -$504FEF4F, -$548EF2FA, -$59CDD421, -$5D0CC998,\n    -$434B9993, -$478A8426, -$4AC9A2FD, -$4E08BF4C\n    );\n\nprocedure bz_internal_error(errcode: Integer); cdecl;\nbegin\n  raise EBZip2Error.CreateFmt('Compression Error %d', [errcode]);\nend; { _bz_internal_error }\n\nfunction malloc(size: Integer): Pointer; cdecl;\nbegin\n  GetMem(Result, Size);\nend; { _malloc }\n\nprocedure free(block: Pointer); cdecl;\nbegin\n  FreeMem(block);\nend; { _free }\n{$ENDIF}\n\nconst\n  libbz2 = {$IF DEFINED(MSWINDOWS)}'libbz2.dll'\n           {$ELSEIF DEFINED(DARWIN)}'libbz2.dylib'\n           {$ELSE}'libbz2.so.1'{$IFEND};\n\n{$IFDEF Bzip2Runtime}\nvar\n  hBzip2: HMODULE;\n  // deflate compresses data\n  BZ2_bzCompressInit: function(var strm: TBZStreamRec; blockSize100k: Integer;\n    verbosity: Integer; workFactor: Integer): Integer;\n    {$IFDEF MSWINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}\n  BZ2_bzCompress: function(var strm: TBZStreamRec; action: Integer): Integer;\n    {$IFDEF MSWINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}\n  BZ2_bzCompressEnd: function (var strm: TBZStreamRec): Integer;\n    {$IFDEF MSWINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}\n  BZ2_bzBuffToBuffCompress: function(dest: Pointer; var destLen: Integer;\n    source: Pointer; sourceLen, blockSize100k, verbosity, workFactor: Integer): Integer;\n    {$IFDEF MSWINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}\n  // inflate decompresses data\n  BZ2_bzDecompressInit: function(var strm: TBZStreamRec; verbosity: Integer;\n    small: Integer): Integer;\n    {$IFDEF MSWINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}\n  BZ2_bzDecompress: function(var strm: TBZStreamRec): Integer;\n    {$IFDEF MSWINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}\n  BZ2_bzDecompressEnd: function(var strm: TBZStreamRec): Integer;\n    {$IFDEF MSWINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}\n  BZ2_bzBuffToBuffDecompress: function(dest: Pointer; var destLen: Integer;\n    source: Pointer; sourceLen, small, verbosity: Integer): Integer;\n    {$IFDEF MSWINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}\n{$ELSE}\n// deflate compresses data\nfunction BZ2_bzCompressInit(var strm: TBZStreamRec; blockSize100k: Integer;\n  verbosity: Integer; workFactor: Integer): Integer;\n  {$IFDEF MSWINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF} external {$IFDEF Bzip2Dynamic}libbz2{$ENDIF}\n  {$IFDEF DARWIN}name '_BZ2_bzCompressInit'{$ENDIF};\n\nfunction BZ2_bzCompress(var strm: TBZStreamRec; action: Integer): Integer;\n  {$IFDEF MSWINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF} external {$IFDEF Bzip2Dynamic}libbz2{$ENDIF}\n  {$IFDEF DARWIN}name '_BZ2_bzCompress'{$ENDIF};\n\nfunction BZ2_bzCompressEnd(var strm: TBZStreamRec): Integer;\n  {$IFDEF MSWINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF} external {$IFDEF Bzip2Dynamic}libbz2{$ENDIF}\n  {$IFDEF DARWIN}name '_BZ2_bzCompressEnd'{$ENDIF};\n\nfunction BZ2_bzBuffToBuffCompress(dest: Pointer; var destLen: Integer; source: Pointer;\n  sourceLen, blockSize100k, verbosity, workFactor: Integer): Integer;\n  {$IFDEF MSWINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF} external {$IFDEF Bzip2Dynamic}libbz2{$ENDIF}\n  {$IFDEF DARWIN}name '_BZ2_bzBuffToBuffCompress'{$ENDIF};\n\n// inflate decompresses data\nfunction BZ2_bzDecompressInit(var strm: TBZStreamRec; verbosity: Integer;\n  small: Integer): Integer;\n  {$IFDEF MSWINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF} external {$IFDEF Bzip2Dynamic}libbz2{$ENDIF}\n  {$IFDEF DARWIN}name '_BZ2_bzDecompressInit'{$ENDIF};\n\nfunction BZ2_bzDecompress(var strm: TBZStreamRec): Integer;\n  {$IFDEF MSWINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF} external {$IFDEF Bzip2Dynamic}libbz2{$ENDIF}\n  {$IFDEF DARWIN}name '_BZ2_bzDecompress'{$ENDIF};\n\nfunction BZ2_bzDecompressEnd(var strm: TBZStreamRec): Integer;\n  {$IFDEF MSWINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF} external {$IFDEF Bzip2Dynamic}libbz2{$ENDIF}\n  {$IFDEF DARWIN}name '_BZ2_bzDecompressEnd'{$ENDIF};\n\nfunction BZ2_bzBuffToBuffDecompress(dest: Pointer; var destLen: Integer; source: Pointer;\n  sourceLen, small, verbosity: Integer): Integer;\n  {$IFDEF MSWINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF} external {$IFDEF Bzip2Dynamic}libbz2{$ENDIF}\n  {$IFDEF DARWIN}name '_BZ2_bzBuffToBuffDecompress'{$ENDIF};\n{$ENDIF}\n\nprocedure LoadBzip2DLL;\nbegin\n  {$IFDEF Bzip2Runtime}\n  if hBzip2 <> 0 then\n    Exit;\n  hBzip2 := LoadLibrary(libbz2);\n  if hBzip2 = 0 then\n    raise EBZip2Error.Create('Bzip2 shared library not found');\n  @BZ2_bzCompressInit := GetProcAddress(hBzip2, 'BZ2_bzCompressInit');\n  @BZ2_bzCompress := GetProcAddress(hBzip2, 'BZ2_bzCompress');\n  @BZ2_bzCompressEnd := GetProcAddress(hBzip2, 'BZ2_bzCompressEnd');\n  @BZ2_bzBuffToBuffCompress := GetProcAddress(hBzip2, 'BZ2_bzBuffToBuffCompress');\n  @BZ2_bzDecompressInit := GetProcAddress(hBzip2, 'BZ2_bzDecompressInit');\n  @BZ2_bzDecompress := GetProcAddress(hBzip2, 'BZ2_bzDecompress');\n  @BZ2_bzDecompressEnd := GetProcAddress(hBzip2, 'BZ2_bzDecompressEnd');\n  @BZ2_bzBuffToBuffDecompress := GetProcAddress(hBzip2, 'BZ2_bzBuffToBuffDecompress');\n  {$ENDIF}\nend;\n\nfunction bzip2AllocMem(AppData: Pointer; Items, Size: Integer): Pointer; cdecl;\nbegin\n  GetMem(Result, Items * Size);\nend; { bzip2AllocMem }\n\nprocedure bzip2FreeMem(AppData, Block: Pointer); cdecl;\nbegin\n  FreeMem(Block);\nend; { bzip2FreeMem }\n\nfunction CCheck(code: Integer): Integer;\nbegin\n  Result := code;\n  if code < 0 then\n    raise EBZCompressionError.CreateFmt('error %d', [code]); //!!\nend; { CCheck }\n\nfunction DCheck(code: Integer): Integer;\nbegin\n  Result := code;\n  if code < 0 then\n    raise EBZDecompressionError.CreateFmt('error %d', [code]); //!!\nend; { DCheck }\n\nprocedure BZCompressBuf(const InBuf: Pointer; InBytes: Integer;\n  out OutBuf: Pointer; out OutBytes: Integer);\nvar\n  strm: TBZStreamRec;\n  P: Pointer;\nbegin\n  LoadBzip2DLL;\n  FillChar(strm, sizeof(strm), 0);\n  strm.bzalloc := bzip2AllocMem;\n  strm.bzfree := bzip2FreeMem;\n  OutBytes := ((InBytes + (InBytes div 10) + 12) + 255) and not 255;\n  GetMem(OutBuf, OutBytes);\n  try\n    strm.next_in := InBuf;\n    strm.avail_in := InBytes;\n    strm.next_out := OutBuf;\n    strm.avail_out := OutBytes;\n    CCheck(BZ2_bzCompressInit(strm, 9, 0, 0));\n    try\n      while CCheck(BZ2_bzCompress(strm, BZ_FINISH)) <> BZ_STREAM_END do\n      begin\n        P := OutBuf;\n        Inc(OutBytes, 256);\n        ReallocMem(OutBuf, OutBytes);\n        strm.next_out := PByte(PtrInt(OutBuf)\n             + (PtrInt(strm.next_out) - PtrInt(P)));\n        strm.avail_out := 256;\n      end;\n    finally\n      CCheck(BZ2_bzCompressEnd(strm));\n    end;\n    ReallocMem(OutBuf, strm.total_out_lo32);\n    OutBytes := strm.total_out_lo32;\n  except\n    FreeMem(OutBuf);\n    raise\n  end;\nend;\n\nprocedure BZDecompressBuf(const InBuf: Pointer; InBytes: Integer;\n  OutEstimate: Integer; out OutBuf: Pointer; out OutBytes: Integer);\nvar\n  strm: TBZStreamRec;\n  P: Pointer;\n  BufInc: Integer;\nbegin\n  LoadBzip2DLL;\n  FillChar(strm, sizeof(strm), 0);\n  strm.bzalloc := bzip2AllocMem;\n  strm.bzfree := bzip2FreeMem;\n  BufInc := (InBytes + 255) and not 255;\n  if OutEstimate = 0 then\n    OutBytes := BufInc\n  else\n    OutBytes := OutEstimate;\n  GetMem(OutBuf, OutBytes);\n  try\n    strm.next_in := InBuf;\n    strm.avail_in := InBytes;\n    strm.next_out := OutBuf;\n    strm.avail_out := OutBytes;\n    DCheck(BZ2_bzDecompressInit(strm, 0, 0));\n    try\n      while DCheck(BZ2_bzDecompress(strm)) <> BZ_STREAM_END do\n      begin\n        P := OutBuf;\n        Inc(OutBytes, BufInc);\n        ReallocMem(OutBuf, OutBytes);\n        strm.next_out := PByte(PtrInt(OutBuf) + (PtrInt(strm.next_out) - PtrInt(P)));\n        strm.avail_out := BufInc;\n      end;\n    finally\n      DCheck(BZ2_bzDecompressEnd(strm));\n    end;\n    ReallocMem(OutBuf, strm.total_out_lo32);\n    OutBytes := strm.total_out_lo32;\n  except\n    FreeMem(OutBuf);\n    raise\n  end;\nend;\n\n// TCustomBZip2Stream\n\nconstructor TCustomBZip2Stream.Create(Strm: TStream);\nbegin\n  inherited Create;\n  FStrm := Strm;\n  FStrmPos := Strm.Position;\n  FBZRec.bzalloc := bzip2AllocMem;\n  FBZRec.bzfree := bzip2FreeMem;\nend;\n\nprocedure TCustomBZip2Stream.Progress(Sender: TObject);\nbegin\n  if Assigned(FOnProgress) then FOnProgress(Sender);\nend; { TCustomBZip2Stream }\n\n\n// TBZCompressionStream\n\nconstructor TBZCompressionStream.Create(BlockSize100k: TBlockSize100k; Dest: TStream);\nconst\n  BlockSizes: array[TBlockSize100k] of ShortInt = (1, 2, 3, 4, 5, 6, 7, 8, 9);\nbegin\n  inherited Create(Dest);\n  LoadBzip2DLL;\n  FBZRec.next_out := @FBuffer[0];\n  FBZRec.avail_out := sizeof(FBuffer);\n  CCheck(BZ2_bzCompressInit(FBZRec, BlockSizes[BlockSize100k], 0, 0));\nend;\n\ndestructor TBZCompressionStream.Destroy;\nbegin\n  if FBZRec.state <> nil then begin\n    FBZRec.next_in := nil;\n    FBZRec.avail_in := 0;\n    try\n      if FStrm.Position <> FStrmPos then FStrm.Position := FStrmPos;\n      while (CCheck(BZ2_bzCompress(FBZRec, BZ_FINISH)) <> BZ_STREAM_END)\n        and (FBZRec.avail_out = 0) do\n      begin\n        FStrm.WriteBuffer(FBuffer, sizeof(FBuffer));\n        FBZRec.next_out := @FBuffer[0];\n        FBZRec.avail_out := sizeof(FBuffer);\n      end;\n      if FBZRec.avail_out < sizeof(FBuffer) then\n        FStrm.WriteBuffer(FBuffer, sizeof(FBuffer) - FBZRec.avail_out);\n    finally\n      BZ2_bzCompressEnd(FBZRec);\n    end;\n  end;\n  inherited Destroy;\nend;\n\nfunction TBZCompressionStream.Read(var Buffer; Count: Longint): Longint;\nbegin\n  raise EBZCompressionError.Create('Invalid stream operation');\nend; { TBZCompressionStream }\n\nfunction TBZCompressionStream.Write(const Buffer; Count: Longint): Longint;\nbegin\n  FBZRec.next_in := @Buffer;\n  FBZRec.avail_in := Count;\n  if FStrm.Position <> FStrmPos then FStrm.Position := FStrmPos;\n  while (FBZRec.avail_in > 0) do\n  begin\n    CCheck(BZ2_bzCompress(FBZRec, BZ_RUN));\n    if FBZRec.avail_out = 0 then\n    begin\n      FStrm.WriteBuffer(FBuffer, sizeof(FBuffer));\n      FBZRec.next_out := @FBuffer[0];\n      FBZRec.avail_out := sizeof(FBuffer);\n      FStrmPos := FStrm.Position;\n    end;\n    Progress(Self);\n  end;\n  Result := Count;\nend; { TBZCompressionStream }\n\nfunction TBZCompressionStream.Seek(const Offset: Int64; Origin: TSeekOrigin): Int64;\nvar\n  conv64 : TLargeInteger;\nbegin\n  if (Offset = 0) and (Origin = soCurrent) then begin\n    conv64.LowPart  := FBZRec.total_in_lo32;\n    conv64.HighPart := FBZRec.total_in_hi32;\n    Result := conv64.QuadPart\n    end\n  else\n    raise EBZCompressionError.Create('Invalid stream operation');\nend; { TBZCompressionStream }\n\nfunction TBZCompressionStream.GetCompressionRate: Single;\nvar\n  conv64In : TLargeInteger;\n  conv64Out: TLargeInteger;\nbegin\n  conv64In.LowPart   := FBZRec.total_in_lo32;\n  conv64In.HighPart  := FBZRec.total_in_hi32;\n  conv64Out.LowPart  := FBZRec.total_out_lo32;\n  conv64Out.HighPart := FBZRec.total_out_hi32;\n\n  if conv64In.QuadPart = 0 then\n    Result := 0\n  else\n    Result := (1.0 - (conv64Out.QuadPart / conv64In.QuadPart)) * 100.0;\nend; { TBZCompressionStream }\n\n// TDecompressionStream\n\nconstructor TBZDecompressionStream.Create(Source: TStream);\nbegin\n  inherited Create(Source);\n  LoadBzip2DLL;\n  FBZRec.next_in := @FBuffer[0];\n  FBZRec.avail_in := 0;\n  DCheck(BZ2_bzDecompressInit(FBZRec, 0, 0));\nend;\n\ndestructor TBZDecompressionStream.Destroy;\nbegin\n  if FBZRec.state <> nil then\n    BZ2_bzDecompressEnd(FBZRec);\n  inherited Destroy;\nend;\n\nfunction TBZDecompressionStream.Read(var Buffer; Count: Longint): Longint;\nbegin\n  FBZRec.next_out := @Buffer;\n  FBZRec.avail_out := Count;\n  if FStrm.Position <> FStrmPos then FStrm.Position := FStrmPos;\n  while (FBZRec.avail_out > 0) do\n  begin\n    if FBZRec.avail_in = 0 then\n    begin\n      FBZRec.avail_in := FStrm.Read(FBuffer, sizeof(FBuffer));\n      if FBZRec.avail_in = 0 then\n      begin\n        Result := Count - FBZRec.avail_out;\n        Exit;\n      end;\n      FBZRec.next_in := @FBuffer[0];\n      FStrmPos := FStrm.Position;\n    end;\n    CCheck(BZ2_bzDecompress(FBZRec));\n    Progress(Self);\n  end;\n  Result := Count;\nend; { TBZDecompressionStream }\n\nfunction TBZDecompressionStream.Write(const Buffer; Count: Longint): Longint;\nbegin\n  raise EBZDecompressionError.Create('Invalid stream operation');\nend; { TBZDecompressionStream }\n\nfunction TBZDecompressionStream.Seek(const Offset: Int64; Origin: TSeekOrigin): Int64;\nvar\n  I     : Integer;\n  Buf   : array[0..4095] of Char;\n  conv64: TLargeInteger;\n  NewOff: Int64;\nbegin\n  conv64.LowPart  := FBZRec.total_out_lo32;\n  conv64.HighPart := FBZRec.total_out_hi32;\n\n  if (Offset = 0) and (Origin = soBeginning) then\n  begin\n    DCheck(BZ2_bzDecompressEnd(FBZRec));\n    DCheck(BZ2_bzDecompressInit(FBZRec, 0, 0));\n    FBZRec.next_in := @FBuffer[0];\n    FBZRec.avail_in := 0;\n    FStrm.Position := 0;\n    FStrmPos := 0;\n  end\n  else if ((Offset >= 0) and (Origin = soCurrent)) or\n    (((Offset - conv64.QuadPart) > 0) and (Origin = soBeginning)) then\n  begin\n    NewOff := Offset;\n    if Origin = soBeginning then Dec(NewOff, conv64.QuadPart);\n    if NewOff > 0 then\n    begin\n      for I := 1 to NewOff div sizeof(Buf) do\n        ReadBuffer(Buf, sizeof(Buf));\n      ReadBuffer(Buf, NewOff mod sizeof(Buf));\n    end;\n  end\n  else\n    raise EBZDecompressionError.Create('Invalid stream operation');\n  Result := conv64.QuadPart;\nend; { TBZDecompressionStream }\n\nend.\n"
  },
  {
    "path": "lib/abbrevia/source/AbBzip2Typ.pas",
    "content": "(* ***** BEGIN LICENSE BLOCK *****\n * Version: MPL 1.1\n *\n * The contents of this file are subject to the Mozilla Public License Version\n * 1.1 (the \"License\"); you may not use this file except in compliance with\n * the License. You may obtain a copy of the License at\n * http://www.mozilla.org/MPL/\n *\n * Software distributed under the License is distributed on an \"AS IS\" basis,\n * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License\n * for the specific language governing rights and limitations under the\n * License.\n *\n * The Original Code is TurboPower Abbrevia\n *\n * The Initial Developer of the Original Code is\n * Joel Haynie\n * Craig Peterson\n *\n * Portions created by the Initial Developer are Copyright (C) 1997-2002\n * the Initial Developer. All Rights Reserved.\n *\n * Contributor(s):\n *\n * ***** END LICENSE BLOCK ***** *)\n\n{*********************************************************}\n{* ABBREVIA: AbBzip2Typ.pas                              *}\n{*********************************************************}\n{* ABBREVIA: TAbBzip2Archive, TAbBzip2Item classes       *}\n{*********************************************************}\n{* Misc. constants, types, and routines for working      *}\n{* with Bzip2 files                                      *}\n{*********************************************************}\n\nunit AbBzip2Typ;\n\n{$I AbDefine.inc}\n\ninterface\n\nuses\n  Classes,\n  AbArcTyp, AbTarTyp, AbUtils;\n\nconst\n  { Default Stream Header for Bzip2s is 'BZhX', where X is the block size setting 1-9 in ASCII }\n  { Each block has the following header: '1AY&SY', and are in units of 100kilobytes NOT 100kibiBytes }\n  AB_BZIP2_FILE_HEADER  = 'BZh';\n  AB_BZIP2_BLOCK_SIZE   = ['1','2','3','4','5','6','7','8','9'];\n  AB_BZIP2_BLOCK_HEADER = '1AY&SY'; { Note: $314159265359, BCD for Pi :) }\n  { Note that Blocks are bit aligned, as such the only time you will \"for sure\" see\n    the block header is on the start of stream/File }\n  AB_BZIP2_FILE_TAIL =#23#114#36#83#133#9#0; { $1772245385090, BCD for sqrt(Pi) :) }\n  { This is odd as the blocks are bit allgned so this is a string that is 13*4 bits = 52 bits }\n\ntype\n  PAbBzip2Header = ^TAbBzip2Header; { File Header }\n  TAbBzip2Header = packed record  { SizeOf(TAbBzip2Header) = 10 }\n    FileHeader  : array[0..2] of AnsiChar;{ 'BZh';    $42,5A,68 }\n    BlockSize   : AnsiChar;               { '1'..'9'; $31-$39 }\n    BlockHeader : array[0..5] of AnsiChar;{ '1AY&SY'; $31,41,59,26,53,59 }\n  end;\n\n{ The Purpose for this Item is the placeholder for aaAdd and aaDelete Support. }\n{ For all intents and purposes we could just use a TAbArchiveItem }\ntype\n  TAbBzip2Item = class(TabArchiveItem);\n\n  TAbBzip2ArchiveState = (gsBzip2, gsTar);\n\n  TAbBzip2Archive = class(TAbTarArchive)\n  private\n    FBzip2Stream  : TStream;        { stream for Bzip2 file}\n    FBzip2Item    : TAbArchiveList; { item in bzip2 (only one, but need polymorphism of class)}\n    FTarStream    : TStream;        { stream for possible contained Tar }\n    FTarList      : TAbArchiveList; { items in possible contained Tar }\n    FTarAutoHandle: Boolean;\n    FState        : TAbBzip2ArchiveState;\n    FIsBzippedTar : Boolean;\n\n    procedure DecompressToStream(aStream: TStream);\n    procedure SetTarAutoHandle(const Value: Boolean);\n    procedure SwapToBzip2;\n    procedure SwapToTar;\n\n  protected\n    { Inherited Abstract functions }\n    function CreateItem(const FileSpec : string): TAbArchiveItem; override;\n    procedure ExtractItemAt(Index : Integer; const NewName : string); override;\n    procedure ExtractItemToStreamAt(Index : Integer; aStream : TStream); override;\n    procedure LoadArchive; override;\n    procedure SaveArchive; override;\n    procedure TestItemAt(Index : Integer); override;\n    function GetSupportsEmptyFolders : Boolean; override;\n\n  public {methods}\n    constructor CreateFromStream(aStream : TStream; const aArchiveName : string); override;\n    destructor  Destroy; override;\n\n    procedure DoSpanningMediaRequest(Sender : TObject; ImageNumber : Integer;\n      var ImageName : string; var Abort : Boolean); override;\n\n    { Properties }\n    property TarAutoHandle : Boolean\n      read FTarAutoHandle write SetTarAutoHandle;\n\n    property IsBzippedTar : Boolean\n      read FIsBzippedTar write FIsBzippedTar;\n  end;\n\nfunction VerifyBzip2(Strm : TStream) : TAbArchiveType;\n\nimplementation\n\nuses\n{$IFDEF MSWINDOWS}\n  Windows, // Fix inline warnings\n{$ENDIF}\n  StrUtils, SysUtils,\n  AbBzip2, AbExcept, AbVMStrm, AbBitBkt;\n\n{ ****************** Helper functions Not from Classes Above ***************** }\nfunction VerifyHeader(const Header : TAbBzip2Header) : Boolean;\nbegin\n  Result := (Header.FileHeader = AB_BZIP2_FILE_HEADER) and\n            (Header.BlockSize in AB_BZIP2_BLOCK_SIZE)  and\n            (Header.BlockHeader = AB_BZIP2_BLOCK_HEADER);\nend;\n{ -------------------------------------------------------------------------- }\nfunction VerifyBzip2(Strm : TStream) : TAbArchiveType;\nvar\n  Hdr : TAbBzip2Header;\n  CurPos : int64;\n  DecompStream, TarStream: TStream;\nbegin\n  Result := atUnknown;\n\n  CurPos := Strm.Position;\n  Strm.Seek(0, soBeginning);\n\n  try\n    if (Strm.Read(Hdr, SizeOf(Hdr)) = SizeOf(Hdr)) and VerifyHeader(Hdr) then begin\n      Result := atBzip2;\n      { Check for embedded TAR }\n      Strm.Seek(0, soBeginning);\n      DecompStream := TBZDecompressionStream.Create(Strm);\n      try\n        TarStream := TMemoryStream.Create;\n        try\n          TarStream.CopyFrom(DecompStream, 512 * 2);\n          TarStream.Seek(0, soBeginning);\n          if VerifyTar(TarStream) = atTar then\n            Result := atBzippedTar;\n        finally\n          TarStream.Free;\n        end;\n      finally\n        DecompStream.Free;\n      end;\n    end;\n  except\n    on EReadError do\n      Result := atUnknown;\n  end;\n  Strm.Position := CurPos; { Return to original position. }\nend;\n\n\n{ ****************************** TAbBzip2Archive ***************************** }\nconstructor TAbBzip2Archive.CreateFromStream(aStream: TStream;\n  const aArchiveName: string);\nbegin\n  inherited CreateFromStream(aStream, aArchiveName);\n  FState       := gsBzip2;\n  FBzip2Stream := FStream;\n  FBzip2Item   := FItemList;\n  FTarStream   := TAbVirtualMemoryStream.Create;\n  FTarList     := TAbArchiveList.Create(True);\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbBzip2Archive.SwapToTar;\nbegin\n  FStream   := FTarStream;\n  FItemList := FTarList;\n  FState    := gsTar;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbBzip2Archive.SwapToBzip2;\nbegin\n  FStream   := FBzip2Stream;\n  FItemList := FBzip2Item;\n  FState    := gsBzip2;\nend;\n{ -------------------------------------------------------------------------- }\nfunction TAbBzip2Archive.CreateItem(const FileSpec: string): TAbArchiveItem;\nbegin\n  if IsBzippedTar and TarAutoHandle then begin\n    SwapToTar;\n    Result := inherited CreateItem(FileSpec);\n  end\n  else begin\n    SwapToBzip2;\n    Result := TAbBzip2Item.Create;\n    try\n      Result.DiskFileName := ExpandFileName(FileSpec);\n      Result.FileName := FixName(FileSpec);\n    except\n      Result.Free;\n      raise;\n    end;\n  end;\nend;\n{ -------------------------------------------------------------------------- }\ndestructor TAbBzip2Archive.Destroy;\nbegin\n  SwapToBzip2;\n  FTarList.Free;\n  FTarStream.Free;\n  inherited Destroy;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbBzip2Archive.ExtractItemAt(Index: Integer;\n  const NewName: string);\nvar\n  OutStream : TFileStream;\nbegin\n  if IsBzippedTar and TarAutoHandle then begin\n    SwapToTar;\n    inherited ExtractItemAt(Index, NewName);\n  end\n  else begin\n    SwapToBzip2;\n    OutStream := TFileStream.Create(NewName, fmCreate or fmShareDenyNone);\n    try\n      try\n        ExtractItemToStreamAt(Index, OutStream);\n      finally\n        OutStream.Free;\n      end;\n      { Bz2 doesn't store the last modified time or attributes, so don't set them }\n    except\n      on E : EAbUserAbort do begin\n        FStatus := asInvalid;\n        if FileExists(NewName) then\n          DeleteFile(NewName);\n        raise;\n      end else begin\n        if FileExists(NewName) then\n          DeleteFile(NewName);\n        raise;\n      end;\n    end;\n  end;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbBzip2Archive.ExtractItemToStreamAt(Index: Integer;\n  aStream: TStream);\nbegin\n  if IsBzippedTar and TarAutoHandle then begin\n    SwapToTar;\n    inherited ExtractItemToStreamAt(Index, aStream);\n  end\n  else begin\n    SwapToBzip2;\n    { Index ignored as there's only one item in a Bz2 }\n    DecompressToStream(aStream);\n  end;\nend;\n{ -------------------------------------------------------------------------- }\nfunction TAbBzip2Archive.GetSupportsEmptyFolders : Boolean;\nbegin\n  Result := IsBzippedTar and TarAutoHandle;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbBzip2Archive.LoadArchive;\nvar\n  Item: TAbBzip2Item;\n  Abort: Boolean;\n  ItemName: string;\nbegin\n  if FBzip2Stream.Size = 0 then\n    Exit;\n\n  if IsBzippedTar and TarAutoHandle then begin\n    { Decompress and send to tar LoadArchive }\n    DecompressToStream(FTarStream);\n    SwapToTar;\n    inherited LoadArchive;\n  end\n  else begin\n    SwapToBzip2;\n    Item := TAbBzip2Item.Create;\n    Item.Action := aaNone;\n    { Filename isn't stored, so constuct one based on the archive name }\n    ItemName := ExtractFileName(ArchiveName);\n    if ItemName = '' then\n      Item.FileName := 'unknown'\n    else if AnsiEndsText('.tbz', ItemName) or AnsiEndsText('.tbz2', ItemName) then\n      Item.FileName := ChangeFileExt(ItemName, '.tar')\n    else\n      Item.FileName := ChangeFileExt(ItemName, '');\n    Item.DiskFileName := Item.FileName;\n    FItemList.Add(Item);\n  end;\n  DoArchiveProgress(100, Abort);\n  FIsDirty := False;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbBzip2Archive.SaveArchive;\nvar\n  CompStream: TStream;\n  i: Integer;\n  CurItem: TAbBzip2Item;\n  InputFileStream: TStream;\nbegin\n  if IsBzippedTar and TarAutoHandle then\n  begin\n    SwapToTar;\n    inherited SaveArchive;\n    FTarStream.Position := 0;\n    FBzip2Stream.Size := 0;\n    CompStream := TBZCompressionStream.Create(bs9, FBzip2Stream);\n    try\n      CompStream.CopyFrom(FTarStream, 0);\n    finally\n      CompStream.Free;\n    end;\n  end\n  else begin\n    { Things we know: There is only one file per archive.}\n    { Actions we have to address in SaveArchive: }\n    { aaNone & aaMove do nothing, as the file does not change, only the meta data }\n    { aaDelete could make a zero size file unless there are two files in the list.}\n    { aaAdd, aaStreamAdd, aaFreshen, & aaReplace will be the only ones to take action. }\n    SwapToBzip2;\n    for i := 0 to pred(Count) do begin\n      FCurrentItem := ItemList[i];\n      CurItem      := TAbBzip2Item(ItemList[i]);\n      case CurItem.Action of\n        aaNone, aaMove: Break;{ Do nothing; bz2 doesn't store metadata }\n        aaDelete: ; {doing nothing omits file from new stream}\n        aaAdd, aaFreshen, aaReplace, aaStreamAdd: begin\n          FBzip2Stream.Size := 0;\n          CompStream := TBZCompressionStream.Create(bs9, FBzip2Stream);\n          try\n            if CurItem.Action = aaStreamAdd then\n              CompStream.CopyFrom(InStream, 0){ Copy/compress entire Instream to FBzip2Stream }\n            else begin\n              InputFileStream := TFileStream.Create(CurItem.DiskFileName, fmOpenRead or fmShareDenyWrite );\n              try\n                CompStream.CopyFrom(InputFileStream, 0);{ Copy/compress entire Instream to FBzip2Stream }\n              finally\n                InputFileStream.Free;\n              end;\n            end;\n          finally\n            CompStream.Free;\n          end;\n          Break;\n        end; { End aaAdd, aaFreshen, aaReplace, & aaStreamAdd }\n      end; { End of CurItem.Action Case }\n    end; { End Item for loop }\n  end; { End Tar Else }\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbBzip2Archive.SetTarAutoHandle(const Value: Boolean);\nbegin\n  if Value then\n    SwapToTar\n  else\n    SwapToBzip2;\n  FTarAutoHandle := Value;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbBzip2Archive.DecompressToStream(aStream: TStream);\nconst\n  BufSize = $F000;\nvar\n  DecompStream: TBZDecompressionStream;\n  Buffer: PByte;\n  N: Integer;\nbegin\n  DecompStream := TBZDecompressionStream.Create(FBzip2Stream);\n  try\n    GetMem(Buffer, BufSize);\n    try\n      N := DecompStream.Read(Buffer^, BufSize);\n      while N > 0 do begin\n        aStream.WriteBuffer(Buffer^, N);\n        N := DecompStream.Read(Buffer^, BufSize);\n      end;\n    finally\n      FreeMem(Buffer, BufSize);\n    end;\n  finally\n    DecompStream.Free;\n  end;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbBzip2Archive.TestItemAt(Index: Integer);\nvar\n  Bzip2Type: TAbArchiveType;\n  BitBucket: TAbBitBucketStream;\nbegin\n  if IsBzippedTar and TarAutoHandle then begin\n    SwapToTar;\n    inherited TestItemAt(Index);\n  end\n  else begin\n    { note Index ignored as there's only one item in a GZip }\n    Bzip2Type := VerifyBzip2(FBzip2Stream);\n    if not (Bzip2Type in [atBzip2, atBzippedTar]) then\n      raise EAbGzipInvalid.Create;// TODO: Add bzip2-specific exceptions }\n    BitBucket := TAbBitBucketStream.Create(1024);\n    try\n      DecompressToStream(BitBucket);\n    finally\n      BitBucket.Free;\n    end;\n  end;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbBzip2Archive.DoSpanningMediaRequest(Sender: TObject;\n  ImageNumber: Integer; var ImageName: string; var Abort: Boolean);\nbegin\n  Abort := False;\nend;\n\nend.\n"
  },
  {
    "path": "lib/abbrevia/source/AbCBrows.pas",
    "content": "(* ***** BEGIN LICENSE BLOCK *****\n * Version: MPL 1.1\n *\n * The contents of this file are subject to the Mozilla Public License Version\n * 1.1 (the \"License\"); you may not use this file except in compliance with\n * the License. You may obtain a copy of the License at\n * http://www.mozilla.org/MPL/\n *\n * Software distributed under the License is distributed on an \"AS IS\" basis,\n * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License\n * for the specific language governing rights and limitations under the\n * License.\n *\n * The Original Code is TurboPower Abbrevia\n *\n * The Initial Developer of the Original Code is\n * TurboPower Software\n *\n * Portions created by the Initial Developer are Copyright (C) 1997-2002\n * the Initial Developer. All Rights Reserved.\n *\n * Contributor(s):\n *\n * ***** END LICENSE BLOCK ***** *)\n\n{*********************************************************}\n{* ABBREVIA: AbCBrows.pas                                *}\n{*********************************************************}\n{* ABBREVIA: Cabinet file browser component              *}\n{*********************************************************}\n\nunit AbCBrows;\n\n{$I AbDefine.inc}\n\ninterface\n\nuses\n  Classes,\n  AbBrowse,\n  AbCabTyp;\n\ntype\n  TAbCustomCabBrowser = class(TAbBaseBrowser)\n  protected {private}\n    FSetID : Word;\n\n    function  GetCabArchive : TAbCabArchive;\n    function  GetCabSize : Longint;\n    function  GetCurrentCab : Word;\n    function  GetFolderCount : Word;\n    function  GetItem(Index : Integer) : TAbCabItem; virtual;\n    function  GetHasNext : Boolean;\n    function  GetHasPrev : Boolean;\n    function  GetSetID : Word;\n    procedure InitArchive;\n      override;\n    procedure SetFileName(const aFileName : string); override;\n    procedure SetSetID(Value : Word);\n\n  protected {properties}\n    property CabSize : Longint\n      read GetCabSize;\n    property CurrentCab : Word\n      read GetCurrentCab;\n    property FolderCount : Word\n      read GetFolderCount;\n    property HasNext : Boolean\n      read GetHasNext;\n    property HasPrev : Boolean\n      read GetHasPrev;\n    property SetID : Word\n      read GetSetID\n      write SetSetID;\n\n  public {methods}\n    constructor Create(AOwner : TComponent);\n      override;\n    destructor Destroy;\n      override;\n\n  public {properties}\n    property CabArchive : TAbCabArchive\n      read  GetCabArchive;\n    property Items[Index : Integer] : TAbCabItem\n      read  GetItem; default;\n  end;\n\n\ntype\n  {$IFDEF HasPlatformsAttribute}\n  [ComponentPlatformsAttribute(pidWin32 or pidWin64)]\n  {$ENDIF}\n  TAbCabBrowser = class(TAbCustomCabBrowser)\n  published\n    property ArchiveProgressMeter;\n    property BaseDirectory;\n    property CabSize;\n    property CurrentCab;\n    property FolderCount;\n    property HasNext;\n    property HasPrev;\n    property ItemProgressMeter;\n    property LogFile;\n    property Logging;\n    property OnArchiveProgress;\n    property OnArchiveItemProgress;\n    property OnChange;\n    property OnLoad;\n    property SetID;\n    property TempDirectory;\n    property Version;\n    property FileName;  {must be after OnLoad}\n  end;\n  {.Z+}\n\n\nimplementation\n\nuses\n  SysUtils,\n  AbArcTyp,\n  AbUtils;\n\n{ TAbCustomCabBrowser ====================================================== }\nconstructor TAbCustomCabBrowser.Create(AOwner : TComponent);\nbegin\n  inherited Create(AOwner);\n  FArchiveType := atCab;\nend;\n{ -------------------------------------------------------------------------- }\ndestructor TAbCustomCabBrowser.Destroy;\nbegin\n  inherited Destroy;\nend;\n{ -------------------------------------------------------------------------- }\nfunction TAbCustomCabBrowser.GetCabArchive : TAbCabArchive;\nbegin\n  if Assigned(Archive) then\n    Result := TAbCabArchive(Archive)\n  else\n    Result := nil;\nend;\n{ -------------------------------------------------------------------------- }\nfunction TAbCustomCabBrowser.GetCabSize : Longint;\nbegin\n  if Assigned(Archive) then\n    Result := TAbCabArchive(Archive).CabSize\n  else\n    Result := 0;\nend;\n{ -------------------------------------------------------------------------- }\nfunction TAbCustomCabBrowser.GetCurrentCab : Word;\nbegin\n  if Assigned(Archive) then\n    Result := TAbCabArchive(Archive).CurrentCab\n  else\n    Result := 0;\nend;\n{ -------------------------------------------------------------------------- }\nfunction TAbCustomCabBrowser.GetFolderCount : Word;\nbegin\n  if Assigned(Archive) then\n    Result := TAbCabArchive(Archive).FolderCount\n  else\n    Result := 0;\nend;\n{ -------------------------------------------------------------------------- }\nfunction TAbCustomCabBrowser.GetHasNext : Boolean;\nbegin\n  if Assigned(Archive) then\n    Result := TAbCabArchive(Archive).HasNext\n  else\n    Result := False;\nend;\n{ -------------------------------------------------------------------------- }\nfunction TAbCustomCabBrowser.GetHasPrev : Boolean;\nbegin\n  if Assigned(Archive) then\n    Result := TAbCabArchive(Archive).HasPrev\n  else\n    Result := False;\nend;\n{ -------------------------------------------------------------------------- }\nfunction TAbCustomCabBrowser.GetItem(Index : Integer) : TAbCabItem;\n  {return cabinet item}\nbegin\n  if Assigned(CabArchive) then\n    Result := CabArchive.Items[Index]\n  else\n    Result := nil;\nend;\n{ -------------------------------------------------------------------------- }\nfunction TAbCustomCabBrowser.GetSetID : Word;\nbegin\n  if Assigned(Archive) then\n    Result := TAbCabArchive(Archive).SetID\n  else\n    Result := 0;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbCustomCabBrowser.InitArchive;\nbegin\n  inherited InitArchive;\n  if Assigned(Archive) then\n    TAbCabArchive(Archive).SetID := FSetID;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbCustomCabBrowser.SetFileName(const aFileName : string);\n  {open/create cabinet archive}\nbegin\n  FFileName := aFileName;\n  if (csDesigning in ComponentState) then\n    Exit;\n  if Assigned(FArchive) then begin\n    FArchive.Free;\n    FArchive := nil;\n  end;\n  if (aFileName <> '') and\n      FileExists(aFilename) and\n     (AbDetermineArcType(aFileName, atCab) = atCab) then\n  begin\n    FArchive := TAbCabArchive.Create(aFileName, fmOpenRead);\n    InitArchive;\n    FArchive.Load;\n  end;\n  DoChange;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbCustomCabBrowser.SetSetID(Value : Word);\nbegin\n  FSetID := Value;\n  if Assigned(Archive) then\n    TAbCabArchive(Archive).SetID := Value;\nend;\n{ -------------------------------------------------------------------------- }\n\nend.\n"
  },
  {
    "path": "lib/abbrevia/source/AbCView.pas",
    "content": "(* ***** BEGIN LICENSE BLOCK *****\n * Version: MPL 1.1\n *\n * The contents of this file are subject to the Mozilla Public License Version\n * 1.1 (the \"License\"); you may not use this file except in compliance with\n * the License. You may obtain a copy of the License at\n * http://www.mozilla.org/MPL/\n *\n * Software distributed under the License is distributed on an \"AS IS\" basis,\n * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License\n * for the specific language governing rights and limitations under the\n * License.\n *\n * The Original Code is TurboPower Abbrevia\n *\n * The Initial Developer of the Original Code is\n * TurboPower Software\n *\n * Portions created by the Initial Developer are Copyright (C) 1997-2002\n * the Initial Developer. All Rights Reserved.\n *\n * Contributor(s):\n *\n * ***** END LICENSE BLOCK ***** *)\n\n{*********************************************************}\n{* ABBREVIA: AbCView.pas                                 *}\n{*********************************************************}\n{* ABBREVIA: Cabinet archive viewer component            *}\n{*   Use AbQCView.pas for CLX                            *}\n{*********************************************************}\n\n{$IFNDEF UsingCLX}\nUnit AbCView;\n{$ENDIF}\n\n{$I AbDefine.inc}\n\ninterface\n\nuses\n  Windows, Classes,\n  {$IFDEF UsingClx}\n  AbQView,\n  {$ELSE}\n  AbView,\n  {$ENDIF}\n  AbCBrows,\n  AbCabTyp, AbArcTyp;\n\ntype\n  TAbCabView = class(TAbBaseViewer)\n  protected\n    FCabComponent : TAbCustomCabBrowser;\n    FEmptyItemList: TAbArchiveList;\n    function GetItem(RowNum : Longint) : TAbCabItem;\n    procedure SetCabComponent(Value : TAbCustomCabBrowser);\n    procedure Notification(AComponent : TComponent; Operation : TOperation);\n      override;\n    procedure DoChange(Sender : TObject);\n      override;\n  public\n    constructor Create(AOwner : TComponent);\n      override;\n    destructor  Destroy;\n      override;\n    property Items[RowNum : Longint] : TAbCabItem\n      read GetItem;\n  published {properties}\n    property Align;\n    property Attributes;\n    property BorderStyle;\n    property Color;\n    property Colors;\n{$IFNDEF UsingClx}\n    property Ctl3D;\n{$ENDIF}\n    property Cursor;\n    property Headings;\n    property DefaultColWidth;\n    property DefaultRowHeight;\n    property DisplayOptions;\n    property HeaderRowHeight;\n    property SortAttributes;\n{$IFNDEF UsingClx}\n    property DragCursor;\n{$ENDIF}\n    property DragMode;\n    property Enabled;\n    property Font;\n    property ParentColor;\n{$IFNDEF UsingClx}\n    property ParentCtl3D;\n{$ENDIF}\n    property ParentFont;\n    property ParentShowHint;\n    property PopupMenu;\n    property ShowHint;\n    property TabOrder;\n    property TabStop;\n    property Version;\n    property CabComponent : TAbCustomCabBrowser\n      read FCabComponent write SetCabComponent;\n  published {Events}\n    property OnChange;\n    property OnClick;\n    property OnDblClick;\n    property OnEnter;\n    property OnExit;\n    property OnKeyDown;\n    property OnKeyPress;\n    property OnKeyUp;\n    property OnMouseDown;\n    property OnMouseMove;\n    property OnMouseUp;\n    property OnSorted;\n    property OnDrawSortArrow;\nend;\n\n\nimplementation\n\ntype\n  TAbCabBrowserFriend = class(TAbCustomCabBrowser);\n\n\n{ ===== TAbCabView ========================================================= }\nconstructor TAbCabView.Create(AOwner : TComponent);\nbegin\n  inherited;\n  FEmptyItemList := FItemList;\nend;\n{ -------------------------------------------------------------------------- }\ndestructor TAbCabView.Destroy;\nbegin\n  FItemList := FEmptyItemList;\n  inherited;\nend;\n{ -------------------------------------------------------------------------- }\nfunction TAbCabView.GetItem(RowNum : Longint) : TAbCabItem;\nbegin\n  if Assigned(FItemList) then\n    Result := TAbCabItem(FItemList.Items[FRowMap[RowNum]])\n  else\n    Result := nil;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbCabView.Notification(AComponent : TComponent; Operation : TOperation);\nbegin\n  inherited Notification(AComponent, Operation);\n  if Operation = opRemove then\n    if Assigned(FCabComponent) and (AComponent = FCabComponent) then begin\n      FCabComponent := nil;\n      Refresh;\n    end;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbCabView.SetCabComponent(Value : TAbCustomCabBrowser);\nbegin\n  FCabComponent := Value;\n  FCabComponent.OnChange := DoChange;\n  FCabComponent.OnLoad := DoLoad;\n  DoChange(Self);\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbCabView.DoChange(Sender : TObject);\nbegin\n  if Assigned(FCabComponent) and Assigned(TAbCabBrowserFriend(FCabComponent).Archive) then\n    FItemList := TAbCabBrowserFriend(FCabComponent).Archive.ItemList\n  else if FEmptyItemList <> nil then\n    FItemList := FEmptyItemList;\n  inherited DoChange(Sender);\nend;\n\nend.\n\n"
  },
  {
    "path": "lib/abbrevia/source/AbCabExt.pas",
    "content": "(* ***** BEGIN LICENSE BLOCK *****\n * Version: MPL 1.1\n *\n * The contents of this file are subject to the Mozilla Public License Version\n * 1.1 (the \"License\"); you may not use this file except in compliance with\n * the License. You may obtain a copy of the License at\n * http://www.mozilla.org/MPL/\n *\n * Software distributed under the License is distributed on an \"AS IS\" basis,\n * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License\n * for the specific language governing rights and limitations under the\n * License.\n *\n * The Original Code is TurboPower Abbrevia\n *\n * The Initial Developer of the Original Code is\n * TurboPower Software\n *\n * Portions created by the Initial Developer are Copyright (C) 1997-2002\n * the Initial Developer. All Rights Reserved.\n *\n * Contributor(s):\n *\n * ***** END LICENSE BLOCK ***** *)\n\n{*********************************************************}\n{* ABBREVIA: AbCabExt.pas                                *}\n{*********************************************************}\n{* ABBREVIA: Cabinet file extractor component            *}\n{*********************************************************}\n\nunit AbCabExt;\n\n{$I AbDefine.inc}\n\ninterface\n\nuses\n  Classes,\n  AbCBrows, \n  AbArcTyp;\n\ntype\n  TAbCustomCabExtractor = class(TAbCustomCabBrowser)\n  protected {private}\n    FExtractOptions : TAbExtractOptions;\n    FOnConfirmOverwrite : TAbConfirmOverwriteEvent;\n\n    procedure DoConfirmOverwrite(var Name : string;\n                                 var Confirm : Boolean);\n    procedure InitArchive;\n      override;\n    procedure SetExtractOptions( Value : TAbExtractOptions );\n\n  protected {properties}\n    property ExtractOptions : TAbExtractOptions\n      read  FExtractOptions\n      write SetExtractOptions\n      default AbDefExtractOptions;\n    property OnConfirmOverwrite : TAbConfirmOverwriteEvent\n      read  FOnConfirmOverwrite\n      write FOnConfirmOverwrite;\n\n  public\n    constructor Create( AOwner : TComponent ); override;\n    destructor Destroy; override;\n\n    procedure ExtractAt(Index : Integer; const NewName : string);\n    procedure ExtractFiles(const FileMask : string);\n    procedure ExtractFilesEx(const FileMask, ExclusionMask : string);\n    procedure ExtractTaggedItems;\n  end;\n\n  {$IFDEF HasPlatformsAttribute}\n  [ComponentPlatformsAttribute(pidWin32 or pidWin64)]\n  {$ENDIF}\n  TAbCabExtractor = class(TAbCustomCabExtractor)\n  published\n    property ArchiveProgressMeter;\n    property BaseDirectory;\n    property CabSize;\n    property CurrentCab;\n    property ExtractOptions;\n    property FolderCount;\n    property HasNext;\n    property HasPrev;\n    property ItemProgressMeter;\n    property OnArchiveProgress;\n    property OnArchiveItemProgress;\n    property OnChange;\n    property OnConfirmOverwrite;\n    property OnConfirmProcessItem;\n    property OnLoad;\n    property OnProcessItemFailure;\n    property OnRequestImage;\n    property SetID;\n    property TempDirectory;\n    property Version;\n    property FileName; {must be after OnLoad}\n  end;\n  {.Z+}\n\n\nimplementation\n\nuses\n  AbExcept;\n\n{ TAbCustomCabExtractor ==================================================== }\nconstructor TAbCustomCabExtractor.Create(AOwner : TComponent);\nbegin\n  inherited Create( AOwner );\n  ExtractOptions := AbDefExtractOptions;\nend;\n{ -------------------------------------------------------------------------- }\ndestructor TAbCustomCabExtractor.Destroy;\nbegin\n  inherited Destroy;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbCustomCabExtractor.DoConfirmOverwrite\n                                     (var Name : string;\n                                      var Confirm : Boolean);\nbegin\n  if Assigned(FOnConfirmOverwrite) then\n    FOnConfirmOverwrite(Name, Confirm);\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbCustomCabExtractor.ExtractAt(Index : Integer;\n                                          const NewName : string);\n  {extract a file from the archive that match the index}\nbegin\n  if Assigned( CabArchive ) then\n    CabArchive.ExtractAt( Index, NewName )\n  else\n    raise EAbNoArchive.Create;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbCustomCabExtractor.ExtractFiles(const FileMask : string);\n  {Extract files from the cabinet matching the filemask}\nbegin\n  if Assigned( CabArchive ) then\n    CabArchive.ExtractFiles( FileMask )\n  else\n    raise EAbNoArchive.Create;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbCustomCabExtractor.ExtractFilesEx(const FileMask, ExclusionMask : string);\n  {Extract files from the cabinet matching the FileMask, exluding those\n   matching ExclusionMask}\nbegin\n  if Assigned( CabArchive ) then\n    CabArchive.ExtractFilesEx( FileMask, ExclusionMask )\n  else\n    raise EAbNoArchive.Create;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbCustomCabExtractor.ExtractTaggedItems;\n  {Extract items in the archive that have been tagged}\nbegin\n  if Assigned( CabArchive ) then\n    CabArchive.ExtractTaggedItems\n  else\n    raise EAbNoArchive.Create;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbCustomCabExtractor.InitArchive;\n  {Archive now points to the Cab file, update all Archive's properties...}\nbegin\n  inherited InitArchive;\n  if Assigned( CabArchive ) then begin\n    {poperties}\n    CabArchive.ExtractOptions     := FExtractOptions;\n    {events}\n    CabArchive.OnConfirmOverwrite := DoConfirmOverwrite;\n  end;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbCustomCabExtractor.SetExtractOptions( Value : TAbExtractOptions );\nbegin\n  FExtractOptions := Value;\n  if Assigned( FArchive ) then\n    FArchive.ExtractOptions := Value;\nend;\n{ -------------------------------------------------------------------------- }\n\nend.\n\n"
  },
  {
    "path": "lib/abbrevia/source/AbCabKit.pas",
    "content": "(* ***** BEGIN LICENSE BLOCK *****\n * Version: MPL 1.1\n *\n * The contents of this file are subject to the Mozilla Public License Version\n * 1.1 (the \"License\"); you may not use this file except in compliance with\n * the License. You may obtain a copy of the License at\n * http://www.mozilla.org/MPL/\n *\n * Software distributed under the License is distributed on an \"AS IS\" basis,\n * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License\n * for the specific language governing rights and limitations under the\n * License.\n *\n * The Original Code is TurboPower Abbrevia\n *\n * The Initial Developer of the Original Code is\n * TurboPower Software\n *\n * Portions created by the Initial Developer are Copyright (C) 1997-2002\n * the Initial Developer. All Rights Reserved.\n *\n * Contributor(s):\n *\n * ***** END LICENSE BLOCK ***** *)\n\n{*********************************************************}\n{* ABBREVIA: AbCabKit.PAS                                *}\n{*********************************************************}\n{* ABBREVIA: Cabinet file builder/extractor component    *}\n{*********************************************************}\n\nunit AbCabKit;\n\n{$I AbDefine.inc}\n\ninterface\n\nuses\n  Classes, AbArcTyp,\n  AbCabMak;\n\ntype\n  TAbCustomCabKit = class(TAbCustomMakeCab)\n  protected {private}\n    FExtractOptions : TAbExtractOptions;\n    FOnConfirmOverwrite : TAbConfirmOverwriteEvent;\n\n    procedure DoConfirmOverwrite(var Name : string;\n                                 var Confirm : Boolean);\n    procedure InitArchive; override;\n    procedure SetExtractOptions( Value : TAbExtractOptions );\n    procedure SetFileName(const aFileName : string); override;\n\n\n  protected {properties}\n    property ExtractOptions : TAbExtractOptions\n      read  FExtractOptions\n      write SetExtractOptions\n      default AbDefExtractOptions;\n\n  protected {events}\n    property OnConfirmOverwrite : TAbConfirmOverwriteEvent\n      read  FOnConfirmOverwrite\n      write FOnConfirmOverwrite;\n\n  public {methods}\n    constructor Create( AOwner : TComponent ); override;\n    destructor Destroy; override;\n\n    procedure ExtractAt(Index : Integer; const NewName : string);\n    procedure ExtractFiles(const FileMask : string);\n    procedure ExtractFilesEx(const FileMask, ExclusionMask : string);\n    procedure ExtractTaggedItems;\n  end;\n\n  {$IFDEF HasPlatformsAttribute}\n  [ComponentPlatformsAttribute(pidWin32 or pidWin64)]\n  {$ENDIF}\n  TAbCabKit = class(TAbCustomCabKit)\n  published\n    property ArchiveProgressMeter;\n    property BaseDirectory;\n    property CabSize;\n    property CompressionType;\n    property CurrentCab;\n    property ExtractOptions;\n    property FolderCount;\n    property FolderThreshold;\n    property HasNext;\n    property HasPrev;\n    property ItemProgressMeter;\n    property OnArchiveProgress;\n    property OnArchiveItemProgress;\n    property OnChange;\n    property OnConfirmOverwrite;\n    property OnConfirmProcessItem;\n    property OnLoad;\n    property OnProcessItemFailure;\n    property OnRequestImage;\n    property OnSave;\n    property SetID;\n    property SpanningThreshold;\n    property TempDirectory;\n    property Version;\n    property FileName; {must be after OnLoad}\n  end;\n\n\nimplementation\n\nuses\n  SysUtils,\n  AbExcept,\n  AbCabTyp,\n  AbCBrows;\n\n{ TAbCustomCabKit ==================================================== }\nconstructor TAbCustomCabKit.Create(AOwner : TComponent);\nbegin\n  inherited Create( AOwner );\n  ExtractOptions := AbDefExtractOptions;\nend;\n{ -------------------------------------------------------------------------- }\ndestructor TAbCustomCabKit.Destroy;\nbegin\n  inherited Destroy;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbCustomCabKit.DoConfirmOverwrite(var Name : string;\n                                             var Confirm : Boolean);\nbegin\n  if Assigned(FOnConfirmOverwrite) then\n    FOnConfirmOverwrite(Name, Confirm);\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbCustomCabKit.ExtractAt(Index : Integer; const NewName : string);\n  {extract a file from the archive that match the index}\nbegin\n  if Assigned( CabArchive ) then\n    CabArchive.ExtractAt( Index, NewName )\n  else\n    raise EAbNoArchive.Create;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbCustomCabKit.ExtractFiles(const FileMask : string);\n  {Extract files from the cabinet matching the filemask}\nbegin\n  if Assigned(CabArchive) then\n    CabArchive.ExtractFiles(FileMask)\n  else\n    raise EAbNoArchive.Create;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbCustomCabKit.ExtractFilesEx(const FileMask, ExclusionMask : string);\n  {Extract files from the cabinet matching the FileMask, exluding those\n   matching ExclusionMask}\nbegin\n  if Assigned(CabArchive) then\n    CabArchive.ExtractFilesEx(FileMask, ExclusionMask)\n  else\n    raise EAbNoArchive.Create;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbCustomCabKit.ExtractTaggedItems;\n  {Extract items in the archive that have been tagged}\nbegin\n  if Assigned(CabArchive) then\n    CabArchive.ExtractTaggedItems\n  else\n    raise EAbNoArchive.Create;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbCustomCabKit.InitArchive;\nbegin\n  inherited InitArchive;\n  if Assigned( CabArchive ) then begin\n    {poperties}\n    CabArchive.ExtractOptions     := FExtractOptions;\n    {events}\n    CabArchive.OnConfirmOverwrite := DoConfirmOverwrite;\n  end;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbCustomCabKit.SetExtractOptions( Value : TAbExtractOptions );\nbegin\n  FExtractOptions := Value;\n  if Assigned( FArchive ) then\n    FArchive.ExtractOptions := Value;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbCustomCabKit.SetFileName(const aFileName : string);\n  {Create or open the specified cabinet file}\nbegin\n  FFilename := aFileName;\n  if csDesigning in ComponentState then\n    Exit;\n  if Assigned(FArchive) then begin\n    FArchive.Free;\n    FArchive := nil;\n  end;\n  if (aFileName <> '') then begin\n    if (aFileName <> '') and FileExists(aFilename) then\n      FArchive := TAbCabArchive.Create(aFileName, fmOpenRead)\n    else\n      FArchive := TAbCabArchive.Create(aFileName, fmOpenWrite);\n    InitArchive;\n    FArchive.Load;\n  end;\n  DoChange;\nend;\n{ -------------------------------------------------------------------------- }\n\nend.\n"
  },
  {
    "path": "lib/abbrevia/source/AbCabMak.pas",
    "content": "(* ***** BEGIN LICENSE BLOCK *****\n * Version: MPL 1.1\n *\n * The contents of this file are subject to the Mozilla Public License Version\n * 1.1 (the \"License\"); you may not use this file except in compliance with\n * the License. You may obtain a copy of the License at\n * http://www.mozilla.org/MPL/\n *\n * Software distributed under the License is distributed on an \"AS IS\" basis,\n * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License\n * for the specific language governing rights and limitations under the\n * License.\n *\n * The Original Code is TurboPower Abbrevia\n *\n * The Initial Developer of the Original Code is\n * TurboPower Software\n *\n * Portions created by the Initial Developer are Copyright (C) 1997-2002\n * the Initial Developer. All Rights Reserved.\n *\n * Contributor(s):\n *\n * ***** END LICENSE BLOCK ***** *)\n\n{*********************************************************}\n{* ABBREVIA: AbCabMak.pas                                *}\n{*********************************************************}\n{* ABBREVIA: Cabinet builder component (VCL)             *}\n{*   See AbQCabMk.pas for the CLX header                 *}\n{*********************************************************}\n\nunit AbCabMak;\n\n{$I AbDefine.inc}\n\ninterface\n\nuses\n  Classes,\n  AbCBrows,\n  AbArcTyp, AbCabTyp;\n\ntype\n  TAbCustomMakeCab = class(TAbCustomCabBrowser)\n  protected {private}\n    FFolderThreshold     : Longint;\n    FCompressionType     : TAbCabCompressionType;\n    FStoreOptions           : TAbStoreOptions;\n    FOnSave              : TAbArchiveEvent;\n\n protected {methods}\n    procedure DoSave(Sender : TObject); virtual;\n    procedure InitArchive; override;\n    procedure SetFolderThreshold(Value : Longint);\n    procedure SetCompressionType(Value : TAbCabCompressionType);\n    procedure SetFileName(const aFileName : string); override;\n    procedure SetStoreOptions( Value : TAbStoreOptions );\n\n  protected {properties}\n    property CompressionType : TAbCabCompressionType\n      read  FCompressionType\n      write SetCompressionType;\n    property FolderThreshold : Longint\n      read  FFolderThreshold\n      write SetFolderThreshold;\n    property StoreOptions : TAbStoreOptions\n      read  FStoreOptions\n      write SetStoreOptions\n      default AbDefStoreOptions;\n\n  protected {events}\n    property OnSave : TAbArchiveEvent\n      read  FOnSave\n      write FOnSave;\n\n  public {methods}\n    constructor Create( AOwner : TComponent ); override;\n    procedure AddFiles(const FileMask : string; SearchAttr : Integer );\n    procedure AddFilesEx(const FileMask : string;\n                         const ExclusionMask : string; SearchAttr : Integer );\n    procedure StartNewFolder;\n    procedure StartNewCabinet;\n  end;\n\ntype\n  {$IFDEF HasPlatformsAttribute}\n  [ComponentPlatformsAttribute(pidWin32 or pidWin64)]\n  {$ENDIF}\n  TAbMakeCab = class(TAbCustomMakeCab)\n  published\n    property ArchiveProgressMeter;\n    property BaseDirectory;\n    property CabSize;\n    property CompressionType;\n    property FolderThreshold;\n    property ItemProgressMeter;\n    property StoreOptions;\n    property OnArchiveProgress;\n    property OnArchiveItemProgress;\n    property OnChange;\n    property OnConfirmProcessItem;\n    property OnLoad;\n    property OnProcessItemFailure;\n    property OnRequestImage;\n    property OnSave;\n    property SetID;\n    property SpanningThreshold;\n    property TempDirectory;\n    property Version;\n    property FileName; {must be after OnLoad}\n  end;\n  {.Z+}\n\n\nimplementation\n\nuses\n  SysUtils,\n  AbExcept,\n  AbUtils;\n\n{ TAbCustomMakeCab ========================================================= }\nconstructor TAbCustomMakeCab.Create( AOwner : TComponent );\nbegin\n  inherited Create( AOwner );\n  FCompressionType := AbDefCompressionType;\n  FSpanningThreshold := AbDefCabSpanningThreshold;\n  FFolderThreshold := AbDefFolderThreshold;\n  FSetID := 0;\n  FStoreOptions := AbDefStoreOptions;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbCustomMakeCab.AddFiles(const FileMask : string; SearchAttr : Integer );\n  {Add files to the cabinet where the disk filespec matches}\nbegin\n  if Assigned(CabArchive) then\n    CabArchive.AddFiles(FileMask, SearchAttr)\n  else\n    raise EAbNoArchive.Create;\n  DoChange;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbCustomMakeCab.AddFilesEx(const FileMask : string;\n                                      const ExclusionMask : string;\n                                            SearchAttr : Integer);\n  {Add files that match Filemask except those matching ExclusionMask}\nbegin\n  if Assigned(CabArchive) then\n    CabArchive.AddFilesEx(FileMask, ExclusionMask, SearchAttr)\n  else\n    raise EAbNoArchive.Create;\n  DoChange;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbCustomMakeCab.DoSave(Sender : TObject);\nbegin\n  if Assigned(FOnSave) then\n    FOnSave(Self);\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbCustomMakeCab.InitArchive;\nbegin\n  inherited InitArchive;\n  if Assigned(CabArchive) then begin\n    {properties}\n    CabArchive.FolderThreshold   := FFolderThreshold;\n    CabArchive.CompressionType   := FCompressionType;\n    CabArchive.SetID             := FSetID;\n    CabArchive.StoreOptions      := FStoreOptions;\n    {events}\n    CabArchive.OnSave            := DoSave;\n  end;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbCustomMakeCab.SetCompressionType(Value : TAbCabCompressionType);\n  {Set the type of compression to use}\nbegin\n  FCompressionType := Value;\n  if Assigned(CabArchive) then\n    CabArchive.CompressionType := Value;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbCustomMakeCab.SetFileName(const aFileName : string);\n  {Create the specified cabinet file}\nbegin\n  FFilename := aFileName;\n  if csDesigning in ComponentState then\n    Exit;\n  if Assigned(FArchive) then begin\n    FArchive.Free;\n    FArchive := nil;\n  end;\n  if (aFileName <> '') then begin\n    FArchive := TAbCabArchive.Create(aFileName, fmOpenWrite);\n    InitArchive;\n    FArchive.Load;\n    FArchiveType := atCab;\n  end;\n  DoChange;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbCustomMakeCab.SetFolderThreshold(Value : Longint);\n  {Set folder compression boundary}\nbegin\n  FFolderThreshold := Value;\n  if Assigned(CabArchive) then\n    CabArchive.FolderThreshold := Value;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbCustomMakeCab.SetStoreOptions(Value : TAbStoreOptions);\nbegin\n  FStoreOptions := Value;\n  if Assigned(CabArchive) then\n    CabArchive.StoreOptions := Value;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbCustomMakeCab.StartNewCabinet;\n  {Flush current cabinet and start a new one}\nbegin\n  if Assigned(CabArchive) then\n    CabArchive.NewCabinet\n  else\n    raise EAbNoArchive.Create;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbCustomMakeCab.StartNewFolder;\n  {Flush current folder and start a new one}\nbegin\n  if Assigned(CabArchive) then\n    CabArchive.NewFolder\n  else\n    raise EAbNoArchive.Create;\nend;\n{ -------------------------------------------------------------------------- }\n\nend.\n"
  },
  {
    "path": "lib/abbrevia/source/AbCabTyp.pas",
    "content": "(* ***** BEGIN LICENSE BLOCK *****\n * Version: MPL 1.1\n *\n * The contents of this file are subject to the Mozilla Public License Version\n * 1.1 (the \"License\"); you may not use this file except in compliance with\n * the License. You may obtain a copy of the License at\n * http://www.mozilla.org/MPL/\n *\n * Software distributed under the License is distributed on an \"AS IS\" basis,\n * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License\n * for the specific language governing rights and limitations under the\n * License.\n *\n * The Original Code is TurboPower Abbrevia\n *\n * The Initial Developer of the Original Code is\n * TurboPower Software\n *\n * Portions created by the Initial Developer are Copyright (C) 1997-2002\n * the Initial Developer. All Rights Reserved.\n *\n * Contributor(s):\n *   Craig Peterson <capeterson@users.sourceforge.net>\n *\n * ***** END LICENSE BLOCK ***** *)\n\n{*********************************************************}\n{* ABBREVIA: AbCabTyp.pas                                *}\n{*********************************************************}\n{* ABBREVIA: Cabinet Archive                             *}\n{* Based on info from the FCI/FDI Library Description,   *}\n{* included in the Microsoft Cabinet SDK                 *}\n{*********************************************************}\n\nunit AbCabTyp;\n\n{$I AbDefine.inc}\n\ninterface\n\nuses\n  Windows, Classes, AbFciFdi, AbArcTyp, AbUtils;\n\ntype\n  TAbCabItem = class(TAbArchiveItem)\n  protected {private}\n    FPartialFile : Boolean;\n    FRawFileName : AnsiString;\n  public\n    property PartialFile : Boolean\n      read  FPartialFile\n      write FPartialFile;\n    property RawFileName : AnsiString\n      read FRawFileName\n      write FRawFileName;\n  end;\n\ntype\n  TAbCabCompressionType = (ctNone, ctMSZIP, ctLZX);\n  TAbCabinetMode = (cmRead, cmWrite);\n  TAbCabStatus = (csFile, csFolder, csCabinet);\n\n\nconst\n  faExtractAndExecute  = $040;\n  faUTF8Name = $080;\n  AbDefCabSpanningThreshold  = 0;\n  AbDefFolderThreshold = 0;\n  AbDefCompressionType = ctMSZIP;\n  AbDefReserveHeaderSize = 0;\n  AbDefReserveFolderSize = 0;\n  AbDefReserveDataSize = 0;\n  AbDefLZXWindowSize = 18;\n\n  CompressionTypeMap : array[TAbCabCompressionType] of Word = (0, 1, 4611);\n\ntype\n  TAbCabArchive = class(TAbArchive)\n  protected {private}\n    {internal variables}\n    FCabName         : AnsiString;\n    FCabPath         : AnsiString;\n    FFCICabInfo      : FCICabInfo;\n    FFCIContext      : HFCI;\n    FFDIContext      : HFDI;\n    FFDICabInfo      : FDICabInfo;\n    FErrors          : CabErrorRecord;\n    FItemInProgress  : TAbCabItem;\n    FItemStream      : TStream;\n    FIIPName         : string;\n    FItemProgress    : DWord;\n    FNextCabinet     : string;\n    FNextDisk        : string;\n    FTempFileID      : Integer;\n\n    {property variables}\n    FCurrentCab         : Word;\n    FCabSize           : Longint;\n    FCompressionType   : TAbCabCompressionType;\n    FFileCount         : Word;\n    FFolderThreshold   : LongWord;\n    FFolderCount       : Word;\n    FHasPrev           : Boolean;\n    FHasNext           : Boolean;\n    FSetID             : Word;\n\n    {internal methods}\n    procedure CloseCabFile;\n    procedure CreateCabFile;\n    function  CreateItem( const FileSpec : string ): TAbArchiveItem;\n      override;\n    procedure DoCabItemProgress(BytesCompressed : DWord;\n      var Abort : Boolean);\n    procedure DoGetNextCabinet(CabIndex : Integer; var CabName : string;\n                               var Abort : Boolean);\n    procedure ExtractItemAt(Index : Integer; const NewName : string);\n      override;\n    procedure ExtractItemToStreamAt(Index : Integer; OutStream : TStream);\n      override;\n    function  GetItem(ItemIndex : Integer) : TAbCabItem;\n    procedure LoadArchive;\n      override;\n    procedure OpenCabFile;\n    procedure PutItem( Index : Integer; Value : TAbCabItem );\n    procedure SaveArchive;\n      override;\n    procedure SetFolderThreshold(Value : LongWord);\n    procedure SetSetID(Value : Word);\n    procedure SetSpanningThreshold(Value : Int64);\n      override;\n    procedure TestItemAt(Index : Integer);\n      override;\n\n  public {methods}\n    constructor Create(const FileName : string; Mode : Word);\n      override;\n    constructor CreateFromStream(aStream : TStream; const aArchiveName : string);\n      override;\n    destructor Destroy;\n      override;\n    procedure Add(aItem : TAbArchiveItem);\n      override;\n    procedure NewCabinet;\n    procedure NewFolder;\n\n  public {properties}\n    property CurrentCab : Word\n      read  FCurrentCab;\n    property CabSize : Longint\n      read  FCabSize;\n    property CompressionType : TAbCabCompressionType\n      read  FCompressionType\n      write FCompressionType;\n    property FolderThreshold : LongWord\n      read  FFolderThreshold\n      write SetFolderThreshold;\n    property FolderCount : Word\n      read  FFolderCount;\n    property HasPrev : Boolean\n      read  FHasPrev;\n    property HasNext : Boolean\n      read  FHasNext;\n    property Items[Index : Integer] : TAbCabItem\n      read  GetItem\n      write PutItem; default;\n    property ItemProgress : DWord\n      read  FItemProgress\n      write FItemProgress;\n    property SetID : Word\n      read  FSetID\n      write SetSetID;\n  end;\n\nfunction VerifyCab(const Fn : string) : TAbArchiveType; overload;\nfunction VerifyCab(Strm : TStream) : TAbArchiveType; overload;\n\nimplementation\n\nuses\n  SysUtils,\n{$IFDEF HasAnsiStrings}\n  System.AnsiStrings,\n{$ENDIF}\n  AbCharset, AbConst, AbExcept;\n\n{$WARN UNIT_PLATFORM OFF}\n{$WARN SYMBOL_PLATFORM OFF}\n\ntype\n  PWord    = ^Word;\n  PInteger = ^Integer;\n\n{ == FDI/FCI Callback Functions - cdecl calling convention ================= }\nfunction FXI_GetMem(uBytes : Integer) : Pointer;\n  cdecl;\n  {allocate memory}\nbegin\n  Result := nil;\n  if (uBytes > 0) then\n    GetMem(Result, uBytes);\nend;\n{ -------------------------------------------------------------------------- }\nprocedure FXI_FreeMem(lpBuffer : Pointer);\n  cdecl;\n  {free memory}\nbegin\n  FreeMem(lpBuffer);\nend;\n\n\n{ == FCI Callback Functions - cdecl calling convention ===================== }\nfunction FCI_FileOpen(lpPathName: PAnsiChar; Flag, Mode: Integer;\n  PError: PInteger; Archive: TAbCabArchive) : PtrInt;\n  cdecl;\n  {open a file}\nbegin\n  Result := _lcreat(lpPathName, 0);\n  if (Result = -1) then\n    raise EAbFCIFileOpenError.Create;\nend;\n{ -------------------------------------------------------------------------- }\nfunction FCI_FileRead(hFile: PtrInt; lpBuffer: Pointer;\n  uBytes: UINT; PError: PInteger; Archive: TAbCabArchive) : UINT;\n  cdecl;\n  {read from a file}\nbegin\n  Result := _lread(hFile, lpBuffer, uBytes);\n  if (Result = UINT(-1)) then\n    raise EAbFCIFileReadError.Create;\nend;\n{ -------------------------------------------------------------------------- }\nfunction FCI_FileWrite(hFile: PtrInt; lpBuffer: Pointer;\n  uBytes: UINT; PError: PInteger; Archive: TAbCabArchive) : UINT;\n  cdecl;\n  {write to a file}\nbegin\n  Result := _lwrite(hFile, lpBuffer, uBytes);\n  if (Result = UINT(-1)) then\n    raise EAbFCIFileWriteError.Create;\nend;\n{ -------------------------------------------------------------------------- }\nfunction FCI_FileClose(hFile: PtrInt; PError: PInteger;\n  Archive: TAbCabArchive) : Integer;\n  cdecl;\n  {close a file}\nbegin\n  Result := _lclose(hFile);\n  if (Result = -1) then\n    raise EAbFCIFileCloseError.Create;\nend;\n{ -------------------------------------------------------------------------- }\nfunction FCI_FileSeek(hFile: PtrInt; Offset: Longint;\n  Origin: Integer; PError: PInteger; Archive: TAbCabArchive) : Longint;\n  cdecl;\n  {reposition file pointer}\nbegin\n  Result := _llseek(hFile, Offset, Origin);\n  if (Result = -1) then\n    raise EAbFCIFileSeekError.Create;\nend;\n{ -------------------------------------------------------------------------- }\nfunction FCI_FileDelete(lpFilename: PAnsiChar;  PError: PInteger;\n  Archive: TAbCabArchive) : Boolean;\n  cdecl;\n  {delete a file}\nbegin\n  Result := SysUtils.DeleteFile(string(lpFilename));\n  if not Result then\n    raise EAbFCIFileDeleteError.Create;\nend;\n{ -------------------------------------------------------------------------- }\nfunction FCI_GetNextCab(lpCCab: PFCICabInfo; PrevCab: Longint;\n  Archive: TAbCabArchive) : Boolean;\n  cdecl;\n  {get next cabinet filename}\nvar\n  CabName : string;\n  Abort : Boolean;\nbegin\n  Abort := False;\n  with lpCCab^ do begin\n    CabName := string(szCab);\n    {obtain next cabinet.  Make index zero-based}\n    Archive.DoGetNextCabinet(Pred(iCab), CabName, Abort);\n    if not Abort then\n      AbStrPLCopy(szCab, AnsiString(CabName), Length(szCab));\n  end;\n  Result := not Abort;\nend;\n{ -------------------------------------------------------------------------- }\nfunction FCI_FileDest(PCCab: PFCICabInfo; PFilename: PAnsiChar; cbFile: Longint;\n  Continuation: Boolean; Archive: TAbCabArchive) : Integer;\n  cdecl;\n  {currently not used}\nbegin\n  Result := 0;\nend;\n{ -------------------------------------------------------------------------- }\nfunction FCI_GetOpenInfo(lpPathname: Pointer; PDate, PTime, PAttribs : PWord;\n  PError: PInteger; Archive: TAbCabArchive) : PtrInt;\n  cdecl;\n  {open a file and return date/attributes}\nvar\n  AttrEx: TAbAttrExRec;\n  I, DT: Integer;\n  RawName: RawByteString;\nbegin\n  Result := FileOpen(string(lpPathname), fmOpenRead or fmShareDenyNone);\n  if (Result = -1) then\n    raise EAbFCIFileOpenError.Create;\n  if not AbFileGetAttrEx(string(lpPathname), AttrEx) then\n    raise EAbFileNotFound.Create;\n  PAttribs^ := AttrEx.Attr;\n  DT := DateTimeToFileDate(AttrEx.Time);\n  PDate^ := DT shr 16;\n  PTime^ := DT and $0FFFF;\n  Archive.ItemProgress := 0;\n  Archive.FItemInProgress.UncompressedSize := AttrEx.Size;\n  RawName := Archive.FItemInProgress.RawFileName;\n  for I := 1 to Length(RawName) do\n    if Ord(RawName[I]) > 127 then\n      PAttribs^ := PAttribs^ or faUTF8Name;\nend;\n{ -------------------------------------------------------------------------- }\nfunction FCI_Status(Status: Word; cb1, cb2: DWord;\n                    Archive: TAbCabArchive) : Longint; cdecl;\n  {keep archive informed}\nvar\n  Abort : Boolean;\nbegin\n  Result := 0;\n  if (Status = Word(csCabinet)) then begin\n    Archive.DoSave;\n    Archive.FCabSize := cb2;\n    Result := cb2;\n  end else if (Status = Word(csFolder)) then\n    Archive.FCabSize := Archive.FCabSize + Longint(cb2)\n  else if (Status = Word(csFile)) then begin\n    Archive.DoCabItemProgress(cb2, Abort);\n    Result := Longint(Abort);\n  end;\nend;\n{ -------------------------------------------------------------------------- }\nfunction FCI_GetTempFile(lpTempName: PAnsiChar; TempNameSize: Integer;\n                         Archive: TAbCabArchive) : PtrInt; cdecl;\n  {obtain temporary filename}\nvar\n  TempPath : array[0..255] of AnsiChar;\nbegin\n  Archive.FTempFileID := Archive.FTempFileID + 1;\n  if (Archive.TempDirectory <> '') then\n    AbStrPLCopy(TempPath, AnsiString(Archive.TempDirectory), Length(TempPath))\n  else\n    GetTempPathA(255, TempPath);\n  GetTempFileNameA(TempPath, 'VMS', Archive.FTempFileID, lpTempName);\n  Result := 1;\nend;\n\n{ == FDI Callback Functions - cdecl calling convention ===================== }\nfunction FDI_FileOpen(lpPathName: PAnsiChar; Flag, Mode: Integer) : PtrInt;\n  cdecl;\n  {open a file}\nbegin\n  try\n    Result := PtrInt(TFileStream.Create(string(lpPathName), fmOpenRead or fmShareDenyWrite));\n  except on EFOpenError do\n    Result := -1;\n  end;\nend;\n{ -------------------------------------------------------------------------- }\nfunction FDI_FileRead(hFile: PtrInt; lpBuffer: Pointer; uBytes: UINT) : UINT;\n  cdecl;\n  {read from a file}\nbegin\n  Result := TStream(hFile).Read(lpBuffer^, uBytes);\nend;\n{ -------------------------------------------------------------------------- }\nfunction FDI_FileWrite(hFile: PtrInt; lpBuffer: Pointer; uBytes: UINT) : UINT;\n  cdecl;\n  {write to a file}\nbegin\n  Result := TStream(hFile).Write(lpBuffer^, uBytes);\nend;\n{ -------------------------------------------------------------------------- }\nfunction FDI_FileClose(hFile : PtrInt) : Longint;\n  cdecl;\n  {close a file}\nbegin\n  try\n    TStream(hFile).Free;\n    Result := 0;\n  except\n    Result := -1;\n  end;\nend;\n{ -------------------------------------------------------------------------- }\nfunction FDI_FileSeek(hFile : PtrInt; Offset : Longint; Origin : Integer) : Longint;\n  cdecl;\n  {reposition file pointer}\nbegin\n  Result := TStream(hFile).Seek(Offset, Origin);\nend;\n{ -------------------------------------------------------------------------- }\nfunction FDI_EnumerateFiles(fdint : FDINOTIFICATIONTYPE;\n  pfdin : PFDINotification) : PtrInt;\n  cdecl;\n  {Enumerate the files and build the archive file list}\nvar\n  Item : TAbCabItem;\n  Archive : TAbCabArchive;\nbegin\n  Result := 0;\n  Archive := pfdin^.pv;\n  with Archive do case fdint of\n    FDINT_Cabinet_Info :\n      begin\n        FSetID := pfdin^.setID;\n        FCurrentCab := pfdin^.iCabinet;\n        FNextCabinet := string(pfdin^.psz1);\n        FNextDisk    := string(pfdin^.psz2);\n        Result := 0;\n      end;\n    FDINT_Copy_File, FDINT_Partial_File :\n      begin\n        Item := TAbCabItem.Create;\n        with Item do begin\n          RawFileName := AnsiString(pfdin^.psz1);\n          if (pfdin^.attribs and faUTF8Name) = faUTF8Name then\n            Filename := UTF8ToString(RawFileName)\n          else\n            Filename := string(RawFileName);\n          UnCompressedSize := pfdin^.cb;\n          LastModFileDate := pfdin^.date;\n          LastModFileTime := pfdin^.time;\n          ExternalFileAttributes := pfdin^.attribs;\n          IsEncrypted := False;  {encryption not implemented at this time}\n          PartialFile := (fdint = FDINT_Partial_File);\n        end;\n        FItemList.Add(Item);\n        Result := 0;\n      end;\n  end;\nend;\n{ -------------------------------------------------------------------------- }\nfunction FDI_ExtractFiles(fdint : FDINOTIFICATIONTYPE;\n  pfdin : PFDINotification) : PtrInt;\n  cdecl;\n  {extract file from cabinet}\nvar\n  Archive : TAbCabArchive;\nbegin\n  Result := 0;\n  Archive := pfdin^.pv;\n  case fdint of\n    FDINT_Copy_File :\n      begin\n        if (AnsiString(pfdin^.psz1) = Archive.FItemInProgress.RawFileName) then\n          if Archive.FIIPName <> '' then\n            Result := Integer(TFileStream.Create(Archive.FIIPName, fmCreate))\n          else\n            Result := Integer(Archive.FItemStream)\n        else\n          Result := 0;\n      end;\n    FDINT_Next_Cabinet :\n      begin\n        if pfdin^.fdie = FDIError_None then\n          Result := 0\n        else\n          Result := -1;\n      end;\n    FDINT_Close_File_Info :\n      begin\n        if Archive.FIIPName <> '' then begin\n          FileSetDate(TFileStream(pfdin^.hf).Handle,\n            Longint(pfdin^.date) shl 16 + pfdin^.time);\n          TFileStream(pfdin^.hf).Free;\n          FileSetAttr(Archive.FIIPName, pfdin^.attribs);\n        end;\n        Result := 1;\n      end;\n  end;\nend;\n\n\n{ == TAbCabArchive ========================================================= }\nfunction VerifyCab(const Fn : string) : TAbArchiveType;\nvar\n  Stream : TFileStream;\nbegin\n  Stream := TFileStream.Create(FN, fmOpenRead or fmShareDenyNone);\n  try\n    Result := VerifyCab(Stream);\n  finally\n    Stream.Free;\n  end;\nend;\n{ -------------------------------------------------------------------------- }\nfunction VerifyCab(Strm : TStream) : TAbArchiveType; overload;\nvar\n  Context : HFDI;\n  Info : FDICabInfo;\n  Errors : CabErrorRecord;\n  StartPos : int64;\nbegin\n  Result := atUnknown;\n  Context := FDICreate(@FXI_GetMem, @FXI_FreeMem, @FDI_FileOpen,\n    @FDI_FileRead, @FDI_FileWrite, @FDI_FileClose, @FDI_FileSeek, cpuDefault,\n    @Errors);\n  if Context = nil then\n    Exit;\n  try\n    StartPos := Strm.Position;\n    if FDIIsCabinet(Context, Integer(Strm), @Info) then\n      Result := atCab;\n    Strm.Position := StartPos;\n  finally\n    FDIDestroy(Context);\n  end;\nend;\n\n\n{ == TAbCabArchive ========================================================= }\nconstructor TAbCabArchive.Create(const FileName : string; Mode : Word );\nbegin\n  {Mode is used to identify which interface to use: }\n  {  fmOpenWrite - FCI, fmOpenRead - FDI}\n  inherited CreateInit;\n  if (Mode and fmCreate) = fmCreate then FMode := fmOpenWrite\n  else FMode := Mode and fmOpenWrite;\n  FArchiveName := FileName;\n  FCabName := AnsiString(ExtractFileName(FileName));\n  FCabPath := AnsiString(ExtractFilePath(FileName));\n  SpanningThreshold := AbDefCabSpanningThreshold;\n  FFolderThreshold := AbDefFolderThreshold;\n  FItemInProgress := nil;\n  FItemProgress := 0;\nend;\n{ -------------------------------------------------------------------------- }\nconstructor TAbCabArchive.CreateFromStream(aStream : TStream;\n  const aArchiveName : string);\nbegin\n  raise EAbCabException.Create('TAbCabArchive does not support CreateFromStream');\nend;\n{ -------------------------------------------------------------------------- }\ndestructor TAbCabArchive.Destroy;\nbegin\n  CloseCabFile;\n  inherited Destroy;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbCabArchive.Add(aItem : TAbArchiveItem);\n  {add a file to the cabinet}\nvar\n  Confirm, ItemAdded : Boolean;\n  Item : TAbCabItem;\nbegin\n  ItemAdded := False;\n  try\n    CheckValid;\n    if (FMode <> fmOpenWrite) then begin\n      DoProcessItemFailure(aItem, ptAdd, ecCabError, 0);\n      Exit;\n    end;\n    if FItemList.IsActiveDupe(aItem.FileName) then begin\n      DoProcessItemFailure(aItem, ptAdd, ecAbbrevia, AbDuplicateName);\n      Exit;\n    end;\n    DoConfirmProcessItem(aItem, ptAdd, Confirm);\n    if not Confirm then\n      Exit;\n    Item := TAbCabItem(aItem);\n    FItemInProgress := Item;\n    Item.Action := aaAdd;\n\n    Item.RawFileName := UTF8Encode(Item.FileName);\n    if not FCIAddFile(FFCIContext, Pointer(Item.DiskFileName),\n       PAnsiChar(Item.RawFileName), False, @FCI_GetNextCab, @FCI_Status,\n       @FCI_GetOpenInfo, CompressionTypeMap[FCompressionType]) then\n      raise EAbFCIAddFileError.Create;\n    FItemList.Add(Item);\n    ItemAdded := True;\n\n    FIsDirty := True;\n  finally\n    if not ItemAdded then\n      aItem.Free;\n  end;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbCabArchive.CloseCabFile;\n  {Make sure the Cabinet DLL is shut down}\nvar\n  Abort : Boolean;\nbegin\n  if (FFDIContext <> nil) then begin\n    FDIDestroy(FFDIContext);\n    FFDIContext := nil;\n  end;\n  if (FFCIContext <> nil) then begin\n    FCIFlushCabinet(FFCIContext, False, @FCI_GetNextCab, @FCI_Status);\n    FCIDestroy(FFCIContext);\n    FFCIContext := nil;\n  end;\n  DoArchiveProgress(0, Abort);\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbCabArchive.CreateCabFile;\n  {create a new cabinet}\nbegin\n    {set cabinet parameters}\n  with FFCICabInfo do begin\n    if (SpanningThreshold > 0) then\n      cb := SpanningThreshold\n    else\n      cb := AbDefCabSpanningThreshold;\n    if (FolderThreshold > 0) then\n      cbFolderThresh := FolderThreshold\n    else\n      cbFolderThresh  := AbDefFolderThreshold;\n    cbReserveCFHeader := AbDefReserveHeaderSize;\n    cbReserveCFFolder := AbDefReserveFolderSize;\n    cbReserveCFData   := AbDefReserveDataSize;\n    iCab              := 1;\n    iDisk             := 0;\n    fFailOnIncompressible := 0;\n    setID             := SetID;\n    AbStrPCopy(szDisk, '');\n    AbStrPLCopy(szCab, FCabName, Length(szCab));\n    AbStrPLCopy(szCabPath, FCabPath, Length(szCabPath));\n  end;\n\n    {obtain an FCI context}\n  FFCIContext := FCICreate(@FErrors, @FCI_FileDest, @FXI_GetMem, @FXI_FreeMem,\n    @FCI_FileOpen, @FCI_FileRead, @FCI_FileWrite, @FCI_FileClose, @FCI_FileSeek,\n    @FCI_FileDelete, @FCI_GetTempFile, @FFCICabInfo, Self);\n  if (FFCIContext = nil) then\n    if FErrors.ErrorPresent then begin\n      CloseCabFile;\n      raise EAbFCICreateError.Create;\n    end;\nend;\n{ -------------------------------------------------------------------------- }\nfunction TAbCabArchive.CreateItem( const FileSpec : string ): TAbArchiveItem;\n  {create a new item for the file list}\nbegin\n  Result := TAbCabItem.Create;\n  with TAbCabItem(Result) do begin\n    CompressedSize := 0;\n    DiskFileName := ExpandFileName(FileSpec);\n    FileName := FixName(FileSpec);\n  end;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbCabArchive.DoCabItemProgress(BytesCompressed : DWord;\n  var Abort : Boolean);\n  {fire OnCabItemProgress event}\nvar\n  Progress : Byte;\nbegin\n  Abort := False;\n  if Assigned(FOnArchiveItemProgress) then begin\n    Inc(FItemProgress, BytesCompressed);\n    Progress := AbPercentage(FItemProgress,\n      FItemInProgress.UnCompressedSize);\n    FOnArchiveItemProgress(Self, FItemInProgress, Progress, Abort);\n  end;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbCabArchive.DoGetNextCabinet(CabIndex : Integer;\n  var CabName : string; var Abort : Boolean);\n  {fire OnRequestImage event}\nbegin\n  Abort := False;\n  if Assigned(FOnRequestImage) then\n    FOnRequestImage(Self, CabIndex, CabName, Abort)\n  else\n    AbIncFilename(CabName, CabIndex);\nend;\n{----------------------------------------------------------------------------}\nprocedure TAbCabArchive.ExtractItemAt(Index : Integer; const NewName : string);\n  {extract a file from the cabinet}\nbegin\n  FItemInProgress := GetItem(Index);\n  FIIPName := NewName;\n  try\n    if not FDICopy(FFDIContext, PAnsiChar(FCabName), PAnsiChar(FCabPath), 0,\n                   @FDI_ExtractFiles, nil, Self) then\n      DoProcessItemFailure(FItemInProgress, ptExtract, ecCabError, FErrors.ErrorCode);\n  finally\n    FIIPName := '';\n  end;\nend;\n{----------------------------------------------------------------------------}\nprocedure TAbCabArchive.ExtractItemToStreamAt(Index : Integer; OutStream : TStream);\nbegin\n  FItemInProgress := GetItem(Index);\n  FItemStream := OutStream;\n  try\n    if not FDICopy(FFDIContext, PAnsiChar(FCabName), PAnsiChar(FCabPath), 0,\n                   @FDI_ExtractFiles, nil, Self) then\n      DoProcessItemFailure(FItemInProgress, ptExtract, ecCabError, FErrors.ErrorCode);\n  finally\n    FItemStream := nil;\n  end;\nend;\n{----------------------------------------------------------------------------}\nfunction TAbCabArchive.GetItem(ItemIndex : Integer) : TAbCabItem;\n  {fetch an item from the file list}\nbegin\n  Result := TAbCabItem(FItemList.Items[ItemIndex]);\nend;\n{----------------------------------------------------------------------------}\nprocedure TAbCabArchive.LoadArchive;\n  {Open existing cabinet or create a new one}\nbegin\n  if (FMode = fmOpenRead) then begin\n    FFDIContext := FDICreate(@FXI_GetMem, @FXI_FreeMem, @FDI_FileOpen,\n    @FDI_FileRead, @FDI_FileWrite, @FDI_FileClose, @FDI_FileSeek,\n    cpuDefault, @FErrors);\n    if (FFDIContext = nil) then\n      raise EAbFDICreateError.Create;\n    OpenCabFile;\n  end else\n    CreateCabFile;\nend;\n{----------------------------------------------------------------------------}\nprocedure TAbCabArchive.NewCabinet;\n  {flush current cabinet and start a new one}\nbegin\n  if not FCIFlushCabinet(FFCIContext, True, @FCI_GetNextCab, @FCI_Status) then\n    raise EAbFCIFlushCabinetError.Create;\nend;\n{----------------------------------------------------------------------------}\nprocedure TAbCabArchive.NewFolder;\n  {flush current folder and start a new one}\nbegin\n  if not FCIFlushFolder(FFCIContext, @FCI_GetNextCab, @FCI_Status) then\n    raise EAbFCIFlushFolderError.Create;\nend;\n{----------------------------------------------------------------------------}\nprocedure TAbCabArchive.OpenCabFile;\n  {Open an existing cabinet}\nvar\n  Abort : Boolean;\n  Stream : TFileStream;\nbegin\n    {verify that the archive can be opened and is a cabinet}\n  Stream := TFileStream.Create(FArchiveName, fmOpenRead or fmShareDenyNone);\n  try\n    if not FDIIsCabinet(FFDIContext, PtrInt(Stream), @FFDICabInfo) then begin\n      CloseCabFile;\n      raise EAbInvalidCabFile.Create;\n    end;\n  finally\n    Stream.Free;\n  end;\n\n    {store information about the cabinet}\n  FCabSize := FFDICabInfo.cbCabinet;\n  FFolderCount := FFDICabInfo.cFolders;\n  FFileCount := FFDICabInfo.cFiles;\n  FCurrentCab := FFDICabInfo.iCabinet;\n  FHasPrev := FFDICabInfo.hasPrev;\n  FHasNext := FFDICabInfo.hasNext;\n\n    {Enumerate the files and build the file list}\n  if not FDICopy(FFDIContext, PAnsiChar(FCabName), PAnsiChar(FCabPath), 0,\n    @FDI_EnumerateFiles, nil, Self) then begin\n    CloseCabFile;\n    raise EAbFDICopyError.Create;\n  end;\n  DoArchiveProgress(100, Abort);\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbCabArchive.PutItem( Index : Integer; Value : TAbCabItem );\n  {replace an existing item in the file list}\nbegin\n  FItemList.Items[Index] := Value;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbCabArchive.SaveArchive;\nbegin\n  { No-op;  file is flushed in destructor }\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbCabArchive.SetFolderThreshold(Value : LongWord);\n  {set maximum compression boundary}\nbegin\n  if (Value > 0) then\n    FFolderThreshold := Value\n  else\n    FFolderThreshold := AbDefFolderThreshold;\n  FFCICabInfo.cbFolderThresh := FFolderThreshold;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbCabArchive.SetSetID(Value : Word);\n  {set cabinet SetID}\nbegin\n  FSetID := Value;\n  FFCICabInfo.SetID := Value;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbCabArchive.SetSpanningThreshold(Value : Int64);\n  {set maximum cabinet size}\nbegin\n  if (Value > 0) then\n    FSpanningThreshold := Value\n  else\n    FSpanningThreshold := AbDefCabSpanningThreshold;\n  FFCICabInfo.cb := FSpanningThreshold;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbCabArchive.TestItemAt(Index : Integer);\nbegin\n  {not implemented for cabinet archives}\nend;\n\nend.\n"
  },
  {
    "path": "lib/abbrevia/source/AbCharset.pas",
    "content": "(* ***** BEGIN LICENSE BLOCK *****\n * Version: MPL 1.1\n *\n * The contents of this file are subject to the Mozilla Public License Version\n * 1.1 (the \"License\"); you may not use this file except in compliance with\n * the License. You may obtain a copy of the License at\n * http://www.mozilla.org/MPL/\n *\n * Software distributed under the License is distributed on an \"AS IS\" basis,\n * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License\n * for the specific language governing rights and limitations under the\n * License.\n *\n * The Original Code is TurboPower Abbrevia\n *\n * The Initial Developer of the Original Code is\n * Craig Peterson <capeterson@users.sourceforge.net>\n *\n * Portions created by the Initial Developer are Copyright (C) 2011\n * the Initial Developer. All Rights Reserved.\n *\n * Contributor(s):\n *\n * ***** END LICENSE BLOCK ***** *)\n\n{*********************************************************}\n{* ABBREVIA: AbCharset.pas                               *}\n{*********************************************************}\n{* ABBREVIA: Types and routines for working with various *}\n{*   character encodings.                                *}\n{*********************************************************}\n\nunit AbCharset;\n\n{$I AbDefine.inc}\n\ninterface\n\n{$IFDEF MSWINDOWS}\nuses\n  Windows;\n{$ENDIF}\n\n{ Unicode backwards compatibility types }\n{$IF NOT DECLARED(RawByteString)}\ntype\n  RawByteString = AnsiString;\n{$IFEND}\n{$IF NOT DECLARED(UnicodeString)}\ntype\n  UnicodeString = WideString;\n{$IFEND}\n\ntype\n  TAbCharSet = (csASCII, csANSI, csUTF8);\n\nfunction AbDetectCharSet(const aValue: RawByteString): TAbCharSet;\n\nfunction AbIsOEM(const aValue: RawByteString): Boolean;\n\nfunction AbRawBytesToString(const aValue: RawByteString): string;\n\nfunction AbStringToUnixBytes(const aValue: string): RawByteString;\n\nfunction AbSysCharSetIsUTF8: Boolean;\n\n{$IFDEF MSWINDOWS}\nfunction AbTryEncode(const aValue: UnicodeString; aCodePage: UINT;\n  aAllowBestFit: Boolean; out aResult: AnsiString): Boolean;\n{$ENDIF}\n\n{ Unicode backwards compatibility functions }\n{$IFNDEF UNICODE}\nfunction UTF8ToString(const S: RawByteString): string;\n{$ENDIF}\n\nimplementation\n\nuses\n{$IFDEF LibcAPI}\n  Libc,\n{$ENDIF}\n  SysUtils;\n\nfunction AbDetectCharSet(const aValue: RawByteString): TAbCharSet;\nvar\n  i, TrailCnt: Integer;\nbegin\n  Result := csASCII;\n  TrailCnt := 0;\n  for i := 1 to Length(aValue) do begin\n    if Byte(aValue[i]) >= $80 then\n      Result := csANSI;\n    if TrailCnt > 0 then\n      if Byte(aValue[i]) in [$80..$BF] then\n        Dec(TrailCnt)\n      else Exit\n    else if Byte(aValue[i]) in [$80..$BF] then\n      Exit\n    else\n      case Byte(aValue[i]) of\n        $C0..$C1, $F5..$FF: Exit;\n        $C2..$DF: TrailCnt := 1;\n        $E0..$EF: TrailCnt := 2;\n        $F0..$F4: TrailCnt := 3;\n      end;\n  end;\n  if (TrailCnt = 0) and (Result = csANSI) then\n    Result := csUTF8;\nend;\n{ -------------------------------------------------------------------------- }\nfunction AbIsOEM(const aValue: RawByteString): Boolean;\n// Detect whether a string of bytes is likely to be the system's ANSI or OEM codepage\n{$IFDEF MSWINDOWS}\nconst\n  // Byte values of alpha-numeric characters in OEM and ANSI codepages.\n  // Excludes NBSP, ordinal indicators, exponents, the florin symbol, and, for\n  // ANSI codepages matched to certain OEM ones, the micro character.\n  //\n  // US (OEM 437, ANSI 1252)\n  Oem437AnsiChars =\n    [138, 140, 142, 154, 156, 158, 159, 181, 192..214, 216..246, 248..255];\n  Oem437OemChars =\n    [128..154, 160..165, 224..235, 237, 238];\n  // Arabic (OEM 720, ANSI 1256)\n  Oem720AnsiChars =\n    [129, 138, 140..144, 152, 154, 156, 159, 170, 181, 192..214, 216..239, 244,\n     249, 251, 252, 255];\n  Oem720OemChars =\n    [130, 131, 133, 135..140, 147, 149..155, 157..173, 224..239];\n  // Greek (OEM 737, ANSI 1253)\n  Oem737AnsiChars =\n    [162, 181, 184..186, 188, 190..209, 211..254];\n  Oem737OemChars =\n    [128..175, 224..240, 244, 245];\n  // Baltic Rim (OEM 775, ANSI 1257)\n  Oem775AnsiChars =\n    [168, 170, 175, 184, 186, 191..214, 216..246, 248..254];\n  Oem775OemChars =\n    [128..149, 151..155, 157, 160..165, 173, 181..184, 189, 190, 198, 199,\n     207..216, 224..238];\n  // Western European (OEM 850, ANSI 1252)\n  Oem850AnsiChars =\n    [138, 140, 142, 154, 156, 158, 159, 192..214, 216..246, 248..255];\n  Oem850OemChars =\n    [128..155, 157, 160..165, 181..183, 198, 199, 208..216, 222, 224..237];\n  // Central & Eastern European (OEM 852, ANSI 1250)\n  Oem852AnsiChars =\n    [138, 140..143, 154, 156..159, 163, 165, 170, 175, 179, 185, 186, 188,\n     190..214, 216..246, 248..254];\n  Oem852OemChars =\n    [128..157, 159..169, 171..173, 181..184, 189, 190, 198, 199, 208..216, 221,\n     222, 224..238, 251..253];\n  // Cyrillic (OEM 855, ANSI 1251)\n  Oem855AnsiChars =\n    [128, 129, 131, 138, 140..144, 154, 156..159, 161..163, 165, 168, 170, 175,\n     178..180, 184, 186, 188..255];\n  Oem855OemChars =\n    [128..173, 181..184, 189, 190, 198, 199, 208..216, 221, 222, 224..238,\n     241..252];\n  // Turkish (OEM 857, ANSI 1254)\n  Oem857AnsiChars =\n    [138, 140, 154, 156, 159, 192..214, 216..246, 248..255];\n  Oem857OemChars =\n    [128..155, 157..167, 181..183, 198, 199, 210..212, 214..216, 222, 224..230,\n     233..237];\n  // Hebrew (OEM 862, ANSI 1255)\n  Oem862AnsiChars =\n    [181, 212..214, 224..250];\n  Oem862OemChars =\n    [128..154, 160..165, 224..235, 237, 238];\n  // Cyrillic CIS (OEM 866, ANSI 1251)\n  Oem866AnsiChars =\n    [128, 129, 131, 138, 140..144, 154, 156..159, 161..163, 165, 168, 170, 175,\n     178..181, 184, 186, 188..255];\n  Oem866OemChars =\n    [128..175, 224..247];\nvar\n  AnsiChars, OemChars: set of Byte;\n  IsANSI: Boolean;\n  i: Integer;\nbegin\n  case GetOEMCP of\n    437:\n    begin\n      AnsiChars := Oem437AnsiChars;\n      OemChars := Oem437OemChars;\n    end;\n    720:\n    begin\n      AnsiChars := Oem720AnsiChars;\n      OemChars := Oem720OemChars;\n    end;\n    737:\n    begin\n      AnsiChars := Oem737AnsiChars;\n      OemChars := Oem737OemChars;\n    end;\n    775:\n    begin\n      AnsiChars := Oem775AnsiChars;\n      OemChars := Oem775OemChars;\n    end;\n    850:\n    begin\n      AnsiChars := Oem850AnsiChars;\n      OemChars := Oem850OemChars;\n    end;\n    852:\n    begin\n      AnsiChars := Oem852AnsiChars;\n      OemChars := Oem852OemChars;\n    end;\n    855:\n    begin\n      AnsiChars := Oem855AnsiChars;\n      OemChars := Oem855OemChars;\n    end;\n    857:\n    begin\n      AnsiChars := Oem857AnsiChars;\n      OemChars := Oem857OemChars;\n    end;\n    862:\n    begin\n      AnsiChars := Oem862AnsiChars;\n      OemChars := Oem862OemChars;\n    end;\n    866:\n    begin\n      AnsiChars := Oem866AnsiChars;\n      OemChars := Oem866OemChars;\n    end;\n    else\n    begin\n      Result := False;\n      Exit;\n    end;\n  end;\n\n  IsANSI := True;\n  Result := True;\n  for i := 0 to Length(aValue) do\n    if Ord(aValue[i]) >= $80 then\n    begin\n      if IsANSI then\n        IsANSI := Ord(aValue[i]) in AnsiChars;\n      if Result then\n        Result := Ord(aValue[i]) in OemChars;\n      if not IsANSI and not Result then\n        Break\n    end;\n  if IsANSI then\n    Result := False;\nend;\n{$ELSE !MSWINDOWS}\nbegin\n  Result := False;\nend;\n{$ENDIF !MSWINDOWS}\n{ -------------------------------------------------------------------------- }\nfunction AbSysCharSetIsUTF8: Boolean;\nbegin\n  {$IFDEF DARWIN}\n  Result := True;\n  {$ENDIF}\n  {$IFDEF MSWINDOWS}\n  Result := False;\n  {$ENDIF}\n  {$IFDEF LINUX}\n  Result := StrComp(nl_langinfo(_NL_CTYPE_CODESET_NAME), 'UTF-8') = 0;\n  {$ENDIF}\nend;\n{ -------------------------------------------------------------------------- }\nfunction AbRawBytesToString(const aValue: RawByteString): string;\n// Detect encoding of raw bytes and convert to a string\nbegin\n  case AbDetectCharSet(aValue) of\n    csASCII:\n      Result := string(aValue);\n\n    csANSI: begin\n      {$IFDEF MSWINDOWS}\n      if AbIsOEM(aValue) then begin\n        SetLength(Result, Length(aValue));\n        OemToCharBuff(PAnsiChar(aValue), PChar(Result), Length(Result));\n      end\n      else\n      {$ENDIF}\n        Result := string(aValue);\n    end;\n\n    csUTF8:\n      Result := UTF8ToString(aValue);\n  end;\nend;\n{ -------------------------------------------------------------------------- }\nfunction AbStringToUnixBytes(const aValue: string): RawByteString;\n// Convert from a string to an appropriate encoding for Unix archive types (tar/gz)\n// Based on testing the system encoding should be used on Linux, and UTF-8\n// everywhere else.  Windows apps don't agree on whether to use ANSI, OEM, or UTF-8.\nbegin\n  // Delphi XE2+ Posix platforms only support the UTF-8 locale\n  {$IF DEFINED(LINUX) AND (DEFINED(FPC) OR DEFINED(KYLIX))}\n  Result := AnsiString(aValue);\n  {$ELSE}\n  Result := UTF8Encode(aValue);\n  {$IFEND}\nend;\n{ -------------------------------------------------------------------------- }\n{$IFDEF MSWINDOWS}\nfunction AbTryEncode(const aValue: UnicodeString; aCodePage: UINT;\n  aAllowBestFit: Boolean; out aResult: AnsiString): Boolean;\n// Try to encode the given Unicode string as the requested codepage\nconst\n  WC_NO_BEST_FIT_CHARS = $00000400;\n  Flags: array[Boolean] of DWORD = (WC_NO_BEST_FIT_CHARS, 0);\nvar\n  UsedDefault: BOOL;\nbegin\n  if not aAllowBestFit and not CheckWin32Version(4, 1) then\n    Result := False\n  else begin\n    SetLength(aResult, WideCharToMultiByte(aCodePage, Flags[aAllowBestFit],\n      PWideChar(aValue), Length(aValue), nil, 0, nil, @UsedDefault));\n    SetLength(aResult, WideCharToMultiByte(aCodePage, Flags[aAllowBestFit],\n      PWideChar(aValue), Length(aValue), PAnsiChar(aResult),\n      Length(aResult), nil, @UsedDefault));\n    Result := not UsedDefault;\n  end;\nend;\n{$ENDIF MSWINDOWS}\n\n\n{ == Unicode backwards compatibility functions ============================= }\n{$IFNDEF UNICODE}\nfunction UTF8ToString(const S: RawByteString): string;\nbegin\n  Result := UTf8ToAnsi(S);\nend;\n{$ENDIF}\n\nend.\n"
  },
  {
    "path": "lib/abbrevia/source/AbComCtrls.pas",
    "content": "(* ***** BEGIN LICENSE BLOCK *****\n * Version: MPL 1.1\n *\n * The contents of this file are subject to the Mozilla Public License Version\n * 1.1 (the \"License\"); you may not use this file except in compliance with\n * the License. You may obtain a copy of the License at\n * http://www.mozilla.org/MPL/\n *\n * Software distributed under the License is distributed on an \"AS IS\" basis,\n * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License\n * for the specific language governing rights and limitations under the\n * License.\n *\n * The Original Code is TurboPower Abbrevia\n *\n * The Initial Developer of the Original Code is Craig Peterson\n *\n * Portions created by the Initial Developer are Copyright (C) 2011\n * the Initial Developer. All Rights Reserved.\n *\n * Contributor(s):\n * Craig Peterson <capeterson@users.sourceforge.net>\n *\n * ***** END LICENSE BLOCK ***** *)\n\n{*********************************************************}\n{* ABBREVIA: AbComCtrls.pas                              *}\n{*********************************************************}\n{* ABBREVIA: Listview and treeview components that work  *}\n{*   with an archive component.  The treeview can have a *}\n{*   listview associated, in which case the listview will*}\n{*   only show items in the selected folder.             *}\n{*********************************************************}\n\nunit AbComCtrls;\n\ninterface\n\n{$I AbDefine.inc}\n\nuses\n  Windows, Messages, SysUtils, Classes, Controls, ComCtrls, Graphics, AbBrowse,\n  AbArcTyp;\n\nconst\n  AbTreeArchiveImage        = 0;\n  AbTreeFolderImage         = 1;\n  AbTreeFolderExpandedImage = 2;\n\ntype\n{ ===== TAbListItem ========================================================= }\n  TAbListItem = class(TListItem)\n  protected {private}\n    FArchiveItem : TAbArchiveItem;\n  protected {methods}\n    function GetIsDirectory : Boolean;\n    function GetIsEncrypted : Boolean;\n  public {properties}\n    property ArchiveItem : TAbArchiveItem\n      read FArchiveItem\n      write FArchiveItem;\n    property IsDirectory : Boolean\n      read GetIsDirectory;\n    property IsEncrypted : Boolean\n      read GetIsEncrypted;\n  end;\n\n\n{ ===== TAbListItems ======================================================== }\n  TAbListItems = class(TListItems)\n  protected {methods}\n    function GetItem(aIndex: Integer): TAbListItem;\n    procedure SetItem(aIndex: Integer; aValue: TAbListItem);\n  public {properties}\n    property Item[Index: Integer]: TAbListItem\n      read GetItem\n      write SetItem; default;\n  end;\n\n\n{ ===== TAbCustomListView =================================================== }\ntype\n  TAbViewColumn =\n    (vcName, vcFileType, vcLastModified, vcSize, vcRatio,\n     vcPacked, vcCRC, vcAttributes, vcEncrypted, vcMethod, vcPath);\n  TAbViewColumns = set of TAbViewColumn;\n\nconst\n  AbDefVisibleColumns = [Low(TAbViewColumn)..High(TAbViewColumn)];\n\ntype\n  TAbCustomTreeView = class;\n\n  {$IF NOT DECLARED(TWindowProcPtr)}\n  TWindowProcPtr = Pointer;\n  {$IFEND}\n\n  TAbCustomListView = class(TCustomListView)\n  protected {private}\n    FArchive : TAbBaseBrowser;\n    FDefHeaderProc : TWindowProcPtr;\n    FFlatList: Boolean;\n    FHeaderHandle : HWND;\n    FHeaderImages : TImageList;\n    FHeaderInstance : Pointer;\n    FInUpdateSortArrows: Boolean;\n    FPath : string;\n    FSortAscending : Boolean;\n    FSortColIndex : Integer;\n    FSortColumn : TAbViewColumn;\n    FSortUpBmp : HBITMAP;\n    FSortDownBmp : HBITMAP;\n    FTreeView : TAbCustomTreeView;\n    FVisibleColumns : TAbViewColumns;\n\n  protected {methods}\n    procedure ColClick(aColumn: TListColumn);\n      override;\n    function CreateListItem: TListItem;\n      override;\n    function CreateListItems: TListItems;\n      override;\n    procedure CreateWnd;\n      override;\n    function CustomDrawSubItem(Item: TListItem; SubItem: Integer;\n      State: TCustomDrawState; Stage: TCustomDrawStage): Boolean;\n      override;\n    procedure DblClick;\n      override;\n    procedure DoChange(Sender : TObject);\n      virtual;\n    function GetListItems: TAbListItems;\n    function GetVersion: string;\n    procedure HeaderWndProc(var Msg: TMessage);\n      virtual;\n    function IsCustomDrawn(Target: TCustomDrawTarget; Stage: TCustomDrawStage): Boolean;\n      override;\n    procedure Notification(aComponent : TComponent; aOperation : TOperation);\n      override;\n    procedure SetArchive(aValue : TAbBaseBrowser);\n    procedure SetFlatList(aValue : Boolean);\n    procedure SetPath(aValue : string);\n    procedure SetTreeView(aValue : TAbCustomTreeView);\n    procedure SetVisibleColumns(aValue : TAbViewColumns);\n    procedure UpdateColumns;\n    procedure UpdateSortArrow;\n    procedure UpdateView;\n\n  protected {properties}\n    property HeaderImages : TImageList\n      read FHeaderImages;\n\n  public {methods}\n    constructor Create(aOwner: TComponent);\n      override;\n    destructor Destroy;\n      override;\n    procedure Sort(aColumn: TAbViewColumn; aAscending: Boolean);\n\n  public {properties}\n    property Archive : TAbBaseBrowser\n      read FArchive\n      write SetArchive;\n    property Columns;\n    // Show only items in the current path\n    property FlatList : Boolean\n      read FFlatList\n      write SetFlatList;\n    property Items: TAbListItems\n      read GetListItems\n      stored False;\n    property TreeView : TAbCustomTreeView\n      read FTreeView\n      write SetTreeView;\n    property Path : string\n      read FPath\n      write SetPath;\n    property Version : string\n      read GetVersion\n      stored False;\n    property VisibleColumns : TAbViewColumns\n      read FVisibleColumns\n      write SetVisibleColumns\n      default AbDefVisibleColumns;\n  end;\n\n\n{ ===== TAbListView ========================================================= }\n  TAbListView = class(TAbCustomListView)\n  published\n    property Action;\n    property Align;\n    property AllocBy;\n    property Anchors;\n    property Archive;\n    property BevelEdges;\n    property BevelInner;\n    property BevelOuter;\n    property BevelKind default bkNone;\n    property BevelWidth;\n    property BiDiMode;\n    property BorderStyle;\n    property BorderWidth;\n    property Checkboxes;\n    property Color;\n    property ColumnClick;\n    property Constraints;\n    property Ctl3D;\n    property DoubleBuffered;\n    property DragCursor;\n    property DragKind;\n    property DragMode;\n    property Enabled;\n    property Font;\n    property FlatScrollBars;\n    property FullDrag;\n    property GridLines;\n{$IFDEF HasListViewGroups}\n    property Groups;\n{$ENDIF}\n    property HideSelection;\n    property HotTrack;\n    property HotTrackStyles;\n    property HoverTime;\n    property IconOptions;\n    property Items;\n    property LargeImages;\n    property MultiSelect;\n{$IFDEF HasListViewGroups}\n    property GroupHeaderImages;\n    property GroupView default False;\n{$ENDIF}\n    property ReadOnly default False;\n    property RowSelect;\n    property ParentBiDiMode;\n    property ParentColor default False;\n{$IFDEF HasParentDoubleBuffered}\n    property ParentDoubleBuffered;\n{$ENDIF}\n    property ParentFont;\n    property ParentShowHint;\n    property Path;\n    property PopupMenu;\n    property ShowColumnHeaders;\n    property ShowWorkAreas;\n    property ShowHint;\n    property TabOrder;\n    property TabStop default True;\n    property TreeView;\n    property Version;\n    property ViewStyle;\n    property Visible;\n    property VisibleColumns;\n    property OnClick;\n    property OnColumnClick;\n    property OnColumnDragged;\n    property OnColumnRightClick;\n    property OnContextPopup;\n    property OnDblClick;\n    property OnEdited;\n    property OnEditing;\n    property OnEndDock;\n    property OnEndDrag;\n    property OnEnter;\n    property OnExit;\n    property OnDragDrop;\n    property OnDragOver;\n    property OnInfoTip;\n    property OnKeyDown;\n    property OnKeyPress;\n    property OnKeyUp;\n{$IFDEF HasOnMouseActivate}\n    property OnMouseActivate;\n{$ENDIF}\n    property OnMouseDown;\n{$IFDEF HasOnMouseEnter}\n    property OnMouseEnter;\n    property OnMouseLeave;\n{$ENDIF}\n    property OnMouseMove;\n    property OnMouseUp;\n    property OnResize;\n    property OnSelectItem;\n{$IFDEF HasListViewOnItemChecked}\n    property OnItemChecked;\n{$ENDIF}\n    property OnStartDock;\n    property OnStartDrag;\n  end;\n\n\n{ ===== TAbCustomTreeView =================================================== }\n  TAbCustomTreeView = class(TTreeView)\n  protected {private}\n    FArchive: TAbBaseBrowser;\n    FListView: TAbCustomListView;\n    FPath: string;\n\n  protected {methods}\n    procedure Change(aNode: TTreeNode);\n      override;\n    procedure DoChange(Sender : TObject);\n      virtual;\n    procedure GetSelectedIndex(aNode: TTreeNode);\n      override;\n    function GetVersion: string;\n    procedure Notification(aComponent : TComponent; aOperation : TOperation);\n      override;\n    procedure SelectPathNode;\n    procedure SetArchive(aValue: TAbBaseBrowser);\n    procedure SetListView(aValue: TAbCustomListView);\n    procedure SetPath(const aValue: string);\n\n  public {methods}\n    constructor Create(aOwner: TComponent);\n      override;\n\n  public {properties}\n    property Archive: TAbBaseBrowser\n      read FArchive\n      write SetArchive;\n    property HideSelection\n      default False;\n    property ListView: TAbCustomListView\n      read FListView\n      write SetListView;\n    property Path: string\n      read FPath\n      write SetPath;\n    property Version: string\n      read GetVersion\n      stored False;\n  end;\n\n\n{ ===== TAbTreeView ========================================================= }\n  TAbTreeView = class(TAbCustomTreeView)\n  published\n    property Align;\n    property Anchors;\n    property Archive;\n    property AutoExpand;\n    property BevelEdges;\n    property BevelInner;\n    property BevelOuter;\n    property BevelKind default bkNone;\n    property BevelWidth;\n    property BiDiMode;\n    property BorderStyle;\n    property BorderWidth;\n    property ChangeDelay;\n    property Color;\n    property Ctl3D;\n    property Constraints;\n    property DoubleBuffered;\n    property DragKind;\n    property DragCursor;\n    property DragMode;\n    property Enabled;\n    property Font;\n    property HideSelection;\n    property HotTrack;\n    property Indent;\n    property Items;\n    property ListView;\n    property ParentBiDiMode;\n    property ParentColor default False;\n    property ParentCtl3D;\n{$IFDEF HasParentDoubleBuffered}\n    property ParentDoubleBuffered;\n{$ENDIF}\n    property ParentFont;\n    property ParentShowHint;\n    property Path;\n    property PopupMenu;\n    property ReadOnly;\n    property RightClickSelect;\n    property RowSelect;\n    property ShowButtons;\n    property ShowHint;\n    property ShowLines;\n    property ShowRoot;\n    property TabOrder;\n    property TabStop default True;\n    property ToolTips;\n    property Version;\n    property Visible;\n    property OnChanging;\n    property OnClick;\n    property OnCollapsed;\n    property OnCollapsing;\n    property OnContextPopup;\n    property OnDblClick;\n    property OnDeletion;\n    property OnDragDrop;\n    property OnDragOver;\n    property OnEdited;\n    property OnEditing;\n    property OnEndDock;\n    property OnEndDrag;\n    property OnEnter;\n    property OnExit;\n    property OnExpanding;\n    property OnExpanded;\n    property OnKeyDown;\n    property OnKeyPress;\n    property OnKeyUp;\n{$IFDEF HasOnMouseActivate}\n    property OnMouseActivate;\n{$ENDIF}\n    property OnMouseDown;\n{$IFDEF HasOnMouseEnter}\n    property OnMouseEnter;\n    property OnMouseLeave;\n{$ENDIF}\n    property OnMouseMove;\n    property OnMouseUp;\n    property OnStartDock;\n    property OnStartDrag;\n  end;\n\n\n{ ===== TAbProgressBar ====================================================== }\n  TAbProgressBar = class(TProgressBar, IAbProgressMeter)\n  protected {private}\n    function  GetVersion : string;\n\n  public {methods}\n    procedure DoProgress(Progress : Byte);\n    procedure Reset;\n\n  published {properties}\n    property Version: string\n      read GetVersion\n      stored False;\n  end;\n\n\nimplementation\n\n{$R AbComCtrls.res}\n\nuses\n  CommCtrl, Contnrs, Forms, ShellAPI, StrUtils, AbConst, AbResString, AbUtils,\n  AbZipTyp;\n\nconst\n  HDF_SORTDOWN = $0200;\n  HDF_SORTUP   = $0400;\n\n{ -------------------------------------------------------------------------- }\n{$IF NOT DECLARED(StartsText)}\nfunction StartsText(const aSubText, aText: string): Boolean;\nbegin\n  Result := (Length(aText) > Length(aSubText)) and\n    SameText(aSubText, Copy(aText, 1, Length(aSubText)));\nend;\n{$IFEND}\n{ -------------------------------------------------------------------------- }\nfunction AbNormalizeFilename(const aFilename: string): string;\nvar\n  i: Integer;\nbegin\n  Result := aFilename;\n  for i := 1 to Length(Result) do\n    if IsDelimiter('\\/', Result, i) then\n      Result[i] := PathDelim;\n  if IsDelimiter(PathDelim, Result, Length(Result)) then\n    SetLength(Result, Length(Result) - 1);\nend;\n{ -------------------------------------------------------------------------- }\nvar\n  ComCtl32MajorVer: Integer = -1;\n\nfunction IsComCtl32Version6: Boolean;\ntype\n  PDllVersionInfo = ^TDllVersionInfo;\n  TDllVersionInfo = packed record\n    cbSize: DWORD;\n    dwMajorVersion: DWORD;\n    dwMinorVersion: DWORD;\n    dwBuildNumber: DWORD;\n    dwPlatformId: DWORD;\n  end;\nvar\n  DllGetVersion: function(pdvi: PDllVersionInfo): HRESULT; stdcall;\n  dvi: TDllVersionInfo;\n  hComCtl32: HMODULE;\nbegin\n  if ComCtl32MajorVer = -1 then begin\n    ComCtl32MajorVer := 0;\n    hComCtl32 := LoadLibrary(comctl32);\n    if hComCtl32 <> 0 then begin\n      DllGetVersion := GetProcAddress(hComCtl32, 'DllGetVersion');\n      if Assigned(DllGetVersion) then begin\n        dvi.cbSize := SizeOf(dvi);\n        if Succeeded(DllGetVersion(@dvi)) then\n          ComCtl32MajorVer := dvi.dwMajorVersion;\n      end;\n      FreeLibrary(hComCtl32);\n    end;\n  end;\n  Result := ComCtl32MajorVer >= 6;\nend;\n{ -------------------------------------------------------------------------- }\nfunction SameEvent(const aEvent1, aEvent2: TNotifyEvent): Boolean;\nbegin\n  Result := (TMethod(aEvent1).Code = TMethod(aEvent2).Code) and\n    (TMethod(aEvent1).Data = TMethod(aEvent2).Data);\nend;\n\n\n\n{ ===== TAbListItem ========================================================= }\nfunction TAbListItem.GetIsDirectory: Boolean;\nbegin\n  Result := (ArchiveItem = nil) or ArchiveItem.IsDirectory;\nend;\n{ -------------------------------------------------------------------------- }\nfunction TAbListItem.GetIsEncrypted: Boolean;\nbegin\n  Result := (ArchiveItem <> nil) and ArchiveItem.IsEncrypted;\nend;\n\n\n{ ===== TAbListItems ======================================================== }\nfunction TAbListItems.GetItem(aIndex: Integer): TAbListItem;\nbegin\n  Result := inherited Item[aIndex] as TAbListItem;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbListItems.SetItem(aIndex: Integer; aValue: TAbListItem);\nbegin\n  inherited Item[aIndex] := aValue;\nend;\n\n{ ===== TAbCustomListView =================================================== }\nconstructor TAbCustomListView.Create(aOwner: TComponent);\nvar\n  Bmp : TBitmap;\n  sfi: SHFILEINFO;\nbegin\n  inherited;\n  FHeaderInstance := MakeObjectInstance(HeaderWndProc);\n  // Load header image into an image list;  the header's hbm property\n  // doesn't support transparency\n  FHeaderImages := TImageList.Create(Self);\n  Bmp := TBitmap.Create;\n  try\n    Bmp.LoadFromResourceName(HInstance, 'AbComCtrls_Lock');\n    FHeaderImages.AddMasked(Bmp, clFuchsia);\n  finally\n    Bmp.Free;\n  end;\n  // Load system image lists\n  LargeImages := TImageList.Create(Self);\n  LargeImages.ShareImages := True;\n  LargeImages.Handle := SHGetFileInfo('', 0, sfi, SizeOf(sfi),\n    SHGFI_LARGEICON or SHGFI_SYSICONINDEX);\n  SmallImages := TImageList.Create(Self);\n  SmallImages.ShareImages := True;\n  SmallImages.Handle := SHGetFileInfo('', 0, sfi, SizeOf(sfi),\n    SHGFI_SMALLICON or SHGFI_SYSICONINDEX);\n  // Load sort arrow bitmaps for older comctrl32.dll versions\n  FSortAscending := True;\n  FSortColumn := vcName;\n  if not IsComCtl32Version6 then begin\n    FSortUpBmp := LoadImage(HInstance, 'AbComCtrls_SortUp', IMAGE_BITMAP, 0, 0, LR_LOADMAP3DCOLORS);\n    FSortDownBmp := LoadImage(HInstance, 'AbComCtrls_SortDown', IMAGE_BITMAP, 0, 0, LR_LOADMAP3DColors);\n  end;\n  // Set default column visibility\n  VisibleColumns := AbDefVisibleColumns;\nend;\n{ -------------------------------------------------------------------------- }\ndestructor TAbCustomListView.Destroy;\nbegin\n  if FHeaderHandle <> 0 then\n    SetWindowLong(FHeaderHandle, GWL_WNDPROC, LongInt(FDefHeaderProc));\n  FreeObjectInstance(FHeaderInstance);\n  if FSortUpBmp <> 0 then\n    DeleteObject(FSortUpBmp);\n  if FSortDownBmp <> 0 then\n    DeleteObject(FSortDownBmp);\n  inherited;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbCustomListView.ColClick(aColumn: TListColumn);\nvar\n  Col: TAbViewColumn;\nbegin\n  inherited;\n  Col := TAbViewColumn(aColumn.Tag);\n  Sort(Col, (Col <> FSortColumn) or not FSortAscending);\nend;\n{ -------------------------------------------------------------------------- }\nfunction TAbCustomListView.CreateListItem: TListItem;\nbegin\n  Result := TAbListItem.Create(Items);\nend;\n{ -------------------------------------------------------------------------- }\nfunction TAbCustomListView.CreateListItems: TListItems;\nbegin\n  Result := TAbListItems.Create(Self);\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbCustomListView.CreateWnd;\nbegin\n  inherited;\n  FHeaderHandle := ListView_GetHeader(Handle);\n  if FHeaderHandle <> 0 then begin\n    FDefHeaderProc := TWindowProcPtr(GetWindowLong(FHeaderHandle, GWL_WNDPROC));\n    SetWindowLong(FHeaderHandle, GWL_WNDPROC, LongInt(FHeaderInstance));\n  end;\n  Header_SetImageList(ListView_GetHeader(Handle), FHeaderImages.Handle);\n  UpdateColumns;\n  UpdateView;\nend;\n{ -------------------------------------------------------------------------- }\nfunction TAbCustomListView.CustomDrawSubItem(Item: TListItem; SubItem: Integer;\n  State: TCustomDrawState; Stage: TCustomDrawStage): Boolean;\nvar\n  i: Integer;\n  R: TRect;\nbegin\n  Result := True;\n  if (Stage = cdPrePaint) and TAbListItem(Item).IsEncrypted then\n    if TAbViewColumn(Columns[SubItem].Tag) = vcEncrypted then begin\n      Result := False;\n      R := Item.DisplayRect(drBounds);\n      Inc(R.Left, 6);\n      for i := 0 to SubItem - 1 do\n        Inc(R.Left, Columns[i].Width);\n      HeaderImages.Draw(Canvas, R.Left, R.Top, 0);\n    end\n    else begin\n      Result := True;\n      // Fixed other columns drawing with wrong font after using TImageList.Draw\n      Canvas.Brush.Color := ColorToRGB(Color);\n      SetBkMode(Canvas.Handle, TRANSPARENT);\n    end;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbCustomListView.DblClick;\nbegin\n  inherited;\n  if TAbListItem(Selected).IsDirectory then\n    if Path = '' then\n      Path := Selected.Caption\n    else\n      Path := Path + PathDelim + Selected.Caption;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbCustomListView.DoChange(Sender: TObject);\nbegin\n  UpdateView;\n  if (Sender = FArchive) and Assigned(FTreeView) then\n    FTreeView.DoChange(Self);\nend;\n{ -------------------------------------------------------------------------- }\nfunction TAbCustomListView.GetListItems: TAbListItems;\nbegin\n  Result := inherited Items as TAbListItems;\nend;\n{ -------------------------------------------------------------------------- }\nfunction TAbCustomListView.GetVersion: string;\nbegin\n  Result := AbVersionS;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbCustomListView.HeaderWndProc(var Msg: TMessage);\nconst\n  FMT_MASK = HDF_BITMAP or HDF_BITMAP_ON_RIGHT or HDF_SORTDOWN or HDF_SORTUP;\nvar\n  Item: THDItem;\nbegin\n  if (Msg.Msg = HDM_SETITEM) and not FInUpdateSortArrows then begin\n    Item.Mask := HDI_FORMAT;\n    if Header_GetItem(FHeaderHandle, Msg.WParam, Item) then begin\n      PHDItem(Msg.LParam).Mask := PHDItem(Msg.LParam).Mask and not HDI_BITMAP;\n      PHDItem(Msg.LParam).fmt := PHDItem(Msg.LParam).fmt and not FMT_MASK\n        or (Item.fmt and FMT_MASK);\n    end;\n  end;\n  Msg.Result := CallWindowProc(FDefHeaderProc, FHeaderHandle, Msg.Msg,\n    Msg.WParam, Msg.LParam);\n  if Msg.Msg = WM_DESTROY then\n    FHeaderHandle := 0;\nend;\n{ -------------------------------------------------------------------------- }\nfunction TAbCustomListView.IsCustomDrawn(Target: TCustomDrawTarget;\n  Stage: TCustomDrawStage): Boolean;\nbegin\n  Result := (vcEncrypted in VisibleColumns) and (Stage = cdPrePaint) and\n    (Target = dtSubItem);\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbCustomListView.Notification(aComponent: TComponent;\n  aOperation: TOperation);\nbegin\n  inherited;\n  if aOperation = opRemove then begin\n    if aComponent = FArchive then begin\n      FArchive := nil;\n      Clear;\n    end;\n    if aComponent = FTreeView then begin\n      if Assigned(FArchive) and SameEvent(FArchive.OnChange, FTreeView.DoChange) then\n        FArchive.OnChange := DoChange;\n      FTreeView := nil;\n    end;\n  end;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbCustomListView.SetArchive(aValue: TAbBaseBrowser);\nbegin\n  if aValue <> FArchive then begin\n    if Assigned(FArchive) then begin\n      FArchive.RemoveFreeNotification(Self);\n      if SameEvent(FArchive.OnChange, DoChange) then\n        if Assigned(TreeView) and (TreeView.Archive = FArchive) then\n          FArchive.OnChange := TreeView.DoChange\n        else\n          FArchive.OnChange := nil;\n    end;\n    FArchive := aValue;\n    if Assigned(FArchive) then begin\n      FArchive.FreeNotification(Self);\n      FArchive.OnChange := DoChange;\n      DoChange(Self);\n    end\n    else\n      Items.Clear;\n    if Assigned(TreeView) then\n      TreeView.Archive := aValue;\n  end;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbCustomListView.SetFlatList(aValue : Boolean);\nbegin\n  if aValue <> FFlatList then begin\n    FFlatList := aValue;\n    UpdateView;\n  end;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbCustomListView.SetPath(aValue: string);\nbegin\n  if aValue <> FPath then begin\n    FPath := ExcludeTrailingPathDelimiter(aValue);\n    if Assigned(TreeView) then\n      TreeView.Path := aValue;\n    if not FlatList then\n      UpdateView;\n  end;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbCustomListView.SetTreeView(aValue: TAbCustomTreeView);\nbegin\n  if aValue <> FTreeView then begin\n    if Assigned(FTreeView) then begin\n      FTreeView.RemoveFreeNotification(Self);\n      FTreeView.ListView := nil;\n    end;\n    FTreeView := aValue;\n    if Assigned(FTreeView) then begin\n      FTreeView.FreeNotification(Self);\n      if Assigned(FArchive) then\n        FTreeView.Archive := FArchive\n      else if Assigned(FTreeView.Archive) then\n        Archive := FTreeView.Archive;\n      FTreeView.ListView := Self;\n    end;\n  end;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbCustomListView.SetVisibleColumns(aValue : TAbViewColumns);\nbegin\n  if aValue <> FVisibleColumns then begin\n    FVisibleColumns := aValue;\n    UpdateColumns;\n    UpdateView;\n  end;\nend;\n{ -------------------------------------------------------------------------- }\nfunction TAbCustomListView_SortProc(aItem1, aItem2: TAbListItem;\n  aListView: TAbCustomListView): Integer; stdcall;\nvar\n  Item1, Item2: TAbArchiveItem;\n  Ratio1, Ratio2: Single;\nbegin\n  if aItem1.IsDirectory <> aItem2.IsDirectory then\n    if aItem1.IsDirectory then\n      Result := -1\n    else\n      Result := 1\n  else begin\n    Result := 0;\n    if aListView.FSortColumn in [vcFileType, vcPath] then begin\n      Result := CompareText(aItem1.SubItems[aListView.FSortColIndex],\n                            aItem2.SubItems[aListView.FSortColIndex]);\n    end\n    else if not aItem1.IsDirectory then begin\n      // Don't do more advanced sorts for directories, since they may be\n      // implicitly stored and won't have corresponding archive items\n      Item1 := aItem1.ArchiveItem;\n      Item2 := aItem2.ArchiveItem;\n      case aListView.FSortColumn of\n        vcLastModified:\n          begin\n            if Item1.LastModTimeAsDateTime < Item2.LastModTimeAsDateTime then\n              Result := -1\n            else if Item1.LastModTimeAsDateTime > Item2.LastModTimeAsDateTime then\n              Result := 1;\n          end;\n        vcSize:\n          begin\n            if Item1.UncompressedSize < Item2.UncompressedSize then\n              Result := -1\n            else if Item1.UncompressedSize > Item2.UncompressedSize then\n              Result := 1;\n          end;\n        vcRatio:\n          begin\n            if Item1.UncompressedSize > 0 then\n              Ratio1 := Item1.CompressedSize / Item1.UncompressedSize\n            else\n              Ratio1 := 1;\n            if Item2.UncompressedSize > 0 then\n              Ratio2 := Item2.CompressedSize / Item2.UncompressedSize\n            else\n              Ratio2 := 1;\n            if Ratio1 > Ratio2 then\n              Result := -1\n            else if Ratio1 < Ratio2 then\n              Result := 1\n          end;\n        vcPacked:\n          begin\n            if Item1.CompressedSize < Item2.CompressedSize then\n              Result := -1\n            else if Item1.CompressedSize > Item2.CompressedSize then\n              Result := 1;\n          end;\n        vcCRC:\n          begin\n            if Longword(Item1.CRC32) < Longword(Item2.CRC32) then\n              Result := -1\n            else if Longword(Item1.CRC32) > Longword(Item2.CRC32) then\n              Result := 1;\n          end;\n        vcAttributes,\n        vcMethod:\n          begin\n            Result := CompareText(aItem1.SubItems[aListView.FSortColIndex],\n                                  aItem2.SubItems[aListView.FSortColIndex]);\n          end;\n        vcEncrypted:\n          begin\n            if not Item1.IsEncrypted and Item2.IsEncrypted then\n              Result := -1\n            else if Item1.IsEncrypted and not Item2.IsEncrypted then\n              Result := 1\n          end;\n      end;\n    end;\n    if Result = 0 then\n      Result := AnsiCompareText(aItem1.Caption, aItem2.Caption);\n  end;\n  if not aListView.FSortAscending then\n    Result := -Result;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbCustomListView.Sort(aColumn: TAbViewColumn; aAscending: Boolean);\nbegin\n  if (aColumn <> FSortColumn) or (aAscending <> FSortAscending) then begin\n    FSortColumn := aColumn;\n    FSortAscending := aAscending;\n    UpdateSortArrow;\n    CustomSort(TLVCompare(@TAbCustomListView_SortProc), LPARAM(Self));\n  end;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbCustomListView.UpdateColumns;\nconst\n  ColWidths: array[TAbViewColumn] of Integer = (\n    180{vcName}, 110{vcFileType}, 130{vcLastModified}, 80{vcSize}, 50{vcRatio},\n    80{vcPacked}, 70{vcCRC}, 30{vcAttributes}, 28{vcEncrypted}, 60{vcMethod},\n    300{vcPath});\nvar\n  Col: TAbViewColumn;\n  Column: TListColumn;\nbegin\n  if HandleAllocated then\n    Items.BeginUpdate;\n  Columns.BeginUpdate;\n  try\n    Columns.Clear;\n    for Col := Low(Col) to High(Col) do begin\n      if not (Col in FVisibleColumns) then\n        Continue;\n      Column := Columns.Add;\n      case Col of\n        vcName: Column.Caption := AbItemNameHeadingS;\n        vcFileType: Column.Caption := AbFileTypeHeadingS;\n        vcLastModified: Column.Caption := AbLastModifiedHeadingS;\n        vcSize: Column.Caption := AbFileSizeHeadingS;\n        vcRatio: Column.Caption := AbRatioHeadingS;\n        vcPacked: Column.Caption := AbPackedHeadingS;\n        vcCRC: Column.Caption := AbCRCHeadingS;\n        vcAttributes: Column.Caption := AbFileAttrHeadingS;\n        vcEncrypted: Column.ImageIndex := 0;\n        vcMethod: Column.Caption := AbMethodHeadingS;\n        vcPath: Column.Caption := AbPathHeadingS;\n      end;\n      Column.Width := ColWidths[Col];\n      Column.Tag := Ord(Col);\n      if Col in [vcSize, vcRatio, vcPacked] then\n        Column.Alignment := taRightJustify;\n    end;\n  finally\n    Columns.EndUpdate;\n    if HandleAllocated then\n      Items.EndUpdate;\n  end;\n  UpdateSortArrow;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbCustomListView.UpdateSortArrow;\nvar\n  i: Integer;\n  Item: THDITEM;\nbegin\n  if not HandleAllocated then\n    Exit;\n  FInUpdateSortArrows := True;\n  try\n    for i := 0 to Columns.Count - 1 do begin\n      FillChar(Item, SizeOf(Item), 0);\n      Item.Mask := HDI_FORMAT;\n      if not IsComCtl32Version6 then\n        Item.Mask := Item.Mask or HDI_BITMAP;\n      Header_GetItem(FHeaderHandle, Columns[i].Index, Item);\n      // Add sort arrow to requested column\n      if TAbViewColumn(Columns[i].Tag) = FSortColumn then begin\n        FSortColIndex := i - 1;\n        if IsComCtl32Version6 then begin\n          Item.fmt := Item.fmt and not (HDF_SORTDOWN or HDF_SORTUP);\n          if FSortAscending then\n            Item.fmt := Item.fmt or HDF_SORTUP\n          else\n            Item.fmt := Item.fmt or HDF_SORTDOWN;\n        end\n        else begin\n          Item.fmt := Item.fmt or HDF_BITMAP or HDF_BITMAP_ON_RIGHT;\n          if FSortAscending then\n            Item.hbm := FSortUpBmp\n          else\n            Item.hbm := FSortDownBmp;\n        end;\n      end\n      // Remove sort arrow from other columns\n      else begin\n        if IsComCtl32Version6 then\n          Item.fmt := Item.fmt and not (HDF_SORTDOWN or HDF_SORTUP)\n        else begin\n          Item.Mask := Item.Mask and not HDI_BITMAP;\n          Item.fmt := Item.fmt and not (HDF_BITMAP OR HDF_BITMAP_ON_RIGHT);\n        end;\n      end;\n      Header_SetItem(FHeaderHandle, Columns[i].Index, Item);\n    end;\n  finally\n    FInUpdateSortArrows := False;\n  end;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbCustomListView.UpdateView;\nvar\n  ArcItem: TAbArchiveItem;\n  Col: TAbViewColumn;\n  ColImage: Integer;\n  ColText, Filename, FolderName: string;\n  DOSAttr: Integer;\n  Folders: TStringList;\n  i, j: Integer;\n  ListItem: TAbListItem;\n  ParentDir: string;\n  sfi: SHFILEINFO;\nbegin\n  ListItem := nil; // Suppress compiler warning\n  if (Items.Count = 0) and (FArchive = nil) then\n    Exit;\n  Items.BeginUpdate;\n  try\n    Items.Clear;\n    if Assigned(FArchive) then begin\n      Folders := TStringList.Create;\n      try\n        for i := 0 to FArchive.Count - 1 do\n          if FArchive[i].Action <> aaDelete then begin\n            ArcItem := FArchive[i];\n            Filename := AbNormalizeFilename(ArcItem.FileName);\n            // Exclude unwanted items\n            if FlatList and ArcItem.IsDirectory then\n              Continue;\n            // Create new ListItem\n            ParentDir := ExtractFileDir(FileName);\n            if FlatList or (ParentDir = Path) then begin\n              // If an ListItem has already been created for a folder, use it\n              if ArcItem.IsDirectory then begin\n                FolderName := ExtractFileName(FileName);\n                if Folders.Find(FolderName, j) then\n                  ListItem := Folders.Objects[j] as TAbListItem\n                else begin\n                  ListItem := Items.Add as TAbListItem;\n                  Folders.AddObject(FolderName, ListItem);\n                end\n              end\n              else\n                ListItem := Items.Add as TAbListItem;\n              ListItem.ArchiveItem := FArchive[i];\n            end\n            else if (Path = '') or StartsText(Path + PathDelim, ParentDir) then begin\n              // Create folder for implicitly stored directories,\n              // if one hasn't been created already\n              while ParentDir <> Path do begin\n                FileName := ParentDir;\n                ParentDir := ExtractFileDir(FileName);\n              end;\n              FolderName := ExtractFileName(FileName);\n              if Folders.IndexOf(FolderName) <> -1 then\n                Continue;\n              ListItem := Items.Add as TAbListItem;\n              Folders.AddObject(FolderName, ListItem);\n              ArcItem := nil;\n            end\n            else\n              // ListItem isn't below Path\n              Continue;\n            // Get file type information from the shell\n            if ListItem.IsDirectory then\n              DOSAttr := FILE_ATTRIBUTE_DIRECTORY\n            else\n              DOSAttr := FILE_ATTRIBUTE_NORMAL;\n            SHGetFileInfo(PChar(ExtractFileName(Filename)), DOSAttr, sfi, sizeof(sfi),\n              SHGFI_TYPENAME or SHGFI_SYSICONINDEX or SHGFI_USEFILEATTRIBUTES);\n            // Fill in columns\n            ListItem.Caption := ExtractFileName(Filename);\n            ListItem.ImageIndex := sfi.iIcon;\n            ListItem.SubItems.Clear;\n            for Col := Succ(Low(Col)) to High(Col) do\n              if Col in FVisibleColumns then begin\n                ColText := '';\n                ColImage := -1;\n                case Col of\n                  vcFileType:\n                    ColText := sfi.szTypeName;\n                  vcLastModified:\n                    if ArcItem <> nil then\n                      ColText := DateToStr(ArcItem.LastModTimeAsDateTime) + ' ' +\n                        TimeToStr(ArcItem.LastModTimeAsDateTime);\n                  vcSize:\n                    if not ListItem.IsDirectory then\n                      ColText := FormatFloat('#,##0', ArcItem.UncompressedSize);\n                  vcRatio:\n                    if not ListItem.IsDirectory then\n                      if ArcItem.UncompressedSize > 0 then\n                        ColText := Format('%d%%',\n                          [100 - Round(ArcItem.CompressedSize * 100 / ArcItem.UncompressedSize)])\n                      else\n                        ColText := '0%';\n                  vcPacked:\n                    if not ListItem.IsDirectory then\n                      ColText := FormatFloat('#,##0', ArcItem.CompressedSize);\n                  vcCRC:\n                    if not ListItem.IsDirectory then\n                      ColText := IntToHex(ArcItem.CRC32, 8);\n                  vcAttributes:\n                    if ArcItem <> nil then begin\n                      {$WARN SYMBOL_PLATFORM OFF}\n                      if (faReadOnly and ArcItem.ExternalFileAttributes) = faReadOnly then\n                        ColText := ColText + AbReadOnlyS;\n                      if (faHidden and ArcItem.ExternalFileAttributes) = faHidden then\n                        ColText := ColText + AbHiddenS;\n                      if (faSysFile and ArcItem.ExternalFileAttributes) = faSysFile then\n                        ColText := ColText + AbSystemS;\n                      if (faArchive and ArcItem.ExternalFileAttributes) = faArchive then\n                        ColText := ColText + AbArchivedS;\n                      {$WARN SYMBOL_PLATFORM ON}\n                    end;\n                  vcMethod:\n                    if ArcItem is TAbZipItem then\n                      ColText := ZipCompressionMethodToString(\n                        TAbZipItem(ArcItem).CompressionMethod);\n                  vcPath:\n                    ColText := ExtractFileDir(FileName);\n                end;\n                ListItem.SubItems.Add(ColText);\n                ListItem.SubItemImages[ListItem.SubItems.Count - 1] := ColImage;\n              end;\n          end;\n        finally\n          Folders.Free;\n        end;\n      CustomSort(TLVCompare(@TAbCustomListView_SortProc), LPARAM(Self));\n    end;\n  finally\n    Items.EndUpdate;\n  end;\nend;\n\n\n{ ===== TAbCustomTreeView =================================================== }\nconstructor TAbCustomTreeView.Create(aOwner: TComponent);\nvar\n  Bmp : TBitmap;\n  Icon : TIcon;\n  sfi: SHFILEINFO;\nbegin\n  inherited;\n  HideSelection := False;\n  Images := TImageList.Create(Self);\n  Bmp := TBitmap.Create;\n  try\n    Bmp.LoadFromResourceName(HInstance, 'AbComCtrls_Zip');\n    Images.AddMasked(Bmp, clFuchsia);\n    Icon := TIcon.Create;\n    try\n      // On Windows 7 an empty filename returns the drive icon instead of a folder\n      SHGetFileInfo('Folder', FILE_ATTRIBUTE_DIRECTORY, sfi, sizeof(sfi),\n        SHGFI_ICON or SHGFI_SMALLICON or SHGFI_USEFILEATTRIBUTES);\n      Icon.Handle := sfi.hIcon;\n      Bmp.PixelFormat := pf24bit;\n      Bmp.Canvas.Brush.Color := clWindow;\n      Bmp.Canvas.FillRect(Rect(0, 0, 16, 16));\n      Bmp.Canvas.Draw(0, 0, Icon);\n      Images.AddMasked(Bmp, clWindow);\n      SHGetFileInfo('Folder', FILE_ATTRIBUTE_DIRECTORY, sfi, sizeof(sfi),\n        SHGFI_ICON or SHGFI_OPENICON or SHGFI_SMALLICON or SHGFI_USEFILEATTRIBUTES);\n      Icon.Handle := sfi.hIcon;\n      Bmp.Canvas.FillRect(Rect(0, 0, 16, 16));\n      Bmp.Canvas.Draw(0, 0, Icon);\n      Images.AddMasked(Bmp, clWindow);\n    finally\n      Icon.Free;\n    end;\n  finally\n    Bmp.Free;\n  end;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbCustomTreeView.Change(aNode: TTreeNode);\nvar\n  Filename: string;\nbegin\n  inherited;\n  if aNode.Selected then begin\n    Filename := '';\n    if aNode <> Items.GetFirstNode then begin\n      Filename := aNode.Text;\n      aNode := aNode.Parent;\n      while aNode <> Items.GetFirstNode do begin\n        Filename := aNode.Text + PathDelim + Filename;\n        aNode := aNode.Parent;\n      end;\n    end;\n    Path := Filename;\n  end;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbCustomTreeView.DoChange(Sender: TObject);\nvar\n  Nodes: TStringList;\n  ZipNode: TTreeNode;\n\n  function GetNode(const aFilename: string): TTreeNode;\n  var\n    i: Integer;\n  begin\n    if aFilename = '' then\n      Result := ZipNode\n    else if Nodes.Find(aFilename, i) then\n      Result := TTreeNode(Nodes.Objects[i])\n    else begin\n      Result := Items.AddChild(GetNode(ExtractFileDir(aFilename)),\n                               ExtractFileName(aFilename));\n      {$IFDEF HasTreeViewExpandedImageIndex}\n      Result.ExpandedImageIndex := AbTreeFolderExpandedImage;\n      {$ENDIF}\n      Result.ImageIndex := AbTreeFolderImage;\n      Nodes.AddObject(aFilename, Result);\n    end;\n  end;\n\nvar\n  i: Integer;\n  Filename: string;\nbegin\n  Items.BeginUpdate;\n  try\n    Items.Clear;\n    if Assigned(FArchive) then begin\n      Nodes := TStringList.Create;\n      try\n        Nodes.Sorted := True;\n        if Archive.FArchive <> nil then\n          Filename := ExtractFileName(Archive.FArchive.ArchiveName)\n        else\n          Filename := PathDelim;\n        ZipNode := Items.AddChild(nil, Filename);\n        {$IFDEF HasTreeViewExpandedImageIndex}\n        ZipNode.ExpandedImageIndex := AbTreeArchiveImage;\n        {$ENDIF}\n        ZipNode.ImageIndex := AbTreeArchiveImage;\n        for i := 0 to FArchive.Count - 1 do\n          if FArchive[i].Action <> aaDelete then begin\n            Filename := AbNormalizeFilename(FArchive[i].FileName);\n            if not FArchive[i].IsDirectory then\n              Filename := ExtractFileDir(Filename);\n            GetNode(Filename);\n          end;\n      finally\n        Nodes.Free;\n      end;\n      Items.AlphaSort(True);\n      ZipNode.Expand(False);\n      SelectPathNode;\n    end;\n  finally\n    Items.EndUpdate;\n  end;\n  if (Sender = FArchive) and Assigned(FListView) then\n    FListView.DoChange(Self);\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbCustomTreeView.GetSelectedIndex(aNode: TTreeNode);\nbegin\n  {$IFDEF HasTreeViewExpandedImageIndex}\n  if aNode.Expanded then\n    aNode.SelectedIndex := aNode.ExpandedImageIndex\n  else\n  {$ENDIF}\n    aNode.SelectedIndex := aNode.ImageIndex;\nend;\n{ -------------------------------------------------------------------------- }\nfunction TAbCustomTreeView.GetVersion: string;\nbegin\n  Result := AbVersionS;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbCustomTreeView.Notification(aComponent: TComponent;\n  aOperation: TOperation);\nbegin\n  inherited;\n  if aOperation = opRemove then begin\n    if aComponent = FArchive then begin\n      FArchive := nil;\n      Items.Clear;\n    end;\n    if aComponent = FListView then begin\n      if Assigned(FArchive) and SameEvent(FArchive.OnChange, FListView.DoChange) then\n        FArchive.OnChange := DoChange;\n      FListView := nil;\n    end;\n  end;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbCustomTreeView.SelectPathNode;\nvar\n  Filename, Remaining: string;\n  i: Integer;\n  Node: TTreeNode;\nbegin\n  // Find selected node, expanding parents along the way\n  Node := Items.GetFirstNode;\n  Remaining := FPath;\n  if StartsText(PathDelim, Remaining) then\n    System.Delete(Remaining, 1, 1);\n  while Remaining <> '' do begin\n    Node.Expand(False);\n    i := Pos(PathDelim, Remaining);\n    if i = 0 then\n      i := Length(Remaining) + 1;\n    Filename := Copy(Remaining, 1, i - 1);\n    Remaining := Copy(Remaining, i + 1, MaxInt);\n    if Filename = '' then\n      Continue;\n    Node := Node.getFirstChild;\n    while (Node <> nil) and not SameText(Filename, Node.Text) do\n      Node := Node.getNextSibling;\n    if Node = nil then begin\n      Node := Items.GetFirstNode;\n      Break;\n    end;\n  end;\n  Selected := Node;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbCustomTreeView.SetArchive(aValue: TAbBaseBrowser);\nbegin\n  if aValue <> FArchive then begin\n    if Assigned(FArchive) then begin\n      FArchive.RemoveFreeNotification(Self);\n      if SameEvent(FArchive.OnChange, DoChange) then\n        if Assigned(ListView) and (ListView.Archive = FArchive) then\n          FArchive.OnChange := ListView.DoChange\n        else\n          FArchive.OnChange := nil;\n    end;\n    FArchive := aValue;\n    if Assigned(FArchive) then begin\n      FArchive.FreeNotification(Self);\n      FArchive.OnChange := DoChange;\n      DoChange(Self);\n    end\n    else\n      Items.Clear;\n    if Assigned(ListView) then\n      ListView.Archive := aValue;\n    SelectPathNode;\n  end;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbCustomTreeView.SetListView(aValue: TAbCustomListView);\nbegin\n  if aValue <> FListView then begin\n    if Assigned(FListView) then begin\n      FListView.RemoveFreeNotification(Self);\n      FListView.TreeView := nil;\n    end;\n    FListView := aValue;\n    if Assigned(FListView) then begin\n      FListView.FreeNotification(Self);\n      if Assigned(FArchive) then\n        FListView.Archive := FArchive\n      else if Assigned(FListView.Archive) then\n        Archive := FListView.Archive;\n      FListView.TreeView := Self;\n    end;\n  end;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbCustomTreeView.SetPath(const aValue: string);\nbegin\n  if FPath <> aValue then begin\n    FPath := ExcludeTrailingPathDelimiter(aValue);\n    SelectPathNode;\n    if Assigned(FListView) then\n      FListView.Path := aValue;\n  end;\nend;\n\n\n{ ===== TAbProgressBar ====================================================== }\nprocedure TAbProgressBar.DoProgress(Progress : Byte);\nbegin\n  Position := Progress;\n  Application.ProcessMessages;\nend;\n{ -------------------------------------------------------------------------- }\nfunction  TAbProgressBar.GetVersion : string;\nbegin\n  Result := AbVersionS;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbProgressBar.Reset;\nbegin\n  DoProgress(0);\nend;\n\nend.\n"
  },
  {
    "path": "lib/abbrevia/source/AbCompnd.pas",
    "content": "(* ***** BEGIN LICENSE BLOCK *****\n * Version: MPL 1.1\n *\n * The contents of this file are subject to the Mozilla Public License Version\n * 1.1 (the \"License\"); you may not use this file except in compliance with\n * the License. You may obtain a copy of the License at\n * http://www.mozilla.org/MPL/\n *\n * Software distributed under the License is distributed on an \"AS IS\" basis,\n * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License\n * for the specific language governing rights and limitations under the\n * License.\n *\n * The Original Code is TurboPower Abbrevia\n *\n * The Initial Developer of the Original Code is\n * TurboPower Software\n *\n * Portions created by the Initial Developer are Copyright (C) 1997-2002\n * the Initial Developer. All Rights Reserved.\n *\n * Contributor(s):\n *\n * ***** END LICENSE BLOCK ***** *)\n\n{*********************************************************}\n{* ABBREVIA: AbCompnd.pas                                *}\n{*********************************************************}\n{* ABBREVIA: Compound File classes and component         *}\n{*   Use AbQCmpnd.pas for CLX                            *}\n{*********************************************************}\n\n{$IFNDEF UsingCLX}\nunit AbCompnd;\n{$ENDIF}\n\n{$I AbDefine.inc}\n\ninterface\n\nuses\n  Classes, SysUtils,\n{$IFDEF UsingClx}\n  QComCtrls,\n{$ELSE}\n  ComCtrls,\n{$ENDIF}\n  AbBase, AbResString, AbDfDec, AbDfEnc, AbDfBase;\n\nconst\n  AbCompoundFileVersion = '3.1';\n\nconst\n  {SystemBlock constants}\n  sbSignatureSize       = 40;   {byte size of Signature field}\n  sbVolumeLabelSize     = 40;   {byte size of Volume Label field}\n  sbAllocationSizeSize  = 4;    {byte size of Allocation Size field}\n  sbVersionSize         = 4;    {byte size of Version field}\n  sbUpdateSize          = 1;    {byte size of Updating Flag field}\n\n  {Total size of System Block}\n  SizeOfSystemBlock = sbSignatureSize + sbVolumeLabelSize +\n                      sbAllocationSizeSize + sbVersionSize + sbUpdateSize;\n\n  {RootDir constants}\n  rdEntryNameSize       = 28;  {byte size of Name field}\n  rdEntryIDSize         = 4;   {byte size of EntryID field}\n  rdParentFolderSize    = 4;   {byte size of ParentFolder field}\n  rdEntryTypeSize       = 4;   {byte size of EntryType field}\n  rdAttributesSize      = 4;   {byte size of Attributes field}\n  rdStartBlockSize      = 4;   {byte size of StartBlock field}\n  rdLastModifiedSize    = 8;   {byte size of LastModified field}\n  rdSizeSize            = 4;   {byte size of UncompressedSize field}\n  rdCompressedSizeSize  = 4;   {byte size of CompressedSize field}\n\n  {Total size of a single Root Directory Entry}\n  rdSizeOfDirEntry = rdEntryNameSize + rdEntryIDSize + rdParentFolderSize +\n                     rdEntryTypeSize + rdAttributesSize + rdStartBlockSize +\n                     rdLastModifiedSize + rdSizeSize + rdCompressedSizeSize;\n\n  rdUnUsed              = -2;  {Constant used to flag an RD entry as unused}\n\n  {Total size of a Root Directory entry}\n  SizeOfRootDirBlock = rdEntryNameSize + rdEntryIDSize + rdParentFolderSize +\n                       rdEntryTypeSize + rdAttributesSize + rdStartBlockSize +\n                       rdLastModifiedSize + rdSizeSize + rdCompressedSizeSize;\n\n  {FAT table constants}\n  ftEndOfBlock          = -1;   {End of Block}\n  ftUnusedBlock         = -2;   {Unused Block}\n\n  {General constants}\n  cfAllocationSize      = 512;  {Default AllocationSize (bytes)}\n\ntype\n  ECompoundFileError = class(Exception);\n  TrdEntryType = (etFolder, etFile);\n\n  {dynamic array parameter for returning FAT chain sequences}\n  type TFATChainArray = array of Integer;\n\n  {forwards}\n{$M+}\n  TAbCompoundFile = class;\n{$M-}\n  TBeforeDirDeleteEvent = procedure(Sender : TAbCompoundFile; Dir : AnsiString;\n                                    var AllowDelete : Boolean) of object;\n  TBeforeDirModifiedEvent = procedure(Sender : TAbCompoundFile; Dir : AnsiString;\n                                      var AllowModify : Boolean) of object;\n  TBeforeFileDeleteEvent = procedure(Sender : TAbCompoundFile;FileName : AnsiString;\n                                     var AllowDelete : Boolean) of object;\n  TBeforeFileModifiedEvent = procedure(Sender : TAbCompoundFile;\n                                       FileName : AnsiString; var AllowModify :\n                                       Boolean) of object;\n\n  TMultiNode = class(TObject)\n  protected  {private}\n    FParent     : Pointer;       {pointer to the parent node}\n    FKey        : AnsiString;    {node identifier}\n    FChildren   : TStringList;   {list for child keys & nodes}\n    FData       : TObject;       {contained object}\n\n    function GetChildCount : Integer;\n  public\n    constructor Create(const Key : AnsiString);\n    destructor Destroy; override;\n    function AddChild(const Key : AnsiString) : TMultiNode;\n    procedure DeleteChild(Index : Integer);\n    function DeleteChildByName(const ChildKey : AnsiString) : Boolean;\n    function DeleteChildren : Boolean;\n    function GetChild(Index : integer) : TMultiNode;\n    function GetChildByName(const Key : AnsiString) : TMultiNode;\n    function HasParent : Boolean;\n    function HasChildren : Boolean;\n    function Contains(const Key : AnsiString) : Boolean;\n    property Parent : Pointer read FParent write FParent;\n    property ChildCount : Integer read GetChildCount;\n    property Children[Index : Integer] : TMultiNode read GetChild;\n    property Data : TObject read FData write FData;\n    property Key : AnsiString read FKey write FKey;\n  end;\n\n\n  TMultiTree = class(TObject)\n  protected  {private}\n    FRoot        : TMultiNode;     {reference to root node}\n    FCount       : Integer;        {count of nodes in the tree}\n    FCurrentNode : TMultiNode;     {analogous to current directory}\n    FSepChar     : AnsiChar;       {directory separator character}\n    FIDCount     : Integer;        {counter incremented during preorder trav.}\n                                   {(used to assign unique ID to each node)}\n\n    procedure VisitSubNodesPost(Node : TMultiNode; ID : Integer);\n    procedure VisitSubNodesPre(Node : TMultiNode; Strm : TStream);\n    procedure VisitNode(Node : TMultiNode; Strm : TStream);\n    procedure ParseDirStr(const Key : AnsiString; Lst : TStringList);\n    procedure PopulateSubNodes(ParentNode : TMultiNode;\n                               TreeView : TTreeView; TreeNode : TTreeNode);\n    procedure TraversePost(ID : Integer);\n    procedure TraversePre(Strm : TStream);\n\n  public\n    constructor Create;\n    destructor Destroy; override;\n    function Insert(ParentNode : TMultiNode; const Key : AnsiString) : TMultiNode;\n    function GetNode(const Key : AnsiString) : TMultiNode;\n    function DeleteNode(const Key : AnsiString) : Boolean;\n    procedure ChangeDir(const Key : AnsiString);\n    function PopulateTreeView(TreeView : TTreeView) : Integer;\n    property Root : TMultiNode read FRoot;\n    property Count : Integer read FCount;\n    property CurrentNode : TMultiNode read FCurrentNode;\n    property SepChar : AnsiChar read FSepChar write FSepChar;\n  end;\n\n\n  TAbSystemBlock = class(TObject)\n  protected {private}\n    FSignature      : AnsiString;  {identifies the compound file structure}\n    FVolumeLabel    : AnsiString;  {file identification in addition to filename}\n    FAllocationSize : Integer;     {size of allocation block}\n    FVersion        : AnsiString;  {version string identifier}\n    FUpdating       : Boolean;     {internal processing indicator}\n\n  {protected methods}\n    procedure BeginUpdate;\n    procedure EndUpdate;\n    procedure WriteToStream(Strm : TMemoryStream);\n\n  {properties}\n    property Signature : AnsiString read FSignature write FSignature;\n    property VolumeLabel : AnsiString read FVolumeLabel write FVolumeLabel;\n    property Updating : Boolean read FUpdating;\n    property AllocationSize : Integer\n      read FAllocationSize write FAllocationSize;\n    property Version : AnsiString read FVersion;\n  public\n    constructor Create(const VolLabel : AnsiString; AllocationSz : Integer);\n  end;\n\n  TAbDirectoryEntry = class(TObject)\n  protected {private}\n    FName           : AnsiString;       {name of file or folder}\n    FEntryID        : Integer;          {unique ID for this dir. entry}\n    FParentFolder   : LongInt;          {unique ID of parent folder}\n    FEntryType      : TrdEntryType;     {folder or file}\n    FAttributes     : LongInt;          {file system attributes}\n    FStartBlock     : LongInt;          {starting allocation block}\n    FLastModified   : TDateTime;        {last modification date/time}\n    FSize           : LongInt;          {uncompressed file size}\n    FCompressedSize : LongInt;          {compressed file size}\n\n    procedure WriteToStream(Strm : TMemoryStream);\n    function IsReadOnly : Boolean;\n    function IsHidden : Boolean;\n    function IsSysFile : Boolean;\n    function IsVolumeID : Boolean;\n    function IsDirectory : Boolean;\n    function IsArchive : Boolean;\n    function GetIsFree : Boolean;\n\n  public\n    constructor Create(AsFile : Boolean);\n\n    property EntryName : AnsiString read FName write FName;\n    property ParentFolder : LongInt read FParentFolder write FParentFolder;\n    property Attributes : LongInt read FAttributes write FAttributes;\n    property StartBlock : LongInt read FStartBlock write FStartBlock;\n    property LastModified : TDateTime read FLastModified write FLastModified;\n    property Size : LongInt read FSize write FSize;\n    property CompressedSize : LongInt\n      read FCompressedSize write FCompressedSize;\n    property IsFree : Boolean read GetIsFree;\n    property EntryType : TrdEntryType read FEntryType write FEntryType;\n  end;\n\n\n  TAbRootDir = class(TMultiTree)\n    fAllocSize : Integer;\n  protected {private}\n    function AddFolder(FolderName : AnsiString) : TAbDirectoryEntry;\n    function AddFile(FileName : AnsiString) : TAbDirectoryEntry;\n    procedure DeleteFolder(FolderName : AnsiString);\n    procedure DeleteFile(FileName : AnsiString);\n    procedure WriteToStream(Strm : TMemoryStream);\n    procedure GoToEntryID(ID : Integer);\n  public\n    constructor Create(VolLabel : AnsiString; AllocSize : Integer);\n    destructor Destroy; override;\n  end;\n\n\n  TAbFATTable = class(TObject)\n  protected {private}\n    fFATArray  : Array of Integer;       {dynamic array for the FAT}\n    fAllocSize : Integer;\n\n    procedure WriteToStream(Strm : TMemoryStream);\n\n  public\n    constructor Create(AllocSize : Integer);\n    destructor Destroy; override;\n    function IsEndOfFile(Ndx : Integer) : Boolean;\n    function IsUnUsed(Ndx : Integer) : Boolean;\n    function GetNextUnusedBlock : Integer;\n    procedure GetNewChain(NumBytes : Integer;\n                          var ChainArray : TFATChainArray);\n    procedure GetExistingChain(StartNdx : Integer;\n                               var ChainArray : TFATChainArray);\n    procedure ClearExistingChain(StartNdx : Integer);\n    procedure GetRootDirChain(var ChainArray : TFATChainArray);\n    procedure GetFATChain(var ChainArray : TFATChainArray);\n    procedure GetNewRootDirChain(NumBytes : Integer;\n                                 var ChainArray : TFATChainArray);\n    procedure GetNewFATChain(NumBytes : Integer;\n                             var ChainArray : TFATChainArray);\n    procedure ClearRootDirChain;\n    procedure ClearFATChain;\n  end;\n\n\n  TAbCompoundFile = class(TObject)\n  protected {private}\n    FSystemBlock : TAbSystemBlock;      {system block}\n    FFATTable    : TAbFATTable;         {FAT table}\n    FRootDir     : TAbRootDir;          {root directory}\n    FDiskFile    : string;              {compound file name}\n    FSizeOnDisk  : Integer;             {sum total of compressed sizes +\n                                         uncompressed Sys, RootDir, & FAT blks}\n    FStream      : TFileStream;         {Compound file stream (*.cf)}\n\n    FOnAfterOpen          : TNotifyEvent;\n    FOnBeforeClose        : TNotifyEvent;\n    FOnBeforeDirDelete    : TBeforeDirDeleteEvent;\n    FOnBeforeDirModified  : TBeforeDirModifiedEvent;\n    FOnBeforeFileDelete   : TBeforeFileDeleteEvent;\n    FOnBeforeFileModified : TBeforeFileModifiedEvent;\n\n    function GetVolumeLabel : AnsiString;\n    procedure SetVolumeLabel(Val : AnsiString);\n    function GetDirectoryEntries : Integer;\n    function GetSizeOnDisk : Integer;\n    procedure PersistFileData(FileData : TStream;\n                              var ChainArray : TFATChainArray);\n    procedure PersistSystemBlock;\n    procedure PersistRootDirBlock;\n    procedure PersistFATBlock;\n    procedure BuildSysBlock;\n    procedure BuildFat;\n    procedure BuildRootDir;\n    procedure AddDirEntriesFromList(Lst : TStringList);\n\n    procedure Defrag;                   {not implemented}\n  public\n    constructor Create(const FileName : string; const VolLabel : AnsiString;\n                       AllocSize : Integer); overload;\n    constructor Create(const FileName : string; const VolLabel : AnsiString;\n                       AllocSize : Integer; const Signature: AnsiString); overload;\n    destructor Destroy; override;\n    procedure EnumerateFiles(Lst : TStringList);\n    procedure EnumerateFolders(Lst : TStringList);\n    procedure AddFile(FName : AnsiString; FileData : TStream; FileSize : Integer);\n    function AddFolder(FName : AnsiString) : Boolean;\n    procedure UpdateFile(FName : AnsiString; FData : TStream);\n    procedure DeleteFile(FName : AnsiString);\n    procedure DeleteFolder(FName : AnsiString);\n    procedure Open(const FName : string); overload;\n    procedure Open(const FName : string; const Signature: AnsiString); overload;\n    function OpenFile(FileName : AnsiString; var Strm : TStream) : Integer;\n    function PopulateTreeView(TreeView : TTreeView) : Integer;\n    procedure PopulateSubNodes(ParentNode : TMultiNode;\n                     TreeView : TTreeView; TreeNode : TTreeNode);\n    procedure RenameFile(OrigName, NewName : AnsiString);\n    procedure RenameFolder(OrigName, NewName : AnsiString);\n    procedure SetCurrentDirectory(val : AnsiString);\n    function GetCurrentDirectory : AnsiString;\n    function GetAllocationSize : Integer;\n    property CurrentDirectory : AnsiString\n      read GetCurrentDirectory write SetCurrentDirectory;\n    property DirectoryEntries : Integer read GetDirectoryEntries;\n    property SizeOnDisk : Integer read GetSizeOnDisk;\n    property Stream : TFileStream read FStream write FStream;\n\n\n  published\n    property VolumeLabel : AnsiString read GetVolumeLabel write SetVolumeLabel;\n    property FileName : string read FDiskFile;\n    property AllocationSize : Integer read GetAllocationSize;\n\n    property OnAfterOpen : TNotifyEvent\n      read FOnAfterOpen write FOnAfterOpen;\n    property OnBeforeClose : TNotifyEvent\n      read FOnBeforeClose write FOnBeforeClose;\n    property OnBeforeDirDelete : TBeforeDirDeleteEvent\n      read FOnBeforeDirDelete write FOnBeforeDirDelete;\n    property OnBeforeDirModified : TBeforeDirModifiedEvent\n      read FOnBeforeDirModified write FOnBeforeDirModified;\n    property OnBeforeFileDelete : TBeforeFileDeleteEvent\n      read FOnBeforeFileDelete write FOnBeforeFileDelete;\n    property OnBeforeFileModified : TBeforeFileModifiedEvent\n      read FOnBeforeFileModified write FOnBeforeFileModified;\n  end;\n\nimplementation\n\nuses\n  StrUtils,\n  {$IFDEF HasAnsiStrings}AnsiStrings,{$ENDIF}\n  ABUtils;\n\n{-----------------------------------------------------------------------------}\n{-----------------------------------------------------------------------------}\n             {TMultiNode}\n{-----------------------------------------------------------------------------}\n{-----------------------------------------------------------------------------}\nconstructor TMultiNode.Create(const Key : AnsiString);\n  {- Creates and initializes a new node}\nbegin\n  inherited Create;\n  FKey := Key;\n  FChildren := TStringList.Create;\n  FChildren.Sorted := True;\n  FChildren.Duplicates := dupError;\nend;\n{-----------------------------------------------------------------------------}\ndestructor TMultiNode.Destroy;\n  {- Destroys the node and all of the children}\nvar\n  i : integer;\nbegin\n  {free children}\n  for i := FChildren.Count - 1 downto 0 do\n    FChildren.Objects[i].Free;\n  FChildren.Free;\n  if Assigned(FData) then\n    TAbDirectoryEntry(FData).Free;\n  inherited Destroy;\nend;\n{-----------------------------------------------------------------------------}\nfunction TMultiNode.AddChild(const Key : AnsiString) : TMultiNode;\n  {- Creates and adds a new node - returns the newly added node}\nbegin\n  if Contains(Key) then\n    Result := nil\n  else begin\n    Result := TMultiNode.Create(Key);\n    Result.Parent := self;\n    FChildren.AddObject(string(Key), Result);\n  end;\nend;\n{-----------------------------------------------------------------------------}\nfunction TMultiNode.Contains(const Key : AnsiString) : Boolean;\n  {- Returns true if the node contains a child of the name specified by 'Key'}\nbegin\n  Result := (FChildren.IndexOf(string(Key)) >= 0);\nend;\n{-----------------------------------------------------------------------------}\nprocedure TMultiNode.DeleteChild(Index : Integer);\n  {- Deletes the child node specified by 'Index'}\nbegin\n  if ((Index < 0) or (Index > FChildren.Count - 1)) then\n    raise ECompoundFileError.Create(AbCmpndIndexOutOfBounds);\n  FChildren.Objects[Index].Free;\n  FChildren.Delete(Index);\nend;\n{-----------------------------------------------------------------------------}\nfunction TMultiNode.DeleteChildByName(const ChildKey : AnsiString) : Boolean;\n  {- If node found, node is deleted and true is returned, else returns false}\nbegin\n  Result := Contains(ChildKey);\n  if Result then begin\n    FChildren.Objects[FChildren.IndexOf(string(ChildKey))].Free;\n    FChildren.Delete(FChildren.IndexOf(string(ChildKey)));\n  end;\nend;\n{-----------------------------------------------------------------------------}\nfunction TMultiNode.DeleteChildren : Boolean;\n  {- Deletes all child nodes}\nvar\n  i : Integer;\nbegin\n  Result := FChildren.Count > 0;\n  for i := FChildren.Count - 1 downto 0 do begin\n    FChildren.Objects[i].Free;\n    FChildren.Delete(i);\n  end;\nend;\n{-----------------------------------------------------------------------------}\nfunction TMultiNode.GetChild(Index : integer) : TMultiNode;\n  {- Returns the node specified by Index}\nbegin\n  if ((Index < 0) or (Index > FChildren.Count - 1)) then\n    raise ECompoundFileError.Create(AbCmpndIndexOutOfBounds);\n  Result := (FChildren.Objects[Index] as TMultiNode);\nend;\n{-----------------------------------------------------------------------------}\nfunction TMultiNode.GetChildByName(const Key : AnsiString) : TMultiNode;\n  {- Returns the child node specified by 'Key'.  If not found, result = nil}\nbegin\n  Result := nil;\n  if Contains(Key) then\n    Result := (FChildren.Objects[FChildren.IndexOf(string(Key))] as TMultiNode);\nend;\n{-----------------------------------------------------------------------------}\nfunction TMultiNode.GetChildCount : Integer;\n  {- Returns the node's children count}\nbegin\n  Result := FChildren.Count;\nend;\n{-----------------------------------------------------------------------------}\nfunction TMultiNode.HasParent : Boolean;\n  {- Returns true if parent is assigned, else returns false}\nbegin\n  Result := (FParent <> nil);\nend;\n{-----------------------------------------------------------------------------}\nfunction TMultiNode.HasChildren : Boolean;\n  {- Returns true if the node contains 1 or more child nodes.}\nbegin\n  Result := (FChildren.Count > 0);\nend;\n{-----------------------------------------------------------------------------}\n{-----------------------------------------------------------------------------}\n          {TMultiTree}\n{-----------------------------------------------------------------------------}\n{-----------------------------------------------------------------------------}\nconstructor TMultiTree.Create;\n  {- creates an empty tree}\nbegin\n  inherited Create;\n  FSepChar := '\\';\nend;\n{-----------------------------------------------------------------------------}\ndestructor TMultiTree.Destroy;\n  {- destroys all nodes (post-order)}\nvar\n  Curr : TMultiNode;\nbegin\n  Curr := Root;\n  while Curr <> nil do begin\n    if Curr.HasChildren then\n      Curr := Curr.Children[0]\n    else\n      begin\n        if Curr = Root then begin\n          Curr.Free;\n          exit;\n        end else begin\n          Curr := Curr.Parent;\n          Curr.DeleteChild(0);\n        end;\n      end;\n  end;\nend;\n{-----------------------------------------------------------------------------}\nprocedure TMultiTree.ChangeDir(const Key : AnsiString);\n  {- Sets current directory of tree if path('Key') is valid}\nvar\n  Node     : TMultiNode;\n  Lst      : TStringList;\n  i, Ndx   : integer;\n  NotFound : Boolean;\nbegin\n  if Root = nil then exit;\n  NotFound := False;\n  Lst := TStringList.Create;\n  try\n    ParseDirStr(Key, Lst);\n    Node := CurrentNode;\n    for i := 0 to Lst.Count - 1 do begin\n\n      if Lst.Strings[i] = '\\' then begin\n        Node := Root;\n        Continue;\n      end\n\n      else if Lst.Strings[i] = '.' then\n        Continue\n\n      else if Lst.Strings[i] = '..' then begin\n        if Node <> Root then\n          Node := TMultiNode(Node.Parent);\n      end else begin\n        Ndx := Node.FChildren.IndexOf(Lst.Strings[i]);\n        if Ndx >= 0 then\n          Node := Node.GetChild(Ndx)\n        else begin\n          NotFound := True;\n          Break;\n        end;\n      end;\n    end;\n  finally\n    Lst.Free;\n  end;\n  if NotFound = false then\n    FCurrentNode := Node;\nend;\n{-----------------------------------------------------------------------------}\nfunction TMultiTree.DeleteNode(const Key : AnsiString) : Boolean;\n  {- If node found, deletes the node & returns true, else returns false}\nbegin\n  Result := False;\n  if CurrentNode <> nil then\n    if CurrentNode.Contains(Key) then begin\n      Result := CurrentNode.DeleteChildByName(Key);\n      Dec(FCount);\n    end;\nend;\n{-----------------------------------------------------------------------------}\nfunction TMultiTree.GetNode(const Key : AnsiString) : TMultiNode;\n  {- Returns the node if found, else returns nil}\nbegin\n  Result := nil;\n  if CurrentNode <> nil then\n    if CurrentNode.Contains(Key) then\n      Result := CurrentNode.GetChildByName(Key);\nend;\n{-----------------------------------------------------------------------------}\nfunction TMultiTree.Insert(ParentNode : TMultiNode;\n                        const Key : AnsiString) : TMultiNode;\n  {- Adds child node to specified ParentNode}\nvar\n  NewNode : TMultiNode;\nbegin\n  Result := nil;\n  if CurrentNode = nil then begin\n    {adding root node}\n    NewNode := TMultiNode.Create(Key);\n    FRoot := NewNode;\n    FCurrentNode := NewNode;\n    Result := NewNode;\n  end else begin\n    if not CurrentNode.Contains(Key) then begin\n      Result := CurrentNode.AddChild(Key);\n      Result.Parent := CurrentNode;\n    end;\n  end;\n  Inc(FCount);\nend;\n{-----------------------------------------------------------------------------}\nprocedure TMultiTree.ParseDirStr(const Key : AnsiString; Lst : TStringList);\n  {- parses Key into individual dir commands adding each to Lst}\nvar\n  LocKey : AnsiString;\n  Counter : integer;\nbegin\n  LocKey := Key;\n  Lst.Clear;\n  if LocKey = '' then\n    LocKey := '\\';\n\n  {- are we to start from the root folder}\n  Counter := 0;\n  while LocKey[Counter+1] = '\\' do\n    inc(Counter);\n\n  if Counter = 1 then\n    Lst.Add('\\');\n\n  {- begin parsing}\n  while Length(LocKey) > 0 do begin\n    while LocKey[1] = '\\' do\n    begin\n      Delete(LocKey, 1, 1);\n      if Length(LocKey) = 0 then\n        exit;\n    end;\n\n    if pos(SepChar,LocKey) > 0 then begin\n      Lst.Add(string(copy(LocKey, 1, Pos(SepChar, LocKey) - 1)));\n      Delete(LocKey, 1, Pos(SepChar, LocKey));\n    end else\n      if Length(LocKey) > 0 then begin\n        Lst.Add(string(LocKey));\n        LocKey := '';\n      end;\n  end;\nend;\n{-----------------------------------------------------------------------------}\nprocedure TMultiTree.PopulateSubNodes(ParentNode : TMultiNode;\n                     TreeView : TTreeView; TreeNode : TTreeNode);\n  {- Visits sub-nodes recursively - pre order}\nvar\n  Curr : TMultiNode;\n  i    : Integer;\n  Node : TTreeNode;\nbegin\n  Node := TreeView.Items.AddChild(TreeNode, string(ParentNode.Key));\n  Curr := ParentNode;\n  if Curr <> nil then begin\n    if Curr.HasChildren then begin\n      for i := 0 to Curr.ChildCount -1 do\n        PopulateSubNodes(Curr.Children[i], TreeView, Node);\n    end;\n  end;\nend;\n{-----------------------------------------------------------------------------}\nfunction TMultiTree.PopulateTreeView(TreeView : TTreeView) : Integer;\n{- Populates a user-supplied TTreeView with multiway tree nodes}\nvar\n  i        : Integer;\n  TreeNode : TTreeNode;\nbegin\n  TreeView.Items.Clear;\n  if Root <> nil then begin\n    TreeNode := TreeView.Items.Add(nil, string(Root.Key));\n    if Root.HasChildren then begin\n      for i := 0 to Root.ChildCount - 1 do\n        PopulateSubNodes(Root.Children[i], TreeView, TreeNode);\n    end;\n  end;\n  Result := TreeView.Items.Count\nend;\n{-----------------------------------------------------------------------------}\nprocedure TMultiTree.TraversePost(ID : Integer);\n  {- Traverses tree post-order - CurrentNode after traversal will be the node\n     whose EntryID = ID}\nvar\n  i : Integer;\nbegin\n  if Root <> nil then begin\n    if Root.HasChildren then begin\n      for i := 0 to Root.ChildCount - 1 do\n        VisitSubNodesPost(Root.Children[i], ID);\n    end;\n    if (TAbDirectoryEntry(Root.FData).FEntryID = ID) then\n      FCurrentNode := Root;\n  end;\nend;\n{-----------------------------------------------------------------------------}\nprocedure TMultiTree.TraversePre(Strm : TStream);\n  {- Traverses tree pre-order}\nvar\n  i : Integer;\nbegin\n  if Root <> nil then begin\n    FIDCount := 1;\n    TAbDirectoryEntry(Root.Data).FEntryID := FIDCount;\n\n    VisitNode(Root, Strm);\n    if Root.HasChildren then begin\n      for i := 0 to Root.ChildCount - 1 do\n        VisitSubNodesPre(Root.Children[i], Strm);\n    end;\n  end;\nend;\n{-----------------------------------------------------------------------------}\nprocedure TMultiTree.VisitNode(Node : TMultiNode; Strm : TStream);\n  {- Called recursively from VisitSubNodesPre. Assigns unique entry ID's for\n     each directory entry to maintain hierarchy}\nbegin\n  if Node.Parent = nil then\n    TAbDirectoryEntry(Node.Data).ParentFolder := -1\n  else\n    TAbDirectoryEntry(Node.Data).ParentFolder :=\n      TAbDirectoryEntry(TMultiNode(Node.Parent).Data).FEntryID;\n\n  TAbDirectoryEntry(Node.Data).WriteToStream(TMemoryStream(Strm));\nend;\n{-----------------------------------------------------------------------------}\nprocedure TMultiTree.VisitSubNodesPost(Node : TMultiNode; ID : Integer);\n  {- Visits sub-nodes recursively - post order}\nvar\n  Curr : TMultiNode;\n  i    : Integer;\nbegin\n  Curr := Node;\n  if Curr <> nil then begin\n    if Curr.HasChildren then begin\n      for i := 0 to Curr.ChildCount -1 do\n        VisitSubNodesPost(Curr.Children[i], ID);\n    end;\n    if (TAbDirectoryEntry(Curr.FData).FEntryID = ID) then\n      FCurrentNode := Curr;\n  end;\nend;\n{-----------------------------------------------------------------------------}\nprocedure TMultiTree.VisitSubNodesPre(Node : TMultiNode; Strm : TStream);\n  {- Visits sub-nodes recursively - pre order}\nvar\n  Curr : TMultiNode;\n  i    : Integer;\nbegin\n  Curr := Node;\n  if Curr <> nil then begin\n    Inc(FIDCount);\n    TAbDirectoryEntry(Curr.Data).FEntryID := FIDCount;\n\n    VisitNode(Curr, Strm);\n    if Curr.HasChildren then begin\n      for i := 0 to Curr.ChildCount -1 do\n        VisitSubNodesPre(Curr.Children[i], Strm);\n    end;\n  end;\nend;\n{-----------------------------------------------------------------------------}\n{-----------------------------------------------------------------------------}\n              {TAbSystemBlock}\n{-----------------------------------------------------------------------------}\n{-----------------------------------------------------------------------------}\nconstructor TAbSystemBlock.Create(const VolLabel : AnsiString; AllocationSz : Integer);\n{- Creates the System block structure of the compound file}\nbegin\n  inherited Create;\n  FSignature      := 'AbCompoundFile';\n  FVolumeLabel    := VolLabel;\n  FAllocationSize := AllocationSz;\n  FVersion        := AbCompoundFileVersion;\n  FUpdating       := False;\nend;\n{-----------------------------------------------------------------------------}\nprocedure TAbSystemBlock.BeginUpdate;\n  {- Sets updating to true - temporarily blocking other actions}\nbegin\n  FUpdating := True;\nend;\n{-----------------------------------------------------------------------------}\nprocedure TAbSystemBlock.EndUpdate;\n  {- Clears updating flag & allows for other actions}\nbegin\n  FUpdating := False;\nend;\n{-----------------------------------------------------------------------------}\nprocedure TAbSystemBlock.WriteToStream(Strm : TMemoryStream);\n  {- writes the contents to the stream parameter}\nvar\n  Sig       : Array[0..sbSignatureSize - 1] of AnsiChar;\n  VolLabel  : Array[0..sbVolumeLabelSize - 1] of AnsiChar;\n  AllocSize : Integer;\n  Version   : Array[0..sbVersionSize - 1] of AnsiChar;\n  Updt      : Byte;\nbegin\n  FillChar(Sig, sbSignatureSize, #0);\n  AbStrPCopy(Sig, FSignature);\n\n  FillChar(VolLabel[0], sbVolumeLabelSize, #0);\n  AbStrPCopy(VolLabel, FVolumeLabel);\n\n  AllocSize := FAllocationSize;\n\n  FillChar(Version[0], sbVersionSize, #0);\n  AbStrPCopy(Version, FVersion);\n\n  if FUpdating then\n    Updt := $01\n  else\n    Updt := $00;\n\n  Strm.Write(Sig[0], sbSignatureSize);\n  Strm.Write(VolLabel[0], sbVolumeLabelSize);\n  Strm.Write(AllocSize, SizeOf(Integer));\n  Strm.Write(Version[0], sbVersionSize);\n  Strm.Write(Updt, sbUpdateSize);\nend;\n{-----------------------------------------------------------------------------}\n{-----------------------------------------------------------------------------}\n           {TAbDirectoryEntry}\n{-----------------------------------------------------------------------------}\n{-----------------------------------------------------------------------------}\nconstructor TAbDirectoryEntry.Create(AsFile : Boolean);\n  {- Creates & initializes a new TAbDirectoryEntry}\nbegin\n  inherited Create;\n  FName           := '';\n  FParentFolder   := rdUnused;\n  if AsFile then begin\n    FEntryType     := etFile;\n    {$WARN SYMBOL_PLATFORM OFF}\n    FAttributes     := faArchive;\n    {$WARN SYMBOL_PLATFORM ON}\n  end else begin\n    FEntryType     := etFolder;\n    FAttributes     := faDirectory;\n  end;\n  FStartBlock     := rdUnused;\n  FLastModified   := 0;\n  FSize           := rdUnused;\n  FCompressedSize := rdUnused;\nend;\n{-----------------------------------------------------------------------------}\nfunction TAbDirectoryEntry.GetIsFree : Boolean;\n  {- returns true if the entry has been marked for deletion}\nbegin\n  Result := (FName = '');\nend;\n{-----------------------------------------------------------------------------}\nfunction TAbDirectoryEntry.IsArchive : Boolean;\n  {- returns true if the entry is an archive}\nbegin\n{$WARN SYMBOL_PLATFORM OFF}\n  Result := ((FAttributes and faArchive) > 0);\n{$WARN SYMBOL_PLATFORM ON}\nend;\n{-----------------------------------------------------------------------------}\nfunction TAbDirectoryEntry.IsDirectory : Boolean;\n  {- returns true if the entry is a directory}\nbegin\n  Result := ((FAttributes and faDirectory) > 0);\nend;\n{-----------------------------------------------------------------------------}\nfunction TAbDirectoryEntry.IsHidden : Boolean;\n  {- returns true if the entry is hidden}\nbegin\n{$WARN SYMBOL_PLATFORM OFF}\n  Result := ((FAttributes and faHidden) > 0);\n{$WARN SYMBOL_PLATFORM ON}\nend;\n{-----------------------------------------------------------------------------}\nfunction TAbDirectoryEntry.IsReadOnly : Boolean;\n  {- returns true if the entry is read-only}\nbegin\n{$WARN SYMBOL_PLATFORM OFF}\n  Result := ((FAttributes and faReadOnly) > 0);\n{$WARN SYMBOL_PLATFORM ON}\nend;\n{-----------------------------------------------------------------------------}\nfunction TAbDirectoryEntry.IsSysFile : Boolean;\n  {- returns true if the entry is a system file}\nbegin\n{$WARN SYMBOL_PLATFORM OFF}\n  Result := ((FAttributes and faSysFile) > 0);\n{$WARN SYMBOL_PLATFORM ON}\nend;\n{-----------------------------------------------------------------------------}\nfunction TAbDirectoryEntry.IsVolumeID : Boolean;\n  {- returns true if the entry is a volume ID}\nbegin\n{$WARN SYMBOL_DEPRECATED OFF}\n{$WARN SYMBOL_PLATFORM OFF}\n  Result := ((FAttributes and faVolumeID) > 0);\n{$WARN SYMBOL_PLATFORM ON}\n{$WARN SYMBOL_DEPRECATED ON}\nend;\n{-----------------------------------------------------------------------------}\nprocedure TAbDirectoryEntry.WriteToStream(Strm : TMemoryStream);\n  {- writes properties to stream}\nvar\n  EntryName : Array[0..rdEntryNameSize] of AnsiChar;\n  FType     : Integer;\nbegin\n  FillChar(EntryName, rdEntryNameSize - 1, #0);\n  AbStrPCopy(EntryName, FName);\n\n  Strm.Write(EntryName[0], rdEntryNameSize);\n\n  Strm.Write(FEntryID, rdEntryIDSize);\n  Strm.Write(FParentFolder, rdParentFolderSize);\n\n  if EntryType = etFolder then\n    FType := $00000000\n  else\n    FType := $00000001;\n  Strm.Write(FType, rdEntryTypeSize);\n  Strm.Write(FAttributes, rdAttributesSize);\n  Strm.Write(FStartBlock, rdStartBlockSize);\n  Strm.Write(FLastModified, rdLastModifiedSize);\n  Strm.Write(FSize, rdSizeSize);\n  Strm.Write(FCompressedSize, rdCompressedSizeSize);\nend;\n{-----------------------------------------------------------------------------}\n{-----------------------------------------------------------------------------}\n            {TAbRootDir}\n{-----------------------------------------------------------------------------}\n{-----------------------------------------------------------------------------}\nconstructor TAbRootDir.Create(VolLabel : AnsiString; AllocSize : Integer);\n  {- Creates a single-entry (vol-label) root directory structure}\nbegin\n  inherited Create;\n  fAllocSize := AllocSize;\n  if VolLabel <> '' then\n    AddFolder(VolLabel);\nend;\n{-----------------------------------------------------------------------------}\ndestructor TAbRootDir.Destroy;\n  {- Destroys the root dir.}\nbegin\n  inherited Destroy;\nend;\n{-----------------------------------------------------------------------------}\nfunction TAbRootDir.AddFile(FileName : AnsiString) : TAbDirectoryEntry;\n  {- Adds a file to the current directory of the compound file}\nvar\n  NewNode : TMultiNode;\n  NewData : TAbDirectoryEntry;\nbegin\n  NewData := nil;\n  NewNode := Insert(CurrentNode, FileName);\n  if NewNode <> nil then begin\n    NewData := TAbDirectoryEntry.Create(True);\n    NewData.FName := FileName;\n    NewData.ParentFolder := 1;\n{$WARN SYMBOL_PLATFORM OFF}\n    NewData.Attributes := faArchive;\n{$WARN SYMBOL_PLATFORM ON}\n    NewData.StartBlock := 3;\n    NewData.LastModified := Now;\n    NewData.Size := 4;\n    NewData.CompressedSize := 5;\n    NewData.EntryType := etFile;\n    NewNode.Data := NewData;\n  end;\n  Result := NewData;\nend;\n{-----------------------------------------------------------------------------}\nfunction TAbRootDir.AddFolder(FolderName : AnsiString) : TAbDirectoryEntry;\n  {- Adds a folder to the current directory of the compound file}\nvar\n  NewNode : TMultiNode;\n  NewData : TAbDirectoryEntry;\nbegin\n  Result := nil;\n  NewNode := Insert(CurrentNode, FolderName);\n  if NewNode <> nil then begin\n    NewData := TAbDirectoryEntry.Create(False);\n    NewData.FName := FolderName;\n    NewData.ParentFolder := 1;\n    NewData.Attributes := faDirectory;\n    NewData.StartBlock := rdUnUsed;\n    NewData.LastModified := Now;\n    NewData.Size := 0;\n    NewData.CompressedSize := 0;\n    NewData.EntryType := etFolder;\n    NewNode.Data := NewData;\n    Result :=NewData;\n  end;\nend;\n{-----------------------------------------------------------------------------}\nprocedure TAbRootDir.DeleteFile(FileName : AnsiString);\n  {- Deletes the specified file if found}\nbegin\n  DeleteNode(FileName);\nend;\n{-----------------------------------------------------------------------------}\nprocedure TAbRootDir.DeleteFolder(FolderName : AnsiString);\n  {- Deletes the specifed folder if found & empty}\nbegin\n  if not CurrentNode.Contains(FolderName) then\n    raise ECompoundFileError.Create(AbCmpndFileNotFound);\n  if CurrentNode.ChildCount > 0 then\n    raise ECompoundFileError.Create(AbCmpndFolderNotEmpty);\n  DeleteFolder(FolderName);\nend;\n{-----------------------------------------------------------------------------}\nprocedure TAbRootDir.WriteToStream(Strm : TMemoryStream);\n  {- Streams and writes the root directory entries to the stream parameter}\nbegin\n  TraversePre(Strm);\nend;\n{-----------------------------------------------------------------------------}\n{-----------------------------------------------------------------------------}\n            {TAbFATTable}\n{-----------------------------------------------------------------------------}\n{-----------------------------------------------------------------------------}\nconstructor TAbFATTable.Create(AllocSize : Integer);\n  {- Creates the FAT table structure}\nvar\n  i : Integer;\nbegin\n  {Sets FAT length equal to one allocation block}\n  fAllocSize := AllocSize;\n  SetLength(fFATArray, AllocSize div SizeOf(Integer));\n  for i := 0 to High(fFATArray) do\n    fFATArray[i] := ftUnusedBlock;\n  for i := 0 to 2 do\n    fFATArray[i] := ftEndOfBlock;\nend;\n{-----------------------------------------------------------------------------}\ndestructor TAbFATTable.Destroy;\n  {- Destroys the FAT table}\nbegin\n  Finalize(fFATArray);\nend;\n{-----------------------------------------------------------------------------}\nprocedure TAbFATTable.ClearExistingChain(StartNdx : Integer);\n  {- Sets all of the FAT entries pertaining to the sequence starting at StartNds\n     to ftUnUsedBlock}\nvar\n  ChainArray : TFATChainArray;\n  i          : Integer;\nbegin\n  SetLength(ChainArray, 0);\n  GetExistingChain(StartNdx, ChainArray);\n  for i := 0 to High(ChainArray) do\n    fFATArray[ChainArray[i]] := ftUnUsedBlock;\nend;\n{-----------------------------------------------------------------------------}\nprocedure TAbFATTable.ClearFATChain;\n  {- Sets the FAT entries pertaining to the FAT table to unused}\nbegin\n  ClearExistingChain(2);\nend;\n{-----------------------------------------------------------------------------}\nprocedure TAbFATTable.ClearRootDirChain;\n  {- Sets the FAT entries pertaining the the RootDir to unused}\nbegin\n  ClearExistingChain(1);\nend;\n{-----------------------------------------------------------------------------}\nprocedure TAbFATTable.GetExistingChain(StartNdx : Integer;\n                                       var ChainArray : TFATChainArray);\n  {- Walks the FAT table starting at the index specified, and populates the\n     chain array parameter with the results}\nvar\n  BlkCount, i, ChainNdx : Integer;\nbegin\n  if fFATArray[StartNdx] = ftUnUsedBlock then begin\n    SetLength(ChainArray, 0);\n    exit;\n  end;\n\n  {determine count}\n  if StartNdx < 1 then\n    SetLength(ChainArray, 0)\n  else begin\n    BlkCount := 1;\n    i := StartNdx;\n    while fFATArray[i] <> ftEndOfBlock do begin\n      i := fFATArray[i];\n      Inc(BlkCount);\n    end;\n\n    {set up array}\n    SetLength(ChainArray, BlkCount);\n    for i := 0 to High(ChainArray) do\n      ChainArray[i] := ftUnusedBlock;\n\n    {walk FAT & populate array}\n    ChainNdx := 0;\n    ChainArray[ChainNdx] := StartNdx;\n    i := StartNdx;\n    while fFATArray[i] <> ftEndOfBlock do begin\n      Inc(ChainNdx);\n      ChainArray[ChainNdx] := fFATArray[i];\n      i := fFATArray[i];\n    end;\n  end;\nend;\n{-----------------------------------------------------------------------------}\nprocedure TAbFATTable.GetFATChain(var ChainArray : TFATChainArray);\n  {- Returns the sequence of FAT blocks used by the FAT table in the\n     ChainArray parameter}\nbegin\n  GetExistingChain(2, ChainArray);\nend;\n{-----------------------------------------------------------------------------}\nprocedure TAbFATTable.GetNewChain(NumBytes : Integer;\n                                  var ChainArray : TFATChainArray);\n  {- Finds sequence of free blocks required of a file of size NumBytes\n     The new FAT chain is commited and passed back in the ChainArray parameter}\nvar\n  FirstBlock          : Integer;\n  TotalBlocksRequired : Integer;\n  i, j, BlocksFound   : Integer;\nbegin\n  if ((NumBytes mod fAllocSize) <> 0) then\n    TotalBlocksRequired := (NumBytes div fAllocSize) + 1\n  else\n    TotalBlocksRequired := (NumBytes div fAllocSize);\n\n  if TotalBlocksRequired = 0 then\n    exit;\n\n  FirstBlock := GetNextUnusedBlock;\n\n  {set up array}\n  SetLength(ChainArray, TotalBlocksRequired);\n  for i := 0 to High(ChainArray) do\n    ChainArray[i] := ftUnusedBlock;\n\n  ChainArray[0] := FirstBlock;\n  BlocksFound := 1;\n  i := FirstBlock + 1;\n\n  while BlocksFound < TotalBlocksRequired do begin\n    if ((fFATArray[i] = ftUnusedBlock) and (i > 2)) then begin\n      ChainArray[BlocksFound] := i;\n      inc(BlocksFound);\n    end;\n    Inc(i);\n\n    if i > High(fFATArray) then begin\n      {grow FAT (allocate another block)}\n      SetLength(fFATArray, Length(fFATArray) + (fAllocSize div SizeOf(Integer)));\n      for j := High(fFATArray) downto (Length(fFATArray) -\n                                      (fAllocSize div SizeOf(Integer))) do\n        fFATArray[j] := ftUnUsedBlock;\n      end;\n  end;\n\n  {Update FAT}\n  for i := 0 to High(ChainArray) do begin\n    if i = High(ChainArray) then\n      fFATArray[ChainArray[i]] := -1\n    else\n      fFATArray[ChainArray[i]] := ChainArray[i+1];\n  end;\nend;\n{-----------------------------------------------------------------------------}\nprocedure TAbFATTable.GetNewFATChain(NumBytes : Integer;\n                                     var ChainArray : TFATChainArray);\n  {- Finds and commits a new chain starting at the 3rd block. The new chain is\n     returned in the ChainArray parameter}\nvar\n  FirstBlock          : Integer;\n  TotalBlocksRequired : Integer;\n  i, j, BlocksFound   : Integer;\nbegin\n  if ((NumBytes mod fAllocSize) <> 0) then\n    TotalBlocksRequired := (NumBytes div fAllocSize) + 1\n  else\n    TotalBlocksRequired := (NumBytes div fAllocSize);\n\n  if TotalBlocksRequired = 0 then\n    exit;\n\n  FirstBlock := 2;\n\n  {set up array}\n  SetLength(ChainArray, TotalBlocksRequired);\n  for i := 0 to High(ChainArray) do\n    ChainArray[i] := ftUnusedBlock;\n\n  ChainArray[0] := FirstBlock;\n  BlocksFound := 1;\n  i := FirstBlock + 1;\n\n  while BlocksFound < TotalBlocksRequired do begin\n    if ((fFATArray[i] = ftUnusedBlock) and (i > 2)) then begin\n      ChainArray[BlocksFound] := i;\n      inc(BlocksFound);\n    end;\n    Inc(i);\n\n    if i > High(fFATArray) then begin\n      {grow FAT (allocate another block)}\n      SetLength(fFATArray, Length(fFATArray) + (fAllocSize div SizeOf(Integer)));\n      for j := High(fFATArray) downto (Length(fFATArray) -\n                                      (fAllocSize div SizeOf(Integer))) do\n        fFATArray[j] := ftUnUsedBlock;\n      end;\n  end;\n\n  {Update FAT}\n  for i := 0 to High(ChainArray) do begin\n    if i = High(ChainArray) then\n      fFATArray[ChainArray[i]] := -1\n    else\n      fFATArray[ChainArray[i]] := ChainArray[i+1];\n  end;\nend;\n{-----------------------------------------------------------------------------}\nprocedure TAbFATTable.GetNewRootDirChain(NumBytes : Integer;\n                                         var ChainArray : TFATChainArray);\n  {- Finds and commits a new chain starting at the 2nd block. The new chain is\n     returned in the ChainArray parameter}\nvar\n  FirstBlock          : Integer;\n  TotalBlocksRequired : Integer;\n  i, j, BlocksFound   : Integer;\nbegin\n  if ((NumBytes mod fAllocSize) <> 0) then\n    TotalBlocksRequired := (NumBytes div fAllocSize) + 1\n  else\n    TotalBlocksRequired := (NumBytes div fAllocSize);\n\n  if TotalBlocksRequired = 0 then\n    exit;\n\n  FirstBlock := 1;\n\n  {set up array}\n  SetLength(ChainArray, TotalBlocksRequired);\n  for i := 0 to High(ChainArray) do\n    ChainArray[i] := ftUnusedBlock;\n\n  ChainArray[0] := FirstBlock;\n  BlocksFound := 1;\n  i := FirstBlock + 1;\n\n  while BlocksFound < TotalBlocksRequired do begin\n    if ((fFATArray[i] = ftUnusedBlock) and (i > 2)) then begin\n      ChainArray[BlocksFound] := i;\n      inc(BlocksFound);\n    end;\n    Inc(i);\n\n    if i > High(fFATArray) then begin\n      {grow FAT (allocate another block)}\n      SetLength(fFATArray, Length(fFATArray) + (fAllocSize div SizeOf(Integer)));\n      for j := High(fFATArray) downto (Length(fFATArray) -\n                                      (fAllocSize div SizeOf(Integer))) do\n        fFATArray[j] := ftUnUsedBlock;\n      end;\n  end;\n\n  {Update FAT}\n  for i := 0 to High(ChainArray) do begin\n    if i = High(ChainArray) then\n      fFATArray[ChainArray[i]] := -1\n    else\n      fFATArray[ChainArray[i]] := ChainArray[i+1];\n  end;\nend;\n{-----------------------------------------------------------------------------}\nfunction TAbFATTable.GetNextUnusedBlock : Integer;\n  {- Returns the index into the FAT table of the next block marked as unused}\nvar\n  i, j : Integer;\nbegin\n  if Length(fFATArray) = 0 then\n    Result := -1\n  else begin\n    Result := -1;\n    i := 3;\n    while i <= High(fFATArray) do begin\n      if fFATArray[i] = ftUnusedBlock then begin\n        Result := i;\n        exit;\n      end;\n      inc(i);\n\n      if i > High(fFATArray) then begin\n        {grow FAT (allocate another block)}\n        SetLength(fFATArray, Length(fFATArray) +\n                  (fAllocSize div SizeOf(Integer)));\n        for j := High(fFATArray) downto (Length(fFATArray) -\n                      (fAllocSize div SizeOf(Integer))) do\n          fFATArray[j] := ftUnUsedBlock;\n        end;\n    end;\n  end;\nend;\n{-----------------------------------------------------------------------------}\nprocedure TAbFATTable.GetRootDirChain(var ChainArray : TFATChainArray);\n  {- Returns the sequence of FAT blocks used by the RootDir in the\n     ChainArray parameter}\nbegin\n  GetExistingChain(1, ChainArray);\nend;\n{-----------------------------------------------------------------------------}\nfunction TAbFATTable.IsEndOfFile(Ndx : Integer) : Boolean;\n  {- Returns true if Ndx into FAT signifies end of file}\nbegin\n  if ((Ndx < 0) or (Ndx > High(fFATArray)) or\n      (Length(fFATArray) = 0)) then\n    raise ECompoundFileError.Create(AbCmpndIndexOutOfBounds)\n  else\n    Result := (fFATArray[Ndx] = ftEndOfBlock);\nend;\n{-----------------------------------------------------------------------------}\nfunction TAbFATTable.IsUnUsed(Ndx : Integer) : Boolean;\n  {- Returns true if Ndx into FAT signifies an unused block}\nbegin\n  if ((Ndx < 0) or (Ndx > High(fFATArray)) or\n      (Length(fFATArray) = 0)) then\n    raise ECompoundFileError.Create(AbCmpndIndexOutOfBounds)\n  else\n    Result := (fFATArray[Ndx] = ftUnUsedBlock);\nend;\n{-----------------------------------------------------------------------------}\nprocedure TAbFATTable.WriteToStream(Strm : TMemoryStream);\n  {- Streams and writes the FAT entries to the stream parameter}\nbegin\n  Strm.Write(fFATArray[0], Length(fFATArray) * SizeOf(Integer));\nend;\n{-----------------------------------------------------------------------------}\n{-----------------------------------------------------------------------------}\n           {TAbCompoundFile}\n{-----------------------------------------------------------------------------}\n{-----------------------------------------------------------------------------}\nconstructor TAbCompoundFile.Create(const FileName : string; const VolLabel : AnsiString;\n                                   AllocSize : Integer);\n  {- Creates a new instance}\nvar\n  Buff : Array of Byte;\nbegin\n  inherited Create;\n  FSystemBlock := TAbSystemBlock.Create(VolLabel, AllocSize);\n  FFATTable    := TAbFATTable.Create(AllocSize);\n  FRootDir     := TAbRootDir.Create(VolLabel, AllocSize);\n  {create file}\n\n  if FileName <> '' then begin\n    FDiskFile := FileName;\n    FStream := TFileStream.Create(FileName, fmOpenReadWrite or\n                                  fmCreate or fmShareDenyNone);\n\n    {fill first 3 blocks of file}\n    SetLength(Buff, 3 * AllocSize);\n    FStream.Write(Buff, 3 * AllocSize);\n\n    {write System, RootDir, and FAT blocks}\n    PersistSystemBlock;\n    PersistRootDirBlock;\n    PersistFATBlock;\n\n    if Assigned(FOnAfterOpen) then\n      FOnAfterOpen(self);\n  end;\nend;\n\nconstructor TAbCompoundFile.Create(const FileName : string; const VolLabel : AnsiString;\n                       AllocSize : Integer; const Signature: AnsiString);\n  {- Creates a new instance}\nvar\n  Buff : Array of Byte;\nbegin\n  inherited Create;\n  FSystemBlock := TAbSystemBlock.Create(VolLabel, AllocSize);\n  FSystemBlock.Signature := AbLeftStr(Signature, sbSignatureSize);\n  FFATTable    := TAbFATTable.Create(AllocSize);\n  FRootDir     := TAbRootDir.Create(VolLabel, AllocSize);\n  {create file}\n\n  if FileName <> '' then begin\n    FDiskFile := FileName;\n    FStream := TFileStream.Create(FileName, fmOpenReadWrite or\n                                  fmCreate or fmShareDenyNone);\n\n    {fill first 3 blocks of file}\n    SetLength(Buff, 3 * AllocSize);\n    FStream.Write(Buff, 3 * AllocSize);\n\n    {write System, RootDir, and FAT blocks}\n    PersistSystemBlock;\n    PersistRootDirBlock;\n    PersistFATBlock;\n\n    if Assigned(FOnAfterOpen) then\n      FOnAfterOpen(self);\n  end;\nend;\n\n{-----------------------------------------------------------------------------}\ndestructor TAbCompoundFile.Destroy;\n  {- Persists and then destroys the instance of the compound file}\nbegin\n  PersistSystemBlock;\n  PersistRootDirBlock;\n  PersistFATBlock;\n\n  if Assigned(FOnBeforeClose) then\n    FOnBeforeClose(self);\n\n  FSystemBlock.Free;\n  FFATTable.Free;\n  FRootDir.Free;\n  FStream.Free;\n  inherited;\nend;\n{-----------------------------------------------------------------------------}\nprocedure TAbCompoundFile.AddFile(FName : AnsiString; FileData : TStream;\n                                  FileSize : Integer);\n   function JustFilename(const PathName : AnsiString) : AnsiString;\n     {-Return just the filename and extension of a pathname.}\n   var\n     I : Cardinal;\n   begin\n     Result := '';\n     if PathName = '' then Exit;\n     I := Succ(Word(Length(PathName)));\n     repeat\n       Dec(I);\n     until (PathName[I] in ['\\',':']) or (I = 0);\n     Result := System.Copy(PathName, Succ(I), rdEntryNameSize);\n   end;\n\n  {- Compresses, adds & persists the data (FileData)}\nvar\n  DirEntry   : TAbDirectoryEntry;\n  CompStream : TStream;\n  CompHelper : TAbDeflateHelper;\n  ChainArray : TFATChainArray;\nbegin\n  FName := JustFileName(FName);\n  if ((FStream.Size + FileData.Size +\n      (4 * FSystemBlock.AllocationSize)) >= MaxLongInt) then\n    raise ECompoundFileError.Create(AbCmpndExceedsMaxFileSize);\n\n  if FSystemBlock.Updating then\n    raise ECompoundFileError.Create(AbCmpndBusyUpdating);\n  FSystemBlock.BeginUpdate;\n  CompStream := TMemoryStream.Create;\n  CompHelper := TAbDeflateHelper.Create;\n  try\n    DirEntry := FRootDir.AddFile(FName);\n    if DirEntry <> nil then begin\n      DirEntry.FSize := FileSize;\n\n      {compress & update dir entry's compressed size}\n      FileData.Seek(0, soBeginning);\n      Deflate(FileData, CompStream, CompHelper);\n      DirEntry.FCompressedSize := CompStream.Size;\n\n      {Get new FAT chain & persist the data}\n      SetLength(ChainArray, 0);\n      FFATTable.GetNewChain(CompStream.Size, ChainArray);\n      DirEntry.FStartBlock := ChainArray[0];\n      PersistFileData(CompStream, ChainArray);\n      PersistRootDirBlock;\n      PersistFATBlock;\n    end;\n  finally\n    CompStream.Free;\n    CompHelper.Free;\n    FSystemBlock.EndUpdate;\n  end;\nend;\n{-----------------------------------------------------------------------------}\nprocedure TAbCompoundFile.AddDirEntriesFromList(Lst : TStringList);\n  {- Add individual root directory entries to RootDir structure maintaining seq.}\nvar\n  i        : Integer;\n  LstEntry : TAbDirectoryEntry;\n  Entry    : TAbDirectoryEntry;\nbegin\n  for i := 0 to Lst.Count - 1 do begin\n    LstEntry := (Lst.Objects[i] as TAbDirectoryEntry);\n\n    {locate parent folder}\n    FRootDir.GoToEntryID(LstEntry.FParentFolder);\n\n    {Add file or folder}\n    if LstEntry.EntryType = etFolder then\n      Entry := FRootDir.AddFolder(LstEntry.FName)\n    else\n      Entry := FRootDir.AddFile(LstEntry.FName);\n\n    {assign values}\n    Entry.FName := LstEntry.FName;\n    Entry.FEntryID := LstEntry.FEntryID;\n    Entry.FParentFolder := LstEntry.FParentFolder;\n    Entry.FEntryType := LstEntry.FEntryType;\n    Entry.FAttributes := LstEntry.FAttributes;\n    Entry.FStartBlock := LstEntry.FStartBlock;\n    Entry.FLastModified := LstEntry.FLastModified;\n    Entry.FSize := LstEntry.FSize;\n    Entry.FCompressedSize := LstEntry.FCompressedSize;\n  end;\nend;\n{-----------------------------------------------------------------------------}\nfunction TAbCompoundFile.AddFolder(FName : AnsiString) : Boolean;\n  {- Adds a new folder (directory) to the compound file}\nvar\n  EntryCount : Integer;\nbegin\n  if ((FStream.Size + FSystemBlock.AllocationSize) >= MaxLongInt) then\n    raise ECompoundFileError.Create(AbCmpndExceedsMaxFileSize);\n\n  EntryCount := FRootDir.Count;\n  FSystemBlock.BeginUpdate;\n    try\n      FRootDir.AddFolder(FName);\n      PersistRootDirBlock;\n      PersistFATBlock;\n    finally\n      FSystemBlock.EndUpdate;\n    end;\n  Result := ((FRootDir.Count - EntryCount) = 1);\nend;\n{-----------------------------------------------------------------------------}\nprocedure TAbCompoundFile.BuildFat;\n  {- Extracts FAT from this string, writes it to DestStrm(TMemoryStream) and\n     ultimately updates/persists the FAT table}\nvar\n  Buff       : Array of Integer;\n  IntBuff    : Array[0..0] of Integer;\n  DestStrm   : TMemoryStream;\n  i, CurrPos : Integer;\n  NextBlock  : Integer;\nbegin\n  DestStrm := TMemoryStream.Create;\n  try\n    {Dim Buff to allocation block size}\n    SetLength(Buff, FSystemBlock.AllocationSize div SizeOf(Integer));\n\n    {Clear Buff}\n    for i := Low(Buff) to High(Buff) do\n      Buff[i] := ftUnusedBlock;\n\n    {read 1st FAT block into Buff -> Write Buff to DestStrm}\n    FStream.Seek(2 * FSystemBlock.AllocationSize, soBeginning);\n    FStream.Read(Buff[0], FSystemBlock.AllocationSize);\n    DestStrm.Write(Buff[0], FSystemBlock.AllocationSize);\n\n    {Determine next block of FAT chain}\n    NextBlock := Buff[2];\n\n    {read remaining FAT blocks if they exist}\n    While NextBlock <> ftEndOfBlock do begin\n      FStream.Seek((NextBlock) * FSystemBlock.AllocationSize, soBeginning);\n\n      {Clear buff}\n      for i := Low(Buff) to High(Buff) do\n        Buff[i] := ftUnusedBlock;\n\n      FStream.Read(Buff[0], FSystemBlock.AllocationSize);\n      DestStrm.Write(Buff[0], FSystemBlock.AllocationSize);\n\n      {Determine the next FAT block - we'll return to this position in stream}\n      CurrPos := DestStrm.Position;\n      DestStrm.Seek((NextBlock - 1) * SizeOf(Integer), soBeginning);\n      DestStrm.Read(IntBuff[0], SizeOf(Integer));\n      NextBlock := IntBuff[0];\n      DestStrm.Seek(CurrPos, soBeginning);\n    end;\n\n    {Set length of and populate the FFATTable.fFATArray in mem structure}\n    DestStrm.Seek(0, soBeginning);\n    SetLength(FFATTable.fFATArray, DestStrm.Size div SizeOf(Integer));\n    for i := 1 to DestStrm.Size div SizeOf(Integer) do begin\n      DestStrm.Read(IntBuff[0], SizeOf(Integer));\n      FFATTable.fFATArray[i-1] := IntBuff[0];\n    end;\n  finally\n    DestStrm.Free;\n  end;\n  PersistFATBlock;\nend;\n{-----------------------------------------------------------------------------}\nprocedure TAbCompoundFile.BuildRootDir;\n  {- Builds list of root directory entries & passes list to AddDirEntriesFromList}\nvar\n  ChainArray : TFATChainArray;\n  DestStrm   : TMemoryStream;\n  Buff       : Array of Byte;\n  i          : Integer;\n  Entry      : TAbDirectoryEntry;\n  Lst        : TStringList;\n\n  {RootDirEntry buffers}\n  EName     : Array[0..rdEntryNameSize - 1] of AnsiChar;\n  EID       : Array[0..0] of Integer;\n  EPF       : Array[0..0] of Integer;\n  EType     : Array[0..0] of Integer;\n  EAttrib   : Array[0..0] of Integer;\n  EStartBlk : Array[0..0] of Integer;\n  EMod      : Array[0..0] of TDateTime;\n  ESz       : Array[0..0] of Integer;\n  ECompSz   : Array[0..0] of Integer;\nbegin\n  {Get RootDir FAT chain}\n  FFATTable.GetRootDirChain(ChainArray);\n  SetLength(Buff, FSystemBlock.AllocationSize);\n  DestStrm := TMemoryStream.Create;\n  Lst := TStringList.Create;\n  Lst.Duplicates := dupAccept;\n  Lst.Sorted := False;\n  try\n    {Read entire RotDir block to DestStrm}\n    for i := 0 to High(ChainArray) do begin\n      FStream.Seek(FSystemBlock.AllocationSize * ChainArray[i], soBeginning);\n      FStream.Read(Buff[0], FSystemBlock.AllocationSize);\n      DestStrm.Write(Buff[0], FSystemBlock.AllocationSize);\n    end;\n\n    {Reset DestStrm}\n    DestStrm.Seek(0, soBeginning);\n\n    {For all directory entries, read entry, create object, & add to Lst}\n    for i := 0 to (DestStrm.Size div rdSizeOfDirEntry) - 1 do begin\n      {read a single directory entry}\n      DestStrm.Read(EName[0], rdEntryNameSize);\n      if EName = '' then\n        continue;\n      DestStrm.Read(EID[0], SizeOf(Integer));\n      DestStrm.Read(EPF[0], SizeOf(Integer));\n      DestStrm.Read(EType[0], SizeOf(Integer));\n      DestStrm.Read(EAttrib[0], SizeOf(Integer));\n      DestStrm.Read(EStartBlk[0], SizeOf(Integer));\n      DestStrm.Read(EMod[0], SizeOf(TDateTime));\n      DestStrm.Read(ESz[0], SizeOf(Integer));\n      DestStrm.Read(ECompSz[0], SizeOf(Integer));\n\n      if EType[0] = 0 then\n        Entry := TAbDirectoryEntry.Create(False)\n      else\n        Entry := TAbDirectoryEntry.Create(True);\n\n      Entry.FName := EName;\n      Entry.FEntryID := EID[0];\n      Entry.FParentFolder := EPF[0];\n      if EType[0] = 0 then\n        Entry.FEntryType := etFolder\n      else\n        Entry.FEntryType := etFile;\n      Entry.FAttributes := EAttrib[0];\n      Entry.FStartBlock := EStartBlk[0];\n      Entry.FLastModified := EMod[0];\n      Entry.FSize := ESz[0];\n      Entry.FCompressedSize := ECompSz[0];\n\n      {Don't add an empty dir entry}\n      if Entry.FName <> '' then\n        Lst.AddObject(IntToStr(i), TObject(Entry));\n    end;\n\n  {Add individual root directory entries to RootDir structure maintaining seq.}\n  AddDirEntriesFromList(Lst);\n  finally\n    DestStrm.Free;\n    for i := 0 to Lst.Count - 1 do\n      if Lst.Objects[i] <> nil then\n        TAbDirectoryEntry(Lst.Objects[i]).Free;\n    Lst.Free;\n  end;\n\n  {Save updates}\n  PersistRootDirBlock;\n  PersistFATBlock;\nend;\n{-----------------------------------------------------------------------------}\nprocedure TAbCompoundFile.BuildSysBlock;\n  {- Constructs System block from the contents of FStream\n     (used when opening an existing compound file)}\nvar\n  Sig          : Array[0..sbSignatureSize - 1] of AnsiChar;\n  VolLabel     : Array[0..sbVolumeLabelSize - 1] of AnsiChar;\n  Version      : Array[0..sbVersionSize - 1] of AnsiChar;\n  AllocationSz : Array[0..0] of Integer;\nbegin\n  FStream.Seek(0, soBeginning);\n  FStream.Read(Sig[0], sbSignatureSize);\n  FStream.Read(VolLabel[0], sbVolumeLabelSize);\n  FStream.Read(AllocationSz[0], sbAllocationSizeSize);\n  FStream.Read(Version[0], sbVersionSize);\n\n  FSystemBlock.Signature := Sig;\n  FSystemBlock.VolumeLabel := VolLabel;\n  FSystemBlock.AllocationSize := AllocationSz[0];\n  FSystemBlock.FVersion := Version;\n  PersistSystemBlock;\nend;\n{-----------------------------------------------------------------------------}\nprocedure TAbCompoundFile.Defrag;\n  {- Optimizes disk storage}\nbegin\n{ not implemeneted }\nend;\n{-----------------------------------------------------------------------------}\nprocedure TAbCompoundFile.DeleteFile(FName : AnsiString);\n  {- Deletes the file from the RootDirectory and FAT blocks (data remains)}\nvar\n  StartBlock  : Integer;\n  Allow       : Boolean;\n  AllowDirMod : Boolean;\nbegin\n  Allow := True;\n  AllowDirMod := True;\n\n  if not FRootDir.CurrentNode.Contains(FName) then\n    raise ECompoundFileError.Create(AbCmpndFileNotFound);\n\n  if Assigned(FOnBeforeFileDelete) then\n    FOnBeforeFileDelete(self, FName, Allow);\n\n  if Assigned(FOnBeforeDirModified) then\n    FOnBeforeDirModified(self, TMultiNode(FRootDir.CurrentNode.Parent).Key,\n                         AllowDirMod);\n\n  if (Allow and AllowDirMod) then begin\n    StartBlock := TAbDirectoryEntry(FRootDir.GetNode(FName).FData).StartBlock;\n    FFATTable.ClearExistingChain(StartBlock);\n\n    FRootDir.DeleteFile(FName);\n    PersistRootDirBlock;\n    PersistFATBlock;\n  end;\nend;\n{-----------------------------------------------------------------------------}\nprocedure TAbCompoundFile.DeleteFolder(FName : AnsiString);\n  {- Deletes the folder from the RootDirectory block}\nvar\n  Allow       : Boolean;\n  AllowDirMod : Boolean;\nbegin\n  Allow := True;\n  AllowDirMod := True;\n\n  if not FRootDir.CurrentNode.Contains(FName) then\n    raise ECompoundFileError.Create(AbCmpndFileNotFound);\n\n  if Assigned(FOnBeforeDirDelete) then\n    FOnBeforeDirDelete(self, FName, Allow);\n\n  if Assigned(FOnBeforeDirModified) then\n    FOnBeforeDirModified(self, TMultiNode(FRootDir.CurrentNode.Parent).Key,\n                         AllowDirMod);\n\n  if (Allow and AllowDirMod) then begin\n    FRootDir.DeleteFolder(FName);\n    PersistRootDirBlock;\n    PersistFATBlock;\n  end;\nend;\n{-----------------------------------------------------------------------------}\nprocedure TAbCompoundFile.EnumerateFiles(Lst : TStringList);\nvar\n  i : Integer;\nbegin\n  Lst.Clear;\n  for i := 0 to FRootDir.CurrentNode.ChildCount - 1 do begin\n    if (FRootDir.CurrentNode.Children[i].Data as TAbDirectoryEntry).EntryType = etFile then\n      Lst.Add(string((FRootDir.CurrentNode.Children[i].Data as TAbDirectoryEntry).EntryName));\n  end;\nend;\n{-----------------------------------------------------------------------------}\nprocedure TAbCompoundFile.EnumerateFolders(Lst : TStringList);\nvar\n  i : Integer;\nbegin\n  Lst.Clear;\n  for i := 0 to FRootDir.CurrentNode.ChildCount - 1 do begin\n    if (FRootDir.CurrentNode.Children[i].Data as TAbDirectoryEntry).EntryType = etFolder then\n      Lst.Add(string((FRootDir.CurrentNode.Children[i].Data as TAbDirectoryEntry).EntryName));\n  end;\nend;\n{-----------------------------------------------------------------------------}\nfunction TAbCompoundFile.GetAllocationSize : Integer;\n  {- Returns the block allocation size used by the compound file}\nbegin\n  result := FSystemBlock.AllocationSize;\nend;\n{-----------------------------------------------------------------------------}\nfunction TAbCompoundFile.GetCurrentDirectory : AnsiString;\n  {- Returns the current directory}\nbegin\n  Result := FRootDir.CurrentNode.Key;\nend;\n{-----------------------------------------------------------------------------}\nfunction TAbCompoundFile.GetDirectoryEntries : Integer;\n  {- Returns the total number of directory entries (files and folders)}\nbegin\n  Result := FRootDir.Count;\nend;\n{-----------------------------------------------------------------------------}\nfunction TAbCompoundFile.GetSizeOnDisk : Integer;\n  {- Returns the compound file size (FStream.Size)}\nbegin\n  Result := FStream.Size;\nend;\n{-----------------------------------------------------------------------------}\nfunction TAbCompoundFile.GetVolumeLabel : AnsiString;\n  {- Returns the volume label of the compound file}\nbegin\n  Result := FSystemBlock.VolumeLabel;\nend;\n{-----------------------------------------------------------------------------}\nprocedure TAbRootDir.GoToEntryID(ID : Integer);\n  {- Traverses tree and sets the current node to the node whose EntryID = ID}\nbegin\n  TraversePost(ID);\nend;\n{-----------------------------------------------------------------------------}\nprocedure TAbCompoundFile.Open(const FName : string);\n{- Opens an existing compound file and builds Sys, Root Dir, and FAT blocks}\nvar\n  Sig : Array[0..sbSignatureSize - 1] of AnsiChar;\nbegin\n  if FStream <> nil then\n    FStream.Free;\n  FStream := TFileStream.Create(FName, fmOpenReadWrite or fmShareDenyNone);\n\n  {Ensure valid signature}\n  FStream.Read(Sig[0], sbSignatureSize);\n  if Sig <> AbLeftStr(FSystemBlock.Signature, sbSignatureSize) then begin\n    raise ECompoundFileError.Create(AbCmpndInvalidFile);\n    exit;\n  end;\n\n  FDiskFile := FName;\n  {populate Compound File structure}\n  BuildSysBlock;\n  BuildFat;\n  BuildRootDir;\n\n  if Assigned(FOnAfterOpen) then\n    FOnAfterOpen(self);\nend;\n\nprocedure TAbCompoundFile.Open(const FName : string; const Signature: AnsiString);\n{- Opens an existing compound file and builds Sys, Root Dir, and FAT blocks}\nvar\n  Sig : Array[0..sbSignatureSize - 1] of AnsiChar;\nbegin\n  if FStream <> nil then\n    FStream.Free;\n  FStream := TFileStream.Create(FName, fmOpenReadWrite or fmShareDenyNone);\n\n  {Ensure valid signature}\n  FStream.Read(Sig[0], sbSignatureSize);\n  if Sig <> AbLeftStr(Signature, sbSignatureSize) then begin\n    raise ECompoundFileError.Create(AbCmpndInvalidFile);\n    exit;\n  end;\n\n  FDiskFile := FName;\n  {populate Compound File structure}\n  BuildSysBlock;\n  BuildFat;\n  BuildRootDir;\n\n  if Assigned(FOnAfterOpen) then\n    FOnAfterOpen(self);\nend;\n{-----------------------------------------------------------------------------}\nfunction TAbCompoundFile.OpenFile(FileName : AnsiString; var Strm : TStream)\n                                  : Integer;\n  {- Opens the file and writes the file contents to Strm}\nvar\n  ChainArray     : TFatChainArray;\n  i, j           : Integer;\n  Buff           : Array of Byte;\n  RemainingBytes : Integer;\n  CompStream     : TStream;\n  CompHelper     : TAbDeflateHelper;\nbegin\n  if not FRootDir.CurrentNode.Contains(FileName) then\n    raise ECompoundFileError.Create(AbCmpndFileNotFound);\n\n  CompStream := TMemoryStream.Create;\n  CompHelper := TAbDeflateHelper.Create;\n\n  try\n    {Read the existing (compressed) file into CompStream}\n    FFATTable.GetExistingChain((FRootDir.GetNode(FileName).FData\n                                as TAbDirectoryEntry).StartBlock, ChainArray);\n    SetLength(Buff, FSystemBlock.AllocationSize);\n    for i := 0 to high(ChainArray) do begin\n      for j := 0 to Pred(FSystemBlock.AllocationSize) do\n        Buff[j] := Byte(chr(0));\n      FStream.Seek((ChainArray[i]) * FSystemBlock.AllocationSize, soBeginning);\n      if i <> High(ChainArray) then begin\n        FStream.Read(buff[0], FSystemBlock.AllocationSize);\n        CompStream.Write(Buff[0], FSystemBlock.AllocationSize);\n      end else begin\n        {read less than entire block}\n        RemainingBytes := (FRootDir.GetNode(FileName).FData as TAbDirectoryEntry).\n                           CompressedSize mod FSystemBlock.AllocationSize;\n        FStream.Read(Buff[0], RemainingBytes);\n        CompStream.Write(Buff[0], RemainingBytes);\n      end;\n    end;\n\n    {CompStream now contains the entire compressed file stream}\n    CompStream.Seek(0, soBeginning);\n    Inflate(CompStream, Strm, CompHelper);\n  finally\n    CompStream.Free;\n    CompHelper.Free;\n  end;\n  Result := Strm.Size;\nend;\n{-----------------------------------------------------------------------------}\nprocedure TAbCompoundFile.PersistFATBlock;\n  {- Saves the FAT table to disk}\nvar\n  FATStrm    : TMemoryStream;\n  Buff       : Array of Byte;\n  i          : Integer;\n  ChainArray : TFATChainArray;\nbegin\n  {Init Buffer}\n  SetLength(Buff, FSystemBlock.AllocationSize);\n\n  {Init & fill RootDir stream}\n  FATStrm := TMemoryStream.Create;\n\n  try\n    FFATTable.WriteToStream(FATStrm);\n\n    {prep FAT Table}\n    fFATTable.ClearFATChain;\n    fFATTable.GetNewFATChain(FATStrm.Size, ChainArray);\n\n    FATStrm.Seek(0, soBeginning);\n    for i := 0 to High(ChainArray) do begin\n\n      {Clear block contents}\n      FillChar(Buff[0], FSystemBlock.AllocationSize, #0);\n      FStream.Seek(FSystemBlock.FAllocationSize * ChainArray[i], soBeginning);\n      FStream.Write(Buff[0], FSystemBlock.AllocationSize);\n\n      {write new contents}\n      FATStrm.Read(Buff[0], FSystemBlock.AllocationSize);\n      FStream.Seek(FSystemBlock.FAllocationSize * ChainArray[i], soBeginning);\n      FStream.Write(Buff[0], FSystemBlock.AllocationSize);\n    end;\n  finally\n    FATStrm.Free;\n  end;\nend;\n{-----------------------------------------------------------------------------}\nprocedure TAbCompoundFile.PersistFileData(FileData : TStream;\n                                          var ChainArray : TFATChainArray);\n  {- Walks FAT chain and persists data (FileData) to the corresponding blocks}\nvar\n  Buff : Array of Byte;\n  i    : Integer;\n  j    : Integer;\nbegin\n  if FileData <> nil then begin\n    FileData.Seek(0, soBeginning);\n    SetLength(Buff, FSystemBlock.AllocationSize);\n    for i := 0 to High(ChainArray) do begin\n      for j := 0 to FSystemBlock.AllocationSize - 1 do\n        Buff[j] := Byte(chr(0));\n      FileData.Read(Buff[0], FSystemBlock.AllocationSize);\n      FStream.Seek(FSystemBlock.AllocationSize * ChainArray[i], soBeginning);\n\n      FStream.Write(Buff[0],FSystemBlock.AllocationSize);\n    end;\n  end;\nend;\n{-----------------------------------------------------------------------------}\nprocedure TAbCompoundFile.PersistRootDirBlock;\n  {- Saves the RootDirectory block to disk}\nvar\n  RdStrm     : TMemoryStream;\n  Buff       : Array of Byte;\n  i          : Integer;\n  ChainArray : TFATChainArray;\nbegin\n  {Init Buffer}\n  SetLength(Buff, FSystemBlock.AllocationSize);\n\n  {Init & fill RootDir stream}\n  RdStrm := TMemoryStream.Create;\n  try\n    FRootDir.WriteToStream(RdStrm);\n\n    {prep FAT Table}\n    fFATTable.ClearRootDirChain;\n    fFATTable.GetNewRootDirChain(RdStrm.Size, ChainArray);\n\n    RdStrm.Seek(0, soBeginning);\n    for i := 0 to High(ChainArray) do begin\n      {Clear block contents}\n      FillChar(Buff[0], FSystemBlock.AllocationSize, #0);\n      FStream.Seek(FSystemBlock.FAllocationSize * ChainArray[i], soBeginning);\n      FStream.Write(Buff[0], FSystemBlock.AllocationSize);\n\n      {write new contents}\n      RdStrm.Read(Buff[0], FSystemBlock.AllocationSize);\n      FStream.Seek(FSystemBlock.FAllocationSize * ChainArray[i], soBeginning);\n      FStream.Write(Buff[0], FSystemBlock.AllocationSize);\n    end;\n  finally\n    RdStrm.Free;\n  end;\nend;\n{-----------------------------------------------------------------------------}\nprocedure TAbCompoundFile.PersistSystemBlock;\n  {- Saves the System block to disk}\nvar\n  Strm : TMemoryStream;\n  Buff : Array of Byte;\nbegin\n  SetLength(Buff, FSystemBlock.AllocationSize);\n  Strm := TMemoryStream.Create;\n  try\n    FSystemBlock.WriteToStream(Strm);\n    Strm.Seek(0, soBeginning);\n    Strm.Read(Buff[0], Strm.Size);\n    FStream.Seek(0, soBeginning);\n    FStream.Write(Buff[0], FSystemBlock.AllocationSize);\n  finally\n    Strm.Free;\n  end;\nend;\n{-----------------------------------------------------------------------------}\nprocedure TAbCompoundFile.SetCurrentDirectory(val : AnsiString);\n  {- Changes the current directory to the val parameter}\nbegin\n  FRootDir.ChangeDir(Val);\nend;\n{-----------------------------------------------------------------------------}\nprocedure TAbCompoundFile.SetVolumeLabel(Val : AnsiString);\n  {- Sets the volume label of the compound file}\nbegin\n  FSystemBlock.VolumeLabel := Val;\n  PersistSystemBlock;\nend;\n{-----------------------------------------------------------------------------}\nprocedure TAbCompoundFile.UpdateFile(FName : AnsiString; FData : TStream);\nvar\n  StartBlk    : Integer;\n  ChainArray  : TFATChainArray;\n  DirEntry    : TAbDirectoryEntry;\n  CompStream  : TStream;\n  CompHelper  : TAbDeflateHelper;\n  Allow       : Boolean;\n  AllowDirMod : Boolean;\nbegin\n  Allow := True;\n  AllowDirMod := True;\n  if not FRootDir.CurrentNode.Contains(FName) then\n    raise ECompoundFileError.Create(AbCmpndFileNotFound);\n\n  if ((FStream.Size + FData.Size +\n      (4 * FSystemBlock.AllocationSize)) >= MaxLongInt) then\n    raise ECompoundFileError.Create(AbCmpndExceedsMaxFileSize);\n\n  if Assigned(FOnBeforeFileModified) then\n    FOnBeforeFileModified(self, FName, Allow);\n\n  if Assigned(FOnBeforeDirModified) then\n    FOnBeforeDirModified(self, TMultiNode(FRootDir.CurrentNode.Parent).Key,\n                         AllowDirMod);\n\n  if (Allow and AllowDirMod) then begin\n    {get dir entry & start block}\n    DirEntry := TAbDirectoryEntry(FRootDir.CurrentNode.GetChildByName(FName).Data);\n    StartBlk := DirEntry.StartBlock;\n    CompStream := TMemoryStream.Create;\n    CompHelper := TAbDeflateHelper.Create;\n\n    try\n      {clear existing FAT chain}\n      FFATTable.ClearExistingChain(StartBlk);\n      SetLength(ChainArray, 0);\n\n      {Deflate data}\n      FData.Seek(0, soBeginning);\n      Deflate(FData, CompStream, CompHelper);\n\n      {Commit new FAT chain}\n      FFATTable.GetNewChain(CompStream.Size, ChainArray);\n\n      {update start block, size, compressed size}\n      DirEntry.FStartBlock := ChainArray[0];\n      DirEntry.Size := FData.Size;\n      DirEntry.CompressedSize := CompStream.Size;\n\n      {persist changes}\n      PersistFileData(CompStream, ChainArray);\n      PersistRootDirBlock;\n      PersistFATBlock;\n    finally\n      CompStream.Free;\n      CompHelper.Free;\n    end;\n  end;\nend;\n{-----------------------------------------------------------------------------}\n\n\n\nfunction TAbCompoundFile.PopulateTreeView(TreeView : TTreeView) : Integer;\n  {- Populates the tree view parameter with all root directory entries}\nvar\n  i        : Integer;\n  TreeNode : TTreeNode;\nbegin\n  TreeView.Items.Clear;\n  if FRootDir.Root <> nil then begin\n    TreeNode := TreeView.Items.Add(nil, string(FRootDir.Root.Key));\n    TreeNode.ImageIndex := 0;\n    TreeNode.SelectedIndex := 0;\n    if FRootDir.Root.HasChildren then begin\n      for i := 0 to FRootDir.Root.ChildCount - 1 do\n        PopulateSubNodes(FRootDir.Root.Children[i], TreeView, TreeNode);\n    end;\n  end;\n  Result := TreeView.Items.Count;\nend;\n{-----------------------------------------------------------------------------}\nprocedure TAbCompoundFile.PopulateSubNodes(ParentNode : TMultiNode;\n                     TreeView : TTreeView; TreeNode : TTreeNode);\n  {- Visits sub-nodes recursively - pre order}\nvar\n  Curr : TMultiNode;\n  i    : Integer;\n  Node : TTreeNode;\nbegin\n  Node := TreeView.Items.AddChild(TreeNode, string(ParentNode.Key));\n  if TAbDirectoryEntry(ParentNode.Data).EntryType = etFolder then begin\n    Node.ImageIndex := 0;\n    Node.SelectedIndex := 0;\n  end else begin\n    Node.ImageIndex := 1;\n    Node.SelectedIndex := 1;\n  end;\n  Curr := ParentNode;\n  if Curr <> nil then begin\n    if Curr.HasChildren then begin\n      for i := 0 to Curr.ChildCount -1 do\n        PopulateSubNodes(Curr.Children[i], TreeView, Node);\n    end;\n  end;\nend;\n{-----------------------------------------------------------------------------}\nprocedure TAbCompoundFile.RenameFile(OrigName, NewName : AnsiString);\n  {- Renames the file if file is found}\nvar\n  MultNode    : TMultiNode;\n  Allow       : Boolean;\n  AllowDirMod : Boolean;\nbegin\n  Allow := True;\n  AllowDirMod := True;\n\n  {confirm valid names}\n  if ((OrigName = '') or (NewName = '')) then exit;\n\n  {prevent duplicate names}\n  if ((FRootDir.FCurrentNode.Contains(NewName)) or\n     (FRootDir.FCurrentNode.Key = NewName)) then exit;\n\n  if Assigned(FOnBeforeFileModified) then\n    FOnBeforeFileModified(self, OrigName, Allow);\n\n  if Assigned(FOnBeforeDirModified) then\n    FOnBeforeDirModified(self, TMultiNode(FRootDir.CurrentNode.Parent).Key,\n                         AllowDirMod);\n\n  if (Allow and AllowDirMod) then begin\n    if FRootDir.FCurrentNode.Contains(OrigName) then begin\n      MultNode := FRootDir.FCurrentNode.GetChildByName(OrigName);\n      MultNode.Key := NewName;\n      TAbDirectoryEntry(MultNode.Data).FName := NewName;\n      PersistRootDirBlock;\n    end else if FRootDir.FCurrentNode.Key = OrigName then begin\n      MultNode := FRootDir.FCurrentNode;\n      MultNode.Key := NewName;\n      TAbDirectoryEntry(MultNode.Data).FName := NewName;\n      PersistRootDirBlock;\n    end else\n      raise ECompoundFileError.Create(AbCmpndFileNotFound);\n  end;\nend;\n{-----------------------------------------------------------------------------}\nprocedure TAbCompoundFile.RenameFolder(OrigName, NewName : AnsiString);\n  {- Renames the folder if the folder is found}\nvar\n  MultNode    : TMultiNode;\n  Allow       : Boolean;\n  AllowDirMod : Boolean;\nbegin\n  Allow := True;\n  AllowDirMod := True;\n\n  {confirm valid names}\n  if ((OrigName = '') or (NewName = '')) then exit;\n\n  {prevent duplicate names}\n  if ((FRootDir.FCurrentNode.Contains(NewName)) or\n     (FRootDir.FCurrentNode.Key = NewName)) then exit;\n\n\n  if Assigned(FOnBeforeFileModified) then\n    FOnBeforeFileModified(self, OrigName, Allow);\n\n  if Assigned(FOnBeforeDirModified) then\n    FOnBeforeDirModified(self, TMultiNode(FRootDir.CurrentNode.Parent).Key,\n                         AllowDirMod);\n\n  if (Allow and AllowDirMod) then begin\n    if FRootDir.FCurrentNode.Contains(OrigName) then begin\n      MultNode := FRootDir.FCurrentNode.GetChildByName(OrigName);\n      if (TAbDirectoryEntry(MultNode.Data).EntryType <> etFolder) then\n        exit;\n      MultNode.Key := NewName;\n      TAbDirectoryEntry(MultNode.Data).FName := NewName;\n      PersistRootDirBlock;\n    end else if FRootDir.FCurrentNode.Key = OrigName then begin\n      MultNode := FRootDir.FCurrentNode;\n      if (TAbDirectoryEntry(MultNode.Data).EntryType <> etFolder) then\n        exit;\n      MultNode.Key := NewName;\n      TAbDirectoryEntry(MultNode.Data).FName := NewName;\n      PersistRootDirBlock;\n    end else\n      raise ECompoundFileError.Create(AbCmpndFileNotFound);\n  end;\nend;\n{-----------------------------------------------------------------------------}\n\nend.\n"
  },
  {
    "path": "lib/abbrevia/source/AbConst.pas",
    "content": "(* ***** BEGIN LICENSE BLOCK *****\n * Version: MPL 1.1\n *\n * The contents of this file are subject to the Mozilla Public License Version\n * 1.1 (the \"License\"); you may not use this file except in compliance with\n * the License. You may obtain a copy of the License at\n * http://www.mozilla.org/MPL/\n *\n * Software distributed under the License is distributed on an \"AS IS\" basis,\n * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License\n * for the specific language governing rights and limitations under the\n * License.\n *\n * The Original Code is TurboPower Abbrevia\n *\n * The Initial Developer of the Original Code is\n * TurboPower Software\n *\n * Portions created by the Initial Developer are Copyright (C) 1997-2002\n * the Initial Developer. All Rights Reserved.\n *\n * Contributor(s):\n *\n * ***** END LICENSE BLOCK ***** *)\n\n{*********************************************************}\n{* Abbrevia: AbConst.pas                                 *}\n{*********************************************************}\n{* Abbrevia: Constants                                   *}\n{*********************************************************}\n\nunit AbConst;\n\n{$I AbDefine.inc}\n\ninterface\n\nconst\n  AbVersion = 5.0;\n  AbVersionS = '5.0';\n  Ab_MessageLen = 255;\n  Ab_CaptionLen = 80;\n  AB_ZIPPATHDELIM = '/';\n\nconst\n  AbZipVersionNeeded             = 1;\n  AbUnknownCompressionMethod     = 2;\n  AbNoExtractionMethod           = 3;\n  AbInvalidPassword              = 4;\n  AbNoInsertionMethod            = 5;\n  AbInvalidFactor                = 6;\n  AbDuplicateName                = 7;\n  AbUnsupportedCompressionMethod = 8;\n  AbUserAbort                    = 9;\n  AbArchiveBusy                  = 10;\n  AbBadSpanStream                = 11;\n  AbNoOverwriteSpanStream        = 12;\n  AbNoSpannedSelfExtract         = 13;\n  AbStreamFull                   = 14;\n  AbNoSuchDirectory              = 15;\n  AbInflateBlockError            = 16;\n  AbBadStreamType                = 17;\n  AbTruncateError                = 18;\n  AbZipBadCRC                    = 19;\n  AbZipBadStub                   = 20;\n  AbFileNotFound                 = 21;\n  AbInvalidLFH                   = 22;\n  AbNoArchive                    = 23;\n  AbErrZipInvalid                = 24;\n  AbReadError                    = 25;\n  AbInvalidIndex                 = 26;\n  AbInvalidThreshold             = 27;\n  AbUnhandledFileType            = 28;\n  AbSpanningNotSupported         = 29;\n\n  AbBBSReadTooManyBytes          = 40;\n  AbBBSSeekOutsideBuffer         = 41;\n  AbBBSInvalidOrigin             = 42;\n  AbBBSWriteTooManyBytes         = 43;\n\n  AbNoCabinetDllError            = 50;\n  AbFCIFileOpenError             = 51;\n  AbFCIFileReadError             = 52;\n  AbFCIFileWriteError            = 53;\n  AbFCIFileCloseError            = 54;\n  AbFCIFileSeekError             = 55;\n  AbFCIFileDeleteError           = 56;\n  AbFCIAddFileError              = 57;\n  AbFCICreateError               = 58;\n  AbFCIFlushCabinetError         = 59;\n  AbFCIFlushFolderError          = 60;\n  AbFDICopyError                 = 61;\n  AbFDICreateError               = 62;\n  AbInvalidCabTemplate           = 63;\n  AbInvalidCabFile               = 64;\n\n  AbSWSNotEndofStream            = 80;\n  AbSWSSeekFailed                = 81;\n  AbSWSWriteFailed               = 82;\n  AbSWSInvalidOrigin             = 83;\n  AbSWSInvalidNewOrigin          = 84;\n\n  AbVMSReadTooManyBytes           = 100;\n  AbVMSInvalidOrigin              = 101;\n  AbVMSErrorOpenSwap              = 102;\n  AbVMSSeekFail                   = 103;\n  AbVMSReadFail                   = 104;\n  AbVMSWriteFail                  = 105;\n  AbVMSWriteTooManyBytes          = 106;\n\n  AbGZipInvalid                   = 200;\n  AbGzipBadCRC                    = 201;\n  AbGzipBadFileSize               = 202;\n\n  AbTarInvalid                    = 220;\n  AbTarBadFileName                = 221;\n  AbTarBadLinkName                = 222;\n  AbTarBadOp                      = 223;\n\n\nfunction AbStrRes(Index : Integer) : string;\n\nimplementation\n\nuses\n  AbResString;\n\ntype\n  AbStrRec = record\n    ID: Integer;\n    Str: string;\n  end;\n\nconst\n  AbStrArray : array [0..66] of AbStrRec = (\n    (ID: AbZipVersionNeeded; Str: AbZipVersionNeededS),\n    (ID: AbUnknownCompressionMethod; Str: AbUnknownCompressionMethodS),\n    (ID: AbNoExtractionMethod; Str: AbNoExtractionMethodS),\n    (ID: AbInvalidPassword; Str: AbInvalidPasswordS),\n    (ID: AbNoInsertionMethod; Str: AbNoInsertionMethodS),\n    (ID: AbInvalidFactor; Str: AbInvalidFactorS),\n    (ID: AbDuplicateName; Str: AbDuplicateNameS),\n    (ID: AbUnsupportedCompressionMethod; Str: AbUnsupportedCompressionMethodS),\n    (ID: AbUserAbort; Str: AbUserAbortS),\n    (ID: AbArchiveBusy; Str: AbArchiveBusyS),\n    (ID: AbBadSpanStream; Str: AbBadSpanStreamS),\n    (ID: AbNoOverwriteSpanStream; Str: AbNoOverwriteSpanStreamS),\n    (ID: AbNoSpannedSelfExtract; Str: AbNoSpannedSelfExtractS),\n    (ID: AbStreamFull; Str: AbStreamFullS),\n    (ID: AbNoSuchDirectory; Str: AbNoSuchDirectoryS),\n    (ID: AbInflateBlockError; Str: AbInflateBlockErrorS),\n    (ID: AbBadStreamType; Str: AbBadStreamTypeS),\n    (ID: AbTruncateError; Str: AbTruncateErrorS),\n    (ID: AbZipBadCRC; Str: AbZipBadCRCS),\n    (ID: AbZipBadStub; Str: AbZipBadStubS),\n    (ID: AbFileNotFound; Str: AbFileNotFoundS),\n    (ID: AbInvalidLFH; Str: AbInvalidLFHS),\n    (ID: AbNoArchive; Str: AbNoArchiveS),\n    (ID: AbErrZipInvalid; Str: AbErrZipInvalidS),\n    (ID: AbReadError; Str: AbReadErrorS),\n    (ID: AbInvalidIndex; Str: AbInvalidIndexS),\n    (ID: AbInvalidThreshold; Str: AbInvalidThresholdS),\n    (ID: AbUnhandledFileType; Str: AbUnhandledFileTypeS),\n    (ID: AbSpanningNotSupported; Str: AbSpanningNotSupportedS),\n\n    (ID: AbBBSReadTooManyBytes; Str: AbBBSReadTooManyBytesS),\n    (ID: AbBBSSeekOutsideBuffer; Str: AbBBSSeekOutsideBufferS),\n    (ID: AbBBSInvalidOrigin; Str: AbBBSInvalidOriginS),\n    (ID: AbBBSWriteTooManyBytes; Str: AbBBSWriteTooManyBytesS),\n\n    (ID: AbNoCabinetDllError; Str: AbNoCabinetDllErrorS),\n    (ID: AbFCIFileOpenError; Str: AbFCIFileOpenErrorS),\n    (ID: AbFCIFileReadError; Str: AbFCIFileReadErrorS),\n    (ID: AbFCIFileWriteError; Str: AbFCIFileWriteErrorS),\n    (ID: AbFCIFileCloseError; Str: AbFCIFileCloseErrorS),\n    (ID: AbFCIFileSeekError; Str: AbFCIFileSeekErrorS),\n    (ID: AbFCIFileDeleteError; Str: AbFCIFileDeleteErrorS),\n    (ID: AbFCIAddFileError; Str: AbFCIAddFileErrorS),\n    (ID: AbFCICreateError; Str: AbFCICreateErrorS),\n    (ID: AbFCIFlushCabinetError; Str: AbFCIFlushCabinetErrorS),\n    (ID: AbFCIFlushFolderError; Str: AbFCIFlushFolderErrorS),\n    (ID: AbFDICopyError; Str: AbFDICopyErrorS),\n    (ID: AbFDICreateError; Str: AbFDICreateErrorS),\n    (ID: AbInvalidCabTemplate; Str: AbInvalidCabTemplateS),\n    (ID: AbInvalidCabFile; Str: AbInvalidCabFileS),\n\n    (ID: AbSWSNotEndofStream; Str: AbSWSNotEndofStreamS),\n    (ID: AbSWSSeekFailed; Str: AbSWSSeekFailedS),\n    (ID: AbSWSWriteFailed; Str: AbSWSWriteFailedS),\n    (ID: AbSWSInvalidOrigin; Str: AbSWSInvalidOriginS),\n    (ID: AbSWSInvalidNewOrigin; Str: AbSWSInvalidNewOriginS),\n\n    (ID: AbVMSReadTooManyBytes; Str: AbVMSReadTooManyBytesS),\n    (ID: AbVMSInvalidOrigin; Str: AbVMSInvalidOriginS),\n    (ID: AbVMSErrorOpenSwap; Str: AbVMSErrorOpenSwapS),\n    (ID: AbVMSSeekFail; Str: AbVMSSeekFailS),\n    (ID: AbVMSReadFail; Str: AbVMSReadFailS),\n    (ID: AbVMSWriteFail; Str: AbVMSWriteFailS),\n    (ID: AbVMSWriteTooManyBytes; Str: AbVMSWriteTooManyBytesS),\n\n    (ID: AbGzipInvalid; Str: AbGzipInvalidS),\n    (ID: AbGzipBadCRC; Str: AbGzipBadCRCS),\n    (ID: AbGzipBadFileSize; Str: AbGzipBadFileSizeS),\n\n    (ID: AbTarInvalid; Str: AbTarInvalidS),\n    (ID: AbTarBadFileName; Str: AbTarBadFileNameS),\n    (ID: AbTarBadLinkName; Str: AbTarBadLinkNameS),\n    (ID: AbTarBadOp; Str: AbTarBadOpS)\n  );\n\nfunction AbStrRes(Index : Integer) : string;\nvar\n  i : Integer;\nbegin\n  for i := Low(AbStrArray) to High(AbStrArray) do\n    if AbStrArray[i].ID = Index then\n      Result := AbStrArray[i].Str;\nend;\n\nend.\n"
  },
  {
    "path": "lib/abbrevia/source/AbCrtl.pas",
    "content": "(* ***** BEGIN LICENSE BLOCK *****\n * Version: MPL 1.1\n *\n * The contents of this file are subject to the Mozilla Public License Version\n * 1.1 (the \"License\"); you may not use this file except in compliance with\n * the License. You may obtain a copy of the License at\n * http://www.mozilla.org/MPL/\n *\n * Software distributed under the License is distributed on an \"AS IS\" basis,\n * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License\n * for the specific language governing rights and limitations under the\n * License.\n *\n * The Original Code is TurboPower Abbrevia\n *\n * The Initial Developer of the Original Code is\n * TurboPower Software\n *\n * Portions created by the Initial Developer are Copyright (C) 1997-2002\n * the Initial Developer. All Rights Reserved.\n *\n * Contributor(s):\n * Craig Peterson <capeterson@users.sourceforge.net>\n *\n * ***** END LICENSE BLOCK ***** *)\n\n{*********************************************************}\n{* ABBREVIA: AbCrtl.pas                                  *}\n{*********************************************************}\n{* ABBREVIA: C++Builder C runtime functions              *}\n{*********************************************************}\n\nunit AbCrtl;\n\n{$I AbDefine.inc}\n\ninterface\n\nuses\n  Windows;\n\ntype\n  UInt32 = LongWord;\n  size_t = {$IF defined(CPUX64)}Int64{$ELSE}Integer{$IFEND}; // NativeInt is 8 bytes in Delphi 2007\n\nconst\n  __turboFloat: LongInt = 0;\n  _fltused: LongInt = 0;\n\nprocedure abs; cdecl;\n  external 'msvcrt.dll';\nprocedure _llshl; cdecl;\n  external 'msvcrt.dll';\nprocedure _llushr; cdecl;\n  external 'msvcrt.dll';\nprocedure _ftol; cdecl;\n  external 'msvcrt.dll' {$IFDEF BCB}name '__ftol'{$ENDIF};\n\n{ ctype.h declarations ===================================================== }\nfunction isdigit(ch: Integer): Integer; cdecl;\n\n{ string.h declarations ==================================================== }\nfunction memcpy(Dest, Src: Pointer; Count: size_t): Pointer; cdecl;\nfunction memmove(Dest, Src: Pointer; Count: size_t): Pointer; cdecl;\nfunction memset(Dest: Pointer; Value: Byte; Count: size_t): Pointer; cdecl;\nfunction strlen(P: PAnsiChar): Integer; cdecl;\nfunction strcpy(Des, Src: PAnsiChar): PAnsiChar; cdecl;\nfunction strncpy(Des, Src: PAnsiChar; MaxLen: Integer): PAnsiChar; cdecl;\n\nfunction memcmp(s1,s2: Pointer; numBytes: LongWord): integer; cdecl;\n  external 'msvcrt.dll';\nfunction wcscpy(strDestination, strSource: PWideChar): PWideChar; cdecl;\n  external 'msvcrt.dll';\n\n{ stdlib.h declarations ==================================================== }\nfunction malloc(Size: Integer): Pointer; cdecl;\nprocedure free(Ptr: Pointer); cdecl;\nfunction realloc(Ptr: Pointer; Size: Integer): Pointer; cdecl;\n\n{ intrin.h declarations ==================================================== }\nprocedure ___cpuid(CPUInfo: PInteger; InfoType: Integer); cdecl;\n  external 'msvcrt.dll';\n\n{ stdio.h declarations ===================================================== }\nfunction sprintf(S: PChar; const Format: PChar): Integer;\n  cdecl; varargs; external 'msvcrt.dll' {$IFDEF BCB}name '_sprintf'{$ENDIF};\n\n{ process.h declarations =================================================== }\nfunction _beginthreadex(security: Pointer; stack_size: Cardinal;\n  start_address: Pointer; arglist: Pointer; initflag: Cardinal;\n  var thrdaddr: Cardinal): THandle; cdecl;\n\n{ MSVC/Win64 declarations ================================================== }\nprocedure __C_specific_handler; cdecl; external 'msvcrt.dll';\n\nimplementation\n\n{ ctype.h declarations ===================================================== }\nfunction isdigit(ch: Integer): Integer; cdecl;\nbegin\n  if AnsiChar(ch) in ['0'..'9'] then\n    Result := 1\n  else\n    Result := 0;\nend;\n\n{ string.h declarations ==================================================== }\nfunction memcpy(Dest, Src: Pointer; Count: size_t): Pointer; cdecl;\nbegin\n  System.Move(Src^, Dest^, Count);\n  Result := Dest;\nend;\n{ -------------------------------------------------------------------------- }\nfunction memmove(Dest, Src: Pointer; Count: size_t): Pointer; cdecl;\nbegin\n  System.Move(Src^, Dest^, Count);\n  Result := Dest;\nend;\n{ -------------------------------------------------------------------------- }\nfunction memset(Dest: Pointer; Value: Byte; Count: size_t): Pointer; cdecl;\nbegin\n  FillChar(Dest^, Count, Value);\n  Result := Dest;\nend;\n{ -------------------------------------------------------------------------- }\nfunction strlen(P: PAnsiChar): Integer; cdecl;\n{$IF RTLVersion >= 20}\nasm\n  jmp System.@PCharLen\nend;\n{$ELSE}\nbegin\n  Result := 0;\n  while P^ <> #0 do\n    Inc(P);\nend;\n{$IFEND}\n{ -------------------------------------------------------------------------- }\nfunction strcpy(Des, Src: PAnsiChar): PAnsiChar; cdecl;\nbegin\n  Result := Des;\n  Move(Src^, Des^, strlen(Src) + 1);\nend;\n{ -------------------------------------------------------------------------- }\nfunction strncpy(Des, Src: PAnsiChar; MaxLen: Integer): PAnsiChar; cdecl;\nvar\n  Len: Integer;\nbegin\n  Len := strlen(Src);\n  if Len > MaxLen then\n    Len := MaxLen;\n  Move(Src^, Des^, Len);\n  if Len < MaxLen then\n    FillChar(Des[Len], MaxLen - Len, 0);\n  Result := Des;\nend;\n\n{ stdlib.h declarations ==================================================== }\nfunction malloc(Size: Integer): Pointer; cdecl;\nbegin\n  GetMem(Result, Size);\nend;\n{ -------------------------------------------------------------------------- }\nprocedure free(Ptr: Pointer); cdecl;\nbegin\n  FreeMem(Ptr)\nend;\n{ -------------------------------------------------------------------------- }\nfunction realloc(Ptr: Pointer; Size: Integer): Pointer; cdecl;\nbegin\n  Result := ReallocMemory(Ptr, Size);\nend;\n\n{ process.h declarations =================================================== }\nfunction _beginthreadex(security: Pointer; stack_size: Cardinal;\n  start_address: Pointer; arglist: Pointer; initflag: Cardinal;\n  var thrdaddr: Cardinal): THandle; cdecl;\nbegin\n  Result := CreateThread(security, stack_size, start_address, arglist,\n    initflag, thrdaddr);\nend;\n{ -------------------------------------------------------------------------- }\n\nend.\n"
  },
  {
    "path": "lib/abbrevia/source/AbDefine.inc",
    "content": "(* ***** BEGIN LICENSE BLOCK *****\n * Version: MPL 1.1\n *\n * The contents of this file are subject to the Mozilla Public License Version\n * 1.1 (the \"License\"); you may not use this file except in compliance with\n * the License. You may obtain a copy of the License at\n * http://www.mozilla.org/MPL/\n *\n * Software distributed under the License is distributed on an \"AS IS\" basis,\n * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License\n * for the specific language governing rights and limitations under the\n * License.\n *\n * The Original Code is TurboPower Abbrevia\n *\n * The Initial Developer of the Original Code is\n * TurboPower Software\n *\n * Portions created by the Initial Developer are Copyright (C) 1997-2002\n * the Initial Developer. All Rights Reserved.\n *\n * Contributor(s):\n *\n * ***** END LICENSE BLOCK ***** *)\n\n{*********************************************************}\n{* ABBREVIA: AbDefine.inc                                *}\n{*********************************************************}\n{* ABBREVIA: Compiler options/directives include file    *}\n{*********************************************************}\n\n{NOTE: ABDEFINE.INC is included in all ABBREVIA units; hence you can\n       specify global compiler options here. ABDEFINE.INC is included\n       *before* each unit's own required compiler options, so options\n       specified here could be overridden by hardcoded options in the\n       unit source file.}\n\n\n{====Compiler options that can be changed====}\n{$A+ Force alignment on word/dword boundaries}\n{$S- No stack checking}\n\n{---Global compiler defines for 32-bit OS's---}\n{====Global fixed compiler options (do NOT change)====}\n\n{$B- Incomplete boolean evaluation}\n{$H+ Long string support}\n{$P- No open string parameters}\n{$Q- Arithmetic overflow checking} {!! - Needs to be turned on!}\n{$R- Range checking}               {!! - Needs to be turned on!}\n{$T+ No type-checked pointers}\n{$V- No var string checking}\n{$X+ Extended syntax}\n{$Z1 Enumerations are byte sized}\n\n{====Platform defines================================================}\n\n{ map Delphi platform defines to FreePascal's (MSWINDOWS/UNIX/LINUX/DARWIN) }\n{$IFNDEF FPC}\n  {$IF DEFINED(LINUX) AND (CompilerVersion < 15)}\n    {$DEFINE KYLIX}\n    {$DEFINE UNIX}\n  {$IFEND}\n  {$IFDEF MACOS}\n    {$DEFINE DARWIN}\n  {$ENDIF}\n  {$IFDEF POSIX}\n    {$DEFINE UNIX}\n  {$ENDIF}\n{$ENDIF}\n\n{ Unix API (Kylix/Delphi/FreePascal) }\n{$IFDEF UNIX}\n  {$IF DEFINED(FPC)}\n    {$DEFINE FPCUnixAPI}\n  {$ELSEIF DEFINED(KYLIX)}\n    {$DEFINE LibcAPI}\n  {$ELSE}\n    {$DEFINE PosixAPI}\n  {$IFEND}\n{$ENDIF}\n\n{$IFDEF FPC}\n  {$MODE DELPHI}\n  {$PACKRECORDS C}\n{$ENDIF}\n\n{Activate this define to show CLX/LCL dialogs for spanning media requests.  The\n default behavior will abort the operation instead.  This define is only safe\n when using Abbrevia from the foreground thread.  If using it from a background\n thread override OnRequestLastDisk, OnRequestNthDisk, and OnRequestBlankDisk and\n synchronize to the foreground yourself.  The Windows version always MessageBox\n so it's thread-safe.}\n{.$DEFINE UnixDialogs}\n\n{====RTL defines=====================================================}\n\n{$IFNDEF FPC}\n  {$IF RTLVersion >= 18} // Delphi 2006\n    {$DEFINE HasAdvancedRecords}\n  {$IFEND}\n  {$IF RTLVersion >= 20} // Delphi 2009\n    {$DEFINE HasThreadFinished}\n    {$DEFINE HasInline}\n  {$IFEND}\n  {$IF RTLVersion >= 21} // Delphi 2010\n    {$DEFINE HasThreadStart}\n  {$IFEND}\n  {$IF RTLVersion >= 23} // Delphi XE2\n    {$DEFINE HasPlatformsAttribute}\n  {$IFEND}\n{$ENDIF}\n\n{====Widgetset defines===============================================}\n\n{ VCL version specific defines }\n{$IFNDEF FPC}\n  {$IF RTLVersion >= 17} // Delphi 2005\n    {$DEFINE HasOnMouseActivate}\n  {$IFEND}\n  {$IF RTLVersion >= 18} // Delphi 2006\n    {$DEFINE HasOnMouseEnter}\n  {$IFEND}\n  {$IF RTLVersion >= 20} // Delphi 2009\n    {$DEFINE HasListViewGroups}\n    {$DEFINE HasListViewOnItemChecked}\n    {$DEFINE HasParentDoubleBuffered}\n    {$DEFINE HasTreeViewExpandedImageIndex}\n  {$IFEND}\n  {$IF RTLVersion >= 21} // Delphi 2010\n    {$DEFINE HasGridDrawingStyle}\n    {$DEFINE HasTouch}\n  {$IFEND}\n  {$IF RTLVersion >= 24} // Delphi XE3\n    {$DEFINE HasUITypes}\n  {$IFEND}\n  {$IF RTLVersion >= 25} // Delphi XE4\n    {$DEFINE HasAnsiStrings}\n  {$IFEND}\n{$ENDIF}\n\n{====General defines=================================================}\n\n{Activate the following define to include extra code to get rid of all\n hints and warnings. Parts of ABBREVIA are written in such a way\n that the hint/warning algorithms of the Delphi compilers are\n fooled and report things like variables being used before\n initialisation and so on when in reality the problem does not exist.}\n{$DEFINE DefeatWarnings}\n\n{ Disable warnings for explicit string casts }\n{$IFDEF UNICODE}\n  {$WARN EXPLICIT_STRING_CAST OFF}\n  {$WARN EXPLICIT_STRING_CAST_LOSS OFF}\n{$ENDIF}\n\n{ Disable hints on Delphi XE2/Mac to prevent unexpanded inline messages }\n{$IFDEF POSIX}\n  {$HINTS OFF}\n{$ENDIF}\n\n{====Bzip2 defines===================================================}\n\n{Activate this define to statically link bzip2 .obj files into the application.\n Curerntly only supported by Delphi/Win32.}\n{.$DEFINE Bzip2Static}\n\n{Activate this define to dynamically link to a libbz2.dll/libbbz2.so.1}\n{.$DEFINE Bzip2Dynamic}\n\n{Activate this define to load libbz2.dll/libbz2.so.1 at runtime using LoadLibrary}\n{.$DEFINE Bzip2Runtime}\n\n{Pick an appropriate linking method if none of the above are activate}\n{$IF NOT DEFINED(Bzip2Static) AND NOT DEFINED(Bzip2Dynamic) AND NOT DEFINED(Bzip2Runtime)}\n  {$IFDEF FPC}\n    {$DEFINE Bzip2Runtime}\n  {$ELSE}\n    {$IFDEF MSWINDOWS}\n      {$DEFINE Bzip2Static}\n    {$ELSE}\n      {$DEFINE Bzip2Dynamic}\n    {$ENDIF}\n  {$ENDIF}\n{$IFEND}\n\n{====Zip defines=====================================================}\n\n{Activate the following define when you don't want Visual parts of\nthe VCL library included for a program using a TAbArchive or\nTAbZipArchive}\n{.$DEFINE BuildingStub}\n\n{Activate the following define to include support for extracting files\nusing PKzip compatible unShrink.}\n\n{.$DEFINE UnzipShrinkSupport}\n\n{Activate the following define to include support for extracting files\nusing PKZip compatible unReduce.}\n\n{.$DEFINE UnzipReduceSupport}\n\n{Activate the following define to include support for extracting files\nusing PKZip compatible unImplode.}\n\n{.$DEFINE UnzipImplodeSupport}\n\n{Activate the following to include support for extracting files using\nall older PKZip compatible methods (Shrink, Reduce, Implode}\n\n{$DEFINE UnzipBackwardSupport}\n\n{Activate the following to include support for extracting files using\nBZIP2 compression.  Added in AppNote.txt v4.6. }\n\n{.$DEFINE UnzipBzip2Support}\n\n{Activate the following to include support for extracting files using\n7-zip compatible Lzma compression.  Added in AppNote.txt v6.3.}\n\n{.$DEFINE UnzipLzmaSupport}\n\n{Activate the following to include support for extracting files using\nzipx PPMd I compression.  Added in AppNote.txt v6.3.}\n\n{.$DEFINE UnzipPPMdSupport}\n\n{Activate the following to include support for extracting .wav files\nusing zipx WavPack compression.  Requires copyright notice in your\ndocumentation.  Check \"WavPack License.txt\" for details.\nAdded in AppNote.txt v6.3.  }\n\n{.$DEFINE UnzipWavPackSupport}\n\n{Activate the following to include support for extracting files using\nall newer (zipx) compatible methods (Bzip2, Lzma, PPMd, WavPack)}\n\n{$DEFINE UnzipZipxSupport}\n\n{Activate the following to include logging support in the deflate/\n inflate code. Since this logging support is a by-product of assertion\n checking, you should only activate it if that is also on: $C+}\n{$IFOPT C+} //if Assertions are on\n{.$DEFINE UseLogging}\n{$ENDIF}\n\n{\n According to\n    http://www.gzip.org/zlib/rfc1952.txt\n\n A compliant gzip compressor should calculate and set the CRC32 and ISIZE.\n However, a compliant decompressor should not check these values.\n\n If you want to check the the values of the CRC32 and ISIZE in a GZIP file\n when decompressing enable the STRICTGZIP define below. }\n\n{.$DEFINE STRICTGZIP}\n\n{ The following define is ONLY used for Abbrevia Unit Tests.\n  It has no effect on the Abbrevia Library.\n\n  If defined it uses Winzip to create and test archives for compatability.\n  The winzip tests require Systools stSpawn.pas\n  It can be downloaded at http://sf.net/projects/tpsystools }\n\n{$IFDEF MSWINDOWS}\n  {.$DEFINE WINZIPTESTS}\n{$ENDIF}\n\n\n{-------- !! DO NOT CHANGE DEFINES BELOW THIS LINE !! --------}\n\n{$IFDEF UnzipBackwardSupport}\n  {$DEFINE UnzipShrinkSupport}\n  {$DEFINE UnzipReduceSupport}\n  {$DEFINE UnzipImplodeSupport}\n{$ENDIF}\n\n{$IFDEF UnzipZipxSupport}\n  {$DEFINE UnzipBzip2Support}\n  {$DEFINE UnzipLzmaSupport}\n  {$DEFINE UnzipPPMdSupport}\n  {$DEFINE UnzipWavPackSupport}\n{$ENDIF}\n\n{ Linking .obj files isn't currently supported in Kylix or FPC }\n{$IF DEFINED(FPC) OR NOT DEFINED(MSWINDOWS)}\n  {$UNDEF UnzipLzmaSupport}\n  {$UNDEF UnzipPPMdSupport}\n  {$UNDEF UnzipWavPackSupport}\n{$IFEND}\n\n"
  },
  {
    "path": "lib/abbrevia/source/AbDfBase.pas",
    "content": "(* ***** BEGIN LICENSE BLOCK *****\n * Version: MPL 1.1\n *\n * The contents of this file are subject to the Mozilla Public License Version\n * 1.1 (the \"License\"); you may not use this file except in compliance with\n * the License. You may obtain a copy of the License at\n * http://www.mozilla.org/MPL/\n *\n * Software distributed under the License is distributed on an \"AS IS\" basis,\n * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License\n * for the specific language governing rights and limitations under the\n * License.\n *\n * The Original Code is TurboPower Abbrevia\n *\n * The Initial Developer of the Original Code is\n * TurboPower Software\n *\n * Portions created by the Initial Developer are Copyright (C) 1997-2002\n * the Initial Developer. All Rights Reserved.\n *\n * Contributor(s):\n *\n * ***** END LICENSE BLOCK ***** *)\n\n{*********************************************************}\n{* ABBREVIA: AbDfBase.pas                                *}\n{*********************************************************}\n{* Deflate base unit                                     *}\n{*********************************************************}\n\nunit AbDfBase;\n\n{$I AbDefine.inc}\n\ninterface\n\nuses\n  SysUtils,\n  Classes;\n\ntype\n  PAbDfLongintList = ^TAbDfLongintList;\n  TAbDfLongintList =\n               array [0..pred(MaxInt div sizeof(longint))] of longint;\n\nconst\n  dfc_CodeLenCodeLength = 7;\n  dfc_LitDistCodeLength = 15;\n  dfc_MaxCodeLength     = 15;\n\nconst\n  dfc_MaxMatchLen = 258;         {lengths are 3..258 for deflate}\n  dfc_MaxMatchLen64 = 64 * 1024; {lengths are 3..65536  for deflate64}\n\nconst\n  dfc_LitExtraOffset = 257;\n  dfc_LitExtraBits : array [0..30] of byte =\n    (0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3,\n     4, 4, 4, 4, 5, 5, 5, 5, 16, 99, 99);\n     { note: the last two are required to avoid going beyond the end}\n     {       of the array when generating static trees}\n\n  dfc_DistExtraOffset = 0;\n  dfc_DistExtraBits : array [0..31] of byte =\n    (0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9,\n     10, 10, 11, 11, 12, 12, 13, 13, 14, 14);\n     { note: the last two are only use for deflate64}\n\n  dfc_LengthBase : array [0..28] of word =\n    (3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31, 35, 43,\n     51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 3);\n     { note: the final 3 is correct for deflate64; for symbol 285,}\n     {       lengths are stored as (length - 3)}\n     {       for deflate it's very wrong, but there's special code in}\n     {       the (de)compression code to cater for this}\n\n  dfc_DistanceBase : array [0..31] of word =\n    (1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, 257,\n     385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145, 8193, 12289,\n     16385, 24577, 32769, 49153);\n\n  dfc_CodeLengthIndex : array [0..18] of byte =\n    (16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15);\n\nconst\n  dfc_CanUseStored  = $01;\n  dfc_CanUseStatic  = $02;\n  dfc_CanUseDynamic = $04;\n  dfc_UseLazyMatch  = $08;\n  dfc_UseDeflate64  = $10;\n  dfc_UseAdler32    = $20;\n  dfc_CanUseHuffman = dfc_CanUseStatic or dfc_CanUseDynamic;\n  dfc_TestOnly      = $40000000;\n\ntype\n  TAbProgressStep = procedure (aPercentDone : integer) of object;\n    {-progress metering of deflate/inflate; abort with AbortProgress}\n\n  TAbDeflateHelper = class\n    private\n      FAmpleLength    : longint;\n      FChainLength    : longint;\n      FLogFile        : string;\n      FMaxLazy        : longint;\n      FOnProgressStep : TAbProgressStep;\n      FOptions        : longint;\n      FPartSize       : Int64;\n      FSizeCompressed : Int64;\n      FSizeNormal     : Int64;\n      FStreamSize     : Int64;\n      FWindowSize     : longint;\n      FZipOption      : AnsiChar;\n    protected\n      procedure dhSetAmpleLength(aValue : longint);\n      procedure dhSetChainLength(aValue : longint);\n      procedure dhSetLogFile(const aValue : string);\n      procedure dhSetMaxLazy(aValue : longint);\n      procedure dhSetOnProgressStep(aValue : TAbProgressStep);\n      procedure dhSetOptions(aValue : longint);\n      procedure dhSetWindowSize(aValue : longint);\n      procedure dhSetZipOption(aValue : AnsiChar);\n    public\n      constructor Create;\n\n      procedure Assign(aHelper : TAbDeflateHelper);\n\n      property AmpleLength : longint\n                  read FAmpleLength write dhSetAmpleLength;\n      property ChainLength : longint\n                  read FChainLength write dhSetChainLength;\n      property LogFile : string\n                  read FLogFile write dhSetLogFile;\n      property MaxLazyLength : longint\n                  read FMaxLazy write dhSetMaxLazy;\n      property Options : longint\n                  read FOptions write dhSetOptions;\n      property PartialSize : Int64\n                  read FPartSize write FPartSize;\n      property PKZipOption : AnsiChar\n                  read FZipOption write dhSetZipOption;\n      property StreamSize : Int64\n                  read FStreamSize write FStreamSize;\n      property WindowSize : longint\n                  read FWindowSize write dhSetWindowSize;\n\n      property CompressedSize : Int64\n                  read FSizeCompressed write FSizeCompressed;\n      property NormalSize : Int64\n                  read FSizeNormal write FSizeNormal;\n\n      property OnProgressStep : TAbProgressStep\n                  read FOnProgressStep write dhSetOnProgressStep;\n  end;\n\ntype\n  TAbLineDelimiter = (ldCRLF, ldLF);\n\n  TAbLogger = class(TStream)\n    private\n      FBuffer    : PAnsiChar;\n      FCurPos    : PAnsiChar;\n      FLineDelim : TAbLineDelimiter;\n      FStream    : TFileStream;\n    protected\n      function logWriteBuffer : boolean;\n    public\n      constructor Create(const aLogName : string);\n      destructor Destroy; override;\n\n      function Read(var Buffer; Count : longint) : longint; override;\n      function Seek(const Offset : Int64; Origin : TSeekOrigin) : Int64; override;\n      function Write(const Buffer; Count : longint) : longint; override;\n      procedure WriteLine(const S : string);\n      procedure WriteStr(const S : string);\n\n      property LineDelimiter : TAbLineDelimiter\n                  read FLineDelim write FLineDelim;\n  end;\n\ntype\n  TAbNodeManager = class\n    private\n      FFreeList     : pointer;\n      FNodeSize     : cardinal;\n      FNodesPerPage : cardinal;\n      FPageHead     : pointer;\n      FPageSize     : cardinal;\n    protected\n      function nmAllocNewPage : pointer;\n    public\n      constructor Create(aNodeSize : cardinal);\n      destructor Destroy; override;\n\n      function AllocNode : pointer;\n      function AllocNodeClear : pointer;\n      procedure FreeNode(aNode : pointer);\n  end;\n\n{---exception classes---}\ntype\n  EAbAbortProgress = class(Exception);\n  EAbPartSizedInflate = class(Exception);\n  EAbInflatePasswordError = class(Exception);\n  EAbInternalInflateError = class(Exception);\n  EAbInflateError = class(Exception)\n    public\n      constructor Create(const aMsg : string);\n      constructor CreateUnknown(const aMsg : string;\n                                const aErrorMsg : string);\n  end;\n  EAbInternalDeflateError = class(Exception);\n  EAbDeflateError = class(Exception)\n    public\n      constructor Create(const aMsg : string);\n      constructor CreateUnknown(const aMsg : string;\n                                const aErrorMsg : string);\n  end;\n\n{---aborting a process---}\nprocedure AbortProgress;\n\n{---calculation of checksums---}\nprocedure AbUpdateAdlerBuffer(var aAdler : longint;\n                              var aBuffer; aCount : integer);\nprocedure AbUpdateCRCBuffer(var aCRC : longint;\n                            var aBuffer; aCount : integer);\n\n\nimplementation\n\nuses\n  AbUtils;\n\n{===TAbDeflateHelper=================================================}\nconstructor TAbDeflateHelper.Create;\nbegin\n  inherited Create;\n  FAmpleLength := 8;\n  FChainLength := 32;\n  {FLogFile := '';}\n  FMaxLazy := 16;\n  {FOnProgressStep := nil;}\n  FOptions := $F;\n  {FStreamSize := 0;}\n  FWindowSize := 32 * 1024;\n  FZipOption := 'n';\nend;\n{--------}\nprocedure TAbDeflateHelper.Assign(aHelper : TAbDeflateHelper);\nbegin\n  FAmpleLength := aHelper.FAmpleLength;\n  FChainLength := aHelper.FChainLength;\n  FLogFile := aHelper.FLogFile;\n  FMaxLazy := aHelper.FMaxLazy;\n  FOnProgressStep := aHelper.FOnProgressStep;\n  FOptions := aHelper.FOptions;\n  FPartSize := aHelper.FPartSize;\n  FStreamSize := aHelper.FStreamSize;\n  FWindowSize := aHelper.FWindowSize;\n  FZipOption := aHelper.FZipOption;\nend;\n{--------}\nprocedure TAbDeflateHelper.dhSetAmpleLength(aValue : longint);\nbegin\n  if (aValue <> AmpleLength) then begin\n    if (aValue <> -1) and (aValue < 4) then\n      aValue := 4;\n    FAmpleLength := aValue;\n    FZipOption := '?';\n  end;\nend;\n{--------}\nprocedure TAbDeflateHelper.dhSetChainLength(aValue : longint);\nbegin\n  if (aValue <> ChainLength) then begin\n    if (aValue <> -1) and (aValue < 4) then\n      aValue := 4;\n    FChainLength := aValue;\n    FZipOption := '?';\n  end;\nend;\n{--------}\nprocedure TAbDeflateHelper.dhSetLogFile(const aValue : string);\nbegin\n  FLogFile := aValue;\nend;\n{--------}\nprocedure TAbDeflateHelper.dhSetMaxLazy(aValue : longint);\nbegin\n  if (aValue <> MaxLazyLength) then begin\n    if (aValue <> -1) and (aValue < 4) then\n      aValue := 4;\n    FMaxLazy := aValue;\n    FZipOption := '?';\n  end;\nend;\n{--------}\nprocedure TAbDeflateHelper.dhSetOnProgressStep(aValue : TAbProgressStep);\nbegin\n  FOnProgressStep := aValue;\nend;\n{--------}\nprocedure TAbDeflateHelper.dhSetOptions(aValue : longint);\nbegin\n  if (aValue <> Options) then begin\n    FOptions := aValue;\n    FZipOption := '?';\n  end;\nend;\n{--------}\nprocedure TAbDeflateHelper.dhSetWindowSize(aValue : longint);\nvar\n  NewValue : longint;\nbegin\n  if (aValue <> WindowSize) then begin\n    {calculate the window size rounded to nearest 1024 bytes}\n    NewValue := ((aValue + 1023) div 1024) * 1024;\n    {if the new window size is greater than 32KB...}\n    if (NewValue > 32 * 1024) then\n      {if the Deflate64 option is set, force to 64KB}\n      if ((Options and dfc_UseDeflate64) <> 0) then\n        NewValue := 64 * 1024\n      {otherwise, force to 32KB}\n      else\n        NewValue := 32 * 1024;\n    {set the new window size}\n    FWindowSize := NewValue;\n  end;\nend;\n{--------}\nprocedure TAbDeflateHelper.dhSetZipOption(aValue : AnsiChar);\nbegin\n  {notes:\n     The original Abbrevia code used the following table for\n     setting the equivalent values:\n            Good  Lazy  Chain  UseLazy  Option\n               4     4      4     N       s        ^\n               4     5      8     N                |\n               4     6     32     N       f      faster\n               4     4     16     Y              slower\n               8    16     32     Y       n        |\n               8    16    128     Y                |\n               8    32    256     Y                |\n              32   128   1024     Y                |\n              32   258   4096     Y       x        V\n     The new Abbrevia 3 code follows these values to a certain extent.\n  }\n\n  {force to lower case}\n  if ('A' <= aValue) and (aValue <= 'Z') then\n    aValue := AnsiChar(ord(aValue) + ord('a') - ord('A'));\n\n  {if the value has changed...}\n  if (aValue <> PKZipOption) then begin\n\n    {switch on the new value...}\n    case aValue of\n      '0' : {no compression}\n        begin\n          FZipOption := aValue;\n          FOptions := (FOptions and (not $0F)) or dfc_CanUseStored;\n          FAmpleLength := 8;  { not actually needed}\n          FChainLength := 32; { not actually needed}\n          FMaxLazy := 16;     { not actually needed}\n        end;\n      '2' : {hidden option: Abbrevia 2 compatibility}\n        begin\n          FZipOption := aValue;\n          FOptions := FOptions or $0F;\n          FAmpleLength := 8;\n          FChainLength := 32;\n          FMaxLazy := 16;\n        end;\n      'f' : {fast compression}\n        begin\n          FZipOption := aValue;\n          FOptions := FOptions or $07; { no lazy matching}\n          FAmpleLength := 4;\n          FChainLength := 32;\n          FMaxLazy := 6;\n        end;\n      'n' : {normal compression}\n        begin\n          FZipOption := aValue;\n          FOptions := FOptions or $0F;\n          FAmpleLength := 16;\n          FChainLength := 32;\n          FMaxLazy := 24;\n        end;\n      's' : {super fast compression}\n        begin\n          FZipOption := aValue;\n          FOptions := FOptions or $07; { no lazy matching}\n          FAmpleLength := 4;\n          FChainLength := 4;\n          FMaxLazy := 4;\n        end;\n      'x' : {maximum compression}\n        begin\n          FZipOption := aValue;\n          FOptions := FOptions or $0F;\n          FAmpleLength := 64;{32;}\n          FChainLength := 4096;\n          FMaxLazy := 258;\n        end;\n    end;\n  end;\nend;\n{====================================================================}\n\n\n{===TAbLogger========================================================}\nconst\n  LogBufferSize = 4096;\n{--------}\nconstructor TAbLogger.Create(const aLogName : string);\nbegin\n  Assert(aLogName <> '',\n         'TAbLogger.Create: a filename must be provided for the logger');\n\n  {create the ancestor}\n  inherited Create;\n\n  {set the default line terminator}\n  {$IFDEF MSWINDOWS}\n  FLineDelim := ldCRLF;\n  {$ENDIF}\n  {$IFDEF UNIX}\n  FLineDelim := ldLF;\n  {$ENDIF}\n\n  {create and initialize the buffer}\n  GetMem(FBuffer, LogBufferSize);\n  FCurPos := FBuffer;\n\n  {create the log file}\n  FStream := TFileStream.Create(aLogName, fmCreate);\nend;\n{--------}\ndestructor TAbLogger.Destroy;\nbegin\n  {if there is a buffer ensure that it is flushed before freeing it}\n  if (FBuffer <> nil) then begin\n    if (FCurPos <> FBuffer) then\n      logWriteBuffer;\n    FreeMem(FBuffer, LogBufferSize);\n  end;\n\n  {free the stream}\n  FStream.Free;\n\n  {destroy the ancestor}\n  inherited Destroy;\nend;\n{--------}\nfunction TAbLogger.logWriteBuffer : boolean;\nvar\n  BytesToWrite : longint;\n  BytesWritten : longint;\nbegin\n  BytesToWrite := FCurPos - FBuffer;\n  BytesWritten := FStream.Write(FBuffer^, BytesToWrite);\n  if (BytesWritten = BytesToWrite) then begin\n    Result := true;\n    FCurPos := FBuffer;\n  end\n  else begin\n    Result := false;\n    if (BytesWritten <> 0) then begin\n      Move(FBuffer[BytesWritten], FBuffer^, BytesToWrite - BytesWritten);\n      FCurPos := FBuffer + (BytesToWrite - BytesWritten);\n    end;\n  end;\nend;\n{--------}\nfunction TAbLogger.Read(var Buffer; Count : longint) : longint;\nbegin\n  Assert(false, 'TAbLogger.Read: loggers are write-only, no reading allowed');\n  Result := 0;\nend;\n{--------}\nfunction TAbLogger.Seek(const Offset : Int64; Origin : TSeekOrigin) : Int64;\nbegin\n  case Origin of\n    soBeginning :\n      begin\n      end;\n    soCurrent :\n      if (Offset = 0) then begin\n        Result := FStream.Position + (FCurPos - FBuffer);\n        Exit;\n      end;\n    soEnd :\n      if (Offset = 0) then begin\n        Result := FStream.Position + (FCurPos - FBuffer);\n        Exit;\n      end;\n  end;\n\n  Assert(false, 'TAbLogger.Seek: loggers are write-only, no seeking allowed');\n  Result := 0;\nend;\n{--------}\nfunction TAbLogger.Write(const Buffer; Count : longint) : longint;\nvar\n  UserBuf      : PAnsiChar;\n  BytesToGo    : longint;\n  BytesToWrite : longint;\nbegin\n  {reference the user's buffer as a PChar}\n  UserBuf := @Buffer;\n\n  {start the counter for the number of bytes written}\n  Result := 0;\n\n  {if needed, empty the internal buffer into the underlying stream}\n  if (LogBufferSize = FCurPos - FBuffer) then\n    if not logWriteBuffer then\n      Exit;\n\n  {calculate the number of bytes to copy this time from the user's\n   buffer to the internal buffer}\n  BytesToGo := Count;\n  BytesToWrite := LogBufferSize - (FCurPos - FBuffer);\n  if (BytesToWrite > BytesToGo) then\n    BytesToWrite := BytesToGo;\n\n  {copy the bytes}\n  Move(UserBuf^, FCurPos^, BytesToWrite);\n\n  {adjust the counters}\n  inc(FCurPos, BytesToWrite);\n  dec(BytesToGo, BytesToWrite);\n  inc(Result, BytesToWrite);\n\n  {while there are still more bytes to copy, do so}\n  while (BytesToGo <> 0) do begin\n    {advance the user's buffer}\n    inc(UserBuf, BytesToWrite);\n\n    {empty the internal buffer into the underlying stream}\n    if not logWriteBuffer then\n      Exit;\n\n    {calculate the number of bytes to copy this time from the user's\n     buffer to the internal buffer}\n    BytesToWrite := LogBufferSize;\n    if (BytesToWrite > BytesToGo) then\n      BytesToWrite := BytesToGo;\n\n    {copy the bytes}\n    Move(UserBuf^, FCurPos^, BytesToWrite);\n\n    {adjust the counters}\n    inc(FCurPos, BytesToWrite);\n    dec(BytesToGo, BytesToWrite);\n    inc(Result, BytesToWrite);\n  end;\nend;\n{--------}\nprocedure TAbLogger.WriteLine(const S : string);\nconst\n  cLF : AnsiChar = ^J;\n  cCRLF : array [0..1] of AnsiChar = ^M^J;\nbegin\n  if (length(S) > 0) then\n    Write(S[1], length(S));\n  case FLineDelim of\n    ldLF   : Write(cLF, sizeof(cLF));\n    ldCRLF : Write(cCRLF, sizeof(cCRLF));\n  end;\nend;\n{--------}\nprocedure TAbLogger.WriteStr(const S : string);\nbegin\n  if (length(S) > 0) then\n    Write(S[1], length(S));\nend;\n{====================================================================}\n\n\n{===Calculate checksums==============================================}\nprocedure AbUpdateAdlerBuffer(var aAdler : longint;\n                              var aBuffer; aCount : integer);\nvar\n  S1 : LongWord;\n  S2 : LongWord;\n  i  : integer;\n  Buffer     : PAnsiChar;\n  BytesToUse : integer;\nbegin\n  {Note: this algorithm will *only* work if the buffer is 4KB or less,\n         which is why we go to such lengths to chop up the user buffer\n         into usable chunks of 4KB.\n\n         However, for Delphi 3 there is no proper 32-bit longword.\n         Although the additions pose no problems in this situation,\n         the mod operations below (especially for S2) will be signed\n         integer divisions, producing an (invalid) signed result. In\n         this case, the buffer is chopped up into 2KB chunks to avoid\n         any signed problems.}\n\n  {split the current Adler checksum into its halves}\n  S1 := LongWord(aAdler) and $FFFF;\n  S2 := LongWord(aAdler) shr 16;\n\n  {reference the user buffer as a PChar: it makes it easier}\n  Buffer := @aBuffer;\n\n  {while there's still data to checksum...}\n  while (aCount <> 0) do begin\n\n    {calculate the number of bytes to checksum this time}\n    {$IFDEF HasLongWord}\n    BytesToUse := 4096;\n    {$ELSE}\n    BytesToUse := 2048;\n    {$ENDIF}\n    if (BytesToUse > aCount) then\n      BytesToUse := aCount;\n\n    {checksum the bytes}\n    for i := 0 to pred(BytesToUse) do begin\n      inc(S1, ord(Buffer^));\n      inc(S2, S1);\n      inc(Buffer);\n    end;\n\n    {recalibrate the Adler checksum halves}\n    S1 := S1 mod 65521;\n    S2 := S2 mod 65521;\n\n    {calculate the number of bytes still to go}\n    dec(aCount, BytesToUse);\n  end;\n\n  {join the halves to produce the complete Adler checksum}\n  aAdler := longint((S2 shl 16) or S1);\nend;\n{--------}\nprocedure AbUpdateCRCBuffer(var aCRC : longint;\n                            var aBuffer; aCount : integer);\nvar\n  i      : integer;\n  CRC    : LongWord;\n  Buffer : PAnsiChar;\nbegin\n{$R-}{$Q-}\n  {reference the user buffer as a PChar: it makes it easier}\n  Buffer := @aBuffer;\n\n  {get the current CRC as a local variable, it's faster}\n  CRC := aCRC;\n\n  {checksum the bytes in the buffer}\n  for i := 0 to pred(aCount) do begin\n    CRC := AbCrc32Table[byte(CRC) xor byte(Buffer^)] xor (CRC shr 8);\n    inc(Buffer);\n  end;\n\n  {return the new CRC}\n  aCRC := CRC;\n{$R+}{$Q+}\nend;\n{====================================================================}\n\n\n{===EAbInflateError==================================================}\nconstructor EAbInflateError.Create(const aMsg : string);\nbegin\n  inherited Create(\n     'Abbrevia inflate error, possibly a corrupted compressed stream. ' +\n     '(Internal cause: ' + aMsg + ')');\nend;\n{--------}\nconstructor EAbInflateError.CreateUnknown(const aMsg : string;\n                                          const aErrorMsg : string);\nbegin\n  inherited Create(aMsg + ': ' + aErrorMsg);\nend;\n{====================================================================}\n\n\n{===EAbDeflateError==================================================}\nconstructor EAbDeflateError.Create(const aMsg : string);\nbegin\n  inherited Create(\n     'Abbrevia deflate error. ' +\n     '(Internal cause: ' + aMsg + ')');\nend;\n{--------}\nconstructor EAbDeflateError.CreateUnknown(const aMsg : string;\n                                          const aErrorMsg : string);\nbegin\n  inherited Create(aMsg + ': ' + aErrorMsg);\nend;\n{====================================================================}\n\n\n{===Node manager=====================================================}\nconst\n  PageSize = 8 * 1024;\ntype\n  PGenericNode = ^TGenericNode;\n  TGenericNode = packed record\n    gnNext : PGenericNode;\n    gnData : record end;\n  end;\n{--------}\nconstructor TAbNodeManager.Create(aNodeSize : cardinal);\nconst\n  Gran = sizeof(pointer);\n  Mask = not (Gran - 1);\nbegin\n  {create the ancestor}\n  inherited Create;\n\n  {save the node size rounded to nearest 4 bytes}\n  if (aNodeSize <= sizeof(pointer)) then\n    aNodeSize := sizeof(pointer)\n  else\n    aNodeSize := (aNodeSize + Gran - 1) and Mask;\n  FNodeSize := aNodeSize;\n\n  {calculate the page size (default 1024 bytes) and the number of\n   nodes per page; if the default page size is not large enough for\n   two or more nodes, force a single node per page}\n  FNodesPerPage := (PageSize - sizeof(pointer)) div aNodeSize;\n  if (FNodesPerPage > 1) then\n    FPageSize := PageSize\n  else begin\n    FNodesPerPage := 1;\n    FPagesize := aNodeSize + sizeof(pointer);\n  end;\nend;\n{--------}\ndestructor TAbNodeManager.Destroy;\nvar\n  Temp : pointer;\nbegin\n  {dispose of all the pages, if there are any}\n  while (FPageHead <> nil) do begin\n    Temp := PGenericNode(FPageHead)^.gnNext;\n    FreeMem(FPageHead, FPageSize);\n    FPageHead := Temp;\n  end;\n\n  {destroy the ancestor}\n  inherited Destroy;\nend;\n{--------}\nfunction TAbNodeManager.AllocNode : pointer;\nbegin\n  Result := FFreeList;\n  if (Result = nil) then\n    Result := nmAllocNewPage\n  else\n    FFreeList := PGenericNode(Result)^.gnNext;\nend;\n{--------}\nfunction TAbNodeManager.AllocNodeClear : pointer;\nbegin\n  Result := FFreeList;\n  if (Result = nil) then\n    Result := nmAllocNewPage\n  else\n    FFreeList := PGenericNode(Result)^.gnNext;\n  FillChar(Result^, FNodeSize, 0);\nend;\n{--------}\nprocedure TAbNodeManager.FreeNode(aNode : pointer);\nbegin\n  {add the node (if non-nil) to the top of the free list}\n  if (aNode <> nil) then begin\n    PGenericNode(aNode)^.gnNext := FFreeList;\n    FFreeList := aNode;\n  end;\nend;\n{--------}\nfunction TAbNodeManager.nmAllocNewPage : pointer;\nvar\n  NewPage  : PAnsiChar;\n  i        : integer;\n  FreeList : pointer;\n  NodeSize : integer;\nbegin\n  {allocate a new page and add it to the front of the page list}\n  GetMem(NewPage, FPageSize);\n  PGenericNode(NewPage)^.gnNext := FPageHead;\n  FPageHead := NewPage;\n\n  {now split up the new page into nodes and push them all onto the\n   free list; note that the first 4 bytes of the page is a pointer to\n   the next page, so remember to skip over it}\n  inc(NewPage, sizeof(pointer));\n  FreeList := FFreeList;\n  NodeSize := FNodeSize;\n  for i := 0 to pred(FNodesPerPage) do begin\n    PGenericNode(NewPage)^.gnNext := FreeList;\n    FreeList := NewPage;\n    inc(NewPage, NodeSize);\n  end;\n\n  {return the top of the list}\n  Result := FreeList;\n  FFreeList := PGenericNode(Result)^.gnNext;\nend;\n{====================================================================}\n\n\n{====================================================================}\nprocedure AbortProgress;\nbegin\n  raise EAbAbortProgress.Create('Abort');\nend;\n{====================================================================}\n\nend.\n"
  },
  {
    "path": "lib/abbrevia/source/AbDfCryS.pas",
    "content": "(* ***** BEGIN LICENSE BLOCK *****\n * Version: MPL 1.1\n *\n * The contents of this file are subject to the Mozilla Public License Version\n * 1.1 (the \"License\"); you may not use this file except in compliance with\n * the License. You may obtain a copy of the License at\n * http://www.mozilla.org/MPL/\n *\n * Software distributed under the License is distributed on an \"AS IS\" basis,\n * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License\n * for the specific language governing rights and limitations under the\n * License.\n *\n * The Original Code is TurboPower Abbrevia\n *\n * The Initial Developer of the Original Code is\n * TurboPower Software\n *\n * Portions created by the Initial Developer are Copyright (C) 1997-2002\n * the Initial Developer. All Rights Reserved.\n *\n * Contributor(s):\n *\n * ***** END LICENSE BLOCK ***** *)\n\n{*********************************************************}\n{* ABBREVIA: AbDfCryS.pas                                *}\n{*********************************************************}\n{* Deflate encryption streams                            *}\n{*********************************************************}\n\nunit AbDfCryS;\n\n{$I AbDefine.inc}\n\ninterface\n\nuses\n  Classes;\n\ntype\n  TAbZipEncryptHeader = array [0..11] of byte;\n\n  TAbZipDecryptEngine = class\n    private\n      FReady : boolean;\n      FState : array [0..2] of longint;\n    protected\n      procedure zdeInitState(const aPassphrase : AnsiString);\n    public\n      constructor Create;\n\n      function Decode(aCh : byte) : byte;\n        {-decodes a byte}\n      procedure DecodeBuffer(var aBuffer; aCount : integer);\n        {-decodes a buffer}\n\n      function VerifyHeader(const aHeader     : TAbZipEncryptHeader;\n                            const aPassphrase : AnsiString;\n                                  aCheckValue : longint) : boolean;\n        {-validate an encryption header}\n    end;\n\n  TAbDfDecryptStream = class(TStream)\n    private\n      FCheckValue : longint;\n      FEngine     : TAbZipDecryptEngine;\n      FOwnsStream : Boolean;\n      FPassphrase : AnsiString;\n      FReady      : boolean;\n      FStream     : TStream;\n    protected\n    public\n      constructor Create(aStream     : TStream;\n                         aCheckValue : longint;\n                   const aPassphrase : AnsiString);\n      destructor Destroy; override;\n\n      function IsValid : boolean;\n\n      function Read(var aBuffer; aCount : longint) : longint; override;\n      function Seek(aOffset : longint; aOrigin : word) : longint; override;\n      function Write(const aBuffer; aCount : longint) : longint; override;\n\n      property OwnsStream : Boolean\n        read FOwnsStream\n        write FOwnsStream;\n  end;\n\n  TAbZipEncryptEngine = class\n    private\n      FReady : boolean;\n      FState : array [0..2] of longint;\n    protected\n      procedure zeeInitState(const aPassphrase : AnsiString);\n    public\n      constructor Create;\n\n      function Encode(aCh : byte) : byte;\n        {-encodes a byte}\n      procedure EncodeBuffer(var aBuffer; aCount : integer);\n        {-encodes a buffer}\n\n      procedure CreateHeader(var aHeader     : TAbZipEncryptHeader;\n                           const aPassphrase : AnsiString;\n                                 aCheckValue : longint);\n        {-generate an encryption header}\n    end;\n\n  TAbDfEncryptStream = class(TStream)\n    private\n      FBuffer  : PAnsiChar;\n      FBufSize : integer;\n      FEngine  : TAbZipEncryptEngine;\n      FStream  : TStream;\n    protected\n    public\n      constructor Create(aStream     : TStream;\n                         aCheckValue : longint;\n                   const aPassphrase : AnsiString);\n      destructor Destroy; override;\n\n      function Read(var aBuffer; aCount : longint) : longint; override;\n      function Seek(aOffset : longint; aOrigin : word) : longint; override;\n      function Write(const aBuffer; aCount : longint) : longint; override;\n  end;\n\nimplementation\n\n{Notes: the ZIP spec defines a couple of primitive routines for\n        performing encryption. For speed Abbrevia inlines them into\n        the respective methods of the encryption/decryption engines\n\n        char crc32(long,char)\n          return updated CRC from current CRC and next char\n\n        update_keys(char):\n          Key(0) <- crc32(key(0),char)\n          Key(1) <- Key(1) + (Key(0) & 000000ffH)\n          Key(1) <- Key(1) * 134775813 + 1\n          Key(2) <- crc32(key(2),key(1) >> 24)\n        end update_keys\n\n        char decrypt_byte()\n          local unsigned short temp\n          temp <- Key(2) | 2\n          decrypt_byte <- (temp * (temp ^ 1)) >> 8\n        end decrypt_byte\n}\n\nuses\n  AbUtils;\n\n{---magic numbers from ZIP spec---}\nconst\n  StateInit1 = 305419896;\n  StateInit2 = 591751049;\n  StateInit3 = 878082192;\n  MagicNumber = 134775813;\n\n{===internal encryption class========================================}\nconstructor TAbZipDecryptEngine.Create;\nbegin\n  {create the ancestor}\n  inherited Create;\n\n  {we're not ready for decryption yet since a header hasn't been\n   properly verified with VerifyHeader}\n  FReady := false;\nend;\n{--------}\nfunction TAbZipDecryptEngine.Decode(aCh : byte) : byte;\nvar\n  Temp : longint;\nbegin\n  {check for programming error}\n  Assert(FReady,\n         'TAbZipDecryptEngine.Decode: must successfully call VerifyHeader first');\n\n  {calculate the decoded byte (uses inlined decrypt_byte)}\n  Temp := (FState[2] and $FFFF) or 2;\n  Result := aCh xor ((Temp * (Temp xor 1)) shr 8);\n\n  {mix the decoded byte into the state (uses inlined update_keys)}\n  FState[0] := AbUpdateCrc32(Result, FState[0]);\n  FState[1] := FState[1] + (FState[0] and $FF);\n  FState[1] := (FState[1] * MagicNumber) + 1;\n  FState[2] := AbUpdateCrc32(FState[1] shr 24, FState[2]);\nend;\n{--------}\nprocedure TAbZipDecryptEngine.DecodeBuffer(var aBuffer; aCount : integer);\nvar\n  i      : integer;\n  Temp   : longint;\n  Buffer : PAnsiChar;\n  WorkState : array [0..2] of longint;\nbegin\n  {check for programming error}\n  Assert(FReady,\n         'TAbZipDecryptEngine.Decode: must successfully call VerifyHeader first');\n\n  {move the state to a local variable--for better speed}\n  WorkState[0] := FState[0];\n  WorkState[1] := FState[1];\n  WorkState[2] := FState[2];\n\n  {reference the buffer as a PChar--easier arithmetic}\n  Buffer := @aBuffer;\n\n  {for each byte in the buffer...}\n  for i := 0 to pred(aCount) do begin\n\n    {calculate the next decoded byte (uses inlined decrypt_byte)}\n    Temp := (WorkState[2] and $FFFF) or 2;\n    Buffer^ := AnsiChar(\n                  byte(Buffer^) xor ((Temp * (Temp xor 1)) shr 8));\n\n    {mix the decoded byte into the state (uses inlined update_keys)}\n    WorkState[0] := AbUpdateCrc32(byte(Buffer^), WorkState[0]);\n    WorkState[1] := WorkState[1] + (WorkState[0] and $FF);\n    WorkState[1] := (WorkState[1] * MagicNumber) + 1;\n    WorkState[2] := AbUpdateCrc32(WorkState[1] shr 24, WorkState[2]);\n\n    {move onto the next byte}\n    inc(Buffer);\n  end;\n\n  {save the state}\n  FState[0] := WorkState[0];\n  FState[1] := WorkState[1];\n  FState[2] := WorkState[2];\nend;\n{--------}\nfunction TAbZipDecryptEngine.VerifyHeader(const aHeader     : TAbZipEncryptHeader;\n                                          const aPassphrase : AnsiString;\n                                                aCheckValue : longint) : boolean;\ntype\n  TLongAsBytes = packed record\n    L1, L2, L3, L4 : byte\n  end;\nvar\n  i    : integer;\n  Temp : longint;\n  WorkHeader : TAbZipEncryptHeader;\nbegin\n  {check for programming errors}\n  Assert(aPassphrase <> '',\n         'TAbZipDecryptEngine.VerifyHeader: need a passphrase');\n\n  {initialize the decryption state}\n  zdeInitState(aPassphrase);\n\n  {decrypt the bytes in the header}\n  for i := 0 to 11 do begin\n\n    {calculate the next decoded byte (uses inlined decrypt_byte)}\n    Temp := (FState[2] and $FFFF) or 2;\n    WorkHeader[i] := aHeader[i] xor ((Temp * (Temp xor 1)) shr 8);\n\n    {mix the decoded byte into the state (uses inlined update_keys)}\n    FState[0] := AbUpdateCrc32(WorkHeader[i], FState[0]);\n    FState[1] := FState[1] + (FState[0] and $FF);\n    FState[1] := (FState[1] * MagicNumber) + 1;\n    FState[2] := AbUpdateCrc32(FState[1] shr 24, FState[2]);\n  end;\n\n  {the header is valid if the twelfth byte of the decrypted header\n   equals the fourth byte of the check value}\n  Result := WorkHeader[11] = TLongAsBytes(aCheckValue).L4;\n\n  {note: zips created with PKZIP prior to version 2.0 also checked\n         that the tenth byte of the decrypted header equals the third\n         byte of the check value}\n  FReady := Result;\nend;\n{--------}\nprocedure TAbZipDecryptEngine.zdeInitState(const aPassphrase : AnsiString);\nvar\n  i : integer;\nbegin\n  {initialize the decryption state}\n  FState[0] := StateInit1;\n  FState[1] := StateInit2;\n  FState[2] := StateInit3;\n\n  {mix in the passphrase to the state (uses inlined update_keys)}\n  for i := 1 to length(aPassphrase) do begin\n    FState[0] := AbUpdateCrc32(byte(aPassphrase[i]), FState[0]);\n    FState[1] := FState[1] + (FState[0] and $FF);\n    FState[1] := (FState[1] * MagicNumber) + 1;\n    FState[2] := AbUpdateCrc32(FState[1] shr 24, FState[2]);\n  end;\nend;\n{====================================================================}\n\n\n{====================================================================}\nconstructor TAbDfDecryptStream.Create(aStream     : TStream;\n                                      aCheckValue : longint;\n                                const aPassphrase : AnsiString);\nbegin\n  {create the ancestor}\n  inherited Create;\n\n  {save the parameters}\n  FStream := aStream;\n  FCheckValue := aCheckValue;\n  FPassphrase := aPassphrase;\n\n  {create the decryption engine}\n  FEngine := TAbZipDecryptEngine.Create;\nend;\n{--------}\ndestructor TAbDfDecryptStream.Destroy;                     {new !!.02}\nbegin\n  FEngine.Free;\n  if FOwnsStream then\n    FStream.Free;\n  inherited Destroy;\nend;\n{--------}\nfunction TAbDfDecryptStream.IsValid : boolean;\nvar\n  Header : TAbZipEncryptHeader;\nbegin\n  {read the header from the stream}\n  FStream.ReadBuffer(Header, sizeof(Header));\n\n  {check to see if the decryption engine agrees it's valid}\n  Result := FEngine.VerifyHeader(Header, FPassphrase, FCheckValue);\n\n  {if it isn't valid, reposition the stream, ready for the next try}\n  if not Result then begin\n    FStream.Seek(-sizeof(Header), soCurrent);\n    FReady := false;\n  end\n\n  {otherwise, the stream is ready for decrypting data}\n  else\n    FReady := true;\nend;\n{--------}\nfunction TAbDfDecryptStream.Read(var aBuffer; aCount : longint) : longint;\nbegin\n  {check for programming error}\n  Assert(FReady,\n         'TAbDfDecryptStream.Read: the stream header has not been verified');\n\n  {read the data from the underlying stream}\n  Result := FStream.Read(aBuffer, aCount);\n\n  {decrypt the data}\n  FEngine.DecodeBuffer(aBuffer, Result);\nend;\n{--------}\nfunction TAbDfDecryptStream.Seek(aOffset : longint; aOrigin : word) : longint;\nbegin\n  Result := FStream.Seek(aOffset, aOrigin);\nend;\n{--------}\nfunction TAbDfDecryptStream.Write(const aBuffer; aCount : longint) : longint;\nbegin\n  {check for programming error}\n  Assert(false,\n         'TAbDfDecryptStream.Write: the stream is read-only');\n  Result := 0;\nend;\n{====================================================================}\n\n\n{===TAbZipEncryptEngine==============================================}\nconstructor TAbZipEncryptEngine.Create;\nbegin\n  {create the ancestor}\n  inherited Create;\n\n  {we're not ready for encryption yet since a header hasn't been\n   properly generated with CreateHeader}\n  FReady := false;\nend;\n{--------}\nprocedure TAbZipEncryptEngine.CreateHeader(\n                                var aHeader     : TAbZipEncryptHeader;\n                              const aPassphrase : AnsiString;\n                                    aCheckValue : longint);\ntype\n  TLongAsBytes = packed record\n    L1, L2, L3, L4 : byte\n  end;\nvar\n  Ch   : byte;\n  i    : integer;\n  Temp : longint;\n  WorkHeader : TAbZipEncryptHeader;\nbegin\n  {check for programming errors}\n  Assert(aPassphrase <> '',\n         'TAbZipEncryptEngine.CreateHeader: need a passphrase');\n\n  {set the first ten bytes of the header with random values (in fact,\n   we use a random value for each byte and mix it in with the state)}\n\n  {initialize the decryption state}\n  zeeInitState(aPassphrase);\n\n  {for the first ten bytes...}\n  for i := 0 to 9 do begin\n\n    {get a random value}\n    Ch := Random( 256 );\n\n    {calculate the XOR encoding byte (uses inlined decrypt_byte)}\n    Temp := (FState[2] and $FFFF) or 2;\n    Temp := (Temp * (Temp xor 1)) shr 8;\n\n    {mix the unencoded byte into the state (uses inlined update_keys)}\n    FState[0] := AbUpdateCrc32(Ch, FState[0]);\n    FState[1] := FState[1] + (FState[0] and $FF);\n    FState[1] := (FState[1] * MagicNumber) + 1;\n    FState[2] := AbUpdateCrc32(FState[1] shr 24, FState[2]);\n\n    {set the current byte of the header}\n    WorkHeader[i] := Ch xor Temp;\n  end;\n\n  {now encrypt the first ten bytes of the header (this merely sets up\n   the state so that we can encrypt the last two bytes)}\n\n  {reinitialize the decryption state}\n  zeeInitState(aPassphrase);\n\n  {for the first ten bytes...}\n  for i := 0 to 9 do begin\n\n    {calculate the XOR encoding byte (uses inlined decrypt_byte)}\n    Temp := (FState[2] and $FFFF) or 2;\n    Temp := (Temp * (Temp xor 1)) shr 8;\n\n    {mix the unencoded byte into the state (uses inlined update_keys)}\n    FState[0] := AbUpdateCrc32(WorkHeader[i], FState[0]);\n    FState[1] := FState[1] + (FState[0] and $FF);\n    FState[1] := (FState[1] * MagicNumber) + 1;\n    FState[2] := AbUpdateCrc32(FState[1] shr 24, FState[2]);\n\n    {set the current byte of the header}\n    WorkHeader[i] := WorkHeader[i] xor Temp;\n  end;\n\n  {now initialize byte 10 of the header, and encrypt it}\n  Ch := TLongAsBytes(aCheckValue).L3;\n  Temp := (FState[2] and $FFFF) or 2;\n  Temp := (Temp * (Temp xor 1)) shr 8;\n  FState[0] := AbUpdateCrc32(Ch, FState[0]);\n  FState[1] := FState[1] + (FState[0] and $FF);\n  FState[1] := (FState[1] * MagicNumber) + 1;\n  FState[2] := AbUpdateCrc32(FState[1] shr 24, FState[2]);\n  WorkHeader[10] := Ch xor Temp;\n\n  {now initialize byte 11 of the header, and encrypt it}\n  Ch := TLongAsBytes(aCheckValue).L4;\n  Temp := (FState[2] and $FFFF) or 2;\n  Temp := (Temp * (Temp xor 1)) shr 8;\n  FState[0] := AbUpdateCrc32(Ch, FState[0]);\n  FState[1] := FState[1] + (FState[0] and $FF);\n  FState[1] := (FState[1] * MagicNumber) + 1;\n  FState[2] := AbUpdateCrc32(FState[1] shr 24, FState[2]);\n  WorkHeader[11] := Ch xor Temp;\n\n  {we're now ready to encrypt}\n  FReady := true;\n\n  {return the header}\n  aHeader := WorkHeader;\nend;\n{--------}\nfunction TAbZipEncryptEngine.Encode(aCh : byte) : byte;\nvar\n  Temp : longint;\nbegin\n  {check for programming error}\n  Assert(FReady,\n         'TAbZipEncryptEngine.Encode: must call CreateHeader first');\n\n  {calculate the encoded byte (uses inlined decrypt_byte)}\n  Temp := (FState[2] and $FFFF) or 2;\n  Result := aCh xor (Temp * (Temp xor 1)) shr 8;\n\n  {mix the unencoded byte into the state (uses inlined update_keys)}\n  FState[0] := AbUpdateCrc32(aCh, FState[0]);\n  FState[1] := FState[1] + (FState[0] and $FF);\n  FState[1] := (FState[1] * MagicNumber) + 1;\n  FState[2] := AbUpdateCrc32(FState[1] shr 24, FState[2]);\nend;\n{--------}\nprocedure TAbZipEncryptEngine.EncodeBuffer(var aBuffer; aCount : integer);\nvar\n  Ch     : byte;\n  i      : integer;\n  Temp   : longint;\n  Buffer : PAnsiChar;\n  WorkState : array [0..2] of longint;\nbegin\n  {check for programming error}\n  Assert(FReady,\n         'TAbZipEncryptEngine.EncodeBuffer: must call CreateHeader first');\n\n  {move the state to a local variable--for better speed}\n  WorkState[0] := FState[0];\n  WorkState[1] := FState[1];\n  WorkState[2] := FState[2];\n\n  {reference the buffer as a PChar--easier arithmetic}\n  Buffer := @aBuffer;\n\n  {for each byte in the buffer...}\n  for i := 0 to pred(aCount) do begin\n\n    {calculate the next encoded byte (uses inlined decrypt_byte)}\n    Temp := (WorkState[2] and $FFFF) or 2;\n    Ch := byte(Buffer^);\n    Buffer^ := AnsiChar(Ch xor ((Temp * (Temp xor 1)) shr 8));\n\n    {mix the decoded byte into the state (uses inlined update_keys)}\n    WorkState[0] := AbUpdateCrc32(Ch, WorkState[0]);\n    WorkState[1] := WorkState[1] + (WorkState[0] and $FF);\n    WorkState[1] := (WorkState[1] * MagicNumber) + 1;\n    WorkState[2] := AbUpdateCrc32(WorkState[1] shr 24, WorkState[2]);\n\n    {move onto the next byte}\n    inc(Buffer);\n  end;\n\n  {save the state}\n  FState[0] := WorkState[0];\n  FState[1] := WorkState[1];\n  FState[2] := WorkState[2];\nend;\n{--------}\nprocedure TAbZipEncryptEngine.zeeInitState(const aPassphrase : AnsiString);\nvar\n  i : integer;\nbegin\n  {initialize the decryption state}\n  FState[0] := StateInit1;\n  FState[1] := StateInit2;\n  FState[2] := StateInit3;\n\n  {mix in the passphrase to the state (uses inlined update_keys)}\n  for i := 1 to length(aPassphrase) do begin\n    FState[0] := AbUpdateCrc32(byte(aPassphrase[i]), FState[0]);\n    FState[1] := FState[1] + (FState[0] and $FF);\n    FState[1] := (FState[1] * MagicNumber) + 1;\n    FState[2] := AbUpdateCrc32(FState[1] shr 24, FState[2]);\n  end;\nend;\n{====================================================================}\n\n\n{===TAbDfEncryptStream===============================================}\nconstructor TAbDfEncryptStream.Create(aStream     : TStream;\n                                      aCheckValue : longint;\n                                const aPassphrase : AnsiString);\nvar\n  Header : TAbZipEncryptHeader;\nbegin\n  {create the ancestor}\n  inherited Create;\n\n  {save the stream parameter}\n  FStream := aStream;\n\n  {create the encryption engine}\n  FEngine := TAbZipEncryptEngine.Create;\n\n  {generate the encryption header, write it to the stream}\n  FEngine.CreateHeader(Header, aPassphrase, aCheckValue);\n  aStream.WriteBuffer(Header, sizeof(Header));\nend;\n{--------}\ndestructor TAbDfEncryptStream.Destroy;\nbegin\n  {free the internal buffer if used}\n  if (FBuffer <> nil) then\n    FreeMem(FBuffer);\n\n  {free the engine}\n  FEngine.Free;\n\n  {destroy the ancestor}\n  inherited Destroy;\nend;\n{--------}\nfunction TAbDfEncryptStream.Read(var aBuffer; aCount : longint) : longint;\nbegin\n  {check for programming error}\n  Assert(false,\n         'TAbDfEncryptStream.Read: the stream is write-only');\n  Result := 0;\nend;\n{--------}\nfunction TAbDfEncryptStream.Seek(aOffset : longint; aOrigin : word) : longint;\nbegin\n  Result := FStream.Seek(aOffset, aOrigin);\nend;\n{--------}\nfunction TAbDfEncryptStream.Write(const aBuffer; aCount : longint) : longint;\nbegin\n  {note: since we cannot alter a const parameter, we should copy the\n         data to our own buffer, encrypt it and then write it}\n\n  {check that our buffer is large enough}\n  if (FBufSize < aCount) then begin\n    if (FBuffer <> nil) then\n      FreeMem(FBuffer);\n    GetMem(FBuffer, aCount);\n    FBufSize := aCount;\n  end;\n\n  {copy the data to our buffer}\n  Move(aBuffer, FBuffer^, aCount);\n\n  {encrypt the data in our buffer}\n  FEngine.EncodeBuffer(FBuffer^, aCount);\n\n  {write the data in our buffer to the underlying stream}\n  Result := FStream.Write(FBuffer^, aCount);\nend;\n{====================================================================}\n\n\nend.\n\n\n\n"
  },
  {
    "path": "lib/abbrevia/source/AbDfDec.pas",
    "content": "(* ***** BEGIN LICENSE BLOCK *****\n * Version: MPL 1.1\n *\n * The contents of this file are subject to the Mozilla Public License Version\n * 1.1 (the \"License\"); you may not use this file except in compliance with\n * the License. You may obtain a copy of the License at\n * http://www.mozilla.org/MPL/\n *\n * Software distributed under the License is distributed on an \"AS IS\" basis,\n * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License\n * for the specific language governing rights and limitations under the\n * License.\n *\n * The Original Code is TurboPower Abbrevia\n *\n * The Initial Developer of the Original Code is\n * TurboPower Software\n *\n * Portions created by the Initial Developer are Copyright (C) 1997-2002\n * the Initial Developer. All Rights Reserved.\n *\n * Contributor(s):\n *\n * ***** END LICENSE BLOCK ***** *)\n\n{*********************************************************}\n{* ABBREVIA: AbDfDec.pas                                 *}\n{*********************************************************}\n{* Deflate decoding unit                                 *}\n{*********************************************************}\n\nunit AbDfDec;\n\n{$I AbDefine.inc}\n\ninterface\n\nuses\n  Classes,\n  AbDfBase;\n\nfunction Inflate(aSource : TStream; aDest : TStream;\n                 aHelper : TAbDeflateHelper) : longint;\n\nimplementation\n\nuses\n  SysUtils,\n  AbDfStrm,\n  AbDfHufD,\n  AbDfOutW,\n  AbDfCryS;\n\n\n{===Helper routines==================================================}\nprocedure ReadLitDistCodeLengths(aInStrm      : TAbDfInBitStream;\n                                 aCodeLenTree : TAbDfDecodeHuffmanTree;\n                             var aCodeLens    : array of integer;\n                                 aCount       : integer;\n                             var aTotalBits   : integer);\nvar\n  i : integer;\n  SymbolCount   : integer;\n  LookupValue   : integer;\n  EncodedSymbol : longint;\n  Symbol        : integer;\n  SymbolCodeLen : integer;\n  RepeatCount   : integer;\n  BitBuffer     : TAb32bit;\n  BitCount      : integer;\nbegin\n  {$IFDEF UseLogging}\n  {we need to calculate the total number of bits in the code lengths\n   for reporting purposes, so zero the count}\n  aTotalBits := 0;\n  {$ENDIF}\n\n  {clear the code lengths array}\n  FillChar(aCodeLens, sizeof(aCodeLens), 0);\n\n  {read all the Symbols required in the bit stream}\n  SymbolCount := 0;\n  while (SymbolCount < aCount) do begin\n    {grab the lookup set of bits}\n    BitCount := aCodeLenTree.LookupBitLength + 7;\n    {$IFOPT C+}\n    BitBuffer := aInStrm.PeekBits(BitCount);\n    {$ELSE}\n    if (aInStrm.BitsLeft < BitCount) then\n      BitBuffer := aInStrm.PeekMoreBits(BitCount)\n    else\n      BitBuffer := aInStrm.BitBuffer and AbExtractMask[BitCount];\n    {$ENDIF}\n    LookupValue :=\n       BitBuffer and AbExtractMask[aCodeLenTree.LookupBitLength];\n\n    {get the encoded Symbol}\n    {$IFOPT C+} {if Assertions are on}\n    EncodedSymbol := aCodeLenTree.Decode(LookupValue);\n    {$ELSE}\n    EncodedSymbol := aCodeLenTree.Decodes^[LookupValue];\n    {$ENDIF}\n\n    {extract the data}\n    Symbol := EncodedSymbol and $FFFF;\n    SymbolCodeLen := (EncodedSymbol shr 16) and $FF;\n\n    {$IFDEF UseLogging}\n    {keep count of the total number of bits read}\n    inc(aTotalBits, SymbolCodeLen);\n    {$ENDIF}\n\n    {check that the symbol is between 0 and 18}\n    if not ((0 <= Symbol) and (Symbol <= 18)) then\n      raise EAbInternalInflateError.Create(\n         'decoded a symbol not between 0 and 18 {ReadLitDistCodeLengths}');\n\n    {check that the codelength is in range}\n    if not ((0 < SymbolCodeLen) and\n            (SymbolCodeLen <= aCodeLenTree.LookupBitLength)) then\n      raise EAbInternalInflateError.Create(\n         'decoded a code length out of range {ReadLitDistCodeLengths}');\n\n    {for a Symbol of 0..15, just save the value}\n    if (Symbol <= 15) then begin\n      aCodeLens[SymbolCount] := Symbol;\n      inc(SymbolCount);\n      {$IFOPT C+}\n      aInStrm.DiscardBits(SymbolCodeLen);\n      {$ELSE}\n      if (aInStrm.BitsLeft < SymbolCodeLen) then\n        aInStrm.DiscardMoreBits(SymbolCodeLen)\n      else begin\n        aInStrm.BitBuffer := aInStrm.BitBuffer shr SymbolCodeLen;\n        aInStrm.BitsLeft := aInStrm.BitsLeft - SymbolCodeLen;\n      end;\n      {$ENDIF}\n    end\n\n    {for a Symbol of 16, get two more bits and copy the previous\n     code length that many times + 3}\n    else if (Symbol = 16) then begin\n      RepeatCount := 3 + ((BitBuffer shr SymbolCodeLen) and $3);\n      Symbol := aCodeLens[SymbolCount-1];\n      for i := 0 to pred(RepeatCount) do\n        aCodeLens[SymbolCount+i] := Symbol;\n      inc(SymbolCount, RepeatCount);\n      BitCount := SymbolCodeLen + 2;\n      {$IFOPT C+}\n      aInStrm.DiscardBits(BitCount);\n      {$ELSE}\n      if (aInStrm.BitsLeft < BitCount) then\n        aInStrm.DiscardMoreBits(BitCount)\n      else begin\n        aInStrm.BitBuffer := aInStrm.BitBuffer shr BitCount;\n        aInStrm.BitsLeft := aInStrm.BitsLeft - BitCount;\n      end;\n      {$ENDIF}\n      {$IFDEF UseLogging}\n      inc(aTotalBits, 2);\n      {$ENDIF}\n    end\n\n    {for a Symbol of 17, get three more bits and copy a zero code\n     length that many times + 3}\n    else if (Symbol = 17) then begin\n      RepeatCount := 3 + ((BitBuffer shr SymbolCodeLen) and $7);\n      {note: the codelengths array was aet to zeros at the start so\n             the following two lines are not needed\n      for i := 0 to pred(RepeatCount) do\n        aCodeLens[SymbolCount+i] := 0;}\n      inc(SymbolCount, RepeatCount);\n      BitCount := SymbolCodeLen + 3;\n      {$IFOPT C+}\n      aInStrm.DiscardBits(BitCount);\n      {$ELSE}\n      if (aInStrm.BitsLeft < BitCount) then\n        aInStrm.DiscardMoreBits(BitCount)\n      else begin\n        aInStrm.BitBuffer := aInStrm.BitBuffer shr BitCount;\n        aInStrm.BitsLeft := aInStrm.BitsLeft - BitCount;\n      end;\n      {$ENDIF}\n      {$IFDEF UseLogging}\n      inc(aTotalBits, 3);\n      {$ENDIF}\n    end\n\n    {for a Symbol of 18, get seven more bits and copy a zero code\n     length that many times + 11}\n    else if (Symbol = 18) then begin\n      RepeatCount := 11 + ((BitBuffer shr SymbolCodeLen) and $7F);\n      {note: the codelengths array was aet to zeros at the start so\n             the following two lines are not needed\n      for i := 0 to pred(RepeatCount) do\n        aCodeLens[SymbolCount+i] := 0;}\n      inc(SymbolCount, RepeatCount);\n      BitCount := SymbolCodeLen + 7;\n      {$IFOPT C+}\n      aInStrm.DiscardBits(BitCount);\n      {$ELSE}\n      if (aInStrm.BitsLeft < BitCount) then\n        aInStrm.DiscardMoreBits(BitCount)\n      else begin\n        aInStrm.BitBuffer := aInStrm.BitBuffer shr BitCount;\n        aInStrm.BitsLeft := aInStrm.BitsLeft - BitCount;\n      end;\n      {$ENDIF}\n      {$IFDEF UseLogging}\n      inc(aTotalBits, 7);\n      {$ENDIF}\n    end;\n  end;\nend;\n{--------}\nprocedure DecodeData(aInStrm       : TAbDfInBitStream;\n                     aOutWindow    : TAbDfOutputWindow;\n                     aLiteralTree  : TAbDfDecodeHuffmanTree;\n                     aDistanceTree : TAbDfDecodeHuffmanTree;\n                     aDeflate64    : boolean);\nvar\n  LookupValue   : integer;\n  EncodedSymbol : longint;\n  Symbol        : integer;\n  SymbolCodeLen : integer;\n  ExtraBitCount : integer;\n  Length        : integer;\n  Distance      : integer;\n  BitBuffer     : TAb32bit;\n  BitCount      : integer;\nbegin\n  {extract the first symbol (it's got to be a literal/length symbol)}\n  {..grab the lookup set of bits}\n  if aDeflate64 then\n    BitCount := aLiteralTree.LookupBitLength + 16\n  else\n    BitCount := aLiteralTree.LookupBitLength + 5;\n  {$IFOPT C+}\n  BitBuffer := aInStrm.PeekBits(BitCount);\n  {$ELSE}\n  if (aInStrm.BitsLeft < BitCount) then\n    BitBuffer := aInStrm.PeekMoreBits(BitCount)\n  else\n    BitBuffer := aInStrm.BitBuffer and AbExtractMask[BitCount];\n  {$ENDIF}\n  LookupValue :=\n     BitBuffer and AbExtractMask[aLiteralTree.LookupBitLength];\n  {..get the encoded symbol}\n  {$IFOPT C+} {if Assertions are on}\n  EncodedSymbol := aLiteralTree.Decode(LookupValue);\n  {$ELSE}\n  EncodedSymbol := aLiteralTree.Decodes^[LookupValue];\n  {$ENDIF}\n  {..extract the data}\n  Symbol := EncodedSymbol and $FFFF;\n  SymbolCodeLen := (EncodedSymbol shr 16) and $FF;\n//  ExtraBitCount := EncodedSymbol shr 24;\n\n  {repeat until we get the end-of-block symbol}\n  while ((Symbol <> 256) {and (ExtraBitCount <> 15)}) do begin\n    {for a literal, just output it to the sliding window}\n    if (Symbol < 256) then begin\n      aOutWindow.AddLiteral(AnsiChar(Symbol));\n      {$IFOPT C+}\n      aInStrm.DiscardBits(SymbolCodeLen);\n      {$ELSE}\n      if (aInStrm.BitsLeft < SymbolCodeLen) then\n        aInStrm.DiscardMoreBits(SymbolCodeLen)\n      else begin\n        aInStrm.BitBuffer := aInStrm.BitBuffer shr SymbolCodeLen;\n        aInStrm.BitsLeft := aInStrm.BitsLeft - SymbolCodeLen;\n      end;\n      {$ENDIF}\n    end\n\n    {for a length value, we need to get any extra bits, and then the\n     distance (plus any extra bits for that), and then add the\n     duplicated characters to the sliding window}\n    else begin\n\n      {check that the length symbol is less than or equal to 285}\n      if (Symbol > 285) then\n        raise EAbInternalInflateError.Create(\n           'decoded an invalid length symbol: greater than 285 [DecodeData]');\n\n      {calculate the length (if need be, by calculating the number of\n       extra bits that encode the length)}\n      if (not aDeflate64) and (Symbol = 285) then begin\n        Length := 258;\n        {$IFOPT C+}\n        aInStrm.DiscardBits(SymbolCodeLen);\n        {$ELSE}\n        if (aInStrm.BitsLeft < SymbolCodeLen) then\n          aInStrm.DiscardMoreBits(SymbolCodeLen)\n        else begin\n          aInStrm.BitBuffer := aInStrm.BitBuffer shr SymbolCodeLen;\n          aInStrm.BitsLeft := aInStrm.BitsLeft - SymbolCodeLen;\n        end;\n        {$ENDIF}\n      end\n      else begin\n        ExtraBitCount := EncodedSymbol shr 24;\n        if (ExtraBitCount = 0) then begin\n          Length := dfc_LengthBase[Symbol - 257];\n          {$IFOPT C+}\n          aInStrm.DiscardBits(SymbolCodeLen);\n          {$ELSE}\n          if (aInStrm.BitsLeft < SymbolCodeLen) then\n            aInStrm.DiscardMoreBits(SymbolCodeLen)\n          else begin\n            aInStrm.BitBuffer := aInStrm.BitBuffer shr SymbolCodeLen;\n            aInStrm.BitsLeft := aInStrm.BitsLeft - SymbolCodeLen;\n          end;\n          {$ENDIF}\n        end\n        else begin\n          Length := dfc_LengthBase[Symbol - 257] +\n                    ((BitBuffer shr SymbolCodeLen) and\n                     AbExtractMask[ExtraBitCount]);\n          BitCount := SymbolCodeLen + ExtraBitCount;\n          {$IFOPT C+}\n          aInStrm.DiscardBits(BitCount);\n          {$ELSE}\n          if (aInStrm.BitsLeft < BitCount) then\n            aInStrm.DiscardMoreBits(BitCount)\n          else begin\n            aInStrm.BitBuffer := aInStrm.BitBuffer shr BitCount;\n            aInStrm.BitsLeft := aInStrm.BitsLeft - BitCount;\n          end;\n          {$ENDIF}\n        end;\n      end;\n\n      {extract the distance}\n      {..grab the lookup set of bits}\n      BitCount := aDistanceTree.LookupBitLength + 14;\n      {$IFOPT C+}\n      BitBuffer := aInStrm.PeekBits(BitCount);\n      {$ELSE}\n      if (aInStrm.BitsLeft < BitCount) then\n        BitBuffer := aInStrm.PeekMoreBits(BitCount)\n      else\n        BitBuffer := aInStrm.BitBuffer and AbExtractMask[BitCount];\n      {$ENDIF}\n      LookupValue :=\n         BitBuffer and AbExtractMask[aDistanceTree.LookupBitLength];\n      {..get the encoded symbol}\n      {$IFOPT C+} {if Assertions are on}\n      EncodedSymbol := aDistanceTree.Decode(LookupValue);\n      {$ELSE}\n      EncodedSymbol := aDistanceTree.Decodes^[LookupValue];\n      {$ENDIF}\n      {..extract the data}\n      Symbol := EncodedSymbol and $FFFF;\n      SymbolCodeLen := (EncodedSymbol shr 16) and $FF;\n\n      {check that the distance symbol is less than or equal to 29}\n      if (not aDeflate64) and (Symbol > 29) then\n        raise EAbInternalInflateError.Create(\n           'decoded an invalid distance symbol: greater than 29 [DecodeData]');\n\n      {..calculate the extra bits for the distance}\n      ExtraBitCount := EncodedSymbol shr 24;\n      {..calculate the distance}\n      if (ExtraBitCount = 0) then begin\n        Distance := dfc_DistanceBase[Symbol];\n        {$IFOPT C+}\n        aInStrm.DiscardBits(SymbolCodeLen);\n        {$ELSE}\n        if (aInStrm.BitsLeft < SymbolCodeLen) then\n          aInStrm.DiscardMoreBits(SymbolCodeLen)\n        else begin\n          aInStrm.BitBuffer := aInStrm.BitBuffer shr SymbolCodeLen;\n          aInStrm.BitsLeft := aInStrm.BitsLeft - SymbolCodeLen;\n        end;\n        {$ENDIF}\n      end\n      else begin\n        Distance := dfc_DistanceBase[Symbol] +\n                    ((BitBuffer shr SymbolCodeLen) and\n                     AbExtractMask[ExtraBitCount]);\n        BitCount := SymbolCodeLen + ExtraBitCount;\n        {$IFOPT C+}\n        aInStrm.DiscardBits(BitCount);\n        {$ELSE}\n        if (aInStrm.BitsLeft < BitCount) then\n          aInStrm.DiscardMoreBits(BitCount)\n        else begin\n          aInStrm.BitBuffer := aInStrm.BitBuffer shr BitCount;\n          aInStrm.BitsLeft := aInStrm.BitsLeft - BitCount;\n        end;\n        {$ENDIF}\n      end;\n\n      {duplicate the characters in the sliding window}\n      aOutWindow.AddLenDist(Length, Distance);\n    end;\n\n    {extract the next symbol}\n    {..grab the lookup set of bits}\n    if aDeflate64 then\n      BitCount := aLiteralTree.LookupBitLength + 16\n    else\n      BitCount := aLiteralTree.LookupBitLength + 5;\n    {$IFOPT C+}\n    BitBuffer := aInStrm.PeekBits(BitCount);\n    {$ELSE}\n    if (aInStrm.BitsLeft < BitCount) then\n      BitBuffer := aInStrm.PeekMoreBits(BitCount)\n    else\n      BitBuffer := aInStrm.BitBuffer and AbExtractMask[BitCount];\n    {$ENDIF}\n    LookupValue :=\n       BitBuffer and AbExtractMask[aLiteralTree.LookupBitLength];\n    {..get the encoded symbol}\n    {$IFOPT C+} {if Assertions are on}\n    EncodedSymbol := aLiteralTree.Decode(LookupValue);\n    {$ELSE}\n    EncodedSymbol := aLiteralTree.Decodes^[LookupValue];\n    {$ENDIF}\n    {..extract the data}\n    Symbol := EncodedSymbol and $FFFF;\n    SymbolCodeLen := (EncodedSymbol shr 16) and $FF;\n  end;\n\n  {discard the bits for the end-of-block marker}\n  {$IFOPT C+}\n  aInStrm.DiscardBits(SymbolCodeLen);\n  {$ELSE}\n  if (aInStrm.BitsLeft < SymbolCodeLen) then\n    aInStrm.DiscardMoreBits(SymbolCodeLen)\n  else begin\n    aInStrm.BitBuffer := aInStrm.BitBuffer shr SymbolCodeLen;\n    aInStrm.BitsLeft := aInStrm.BitsLeft - SymbolCodeLen;\n  end;\n  {$ENDIF}\nend;\n{--------}\nprocedure InflateStoredBlock(aInStrm    : TAbDfInBitStream;\n                             aOutWindow : TAbDfOutputWindow;\n                             aLog       : TAbLogger);\nconst\n  BufferSize = 16 * 1024;\nvar\n  LenNotLen : packed record\n    Len    : word;\n    NotLen : word;\n  end;\n  BytesToGo    : integer;\n  BytesToWrite : integer;\n  Buffer       : pointer;\nbegin\n  {$IFDEF UseLogging}\n  {log it}\n  if (aLog <> nil) then\n    aLog.WriteLine('....a stored block');\n  {$ENDIF}\n\n  {align the input bit stream to the nearest byte boundary}\n  aInStrm.AlignToByte;\n\n  {read the length of the stored data and the notted length}\n  aInStrm.ReadBuffer(LenNotLen, sizeof(LenNotLen));\n\n  {$IFDEF UseLogging}\n  {log it}\n  if (aLog <> nil) then\n    aLog.WriteLine(Format('..block length: %d (%-4x, NOT %-4x)',\n                          [LenNotLen.Len, LenNotLen.Len, LenNotLen.NotLen]));\n  {$ENDIF}\n\n  {check that NOT of the length equals the notted length}\n  if ((not LenNotLen.Len) <> LenNotLen.NotLen) then\n    raise EAbInternalInflateError.Create(\n       'invalid stored block (length and NOT length do not match) [InflateStoredBlock]');\n\n  {calculate the number of bytes to copy from the stored block}\n  BytesToGo := LenNotLen.Len;\n\n  {allocate a large buffer}\n  GetMem(Buffer, BufferSize);\n\n  {copy all the data in the stored block to the output window}\n  try\n    {while there are still some bytes to copy...}\n    while (BytesToGo <> 0) do begin\n      {calculate the number of bytes this time}\n      if (BytesToGo > BufferSize) then\n        BytesToWrite := BufferSize\n      else\n        BytesToWrite := BytesToGo;\n\n      {read that many bytes and write them to the output window}\n      aInStrm.ReadBuffer(Buffer^, BytesToWrite);\n      aOutWindow.AddBuffer(Buffer^, BytesToWrite);\n\n      {calculate the number of bytes still to copy}\n      dec(BytesToGo, BytesToWrite);\n    end;\n  finally\n    FreeMem(Buffer);\n  end;\nend;\n{--------}\nprocedure InflateStaticBlock(aInStrm    : TAbDfInBitStream;\n                             aOutWindow : TAbDfOutputWindow;\n                             aLog       : TAbLogger;\n                             aDeflate64 : boolean);\nbegin\n  {$IFDEF UseLogging}\n  {log it}\n  if (aLog <> nil) then\n    aLog.WriteLine('....a static huffman tree block');\n  {$ENDIF}\n\n  {decode the data with the static trees}\n  DecodeData(aInStrm, aOutWindow,\n             AbStaticLiteralTree, AbStaticDistanceTree, aDeflate64);\nend;\n{--------}\nprocedure InflateDynamicBlock(aInStrm    : TAbDfInBitStream;\n                              aOutWindow : TAbDfOutputWindow;\n                              aLog       : TAbLogger;\n                              aDeflate64 : boolean);\nvar\n  i : integer;\n  LitCount      : integer;\n  DistCount     : integer;\n  CodeLenCount  : integer;\n  CodeLens      : array [0..285+32] of integer;\n  CodeLenTree   : TAbDfDecodeHuffmanTree;\n  LiteralTree   : TAbDfDecodeHuffmanTree;\n  DistanceTree  : TAbDfDecodeHuffmanTree;\n  TotalBits     : integer;\nbegin\n  {$IFDEF UseLogging}\n  {log it}\n  if (aLog <> nil) then\n    aLog.WriteLine('....a dynamic huffman tree block');\n  {$ENDIF}\n\n  {prepare for the try..finally}\n  CodeLenTree := nil;\n  LiteralTree := nil;\n  DistanceTree := nil;\n\n  try\n    {decode the number of literal, distance and codelength codes}\n    LitCount := aInStrm.ReadBits(5) + 257;\n    DistCount := aInStrm.ReadBits(5) + 1;\n    CodeLenCount := aInStrm.ReadBits(4) + 4;\n\n    {$IFDEF UseLogging}\n    {log it}\n    if (aLog <> nil) then begin\n      aLog.WriteLine(Format('Count of literals:     %d', [LitCount]));\n      aLog.WriteLine(Format('Count of distances:    %d', [DistCount]));\n      aLog.WriteLine(Format('Count of code lengths: %d', [CodeLenCount]));\n    end;\n    {$ENDIF}\n\n    {verify that the counts are valid}\n    if (LitCount > 286) then\n      raise EAbInternalInflateError.Create(\n         'count of literal codes in dynamic block is greater than 286 [InflateDynamicBlock]');\n    if (not aDeflate64) and (DistCount > 30) then\n      raise EAbInternalInflateError.Create(\n         'count of distance codes in dynamic block is greater than 30 [InflateDynamicBlock]');\n\n    {read the codelengths}\n    FillChar(CodeLens, 19 * sizeof(integer), 0);\n    for i := 0 to pred(CodeLenCount) do\n      CodeLens[dfc_CodeLengthIndex[i]] := aInStrm.ReadBits(3);\n\n    {$IFDEF UseLogging}\n    {log them}\n    if (aLog <> nil) then begin\n      aLog.WriteLine('CodeLength Huffman tree: code lengths');\n      for i := 0 to 18 do\n        aLog.WriteStr(Format('%-3d', [CodeLens[i]]));\n      aLog.WriteLine('');\n      aLog.WriteLine(Format('..total bits: %d', [CodeLenCount * 3]));\n    end;\n    {$ENDIF}\n\n    {create the codelength huffman tree}\n    CodeLenTree := TAbDfDecodeHuffmanTree.Create(19, 7, huDecoding);\n    CodeLenTree.Build(CodeLens, 0, 19, [0], $FFFF);\n\n    {$IFDEF UseLogging}\n    {log the tree}\n    if (aLog <> nil) then begin\n      aLog.WriteLine('Code lengths tree');\n      CodeLenTree.DebugPrint(aLog);\n    end;\n    {$ENDIF}\n\n    {read the codelengths for both the literal/length and distance\n     huffman trees}\n    ReadLitDistCodeLengths(aInStrm, CodeLenTree, CodeLens,\n                           LitCount + DistCount, TotalBits);\n\n    {$IFDEF UseLoggingx}\n    {log them}\n    if (aLog <> nil) then begin\n      aLog.WriteLine('Literal/length & Dist Huffman trees: code lengths');\n      for i := 0 to pred(LitCount + DistCount) do\n        aLog.WriteLine(Format('%3d: %3d', [i, CodeLens[i]]));\n      aLog.WriteLine('');\n      aLog.WriteLine(Format('..total bits: %d', [TotalBits]));\n    end;\n    {$ENDIF}\n\n    {create the literal huffman tree}\n    LiteralTree := TAbDfDecodeHuffmanTree.Create(286, 15, huDecoding);\n    LiteralTree.Build(CodeLens, 0, LitCount,\n                      dfc_LitExtraBits, dfc_LitExtraOffset);\n\n    {$IFDEF UseLogging}\n    {log the tree}\n    if (aLog <> nil) then begin\n      aLog.WriteLine('Literal/length tree');\n      LiteralTree.DebugPrint(aLog);\n    end;\n    {$ENDIF}\n\n    {create the distance huffman tree}\n    if aDeflate64 then\n      DistanceTree := TAbDfDecodeHuffmanTree.Create(32, 15, huDecoding)\n    else\n      DistanceTree := TAbDfDecodeHuffmanTree.Create(30, 15, huDecoding);\n    DistanceTree.Build(CodeLens, LitCount, DistCount,\n                       dfc_DistExtraBits, dfc_DistExtraOffset);\n\n    {$IFDEF UseLogging}\n    {log the tree}\n    if (aLog <> nil) then begin\n      aLog.WriteLine('Distance tree');\n      DistanceTree.DebugPrint(aLog);\n    end;\n    {$ENDIF}\n\n    {using the literal and distance trees, decode the bit stream}\n    DecodeData(aInStrm, aOutWindow,\n               LiteralTree, DistanceTree, aDeflate64);\n  finally\n    CodeLenTree.Free;\n    LiteralTree.Free;\n    DistanceTree.Free;\n  end;\nend;\n{====================================================================}\n\n\n{===Interfaced routine===============================================}\nfunction Inflate(aSource : TStream; aDest : TStream;\n                 aHelper : TAbDeflateHelper) : longint;\nvar\n  Helper       : TAbDeflateHelper;\n  InBitStrm    : TAbDfInBitStream;\n  OutWindow    : TAbDfOutputWindow;\n  Log          : TAbLogger;\n  UseDeflate64 : boolean;\n  UseCRC32     : boolean;\n  IsFinalBlock : boolean;\n  BlockType    : integer;\n  TestOnly     : boolean;\n  SourceStartPos : longint;\n  DestStartPos   : longint;\n  {$IFDEF UseLogging}\n  StartPosn    : longint;\n  {$ENDIF}\nbegin\n  {$IFDEF DefeatWarnings}\n  Result := 0;\n  SourceStartPos := 0;\n  DestStartPos := 0;\n  TestOnly := False;\n  {$ENDIF}\n\n  {$IFDEF UseLogging}\n  StartPosn := 0;\n  {$ENDIF}\n\n  {pre-conditions: streams must be allocated of course}\n  Assert(aSource <> nil, 'Deflate: aSource stream cannot be nil');\n  Assert(aDest <> nil, 'Deflate: aDest stream cannot be nil');\n\n  {prepare for the try..finally}\n  Helper := nil;\n  InBitStrm := nil;\n  OutWindow := nil;\n  Log := nil;\n\n  try {finally}\n    try {except}\n      {create our helper; assign the passed one to it}\n      Helper := TAbDeflateHelper.Create;\n      if (aHelper <> nil) then\n        Helper.Assign(aHelper);\n\n      {get the initial start positions of both streams}\n      SourceStartPos := aSource.Position;\n      DestStartPos := aDest.Position;\n\n      {if the helper's stream size is -1, and it has a progress event\n       handler, calculate the stream size from the stream itself}\n      if Assigned(Helper.OnProgressStep) then begin\n        if (Helper.StreamSize = -1) then\n          Helper.StreamSize := aSource.Size;\n      end\n      \n      {otherwise we certainly can't do any progress reporting}\n      else begin\n        Helper.OnProgressStep := nil;\n        Helper.StreamSize := 0;\n      end;\n\n      {create the logger, if requested}\n      if (Helper.LogFile <> '') then begin\n        Log := TAbLogger.Create(Helper.LogFile);\n        Log.WriteLine('INFLATING STREAM...');\n        {$IFNDEF UseLogging}\n        Log.WriteLine('Need to recompile the app with UseLogging turned on');\n        {$ENDIF}\n      end;\n\n      InBitStrm := TAbDfInBitStream.Create(aSource,\n                                           Helper.OnProgressStep,\n                                           Helper.StreamSize);\n\n      {create the output sliding window}\n      UseDeflate64 := (Helper.Options and dfc_UseDeflate64) <> 0;\n      UseCRC32 := (Helper.Options and dfc_UseAdler32) = 0;\n      TestOnly := (Helper.Options and dfc_TestOnly) <> 0;\n      OutWindow := TAbDfOutputWindow.Create(\n              aDest, UseDeflate64, UseCRC32, Helper.PartialSize,\n              TestOnly, Log);\n\n      {start decoding the deflated stream}\n      repeat\n        {read the final block flag and the block type}\n        IsFinalBlock := InBitStrm.ReadBit;\n        BlockType := InBitStrm.ReadBits(2);\n\n        {$IFDEF UseLogging}\n        {log it}\n        if (Log <> nil) then begin\n          Log.WriteLine('');\n          Log.WriteLine('Starting new block');\n          Log.WriteLine(Format('..final block? %d', [ord(IsFinalBlock)]));\n          Log.WriteLine(Format('..block type? %d', [BlockType]));\n          StartPosn := OutWindow.Position;\n        end;\n        {$ENDIF}\n\n        case BlockType of\n          0 : InflateStoredBlock(InBitStrm, OutWindow, Log);\n          1 : InflateStaticBlock(InBitStrm, OutWindow, Log, UseDeflate64);\n          2 : InflateDynamicBlock(InBitStrm, OutWindow, Log, UseDeflate64);\n        else\n          raise EAbInternalInflateError.Create(\n             'starting new block, but invalid block type [Inflate]');\n        end;\n\n        {$IFDEF UseLogging}\n        {log it}\n        if (Log <> nil) then\n          Log.WriteLine(Format('---block end---  (decoded size %d bytes)',\n                               [OutWindow.Position - StartPosn]));\n        {$ENDIF}\n      until IsFinalBlock;\n\n      {get the uncompressed stream's checksum}\n      Result := OutWindow.Checksum;\n      if TestOnly and (aHelper <> nil) then\n        aHelper.NormalSize := OutWindow.Position;\n      {$IFDEF UseLogging}\n      {log it}\n      if (Log <> nil) then\n        Log.WriteLine(Format('End of compressed stream, checksum %-8x',\n                             [Result]));\n      {$ENDIF}\n    except\n      on E : EAbPartSizedInflate do begin\n        {nothing, just swallow the exception}\n        Result := 0;\n      end;\n      on E : EAbAbortProgress do begin\n        {nothing, just swallow the exception}\n        Result := 0;\n      end;\n      on E : EAbInternalInflateError do begin\n        if (Log <> nil) then\n          Log.WriteLine(Format('Internal exception raised: %s',\n                                [E.Message]));\n        raise EAbInflateError.Create(E.Message);\n      end;\n    end;\n  finally\n    Helper.Free;\n    OutWindow.Free;\n    InBitStrm.Free;\n    Log.Free;\n  end;\n\n  {if there's a helper return the compressed and uncompressed sizes}\n  if (aHelper <> nil) then begin\n    if not TestOnly then\n      aHelper.NormalSize := aDest.Position - DestStartPos;\n    aHelper.CompressedSize := aSource.Position - SourceStartPos;\n  end;\n\n  {WARNING NOTE: the compiler will warn that the return value of this\n                 function might be undefined. However, it is wrong: it\n                 has been fooled by the code. If you don't want to see\n                 this warning again, enable the DefeatWarnings\n                 compiler define in AbDefine.inc.}\nend;\n{====================================================================}\n\nend.\n"
  },
  {
    "path": "lib/abbrevia/source/AbDfEnc.pas",
    "content": "(* ***** BEGIN LICENSE BLOCK *****\n * Version: MPL 1.1\n *\n * The contents of this file are subject to the Mozilla Public License Version\n * 1.1 (the \"License\"); you may not use this file except in compliance with\n * the License. You may obtain a copy of the License at\n * http://www.mozilla.org/MPL/\n *\n * Software distributed under the License is distributed on an \"AS IS\" basis,\n * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License\n * for the specific language governing rights and limitations under the\n * License.\n *\n * The Original Code is TurboPower Abbrevia\n *\n * The Initial Developer of the Original Code is\n * TurboPower Software\n *\n * Portions created by the Initial Developer are Copyright (C) 1997-2002\n * the Initial Developer. All Rights Reserved.\n *\n * Contributor(s):\n *\n * ***** END LICENSE BLOCK ***** *)\n\n{*********************************************************}\n{* ABBREVIA: AbDfEnc.pas                                 *}\n{*********************************************************}\n{* Deflate encoding unit                                 *}\n{*********************************************************}\n\nunit AbDfEnc;\n\n{$I AbDefine.inc}\n\ninterface\n\nuses\n  Classes,\n  AbDfBase;\n\nfunction Deflate(aSource : TStream; aDest : TStream;\n                 aHelper : TAbDeflateHelper) : longint;\n\nimplementation\n\nuses\n  AbDfInW,\n  AbDfHufD,\n  AbDfStrm,\n  AbDfCryS,\n  AbDfPkMg;\n\n{====================================================================}\nfunction CalcDynamicBitCount(aUseDeflate64: boolean;\n                             aLitBuckets  : PAbDfLitBuckets;\n                             aDistBuckets : PAbDfDistBuckets;\n                             aCodeBuckets : PAbDfCodeLenBuckets;\n                       const aCodeLens    : array of integer;\n                       const aCLCodeLens  : array of integer;\n                             aLitCount    : integer;\n                             aDistCount   : integer;\n                             aCodeCount   : integer) : longint;\nvar\n  Symbol     : integer;\n  LastSymbol : integer;\n  Inx        : integer;\nbegin\n  {note: this routine calculates the number of bits required to\n         compress a given block}\n\n  {a dynamic block starts off with 5 bits of literal symbol count, 5\n   bits of distance symbol count, 4 bits of codelength symbol count,\n   and then 3 bits for every codelength symbol used}\n  Result := 5 + 5 + 4 +\n            (aCodeCount * 3);\n\n  {add in the bits needed to compress the literal and distance trees}\n  inc(Result, aCodeBuckets^[16] * (aCLCodeLens[16] + 2));\n  inc(Result, aCodeBuckets^[17] * (aCLCodeLens[16] + 3));\n  inc(Result, aCodeBuckets^[18] * (aCLCodeLens[16] + 7));\n  for Symbol := 3 to pred(aCodeCount) do begin\n    Inx := dfc_CodeLengthIndex[Symbol];\n    Assert(Inx <=15,\n           'CalcDynamicBitCount: the index array of codelengths is corrupted');\n    inc(Result, aCodeBuckets^[Inx] * aCLCodeLens[Inx])\n  end;\n\n  {make the literal symbol 285 a special case}\n  LastSymbol := pred(aLitCount);\n  if (LastSymbol = 285) then\n    LastSymbol := 284;\n\n  {add in all the bits needed to compress the literals (except 285)}\n  for Symbol := 0 to LastSymbol do\n    if (Symbol < dfc_LitExtraOffset) then\n      inc(Result, aLitBuckets^[Symbol] * aCodeLens[Symbol])\n    else\n      inc(Result, aLitBuckets^[Symbol] *\n                  (aCodeLens[Symbol] +\n                   dfc_LitExtraBits[Symbol - dfc_LitExtraOffset]));\n\n  {add in all the bits needed to compress the literal symbol 285}\n  if (pred(aLitCount) = 285) then\n    if (not aUseDeflate64) then\n      inc(Result, aLitBuckets^[285] * aCodeLens[285])\n    else\n      inc(Result, aLitBuckets^[285] * (aCodeLens[285] + 16));\n\n  {add in all the bits needed to compress the distances}\n  for Symbol := 0 to pred(aDistCount) do\n    inc(Result, aDistBuckets^[Symbol] *\n                (aCodeLens[aLitCount + Symbol] +\n                 dfc_DistExtraBits[Symbol]));\nend;\n{====================================================================}\n\n\n{====================================================================}\nprocedure OutputEndOfBlock(aBitStrm : TAbDfOutBitStream;\n                           aLitTree : TAbDfDecodeHuffmanTree);\nvar\n  Code : longint;\nbegin\n  {note: this routine encodes the end-of-block character (symbol 256)\n         and then writes out the code to the bit stream}\n\n  {encode the end-of-block character as a symbol}\n  {$IFOPT C+} {if Assertions are on }\n  Code := aLitTree.Encode(256);\n  {$ELSE}\n  Code := aLitTree.Encodes^[256];\n  {$ENDIF}\n\n  {write the code out to the bit stream}\n  aBitStrm.WriteBits(Code and $FFFF, (Code shr 16) and $FF);\nend;\n{--------}\nprocedure EncodeLZStreamStored(aFinalBlock   : boolean;\n                               aStream       : TAbDfLZStream;\n                               aBitStrm      : TAbDfOutBitStream;\n                               aDataSize     : integer;\n                               aLog          : TAbLogger);\nvar\n  BlockHeader : packed record\n    bhSize    : word;\n    bhNotSize : word;\n  end;\n  Buffer    : pointer;\n  Code      : integer;\n  BlockSize : integer;\nbegin\n  {note: this routine writes out an incompressible block to the bit\n         stream (the store algorithm)}\n\n  {allocate the maximum buffer we can write at once}\n  GetMem(Buffer, 64 * 1024);\n  try\n\n    {while there's more incompressible data to store...}\n    while (aDataSize <> 0) do begin\n\n      {calculate the block size to write this time}\n      if (aDataSize > $FFFF) then begin\n        BlockSize := $FFFF;\n        dec(aDataSize, $FFFF);\n      end\n      else begin\n        BlockSize := aDataSize;\n        aDataSize := 0;\n      end;\n\n      {$IFDEF UseLogging}\n      {log it}\n      if (aLog <> nil) then begin\n        aLog.WriteLine('..Writing new block...');\n        aLog.WriteLine(Format('..final block? %d', [ord(aFinalBlock)]));\n        aLog.WriteLine('..block type? 0');\n        aLog.WriteLine(Format('..block size:  %d', [BlockSize]));\n      end;\n      {$ENDIF}\n\n      {output the block information to the bit stream}\n      if aFinalBlock then\n        Code := 1 + (0 shl 1)\n      else\n        Code := 0 + (0 shl 1);\n      aBitStrm.WriteBits(Code, 3);\n\n      {align the bit stream to the nearest byte}\n      aBitStrm.AlignToByte;\n\n      {write the stored block header}\n      BlockHeader.bhSize := BlockSize;\n      BlockHeader.bhNotSize := not BlockHeader.bhSize;\n      aBitStrm.WriteBuffer(BlockHeader, sizeof(BlockHeader));\n\n      {get and write this block}\n      aStream.ReadStoredBuffer(Buffer^, BlockSize);\n      aBitStrm.WriteBuffer(Buffer^, BlockSize);\n    end;\n  finally\n    FreeMem(Buffer);\n  end;\n\n  {clear the stream, ready for the next block}\n  aStream.Clear;\nend;\n{--------}\nprocedure EncodeLZStreamStatic(aFinalBlock   : boolean;\n                               aUseDeflate64 : boolean;\n                               aStream       : TAbDfLZStream;\n                               aBitStrm      : TAbDfOutBitStream;\n                               aLog          : TAbLogger);\nvar\n  Code : integer;\nbegin\n  {note: this routine writes out the stream of LZ77 tokens for the\n         current block to the bit stream, using the static huffman\n         trees to encode the token symbols}\n\n  {$IFDEF UseLogging}\n  {log it}\n  if (aLog <> nil) then begin\n    aLog.WriteLine('..Writing new block...');\n    aLog.WriteLine(Format('..final block? %d', [ord(aFinalBlock)]));\n    aLog.WriteLine('..block type? 1');\n  end;\n  {$ENDIF}\n\n  {output the block information to the bit stream}\n  if aFinalBlock then\n    Code := 1 + (1 shl 1)\n  else\n    Code := 0 + (1 shl 1);\n  aBitStrm.WriteBits(Code, 3);\n\n  {encode the LZ77 stream}\n  aStream.Encode(aBitStrm,\n                 AbStaticLiteralTree, AbStaticDistanceTree,\n                 aUseDeflate64);\n\n  {output the end-of-block marker to the bit stream}\n  OutputEndOfBlock(aBitStrm, AbStaticLiteralTree);\n  {$IFDEF UseLogging}\n  if (aLog <> nil) then\n    aLog.WriteLine('Char: end-of-block marker (#256)');\n  {$ENDIF}\nend;\n{--------}\nprocedure EncodeLZStreamDynamic(aFinalBlock   : boolean;\n                                aUseDeflate64 : boolean;\n                                aUseBest      : boolean;\n                                aStream       : TAbDfLZStream;\n                                aBitStrm      : TAbDfOutBitStream;\n                                aLog          : TAbLogger);\nvar\n  i : integer;\n  LitTree     : TAbDfDecodeHuffmanTree;\n  DistTree    : TAbDfDecodeHuffmanTree;\n  CodeLenTree : TAbDfDecodeHuffmanTree;\n  CodeLenStream : TAbDfCodeLenStream;\n  CodeLens      : array [0..285+32] of integer;\n  CLCodeLens    : array [0..18] of integer;\n  LitCodeCount  : integer;\n  DistCodeCount : integer;\n  LenCodeCount  : integer;\n  BitCount      : integer;\n  Code          : integer;\n  StaticSize    : integer;\n  StoredSize    : integer;\nbegin\n  {note: this routine writes out the stream of LZ77 tokens for the\n         current block to the bit stream, using the dynamic huffman\n         trees to encode the token symbols; if the routine determines\n         that the data can better be compressed using the static\n         huffman trees or should be stored as is, it'll switch\n         algorithms}\n\n  {prepare for the try..finally}\n  LitTree := nil;\n  DistTree := nil;\n  CodeLenTree := nil;\n  CodeLenStream := nil;\n\n  try\n\n    {calculate the code lengths for the literal symbols}\n    GenerateCodeLengths(15, aStream.LitBuckets^, CodeLens, 0, aLog);\n\n    {calculate the number of the used codelengths for the literals}\n    LitCodeCount := 286;\n    repeat\n      dec(LitCodeCount);\n    until (CodeLens[LitCodeCount] <> 0);\n    inc(LitCodeCount);\n\n    {calculate the code lengths for the distance symbols}\n    GenerateCodeLengths(15, aStream.DistBuckets^, CodeLens,\n                                                  LitCodeCount, aLog);\n\n    {calculate the number of the used codelengths for the distances}\n    DistCodeCount := 32;\n    repeat\n      dec(DistCodeCount);\n    until (CodeLens[DistCodeCount + LitCodeCount] <> 0);\n    inc(DistCodeCount);\n\n    {calculate the code lengths array as a stream of items}\n    CodeLenStream := TAbDfCodeLenStream.Create(aLog);\n    CodeLenStream.Build(CodeLens, LitCodeCount + DistCodeCount);\n\n    {calculate the codelengths for the code lengths}\n    GenerateCodeLengths(7, CodeLenStream.Buckets^, CLCodeLens, 0, nil);\n\n    {calculate the number of the used codelengths for the code lengths}\n    LenCodeCount := 19;\n    repeat\n      dec(LenCodeCount);\n    until (CLCodeLens[dfc_CodeLengthIndex[LenCodeCount]] <> 0);\n    inc(LenCodeCount);\n    {..there's a minimum of four, though}\n    if (LenCodeCount < 4) then\n      LenCodeCount := 4;\n\n    {if we have to work out and use the best method...}\n    if aUseBest then begin\n\n      {calculate the number of bits required for the compressed data\n       using dynamic huffman trees}\n      BitCount := CalcDynamicBitCount(aUseDeflate64,\n                                      aStream.LitBuckets,\n                                      aStream.DistBuckets,\n                                      CodeLenStream.Buckets,\n                                      CodeLens,\n                                      CLCodeLens,\n                                      LitCodeCount,\n                                      DistCodeCount,\n                                      LenCodeCount);\n\n      {choose the algorithm with the smallest size}\n      StaticSize := aStream.StaticSize;\n      StoredSize := (aStream.StoredSize + 4) * 8;\n      if (StaticSize < BitCount) then begin\n        if (StoredSize < StaticSize) then\n          EncodeLZStreamStored(aFinalBlock, aStream, aBitStrm,\n                               (StoredSize div 8) - 4, aLog)\n        else\n          EncodeLZStreamStatic(aFinalBlock, aUseDeflate64,\n                               aStream, aBitStrm, aLog);\n        Exit;\n      end\n      else if (StoredSize < BitCount) then begin\n        EncodeLZStreamStored(aFinalBlock, aStream, aBitStrm,\n                             (StoredSize div 8) - 4, aLog);\n        Exit;\n      end;\n    end;\n\n    {create the code lengths tree}\n    CodeLenTree := TAbDfDecodeHuffmanTree.Create(19, 7, huEncoding);\n    CodeLenTree.Build(CLCodeLens, 0, 19, [0], $FFFF);\n\n    {$IFDEF UseLogging}\n    {log the tree}\n    if (aLog <> nil) then begin\n      aLog.WriteLine('Code lengths tree');\n      CodeLenTree.DebugPrint(aLog);\n    end;\n    {$ENDIF}\n\n    {calculate the literal encoding tree}\n    LitTree := TAbDfDecodeHuffmanTree.Create(286, 15, huEncoding);\n    LitTree.Build(CodeLens, 0, LitCodeCount,\n                                  dfc_LitExtraBits, dfc_LitExtraOffset);\n\n    {$IFDEF UseLogging}\n    {log the tree}\n    if (aLog <> nil) then begin\n      aLog.WriteLine('Literal/length tree');\n      LitTree.DebugPrint(aLog);\n    end;\n    {$ENDIF}\n\n    {calculate the distance tree}\n    if aUseDeflate64 then\n      DistTree := TAbDfDecodeHuffmanTree.Create(32, 15, huEncoding)\n    else\n      DistTree := TAbDfDecodeHuffmanTree.Create(30, 15, huEncoding);\n    DistTree.Build(CodeLens, LitCodeCount, DistCodeCount,\n                                dfc_DistExtraBits, dfc_DistExtraOffset);\n\n    {$IFDEF UseLogging}\n    if (aLog <> nil) then begin\n      {log the tree}\n      aLog.WriteLine('Distance tree');\n      DistTree.DebugPrint(aLog);\n\n      {log the new block}\n      aLog.WriteLine('..Writing new block...');\n      aLog.WriteLine(Format('..final block? %d', [ord(aFinalBlock)]));\n      aLog.WriteLine('..block type? 2');\n      aLog.WriteLine(Format('Count of literals:     %d', [LitCodeCount]));\n      aLog.WriteLine(Format('Count of distances:    %d', [DistCodeCount]));\n      aLog.WriteLine(Format('Count of code lengths: %d', [LenCodeCount]));\n    end;\n    {$ENDIF}\n\n    {output the block information to the bit stream}\n    if aFinalBlock then\n      Code := 1 + (2 shl 1)\n    else\n      Code := 0 + (2 shl 1);\n    aBitStrm.WriteBits(Code, 3);\n\n    {output the various counts to the bit stream}\n    Code := (LitCodeCount - 257) +\n            ((DistCodeCount - 1) shl 5) +\n            ((LenCodeCount - 4) shl 10);\n    aBitStrm.WriteBits(Code, 14);\n\n    {output the code length codelengths to the bit stream}\n    for i := 0 to pred(LenCodeCount) do\n      aBitStrm.WriteBits(CLCodeLens[dfc_CodeLengthIndex[i]], 3);\n\n    {encode and write the codelength stream to the bit stream}\n    CodeLenStream.Encode(aBitStrm, CodeLenTree);\n\n    {encode and write the LZ77 stream to the bit stream}\n    aStream.Encode(aBitStrm, LitTree, DistTree, aUseDeflate64);\n\n    {output the end-of-block marker to the bit stream}\n    OutputEndOfBlock(aBitStrm, LitTree);\n    {$IFDEF UseLogging}\n    if (aLog <> nil) then\n      aLog.WriteLine('Char: end-of-block marker (#256)');\n    {$ENDIF}\n\n  finally\n    LitTree.Free;\n    DistTree.Free;\n    CodeLenTree.Free;\n    CodeLenStream.Free;\n  end;\nend;\n{====================================================================}\n\n\n{===Single algorithm Static/Dynamic Huffman tree deflate=============}\nfunction DeflateStaticDynamic(aStatic : boolean;\n                              aUseBest: boolean;\n                              aSource : TStream; aDest : TStream;\n                              aHelper : TAbDeflateHelper;\n                              aLog    : TAbLogger) : longint;\nvar\n  i : integer;\n  SlideWin     : TAbDfInputWindow;\n  BitStrm      : TAbDfOutBitStream;\n  LZ77Stream   : TAbDfLZStream;\n  KeyLen       : integer;\n  Match        : TAbDfMatch;\n  PrevMatch    : TAbDfMatch;\n  UseDeflate64 : boolean;\n  UseCRC32     : boolean;\n  GotMatch     : boolean;\n  LZStrmIsFull : boolean;\n  TestForBinary: boolean;\nbegin\n  {note: turn on the following define to see when and how the lazy\n         matching algorithm works}\n  {$IFDEF UseLogging}\n    {$DEFINE UseLazyMatchLogging}\n  {$ENDIF}\n\n  {$IFDEF UseLogging}\n  if (aLog <> nil) then\n    if aStatic then\n      aLog.WriteLine('..compressing source data with static huffman trees')\n    else\n      aLog.WriteLine('..compressing source data with dynamic huffman trees');\n  {$ENDIF}\n\n  {prepare for the try..finally}\n  SlideWin := nil;\n  BitStrm := nil;\n  LZ77Stream := nil;\n  try\n\n    {create the sliding window}\n    UseDeflate64 := (aHelper.Options and dfc_UseDeflate64) <> 0;\n    UseCRC32 := (aHelper.Options and dfc_UseAdler32) = 0;\n    SlideWin := TAbDfInputWindow.Create(aSource,\n                                        aHelper.StreamSize,\n                                        aHelper.WindowSize,\n                                        aHelper.ChainLength,\n                                        UseDeflate64, UseCRC32);\n    SlideWin.OnProgress := aHelper.OnProgressStep;\n\n    {create the bit stream}\n    BitStrm := TAbDfOutBitStream.Create(aDest);\n\n    {create the LZ77 stream}\n    LZ77Stream := TAbDfLZStream.Create(SlideWin, UseDeflate64, aLog);\n    LZStrmIsFull := false;\n    TestForBinary := true;\n\n    {set the previous match to be a literal character: this will\n     ensure that no lazy matching goes on with the first key read}\n    PrevMatch.maLen := 0;\n\n    {get the first key length}\n    KeyLen := SlideWin.GetNextKeyLength;\n\n    {while the current key is three characters long...}\n    while (KeyLen = 3) do begin\n\n      {tweak for binary/text}\n      {note: the test for whether a stream is binary or not is to\n             check whether there are any #0 characters in the first\n             1024 bytes: if there are the stream is binary.\n             this test and tweaking is based on experimentation\n             compression ratios for binary and text files based on the\n             PKZIP 'n' option.}\n      if TestForBinary and (LZ77Stream.StoredSize = 1024) then begin\n        if (aHelper.PKZipOption = 'n') then\n          if (LZ77Stream.LitBuckets^[0] = 0) then begin\n            aHelper.AmpleLength := aHelper.AmpleLength * 2;\n            aHelper.MaxLazyLength := aHelper.MaxLazyLength * 2;\n            aHelper.ChainLength := aHelper.ChainLength * 2;\n            SlideWin.ChainLen := aHelper.ChainLength;\n          end;\n        TestForBinary := false;\n      end;\n\n      {if the LZ77 stream is full, empty it}\n      if LZStrmIsFull then begin\n        if aStatic then\n          EncodeLZStreamStatic(false, UseDeflate64,\n                               LZ77Stream, BitStrm, aLog)\n        else\n          EncodeLZStreamDynamic(false, UseDeflate64, aUseBest,\n                                LZ77Stream, BitStrm, aLog);\n        LZ77Stream.Clear;\n        LZStrmIsFull := false;\n      end;\n\n      {try and find a match of three or more characters (note: this\n       has the side effect of adding the current key to the internal\n       hash table); this routine will only return true if it finds a\n       match greater than the previous match}\n      GotMatch := SlideWin.FindLongestMatch(aHelper.AmpleLength,\n                                            Match, PrevMatch);\n\n      {if the maximum match length were three and the distance exceeds\n       4096 bytes, it's most likely that we'll get better compression\n       by outputting the three literal bytes rather than by outputting\n       a length symbol, a distance symbol, and at least ten extra\n       bits for the extra distance value}\n      if (Match.maLen = 3) and (Match.maDist > 4096) then\n        GotMatch := false;\n\n      {if we found a match...}\n      if GotMatch then begin\n\n        {if there were no previous match, we can't do any lazy match\n         processing now, so save the current match details ready for\n         lazy matching the next time through, and advance the sliding\n         window}\n        if (PrevMatch.maLen = 0) then begin\n          PrevMatch.maLen := Match.maLen;\n          PrevMatch.maDist := Match.maDist;\n          PrevMatch.maLit := Match.maLit;\n          SlideWin.AdvanceByOne;\n        end\n\n        {otherwise the previous match is smaller than this one, so\n         we're going to accept this match in preference; throw away\n         the previous match, output the previous literal character\n         instead and save these match details}\n        else begin\n          {$IFDEF UseLazyMatchLogging}\n          if (aLog <> nil) then\n            aLog.WriteLine(\n               Format(\n                  '..this match longer, rejecting previous one (%d,%d)',\n                  [PrevMatch.maLen, PrevMatch.maDist]));\n          {$ENDIF}\n          LZStrmIsFull := LZ77Stream.AddLiteral(PrevMatch.maLit);\n          PrevMatch.maLen := Match.maLen;\n          PrevMatch.maDist := Match.maDist;\n          PrevMatch.maLit := Match.maLit;\n          SlideWin.AdvanceByOne;\n        end;\n\n        {if, by this point, we're storing up a match, check to see\n         if it equals or exceeds the maximum lazy match length; if\n         it does then output the match right now and avoid checking\n         for a lazy match}\n        if (PrevMatch.maLen >= aHelper.MaxLazyLength) then begin\n          {$IFDEF UseLazyMatchLogging}\n          if (aLog <> nil) then\n            if ((aHelper.Options and dfc_UseLazyMatch) <> 0) then\n              aLog.WriteLine('..match longer than max lazy match, using it');\n          {$ENDIF}\n          LZStrmIsFull :=\n             LZ77Stream.AddLenDist(PrevMatch.maLen, PrevMatch.maDist);\n          SlideWin.Advance(PrevMatch.maLen - 1, PrevMatch.maLen - 1);\n          PrevMatch.maLen := 0;\n        end;\n      end\n\n      {otherwise, we don't have a match at all: so we possibly just\n       need to output a literal character}\n      else begin\n        {if there was a previous match, output it and discard the\n         results of this match}\n        if (PrevMatch.maLen <> 0) then begin\n          LZStrmIsFull :=\n             LZ77Stream.AddLenDist(PrevMatch.maLen, PrevMatch.maDist);\n          SlideWin.Advance(PrevMatch.maLen - 1, PrevMatch.maLen - 2);\n          PrevMatch.maLen := 0;\n        end\n\n        {otherwise there was no previous match or it's already been\n         output, so output this literal}\n        else begin\n          LZStrmIsFull := LZ77Stream.AddLiteral(Match.maLit);\n          SlideWin.AdvanceByOne;\n          PrevMatch.maLen := 0;\n        end;\n      end;\n\n      {get the next key}\n      KeyLen := SlideWin.GetNextKeyLength;\n    end;\n\n    {if the last key read were one or two characters in length, save\n     them as literal character encodings}\n    if (KeyLen > 0) then begin\n      {if there's a match pending, it'll be of length 3: output it}\n      if (PrevMatch.maLen <> 0) then begin\n        Assert(PrevMatch.maLen = 3,\n               'DeflateStaticDynamic: previous match should be length 3');\n        LZ77Stream.AddLenDist(PrevMatch.maLen, PrevMatch.maDist);\n      end\n      {otherwise, output the one or two final literals}\n      else\n        for i := 1 to KeyLen do\n          LZ77Stream.AddLiteral(SlideWin.GetNextChar);\n    end;\n\n    {empty the LZ77 stream}\n    if aStatic then\n      EncodeLZStreamStatic(true, UseDeflate64,\n                           LZ77Stream, BitStrm, aLog)\n    else\n      EncodeLZStreamDynamic(true, UseDeflate64, aUseBest,\n                            LZ77Stream, BitStrm, aLog);\n\n    {calculate the checksum of the input stream}\n    Result := SlideWin.Checksum;\n  finally\n    {free the objects}\n    SlideWin.Free;\n    BitStrm.Free;\n    LZ77Stream.Free;\n  end;{try..finally}\n\n  {$IFDEF UseLogging}\n  {log it}\n  if (aLog <> nil) then\n    aLog.WriteLine(Format('..checksum: %8x', [Result]))\n  {$ENDIF}\nend;\n{====================================================================}\n\n\n{===Simple storing===================================================}\nfunction DeflateStored(aSource : TStream; aDest : TStream;\n                       aHelper : TAbDeflateHelper;\n                       aLog    : TAbLogger) : longint;\nconst\n  StoredBlockSize = $FFFF;\nvar\n  Buffer    : PAnsiChar;\n  BytesRead : LongWord;\n  ByteCount : Int64;\n  BytesToGo : Int64;\n  CurPos    : Int64;\n  Size      : Int64;\n  Percent   : longint;\n  CheckSum  : longint;\n  UseCRC32  : boolean;\n  BlockHeader : packed record\n    bhInfo    : byte;\n    bhSize    : word;\n    bhNotSize : word;\n  end;\nbegin\n  {note: this routine merely stores the aSource stream data, no\n         compression is attempted or done}\n  {$IFDEF UseLogging}\n  if (aLog <> nil) then\n    aLog.WriteLine('..storing source data to destination, no compression');\n  {$ENDIF}\n\n  {initialize}\n  ByteCount := 0;\n  UseCRC32 := (aHelper.Options and dfc_UseAdler32) = 0;\n  if UseCRC32 then\n    Checksum := -1  { CRC32 starts off with all bits set}\n  else\n    CheckSum := 1;  { Adler32 starts off with a value of 1}\n  if (aHelper.StreamSize > 0) then\n    BytesToGo := aHelper.StreamSize\n  else begin\n    CurPos := aSource.Seek(0, soCurrent);\n    Size := aSource.Seek(0, soEnd);\n    aSource.Seek(CurPos, soBeginning);\n    BytesToGo := Size - CurPos;\n  end;\n\n  {get a buffer}\n  GetMem(Buffer, StoredBlockSize);\n  try\n\n    {while there is still data to be stored...}\n    while (BytesToGo <> 0) do begin\n\n      {read the next block}\n      BytesRead := aSource.Read(Buffer^, StoredBlockSize);\n\n      {fire the progress event}\n      if Assigned(aHelper.OnProgressStep) then begin\n        inc(ByteCount, BytesRead);\n        Percent := Round((100.0 * ByteCount) / aHelper.StreamSize);\n        aHelper.OnProgressStep(Percent);\n      end;\n\n      {update the checksum}\n      if UseCRC32 then\n        AbUpdateCRCBuffer(Checksum, Buffer^, BytesRead)\n      else\n        AbUpdateAdlerBuffer(Checksum, Buffer^, BytesRead);\n\n      {write the block header}\n      if (BytesRead = BytesToGo) then\n        BlockHeader.bhInfo := 1  {ie, final block, stored}\n      else\n        BlockHeader.bhInfo := 0; {ie, not final block, stored}\n      BlockHeader.bhSize := BytesRead;\n      BlockHeader.bhNotSize := not BlockHeader.bhSize;\n      aDest.WriteBuffer(BlockHeader, sizeof(BlockHeader));\n\n      {write the block of data}\n      aDest.WriteBuffer(Buffer^, BytesRead);\n\n      {$IFDEF UseLogging}\n      {log it}\n      if (aLog <> nil) then begin\n        if (BlockHeader.bhInfo = 0) then\n          aLog.WriteLine(Format('..block size: %d', [BytesRead]))\n        else\n          aLog.WriteLine(Format('..block size: %d (final block)',\n                                [BytesRead]));\n      end;\n      {$ENDIF}\n\n      {decrement the number of bytes to go}\n      dec(BytesToGo, BytesRead);\n    end;\n  finally\n    FreeMem(Buffer);\n  end;\n\n  {return the checksum}\n  {note: the CRC32 checksum algorithm requires a post-conditioning\n         step after being calculated (the result is NOTted), whereas\n         Adler32 does not}\n  if UseCRC32 then\n    Result := not Checksum\n  else\n    Result := Checksum;\n\n  {$IFDEF UseLogging}\n  {log it}\n  if (aLog <> nil) then\n    aLog.WriteLine(Format('..checksum: %8x', [Result]))\n  {$ENDIF}\nend;\n{====================================================================}\n\n\n{===Interfaced routine===============================================}\nfunction Deflate(aSource : TStream; aDest : TStream;\n                 aHelper : TAbDeflateHelper) : longint;\nvar\n  Helper   : TAbDeflateHelper;\n  Log      : TAbLogger;\n  SourceStartPos : longint;\n  DestStartPos   : longint;\nbegin\n  {pre-conditions: streams are allocated,\n                   options enable some kind of archiving}\n  Assert(aSource <> nil, 'Deflate: aSource stream cannot be nil');\n  Assert(aDest <> nil, 'Deflate: aDest stream cannot be nil');\n  Assert((aHelper = nil) or ((aHelper.Options and $07) <> 0),\n         'Deflate: aHelper.Options must enable some kind of archiving');\n\n  {$IFDEF DefeatWarnings}\n  Result := 0;\n  {$ENDIF}\n\n  {prepare for the try..finally}\n  Helper := nil;\n  Log := nil;\n\n  try {finally}\n    try {except}\n      {create our helper; assign the passed one to it}\n      Helper := TAbDeflateHelper.Create;\n      if (aHelper <> nil) then\n        Helper.Assign(aHelper);\n\n      {save the current positions of both streams}\n      SourceStartPos := aSource.Position;\n      DestStartPos := aDest.Position;\n\n      {if the helper's stream size is -1, and it has a progress event\n       handler, calculate the stream size from the stream itself}\n      if Assigned(Helper.OnProgressStep) then begin\n        if (Helper.StreamSize = -1) then\n          Helper.StreamSize := aSource.Size;\n      end\n\n      {otherwise we certainly can't do any progress reporting}\n      else begin\n        Helper.OnProgressStep := nil;\n        Helper.StreamSize := 0;\n      end;\n\n      {if lazy matching is not requested, ensure the maximum lazy\n       match length is zero: this make the LZ77 code a little easier\n       to understand}\n      if ((Helper.Options and dfc_UseLazyMatch) = 0) then\n        Helper.MaxLazyLength := 0;\n\n      {patch up the various lengths in the helper if they specify the\n       maximum (that is, are equal to -1)}\n      if (Helper.AmpleLength = -1) then\n        Helper.AmpleLength := MaxLongInt;\n      if (Helper.MaxLazyLength = -1) then\n        Helper.MaxLazyLength := MaxLongInt;\n      if (Helper.ChainLength = -1) then\n        Helper.ChainLength := MaxLongInt;\n\n      {create the logger, if requested}\n      if (Helper.LogFile <> '') then begin\n        Log := TAbLogger.Create(Helper.LogFile);\n        Log.WriteLine('DEFLATING STREAM...');\n        {$IFNDEF UseLogging}\n        Log.WriteLine('Need to recompile the app with UseLogging turned on');\n        {$ENDIF}\n      end;\n\n      {use the helper's options property to decide what to do}\n      case (Helper.Options and $07) of\n        dfc_CanUseStored :\n          Result := DeflateStored(aSource, aDest, Helper, Log);\n        dfc_CanUseStatic :\n          Result := DeflateStaticDynamic(true, false, aSource, aDest, Helper, Log);\n        dfc_CanUseDynamic :\n          Result := DeflateStaticDynamic(false, false, aSource, aDest, Helper, Log);\n      else\n        Result := DeflateStaticDynamic(false, true, aSource, aDest, Helper, Log);\n      end;\n\n      {save the uncompressed and compressed sizes}\n      if (aHelper <> nil) then begin\n        aHelper.NormalSize := aSource.Position - SourceStartPos;\n        aHelper.CompressedSize := aDest.Position - DestStartPos;\n      end;\n    except\n      on E : EAbInternalDeflateError do begin\n        {$IFDEF UseLogging}\n        if (Log <> nil) then\n          Log.WriteLine(Format('Internal exception raised: %s',\n                                [E.Message]));\n        {$ENDIF}\n        raise EAbDeflateError.Create(E.Message);\n      end;\n    end;\n  finally\n    Helper.Free;\n    Log.Free;\n  end;\n  {WARNING NOTE: the compiler will warn that the return value of this\n                 function might be undefined. However, it is wrong: it\n                 has been fooled by the code. If you don't want to see\n                 this warning again, enable the DefeatWarnings\n                 compiler define in AbDefine.inc.}\nend;\n{====================================================================}\n\nend.\n\n"
  },
  {
    "path": "lib/abbrevia/source/AbDfHufD.pas",
    "content": "(* ***** BEGIN LICENSE BLOCK *****\n * Version: MPL 1.1\n *\n * The contents of this file are subject to the Mozilla Public License Version\n * 1.1 (the \"License\"); you may not use this file except in compliance with\n * the License. You may obtain a copy of the License at\n * http://www.mozilla.org/MPL/\n *\n * Software distributed under the License is distributed on an \"AS IS\" basis,\n * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License\n * for the specific language governing rights and limitations under the\n * License.\n *\n * The Original Code is TurboPower Abbrevia\n *\n * The Initial Developer of the Original Code is\n * TurboPower Software\n *\n * Portions created by the Initial Developer are Copyright (C) 1997-2002\n * the Initial Developer. All Rights Reserved.\n *\n * Contributor(s):\n *\n * ***** END LICENSE BLOCK ***** *)\n\n{*********************************************************}\n{* ABBREVIA: AbDfHufD.pas                                *}\n{*********************************************************}\n{* Deflate Huffman tree for decoder                      *}\n{*********************************************************}\n\nunit AbDfHufD;\n\n{$I AbDefine.inc}\n\n{Activate this compiler define and rebuild if you want the complete\n huffman tree output to print to the current log. The output is\n voluminous to say the least...}\n{$IFDEF UseLogging}\n{.$DEFINE EnableMegaLog}\n{$ENDIF}\n\n{Notes:\n\nThe object of this class is to build a decoder array, not to build a\nHuffman tree particularly. We don't want to decode huffman strings bit\nby bit. moving down the Huffman tree sometimes left, sometimes right.\nInstead we want to grab a set of bits and look them up in an array.\nSometimes we'll grab too many bits, sure, but we can deal with that\nlater. So, the object of the exercise is to calculate the code for a\nsymbol, reverse it ('cos that's how the input bit stream will present\nit to us) and set that element of the array to the decoded symbol\nvalue (plus some extra information: bit lengths).\n\nIf the alphabet size were 19 (the codelengths huffman tree) and the\nmaximum code length 5, for example, the decoder array would be 2^5\nelements long, much larger than the alphabet size. The user of this\nclass will be presenting sets of 5 bits for us to decode. We would\nlike to look up these 5 bits in the array (as an index) and have the\nsymbol returned. Now, since the alphabet size is much less than the\nnumber of elements in the decoder array, we must set the other\nelements in the array as well. Consider a symbol that has a code of\n110 in this scenario. The reversed code is 011, or 3, so we'd be\nsetting element 3. However we should also be setting elements 01011,\n10011, and 11011 to this symbol information as well, since the lookup\nwill be 5 bits long.\n\nBecause the code is a huffman code from a prefix tree, we won't get\nany index clashes between actual codes by this \"filling in\" process.\n\nFor the codelength Huffman tree, the maximum code length is at most 7.\nThis equates to a 128 element array. For the literal and distance\ntrees, the max code length is at most 15. This equates to a 32768\nelement array.\n\nFor a given lookup value the decoder will return a 32-bit value. The\nlower 16 bits is the decoded symbol, the next 8 bits is the code\nlength for that symbol, the last 8 bits (the most significant) are the\nnumber of extra bits that must be extracted from the input bit stream.\n}\n\ninterface\n\nuses\n  AbDfBase;\n\ntype\n  TAbDfHuffmanUsage = (   {usage of a huffman decoder..}\n       huEncoding,        {..encoding}\n       huDecoding,        {..decoding}\n       huBoth);           {..both (used for static trees)}\n\n  TAbDfDecodeHuffmanTree = class\n    private\n      FAlphaSize     : integer;\n      FDecodes       : PAbDfLongintList;\n      FDefMaxCodeLen : integer;\n      FEncodes       : PAbDfLongintList;\n      {$IFOPT C+}\n      FMask          : integer;\n      {$ENDIF}\n      FMaxCodeLen    : integer;\n      FUsage         : TAbDfHuffmanUsage;\n    protected\n    public\n      constructor Create(aAlphabetSize : integer;\n                         aDefMaxCodeLen: integer;\n                         aUsage        : TAbDfHuffmanUsage);\n      destructor Destroy; override;\n\n      procedure Build(const aCodeLengths : array of integer;\n                            aStartInx    : integer;\n                            aCount       : integer;\n                      const aExtraBits   : array of byte;\n                            aExtraOffset : integer);\n      function Decode(aLookupBits : integer) : longint;\n      function Encode(aSymbol : integer) : longint;\n\n      {$IFDEF UseLogging}\n      procedure DebugPrint(aLog : TAbLogger);\n      {$ENDIF}\n\n      property LookupBitLength : integer read FMaxCodeLen;\n      property Decodes : PAbDfLongintList read FDecodes;\n      property Encodes : PAbDfLongintList read FEncodes;\n  end;\n\nvar\n  AbStaticLiteralTree  : TAbDfDecodeHuffmanTree;\n  AbStaticDistanceTree : TAbDfDecodeHuffmanTree;\n\nimplementation\n\nuses\n  SysUtils;\n\nconst\n  PowerOfTwo : array [0..dfc_MaxCodeLength] of integer =\n               (1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048,\n                4096, 8192, 16384, 32768);\n\n{===Debug helper routine=============================================}\n{$IFDEF EnableMegaLog}\nfunction CodeToStr(aCode : longint; aLen : integer) : string;\nvar\n  i : integer;\nbegin\n  if (aLen = 0) then\n    Result := 'no code'\n  else begin\n    SetLength(Result, 32);\n    FillChar(Result[1], 32, ' ');\n    for i := 32 downto (33-aLen) do begin\n      if Odd(aCode) then\n        Result[i] := '1'\n      else\n        Result[i] := '0';\n      aCode := aCode shr 1;\n    end;\n  end;\nend;\n{$ENDIF}\n{====================================================================}\n\n\n{===TAbDfDecodeHuffmanTree===========================================}\nconstructor TAbDfDecodeHuffmanTree.Create(\n                                 aAlphabetSize : integer;\n                                 aDefMaxCodeLen: integer;\n                                 aUsage        : TAbDfHuffmanUsage);\nbegin\n  {protect against dumb programming mistakes}\n  Assert(aAlphabetSize >= 2,\n         'TAbDfDecodeHuffmanTree.Create: a huffman tree must be for at least two symbols');\n\n  {let the ancestor initialize}\n  inherited Create;\n\n  {save the alphabet size, etc}\n  FAlphaSize := aAlphabetSize;\n  FDefMaxCodeLen := aDefMaxCodeLen;\n  FUsage := aUsage;\n\n  {allocate the encoder array (needs to be initialized to zeros)}\n  if (aUsage <> huDecoding) then\n    FEncodes := AllocMem(FAlphaSize * sizeof(longint));\nend;\n{--------}\ndestructor TAbDfDecodeHuffmanTree.Destroy;\nbegin\n  {destroy the codes arrays}\n  if (FDecodes <> nil) then\n    FreeMem(FDecodes);\n  if (FEncodes <> nil) then\n    FreeMem(FEncodes);\n\n  {let the ancestor die}\n  inherited Destroy;\nend;\n{--------}\nprocedure TAbDfDecodeHuffmanTree.Build(\n                                const aCodeLengths : array of integer;\n                                      aStartInx    : integer;\n                                      aCount       : integer;\n                                const aExtraBits   : array of byte;\n                                      aExtraOffset : integer);\nconst\n  ByteRevTable : array [0..255] of byte = (\n   $00, $80, $40, $C0, $20, $A0, $60, $E0, $10, $90, $50, $D0,\n   $30, $B0, $70, $F0, $08, $88, $48, $C8, $28, $A8, $68, $E8,\n   $18, $98, $58, $D8, $38, $B8, $78, $F8, $04, $84, $44, $C4,\n   $24, $A4, $64, $E4, $14, $94, $54, $D4, $34, $B4, $74, $F4,\n   $0C, $8C, $4C, $CC, $2C, $AC, $6C, $EC, $1C, $9C, $5C, $DC,\n   $3C, $BC, $7C, $FC, $02, $82, $42, $C2, $22, $A2, $62, $E2,\n   $12, $92, $52, $D2, $32, $B2, $72, $F2, $0A, $8A, $4A, $CA,\n   $2A, $AA, $6A, $EA, $1A, $9A, $5A, $DA, $3A, $BA, $7A, $FA,\n   $06, $86, $46, $C6, $26, $A6, $66, $E6, $16, $96, $56, $D6,\n   $36, $B6, $76, $F6, $0E, $8E, $4E, $CE, $2E, $AE, $6E, $EE,\n   $1E, $9E, $5E, $DE, $3E, $BE, $7E, $FE, $01, $81, $41, $C1,\n   $21, $A1, $61, $E1, $11, $91, $51, $D1, $31, $B1, $71, $F1,\n   $09, $89, $49, $C9, $29, $A9, $69, $E9, $19, $99, $59, $D9,\n   $39, $B9, $79, $F9, $05, $85, $45, $C5, $25, $A5, $65, $E5,\n   $15, $95, $55, $D5, $35, $B5, $75, $F5, $0D, $8D, $4D, $CD,\n   $2D, $AD, $6D, $ED, $1D, $9D, $5D, $DD, $3D, $BD, $7D, $FD,\n   $03, $83, $43, $C3, $23, $A3, $63, $E3, $13, $93, $53, $D3,\n   $33, $B3, $73, $F3, $0B, $8B, $4B, $CB, $2B, $AB, $6B, $EB,\n   $1B, $9B, $5B, $DB, $3B, $BB, $7B, $FB, $07, $87, $47, $C7,\n   $27, $A7, $67, $E7, $17, $97, $57, $D7, $37, $B7, $77, $F7,\n   $0F, $8F, $4F, $CF, $2F, $AF, $6F, $EF, $1F, $9F, $5F, $DF,\n   $3F, $BF, $7F, $FF);\nvar\n  i : integer;\n  Symbol      : integer;\n  LengthCount : array [0..dfc_MaxCodeLength] of integer;\n  NextCode    : array [0..dfc_MaxCodeLength] of integer;\n  Code        : longint;\n  CodeLen     : integer;\n  CodeData    : longint;\n  DecoderLen  : integer;\n  CodeIncr    : integer;\n  Decodes     : PAbDfLongintList;\n  Encodes     : PAbDfLongintList;\n  {$IFDEF CPU386}\n  DecodesEnd  : pointer;\n  {$ENDIF}\n  TablePtr    : pointer;\nbegin\n  {count the number of instances of each code length and calculate the\n   maximum code length at the same time}\n  FillChar(LengthCount, sizeof(LengthCount), 0);\n  FMaxCodeLen := 0;\n  for i := 0 to pred(aCount) do begin\n    CodeLen := aCodeLengths[i + aStartInx];\n    Assert((CodeLen <= FDefMaxCodeLen),\n           Format('TAbDfDecodeHuffmanTree.Build: a code length is greater than %d',\n                  [FDefMaxCodeLen]));\n    if (CodeLen > FMaxCodeLen) then\n      FMaxCodeLen := CodeLen;\n    inc(LengthCount[CodeLen]);\n  end;\n\n  {now we know the maximum code length we can allocate our decoder\n   array}\n  {$IFNDEF CPU386}\n  DecoderLen := 0;\n  {$ENDIF}\n  if (FUsage <> huEncoding) then begin\n    DecoderLen := PowerOfTwo[FMaxCodeLen];\n    GetMem(FDecodes, DecoderLen * sizeof(longint));\n    {$IFDEF CPU386}\n    DecodesEnd := PAnsiChar(FDecodes) + (DecoderLen * sizeof(longint));\n    {$ENDIF}\n    {$IFOPT C+}\n    FillChar(FDecodes^, DecoderLen * sizeof(longint), $FF);\n    FMask := not (DecoderLen - 1);\n    {$ENDIF}\n  end;\n\n  {calculate the start codes for each code length}\n  Code := 0;\n  LengthCount[0] := 0;\n  for i := 1 to FDefMaxCodeLen do begin\n    Code := (Code + LengthCount[i-1]) shl 1;\n    NextCode[i] := Code;\n  end;\n\n  {for speed and convenience}\n  Decodes := FDecodes;\n  Encodes := FEncodes;\n  TablePtr := @ByteRevTable;\n\n  {for each symbol...}\n  for Symbol := 0 to pred(aCount) do begin\n    {calculate the code length}\n    CodeLen := aCodeLengths[Symbol + aStartInx];\n\n    {if the code length were zero, just set the relevant entry in the\n     encoder array; the decoder array doesn't need anything}\n    if (CodeLen = 0) then begin\n      if (FUsage <> huDecoding) then\n        Encodes^[Symbol] := -1\n    end\n\n    {otherwise we need to fill elements in both the encoder and\n     decoder arrays}\n    else begin\n      {calculate *reversed* code}\n      Code := NextCode[CodeLen];\n      {$IFDEF CPU386}\n      asm\n        push esi\n        mov eax, Code\n        mov esi, TablePtr\n        xor ecx, ecx\n        xor edx, edx\n        mov cl, ah\n        mov dl, al\n        mov al, [esi+ecx]\n        mov ah, [esi+edx]\n        mov ecx, 16\n        pop esi\n        sub ecx, CodeLen\n        shr eax, cl\n        mov Code, eax\n      end;\n      {$ELSE}\n      CodeData:= Code;\n      LongRec(Code).Bytes[1]:= ByteRevTable[LongRec(CodeData).Bytes[0]];\n      LongRec(Code).Bytes[0]:= ByteRevTable[LongRec(CodeData).Bytes[1]];\n      Code:= Code shr (16-CodeLen);\n      {$ENDIF}\n\n      {set the code data (bit count, extra bits required, symbol),\n       everywhere the reversed code would appear in the decoder array;\n       set the code data in the encoder array as well}\n      if (Symbol >= aExtraOffset) then begin\n        if (FUsage <> huEncoding) then\n          CodeData := Symbol +                  { symbol}\n                      (CodeLen shl 16) +        { code length}\n                      (aExtraBits[Symbol-aExtraOffset] shl 24);\n                                                { extra bits required}\n        if (FUsage <> huDecoding) then\n          Encodes^[Symbol] := Code +            { code}\n                      (CodeLen shl 16) +        { code length}\n                      (aExtraBits[Symbol-aExtraOffset] shl 24)\n                                                { extra bits required}\n      end\n      else begin\n        if (FUsage <> huEncoding) then\n          CodeData := Symbol +                  { symbol}\n                      (CodeLen shl 16);         { code length}\n        if (FUsage <> huDecoding) then\n          Encodes^[Symbol] := Code +            { code}\n                      (CodeLen shl 16);         { code length}\n      end;\n\n      {OPTIMIZATION NOTE: the following code\n\n            CodeIncr := PowerOfTwo[CodeLen];\n            while Code < DecoderLen do begin\n              Decodes^[Code] := CodeData;\n              inc(Code, CodeIncr);\n            end;\n\n      was replaced by the asm code below to improve the speed. The\n      code in the loop is the big time sink in this routine so it was\n      best to replace it.}\n      if (FUsage <> huEncoding) then begin\n        {$IFDEF CPU386}\n        CodeIncr := PowerOfTwo[CodeLen] * sizeof(longint);\n        asm\n          push edi                { save edi}\n          mov eax, Decodes        { get the Decodes array}\n          mov edi, DecodesEnd     { get the end of the Decodes array}\n          mov edx, Code           { get Code and..}\n          shl edx, 1              { ..multiply by 4}\n          shl edx, 1\n          add eax, edx            { eax => first element to be set}\n          mov edx, CodeData       { get the CodeData}\n          mov ecx, CodeIncr       { get the increment per loop}\n        @@1:\n          mov [eax], edx          { set the element}\n          add eax, ecx            { move to the next element}\n          cmp eax, edi            { if we haven't gone past the end..}\n          jl @@1                  { ..go back for the next one}\n          pop edi                 { retrieve edi}\n        end;\n        {$ELSE}\n        CodeIncr := PowerOfTwo[CodeLen];\n        while Code < DecoderLen do begin\n          Decodes^[Code] := CodeData;\n          inc(Code, CodeIncr);\n        end;\n        {$ENDIF}\n      end;\n\n      {we've used this code up for this symbol, so increment for the\n       next symbol at this code length}\n      inc(NextCode[CodeLen]);\n    end;\n  end;\nend;\n{--------}\n{$IFDEF UseLogging}\nprocedure TAbDfDecodeHuffmanTree.DebugPrint(aLog : TAbLogger);\n{$IFDEF EnableMegaLog}\nvar\n  i : integer;\n  Code : longint;\n{$ENDIF}\nbegin\n  {to print the huffman tree, we must have a logger...}\n  Assert(aLog <> nil,\n         'TAbDfDecodeHuffmanTree.DebugPrint needs a logger object to which to print');\n\n  if (FUsage <> huEncoding) then begin\n    aLog.WriteLine('Huffman decoder array');\n    aLog.WriteLine(Format('Alphabet size:  %d', [FAlphaSize]));\n    aLog.WriteLine(Format('Max codelength: %d', [FMaxCodeLen]));\n\n    {$IFDEF EnableMegaLog}\n    aLog.WriteLine('Index Len Xtra Symbol                    Reversed Code');\n    for i := 0 to pred(PowerOfTwo[FMaxCodeLen]) do begin\n      Code := FDecodes^[i];\n      if (Code = -1) then\n        aLog.WriteLine(Format('%5d%49s', [i, 'no code']))\n      else\n        aLog.WriteLine(Format('%5d%4d%5d%7d%33s',\n                       [i,\n                        ((Code shr 16) and $FF),\n                        ((Code shr 24) and $FF),\n                        (Code and $FFFF),\n                        CodeToStr(i, ((Code shr 16) and $FF))]));\n    end;\n    aLog.WriteLine('---end decoder array---');\n    {$ENDIF}\n  end;\n\n  if (FUsage <> huDecoding) then begin\n    aLog.WriteLine('Huffman encoder array');\n    aLog.WriteLine(Format('Alphabet size: %d', [FAlphaSize]));\n\n    {$IFDEF EnableMegaLog}\n    aLog.WriteLine('Symbol Len Xtra                    Reversed Code');\n    for i := 0 to pred(FAlphaSize) do begin\n      Code := FEncodes^[i];\n      if (Code = -1) then\n        aLog.WriteLine(Format('%6d%42s', [i, 'no code']))\n      else\n        aLog.WriteLine(Format('%6d%4d%5d%33s',\n                       [i,\n                        ((Code shr 16) and $FF),\n                        ((Code shr 24) and $FF),\n                        CodeToStr((Code and $FFFF), ((Code shr 16) and $FF))]));\n    end;\n    aLog.WriteLine('---end encoder array---');\n    {$ENDIF}\n  end;\nend;\n{$ENDIF}\n{--------}\nfunction TAbDfDecodeHuffmanTree.Decode(aLookupBits : integer) : longint;\nbegin\n  {protect against dumb programming mistakes (note: FMask only exists\n   if assertions are on)}\n  {$IFOPT C+}\n  Assert((aLookupBits and FMask) = 0,\n         'TAbDfDecodeHuffmanTree.Decode: trying to decode too many bits, use LookupBitLength property');\n  {$ENDIF}\n\n  {return the code data}\n  Result := FDecodes^[aLookupBits];\nend;\n{--------}\nfunction TAbDfDecodeHuffmanTree.Encode(aSymbol : integer) : longint;\nbegin\n  {protect against dumb programming mistakes}\n  Assert((0 <= aSymbol) and (aSymbol < FAlphaSize),\n         'TAbDfDecodeHuffmanTree.Encode: trying to encode a symbol that is not in the alphabet');\n\n  {return the code data}\n  Result := FEncodes^[aSymbol];\n\n  {if the result is -1, it's another programming mistake: the user is\n   attempting to get a code for a symbol that wasn't being used}\n  Assert(Result <> -1,\n         'TAbDfDecodeHuffmanTree.Encode: trying to encode a symbol that was not used');\nend;\n{====================================================================}\n\n\n{===BuildStaticTrees=================================================}\nprocedure BuildStaticTrees;\nvar\n  i        : integer;\n  CodeLens : array [0..287] of integer;\nbegin\n  {this routine builds the static huffman trees, those whose code\n   lengths are determined by the deflate spec}\n\n  {the static literal tree first}\n  for i := 0 to 143 do\n    CodeLens[i] := 8;\n  for i := 144 to 255 do\n    CodeLens[i] := 9;\n  for i := 256 to 279 do\n    CodeLens[i] := 7;\n  for i := 280 to 287 do\n    CodeLens[i] := 8;\n  AbStaticLiteralTree := TAbDfDecodeHuffmanTree.Create(288, 15, huBoth);\n  AbStaticLiteralTree.Build(CodeLens, 0, 288,\n                            dfc_LitExtraBits, dfc_LitExtraOffset);\n\n  {the static distance tree afterwards}\n  for i := 0 to 31 do\n    CodeLens[i] := 5;\n  AbStaticDistanceTree := TAbDfDecodeHuffmanTree.Create(32, 15, huBoth);\n  AbStaticDistanceTree.Build(CodeLens, 0, 32,\n                             dfc_DistExtraBits, dfc_DistExtraOffset);\nend;\n{====================================================================}\n\ninitialization\n  BuildStaticTrees;\n\nfinalization\n  AbStaticLiteralTree.Free;\n  AbStaticDistanceTree.Free;\n  \nend.\n"
  },
  {
    "path": "lib/abbrevia/source/AbDfInW.pas",
    "content": "(* ***** BEGIN LICENSE BLOCK *****\n * Version: MPL 1.1\n *\n * The contents of this file are subject to the Mozilla Public License Version\n * 1.1 (the \"License\"); you may not use this file except in compliance with\n * the License. You may obtain a copy of the License at\n * http://www.mozilla.org/MPL/\n *\n * Software distributed under the License is distributed on an \"AS IS\" basis,\n * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License\n * for the specific language governing rights and limitations under the\n * License.\n *\n * The Original Code is TurboPower Abbrevia\n *\n * The Initial Developer of the Original Code is\n * TurboPower Software\n *\n * Portions created by the Initial Developer are Copyright (C) 1997-2002\n * the Initial Developer. All Rights Reserved.\n *\n * Contributor(s):\n *\n * ***** END LICENSE BLOCK ***** *)\n\n{*********************************************************}\n{* ABBREVIA: AbDfInW.pas                                 *}\n{*********************************************************}\n{* Deflate input sliding window unit                     *}\n{*********************************************************}\n\nunit AbDfInW;\n\n{$I AbDefine.inc}\n\ninterface\n\nuses\n  Classes,\n  AbDfBase;\n\n{Notes: TdfInputWindow implements a sliding window on data for the\n        LZ77 dictionary encoding.\n\n        The stream passed to the class is automatically read when\n        required to keep the internal buffer fully loaded.\n        }\n\ntype\n  TAbDfMatch = record\n    maLen  : integer;\n    maDist : integer;\n    maLit  : AnsiChar;\n  end;\n\ntype\n  PAbPointerList = ^TAbPointerList;\n  TAbPointerList = array[0..MaxInt div SizeOf(Pointer) - 1] of Pointer;\n\n  TAbDfInputWindow = class\n    private\n      FAdvanceStart : boolean;\n      FBuffer       : PAnsiChar;\n      FBufferEnd    : PAnsiChar;\n      FBytesUsed    : longint;\n      FChainLen     : integer;\n      FHashChains   : PAbPointerList;\n      FHashHeads    : PAbPointerList;\n      FHashIndex    : integer;\n      FChecksum     : longint;\n      FCurrent      : PAnsiChar;\n      FLookAheadEnd : PAnsiChar;\n      FMaxMatchLen  : integer;\n      FMustSlide    : boolean;\n      FOnProgress   : TAbProgressStep;\n      FSlidePoint   : PAnsiChar;\n      FStart        : PAnsiChar;\n      FStartOffset  : longint;\n      FStream       : TStream;\n      FStreamSize   : Int64;\n      FUseCRC32     : boolean;\n      FUseDeflate64 : boolean;\n      FWinMask      : integer;\n      FWinSize      : integer;\n    protected\n      function iwGetChecksum : longint;\n      procedure iwReadFromStream;\n      procedure iwSetCapacity(aValue : longint);\n      procedure iwSlide;\n    public\n      constructor Create(aStream       : TStream;\n                         aStreamSize   : Int64;\n                         aWinSize      : integer;\n                         aChainLength  : integer;\n                         aUseDeflate64 : boolean;\n                         aUseCRC32     : boolean);\n      destructor Destroy; override;\n\n      procedure Advance(aCount     : integer;\n                        aHashCount : integer);\n      procedure AdvanceByOne;\n      function FindLongestMatch(aAmpleLength : integer;\n                            var aMatch       : TAbDfMatch;\n                          const aPrevMatch   : TAbDfMatch) : boolean;\n      function GetNextChar : AnsiChar;\n      function GetNextKeyLength : integer;\n      function Position : longint;\n      procedure ReadBuffer(var aBuffer; aCount  : longint;\n                                        aOffset : Int64);\n\n      property ChainLen : integer read FChainLen write FChainLen;\n      property Checksum : longint read iwGetChecksum;\n      property OnProgress : TAbProgressStep\n                  read FOnProgress write FOnProgress;\n  end;\n\nimplementation\n\nuses\n  SysUtils;\n\n{Notes:\n        Meaning of the internal pointers:\n\n        |----------+===================+==+--------------------------|\n        |          |                   |  |                          |\n        FBuffer    FStart       FCurrent  FLookAheadEnd     FBufferEnd\n\n        FCurrent is the current match position. The valid data that\n        can be matched is between FStart and FLookAheadEnd, The data\n        between FStart and FCurrent has already been seen; the data\n        between FCurrent and FLookAheadEnd can be used for matching.\n\n        The buffer size depends on the requested window size (a\n        multiple of 1KB, up to 32KB for deflate, up to 64KB for\n        deflate64) and the lookahead size (up to 258 bytes for deflate\n        and 64KB for deflate64.)\n\n        The window of data continuously slides to the right, and is\n        slid back to FBuffer whenever FStart reaches a point 16KB\n        away, this point being given by FSlidePoint.\n\n\n        The hash table:\n        This is a chained hash table with some peculiarities. First\n        the table itself, FHashHeads. It contains pointers to strings\n        in the window buffer, not to chains. The chains are held is a\n        separate structure, FHashChains. The hash function on the\n        three-character keys is a Rabin-Karp function:\n          ((((Ch1 shl 5) xor Ch2) shl 5) xor Ch3) and $3FFF\n        designed so that a running hash value can be kept and\n        calculated per character. The hash table is $4000 elements\n        long (obviously, given the hash function).\n        On insertion, the previous pointer in the hash table at the\n        calculated index is saved and replaced by the new pointer. The\n        old pointer is saved in the chains array. This has the same\n        number of elements as the sliding window has characters. The\n        pointer is placed at (Ptr and (WindowsSize-1)) overwriting the\n        value that's already there. In this fashion the individual\n        chains in the standard hash table are interwoven with each\n        other in this hash table, like a skein of threads.\n        }\n\nconst\n  c_HashCount = $4000;             {the number of hash entries}\n  c_HashMask  = c_HashCount - 1;   {a mask for the hash function}\n  c_HashShift = 5;                 {shift value for the hash function}\n\n{===TAbDfInputWindow=================================================}\nconstructor TAbDfInputWindow.Create(aStream       : TStream;\n                                    aStreamSize   : Int64;\n                                    aWinSize      : integer;\n                                    aChainLength  : integer;\n                                    aUseDeflate64 : boolean;\n                                    aUseCRC32     : boolean);\nbegin\n  {create the ancestor}\n  inherited Create;\n\n  {save parameters}\n  FStreamSize := aStreamSize;\n  FWinSize := aWinSize;\n  FWinMask := aWinSize - 1;\n  FStream := aStream;\n  FChainLen := aChainLength;\n  FUseDeflate64 := aUseDeflate64;\n  FUseCRC32 := aUseCRC32;\n  if aUseCRC32 then\n    FChecksum := -1  { CRC32 starts off with all bits set }\n  else\n    FCheckSum := 1;  { Adler32 starts off with a value of 1 }\n\n  {set capacity of sliding window}\n  iwSetCapacity(aWinSize);\n\n  {create the hash table, first the hash table itself (and set all\n   entries to nil)}\n  FHashHeads := AllocMem(c_HashCount * sizeof(pointer));\n\n  {..now the chains (there's no need to set the entries to nil, since\n   the chain entries get fed from the head entries before searching)}\n  GetMem(FHashChains, aWinSize * sizeof(pointer));\n\n  {read the first chunk of data from the stream}\n  FMustSlide := true;\n  iwReadFromStream;\n\n  {if there are at least two bytes, prime the hash index}\n  if ((FLookAheadEnd - FBuffer) >= 2) then \n    FHashIndex := ((longint(FBuffer[0]) shl c_HashShift) xor\n                   longint(FBuffer[1])) and\n                  c_HashMask;\nend;\n{--------}\ndestructor TAbDfInputWindow.Destroy;\nbegin\n  {free the hash table}\n  FreeMem(FHashHeads);\n  FreeMem(FHashChains);\n\n  {free the buffer}\n  FreeMem(FBuffer);\n\n  {destroy the ancestor}\n  inherited Destroy;\nend;\n{--------}\nprocedure TAbDfInputWindow.Advance(aCount     : integer;\n                                   aHashCount : integer);\nvar\n  i : integer;\n  ByteCount : integer;\n  Percent   : integer;\n  HashChains: PAbPointerList;\n  HashHeads : PAbPointerList;\n  HashInx   : integer;\n  CurPos    : PAnsiChar;\nbegin\n  Assert((FLookAheadEnd - FCurrent) >= aCount,\n         'TAbDfInputWindow.Advance: seem to be advancing into the unknown');\n  Assert((aHashCount = aCount) or (aHashCount = pred(aCount)),\n         'TAbDfInputWindow.Advance: the parameters are plain wrong');\n  {use local var for speed}\n  CurPos := FCurrent;\n\n  {advance the current pointer if needed}\n  if (aCount > aHashCount) then\n    inc(CurPos);\n\n  {make sure we update the hash table; remember that the string[3] at\n   the current position has already been added to the hash table (for\n   notes on updating the hash table, see FindLongestMatch}\n\n  {use local vars for speed}\n  HashChains := FHashChains;\n  HashHeads := FHashHeads;\n  HashInx := FHashIndex;\n\n  {update the hash table}\n  for i := 0 to pred(aHashCount) do begin\n    HashInx :=\n       ((HashInx shl c_HashShift) xor longint(CurPos[2])) and\n       c_HashMask;\n    HashChains^[longint(CurPos) and FWinMask] :=\n       HashHeads^[HashInx];\n    HashHeads^[HashInx] := CurPos;\n    inc(CurPos);\n  end;\n\n  {replace old values}\n  FHashChains := HashChains;\n  FHashHeads := HashHeads;\n  FHashIndex := HashInx;\n  FCurrent := CurPos;\n\n  {if we've seen at least FWinSize bytes...}\n  if FAdvanceStart then begin\n\n    {advance the start of the sliding window}\n    inc(FStart, aCount);\n    inc(FStartOffset, aCount);\n\n    {check to see if we have advanced into the slide zone}\n    if FMustSlide and (FStart >= FSlidePoint) then\n      iwSlide;\n  end\n\n  {otherwise check to see if we've seen at least FWinSize bytes}\n  else if ((CurPos - FStart) >= FWinSize) then begin\n    FAdvanceStart := true;\n    {note: we can't advance automatically aCount bytes here, we need\n           to calculate the actual count}\n    ByteCount := (CurPos - FWinSize) - FStart;\n    inc(FStart, ByteCount);\n    inc(FStartOffset, ByteCount);\n  end;\n\n  {show progress}\n  if Assigned(FOnProgress) then begin\n    inc(FBytesUsed, aCount);\n    if ((FBytesUsed and $FFF) = 0) then begin\n      Percent := Round((100.0 * FBytesUsed) / FStreamSize);\n      FOnProgress(Percent);\n    end;\n  end;\n\n  {check to see if we have advanced into the slide zone}\n  if (FStart >= FSlidePoint) then\n    iwSlide;\nend;\n{--------}\nprocedure TAbDfInputWindow.AdvanceByOne;\nvar\n  Percent   : integer;\nbegin\n  {advance the current pointer}\n  inc(FCurrent);\n\n  {if we've seen at least FWinSize bytes...}\n  if FAdvanceStart then begin\n\n    {advance the start of the sliding window}\n    inc(FStart, 1);\n    inc(FStartOffset, 1);\n\n    {check to see if we have advanced into the slide zone}\n    if FMustSlide and (FStart >= FSlidePoint) then\n      iwSlide;\n  end\n\n  {otherwise check to see if we've seen FWinSize bytes}\n  else if ((FCurrent - FStart) = FWinSize) then\n    FAdvanceStart := true;\n\n  {show progress}\n  if Assigned(FOnProgress) then begin\n    inc(FBytesUsed, 1);\n    if ((FBytesUsed and $FFF) = 0) then begin\n      Percent := Round((100.0 * FBytesUsed) / FStreamSize);\n      FOnProgress(Percent);\n    end;\n  end;\nend;\n{--------}\nfunction TAbDfInputWindow.FindLongestMatch(aAmpleLength : integer;\n                                       var aMatch       : TAbDfMatch;\n                                     const aPrevMatch   : TAbDfMatch)\n                                                        : boolean;\n{Note: this routine implements a greedy algorithm and is by far the\n       time sink for compression. There are two versions, one written\n       in Pascal for understanding, one in assembler for speed.\n       Activate one and only one of the following compiler defines.}\n{$IFDEF CPU386}\n  {$DEFINE UseGreedyAsm}\n{$ELSE}\n  {$DEFINE UseGreedyPascal}\n{$ENDIF}\n\n{Check to see that all is correct}\n{$IFDEF UseGreedyAsm}\n  {$IFDEF UseGreedyPascal}\n    !! Compile Error: only one of the greedy compiler defines can be used\n  {$ENDIF}\n{$ELSE}\n  {$IFNDEF UseGreedyPascal}\n    !! Compile Error: one of the greedy compiler defines must be used\n  {$ENDIF}\n{$ENDIF}\ntype\n  PLongint = ^longint;\n  PWord    = ^word;\nvar\n  MaxLen     : longint;\n  MaxDist    : longint;\n  MaxMatch   : integer;\n  ChainLen   : integer;\n  PrevStrPos : PAnsiChar;\n  CurPos     : PAnsiChar;\n  {$IFDEF UseGreedyAsm}\n  CurWord    : word;\n  MaxWord    : word;\n  {$ENDIF}\n  {$IFDEF UseGreedyPascal}\n  Len        : longint;\n  MatchStr   : PAnsiChar;\n  CurrentCh  : PAnsiChar;\n  CurCh      : AnsiChar;\n  MaxCh      : AnsiChar;\n  {$ENDIF}\nbegin\n  {calculate the hash index for the current position; using the\n   Rabin-Karp algorithm this is equal to the previous index less the\n   effect of the character just lost plus the effect of the character\n   just gained}\n  CurPos := FCurrent;\n  FHashIndex :=\n     ((FHashIndex shl c_HashShift) xor longint(CurPos[2])) and\n     c_HashMask;\n\n  {get the head of the hash chain: this is the position in the sliding\n   window of the previous 3-character string with this hash value}\n  PrevStrPos := FHashHeads^[FHashIndex];\n\n  {set the head of the hash chain equal to our current position}\n  FHashHeads^[FHashIndex] := CurPos;\n\n  {update the chain itself: set the entry for this position equal to\n   the previous string position}\n  FHashChains^[longint(CurPos) and FWinMask] := PrevStrPos;\n\n  {calculate the maximum match we could do at this position}\n  MaxMatch := (FLookAheadEnd - CurPos);\n  if (MaxMatch > FMaxMatchLen) then\n    MaxMatch := FMaxMatchLen;\n  if (aAmpleLength > MaxMatch) then\n    aAmpleLength := MaxMatch;\n\n  {calculate the current match length}\n  if (aPrevMatch.maLen = 0) then\n    MaxLen := 2\n  else begin\n    if (MaxMatch < aPrevMatch.maLen) then begin\n      Result := false;\n      aMatch.maLen := 0;\n      aMatch.maLit := CurPos^;\n      Exit;\n    end;\n    MaxLen := aPrevMatch.maLen;\n  end;\n\n  {get the bytes at the current position and at the end of the maximum\n   match we have to better}\n  {$IFDEF UseGreedyAsm}\n  CurWord := PWord(CurPos)^;\n  MaxWord := PWord(CurPos + pred(MaxLen))^;\n  {$ENDIF}\n  {$IFDEF UseGreedyPascal}\n  CurCh := CurPos^;\n  MaxCh := (CurPos + pred(MaxLen))^;\n  {$ENDIF}\n\n  {set the chain length to search based on the current maximum match\n   (basically: if we've already satisfied the ample length\n   requirement, don't search as far)}\n  if (MaxLen >= aAmpleLength) then\n    ChainLen := FChainLen div 4\n  else\n    ChainLen := FChainLen;\n\n  {get ready for the loop}\n  {$IFDEF DefeatWarnings}\n  MaxDist := 0;\n  {$ENDIF}\n\n  {$IFDEF UseGreedyAsm} { slip into assembler for speed...}\n  asm\n    push ebx                 { save those registers we should}\n    push esi\n    push edi\n\n    mov ebx, Self            { ebx will store the Self pointer}\n    mov edi, PrevStrPos      { edi => previous string}\n    mov esi, CurPos          { esi => current string}\n\n  @@TestThisPosition:\n                             { check previous string is in range}\n    or edi, edi\n    je @@Exit\n    cmp edi, [ebx].TAbDfInputWindow.FStart\n    jb @@Exit\n    cmp edi, CurPos\n    jae @@Exit\n\n    mov ax, [edi]            { check previous string starts with same}\n    cmp CurWord, ax          {   two bytes as current}\n    jne @@GetNextPosition    { ..nope, they don't match}\n\n    mov edx, edi             { check previous string ends with same}\n    add edi, MaxLen          {   two bytes as current (by \"ends\" we}\n    dec edi                  {   mean the last two bytes at the}\n    mov ax, [edi]            {   current match length)}\n    cmp MaxWord, ax\n    mov edi, edx\n    jne @@GetNextPosition    { ..nope, they don't match}\n\n    push edi                 { compare the previous string with the}\n    push esi                 {   current string}\n    mov eax, MaxMatch\n    add edi, 2               { (we've already checked that the first}\n    sub eax, 2               { two characters are the same)}\n    add esi, 2\n    mov ecx, eax\n\n  @@CmpQuads:\n    cmp ecx, 4\n    jb @@CmpSingles\n\n    mov edx, [esi]\n    cmp edx, [edi]\n    jne @@CmpSingles\n\n    add esi, 4\n    add edi, 4\n    sub ecx, 4\n    jnz @@CmpQuads\n\n    jmp @@MatchCheck\n\n  @@CmpSingles:\n    or ecx, ecx\n    jb @@MatchCheck\n\n    mov dl, [esi]\n    cmp dl, [edi]\n    jne @@MatchCheck\n\n    inc esi\n    inc edi\n    dec ecx\n    jnz @@CmpSingles\n\n  @@MatchCheck:\n    sub eax, ecx\n    add eax, 2\n    pop esi\n    pop edi\n\n    cmp eax, MaxLen          { have we found a longer match?}\n    jbe @@GetNextPosition    { ..no}\n    mov MaxLen, eax          { ..yes, so save it}\n\n    mov eax, esi             { calculate the dist for this new match}\n    sub eax, edi\n    mov MaxDist, eax\n\n    cmp eax, aAmpleLength    { if this match is ample enough, exit}\n    jae @@Exit\n\n    mov eax, esi             { calculate the two bytes at the end of}\n    add eax, MaxLen          {   this new match}\n    dec eax\n    mov ax, [eax]\n    mov MaxWord, ax\n\n  @@GetNextPosition:\n    mov eax, ChainLen        { we've visited one more link on the}\n    dec eax                  {   chain, if that's the last one we}\n    je @@Exit                {   should visit, exit}\n    mov ChainLen, eax\n\n                             { advance along the chain}\n    mov edx, [ebx].TAbDfInputWindow.FHashChains\n    mov eax, [ebx].TAbDfInputWindow.FWinMask\n    and edi, eax\n    shl edi, 2\n    mov edi, [edx+edi]\n    jmp @@TestThisPosition\n\n  @@Exit:\n    pop edi\n    pop esi\n    pop ebx\n  end;\n  {$ENDIF}\n\n  {$IFDEF UseGreedyPascal}\n  {for all possible hash nodes in the chain...}\n  while (FStart <= PrevStrPos) and (PrevStrPos < CurPos) do begin\n\n    {if the initial and maximal characters match...}\n    if (PrevStrPos[0] = CurCh) and\n       (PrevStrPos[pred(MaxLen)] = MaxCh) then begin\n\n      {compare more characters}\n      Len := 1;\n      CurrentCh := CurPos + 1;\n      MatchStr := PrevStrPos + 1;\n\n      {compare away, but don't go above the maximum length}\n      while (Len < MaxMatch) and (MatchStr^ = CurrentCh^) do begin\n        inc(CurrentCh);\n        inc(MatchStr);\n        inc(Len);\n      end;\n\n      {have we reached another maximum for the length?}\n      if (Len > MaxLen) then begin\n        MaxLen := Len;\n        {calculate the distance}\n        MaxDist := CurPos - PrevStrPos;\n        MaxCh := CurPos[pred(MaxLen)];\n\n        {is the new best length ample enough?}\n        if MaxLen >= aAmpleLength then\n          Break;\n      end;\n    end;\n\n    {have we reached the end of this chain?}\n    dec(ChainLen);\n    if (ChainLen = 0) then\n      Break;\n\n    {otherwise move onto the next position}\n    PrevStrPos := FHashChains^[longint(PrevStrPos) and FWinMask];\n  end;\n  {$ENDIF}\n\n  {based on the results of our investigation, return the match values}\n  if (MaxLen < 3) or (MaxLen <= aPrevMatch.maLen) then begin\n    Result := false;\n    aMatch.maLen := 0;\n    aMatch.maLit := CurPos^;\n  end\n  else begin\n    Result := true;\n    aMatch.maLen := MaxLen;\n    aMatch.maDist := MaxDist;\n    aMatch.maLit := CurPos^; { just in case...}\n  end;\nend;\n{--------}\nfunction TAbDfInputWindow.GetNextChar : AnsiChar;\nbegin\n  Result := FCurrent^;\n  inc(FCurrent);\nend;\n{--------}\nfunction TAbDfInputWindow.GetNextKeyLength : integer;\nbegin\n  Result := FLookAheadEnd - FCurrent;\n  if (Result > 3) then\n    Result := 3;\nend;\n{--------}\nfunction TAbDfInputWindow.iwGetChecksum : longint;\nbegin\n  {the CRC32 checksum algorithm requires a post-conditioning step\n   after being calculated (the result is NOTted), whereas Adler32 does\n   not}\n  if FUseCRC32 then\n    Result := not FChecksum\n  else\n    Result := FChecksum;\nend;\n{--------}\nprocedure TAbDfInputWindow.iwReadFromStream;\nvar\n  BytesRead   : longint;\n  BytesToRead : longint;\nbegin\n  {read some more data into the look ahead zone}\n  BytesToRead := FBufferEnd - FLookAheadEnd;\n  BytesRead := FStream.Read(FLookAheadEnd^, BytesToRead);\n\n  {if nothing was read, we reached the end of the stream; hence\n   there's no more need to slide the window since we have all the\n   data}\n  if (BytesRead = 0) then\n    FMustSlide := false\n\n  {otherwise something was actually read...}\n  else begin\n    {update the checksum}\n    if FUseCRC32 then\n      AbUpdateCRCBuffer(FChecksum, FLookAheadEnd^, BytesRead)\n    else\n      AbUpdateAdlerBuffer(FChecksum, FLookAheadEnd^, BytesRead);\n\n    {reposition the pointer for the end of the lookahead area}\n    inc(FLookAheadEnd, BytesRead);\n  end;\nend;\n{--------}\nprocedure TAbDfInputWindow.iwSetCapacity(aValue : longint);\nvar\n  ActualSize : integer;\nbegin\n  {calculate the actual size; this will be the value passed in, plus\n   the correct look ahead size, plus 16KB}\n  ActualSize := aValue + (16 * 1024);\n  if FUseDeflate64 then begin\n    inc(ActualSize, dfc_MaxMatchLen64);\n    FMaxMatchLen := dfc_MaxMatchLen64;\n  end\n  else begin\n    inc(ActualSize, dfc_MaxMatchLen);\n    FMaxMatchLen := dfc_MaxMatchLen;\n  end;\n\n  {get the new buffer}\n  GetMem(FBuffer, ActualSize);\n\n  {set the other buffer pointers}\n  FStart := FBuffer;\n  FCurrent := FBuffer;\n  FLookAheadEnd := FBuffer;\n  FBufferEnd := FBuffer + ActualSize;\n  FSlidePoint := FBuffer + (16 * 1024);\nend;\n{--------}\nprocedure TAbDfInputWindow.iwSlide;\ntype\n  PLongint = ^longint;\nvar\n  i : integer;\n  ByteCount : integer;\n  Buffer    : longint;\n  ListItem  : PLongint;\nbegin\n  {move current valid data back to the start of the buffer}\n  ByteCount := FLookAheadEnd - FStart;\n  Move(FStart^, FBuffer^, ByteCount);\n\n  {reset the various pointers}\n  ByteCount := FStart - FBuffer;\n  FStart := FBuffer;\n  dec(FCurrent, ByteCount);\n  dec(FLookAheadEnd, ByteCount);\n\n  {patch up the hash table: the head pointers}\n  Buffer := longint(FBuffer);\n  ListItem := PLongint(@FHashHeads^[0]);\n  for i := 0 to pred(c_HashCount) do begin\n    dec(ListItem^, ByteCount);\n    if (ListItem^ < Buffer) then\n      ListItem^ := 0;\n    inc(PAnsiChar(ListItem), sizeof(pointer));\n  end;\n\n  {..the chain pointers}\n  ListItem  := PLongint(@FHashChains^[0]);\n  for i := 0 to pred(FWinSize) do begin\n    dec(ListItem^, ByteCount);\n    if (ListItem^ < Buffer) then\n      ListItem^ := 0;\n    inc(PAnsiChar(ListItem), sizeof(pointer));\n  end;\n\n  {now read some more data from the stream}\n  iwReadFromStream;\nend;\n{--------}\nfunction TAbDfInputWindow.Position : longint;\nbegin\n  Result := (FCurrent - FStart) + FStartOffset;\nend;\n{--------}\nprocedure TAbDfInputWindow.ReadBuffer(var aBuffer; aCount  : longint;\n                                                   aOffset : Int64);\nvar\n  CurPos : Int64;              \nbegin\n  CurPos := FStream.Seek(0, soCurrent);\n  FStream.Seek(aOffSet, soBeginning);\n  FStream.ReadBuffer(aBuffer, aCount);\n  FStream.Seek(CurPos, soBeginning);\nend;\n{====================================================================}\n\nend.\n\n\n\n"
  },
  {
    "path": "lib/abbrevia/source/AbDfOutW.pas",
    "content": "(* ***** BEGIN LICENSE BLOCK *****\n * Version: MPL 1.1\n *\n * The contents of this file are subject to the Mozilla Public License Version\n * 1.1 (the \"License\"); you may not use this file except in compliance with\n * the License. You may obtain a copy of the License at\n * http://www.mozilla.org/MPL/\n *\n * Software distributed under the License is distributed on an \"AS IS\" basis,\n * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License\n * for the specific language governing rights and limitations under the\n * License.\n *\n * The Original Code is TurboPower Abbrevia\n *\n * The Initial Developer of the Original Code is\n * TurboPower Software\n *\n * Portions created by the Initial Developer are Copyright (C) 1997-2002\n * the Initial Developer. All Rights Reserved.\n *\n * Contributor(s):\n *\n * ***** END LICENSE BLOCK ***** *)\n\n{*********************************************************}\n{* ABBREVIA: AbDfOutW.pas                                *}\n{*********************************************************}\n{* Deflate output sliding window                         *}\n{*********************************************************}\n\nunit AbDfOutW;\n\n{$I AbDefine.inc}\n\ninterface\n\nuses\n  Classes,\n  AbDfBase;\n\n{Notes: TAbDfOutputWindow implements a sliding window on previously\n        written data for the LZ77 dictionary decoding.\n\n        AddLiteral will add a literal character at the current\n        position and advance by one. AddLenDist will copy the required\n        number of characters from the given position to the current\n        position, and advance the stream on by the length. The class\n        will periodically update the stream from the internal buffer.\n\n        For normal Deflate, the internal buffer is 48K + 512 bytes in\n        size. Once there is 48Kb worth of data, 16KB is written to\n        file, and the buffer is shifted left by 16KB. We need to keep\n        the last decoded 32KB in memory at all times.\n\n        For Deflate64, the internal buffer is 96K + 512 bytes in\n        size. Once there is 96Kb worth of data, 32KB is written to\n        file, and the buffer is shifted left by 32KB. We need to keep\n        the last decoded 64KB in memory at all times.\n        }\n\ntype\n  TAbDfOutputWindow = class\n    private\n      FBuffer     : PAnsiChar;\n      FChecksum   : longint;\n      FCurrent    : PAnsiChar;\n      FLog        : TAbLogger;\n      FPartSize   : longint;\n      FSlideCount : integer;\n      FStream     : TStream;\n      FStreamPos  : longint;\n      FTestOnly   : boolean;\n      FUseCRC32   : boolean;\n      FWritePoint : PAnsiChar;\n    protected\n      function swGetChecksum : longint;\n      procedure swWriteToStream(aFlush : boolean);\n    public\n      constructor Create(aStream       : TStream;\n                         aUseDeflate64 : boolean;\n                         aUseCRC32     : boolean;\n                         aPartSize     : longint;\n                         aTestOnly     : boolean;\n                         aLog          : TAbLogger);\n      destructor Destroy; override;\n\n      procedure AddBuffer(var aBuffer; aCount : integer);\n      procedure AddLiteral(aCh : AnsiChar);\n      procedure AddLenDist(aLen : integer; aDist : integer);\n      function Position : longint;\n\n      property Checksum : longint read swGetChecksum;\n      property Log : TAbLogger read FLog;\n  end;\n\nimplementation\n\nuses\n  SysUtils;\n\n{Notes:\n        Meaning of the internal pointers:\n\n        |==============================+------------------------+----|\n        |                              |                        |\n        FBuffer                 FCurrent              FWritePoint\n\n        Once FCurrent reaches or exceeds FWritePoint, FSlideCount\n        bytes of data from FBuffer are written to the stream and the\n        remaining data is moved back FSlideCount bytes, moving\n        FCurrent along with it as well.\n        }\n\n{===TAbDfOutputWindow==================================================}\nconstructor TAbDfOutputWindow.Create(aStream       : TStream;\n                                     aUseDeflate64 : boolean;\n                                     aUseCRC32     : boolean;\n                                     aPartSize     : longint;\n                                     aTestOnly     : boolean;\n                                     aLog          : TAbLogger);\nvar\n  Size          : integer;\n  LookAheadSize : integer;\nbegin\n  {allow the ancestor to initialize}\n  inherited Create;\n\n  {save parameters}\n  FLog := aLog;\n  FStream := aStream;\n  FTestOnly := aTestOnly;\n  if (aPartSize <= 0) then\n    FPartSize := 0\n  else\n    FPartSize := aPartSize;\n  FUseCRC32 := aUseCRC32;\n  if aUseCRC32 then\n    FChecksum := -1  { CRC32 starts off with all bits set}\n  else\n    FCheckSum := 1;  { Adler32 starts off with a value of 1}\n\n  {set capacity of sliding window}\n  if aUseDeflate64 then begin\n    Size := 96 * 1024;\n    FSlideCount := 32 * 1024;\n    LookAheadSize := 64 * 1024;\n  end\n  else begin\n    Size := 64 * 1024;\n    FSlideCount := 32 * 1024;\n    LookAheadSize := 258;\n  end;\n  GetMem(FBuffer, Size + LookAheadSize);\n\n  {set the other internal pointers}\n  FCurrent := FBuffer;\n  FWritePoint := FBuffer + Size;\n  if (FPartSize > Size) then\n    FPartSize := Size;\nend;\n{--------}\ndestructor TAbDfOutputWindow.Destroy;\nbegin\n  {write remaining data and free the buffer}\n  if (FBuffer <> nil) then begin\n    if (FCurrent <> FBuffer) then\n      swWriteToStream(true);\n    FreeMem(FBuffer);\n  end;\n\n  {destroy the ancestor}\n  inherited Destroy;\nend;\n{--------}\nprocedure TAbDfOutputWindow.AddBuffer(var aBuffer; aCount : integer);\nvar\n  Buffer : PAnsiChar;\n  BytesToWrite : integer;\nbegin\n  {if we've advanced to the point when we need to write, do so}\n  if (FCurrent >= FWritePoint) then\n    swWriteToStream(false);\n\n  {cast the user buffer to a PChar, it's easier to use}\n  Buffer := @aBuffer;\n\n  {calculate the number of bytes to copy}\n  BytesToWrite := FWritePoint - FCurrent;\n  if (BytesToWrite > aCount) then\n    BytesToWrite := aCount;\n\n  {move this block of bytes}\n  Move(Buffer^, FCurrent^, BytesToWrite);\n\n  {advance pointers and counters}\n  inc(FCurrent, BytesToWrite);\n  dec(aCount, BytesToWrite);\n\n  {while there is still data to copy...}\n  while (aCount > 0) do begin\n    {advance the user buffer pointer}\n    inc(Buffer, BytesToWrite);\n\n    {write the sliding window chunk to the stream}\n    swWriteToStream(false);\n\n    {calculate the number of bytes to copy}\n    BytesToWrite := FWritePoint - FCurrent;\n    if (BytesToWrite > aCount) then\n      BytesToWrite := aCount;\n\n    {move this block of bytes}\n    Move(Buffer^, FCurrent^, BytesToWrite);\n\n    {advance pointers and counters}\n    inc(FCurrent, BytesToWrite);\n    dec(aCount, BytesToWrite);\n  end;\nend;\n{--------}\nprocedure AddLenDistToLog(aLog     : TAbLogger;\n                          aPosn    : longint;\n                          aLen     : integer;\n                          aDist    : integer;\n                          aOverLap : boolean);\nbegin\n  {NOTE the reason for this separate routine is to avoid string\n        allocations and try..finally blocks in the main method: an\n        optimization issue}\n  if aOverLap then\n    aLog.WriteLine(Format('%8x Len: %-3d, Dist: %-5d  **overlap**',\n                          [aPosn, aLen, aDist]))\n  else\n    aLog.WriteLine(Format('%8x Len: %-3d, Dist: %-5d',\n                          [aPosn, aLen, aDist]));\nend;\n{--------}\nprocedure TAbDfOutputWindow.AddLenDist(aLen : integer; aDist : integer);\nvar\n  i : integer;\n  ToChar   : PAnsiChar;\n  FromChar : PAnsiChar;\nbegin\n  {log it}\n  {$IFDEF UseLogging}\n  if (FLog <> nil) then\n    AddLenDistToLog(FLog, Position, aLen, aDist, (aLen > aDist));\n  {$ENDIF}\n\n  {if the length to copy is less than the distance, just do a move}\n  if (aLen <= aDist) then begin\n    Move((FCurrent - aDist)^ , FCurrent^, aLen);\n  end\n\n  {otherwise we have to use a byte-by-byte copy}\n  else begin\n    FromChar := FCurrent - aDist;\n    ToChar := FCurrent;\n    for i := 1 to aLen do begin\n      ToChar^ := FromChar^;\n      inc(FromChar);\n      inc(ToChar);\n    end;\n  end;\n\n  {increment the current pointer}\n  inc(FCurrent, aLen);\n\n  {if we've reached the point requested, abort}\n  if (FPartSize > 0) and ((FCurrent - FBuffer) >= FPartSize) then\n    raise EAbPartSizedInflate.Create(''); {NOTE: This exception is expected during detection of .GZ and .TGZ files. (VerifyGZip)}\n\n  {if we've advanced to the point when we need to write, do so}\n  if (FCurrent >= FWritePoint) then\n    swWriteToStream(false);\nend;\n{--------}\nprocedure AddLiteralToLog(aLog     : TAbLogger;\n                          aPosn    : longint;\n                          aCh      : AnsiChar);\nbegin\n  {NOTE the reason for this separate routine is to avoid string\n        allocations and try..finally blocks in the main method: an\n        optimization issue}\n  if (' ' < aCh) and (aCh <= '~') then\n    aLog.WriteLine(Format('%8x Char: %3d $%2x [%s]', [aPosn, ord(aCh), ord(aCh), aCh]))\n  else\n    aLog.WriteLine(Format('%8x Char: %3d $%2x', [aPosn, ord(aCh), ord(aCh)]));\nend;\n{--------}\nprocedure TAbDfOutputWindow.AddLiteral(aCh : AnsiChar);\nbegin\n  {log it}\n  {$IFDEF UseLogging}\n  if (FLog <> nil) then\n    AddLiteralToLog(FLog, Position, aCh);\n  {$ENDIF}\n\n  {add the literal to the buffer}\n  FCurrent^ := aCh;\n\n  {increment the current pointer}\n  inc(FCurrent);\n\n  {if we've reached the point requested, abort}\n  if (FPartSize > 0) and ((FCurrent - FBuffer) >= FPartSize) then\n    raise EAbPartSizedInflate.Create('');\n\n  {if we've advanced to the point when we need to write, do so}\n  if (FCurrent >= FWritePoint) then\n    swWriteToStream(false);\nend;\n{--------}\nfunction TAbDfOutputWindow.Position : longint;\nbegin\n  if FTestOnly then\n    Result := FStreamPos + (FCurrent - FBuffer)\n  else\n    Result := FStream.Position + (FCurrent - FBuffer);\nend;\n{--------}\nfunction TAbDfOutputWindow.swGetChecksum : longint;\nbegin\n  {since the checksum is calculated by the method that flushes to the\n   stream, make sure any buffered data is written out first}\n  if (FCurrent <> FBuffer) then\n    swWriteToStream(true);\n\n  {the CRC32 checksum algorithm requires a post-conditioning step\n   after being calculated (the result is NOTted), whereas Adler32 does\n   not}\n  if FUseCRC32 then\n    Result := not FChecksum\n  else\n    Result := FChecksum;\nend;\n{--------}\nprocedure TAbDfOutputWindow.swWriteToStream(aFlush : boolean);\nvar\n  FromPtr : PAnsiChar;\nbegin\n  {if the request was to flush, write all remaining data after\n   updating the checksum}\n  if aFlush then begin\n    if FUseCRC32 then\n      AbUpdateCRCBuffer(FChecksum, FBuffer^, FCurrent - FBuffer)\n    else\n      AbUpdateAdlerBuffer(FChecksum, FBuffer^, FCurrent - FBuffer);\n    if FTestOnly then\n      inc(FStreamPos, FCurrent - FBuffer)\n    else\n      FStream.WriteBuffer(FBuffer^, FCurrent - FBuffer);\n    FCurrent := FBuffer;\n  end\n\n  {otherwise, update the checksum with the data in the sliding window\n   chunk, write it out to the stream, and move the rest of the buffer\n   back}\n  else begin\n    if FUseCRC32 then\n      AbUpdateCRCBuffer(FChecksum, FBuffer^, FSlideCount)\n    else\n      AbUpdateAdlerBuffer(FChecksum, FBuffer^, FSlideCount);\n    if FTestOnly then\n      inc(FStreamPos, FSlideCount)\n    else\n      FStream.WriteBuffer(FBuffer^, FSlideCount);\n    FromPtr := FBuffer + FSlideCount;\n    Move(FromPtr^, FBuffer^, FCurrent - FromPtr);\n    FCurrent := FCurrent - FSlideCount;\n  end;\nend;\n{====================================================================}\n\nend.\n\n"
  },
  {
    "path": "lib/abbrevia/source/AbDfPkMg.pas",
    "content": "(* ***** BEGIN LICENSE BLOCK *****\n * Version: MPL 1.1\n *\n * The contents of this file are subject to the Mozilla Public License Version\n * 1.1 (the \"License\"); you may not use this file except in compliance with\n * the License. You may obtain a copy of the License at\n * http://www.mozilla.org/MPL/\n *\n * Software distributed under the License is distributed on an \"AS IS\" basis,\n * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License\n * for the specific language governing rights and limitations under the\n * License.\n *\n * The Original Code is TurboPower Abbrevia\n *\n * The Initial Developer of the Original Code is\n * TurboPower Software\n *\n * Portions created by the Initial Developer are Copyright (C) 1997-2002\n * the Initial Developer. All Rights Reserved.\n *\n * Contributor(s):\n *\n * ***** END LICENSE BLOCK ***** *)\n\n{*********************************************************}\n{* ABBREVIA: AbDfPkMg.pas                                *}\n{*********************************************************}\n{* Deflate package-merge algorithm                       *}\n{*********************************************************}\n\nunit AbDfPkMg;\n\n{$I AbDefine.inc}\n\ninterface\n\nuses\n  AbDfBase;\n\nprocedure GenerateCodeLengths(aMaxCodeLen  : integer;\n                        const aWeights     : array of integer;\n                          var aCodeLengths : array of integer;\n                              aStartInx    : integer;\n                              aLog         : TAbLogger);\n\nimplementation\n\ntype\n  PPkgNode = ^TPkgNode;\n  TPkgNode = packed record\n    pnWeight : integer;\n    pnCount  : integer;\n    pnLeft   : PPkgNode;\n    pnRight  : PPkgNode;\n  end;\n\n  PPkgNodeList = ^TPkgNodeList;\n  TPkgNodeList = array [0..pred(286 * 2)] of PPkgNode;\n  {Note: the \"286\" is the number of literal/length symbols, the\n         maximum number of weights we'll be calculating the optimal\n         code lengths for}\n\n\n{===helper routines==================================================}\nfunction IsCalcFeasible(aCount      : integer;\n                        aMaxCodeLen : integer) : boolean;\n\nbegin\n  {works out if length-limited codes can be calculated for a given\n   number of symbols and the maximum code length}\n\n  {return whether 2^aMaxCodeLen > aCount}\n  Result := (1 shl aMaxCodeLen) > aCount;\nend;\n{--------}\nprocedure QSS(aList  : PPkgNodeList;\n              aFirst : integer;\n              aLast  : integer);\nvar\n  L, R  : integer;\n  Pivot : integer;\n  Temp  : pointer;\nbegin\n  {while there are at least two items to sort}\n  while (aFirst < aLast) do begin\n    {the pivot is the middle item}\n    Pivot := aList^[(aFirst+aLast) div 2]^.pnWeight;\n    {set indexes and partition}\n    L := pred(aFirst);\n    R := succ(aLast);\n    while true do begin\n      repeat dec(R); until (aList^[R]^.pnWeight <= Pivot);\n      repeat inc(L); until (aList^[L]^.pnWeight >= Pivot);\n      if (L >= R) then Break;\n      Temp := aList^[L];\n      aList^[L] := aList^[R];\n      aList^[R] := Temp;\n    end;\n    {quicksort the first subfile}\n    if (aFirst < R) then\n      QSS(aList, aFirst, R);\n    {quicksort the second subfile - recursion removal}\n    aFirst := succ(R);\n  end;\nend;\n{--------}\nprocedure SortList(aList : PPkgNodeList; aCount : integer);\nbegin\n  QSS(aList, 0, pred(aCount));\nend;\n{--------}\nprocedure Accumulate(aNode : PPkgNode);\nbegin\n  while (aNode^.pnLeft <> nil) do begin\n    Accumulate(aNode^.pnLeft);\n    aNode := aNode^.pnRight;\n  end;\n  inc(aNode^.pnCount);\nend;\n{====================================================================}\n\n\n{===Interfaced routine===============================================}\nprocedure GenerateCodeLengths(aMaxCodeLen  : integer;\n                        const aWeights     : array of integer;\n                          var aCodeLengths : array of integer;\n                              aStartInx    : integer;\n                              aLog         : TAbLogger);\nvar\n  i   : integer;\n  Bit : integer;\n  WeightCount    : integer;\n  OrigList       : PPkgNodeList;\n  OrigListCount  : integer;\n  MergeList      : PPkgNodeList;\n  MergeListCount : integer;\n  PkgList        : PPkgNodeList;\n  PkgListCount   : integer;\n  OrigInx        : integer;\n  PkgInx         : integer;\n  Node           : PPkgNode;\n  NodeMgr        : TAbNodeManager;\nbegin\n  {calculate the number of weights}\n  WeightCount := succ(high(aWeights));\n\n  {check for dumb programming errors}\n  Assert((0 < aMaxCodeLen) and (aMaxCodeLen <= 15),\n         'GenerateCodeLengths: the maximum code length should be in the range 1..15');\n  Assert((1 <= WeightCount) and (WeightCount <= 286),\n         'GenerateCodeLengths: the weight array must have 1..286 elements');\n  Assert(IsCalcFeasible(WeightCount, aMaxCodeLen),\n         'GenerateCodeLengths: the package-merge algorithm should always be feasible');\n\n  {clear the code lengths array}\n  FillChar(aCodeLengths[aStartInx], WeightCount * sizeof(integer), 0);\n\n  {prepare for the try..finally}\n  OrigList := nil;\n  MergeList := nil;\n  PkgList := nil;\n  NodeMgr := nil;\n  try\n\n    {create the node manager}\n    NodeMgr := TAbNodeManager.Create(sizeof(TPkgNode));\n\n    {create the original list of nodes}\n    GetMem(OrigList, WeightCount * sizeof(PPkgNode));\n    OrigListCount := 0;\n    for i := 0 to pred(WeightCount) do\n      if (aWeights[i] <> 0) then begin\n        Node := NodeMgr.AllocNode;\n        Node^.pnLeft := nil;           { this will indicate a leaf}\n        Node^.pnRight := pointer(i);   { the index of the weight}\n        Node^.pnWeight := aWeights[i]; { the weight itself}\n        Node^.pnCount := 1;            { how many times used}\n        OrigList^[OrigListCount] := Node;\n        inc(OrigListCount);\n      end;\n\n    {we need at least 2 items, so make anything less a special case}\n    if (OrigListCount <= 1) then begin\n\n      {if there are no items at all in the original list, we need to\n       pretend that there is one, since we shall eventually need to\n       calculate a Count-1 value that cannot be negative}\n      if (OrigListCount = 0) then begin\n        aCodeLengths[aStartInx] := 1;\n        Exit;\n      end;\n\n      {otherwise there is only one item: set its code length directly}\n      for i := 0 to pred(WeightCount) do\n        if (aWeights[i] <> 0) then begin\n          aCodeLengths[aStartInx + i] := 1;\n          Exit;\n        end;\n    end;\n\n    {there are at least 2 items in the list; so sort the list}\n    SortList(OrigList, OrigListCount);\n\n    {create the merge and package lists}\n    GetMem(MergeList, OrigListCount * 2 * sizeof(PPkgNode));\n    GetMem(PkgList, OrigListCount * 2 * sizeof(PPkgNode));\n\n    {initialize the merge list to have the same items as the\n     original list}\n    Move(OrigList^, MergeList^, OrigListCount * sizeof(PPkgNode));\n    MergeListCount := OrigListCount;\n\n    {do aMaxCodeLen - 2 times...}\n    for Bit := 1 to pred(aMaxCodeLen) do begin\n\n      {generate the package list from the merge list by grouping pairs\n       from the merge list and adding them to the package list}\n      PkgListCount := 0;\n      for i := 0 to pred(MergeListCount div 2) do begin\n        Node := NodeMgr.AllocNode;\n        Node^.pnLeft := MergeList^[i * 2];\n        Node^.pnRight := MergeList^[i * 2 + 1];\n        Node^.pnWeight := Node^.pnLeft^.pnWeight +\n                          Node^.pnRight^.pnWeight;\n        {$IFOPT C+}\n        Node^.pnCount := 0;\n        {$ENDIF}\n        PkgList^[PkgListCount] := Node;\n        inc(PkgListCount);\n      end;\n\n      {merge the original list and the package list}\n      MergeListCount := 0;\n      OrigInx := 0;\n      PkgInx := 0;\n      {note the optimization here: the package list will *always* be\n       last to empty in the merge process since it will have at least\n       one item whose accumulated weight is greater than all of the\n       items in the original list}\n      while (OrigInx < OrigListCount) and (PkgInx < PkgListCount) do begin\n        if (OrigList^[OrigInx]^.pnWeight <= PkgList^[PkgInx]^.pnWeight) then begin\n          MergeList^[MergeListCount] := OrigList^[OrigInx];\n          inc(OrigInx);\n        end\n        else begin\n          MergeList^[MergeListCount] := PkgList^[PkgInx];\n          inc(PkgInx);\n        end;\n        inc(MergeListCount);\n      end;\n      if (OrigInx < OrigListCount) then begin\n        Move(OrigList^[OrigInx], MergeList^[MergeListCount],\n             (OrigListCount - OrigInx) * sizeof(PPkgNode));\n        inc(MergeListCount, (OrigListCount - OrigInx));\n      end\n      else begin\n        Move(PkgList^[PkgInx], MergeList^[MergeListCount],\n             (PkgListCount - PkgInx) * sizeof(PPkgNode));\n        inc(MergeListCount, (PkgListCount - PkgInx));\n      end;\n    end;\n\n    {calculate the code lengths}\n    for i := 0 to (OrigListCount * 2) - 3 do begin\n      Node := MergeList^[i];\n      if (Node^.pnLeft <> nil) then\n        Accumulate(Node);\n    end;\n    for i := 0 to pred(OrigListCount) do\n      aCodeLengths[aStartInx + integer(OrigList^[i].pnRight)] :=\n          OrigList^[i].pnCount;\n  finally\n    FreeMem(OrigList);\n    FreeMem(MergeList);\n    FreeMem(PkgList);\n    NodeMgr.Free;\n  end;\nend;\n{====================================================================}\n\nend.\n"
  },
  {
    "path": "lib/abbrevia/source/AbDfStrm.pas",
    "content": "(* ***** BEGIN LICENSE BLOCK *****\n * Version: MPL 1.1\n *\n * The contents of this file are subject to the Mozilla Public License Version\n * 1.1 (the \"License\"); you may not use this file except in compliance with\n * the License. You may obtain a copy of the License at\n * http://www.mozilla.org/MPL/\n *\n * Software distributed under the License is distributed on an \"AS IS\" basis,\n * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License\n * for the specific language governing rights and limitations under the\n * License.\n *\n * The Original Code is TurboPower Abbrevia\n *\n * The Initial Developer of the Original Code is\n * TurboPower Software\n *\n * Portions created by the Initial Developer are Copyright (C) 1997-2002\n * the Initial Developer. All Rights Reserved.\n *\n * Contributor(s):\n *\n * ***** END LICENSE BLOCK ***** *)\n\n{*********************************************************}\n{* ABBREVIA: AbDfStrm.pas                                *}\n{*********************************************************}\n{* Deflate streams unit for various streams              *}\n{*********************************************************}\n\nunit AbDfStrm;\n\n{$I AbDefine.inc}\n\ninterface\n\nuses\n  Classes,\n  AbDfBase,\n  AbDfInW,\n  AbDfHufD;\n\ntype\n  TAb32bit = longint; { a 32-bit type}\n\n  PAbDfLitBuckets = ^TAbDfLitBuckets;\n  TAbDfLitBuckets = array [0..285] of integer;\n  PAbDfDistBuckets = ^TAbDfDistBuckets;\n  TAbDfDistBuckets = array [0..31] of integer;\n  PAbDfCodeLenBuckets = ^TAbDfCodeLenBuckets;\n  TAbDfCodeLenBuckets = array [0..18] of integer;\n\n\nconst\n  AbExtractMask : array [1..31] of TAb32bit =\n       ($00000001, $00000003, $00000007, $0000000F,\n        $0000001F, $0000003F, $0000007F, $000000FF,\n        $000001FF, $000003FF, $000007FF, $00000FFF,\n        $00001FFF, $00003FFF, $00007FFF, $0000FFFF,\n        $0001FFFF, $0003FFFF, $0007FFFF, $000FFFFF,\n        $001FFFFF, $003FFFFF, $007FFFFF, $00FFFFFF,\n        $01FFFFFF, $03FFFFFF, $07FFFFFF, $0FFFFFFF,\n        $1FFFFFFF, $3FFFFFFF, $7FFFFFFF);\n\ntype\n  TAbDfInBitStream = class { input bit stream}\n    private\n      FBitBuffer : TAb32bit;\n      FBitsLeft  : integer;\n      FBufEnd    : PAnsiChar;\n      FBuffer    : PAnsiChar;\n      FBufPos    : PAnsiChar;\n      FByteCount : longint;\n      FFakeCount : integer;\n      FOnProgress: TAbProgressStep;\n      {$IFOPT C+}\n      FPeekCount : integer;\n      {$ENDIF}\n      FStream    : TStream;\n      FStreamSize: longint;\n    protected\n      function ibsFillBuffer : boolean;\n    public\n      constructor Create(aStream     : TStream;\n                         aOnProgress : TAbProgressStep;\n                         aStreamSize : longint);\n      destructor Destroy; override;\n\n      procedure AlignToByte;\n      procedure DiscardBits(aCount : integer);\n      procedure DiscardMoreBits(aCount : integer);\n      function PeekBits(aCount : integer) : integer;\n      function PeekMoreBits(aCount : integer) : integer;\n      function ReadBit : boolean;\n      function ReadBits(aCount : integer) : integer;\n      procedure ReadBuffer(var aBuffer; aCount : integer);\n\n      property BitBuffer : TAb32bit read FBitBuffer write FBitBuffer;\n      property BitsLeft  : integer read FBitsLeft write FBitsLeft;\n  end;\n\ntype\n  TAbDfOutBitStream = class { output bit stream}\n    private\n      FBitBuffer : TAb32bit;\n      FBitsUsed  : integer;\n      FBufEnd    : PAnsiChar;\n      FBuffer    : PAnsiChar;\n      FBufPos    : PAnsiChar;\n      FStream    : TStream;\n    protected\n      procedure obsEmptyBuffer;\n    public\n      constructor Create(aStream : TStream);\n      destructor Destroy; override;\n\n      procedure AlignToByte;\n      function Position : longint;\n      procedure WriteBit(aBit : boolean);\n      procedure WriteBits(aBits : integer; aCount : integer);\n      procedure WriteBuffer(var aBuffer; aCount : integer);\n      procedure WriteMoreBits(aBits : integer; aCount : integer);\n\n      property BitBuffer : TAb32bit read FBitBuffer write FBitBuffer;\n      property BitsUsed  : integer read FBitsUsed write FBitsUsed;\n  end;\n\ntype\n  TAbDfLZStream = class { LZ77 token stream}\n    private\n      FCurPos      : PAnsiChar;\n      FDistBuckets : PAbDfDistBuckets;\n      FDistCount   : integer;\n      FLitBuckets  : PAbDfLitBuckets;\n      FLitCount    : integer;\n      FLog         : TAbLogger;\n      FSlideWin    : TAbDfInputWindow;\n      FStartOfs    : Int64;\n      FStoredSize  : LongWord;\n      FStream      : PAnsiChar;\n      FStrmEnd     : PAnsiChar;\n      {$IFDEF UseLogging}\n      FSWPos       : longint;\n      {$ENDIF}\n      FUseDeflate64: boolean;\n    protected\n      function lzsGetApproxSize : LongWord;\n      function lzsGetStaticSize : integer;\n      function lzsGetStoredSize : integer;\n      function lzsIsFull : boolean;\n    public\n      constructor Create(aSlideWin     : TAbDfInputWindow;\n                         aUseDeflate64 : boolean;\n                         aLog          : TAbLogger);\n      destructor Destroy; override;\n\n      function AddLenDist(aLen : integer; aDist : integer) : boolean;\n        { returns true if the stream is \"full\"}\n      function AddLiteral(aCh : AnsiChar) : boolean;\n        { returns true if the stream is \"full\"}\n\n      procedure Clear;\n      procedure Encode(aBitStrm      : TAbDfOutBitStream;\n                       aLitTree      : TAbDfDecodeHuffmanTree;\n                       aDistTree     : TAbDfDecodeHuffmanTree;\n                       aUseDeflate64 : boolean);\n      procedure Rewind;\n\n      procedure ReadStoredBuffer(var aBuffer; aCount : integer);\n\n      property LenDistCount : integer read FDistCount;\n      property LiteralCount : integer read FLitCount;\n\n      property DistBuckets : PAbDfDistBuckets read FDistBuckets;\n      property LitBuckets : PAbDfLitBuckets read FLitBuckets;\n\n      property StaticSize  : integer read lzsGetStaticSize;{ in bits}\n      property StoredSize  : integer read lzsGetStoredSize;{ in bytes}\n  end;\n\ntype\n  TAbDfCodeLenStream = class { codelength token stream}\n    private\n      FBuckets  : PAbDfCodeLenBuckets;\n      FPosition : PAnsiChar;\n      FStream   : PAnsiChar; {array [0..285+32*2] of byte;}\n      FStrmEnd  : PAnsiChar;\n    protected\n    public\n      constructor Create(aLog : TAbLogger);\n      destructor Destroy; override;\n\n      procedure Build(const aCodeLens : array of integer;\n                            aCount    : integer);\n      procedure Encode(aBitStrm : TAbDfOutBitStream;\n                       aTree    : TAbDfDecodeHuffmanTree);\n\n      property Buckets : PAbDfCodeLenBuckets read FBuckets;\n  end;\n\nimplementation\n\nuses\n  SysUtils,\n  AbDfXlat;\n\ntype\n  PAb32bit = ^TAb32bit;\n\nconst\n  BitStreamBufferSize = 16*1024;\n\n{===TAbDfInBitStream=================================================}\nconstructor TAbDfInBitStream.Create(aStream     : TStream;\n                                    aOnProgress : TAbProgressStep;\n                                    aStreamSize : longint);\nbegin\n  {protect against dumb programming mistakes}\n  Assert(aStream <> nil,\n         'TAbDfInBitStream.Create: Cannot create a bit stream wrapping a nil stream');\n\n  {create the ancestor}\n  inherited Create;\n\n  {save the stream instance, allocate the buffer}\n  FStream := aStream;\n  GetMem(FBuffer, BitStreamBufferSize);\n\n  {save the on progress handler}\n  if Assigned(aOnProgress) and (aStreamSize > 0) then begin\n    FOnProgress := aOnProgress;\n    FStreamSize := aStreamSize;\n  end;\nend;\n{--------}\ndestructor TAbDfInBitStream.Destroy;\nbegin\n  {if we did some work...}\n  if (FBuffer <> nil) then begin\n\n    {reposition the underlying stream to the point where we stopped;\n     this position is equal to...\n      the position of the underlying stream, PLUS\n      the number of fake bytes we added, LESS\n      the number of bytes in the buffer, PLUS\n      the position in the buffer, PLUS\n      the number of complete bytes in the bit buffer}\n    FStream.Seek(FStream.Position +\n                 FFakeCount -\n                 (FBufEnd - FBuffer) +\n                 (FBufPos - FBuffer) -\n                 (FBitsLeft div 8), soBeginning);\n\n    {free the buffer}\n    FreeMem(FBuffer);\n  end;\n\n  {destroy the ancestor}\n  inherited Destroy;\nend;\n{--------}\nprocedure TAbDfInBitStream.AlignToByte;\nbegin\n  {get rid of the odd bits by shifting them out of the bit cache}\n  FBitBuffer := FBitBuffer shr (FBitsLeft mod 8);\n  dec(FBitsLeft, FBitsLeft mod 8);\nend;\n{--------}\nprocedure TAbDfInBitStream.DiscardBits(aCount : integer);\nvar\n  BitsToGo : integer;\nbegin\n  {aCount comes from a (possibly corrupt) stream, so check that it is\n   the correct range, 1..32}\n  if (aCount <= 0) or (aCount > 32) then\n    raise EAbInternalInflateError.Create(\n       'count of bits must be between 1 and 32 inclusive [TAbDfInBitStream.DiscardBits]');\n\n  {$IFOPT C+}\n  {verify that the count of bits to discard is less than or equal to\n   the recent count from PeekBits--a programming error}\n  Assert((aCount <= FPeekCount),\n         'TAbDfInBitStream.DiscardBits: discarding more bits than peeked');\n  {since we're discarding bits already peeked, reset the peek count}\n  FPeekCount := 0;\n  {$ENDIF}\n\n  {if we have more than enough bits in our bit buffer, update the\n   bitbuffer and the number of bits left}\n  if (aCount <= FBitsLeft) then begin\n    FBitBuffer := FBitBuffer shr aCount;\n    dec(FBitsLeft, aCount);\n  end\n\n  {otherwise we shall have to read another integer out of the buffer\n   to satisfy the request}\n  else begin\n    {check that there is data in the buffer, if not it's indicates a\n     corrupted stream: PeekBits should have filled it}\n    if (FBufPos = FBufEnd) then\n      raise EAbInternalInflateError.Create(\n         'no more compressed data in stream [TAbDfInBitStream.DiscardBits]');\n\n    {refill the bit buffer}\n    BitsToGo := aCount - FBitsLeft;\n    FBitBuffer := PAb32bit(FBufPos)^;\n    inc(FBufPos, sizeof(TAb32bit));\n    FBitBuffer := FBitBuffer shr BitsToGo;\n    FBitsLeft := 32 - BitsToGo;\n  end;\nend;\n{--------}\nprocedure TAbDfInBitStream.DiscardMoreBits(aCount : integer);\nvar\n  BitsToGo : integer;\nbegin\n  {aCount comes from a (possibly corrupt) stream, so check that it is\n   the correct range, 1..32}\n  if (aCount <= 0) or (aCount > 32) then\n    raise EAbInternalInflateError.Create(\n       'count of bits must be between 1 and 32 inclusive [TAbDfInBitStream.DiscardMoreBits]');\n\n  {$IFOPT C+}\n  {verify that the count of bits to discard is less than or equal to\n   the recent count from PeekBits--a programming error}\n  Assert((aCount <= FPeekCount),\n         'TAbDfInBitStream.DiscardBits: discarding more bits than peeked');\n  {since we're discarding bits already peeked, reset the peek count}\n  FPeekCount := 0;\n  {$ENDIF}\n\n  {check that there is data in the buffer, if not it's indicates a\n   corrupted stream: PeekBits/PeekMoreBits should have filled it}\n  if (FBufPos = FBufEnd) then\n    raise EAbInternalInflateError.Create(\n       'no more compressed data in stream [TAbDfInBitStream.DiscardBits]');\n\n  {refill the bit buffer}\n  BitsToGo := aCount - FBitsLeft;\n  FBitBuffer := PAb32bit(FBufPos)^;\n  inc(FBufPos, sizeof(TAb32bit));\n  FBitBuffer := FBitBuffer shr BitsToGo;\n  FBitsLeft := 32 - BitsToGo;\nend;\n{--------}\nfunction TAbDfInBitStream.ibsFillBuffer : boolean;\nvar\n  BytesRead   : longint;\n  BytesToRead : longint;\n  i           : integer;\n  Percent     : integer;\n  Buffer      : PAnsiChar;\n  BufferCount : integer;\nbegin\n  {check for dumb programming mistakes: this routine should only be\n   called if there are less than 4 bytes unused in the buffer}\n  Assert((FBufEnd - FBufPos) < sizeof(longint),\n         'TAbDfInBitStream.ibsFillBuffer: the buffer should be almost empty');\n\n  {if there are still 1, 2, or three bytes unused, move them to the\n   front of the buffer}\n  Buffer := FBuffer;\n  while (FBufPos <> FBufEnd) do begin\n    Buffer^ := FBufPos^;\n    inc(FBufPos);\n    inc(Buffer);\n  end;\n\n  {fill the buffer}\n  BytesToRead := BitStreamBufferSize - (Buffer - FBuffer);\n  BytesRead := FStream.Read(Buffer^, BytesToRead);\n\n  {reset the internal pointers}\n  FBufPos := FBuffer;\n  FBufEnd := Buffer + BytesRead;\n  BufferCount := FBufEnd - FBuffer;\n\n  {if, as a result of the read, no data is in the buffer, return\n   false; the caller will decide what to do about the problem}\n  if (BufferCount = 0) then\n    Result := false\n\n  {otherwise there is data to be processed}\n  else begin\n    Result := true;\n\n    {if we didn't read anything from the stream, we need to make sure\n     that enough buffer is zeroed out so that reading longint values\n     don't produce (dreadfully) bogus values}\n    if (BytesRead = 0) and ((BufferCount mod 4) <> 0) then begin\n      FFakeCount := 4 - (BufferCount mod 4);\n      for i := 0 to pred(FFakeCount) do begin\n        FBufEnd^ := #0;\n        inc(FBufEnd);\n      end;\n    end;\n\n    {fire the progress event}\n    if Assigned(FOnProgress) then begin\n      inc(FByteCount, BytesRead);\n      Percent := Round((100.0 * FByteCount) / FStreamSize);\n      FOnProgress(Percent);\n    end;\n  end;\nend;\n{--------}\nfunction TAbDfInBitStream.PeekBits(aCount : integer) : integer;\nvar\n  BitsToGo : integer;\n  TempBuffer : integer;\nbegin\n  {check that aCount is in the correct range 1..32}\n  Assert((0 <= aCount) and (aCount <= 32),\n         'TAbDfInBitStream.PeekBits: count of bits must be between 1 and 32 inclusive');\n\n  {if we have more than enough bits in our bit buffer, return as many\n   as needed}\n  if (aCount <= FBitsLeft) then\n    Result := FBitBuffer and AbExtractMask[aCount]\n\n  {otherwise we shall have to read another integer out of the buffer\n   to satisfy the request; note that this will fill the stream buffer\n   if required}\n  else begin\n    BitsToGo := aCount - FBitsLeft;\n    Result := FBitBuffer;\n    if ((FBufEnd - FBufPos) < sizeof(TAb32bit)) then\n      if not ibsFillBuffer then\n        TempBuffer := 0\n      else\n        TempBuffer := PAb32bit(FBufPos)^\n    else\n      TempBuffer := PAb32bit(FBufPos)^;\n    Result := Result +\n             ((TempBuffer and AbExtractMask[BitsToGo]) shl FBitsLeft);\n  end;\n\n  {$IFOPT C+}\n  {save the number of bits peeked for an assertion check later}\n  FPeekCount := aCount;\n  {$ENDIF}\nend;\n{--------}\nfunction TAbDfInBitStream.PeekMoreBits(aCount : integer) : integer;\nvar\n  BitsToGo : integer;\n  TempBuffer : integer;\nbegin\n  BitsToGo := aCount - FBitsLeft;\n  Result := FBitBuffer;\n  if ((FBufEnd - FBufPos) < sizeof(TAb32bit)) then\n    if not ibsFillBuffer then\n      TempBuffer := 0\n    else\n      TempBuffer := PAb32bit(FBufPos)^\n  else\n    TempBuffer := PAb32bit(FBufPos)^;\n  Result := Result +\n           ((TempBuffer and AbExtractMask[BitsToGo]) shl FBitsLeft);\nend;\n{--------}\nfunction TAbDfInBitStream.ReadBit : boolean;\nbegin\n  if (FBitsLeft = 0) then begin\n    if ((FBufEnd - FBufPos) < sizeof(TAb32bit)) then\n      if not ibsFillBuffer then\n        raise EAbInternalInflateError.Create(\n          'no more compressed data in stream [TAbDfInBitStream.ReadBit]');\n    FBitBuffer := PAb32bit(FBufPos)^;\n    inc(FBufPos, sizeof(TAb32bit));\n    FBitsLeft := 32;\n  end;\n  Result := Odd(FBitBuffer);\n  FBitBuffer := FBitBuffer shr 1;\n  dec(FBitsLeft);\nend;\n{--------}\nfunction TAbDfInBitStream.ReadBits(aCount : integer) : integer;\nvar\n  BitsToGo : integer;\nbegin\n  {aCount comes from a (possibly corrupt) stream, so check that it is\n   the correct range, 1..16}\n  if (aCount <= 0) or (aCount > 16) then\n    raise EAbInternalInflateError.Create(\n       'count of bits must be between 1 and 16 inclusive [TAbDfInBitStream.ReadBits]');\n\n  {if we have more than enough bits in our bit buffer, return as many\n   as needed, and update the bitbuffer and the number of bits left}\n  if (aCount <= FBitsLeft) then begin\n    Result := FBitBuffer and AbExtractMask[aCount];\n    FBitBuffer := FBitBuffer shr aCount;\n    dec(FBitsLeft, aCount);\n  end\n\n  {if we have exactly enough bits in our bit buffer, return them all,\n   and update the bitbuffer and the number of bits left}\n  else if (aCount = FBitsLeft) then begin\n    Result := FBitBuffer;\n    FBitBuffer := 0;\n    FBitsLeft := 0;\n  end\n\n  {otherwise we shall have to read another integer out of the buffer\n   to satisfy the request}\n  else begin\n    BitsToGo := aCount - FBitsLeft;\n    Result := FBitBuffer;\n    if ((FBufEnd - FBufPos) < sizeof(TAb32bit)) then\n      if not ibsFillBuffer then\n        raise EAbInternalInflateError.Create(\n          'no more compressed data in stream [TAbDfInBitStream.ReadBits]');\n    FBitBuffer := PAb32bit(FBufPos)^;\n    inc(FBufPos, sizeof(TAb32bit));\n    Result := Result +\n              ((FBitBuffer and AbExtractMask[BitsToGo]) shl FBitsLeft);\n    FBitBuffer := FBitBuffer shr BitsToGo;\n    FBitsLeft := 32 - BitsToGo;\n  end;\nend;\n{--------}\nprocedure TAbDfInBitStream.ReadBuffer(var aBuffer; aCount : integer);\nvar\n  i : integer;\n  Buffer : PAnsiChar;\n  BytesToRead   : integer;\n  BytesInBuffer : integer;\nbegin\n  {this method is designed to read a set of bytes and this can only be\n   done if the stream has been byte aligned--if it isn't, it's a\n   programming error}\n  Assert((FBitsLeft mod 8) = 0,\n         'TAbDfInBitStream.ReadBuffer. cannot read a buffer unless the stream is byte-aligned');\n\n  {get the address of the user buffer as a PChar: easier arithmetic}\n  Buffer := @aBuffer;\n\n  {if we have some bits left in the bit buffer, we need to copy those\n   first}\n  if (FBitsLeft > 0) then begin\n    BytesToRead := FBitsLeft div 8;\n    for i := 0 to pred(BytesToRead) do begin\n      Buffer^ := AnsiChar(FBitBuffer and $FF);\n      inc(Buffer);\n      FBitBuffer := FBitBuffer shr 8;\n    end;\n    {calculate the count of bytes still to read}\n    dec(aCount, BytesToRead);\n  end;\n\n  {calculate the number of bytes to copy}\n  BytesInBuffer := FBufEnd - FBufPos;\n  if (aCount <= BytesInBuffer) then\n    BytesToRead := aCount\n  else\n    BytesToRead := BytesInBuffer;\n\n  {copy the data from our buffer to the user buffer}\n  Move(FBufPos^, Buffer^, BytesToRead);\n\n  {update variables}\n  dec(aCount, BytesToRead);\n  inc(FBufPos, BytesToRead);\n\n  {while there is still data to copy, keep on filling our internal\n   buffer and copy it to the user buffer}\n  while (aCount <> 0) do begin\n\n    {increment the user buffer pointer past the data just copied}\n    inc(Buffer, BytesToRead);\n\n    {fill our buffer}\n    if not ibsFillBuffer then\n      raise EAbInternalInflateError.Create(\n        'no more compressed data in stream [TAbDfInBitStream.ReadBuffer]');\n\n    {calculate the number of bytes to copy}\n    BytesInBuffer := FBufEnd - FBufPos;\n    if (aCount <= BytesInBuffer) then\n      BytesToRead := aCount\n    else\n      BytesToRead := BytesInBuffer;\n\n    {copy the data from our buffer to the user buffer}\n    Move(FBufPos^, Buffer^, BytesToRead);\n\n    {update variables}\n    dec(aCount, BytesToRead);\n    inc(FBufPos, BytesToRead);\n  end;\n\n  {now we've copied everything over, reset the bit variables: they're\n   empty and need refilling}\n  FBitBuffer := 0;\n  FBitsLeft := 0;\nend;\n{====================================================================}\n\n\n{===TAbDfOutBitStream================================================}\nconstructor TAbDfOutBitStream.Create(aStream : TStream);\nbegin\n  {protect against dumb programming mistakes}\n  Assert(aStream <> nil,\n         'TAbDfOutBitStream.Create: Cannot create a bit stream wrapping a nil stream');\n\n  {create the ancestor}\n  inherited Create;\n\n  {save the stream instance, allocate the buffer}\n  FStream := aStream;\n  GetMem(FBuffer, BitStreamBufferSize);\n  FBufEnd := FBuffer + BitStreamBufferSize;\n  FBufPos := FBuffer;\nend;\n{--------}\ndestructor TAbDfOutBitStream.Destroy;\nvar\n  i : integer;\nbegin\n  {if the buffer was allocated...}\n  if (FBuffer <> nil) then begin\n\n    {if there are still some bits in the bit buffer...}\n    if (FBitsUsed <> 0) then begin\n\n      {pad the bit buffer to a byte boundary}\n      AlignToByte;\n\n      {empty the main buffer if there isn't enough room to copy over\n       the 1 to 4 bytes in the bit buffer}\n      if ((FBufEnd - FBufPos) < FBitsUsed div 8) then\n        obsEmptyBuffer;\n\n      {flush the bit buffer}\n      for i := 1 to (FBitsUsed div 8) do begin\n        FBufPos^ := AnsiChar(FBitBuffer);\n        FBitBuffer := FBitBuffer shr 8;\n        inc(FBufPos);\n      end;\n    end;\n\n    {if there is some data in the main buffer, empty it}\n    if (FBufPos <> FBuffer) then\n      obsEmptyBuffer;\n\n    {free the buffer}\n    FreeMem(FBuffer);\n  end;\n\n  {destroy the ancestor}\n  inherited Destroy;\nend;\n{--------}\nprocedure TAbDfOutBitStream.AlignToByte;\nbegin\n  {round up the number of bits used to the nearest 8}\n  FBitsUsed := (FBitsUsed + 7) and $F8;\n\n  {if the bit buffer is now full, flush it to the main buffer}\n  if (FBitsUsed = 32) then begin\n    if ((FBufEnd - FBufPos) < sizeof(TAb32bit)) then\n      obsEmptyBuffer;\n    PAb32bit(FBufPos)^ := FBitBuffer;\n    inc(FBufPos, sizeof(TAb32bit));\n    FBitBuffer := 0;\n    FBitsUsed := 0;\n  end;\nend;\n{--------}\nprocedure TAbDfOutBitStream.obsEmptyBuffer;\nvar\n  ByteCount    : integer;\n  BytesWritten : longint;\nbegin\n  {empty the buffer}\n  ByteCount := FBufPos - FBuffer;\n  BytesWritten := FStream.Write(FBuffer^, ByteCount);\n\n  {if we couldn't write the correct number of bytes, it's an error}\n  if (BytesWritten <> ByteCount) then\n    raise EAbInternalDeflateError.Create(\n       'could not write to the output stream [TAbDfInBitStream.obsEmptyBuffer]');\n\n  {reset the pointers}\n  FBufPos := FBuffer;\nend;\n{--------}\nfunction TAbDfOutBitStream.Position : longint;\nbegin\n  Assert(false,\n         'TAbDfOutBitStream.Position: not implemented yet!');\n  Result := -1;\nend;\n{--------}\nprocedure TAbDfOutBitStream.WriteBit(aBit : boolean);\nbegin\n  {only set the corresponding bit in the bit buffer if the passed bit\n   is set (the bit buffer is set to zero when emptied, so we don't\n   actually have to record clear bits)}\n  if aBit then\n    FBitBuffer := FBitBuffer or (1 shl FBitsUsed);\n\n  {we've now got one more bit}\n  inc(FBitsUsed);\n\n  {if the bit buffer is now full, flush it to the main buffer}\n  if (FBitsUsed = 32) then begin\n    if ((FBufEnd - FBufPos) < sizeof(TAb32bit)) then\n      obsEmptyBuffer;\n    PAb32bit(FBufPos)^ := FBitBuffer;\n    inc(FBufPos, sizeof(TAb32bit));\n    FBitBuffer := 0;\n    FBitsUsed := 0;\n  end;\nend;\n{--------}\nprocedure TAbDfOutBitStream.WriteBits(aBits : integer; aCount : integer);\nbegin\n  {protect against programming mistakes...}\n  {..the count should be in the range 1 to 16 (BTW, the latter is only\n     used once: Deflate64 with length symbol 258)}\n  Assert((0 < aCount) and (aCount <= 16),\n         'TAbDfOutBitStream.WriteBits: aCount should be from 1 to 16');\n  {..there shouldn't be more than aCount bits}\n  Assert((aBits shr aCount) = 0,\n         'TAbDfOutBitStream.WriteBits: aBits has more than aCount bits');\n\n  {copy as many bits as we can to the bit buffer}\n  FBitBuffer := FBitBuffer or (aBits shl FBitsUsed);\n\n  {increment the number of bits used}\n  inc(FBitsUsed, aCount);\n\n  {if we've overshot...}\n  if (FBitsUsed >= 32) then begin\n\n    {the bit buffer is now full, so flush it}\n    if ((FBufEnd - FBufPos) < sizeof(TAb32bit)) then\n      obsEmptyBuffer;\n    PAb32bit(FBufPos)^ := FBitBuffer;\n    inc(FBufPos, sizeof(TAb32bit));\n\n    {patch up the bit buffer and the number of bits used}\n    dec(FBitsUsed, 32);\n    FBitBuffer := aBits shr (aCount - FBitsUsed);\n  end;\nend;\n{--------}\nprocedure TAbDfOutBitStream.WriteBuffer(var aBuffer; aCount : integer);\nvar\n  Buffer : PAnsiChar;\n  BytesToCopy : integer;\nbegin\n  {guard against dumb programming errors: we must be byte aligned}\n  Assert((FBitsUsed and $7) = 0,\n         'TAbDfOutBitStream.WriteBuffer: must be byte aligned');\n\n  {use the user buffer as a PChar}\n  Buffer := @aBuffer;\n\n  {flush the bit buffer to the underlying stream}\n  while (FBitsUsed <> 0) do begin\n    if (FBufEnd = FBufPos) then\n      obsEmptyBuffer;\n    FBufPos^ := AnsiChar(FBitBuffer and $FF);\n    inc(FBufPos);\n    FBitBuffer := FBitBuffer shr 8;\n    dec(FBitsUsed, 8);\n  end;\n\n  {copy over the data to the underlying stream}\n  BytesToCopy := FBufEnd - FBufPos;\n  if (BytesToCopy > aCount) then\n    BytesToCopy := aCount;\n  Move(Buffer^, FBufPos^, BytesToCopy);\n  inc(FBufPos, BytesToCopy);\n  dec(aCount, BytesToCopy);\n  while (aCount <> 0) do begin\n    inc(Buffer, BytesToCopy);\n    obsEmptyBuffer;\n    BytesToCopy := FBufEnd - FBufPos;\n    if (BytesToCopy > aCount) then\n      BytesToCopy := aCount;\n    Move(Buffer^, FBufPos^, BytesToCopy);\n    inc(FBufPos, BytesToCopy);\n    dec(aCount, BytesToCopy);\n  end;\n\n  {finish with a flushed buffer}\n  obsEmptyBuffer;\nend;\n{--------}\nprocedure TAbDfOutBitStream.WriteMoreBits(aBits : integer; aCount : integer);\nbegin\n  {the bit buffer is now full, so flush it}\n  if ((FBufEnd - FBufPos) < sizeof(TAb32bit)) then\n    obsEmptyBuffer;\n  PAb32bit(FBufPos)^ := FBitBuffer;\n  inc(FBufPos, sizeof(TAb32bit));\n\n  {patch up the bit buffer and the number of bits used}\n  dec(FBitsUsed, 32);\n  FBitBuffer := aBits shr (aCount - FBitsUsed);\nend;\n{====================================================================}\n\n\n{===TAbDfLZStream====================================================}\nconst\n  {Implementation note: this stream size has been chosen so that if\n   the data must be stored, a block size of about 64K will result}\n  StreamSize = 160 * 1024;\ntype\n  PWord = ^word;\n{--------}\nconstructor TAbDfLZStream.Create(aSlideWin     : TAbDfInputWindow;\n                                 aUseDeflate64 : boolean;\n                                 aLog          : TAbLogger);\nbegin\n  {create the ancestor}\n  inherited Create;\n\n  {save the sliding window and the logger}\n  FSlideWin := aSlideWin;\n  FUseDeflate64 := aUseDeflate64;\n  FLog := aLog;\n\n  {create the buckets}\n  New(FDistBuckets);\n  New(FLitBuckets);\n\n  {create the memory stream, allocate its buffer, position at start}\n  GetMem(FStream, StreamSize);\n  Clear;\nend;\n{--------}\ndestructor TAbDfLZStream.Destroy;\nbegin\n  {free the buckets}\n  if (FDistBuckets <> nil) then\n    Dispose(FDistBuckets);\n  if (FLitBuckets <> nil) then\n    Dispose(FLitBuckets);\n\n  {free the memory stream}\n  if (FStream <> nil) then\n    FreeMem(FStream);\n\n  {destroy the ancestor}\n  inherited Destroy;\nend;\n{--------}\n{$IFDEF UseLogging}\nprocedure AddLenDistToLog(aLog     : TAbLogger;\n                          aPosn    : longint;\n                          aLen     : integer;\n                          aDist    : integer;\n                          aOverLap : boolean);\nbegin\n  {NOTE the reason for this separate routine is to avoid string\n        allocations and try..finally blocks in the main method: an\n        optimization issue}\n  if aOverLap then\n    aLog.WriteLine(Format('%8x Len: %-3d, Dist: %-5d  **overlap**',\n                          [aPosn, aLen, aDist]))\n  else\n    aLog.WriteLine(Format('%8x Len: %-3d, Dist: %-5d',\n                          [aPosn, aLen, aDist]));\nend;\n{$ENDIF}\n{--------}\nfunction TAbDfLZStream.AddLenDist(aLen : integer; aDist : integer)\n                                                            : boolean;\nvar\n  LenSymbol  : integer;\n  DistSymbol : integer;\n  CurPos     : PAnsiChar;\nbegin\n  {$IFDEF UseLogging}\n  {log it}\n  if (FLog <> nil) then begin\n    if (aLen > aDist) then\n      AddLenDistToLog(FLog, FSWPos, aLen, aDist, true)\n    else\n      AddLenDistToLog(FLog, FSWPos, aLen, aDist, false);\n    inc(FSWPos, aLen);\n  end;\n  {$ENDIF}\n\n  {write a length/distance record to the stream}\n  CurPos := FCurPos;\n  CurPos^ := AnsiChar(false);\n  inc(CurPos);\n  PWord(CurPos)^ := word(aLen - 1);\n  inc(CurPos, sizeof(word));\n  PWord(CurPos)^ := word(aDist - 1);\n  inc(CurPos, sizeof(word));\n  FCurPos := CurPos;\n\n  {increment the various counters}\n  inc(FDistCount);\n  inc(FStoredSize, aLen);\n\n  {convert the length and distance to their symbols}\n  {$IFOPT C+} {if Assertions are on}\n  LenSymbol := AbSymbolTranslator.TranslateLength(aLen);\n  DistSymbol := AbSymbolTranslator.TranslateDistance(aDist);\n  {$ELSE}\n  if (3 <= aLen) and (aLen <= 258) then\n    LenSymbol := AbSymbolTranslator.LenSymbols[aLen-3] + 257\n  else\n    LenSymbol := 285;\n  if (aDist <= 256) then\n    DistSymbol := AbSymbolTranslator.ShortDistSymbols[aDist - 1]\n  else if (aDist <= 32768) then\n    DistSymbol := AbSymbolTranslator.MediumDistSymbols[((aDist - 1) div 128) - 2]\n  else\n    DistSymbol := AbSymbolTranslator.LongDistSymbols[((aDist - 1) div 16384) - 2];\n  {$ENDIF}\n\n  {increment the buckets}\n  inc(FLitBuckets^[LenSymbol]);\n  inc(FDistBuckets^[DistSymbol]);\n\n  {return whether the stream is full and needs encoding}\n  Result := lzsIsFull;\nend;\n{--------}\n{$IFDEF UseLogging}\nprocedure AddLiteralToLog(aLog     : TAbLogger;\n                          aPosn    : longint;\n                          aCh      : AnsiChar);\nbegin\n  {NOTE the reason for this separate routine is to avoid string\n        allocations and try..finally blocks in the main method: an\n        optimization issue}\n  if (' ' < aCh) and (aCh <= '~') then\n    aLog.WriteLine(Format('%8x Char: %3d $%2x [%s]', [aPosn, ord(aCh), ord(aCh), aCh]))\n  else\n    aLog.WriteLine(Format('%8x Char: %3d $%2x', [aPosn, ord(aCh), ord(aCh)]));\nend;\n{$ENDIF}\n{--------}\nfunction TAbDfLZStream.AddLiteral(aCh : AnsiChar) : boolean;\nvar\n  CurPos : PAnsiChar;\nbegin\n  {$IFDEF UseLogging}\n  {log it}\n  if (FLog <> nil) then begin\n    AddLiteralToLog(FLog, FSWPos, aCh);\n    inc(FSWPos);\n  end;\n  {$ENDIF}\n\n  {write a literal to the internal stream}\n  CurPos := FCurPos;\n  CurPos^ := AnsiChar(true);\n  inc(CurPos);\n  CurPos^ := aCh;\n  inc(CurPos);\n  FCurPos := CurPos;\n\n  {increment the various counters}\n  inc(FLitCount);\n  inc(FLitBuckets^[byte(aCh)]);\n  inc(FStoredSize);\n\n  {return whether the stream is full and needs encoding}\n  Result := lzsIsFull;\nend;\n{--------}\nprocedure TAbDfLZStream.Clear;\nbegin\n  {position the stream at the start}\n  Rewind;\n\n  {reset all variables}\n  FStrmEnd := nil;\n  FLitCount := 0;\n  FDistCount := 0;\n  FStartOfs := FSlideWin.Position;\n  FStoredSize := 0;\n  {$IFDEF UseLogging}\n  FSWPos := FStartOfs;\n  {$ENDIF}\n\n  {reset the buckets}\n  FillChar(FLitBuckets^, sizeof(FLitBuckets^), 0);\n  FLitBuckets^[256] := 1; { end-of-block marker: it's always there...}\n  FillChar(FDistBuckets^, sizeof(FDistBuckets^), 0);\nend;\n{--------}\nprocedure TAbDfLZStream.Encode(aBitStrm      : TAbDfOutBitStream;\n                               aLitTree      : TAbDfDecodeHuffmanTree;\n                               aDistTree     : TAbDfDecodeHuffmanTree;\n                               aUseDeflate64 : boolean);\nvar\n  Len       : integer;\n  Dist      : integer;\n  Symbol    : integer;\n  CurPos    : PAnsiChar;\n  StrmEnd   : PAnsiChar;\n  Code      : longint;\n  ExtraBits : longint;\nbegin\n  {rewind the LZ77 stream}\n  Rewind;\n\n  {for speed use local variables}\n  CurPos := FCurPos;\n  StrmEnd := FStrmEnd;\n\n  {while there are still items in the stream...}\n  while (CurPos < StrmEnd) do begin\n\n    {if the next item is a literal...}\n    if boolean(CurPos^) then begin\n\n      {encode the literal character as a symbol}\n      inc(CurPos);\n      {$IFOPT C+} {if Assertions are on}\n      Code := aLitTree.Encode(byte(CurPos^));\n      {$ELSE}\n      Code := aLitTree.Encodes^[byte(CurPos^)];\n      {$ENDIF}\n      inc(CurPos);\n\n      {write the code out to the bit stream}\n      {$IFOPT C+}\n      aBitStrm.WriteBits(Code and $FFFF, (Code shr 16) and $FF);\n      {$ELSE}\n      with aBitStrm do begin\n        BitBuffer := BitBuffer or ((Code and $FFFF) shl BitsUsed);\n        BitsUsed := BitsUsed + ((Code shr 16) and $FF);\n        if (BitsUsed >= 32) then\n          WriteMoreBits(Code and $FFFF, (Code shr 16) and $FF);\n      end;\n      {$ENDIF}\n    end\n\n    {otherwise it's a length/distance pair}\n    else begin\n\n      {DO THE LENGTH FIRST-------------------------------------------}\n      {get the length from the stream}\n      inc(CurPos);\n      Len := integer(PWord(CurPos)^) + 1;\n      inc(CurPos, sizeof(word));\n\n      {translate it to a symbol and convert that to a code using the\n       literal/length huffman tree}\n      {$IFOPT C+} {if Assertions are on}\n      Symbol := AbSymbolTranslator.TranslateLength(Len);\n      Code := aLitTree.Encode(Symbol);\n      {$ELSE}\n      if (3 <= Len) and (Len <= 258) then\n        Symbol := AbSymbolTranslator.LenSymbols[Len-3] + 257\n      else\n        Symbol := 285;\n      Code := aLitTree.Encodes^[Symbol];\n      {$ENDIF}\n\n      {output the length code}\n      {$IFOPT C+}\n      aBitStrm.WriteBits(Code and $FFFF, (Code shr 16) and $FF);\n      {$ELSE}\n      with aBitStrm do begin\n        BitBuffer := BitBuffer or ((Code and $FFFF) shl BitsUsed);\n        BitsUsed := BitsUsed + ((Code shr 16) and $FF);\n        if (BitsUsed >= 32) then\n          WriteMoreBits(Code and $FFFF, (Code shr 16) and $FF);\n      end;\n      {$ENDIF}\n\n      {if the length symbol were 285, its definition changes from Deflate\n       to Deflate64, so make it a special case: for Deflate there are no\n       extra bits, for Deflate64 output the (length - 3) as 16 bits}\n      if (Symbol = 285) then begin\n        if aUseDeflate64 then begin\n          {$IFOPT C+}\n          aBitStrm.WriteBits(Len - 3, 16);\n          {$ELSE}\n          with aBitStrm do begin\n            BitBuffer := BitBuffer or ((Len - 3) shl BitsUsed);\n            BitsUsed := BitsUsed + 16;\n            if (BitsUsed >= 32) then\n              WriteMoreBits(Len - 3, 16);\n          end;\n          {$ENDIF}\n        end;\n      end\n\n      {otherwise if there are extra bits to be output for this length,\n       calculate them and output them}\n      else begin\n        ExtraBits := Code shr 24;\n        if (ExtraBits <> 0) then begin\n          {$IFOPT C+}\n          aBitStrm.WriteBits((Len - dfc_LengthBase[Symbol - 257]),\n                              ExtraBits);\n          {$ELSE}\n          with aBitStrm do begin\n            BitBuffer := BitBuffer or\n                  ((Len - dfc_LengthBase[Symbol - 257]) shl BitsUsed);\n            BitsUsed := BitsUsed + ExtraBits;\n            if (BitsUsed >= 32) then\n              WriteMoreBits((Len - dfc_LengthBase[Symbol - 257]),\n                            ExtraBits);\n          end;\n          {$ENDIF}\n        end;\n      end;\n\n      {DO THE DISTANCE NEXT------------------------------------------}\n      {get the distance from the stream}\n      Dist := integer(PWord(CurPos)^) + 1;\n      inc(CurPos, sizeof(word));\n\n      {translate it to a symbol and convert that to a code using the\n       distance huffman tree}\n      {$IFOPT C+} {if Assertions are on}\n      Symbol := AbSymbolTranslator.TranslateDistance(Dist);\n      Assert(aUseDeflate64 or (Symbol < 30),\n         'TAbDfLZStream.Encode: a Deflate64 distance symbol has been generated for Deflate');\n      Code := aDistTree.Encode(Symbol);\n      {$ELSE}\n      if (Dist <= 256) then\n        Symbol := AbSymbolTranslator.ShortDistSymbols[Dist - 1]\n      else if (Dist <= 32768) then\n        Symbol := AbSymbolTranslator.MediumDistSymbols[((Dist - 1) div 128) - 2]\n      else\n        Symbol := AbSymbolTranslator.LongDistSymbols[((Dist - 1) div 16384) - 2];\n      Code := aDistTree.Encodes^[Symbol];\n      {$ENDIF}\n\n      {output the distance code}\n      {$IFOPT C+}\n      aBitStrm.WriteBits(Code and $FFFF, (Code shr 16) and $FF);\n      {$ELSE}\n      with aBitStrm do begin\n        BitBuffer := BitBuffer or ((Code and $FFFF) shl BitsUsed);\n        BitsUsed := BitsUsed + ((Code shr 16) and $FF);\n        if (BitsUsed >= 32) then\n          WriteMoreBits(Code and $FFFF, (Code shr 16) and $FF);\n      end;\n      {$ENDIF}\n\n      {if there are extra bits to be output for this distance, calculate\n       them and output them}\n      ExtraBits := Code shr 24;\n      if (ExtraBits <> 0) then begin\n        {$IFOPT C+}\n        aBitStrm.WriteBits((Dist - dfc_DistanceBase[Symbol]),\n                           ExtraBits);\n        {$ELSE}\n        with aBitStrm do begin\n          BitBuffer := BitBuffer or\n                     ((Dist - dfc_DistanceBase[Symbol]) shl BitsUsed);\n          BitsUsed := BitsUsed + ExtraBits;\n          if (BitsUsed >= 32) then\n            WriteMoreBits((Dist - dfc_DistanceBase[Symbol]),\n                          ExtraBits);\n        end;\n        {$ENDIF}\n      end;\n    end;\n  end;\n\n{clear the stream; ready for some more items}\n{  Clear;}\nend;\n{--------}\nfunction TAbDfLZStream.lzsGetApproxSize : LongWord;\nvar\n  i : integer;\nbegin\n  {note: calculates an approximate compressed size without taking too\n         long about it. The average encoded bit length for literals\n         and lengths is assumed to be 8. Distances are assumed to\n         follow the static tree definition (ie, 5 bits per distance,\n         plus any extra bits).\n         There are FLitCount literals, FDistCount lengths, and\n         FDistCount distances}\n  Result := (13 * FDistCount) + (8 * FLitCount);\n  for i := 4 to 31 do\n    inc(Result, FDistBuckets^[i] * dfc_DistExtraBits[i]);\n  Result := Result div 8;\nend;\n{--------}\nfunction TAbDfLZStream.lzsGetStaticSize : integer;\nvar\n  i : integer;\nbegin\n  Result := 0;\n  for i := 0 to 143 do\n    inc(Result, FLitBuckets^[i] * 8);\n  for i := 144 to 255 do\n    inc(Result, FLitBuckets^[i] * 9);\n  inc(Result, FLitBuckets^[256] * 7);\n  for i := 257 to 279 do\n    inc(Result, FLitBuckets^[i] *\n                (7 + dfc_LitExtraBits[i - dfc_LitExtraOffset]));\n  for i := 280 to 284 do\n    inc(Result, FLitBuckets^[i] *\n                (8 + dfc_LitExtraBits[i - dfc_LitExtraOffset]));\n  if FUseDeflate64 then\n    inc(Result, FLitBuckets^[285] * (8 + 16))\n  else\n    inc(Result, FLitBuckets^[285] * 8);\n\n  for i := 0 to 31 do\n    inc(Result, FDistBuckets^[i] * (5 + dfc_DistExtraBits[i]));\nend;\n{--------}\nfunction TAbDfLZStream.lzsGetStoredSize : integer;\nbegin\n  Result := FStoredSize;\n{Result := FSlideWin.Position - FStartOfs;}\nend;\n{--------}\nfunction TAbDfLZStream.lzsIsFull : boolean;\nbegin\n  {if the number of hits on the (eventual) literal tree is a multiple\n   of 8192, the stream is full if the majority were straight literals\n   and we're getting approx 50% compression}\n  if (((FLitCount + FDistCount) and $1FFF) = 0) then begin\n    Result := (FDistCount < FLitCount) and\n              (lzsGetApproxSize < (FStoredSize div 2));\n    if Result then\n      Exit;\n  end;\n\n  {otherwise the stream is full if the number of hits on the literal\n   tree or on the distance tree is 32768}\n{    Result := (FCurPos - FStream) > (StreamSIze - 100);}\n  Result := (FDistCount >= 32768) or\n            ((FLitCount + FDistCount) >= 32768);\nend;\n{--------}\nprocedure TAbDfLZStream.ReadStoredBuffer(var aBuffer; aCount : integer);\nbegin\n  FSlideWin.ReadBuffer(aBuffer, aCount, FStartOfs);\n  inc(FStartOfs, aCount);\nend;\n{--------}\nprocedure TAbDfLZStream.Rewind;\nbegin\n  {position the stream at the beginning}\n  FStrmEnd := FCurPos;\n  FCurPos := FStream;\nend;\n{====================================================================}\n\n\n{===TAbDfCodeLenStream===============================================}\nconstructor TAbDfCodeLenStream.Create(aLog : TAbLogger);\nbegin\n  {create the ancestor}\n  inherited Create;\n\n  {allocate the stream (to contain all literals and distances and\n   possible extra data}\n  GetMem(FStream, (285 + 32) * 2);\n  FPosition := FStream;\n\n  {allocate the buckets}\n  FBuckets := AllocMem(sizeof(TAbDfCodeLenBuckets));\nend;\n{--------}\ndestructor TAbDfCodeLenStream.Destroy;\nbegin\n  {free the stream}\n  if (FStream <> nil) then\n    FreeMem(FStream);\n\n  {free the buckets}\n  if (FBuckets <> nil) then\n    Dispose(FBuckets);\n\n  {destroy the ancestor}\n  inherited Destroy;\nend;\n{--------}\nprocedure TAbDfCodeLenStream.Build(const aCodeLens : array of integer;\n                                         aCount    : integer);\nvar\n  i : integer;\n  State       : (ScanStart, ScanNormal, Got2nd, Got3rd);\n  Count       : integer;\n  ThisCount   : integer;\n  CodeLen     : integer;\n  PrevCodeLen : integer;\n  CurPos      : PAnsiChar;\n  Buckets     : PAbDfCodeLenBuckets;\nbegin\n  {start the automaton}\n  State := ScanStart;\n  CurPos := FStream;\n  Buckets := FBuckets;\n  Count := 0;\n  PrevCodeLen := 0;\n\n  {for all the codelengths in the array (plus a fake one at the end to\n   ensure all codeslengths are counted)...}\n  for i := 0 to aCount do begin\n\n    {get the current codelength}\n    if (i = aCount) then\n      CodeLen := -1\n    else\n      CodeLen := aCodeLens[i];\n\n    {switch based on the state...}\n    case State of\n      ScanStart :\n        begin\n          PrevCodeLen := CodeLen;\n          State := ScanNormal;\n        end;\n\n      ScanNormal :\n        begin\n          {if the current code is the same as the previous, move to\n           the next state}\n          if (CodeLen = PrevCodeLen) then\n            State := Got2nd\n\n          {otherwise output the previous code}\n          else begin\n            CurPos^ := AnsiChar(PrevCodeLen);\n            inc(CurPos);\n            inc(Buckets^[PrevCodeLen]);\n            PrevCodeLen := CodeLen;\n          end;\n        end;\n\n      Got2nd :\n        begin\n          {if the current code is the same as the previous, move to\n           the next state; we now have three similar codes in a row}\n          if (CodeLen = PrevCodeLen) then begin\n            State := Got3rd;\n            Count := 3;\n          end\n\n          {otherwise output the previous two similar codes, move back\n           to the initial state}\n          else begin\n            CurPos^ := AnsiChar(PrevCodeLen);\n            inc(CurPos);\n            CurPos^ := AnsiChar(PrevCodeLen);\n            inc(CurPos);\n            inc(Buckets^[PrevCodeLen], 2);\n            PrevCodeLen := CodeLen;\n            State := ScanNormal;\n          end;\n        end;\n\n      Got3rd:\n        begin\n          {if the current code is the same as the previous, increment\n           the count of similar codes}\n          if (CodeLen = PrevCodeLen) then\n            inc(Count)\n\n          {otherwise we need to output the repeat values...}\n          else begin\n\n            {if the previous code were a zero code...}\n            if (PrevCodeLen = 0) then begin\n\n              {while there are zero codes to be output...}\n              while (Count <> 0) do begin\n\n                {if there are less than three zero codes, output them\n                 individually}\n                if (Count < 3) then begin\n                  while (Count <> 0) do begin\n                    CurPos^ := #0;\n                    inc(CurPos);\n                    inc(Buckets^[0]);\n                    dec(Count);\n                  end;\n                end\n\n                {if there are less than 11 successive zero codes,\n                 output a 17 code and the count of zeros}\n                else if (Count < 11) then begin\n                  CurPos^ := #17;\n                  inc(CurPos);\n                  inc(Buckets^[17]);\n                  CurPos^ := AnsiChar(Count - 3);\n                  inc(CurPos);\n                  Count := 0;\n                end\n\n                {otherwise output an 18 code and the count of zeros}\n                else begin\n                  ThisCount := Count;\n                  if (ThisCount > 138) then\n                    ThisCount := 138;\n                  CurPos^ := #18;\n                  inc(CurPos);\n                  inc(Buckets^[18]);\n                  CurPos^ := AnsiChar(ThisCount - 11);\n                  inc(CurPos);\n                  dec(Count, ThisCount);\n                end;\n              end;\n            end\n\n            {otherwise the previous code was a non-zero code...}\n            else begin\n\n              {output the first code}\n              CurPos^ := AnsiChar(PrevCodeLen);\n              inc(CurPos);\n              inc(Buckets^[PrevCodeLen]);\n              dec(Count);\n\n              {while there are more codes to be output...}\n              while (Count <> 0) do begin\n\n                {if there are less than three codes, output them\n                 individually}\n                if (Count < 3) then begin\n                  while (Count <> 0) do begin\n                    CurPos^ := AnsiChar(PrevCodeLen);\n                    inc(CurPos);\n                    inc(Buckets^[PrevCodeLen]);\n                    dec(Count);\n                  end;\n                end\n\n                {otherwise output an 16 code and the count}\n                else begin\n                  ThisCount := Count;\n                  if (ThisCount > 6) then\n                    ThisCount := 6;\n                  CurPos^ := #16;\n                  inc(CurPos);\n                  inc(Buckets^[16]);\n                  CurPos^ := AnsiChar(ThisCount - 3);\n                  inc(CurPos);\n                  dec(Count, ThisCount);\n                end;\n              end;\n            end;\n\n            {move back to the initial state}\n            PrevCodeLen := CodeLen;\n            State := ScanNormal;\n          end;\n        end;\n    end;\n  end;\n\n  {set the read position}\n  FStrmEnd := CurPos;\n  FPosition := FStream;\nend;\n{--------}\nprocedure TAbDfCodeLenStream.Encode(aBitStrm : TAbDfOutBitStream;\n                                    aTree    : TAbDfDecodeHuffmanTree);\nvar\n  Symbol    : integer;\n  ExtraData : integer;\n  Code      : longint;\n  CurPos    : PAnsiChar;\n  StrmEnd   : PAnsiChar;\nbegin\n  {prepare for the loop}\n  CurPos := FPosition;\n  StrmEnd := FStrmEnd;\n\n  {while there are tokens in the stream...}\n  while (CurPos <> StrmEnd) do begin\n\n    {get the next symbol}\n    Symbol := ord(CurPos^);\n    inc(CurPos);\n\n    {if the symbol is 0..15, get the code and output it}\n    if (Symbol <= 15) then begin\n      {$IFOPT C+} {if Assertions are on}\n      Code := aTree.Encode(Symbol);\n      {$ELSE}\n      Code:= aTree.Encodes^[Symbol];\n      {$ENDIF}\n      aBitStrm.WriteBits(Code and $FFFF, (Code shr 16) and $FF);\n    end\n\n    {otherwise the symbol is 16, 17, or 18}\n    else begin\n      {get the extra data}\n      ExtraData := ord(CurPos^);\n      inc(CurPos);\n      {get the code and output it}\n      {$IFOPT C+} {if Assertions are on}\n      Code := aTree.Encode(Symbol);\n      {$ELSE}\n      Code:= aTree.Encodes^[Symbol];\n      {$ENDIF}\n      aBitStrm.WriteBits(Code and $FFFF, (Code shr 16) and $FF);\n      if (Symbol = 16) then\n        aBitStrm.WriteBits(ExtraData, 2)\n      else if (Symbol = 17) then\n        aBitStrm.WriteBits(ExtraData, 3)\n      else {Symbol = 18}\n        aBitStrm.WriteBits(ExtraData, 7);\n    end;\n  end;\nend;\n{====================================================================}\n\nend.\n"
  },
  {
    "path": "lib/abbrevia/source/AbDfXlat.pas",
    "content": "(* ***** BEGIN LICENSE BLOCK *****\n * Version: MPL 1.1\n *\n * The contents of this file are subject to the Mozilla Public License Version\n * 1.1 (the \"License\"); you may not use this file except in compliance with\n * the License. You may obtain a copy of the License at\n * http://www.mozilla.org/MPL/\n *\n * Software distributed under the License is distributed on an \"AS IS\" basis,\n * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License\n * for the specific language governing rights and limitations under the\n * License.\n *\n * The Original Code is TurboPower Abbrevia\n *\n * The Initial Developer of the Original Code is\n * TurboPower Software\n *\n * Portions created by the Initial Developer are Copyright (C) 1997-2002\n * the Initial Developer. All Rights Reserved.\n *\n * Contributor(s):\n *\n * ***** END LICENSE BLOCK ***** *)\n\n{*********************************************************}\n{* ABBREVIA: AbDfXlat.pas                                *}\n{*********************************************************}\n{* Deflate length/dist to symbol translator              *}\n{*********************************************************}\n\nunit AbDfXlat;\n\n{$I AbDefine.inc}\n\ninterface\n\nuses\n  SysUtils;\n\ntype\n  TAbDfTranslator = class\n    private\n      FBuffer : PAnsiChar;\n      FLenSymbols        : PByteArray;\n                           {for lengths 3..258}\n      FLongDistSymbols   : PByteArray;\n                           {for distances 32769..65536 (deflate64)}\n      FMediumDistSymbols : PByteArray;\n                           {for distances 257..32768}\n      FShortDistSymbols  : PByteArray;\n                           {for distances 1..256}\n    protected\n      procedure trBuild;\n    public\n      constructor Create;\n      destructor Destroy; override;\n\n      function TranslateLength(aLen  : integer): integer;\n      function TranslateDistance(aDist : integer) : integer;\n\n      property LenSymbols : PByteArray read FLenSymbols;\n      property LongDistSymbols : PByteArray read FLongDistSymbols;\n      property MediumDistSymbols : PByteArray read FMediumDistSymbols;\n      property ShortDistSymbols  : PByteArray read FShortDistSymbols;\n  end;\n\nvar\n  AbSymbolTranslator : TAbDfTranslator;\n\nimplementation\n\nuses\n  AbDfBase;\n\n{====================================================================}\nconstructor TAbDfTranslator.Create;\nbegin\n  {create the ancestor}\n  inherited Create;\n\n  {allocate the translation arrays (the buffer *must* be zeroed)}\n  FBuffer := AllocMem(256 + 2 + 256 + 256);\n  FLenSymbols := PByteArray(FBuffer);\n  FLongDistSymbols := PByteArray(FBuffer + 256);\n  FMediumDistSymbols := PByteArray(FBuffer + 256 + 2);\n  FShortDistSymbols := PByteArray(FBuffer + 256 + 2 + 256);\n\n  {build the translation arrays}\n  trBuild;\nend;\n{--------}\ndestructor TAbDfTranslator.Destroy;\nbegin\n  if (FBuffer <> nil) then\n    FreeMem(FBuffer);\n  inherited Destroy;\nend;\n{--------}\nfunction TAbDfTranslator.TranslateDistance(aDist : integer) : integer;\nbegin\n  {save against dumb programming mistakes}\n  Assert((1 <= aDist) and (aDist <= 65536),\n         'TAbDfTranslator.Translate: distance should be 1..65536');\n\n  {translate the distance}\n  if (aDist <= 256) then\n    Result := FShortDistSymbols[aDist - 1]\n  else if (aDist <= 32768) then\n    Result := FMediumDistSymbols[((aDist - 1) div 128) - 2]\n  else\n    Result := FLongDistSymbols[((aDist - 1) div 16384) - 2];\nend;\n{--------}\nfunction TAbDfTranslator.TranslateLength(aLen  : integer): integer;\nbegin\n  {save against dumb programming mistakes}\n  Assert((3 <= aLen) and (aLen <= 65536),\n         'TAbDfTranslator.Translate: length should be 3..65536');\n\n  {translate the length}\n  dec(aLen, 3);\n  if (0 <= aLen) and (aLen <= 255) then\n    Result := FLenSymbols[aLen] + 257\n  else\n    Result := 285;\nend;\n{--------}\nprocedure TAbDfTranslator.trBuild;\nvar\n  i     : integer;\n  Len   : integer;\n  Dist  : integer;\n  Value : integer;\nbegin\n  {initialize the length translation array; elements will contain\n   (Symbol - 257) for a given (length - 3)}\n  for i := low(dfc_LengthBase) to pred(high(dfc_LengthBase)) do begin\n    Len := dfc_LengthBase[i] - 3;\n    FLenSymbols[Len] := i;\n  end;\n  FLenSymbols[255] := 285 - 257;\n  Value := -1;\n  for i := 0 to 255 do begin\n    if (Value < FLenSymbols[i]) then\n      Value := FLenSymbols[i]\n    else\n      FLenSymbols[i] := Value;\n  end;\n\n  {initialize the short distance translation array: it will contain\n   the Symbol for a given (distance - 1) where distance <= 256}\n  for i := 0 to 15 do begin\n    Dist := dfc_DistanceBase[i] - 1;\n    FShortDistSymbols[Dist] := i;\n  end;\n  Value := -1;\n  for i := 0 to 255 do begin\n    if (Value < FShortDistSymbols[i]) then\n      Value := FShortDistSymbols[i]\n    else\n      FShortDistSymbols[i] := Value;\n  end;\n\n  {initialize the medium distance translation array: it will contain\n   the Symbol for a given (((distance - 1) div 128) - 2) where\n   distance is in the range 256..32768}\n  for i := 16 to 29 do begin\n    Dist := ((dfc_DistanceBase[i] - 1) div 128) - 2;\n    FMediumDistSymbols[Dist] := i;\n  end;\n  Value := -1;\n  for i := 0 to 255 do begin\n    if (Value < FMediumDistSymbols[i]) then\n      Value := FMediumDistSymbols[i]\n    else\n      FMediumDistSymbols[i] := Value;\n  end;\n\n  {initialize the long distance translation array: it will contain the\n   Symbol for a given ((distance - 1) div 16384) - 2) for distances\n   over 32768 in deflate64}\n  FLongDistSymbols[0] := 30;\n  FLongDistSymbols[1] := 31;\nend;\n{====================================================================}\n\ninitialization\n  AbSymbolTranslator := TAbDfTranslator.Create;\n\nfinalization\n  AbSymbolTranslator.Free;\n\nend.\n"
  },
  {
    "path": "lib/abbrevia/source/AbDlgDir.pas",
    "content": "(* ***** BEGIN LICENSE BLOCK *****\n * Version: MPL 1.1\n *\n * The contents of this file are subject to the Mozilla Public License Version\n * 1.1 (the \"License\"); you may not use this file except in compliance with\n * the License. You may obtain a copy of the License at\n * http://www.mozilla.org/MPL/\n *\n * Software distributed under the License is distributed on an \"AS IS\" basis,\n * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License\n * for the specific language governing rights and limitations under the\n * License.\n *\n * The Original Code is TurboPower Abbrevia\n *\n * The Initial Developer of the Original Code is\n * TurboPower Software\n *\n * Portions created by the Initial Developer are Copyright (C) 1997-2002\n * the Initial Developer. All Rights Reserved.\n *\n * Contributor(s):\n *\n * ***** END LICENSE BLOCK ***** *)\n\n{*********************************************************}\n{* ABBREVIA: AbDlgDir.pas                                *}\n{*********************************************************}\n{* ABBREVIA: Dialog - Directory                          *}\n{*   Use AbQDgDir.pas for CLX                            *}\n{*********************************************************}\n\n{$IFNDEF UsingCLX}\nunit AbDlgDir;\n{$ENDIF}\n\n{$I AbDefine.inc}\n\ninterface\n\nuses\n{$IFDEF MSWINDOWS}\n  Windows, Messages, ShlObj, ActiveX,\n{$ENDIF}\n  SysUtils, Classes,\n{$IFDEF UsingClx}\n  QButtons, QExtCtrls, QGraphics, QForms, QControls, QStdCtrls,\n{$ELSE}\n  Buttons, ExtCtrls, Graphics, Forms, Controls, StdCtrls,\n  {$WARN UNIT_PLATFORM OFF}\n  FileCtrl,\n  {$WARN UNIT_PLATFORM ON}\n{$ENDIF}\n  AbResString;\n\ntype\n{$IFNDEF UsingClx}\n  TDirDlg = class(TForm)\n    OKBtn: TButton;\n    CancelBtn: TButton;\n    Bevel1: TBevel;\n    DriveComboBox1: TDriveComboBox;\n    DirectoryListBox1: TDirectoryListBox;\n    Panel1: TPanel;\n    procedure DirectoryListBox1Change(Sender: TObject);\n    procedure FormCreate(Sender: TObject);\n  public\n    SelectedFolder: string;\n  end;\n{$ELSE}\n  TDirDlg = class(TForm)\n    OKBtn: TButton;\n    CancelBtn: TButton;\n    Bevel1: TBevel;\n    Panel1: TPanel;\n    procedure DirectoryListBox1Change(Sender: TObject);\n    procedure FormCreate(Sender: TObject);\n  public\n    SelectedFolder: string;\n  end;\n{$ENDIF}\n\n\n{$IFDEF MSWINDOWS}\ntype\n  TAbDirDlg = class(TComponent)\n  protected {private}\n    FAdditionalText      : string;\n    FCaption             : string;\n    FHandle              : Integer;\n    FIDList              : PItemIDList;\n    FSelectedFolder      : string;\n\n    procedure SetSelectedFolder(const Value : string);\n    procedure FreeIDList;\n\n  public {properties}\n    property AdditionalText : string\n      read FAdditionalText\n      write FAdditionalText;\n    property Caption : string\n      read FCaption\n      write FCaption;\n    property Handle : Integer\n      read FHandle;\n    property IDList : PItemIDList\n      read FIDList;\n    property SelectedFolder : string\n      read FSelectedFolder\n      write SetSelectedFolder;\n\n  public {methods}\n    constructor Create(AOwner : TComponent);\n      override;\n    destructor Destroy;\n      override;\n    function Execute : Boolean;\n  end;\n{$ENDIF}\n\nvar\n  DirDlg: TDirDlg;\n\nimplementation\n\n{$IFNDEF UsingCLX}\n{$R *.dfm}\n{$ENDIF}\n\n{== TAbDirDlg ========================================================}\n{$IFDEF MSWINDOWS}\nfunction AbDirDlgCallbackProc(hWnd : HWND; Msg : UINT; lParam : LPARAM;\n                              Data : LPARAM): Integer; stdcall;\nvar\n  X, Y : Integer;\n  R    : TRect;\n  Buf    : array[0..MAX_PATH-1] of Char;\nbegin\n  Result := 0;\n  with TAbDirDlg(Data) do begin\n    case Msg of\n      BFFM_INITIALIZED :\n        begin\n          FHandle := hWnd;\n          if (FCaption <> '') then\n            SendMessage(hWnd, WM_SETTEXT, 0, Integer(PChar(FCaption)));\n          SendMessage(hWnd, BFFM_SETSELECTION, 1, Integer(PChar(SelectedFolder)));\n          GetWindowRect(hWnd, R);\n          X := (Screen.Width div 2) - ((R.Right - R.Left) div 2);\n          Y := (Screen.Height div 2) - ((R.Bottom - R.Top) div 2);\n          SetWindowPos(hWnd, 0, X, Y, 0, 0, SWP_NOSIZE or SWP_NOZORDER);\n        end;\n      BFFM_SELCHANGED :\n        if (FHandle <> 0) then begin\n          FIDList := PItemIDList(lParam);\n          SHGetPathFromIDList(IDList, Buf);\n          SelectedFolder := Buf;\n        end;\n    end;\n  end;\nend;\n{ -------------------------------------------------------------------------- }\nconstructor TAbDirDlg.Create(AOwner : TComponent);\nbegin\n  inherited Create(AOwner);\nend;\n{ -------------------------------------------------------------------------- }\ndestructor TAbDirDlg.Destroy;\nbegin\n  if FIDList <> nil then\n    FreeIDList;\n  inherited Destroy;\nend;\n{ -------------------------------------------------------------------------- }\nfunction TAbDirDlg.Execute : Boolean;\nvar\n  Info   : TBrowseInfo;\n  Buf    : array[0..MAX_PATH-1] of Char;\nbegin\n  if (FIDList <> nil) then\n    FreeIDList;\n\n{$IFNDEF UsingClx}\n  if (Owner is TWinControl) then\n    Info.hwndOwner := (Owner as TWinControl).Handle\n  else if Owner is TApplication then\n    Info.hwndOwner := (Owner as TApplication).Handle\n  else\n{$ENDIF}\n    Info.hwndOwner := 0;\n  Info.pidlRoot := nil;\n  Info.pszDisplayName := Buf;\n  Info.lpszTitle := PChar(FAdditionalText);\n  Info.ulFlags := BIF_RETURNONLYFSDIRS;\n  Info.lpfn := AbDirDlgCallbackProc;\n  Info.lParam := Integer(Self);\n  Info.iImage := 0;\n\n  FIDList := SHBrowseForFolder(Info);\n  FHandle := 0;\n  Result := (FIDList <> nil);\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbDirDlg.FreeIDList;\nvar\n  Malloc : IMalloc;\nbegin\n  if coGetMalloc(MEMCTX_TASK, Malloc) = NOERROR then begin\n    Malloc.Free(FIDList);\n    FIDList := nil;\n  end;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbDirDlg.SetSelectedFolder(const Value : string);\nbegin\n  FSelectedFolder := Value;\n  if FSelectedFolder <> '' then\n    if FSelectedFolder[Length(FSelectedFolder)] = '\\' then\n      Delete(FSelectedFolder, Length(FSelectedFolder), 1);\n  if (Length(FSelectedFolder) = 2) then\n    FSelectedFolder := FSelectedFolder + '\\';\nend;\n{$ENDIF}\n\n{== TDirDlg ========================================================}\n{ TDirDlg }\nprocedure TDirDlg.FormCreate(Sender: TObject);\nbegin\n  DirectoryListBox1Change(nil);\n  OKBtn.Caption := AbOKS;\n  CancelBtn.Caption := AbCancelS;\n  Caption := AbSelectDirectoryS;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TDirDlg.DirectoryListBox1Change(Sender: TObject);\nbegin\n{$IFNDEF UsingClx}\n  SelectedFolder := DirectoryListBox1.Directory;\n{$ENDIF}\n  Panel1.Caption := SelectedFolder;\nend;\n\nend.\n"
  },
  {
    "path": "lib/abbrevia/source/AbDlgPwd.pas",
    "content": "(* ***** BEGIN LICENSE BLOCK *****\n * Version: MPL 1.1\n *\n * The contents of this file are subject to the Mozilla Public License Version\n * 1.1 (the \"License\"); you may not use this file except in compliance with\n * the License. You may obtain a copy of the License at\n * http://www.mozilla.org/MPL/\n *\n * Software distributed under the License is distributed on an \"AS IS\" basis,\n * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License\n * for the specific language governing rights and limitations under the\n * License.\n *\n * The Original Code is TurboPower Abbrevia\n *\n * The Initial Developer of the Original Code is\n * TurboPower Software\n *\n * Portions created by the Initial Developer are Copyright (C) 1997-2002\n * the Initial Developer. All Rights Reserved.\n *\n * Contributor(s):\n *\n * ***** END LICENSE BLOCK ***** *)\n\n{*********************************************************}\n{* ABBREVIA: AbDlgPwd.pas                                *}\n{*********************************************************}\n{* ABBREVIA: Dialog - Password                           *}\n{*   Use AbQDgPwd.pas for CLX                            *}\n{*********************************************************}\n\n{$IFNDEF UsingCLX}\nunit AbDlgPwd;\n\n{$R *.dfm}\n{$ENDIF}\n\n{$I AbDefine.inc}\n\ninterface\n\nuses\n  SysUtils,\n{$IFDEF MSWINDOWS}\n  Windows,\n{$ENDIF}\n{$IFDEF LibcAPI}\n  Libc,\n{$ENDIF}\n{$IFDEF UsingClx}\n  QGraphics, QForms, QControls, QStdCtrls,\n  QButtons, QExtCtrls,\n{$ELSE}\n  Graphics, Forms, Controls, StdCtrls,\n  Buttons, ExtCtrls,\n{$ENDIF}\n  Classes;\n\ntype\n  TPassWordDlg = class(TForm)\n    OKBtn: TButton;\n    CancelBtn: TButton;\n    Bevel1: TBevel;\n    Edit1: TEdit;\n{$IFDEF MSWINDOWS}\n    Edit2: TEdit;\n{$ENDIF}\n    Label1: TLabel;\n{$IFDEF MSWINDOWS}\n    Label2: TLabel;\n{$ENDIF}\n    procedure Edit1Change(Sender: TObject);\n    procedure Edit2Change(Sender: TObject);\n    procedure FormActivate(Sender: TObject);\n    procedure FormCreate(Sender: TObject);\n  private\n    { Private declarations }\n  public\n    { Public declarations }\n  end;\n\nvar\n  PassWordDlg: TPassWordDlg;\n\nimplementation\n\nuses\n  AbResString;\n\nprocedure TPassWordDlg.Edit1Change(Sender: TObject);\nbegin\n{$IFDEF MSWINDOWS}\n  Edit2.Text := '';\n  OKBtn.Enabled := ( CompareStr( Edit1.Text, Edit2.Text ) = 0);\n{$ELSE}\n  OKBtn.Enabled := true;\n{$ENDIF}\nend;\n\nprocedure TPassWordDlg.Edit2Change(Sender: TObject);\nbegin\n{$IFDEF MSWINDOWS}\n  OKBtn.Enabled := ( CompareStr( Edit1.Text, Edit2.Text ) = 0);\n{$ELSE}\n  OKBtn.Enabled := true;\n{$ENDIF}\nend;\n\nprocedure TPassWordDlg.FormActivate(Sender: TObject);\nbegin\n{$IFDEF MSWINDOWS}\n  OKBtn.Enabled := ( CompareStr( Edit1.Text, Edit2.Text ) = 0);\n{$ELSE}\n  OKBtn.Enabled := true;\n{$ENDIF}\nend;\n\nprocedure TPassWordDlg.FormCreate(Sender: TObject);\nbegin\n  Caption := AbEnterPasswordS;\n  OKBtn.Caption := AbOKS;\n  CancelBtn.Caption := AbCancelS;\n  Label1.Caption := AbPasswordS;\n{$IFDEF MSWINDOWS}\n  Label2.Caption := AbVerifyS;\n{$ENDIF}\nend;\n\nend.\n"
  },
  {
    "path": "lib/abbrevia/source/AbExcept.pas",
    "content": "(* ***** BEGIN LICENSE BLOCK *****\n * Version: MPL 1.1\n *\n * The contents of this file are subject to the Mozilla Public License Version\n * 1.1 (the \"License\"); you may not use this file except in compliance with\n * the License. You may obtain a copy of the License at\n * http://www.mozilla.org/MPL/\n *\n * Software distributed under the License is distributed on an \"AS IS\" basis,\n * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License\n * for the specific language governing rights and limitations under the\n * License.\n *\n * The Original Code is TurboPower Abbrevia\n *\n * The Initial Developer of the Original Code is\n * TurboPower Software\n *\n * Portions created by the Initial Developer are Copyright (C) 1997-2002\n * the Initial Developer. All Rights Reserved.\n *\n * Contributor(s):\n *\n * ***** END LICENSE BLOCK ***** *)\n\n{*********************************************************}\n{* ABBREVIA: AbExcept.pas                                *}\n{*********************************************************}\n{* ABBREVIA: Exception classes                           *}\n{*********************************************************}\n\nunit AbExcept;\n\n{$I AbDefine.inc}\n\ninterface\n\nuses\n  SysUtils,\n  AbUtils;\n\ntype\n  EAbException = class( Exception )\n  public\n    ErrorCode : Integer;\n  end;\n\n  EAbArchiveBusy = class( EAbException )\n  public\n    constructor Create;\n  end;\n\n  EAbBadStream = class( EAbException )\n  protected\n    FInnerException : Exception;\n  public\n    constructor Create;\n    constructor CreateInner(aInnerException : Exception);\n    property InnerException : Exception read FInnerException;\n  end;\n\n  EAbDuplicateName = class( EAbException )\n  public\n    constructor Create;\n  end;\n\n  EAbFileNotFound = class( EAbException )\n  public\n    constructor Create;\n  end;\n\n  EAbNoArchive = class( EAbException )\n  public\n    constructor Create;\n  end;\n\n  EAbUserAbort = class( EAbException )\n  public\n    constructor Create;\n  end;\n\n  EAbNoSuchDirectory = class( EAbException )\n  public\n    constructor Create;\n  end;\n\n  EAbUnhandledType = class( EAbException )\n  public\n    constructor Create;\n  end;\n\n  EAbSpanningNotSupported = class (EAbException)\n  public\n    constructor Create;\n  end;\n\n  EAbInvalidSpanningThreshold = class ( EAbException )\n  public\n    constructor Create;\n  end;\n\n  EAbZipException = class( EAbException ); {Zip exception}\n  EAbCabException = class( EAbException ); {Cab exception}\n  EAbTarException = class( EAbException ); {Tar Exception}\n  EAbGzipException = class( EAbException); {GZip exception}\n\n  EAbZipBadSpanStream = class( EAbZipException )\n  public\n    constructor Create;\n  end;\n\n  EAbZipBadCRC = class( EAbZipException )\n  public\n    constructor Create;\n  end;\n\n  EAbZipInflateBlock = class( EAbZipException )\n  public\n    constructor Create;\n  end;\n\n  EAbZipInvalid = class( EAbZipException )\n  public\n    constructor Create;\n  end;\n\n  EAbInvalidIndex = class( EAbZipException )\n  public\n    constructor Create;\n  end;\n\n  EAbZipInvalidFactor = class( EAbZipException )\n  public\n    constructor Create;\n  end;\n\n  EAbZipInvalidLFH = class( EAbZipException )\n  public\n    constructor Create;\n  end;\n\n  EAbZipInvalidMethod = class( EAbZipException )\n  public\n    constructor Create;\n  end;\n\n  EAbZipInvalidPassword = class( EAbZipException )\n  public\n    constructor Create;\n  end;\n\n  EAbZipInvalidStub= class( EAbZipException )\n  public\n    constructor Create;\n  end;\n\n  EAbZipNoExtraction = class( EAbZipException )\n  public\n    constructor Create;\n  end;\n\n  EAbZipNoInsertion = class( EAbZipException )\n  public\n    constructor Create;\n  end;\n\n  EAbZipSpanOverwrite= class( EAbZipException )\n  public\n    constructor Create;\n  end;\n\n  EAbZipStreamFull = class( EAbZipException )\n  public\n    constructor Create;\n  end;\n\n  EAbZipTruncate = class( EAbZipException )\n  public\n    constructor Create;\n  end;\n\n  EAbZipUnsupported = class( EAbZipException )\n  public\n    constructor Create;\n  end;\n\n  EAbZipVersion = class( EAbZipException )\n  public\n    constructor Create;\n  end;\n\n  EAbReadError = class( EAbZipException )\n  public\n    constructor Create;\n  end;\n\n  EAbGzipBadCRC = class( EAbGZipException )\n  public\n    constructor Create;\n  end;\n\n  EAbGzipBadFileSize = class( EAbGZipException )\n  public\n    constructor Create;\n  end;\n\n  EAbGzipInvalid = class( EAbGZipException )\n  public\n    constructor Create;\n  end;\n\n  EAbTarInvalid = class( EAbTarException)\n  public\n    constructor Create;\n  end;\n\n  EAbTarBadFileName = class( EAbTarException)\n  public\n    constructor Create;\n  end;\n\n  EAbTarBadLinkName = class( EAbTarException)\n  public\n    constructor Create;\n  end;\n\n  EAbTarBadOp = class( EAbTarException)\n  public\n    constructor Create;\n  end;\n\n  EAbVMSInvalidOrigin = class( EAbZipException )\n  public\n    constructor Create( Value : Integer );\n  end;\n\n  EAbVMSErrorOpenSwap = class( EAbZipException )\n  public\n    constructor Create( const Value : string );\n  end;\n\n  EAbVMSSeekFail = class( EAbZipException )\n  public\n    constructor Create( const Value : string );\n  end;\n\n  EAbVMSReadFail = class( EAbZipException )\n  public\n    constructor Create( Count : Integer; const Value : string );\n  end;\n\n  EAbVMSWriteFail = class( EAbZipException )\n  public\n    constructor Create( Count : Integer; const Value : string );\n  end;\n\n  EAbVMSWriteTooManyBytes = class( EAbZipException )\n  public\n    constructor Create( Count : Integer );\n  end;\n\n  EAbBBSReadTooManyBytes = class( EAbZipException )\n  public\n    constructor Create(Count : Integer );\n  end;\n\n  EAbBBSSeekOutsideBuffer = class( EAbZipException )\n  public\n    constructor Create;\n  end;\n\n  EAbBBSInvalidOrigin = class( EAbZipException )\n  public\n    constructor Create;\n  end;\n\n  EAbBBSWriteTooManyBytes = class( EAbZipException )\n  public\n    constructor Create(Count : Integer );\n  end;\n\n  EAbSWSNotEndofStream = class( EAbZipException )\n  public\n    constructor Create;\n  end;\n\n  EAbSWSSeekFailed = class( EAbZipException )\n  public\n    constructor Create;\n  end;\n\n  EAbSWSWriteFailed = class( EAbZipException )\n  public\n    constructor Create;\n  end;\n\n  EAbSWSInvalidOrigin = class( EAbZipException )\n  public\n    constructor Create;\n  end;\n\n  EAbSWSInvalidNewOrigin = class( EAbZipException )\n  public\n    constructor Create;\n  end;\n\n  EAbNoCabinetDll = class( EAbCabException )\n  public\n    constructor Create;\n  end;\n\n  EAbFCIFileOpenError = class( EAbCabException )\n  public\n    constructor Create;\n  end;\n\n  EAbFCIFileReadError = class( EAbCabException )\n  public\n    constructor Create;\n  end;\n\n  EAbFCIFileWriteError = class( EAbCabException )\n  public\n    constructor Create;\n  end;\n\n  EAbFCIFileCloseError = class( EAbCabException )\n  public\n    constructor Create;\n  end;\n\n  EAbFCIFileSeekError = class( EAbCabException )\n  public\n    constructor Create;\n  end;\n\n  EAbFCIFileDeleteError = class( EAbCabException )\n  public\n    constructor Create;\n  end;\n\n  EAbFCIAddFileError = class( EAbCabException )\n  public\n    constructor Create;\n  end;\n\n  EAbFCICreateError = class( EAbCabException )\n  public\n    constructor Create;\n  end;\n\n  EAbFCIFlushCabinetError = class( EAbCabException )\n  public\n    constructor Create;\n  end;\n\n  EAbFCIFlushFolderError = class( EAbCabException )\n  public\n    constructor Create;\n  end;\n\n  EAbFDICopyError = class( EAbCabException )\n  public\n    constructor Create;\n  end;\n\n  EAbFDICreateError = class( EAbCabException )\n  public\n    constructor Create;\n  end;\n\n  EAbInvalidCabTemplate = class( EAbCabException )\n  public\n    constructor Create;\n  end;\n\n  EAbInvalidCabFile = class( EAbCabException )\n  public\n    constructor Create;\n  end;\n\n  EAbFileTooLarge = class(EAbException)\n  public\n    constructor Create;\n  end;\n\n  procedure AbConvertException( const E : Exception;\n                                var eClass : TAbErrorClass;\n                                var eErrorCode : Integer );\n\n\nimplementation\n\nuses\n  Classes,\n  AbConst,\n  AbResString;\n\nconstructor EAbArchiveBusy.Create;\nbegin\n  inherited Create(AbArchiveBusyS);\n  ErrorCode := AbArchiveBusy;\nend;\n\nconstructor EAbBadStream.Create;\nbegin\n  inherited Create(AbBadStreamTypeS);\n  FInnerException := nil;\n  ErrorCode := AbBadStreamType;\nend;\n\nconstructor EAbBadStream.CreateInner(aInnerException: Exception);\nbegin\n  inherited Create(AbBadStreamTypeS + #13#10 + aInnerException.Message);\n  FInnerException := aInnerException;\n  ErrorCode := AbBadStreamType;\nend;\n\n\nconstructor EAbDuplicateName.Create;\nbegin\n  inherited Create(AbDuplicateNameS);\n  ErrorCode := AbDuplicateName;\nend;\n\nconstructor EAbNoSuchDirectory.Create;\nbegin\n  inherited Create(AbNoSuchDirectoryS);\n  ErrorCode := AbNoSuchDirectory;\nend;\n\nconstructor EAbInvalidSpanningThreshold.Create;\nbegin\n  inherited Create(AbInvalidThresholdS);\n  ErrorCode := AbInvalidThreshold;\nend;\n\nconstructor EAbFileNotFound.Create;\nbegin\n  inherited Create(AbFileNotFoundS);\n  ErrorCode := AbFileNotFound;\nend;\n\nconstructor EAbNoArchive.Create;\nbegin\n  inherited Create(AbNoArchiveS);\n  ErrorCode := AbNoArchive;\nend;\n\nconstructor EAbUserAbort.Create;\nbegin\n  inherited Create(AbUserAbortS);\n  ErrorCode := AbUserAbort;\nend;\n\nconstructor EAbZipBadSpanStream.Create;\nbegin\n  inherited Create(AbBadSpanStreamS);\n  ErrorCode := AbBadSpanStream;\nend;\n\nconstructor EAbZipBadCRC.Create;\nbegin\n  inherited Create(AbZipBadCRCS);\n  ErrorCode := AbZipBadCRC;\nend;\n\nconstructor EAbZipInflateBlock.Create;\nbegin\n  inherited Create(AbInflateBlockErrorS);\n  ErrorCode := AbInflateBlockError;\nend;\n\nconstructor EAbZipInvalid.Create;\nbegin\n  inherited Create(AbErrZipInvalidS);\n  ErrorCode := AbErrZipInvalid;\nend;\n\nconstructor EAbInvalidIndex.Create;\nbegin\n  inherited Create(AbInvalidIndexS);\n  ErrorCode := AbInvalidIndex;\nend;\n\nconstructor EAbZipInvalidFactor.Create;\nbegin\n  inherited Create(AbInvalidFactorS);\n  ErrorCode := AbInvalidFactor;\nend;\n\nconstructor EAbZipInvalidLFH.Create;\nbegin\n  inherited Create(AbInvalidLFHS);\n  ErrorCode := AbInvalidLFH;\nend;\n\nconstructor EAbZipInvalidMethod.Create;\nbegin\n  inherited Create(AbUnknownCompressionMethodS);\n  ErrorCode := AbUnknownCompressionMethod;\nend;\n\nconstructor EAbZipInvalidPassword.Create;\nbegin\n  inherited Create(AbInvalidPasswordS);\n  ErrorCode := AbInvalidPassword;\nend;\n\nconstructor EAbZipInvalidStub.Create;\nbegin\n  inherited Create(AbZipBadStubS);\n  ErrorCode := AbZipBadStub;\nend;\n\nconstructor EAbZipNoExtraction.Create;\nbegin\n  inherited Create(AbNoExtractionMethodS);\n  ErrorCode := AbNoExtractionMethod;\nend;\n\nconstructor EAbZipNoInsertion.Create;\nbegin\n  inherited Create(AbNoInsertionMethodS);\n  ErrorCode := AbNoInsertionMethod;\nend;\n\nconstructor EAbZipSpanOverwrite.Create;\nbegin\n  inherited Create(AbNoOverwriteSpanStreamS);\n  ErrorCode := AbNoOverwriteSpanStream;\nend;\n\nconstructor EAbZipStreamFull.Create;\nbegin\n  inherited Create(AbStreamFullS);\n  ErrorCode := AbStreamFull;\nend;\n\nconstructor EAbZipTruncate.Create;\nbegin\n  inherited Create(AbTruncateErrorS);\n  ErrorCode := AbTruncateError;\nend;\n\nconstructor EAbZipUnsupported.Create;\nbegin\n  inherited Create(AbUnsupportedCompressionMethodS);\n  ErrorCode := AbUnsupportedCompressionMethod;\nend;\n\nconstructor EAbZipVersion.Create;\nbegin\n  inherited Create(AbZipVersionNeededS);\n  ErrorCode := AbZipVersionNeeded;\nend;\n\nconstructor EAbReadError.Create;\nbegin\n  inherited Create(AbReadErrorS);\n  ErrorCode := AbReadError;\nend;\n\nconstructor EAbVMSInvalidOrigin.Create( Value : Integer );\nbegin\n  inherited Create(Format(AbVMSInvalidOriginS, [Value]));\n  ErrorCode := AbVMSInvalidOrigin;\nend;\n\nconstructor EAbBBSReadTooManyBytes.Create(Count : Integer );\nbegin\n  inherited Create(Format(AbBBSReadTooManyBytesS, [Count]));\n  ErrorCode := AbBBSReadTooManyBytes;\nend;\n\nconstructor EAbBBSSeekOutsideBuffer.Create;\nbegin\n  inherited Create(AbBBSSeekOutsideBufferS);\n  ErrorCode := AbBBSSeekOutsideBuffer;\nend;\n\nconstructor EAbBBSInvalidOrigin.Create;\nbegin\n  inherited Create(AbBBSInvalidOriginS);\n  ErrorCode := AbBBSInvalidOrigin;\nend;\n\nconstructor EAbBBSWriteTooManyBytes.Create(Count : Integer);\nbegin\n  inherited Create(Format(AbBBSWriteTooManyBytesS, [Count]));\n  ErrorCode := AbBBSWriteTooManyBytes;\nend;\n\nconstructor EAbVMSErrorOpenSwap.Create( const Value : string );\nbegin\n  inherited Create(Format(AbVMSErrorOpenSwapS, [Value]));\n  ErrorCode := AbVMSErrorOpenSwap;\nend;\n\nconstructor EAbVMSSeekFail.Create( const Value : string );\nbegin\n  inherited Create(Format(AbVMSSeekFailS, [Value]));\n  ErrorCode := AbVMSSeekFail;\nend;\n\nconstructor EAbVMSReadFail.Create( Count : Integer; const Value : string );\nbegin\n  inherited Create(Format(AbVMSReadFailS, [Count, Value]));\n  ErrorCode := AbVMSReadFail;\nend;\n\nconstructor EAbVMSWriteFail.Create( Count : Integer; const Value : string );\nbegin\n  inherited Create(Format(AbVMSWriteFailS, [Count, Value]));\n  ErrorCode := AbVMSWriteFail;\nend;\n\nconstructor EAbVMSWriteTooManyBytes.Create( Count : Integer );\nbegin\n  inherited Create(Format(AbVMSWriteTooManyBytesS, [Count]));\n  ErrorCode := AbVMSWriteTooManyBytes;\nend;\n\nconstructor EAbSWSNotEndofStream.Create;\nbegin\n  inherited Create(AbSWSNotEndofStreamS);\n  ErrorCode := AbSWSNotEndofStream;\nend;\n\nconstructor EAbSWSSeekFailed.Create;\nbegin\n  inherited Create(AbSWSSeekFailedS);\n  ErrorCode := AbSWSSeekFailed;\nend;\n\nconstructor EAbSWSWriteFailed.Create;\nbegin\n  inherited Create(AbSWSWriteFailedS);\n  ErrorCode := AbSWSWriteFailed;\nend;\n\nconstructor EAbSWSInvalidOrigin.Create;\nbegin\n  inherited Create(AbSWSInvalidOriginS);\n  ErrorCode := AbSWSInvalidOrigin;\nend;\n\nconstructor EAbSWSInvalidNewOrigin.Create;\nbegin\n  inherited Create(AbSWSInvalidNewOriginS);\n  ErrorCode := AbSWSInvalidNewOrigin;\nend;\n\nconstructor EAbFCIFileOpenError.Create;\nbegin\n  inherited Create(AbFCIFileOpenErrorS);\n  ErrorCode := AbFCIFileOpenError;\nend;\n\nconstructor EAbNoCabinetDll.Create;\nbegin\n  inherited Create(AbNoCabinetDllErrorS);\n  ErrorCode := AbNoCabinetDllError;\nend;\n\nconstructor EAbFCIFileReadError.Create;\nbegin\n  inherited Create(AbFCIFileReadErrorS);\n  ErrorCode := AbFCIFileReadError;\nend;\n\nconstructor EAbFCIFileWriteError.Create;\nbegin\n  inherited Create(AbFCIFileWriteErrorS);\n  ErrorCode := AbFCIFileWriteError;\nend;\n\nconstructor EAbFCIFileCloseError.Create;\nbegin\n  inherited Create(AbFCIFileCloseErrorS);\n  ErrorCode := AbFCIFileCloseError;\nend;\n\nconstructor EAbFCIFileSeekError.Create;\nbegin\n  inherited Create(AbFCIFileSeekErrorS);\n  ErrorCode := AbFCIFileSeekError;\nend;\n\nconstructor EAbFCIFileDeleteError.Create;\nbegin\n  inherited Create(AbFCIFileDeleteErrorS);\n  ErrorCode := AbFCIFileDeleteError;\nend;\n\nconstructor EAbFCIAddFileError.Create;\nbegin\n  inherited Create(AbFCIAddFileErrorS);\n  ErrorCode := AbFCIAddFileError;\nend;\n\nconstructor EAbFCICreateError.Create;\nbegin\n  inherited Create(AbFCICreateErrorS);\n  ErrorCode := AbFCICreateError;\nend;\n\nconstructor EAbFCIFlushCabinetError.Create;\nbegin\n  inherited Create(AbFCIFlushCabinetErrorS);\n  ErrorCode := AbFCIFlushCabinetError;\nend;\n\nconstructor EAbFCIFlushFolderError.Create;\nbegin\n  inherited Create(AbFCIFlushFolderErrorS);\n  ErrorCode := AbFCIFlushFolderError;\nend;\n\nconstructor EAbFDICopyError.Create;\nbegin\n  inherited Create(AbFDICopyErrorS);\n  ErrorCode := AbFDICopyError;\nend;\n\nconstructor EAbFDICreateError.Create;\nbegin\n  inherited Create(AbFDICreateErrorS);\n  ErrorCode := AbFDICreateError;\nend;\n\nconstructor EAbInvalidCabTemplate.Create;\nbegin\n  inherited Create(AbInvalidCabTemplateS);\n  ErrorCode := AbInvalidCabTemplate;\nend;\n\nconstructor EAbInvalidCabFile.Create;\nbegin\n  inherited Create(AbInvalidCabFileS);\n  ErrorCode := AbInvalidCabFile;\nend;\n\nprocedure AbConvertException( const E : Exception;\n                              var eClass : TAbErrorClass;\n                              var eErrorCode : Integer );\nbegin\n  eClass := ecOther;\n  eErrorCode := 0;\n  if E is EAbException then begin\n    eClass := ecAbbrevia;\n    eErrorCode := (E as EAbException).ErrorCode;\n  end\n  else if E is EInOutError then begin\n    eClass := ecInOutError;\n    eErrorCode := (E as EInOutError).ErrorCode;\n  end\n  else if E is EFilerError then\n    eClass := ecFilerError\n  else if E is EFOpenError then\n    eClass := ecFileOpenError\n  else if E is EFCreateError then\n    eClass := ecFileCreateError;\nend;\n\n{ EAbUnhandledType }\n\nconstructor EAbUnhandledType.Create;\nbegin\n  inherited Create(AbUnhandledFileTypeS);\n  ErrorCode := AbUnhandledFileType;\nend;\n\n{ EAbGzipBadCRC }\n\nconstructor EAbGzipBadCRC.Create;\nbegin\n  inherited Create(AbGzipBadCRCS);\n  ErrorCode := AbGzipBadCRC;\nend;\n\n{ EAbGzipBadFileSize }\n\nconstructor EAbGzipBadFileSize.Create;\nbegin\n  inherited Create(AbGzipBadFileSizeS);\n  ErrorCode := AbGzipBadFileSize;\nend;\n\n{ EAbGzipInvalid }\n\nconstructor EAbGzipInvalid.Create;\nbegin\n  inherited Create(AbSpanningNotSupportedS);\n  ErrorCode := AbSpanningNotSupported;\n\nend;\n\n{ EAbTarInvalid }\n\nconstructor EAbTarInvalid.Create;\nbegin\n  inherited Create(AbTarInvalidS);\n  ErrorCode := AbTarInvalid;\nend;\n\n{ EAbTarBadFileName }\n\nconstructor EAbTarBadFileName.Create;\nbegin\n  inherited Create(AbTarBadFileNameS);\n  ErrorCode := AbTarBadFileName;\nend;\n\n{ EAbTarBadLinkName }\n\nconstructor EAbTarBadLinkName.Create;\nbegin\n  inherited Create(AbTarBadLinkNameS);\n  ErrorCode := AbTarBadLinkName;\nend;\n\n{ EAbTarBadOp }\n\nconstructor EAbTarBadOp.Create;\nbegin\n  inherited Create(AbTarBadOpS);\n  ErrorCode := AbTarBadOp;\nend;\n\n{ EAbSpanningNotSupported }\n\nconstructor EAbSpanningNotSupported.Create;\nbegin\n  inherited Create(AbSpanningNotSupportedS);\n  ErrorCode := AbSpanningNotSupported;\nend;\n\n{ EAbFileTooLarge }\n\nconstructor EAbFileTooLarge.Create;\nbegin\n  {TODO Create const and fix wording}\n  inherited Create(AbFileSizeTooBigS);\nend;\n\nend.\n"
  },
  {
    "path": "lib/abbrevia/source/AbFciFdi.pas",
    "content": "(* ***** BEGIN LICENSE BLOCK *****\n * Version: MPL 1.1\n *\n * The contents of this file are subject to the Mozilla Public License Version\n * 1.1 (the \"License\"); you may not use this file except in compliance with\n * the License. You may obtain a copy of the License at\n * http://www.mozilla.org/MPL/\n *\n * Software distributed under the License is distributed on an \"AS IS\" basis,\n * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License\n * for the specific language governing rights and limitations under the\n * License.\n *\n * The Original Code is TurboPower Abbrevia\n *\n * The Initial Developer of the Original Code is\n * TurboPower Software\n *\n * Portions created by the Initial Developer are Copyright (C) 1997-2002\n * the Initial Developer. All Rights Reserved.\n *\n * Contributor(s):\n *\n * ***** END LICENSE BLOCK ***** *)\n\n{*********************************************************}\n{* ABBREVIA: AbFciFdi.pas                                *}\n{*********************************************************}\n{* ABBREVIA: Cabinet DLL wrapper                         *}\n{* Based on info from the FCI/FDI Library Description,   *}\n{* included in the Microsoft Cabinet SDK                 *}\n{*********************************************************}\n\nunit AbFciFdi;\n\n{$I AbDefine.inc}\n\ninterface\n\nuses\n  Windows, AbUtils;\n\nconst\n  CabinetDLL  = 'cabinet.dll';\n  cpuUnknown  = -1;\n  cpu80286    = 0;\n  cpu80386    = 1;\n  cpuDefault  = cpuUnknown;\n\n\ntype\n  {FDI errors}\n  FDIError =\n    (FDIError_None,            FDIError_Cabinet_Not_Found,\n     FDIError_Not_A_Cabinet,   FDIError_Unknown_Cabinet_Version,\n     FDIError_Corrupt_Cabinet, FDIError_Alloc_Fail,\n     FDIError_Bad_Compr_Type,  FDIError_MDI_Fail,\n     FDIError_Target_File,     FDIError_Reserve_Mismatch,\n     FDIError_Wrong_Cabinet,   FDIError_User_Abort);\n\n  {FCI errors}\n  FCIError =\n    (FCIError_NONE,      FCIError_Open_SRC,\n     FCIError_Read_SRC,  FCIError_Alloc_Fail,\n     FCIError_Temp_File, FCIError_Bad_Compr_Type,\n     FCIError_Cab_File,  FCIError_User_Abort,\n     FCIERRor_MCI_Fail);\n\n  {FDI notifications}\n  FDINotificationType =\n    (FDINT_Cabinet_Info, FDINT_Partial_File,\n     FDINT_Copy_File,    FDINT_Close_File_Info,\n     FDINT_Next_Cabinet, FDINT_Enumerate);\n\n  {FDI/FCI error structure}\n  PCabErrorRecord = ^CabErrorRecord;\n  CabErrorRecord  = record\n    ErrorCode     : Integer;\n    ErrorType     : Integer;\n    ErrorPresent  : BOOL;\n  end;\n\n  {FDI cabinet information structure}\n  PFDICabInfo = ^FDICabInfo;\n  FDICabInfo  = record\n    cbCabinet : Longint;\n    cFolders  : Word;\n    cFiles    : Word;\n    setID     : Word;\n    iCabinet  : Word;\n    fReserve  : BOOL;\n    hasprev   : BOOL;\n    hasnext   : BOOL;\n  end;\n\n  {FCI cabinet information structure}\n  PFCICabInfo = ^FCICabInfo;\n  FCICabInfo  = record\n    cb                    : Longint;\n    cbFolderThresh        : Longint;\n    cbReserveCFHeader     : Integer;\n    cbReserveCFFolder     : Integer;\n    cbReserveCFData       : Integer;\n    iCab                  : Integer;\n    iDisk                 : Integer;\n    fFailOnIncompressible : Integer;\n    setID                 : Word;\n    szDisk                : array[0..255] of AnsiChar;\n    szCab                 : array[0..255] of AnsiChar;\n    szCabPath             : array[0..255] of AnsiChar;\n  end;\n\n  {FDI notification structure}\n  PFDINotification = ^FDINotification;\n  FDINotification  = record\n    cb       : Longint;\n    psz1     : PAnsiChar;\n    psz2     : PAnsiChar;\n    psz3     : PAnsiChar;\n    pv       : Pointer;\n    hf       : PtrInt;\n    date     : Word;\n    time     : Word;\n    attribs  : Word;\n    setID    : Word;\n    iCabinet : Word;\n    iFolder  : Word;\n    fdie     : FDIERROR;\n  end;\n\n  {misc defines}\n  HFDI    = Pointer;\n  HFCI    = Pointer;\n  FARPROC = Pointer;\n\n\n{== Cabinet DLL routine prototypes ==========================================}\ntype\n  TFDICreate =\n    function (pfnalloc, pfnfree, pfnopen, pfnread, pfnwrite, pfnclose,\n      pfnseek : FARPROC; cpuType  : Integer; pError : PCabErrorRecord) : HFDI;\n      cdecl;\n{----------------------------------------------------------------------------}\n  TFDIIsCabinet =\n    function(hfdi : HFDI; hf : PtrInt; pfdici : PFDICabInfo) : BOOL;\n      cdecl;\n{----------------------------------------------------------------------------}\n  TFDICopy =\n    function(hfdi : HFDI; pszCabinet, pszCabPath : PAnsiChar;\n      flags : Integer; pfnfdin, pfnfdid : FARPROC; Archive : Pointer) : BOOL;\n      cdecl;\n{----------------------------------------------------------------------------}\n  TFDIDestroy =\n    function(hfdi : HFDI) : BOOL;\n      cdecl;\n{----------------------------------------------------------------------------}\n  TFCICreate =\n    function(pError : PCabErrorRecord; pfnfcifp, pfnalloc, pfnfree,\n      pfnopen, pfnread, pfnwrite, pfnclose, pfnseek, pfndelete,\n      pfnfcigtf : FARPROC; pccab : PFCICabInfo; Archive : Pointer) : HFCI;\n      cdecl;\n{----------------------------------------------------------------------------}\n  TFCIAddFile =\n    function(hfci : HFCI; pszFilePath, pszFileName : PAnsiChar;\n\t  fExecute : BOOL; pfnfcignc, pfnfcis, pfnfcigoi : FARPROC;\n      typeCompress : Word) : BOOL;\n      cdecl;\n{----------------------------------------------------------------------------}\n  TFCIFlushCabinet =\n\tfunction(hfci : HFCI; fGetNextCab : BOOL;\n      pfnfcignc, pfnfcis : FARPROC) : BOOL;\n      cdecl;\n{----------------------------------------------------------------------------}\n  TFCIFlushFolder =\n\tfunction(hfci : HFCI; pfnfcignc, pfnfcis : FARPROC) : BOOL;\n      cdecl;\n{----------------------------------------------------------------------------}\n  TFCIDestroy =\n    function(hfci : HFCI) : BOOL;\n      cdecl;\n\n\n{== DLL routine wrappers ====================================================}\nfunction FDICreate(pfnalloc, pfnfree, pfnopen, pfnread,\n  pfnwrite, pfnclose, pfnseek : FARPROC;\n  cpuType  : Integer; pError : PCabErrorRecord) : HFDI;\n  {returns an FDI context for opening an existing cabinet}\n  {  pfnalloc - heap allocation callback function }\n  {  pfnfree  -  heap deallocation callback function }\n  {  pfnopen  -  open file callback function }\n  {  pfnwrite - write file callback function }\n  {  pfnclose - close file callback function }\n  {  pfnseek  - reposition file pointer callback function }\n  {  cpuType  -  -1: unknown, 0: 80286, 1: 80386 }\n  {  pError   -  pointer to error record }\n{----------------------------------------------------------------------------}\nfunction FDIIsCabinet(hfdi : HFDI; hf : PtrInt;\n  pfdici : PFDICabInfo) : BOOL;\n  {checks cabinet file for validity}\n  {  hfdi   - FDI context }\n  {  hf     - cabinet file handle }\n  {  pfdici - pointer to FDI cabinet info structure }\n{----------------------------------------------------------------------------}\nfunction FDICopy(hfdi : HFDI; pszCabinet, pszCabPath : PAnsiChar;\n  flags : Integer; pfnfdin, pfnfdid : FARPROC;\n  Archive : Pointer) : BOOL;\n  {enumerates every file in the cabinet.  The callback function }\n  {should indicate whether or not to extract a given file}\n  {  hfdi       - FDI context }\n  {  pszCabinet - cabinet file name }\n  {  pszCabPath - cabinet file path }\n  {  flags      - currently not used }\n  {  pfnfdin    - FDI notifaction callback function }\n  {  pfnfdid    - decryption callback (currently not used)}\n  {  Archive    - the calling TAbCabArchive instance }\n{----------------------------------------------------------------------------}\nfunction FDIDestroy(hfdi : HFDI) : BOOL;\n  {releases FDI context and frees resources}\n  {  hfdi - FDI context }\n{----------------------------------------------------------------------------}\nfunction FCICreate(pError : PCabErrorRecord;\n  pfnfcifp, pfnalloc, pfnfree, pfnopen, pfnread, pfnwrite, pfnclose,\n  pfnseek, pfndelete, pfnfcigtf : FARPROC;\n  pccab : PFCICabInfo; Archive : Pointer) : HFCI;\n  {creates a new cabinet file and returns the FCI context}\n  {  pError    - pointer to error record }\n  {  pfnfcifp  - callback notification when file has been placed in cabinet }\n  {  pfnalloc  - callback function to allocate memory }\n  {  pfnfree   - callback function to free memory }\n  {  pfnopen   - callback function to open a file }\n  {  pfnwrite  - callback function to write to a file }\n  {  pfnclose  - callback function to close a file }\n  {  pfnseek   - callback function to reposition file pointer }\n  {  pfndelete - callback function to delete a file }\n  {  pfnfcigtf - callback function to obtain temp filename }\n  {  pccab     - pointer to FCI cabinet infor structure }\n  {  Archive   - the calling TAbCabArchive instance }\n{----------------------------------------------------------------------------}\nfunction FCIAddFile(hfci : HFCI; pszFilePath, pszFileName : PAnsiChar;\n  fExecute : BOOL; pfnfcignc, pfnfcis, pfnfcigoi : FARPROC;\n  typeCompress : Word) : BOOL;\n  {adds a file to the cabinet}\n  {  hfci         - FCI context }\n  {  pszFilePath  - full pathname of file being added }\n  {  pszFileName  - just the file name }\n  {  fExecute     - flag to indicate if file is executable }\n  {  pfnfcignc    - callback function to obtain next cabinet info }\n  {  pfnfcis      - callback function to relay progress }\n  {  pfnfcigoi    - callback function to open file and get attributes }\n  {  typeCompress - compression type to use }\n{----------------------------------------------------------------------------}\nfunction FCIFlushCabinet(hfci : HFCI; fGetNextCab : BOOL;\n  pfnfcignc, pfnfcis : FARPROC) : BOOL;\n  {writes current cabinet file out to disk and optionally starts a new one}\n  {  hfci        - FCI context }\n  {  fGetNextCab - flag indicating whether to start a new cabinet }\n  {  pfnfcignc   - callback function to obtain next cabinet info }\n  {  pfnfcis     - callback function to relay progress }\n{----------------------------------------------------------------------------}\nfunction FCIFlushFolder(hfci : HFCI;\n  pfnfcignc, pfnfcis : FARPROC) : BOOL;\n  {close current compression block and start a new one}\n  {  hfci      - FCI context }\n  {  pfnfcignc - callback function to obtain next cabinet info }\n  {  pfnfcis   - callback function to relay progress }\n{----------------------------------------------------------------------------}\nfunction FCIDestroy(hfci : HFCI) : BOOL;\n  {releases FCI context and frees resources}\n  {  hfdi - FDI context }\n{----------------------------------------------------------------------------}\n\n\nimplementation\n\nuses\n  AbExcept;\n\n\nvar\n  CabDLLLoaded        : Boolean;\n  CabDLLHandle        : THandle;\n  FDICreateProc       : TFDICreate;\n  FDIIsCabinetProc    : TFDIIsCabinet;\n  FDICopyProc         : TFDICopy;\n  FDIDestroyProc      : TFDIDestroy;\n  FCICreateProc       : TFCICreate;\n  FCIAddFileProc      : TFCIAddFile;\n  FCIFlushCabinetProc : TFCIFlushCabinet;\n  FCIFlushFolderProc  : TFCIFlushFolder;\n  FCIDestroyProc      : TFCIDestroy;\n\n\n{============================================================================}\nprocedure LoadCabinetDLL;\nbegin\n  if CabDllLoaded then\n    Exit;\n  CabDllHandle := LoadLibrary(CabinetDLL);\n  if (CabDllHandle = 0) then\n    raise EAbNoCabinetDLL.Create;\n  @FDICreateProc := GetProcAddress(CabDllHandle, 'FDICreate');\n  @FDIIsCabinetProc := GetProcAddress(CabDllHandle, 'FDIIsCabinet');\n  @FDICopyProc := GetProcAddress(CabDllHandle, 'FDICopy');\n  @FDIDestroyProc := GetProcAddress(CabDllHandle, 'FDIDestroy');\n  @FCICreateProc := GetProcAddress(CabDllHandle, 'FCICreate');\n  @FCIAddFileProc := GetProcAddress(CabDllHandle, 'FCIAddFile');\n  @FCIFlushCabinetProc := GetProcAddress(CabDllHandle, 'FCIFlushCabinet');\n  @FCIFlushFolderProc := GetProcAddress(CabDllHandle, 'FCIFlushFolder');\n  @FCIDestroyProc := GetProcAddress(CabDllHandle, 'FCIDestroy');\n  CabDllLoaded := True;\nend;\n{----------------------------------------------------------------------------}\nfunction FDICreate(pfnalloc, pfnfree, pfnopen, pfnread,\n  pfnwrite, pfnclose, pfnseek : FARPROC;\n  cpuType  : Integer; pError : PCabErrorRecord) : HFDI;\nbegin\n  LoadCabinetDLL;\n  if Assigned(FDICreateProc) then\n    Result := FDICreateProc(pfnalloc, pfnfree, pfnopen, pfnread,\n      pfnwrite, pfnclose, pfnseek, cpuType, pError)\n  else\n    Result := nil;\nend;\n{----------------------------------------------------------------------------}\nfunction FDIIsCabinet(hfdi : HFDI; hf : PtrInt;\n  pfdici : PFDICabInfo) : BOOL;\nbegin\n  LoadCabinetDLL;\n  if Assigned(FDIIsCabinetProc) then\n    Result := FDIIsCabinetProc(hfdi, hf, pfdici)\n  else\n    Result := False;\nend;\n{----------------------------------------------------------------------------}\nfunction FDICopy(hfdi : HFDI; pszCabinet, pszCabPath : PAnsiChar;\n  flags : Integer; pfnfdin, pfnfdid : FARPROC;\n  Archive : Pointer) : BOOL;\nbegin\n  LoadCabinetDLL;\n  if Assigned(FDICopyProc) then\n    Result := FDICopyProc(hfdi, pszCabinet, pszCabPath, flags,\n      pfnfdin, pfnfdid, Archive)\n  else\n    Result := False;\nend;\n{----------------------------------------------------------------------------}\nfunction FDIDestroy(hfdi : HFDI) : BOOL;\nbegin\n  LoadCabinetDLL;\n  if Assigned(FDIDestroyProc) then\n    Result := FDIDestroyProc(hfdi)\n  else\n    Result := False;\nend;\n{----------------------------------------------------------------------------}\nfunction FCICreate(pError : PCabErrorRecord;\n  pfnfcifp, pfnalloc, pfnfree, pfnopen, pfnread, pfnwrite, pfnclose,\n  pfnseek, pfndelete, pfnfcigtf : FARPROC;\n  pccab : PFCICabInfo; Archive : Pointer) : HFCI;\nbegin\n  LoadCabinetDLL;\n  if Assigned(FCICreateProc) then\n    Result := FCICreateProc(pError, pfnfcifp, pfnalloc, pfnfree, pfnopen,\n      pfnread, pfnwrite, pfnclose, pfnseek, pfndelete, pfnfcigtf,\n      pccab, Archive)\n  else\n    Result := nil;\nend;\n{----------------------------------------------------------------------------}\nfunction FCIAddFile(hfci : HFCI; pszFilePath, pszFileName : PAnsiChar;\n  fExecute : BOOL; pfnfcignc, pfnfcis, pfnfcigoi : FARPROC;\n  typeCompress : Word) : BOOL;\nbegin\n  LoadCabinetDLL;\n  if Assigned(FCIAddFileProc) then\n    Result := FCIAddFileProc(hfci, pszFilePath, pszFileName,\n      fExecute, pfnfcignc, pfnfcis, pfnfcigoi, typeCompress)\n  else\n    Result := False;\nend;\n{----------------------------------------------------------------------------}\nfunction FCIFlushCabinet(hfci : HFCI; fGetNextCab : BOOL;\n  pfnfcignc, pfnfcis : FARPROC) : BOOL;\nbegin\n  LoadCabinetDLL;\n  if Assigned(FCIFlushCabinetProc) then\n    Result := FCIFlushCabinetProc(hfci, fGetNextCab, pfnfcignc, pfnfcis)\n  else\n    Result := False;\nend;\n{----------------------------------------------------------------------------}\nfunction FCIFlushFolder(hfci : HFCI;\n  pfnfcignc, pfnfcis : FARPROC) : BOOL;\nbegin\n  LoadCabinetDLL;\n  if Assigned(FCIFlushFolderProc) then\n    Result := FCIFlushFolderProc(hfci, pfnfcignc, pfnfcis)\n  else\n    Result := False;\nend;\n{----------------------------------------------------------------------------}\nfunction FCIDestroy(hfci : HFCI) : BOOL;\nbegin\n  LoadCabinetDLL;\n  if Assigned(FCIDestroyProc) then\n    Result := FCIDestroyProc(hfci)\n  else\n    Result := False;\nend;\n{----------------------------------------------------------------------------}\ninitialization\n  CabDllLoaded := False;\n\nend.\n"
  },
  {
    "path": "lib/abbrevia/source/AbGzTyp.pas",
    "content": "(* ***** BEGIN LICENSE BLOCK *****\n * Version: MPL 1.1\n *\n * The contents of this file are subject to the Mozilla Public License Version\n * 1.1 (the \"License\"); you may not use this file except in compliance with\n * the License. You may obtain a copy of the License at\n * http://www.mozilla.org/MPL/\n *\n * Software distributed under the License is distributed on an \"AS IS\" basis,\n * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License\n * for the specific language governing rights and limitations under the\n * License.\n *\n * The Original Code is TurboPower Abbrevia\n *\n * The Initial Developer of the Original Code is\n * TurboPower Software\n *\n * Portions created by the Initial Developer are Copyright (C) 1997-2002\n * the Initial Developer. All Rights Reserved.\n *\n * Contributor(s):\n * Craig Peterson <capeterson@users.sourceforge.net>\n *\n * ***** END LICENSE BLOCK ***** *)\n\n{*********************************************************}\n{* ABBREVIA: AbGzTyp.pas                                 *}\n{*********************************************************}\n{* ABBREVIA: TAbGzipArchive, TAbGzipItem classes         *}\n{*********************************************************}\n{* Misc. constants, types, and routines for working      *}\n{* with GZip files                                       *}\n{* See: RFC 1952                                         *}\n{* \"GZIP file format specification version 4.3\"          *}\n{* for more information on GZip                          *}\n{* See \"algorithm.doc\" in Gzip source and \"format.txt\"   *}\n{* on gzip.org for differences from RFC                  *}\n{*********************************************************}\n\nunit AbGzTyp;\n\n{$I AbDefine.inc}\n\ninterface\n\nuses\n  Classes, AbUtils, AbArcTyp, AbTarTyp, AbVMStrm;\n\ntype\n  { pre-defined \"operating system\" (really more FILE system)\n    types for the Gzip header }\n  TAbGzFileSystem =\n    (osFat, osAmiga, osVMS, osUnix, osVM_CMS, osAtariTOS,\n    osHPFS, osMacintosh, osZSystem, osCP_M, osTOPS20,\n    osNTFS, osQDOS, osAcornRISCOS, osVFAT, osMVS, osBeOS,\n    osTandem, osTHEOS, osUnknown, osUndefined);\n\ntype\n  PAbGzHeader = ^TAbGzHeader;\n  TAbGzHeader = packed record  { SizeOf(TGzHeader) = 10}\n    ID1        : Byte;  { ID Byte, should always be $1F}\n    ID2        : Byte;  { ID Byte, should always be $8B}\n    CompMethod : Byte;  { compression method used}\n    { 0..7 reserved, 8 = deflate, others undefined as of this writing (4/27/2001)}\n    Flags      : Byte; { misc flags}\n      { Bit 0: FTEXT    compressed file contains text, can be used for}\n                      { cross platform line termination translation}\n      { Bit 1: FCONTINUATION file is a continuation of a multi-part gzip file}\n                      { RFC 1952 says this is the header CRC16 flag, but gzip}\n                      { reserves it and won't extract the file if this is set}\n                      { header data includes part number after header record}\n      { Bit 2: FEXTRA   header data contains Extra Data, starts after part}\n                      { number (if any)}\n      { Bit 3: FNAME    header data contains FileName, null terminated}\n                      { string starting immediately after Extra Data (if any)}\n                      { RFC 1952 says this is ISO 8859-1 encoded, but gzip}\n                      { always uses the system encoding}\n      { Bit 4: FCOMMENT header data contains Comment, null terminated string}\n                      { starting immediately after FileName (if any)}\n      { Bit 5: FENCRYPTED file is encrypted using zip-1.9 encryption }\n                      { header data contains a 12-byte encryption header }\n                      { starting immediately after Comment.  Documented in}\n                      { \"algorithm.doc\", but unsupported in gzip}\n      { Bits 6..7 are undefined and reserved as of this writing (8/25/2009)}\n    ModTime    : LongInt; { File Modification (Creation) time,}\n                          { UNIX cdate format}\n    XtraFlags  : Byte;   { additional flags}\n      { XtraFlags = 2  -- Deflate compressor used maximum compression algorithm}\n      { XtraFlags = 4  -- Deflate compressor used fastest algorithm}\n    OS         : Byte; { Operating system that created file,}\n                       { see GZOsToStr routine for values}\n  end;\n\n  TAbGzTailRec = packed record\n    CRC32 : LongInt;  { crc for uncompressed data }\n    ISize : LongWord;  { size of uncompressed data }\n  end;\n\n  TAbGzExtraFieldSubID = array[0..1] of AnsiChar;\n\ntype\n  TAbGzipExtraField = class(TAbExtraField)\n  private\n    FGZHeader : PAbGzHeader;\n    function GetID(aIndex : Integer): TAbGzExtraFieldSubID;\n  protected\n    procedure Changed; override;\n  public\n    constructor Create(aGZHeader : PAbGzHeader);\n    procedure Delete(aID : TAbGzExtraFieldSubID);\n    function Get(aID : TAbGzExtraFieldSubID;\n      out aData : Pointer; out aDataSize : Word) : Boolean;\n    procedure Put(aID : TAbGzExtraFieldSubID; const aData; aDataSize : Word);\n  public\n    property IDs[aIndex : Integer]: TAbGzExtraFieldSubID\n      read GetID;\n  end;\n\n  TAbGzipItem = class(TAbArchiveItem)\n  protected {private}\n    FGZHeader : TAbGzHeader;\n    FExtraField : TAbGzipExtraField;\n    FFileComment : AnsiString;\n    FRawFileName : AnsiString;\n\n  protected\n    function GetFileSystem: TAbGzFileSystem;\n    function GetHasExtraField: Boolean;\n    function GetHasFileComment: Boolean;\n    function GetHasFileName: Boolean;\n    function GetIsText: Boolean;\n\n    procedure SetFileComment(const Value : AnsiString);\n    procedure SetFileSystem(const Value: TAbGzFileSystem);\n    procedure SetIsText(const Value: Boolean);\n\n    function GetExternalFileAttributes : LongWord; override;\n    function GetIsEncrypted : Boolean; override;\n    function GetLastModFileDate : Word; override;\n    function GetLastModFileTime : Word; override;\n    function GetLastModTimeAsDateTime: TDateTime; override;\n\n    procedure SetExternalFileAttributes( Value : LongWord ); override;\n    procedure SetFileName(const Value : string); override;\n    procedure SetIsEncrypted(Value : Boolean); override;\n    procedure SetLastModFileDate(const Value : Word); override;\n    procedure SetLastModFileTime(const Value : Word); override;\n    procedure SetLastModTimeAsDateTime(const Value: TDateTime); override;\n\n    procedure SaveGzHeaderToStream(AStream : TStream);\n    procedure LoadGzHeaderFromStream(AStream : TStream);\n  public\n    property CompressionMethod : Byte\n      read FGZHeader.CompMethod;\n\n    property ExtraFlags : Byte {Default: 2}\n      read FGZHeader.XtraFlags write FGZHeader.XtraFlags;\n\n    property Flags : Byte\n      read FGZHeader.Flags;\n\n    property FileComment : AnsiString\n      read FFileComment write SetFileComment;\n\n    property FileSystem : TAbGzFileSystem {Default: osFat (Windows); osUnix (Linux)}\n      read GetFileSystem write SetFileSystem;\n\n    property ExtraField : TAbGzipExtraField\n      read FExtraField;\n\n    property IsEncrypted : Boolean\n      read GetIsEncrypted;\n\n    property HasExtraField : Boolean\n      read GetHasExtraField;\n\n    property HasFileName : Boolean\n      read GetHasFileName;\n\n    property HasFileComment : Boolean\n      read GetHasFileComment;\n\n    property IsText : Boolean\n      read GetIsText write SetIsText;\n\n    property GZHeader : TAbGzHeader\n      read FGZHeader;\n\n    constructor Create;\n    destructor Destroy; override;\n  end;\n\n  TAbGzipStreamHelper = class(TAbArchiveStreamHelper)\n  private\n    function GetGzCRC: LongInt;\n    function GetFileSize: LongInt;\n  protected {private}\n    FItem : TAbGzipItem;\n    FTail : TAbGzTailRec;\n  public\n    constructor Create(AStream : TStream);\n    destructor Destroy; override;\n\n    procedure ExtractItemData(AStream : TStream); override;\n    function FindFirstItem : Boolean; override;\n    function FindNextItem : Boolean; override;\n    function SeekItem(Index : Integer): Boolean; override;\n    procedure SeekToItemData;\n    procedure WriteArchiveHeader; override;\n    procedure WriteArchiveItem(AStream : TStream); override;\n    procedure WriteArchiveTail; override;\n    function GetItemCount : Integer; override;\n    procedure ReadHeader; override;\n    procedure ReadTail; override;\n\n    property CRC : LongInt\n      read GetGzCRC;\n    property FileSize : LongInt\n      read GetFileSize;\n    property TailCRC : LongInt\n      read FTail.CRC32;\n    property TailSize : LongWord\n      read FTail.ISize;\n  end;\n\n  TAbGzipArchiveState = (gsGzip, gsTar);\n\n  TAbGzipArchive = class(TAbTarArchive)\n  private\n    FGZStream  : TStream;        { stream for GZip file}\n    FGZItem    : TAbArchiveList; { item in Gzip (only one, but need polymorphism of class)}\n    FTarStream : TAbVirtualMemoryStream; { stream for possible contained Tar }\n    FTarList   : TAbArchiveList; { items in possible contained Tar }\n    FTarAutoHandle: Boolean;\n    FState     : TAbGzipArchiveState;\n    FIsGzippedTar : Boolean;\n\n    procedure SetTarAutoHandle(const Value: Boolean);\n    function GetIsGzippedTar: Boolean;\n    procedure SwapToGzip;\n    procedure SwapToTar;\n\n  protected\n    function CreateItem(const FileSpec : string): TAbArchiveItem;\n      override;\n    procedure ExtractItemAt(Index : Integer; const UseName : string);\n      override;\n    procedure ExtractItemToStreamAt(Index : Integer; aStream : TStream);\n      override;\n    procedure LoadArchive;\n      override;\n    procedure SaveArchive;\n      override;\n    procedure TestItemAt(Index : Integer);\n      override;\n    function FixName(const Value : string) : string;\n      override;\n    function GetSupportsEmptyFolders : Boolean;\n      override;\n\n    function GetItem(Index: Integer): TAbGzipItem;\n    procedure PutItem(Index: Integer; const Value: TAbGzipItem);\n  public {methods}\n    constructor CreateFromStream(aStream : TStream; const aArchiveName : string);\n      override;\n    destructor  Destroy;\n      override;\n\n    procedure DoSpanningMediaRequest(Sender : TObject; ImageNumber : Integer;\n      var ImageName : string; var Abort : Boolean); override;\n\n    property TarAutoHandle : Boolean\n      read FTarAutoHandle write SetTarAutoHandle;\n\n    property IsGzippedTar : Boolean\n      read GetIsGzippedTar write FIsGzippedTar;\n\n    property Items[Index : Integer] : TAbGzipItem\n      read GetItem\n      write PutItem; default;\n  end;\n\nfunction VerifyGZip(Strm : TStream) : TAbArchiveType;\nfunction GZOsToStr(OS: Byte) : string;\n\nimplementation\n\nuses\n  {$IFDEF MSWINDOWS}\n  Windows,\n  {$ENDIF}\n{$IFDEF HasAnsiStrings}\n  System.AnsiStrings,\n{$ENDIF}\n  SysUtils, AbBitBkt, AbCharset, AbDfBase, AbDfDec, AbDfEnc, AbExcept, AbResString;\n\nconst\n  { Header Signature Values}\n  AB_GZ_HDR_ID1 = $1F;\n  AB_GZ_HDR_ID2 = $8B;\n\n  { Test bits for TGzHeader.Flags field }\n  AB_GZ_FLAG_FTEXT         = $01;\n  AB_GZ_FLAG_FCONTINUATION = $02;\n  AB_GZ_FLAG_FEXTRA        = $04;\n  AB_GZ_FLAG_FNAME         = $08;\n  AB_GZ_FLAG_FCOMMENT      = $10;\n  AB_GZ_FLAG_FENCRYPTED    = $20;\n  AB_GZ_UNSUPPORTED_FLAGS  = $E2;\n\n  { GZip OS source flags }\n  AB_GZ_OS_ID_FAT         = 0;\n  AB_GZ_OS_ID_Amiga       = 1;\n  AB_GZ_OS_ID_VMS         = 2;\n  AB_GZ_OS_ID_Unix        = 3;\n  AB_GZ_OS_ID_VM_CMS      = 4;\n  AB_GZ_OS_ID_AtariTOS    = 5;\n  AB_GZ_OS_ID_HPFS        = 6;\n  AB_GZ_OS_ID_Macintosh   = 7;\n  AB_GZ_OS_ID_Z_System    = 8;\n  AB_GZ_OS_ID_CP_M        = 9;\n  AB_GZ_OS_ID_TOPS20      = 10;\n  AB_GZ_OS_ID_NTFS        = 11;\n  AB_GZ_OS_ID_QDOS        = 12;\n  AB_GZ_OS_ID_AcornRISCOS = 13;\n  AB_GZ_OS_ID_VFAT        = 14;\n  AB_GZ_OS_ID_MVS         = 15;\n  AB_GZ_OS_ID_BEOS        = 16;\n  AB_GZ_OS_ID_TANDEM      = 17;\n  AB_GZ_OS_ID_THEOS       = 18;\n  AB_GZ_OS_ID_unknown     = 255;\n\nfunction GZOsToStr(OS: Byte) : string;\n{\nReturn a descriptive string for TGzHeader.OS field\n}\nbegin\n  case OS of\n    AB_GZ_OS_ID_FAT         : Result := AbGzOsFat;\n    AB_GZ_OS_ID_Amiga       : Result := AbGzOsAmiga;\n    AB_GZ_OS_ID_VMS         : Result := AbGzOsVMS;\n    AB_GZ_OS_ID_Unix        : Result := AbGzOsUnix;\n    AB_GZ_OS_ID_VM_CMS      : Result := AbGzOsVM_CMS;\n    AB_GZ_OS_ID_AtariTOS    : Result := AbGzOsAtari;\n    AB_GZ_OS_ID_HPFS        : Result := AbGzOsHPFS;\n    AB_GZ_OS_ID_Macintosh   : Result := AbGzOsMacintosh;\n    AB_GZ_OS_ID_Z_System    : Result := AbGzOsZ_System;\n    AB_GZ_OS_ID_CP_M        : Result := AbGzOsCP_M;\n    AB_GZ_OS_ID_TOPS20      : Result := AbGzOsTOPS_20;\n    AB_GZ_OS_ID_NTFS        : Result := AbGzOsNTFS;\n    AB_GZ_OS_ID_QDOS        : Result := AbGzOsQDOS;\n    AB_GZ_OS_ID_AcornRISCOS : Result := AbGzOsAcornRISCOS;\n    AB_GZ_OS_ID_VFAT        : Result := AbGzOsVFAT;\n    AB_GZ_OS_ID_MVS         : Result := AbGzOsMVS;\n    AB_GZ_OS_ID_BEOS        : Result := AbGzOsBeOS;\n    AB_GZ_OS_ID_TANDEM      : Result := AbGzOsTandem;\n    AB_GZ_OS_ID_THEOS       : Result := AbGzOsTHEOS;\n    AB_GZ_OS_ID_unknown     : Result := AbGzOsunknown;\n  else\n    Result := AbGzOsUndefined;\n  end;\nend;\n\n\nfunction VerifyHeader(const Header : TAbGzHeader) : Boolean;\nbegin\n  { check id fields and if deflated (only handle deflate anyway)}\n  Result := (Header.ID1 = AB_GZ_HDR_ID1) and\n     (Header.ID2 = AB_GZ_HDR_ID2) and\n     (Header.CompMethod = 8 {deflate});\nend;\n\nfunction VerifyGZip(Strm : TStream) : TAbArchiveType;\nvar\n  GHlp : TAbGzipStreamHelper;\n  Hlpr : TAbDeflateHelper;\n  PartialTarData : TMemoryStream;\n  CurPos : Int64;\nbegin\n  Result := atUnknown;\n  CurPos := Strm.Position;\n  try\n    Strm.Seek(0, soBeginning);\n\n    {prepare for the try..finally}\n    Hlpr := nil;\n    PartialTarData := nil;\n\n    GHlp := TAbGzipStreamHelper.Create(Strm);\n    try\n      {create the stream helper and read the item header}\n      GHlp.ReadHeader;\n\n      { check id fields and if deflated (only handle deflate anyway)}\n      if VerifyHeader(GHlp.FItem.FGZHeader) then begin\n        Result := atGZip; { provisional }\n\n        { check if is actually a Gzipped Tar }\n        { partial extract contents, verify vs. Tar }\n        PartialTarData := TMemoryStream.Create;\n        GHlp.SeekToItemData;\n        Hlpr := TAbDeflateHelper.Create;\n        Hlpr.PartialSize := 512;\n        PartialTarData.SetSize(512 * 2);\n        Inflate(Strm, PartialTarData, Hlpr);\n\n        {set to beginning of extracted data}\n        PartialTarData.Position := 0;\n\n        if (VerifyTar(PartialTarData) = atTar) then\n          Result := atGZippedTar;\n      end;\n    finally\n      GHlp.Free;\n      Hlpr.Free;\n      PartialTarData.Free;\n    end;\n  except\n    on EReadError do\n      Result := atUnknown;\n  end;\n  Strm.Position := CurPos;\nend;\n\n{ TAbGzipExtraField }\n\nconstructor TAbGzipExtraField.Create(aGZHeader : PAbGzHeader);\nbegin\n  inherited Create;\n  FGZHeader := aGZHeader;\nend;\n\nprocedure TAbGzipExtraField.Changed;\nbegin\n  if Buffer = nil then\n    FGzHeader.Flags := FGzHeader.Flags and not AB_GZ_FLAG_FEXTRA\n  else\n    FGzHeader.Flags := FGzHeader.Flags or AB_GZ_FLAG_FEXTRA;\nend;\n\nprocedure TAbGzipExtraField.Delete(aID : TAbGzExtraFieldSubID);\nbegin\n  inherited Delete(Word(aID));\nend;\n\nfunction TAbGzipExtraField.GetID(aIndex : Integer): TAbGzExtraFieldSubID;\nbegin\n  Result := TAbGzExtraFieldSubID(inherited IDs[aIndex]);\nend;\n\nfunction TAbGzipExtraField.Get(aID : TAbGzExtraFieldSubID; out aData : Pointer;\n  out aDataSize : Word) : Boolean;\nbegin\n  Result := inherited Get(Word(aID), aData, aDataSize);\nend;\n\nprocedure TAbGzipExtraField.Put(aID : TAbGzExtraFieldSubID; const aData; aDataSize : Word);\nbegin\n  inherited Put(Word(aID), aData, aDataSize);\nend;\n\n\n{ TAbGzipStreamHelper }\n\nconstructor TAbGzipStreamHelper.Create(AStream : TStream);\nbegin\n  inherited Create(AStream);\n  FItem := TAbGzipItem.Create;\nend;\n\ndestructor TAbGzipStreamHelper.Destroy;\nbegin\n  FItem.Free;\n  inherited;\nend;\n\nfunction ReadCStringInStream(AStream: TStream): AnsiString;\n{\nlocate next instance of a null character in a stream\nleaves stream positioned just past that,\nor at end of stream if not found or null is last byte in stream.\nResult is the entire read string.\n}\nconst\n  BuffSiz = 1024;\nvar\n  Buff   : array [0..BuffSiz-1] of AnsiChar;\n  Len, DataRead : LongInt;\nbegin\n{ basically what this is supposed to do is...}\n{\n  repeat\n    AStream.Read(C, 1);\n    Result := Result + C;\n  until (AStream.Position = AStream.Size) or (C = #0);\n}\n  Result := '';\n  repeat\n    DataRead := AStream.Read(Buff, BuffSiz - 1);\n    Buff[DataRead] := #0;\n    Len := AbStrLen(Buff);\n    if Len > 0 then begin\n      SetLength(Result, Length(Result) + Len);\n      Move(Buff, Result[Length(Result) - Len + 1], Len);\n    end;\n    if Len < DataRead then begin\n      AStream.Seek(Len - DataRead + 1, soCurrent);\n      Break;\n    end;\n  until DataRead = 0;\nend;\n\nprocedure TAbGzipStreamHelper.SeekToItemData;\n{find end of header data, including FileName etc.}\nbegin\n  {** Seek to Compressed Data **}\n  FStream.Seek(0, soBeginning);\n  FItem.LoadGzHeaderFromStream(FStream);\nend;\n\nprocedure TAbGzipStreamHelper.ExtractItemData(AStream: TStream);\nvar\n  Helper : TAbDeflateHelper;\nbegin\n  Helper := TAbDeflateHelper.Create;\n  try\n    SeekToItemData;\n    if (AStream is TAbBitBucketStream) then\n      Helper.Options := Helper.Options or dfc_TestOnly;\n    FItem.CRC32 := Inflate(FStream, AStream, Helper);\n    FItem.UncompressedSize := AStream.Size{Helper.NormalSize};\n  finally\n    Helper.Free;\n  end;\nend;\n\nfunction TAbGzipStreamHelper.FindFirstItem: Boolean;\nvar\n  GZH : TAbGzHeader;\n  DataRead : Integer;\nbegin\n  Result := False;\n  FStream.Seek(0, soBeginning);\n  DataRead := FStream.Read(GZH, SizeOf(TAbGzHeader));\n  if (DataRead = SizeOf(TAbGzHeader)) and VerifyHeader(GZH) then begin\n    FItem.FGZHeader := GZH;\n    Result := True;\n  end;\n  FStream.Seek(0, soBeginning);\nend;\n\nfunction TAbGzipStreamHelper.FindNextItem: Boolean;\nbegin\n  { only one item in a GZip }\n  Result := False;\nend;\n\nfunction TAbGzipStreamHelper.SeekItem(Index: Integer): Boolean;\nbegin\n  if Index > 0 then\n    Result := False\n  else\n    Result := FindFirstItem;\nend;\n\nprocedure TAbGzipStreamHelper.WriteArchiveHeader;\nbegin\n  FItem.SaveGzHeaderToStream(FStream);\nend;\n\nprocedure TAbGzipStreamHelper.WriteArchiveItem(AStream: TStream);\nvar\n  Helper : TAbDeflateHelper;\nbegin\n  Helper := TAbDeflateHelper.Create;\n  try\n    FItem.CRC32 := Deflate(AStream, FStream, Helper);\n    FItem.UncompressedSize := AStream.Size;\n  finally\n    Helper.Free;\n  end;\nend;\n\nprocedure TAbGzipStreamHelper.WriteArchiveTail;\nvar\n  Tail : TAbGzTailRec;\nbegin\n  Tail.CRC32 := FItem.CRC32;\n  Tail.ISize := FItem.UncompressedSize;\n  FStream.Write(Tail, SizeOf(TAbGzTailRec));\nend;\n\nfunction TAbGzipStreamHelper.GetItemCount: Integer;\nbegin\n  { only one item in a gzip }\n  Result := 1;\nend;\n\nprocedure TAbGzipStreamHelper.ReadHeader;\nbegin\n  FItem.LoadGzHeaderFromStream(FStream);\nend;\n\nprocedure TAbGzipStreamHelper.ReadTail;\nbegin\n  FStream.Read(FTail, SizeOf(TAbGzTailRec));\nend;\n\nfunction TAbGzipStreamHelper.GetGzCRC: LongInt;\nbegin\n  Result := FItem.CRC32;\nend;\n\nfunction TAbGzipStreamHelper.GetFileSize: LongInt;\nbegin\n  Result := FItem.UncompressedSize;\nend;\n\n{ TAbGzipItem }\n\nconstructor TAbGzipItem.Create;\nbegin\n  inherited Create;\n\n  { default ID fields }\n  FGzHeader.ID1 := AB_GZ_HDR_ID1;\n  FGzHeader.ID2 := AB_GZ_HDR_ID2;\n\n  { compression method }\n  FGzHeader.CompMethod := 8;  { deflate }\n\n  { Maxium Compression }\n  FGzHeader.XtraFlags := 2;\n\n  FFileName := '';\n  FFileComment := '';\n  FExtraField := TAbGzipExtraField.Create(@FGzHeader);\n\n  { source OS ID }\n{$IFDEF LINUX } {assume EXT2 system }\n  FGzHeader.OS := AB_GZ_OS_ID_Unix;\n{$ENDIF LINUX }\n{$IFDEF MSWINDOWS } {assume FAT system }\n  FGzHeader.OS := AB_GZ_OS_ID_FAT;\n{$ENDIF MSWINDOWS }\nend;\n\ndestructor TAbGzipItem.Destroy;\nbegin\n  FExtraField.Free;\n  inherited;\nend;\n\nfunction TAbGzipItem.GetExternalFileAttributes: LongWord;\nbegin\n  { GZip has no provision for storing attributes }\n  Result := 0;\nend;\n\nfunction TAbGzipItem.GetFileSystem: TAbGzFileSystem;\nbegin\n  case FGzHeader.OS of\n    0..18: Result := TAbGzFileSystem(FGzHeader.OS);\n    255:   Result := osUnknown;\n    else\n      Result := osUndefined;\n  end; { case }\nend;\n\nfunction TAbGzipItem.GetIsEncrypted: Boolean;\nbegin\n  Result := (FGZHeader.Flags and AB_GZ_FLAG_FENCRYPTED) = AB_GZ_FLAG_FENCRYPTED;\nend;\n\nfunction TAbGzipItem.GetHasExtraField: Boolean;\nbegin\n  Result := (FGZHeader.Flags and AB_GZ_FLAG_FEXTRA) = AB_GZ_FLAG_FEXTRA;\nend;\n\nfunction TAbGzipItem.GetHasFileComment: Boolean;\nbegin\n  Result := (FGZHeader.Flags and AB_GZ_FLAG_FCOMMENT) = AB_GZ_FLAG_FCOMMENT;\nend;\n\nfunction TAbGzipItem.GetHasFileName: Boolean;\nbegin\n  Result := (FGZHeader.Flags and AB_GZ_FLAG_FNAME) = AB_GZ_FLAG_FNAME;\nend;\n\nfunction TAbGzipItem.GetIsText: Boolean;\nbegin\n  Result := (FGZHeader.Flags and AB_GZ_FLAG_FTEXT) = AB_GZ_FLAG_FTEXT;\nend;\n\nfunction TAbGzipItem.GetLastModFileDate: Word;\nbegin\n  { convert to local DOS file Date }\n  Result := LongRec(AbDateTimeToDosFileDate(LastModTimeAsDateTime)).Hi;\nend;\n\nfunction TAbGzipItem.GetLastModFileTime: Word;\nbegin\n  { convert to local DOS file Time }\n  Result := LongRec(AbDateTimeToDosFileDate(LastModTimeAsDateTime)).Lo;\nend;\n\nfunction TAbGzipItem.GetLastModTimeAsDateTime: TDateTime;\nbegin\n  Result := AbUnixTimeToLocalDateTime(FGZHeader.ModTime);\nend;\n\nprocedure TAbGzipItem.LoadGzHeaderFromStream(AStream: TStream);\nvar\n  LenW : Word;\nbegin\n  AStream.Read(FGzHeader, SizeOf(TAbGzHeader));\n  if not VerifyHeader(FGzHeader) then\n    Exit;\n\n  { Skip part number, if any  }\n  if (FGzHeader.Flags and AB_GZ_FLAG_FCONTINUATION) = AB_GZ_FLAG_FCONTINUATION then\n    AStream.Seek(SizeOf(Word), soCurrent);\n\n  if HasExtraField then begin\n    { get length of extra data }\n    AStream.Read(LenW, SizeOf(Word));\n    FExtraField.LoadFromStream(AStream, LenW);\n  end\n  else\n    FExtraField.Clear;\n\n  { Get Filename, if any }\n  if HasFileName then begin\n    FRawFileName := ReadCStringInStream(AStream);\n    FFileName := AbRawBytesToString(FRawFileName)\n  end\n  else\n    FFileName := 'unknown';\n\n  { any comment present? }\n  if HasFileComment then\n    FFileComment := ReadCStringInStream(AStream)\n  else\n    FFileComment := '';\n\n\n  {Assert: stream should now be located at start of compressed data }\n  {If file was compressed with 3.3 spec this will be invalid so use with care}\n  CompressedSize := AStream.Size - AStream.Position - SizeOf(TAbGzTailRec);\n\n  FDiskFileName := FileName;\n  AbUnfixName(FDiskFileName);\n  Action := aaNone;\n  Tagged := False;\nend;\n\nprocedure TAbGzipItem.SaveGzHeaderToStream(AStream: TStream);\nvar\n  LenW : Word;\nbegin\n  { default ID fields }\n  FGzHeader.ID1 := AB_GZ_HDR_ID1;\n  FGzHeader.ID2 := AB_GZ_HDR_ID2;\n\n  { compression method }\n  FGzHeader.CompMethod := 8;  { deflate }\n\n  { reset unsupported flags }\n  FGzHeader.Flags := FGzHeader.Flags and not AB_GZ_UNSUPPORTED_FLAGS;\n\n  { main header data }\n  AStream.Write(FGzHeader, SizeOf(TAbGzHeader));\n\n  { add extra field if any }\n  if HasExtraField then begin\n    LenW := Length(FExtraField.Buffer);\n    AStream.Write(LenW, SizeOf(LenW));\n    if LenW > 0 then\n      AStream.Write(FExtraField.Buffer[0], LenW);\n  end;\n\n  { add filename if any (and include final #0 from string) }\n  if HasFileName then\n    AStream.Write(FRawFileName[1], Length(FRawFileName) + 1);\n\n  { add file comment if any (and include final #0 from string) }\n  if HasFileComment then\n    AStream.Write(FFileComment[1], Length(FFileComment) + 1);\nend;\n\nprocedure TAbGzipItem.SetExternalFileAttributes(Value: LongWord);\nbegin\n  { do nothing }\nend;\n\nprocedure TAbGzipItem.SetFileComment(const Value: AnsiString);\nbegin\n  FFileComment := Value;\n  if FFileComment <> '' then\n    FGzHeader.Flags := FGzHeader.Flags or AB_GZ_FLAG_FCOMMENT\n  else\n    FGzHeader.Flags := FGzHeader.Flags and not AB_GZ_FLAG_FCOMMENT;\nend;\n\nprocedure TAbGzipItem.SetFileName(const Value: string);\nbegin\n  FFileName := Value;\n  FRawFileName := AbStringToUnixBytes(Value);\n  if Value <> '' then\n    FGzHeader.Flags := FGzHeader.Flags or AB_GZ_FLAG_FNAME\n  else\n    FGzHeader.Flags := FGzHeader.Flags and not AB_GZ_FLAG_FNAME;\nend;\n\nprocedure TAbGzipItem.SetFileSystem(const Value: TAbGzFileSystem);\nbegin\n  if Value = osUnknown then\n    FGzHeader.OS := 255\n  else\n    FGzHeader.OS := Ord(Value);\nend;\n\nprocedure TAbGzipItem.SetIsEncrypted(Value: Boolean);\nbegin\n  { do nothing }\nend;\n\nprocedure TAbGzipItem.SetIsText(const Value: Boolean);\nbegin\n  if Value then\n    FGzHeader.Flags := FGzHeader.Flags or AB_GZ_FLAG_FTEXT\n  else\n    FGzHeader.Flags := FGzHeader.Flags and not AB_GZ_FLAG_FTEXT;\nend;\n\nprocedure TAbGzipItem.SetLastModFileDate(const Value: Word);\nbegin\n  { replace date, keep existing time }\n  LastModTimeAsDateTime :=\n    EncodeDate(\n      Value shr 9 + 1980,\n      Value shr 5 and 15,\n      Value and 31) +\n    Frac(LastModTimeAsDateTime);\nend;\n\nprocedure TAbGzipItem.SetLastModFileTime(const Value: Word);\nbegin\n  { keep current date, replace time }\n  LastModTimeAsDateTime :=\n    Trunc(LastModTimeAsDateTime) +\n    EncodeTime(\n      Value shr 11,\n      Value shr 5 and 63,\n      Value and 31 shl 1, 0);\nend;\n\nprocedure TAbGzipItem.SetLastModTimeAsDateTime(const Value: TDateTime);\nbegin\n  FGZHeader.ModTime := AbLocalDateTimeToUnixTime(Value);\nend;\n\n{ TAbGzipArchive }\n\nconstructor TAbGzipArchive.CreateFromStream(aStream : TStream;\n  const aArchiveName : string);\nbegin\n  inherited CreateFromStream(aStream, aArchiveName);\n  FState     := gsGzip;\n  FGZStream  := FStream;\n  FGZItem    := FItemList;\n  FTarStream := TAbVirtualMemoryStream.Create;\n  FTarList   := TAbArchiveList.Create(True);\nend;\n\nprocedure TAbGzipArchive.SwapToTar;\nbegin\n  FStream := FTarStream;\n  FItemList := FTarList;\n  FState := gsTar;\nend;\n\nprocedure TAbGzipArchive.SwapToGzip;\nbegin\n  FStream := FGzStream;\n  FItemList := FGzItem;\n  FState := gsGzip;\nend;\n\nfunction TAbGzipArchive.CreateItem(const FileSpec: string): TAbArchiveItem;\nvar\n  GzItem : TAbGzipItem;\nbegin\n  if IsGZippedTar and TarAutoHandle then begin\n    SwapToTar;\n    Result := inherited CreateItem(FileSpec);\n  end\n  else begin\n    SwapToGzip;\n    GzItem := TAbGzipItem.Create;\n    try\n      GzItem.CompressedSize := 0;\n      GzItem.CRC32 := 0;\n      GzItem.DiskFileName := ExpandFileName(FileSpec);\n      GzItem.FileName := FixName(FileSpec);\n      Result := GzItem;\n    except\n      Result := nil;\n    end;\n  end;\nend;\n\ndestructor TAbGzipArchive.Destroy;\nbegin\n  SwapToGzip;\n  FTarList.Free;\n  FTarStream.Free;\n  inherited Destroy;\nend;\n\n\nprocedure TAbGzipArchive.ExtractItemAt(Index: Integer;\n  const UseName: string);\nvar\n  OutStream : TFileStream;\n  CurItem : TAbGzipItem;\nbegin\n  if IsGZippedTar and TarAutoHandle then begin\n    SwapToTar;\n    inherited ExtractItemAt(Index, UseName);\n  end\n  else begin\n    SwapToGzip;\n    if Index > 0 then Index := 0; { only one item in a GZip}\n\n    CurItem := TAbGzipItem(ItemList[Index]);\n\n    OutStream := TFileStream.Create(UseName, fmCreate or fmShareDenyNone);\n    try\n      try {OutStream}\n        ExtractItemToStreamAt(Index, OutStream);\n      finally {OutStream}\n        OutStream.Free;\n      end; {OutStream}\n      AbSetFileTime(UseName, CurItem.LastModTimeAsDateTime);\n      AbSetFileAttr(UseName, CurItem.NativeFileAttributes);\n    except\n      on E : EAbUserAbort do begin\n        FStatus := asInvalid;\n        if FileExists(UseName) then\n          DeleteFile(UseName);\n        raise;\n      end else begin\n        if FileExists(UseName) then\n          DeleteFile(UseName);\n        raise;\n      end;\n    end;\n  end;\nend;\n\nprocedure TAbGzipArchive.ExtractItemToStreamAt(Index: Integer;\n  aStream: TStream);\nvar\n  GzHelp  : TAbGzipStreamHelper;\nbegin\n  if IsGzippedTar and TarAutoHandle then begin\n    SwapToTar;\n    inherited ExtractItemToStreamAt(Index, aStream);\n  end\n  else begin\n    SwapToGzip;\n    { note Index ignored as there's only one item in a GZip }\n\n    GZHelp := TAbGzipStreamHelper.Create(FGzStream);\n    try\n      { read GZip Header }\n      GzHelp.ReadHeader;\n\n      { extract copy data from GZip}\n      GzHelp.ExtractItemData(aStream);\n\n      { Get validation data }\n      GzHelp.ReadTail;\n\n      {$IFDEF STRICTGZIP}\n      { According to\n          http://www.gzip.org/zlib/rfc1952.txt\n\n       A compliant gzip compressor should calculate and set the CRC32 and ISIZE.\n       However, a compliant decompressor should not check these values.\n\n       If you want to check the the values of the CRC32 and ISIZE in a GZIP file\n       when decompressing enable the STRICTGZIP define contained in AbDefine.inc }\n\n      { validate against CRC }\n      if GzHelp.FItem.Crc32 <> GzHelp.TailCRC then\n        raise EAbGzipBadCRC.Create;\n\n      { validate against file size }\n      if GzHelp.FItem.UncompressedSize <> GZHelp.TailSize then\n        raise EAbGzipBadFileSize.Create;\n      {$ENDIF}\n    finally\n      GzHelp.Free;\n    end;\n  end;\nend;\n\nfunction TAbGzipArchive.FixName(const Value: string): string;\n{ fix up fileaname for storage }\nbegin\n  if FState = gsTar then\n    Result := inherited FixName( Value )\n  else begin\n    {GZip files Always strip the file path}\n    StoreOptions := StoreOptions + [soStripDrive, soStripPath];\n    Result := '';\n    if Value <> '' then\n      Result := ExtractFileName(Value);\n  end;\nend;\n\nfunction TAbGzipArchive.GetIsGzippedTar: Boolean;\nbegin\n  Result := FIsGzippedTar;\nend;\n\nfunction TAbGzipArchive.GetItem(Index: Integer): TAbGzipItem;\nbegin\n  Result := nil;\n  if Index = 0 then\n    Result := TAbGzipItem(FItemList.Items[Index]);\nend;\n\nfunction TAbGzipArchive.GetSupportsEmptyFolders : Boolean;\nbegin\n  Result := IsGzippedTar and TarAutoHandle;\nend;\n\nprocedure TAbGzipArchive.LoadArchive;\nvar\n  GzHelp : TAbGzipStreamHelper;\n  Item   : TAbGzipItem;\n  Abort  : Boolean;\nbegin\n  SwapToGzip;\n  if FGzStream.Size > 0 then begin\n    GzHelp := TAbGzipStreamHelper.Create(FGzStream);\n    try\n      if GzHelp.FindFirstItem then begin\n        Item := TAbGzipItem.Create;\n        Item.LoadGzHeaderFromStream(FGzStream);\n        FGzStream.Seek(-SizeOf(TAbGzTailRec), soEnd);\n        GZHelp.ReadTail;\n        Item.CRC32 := GZHelp.TailCRC;\n        Item.UncompressedSize := GZHelp.TailSize;\n\n        Item.Action := aaNone;\n        FGZItem.Add(Item);\n\n        if IsGzippedTar and TarAutoHandle then begin\n          { extract Tar and set stream up }\n          FTarStream.SwapFileDirectory := FTempDir;\n          GzHelp.SeekToItemData;\n          GzHelp.ExtractItemData(FTarStream);\n          SwapToTar;\n          inherited LoadArchive;\n        end;\n      end;\n\n      DoArchiveProgress(100, Abort);\n      FIsDirty := False;\n    finally\n      { Clean Up }\n      GzHelp.Free;\n    end;\n  end;\nend;\n\nprocedure TAbGzipArchive.PutItem(Index: Integer; const Value: TAbGzipItem);\nbegin\n  if Index = 0 then\n    FItemList.Items[Index] := Value;\nend;\n\nprocedure TAbGzipArchive.SaveArchive;\nvar\n  InGzHelp, OutGzHelp : TAbGzipStreamHelper;\n  Abort               : Boolean;\n  i                   : Integer;\n  NewStream           : TAbVirtualMemoryStream;\n  UncompressedStream  : TStream;\n  SaveDir             : string;\n  CurItem             : TAbGzipItem;\nbegin\n  {prepare for the try..finally}\n  OutGzHelp := nil;\n  NewStream := nil;\n\n  try\n    InGzHelp := TAbGzipStreamHelper.Create(FGzStream);\n\n    try\n      {init new archive stream}\n      NewStream := TAbVirtualMemoryStream.Create;\n      OutGzHelp := TAbGzipStreamHelper.Create(NewStream);\n\n      { create helper }\n      NewStream.SwapFileDirectory := FTempDir;\n\n      { save the Tar data }\n      if IsGzippedTar and TarAutoHandle then begin\n        SwapToTar;\n        inherited SaveArchive;\n        if FGZItem.Count = 0 then begin\n          CurItem := TAbGzipItem.Create;\n          FGZItem.Add(CurItem);\n        end;\n        CurItem := FGZItem[0] as TAbGzipItem;\n        CurItem.Action := aaNone;\n        CurItem.LastModTimeAsDateTime := Now;\n        CurItem.SaveGzHeaderToStream(NewStream);\n        FTarStream.Position := 0;\n        OutGzHelp.WriteArchiveItem(FTarStream);\n        CurItem.CRC32 := OutGzHelp.CRC;\n        CurItem.UncompressedSize := OutGzHelp.FileSize;\n        OutGzHelp.WriteArchiveTail;\n      end\n      else begin\n        SwapToGzip;\n\n        {build new archive from existing archive}\n        for i := 0 to pred(Count) do begin\n          FCurrentItem := ItemList[i];\n          CurItem      := TAbGzipItem(ItemList[i]);\n          InGzHelp.SeekToItemData;\n\n          case CurItem.Action of\n            aaNone, aaMove : begin\n            {just copy the file to new stream}\n              CurItem.SaveGzHeaderToStream(NewStream);\n              InGzHelp.SeekToItemData;\n              NewStream.CopyFrom(FGZStream, FGZStream.Size - FGZStream.Position);\n            end;\n\n            aaDelete: {doing nothing omits file from new stream} ;\n\n            aaAdd, aaFreshen, aaReplace, aaStreamAdd: begin\n              try\n                if (CurItem.Action = aaStreamAdd) then begin\n                { adding from a stream }\n                  CurItem.SaveGzHeaderToStream(NewStream);\n                  CurItem.UncompressedSize := InStream.Size;\n                  OutGzHelp.WriteArchiveItem(InStream);\n                  OutGzHelp.WriteArchiveTail;\n                end\n                else begin\n                { it's coming from a file }\n                  GetDir(0, SaveDir);\n                  try {SaveDir}\n                    if (BaseDirectory <> '') then\n                      ChDir(BaseDirectory);\n                    CurItem.LastModTimeAsDateTime := AbGetFileTime(CurItem.DiskFileName);\n                    UncompressedStream := TFileStream.Create(CurItem.DiskFileName,\n                      fmOpenRead or fmShareDenyWrite );\n                  finally {SaveDir}\n                    ChDir( SaveDir );\n                  end; {SaveDir}\n\n                  try\n                    CurItem.UncompressedSize := UncompressedStream.Size;\n                    CurItem.SaveGzHeaderToStream(NewStream);\n                    OutGzHelp.WriteArchiveItem(UncompressedStream);\n                    OutGzHelp.WriteArchiveTail;\n\n                  finally {UncompressedStream}\n                    UncompressedStream.Free;\n                  end; {UncompressedStream}\n                end;\n              except\n                ItemList[i].Action := aaDelete;\n                DoProcessItemFailure(ItemList[i], ptAdd, ecFileOpenError, 0);\n              end;\n            end;\n          end; {case}\n        end; { for }\n      end;\n    finally\n      InGzHelp.Free;\n    end;\n\n    {copy new stream to FStream}\n    SwapToGzip;\n    NewStream.Position := 0;\n    if (FStream is TMemoryStream) then\n      TMemoryStream(FStream).LoadFromStream(NewStream)\n    else if FOwnsStream then begin\n      { need new stream to write }\n      FreeAndNil(FStream);\n      FGZStream := nil;\n      FStream := TFileStream.Create(FArchiveName, fmCreate or fmShareDenyWrite);\n      FGZStream := FStream;\n      FStream.CopyFrom(NewStream, NewStream.Size);\n    end\n    else begin\n      FStream.Size := 0;\n      FStream.Position := 0;\n      FStream.CopyFrom(NewStream, NewStream.Size);\n    end;\n\n    {update Items list}\n    for i := pred( Count ) downto 0 do begin\n      if ItemList[i].Action = aaDelete then\n        FItemList.Delete( i )\n      else if ItemList[i].Action <> aaFailed then\n        ItemList[i].Action := aaNone;\n    end;\n\n    if IsGzippedTar and TarAutoHandle then\n      SwapToTar;\n\n    DoArchiveSaveProgress( 100, Abort );\n    DoArchiveProgress( 100, Abort );\n  finally {NewStream}\n    OutGzHelp.Free;\n    NewStream.Free;\n  end;\nend;\n\nprocedure TAbGzipArchive.SetTarAutoHandle(const Value: Boolean);\nbegin\n  if Value then\n    SwapToTar\n  else\n    SwapToGzip;\n  FTarAutoHandle := Value;\nend;\n\nprocedure TAbGzipArchive.TestItemAt(Index: Integer);\nvar\n  SavePos   : LongInt;\n  GZType    : TAbArchiveType;\n  BitBucket : TAbBitBucketStream;\n  GZHelp    : TAbGzipStreamHelper;\nbegin\n  if IsGzippedTar and TarAutoHandle then begin\n    inherited TestItemAt(Index);\n  end\n  else begin\n    { note Index ignored as there's only one item in a GZip }\n    SavePos := FGzStream.Position;\n    GZType := VerifyGZip(FGZStream);\n    if not (GZType in [atGZip, atGZippedTar]) then\n      raise EAbGzipInvalid.Create;\n\n    BitBucket := nil;\n    GZHelp := nil;\n    try\n      BitBucket := TAbBitBucketStream.Create(1024);\n      GZHelp := TAbGzipStreamHelper.Create(FGZStream);\n\n      GZHelp.ExtractItemData(BitBucket);\n      GZHelp.ReadTail;\n\n      { validate against CRC }\n      if GzHelp.FItem.Crc32 <> GZHelp.TailCRC then\n        raise EAbGzipBadCRC.Create;\n\n      { validate against file size }\n      if GzHelp.FItem.UncompressedSize <> GZHelp.TailSize then\n        raise EAbGzipBadFileSize.Create;\n\n    finally\n      GZHelp.Free;\n      BitBucket.Free;\n    end;\n\n    FGzStream.Position := SavePos;\n  end;\nend;\n\nprocedure TAbGzipArchive.DoSpanningMediaRequest(Sender: TObject;\n  ImageNumber: Integer; var ImageName: string; var Abort: Boolean);\nbegin\n  Abort := False;\nend;\n\nend.\n"
  },
  {
    "path": "lib/abbrevia/source/AbHexVw.pas",
    "content": "(* ***** BEGIN LICENSE BLOCK *****\n * Version: MPL 1.1\n *\n * The contents of this file are subject to the Mozilla Public License Version\n * 1.1 (the \"License\"); you may not use this file except in compliance with\n * the License. You may obtain a copy of the License at\n * http://www.mozilla.org/MPL/\n *\n * Software distributed under the License is distributed on an \"AS IS\" basis,\n * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License\n * for the specific language governing rights and limitations under the\n * License.\n *\n * The Original Code is TurboPower Abbrevia\n *\n * The Initial Developer of the Original Code is\n * TurboPower Software\n *\n * Portions created by the Initial Developer are Copyright (C) 1997-2002\n * the Initial Developer. All Rights Reserved.\n *\n * Contributor(s):\n *\n * ***** END LICENSE BLOCK ***** *)\n\n{*********************************************************}\n{* Abbrevia: AbHexVw.pas                                 *}\n{*********************************************************}\n{* Abbrevia: Hex View utility                            *}\n{*********************************************************}\n\n{$I AbDefine.inc}\n\n{$IFNDEF UsingCLX}\nunit AbHexVw;\n{$ENDIF}\n\ninterface\n\nuses\n  Classes,\n{$IFDEF UsingCLX}\n  QStdCtrls, QGraphics,\n{$ELSE}\n  StdCtrls, Graphics, \n{$ENDIF}\n  SysUtils;\ntype\n  THexView = class(TMemo)\n  protected\n    FBlockSize : Integer;\n  public\n    procedure SetStream(Strm : TStream);\n    constructor Create(AOwner : TComponent); override;\n    destructor Destroy; override;\n    property Stream : TStream write SetStream;\n    property BlockSize : Integer read FBlockSize write FBlockSize;\n  end;\n\nimplementation\n\n{$IFDEF HasUITypes}\nuses\n  System.UITypes;\n{$ENDIF}\n\nconstructor THexView.Create(AOwner : TComponent);\nbegin\n  Inherited Create(AOwner);\n  Font.Style := Font.Style + [fsBold];\n  ReadOnly := True;\n  ScrollBars := ssVertical;\n  WordWrap := False;\n  WantTabs := True;\n  FBlockSize := 512;\nend;\n\ndestructor THexView.Destroy;\nbegin\n  inherited Destroy;\nend;\n\nprocedure THexView.SetStream(Strm : TStream);\nvar\n  Buff : Array[0..15] of Byte;\n  i, j : Integer;\n  Str : String;\n  StrList : TStringList;\nbegin\n  Strm.Seek(0, soBeginning);\n  StrList := TStringList.Create;\n  Clear;\n  while Strm.Position < Strm.Size do begin\n    if ((Strm.Position mod FBlockSize) = 0) then\n      StrList.Add('===========================================================');\n    Str := '';\n\n    for j := 0 to 15 do\n      Buff[j] := Byte(chr(0));\n    Strm.Read(Buff, 16);\n    Str := Str + Format('%4.4X', [strm.Position - $10]) + ':' + #9;\n\n    for i := 0 to 15 do begin\n      Str := Str + Format('%2.2X', [Buff[i]]) + ' ';\n      if i = 7 then Str := Str + #9;\n    end;\n    Str := Str + #9;\n    for i := 0 to 15 do begin\n      if (Buff[i] < $30) then\n        Buff[i] := byte('.');\n      Str := Str + Char(Buff[i]);\n    end;\n    StrList.Add(Str);\n  end;\n  SetLines(StrList);\n  StrList.Free;\nend;\n\nend.\n"
  },
  {
    "path": "lib/abbrevia/source/AbLZMA.pas",
    "content": "(* ***** BEGIN LICENSE BLOCK *****\n * Version: MPL 1.1\n *\n * The contents of this file are subject to the Mozilla Public License Version\n * 1.1 (the \"License\"); you may not use this file except in compliance with\n * the License. You may obtain a copy of the License at\n * http://www.mozilla.org/MPL/\n *\n * Software distributed under the License is distributed on an \"AS IS\" basis,\n * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License\n * for the specific language governing rights and limitations under the\n * License.\n *\n * The Original Code is TurboPower Abbrevia\n *\n * The Initial Developer of the Original Code is Craig Peterson\n *\n * Portions created by the Initial Developer are Copyright (C) 2011\n * the Initial Developer. All Rights Reserved.\n *\n * Contributor(s):\n * Craig Peterson <capeterson@users.sourceforge.net>\n * Pierre le Riche <pierre_le_riche@users.sourceforge.net>\n *\n * ***** END LICENSE BLOCK ***** *)\n\n{*********************************************************}\n{* ABBREVIA: AbLZMA.pas                                  *}\n{*********************************************************}\n{* ABBREVIA: Lzma compression/decompression procedures.  *}\n{*********************************************************}\n\nunit AbLZMA;\n\n{$I AbDefine.inc}\n\ninterface\n\nuses\n  Classes, Windows, SysUtils, AbCrtl, AbUtils;\n\n{ Raw LZMA decompression =================================================== }\n\n{ Decompresses the LZMA compressed data in ASrc to ADes.  ASrc should not have\n  the header used by the other compression/decompression routines, and\n  AProperties should contain any necessary data. }\nprocedure LzmaDecodeStream(AProperties: PByte; APropSize: Integer; ASrc, ADes: TStream;\n  AUncompressedSize: Int64 = -1); overload;\n\n\n{ Stream compression and decompression (taken from LzmaUtil.c) ============= }\n\nprocedure LzmaDecodeStream(ASourceStream, ATargetStream: TStream); overload;\nprocedure LzmaEncodeStream(ASourceStream, ATargetStream: TStream; ASourceSize: Int64);\n\n\n{ In-memory compression and decompression ================================== }\n\n{ Given a pointer to the compressed data, this will return the size of the\n  decompressed data. }\nfunction LzmaGetUncompressedSize(APCompressedData: Pointer; ACompressedSize: Integer): Integer;\n\n{ Decompresses the LZMA compressed data at APCompressedData to the buffer\n  pointed to by APUncompressedData.  The buffer at APUncompressedData should be\n  large enough to hold the number of bytes as returned by LzmaGetDecompressedSize. }\nprocedure LzmaDecodeBuffer(APCompressedData: Pointer; ACompressedSize: Integer;\n  APUncompressedData: Pointer);\n\n{ Compresses the data at APUncompressedData to the buffer at APCompressedData,\n  and returns the number of bytes written. If ACompressedDataBufferCapacity is\n  less than the number of bytes required to store the entire compressed stream,\n  or any other error occurs, then an exception is raised. (A safe number for\n  ACompressedDataBufferCapacity is slightly more than AUncompressedDataBufferSize.)\n  Leave ACompressionLevel and ADictionarySize at -1 in order to use the default\n  values (5 and 16MB respectively). }\nfunction LzmaEncodeBuffer(APUncompressedData: Pointer; AUncompressedSize: Integer;\n  APCompressedData: Pointer; ACompressedDataBufferCapacity: Integer;\n  ACompressionLevel: Integer = -1; ADictionarySize: Integer = -1): Integer;\n\n\n{ Types.h declarations ===================================================== }\n\nconst\n  SZ_OK = 0;\n  SZ_ERROR_DATA = 1;\n  SZ_ERROR_MEM = 2;\n  SZ_ERROR_CRC = 3;\n  SZ_ERROR_UNSUPPORTED = 4;\n  SZ_ERROR_PARAM = 5;\n  SZ_ERROR_INPUT_EOF = 6;\n  SZ_ERROR_OUTPUT_EOF = 7;\n  SZ_ERROR_READ = 8;\n  SZ_ERROR_WRITE = 9;\n  SZ_ERROR_PROGRESS = 10;\n  SZ_ERROR_FAIL = 11;\n  SZ_ERROR_THREAD = 12;\n  SZ_ERROR_ARCHIVE = 16;\n  SZ_ERROR_NO_ARCHIVE = 17;\n\ntype\n  SRes = Integer;\n\n  ISeqInStream = packed record\n    Read: function(p: Pointer; var buf; var size: size_t): SRes; cdecl;\n  end;\n  PISeqInStream = ^ISeqInStream;\n\n  ISeqOutStream = packed record\n    Write: function(p: Pointer; const buf; size: size_t): size_t; cdecl;\n  end;\n  PISeqOutStream = ^ISeqOutStream;\n\n  ICompressProgress = packed record\n    Progress: function(p: Pointer; inSize, outSize: Int64): SRes; cdecl;\n  end;\n  PICompressProgress = ^ICompressProgress;\n\n  ISzAlloc = packed record\n    Alloc: function(p: Pointer; size: size_t): Pointer; cdecl;\n    Free: procedure(p: Pointer; address: Pointer); cdecl;\n  end;\n  PISzAlloc = ^ISzAlloc;\n\n\n{ LzmaDec.h declarations =================================================== }\n\ntype\n  CLzmaProb = Word;\n\n// LZMA Properties\nconst\n  LZMA_PROPS_SIZE = 5;\n\ntype\n  CLzmaProps = packed record\n    lc, lp, pb: Cardinal;\n    dicSize: UInt32;\n  end;\n\n// LZMA Decoder state\nconst\n  LZMA_REQUIRED_INPUT_MAX = 20;\n\ntype\n  CLzmaDec = packed record\n    prop: CLzmaProps;\n    probs: ^CLzmaProb;\n    dic: PByte;\n    buf: PByte;\n    range, code: UInt32;\n    dicPos: size_t;\n    dicBufSize: size_t;\n    processedPos: UInt32;\n    checkDicSize: UInt32;\n    state: Cardinal;\n    reps: array[0..3] of UInt32;\n    remainLen: Cardinal;\n    needFlush: Integer;\n    needInitState: Integer;\n    numProbs: UInt32;\n    tempBufSize: Cardinal;\n    tempBuf: array[0..LZMA_REQUIRED_INPUT_MAX - 1] of Byte;\n  end;\n\ntype\n  ELzmaFinishMode = LongInt;\n\nconst\n  LZMA_FINISH_ANY = 0; // finish at any point\n  LZMA_FINISH_END = 1; // block must be finished at the end\n\ntype\n  ELzmaStatus = LongInt;\n\nconst\n  LZMA_STATUS_NOT_SPECIFIED = 0;               // use main error code instead\n  LZMA_STATUS_FINISHED_WITH_MARK = 1;          // stream was finished with end mark.\n  LZMA_STATUS_NOT_FINISHED = 3;                // stream was not finished\n  LZMA_STATUS_NEEDS_MORE_INPUT = 4;            // you must provide more input bytes\n  LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK = 5; // there is probability that stream was finished without end mark\n\nprocedure LzmaDec_Construct(var p: CLzmaDec); cdecl;\nprocedure LzmaDec_Init(var p: CLzmaDec); cdecl; external;\nfunction LzmaDec_DecodeToBuf(var p: CLzmaDec; dest: PByte; var destLen: size_t;\n  src: PByte; var srcLen: size_t; finishMode: ELzmaFinishMode;\n  var status: ELzmaStatus): SRes; cdecl; external;\nfunction LzmaDec_Allocate(var state: CLzmaDec; prop: PByte; propsSize: Integer;\n  alloc: PISzAlloc): SRes; cdecl; external;\nprocedure LzmaDec_Free(var state: CLzmaDec; alloc: PISzAlloc); cdecl; external;\n\n// One call decoding interface\nfunction LzmaDecode(dest: PByte; var destLen: size_t; src: PByte;\n  var srcLen: size_t; propData: PByte; propSize: Integer;\n  finishMode: ELzmaFinishMode; var status: ELzmaStatus; \n  alloc: PISzAlloc): SRes; cdecl; external;\n\n\n{ LzmaEnc.h declarations =================================================== }\n\ntype\n  CLzmaEncHandle = Pointer;\n\n  CLzmaEncProps = packed record\n    level: Integer;         // 0 <= level <= 9\n    dictSize: UInt32;       // (1 << 12) <= dictSize <= (1 << 27) for 32-bit version\n                            // (1 << 12) <= dictSize <= (1 << 30) for 64-bit version\n                            // default = (1 << 24)\n    lc: Integer;            // 0 <= lc <= 8, default = 3\n    lp: Integer;            // 0 <= lp <= 4, default = 0\n    pb: Integer;            // 0 <= pb <= 4, default = 2\n    algo: Integer;          // 0 - fast, 1 - normal, default = 1\n    fb: Integer;            // 5 <= fb <= 273, default = 32\n    btMode: Integer;        // 0 - hashChain Mode, 1 - binTree mode - normal, default = 1\n    numHashBytes: Integer;  // 2, 3 or 4, default = 4\n    mc: UInt32;             // 1 <= mc <= (1 << 30), default = 32\n    writeEndMark: Cardinal; // 0 - do not write EOPM, 1 - write EOPM, default = 0\n    numThreads: Integer;    // 1 or 2, default = 2\n  end;\n\nprocedure LzmaEncProps_Init(var p: CLzmaEncProps); cdecl; external;\nfunction LzmaEnc_Create(Alloc: PISzAlloc): CLzmaEncHandle; cdecl; external;\nprocedure LzmaEnc_Destroy(p: CLzmaEncHandle; Alloc, allocBig: PISzAlloc); cdecl; external;\nfunction LzmaEnc_SetProps(p: CLzmaEncHandle; var props: CLzmaEncProps): SRes; cdecl; external;\nfunction LzmaEnc_WriteProperties(p: CLzmaEncHandle; properties: PByte;\n  var size: size_t): SRes; cdecl; external;\nfunction LzmaEnc_Encode(p: CLzmaEncHandle; outStream: PISeqOutStream;\n  inStream: PISeqInStream; Progress: PICompressProgress;\n  Alloc, allocBig: PISzAlloc): SRes; cdecl; external;\nfunction LzmaEnc_MemEncode(p: CLzmaEncHandle; dest: PByte; var destLen: size_t;\n  src: PByte; srcLen: size_t; writeEndMark: Integer; Progress: PICompressProgress;\n  Alloc, allocBig: PISzAlloc): SRes; cdecl; external;\n\n// One call encoding interface\nfunction LzmaEncode(dest: PByte; var destLen: size_t; src: PByte;\n  srcLen: size_t; var props: CLzmaEncProps; propsEncoded: PByte;\n  var propsSize: size_t; writeEndMark: Integer; progress: PICompressProgress;\n  alloc: pISzAlloc; allocBig: PISzAlloc): SRes; cdecl; external;\n\n\n{ LzFind.h declarations ==================================================== }\n\nprocedure MatchFinder_NeedMove; external;\nprocedure MatchFinder_GetPointerToCurrentPos; external;\nprocedure MatchFinder_MoveBlock; external;\nprocedure MatchFinder_ReadIfRequired; external;\nprocedure MatchFinder_Construct; external;\nprocedure MatchFinder_Create; external;\nprocedure MatchFinder_Free; external;\nprocedure MatchFinder_Normalize3; external;\nprocedure MatchFinder_ReduceOffsets; external;\nprocedure GetMatchesSpec1; external;\nprocedure MatchFinder_Init; external;\nprocedure MatchFinder_CreateVTable; external;\n\n\n{ LzFindMt.h declarations ================================================== }\n\nprocedure MatchFinderMt_Construct; external;\nprocedure MatchFinderMt_Destruct; external;\nprocedure MatchFinderMt_Create; external;\nprocedure MatchFinderMt_CreateVTable; external;\nprocedure MatchFinderMt_ReleaseStream; external;\n\n\n{ Lzma header fields ======================================================= }\n\ntype\n  // The condensed compression properties\n  TLZMAPropertyData = array[0..LZMA_PROPS_SIZE - 1] of Byte;\n\n  // The header usually stored in front of LZMA compressed data\n  TLZMAHeader = packed record\n    PropertyData: TLZMAPropertyData;\n    UncompressedSize: Int64;\n  end;\n  PLZMAHeader = ^TLZMAHeader;\n\n\n{ Error handling =========================================================== }\n\ntype\n  EAbLZMAException = class(Exception);\n\nprocedure LzmaCheck(AResultCode: SRes);\nprocedure RaiseLzmaException(AResultCode: SRes);\n\n\n{ Linker directives ======================================================== }\n\n{$WARN BAD_GLOBAL_SYMBOL OFF}\n{$IF DEFINED(WIN32)}\n  {$L Win32\\LzFind.obj}\n  {$L Win32\\LzFindMt.obj}\n  {$L Win32\\LzmaDec.obj}\n  {$L Win32\\LzmaEnc.obj}\n  {$L Win32\\Threads.obj}\n{$ELSEIF DEFINED(WIN64)}\n  {$L Win64\\LzFind.obj}\n  {$L Win64\\LzFindMt.obj}\n  {$L Win64\\LzmaDec.obj}\n  {$L Win64\\LzmaEnc.obj}\n  {$L Win64\\Threads.obj}\n{$IFEND}\n\n\nimplementation\n\n{ Error handling =========================================================== }\n\nprocedure LzmaCheck(AResultCode: SRes);\nbegin\n  if AResultCode <> SZ_OK then\n    RaiseLzmaException(AResultCode);\nend;\n{ -------------------------------------------------------------------------- }\nprocedure RaiseLzmaException(AResultCode: SRes);\nbegin\n  case AResultCode of\n    SZ_ERROR_DATA: raise EAbLZMAException.Create('LZMA Data Error.');\n    SZ_ERROR_MEM: raise EAbLZMAException.Create('LZMA Memory Error.');\n    SZ_ERROR_CRC: raise EAbLZMAException.Create('LZMA CRC Error.');\n    SZ_ERROR_UNSUPPORTED: raise EAbLZMAException.Create('LZMA \"Unsupported\" Error.');\n    SZ_ERROR_PARAM: raise EAbLZMAException.Create('LZMA Parameter Error.');\n    SZ_ERROR_INPUT_EOF: raise EAbLZMAException.Create('LZMA Input EOF Error.');\n    SZ_ERROR_OUTPUT_EOF: raise EAbLZMAException.Create('LZMA Output EOF Error.');\n    SZ_ERROR_READ: raise EAbLZMAException.Create('LZMA Read Error.');\n    SZ_ERROR_WRITE: raise EAbLZMAException.Create('LZMA Write Error.');\n    SZ_ERROR_PROGRESS: raise EAbLZMAException.Create('LZMA Progress Error.');\n    SZ_ERROR_FAIL: raise EAbLZMAException.Create('LZMA \"Fail\" Error.');\n    SZ_ERROR_THREAD: raise EAbLZMAException.Create('LZMA Thread Error.');\n    SZ_ERROR_ARCHIVE: raise EAbLZMAException.Create('LZMA Archive Error.');\n    SZ_ERROR_NO_ARCHIVE: raise EAbLZMAException.Create('LZMA \"No Archive\" Error.');\n  else\n    raise EAbLZMAException.CreateFmt('Unknown LZMA error (%d)', [AResultCode]);\n  end;\nend;\n\n\n{ Helper Routines ========================================================== }\n\nprocedure LzmaDec_Construct(var p: CLzmaDec); cdecl;\nbegin\n  p.dic := nil;\n  p.probs := nil;\nend;\n{ -------------------------------------------------------------------------- }\nfunction SzAlloc(p: Pointer; size: size_t): Pointer; cdecl;\nbegin\n  Result := GetMemory(size);\nend;\n{ -------------------------------------------------------------------------- }\nprocedure SzFree(p, address: Pointer); cdecl;\nbegin\n  FreeMemory(address);\nend;\n\nvar\n  DelphiMMInterface: ISzAlloc = (Alloc: SzAlloc; Free: SzFree);\n\n\n{ CSeq*Stream implementation =============================================== }\n\ntype\n  CSeqInStream = packed record\n    Intf: ISeqInStream;\n    Stream: TStream;\n  end;\n\n  CSeqOutStream = packed record\n    Intf: ISeqOutStream;\n    Stream: TStream;\n  end;\n{ -------------------------------------------------------------------------- }\nfunction ISeqInStream_Read(p: Pointer; var buf; var size: size_t): SRes; cdecl;\nbegin\n  try\n    size := CSeqInStream(p^).Stream.Read(buf, size);\n    Result := SZ_OK;\n  except\n    Result := SZ_ERROR_DATA;\n  end;\nend;\n{ -------------------------------------------------------------------------- }\nfunction ISeqOutStream_Write(p: Pointer; const buf; size: size_t): size_t; cdecl;\nbegin\n  try\n    Result := CSeqOutStream(p^).Stream.Write(buf, size);\n  except\n    Result := 0;\n  end;\nend;\n\n\n{ Raw LZMA decompression =================================================== }\n\n{ Decompress an Lzma compressed stream. Based on LzmaUtil.c::Decode2 }\nfunction LzmaDecode2(var aState: CLzmaDec; aOutStream, aInStream: TStream;\n  aUncompressedSize: Int64 = -1): SRes;\nconst\n  IN_BUF_SIZE = 1 shl 16;\n  OUT_BUF_SIZE = 1 shl 16;\nvar\n  LHasSize: Boolean;\n  LInBuf: array [0..IN_BUF_SIZE - 1] of Byte;\n  LOutBuf: array [0..OUT_BUF_SIZE - 1] of Byte;\n  LInPos, LInSize, LOutPos: size_t;\n  LInProcessed, LOutProcessed: size_t;\n  LFinishMode: ELzmaFinishMode;\n  LStatus: ELzmaStatus;\nbegin\n  Result := 0;\n  LHasSize := aUncompressedSize <> -1;\n  LInPos := 0;\n  LInSize := 0;\n  LOutPos := 0;\n\n  LzmaDec_Init(aState);\n  while True do\n  begin\n    if LInPos = LInSize then\n    begin\n      LInSize := aInStream.Read(LInBuf, IN_BUF_SIZE);\n      LInPos := 0;\n      if LInSize = 0 then\n        Break;\n    end\n    else\n    begin\n      LInProcessed := LInSize - LInPos;\n      LOutProcessed := OUT_BUF_SIZE - LOutPos;\n      LFinishMode := LZMA_FINISH_ANY;\n      if LHasSize and (LOutProcessed > aUncompressedSize) then\n      begin\n        LOutProcessed := size_t(aUncompressedSize);\n        LFinishMode := LZMA_FINISH_END;\n      end;\n      Result := LzmaDec_DecodeToBuf(aState, @LOutBuf[LOutPos], LOutProcessed,\n        @LInBuf[LInPos], LInProcessed, LFinishMode, LStatus);\n      Inc(LInPos, LInProcessed);\n      Inc(LOutPos, LOutProcessed);\n      Dec(aUncompressedSize, LOutProcessed);\n\n      if (aOutStream <> nil) and (aOutStream.Write(LOutBuf, LOutPos) <> LOutPos) then\n      begin\n        Result := SZ_ERROR_WRITE;\n        Exit;\n      end;\n\n      LOutPos := 0;\n\n      if (Result <> SZ_OK) or (LHasSize and (aUncompressedSize = 0)) then\n        Exit;\n\n      if (LInProcessed = 0) and (LOutProcessed = 0) then\n      begin\n        if LHasSize or (LStatus <> LZMA_STATUS_FINISHED_WITH_MARK) then\n          Result := SZ_ERROR_DATA;\n        Exit;\n      end;\n    end;\n  end;\nend;\n{ -------------------------------------------------------------------------- }\n{ Decompress an LZMA compressed stream. Pass AUncompressedSize = -1 if the\n  uncompressed size is not known. }\nprocedure LzmaDecodeStream(AProperties: PByte; APropSize: Integer;\n  ASrc, ADes: TStream; AUncompressedSize: Int64);\nvar\n  LLZMADecState: CLzmaDec;\nbegin\n  LzmaDec_Construct(LLZMADecState);\n  try\n    LzmaCheck(LzmaDec_Allocate(LLZMADecState, AProperties, APropSize, @DelphiMMInterface));\n    LzmaCheck(LzmaDecode2(LLZMADecState, ADes, ASrc, AUncompressedSize));\n  finally\n    LzmaDec_Free(LLZMADecState, @DelphiMMInterface);\n  end;\nend;\n\n\n{ Stream to stream compression and decompression =========================== }\n\n{ Decompresses streams compressed with the LZMA SDK's LzmaUtil.exe.\n  Based on LzmaUtil.c::Decode }\nprocedure LzmaDecodeStream(ASourceStream, ATargetStream: TStream);\nvar\n  LUncompressedSize: Int64;\n  // Header: 5 bytes of LZMA properties and 8 bytes of uncompressed size\n  LHeader: TLZMAHeader;\nbegin\n  // Read and parse header\n  ASourceStream.ReadBuffer(LHeader, SizeOf(LHeader));\n  LUncompressedSize := LHeader.UncompressedSize;\n\n  LzmaDecodeStream(PByte(@LHeader.PropertyData), LZMA_PROPS_SIZE, ASourceStream,\n    ATargetStream, LUncompressedSize);\nend;\n{ -------------------------------------------------------------------------- }\n{ Compresses a stream so it's compatible with the LZMA SDK's LzmaUtil.exe.\n  Based on LzmaUtil.c::Encode }\nprocedure LzmaEncodeStream(ASourceStream, ATargetStream: TStream; ASourceSize: Int64);\nvar\n  LEncHandle: CLzmaEncHandle;\n  LEncProps: CLzmaEncProps;\n  LHeader: TLZMAHeader;\n  LPropDataSize: size_t;\n  LInStreamRec: CSeqInStream;\n  LOutStreamRec: CSeqOutStream;\nbegin\n  LInStreamRec.Intf.Read := ISeqInStream_Read;\n  LInStreamRec.Stream := ASourceStream;\n  LOutStreamRec.Intf.Write := ISeqOutStream_Write;\n  LOutStreamRec.Stream := ATargetStream;\n\n  LEncHandle := LzmaEnc_Create(@DelphiMMInterface);\n  if LEncHandle = nil then\n    LzmaCheck(SZ_ERROR_MEM);\n\n  try\n    LzmaEncProps_Init(LEncProps);\n\n    LzmaCheck(LzmaEnc_SetProps(LEncHandle, LEncProps));\n\n    LPropDataSize := LZMA_PROPS_SIZE;\n\n    LzmaCheck(LzmaEnc_WriteProperties(LEncHandle, PByte(@LHeader.PropertyData),\n      LPropDataSize));\n\n    LHeader.UncompressedSize := ASourceSize;\n\n    ATargetStream.WriteBuffer(LHeader, SizeOf(LHeader));\n\n    LzmaCheck(LzmaEnc_Encode(LEncHandle, @LOutStreamRec.Intf,\n      @LInStreamRec.Intf, nil, @DelphiMMInterface, @DelphiMMInterface));\n\n  finally\n    LzmaEnc_Destroy(LEncHandle, @DelphiMMInterface, @DelphiMMInterface);\n  end;\nend;\n\n\n{ In-memory compression and decompression ================================== }\n\n{ Given a pointer to the compressed data, this will return the size of the\n  decompressed data. }\nfunction LzmaGetUncompressedSize(APCompressedData: Pointer; ACompressedSize: Integer): Integer;\nbegin\n  if ACompressedSize <= SizeOf(TLZMAHeader) then\n    raise EAbLZMAException.Create('The LZMA compressed data is invalid (not enough bytes)');\n\n  Result := PLZMAHeader(APCompressedData).UncompressedSize;\nend;\n{ -------------------------------------------------------------------------- }\n{ Decompresses the LZMA compressed data at APCompressedData to the buffer\n  pointed to by APUncompressedData.  The buffer at APUncompressedData should be\n  large enough to hold the number of bytes as returned by LzGetDecompressedSize. }\nprocedure LzmaDecodeBuffer(APCompressedData: Pointer; ACompressedSize: Integer;\n  APUncompressedData: Pointer);\nvar\n  LPropertyData: TLZMAPropertyData;\n  LUncompressedSize: Int64;\n  LInputByteCount, LOutputByteCount: size_t;\n  LStatus: ELzmaStatus;\nbegin\n  if ACompressedSize <= SizeOf(TLZMAHeader) then\n    raise EAbLZMAException.Create('The LZMA compressed data is invalid (not enough bytes)');\n\n  // Read the header from the compressed data.\n  LPropertyData := PLZMAHeader(APCompressedData).PropertyData;\n  LUncompressedSize := PLZMAHeader(APCompressedData).UncompressedSize;\n  Inc(PAnsiChar(APCompressedData), SizeOf(TLZMAHeader));\n  Dec(ACompressedSize, SizeOf(TLZMAHeader));\n\n  // Decompress from the input to the output buffer. This will change the byte\n  // count variables to the actual number of bytes consumed/written.\n  LInputByteCount := ACompressedSize;\n  LOutputByteCount := LUncompressedSize;\n  LzmaCheck(LzmaDecode(APUncompressedData, LOutputByteCount,\n    APCompressedData, LInputByteCount, PByte(@LPropertyData), LZMA_PROPS_SIZE,\n    LZMA_FINISH_END, LStatus, @DelphiMMInterface));\n\n  // Check that the input buffer was fully consumed and the output buffer was filled up.\n  if (LOutputByteCount <> LUncompressedSize) or (LInputByteCount <> ACompressedSize) then\n    raise EAbLZMAException.Create('LZMA decompression data error');\nend;\n{ -------------------------------------------------------------------------- }\n{ Compresses the data at APUncompressedData to the buffer at APCompressedData,\n  and returns the number of bytes written. If ACompressedDataBufferCapacity is\n  less than the number of bytes required to store the entire compressed stream,\n  or any other error occurs, then an exception is raised. (A safe number for\n  ACompressedDataBufferCapacity is slightly more than AUncompressedDataBufferSize.) \n  Leave ACompressionLevel and ADictionarySize at -1 in order to use the default\n  values (5 and 16MB respectively). }\nfunction LzmaEncodeBuffer(APUncompressedData: Pointer; AUncompressedSize: Integer;\n  APCompressedData: Pointer;\n  ACompressedDataBufferCapacity, ACompressionLevel, ADictionarySize: Integer): Integer;\nvar\n  LEncProps: CLzmaEncProps;\n  LPropsSize: size_t;\n  LPOutBuf: PByte;\n  LOutputBytes: size_t;\nbegin\n  if ACompressedDataBufferCapacity <= SizeOf(TLZMAHeader) then\n    raise EAbLZMAException.Create('LZMA output buffer too small');\n\n  // Set the uncompressed size in the header\n  PLZMAHeader(APCompressedData).UncompressedSize := AUncompressedSize;\n\n  // Set the properties\n  LzmaEncProps_Init(LEncProps);\n  if ACompressionLevel >= 0 then\n    LEncProps.level := ACompressionLevel;\n  if ADictionarySize >= 0 then\n    LEncProps.dictSize := ADictionarySize;\n\n  LPOutBuf := PByte(PtrUInt(APCompressedData) + SizeOf(TLZMAHeader));\n  LOutputBytes := ACompressedDataBufferCapacity - SizeOf(TLZMAHeader);\n  LPropsSize := LZMA_PROPS_SIZE;\n  LzmaCheck(LzmaEncode(LPOutBuf, LOutputBytes, APUncompressedData,\n    AUncompressedSize, LEncProps, APCompressedData, LPropsSize, 0, nil,\n    @DelphiMMInterface, @DelphiMMInterface));\n\n  Result := LOutputBytes + SizeOf(TLZMAHeader);\nend;\n\ninitialization\n  // The LZMA routines are multithreaded and use the Delphi memory manager.\n  IsMultiThread := True;\n\nend.\n"
  },
  {
    "path": "lib/abbrevia/source/AbLZMAStream.pas",
    "content": "(* ***** BEGIN LICENSE BLOCK *****\n  * Version: MPL 1.1\n  *\n  * The contents of this file are subject to the Mozilla Public License Version\n  * 1.1 (the \"License\"); you may not use this file except in compliance with\n  * the License. You may obtain a copy of the License at\n  * http://www.mozilla.org/MPL/\n  *\n  * Software distributed under the License is distributed on an \"AS IS\" basis,\n  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License\n  * for the specific language governing rights and limitations under the\n  * License.\n  *\n  * The Original Code is TurboPower Abbrevia\n  *\n  * The Initial Developer of the Original Code is Pierre le Riche\n  *\n  * Portions created by the Initial Developer are Copyright (C) 2011\n  * the Initial Developer. All Rights Reserved.\n  *\n  * Contributor(s):\n  * Pierre le Riche <pierre_le_riche@users.sourceforge.net>\n  * Craig Peterson <capeterson@users.sourceforge.net>\n  *\n  * ***** END LICENSE BLOCK *****\n\n\nUsage:\n  LZMA Compression:\n  1) Create a TAbLZMACompressionStream, passing as parameter to the constructor\n     the output stream where you want the compressed data stored.\n  2) Write the data that you want to compress to the TAbLZMACompressionStream.\n     Compression occurs in a background thread.\n  3) (Optional) Notify the background compression thread that no more data will\n     be written by calling NoMoreDataToCompress. Poll the IsBusy method to\n     determine whether the background thread is still busy.\n  4) Free the TAbLZMACompressionStream to finish up and release resources. The\n     compressed data will now be available in the output stream.\n\n  LZMA Decompression:\n  1) Create a TAbLZMADecompressionStream, passing as parameter to the constructor\n     the stream that contains the compressed data.\n  2) Read the decompressed data from TAbLZMADecompressionStream.\n  3) Free the TAbLZMADecompressionStream to finish up and release resources.\n\n*)\n\nunit AbLZMAStream;\n\n{$I AbDefine.inc}\n\ninterface\n\nuses\n  Windows, Classes, SysUtils, AbLZMA, AbUtils;\n\nconst\n  {The size of the intermediate buffers for compressed and decompressed data.}\n  CompressedDataBufferSize = 16 * 1024;\n  UncompressedDataBufferSize = 32 * 1024;\n  {When reading/writing very small blocks from/to a (de)compression stream an\n   intermediate buffer is used to buffer the small IO operations in order to\n   improve performance. Reads and writes larger than this size are unbuffered\n   and handled by the (de)compression algorithm directly. This value must be\n   smaller than the compressed and uncompressed data buffers.}\n  MaximumBlockSizeForBufferedIO = 1024;\n\ntype\n\n  {------------LZMA compression stream------------}\n\n  TAbLZMACompressionStream = class;\n\n  {The background compression thread.}\n  TAbLZMACompressionThread = class(TThread)\n  protected\n    FCompressionStream: TAbLZMACompressionStream;\n    {$IFNDEF HasThreadFinished}\n    FFinished: Boolean;\n    procedure DoTerminate; override;\n    property Finished: Boolean read FFinished;\n    {$ENDIF}\n  public\n    procedure Execute; override;\n  end;\n\n  {Buffers queued for compression by the background compression thread.}\n  PAbQueuedBuffer = ^TAbQueuedBuffer;\n  TAbQueuedBuffer = packed record\n    PreviousBuffer, NextBuffer: PAbQueuedBuffer;\n    DataSize: Integer;\n    {Adds this buffer to the compression queue for the given compression stream.\n     It is assumed that the compression stream has acquired the buffer critical\n     section.}\n    procedure QueueBuffer(ACompressionStream: TAbLZMACompressionStream);\n    {Removes this buffer from the compression queue}\n    procedure UnQueueBuffer;\n    {Returns a pointer to the data the given offset into the buffer}\n    function GetDataPointer(AOffset: Integer): Pointer;\n  end;\n\n  TAbLZMACompressionStream = class(TStream)\n  protected\n    FOutputStream: TStream;\n    {The critical section used to control access to the buffers that are queued\n     for compression. The main thread and the compression thread may not access\n     the buffer queue at the same time.}\n    FBufferCriticalSection: TRTLCriticalSection;\n    {This semaphore is signalled by the main thread when it added a workload\n     for the compression thread (usually when a buffer has been added to\n     compress).}\n    FPendingWorkSemaphore: THandle;\n    {The LZMA compression handle}\n    FLZMAEncHandle: CLzmaEncHandle;\n    {The background thread used to perform the compression}\n    FCompressionThread: TAbLZMACompressionThread;\n    {The error code returned by the compression method. 0 = Success.}\n    FCompressionErrorCode: Integer;\n    {The intermediate compression buffer used to aggregate small writes. When\n     NoMoreDataToCompress is called this buffer is freed, so no more data may\n     be written.}\n    FPIntermediateCompressionBuffer: PAbQueuedBuffer;\n    FIntermediateCompressionBufferAvailableBytes: Integer;\n    {The circular linked list of buffers that are queued for compression.}\n    FQueuedData: TAbQueuedBuffer;\n    {The number of bytes of buffer FQueuedData.NextBuffer that has already been\n     submitted to the compressor.}\n    FCurrentBufferBytesSubmitted: Integer;\n    {The position in the output stream where the uncompressed size must be\n     stored.}\n    FOutputStreamHeaderSizeFieldPosition: Int64;\n    {The total number of bytes written to the compression stream}\n    FTotalBytesWritten: Int64;\n    {Wakes up the compression thread by signalling the \"pending work semaphore\"}\n    procedure WakeCompressionThread; inline;\n  public\n    constructor Create(AOutputStream: TStream; ACompressionLevel: Integer = 5;\n      ADictionarySize: Integer = 65536);\n    destructor Destroy; override;\n    {Reading is not supported and will raise an exception.}\n    function Read(var ABuffer; ACount: Longint): Longint; override;\n    {Submits data to the compression queue.}\n    function Write(const ABuffer; ACount: Longint): Longint; override;\n    {Will raise an exception if an attempt is made to seek off the current\n     position.}\n    function Seek(AOffset: Integer; AOrigin: Word): Integer; override;\n    function Seek(const AOffset: Int64; AOrigin: TSeekOrigin): Int64; override;\n    {Signals the compression thread that no more data will be submitted.\n     Calling write after NoMoreDataToCompress has been called will raise an\n     exception.}\n    procedure NoMoreDataToCompress;\n    {Calls NoMoreDataToCompress and then waits for the background compression\n     process to complete, returning the value of ErrorCode (0 = success).}\n    function WaitForCompressionToFinish: Integer;\n    {Returns True if the background thread is still busy compressing data. Will\n     always return True until NoMoreDataToCompress is called.}\n    function IsBusy: Boolean;\n    {-------------Public properties---------------}\n    {The error code returned by the compression method. 0 = Success.}\n    property ErrorCode: Integer read FCompressionErrorCode;\n  end;\n\n  {------------LZMA decompression stream------------}\n\n  TAbLZMADecompressionStream = class(TStream)\n  protected\n    FSourceStream: TStream;\n    {The intermediate buffers for compressed and uncompressed data\n     respectively.}\n    FCompressedDataBuffer: array[0..CompressedDataBufferSize - 1] of Byte;\n    FUncompressedDataBuffer: array[0..UncompressedDataBufferSize - 1] of Byte;\n    {Read buffer control: Used to speed up frequent small reads via\n     FUncompressedDataBuffer.}\n    FReadBufferSize: Integer;\n    FReadBufferAvailableBytes: Integer;\n    {The current size and position into FCompressedDataBuffer}\n    FCompressedDataBufferSize: Integer;\n    FCompressedDataBufferPosition: Integer;\n    {The uncompressed size according to the header.}\n    FUncompressedSize: Int64;\n    {The total number of bytes that have been decompressed.}\n    FBytesDecompressed: Int64;\n    {The LZMA decompression state}\n    FLzmaState: CLzmaDec;\n    {Decompresses data from the compressed source to the buffer pointed to by\n     APBuffer. Returns the number of actual bytes stored (which may be less\n     than the requested size if the end of the compressed stream was reached).}\n    function InternalDecompressToBuffer(APBuffer: Pointer; ABufferSize: Integer): Integer;\n    {---Property getters/setters---}\n    function GetBytesRead: Int64;\n    function GetSize: Int64; override;\n  public\n    constructor Create(ASourceStream: TStream);\n    destructor Destroy; override;\n    function Read(var ABuffer; ACount: Integer): Integer; override;\n    {Writing to a decompression stream is not allowed}\n    function Write(const ABuffer; ACount: Integer): Integer; override;\n    {Will raise an exception if an attempt is made to seek off the current\n     position.}\n    function Seek(AOffset: Integer; AOrigin: Word): Integer; override;\n    function Seek(const AOffset: Int64; AOrigin: TSeekOrigin): Int64; override;\n    {---Public properties---}\n    {The number of decompressed bytes read from the decompression stream.}\n    property BytesRead: Int64 read GetBytesRead;\n  end;\n\nimplementation\n\nuses\n  AbCrtl;\n\n{------------Memory management-------------}\n\nfunction SzAlloc(p: Pointer; size: size_t): Pointer; cdecl;\nbegin\n  Result := GetMemory(size);\nend;\n\nprocedure SzFree(p, address: Pointer); cdecl;\nbegin\n  FreeMemory(address);\nend;\n\nvar\n  DelphiMMInterface: ISzAlloc = (Alloc: SzAlloc; Free: SzFree);\n\n{------------Compression \"interface\"-------------}\n\ntype\n\n  {The \"interfaces\" for the input and output streams}\n  CSeqInStream_Compress = packed record\n    Intf: ISeqInStream;\n    CompressionStream: TAbLZMACompressionStream;\n  end;\n\n  CSeqOutStream_Compress = packed record\n    Intf: ISeqOutStream;\n    OutputStream: TStream;\n  end;\n\nfunction ISeqInStream_Compress_Read(p: Pointer; var buf; var size: size_t): SRes; cdecl;\nvar\n  LDoNotWaitForMoreData: Boolean;\n  LStream: TAbLZMACompressionStream;\n  LPSourceBuf, LPTargetBuf: PAnsiChar;\n  LTargetSpace, LSourceBytesAvail: Integer;\n  LPCurBuf: PAbQueuedBuffer;\nbegin\n  try\n    LTargetSpace := size;\n    LPTargetBuf := @buf;\n    LStream := CSeqInStream_Compress(p^).CompressionStream;\n    while True do\n    begin\n      {Copy any buffered data to the LZMA buffer, returning the number of bytes\n       written}\n      EnterCriticalSection(LStream.FBufferCriticalSection);\n      try\n        {If the write buffer has been freed that the main thread will not add\n         any more buffers for compression.}\n        LDoNotWaitForMoreData := LStream.FPIntermediateCompressionBuffer = nil;\n\n        {Copy as much queued data to the LZMA compression buffer as we have (or\n         will fit).}\n        while True do\n        begin\n          LPCurBuf := LStream.FQueuedData.NextBuffer;\n          {No buffers left? -> Break the loop}\n          if LPCurBuf = @LStream.FQueuedData then\n            Break;\n          {Can this buffer be submitted in its entirety, or only a part?}\n          LPSourceBuf := LPCurBuf.GetDataPointer(LStream.FCurrentBufferBytesSubmitted);\n          LSourceBytesAvail := LPCurBuf.DataSize - LStream.FCurrentBufferBytesSubmitted;\n          if LSourceBytesAvail > LTargetSpace then\n          begin\n            {Submit only part of the buffer}\n            System.Move(LPSourceBuf^, LPTargetBuf^, LTargetSpace);\n            Inc(LStream.FCurrentBufferBytesSubmitted, LTargetSpace);\n            LTargetSpace := 0;\n            Break;\n          end\n          else\n          begin\n            {Submit all the remaining bytes in the buffer and free it.}\n            System.Move(LPSourceBuf^, LPTargetBuf^, LSourceBytesAvail);\n            Inc(LPTargetBuf, LSourceBytesAvail);\n            Dec(LTargetSpace, LSourceBytesAvail);\n            LStream.FCurrentBufferBytesSubmitted := 0;\n            LPCurBuf.UnQueueBuffer;\n            FreeMem(LPCurBuf);\n          end;\n        end;\n      finally\n        LeaveCriticalSection(LStream.FBufferCriticalSection);\n      end;\n\n      {If data was submitted to the compressor, or the main thread indicated\n       that compression is complete then the loop is broken.}\n      if (LTargetSpace <> size) or LDoNotWaitForMoreData then\n        Break;\n      {No data currently queued, but there may still be more coming: Wait for\n       the main thread to notify this thread that more work is pending.}\n      WaitForSingleObject(LStream.FPendingWorkSemaphore, INFINITE);\n    end;\n    {Update the number of bytes written}\n    Dec(size, LTargetSpace);\n    Result := SZ_OK;\n  except\n    Result := SZ_ERROR_DATA;\n  end;\nend;\n\nfunction ISeqOutStream_Compress_Write(p: Pointer; const buf; size: size_t): size_t; cdecl;\nbegin\n  try\n    Result := CSeqOutStream_Compress(p^).OutputStream.Write(buf, size);\n  except\n    Result := 0;\n  end;\nend;\n\n{ TAbQueuedBuffer }\n\nfunction TAbQueuedBuffer.GetDataPointer(AOffset: Integer): Pointer;\nbegin\n  Result := Pointer(PtrUInt(@Self) + SizeOf(TAbQueuedBuffer) + PtrUInt(AOffset));\nend;\n\nprocedure TAbQueuedBuffer.QueueBuffer(ACompressionStream: TAbLZMACompressionStream);\nbegin\n  PreviousBuffer:= ACompressionStream.FQueuedData.PreviousBuffer;\n  NextBuffer:= @ACompressionStream.FQueuedData;\n  ACompressionStream.FQueuedData.PreviousBuffer.NextBuffer := @Self;\n  ACompressionStream.FQueuedData.PreviousBuffer := @Self;\nend;\n\nprocedure TAbQueuedBuffer.UnQueueBuffer;\nbegin\n  PreviousBuffer.NextBuffer := NextBuffer;\n  NextBuffer.PreviousBuffer := PreviousBuffer;\n  PreviousBuffer := nil;\n  NextBuffer := nil;\nend;\n\n{ TAbLZMACompressionStream }\n\nconstructor TAbLZMACompressionStream.Create(AOutputStream: TStream; ACompressionLevel,\n  ADictionarySize: Integer);\nvar\n  LLZMAProps: CLzmaEncProps;\n  LLZMAPropData: TLZMAPropertyData;\n  LHeaderSize: size_t;\nbegin\n  inherited Create;\n\n  FOutputStream := AOutputStream;\n\n  {Initialize the linked list of buffers.}\n  FQueuedData.PreviousBuffer := @FQueuedData;\n  FQueuedData.NextBuffer := @FQueuedData;\n\n  {Allocate the intermediate compression buffer}\n  GetMem(FPIntermediateCompressionBuffer, UncompressedDataBufferSize + SizeOf(TAbQueuedBuffer));\n  FIntermediateCompressionBufferAvailableBytes := UncompressedDataBufferSize;\n\n  {Initialize the critical section used to control access to the queued data\n   buffer.}\n  InitializeCriticalSection(FBufferCriticalSection);\n  {Create the semaphore used to put the worker thread to sleep when the input\n   buffer is empty.}\n  FPendingWorkSemaphore := CreateSemaphore(nil, 0, 1, nil);\n\n  {Create the LZMA encoder}\n  FLZMAEncHandle := LzmaEnc_Create(@DelphiMMInterface);\n  if FLZMAEncHandle = nil then\n    raise Exception.Create('Unable to allocate memory for the LZMA compressor.');\n\n  {Set the compression properties}\n  LzmaEncProps_Init(LLZMAProps);\n  LLZMAProps.level := ACompressionLevel;\n  LLZMAProps.dictSize := ADictionarySize;\n  LzmaCheck(LzmaEnc_SetProps(FLZMAEncHandle, LLZMAProps));\n\n  {Store the header in the output stream, making note of the position in the\n   stream where the uncompressed size will be stored when compression is\n   completed.}\n  LHeaderSize := LZMA_PROPS_SIZE;\n  LzmaCheck(LzmaEnc_WriteProperties(FLZMAEncHandle, PByte(@LLZMAPropData), LHeaderSize));\n  FOutputStream.WriteBuffer(LLZMAPropData, LHeaderSize);\n  FOutputStreamHeaderSizeFieldPosition := FOutputStream.Position;\n  FOutputStream.WriteBuffer(FTotalBytesWritten, SizeOf(FTotalBytesWritten));\n\n  {Create and start the compression thread.}\n  FCompressionThread := TAbLZMACompressionThread.Create(True);\n  FCompressionThread.FCompressionStream := Self;\n  {$IFDEF HasThreadStart}\n  FCompressionThread.Start;\n  {$ELSE}\n  FCompressionThread.Resume;\n  {$ENDIF}\nend;\n\ndestructor TAbLZMACompressionStream.Destroy;\nvar\n  LPBuf: PAbQueuedBuffer;\n  LOldPos: Int64;\nbegin\n  WaitForCompressionToFinish;\n\n  {If something went wrong during creation of this object before the thread was\n   created, then the encoder handle may be non-nil.}\n  if FLZMAEncHandle <> nil then\n  begin\n    LzmaEnc_Destroy(FLZMAEncHandle, @DelphiMMInterface, @DelphiMMInterface);\n    FLZMAEncHandle := nil;\n  end;\n\n  {Free the critical section and semaphore}\n  DeleteCriticalSection(FBufferCriticalSection);\n  CloseHandle(FPendingWorkSemaphore);\n\n  {Free the intermediate compression buffer if something went wrong before the\n   thread could be created.}\n  FreeMem(FPIntermediateCompressionBuffer);\n\n  {If compression failed there may be uncompressed data in the queue: free\n   those buffers.}\n  while True do\n  begin\n    LPBuf := FQueuedData.NextBuffer;\n    if LPBuf = @FQueuedData then\n      Break;\n    LPBuf.UnQueueBuffer;\n    FreeMem(LPBuf);\n  end;\n\n  {Unpdate the uncompressed size in the header}\n  if FTotalBytesWritten > 0 then\n  begin\n    LOldPos := FOutputStream.Position;\n    FOutputStream.Position := FOutputStreamHeaderSizeFieldPosition;\n    FOutputStream.WriteBuffer(FTotalBytesWritten, SizeOf(FTotalBytesWritten));\n    FOutputStream.Position := LOldPos;\n  end;\n\n  inherited Destroy;\nend;\n\nfunction TAbLZMACompressionStream.IsBusy: Boolean;\nbegin\n  Result := (FCompressionThread <> nil) and (not FCompressionThread.Finished);\nend;\n\nprocedure TAbLZMACompressionStream.NoMoreDataToCompress;\nvar\n  LUnqueuedBytes: Integer;\nbegin\n  if FPIntermediateCompressionBuffer <> nil then\n  begin\n    EnterCriticalSection(FBufferCriticalSection);\n    try\n      {No more data may be submitted at this point. Set the flag to indicate\n       this, and wake the compression thread so that it can finish up.}\n      LUnqueuedBytes := UncompressedDataBufferSize - FIntermediateCompressionBufferAvailableBytes;\n      if LUnqueuedBytes > 0 then\n      begin\n        FPIntermediateCompressionBuffer.DataSize := LUnqueuedBytes;\n        FPIntermediateCompressionBuffer.QueueBuffer(Self);\n      end\n      else\n        FreeMem(FPIntermediateCompressionBuffer);\n      {The temporary buffer is always released, so no further writes may be\n       performed.}\n      FPIntermediateCompressionBuffer := nil;\n    finally\n      LeaveCriticalSection(FBufferCriticalSection);\n    end;\n    {Wake up the compression thread so it can finish the compression process.}\n    WakeCompressionThread;\n  end;\nend;\n\nfunction TAbLZMACompressionStream.Read(var ABuffer; ACount: Integer): Longint;\nbegin\n  raise Exception.Create('The compression stream does not support reading.');\nend;\n\nfunction TAbLZMACompressionStream.Seek(const AOffset: Int64;\n  AOrigin: TSeekOrigin): Int64;\nbegin\n  Result := FTotalBytesWritten;\n  if ((AOrigin <> soBeginning) or (AOffset <> Result))\n    and ((AOrigin = soBeginning) or (AOffset <> 0)) then\n  begin\n    raise Exception.Create('The compression stream does not support seeking away from the current position.');\n  end;\nend;\n\nfunction TAbLZMACompressionStream.Seek(AOffset: Integer; AOrigin: Word): Integer;\nbegin\n  Result := Seek(Int64(AOffset), TSeekOrigin(AOrigin));\nend;\n\nfunction TAbLZMACompressionStream.WaitForCompressionToFinish: Integer;\nbegin\n  if FCompressionThread <> nil then\n  begin\n    {Notify the thread that no further data will be submitted.}\n    NoMoreDataToCompress;\n    {Wait for the compression thread to complete normally and then free it.}\n    FCompressionThread.WaitFor;\n    FreeAndNil(FCompressionThread);\n  end;\n  Result := FCompressionErrorCode;\nend;\n\nprocedure TAbLZMACompressionStream.WakeCompressionThread;\nbegin\n  ReleaseSemaphore(FPendingWorkSemaphore, 1, nil);\nend;\n\nfunction TAbLZMACompressionStream.Write(const ABuffer; ACount: Integer): Longint;\nvar\n  LPSource: PAnsiChar;\n  LPBufData: Pointer;\n  LPLargeBuf: PAbQueuedBuffer;\nbegin\n  if FPIntermediateCompressionBuffer = nil then\n    raise Exception.Create('Write may not be called after NoMoreDataToCompress.');\n\n  if ACount <= 0 then\n  begin\n    Result := 0;\n    Exit;\n  end;\n\n  LPSource := @ABuffer;\n  {Get a pointer to the position in the intermediate buffer to be written.}\n  LPBufData := FPIntermediateCompressionBuffer.GetDataPointer(\n    UncompressedDataBufferSize - FIntermediateCompressionBufferAvailableBytes);\n  if FIntermediateCompressionBufferAvailableBytes > ACount then\n  begin\n    {Copy the data into the intermediate buffer and exit.}\n    System.Move(LPSource^, LPBufData^, ACount);\n    Dec(FIntermediateCompressionBufferAvailableBytes, ACount);\n    Result := ACount;\n  end\n  else\n  begin\n    {Fill up the intermediate buffer}\n    System.Move(LPSource^, LPBufData^, FIntermediateCompressionBufferAvailableBytes);\n    Dec(ACount, FIntermediateCompressionBufferAvailableBytes);\n    Inc(LPSource, FIntermediateCompressionBufferAvailableBytes);\n    Result := FIntermediateCompressionBufferAvailableBytes;\n    {If we get here the current intermediate buffer is now full, and must be\n     queued.}\n    EnterCriticalSection(FBufferCriticalSection);\n    try\n      {Insert this buffer into the compression queue.}\n      FPIntermediateCompressionBuffer.DataSize := UncompressedDataBufferSize;\n      FPIntermediateCompressionBuffer.QueueBuffer(Self);\n      {Allocate a new intermediate compression buffer}\n      GetMem(FPIntermediateCompressionBuffer, UncompressedDataBufferSize + SizeOf(TAbQueuedBuffer));\n      FIntermediateCompressionBufferAvailableBytes := UncompressedDataBufferSize;\n      {Should the remaining data be copied into the intermediate compression\n       buffer, or is it too large and must it be queued separately?}\n      if ACount < UncompressedDataBufferSize then\n      begin\n        LPBufData := FPIntermediateCompressionBuffer.GetDataPointer(0);\n        System.Move(LPSource^, LPBufData^, ACount);\n        Dec(FIntermediateCompressionBufferAvailableBytes, ACount);\n      end\n      else\n      begin\n        {The remaining data is larger than the intermediate buffer: queue it\n         separately}\n        GetMem(LPLargeBuf, ACount + SizeOf(TAbQueuedBuffer));\n        LPLargeBuf.DataSize := ACount;\n        LPLargeBuf.QueueBuffer(Self);\n        {Copy the data across}\n        LPBufData := LPLargeBuf.GetDataPointer(0);\n        System.Move(LPSource^, LPBufData^, ACount);\n      end;\n      {Update the number of bytes written}\n      Inc(Result, ACount);\n    finally\n      LeaveCriticalSection(FBufferCriticalSection);\n    end;\n    {Wake up the compression thread to compress the newly queued data}\n    WakeCompressionThread;\n  end;\n\n  Inc(FTotalBytesWritten, Result);\nend;\n\n{ TAbLZMACompressionThread }\n\n{$IFNDEF HasThreadFinished}\nprocedure TAbLZMACompressionThread.DoTerminate;\nbegin\n  inherited DoTerminate;\n  FFinished := True;\nend;\n{$ENDIF}\n\nprocedure TAbLZMACompressionThread.Execute;\nvar\n  LInStreamRec: CSeqInStream_Compress;\n  LOutStreamRec: CSeqOutStream_Compress;\nbegin\n  {Call the compression function and save the error code}\n  LInStreamRec.Intf.Read := ISeqInStream_Compress_Read;\n  LInStreamRec.CompressionStream := FCompressionStream;\n  LOutStreamRec.Intf.Write := ISeqOutStream_Compress_Write;\n  LOutStreamRec.OutputStream := FCompressionStream.FOutputStream;\n  FCompressionStream.FCompressionErrorCode := LzmaEnc_Encode(FCompressionStream.FLZMAEncHandle,\n    @LOutStreamRec.Intf, @LInStreamRec.Intf, nil, @DelphiMMInterface, @DelphiMMInterface);\n  {Free the compression handle}\n  LzmaEnc_Destroy(FCompressionStream.FLZMAEncHandle, @DelphiMMInterface, @DelphiMMInterface);\n  FCompressionStream.FLZMAEncHandle := nil;\nend;\n\n{ TAbLZMADecompressionStream }\n\nconstructor TAbLZMADecompressionStream.Create(ASourceStream: TStream);\nvar\n  LLZMAPropData: TLZMAPropertyData;\nbegin\n  inherited Create;\n\n  FSourceStream := ASourceStream;\n\n  {Read the header and uncompressed size from the compressed data stream.}\n  FSourceStream.ReadBuffer(LLZMAPropData, LZMA_PROPS_SIZE);\n  FSourceStream.ReadBuffer(FUncompressedSize, SizeOf(FUncompressedSize));\n\n  {Initialize the decompressor using the information from the header}\n  LzmaDec_Construct(FLzmaState);\n  LzmaCheck(LzmaDec_Allocate(FLzmaState, PByte(@LLZMAPropData), LZMA_PROPS_SIZE,\n    @DelphiMMInterface));\n  LzmaDec_Init(FLzmaState);\nend;\n\ndestructor TAbLZMADecompressionStream.Destroy;\nvar\n  LUnusedBytes: Integer;\nbegin\n  {Release all decompression resources.}\n  LzmaDec_Free(FLzmaState, @DelphiMMInterface);\n\n  {Any unconsumed bytes in the compressed input buffer should be returned to\n   the source stream.}\n  LUnusedBytes := FCompressedDataBufferSize - FCompressedDataBufferPosition;\n  if LUnusedBytes > 0 then\n    FSourceStream.Position := FSourceStream.Position - LUnusedBytes;\n\n  inherited Destroy;\nend;\n\nfunction TAbLZMADecompressionStream.GetBytesRead: Int64;\nbegin\n  Result := FBytesDecompressed - FReadBufferAvailableBytes;\nend;\n\nfunction TAbLZMADecompressionStream.GetSize: Int64;\nbegin\n  Result := FUncompressedSize;\nend;\n\nfunction TAbLZMADecompressionStream.InternalDecompressToBuffer(APBuffer: Pointer;\n  ABufferSize: Integer): Integer;\nvar\n  LInputBytesProcessed, LOutputBytesProcessed: size_t;\n  LFinishMode: Integer;\n  LStatus: ELzmaStatus;\nbegin\n  Result := 0;\n  {Any more data to decompress to the output buffer?}\n  while ABufferSize > 0 do\n  begin\n    {Read more compressed data into the compressed data buffer, if required.}\n    if FCompressedDataBufferPosition >= FCompressedDataBufferSize then\n    begin\n      FCompressedDataBufferSize := FSourceStream.Read(FCompressedDataBuffer,\n        CompressedDataBufferSize);\n      FCompressedDataBufferPosition := 0;\n    end;\n\n    {Initialize the \"processed byte count\" variables to the sizes of the input\n     and output buffers.}\n    LInputBytesProcessed := FCompressedDataBufferSize - FCompressedDataBufferPosition;\n    LOutputBytesProcessed := ABufferSize;\n    {We may not read more bytes than the number of uncompressed bytes according\n     to the header.}\n    if (FUncompressedSize - FBytesDecompressed) <= LOutputBytesProcessed then\n    begin\n      LOutputBytesProcessed := FUncompressedSize - FBytesDecompressed;\n      LFinishMode := LZMA_FINISH_END;\n    end\n    else\n      LFinishMode := LZMA_FINISH_ANY;\n\n    {Decompress from the input to the output buffer}\n    LzmaCheck(LzmaDec_DecodeToBuf(FLzmaState, APBuffer,\n      LOutputBytesProcessed, @FCompressedDataBuffer[FCompressedDataBufferPosition],\n      LInputBytesProcessed, LFinishMode, LStatus));\n\n    {Update the input and output buffer stats}\n    Inc(FCompressedDataBufferPosition, LInputBytesProcessed);\n    Inc(PAnsiChar(APBuffer), LOutputBytesProcessed);\n    Dec(ABufferSize, LOutputBytesProcessed);\n\n    {Update the number of bytes decompressed}\n    Inc(Result, LOutputBytesProcessed);\n    Inc(FBytesDecompressed, LOutputBytesProcessed);\n\n    {Was all the data decompressed? If so, break the loop.}\n    if FUncompressedSize = FBytesDecompressed then\n      Break;\n\n    {Was nothing from the input or output streams processed? If so, then\n     something has gone wrong.}\n    if (LInputBytesProcessed = 0) and (LOutputBytesProcessed = 0) then\n      raise Exception.Create('LZMA decompression data error');\n\n  end;\nend;\n\nfunction TAbLZMADecompressionStream.Read(var ABuffer; ACount: Integer): Integer;\nvar\n  LBytesAlreadyRead: Integer;\nbegin\n  {Anything to read?}\n  if ACount > 0 then\n  begin\n    {Do we have enough data in the read buffer to satisfy the request?}\n    if FReadBufferAvailableBytes >= ACount then\n    begin\n      {Enough data in the buffer: Fill the output buffer.}\n      System.Move(PAnsiChar(@FUncompressedDataBuffer)[FReadBufferSize - FReadBufferAvailableBytes],\n        ABuffer, ACount);\n      {Subtract from the available bytes in the read buffer.}\n      Dec(FReadBufferAvailableBytes, ACount);\n      {Successfully read the number of bytes requested}\n      Result := ACount;\n    end\n    else\n    begin\n      {Not enough bytes available in the read buffer: Is there anything\n       available in the uncompressed data buffer? If so, then transfer what we\n       have.}\n      if FReadBufferAvailableBytes > 0 then\n      begin\n        {There is some data in the buffer: Read everything}\n        System.Move(PAnsiChar(@FUncompressedDataBuffer)[FReadBufferSize - FReadBufferAvailableBytes],\n          ABuffer, FReadBufferAvailableBytes);\n        LBytesAlreadyRead := FReadBufferAvailableBytes;\n        FReadBufferAvailableBytes := 0;\n      end\n      else\n        LBytesAlreadyRead := 0;\n      {If we get here it means the read buffer has been emptied and some data\n       still has to be read: Do we need to fill up the read buffer again, or do\n       we read directly into the target buffer? Large reads bypass the read\n       buffering mechanism.}\n      if ACount <= MaximumBlockSizeForBufferedIO then\n      begin\n        {Try to fill the read buffer again}\n        FReadBufferSize := InternalDecompressToBuffer(@FUncompressedDataBuffer, UncompressedDataBufferSize);\n        FReadBufferAvailableBytes := FReadBufferSize;\n        {No more data available? If so we're done.}\n        if FReadBufferAvailableBytes = 0 then begin\n          Result := LBytesAlreadyRead;\n          Exit;\n        end;\n        {Is enough data now available?}\n        if FReadBufferAvailableBytes >= (ACount - LBytesAlreadyRead) then\n        begin\n          {Enough data in the buffer: Fill the output buffer.}\n          System.Move(FUncompressedDataBuffer,\n            PAnsiChar(@ABuffer)[LBytesAlreadyRead],\n            ACount - LBytesAlreadyRead);\n          {Subtract from the available bytes in the read buffer and return the\n           number of bytes read.}\n          Dec(FReadBufferAvailableBytes, ACount - LBytesAlreadyRead);\n          {Successfully read the number of bytes requested}\n          Result := ACount;\n        end\n        else\n        begin\n          {Enough data is still not available (the end of the compressed stream\n           has been reached): Read what we can.}\n          System.Move(FUncompressedDataBuffer,\n            PAnsiChar(@ABuffer)[LBytesAlreadyRead],\n            FReadBufferAvailableBytes);\n          Inc(LBytesAlreadyRead, FReadBufferAvailableBytes);\n          FReadBufferAvailableBytes := 0;\n          Result := LBytesAlreadyRead;\n        end;\n      end\n      else\n      begin\n        {Decompress directly into the output buffer.}\n        Result := InternalDecompressToBuffer(\n          @PAnsiChar(@ABuffer)[LBytesAlreadyRead],\n          ACount - LBytesAlreadyRead) + LBytesAlreadyRead;\n      end;\n    end;\n  end\n  else\n    Result := 0;\nend;\n\nfunction TAbLZMADecompressionStream.Seek(const AOffset: Int64; AOrigin: TSeekOrigin): Int64;\nbegin\n  Result := GetBytesRead;\n  if ((AOrigin <> soBeginning) or (AOffset <> Result))\n    and ((AOrigin <> soCurrent) or (AOffset <> 0)) then\n  begin\n    raise Exception.Create('Decompression streams do not support seeking away '\n      + 'from the current position.');\n  end;\nend;\n\nfunction TAbLZMADecompressionStream.Seek(AOffset: Integer; AOrigin: Word): Integer;\nbegin\n  Result := Seek(Int64(AOffset), TSeekOrigin(AOrigin));\nend;\n\nfunction TAbLZMADecompressionStream.Write(const ABuffer; ACount: Integer): Integer;\nbegin\n  raise Exception.Create('Writing to a LZMA decompression stream is not supported.');\nend;\n\nend.\n"
  },
  {
    "path": "lib/abbrevia/source/AbMeter.pas",
    "content": "(* ***** BEGIN LICENSE BLOCK *****\n * Version: MPL 1.1\n *\n * The contents of this file are subject to the Mozilla Public License Version\n * 1.1 (the \"License\"); you may not use this file except in compliance with\n * the License. You may obtain a copy of the License at\n * http://www.mozilla.org/MPL/\n *\n * Software distributed under the License is distributed on an \"AS IS\" basis,\n * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License\n * for the specific language governing rights and limitations under the\n * License.\n *\n * The Original Code is TurboPower Abbrevia\n *\n * The Initial Developer of the Original Code is\n * TurboPower Software\n *\n * Portions created by the Initial Developer are Copyright (C) 1997-2002\n * the Initial Developer. All Rights Reserved.\n *\n * Contributor(s):\n *\n * ***** END LICENSE BLOCK ***** *)\n\n{*********************************************************}\n{* ABBREVIA: AbMeter.pas                                 *}\n{*********************************************************}\n{* ABBREVIA: Progress meter                              *}\n{*   Use AbQMeter.pas for CLX                            *}\n{*********************************************************}\n\n{$IFNDEF UsingCLX}\nunit AbMeter;\n{$ENDIF}\n\n{$I AbDefine.inc}\n\ninterface\n\nuses\n  Classes,\n  {$IFDEF MSWINDOWS}\n  Windows,\n  {$ENDIF}\n  {$IFDEF LibcAPI}\n  Libc,\n  {$ENDIF}\n  {$IFDEF UsingCLX }\n  QControls, QGraphics, QForms, QExtCtrls,\n  {$ELSE}\n  Controls, Graphics, Forms, ExtCtrls,\n  {$ENDIF}\n  AbBrowse;\n\ntype\n  TAbMeterOrientation = (moHorizontal, moVertical);\n\n  TAbCustomMeter = class(TGraphicControl, IAbProgressMeter)\n  {.Z+}\n  protected {private}\n    {property variables}\n    FBorderStyle   : TBorderStyle;\n    FCtl3D         : Boolean;\n    FOrientation   : TAbMeterOrientation;\n    FPercent       : Integer;\n  \tFTickMarks     : Byte;\n    FUsedColor     : TColor;\n    FUnusedColor   : TColor;\n\n    {internal methods}\n    function  GetVersion : string;\n    procedure Paint;\n      override;\n    procedure SetBorderStyle(const Value : TBorderStyle);\n    procedure SetCtl3D(const Value : Boolean);\n    procedure SetOrientation(const O : TAbMeterOrientation);\n    procedure SetTickMarks(const Value: Byte);\n    procedure SetUnusedColor(const C : TColor);\n    procedure SetUsedColor(const C : TColor);\n    procedure SetVersion(Value : string);\n    property Version : string\n      read  GetVersion write SetVersion stored False;\n\n  {.Z-}\n  public {methods}\n    constructor Create(AOwner : TComponent);\n      override;\n    procedure DoProgress(Progress : Byte);\n    procedure Reset;\n\n  public {properties}\n    property BorderStyle : TBorderStyle\n      read FBorderStyle write SetBorderStyle default bsSingle;\n    property Ctl3D : Boolean\n      read FCtl3D write SetCtl3D default True;\n    property Orientation : TAbMeterOrientation\n      read FOrientation write SetOrientation;\n    property TickMarks: Byte\n\t\t  read FTickMarks write SetTickMarks default 10;\n    property UnusedColor : TColor\n      read FUnusedColor write SetUnusedColor;\n    property UsedColor : TColor\n      read FUsedColor write SetUsedColor;\n  end;\n\n  TAbMeter = class(TAbCustomMeter)\n  published\n    property Anchors;\n    property Constraints;\n    property Align;\n    property BorderStyle;\n    property Ctl3D;\n    property Font;\n    property OnClick;\n    property OnDblClick;\n    property OnMouseDown;\n    property OnMouseMove;\n    property OnMouseUp;\n    property Orientation;\n    property ParentFont;\n    property ParentShowHint;\n    property ShowHint;\n    property TickMarks;\n    property UnusedColor;\n    property UsedColor;\n    property Version;\n    property Visible;\n  end;\n  {.Z+}\n\n\nimplementation\n\nuses\n  Types, AbConst;\n\n{ == TAbCustomMeter ======================================================== }\nconstructor TAbCustomMeter.Create(AOwner : TComponent);\nbegin\n  inherited Create(AOwner);\n  {$IFNDEF UsingCLX}\n  if NewStyleControls then\n    ControlStyle := ControlStyle + [csOpaque]\n  else\n    ControlStyle := ControlStyle + [csOpaque, csFramed];\n  {$ELSE}\n    ControlStyle := ControlStyle + [csOpaque, csFramed];\n  {$ENDIF}\n\n  FBorderStyle := bsSingle;\n  FCtl3D       := True;\n  FOrientation := moHorizontal;\n  FTickMarks   := 10;\n  FUnusedColor := clBtnFace;\n  FUsedColor   := clNavy;\n  Width        := 150;\n  Height       := 16;\nend;\n{ -------------------------------------------------------------------------- }\nfunction TAbCustomMeter.GetVersion : string;\nbegin\n  Result := AbVersionS;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbCustomMeter.DoProgress(Progress : Byte);\nbegin\n  if (Progress <> FPercent) then begin\n    FPercent := Progress;\n    if (FPercent >= 100) then\n      FPercent := 0;\n    Refresh;\n    Application.ProcessMessages;\n  end;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbCustomMeter.Paint;\nconst\n  VSpace = 2;\n  HSpace = 1;\n  LSpace = 1;\n  RSpace = 1;\nvar\n  ClRect, R  : TRect;\n  ClWidth    : Integer;\n  ClHeight   : Integer;\n  BlockWidth : Integer;\n  BlockCount : Integer;\n  i : Integer;\nbegin\n  ClRect := ClientRect;\n\n  ClWidth := ClRect.Right - CLRect.Left + 1;\n  ClHeight := ClRect.Bottom - ClRect.Top + 1;\n\n  if (Orientation = moHorizontal) then\n    BlockWidth := ((ClWidth - LSpace - RSpace - (9 * VSpace)) div FTickMarks) + 1\n  else\n    BlockWidth := ((ClHeight - LSpace - RSpace - (9 * HSpace)) div FTickMarks) + 1;\n  BlockCount  := FPercent div FTickMarks;\n\n  if not Assigned((Canvas as TControlCanvas).Control) then begin\n    TControlCanvas(Canvas).Control := self;\n  end;\n  with Canvas do begin\n    Brush.Color := FUnusedColor;\n    FillRect(Rect(ClRect.Left, ClRect.Top, ClRect.Left + ClWidth - 1,\n      ClRect.Top + ClHeight - 1));\n    Brush.Color := FUsedColor;\n    if (BlockCount > 0) then begin\n      if (Orientation = moHorizontal) then begin\n        R.Top := ClRect.Top + HSpace;\n        R.Bottom := ClRect.Bottom - HSpace;\n        for i := 0 to Pred(BlockCount) do begin\n          R.Left := ClRect.Left + LSpace + (i * VSpace) +\n            (i * BlockWidth);\n          R.Right := R.Left + BlockWidth;\n          FillRect(R);\n        end;\n      end else begin {moVertical}\n        R.Left := ClRect.Left + VSpace;\n        R.Right := ClRect.Right - VSpace;\n        for i := 0 to Pred(BlockCount) do begin\n          R.Bottom := ClRect.Bottom - LSpace - (i * HSpace) -\n            (i * BlockWidth);\n          R.Top := R.Bottom - BlockWidth;\n          FillRect(R);\n        end;\n      end;\n    end;\n  end;\n  {$IFNDEF LCL}\n  if (BorderStyle <> bsNone) then begin\n    if Ctl3D then\n      Frame3D(Canvas, ClRect, clBtnShadow, clBtnHighlight, 1)\n    else\n      Frame3D(Canvas, ClRect, clBlack, clBlack, 1);\n  end;\n  {$ENDIF}\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbCustomMeter.Reset;\nbegin\n  DoProgress(0);\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbCustomMeter.SetBorderStyle(const Value : TBorderStyle);\nbegin\n  if (Value <> FBorderStyle) then begin\n    FBorderStyle := Value;\n    Invalidate;\n  end;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbCustomMeter.SetCtl3D(const Value : Boolean);\nbegin\n  if (Value <> FCtl3D) then begin\n    FCtl3D := Value;\n    Invalidate;\n  end;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbCustomMeter.SetOrientation(const O : TAbMeterOrientation);\nvar\n  Temp : Integer;\nbegin\n  if (O <> FOrientation) then begin\n    FOrientation := O;\n    if not (csLoading in ComponentState) then begin\n      Temp := Width;\n      Width := Height;\n      Height := Temp;\n    end;\n    Invalidate;\n  end;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbCustomMeter.SetTickMarks(const Value: Byte);\nbegin\n\tif Value <= 0 then\n\t  FTickMarks := 10\n\telse\n\t  FTickMarks := Value;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbCustomMeter.SetUnusedColor(const C : TColor);\nbegin\n  if (C <> FUnusedColor) then begin\n    FUnusedColor := C;\n    Invalidate;\n  end;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbCustomMeter.SetUsedColor(const C : TColor);\nbegin\n  if (C <> FUsedColor) then begin\n    FUsedColor := C;\n    Invalidate;\n  end;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbCustomMeter.SetVersion(Value : string);\nbegin\n  {NOP}\nend;\n\nend.\n"
  },
  {
    "path": "lib/abbrevia/source/AbPPMd.pas",
    "content": "(* ***** BEGIN LICENSE BLOCK *****\n * Version: MPL 1.1\n *\n * The contents of this file are subject to the Mozilla Public License Version\n * 1.1 (the \"License\"); you may not use this file except in compliance with\n * the License. You may obtain a copy of the License at\n * http://www.mozilla.org/MPL/\n *\n * Software distributed under the License is distributed on an \"AS IS\" basis,\n * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License\n * for the specific language governing rights and limitations under the\n * License.\n *\n * The Original Code is TurboPower Abbrevia\n *\n * The Initial Developer of the Original Code is Craig Peterson\n *\n * Portions created by the Initial Developer are Copyright (C) 2011\n * the Initial Developer. All Rights Reserved.\n *\n * Contributor(s):\n * Craig Peterson <capeterson@users.sourceforge.net>\n *\n * ***** END LICENSE BLOCK ***** *)\n\n{*********************************************************}\n{* ABBREVIA: AbPPMd.pas                                  *}\n{*********************************************************}\n{* ABBREVIA: PPMd decompression                          *}\n{*********************************************************}\n\nunit AbPPMd;\n\n{$I AbDefine.inc}\n\ninterface\n\nuses\n  Classes;\n\nprocedure DecompressPPMd(aSrc, aDes: TStream);\n\nimplementation\n\nuses\n  AbCrtl,\n  SysUtils,\n  AbExcept;\n\n\n// Compiled with:\n//   Release: bcc32 -q -c *.c\n//   Debug:   bcc32 -q -c -v -y *.c\n\n\n{ Linker derectives ======================================================== }\n\n// Don't re-order these;  it will cause linker errors\n{$IF DEFINED(WIN32)}\n  {$L Win32\\PPMdVariantI.obj}\n  {$L Win32\\PPMdContext.obj}\n  {$L Win32\\PPMdSubAllocatorVariantI.obj}\n  {$L Win32\\CarrylessRangeCoder.obj}\n{$ELSEIF DEFINED(WIN64)}\n  {$L Win64\\PPMdVariantI.obj}\n  {$L Win64\\PPMdContext.obj}\n  {$L Win64\\PPMdSubAllocatorVariantI.obj}\n  {$L Win64\\CarrylessRangeCoder.obj}\n{$IFEND}\n\n\n{ CarrylessRangeCoder.h ==================================================== }\n\ntype\n  PInStream = ^TInStream;\n  TInStream = record\n\t  nextByte: function(Self: PInStream): Byte; cdecl;\n    // Private data\n    stream: TStream;\n    InPos: Integer;\n    InCount: Integer;\n    InBuf: array[0..4097] of Byte;\n  end;\n{ -------------------------------------------------------------------------- }\nfunction TInStream_NextByte(Self: PInStream): Byte; cdecl;\nbegin\n  if Self.InPos = Self.InCount then begin\n    Self.InCount := Self.stream.Read(Self.InBuf, SizeOf(Self.InBuf));\n    if Self.InCount = 0 then\n      raise EAbReadError.Create;\n    Self.InPos := 0;\n  end;\n  Result := Self.InBuf[Self.InPos];\n  Inc(Self.InPos);\nend;\n{ -------------------------------------------------------------------------- }\nfunction TInStream_Create(aStream: TStream): PInStream;\nbegin\n  GetMem(Result, SizeOf(TInStream));\n  Result.nextByte := TInStream_NextByte;\n  Result.stream := aStream;\n  Result.InPos := 0;\n  Result.InCount := 0;\nend;\n\n\n{ PPMdVariantI.h =========================================================== }\n\ntype\n  PPMdModelVariantI = Pointer;\n\nfunction CreatePPMdModelVariantI(const input: TInStream;\n  suballocsize, maxorder, restoration: Integer): PPMdModelVariantI; cdecl; external;\nprocedure FreePPMdModelVariantI(Self: PPMdModelVariantI); cdecl; external;\n\nfunction NextPPMdVariantIByte(Self: PPMdModelVariantI): Integer; cdecl; external;\n\n\n{ Decompression routines =================================================== }\n\nprocedure DecompressPPMd(aSrc, aDes: TStream);\nconst\n  OutBufSize = 4096;\nvar\n  nextByte: Integer;\n  params: word;\n  ppmd: PPMdModelVariantI;\n  Src: PInStream;\n  OutBuf: PByteArray;\n  OutPos: Integer;\nbegin\n  Src := TInStream_Create(aSrc);\n  try\n    GetMem(OutBuf, OutBufSize);\n    try\n      OutPos := 0;\n\n      ASrc.ReadBuffer(Params, SizeOf(Params));// Pkzip stream header\n      ppmd := CreatePPMdModelVariantI(Src^,\n        (((Params shr 4) and $FF) + 1) shl 20,// sub-allocator size\n        (Params and $0F) + 1,                 // model order\n        Params shr 12);                       // model restoration method\n      try\n          while True do begin\n            nextByte := NextPPMdVariantIByte(ppmd);\n            if nextByte < 0 then Break;\n            OutBuf[OutPos] := Byte(nextByte);\n            Inc(OutPos);\n            if OutPos = OutBufSize then begin\n              aDes.WriteBuffer(OutBuf^, OutBufSize);\n              OutPos := 0;\n            end;\n          end;\n          if OutPos > 0 then\n            aDes.WriteBuffer(OutBuf^, OutPos);\n      finally\n        FreePPMdModelVariantI(ppmd);\n      end;\n    finally\n      FreeMem(OutBuf);\n    end;\n  finally\n    FreeMem(Src);\n  end;\nend;\n\nend.\n"
  },
  {
    "path": "lib/abbrevia/source/AbPeCol.pas",
    "content": "(* ***** BEGIN LICENSE BLOCK *****\n * Version: MPL 1.1\n *\n * The contents of this file are subject to the Mozilla Public License Version\n * 1.1 (the \"License\"); you may not use this file except in compliance with\n * the License. You may obtain a copy of the License at\n * http://www.mozilla.org/MPL/\n *\n * Software distributed under the License is distributed on an \"AS IS\" basis,\n * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License\n * for the specific language governing rights and limitations under the\n * License.\n *\n * The Original Code is TurboPower Abbrevia\n *\n * The Initial Developer of the Original Code is\n * TurboPower Software\n *\n * Portions created by the Initial Developer are Copyright (C) 1997-2002\n * the Initial Developer. All Rights Reserved.\n *\n * Contributor(s):\n *\n * ***** END LICENSE BLOCK ***** *)\n\n{*********************************************************}\n{* ABBREVIA: AbPeCol.pas                                 *}\n{*********************************************************}\n{* ABBREVIA: Property Editor - ZipView column headings   *}\n{*   Use AbQPeCol.pas for CLX                            *}\n{*********************************************************}\n\n{$IFNDEF UsingCLX}\nunit AbPeCol;\n{$ENDIF}\n\n{$I AbDefine.inc}\n\ninterface\n\nuses\n{$IFDEF MSWINDOWS}\n  Windows,\n{$ENDIF}\n{$IFDEF UsingClx}\n  QGraphics,\n  QForms,\n  QControls,\n  QStdCtrls,\n  QButtons,\n  QExtCtrls,\n  AbQView,\n  AbBseCLX,\n{$ELSE}\n  Graphics,\n  Forms,\n  Controls,\n  StdCtrls,\n  Buttons,\n  ExtCtrls,\n  AbView,\n  AbBseVcl,\n{$ENDIF}\n  DesignIntf,\n  DesignEditors,\n  AbConst,\n  SysUtils,\n  Classes;\n\ntype\n  TAbColHeadingsEditor = class(TForm)\n    Panel1: TPanel;\n    Label1: TLabel;\n    Attribute1: TComboBox;\n    Done1: TBitBtn;\n    Apply1: TBitBtn;\n    Label2: TLabel;\n    Heading1: TEdit;\n    Button1: TButton;\n    procedure FormShow(Sender: TObject);\n    procedure Attribute1Click(Sender: TObject);\n    procedure Apply1Click(Sender: TObject);\n    procedure Heading1Exit(Sender: TObject);\n  private\n    { Private declarations }\n  public\n    Viewer : TAbBaseViewer;\n\n  end;\n\n  TAbColHeadingsProperty = class(TClassProperty)\n  public\n    procedure Edit; override;\n    function GetAttributes: TPropertyAttributes; override;\n  end;\n\n\nvar\n  AbColHeadingsEditor: TAbColHeadingsEditor;\n\nimplementation\n\nuses\n  AbResString;\n\n{$IFNDEF UsingCLX}\n{$R *.dfm}\n{$ENDIF}\n\ntype\n  TAbViewerFriend = class(TAbBaseViewer);\n\n\n{===TAbColHeadingsProperty==========================================}\nprocedure TAbColHeadingsProperty.Edit;\nvar\n  hEditor : TAbColHeadingsEditor;\nbegin\n  hEditor := TAbColHeadingsEditor.Create(Application);\n  try\n    hEditor.Viewer := TAbViewerFriend(GetComponent(0));\n    hEditor.ShowModal;\n    Designer.Modified;\n  finally\n    hEditor.Free;\n  end;\nend;\n{ -------------------------------------------------------------------------- }\nfunction TAbColHeadingsProperty.GetAttributes: TPropertyAttributes;\n  begin\n    Result := inherited GetAttributes + [paDialog, paAutoUpdate];\n  end;\n\n\n{===TAbColHeadingsEditor============================================}\n\nprocedure TAbColHeadingsEditor.FormShow(Sender: TObject);\nconst\n  cResString: array[TAbViewAttribute] of string = (AbItemNameHeadingS,\n    AbPackedHeadingS, AbMethodHeadingS, AbRatioHeadingS, AbCRCHeadingS,\n    AbFileAttrHeadingS, AbFileFormatHeadingS, AbEncryptionHeadingS,\n    AbTimeStampHeadingS, AbFileSizeHeadingS, AbVersionMadeHeadingS,\n    AbVersionNeededHeadingS, AbPathHeadingS);\nvar\n  i : TAbViewAttribute;\nbegin\n  with Attribute1 do begin\n    Clear;\n    for i := Low(TAbViewAttribute) to High(TAbViewAttribute) do\n      Items.Add(cResString[i]);\n\n    ItemIndex := 0;\n  end;\n  Attribute1Click(nil);\nend;\n\nprocedure TAbColHeadingsEditor.Attribute1Click(Sender: TObject);\nbegin\n  if (Attribute1.ItemIndex > -1) then\n    Heading1.Text := TAbViewerFriend(Viewer).Headings[Attribute1.ItemIndex];\nend;\n\nprocedure TAbColHeadingsEditor.Apply1Click(Sender: TObject);\nbegin\n  if (Attribute1.ItemIndex > -1) then begin\n    TAbViewerFriend(Viewer).Headings[Attribute1.ItemIndex] := Heading1.Text;\n    TAbViewerFriend(Viewer).InvalidateRow(0);\n  end;\nend;\n\nprocedure TAbColHeadingsEditor.Heading1Exit(Sender: TObject);\nbegin\n  Apply1Click(nil);\nend;\n\nend.\n\n"
  },
  {
    "path": "lib/abbrevia/source/AbPeDir.pas",
    "content": "(* ***** BEGIN LICENSE BLOCK *****\n * Version: MPL 1.1\n *\n * The contents of this file are subject to the Mozilla Public License Version\n * 1.1 (the \"License\"); you may not use this file except in compliance with\n * the License. You may obtain a copy of the License at\n * http://www.mozilla.org/MPL/\n *\n * Software distributed under the License is distributed on an \"AS IS\" basis,\n * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License\n * for the specific language governing rights and limitations under the\n * License.\n *\n * The Original Code is TurboPower Abbrevia\n *\n * The Initial Developer of the Original Code is\n * TurboPower Software\n *\n * Portions created by the Initial Developer are Copyright (C) 1997-2002\n * the Initial Developer. All Rights Reserved.\n *\n * Contributor(s):\n *\n * ***** END LICENSE BLOCK ***** *)\n\n{*********************************************************}\n{* ABBREVIA: AbPeDir.pas                                 *}\n{*********************************************************}\n{* ABBREVIA: Property Editor - Directory                 *}\n{*   Use AbQPeDir.pas for CLX                            *}\n{*********************************************************}\n\n{$IFNDEF UsingCLX}\nunit AbPeDir;\n{$ENDIF}\n\n{$I AbDefine.inc}\n\ninterface\n\nuses\n{$IFDEF MSWINDOWS}\n  Windows,\n{$ENDIF}\n{$IFDEF UsingClx}\n  QGraphics,\n  QForms,\n  QControls,\n  QStdCtrls,\n  QButtons,\n  QExtCtrls,\n{$ELSE}\n  Graphics,\n  Forms,\n  Controls,\n  StdCtrls,\n  Buttons,\n  ExtCtrls,\n{$ENDIF}\n  DesignIntf,\n  DesignEditors,\n  SysUtils,\n  Classes;\n\ntype\n  TAbDirectoryProperty = class( TStringProperty )\n  public\n    function GetAttributes: TPropertyAttributes;\n             override;\n    procedure Edit;\n              override;\n  end;\n\nimplementation\n\nuses\n{$IFDEF UsingClx}\n  AbQDgDir;\n{$ELSE}\n  AbDlgDir;\n{$ENDIF}\n\n\nfunction TAbDirectoryProperty.GetAttributes: TPropertyAttributes;\nbegin\n  Result := [paDialog];\nend;\n\n{$IFDEF MSWINDOWS}\nprocedure TAbDirectoryProperty.Edit;\nvar\n  D : TAbDirDlg;\nbegin\n  D := TAbDirDlg.Create(Application);\n  try\n    D.Caption := 'Directory';\n    D.AdditionalText := 'Select Directory';\n    if D.Execute then\n      Value := D.SelectedFolder;\n  finally\n    D.Free;\n  end;\nend;\n{$ELSE}\nprocedure TAbDirectoryProperty.Edit;\nvar\n  D : TDirDlg;\nbegin\n  D := TDirDlg.Create(Application);\n  try\n{$IFDEF MSWINDOWS}\n    D.DirectoryListBox1.Directory := Value;\n{$ENDIF}\n    D.ShowModal;\n    if D.ModalResult = mrOK then\n      Value := D.SelectedFolder;\n  finally\n    D.Free;\n  end;\nend;\n{$ENDIF}\n\nend.\n"
  },
  {
    "path": "lib/abbrevia/source/AbPeFn.pas",
    "content": "(* ***** BEGIN LICENSE BLOCK *****\n * Version: MPL 1.1\n *\n * The contents of this file are subject to the Mozilla Public License Version\n * 1.1 (the \"License\"); you may not use this file except in compliance with\n * the License. You may obtain a copy of the License at\n * http://www.mozilla.org/MPL/\n *\n * Software distributed under the License is distributed on an \"AS IS\" basis,\n * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License\n * for the specific language governing rights and limitations under the\n * License.\n *\n * The Original Code is TurboPower Abbrevia\n *\n * The Initial Developer of the Original Code is\n * TurboPower Software\n *\n * Portions created by the Initial Developer are Copyright (C) 1997-2002\n * the Initial Developer. All Rights Reserved.\n *\n * Contributor(s):\n *\n * ***** END LICENSE BLOCK ***** *)\n\n{*********************************************************}\n{* ABBREVIA: AbPeFn.pas                                  *}\n{*********************************************************}\n{* ABBREVIA: Property Editor - FileName                  *}\n{*   Use AbQPeFn.pas for CLX                             *}\n{*********************************************************}\n\n{$IFNDEF UsingCLX}\nunit AbPeFn;\n{$ENDIF}\n\n{$I AbDefine.inc}\n\ninterface\n\nuses\n{$IFDEF UsingClx }\n  QDialogs, QForms,\n{$ELSE}\n  Dialogs, Forms,\n{$ENDIF}\n  DesignIntf,\n  DesignEditors,\n  SysUtils;\n\n\ntype\n  TAbFileNameProperty = class(TStringProperty)\n  public\n    function GetAttributes: TPropertyAttributes;\n      override;\n    procedure Edit;\n      override;\n  end;\n\n  TAbExeNameProperty = class(TStringProperty)\n  public\n    function GetAttributes: TPropertyAttributes;\n      override;\n    procedure Edit;\n      override;\n  end;\n\n  TAbCabNameProperty = class( TStringProperty )\n  public\n    function GetAttributes: TPropertyAttributes;\n      override;\n    procedure Edit;\n      override;\n  end;\n\n  TAbLogNameProperty = class( TStringProperty )\n  public\n    function GetAttributes: TPropertyAttributes;\n      override;\n    procedure Edit;\n      override;\n  end;\n\nimplementation\n\nuses\n  AbResString,\n  AbArcTyp;\n\n{ -------------------------------------------------------------------------- }\nprocedure AbGetFilename(const Ext : string;\n                        const Filter : string;\n                        const Title : string;\n                          var aFilename : string);\nvar\n  D : TOpenDialog;\nbegin\n  D := TOpenDialog.Create( Application );\n  try\n    D.DefaultExt := Ext;\n    D.Filter := Filter;\n    D.FilterIndex := 0;\n    D.Options := [];\n    D.Title := Title;\n    D.FileName := aFilename;\n    if D.Execute then\n      aFilename := D.FileName;\n  finally\n    D.Free;\n  end;\nend;\n\n{ == for zip files ========================================================= }\nfunction TAbFileNameProperty.GetAttributes: TPropertyAttributes;\nbegin\n  Result := [paDialog];\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbFileNameProperty.Edit;\nvar\n  FN : string;\nbegin\n  FN := Value;\n  AbGetFilename(AbDefaultExtS, AbFilterS, AbFileNameTitleS, FN);\n  Value := FN;\nend;\n\n{ == for exe files ========================================================= }\nfunction TAbExeNameProperty.GetAttributes: TPropertyAttributes;\nbegin\n  Result := [paDialog];\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbExeNameProperty.Edit;\nvar\n  FN : string;\nbegin\n  FN := Value;\n  AbGetFilename(AbExeExtS, AbExeFilterS, AbFileNameTitleS, FN);\n  Value := FN;\nend;\n\n{ == for cab files ========================================================= }\nfunction TAbCabNameProperty.GetAttributes: TPropertyAttributes;\nbegin\n  Result := [paDialog];\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbCabNameProperty.Edit;\nvar\n  FN : string;\nbegin\n  FN := Value;\n  AbGetFilename(AbCabExtS, AbCabFilterS, AbFileNameTitleS, FN);\n  Value := FN;\nend;\n\n{ == for log files ========================================================= }\nfunction TAbLogNameProperty.GetAttributes: TPropertyAttributes;\nbegin\n  Result := [paDialog];\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbLogNameProperty.Edit;\nvar\n  FN : string;\nbegin\n  FN := Value;\n  AbGetFilename(AbLogExtS, AbLogFilterS, AbFileNameTitleS, FN);\n  Value := FN;\nend;\n{ -------------------------------------------------------------------------- }\n\nend.\n\n"
  },
  {
    "path": "lib/abbrevia/source/AbPePass.pas",
    "content": "(* ***** BEGIN LICENSE BLOCK *****\n * Version: MPL 1.1\n *\n * The contents of this file are subject to the Mozilla Public License Version\n * 1.1 (the \"License\"); you may not use this file except in compliance with\n * the License. You may obtain a copy of the License at\n * http://www.mozilla.org/MPL/\n *\n * Software distributed under the License is distributed on an \"AS IS\" basis,\n * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License\n * for the specific language governing rights and limitations under the\n * License.\n *\n * The Original Code is TurboPower Abbrevia\n *\n * The Initial Developer of the Original Code is\n * TurboPower Software\n *\n * Portions created by the Initial Developer are Copyright (C) 1997-2002\n * the Initial Developer. All Rights Reserved.\n *\n * Contributor(s):\n *\n * ***** END LICENSE BLOCK ***** *)\n\n{*********************************************************}\n{* ABBREVIA: AbPePass.pas                                *}\n{*********************************************************}\n{* ABBREVIA: Password property editor                    *}\n{*   Use AbQPePas.pas for CLX                            *}\n{*********************************************************}\n\n{$IFNDEF UsingCLX}\nunit AbPePass;\n{$ENDIF}\n\n{$I AbDefine.inc}\n\ninterface\n\nuses\n{$IFDEF MSWINDOWS}\n  Windows,\n{$ENDIF}\n{$IFDEF UsingClx}\n  QGraphics,\n  QForms,\n  QControls,\n  QStdCtrls,\n  QButtons,\n  QExtCtrls,\n{$ELSE}\n  Graphics,\n  Forms,\n  Controls,\n  StdCtrls,\n  Buttons,\n  ExtCtrls,\n{$ENDIF}\n  DesignIntf,\n  DesignEditors,\n  SysUtils,\n  Classes;\n\ntype\n  TAbPasswordProperty = class( TStringProperty )\n  public\n    function GetAttributes: TPropertyAttributes;\n             override;\n    procedure Edit;\n              override;\n  end;\n\nimplementation\n\nuses\n{$IFDEF UsingClx}\n  AbQDgPwd;\n{$ELSE}\n  AbDlgPwd;\n{$ENDIF}\n\nfunction TAbPasswordProperty.GetAttributes: TPropertyAttributes;\nbegin\n  Result := [paDialog];\nend;\n\nprocedure TAbPasswordProperty.Edit;\nvar\n  D : TPasswordDlg;\nbegin\n  D := TPasswordDlg.Create( Application );\n  try\n    D.Edit1.Text := Value;\n    D.ShowModal;\n    if D.ModalResult = mrOK then\n      Value := D.Edit1.Text;\n  finally\n    D.Free;\n  end;\nend;\n\nend.\n"
  },
  {
    "path": "lib/abbrevia/source/AbPeVer.pas",
    "content": "(* ***** BEGIN LICENSE BLOCK *****\n * Version: MPL 1.1\n *\n * The contents of this file are subject to the Mozilla Public License Version\n * 1.1 (the \"License\"); you may not use this file except in compliance with\n * the License. You may obtain a copy of the License at\n * http://www.mozilla.org/MPL/\n *\n * Software distributed under the License is distributed on an \"AS IS\" basis,\n * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License\n * for the specific language governing rights and limitations under the\n * License.\n *\n * The Original Code is TurboPower Abbrevia\n *\n * The Initial Developer of the Original Code is\n * TurboPower Software\n *\n * Portions created by the Initial Developer are Copyright (C) 1997-2002\n * the Initial Developer. All Rights Reserved.\n *\n * Contributor(s):\n *\n * ***** END LICENSE BLOCK ***** *)\n\n{*********************************************************}\n{* ABBREVIA: AbPeVer.pas                                 *}\n{*********************************************************}\n{* ABBREVIA: Property Editor - Version                   *}\n{*   Use AbQPeVer.pas for CLX                            *}\n{*********************************************************}\n\n{$IFNDEF UsingCLX}\nunit AbPeVer;\n{$ENDIF}\n\n{$I AbDefine.inc}\n\ninterface\n\nuses\n{$IFDEF MSWINDOWS}\n  Windows,\n  ShellAPI,\n{$ENDIF}\n{$IFDEF LibcAPI}\n  Libc,\n{$ENDIF}\n{$IFDEF UsingClx}\n  QGraphics,\n  QForms,\n  QControls,\n  QStdCtrls,\n  QButtons,\n  QExtCtrls,\n  QDialogs,\n{$ELSE}\n  Graphics,\n  Forms,\n  Controls,\n  StdCtrls,\n  Buttons,\n  ExtCtrls,\n  Dialogs,\n{$ENDIF}\n  DesignIntf,\n  DesignEditors,\n  SysUtils,\n  Classes;\n\ntype\n  TAbAboutBox = class(TForm)\n    lblVersion: TLabel;\n    Panel1: TPanel;\n    Image1: TImage;\n    btnOK: TButton;\n    Panel2: TPanel;\n    WebLbl: TLabel;\n    NewsLbl: TLabel;\n    Bevel1: TBevel;\n    Label1: TLabel;\n    Label2: TLabel;\n    Label3: TLabel;\n    Label5: TLabel;\n    Label6: TLabel;\n    Label7: TLabel;\n    Label10: TLabel;\n    Label11: TLabel;\n    procedure FormCreate(Sender: TObject);\n    procedure btnOKClick(Sender: TObject);\n    procedure WebLblClick(Sender: TObject);\n    procedure WebLblMouseMove(Sender: TObject; Shift: TShiftState; X,\n      Y: Integer);\n    procedure NewsLblClick(Sender: TObject);\n    procedure NewsLblMouseMove(Sender: TObject; Shift: TShiftState; X,\n      Y: Integer);\n    procedure Panel2MouseMove(Sender: TObject; Shift: TShiftState; X,\n      Y: Integer);\n    procedure FormMouseMove(Sender: TObject; Shift: TShiftState; X,\n      Y: Integer);\n  private\n    { Private declarations }\n  public\n    { Public declarations }\n  end;\n\n\n  TAbVersionProperty = class( TStringProperty )\n  public\n    function GetAttributes: TPropertyAttributes;\n             override;\n    procedure Edit;\n              override;\n  end;\n\nvar\n  AbAboutBox : TAbAboutBox;\n\nimplementation\n\n{$IFNDEF UsingCLX}\n{$R *.dfm}\n{$ENDIF}\n\nuses\n  AbArcTyp,\n  AbConst,\n  AbResString;\n\n{$IFDEF LINUX}\nconst\n  { String Constants }\n  sCannotStartBrowser = 'Unable to start web browser. Make sure you have it properly set-up on your system.';\n\nconst\n  MaxBrowsers = 1;\n\ntype\n  ECannotStartBrowser = class(Exception);\n\ntype\n  TBrowserStartCmd = record\n    Command    : string [64];\n    Parameters : string [255];\n    XTerm      : Boolean; { Start browser in an XTerm }\n  end;\n\nconst\n  { The list of browsers we can launch. }\n\n  BrowserList : array [1..MaxBrowsers] of TBrowserStartCmd =\n    ((Command : 'netscape'; Parameters : '<site>'; Xterm : False));\n\n\nprocedure GetCurrentPath (PathList : TStringList);\nvar\n  WorkPath : PChar;\n  StartPos : PChar;\n  CurrentPath : PChar;\n  State : (Scanning, GotColon);\nbegin\n  WorkPath := getenv ('PATH');\n\n  PathList.Clear;\n\n  StartPos := WorkPath;\n  State := Scanning;\n  while (WorkPath^ <> #0) do begin\n    case State of\n      Scanning :\n        begin\n          if (WorkPath^ = ':') then begin\n            State := GotColon;\n            if (WorkPath <> StartPos) then begin\n              CurrentPath := StrAlloc(WorkPath - StartPos + 1);\n              StrLCopy(CurrentPath, StartPos, WorkPath-StartPos);\n              PathList.Add (CurrentPath);\n              StrDispose(CurrentPath);\n            end;\n          end;\n        end;\n      GotColon :\n        begin\n          if (WorkPath^ <> ':') then begin\n            StartPos := WorkPath;\n            State := Scanning;\n          end;\n        end;\n    end;{case}\n    inc(WorkPath);\n  end;\n  if (State = Scanning) and (WorkPath <> StartPos) then begin\n    CurrentPath := StrAlloc(WorkPath - StartPos + 1);\n    StrLCopy(CurrentPath, StartPos, WorkPath-StartPos);\n    PathList.Add (CurrentPath);\n    StrDispose(CurrentPath);\n  end;\nend;\n\n\nfunction IsBrowserPresent (PathList : TStringList;\n                                        Browser : string) : Boolean;\nvar\n  i : integer;\nbegin\n  Result := False;\n  for i := 0 to PathList.Count - 1 do begin\n    if FileExists (PathList[i] + '/' + Browser) then begin\n      Result := True;\n      exit;\n    end;\n  end;\nend;\n\nprocedure CallBrowser (Browser    : string;\n                                      Parameters : string;\n                                      Website    : string;\n                                      XTerm      : Boolean);\nbegin\n  if Pos ('<site>', Parameters) > 0 then begin\n    Parameters := Copy (Parameters, 1, Pos ('<site>', Parameters) - 1) +\n                        Website +\n                        Copy (Parameters, Pos ('<site>', Parameters) + 6, 255);\n  end else\n    Parameters := Parameters + ' ' + Website;\n  if XTerm then begin\n    Parameters := '-e ' + Browser + ' ' + Parameters;\n    Browser := 'xterm';\n  end;\n  Libc.system (PChar (Browser + ' ' + Parameters + ' &'));\nend;\n\nprocedure StartBrowser (Website : string);\n\nvar\n  PathList : TStringList;\n  i : integer;\n\nbegin\n  PathList := TStringList.Create;\n  try\n    GetCurrentPath (PathList);\n    for i := 1 to MaxBrowsers do begin\n      if IsBrowserPresent (PathList, BrowserList[i].Command) then begin\n        CallBrowser (BrowserList[i].Command, BrowserList[i].Parameters,\n                     Website, BrowserList[i].XTerm);\n        exit;\n      end;\n    end;\n    raise ECannotStartBrowser.Create(sCannotStartBrowser);\n  finally\n    PathList.Free;\n  end;\nend;\n{$ENDIF}\n\n\nprocedure TAbAboutBox.FormCreate(Sender: TObject);\nbegin\n  Top := (Screen.Height - Height ) div 3;\n  Left := (Screen.Width - Width ) div 2;\n  lblVersion.Caption := Format(AbVersionFormatS, [AbVersionS] );\nend;\n\nfunction TAbVersionProperty.GetAttributes: TPropertyAttributes;\nbegin\n  Result := [paDialog, paReadOnly];\nend;\n\nprocedure TAbVersionProperty.Edit;\nbegin\n  with TAbAboutBox.Create( Application ) do\n    try\n      ShowModal;\n    finally\n      Free;\n    end;\nend;\n\nprocedure TAbAboutBox.btnOKClick(Sender: TObject);\nbegin\n  Close;\nend;\n\nprocedure TAbAboutBox.WebLblClick(Sender: TObject);\nbegin\n{$IFDEF MSWINDOWS }\n  if ShellExecute(0, 'open', 'http://www.sourceforge.net/projects/tpabbrevia', '', '',\n    SW_SHOWNORMAL) <= 32 then\n    ShowMessage('Unable to start web browser');\n{$ENDIF MSWINDOWS }\n{$IFDEF LINUX }\n  try\n    StartBrowser('http://www.sourceforge.net/projects/tpabbrevia');\n  except\n    on ECannotStartBrowser do\n      ShowMessage('Unable to start web browser');\n  end;\n{$ENDIF LINUX }\n  WebLbl.Font.Color := clNavy;\nend;\n\nprocedure TAbAboutBox.WebLblMouseMove(Sender: TObject; Shift: TShiftState;\n  X, Y: Integer);\nbegin\n  WebLbl.Font.Color := clRed;\nend;\n\nprocedure TAbAboutBox.NewsLblClick(Sender: TObject);\nbegin\n{$IFDEF MSWINDOWS }\n  if ShellExecute(0, 'open', 'http://www.sourceforge.net/forum/forum.php?forum_id=241865', '', '',\n    SW_SHOWNORMAL) <= 32 then\n    ShowMessage('Unable to start web browser');\n{$ENDIF MSWINDOWS }\n{$IFDEF LINUX }\n  try\n    StartBrowser('http://www.sourceforge.net/forum/forum.php?forum_id=241865');\n  except\n    on ECannotStartBrowser do\n      ShowMessage('Unable to start web browser');\n  end;\n{$ENDIF LINUX }\n  NewsLbl.Font.Color := clNavy;\nend;\n\nprocedure TAbAboutBox.NewsLblMouseMove(Sender: TObject; Shift: TShiftState;\n  X, Y: Integer);\nbegin\n  NewsLbl.Font.Color := clRed;\nend;\n\nprocedure TAbAboutBox.Panel2MouseMove(Sender: TObject; Shift: TShiftState;\n  X, Y: Integer);\nbegin\n  NewsLbl.Font.Color := clNavy;\nend;\n\nprocedure TAbAboutBox.FormMouseMove(Sender: TObject; Shift: TShiftState; X,\n  Y: Integer);\nbegin\n  WebLbl.Font.Color := clNavy;\n  NewsLbl.Font.Color := clNavy;\nend;\n\nend.\n\n"
  },
  {
    "path": "lib/abbrevia/source/AbQCView.pas",
    "content": "(* ***** BEGIN LICENSE BLOCK *****\n * Version: MPL 1.1\n *\n * The contents of this file are subject to the Mozilla Public License Version\n * 1.1 (the \"License\"); you may not use this file except in compliance with\n * the License. You may obtain a copy of the License at\n * http://www.mozilla.org/MPL/\n *\n * Software distributed under the License is distributed on an \"AS IS\" basis,\n * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License\n * for the specific language governing rights and limitations under the\n * License.\n *\n * The Original Code is TurboPower Abbrevia\n *\n * The Initial Developer of the Original Code is\n * TurboPower Software\n *\n * Portions created by the Initial Developer are Copyright (C) 1997-2002\n * the Initial Developer. All Rights Reserved.\n *\n * Contributor(s):\n *\n * ***** END LICENSE BLOCK ***** *)\n\n{*********************************************************}\n{* ABBREVIA: AbQCView.pas                                *}\n{*********************************************************}\n{* ABBREVIA: Cabinet archive viewer component (CLX)      *}\n{*   Use AbCView.pas for VCL                             *}\n{*********************************************************}\n\nUnit AbQCView;\n\n{$DEFINE UsingCLX}\n\n{$I AbCView.pas}\n\n\n"
  },
  {
    "path": "lib/abbrevia/source/AbQCmpnd.pas",
    "content": "(* ***** BEGIN LICENSE BLOCK *****\n * Version: MPL 1.1\n *\n * The contents of this file are subject to the Mozilla Public License Version\n * 1.1 (the \"License\"); you may not use this file except in compliance with\n * the License. You may obtain a copy of the License at\n * http://www.mozilla.org/MPL/\n *\n * Software distributed under the License is distributed on an \"AS IS\" basis,\n * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License\n * for the specific language governing rights and limitations under the\n * License.\n *\n * The Original Code is TurboPower Abbrevia\n *\n * The Initial Developer of the Original Code is\n * TurboPower Software\n *\n * Portions created by the Initial Developer are Copyright (C) 1997-2002\n * the Initial Developer. All Rights Reserved.\n *\n * Contributor(s):\n *\n * ***** END LICENSE BLOCK ***** *)\n\n{*********************************************************}\n{* ABBREVIA: AbQCmpnd.pas                                *}\n{*********************************************************}\n{* ABBREVIA: Compound File classes and component (CLX)   *}\n{*   Use AbCompnd.pas for VCL                            *}\n{*********************************************************}\n\nunit AbQCmpnd;\n\n{$DEFINE UsingCLX}\n\n{$I AbCompnd.pas}\n\n\n"
  },
  {
    "path": "lib/abbrevia/source/AbQDgDir.pas",
    "content": "(* ***** BEGIN LICENSE BLOCK *****\n * Version: MPL 1.1\n *\n * The contents of this file are subject to the Mozilla Public License Version\n * 1.1 (the \"License\"); you may not use this file except in compliance with\n * the License. You may obtain a copy of the License at\n * http://www.mozilla.org/MPL/\n *\n * Software distributed under the License is distributed on an \"AS IS\" basis,\n * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License\n * for the specific language governing rights and limitations under the\n * License.\n *\n * The Original Code is TurboPower Abbrevia\n *\n * The Initial Developer of the Original Code is\n * TurboPower Software\n *\n * Portions created by the Initial Developer are Copyright (C) 1997-2002\n * the Initial Developer. All Rights Reserved.\n *\n * Contributor(s):\n *\n * ***** END LICENSE BLOCK ***** *)\n\n{*********************************************************}\n{* ABBREVIA: AbQDgDir.pas                                *}\n{*********************************************************}\n{* ABBREVIA: Dialog - Directory (CLX)                    *}\n{*   Use AbDlgDir.pas for VCL                            *}\n{*********************************************************}\n\n{$DEFINE UsingClx }\n\nunit AbQDgDir;\n\n{$R *.xfm}\n\n{$I AbDlgDir.pas}\n\n"
  },
  {
    "path": "lib/abbrevia/source/AbQDgPwd.pas",
    "content": "(* ***** BEGIN LICENSE BLOCK *****\n * Version: MPL 1.1\n *\n * The contents of this file are subject to the Mozilla Public License Version\n * 1.1 (the \"License\"); you may not use this file except in compliance with\n * the License. You may obtain a copy of the License at\n * http://www.mozilla.org/MPL/\n *\n * Software distributed under the License is distributed on an \"AS IS\" basis,\n * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License\n * for the specific language governing rights and limitations under the\n * License.\n *\n * The Original Code is TurboPower Abbrevia\n *\n * The Initial Developer of the Original Code is\n * TurboPower Software\n *\n * Portions created by the Initial Developer are Copyright (C) 1997-2002\n * the Initial Developer. All Rights Reserved.\n *\n * Contributor(s):\n *\n * ***** END LICENSE BLOCK ***** *)\n\n{*********************************************************}\n{* ABBREVIA: AbQDgPwd.pas                                *}\n{*********************************************************}\n{* ABBREVIA: Dialog - Password (CLX)                     *}\n{*   Use AbDlgPwd.pas for VCL                            *}\n{*********************************************************}\n\n{$DEFINE UsingClx}\n\nunit AbQDgPwd;\n\n{$R *.xfm}\n\n{$I AbDlgPwd.pas}\n\n"
  },
  {
    "path": "lib/abbrevia/source/AbQHexVw.pas",
    "content": "(* ***** BEGIN LICENSE BLOCK *****\n * Version: MPL 1.1\n *\n * The contents of this file are subject to the Mozilla Public License Version\n * 1.1 (the \"License\"); you may not use this file except in compliance with\n * the License. You may obtain a copy of the License at\n * http://www.mozilla.org/MPL/\n *\n * Software distributed under the License is distributed on an \"AS IS\" basis,\n * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License\n * for the specific language governing rights and limitations under the\n * License.\n *\n * The Original Code is TurboPower Abbrevia\n *\n * The Initial Developer of the Original Code is\n * TurboPower Software\n *\n * Portions created by the Initial Developer are Copyright (C) 1997-2002\n * the Initial Developer. All Rights Reserved.\n *\n * Contributor(s):\n *\n * ***** END LICENSE BLOCK ***** *)\n\n{*********************************************************}\n{* ABBREVIA: AbQCmpnd.pas                                *}\n{*********************************************************}\n{* ABBREVIA: Compound File classes and component (CLX)   *}\n{*   Use AbCompnd.pas for VCL                            *}\n{*********************************************************}\n\nunit AbQHexVw;\n\n{$DEFINE UsingCLX}\n\n{$I AbHexVw.pas}\n\n\n"
  },
  {
    "path": "lib/abbrevia/source/AbQMeter.pas",
    "content": "(* ***** BEGIN LICENSE BLOCK *****\n * Version: MPL 1.1\n *\n * The contents of this file are subject to the Mozilla Public License Version\n * 1.1 (the \"License\"); you may not use this file except in compliance with\n * the License. You may obtain a copy of the License at\n * http://www.mozilla.org/MPL/\n *\n * Software distributed under the License is distributed on an \"AS IS\" basis,\n * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License\n * for the specific language governing rights and limitations under the\n * License.\n *\n * The Original Code is TurboPower Abbrevia\n *\n * The Initial Developer of the Original Code is\n * TurboPower Software\n *\n * Portions created by the Initial Developer are Copyright (C) 1997-2002\n * the Initial Developer. All Rights Reserved.\n *\n * Contributor(s):\n *\n * ***** END LICENSE BLOCK ***** *)\n\n{*********************************************************}\n{* ABBREVIA: AbQMeter.pas                                *}\n{*********************************************************}\n{* ABBREVIA: Progress meter (CLX)                        *}\n{*   Use AbMeter.pas for VCL                             *}\n{*********************************************************}\n\n{$DEFINE UsingCLX}\n\nunit AbQMeter;\n\n{$I AbMeter.pas}\n\n"
  },
  {
    "path": "lib/abbrevia/source/AbQPeCol.pas",
    "content": "(* ***** BEGIN LICENSE BLOCK *****\n * Version: MPL 1.1\n *\n * The contents of this file are subject to the Mozilla Public License Version\n * 1.1 (the \"License\"); you may not use this file except in compliance with\n * the License. You may obtain a copy of the License at\n * http://www.mozilla.org/MPL/\n *\n * Software distributed under the License is distributed on an \"AS IS\" basis,\n * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License\n * for the specific language governing rights and limitations under the\n * License.\n *\n * The Original Code is TurboPower Abbrevia\n *\n * The Initial Developer of the Original Code is\n * TurboPower Software\n *\n * Portions created by the Initial Developer are Copyright (C) 1997-2002\n * the Initial Developer. All Rights Reserved.\n *\n * Contributor(s):\n *\n * ***** END LICENSE BLOCK ***** *)\n\n{*********************************************************}\n{* ABBREVIA: AbQPeCol.pas                                *}\n{*********************************************************}\n{* ABBREVIA: Property Editor - ZipView column headings   *}\n{* (CLX)                                                 *}\n{*   Use AbPeCol.pas for VCL                             *}\n{*********************************************************}\n\n{$DEFINE UsingClx}\n\nunit AbQPeCol;\n\n{$R *.xfm}\n\n{$I AbPeCol.pas}\n\n\n\n"
  },
  {
    "path": "lib/abbrevia/source/AbQPeDir.pas",
    "content": "(* ***** BEGIN LICENSE BLOCK *****\n * Version: MPL 1.1\n *\n * The contents of this file are subject to the Mozilla Public License Version\n * 1.1 (the \"License\"); you may not use this file except in compliance with\n * the License. You may obtain a copy of the License at\n * http://www.mozilla.org/MPL/\n *\n * Software distributed under the License is distributed on an \"AS IS\" basis,\n * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License\n * for the specific language governing rights and limitations under the\n * License.\n *\n * The Original Code is TurboPower Abbrevia\n *\n * The Initial Developer of the Original Code is\n * TurboPower Software\n *\n * Portions created by the Initial Developer are Copyright (C) 1997-2002\n * the Initial Developer. All Rights Reserved.\n *\n * Contributor(s):\n *\n * ***** END LICENSE BLOCK ***** *)\n\n{*********************************************************}\n{* ABBREVIA: AbPeDir.pas                                 *}\n{*********************************************************}\n{* ABBREVIA: Property Editor - Directory (CLX)           *}\n{*   Use AbPeDir.pas for VCL                             *}\n{*********************************************************}\n\n{$DEFINE UsingCLX}\n\nunit AbQPeDir;\n\n{$I AbPeDir.pas}\n"
  },
  {
    "path": "lib/abbrevia/source/AbQPeFn.pas",
    "content": "(* ***** BEGIN LICENSE BLOCK *****\n * Version: MPL 1.1\n *\n * The contents of this file are subject to the Mozilla Public License Version\n * 1.1 (the \"License\"); you may not use this file except in compliance with\n * the License. You may obtain a copy of the License at\n * http://www.mozilla.org/MPL/\n *\n * Software distributed under the License is distributed on an \"AS IS\" basis,\n * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License\n * for the specific language governing rights and limitations under the\n * License.\n *\n * The Original Code is TurboPower Abbrevia\n *\n * The Initial Developer of the Original Code is\n * TurboPower Software\n *\n * Portions created by the Initial Developer are Copyright (C) 1997-2002\n * the Initial Developer. All Rights Reserved.\n *\n * Contributor(s):\n *\n * ***** END LICENSE BLOCK ***** *)\n\n{*********************************************************}\n{* ABBREVIA: AbQPeFn.PAS                                 *}\n{*********************************************************}\n{* ABBREVIA: Property Editor - FileName (CLX)            *}\n{*   Use AbPeFn.pas for VCL                              *}\n{*********************************************************}\n\n{$DEFINE UsingClx}\n\nunit AbQPeFn;\n\n{$I AbPeFn.pas}\n\n"
  },
  {
    "path": "lib/abbrevia/source/AbQPePas.pas",
    "content": "(* ***** BEGIN LICENSE BLOCK *****\n * Version: MPL 1.1\n *\n * The contents of this file are subject to the Mozilla Public License Version\n * 1.1 (the \"License\"); you may not use this file except in compliance with\n * the License. You may obtain a copy of the License at\n * http://www.mozilla.org/MPL/\n *\n * Software distributed under the License is distributed on an \"AS IS\" basis,\n * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License\n * for the specific language governing rights and limitations under the\n * License.\n *\n * The Original Code is TurboPower Abbrevia\n *\n * The Initial Developer of the Original Code is\n * TurboPower Software\n *\n * Portions created by the Initial Developer are Copyright (C) 1997-2002\n * the Initial Developer. All Rights Reserved.\n *\n * Contributor(s):\n *\n * ***** END LICENSE BLOCK ***** *)\n\n{*********************************************************}\n{* ABBREVIA: AbQPePas.pas                                *}\n{*********************************************************}\n{* ABBREVIA: Password property editor (CLX)              *}\n{*   Use AbPePass.pas for VCL                            *}\n{*********************************************************}\n\n{$DEFINE UsingClx}\n\nunit AbQPePas;\n\n{$I AbPePass.pas}\n\n\n"
  },
  {
    "path": "lib/abbrevia/source/AbQPeVer.pas",
    "content": "(* ***** BEGIN LICENSE BLOCK *****\n * Version: MPL 1.1\n *\n * The contents of this file are subject to the Mozilla Public License Version\n * 1.1 (the \"License\"); you may not use this file except in compliance with\n * the License. You may obtain a copy of the License at\n * http://www.mozilla.org/MPL/\n *\n * Software distributed under the License is distributed on an \"AS IS\" basis,\n * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License\n * for the specific language governing rights and limitations under the\n * License.\n *\n * The Original Code is TurboPower Abbrevia\n *\n * The Initial Developer of the Original Code is\n * TurboPower Software\n *\n * Portions created by the Initial Developer are Copyright (C) 1997-2002\n * the Initial Developer. All Rights Reserved.\n *\n * Contributor(s):\n *\n * ***** END LICENSE BLOCK ***** *)\n\n{*********************************************************}\n{* ABBREVIA: AbQPeVer.pas                                *}\n{*********************************************************}\n{* ABBREVIA: Property Editor - Version (CLX)             *}\n{*   See AbPeVer.pas for the VCL header                  *}\n{*********************************************************}\n\n{$DEFINE UsingClx}\n\nunit AbQPeVer;\n\n{$R *.xfm}\n\n{$I AbPeVer.pas}\n\n"
  },
  {
    "path": "lib/abbrevia/source/AbQView.pas",
    "content": "(* ***** BEGIN LICENSE BLOCK *****\n * Version: MPL 1.1\n *\n * The contents of this file are subject to the Mozilla Public License Version\n * 1.1 (the \"License\"); you may not use this file except in compliance with\n * the License. You may obtain a copy of the License at\n * http://www.mozilla.org/MPL/\n *\n * Software distributed under the License is distributed on an \"AS IS\" basis,\n * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License\n * for the specific language governing rights and limitations under the\n * License.\n *\n * The Original Code is TurboPower Abbrevia\n *\n * The Initial Developer of the Original Code is\n * TurboPower Software\n *\n * Portions created by the Initial Developer are Copyright (C) 1997-2002\n * the Initial Developer. All Rights Reserved.\n *\n * Contributor(s):\n *\n * ***** END LICENSE BLOCK ***** *)\n\n{*********************************************************}\n{* ABBREVIA: AbQView.pas                                 *}\n{*********************************************************}\n{* ABBREVIA: Base archive viewer component (CLX)         *}\n{*   Use AbView.pas for VCL                              *}\n{*********************************************************}\n\n{$DEFINE UsingCLX}\n\nunit AbQView;\n\n{$I AbView.pas}\n\n"
  },
  {
    "path": "lib/abbrevia/source/AbQZView.pas",
    "content": "(* ***** BEGIN LICENSE BLOCK *****\n * Version: MPL 1.1\n *\n * The contents of this file are subject to the Mozilla Public License Version\n * 1.1 (the \"License\"); you may not use this file except in compliance with\n * the License. You may obtain a copy of the License at\n * http://www.mozilla.org/MPL/\n *\n * Software distributed under the License is distributed on an \"AS IS\" basis,\n * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License\n * for the specific language governing rights and limitations under the\n * License.\n *\n * The Original Code is TurboPower Abbrevia\n *\n * The Initial Developer of the Original Code is\n * TurboPower Software\n *\n * Portions created by the Initial Developer are Copyright (C) 1997-2002\n * the Initial Developer. All Rights Reserved.\n *\n * Contributor(s):\n *\n * ***** END LICENSE BLOCK ***** *)\n\n{*********************************************************}\n{* ABBREVIA: AbQZView.pas                                *}\n{*********************************************************}\n{* ABBREVIA: Zip archive viewer component (CLX)          *}\n{*   Use AbZView.pas for VCL                             *}\n{*********************************************************}\n\n{$DEFINE UsingCLX}\n\nunit AbQZView;\n\n{$I AbZView.pas}\n\n\n"
  },
  {
    "path": "lib/abbrevia/source/AbQZpOut.pas",
    "content": "(* ***** BEGIN LICENSE BLOCK *****\n * Version: MPL 1.1\n *\n * The contents of this file are subject to the Mozilla Public License Version\n * 1.1 (the \"License\"); you may not use this file except in compliance with\n * the License. You may obtain a copy of the License at\n * http://www.mozilla.org/MPL/\n *\n * Software distributed under the License is distributed on an \"AS IS\" basis,\n * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License\n * for the specific language governing rights and limitations under the\n * License.\n *\n * The Original Code is TurboPower Abbrevia\n *\n * The Initial Developer of the Original Code is\n * TurboPower Software\n *\n * Portions created by the Initial Developer are Copyright (C) 1997-2002\n * the Initial Developer. All Rights Reserved.\n *\n * Contributor(s):\n *\n * ***** END LICENSE BLOCK ***** *)\n\n{*********************************************************}\n{* ABBREVIA: AbQZpOut.pas                                *}\n{*********************************************************}\n{* ABBREVIA: Visual Component with Zip and unzip support *}\n{* (CLX)                                                 *}\n{*   Use AbZipOut.pas for VCL                            *}\n{*********************************************************}\n\n{$DEFINE UsingCLX}\n\nunit AbQZpOut;\n\n{$I AbZipOut.pas}\n\n\n"
  },
  {
    "path": "lib/abbrevia/source/AbReg.pas",
    "content": "(* ***** BEGIN LICENSE BLOCK *****\n * Version: MPL 1.1\n *\n * The contents of this file are subject to the Mozilla Public License Version\n * 1.1 (the \"License\"); you may not use this file except in compliance with\n * the License. You may obtain a copy of the License at\n * http://www.mozilla.org/MPL/\n *\n * Software distributed under the License is distributed on an \"AS IS\" basis,\n * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License\n * for the specific language governing rights and limitations under the\n * License.\n *\n * The Original Code is TurboPower Abbrevia\n *\n * The Initial Developer of the Original Code is\n * TurboPower Software\n *\n * Portions created by the Initial Developer are Copyright (C) 1997-2002\n * the Initial Developer. All Rights Reserved.\n *\n * Contributor(s):\n *\n * ***** END LICENSE BLOCK ***** *)\n\n{*********************************************************}\n{* ABBREVIA: AbReg.pas                                   *}\n{*********************************************************}\n{* ABBREVIA: Registrations (VCL)                         *}\n{*********************************************************}\n\nunit AbReg;\n\n{$I AbDefine.inc}\n{$UNDEF UsingClx }\n\n{$R AbReg.res}\n\ninterface\n\nuses\n  Classes,\n  {$IFDEF LCL}\n  LResources,\n  {$ENDIF}\n  {$IFDEF MSWINDOWS}\n  AbCBrows, AbCabExt, AbCabMak, AbCabKit,\n  {$ENDIF}\n  AbZBrows, AbUnzper, AbZipper, AbZipKit, AbSelfEx;\n\nprocedure Register;\n\nimplementation\n\n{$IFNDEF FPC}\nuses\n  AbUtils,\n  AbPeDir,\n  AbPeFn,\n  AbPePass,\n  AbPeVer,\n  AbPeCol,\n  DesignIntf,\n  DesignEditors,\n  SysUtils;\n{$ENDIF}\n\nprocedure Register;\nbegin\n{$IFNDEF FPC}\n  RegisterPropertyEditor( TypeInfo( string ), TAbZipBrowser, 'FileName',\n                          TAbFileNameProperty );\n  RegisterPropertyEditor( TypeInfo( string ), TAbZipper, 'FileName',\n                          TAbFileNameProperty );\n  RegisterPropertyEditor( TypeInfo( string ), TAbUnZipper, 'FileName',\n                          TAbFileNameProperty );\n  RegisterPropertyEditor( TypeInfo( string ), TAbZipKit, 'FileName',\n                          TAbFileNameProperty );\n  RegisterPropertyEditor( TypeInfo( string ), TAbZipBrowser, 'LogFile',\n                          TAbLogNameProperty );\n  RegisterPropertyEditor( TypeInfo( string ), TAbZipper, 'LogFile',\n                          TAbLogNameProperty );\n  RegisterPropertyEditor( TypeInfo( string ), TAbUnZipper, 'LogFile',\n                          TAbLogNameProperty );\n  RegisterPropertyEditor( TypeInfo( string ), TAbZipKit, 'LogFile',\n                          TAbLogNameProperty );\n  RegisterPropertyEditor( TypeInfo( string ), TAbMakeSelfExe, 'SelfExe',\n                          TAbExeNameProperty );\n  RegisterPropertyEditor( TypeInfo( string ), TAbMakeSelfExe, 'StubExe',\n                          TAbExeNameProperty );\n  RegisterPropertyEditor( TypeInfo( string ), TAbMakeSelfExe, 'ZipFile',\n                          TAbFileNameProperty );\n  RegisterPropertyEditor( TypeInfo( string ), TAbZipBrowser, 'BaseDirectory',\n                          TAbDirectoryProperty );\n  RegisterPropertyEditor( TypeInfo( string ), TAbZipper, 'BaseDirectory',\n                          TAbDirectoryProperty );\n  RegisterPropertyEditor( TypeInfo( string ), TAbUnZipper, 'BaseDirectory',\n                          TAbDirectoryProperty );\n  RegisterPropertyEditor( TypeInfo( string ), TAbZipKit, 'BaseDirectory',\n                          TAbDirectoryProperty );\n  RegisterPropertyEditor( TypeInfo( string ), TAbZipBrowser, 'TempDirectory',\n                          TAbDirectoryProperty );\n  RegisterPropertyEditor( TypeInfo( string ), TAbZipper, 'TempDirectory',\n                          TAbDirectoryProperty );\n  RegisterPropertyEditor( TypeInfo( string ), TAbUnZipper, 'TempDirectory',\n                          TAbDirectoryProperty );\n  RegisterPropertyEditor( TypeInfo( string ), TAbZipKit, 'TempDirectory',\n                          TAbDirectoryProperty );\n  RegisterPropertyEditor( TypeInfo( string ), TAbZipBrowser, 'Version',\n                          TAbVersionProperty );\n  RegisterPropertyEditor( TypeInfo( string ), TAbZipper, 'Version',\n                          TAbVersionProperty );\n  RegisterPropertyEditor( TypeInfo( string ), TAbUnZipper, 'Version',\n                          TAbVersionProperty );\n  RegisterPropertyEditor( TypeInfo( string ), TAbZipKit, 'Version',\n                          TAbVersionProperty );\n  RegisterPropertyEditor( TypeInfo( string ), TAbMakeSelfExe, 'Version',\n                          TAbVersionProperty );\n  RegisterPropertyEditor( TypeInfo( string ), TAbZipBrowser, 'Password',\n                          TAbPasswordProperty );\n  RegisterPropertyEditor( TypeInfo( string ), TAbZipper, 'Password',\n                          TAbPasswordProperty );\n  RegisterPropertyEditor( TypeInfo( string ), TAbUnZipper, 'Password',\n                          TAbPasswordProperty );\n  RegisterPropertyEditor( TypeInfo( string ), TAbZipKit, 'Password',\n                          TAbPasswordProperty );\n  RegisterPropertyEditor( TypeInfo( string ), TAbCabBrowser, 'FileName',\n                          TAbCabNameProperty );\n  RegisterPropertyEditor( TypeInfo( string ), TAbMakeCab, 'FileName',\n                          TAbCabNameProperty );\n  RegisterPropertyEditor( TypeInfo( string ), TAbCabExtractor, 'FileName',\n                          TAbCabNameProperty );\n  RegisterPropertyEditor( TypeInfo( string ), TAbCabKit, 'FileName',\n                          TAbCabNameProperty );\n  RegisterPropertyEditor( TypeInfo( string ), TAbCabBrowser, 'BaseDirectory',\n                          TAbDirectoryProperty );\n  RegisterPropertyEditor( TypeInfo( string ), TAbMakeCab, 'BaseDirectory',\n                          TAbDirectoryProperty );\n  RegisterPropertyEditor( TypeInfo( string ), TAbCabExtractor, 'BaseDirectory',\n                          TAbDirectoryProperty );\n  RegisterPropertyEditor( TypeInfo( string ), TAbCabKit, 'BaseDirectory',\n                          TAbDirectoryProperty );\n  RegisterPropertyEditor( TypeInfo( string ), TAbCabBrowser, 'LogFile',\n                          TAbLogNameProperty );\n  RegisterPropertyEditor( TypeInfo( string ), TAbMakeCab, 'LogFile',\n                          TAbLogNameProperty );\n  RegisterPropertyEditor( TypeInfo( string ), TAbCabExtractor, 'LogFile',\n                          TAbLogNameProperty );\n  RegisterPropertyEditor( TypeInfo( string ), TAbCabKit, 'LogFile',\n                          TAbLogNameProperty );\n  RegisterPropertyEditor( TypeInfo( string ), TAbCabBrowser, 'TempDirectory',\n                          TAbDirectoryProperty );\n  RegisterPropertyEditor( TypeInfo( string ), TAbMakeCab, 'TempDirectory',\n                          TAbDirectoryProperty );\n  RegisterPropertyEditor( TypeInfo( string ), TAbCabExtractor, 'TempDirectory',\n                          TAbDirectoryProperty );\n  RegisterPropertyEditor( TypeInfo( string ), TAbCabKit, 'TempDirectory',\n                          TAbDirectoryProperty );\n  RegisterPropertyEditor( TypeInfo( string ), TAbCabBrowser, 'Version',\n                          TAbVersionProperty );\n  RegisterPropertyEditor( TypeInfo( string ), TAbMakeCab, 'Version',\n                          TAbVersionProperty );\n  RegisterPropertyEditor( TypeInfo( string ), TAbCabExtractor, 'Version',\n                          TAbVersionProperty );\n  RegisterPropertyEditor( TypeInfo( string ), TAbCabKit, 'Version',\n                          TAbVersionProperty );\n{$ENDIF}\n\n  RegisterComponents( 'Abbrevia',\n                      [ TAbZipBrowser,\n                        TAbUnzipper,\n                        TAbZipper,\n                        TAbZipKit,\n                        {$IFDEF MSWINDOWS}\n                        TAbCabBrowser,\n                        TAbCabExtractor,\n                        TAbMakeCab,\n                        TAbCabKit,\n                        {$ENDIF}\n                        TAbMakeSelfExe ]);\nend;\n\n{$IFDEF LCL}\ninitialization\n  {$I abbrevia.lrs}\n{$ENDIF}\n\nend.\n"
  },
  {
    "path": "lib/abbrevia/source/AbRegClx.pas",
    "content": "(* ***** BEGIN LICENSE BLOCK *****\n * Version: MPL 1.1\n *\n * The contents of this file are subject to the Mozilla Public License Version\n * 1.1 (the \"License\"); you may not use this file except in compliance with\n * the License. You may obtain a copy of the License at\n * http://www.mozilla.org/MPL/\n *\n * Software distributed under the License is distributed on an \"AS IS\" basis,\n * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License\n * for the specific language governing rights and limitations under the\n * License.\n *\n * The Original Code is TurboPower Abbrevia\n *\n * The Initial Developer of the Original Code is\n * TurboPower Software\n *\n * Portions created by the Initial Developer are Copyright (C) 1997-2002\n * the Initial Developer. All Rights Reserved.\n *\n * Contributor(s):\n *\n * ***** END LICENSE BLOCK ***** *)\n\n{*********************************************************}\n{* ABBREVIA: AbRegClx.pas                                *}\n{*********************************************************}\n{* ABBREVIA: Registrations (CLX)                         *}\n{*********************************************************}\n\nunit AbRegClx;\n\n{$I AbDefine.inc}\n{$DEFINE UsingCLX}\n\n{$R AbReg.res}\n\ninterface\n\n{$IFDEF LINUX}\n  !! Error, this unit is for CLX on Windows, use AbRegLinux.pas for Linux\n{$ENDIF}\n\nuses\n  Classes,\n  AbCBrows, AbCabExt, AbCabMak, AbCabKit,\n  AbZBrows, AbUnzper, AbZipper, AbZipKit, AbSelfEx,\n  AbQCView,  AbQZpOut, AbQView, AbQZView, AbQMeter;\n\nprocedure Register;\n\nimplementation\n\nuses\n  AbUtils,\n  AbQPeDir,\n  AbQPeFn,\n  AbQPePas,\n  AbQPeVer,\n  AbQPeCol,\n  AbQDgDir,\n  AbQDgPwd,\n  DesignIntf,\n  DesignEditors,\n  SysUtils;\n\nprocedure Register;\nbegin\n  RegisterPropertyEditor( TypeInfo( string ), TAbZipBrowser, 'FileName',\n                          TAbFileNameProperty );\n  RegisterPropertyEditor( TypeInfo( string ), TAbZipper, 'FileName',\n                          TAbFileNameProperty );\n  RegisterPropertyEditor( TypeInfo( string ), TAbUnZipper, 'FileName',\n                          TAbFileNameProperty );\n  RegisterPropertyEditor( TypeInfo( string ), TAbZipKit, 'FileName',\n                          TAbFileNameProperty );\n  RegisterPropertyEditor( TypeInfo( string ), TAbZipOutline, 'FileName',\n                          TAbFileNameProperty );\n  RegisterPropertyEditor( TypeInfo( string ), TAbZipBrowser, 'LogFile',\n                          TAbLogNameProperty );\n  RegisterPropertyEditor( TypeInfo( string ), TAbZipper, 'LogFile',\n                          TAbLogNameProperty );\n  RegisterPropertyEditor( TypeInfo( string ), TAbUnZipper, 'LogFile',\n                          TAbLogNameProperty );\n  RegisterPropertyEditor( TypeInfo( string ), TAbZipKit, 'LogFile',\n                          TAbLogNameProperty );\n  RegisterPropertyEditor( TypeInfo( string ), TAbZipOutline, 'LogFile',\n                          TAbLogNameProperty );\n  RegisterPropertyEditor( TypeInfo( string ), TAbMakeSelfExe, 'SelfExe',\n                          TAbExeNameProperty );\n  RegisterPropertyEditor( TypeInfo( string ), TAbMakeSelfExe, 'StubExe',\n                          TAbExeNameProperty );\n  RegisterPropertyEditor( TypeInfo( string ), TAbMakeSelfExe, 'ZipFile',\n                          TAbFileNameProperty );\n\n  RegisterPropertyEditor( TypeInfo( string ), TAbZipBrowser, 'BaseDirectory',\n                          TAbDirectoryProperty );\n  RegisterPropertyEditor( TypeInfo( string ), TAbZipper, 'BaseDirectory',\n                          TAbDirectoryProperty );\n  RegisterPropertyEditor( TypeInfo( string ), TAbUnZipper, 'BaseDirectory',\n                          TAbDirectoryProperty );\n  RegisterPropertyEditor( TypeInfo( string ), TAbZipKit, 'BaseDirectory',\n                          TAbDirectoryProperty );\n  RegisterPropertyEditor( TypeInfo( string ), TAbZipOutline, 'BaseDirectory',\n                          TAbDirectoryProperty );\n  RegisterPropertyEditor( TypeInfo( string ), TAbZipBrowser, 'TempDirectory',\n                          TAbDirectoryProperty );\n  RegisterPropertyEditor( TypeInfo( string ), TAbZipper, 'TempDirectory',\n                          TAbDirectoryProperty );\n  RegisterPropertyEditor( TypeInfo( string ), TAbUnZipper, 'TempDirectory',\n                          TAbDirectoryProperty );\n  RegisterPropertyEditor( TypeInfo( string ), TAbZipKit, 'TempDirectory',\n                          TAbDirectoryProperty );\n  RegisterPropertyEditor( TypeInfo( string ), TAbZipOutline, 'TempDirectory',\n                          TAbDirectoryProperty );\n  RegisterPropertyEditor( TypeInfo( string ), TAbZipBrowser, 'Version',\n                          TAbVersionProperty );\n  RegisterPropertyEditor( TypeInfo( string ), TAbZipper, 'Version',\n                          TAbVersionProperty );\n  RegisterPropertyEditor( TypeInfo( string ), TAbUnZipper, 'Version',\n                          TAbVersionProperty );\n  RegisterPropertyEditor( TypeInfo( string ), TAbZipKit, 'Version',\n                          TAbVersionProperty );\n  RegisterPropertyEditor( TypeInfo( string ), TAbZipOutline, 'Version',\n                          TAbVersionProperty );\n  RegisterPropertyEditor( TypeInfo( string ), TAbZipView, 'Version',\n                          TAbVersionProperty );\n  RegisterPropertyEditor( TypeInfo( string ), TAbMeter, 'Version',\n                          TAbVersionProperty );\n  RegisterPropertyEditor( TypeInfo( string ), TAbMakeSelfExe, 'Version',\n                          TAbVersionProperty );\n  RegisterPropertyEditor( TypeInfo( string ), TAbZipBrowser, 'Password',\n                          TAbPasswordProperty );\n  RegisterPropertyEditor( TypeInfo( string ), TAbZipper, 'Password',\n                          TAbPasswordProperty );\n  RegisterPropertyEditor( TypeInfo( string ), TAbUnZipper, 'Password',\n                          TAbPasswordProperty );\n  RegisterPropertyEditor( TypeInfo( string ), TAbZipKit, 'Password',\n                          TAbPasswordProperty );\n  RegisterPropertyEditor( TypeInfo( string ), TAbZipOutline, 'Password',\n                          TAbPasswordProperty );\n  RegisterPropertyEditor( TypeInfo( TAbColHeadings ), TAbZipView, 'Headings',\n                          TAbColHeadingsProperty );\n{$IFDEF MSWINDOWS}\n  RegisterPropertyEditor( TypeInfo( string ), TAbCabBrowser, 'FileName',\n                          TAbCabNameProperty );\n  RegisterPropertyEditor( TypeInfo( string ), TAbMakeCab, 'FileName',\n                          TAbCabNameProperty );\n  RegisterPropertyEditor( TypeInfo( string ), TAbCabExtractor, 'FileName',\n                          TAbCabNameProperty );\n  RegisterPropertyEditor( TypeInfo( string ), TAbCabKit, 'FileName',\n                          TAbCabNameProperty );\n  RegisterPropertyEditor( TypeInfo( string ), TAbCabBrowser, 'BaseDirectory',\n                          TAbDirectoryProperty );\n  RegisterPropertyEditor( TypeInfo( string ), TAbMakeCab, 'BaseDirectory',\n                          TAbDirectoryProperty );\n  RegisterPropertyEditor( TypeInfo( string ), TAbCabExtractor, 'BaseDirectory',\n                          TAbDirectoryProperty );\n  RegisterPropertyEditor( TypeInfo( string ), TAbCabKit, 'BaseDirectory',\n                          TAbDirectoryProperty );\n  RegisterPropertyEditor( TypeInfo( string ), TAbCabBrowser, 'LogFile',\n                          TAbLogNameProperty );\n  RegisterPropertyEditor( TypeInfo( string ), TAbMakeCab, 'LogFile',\n                          TAbLogNameProperty );\n  RegisterPropertyEditor( TypeInfo( string ), TAbCabExtractor, 'LogFile',\n                          TAbLogNameProperty );\n  RegisterPropertyEditor( TypeInfo( string ), TAbCabKit, 'LogFile',\n                          TAbLogNameProperty );\n  RegisterPropertyEditor( TypeInfo( string ), TAbCabBrowser, 'TempDirectory',\n                          TAbDirectoryProperty );\n  RegisterPropertyEditor( TypeInfo( string ), TAbMakeCab, 'TempDirectory',\n                          TAbDirectoryProperty );\n  RegisterPropertyEditor( TypeInfo( string ), TAbCabExtractor, 'TempDirectory',\n                          TAbDirectoryProperty );\n  RegisterPropertyEditor( TypeInfo( string ), TAbCabKit, 'TempDirectory',\n                          TAbDirectoryProperty );\n  RegisterPropertyEditor( TypeInfo( string ), TAbCabBrowser, 'Version',\n                          TAbVersionProperty );\n  RegisterPropertyEditor( TypeInfo( string ), TAbMakeCab, 'Version',\n                          TAbVersionProperty );\n  RegisterPropertyEditor( TypeInfo( string ), TAbCabExtractor, 'Version',\n                          TAbVersionProperty );\n  RegisterPropertyEditor( TypeInfo( string ), TAbCabKit, 'Version',\n                          TAbVersionProperty );\n  RegisterPropertyEditor( TypeInfo( string ), TAbCabView, 'Version',\n                          TAbVersionProperty );\n  RegisterPropertyEditor( TypeInfo( TAbColHeadings ), TAbCabView, 'Headings',\n                          TAbColHeadingsProperty );\n{$ENDIF}\n\n  RegisterComponents( 'Abbrevia',\n                      [ TAbZipBrowser,\n                        TAbUnzipper,\n                        TAbZipper,\n                        TAbZipKit,\n                        TAbZipView,\n                        TAbZipOutline,\n\n{$IFDEF MSWINDOWS}\n                        TAbCabBrowser,\n                        TAbCabExtractor,\n                        TAbMakeCab,\n                        TAbCabKit,\n                        TAbCabView,\n{$ENDIF}\n\n                        TAbMeter,\n                        TAbMakeSelfExe ]);\n\n  RegisterPropertyEditor( TypeInfo( string ), TAbZipOutline, 'FileName',\n                          TAbFileNameProperty );\n  RegisterPropertyEditor( TypeInfo( string ), TAbZipOutline, 'LogFile',\n                          TAbLogNameProperty );\n  RegisterPropertyEditor( TypeInfo( string ), TAbZipOutline, 'BaseDirectory',\n                          TAbDirectoryProperty );\n  RegisterPropertyEditor( TypeInfo( string ), TAbZipOutline, 'TempDirectory',\n                          TAbDirectoryProperty );\n  RegisterPropertyEditor( TypeInfo( string ), TAbZipOutline, 'Version',\n                          TAbVersionProperty );\n  RegisterPropertyEditor( TypeInfo( string ), TAbZipView, 'Version',\n                          TAbVersionProperty );\n  RegisterPropertyEditor( TypeInfo( TAbColHeadings ), TAbZipView, 'Headings',\n                          TAbColHeadingsProperty );\n\n  RegisterComponents( 'Abbrevia',\n                      [\n                        TAbMeter,\n                        TAbCabView,\n                        TAbZipView,\n                        TAbZipOutline\n                      ]);\nend;\n\nend.\n"
  },
  {
    "path": "lib/abbrevia/source/AbRegLinux.pas",
    "content": "(* ***** BEGIN LICENSE BLOCK *****\n * Version: MPL 1.1\n *\n * The contents of this file are subject to the Mozilla Public License Version\n * 1.1 (the \"License\"); you may not use this file except in compliance with\n * the License. You may obtain a copy of the License at\n * http://www.mozilla.org/MPL/\n *\n * Software distributed under the License is distributed on an \"AS IS\" basis,\n * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License\n * for the specific language governing rights and limitations under the\n * License.\n *\n * The Original Code is TurboPower Abbrevia\n *\n * The Initial Developer of the Original Code is\n * TurboPower Software\n *\n * Portions created by the Initial Developer are Copyright (C) 1997-2002\n * the Initial Developer. All Rights Reserved.\n *\n * Contributor(s):\n *\n * ***** END LICENSE BLOCK ***** *)\n\n{*********************************************************}\n{* ABBREVIA: AbRegLinux.pas                              *}\n{*********************************************************}\n{* ABBREVIA: Registrations                               *}\n{*********************************************************}\n\nunit AbRegLinux;\n\n{$I AbDefine.inc}\n{$R AbReg.res}\n\ninterface\n\n{$IFDEF MSWINDOWS}\n  !! Error, this unit is for CLX on Linux, use AbRegClx.pas for Windows\n{$ENDIF}\n\nuses\n  Classes,\n  AbQZpOut, AbQView, AbQZView, AbQMeter;\n\nprocedure Register;\n\nimplementation\n\nuses\n  AbUtils,\n  AbQPeDir,\n  AbQPeFn,\n  AbQPePas,\n  AbQPeVer,\n  AbQPeCol,\n  AbZBrows,\n  AbZipper,\n  AbUnzper,\n  AbZipKit,\n  AbSelfEx,\n  DesignIntf,\n  DesignEditors;\n\nprocedure Register;\nbegin\n  RegisterPropertyEditor( TypeInfo( string ), TAbZipBrowser, 'FileName',\n                          TAbFileNameProperty );\n  RegisterPropertyEditor( TypeInfo( string ), TAbZipper, 'FileName',\n                          TAbFileNameProperty );\n  RegisterPropertyEditor( TypeInfo( string ), TAbUnZipper, 'FileName',\n                          TAbFileNameProperty );\n  RegisterPropertyEditor( TypeInfo( string ), TAbZipKit, 'FileName',\n                          TAbFileNameProperty );\n  RegisterPropertyEditor( TypeInfo( string ), TAbZipOutline, 'FileName',\n                          TAbFileNameProperty );\n  RegisterPropertyEditor( TypeInfo( string ), TAbZipBrowser, 'LogFile',\n                          TAbLogNameProperty );\n  RegisterPropertyEditor( TypeInfo( string ), TAbZipper, 'LogFile',\n                          TAbLogNameProperty );\n  RegisterPropertyEditor( TypeInfo( string ), TAbUnZipper, 'LogFile',\n                          TAbLogNameProperty );\n  RegisterPropertyEditor( TypeInfo( string ), TAbZipKit, 'LogFile',\n                          TAbLogNameProperty );\n  RegisterPropertyEditor( TypeInfo( string ), TAbZipOutline, 'LogFile',\n                          TAbLogNameProperty );\n  RegisterPropertyEditor( TypeInfo( string ), TAbMakeSelfExe, 'SelfExe',\n                          TAbExeNameProperty );\n  RegisterPropertyEditor( TypeInfo( string ), TAbMakeSelfExe, 'StubExe',\n                          TAbExeNameProperty );\n  RegisterPropertyEditor( TypeInfo( string ), TAbMakeSelfExe, 'ZipFile',\n                          TAbFileNameProperty );\n  RegisterPropertyEditor( TypeInfo( string ), TAbZipBrowser, 'BaseDirectory',\n                          TAbDirectoryProperty );\n  RegisterPropertyEditor( TypeInfo( string ), TAbZipper, 'BaseDirectory',\n                          TAbDirectoryProperty );\n  RegisterPropertyEditor( TypeInfo( string ), TAbUnZipper, 'BaseDirectory',\n                          TAbDirectoryProperty );\n  RegisterPropertyEditor( TypeInfo( string ), TAbZipKit, 'BaseDirectory',\n                          TAbDirectoryProperty );\n  RegisterPropertyEditor( TypeInfo( string ), TAbZipOutline, 'BaseDirectory',\n                          TAbDirectoryProperty );\n  RegisterPropertyEditor( TypeInfo( string ), TAbZipBrowser, 'TempDirectory',\n                          TAbDirectoryProperty );\n  RegisterPropertyEditor( TypeInfo( string ), TAbZipper, 'TempDirectory',\n                          TAbDirectoryProperty );\n  RegisterPropertyEditor( TypeInfo( string ), TAbUnZipper, 'TempDirectory',\n                          TAbDirectoryProperty );\n  RegisterPropertyEditor( TypeInfo( string ), TAbZipKit, 'TempDirectory',\n                          TAbDirectoryProperty );\n  RegisterPropertyEditor( TypeInfo( string ), TAbZipOutline, 'TempDirectory',\n                          TAbDirectoryProperty );\n  RegisterPropertyEditor( TypeInfo( string ), TAbZipBrowser, 'Version',\n                          TAbVersionProperty );\n  RegisterPropertyEditor( TypeInfo( string ), TAbZipper, 'Version',\n                          TAbVersionProperty );\n  RegisterPropertyEditor( TypeInfo( string ), TAbUnZipper, 'Version',\n                          TAbVersionProperty );\n  RegisterPropertyEditor( TypeInfo( string ), TAbZipKit, 'Version',\n                          TAbVersionProperty );\n  RegisterPropertyEditor( TypeInfo( string ), TAbZipOutline, 'Version',\n                          TAbVersionProperty );\n  RegisterPropertyEditor( TypeInfo( string ), TAbZipView, 'Version',\n                          TAbVersionProperty );\n  RegisterPropertyEditor( TypeInfo( string ), TAbMeter, 'Version',\n                          TAbVersionProperty );\n  RegisterPropertyEditor( TypeInfo( string ), TAbMakeSelfExe, 'Version',\n                          TAbVersionProperty );\n  RegisterPropertyEditor( TypeInfo( string ), TAbZipBrowser, 'Password',\n                          TAbPasswordProperty );\n  RegisterPropertyEditor( TypeInfo( string ), TAbZipper, 'Password',\n                          TAbPasswordProperty );\n  RegisterPropertyEditor( TypeInfo( string ), TAbUnZipper, 'Password',\n                          TAbPasswordProperty );\n  RegisterPropertyEditor( TypeInfo( string ), TAbZipKit, 'Password',\n                          TAbPasswordProperty );\n  RegisterPropertyEditor( TypeInfo( string ), TAbZipOutline, 'Password',\n                          TAbPasswordProperty );\n  RegisterPropertyEditor( TypeInfo( TAbColHeadings ), TAbZipView, 'Headings',\n                          TAbColHeadingsProperty );\n  RegisterComponents( 'Abbrevia',\n                      [TAbZipBrowser,\n                        TAbUnzipper,\n                        TAbZipper,\n                        TAbZipKit,\n                        TAbZipOutline,\n                        TAbZipView,\n                        TAbMeter,\n                        TAbMakeSelfExe]);\nend;\n\nend.\n"
  },
  {
    "path": "lib/abbrevia/source/AbRegVcl.pas",
    "content": "(* ***** BEGIN LICENSE BLOCK *****\n * Version: MPL 1.1\n *\n * The contents of this file are subject to the Mozilla Public License Version\n * 1.1 (the \"License\"); you may not use this file except in compliance with\n * the License. You may obtain a copy of the License at\n * http://www.mozilla.org/MPL/\n *\n * Software distributed under the License is distributed on an \"AS IS\" basis,\n * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License\n * for the specific language governing rights and limitations under the\n * License.\n *\n * The Original Code is TurboPower Abbrevia\n *\n * The Initial Developer of the Original Code is\n * TurboPower Software\n *\n * Portions created by the Initial Developer are Copyright (C) 1997-2002\n * the Initial Developer. All Rights Reserved.\n *\n * Contributor(s):\n *\n * ***** END LICENSE BLOCK ***** *)\n\n{*********************************************************}\n{* ABBREVIA: AbRegVcl.pas                                *}\n{*********************************************************}\n{* ABBREVIA: Registrations (VCL)                         *}\n{*********************************************************}\n\nunit AbRegVcl;\n\n{$I AbDefine.inc}\n{$UNDEF UsingClx }\n\n{$R AbReg.res}\n\ninterface\n\nuses\n  Classes,\n  AbCBrows, AbCabExt, AbCabMak, AbCabKit, AbCView,\n  AbCompnd, AbHexVw,  AbZBrows, AbUnzper, AbZipper, AbZipKit, AbZipOut, \n  AbView, AbComCtrls, AbZView, AbMeter, AbSelfEx, AbZipExt;\n\nprocedure Register;\n\nimplementation\n\nuses\n  AbConst,\n  AbUtils,\n  AbPeDir,\n  AbPeFn,\n  AbPePass,\n  AbPeVer,\n  AbPeCol,\n  DesignIntf,\n  DesignEditors,\n  Graphics,\n  ToolsAPI,\n  SysUtils,\n  Windows;\n\nprocedure Register;\nbegin\n\n  RegisterPropertyEditor( TypeInfo( string ), TAbZipBrowser, 'FileName',\n                          TAbFileNameProperty );\n  RegisterPropertyEditor( TypeInfo( string ), TAbZipper, 'FileName',\n                          TAbFileNameProperty );\n  RegisterPropertyEditor( TypeInfo( string ), TAbUnZipper, 'FileName',\n                          TAbFileNameProperty );\n  RegisterPropertyEditor( TypeInfo( string ), TAbZipKit, 'FileName',\n                          TAbFileNameProperty );\n  RegisterPropertyEditor( TypeInfo( string ), TAbZipOutline, 'FileName',\n                          TAbFileNameProperty );\n  RegisterPropertyEditor( TypeInfo( string ), TAbZipBrowser, 'LogFile',\n                          TAbLogNameProperty );\n  RegisterPropertyEditor( TypeInfo( string ), TAbZipper, 'LogFile',\n                          TAbLogNameProperty );\n  RegisterPropertyEditor( TypeInfo( string ), TAbUnZipper, 'LogFile',\n                          TAbLogNameProperty );\n  RegisterPropertyEditor( TypeInfo( string ), TAbZipKit, 'LogFile',\n                          TAbLogNameProperty );\n  RegisterPropertyEditor( TypeInfo( string ), TAbZipOutline, 'LogFile',\n                          TAbLogNameProperty );\n  RegisterPropertyEditor( TypeInfo( string ), TAbMakeSelfExe, 'SelfExe',\n                          TAbExeNameProperty );\n  RegisterPropertyEditor( TypeInfo( string ), TAbMakeSelfExe, 'StubExe',\n                          TAbExeNameProperty );\n  RegisterPropertyEditor( TypeInfo( string ), TAbMakeSelfExe, 'ZipFile',\n                          TAbFileNameProperty );\n  RegisterPropertyEditor( TypeInfo( string ), TAbZipBrowser, 'BaseDirectory',\n                          TAbDirectoryProperty );\n  RegisterPropertyEditor( TypeInfo( string ), TAbZipper, 'BaseDirectory',\n                          TAbDirectoryProperty );\n  RegisterPropertyEditor( TypeInfo( string ), TAbUnZipper, 'BaseDirectory',\n                          TAbDirectoryProperty );\n  RegisterPropertyEditor( TypeInfo( string ), TAbZipKit, 'BaseDirectory',\n                          TAbDirectoryProperty );\n  RegisterPropertyEditor( TypeInfo( string ), TAbZipOutline, 'BaseDirectory',\n                          TAbDirectoryProperty );\n  RegisterPropertyEditor( TypeInfo( string ), TAbZipBrowser, 'TempDirectory',\n                          TAbDirectoryProperty );\n  RegisterPropertyEditor( TypeInfo( string ), TAbZipper, 'TempDirectory',\n                          TAbDirectoryProperty );\n  RegisterPropertyEditor( TypeInfo( string ), TAbUnZipper, 'TempDirectory',\n                          TAbDirectoryProperty );\n  RegisterPropertyEditor( TypeInfo( string ), TAbZipKit, 'TempDirectory',\n                          TAbDirectoryProperty );\n  RegisterPropertyEditor( TypeInfo( string ), TAbZipOutline, 'TempDirectory',\n                          TAbDirectoryProperty );\n  RegisterPropertyEditor( TypeInfo( string ), TAbZipBrowser, 'Version',\n                          TAbVersionProperty );\n  RegisterPropertyEditor( TypeInfo( string ), TAbZipper, 'Version',\n                          TAbVersionProperty );\n  RegisterPropertyEditor( TypeInfo( string ), TAbUnZipper, 'Version',\n                          TAbVersionProperty );\n  RegisterPropertyEditor( TypeInfo( string ), TAbZipKit, 'Version',\n                          TAbVersionProperty );\n  RegisterPropertyEditor( TypeInfo( string ), TAbZipOutline, 'Version',\n                          TAbVersionProperty );\n  RegisterPropertyEditor( TypeInfo( string ), TAbListView, 'Version',\n                          TAbVersionProperty );\n  RegisterPropertyEditor( TypeInfo( string ), TAbTreeView, 'Version',\n                          TAbVersionProperty );\n  RegisterPropertyEditor( TypeInfo( string ), TAbZipView, 'Version',\n                          TAbVersionProperty );\n  RegisterPropertyEditor( TypeInfo( string ), TAbMeter, 'Version',\n                          TAbVersionProperty );\n  RegisterPropertyEditor( TypeInfo( string ), TAbProgressBar, 'Version',\n                          TAbVersionProperty );\n  RegisterPropertyEditor( TypeInfo( string ), TAbMakeSelfExe, 'Version',\n                          TAbVersionProperty );\n  RegisterPropertyEditor( TypeInfo( string ), TAbZipBrowser, 'Password',\n                          TAbPasswordProperty );\n  RegisterPropertyEditor( TypeInfo( string ), TAbZipper, 'Password',\n                          TAbPasswordProperty );\n  RegisterPropertyEditor( TypeInfo( string ), TAbUnZipper, 'Password',\n                          TAbPasswordProperty );\n  RegisterPropertyEditor( TypeInfo( string ), TAbZipKit, 'Password',\n                          TAbPasswordProperty );\n  RegisterPropertyEditor( TypeInfo( string ), TAbZipOutline, 'Password',\n                          TAbPasswordProperty );\n  RegisterPropertyEditor( TypeInfo( TAbColHeadings ), TAbZipView, 'Headings',\n                          TAbColHeadingsProperty );\n  RegisterPropertyEditor( TypeInfo( string ), TAbCabBrowser, 'FileName',\n                          TAbCabNameProperty );\n  RegisterPropertyEditor( TypeInfo( string ), TAbMakeCab, 'FileName',\n                          TAbCabNameProperty );\n  RegisterPropertyEditor( TypeInfo( string ), TAbCabExtractor, 'FileName',\n                          TAbCabNameProperty );\n  RegisterPropertyEditor( TypeInfo( string ), TAbCabKit, 'FileName',\n                          TAbCabNameProperty );\n  RegisterPropertyEditor( TypeInfo( string ), TAbCabBrowser, 'BaseDirectory',\n                          TAbDirectoryProperty );\n  RegisterPropertyEditor( TypeInfo( string ), TAbMakeCab, 'BaseDirectory',\n                          TAbDirectoryProperty );\n  RegisterPropertyEditor( TypeInfo( string ), TAbCabExtractor, 'BaseDirectory',\n                          TAbDirectoryProperty );\n  RegisterPropertyEditor( TypeInfo( string ), TAbCabKit, 'BaseDirectory',\n                          TAbDirectoryProperty );\n  RegisterPropertyEditor( TypeInfo( string ), TAbCabBrowser, 'LogFile',\n                          TAbLogNameProperty );\n  RegisterPropertyEditor( TypeInfo( string ), TAbMakeCab, 'LogFile',\n                          TAbLogNameProperty );\n  RegisterPropertyEditor( TypeInfo( string ), TAbCabExtractor, 'LogFile',\n                          TAbLogNameProperty );\n  RegisterPropertyEditor( TypeInfo( string ), TAbCabKit, 'LogFile',\n                          TAbLogNameProperty );\n  RegisterPropertyEditor( TypeInfo( string ), TAbCabBrowser, 'TempDirectory',\n                          TAbDirectoryProperty );\n  RegisterPropertyEditor( TypeInfo( string ), TAbMakeCab, 'TempDirectory',\n                          TAbDirectoryProperty );\n  RegisterPropertyEditor( TypeInfo( string ), TAbCabExtractor, 'TempDirectory',\n                          TAbDirectoryProperty );\n  RegisterPropertyEditor( TypeInfo( string ), TAbCabKit, 'TempDirectory',\n                          TAbDirectoryProperty );\n  RegisterPropertyEditor( TypeInfo( string ), TAbCabBrowser, 'Version',\n                          TAbVersionProperty );\n  RegisterPropertyEditor( TypeInfo( string ), TAbMakeCab, 'Version',\n                          TAbVersionProperty );\n  RegisterPropertyEditor( TypeInfo( string ), TAbCabExtractor, 'Version',\n                          TAbVersionProperty );\n  RegisterPropertyEditor( TypeInfo( string ), TAbCabKit, 'Version',\n                          TAbVersionProperty );\n  RegisterPropertyEditor( TypeInfo( string ), TAbCabView, 'Version',\n                          TAbVersionProperty );\n  RegisterPropertyEditor( TypeInfo( TAbColHeadings ), TAbCabView, 'Headings',\n                          TAbColHeadingsProperty );\n\n  RegisterComponents( 'Abbrevia',\n                      [ TAbZipBrowser,\n                        TAbUnzipper,\n                        TAbZipper,\n                        TAbZipKit,\n                        TAbZipView,\n                        TAbZipOutline,\n                        TAbTreeView,\n                        TAbListView,\n                        TAbCabBrowser,\n                        TAbCabExtractor,\n                        TAbMakeCab,\n                        TAbCabKit,\n                        TAbCabView,\n                        TAbProgressBar,\n                        TAbMeter,\n                        TAbMakeSelfExe ]);\nend;\n\n{$IF DECLARED(IOTAAboutBoxServices)}\nvar\n  AboutBoxIndex: Integer = -1;\n\nprocedure RegisterAboutBox;\nbegin\n  SplashScreenServices.AddPluginBitmap(\n    'Abbrevia: Advanced data compression toolkit, v' + AbVersionS,\n    LoadBitmap(HInstance, 'SPLASH'));\n  AboutBoxIndex := (BorlandIDEServices as IOTAAboutBoxServices).AddPluginInfo(\n    'Abbrevia ' + AbVersionS,\n    'Abbrevia: Advanced data compression toolkit, v' + AbVersionS + sLineBreak +\n    'http://tpabbrevia.sourceforge.net/' + sLineBreak +\n    sLineBreak +\n    'Copyright (c) 1997-2011 Abbrevia development team' + sLineBreak +\n    'Covered under the Mozilla Public License (MPL) v1.1' + sLineBreak +\n    'Abbrevia includes source code from bzip2, the LZMA SDK,' + sLineBreak +\n    'Dag gren''s version of PPMd, and the WavPack SDK.',\n    LoadBitmap(HInstance, 'SPLASH'));\nend;\n\nprocedure UnregisterAboutBox;\nbegin\n  if AboutBoxIndex <> -1 then\n    (BorlandIDEServices as IOTAAboutBoxServices).RemovePluginInfo(AboutBoxIndex);\nend;\n\ninitialization\n  RegisterAboutBox;\n\nfinalization\n  UnRegisterAboutBox;\n{$IFEND}\n\nend.\n"
  },
  {
    "path": "lib/abbrevia/source/AbResString.pas",
    "content": "(* ***** BEGIN LICENSE BLOCK *****\n * Version: MPL 1.1\n *\n * The contents of this file are subject to the Mozilla Public License Version\n * 1.1 (the \"License\"); you may not use this file except in compliance with\n * the License. You may obtain a copy of the License at\n * http://www.mozilla.org/MPL/\n *\n * Software distributed under the License is distributed on an \"AS IS\" basis,\n * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License\n * for the specific language governing rights and limitations under the\n * License.\n *\n * The Original Code is TurboPower Abbrevia\n *\n * The Initial Developer of the Original Code is\n * TurboPower Software\n *\n * Portions created by the Initial Developer are Copyright (C) 1997-2002\n * the Initial Developer. All Rights Reserved.\n *\n * Contributor(s):\n * Roman Kassebaum\n *\n * ***** END LICENSE BLOCK ***** *)\n\n{*********************************************************}\n{* Abbrevia: AbResString.pas                             *}\n{*********************************************************}\n{* Abbrevia: Resource strings                            *}\n{*********************************************************}\n\nunit AbResString;\n\n{$I AbDefine.inc}\n\ninterface\n\nresourcestring\n  AbErrZipInvalidS = 'Invalid file - not a PKZip file';\n  AbZipVersionNeededS = 'Cannot extract file - newer version required';\n  AbUnknownCompressionMethodS = 'Cannot extract file - unsupported compression method';\n  AbNoExtractionMethodS = 'Cannot extract file - no extraction support provided';\n  AbInvalidPasswordS = 'Cannot extract file - invalid password';\n  AbNoInsertionMethodS = 'Cannot insert file - no insertion support provided';\n  AbInvalidFactorS = 'Invalid Reduce Factor';\n  AbDuplicateNameS = 'Cannot insert file - duplicates stored name';\n  AbUnsupportedCompressionMethodS = 'Cannot insert file - unsupported compression method';\n  AbUserAbortS = 'Process aborted by user';\n  AbArchiveBusyS = 'Archive is busy - cannot process new requests';\n  AbLastDiskRequestS = 'Insert the last disk in the spanned disk set';\n  AbDiskRequestS = 'Insert floppy';\n  AbImageRequestS = 'Image file name';\n  AbBadSpanStreamS = 'Spanned archives must be opened as file streams';\n  AbDiskNumRequestS = 'Insert disk number %d of the spanned disk set';\n  AbImageNumRequestS = 'Insert span number %d of the spanned file set';\n  AbNoOverwriteSpanStreamS = 'Cannot update an existing spanned disk set';\n  AbNoSpannedSelfExtractS = 'Cannot make a self-extracting spanned disk set';\n  AbBlankDiskS = 'Insert a blank floppy disk';\n  AbStreamFullS = 'Stream write error';\n  AbNoSuchDirectoryS = 'Directory does not exist';\n  AbInflateBlockErrorS = 'Cannot inflate block';\n  AbBadStreamTypeS = 'Invalid Stream';\n  AbTruncateErrorS = 'Error truncating Zip File';\n  AbZipBadCRCS = 'Failed CRC Check';\n  AbZipBadStubS = 'Stub must be an executable';\n  AbFileNotFoundS = 'File not found';\n  AbInvalidLFHS = 'Invalid Local File Header entry';\n  AbNoArchiveS = 'Archive does not exist - Filename is blank';\n  AbReadErrorS = 'Error reading archive';\n  AbInvalidIndexS = 'Invalid archive item index';\n  AbInvalidThresholdS = 'Invalid archive size threshold';\n  AbUnhandledFileTypeS = 'Unhandled Archive Type';\n  AbSpanningNotSupportedS = 'Spanning not supported by this Archive type';\n  AbLogCreateErrorS = 'Error creating Log File';\n  AbMoveFileErrorS = 'Error Moving File %s to %s';\n  AbFileSizeTooBigS = 'File size is too big for archive type';\n\n  AbNoCabinetDllErrorS = 'Cannot load cabinet.dll';\n  AbFCIFileOpenErrorS = 'FCI cannot open file';\n  AbFCIFileReadErrorS = 'FCI cannot read file';\n  AbFCIFileWriteErrorS = 'FCI cannot write file';\n  AbFCIFileCloseErrorS = 'FCI close file error';\n  AbFCIFileSeekErrorS = 'FCI file seek error';\n  AbFCIFileDeleteErrorS = 'FCI file delete error';\n  AbFCIAddFileErrorS = 'FCI cannot add file';\n  AbFCICreateErrorS = 'FCI cannot create context';\n  AbFCIFlushCabinetErrorS = 'FCI cannot flush cabinet';\n  AbFCIFlushFolderErrorS = 'FCI cannot flush folder';\n  AbFDICopyErrorS = 'FDI cannot enumerate files';\n  AbFDICreateErrorS = 'FDI cannot create context';\n  AbInvalidCabTemplateS = 'Invalid cab file template';\n  AbInvalidCabFileS = 'Invalid file - not a cabinet file';\n\n  AbZipStored = 'Stored';\n  AbZipShrunk = 'Shrunk';\n  AbZipReduced = 'Reduced';\n  AbZipImploded = 'Imploded';\n  AbZipTokenized = 'Tokenized';\n  AbZipDeflated = 'Deflated';\n  AbZipDeflate64 = 'Enhanced Deflation';\n  AbZipDCLImploded = 'DCL Imploded';\n  AbZipBzip2 = 'Bzip2';\n  AbZipLZMA = 'LZMA';\n  AbZipIBMTerse = 'IBM Terse';\n  AbZipLZ77 = 'IBM LZ77';\n  AbZipJPEG = 'JPEG';\n  AbZipWavPack = 'WavPack';\n  AbZipPPMd = 'PPMd';\n  AbZipUnknown = 'Unknown (%d)';\n  AbZipBestMethod = 'Best Method';\n\n  AbVersionFormatS = 'Version %s';\n  AbCompressedSizeFormatS = 'Compressed Size: %d';\n  AbUncompressedSizeFormatS = 'Uncompressed Size: %d';\n  AbCompressionMethodFormatS = 'Compression Method: %s';\n  AbCompressionRatioFormatS = 'Compression Ratio: %2.0f%%';\n  AbCRCFormatS = 'CRC: %x';\n  AbReadOnlyS = 'r';\n  AbHiddenS = 'h';\n  AbSystemS = 's';\n  AbArchivedS = 'a';\n  AbEFAFormatS = 'External File Attributes: %s';\n  AbIFAFormatS = 'File Type: %s';\n  AbTextS = 'Text';\n  AbBinaryS = 'Binary';\n  AbEncryptionFormatS = 'Encryption: %s';\n  AbEncryptedS = 'Encrypted';\n  AbNotEncryptedS = 'Not Encrypted';\n  AbUnknownS = 'Unknown';\n  AbTimeStampFormatS = 'Time Stamp: %s';\n  AbMadeByFormatS = 'Made by Version: %f';\n  AbNeededFormatS = 'Version Needed to Extract: %f';\n  AbCommentFormatS = 'Comment: %s';\n  AbDefaultExtS = '*.zip';\n  AbFilterS = 'PKZip Archives (*.zip)|*.zip|Self Extracting Archives (*.exe)|*.exe|All Files (*.*)|*.*';\n  AbFileNameTitleS = 'Select File Name';\n\n  AbOKS = 'OK';\n  AbCancelS = 'Cancel';\n  AbSelectDirectoryS = 'Select Directory';\n\n  AbEnterPasswordS = 'Enter Password';\n  AbPasswordS = '&Password';\n  AbVerifyS = '&Verify';\n\n  AbCabExtS = '*.cab';\n  AbCabFilterS = 'Cabinet Archives (*.cab)|*.CAB|All Files (*.*)|*.*';\n  AbLogExtS = '*.txt';\n  AbLogFilterS = 'Text Files (*.txt)|*.TXT|All Files (*.*)|*.*';\n  AbExeExtS = '*.exe';\n  AbExeFilterS = 'Self-Extracting Zip Files (*.exe)|*.EXE|All Files (*.*)|*.*';\n\n  AbVMSReadTooManyBytesS = 'VMS: request to read too many bytes [%d]';\n  AbVMSInvalidOriginS = 'VMS: invalid origin %d, should be 0, 1, 2';\n  AbVMSErrorOpenSwapS = 'VMS: Cannot open swap file %s';\n  AbVMSSeekFailS = 'VMS: Failed to seek in swap file %s';\n  AbVMSReadFailS = 'VMS: Failed to read %d bytes from swap file %s';\n  AbVMSWriteFailS = 'VMS: Failed to write %d bytes to swap file %s';\n  AbVMSWriteTooManyBytesS = 'VMS: request to write too many bytes [%d]';\n\n  AbBBSReadTooManyBytesS = 'BBS: request to read too many bytes [%d]';\n  AbBBSSeekOutsideBufferS = 'BBS: New position is outside the buffer';\n  AbBBSInvalidOriginS = 'BBS: Invalid Origin value';\n  AbBBSWriteTooManyBytesS = 'BBS: request to write too many bytes [%d]';\n\n  AbSWSNotEndofStreamS = 'TabSlidingWindowStream.Write: Not at end of stream';\n  AbSWSSeekFailedS = 'TabSlidingWindowStream.bsWriteChunk: seek failed';\n  AbSWSWriteFailedS = 'TabSlidingWindowStream.bsWriteChunk: write failed';\n  AbSWSInvalidOriginS = 'TabSlidingWindowStream.Seek: invalid origin';\n  AbSWSInvalidNewOriginS = 'TabSlidingWindowStream.Seek: invalid new position';\n\n  AbItemNameHeadingS = 'Name';\n  AbPackedHeadingS = 'Packed';\n  AbMethodHeadingS = 'Method';\n  AbRatioHeadingS = 'Ratio (%)';\n  AbCRCHeadingS = 'CRC32';\n  AbFileAttrHeadingS = 'Attributes';\n  AbFileFormatHeadingS = 'Format';\n  AbEncryptionHeadingS = 'Encrypted';\n  AbTimeStampHeadingS = 'Time Stamp';\n  AbFileSizeHeadingS = 'Size';\n  AbVersionMadeHeadingS = 'Version Made';\n  AbVersionNeededHeadingS = 'Version Needed';\n  AbPathHeadingS = 'Path';\n  AbPartialHeadingS = 'Partial';\n  AbExecutableHeadingS = 'Executable';\n  AbFileTypeHeadingS = 'Type';\n  AbLastModifiedHeadingS = 'Modified';\n\n  AbCabMethod0S = 'None';\n  AbCabMethod1S = 'MSZip';\n\n  AbLtAddS = ' added ';\n  AbLtDeleteS = ' deleted ';\n  AbLtExtractS = ' extracted ';\n  AbLtFreshenS = ' freshened ';\n  AbLtMoveS = ' moved ';\n  AbLtReplaceS = ' replaced ';\n  AbLtStartS = ' logging ';\n\n  AbGzipInvalidS                   = 'Invalid Gzip';\n  AbGzipBadCRCS                    = 'Bad CRC';\n  AbGzipBadFileSizeS               = 'Bad File Size';\n\n  AbTarInvalidS                    = 'Invalid Tar';\n  AbTarBadFileNameS                = 'File name too long';\n  AbTarBadLinkNameS                = 'Symbolic link path too long';\n  AbTarBadOpS                      = 'Unsupported Operation';\n\n  AbUnhandledEntityS             = 'Unhandled Entity';\n\n  { pre-defined \"operating system\" (really more FILE system) identifiers for the\n    Gzip header }\n  AbGzOsFat         = 'FAT File System (MS-DOS, OS/2, NT/Win32)';\n  AbGzOsAmiga       = 'Amiga';\n  AbGzOsVMS         = 'VMS (or OpenVMS)';\n  AbGzOsUnix        = 'Unix';\n  AbGzOsVM_CMS      = 'VM/CMS';\n  AbGzOsAtari       = 'Atari TOS';\n  AbGzOsHPFS        = 'HPFS File System (OS/2, NT)';\n  AbGzOsMacintosh   = 'Macintosh';\n  AbGzOsZ_System    = 'Z-System';\n  AbGzOsCP_M        = 'CP/M';\n  AbGzOsTOPS_20     = 'TOPS-20';\n  AbGzOsNTFS        = 'NTFS File System (NT)';\n  AbGzOsQDOS        = 'QDOS';\n  AbGzOsAcornRISCOS = 'Acorn RISCOS';\n  AbGzOsVFAT        = 'VFAT File System (Win95, NT)';\n  AbGzOsMVS         = 'MVS';\n  AbGzOsBeOS        = 'BeOS (BeBox or PowerMac)';\n  AbGzOsTandem      = 'Tandem/NSK';\n  AbGzOsTHEOS       = 'THEOS';\n  AbGzOsunknown     = 'unknown';\n  AbGzOsUndefined   = 'ID undefined by gzip';\n\n{ Compound File specific error messages }\nresourcestring\n  AbCmpndIndexOutOfBounds   = 'Index out of bounds';\n  AbCmpndBusyUpdating       = 'Compound file is busy updating';\n  AbCmpndInvalidFile        = 'Invalid compound file';\n  AbCmpndFileNotFound       = 'File/Directory not found';\n  AbCmpndFolderNotEmpty     = 'Folder not empty';\n  AbCmpndExceedsMaxFileSize = 'File size exceeds maximum allowable';\n\n\n\nimplementation\n\nend.\n"
  },
  {
    "path": "lib/abbrevia/source/AbSWStm.pas",
    "content": "(* ***** BEGIN LICENSE BLOCK *****\n * Version: MPL 1.1\n *\n * The contents of this file are subject to the Mozilla Public License Version\n * 1.1 (the \"License\"); you may not use this file except in compliance with\n * the License. You may obtain a copy of the License at\n * http://www.mozilla.org/MPL/\n *\n * Software distributed under the License is distributed on an \"AS IS\" basis,\n * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License\n * for the specific language governing rights and limitations under the\n * License.\n *\n * The Original Code is TurboPower Abbrevia\n *\n * The Initial Developer of the Original Code is\n * TurboPower Software\n *\n * Portions created by the Initial Developer are Copyright (C) 1997-2002\n * the Initial Developer. All Rights Reserved.\n *\n * Contributor(s):\n *\n * ***** END LICENSE BLOCK ***** *)\n\n{*********************************************************}\n{* ABBREVIA: AbSWStm.pas                                 *}\n{*********************************************************}\n{* ABBREVIA: TabSlidingWindowStream class                *}\n{*********************************************************}\n\nunit AbSWStm;    \n                 \n{$I AbDefine.inc}\n                 \n{Notes: The TabSlidingWindowStream class provides a simple buffered\n        stream for sliding window compression/decompression routines.\n        The sliding window stream is limited when compared with a true\n        buffered stream:\n         - it is assumed that the underlying stream is just going to\n           be written to and is initially empty\n         - the buffer is fixed in size to 40KB\n         - write operations can only occur at the end of the stream\n         - the stream can only be positioned with a certain limited\n           range \n         - we can only read up to 32KB\n         - we can only write up to 32KB\n        The stream is written as a wrapper around another stream\n        (presumably a file stream) which is used for actual reads to\n        the buffer and writes from the buffer.\n        The stream buffer is organized as five 8KB chunks in an\n        array. The last chunk is the only one used for writing, the\n        other four are a 32KB buffer for reading. As the final chunk\n        gets filled, the class will drop off the first chunk (writing\n        it to the underlying stream, and shift the other chunks in the\n        array.}  \n                 \n                 \n{Define this if you wish to see a trace of the stream usage in a file\n called C:\\SlideWin.LOG}\n{.$DEFINE DebugTrace}\n                 \ninterface        \n                 \nuses             \n  SysUtils,      \n  Classes;       \n                 \nconst            \n  abSWChunkCount = 5;\n                 \ntype             \n  TabSlidingWindowStream = class(TStream)\n    protected {private}\n      bsChunks      : array [0..pred(abSWChunkCount)] of PByteArray;\n      bsBufferStart : longint;\n      bsLastPos     : integer;\n      bsCurChunk    : integer;\n      bsPosInChunk  : integer;\n      bsPosInBuffer : longint;\n      bsSize      : Longint;    {count of bytes in stream}\n      bsDirty     : boolean;    {whether the buffer is dirty or not}\n      bsStream    : TStream;    {actual stream containing data}\n      {$IFDEF DebugTrace}\n      bsF : System.Text;\n      {$ENDIF}   \n    protected    \n      procedure bsWriteChunk(aIndex : integer);\n      procedure bsSlide;\n                 \n    public       \n      constructor Create(aStream : TStream);\n        {-create the buffered stream}\n      destructor Destroy; override;\n        {-destroy the buffered stream}\n                 \n      procedure Flush;\n        {-ensures that all dirty buffered data is flushed}\n      function Read(var Buffer; Count : Longint) : Longint; override;\n        {-read from the stream into a buffer}\n      function Seek(Offset : Longint; Origin : Word) : Longint; override;\n        {-seek to a particular point in the stream}\n      function Write(const Buffer; Count : Longint) : Longint; override;\n        {-write to the stream from a buffer}\n  end;           \n                 \nimplementation   \n                 \nconst\n  ChunkSize = 8192; {cannot be greater than MaxInt}\n\n\n{===Helper routines==================================================}\nprocedure RaiseException(const S : string);\nbegin            \n  raise Exception.Create(S);\nend;             \n{====================================================================}\n                 \n                 \n{===TabSlidingWindowStream===========================================}\nconstructor TabSlidingWindowStream.Create(aStream  : TStream);\nvar              \n  i : integer;   \nbegin            \n  inherited Create;\n  {save the actual stream}\n  bsStream := aStream;\n  {allocate the chunks-they must be set to binary zeros}\n  for i := 0 to pred(abSWChunkCount) do\n    bsChunks[i] := AllocMem(ChunkSize);\n  {set the page/buffer variables to the start of the stream; remember\n   we only write to the last chunk--the previous chunks are set to\n   binary zeros} \n  aStream.Position := 0;\n  bsSize := 0;   \n  bsBufferStart := -ChunkSize * pred(abSWChunkCount);\n  bsPosInBuffer := ChunkSize * pred(abSWChunkCount);\n  bsCurChunk := pred(abSWChunkCount);\n  bsPosInChunk := 0;\n  bsDirty := false;\n  {$IFDEF DebugTrace}\n  System.Assign(bsF, 'c:\\SlideWin.LOG');\n  if FileExists('c:\\SlideWin.LOG') then\n    System.Append(bsF)\n  else           \n    System.Rewrite(bsF);\n  writeln(bsF, '---NEW LOG---');\n  {$ENDIF}       \nend;             \n{--------}       \ndestructor TabSlidingWindowStream.Destroy;\nvar              \n  i : integer;   \nbegin            \n  {destroy the buffer, after writing it to the actual stream}\n  if bsDirty then\n    Flush;       \n  for i := 0 to pred(abSWChunkCount) do\n    if (bsChunks[i] <> nil) then\n      FreeMem(bsChunks[i], ChunkSize);\n  {$IFDEF DebugTrace}\n  System.Close(bsF);\n  {$ENDIF}       \n  {let our ancestor clean up}\n  inherited Destroy;\nend;             \n{--------}       \nprocedure TabSlidingWindowStream.bsSlide;\nvar              \n  SavePtr : PByteArray;\n  i       : integer;\nbegin            \n  {write out the first chunk}\n  bsWriteChunk(0);\n  {slide the chunks around}\n  SavePtr := bsChunks[0];\n  for i := 0 to abSWChunkCount-2 do\n    bsChunks[i] := bsChunks[i+1];\n  bsChunks[pred(abSWChunkCount)] := SavePtr;\n  {advance the buffer start position}\n  inc(bsBufferStart, ChunkSize);\n  {reset the write position}\n  bsPosInChunk := 0;\n  bsPosInBuffer := ChunkSize * pred(abSWChunkCount);\n  bsLastPos := 0;\nend;             \n{--------}       \nprocedure TabSlidingWindowStream.bsWriteChunk(aIndex : integer);\nvar              \n  SeekResult : longint;\n  BytesWrit  : longint;\n  Offset     : longint;\n  BytesToWrite : integer;\nbegin            \n  Offset := bsBufferStart + (longint(aIndex) * ChunkSize);\n  if (Offset >= 0) then begin\n    SeekResult := bsStream.Seek(Offset, 0);\n    if (SeekResult = -1) then\n      RaiseException('TabSlidingWindowStream.bsWriteChunk: seek failed');\n    if (aIndex <> pred(abSWChunkCount)) then\n      BytesToWrite := ChunkSize\n    else         \n      BytesToWrite := bsLastPos;\n    BytesWrit := bsStream.Write(bsChunks[aIndex]^, BytesToWrite);\n    if (BytesWrit <> BytesToWrite) then\n      RaiseException('TabSlidingWindowStream.bsWriteChunk: write failed');\n  end;           \nend;             \n{--------}       \nprocedure TabSlidingWindowStream.Flush;\nvar              \n  i : integer;   \nbegin            \n  if bsDirty then begin\n    for i := 0 to pred(abSWChunkCount) do\n      bsWriteChunk(i);\n    bsDirty := false;\n  end;           \nend;             \n{--------}       \nfunction TabSlidingWindowStream.Read(var Buffer; Count : Longint) : Longint;\nvar              \n  BufPtr      : PByte;\n  BytesToGo   : Longint;\n  BytesToRead : integer;\nbegin\n  BufPtr := @Buffer;\n\n  {$IFDEF DebugTrace}\n  System.Writeln(bsF, 'Read:  ', Count, ' bytes');\n  {$ENDIF}       \n  {we do not support reads greater than 32KB bytes}\n  if (Count > 32*1024) then\n    Count := 32*1024;\n                 \n  {reading is complicated by the fact we can only read in chunks of\n   ChunkSize: we need to partition out the overall read into a\n   read from part of the chunk, zero or more reads from complete\n   chunks and then a possible read from part of a chunk}\n                 \n  {calculate the actual number of bytes we can read - this depends on\n   the current position and size of the stream as well as the number\n   of bytes requested}\n  BytesToGo := Count;\n  if (bsSize < (bsBufferStart + bsPosInBuffer + Count)) then\n    BytesToGo := bsSize - (bsBufferStart + bsPosInBuffer);\n  if (BytesToGo <= 0) then begin\n    Result := 0; \n    Exit;        \n  end;           \n  {remember to return the result of our calculation}\n  Result := BytesToGo;\n                 \n  {calculate the number of bytes we can read prior to the loop}\n  BytesToRead := ChunkSize - bsPosInChunk;\n  if (BytesToRead > BytesToGo) then\n    BytesToRead := BytesToGo;\n  {copy from the stream buffer to the caller's buffer}\n  if (BytesToRead = 1) then\n    BufPtr^ := bsChunks[bsCurChunk]^[bsPosInChunk]\n  else           \n    Move(bsChunks[bsCurChunk]^[bsPosInChunk], BufPtr^, BytesToRead);\n  {calculate the number of bytes still to read}\n  dec(BytesToGo, BytesToRead);\n                 \n  {while we have bytes to read, read them}\n  while (BytesToGo > 0) do begin\n    {advance the pointer for the caller's buffer}\n    inc(BufPtr, BytesToRead);\n    {as we've exhausted this chunk, advance to the next}\n    inc(bsCurChunk);\n    bsPosInChunk := 0;\n    {calculate the number of bytes we can read in this cycle}\n    BytesToRead := ChunkSize;\n    if (BytesToRead > BytesToGo) then\n      BytesToRead := BytesToGo;\n    {copy from the stream buffer to the caller's buffer}\n    Move(bsChunks[bsCurChunk]^, BufPtr^, BytesToRead);\n    {calculate the number of bytes still to read}\n    dec(BytesToGo, BytesToRead);\n  end;           \n  {remember our new position}\n  inc(bsPosInChunk, BytesToRead);\nend;             \n{--------}       \nfunction TabSlidingWindowStream.Seek(Offset : Longint;\n                                     Origin : Word) : Longint;\n{$IFDEF DebugTrace}\nconst            \n  OriginStr : array [0..2] of string[7] = ('start', 'current', 'end');\n{$ENDIF}         \nvar              \n  NewPos       : Longint;\nbegin            \n  {$IFDEF DebugTrace}\n  System.Writeln(bsF, 'Seek:  ', Offset, ' bytes from ', OriginStr[Origin]);\n  {$ENDIF}       \n  {calculate the new position}\n  case Origin of \n    soFromBeginning : NewPos := Offset;\n    soFromCurrent   : NewPos := bsBufferStart + bsPosInBuffer + Offset;\n    soFromEnd       : NewPos := bsSize + Offset;\n  else           \n    NewPos := 0; \n    RaiseException('TabSlidingWindowStream.Seek: invalid origin');\n  end;           \n  {if the new position is invalid, say so}\n  if (NewPos < bsBufferStart) or (NewPos > bsSize) then\n    RaiseException('TabSlidingWindowStream.Seek: invalid new position');\n  {calculate the chunk number and the position in buffer & chunk}\n  bsPosInBuffer := NewPos - bsBufferStart;\n  bsCurChunk := bsPosInBuffer div ChunkSize;\n  bsPosInChunk := bsPosInBuffer mod ChunkSize;\n  {return the new position}\n  Result := NewPos;\nend;             \n{--------}       \nfunction TabSlidingWindowStream.Write(const Buffer; Count : Longint) : Longint;\nvar              \n  BufPtr      : PByte;\n  BytesToGo   : Longint;\n  BytesToWrite: integer;\nbegin\n  BufPtr := @Buffer;\n\n  {$IFDEF DebugTrace}\n  System.Writeln(bsF, 'Write: ', Count, ' bytes');\n  {$ENDIF}       \n  {we ONLY write at the end of the stream}\n  if ((bsBufferStart + bsPosInBuffer) <> bsSize) then\n    RaiseException('TabSlidingWindowStream.Write: Not at end of stream');\n                 \n  {we do not support writes greater than 32KB bytes}\n  if (Count > 32*1024) then\n    Count := 32*1024;\n                 \n  {writing is complicated by the fact we write in chunks of Chunksize\n   bytes: we need to partition out the overall write into a write\n   to part of the chunk, zero or more writes to complete chunks and\n   then a possible write to part of a chunk; every time we fill a\n   chunk we have toi slide the buffer}\n                 \n  {when we write to this stream we always assume that we can write the\n   requested number of bytes: if we can't (eg, the disk is full) we'll\n   get an exception somewhere eventually}\n  BytesToGo := Count;\n  {remember to return the result of our calculation}\n  Result := BytesToGo;\n                 \n  {calculate the number of bytes we can write prior to the loop}\n  BytesToWrite := ChunkSize - bsPosInChunk;\n  if (BytesToWrite > BytesToGo) then\n    BytesToWrite := BytesToGo;\n  {copy from the caller's buffer to the stream buffer}\n  if (BytesToWrite = 1) then\n    bsChunks[pred(abSWChunkCount)]^[bsPosInChunk] := BufPtr^\n  else           \n    Move(BufPtr^,\n         bsChunks[pred(abSWChunkCount)]^[bsPosInChunk],\n         BytesToWrite);\n  {mark our buffer as requiring a save to the actual stream}\n  bsDirty := true;\n  {calculate the number of bytes still to write}\n  dec(BytesToGo, BytesToWrite);\n                 \n  {while we have bytes to write, write them}\n  while (BytesToGo > 0) do begin\n    {slide the buffer}\n    bsSlide;     \n    {advance the pointer for the caller's buffer}\n    inc(BufPtr, BytesToWrite);\n    {calculate the number of bytes we can write in this cycle}\n    BytesToWrite := ChunkSize;\n    if (BytesToWrite > BytesToGo) then\n      BytesToWrite := BytesToGo;\n    {copy from the caller's buffer to our buffer}\n    Move(BufPtr^,\n         bsChunks[pred(abSWChunkCount)]^,\n         BytesToWrite);\n    {calculate the number of bytes still to write}\n    dec(BytesToGo, BytesToWrite);\n  end;           \n  {remember our new position}\n  inc(bsPosInChunk, BytesToWrite);\n  bsPosInBuffer := (longint(ChunkSize) * pred(abSWChunkCount)) + bsPosInChunk;\n  bsLastPos := bsPosInChunk;\n  {make sure the stream size is correct}\n  inc(bsSize, Result);\n  {if we're at the end of the chunk, slide the buffer ready for next\n   time we write}\n  if (bsPosInChunk = ChunkSize) then\n    bsSlide;     \nend;             \n{====================================================================}\n                 \nend.             \n"
  },
  {
    "path": "lib/abbrevia/source/AbSelfEx.pas",
    "content": "(* ***** BEGIN LICENSE BLOCK *****\n * Version: MPL 1.1\n *\n * The contents of this file are subject to the Mozilla Public License Version\n * 1.1 (the \"License\"); you may not use this file except in compliance with\n * the License. You may obtain a copy of the License at\n * http://www.mozilla.org/MPL/\n *\n * Software distributed under the License is distributed on an \"AS IS\" basis,\n * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License\n * for the specific language governing rights and limitations under the\n * License.\n *\n * The Original Code is TurboPower Abbrevia\n *\n * The Initial Developer of the Original Code is\n * TurboPower Software\n *\n * Portions created by the Initial Developer are Copyright (C) 1997-2002\n * the Initial Developer. All Rights Reserved.\n *\n * Contributor(s):\n *\n * ***** END LICENSE BLOCK ***** *)\n\n{*********************************************************}\n{* ABBREVIA: AbSelfEx.pas                                *}\n{*********************************************************}\n{* ABBREVIA: Component for building self-extracting zips *}\n{*********************************************************}\n\nunit AbSelfEx;\n\n{$I AbDefine.inc}\n\ninterface\n\nuses\n  Classes,\n  AbBase;\n\ntype\n  TAbGetFileEvent = procedure(Sender : TObject; var aFilename : string;\n                              var Abort : Boolean) of object;\n\ntype\n  TAbMakeSelfExe = class(TAbBaseComponent)\n  protected {private}\n    FStubExe      : string;\n    FZipFile      : string;\n    FSelfExe      : string;\n    FStubStream   : TFileStream;\n    FZipStream    : TFileStream;\n    FSelfStream    : TFileStream;\n    FOnGetStubExe : TAbGetFileEvent;\n    FOnGetZipFile : TAbGetFileEvent;\n\n    procedure DoGetStubExe(var Abort : Boolean);\n    procedure DoGetZipFile(var Abort : Boolean);\n\n  public\n    function Execute : Boolean;\n\n  published\n    property SelfExe : string\n      read FSelfExe\n      write FSelfExe;\n    property StubExe : string\n      read FStubExe\n      write FStubExe;\n    property ZipFile : string\n      read FZipFile\n      write FZipFile;\n    property OnGetStubExe : TAbGetFileEvent\n      read FOnGetStubExe\n      write FOnGetStubExe;\n    property OnGetZipFile : TAbGetFileEvent\n      read FOnGetZipFile\n      write FOnGetZipFile;\n    property Version;\n  end;\n\n\nimplementation\n\nuses\n  SysUtils,\n{$IFDEF LibcAPI}\n  Libc,\n{$ENDIF}\n  AbExcept, AbZipTyp;\n\n{ -------------------------------------------------------------------------- }\nfunction TAbMakeSelfExe.Execute : Boolean;\nvar\n  Abort : Boolean;\nbegin\n  Abort := False;\n  if (FStubExe = '') then\n    DoGetStubExe(Abort);\n  if Abort then\n    raise EAbUserAbort.Create;\n  if not FileExists(FStubExe) then\n    raise EAbFileNotFound.Create;\n  if (FZipFile = '') then\n    DoGetZipFile(Abort);\n  if Abort then\n    raise EAbUserAbort.Create;\n  if not FileExists(FZipFile) then\n    raise EAbFileNotFound.Create;\n\n  FStubStream := TFileStream.Create(FStubExe, fmOpenRead or fmShareDenyWrite);\n  FZipStream := TFileStream.Create(FZipFile, fmOpenRead or fmShareDenyWrite);\n  if (FSelfExe = '') then\n    FSelfExe := ChangeFileExt(FZipFile, '.exe');\n  FSelfStream := TFileStream.Create(FSelfExe, fmCreate or fmShareExclusive);\n  try\n    MakeSelfExtracting(FStubStream, FZipStream, FSelfStream);\n    Result := True;\n  finally\n    FStubStream.Free;\n    FZipStream.Free;\n    FSelfStream.Free;\n  end;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbMakeSelfExe.DoGetStubExe(var Abort: Boolean);\nbegin\n  if Assigned(FOnGetStubExe) then\n    FOnGetStubExe(Self, FStubExe, Abort);\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbMakeSelfExe.DoGetZipFile(var Abort : Boolean);\nbegin\n  if Assigned(FOnGetZipFile) then\n    FOnGetZipFile(Self, FZipFile, Abort);\nend;\n{ -------------------------------------------------------------------------- }\n\nend.\n"
  },
  {
    "path": "lib/abbrevia/source/AbSpanSt.pas",
    "content": "(* ***** BEGIN LICENSE BLOCK *****\n * Version: MPL 1.1\n *\n * The contents of this file are subject to the Mozilla Public License Version\n * 1.1 (the \"License\"); you may not use this file except in compliance with\n * the License. You may obtain a copy of the License at\n * http://www.mozilla.org/MPL/\n *\n * Software distributed under the License is distributed on an \"AS IS\" basis,\n * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License\n * for the specific language governing rights and limitations under the\n * License.\n *\n * The Original Code is TurboPower Abbrevia\n *\n * The Initial Developer of the Original Code is\n * TurboPower Software\n *\n * Portions created by the Initial Developer are Copyright (C) 1997-2002\n * the Initial Developer. All Rights Reserved.\n *\n * Contributor(s):\n * Craig Peterson <capeterson@users.sourceforge.net>\n *\n * ***** END LICENSE BLOCK ***** *)\n\n{*********************************************************}\n{* ABBREVIA: AbSpanSt.pas                                *}\n{*********************************************************}\n{* ABBREVIA: TAbSpan*Stream Classes                      *}\n{*********************************************************}\n{* Streams to handle splitting ZIP files or spanning     *}\n{* them to diskettes                                     *}\n{*********************************************************}\n\nunit AbSpanSt;\n\n{$I AbDefine.inc}\n\ninterface\n\nuses\n  Classes,\n  AbArcTyp;\n\ntype\n{ TAbSpanBaseStream interface ============================================== }\n  TAbSpanBaseStream = class(TStream)\n  protected {private}\n    FArchiveName: string;\n\n    FOnRequestImage: TAbRequestImageEvent;\n\n  protected {methods}\n    function GetImageName( ImageNumber: Integer ): string;\n\n  public {methods}\n    constructor Create( const ArchiveName: string );\n\n  public {events}\n    property OnRequestImage : TAbRequestImageEvent\n      read FOnRequestImage\n      write FOnRequestImage;\n  end;\n\n{ TAbSpanReadStream interface ============================================== }\n  TAbSpanReadStream = class(TAbSpanBaseStream)\n  protected {private}\n    FCurrentImage: LongWord;\n    FIsSplit: Boolean;\n    FLastImage: LongWord;\n    FStream: TStream;\n\n    FOnRequestNthDisk : TAbRequestNthDiskEvent;\n\n  protected {methods}\n    procedure GotoImage( ImageNumber: Integer );\n    procedure SetOnRequestImage(Value: TAbRequestImageEvent);\n\n  public {methods}\n    constructor Create( const ArchiveName: string; CurrentImage: LongWord;\n      Stream: TStream );\n    destructor Destroy;\n      override;\n    function Read(var Buffer; Count: Longint): Longint;\n      override;\n    function Write(const Buffer; Count: Longint): Longint;\n      override;\n    function Seek(const Offset: Int64; Origin: TSeekOrigin): Int64;\n      override;\n    procedure SeekImage( Image: LongWord; const Offset: Int64);\n\n  public {events}\n    property OnRequestImage\n      write SetOnRequestImage;\n    property OnRequestNthDisk : TAbRequestNthDiskEvent\n      read FOnRequestNthDisk\n      write FOnRequestNthDisk;\n  end;\n\n{ TAbSpanWriteStream interface ============================================= }\n  TAbSpanWriteStream = class(TAbSpanBaseStream)\n  protected {private}\n    FCurrentImage: LongWord;\n    FImageSize: Int64;\n    FStream: TStream;\n    FThreshold: Int64;\n\n    FOnRequestBlankDisk : TAbRequestDiskEvent;\n\n  protected {methods}\n    procedure NewImage;\n\n  public {methods}\n    constructor Create( const ArchiveName: string; Stream: TStream;\n      Threshold: Int64 );\n    destructor Destroy;\n      override;\n    function Read(var Buffer; Count: Longint): Longint;\n      override;\n    function Write(const Buffer; Count: Longint): Longint;\n      override;\n    function WriteUnspanned(const Buffer; Count: Longint;\n      FailOnSpan: Boolean = False): Boolean;\n    function Seek(const Offset: Int64; Origin: TSeekOrigin): Int64;\n      override;\n    function ReleaseStream: TStream;\n\n  public {properties}\n    property CurrentImage : LongWord\n      read FCurrentImage;\n\n  public {events}\n    property OnRequestBlankDisk : TAbRequestDiskEvent\n      read FOnRequestBlankDisk\n      write FOnRequestBlankDisk;\n  end;\n\nimplementation\n\nuses\n{$IFDEF MSWINDOWS}\n  Windows,\n{$ENDIF}\n  Math, RTLConsts, SysUtils, AbUtils, AbExcept;\n\n\n{============================================================================}\n{ TAbSpanBaseStream implementation ========================================= }\nconstructor TAbSpanBaseStream.Create( const ArchiveName: string );\nbegin\n  inherited Create;\n  FArchiveName := ArchiveName;\nend;\n{------------------------------------------------------------------------------}\nfunction TAbSpanBaseStream.GetImageName( ImageNumber: Integer ): string;\nvar\n  Abort : Boolean;\n  Ext : string;\nbegin\n  {generate default name}\n  Ext := ExtractFileExt(FArchiveName);\n  if (Length(Ext) < 2) then\n    Ext := '.' + Format('%.2d', [ImageNumber])\n  else\n    Ext := Ext[1] + Ext[2] + Format('%.2d', [ImageNumber]);\n  Result := ChangeFileExt(FArchiveName, Ext);\n  {call event}\n  if Assigned(FOnRequestImage) then begin\n    Abort := False;\n    FOnRequestImage(Self, ImageNumber, Result, Abort);\n    if Abort then\n      raise EAbUserAbort.Create;\n  end;\nend;\n\n{============================================================================}\n{ TAbSpanReadStream implementation ========================================= }\nconstructor TAbSpanReadStream.Create( const ArchiveName: string;\n  CurrentImage: LongWord; Stream: TStream );\nbegin\n  inherited Create(ArchiveName);\n  FCurrentImage := CurrentImage;\n  FIsSplit := FileExists(GetImageName(1)) or not AbDriveIsRemovable(ArchiveName);\n  FLastImage := CurrentImage;\n  FStream := Stream;\nend;\n{------------------------------------------------------------------------------}\ndestructor TAbSpanReadStream.Destroy;\nbegin\n  FreeAndNil(FStream);\n  inherited;\nend;\n{------------------------------------------------------------------------------}\nprocedure TAbSpanReadStream.GotoImage( ImageNumber: Integer );\nvar\n  Abort: Boolean;\n  ImageName: string;\nbegin\n  { switch to the requested image.  ImageNumber is passed in as 0-based to\n    match the zip spec, but all of the callbacks receive 1-based values. }\n  FreeAndNil(FStream);\n  FCurrentImage := ImageNumber;\n  Inc(ImageNumber);\n  ImageName := FArchiveName;\n  if FIsSplit then begin\n    { the last image uses the original filename }\n    if FCurrentImage <> FLastImage then\n      ImageName := GetImageName(ImageNumber)\n  end\n  else if Assigned(FOnRequestNthDisk) then begin\n    Abort := False;\n    repeat\n      FOnRequestNthDisk(Self, ImageNumber, Abort);\n      if Abort then\n        raise EAbUserAbort.Create;\n    until AbGetDriveFreeSpace(ImageName) <> -1;\n  end\n  else\n    raise EAbUserAbort.Create;\n  FStream := TFileStream.Create(ImageName, fmOpenRead or fmShareDenyWrite);\nend;\n{------------------------------------------------------------------------------}\nfunction TAbSpanReadStream.Read(var Buffer; Count: Longint): Longint;\nvar\n  BytesRead, BytesLeft: LongInt;\n  PBuf: PByte;\nbegin\n  { read until the buffer's full, switching images if necessary }\n  Result := 0;\n  if FStream = nil then\n    Exit;\n  PBuf := @Buffer;\n  BytesLeft := Count;\n  while Result < Count do begin\n    BytesRead := FStream.Read(PBuf^, BytesLeft);\n    Inc(Result, BytesRead);\n    Inc(PBuf, BytesRead);\n    Dec(BytesLeft, BytesRead);\n    if BytesRead < BytesLeft then begin\n      if FCurrentImage <> FLastImage then\n        GotoImage(FCurrentImage + 1)\n      else\n        Break;\n    end;\n  end;\nend;\n{------------------------------------------------------------------------------}\nfunction TAbSpanReadStream.Write(const Buffer; Count: Longint): Longint;\nbegin\n  raise EAbException.Create('TAbSpanReadStream.Write unsupported');\nend;\n{------------------------------------------------------------------------------}\nfunction TAbSpanReadStream.Seek(const Offset: Int64; Origin: TSeekOrigin): Int64;\nbegin\n  if FStream = nil then\n    Result := 0\n  else if (Offset = 0) and (Origin = soCurrent) then\n    Result := FStream.Position\n  else\n    raise EAbException.Create('TAbSpanReadStream.Seek unsupported');\nend;\n{------------------------------------------------------------------------------}\nprocedure TAbSpanReadStream.SeekImage( Image: LongWord; const Offset: Int64);\nbegin\n  if FStream = nil then\n    Exit;\n  if FCurrentImage <> Image then\n    GotoImage(Image);\n  FStream.Position := Offset;\nend;\n{------------------------------------------------------------------------------}\nprocedure TAbSpanReadStream.SetOnRequestImage(Value: TAbRequestImageEvent);\nbegin\n  FOnRequestImage := Value;\n  FIsSplit := FileExists(GetImageName(1)) or not AbDriveIsRemovable(FArchiveName);\nend;\n\n{============================================================================}\n{ TAbSpanWriteStream implementation ======================================== }\nconstructor TAbSpanWriteStream.Create( const ArchiveName: string;\n  Stream: TStream; Threshold: Int64 );\nbegin\n  inherited Create(ArchiveName);\n  FCurrentImage := 0;\n  FStream := Stream;\n  FThreshold := Threshold;\nend;\n{------------------------------------------------------------------------------}\ndestructor TAbSpanWriteStream.Destroy;\nbegin\n  FStream.Free;\n  inherited;\nend;\n{------------------------------------------------------------------------------}\nprocedure TAbSpanWriteStream.NewImage;\nvar\n  Abort: Boolean;\nbegin\n  { start a new span or blank disk.  FCurrentImage is 0-based to match the zip\n    spec, but all of the callbacks receive 1-based values. }\n  FreeAndNil(FStream);\n  Inc(FCurrentImage);\n  if FThreshold > 0 then\n    RenameFile(FArchiveName, GetImageName(FCurrentImage))\n  else begin\n    if Assigned(FOnRequestBlankDisk) then begin\n      Abort := False;\n      repeat\n        FOnRequestBlankDisk(Self, Abort);\n        if Abort then\n          raise EAbUserAbort.Create;\n      until AbGetDriveFreeSpace(FArchiveName) <> -1;\n    end\n    else\n      raise EAbUserAbort.Create;\n    AbSetSpanVolumeLabel(AbDrive(FArchiveName), FCurrentImage);\n  end;\n  FStream := TFileStream.Create(FArchiveName, fmCreate or fmShareDenyWrite);\n  FImageSize := 0;\nend;\n{------------------------------------------------------------------------------}\nfunction TAbSpanWriteStream.Read(var Buffer; Count: Longint): Longint;\nbegin\n  raise EAbException.Create('TAbSpanWriteStream.Read unsupported');\nend;\n{------------------------------------------------------------------------------}\nfunction TAbSpanWriteStream.Write(const Buffer; Count: Longint): Longint;\nvar\n  BytesWritten, BytesLeft: LongInt;\n  PBuf: PByte;\nbegin\n  { write until the buffer is done, starting new spans if necessary }\n  Result := 0;\n  if FStream = nil then\n    Exit;\n  PBuf := @Buffer;\n  BytesLeft := Count;\n  while Result < Count do begin\n    if FThreshold > 0 then\n      BytesWritten := FStream.Write(PBuf^, Min(BytesLeft, FThreshold - FImageSize))\n    else\n      BytesWritten := FStream.Write(PBuf^, BytesLeft);\n    Inc(FImageSize, BytesWritten);\n    Inc(Result, BytesWritten);\n    Inc(PBuf, BytesWritten);\n    Dec(BytesLeft, BytesWritten);\n    if BytesWritten < BytesLeft then\n      NewImage;\n  end;\nend;\n{------------------------------------------------------------------------------}\nfunction TAbSpanWriteStream.WriteUnspanned(const Buffer; Count: Longint;\n  FailOnSpan: Boolean = False): Boolean;\nvar\n  BytesWritten: LongInt;\nbegin\n  { write as a contiguous block, starting a new span if there isn't room.\n    FailOnSpan (and result = false) can be used to update data before it's\n    written again }\n  if FStream = nil then\n    raise EWriteError.Create(SWriteError);\n  if (FThreshold > 0) and (FThreshold - FImageSize < Count) then\n    BytesWritten := 0\n  else\n    BytesWritten := FStream.Write(Buffer, Count);\n  if BytesWritten < Count then begin\n    if BytesWritten > 0 then\n      FStream.Size := FStream.Size - BytesWritten;\n    NewImage;\n    if FailOnSpan then\n      BytesWritten := 0\n    else begin\n      BytesWritten := Count;\n      FStream.WriteBuffer(Buffer, Count);\n    end;\n  end;\n  Inc(FImageSize, BytesWritten);\n  Result := (BytesWritten = Count);\nend;\n{------------------------------------------------------------------------------}\nfunction TAbSpanWriteStream.Seek(const Offset: Int64; Origin: TSeekOrigin): Int64;\nbegin\n  if FStream = nil then\n    Result := 0\n  else if (Offset = 0) and (Origin = soCurrent) then\n    Result := FStream.Position\n  else\n    raise EAbException.Create('TAbSpanWriteStream.Seek unsupported');\nend;\n{------------------------------------------------------------------------------}\nfunction TAbSpanWriteStream.ReleaseStream: TStream;\nbegin\n  Result := FStream;\n  FStream := nil;\nend;\n{------------------------------------------------------------------------------}\nend.\n"
  },
  {
    "path": "lib/abbrevia/source/AbTarTyp.pas",
    "content": "(* ***** BEGIN LICENSE BLOCK *****\n * Version: MPL 1.1\n *\n * The contents of this file are subject to the Mozilla Public License Version\n * 1.1 (the \"License\"); you may not use this file except in compliance with\n * the License. You may obtain a copy of the License at\n * http://www.mozilla.org/MPL/\n *\n * Software distributed under the License is distributed on an \"AS IS\" basis,\n * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License\n * for the specific language governing rights and limitations under the\n * License.\n *\n * The Original Code is TurboPower Abbrevia\n *\n * The Initial Developer of the Original Code is\n * TurboPower Software\n *\n * Portions created by the Initial Developer are Copyright (C) 1997-2002\n * the Initial Developer. All Rights Reserved.\n *\n * Contributor(s):\n * Joel Haynie\n * Craig Peterson <capeterson@users.sourceforge.net>\n *\n * ***** END LICENSE BLOCK ***** *)\n\n{*********************************************************}\n{* ABBREVIA: AbTarTyp.pas                                *}\n{*********************************************************}\n{* ABBREVIA: TAbTarArchive, TAbTarItem classes           *}\n{*********************************************************}\n{* Misc. constants, types, and routines for working      *}\n{* with Tar files                                        *}\n{*********************************************************}\n\nunit AbTarTyp;\n\n{$I AbDefine.inc}\n\ninterface\n\nuses\n  Classes,\n  AbUtils, AbArcTyp;\n\nconst\n  AB_TAR_RECORDSIZE  = 512; {Note: SizeOf(TAbTarHeaderRec) = AB_TAR_RECORDSIZE}\n  AB_TAR_NAMESIZE    = 100;\n  AB_TAR_V7_EMPTY_SIZE = 167;\n  AB_TAR_USTAR_PREFIX_SIZE = 155;\n  AB_TAR_STAR_PREFIX_SIZE = 131;\n  AB_TAR_OLD_GNU_EMPTY1_SIZE = 5;\n  AB_TAR_OLD_GNU_SPARSE_SIZE = 96;\n  AB_TAR_OLD_GNU_EMPTY2_SIZE = 17;\n  AB_TAR_SIZE_AFTER_STDHDR = 167;\n  AB_TAR_TUSRNAMELEN = 32;\n  AB_TAR_TGRPNAMELEN = 32;\n\n\n{ The checksum field is filled with this while the checksum is computed. }\n  AB_TAR_CHKBLANKS     = '        ';  { 8 blank spaces(#20), no null }\n  AB_TAR_L_HDR_NAME    = '././@LongLink'; { As seen in the GNU File Examples}\n  AB_TAR_L_HDR_USR_NAME='root';       { On Cygwin this is #0, Redhat it is 'root' }\n  AB_TAR_L_HDR_GRP_NAME='root';       { Same on all OS's }\n  AB_TAR_L_HDR_ARR8_0  ='0000000'#0;  { 7 zeros and one null }\n  AB_TAR_L_HDR_ARR12_0 ='00000000000'#0;{ 11 zeros and one null }\n  AB_TAR_MAGIC_VAL     = 'ustar'#0;   { 5 chars & a nul }\n  AB_TAR_MAGIC_VER     = '00';        { 2 chars }\n  AB_TAR_MAGIC_GNUOLD  = 'ustar  '#0; { 7 chars & a null }\n  AB_TAR_MAGIC_V7_NONE = #0#0#0#0#0#0#0#0;{ 8, #0 }\n\n{ The linkflag defines the type of file(FH), and Meta Data about File(MDH) }\n  AB_TAR_LF_OLDNORMAL = #0;   {  FH, Normal disk file, Unix compatible } { Historically used for V7 }\n  AB_TAR_LF_NORMAL    = '0';  {  FH, Normal disk file }\n  AB_TAR_LF_LINK      = '1';  {  FH, Link to previously archived file }\n  AB_TAR_LF_SYMLINK   = '2';  {  FH, Symbolic(soft) link }\n  AB_TAR_LF_CHR       = '3';  {  FH, Character special file }{ Used for device nodes, Conditionally compiled into GNUTAR }\n  AB_TAR_LF_BLK       = '4';  {  FH, Block special file }{ Used for device nodes, Conditionally compiled into GNUTAR }\n  AB_TAR_LF_DIR       = '5';  {  FH, Directory, Zero size File }\n  AB_TAR_LF_FIFO      = '6';  {  FH, FIFO special file }{ Used for fifo files(pipe like), Conditionally complied into GNUTAR }\n  AB_TAR_LF_CONTIG    = '7';  {  FH, Contiguous file } { Normal File, but All blocks should be contiguos on the disk }\n  AB_TAR_LF_XHDR      = 'x';  { MDH, POSIX, Next File has Extended Header }\n  AB_TAR_LF_XGL       = 'g';  { MDH, POSIX, Global Extended Header }\n  AB_TAR_LF_DUMPDIR   = 'D';  {  FH, Extra GNU, Dump Directory} { Generated Dump of Files in a directory, has a size }\n  AB_TAR_LF_LONGLINK  = 'K';  { MDH, Extra GNU, Next File has Long LinkName}\n  AB_TAR_LF_LONGNAME  = 'L';  { MDH, Extra GNU, Next File has Long Name}\n  AB_TAR_LF_MULTIVOL  = 'M';  {  FH, Extra GNU, MultiVolume File Cont.}{ End of a file that spans multiple TARs }\n  AB_TAR_LF_SPARSE    = 'S';  {  FH, Extra GNU, Sparse File Cont.}\n  AB_TAR_LF_VOLHDR    = 'V';  {  FH, Extra GNU, File is Volume Header }\n  AB_TAR_LF_EXHDR     = 'X';  { MDH, Extra GNU, Solaris Extended Header }\n  { The only questionable MetaData type is 'V', file or meta-data? will treat as file header }\n  AB_SUPPORTED_F_HEADERS   = [AB_TAR_LF_OLDNORMAL, AB_TAR_LF_NORMAL, AB_TAR_LF_LINK,\n                              AB_TAR_LF_SYMLINK, AB_TAR_LF_DIR];\n  AB_UNSUPPORTED_F_HEADERS = [AB_TAR_LF_CHR, AB_TAR_LF_BLK, AB_TAR_LF_FIFO,\n                              AB_TAR_LF_CONTIG, AB_TAR_LF_DUMPDIR, AB_TAR_LF_MULTIVOL,\n                              AB_TAR_LF_SPARSE, AB_TAR_LF_VOLHDR];\n  AB_SUPPORTED_MD_HEADERS  = [AB_TAR_LF_LONGNAME, AB_TAR_LF_LONGLINK];\n  AB_UNSUPPORTED_MD_HEADERS= [AB_TAR_LF_XHDR, AB_TAR_LF_XGL, AB_TAR_LF_EXHDR];\n  AB_GNU_MD_HEADERS        = [AB_TAR_LF_LONGLINK, AB_TAR_LF_LONGNAME]; { If present then OLD_/GNU_FORMAT }\n  AB_PAX_MD_HEADERS        = [AB_TAR_LF_XHDR, AB_TAR_LF_XGL]; { If present then POSIX_FORMAT }\n  AB_IGNORE_SIZE_HEADERS   = [AB_TAR_LF_LINK, AB_TAR_LF_SYMLINK, AB_TAR_LF_CHR,\n                              AB_TAR_LF_BLK, AB_TAR_LF_DIR, AB_TAR_LF_FIFO];\n{ The rest of the Chars are unsupported and unknown types Treat those headers as File types }\n{ Further link types may be defined later. }\n\n{ Bits used in the mode field - values in octal }\n  AB_TAR_TSUID   = $0800;   { Set UID on execution }\n  AB_TAR_TSGID   = $0400;   { Set GID on execution }\n  AB_TAR_TSVTX   = $0200;   { Save text (sticky bit) }\n\n\ntype\n  Arr8  = array [0..7] of AnsiChar;\n  Arr12 = array [0..11] of AnsiChar;\n  Arr12B = array[0..11] of Byte;\n  ArrName = array [0..AB_TAR_NAMESIZE-1] of AnsiChar;\n  TAbTarHeaderFormat = (UNKNOWN_FORMAT, V7_FORMAT, OLDGNU_FORMAT, GNU_FORMAT,\n                        USTAR_FORMAT, STAR_FORMAT, POSIX_FORMAT);\n  TAbTarItemType = (SUPPORTED_ITEM, UNSUPPORTED_ITEM, UNKNOWN_ITEM);\n  TAbTarHeaderType = (FILE_HEADER, META_DATA_HEADER, MD_DATA_HEADER, UNKNOWN_HEADER);\n  TAbTarMagicType = (GNU_OLD, NORMAL);\n  TAbTarMagicRec = packed record\n    case TAbTarMagicType of\n      GNU_OLD: (gnuOld : array[0..7] of AnsiChar); { Old GNU magic: (Magic.gnuOld) }\n      NORMAL : (value  : array[0..5] of AnsiChar;  {   Magic value: (Magic.value)}\n                version: array[0..1] of AnsiChar); {       Version: (Magic.version) }\n  end;\n\n{ Notes from GNU Tar & POSIX Spec.: }\n{All the first 345 bytes are the same. }\n{   \"USTAR_header\": Prefix(155): 345-499,\n                    empty(12): 500-511 }\n{ \"old_gnu_header\": atime(12): 345-356,\n                    ctime(12): 357-368,\n                    offset(12): 369-380,\n                    longnames(4): 381-384,\n                    empty(1): 385,\n                    sparse structs(4x(12+12)=96): 386-481,\n                    isextended(1): 482,\n                    realsize(12): 483-494,\n                    empty(16): 495-511 }\n{    \"star_header\": Prefix(131): 345-475,\n                    atime(12): 476-487,\n                    ctime(12): 488-499,\n                    empty(12): 500-511 }\n{ \"star_in_header\": prefix(1): 345,\n                    empty(9): 346-354,\n                    isextended(1): 355,\n                    sparse structs(4x(12+12)=96): 356-451,\n                    realsize(12): 452-463,\n                    offset(12): 464-475,\n                    atime(12): 476-487,\n                    ctime(12): 488-499,\n                    empty(8): 500-507,\n                    xmagic(4): 508-511 }\n{  \"sparse_header\": These two structs are the same, and they are Meta data about file. }\n{\"star_ext_header\": sparse structs(21x(12+12)=504): 0-503,\n                    isextended(1): 504 }\n{POSIX(PAX) extended header: is a buffer packed with content of this form:\n     This if from the POSIX spec. References the C printf command string.\n     \"%d %s=%s\\n\".  Then they are simply concatenated. }\n    { PAX Extended Header Keywords: }\n    { 'atime', 'charset', 'comment', 'ctime', 'gid', 'gname', 'linkpath', 'mtime', 'path',\n      'realtime.', 'security.', 'size', 'uid', 'uname' }\n    { GNU Added PAX Extended Header Keywords: }\n    { 'GNU.sparse.name', 'GNU.sparse.major', 'GNU.sparse.minor',\n      'GNU.sparse.realsize', 'GNU.sparse.numblocks', 'GNU.sparse.size',\n      'GNU.sparse.offset', 'GNU.sparse.numbytes', 'GNU.sparse.map', 'GNU.dumpdir',\n      'GNU.volume.label', 'GNU.volume.filename', 'GNU.volume.size',\n      'GNU.volume.offset' }\n\n  { V7 uses AB_TAR_LF_OLDNORMAL linkflag, has no magic field & no Usr/Grp Names }\n  { V7 Format ends Empty(padded with zeros), as does the POSIX record. }\n  TAbTarEnd_Empty_Rec = packed record\n    Empty: array[0..AB_TAR_V7_EMPTY_SIZE-1] of Byte; { 345-511, $159-1FF, Empty Space }\n  end;\n  { UStar End Format }\n  TAbTarEnd_UStar_Rec = packed record\n    Prefix: array[0..AB_TAR_USTAR_PREFIX_SIZE-1] of AnsiChar;\n                   { 345-499, $159-1F3, Prefix of file & path name, null terminated ASCII string }\n    Empty : Arr12B;{ 500-512, $1F4-1FF, Empty Space }\n  end;\n  { Old GNU End Format }\n  TAbTarEnd_GNU_old_Rec = packed record\n    Atime : Arr12;  { 345-356, $159-164, time of last access (UNIX Date in ASCII coded Octal)}\n    Ctime : Arr12;  { 357-368, $165-170, time of last status change (UNIX Date in ASCII coded Octal)}\n    Offset: Arr12;  { 369-380, $171-17C, Multirecord specific value }\n    Empty1: array[0..AB_TAR_OLD_GNU_EMPTY1_SIZE-1] of Byte;\n                    { 381-385, $17D-181, Empty Space, Once contained longname ref. }\n    Sparse: array[0..AB_TAR_OLD_GNU_SPARSE_SIZE-1] of Byte;\n                    { 386-481, $182-1E1, Sparse File specific values }\n    IsExtended: byte;{    482, $    1E2, Flag to signify Sparse file headers follow }\n    RealSize: Arr12;{ 483-494, $1E3-1EE, Real size of a Sparse File. }\n    Empty2: array[0..AB_TAR_OLD_GNU_EMPTY2_SIZE-1] of Byte;\n                    { 495-511, $1EF-1FF, Empty Space }\n  end;\n  { Star End Format }\n  TAbTarEnd_Star_Rec = packed record\n    Prefix: array[0..AB_TAR_STAR_PREFIX_SIZE-1] of AnsiChar;\n                   { 345-499, $159-1F3, prefix of file & path name, null terminated ASCII string }\n    Atime : Arr12; { 476-487, $1DC-1E7, time of last access (UNIX Date in ASCII coded Octal)}\n    Ctime : Arr12; { 488-499, $1E8-1F3, time of last status change (UNIX Date in ASCII coded Octal)}\n    Empty : Arr12B;{ 500-512, $1F4-1FF, Empty Space }\n  end;\n  { When support for sparse files is added, Add another record for sparse in header }\n\n\n{ Note: SizeOf(TAbTarHeaderRec) = AB_TAR_RECORDSIZE by design }\n  PAbTarHeaderRec = ^TAbTarHeaderRec; { Declare pointer type for use in the list }\n  TAbTarHeaderRec = packed record\n    Name    : ArrName;  {   0- 99, $  0- 63, filename, null terminated ASCII string, unless length is 100 }\n    Mode    : Arr8;     { 100-107, $ 64- 6B, file mode (UNIX style, ASCII coded Octal) }\n    uid     : Arr8;     { 108-115, $ 6C- 73, usrid # (UNIX style, ASCII coded Octal) }\n    gid     : Arr8;     { 116-123, $ 74- 7B, grpid # (UNIX style, ASCII coded Octal) }\n    Size    : Arr12;    { 124-135, $ 7C- 87, size of TARred file (ASCII coded Octal) }\n    ModTime : Arr12;    { 136-147, $ 88- 93, time of last modification.(UNIX Date in ASCII coded Octal)\n                                             UTC time }\n    ChkSum  : Arr8;     { 148-155, $ 94- 9B, checksum of header (6 bytes ASCII coded Octal, #00, #20) }\n    LinkFlag: AnsiChar; {     156, $     9C, type of item, one of the Link Flag constants from above }\n    LinkName: ArrName;  { 157-256, $ 9D-100, name of link, null terminated ASCII string }\n    Magic   : TAbTarMagicRec;\n                        { 257-264, $101-108, identifier, usually 'ustar'#00'00' }\n    UsrName : array [0..AB_TAR_TUSRNAMELEN-1] of AnsiChar;\n                        { 265-296, $109-128, username, null terminated ASCII string }\n    GrpName : array [0..AB_TAR_TGRPNAMELEN-1] of AnsiChar;\n                        { 297-328, $129-148, groupname, null terminated ASCII string }\n    DevMajor: Arr8;     { 329-336, $149-150, major device ID (UNIX style, ASCII coded Octal) }\n    DevMinor: Arr8;     { 337-344, $151-158, minor device ID (UNIX style, ASCII coded Octal) }\n    case TAbTarHeaderFormat of{ 345-511, $159-1FF  See byte Definitions above.}\n      V7_FORMAT    : ( v7    : TAbTarEnd_Empty_Rec );\n      OLDGNU_FORMAT: ( gnuOld: TAbTarEnd_GNU_old_Rec );\n      GNU_FORMAT   : ( gnu   : TAbTarEnd_GNU_old_Rec );\n      USTAR_FORMAT : ( ustar : TAbTarEnd_UStar_Rec );\n      STAR_FORMAT  : ( star  : TAbTarEnd_Star_Rec );\n      POSIX_FORMAT : ( pax   : TAbTarEnd_Empty_Rec );\n  end;{ end TAbTarHeaderRec }\n   { There are three main types of headers we will see in a Tar file }\n   { TAbTarHeaderType = (STANDARD_HDR, SPARSE_HDR, POSIX_EXTENDED_HDR); }\n   { The 1st is defined above, The later two are simply organized data types. }\n\n  TAbTarItemRec = record\n    { Note: that the actual The name needs to be coherient with the name Inherited\n            from parent type TAbArchiveItem }\n    Name       : string;   { Path & File name. }\n    Mode       : LongWord; { File Permissions }\n    uid        : Integer;  { User ID }\n    gid        : Integer;  { Group ID }\n    Size       : Int64;    { Tared File size }\n    ModTime    : Int64;    { Last time of Modification, in UnixTime }\n    ChkSumPass : Boolean;  { Header Check sum found to be good }\n    LinkFlag   : AnsiChar; { Link Flag, Echos the actual File Type of this Item. }\n    ItemType   : TAbTarItemType; { Item Type Assigned from LinkFlag Header Types. }\n    LinkName   : string;   { Link Name }\n    Magic      : AnsiString;   { Magic value }\n    Version    : Integer;  { Version Number }\n    UsrName    : string;   { User Name, for User ID }\n    GrpName    : string;   { Group Name, for Group ID }\n    DevMajor   : Integer;  { Major Device ID }\n    DevMinor   : Integer;  { Minor Device ID }\n    { Additional Types used for holding info. }\n    AccessTime : Int64;    { Time of Last Access, in UnixTime }\n    ChangeTime : Int64;    { Time of Last Status Change, in UnixTime }\n    ArchiveFormat: TAbTarHeaderFormat; { Type of Archive of this record }\n    StreamPosition: Int64; { Pointer to the top of the item in the file. }\n    Dirty      : Boolean;  { Indication if this record needs to have its headers CheckSum recalculated }\n    ItemReadOnly: Boolean; { Indication if this record is READ ONLY }\n    FileHeaderCount:Integer;{ Number of Headers in the Orginal TarHeaders in the File Stream }\n  end;\n\ntype\n  PTAbTarItem = ^TAbTarItem;\n  TAbTarItem = class(TAbArchiveItem)\n  private\n    {  The following private members are used for Stuffing FTarItem struct }\n    procedure ParseTarHeaders; { Error in header if }\n    procedure DetectHeaderFormat; { Helper to stuff HeaderFormat }\n    procedure GetFileNameFromHeaders; { Helper to pull name from Headers }\n    procedure GetLinkNameFromHeaders; { Helper to pull name from Headers }\n    function  TestCheckSum: Boolean;  { Helper to Calculate Checksum of a header. }\n    procedure DoGNUExistingLongNameLink(LinkFlag: AnsiChar; I: Integer; const Value: AnsiString);\n    procedure DoGNUNewLongNameLink(LinkFlag: AnsiChar; I: Integer; const Value: AnsiString);\n  protected {private}\n    PTarHeader: PAbTarHeaderRec;{ Points to FTarHeaderList.Items[FTarHeaderList.Count-1] }\n    FTarHeaderList: TList;      { List of The Headers }\n    FTarHeaderTypeList: TList;  { List of the Header Types }\n    FTarItem: TAbTarItemRec;    { Data about current TAR Item }\n  protected\n    function GetDevMajor: Integer;\n    function GetDevMinor: Integer;\n    function GetGroupID: Integer;\n    function GetGroupName: string;\n    function GetLinkName: string;\n    function GetUserID: Integer;\n    function GetUserName: string;\n    function GetModTime: Int64;\n    function GetNumHeaders: Integer;\n    function GetMagic: string;\n\n    { All Sets shall update the headers Or add headers as needed.  }\n    procedure SetDevMajor(const Value: Integer);\n    procedure SetDevMinor(const Value: Integer);\n    procedure SetGroupID(const Value: Integer);  { Extended Headers }\n    procedure SetGroupName(const Value: string); { Extended Headers }\n    procedure SetLinkFlag(Value: AnsiChar);\n    procedure SetLinkName(const Value: string);  { Extended Headers }\n    procedure SetUserID(const Value: Integer);   { Extended Headers }\n    procedure SetUserName(const Value: string);  { Extended Headers }\n    procedure SetModTime(const Value: Int64);\n    Procedure SetMagic(const Value: string);\n    { TODO: add support for Atime and Ctime here }\n\n    { Overrides for Inherited Properties from type TAbArchiveItem }\n    function GetCompressedSize : Int64; override;\n    function GetExternalFileAttributes : LongWord; override;\n    function GetFileName : string; override;\n    function GetIsDirectory: Boolean; override;\n    function GetIsEncrypted : Boolean; override;\n    function GetLastModFileDate : Word; override;\n    function GetLastModFileTime : Word; override;\n    function GetLastModTimeAsDateTime: TDateTime; override;\n    function GetNativeFileAttributes : LongInt; override;\n    function GetUncompressedSize : Int64; override;\n\n    procedure SetCompressedSize(const Value : Int64); override;       { Extended Headers }\n    procedure SetExternalFileAttributes( Value : LongWord ); override;\n    procedure SetFileName(const Value : string); override;            { Extended Headers }\n    procedure SetIsEncrypted(Value : Boolean); override;\n    procedure SetLastModFileDate(const Value : Word); override;       { Extended Headers }\n    procedure SetLastModFileTime(const Value : Word); override;       { Extended Headers }\n    procedure SetLastModTimeAsDateTime(const Value: TDateTime); override;\n    procedure SetUncompressedSize(const Value : Int64); override;     { Extended Headers }\n\n    procedure SaveTarHeaderToStream(AStream : TStream);\n    procedure LoadTarHeaderFromStream(AStream : TStream);\n\n    property Magic : string { Magic value }\n      read GetMagic write SetMagic;\n  public\n  { property Name : STRING; Path & File name. Inherited from parent type TAbArchiveItem }\n  {   read GetFileName write SetFileName;  overridden above}\n    property Mode : LongWord   { File Permissions }\n      read GetExternalFileAttributes write SetExternalFileAttributes;\n    property UserID : Integer { User ID }\n      read GetUserID write SetUserID;\n    property GroupID : Integer { Group ID }\n      read GetGroupID write SetGroupID;\n    property ModTime : Int64\n      read GetModTime write SetModTime;\n  { property UncompressedSize/CompressedSize(Size): Int64; File size (comp/uncomp) Inherited from parent type TAbArchiveItem }\n  {   read  GetUncompressedSize, GetCompressedSize;  overridden above }\n  {   write SetUncompressedSize, SetCompressedSize;  overridden above }\n  { property LastModFileTime/LastModFileDate(ModeTime): TDateTime; Last time of Modification Inherited from parent type TAbArchiveItem }\n  {   read  GetLastModFileTime, GetLastModFileDate;  overridden above }\n  {   write SetLastModFileTime, SetLastModFileDate;  overridden above }\n\n    property CheckSumGood: Boolean\n      read FTarItem.ChkSumPass; { Header Check sum found to be good }\n    property LinkFlag : AnsiChar { Link Flag of File Header }\n      read FTarItem.LinkFlag write SetLinkFlag;\n    property LinkName : string { Link Name }\n      read GetLinkName write SetLinkName;\n    property UserName : string { User Name, for User ID }\n      read GetUserName write SetUserName;\n    property GroupName : string { Group Name, for Group ID }\n      read GetGroupName write SetGroupName;\n    property DevMajor : Integer { Major Device ID }\n      read GetDevMajor write SetDevMajor;\n    property DevMinor : Integer { Minor Device ID }\n      read GetDevMinor write SetDevMinor;\n    { TODO: Add support ATime and CTime }\n    {AccessTime : TDateTime;} { Time of Last Access }\n    {ChangeTime : TDateTime;} { Time of Last Status Change }\n    { Additional Types used for holding info. }\n    property ExternalFileAttributes;\n    property ArchiveFormat: TAbTarHeaderFormat\n      read FTarItem.ArchiveFormat write FTarItem.ArchiveFormat;\n    property ItemType: TAbTarItemType\n      read FTarItem.ItemType write FTarItem.ItemType;\n    property ItemReadOnly:  Boolean\n      read FTarItem.ItemReadOnly write FTarItem.ItemReadOnly;\n    property FileHeaderCount: Integer\n      read FTarItem.FileHeaderCount;\n    property HeaderCount: Integer\n      read GetNumHeaders;\n    property StreamPosition: Int64\n      read FTarItem.StreamPosition write FTarItem.StreamPosition;\n    constructor Create;\n    destructor Destroy; override;\n  end;  { end TAbArchiveItem }\n\n\n  TAbTarStreamHelper = class(TAbArchiveStreamHelper)\n  private\n    function FindItem: Boolean; { Tool for FindFirst/NextItem functions }\n  protected\n    FTarHeader      : TAbTarHeaderRec; { Speed-up Buffer only }\n    FCurrItemSize   : Int64;           { Current Item size }\n    FCurrItemPreHdrs: Integer;         { Number of Meta-data Headers before the Item }\n  public\n    destructor Destroy; override;\n    procedure ExtractItemData(AStream : TStream); override;\n    function FindFirstItem : Boolean; override;\n    function FindNextItem : Boolean; override;\n    procedure ReadHeader; override;\n    procedure ReadTail; override;\n    function SeekItem(Index : Integer): Boolean; override;\n    procedure WriteArchiveHeader; override;\n    procedure WriteArchiveItem(AStream : TStream); override;\n    procedure WriteArchiveItemSize(AStream : TStream; Size: Int64);\n    procedure WriteArchiveTail; override;\n    function GetItemCount : Integer; override;\n  end;\n\n\n  TAbTarArchive = class(TAbArchive)\n  private\n    FArchReadOnly : Boolean;\n    FArchFormat: TAbTarHeaderFormat;\n  protected\n    function CreateItem(const FileSpec : string): TAbArchiveItem;\n      override;\n    procedure ExtractItemAt(Index : Integer; const UseName : string);\n      override;\n    procedure ExtractItemToStreamAt(Index : Integer; aStream : TStream);\n      override;\n    procedure LoadArchive;\n      override;\n    procedure SaveArchive;\n      override;\n    procedure TestItemAt(Index : Integer);\n      override;\n    function FixName(const Value: string): string;\n      override;\n    function GetSupportsEmptyFolders: Boolean;\n      override;\n\n    function GetItem(Index: Integer): TAbTarItem;\n    procedure PutItem(Index: Integer; const Value: TAbTarItem);\n\n  public {methods}\n    constructor CreateFromStream(aStream : TStream; const aArchiveName : string);\n      override;\n    property UnsupportedTypesDetected : Boolean\n      read FArchReadOnly;\n    property Items[Index : Integer] : TAbTarItem\n      read GetItem\n      write PutItem; default;\n  end;\n\nfunction VerifyTar(Strm : TStream) : TAbArchiveType;\n\n\nimplementation\n\nuses\n  {$IFDEF MSWINDOWS}\n  Windows, // Fix inline warnings\n  {$ENDIF MSWINDOWS}\n  Math, RTLConsts, SysUtils,\n  {$IFDEF HasAnsiStrings}AnsiStrings, {$ENDIF}\n  AbCharset, AbVMStrm, AbExcept;\n\n{ ****************** Helper functions Not from Classes Above ***************** }\nfunction OctalToInt(const Oct : PAnsiChar; aLen : integer): Int64;\nvar\n  i : integer;\nbegin\n  Result := 0;\n\n  i := 0;\n  while (i < aLen) and (Oct[i] = ' ') do\n    inc(i);\n\n  if (i = aLen) then\n    Exit;\n\n  while (i < aLen) and (Oct[i] in ['0'..'7']) do begin\n    Result := (Result * 8) + (Ord(Oct[i]) - Ord('0'));\n    inc(i);\n  end;\nend;\n\nfunction IntToOctal(Value : Int64): AnsiString;\nconst\n  OctDigits  : array[0..7] of AnsiChar = '01234567';\nbegin\n  if Value = 0 then\n    Result := '0'\n  else begin\n    Result := '';\n    while Value > 0 do begin\n      Result := OctDigits[Value and 7] + Result;\n      Value := Value shr 3;\n    end;\n  end;\nend;\n\n\nfunction CalcTarHeaderChkSum(const TarH : TAbTarHeaderRec): LongInt;\nvar\n  HdrBuffer : PAnsiChar;\n  HdrChkSum : LongInt;\n  j : Integer;\nbegin\n  { prepare for the checksum calculation }\n  HdrBuffer := PAnsiChar(@TarH);\n  HdrChkSum := 0;\n\n  {calculate the checksum, a simple sum of the bytes in the header}\n  for j := 0 to Pred(SizeOf(TAbTarHeaderRec)) do\n    HdrChkSum := HdrChkSum + Ord(HdrBuffer[j]);\n\n  Result := HdrChkSum;\nend;\n\nfunction VerifyTar(Strm : TStream) : TAbArchiveType;\n{ assumes Tar positioned correctly for test of item }\nvar\n  TarItem  : TAbTarItem;\n  StartPos : Int64;\nbegin\n  StartPos := Strm.Position;\n  try\n    { Verifies that the header checksum is valid, and Item type is understood.\n      This does not mean that extraction is supported. }\n    TarItem := TAbTarItem.Create;\n    try\n      { get current Tar Header }\n      TarItem.LoadTarHeaderFromStream(Strm);\n      if TarItem.CheckSumGood then\n        Result := atTar\n      else\n        Result := atUnknown;\n    finally\n      TarItem.Free;\n    end;\n  except\n    on EReadError do\n      Result := atUnknown;\n  end;\n  Strm.Position := StartPos;\nend;\n\nfunction PadString(const S : AnsiString; Places : Integer) : AnsiString;\n{\nPads a string (S) with one right space and as many left spaces as\nneeded to fill Places\n\nIf length S greater than Places, just returns S\n\nSome TAR utilities evidently expect Octal numeric fields to be in\nthis format\n}\nbegin\n  if Length(S) >= LongInt(Places) then\n    Result := S\n  else begin\n    Result := S + ' ';\n    Result := StringOfChar(AnsiChar(' '), Places - Length(Result)) + Result;\n  end;\nend;\n\n{ Round UP to the nearest Tar Block Boundary. }\nfunction RoundToTarBlock(Size: Int64) : Int64;\nbegin\n  Result := (Size + (AB_TAR_RECORDSIZE - 1)) and\n             not (AB_TAR_RECORDSIZE - 1);\nend;\n\n\n{ ****************************** TAbTarItem ********************************** }\nconstructor TAbTarItem.Create;\nbegin\n  inherited Create;\n  FTarHeaderList := TList.Create;\n  FTarHeaderTypeList := TList.Create;\n  GetMem(PTarHeader, AB_TAR_RECORDSIZE); { PTarHeader is our new Header }\n  FillChar(PTarHeader^, AB_TAR_RECORDSIZE, #0);\n  FTarHeaderList.Add(PTarHeader);\n  FTarHeaderTypeList.Add(Pointer(FILE_HEADER));\n  FTarItem.FileHeaderCount := 1;\n  { set defaults }\n  FTarItem.ArchiveFormat := UNKNOWN_FORMAT;\n\n  FileName := '';\n  Mode := AB_FPERMISSION_GENERIC;\n  UserID := 0;\n  GroupID := 0;\n  UncompressedSize := 0;\n  { ModTime }\n  LinkFlag := AB_TAR_LF_OLDNORMAL;\n  { Link Name }\n  PTarHeader.Magic.gnuOld := AB_TAR_MAGIC_V7_NONE; { Default to GNU type }\n  UserName := '';\n  GroupName := '';\n  DevMajor := 0;\n  DevMinor := 0;\n  { TODO: atime, ctime }\n  FTarItem.ItemType := SUPPORTED_ITEM;\n  FTarItem.Dirty := True; { Checksum needs to be generated }\n  FTarItem.ItemReadOnly := False;\nend;\n\ndestructor TAbTarItem.Destroy;\nvar\n  i : Integer;\nbegin\n  if Assigned(FTarHeaderList) then\n  begin\n    for i := 0 to FTarHeaderList.Count - 1 do\n      FreeMem(FTarHeaderList.Items[i]); { This list holds PAbTarHeaderRec's }\n    FTarHeaderList.Free;\n  end;\n  FTarHeaderTypeList.Free;\n  inherited Destroy;\nend;\n\nfunction TAbTarItem.GetCompressedSize: Int64;\n{ TAR includes no internal compression, returns same value as GetUncompressedSize }\nbegin\n  Result := FTarItem.Size;\nend;\n\nfunction TAbTarItem.GetDevMajor: Integer;\nbegin\n  Result := FTarItem.DevMajor;\nend;\n\nfunction TAbTarItem.GetDevMinor: Integer;\nbegin\n  Result := FTarItem.DevMinor;\nend;\n\nfunction TAbTarItem.GetExternalFileAttributes: LongWord;\nbegin\n  Result := FTarItem.Mode;\nend;\n\nfunction TAbTarItem.GetFileName: string;\nbegin\n  Result := FTarItem.Name; { Inherited String from Parent Class }\nend;\n\nfunction TAbTarItem.GetGroupID: Integer;\nbegin\n  Result := FTarItem.gid;\nend;\n\nfunction TAbTarItem.GetGroupName: string;\nbegin\n  Result := FTarItem.GrpName;\nend;\n\nfunction TAbTarItem.GetIsDirectory: Boolean;\nbegin\n  Result := (LinkFlag = AB_TAR_LF_DIR);\nend;\n\nfunction TAbTarItem.GetIsEncrypted: Boolean;\nbegin\n  { TAR has no native encryption }\n  Result := False;\nend;\n\nfunction TAbTarItem.GetLastModFileDate: Word;\nbegin\n  { convert to local DOS file Date }\n  Result := LongRec(AbDateTimeToDosFileDate(LastModTimeAsDateTime)).Hi;\nend;\n\nfunction TAbTarItem.GetLastModFileTime: Word;\nbegin\n  { convert to local DOS file Time }\n  Result := LongRec(AbDateTimeToDosFileDate(LastModTimeAsDateTime)).Lo;\nend;\n\nfunction TAbTarItem.GetLastModTimeAsDateTime: TDateTime;\nbegin\n  Result := AbUnixTimeToLocalDateTime(FTarItem.ModTime);\nend;\n\nfunction TAbTarItem.GetLinkName: string;\nbegin\n  Result := FTarItem.LinkName;\nend;\n\nfunction TAbTarItem.GetMagic: string;\nbegin\n  Result := string(FTarItem.Magic);\nend;\n\nfunction TAbTarItem.GetNativeFileAttributes : LongInt;\nbegin\n  Result := GetExternalFileAttributes;\n{$IFDEF MSWINDOWS}\n  Result := AbUnix2DosFileAttributes(Result);\n{$ENDIF}\nend;\n\nfunction TAbTarItem.GetUncompressedSize: Int64;\n{ TAR includes no internal compression, returns same value as GetCompressedSize }\nbegin\n  Result := FTarItem.Size;\nend;\n\nfunction TAbTarItem.GetUserID: Integer;\nbegin\n  Result := FTarItem.uid;\nend;\n\nfunction TAbTarItem.GetUserName: string;\nbegin\n  Result := FTarItem.UsrName;\nend;\n\nfunction TAbTarItem.GetModTime: Int64;\nbegin\n  Result := FTarItem.ModTime;\nend;\n\n{ Get Number of tar headers currently for this item }\nfunction  TAbTarItem.GetNumHeaders: Integer;\nbegin\n  Result := FTarHeaderList.Count;\nend;\n\n{ Takes data from Supported Header types stored in TAbTarItem.FTarHeaderList }\n{ and updates values in the TAbTarItem.FTarItem.X }\n\nprocedure TAbTarItem.DetectHeaderFormat;\nbegin\n  if FTarItem.ArchiveFormat <> UNKNOWN_FORMAT then\n    Exit;{ We have already set the format. }\n  { In the previous header parsing if pax headers are detected the format is changed }\n  { GNU_FORMAT is detected by the presence of GNU extended headers. }\n\n  { These detections are similar to GNU tar's. }\n  if (PTarHeader.Magic.value = AB_TAR_MAGIC_VAL) then\n  begin { We have one of three types, STAR_FORMAT, USTAR_FORMAT, POSIX_FORMAT }\n    { Detect STAR format.  Leave disabled until explicit STAR support is added. }\n    {if (PTarHeader.star.Prefix[130] = #00) and\n       (PTarHeader.star.Atime[0] in ['0'..'7']) and\n       (PTarHeader.star.Atime[11] = #20) and\n       (PTarHeader.star.Ctime[0]in ['0'..'7']) and\n       (PTarHeader.star.Ctime[11] = #20) then\n    begin\n      FTarItme.ArchiveType := STAR_FORMAT;\n    end }\n    { else if } { POSIX uses the existance of x headers }\n\n    { This can define false positives, Pax headers/ STAR format could be detected as this }\n    FTarItem.ArchiveFormat := USTAR_FORMAT;\n  end\n  else if (PTarHeader.Magic.gnuOld = AB_TAR_MAGIC_GNUOLD) then\n  begin\n    FTarItem.ArchiveFormat := OLDGNU_FORMAT;\n  end\n  else { V7 uses AB_TAR_LF_OLDNORMAL linkflag, has no magic field & no Usr/Grp Names }\n  begin\n    FTarItem.ArchiveFormat := V7_FORMAT; { Lowest Common Denominator }\n  end;\nend;\n\n{ Extract the file name from the headers }\nprocedure TAbTarItem.GetFileNameFromHeaders;\nvar\n  I, J : Integer;\n  PHeader: PAbTarHeaderRec;\n  FoundName: Boolean;\n  NameLength : Int64;\n  NumMHeaders: integer;\n  ExtraName: integer;\n  RawFileName, TempStr: AnsiString;\nbegin\n {  UNKNOWN_FORMAT, V7_FORMAT, OLDGNU_FORMAT, GNU_FORMAT, USTAR_FORMAT, STAR_FORMAT, POSIX_FORMAT }\n  FoundName := False;\n  I := 0;\n  while (not FoundName) and (I <= (FTarHeaderList.Count - 1)) do\n  begin\n    PHeader := FTarHeaderList.Items[I];\n    if PHeader.LinkFlag = AB_TAR_LF_LONGNAME then\n    begin\n      FoundName := True;\n      RawFileName := '';\n      NameLength := OctalToInt(PHeader.Size, SizeOf(PHeader.Size));\n      NumMHeaders := NameLength div AB_TAR_RECORDSIZE;\n      ExtraName := NameLength mod AB_TAR_RECORDSIZE; { Chars in the last Header }\n      { NumMHeaders should never be zero }\n      { It appears that it is not null terminated in the blocks }\n      for J := 1 to NumMHeaders do\n      begin\n        { Copy entire content of Header to String }\n        PHeader := FTarHeaderList.Items[I+J];\n        SetString(TempStr, PAnsiChar(PHeader), AB_TAR_RECORDSIZE);\n        RawFileName := RawFileName + TempStr;\n      end;\n      if ExtraName <> 0 then\n      begin\n        PHeader := FTarHeaderList.Items[I+NumMHeaders+1];\n        SetString(TempStr, PAnsiChar(PHeader), ExtraName-1);\n        RawFileName := RawFileName + TempStr;\n      end\n      else { We already copied the entire name, but the string is still null terminated. }\n      begin\n        { Removed the last zero }\n        SetLength(RawFileName, (Length(RawFileName)-1));\n      end;\n    end { end long filename link flag }\n    else\n      I := I + 1;\n  end; { End While }\n\n  if not FoundName then\n  begin\n    if (FTarItem.ArchiveFormat = USTAR_FORMAT) and\n       (PTarHeader.ustar.Prefix[0] <> #0) then\n      RawFileName := PTarHeader.ustar.Prefix+'/'+PTarHeader.Name\n    else\n      { V7_FORMAT, OLDGNU_FORMAT }\n      RawFileName := PTarHeader.Name;\n  end; { End not FoundName }\n\n  FTarItem.Name := AbRawBytesToString(RawFileName);\nend;\n\n{ Extract the file name from the headers }\nprocedure TAbTarItem.GetLinkNameFromHeaders;\nvar\n  I, J : Integer;\n  PHeader: PAbTarHeaderRec;\n  FoundName: Boolean;\n  NameLength : Int64;\n  NumMHeaders: integer;\n  ExtraName: integer;\n  RawLinkName, TempStr: AnsiString;\nbegin\n {  UNKNOWN_FORMAT, V7_FORMAT, OLDGNU_FORMAT, GNU_FORMAT, USTAR_FORMAT, STAR_FORMAT, POSIX_FORMAT }\n  PHeader := nil;\n  FoundName := False;\n  I := 0;\n  { Note that: FTarHeaderList.Count <= 1, always }\n  while (not FoundName) and (I <= (FTarHeaderList.Count - 1)) do\n  begin\n    PHeader := FTarHeaderList.Items[I];\n    if PHeader.LinkFlag = AB_TAR_LF_LONGLINK then\n    begin\n      FoundName := True;\n      RawLinkName := '';\n      NameLength := OctalToInt(PHeader.Size, SizeOf(PHeader.Size));\n      NumMHeaders := NameLength div AB_TAR_RECORDSIZE;\n      ExtraName := NameLength mod AB_TAR_RECORDSIZE; { Chars in the last Header }\n      { NumMHeaders should never be zero }\n      { It appears that it is not null terminated in the blocks }\n      for J := 1 to NumMHeaders do\n      begin\n        { Copy entire content of Header to String }\n        PHeader := FTarHeaderList.Items[I+J];\n        SetString(TempStr, PAnsiChar(PHeader), AB_TAR_RECORDSIZE);\n        RawLinkName := RawLinkName + TempStr;\n      end;\n      if ExtraName <> 0 then\n      begin\n        PHeader := FTarHeaderList.Items[I+NumMHeaders+1];\n        SetString(TempStr, PAnsiChar(PHeader), ExtraName-1);\n        RawLinkName := RawLinkName + TempStr;\n      end\n      else { We already copied the entire name, but the string is still null terminated. }\n      begin\n        { Removed the last zero }\n        SetLength(RawLinkName, (Length(RawLinkName)-1));\n      end;\n    end { end long filename link flag }\n    else\n      I := I + 1;\n  end; { End While }\n\n  if not FoundName then\n    RawLinkName := PHeader.LinkName;\n\n  FTarItem.LinkName := AbRawBytesToString(RawLinkName);\nend;\n\n{ Return True if CheckSum passes out. }\nfunction TAbTarItem.TestCheckSum : Boolean;\nvar\n  TarChkSum : LongInt;\n  TarChkSumArr : Arr8; { ChkSum field is Arr8 }\n  PHeader: PAbTarHeaderRec;\n  I: Integer;\nbegin\n  Result := True;\n  { Check sums are in valid headers but NOT in the data headers. }\n  for I := 0 to FTarHeaderList.Count - 1 do\n  begin\n    if TAbTarHeaderType(FTarHeaderTypeList.Items[I]) in [FILE_HEADER, META_DATA_HEADER] then\n    begin\n      PHeader := FTarHeaderList.Items[i];\n      { Save off old Check sum }\n      Move(PHeader.ChkSum, TarChkSumArr, SizeOf(PHeader.ChkSum));\n      TarChkSum := OctalToInt(TarChkSumArr, SizeOf(TarChkSumArr));\n      { Set to Generator Value }\n      PHeader.ChkSum := AB_TAR_CHKBLANKS;\n      if CalcTarHeaderChkSum(PHeader^) <> TarChkSum then\n        Result := False; { Pass unless one miss-compares }\n      { Save back old checksum }\n      Move(TarChkSumArr, PHeader.ChkSum, SizeOf(TarChkSumArr));\n    end;\n  end;\nend;\n\nprocedure TAbTarItem.ParseTarHeaders;\nbegin\n  { The final index is the Item index }\n  DetectHeaderFormat;\n  { Long term this parsing is not correct, as the values in extended headers\n    override the later values in this header }\n  FTarItem.Mode := OctalToInt(PTarHeader.Mode, SizeOf(PTarHeader.Mode));\n  FTarItem.uid := OctalToInt(PTarHeader.uid, SizeOf(PTarHeader.uid)); { Extended in PAX Headers }\n  FTarItem.gid := OctalToInt(PTarHeader.gid, SizeOf(PTarHeader.gid)); { Extended in PAX Headers }\n  FTarItem.Size := OctalToInt(PTarHeader.Size, SizeOf(PTarHeader.Size)); { Extended in PAX Headers }\n  { ModTime should be an Int64 but no tool support, No issues until Feb 6th, 2106 :) }\n  { ModTime is Extended in PAX Headers }\n  FTarItem.ModTime := OctalToInt(PTarHeader.ModTime, SizeOf(PTarHeader.ModTime));\n  FTarItem.ChkSumPass := TestCheckSum();\n  FTarItem.LinkFlag := PTarHeader.LinkFlag;\n  GetLinkNameFromHeaders; { Extended in PAX Headers }\n  FTarItem.Magic := PTarHeader.Magic.value;\n  FTarItem.Version := OctalToInt(PTarHeader.Magic.version, SizeOf(PTarHeader.Magic.version));\n  FTarItem.UsrName := string(PTarHeader.UsrName); { Extended in PAX Headers }\n  FTarItem.GrpName := string(PTarHeader.GrpName); { Extended in PAX Headers }\n  FTarItem.DevMajor := OctalToInt(PTarHeader.DevMajor, SizeOf(PTarHeader.DevMajor));\n  FTarItem.DevMinor := OctalToInt(PTarHeader.DevMinor, SizeOf(PTarHeader.DevMinor));\n  GetFileNameFromHeaders;\n  { FTarItem.ArchiveFormat;  Already stuffed }\n  { FTarItem.StreamPosition: Already Stuffed }\n  { FTarItem.Dirty; Stuffed upon creaction }\nend;\n\nprocedure TAbTarItem.LoadTarHeaderFromStream(AStream: TStream);\nvar\n  NumMHeaders : Integer;\n  I : Integer;\n  FoundItem : Boolean;\nbegin\n  { Note: The SizeOf(TAbTarHeaderRec) = AB_TAR_RECORDSIZE }\n  { We should expect FindNext/FirstItem, and next check for bounds. }\n  if FTarHeaderList.Count > 0 then\n  begin { We're Going to stomp over the headers that are already present }\n    { We need to destory the memory we've used }\n    PTarHeader := nil;\n    for i := 0 to FTarHeaderList.Count - 1 do\n      FreeMem(FTarHeaderList.Items[i]); { This list holds PAbTarHeaderRec's }\n    FTarHeaderList.Clear;\n    FTarHeaderTypeList.Clear;\n    FTarItem.FileHeaderCount := 0;\n    { All pointers should now be removed from those headers }\n  end;\n  { Now lets start filling up that list. }\n  FTarItem.ItemType := UNKNOWN_ITEM; { We don't know what we have yet }\n  FoundItem := False;\n  while not FoundItem do\n  begin\n    { Create a Header to be Stored in the Items List }\n    GetMem(PTarHeader, AB_TAR_RECORDSIZE);\n    AStream.ReadBuffer(PTarHeader^, AB_TAR_RECORDSIZE);\n    FTarHeaderList.Add(PTarHeader); { Store the Header to the list }\n    { Parse header based on LinkFlag }\n    if PTarHeader.LinkFlag in (AB_SUPPORTED_MD_HEADERS+AB_UNSUPPORTED_MD_HEADERS) then\n    begin { This Header type is in the Set of un/supported Meta data type headers }\n      if PTarHeader.LinkFlag in AB_UNSUPPORTED_MD_HEADERS then\n        FTarItem.ItemReadOnly := True; { We don't fully support this meta-data type }\n      if (PTarHeader.LinkFlag in AB_PAX_MD_HEADERS) and (PTarHeader.Magic.value = AB_TAR_MAGIC_VAL) then\n        FTarItem.ArchiveFormat := POSIX_FORMAT; { We have a POSIX_FORMAT, has x headers, and Magic matches }\n      if PTarHeader.LinkFlag in AB_GNU_MD_HEADERS then\n        FTarItem.ArchiveFormat := OLDGNU_FORMAT; { We have a OLDGNU_FORMAT, has L/K headers }\n      { There can be a unknown number of Headers of data }\n      { We are for sure going to read at least one more header, but are we going to read more than that? }\n      FTarHeaderTypeList.Add(Pointer(META_DATA_HEADER));\n      NumMHeaders := Ceil(OctalToInt(PTarHeader.Size, SizeOf(PTarHeader.Size)) / AB_TAR_RECORDSIZE);\n      { NumMHeasder should never be zero }\n      for I := 1 to NumMHeaders do\n      begin\n        GetMem(PTarHeader, AB_TAR_RECORDSIZE); { Create a new Header }\n        AStream.ReadBuffer(PTarHeader^, AB_TAR_RECORDSIZE); { Get the Meta Data }\n        FTarHeaderList.Add(PTarHeader); { Store the Header to the list }\n        FTarHeaderTypeList.Add(Pointer(MD_DATA_HEADER));\n      end;\n      { Loop and reparse }\n    end\n    else if PTarHeader.LinkFlag in AB_SUPPORTED_F_HEADERS then\n    begin { This Header type is in the Set of supported File type Headers }\n      FoundItem := True; { Exit Criterion }\n      FTarItem.ItemType := SUPPORTED_ITEM;\n      if FTarItem.ItemReadOnly then            { Since some of the Headers are read only. }\n        FTarItem.ItemType := UNSUPPORTED_ITEM; { This Item is unsupported }\n      FTarHeaderTypeList.Add(Pointer(FILE_HEADER));\n    end\n    else if PTarHeader.LinkFlag in AB_UNSUPPORTED_F_HEADERS then\n    begin { This Header type is in the Set of unsupported File type Headers }\n      FoundItem := True; { Exit Criterion }\n      FTarItem.ItemType := UNSUPPORTED_ITEM;\n      FTarHeaderTypeList.Add(Pointer(FILE_HEADER));\n    end\n    else { These are unknown header types }\n    begin { Note: Some of these unknown types could have known Meta-data headers }\n      FoundItem := True;\n      FTarItem.ItemType := UNKNOWN_ITEM;\n      FTarHeaderTypeList.Add(Pointer(UNKNOWN_HEADER));\n    end;{ end LinkFlag parsing }\n  end; { end Found Item While }\n  { PTarHeader points to FTarHeaderList.Items[FTarHeaderList.Count-1]; }\n\n  { Re-wind the Stream back to the begining of this Item inc. all headers }\n  AStream.Seek(-(FTarHeaderList.Count*AB_TAR_RECORDSIZE), soCurrent);\n  { AStream.Position := FTarItem.StreamPosition; } { This should be equivalent as above }\n  FTarItem.FileHeaderCount := FTarHeaderList.Count;\n  if FTarItem.ItemType <> UNKNOWN_ITEM then\n  begin\n    ParseTarHeaders; { Update FTarItem values }\n    FFileName := FTarItem.Name; {FTarHeader.Name;}\n    FDiskFileName := FileName;\n    AbUnfixName(FDiskFileName);\n  end;\n  Action := aaNone;\n  Tagged := False;\nend;\n\n\n{ ****************** BEGIN SET ********************** }\n\nprocedure TAbTarItem.SaveTarHeaderToStream(AStream: TStream);\nvar\n  i : Integer;\n  j : Integer;\n  PHeader :  PAbTarHeaderRec;\n  HdrChkSum : Integer;\n  HdrChkStr : AnsiString;\n  HdrBuffer : PAnsiChar;\n  SkipNextChkSum: Integer;\n  SkipChkSum: Boolean;\nbegin\n  if FTarItem.ItemReadOnly then { Read Only - Do Not Save }\n    Exit;\n  { Note: The SizeOf(TAbTarHeaderRec) = AB_TAR_RECORDSIZE }\n  if FTarItem.Dirty then\n    SkipNextChkSum := 0\n  else\n    SkipNextChkSum := FTarHeaderList.Count; { Don't recalc any chkSums }\n\n  { The first header in the Item list must have a checksum calculation }\n  for i := 0 to (FTarHeaderList.Count-1) do\n  begin\n    SkipChkSum := False;\n    PHeader := FTarHeaderList.Items[i];\n    if (SkipNextChkSum = 0) then\n    begin { We need to parse this header }\n      if PHeader.LinkFlag in (AB_SUPPORTED_MD_HEADERS+AB_UNSUPPORTED_MD_HEADERS) then\n      begin { We have a Meta-Data Header, Calculate how many headers to skip. }\n        { These meta-data headers have non-Header buffers after this Header }\n        SkipNextChkSum := Ceil(OctalToInt(PHeader.Size, SizeOf(PHeader.Size)) / AB_TAR_RECORDSIZE);\n        { Ceil will mandate one run through, and will handle 512 correctly }\n      end\n      else if PHeader.LinkFlag in AB_SUPPORTED_F_HEADERS then\n      begin\n        SkipNextChkSum := 0;\n      end\n      else\n      begin { Un-Supported Header type, Copy but do nothing to the data }\n        SkipNextChkSum := 0;\n        SkipChkSum := True;\n      end;{ end LinkFlag parsing }\n    end\n    else\n    begin { Do not calcuate the check sum on this meta Data header buffer }\n      SkipNextChkSum := SkipNextChkSum - 1;\n      SkipChkSum := True;\n    end;{ end SkipNextChkSum }\n\n    if not SkipChkSum then\n    begin { We are Calculating the Checksum for this Header }\n      {Tar ChkSum is \"odd\" The check sum field is filled with #20 chars as empty }\n      { ChkSum field itself is #20'd and has an effect on the sum }\n      PHeader.ChkSum := AB_TAR_CHKBLANKS;\n      { Set up the buffers }\n      HdrBuffer := PAnsiChar(PHeader);\n      HdrChkSum := 0;\n      { Calculate the checksum, a simple sum of the bytes in the header }\n      for j := 0 to (AB_TAR_RECORDSIZE-1) do\n        HdrChkSum := HdrChkSum + Ord(HdrBuffer[j]);\n      { set the checksum in the header }\n      HdrChkStr := PadString(IntToOctal(HdrChkSum), SizeOf(PHeader.ChkSum));\n      Move(HdrChkStr[1], PHeader.ChkSum, Length(HdrChkStr));\n    end; { end Skip Check Sum }\n    { write header to the file }\n    AStream.Write(PHeader^, AB_TAR_RECORDSIZE);\n  end; { End for the number of headers in the list }\n  { Updated here as the stream is now updated to the latest number of headers }\n  FTarItem.FileHeaderCount := FTarHeaderList.Count;\nend;\n\nprocedure TAbTarItem.SetCompressedSize(const Value: Int64);\nvar\n  S : AnsiString;\nbegin\n  if FTarItem.ItemReadOnly then { Read Only - Do Not Save }\n    Exit;\n  { Size is extendable in PAX Headers, Remember PAX extended Header Over Rule File Headers }\n  FTarItem.Size := Value; { Store our Vitrual Copy }\n  S := PadString(IntToOctal(Value), SizeOf(Arr12));{ Stuff to header }\n  Move(S[1], PTarHeader.Size, Length(S));\n  FTarItem.Dirty := True;\nend;\n\nprocedure TAbTarItem.SetDevMajor(const Value: Integer);\nvar\n  S : AnsiString;\nbegin\n  if FTarItem.ItemReadOnly then { Read Only - Do Not Save }\n    Exit;\n  { Dev Major and Minor are Only used for AB_TAR_LF_CHR, AB_TAR_LF_BLK }\n  { Otherwise they are stuffed with #00 }\n  FTarItem.DevMajor := Value; { Store to the struct }\n  S := PadString(IntToOctal(Value), SizeOf(Arr8));\n  Move(S[1], PTarHeader.DevMajor, Length(S));\n  FTarItem.Dirty := True;\nend;\n\nprocedure TAbTarItem.SetDevMinor(const Value: Integer);\nvar\n  S : AnsiString;\nbegin\n  if FTarItem.ItemReadOnly then { Read Only - Do Not Save }\n    Exit;\n  { Dev Major and Minor are Only used for AB_TAR_LF_CHR, AB_TAR_LF_BLK }\n  { Otherwise they are stuffed with #00 }\n  FTarItem.DevMinor := Value;\n  S := PadString(IntToOctal(Value), SizeOf(Arr8));\n  Move(S[1], PTarHeader.DevMinor, Length(S));\n  FTarItem.Dirty := True;\nend;\n\nprocedure TAbTarItem.SetExternalFileAttributes(Value: LongWord);\nvar\n  S : AnsiString;\n  I: Integer;\nbegin\n  if FTarItem.ItemReadOnly then { Read Only - Do Not Save }\n    Exit;\n  FTarItem.Mode := Value;\n  S := PadString(IntToOctal(Value), SizeOf(Arr8));\n  for I := 0 to FTarHeaderList.Count - 1 do\n    if TAbTarHeaderType(FTarHeaderTypeList.Items[I]) in [FILE_HEADER, META_DATA_HEADER] then\n      Move(S[1], PAbTarHeaderRec(FTarHeaderList.Items[I]).Mode, Length(S));\n  FTarItem.Dirty := True;\nend;\n\n{ Add/Remove Headers as needed To/From Existing GNU Long (Link/Name) TarItems }\nprocedure TAbTarItem.DoGNUExistingLongNameLink(LinkFlag: AnsiChar; I: Integer; const Value: AnsiString);\nvar\n  PHeader: PAbTarHeaderRec;\n  J: Integer;\n  OldNameLength: Integer;\n  TotalOldNumHeaders: Integer;\n  TotalNewNumHeaders: Integer;\n  NumHeaders: Integer;\n  ExtraName: Integer;\n  tempStr: AnsiString;\nbegin\n  PHeader := FTarHeaderList.Items[I];\n\n  { Need this data from the old header }\n  OldNameLength := OctalToInt(PHeader.Size, SizeOf(PHeader.Size));{ inlcudes Null termination }\n  { Length(FTarItem.Name)+1 = OldNameLength; }{ This should be true, always }\n\n  { Save off the new Length, so we don't have to change the pointers later. }\n  tempStr := PadString(IntToOctal(Length(Value)+1), SizeOf(PHeader.Size));\n  Move(tempStr[1], PHeader.Size, Length(tempStr));\n\n  TotalOldNumHeaders := Ceil(OldNameLength / AB_TAR_RECORDSIZE);\n  TotalNewNumHeaders := Ceil((Length(Value)+1) / AB_TAR_RECORDSIZE);{ Null terminated }\n  {Length(Value)+1: 1-512 = 1, 513-1024 = 2 ... }\n  J := TotalOldNumHeaders - TotalNewNumHeaders;\n  while J <> 0 do\n  begin\n    if J > 0 then\n    begin { Old > New, Have to many Headers, Remove }\n      FreeMem(FTarHeaderList.Items[I+J]); { Free the Memory for the extra Header }\n      FTarHeaderList.Delete(I+J);         { Delete the List index }\n      FTarHeaderTypeList.Delete(I+J);\n      J := J - 1;\n    end\n    else { if J < 0 then }\n    begin { Old < New, Need more Headers, Insert }\n      GetMem(PHeader, AB_TAR_RECORDSIZE);\n      FTarHeaderList.Insert(I+1,PHeader);{ Insert: Inserts at index }\n      FTarHeaderTypeList.Insert(I+1,Pointer(MD_DATA_HEADER));{ We are only adding MD Data headers here }\n      J := J + 1;\n    end;\n  end;{ end numHeaders while }\n  { Yes, GNU Tar adds a Nil filled MD data header if Length(Value) mod AB_TAR_RECORDSIZE = 0 }\n  NumHeaders := (Length(Value)+1) div AB_TAR_RECORDSIZE; { Include Null terminator }\n  ExtraName := (Length(Value)+1) mod AB_TAR_RECORDSIZE; { Chars in the last Header }\n  { Now we have the number of headers set up, stuff the name in the Headers }\n  TempStr := AnsiString(Value);\n  for J := 1 to NumHeaders do\n  begin\n    { Copy entire next AB_TAR_RECORDSIZE bytes of tempString to content of Header }\n    { There may only be AB_TAR_RECORDSIZE-1 bytes if this is the last rounded header }\n    PHeader := FTarHeaderList.Items[I+J];\n    Move(TempStr[1], PHeader^, AB_TAR_RECORDSIZE);\n    if Length(TempStr) >= AB_TAR_RECORDSIZE then\n      Delete(TempStr, 1, AB_TAR_RECORDSIZE);{ Crop string }\n  end;\n  if ExtraName <> 0 then\n  begin\n    { Copy whatever is left in tempStr into the rest of the buffer }\n    PHeader := FTarHeaderList.Items[I+NumHeaders+1];\n    FillChar(PHeader^, AB_TAR_RECORDSIZE, #0); { Zero the whole block }\n    Move(TempStr[1], PHeader^, ExtraName-1); { The string is null terminated }\n  end\n  else { We already copied the entire name, but it must be null terminated }\n  begin\n    FillChar(Pointer(PtrInt(PHeader)+AB_TAR_RECORDSIZE-1)^, 1, #0); { Zero rest of the block }\n  end;\n\n  { Finally we need to stuff the file type Header. }\n  { Note: Value.length > AB_TAR_NAMESIZE(100) }\n  if LinkFlag = AB_TAR_LF_LONGNAME then\n    Move(Value[1], PTarHeader.Name, AB_TAR_NAMESIZE)\n  else\n    Move(Value[1], PTarHeader.LinkName, AB_TAR_NAMESIZE);\nend;\n\n\n{ Always inserts the L/K Headers at index 0+ }\nprocedure TAbTarItem.DoGNUNewLongNameLink(LinkFlag: AnsiChar; I: Integer; const Value: AnsiString);\nvar\n  PHeader: PAbTarHeaderRec;\n  J: Integer;\n  NumHeaders: Integer;\n  ExtraName: Integer;\n  tempStr: AnsiString;\nbegin\n  { We have a GNU_FORMAT, and no L/K Headers.}\n  { Add a new MD Header and MD Data Headers }\n  { Make an L/K header }\n  GetMem(PHeader, AB_TAR_RECORDSIZE);\n  FTarHeaderList.Insert(I, PHeader);{ Insert: Inserts at base index }\n  FTarHeaderTypeList.Insert(I, Pointer( META_DATA_HEADER));{ This is the L/K Header }\n  FillChar(PHeader^, AB_TAR_RECORDSIZE, #0); { Zero the whole block }\n  AbStrPCopy(PHeader.Name, AB_TAR_L_HDR_NAME); { Stuff L/K String Name }\n  AbStrPCopy(PHeader.Mode, AB_TAR_L_HDR_ARR8_0); { Stuff zeros }\n  AbStrPCopy(PHeader.uid, AB_TAR_L_HDR_ARR8_0);  { Stuff zeros }\n  AbStrPCopy(PHeader.gid, AB_TAR_L_HDR_ARR8_0);  { Stuff zeros }\n  tempStr := PadString(IntToOctal(Length(Value)+1), SizeOf(PHeader.Size)); { Stuff Size }\n  Move(tempStr[1], PHeader.Size, Length(tempStr));\n  AbStrPCopy(PHeader.ModTime, AB_TAR_L_HDR_ARR12_0);  { Stuff zeros }\n  { Check sum will be calculated as the Dirty flag is in caller. }\n  PHeader.LinkFlag := LinkFlag;  { Stuff Link FlagSize }\n  AbStrPCopy(PHeader.Magic.gnuOld, AB_TAR_MAGIC_GNUOLD); { Stuff the magic }\n  AbStrPCopy(PHeader.UsrName, AB_TAR_L_HDR_USR_NAME);\n  AbStrPCopy(PHeader.GrpName, AB_TAR_L_HDR_GRP_NAME);\n  { All else stays as Zeros. }\n  { Completed with L/K Header }\n\n  { OK, now we need to add the proper number of MD Data Headers, and intialize to new name }\n  { Yes, GNU Tar adds an extra Nil filled MD data header if Length(Value) mod AB_TAR_RECORDSIZE = 0 }\n  NumHeaders := Ceil((Length(Value)+1) / AB_TAR_RECORDSIZE); { Include Null terminator }\n  ExtraName := (Length(Value)+1) mod AB_TAR_RECORDSIZE; { Chars in the last Header }\n  { Now we have the number of headers set up, stuff the name in the Headers }\n  TempStr := AnsiString(Value);\n  for J := 1 to NumHeaders-1 do\n  begin\n    { Make a buffer, and copy entire next AB_TAR_RECORDSIZE bytes of tempStr to content of Header }\n    { There may only be AB_TAR_RECORDSIZE-1 bytes if this is the last rounded header }\n    GetMem(PHeader, AB_TAR_RECORDSIZE);\n    FTarHeaderList.Insert(J+I, PHeader);\n    FTarHeaderTypeList.Insert(J+I, Pointer(MD_DATA_HEADER));{ We are adding MD Data headers here }\n    Move(TempStr[1], PHeader^, AB_TAR_RECORDSIZE);\n    if Length(TempStr) >= AB_TAR_RECORDSIZE then\n      Delete(TempStr, 1, AB_TAR_RECORDSIZE);{ Crop string }\n  end;\n  if ExtraName <> 0 then\n  begin\n    { Copy what ever is left in tempStr into the rest of the buffer }\n    { Create the last MD Data Header }\n    GetMem(PHeader, AB_TAR_RECORDSIZE);\n    FTarHeaderList.Insert(I+NumHeaders, PHeader);{ Insert: Inserts at base index }\n    FTarHeaderTypeList.Insert(I+NumHeaders, Pointer(MD_DATA_HEADER));{ We are only adding MD Data headers here }\n    FillChar(PHeader^, AB_TAR_RECORDSIZE, #0); { Zero the whole block }\n    Move(TempStr[1], PHeader^, ExtraName-1); { The string is null terminated in the header }\n  end\n  else { We already copied the entire name, but it must be null terminated }\n  begin\n    FillChar(Pointer(PtrInt(PHeader)+AB_TAR_RECORDSIZE-1)^, 1, #0); { Zero rest of the block }\n  end;\n\n  { Finally we need to stuff the file type Header. }\n  { Note: Value.length > AB_TAR_NAMESIZE(100) }\n  if LinkFlag = AB_TAR_LF_LONGNAME then\n    Move(Value[1], PHeader.Name, AB_TAR_NAMESIZE)\n  else\n    Move(Value[1], PHeader.LinkName, AB_TAR_NAMESIZE);\nend;\n\nprocedure TAbTarItem.SetFileName(const Value: string);\nvar\n  FoundMetaDataHeader: Boolean;\n  PHeader: PAbTarHeaderRec;\n  I, J: Integer;\n  TotalOldNumHeaders: Integer;\n  RawFileName: AnsiString;\nbegin\n  if FTarItem.ItemReadOnly then { Read Only - Do  Not Save }\n    Exit;\n  { Assume ItemReadOnly is set for all Unsupported Type. }\n\n  { Cases:\n    New File Name is short, Length <= 100,\n      All formats: Zero Name field and move new name to field.\n      V7: Work complete, 1 header\n      USTAR: zero prefix field, 1 Header\n      OLD_GNU & GNU: Remove old name headers, 1 header.\n      STAR & PAX: And should not yet get here.\n    New File Name is Long, Length >=101\n      Note: The Header Parsing sets any V7 to GNU if 'L'/'K\" Headers are present\n      V7: Raise an exception, as this can NOT be done, no change to header.\n      USTAR: if new length <= 254 zero fill header, update name fields,  1 updated Header\n             if new Length >= 255 raise an exception, as this can NOT be done, no change to header\n      if old was Short,  Add files to match format,\n         OLD_GNU & GNU: Create new Name header, Add N Headers for name, Update name in file header, update name fields, min 3 headers\n         STAR & PAX: And should not yet get here.\n      if old was Long,\n         OLD_GNU & GNU: Add N Headers for name, Update name in MD header, update name field in File Headers, min 3 headers\n\n      Add headers to length of new Name Length, update name in file header, update name fields }\n  RawFileName := AbStringToUnixBytes(Value);\n  { In all cases zero out the name fields in the File Header. }\n  if Length(RawFileName) > AB_TAR_NAMESIZE then begin { Must be null terminated except at 100 char length }\n    { Look for long name meta-data headers already in the archive. }\n    FoundMetaDataHeader := False;\n    I := 0;\n    { FTarHeaderList.Count <= 1 always }\n    while (not FoundMetaDataHeader) and (I <= (FTarHeaderList.Count - 1)) do begin\n      PHeader := FTarHeaderList.Items[I];\n      if PHeader.LinkFlag = AB_TAR_LF_LONGNAME then begin\n        { We are growing or Shriking the Name MD Data fields.  }\n        FoundMetaDataHeader := True;\n        DoGNUExistingLongNameLink(AB_TAR_LF_LONGNAME, I, RawFileName);\n        { Need to copy the Name to the header. }\n        FTarItem.Name := Value;\n      end\n      else\n        I := I + 1;\n    end; { End While }\n    { MD Headers & MD Data Headers have been stuffed if FoundMetaDataHeader }\n    { Still need to stuff the File type header contents. }\n    if not FoundMetaDataHeader then\n    begin\n      case FTarItem.ArchiveFormat of\n        V7_FORMAT: raise EAbTarBadFileName.Create; { File Name to Long }\n        USTAR_FORMAT:\n          begin\n            { Longest file name is AB_TAR_NAMESIZE(100) chars }\n            { Longest Prefix is AB_TAR_USTAR_PREFIX_SIZE(155) chars }\n            { These two fields are delimted by a '/' char }\n            {0123456789012345, Length = 15, NameLength = 5, PrefixLength = 9}\n            { AAAA/BBBB/C.txt, Stored as Name := 'C.txt', Prefix := 'AAAA/BBBB' }\n            { That means Theoretical maximum is 256 for Length(RawFileName) }\n            if Length(RawFileName) > (AB_TAR_NAMESIZE+AB_TAR_USTAR_PREFIX_SIZE+1) then { Check the obvious one. }\n              raise EAbTarBadFileName.Create; { File Name to Long }\n            for I := Length(RawFileName) downto Length(RawFileName)-AB_TAR_NAMESIZE-1 do begin\n              if RawFileName[I] = '/' then begin\n                if (I <= AB_TAR_USTAR_PREFIX_SIZE+1) and (Length(RawFileName)-I <= AB_TAR_NAMESIZE) then begin\n                  { We have a successfull parse. }\n                  FillChar(PTarHeader.Name, SizeOf(PTarHeader.Name), #0);\n                  FillChar(PTarHeader.ustar.Prefix, SizeOf(PTarHeader.ustar.Prefix), #0);\n                  Move(RawFileName[I+1], PTarHeader.Name, Length(RawFileName)-I);\n                  Move(RawFileName[1], PTarHeader.ustar.Prefix, I);\n                  break;\n                end\n                else if (Length(RawFileName)-I > AB_TAR_NAMESIZE) then\n                  raise EAbTarBadFileName.Create { File Name not splittable }\n                { else continue; }\n              end;\n            end;{ End for I... }\n          end; { End USTAR Format }\n        OLDGNU_FORMAT: DoGNUNewLongNameLink(AB_TAR_LF_LONGNAME, 0, RawFileName); {GNU_FORMAT}\n        else begin\n          { UNKNOWN_FORMAT, STAR_FORMAT, POSIX_FORMAT }\n          raise EAbTarBadOp.Create; { Unknown Archive Format }\n        end;{ End of Else for case statement }\n      end;{ End of case statement }\n      FTarItem.Name := Value;\n    end; { if no Meta data header found }\n  end { End \"name length larger than 100\" }\n  else\n  begin { Short new name, Simple Case Just put it in the Name Field & remove any headers }\n    { PTarHeader Points to the File type Header }\n    { Zero the Name field }\n    FillChar(PTarHeader.Name, SizeOf(PTarHeader.Name), #0);\n    if FTarItem.ArchiveFormat in [USTAR_FORMAT] then { Zero the prefix field }\n      FillChar(PTarHeader.ustar.Prefix, SizeOf(PTarHeader.ustar.Prefix), #0);\n    if FTarItem.ArchiveFormat in [GNU_FORMAT, OLDGNU_FORMAT] then\n    begin { We may have AB_TAR_LF_LONGNAME Headers to be removed }\n      { Remove long file names Headers if they exist}\n      FoundMetaDataHeader := False;\n      I := 0;\n      while not FoundMetaDataHeader and (I <= (FTarHeaderList.Count - 1)) do\n      begin\n        PHeader := FTarHeaderList.Items[I];\n        if PHeader.LinkFlag in [AB_TAR_LF_LONGNAME] then\n        begin  { Delete this Header, and the data Headers. }\n          FoundMetaDataHeader := True;\n          TotalOldNumHeaders := Ceil( OctalToInt(PHeader.Size, SizeOf(PHeader.Size)) / AB_TAR_RECORDSIZE);\n          for J := TotalOldNumHeaders downto 0 do\n          begin { Note 0 will delete the Long Link MD Header }\n            FreeMem(FTarHeaderList.Items[I+J]); { This list holds PAbTarHeaderRec's }\n            FTarHeaderList.Delete(I+J);\n            FTarHeaderTypeList.Delete(I+J);\n          end;\n        end\n        else\n          I := I + 1; { Got to next header }\n      end;{ End While not found... }\n    end; { End if GNU... }\n    { Save off the new name and store to the Header }\n    FTarItem.Name := Value;\n    { Must add Null Termination before we store to Header }\n    AbStrPLCopy(PTarHeader.Name, RawFileName, AB_TAR_NAMESIZE);\n  end;{ End else Short new name,... }\n\n  { Update the inherited file names. }\n  FFileName := FTarItem.Name;\n  DiskFileName := FFileName;\n  AbUnfixName(FDiskFileName);\n  FTarItem.Dirty := True;\nend;\n\nprocedure TAbTarItem.SetGroupID(const Value: Integer);\nvar\n  S : AnsiString;\nbegin\n  if FTarItem.ItemReadOnly then { Read Only - Do Not Save }\n    Exit;\n  { gid is extendable in PAX Headers, Rember PAX extended Header Over Rule File Headers }\n  FTarItem.gid := Value;\n  S := PadString(IntToOctal(Value), SizeOf(Arr8));\n  Move(S[1], PTarHeader.gid, Length(S));\n  FTarItem.Dirty := True;\nend;\n\nprocedure TAbTarItem.SetGroupName(const Value: string);\nbegin\n  if FTarItem.ItemReadOnly then { Read Only - Do Not Save }\n    Exit;\n  { GrpName is extendable in PAX Headers, Rember PAX extended Header Over Rule File Headers }\n  FTarItem.GrpName := Value;\n  AbStrPLCopy(PTarHeader.GrpName, AnsiString(Value), SizeOf(PTarHeader.GrpName));\n  FTarItem.Dirty := True;\nend;\n\nprocedure TAbTarItem.SetIsEncrypted(Value: Boolean);\nbegin\n  { do nothing, TAR has no native encryption }\nend;\n\nprocedure TAbTarItem.SetLastModFileDate(const Value: Word);\nbegin\n  { replace date, keep existing time }\n  LastModTimeAsDateTime :=\n    EncodeDate(\n      Value shr 9 + 1980,\n      Value shr 5 and 15,\n      Value and 31) +\n    Frac(LastModTimeAsDateTime);\nend;\n\nprocedure TAbTarItem.SetLastModFileTime(const Value: Word);\nbegin\n  { keep current date, replace time }\n  LastModTimeAsDateTime :=\n    Trunc(LastModTimeAsDateTime) +\n    EncodeTime(\n      Value shr 11,\n      Value shr 5 and 63,\n      Value and 31 shl 1, 0);\nend;\n\nprocedure TAbTarItem.SetLastModTimeAsDateTime(const Value: TDateTime);\nbegin\n  // TAR stores always Unix time.\n  SetModTime(AbLocalDateTimeToUnixTime(Value));    // also updates headers\nend;\n\nprocedure TAbTarItem.SetLinkFlag(Value: AnsiChar);\nbegin\n  if FTarItem.ItemReadOnly then\n    Exit;\n  FTarItem.LinkFlag := Value;\n  PTarHeader.LinkFlag := Value;\n  FTarItem.Dirty := True;\nend;\n\nprocedure TAbTarItem.SetLinkName(const Value: string);\nvar\n  FoundMetaDataHeader: Boolean;\n  PHeader: PAbTarHeaderRec;\n  I, J: Integer;\n  TotalOldNumHeaders: Integer;\n  RawLinkName: AnsiString;\nbegin\n  if FTarItem.ItemReadOnly then { Read Only - Do Not Save }\n    Exit;\n    { Cases:\n    New Link Name is short, Length <= 100,\n      All formats: Zero Name field and move new name to field.\n      V7: Work complete, 1 header\n      USTAR: Work complete, 1 Header\n      OLD_GNU & GNU: Remove old link headers, 1 header.\n      STAR & PAX: And should not yet get here.\n    New File Name is Long, Length >=101\n      Note: The Header Parsing sets any V7 to GNU if 'L'/'K' Headers are present\n      V7: Raise an exception, as this can NOT be done, no change to header.\n      USTAR: Raise an exception, as this can NOT be done, no change to header.\n      if old was Short,  Add files to match format,\n         OLD_GNU & GNU: Create new Link header, Add N Headers for name, Update name in file header, update name fields, min 3 headers\n      if old was Long,\n         OLD_GNU & GNU: Add N Headers for name, Update name in MD header, update name field in File Headers, min 3 headers\n      STAR & PAX: And should not yet get here.}\n  RawLinkName := AbStringToUnixBytes(Value);\n  if Length(RawLinkName) > AB_TAR_NAMESIZE then { Must be null terminated except at 100 char length }\n  begin\n    { Look for long name meta-data headers already in the archive. }\n    FoundMetaDataHeader := False;\n    I := 0;\n    { FTarHeaderList.Count <= 1 always }\n    while (not FoundMetaDataHeader) and (I <= (FTarHeaderList.Count - 1)) do begin\n      PHeader := FTarHeaderList.Items[I];\n      if PHeader.LinkFlag = AB_TAR_LF_LONGLINK then\n      begin { We are growing or Shriking the Name MD Data fields.  }\n        FoundMetaDataHeader := True;\n        DoGNUExistingLongNameLink(AB_TAR_LF_LONGLINK, I, RawLinkName);\n        { Need to copy the Name to the header. }\n        FTarItem.LinkName := Value;\n      end\n      else\n        I := I + 1;\n    end; { End While }\n    { MD Headers & MD Data Headers have been stuffed if FoundMetaDataHeader }\n    { Still need to stuff the File type header contents. }\n    if not FoundMetaDataHeader then\n    begin\n      case FTarItem.ArchiveFormat of\n        V7_FORMAT: raise EAbTarBadLinkName.Create; { Link Name to Long }\n        USTAR_FORMAT: raise EAbTarBadLinkName.Create; { Link Name to Long }\n        OLDGNU_FORMAT: DoGNUNewLongNameLink(AB_TAR_LF_LONGLINK, 0, RawLinkName); {GNU_FORMAT}\n        else\n          begin\n          { UNKNOWN_FORMAT, STAR_FORMAT, POSIX_FORMAT }\n          raise EAbTarBadOp.Create; { Unknown Archive Format }\n        end;{ End of Else for case statement }\n      end;{ End of case statement }\n      FTarItem.LinkName := Value;\n    end; { if no Meta data header found }\n  end { End \"name length larger than 100\" }\n  else\n  begin { Short new name, Simple Case Just put it in the Link Field & remove any headers }\n    { PTarHeader Points to the File type Header }\n    { Zero the Link field }\n    FillChar(PTarHeader.LinkName, SizeOf(PTarHeader.LinkName), #0);\n    if FTarItem.ArchiveFormat in [GNU_FORMAT, OLDGNU_FORMAT] then\n    begin { We may have AB_TAR_LF_LONGNAME Headers to be removed }\n      { Remove long file names Headers if they exist}\n      FoundMetaDataHeader := False;\n      I := 0;\n      while not FoundMetaDataHeader and (I <= (FTarHeaderList.Count - 1)) do\n      begin\n        PHeader := FTarHeaderList.Items[I];\n        if PHeader.LinkFlag in [AB_TAR_LF_LONGLINK] then\n        begin  { Delete this Header, and the data Headers. }\n          FoundMetaDataHeader := True;\n          TotalOldNumHeaders := Ceil( OctalToInt(PHeader.Size, SizeOf(PHeader.Size)) / AB_TAR_RECORDSIZE);\n          for J := TotalOldNumHeaders downto 0 do\n          begin { Note 0 will delete the Long Link MD Header }\n            FreeMem(FTarHeaderList.Items[I+J]); { This list holds PAbTarHeaderRec's }\n            FTarHeaderList.Delete(I+J);\n            FTarHeaderTypeList.Delete(I+J);\n          end;\n        end\n        else\n          I := I + 1; { Got to next header }\n      end;{ End While not found... }\n    end; { End if GNU... }\n    { Save off the new name and store to the Header }\n    FTarItem.LinkName := Value;\n    AbStrPLCopy(PTarHeader.LinkName, RawLinkName, AB_TAR_NAMESIZE);\n  end;{ End else Short new name,... }\n  FTarItem.Dirty := True;\nend;\n\nprocedure TAbTarItem.SetMagic(const Value: String);\nbegin\n  if FTarItem.ItemReadOnly then { Read Only - Do Not Save }\n    Exit;\n  FTarItem.Magic := AnsiString(Value);\n  Move(Value[1], PTarHeader.Magic, SizeOf(TAbTarMagicRec));\n  FTarItem.Dirty := True;\nend;\n\nprocedure TAbTarItem.SetUncompressedSize(const Value: Int64);\nvar\n  S : AnsiString;\nbegin\n  if FTarItem.ItemReadOnly then { Read Only - Do Not Save }\n    Exit;\n  { Size is extendable in PAX Headers, Remember PAX extended Header Over Rule File Headers }\n  FTarItem.Size := Value; { Store our Vitrual Copy }\n  S := PadString(IntToOctal(Value), SizeOf(Arr12));{ Stuff to header }\n  Move(S[1], PTarHeader.Size, Length(S));\n  FTarItem.Dirty := True;\nend;\n\nprocedure TAbTarItem.SetUserID(const Value: Integer);\nvar\n  S : AnsiString;\nbegin\n  if FTarItem.ItemReadOnly then { Read Only - Do Not Save }\n    Exit;\n  { uid is extendable in PAX Headers, Remember PAX extended Header Over Rule File Headers }\n  FTarItem.uid := Value;\n  S := PadString(IntToOctal(Value), SizeOf(Arr8));\n  Move(S[1], PTarHeader.uid, Length(S));\n  FTarItem.Dirty := True;\nend;\n\nprocedure TAbTarItem.SetUserName(const Value: string);\nbegin\n  if FTarItem.ItemReadOnly then { Read Only - Do Not Save }\n    Exit;\n  { UsrName is extendable in PAX Headers, Remember PAX extended Header Over Rule File Headers }\n  FTarItem.UsrName := Value;\n  AbStrPLCopy(PTarHeader.UsrName, AnsiString(Value), SizeOf(PTarHeader.UsrName));\n  FTarItem.Dirty := True;\nend;\n\nprocedure TAbTarItem.SetModTime(const Value: Int64);\nvar\n  S: AnsiString;\nbegin\n  if FTarItem.ItemReadOnly then { Read Only - Do Not Save }\n    Exit;\n  { ModTime is extendable in PAX Headers, Remember PAX extended Header Over Rule File Headers }\n  FTarItem.ModTime := Value; { Store our Virtual Copy }\n  S := PadString(IntToOctal(Value), SizeOf(Arr12));{ Stuff to header }\n  Move(S[1], PTarHeader.ModTime, Length(S));\n  FTarItem.Dirty := True;\nend;\n\n\n{ ************************** TAbTarStreamHelper ****************************** }\ndestructor TAbTarStreamHelper.Destroy;\nbegin\n  inherited Destroy;\nend;\n\n{ This is slow, use the archive class instead }\nprocedure TAbTarStreamHelper.ExtractItemData(AStream: TStream);\nbegin\n  { Note: The SizeOf(TAbTarHeaderRec) = AB_TAR_RECORDSIZE }\n  if FCurrItemSize <> 0 then\n  begin\n    { copy stored data to output }\n    AStream.CopyFrom(FStream, FCurrItemSize);\n    {reset the stream to the start of the item}\n    FStream.Seek(-(FCurrItemPreHdrs*AB_TAR_RECORDSIZE+FCurrItemSize), soCurrent);\n  end;\n  { else do nothing }\nend;\n\n{ This function Should only be used from LoadArchive, as it is slow. }\nfunction TAbTarStreamHelper.FindItem: Boolean;\nvar\n  DataRead : LongInt;\n  FoundItem: Boolean;\n  SkipHdrs : Integer;\nbegin\n  { Note: The SizeOf(TAbTarHeaderRec) = AB_TAR_RECORDSIZE }\n  { Note: Standard LBA size of hard disks is 512 bytes = AB_TAR_RECORDSIZE }\n  FoundItem := False;\n  { Getting an new Item reset these numbers }\n  FCurrItemSize := 0;\n  FCurrItemPreHdrs := 0;\n  DataRead := FStream.Read(FTarHeader, AB_TAR_RECORDSIZE); { Read in a header }\n  { DataRead <> AB_TAR_RECORDSIZE means end of stream, and the End Of Archive\n    record is all #0's, which the StrLen(FTarHeader.Name) check will catch }\n  while (DataRead = AB_TAR_RECORDSIZE) and (AbStrLen(FTarHeader.Name) > 0) and not FoundItem do\n  begin { Either exit when we find a supported file or end of file or an invalid header name. }\n    if FTarHeader.LinkFlag in (AB_SUPPORTED_MD_HEADERS+AB_UNSUPPORTED_MD_HEADERS) then\n    begin { We have a un/supported Meta-Data Header }\n      { FoundItem := False } { Value remains False. }\n      SkipHdrs := Ceil(OctalToInt(FTarHeader.Size, SizeOf(FTarHeader.Size))/AB_TAR_RECORDSIZE);\n      FStream.Seek(SkipHdrs*AB_TAR_RECORDSIZE, soCurrent);\n      { Tally new Headers: Consumed + Current }\n      FCurrItemPreHdrs := FCurrItemPreHdrs + SkipHdrs + 1;\n      { Read our next header, Loop, and re-parse }\n      DataRead := FStream.Read(FTarHeader, AB_TAR_RECORDSIZE);\n    end\n    else if FTarHeader.LinkFlag in (AB_SUPPORTED_F_HEADERS+AB_UNSUPPORTED_F_HEADERS) then\n    begin { We have a un/supported File Header. }\n      FoundItem := True;\n      if not (FTarHeader.LinkFlag in AB_IGNORE_SIZE_HEADERS) then\n        FCurrItemSize := OctalToInt(FTarHeader.Size, SizeOf(FTarHeader.Size))\n      else FCurrItemSize := 0; { Per The spec these Headers do not have file content }\n      FCurrItemPreHdrs := FCurrItemPreHdrs + 1; { Tally current header }\n    end\n    else\n    begin{ We Have an Unknown header }\n      FoundItem := True;\n      FCurrItemSize := 0;\n      { We could have many un/supported headers before this unknown type }\n      FCurrItemPreHdrs := FCurrItemPreHdrs + 1; { Tally current header }\n      { These Headers should throw exceptions when TAbTarItem.LoadTarHeaderFromStream is called }\n    end; { End of Link Flag parsing }\n  end;\n  { Rewind to the \"The Beginning\" of this Item }\n  { Really that means to the first supported Header Type before a supported Item Type }\n  if FoundItem then\n    FStream.Seek(-(FCurrItemPreHdrs*AB_TAR_RECORDSIZE), soCurrent);\n  Result := FoundItem;\nend;\n\n{ Should only be used from LoadArchive, as it is slow. }\nfunction TAbTarStreamHelper.FindFirstItem: Boolean;\nbegin\n  FStream.Seek(0, soBeginning);\n  Result := FindItem;\nend;\n\n{ Should only be used from LoadArchive, as it is slow. }\nfunction TAbTarStreamHelper.FindNextItem: Boolean;\nbegin\n  { Fast Forward Past the current Item }\n  FStream.Seek((FCurrItemPreHdrs*AB_TAR_RECORDSIZE + RoundToTarBlock(FCurrItemSize)), soCurrent);\n  Result := FindItem;\nend;\n\n{ This is slow, use the archive class instead }\nfunction TAbTarStreamHelper.GetItemCount : Integer;\nvar\n  Found : Boolean;\nbegin\n  Result := 0;\n  Found := FindFirstItem;\n  while Found do begin\n    Inc(Result);\n    Found := FindNextItem;\n  end;\nend;\n\nprocedure TAbTarStreamHelper.ReadHeader;\nbegin\n  { do nothing }\n  { Tar archives have no overall header data }\nend;\n\nprocedure TAbTarStreamHelper.ReadTail;\nbegin\n  { do nothing }\n  { Tar archives have no overall tail data }\nend;\n\n{ This is slow, use the archive class instead }\nfunction TAbTarStreamHelper.SeekItem(Index: Integer): Boolean;\nvar\n  i : Integer;\nbegin\n  Result := FindFirstItem; { see if can get to first item }\n  i := 1;\n  while Result and (i < Index) do begin\n    Result := FindNextItem;\n    Inc(i);\n  end;\nend;\n\nprocedure TAbTarStreamHelper.WriteArchiveHeader;\nbegin\n  { do nothing }\n  { Tar archives have no overall header data }\nend;\n\nprocedure TAbTarStreamHelper.WriteArchiveItem(AStream: TStream);\nbegin\n  WriteArchiveItemSize(AStream, AStream.Size);\nend;\n\nprocedure TAbTarStreamHelper.WriteArchiveItemSize(AStream: TStream; Size: Int64);\nvar\n  PadBuff : PAnsiChar;\n  PadSize : Integer;\nbegin\n  if Size = 0 then\n    Exit;\n  { transfer actual item data }\n  FStream.CopyFrom(AStream, Size);\n\n  { Pad to Next block }\n  PadSize := RoundToTarBlock(Size) - Size;\n  GetMem(PadBuff, PadSize);\n  FillChar(PadBuff^, PadSize, #0);\n  FStream.Write(PadBuff^, PadSize);\n  FreeMem(PadBuff, PadSize);\nend;\n\n\nprocedure TAbTarStreamHelper.WriteArchiveTail;\nvar\n  PadBuff : PAnsiChar;\n  PadSize : Integer;\nbegin\n  { append 2 terminating null blocks }\n  PadSize := AB_TAR_RECORDSIZE;\n  GetMem(PadBuff, PadSize);\n  try\n    FillChar(PadBuff^, PadSize, #0);\n    FStream.Write(PadBuff^, PadSize);\n    FStream.Write(PadBuff^, PadSize);\n  finally\n    FreeMem(PadBuff, PadSize);\n  end;\nend;\n\n\n\n{ ***************************** TAbTarArchive ******************************** }\nconstructor TAbTarArchive.CreateFromStream(aStream : TStream; const aArchiveName : string);\nbegin\n  inherited;\n  FArchFormat := V7_FORMAT;  // Default for new archives\nend;\n\nfunction TAbTarArchive.CreateItem(const FileSpec: string): TAbArchiveItem;\nvar\n  Item : TAbTarItem;\n  S : String;\n  I: Integer;\nbegin\n  if FArchReadOnly then\n    raise EAbTarBadOp.Create; { Create Item Unsupported in this Archive }\n\n  S := FixName(FileSpec);\n  Item := TAbTarItem.Create;\n  try\n  //  HeaderFormat = (UNKNOWN_FORMAT, V7_FORMAT, OLDGNU_FORMAT, GNU_FORMAT, USTAR_FORMAT, STAR_FORMAT, POSIX_FORMAT);\n    if FArchFormat in [OLDGNU_FORMAT, GNU_FORMAT] then\n    begin\n      Item.ArchiveFormat := FArchFormat;\n      Item.LinkFlag := AB_TAR_LF_NORMAL;\n      Item.Magic := AB_TAR_MAGIC_GNUOLD;\n    end\n    else if FArchFormat in [USTAR_FORMAT] then\n    begin\n      Item.ArchiveFormat := USTAR_FORMAT;\n      Item.LinkFlag := AB_TAR_LF_NORMAL;\n      Item.Magic := AB_TAR_MAGIC_VAL+AB_TAR_MAGIC_VER;\n    end\n    else if (FArchFormat = V7_FORMAT) and (Length(S) > 100) then\n      begin { Switch the rep over to GNU so it can have long file names. }\n      FArchFormat := OLDGNU_FORMAT;\n      Item.ArchiveFormat := OLDGNU_FORMAT;\n      { Leave the Defaults for LinkFlag, and Magic }\n      { Update all the rest so that it can transistion to GNU_FORMAT }\n      for I := 0 to FItemList.Count - 1 do\n        TAbTarItem(FItemList.Items[i]).ArchiveFormat := OLDGNU_FORMAT;\n    end;{ This should not execute... }{\n    else if FArchFormat in [STAR_FORMAT, POSIX_FORMAT] then\n    begin\n      Item.ArchiveFormat := FArchFormat;\n      Item.LinkFlag := AB_TAR_LF_NORMAL;\n      Item.Magic := AB_TAR_MAGIC_VAL+AB_TAR_MAGIC_VER;\n    end;\n    }{ else  FArchFormat in [ UNKNOWN_FORMAT, V7_FORMAT and Length(S) <= 100 ] } { This is the default. }\n\n    { Most others are initialized in the .Create }\n    Item.CRC32 := 0;\n    { Note this can raise exceptions for file name lengths. }\n    Item.FileName := FixName(FileSpec);\n    Item.DiskFileName := ExpandFileName(FileSpec);\n    Item.Action := aaNone;\n  finally\n    Result := Item;\n  end;\nend;\n\n\nprocedure TAbTarArchive.ExtractItemAt(Index: Integer; const UseName: string);\nvar\n  OutStream : TFileStream;\n  CurItem : TAbTarItem;\nbegin\n  { Check the index is not out of range. }\n  if(Index >= ItemList.Count) then\n      raise EListError.CreateFmt(SListIndexError, [Index]);\n\n  CurItem := TAbTarItem(ItemList[Index]);\n\n  if CurItem.ItemType in [UNKNOWN_ITEM] then\n    raise EAbTarBadOp.Create; { Unsupported Type, Cannot Extract }\n  if (CurItem.ItemType = UNSUPPORTED_ITEM) and\n     ((Length(CurItem.FileName) >= AB_TAR_NAMESIZE) or\n      (Length(CurItem.LinkName) >= AB_TAR_NAMESIZE)) then\n    raise EAbTarBadOp.Create; { Unsupported Type, Cannot Extract }\n  { We will allow extractions if the file name/Link name are strickly less than 100 chars }\n\n  if CurItem.IsDirectory then\n    AbCreateDirectory(UseName)\n  else begin\n    OutStream := TFileStream.Create(UseName, fmCreate or fmShareDenyNone);\n    try\n      try {OutStream}\n        ExtractItemToStreamAt(Index, OutStream);\n      finally {OutStream}\n        OutStream.Free;\n      end; {OutStream}\n    except\n      if ExceptObject is EAbUserAbort then\n        FStatus := asInvalid;\n      DeleteFile(UseName);\n      raise;\n    end;\n  end;\n  AbSetFileTime(UseName, CurItem.LastModTimeAsDateTime);\n  AbSetFileAttr(UseName, CurItem.NativeFileAttributes);\nend;\n\nprocedure TAbTarArchive.ExtractItemToStreamAt(Index: Integer;\n  aStream: TStream);\nvar\n  CurItem : TAbTarItem;\nbegin\n  if(Index >= ItemList.Count) then\n      raise EListError.CreateFmt(SListIndexError, [Index]);\n\n  CurItem := TAbTarItem(ItemList[Index]);\n\n  if CurItem.ItemType in [UNKNOWN_ITEM] then\n    raise EAbTarBadOp.Create; { Unsupported Type, Cannot Extract }\n  if (CurItem.ItemType = UNSUPPORTED_ITEM) and\n     ((Length(CurItem.FileName) >= AB_TAR_NAMESIZE) or\n      (Length(CurItem.LinkName) >= AB_TAR_NAMESIZE)) then\n    raise EAbTarBadOp.Create; { Unsupported Type, Cannot Extract }\n  { We will allow extractions if the file name is strictly less than 100 chars }\n\n  FStream.Position := CurItem.StreamPosition+CurItem.FileHeaderCount*AB_TAR_RECORDSIZE;\n  if CurItem.UncompressedSize <> 0 then\n    aStream.CopyFrom(FStream, CurItem.UncompressedSize);\n  { Else there is nothing to copy. }\nend;\n\nprocedure TAbTarArchive.LoadArchive;\nvar\n  TarHelp      : TAbTarStreamHelper;\n  Item         : TAbTarItem;\n  ItemFound    : Boolean;\n  Abort        : Boolean;\n  Confirm      : Boolean;\n  i            : Integer;\n  Progress     : Byte;\n\nbegin\n  { create helper }\n  TarHelp := TAbTarStreamHelper.Create(FStream);\n  try {TarHelp}\n    {build Items list from tar header records}\n\n    { reset Tar }\n    ItemFound := (FStream.Size > 0) and TarHelp.FindFirstItem;\n    if ItemFound then FArchFormat := UNKNOWN_FORMAT\n    else FArchFormat := V7_FORMAT;\n\n    { while more data in Tar }\n    while (FStream.Position < FStream.Size) and ItemFound do begin\n      {create new Item}\n      Item := TAbTarItem.Create;\n      Item.FTarItem.StreamPosition := FStream.Position;\n      try  {Item}\n        Item.LoadTarHeaderFromStream(FStream);\n        if Item.ItemReadOnly then\n          FArchReadOnly := True; { Set Archive as Read Only }\n        if Item.ItemType in [SUPPORTED_ITEM, UNSUPPORTED_ITEM] then begin\n        { List of supported Item/File Types. }\n          { Add the New Supported Item to the List }\n          if FArchFormat < Item.ArchiveFormat then\n            FArchFormat := Item.ArchiveFormat; { Take the max format }\n          Item.Action := aaNone;\n          FItemList.Add(Item);\n        end { end if }\n        else begin\n        { unhandled Tar file system entity, notify user, but otherwise ignore }\n          if Assigned(FOnConfirmProcessItem) then\n            FOnConfirmProcessItem(self, Item, ptFoundUnhandled, Confirm);\n        end;\n\n        { show progress and allow for aborting }\n        Progress := (FStream.Position*100) div FStream.Size;\n        DoArchiveProgress(Progress, Abort);\n        if Abort then begin\n          FStatus := asInvalid;\n          raise EAbUserAbort.Create;\n        end;\n\n        { get the next item }\n        ItemFound := TarHelp.FindNextItem;\n      except {Item}\n        raise EAbTarBadOp.Create; { Invalid Item }\n      end; {Item}\n    end; {end while }\n\n    { All the items need to reflect this information. }\n    for i := 0 to FItemList.Count - 1 do\n    begin\n      TAbTarItem(FItemList.Items[i]).ArchiveFormat := FArchFormat;\n      TAbTarItem(FItemList.Items[i]).ItemReadOnly := FArchReadOnly;\n    end;\n\n    DoArchiveProgress(100, Abort);\n    FIsDirty := False;\n\n  finally {TarHelp}\n    { Clean Up }\n    TarHelp.Free;\n  end; {TarHelp}\nend;\n\n\nfunction TAbTarArchive.FixName(const Value: string): string;\n{ fixup filename for storage }\nvar\n  lValue : string;\nbegin\n  lValue := Value;\n  {$IFDEF MSWINDOWS}\n  if DOSMode then begin\n    {Add the base directory to the filename before converting }\n    {the file spec to the short filespec format. }\n    if BaseDirectory <> '' then begin\n      {Does the filename contain a drive or a leading backslash? }\n      if not ((Pos(':', lValue) = 2) or (Pos(AbPathDelim, lValue) = 1)) then\n        {If not, add the BaseDirectory to the filename.}\n        lValue := BaseDirectory + AbPathDelim + lValue;\n    end;\n    lValue := AbGetShortFileSpec( lValue );\n  end;\n  {$ENDIF MSWINDOWS}\n\n  { Should always trip drive info if on a Win/Dos system }\n  StoreOptions := StoreOptions + [soStripDrive];\n\n  { strip drive stuff }\n  if soStripDrive in StoreOptions then\n    AbStripDrive( lValue );\n\n  { check for a leading slash }\n  if lValue[1] = AbPathDelim then\n    System.Delete( lValue, 1, 1 );\n\n  if soStripPath in StoreOptions then\n    lValue := ExtractFileName(lValue);\n\n  if soRemoveDots in StoreOptions then\n    AbStripDots(lValue);\n\n  AbFixName(lValue);\n\n  Result := lValue;\nend;\n\nfunction TAbTarArchive.GetItem(Index: Integer): TAbTarItem;\nbegin\n  Result := TAbTarItem(FItemList.Items[Index]);\nend;\n\nfunction TAbTarArchive.GetSupportsEmptyFolders: Boolean;\nbegin\n  Result := True;\nend;\n\nprocedure TAbTarArchive.PutItem(Index: Integer; const Value: TAbTarItem);\nbegin\n  //TODO: Remove this from all archives\n  FItemList.Items[Index] := Value;\nend;\n\nprocedure TAbTarArchive.SaveArchive;\nvar\n  OutTarHelp     : TAbTarStreamHelper;\n  Abort          : Boolean;\n  i              : Integer;\n  NewStream      : TAbVirtualMemoryStream;\n  TempStream     : TStream;\n  SaveDir        : string;\n  CurItem        : TAbTarItem;\n  AttrEx         : TAbAttrExRec;\nbegin\n  if FArchReadOnly then\n    raise EAbTarBadOp.Create; { Archive is read only }\n\n  {init new archive stream}\n  NewStream := TAbVirtualMemoryStream.Create;\n  OutTarHelp := TAbTarStreamHelper.Create(NewStream);\n\n  try {NewStream/OutTarHelp}\n    { create helper }\n    NewStream.SwapFileDirectory := FTempDir;\n\n    {build new archive from existing archive}\n    for i := 0 to pred(Count) do begin\n      FCurrentItem := ItemList[i];\n      CurItem      := TAbTarItem(ItemList[i]);\n\n      case CurItem.Action of\n        aaNone, aaMove : begin  {just copy the file to new stream}\n          { \"Seek\" to the Item Data } { SaveTarHeaders, Updates FileHeaderCount }\n          FStream.Position := CurItem.StreamPosition+CurItem.FileHeaderCount*AB_TAR_RECORDSIZE;\n          CurItem.StreamPosition := NewStream.Position;{ Reset the Stream Pointer. }\n          { Flush The Headers to the new stream }\n          CurItem.SaveTarHeaderToStream(NewStream);\n          { Copy to new Stream, Round to the AB_TAR_RECORDSIZE boundry, and Pad zeros}\n          outTarhelp.WriteArchiveItemSize(FStream, CurItem.UncompressedSize);\n        end;\n\n        aaDelete: {doing nothing omits file from new stream} ;\n\n        aaStreamAdd : begin\n          try\n            { adding from a stream }\n            CurItem.StreamPosition := NewStream.Position;{ Reset the Stream Pointer. }\n            CurItem.UncompressedSize := InStream.Size;\n            CurItem.SaveTarHeaderToStream(NewStream);\n            OutTarHelp.WriteArchiveItemSize(InStream, InStream.Size);\n          except\n            ItemList[i].Action := aaDelete;\n            DoProcessItemFailure(ItemList[i], ptAdd, ecFileOpenError, 0);\n          end;\n        end;\n\n        aaAdd, aaFreshen, aaReplace: begin\n          try\n            { it's coming from a file }\n            GetDir(0, SaveDir);\n            try {SaveDir}\n              if (BaseDirectory <> '') then\n                ChDir(BaseDirectory);\n              { update metadata }\n              if not AbFileGetAttrEx(CurItem.DiskFileName, AttrEx) then\n                raise EAbFileNotFound.Create;\n              CurItem.ExternalFileAttributes := AttrEx.Mode;\n              CurItem.LastModTimeAsDateTime := AttrEx.Time;\n              { TODO: uid, gid, uname, gname should be added here }\n              { TODO: Add support for different types of files here }\n              if (AttrEx.Mode and AB_FMODE_DIR) <> 0 then begin\n                CurItem.LinkFlag := AB_TAR_LF_DIR;\n                CurItem.UncompressedSize := 0;\n                CurItem.SaveTarHeaderToStream(NewStream);\n              end\n              else begin\n                TempStream := TFileStream.Create(CurItem.DiskFileName,\n                  fmOpenRead or fmShareDenyWrite );\n                try { TempStream }\n                  CurItem.UncompressedSize := TempStream.Size;\n                  CurItem.StreamPosition := NewStream.Position;{ Reset the Stream Pointer. }\n                  CurItem.SaveTarHeaderToStream(NewStream);\n                  OutTarHelp.WriteArchiveItemSize(TempStream, TempStream.Size);\n                finally { TempStream }\n                  TempStream.Free;\n                end; { TempStream }\n              end;\n            finally {SaveDir}\n              ChDir( SaveDir );\n            end; {SaveDir}\n          except\n            ItemList[i].Action := aaDelete;\n            DoProcessItemFailure(ItemList[i], ptAdd, ecFileOpenError, 0);\n          end;\n        end; { aaAdd ... }\n      end; { case }\n    end; { for i ... }\n\n    if NewStream.Size <> 0  then\n      OutTarHelp.WriteArchiveTail; { Terminate the TAR }\n    { Size of NewStream is still 0, and max of the stream will also be 0 }\n\n    {copy new stream to FStream}\n    NewStream.Position := 0;\n    if (FStream is TMemoryStream) then\n      TMemoryStream(FStream).LoadFromStream(NewStream)\n    else if (FStream is TAbVirtualMemoryStream) or not FOwnsStream then begin\n      FStream.Size := 0;\n      FStream.Position := 0;\n      FStream.CopyFrom(NewStream, NewStream.Size);\n    end\n    else begin\n      { write to a new stream }\n      FreeAndNil(FStream);\n      FStream := TFileStream.Create(FArchiveName, fmCreate or fmShareDenyWrite);\n      FStream.CopyFrom(NewStream, NewStream.Size);\n    end;\n\n    {update Items list}\n    for i := pred( Count ) downto 0 do begin\n      if ItemList[i].Action = aaDelete then\n        FItemList.Delete( i )\n      else if ItemList[i].Action <> aaFailed then\n        ItemList[i].Action := aaNone;\n    end;\n\n    DoArchiveSaveProgress( 100, Abort );\n    DoArchiveProgress( 100, Abort );\n  finally {NewStream/OutTarHelp}\n    OutTarHelp.Free;\n    NewStream.Free;\n  end;\nend;\n\n{ This assumes that LoadArchive has been called. }\nprocedure TAbTarArchive.TestItemAt(Index: Integer);\nbegin\n  FStream.Position := TAbTarItem(FItemList[Index]).StreamPosition;\n  if VerifyTar(FStream) <> atTar then\n    raise EAbTarInvalid.Create; { Invalid Tar }\nend;\n\nend.\n"
  },
  {
    "path": "lib/abbrevia/source/AbUnzOutStm.pas",
    "content": "(* ***** BEGIN LICENSE BLOCK *****\n * Version: MPL 1.1\n *\n * The contents of this file are subject to the Mozilla Public License Version\n * 1.1 (the \"License\"); you may not use this file except in compliance with\n * the License. You may obtain a copy of the License at\n * http://www.mozilla.org/MPL/\n *\n * Software distributed under the License is distributed on an \"AS IS\" basis,\n * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License\n * for the specific language governing rights and limitations under the\n * License.\n *\n * The Original Code is TurboPower Abbrevia\n *\n * The Initial Developer of the Original Code is Craig Peterson\n *\n * Portions created by the Initial Developer are Copyright (C) 2011\n * the Initial Developer. All Rights Reserved.\n *\n * Contributor(s):\n * Craig Peterson <capeterson@users.sourceforge.net>\n *\n * ***** END LICENSE BLOCK ***** *)\n\n{*********************************************************}\n{* ABBREVIA: AbUnzOutStm.pas                             *}\n{*********************************************************}\n{* ABBREVIA: UnZip output stream;  progress and CRC32    *}\n{*********************************************************}\n\nunit AbUnzOutStm;\n\n{$I AbDefine.inc}\n\ninterface\n\nuses\n  SysUtils, Classes, AbArcTyp;\n\ntype\n  // Fixed-length read-only stream, limits reads to the range between\n  // the input stream's starting position and a specified size.  Seek/Position\n  // are adjusted to be 0 based.\n  TAbUnzipSubsetStream = class( TStream )\n  private\n    FStream : TStream;\n    FStartPos: Int64;\n    FCurPos: Int64;\n    FEndPos: Int64;\n\n  public\n    constructor Create(aStream: TStream; aStreamSize: Int64);\n\n    function Read(var Buffer; Count: Longint): Longint; override;\n    function Write(const Buffer; Count: Longint): Longint; override;\n    function Seek(const Offset: Int64; Origin: TSeekOrigin): Int64; override;\n  end;\n\n\n  // Write-only output stream, computes CRC32 and calls progress event\n  TAbUnzipOutputStream = class( TStream )\n  private\n    FBytesWritten : Int64;\n    FCRC32 : LongInt;\n    FCurrentProgress : Byte;\n    FStream : TStream;\n    FUncompressedSize : Int64;\n    FOnProgress : TAbProgressEvent;\n\n    function GetCRC32 : LongInt;\n\n  public\n    constructor Create(aStream : TStream);\n\n    function Read(var Buffer; Count: Longint): Longint; override;\n    function Write(const Buffer; Count: Longint): Longint; override;\n    function Seek(const Offset: Int64; Origin: TSeekOrigin): Int64; override;\n\n    property CRC32 : LongInt\n      read GetCRC32;\n    property Stream : TStream\n      read FStream\n      write FStream;\n    property UncompressedSize : Int64\n      read FUncompressedSize\n      write FUncompressedSize;\n    property OnProgress : TAbProgressEvent\n      read FOnProgress\n      write FOnProgress;\n  end;\n\n\nimplementation\n\nuses\n  Math, AbExcept, AbUtils;\n\n{ TAbUnzipSubsetStream implementation ====================================== }\n\n{ -------------------------------------------------------------------------- }\nconstructor TAbUnzipSubsetStream.Create(aStream: TStream; aStreamSize: Int64);\nbegin\n  inherited Create;\n  FStream := aStream;\n  FStartPos := FStream.Position;\n  FCurPos := FStartPos;\n  FEndPos := FStartPos + aStreamSize;\nend;\n{ -------------------------------------------------------------------------- }\nfunction TAbUnzipSubsetStream.Read(var Buffer; Count: Longint): Longint;\nbegin\n  if Count > FEndPos - FCurPos then\n    Count := FEndPos - FCurPos;\n  if Count > 0 then begin\n    Result := FStream.Read(Buffer, Count);\n    Inc(FCurPos, Result);\n  end\n  else\n    Result := 0;\nend;\n{ -------------------------------------------------------------------------- }\nfunction TAbUnzipSubsetStream.Write(const Buffer; Count: Longint): Longint;\nbegin\n  raise EAbException.Create('TAbUnzipSubsetStream.Write not supported');\nend;\n{ -------------------------------------------------------------------------- }\nfunction TAbUnzipSubsetStream.Seek(const Offset: Int64; Origin: TSeekOrigin): Int64;\nvar\n  OldPos: Int64;\nbegin\n  OldPos := FCurPos;\n  case Origin of\n    soBeginning: FCurPos := FStartPos + Offset;\n    soCurrent: FCurPos := FCurPos + Offset;\n    soEnd: FCurPos := FEndPos + Offset;\n  end;\n  if FCurPos < FStartPos then\n    FCurPos := FStartPos;\n  if FCurPos > FEndPos then\n    FCurPos := FEndPos;\n  if OldPos <> FCurPos then\n    FStream.Position := FCurPos;\n  Result := FCurPos - FStartPos;\nend;\n{ -------------------------------------------------------------------------- }\n\n\n{ TAbUnzipOutputStream implementation ====================================== }\n\n{ -------------------------------------------------------------------------- }\nconstructor TAbUnzipOutputStream.Create(aStream: TStream);\nbegin\n  inherited Create;\n  FStream := aStream;\n  FCRC32 := -1;\nend;\n{ -------------------------------------------------------------------------- }\nfunction TAbUnzipOutputStream.Read(var Buffer; Count: Integer): Longint;\nbegin\n  raise EAbException.Create('TAbUnzipOutputStream.Read not supported');\nend;\n{ -------------------------------------------------------------------------- }\nfunction TAbUnzipOutputStream.Write(const Buffer; Count: Longint): Longint;\nvar\n  Abort : Boolean;\n  NewProgress : Byte;\nbegin\n  AbUpdateCRC( FCRC32, Buffer, Count );\n\n  Result := FStream.Write(Buffer, Count);\n\n  Inc( FBytesWritten, Result );\n  if Assigned( FOnProgress ) then begin\n    Abort := False;\n    NewProgress := AbPercentage(FBytesWritten, FUncompressedSize);\n    if (NewProgress <> FCurrentProgress) then begin\n      FOnProgress( NewProgress, Abort );\n      FCurrentProgress := NewProgress;\n    end;\n    if Abort then\n      raise EAbUserAbort.Create;\n  end;\nend;\n{ -------------------------------------------------------------------------- }\nfunction TAbUnzipOutputStream.Seek(const Offset: Int64; Origin: TSeekOrigin): Int64;\nbegin\n  Result := FStream.Seek(Offset, Origin);\nend;\n{ -------------------------------------------------------------------------- }\nfunction TAbUnzipOutputStream.GetCRC32: LongInt;\nbegin\n  Result := not FCRC32;\nend;\n\nend.\n\n"
  },
  {
    "path": "lib/abbrevia/source/AbUnzPrc.pas",
    "content": "(* ***** BEGIN LICENSE BLOCK *****\n * Version: MPL 1.1\n *\n * The contents of this file are subject to the Mozilla Public License Version\n * 1.1 (the \"License\"); you may not use this file except in compliance with\n * the License. You may obtain a copy of the License at\n * http://www.mozilla.org/MPL/\n *\n * Software distributed under the License is distributed on an \"AS IS\" basis,\n * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License\n * for the specific language governing rights and limitations under the\n * License.\n *\n * The Original Code is TurboPower Abbrevia\n *\n * The Initial Developer of the Original Code is\n * TurboPower Software\n *\n * Portions created by the Initial Developer are Copyright (C) 1997-2002\n * the Initial Developer. All Rights Reserved.\n *\n * Contributor(s):\n * Craig Peterson <capeterson@users.sourceforge.net>\n *\n * ***** END LICENSE BLOCK ***** *)\n\n{*********************************************************}\n{* ABBREVIA: AbUnzPrc.pas                                *}\n{*********************************************************}\n{* ABBREVIA: UnZip procedures                            *}\n{*********************************************************}\n\nunit AbUnzPrc;\n\n{$I AbDefine.inc}\n\ninterface\n\nuses\n  Classes,\n  AbArcTyp,\n  AbZipTyp;\n\ntype\n  TAbUnzipHelper = class( TObject )\n  protected {private}\n    {internal variables}\n    FOutWriter : TStream;\n    FOutStream : TStream;\n    FUnCompressedSize : LongInt;\n    FCompressionMethod : TAbZipCompressionMethod;\n    FDictionarySize : TAbZipDictionarySize;\n    FShannonFanoTreeCount : Byte;\n\n    FOutBuf : PAbByteArray;          {output buffer}\n    FOutSent : LongInt;              {number of bytes sent to output buffer}\n    FOutPos : Cardinal;              {current position in output buffer}\n    FBitSValid : Byte;               {Number of valid bits}\n\n    FInBuf : TAbByteArray4K;\n    FInPos : Integer;                {current position in input buffer}\n    FInCnt : Integer;                {number of bytes in input buffer}\n    FInEof  : Boolean;               {set when stream read returns 0}\n    FCurByte : Byte;                 {current input byte}\n    FBitsLeft : Byte;                {bits left to process in FCurByte}\n\n    FZStream : TStream;\n  protected\n    procedure uzFlushOutBuf;\n      {-Flushes the output buffer}\n\n    function uzReadBits(Bits : Byte) : Integer;\n      {-Read the specified number of bits}\n    procedure uzReadNextPrim;\n      {-does less likely part of uzReadNext}\n\n    {$IFDEF UnzipImplodeSupport}\n    procedure uzUnImplode;\n      {-Extract an imploded file}\n    {$ENDIF}\n\n    {$IFDEF UnzipReduceSupport}\n    procedure uzUnReduce;\n      {-Extract a reduced file}\n    {$ENDIF}\n\n    {$IFDEF UnzipShrinkSupport}\n    procedure uzUnShrink;\n      {-Extract a shrunk file}\n    {$ENDIF}\n    procedure uzWriteByte(B : Byte);\n      {write to output}\n  public\n    constructor Create( InputStream, OutputStream : TStream );\n    destructor Destroy;\n      override;\n\n    procedure Execute;\n\n    property UnCompressedSize : LongInt\n      read FUncompressedSize\n      write FUncompressedSize;\n    property CompressionMethod : TAbZipCompressionMethod\n      read FCompressionMethod\n      write FCompressionMethod;\n    property DictionarySize : TAbZipDictionarySize\n      read FDictionarySize\n      write FDictionarySize;\n    property ShannonFanoTreeCount : Byte\n      read FShannonFanoTreeCount\n      write FShannonFanoTreeCount;\n  end;\n\n\n\n  procedure AbUnzipToStream( Sender : TObject; Item : TAbZipItem;\n    OutStream : TStream);\n\n  procedure AbUnzip(Sender : TObject; Item : TAbZipItem; const UseName : string);\n\n  procedure AbTestZipItem(Sender : TObject; Item : TAbZipItem);\n\n  procedure InflateStream(CompressedStream, UnCompressedStream : TStream);\n  {-Inflates everything in CompressedStream to UncompressedStream\n    no encryption is tried, no check on CRC is done, uses the whole\n    compressedstream - no Progress events - no Frills!}\n\nimplementation\n\nuses\n  {$IFDEF MSWINDOWS}\n  Windows,\n  {$ENDIF}\n  SysUtils,\n  {$IFDEF UnzipBzip2Support}\n  AbBzip2,\n  {$ENDIF}\n  {$IFDEF UnzipLzmaSupport}\n  AbLzma,\n  {$ENDIF}\n  {$IFDEF UnzipPPMdSupport}\n  AbPPMd,\n  {$ENDIF}\n  {$IFDEF UnzipWavPackSupport}\n  AbWavPack,\n  {$ENDIF}\n  AbBitBkt,\n  AbConst,\n  AbDfBase,\n  AbDfCryS,\n  AbDfDec,\n  AbExcept,\n  AbSpanSt,\n  AbSWStm,\n  AbUnzOutStm,\n  AbUtils;\n\n{ -------------------------------------------------------------------------- }\nprocedure AbReverseBits(var W : Word);\n  {-Reverse the order of the bits in W}\nregister;\nconst\n  RevTable : array[0..255] of Byte = ($00, $80, $40, $C0, $20, $A0, $60,\n   $E0, $10, $90, $50, $D0, $30, $B0, $70, $F0, $08, $88, $48, $C8, $28,\n   $A8, $68, $E8, $18, $98, $58, $D8, $38, $B8, $78, $F8, $04, $84, $44,\n   $C4, $24, $A4, $64, $E4, $14, $94, $54, $D4, $34, $B4, $74, $F4, $0C,\n   $8C, $4C, $CC, $2C, $AC, $6C, $EC, $1C, $9C, $5C, $DC, $3C, $BC, $7C,\n   $FC, $02, $82, $42, $C2, $22, $A2, $62, $E2, $12, $92, $52, $D2, $32,\n   $B2, $72, $F2, $0A, $8A, $4A, $CA, $2A, $AA, $6A, $EA, $1A, $9A, $5A,\n   $DA, $3A, $BA, $7A, $FA, $06, $86, $46, $C6, $26, $A6, $66, $E6, $16,\n   $96, $56, $D6, $36, $B6, $76, $F6, $0E, $8E, $4E, $CE, $2E, $AE, $6E,\n   $EE, $1E, $9E, $5E, $DE, $3E, $BE, $7E, $FE, $01, $81, $41, $C1, $21,\n   $A1, $61, $E1, $11, $91, $51, $D1, $31, $B1, $71, $F1, $09, $89, $49,\n   $C9, $29, $A9, $69, $E9, $19, $99, $59, $D9, $39, $B9, $79, $F9, $05,\n   $85, $45, $C5, $25, $A5, $65, $E5, $15, $95, $55, $D5, $35, $B5, $75,\n   $F5, $0D, $8D, $4D, $CD, $2D, $AD, $6D, $ED, $1D, $9D, $5D, $DD, $3D,\n   $BD, $7D, $FD, $03, $83, $43, $C3, $23, $A3, $63, $E3, $13, $93, $53,\n   $D3, $33, $B3, $73, $F3, $0B, $8B, $4B, $CB, $2B, $AB, $6B, $EB, $1B,\n   $9B, $5B, $DB, $3B, $BB, $7B, $FB, $07, $87, $47, $C7, $27, $A7, $67,\n   $E7, $17, $97, $57, $D7, $37, $B7, $77, $F7, $0F, $8F, $4F, $CF, $2F,\n   $AF, $6F, $EF, $1F, $9F, $5F, $DF, $3F, $BF, $7F, $FF);\nbegin\n  W := RevTable[Byte(W shr 8)] or Word(RevTable[Byte(W)] shl 8);\nend;\n\n\n{ TAbUnzipHelper implementation ============================================ }\n\n{ -------------------------------------------------------------------------- }\nconstructor TAbUnzipHelper.Create( InputStream, OutputStream : TStream );\nbegin\n  inherited Create;\n  FOutBuf := AllocMem( AbBufferSize );\n  FOutPos := 0;                                                        \n  FZStream := InputStream;\n  FOutStream := OutputStream;\n  FUncompressedSize := 0;\n  FDictionarySize := dsInvalid;\n  FShannonFanoTreeCount := 0;\n  FCompressionMethod := cmDeflated;\nend;\n{ -------------------------------------------------------------------------- }\ndestructor TAbUnzipHelper.Destroy;\nbegin\n  FreeMem( FOutBuf, AbBufferSize );                                    \n  inherited Destroy;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbUnzipHelper.Execute;\nbegin\n  {parent class handles exceptions via OnExtractFailure}\n  FBitsLeft := 0;\n  FCurByte := 0;\n  FInCnt := 0;\n  FOutSent := 0;\n  FOutPos := 0;\n  FInEof := False;\n\n  {set the output stream; for Imploded/Reduced files this has to be\n   buffered, for all other types of compression, the code buffers the\n   output data nicely and so the given output stream can be used.}\n  {$IFDEF UnzipImplodeSupport}\n  if (FCompressionMethod = cmImploded) then\n    FOutWriter := TabSlidingWindowStream.Create(FOutStream)\n  else\n  {$ENDIF}\n  {$IFDEF UnzipReduceSupport}\n  if (FCompressionMethod >= cmReduced1) and\n     (FCompressionMethod <= cmReduced4) then\n    FOutWriter := TabSlidingWindowStream.Create(FOutStream)\n  else\n  {$ENDIF}\n    FOutWriter := FOutStream;\n  FInPos := 1+SizeOf(FInBuf);\n\n{  GetMem( FInBuf, SizeOf(FInBuf^) );}\n  try\n    {uncompress it with the appropriate method}\n    case FCompressionMethod of\n      {$IFDEF UnzipShrinkSupport}\n      cmShrunk               : uzUnshrink;\n      {$ENDIF}\n      {$IFDEF UnzipReduceSupport}\n      cmReduced1..cmReduced4 : uzUnReduce;\n      {$ENDIF}\n      {$IFDEF UnzipImplodeSupport}\n      cmImploded             : uzUnImplode;\n      {$ENDIF}\n      {cmTokenized}\n      {cmEnhancedDeflated}\n      {cmDCLImploded}\n    else\n      raise EAbZipInvalidMethod.Create;\n    end;\n\n  finally\n    uzFlushOutBuf;\n    {free any memory}\n    if (FOutWriter <> FOutStream) then\n      FOutWriter.Free;\n  end;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbUnzipHelper.uzReadNextPrim;\nbegin\n  FInCnt := FZStream.Read( FInBuf, sizeof( FInBuf ) );\n  FInEof := FInCnt = 0;\n  {load first byte in buffer and set position counter}\n  FCurByte := FInBuf[1];\n  FInPos := 2;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbUnzipHelper.uzFlushOutBuf;\n  {-flushes the output buffer}\nbegin\n  if (FOutPos <> 0) then begin\n    FOutWriter.Write( FOutBuf^, FOutPos );\n    Inc( FOutSent, FOutPos );\n    FOutPos := 0;\n  end;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbUnzipHelper.uzWriteByte(B : Byte);\n  {-Write one byte to the output buffer}\nbegin\n  FOutBuf^[FOutPos] := B;\n  inc(FOutPos);\n  if (FOutPos = AbBufferSize) or\n     (LongInt(FOutPos) + FOutSent = FUncompressedSize) then\n    uzFlushOutBuf;\nend;\n{ -------------------------------------------------------------------------- }\nfunction TAbUnzipHelper.uzReadBits(Bits : Byte) : Integer;\n  {-Read the specified number of bits}\nvar\n  SaveCurByte, Delta, SaveBitsLeft : Byte;\nbegin\n  {read next byte if we're out of bits}\n  if FBitsLeft = 0 then begin\n    {do we still have a byte buffered?}\n    if FInPos <= FInCnt then begin\n      {get next byte out of buffer and advance position counter}\n      FCurByte := FInBuf[FInPos];\n      Inc(FInPos);\n    end\n    {are there any left to read?}\n    else\n      uzReadNextPrim;\n\n    FBitsLeft := 8;\n  end;\n  if ( Bits < FBitsLeft ) then begin\n    Dec( FBitsLeft, Bits );\n    Result := ((1 shl Bits) - 1) and FCurByte;\n    FCurByte := FCurByte shr Bits;\n  end\n  else if ( Bits = FBitsLeft ) then begin\n    Result := FCurByte;\n    FCurByte := 0;\n    FBitsLeft := 0;\n  end\n  else begin\n    SaveCurByte := FCurByte;\n    SaveBitsLeft := FBitsLeft;\n    {number of additional bits that we need}\n    Delta := Bits - FBitsLeft;\n    {do we still have a byte buffered?}\n    if FInPos <= FInCnt then begin\n      {get next byte out of buffer and advance position counter}\n      FCurByte := FInBuf[FInPos];\n      Inc(FInPos);\n    end\n    {are there any left to read?}\n    else\n      uzReadNextPrim;\n\n    FBitsLeft := 8;\n    Result := ( uzReadBits( Delta ) shl SaveBitsLeft ) or SaveCurByte;\n  end;\nend;\n{$IFDEF UnzipImplodeSupport}\n{ -------------------------------------------------------------------------- }\nprocedure TAbUnzipHelper.uzUnImplode;\n    {-Extract an imploded file}\nconst\n  szLengthTree = SizeOf(TAbSfTree)-(192*SizeOf(TAbSfEntry));\n  szDistanceTree = SizeOf(TAbSfTree)-(192*SizeOf(TAbSfEntry));\n  szLitTree = SizeOf(TAbSfTree);\nvar\n  Length : Integer;\n  DIndex : LongInt;\n  Distance : Integer;\n  SPos : LongInt;\n  MyByte : Byte;\n  DictBits : Integer;             {number of bits used in sliding dictionary}\n  MinMatchLength : Integer;       {minimum match length}\n  LitTree : PAbSfTree;              {Literal tree}\n  LengthTree : PAbSfTree;           {Length tree}\n  DistanceTree : PAbSfTree;         {Distance tree}\n\n  procedure uzLoadTree(var T; TreeSize : Integer);\n    {-Load one Shannon-Fano tree}\n  var\n    I : Word;\n    Tree : TAbSfTree absolute T;\n\n    procedure GenerateTree;\n      {-Generate a Shannon-Fano tree}\n    var\n      C : Word;\n      CodeIncrement : Integer;\n      LastBitLength : Integer;\n      I : Integer;\n    begin\n      C := 0;\n      CodeIncrement := 0;\n      LastBitLength := 0;\n\n      for I := Tree.Entries-1 downto 0 do\n        with Tree.Entry[I] do begin\n          Inc(C, CodeIncrement);\n          if BitLength <> LastBitLength then begin\n            LastBitLength := BitLength;\n            CodeIncrement := 1 shl (16-LastBitLength);\n          end;\n          Code := C;\n        end;\n    end;\n\n    procedure SortLengths;\n      {-Sort the bit lengths in ascending order, while retaining the order\n        of the original lengths stored in the file}\n    var\n      XL : Integer;\n      XGL : Integer;\n      TXP  : PAbSfEntry;\n      TXGP : PAbSfEntry;\n      X, Gap : Integer;\n      Done : Boolean;\n      LT : LongInt;\n    begin\n      Gap := Tree.Entries shr 1;\n      repeat\n        repeat\n          Done := True;\n          for X := 0 to (Tree.Entries-1)-Gap do begin\n            TXP := @Tree.Entry[X];\n            TXGP := @Tree.Entry[X+Gap];\n            XL := TXP^.BitLength;\n            XGL := TXGP^.BitLength;\n            if (XL > XGL) or\n               ((XL = XGL) and (TXP^.Value > TXGP^.Value)) then begin\n              LT := TXP^.L;\n              TXP^.L := TXGP^.L;\n              TXGP^.L := LT;\n              Done := False;\n            end;\n          end;\n        until Done;\n\n        Gap := Gap shr 1;\n      until (Gap = 0);\n    end;\n\n    procedure uzReadLengths;\n      {-Read bit lengths for a tree}\n    var\n      TreeBytes : Integer;\n      I, J, K : Integer;\n      Num, Len : Integer;\n      B : Byte;\n    begin\n      {get number of bytes in compressed tree}\n      TreeBytes := uzReadBits(8)+1;\n\n      I := 0;\n      Tree.MaxLength := 0;\n\n      {High nibble: Number of values at this bit length + 1.\n       Low  nibble: Bits needed to represent value + 1}\n      for J := 1 to TreeBytes do begin\n        B := uzReadBits(8);\n        Len := (B and $0F)+1;\n        Num := (B shr 4)+1;\n\n        for K := I to I+Num-1 do\n          with Tree, Entry[K] do begin\n            if Len > MaxLength then\n              MaxLength := Len;\n            BitLength := Len;\n            Value := K;\n          end;\n        Inc(I, Num);\n      end;\n    end;\n\n  begin\n    Tree.Entries := TreeSize;\n    uzReadLengths;\n    SortLengths;\n    GenerateTree;\n    for I := 0 to TreeSize-1 do\n      AbReverseBits(Tree.Entry[I].Code);\n  end;\n\n  function uzReadTree(var T) : Byte;\n    {-Read next byte using a Shannon-Fano tree}\n  var\n    Bits : Integer;\n    CV   : Word;\n    E    : Integer;\n    Cur  : Integer;\n  var\n    Tree : TAbSfTree absolute T;\n  begin\n    Result := 0;\n    Bits := 0;\n    CV := 0;\n    Cur := 0;\n    E := Tree.Entries;\n    repeat\n      CV := CV or (uzReadBits(1) shl Bits);\n      Inc(Bits);\n      while Tree.Entry[Cur].BitLength < Bits do begin\n        Inc(Cur);\n        if Cur >= E then\n          Exit;\n      end;\n      while Tree.Entry[Cur].BitLength = Bits do begin\n        if Tree.Entry[Cur].Code = CV then begin\n          Result := Tree.Entry[Cur].Value;\n          Exit;\n        end;\n        Inc(Cur);\n        if Cur >= E then\n          Exit;\n      end;\n    until False;\n  end;\n\nbegin\n  {do we have an 8K dictionary?}\n  if FDictionarySize = ds8K then\n    DictBits := 7\n  else\n    DictBits := 6;\n\n  {allocate trees}\n  LengthTree := AllocMem(szLengthTree);\n  DistanceTree := AllocMem(szDistanceTree);\n  LitTree := nil;\n  try\n    {do we have a Literal tree?}\n    MinMatchLength := FShannonFanoTreeCount;\n    if MinMatchLength = 3 then begin\n      LitTree := AllocMem(szLitTree);\n      uzLoadTree(LitTree^, 256);\n    end;\n\n    {load the other two trees}\n    uzLoadTree(LengthTree^, 64);\n    uzLoadTree(DistanceTree^, 64);\n\n    while (not FInEof) and (FOutSent + LongInt(FOutPos) < FUncompressedSize) do\n      {is data literal?}\n      if Boolean(uzReadBits(1)) then begin\n        {if MinMatchLength = 3 then we have a Literal tree}\n        if (MinMatchLength = 3) then\n          uzWriteByte( uzReadTree(LitTree^) )\n        else\n          uzWriteByte( uzReadBits(8) );\n      end\n      else begin\n        {data is a sliding dictionary}\n        Distance := uzReadBits(DictBits);\n\n        {using the Distance Shannon-Fano tree, read and decode the\n         upper 6 bits of the Distance value}\n        Distance := Distance or (uzReadTree(DistanceTree^) shl DictBits);\n\n        {using the Length Shannon-Fano tree, read and decode the Length value}\n        Length := uzReadTree(LengthTree^);\n        if Length = 63 then\n          Inc(Length, uzReadBits(8));\n        Inc(Length, MinMatchLength);\n\n        {move backwards Distance+1 bytes in the output stream, and copy\n         Length characters from this position to the output stream.\n         (if this position is before the start of the output stream,\n         then assume that all the data before the start of the output\n         stream is filled with zeros)}\n        DIndex := (FOutSent + LongInt(FOutPos))-(Distance+1);\n        while Length > 0 do begin\n          if DIndex < 0 then\n            uzWriteByte(0)\n          else begin\n            uzFlushOutBuf;\n            SPos := FOutWriter.Position;\n            FOutWriter.Position := DIndex;\n            FOutWriter.Read( MyByte, 1 );\n            FOutWriter.Position := SPos;\n            uzWriteByte(MyByte);\n          end;\n          Inc(DIndex);\n          Dec(Length);\n        end;\n      end;\n  finally\n    if (LitTree <> nil) then\n      FreeMem(LitTree, szLitTree);\n    FreeMem(LengthTree, szLengthTree);\n    FreeMem(DistanceTree, szDistanceTree);\n  end;\nend;\n{$ENDIF UnzipImplodeSupport}\n{ -------------------------------------------------------------------------- }\n{$IFDEF UnzipReduceSupport}\nprocedure TAbUnzipHelper.uzUnReduce;\nconst\n  FactorMasks : array[1..4] of Byte = ($7F, $3F, $1F, $0F);\n  DLE = 144;\nvar\n  C, Last : Byte;\n  OpI : LongInt;\n  I, J, Sz : Integer;\n  D : Word;\n  SPos : LongInt;\n  MyByte : Byte;\n  Factor : Byte;                  {reduction Factor}\n  FactorMask : Byte;              {bit mask to use based on Factor}\n  Followers : PAbFollowerSets;      {array of follower sets}\n  State : Integer;                {used while processing reduced files}\n  V : Integer;                    {\"}\n  Len : Integer;                  {\"}\n\n  function BitsNeeded( i : Byte ) : Word;\n  begin\n    dec( i );\n    Result := 0;\n    repeat\n      inc( Result );\n      i := i shr 1;\n    until i = 0;\n  end;\n\nbegin\n  GetMem(Followers, SizeOf(TAbFollowerSets));\n  try\n    Factor := Ord( FCompressionMethod ) - 1;\n    FactorMask := FactorMasks[Factor];\n    State := 0;\n    C := 0;\n    V := 0;\n    Len := 0;\n    D := 0;\n\n    {load follower sets}\n    for I := 255 downto 0 do begin\n      Sz := uzReadBits(6);\n      Followers^[I].Size := Sz;\n      Dec(Sz);\n      for J := 0 to Sz do\n        Followers^[I].FSet[J] := uzReadBits(8);\n    end;\n\n    while (not FInEof) and ((FOutSent + LongInt(FOutPos)) < FUncompressedSize) do begin\n      Last := C;\n      with Followers^[Last] do\n        if Size = 0 then\n          C := uzReadBits(8)\n        else begin\n          C := uzReadBits(1);\n          if C <> 0 then\n            C := uzReadBits(8)\n          else\n            C := FSet[uzReadBits(BitsNeeded(Size))];\n        end;\n\n      if FInEof then\n        Exit;\n\n      case State of\n        0 :\n          if C <> DLE then\n            uzWriteByte(C)\n          else\n            State := 1;\n        1 :\n          if C <> 0 then begin\n            V := C;\n            Len := V and FactorMask;\n            if Len = FactorMask then\n              State := 2\n            else\n              State := 3;\n          end\n          else begin\n            uzWriteByte(DLE);\n            State := 0;\n          end;\n\n        2 :\n          begin\n            Inc(Len, C);\n            State := 3;\n          end;\n\n        3 :\n          begin\n            case Factor of\n              1 : D := (V shr 7) and $01;\n              2 : D := (V shr 6) and $03;\n              3 : D := (V shr 5) and $07;\n              4 : D := (V shr 4) and $0f;\n            else\n              raise EAbZipInvalidFactor.Create;\n            end;\n            {Delphi raises compiler Hints here, saying D might\n             be undefined...  If Factor is not in [1..4], the\n             exception gets raised, and we never execute the following\n             line}\n            OpI := (FOutSent + LongInt(FOutPos))-(Swap(D)+C+1);\n\n            for I := 0 to Len+2 do begin\n              if OpI < 0 then\n                uzWriteByte(0)\n              else if OpI >= FOutSent then\n                uzWriteByte(FOutBuf[OpI - FOutSent])\n              else begin\n                SPos := FOutWriter.Position;\n                FOutWriter.Position := OpI;\n                FOutWriter.Read( MyByte, 1 );\n                FOutWriter.Position := SPos;\n                uzWriteByte(MyByte);\n              end;\n              Inc(OpI);\n            end;\n\n            State := 0;\n          end;\n      end;\n    end;\n  finally\n    FreeMem(Followers, SizeOf(Followers^));\n  end;\nend;\n{$ENDIF UnzipReduceSupport}\n{ -------------------------------------------------------------------------- }\n{$IFDEF UnzipShrinkSupport}\nprocedure TAbUnzipHelper.uzUnShrink;\n  {-Extract a file that was shrunk}\nconst\n  MaxBits = 13;\n  InitBits = 9;\n  FirstFree = 257;\n  Clear = 256;\n  MaxCodeMax = 8192; {= 1 shl MaxBits}\n  Unused = -1;\nvar\n  CodeSize : SmallInt;\n  NextFree : SmallInt;\n  BaseChar : SmallInt;\n  NewCode : SmallInt;\n  OldCode : SmallInt;\n  SaveCode : SmallInt;\n  N, R : SmallInt;\n  I : Integer;\n  PrefixTable : PAbIntArray8K;      {used while processing shrunk files}\n  SuffixTable : PAbByteArray8K;     {\"}\n  Stack : PAbByteArray8K;           {\"}\n  StackIndex : Integer;           {\"}\nbegin\n  CodeSize := InitBits;\n{  MaxCode := (1 shl InitBits)-1;}\n  NextFree := FirstFree;\n\n  PrefixTable := nil;\n  SuffixTable := nil;\n  Stack := nil;\n\n  try\n    GetMem(PrefixTable, SizeOf(PrefixTable^));\n    SuffixTable := AllocMem(SizeOf(SuffixTable^));\n    GetMem(Stack, SizeOf(Stack^));\n\n    FillChar(PrefixTable^, SizeOf(PrefixTable^), $FF);\n    for NewCode := 255 downto 0 do begin\n      PrefixTable^[NewCode] := 0;\n      SuffixTable^[NewCode] := NewCode;\n    end;\n\n    OldCode := uzReadBits(CodeSize);\n    if FInEof then\n      Exit;\n    BaseChar := OldCode;\n\n    uzWriteByte(BaseChar);\n\n    StackIndex := 0;\n    while (not FInEof) do begin\n      NewCode := uzReadBits(CodeSize);\n      while (NewCode = Clear) and (not FInEof) do begin\n        case uzReadBits(CodeSize) of\n          1 : begin\n                Inc(CodeSize);\n              end;\n          2 : begin\n                {mark all nodes as potentially unused}\n                for I := FirstFree to pred( NextFree ) do\n                  PrefixTable^[I] := PrefixTable^[I] or LongInt($8000);\n\n                {unmark those used by other nodes}\n                for N := FirstFree to NextFree-1 do begin\n                  {reference to another node?}\n                  R := PrefixTable^[N] and $7FFF;\n                  {flag node as referenced}\n                  if R >= FirstFree then\n                    PrefixTable^[R] := PrefixTable^[R] and $7FFF;\n                end;\n\n                {clear the ones that are still marked}\n                for I := FirstFree to pred( NextFree ) do\n                  if PrefixTable^[I] < 0 then\n                    PrefixTable^[I] := -1;\n\n                {recalculate NextFree}\n                NextFree := FirstFree;\n                while (NextFree < MaxCodeMax) and\n                      (PrefixTable^[NextFree] <> -1) do\n                  Inc(NextFree);\n              end;\n        end;\n\n        NewCode := uzReadBits(CodeSize);\n      end;\n\n      if FInEof then\n        Exit;\n\n      {save current code}\n      SaveCode := NewCode;\n\n      {special case}\n      if PrefixTable^[NewCode] = Unused then begin\n        Stack^[StackIndex] := BaseChar;\n        Inc(StackIndex);\n        NewCode := OldCode;\n      end;\n\n      {generate output characters in reverse order}\n      while (NewCode >= FirstFree) do begin\n        if PrefixTable^[NewCode] = Unused then begin\n          Stack^[StackIndex] := BaseChar;\n          Inc(StackIndex);\n          NewCode := OldCode;\n        end else begin\n          Stack^[StackIndex] := SuffixTable^[NewCode];\n          Inc(StackIndex);\n          NewCode := PrefixTable^[NewCode];\n        end;\n      end;\n\n      BaseChar := SuffixTable^[NewCode];\n      uzWriteByte(BaseChar);\n\n      {put them out in forward order}\n      while (StackIndex > 0) do begin\n        Dec(StackIndex);\n        uzWriteByte(Stack^[StackIndex]);\n      end;\n\n      {add new entry to tables}\n      NewCode := NextFree;\n      if NewCode < MaxCodeMax then begin\n        PrefixTable^[NewCode] := OldCode;\n        SuffixTable^[NewCode] := BaseChar;\n        while (NextFree < MaxCodeMax) and\n              (PrefixTable^[NextFree] <> Unused) do\n          Inc(NextFree);\n      end;\n\n      {remember previous code}\n      OldCode := SaveCode;\n    end;\n  finally\n    FreeMem(PrefixTable, SizeOf(PrefixTable^));\n    FreeMem(SuffixTable, SizeOf(SuffixTable^));\n    FreeMem(Stack, SizeOf(Stack^));\n  end;\nend;\n{$ENDIF}\n{ -------------------------------------------------------------------------- }\nprocedure RequestPassword(Archive : TAbZipArchive; var Abort : Boolean);\nvar\n  APassPhrase : AnsiString;\nbegin\n  APassPhrase := Archive.Password;\n  Abort := False;\n  if Assigned(Archive.OnNeedPassword) then begin\n    Archive.OnNeedPassword(Archive, APassPhrase);\n    if APassPhrase = '' then\n      Abort := True\n    else\n      Archive.Password := APassPhrase;\n  end;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure CheckPassword(Archive : TAbZipArchive; var Tries : Integer; var Abort : Boolean);\nbegin\n  { if current password empty }\n  if Archive.Password = '' then begin\n    { request password }\n    RequestPassword(Archive, Abort);\n    { increment tries }\n    Inc(Tries);\n  end;\n\n  { if current password still empty }\n  if Archive.Password = '' then begin\n    { abort }\n    raise EAbZipInvalidPassword.Create;\n  end;\nend;\n\n\n{ -------------------------------------------------------------------------- }\nprocedure DoInflate(Archive : TAbZipArchive; Item : TAbZipItem; InStream, OutStream : TStream);\nvar\n  Hlpr  : TAbDeflateHelper;\nbegin\n  Hlpr := TAbDeflateHelper.Create;\n  try\n    if Item.CompressionMethod = cmEnhancedDeflated then\n      Hlpr.Options := Hlpr.Options or dfc_UseDeflate64;\n\n    Hlpr.StreamSize := Item.CompressedSize;\n\n    Inflate(InStream, OutStream, Hlpr);\n  finally\n    Hlpr.Free;\n  end;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure DoLegacyUnzip(Archive : TAbZipArchive; Item : TAbZipItem; InStream, OutStream : TStream);\nvar\n  Helper     : TAbUnzipHelper;\nbegin\n  Helper := TAbUnzipHelper.Create(InStream, OutStream);\n  try {Helper}\n    Helper.DictionarySize       := Item.DictionarySize;\n    Helper.UnCompressedSize     := Item.UncompressedSize;\n    Helper.CompressionMethod    := Item.CompressionMethod;\n    Helper.ShannonFanoTreeCount := Item.ShannonFanoTreeCount;\n    Helper.Execute;\n  finally\n    Helper.Free;\n  end;\nend;\n{ -------------------------------------------------------------------------- }\n{$IFDEF UnzipBzip2Support}\nprocedure DoExtractBzip2(Archive : TAbZipArchive; Item : TAbZipItem; InStream, OutStream : TStream);\nvar\n  Bzip2Stream: TStream;\nbegin\n  Bzip2Stream := TBZDecompressionStream.Create(InStream);\n  try\n    OutStream.CopyFrom(Bzip2Stream, Item.UncompressedSize);\n  finally\n    Bzip2Stream.Free;\n  end;\nend;\n{$ENDIF}\n{ -------------------------------------------------------------------------- }\n{$IFDEF UnzipLzmaSupport}\nprocedure DoExtractLzma(Archive : TAbZipArchive; Item : TAbZipItem;\n  InStream, OutStream : TStream);\nvar\n  Header: packed record\n    MajorVer, MinorVer: Byte;\n    PropSize: Word;\n  end;\n  Properties: array of Byte;\nbegin\n  InStream.ReadBuffer(Header, SizeOf(Header));\n  SetLength(Properties, Header.PropSize);\n  InStream.ReadBuffer(Properties[0], Header.PropSize);\n  LzmaDecodeStream(PByte(Properties), Header.PropSize, InStream, OutStream,\n    Item.UncompressedSize);\nend;\n{$ENDIF}\n{ -------------------------------------------------------------------------- }\nfunction ExtractPrep(ZipArchive: TAbZipArchive; Item: TAbZipItem): TStream;\nvar\n  LFH         : TAbZipLocalFileHeader;\n  Abort       : Boolean;\n  Tries       : Integer;\n  CheckValue  : LongInt;\n  DecryptStream: TAbDfDecryptStream;\nbegin\n  { validate }\n  if (Lo(Item.VersionNeededToExtract) > Ab_ZipVersion) then\n    raise EAbZipVersion.Create;\n\n  { seek to compressed file }\n  if ZipArchive.FStream is TAbSpanReadStream then\n    TAbSpanReadStream(ZipArchive.FStream).SeekImage(Item.DiskNumberStart,\n                                                    Item.RelativeOffset)\n  else\n    ZipArchive.FStream.Position := Item.RelativeOffset;\n\n  { get local header info for Item}\n  LFH := TAbZipLocalFileHeader.Create;\n  try\n    { select appropriate CRC value based on General Purpose Bit Flag }\n    { also get whether the file is stored, while we've got the local file header }\n    LFH.LoadFromStream(ZipArchive.FStream);\n    if (LFH.GeneralPurposeBitFlag and AbHasDataDescriptorFlag = AbHasDataDescriptorFlag) then\n    { if bit 3 is set, then the data descriptor record is appended\n      to the compressed data }\n      CheckValue := LFH.LastModFileTime shl $10\n    else\n      CheckValue := Item.CRC32;\n  finally\n    LFH.Free;\n  end;\n\n  Result := TAbUnzipSubsetStream.Create(ZipArchive.FStream,\n    Item.CompressedSize);\n\n  { get decrypting stream }\n  if Item.IsEncrypted then begin\n    try\n      { need to decrypt }\n      Tries := 0;\n      Abort := False;\n      CheckPassword(ZipArchive, Tries, Abort);\n      while True do begin\n        if Abort then\n          raise EAbUserAbort.Create;\n        { check for valid password }\n        DecryptStream := TAbDfDecryptStream.Create(Result,\n          CheckValue, ZipArchive.Password);\n        if DecryptStream.IsValid then begin\n          DecryptStream.OwnsStream := True;\n          Result := DecryptStream;\n          Break;\n        end;\n        FreeAndNil(DecryptStream);\n        { prompt again }\n        Inc(Tries);\n        if (Tries > ZipArchive.PasswordRetries) then\n          raise EAbZipInvalidPassword.Create;\n        RequestPassword(ZipArchive, Abort);\n      end;\n    except\n      Result.Free;\n      raise;\n    end;\n  end;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure DoExtract(aZipArchive: TAbZipArchive; aItem: TAbZipItem;\n  aInStream, aOutStream: TStream);\nvar\n  OutStream : TAbUnzipOutputStream;\nbegin\n  if aItem.UncompressedSize = 0 then\n    Exit;\n\n  OutStream := TAbUnzipOutputStream.Create(aOutStream);\n  try\n    OutStream.UncompressedSize := aItem.UncompressedSize;\n    OutStream.OnProgress := aZipArchive.OnProgress;\n\n    { determine storage type }\n    case aItem.CompressionMethod of\n      cmStored: begin\n        { unstore aItem }\n        OutStream.CopyFrom(aInStream, aItem.UncompressedSize);\n      end;\n      cmDeflated, cmEnhancedDeflated: begin\n        { inflate aItem }\n        DoInflate(aZipArchive, aItem, aInStream, OutStream);\n      end;\n      {$IFDEF UnzipBzip2Support}\n      cmBzip2: begin\n        DoExtractBzip2(aZipArchive, aItem, aInStream, OutStream);\n      end;\n      {$ENDIF}\n      {$IFDEF UnzipLzmaSupport}\n      cmLZMA: begin\n        DoExtractLzma(aZipArchive, aItem, aInStream, OutStream);\n      end;\n      {$ENDIF}\n      {$IFDEF UnzipPPMdSupport}\n      cmPPMd: begin\n        DecompressPPMd(aInStream, OutStream);\n      end;\n      {$ENDIF}\n      {$IFDEF UnzipWavPackSupport}\n      cmWavPack: begin\n        DecompressWavPack(aInStream, OutStream);\n      end;\n      {$ENDIF}\n      cmShrunk..cmImploded: begin\n        DoLegacyUnzip(aZipArchive, aItem, aInStream, OutStream);\n      end;\n      else\n        raise EAbZipInvalidMethod.Create;\n    end;\n\n    { check CRC }\n    if OutStream.CRC32 <> aItem.CRC32 then\n      if Assigned(aZipArchive.OnProcessItemFailure) then\n        aZipArchive.OnProcessItemFailure(aZipArchive, aItem, ptExtract,\n          ecAbbrevia, AbZipBadCRC)\n      else\n        raise EAbZipBadCRC.Create;\n  finally\n    OutStream.Free;\n  end;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure AbUnzipToStream( Sender : TObject; Item : TAbZipItem; OutStream : TStream);\nvar\n  ZipArchive : TAbZipArchive;\n  InStream : TStream;\nbegin\n  ZipArchive := Sender as TAbZipArchive;\n  if not Assigned(OutStream) then\n    raise EAbBadStream.Create;\n\n  InStream := ExtractPrep(ZipArchive, Item);\n  try\n    DoExtract(ZipArchive, Item, InStream, OutStream);\n  finally\n    InStream.Free\n  end;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure AbUnzip(Sender : TObject; Item : TAbZipItem; const UseName : string);\n  {create the output filestream and pass it to DoExtract}\nvar\n  InStream, OutStream : TStream;\n  ZipArchive : TAbZipArchive;\nbegin\n  ZipArchive := TAbZipArchive(Sender);\n\n  if Item.IsDirectory then\n    AbCreateDirectory(UseName)\n  else begin\n    InStream := ExtractPrep(ZipArchive, Item);\n    try\n      OutStream := TFileStream.Create(UseName, fmCreate or fmShareDenyWrite);\n      try\n        try    {OutStream}\n          DoExtract(ZipArchive, Item, InStream, OutStream);\n        finally {OutStream}\n          OutStream.Free;\n        end;   {OutStream}\n      except\n        if ExceptObject is EAbUserAbort then\n          ZipArchive.FStatus := asInvalid;\n        DeleteFile(UseName);\n        raise;\n      end;\n    finally\n      InStream.Free\n    end;\n  end;\n\n  AbSetFileTime(UseName, Item.LastModTimeAsDateTime);\n  AbSetFileAttr(UseName, Item.NativeFileAttributes);\nend;\n{ -------------------------------------------------------------------------- }\nprocedure AbTestZipItem(Sender : TObject; Item : TAbZipItem);\n  {extract item to bit bucket and verify its local file header}\nvar\n  BitBucket  : TAbBitBucketStream;\n  FieldSize  : Word;\n  LFH        : TAbZipLocalFileHeader;\n  Zip64Field : PZip64LocalHeaderRec;\n  ZipArchive : TAbZipArchive;\nbegin\n  ZipArchive := TAbZipArchive(Sender);\n\n  if (Lo(Item.VersionNeededToExtract) > Ab_ZipVersion) then\n    raise EAbZipVersion.Create;\n\n  { seek to compressed file }\n  if ZipArchive.FStream is TAbSpanReadStream then\n    TAbSpanReadStream(ZipArchive.FStream).SeekImage(Item.DiskNumberStart,\n                                                    Item.RelativeOffset)\n  else\n    ZipArchive.FStream.Position := Item.RelativeOffset;\n\n  BitBucket := nil;\n  LFH := nil;\n  try\n    BitBucket := TAbBitBucketStream.Create(0);\n    LFH := TAbZipLocalFileHeader.Create;\n      {get the item's local file header}\n    ZipArchive.FStream.Seek(Item.RelativeOffset, soBeginning);\n    LFH.LoadFromStream(ZipArchive.FStream);\n    ZipArchive.FStream.Seek(Item.RelativeOffset, soBeginning);\n\n      {currently a single exception is raised for any LFH error}\n    if (LFH.VersionNeededToExtract <> Item.VersionNeededToExtract) then\n      raise EAbZipInvalidLFH.Create;\n    if (LFH.GeneralPurposeBitFlag <> Item.GeneralPurposeBitFlag) then\n      raise EAbZipInvalidLFH.Create;\n    if (LFH.LastModFileTime <> Item.LastModFileTime) then\n      raise EAbZipInvalidLFH.Create;\n    if (LFH.LastModFileDate <> Item.LastModFileDate) then\n      raise EAbZipInvalidLFH.Create;\n    if (LFH.CRC32 <> Item.CRC32) then\n      raise EAbZipInvalidLFH.Create;\n    if LFH.ExtraField.Get(Ab_Zip64SubfieldID, Pointer(Zip64Field), FieldSize) then begin\n      if (Zip64Field.CompressedSize <> Item.CompressedSize) then\n        raise EAbZipInvalidLFH.Create;\n      if (Zip64Field.UncompressedSize <> Item.UncompressedSize) then\n        raise EAbZipInvalidLFH.Create;\n    end\n    else begin\n      if (LFH.CompressedSize <> Item.CompressedSize) then\n        raise EAbZipInvalidLFH.Create;\n      if (LFH.UncompressedSize <> Item.UncompressedSize) then\n        raise EAbZipInvalidLFH.Create;\n    end;\n    if (LFH.FileName <> Item.RawFileName) then\n      raise EAbZipInvalidLFH.Create;\n\n      {any CRC errors will raise exception during extraction}\n    AbUnZipToStream(Sender, Item, BitBucket);\n  finally\n    BitBucket.Free;\n    LFH.Free;\n  end;\n\nend;\n{ -------------------------------------------------------------------------- }\nprocedure InflateStream( CompressedStream, UnCompressedStream : TStream );\n  {-Inflates everything in CompressedStream to UncompressedStream\n    no encryption is tried, no check on CRC is done, uses the whole\n    compressedstream - no Progress events - no Frills!}\nbegin\n  Inflate(CompressedStream, UncompressedStream, nil);\nend;\n\nend.\n\n"
  },
  {
    "path": "lib/abbrevia/source/AbUnzper.pas",
    "content": "(* ***** BEGIN LICENSE BLOCK *****\n * Version: MPL 1.1\n *\n * The contents of this file are subject to the Mozilla Public License Version\n * 1.1 (the \"License\"); you may not use this file except in compliance with\n * the License. You may obtain a copy of the License at\n * http://www.mozilla.org/MPL/\n *\n * Software distributed under the License is distributed on an \"AS IS\" basis,\n * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License\n * for the specific language governing rights and limitations under the\n * License.\n *\n * The Original Code is TurboPower Abbrevia\n *\n * The Initial Developer of the Original Code is\n * TurboPower Software\n *\n * Portions created by the Initial Developer are Copyright (C) 1997-2002\n * the Initial Developer. All Rights Reserved.\n *\n * Contributor(s):\n *\n * ***** END LICENSE BLOCK ***** *)\n\n{*********************************************************}\n{* ABBREVIA: ABUnzper.pas                                *}\n{*********************************************************}\n{* ABBREVIA: Non-visual Component with UnZip support     *}\n{*********************************************************}\n\nunit AbUnzper;\n\n{$I AbDefine.inc}\n\ninterface\n\nuses\n  Classes,\n  AbZBrows, AbArcTyp, AbZipTyp;\n\ntype\n  TAbCustomUnZipper = class(TAbCustomZipBrowser)\n  protected {private}\n    FExtractOptions     : TAbExtractOptions;\n    FOnConfirmOverwrite : TAbConfirmOverwriteEvent;\n    FOnNeedPassword     : TAbNeedPasswordEvent;\n    FPasswordRetries    : Byte;\n\n  protected {methods}\n    procedure DoConfirmOverwrite(var Name : string;\n                                 var Confirm : Boolean);\n      virtual;\n    procedure DoNeedPassword(Sender : TObject;\n                             var NewPassword : AnsiString);\n      virtual;\n    procedure InitArchive; override;\n    procedure SetExtractOptions(Value : TAbExtractOptions);\n    procedure SetPasswordRetries(Value : Byte);\n    procedure UnzipProc(Sender : TObject; Item : TAbArchiveItem;\n                        const NewName : string );\n    procedure UnzipToStreamProc(Sender : TObject; Item : TAbArchiveItem;\n                                OutStream : TStream);\n    procedure TestItemProc(Sender : TObject; Item : TAbArchiveItem);\n\n    procedure SetFileName(const aFileName : string);\n      override;\n\n  protected {properties}\n    property ExtractOptions : TAbExtractOptions\n      read  FExtractOptions\n      write SetExtractOptions\n      default AbDefExtractOptions;\n    property OnConfirmOverwrite : TAbConfirmOverwriteEvent\n      read  FOnConfirmOverwrite\n      write FOnConfirmOverwrite;\n    property OnNeedPassword : TAbNeedPasswordEvent\n      read  FOnNeedPassword\n      write FOnNeedPassword;\n    property PasswordRetries : Byte\n      read  FPasswordRetries\n      write SetPasswordRetries\n      default AbDefPasswordRetries;\n\n  public {methods}\n    constructor Create( AOwner : TComponent );\n      override;\n    destructor Destroy;\n      override;\n    procedure ExtractAt(Index : Integer; const NewName : string);\n    procedure ExtractFiles(const FileMask : string);\n    procedure ExtractFilesEx(const FileMask, ExclusionMask : string);\n    procedure ExtractToStream(const aFileName : string; ToStream : TStream);\n    procedure ExtractTaggedItems;\n    procedure TestTaggedItems;\n  end;\n\n  TAbUnZipper = class(TAbCustomUnZipper)\n  published\n    property ArchiveProgressMeter;\n    property ItemProgressMeter;\n    property BaseDirectory;\n    property ExtractOptions;\n    property LogFile;\n    property Logging;\n    property OnArchiveProgress;\n    property OnArchiveItemProgress;\n    property OnChange;\n    property OnConfirmOverwrite;\n    property OnConfirmProcessItem;\n    property OnLoad;\n    property OnNeedPassword;\n    property OnRequestImage;\n    property OnProcessItemFailure;\n    property OnRequestLastDisk;\n    property OnRequestNthDisk;\n    property Password;\n    property PasswordRetries;\n    property TempDirectory;\n    property Version;\n    property FileName; {must be after OnLoad}                          \n  end;\n\n\nimplementation\n\nuses\n  SysUtils,\n  AbUtils,\n  AbExcept,\n  AbUnzPrc;\n\n{ -------------------------------------------------------------------------- }\nconstructor TAbCustomUnZipper.Create( AOwner : TComponent );\nbegin\n  inherited Create(AOwner);\n  ExtractOptions := AbDefExtractOptions;\n  PasswordRetries := AbDefPasswordRetries;\nend;\n{ -------------------------------------------------------------------------- }\ndestructor TAbCustomUnZipper.Destroy;\nbegin\n  inherited Destroy;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbCustomUnZipper.DoConfirmOverwrite(var Name : string;\n                                               var Confirm : Boolean);\nbegin\n  Confirm := True;\n  if Assigned(FOnConfirmOverwrite) then\n    FOnConfirmOverwrite( Name, Confirm );\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbCustomUnZipper.DoNeedPassword(Sender : TObject;\n                                           var NewPassword : AnsiString);\nbegin\n  if Assigned(FOnNeedPassword) then begin\n    FOnNeedPassword(Self, NewPassword);\n    Password := NewPassword;\n  end;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbCustomUnZipper.ExtractAt(Index : Integer; const NewName : string);\n  {extract a file from the archive that match the index}\nbegin\n  if (FArchive <> nil) then\n    FArchive.ExtractAt(Index, NewName)\n  else\n    raise EAbNoArchive.Create;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbCustomUnZipper.ExtractFiles(const FileMask : string);\n  {extract all files from the archive that match the mask}\nbegin\n  if (FArchive <> nil) then\n    FArchive.ExtractFiles( FileMask )\n  else\n    raise EAbNoArchive.Create;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbCustomUnZipper.ExtractFilesEx(const FileMask, ExclusionMask : string);\n  {extract files matching FileMask except those matching ExclusionMask}\nbegin\n  if (FArchive <> nil) then\n    FArchive.ExtractFilesEx(FileMask, ExclusionMask)\n  else\n    raise EAbNoArchive.Create;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbCustomUnZipper.ExtractToStream(const aFileName : string;\n                                            ToStream : TStream);\nbegin\n  if (FArchive <> nil) then\n    FArchive.ExtractToStream(aFileName, ToStream)\n  else\n    raise EAbNoArchive.Create;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbCustomUnZipper.ExtractTaggedItems;\n  {extract all tagged items from the archive}\nbegin\n  if (FArchive <> nil) then\n    FArchive.ExtractTaggedItems\n  else\n    raise EAbNoArchive.Create;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbCustomUnZipper.InitArchive;\nbegin\n  inherited InitArchive;\n  if FArchive <> nil then begin\n\tFArchive.ExtractOptions                       := FExtractOptions;\n\tFArchive.OnConfirmOverwrite                   := DoConfirmOverwrite;\n  end;\n  if FArchive is TAbZipArchive then begin\n\tTAbZipArchive(FArchive).PasswordRetries       := FPasswordRetries;\n\tTAbZipArchive(FArchive).OnNeedPassword        := DoNeedPassword;\n\tTAbZipArchive(FArchive).TestHelper            := TestItemProc;\n\tTAbZipArchive(FArchive).ExtractHelper         := UnzipProc;\n\tTAbZipArchive(FArchive).ExtractToStreamHelper := UnzipToStreamProc;\n  end;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbCustomUnZipper.SetExtractOptions(Value : TAbExtractOptions);\nbegin\n  FExtractOptions := Value;\n  if (FArchive <> nil) then\n\tFArchive.ExtractOptions := Value;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbCustomUnZipper.SetPasswordRetries(Value : Byte);\nbegin\n  FPasswordRetries := Value;\n  if FArchive is TAbZipArchive then\n\tTAbZipArchive(FArchive).PasswordRetries := Value;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbCustomUnZipper.TestTaggedItems;\n  {Test specified items}\nbegin\n  if (FArchive <> nil) then\n\tFArchive.TestTaggedItems\n  else\n    raise EAbNoArchive.Create;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbCustomUnZipper.UnzipProc(Sender : TObject;\n                                      Item : TAbArchiveItem;\n                                      const NewName : string);\nbegin\n  AbUnzip( TAbZipArchive(Sender), TAbZipItem(Item), NewName);\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbCustomUnZipper.UnzipToStreamProc(Sender : TObject;\n                                              Item : TAbArchiveItem;\n                                              OutStream : TStream);\nbegin\n  AbUnzipToStream(TAbZipArchive(Sender), TAbZipItem(Item), OutStream);\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbCustomUnZipper.TestItemProc(Sender : TObject;\n                                         Item : TAbArchiveItem);\nbegin\n  AbTestZipItem(TAbZipArchive(Sender), TAbZipItem(Item));\nend;\n{ -------------------------------------------------------------------------- }\n\nprocedure TAbCustomUnZipper.SetFileName(const aFileName: string);\nbegin\n  if aFileName <> '' then\n  begin\n    if not FileExists(aFileName) then\n      raise EAbFileNotFound.Create;\n    if AbFileGetSize(aFileName) <= 0 then\n      raise EAbBadStream.Create;\n  end;\n\n  inherited SetFileName(aFileName);\nend;\n\nend.\n\n"
  },
  {
    "path": "lib/abbrevia/source/AbUtils.pas",
    "content": "(* ***** BEGIN LICENSE BLOCK *****\n * Version: MPL 1.1\n *\n * The contents of this file are subject to the Mozilla Public License Version\n * 1.1 (the \"License\"); you may not use this file except in compliance with\n * the License. You may obtain a copy of the License at\n * http://www.mozilla.org/MPL/\n *\n * Software distributed under the License is distributed on an \"AS IS\" basis,\n * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License\n * for the specific language governing rights and limitations under the\n * License.\n *\n * The Original Code is TurboPower Abbrevia\n *\n * The Initial Developer of the Original Code is\n * TurboPower Software\n *\n * Portions created by the Initial Developer are Copyright (C) 1997-2002\n * the Initial Developer. All Rights Reserved.\n *\n * Contributor(s):\n *\n * ***** END LICENSE BLOCK ***** *)\n\n{*********************************************************}\n{* ABBREVIA: AbUtils.pas                                 *}\n{*********************************************************}\n{* ABBREVIA: Utility classes and routines                *}\n{*********************************************************}\n\nunit AbUtils;\n\n{$I AbDefine.inc}\n\ninterface\n\nuses\n{$IFDEF MSWINDOWS}\n  Windows,\n{$ENDIF}\n{$IFDEF LibcAPI}\n  Libc,\n{$ENDIF}\n{$IFDEF FPCUnixAPI}\n  baseunix,\n  {$IFDEF Linux}\n  initc,\n  {$ENDIF}\n  unix,\n{$ENDIF}\n{$IFDEF PosixAPI}\n  Posix.SysStatvfs,\n  Posix.SysStat,\n  Posix.Utime,\n  Posix.Base,\n  Posix.Unistd,\n  Posix.Fcntl,\n  Posix.SysTypes,\n{$ENDIF}\n{$IFDEF UNIX}\n  DateUtils,\n{$ENDIF}\n{$IFDEF HasAnsiStrings}\n  System.AnsiStrings,\n{$ENDIF}\n  SysUtils,\n  Classes,\n  AbCharset;\n\n\ntype\n  {describe the pending action for an archive item}\n  TAbArchiveAction =\n    (aaFailed, aaNone, aaAdd, aaDelete, aaFreshen, aaMove, aaReplace,\n     aaStreamAdd);\n  TAbProcessType =\n    (ptAdd, ptDelete, ptExtract, ptFreshen, ptMove, ptReplace, ptFoundUnhandled);\n  TAbLogType =\n    (ltAdd, ltDelete, ltExtract, ltFreshen, ltMove, ltReplace, ltStart, ltFoundUnhandled);\n  TAbErrorClass =\n    (ecAbbrevia, ecInOutError, ecFilerError, ecFileCreateError,\n     ecFileOpenError, ecCabError, ecOther);\n\nconst\n  AbPathDelim     = PathDelim; { Delphi/Linux constant }\n  AbPathSep       = PathSep;   { Delphi/Linux constant }\n  AbDosPathDelim  = '\\';\n  AbUnixPathDelim = '/';\n  AbDosPathSep    = ';';\n  AbUnixPathSep   = ':';\n  AbDosAnyFile    = '*.*';\n  AbUnixAnyFile   = '*';\n  AbAnyFile       = {$IFDEF UNIX} AbUnixAnyFile; {$ELSE} AbDosAnyFile; {$ENDIF}\n  AbThisDir       = '.';\n  AbParentDir     = '..';\n\ntype\n  TAbArchiveType = (atUnknown, atZip, atSpannedZip, atSelfExtZip,\n                    atTar, atGzip, atGzippedTar, atCab, atBzip2, atBzippedTar);\n\n\n{$IF NOT DECLARED(DWORD)}\ntype\n  DWORD = LongWord;\n{$IFEND}\n\n{$IF NOT DECLARED(PtrInt)}\ntype\n  // Delphi 7-2007 declared NativeInt incorrectly\n  {$IFDEF CPU386}\n  PtrInt = LongInt;\n  PtrUInt = LongWord;\n  {$ELSE}\n  PtrInt = NativeInt;\n  PtrUInt = NativeUInt;\n  {$ENDIF}\n{$IFEND}\n\n{ System-encoded SBCS string (formerly AnsiString) }\ntype\n  AbSysString = {$IFDEF Posix}UTF8String{$ELSE}AnsiString{$ENDIF};\n\nconst\n  AbCrc32Table : array[0..255] of DWord = (\n  $00000000, $77073096, $ee0e612c, $990951ba,\n  $076dc419, $706af48f, $e963a535, $9e6495a3,\n  $0edb8832, $79dcb8a4, $e0d5e91e, $97d2d988,\n  $09b64c2b, $7eb17cbd, $e7b82d07, $90bf1d91,\n  $1db71064, $6ab020f2, $f3b97148, $84be41de,\n  $1adad47d, $6ddde4eb, $f4d4b551, $83d385c7,\n  $136c9856, $646ba8c0, $fd62f97a, $8a65c9ec,\n  $14015c4f, $63066cd9, $fa0f3d63, $8d080df5,\n  $3b6e20c8, $4c69105e, $d56041e4, $a2677172,\n  $3c03e4d1, $4b04d447, $d20d85fd, $a50ab56b,\n  $35b5a8fa, $42b2986c, $dbbbc9d6, $acbcf940,\n  $32d86ce3, $45df5c75, $dcd60dcf, $abd13d59,\n  $26d930ac, $51de003a, $c8d75180, $bfd06116,\n  $21b4f4b5, $56b3c423, $cfba9599, $b8bda50f,\n  $2802b89e, $5f058808, $c60cd9b2, $b10be924,\n  $2f6f7c87, $58684c11, $c1611dab, $b6662d3d,\n  $76dc4190, $01db7106, $98d220bc, $efd5102a,\n  $71b18589, $06b6b51f, $9fbfe4a5, $e8b8d433,\n  $7807c9a2, $0f00f934, $9609a88e, $e10e9818,\n  $7f6a0dbb, $086d3d2d, $91646c97, $e6635c01,\n  $6b6b51f4, $1c6c6162, $856530d8, $f262004e,\n  $6c0695ed, $1b01a57b, $8208f4c1, $f50fc457,\n  $65b0d9c6, $12b7e950, $8bbeb8ea, $fcb9887c,\n  $62dd1ddf, $15da2d49, $8cd37cf3, $fbd44c65,\n  $4db26158, $3ab551ce, $a3bc0074, $d4bb30e2,\n  $4adfa541, $3dd895d7, $a4d1c46d, $d3d6f4fb,\n  $4369e96a, $346ed9fc, $ad678846, $da60b8d0,\n  $44042d73, $33031de5, $aa0a4c5f, $dd0d7cc9,\n  $5005713c, $270241aa, $be0b1010, $c90c2086,\n  $5768b525, $206f85b3, $b966d409, $ce61e49f,\n  $5edef90e, $29d9c998, $b0d09822, $c7d7a8b4,\n  $59b33d17, $2eb40d81, $b7bd5c3b, $c0ba6cad,\n  $edb88320, $9abfb3b6, $03b6e20c, $74b1d29a,\n  $ead54739, $9dd277af, $04db2615, $73dc1683,\n  $e3630b12, $94643b84, $0d6d6a3e, $7a6a5aa8,\n  $e40ecf0b, $9309ff9d, $0a00ae27, $7d079eb1,\n  $f00f9344, $8708a3d2, $1e01f268, $6906c2fe,\n  $f762575d, $806567cb, $196c3671, $6e6b06e7,\n  $fed41b76, $89d32be0, $10da7a5a, $67dd4acc,\n  $f9b9df6f, $8ebeeff9, $17b7be43, $60b08ed5,\n  $d6d6a3e8, $a1d1937e, $38d8c2c4, $4fdff252,\n  $d1bb67f1, $a6bc5767, $3fb506dd, $48b2364b,\n  $d80d2bda, $af0a1b4c, $36034af6, $41047a60,\n  $df60efc3, $a867df55, $316e8eef, $4669be79,\n  $cb61b38c, $bc66831a, $256fd2a0, $5268e236,\n  $cc0c7795, $bb0b4703, $220216b9, $5505262f,\n  $c5ba3bbe, $b2bd0b28, $2bb45a92, $5cb36a04,\n  $c2d7ffa7, $b5d0cf31, $2cd99e8b, $5bdeae1d,\n  $9b64c2b0, $ec63f226, $756aa39c, $026d930a,\n  $9c0906a9, $eb0e363f, $72076785, $05005713,\n  $95bf4a82, $e2b87a14, $7bb12bae, $0cb61b38,\n  $92d28e9b, $e5d5be0d, $7cdcefb7, $0bdbdf21,\n  $86d3d2d4, $f1d4e242, $68ddb3f8, $1fda836e,\n  $81be16cd, $f6b9265b, $6fb077e1, $18b74777,\n  $88085ae6, $ff0f6a70, $66063bca, $11010b5c,\n  $8f659eff, $f862ae69, $616bffd3, $166ccf45,\n  $a00ae278, $d70dd2ee, $4e048354, $3903b3c2,\n  $a7672661, $d06016f7, $4969474d, $3e6e77db,\n  $aed16a4a, $d9d65adc, $40df0b66, $37d83bf0,\n  $a9bcae53, $debb9ec5, $47b2cf7f, $30b5ffe9,\n  $bdbdf21c, $cabac28a, $53b39330, $24b4a3a6,\n  $bad03605, $cdd70693, $54de5729, $23d967bf,\n  $b3667a2e, $c4614ab8, $5d681b02, $2a6f2b94,\n  $b40bbe37, $c30c8ea1, $5a05df1b, $2d02ef8d\n  );\n\n\ntype\n  TAbPathType = ( ptNone, ptRelative, ptAbsolute );\n\n  {===Helper functions===}\n  function AbCopyFile(const Source, Destination: string; FailIfExists: Boolean): Boolean;\n\n  procedure AbCreateDirectory( const Path : string );\n    {creates the requested directory tree.  CreateDir is insufficient,\n     because if you have a path x:\\dir, and request x:\\dir\\sub1\\sub2,\n     (/dir and /dir/sub1/sub2 on Unix) it fails.}\n\n  function AbCreateTempFile(const Dir : string) : string;\n\n  function AbGetTempDirectory : string;\n    {-Return the system temp directory}\n\n  function AbGetTempFile(const Dir : string; CreateIt : Boolean) : string;\n\n  function AbDrive(const ArchiveName : string) : Char;\n\n  function AbDriveIsRemovable(const ArchiveName : string) : Boolean;\n\n  function AbFileMatch(FileName : string; FileMask : string ) : Boolean;\n    {see if FileName matches FileMask}\n\n  procedure AbFindFiles(const FileMask : string; SearchAttr : Integer;\n                         FileList : TStrings; Recurse : Boolean );\n\n  procedure AbFindFilesEx( const FileMask : string; SearchAttr : Integer;\n                         FileList : TStrings; Recurse : Boolean );\n\n  function AbAddBackSlash(const DirName : string) : string;\n\n  function AbFindNthSlash( const Path : string; n : Integer ) : Integer;\n    {return the position of the character just before the nth backslash}\n\n  function AbGetDriveFreeSpace(const ArchiveName : string) : Int64;\n    {return the available space on the specified drive }\n\n  function AbGetPathType( const Value : string ) : TAbPathType;\n    {returns path type - none, relative or absolute}\n\n  {$IFDEF MSWINDOWS}\n  function AbGetShortFileSpec(const LongFileSpec : string ) : string;\n  {$ENDIF}\n\n  procedure AbIncFilename( var Filename : string; Value : Word );\n\n  procedure AbParseFileName( FileSpec : string;\n                             out Drive : string;\n                             out Path : string;\n                             out FileName : string );\n\n  procedure AbParsePath( Path : string; SubPaths : TStrings );\n    {- break abart path into subpaths --- Path : abbrevia/examples ->\n                                          SubPaths[0] = abbrevia\n                                          SubPaths[1] = examples}\n\n  function AbPatternMatch(const Source : string; iSrc : Integer;\n                          const Pattern : string; iPat : Integer ) : Boolean;\n    { recursive routine to see if the source string matches\n      the pattern.  Both ? and * wildcard characters are allowed.}\n\n  function AbPercentage(V1, V2 : Int64) : Byte;\n    {-Returns the ratio of V1 to V2 * 100}\n\n  procedure AbStripDots( var FName : string );\n    {-strips relative path information}\n\n  procedure AbStripDrive( var FName : string );\n    {-strips the drive off a filename}\n\n  procedure AbFixName( var FName : string );\n    {-changes backslashes to forward slashes}\n\n  procedure AbUnfixName( var FName : string );\n    {-changes forward slashes to backslashes}\n\n  procedure AbUpdateCRC( var CRC : LongInt; const Buffer; Len : Integer );\n\n  function AbUpdateCRC32(CurByte : Byte; CurCrc : LongInt) : LongInt;\n    {-Returns an updated crc32}\n\n  function AbCRC32Of( const aValue : RawByteString ) : LongInt;\n\n\n  function AbWriteVolumeLabel(const VolName : string;\n                                  Drive : Char) : Cardinal;\nconst\n  AB_SPAN_VOL_LABEL = 'PKBACK# %3.3d';\n\n  function AbGetVolumeLabel(Drive : Char) : string;\n  procedure AbSetSpanVolumeLabel(Drive: Char; VolNo : Integer);\n  function AbTestSpanVolumeLabel(Drive: Char; VolNo : Integer): Boolean;\n\n  procedure AbSetFileAttr(const aFileName : string; aAttr: Integer);\n    {-Sets platform-native file attributes (DOS attr or Unix mode)}\n  function AbFileGetSize(const aFileName : string) : Int64;\n\ntype\n  TAbAttrExRec = record\n    Time: TDateTime;\n    Size: Int64;\n    Attr: Integer;\n    Mode: {$IFDEF UNIX}mode_t{$ELSE}Cardinal{$ENDIF};\n  end;\n\n  function AbFileGetAttrEx(const aFileName: string; out aAttr: TAbAttrExRec) : Boolean;\n\n  function AbSwapLongEndianness(Value : LongInt): LongInt;\n\n\n{ date and time stuff }\nconst\n  Date1900 {: LongInt} = $0001AC05;  {Julian day count for 01/01/1900 -- TDateTime Start Date}\n  Date1970 {: LongInt} = $00020FE4;  {Julian day count for 01/01/1970 -- Unix Start Date}\n  Unix0Date: TDateTime = 25569;      {Date1970 - Date1900}\n\n  SecondsInDay    = 86400;  {Number of seconds in a day}\n  SecondsInHour   =  3600;  {Number of seconds in an hour}\n  SecondsInMinute =    60;  {Number of seconds in a minute}\n  HoursInDay      =    24;  {Number of hours in a day}\n  MinutesInHour   =    60;  {Number of minutes in an hour}\n  MinutesInDay    =  1440;  {Number of minutes in a day}\n\n\n  function AbUnixTimeToLocalDateTime(UnixTime : LongInt) : TDateTime;\n  function AbLocalDateTimeToUnixTime(DateTime : TDateTime) : LongInt;\n\n  function AbDosFileDateToDateTime(FileDate, FileTime : Word) : TDateTime;\n  function AbDateTimeToDosFileDate(Value : TDateTime) : LongInt;\n\n  function AbGetFileTime(const aFileName: string): TDateTime;\n  function AbSetFileTime(const aFileName: string; aValue: TDateTime): Boolean;\n\n{ file attributes }\n  function AbDOS2UnixFileAttributes(Attr: LongInt): LongInt;\n  function AbUnix2DosFileAttributes(Attr: LongInt): LongInt;\n\n{ AnisStrings }\n  function AbLeftStr(const AText: AnsiString; const ACount: Integer): AnsiString; {$IFDEF HasInline}inline;{$ENDIF}\n  function AbStrLen(const Str: PAnsiChar): Cardinal; {$IFDEF HasInline}inline;{$ENDIF}\n  function AbStrPCopy(Dest: PAnsiChar; const Source: AnsiString): PAnsiChar; {$IFDEF HasInline}inline;{$ENDIF}\n  function AbStrPLCopy(Dest: PAnsiChar; const Source: AnsiString; MaxLen: Cardinal): PAnsiChar; {$IFDEF HasInline}inline;{$ENDIF}\n\n{ UNIX File Types and Permissions }\nconst\n  AB_FMODE_FILE          = $0000;\n  AB_FMODE_FIFO          = $1000;\n  AB_FMODE_CHARSPECFILE  = $2000;\n  AB_FMODE_DIR           = $4000;\n  AB_FMODE_BLOCKSPECFILE = $6000;\n  AB_FMODE_FILE2         = $8000;\n  AB_FMODE_FILELINK      = $A000;\n  AB_FMODE_SOCKET        = $C000;\n\n\n  AB_FPERMISSION_OWNERREAD    = $0100; { read by owner }\n  AB_FPERMISSION_OWNERWRITE   = $0080; { write by owner }\n  AB_FPERMISSION_OWNEREXECUTE = $0040; { execute/search by owner }\n  AB_FPERMISSION_GROUPREAD    = $0020; { read by group }\n  AB_FPERMISSION_GROUPWRITE   = $0010; { write by group }\n  AB_FPERMISSION_GROUPEXECUTE = $0008; { execute/search by group }\n  AB_FPERMISSION_OTHERREAD    = $0004; { read by other }\n  AB_FPERMISSION_OTHERWRITE   = $0002; { write by other }\n  AB_FPERMISSION_OTHEREXECUTE = $0001; { execute/search by other }\n\n  AB_FPERMISSION_GENERIC      =\n    AB_FPERMISSION_OWNERREAD or\n    AB_FPERMISSION_OWNERWRITE or\n    AB_FPERMISSION_GROUPREAD or\n    AB_FPERMISSION_OTHERREAD;\n\n{ Unicode backwards compatibility functions }\n{$IFNDEF UNICODE}\nfunction CharInSet(C: AnsiChar; CharSet: TSysCharSet): Boolean;\n{$ENDIF}\n\nimplementation\n\nuses\n  StrUtils,\n  AbConst,\n  AbExcept;\n\n{$IF DEFINED(FPCUnixAPI)}\nfunction mktemp(template: PAnsiChar): PAnsiChar; cdecl;\n  external clib name 'mktemp';\n{$ELSEIF DEFINED(PosixAPI)}\nfunction mktemp(template: PAnsiChar): PAnsiChar; cdecl;\n  external libc name _PU + 'mktemp';\n{$IFEND}\n\n{$IF DEFINED(FPCUnixAPI) AND DEFINED(Linux)}\n// FreePascal libc definitions\ntype\n  nl_item = cint;\n\nconst\n  __LC_CTYPE = 0;\n  _NL_CTYPE_CLASS = (__LC_CTYPE shl 16);\n  _NL_CTYPE_CODESET_NAME = (_NL_CTYPE_CLASS)+14;\n\nfunction nl_langinfo(__item: nl_item): PAnsiChar; cdecl;\n  external clib name 'nl_langinfo';\n{$IFEND}\n\n{===platform independent routines for platform dependent stuff=======}\nfunction ExtractShortName(const SR : TSearchRec) : string;\nbegin\n  {$IFDEF MSWINDOWS}\n  {$WARN SYMBOL_PLATFORM OFF}\n  if SR.FindData.cAlternateFileName[0] <> #0 then\n    Result := SR.FindData.cAlternateFileName\n  else\n    Result := SR.FindData.cFileName;\n  {$WARN SYMBOL_PLATFORM ON}\n  {$ENDIF}\n  {$IFDEF UNIX}\n  Result := SR.Name;\n  {$ENDIF}\nend;\n{====================================================================}\n\n\n{ ========================================================================== }\nfunction AbCopyFile(const Source, Destination: string; FailIfExists: Boolean): Boolean;\n{$IFDEF UNIX}\nvar\n  DesStream, SrcStream: TFileStream;\n{$ENDIF}\nbegin\n{$IFDEF UNIX}\n  Result := False;\n  if not FailIfExists or not FileExists(Destination) then\n    try\n      SrcStream := TFileStream.Create(Source, fmOpenRead or fmShareDenyWrite);\n      try\n        DesStream := TFileStream.Create(Destination, fmCreate);\n        try\n          DesStream.CopyFrom(SrcStream, 0);\n          Result := True;\n        finally\n          DesStream.Free;\n        end;\n      finally\n        SrcStream.Free;\n      end;\n    except\n      // Ignore errors and just return false\n    end;\n{$ENDIF UNIX}\n{$IFDEF MSWINDOWS}\n  Result := CopyFile(PChar(Source), PChar(Destination), FailIfExists);\n{$ENDIF MSWINDOWS}\nend;\n{ -------------------------------------------------------------------------- }\nprocedure AbCreateDirectory( const Path : string );\n  {creates the requested directory tree.  CreateDir is insufficient,\n   because if you have a path x:\\dir, and request x:\\dir\\sub1\\sub2,\n   (/dir and /dir/sub1/sub2 on Unix) it fails.}\nvar\n  iStartSlash : Integer;\n  i : Integer;\n  TempPath : string;\nbegin\n  if DirectoryExists( Path ) then\n    Exit;\n  {see how much of the path currently exists}\n  if Pos( '\\\\', Path ) > 0 then\n    {UNC Path  \\\\computername\\sharename\\path1..\\pathn}\n    iStartSlash := 5\n  else\n    {standard Path drive:\\path1..\\pathn}\n    iStartSlash := 2;\n\n  repeat\n    {find the Slash at iStartSlash}\n    i := AbFindNthSlash( Path, iStartSlash );\n    {get a temp path to try: drive:\\path1}\n    TempPath := Copy( Path, 1, i );\n    {if it doesn't exist, create it}\n    if not DirectoryExists( TempPath ) then\n      MkDir( TempPath );\n    inc( iStartSlash );\n  until ( Length( TempPath ) = Length( Path ) );\nend;\n{ -------------------------------------------------------------------------- }\nfunction AbCreateTempFile(const Dir : string) : string;\nbegin\n  Result := AbGetTempFile(Dir, True);\nend;\n{ -------------------------------------------------------------------------- }\nfunction AbGetTempDirectory : string;\nbegin\n{$IFDEF MSWiNDOWS}\n  SetLength(Result, MAX_PATH);\n  SetLength(Result, GetTempPath(Length(Result),  PChar(Result)));\n{$ENDIF}\n{$IFDEF UNIX}\n  Result := '/tmp/';\n{$ENDIF}\nend;\n{ -------------------------------------------------------------------------- }\nfunction AbGetTempFile(const Dir : string; CreateIt : Boolean) : string;\nvar\n  TempPath : string;\n{$IFDEF MSWINDOWS}\n  FileNameZ : array [0..259] of char;\n{$ENDIF}\n{$IFDEF UNIX}\n  hFile: Integer;\n  FileName: AbSysString;\n{$ENDIF}\nbegin\n  if DirectoryExists(Dir) then\n    TempPath := Dir\n  else\n    TempPath := AbGetTempDirectory;\n{$IFDEF MSWINDOWS}\n  GetTempFileName(PChar(TempPath), 'VMS', Word(not CreateIt), FileNameZ);\n  Result := string(FileNameZ);\n{$ENDIF}\n{$IFDEF UNIX}\n  FileName := AbSysString(TempPath) + 'VMSXXXXXX';\n  mktemp(PAnsiChar(AbSysString(FileName)));\n  Result := string(FileName);\n  if CreateIt then begin\n    hFile := FileCreate(Result);\n    if hFile <> -1 then\n      FileClose(hFile);\n  end;\n{$ENDIF}\nend;\n{ -------------------------------------------------------------------------- }\nfunction AbDrive(const ArchiveName : string) : Char;\nvar\n  iPos: Integer;\n  Path : string;\nbegin\n  Path := ExpandFileName(ArchiveName);\n  iPos := Pos(':', Path);\n  if (iPos <= 0) then\n    Result := 'A'\n  else\n    Result := Path[1];\nend;\n{ -------------------------------------------------------------------------- }\nfunction AbDriveIsRemovable(const ArchiveName : string) : Boolean;\n{$IFDEF MSWINDOWS}\nvar\n  Path: string;\n{$ENDIF}\nbegin\n{$IFDEF MSWINDOWS}\n  Path := ExpandFileName(ArchiveName);\n  if AnsiStartsText('\\\\?\\UNC\\', Path) then\n    Delete(Path, 1, 8)\n  else if AnsiStartsText('\\\\?\\', Path) then\n    Delete(Path, 1, 4);\n  Path := IncludeTrailingPathDelimiter(ExtractFileDrive(Path));\n  Result := GetDriveType(PChar(Path)) = DRIVE_REMOVABLE;\n{$ENDIF}\n{$IFDEF LINUX}\n  {LINUX -- Following may not cover all the bases}\n  Result := AnsiStartsText('/mnt/floppy', ExtractFilePath(ExpandFileName(ArchiveName)));\n{$ENDIF}\n{$IFDEF DARWIN}\n  Result := False;\n{$ENDIF}\nend;\n{ -------------------------------------------------------------------------- }\nfunction AbGetDriveFreeSpace(const ArchiveName : string) : Int64;\n{ attempt to find free space (in bytes) on drive/volume,\n  returns -1 if fails for some reason }\n{$IFDEF MSWINDOWS}\nvar\n  FreeAvailable, TotalSpace: Int64;\nbegin\n  if GetDiskFreeSpaceEx(PChar(ExtractFilePath(ExpandFileName(ArchiveName))),\n                        FreeAvailable, TotalSpace, nil) then\n    Result := FreeAvailable\n  else\n    Result := -1;\n{$ENDIF}\n{$IFDEF UNIX}\nvar\n  FStats : {$IFDEF PosixAPI}_statvfs{$ELSE}TStatFs{$ENDIF};\nbegin\n  {$IF DEFINED(LibcAPI)}\n  if statfs(PAnsiChar(ExtractFilePath(ArchiveName)), FStats) = 0 then\n    Result := Int64(FStats.f_bAvail) * Int64(FStats.f_bsize)\n  {$ELSEIF DEFINED(FPCUnixAPI)}\n  if fpStatFS(PAnsiChar(ExtractFilePath(ArchiveName)), @FStats) = 0 then\n    Result := Int64(FStats.bAvail) * Int64(FStats.bsize)\n  {$ELSEIF DEFINED(PosixAPI)}\n  if statvfs(PAnsiChar(AbSysString(ExtractFilePath(ArchiveName))), FStats) = 0 then\n    Result := Int64(FStats.f_bavail) * Int64(FStats.f_bsize)\n  {$IFEND}\n  else\n    Result := -1;\n{$ENDIF}\nend;\n{ -------------------------------------------------------------------------- }\nfunction AbFileMatch(FileName: string; FileMask: string ): Boolean;\n  {see if FileName matches FileMask}\nvar\n  DirMatch : Boolean;\n  MaskDir : string;\nbegin\n  FileName := UpperCase( FileName );\n  FileMask := UpperCase( FileMask );\n  MaskDir := ExtractFilePath( FileMask );\n  if MaskDir = '' then\n    DirMatch := True\n  else\n    DirMatch := AbPatternMatch( ExtractFilePath( FileName ), 1, MaskDir, 1 );\n\n  Result := DirMatch and AbPatternMatch( ExtractFileName( FileName ), 1,\n                                       ExtractFileName( FileMask ), 1 );\nend;\n{ -------------------------------------------------------------------------- }\nprocedure AbFindFiles( const FileMask : string; SearchAttr : Integer;\n                       FileList : TStrings; Recurse : Boolean );\nvar\n  NewFile : string;\n  SR : TSearchRec;\n  Found : Integer;\n  NameMask: string;\nbegin\n  Found := FindFirst( FileMask, SearchAttr, SR );\n  if Found = 0 then begin\n    try\n      NameMask := UpperCase(ExtractFileName(FileMask));\n      while Found = 0 do begin\n        NewFile := ExtractFilePath( FileMask ) + SR.Name;\n        if (SR.Name <> AbThisDir) and\n           (SR.Name <> AbParentDir) and\n           AbPatternMatch(UpperCase(SR.Name), 1, NameMask, 1) then\n          if (SR.Attr and faDirectory) <> 0 then\n            FileList.Add( NewFile + PathDelim )\n          else\n            FileList.Add( NewFile );\n        Found := FindNext( SR );\n      end;\n    finally\n      FindClose( SR );\n    end;\n  end;\n  if not Recurse then\n    Exit;\n  NewFile := ExtractFilePath( FileMask );\n  if ( NewFile <> '' ) and ( NewFile[Length(NewFile)] <> AbPathDelim) then\n    NewFile := NewFile + AbPathDelim;\n  NewFile := NewFile + AbAnyFile;\n\n  Found := FindFirst( NewFile, faDirectory or SearchAttr, SR );\n  if Found = 0 then begin\n    try\n      while ( Found = 0 ) do begin\n        if ( SR.Name <> AbThisDir ) and\n           ( SR.Name <> AbParentDir ) and\n           ((SR.Attr and faDirectory) > 0 ) then\n          AbFindFiles( ExtractFilePath( NewFile ) + SR.Name + AbPathDelim +\n                       ExtractFileName( FileMask ), SearchAttr,\n                       FileList, True );\n        Found := FindNext( SR );\n      end;\n    finally\n      FindClose( SR );\n    end;\n  end;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure AbFindFilesEx( const FileMask : string; SearchAttr : Integer;\n                       FileList : TStrings; Recurse : Boolean );\nvar\n  I, J: Integer;\n  MaskPart: string;\nbegin\n  I := 1;\n  while I <= Length(FileMask) do begin\n    J := I;\n    while (I <= Length(FileMask)) and (FileMask[I] <> AbPathSep) do Inc(I);\n    MaskPart := Trim(Copy(FileMask, J, I - J));\n    if (I <= Length(FileMask)) and (FileMask[I] = AbPathSep) then Inc(I);\n\n    AbFindFiles(MaskPart, SearchAttr, FileList, Recurse);\n  end;\nend;\n{ -------------------------------------------------------------------------- }\nfunction AbAddBackSlash(const DirName : string) : string;\n{ Add a default slash to a directory name }\nconst\n  AbDelimSet : set of AnsiChar = [AbPathDelim, ':', #0];\nbegin\n  Result := DirName;\n  if Length(DirName) = 0 then\n    Exit;\n  if not CharInSet(DirName[Length(DirName)], AbDelimSet) then\n    Result := DirName + AbPathDelim;\nend;\n{ -------------------------------------------------------------------------- }\nfunction AbFindNthSlash( const Path : string; n : Integer ) : Integer;\n{ return the position of the character just before the nth slash }\nvar\n  i : Integer;\n  Len : Integer;\n  iSlash : Integer;\nbegin\n  Len := Length( Path );\n  Result := Len;\n  iSlash := 0;\n  i := 0;\n  while i <= Len do begin\n    if Path[i] = AbPathDelim then begin\n      inc( iSlash );\n      if iSlash = n then begin\n        Result := pred( i );\n        break;\n      end;\n    end;\n    inc( i );\n  end;\nend;\n{ -------------------------------------------------------------------------- }\nfunction AbGetPathType( const Value : string ) : TAbPathType;\n{ returns path type - none, relative or absolute }\nbegin\n  Result := ptNone;\n{$IFDEF MSWINDOWS}\n{check for drive/unc info}\n  if ( Pos( '\\\\', Value ) > 0 ) or ( Pos( ':', Value ) > 0 ) then\n{$ENDIF MSWINDOWS}\n{$IFDEF UNIX}\n{ UNIX absolute paths start with a slash }\n  if (Value[1] = AbPathDelim) then\n{$ENDIF UNIX}\n    Result := ptAbsolute\n  else if ( Pos( AbPathDelim, Value ) > 0 ) or ( Pos( AB_ZIPPATHDELIM, Value ) > 0 ) then\n    Result := ptRelative;\nend;\n{ -------------------------------------------------------------------------- }\n{$IFDEF MSWINDOWS}\n{$WARN SYMBOL_PLATFORM OFF}\nfunction AbGetShortFileSpec(const LongFileSpec : string ) : string;\nvar\n  SR : TSearchRec;\n  Search : string;\n  Drive : string;\n  Path : string;\n  FileName : string;\n  Found : Integer;\n  SubPaths : TStrings;\n  i : Integer;\nbegin\n  AbParseFileName( LongFileSpec, Drive, Path, FileName );\n  SubPaths := TStringList.Create;\n  try\n    AbParsePath( Path, SubPaths );\n    Search := Drive;\n    Result := Search + AbPathDelim;\n    if SubPaths.Count > 0 then\n      for i := 0 to pred( SubPaths.Count ) do begin\n        Search := Search + AbPathDelim + SubPaths[i];\n        Found := FindFirst( Search, faHidden + faSysFile + faDirectory, SR );\n        if Found <> 0 then\n          raise EAbException.Create( 'Path not found' );\n        try\n          Result := Result + ExtractShortName(SR) + AbPathDelim;\n        finally\n          FindClose( SR );\n        end;\n      end;\n    Search := Search + AbPathDelim + FileName;\n    Found := FindFirst( Search,\n                        faReadOnly + faHidden + faSysFile + faArchive, SR );\n    if Found <> 0 then\n      raise EAbFileNotFound.Create;\n    try\n      Result := Result + ExtractShortName(SR);\n    finally\n      FindClose( SR );\n    end;\n  finally\n    SubPaths.Free;\n  end;\nend;\n{$WARN SYMBOL_PLATFORM ON}\n{$ENDIF}\n{ -------------------------------------------------------------------------- }\nprocedure AbIncFilename( var Filename : string; Value : Word );\n{ place value at the end of filename, e.g. Files.C04 }\nvar\n  Ext : string;\n  I : Word;\nbegin\n  I := (Value + 1) mod 100;\n  Ext := ExtractFileExt(Filename);\n  if (Length(Ext) < 2) then\n    Ext := '.' + Format('%.2d', [I])\n  else\n    Ext := Ext[1] + Ext[2] + Format('%.2d', [I]);\n  Filename := ChangeFileExt(Filename, Ext);\nend;\n{ -------------------------------------------------------------------------- }\nprocedure AbParseFileName( FileSpec : string;\n                           out Drive : string;\n                           out Path : string;\n                           out FileName : string );\nvar\n  i : Integer;\n  iColon : Integer;\n  iStartSlash : Integer;\nbegin\n  if Pos( AB_ZIPPATHDELIM, FileSpec ) > 0 then\n    AbUnfixName( FileSpec );\n  FileName := ExtractFileName( FileSpec );\n  Path := ExtractFilePath( FileSpec );\n  {see how much of the path currently exists}\n  iColon := Pos( ':', Path );\n  if Pos( '\\\\', Path ) > 0 then begin\n    {UNC Path  \\\\computername\\sharename\\path1..\\pathn}\n    {everything up to the 4th slash is the drive}\n    iStartSlash := 4;\n    i := AbFindNthSlash( Path, iStartSlash );\n    Drive := Copy( Path, 1, i );\n    Delete( Path, 1, i + 1 );\n  end\n  else if iColon > 0 then begin\n    Drive := Copy( Path, 1, iColon );\n    Delete( Path, 1, iColon );\n    if Path[1] = AbPathDelim then\n      Delete( Path, 1, 1 );\n  end;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure AbParsePath( Path : string; SubPaths : TStrings );\n{ break abart path into subpaths --- Path : abbrevia/examples >\n                                        SubPaths[0] = abbrevia\n                                        SubPaths[1] = examples}\nvar\n  i : Integer;\n  iStart : Integer;\n  iStartSlash : Integer;\n  SubPath : string;\nbegin\n  if Path = '' then Exit;\n  if Path[ Length( Path ) ] = AbPathDelim then\n    Delete( Path, Length( Path ), 1 );\n  iStart := 1;\n  iStartSlash := 1;\n  repeat\n    {find the Slash at iStartSlash}\n    i := AbFindNthSlash( Path, iStartSlash );\n    {get the subpath}\n    SubPath := Copy( Path, iStart, i - iStart + 1 );\n    iStart := i + 2;\n    inc( iStartSlash );\n    SubPaths.Add( SubPath );\n  until ( i = Length( Path ) );\nend;\n{ -------------------------------------------------------------------------- }\nfunction AbPatternMatch(const Source : string; iSrc : Integer;\n                        const Pattern : string; iPat : Integer ) : Boolean;\n{ recursive routine to see if the source string matches\n  the pattern.  Both ? and * wildcard characters are allowed.\n  Compares Source from iSrc to Length(Source) to\n  Pattern from iPat to Length(Pattern)}\nvar\n  Matched : Boolean;\n  k : Integer;\nbegin\n  if Length( Source ) = 0 then begin\n    Result := Length( Pattern ) = 0;\n    Exit;\n  end;\n\n  if iPat = 1 then begin\n    if ( CompareStr( Pattern, AbDosAnyFile) = 0 ) or\n       ( CompareStr( Pattern, AbUnixAnyFile ) = 0 ) then begin\n      Result := True;\n      Exit;\n    end;\n  end;\n\n  if Length( Pattern ) = 0 then begin\n    Result := (Length( Source ) - iSrc + 1 = 0);\n    Exit;\n  end;\n\n  while True do begin\n    if ( Length( Source ) < iSrc ) and\n       ( Length( Pattern ) < iPat ) then begin\n      Result := True;\n      Exit;\n    end;\n\n    if Length( Pattern ) < iPat then begin\n      Result := False;\n      Exit;\n    end;\n\n    if Pattern[iPat] = '*' then begin\n      k := iPat;\n      if ( Length( Pattern ) < iPat + 1 ) then begin\n        Result := True;\n        Exit;\n      end;\n\n      while True do begin\n        Matched := AbPatternMatch( Source, k, Pattern, iPat + 1 );\n        if Matched or ( Length( Source ) < k ) then begin\n          Result := Matched;\n          Exit;\n        end;\n        inc( k );\n      end;\n    end\n    else begin\n      if ( (Pattern[iPat] = '?') and\n           ( Length( Source ) <> iSrc - 1 ) ) or\n           ( Pattern[iPat] = Source[iSrc] ) then begin\n        inc( iPat );\n        inc( iSrc );\n      end\n      else begin\n        Result := False;\n        Exit;\n      end;\n    end;\n  end;\nend;\n{ -------------------------------------------------------------------------- }\nfunction AbPercentage(V1, V2 : Int64) : Byte;\n{ Returns the ratio of V1 to V2 * 100 }\nbegin\n  if V2 <= 0 then\n    Result := 0\n  else if V1 >= V2 then\n    Result := 100\n  else\n    Result := (V1 * 100) div V2;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure AbStripDots( var FName : string );\n{ strips relative path information, e.g. \"..\"}\nbegin\n  while Pos( AbParentDir + AbPathDelim, FName ) = 1 do\n    System.Delete( FName, 1, 3 );\nend;\n{ -------------------------------------------------------------------------- }\nprocedure AbStripDrive( var FName : string );\n{ strips the drive off a filename }\nvar\n  Drive, Path, Name : string;\nbegin\n  AbParseFileName( FName, Drive, Path, Name );\n  FName := Path + Name;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure AbFixName( var FName : string );\n{ changes backslashes to forward slashes }\nvar\n  i : Integer;\nbegin\n  for i := 1 to Length( FName ) do\n    if FName[i] = AbPathDelim then\n      FName[i] := AB_ZIPPATHDELIM;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure AbUnfixName( var FName : string );\n{ changes forward slashes to backslashes }\nvar\n  i : Integer;\nbegin\n  for i := 1 to Length( FName ) do\n    if FName[i] = AB_ZIPPATHDELIM then\n      FName[i] := AbPathDelim;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure AbUpdateCRC( var CRC : LongInt; const Buffer; Len : Integer );\nvar\n  BufPtr : PByte;\n  i : Integer;\n  CRCTemp : DWORD;\nbegin\n  BufPtr := @Buffer;\n  CRCTemp := CRC;\n  for i := 0 to pred( Len ) do\n  begin\n    CRCTemp := AbCrc32Table[ Byte(CrcTemp) xor (BufPtr^) ] xor\n              ((CrcTemp shr 8) and $00FFFFFF);\n    Inc(BufPtr);\n  end;\n  CRC := CRCTemp;\nend;\n{ -------------------------------------------------------------------------- }\nfunction AbUpdateCRC32(CurByte : Byte; CurCrc : LongInt) : LongInt;\n{ Return the updated 32bit CRC }\n{ Normally a good candidate for basm, but Delphi32's code\n    generation couldn't be beat on this one!}\nbegin\n  Result := DWORD(AbCrc32Table[ Byte(CurCrc xor LongInt( CurByte ) ) ] xor\n            ((CurCrc shr 8) and DWORD($00FFFFFF)));\nend;\n{ -------------------------------------------------------------------------- }\nfunction AbCRC32Of( const aValue : RawByteString ) : LongInt;\nbegin\n  Result := -1;\n  AbUpdateCRC(Result, aValue[1], Length(aValue));\n  Result := not Result;\nend;\n{ -------------------------------------------------------------------------- }\nfunction AbWriteVolumeLabel(const VolName : string;\n                                Drive : Char) : Cardinal;\nvar\n  Temp : string;\n  Vol : array[0..11] of Char;\n  Root : array[0..3] of Char;\nbegin\n  Temp := VolName;\n  StrCopy(Root, '%:' + AbPathDelim);\n  Root[0] := Drive;\n  if Length(Temp) > 11 then\n    SetLength(Temp, 11);\n  StrPCopy(Vol, Temp);\n{$IFDEF MSWINDOWS}\n  if Windows.SetVolumeLabel(Root, Vol) then\n    Result := 0\n  else Result := GetLastError;\n{$ENDIF MSWINDOWS}\n{$IFDEF UNIX}\n{ Volume labels not supported on Unix }\n  Result := 0;\n{$ENDIF UNIX}\nend;\n{ -------------------------------------------------------------------------- }\n{$IFDEF MSWINDOWS}\nfunction AbOffsetFromUTC: LongInt;\n{ local timezone's offset from UTC in seconds (UTC = local + bias) }\nvar\n\tTZI: TTimeZoneInformation;\nbegin\ncase GetTimeZoneInformation(TZI) of\n\tTIME_ZONE_ID_UNKNOWN:\n\t\tResult := TZI.Bias;\n\tTIME_ZONE_ID_DAYLIGHT:\n\t\tResult := TZI.Bias + TZI.DaylightBias;\n\tTIME_ZONE_ID_STANDARD:\n\t\tResult := TZI.Bias + TZI.StandardBias\n\telse\n    Result := 0\n\tend;\nResult := Result * SecondsInMinute;\nend;\n{$ENDIF}\n{ -------------------------------------------------------------------------- }\nfunction AbUnixTimeToLocalDateTime(UnixTime : LongInt) : TDateTime;\n{ convert UTC unix date to Delphi TDateTime in local timezone }\n{$IFDEF MSWINDOWS}\nvar\n  Hrs, Mins, Secs : Word;\n  TodaysSecs : LongInt;\n  Time: TDateTime;\nbegin\n  UnixTime := UnixTime - AbOffsetFromUTC;\n  TodaysSecs := UnixTime mod SecondsInDay;\n  Hrs := TodaysSecs div SecondsInHour;\n  TodaysSecs := TodaysSecs - (Hrs * SecondsInHour);\n  Mins := TodaysSecs div SecondsInMinute;\n  Secs := TodaysSecs - (Mins * SecondsInMinute);\n\n  if TryEncodeTime(Hrs, Mins, Secs, 0, Time) then\n    Result := Unix0Date + (UnixTime div SecondsInDay) + Time\n  else\n    Result := 0;\n{$ENDIF}\n{$IFDEF UNIX}\nbegin\n  Result := FileDateToDateTime(UnixTime);\n{$ENDIF}\nend;\n\n{ -------------------------------------------------------------------------- }\nfunction AbLocalDateTimeToUnixTime(DateTime : TDateTime) : LongInt;\n{ convert local Delphi TDateTime to UTC unix date }\n{$IFDEF MSWINDOWS}\nvar\n  Hrs, Mins, Secs, MSecs : Word;\n  Dt, Tm : TDateTime;\nbegin\n  Dt := Trunc(DateTime);\n  Tm := DateTime - Dt;\n  if Dt < Unix0Date then\n    Result := 0\n  else\n    Result := Trunc(Dt - Unix0Date) * SecondsInDay;\n\n  DecodeTime(Tm, Hrs, Mins, Secs, MSecs);\n  Result := Result + (Hrs * SecondsInHour) + (Mins * SecondsInMinute) + Secs;\n  Result := Result + AbOffsetFromUTC;\n{$ENDIF}\n{$IFDEF UNIX}\nbegin\n  Result := DateTimeToFileDate(DateTime);\n{$ENDIF}\nend;\n{ -------------------------------------------------------------------------- }\nfunction AbDosFileDateToDateTime(FileDate, FileTime : Word) : TDateTime;\n{$IFDEF MSWINDOWS}\nvar\n  Temp : LongInt;\nbegin\n  LongRec(Temp).Lo := FileTime;\n  LongRec(Temp).Hi := FileDate;\n  Result := FileDateToDateTime(Temp);\n{$ENDIF MSWINDOWS}\n{$IFDEF UNIX}\nvar\n  Yr, Mo, Dy : Word;\n  Hr, Mn, S  : Word;\nbegin\n  Yr := FileDate shr 9 + 1980;\n\n  Mo := FileDate shr 5 and 15;\n  if Mo < 1 then Mo := 1;\n  if Mo > 12 then Mo := 12;\n\n  Dy := FileDate and 31;\n  if Dy < 1 then Dy := 1;\n  if Dy > DaysInAMonth(Yr, Mo) then\n    Dy := DaysInAMonth(Yr, Mo);\n\n  Hr := FileTime shr 11;\n  if Hr > 23 then Hr := 23;\n\n  Mn := FileTime shr 5 and 63;\n  if Mn > 59 then Mn := 59;\n\n  S  := FileTime and 31 shl 1;\n  if S > 59 then S := 59;\n\n  Result :=\n    EncodeDate(Yr, Mo, Dy) +\n    EncodeTime(Hr, Mn, S, 0);\n{$ENDIF UNIX}\nend;\n\nfunction AbDateTimeToDosFileDate(Value : TDateTime) : LongInt;\n{$IFDEF MSWINDOWS}\nbegin\n  Result := DateTimeToFileDate(Value);\n{$ENDIF MSWINDOWS}\n{$IFDEF UNIX}\nvar\n  Yr, Mo, Dy : Word;\n  Hr, Mn, S, MS: Word;\nbegin\n  DecodeDate(Value, Yr, Mo, Dy);\n  if (Yr < 1980) or (Yr > 2107) then { outside DOS file date year range }\n    Yr := 1980;\n  DecodeTime(Value, Hr, Mn, S, MS);\n\n  LongRec(Result).Lo := (S shr 1) or (Mn shl 5) or (Hr shl 11);\n  LongRec(Result).Hi := Dy or (Mo shl 5) or (Word(Yr - 1980) shl 9);\n{$ENDIF UNIX}\nend;\n\n{ -------------------------------------------------------------------------- }\n\nfunction AbGetFileTime(const aFileName: string): TDateTime;\nvar\n  Attr: TAbAttrExRec;\nbegin\n  AbFileGetAttrEx(aFileName, Attr);\n  Result := Attr.Time;\nend;\n\nfunction AbSetFileTime(const aFileName: string; aValue: TDateTime): Boolean;\nbegin\n  {$IFDEF MSWINDOWS}\n  Result := FileSetDate(aFileName, AbDateTimeToDosFileDate(aValue)) = 0;\n  {$ENDIF}\n  {$IFDEF UNIX}\n  Result := FileSetDate(aFileName, AbLocalDateTimeToUnixTime(aValue)) = 0;\n  {$ENDIF}\nend;\n\n{ -------------------------------------------------------------------------- }\nfunction AbSwapLongEndianness(Value : LongInt): LongInt;\n{ convert BigEndian <-> LittleEndian 32-bit value }\ntype\n  TCastArray = array [0..3] of Byte;\nvar\n  i : Integer;\nbegin\n  for i := 3 downto 0 do\n    TCastArray(Result)[3-i] := TCastArray(Value)[i];\nend;\n{ -------------------------------------------------------------------------- }\nfunction AbDOS2UnixFileAttributes(Attr: LongInt): LongInt;\nbegin\n  {$WARN SYMBOL_PLATFORM OFF}\n  Result := { default permissions }\n    AB_FPERMISSION_OWNERREAD or\n    AB_FPERMISSION_GROUPREAD or\n    AB_FPERMISSION_OTHERREAD;\n\n  if (Attr and faReadOnly) = 0 then\n    Result := Result or AB_FPERMISSION_OWNERWRITE;\n\n  if (Attr and faDirectory) <> 0 then\n    Result := Result or AB_FMODE_DIR or AB_FPERMISSION_OWNEREXECUTE or\n      AB_FPERMISSION_GROUPEXECUTE or AB_FPERMISSION_OTHEREXECUTE\n  else\n    Result := Result or AB_FMODE_FILE;\n  {$WARN SYMBOL_PLATFORM ON}\nend;\n{ -------------------------------------------------------------------------- }\nfunction AbUnix2DosFileAttributes(Attr: LongInt): LongInt;\nbegin\n  {$WARN SYMBOL_PLATFORM OFF}\n  Result := 0;\n  case (Attr and $F000) of\n    AB_FMODE_FILE, AB_FMODE_FILE2: { standard file }\n      Result := 0;\n\n    AB_FMODE_DIR: { directory }\n      Result := Result or faDirectory;\n\n    AB_FMODE_FIFO,\n    AB_FMODE_CHARSPECFILE,\n    AB_FMODE_BLOCKSPECFILE,\n    AB_FMODE_FILELINK,\n    AB_FMODE_SOCKET:\n      Result := Result or faSysFile;\n  end;\n\n  if (Attr and AB_FPERMISSION_OWNERWRITE) <> AB_FPERMISSION_OWNERWRITE then\n    Result := Result or faReadOnly;\n  {$WARN SYMBOL_PLATFORM ON}\nend;\n{ -------------------------------------------------------------------------- }\nprocedure AbSetFileAttr(const aFileName : string; aAttr: Integer);\nbegin\n  {$WARN SYMBOL_PLATFORM OFF}\n  {$IFDEF MSWINDOWS}\n  FileSetAttr(aFileName, aAttr);\n  {$ENDIF}\n  {$IF DEFINED(LibcAPI) OR DEFINED(PosixAPI)}\n  chmod(PAnsiChar(AbSysString(aFileName)), aAttr);\n  {$ELSEIF DEFINED(FPCUnixAPI)}\n  fpchmod(aFileName, aAttr);\n  {$IFEND}\n  {$WARN SYMBOL_PLATFORM ON}\nend;\n{ -------------------------------------------------------------------------- }\nfunction AbFileGetSize(const aFileName : string) : Int64;\nvar\n  SR: TAbAttrExRec;\nbegin\n  if AbFileGetAttrEx(aFileName, SR) then\n    Result := SR.Size\n  else\n    Result := -1;\nend;\n{ -------------------------------------------------------------------------- }\nfunction AbFileGetAttrEx(const aFileName: string; out aAttr: TAbAttrExRec) : Boolean;\nvar\n{$IFDEF MSWINDOWS}\n  FileDate: LongRec;\n  FindData: TWin32FindData;\n  LocalFileTime: TFileTime;\n{$ENDIF}\n{$IFDEF FPCUnixAPI}\n  StatBuf: stat;\n{$ENDIF}\n{$IFDEF LibcAPI}\n  StatBuf: TStatBuf64;\n{$ENDIF}\n{$IFDEF PosixAPI}\n  StatBuf: _stat;\n{$ENDIF}\nbegin\n  aAttr.Time := 0;\n  aAttr.Size := -1;\n  aAttr.Attr := -1;\n  aAttr.Mode := 0;\n{$IFDEF MSWINDOWS}\n  Result := GetFileAttributesEx(PChar(aFileName), GetFileExInfoStandard, @FindData);\n  if Result then begin\n    if FileTimeToLocalFileTime(FindData.ftLastWriteTime, LocalFileTime) and\n       FileTimeToDosDateTime(LocalFileTime, FileDate.Hi, FileDate.Lo) then\n      aAttr.Time := FileDateToDateTime(Integer(FileDate));\n    LARGE_INTEGER(aAttr.Size).LowPart := FindData.nFileSizeLow;\n    LARGE_INTEGER(aAttr.Size).HighPart := FindData.nFileSizeHigh;\n    aAttr.Attr := FindData.dwFileAttributes;\n    aAttr.Mode := AbDOS2UnixFileAttributes(FindData.dwFileAttributes);\n  end;\n{$ENDIF}\n{$IFDEF UNIX}\n  {$IFDEF FPCUnixAPI}\n  Result := (FpStat(aFileName, StatBuf) = 0);\n  {$ENDIF}\n  {$IFDEF LibcAPI}\n  // Work around Kylix QC#2761: Stat64, et al., are defined incorrectly\n  Result := (__lxstat64(_STAT_VER, PAnsiChar(aFileName), StatBuf) = 0);\n  {$ENDIF}\n  {$IFDEF PosixAPI}\n  Result := (stat(PAnsiChar(AbSysString(aFileName)), StatBuf) = 0);\n  {$ENDIF}\n  if Result then begin\n    aAttr.Time := FileDateToDateTime(StatBuf.st_mtime);\n    aAttr.Size := StatBuf.st_size;\n    aAttr.Attr := AbUnix2DosFileAttributes(StatBuf.st_mode);\n    aAttr.Mode := StatBuf.st_mode;\n  end;\n{$ENDIF UNIX}\nend;\n\n\nconst\n  MAX_VOL_LABEL = 16;\n\nfunction AbGetVolumeLabel(Drive : Char) : string;\n{-Get the volume label for the specified drive.}\n{$IFDEF MSWINDOWS}\nvar\n  Root : string;\n  Flags, MaxLength : DWORD;\n  NameSize : Integer;\n  VolName : string;\n{$ENDIF}\nbegin\n{$IFDEF MSWINDOWS}\n  NameSize := 0;\n  Root := Drive + ':\\';\n  SetLength(VolName, MAX_VOL_LABEL);\n\n  Result := '';\n\n  if GetVolumeInformation(PChar(Root), PChar(VolName), Length(VolName),\n    nil, MaxLength, Flags, nil, NameSize)\n  then\n    Result := VolName;\n{$ELSE}\n  Result := ''; //Stop Gap, spanning support needs to be rethought for Unix\n{$ENDIF}\nend;\n\nprocedure AbSetSpanVolumeLabel(Drive: Char; VolNo : Integer);\nbegin\n  AbWriteVolumeLabel(Format(AB_SPAN_VOL_LABEL,\n    [VolNo]), Drive);\nend;\n\nfunction AbTestSpanVolumeLabel(Drive: Char; VolNo : Integer): Boolean;\nvar\n  VolLabel, TestLabel : string;\nbegin\n  TestLabel := Format(AB_SPAN_VOL_LABEL, [VolNo]);\n  VolLabel := UpperCase(AbGetVolumeLabel(Drive));\n  Result := VolLabel = TestLabel;\nend;\n\n{ Unicode backwards compatibility functions }\n{$IFNDEF UNICODE}\nfunction CharInSet(C: AnsiChar; CharSet: TSysCharSet): Boolean;\nbegin\n  Result := C in CharSet;\nend;\n{$ENDIF}\n\nfunction AbLeftStr(const AText: AnsiString; const ACount: Integer): AnsiString;\nbegin\n{$IFDEF HasAnsiStrings}\n  Result := System.AnsiStrings.LeftStr(AText, ACount);\n{$ELSE}\n  Result := StrUtils.LeftStr(AText, ACount);\n{$ENDIF}\nend;\n\nfunction AbStrLen(const Str: PAnsiChar): Cardinal;\nbegin\n{$IFDEF HasAnsiStrings}\n  Result := System.AnsiStrings.StrLen(Str);\n{$ELSE}\n  Result := SysUtils.StrLen(Str);\n{$ENDIF}\nend;\n\nfunction AbStrPCopy(Dest: PAnsiChar; const Source: AnsiString): PAnsiChar;\nbegin\n{$IFDEF HasAnsiStrings}\n  Result := System.AnsiStrings.StrPCopy(Dest, Source);\n{$ELSE}\n  Result := SysUtils.StrPCopy(Dest, Source);\n{$ENDIF}\nend;\n\nfunction AbStrPLCopy(Dest: PAnsiChar; const Source: AnsiString; MaxLen: Cardinal): PAnsiChar;\nbegin\n{$IFDEF HasAnsiStrings}\n  Result := System.AnsiStrings.StrPLCopy(Dest, Source, MaxLen);\n{$ELSE}\n  Result := SysUtils.StrPLCopy(Dest, Source, MaxLen);\n{$ENDIF}\nend;\n\nend.\n"
  },
  {
    "path": "lib/abbrevia/source/AbVMStrm.pas",
    "content": "(* ***** BEGIN LICENSE BLOCK *****\n * Version: MPL 1.1\n *\n * The contents of this file are subject to the Mozilla Public License Version\n * 1.1 (the \"License\"); you may not use this file except in compliance with\n * the License. You may obtain a copy of the License at\n * http://www.mozilla.org/MPL/\n *\n * Software distributed under the License is distributed on an \"AS IS\" basis,\n * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License\n * for the specific language governing rights and limitations under the\n * License.\n *\n * The Original Code is TurboPower Abbrevia\n *\n * The Initial Developer of the Original Code is\n * TurboPower Software\n *\n * Portions created by the Initial Developer are Copyright (C) 1997-2002\n * the Initial Developer. All Rights Reserved.\n *\n * Contributor(s):\n *\n * ***** END LICENSE BLOCK ***** *)\n\n{*********************************************************}\n{* ABBREVIA: AbVMStrm.pas                                *}\n{*********************************************************}\n{* ABBREVIA: Virtual Memory Stream                       *}\n{*********************************************************}\n\nunit AbVMStrm;\n\n{$I AbDefine.inc}\n\ninterface\n\nuses\n  Classes;\n\nconst\n  AB_VMSPageSize = 4096; {must be a power of two}\n  AB_VMSMaxPages = 2048; {makes 8MB with the above value}\n\ntype\n  PvmsPage = ^TvmsPage;\n  TvmsPage = packed record\n    vpStmOfs : Int64;    {value will be multiple of AB_VMSPageSize}\n    vpLRU    : integer;  {'time' page was last accessed}\n    vpDirty  : Boolean;  {has the page been changed?}\n    vpData   : array [0..pred(AB_VMSPageSize)] of byte; {stream data}\n  end;\n\ntype\n  TAbVirtualMemoryStream = class(TStream)\n    protected {private}\n      vmsCachePage    : PvmsPage;   {the latest page used}\n      vmsLRU          : Longint;    {'tick' value}\n      vmsMaxMemToUse  : Longword;   {maximum memory to use for data}\n      vmsMaxPages     : Integer;    {maximum data pages}\n      vmsPageList     : TList;      {page array, sorted by offset}\n      vmsPosition     : Int64;      {position of stream}\n      vmsSize         : Int64;      {size of stream}\n      vmsSwapFileDir  : string;     {swap file directory}\n      vmsSwapFileName : string;     {swap file name}\n      vmsSwapFileSize : Int64;      {size of swap file}\n      vmsSwapStream   : TFileStream;{swap file stream}\n    protected\n      procedure vmsSetMaxMemToUse(aNewMem : Longword);\n\n      function vmsAlterPageList(aNewMem : Longword) : Longword;\n      procedure vmsFindOldestPage(out OldestInx : Longint;\n                                  out OldestPage: PvmsPage);\n      function vmsGetNextLRU : Longint;\n      function vmsGetPageForOffset(aOffset : Int64) : PvmsPage;\n\n      procedure vmsSwapFileCreate;\n      procedure vmsSwapFileDestroy;\n      procedure vmsSwapFileRead(aPage : PvmsPage);\n      procedure vmsSwapFileWrite(aPage : PvmsPage);\n    public\n      constructor Create;\n        {-create the virtual memory stream}\n      destructor Destroy; override;\n        {-destroy the virtual memory stream}\n\n      function Read(var Buffer; Count : Longint) : Longint; override;\n        {-read from the stream into a buffer}\n      function Write(const Buffer; Count : Longint) : Longint; override;\n        {-write to the stream from a buffer}\n      function Seek(const Offset : Int64; Origin : TSeekOrigin) : Int64; override;\n        {-seek to a particular point in the stream}\n\n      procedure SetSize(const NewSize : Int64); override;\n        {-set the stream size}\n\n      property MaxMemToUse : Longword\n         read vmsMaxMemToUse write vmsSetMaxMemToUse;\n        {-maximum memory to use for data before swapping to disk}\n      property SwapFileDirectory : string\n        read vmsSwapFileDir write vmsSwapFileDir;\n  end;\n\nimplementation\n\nuses\n  {$IFDEF MSWINDOWS}\n  Windows, // Fix warning about unexpanded inline functions\n  {$ENDIF}\n  SysUtils,\n  AbExcept,\n  AbUtils;\n\nconst\n  LastLRUValue = $7FFFFFFF;\n\n{===TAbVirtualMemoryStream===========================================}\nconstructor TAbVirtualMemoryStream.Create;\nvar\n  Page : PvmsPage;\nbegin\n  inherited Create;\n  {create the page array}\n  vmsPageList := TList.Create;\n  {create the first page}\n  New(Page);\n  with Page^ do begin\n    vpStmOfs := 0;\n    vpLRU := vmsGetNextLRU;\n    vpDirty := False;\n    FillChar(vpData, AB_VMSPageSize, 0);\n  end;\n  vmsPageList.Insert(0, pointer(Page));\n  {prime the cache, from now on the cache will never be nil}\n  vmsCachePage := Page;\n  {default to using all allowed pages}\n  MaxMemToUse := AB_VMSMaxPages * AB_VMSPageSize;\nend;\n{--------}\ndestructor TAbVirtualMemoryStream.Destroy;\nvar\n  Inx : integer;\nbegin\n  {destroy the swap file}\n  vmsSwapFileDestroy;\n  {throw away all pages in the list}\n  if (vmsPageList <> nil) then begin\n    for Inx := 0 to pred(vmsPageList.Count) do\n      Dispose(PvmsPage(vmsPageList[Inx]));\n    vmsPageList.Destroy;\n  end;\n  {let our ancestor clean up}\n  inherited Destroy;\nend;\n{--------}\nfunction TAbVirtualMemoryStream.Read(var Buffer; Count : Longint) : Longint;\nvar\n  BufPtr      : PByte;\n  Page        : PvmsPage;\n  PageDataInx : integer;\n  Posn        : int64;\n  BytesToGo   : int64;\n  BytesToRead : int64;\n  StartOfs    : int64;\nbegin\n  {reading is complicated by the fact we can only read in chunks of\n   AB_VMSPageSize: we need to partition out the overall read into a read\n   from a partial page, zero or more reads from complete pages and\n   then a possible read from a partial page}\n\n  {initialise some variables, note that the complex calc in the\n   expression for PageDataInx is the offset of the start of the page\n   where Posn is found.}\n  BufPtr := @Buffer;\n  Posn := vmsPosition;\n  PageDataInx := Posn - (Posn and (not pred(AB_VMSPageSize)));\n  BytesToRead := AB_VMSPageSize - PageDataInx;\n  {calculate the actual number of bytes to read - this depends on the\n   current position and size of the stream}\n  BytesToGo := Count;\n  if (vmsSize < (vmsPosition + Count)) then\n    BytesToGo := vmsSize - vmsPosition;\n  if (BytesToGo < 0) then\n    BytesToGo := 0;\n  Result := BytesToGo;\n\n  {while we have bytes to read, read them}\n  while (BytesToGo <> 0) do begin\n    if (BytesToRead > BytesToGo) then\n      BytesToRead := BytesToGo;\n    StartOfs := Posn and (not pred(AB_VMSPageSize));\n    if (vmsCachePage^.vpStmOfs = StartOfs) then\n      Page := vmsCachePage\n    else\n      Page := vmsGetPageForOffset(StartOfs);\n    Move(Page^.vpData[PageDataInx], BufPtr^, BytesToRead);\n    dec(BytesToGo, BytesToRead);\n    inc(Posn, BytesToRead);\n    inc(BufPtr, BytesToRead);\n    PageDataInx := 0;\n    BytesToRead := AB_VMSPageSize;\n  end;\n  {remember our new position}\n  vmsPosition := Posn;\nend;\n{--------}\nfunction TAbVirtualMemoryStream.Seek(const Offset : Int64;\n                                     Origin : TSeekOrigin) : Int64;\nbegin\n  case Origin of\n    soBeginning : vmsPosition := Offset;\n    soCurrent   : inc(vmsPosition, Offset);\n    soEnd       : vmsPosition := vmsSize + Offset;\n  else\n    raise EAbVMSInvalidOrigin.Create( Integer(Origin));\n  end;\n  Result := vmsPosition;\nend;\n{--------}\nprocedure TAbVirtualMemoryStream.SetSize(const NewSize : Int64);\nvar\n  Page : PvmsPage;\n  Inx  : integer;\n  NewFileSize : Int64;\nbegin\n  if (NewSize < vmsSize) then begin\n    {go through the page list discarding pages whose offset is greater\n     than our new size; don't bother saving any data from them since\n     it be beyond the end of the stream anyway}\n    {never delete the last page here}\n    for Inx := pred(vmsPageList.Count) downto 1 do begin\n      Page := PvmsPage(vmsPageList[Inx]);\n      if (Page^.vpStmOfs >= NewSize) then begin\n        Dispose(Page);\n        vmsPageList.Delete(Inx);\n      end else begin\n        Break;\n      end;\n    end;\n\n    { Reset cache to the first page in case the cached page was deleted. }\n    vmsCachePage := vmsPageList[0];\n\n    {force the swap file file size in range, it'll be a multiple of\n     AB_VMSPageSize}\n    NewFileSize := pred(NewSize + AB_VMSPageSize) and\n                   (not pred(AB_VMSPageSize));\n    if (NewFileSize < vmsSwapFileSize) then\n      vmsSwapFileSize := NewFileSize;\n    {ignore the swap file itself}\n  end;\n  vmsSize := NewSize;\n  if (vmsPosition > NewSize) then\n    vmsPosition := NewSize;\nend;\n{--------}\nfunction TAbVirtualMemoryStream.vmsAlterPageList(aNewMem : Longword) : Longword;\nvar\n  NumPages : Longint;\n  Page     : PvmsPage;\n  i        : integer;\n  OldestPageNum : Longint;\nbegin\n  {calculate the max number of pages required}\n  if aNewMem = 0 then\n    NumPages := 1 // always have at least one page\n  else\n    NumPages := pred(aNewMem + AB_VMSPageSize) div AB_VMSPageSize;\n  if (NumPages > AB_VMSMaxPages) then\n    NumPages := AB_VMSMaxPages;\n  {if the maximum number of pages means we have to shrink the current\n   list, do so, tossing out the oldest pages first}\n  if (NumPages < vmsPageList.Count) then\n  begin\n    for i := 1 to (vmsPageList.Count - NumPages) do begin\n      {find the oldest page}\n      vmsFindOldestPage(OldestPageNum, Page);\n      {if it is dirty, write it out to the swap file}\n      if Page^.vpDirty then begin\n        vmsSwapFileWrite(Page);\n      end;\n      {remove it from the page list}\n      vmsPageList.Delete(OldestPageNum);\n      {free the page memory}\n      Dispose(Page);\n    end;\n\n    { Reset cache to the first page in case the cached page was deleted. }\n    vmsCachePage := vmsPageList[0];\n  end;\n  {remember our new max number of pages}\n  vmsMaxPages := NumPages;\n  Result := NumPages * AB_VMSPageSize;\nend;\n{--------}\nprocedure TAbVirtualMemoryStream.vmsFindOldestPage(out OldestInx : Longint;\n                                                   out OldestPage: PvmsPage);\nvar\n  OldestLRU : Longint;\n  Inx       : integer;\n  Page      : PvmsPage;\nbegin\n  OldestInx := -1;\n  OldestLRU := LastLRUValue;\n  for Inx := 0 to pred(vmsPageList.Count) do begin\n    Page := PvmsPage(vmsPageList[Inx]);\n    if (Page^.vpLRU < OldestLRU) then begin\n      OldestInx := Inx;\n      OldestLRU := Page^.vpLRU;\n      OldestPage := Page;\n    end;\n  end;\nend;\n{--------}\nfunction TAbVirtualMemoryStream.vmsGetNextLRU : Longint;\nvar\n  Inx : integer;\nbegin\n  if (vmsLRU = LastLRUValue) then begin\n    {reset all LRUs in list}\n    for Inx := 0 to pred(vmsPageList.Count) do\n      PvmsPage(vmsPageList[Inx])^.vpLRU := 0;\n    vmsLRU := 0;\n  end;\n  inc(vmsLRU);\n  Result := vmsLRU;\nend;\n{--------}\nfunction TAbVirtualMemoryStream.vmsGetPageForOffset(aOffset : Int64) : PvmsPage;\nvar\n  Page     : PvmsPage;\n  PageOfs  : Int64;\n  L, M, R  : integer;\n  OldestPageNum : integer;\n  CreatedNewPage: boolean;\nbegin\n  {using a sequential or a binary search (depending on the number of\n   pages), try to find the page in the cache; we'll do a sequential\n   search if the number of pages is very small, eg less than 4}\n  if (vmsPageList.Count < 4) then begin\n    L := vmsPageList.Count;\n    for M := 0 to pred(vmsPageList.Count) do begin\n      Page := PvmsPage(vmsPageList[M]);\n      PageOfs := Page^.vpStmOfs;\n      if (aOffset < PageOfs) then begin\n        L := M;\n        Break;\n      end;\n      if (aOffset = PageOfs) then begin\n        Page^.vpLRU := vmsGetNextLRU;\n        vmsCachePage := Page;\n        Result := Page;\n        Exit;\n      end;\n    end;\n  end\n  else {we need to do a binary search} begin\n    L := 0;\n    R := pred(vmsPageList.Count);\n    repeat\n      M := (L + R) div 2;\n      Page := PvmsPage(vmsPageList[M]);\n      PageOfs := Page^.vpStmOfs;\n      if (aOffset < PageOfs) then\n        R := pred(M)\n      else if (aOffset > PageOfs) then\n        L := succ(M)\n      else {aOffset = PageOfs} begin\n        Page^.vpLRU := vmsGetNextLRU;\n        vmsCachePage := Page;\n        Result := Page;\n        Exit;\n      end;\n    until (L > R);\n  end;\n  {if we get here the page for the offset is not present in the page\n   list, and once created/loaded, the page should be inserted at L}\n\n  {enter a try..except block so that if a new page is created and an\n   exception occurs, the page is freed}\n  CreatedNewPage := false;\n  Result := nil;\n  try\n    {if there is room to insert a new page, create one ready}\n    if (vmsPageList.Count < vmsMaxPages) then begin\n      New(Page);\n      CreatedNewPage := true;\n    end\n    {otherwise there is no room for the insertion, so find the oldest\n     page in the list and discard it}\n    else {vmsMaxPages <= vmsPageList.Count} begin\n      {find the oldest page}\n      vmsFindOldestPage(OldestPageNum, Page);\n      {if it is dirty, write it out to the swap file}\n      if Page^.vpDirty then begin\n        vmsSwapFileWrite(Page);\n      end;\n      {remove it from the page list}\n      vmsPageList.Delete(OldestPageNum);\n      {patch up the insertion point, in case the page just deleted was\n       before it}\n      if (OldestPageNum < L) then\n        dec(L);\n    end;\n    {set all the page fields}\n    with Page^ do begin\n      vpStmOfs := aOffset;\n      vpLRU := vmsGetNextLRU;\n      vpDirty := False;\n      vmsSwapFileRead(Page);\n    end;\n    {insert the page into the correct spot}\n    vmsPageList.Insert(L, pointer(Page));\n    {return the page, remembering to save it in the cache}\n    vmsCachePage := Page;\n    Result := Page;\n  except\n    if CreatedNewPage then\n      Dispose(Page);\n  end;{try..except}\nend;\n{--------}\nprocedure TAbVirtualMemoryStream.vmsSetMaxMemToUse(aNewMem : Longword);\nbegin\n  vmsMaxMemToUse := vmsAlterPageList(aNewMem);\nend;\n{--------}\nprocedure TAbVirtualMemoryStream.vmsSwapFileCreate;\nbegin\n  if (vmsSwapStream = nil) then begin\n    vmsSwapFileName := AbCreateTempFile(vmsSwapFileDir);\n    try\n      vmsSwapStream := TFileStream.Create(vmsSwapFileName, fmCreate);\n    except\n      DeleteFile(vmsSwapFileName);\n      raise EAbVMSErrorOpenSwap.Create( vmsSwapFileName );\n    end;\n    vmsSwapFileSize := 0;\n  end;\nend;\n{--------}\nprocedure TAbVirtualMemoryStream.vmsSwapFileDestroy;\nbegin\n  if (vmsSwapStream <> nil) then begin\n    FreeAndNil(vmsSwapStream);\n    DeleteFile(vmsSwapFileName);\n  end;\nend;\n{--------}\nprocedure TAbVirtualMemoryStream.vmsSwapFileRead(aPage : PvmsPage);\nvar\n  BytesRead : Longint;\n  SeekResult: Int64;\nbegin\n  if (vmsSwapStream = nil) or (aPage^.vpStmOfs >= vmsSwapFileSize) then begin\n    {there is nothing to be read from the disk (either the swap file\n     doesn't exist or it's too small) so zero out the page data}\n    FillChar(aPage^.vpData, AB_VMSPageSize, 0)\n  end\n  else {there is something to be read from the swap file} begin\n    SeekResult := vmsSwapStream.Seek(aPage^.vpStmOfs, soBeginning);\n    if (SeekResult = -1) then\n      raise EAbVMSSeekFail.Create( vmsSwapFileName );\n    BytesRead := vmsSwapStream.Read(aPage^.vpData, AB_VMSPageSize);\n    if (BytesRead <> AB_VMSPageSize) then\n      raise EAbVMSReadFail.Create( AB_VMSPageSize, vmsSwapFileName );\n  end;\nend;\n{--------}\nprocedure TAbVirtualMemoryStream.vmsSwapFileWrite(aPage : PvmsPage);\nvar\n  NewPos : Int64;\n  SeekResult: Int64;\n  BytesWritten : Longint;\nbegin\n  if (vmsSwapStream = nil) then\n    vmsSwapFileCreate;\n  SeekResult := vmsSwapStream.Seek(aPage^.vpStmOfs, soBeginning);\n  if (SeekResult = -1) then\n    raise EAbVMSSeekFail.Create( vmsSwapFileName );\n  BytesWritten := vmsSwapStream.Write(aPage^.vpData, AB_VMSPageSize);\n  if BytesWritten <> AB_VMSPageSize then\n    raise EAbVMSWriteFail.Create( AB_VMSPageSize, vmsSwapFileName );   \n  NewPos := aPage^.vpStmOfs + AB_VMSPageSize;\n  if (NewPos > vmsSwapFileSize) then\n    vmsSwapFileSize := NewPos;\nend;\n{--------}\nfunction TAbVirtualMemoryStream.Write(const Buffer; Count : Longint) : Longint;\nvar\n  BufPtr      : PByte;\n  Page        : PvmsPage;\n  PageDataInx : integer;\n  Posn        : Int64;\n  BytesToGo   : Int64;\n  BytesToWrite: Int64;\n  StartOfs    : Int64;\nbegin\n  {writing is complicated by the fact we can only write in chunks of\n   AB_VMSPageSize: we need to partition out the overall write into a\n   write to a partial page, zero or more writes to complete pages and\n   then a possible write to a partial page}\n\n  {initialise some variables, note that the complex calc in the\n   expression for PageDataInx is the offset of the start of the page\n   where Posn is found.}\n  BufPtr := @Buffer;\n  Posn := vmsPosition;\n  PageDataInx := Posn - (Posn and (not pred(AB_VMSPageSize)));\n  BytesToWrite := AB_VMSPageSize - PageDataInx;\n  {calculate the actual number of bytes to write}\n  BytesToGo := Count;\n  Result := BytesToGo;\n\n  {while we have bytes to write, write them}\n  while (BytesToGo <> 0) do begin\n    if (BytesToWrite > BytesToGo) then\n      BytesToWrite := BytesToGo;\n    StartOfs := Posn and (not pred(AB_VMSPageSize));\n    if (vmsCachePage^.vpStmOfs = StartOfs) then\n      Page := vmsCachePage\n    else\n      Page := vmsGetPageForOffset(StartOfs);\n    Move(BufPtr^, Page^.vpData[PageDataInx], BytesToWrite);\n    Page^.vpDirty := True;\n    dec(BytesToGo, BytesToWrite);\n    inc(Posn, BytesToWrite);\n    inc(BufPtr, BytesToWrite);\n    PageDataInx := 0;\n    BytesToWrite := AB_VMSPageSize;\n  end;\n  {remember our new position}\n  vmsPosition := Posn;\n  {if we've grown the stream, make a note of it}\n  if (vmsPosition > vmsSize) then\n    vmsSize := vmsPosition;\nend;\n{====================================================================}\n\nend.\n"
  },
  {
    "path": "lib/abbrevia/source/AbView.pas",
    "content": "(* ***** BEGIN LICENSE BLOCK *****\n * Version: MPL 1.1\n *\n * The contents of this file are subject to the Mozilla Public License Version\n * 1.1 (the \"License\"); you may not use this file except in compliance with\n * the License. You may obtain a copy of the License at\n * http://www.mozilla.org/MPL/\n *\n * Software distributed under the License is distributed on an \"AS IS\" basis,\n * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License\n * for the specific language governing rights and limitations under the\n * License.\n *\n * The Original Code is TurboPower Abbrevia\n *\n * The Initial Developer of the Original Code is\n * TurboPower Software\n *\n * Portions created by the Initial Developer are Copyright (C) 1997-2002\n * the Initial Developer. All Rights Reserved.\n *\n * Contributor(s):\n *\n * ***** END LICENSE BLOCK ***** *)\n\n{*********************************************************}\n{* ABBREVIA: AbView.pas                                  *}\n{*********************************************************}\n{* ABBREVIA: Base archive viewer component               *}\n{*   Use AbQView.pas for CLX                             *}\n{*********************************************************}\n\n{$IFNDEF UsingCLX}\nunit AbView;\n{$ENDIF}\n\n{$I AbDefine.inc}\n\ninterface\n\nuses\n  Classes,\n  Types,\n{$IFDEF MSWINDOWS}\n  Windows,\n  Messages,\n{$ENDIF}\n{$IFDEF LibcAPI}\n  Libc,\n{$ENDIF}\n{$IFDEF UsingCLX }\n  Qt,\n  QControls,\n  QGraphics,\n  QGrids,\n{$ELSE}\n  Controls,\n  Graphics,\n  Grids,\n{$ENDIF}\n  AbArcTyp;\n\ntype\n  TAbViewAttribute =\n    (vaItemName, vaPacked, vaMethod, vaRatio, vaCRC,\n     vaFileAttributes, vaFileType, vaEncryption, vaTimeStamp,\n     vaFileSize, vaVersionMade, vaVersionNeeded, vaPath);\n  TAbViewAttributes = set of TAbViewAttribute;\n\n  TAbDisplayOption =\n    (doAlternateColors, doColLines, doColMove, doColSizing, doMultiSelect,\n     doRowLines, doShowIcons, doThumbTrack, doTrackActiveRow);\n  TAbDisplayOptions = set of TAbDisplayOption;\n\n  TAbSortAttribute =\n    (saItemName, saPacked,  saPath, saRatio, saTimeStamp, saFileSize);\n  TAbSortAttributes = set of TAbSortAttribute;\n\nconst\n  AbDefColWidth = 150;\n  AbDefRowHeight = 24;\n  AbHeaderRow = 0;\n  AbDefSelColor = clHighlight;\n  AbDefSelTextColor = clHighlightText;\n  AbDefHighColor = clAqua;\n  AbDefHighTextColor = clRed;\n  AbDefDelColor = clYellow;\n  AbDefDelTextColor = clNavy;\n\n\n{ ===== TAbColors ========================================================== }\ntype\n  TAbColors = class(TPersistent)\n  protected {private}\n    FSelected : TColor;\n    FSelectedText : TColor;\n    FAlternate : TColor;\n    FAlternateText : TColor;\n    FDeleted : TColor;\n    FDeletedText : TColor;\n    FUpdating  : Boolean;\n    FOnChange  : TNotifyEvent;\n    procedure DoOnChange;\n    procedure SetSelected(Value : TColor);\n    procedure SetSelectedText(Value : TColor);\n    procedure SetAlternate(Value : TColor);\n    procedure SetAlternateText(Value : TColor);\n    procedure SetDeleted(Value : TColor);\n    procedure SetDeletedText(Value : TColor);\n  public\n    procedure BeginUpdate;\n    procedure EndUpdate;\n    property OnChange : TNotifyEvent\n      read FOnChange\n      write FOnChange;\n  published\n    property Selected : TColor\n      read FSelected\n      write SetSelected;\n    property SelectedText : TColor\n      read FSelectedText\n      write SetSelectedText;\n    property Alternate : TColor\n      read FAlternate\n      write SetAlternate;\n    property AlternateText : TColor\n      read FAlternateText\n      write SetAlternateText;\n    property Deleted : TColor\n      read FDeleted\n      write SetDeleted;\n    property DeletedText : TColor\n      read FDeletedText\n      write SetDeletedText;\n  end;\n\n\n{ ===== TAbSelList ========================================================= }\ntype\n  TAbSelList = class\n  protected {private}\n    FList  : TList;\n    FCurrent : Longint;\n  public {methods}\n    constructor Create;\n    destructor Destroy;\n      override;\n    procedure Clear;\n    procedure Deselect(Index : Longint);\n    function IsSelected(Index : Longint) : Boolean;\n    procedure Select(Index : Longint);\n    procedure SelectAll(Count : Longint);\n    function SelCount : Longint;\n    procedure Toggle(Index : Longint);\n    function FindFirst : Longint;\n    function FindNext : Longint;\n  end;\n\n\n{ ===== TAbRowMap ========================================================== }\ntype\n  TAbRowMap = class\n  protected {private}\n    FRows : TList;\n    FInvRows : TList;\n    FSortAscending : Boolean;\n    function GetRow(RowNum : Longint) : Longint;\n    function GetInvRow(RowNum : Longint) : Longint;\n    procedure SortOnItemName(ItemList : TAbArchiveList);\n    procedure SortOnItemDir(ItemList : TAbArchiveList);\n  public {methods}\n    constructor Create;\n    destructor Destroy;\n      override;\n    procedure Clear;\n    procedure Init(RowCount : Longint);\n    procedure SortBy(Attr : TAbSortAttribute; ItemList : TAbArchiveList);\n  public {properties}\n    property Rows[RowNum : Longint] : Longint\n      read GetRow; default;\n    property InvRows[RowNum : Longint] : Longint\n      read GetInvRow;\n    property SortAscending : Boolean\n      read FSortAscending;\n  end;\n\n\n{ ===== TAbBaseViewer ==================================================== }\ntype\n  TAbColHeadings = class(TStringList)\n    end;\n  TAbSortedEvent =\n    procedure (Sender : TObject; Attr : TAbViewAttribute) of object;\n  TAbDrawSortArrowEvent =\n    procedure (Sender : TObject; Column : Integer; Ascending: Boolean;\n      Cnv: TCanvas; Rect : TRect) of object;\n\n  TAbBaseViewer = class(TCustomGrid)\n  protected {private}\n    FAllowInvalidate : Boolean;\n    FAttributes : TAbViewAttributes;\n    FDisplayOptions : TAbDisplayOptions;\n    FSortAttributes : TAbSortAttributes;\n    FColMap : array[TAbViewAttribute] of Integer;\n    FColSizing : Boolean;\n    FColMoving : Boolean;\n    FHeadings : TAbColHeadings;\n    FItemList : TAbArchiveList;\n    FRowMap : TAbRowMap;\n    FFileName : string;\n    FFontSize : Integer;\n    FItemIndex : Longint;\n    FColors : TAbColors;\n    FButtonDown : Boolean;\n    FIcons : TStringList;\n    FSelList : TAbSelList;\n    FMultiSelecting : Boolean;\n    FShiftState : TShiftState;\n    FSortCol : Integer;\n    RowAnchor : Longint;\n    ViewMouseCoord : TGridCoord;\n\n    FOnChange : TNotifyEvent;\n    FOnClick : TNotifyEvent;\n    FOnDblClick : TNotifyEvent;\n    FOnSorted : TAbSortedEvent;\n    FOnDrawSortArrow : TAbDrawSortArrowEvent;\n\n    function AttrToSortAttribute(Attr : TAbViewAttribute;\n      var SortAttr : TAbSortAttribute) : Boolean;\n    function AttrToStr(Attr : TAbViewAttribute; aItem : TAbArchiveItem) : string;\n    function ColMap(ColNum : Integer) : Integer;\n    procedure ColorsChange(Sender : TObject);\n    procedure DrawHeaderButton(ACol : Integer; const AText : string);\n    procedure DrawSortArrow;\n    function DrawTextFormat(Attr : TAbViewAttribute; var Rect : TRect) : Word;\n    function GetCount : Longint;\n    function GetActiveRow : Longint;\n    function GetHeaderRowHeight : Integer;\n{$IFDEF MSWINDOWS}\n    function GetIcon(const ItemName : string) : HIcon;\n{$ENDIF}\n{$IFDEF UsingClx}\n  { no file type icons in Clx }\n{$ENDIF}\n    function GetSelCount : Longint;\n    function GetSelected(RowNum : Longint) : Boolean;\n    function GetVersion : string;\n    procedure InitColMap;\n    procedure InvalidateRow(ARow: Longint);\n    procedure MoveColumn(FromCol, ToCol : Integer);\n    procedure RefreshCell(ARow, ACol: Longint);\n    procedure RefreshRow(ARow: Longint);\n    procedure SetActiveRow(RowNum : Longint);\n    procedure SetAttributes(Value : TAbViewAttributes);\n    procedure SetDisplayOptions(Value : TAbDisplayOptions);\n    procedure SetSortAttributes(Value : TAbSortAttributes);\n    procedure SetHeaderRowHeight(Value : Integer);\n    procedure SetHeadings(Value: TAbColHeadings);\n    procedure SetSelected(RowNum : Longint; Value : Boolean);\n    procedure SetVersion(const Value : string);\n    function UpdateColCount(Attributes : TAbViewAttributes) : Integer;\n{$IFDEF UsingCLX}\n    procedure FontChanged; override;\n    procedure SizeChanged(OldColCount, OldRowCount: Longint); override;\n{$ELSE}\n    procedure WMSize(var Msg: TWMSize);\n      message WM_SIZE;\n    procedure WMEraseBkgnd(var Msg: TWMEraseBkgnd);\n      message WM_ERASEBKGND;\n    procedure CMFontChanged(var Message: TMessage);\n      message CM_FONTCHANGED;\n{$ENDIF UsingCLX}\n\n  protected {overridden methods}\n    procedure Click;\n      override;\n    procedure DblClick;\n      override;\n    procedure KeyDown(var Key: Word; Shift: TShiftState);\n      override;\n    procedure KeyUp(var Key: Word; Shift: TShiftState);\n      override;\n    procedure Loaded;\n      override;\n    procedure MouseDown(Button: TMouseButton; Shift: TShiftState; X, Y : Integer);\n      override;\n    procedure MouseUp(Button: TMouseButton; Shift: TShiftState; X, Y: Integer);\n      override;\n    procedure MouseMove(Shift: TShiftState; X, Y: Integer);\n      override;\n    procedure ColumnMoved(FromIndex, ToIndex: Longint);\n      override;\n{$IFDEF HasGridDrawingStyle}\n    procedure Paint;\n      override;\n{$ENDIF}\n    procedure DrawCell(ACol, ARow: Longint; ARect: TRect; AState: TGridDrawState);\n      override;\n    procedure TopLeftChanged;\n      override;\n\n  protected {virtual methods}\n    procedure DoChange(Sender : TObject);\n      virtual;\n    procedure DoLoad(Sender : TObject);\n      virtual;\n    procedure DoSorted(Attr : TAbViewAttribute);\n      virtual;\n\n  protected {properties}\n    property Attributes : TAbViewAttributes\n      read FAttributes\n      write SetAttributes;\n    property DisplayOptions : TAbDisplayOptions\n      read FDisplayOptions\n      write SetDisplayOptions;\n    property HeaderRowHeight : Integer\n      read GetHeaderRowHeight\n      write SetHeaderRowHeight;\n    property Headings : TAbColHeadings\n      read FHeadings\n      write SetHeadings;\n    property ItemList : TAbArchiveList\n      read FItemList\n      write FItemList;\n    property SortAttributes : TAbSortAttributes\n      read FSortAttributes\n      write SetSortAttributes;\n    property Version : string\n      read GetVersion\n      write SetVersion\n      stored False;\n\n  protected {events}\n    property OnChange : TNotifyEvent\n      read FOnChange\n      write FOnChange;\n    property OnClick : TNotifyEvent\n      read FOnClick\n      write FOnClick;\n    property OnDblClick : TNotifyEvent\n      read FOnDblClick\n      write FOnDblClick;\n    property OnSorted :  TAbSortedEvent\n      read FOnSorted\n      write FOnSorted;\n    property OnDrawSortArrow : TAbDrawSortArrowEvent\n      read FOnDrawSortArrow\n      write FOnDrawSortArrow;\n\n  public {methods}\n    constructor Create(AOwner : TComponent);\n      override;\n    destructor  Destroy;\n      override;\n    procedure BeginUpdate;\n    procedure EndUpdate;\n    procedure ClearSelections;\n    procedure SelectAll;\n\n  public {run-time properties}\n    property ActiveRow : Longint\n      read GetActiveRow  write SetActiveRow;\n    property Colors : TAbColors\n      read FColors write FColors;\n    property Count : Longint\n      read GetCount;\n    property SelCount : Longint\n      read GetSelCount;\n    property Selected[RowNum : Longint] : Boolean\n      read GetSelected write SetSelected;\n\n    property ColWidths;\n    property RowHeights;\n  published\n    property OnDragDrop;\n    property OnDragOver;\n  end;\n\n\nimplementation\n\nuses\n{$IFDEF MSWINDOWS}\n  ShellApi,\n{$ENDIF}\n{$IFDEF HasUITypes}\n  UITypes,\n{$ENDIF}\n  SysUtils,\n  AbUtils,\n  AbConst,\n  AbResString,\n  AbZipTyp;\n\n{ ===== TAbColors ========================================================== }\nprocedure TAbColors.BeginUpdate;\nbegin\n  FUpdating := True;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbColors.EndUpdate;\nbegin\n  FUpdating := False;\n  DoOnChange;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbColors.DoOnChange;\nbegin\n  if not FUpdating and Assigned(FOnChange) then\n    FOnChange(Self);\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbColors.SetSelected(Value : TColor);\nbegin\n  if (Value <> FSelected) then begin\n    FSelected := Value;\n    DoOnChange;\n  end;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbColors.SetSelectedText(Value : TColor);\nbegin\n  if (Value <> FSelectedText) then begin\n    FSelectedText := Value;\n    DoOnChange;\n  end;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbColors.SetAlternate(Value : TColor);\nbegin\n  if (Value <> FAlternate) then begin\n    FAlternate := Value;\n    DoOnChange;\n  end;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbColors.SetAlternateText(Value : TColor);\nbegin\n  if (Value <> FAlternateText) then begin\n    FAlternateText := Value;\n    DoOnChange;\n  end;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbColors.SetDeleted(Value : TColor);\nbegin\n  if (Value <> FDeleted) then begin\n    FDeleted := Value;\n    DoOnChange;\n  end;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbColors.SetDeletedText(Value : TColor);\nbegin\n  if (Value <> FDeletedText) then begin\n    FDeletedText := Value;\n    DoOnChange;\n  end;\nend;\n\n\n{ ===== TAbSelList ========================================================= }\nconstructor TAbSelList.Create;\nbegin\n  FList := TList.Create;\n  FCurrent := -1;\nend;\n{ -------------------------------------------------------------------------- }\ndestructor TAbSelList.Destroy;\nbegin\n  FList.Free;\n  inherited Destroy;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbSelList.Clear;\nbegin\n  FList.Clear;\n  FCurrent := -1;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbSelList.Select(Index: Longint);\nbegin\n  if FList.IndexOf(Pointer(Index)) < 0 then\n    FList.Add(Pointer(Index));\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbSelList.Deselect(Index: Longint);\nvar\n  i : Longint;\nbegin\n  i := FList.IndexOf(Pointer(Index));\n  if (i >= 0) then\n    FList.Delete(i);\nend;\n{ -------------------------------------------------------------------------- }\nfunction TAbSelList.IsSelected(Index : Longint) : Boolean;\nbegin\n  Result := FList.IndexOf(Pointer(Index)) >= 0;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbSelList.Toggle(Index: Longint);\nbegin\n  if IsSelected(Index) then\n    Deselect(Index)\n  else\n    Select(Index);\nend;\n{ -------------------------------------------------------------------------- }\nfunction TAbSelList.SelCount : Longint;\nbegin\n  Result := FList.Count;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbSelList.SelectAll(Count : Longint);\nvar\n  i : Longint;\nbegin\n  for i := 0 to Pred(Count) do\n    Select(i);\nend;\n{ -------------------------------------------------------------------------- }\nfunction TAbSelList.FindFirst : Longint;\nbegin\n  FCurrent := -1;\n  if (FList.Count > 0) then\n    Result := FindNext\n  else\n    Result := -1;\nend;\n{ -------------------------------------------------------------------------- }\nfunction TAbSelList.FindNext : Longint;\nbegin\n  if (FList.Count > 0) and (FCurrent < Pred(FList.Count)) then begin\n    Inc(FCurrent);\n    Result := Longint(FList[FCurrent]);\n  end else\n    Result := -1;\nend;\n\n\n{ ===== TAbRowMap ========================================================== }\nprocedure TAbRowMap.Clear;\nbegin\n  FRows.Clear;\n  FInvRows.Clear;\nend;\n{ -------------------------------------------------------------------------- }\nfunction TAbRowMap.GetRow(RowNum : Longint) : Longint;\nbegin\n  if (RowNum >= 0) and (RowNum < FRows.Count) then\n    Result := Longint(FRows[RowNum])\n  else\n    Result := 0;\nend;\n{ -------------------------------------------------------------------------- }\nfunction TAbRowMap.GetInvRow(RowNum : Longint) : Longint;\nbegin\n  if (RowNum >= 0) and (RowNum < FInvRows.Count) then\n    Result := Longint(FInvRows[RowNum])\n  else\n    Result := 0;\nend;\n{ -------------------------------------------------------------------------- }\nconstructor TAbRowMap.Create;\nbegin\n  inherited Create;\n  FRows := TList.Create;\n  FInvRows := TList.Create;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbRowMap.Init(RowCount : Longint);\nvar\n  i : Longint;\nbegin\n  Clear;\n  if (RowCount > 0) then\n    for i := 0 to Pred(RowCount) do begin\n      FRows.Add(Pointer(i));\n      FInvRows.Add(Pointer(i));\n    end;\nend;\n{ -------------------------------------------------------------------------- }\ndestructor TAbRowMap.Destroy;\nbegin\n  FRows.Free;\n  FInvRows.Free;\n  inherited Destroy;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbRowMap.SortBy(Attr : TAbSortAttribute; ItemList : TAbArchiveList);\ntype\n  PSortRec = ^TSortRec;\n  TSortRec = record\n    Val : Double;\n    Index : Longint;\n  end;\nvar\n  i, LI : Longint;\n  SL : TList;\n  RowCount : Longint;\n  P : PSortRec;\n  DT : TDateTime;\n  aItem : TAbArchiveItem;\n\n  procedure QuickSort(SL : TList; L, R: Integer);\n  var\n    i, j: Integer;\n    P: PSortRec;\n  begin\n    i := L;\n    j := R;\n    P := SL[(L + R) shr 1];\n    repeat\n      while PSortRec(SL[i])^.Val < P^.Val do Inc(i);\n      while PSortRec(SL[j])^.Val > P^.Val do Dec(j);\n      if (i <= j) then\n      begin\n        SL.Exchange(i, j);\n        Inc(i);\n        Dec(j);\n      end;\n    until i > j;\n    if L < j then QuickSort(SL, L, j);\n    if i < R then QuickSort(SL, i, R);\n  end;\n\nbegin\n  if (ItemList.Count <= 0) then\n    Exit;\n  case Attr of\n    saItemName : SortOnItemName(ItemList);\n    saPath : SortOnItemDir(ItemList);\n    else begin\n      RowCount := ItemList.Count;\n      SL := TList.Create;\n      try {SL}\n        SL.Capacity := RowCount;\n        for i := 0 to Pred(RowCount) do begin\n          GetMem(P, SizeOf(TSortRec));\n          aItem := TAbArchiveItem(ItemList.Items[i]);\n          case Attr of\n            saPacked   : P^.Val := aItem.CompressedSize;\n            saRatio :\n              begin\n                if (aItem is TAbZipItem) then\n                  P^.Val := TAbZipItem(aItem).CompressionRatio\n                else\n                  P^.Val := 0;\n              end;\n            saFileSize : P^.Val := aItem.UnCompressedSize;\n            saTimeStamp : begin\n              LI := LongInt(aItem.LastModFileDate) shl 16 +\n                aItem.LastModFileTime;\n              DT := FileDateToDateTime(LI);\n              P^.Val := Double(DT);\n             end;\n          end;\n          P^.Index := i;\n          SL.Add(P);\n        end;\n        QuickSort(SL, 0, Pred(SL.Count));\n        for i := 0 to Pred(SL.Count) do begin\n          if FSortAscending then\n            P := SL[i]\n          else\n            P := SL[Pred(SL.Count) - i];\n          FRows[i] := Pointer(P^.Index)\n        end;\n      finally {SL}\n        while (SL.Count > 0) do begin\n          FreeMem(SL[0], Sizeof(TSortRec));\n          SL.Delete(0);\n        end;\n        SL.Free;\n      end; {SL}\n    end;\n  end;\n\n  FSortAscending := not FSortAscending;\n  for i := 0 to Pred(ItemList.Count) do\n    FInvRows[Rows[i]] := Pointer(i);\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbRowMap.SortOnItemName(ItemList : TAbArchiveList);\nvar\n  i, RowCount : Longint;\n  SL : TStringList;\n  FN : string;\nbegin\n  RowCount := ItemList.Count;\n  SL := TStringList.Create;\n  try {SL}\n    for i := 0 to Pred(RowCount) do begin\n      FN := TAbArchiveItem(ItemList.Items[i]).Filename;\n      AbUnFixName(FN);\n      SL.AddObject(ExtractFilename(FN), Pointer(i));\n    end;\n    SL.Sort;\n    for i := 0 to Pred(RowCount) do begin\n      if FSortAscending then\n        FRows[i] := SL.Objects[i]\n      else\n        FRows[i] := SL.Objects[Pred(RowCount) - i];\n    end;\n  finally {SL}\n    SL.Free;\n  end; {SL}\nend;\n\n{ -------------------------------------------------------------------------- }\nprocedure TAbRowMap.SortOnItemDir(ItemList : TAbArchiveList);\nvar\n  i, RowCount : Longint;\n  SL : TStringList;\n  FN : string;\nbegin\n  RowCount := ItemList.Count;\n  SL := TStringList.Create;\n  try {SL}\n    for i := 0 to Pred(RowCount) do begin\n      FN := TAbArchiveItem(ItemList.Items[i]).DiskPath;\n      AbUnFixName(FN);\n      SL.AddObject(ExtractFilePath(FN), Pointer(i));\n    end;\n    SL.Sort;\n    for i := 0 to Pred(RowCount) do begin\n      if FSortAscending then\n        FRows[i] := SL.Objects[i]\n      else\n        FRows[i] := SL.Objects[Pred(RowCount) - i];\n    end;\n  finally {SL}\n    SL.Free;\n  end; {SL}\nend;\n\n{===== TAbBaseViewer ===============================================}\nconstructor TAbBaseViewer.Create(AOwner : TComponent);\nbegin\n  inherited Create(AOwner);\n\n  FItemList := TAbArchiveList.Create(False);\n\n  RowCount := 2;\n  FixedCols := 0;\n  FixedRows := 1;   {Header Row}\n  FSortCol := -1;\n  Color := clWindow;\n  FColors := TAbColors.Create;\n  FColors.OnChange := ColorsChange;\n  FColors.Selected := AbDefSelColor;\n  FColors.SelectedText := AbDefSelTextColor;\n  FColors.Alternate := AbDefHighColor;\n  FColors.AlternateText := AbDefHighTextColor;\n  FColors.Deleted := AbDefDelColor;\n  FColors.DeletedText := AbDefDelTextColor;\n  DefaultColWidth := AbDefColWidth;\n  DefaultRowHeight := AbDefRowHeight;\n  DefaultDrawing := False;\n  ParentColor := False;\n{$IFNDEF UsingCLX}\n  ParentCtl3D := True;\n{$ENDIF}\n  ParentFont := True;\n  ParentShowHint := True;\n  FHeadings := TAbColHeadings.Create;\n  InitColMap;\n  FColSizing := False;\n  FColMoving := False;\n  FAllowInvalidate := True;\n  FRowMap := TAbRowMap.Create;\n  FIcons := TStringList.Create;\n  FSelList := TAbSelList.Create;\n  Attributes :=  [vaItemname, vaPacked, vaTimeStamp, vaFileSize, vaPath];\n  SetDisplayOptions([doColSizing]);\n  Visible := True;\nend;\n{ -------------------------------------------------------------------------- }\ndestructor TAbBaseViewer.Destroy;\nbegin\n  FRowMap.Free;\n  FHeadings.Free;\n  FColors.Free;\n  FIcons.Free;\n  FSelList.Free;\n  FItemList.Free;\n  inherited Destroy;\nend;\n{ -------------------------------------------------------------------------- }\nfunction TAbBaseViewer.AttrToSortAttribute(Attr : TAbViewAttribute;\n  var SortAttr : TAbSortAttribute) : Boolean;\nbegin\n  Result := True;\n  case Attr of\n    vaItemName  : SortAttr := saItemName;\n    vaPacked    : SortAttr := saPacked;\n    vaFileSize  : SortAttr := saFileSize;\n    vaRatio     : SortAttr := saRatio;\n    vaTimeStamp : SortAttr := saTimeStamp;\n    vaPath      : SortAttr := saPath;\n  else\n    Result := False;\n  end;\nend;\n{ -------------------------------------------------------------------------- }\nfunction TAbBaseViewer.AttrToStr(Attr : TAbViewAttribute;\n  aItem : TAbArchiveItem) : string;\nvar\n  FN : string;\n  LI : Longint;\nbegin\n  Result := '';\n  if Attr in [vaItemName, vaPath] then begin\n    FN := aItem.Filename;\n    AbUnFixName(FN);\n  end;\n\n  {first take care of common attributes}\n  with aItem do case Attr of\n    vaCRC :\n      Result := IntToHex(CRC32, 8);\n    vaItemname :\n      Result := ExtractFilename(FN);\n    vaPacked :\n      Result := IntToStr(CompressedSize);\n    vaFileSize :\n      Result := IntToStr(UncompressedSize);\n    vaFileAttributes :\n      begin\n{$IFDEF MSWINDOWS}\n{$WARN SYMBOL_PLATFORM OFF}\n        if (faReadOnly and ExternalFileAttributes) = faReadOnly then\n          Result := Result + AbReadOnlyS;\n        if (faHidden and ExternalFileAttributes) = faHidden then\n          Result := Result + AbHiddenS;\n        if (faSysFile and ExternalFileAttributes) = faSysFile then\n          Result := Result + AbSystemS;\n        if (faArchive and ExternalFileAttributes) = faArchive then\n          Result := Result + AbArchivedS;\n{$WARN SYMBOL_PLATFORM OFF}\n{$ENDIF MSWINDOWS}\n      end;\n    vaEncryption :\n      if IsEncrypted then\n        Result := AbEncryptedS;\n    vaTimeStamp :\n      if (LastModFileDate + LastModFileTime = 0) then\n        Result := AbUnknownS\n      else begin\n        LI := LongInt(LastModFileDate) shl 16 + LastModFileTime;\n        Result := DateTimeToStr(FileDateToDateTime(LI));\n      end;\n    vaPath :\n      Result := DiskPath;\n  end;\n\n  {now handle the zip specific attributes}\n  if (aItem is TAbZipItem) then with TAbZipItem(aItem) do case Attr of\n    vaFileType :\n      if (InternalFileAttributes = 1) then\n        Result := AbTextS\n      else\n        Result := AbBinaryS;\n    vaMethod :\n      Result := ZipCompressionMethodToString(CompressionMethod);\n    vaRatio :\n      Result := IntToStr(Round(CompressionRatio));\n    vaVersionMade :\n      Result := IntToStr(Round(Lo(VersionMadeBy)/ 10.0));\n    vaVersionNeeded :\n      Result := IntToStr(Round(Lo(VersionNeededToExtract)/ 10.0));\n  end;\n{$IFDEF LINUX}\n  Result := ' ' + Result;\n{$ENDIF}\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbBaseViewer.BeginUpdate;\nbegin\n  FAllowInvalidate := False;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbBaseViewer.EndUpdate;\nbegin\n  FAllowInvalidate := True;\n  Refresh;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbBaseViewer.ClearSelections;\nvar\n  i : Longint;\nbegin\n  if (FSelList.SelCount > 0) then begin\n    i := FSelList.FindFirst;\n    repeat\n      InvalidateRow(FRowMap.InvRows[i]+1);\n      i := FSelList.FindNext;\n    until (i < 0);\n    FSelList.Clear;\n  end;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbBaseViewer.Click;\n  {Here is the logic for MultiSelect}\nvar\n  i : Longint;\nbegin\n  inherited Click;\n  if Assigned(FItemList) and (FItemList.Count > 0) then begin\n    if (ssCtrl in FShiftState) and (doMultiSelect in FDisplayOptions) then\n      Selected[ActiveRow] := not Selected[ActiveRow]\n    else begin\n      if not ((ssShift in FShiftState) and\n             (doMultiSelect in FDisplayOptions)) then begin\n        ClearSelections;\n        Selected[ActiveRow] := True;\n      end else begin\n        ClearSelections;\n        if (RowAnchor < ActiveRow) then\n          for i := RowAnchor to ActiveRow do\n            Selected[i] := True\n        else\n          for i := ActiveRow to RowAnchor do\n            Selected[i] := True;\n      end;\n    end;\n    Update;\n    if Assigned(FOnClick) then\n      FOnClick(Self);\n  end;\nend;\n{ -------------------------------------------------------------------------- }\n{$IFDEF UsingCLX}\nprocedure TAbBaseViewer.FontChanged;\n{$ELSE}\nprocedure TAbBaseViewer.CMFontChanged(var Message: TMessage);\n{$ENDIF}\nbegin\n  inherited;\n  if not (csLoading in ComponentState) then begin\n    Canvas.Font := Font;\n    DefaultRowHeight := Canvas.TextHeight('W') + 2;\n    HeaderRowHeight := Canvas.TextHeight('W') + 4;\n  end;\nend;\n{ -------------------------------------------------------------------------- }\nfunction TAbBaseViewer.ColMap(ColNum : Integer) : Integer;\nbegin\n  Result := FColMap[TAbViewAttribute(ColNum)];\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbBaseViewer.ColorsChange(Sender : TObject);\nbegin\n  Invalidate;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbBaseViewer.ColumnMoved(FromIndex, ToIndex : Longint);\nbegin\n  MoveColumn(FromIndex, ToIndex);\n  Invalidate;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbBaseViewer.DblClick;\n  {Dont pass along the event if double click in header}\nbegin\n  inherited DblClick;\n  if (ViewMouseCoord.Y <> abHeaderRow) then\n    if Assigned(FItemList) and (FItemList.Count > 0) then\n      if Assigned(FOnDblClick) then\n        FOnDblClick(Self);\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbBaseViewer.DoChange;\nbegin\n  RowCount := 2;   {HeaderRow + 1}\n  FSelList.Clear;\n  if Assigned(FItemList) then begin\n    FRowMap.Init(FItemList.Count);\n    if (FItemList.Count > 0) then\n      RowCount := FItemList.Count + 1\n    else begin\n{      RefreshRow(1);}\n      FSortCol := -1;\n    end;\n  end;\n  if FAllowInvalidate then\n    Refresh;\n  if Assigned(FOnChange) then\n    FOnChange(Self);\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbBaseViewer.DoLoad;\nbegin\n  FIcons.Clear;\n  FSelList.Clear;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbBaseViewer.DoSorted(Attr : TAbViewAttribute);\nbegin\n  DrawSortArrow;\n  if Assigned(FOnSorted) then\n    FOnSorted(Self, Attr);\nend;\n{ -------------------------------------------------------------------------- }\n{$IFDEF HasGridDrawingStyle}\nprocedure TAbBaseViewer.Paint;\nbegin\n  DefaultDrawing := FInternalDrawingStyle <> gdsClassic;\n  inherited;\nend;\n{$ENDIF}\n{ -------------------------------------------------------------------------- }\nprocedure TAbBaseViewer.DrawCell(ACol, ARow: Longint; ARect: TRect;\n  AState: TGridDrawState);\nvar\n  s : string;\n  aItem : TAbArchiveItem;\n  TxtRect : TRect;\n  Attr : TAbViewAttribute;\n  DTFormat : Word;\n{$IFNDEF UsingClx}\n  H : Integer;\n  Icon : HIcon;\n{$ENDIF}\nbegin\n{$IFDEF LINUX}\n  if not DefaultDrawing then\n    DefaultDrawing := true;\n{$ENDIF}\n\n  Canvas.Font := Font;\n  if (ARow = AbHeaderRow) then begin\n    DrawHeaderButton(ACol, FHeadings[ColMap(ACol)])\n  end else if not FAllowInvalidate then  {waiting for EndUpdate}\n    Exit\n  else with Canvas do begin\n    if not (doColLines in DisplayOptions) then\n      ARect.Right := ARect.Right + 1;\n    Brush.Color := clWindow;\n    if (not Assigned(FItemList)) or (FItemList.Count = 0) then begin\n      if not DefaultDrawing then Canvas.FillRect(ARect);\n      Exit;\n    end;\n\n    aItem := FItemList.Items[FRowMap[ARow-1]];\n    Attr := TAbViewAttribute(ColMap(ACol));\n    S := AttrToStr(Attr, aItem);\n    if (gdSelected in AState) or FSelList.IsSelected(FRowMap[ARow-1]) then begin\n      if not DefaultDrawing then begin\n        Brush.Color := FColors.Selected;\n        Font.Color  := FColors.SelectedText;\n      end\n{$IFDEF HasGridDrawingStyle}\n      else begin\n        if DrawingStyle = gdsGradient then\n          Canvas.Font.Color := clHighlightText;\n        if not (gdSelected in AState) then begin\n          if (goRowSelect in Options) then\n            Include(AState, gdRowSelected);\n          DrawCellHighlight(ARect, AState, ACol, ARow);\n        end;\n      end;\n{$ENDIF}\n    end else if aItem.Action = aaDelete then begin\n      Brush.Color := FColors.Deleted;\n      Font.Color  := FColors.DeletedText;\n    end else if ((doAlternateColors in FDisplayOptions) and\n    not Odd(ARow)) then begin\n      Brush.Color := FColors.Alternate;\n      Font.Color  := FColors.AlternateText;\n    end;\n    if not DefaultDrawing then\n      Canvas.FillRect(ARect);\n    Canvas.Brush.Style := bsClear;\n    TxtRect := ARect;\n{$IFNDEF UsingCLX}\n    Icon := 0;\n    if (Attr = vaItemName) then\n      Icon := GetIcon(aItem.Filename);\n    if (Icon <> 0) then begin\n      H := ARect.Bottom - ARect.Top;\n      DrawIconEx(Canvas.Handle, ARect.Left+1, ARect.Top+1, Icon,\n        H - 2, H - 2, 0, 0, DI_NORMAL);\n      TxtRect.Left := TxtRect.Left + H;\n    end;\n{$ENDIF}\n\n    DTFormat := DrawTextFormat(Attr, TxtRect);\n{$IFNDEF UsingCLX}\n    DrawText(Canvas.Handle, PChar(s), -1, TxtRect, DTFormat);\n{$ELSE}\n    Canvas.TextRect(TxtRect, TxtRect.Left, TxtRect.Top, s, DTFormat);\n{$ENDIF}\n  end;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbBaseViewer.DrawHeaderButton(ACol : Integer; const AText : string);\nvar\n  ARect : TRect;\n  DTFormat : Word;\nbegin\n  ARect := CellRect(ACol, 0);\n  if not DefaultDrawing then with Canvas do begin\n    Brush.Style := bsSolid;\n    Brush.Color := clBtnface;\n    FillRect(ARect);\n    if FButtonDown then\n      Pen.Color := clBtnHighlight\n    else\n      Pen.Color := clBtnShadow;\n    MoveTo(ARect.Left, ARect.Bottom - 1);\n    LineTo(ARect.Right - 1, ARect.Bottom - 1);\n    LineTo(ARect.Right - 1, ARect.Top -1);\n    if FButtonDown then\n      Pen.Color := clBtnShadow\n    else\n      Pen.Color := clBtnHighlight;\n    MoveTo(ARect.Left, ARect.Bottom - 2);\n    LineTo(ARect.Left, ARect.Top);\n    LineTo(ARect.Right - 1, ARect.Top);\n    Brush.Style := bsClear;\n  end;\n  ARect.Right := ARect.Left + ColWidths[ACol];\n  if FSortCol = ACol then\n    ARect.Right := ARect.Right - 5 - (2 * (ARect.Bottom - ARect.Top) div 10);\n{$IFDEF UsingCLX}\n  { prefix is off by default in Qt}\n  DTFormat := Integer(AlignmentFlags_AlignVCenter) or\n              Integer(AlignmentFlags_SingleLine) or\n              Integer(AlignmentFlags_AlignHCenter);\n{$ELSE}\n  DTFormat := DT_VCENTER or DT_SINGLELINE or DT_NOPREFIX or DT_CENTER;\n{$ENDIF}\n  if FButtonDown then\n    ARect := Rect(ARect.Left+1, ARect.Top+1, ARect.Right, ARect.Bottom);\n{$IFDEF UsingCLX}\n  Canvas.TextRect(ARect, ARect.Left, ARect.Top, AText, DTFormat);\n{$ELSE}\n  DrawText(Canvas.Handle, PChar(AText), -1, ARect, DTFormat);\n{$ENDIF}\n  if FSortCol = ACol then\n    DrawSortArrow;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbBaseViewer.DrawSortArrow;\nvar\n  ARect : TRect;\n  SavedColor : TColor;\nbegin\n  if (FSortCol > -1) then begin\n    { set up Rect for the OnDrawSortArrow event }\n    ARect := CellRect(FSortCol, 0);\n    ARect.Top := (ARect.Bottom - ARect.Top) div 10;\n    ARect.Bottom := ARect.Bottom - ARect.Top;\n    ARect.Right := ARect.Left + ColWidths[FSortCol] - 5;\n    ARect.Left := ARect.Right - ((ARect.Bottom - ARect.Top));\n\n    if Assigned(FOnDrawSortArrow) then begin\n      FOnDrawSortArrow(Self, FSortCol, FRowMap.SortAscending, Canvas, ARect);\n      Exit;\n    end;\n    { make ARect smaller for our own drawing }\n    inc(ARect.Left, 10);\n    inc(ARect.Top, 5);\n    dec(ARect.Bottom, 5);\n\n    with Canvas do begin\n      Pen.Color := clBtnShadow;\n\n      SavedColor := Brush.Color;\n      Brush.Color := clBtnFace;\n      with ARect do\n        if FRowMap.SortAscending then begin\n           Polygon([Point(((Right-Left)div 2)+Left, Bottom), Point(Right, Top),\n             Point(Left, Top)]);\n{$IFNDEF UsingCLX}\n          if Ctl3D then begin\n            Pen.Color := clBtnHighlight;\n            MoveTo(((Right-Left)div 2)+Left, Bottom);\n            LineTo(Right, Top);\n          end;\n{$ENDIF}\n        end else begin\n          Polygon([Point(((Right-Left)div 2)+Left, Top), Point(Right, Bottom),\n            Point(Left, Bottom)]);\n{$IFNDEF UsingCLX}\n          if Ctl3D then begin\n            Pen.Color := clBtnHighlight;\n            MoveTo(((Right-Left)div 2)+Left, Top);\n            LineTo(Right, Bottom);\n            LineTo(Left, Bottom);\n            Pen.Color := clBtnShadow;\n            LineTo(((Right-Left)div 2)+Left, Top);\n          end;\n{$ENDIF}\n        end;\n      Brush.Color := SavedColor;\n    end;\n  end;\nend;\n{ -------------------------------------------------------------------------- }\nfunction TAbBaseViewer.DrawTextFormat(Attr : TAbViewAttribute;\n  var Rect : TRect) : Word;\nbegin\n{$IFDEF MSWINDOWS}\n  Result := DT_VCENTER or DT_SINGLELINE or DT_NOPREFIX;\n  case Attr of\n    vaItemname       : Result := Result or DT_LEFT;\n    vaPacked         : Result := Result or DT_RIGHT;\n    vaFileSize       : Result := Result or DT_RIGHT;\n    vaMethod         : Result := Result or DT_CENTER;\n    vaRatio          : Result := Result or DT_CENTER;\n    vaCRC            : Result := Result or DT_CENTER;\n    vaFileAttributes : Result := Result or DT_CENTER;\n    vaFileType       : Result := Result or DT_CENTER;\n    vaEncryption     : Result := Result or DT_CENTER;\n    vaTimeStamp      : Result := Result or DT_LEFT;\n    vaVersionMade    : Result := Result or DT_CENTER;\n    vaVersionNeeded  : Result := Result or DT_CENTER;\n    vaPath           : Result := Result or DT_LEFT;\n  end;\n  if (Result and 3) = DT_LEFT then\n    OffsetRect(Rect, 5, 0)\n  else if (Result and 3) = DT_RIGHT then\n    OffsetRect(Rect, -5, 0);\n{$ENDIF}\n{$IFDEF LINUX}\n  Result := Integer(AlignmentFlags_AlignVCenter) or\n            Integer(AlignmentFlags_SingleLine);\n  case Attr of\n    vaItemname       : Result := Result or Integer(AlignmentFlags_AlignLeft);\n    vaPacked         : Result := Result or Integer(AlignmentFlags_AlignRight);\n    vaFileSize       : Result := Result or Integer(AlignmentFlags_AlignRight);\n    vaMethod         : Result := Result or Integer(AlignmentFlags_AlignCenter);\n    vaRatio          : Result := Result or Integer(AlignmentFlags_AlignCenter);\n    vaCRC            : Result := Result or Integer(AlignmentFlags_AlignCenter);\n    vaFileAttributes : Result := Result or Integer(AlignmentFlags_AlignCenter);\n    vaFileType       : Result := Result or Integer(AlignmentFlags_AlignCenter);\n    vaEncryption     : Result := Result or Integer(AlignmentFlags_AlignCenter);\n    vaTimeStamp      : Result := Result or Integer(AlignmentFlags_AlignLeft);\n    vaVersionMade    : Result := Result or Integer(AlignmentFlags_AlignCenter);\n    vaVersionNeeded  : Result := Result or Integer(AlignmentFlags_AlignCenter);\n    vaPath           : Result := Result or Integer(AlignmentFlags_AlignLeft);\n  end;\n{$ENDIF}\nend;\n\n{ -------------------------------------------------------------------------- }\nfunction TAbBaseViewer.GetActiveRow : Longint;\nbegin\n  Result := Row - 1;\nend;\n{ -------------------------------------------------------------------------- }\nfunction TAbBaseViewer.GetCount : Longint;\nbegin\n  if Assigned(FItemList) then\n    Result := FItemList.Count\n  else\n    Result := 0;\nend;\n{ -------------------------------------------------------------------------- }\nfunction TAbBaseViewer.GetHeaderRowHeight : Integer;\nbegin\n  Result := RowHeights[AbHeaderRow];\nend;\n{ -------------------------------------------------------------------------- }\n{$IFDEF MSWINDOWS}\nfunction TAbBaseViewer.GetIcon(const ItemName : string) : HIcon;\nvar\n  i : Longint;\n  t : string;\n  sfi : SHFILEINFO;\nbegin\n  Result := 0;\n  if not (doShowIcons in FDisplayOptions) then\n    Exit;\n  t := ExtractFileExt(ItemName);\n  i := FIcons.IndexOf(t);\n  if (i > -1) then\n    Result := HIcon(FIcons.Objects[i])\n  else begin\n    SHGetFileInfo(PChar(t), FILE_ATTRIBUTE_NORMAL, sfi, sizeof(sfi),\n      SHGFI_ICON or SHGFI_USEFILEATTRIBUTES);\n    Result := sfi.hIcon;\n    FIcons.AddObject(t, Pointer(Result));\n  end;\nend;\n{$ENDIF}\n{$IFDEF UsingCLX }\n  { no file type icons in CLX }\n{$ENDIF}\n{ -------------------------------------------------------------------------- }\nfunction TAbBaseViewer.GetSelCount : Longint;\nbegin\n  Result := FSelList.SelCount;\nend;\n{ -------------------------------------------------------------------------- }\nfunction TAbBaseViewer.GetSelected(RowNum : Longint) : Boolean;\nbegin\n  if Assigned(FItemList) then\n    Result := FSelList.IsSelected(FRowMap[RowNum])\n  else\n    Result := False;\nend;\n{ -------------------------------------------------------------------------- }\nfunction TAbBaseViewer.GetVersion : string;\nbegin\n  Result := AbVersionS;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbBaseViewer.InitColMap;\nconst\n  cResString: array[TAbViewAttribute] of string = (AbItemNameHeadingS,\n    AbPackedHeadingS, AbMethodHeadingS, AbRatioHeadingS, AbCRCHeadingS,\n    AbFileAttrHeadingS, AbFileFormatHeadingS, AbEncryptionHeadingS,\n    AbTimeStampHeadingS, AbFileSizeHeadingS, AbVersionMadeHeadingS,\n    AbVersionNeededHeadingS, AbPathHeadingS);\nvar\n  i : TAbViewAttribute;\nbegin\n  FHeadings.Clear;\n  for i := Low(TAbViewAttribute) to High(TAbViewAttribute) do begin\n    FHeadings.Add(cResString[i]);\n    FColMap[i] := Ord(i);\n  end;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbBaseViewer.InvalidateRow(ARow: Longint);\nvar\n  Rect: TRect;\nbegin\n  if not HandleAllocated then\n    Exit;\n  if ((ARow < TopRow) or (ARow > TopRow + VisibleRowCount)) and (ARow <> 0) then\n    Exit;\n  Rect := CellRect(0, ARow);\n  Rect.Right := ClientWidth;\n{$IFDEF UsingCLX}\n  InvalidateRect(Rect, False);\n{$ELSE}\n  InvalidateRect(Handle, @Rect, True);\n{$ENDIF}\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbBaseViewer.KeyDown(var Key: Word; Shift: TShiftState);\nbegin\n  FShiftState := Shift;\n  inherited KeyDown(Key, Shift);\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbBaseViewer.KeyUp(var Key: Word; Shift: TShiftState);\nbegin\n  FShiftState := Shift;\n  inherited KeyUp(Key, Shift);\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbBaseViewer.Loaded;\nbegin\n  inherited Loaded;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbBaseViewer.MouseDown(Button: TMouseButton;\n  Shift: TShiftState; X, Y : Integer);\n\n  function GetMinLen(Col: Integer): Word;\n  var\n    I, L : Integer;\n    s : String;\n    aItem : TAbArchiveItem;\n    Attr : TAbViewAttribute;\n    Sorted : Boolean;\n  begin\n    Attr := TAbViewAttribute(ColMap(Col));\n    Result := Canvas.TextWidth(FHeadings[ColMap(Col)]);\n    case Attr of\n      vaItemName : Sorted := saItemName in FSortAttributes;\n      vaPacked   : Sorted := saPacked in FSortAttributes;\n      vaRatio    : Sorted := saRatio in FSortAttributes;\n      vaTimeStamp: Sorted := saTimeStamp in FSortAttributes;\n      vaFileSize : Sorted := saFileSize in FSortAttributes;\n      vaPath     : Sorted := saPath in FSortAttributes;\n      else Sorted := False;\n    end;\n    if Sorted then\n      Result := Result + RowHeights[0] + 16\n    else\n      Result := Result + 8;\n\n    if Assigned(FItemList) then\n    for I := 0 to (FItemList.Count-1) do begin\n      aItem := FItemList.Items[I];\n      S := AttrToStr(Attr, aItem);\n      L := Canvas.TextWidth(S) + 8;\n      if (doShowIcons in FDisplayOptions) and (Attr = vaItemName) then\n        inc(L, RowHeights[I]);\n      if L > Result then\n        Result := L;\n    end;\n  end;\n\nvar\n  ACol : Longint;\n  ARow : Longint;\n  Rect : TRect;\nbegin\n  ViewMouseCoord := MouseCoord(X, Y);\n  inherited MouseDown(Button, Shift, X, Y);\n\n  FShiftState := Shift;\n  { handle double clicks on header row dividers }\n  if (ssDouble in FShiftState) and (ViewMouseCoord.Y = AbHeaderRow) then begin\n    FColSizing := True;\n    Rect := CellRect(ViewMouseCoord.X, ViewMouseCoord.Y);\n    Rect.Left := Rect.Right - 3;\n    if PtInRect(Rect, Point(X, Y)) then begin\n      ColWidths[MouseCoord(Rect.Left, Y).X] :=\n        GetMinLen(MouseCoord(Rect.Left, Y).X)\n    end\n    else begin\n      Rect := CellRect(ViewMouseCoord.X, ViewMouseCoord.Y);\n      Rect.Right := Rect.Left + 4;\n      if PtInRect(Rect, Point(X, Y)) then\n        ColWidths[MouseCoord(Rect.Left, Y).X-1] :=\n          GetMinLen(MouseCoord(Rect.Left, Y).X-1);\n    end;\n  end;\n\n  { if grid is being resized }\n  if (FGridState = gsColSizing) then begin\n    FColSizing := True;\n    Exit;  {dont press button when resizing column}\n  end;\n\n  { refresh the headers}\n  if Assigned(FItemList) then\n    if (FItemList.Count > 0) then begin\n      ARow := ViewMouseCoord.Y;\n      ACol := ViewMouseCoord.X;\n      if (ARow = abHeaderRow) then begin\n        {if not (doColMove in FDisplayOptions) then}\n        if not (doColMove in FDisplayOptions) and not FColSizing then\n          FButtonDown := True;\n        RefreshCell(0, ACol);\n      end else if not (ssShift in Shift) then\n        RowAnchor := ActiveRow;\n    end;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbBaseViewer.MouseUp(Button: TMouseButton;\n  Shift: TShiftState; X, Y: Integer);\nvar\n  ACol   : Longint;\n  ARow   : Longint;\n  Attr   : TAbViewAttribute;\n  SortAttribute : TAbSortAttribute;\nbegin\n  inherited MouseUp(Button, Shift, X, Y);\n  if csDesigning in ComponentState then Exit;\n\n  FShiftState := Shift;\n  FButtonDown := False;\n\n  if FColSizing then begin\n    Refresh;\n    FColSizing := False;\n  end else\n    if Assigned(FItemList) then\n      if (FItemList.Count > 0) then begin\n        ARow := ViewMouseCoord.Y;\n        ACol := ViewMouseCoord.X;\n        if (ARow = abHeaderRow) then begin\n          Attr := TAbViewAttribute(ColMap(ACol));\n          if not FColMoving and\n            AttrToSortAttribute(Attr, SortAttribute) and\n            (SortAttribute in FSortAttributes) then begin\n            FSortCol := ACol;\n            FItemIndex := FRowMap[Row-1];\n            FRowMap.SortBy(SortAttribute, FItemList);\n            FButtonDown := False;\n            RefreshCell(0, ACol);\n            if (doTrackActiveRow in FDisplayOptions) then\n              Row := FRowMap.InvRows[FItemIndex] + 1;\n            Refresh;\n            DoSorted(Attr);\n          end else begin\n            FButtonDown := False;\n            RefreshCell(0, ACol);\n          end;\n        end else\n          Paint;\n      end;\n\n  FColMoving := False;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbBaseViewer.MouseMove(Shift: TShiftState; X, Y: Integer);\nbegin\n  inherited MouseMove(Shift, X, Y);\n\n  if (FGridState = gsColMoving) then\n    FColMoving := True;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbBaseViewer.MoveColumn(FromCol, ToCol : Integer);\nvar\n  temp, i : Integer;\nbegin\n  Temp := ColMap(FromCol);\n  if (FromCol < ToCol) then begin\n    for i := (FromCol + 1) to ToCol do\n      FColMap[TAbViewAttribute(i-1)] := FColMap[TAbViewAttribute(i)]; {Shift left}\n  end else begin\n    for i := (FromCol - 1) downto ToCol do\n      FColMap[TAbViewAttribute(i+1)] := FColMap[TAbViewAttribute(i)]; {Shift right}\n  end;\n  FColMap[TAbViewAttribute(ToCol)] := Temp;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbBaseViewer.RefreshCell(ARow, ACol: Longint);\nvar\n  Rect: TRect;\nbegin\n  if not HandleAllocated then\n    Exit;\n  Rect := CellRect(ACol, ARow);\n{$IFDEF UsingCLX}\n  InvalidateRect(Rect, False);\n{$ELSE}\n  InvalidateRect(Handle, @Rect, False);\n{$ENDIF}\n  Update;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbBaseViewer.RefreshRow(ARow: Longint);\nbegin\n  InvalidateRow(ARow);\n  Update;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbBaseViewer.SelectAll;\nbegin\n  if Assigned(FItemList) then\n    if (FItemList.Count > 0) then begin\n      FSelList.SelectAll(FItemList.Count);\n      Invalidate;\n    end;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbBaseViewer.SetActiveRow(RowNum : Longint);\nbegin\n  if Assigned(FItemList) then\n    if (RowNum >= 0) and (RowNum < FItemList.Count) then\n       Row := RowNum + 1;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbBaseViewer.SetAttributes(Value : TAbViewAttributes);\nbegin\n  FAttributes := Value;\n  ColCount := UpdateColCount(FAttributes);\n  DoChange(Self);\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbBaseViewer.SetDisplayOptions(Value : TAbDisplayOptions);\n  {maps DisplayOptions to TGridOptions}\nbegin\n  FDisplayOptions := Value;\n  Options := [goFixedVertLine, goFixedHorzLine, goRowSelect];\n{$IFDEF HasGridDrawingStyle}\n  Options := Options + [goFixedRowClick]; // Highlight pressed header when themed\n{$ENDIF}\n\n  if (doColLines in Value) then\n    Options := Options + [goVertLine];\n  if (doColMove in Value) then\n    Options := Options + [goColMoving];\n  if (doColSizing in Value) then\n    Options := Options + [goColSizing];\n  if (doRowLines in Value) then\n    Options := Options + [goHorzLine];\n  if (doThumbTrack in Value) then\n    Options := Options + [goThumbTracking];\n  DoChange(nil);\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbBaseViewer.SetHeaderRowHeight(Value : Integer);\nbegin\n  RowHeights[abHeaderRow] := Value;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbBaseViewer.SetHeadings(Value: TAbColHeadings);\nbegin\n  Headings.Assign(Value);\n  Refresh;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbBaseViewer.SetSortAttributes(Value : TAbSortAttributes);\nbegin\n  FSortAttributes := Value;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbBaseViewer.SetSelected(RowNum : Longint; Value: Boolean);\nbegin\n  if Assigned(FItemList) then\n    case Value of\n      True  : FSelList.Select(FRowMap[RowNum]);\n      False : FSelList.Deselect(FRowMap[RowNum]);\n    end;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbBaseViewer.SetVersion(const Value : string);\nbegin\n  {NOP}\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbBaseViewer.TopLeftChanged;\nbegin\n  if FAllowInvalidate then\n    Invalidate;\nend;\n{ -------------------------------------------------------------------------- }\nfunction TAbBaseViewer.UpdateColCount(Attributes : TAbViewAttributes) : Integer;\nvar\n  i : TAbViewAttribute;\nbegin\n  Result := 0;\n  for i := Low(TAbViewAttribute) to High(TAbViewAttribute) do begin\n    if (i in Attributes) then begin\n      FColMap[TAbViewAttribute(Result)] := Ord(i);\n      Inc(Result);\n    end;\n  end;\nend;\n{ -------------------------------------------------------------------------- }\n{$IFDEF UsingCLX}\nprocedure TAbBaseViewer.SizeChanged(OldColCount, OldRowCount: Longint);\nbegin\n  inherited SizeChanged(OldColCount, OldRowCount);\n  Refresh;\nend;\n{$ELSE}\nprocedure TAbBaseViewer.WMSize(var Msg: TWMSize);\nbegin\n  inherited;\n  Refresh;\nend;\n{$ENDIF}\n{ -------------------------------------------------------------------------- }\n{$IFNDEF UsingCLX}\nprocedure TAbBaseViewer.WMEraseBkgnd(var Msg: TWMEraseBkgnd);\nbegin\n  Msg.Result := -1;\nend;\n{$ENDIF}\n\nend.\n"
  },
  {
    "path": "lib/abbrevia/source/AbWavPack.pas",
    "content": "(* ***** BEGIN LICENSE BLOCK *****\n * Version: MPL 1.1\n *\n * The contents of this file are subject to the Mozilla Public License Version\n * 1.1 (the \"License\"); you may not use this file except in compliance with\n * the License. You may obtain a copy of the License at\n * http://www.mozilla.org/MPL/\n *\n * Software distributed under the License is distributed on an \"AS IS\" basis,\n * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License\n * for the specific language governing rights and limitations under the\n * License.\n *\n * The Original Code is TurboPower Abbrevia\n *\n * The Initial Developer of the Original Code is Craig Peterson\n *\n * Portions created by the Initial Developer are Copyright (C) 2011\n * the Initial Developer. All Rights Reserved.\n *\n * Contributor(s):\n * Craig Peterson <capeterson@users.sourceforge.net>\n *\n * ***** END LICENSE BLOCK ***** *)\n\n{*********************************************************}\n{* ABBREVIA: AbWavPack.pas                               *}\n{*********************************************************}\n{* ABBREVIA: WavPack decompression procedures            *}\n{*********************************************************}\n\nunit AbWavPack;\n\n{$I AbDefine.inc}\n\ninterface\n\nuses\n  Classes;\n\n// Decompress a WavPack compressed stream from aSrc and write to aDes.\n// aSrc must not allow reads past the compressed data.\nprocedure DecompressWavPack(aSrc, aDes: TStream);\n\n\nimplementation\n\nuses\n  AbCrtl,\n  Math,\n  SysUtils;\n\n// Compile using\n//   bcc32 -DWIN32 -DNO_USE_FSTREAMS -c -w-8004 -w-8012 -w-8017 -w-8057 -w-8065 *.c\n//\n// In wavpack_local.h remove the line \"#define FASTCALL __fastcall\"\n\n{ C runtime library ======================================================== }\n\nfunction fabs(x: Double): Double; cdecl;\nbegin\n  if x < 0 then Result := -1\n  else Result := x\nend;\n\nfunction floor(x: Double): Integer; cdecl;\nbegin\n  Result := Floor(x);\nend;\n\nfunction labs(n: Integer): Integer; cdecl;\nbegin\n  if n < 0 then Result := -n\n  else Result := n;\nend;\n\nfunction _stricmp(str1, str2: PAnsiChar): Integer; cdecl;\n  external 'msvcrt.dll' name '_stricmp';\n\nfunction strncmp(str1, str2: PAnsiChar; num: Integer): Integer; cdecl;\n  external 'msvcrt.dll' {$IFDEF BCB}name '_strncmp'{$ENDIF};\n\n\n{ Forward declarations ===================================================== }\n\n// bits.c\nprocedure bs_open_read; external;\nprocedure bs_close_read; external;\nprocedure bs_open_write; external;\nprocedure bs_close_write; external;\nprocedure little_endian_to_native; external;\nprocedure native_to_little_endian; external;\n\n// extra1.c\nprocedure execute_mono; external;\n\n// extra2.c\nprocedure execute_stereo; external;\n\n// float.c\nprocedure float_values; external;\nprocedure read_float_info; external;\nprocedure scan_float_data; external;\nprocedure send_float_data; external;\nprocedure WavpackFloatNormalize; external;\nprocedure write_float_info; external;\n\n// metadata.c\nprocedure add_to_metadata; external;\nprocedure copy_metadata; external;\nprocedure free_metadata; external;\nprocedure process_metadata; external;\nprocedure read_metadata_buff; external;\nprocedure write_metadata_block; external;\n\n// pack.c\nprocedure pack_block; external;\nprocedure pack_init; external;\n\n// tags.c\nprocedure load_tag; external;\nprocedure valid_tag; external;\n\n// unpack.c\nprocedure check_crc_error; external;\nprocedure free_tag; external;\nprocedure unpack_init; external;\nprocedure unpack_samples; external;\n\n// unpack3.c\nprocedure free_stream3; external;\nprocedure get_version3; external;\nprocedure get_sample_index3; external;\nprocedure open_file3; external;\nprocedure seek_sample3; external;\nprocedure unpack_samples3; external;\n\n// words.c\nprocedure exp2s; external;\nprocedure flush_word; external;\nprocedure get_word; external;\nprocedure get_words_lossless; external;\nprocedure init_words; external;\nprocedure log2s; external;\nprocedure log2buffer; external;\nprocedure nosend_word; external;\nprocedure read_hybrid_profile; external;\nprocedure read_entropy_vars; external;\nprocedure restore_weight; external;\nprocedure scan_word; external;\nprocedure send_word; external;\nprocedure send_words_lossless; external;\nprocedure store_weight; external;\nprocedure write_entropy_vars; external;\nprocedure write_hybrid_profile; external;\n\n\n{ Linker derectives ======================================================== }\n\n{$IF DEFINED(WIN32)}\n  {$L Win32\\wv_bits.obj}\n  {$L Win32\\wv_extra1.obj}\n  {$L Win32\\wv_extra2.obj}\n  {$L Win32\\wv_float.obj}\n  {$L Win32\\wv_metadata.obj}\n  {$L Win32\\wv_pack.obj}\n  {$L Win32\\wv_tags.obj}\n  {$L Win32\\wv_unpack.obj}\n  {$L Win32\\wv_unpack3.obj}\n  {$L Win32\\wv_words.obj}\n  {$L Win32\\wv_wputils.obj}\n{$ELSEIF DEFINED(WIN64)}\n  {$L Win64\\wv_bits.obj}\n  {$L Win64\\wv_extra1.obj}\n  {$L Win64\\wv_extra2.obj}\n  {$L Win64\\wv_float.obj}\n  {$L Win64\\wv_metadata.obj}\n  {$L Win64\\wv_pack.obj}\n  {$L Win64\\wv_tags.obj}\n  {$L Win64\\wv_unpack.obj}\n  {$L Win64\\wv_unpack3.obj}\n  {$L Win64\\wv_words.obj}\n  {$L Win64\\wv_wputils.obj}\n{$IFEND}\n\n{ wavpack_local.h ========================================================== }\n\nconst\n  OPEN_WVC       = $1;     // open/read \"correction\" file\n  OPEN_TAGS      = $2;     // read ID3v1 / APEv2 tags (seekable file)\n  OPEN_WRAPPER   = $4;     // make audio wrapper available (i.e. RIFF)\n  OPEN_2CH_MAX   = $8;     // open multichannel as stereo (no downmix)\n  OPEN_NORMALIZE = $10;    // normalize floating point data to +/- 1.0\n  OPEN_STREAMING = $20;    // \"streaming\" mode blindly unpacks blocks\n                           // w/o regard to header file position info\n  OPEN_EDIT_TAGS = $40;    // allow editing of tags\n\ntype\n  int32_t = LongInt;\n  uint32_t = LongWord;\n\n  WavpackStreamReader = record\n    read_bytes: function(id, data: Pointer; bcount: int32_t): int32_t; cdecl;\n    get_pos: function(id: Pointer): uint32_t; cdecl;\n    set_pos_abs: function(id: Pointer; pos: uint32_t): Integer; cdecl;\n    set_pos_rel: function(id: Pointer; delta: int32_t; mode: Integer): Integer; cdecl;\n    push_back_byte: function(id: Pointer; c: Integer): Integer; cdecl;\n    get_length: function(id: Pointer): uint32_t; cdecl;\n    can_seek: function(id: Pointer): Integer; cdecl;\n    write_bytes: function(id, data: Pointer; bcount: int32_t): int32_t; cdecl;\n  end;\n\n  WavpackContext = Pointer;\n\n\n{ wputils.c ================================================================ }\n\nfunction WavpackOpenFileInputEx(const reader: WavpackStreamReader;\n  wv_id, wvc_id: Pointer; error: PAnsiChar; flags, norm_offset: Integer): WavpackContext;\n  cdecl; external;\n\nfunction WavpackGetWrapperBytes(wpc: WavpackContext): uint32_t; cdecl; external;\nfunction WavpackGetWrapperData(wpc: WavpackContext): PByte; cdecl; external;\nprocedure WavpackFreeWrapper (wpc: WavpackContext); cdecl; external;\n\nprocedure WavpackSeekTrailingWrapper(wpc: WavpackContext); cdecl; external;\n\nfunction WavpackGetNumSamples(wpc: WavpackContext): uint32_t; cdecl; external;\nfunction WavpackGetNumChannels(wpc: WavpackContext): Integer; cdecl; external;\nfunction WavpackGetBytesPerSample (wpc: WavpackContext): Integer; cdecl; external;\n\nfunction WavpackUnpackSamples(wpc: WavpackContext; buffer: Pointer;\n  samples: uint32_t): uint32_t; cdecl; external;\n\nfunction WavpackCloseFile(wpc: WavpackContext): WavpackContext; cdecl; external;\n\n\n{ TWavPackStream implementation ============================================ }\n\ntype\n  PWavPackStream = ^TWavPackStream;\n  TWavPackStream = record\n    HasPushedByte: Boolean;\n    PushedByte: Byte;\n    Stream: TStream;\n  end;\n{ -------------------------------------------------------------------------- }\nfunction TWavPackStream_read_bytes(id, data: Pointer; bcount: int32_t): int32_t; cdecl;\nbegin\n  if PWavPackStream(id).HasPushedByte then begin\n    PByte(data)^ := PWavPackStream(id).PushedByte;\n    PWavPackStream(id).HasPushedByte := False;\n    Inc(PByte(data));\n    Dec(bcount);\n    if bcount = 0 then\n      Result := 1\n    else\n      Result := PWavPackStream(id).Stream.Read(data^, bcount) + 1;\n  end\n  else\n    Result := PWavPackStream(id).Stream.Read(data^, bcount);\nend;\n{ -------------------------------------------------------------------------- }\nfunction TWavPackStream_get_pos(id: Pointer): uint32_t; cdecl;\nbegin\n  Result := PWavPackStream(id).Stream.Position;\nend;\n{ -------------------------------------------------------------------------- }\nfunction TWavPackStream_set_pos_abs(id: Pointer; pos: uint32_t): Integer; cdecl;\nbegin\n  PWavPackStream(id).Stream.Position := pos;\n  Result := 0;\nend;\n{ -------------------------------------------------------------------------- }\nfunction TWavPackStream_set_pos_rel(id: Pointer; delta: int32_t;\n  mode: Integer): Integer; cdecl;\nbegin\n  PWavPackStream(id).Stream.Seek(delta, mode);\n  Result := 1;\nend;\n{ -------------------------------------------------------------------------- }\nfunction TWavPackStream_push_back_byte(id: Pointer; c: Integer): Integer; cdecl;\nbegin\n  Assert(not PWavPackStream(id).HasPushedByte);\n  PWavPackStream(id).HasPushedByte := True;\n  PWavPackStream(id).PushedByte := Byte(c);\n  Result := 1;\nend;\n{ -------------------------------------------------------------------------- }\nfunction TWavPackStream_get_length(id: Pointer): uint32_t; cdecl;\nbegin\n  Result := PWavPackStream(id).Stream.Size;\nend;\n{ -------------------------------------------------------------------------- }\nfunction TWavPackStream_can_seek(id: Pointer): Integer; cdecl;\nbegin\n  Result := 1;\nend;\n{ -------------------------------------------------------------------------- }\nfunction TWavPackStream_write_bytes(id, data: Pointer;\n  bcount: int32_t): int32_t; cdecl;\nbegin\n  Result := PWavPackStream(id).Stream.Write(data^, bcount);\nend;\n\n\n{ Decompression routines =================================================== }\n\n{ -------------------------------------------------------------------------- }\n// Reformat samples from longs in processor's native endian mode to\n// little-endian data with (possibly) less than 4 bytes / sample.\n//\n// Based on wvunpack.c::format_samples.\n// Conversions simplified since we only support little-endian processors\nfunction FormatSamples(bps: Integer; dst, src: PByte; samcnt: uint32_t): PByte;\nvar\n  sample: LongWord;\nbegin\n  while samcnt > 0 do begin\n    Dec(samcnt);\n    // Get next sample\n    sample := PLongWord(src)^;\n    // Convert and write to output\n    case bps of\n      1: begin\n        dst^ := sample + 128;\n      end;\n      2: begin\n        PWord(dst)^ := sample;\n      end;\n      3: begin\n        PByteArray(dst)[0] := sample;\n        PByteArray(dst)[1] := sample shr 8;\n        PByteArray(dst)[2] := sample shr 16;\n      end;\n      4: begin\n        PLongWord(dst)^ := sample;\n      end;\n    end;\n    Inc(src, SizeOf(LongWord));\n    Inc(dst, bps);\n  end;\n  Result := dst;\nend;\n{ -------------------------------------------------------------------------- }\n// Decompress a WavPack compressed stream from aSrc and write to aDes.\n// aSrc must not allow reads past the compressed data.\n//\n// Based on wvunpack.c::unpack_file()\nprocedure DecompressWavPack(aSrc, aDes: TStream);\ntype\n  PtrInt = {$IF DEFINED(CPUX64)}Int64{$ELSE}LongInt{$IFEND};\nconst\n  OutputBufSize = 256 * 1024;\nvar\n  StreamReader: WavpackStreamReader;\n  Context: WavpackContext;\n  Src: TWavpackStream;\n  Error: array[0..79] of AnsiChar;\n  SamplesToUnpack, SamplesUnpacked: uint32_t;\n  NumChannels, bps, BytesPerSample: Integer;\n  OutputBuf, OutputPtr: PByte;\n  DecodeBuf: Pointer;\nbegin\n  OutputBuf := nil;\n  DecodeBuf := nil;\n\n  StreamReader.read_bytes := TWavPackStream_read_bytes;\n  StreamReader.get_pos := TWavPackStream_get_pos;\n  StreamReader.set_pos_abs := TWavPackStream_set_pos_abs;\n  StreamReader.set_pos_rel := TWavPackStream_set_pos_rel;\n  StreamReader.push_back_byte := TWavPackStream_push_back_byte;\n  StreamReader.get_length := TWavPackStream_get_length;\n  StreamReader.can_seek := TWavPackStream_can_seek;\n  StreamReader.write_bytes := TWavPackStream_write_bytes;\n\n  FillChar(Src, SizeOf(Src), 0);\n  Src.Stream := aSrc;\n\n  Context := WavpackOpenFileInputEx(StreamReader, @Src, nil, Error, OPEN_WRAPPER, 0);\n  if Context = nil then\n    raise Exception.Create('WavPack decompression failed: ' + Error);\n  try\n    // Write .wav header\n    if WavpackGetWrapperBytes(Context) > 0 then begin\n      aDes.WriteBuffer(WavpackGetWrapperData(Context)^, WavpackGetWrapperBytes(Context));\n      WavpackFreeWrapper(Context);\n    end;\n\n    NumChannels := WavpackGetNumChannels(Context);\n    bps := WavpackGetBytesPerSample(Context);\n    BytesPerSample := NumChannels * bps;\n\n    GetMem(OutputBuf, OutputBufSize);\n    OutputPtr := OutputBuf;\n    GetMem(DecodeBuf, 4096 * NumChannels * SizeOf(Integer));\n\n    repeat\n      // Unpack samples\n      SamplesToUnpack := (OutputBufSize - (PtrInt(OutputPtr) - PtrInt(OutputBuf))) div BytesPerSample;\n      if (SamplesToUnpack > 4096) then\n        SamplesToUnpack := 4096;\n      SamplesUnpacked := WavpackUnpackSamples(Context, DecodeBuf, SamplesToUnpack);\n\n      // Convert from 32-bit integers down to appriopriate bit depth\n      // and copy to output buffer.\n      if (SamplesUnpacked > 0) then\n        OutputPtr := FormatSamples(bps, OutputPtr, DecodeBuf,\n          SamplesUnpacked * uint32_t(NumChannels));\n\n      // Write output when it's full or when we're done\n      if (SamplesUnpacked = 0) or\n         ((OutputBufSize - (PtrInt(OutputPtr) - PtrInt(OutputBuf))) < BytesPerSample) then begin\n        aDes.WriteBuffer(OutputBuf^, PtrInt(OutputPtr) - PtrInt(OutputBuf));\n        OutputPtr := OutputBuf;\n      end;\n    until (SamplesUnpacked = 0);\n\n    // Write .wav footer\n    while WavpackGetWrapperBytes(Context) > 0 do begin\n      try\n        aDes.WriteBuffer(WavpackGetWrapperData(Context)^,\n          WavpackGetWrapperBytes(Context));\n      finally\n        WavpackFreeWrapper(Context);\n      end;\n      // Check for more RIFF data\n      WavpackUnpackSamples (Context, DecodeBuf, 1);\n    end;\n  finally\n    if DecodeBuf <> nil then\n      FreeMemory(DecodeBuf);\n    if OutputBuf <> nil then\n      FreeMemory(OutputBuf);\n    WavpackCloseFile(Context);\n  end;\nend;\n\nend.\n"
  },
  {
    "path": "lib/abbrevia/source/AbZBrows.pas",
    "content": "(* ***** BEGIN LICENSE BLOCK *****\n * Version: MPL 1.1\n *\n * The contents of this file are subject to the Mozilla Public License Version\n * 1.1 (the \"License\"); you may not use this file except in compliance with\n * the License. You may obtain a copy of the License at\n * http://www.mozilla.org/MPL/\n *\n * Software distributed under the License is distributed on an \"AS IS\" basis,\n * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License\n * for the specific language governing rights and limitations under the\n * License.\n *\n * The Original Code is TurboPower Abbrevia\n *\n * The Initial Developer of the Original Code is\n * TurboPower Software\n *\n * Portions created by the Initial Developer are Copyright (C) 1997-2002\n * the Initial Developer. All Rights Reserved.\n *\n * Contributor(s):\n *   Craig Peterson <capeterson@users.sourceforge.net>\n *\n * ***** END LICENSE BLOCK ***** *)\n\n{*********************************************************}\n{* ABBREVIA: AbZBrows.pas                                *}\n{*********************************************************}\n{* ABBREVIA: Zip file Browser Component                  *}\n{*********************************************************}\n\nunit AbZBrows;\n\n{$I AbDefine.inc}\n\ninterface\n\nuses\n  Classes,\n  AbArcTyp, AbBrowse, AbSpanSt, AbZipTyp;\n\ntype\n  TAbCustomZipBrowser = class(TAbBaseBrowser)\n  private\n    function GetTarAutoHandle: Boolean;\n    procedure SetTarAutoHandle(const Value: Boolean);\n  protected {private}\n    FPassword          : AnsiString;\n    FOnRequestLastDisk : TAbRequestDiskEvent;\n    FOnRequestNthDisk  : TAbRequestNthDiskEvent;\n    FOnRequestBlankDisk     : TAbRequestDiskEvent;\n    FTarAutoHandle     : Boolean;\n\n  protected {methods}\n    function  GetItem(Index : Integer) : TAbZipItem; virtual;\n    function  GetStream: TStream;\n    function  GetZipfileComment : AnsiString;\n    procedure InitArchive;\n      override;\n    procedure SetFileName(const aFileName : string);\n      override;\n    procedure SetStream(aValue: TStream);\n    procedure SetOnRequestLastDisk(Value : TAbRequestDiskEvent);\n    procedure SetOnRequestNthDisk(Value : TAbRequestNthDiskEvent);\n    procedure SetOnRequestBlankDisk(Value : TAbRequestDiskEvent);\n\n    procedure SetPassword(const Value : AnsiString);\n    procedure SetZipfileComment(const Value : AnsiString);\n      virtual;\n\n  protected {properties}\n    property Password : AnsiString\n      read  FPassword\n      write SetPassword;\n\n  protected {events}\n    property OnRequestLastDisk : TAbRequestDiskEvent\n      read  FOnRequestLastDisk\n      write SetOnRequestLastDisk;\n    property OnRequestNthDisk : TAbRequestNthDiskEvent\n      read  FOnRequestNthDisk\n      write SetOnRequestNthDisk;\n    property OnRequestBlankDisk : TAbRequestDiskEvent\n      read  FOnRequestBlankDisk\n      write SetOnRequestBlankDisk;\n\n  public {methods}\n    constructor Create(AOwner : TComponent); override;\n    destructor Destroy; override;\n\n  public {properties}\n    property Items[Index : Integer] : TAbZipItem\n      read  GetItem; default;\n    property Stream : TStream // This can be used instead of Filename\n      read GetStream write SetStream;\n    property ZipArchive : {TAbZipArchive} TAbArchive\n      read FArchive;\n    property ZipfileComment : AnsiString\n      read GetZipfileComment\n      write SetZipfileComment;\n\n    property TarAutoHandle : Boolean\n      read GetTarAutoHandle\n      write SetTarAutoHandle;\n  end;\n\n  TAbZipBrowser = class(TAbCustomZipBrowser)\n  published\n    property ArchiveProgressMeter;\n    property ItemProgressMeter;\n    property BaseDirectory;\n    property LogFile;\n    property Logging;\n    property OnArchiveProgress;\n    property OnArchiveItemProgress;\n    property OnChange;\n    property OnConfirmProcessItem;\n    property OnLoad;\n    property OnProcessItemFailure;\n    property OnRequestLastDisk;\n    property OnRequestNthDisk;\n    property Version;\n    property TarAutoHandle;\n    property FileName;  {must be after OnLoad}\n  end;\n\n\nimplementation\n\nuses\n  SysUtils, AbBzip2Typ, AbExcept, AbGzTyp, AbTarTyp, AbUtils;\n\n{ TAbCustomZipBrowser implementation ======================================= }\n\n{ -------------------------------------------------------------------------- }\nconstructor TAbCustomZipBrowser.Create(AOwner : TComponent);\nbegin\n  inherited Create(AOwner);\nend;\n{ -------------------------------------------------------------------------- }\ndestructor TAbCustomZipBrowser.Destroy;\nbegin\n  inherited Destroy;\nend;\n{ -------------------------------------------------------------------------- }\nfunction TAbCustomZipBrowser.GetItem(Index : Integer) : TAbZipItem;\nbegin\n  Result := TAbZipItem(ZipArchive.ItemList[Index]);\nend;\n{ -------------------------------------------------------------------------- }\nfunction TAbCustomZipBrowser.GetStream: TStream;\nbegin\n  if FArchive <> nil then\n    Result := FArchive.FStream\n  else\n    Result := nil\nend;\n{ -------------------------------------------------------------------------- }\nfunction TAbCustomZipBrowser.GetTarAutoHandle: Boolean;\nbegin\n  Result := False;\n  if FArchive is TAbGzipArchive then\n    Result := TAbGzipArchive(FArchive).TarAutoHandle\n  else if FArchive is TAbBzip2Archive then\n    Result := TAbBzip2Archive(FArchive).TarAutoHandle;\nend;\n{ -------------------------------------------------------------------------- }\nfunction TAbCustomZipBrowser.GetZipfileComment : AnsiString;\nbegin\n  if FArchive is TAbZipArchive then\n    Result := TAbZipArchive(FArchive).ZipfileComment\n  else\n    Result := '';\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbCustomZipBrowser.InitArchive;\nbegin\n  inherited InitArchive;\n  if FArchive is TAbZipArchive then begin\n    {properties}\n    TAbZipArchive(FArchive).Password          := FPassword;\n    {events}\n    TAbZipArchive(FArchive).OnRequestLastDisk := FOnRequestLastDisk;\n    TAbZipArchive(FArchive).OnRequestNthDisk  := FOnRequestNthDisk;\n  end;\nend;\n{ -------------------------------------------------------------------------- }\n\nprocedure TAbCustomZipBrowser.SetFileName(const aFileName : string);\nvar\n  ArcType : TAbArchiveType;\nbegin\n\n  FFileName := aFileName;\n  if csDesigning in ComponentState then\n    Exit;\n  try\n    if Assigned(FArchive) then begin\n      FArchive.Save;\n    end;\n  except\n  end;\n  FArchive.Free;\n  FArchive := nil;\n\n  if FileName <> '' then begin\n    if FileExists(FileName) then begin { open it }\n      ArcType := ArchiveType;\n      if not ForceType then\n         ArcType := AbDetermineArcType(FileName, atUnknown);\n\n      case ArcType of\n        atZip, atSpannedZip, atSelfExtZip : begin\n          FArchive := TAbZipArchive.Create(FileName, fmOpenRead or fmShareDenyNone);\n          InitArchive;\n        end;\n\n        atTar : begin\n          FArchive := TAbTarArchive.Create(FileName, fmOpenRead or fmShareDenyNone);\n          inherited InitArchive;\n        end;\n\n        atGZip : begin\n          FArchive := TAbGzipArchive.Create(FileName, fmOpenRead or fmShareDenyNone);\n          TAbGzipArchive(FArchive).TarAutoHandle := FTarAutoHandle;\n          TAbGzipArchive(FArchive).IsGzippedTar := False;\n          inherited InitArchive;\n        end;\n\n        atGZippedTar : begin\n          FArchive := TAbGzipArchive.Create(FileName, fmOpenRead or fmShareDenyNone);\n          TAbGzipArchive(FArchive).TarAutoHandle := FTarAutoHandle;\n          TAbGzipArchive(FArchive).IsGzippedTar := True;\n          inherited InitArchive;\n        end;\n\n        atBzip2 : begin\n          FArchive := TAbBzip2Archive.Create(FileName, fmOpenRead or fmShareDenyNone);\n          TAbBzip2Archive(FArchive).TarAutoHandle := FTarAutoHandle;\n          TAbBzip2Archive(FArchive).IsBzippedTar := False;\n          inherited InitArchive;\n        end;\n\n        atBzippedTar : begin\n          FArchive := TAbBzip2Archive.Create(FileName, fmOpenRead or fmShareDenyNone);\n          TAbBzip2Archive(FArchive).TarAutoHandle := FTarAutoHandle;\n          TAbBzip2Archive(FArchive).IsBzippedTar := True;\n          inherited InitArchive;\n        end;\n\n        else\n          raise EAbUnhandledType.Create;\n      end {case};\n      FArchive.Load;\n      FArchiveType := ArcType;\n    end;\n  end;\n  DoChange;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbCustomZipBrowser.SetStream(aValue: TStream);\nvar\n  ArcType : TAbArchiveType;\nbegin\n  FFileName := '';\n  try\n    if FArchive <> nil then\n      FArchive.Save;\n  except\n  end;\n  FreeAndNil(FArchive);\n\n  if aValue <> nil then begin\n    ArcType := ArchiveType;\n    if not ForceType then\n      ArcType := AbDetermineArcType(aValue);\n\n    case ArcType of\n      atZip, atSpannedZip, atSelfExtZip : begin\n        FArchive := TAbZipArchive.CreateFromStream(aValue, '');\n      end;\n\n      atTar : begin\n        FArchive := TAbTarArchive.CreateFromStream(aValue, '');\n      end;\n\n      atGZip, atGZippedTar : begin\n        FArchive := TAbGzipArchive.CreateFromStream(aValue, '');\n        TAbGzipArchive(FArchive).TarAutoHandle := FTarAutoHandle;\n        TAbGzipArchive(FArchive).IsGzippedTar := (ArcType = atGZippedTar);\n      end;\n\n      atBzip2, atBzippedTar : begin\n        FArchive := TAbBzip2Archive.CreateFromStream(aValue, '');\n        TAbBzip2Archive(FArchive).TarAutoHandle := FTarAutoHandle;\n        TAbBzip2Archive(FArchive).IsBzippedTar := (ArcType = atBzippedTar);\n      end;\n\n      else\n        raise EAbUnhandledType.Create;\n    end {case};\n    InitArchive;\n    FArchive.Load;\n    FArchiveType := ArcType;\n  end;\n  DoChange;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbCustomZipBrowser.SetOnRequestBlankDisk(Value : TAbRequestDiskEvent);\nbegin\n  FOnRequestBlankDisk := Value;\n  if FArchive is TAbZipArchive then\n    TAbZipArchive(FArchive).OnRequestBlankDisk := FOnRequestBlankDisk;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbCustomZipBrowser.SetOnRequestLastDisk(Value : TAbRequestDiskEvent);\nbegin\n  FOnRequestLastDisk := Value;\n  if FArchive is TAbZipArchive then\n    TAbZipArchive(FArchive).OnRequestLastDisk := FOnRequestLastDisk;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbCustomZipBrowser.SetOnRequestNthDisk(Value : TAbRequestNthDiskEvent);\nbegin\n  FOnRequestNthDisk := Value;\n  if FArchive is TAbZipArchive then\n    TAbZipArchive(FArchive).OnRequestNthDisk := FOnRequestNthDisk;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbCustomZipBrowser.SetPassword(const Value : AnsiString);\nbegin\n  FPassword := Value;\n  if FArchive is TAbZipArchive then\n    TAbZipArchive(FArchive).Password := Value;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbCustomZipBrowser.SetTarAutoHandle(const Value: Boolean);\nbegin\n  FTarAutoHandle := Value;\n\n  if FArchive is TAbGzipArchive then begin\n    if TAbGzipArchive(FArchive).TarAutoHandle <> Value then begin\n      TAbGzipArchive(FArchive).TarAutoHandle := Value;\n      InitArchive;\n      FArchive.Load;\n      DoChange;\n    end;\n  end;\n  if FArchive is TAbBzip2Archive then begin\n    if TAbBzip2Archive(FArchive).TarAutoHandle <> Value then begin\n      TAbBzip2Archive(FArchive).TarAutoHandle := Value;\n      InitArchive;\n      FArchive.Load;\n      DoChange;\n    end;\n  end;\nend;\n\nprocedure TAbCustomZipBrowser.SetZipfileComment(const Value : AnsiString);\nbegin\n  {NOP - descendents wishing to set this property should override}\nend;\n{ -------------------------------------------------------------------------- }\n\nend.\n"
  },
  {
    "path": "lib/abbrevia/source/AbZLTyp.pas",
    "content": "(* ***** BEGIN LICENSE BLOCK *****\n * Version: MPL 1.1\n *\n * The contents of this file are subject to the Mozilla Public License Version\n * 1.1 (the \"License\"); you may not use this file except in compliance with\n * the License. You may obtain a copy of the License at\n * http://www.mozilla.org/MPL/\n *\n * Software distributed under the License is distributed on an \"AS IS\" basis,\n * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License\n * for the specific language governing rights and limitations under the\n * License.\n *\n * The Original Code is TurboPower Abbrevia\n *\n * The Initial Developer of the Original Code is\n * TurboPower Software\n *\n * Portions created by the Initial Developer are Copyright (C) 1997-2002\n * the Initial Developer. All Rights Reserved.\n *\n * Contributor(s):\n *\n * ***** END LICENSE BLOCK ***** *)\n\n{*********************************************************}\n{* ABBREVIA: AbZLTyp.pas                                 *}\n{*********************************************************}\n{* ABBREVIA: TAbZlItem class                             *}\n{*********************************************************}\n{* Misc. constants, types, and routines for working      *}\n{* with ZLib compressed data                             *}\n{* See: RFC 1950                                         *}\n{* \"ZLIB Compressed Data Format Specification            *}\n{*  version 3.3\" for more information on ZLib            *}\n{*********************************************************}\n\nunit AbZLTyp;\n\n{$I AbDefine.inc}\n\ninterface\n\nuses\n  SysUtils, Classes, AbUtils, AbArcTyp, AbZipPrc, AbDfBase, AbDfDec, AbDfEnc;\n\nconst\n  AB_ZL_PRESET_DICT = $20;\n\n  AB_ZL_DEF_COMPRESSIONMETHOD = $8;  { Deflate }\n  AB_ZL_DEF_COMPRESSIONINFO   = $7;  { 32k window for Deflate }\n\n  AB_ZL_FASTEST_COMPRESSION = $0;\n  AB_ZL_FAST_COMPRESSION    = $1;\n  AB_ZL_DEFAULT_COMPRESSION = $2;\n  AB_ZL_MAXIMUM_COMPRESSION = $3;\n\n  AB_ZL_FCHECK_MASK         = $1F;\n  AB_ZL_CINFO_MASK          = $F0; { mask out leftmost 4 bits }\n  AB_ZL_FLEVEL_MASK         = $C0; { mask out leftmost 2 bits }\n  AB_ZL_CM_MASK             = $0F; { mask out rightmost 4 bits }\n\n\ntype\n  TAbZLHeader = packed record\n    CMF : Byte;\n    FLG : Byte;\n  end;\n\n  TAbZLItem = class(TAbArchiveItem)\n  private\n    function GetCompressionInfo: Byte;\n    function GetCompressionLevel: Byte;\n    function GetIsPresetDictionaryPresent: Boolean;\n    procedure SetCompressionInfo(Value: Byte);\n    procedure SetCompressionLevel(Value: Byte);\n    function GetCompressionMethod: Byte;\n    procedure SetCompressionMethod(Value: Byte);\n    function GetFCheck: Byte;\n    procedure MakeFCheck;\n  protected { private }\n    FZLHeader : TAbZlHeader;\n    FAdler32  : LongInt;\n  public\n    constructor Create;\n\n    property IsPresetDictionaryPresent : Boolean\n      read GetIsPresetDictionaryPresent;\n    property CompressionLevel : Byte\n      read GetCompressionLevel write SetCompressionLevel;\n    property CompressionInfo : Byte\n      read GetCompressionInfo write SetCompressionInfo;\n\n    property CompressionMethod : Byte\n      read GetCompressionMethod write SetCompressionMethod;\n    property Adler32 : LongInt\n      read FAdler32 write FAdler32;\n\n    property FCheck : Byte\n      read GetFCheck;\n\n    procedure SaveZLHeaderToStream(AStream : TStream);\n    procedure ReadZLHeaderFromStream(AStream : TStream);\n  end;\n\n  TAbZLStreamHelper = class(TAbArchiveStreamHelper)\n  protected { private }\n    FItem : TAbZLItem;\n  public\n    constructor Create(AStream : TStream);\n    destructor Destroy; override;\n\n    property Item : TAbZLItem\n      read FItem;\n\n    procedure ExtractItemData(AStream : TStream); override;\n    function FindFirstItem : Boolean; override;\n    function FindNextItem : Boolean; override;\n    procedure ReadHeader; override;\n    procedure ReadTail; override;\n    function SeekItem(Index : Integer): Boolean; override;\n    procedure WriteArchiveHeader; override;\n    procedure WriteArchiveItem(AStream : TStream); override;\n    procedure WriteArchiveTail; override;\n    function GetItemCount : Integer; override;\n  end;\n\n\nimplementation\n\n{ TAbZLStreamHelper }\n\nconstructor TAbZLStreamHelper.Create(AStream: TStream);\nbegin\n  inherited Create(AStream);\n  FItem := TAbZLItem.Create;\nend;\n\ndestructor TAbZLStreamHelper.Destroy;\nbegin\n  FItem.Free;\n  inherited Destroy;\nend;\n\nprocedure TAbZLStreamHelper.ExtractItemData(AStream: TStream);\n{ assumes already positioned appropriately }\nvar\n  Hlpr : TAbDeflateHelper;\nbegin\n  Hlpr := TAbDeflateHelper.Create;\n  Hlpr.Options := Hlpr.Options or dfc_UseAdler32;\n  if not FItem.IsPresetDictionaryPresent then\n    Inflate(FStream, AStream, Hlpr)\n  else\n    raise Exception.Create('preset dictionaries unsupported');\n  Hlpr.Free;\nend;\n\nfunction TAbZLStreamHelper.FindFirstItem: Boolean;\nvar\n  ZLH : TAbZLHeader;\nbegin\n  FStream.Seek(0, soBeginning);\n  Result := FStream.Read(ZLH, SizeOf(TAbZLHeader)) = SizeOf(TAbZLHeader);\n  FItem.FZLHeader := ZLH;\n  FStream.Seek(0, soBeginning);\nend;\n\nfunction TAbZLStreamHelper.FindNextItem: Boolean;\nbegin\n  { only one item in a ZLib Stream }\n  Result := FindFirstItem;\nend;\n\nfunction TAbZLStreamHelper.GetItemCount: Integer;\nbegin\n  { only one item in a ZLib Stream }\n  Result := 1;\nend;\n\nprocedure TAbZLStreamHelper.ReadHeader;\n{ assumes already positioned appropriately }\nvar\n  ZLH : TAbZLHeader;\nbegin\n  FStream.Read(ZLH, SizeOf(TAbZlHeader));\n  FItem.FZLHeader := ZLH;\nend;\n\nprocedure TAbZLStreamHelper.ReadTail;\n{ assumes already positioned appropriately }\nvar\n  Adler: LongInt;\nbegin\n  FStream.Read(Adler, SizeOf(LongInt));\n  FItem.Adler32 := Adler;\nend;\n\nfunction TAbZLStreamHelper.SeekItem(Index: Integer): Boolean;\nbegin\n  { only one item in a ZLib Stream }\n  if Index <> 1 then\n    Result := False\n  else\n    Result := FindFirstItem;\nend;\n\nprocedure TAbZLStreamHelper.WriteArchiveHeader;\nbegin\n  Item.SaveZLHeaderToStream(FStream);\nend;\n\nprocedure TAbZLStreamHelper.WriteArchiveItem(AStream: TStream);\nvar\n  Hlpr : TAbDeflateHelper;\nbegin\n  { Compress file }\n  Hlpr := TAbDeflateHelper.Create;\n  Hlpr.Options := Hlpr.Options or dfc_UseAdler32;\n  Item.Adler32 := AbDfEnc.Deflate(AStream, FStream, Hlpr);\n  Hlpr.Free;\nend;\n\nprocedure TAbZLStreamHelper.WriteArchiveTail;\nvar\n  Ad32 : LongInt;\nbegin\n  Ad32 := AbSwapLongEndianness(Item.Adler32);\n  FStream.Write(Ad32, SizeOf(LongInt));\nend;\n\n{ TAbZLItem }\n\nconstructor TAbZLItem.Create;\nbegin\n  { Set default Values for fields }\n  FillChar(FZLHeader, SizeOf(TAbZlHeader), #0);\n  FZLHeader.CMF := (AB_ZL_DEF_COMPRESSIONINFO shl 4); { 32k Window size }\n  FZLHeader.CMF := FZLHeader.CMF or AB_ZL_DEF_COMPRESSIONMETHOD; { Deflate }\n  FZLHeader.FLG := FZLHeader.FLG and not AB_ZL_PRESET_DICT; { no preset dictionary}\n  FZLHeader.FLG := FZLHeader.FLG or (AB_ZL_DEFAULT_COMPRESSION shl 6); { assume default compression }\n  MakeFCheck;\nend;\n\nfunction TAbZLItem.GetCompressionInfo: Byte;\nbegin\n  Result := FZLHeader.CMF shr 4;\nend;\n\nfunction TAbZLItem.GetCompressionLevel: Byte;\nbegin\n  Result := FZLHeader.FLG shr 6;\nend;\n\nfunction TAbZLItem.GetCompressionMethod: Byte;\nbegin\n  Result := FZLHeader.CMF and AB_ZL_CM_MASK;\nend;\n\nfunction TAbZLItem.GetFCheck: Byte;\nbegin\n  Result := FZLHeader.FLG and AB_ZL_FCHECK_MASK;\nend;\n\nfunction TAbZLItem.GetIsPresetDictionaryPresent: Boolean;\nbegin\n  Result := (FZLHeader.FLG and AB_ZL_PRESET_DICT) = AB_ZL_PRESET_DICT;\nend;\n\nprocedure TAbZLItem.MakeFCheck;\n{ create the FCheck value for the current Header }\nvar\n  zlh : Word;\nbegin\n  FZLHeader.FLG := FZLHeader.FLG and not AB_ZL_FCHECK_MASK;\n  zlh := (FZLHeader.CMF * 256) + FZLHeader.FLG;\n  Inc(FZLHeader.FLG, 31 - (zlh mod 31));\nend;\n\nprocedure TAbZLItem.ReadZLHeaderFromStream(AStream: TStream);\nbegin\n  AStream.Read(FZLHeader, SizeOf(TAbZLHeader));\nend;\n\nprocedure TAbZLItem.SaveZLHeaderToStream(AStream: TStream);\nbegin\n  MakeFCheck;\n  AStream.Write(FZLHeader, SizeOf(TAbZlHeader));\nend;\n\nprocedure TAbZLItem.SetCompressionInfo(Value: Byte);\nbegin\n  FZLHeader.CMF := FZLHeader.CMF and not AB_ZL_CINFO_MASK;\n  FZLHeader.CMF := FZLHeader.CMF or (Value shl 4); { shift value and add to bit field }\nend;\n\nprocedure TAbZLItem.SetCompressionLevel(Value: Byte);\nvar\n  Temp : Byte;\nbegin\n  Temp := Value;\n  if not Temp in [AB_ZL_FASTEST_COMPRESSION..AB_ZL_MAXIMUM_COMPRESSION] then\n    Temp := AB_ZL_DEFAULT_COMPRESSION;\n  FZLHeader.FLG := FZLHeader.FLG and not AB_ZL_FLEVEL_MASK;\n  FZLHeader.FLG := FZLHeader.FLG or (Temp shl 6); { shift value and add to bit field }\nend;\n\nprocedure TAbZLItem.SetCompressionMethod(Value: Byte);\nbegin\n  if Value > AB_ZL_CM_MASK then Value := (Value shl 4) shr 4;\n  FZLHeader.CMF := FZLHeader.CMF and not AB_ZL_CM_MASK;\n  FZLHeader.CMF := FZLHeader.CMF or Value;\nend;\n\nend.\n"
  },
  {
    "path": "lib/abbrevia/source/AbZView.pas",
    "content": "(* ***** BEGIN LICENSE BLOCK *****\n * Version: MPL 1.1\n *\n * The contents of this file are subject to the Mozilla Public License Version\n * 1.1 (the \"License\"); you may not use this file except in compliance with\n * the License. You may obtain a copy of the License at\n * http://www.mozilla.org/MPL/\n *\n * Software distributed under the License is distributed on an \"AS IS\" basis,\n * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License\n * for the specific language governing rights and limitations under the\n * License.\n *\n * The Original Code is TurboPower Abbrevia\n *\n * The Initial Developer of the Original Code is\n * TurboPower Software\n *\n * Portions created by the Initial Developer are Copyright (C) 1997-2002\n * the Initial Developer. All Rights Reserved.\n *\n * Contributor(s):\n *\n * ***** END LICENSE BLOCK ***** *)\n\n{*********************************************************}\n{* ABBREVIA: AbZView.pas                                 *}\n{*********************************************************}\n{* ABBREVIA: Zip archive viewer component                *}\n{*   Use AbQZView.pas for CLX                            *}\n{*********************************************************}\n\n{$IFNDEF UsingCLX}\nunit AbZView;\n{$ENDIF}\n\n{$I AbDefine.inc}\n\ninterface\n\nuses\n  Classes,\n{$IFDEF MSWINDOWS}\n  Windows,\n{$ENDIF}\n{$IFDEF UsingCLX }\n  QControls,\n  AbQView,\n{$ELSE}\n  Controls,\n  AbView,\n{$ENDIF}\n  AbZBrows,\n  AbZipTyp;\n\ntype\n  TAbIncludeItemEvent = procedure (Sender:  TObject;\n                                   Item:    TAbZipItem;\n                               var Include: Boolean) of object;\n\n  TAbZipView = class(TAbBaseViewer)\n  protected\n    FZipComponent : TAbCustomZipBrowser;\n    FOnIncludeItem: TAbIncludeItemEvent;\n\n    function GetItem(RowNum : Longint) : TAbZipItem;\n    procedure SetZipComponent(Value : TAbCustomZipBrowser);\n    procedure Notification(AComponent : TComponent; Operation : TOperation);\n      override;\n    procedure DoChange(Sender : TObject);\n      override;\n  public\n    property Items[RowNum : Longint] : TAbZipItem\n      read GetItem;\n  published {properties}\n    property Align;\n    property Anchors;\n    property Attributes;\n{$IFNDEF UsingCLX}\n    property BevelEdges;\n    property BevelInner;\n    property BevelKind;\n    property BevelOuter;\n    property BevelWidth;\n{$ENDIF}\t\n    property BorderStyle;\n    property Color;\n    property Colors;\n{$IFNDEF UsingCLX}\n    property Ctl3D;\n    property ParentCtl3D;\n    property DragCursor;\n{$ENDIF}\n    property Cursor;\n    property Headings;\n    property DefaultColWidth;\n    property DefaultRowHeight;\n    property DisplayOptions;\n    property HeaderRowHeight;\n    property SortAttributes;\n    property DragMode;\n{$IFDEF HasGridDrawingStyle}\n    property DrawingStyle;\n{$ENDIF}\n    property Enabled;\n    property Font;\n{$IFDEF HasGridDrawingStyle}\n    property GradientEndColor;\n    property GradientStartColor;\n{$ENDIF}\n    property ParentColor;\n    property ParentFont;\n    property ParentShowHint;\n    property PopupMenu;\n    property ShowHint;\n    property TabOrder;\n    property TabStop;\n{$IFDEF HasTouch}\n    property Touch;\n{$ENDIF}\n    property Version;\n    property ZipComponent : TAbCustomZipBrowser\n      read FZipComponent write SetZipComponent;\n  published {Events}\n    property OnChange;\n    property OnClick;\n    property OnDblClick;\n    property OnEnter;\n    property OnExit;\n{$IFDEF HasTouch}\n    property OnGesture;\n{$ENDIF}\n    property OnKeyDown;\n    property OnKeyPress;\n    property OnKeyUp;\n{$IFDEF HasOnMouseActivate}\n    property OnMouseActivate;\n{$ENDIF}\n    property OnMouseDown;\n{$IFDEF HasOnMouseEnter}\n    property OnMouseEnter;\n    property OnMouseLeave;\n{$ENDIF}\n    property OnMouseMove;\n    property OnMouseUp;\n    property OnSorted;\n    property OnDrawSortArrow;\n\n    property OnIncludeItem: TAbIncludeItemEvent\n      read FOnIncludeItem\n      write FOnIncludeItem;\nend;\n\nimplementation\n\nuses\n  AbArcTyp;\n\n{ ===== TAbZipView ========================================================= }\nfunction TAbZipView.GetItem(RowNum : Longint) : TAbZipItem;\nbegin\n  if Assigned(FItemList) then\n    Result := TAbZipItem(FItemList.Items[FRowMap[RowNum]])\n  else\n    Result := nil;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbZipView.Notification(AComponent : TComponent; Operation : TOperation);\nbegin\n  inherited Notification(AComponent, Operation);\n  if Operation = opRemove then\n    if Assigned(FZipComponent) and (AComponent = FZipComponent) then begin\n      FZipComponent := nil;\n      Refresh;\n    end;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbZipView.SetZipComponent(Value : TAbCustomZipBrowser);\nbegin\n  if Value <> nil then begin\n    FZipComponent := Value;\n\n    if not (csDesigning in ComponentState) then begin\n      FZipComponent.OnChange := DoChange;\n      FZipComponent.OnLoad := DoLoad;\n      DoChange(Self);\n    end;\n  end\n  else\n    FZipComponent := nil;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbZipView.DoChange(Sender : TObject);\nvar\n  i : Integer;\n  TheArchive : TAbArchive;\n  Include : Boolean;\nbegin\n  FItemList.Clear;\n  if Assigned(FZipComponent) then begin\n    { let's make this a bit easier to read }\n    TheArchive := FZipComponent.FArchive;\n\n    if Assigned(TheArchive) then begin\n      for i := 0 to Pred(TheArchive.ItemList.Count) do begin\n        if Assigned(FOnIncludeItem) then begin\n          FOnIncludeItem(self, TAbZipItem(TheArchive.ItemList[i]), Include);\n          if Include then\n            FItemList.Add(TheArchive.ItemList[i]);\n        end\n        else begin\n        { if it doesn't look like a folder place holder... }\n        if TAbZipItem(TheArchive.ItemList[i]).DiskFileName <>\n           TAbZipItem(TheArchive.ItemList[i]).DiskPath then\n            { ...add it to the display list }\n            FItemList.Add(TheArchive.ItemList[i]);\n        end;\n      end;\n    end\n    else\n      FItemList.Clear;\n  end\n  else\n    FItemList.Clear;\n  inherited DoChange(Sender);\nend;\n\nend.\n\n"
  },
  {
    "path": "lib/abbrevia/source/AbZipExt.pas",
    "content": "(* ***** BEGIN LICENSE BLOCK *****\n * Version: MPL 1.1\n *\n * The contents of this file are subject to the Mozilla Public License Version\n * 1.1 (the \"License\"); you may not use this file except in compliance with\n * the License. You may obtain a copy of the License at\n * http://www.mozilla.org/MPL/\n *\n * Software distributed under the License is distributed on an \"AS IS\" basis,\n * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License\n * for the specific language governing rights and limitations under the\n * License.\n *\n * The Original Code is TurboPower Abbrevia\n *\n * The Initial Developer of the Original Code is\n * TurboPower Software\n *\n * Portions created by the Initial Developer are Copyright (C) 1997-2002\n * the Initial Developer. All Rights Reserved.\n *\n * Contributor(s):\n *\n * ***** END LICENSE BLOCK ***** *)\n\n{*********************************************************}\n{* ABBREVIA: AbZipExt.pas                                *}\n{*********************************************************}\n{* ABBREVIA: Zip file registration                       *}\n{*********************************************************}\n\nunit AbZipExt;\n\n{$I AbDefine.inc}\n\ninterface\n\nuses\n  SysUtils, Classes;\n\nfunction AbExistingZipAssociation : Boolean;\nfunction AbGetZipAssociation(var App, ID, FileType : string) : Boolean;\nfunction AbRegisterZipExtension(const App : string;\n                                      ID, FileType : string;\n                                      Replace : Boolean) : Boolean;\n\n\nimplementation\n\nuses\n{$IFDEF MSWINDOWS}\n  Windows,\n  Messages,\n  Registry,\n  ShellAPI,\n{$ENDIF}\n{$IFDEF LibcAPI}\n  Libc,\n{$ENDIF}\n  AbConst;\n\nconst\n  ZipExt     = '.zip';\n  DefZipID      = 'Zip';\n  DefZipType    = 'Zip File';\n  OpenCommand = 'Shell\\Open\\Command';\n  DefaultIcon = 'DefaultIcon';\n\nvar\n  Reg  : TRegistry;\n\n{ -------------------------------------------------------------------------- }\nfunction AbExistingZipAssociation : Boolean;\nvar\n  App, ID, FileType : string;\nbegin\n  Result := False;\n  Reg := TRegistry.Create;\n  Reg.RootKey := HKEY_CLASSES_ROOT;\n  Reg.OpenKey('',False);\n  if Reg.OpenKey(ZipExt, False) then begin\n    ID := Reg.ReadString('');\n    if Reg.OpenKey('\\' + ID, False) then begin\n      FileType := Reg.ReadString('');\n      if Reg.OpenKey(OpenCommand, False) then begin\n        App := Reg.ReadString('');\n        if (App <> '') then\n          Result := True;\n      end;\n    end;\n  end;\n  Reg.Free;\nend;\n{ -------------------------------------------------------------------------- }\nfunction AbGetZipAssociation(var App, ID, FileType : string) : Boolean;\nbegin\n  Result := False;\n  Reg := TRegistry.Create;\n  Reg.RootKey := HKEY_CLASSES_ROOT;\n  Reg.OpenKey('',False);\n  if Reg.OpenKey(ZipExt, False) then begin\n    ID := Reg.ReadString('');\n    if Reg.OpenKey('\\' + ID, False) then begin\n      FileType := Reg.ReadString('');\n      if Reg.OpenKey(OpenCommand, False) then begin\n        App := Reg.ReadString('');\n        Result := True;\n      end;\n    end;\n  end;\n  Reg.Free;\nend;\n{ -------------------------------------------------------------------------- }\nfunction AbRegisterZipExtension(const App : string;\n                                      ID, FileType : string;\n                                      Replace : Boolean) : Boolean;\nbegin\n  Result := False;\n  if AbExistingZipAssociation and not Replace then\n    Exit;\n  try\n    if (ID = '') then\n      ID := DefZipID;\n    if (FileType = '') then\n      FileType := DefZipType;\n    Reg := TRegistry.Create;\n    Reg.RootKey := HKEY_CLASSES_ROOT;\n    Reg.OpenKey('',False);\n    Reg.OpenKey(ZipExt, True);\n    Reg.WriteString('', ID);\n    Reg.OpenKey('\\' + ID, True);\n    Reg.WriteString('', FileType);\n    Reg.OpenKey(OpenCommand, True);\n    Reg.WriteString('', App);\n    Reg.OpenKey('\\' + DefaultIcon, True);\n    Reg.WriteString('', App + ',0');\n    Result := True;\n  finally\n    Reg.Free;\n  end;\nend;\n{ -------------------------------------------------------------------------- }\n\nend.\n"
  },
  {
    "path": "lib/abbrevia/source/AbZipKit.pas",
    "content": "(* ***** BEGIN LICENSE BLOCK *****\n * Version: MPL 1.1\n *\n * The contents of this file are subject to the Mozilla Public License Version\n * 1.1 (the \"License\"); you may not use this file except in compliance with\n * the License. You may obtain a copy of the License at\n * http://www.mozilla.org/MPL/\n *\n * Software distributed under the License is distributed on an \"AS IS\" basis,\n * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License\n * for the specific language governing rights and limitations under the\n * License.\n *\n * The Original Code is TurboPower Abbrevia\n *\n * The Initial Developer of the Original Code is\n * TurboPower Software\n *\n * Portions created by the Initial Developer are Copyright (C) 1997-2002\n * the Initial Developer. All Rights Reserved.\n *\n * Contributor(s):\n *\n * ***** END LICENSE BLOCK ***** *)\n\n{*********************************************************}\n{* ABBREVIA: AbZipKit.pas                                *}\n{*********************************************************}\n{* ABBREVIA: TABZipKit component                         *}\n{*********************************************************}\n\nunit AbZipKit;\n\n{$I AbDefine.inc}\n\ninterface\n\nuses\n  Classes, AbZipper, AbArcTyp, AbZipTyp;\n\ntype\n  TAbCustomZipKit = class(TAbCustomZipper)\n  protected {private}\n    FExtractOptions : TAbExtractOptions;\n    FOnConfirmOverwrite : TAbConfirmOverwriteEvent;\n    FOnNeedPassword : TAbNeedPasswordEvent;\n    FPasswordRetries : Byte;\n\n  protected {methods}\n    procedure DoConfirmOverwrite(var Name : string; var Confirm : Boolean);\n      virtual;\n    procedure DoNeedPassword(Sender : TObject; var NewPassword : AnsiString);\n      virtual;\n    procedure InitArchive;\n      override;\n    procedure SetExtractOptions(Value : TAbExtractOptions);\n    procedure SetPasswordRetries(Value : Byte);\n    procedure UnzipProc(Sender : TObject; Item : TAbArchiveItem;\n                        const NewName : string );\n    procedure UnzipToStreamProc(Sender : TObject; Item : TAbArchiveItem;\n                                OutStream : TStream);\n    procedure TestItemProc(Sender : TObject; Item : TAbArchiveItem);\n\n  protected {properties}\n    property ExtractOptions : TAbExtractOptions\n      read  FExtractOptions\n      write SetExtractOptions\n      default AbDefExtractOptions;\n    property PasswordRetries : Byte\n      read  FPasswordRetries\n      write SetPasswordRetries\n      default AbDefPasswordRetries;\n\n  protected {events}\n    property OnConfirmOverwrite : TAbConfirmOverwriteEvent\n      read  FOnConfirmOverwrite\n      write FOnConfirmOverwrite;\n    property OnNeedPassword : TAbNeedPasswordEvent\n      read  FOnNeedPassword\n      write FOnNeedPassword;\n\n  public {methods}\n    constructor Create(AOwner : TComponent);\n      override;\n    destructor Destroy;\n      override;\n    procedure ExtractAt(Index : Integer; const NewName : string);\n    procedure ExtractFiles(const FileMask : string);\n      {extract all files from the archive that match the mask}\n    procedure ExtractFilesEx(const FileMask, ExclusionMask : string);\n      {extract files matching FileMask except those matching ExclusionMask}\n    procedure ExtractTaggedItems;\n      {extract all tagged items from the archive}\n    procedure ExtractToStream(const aFileName : string; ToStream : TStream);\n      {extract the specified item to TStream descendant}\n    procedure TestTaggedItems;\n      {test all tagged items in the archive}\n\n  public {property}\n    property Spanned;\n  end;\n\n  TAbZipKit = class(TAbCustomZipKit)\n  published\n    property ArchiveProgressMeter;\n    property ArchiveSaveProgressMeter;\n    property AutoSave;\n    property BaseDirectory;\n    property CompressionMethodToUse;\n    property DeflationOption;\n    {$IFDEF MSWINDOWS}\n    property DOSMode;\n    {$ENDIF}\n    property ExtractOptions;\n    property SpanningThreshold;\n    property ItemProgressMeter;\n    property LogFile;\n    property Logging;\n    property OnArchiveProgress;\n    property OnArchiveSaveProgress;\n    property OnArchiveItemProgress;\n    property OnChange;\n    property OnConfirmOverwrite;\n    property OnConfirmProcessItem;\n    property OnConfirmSave;\n    property OnLoad;\n    property OnNeedPassword;\n    property OnProcessItemFailure;\n    property OnRequestBlankDisk;\n    property OnRequestImage;\n    property OnRequestLastDisk;\n    property OnRequestNthDisk;\n    property OnSave;\n    property Password;\n    property PasswordRetries;\n    property StoreOptions;\n    property TempDirectory;\n    property Version;\n    property FileName; {must be after OnLoad}\n  end;\n\n\nimplementation\n\nuses\n  AbExcept,\n  AbUnzPrc,\n  AbZBrows;\n\n{ -------------------------------------------------------------------------- }\nconstructor TAbCustomZipKit.Create( AOwner : TComponent );\nbegin\n  inherited Create( AOwner );\n  PasswordRetries := AbDefPasswordRetries;\nend;\n{ -------------------------------------------------------------------------- }\ndestructor TAbCustomZipKit.Destroy;\nbegin\n  inherited Destroy;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbCustomZipKit.DoConfirmOverwrite( var Name : string;\n                                        var Confirm : Boolean );\nbegin\n  Confirm := True;\n  if Assigned( FOnConfirmOverwrite ) then\n    FOnConfirmOverwrite( Name, Confirm );\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbCustomZipKit.DoNeedPassword( Sender : TObject;\n                                    var NewPassword : AnsiString );\nbegin\n  if Assigned( FOnNeedPassword ) then begin\n    FOnNeedPassword( Self, NewPassword );\n    FPassword := NewPassword;\n  end;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbCustomZipKit.ExtractAt(Index : Integer; const NewName : string);\n  {extract a file from the archive that match the index}\nbegin\n  if (FArchive <> nil) then\n    FArchive.ExtractAt( Index, NewName )\n  else\n    raise EAbNoArchive.Create;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbCustomZipKit.ExtractFiles(const FileMask : string);\n  {extract all files from the archive that match the mask}\nbegin\n  if (FArchive <> nil) then\n    FArchive.ExtractFiles( FileMask )\n  else\n    raise EAbNoArchive.Create;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbCustomZipKit.ExtractFilesEx(const FileMask, ExclusionMask : string);\n  {extract files matching FileMask except those matching ExclusionMask}\nbegin\n  if (FArchive <> nil) then\n    FArchive.ExtractFilesEx( FileMask, ExclusionMask )\n  else\n    raise EAbNoArchive.Create;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbCustomZipKit.ExtractTaggedItems;\n  {extract all tagged items from the archive}\nbegin\n  if (FArchive <> nil) then\n    FArchive.ExtractTaggedItems\n  else\n    raise EAbNoArchive.Create;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbCustomZipKit.ExtractToStream(const aFileName : string;\n                                          ToStream : TStream);\nbegin\n  if (FArchive <> nil) then\n    FArchive.ExtractToStream(aFileName, ToStream)\n  else\n    raise EAbNoArchive.Create;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbCustomZipKit.InitArchive;                                 \nbegin\n  inherited InitArchive;\n  if (FArchive <> nil) then begin\n    FArchive.ExtractOptions                       := FExtractOptions;\n    FArchive.OnConfirmOverwrite                   := DoConfirmOverwrite;\n  end;\n  if FArchive is TAbZipArchive then begin\n    {properties}\n    TAbZipArchive(FArchive).PasswordRetries       := FPasswordRetries;\n    {events}\n    TAbZipArchive(FArchive).OnNeedPassword        := DoNeedPassword;\n    TAbZipArchive(FArchive).ExtractHelper         := UnzipProc;\n    TAbZipArchive(FArchive).ExtractToStreamHelper := UnzipToStreamProc;\n    TAbZipArchive(FArchive).TestHelper            := TestItemProc;\n  end;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbCustomZipKit.SetExtractOptions( Value : TAbExtractOptions );\nbegin\n  FExtractOptions := Value;\n  if (FArchive <> nil) then\n    FArchive.ExtractOptions := Value;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbCustomZipKit.SetPasswordRetries( Value : Byte );\nbegin\n  FPasswordRetries := Value;\n  if (FArchive <> nil) then\n    (FArchive as TAbZipArchive).PasswordRetries := Value;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbCustomZipKit.TestTaggedItems;\n  {test all tagged items in the archive}\nbegin\n  if (FArchive <> nil) then\n    FArchive.TestTaggedItems\n  else\n    raise EAbNoArchive.Create;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbCustomZipKit.UnzipProc( Sender : TObject; Item : TAbArchiveItem;\n  const NewName : string );\nbegin\n  AbUnzip( TAbZipArchive(Sender), TAbZipItem(Item), NewName);\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbCustomZipKit.UnzipToStreamProc(Sender : TObject; Item : TAbArchiveItem;\n  OutStream : TStream);\nbegin\n  AbUnzipToStream(TAbZipArchive(Sender), TAbZipItem(Item), OutStream);\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbCustomZipKit.TestItemProc(Sender : TObject; Item : TAbArchiveItem);\nbegin\n  AbTestZipItem(TAbZipArchive(Sender), TAbZipItem(Item));\nend;\n{ -------------------------------------------------------------------------- }\n\nend.\n\n"
  },
  {
    "path": "lib/abbrevia/source/AbZipOut.pas",
    "content": "(* ***** BEGIN LICENSE BLOCK *****\n * Version: MPL 1.1\n *\n * The contents of this file are subject to the Mozilla Public License Version\n * 1.1 (the \"License\"); you may not use this file except in compliance with\n * the License. You may obtain a copy of the License at\n * http://www.mozilla.org/MPL/\n *\n * Software distributed under the License is distributed on an \"AS IS\" basis,\n * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License\n * for the specific language governing rights and limitations under the\n * License.\n *\n * The Original Code is TurboPower Abbrevia\n *\n * The Initial Developer of the Original Code is\n * TurboPower Software\n *\n * Portions created by the Initial Developer are Copyright (C) 1997-2002\n * the Initial Developer. All Rights Reserved.\n *\n * Contributor(s):\n *\n * ***** END LICENSE BLOCK ***** *)\n\n{*********************************************************}\n{* ABBREVIA: AbZipOut.pas                                *}\n{*********************************************************}\n{* ABBREVIA: Visual Component with Zip and unzip support *}\n{*   Use AbQZpOut.pas for CLX                            *}\n{*********************************************************}\n\n{$IFNDEF UsingCLX}\nunit AbZipOut;\n{$ENDIF}\n\n{$I AbDefine.inc}\n\ninterface\n\nuses\n  Classes,\n{$IFDEF MSWINDOWS}\n  Windows,\n  Messages,\n{$ENDIF}\n  Types,\n{$IFDEF UsingCLX}\n  QGraphics,\n  QComCtrls,\n  QImglist,\n  QControls,\n  QForms,\n{$ELSE}\n  Graphics,\n  Controls,\n  Forms,\n  ComCtrls,\n  Imglist,\n{$ENDIF}\n  AbArcTyp,\n  AbBrowse,\n  AbUtils,\n  AbZipTyp;\n\n\nconst\n  cBitmapHeight = 16;\n  cBitmapWidth  = 16;\n\ntype\n  TAbZipAttribute =\n    (zaCompressedSize, zaCompressionMethod, zaCompressionRatio, zaCRC,\n     zaExternalFileAttributes, zaInternalFileAttributes, zaEncryption,\n     zaTimeStamp, zaUncompressedSize, zaVersionMade, zaVersionNeeded,\n     zaComment);\n\n  TAbZipAttributes = set of TAbZipAttribute;\n\nconst\n  AbDefZipAttributes =\n    [zaCompressedSize, zaCompressionMethod, zaCompressionRatio, zaCRC,\n     zaExternalFileAttributes, zaEncryption, zaTimeStamp, zaUncompressedSize];\n\n  AbDefColor = clWindow;\n  AbDefHierarchy = True;\n  AbDefParentColor = False;\n\n{.Z+}\ntype\n  TTreeNodeFriend = class(TTreeNode)\n  end;\n{.Z-}\n\ntype\n  TWindowsDropEvent =\n    procedure(Sender : TObject; FileName : string) of object;\n{TAbZipDisplayOutline does not support Owner-Draw}\ntype\n  TAbZipDisplayOutline = class(TTreeView)\n    private\n      FDirBitMap          : TBitMap;\n      FFileBitMap         : TBitMap;\n      FAttrBitMap         : TBitMap;\n      FDirBitMapSelected  : TBitMap;\n      FFileBitMapSelected : TBitMap;\n      FAttrBitMapSelected : TBitMap;\n      FImageList          : TImageList;\n      FFileIndex          : integer;\n      FFileSelectedIndex  : integer;\n      FDirectoryIndex     : integer;\n      FDirSelectedIndex   : integer;\n      FAttrIndex          : integer;\n      FBitMapHeight       : integer;\n      FBitMapWidth        : integer;\n      FAttrSelectedIndex  : integer;\n\n      FOnWindowsDrop   : TWindowsDropEvent;\n\n{$IFNDEF UsingCLX}\n      procedure WMDropFiles(var Msg : TWMDropFiles);\n        message WM_DROPFILES;\n{$ENDIF}\n\n      procedure IndexBitmaps;\n\n      procedure SetDirectoryBitMap(Value : TBitmap);\n      procedure SetFileBitMap(Value : TBitmap);\n      procedure SetAttributeBitMap(Value : TBitmap);\n      procedure SetDirectoryBitMapSelected(Value : TBitmap);\n      procedure SetFileBitMapSelected(Value : TBitmap);\n      procedure SetAttributeBitMapSelected(Value : TBitmap);\n      procedure SetBitMapHeight(Value : Integer);\n      procedure SetBitMapWidth(Value : Integer);\n\n    protected\n      procedure DoOnWindowsDrop(FileName : string); virtual;\n\n{$IFDEF UsingCLX}\n      function DoMouseWheel(Shift: TShiftState; WheelDelta: Integer;\n        const MousePos: TPoint): Boolean;\n        override;\n{$ELSE}\n      function DoMouseWheel(Shift: TShiftState; WheelDelta: Integer;\n        MousePos: TPoint): Boolean;\n        override;\n{$ENDIF}\n      procedure Loaded; override;\n      procedure SetOnWindowsDrop(Value : TWindowsDropEvent);\n    public\n      constructor Create(AOwner : TComponent); override;\n      destructor Destroy; override;\n    public\n      property zdPictureDirectory : TBitmap\n        read FDirBitMap\n        write SetDirectoryBitMap;\n      property zdPictureFile : TBitmap\n        read FFileBitMap\n        write SetFileBitMap;\n      property zdPictureZipAttribute : TBitmap\n        read FAttrBitMap\n        write SetAttributeBitMap;\n      property zdPictureDirectorySelected : TBitmap\n        read FDirBitMapSelected\n        write SetDirectoryBitMapSelected;\n      property zdPictureFileSelected : TBitmap\n        read FFileBitMapSelected\n        write SetFileBitMapSelected;\n      property zdPictureZipAttributeSelected : TBitmap\n        read FAttrBitMapSelected\n        write SetAttributeBitMapSelected;\n      property BitMapHeight : Integer\n        read FBitMapHeight\n        write SetBitMapHeight;\n      property BitMapWidth : Integer\n        read FBitMapWidth\n        write SetBitMapWidth;\n      property OnWindowsDrop : TWindowsDropEvent\n        read FOnWindowsDrop\n        write SetOnWindowsDrop;\n  end;\n\ntype\n{$IFDEF UsingClx}\n  TAbCustomZipOutline = class(TWidgetControl)\n{$ELSE}\n  TAbCustomZipOutline = class(TWinControl)\n{$ENDIF}\n  protected {private}\n    FArchive                : TAbZipArchive;\n    FItemProgressMeter      : IAbProgressMeter;\n    FArchiveProgressMeter   : IAbProgressMeter;\n    FAttributes             : TAbZipAttributes;\n    FAutoSave               : Boolean;\n    FBaseDirectory          : string;\n    FCompressionMethodToUse : TAbZipSupportedMethod;\n    FDeflationOption        : TAbZipDeflationOption;\n{$IFDEF MSWINDOWS}\n    FDOSMode                : Boolean;\n{$ENDIF}\n    FFileName               : string;\n    FExtractOptions         : TAbExtractOptions;\n    FHierarchy              : Boolean;\n    FLogFile                : string;\n    FLogging                : Boolean;\n    FSpanningThreshold      : Longint;\n    FOutline                : TAbZipDisplayOutline;\n    FPassword               : AnsiString;\n    FPasswordRetries        : Byte;\n    FStoreOptions           : TAbStoreOptions;\n    FTempDirectory          : string;\n\n    FOnProcessItemFailure   : TAbArchiveItemFailureEvent;\n    FOnArchiveItemProgress  : TAbArchiveItemProgressEvent;\n    FOnArchiveProgress      : TAbArchiveProgressEvent;\n    FOnChange               : TNotifyEvent;\n    FOnClick                : TNotifyEvent;\n    FOnCollapse             : TTVExpandedEvent;\n    FOnConfirmOverwrite     : TAbConfirmOverwriteEvent;\n    FOnConfirmProcessItem   : TAbArchiveItemConfirmEvent;\n    FOnConfirmSave          : TAbArchiveConfirmEvent;\n    FOnDblClick             : TNotifyEvent;\n    FOnDragDrop             : TDragDropEvent;\n    FOnDragOver             : TDragOverEvent;\n    FOnEndDrag              : TEndDragEvent;\n    FOnEnter                : TNotifyEvent;\n    FOnExit                 : TNotifyEvent;\n    FOnExpand               : TTVExpandedEvent;\n    FOnKeyDown              : TKeyEvent;\n    FOnKeyPress             : TKeyPressEvent;\n    FOnKeyUp                : TKeyEvent;\n    FOnLoad                 : TAbArchiveEvent;\n    FOnMouseDown            : TMouseEvent;\n    FOnMouseMove            : TMouseMoveEvent;\n    FOnMouseUp              : TMouseEvent;\n    FOnNeedPassword         : TAbNeedPasswordEvent;\n    FOnRequestImage         : TAbRequestImageEvent;\n    FOnRequestLastDisk      : TAbRequestDiskEvent;\n    FOnRequestNthDisk       : TAbRequestNthDiskEvent;\n    FOnRequestBlankDisk     : TAbRequestDiskEvent;\n    FOnSave                 : TAbArchiveEvent;\n{$IFDEF MSWINDOWS}\n    FOnStartDrag            : TStartDragEvent;\n{$ENDIF MSWINDOWS}\n    FOnWindowsDrop          : TWindowsDropEvent;\n\n  protected {methods}\n    procedure AddAttributeNodes(Item : TAbZipItem; oNode : TTreeNode);\n    procedure DoProcessItemFailure(Sender : TObject; Item : TAbArchiveItem;\n                                   ProcessType : TAbProcessType;\n                                   ErrorClass : TAbErrorClass;\n                                   ErrorCode : Integer); virtual;\n    procedure DoArchiveItemProgress(Sender : TObject; Item : TAbArchiveItem;\n                                    Progress : Byte; var Abort : Boolean); virtual;\n    procedure DoArchiveProgress(Sender : TObject; Progress : Byte;\n                                var Abort : Boolean); virtual;\n    procedure DoChange; virtual;\n    procedure DoClick(Sender : TObject); virtual;\n    procedure DoCollapse(Sender : TObject; Node: TTreeNode); virtual;\n    procedure DoConfirmProcessItem(Sender : TObject; Item : TAbArchiveItem;\n                                   ProcessType : TAbProcessType;\n                                   var Confirm : Boolean); virtual;\n    procedure DoConfirmOverwrite(var Name : string; var Confirm : Boolean); virtual;\n    procedure DoConfirmSave(Sender : TObject; var Confirm : Boolean); virtual;\n    procedure DoDblClick(Sender : TObject); virtual;\n    procedure DoDragDrop(Sender, Source: TObject; X, Y: Integer); virtual;\n    procedure DoDragOver(Sender, Source: TObject; X, Y: Integer;\n                         State: TDragState; var Accept: Boolean); virtual;\n    procedure DoOnEndDrag(Sender, Target: TObject; X, Y: Integer); virtual;\n    procedure DoOnEnter(Sender : TObject); virtual;\n    procedure DoOnExit(Sender : TObject); virtual;\n    procedure DoExpand(Sender: TObject; Node : TTreeNode); virtual;\n    procedure DoKeyDown(Sender : TObject; var Key: Word; Shift: TShiftState);\n                        virtual;\n    procedure DoKeyPress(Sender : TObject; var Key: Char); virtual;\n    procedure DoKeyUp(Sender : TObject; var Key: Word; Shift: TShiftState);\n                      virtual;\n    procedure DoLoad(Sender : TObject); virtual;\n    procedure DoMouseDown(Sender : TObject; Button: TMouseButton;\n                          Shift: TShiftState; X, Y : Integer); virtual;\n    procedure DoMouseMove(Sender : TObject; Shift: TShiftState; X, Y: Integer);\n                          virtual;\n    procedure DoMouseUp(Sender : TObject; Button: TMouseButton;\n                        Shift: TShiftState; X, Y: Integer); virtual;\n    procedure DoNeedPassword(Sender : TObject; var NewPassword : AnsiString);\n                             virtual;\n    procedure DoSave(Sender : TObject); virtual;\n{$IFDEF MSWINDOWS}\n    procedure DoOnStartDrag(Sender: TObject; var DragObject: TDragObject);\n                            virtual;\n{$ENDIF}\n    procedure DoWindowsDrop(Sender : TObject; FileName : string); virtual;\n    function GetBorderStyle : TBorderStyle;\n    function GetCount : Integer;\n    function GetCursor : TCursor;\n{$IFNDEF UsingCLX}\n    function GetDragCursor : TCursor;\n{$ENDIF}\n    function GetDragMode : TDragMode;\n    function GetItem(Index : Integer) : TAbZipItem;\n    function GetPictureDirectory : TBitmap;\n    function GetPictureFile : TBitmap;\n    function GetPictureZipAttribute: TBitmap;\n    function GetPictureDirectorySelected : TBitmap;\n    function GetPictureFileSelected : TBitmap;\n    function GetPictureZipAttributeSelected : TBitmap;\n    function GetPictureHeight : Integer;\n    function GetPictureWidth : Integer;\n    function GetSelectedItem : LongInt;\n    function GetSelectedZipItem : TAbZipItem;\n    function GetStatus : TAbArchiveStatus;\n    function GetVersion : string;\n    function GetZipfileComment : AnsiString;\n    procedure InitArchive;\n    procedure Loaded; override;\n    procedure Notification(Component: TComponent; Operation: TOperation);\n                           override;\n    procedure PutItem(Index : Integer; Value : TAbZipItem);\n    procedure SetArchiveProgressMeter(const Value: IAbProgressMeter);\n    procedure SetAttributes(Value : TAbZipAttributes);\n    procedure SetAutoSave(Value : Boolean);\n    procedure SetBaseDirectory(Value : string);\n    procedure SetBorderStyle(Value : TBorderStyle);\n    procedure SetCompressionMethodToUse(Value : TAbZipSupportedMethod);\n    procedure SetDeflationOption(Value : TAbZipDeflationOption);\n{$IFDEF MSWINDOWS}\n    procedure SetDOSMode(Value : Boolean);\n{$ENDIF}\n    procedure SetCursor(Value : TCursor);\n{$IFNDEF UsingCLX}\n    procedure SetDragCursor(Value : TCursor);\n{$ENDIF}\n{$IFNDEF UsingCLX}\n    procedure SetDragMode(Value : TDragMode); override;\n{$ENDIF}\n    procedure SetExtractOptions(Value : TAbExtractOptions);\n    procedure SetFileName(const aFileName : string); virtual;\n    procedure SetHierarchy(Value : Boolean);\n    procedure SetItemProgressMeter(const Value: IAbProgressMeter);\n    procedure SetLogFile(Value : string);\n    procedure SetLogging(Value : Boolean);\n    procedure SetOnRequestImage(Value : TAbRequestImageEvent);\n    procedure SetOnRequestLastDisk(Value : TAbRequestDiskEvent);\n    procedure SetOnRequestNthDisk(Value : TAbRequestNthDiskEvent);\n    procedure SetOnRequestBlankDisk(Value : TAbRequestDiskEvent);\n    procedure SetOnWindowsDrop(Value : TWindowsDropEvent);\n    procedure SetPassword(Value : AnsiString);\n    procedure SetPasswordRetries(Value : Byte);\n    procedure SetPictureDirectory(Value : TBitmap);\n    procedure SetPictureFile(Value : TBitmap);\n    procedure SetPictureZipAttribute(Value : TBitmap);\n    procedure SetPictureDirectorySelected(Value : TBitmap);\n    procedure SetPictureFileSelected(Value : TBitmap);\n    procedure SetPictureZipAttributeSelected(Value : TBitmap);\n    procedure SetPictureHeight(Value : Integer);\n    procedure SetPictureWidth(Value : Integer);\n    procedure SetSelectedItem(Value : LongInt);\n    procedure SetStoreOptions(Value : TAbStoreOptions);\n    procedure SetTempDirectory(Value : string);\n    procedure SetSpanningThreshold(Value : Longint);\n    procedure SetVersion(Value : string);\n    procedure SetZipfileComment(Value : AnsiString);\n    procedure TestItemProc(Sender : TObject; Item : TAbArchiveItem);\n    procedure UnzipProc(Sender : TObject; Item : TAbArchiveItem;\n                        const NewName : string);\n    procedure UnzipToStreamProc(Sender : TObject; Item : TAbArchiveItem;\n                                OutStream : TStream);\n    procedure UpdateOutline;\n    procedure ZipProc(Sender : TObject; Item : TAbArchiveItem;\n                      OutStream : TStream);\n    procedure ZipFromStreamProc(Sender : TObject; Item : TAbArchiveItem;\n                                OutStream, InStream : TStream);\n\n  protected {properties}\n    property ArchiveProgressMeter : IAbProgressMeter\n             read  FArchiveProgressMeter\n             write SetArchiveProgressMeter;\n    property Attributes : TAbZipAttributes\n             read  FAttributes\n             write SetAttributes\n             default AbDefZipAttributes;\n    property AutoSave : Boolean\n             read  FAutoSave\n             write SetAutoSave\n             default AbDefAutoSave;\n    property BaseDirectory : string\n             read  FBaseDirectory\n             write SetBaseDirectory;\n    property BorderStyle : TBorderStyle\n             read  GetBorderStyle\n             write SetBorderStyle;\n    property CompressionMethodToUse : TAbZipSupportedMethod\n             read  FCompressionMethodToUse\n             write SetCompressionMethodToUse\n             default AbDefCompressionMethodToUse;\n    property Cursor : TCursor\n             read  GetCursor\n             write SetCursor;\n    property DeflationOption : TAbZipDeflationOption\n             read  FDeflationOption\n             write SetDeflationOption\n             default AbDefDeflationOption;\n{$IFDEF MSWINDOWS}\n    property DOSMode : Boolean\n             read FDOSMode\n             write SetDOSMode;\n{$ENDIF}\n{$IFNDEF UsingCLX}\n    property DragCursor : TCursor\n             read  GetDragCursor\n             write SetDragCursor;\n    property DragMode : TDragMode\n             read  GetDragMode\n             write SetDragMode;\n{$ENDIF}\n    property ExtractOptions : TAbExtractOptions\n             read  FExtractOptions\n             write SetExtractOptions\n             default AbDefExtractOptions;\n    property FileName : string\n             read  FFileName\n             write SetFileName;\n    property Hierarchy : Boolean\n             read  FHierarchy\n             write SetHierarchy\n             default AbDefHierarchy;\n    property SpanningThreshold : Longint\n             read  FSpanningThreshold\n             write SetSpanningThreshold\n             default 0;\n    property ItemProgressMeter : IAbProgressMeter\n             read  FItemProgressMeter\n             write SetItemProgressMeter;\n    property LogFile : string\n             read  FLogFile\n             write SetLogFile;\n    property Logging : Boolean\n             read  FLogging\n             write SetLogging;\n    property OnWindowsDrop : TWindowsDropEvent\n             read  FOnWindowsDrop\n             write SetOnWindowsDrop;\n    property Password : AnsiString\n             read  FPassword\n             write SetPassword;\n    property PasswordRetries : Byte\n             read  FPasswordRetries\n             write SetPasswordRetries\n             default AbDefPasswordRetries;\n    property PictureDirectory : TBitmap\n             read  GetPictureDirectory\n             write SetPictureDirectory;\n    property PictureFile : TBitmap\n             read  GetPictureFile\n             write SetPictureFile;\n    property PictureZipAttribute : TBitmap\n             read  GetPictureZipAttribute\n             write SetPictureZipAttribute;\n    property PictureDirectorySelected : TBitmap\n             read  GetPictureDirectorySelected\n             write SetPictureDirectorySelected;\n    property PictureFileSelected : TBitmap\n             read  GetPictureFileSelected\n             write SetPictureFileSelected;\n    property PictureZipAttributeSelected : TBitmap\n             read  GetPictureZipAttributeSelected\n             write SetPictureZipAttributeSelected;\n    property PictureHeight : Integer\n             read  GetPictureHeight\n             write SetPictureHeight;\n    property PictureWidth : Integer\n             read  GetPictureWidth\n             write SetPictureWidth;\n    property StoreOptions : TAbStoreOptions\n             read  FStoreOptions\n             write SetStoreOptions\n             default AbDefStoreOptions;\n    property Version : string\n             read GetVersion\n             write SetVersion\n             stored False;\n\n  protected {events}\n    property OnProcessItemFailure : TAbArchiveItemFailureEvent\n             read  FOnProcessItemFailure\n             write FOnProcessItemFailure;\n    property OnArchiveItemProgress : TAbArchiveItemProgressEvent\n             read  FOnArchiveItemProgress\n             write FOnArchiveItemProgress;\n    property OnArchiveProgress : TAbArchiveProgressEvent\n             read  FOnArchiveProgress\n             write FOnArchiveProgress;\n    property OnChange : TNotifyEvent\n             read  FOnChange\n             write FOnChange;\n    property OnClick : TNotifyEvent\n             read  FOnClick\n             write FOnClick;\n    property OnConfirmProcessItem : TAbArchiveItemConfirmEvent\n             read  FOnConfirmProcessItem\n             write FOnConfirmProcessItem;\n    property OnConfirmOverwrite : TAbConfirmOverwriteEvent\n             read  FOnConfirmOverwrite\n             write FOnConfirmOverwrite;\n    property OnConfirmSave : TAbArchiveConfirmEvent\n             read  FOnConfirmSave\n             write FOnConfirmSave;\n    property OnCollapse : TTVExpandedEvent\n             read  FOnCollapse\n             write FOnCollapse;\n    property OnDblClick : TNotifyEvent\n             read  FOnDblClick\n             write FOnDblClick;\n    property OnDragDrop : TDragDropEvent\n             read FOnDragDrop\n             write FOnDragDrop;\n    property OnDragOver : TDragOverEvent\n             read  FOnDragOver\n             write FOnDragOver;\n    property OnEndDrag : TEndDragEvent\n             read  FOnEndDrag\n             write FOnEndDrag;\n    property OnEnter : TNotifyEvent\n             read  FOnEnter\n             write FOnEnter;\n    property OnExit : TNotifyEvent\n             read  FOnExit\n             write FOnExit;\n    property OnExpand : TTVExpandedEvent\n             read  FOnExpand\n             write FOnExpand;\n    property OnKeyDown : TKeyEvent\n             read  FOnKeyDown\n             write FOnKeyDown;\n    property OnKeyPress : TKeyPressEvent\n             read  FOnKeyPress\n             write FOnKeyPress;\n    property OnKeyUp : TKeyEvent\n             read  FOnKeyUp\n             write FOnKeyUp;\n    property OnLoad : TAbArchiveEvent\n             read  FOnLoad\n             write FOnLoad;\n    property OnMouseDown : TMouseEvent\n             read  FOnMouseDown\n             write FOnMouseDown;\n    property OnMouseMove : TMouseMoveEvent\n             read  FOnMouseMove\n             write FOnMouseMove;\n    property OnMouseUp : TMouseEvent\n             read  FOnMouseUp\n             write FOnMouseUp;\n    property OnNeedPassword : TAbNeedPasswordEvent\n             read  FOnNeedPassword\n             write FOnNeedPassword;\n    property OnRequestImage : TAbRequestImageEvent\n             read  FOnRequestImage\n             write SetOnRequestImage;\n    property OnRequestLastDisk : TAbRequestDiskEvent\n             read  FOnRequestLastDisk\n             write SetOnRequestLastDisk;\n    property OnRequestNthDisk : TAbRequestNthDiskEvent\n             read  FOnRequestNthDisk\n             write SetOnRequestNthDisk;\n    property OnRequestBlankDisk : TAbRequestDiskEvent\n             read  FOnRequestBlankDisk\n             write SetOnRequestBlankDisk;\n    property OnSave : TAbArchiveEvent\n             read  FOnSave\n             write FOnSave;\n{$IFDEF MSWINDOWS}\n    property OnStartDrag : TStartDragEvent\n             read  FOnStartDrag\n             write FOnStartDrag;\n{$ENDIF MSWINDOWS}\n\n  public {methods}\n    constructor Create(AOwner : TComponent); override;\n    destructor Destroy; override;\n\n    procedure AddFiles(const FileMask : string; SearchAttr : Integer);\n      {Add files to the archive where the disk filespec matches}\n    procedure AddFilesEx(const FileMask, ExclusionMask : string;\n                         SearchAttr : Integer);\n      {Add files that match Filemask except those matching ExclusionMask}\n    procedure AddFromStream(const NewName : string; FromStream : TStream);\n      {Create and add a zip item directly from a stream}\n    procedure ClearTags;\n      {Clear all tags from the archive}\n    procedure CloseArchive;\n      {closes the archive by setting FileName to ''}\n    procedure DeleteAt(Index : Integer);\n      {delete item specified by index}\n    procedure DeleteFiles(const FileMask : string);\n      {Delete all files from the archive that match the file mask}\n    procedure DeleteFilesEx(const FileMask, ExclusionMask : string);\n      {Delete files that match Filemask except those matching ExclusionMask}\n    procedure DeleteTaggedItems;\n      {delete all tagged items from the archive}\n    procedure ExtractAt(Index : Integer; const NewName : string);\n      {extract item specified by index}\n    procedure ExtractFiles(const FileMask : string);\n      {extract all files from the archive that match the mask}\n    procedure ExtractFilesEx(const FileMask, ExclusionMask : string);\n      {Extract files that match Filemask except those matching ExclusionMask}\n    procedure ExtractTaggedItems;\n      {extract all tagged items from the archive}\n    procedure ExtractToStream(const aFileName : string; ToStream : TStream);\n      {extract an item directly to a stream}\n    function FindItem(aItem : TAbArchiveItem) : Integer;\n      {extract specified item}\n    function FindFile(const aFileName : string) : Integer;\n      {find the item with the given file name}\n    procedure FreshenFiles(const FileMask : string);\n      {freshen all items that match the file mask}\n    procedure FreshenFilesEx(const FileMask, ExclusionMask : string);\n      {freshen items matching FileMask but not ExclusionMask}\n    procedure FreshenTaggedItems;\n      {freshen all tagged items}\n    procedure FullCollapse;\n    procedure FullExpand;\n    function GetTextItem(const Value: string): LongInt;\n    function GetOutLineItem(X, Y : Integer): LongInt;\n    procedure Move(aItem : TAbArchiveItem; NewStoredPath : string);\n    procedure OpenArchive(const aFileName : String);\n      {opens the archive}\n    procedure Replace(aItem : TAbArchiveItem);\n    procedure Save;\n      {saves the archive}\n    procedure TagItems(const FileMask : string);\n    procedure TestTaggedItems;\n    procedure UnTagItems(const FileMask : string);\n\n  public {properties}\n    property Count : Integer\n             read GetCount;\n    property Items[Index : Integer] : TAbZipItem\n             read GetItem\n             write PutItem; default;\n    property SelectedItem: LongInt\n             read GetSelectedItem\n             write SetSelectedItem;\n    property SelectedZipItem : TAbZipItem\n             read GetSelectedZipItem;\n    property Status : TAbArchiveStatus\n             read GetStatus;\n    property TempDirectory : string\n             read FTempDirectory\n             write SetTempDirectory;\n    property ZipfileComment : AnsiString\n             read GetZipfileComment\n             write SetZipfileComment;\n  end;\n\n\ntype\n  TAbZipOutline = class(TAbCustomZipOutline)\n  published\n    property Align;\n    property ArchiveProgressMeter;\n    property ItemProgressMeter;\n    property Attributes;\n    property AutoSave;\n    property BaseDirectory;\n    property BorderStyle;\n    property Color\n             default AbDefColor;\n    property CompressionMethodToUse;\n    property Count;\n{$IFNDEF UsingCLX}\n    property Ctl3D;\n{$ENDIF}\n    property Cursor;\n    property DeflationOption;\n{$IFDEF MSWINDOWS}\n    property DOSMode;\n{$ENDIF}\n{$IFNDEF UsingCLX}\n    property DragCursor;\n{$ENDIF}\n    property DragMode;\n    property Enabled;\n    property ExtractOptions;\n    property Font;\n    property Hierarchy;\n    property LogFile;\n    property Logging;\n    property OnProcessItemFailure;\n    property OnArchiveItemProgress;\n    property OnArchiveProgress;\n    property OnChange;\n    property OnClick;\n    property OnConfirmProcessItem;\n    property OnConfirmOverwrite;\n    property OnConfirmSave;\n    property OnCollapse;\n    property OnDblClick;\n    property OnDragDrop;\n    property OnDragOver;\n    property OnEndDrag;\n    property OnEnter;\n    property OnExit;\n    property OnExpand;\n    property OnKeyDown;\n    property OnKeyPress;\n    property OnKeyUp;\n    property OnLoad;\n    property OnMouseDown;\n    property OnMouseMove;\n    property OnMouseUp;\n{$IFNDEF UsingCLX}\n    property OnMouseWheel;\n    property OnMouseWheelDown;\n    property OnMouseWheelUp;\n{$ENDIF}\n    property OnNeedPassword;\n    property OnRequestImage;\n    property OnRequestLastDisk;\n    property OnRequestNthDisk;\n    property OnRequestBlankDisk;\n    property OnSave;\n{$IFDEF MSWINDOWS}\n    property OnStartDrag;\n{$ENDIF MSWINDOWS}\n    property OnWindowsDrop;\n    property ParentColor\n             default AbDefParentColor;\n{$IFNDEF UsingCLX}\n    property ParentCtl3D;\n{$ENDIF}\n    property ParentFont;\n    property ParentShowHint;\n    property Password;\n    property PasswordRetries;\n    property PictureDirectory;\n    property PictureDirectorySelected;\n    property PictureFile;\n    property PictureFileSelected;\n    property PictureZipAttribute;\n    property PictureZipAttributeSelected;\n    property PopupMenu;\n    property ShowHint;\n    property StoreOptions;\n    property TabOrder;\n    property TabStop;\n    property SpanningThreshold;\n    property Version;\n    property TempDirectory;\n    property Visible;\n    property FileName; {must be after OnLoad}\n  end;\n\nimplementation\n\nuses\n{$IFDEF MSWINDOWS}\n  ShellApi,\n{$ENDIF}\n  SysUtils,\n  AbConst,\n  AbExcept,\n  AbResString,\n  AbUnzPrc,\n  AbZipPrc;\n\n{$R AbZipOut.res}\n\ntype\n  TAbZipArchiveFriend = class(TAbZipArchive)\n  end;\n\n{ -------------------------------------------------------------------------- }\n{ ========================================================================== }\n{ -------------------------------------------------------------------------- }\nprocedure TAbZipDisplayOutline.IndexBitmaps;\nbegin\n  FImageList.Clear;\n\n  FImageList.Height := FBitMapHeight;\n  FImageList.Width  := FBitMapWidth;\n\n  if not FAttrBitMap.Empty then\n   FAttrIndex := FImageList.Add( FAttrBitMap, nil );\n  if not FAttrBitMap.Empty then\n    FAttrSelectedIndex := FImageList.Add( FAttrBitMapSelected, nil );\n  if not FAttrBitMap.Empty then\n    FDirectoryIndex := FImageList.Add( FDirBitMap, nil );\n  if not FAttrBitMap.Empty then\n    FDirSelectedIndex := FImageList.Add( FDirBitMapSelected , nil );\n  if not FAttrBitMap.Empty then\n    FFileIndex := FImageList.Add( FFileBitMap, nil );\n  if not FAttrBitMap.Empty then\n    FFileSelectedIndex := FImageList.Add( FFileBitMapSelected, nil );\nend;\n{ -------------------------------------------------------------------------- }\nconstructor TAbZipDisplayOutline.Create(AOwner : TComponent);\nbegin\n  FBitMapHeight := cBitmapHeight;\n  FBitMapWidth  := cBitmapWidth;\n\n  FDirBitMap := TBitMap.Create;\n  FFileBitMap := TBitMap.Create;\n  FAttrBitMap := TBitMap.Create;\n  FDirBitMapSelected  := TBitMap.Create;\n  FFileBitMapSelected := TBitMap.Create;\n  FAttrBitMapSelected := TBitMap.Create;\n\n  FDirBitMap.LoadFromResourceName( HInstance, 'DIR' );\n  FFileBitMap.LoadFromResourceName( HInstance, 'FILEFIX' );\n  FAttrBitMap.LoadFromResourceName( HInstance, 'ATTR' );\n  FDirBitMapSelected.LoadFromResourceName ( HInstance, 'DIRS'  );\n  FFileBitMapSelected.LoadFromResourceName( HInstance, 'FILES' );\n  FAttrBitMapSelected.LoadFromResourceName( HInstance, 'ATTRS' );\n\n  inherited Create(AOwner);\n\n  FImageList := TImageList.Create(Self);\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbZipDisplayOutline.Loaded;\nbegin\n  inherited Loaded;\n{$IFNDEF UsingCLX}\n  if Assigned(FOnWindowsDrop) then\n    DragAcceptFiles(Handle, True);\n{$ENDIF}\nend;\n{ -------------------------------------------------------------------------- }\ndestructor TAbZipDisplayOutline.Destroy;\nbegin\n  FImageList.Free;\n  FDirBitMap.Free;\n  FFileBitMap.Free;\n  FAttrBitMap.Free;\n  FDirBitMapSelected.Free;\n  FFileBitMapSelected.Free;\n  FAttrBitMapSelected.Free;\n  inherited Destroy;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbZipDisplayOutline.SetAttributeBitMap(Value : TBitmap);\nbegin\n  if Value <> nil then begin\n    FAttrBitMap.assign( Value )\n  end else begin\n    FAttrBitMap.LoadFromResourceName( HInstance, 'ATTR' );\n  end;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbZipDisplayOutline.SetDirectoryBitMap(Value : TBitmap);\nbegin\n  if Value <> nil then begin\n    FDirBitMap.assign( Value )\n  end else begin\n    FDirBitMap.LoadFromResourceName( HInstance, 'DIR' );\n  end;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbZipDisplayOutline.SetFileBitMap(Value : TBitmap);\nbegin\n  if Value <> nil then begin\n    FFileBitMap.assign( Value )\n  end else begin\n    FFileBitMap.LoadFromResourceName( HInstance, 'FILEFIX' );\n  end;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbZipDisplayOutline.SetAttributeBitMapSelected(Value : TBitmap);\nbegin\n  if Value <> nil then\n    FAttrBitMapSelected.assign( Value )\n  else begin\n    FAttrBitMapSelected.LoadFromResourceName( HInstance, 'ATTRS' );\n  end;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbZipDisplayOutline.SetDirectoryBitMapSelected(Value : TBitmap);\nbegin\n  if Value <> nil then\n    FDirBitMapSelected.assign( Value )\n  else begin\n    FDirBitMapSelected.LoadFromResourceName ( HInstance, 'DIRS'  );\n  end;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbZipDisplayOutline.SetFileBitMapSelected(Value : TBitmap);\nbegin\n  if Value <> nil then\n    FFileBitMapSelected.assign( Value )\n  else begin\n    FFileBitMapSelected.LoadFromResourceName( HInstance, 'FILES' );\n  end;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbZipDisplayOutline.SetBitMapHeight(Value : Integer);\nbegin\n  if FBitMapHeight <> Value then\n    FBitMapHeight := Value;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbZipDisplayOutline.SetBitMapWidth(Value : Integer);\nbegin\n  if FBitMapWidth <> Value then\n    FBitMapWidth := Value;\nend;\n{$IFNDEF UsingCLX}\n{ -------------------------------------------------------------------------- }\nprocedure TAbZipDisplayOutline.WMDropFiles(var Msg : TWMDropFiles);\nvar\n  FileName : string;\n  I : Integer;\n  NumFiles : Integer;\nbegin\n  Msg.Result := 1;\n  NumFiles := DragQueryFile(Msg.Drop, Cardinal(-1), nil, 0);\n  try\n    for I := 0 to pred(NumFiles) do begin\n      SetLength(FileName, DragQueryFile(Msg.Drop, I, nil, 0));\n      DragQueryFile(Msg.Drop, I, PChar(FileName), Length(FileName) + 1);\n      DoOnWindowsDrop(FileName);\n    end;\n  finally\n    DragFinish(Msg.Drop);\n  end;\n  if IsIconic(Application.Handle) then\n    ShowWindow(Application.Handle, SW_SHOWNORMAL)\n  else\n    BringWindowToTop(Handle);\nend;\n{$ENDIF}\n{ -------------------------------------------------------------------------- }\nprocedure TAbZipDisplayOutline.DoOnWindowsDrop(FileName : string);\nbegin\n  if csDesigning in ComponentState then\n    Exit;\n  if csLoading in ComponentState then\n    Exit;\n  if Assigned(FOnWindowsDrop) then\n    FOnWindowsDrop(Self, FileName);\nend;\n{ -------------------------------------------------------------------------- }\n{$IFDEF UsingCLX}\nfunction TAbZipDisplayOutline.DoMouseWheel(Shift: TShiftState;\n  WheelDelta: Integer; const MousePos: TPoint): Boolean;\n{$ELSE}\nfunction TAbZipDisplayOutline.DoMouseWheel(Shift: TShiftState;\n  WheelDelta: Integer; MousePos: TPoint): Boolean;\n{$ENDIF}\n const\n   WHEEL_DELTA = 120;\n var\n  oHold : TTreeNode;\n  oNode : TTreeNode;\nbegin\n  { We always return true - if there's an event handler that returns }\n  { false, we'll do the work; if it returns true, the work has been  }\n  { done, ergo this routine should return true.                      }\n  Result := True;\n  if not inherited DoMouseWheel(Shift, WheelDelta, MousePos) then begin\n    if Items.Count = 0 then\n      Exit;\n\n      if Selected = nil then\n        exit;\n      if Selected.HasChildren then\n        Selected.Expand( false );\n\n      oNode := nil;\n      oHold := Selected;\n      if WheelDelta < 0 then begin\n        if oHold.HasChildren then\n          oNode := oHold.getFirstChild;\n        if oNode = nil then\n          oNode := oHold.GetNextChild( oHold );\n        if oNode = nil then\n          oNode := oHold.GetNext;\n      end else begin\n        oNode := oHold.GetPrevChild( oHold );\n        if oNode <> nil then begin\n          if oNode.HasChildren then\n            oNode := oNode.GetLastChild;\n        end else\n          oNode := oHold.GetPrev;\n      end;\n      if oNode <> nil then\n        Selected := oNode;\n  end;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbZipDisplayOutline.SetOnWindowsDrop(Value : TWindowsDropEvent);\n{$IFNDEF UsingCLX}\nvar\n  WasAccepting : Boolean;\n{$ENDIF}\nbegin\n{$IFNDEF UsingCLX}\n  WasAccepting := Assigned(FOnWindowsDrop);\n  FOnWindowsDrop := Value;\n  if csLoading in ComponentState then\n    Exit;\n  if csDestroying in ComponentState then\n    Exit;\n  if Assigned(Value) then\n    DragAcceptFiles(Handle, True)\n  else if WasAccepting then\n    DragAcceptFiles(Handle, False);\n{$ENDIF}\nend;\n{ -------------------------------------------------------------------------- }\n{ ========================================================================== }\n{ -------------------------------------------------------------------------- }\nconstructor TAbCustomZipOutline.Create(AOwner : TComponent);\nbegin\n  inherited Create(AOwner);\n  Width := 300;\n  Height := 143;\n  Color := AbDefColor;\n  ParentColor := AbDefParentColor;\n\n  FOutline := TAbZipDisplayOutline.Create(Self);\n  FOutline.Parent := Self;\n  FOutline.Visible := True;\n  FOutline.Align := alClient;\n  FOutline.ParentColor := True;\n{$IFNDEF UsingCLX}\n  FOutline.ParentCtl3D := True;\n{$ENDIF}\n  FOutline.ParentFont := True;\n  FOutline.ParentShowHint := True;\n\n  FOutline.Images := FOutline.FImageList;\n\n  AutoSave := AbDefAutoSave;\n  Attributes := AbDefZipAttributes;\n  CompressionMethodToUse := AbDefCompressionMethodToUse;\n  DeflationOption := AbDefDeflationOption;\n  ExtractOptions := AbDefExtractOptions;\n  Hierarchy := AbDefHierarchy;\n  PasswordRetries := AbDefPasswordRetries;\n  StoreOptions := AbDefStoreOptions;\nend;\n{ -------------------------------------------------------------------------- }\ndestructor TAbCustomZipOutline.Destroy;\nbegin\n  FArchive.Free;\n  inherited Destroy;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbCustomZipOutline.AddAttributeNodes( Item : TAbZipItem;\n                                                 oNode : TTreeNode );\nvar\n  ExtAttrString : string;\n  dt : TDateTime;\n  li : LongInt;\n  s : string;\n  tmpNode : TTreeNode;\nbegin\n  with Item do begin\n    if zaCompressedSize in Attributes then begin\n      tmpNode := FOutline.Items.AddChild(oNode,\n                         Format(AbCompressedSizeFormatS,\n                                 [CompressedSize]));\n      tmpNode.ImageIndex    := FOutline.FAttrIndex;\n      tmpNode.SelectedIndex := FOutline.FAttrSelectedIndex;\n    end;\n    if zaUnCompressedSize in Attributes then begin\n      tmpNode := FOutline.Items.AddChild(oNode,                       \n                         Format(AbUncompressedSizeFormatS,\n                                 [UncompressedSize]));\n      tmpNode.ImageIndex    := FOutline.FAttrIndex;\n      tmpNode.SelectedIndex := FOutline.FAttrSelectedIndex;\n    end;\n    if zaCompressionMethod in Attributes then begin\n      tmpNode := FOutline.Items.AddChild(oNode,                       \n                         Format(AbCompressionMethodFormatS,\n                                 [ZipCompressionMethodToString(CompressionMethod)]));\n      tmpNode.ImageIndex    := FOutline.FAttrIndex;\n      tmpNode.SelectedIndex := FOutline.FAttrSelectedIndex;\n    end;\n    if zaCompressionRatio in Attributes then begin\n      tmpNode := FOutline.Items.AddChild(oNode,                       \n                         Format(AbCompressionRatioFormatS,\n                                 [CompressionRatio]));\n      tmpNode.ImageIndex    := FOutline.FAttrIndex;\n      tmpNode.SelectedIndex := FOutline.FAttrSelectedIndex;\n    end;\n    if zaCRC in Attributes then begin\n      tmpNode := FOutline.Items.AddChild(oNode,                       \n                         Format(AbCRCFormatS,\n                                 [CRC32]));\n      tmpNode.ImageIndex    := FOutline.FAttrIndex;\n      tmpNode.SelectedIndex := FOutline.FAttrSelectedIndex;\n    end;\n    if zaExternalFileAttributes in Attributes then begin\n      ExtAttrString := '';\n{$IFDEF MSWINDOWS}\n{$WARN SYMBOL_PLATFORM OFF}\n      if (faReadOnly and ExternalFileAttributes) = faReadOnly then\n        ExtAttrString := ExtAttrString + AbReadOnlyS;\n      if (faHidden and ExternalFileAttributes) = faHidden then\n        ExtAttrString := ExtAttrString + AbHiddenS;\n      if (faSysFile and ExternalFileAttributes) = faSysFile then\n        ExtAttrString := ExtAttrString + AbSystemS;\n      if (faArchive and ExternalFileAttributes) = faArchive then\n        ExtAttrString := ExtAttrString + AbArchivedS;\n{$WARN SYMBOL_PLATFORM ON}\n{$ENDIF}\n      tmpNode := FOutline.Items.AddChild(oNode,\n                         Format(AbEFAFormatS,\n                                 [ExtAttrString]));\n      tmpNode.ImageIndex    := FOutline.FAttrIndex;\n      tmpNode.SelectedIndex := FOutline.FAttrSelectedIndex;\n    end;\n    if zaInternalFileAttributes in Attributes then\n      if InternalFileAttributes = 1 then begin\n        tmpNode := FOutline.Items.AddChild(oNode,                     \n                           Format(AbIFAFormatS,\n                                   [AbTextS]));\n        tmpNode.ImageIndex    := FOutline.FAttrIndex;\n        tmpNode.SelectedIndex := FOutline.FAttrSelectedIndex;\n      end else begin\n        tmpNode := FOutline.Items.AddChild(oNode,\n                           Format(AbIFAFormatS,\n                                   [AbBinaryS]));\n        tmpNode.ImageIndex    := FOutline.FAttrIndex;\n        tmpNode.SelectedIndex := FOutline.FAttrSelectedIndex;\n      end;\n    if zaEncryption in Attributes then\n      if IsEncrypted then begin\n        tmpNode := FOutline.Items.AddChild(oNode,                     \n                           Format(AbEncryptionFormatS,\n                                   [AbEncryptedS]));\n        tmpNode.ImageIndex    := FOutline.FAttrIndex;\n        tmpNode.SelectedIndex := FOutline.FAttrSelectedIndex;\n      end else begin\n        tmpNode := FOutline.Items.AddChild(oNode,                     \n                           Format(AbEncryptionFormatS,\n                                   [AbNotEncryptedS]));\n        tmpNode.ImageIndex    := FOutline.FAttrIndex;\n        tmpNode.SelectedIndex := FOutline.FAttrSelectedIndex;\n      end;\n    if zaTimeStamp in Attributes then begin\n      if (LastModFileDate + LastModFileTime = 0) then\n        s := AbUnknownS\n      else begin\n        li := LongInt(LastModFileDate) shl 16 + LastModFileTime;\n        dt := FileDateToDateTime(li);\n        s := DateTimeToStr(dt);\n      end;\n      tmpNode := FOutline.Items.AddChild(oNode,                     \n                         Format(AbTimeStampFormatS, [s]));\n      tmpNode.ImageIndex    := FOutline.FAttrIndex;\n      tmpNode.SelectedIndex := FOutline.FAttrSelectedIndex;\n    end;\n    if zaVersionMade in Attributes then begin\n      tmpNode := FOutline.Items.AddChild(oNode,                     \n                         Format(AbMadeByFormatS,\n                                 [Lo(VersionMadeBy)/ 10.0]));\n      tmpNode.ImageIndex    := FOutline.FAttrIndex;\n      tmpNode.SelectedIndex := FOutline.FAttrSelectedIndex;\n    end;\n    if zaVersionNeeded in Attributes then begin\n      tmpNode := FOutline.Items.AddChild(oNode,                     \n                         Format(AbNeededFormatS,\n                                 [Lo(VersionNeededToExtract)/ 10.0]));\n      tmpNode.ImageIndex    := FOutline.FAttrIndex;\n      tmpNode.SelectedIndex := FOutline.FAttrSelectedIndex;\n    end;\n    if zaComment in Attributes then begin\n      tmpNode := FOutline.Items.AddChild(oNode,\n                         Format(AbCommentFormatS,\n                                 [FileComment]));\n      tmpNode.ImageIndex    := FOutline.FAttrIndex;\n      tmpNode.SelectedIndex := FOutline.FAttrSelectedIndex;\n    end;\n  end;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbCustomZipOutline.AddFiles(const FileMask : string;\n                                       SearchAttr : Integer);\n  {Add files to the archive where the disk filespec matches}\nbegin\n  if Assigned(FArchive) then\n    FArchive.AddFiles(FileMask, SearchAttr)\n  else\n    raise EAbNoArchive.Create;\n  DoChange;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbCustomZipOutline.AddFilesEx(const FileMask, ExclusionMask : string;\n                                         SearchAttr : Integer);\n  {Add files that match Filemask except those matching ExclusionMask}\nbegin\n  if Assigned(FArchive) then\n    FArchive.AddFilesEx(FileMask, ExclusionMask, SearchAttr)\n  else\n    raise EAbNoArchive.Create;\n  DoChange;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbCustomZipOutline.AddFromStream(const NewName : string;\n                                            FromStream : TStream);\n  {Add zip item directly from TStream descendant}\nbegin\n  if Assigned(FArchive) then begin\n    FromStream.Position := 0;\n    FArchive.AddFromStream(NewName, FromStream);\n  end else\n    raise EAbNoArchive.Create;\n  DoChange;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbCustomZipOutline.ClearTags;\n  {Clear all tags from the archive}\nbegin\n  if Assigned(FArchive) then\n    FArchive.ClearTags\n  else\n    raise EAbNoArchive.Create;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbCustomZipOutline.DeleteAt(Index : Integer);\n  {delete item at Index}\nbegin\n  if Assigned( FArchive ) then\n    FArchive.DeleteAt( Index )\n  else\n    raise EAbNoArchive.Create;\n  DoChange;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbCustomZipOutline.DeleteFiles(const FileMask : string);\n  {delete all files from the archive that match the file mask}\nbegin\n  if Assigned(FArchive) then\n    FArchive.DeleteFiles(FileMask)\n  else\n    raise EAbNoArchive.Create;\n  DoChange;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbCustomZipOutline.DeleteFilesEx(const FileMask, ExclusionMask : string);\n  {Delete files that match Filemask except those matching ExclusionMask}\nbegin\n  if Assigned(FArchive) then\n    FArchive.DeleteFilesEx(FileMask, ExclusionMask)\n  else\n    raise EAbNoArchive.Create;\n  DoChange;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbCustomZipOutline.DeleteTaggedItems;\n  {delete all tagged items from the archive}\nbegin\n  if Assigned(FArchive) then\n    FArchive.DeleteTaggedItems\n  else\n    raise EAbNoArchive.Create;\n  DoChange;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbCustomZipOutline.DoProcessItemFailure(Sender : TObject;\n                                              Item : TAbArchiveItem;\n                                              ProcessType : TAbProcessType;\n                                              ErrorClass : TAbErrorClass;\n                                              ErrorCode : Integer);\nbegin\n  if Assigned(FOnProcessItemFailure) then\n    FOnProcessItemFailure(Self, Item, ProcessType, ErrorClass, ErrorCode);\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbCustomZipOutline.DoArchiveItemProgress(Sender : TObject;\n                                               Item : TAbArchiveItem;\n                                               Progress : Byte;\n                                               var Abort : Boolean);\nbegin\n  Abort := False;\n  if Assigned(FItemProgressMeter) then\n    FItemProgressMeter.DoProgress(Progress);\n  if Assigned(FOnArchiveItemProgress) then\n    FOnArchiveItemProgress(Self, Item, Progress, Abort);\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbCustomZipOutline.DoArchiveProgress(Sender : TObject;\n                                           Progress : Byte;\n                                           var Abort : Boolean);\nbegin\n  Abort := False;\n  if Assigned(FArchiveProgressMeter) then\n    FArchiveProgressMeter.DoProgress(Progress);\n  if Assigned(FOnArchiveProgress) then\n    FOnArchiveProgress(Self, Progress, Abort);\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbCustomZipOutline.DoChange;\nbegin\n  {Archive now points to the new zip file}\n  UpdateOutline;\n  {then, call the FOnChange event...}\n  if Assigned(FOnChange) then\n    FOnChange(Self);\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbCustomZipOutline.DoClick(Sender : TObject);\nbegin\n  if Assigned(FOnClick) then\n    FOnClick(Self);\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbCustomZipOutline.DoCollapse(Sender: TObject; Node: TTreeNode);\nbegin\n  if Assigned(FOnCollapse) then\n    FOnCollapse(Self, Node);\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbCustomZipOutline.DoConfirmProcessItem(Sender : TObject;\n                                              Item : TAbArchiveItem;\n                                              ProcessType : TAbProcessType;\n                                              var Confirm : Boolean);\nbegin\n  Confirm := True;\n  if Assigned(FItemProgressMeter) then\n    FItemProgressMeter.Reset;\n  if Assigned(FOnConfirmProcessItem) then\n    FOnConfirmProcessItem(Self, Item, ProcessType, Confirm);\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbCustomZipOutline.DoConfirmOverwrite(var Name : string;\n                                            var Confirm : Boolean);\nbegin\n  Confirm := True;\n  if Assigned(FOnConfirmOverwrite) then\n    FOnConfirmOverwrite(Name, Confirm);\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbCustomZipOutline.DoConfirmSave(Sender : TObject;\n                                       var Confirm : Boolean);\nbegin\n  Confirm := True;\n  if Assigned(FOnConfirmSave) then\n    FOnConfirmSave(Self, Confirm);\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbCustomZipOutline.DoDblClick(Sender : TObject);\nbegin\n  if Assigned(FOnDblClick) then\n    FOnDblClick(Self);\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbCustomZipOutline.DoDragDrop(Sender, Source: TObject; X, Y: Integer);\nbegin\n  if Assigned(FOnDragDrop) then\n    FOnDragDrop(Self, Source, X, Y);\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbCustomZipOutline.DoDragOver(Sender, Source: TObject; X, Y: Integer;\n                                    State: TDragState; var Accept: Boolean);\nbegin\n  Accept := False;\n  if Assigned(FOnDragOver) then\n    FOnDragOver(Self, Source, X, Y, State, Accept);\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbCustomZipOutline.DoOnEndDrag(Sender, Target: TObject; X, Y: Integer);\nbegin\n  if Assigned(FOnEndDrag) then\n    FOnEndDrag(Self, Target, X, Y);\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbCustomZipOutline.DoOnEnter(Sender : TObject);\nbegin\n  if Assigned(FOnEnter) then\n    FOnEnter(Self);\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbCustomZipOutline.DoOnExit(Sender : TObject);\nbegin\n  if Assigned(FOnExit) then\n    FOnExit(Self);\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbCustomZipOutline.DoExpand(Sender: TObject; Node : TTreeNode);\nbegin\n  if Assigned(FOnExpand) then\n    FOnExpand(Self, Node);\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbCustomZipOutline.DoKeyDown(Sender : TObject; var Key: Word;\n                                   Shift: TShiftState);\nbegin\n  if Assigned(FOnKeyDown) then\n    FOnKeyDown(Self, Key, Shift);\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbCustomZipOutline.DoKeyPress(Sender : TObject; var Key: Char);\nbegin\n  if Assigned(FOnKeyPress) then\n    FOnKeyPress(Self, Key);\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbCustomZipOutline.DoKeyUp(Sender : TObject; var Key: Word;\n                                 Shift: TShiftState);\nbegin\n  if Assigned(FOnKeyUp) then\n    FOnKeyUp(Self, Key, Shift);\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbCustomZipOutline.DoLoad(Sender : TObject);\nbegin\n  if Assigned(FOnLoad) then\n    FOnLoad(Self);\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbCustomZipOutline.DoMouseDown(Sender : TObject; Button: TMouseButton;\n                                     Shift: TShiftState;\n                                     X, Y : Integer);\nbegin\n  if Assigned(FOnMouseDown) then\n    FOnMouseDown(Self, Button, Shift, X, Y);\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbCustomZipOutline.DoMouseMove(Sender : TObject;\n                                     Shift: TShiftState; X, Y: Integer);\nbegin\n  if Assigned(FOnMouseMove) then\n    FOnMouseMove(Self, Shift, X, Y);\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbCustomZipOutline.DoMouseUp(Sender : TObject;\n                                   Button: TMouseButton; Shift: TShiftState;\n                                   X, Y: Integer);\nbegin\n  if Assigned(FOnMouseUp) then\n    FOnMouseUp(Self, Button, Shift, X, Y);\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbCustomZipOutline.DoNeedPassword(Sender : TObject;\n                                        var NewPassword : AnsiString);\nbegin\n  if Assigned(FOnNeedPassword) then begin\n    FOnNeedPassword(Sender, NewPassword);\n    Password := NewPassword;\n  end;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbCustomZipOutline.DoSave(Sender : TObject);\nbegin\n  if Assigned(FOnSave) then\n    FOnSave(Self);\nend;\n{ -------------------------------------------------------------------------- }\n{$IFDEF MSWINDOWS}\nprocedure TAbCustomZipOutline.DoOnStartDrag(Sender: TObject;\n                                       var DragObject: TDragObject);\nbegin\n  if Assigned(FOnStartDrag) then\n    FOnStartDrag(Self, DragObject);\nend;\n{$ENDIF}\n{ -------------------------------------------------------------------------- }\nprocedure TAbCustomZipOutline.DoWindowsDrop(Sender : TObject;\n                                       FileName : string);\nbegin\n  if csDesigning in ComponentState then\n    Exit;\n  if csLoading in ComponentState then\n    Exit;\n  if Assigned(FOnWindowsDrop) then\n    FOnWindowsDrop(Self, FileName);\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbCustomZipOutline.ExtractAt(Index : Integer; const NewName : string);\n  {extract a file from the archive that match the index}\nbegin\n  if Assigned(FArchive) then\n    FArchive.ExtractAt(Index, NewName)\n  else\n    raise EAbNoArchive.Create;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbCustomZipOutline.ExtractFiles(const FileMask : string);\n  {extract all files from the archive that match the mask}\nbegin\n  if Assigned(FArchive) then\n    FArchive.ExtractFiles(FileMask)\n  else\n    raise EAbNoArchive.Create;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbCustomZipOutline.ExtractFilesEx(const FileMask, ExclusionMask : string);\n  {extract files that match FileMask except those matching ExclusionMask}\nbegin\n  if Assigned(FArchive) then\n    FArchive.ExtractFilesEx(FileMask, ExclusionMask)\n  else\n    raise EAbNoArchive.Create;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbCustomZipOutline.ExtractTaggedItems;\n  {extract all tagged items from the archive}\nbegin\n  if Assigned(FArchive) then\n    FArchive.ExtractTaggedItems\n  else\n    raise EAbNoArchive.Create;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbCustomZipOutline.ExtractToStream(const aFileName : string;\n                                              ToStream : TStream);\nbegin\n  if Assigned(FArchive) then\n    FArchive.ExtractToStream(aFileName, ToStream)\n  else\n    raise EAbNoArchive.Create;\nend;\n{ -------------------------------------------------------------------------- }\nfunction TAbCustomZipOutline.FindFile(const aFileName : string) : Integer;\nbegin\n  if Assigned(FArchive) then\n    Result := FArchive.FindFile(aFileName)\n  else\n    raise EAbNoArchive.Create;\nend;\n{ -------------------------------------------------------------------------- }\nfunction TAbCustomZipOutline.FindItem(aItem : TAbArchiveItem) : Integer;\nbegin\n  if Assigned(FArchive) then\n    Result := FArchive.FindItem(aItem)\n  else\n    Result := -1;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbCustomZipOutline.FreshenFiles(const FileMask : string);\n  {freshen all items that match the file mask}\nbegin\n  if Assigned(FArchive) then\n    FArchive.FreshenFiles(FileMask)\n  else\n    raise EAbNoArchive.Create;\n  DoChange;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbCustomZipOutline.FreshenFilesEx(const FileMask, ExclusionMask : string);\n  {freshen all items matching FileMask except those matching ExclusionMask}\nbegin\n  if Assigned(FArchive) then\n    FArchive.FreshenFilesEx(FileMask, ExclusionMask)\n  else\n    raise EAbNoArchive.Create;\n  DoChange;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbCustomZipOutline.FreshenTaggedItems;\n  {freshen all tagged items}\nbegin\n  if Assigned(FArchive) then\n    FArchive.FreshenTaggedItems\n  else\n    raise EAbNoArchive.Create;\n  DoChange;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbCustomZipOutline.FullCollapse;\nbegin\n  FOutline.FullCollapse;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbCustomZipOutline.FullExpand;\nbegin\n  FOutline.FullExpand;\nend;\n{ -------------------------------------------------------------------------- }\nfunction TAbCustomZipOutline.GetBorderStyle : TBorderStyle;\nbegin\n  Result := FOutline.BorderStyle;\nend;\n{ -------------------------------------------------------------------------- }\nfunction TAbCustomZipOutline.GetCount : Integer;\nbegin\n  if Assigned(FArchive) then\n    Result := FArchive.Count\n  else\n    Result := 0;\nend;\n{ -------------------------------------------------------------------------- }\nfunction TAbCustomZipOutline.GetCursor : TCursor;\nbegin\n  Result := FOutline.Cursor;\nend;\n{ -------------------------------------------------------------------------- }\n{$IFNDEF UsingCLX}\nfunction TAbCustomZipOutline.GetDragCursor : TCursor;\nbegin\n  Result := FOutline.DragCursor;\nend;\n{$ENDIF}\n{ -------------------------------------------------------------------------- }\nfunction TAbCustomZipOutline.GetDragMode : TDragMode;\nbegin\n  Result := FOutline.DragMode;\nend;\n{ -------------------------------------------------------------------------- }\nfunction TAbCustomZipOutline.GetItem(Index : Integer) : TAbZipItem;\nbegin\n  if Assigned(FArchive) then\n    Result := TAbZipItem(FArchive.ItemList[Index])\n  else\n    Result := nil;\nend;\n{ -------------------------------------------------------------------------- }\nfunction TAbCustomZipOutline.GetPictureDirectory : TBitmap;\nbegin\n  Result := FOutline.zdPictureDirectory;\nend;\n{ -------------------------------------------------------------------------- }\nfunction TAbCustomZipOutline.GetPictureFile : TBitmap;\nbegin\n  Result := FOutline.zdPictureFile;\nend;\n{ -------------------------------------------------------------------------- }\nfunction TAbCustomZipOutline.GetPictureZipAttribute: TBitmap;\nbegin\n  Result := FOutline.zdPictureZipAttribute;\nend;\n{ -------------------------------------------------------------------------- }\nfunction TAbCustomZipOutline.GetPictureDirectorySelected : TBitmap;\nbegin\n  Result := FOutline.zdPictureDirectorySelected;\nend;\n{ -------------------------------------------------------------------------- }\nfunction TAbCustomZipOutline.GetPictureFileSelected : TBitmap;\nbegin\n  Result := FOutline.zdPictureFileSelected;\nend;\n{ -------------------------------------------------------------------------- }\nfunction TAbCustomZipOutline.GetPictureZipAttributeSelected: TBitmap;\nbegin\n  Result := FOutline.zdPictureZipAttributeSelected;\nend;\n{ -------------------------------------------------------------------------- }\nfunction TAbCustomZipOutline.GetPictureHeight: Integer;\nbegin\n  Result := FOutline.FBitMapHeight;\nend;\n{ -------------------------------------------------------------------------- }\nfunction TAbCustomZipOutline.GetPictureWidth: Integer;\nbegin\n  Result := FOutline.FBitMapWidth;\nend;\n{ -------------------------------------------------------------------------- }\nfunction TAbCustomZipOutline.GetSelectedItem : LongInt;\nbegin\n  Result := FOutline.Selected.AbsoluteIndex;\nend;\n{ -------------------------------------------------------------------------- }\nfunction TAbCustomZipOutline.GetSelectedZipItem : TAbZipItem;\nbegin\n  {returns nil if the currently selected item of the outline is a folder or\n  a zip attribute}\n  if FOutline.Items.Count > 0 then\n    Result := FOutline.Selected.Data\n  else\n    Result := nil;\nend;\n{ -------------------------------------------------------------------------- }\nfunction TAbCustomZipOutline.GetStatus : TAbArchiveStatus;\nbegin\n  if Assigned(FArchive) then\n    Result := FArchive.Status\n  else\n    Result := asInvalid;\nend;\n{ -------------------------------------------------------------------------- }\nfunction TAbCustomZipOutline.GetTextItem(const Value: string): LongInt;\nvar\n  oNode : TTreeNode;\n  oHold : TTreeNode;\nbegin\n  Result := -1;\n  if FOutline.Items.Count <= 0 then\n    exit;\n\n  oNode := FOutline.Items[0];\n  while oNode <> nil do begin\n    if oNode.Text = Value then\n      break;\n    oHold := oNode;\n    oNode := nil;\n    if oHold.HasChildren then\n      oNode := oHold.getFirstChild;\n    if oNode = nil then\n      oNode := oHold.GetNextChild( oHold );\n    if oNode = nil then\n      oNode := oHold.GetNext;\n  end;\n  if oNode <> nil then\n     Result := oNode.AbsoluteIndex\nend;\n{ -------------------------------------------------------------------------- }\nfunction TAbCustomZipOutline.GetOutLineItem(X, Y : Integer): LongInt;\nvar\n  oNode : TTreeNode;\nbegin\n  oNode := FOutLine.GetNodeAt(X, X);\n  if oNode <> nil then\n    Result := oNode.AbsoluteIndex\n  else\n    Result := -1;\nend;\n{ -------------------------------------------------------------------------- }\nfunction TAbCustomZipOutline.GetVersion : string;\nbegin\n  Result := AbVersionS;\nend;\n{ -------------------------------------------------------------------------- }\nfunction TAbCustomZipOutline.GetZipfileComment : AnsiString;\nbegin\n  if Assigned(FArchive) then\n    Result := TAbZipArchive(FArchive).ZipfileComment\n  else\n    Result := '';\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbCustomZipOutline.InitArchive;\nbegin\n  if Assigned(FArchive) then begin\n    {properties}\n    FArchive.AutoSave := FAutoSave;\n    FArchive.CompressionMethodToUse := FCompressionMethodToUse;\n    SetBaseDirectory(FBaseDirectory);\n    FArchive.DeflationOption := FDeflationOption;\n{$IFDEF MSWINDOWS}\n    FArchive.DOSMode := FDOSMode;\n{$ENDIF}\n    FArchive.ExtractOptions := FExtractOptions;\n    FArchive.LogFile := FLogFile;\n    FArchive.Logging := FLogging;\n    FArchive.Password := FPassword;\n    FArchive.PasswordRetries := FPasswordRetries;\n    FArchive.StoreOptions := FStoreOptions;\n    FArchive.TempDirectory := FTempDirectory;\n    FArchive.SpanningThreshold := FSpanningThreshold;\n    {events}\n    TAbZipArchiveFriend(FArchive).ExtractHelper := UnzipProc;\n    TAbZipArchiveFriend(FArchive).ExtractToStreamHelper := UnzipToStreamProc;\n    TAbZipArchiveFriend(FArchive).InsertHelper := ZipProc;\n    TAbZipArchiveFriend(FArchive).InsertFromStreamHelper := ZipFromStreamProc;\n    FArchive.OnProcessItemFailure := DoProcessItemFailure;\n    FArchive.OnArchiveItemProgress := DoArchiveItemProgress;\n    FArchive.OnArchiveProgress := DoArchiveProgress;\n    FArchive.OnConfirmProcessItem := DoConfirmProcessItem;\n    FArchive.OnConfirmOverwrite := DoConfirmOverwrite;\n    FArchive.OnConfirmSave := DoConfirmSave;\n    FArchive.OnLoad := DoLoad;\n    FArchive.OnSave := DoSave;\n    FArchive.OnRequestImage := FOnRequestImage;\n    FArchive.OnNeedPassword := DoNeedPassword;\n    FArchive.OnRequestBlankDisk := FOnRequestBlankDisk;\n    FArchive.OnRequestLastDisk := FOnRequestLastDisk;\n    FArchive.OnRequestNthDisk := FOnRequestNthDisk;\n    TAbZipArchiveFriend(FArchive).TestHelper := TestItemProc;\n  end;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbCustomZipOutline.Loaded;\nbegin\n  inherited Loaded;\n  FOutline.OnClick := DoClick;\n  FOutline.OnCollapsed := DoCollapse;\n  FOutline.OnDblClick := DoDblClick;\n  FOutline.OnDragDrop := DoDragDrop;\n  FOutline.OnDragOver := DoDragOver;\n  FOutline.OnEndDrag := DoOnEndDrag;\n  FOutline.OnEnter := DoOnEnter;\n  FOutline.OnExit := DoOnExit;\n  FOutline.OnExpanded := DoExpand;\n  FOutline.OnKeyDown := DoKeyDown;\n  FOutline.OnKeyPress := DoKeyPress;\n  FOutline.OnKeyUp := DoKeyUp;\n  FOutline.OnMouseDown := DoMouseDown;\n  FOutline.OnMouseMove := DoMouseMove;\n  FOutline.OnMouseUp := DoMouseUp;\n{$IFDEF MSWINDOWS}\n  FOutline.OnStartDrag := DoOnStartDrag;\n{$ENDIF MSWINDOWS}\n  if Assigned(FOnWindowsDrop) then\n    FOutline.OnWindowsDrop := DoWindowsDrop\n  else\n    FOutline.OnWindowsDrop := nil;\n  DoChange;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbCustomZipOutline.Move(aItem : TAbArchiveItem; NewStoredPath : string);\nbegin\n  if Assigned(FArchive) then\n    FArchive.Move(aItem, NewStoredPath)\n  else\n    raise EAbNoArchive.Create;\n  DoChange;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbCustomZipOutline.Notification(Component: TComponent;\n  Operation: TOperation);\nbegin\n  inherited Notification(Component, Operation);\n  if (Operation = opRemove) then begin\n    if Assigned(ItemProgressMeter) and Component.IsImplementorOf(ItemProgressMeter) then\n      ItemProgressMeter := nil;\n    if Assigned(ArchiveProgressMeter) and Component.IsImplementorOf(ArchiveProgressMeter) then\n      ArchiveProgressMeter := nil;\n  end;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbCustomZipOutline.PutItem(Index : Integer; Value : TAbZipItem);\nbegin\n  if Assigned(FArchive) then\n    FArchive.ItemList[Index] := Value\n  else\n    raise EAbNoArchive.Create;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbCustomZipOutline.Replace(aItem : TAbArchiveItem);\n  {replace the item}\nbegin\n  if Assigned( FArchive ) then\n    FArchive.Replace( aItem )\n  else\n    raise EAbNoArchive.Create;\n  DoChange;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbCustomZipOutline.Save;\nbegin\n  if Assigned(FArchive) then begin\n    FArchive.Save;\n  end;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbCustomZipOutline.SetArchiveProgressMeter(const Value: IAbProgressMeter);\nbegin\n  ReferenceInterface(FArchiveProgressMeter, opRemove);\n  FArchiveProgressMeter := Value;\n  ReferenceInterface(FArchiveProgressMeter, opInsert);\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbCustomZipOutline.SetAttributes(Value : TAbZipAttributes);\nbegin\n  FAttributes := Value;\n  UpdateOutline;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbCustomZipOutline.SetAutoSave(Value : Boolean);\nbegin\n  FAutoSave := Value;\n  if Assigned(FArchive) then\n    FArchive.AutoSave := Value;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbCustomZipOutline.SetBaseDirectory(Value : string);\nbegin\n  if Assigned(FArchive) then begin\n    FArchive.BaseDirectory := Value;\n    FBaseDirectory := FArchive.BaseDirectory;\n  end\n  else\n    FBaseDirectory := Value;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbCustomZipOutline.SetBorderStyle(Value : TBorderStyle);\nbegin\n  FOutline.BorderStyle := Value;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbCustomZipOutline.SetCompressionMethodToUse(\n                                            Value : TAbZipSupportedMethod);\nbegin\n  FCompressionMethodToUse := Value;\n  if Assigned(FArchive) then\n    FArchive.CompressionMethodToUse := Value;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbCustomZipOutline.SetCursor(Value : TCursor);\nbegin\n  FOutline.Cursor := Value;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbCustomZipOutline.SetDeflationOption(Value : TAbZipDeflationOption);\nbegin\n  FDeflationOption := Value;\n  if Assigned(FArchive) then\n    FArchive.DeflationOption := Value;\nend;\n{ -------------------------------------------------------------------------- }\n{$IFDEF MSWINDOWS}\nprocedure TAbCustomZipOutline.SetDOSMode(Value : Boolean);\nbegin\n  FDOSMode := Value;\n  if Assigned(FArchive) then\n    FArchive.DOSMode := Value;\nend;\n{$ENDIF}\n{ -------------------------------------------------------------------------- }\n{$IFNDEF UsingCLX}\nprocedure TAbCustomZipOutline.SetDragCursor(Value : TCursor);\nbegin\n  FOutline.DragCursor := Value;\nend;\n{$ENDIF}\n{ -------------------------------------------------------------------------- }\n{$IFNDEF UsingCLX}\nprocedure TAbCustomZipOutline.SetDragMode(Value : TDragMode);\nbegin\n  {$IFDEF MSWINDOWS}\n  inherited SetDragMode(Value);\n  {$ENDIF}\n  FOutline.DragMode := Value;\nend;\n{$ENDIF}\n{ -------------------------------------------------------------------------- }\nprocedure TAbCustomZipOutline.SetExtractOptions(Value : TAbExtractOptions);\nbegin\n  FExtractOptions := Value;\n  if Assigned(FArchive) then\n    FArchive.ExtractOptions := Value;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbCustomZipOutline.SetFileName(const aFileName : string);\nbegin\n  if Assigned(FArchive) and (Status = asBusy) then\n    raise EAbArchiveBusy.Create;\n  FFileName := aFileName;\n  try\n    if Assigned(FArchive) then\n      FArchive.Save;\n  except\n  end;\n  FArchive.Free;\n  FArchive := nil;\n  if FileName <> '' then\n    if FileExists(FileName) then begin\n      if csDesigning in ComponentState then\n        FArchive := TAbZipArchive.Create(FileName,\n                                          fmOpenRead or\n                                          fmShareDenyNone)\n      else begin\n        try\n          FArchive := TAbZipArchive.Create(FileName,\n                                            fmOpenReadWrite or\n                                            fmShareDenyWrite);\n        except\n          {deals with read-only files}\n          FArchive := TAbZipArchive.Create(FileName,\n                                            fmOpenRead or\n                                            fmShareDenyWrite);\n        end;\n        InitArchive;\n      end;\n      FArchive.Load;\n    end\n    else begin\n      FArchive := TAbZipArchive.Create(FileName,\n                                        fmCreate or fmShareDenyNone);\n      InitArchive;\n      try\n        FArchive.Load;\n      except\n      end;\n    end;\n  DoChange;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbCustomZipOutline.SetHierarchy(Value : Boolean);\nbegin\n  FHierarchy := Value;\n  UpdateOutline;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbCustomZipOutline.SetItemProgressMeter(const Value: IAbProgressMeter);\nbegin\n  ReferenceInterface(FItemProgressMeter, opRemove);\n  FItemProgressMeter := Value;\n  ReferenceInterface(FItemProgressMeter, opInsert);\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbCustomZipOutline.SetLogFile(Value : string);\nbegin\n  FLogFile := Value;\n  if (csDesigning in ComponentState) then\n    Exit;\n  if Assigned(FArchive) then\n    FArchive.LogFile := Value;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbCustomZipOutline.SetLogging(Value : Boolean);\nbegin\n  FLogging := Value;\n  if (csDesigning in ComponentState) then\n    Exit;\n  if Assigned(FArchive) then\n    FArchive.Logging:= Value;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbCustomZipOutline.SetOnRequestImage(Value : TAbRequestImageEvent);\nbegin\n  FOnRequestImage := Value;\n  if Assigned(FArchive) then\n    FArchive.OnRequestImage := Value;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbCustomZipOutline.SetOnRequestLastDisk(Value : TAbRequestDiskEvent);\nbegin\n  FOnRequestLastDisk := Value;\n  if Assigned(FArchive) then\n    FArchive.OnRequestLastDisk := FOnRequestLastDisk;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbCustomZipOutline.SetOnRequestNthDisk(Value : TAbRequestNthDiskEvent);\nbegin\n  FOnRequestNthDisk := Value;\n  if Assigned(FArchive) then\n    FArchive.OnRequestNthDisk := FOnRequestNthDisk;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbCustomZipOutline.SetOnRequestBlankDisk(Value : TAbRequestDiskEvent);\nbegin\n  FOnRequestBlankDisk := Value;\n  if Assigned(FArchive) then\n    FArchive.OnRequestBlankDisk := FOnRequestBlankDisk;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbCustomZipOutline.SetOnWindowsDrop(Value : TWindowsDropEvent);\nbegin\n  FOnWindowsDrop := Value;\n  if csLoading in ComponentState then\n    Exit;\n  if csDestroying in ComponentState then\n    Exit;\n  if Assigned(Value) then\n    FOutline.OnWindowsDrop := DoWindowsDrop\n  else\n    FOutline.OnWindowsDrop := nil;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbCustomZipOutline.SetPassword(Value : AnsiString);\nbegin\n  FPassword := Value;\n  if Assigned(FArchive) then\n    FArchive.Password := Value;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbCustomZipOutline.SetPasswordRetries(Value : Byte);\nbegin\n  FPasswordRetries := Value;\n  if Assigned(FArchive) then\n    FArchive.PasswordRetries := Value;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbCustomZipOutline.SetPictureDirectory(Value : TBitmap);\nbegin\n  if Value <> nil then begin\n    if (Value.Height = FOutline.FBitMapHeight) and\n       (Value.Width = FOutline.FBitMapWidth) then\n      FOutline.zdPictureDirectory := Value;\n  end else\n    FOutline.zdPictureDirectory := nil;\n\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbCustomZipOutline.SetPictureFile(Value : TBitmap);\nbegin\n  if Value <> nil then begin\n    if (Value.Height = FOutline.FBitMapHeight) and\n       (Value.Width = FOutline.FBitMapWidth) then\n      FOutline.zdPictureFile := Value;\n  end else\n    FOutline.zdPictureFile := nil;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbCustomZipOutline.SetPictureZipAttribute(Value : TBitmap);\nbegin\n  if Value <> nil then begin\n    if (Value.Height = FOutline.FBitMapHeight) and\n       (Value.Width = FOutline.FBitMapWidth) then\n      FOutline.zdPictureZipAttribute := Value;\n  end else\n    FOutline.zdPictureZipAttribute := nil;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbCustomZipOutline.SetPictureDirectorySelected(Value : TBitmap);\nbegin\n  if Value <> nil then begin\n    if (Value.Height = FOutline.FBitMapHeight) and\n       (Value.Width = FOutline.FBitMapWidth) then\n      FOutline.zdPictureDirectorySelected := Value;\n  end else\n    FOutline.zdPictureDirectorySelected := nil;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbCustomZipOutline.SetPictureFileSelected(Value : TBitmap);\nbegin\n  if Value <> nil then begin\n    if (Value.Height = FOutline.FBitMapHeight) and\n       (Value.Width = FOutline.FBitMapWidth) then\n      FOutline.zdPictureFileSelected := Value;\n  end else\n    FOutline.zdPictureFileSelected := nil;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbCustomZipOutline.SetPictureZipAttributeSelected(Value : TBitmap);\nbegin\n  if Value <> nil then begin\n    if (Value.Height = FOutline.FBitMapHeight) and\n       (Value.Width = FOutline.FBitMapWidth) then\n      FOutline.zdPictureZipAttributeSelected := Value;\n  end else\n    FOutline.zdPictureZipAttributeSelected := nil;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbCustomZipOutline.SetPictureHeight(Value : Integer);\nbegin\n  FOutline.FBitMapHeight := Value;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbCustomZipOutline.SetPictureWidth(Value : Integer);\nbegin\n  FOutline.FBitMapWidth := Value;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbCustomZipOutline.SetSelectedItem(Value : LongInt);\nbegin\n  if ( Value >= 0 ) and ( Value <= pred( FOutline.Items.Count )) then\n  FOutline.Selected := FOutline.Items[ Value ];\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbCustomZipOutline.SetStoreOptions(Value : TAbStoreOptions);\nbegin\n  FStoreOptions := Value;\n  if Assigned(FArchive) then\n    FArchive.StoreOptions := Value;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbCustomZipOutline.SetTempDirectory(Value : string);\nbegin\n  FTempDirectory := Value;\n  if Assigned(FArchive) then\n    FArchive.TempDirectory := Value;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbCustomZipOutline.SetSpanningThreshold(Value : Longint);\nbegin\n  FSpanningThreshold := Value;\n  if Assigned(FArchive) then\n    FArchive.SpanningThreshold := Value;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbCustomZipOutline.SetVersion(Value : string);\nbegin\n  {NOP}\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbCustomZipOutline.SetZipfileComment(Value : AnsiString);\nbegin\n  if Assigned(FArchive) then\n    TAbZipArchive(FArchive).ZipfileComment := Value;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbCustomZipOutline.TagItems(const FileMask : string);\n  {tag all items that match the mask}\nbegin\n  if Assigned(FArchive) then\n    FArchive.TagItems(FileMask)\n  else\n    raise EAbNoArchive.Create;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbCustomZipOutline.UnTagItems(const FileMask : string);\n  {clear tags for all items that match the mask}\nbegin\n  if Assigned(FArchive) then\n    FArchive.UnTagItems(FileMask)\n  else\n    raise EAbNoArchive.Create;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbCustomZipOutline.UnzipProc(Sender : TObject;\n                                        Item : TAbArchiveItem;\n                                        const NewName : string);\nbegin\n  AbUnzip( TAbZipArchive(Sender), TAbZipItem(Item), NewName);\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbCustomZipOutline.UnzipToStreamProc(Sender : TObject;\n                                                Item : TAbArchiveItem;\n                                                OutStream : TStream);\nbegin\n  if Assigned(OutStream) then\n    AbUnzipToStream(TAbZipArchive(Sender), TAbZipItem(Item), OutStream);\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbCustomZipOutline.UpdateOutline;\nvar\n  Found : Boolean;\n  i : Integer;\n  CurRoot : TTreeNode;\n  CurParent : TTreeNode;\n  CurChild : TTreeNode;\n  RootNode : TTreeNode;\n  oNode : TTreeNode;\n  SubDir : string;\n  ItemString : string;\n\n  function GetSubDir(var ItemString : string) : string;\n  var\n    i : Integer;\n  begin\n    i := Pos(AbPathDelim, ItemString);\n    Result := '';\n    if i > 0 then begin\n      Result := Copy(ItemString, 1, pred(i));\n      System.Delete(ItemString, 1, i);\n    end;\n  end;\nbegin\n  RootNode := nil;\n  CurRoot := nil;\n  FOutline.Items.Clear;\n  if not Assigned(FArchive) then\n    Exit;\n  if FArchive.Count = 0 then\n    Exit;\n\n  FOutline.IndexBitmaps;\n\n  if Hierarchy then begin\n    for i := 0 to pred(FArchive.Count) do begin\n      {do not display deleted items...}\n      if FArchive.ItemList[i].Action = aaDelete then\n        continue;\n\n      ItemString := FArchive.ItemList[i].FileName;\n      AbUnfixName(ItemString);\n\n      if ItemString[ Length( ItemString )] = AbPathDelim then\n        Continue;\n\n      if ( FOutline.Items.Count <> 0 ) and ( CurRoot <> nil ) then begin\n        SubDir := GetSubDir(ItemString);\n\n        if RootNode = nil then\n          RootNode := FOutline.TopItem;\n\n        CurParent := RootNode;\n        while CurParent <> nil do begin\n          if CurParent.Text = SubDir then begin\n            CurRoot := CurParent;\n            break;\n          end else begin\n            CurParent := CurParent.getNextSibling;\n          end;\n        end;\n        if CurParent = nil then begin\n          ItemString := FArchive.ItemList[i].FileName;\n          AbUnfixName(ItemString);\n        end;\n      end else\n        CurParent := nil;\n\n      SubDir := GetSubDir(ItemString);\n      while SubDir <> '' do begin\n        if CurParent <> nil then begin\n          Found := False;\n          CurChild := CurParent.GetFirstChild;\n          while CurChild <> nil do begin\n            if CurChild.Text <> SubDir then\n              CurChild := CurParent.GetNextChild( CurChild )\n            else begin\n              Found := True;\n              break;\n            end;\n          end;\n          if Found then\n            CurParent := CurChild\n          else begin\n            if ItemString <> '' then begin\n              CurParent := FOutline.Items.AddChild( CurParent, SubDir );\n              CurParent.ImageIndex    := FOutline.FDirectoryIndex;\n              CurParent.SelectedIndex := FOutline.FDirSelectedIndex;\n            end;\n          end;\n        end else begin\n          if ItemString <> '' then begin\n            CurRoot := FOutline.Items.Add( nil, SubDir );\n            if FOutline.Items.Count = 1 then\n              RootNode := CurRoot;\n            CurRoot.ImageIndex := FOutline.FDirectoryIndex;\n            CurRoot.SelectedIndex := FOutline.FDirSelectedIndex;\n            CurParent := CurRoot\n          end;\n        end;\n        SubDir := GetSubDir(ItemString);\n      end;\n      if ItemString <> '' then begin\n        oNode := FOutline.Items.AddChildObject(CurParent, ItemString,\n          FArchive.ItemList[i]);\n\n        if FOutline.Items.Count = 1 then\n          RootNode := oNode;\n        oNode.ImageIndex := FOutline.FFileIndex;\n        oNode.SelectedIndex := FOutline.FFileSelectedIndex;\n        AddAttributeNodes(TAbZipItem(FArchive.ItemList[i]), oNode);\n      end;\n    end;\n  end\n  else begin\n    for i := 0 to pred(FArchive.Count) do begin\n      ItemString := FArchive.ItemList[i].FileName;\n      AbUnfixName(ItemString);\n      oNode := FOutline.Items.AddObject(FOutline.Selected, ItemString,\n        FArchive.ItemList[i]);\n\n      oNode.ImageIndex := FOutline.FFileIndex;\n      oNode.SelectedIndex := FOutline.FFileSelectedIndex;\n      AddAttributeNodes(TAbZipItem(FArchive.ItemList[i]), oNode);\n    end;\n  end;\n  FullExpand;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbCustomZipOutline.TestItemProc(Sender : TObject; Item : TAbArchiveItem);\nbegin\n  AbTestZipItem(TAbZipArchive(Sender), TAbZipItem(Item));\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbCustomZipOutline.TestTaggedItems;\n  {Test specified items}\nbegin\n  if Assigned(FArchive) then\n    FArchive.TestTaggedItems\n  else\n    raise EAbNoArchive.Create;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbCustomZipOutline.ZipProc(Sender : TObject;\n                             Item : TAbArchiveItem;\n                             OutStream : TStream);\nbegin\n  AbZip(TAbZipArchive(Sender), TAbZipItem(Item), OutStream);\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbCustomZipOutline.ZipFromStreamProc(Sender : TObject;\n                                                Item : TAbArchiveItem;\n                                                OutStream, InStream : TStream);\nbegin\n  if Assigned(InStream) then\n    AbZipFromStream(TAbZipArchive(Sender), TAbZipItem(Item),\n                    OutStream, InStream)\n  else\n    raise EAbZipNoInsertion.Create;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbCustomZipOutline.CloseArchive;\n  {closes the archive by setting FileName to ''}\nbegin\n  if FFileName <> '' then\n    FileName := '';\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbCustomZipOutline.OpenArchive(const aFileName : String);\n  {opens the archive}\nbegin\n  FileName := AFileName;\nend;\n{ -------------------------------------------------------------------------- }\nend.\n\n"
  },
  {
    "path": "lib/abbrevia/source/AbZipPrc.pas",
    "content": "(* ***** BEGIN LICENSE BLOCK *****\n * Version: MPL 1.1\n *\n * The contents of this file are subject to the Mozilla Public License Version\n * 1.1 (the \"License\"); you may not use this file except in compliance with\n * the License. You may obtain a copy of the License at\n * http://www.mozilla.org/MPL/\n *\n * Software distributed under the License is distributed on an \"AS IS\" basis,\n * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License\n * for the specific language governing rights and limitations under the\n * License.\n *\n * The Original Code is TurboPower Abbrevia\n *\n * The Initial Developer of the Original Code is\n * TurboPower Software\n *\n * Portions created by the Initial Developer are Copyright (C) 1997-2002\n * the Initial Developer. All Rights Reserved.\n *\n * Contributor(s):\n *\n * ***** END LICENSE BLOCK ***** *)\n\n{*********************************************************}\n{* ABBREVIA: AbZipPrc.pas                                *}\n{*********************************************************}\n{* ABBREVIA: TABZipHelper class                          *}\n{*********************************************************}\n\nunit AbZipPrc;\n\n{$I AbDefine.inc}\n\ninterface\n\nuses\n  Classes,\n  AbZipTyp;\n\n  procedure AbZip( Sender : TAbZipArchive; Item : TAbZipItem;\n    OutStream : TStream );\n\n  procedure AbZipFromStream(Sender : TAbZipArchive; Item : TAbZipItem;\n    OutStream, InStream : TStream);\n\n  procedure DeflateStream( UncompressedStream, CompressedStream : TStream );\n    {-Deflates everything in UncompressedStream to CompressedStream\n      no encryption is tried, no check on CRC is done, uses the whole\n      compressedstream - no Progress events - no Frills! }\n\nimplementation\n\nuses\n{$IFDEF MSWINDOWS}\n  Windows,\n{$ENDIF}\n{$IFDEF LibcAPI}\n  Libc,\n{$ENDIF}\n  SysUtils,\n  AbArcTyp,\n  AbExcept,\n  AbUtils,\n  AbDfCryS,\n  AbVMStrm,\n  AbDfBase,\n  AbDfEnc,\n  AbSpanSt;\n\n\n{ ========================================================================== }\nprocedure DoDeflate(Archive : TAbZipArchive; Item : TAbZipItem; OutStream, InStream : TStream);\nconst\n  DEFLATE_NORMAL_MASK    = $00;\n  DEFLATE_MAXIMUM_MASK   = $02;\n  DEFLATE_FAST_MASK      = $04;\n  DEFLATE_SUPERFAST_MASK = $06;\nvar\n  Hlpr : TAbDeflateHelper;\nbegin\n  Item.CompressionMethod := cmDeflated;\n\n  Hlpr := TAbDeflateHelper.Create;\n\n  {anything dealing with store options, etc. should already be done.}\n\n  try {Hlpr}\n    Hlpr.StreamSize := InStream.Size;\n\n    { set deflation level desired }\n    Hlpr.PKZipOption := '0';\n\n    case Archive.DeflationOption of\n      doNormal    : begin\n        Hlpr.PKZipOption := 'n';\n        Item.GeneralPurposeBitFlag :=\n          Item.GeneralPurposeBitFlag or DEFLATE_NORMAL_MASK;\n      end;\n\n      doMaximum   : begin\n        Hlpr.PKZipOption := 'x';\n        Item.GeneralPurposeBitFlag :=\n          Item.GeneralPurposeBitFlag or DEFLATE_MAXIMUM_MASK;\n      end;\n\n      doFast      : begin\n        Hlpr.PKZipOption := 'f';\n        Item.GeneralPurposeBitFlag :=\n          Item.GeneralPurposeBitFlag or DEFLATE_FAST_MASK;\n      end;\n\n      doSuperFast : begin\n        Hlpr.PKZipOption := 's';\n        Item.GeneralPurposeBitFlag :=\n          Item.GeneralPurposeBitFlag or DEFLATE_SUPERFAST_MASK;\n      end;\n    end;\n\n    { attach progress notification method }\n    Hlpr.OnProgressStep := Archive.DoInflateProgress;\n\n    { provide encryption check value }\n    Item.CRC32 := Deflate(InStream, OutStream, Hlpr);\n\n  finally {Hlpr}\n    Hlpr.Free;\n  end;    {Hlpr}\nend;\n{ ========================================================================== }\nprocedure DoStore(Archive : TAbZipArchive; Item : TAbZipItem; OutStream, InStream : TStream);\nvar\n  CRC32       : LongInt;\n  Percent     : LongInt;\n  LastPercent : LongInt;\n  InSize      : Int64;\n  DataRead    : Int64;\n  Total       : Int64;\n  Abort       : Boolean;\n  Buffer      : array [0..8191] of byte;\nbegin\n  { setup }\n  Item.CompressionMethod := cmStored;\n  Abort := False;\n  CRC32 := -1;\n  Total := 0;\n  Percent := 0;\n  LastPercent := 0;\n  InSize := InStream.Size;\n\n  { get first bufferful }\n  DataRead := InStream.Read(Buffer, SizeOf(Buffer));\n  { while more data has been read and we're not told to bail }\n  while (DataRead <> 0) and not Abort do begin\n    {report the progress}\n    if Assigned(Archive.OnProgress) then begin\n      Total := Total + DataRead;\n      Percent := Round((100.0 * Total) / InSize);\n      if (LastPercent <> Percent) then\n        Archive.OnProgress(Percent, Abort);\n      LastPercent := Percent;\n    end;\n\n    { update CRC}\n    AbUpdateCRCBuffer(CRC32, Buffer, DataRead);\n\n    { write data (encrypting if needed) }\n    OutStream.WriteBuffer(Buffer, DataRead);\n\n    { get next bufferful }\n    DataRead := InStream.Read(Buffer, SizeOf(Buffer));\n  end;\n\n  { finish CRC calculation }\n  Item.CRC32 := not CRC32;\n\n  { show final progress increment }\n  if (Percent < 100) and Assigned(Archive.OnProgress) then\n    Archive.OnProgress(100, Abort);\n\n  { User wants to bail }\n  if Abort then begin\n    raise EAbUserAbort.Create;\n  end;\n\nend;\n{ ========================================================================== }\nprocedure DoZipFromStream(Sender : TAbZipArchive; Item : TAbZipItem;\n  OutStream, InStream : TStream);\nvar\n  ZipArchive : TAbZipArchive;\n  InStartPos : LongInt;\n  TempOut : TAbVirtualMemoryStream;\n  DestStrm : TStream;\nbegin\n  ZipArchive := TAbZipArchive(Sender);\n\n  { configure Item }\n  Item.UncompressedSize := InStream.Size;\n  Item.GeneralPurposeBitFlag := Item.GeneralPurposeBitFlag and AbLanguageEncodingFlag;\n\n  if ZipArchive.Password <> '' then  { encrypt the stream }\n    DestStrm := TAbDfEncryptStream.Create(OutStream,\n                                          LongInt(Item.LastModFileTime shl $10),\n                                          ZipArchive.Password)\n  else\n    DestStrm := OutStream;\n  try\n    if InStream.Size > 0 then begin\n\n      { determine how to store Item based on specified CompressionMethodToUse }\n      case ZipArchive.CompressionMethodToUse of\n        smDeflated : begin\n        { Item is to be deflated regarless }\n          { deflate item }\n          DoDeflate(ZipArchive, Item, DestStrm, InStream);\n        end;\n\n        smStored : begin\n        { Item is to be stored regardless }\n          { store item }\n          DoStore(ZipArchive, Item, DestStrm, InStream);\n        end;\n\n        smBestMethod : begin\n        { Item is to be archived using method producing best compression }\n          TempOut := TAbVirtualMemoryStream.Create;\n          try\n            TempOut.SwapFileDirectory := Sender.TempDirectory;\n\n            { save starting points }\n            InStartPos  := InStream.Position;\n\n            { try deflating item }\n            DoDeflate(ZipArchive, Item, TempOut, InStream);\n            { if deflated size > input size then got negative compression }\n            { so storing the item is more efficient }\n\n            if TempOut.Size > InStream.Size then begin { store item instead }\n              { reset streams to original positions }\n              InStream.Position  := InStartPos;\n              TempOut.Free;\n              TempOut := TAbVirtualMemoryStream.Create;\n              TempOut.SwapFileDirectory := Sender.TempDirectory;\n\n              { store item }\n              DoStore(ZipArchive, Item, TempOut, InStream);\n            end {if};\n\n            TempOut.Seek(0, soBeginning);\n            DestStrm.CopyFrom(TempOut, TempOut.Size);\n          finally\n            TempOut.Free;\n          end;\n        end;\n      end; { case }\n\n    end\n    else begin\n      { InStream is zero length}\n      Item.CRC32 := 0;\n      { ignore any storage indicator and treat as stored }\n      DoStore(ZipArchive, Item, DestStrm, InStream);\n    end;\n  finally\n    if DestStrm <> OutStream then\n      DestStrm.Free;\n  end;\n\n  { update item }\n  Item.CompressedSize := OutStream.Size;\n  Item.InternalFileAttributes := 0; { don't care }\n  if (ZipArchive.Password <> '') then\n    Item.GeneralPurposeBitFlag := Item.GeneralPurposeBitFlag\n      or AbFileIsEncryptedFlag or AbHasDataDescriptorFlag;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure AbZipFromStream(Sender : TAbZipArchive; Item : TAbZipItem;\n  OutStream, InStream : TStream);\nvar\n  FileTimeStamp : LongInt;\nbegin\n  // Set item properties for non-file streams\n  Item.ExternalFileAttributes := 0;\n  FileTimeStamp := DateTimeToFileDate(SysUtils.Now);\n  Item.LastModFileTime := LongRec(FileTimeStamp).Lo;\n  Item.LastModFileDate := LongRec(FileTimeStamp).Hi;\n\n  DoZipFromStream(Sender, Item, OutStream, InStream);\nend;\n{ -------------------------------------------------------------------------- }\nprocedure AbZip( Sender : TAbZipArchive; Item : TAbZipItem;\n                 OutStream : TStream );\nvar\n  UncompressedStream : TStream;\n  SaveDir : string;\n  AttrEx : TAbAttrExRec;\nbegin\n  UncompressedStream := nil;\n  GetDir(0, SaveDir);\n  try {SaveDir}\n    if (Sender.BaseDirectory <> '') then\n      ChDir(Sender.BaseDirectory);\n    if not AbFileGetAttrEx(Item.DiskFileName, AttrEx) then\n      raise EAbFileNotFound.Create;\n    if ((AttrEx.Attr and faDirectory) <> 0) then\n      UncompressedStream := TMemoryStream.Create\n    else\n      UncompressedStream :=\n        TFileStream.Create(Item.DiskFileName, fmOpenRead or fmShareDenyWrite);\n  finally {SaveDir}\n    ChDir( SaveDir );\n  end; {SaveDir}\n  try {UncompressedStream}\n    {$IFDEF UNIX}\n    Item.ExternalFileAttributes := LongWord(AttrEx.Mode) shl 16 + LongWord(AttrEx.Attr);\n    {$ELSE}\n    Item.ExternalFileAttributes := AttrEx.Attr;\n    {$ENDIF}\n    Item.LastModTimeAsDateTime := AttrEx.Time;\n    DoZipFromStream(Sender, Item, OutStream, UncompressedStream);\n  finally {UncompressedStream}\n    UncompressedStream.Free;\n  end; {UncompressedStream}\nend;\n{ -------------------------------------------------------------------------- }\nprocedure DeflateStream( UncompressedStream, CompressedStream : TStream );\n  {-Deflates everything in CompressedStream to UncompressedStream\n    no encryption is tried, no check on CRC is done, uses the whole\n    Uncompressedstream - no Progress events - no Frills!\n  }\nbegin\n  Deflate(UncompressedStream, CompressedStream, nil);\nend;\n{ -------------------------------------------------------------------------- }\n\nend.\n\n"
  },
  {
    "path": "lib/abbrevia/source/AbZipTyp.pas",
    "content": "(* ***** BEGIN LICENSE BLOCK *****\n * Version: MPL 1.1\n *\n * The contents of this file are subject to the Mozilla Public License Version\n * 1.1 (the \"License\"); you may not use this file except in compliance with\n * the License. You may obtain a copy of the License at\n * http://www.mozilla.org/MPL/\n *\n * Software distributed under the License is distributed on an \"AS IS\" basis,\n * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License\n * for the specific language governing rights and limitations under the\n * License.\n *\n * The Original Code is TurboPower Abbrevia\n *\n * The Initial Developer of the Original Code is\n * TurboPower Software\n *\n * Portions created by the Initial Developer are Copyright (C) 1997-2002\n * the Initial Developer. All Rights Reserved.\n *\n * Contributor(s):\n * Craig Peterson <capeterson@users.sourceforge.net>\n *\n * ***** END LICENSE BLOCK ***** *)\n\n{*********************************************************}\n{* ABBREVIA: AbZipTyp.pas                                *}\n{*********************************************************}\n{* ABBREVIA: PKZip types                                 *}\n{* Based on information from Appnote.txt, shipped with   *}\n{* PKWare's PKZip for Windows 2.5                        *}\n{*********************************************************}\n\nunit AbZipTyp;\n\n{$I AbDefine.inc}\n\ninterface\n\nuses\n  Classes, AbArcTyp, AbUtils, AbSpanSt;\n\nconst\n  { note  #$50 = 'P', #$4B = 'K'}\n  Ab_ZipVersion = 63;\n  Ab_ZipLocalFileHeaderSignature            : Longint = $04034B50;\n  Ab_ZipDataDescriptorSignature             : Longint = $08074B50;\n  Ab_ZipCentralDirectoryFileHeaderSignature : Longint = $02014B50;\n  Ab_Zip64EndCentralDirectorySignature      : Longint = $06064B50;\n  Ab_Zip64EndCentralDirectoryLocatorSignature:Longint = $07064B50;\n  Ab_ZipEndCentralDirectorySignature        : Longint = $06054B50;\n  Ab_ZipSpannedSetSignature                 : Longint = $08074B50;\n  Ab_ZipPossiblySpannedSignature            : Longint = $30304B50;\n  Ab_GeneralZipSignature                    : Word    = $4B50;\n\n  Ab_ArchiveExtraDataRecord                 : Longint = $08064B50;\n  Ab_DigitalSignature                       : Longint = $05054B50;\n\n  Ab_WindowsExeSignature                    : Word    = $5A4D;\n  Ab_LinuxExeSignature                      : Longint = $464C457F;\n\n  AbDefZipSpanningThreshold = 0;\n  AbDefPasswordRetries      = 3;\n  AbFileIsEncryptedFlag     = $0001;\n  AbHasDataDescriptorFlag   = $0008;\n  AbLanguageEncodingFlag    = $0800;\n\n  Ab_Zip64SubfieldID                        : Word    = $0001;\n  Ab_InfoZipUnicodePathSubfieldID           : Word    = $7075;\n  Ab_XceedUnicodePathSubfieldID             : Word    = $554E;\n  Ab_XceedUnicodePathSignature              : LongWord= $5843554E;\n\ntype\n  PAbByteArray4K = ^TAbByteArray4K;\n  TAbByteArray4K = array[1..4096] of Byte;\n  PAbByteArray8K = ^TAbByteArray8K;\n  TAbByteArray8K = array[0..8192] of Byte;\n  PAbIntArray8K  = ^TAbIntArray8K;\n  TAbIntArray8K  = array[0..8192] of SmallInt;\n\n  PAbWordArray   = ^TAbWordArray;\n  TAbWordArray   = array[0..65535 div SizeOf(Word)-1] of Word;\n  PAbByteArray   = ^TAbByteArray;\n  TAbByteArray   = array[0..65535-1] of Byte;\n  PAbSmallIntArray = ^TAbSmallIntArray;\n  TAbSmallIntArray = array[0..65535 div SizeOf(SmallInt)-1] of SmallInt;\n\n  PAbIntegerArray = ^TAbIntegerArray;\n  TAbIntegerArray = array[0..65535 div sizeof(integer)-1] of integer;\n\n  TAbZip64EndOfCentralDirectoryRecord = packed record\n    Signature               : Longint;\n    RecordSize              : Int64;\n    VersionMadeBy           : Word;\n    VersionNeededToExtract  : Word;\n    DiskNumber              : LongWord;\n    StartDiskNumber         : LongWord;\n    EntriesOnDisk           : Int64;\n    TotalEntries            : Int64;\n    DirectorySize           : Int64;\n    DirectoryOffset         : Int64;\n  end;\n\n  TAbZip64EndOfCentralDirectoryLocator = packed record\n    Signature               : Longint;\n    StartDiskNumber         : Longint;\n    RelativeOffset          : Int64;\n    TotalDisks              : Longint;\n  end;\n\n  TAbZipEndOfCentralDirectoryRecord = packed record\n    Signature               : Longint;\n    DiskNumber              : Word;\n    StartDiskNumber         : Word;\n    EntriesOnDisk           : Word;\n    TotalEntries            : Word;\n    DirectorySize           : LongWord;\n    DirectoryOffset         : LongWord;\n    CommentLength           : Word;\n  end;\n\n  TAbFollower =                      {used to expand reduced files}\n    packed record\n      Size : Byte;                {size of follower set}\n      FSet : array[0..31] of Byte; {follower set}\n    end;\n  PAbFollowerSets = ^TAbFollowerSets;\n  TAbFollowerSets = array[0..255] of TAbFollower;\n\n\n  PAbSfEntry = ^TAbSfEntry;\n  TAbSfEntry =                       {entry in a Shannon-Fano tree}\n    packed record\n      case Byte of\n        0 : (Code : Word; Value, BitLength : Byte);\n        1 : (L : Longint);\n    end;\n  PAbSfTree = ^TAbSfTree;\n  TAbSfTree =\n    packed record                        {a Shannon-Fano tree}\n      Entries : SmallInt;\n      MaxLength : SmallInt;\n      Entry : array[0..256] of TAbSfEntry;\n    end;\n\n  PInfoZipUnicodePathRec = ^TInfoZipUnicodePathRec;\n  TInfoZipUnicodePathRec = packed record\n    Version: Byte;\n    NameCRC32: LongInt;\n    UnicodeName: array[0..0] of AnsiChar;\n  end;\n\n  PXceedUnicodePathRec = ^TXceedUnicodePathRec;\n  TXceedUnicodePathRec = packed record\n    Signature: LongWord;\n    Length: Integer;\n    UnicodeName: array[0..0] of WideChar;\n  end;\n\n  PZip64LocalHeaderRec = ^TZip64LocalHeaderRec;\n  TZip64LocalHeaderRec = packed record\n    UncompressedSize: Int64;\n    CompressedSize: Int64;\n  end;\n\ntype\n  TAbZipCompressionMethod =\n    (cmStored, cmShrunk, cmReduced1, cmReduced2, cmReduced3,\n     cmReduced4, cmImploded, cmTokenized, cmDeflated,\n     cmEnhancedDeflated, cmDCLImploded, cmBzip2 = 12, cmLZMA = 14,\n     cmIBMTerse = 18, cmLZ77, cmJPEG = 96, cmWavPack = 97, cmPPMd);\n\n  TAbZipSupportedMethod =\n    (smStored, smDeflated, smBestMethod);\n\n  {ExternalFileAttributes compatibility;  aliases are Info-ZIP/PKZIP overlaps}\n  TAbZipHostOS =\n    (hosDOS, hosAmiga, hosVAX, hosUnix, hosVMCMS, hosAtari,\n     hosOS2, hosMacintosh, hosZSystem, hosCPM, hosNTFS, hosTOPS20 = hosNTFS,\n     hosMVS, hosWinNT = hosMVS, hosVSE, hosQDOS = hosVSE, hosRISC,\n     hosVFAT, hosAltMVS, hosBeOS, hosTandem, hosOS400, hosTHEOS = hosOS400,\n     hosDarwin, hosAtheOS = 30);\n\n  {for method 6 - imploding}\n  TAbZipDictionarySize =\n    (dsInvalid, ds4K, ds8K);\n\n  {for method 8 - deflating}\n  TAbZipDeflationOption =\n    (doInvalid, doNormal, doMaximum, doFast, doSuperFast );\n\ntype\n  TAbNeedPasswordEvent = procedure(Sender : TObject;\n                                   var NewPassword : AnsiString) of object;\n\nconst\n  AbDefCompressionMethodToUse = smBestMethod;\n  AbDefDeflationOption = doNormal;\n\n\ntype\n  TAbZipDataDescriptor = class( TObject )\n  protected {private}\n    FCRC32            : Longint;\n    FCompressedSize   : Int64;\n    FUncompressedSize : Int64;\n  public {methods}\n    procedure SaveToStream( Stream : TStream );\n  public {properties}\n    property CRC32 : Longint\n      read FCRC32 write FCRC32;\n    property CompressedSize : Int64\n      read FCompressedSize write FCompressedSize;\n    property UncompressedSize : Int64\n      read FUncompressedSize write FUncompressedSize;\n  end;\n\ntype\n{ TAbZipFileHeader interface =============================================== }\n  {ancestor class for ZipLocalFileHeader and DirectoryFileHeader}\n  TAbZipFileHeader = class( TObject )\n  protected {private}\n    FValidSignature : Longint;\n    FSignature : Longint;\n    FVersionNeededToExtract : Word;\n    FGeneralPurposeBitFlag : Word;\n    FCompressionMethod : Word;\n    FLastModFileTime : Word;\n    FLastModFileDate : Word;\n    FCRC32 : Longint;\n    FCompressedSize : LongWord;\n    FUncompressedSize : LongWord;\n    FFileName : AnsiString;\n    FExtraField : TAbExtraField;\n  protected {methods}\n    function GetCompressionMethod : TAbZipCompressionMethod;\n    function GetCompressionRatio : Double;\n    function GetDataDescriptor : Boolean;\n    function GetDeflationOption : TAbZipDeflationOption;\n    function GetDictionarySize : TAbZipDictionarySize;\n    function GetEncrypted : Boolean;\n    function GetIsUTF8 : Boolean;\n    function GetShannonFanoTreeCount : Byte;\n    function GetValid : Boolean;\n    procedure SetCompressionMethod( Value : TAbZipCompressionMethod );\n    procedure SetIsUTF8( Value : Boolean );\n  public {methods}\n    constructor Create;\n    destructor Destroy; override;\n  public {properties}\n    property Signature : Longint\n      read FSignature write FSignature;\n    property VersionNeededToExtract : Word\n      read FVersionNeededToExtract write FVersionNeededToExtract;\n    property GeneralPurposeBitFlag : Word\n      read FGeneralPurposeBitFlag write FGeneralPurposeBitFlag;\n    property CompressionMethod : TAbZipCompressionMethod\n      read GetCompressionMethod write SetCompressionMethod;\n    property LastModFileTime : Word\n      read FLastModFileTime write FLastModFileTime;\n    property LastModFileDate : Word\n      read FLastModFileDate write FLastModFileDate;\n    property CRC32 : Longint\n      read FCRC32 write FCRC32;\n    property CompressedSize : LongWord\n      read FCompressedSize write FCompressedSize;\n    property UncompressedSize : LongWord\n      read FUncompressedSize write FUncompressedSize;\n    property FileName : AnsiString\n      read FFileName write FFileName;\n    property ExtraField : TAbExtraField\n      read FExtraField;\n\n    property CompressionRatio : Double\n      read GetCompressionRatio;\n    property DeflationOption : TAbZipDeflationOption\n      read GetDeflationOption;\n    property DictionarySize : TAbZipDictionarySize\n      read GetDictionarySize;\n    property HasDataDescriptor : Boolean\n      read GetDataDescriptor;\n    property IsValid : Boolean\n      read GetValid;\n    property IsEncrypted : Boolean\n      read GetEncrypted;\n    property IsUTF8 : Boolean\n      read GetIsUTF8 write SetIsUTF8;\n    property ShannonFanoTreeCount : Byte\n      read GetShannonFanoTreeCount;\n  end;\n\n{ TAbZipLocalFileHeader interface ========================================== }\n  TAbZipLocalFileHeader = class( TAbZipFileHeader )\n  public {methods}\n    constructor Create;\n    destructor Destroy; override;\n    procedure LoadFromStream( Stream : TStream );\n    procedure SaveToStream( Stream : TStream );\n  end;\n\n{ TAbZipDirectoryFileHeader interface ====================================== }\n  TAbZipDirectoryFileHeader = class( TAbZipFileHeader )\n  protected {private}\n    FVersionMadeBy          : Word;\n    FDiskNumberStart        : Word;\n    FInternalFileAttributes : Word;\n    FExternalFileAttributes : LongWord;\n    FRelativeOffset         : LongWord;\n    FFileComment            : AnsiString;\n  public {methods}\n    constructor Create;\n    destructor Destroy; override;\n    procedure LoadFromStream( Stream : TStream );\n    procedure SaveToStream( Stream : TStream );\n  public {properties}\n    property VersionMadeBy : Word\n      read FVersionMadeBy write FVersionMadeBy;\n    property DiskNumberStart : Word\n      read FDiskNumberStart write FDiskNumberStart;\n    property InternalFileAttributes : Word\n      read FInternalFileAttributes write FInternalFileAttributes;\n    property ExternalFileAttributes : LongWord\n      read FExternalFileAttributes write FExternalFileAttributes;\n    property RelativeOffset : LongWord\n      read FRelativeOffset write FRelativeOffset;\n    property FileComment : AnsiString\n      read FFileComment write FFileComment;\n  end;\n\n{ TAbZipDirectoryFileFooter interface ====================================== }\n  TAbZipDirectoryFileFooter = class( TObject )\n  protected {private}\n    FDiskNumber             : LongWord;\n    FStartDiskNumber        : LongWord;\n    FEntriesOnDisk          : Int64;\n    FTotalEntries           : Int64;\n    FDirectorySize          : Int64;\n    FDirectoryOffset        : Int64;\n    FZipfileComment         : AnsiString;\n    function GetIsZip64: Boolean;\n  public {methods}\n    procedure LoadFromStream( Stream : TStream );\n    procedure LoadZip64FromStream( Stream : TStream );\n    procedure SaveToStream( Stream : TStream; aZip64TailOffset : Int64 = -1 );\n  public {properties}\n    property DiskNumber : LongWord\n      read FDiskNumber write FDiskNumber;\n    property EntriesOnDisk : Int64\n      read FEntriesOnDisk write FEntriesOnDisk;\n    property TotalEntries : Int64\n      read FTotalEntries write FTotalEntries;\n    property DirectorySize : Int64\n      read FDirectorySize write FDirectorySize;\n    property DirectoryOffset : Int64\n      read FDirectoryOffset write FDirectoryOffset;\n    property StartDiskNumber : LongWord\n      read FStartDiskNumber write FStartDiskNumber;\n    property ZipfileComment : AnsiString\n      read FZipfileComment write FZipfileComment;\n    property IsZip64: Boolean\n      read GetIsZip64;\n  end;\n\n{ TAbZipItem interface ===================================================== }\n  TAbZipItem = class( TAbArchiveItem )\n  protected {private}\n    FItemInfo : TAbZipDirectoryFileHeader;\n    FDiskNumberStart : LongWord;\n    FLFHExtraField : TAbExtraField;\n    FRelativeOffset : Int64;\n\n  protected {methods}\n    function GetCompressionMethod : TAbZipCompressionMethod;\n    function GetCompressionRatio : Double;\n    function GetDeflationOption : TAbZipDeflationOption;\n    function GetDictionarySize : TAbZipDictionarySize;\n    function GetExtraField : TAbExtraField;\n    function GetFileComment : AnsiString;\n    function GetGeneralPurposeBitFlag : Word;\n    function GetHostOS: TAbZipHostOS;\n    function GetInternalFileAttributes : Word;\n    function GetRawFileName : AnsiString;\n    function GetShannonFanoTreeCount : Byte;\n    function GetVersionMadeBy : Word;\n    function GetVersionNeededToExtract : Word;\n    procedure SaveCDHToStream( Stream : TStream );\n    procedure SaveDDToStream( Stream : TStream );\n    procedure SaveLFHToStream( Stream : TStream );\n    procedure SetCompressionMethod( Value : TAbZipCompressionMethod );\n    procedure SetDiskNumberStart( Value : LongWord );\n    procedure SetFileComment(const Value : AnsiString );\n    procedure SetGeneralPurposeBitFlag( Value : Word );\n    procedure SetHostOS( Value : TAbZipHostOS );\n    procedure SetInternalFileAttributes( Value : Word );\n    procedure SetRelativeOffset( Value : Int64 );\n    procedure SetVersionMadeBy( Value : Word );\n    procedure SetVersionNeededToExtract( Value : Word );\n    procedure UpdateVersionNeededToExtract;\n    procedure UpdateZip64ExtraHeader;\n\n  protected {redefined property methods}\n    function  GetCRC32 : Longint; override;\n    function  GetExternalFileAttributes : LongWord; override;\n    function  GetIsDirectory: Boolean; override;\n    function  GetIsEncrypted : Boolean; override;\n    function  GetLastModFileDate : Word; override;\n    function  GetLastModFileTime : Word; override;\n    function  GetNativeFileAttributes : LongInt; override;\n    procedure SetCompressedSize( const Value : Int64 ); override;\n    procedure SetCRC32( const Value : Longint ); override;\n    procedure SetExternalFileAttributes( Value : LongWord ); override;\n    procedure SetFileName(const Value : string ); override;\n    procedure SetLastModFileDate(const Value : Word ); override;\n    procedure SetLastModFileTime(const Value : Word ); override;\n    procedure SetUncompressedSize( const Value : Int64 ); override;\n\n  public {methods}\n    constructor Create;\n    destructor  Destroy; override;\n    procedure LoadFromStream( Stream : TStream );\n\n  public {properties}\n    property CompressionMethod : TAbZipCompressionMethod\n      read GetCompressionMethod\n      write SetCompressionMethod;\n    property CompressionRatio : Double\n      read GetCompressionRatio;\n    property DeflationOption : TAbZipDeflationOption\n      read GetDeflationOption;\n    property DictionarySize : TAbZipDictionarySize\n      read GetDictionarySize;\n    property DiskNumberStart : LongWord\n      read FDiskNumberStart\n      write SetDiskNumberStart;\n    property ExtraField : TAbExtraField\n      read GetExtraField;\n    property FileComment : AnsiString\n      read GetFileComment\n      write SetFileComment;\n    property HostOS: TAbZipHostOS\n      read GetHostOS\n      write SetHostOS;\n    property InternalFileAttributes : Word\n      read GetInternalFileAttributes\n      write SetInternalFileAttributes;\n    property GeneralPurposeBitFlag : Word\n      read GetGeneralPurposeBitFlag\n      write SetGeneralPurposeBitFlag;\n    property LFHExtraField : TAbExtraField\n      read FLFHExtraField;\n    property RawFileName : AnsiString\n      read GetRawFileName;\n    property RelativeOffset : Int64\n      read FRelativeOffset\n      write SetRelativeOffset;\n    property ShannonFanoTreeCount : Byte\n      read GetShannonFanoTreeCount;\n    property VersionMadeBy : Word\n      read GetVersionMadeBy\n      write SetVersionMadeBy;\n    property VersionNeededToExtract : Word\n      read GetVersionNeededToExtract\n      write SetVersionNeededToExtract;\n  end;\n\n{ TAbZipArchive interface ================================================== }\n  TAbZipArchive = class( TAbArchive )\n  protected {private}\n    FCompressionMethodToUse : TAbZipSupportedMethod;\n    FDeflationOption        : TAbZipDeflationOption;\n    FInfo                   : TAbZipDirectoryFileFooter;\n    FIsExecutable           : Boolean;\n    FPassword               : AnsiString;\n    FPasswordRetries        : Byte;\n    FStubSize               : LongWord;\n\n    FExtractHelper          : TAbArchiveItemExtractEvent;\n    FExtractToStreamHelper  : TAbArchiveItemExtractToStreamEvent;\n    FTestHelper             : TAbArchiveItemTestEvent;\n    FInsertHelper           : TAbArchiveItemInsertEvent;\n    FInsertFromStreamHelper : TAbArchiveItemInsertFromStreamEvent;\n    FOnNeedPassword         : TAbNeedPasswordEvent;\n    FOnRequestLastDisk      : TAbRequestDiskEvent;\n    FOnRequestNthDisk       : TAbRequestNthDiskEvent;\n    FOnRequestBlankDisk     : TAbRequestDiskEvent;\n\n  protected {methods}\n    procedure DoExtractHelper(Index : Integer; const NewName : string);\n    procedure DoExtractToStreamHelper(Index : Integer; aStream : TStream);\n    procedure DoTestHelper(Index : Integer);\n    procedure DoInsertHelper(Index : Integer; OutStream : TStream);\n    procedure DoInsertFromStreamHelper(Index : Integer; OutStream : TStream);\n    function GetItem( Index : Integer ) : TAbZipItem;\n    function GetZipfileComment : AnsiString;\n    procedure PutItem( Index : Integer; Value : TAbZipItem );\n    procedure DoRequestDisk(const AMessage: string; var Abort : Boolean);\n    procedure DoRequestLastDisk( var Abort : Boolean );\n      virtual;\n    procedure DoRequestNthDisk(Sender: TObject; DiskNumber : Byte; var Abort : Boolean );\n      virtual;\n    procedure DoRequestBlankDisk(Sender: TObject; var Abort : Boolean );\n      virtual;\n    procedure ExtractItemAt(Index : Integer; const UseName : string);\n      override;\n    procedure ExtractItemToStreamAt(Index : Integer; aStream : TStream);\n      override;\n    procedure TestItemAt(Index : Integer);\n      override;\n    function FixName(const Value : string ) : string;\n      override;\n    function GetSupportsEmptyFolders: Boolean;\n      override;\n    procedure LoadArchive;\n      override;\n    procedure SaveArchive;\n      override;\n    procedure SetZipfileComment(const Value : AnsiString );\n\n  protected {properties}\n    property IsExecutable : Boolean\n      read FIsExecutable write FIsExecutable;\n\n  public {protected}\n    procedure DoRequestImage(Sender: TObject; ImageNumber: Integer;\n      var ImageName: string; var Abort: Boolean);\n\n  public {methods}\n    constructor CreateFromStream( aStream : TStream; const ArchiveName : string );\n      override;\n    destructor Destroy;\n      override;\n    function CreateItem(const FileName : string): TAbArchiveItem;\n      override;\n\n  public {properties}\n    property CompressionMethodToUse : TAbZipSupportedMethod\n      read FCompressionMethodToUse\n      write FCompressionMethodToUse;\n    property DeflationOption : TAbZipDeflationOption\n      read FDeflationOption\n      write FDeflationOption;\n    property ExtractHelper : TAbArchiveItemExtractEvent\n      read FExtractHelper\n      write FExtractHelper;\n    property ExtractToStreamHelper : TAbArchiveItemExtractToStreamEvent\n      read FExtractToStreamHelper\n      write FExtractToStreamHelper;\n    property TestHelper : TAbArchiveItemTestEvent\n      read FTestHelper\n      write FTestHelper;\n    property InsertHelper : TAbArchiveItemInsertEvent\n      read FInsertHelper\n      write FInsertHelper;\n    property InsertFromStreamHelper : TAbArchiveItemInsertFromStreamEvent\n      read FInsertFromStreamHelper\n      write FInsertFromStreamHelper;\n    property Password : AnsiString\n      read FPassword\n      write FPassword;\n    property PasswordRetries : Byte\n      read FPasswordRetries\n      write FPasswordRetries\n      default AbDefPasswordRetries;\n    property StubSize : LongWord\n      read FStubSize;\n    property ZipfileComment : AnsiString\n      read GetZipfileComment\n      write SetZipfileComment;\n\n    property Items[Index : Integer] : TAbZipItem\n      read GetItem\n      write PutItem; default;\n\n  public {events}\n    property OnNeedPassword : TAbNeedPasswordEvent\n      read FOnNeedPassword write FOnNeedPassword;\n    property OnRequestLastDisk : TAbRequestDiskEvent\n      read FOnRequestLastDisk write FOnRequestLastDisk;\n    property OnRequestNthDisk : TAbRequestNthDiskEvent\n      read FOnRequestNthDisk write FOnRequestNthDisk;\n    property OnRequestBlankDisk : TAbRequestDiskEvent\n      read FOnRequestBlankDisk write FOnRequestBlankDisk;\n  end;\n\n{============================================================================}\nprocedure MakeSelfExtracting( StubStream, ZipStream,\n  SelfExtractingStream : TStream );\n    {-takes an executable stub, and a .zip format stream, and creates\n     a SelfExtracting stream.  The stub should create a TAbZipArchive\n     passing itself as the file, using a read-only open mode.  It should\n     then perform operations as needed - like ExtractFiles( '*.*' ).\n     This routine updates the RelativeOffset of each item in the archive}\n\nfunction FindCentralDirectoryTail(aStream : TStream) : Int64;\n\nfunction VerifyZip(Strm : TStream) : TAbArchiveType;\n\nfunction VerifySelfExtracting(Strm : TStream) : TAbArchiveType;\n\nfunction ZipCompressionMethodToString(aMethod: TAbZipCompressionMethod): string;\n\nimplementation\n\nuses\n  {$IFDEF MSWINDOWS}\n  Windows,\n  {$ENDIF}\n  {$IFDEF LibcAPI}\n  Libc,\n  {$ENDIF}\n  {$IFDEF UnixDialogs}\n  {$IFDEF KYLIX}\n  QControls,\n  QDialogs,\n  {$ENDIF}\n  {$IFDEF LCL}\n  Controls,\n  Dialogs,\n  {$ENDIF}\n  {$ENDIF}\n  Math,\n  AbCharset,\n  AbResString,\n  AbExcept,\n  AbVMStrm,\n  SysUtils;\n\nfunction VerifyZip(Strm : TStream) : TAbArchiveType;\n{ determine if stream appears to be in PkZip format }\nvar\n  Footer       : TAbZipEndOfCentralDirectoryRecord;\n  Sig          : LongInt;\n  TailPosition : int64;\n  StartPos     : int64;\nbegin\n  StartPos := Strm.Position;\n  Result := atUnknown;\n  try\n    Strm.Position := 0;\n    Strm.Read(Sig, SizeOf(Sig));\n    if (Sig = Ab_ZipSpannedSetSignature) then\n      Result := atSpannedZip\n    else begin\n      { attempt to find Central Directory Tail }\n      TailPosition := FindCentralDirectoryTail( Strm );\n      if TailPosition <> -1 then begin\n        { check Central Directory Signature }\n        Strm.ReadBuffer(Footer, SizeOf(Footer));\n        if Footer.Signature = Ab_ZipEndCentralDirectorySignature then\n          if Footer.DiskNumber = 0 then\n            Result := atZip\n          else\n            Result := atSpannedZip;\n      end;\n    end;\n  except\n    on EReadError do\n      Result := atUnknown;\n  end;\n  Strm.Position := StartPos;\nend;\n\nfunction VerifySelfExtracting(Strm : TStream) : TAbArchiveType;\n{ determine if stream appears to be an executable with appended PkZip data }\nvar\n  FileSignature : Longint;\n  StartPos      : Int64;\n  IsWinExe, IsLinuxExe : Boolean;\nbegin\n  StartPos := Strm.Position;\n  { verify presence of executable stub }\n  {check file type of stub stream}\n  Strm.Position := 0;\n  Strm.Read( FileSignature, sizeof( FileSignature ) );\n\n  Result := atSelfExtZip;\n\n  { detect executable type }\n  IsLinuxExe := FileSignature = Ab_LinuxExeSignature;\n  IsWinExe := LongRec(FileSignature).Lo = Ab_WindowsExeSignature;\n  if not (IsWinExe or IsLinuxExe) then\n    Result := atUnknown;\n\n  { Check for central directory tail }\n  if VerifyZip(Strm) <> atZip then\n    Result := atUnknown;\n\n  Strm.Position := StartPos;\nend;\n{============================================================================}\nfunction ZipCompressionMethodToString(aMethod: TAbZipCompressionMethod): string;\nbegin\n  case aMethod of\n    cmStored:\n      Result := AbZipStored;\n    cmShrunk:\n      Result := AbZipShrunk;\n    cmReduced1..cmReduced4:\n      Result := AbZipReduced;\n    cmImploded:\n      Result := AbZipImploded;\n    cmTokenized:\n      Result := AbZipTokenized;\n    cmDeflated:\n      Result := AbZipDeflated;\n    cmEnhancedDeflated:\n      Result := AbZipDeflate64;\n    cmDCLImploded:\n      Result := AbZipDCLImploded;\n    cmBzip2:\n      Result := AbZipBzip2;\n    cmLZMA:\n      Result := AbZipLZMA;\n    cmIBMTerse:\n      Result := AbZipIBMTerse;\n    cmLZ77:\n      Result := AbZipLZ77;\n    cmJPEG:\n      Result := AbZipJPEG;\n    cmWavPack:\n      Result := AbZipWavPack;\n    cmPPMd:\n      Result := AbZipPPMd;\n    else\n      Result := Format(AbZipUnknown, [Ord(aMethod)]);\n  end;\nend;\n{============================================================================}\nfunction FindCentralDirectoryTail(aStream : TStream) : Int64;\n{ search end of aStream looking for ZIP Central Directory structure\n  returns position in stream if found (otherwise returns -1),\n  leaves stream positioned at start of structure or at original\n  position if not found }\nconst\n  StartBufSize = 512;\n  MaxBufSize = 64 * 1024;\nvar\n  StartPos  : Int64;\n  TailRec   : TAbZipEndOfCentralDirectoryRecord;\n  Buffer    : PAnsiChar;\n  Offset    : Int64;\n  TestPos   : PAnsiChar;\n  Done      : boolean;\n  BytesRead : Int64;\n  BufSize   : Int64;\n  CommentLen: integer;\nbegin\n  {save the starting position}\n  StartPos := aStream.Seek(0, soCurrent);\n\n  {start off with the majority case: no zip file comment, so the\n   central directory tail is the last thing in the stream and it's a\n   fixed size and doesn't indicate a zip file comment}\n  Result := aStream.Seek(-sizeof(TailRec), soEnd);\n  if (Result >= 0) then begin\n    aStream.ReadBuffer(TailRec, sizeof(TailRec));\n    if (TailRec.Signature = Ab_ZipEndCentralDirectorySignature) and\n       (TailRec.CommentLength = 0) then begin\n      aStream.Seek(Result, soBeginning);\n      Exit;\n    end;\n  end;\n\n  {the zip stream seems to have a comment, or it has null padding\n   bytes from some flaky program, or it's not even a zip formatted\n   stream; we need to search for the tail signature}\n\n  {get a buffer}\n  BufSize := StartBufSize;\n  GetMem(Buffer, BufSize);\n  try\n\n    {start out searching backwards}\n    Offset := -BufSize;\n\n    {while there is still data to search ...}\n    Done := false;\n    while not Done do begin\n\n      {seek to the search position}\n      Result := aStream.Seek(Offset, soEnd);\n      if (Result <= 0) then begin\n        Result := aStream.Seek(0, soBeginning);\n        Done := true;\n      end;\n\n      {read a buffer full}\n      BytesRead := aStream.Read(Buffer^, BufSize);\n\n      if BytesRead < sizeOf(TailRec) then begin\n        Result := -1;\n        Exit;\n      end;\n\n      {search backwards through the buffer looking for the signature}\n      TestPos := Buffer + BytesRead - sizeof(TailRec);\n      while (TestPos <> Buffer) and\n            (PLongint(TestPos)^ <> Ab_ZipEndCentralDirectorySignature) do\n        dec(TestPos);\n\n      {if we found the signature...}\n      if (PLongint(TestPos)^ = Ab_ZipEndCentralDirectorySignature) then begin\n\n        {get the tail record at this position}\n        Move(TestPos^, TailRec, sizeof(TailRec));\n\n        {if it's as valid a tail as we can check here...}\n        CommentLen := -Offset - (TestPos - Buffer + sizeof(TailRec));\n        if (TailRec.CommentLength <= CommentLen) then begin\n\n          {calculate its position and exit}\n          Result := Result + (TestPos - Buffer);\n          aStream.Seek(Result, soBeginning);\n          Exit;\n        end;\n      end;\n\n      {otherwise move back one step, doubling the buffer}\n      if (BufSize < MaxBufSize) then begin\n        FreeMem(Buffer);\n        BufSize := BufSize * 2;\n        if BufSize > MaxBufSize then\n          BufSize := MaxBufSize;\n        GetMem(Buffer, BufSize);\n      end;\n      dec(Offset, BufSize - SizeOf(TailRec));\n    end;\n\n    {if we reach this point, the CD tail is not present}\n    Result := -1;\n    aStream.Seek(StartPos, soBeginning);\n  finally\n    FreeMem(Buffer);\n  end;\nend;\n{============================================================================}\nprocedure MakeSelfExtracting( StubStream, ZipStream,\n                              SelfExtractingStream : TStream );\n  {-takes an executable stub, and a .zip format stream, and creates\n   a SelfExtracting stream.  The stub should create a TAbZipArchive\n   passing itself as the file, using a read-only open mode.  It should\n   then perform operations as needed - like ExtractFiles( '*.*' ).\n   This routine updates the RelativeOffset of each item in the archive}\nvar\n  DirectoryStart : Int64;\n  FileSignature : Longint;\n  StubSize : LongWord;\n  TailPosition : Int64;\n  ZDFF : TAbZipDirectoryFileFooter;\n  ZipItem : TAbZipItem;\n  IsWinExe, IsLinuxExe : Boolean;\nbegin\n  {check file type of stub stream}\n  StubStream.Position := 0;\n  StubStream.Read(FileSignature, SizeOf(FileSignature));\n\n  {detect executable type }\n  IsLinuxExe := FileSignature = Ab_LinuxExeSignature;\n  IsWinExe := LongRec(FileSignature).Lo = Ab_WindowsExeSignature;\n\n  if not (IsWinExe or IsLinuxExe) then\n    raise EAbZipInvalidStub.Create;\n\n  StubStream.Position := 0;\n  StubSize := StubStream.Size;\n\n  ZipStream.Position := 0;\n  ZipStream.Read( FileSignature, sizeof( FileSignature ) );\n  if LongRec(FileSignature).Lo <> Ab_GeneralZipSignature then\n    raise EAbZipInvalid.Create;\n  ZipStream.Position := 0;\n\n  {copy the stub into the selfex stream}\n  SelfExtractingStream.Position := 0;\n  SelfExtractingStream.CopyFrom( StubStream, 0 );\n\n  TailPosition := FindCentralDirectoryTail( ZipStream );\n  if TailPosition = -1 then\n    raise EAbZipInvalid.Create;\n  {load the ZipDirectoryFileFooter}\n  ZDFF := TAbZipDirectoryFileFooter.Create;\n  try\n    ZDFF.LoadFromStream( ZipStream );\n    DirectoryStart := ZDFF.DirectoryOffset;\n  finally\n    ZDFF.Free;\n  end;\n  {copy everything up to the CDH into the SelfExtractingStream}\n  ZipStream.Position := 0;\n  SelfExtractingStream.CopyFrom( ZipStream, DirectoryStart );\n  ZipStream.Position := DirectoryStart;\n  repeat\n    ZipItem := TAbZipItem.Create;\n    try\n      ZipItem.LoadFromStream( ZipStream );\n      ZipItem.RelativeOffset := ZipItem.RelativeOffset + StubSize;\n      {save the modified entry into the Self Extracting Stream}\n      ZipItem.SaveCDHToStream( SelfExtractingStream );\n    finally\n      ZipItem.Free;\n    end;\n  until ZipStream.Position = TailPosition;\n\n  {save the CDH Footer.}\n  ZDFF := TAbZipDirectoryFileFooter.Create;\n  try\n    ZDFF.LoadFromStream( ZipStream );\n    ZDFF.DirectoryOffset := ZDFF.DirectoryOffset + StubSize;\n    ZDFF.SaveToStream( SelfExtractingStream );\n  finally\n    ZDFF.Free;\n  end;\nend;         \n{============================================================================}\n{ TAbZipDataDescriptor implementation ====================================== }\nprocedure TAbZipDataDescriptor.SaveToStream( Stream : TStream );\nbegin\n  Stream.Write( Ab_ZipDataDescriptorSignature, sizeof( Ab_ZipDataDescriptorSignature ) );\n  Stream.Write( FCRC32, sizeof( FCRC32 ) );\n  if (FCompressedSize >= $FFFFFFFF) or (FUncompressedSize >= $FFFFFFFF) then begin\n    Stream.Write( FCompressedSize, sizeof( FCompressedSize ) );\n    Stream.Write( FUncompressedSize, sizeof( FUncompressedSize ) );\n  end\n  else begin\n    Stream.Write( FCompressedSize, sizeof( LongWord ) );\n    Stream.Write( FUncompressedSize, sizeof( LongWord ) );\n  end;\nend;\n{ -------------------------------------------------------------------------- }\n\n{ TAbZipFileHeader implementation ========================================== }\nconstructor TAbZipFileHeader.Create;\nbegin\n  inherited Create;\n  FExtraField := TAbExtraField.Create;\n  FValidSignature := $0;\nend;\n{ -------------------------------------------------------------------------- }\ndestructor TAbZipFileHeader.Destroy;\nbegin\n  FreeAndNil(FExtraField);\n  inherited Destroy;\nend;\n{ -------------------------------------------------------------------------- }\nfunction TAbZipFileHeader.GetCompressionMethod : TAbZipCompressionMethod;\nbegin\n  Result := TAbZipCompressionMethod( FCompressionMethod );\nend;\n{ -------------------------------------------------------------------------- }\nfunction TAbZipFileHeader.GetDataDescriptor : Boolean;\nbegin\n  Result := ( CompressionMethod = cmDeflated ) and\n            ( ( FGeneralPurposeBitFlag and AbHasDataDescriptorFlag ) <> 0 );\nend;\n{ -------------------------------------------------------------------------- }\nfunction TAbZipFileHeader.GetCompressionRatio : Double;\nvar\n  CompSize : Int64;\nbegin\n  {adjust for encrypted headers - ensures we never get negative compression\n  ratios for stored, encrypted files - no guarantees about negative\n  compression ratios in other cases}\n  if isEncrypted then\n    CompSize := CompressedSize - 12\n  else\n    CompSize := CompressedSize;\n  if UncompressedSize > 0 then\n    Result := 100.0 * ( 1 - ( ( 1.0 * CompSize ) / UncompressedSize ) )\n  else\n    Result := 0.0;\nend;\n{ -------------------------------------------------------------------------- }\nfunction TAbZipFileHeader.GetDeflationOption : TAbZipDeflationOption;\nbegin\n  if CompressionMethod = cmDeflated then\n    if ( ( FGeneralPurposeBitFlag and $02 ) <> 0 ) then\n      if ( ( FGeneralPurposeBitFlag and $04 ) <> 0 ) then\n        Result := doSuperFast\n      else\n        Result := doMaximum\n    else\n      if ( ( FGeneralPurposeBitFlag and $04 ) <> 0 ) then\n        Result := doFast\n      else\n        Result := doNormal\n  else\n    Result := doInvalid;\nend;\n{ -------------------------------------------------------------------------- }\nfunction TAbZipFileHeader.GetDictionarySize : TAbZipDictionarySize;\nbegin\n  if CompressionMethod = cmImploded  then\n    if ( ( FGeneralPurposeBitFlag and $02 ) <> 0 ) then\n      Result := ds8K\n    else\n      Result := ds4K\n  else\n    Result := dsInvalid;\nend;\n{ -------------------------------------------------------------------------- }\nfunction TAbZipFileHeader.GetEncrypted : Boolean;\nbegin\n  {bit 0 of the GeneralPurposeBitFlag}\n  Result := ( ( FGeneralPurposeBitFlag and AbFileIsEncryptedFlag ) <> 0 );\nend;\n{ -------------------------------------------------------------------------- }\nfunction TAbZipFileHeader.GetIsUTF8 : Boolean;\nbegin\n  Result := ( ( GeneralPurposeBitFlag and AbLanguageEncodingFlag ) <> 0 );\nend;\n{ -------------------------------------------------------------------------- }\nfunction TAbZipFileHeader.GetShannonFanoTreeCount : Byte;\nbegin\n  if CompressionMethod = cmImploded then\n    if ( ( FGeneralPurposeBitFlag and $04 ) <> 0 ) then\n      Result := 3\n    else\n      Result := 2\n  else\n    Result := 0;\nend;\n{ -------------------------------------------------------------------------- }\nfunction TAbZipFileHeader.GetValid : Boolean;\nbegin\n  Result := ( FValidSignature = FSignature );\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbZipFileHeader.SetCompressionMethod( Value :\n                                               TAbZipCompressionMethod );\nbegin\n  FCompressionMethod := Ord( Value );\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbZipFileHeader.SetIsUTF8( Value : Boolean );\nbegin\n  if Value then\n    GeneralPurposeBitFlag := GeneralPurposeBitFlag or AbLanguageEncodingFlag\n  else\n    GeneralPurposeBitFlag := GeneralPurposeBitFlag and not AbLanguageEncodingFlag;\nend;\n{ -------------------------------------------------------------------------- }\n\n{ TAbZipLocalFileHeader implementation ===================================== }\nconstructor TAbZipLocalFileHeader.Create;\nbegin\n  inherited Create;\n  FValidSignature := Ab_ZipLocalFileHeaderSignature;\nend;\n{ -------------------------------------------------------------------------- }\ndestructor TAbZipLocalFileHeader.Destroy;\nbegin\n  inherited Destroy;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbZipLocalFileHeader.LoadFromStream( Stream : TStream );\nvar\n  ExtraFieldLength, FileNameLength : Word;\nbegin\n  with Stream do begin\n    Read( FSignature, sizeof( FSignature ) );\n    Read( FVersionNeededToExtract, sizeof( FVersionNeededToExtract ) );\n    Read( FGeneralPurposeBitFlag, sizeof( FGeneralPurposeBitFlag ) );\n    Read( FCompressionMethod, sizeof( FCompressionMethod ) );\n    Read( FLastModFileTime, sizeof( FLastModFileTime ) );\n    Read( FLastModFileDate, sizeof( FLastModFileDate ) );\n    Read( FCRC32, sizeof( FCRC32 ) );\n    Read( FCompressedSize, sizeof( FCompressedSize ) );\n    Read( FUncompressedSize, sizeof( FUncompressedSize ) );\n    Read( FileNameLength, sizeof( FileNameLength ) );\n    Read( ExtraFieldLength, sizeof( ExtraFieldLength ) );\n\n    SetLength( FFileName, FileNameLength );\n    if FileNameLength > 0 then\n      Read( FFileName[1], FileNameLength );\n\n    FExtraField.LoadFromStream( Stream, ExtraFieldLength );\n  end;\n  if not IsValid then\n    raise EAbZipInvalid.Create;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbZipLocalFileHeader.SaveToStream( Stream : TStream );\nvar\n  ExtraFieldLength, FileNameLength: Word;\nbegin\n  with Stream do begin\n    {write the valid signature from the constant}\n    Write( FValidSignature, sizeof( FValidSignature ) );\n    Write( FVersionNeededToExtract, sizeof( FVersionNeededToExtract ) );\n    Write( FGeneralPurposeBitFlag, sizeof( FGeneralPurposeBitFlag ) );\n    Write( FCompressionMethod, sizeof( FCompressionMethod ) );\n    Write( FLastModFileTime, sizeof( FLastModFileTime ) );\n    Write( FLastModFileDate, sizeof( FLastModFileDate ) );\n    Write( FCRC32, sizeof( FCRC32 ) );\n    Write( FCompressedSize, sizeof( FCompressedSize ) );\n    Write( FUncompressedSize, sizeof( FUncompressedSize ) );\n    FileNameLength := Word( Length( FFileName ) );\n    Write( FileNameLength, sizeof( FileNameLength ) );\n    ExtraFieldLength := Length(FExtraField.Buffer);\n    Write( ExtraFieldLength, sizeof( ExtraFieldLength ) );\n    if FileNameLength > 0 then\n      Write( FFileName[1], FileNameLength );\n    if ExtraFieldLength > 0 then\n      Write(FExtraField.Buffer[0], ExtraFieldLength);\n  end;\nend;\n{ -------------------------------------------------------------------------- }\n\n{ TAbZipDirectoryFileHeader implementation ================================= }\nconstructor TAbZipDirectoryFileHeader.Create;\nbegin\n  inherited Create;\n  FValidSignature := Ab_ZipCentralDirectoryFileHeaderSignature;\nend;\n{ -------------------------------------------------------------------------- }\ndestructor TAbZipDirectoryFileHeader.Destroy;\nbegin\n  inherited Destroy;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbZipDirectoryFileHeader.LoadFromStream( Stream : TStream );\nvar\n  ExtraFieldLength, FileCommentLength, FileNameLength : Word;\nbegin\n  with Stream do begin\n    Read( FSignature, sizeof( FSignature ) );\n    Read( FVersionMadeBy, sizeof( FVersionMadeBy ) );\n    Read( FVersionNeededToExtract, sizeof( FVersionNeededToExtract ) );\n    Read( FGeneralPurposeBitFlag, sizeof( FGeneralPurposeBitFlag ) );\n    Read( FCompressionMethod, sizeof( FCompressionMethod ) );\n    Read( FLastModFileTime, sizeof( FLastModFileTime ) );\n    Read( FLastModFileDate, sizeof( FLastModFileDate ) );\n    Read( FCRC32, sizeof( FCRC32 ) );\n    Read( FCompressedSize, sizeof( FCompressedSize ) );\n    Read( FUncompressedSize, sizeof( FUncompressedSize ) );\n    Read( FileNameLength, sizeof( FileNameLength ) );\n    Read( ExtraFieldLength, sizeof( ExtraFieldLength ) );\n    Read( FileCommentLength, sizeof( FileCommentLength ) );\n    Read( FDiskNumberStart, sizeof( FDiskNumberStart ) );\n    Read( FInternalFileAttributes, sizeof( FInternalFileAttributes ) );\n    Read( FExternalFileAttributes, sizeof( FExternalFileAttributes ) );\n    Read( FRelativeOffset, sizeof( FRelativeOffset ) );\n\n    SetLength( FFileName, FileNameLength );\n    if FileNameLength > 0 then\n      Read( FFileName[1], FileNameLength );\n\n    FExtraField.LoadFromStream( Stream, ExtraFieldLength );\n\n    SetLength( FFileComment, FileCommentLength );\n    if FileCommentLength > 0 then\n      Read( FFileComment[1], FileCommentLength );\n  end;\n  if not IsValid then\n    raise EAbZipInvalid.Create;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbZipDirectoryFileHeader.SaveToStream( Stream : TStream );\nvar\n  ExtraFieldLength, FileCommentLength, FileNameLength : Word;\nbegin\n  with Stream do begin\n    {write the valid signature from the constant}\n    Write( FValidSignature, sizeof( FValidSignature ) );\n    Write( FVersionMadeBy, sizeof( FVersionMadeBy ) );\n    Write( FVersionNeededToExtract, sizeof( FVersionNeededToExtract ) );\n    Write( FGeneralPurposeBitFlag, sizeof( FGeneralPurposeBitFlag ) );\n    Write( FCompressionMethod, sizeof( FCompressionMethod ) );\n    Write( FLastModFileTime, sizeof( FLastModFileTime ) );\n    Write( FLastModFileDate, sizeof( FLastModFileDate ) );\n    Write( FCRC32, sizeof( FCRC32 ) );\n    Write( FCompressedSize, sizeof( FCompressedSize ) );\n    Write( FUncompressedSize, sizeof( FUncompressedSize ) );\n    FileNameLength := Word( Length( FFileName ) );\n    Write( FileNameLength, sizeof( FileNameLength ) );\n    ExtraFieldLength := Length(FExtraField.Buffer);\n    Write( ExtraFieldLength, sizeof( ExtraFieldLength ) );\n    FileCommentLength := Word( Length( FFileComment ) );\n    Write( FileCommentLength, sizeof( FileCommentLength ) );\n    Write( FDiskNumberStart, sizeof( FDiskNumberStart ) );\n    Write( FInternalFileAttributes, sizeof( FInternalFileAttributes ) );\n    Write( FExternalFileAttributes, sizeof( FExternalFileAttributes ) );\n    Write( FRelativeOffset, sizeof( FRelativeOffset ) );\n    if FileNameLength > 0 then\n      Write( FFileName[1], FileNameLength );\n    if ExtraFieldLength > 0 then\n      Write( FExtraField.Buffer[0], ExtraFieldLength );\n    if FileCommentLength > 0 then\n      Write( FFileComment[1], FileCommentLength );\n  end;\nend;\n{ -------------------------------------------------------------------------- }\n\n{ TAbZipDirectoryFileFooter implementation ================================= }\nfunction TAbZipDirectoryFileFooter.GetIsZip64: Boolean;\nbegin\n  Result := (DiskNumber >= $FFFF) or\n            (StartDiskNumber >= $FFFF) or\n            (EntriesOnDisk >= $FFFF) or\n            (TotalEntries >= $FFFF) or\n            (DirectorySize >= $FFFFFFFF) or\n            (DirectoryOffset >= $FFFFFFFF);\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbZipDirectoryFileFooter.LoadFromStream( Stream : TStream );\nvar\n  Footer: TAbZipEndOfCentralDirectoryRecord;\nbegin\n  Stream.ReadBuffer( Footer, SizeOf(Footer) );\n  if Footer.Signature <> Ab_ZipEndCentralDirectorySignature then\n    raise EAbZipInvalid.Create;\n  FDiskNumber := Footer.DiskNumber;\n  FStartDiskNumber := Footer.StartDiskNumber;\n  FEntriesOnDisk := Footer.EntriesOnDisk;\n  FTotalEntries := Footer.TotalEntries;\n  FDirectorySize := Footer.DirectorySize;\n  FDirectoryOffset := Footer.DirectoryOffset;\n  SetLength( FZipfileComment, Footer.CommentLength );\n  if Footer.CommentLength > 0 then\n    Stream.ReadBuffer( FZipfileComment[1], Footer.CommentLength );\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbZipDirectoryFileFooter.LoadZip64FromStream( Stream : TStream );\n  {load the ZIP64 end of central directory record.\n   LoadFromStream() must be called first to load the standard record}\nvar\n  Footer: TAbZip64EndOfCentralDirectoryRecord;\nbegin\n  Stream.ReadBuffer( Footer, SizeOf(Footer) );\n  if Footer.Signature <> Ab_Zip64EndCentralDirectorySignature then\n    raise EAbZipInvalid.Create;\n  if FDiskNumber = $FFFF then\n    FDiskNumber := Footer.DiskNumber;\n  if FStartDiskNumber = $FFFF then\n    FStartDiskNumber := Footer.StartDiskNumber;\n  if FEntriesOnDisk = $FFFF then\n    FEntriesOnDisk := Footer.EntriesOnDisk;\n  if FTotalEntries = $FFFF then\n    FTotalEntries := Footer.TotalEntries;\n  if FDirectorySize = $FFFFFFFF then\n    FDirectorySize := Footer.DirectorySize;\n  if FDirectoryOffset = $FFFFFFFF then\n    FDirectoryOffset := Footer.DirectoryOffset;\n  {RecordSize, VersionMadeBy, and VersionNeededToExtract are currently ignored}\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbZipDirectoryFileFooter.SaveToStream( Stream : TStream;\n  aZip64TailOffset: Int64 = -1);\n  {write end of central directory record, along with Zip64 records if necessary.\n   aZip64TailOffset is the value to use for the Zip64 locator's directory\n   offset, and is only necessary when writing to an intermediate stream}\nvar\n  Footer: TAbZipEndOfCentralDirectoryRecord;\n  Zip64Footer: TAbZip64EndOfCentralDirectoryRecord;\n  Zip64Locator: TAbZip64EndOfCentralDirectoryLocator;\nbegin\n  if IsZip64 then begin\n    {setup Zip64 end of central directory record}\n    Zip64Footer.Signature := Ab_Zip64EndCentralDirectorySignature;\n    Zip64Footer.RecordSize := SizeOf(Zip64Footer) -\n      SizeOf(Zip64Footer.Signature) - SizeOf(Zip64Footer.RecordSize);\n    Zip64Footer.VersionMadeBy := 45;\n    Zip64Footer.VersionNeededToExtract := 45;\n    Zip64Footer.DiskNumber := DiskNumber;\n    Zip64Footer.StartDiskNumber := StartDiskNumber;\n    Zip64Footer.EntriesOnDisk := EntriesOnDisk;\n    Zip64Footer.TotalEntries := TotalEntries;\n    Zip64Footer.DirectorySize := DirectorySize;\n    Zip64Footer.DirectoryOffset := DirectoryOffset;\n    {setup Zip64 end of central directory locator}\n    Zip64Locator.Signature := Ab_Zip64EndCentralDirectoryLocatorSignature;\n    Zip64Locator.StartDiskNumber := DiskNumber;\n    if aZip64TailOffset = -1 then\n      Zip64Locator.RelativeOffset := Stream.Position\n    else\n      Zip64Locator.RelativeOffset := aZip64TailOffset;\n    Zip64Locator.TotalDisks := DiskNumber + 1;\n    {write Zip64 records}\n    Stream.WriteBuffer(Zip64Footer, SizeOf(Zip64Footer));\n    Stream.WriteBuffer(Zip64Locator, SizeOf(Zip64Locator));\n  end;\n  Footer.Signature := Ab_ZipEndCentralDirectorySignature;\n  Footer.DiskNumber := Min(FDiskNumber, $FFFF);\n  Footer.StartDiskNumber := Min(FStartDiskNumber, $FFFF);\n  Footer.EntriesOnDisk := Min(FEntriesOnDisk, $FFFF);\n  Footer.TotalEntries := Min(FTotalEntries, $FFFF);\n  Footer.DirectorySize := Min(FDirectorySize, $FFFFFFFF);\n  Footer.DirectoryOffset := Min(FDirectoryOffset, $FFFFFFFF);\n  Footer.CommentLength := Length( FZipfileComment );\n  Stream.WriteBuffer( Footer, SizeOf(Footer) );\n  if FZipfileComment <> '' then\n    Stream.Write( FZipfileComment[1], Length(FZipfileComment) );\nend;\n{ -------------------------------------------------------------------------- }\n\n{ TAbZipItem implementation ================================================ }\nconstructor TAbZipItem.Create;\nbegin\n  inherited Create;\n  FItemInfo := TAbZipDirectoryFileHeader.Create;\n  FLFHExtraField := TAbExtraField.Create;\nend;\n{ -------------------------------------------------------------------------- }\ndestructor TAbZipItem.Destroy;\nbegin\n  FLFHExtraField.Free;\n  FItemInfo.Free;\n  FItemInfo := nil;\n  inherited Destroy;\nend;\n{ -------------------------------------------------------------------------- }\nfunction TAbZipItem.GetCompressionMethod : TAbZipCompressionMethod;\nbegin\n  Result := FItemInfo.CompressionMethod;\nend;\n{ -------------------------------------------------------------------------- }\nfunction TAbZipItem.GetCompressionRatio : Double;\nbegin\n  Result := FItemInfo.CompressionRatio;\nend;\n{ -------------------------------------------------------------------------- }\nfunction TAbZipItem.GetCRC32 : Longint;\nbegin\n  Result := FItemInfo.CRC32;\nend;\n{ -------------------------------------------------------------------------- }\nfunction TAbZipItem.GetDeflationOption : TAbZipDeflationOption;\nbegin\n  Result := FItemInfo.DeflationOption;\nend;\n{ -------------------------------------------------------------------------- }\nfunction TAbZipItem.GetDictionarySize : TAbZipDictionarySize;\nbegin\n  Result := FItemInfo.DictionarySize;\nend;\n{ -------------------------------------------------------------------------- }\nfunction TAbZipItem.GetGeneralPurposeBitFlag : Word;\nbegin\n  Result := FItemInfo.GeneralPurposeBitFlag;\nend;\n{ -------------------------------------------------------------------------- }\nfunction TAbZipItem.GetHostOS: TAbZipHostOS;\nbegin\n  Result := TAbZipHostOS(Hi(VersionMadeBy));\nend;\n{ -------------------------------------------------------------------------- }\nfunction TAbZipItem.GetExternalFileAttributes : LongWord;\nbegin\n  Result := FItemInfo.ExternalFileAttributes;\nend;\n{ -------------------------------------------------------------------------- }\nfunction TAbZipItem.GetExtraField : TAbExtraField;\nbegin\n  Result := FItemInfo.ExtraField;\nend;\n{ -------------------------------------------------------------------------- }\nfunction TAbZipItem.GetFileComment : AnsiString;\nbegin\n  Result := FItemInfo.FileComment;\nend;\n{ -------------------------------------------------------------------------- }\nfunction TAbZipItem.GetInternalFileAttributes : Word;\nbegin\n  Result := FItemInfo.InternalFileAttributes;\nend;\n{ -------------------------------------------------------------------------- }\nfunction TAbZipItem.GetIsDirectory: Boolean;\nbegin\n  Result := ((ExternalFileAttributes and faDirectory) <> 0) or\n    ((FileName <> '') and CharInSet(Filename[Length(FFilename)], ['\\','/']));\nend;\n{ -------------------------------------------------------------------------- }\nfunction TAbZipItem.GetIsEncrypted : Boolean;\nbegin\n  Result := FItemInfo.IsEncrypted;\nend;\n{ -------------------------------------------------------------------------- }\nfunction TAbZipItem.GetLastModFileDate : Word;\nbegin\n  Result := FItemInfo.LastModFileDate;\nend;\n{ -------------------------------------------------------------------------- }\nfunction TAbZipItem.GetLastModFileTime : Word;\nbegin\n  Result := FItemInfo.LastModFileTime;\nend;\n{ -------------------------------------------------------------------------- }\nfunction TAbZipItem.GetNativeFileAttributes : LongInt;\nbegin\n{$IFDEF MSWINDOWS}\n  if (HostOS = hosUnix) or (ExternalFileAttributes > $1FFFF) then\n    Result := AbUnix2DosFileAttributes(ExternalFileAttributes shr 16)\n  else\n    Result := Byte(ExternalFileAttributes);\n{$ENDIF}\n{$IFDEF UNIX}\n  if HostOS in [hosDOS, hosNTFS, hosWinNT] then\n    Result := AbDOS2UnixFileAttributes(ExternalFileAttributes)\n  else\n    Result := ExternalFileAttributes shr 16;\n{$ENDIF}\nend;\n{ -------------------------------------------------------------------------- }\nfunction TAbZipItem.GetRawFileName : AnsiString;\nbegin\n  Result := FItemInfo.FileName;\nend;\n{ -------------------------------------------------------------------------- }\nfunction TAbZipItem.GetShannonFanoTreeCount : Byte;\nbegin\n  Result := FItemInfo.ShannonFanoTreeCount;\nend;\n{ -------------------------------------------------------------------------- }\nfunction TAbZipItem.GetVersionMadeBy : Word;\nbegin\n  Result := FItemInfo.VersionMadeBy;\nend;\n{ -------------------------------------------------------------------------- }\nfunction TAbZipItem.GetVersionNeededToExtract : Word;\nbegin\n  Result := FItemInfo.VersionNeededToExtract;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbZipItem.LoadFromStream( Stream : TStream );\nvar\n  FieldSize: Word;\n  FieldStream: TStream;\n  InfoZipField: PInfoZipUnicodePathRec;\n  UnicodeName: UnicodeString;\n  UTF8Name: AnsiString;\n  XceedField: PXceedUnicodePathRec;\nbegin\n  FItemInfo.LoadFromStream( Stream );\n\n  { decode filename (ANSI/OEM/UTF-8) }\n  if FItemInfo.IsUTF8 or (AbDetectCharSet(FItemInfo.FileName) = csUTF8) then\n    FFileName := UTF8ToString(FItemInfo.FileName)\n  else if FItemInfo.ExtraField.Get(Ab_InfoZipUnicodePathSubfieldID, Pointer(InfoZipField), FieldSize) and\n     (FieldSize > SizeOf(TInfoZipUnicodePathRec)) and\n     (InfoZipField.Version = 1) and\n     (InfoZipField.NameCRC32 = AbCRC32Of(FItemInfo.FileName)) then begin\n    SetString(UTF8Name, InfoZipField.UnicodeName,\n      FieldSize - SizeOf(TInfoZipUnicodePathRec) + 1);\n    FFileName := UTF8ToString(UTF8Name);\n  end\n  else if FItemInfo.ExtraField.Get(Ab_XceedUnicodePathSubfieldID, Pointer(XceedField), FieldSize) and\n     (FieldSize > SizeOf(TXceedUnicodePathRec)) and\n     (XceedField.Signature = Ab_XceedUnicodePathSignature) and\n     (XceedField.Length * SizeOf(WideChar) = FieldSize - SizeOf(TXceedUnicodePathRec) + SizeOf(WideChar)) then begin\n    SetString(UnicodeName, XceedField.UnicodeName, XceedField.Length);\n    FFileName := string(UnicodeName);\n  end\n  {$IFDEF MSWINDOWS}\n  else if (GetACP <> GetOEMCP) and ((HostOS = hosDOS) or AbIsOEM(FItemInfo.FileName)) then begin\n    SetLength(FFileName, Length(FItemInfo.FileName));\n    OemToCharBuff(PAnsiChar(FItemInfo.FileName), PChar(FFileName), Length(FFileName));\n  end\n  {$ENDIF}\n  else\n    FFileName := string(FItemInfo.FileName);\n\n  { read ZIP64 extended header }\n  FUncompressedSize := FItemInfo.UncompressedSize;\n  FCompressedSize := FItemInfo.CompressedSize;\n  FRelativeOffset := FItemInfo.RelativeOffset;\n  FDiskNumberStart := FItemInfo.DiskNumberStart;\n  if FItemInfo.ExtraField.GetStream(Ab_Zip64SubfieldID, FieldStream) then\n    try\n      if FItemInfo.UncompressedSize = $FFFFFFFF then\n        FieldStream.ReadBuffer(FUncompressedSize, SizeOf(Int64));\n      if FItemInfo.CompressedSize = $FFFFFFFF then\n        FieldStream.ReadBuffer(FCompressedSize, SizeOf(Int64));\n      if FItemInfo.RelativeOffset = $FFFFFFFF then\n        FieldStream.ReadBuffer(FRelativeOffset, SizeOf(Int64));\n      if FItemInfo.DiskNumberStart = $FFFF then\n        FieldStream.ReadBuffer(FDiskNumberStart, SizeOf(LongWord));\n    finally\n      FieldStream.Free;\n    end;\n\n  LastModFileTime := FItemInfo.LastModFileTime;\n  LastModFileDate := FItemInfo.LastModFileDate;\n  FDiskFileName := FileName;\n  AbUnfixName( FDiskFileName );\n  Action := aaNone;\n  Tagged := False;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbZipItem.SaveLFHToStream( Stream : TStream );\nvar\n  LFH : TAbZipLocalFileHeader;\n  Zip64Field: TZip64LocalHeaderRec;\nbegin\n  LFH := TAbZipLocalFileHeader.Create;\n  try\n    LFH.VersionNeededToExtract := VersionNeededToExtract;\n    LFH.GeneralPurposeBitFlag := GeneralPurposeBitFlag;\n    LFH.CompressionMethod := CompressionMethod;\n    LFH.LastModFileTime := LastModFileTime;\n    LFH.LastModFileDate := LastModFileDate;\n    LFH.CRC32 := CRC32;\n    LFH.FileName := RawFileName;\n    LFH.ExtraField.Assign(LFHExtraField);\n    LFH.ExtraField.CloneFrom(ExtraField, Ab_InfoZipUnicodePathSubfieldID);\n    LFH.ExtraField.CloneFrom(ExtraField, Ab_XceedUnicodePathSubfieldID);\n    { setup sizes;  unlike the central directory header, the ZIP64 local header\n      needs to store both compressed and uncompressed sizes if either needs it }\n    if (CompressedSize >= $FFFFFFFF) or (UncompressedSize >= $FFFFFFFF) then begin\n      LFH.UncompressedSize := $FFFFFFFF;\n      LFH.CompressedSize := $FFFFFFFF;\n      Zip64Field.UncompressedSize := UncompressedSize;\n      Zip64Field.CompressedSize := CompressedSize;\n      LFH.ExtraField.Put(Ab_Zip64SubfieldID, Zip64Field, SizeOf(Zip64Field));\n    end\n    else begin\n      LFH.UncompressedSize := UncompressedSize;\n      LFH.CompressedSize := CompressedSize;\n      LFH.ExtraField.Delete(Ab_Zip64SubfieldID);\n    end;\n    LFH.SaveToStream( Stream );\n  finally\n    LFH.Free;\n  end;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbZipItem.SaveCDHToStream( Stream : TStream );\n  {-Save a ZipCentralDirectorHeader entry to Stream}\nbegin\n  FItemInfo.SaveToStream( Stream );\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbZipItem.SaveDDToStream( Stream : TStream );\nvar\n  DD : TAbZipDataDescriptor;\nbegin\n  DD := TAbZipDataDescriptor.Create;\n  try\n    DD.CRC32 := CRC32;\n    DD.CompressedSize := CompressedSize;\n    DD.UncompressedSize := UncompressedSize;\n    DD.SaveToStream( Stream );\n  finally\n    DD.Free;\n  end;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbZipItem.SetCompressedSize( const Value : Int64 );\nbegin\n  FCompressedSize := Value;\n  FItemInfo.CompressedSize := Min(Value, $FFFFFFFF);\n  UpdateZip64ExtraHeader;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbZipItem.SetCompressionMethod( Value : TAbZipCompressionMethod );\nbegin\n  FItemInfo.CompressionMethod := Value;\n  UpdateVersionNeededToExtract;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbZipItem.SetCRC32( const Value : Longint );\nbegin\n  FItemInfo.CRC32 := Value;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbZipItem.SetDiskNumberStart( Value : LongWord );\nbegin\n  FDiskNumberStart := Value;\n  FItemInfo.DiskNumberStart := Min(Value, $FFFF);\n  UpdateZip64ExtraHeader;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbZipItem.SetExternalFileAttributes( Value : LongWord );\nbegin\n  FItemInfo.ExternalFileAttributes := Value;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbZipItem.SetFileComment(const Value : AnsiString );\nbegin\n  FItemInfo.FileComment := Value;\nend;\n{ -------------------------------------------------------------------------- }\n{$IFDEF KYLIX}{$IFOPT O+}{$DEFINE OPTIMIZATIONS_ON}{$O-}{$ENDIF}{$ENDIF}\nprocedure TAbZipItem.SetFileName(const Value : string );\nvar\n  {$IFDEF MSWINDOWS}\n  AnsiName : AnsiString;\n  {$ENDIF}\n  UTF8Name : AnsiString;\n  FieldSize : Word;\n  I : Integer;\n  InfoZipField : PInfoZipUnicodePathRec;\n  UseExtraField: Boolean;\nbegin\n  inherited SetFileName(Value);\n  {$IFDEF MSWINDOWS}\n  FItemInfo.IsUTF8 := False;\n  HostOS := hosDOS;\n  if AbTryEncode(Value, CP_OEMCP, False, AnsiName) then\n    {no-op}\n  else if (GetACP <> GetOEMCP) and AbTryEncode(Value, CP_ACP, False, AnsiName) then\n    HostOS := hosWinNT\n  else if AbTryEncode(Value, CP_OEMCP, True, AnsiName) then\n    {no-op}\n  else if (GetACP <> GetOEMCP) and AbTryEncode(Value, CP_ACP, True, AnsiName) then\n    HostOS := hosWinNT\n  else\n    FItemInfo.IsUTF8 := True;\n  if FItemInfo.IsUTF8 then\n    FItemInfo.FileName := Utf8Encode(Value)\n  else\n    FItemInfo.FileName := AnsiName;\n  {$ENDIF}\n  {$IFDEF UNIX}\n  FItemInfo.FileName := AnsiString(Value);\n  FItemInfo.IsUTF8 := AbSysCharSetIsUTF8;\n  {$ENDIF}\n\n  UseExtraField := False;\n  if not FItemInfo.IsUTF8 then\n    for i := 1 to Length(Value) do begin\n      if Ord(Value[i]) > 127 then begin\n        UseExtraField := True;\n        Break;\n      end;\n    end;\n\n  if UseExtraField then begin\n    UTF8Name := AnsiToUTF8(Value);\n    FieldSize := SizeOf(TInfoZipUnicodePathRec) + Length(UTF8Name) - 1;\n    GetMem(InfoZipField, FieldSize);\n    try\n      InfoZipField.Version := 1;\n      InfoZipField.NameCRC32 := AbCRC32Of(FItemInfo.FileName);\n      Move(UTF8Name[1], InfoZipField.UnicodeName, Length(UTF8Name));\n      FItemInfo.ExtraField.Put(Ab_InfoZipUnicodePathSubfieldID, InfoZipField^, FieldSize);\n    finally\n      FreeMem(InfoZipField);\n    end;\n  end\n  else\n    FItemInfo.ExtraField.Delete(Ab_InfoZipUnicodePathSubfieldID);\n  FItemInfo.ExtraField.Delete(Ab_XceedUnicodePathSubfieldID);\nend;\n{$IFDEF OPTIMIZATIONS_ON}{$O+}{$ENDIF}\n{ -------------------------------------------------------------------------- }\nprocedure TAbZipItem.SetGeneralPurposeBitFlag( Value : Word );\nbegin\n  FItemInfo.GeneralPurposeBitFlag := Value;\n  UpdateVersionNeededToExtract;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbZipItem.SetHostOS( Value : TAbZipHostOS );\nbegin\n  FItemInfo.VersionMadeBy := Low(FItemInfo.VersionMadeBy) or\n    Word(Ord(Value)) shl 8;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbZipItem.SetInternalFileAttributes( Value : Word );\nbegin\n  FItemInfo.InternalFileAttributes := Value;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbZipItem.SetLastModFileDate( const Value : Word );\nbegin\n  FItemInfo.LastModFileDate := Value;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbZipItem.SetLastModFileTime( const Value : Word );\nbegin\n  FItemInfo.LastModFileTime := Value;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbZipItem.SetRelativeOffset( Value : Int64 );\nbegin\n  FRelativeOffset := Value;\n  FItemInfo.RelativeOffset := Min(Value, $FFFFFFFF);\n  UpdateZip64ExtraHeader;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbZipItem.SetUncompressedSize( const Value : Int64 );\nbegin\n  FUncompressedSize := Value;\n  FItemInfo.UncompressedSize:= Min(Value, $FFFFFFFF);\n  UpdateZip64ExtraHeader;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbZipItem.SetVersionMadeBy( Value : Word );\nbegin\n  FItemInfo.VersionMadeBy := Value;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbZipItem.SetVersionNeededToExtract( Value : Word );\nbegin\n  FItemInfo.VersionNeededToExtract := Value;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbZipItem.UpdateVersionNeededToExtract;\n  {calculates VersionNeededToExtract and VersionMadeBy based on used features}\nbegin\n  {According to AppNote.txt zipx compression methods should set the Version\n   Needed To Extract to the AppNote version the method was introduced in (e.g.,\n   6.3 for PPMd).  Most utilities just set it to 2.0 and rely on the extractor\n   detecting unsupported compression methods, since it's easier to add support\n   for decompression methods without implementing the entire newer spec. }\n  if ExtraField.Has(Ab_Zip64SubfieldID) then\n    VersionNeededToExtract := 45\n  else if IsDirectory or IsEncrypted or not (CompressionMethod in [cmStored..cmImploded]) then\n    VersionNeededToExtract := 20\n  else\n    VersionNeededToExtract := 10;\n  VersionMadeBy := (VersionMadeBy and $FF00) + Max(20, VersionNeededToExtract);\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbZipItem.UpdateZip64ExtraHeader;\nvar\n  Changed: Boolean;\n  FieldStream: TMemoryStream;\nbegin\n  FieldStream := TMemoryStream.Create;\n  try\n    if UncompressedSize >= $FFFFFFFF then\n      FieldStream.WriteBuffer(FUncompressedSize, SizeOf(Int64));\n    if CompressedSize >= $FFFFFFFF then\n      FieldStream.WriteBuffer(FCompressedSize, SizeOf(Int64));\n    if RelativeOffset >= $FFFFFFFF then\n      FieldStream.WriteBuffer(FRelativeOffset, SizeOf(Int64));\n    if DiskNumberStart >= $FFFF then\n      FieldStream.WriteBuffer(FDiskNumberStart, SizeOf(LongWord));\n    Changed := (FieldStream.Size > 0) <> ExtraField.Has(Ab_Zip64SubfieldID);\n    if FieldStream.Size > 0 then\n      ExtraField.Put(Ab_Zip64SubfieldID, FieldStream.Memory^, FieldStream.Size)\n    else\n      ExtraField.Delete(Ab_Zip64SubfieldID);\n    if Changed then\n      UpdateVersionNeededToExtract;\n  finally\n    FieldStream.Free;\n  end;\nend;\n{ -------------------------------------------------------------------------- }\n\n\n{ TAbZipArchive implementation ============================================= }\nconstructor TAbZipArchive.CreateFromStream( aStream : TStream;\n                                      const ArchiveName : string );\nbegin\n  inherited CreateFromStream( aStream, ArchiveName );\n  FCompressionMethodToUse := smBestMethod;\n  FInfo := TAbZipDirectoryFileFooter.Create;\n  StoreOptions := StoreOptions + [soStripDrive];\n  FDeflationOption := doNormal;\n  FPasswordRetries := AbDefPasswordRetries;\n  FTempDir := '';\n  SpanningThreshold := AbDefZipSpanningThreshold;\nend;\n{ -------------------------------------------------------------------------- }\ndestructor TAbZipArchive.Destroy;\nbegin\n  FInfo.Free;\n  FInfo := nil;\n  inherited Destroy;\nend;\n{ -------------------------------------------------------------------------- }\nfunction TAbZipArchive.CreateItem( const FileName : string ): TAbArchiveItem;\nvar\n  FileSpec : string;\nbegin\n  FileSpec := FileName;\n  Result := TAbZipItem.Create;\n  with TAbZipItem( Result ) do begin\n    CompressionMethod := cmDeflated;\n    GeneralPurposeBitFlag := 0;\n    CompressedSize := 0;\n    CRC32 := 0;\n    DiskFileName := ExpandFileName(FileSpec);\n    FileName := FixName(FileSpec);\n    RelativeOffset := 0;\n  end;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbZipArchive.DoExtractHelper(Index : Integer; const NewName : string);\nbegin\n  if Assigned(FExtractHelper) then\n    FExtractHelper(Self, ItemList[Index], NewName)\n  else\n    raise EAbZipNoExtraction.Create;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbZipArchive.DoExtractToStreamHelper(Index : Integer;\n                                                aStream : TStream);\nbegin\n  if Assigned(FExtractToStreamHelper) then\n    FExtractToStreamHelper(Self, ItemList[Index], aStream)\n  else\n    raise EAbZipNoExtraction.Create;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbZipArchive.DoTestHelper(Index : Integer);\nbegin\n  if Assigned(FTestHelper) then\n    FTestHelper(Self, ItemList[Index])\n  else\n    raise EAbZipNoExtraction.Create;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbZipArchive.DoInsertHelper(Index : Integer; OutStream : TStream);\nbegin\n  if Assigned(FInsertHelper) then\n    FInsertHelper(Self, ItemList[Index], OutStream)\n  else\n    raise EAbZipNoInsertion.Create;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbZipArchive.DoInsertFromStreamHelper(Index : Integer;\n  OutStream : TStream);\nbegin\n  if Assigned(FInsertFromStreamHelper) then\n    FInsertFromStreamHelper(Self, ItemList[Index], OutStream, InStream)\n  else\n    raise EAbZipNoInsertion.Create;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbZipArchive.DoRequestDisk(const AMessage: string; var Abort : Boolean);\nbegin\n{$IFDEF MSWINDOWS}\n  Abort := Windows.MessageBox( 0, PChar(AMessage), PChar(AbDiskRequestS),\n    MB_TASKMODAL or MB_OKCANCEL ) = IDCANCEL;\n{$ENDIF}\n{$IFDEF UnixDialogs}\n  {$IFDEF KYLIX}\n  Abort := QDialogs.MessageDlg(AbDiskRequestS, AMessage, mtWarning,\n    mbOKCancel, 0) = mrCancel;\n  {$ENDIF}\n  {$IFDEF LCL}\n  Abort := Dialogs.MessageDlg(AbDiskRequestS, AMessage, mtWarning, mbOKCancel,\n    0) = mrCancel;\n  {$ENDIF}\n{$ELSE}\n  Abort := True;\n{$ENDIF}\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbZipArchive.DoRequestLastDisk( var Abort : Boolean );\nbegin\n  Abort := False;\n  if Assigned( FOnRequestLastDisk ) then\n    FOnRequestLastDisk( Self, Abort )\n  else\n    DoRequestDisk( AbLastDiskRequestS, Abort );\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbZipArchive.DoRequestNthDisk( Sender: TObject;\n                                          DiskNumber : Byte;\n                                          var Abort : Boolean );\nbegin\n  Abort := False;\n  if Assigned( FOnRequestNthDisk ) then\n    FOnRequestNthDisk( Self, DiskNumber, Abort )\n  else\n    DoRequestDisk( Format(AbDiskNumRequestS, [DiskNumber]), Abort );\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbZipArchive.DoRequestBlankDisk(Sender: TObject; var Abort : Boolean );\nbegin\n  Abort := False;\n  FSpanned := True;\n\n  if Assigned( FOnRequestBlankDisk ) then\n    FOnRequestBlankDisk( Self, Abort )\n  else\n    DoRequestDisk( AbBlankDiskS, Abort );\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbZipArchive.DoRequestImage(Sender: TObject; ImageNumber : Integer;\n  var ImageName : string ; var Abort : Boolean);\nbegin\n  if Assigned(FOnRequestImage) then\n    FOnRequestImage(Self, ImageNumber, ImageName, Abort);\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbZipArchive.ExtractItemAt(Index : Integer; const UseName : string);\nbegin\n  DoExtractHelper(Index, UseName);\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbZipArchive.ExtractItemToStreamAt(Index : Integer;\n                                              aStream : TStream);\nbegin\n  DoExtractToStreamHelper(Index, aStream);\nend;\n{ -------------------------------------------------------------------------- }\nfunction TAbZipArchive.FixName(const Value : string ) : string;\n  {-changes backslashes to forward slashes}\nvar\n  i : SmallInt;\n  lValue : string;\nbegin\n  lValue := Value;\n  {$IFDEF MSWINDOWS}\n  if DOSMode then begin\n    {Add the base directory to the filename before converting }\n    {the file spec to the short filespec format. }\n    if BaseDirectory <> '' then begin\n      {Does the filename contain a drive or a leading backslash? }\n      if not ((Pos(':', lValue) = 2) or (Pos(AbPathDelim, lValue) = 1)) then\n        {If not, add the BaseDirectory to the filename.}\n        lValue := AbAddBackSlash(BaseDirectory) + lValue;\n    end;\n    lValue := AbGetShortFileSpec( lValue );\n  end;\n  {$ENDIF MSWINDOWS}\n\n  {Zip files Always strip the drive path}\n  StoreOptions := StoreOptions + [soStripDrive];\n\n  {strip drive stuff}\n  if soStripDrive in StoreOptions then\n    AbStripDrive( lValue );\n\n  {check for a leading backslash}\n  if (Length(lValue) > 1) and (lValue[1] = AbPathDelim) then\n    System.Delete( lValue, 1, 1 );\n\n  if soStripPath in StoreOptions then begin\n    lValue := ExtractFileName( lValue );\n  end;\n\n  if soRemoveDots in StoreOptions then\n    AbStripDots( lValue );\n\n  for i := 1 to Length( lValue ) do\n    if lValue[i] = '\\' then\n      lValue[i] := '/';\n  Result := lValue;\nend;\n{ -------------------------------------------------------------------------- }\nfunction TAbZipArchive.GetItem( Index : Integer ) : TAbZipItem;\nbegin\n  Result := TAbZipItem(FItemList.Items[Index]);\nend;\n{ -------------------------------------------------------------------------- }\nfunction TAbZipArchive.GetSupportsEmptyFolders: Boolean;\nbegin\n  Result := True;\nend;\n{ -------------------------------------------------------------------------- }\nfunction TAbZipArchive.GetZipfileComment : AnsiString;\nbegin\n  Result := FInfo.ZipfileComment;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbZipArchive.LoadArchive;\nvar\n  Abort : Boolean;\n  TailPosition : int64;\n  Item : TAbZipItem;\n  Progress : Byte;\n  FileSignature : Longint;\n  Zip64Locator : TAbZip64EndOfCentralDirectoryLocator;\nbegin\n  Abort := False;\n  if FStream.Size = 0 then\n    Exit;\n\n  {Get signature info}\n  FStream.Position := 0;\n  FStream.Read( FileSignature, sizeof( FileSignature ) );\n\n  {Get Executable Type;  allow non-native stubs}\n  IsExecutable :=\n    (LongRec(FileSignature).Lo = Ab_WindowsExeSignature) or\n    (FileSignature = Ab_LinuxExeSignature);\n\n  { try to locate central directory tail }\n  TailPosition := FindCentralDirectoryTail( FStream );\n  if (TailPosition = -1) and (FileSignature = Ab_ZipSpannedSetSignature) and\n     FOwnsStream and AbDriveIsRemovable(ArchiveName) then begin\n    while TailPosition = -1 do begin\n      FreeAndNil(FStream);\n      DoRequestLastDisk(Abort);\n      if Abort then begin\n        FStatus := asInvalid; //TODO: Status updates are extremely inconsistent\n        raise EAbUserAbort.Create;\n      end;\n      FStream := TFileStream.Create( ArchiveName, Mode );\n      TailPosition := FindCentralDirectoryTail( FStream );\n    end;\n  end;\n\n  if TailPosition = -1 then begin\n    FStatus := asInvalid;\n    raise EAbZipInvalid.Create;\n  end;\n\n  { load the ZipDirectoryFileFooter }\n  FInfo.LoadFromStream(FStream);\n\n  { find Zip64 end of central directory locator; it will usually occur\n    immediately before the standard end of central directory record.\n    the actual Zip64 end of central directory may be on another disk }\n  if FInfo.IsZip64 then begin\n    Dec(TailPosition, SizeOf(Zip64Locator));\n    repeat\n      if TailPosition < 0 then\n        raise EAbZipInvalid.Create;\n      FStream.Position := TailPosition;\n      FStream.ReadBuffer(Zip64Locator, SizeOf(Zip64Locator));\n      Dec(TailPosition);\n    until Zip64Locator.Signature = Ab_Zip64EndCentralDirectoryLocatorSignature;\n    { update current image number }\n    FInfo.DiskNumber := Zip64Locator.TotalDisks - 1;\n  end;\n\n  { setup spanning support and move to the start of the central directory }\n  FSpanned := FInfo.DiskNumber > 0;\n\n  if FSpanned then begin\n    if FOwnsStream then begin\n      FStream := TAbSpanReadStream.Create( ArchiveName, FInfo.DiskNumber, FStream );\n      TAbSpanReadStream(FStream).OnRequestImage := DoRequestImage;\n      TAbSpanReadStream(FStream).OnRequestNthDisk := DoRequestNthDisk;\n      if FInfo.IsZip64 then begin\n        TAbSpanReadStream(FStream).SeekImage(Zip64Locator.StartDiskNumber,\n          Zip64Locator.RelativeOffset);\n        FInfo.LoadZip64FromStream(FStream);\n      end;\n      TAbSpanReadStream(FStream).SeekImage(FInfo.StartDiskNumber, FInfo.DirectoryOffset);\n    end\n    else\n      raise EAbZipBadSpanStream.Create;\n  end\n  else begin\n    if FInfo.IsZip64 then begin\n      FStream.Position := Zip64Locator.RelativeOffset;\n      FInfo.LoadZip64FromStream(FStream);\n    end;\n    FStream.Position := FInfo.DirectoryOffset;\n  end;\n\n  { build Items list from central directory records }\n  FStubSize := High(LongWord);\n  while Count < FInfo.TotalEntries do begin\n    { create new Item }\n    Item := TAbZipItem.Create;\n    try\n      Item.LoadFromStream(FStream);\n      Item.Action := aaNone;\n      FItemList.Add(Item);\n    except\n      Item.Free;\n      raise;\n    end;\n\n    if IsExecutable and (Item.DiskNumberStart = 0) and\n       (Item.RelativeOffset < FStubSize) then\n      FStubSize := Item.RelativeOffset;\n\n    Progress := (Count * 100) div FInfo.TotalEntries;\n    DoArchiveProgress( Progress, Abort );\n    if Abort then begin\n      FStatus := asInvalid;\n      raise EAbUserAbort.Create;\n    end;\n  end;\n\n  DoArchiveProgress(100, Abort);\n  FIsDirty := False;\nend;\n\n{ -------------------------------------------------------------------------- }\nprocedure TAbZipArchive.PutItem( Index : Integer; Value : TAbZipItem );\nbegin\n  FItemList.Items[Index] := Value;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbZipArchive.SaveArchive;\n  {builds a new archive and copies it to FStream}\nvar\n  Abort              : Boolean;\n  MemStream          : TMemoryStream;\n  HasDataDescriptor  : Boolean;\n  i                  : LongWord;\n  LFH                : TAbZipLocalFileHeader;\n  NewStream          : TStream;\n  WorkingStream      : TAbVirtualMemoryStream;\n  CurrItem           : TAbZipItem;\n  Progress           : Byte;\nbegin\n  if Count = 0 then\n    Exit;\n\n  {shouldn't be trying to overwrite an existing spanned archive}\n  if Spanned then begin\n    for i := 0 to Pred(Count) do\n      if ItemList[i].Action <> aaFailed then\n        ItemList[i].Action := aaNone;\n    FIsDirty := False;\n    raise EAbZipSpanOverwrite.Create;\n  end;\n\n  {init new zip archive stream\n   can span only new archives, if SpanningThreshold > 0 or removable drive\n   spanning writes to original location, rather than writing to a temp stream first}\n  if FOwnsStream and (FStream.Size = 0) and not IsExecutable and\n     ((SpanningThreshold > 0) or  AbDriveIsRemovable(ArchiveName)) then begin\n    NewStream := TAbSpanWriteStream.Create(ArchiveName, FStream, SpanningThreshold);\n    FStream := nil;\n    TAbSpanWriteStream(NewStream).OnRequestBlankDisk := DoRequestBlankDisk;\n    TAbSpanWriteStream(NewStream).OnRequestImage := DoRequestImage;\n  end\n  else begin\n    NewStream := TAbVirtualMemoryStream.Create;\n    TAbVirtualMemoryStream(NewStream).SwapFileDirectory := FTempDir;\n  end;\n\n  try {NewStream}\n    {copy the executable stub over to the output}\n    if IsExecutable then\n      NewStream.CopyFrom( FStream, StubSize )\n    {assume spanned for spanning stream}\n    else if NewStream is TAbSpanWriteStream then\n      NewStream.Write(Ab_ZipSpannedSetSignature,\n        SizeOf(Ab_ZipSpannedSetSignature));\n\n    {build new zip archive from existing archive}\n    for i := 0 to pred( Count ) do begin\n      CurrItem := (ItemList[i] as TAbZipItem);\n      FCurrentItem := ItemList[i];\n\n      case CurrItem.Action of\n        aaNone, aaMove: begin\n          {just copy the file to new stream}\n          Assert(not (NewStream is TAbSpanWriteStream));\n          FStream.Position := CurrItem.RelativeOffset;\n          CurrItem.DiskNumberStart := 0;\n          CurrItem.RelativeOffset := NewStream.Position;\n          {toss old local file header}\n          LFH := TAbZipLocalFileHeader.Create;\n          try {LFH}\n            LFH.LoadFromStream( FStream );\n            if CurrItem.LFHExtraField.Count = 0 then\n              CurrItem.LFHExtraField.Assign(LFH.ExtraField);\n          finally {LFH}\n            LFH.Free;\n          end; {LFH}\n          {write out new local file header and append compressed data}\n\n          CurrItem.SaveLFHToStream( NewStream );\n          if (CurrItem.CompressedSize > 0) then\n            NewStream.CopyFrom(FStream, CurrItem.CompressedSize);\n        end;\n\n        aaDelete: begin\n          {doing nothing omits file from new stream}\n        end;\n\n        aaAdd, aaFreshen, aaReplace, aaStreamAdd: begin\n          {compress the file and add it to new stream}\n          try\n            WorkingStream := TAbVirtualMemoryStream.Create;\n            try {WorkingStream}\n              WorkingStream.SwapFileDirectory := FTempDir;\n              {compress the file}\n              if (CurrItem.Action = aaStreamAdd) then\n                DoInsertFromStreamHelper(i, WorkingStream)\n              else\n                DoInsertHelper(i, WorkingStream);\n              {write local header}\n              if NewStream is TAbSpanWriteStream then begin\n                MemStream := TMemoryStream.Create;\n                try\n                  CurrItem.SaveLFHToStream(MemStream);\n                  TAbSpanWriteStream(NewStream).WriteUnspanned(\n                    MemStream.Memory^, MemStream.Size);\n                  {calculate positions after the write in case it triggered a new span}\n                  CurrItem.DiskNumberStart := TAbSpanWriteStream(NewStream).CurrentImage;\n                  CurrItem.RelativeOffset := NewStream.Position - MemStream.Size;\n                finally\n                  MemStream.Free;\n                end;\n              end\n              else begin\n                CurrItem.DiskNumberStart := 0;\n                CurrItem.RelativeOffset := NewStream.Position;\n                CurrItem.SaveLFHToStream(NewStream);\n              end;\n              {copy compressed data}\n              NewStream.CopyFrom(WorkingStream, 0);\n              if CurrItem.IsEncrypted then\n                CurrItem.SaveDDToStream(NewStream);\n            finally\n              WorkingStream.Free;\n            end;\n          except\n            on E : Exception do\n            begin\n              { Exception was caused by a User Abort and Item Failure should not be called\n                Question:  Do we want an New Event when this occurs or should the\n                exception just be re-raised [783614] }\n              if (E is EAbUserAbort) then\n                raise;\n              CurrItem.Action := aaDelete;\n              DoProcessItemFailure(CurrItem, ptAdd, ecFileOpenError, 0);\n            end;\n          end;\n        end;\n      end; { case }\n\n      { TODO: Check HasDataDescriptior behavior;  seems like it's getting\n              written twice for encrypted files }\n      {Now add the data descriptor record to new stream}\n      HasDataDescriptor := (CurrItem.CompressionMethod = cmDeflated) and\n        ((CurrItem.GeneralPurposeBitFlag and AbHasDataDescriptorFlag) <> 0);\n      if (CurrItem.Action <> aaDelete) and HasDataDescriptor then\n        CurrItem.SaveDDToStream(NewStream);\n      Progress := AbPercentage(9 * succ( i ), 10 * Count);\n      DoArchiveSaveProgress(Progress, Abort);\n      DoArchiveProgress(Progress, Abort);\n      if Abort then\n        raise EAbUserAbort.Create;\n    end;\n\n    {write the central directory}\n    if NewStream is TAbSpanWriteStream then\n      FInfo.DiskNumber := TAbSpanWriteStream(NewStream).CurrentImage\n    else\n      FInfo.DiskNumber := 0;\n    FInfo.StartDiskNumber := FInfo.DiskNumber;\n    FInfo.DirectoryOffset := NewStream.Position;\n    FInfo.DirectorySize := 0;\n    FInfo.EntriesOnDisk := 0;\n    FInfo.TotalEntries := 0;\n    MemStream := TMemoryStream.Create;\n    try\n      {write central directory entries}\n      for i := 0 to Count - 1 do begin\n        if not (FItemList[i].Action in [aaDelete, aaFailed]) then begin\n          (FItemList[i] as TAbZipItem).SaveCDHToStream(MemStream);\n          if NewStream is TAbSpanWriteStream then begin\n            TAbSpanWriteStream(NewStream).WriteUnspanned(MemStream.Memory^, MemStream.Size);\n            {update tail info on span change}\n            if FInfo.DiskNumber <> TAbSpanWriteStream(NewStream).CurrentImage then begin\n              FInfo.DiskNumber := TAbSpanWriteStream(NewStream).CurrentImage;\n              FInfo.EntriesOnDisk := 0;\n              if FInfo.TotalEntries = 0 then begin\n                FInfo.StartDiskNumber := FInfo.DiskNumber;\n                FInfo.DirectoryOffset := NewStream.Position - MemStream.Size;\n              end;\n            end;\n          end\n          else\n            NewStream.WriteBuffer(MemStream.Memory^, MemStream.Size);\n          FInfo.DirectorySize := FInfo.DirectorySize + MemStream.Size;\n          FInfo.EntriesOnDisk := FInfo.EntriesOnDisk + 1;\n          FInfo.TotalEntries := FInfo.TotalEntries + 1;\n          MemStream.Clear;\n        end;\n      end;\n      {append the central directory footer}\n      FInfo.SaveToStream(MemStream, NewStream.Position);\n      if NewStream is TAbSpanWriteStream then begin\n        {update the footer if writing it would trigger a new span}\n        if not TAbSpanWriteStream(NewStream).WriteUnspanned(MemStream.Memory^,\n                                                            MemStream.Size) then begin\n          FInfo.DiskNumber := TAbSpanWriteStream(NewStream).CurrentImage;\n          FInfo.EntriesOnDisk := 0;\n          FInfo.SaveToStream(NewStream);\n        end;\n      end\n      else\n        NewStream.WriteBuffer(MemStream.Memory^, MemStream.Size);\n    finally {MemStream}\n      MemStream.Free;\n    end; {MemStream}\n\n    FSpanned := (FInfo.DiskNumber > 0);\n\n    {update output stream}\n    if NewStream is TAbSpanWriteStream then begin\n      {zip has already been written to target location}\n      FStream := TAbSpanWriteStream(NewStream).ReleaseStream;\n      if Spanned then begin\n        {switch to read stream}\n        FStream := TAbSpanReadStream.Create(ArchiveName, FInfo.DiskNumber, FStream);\n        TAbSpanReadStream(FStream).OnRequestImage := DoRequestImage;\n        TAbSpanReadStream(FStream).OnRequestNthDisk := DoRequestNthDisk;\n      end\n      else begin\n        {replace spanned signature}\n        FStream.Position := 0;\n        FStream.Write(Ab_ZipPossiblySpannedSignature,\n          SizeOf(Ab_ZipPossiblySpannedSignature));\n      end;\n    end\n    else begin\n      {copy new stream to FStream (non-spanned only)}\n      NewStream.Position := 0;\n      if (FStream is TMemoryStream) then\n        TMemoryStream(FStream).LoadFromStream(NewStream)\n      else begin\n        if FOwnsStream then begin\n          {need new stream to write}\n          FreeAndNil(FStream);\n          FStream := TFileStream.Create(FArchiveName,\n            fmOpenReadWrite or fmShareDenyWrite);\n        end;\n        FStream.Size := 0;\n        FStream.Position := 0;\n        FStream.CopyFrom(NewStream, 0)\n      end;\n    end;\n\n    {update Items list}\n    for i := pred( Count ) downto 0 do begin\n      if FItemList[i].Action = aaDelete then\n        FItemList.Delete( i )\n      else if FItemList[i].Action <> aaFailed then\n        FItemList[i].Action := aaNone;\n    end;\n\n    DoArchiveSaveProgress( 100, Abort );\n    DoArchiveProgress( 100, Abort );\n  finally {NewStream}\n    NewStream.Free;\n  end;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbZipArchive.SetZipfileComment(const Value : AnsiString );\nbegin\n  FInfo.FZipfileComment := Value;\n  FIsDirty := True;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbZipArchive.TestItemAt(Index : Integer);\nbegin\n  DoTestHelper(Index);\nend;\n\nend.\n\n\n\n\n"
  },
  {
    "path": "lib/abbrevia/source/AbZipper.pas",
    "content": "(* ***** BEGIN LICENSE BLOCK *****\n * Version: MPL 1.1\n *\n * The contents of this file are subject to the Mozilla Public License Version\n * 1.1 (the \"License\"); you may not use this file except in compliance with\n * the License. You may obtain a copy of the License at\n * http://www.mozilla.org/MPL/\n *\n * Software distributed under the License is distributed on an \"AS IS\" basis,\n * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License\n * for the specific language governing rights and limitations under the\n * License.\n *\n * The Original Code is TurboPower Abbrevia\n *\n * The Initial Developer of the Original Code is\n * TurboPower Software\n *\n * Portions created by the Initial Developer are Copyright (C) 1997-2002\n * the Initial Developer. All Rights Reserved.\n *\n * Contributor(s):\n *\n * ***** END LICENSE BLOCK ***** *)\n\n{*********************************************************}\n{* ABBREVIA: AbZipper.pas                                *}\n{*********************************************************}\n{* ABBREVIA: Non-visual Component with Zip support       *}\n{*********************************************************}\n\nunit AbZipper;\n\n{$I AbDefine.inc}\n\ninterface\n\nuses\n  Classes,\n  AbBrowse, AbZBrows, AbArcTyp, AbZipTyp;\n\ntype\n  TAbCustomZipper = class(TAbCustomZipBrowser)\n  protected {private}\n    FAutoSave               : Boolean;\n    FCompressionMethodToUse : TAbZipSupportedMethod;\n    FDeflationOption        : TAbZipDeflationOption;\n    FDOSMode : Boolean;\n    FOnConfirmSave          : TAbArchiveConfirmEvent;\n    FOnSave                 : TAbArchiveEvent;\n    FOnArchiveSaveProgress  : TAbArchiveProgressEvent;\n    FArchiveSaveProgressMeter : IAbProgressMeter;\n\n    FStoreOptions           : TAbStoreOptions;\n\n  protected {methods}\n    procedure DoConfirmSave(Sender : TObject; var Confirm : Boolean);\n      virtual;\n    procedure DoSave(Sender : TObject);\n      virtual;\n    procedure DoArchiveSaveProgress(Sender : TObject; Progress : Byte;\n                                    var Abort : Boolean);\n\n    procedure InitArchive;\n      override;\n    procedure SetAutoSave(Value : Boolean);\n    procedure SetCompressionMethodToUse(Value : TAbZipSupportedMethod);\n    procedure SetDeflationOption(Value : TAbZipDeflationOption);\n    procedure SetDOSMode( Value : Boolean );\n    procedure SetFileName(const aFileName : string);\n      override;\n    procedure SetStoreOptions( Value : TAbStoreOptions );\n    procedure SetArchiveSaveProgressMeter(const Value: IAbProgressMeter);\n    procedure SetZipfileComment(const Value : AnsiString);\n      override;\n    procedure ZipProc(Sender : TObject; Item : TAbArchiveItem;\n                      OutStream : TStream);\n    procedure ZipFromStreamProc(Sender : TObject; Item : TAbArchiveItem;\n                                OutStream, InStream : TStream );\n    procedure Notification(Component: TComponent;\n      Operation: TOperation); override;\n    procedure ResetMeters; override;\n\n  protected {properties}\n    property AutoSave : Boolean\n      read  FAutoSave\n      write SetAutoSave;\n    property CompressionMethodToUse : TAbZipSupportedMethod\n      read  FCompressionMethodToUse\n      write SetCompressionMethodToUse\n      default AbDefCompressionMethodToUse;\n    property DeflationOption : TAbZipDeflationOption\n      read  FDeflationOption\n      write SetDeflationOption\n      default AbDefDeflationOption;\n    property DOSMode : Boolean\n      read  FDOSMode\n      write SetDOSMode;\n    property StoreOptions : TAbStoreOptions\n      read  FStoreOptions\n      write SetStoreOptions\n      default AbDefStoreOptions;\n    property ArchiveSaveProgressMeter : IAbProgressMeter\n      read  FArchiveSaveProgressMeter\n      write SetArchiveSaveProgressMeter;\n\n\n  protected {events}\n    property OnConfirmSave : TAbArchiveConfirmEvent\n      read  FOnConfirmSave\n      write FOnConfirmSave;\n    property OnSave : TAbArchiveEvent\n      read  FOnSave\n      write FOnSave;\n    property OnArchiveSaveProgress : TAbArchiveProgressEvent\n      read FOnArchiveSaveProgress\n      write FOnArchiveSaveProgress;\n\n  public {methods}\n    constructor Create(AOwner : TComponent);\n      override;\n    destructor Destroy;\n      override;\n    procedure AddFiles(const FileMask : string; SearchAttr : Integer);\n    procedure AddFilesEx(const FileMask, ExclusionMask : string; SearchAttr : Integer);\n    procedure AddFromStream(const NewName : string; FromStream : TStream);\n    procedure DeleteAt(Index : Integer);\n    procedure DeleteFiles(const FileMask : string);\n    procedure DeleteFilesEx(const FileMask, ExclusionMask : string);\n    procedure DeleteTaggedItems;\n    procedure FreshenFiles(const FileMask : string);\n    procedure FreshenFilesEx(const FileMask, ExclusionMask : string);\n    procedure FreshenTaggedItems;\n    procedure Move(aItem : TAbArchiveItem; const NewStoredPath : string);\n    procedure Save;\n    procedure Replace(aItem : TAbArchiveItem);\n  end;\n\ntype\n  TAbZipper = class(TAbCustomZipper)\n  published\n    property ArchiveProgressMeter;\n    property ArchiveSaveProgressMeter;\n    property ItemProgressMeter;\n    property AutoSave;\n    property BaseDirectory;\n    property CompressionMethodToUse;\n    property DeflationOption;\n    property DOSMode;\n    property SpanningThreshold;\n    property LogFile;\n    property Logging;\n    property OnArchiveProgress;\n    property OnArchiveSaveProgress;\n    property OnArchiveItemProgress;\n    property OnChange;\n    property OnConfirmProcessItem;\n    property OnConfirmSave;\n    property OnLoad;\n    property OnProcessItemFailure;\n    property OnRequestBlankDisk;\n    property OnRequestImage;\n    property OnRequestLastDisk;\n    property OnRequestNthDisk;\n    property OnSave;\n    property Password;\n    property StoreOptions;\n    property TempDirectory;\n    property Version;\n    property FileName; {must be after OnLoad}\n  end;\n\nimplementation\n\nuses\n  SysUtils, AbUtils, AbTarTyp, AbGzTyp, AbBzip2Typ, AbExcept, AbZipPrc;\n\n{ -------------------------------------------------------------------------- }\nconstructor TAbCustomZipper.Create( AOwner : TComponent );\nbegin\n  inherited Create( AOwner );\n  CompressionMethodToUse := AbDefCompressionMethodToUse;\n  DeflationOption := AbDefDeflationOption;\n  StoreOptions := AbDefStoreOptions;\nend;\n{ -------------------------------------------------------------------------- }\ndestructor TAbCustomZipper.Destroy;\nbegin\n  inherited Destroy;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbCustomZipper.AddFiles(const FileMask : string; SearchAttr : Integer);\n  {Add files to the archive where the disk filespec matches}\nbegin\n  if (FArchive <> nil) then\n    FArchive.AddFiles(FileMask, SearchAttr)\n  else\n    raise EAbNoArchive.Create;\n  DoChange;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbCustomZipper.AddFilesEx(const FileMask, ExclusionMask : string;\n  SearchAttr : Integer);\n  {Add files that match Filemask except those matching ExclusionMask}\nbegin\n  if (FArchive <> nil) then\n    FArchive.AddFilesEx(FileMask, ExclusionMask, SearchAttr)\n  else\n    raise EAbNoArchive.Create;\n  DoChange;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbCustomZipper.AddFromStream(const NewName : string;\n                                        FromStream : TStream);\n  {Add stream directly to archive}\nbegin\n  if (FArchive <> nil) then begin\n    FromStream.Position := 0;\n    FArchive.AddFromStream(NewName, FromStream);\n  end else\n    raise EAbNoArchive.Create;\n  DoChange;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbCustomZipper.DeleteFiles(const FileMask : string);\n  {delete all files from the archive that match the file mask}\nbegin\n  if (FArchive <> nil) then\n    FArchive.DeleteFiles( FileMask )\n  else\n    raise EAbNoArchive.Create;\n  DoChange;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbCustomZipper.DeleteAt(Index : Integer);\n  {delete item at Index}\nbegin\n  if (FArchive <> nil) then\n    FArchive.DeleteAt( Index )\n  else\n    raise EAbNoArchive.Create;\n  DoChange;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbCustomZipper.DeleteFilesEx(const FileMask, ExclusionMask : string);\n  {Delete files that match Filemask except those matching ExclusionMask}\nbegin\n  if (FArchive <> nil) then\n    FArchive.DeleteFilesEx(FileMask, ExclusionMask)\n  else\n    raise EAbNoArchive.Create;\n  DoChange;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbCustomZipper.DeleteTaggedItems;\n  {delete all tagged items from the archive}\nbegin\n  if (FArchive <> nil) then\n    FArchive.DeleteTaggedItems\n  else\n    raise EAbNoArchive.Create;\n  DoChange;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbCustomZipper.DoConfirmSave(Sender : TObject; var Confirm : Boolean);\nbegin\n  Confirm := True;\n  if Assigned(FOnConfirmSave) then\n    FOnConfirmSave(Self, Confirm);\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbCustomZipper.DoSave(Sender : TObject);\nbegin\n  if Assigned(FOnSave) then\n    FOnSave(Self);\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbCustomZipper.FreshenFiles(const FileMask : string);\n  {freshen all items that match the file mask}\nbegin\n  if (FArchive <> nil) then\n    FArchive.FreshenFiles( FileMask )\n  else\n    raise EAbNoArchive.Create;\n  DoChange;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbCustomZipper.FreshenFilesEx(const FileMask, ExclusionMask : string);\n  {freshen all items matching FileMask except those matching ExclusionMask}\nbegin\n  if (FArchive <> nil) then\n    FArchive.FreshenFilesEx( FileMask, ExclusionMask )\n  else\n    raise EAbNoArchive.Create;\n  DoChange;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbCustomZipper.FreshenTaggedItems;\n  {freshen all tagged items}\nbegin\n  if (FArchive <> nil) then\n    FArchive.FreshenTaggedItems\n  else\n    raise EAbNoArchive.Create;\n  DoChange;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbCustomZipper.InitArchive;\nbegin\n  inherited InitArchive;\n  if FArchive <> nil then begin\n    {properties}\n    FArchive.AutoSave                                := FAutoSave;\n    FArchive.DOSMode                                 := FDOSMode;\n    FArchive.StoreOptions                            := FStoreOptions;\n    {events}\n    FArchive.OnArchiveSaveProgress                   := DoArchiveSaveProgress;\n    FArchive.OnConfirmSave                           := DoConfirmSave;\n    FArchive.OnSave                                  := DoSave;\n  end;\n  if (FArchive is TAbZipArchive) then begin\n    {properties}\n    TAbZipArchive(FArchive).CompressionMethodToUse := FCompressionMethodToUse;\n    TAbZipArchive(FArchive).DeflationOption        := FDeflationOption;\n    {events}\n    TAbZipArchive(FArchive).OnRequestBlankDisk     := OnRequestBlankDisk;\n    TAbZipArchive(FArchive).InsertHelper           := ZipProc;\n    TAbZipArchive(FArchive).InsertFromStreamHelper := ZipFromStreamProc;\n  end;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbCustomZipper.Move(aItem : TAbArchiveItem; const NewStoredPath : string);\n  {renames the item}\nbegin\n  if (FArchive <> nil) then\n    FArchive.Move(aItem, NewStoredPath)\n  else\n    raise EAbNoArchive.Create;\n  DoChange;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbCustomZipper.Replace(aItem : TAbArchiveItem);\n  {replace the item}\nbegin\n  if (FArchive <> nil) then\n    FArchive.Replace( aItem )\n  else\n    raise EAbNoArchive.Create;\n  DoChange;                                                            \nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbCustomZipper.Save;\nbegin\n  if (FArchive <> nil) then begin\n    FArchive.Save;\n    DoChange;\n  end;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbCustomZipper.SetAutoSave(Value : Boolean);\nbegin\n  FAutoSave := Value;\n  if (FArchive <> nil) then\n    FArchive.AutoSave := Value;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbCustomZipper.SetCompressionMethodToUse(\n  Value : TAbZipSupportedMethod);\nbegin\n  FCompressionMethodToUse := Value;\n  if (FArchive is TAbZipArchive) then\n    TAbZipArchive(FArchive).CompressionMethodToUse := Value;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbCustomZipper.SetDeflationOption(Value : TAbZipDeflationOption);\nbegin\n  FDeflationOption := Value;\n  if (FArchive is TAbZipArchive) then\n    TAbZipArchive(FArchive).DeflationOption := Value;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbCustomZipper.SetDOSMode(Value : Boolean);\nbegin\n  FDOSMode := Value;\n  if (FArchive <> nil) then\n    FArchive.DOSMode := Value;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbCustomZipper.SetFileName(const aFileName : string);\nvar\n  ArcType : TAbArchiveType;\nbegin\n  FFileName := aFileName;\n  if (csDesigning in ComponentState) then\n    Exit;\n\n  if Assigned(FArchive) then\n  begin\n    FArchive.Save;\n    FreeAndNil(FArchive);\n  end;\n\n  ArcType := ArchiveType;\n\n  if (FileName <> '') then\n    if FileExists(FileName) then begin { open it }\n\n    if not ForceType then\n      ArcType := AbDetermineArcType(FileName, atUnknown);\n\n      case ArcType of\n        atZip, atSpannedZip, atSelfExtZip : begin\n         FArchive := TAbZipArchive.Create(FileName, fmOpenRead or fmShareDenyNone);\n         InitArchive;\n        end;\n\n        atTar : begin\n          FArchive := TAbTarArchive.Create(FileName, fmOpenReadWrite or fmShareDenyNone);\n          inherited InitArchive;\n        end;\n\n        atGZip : begin\n          FArchive := TAbGzipArchive.Create(FileName, fmOpenReadWrite or fmShareDenyNone);\n          TAbGzipArchive(FArchive).TarAutoHandle := FTarAutoHandle;\n          TAbGzipArchive(FArchive).IsGzippedTar := False;\n          inherited InitArchive;\n        end;\n\n        atGZippedTar : begin\n          FArchive := TAbGzipArchive.Create(FileName, fmOpenReadWrite or fmShareDenyNone);\n          TAbGzipArchive(FArchive).TarAutoHandle := FTarAutoHandle;\n          TAbGzipArchive(FArchive).IsGzippedTar := True;\n          inherited InitArchive;\n        end;\n\n        atBzip2 : begin\n          FArchive := TAbBzip2Archive.Create(FileName, fmOpenReadWrite or fmShareDenyNone);\n          TAbBzip2Archive(FArchive).TarAutoHandle := FTarAutoHandle;\n          TAbBzip2Archive(FArchive).IsBzippedTar := False;\n          inherited InitArchive;\n        end;\n\n        atBzippedTar : begin\n          FArchive := TAbBzip2Archive.Create(FileName, fmOpenReadWrite or fmShareDenyNone);\n          TAbBzip2Archive(FArchive).TarAutoHandle := FTarAutoHandle;\n          TAbBzip2Archive(FArchive).IsBzippedTar := True;\n          inherited InitArchive;\n        end;\n\n        else\n          raise EAbUnhandledType.Create;\n      end {case};\n      FArchive.Load;\n      FArchiveType := ArcType;\n\n    end else begin  { file doesn't exist, so create a new one }\n      if not ForceType then\n        ArcType := AbDetermineArcType(FileName, atUnknown);\n\n      case ArcType of\n        atZip : begin                                                    \n          FArchive := TAbZipArchive.Create(FileName, fmCreate);\n          InitArchive;\n        end;\n\n        atTar : begin\n          FArchive := TAbTarArchive.Create(FileName, fmCreate or fmShareDenyNone);\n          inherited InitArchive;\n        end;\n\n        atGZip : begin\n          FArchive := TAbGzipArchive.Create(FileName, fmCreate or fmShareDenyNone);\n          TAbGzipArchive(FArchive).TarAutoHandle := FTarAutoHandle;\n          TAbGzipArchive(FArchive).IsGzippedTar := False;\n          inherited InitArchive;\n        end;\n\n        atGZippedTar : begin\n          FArchive := TAbGzipArchive.Create(FileName, fmCreate or fmShareDenyNone);\n          TAbGzipArchive(FArchive).TarAutoHandle := FTarAutoHandle;\n          TAbGzipArchive(FArchive).IsGzippedTar := True;\n          inherited InitArchive;\n        end;\n\n        atBzip2 : begin\n          FArchive := TAbBzip2Archive.Create(FileName, fmCreate or fmShareDenyNone);\n          TAbBzip2Archive(FArchive).TarAutoHandle := FTarAutoHandle;\n          TAbBzip2Archive(FArchive).IsBzippedTar := False;\n          inherited InitArchive;\n        end;\n\n        atBzippedTar : begin\n          FArchive := TAbBzip2Archive.Create(FileName, fmCreate or fmShareDenyNone);\n          TAbBzip2Archive(FArchive).TarAutoHandle := FTarAutoHandle;\n          TAbBzip2Archive(FArchive).IsBzippedTar := True;\n          inherited InitArchive;\n        end;\n\n        else\n          raise EAbUnhandledType.Create;\n      end {case};\n\n      FArchiveType := ArcType;\n    end;\n  DoChange;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbCustomZipper.SetStoreOptions(Value : TAbStoreOptions);\nbegin\n  FStoreOptions := Value;\n  if (FArchive <> nil) then\n    FArchive.StoreOptions := Value;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbCustomZipper.SetArchiveSaveProgressMeter(const Value: IAbProgressMeter);\nbegin\n  ReferenceInterface(FArchiveSaveProgressMeter, opRemove);\n  FArchiveSaveProgressMeter := Value;\n  ReferenceInterface(FArchiveSaveProgressMeter, opInsert);\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbCustomZipper.SetZipfileComment(const Value : AnsiString);\nbegin\n  if (FArchive is TAbZipArchive) then\n    TAbZipArchive(FArchive).ZipfileComment := Value\n  else\n    raise EAbNoArchive.Create;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbCustomZipper.ZipProc(Sender : TObject; Item : TAbArchiveItem;\n  OutStream : TStream);\nbegin\n  AbZip(TAbZipArchive(Sender), TAbZipItem(Item), OutStream);\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbCustomZipper.ZipFromStreamProc(Sender : TObject; Item : TAbArchiveItem;\n  OutStream, InStream : TStream);\nbegin\n  if Assigned(InStream) then\n    AbZipFromStream(TAbZipArchive(Sender), TAbZipItem(Item),\n                    OutStream, InStream)\n  else\n    raise EAbZipNoInsertion.Create;\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbCustomZipper.DoArchiveSaveProgress(Sender : TObject;\n                                                Progress : Byte;\n                                                var Abort : Boolean);\nbegin\n  Abort := False;\n  if Assigned(FArchiveSaveProgressMeter) then\n    FArchiveSaveProgressMeter.DoProgress(Progress);\n  if Assigned(FOnArchiveSaveProgress) then\n    FOnArchiveSaveProgress(Self, Progress, Abort);\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbCustomZipper.Notification(Component: TComponent;\n                                       Operation: TOperation);\nbegin\n  inherited Notification(Component, Operation);\n  if (Operation = opRemove) then\n    if Assigned(ArchiveSaveProgressMeter) and Component.IsImplementorOf(ArchiveSaveProgressMeter) then\n      ArchiveSaveProgressMeter := nil\nend;\n{ -------------------------------------------------------------------------- }\nprocedure TAbCustomZipper.ResetMeters;\nbegin\n  inherited ResetMeters;\n  if Assigned(FArchiveSaveProgressMeter) then\n    FArchiveSaveProgressMeter.Reset;\nend;\n{ -------------------------------------------------------------------------- }\n\nend.\n\n"
  },
  {
    "path": "lib/abbrevia/source/COM/Abbrevia.dpr",
    "content": "(* ***** BEGIN LICENSE BLOCK *****\n * Version: MPL 1.1\n *\n * The contents of this file are subject to the Mozilla Public License Version\n * 1.1 (the \"License\"); you may not use this file except in compliance with\n * the License. You may obtain a copy of the License at\n * http://www.mozilla.org/MPL/\n *\n * Software distributed under the License is distributed on an \"AS IS\" basis,\n * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License\n * for the specific language governing rights and limitations under the\n * License.\n *\n * The Original Code is TurboPower Abbrevia\n *\n * The Initial Developer of the Original Code is\n * TurboPower Software\n *\n * Portions created by the Initial Developer are Copyright (C) 1997-2002\n * the Initial Developer. All Rights Reserved.\n *\n * Contributor(s):\n *\n * ***** END LICENSE BLOCK ***** *)\n\nlibrary Abbrevia;\n\nuses\n  ComServ,\n  _ZipKit in '_ZipKit.pas',\n  _ZipItem in '_ZipItem.pas',\n  _GZipItem in '_GZipItem.pas',\n  _TarItem in '_TarItem.pas',\n  Abbrevia_TLB in 'Abbrevia_TLB.pas';\n\nexports\n  DllGetClassObject,\n  DllCanUnloadNow,\n  DllRegisterServer,\n  DllUnregisterServer,\n  DllInstall;\n\n{$R *.TLB}\n\n{$R *.RES}\n\nbegin\nend.\n"
  },
  {
    "path": "lib/abbrevia/source/COM/Abbrevia.dproj",
    "content": "﻿\t<Project xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n\t\t<PropertyGroup>\n\t\t\t<ProjectGuid>{EDA07E3C-7B07-4B14-9B53-64A70EF3F00A}</ProjectGuid>\n\t\t\t<MainSource>Abbrevia.dpr</MainSource>\n\t\t\t<Base>True</Base>\n\t\t\t<Config Condition=\"'$(Config)'==''\">Release</Config>\n\t\t\t<TargetedPlatforms>3</TargetedPlatforms>\n\t\t\t<AppType>Library</AppType>\n\t\t\t<FrameworkType>None</FrameworkType>\n\t\t\t<ProjectVersion>13.4</ProjectVersion>\n\t\t\t<Platform Condition=\"'$(Platform)'==''\">Win32</Platform>\n\t\t</PropertyGroup>\n\t\t<PropertyGroup Condition=\"'$(Config)'=='Base' or '$(Base)'!=''\">\n\t\t\t<Base>true</Base>\n\t\t</PropertyGroup>\n\t\t<PropertyGroup Condition=\"('$(Platform)'=='Win64' and '$(Base)'=='true') or '$(Base_Win64)'!=''\">\n\t\t\t<Base_Win64>true</Base_Win64>\n\t\t\t<CfgParent>Base</CfgParent>\n\t\t\t<Base>true</Base>\n\t\t</PropertyGroup>\n\t\t<PropertyGroup Condition=\"('$(Platform)'=='Win32' and '$(Base)'=='true') or '$(Base_Win32)'!=''\">\n\t\t\t<Base_Win32>true</Base_Win32>\n\t\t\t<CfgParent>Base</CfgParent>\n\t\t\t<Base>true</Base>\n\t\t</PropertyGroup>\n\t\t<PropertyGroup Condition=\"'$(Config)'=='Release' or '$(Cfg_1)'!=''\">\n\t\t\t<Cfg_1>true</Cfg_1>\n\t\t\t<CfgParent>Base</CfgParent>\n\t\t\t<Base>true</Base>\n\t\t</PropertyGroup>\n\t\t<PropertyGroup Condition=\"('$(Platform)'=='Win64' and '$(Cfg_1)'=='true') or '$(Cfg_1_Win64)'!=''\">\n\t\t\t<Cfg_1_Win64>true</Cfg_1_Win64>\n\t\t\t<CfgParent>Cfg_1</CfgParent>\n\t\t\t<Cfg_1>true</Cfg_1>\n\t\t\t<Base>true</Base>\n\t\t</PropertyGroup>\n\t\t<PropertyGroup Condition=\"('$(Platform)'=='Win32' and '$(Cfg_1)'=='true') or '$(Cfg_1_Win32)'!=''\">\n\t\t\t<Cfg_1_Win32>true</Cfg_1_Win32>\n\t\t\t<CfgParent>Cfg_1</CfgParent>\n\t\t\t<Cfg_1>true</Cfg_1>\n\t\t\t<Base>true</Base>\n\t\t</PropertyGroup>\n\t\t<PropertyGroup Condition=\"'$(Config)'=='Debug' or '$(Cfg_2)'!=''\">\n\t\t\t<Cfg_2>true</Cfg_2>\n\t\t\t<CfgParent>Base</CfgParent>\n\t\t\t<Base>true</Base>\n\t\t</PropertyGroup>\n\t\t<PropertyGroup Condition=\"('$(Platform)'=='Win64' and '$(Cfg_2)'=='true') or '$(Cfg_2_Win64)'!=''\">\n\t\t\t<Cfg_2_Win64>true</Cfg_2_Win64>\n\t\t\t<CfgParent>Cfg_2</CfgParent>\n\t\t\t<Cfg_2>true</Cfg_2>\n\t\t\t<Base>true</Base>\n\t\t</PropertyGroup>\n\t\t<PropertyGroup Condition=\"('$(Platform)'=='Win32' and '$(Cfg_2)'=='true') or '$(Cfg_2_Win32)'!=''\">\n\t\t\t<Cfg_2_Win32>true</Cfg_2_Win32>\n\t\t\t<CfgParent>Cfg_2</CfgParent>\n\t\t\t<Cfg_2>true</Cfg_2>\n\t\t\t<Base>true</Base>\n\t\t</PropertyGroup>\n\t\t<PropertyGroup Condition=\"'$(Base)'!=''\">\n\t\t\t<DCC_ExeOutput>.\\$(Platform)</DCC_ExeOutput>\n\t\t\t<DCC_UnitSearchPath>..\\;$(DCC_UnitSearchPath)</DCC_UnitSearchPath>\n\t\t\t<Manifest_File>None</Manifest_File>\n\t\t\t<VerInfo_IncludeVerInfo>true</VerInfo_IncludeVerInfo>\n\t\t\t<VerInfo_MajorVer>5</VerInfo_MajorVer>\n\t\t\t<VerInfo_Locale>1033</VerInfo_Locale>\n\t\t\t<DCC_E>false</DCC_E>\n\t\t\t<VerInfo_Keys>CompanyName=;FileDescription=Abbrevia COM components;FileVersion=5.0.0.0;InternalName=;LegalCopyright=Copyright (c) Abbrevia Group 2011;LegalTrademarks=;OriginalFilename=;ProductName=Abbrevia;ProductVersion=5.0;Comments=</VerInfo_Keys>\n\t\t\t<DCC_Namespace>System;Xml;Data;Datasnap;Web;Soap;System.Win;Winapi;Vcl;$(DCC_Namespace)</DCC_Namespace>\n\t\t\t<DCC_ImageBase>00400000</DCC_ImageBase>\n\t\t\t<DCC_S>false</DCC_S>\n\t\t\t<GenDll>true</GenDll>\n\t\t\t<DCC_N>false</DCC_N>\n\t\t\t<DCC_F>false</DCC_F>\n\t\t\t<DCC_K>false</DCC_K>\n\t\t</PropertyGroup>\n\t\t<PropertyGroup Condition=\"'$(Base_Win64)'!=''\">\n\t\t\t<DCC_Namespace>Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;$(DCC_Namespace)</DCC_Namespace>\n\t\t\t<VerInfo_Keys>CompanyName=;FileDescription=;FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductName=;ProductVersion=1.0.0.0;Comments=</VerInfo_Keys>\n\t\t\t<Icon_MainIcon>Abbrevia_Icon.ico</Icon_MainIcon>\n\t\t</PropertyGroup>\n\t\t<PropertyGroup Condition=\"'$(Base_Win32)'!=''\">\n\t\t\t<Debugger_RunParams>/i:user /n Abbrevia.dll</Debugger_RunParams>\n\t\t\t<Debugger_HostApplication>C:\\Windows\\System32\\regsvr32.exe</Debugger_HostApplication>\n\t\t\t<DCC_Namespace>Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;Bde;$(DCC_Namespace)</DCC_Namespace>\n\t\t\t<VerInfo_Keys>CompanyName=;FileDescription=;FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductName=;ProductVersion=1.0.0.0;Comments=</VerInfo_Keys>\n\t\t</PropertyGroup>\n\t\t<PropertyGroup Condition=\"'$(Cfg_1)'!=''\">\n\t\t\t<DCC_LocalDebugSymbols>false</DCC_LocalDebugSymbols>\n\t\t\t<DCC_DebugInformation>false</DCC_DebugInformation>\n\t\t\t<DCC_SymbolReferenceInfo>0</DCC_SymbolReferenceInfo>\n\t\t\t<DCC_Define>RELEASE;$(DCC_Define)</DCC_Define>\n\t\t</PropertyGroup>\n\t\t<PropertyGroup Condition=\"'$(Cfg_1_Win64)'!=''\">\n\t\t\t<VerInfo_Keys>CompanyName=;FileDescription=Abbrevia COM components;FileVersion=5.0;InternalName=;LegalCopyright=Copyright (c) 2011 Abbrevia Group;LegalTrademarks=;OriginalFilename=Abbrevia.dll;ProductName=Abbrevia;ProductVersion=5.0;Comments=http://tpabbrevia.sourceforge.net/</VerInfo_Keys>\n\t\t</PropertyGroup>\n\t\t<PropertyGroup Condition=\"'$(Cfg_1_Win32)'!=''\">\n\t\t\t<VerInfo_Keys>CompanyName=;FileDescription=Abbrevia COM components;FileVersion=5.0;InternalName=;LegalCopyright=Copyright (c) 2011 Abbrevia Group;LegalTrademarks=;OriginalFilename=Abbrevia.dll;ProductName=Abbrevia;ProductVersion=5.0;Comments=http://tpabbrevia.sourceforge.net/</VerInfo_Keys>\n\t\t</PropertyGroup>\n\t\t<PropertyGroup Condition=\"'$(Cfg_2)'!=''\">\n\t\t\t<DCC_Define>DEBUG;$(DCC_Define)</DCC_Define>\n\t\t\t<DCC_Optimize>false</DCC_Optimize>\n\t\t\t<DCC_GenerateStackFrames>true</DCC_GenerateStackFrames>\n\t\t</PropertyGroup>\n\t\t<PropertyGroup Condition=\"'$(Cfg_2_Win64)'!=''\">\n\t\t\t<DCC_RemoteDebug>true</DCC_RemoteDebug>\n\t\t</PropertyGroup>\n\t\t<PropertyGroup Condition=\"'$(Cfg_2_Win32)'!=''\">\n\t\t\t<DCC_DebugDCUs>true</DCC_DebugDCUs>\n\t\t\t<VerInfo_Keys>CompanyName=;FileDescription=;FileVersion=5.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductName=;ProductVersion=1.0.0.0;Comments=</VerInfo_Keys>\n\t\t</PropertyGroup>\n\t\t<ItemGroup>\n\t\t\t<DelphiCompile Include=\"$(MainSource)\">\n\t\t\t\t<MainSource>MainSource</MainSource>\n\t\t\t</DelphiCompile>\n\t\t\t<DCCReference Include=\"_ZipKit.pas\"/>\n\t\t\t<DCCReference Include=\"_ZipItem.pas\"/>\n\t\t\t<DCCReference Include=\"_GZipItem.pas\"/>\n\t\t\t<DCCReference Include=\"_TarItem.pas\"/>\n\t\t\t<DCCReference Include=\"Abbrevia_TLB.pas\"/>\n\t\t\t<RidlCompile Include=\"Abbrevia.ridl\"/>\n\t\t\t<BuildConfiguration Include=\"Debug\">\n\t\t\t\t<Key>Cfg_2</Key>\n\t\t\t\t<CfgParent>Base</CfgParent>\n\t\t\t</BuildConfiguration>\n\t\t\t<BuildConfiguration Include=\"Base\">\n\t\t\t\t<Key>Base</Key>\n\t\t\t</BuildConfiguration>\n\t\t\t<BuildConfiguration Include=\"Release\">\n\t\t\t\t<Key>Cfg_1</Key>\n\t\t\t\t<CfgParent>Base</CfgParent>\n\t\t\t</BuildConfiguration>\n\t\t</ItemGroup>\n\t\t<ProjectExtensions>\n\t\t\t<Borland.Personality>Delphi.Personality.12</Borland.Personality>\n\t\t\t<Borland.ProjectType/>\n\t\t\t<BorlandProject>\n\t\t\t\t<Delphi.Personality>\n\t\t\t\t\t<Source>\n\t\t\t\t\t\t<Source Name=\"MainSource\">Abbrevia.dpr</Source>\n\t\t\t\t\t</Source>\n\t\t\t\t\t<VersionInfo>\n\t\t\t\t\t\t<VersionInfo Name=\"IncludeVerInfo\">False</VersionInfo>\n\t\t\t\t\t\t<VersionInfo Name=\"AutoIncBuild\">False</VersionInfo>\n\t\t\t\t\t\t<VersionInfo Name=\"MajorVer\">1</VersionInfo>\n\t\t\t\t\t\t<VersionInfo Name=\"MinorVer\">0</VersionInfo>\n\t\t\t\t\t\t<VersionInfo Name=\"Release\">0</VersionInfo>\n\t\t\t\t\t\t<VersionInfo Name=\"Build\">0</VersionInfo>\n\t\t\t\t\t\t<VersionInfo Name=\"Debug\">False</VersionInfo>\n\t\t\t\t\t\t<VersionInfo Name=\"PreRelease\">False</VersionInfo>\n\t\t\t\t\t\t<VersionInfo Name=\"Special\">False</VersionInfo>\n\t\t\t\t\t\t<VersionInfo Name=\"Private\">False</VersionInfo>\n\t\t\t\t\t\t<VersionInfo Name=\"DLL\">False</VersionInfo>\n\t\t\t\t\t\t<VersionInfo Name=\"Locale\">1033</VersionInfo>\n\t\t\t\t\t\t<VersionInfo Name=\"CodePage\">1252</VersionInfo>\n\t\t\t\t\t</VersionInfo>\n\t\t\t\t\t<VersionInfoKeys>\n\t\t\t\t\t\t<VersionInfoKeys Name=\"CompanyName\"/>\n\t\t\t\t\t\t<VersionInfoKeys Name=\"FileDescription\"/>\n\t\t\t\t\t\t<VersionInfoKeys Name=\"FileVersion\">1.0.0.0</VersionInfoKeys>\n\t\t\t\t\t\t<VersionInfoKeys Name=\"InternalName\"/>\n\t\t\t\t\t\t<VersionInfoKeys Name=\"LegalCopyright\"/>\n\t\t\t\t\t\t<VersionInfoKeys Name=\"LegalTrademarks\"/>\n\t\t\t\t\t\t<VersionInfoKeys Name=\"OriginalFilename\"/>\n\t\t\t\t\t\t<VersionInfoKeys Name=\"ProductName\"/>\n\t\t\t\t\t\t<VersionInfoKeys Name=\"ProductVersion\">1.0.0.0</VersionInfoKeys>\n\t\t\t\t\t\t<VersionInfoKeys Name=\"Comments\"/>\n\t\t\t\t\t</VersionInfoKeys>\n\t\t\t\t</Delphi.Personality>\n\t\t\t\t<Platforms>\n\t\t\t\t\t<Platform value=\"Win64\">True</Platform>\n\t\t\t\t\t<Platform value=\"OSX32\">False</Platform>\n\t\t\t\t\t<Platform value=\"Win32\">True</Platform>\n\t\t\t\t</Platforms>\n\t\t\t\t<ActiveXProjectInfo>\n\t\t\t\t\t<version>1</version>\n\t\t\t\t</ActiveXProjectInfo>\n\t\t\t</BorlandProject>\n\t\t\t<ProjectFileVersion>12</ProjectFileVersion>\n\t\t</ProjectExtensions>\n\t\t<Import Condition=\"Exists('$(BDS)\\Bin\\CodeGear.Delphi.Targets')\" Project=\"$(BDS)\\Bin\\CodeGear.Delphi.Targets\"/>\n\t\t<Import Condition=\"Exists('$(APPDATA)\\Embarcadero\\$(BDSAPPDATABASEDIR)\\$(PRODUCTVERSION)\\UserTools.proj')\" Project=\"$(APPDATA)\\Embarcadero\\$(BDSAPPDATABASEDIR)\\$(PRODUCTVERSION)\\UserTools.proj\"/>\n\t</Project>\n"
  },
  {
    "path": "lib/abbrevia/source/COM/Abbrevia.ridl",
    "content": "// ************************************************************************ //\n// WARNING\n// -------\n// This file is generated by the Type Library importer or Type Libary Editor.\n// Barring syntax errors, the Editor will parse modifications made to the file.\n// However, when applying changes via the Editor this file will be regenerated\n// and comments or formatting changes will be lost.\n// ************************************************************************ //\n// File generated on 12/6/2011 11:22:23 AM (- $Rev: 12980 $, 51698824).\n\n[\n  uuid(AF804E20-4043-499E-BB14-237B9F26F89F),\n  version(3.0),\n  helpstring(\"TurboPower Abbrevia Compression Library v3.03\"),\n  helpfile(\"C:\\\\Abbrevia\\\\COM\\\\abrv-com.hlp\"),\n  helpcontext(0x00000001)\n\n]\nlibrary Abbrevia\n{\n\n  importlib(\"stdole2.tlb\");\n\n  interface IZipItem;\n  interface IGZipItem;\n  interface ITarItem;\n  interface IZipKit;\n  dispinterface IZipKitEvents;\n  coclass ZipItem;\n  coclass GZipItem;\n  coclass TarItem;\n  coclass ZipKit;\n\n\n  [\n    uuid(6CABD61B-653C-4CEB-807C-C80E8DE8163D),\n    version(3.0)\n  ]\n  enum TArchiveAction\n  {\n    aaFailed = 0,\n    aaNone = 1,\n    aaAdd = 2,\n    aaDelete = 3,\n    aaFreshen = 4,\n    aaMove = 5,\n    aaStreamAdd = 6\n  };\n\n  [\n    uuid(148F84A1-2B70-4A63-B561-FF0EE49E74B3),\n    version(3.0)\n  ]\n  enum TArchiveStatus\n  {\n    asInvalid = 0,\n    asIdle = 1,\n    asBusy = 2\n  };\n\n  [\n    uuid(5D495174-DB09-4C59-A26D-FEBDE3EAE100),\n    version(3.0)\n  ]\n  enum TErrorClass\n  {\n    eclAbbrevia = 0,\n    eclInOutError = 1,\n    eclFileError = 2,\n    eclFileCreateError = 3,\n    eclFileOpenError = 4,\n    eclOther = 5\n  };\n\n  [\n    uuid(6A4738B9-69F1-4717-8393-681FF21E8DB7),\n    version(3.0)\n  ]\n  enum TFileAttributes\n  {\n    faReadOnly = 1,\n    faHidden = 2,\n    faSysFile = 4,\n    faVolumeID = 8,\n    faDirectory = 16,\n    faArchive = 32\n  };\n\n  [\n    uuid(F77BBE04-0859-4F18-9DEA-B2887C1F6AF7),\n    version(3.0)\n  ]\n  enum TProcessType\n  {\n    ptAdd = 0,\n    ptDelete = 1,\n    ptExtract = 2,\n    ptFreshen = 3,\n    ptMove = 4,\n    ptReplace = 5\n  };\n\n  [\n    uuid(D78287A7-65FA-4391-8F5A-C7D3A11E9970),\n    version(3.0)\n  ]\n  enum TStoreOptions\n  {\n    soStripDrive = 1,\n    soStripPath = 2,\n    soRemoveDots = 4,\n    soRecurse = 8,\n    soFreshen = 16,\n    soReplace = 32\n  };\n\n  [\n    uuid(192C6697-A38D-4F48-B32B-F33500460E62),\n    version(3.0)\n  ]\n  enum TZipCompressionMethod\n  {\n    cmStored = 0,\n    cmShrunk = 1,\n    cmReduced1 = 2,\n    cmReduced2 = 3,\n    cmReduced3 = 4,\n    cmReduced4 = 5,\n    cmImploded = 6,\n    cmTokenized = 7,\n    cmDeflated = 8,\n    cmEnhancedDeflated = 9,\n    cmDCLImploded = 10,\n    cmBestMethod = 11\n  };\n\n  [\n    uuid(800F8CDC-2F0F-4020-BCBB-FEDA82D0EFEF),\n    version(3.0)\n  ]\n  enum TZipDeflateOption\n  {\n    doInvalid = 0,\n    doNormal = 1,\n    doMaximum = 2,\n    doFast = 3,\n    doSuperFast = 4\n  };\n\n  [\n    uuid(D697ED2A-F088-409F-962A-57D8324EEDD6),\n    version(3.0)\n  ]\n  enum TZipDictionarySize\n  {\n    dsInvalid = 0,\n    ds4K = 1,\n    ds8K = 2\n  };\n\n  [\n    uuid(B9889806-26F9-47E7-AC1F-906AA161B078),\n    version(3.0)\n  ]\n  enum TZipExtractOptions\n  {\n    eoCreateDirs = 0,\n    eoRestorePath = 1\n  };\n\n  [\n    uuid(D40E0708-AE71-4A44-A6C8-430EDF760DE2),\n    version(3.0)\n  ]\n  enum TZipSupportMethod\n  {\n    smStored = 0,\n    smDeflated = 1,\n    smBestMethod = 2\n  };\n\n  [\n    uuid(EFD2C909-BF04-4C54-9ACB-38D872B95C9F),\n    version(3.0)\n  ]\n  enum TErrorCode\n  {\n    ecDuplicateName = 0,\n    ecInvalidPassword = 1,\n    ecNoSuchDirectory = 2,\n    ecUnknownCompressionMethod = 3,\n    ecUserAbort = 4,\n    ecZipBadCRC = 5,\n    ecZipVersionNumber = 6,\n    ecSpannedItemNotFound = 7\n  };\n\n  [\n    uuid(44EB05F9-CED9-46D0-84E2-BD3362977437),\n    version(3.0)\n  ]\n  enum TArchiveType\n  {\n    atUnknown = 0,\n    atZip = 1,\n    atSelfExtZip = 2,\n    atTar = 3,\n    atGZip = 4,\n    atGZippedTar = 5,\n    atCab = 6\n  };\n\n  [\n    uuid(36568A72-3B4B-41C4-8E34-19931A8EAF63),\n    version(3.0)\n  ]\n  enum TFileSystem\n  {\n    fsFAT = 0,\n    fsAmiga = 1,\n    fsVMS = 2,\n    fsUnix = 3,\n    fsVM_CMS = 4,\n    fsAtariTOS = 5,\n    fsHPFS = 6,\n    fsMacintosh = 7,\n    fsZSystem = 8,\n    fsCP_M = 9,\n    fsTOPS20 = 10,\n    fsNTFS = 11,\n    fsQDOS = 12,\n    fsAcornRISCOS = 13,\n    fsUnknown = 14,\n    fsUndefined = 15\n  };\n\n  [\n    uuid(851699A1-422A-4C65-8E08-D0499ACDD834),\n    version(3.0),\n    helpstring(\"Dispatch interface for ZipItem Object\"),\n    helpcontext(0x00000005),\n    dual,\n    oleautomation\n  ]\n  interface IZipItem: IDispatch\n  {\n    [propget, id(0x00000001)]\n    HRESULT _stdcall Action([out, retval] enum TArchiveAction* Value);\n    [propget, id(0x00000002)]\n    HRESULT _stdcall CompressedSize([out, retval] long* Value);\n    [propget, id(0x00000003)]\n    HRESULT _stdcall CRC32([out, retval] long* Value);\n    [propget, id(0x00000004)]\n    HRESULT _stdcall DiskFileName([out, retval] BSTR* Value);\n    [propget, id(0x00000005)]\n    HRESULT _stdcall DiskPath([out, retval] BSTR* Value);\n    [propget, id(0x00000006)]\n    HRESULT _stdcall ExternalFileAttributes([out, retval] enum TFileAttributes* Value);\n    [propput, id(0x00000006)]\n    HRESULT _stdcall ExternalFileAttributes([in] enum TFileAttributes Value);\n    [propget, id(0x00000007)]\n    HRESULT _stdcall FileName([out, retval] BSTR* Value);\n    [propput, id(0x00000007)]\n    HRESULT _stdcall FileName([in] BSTR Value);\n    [propget, id(0x00000008)]\n    HRESULT _stdcall IsEncrypted([out, retval] VARIANT_BOOL* Value);\n    [propget, id(0x00000009)]\n    HRESULT _stdcall LastModFileDateTime([out, retval] DATE* Value);\n    [propget, id(0x0000000A)]\n    HRESULT _stdcall StoredPath([out, retval] BSTR* Value);\n    [propget, id(0x0000000B)]\n    HRESULT _stdcall Tagged([out, retval] VARIANT_BOOL* Value);\n    [propput, id(0x0000000B)]\n    HRESULT _stdcall Tagged([in] VARIANT_BOOL Value);\n    [propget, id(0x0000000C)]\n    HRESULT _stdcall UnCompressedSize([out, retval] long* Value);\n    [propget, id(0x0000000D)]\n    HRESULT _stdcall CRC32St([out, retval] BSTR* Value);\n    [propget, id(0x0000000E)]\n    HRESULT _stdcall Password([out, retval] BSTR* Value);\n    [propput, id(0x0000000E)]\n    HRESULT _stdcall Password([in] BSTR Value);\n    [propget, id(0x0000000F)]\n    HRESULT _stdcall CompressionMethod([out, retval] enum TZipCompressionMethod* Value);\n    [propget, id(0x00000010)]\n    HRESULT _stdcall CompressionRatio([out, retval] double* Value);\n    [propget, id(0x00000011)]\n    HRESULT _stdcall DeflateOption([out, retval] enum TZipDeflateOption* Value);\n    [propget, id(0x00000012)]\n    HRESULT _stdcall DictionarySize([out, retval] enum TZipDictionarySize* Value);\n    [propget, id(0x00000013)]\n    HRESULT _stdcall DiskNumberStart([out, retval] long* Value);\n    [propget, id(0x00000014)]\n    HRESULT _stdcall ExtraField([out, retval] BSTR* Value);\n    [propput, id(0x00000014)]\n    HRESULT _stdcall ExtraField([in] BSTR Value);\n    [propget, id(0x00000015)]\n    HRESULT _stdcall FileComment([out, retval] BSTR* Value);\n    [propput, id(0x00000015)]\n    HRESULT _stdcall FileComment([in] BSTR Value);\n    [propget, id(0x00000016)]\n    HRESULT _stdcall InternalFileAttributes([out, retval] long* Value);\n    [propput, id(0x00000016)]\n    HRESULT _stdcall InternalFileAttributes([in] long Value);\n    [propget, id(0x00000017)]\n    HRESULT _stdcall VersionMadeBy([out, retval] long* Value);\n    [propget, id(0x00000018)]\n    HRESULT _stdcall VersionNeededToExtract([out, retval] long* Value);\n  };\n\n  [\n    uuid(8FA78CE0-FD29-441E-9777-93B63EF1A9EE),\n    version(3.0),\n    dual,\n    oleautomation\n  ]\n  interface IGZipItem: IDispatch\n  {\n    [propget, id(0x00000001)]\n    HRESULT _stdcall Action([out, retval] enum TArchiveAction* Value);\n    [propget, id(0x00000002)]\n    HRESULT _stdcall CompressedSize([out, retval] long* Value);\n    [propget, id(0x00000003)]\n    HRESULT _stdcall CRC32([out, retval] long* Value);\n    [propget, id(0x00000004)]\n    HRESULT _stdcall DiskFileName([out, retval] BSTR* Value);\n    [propget, id(0x00000005)]\n    HRESULT _stdcall DiskPath([out, retval] BSTR* Value);\n    [propget, id(0x00000006)]\n    HRESULT _stdcall ExternalFileAttributes([out, retval] enum TFileAttributes* Value);\n    [propput, id(0x00000006)]\n    HRESULT _stdcall ExternalFileAttributes([in] enum TFileAttributes Value);\n    [propget, id(0x00000007)]\n    HRESULT _stdcall FileName([out, retval] BSTR* Value);\n    [propput, id(0x00000007)]\n    HRESULT _stdcall FileName([in] BSTR Value);\n    [propget, id(0x00000008)]\n    HRESULT _stdcall IsEncrypted([out, retval] VARIANT_BOOL* Value);\n    [propget, id(0x00000009)]\n    HRESULT _stdcall LastModFileDateTime([out, retval] DATE* Value);\n    [propget, id(0x0000000A)]\n    HRESULT _stdcall StoredPath([out, retval] BSTR* Value);\n    [propget, id(0x0000000B)]\n    HRESULT _stdcall Tagged([out, retval] VARIANT_BOOL* Value);\n    [propput, id(0x0000000B)]\n    HRESULT _stdcall Tagged([in] VARIANT_BOOL Value);\n    [propget, id(0x0000000C)]\n    HRESULT _stdcall UnCompressedSize([out, retval] long* Value);\n    [propget, id(0x0000000D)]\n    HRESULT _stdcall CRC32St([out, retval] BSTR* Value);\n    [propget, id(0x0000000E)]\n    HRESULT _stdcall Password([out, retval] BSTR* Value);\n    [propput, id(0x0000000E)]\n    HRESULT _stdcall Password([in] BSTR Value);\n    [propget, id(0x0000000F)]\n    HRESULT _stdcall CompressionMethod([out, retval] unsigned char* Value);\n    [propput, id(0x0000000F)]\n    HRESULT _stdcall CompressionMethod([in] unsigned char Value);\n    [propget, id(0x00000010)]\n    HRESULT _stdcall ExtraField([out, retval] BSTR* Value);\n    [propput, id(0x00000010)]\n    HRESULT _stdcall ExtraField([in] BSTR Value);\n    [propget, id(0x00000011)]\n    HRESULT _stdcall ExtraFlags([out, retval] unsigned char* Value);\n    [propput, id(0x00000011)]\n    HRESULT _stdcall ExtraFlags([in] unsigned char Value);\n    [propget, id(0x00000012)]\n    HRESULT _stdcall FileComment([out, retval] BSTR* Value);\n    [propput, id(0x00000012)]\n    HRESULT _stdcall FileComment([in] BSTR Value);\n    [propget, id(0x00000013)]\n    HRESULT _stdcall FileSystem([out, retval] enum TFileSystem* Value);\n    [propput, id(0x00000013)]\n    HRESULT _stdcall FileSystem([in] enum TFileSystem Value);\n    [propget, id(0x00000014)]\n    HRESULT _stdcall Flags([out, retval] unsigned char* Value);\n    [propput, id(0x00000014)]\n    HRESULT _stdcall Flags([in] unsigned char Value);\n    [propget, id(0x00000015)]\n    HRESULT _stdcall HeaderCRC([out, retval] long* Value);\n  };\n\n  [\n    uuid(729E9F52-C489-4A41-A770-4E2C5282AE39),\n    version(3.0),\n    dual,\n    oleautomation\n  ]\n  interface ITarItem: IDispatch\n  {\n    [propget, id(0x00000001)]\n    HRESULT _stdcall Action([out, retval] enum TArchiveAction* Value);\n    [propget, id(0x00000002)]\n    HRESULT _stdcall CompressedSize([out, retval] long* Value);\n    [propget, id(0x00000003)]\n    HRESULT _stdcall CRC32([out, retval] long* Value);\n    [propget, id(0x00000004)]\n    HRESULT _stdcall DiskFileName([out, retval] BSTR* Value);\n    [propget, id(0x00000005)]\n    HRESULT _stdcall DiskPath([out, retval] BSTR* Value);\n    [propget, id(0x00000006)]\n    HRESULT _stdcall ExternalFileAttributes([out, retval] enum TFileAttributes* Value);\n    [propput, id(0x00000006)]\n    HRESULT _stdcall ExternalFileAttributes([in] enum TFileAttributes Value);\n    [propget, id(0x00000007)]\n    HRESULT _stdcall FileName([out, retval] BSTR* Value);\n    [propput, id(0x00000007)]\n    HRESULT _stdcall FileName([in] BSTR Value);\n    [propget, id(0x00000008)]\n    HRESULT _stdcall IsEncrypted([out, retval] VARIANT_BOOL* Value);\n    [propget, id(0x00000009)]\n    HRESULT _stdcall LastModFileDateTime([out, retval] DATE* Value);\n    [propget, id(0x0000000A)]\n    HRESULT _stdcall StoredPath([out, retval] BSTR* Value);\n    [propget, id(0x0000000B)]\n    HRESULT _stdcall Tagged([out, retval] VARIANT_BOOL* Value);\n    [propput, id(0x0000000B)]\n    HRESULT _stdcall Tagged([in] VARIANT_BOOL Value);\n    [propget, id(0x0000000C)]\n    HRESULT _stdcall UnCompressedSize([out, retval] long* Value);\n    [propget, id(0x0000000D)]\n    HRESULT _stdcall CRC32St([out, retval] BSTR* Value);\n    [propget, id(0x0000000E)]\n    HRESULT _stdcall Password([out, retval] BSTR* Value);\n    [propput, id(0x0000000E)]\n    HRESULT _stdcall Password([in] BSTR Value);\n    [propget, id(0x0000000F)]\n    HRESULT _stdcall DevMajor([out, retval] long* Value);\n    [propput, id(0x0000000F)]\n    HRESULT _stdcall DevMajor([in] long Value);\n    [propget, id(0x00000010)]\n    HRESULT _stdcall DevMinor([out, retval] long* Value);\n    [propput, id(0x00000010)]\n    HRESULT _stdcall DevMinor([in] long Value);\n    [propget, id(0x00000011)]\n    HRESULT _stdcall GroupID([out, retval] long* Value);\n    [propput, id(0x00000011)]\n    HRESULT _stdcall GroupID([in] long Value);\n    [propget, id(0x00000012)]\n    HRESULT _stdcall GroupName([out, retval] BSTR* Value);\n    [propput, id(0x00000012)]\n    HRESULT _stdcall GroupName([in] BSTR Value);\n    [propget, id(0x00000013)]\n    HRESULT _stdcall LinkFlag([out, retval] unsigned char* Value);\n    [propput, id(0x00000013)]\n    HRESULT _stdcall LinkFlag([in] unsigned char Value);\n    [propget, id(0x00000014)]\n    HRESULT _stdcall LinkName([out, retval] BSTR* Value);\n    [propput, id(0x00000014)]\n    HRESULT _stdcall LinkName([in] BSTR Value);\n    [propget, id(0x00000015)]\n    HRESULT _stdcall Mode([out, retval] long* Value);\n    [propput, id(0x00000015)]\n    HRESULT _stdcall Mode([in] long Value);\n    [propget, id(0x00000016)]\n    HRESULT _stdcall UserID([out, retval] long* Value);\n    [propput, id(0x00000016)]\n    HRESULT _stdcall UserID([in] long Value);\n    [propget, id(0x00000017)]\n    HRESULT _stdcall UserName([out, retval] BSTR* Value);\n    [propput, id(0x00000017)]\n    HRESULT _stdcall UserName([in] BSTR Value);\n  };\n\n  [\n    uuid(B7480A7F-4E27-4B45-9FE6-224B60295A0C),\n    version(3.0),\n    helpstring(\"Dispatch interface for ZipKit Object\"),\n    helpcontext(0x00000006),\n    dual,\n    oleautomation\n  ]\n  interface IZipKit: IDispatch\n  {\n    [id(0x00000001)]\n    HRESULT _stdcall Add([in] BSTR FileMask, [in] BSTR ExclusionMask, [in] long SearchAttr);\n    [id(0x00000007)]\n    HRESULT _stdcall AddFromStream([in] BSTR FileName, [in] VARIANT Stream);\n    [propget, id(0x00000003)]\n    HRESULT _stdcall AutoSave([out, retval] VARIANT_BOOL* Value);\n    [propput, id(0x00000003)]\n    HRESULT _stdcall AutoSave([in] VARIANT_BOOL Value);\n    [propget, id(0x00000004)]\n    HRESULT _stdcall BaseDirectory([out, retval] BSTR* Value);\n    [propput, id(0x00000004)]\n    HRESULT _stdcall BaseDirectory([in] BSTR Value);\n    [id(0x00000005)]\n    HRESULT _stdcall ClearTags(void);\n    [propget, id(0x00000006)]\n    HRESULT _stdcall CompressionMethodToUse([out, retval] enum TZipSupportMethod* Value);\n    [propput, id(0x00000006)]\n    HRESULT _stdcall CompressionMethodToUse([in] enum TZipSupportMethod Value);\n    [propget, id(0x00000002)]\n    HRESULT _stdcall Count([out, retval] long* Value);\n    [propget, id(0x00000008)]\n    HRESULT _stdcall DeflateOption([out, retval] enum TZipDeflateOption* Value);\n    [propput, id(0x00000008)]\n    HRESULT _stdcall DeflateOption([in] enum TZipDeflateOption Value);\n    [id(0x00000009)]\n    HRESULT _stdcall Delete([in] BSTR FileMask, [in] BSTR ExclusionMask);\n    [id(0x0000000A)]\n    HRESULT _stdcall DeleteAt([in] long Index);\n    [id(0x0000000B)]\n    HRESULT _stdcall DeleteTaggedItems(void);\n    [propget, id(0x0000000C)]\n    HRESULT _stdcall DOSMode([out, retval] VARIANT_BOOL* Value);\n    [propput, id(0x0000000C)]\n    HRESULT _stdcall DOSMode([in] VARIANT_BOOL Value);\n    [id(0x0000000D)]\n    HRESULT _stdcall Extract([in] BSTR FileMask, [in] BSTR ExclusionMask);\n    [id(0x0000000E)]\n    HRESULT _stdcall ExtractAt([in] long Index, [in] BSTR NewName);\n    [propget, id(0x0000000F)]\n    HRESULT _stdcall ExtractOptions([out, retval] enum TZipExtractOptions* Value);\n    [propput, id(0x0000000F)]\n    HRESULT _stdcall ExtractOptions([in] enum TZipExtractOptions Value);\n    [id(0x00000010)]\n    HRESULT _stdcall ExtractTaggedItems(void);\n    [propget, id(0x00000011)]\n    HRESULT _stdcall FileName([out, retval] BSTR* Value);\n    [propput, id(0x00000011)]\n    HRESULT _stdcall FileName([in] BSTR Value);\n    [id(0x00000012)]\n    HRESULT _stdcall Find([in] BSTR FileName, [out, retval] long* Value);\n    [id(0x00000013)]\n    HRESULT _stdcall Freshen([in] BSTR FileMask, [in] BSTR ExclusionMask);\n    [id(0x00000014)]\n    HRESULT _stdcall FreshenTaggedItems(void);\n    [propget, id(0x00000000)]\n    HRESULT _stdcall Item([in] long Index, [out, retval]  IDispatch** Value);\n    [propget, id(0x00000017)]\n    HRESULT _stdcall LogFile([out, retval] BSTR* Value);\n    [propput, id(0x00000017)]\n    HRESULT _stdcall LogFile([in] BSTR Value);\n    [propget, id(0x00000018)]\n    HRESULT _stdcall Logging([out, retval] VARIANT_BOOL* Value);\n    [propput, id(0x00000018)]\n    HRESULT _stdcall Logging([in] VARIANT_BOOL Value);\n    [propget, id(0x00000019)]\n    HRESULT _stdcall Password([out, retval] BSTR* Value);\n    [propput, id(0x00000019)]\n    HRESULT _stdcall Password([in] BSTR Value);\n    [propget, id(0x0000001A)]\n    HRESULT _stdcall PasswordRetries([out, retval] unsigned char* Value);\n    [propput, id(0x0000001A)]\n    HRESULT _stdcall PasswordRetries([in] unsigned char Value);\n    [id(0x0000001B)]\n    HRESULT _stdcall Replace([in] BSTR FileMask);\n    [id(0x0000001C)]\n    HRESULT _stdcall Save(void);\n    [propget, id(0x0000001D)]\n    HRESULT _stdcall Spanned([out, retval] VARIANT_BOOL* Value);\n    [propget, id(0x0000001E)]\n    HRESULT _stdcall SpanningThreshold([out, retval] long* Value);\n    [propput, id(0x0000001E)]\n    HRESULT _stdcall SpanningThreshold([in] long Value);\n    [propget, id(0x0000001F)]\n    HRESULT _stdcall Status([out, retval] enum TArchiveStatus* Value);\n    [propget, id(0x00000020)]\n    HRESULT _stdcall StoreOptions([out, retval] enum TStoreOptions* Value);\n    [propput, id(0x00000020)]\n    HRESULT _stdcall StoreOptions([in] enum TStoreOptions Value);\n    [id(0x00000021)]\n    HRESULT _stdcall TagItems([in] BSTR FileMask);\n    [propget, id(0x00000022)]\n    HRESULT _stdcall TempDirectory([out, retval] BSTR* Value);\n    [propput, id(0x00000022)]\n    HRESULT _stdcall TempDirectory([in] BSTR Value);\n    [id(0x00000023)]\n    HRESULT _stdcall TestTaggedItems(void);\n    [id(0x00000024)]\n    HRESULT _stdcall UntagItems([in] BSTR FileMask);\n    [propget, id(0x00000025)]\n    HRESULT _stdcall ZipFileComment([out, retval] BSTR* Value);\n    [propput, id(0x00000025)]\n    HRESULT _stdcall ZipFileComment([in] BSTR Value);\n    [id(0x00000026)]\n    HRESULT _stdcall License([in] BSTR Key, [out, retval] VARIANT_BOOL* Value);\n    [propget, id(0xFFFFFFFC), restricted, hidden]\n    HRESULT _stdcall _NewEnum([out, retval]  IUnknown** Value);\n    [id(0x00000015)]\n    HRESULT _stdcall ExtractToStream([in] BSTR FileName, [out, retval] VARIANT* Value);\n    [propget, id(0x00000028)]\n    HRESULT _stdcall CompressionType([out, retval] enum TArchiveType* Value);\n    [propput, id(0x00000028)]\n    HRESULT _stdcall CompressionType([in] enum TArchiveType Value);\n    [propget, id(0x00000029)]\n    HRESULT _stdcall TarAutoHandle([out, retval] VARIANT_BOOL* Value);\n    [propput, id(0x00000029)]\n    HRESULT _stdcall TarAutoHandle([in] VARIANT_BOOL Value);\n  };\n\n  [\n    uuid(F094D5F4-3A52-45AE-9D86-4409611DD29E),\n    version(3.0),\n    helpstring(\"Events interface for ZipKit Object\")\n  ]\n  dispinterface IZipKitEvents\n  {\n    properties:\n    methods:\n    [id(0x00000001)]\n    void OnArchiveItemProgress([in]  IDispatch* Item, [in] unsigned char Progress, [in, out] VARIANT_BOOL* Abort);\n    [id(0x00000002)]\n    void OnArchiveProgress([in] unsigned char Progress, [in, out] VARIANT_BOOL* Abort);\n    [id(0x00000003)]\n    void OnChange(void);\n    [id(0x00000004)]\n    void OnConfirmOverwrite([in, out] BSTR* Name, [in, out] VARIANT_BOOL* Confirm);\n    [id(0x00000005)]\n    void OnConfirmProcessItem([in]  IDispatch* Item, [in] enum TProcessType ProcessType, [in, out] VARIANT_BOOL* Confirm);\n    [id(0x00000006)]\n    void OnConfirmSave([in, out] VARIANT_BOOL* Confirm);\n    [id(0x00000007)]\n    void OnLoad(void);\n    [id(0x00000008)]\n    void OnNeedPassword([in, out] BSTR* NewPassword);\n    [id(0x00000009)]\n    void OnProcessItemFailure([in]  IDispatch* Item, [in] enum TProcessType ProcessType, [in] enum TErrorClass ErrorClass, [in] enum TErrorCode ErrorCode, [in] BSTR ErrorString);\n    [id(0x0000000A)]\n    void OnRequestBlankDisk([in, out] VARIANT_BOOL* Abort);\n    [id(0x0000000B)]\n    void OnRequestImage([in] long ImageNumber, [in, out] BSTR* ImageName, [in, out] VARIANT_BOOL* Abort);\n    [id(0x0000000C)]\n    void OnRequestLastDisk([in, out] VARIANT_BOOL* Abort);\n    [id(0x0000000D)]\n    void OnRequestNthDisk([in] long DiskNumber, [in, out] VARIANT_BOOL* Abort);\n    [id(0x0000000E)]\n    void OnSave(void);\n  };\n\n  [\n    uuid(650989D8-F0FF-4C71-83C3-92556F4329F5),\n    version(3.0)\n  ]\n  coclass ZipItem\n  {\n    [default] interface IZipItem;\n  };\n\n  [\n    uuid(2B35BB50-D9C7-4669-B18E-943B5199FD8E),\n    version(3.0)\n  ]\n  coclass GZipItem\n  {\n    [default] interface IGZipItem;\n  };\n\n  [\n    uuid(2DF3E624-0E6C-42CF-8041-676B9A06375E),\n    version(3.0)\n  ]\n  coclass TarItem\n  {\n    [default] interface ITarItem;\n  };\n\n  [\n    uuid(730B4B32-9127-492A-BF02-196A7E6B4E1B),\n    version(3.0),\n    helpstring(\"ZipKit Object\"),\n    helpcontext(0x00000006)\n  ]\n  coclass ZipKit\n  {\n    [default] interface IZipKit;\n    [default, source] dispinterface IZipKitEvents;\n  };\n\n};\n"
  },
  {
    "path": "lib/abbrevia/source/COM/Abbrevia_TLB.pas",
    "content": "(* ***** BEGIN LICENSE BLOCK *****\n * Version: MPL 1.1\n *\n * The contents of this file are subject to the Mozilla Public License Version\n * 1.1 (the \"License\"); you may not use this file except in compliance with\n * the License. You may obtain a copy of the License at\n * http://www.mozilla.org/MPL/\n *\n * Software distributed under the License is distributed on an \"AS IS\" basis,\n * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License\n * for the specific language governing rights and limitations under the\n * License.\n *\n * The Original Code is TurboPower Abbrevia\n *\n * The Initial Developer of the Original Code is\n * TurboPower Software\n *\n * Portions created by the Initial Developer are Copyright (C) 1997-2002\n * the Initial Developer. All Rights Reserved.\n *\n * Contributor(s):\n *\n * ***** END LICENSE BLOCK ***** *)\n\nunit Abbrevia_TLB;\n\n// ************************************************************************ //\n// WARNING                                                                    \n// -------                                                                    \n// The types declared in this file were generated from data read from a       \n// Type Library. If this type library is explicitly or indirectly (via        \n// another type library referring to this type library) re-imported, or the   \n// 'Refresh' command of the Type Library Editor activated while editing the   \n// Type Library, the contents of this file will be regenerated and all        \n// manual modifications will be lost.                                         \n// ************************************************************************ //\n\n// $Rev: 491 $\n// File generated on 7/23/2009 9:45:45 PM from Type Library described below.\n\n// ************************************************************************  //\n// Type Lib: C:\\Abbrevia\\COM\\abbrevia.dll\n// LIBID: {AF804E20-4043-499E-BB14-237B9F26F89F}\n// LCID: 0\n// Helpfile: C:\\Abbrevia\\COM\\abrv-com.hlp\n// HelpString: TurboPower Abbrevia Compression Library v3.03\n// DepndLst: \n//   (1) v2.0 stdole, (C:\\WINDOWS\\System32\\stdole2.tlb)\n// ************************************************************************ //\n{$TYPEDADDRESS OFF} // Unit must be compiled without type-checked pointers. \n{$WARN SYMBOL_PLATFORM OFF}\n{$WRITEABLECONST ON}\n{$VARPROPSETTER ON}\ninterface\n\nuses Windows, ActiveX, Classes, Graphics, StdVCL, Variants;\n  \n\n// *********************************************************************//\n// GUIDS declared in the TypeLibrary. Following prefixes are used:        \n//   Type Libraries     : LIBID_xxxx                                      \n//   CoClasses          : CLASS_xxxx                                      \n//   DISPInterfaces     : DIID_xxxx                                       \n//   Non-DISP interfaces: IID_xxxx                                        \n// *********************************************************************//\nconst\n  // TypeLibrary Major and minor versions\n  AbbreviaMajorVersion = 5;\n  AbbreviaMinorVersion = 0;\n\n  LIBID_Abbrevia: TGUID = '{AF804E20-4043-499E-BB14-237B9F26F89F}';\n\n  IID_IZipItem: TGUID = '{851699A1-422A-4C65-8E08-D0499ACDD834}';\n  IID_IGZipItem: TGUID = '{8FA78CE0-FD29-441E-9777-93B63EF1A9EE}';\n  IID_ITarItem: TGUID = '{729E9F52-C489-4A41-A770-4E2C5282AE39}';\n  IID_IZipKit: TGUID = '{B7480A7F-4E27-4B45-9FE6-224B60295A0C}';\n  DIID_IZipKitEvents: TGUID = '{F094D5F4-3A52-45AE-9D86-4409611DD29E}';\n  CLASS_ZipItem: TGUID = '{650989D8-F0FF-4C71-83C3-92556F4329F5}';\n  CLASS_GZipItem: TGUID = '{2B35BB50-D9C7-4669-B18E-943B5199FD8E}';\n  CLASS_TarItem: TGUID = '{2DF3E624-0E6C-42CF-8041-676B9A06375E}';\n  CLASS_ZipKit: TGUID = '{730B4B32-9127-492A-BF02-196A7E6B4E1B}';\n\n// *********************************************************************//\n// Declaration of Enumerations defined in Type Library                    \n// *********************************************************************//\n// Constants for enum TArchiveAction\ntype\n  TArchiveAction = TOleEnum;\nconst\n  aaFailed = $00000000;\n  aaNone = $00000001;\n  aaAdd = $00000002;\n  aaDelete = $00000003;\n  aaFreshen = $00000004;\n  aaMove = $00000005;\n  aaStreamAdd = $00000006;\n\n// Constants for enum TArchiveStatus\ntype\n  TArchiveStatus = TOleEnum;\nconst\n  asInvalid = $00000000;\n  asIdle = $00000001;\n  asBusy = $00000002;\n\n// Constants for enum TErrorClass\ntype\n  TErrorClass = TOleEnum;\nconst\n  eclAbbrevia = $00000000;\n  eclInOutError = $00000001;\n  eclFileError = $00000002;\n  eclFileCreateError = $00000003;\n  eclFileOpenError = $00000004;\n  eclOther = $00000005;\n\n// Constants for enum TFileAttributes\ntype\n  TFileAttributes = TOleEnum;\nconst\n  faReadOnly = $00000001;\n  faHidden = $00000002;\n  faSysFile = $00000004;\n  faVolumeID = $00000008;\n  faDirectory = $00000010;\n  faArchive = $00000020;\n\n// Constants for enum TProcessType\ntype\n  TProcessType = TOleEnum;\nconst\n  ptAdd = $00000000;\n  ptDelete = $00000001;\n  ptExtract = $00000002;\n  ptFreshen = $00000003;\n  ptMove = $00000004;\n  ptReplace = $00000005;\n\n// Constants for enum TStoreOptions\ntype\n  TStoreOptions = TOleEnum;\nconst\n  soStripDrive = $00000001;\n  soStripPath = $00000002;\n  soRemoveDots = $00000004;\n  soRecurse = $00000008;\n  soFreshen = $00000010;\n  soReplace = $00000020;\n\n// Constants for enum TZipCompressionMethod\ntype\n  TZipCompressionMethod = TOleEnum;\nconst\n  cmStored = $00000000;\n  cmShrunk = $00000001;\n  cmReduced1 = $00000002;\n  cmReduced2 = $00000003;\n  cmReduced3 = $00000004;\n  cmReduced4 = $00000005;\n  cmImploded = $00000006;\n  cmTokenized = $00000007;\n  cmDeflated = $00000008;\n  cmEnhancedDeflated = $00000009;\n  cmDCLImploded = $0000000A;\n  cmBestMethod = $0000000B;\n\n// Constants for enum TZipDeflateOption\ntype\n  TZipDeflateOption = TOleEnum;\nconst\n  doInvalid = $00000000;\n  doNormal = $00000001;\n  doMaximum = $00000002;\n  doFast = $00000003;\n  doSuperFast = $00000004;\n\n// Constants for enum TZipDictionarySize\ntype\n  TZipDictionarySize = TOleEnum;\nconst\n  dsInvalid = $00000000;\n  ds4K = $00000001;\n  ds8K = $00000002;\n\n// Constants for enum TZipExtractOptions\ntype\n  TZipExtractOptions = TOleEnum;\nconst\n  eoCreateDirs = $00000000;\n  eoRestorePath = $00000001;\n\n// Constants for enum TZipSupportMethod\ntype\n  TZipSupportMethod = TOleEnum;\nconst\n  smStored = $00000000;\n  smDeflated = $00000001;\n  smBestMethod = $00000002;\n\n// Constants for enum TErrorCode\ntype\n  TErrorCode = TOleEnum;\nconst\n  ecDuplicateName = $00000000;\n  ecInvalidPassword = $00000001;\n  ecNoSuchDirectory = $00000002;\n  ecUnknownCompressionMethod = $00000003;\n  ecUserAbort = $00000004;\n  ecZipBadCRC = $00000005;\n  ecZipVersionNumber = $00000006;\n  ecSpannedItemNotFound = $00000007;\n\n// Constants for enum TArchiveType\ntype\n  TArchiveType = TOleEnum;\nconst\n  atUnknown = $00000000;\n  atZip = $00000001;\n  atSelfExtZip = $00000002;\n  atTar = $00000003;\n  atGZip = $00000004;\n  atGZippedTar = $00000005;\n  atCab = $00000006;\n\n// Constants for enum TFileSystem\ntype\n  TFileSystem = TOleEnum;\nconst\n  fsFAT = $00000000;\n  fsAmiga = $00000001;\n  fsVMS = $00000002;\n  fsUnix = $00000003;\n  fsVM_CMS = $00000004;\n  fsAtariTOS = $00000005;\n  fsHPFS = $00000006;\n  fsMacintosh = $00000007;\n  fsZSystem = $00000008;\n  fsCP_M = $00000009;\n  fsTOPS20 = $0000000A;\n  fsNTFS = $0000000B;\n  fsQDOS = $0000000C;\n  fsAcornRISCOS = $0000000D;\n  fsUnknown = $0000000E;\n  fsUndefined = $0000000F;\n\ntype\n\n// *********************************************************************//\n// Forward declaration of types defined in TypeLibrary                    \n// *********************************************************************//\n  IZipItem = interface;\n  IZipItemDisp = dispinterface;\n  IGZipItem = interface;\n  IGZipItemDisp = dispinterface;\n  ITarItem = interface;\n  ITarItemDisp = dispinterface;\n  IZipKit = interface;\n  IZipKitDisp = dispinterface;\n  IZipKitEvents = dispinterface;\n\n// *********************************************************************//\n// Declaration of CoClasses defined in Type Library                       \n// (NOTE: Here we map each CoClass to its Default Interface)              \n// *********************************************************************//\n  ZipItem = IZipItem;\n  GZipItem = IGZipItem;\n  TarItem = ITarItem;\n  ZipKit = IZipKit;\n\n\n// *********************************************************************//\n// Interface: IZipItem\n// Flags:     (4416) Dual OleAutomation Dispatchable\n// GUID:      {851699A1-422A-4C65-8E08-D0499ACDD834}\n// *********************************************************************//\n  IZipItem = interface(IDispatch)\n    ['{851699A1-422A-4C65-8E08-D0499ACDD834}']\n    function Get_Action: TArchiveAction; safecall;\n    function Get_CompressedSize: Integer; safecall;\n    function Get_CRC32: Integer; safecall;\n    function Get_DiskFileName: WideString; safecall;\n    function Get_DiskPath: WideString; safecall;\n    function Get_ExternalFileAttributes: TFileAttributes; safecall;\n    procedure Set_ExternalFileAttributes(Value: TFileAttributes); safecall;\n    function Get_FileName: WideString; safecall;\n    procedure Set_FileName(const Value: WideString); safecall;\n    function Get_IsEncrypted: WordBool; safecall;\n    function Get_LastModFileDateTime: TDateTime; safecall;\n    function Get_StoredPath: WideString; safecall;\n    function Get_Tagged: WordBool; safecall;\n    procedure Set_Tagged(Value: WordBool); safecall;\n    function Get_UnCompressedSize: Integer; safecall;\n    function Get_CRC32St: WideString; safecall;\n    function Get_Password: WideString; safecall;\n    procedure Set_Password(const Value: WideString); safecall;\n    function Get_CompressionMethod: TZipCompressionMethod; safecall;\n    function Get_CompressionRatio: Double; safecall;\n    function Get_DeflateOption: TZipDeflateOption; safecall;\n    function Get_DictionarySize: TZipDictionarySize; safecall;\n    function Get_DiskNumberStart: Integer; safecall;\n    function Get_ExtraField: WideString; safecall;\n    procedure Set_ExtraField(const Value: WideString); safecall;\n    function Get_FileComment: WideString; safecall;\n    procedure Set_FileComment(const Value: WideString); safecall;\n    function Get_InternalFileAttributes: Integer; safecall;\n    procedure Set_InternalFileAttributes(Value: Integer); safecall;\n    function Get_VersionMadeBy: Integer; safecall;\n    function Get_VersionNeededToExtract: Integer; safecall;\n    property Action: TArchiveAction read Get_Action;\n    property CompressedSize: Integer read Get_CompressedSize;\n    property CRC32: Integer read Get_CRC32;\n    property DiskFileName: WideString read Get_DiskFileName;\n    property DiskPath: WideString read Get_DiskPath;\n    property ExternalFileAttributes: TFileAttributes read Get_ExternalFileAttributes write Set_ExternalFileAttributes;\n    property FileName: WideString read Get_FileName write Set_FileName;\n    property IsEncrypted: WordBool read Get_IsEncrypted;\n    property LastModFileDateTime: TDateTime read Get_LastModFileDateTime;\n    property StoredPath: WideString read Get_StoredPath;\n    property Tagged: WordBool read Get_Tagged write Set_Tagged;\n    property UnCompressedSize: Integer read Get_UnCompressedSize;\n    property CRC32St: WideString read Get_CRC32St;\n    property Password: WideString read Get_Password write Set_Password;\n    property CompressionMethod: TZipCompressionMethod read Get_CompressionMethod;\n    property CompressionRatio: Double read Get_CompressionRatio;\n    property DeflateOption: TZipDeflateOption read Get_DeflateOption;\n    property DictionarySize: TZipDictionarySize read Get_DictionarySize;\n    property DiskNumberStart: Integer read Get_DiskNumberStart;\n    property ExtraField: WideString read Get_ExtraField write Set_ExtraField;\n    property FileComment: WideString read Get_FileComment write Set_FileComment;\n    property InternalFileAttributes: Integer read Get_InternalFileAttributes write Set_InternalFileAttributes;\n    property VersionMadeBy: Integer read Get_VersionMadeBy;\n    property VersionNeededToExtract: Integer read Get_VersionNeededToExtract;\n  end;\n\n// *********************************************************************//\n// DispIntf:  IZipItemDisp\n// Flags:     (4416) Dual OleAutomation Dispatchable\n// GUID:      {851699A1-422A-4C65-8E08-D0499ACDD834}\n// *********************************************************************//\n  IZipItemDisp = dispinterface\n    ['{851699A1-422A-4C65-8E08-D0499ACDD834}']\n    property Action: TArchiveAction readonly dispid 1;\n    property CompressedSize: Integer readonly dispid 2;\n    property CRC32: Integer readonly dispid 3;\n    property DiskFileName: WideString readonly dispid 4;\n    property DiskPath: WideString readonly dispid 5;\n    property ExternalFileAttributes: TFileAttributes dispid 6;\n    property FileName: WideString dispid 7;\n    property IsEncrypted: WordBool readonly dispid 8;\n    property LastModFileDateTime: TDateTime readonly dispid 9;\n    property StoredPath: WideString readonly dispid 10;\n    property Tagged: WordBool dispid 11;\n    property UnCompressedSize: Integer readonly dispid 12;\n    property CRC32St: WideString readonly dispid 13;\n    property Password: WideString dispid 14;\n    property CompressionMethod: TZipCompressionMethod readonly dispid 15;\n    property CompressionRatio: Double readonly dispid 16;\n    property DeflateOption: TZipDeflateOption readonly dispid 17;\n    property DictionarySize: TZipDictionarySize readonly dispid 18;\n    property DiskNumberStart: Integer readonly dispid 19;\n    property ExtraField: WideString dispid 20;\n    property FileComment: WideString dispid 21;\n    property InternalFileAttributes: Integer dispid 22;\n    property VersionMadeBy: Integer readonly dispid 23;\n    property VersionNeededToExtract: Integer readonly dispid 24;\n  end;\n\n// *********************************************************************//\n// Interface: IGZipItem\n// Flags:     (4416) Dual OleAutomation Dispatchable\n// GUID:      {8FA78CE0-FD29-441E-9777-93B63EF1A9EE}\n// *********************************************************************//\n  IGZipItem = interface(IDispatch)\n    ['{8FA78CE0-FD29-441E-9777-93B63EF1A9EE}']\n    function Get_Action: TArchiveAction; safecall;\n    function Get_CompressedSize: Integer; safecall;\n    function Get_CRC32: Integer; safecall;\n    function Get_DiskFileName: WideString; safecall;\n    function Get_DiskPath: WideString; safecall;\n    function Get_ExternalFileAttributes: TFileAttributes; safecall;\n    procedure Set_ExternalFileAttributes(Value: TFileAttributes); safecall;\n    function Get_FileName: WideString; safecall;\n    procedure Set_FileName(const Value: WideString); safecall;\n    function Get_IsEncrypted: WordBool; safecall;\n    function Get_LastModFileDateTime: TDateTime; safecall;\n    function Get_StoredPath: WideString; safecall;\n    function Get_Tagged: WordBool; safecall;\n    procedure Set_Tagged(Value: WordBool); safecall;\n    function Get_UnCompressedSize: Integer; safecall;\n    function Get_CRC32St: WideString; safecall;\n    function Get_Password: WideString; safecall;\n    procedure Set_Password(const Value: WideString); safecall;\n    function Get_CompressionMethod: Byte; safecall;\n    procedure Set_CompressionMethod(Value: Byte); safecall;\n    function Get_ExtraField: WideString; safecall;\n    procedure Set_ExtraField(const Value: WideString); safecall;\n    function Get_ExtraFlags: Byte; safecall;\n    procedure Set_ExtraFlags(Value: Byte); safecall;\n    function Get_FileComment: WideString; safecall;\n    procedure Set_FileComment(const Value: WideString); safecall;\n    function Get_FileSystem: TFileSystem; safecall;\n    procedure Set_FileSystem(Value: TFileSystem); safecall;\n    function Get_Flags: Byte; safecall;\n    procedure Set_Flags(Value: Byte); safecall;\n    function Get_HeaderCRC: Integer; safecall;\n    property Action: TArchiveAction read Get_Action;\n    property CompressedSize: Integer read Get_CompressedSize;\n    property CRC32: Integer read Get_CRC32;\n    property DiskFileName: WideString read Get_DiskFileName;\n    property DiskPath: WideString read Get_DiskPath;\n    property ExternalFileAttributes: TFileAttributes read Get_ExternalFileAttributes write Set_ExternalFileAttributes;\n    property FileName: WideString read Get_FileName write Set_FileName;\n    property IsEncrypted: WordBool read Get_IsEncrypted;\n    property LastModFileDateTime: TDateTime read Get_LastModFileDateTime;\n    property StoredPath: WideString read Get_StoredPath;\n    property Tagged: WordBool read Get_Tagged write Set_Tagged;\n    property UnCompressedSize: Integer read Get_UnCompressedSize;\n    property CRC32St: WideString read Get_CRC32St;\n    property Password: WideString read Get_Password write Set_Password;\n    property CompressionMethod: Byte read Get_CompressionMethod write Set_CompressionMethod;\n    property ExtraField: WideString read Get_ExtraField write Set_ExtraField;\n    property ExtraFlags: Byte read Get_ExtraFlags write Set_ExtraFlags;\n    property FileComment: WideString read Get_FileComment write Set_FileComment;\n    property FileSystem: TFileSystem read Get_FileSystem write Set_FileSystem;\n    property Flags: Byte read Get_Flags write Set_Flags;\n    property HeaderCRC: Integer read Get_HeaderCRC;\n  end;\n\n// *********************************************************************//\n// DispIntf:  IGZipItemDisp\n// Flags:     (4416) Dual OleAutomation Dispatchable\n// GUID:      {8FA78CE0-FD29-441E-9777-93B63EF1A9EE}\n// *********************************************************************//\n  IGZipItemDisp = dispinterface\n    ['{8FA78CE0-FD29-441E-9777-93B63EF1A9EE}']\n    property Action: TArchiveAction readonly dispid 1;\n    property CompressedSize: Integer readonly dispid 2;\n    property CRC32: Integer readonly dispid 3;\n    property DiskFileName: WideString readonly dispid 4;\n    property DiskPath: WideString readonly dispid 5;\n    property ExternalFileAttributes: TFileAttributes dispid 6;\n    property FileName: WideString dispid 7;\n    property IsEncrypted: WordBool readonly dispid 8;\n    property LastModFileDateTime: TDateTime readonly dispid 9;\n    property StoredPath: WideString readonly dispid 10;\n    property Tagged: WordBool dispid 11;\n    property UnCompressedSize: Integer readonly dispid 12;\n    property CRC32St: WideString readonly dispid 13;\n    property Password: WideString dispid 14;\n    property CompressionMethod: Byte dispid 15;\n    property ExtraField: WideString dispid 16;\n    property ExtraFlags: Byte dispid 17;\n    property FileComment: WideString dispid 18;\n    property FileSystem: TFileSystem dispid 19;\n    property Flags: Byte dispid 20;\n    property HeaderCRC: Integer readonly dispid 21;\n  end;\n\n// *********************************************************************//\n// Interface: ITarItem\n// Flags:     (4416) Dual OleAutomation Dispatchable\n// GUID:      {729E9F52-C489-4A41-A770-4E2C5282AE39}\n// *********************************************************************//\n  ITarItem = interface(IDispatch)\n    ['{729E9F52-C489-4A41-A770-4E2C5282AE39}']\n    function Get_Action: TArchiveAction; safecall;\n    function Get_CompressedSize: Integer; safecall;\n    function Get_CRC32: Integer; safecall;\n    function Get_DiskFileName: WideString; safecall;\n    function Get_DiskPath: WideString; safecall;\n    function Get_ExternalFileAttributes: TFileAttributes; safecall;\n    procedure Set_ExternalFileAttributes(Value: TFileAttributes); safecall;\n    function Get_FileName: WideString; safecall;\n    procedure Set_FileName(const Value: WideString); safecall;\n    function Get_IsEncrypted: WordBool; safecall;\n    function Get_LastModFileDateTime: TDateTime; safecall;\n    function Get_StoredPath: WideString; safecall;\n    function Get_Tagged: WordBool; safecall;\n    procedure Set_Tagged(Value: WordBool); safecall;\n    function Get_UnCompressedSize: Integer; safecall;\n    function Get_CRC32St: WideString; safecall;\n    function Get_Password: WideString; safecall;\n    procedure Set_Password(const Value: WideString); safecall;\n    function Get_DevMajor: Integer; safecall;\n    procedure Set_DevMajor(Value: Integer); safecall;\n    function Get_DevMinor: Integer; safecall;\n    procedure Set_DevMinor(Value: Integer); safecall;\n    function Get_GroupID: Integer; safecall;\n    procedure Set_GroupID(Value: Integer); safecall;\n    function Get_GroupName: WideString; safecall;\n    procedure Set_GroupName(const Value: WideString); safecall;\n    function Get_LinkFlag: Byte; safecall;\n    procedure Set_LinkFlag(Value: Byte); safecall;\n    function Get_LinkName: WideString; safecall;\n    procedure Set_LinkName(const Value: WideString); safecall;\n    function Get_Mode: Integer; safecall;\n    procedure Set_Mode(Value: Integer); safecall;\n    function Get_UserID: Integer; safecall;\n    procedure Set_UserID(Value: Integer); safecall;\n    function Get_UserName: WideString; safecall;\n    procedure Set_UserName(const Value: WideString); safecall;\n    property Action: TArchiveAction read Get_Action;\n    property CompressedSize: Integer read Get_CompressedSize;\n    property CRC32: Integer read Get_CRC32;\n    property DiskFileName: WideString read Get_DiskFileName;\n    property DiskPath: WideString read Get_DiskPath;\n    property ExternalFileAttributes: TFileAttributes read Get_ExternalFileAttributes write Set_ExternalFileAttributes;\n    property FileName: WideString read Get_FileName write Set_FileName;\n    property IsEncrypted: WordBool read Get_IsEncrypted;\n    property LastModFileDateTime: TDateTime read Get_LastModFileDateTime;\n    property StoredPath: WideString read Get_StoredPath;\n    property Tagged: WordBool read Get_Tagged write Set_Tagged;\n    property UnCompressedSize: Integer read Get_UnCompressedSize;\n    property CRC32St: WideString read Get_CRC32St;\n    property Password: WideString read Get_Password write Set_Password;\n    property DevMajor: Integer read Get_DevMajor write Set_DevMajor;\n    property DevMinor: Integer read Get_DevMinor write Set_DevMinor;\n    property GroupID: Integer read Get_GroupID write Set_GroupID;\n    property GroupName: WideString read Get_GroupName write Set_GroupName;\n    property LinkFlag: Byte read Get_LinkFlag write Set_LinkFlag;\n    property LinkName: WideString read Get_LinkName write Set_LinkName;\n    property Mode: Integer read Get_Mode write Set_Mode;\n    property UserID: Integer read Get_UserID write Set_UserID;\n    property UserName: WideString read Get_UserName write Set_UserName;\n  end;\n\n// *********************************************************************//\n// DispIntf:  ITarItemDisp\n// Flags:     (4416) Dual OleAutomation Dispatchable\n// GUID:      {729E9F52-C489-4A41-A770-4E2C5282AE39}\n// *********************************************************************//\n  ITarItemDisp = dispinterface\n    ['{729E9F52-C489-4A41-A770-4E2C5282AE39}']\n    property Action: TArchiveAction readonly dispid 1;\n    property CompressedSize: Integer readonly dispid 2;\n    property CRC32: Integer readonly dispid 3;\n    property DiskFileName: WideString readonly dispid 4;\n    property DiskPath: WideString readonly dispid 5;\n    property ExternalFileAttributes: TFileAttributes dispid 6;\n    property FileName: WideString dispid 7;\n    property IsEncrypted: WordBool readonly dispid 8;\n    property LastModFileDateTime: TDateTime readonly dispid 9;\n    property StoredPath: WideString readonly dispid 10;\n    property Tagged: WordBool dispid 11;\n    property UnCompressedSize: Integer readonly dispid 12;\n    property CRC32St: WideString readonly dispid 13;\n    property Password: WideString dispid 14;\n    property DevMajor: Integer dispid 15;\n    property DevMinor: Integer dispid 16;\n    property GroupID: Integer dispid 17;\n    property GroupName: WideString dispid 18;\n    property LinkFlag: Byte dispid 19;\n    property LinkName: WideString dispid 20;\n    property Mode: Integer dispid 21;\n    property UserID: Integer dispid 22;\n    property UserName: WideString dispid 23;\n  end;\n\n// *********************************************************************//\n// Interface: IZipKit\n// Flags:     (4416) Dual OleAutomation Dispatchable\n// GUID:      {B7480A7F-4E27-4B45-9FE6-224B60295A0C}\n// *********************************************************************//\n  IZipKit = interface(IDispatch)\n    ['{B7480A7F-4E27-4B45-9FE6-224B60295A0C}']\n    procedure Add(const FileMask: WideString; const ExclusionMask: WideString; SearchAttr: Integer); safecall;\n    procedure AddFromStream(const FileName: WideString; Stream: OleVariant); safecall;\n    function Get_AutoSave: WordBool; safecall;\n    procedure Set_AutoSave(Value: WordBool); safecall;\n    function Get_BaseDirectory: WideString; safecall;\n    procedure Set_BaseDirectory(const Value: WideString); safecall;\n    procedure ClearTags; safecall;\n    function Get_CompressionMethodToUse: TZipSupportMethod; safecall;\n    procedure Set_CompressionMethodToUse(Value: TZipSupportMethod); safecall;\n    function Get_Count: Integer; safecall;\n    function Get_DeflateOption: TZipDeflateOption; safecall;\n    procedure Set_DeflateOption(Value: TZipDeflateOption); safecall;\n    procedure Delete(const FileMask: WideString; const ExclusionMask: WideString); safecall;\n    procedure DeleteAt(Index: Integer); safecall;\n    procedure DeleteTaggedItems; safecall;\n    function Get_DOSMode: WordBool; safecall;\n    procedure Set_DOSMode(Value: WordBool); safecall;\n    procedure Extract(const FileMask: WideString; const ExclusionMask: WideString); safecall;\n    procedure ExtractAt(Index: Integer; const NewName: WideString); safecall;\n    function Get_ExtractOptions: TZipExtractOptions; safecall;\n    procedure Set_ExtractOptions(Value: TZipExtractOptions); safecall;\n    procedure ExtractTaggedItems; safecall;\n    function Get_FileName: WideString; safecall;\n    procedure Set_FileName(const Value: WideString); safecall;\n    function Find(const FileName: WideString): Integer; safecall;\n    procedure Freshen(const FileMask: WideString; const ExclusionMask: WideString); safecall;\n    procedure FreshenTaggedItems; safecall;\n    function Get_Item(Index: Integer): IDispatch; safecall;\n    function Get_LogFile: WideString; safecall;\n    procedure Set_LogFile(const Value: WideString); safecall;\n    function Get_Logging: WordBool; safecall;\n    procedure Set_Logging(Value: WordBool); safecall;\n    function Get_Password: WideString; safecall;\n    procedure Set_Password(const Value: WideString); safecall;\n    function Get_PasswordRetries: Byte; safecall;\n    procedure Set_PasswordRetries(Value: Byte); safecall;\n    procedure Replace(const FileMask: WideString); safecall;\n    procedure Save; safecall;\n    function Get_Spanned: WordBool; safecall;\n    function Get_SpanningThreshold: Integer; safecall;\n    procedure Set_SpanningThreshold(Value: Integer); safecall;\n    function Get_Status: TArchiveStatus; safecall;\n    function Get_StoreOptions: TStoreOptions; safecall;\n    procedure Set_StoreOptions(Value: TStoreOptions); safecall;\n    procedure TagItems(const FileMask: WideString); safecall;\n    function Get_TempDirectory: WideString; safecall;\n    procedure Set_TempDirectory(const Value: WideString); safecall;\n    procedure TestTaggedItems; safecall;\n    procedure UntagItems(const FileMask: WideString); safecall;\n    function Get_ZipFileComment: WideString; safecall;\n    procedure Set_ZipFileComment(const Value: WideString); safecall;\n    function License(const Key: WideString): WordBool; safecall;\n    function Get__NewEnum: IUnknown; safecall;\n    function ExtractToStream(const FileName: WideString): OleVariant; safecall;\n    function Get_CompressionType: TArchiveType; safecall;\n    procedure Set_CompressionType(Value: TArchiveType); safecall;\n    function Get_TarAutoHandle: WordBool; safecall;\n    procedure Set_TarAutoHandle(Value: WordBool); safecall;\n    property AutoSave: WordBool read Get_AutoSave write Set_AutoSave;\n    property BaseDirectory: WideString read Get_BaseDirectory write Set_BaseDirectory;\n    property CompressionMethodToUse: TZipSupportMethod read Get_CompressionMethodToUse write Set_CompressionMethodToUse;\n    property Count: Integer read Get_Count;\n    property DeflateOption: TZipDeflateOption read Get_DeflateOption write Set_DeflateOption;\n    property DOSMode: WordBool read Get_DOSMode write Set_DOSMode;\n    property ExtractOptions: TZipExtractOptions read Get_ExtractOptions write Set_ExtractOptions;\n    property FileName: WideString read Get_FileName write Set_FileName;\n    property Item[Index: Integer]: IDispatch read Get_Item;\n    property LogFile: WideString read Get_LogFile write Set_LogFile;\n    property Logging: WordBool read Get_Logging write Set_Logging;\n    property Password: WideString read Get_Password write Set_Password;\n    property PasswordRetries: Byte read Get_PasswordRetries write Set_PasswordRetries;\n    property Spanned: WordBool read Get_Spanned;\n    property SpanningThreshold: Integer read Get_SpanningThreshold write Set_SpanningThreshold;\n    property Status: TArchiveStatus read Get_Status;\n    property StoreOptions: TStoreOptions read Get_StoreOptions write Set_StoreOptions;\n    property TempDirectory: WideString read Get_TempDirectory write Set_TempDirectory;\n    property ZipFileComment: WideString read Get_ZipFileComment write Set_ZipFileComment;\n    property _NewEnum: IUnknown read Get__NewEnum;\n    property CompressionType: TArchiveType read Get_CompressionType write Set_CompressionType;\n    property TarAutoHandle: WordBool read Get_TarAutoHandle write Set_TarAutoHandle;\n  end;\n\n// *********************************************************************//\n// DispIntf:  IZipKitDisp\n// Flags:     (4416) Dual OleAutomation Dispatchable\n// GUID:      {B7480A7F-4E27-4B45-9FE6-224B60295A0C}\n// *********************************************************************//\n  IZipKitDisp = dispinterface\n    ['{B7480A7F-4E27-4B45-9FE6-224B60295A0C}']\n    procedure Add(const FileMask: WideString; const ExclusionMask: WideString; SearchAttr: Integer); dispid 1;\n    procedure AddFromStream(const FileName: WideString; Stream: OleVariant); dispid 7;\n    property AutoSave: WordBool dispid 3;\n    property BaseDirectory: WideString dispid 4;\n    procedure ClearTags; dispid 5;\n    property CompressionMethodToUse: TZipSupportMethod dispid 6;\n    property Count: Integer readonly dispid 2;\n    property DeflateOption: TZipDeflateOption dispid 8;\n    procedure Delete(const FileMask: WideString; const ExclusionMask: WideString); dispid 9;\n    procedure DeleteAt(Index: Integer); dispid 10;\n    procedure DeleteTaggedItems; dispid 11;\n    property DOSMode: WordBool dispid 12;\n    procedure Extract(const FileMask: WideString; const ExclusionMask: WideString); dispid 13;\n    procedure ExtractAt(Index: Integer; const NewName: WideString); dispid 14;\n    property ExtractOptions: TZipExtractOptions dispid 15;\n    procedure ExtractTaggedItems; dispid 16;\n    property FileName: WideString dispid 17;\n    function Find(const FileName: WideString): Integer; dispid 18;\n    procedure Freshen(const FileMask: WideString; const ExclusionMask: WideString); dispid 19;\n    procedure FreshenTaggedItems; dispid 20;\n    property Item[Index: Integer]: IDispatch readonly dispid 0;\n    property LogFile: WideString dispid 23;\n    property Logging: WordBool dispid 24;\n    property Password: WideString dispid 25;\n    property PasswordRetries: Byte dispid 26;\n    procedure Replace(const FileMask: WideString); dispid 27;\n    procedure Save; dispid 28;\n    property Spanned: WordBool readonly dispid 29;\n    property SpanningThreshold: Integer dispid 30;\n    property Status: TArchiveStatus readonly dispid 31;\n    property StoreOptions: TStoreOptions dispid 32;\n    procedure TagItems(const FileMask: WideString); dispid 33;\n    property TempDirectory: WideString dispid 34;\n    procedure TestTaggedItems; dispid 35;\n    procedure UntagItems(const FileMask: WideString); dispid 36;\n    property ZipFileComment: WideString dispid 37;\n    function License(const Key: WideString): WordBool; dispid 38;\n    property _NewEnum: IUnknown readonly dispid $FFFFFFFC;\n    function ExtractToStream(const FileName: WideString): OleVariant; dispid 21;\n    property CompressionType: TArchiveType dispid 40;\n    property TarAutoHandle: WordBool dispid 41;\n  end;\n\n// *********************************************************************//\n// DispIntf:  IZipKitEvents\n// Flags:     (4096) Dispatchable\n// GUID:      {F094D5F4-3A52-45AE-9D86-4409611DD29E}\n// *********************************************************************//\n  IZipKitEvents = dispinterface\n    ['{F094D5F4-3A52-45AE-9D86-4409611DD29E}']\n    procedure OnArchiveItemProgress(const Item: IDispatch; Progress: Byte; var Abort: WordBool); dispid 1;\n    procedure OnArchiveProgress(Progress: Byte; var Abort: WordBool); dispid 2;\n    procedure OnChange; dispid 3;\n    procedure OnConfirmOverwrite(var Name: WideString; var Confirm: WordBool); dispid 4;\n    procedure OnConfirmProcessItem(const Item: IDispatch; ProcessType: TProcessType; \n                                   var Confirm: WordBool); dispid 5;\n    procedure OnConfirmSave(var Confirm: WordBool); dispid 6;\n    procedure OnLoad; dispid 7;\n    procedure OnNeedPassword(var NewPassword: WideString); dispid 8;\n    procedure OnProcessItemFailure(const Item: IDispatch; ProcessType: TProcessType; \n                                   ErrorClass: TErrorClass; ErrorCode: TErrorCode; \n                                   const ErrorString: WideString); dispid 9;\n    procedure OnRequestBlankDisk(var Abort: WordBool); dispid 10;\n    procedure OnRequestImage(ImageNumber: Integer; var ImageName: WideString; var Abort: WordBool); dispid 11;\n    procedure OnRequestLastDisk(var Abort: WordBool); dispid 12;\n    procedure OnRequestNthDisk(DiskNumber: Integer; var Abort: WordBool); dispid 13;\n    procedure OnSave; dispid 14;\n  end;\n\n// *********************************************************************//\n// The Class CoZipItem provides a Create and CreateRemote method to          \n// create instances of the default interface IZipItem exposed by              \n// the CoClass ZipItem. The functions are intended to be used by             \n// clients wishing to automate the CoClass objects exposed by the         \n// server of this typelibrary.                                            \n// *********************************************************************//\n  CoZipItem = class\n    class function Create: IZipItem;\n    class function CreateRemote(const MachineName: string): IZipItem;\n  end;\n\n// *********************************************************************//\n// The Class CoGZipItem provides a Create and CreateRemote method to          \n// create instances of the default interface IGZipItem exposed by              \n// the CoClass GZipItem. The functions are intended to be used by             \n// clients wishing to automate the CoClass objects exposed by the         \n// server of this typelibrary.                                            \n// *********************************************************************//\n  CoGZipItem = class\n    class function Create: IGZipItem;\n    class function CreateRemote(const MachineName: string): IGZipItem;\n  end;\n\n// *********************************************************************//\n// The Class CoTarItem provides a Create and CreateRemote method to          \n// create instances of the default interface ITarItem exposed by              \n// the CoClass TarItem. The functions are intended to be used by             \n// clients wishing to automate the CoClass objects exposed by the         \n// server of this typelibrary.                                            \n// *********************************************************************//\n  CoTarItem = class\n    class function Create: ITarItem;\n    class function CreateRemote(const MachineName: string): ITarItem;\n  end;\n\n// *********************************************************************//\n// The Class CoZipKit provides a Create and CreateRemote method to          \n// create instances of the default interface IZipKit exposed by              \n// the CoClass ZipKit. The functions are intended to be used by             \n// clients wishing to automate the CoClass objects exposed by the         \n// server of this typelibrary.                                            \n// *********************************************************************//\n  CoZipKit = class\n    class function Create: IZipKit;\n    class function CreateRemote(const MachineName: string): IZipKit;\n  end;\n\nimplementation\n\nuses ComObj;\n\nclass function CoZipItem.Create: IZipItem;\nbegin\n  Result := CreateComObject(CLASS_ZipItem) as IZipItem;\nend;\n\nclass function CoZipItem.CreateRemote(const MachineName: string): IZipItem;\nbegin\n  Result := CreateRemoteComObject(MachineName, CLASS_ZipItem) as IZipItem;\nend;\n\nclass function CoGZipItem.Create: IGZipItem;\nbegin\n  Result := CreateComObject(CLASS_GZipItem) as IGZipItem;\nend;\n\nclass function CoGZipItem.CreateRemote(const MachineName: string): IGZipItem;\nbegin\n  Result := CreateRemoteComObject(MachineName, CLASS_GZipItem) as IGZipItem;\nend;\n\nclass function CoTarItem.Create: ITarItem;\nbegin\n  Result := CreateComObject(CLASS_TarItem) as ITarItem;\nend;\n\nclass function CoTarItem.CreateRemote(const MachineName: string): ITarItem;\nbegin\n  Result := CreateRemoteComObject(MachineName, CLASS_TarItem) as ITarItem;\nend;\n\nclass function CoZipKit.Create: IZipKit;\nbegin\n  Result := CreateComObject(CLASS_ZipKit) as IZipKit;\nend;\n\nclass function CoZipKit.CreateRemote(const MachineName: string): IZipKit;\nbegin\n  Result := CreateRemoteComObject(MachineName, CLASS_ZipKit) as IZipKit;\nend;\n\nend.\n"
  },
  {
    "path": "lib/abbrevia/source/COM/Readme.txt",
    "content": "The COM DLLs for v5.0 are compiled using Delphi XE2 (including extended RTTI) and include zipx support.  Recompiling with Delphi 2009 and without zipx support should roughly halve the size of the 32-bit DLL.\n\nThey can be registered for all users (requires admin rights) using:\n\n  regsvr32 Abbrevia.dll\n\nAnd for the current user using:\n\n  regsvr32 /i:user /n Abbrevia.dll\n\nTo uninstall use:\n\n  regsvr32 /u Abbrevia.dll\n\nor \n\n  regsvr32 /i:user /n /u Abbrevia.dll"
  },
  {
    "path": "lib/abbrevia/source/COM/_GZipItem.pas",
    "content": "(* ***** BEGIN LICENSE BLOCK *****\n * Version: MPL 1.1\n *\n * The contents of this file are subject to the Mozilla Public License Version\n * 1.1 (the \"License\"); you may not use this file except in compliance with\n * the License. You may obtain a copy of the License at\n * http://www.mozilla.org/MPL/\n *\n * Software distributed under the License is distributed on an \"AS IS\" basis,\n * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License\n * for the specific language governing rights and limitations under the\n * License.\n *\n * The Original Code is TurboPower Abbrevia\n *\n * The Initial Developer of the Original Code is\n * TurboPower Software\n *\n * Portions created by the Initial Developer are Copyright (C) 1997-2002\n * the Initial Developer. All Rights Reserved.\n *\n * Contributor(s):\n *\n * ***** END LICENSE BLOCK ***** *)\n\nunit _GZipItem;\n\ninterface\n\nuses\n  ComObj, Abbrevia_TLB, AbGzTyp, AbZipKit;\n\ntype\n\n  TGZipItem = class(TAutoIntfObject, IGZipItem)\n  private\n    FOwner  : TAbGzipItem;\n    FParent : TAbZipKit;\n  public\n    constructor Create(AOwner : TAbGzipItem; AParent : TAbZipKit);\n  protected\n    {IArchiveItem}\n    function  Get_Action: TArchiveAction; safecall;\n    function  Get_CompressedSize: Integer; safecall;\n    function  Get_CRC32: Integer; safecall;\n    function  Get_CRC32St: WideString; safecall;\n    function  Get_DiskFileName: WideString; safecall;\n    function  Get_DiskPath: WideString; safecall;\n    function  Get_ExternalFileAttributes: TFileAttributes; safecall;\n    procedure Set_ExternalFileAttributes(Value: TFileAttributes); safecall;\n    function  Get_FileName: WideString; safecall;\n    procedure Set_FileName(const Value: WideString); safecall;\n    function  Get_IsEncrypted: WordBool; safecall;\n    function  Get_LastModFileDateTime: TDateTime; safecall;\n    function  Get_StoredPath: WideString; safecall;\n    function  Get_Tagged: WordBool; safecall;\n    procedure Set_Tagged(Value: WordBool); safecall;\n    function  Get_UnCompressedSize: Integer; safecall;\n    function  Get_Password: WideString; safecall;\n    procedure Set_Password(const Value: WideString); safecall;\n\n    {IGZipItem}\n    function  Get_CompressionMethod: Byte; safecall;\n    procedure Set_CompressionMethod(Value: Byte); safecall;\n    function  Get_ExtraField: WideString; safecall;\n    procedure Set_ExtraField(const Value: WideString); safecall;\n    function  Get_ExtraFlags: Byte; safecall;\n    procedure Set_ExtraFlags(Value: Byte); safecall;\n    function  Get_FileComment: WideString; safecall;\n    procedure Set_FileComment(const Value: WideString); safecall;\n    function  Get_FileSystem: TFileSystem; safecall;\n    procedure Set_FileSystem(Value: TFileSystem); safecall;\n    function  Get_Flags: Byte; safecall;\n    procedure Set_Flags(Value: Byte); safecall;\n    function  Get_HeaderCRC: Integer; safecall;\n  end;\n\n\nimplementation\n\nuses\n  ComServ, {StStrL,} SysUtils;\n\n{------------------------------------------------------------------------------}\nconstructor TGzipItem.Create(AOwner : TAbGzipItem; AParent : TAbZipKit);\nbegin\n  inherited Create(ComServer.TypeLib, IGZipItem);\n  FOwner := AOwner;\n  FParent := AParent;\nend;\n{------------------------------------------------------------------------------}\n{IArchiveItem}\n{------------------------------------------------------------------------------}\nfunction  TGzipItem.Get_Action: TArchiveAction;\nbegin\n  Result := TArchiveAction(FOwner.Action);\nend;\n{------------------------------------------------------------------------------}\nfunction  TGzipItem.Get_CompressedSize: Integer;\nbegin\n  result := FOwner.CompressedSize;\nend;\n{------------------------------------------------------------------------------}\nfunction  TGzipItem.Get_CRC32: Integer;\nbegin\n  result := FOwner.CRC32;\nend;\n{------------------------------------------------------------------------------}\nfunction  TGzipItem.Get_CRC32St: WideString;\nbegin\n  result := IntToHex(FOwner.CRC32, 8);\nend;\n{------------------------------------------------------------------------------}\nfunction  TGzipItem.Get_DiskFileName: WideString;\nbegin\n  result := FOwner.DiskFileName;\nend;\n{------------------------------------------------------------------------------}\nfunction  TGzipItem.Get_DiskPath: WideString;\nbegin\n  result := FOwner.DiskPath;\nend;\n{------------------------------------------------------------------------------}\nfunction  TGzipItem.Get_ExternalFileAttributes: TFileAttributes;\nbegin\n  result := TFileAttributes(FOwner.ExternalFileAttributes);\nend;\n{------------------------------------------------------------------------------}\nprocedure TGzipItem.Set_ExternalFileAttributes(Value: TFileAttributes);\nbegin\n  FOwner.ExternalFileAttributes := LongInt(Value);\n  FParent.ZipArchive.IsDirty := True;\nend;\n{------------------------------------------------------------------------------}\nfunction  TGzipItem.Get_FileName: WideString;\nbegin\n  result := FOwner.FileName;\nend;\n{------------------------------------------------------------------------------}\nprocedure TGzipItem.Set_FileName(const Value: WideString);\nbegin\n  FOwner.FileName := Value;\nend;\n{------------------------------------------------------------------------------}\nfunction  TGzipItem.Get_IsEncrypted: WordBool;\nbegin\n  result := FOwner.IsEncrypted;\nend;\n{------------------------------------------------------------------------------}\nfunction  TGzipItem.Get_LastModFileDateTime: TDateTime;\nbegin\n  result := FileDateToDateTime((FOwner.LastModFileDate shl 16) + FOwner.LastModFileTime);\nend;\n{------------------------------------------------------------------------------}\nfunction  TGzipItem.Get_StoredPath: WideString;\nbegin\n  result := FOwner.StoredPath;\nend;\n{------------------------------------------------------------------------------}\nfunction  TGzipItem.Get_Tagged: WordBool;\nbegin\n  result := FOwner.Tagged;\nend;\n{------------------------------------------------------------------------------}\nprocedure TGzipItem.Set_Tagged(Value: WordBool);\nbegin\n  FOwner.Tagged := Value;\nend;\n{------------------------------------------------------------------------------}\nfunction  TGzipItem.Get_UnCompressedSize: Integer;\nbegin\n  result := FOwner.UncompressedSize;\nend;\n{------------------------------------------------------------------------------}\nfunction  TGzipItem.Get_Password: WideString;\nbegin\n  {!!!}\n  //result := FOwner.Password;\nend;\n{------------------------------------------------------------------------------}\nprocedure TGzipItem.Set_Password(const Value: WideString);\nbegin\n  {!!!}\n  //FOwner.Password := Value;\n  //FParent.ZipArchive.IsDirty := True;\nend;\n{------------------------------------------------------------------------------}\n{IGZipItem}\n{------------------------------------------------------------------------------}\nfunction  TGzipItem.Get_CompressionMethod: Byte;\nbegin\n  result := FOwner.CompressionMethod;\nend;\n{------------------------------------------------------------------------------}\nprocedure TGzipItem.Set_CompressionMethod(Value: Byte);\nbegin\n\nend;\n{------------------------------------------------------------------------------}\nfunction  TGzipItem.Get_ExtraField: WideString;\nbegin\n  result := '';\nend;\n{------------------------------------------------------------------------------}\nprocedure TGzipItem.Set_ExtraField(const Value: WideString);\nbegin\n\nend;\n{------------------------------------------------------------------------------}\nfunction  TGzipItem.Get_ExtraFlags: Byte;\nbegin\n  result := FOwner.ExtraFlags;\nend;\n{------------------------------------------------------------------------------}\nprocedure TGzipItem.Set_ExtraFlags(Value: Byte);\nbegin\n  FOwner.ExtraFlags := Value;\n  FParent.ZipArchive.IsDirty := True;\nend;\n{------------------------------------------------------------------------------}\nfunction  TGzipItem.Get_FileComment: WideString;\nbegin\n  result := WideString(FOwner.FileComment);\nend;\n{------------------------------------------------------------------------------}\nprocedure TGzipItem.Set_FileComment(const Value: WideString);\nbegin\n  FOwner.FileComment := AnsiString(Value);\n  FParent.ZipArchive.IsDirty := True;\nend;\n{------------------------------------------------------------------------------}\nfunction  TGzipItem.Get_FileSystem: TFileSystem;\nbegin\n  result := TFileSystem(FOwner.FileSystem);\nend;\n{------------------------------------------------------------------------------}\nprocedure TGzipItem.Set_FileSystem(Value: TFileSystem);\nbegin\n  FOwner.FileSystem := TAbGzFileSystem(Value);\n  FParent.ZipArchive.IsDirty := True;\nend;\n{------------------------------------------------------------------------------}\nfunction  TGzipItem.Get_Flags: Byte;\nbegin\n  result := FOwner.Flags;\nend;\n{------------------------------------------------------------------------------}\nprocedure TGzipItem.Set_Flags(Value: Byte);\nbegin\n\nend;\n{------------------------------------------------------------------------------}\nfunction  TGzipItem.Get_HeaderCRC: Integer;\nbegin\n  result := 0;\nend;\n{------------------------------------------------------------------------------}\n\n\n\n\nend.\n"
  },
  {
    "path": "lib/abbrevia/source/COM/_TarItem.pas",
    "content": "(* ***** BEGIN LICENSE BLOCK *****\n * Version: MPL 1.1\n *\n * The contents of this file are subject to the Mozilla Public License Version\n * 1.1 (the \"License\"); you may not use this file except in compliance with\n * the License. You may obtain a copy of the License at\n * http://www.mozilla.org/MPL/\n *\n * Software distributed under the License is distributed on an \"AS IS\" basis,\n * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License\n * for the specific language governing rights and limitations under the\n * License.\n *\n * The Original Code is TurboPower Abbrevia\n *\n * The Initial Developer of the Original Code is\n * TurboPower Software\n *\n * Portions created by the Initial Developer are Copyright (C) 1997-2002\n * the Initial Developer. All Rights Reserved.\n *\n * Contributor(s):\n *\n * ***** END LICENSE BLOCK ***** *)\n\nunit _TarItem;\n\ninterface\n\nuses\n  ComObj, Abbrevia_TLB, AbTarTyp, AbZipKit;\n\ntype\n\n  TTarItem = class(TAutoIntfObject, ITarItem)\n  private\n    FOwner  : TAbTarItem;\n    FParent : TAbZipKit;\n  public\n    constructor Create(AOwner : TAbTarItem; AParent : TAbZipKit);\n  protected\n    {IArchiveItem}\n    function  Get_Action: TArchiveAction; safecall;\n    function  Get_CompressedSize: Integer; safecall;\n    function  Get_CRC32: Integer; safecall;\n    function  Get_CRC32St: WideString; safecall;\n    function  Get_DiskFileName: WideString; safecall;\n    function  Get_DiskPath: WideString; safecall;\n    function  Get_ExternalFileAttributes: TFileAttributes; safecall;\n    procedure Set_ExternalFileAttributes(Value: TFileAttributes); safecall;\n    function  Get_FileName: WideString; safecall;\n    procedure Set_FileName(const Value: WideString); safecall;\n    function  Get_IsEncrypted: WordBool; safecall;\n    function  Get_LastModFileDateTime: TDateTime; safecall;\n    function  Get_StoredPath: WideString; safecall;\n    function  Get_Tagged: WordBool; safecall;\n    procedure Set_Tagged(Value: WordBool); safecall;\n    function  Get_UnCompressedSize: Integer; safecall;\n    function  Get_Password: WideString; safecall;\n    procedure Set_Password(const Value: WideString); safecall;\n\n    {ITarItem}\n    function  Get_DevMajor: Integer; safecall;\n    procedure Set_DevMajor(Value: Integer); safecall;\n    function  Get_DevMinor: Integer; safecall;\n    procedure Set_DevMinor(Value: Integer); safecall;\n    function  Get_GroupID: Integer; safecall;\n    procedure Set_GroupID(Value: Integer); safecall;\n    function  Get_GroupName: WideString; safecall;\n    procedure Set_GroupName(const Value: WideString); safecall;\n    function  Get_LinkFlag: Byte; safecall;\n    procedure Set_LinkFlag(Value: Byte); safecall;\n    function  Get_LinkName: WideString; safecall;\n    procedure Set_LinkName(const Value: WideString); safecall;\n    function  Get_Mode: Integer; safecall;\n    procedure Set_Mode(Value: Integer); safecall;\n    function  Get_UserID: Integer; safecall;\n    procedure Set_UserID(Value: Integer); safecall;\n    function  Get_UserName: WideString; safecall;\n    procedure Set_UserName(const Value: WideString); safecall;\n\n  end;\n\n\nimplementation\n\nuses\n  ComServ, {StStrL,} SysUtils;\n\n{------------------------------------------------------------------------------}\nconstructor TTarItem.Create(AOwner : TAbTarItem; AParent : TAbZipKit);\nbegin\n  inherited Create(ComServer.TypeLib, ITarItem);\n  FOwner := AOwner;\n  FParent := AParent;\nend;\n{------------------------------------------------------------------------------}\n{IArchiveItem}\n{------------------------------------------------------------------------------}\nfunction  TTarItem.Get_Action: TArchiveAction;\nbegin\n  Result := TArchiveAction(FOwner.Action);\nend;\n{------------------------------------------------------------------------------}\nfunction  TTarItem.Get_CompressedSize: Integer;\nbegin\n  result := FOwner.CompressedSize;\nend;\n{------------------------------------------------------------------------------}\nfunction  TTarItem.Get_CRC32: Integer;\nbegin\n  result := FOwner.CRC32;\nend;\n{------------------------------------------------------------------------------}\nfunction  TTarItem.Get_CRC32St: WideString;\nbegin\n  result := IntToHex(FOwner.CRC32, 8);\nend;\n{------------------------------------------------------------------------------}\nfunction  TTarItem.Get_DiskFileName: WideString;\nbegin\n  result := FOwner.DiskFileName;\nend;\n{------------------------------------------------------------------------------}\nfunction  TTarItem.Get_DiskPath: WideString;\nbegin\n  result := FOwner.DiskPath;\nend;\n{------------------------------------------------------------------------------}\nfunction  TTarItem.Get_ExternalFileAttributes: TFileAttributes;\nbegin\n  result := TFileAttributes(FOwner.ExternalFileAttributes);\nend;\n{------------------------------------------------------------------------------}\nprocedure TTarItem.Set_ExternalFileAttributes(Value: TFileAttributes);\nbegin\n  FOwner.ExternalFileAttributes := LongInt(Value);\n  FParent.ZipArchive.IsDirty := True;\nend;\n{------------------------------------------------------------------------------}\nfunction  TTarItem.Get_FileName: WideString;\nbegin\n  result := FOwner.FileName;\nend;\n{------------------------------------------------------------------------------}\nprocedure TTarItem.Set_FileName(const Value: WideString);\nbegin\n  FOwner.FileName := Value;\nend;\n{------------------------------------------------------------------------------}\nfunction  TTarItem.Get_IsEncrypted: WordBool;\nbegin\n  result := FOwner.IsEncrypted;\nend;\n{------------------------------------------------------------------------------}\nfunction  TTarItem.Get_LastModFileDateTime: TDateTime;\nbegin\n  result := FileDateToDateTime((FOwner.LastModFileDate shl 16) + FOwner.LastModFileTime);\nend;\n{------------------------------------------------------------------------------}\nfunction  TTarItem.Get_StoredPath: WideString;\nbegin\n  result := FOwner.StoredPath;\nend;\n{------------------------------------------------------------------------------}\nfunction  TTarItem.Get_Tagged: WordBool;\nbegin\n  result := FOwner.Tagged;\nend;\n{------------------------------------------------------------------------------}\nprocedure TTarItem.Set_Tagged(Value: WordBool);\nbegin\n  FOwner.Tagged := Value;\nend;\n{------------------------------------------------------------------------------}\nfunction  TTarItem.Get_UnCompressedSize: Integer;\nbegin\n  result := FOwner.UncompressedSize;\nend;\n{------------------------------------------------------------------------------}\nfunction  TTarItem.Get_Password: WideString;\nbegin\n  {!!!}\n  //result := FOwner.Password;\nend;\n{------------------------------------------------------------------------------}\nprocedure TTarItem.Set_Password(const Value: WideString);\nbegin\n  {!!!}\n  //FOwner.Password := Value;\n  //FParent.ZipArchive.IsDirty := True;\nend;\n{------------------------------------------------------------------------------}\n{ITarItem}\n{------------------------------------------------------------------------------}\nfunction  TTarItem.Get_DevMajor: Integer;\nbegin\n  result := FOwner.DevMajor;\nend;\n{------------------------------------------------------------------------------}\nprocedure TTarItem.Set_DevMajor(Value: Integer);\nbegin\n  FOwner.DevMajor := Value;\n  FParent.ZipArchive.IsDirty := True;\nend;\n{------------------------------------------------------------------------------}\nfunction  TTarItem.Get_DevMinor: Integer;\nbegin\n  result := FOwner.DevMinor;\nend;\n{------------------------------------------------------------------------------}\nprocedure TTarItem.Set_DevMinor(Value: Integer);\nbegin\n  FOwner.DevMinor := Value;\n  FParent.ZipArchive.IsDirty := True;\nend;\n{------------------------------------------------------------------------------}\nfunction  TTarItem.Get_GroupID: Integer;\nbegin\n  result := FOwner.GroupID;\nend;\n{------------------------------------------------------------------------------}\nprocedure TTarItem.Set_GroupID(Value: Integer);\nbegin\n  FOwner.GroupID := Value;\n  FParent.ZipArchive.IsDirty := True;\nend;\n{------------------------------------------------------------------------------}\nfunction  TTarItem.Get_GroupName: WideString;\nbegin\n  result := FOwner.GroupName;\nend;\n{------------------------------------------------------------------------------}\nprocedure TTarItem.Set_GroupName(const Value: WideString);\nbegin\n  FOwner.GroupName := Value;\n  FParent.ZipArchive.IsDirty := True;\nend;\n{------------------------------------------------------------------------------}\nfunction  TTarItem.Get_LinkFlag: Byte;\nbegin\n  result := Byte(FOwner.LinkFlag);\nend;\n{------------------------------------------------------------------------------}\nprocedure TTarItem.Set_LinkFlag(Value: Byte);\nbegin\n  FOwner.LinkFlag := AnsiChar(Value);\n  FParent.ZipArchive.IsDirty := True;\nend;\n{------------------------------------------------------------------------------}\nfunction  TTarItem.Get_LinkName: WideString;\nbegin\n  result := FOwner.LinkName;\nend;\n{------------------------------------------------------------------------------}\nprocedure TTarItem.Set_LinkName(const Value: WideString);\nbegin\n  FOwner.LinkName := Value;\n  FParent.ZipArchive.IsDirty := True;\nend;\n{------------------------------------------------------------------------------}\nfunction  TTarItem.Get_Mode: Integer;\nbegin\n  result := FOwner.Mode;\nend;\n{------------------------------------------------------------------------------}\nprocedure TTarItem.Set_Mode(Value: Integer);\nbegin\n  FOwner.Mode := Value;\n  FParent.ZipArchive.IsDirty := True;\nend;\n{------------------------------------------------------------------------------}\nfunction  TTarItem.Get_UserID: Integer;\nbegin\n  result := FOwner.UserID;\nend;\n{------------------------------------------------------------------------------}\nprocedure TTarItem.Set_UserID(Value: Integer);\nbegin\n  FOwner.UserID := Value;\n  FParent.ZipArchive.IsDirty := True;\nend;\n{------------------------------------------------------------------------------}\nfunction  TTarItem.Get_UserName: WideString;\nbegin\n  result := FOwner.UserName;\nend;\n{------------------------------------------------------------------------------}\nprocedure TTarItem.Set_UserName(const Value: WideString);\nbegin\n  FOwner.UserName := Value;\n  FParent.ZipArchive.IsDirty := True;\nend;\n{------------------------------------------------------------------------------}\n\n\nend.\n"
  },
  {
    "path": "lib/abbrevia/source/COM/_ZipItem.pas",
    "content": "(* ***** BEGIN LICENSE BLOCK *****\n * Version: MPL 1.1\n *\n * The contents of this file are subject to the Mozilla Public License Version\n * 1.1 (the \"License\"); you may not use this file except in compliance with\n * the License. You may obtain a copy of the License at\n * http://www.mozilla.org/MPL/\n *\n * Software distributed under the License is distributed on an \"AS IS\" basis,\n * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License\n * for the specific language governing rights and limitations under the\n * License.\n *\n * The Original Code is TurboPower Abbrevia\n *\n * The Initial Developer of the Original Code is\n * TurboPower Software\n *\n * Portions created by the Initial Developer are Copyright (C) 1997-2002\n * the Initial Developer. All Rights Reserved.\n *\n * Contributor(s):\n *\n * ***** END LICENSE BLOCK ***** *)\n\nunit _ZipItem;\n\ninterface\n\nuses\n  ComObj, Abbrevia_TLB, AbZipTyp, AbZipKit;\n\ntype\n  TZipItem = class(TAutoIntfObject, IZipItem)\n  private\n    FOwner  : TAbZipItem;\n    FParent : TAbZipKit;\n  public\n    constructor Create(AOwner : TAbZipItem; AParent : TAbZipKit);\n  protected\n    {IArchiveItem}\n    function  Get_Action: TArchiveAction; safecall;\n    function  Get_CompressedSize: Integer; safecall;\n    function  Get_CRC32: Integer; safecall;\n    function  Get_CRC32St: WideString; safecall;\n    function  Get_DiskFileName: WideString; safecall;\n    function  Get_DiskPath: WideString; safecall;\n    function  Get_ExternalFileAttributes: TFileAttributes; safecall;\n    procedure Set_ExternalFileAttributes(Value: TFileAttributes); safecall;\n    function  Get_FileName: WideString; safecall;\n    procedure Set_FileName(const Value: WideString); safecall;\n    function  Get_IsEncrypted: WordBool; safecall;\n    function  Get_LastModFileDateTime: TDateTime; safecall;\n    function  Get_StoredPath: WideString; safecall;\n    function  Get_Tagged: WordBool; safecall;\n    procedure Set_Tagged(Value: WordBool); safecall;\n    function  Get_UnCompressedSize: Integer; safecall;\n    function  Get_Password: WideString; safecall;\n    procedure Set_Password(const Value: WideString); safecall;\n\n    {IZipItem}\n    function  Get_CompressionMethod: TZipCompressionMethod; safecall;\n    function  Get_CompressionRatio: Double; safecall;\n    function  Get_DeflateOption: TZipDeflateOption; safecall;\n    function  Get_DictionarySize: TZipDictionarySize; safecall;\n    function  Get_DiskNumberStart: Integer; safecall;\n    function  Get_ExtraField: WideString; safecall;\n    procedure Set_ExtraField(const Value: WideString); safecall;\n    function  Get_FileComment: WideString; safecall;\n    procedure Set_FileComment(const Value: WideString); safecall;\n    function  Get_InternalFileAttributes: Integer; safecall;\n    procedure Set_InternalFileAttributes(Value: Integer); safecall;\n    function  Get_VersionMadeBy: Integer; safecall;\n    function  Get_VersionNeededToExtract: Integer; safecall;\n  end;\n\nimplementation\n\nuses\n  ComServ, SysUtils;\n\n{------------------------------------------------------------------------------}\nconstructor TZipItem.Create(AOwner : TAbZipItem; AParent : TAbZipKit);\nbegin\n  inherited Create(ComServer.TypeLib, IZipItem);\n  FOwner := AOwner;\n  FParent := AParent;\nend;\n{------------------------------------------------------------------------------}\n{IArchiveItem}\n{------------------------------------------------------------------------------}\nfunction  TZipItem.Get_Action: TArchiveAction;\nbegin\n  Result := TArchiveAction(FOwner.Action);\nend;\n{------------------------------------------------------------------------------}\nfunction  TZipItem.Get_CompressedSize: Integer;\nbegin\n  result := FOwner.CompressedSize;\nend;\n{------------------------------------------------------------------------------}\nfunction  TZipItem.Get_CRC32: Integer;\nbegin\n  result := FOwner.CRC32;\nend;\n{------------------------------------------------------------------------------}\nfunction  TZipItem.Get_CRC32St: WideString;\nbegin\n  result := IntToHex(FOwner.CRC32, 8);\nend;\n{------------------------------------------------------------------------------}\nfunction  TZipItem.Get_DiskFileName: WideString;\nbegin\n  result := FOwner.DiskFileName;\nend;\n{------------------------------------------------------------------------------}\nfunction  TZipItem.Get_DiskPath: WideString;\nbegin\n  result := FOwner.DiskPath;\nend;\n{------------------------------------------------------------------------------}\nfunction  TZipItem.Get_ExternalFileAttributes: TFileAttributes;\nbegin\n  result := TFileAttributes(FOwner.ExternalFileAttributes);\nend;\n{------------------------------------------------------------------------------}\nprocedure TZipItem.Set_ExternalFileAttributes(Value: TFileAttributes);\nbegin\n  FOwner.ExternalFileAttributes := LongInt(Value);\n  FParent.ZipArchive.IsDirty := True;\nend;\n{------------------------------------------------------------------------------}\nfunction  TZipItem.Get_FileName: WideString;\nbegin\n  result := FOwner.FileName;\nend;\n{------------------------------------------------------------------------------}\nprocedure TZipItem.Set_FileName(const Value: WideString);\nbegin\n  FOwner.FileName := Value;\nend;\n{------------------------------------------------------------------------------}\nfunction  TZipItem.Get_IsEncrypted: WordBool;\nbegin\n  result := FOwner.IsEncrypted;\nend;\n{------------------------------------------------------------------------------}\nfunction  TZipItem.Get_LastModFileDateTime: TDateTime;\nbegin\n  result := FileDateToDateTime((FOwner.LastModFileDate shl 16) + FOwner.LastModFileTime);\nend;\n{------------------------------------------------------------------------------}\nfunction  TZipItem.Get_StoredPath: WideString;\nbegin\n  result := FOwner.StoredPath;\nend;\n{------------------------------------------------------------------------------}\nfunction  TZipItem.Get_Tagged: WordBool;\nbegin\n  result := FOwner.Tagged;\nend;\n{------------------------------------------------------------------------------}\nprocedure TZipItem.Set_Tagged(Value: WordBool);\nbegin\n  FOwner.Tagged := Value;\nend;\n{------------------------------------------------------------------------------}\nfunction  TZipItem.Get_UnCompressedSize: Integer;\nbegin\n  result := FOwner.UncompressedSize;\nend;\n{------------------------------------------------------------------------------}\nfunction  TZipItem.Get_Password: WideString;\nbegin\n  Result := WideString(FParent.Password);\nend;\n{------------------------------------------------------------------------------}\nprocedure TZipItem.Set_Password(const Value: WideString);\nbegin\n  FParent.Password := AnsiString(Value);\n  FParent.ZipArchive.IsDirty := True;\nend;\n{------------------------------------------------------------------------------}\n{IZipItem}\n{------------------------------------------------------------------------------}\nfunction  TZipItem.Get_CompressionMethod: TZipCompressionMethod;\nbegin\n  Result := TZipCompressionMethod(FOwner.CompressionMethod);\nend;\n{------------------------------------------------------------------------------}\nfunction  TZipItem.Get_CompressionRatio: Double;\nbegin\n  result := FOwner.CompressionRatio;\nend;\n{------------------------------------------------------------------------------}\nfunction  TZipItem.Get_DeflateOption: TZipDeflateOption;\nbegin\n  result := TZipDeflateOption(FOwner.DeflationOption);\nend;\n{------------------------------------------------------------------------------}\nfunction  TZipItem.Get_DictionarySize: TZipDictionarySize;\nbegin\n  result := TZipDictionarySize(FOwner.DictionarySize);\nend;\n{------------------------------------------------------------------------------}\nfunction  TZipItem.Get_DiskNumberStart: Integer;\nbegin\n  result := FOwner.DiskNumberStart;\nend;\n{------------------------------------------------------------------------------}\nfunction  TZipItem.Get_ExtraField: WideString;\nbegin\n  result := '';\nend;\n{------------------------------------------------------------------------------}\nprocedure TZipItem.Set_ExtraField(const Value: WideString);\nbegin\n\nend;\n{------------------------------------------------------------------------------}\nfunction  TZipItem.Get_FileComment: WideString;\nbegin\n  result := WideString(FOwner.FileComment);\nend;\n{------------------------------------------------------------------------------}\nprocedure TZipItem.Set_FileComment(const Value: WideString);\nbegin\n  FOwner.FileComment := AnsiString(Value);\n  FParent.ZipArchive.IsDirty := True;\nend;\n{------------------------------------------------------------------------------}\nfunction  TZipItem.Get_InternalFileAttributes: Integer;\nbegin\n  result := FOwner.InternalFileAttributes;\nend;\n{------------------------------------------------------------------------------}\nprocedure TZipItem.Set_InternalFileAttributes(Value: Integer);\nbegin\n  FOwner.InternalFileAttributes := Value;\n  FParent.ZipArchive.IsDirty := True;\nend;\n{------------------------------------------------------------------------------}\nfunction  TZipItem.Get_VersionMadeBy: Integer;\nbegin\n  result := FOwner.VersionMadeBy;\nend;\n{------------------------------------------------------------------------------}\nfunction  TZipItem.Get_VersionNeededToExtract: Integer;\nbegin\n  result := FOwner.VersionNeededToExtract;\nend;\n{------------------------------------------------------------------------------}\n\n\nend.\n"
  },
  {
    "path": "lib/abbrevia/source/COM/_ZipKit.pas",
    "content": "(* ***** BEGIN LICENSE BLOCK *****\n * Version: MPL 1.1\n *\n * The contents of this file are subject to the Mozilla Public License Version\n * 1.1 (the \"License\"); you may not use this file except in compliance with\n * the License. You may obtain a copy of the License at\n * http://www.mozilla.org/MPL/\n *\n * Software distributed under the License is distributed on an \"AS IS\" basis,\n * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License\n * for the specific language governing rights and limitations under the\n * License.\n *\n * The Original Code is TurboPower Abbrevia\n *\n * The Initial Developer of the Original Code is\n * TurboPower Software\n *\n * Portions created by the Initial Developer are Copyright (C) 1997-2002\n * the Initial Developer. All Rights Reserved.\n *\n * Contributor(s):\n *\n * ***** END LICENSE BLOCK ***** *)\n\nunit _ZipKit;\n\ninterface\n\nuses\n  ComObj, Classes, Windows, Abbrevia_TLB, ActiveX, axctrls, AbZipKit, AbArcTyp,\n  AbUtils, _ZipItem, _GZipItem, _TarItem, AbZipTyp, AbTarTyp, AbGzTyp,\n  AbConst, AbBrowse;\n\ntype\n  {$IFNDEF VER130}{$WARN SYMBOL_PLATFORM OFF}{$ENDIF}\n  TZipKit = class(TAutoObject, IConnectionPointContainer, IEnumVariant, IZipKit)\n  private\n    {private declarations}\n    FConnectionPoints : TConnectionPoints;\n    FEvents           : IZipKitEvents;\n    FOwner            : TAbZipKit;\n    FEnumPos          : Integer;\n\n    {Events for FOwner}\n    procedure _OnArchiveItemProgress(Sender : TObject; Item : TAbArchiveItem; Progress : Byte; var Abort : Boolean);\n    procedure _OnArchiveProgress(Sender : TObject; Progress : Byte; var Abort : Boolean);\n    procedure _OnChange(Sender : TObject);\n    procedure _OnConfirmOverwrite(var Name : string; var confirm : Boolean);\n    procedure _OnConfirmProcessItem(Sender : TObject; Item : TAbArchiveItem; ProcessType : TAbProcessType; var Confirm : Boolean);\n    procedure _OnConfirmSave(Sender : TObject; var Confirm : Boolean);\n    procedure _OnLoad(Sender : TObject);\n    procedure _OnNeedPassword(Sender : TObject; var NewPassword : AnsiString);\n    procedure _OnProcessItemFailure(Sender : TObject; Item : TAbArchiveItem; ProcessType : TAbProcessType; ErrorClass : TAbErrorClass; ErrorCode : Integer);\n    procedure _OnRequestBlankDisk(Sender : TObject; var Abort : Boolean);\n    procedure _OnRequestImage(Sender : TObject; ImageNumber : Integer; var ImageName : string; var Abort : Boolean);\n    procedure _OnRequestLastDisk(Sender : TObject; var Abort : Boolean);\n    procedure _OnRequestNthDisk(Sender : TObject; DiskNumber : Byte; var Abort : Boolean);\n    procedure _OnSave(Sender : TObject);\n\n  public\n    procedure Initialize; override;\n    destructor Destroy; override;\n\n  protected\n\n    {IConnectionPointContainer}\n    property ConnectionPoints: TConnectionPoints read FConnectionPoints\n      implements IConnectionPointContainer;\n    procedure EventSinkChanged(const EventSink: IUnknown); override;\n\n\n    {IEnumVariant}\n    function Next(celt: LongWord; var rgvar : OleVariant; out pceltFetched: LongWord): HResult; stdcall;\n    function Skip(celt: LongWord): HResult; stdcall;\n    function Reset: HResult; stdcall;\n    function Clone(out Enum: IEnumVariant): HResult; stdcall;\n\n\n    {IZipKit}\n    procedure Add(const FileMask: WideString; const ExclusionMask: WideString; SearchAttr: Integer); safecall;\n    procedure AddFromStream(const FileName: WideString; Stream: OleVariant); safecall;\n    function  Get_AutoSave: WordBool; safecall;\n    procedure Set_AutoSave(Value: WordBool); safecall;\n    function  Get_BaseDirectory: WideString; safecall;\n    procedure Set_BaseDirectory(const Value: WideString); safecall;\n    procedure ClearTags; safecall;\n    function  Get_CompressionMethodToUse: TZipSupportMethod; safecall;\n    procedure Set_CompressionMethodToUse(Value: TZipSupportMethod); safecall;\n    function  Get_Count: Integer; safecall;\n    function  Get_DeflateOption: TZipDeflateOption; safecall;\n    procedure Set_DeflateOption(Value: TZipDeflateOption); safecall;\n    procedure Delete(const FileMask: WideString; const ExclusionMask: WideString); safecall;\n    procedure DeleteAt(Index: Integer); safecall;\n    procedure DeleteTaggedItems; safecall;\n    function  Get_DOSMode: WordBool; safecall;\n    procedure Set_DOSMode(Value: WordBool); safecall;\n    procedure Extract(const FileMask: WideString; const ExclusionMask: WideString); safecall;\n    procedure ExtractAt(Index: Integer; const NewName: WideString); safecall;\n    function  Get_ExtractOptions: TZipExtractOptions; safecall;\n    procedure Set_ExtractOptions(Value: TZipExtractOptions); safecall;\n    procedure ExtractTaggedItems; safecall;\n    function  Get_FileName: WideString; safecall;\n    procedure Set_FileName(const Value: WideString); safecall;\n    function  Find(const FileName: WideString): Integer; safecall;\n    procedure Freshen(const FileMask: WideString; const ExclusionMask: WideString); safecall;\n    procedure FreshenTaggedItems; safecall;\n    function  Get_Item(Index: Integer): IDispatch; safecall;\n    function  Get_LogFile: WideString; safecall;\n    procedure Set_LogFile(const Value: WideString); safecall;\n    function  Get_Logging: WordBool; safecall;\n    procedure Set_Logging(Value: WordBool); safecall;\n    function  Get_Password: WideString; safecall;\n    procedure Set_Password(const Value: WideString); safecall;\n    function  Get_PasswordRetries: Byte; safecall;\n    procedure Set_PasswordRetries(Value: Byte); safecall;\n    procedure Replace(const FileMask: WideString); safecall;\n    procedure Save; safecall;\n    function  Get_Spanned: WordBool; safecall;\n    function  Get_SpanningThreshold: Integer; safecall;\n    procedure Set_SpanningThreshold(Value: Integer); safecall;\n    function  Get_Status: TArchiveStatus; safecall;\n    function  Get_StoreOptions: TStoreOptions; safecall;\n    procedure Set_StoreOptions(Value: TStoreOptions); safecall;\n    procedure TagItems(const FileMask: WideString); safecall;\n    function  Get_TempDirectory: WideString; safecall;\n    procedure Set_TempDirectory(const Value: WideString); safecall;\n    procedure TestTaggedItems; safecall;\n    procedure UntagItems(const FileMask: WideString); safecall;\n    function  Get_ZipFileComment: WideString; safecall;\n    procedure Set_ZipFileComment(const Value: WideString); safecall;\n    function  License(const Key: WideString): WordBool; safecall;\n    function  Get__NewEnum: IUnknown; safecall;\n    function ExtractToStream(const FileName: WideString): OleVariant; safecall;\n    function Get_CompressionType: TArchiveType; safecall;\n    procedure Set_CompressionType(Value: TArchiveType); safecall;\n\n    function Get_TarAutoHandle: WordBool; safecall;\n    procedure Set_TarAutoHandle(Value: WordBool); safecall;\n  end;\n\n\nimplementation\n\n\nuses\n  ComServ;\n\n{------------------------------------------------------------------------------}\n{IConnectionPointContainer}\n{------------------------------------------------------------------------------}\nprocedure TZipKit.EventSinkChanged(const EventSink: IUnknown);\nbegin\n  FEvents := EventSink as IZipKitEvents;\nend;\n{------------------------------------------------------------------------------}\n{IEnumVariant}\n{------------------------------------------------------------------------------}\nfunction TZipKit.Next(celt: LongWord; var rgvar : OleVariant; out pceltFetched: LongWord): HResult; stdcall;\nvar\n  V : OleVariant;\n  I : Integer;\nbegin\n  Result := S_FALSE;\n  try\n    if @pceltFetched <> nil then\n      pceltFetched := 0;\n    for I := 0 to celt - 1 do begin\n      if FEnumPos >= FOwner.Count then begin\n        FEnumPos := 0;\n        Exit;\n      end;\n      V := Get_Item(FEnumPos);\n      PVariantArgList(@rgvar)[I] := TVariantArg(V);\n\n      { Prevent COM garbage collection }\n      TVarData(V).VType := varEmpty;\n      TVarData(V).VInteger := 0;\n\n      Inc(FEnumPos);\n      if @pceltFetched <> nil then\n        Inc(pceltFetched);\n    end;\n  except\n  end;\n  if (@pceltFetched = nil) or (pceltFetched = celt) then\n   Result := S_OK;\nend;\n{------------------------------------------------------------------------------}\nfunction TZipKit.Skip(celt: LongWord): HResult;\nbegin\n  Inc(FEnumPos, celt);\n  Result := S_OK;\nend;\n{------------------------------------------------------------------------------}\nfunction TZipKit.Reset: HResult;\nbegin\n  FEnumPos := 0;\n  Result := S_OK;\nend;\n{------------------------------------------------------------------------------}\nfunction TZipKit.Clone(out Enum: IEnumVariant): HResult;\nbegin\n  Enum := nil;\n  Result := S_OK;\n  try\n    Enum := Self.Create;\n    TZipKit(Enum).FOwner := FOwner;\n  except\n    Result := E_OUTOFMEMORY;\n  end;\nend;\n{------------------------------------------------------------------------------}\n{IZipKit}\n{------------------------------------------------------------------------------}\nprocedure TZipKit.Add(const FileMask: WideString; const ExclusionMask: WideString; SearchAttr: Integer);\nbegin\n  FOwner.AddFilesEx(FileMask, ExclusionMask, SearchAttr);\nend;\n{------------------------------------------------------------------------------}\nprocedure TZipKit.AddFromStream(const FileName: WideString; Stream: OleVariant);\nvar\n  InStream : TMemoryStream;\n  Info     : array of Byte;\nbegin\n  Info := nil;\n  InStream := TMemoryStream.Create;\n  try\n    Info := Stream;\n    InStream.Write(Info[0], Length(Info));\n    InStream.Position := 0;\n    FOwner.AddFromStream(FileName, InStream);\n  finally\n    InStream.Free;\n  end;\nend;\n{------------------------------------------------------------------------------}\nfunction  TZipKit.Get_AutoSave: WordBool;\nbegin\n  Result := FOwner.AutoSave;\nend;\n{------------------------------------------------------------------------------}\nprocedure TZipKit.Set_AutoSave(Value: WordBool);\nbegin\n  FOwner.AutoSave := Value;\nend;\n{------------------------------------------------------------------------------}\nfunction  TZipKit.Get_BaseDirectory: WideString;\nbegin\n  Result := FOwner.BaseDirectory;\nend;\n{------------------------------------------------------------------------------}\nprocedure TZipKit.Set_BaseDirectory(const Value: WideString);\nbegin\n  FOwner.BaseDirectory := Value;\nend;\n{------------------------------------------------------------------------------}\nprocedure TZipKit.ClearTags;\nbegin\n  FOwner.ClearTags;\nend;\n{------------------------------------------------------------------------------}\nfunction  TZipKit.Get_CompressionMethodToUse: TZipSupportMethod;\nbegin\n  Result := TZipCompressionMethod(FOwner.CompressionMethodToUse);\nend;\n{------------------------------------------------------------------------------}\nprocedure TZipKit.Set_CompressionMethodToUse(Value: TZipSupportMethod);\nbegin\n  FOwner.CompressionMethodToUse := TAbZipSupportedMethod(Value);\nend;\n{------------------------------------------------------------------------------}\nfunction  TZipKit.Get_Count: Integer;\nbegin\n  Result := FOwner.Count;\nend;\n{------------------------------------------------------------------------------}\nfunction  TZipKit.Get_DeflateOption: TZipDeflateOption;\nbegin\n  Result := TZipDeflateOption(FOwner.DeflationOption);\nend;\n{------------------------------------------------------------------------------}\nprocedure TZipKit.Set_DeflateOption(Value: TZipDeflateOption);\nbegin\n  FOwner.DeflationOption := TAbZipDeflationOption(Value);\nend;\n{------------------------------------------------------------------------------}\nprocedure TZipKit.Delete(const FileMask: WideString; const ExclusionMask: WideString);\nbegin\n  FOwner.DeleteFilesEx(FileMask, ExclusionMask);\nend;\n{------------------------------------------------------------------------------}\nprocedure TZipKit.DeleteAt(Index: Integer);\nbegin\n  FOwner.DeleteAt(Index);\nend;\n{------------------------------------------------------------------------------}\nprocedure TZipKit.DeleteTaggedItems;\nbegin\n  FOwner.DeleteTaggedItems;\nend;\n{------------------------------------------------------------------------------}\nfunction  TZipKit.Get_DOSMode: WordBool;\nbegin\n  Result := FOwner.DOSMode;\nend;\n{------------------------------------------------------------------------------}\nprocedure TZipKit.Set_DOSMode(Value: WordBool);\nbegin\n  FOwner.DOSMode := Value;\nend;\n{------------------------------------------------------------------------------}\nprocedure TZipKit.Extract(const FileMask: WideString; const ExclusionMask: WideString);\nbegin\n  FOwner.ExtractFilesEx(FileMask, ExclusionMask);\nend;\n{------------------------------------------------------------------------------}\nprocedure TZipKit.ExtractAt(Index: Integer; const NewName: WideString);\nbegin\n  FOwner.ExtractAt(Index, NewName);\nend;\n{------------------------------------------------------------------------------}\nfunction  TZipKit.Get_ExtractOptions: TZipExtractOptions;\nbegin\n  Result := 0;\n  if TAbExtractOption(eoCreateDirs) in FOwner.ExtractOptions then\n    Result := Result + TZipExtractOptions(eoCreateDirs);\n  if TAbExtractOption(eoRestorePath) in FOwner.ExtractOptions then\n    Result := Result + TZipExtractOptions(eoRestorePath);\nend;\n{------------------------------------------------------------------------------}\nprocedure TZipKit.Set_ExtractOptions(Value: TZipExtractOptions);\nvar\n  TempOptions : TAbExtractOptions;\nbegin\n  TempOptions := [];\n  if (Value or Abbrevia_TLB.eoCreateDirs) = Value then\n    Include(TempOptions, AbArcTyp.eoCreateDirs);\n  if (Value or Abbrevia_TLB.eoRestorePath) = Value then\n    Include(TempOptions, AbArcTyp.eoRestorePath);\n  FOwner.ExtractOptions := TempOptions\nend;\n{------------------------------------------------------------------------------}\nprocedure TZipKit.ExtractTaggedItems;\nbegin\n  FOwner.ExtractTaggedItems;\nend;\n{------------------------------------------------------------------------------}\nfunction  TZipKit.Get_FileName: WideString;\nbegin\n  Result := FOwner.FileName;\nend;\n{------------------------------------------------------------------------------}\nprocedure TZipKit.Set_FileName(const Value: WideString);\nbegin\n  FOwner.FileName := Value;\nend;\n{------------------------------------------------------------------------------}\nfunction  TZipKit.Find(const FileName: WideString): Integer;\nbegin\n  Result := FOwner.FindFile(FileName);\nend;\n{------------------------------------------------------------------------------}\nprocedure TZipKit.Freshen(const FileMask: WideString; const ExclusionMask: WideString);\nbegin\n  FOwner.FreshenFilesEx(FileMask, ExclusionMask);\nend;\n{------------------------------------------------------------------------------}\nprocedure TZipKit.FreshenTaggedItems;\nbegin\n  FOwner.FreshenTaggedItems;\nend;\n{------------------------------------------------------------------------------}\nfunction  TZipKit.Get_Item(Index: Integer): IDispatch;\nbegin\n  Result := TZipItem.Create(FOwner.Items[Index], FOwner);\nend;\n{------------------------------------------------------------------------------}\nfunction  TZipKit.Get_LogFile: WideString;\nbegin\n  Result := FOwner.LogFile;\nend;\n{------------------------------------------------------------------------------}\nprocedure TZipKit.Set_LogFile(const Value: WideString);\nbegin\n  FOwner.LogFile := Value;\nend;\n{------------------------------------------------------------------------------}\nfunction  TZipKit.Get_Logging: WordBool;\nbegin\n  Result := FOwner.Logging;\nend;\n{------------------------------------------------------------------------------}\nprocedure TZipKit.Set_Logging(Value: WordBool);\nbegin\n  FOwner.Logging := Value;\nend;\n{------------------------------------------------------------------------------}\nfunction  TZipKit.Get_Password: WideString;\nbegin\n  Result := WideString(FOwner.Password);\nend;\n{------------------------------------------------------------------------------}\nprocedure TZipKit.Set_Password(const Value: WideString);\nbegin\n  FOwner.Password := AnsiString(Value);\nend;\n{------------------------------------------------------------------------------}\nfunction  TZipKit.Get_PasswordRetries: Byte;\nbegin\n  Result := FOwner.PasswordRetries;\nend;\n{------------------------------------------------------------------------------}\nprocedure TZipKit.Set_PasswordRetries(Value: Byte);\nbegin\n  FOwner.PasswordRetries := Value;\nend;\n{------------------------------------------------------------------------------}\nprocedure TZipKit.Replace(const FileMask: WideString);\nbegin\n  FOwner.Replace(FOwner.Items[FOwner.FindFile(FileMask)]);\nend;\n{------------------------------------------------------------------------------}\nprocedure TZipKit.Save;\nbegin\n  FOwner.Save;\nend;\n{------------------------------------------------------------------------------}\nfunction  TZipKit.Get_Spanned: WordBool;\nbegin\n  Result := FOwner.Spanned;\nend;\n{------------------------------------------------------------------------------}\nfunction  TZipKit.Get_SpanningThreshold: Integer;\nbegin\n  Result := FOwner.SpanningThreshold;\nend;\n{------------------------------------------------------------------------------}\nprocedure TZipKit.Set_SpanningThreshold(Value: Integer);\nbegin\n  FOwner.SpanningThreshold := Value;\nend;\n{------------------------------------------------------------------------------}\nfunction  TZipKit.Get_Status: TArchiveStatus;\nbegin\n  Result := TArchiveStatus(FOwner.Status);\nend;\n{------------------------------------------------------------------------------}\nfunction  TZipKit.Get_StoreOptions: TStoreOptions;\nbegin\n  Result := 0;\n  if TAbStoreOption(soStripDrive) in FOwner.StoreOptions then\n    Result := Result + TStoreOptions(soStripDrive);\n  if TAbStoreOption(soStripPath) in FOwner.StoreOptions then\n    Result := Result + TStoreOptions(soStripPath);\n  if TAbStoreOption(soRemoveDots) in FOwner.StoreOptions then\n    Result := Result + TStoreOptions(soRemoveDots);\n  if TAbStoreOption(soRecurse) in FOwner.StoreOptions then\n    Result := Result + TStoreOptions(soRecurse);\n  if TAbStoreOption(soFreshen) in FOwner.StoreOptions then\n    Result := Result + TStoreOptions(soFreshen);\n  if TAbStoreOption(soReplace) in FOwner.StoreOptions then\n    Result := Result + TStoreOptions(soReplace);\nend;\n{------------------------------------------------------------------------------}\nprocedure TZipKit.Set_StoreOptions(Value: TStoreOptions);\nvar\n  TempOptions : TAbStoreOptions;\nbegin\n  TempOptions := [];\n  if (Value or Abbrevia_TLB.soStripDrive) = Value then\n    Include(TempOptions, AbArcTyp.soStripDrive);\n  if (Value or Abbrevia_TLB.soStripPath) = Value then\n    Include(TempOptions, AbArcTyp.soStripPath);\n  if (Value or Abbrevia_TLB.soRemoveDots) = Value then\n    Include(TempOptions, AbArcTyp.soRemoveDots);\n  if (Value or Abbrevia_TLB.soRecurse) = Value then\n    Include(TempOptions, AbArcTyp.soRecurse);\n  if (Value or Abbrevia_TLB.soFreshen) = Value then\n    Include(TempOptions, AbArcTyp.soFreshen);\n  if (Value or Abbrevia_TLB.soReplace) = Value then\n    Include(TempOptions, AbArcTyp.soReplace);\n  FOwner.StoreOptions := TempOptions\nend;\n{------------------------------------------------------------------------------}\nprocedure TZipKit.TagItems(const FileMask: WideString);\nbegin\n  FOwner.TagItems(FileMask);\nend;\n{------------------------------------------------------------------------------}\nfunction  TZipKit.Get_TempDirectory: WideString;\nbegin\n  Result := FOwner.TempDirectory;\nend;\n{------------------------------------------------------------------------------}\nprocedure TZipKit.Set_TempDirectory(const Value: WideString);\nbegin\n  FOwner.TempDirectory := Value;\nend;\n{------------------------------------------------------------------------------}\nprocedure TZipKit.TestTaggedItems;\nbegin\n  FOwner.TestTaggedItems;\nend;\n{------------------------------------------------------------------------------}\nprocedure TZipKit.UntagItems(const FileMask: WideString);\nbegin\n  FOwner.UnTagItems(FileMask);\nend;\n{------------------------------------------------------------------------------}\nfunction  TZipKit.Get_ZipFileComment: WideString;\nbegin\n  Result := WideString(FOwner.ZipFileComment);\nend;\n{------------------------------------------------------------------------------}\nprocedure TZipKit.Set_ZipFileComment(const Value: WideString);\nbegin\n  FOwner.ZipfileComment := AnsiString(Value);\nend;\n{------------------------------------------------------------------------------}\nfunction  TZipKit.License(const Key: WideString): WordBool;\nbegin\n  Result := True;\nend;\n{------------------------------------------------------------------------------}\nfunction  TZipKit.Get__NewEnum: IUnknown;\nbegin\n  Result := Self;\nend;\n{------------------------------------------------------------------------------}\nfunction TZipKit.ExtractToStream(const FileName: WideString): OleVariant;\nvar\n  Stream : TMemoryStream;\n  Info : array of Byte;\nbegin\n  Stream := TMemoryStream.Create;\n  try\n    FOwner.ExtractToStream(FileName, Stream);\n    Stream.Position := 0;\n    SetLength(Info, Stream.Size);\n    Stream.Read(Info[0], Stream.Size);\n    Result := Info;\n  finally\n    Stream.Free;\n  end;\nend;\n{------------------------------------------------------------------------------}\nfunction TZipKit.Get_CompressionType: TArchiveType;\nbegin\n  Result := TArchiveType((FOwner as TAbBaseBrowser).ArchiveType);\nend;\n{------------------------------------------------------------------------------}\nprocedure TZipKit.Set_CompressionType(Value: TArchiveType);\nbegin\n  (FOwner as TAbBaseBrowser).ArchiveType := TAbArchiveType(ord(Value));\nend;\n{------------------------------------------------------------------------------}\nfunction TZipKit.Get_TarAutoHandle: WordBool;\nbegin\n  Result := FOwner.TarAutoHandle;\nend;\n{------------------------------------------------------------------------------}\nprocedure TZipKit.Set_TarAutoHandle(Value: WordBool);\nbegin\n  FOwner.TarAutoHandle := Value;\nend;\n{------------------------------------------------------------------------------}\n{TZipKit Events}\n{------------------------------------------------------------------------------}\nprocedure TZipKit._OnArchiveItemProgress(Sender : TObject; Item : TAbArchiveItem;\n                   Progress : Byte; var Abort : Boolean);\nvar\n  FAbort : WordBool;\nbegin\n  FAbort := Abort;\n  if Assigned(FEvents) then begin\n    if ((FOwner as TAbBaseBrowser).ArchiveType = atZip) then\n      FEvents.OnArchiveItemProgress(TZipItem.Create(TAbZipItem(Item), FOwner),\n              Progress, FAbort)\n    else if ((FOwner as TAbBaseBrowser).ArchiveType = atTar) then\n      FEvents.OnArchiveItemProgress(TTarItem.Create(TAbTarItem(Item), FOwner),\n              Progress, FAbort)\n    else if ((FOwner as TAbBaseBrowser).ArchiveType = atGZip) then\n      FEvents.OnArchiveItemProgress(TGZipItem.Create(TAbGZipItem(Item), FOwner),\n              Progress, FAbort);\n  end;\n  Abort := FAbort;\nend;\n{------------------------------------------------------------------------------}\nprocedure TZipKit._OnArchiveProgress(Sender : TObject; Progress : Byte;\n                   var Abort : Boolean);\nvar\n  FAbort : WordBool;\nbegin\n  FAbort := Abort;\n  if Assigned(FEvents) then\n    FEvents.OnArchiveProgress(Progress, FAbort);\n  Abort := FAbort;\nend;\n{------------------------------------------------------------------------------}\nprocedure TZipKit._OnChange(Sender : TObject);\nbegin\n  if Assigned(FEvents) then\n    FEvents.OnChange;\nend;\n{------------------------------------------------------------------------------}\nprocedure TZipKit._OnConfirmOverwrite(var Name : string; var confirm : Boolean);\nvar\n  FConfirm : WordBool;\n  FName    : WideString;\nbegin\n  FConfirm := Confirm;\n  FName    := Name;\n  if Assigned(FEvents) then\n    FEvents.OnConfirmOverwrite(FName, FConfirm);\n  Name    := FName;\n  Confirm := FConfirm;\nend;\n{------------------------------------------------------------------------------}\nprocedure TZipKit._OnConfirmProcessItem(Sender : TObject; Item : TAbArchiveItem;\n                   ProcessType : TAbProcessType; var Confirm : Boolean);\nvar\n  FConfirm : WordBool;\nbegin\n  FConfirm := Confirm;\n  if Assigned(FEvents) then begin\n    if ((FOwner as TAbBaseBrowser).ArchiveType = atZip) then\n      FEvents.OnConfirmProcessItem(TZipItem.Create(TAbZipItem(Item), FOwner),\n              TProcessType(ProcessType), FConfirm)\n    else if ((FOwner as TAbBaseBrowser).ArchiveType = atTar) then\n      FEvents.OnConfirmProcessItem(TTarItem.Create(TAbTarItem(Item), FOwner),\n              TProcessType(ProcessType), FConfirm)\n    else if ((FOwner as TAbBaseBrowser).ArchiveType = atGZip) then\n      FEvents.OnConfirmProcessItem(TGZipItem.Create(TAbGZipItem(Item), FOwner),\n              TProcessType(ProcessType), FConfirm);\n  end;\n  Confirm := FConfirm\nend;\n{------------------------------------------------------------------------------}\nprocedure TZipKit._OnConfirmSave(Sender : TObject; var Confirm : Boolean);\nvar\n  FConfirm : WordBool;\nbegin\n  FConfirm := Confirm;\n  if Assigned(FEvents) then\n    FEvents.OnConfirmSave(FConfirm);\n  Confirm := FConfirm;\nend;\n{------------------------------------------------------------------------------}\nprocedure TZipKit._OnLoad(Sender : TObject);\nbegin\n  if Assigned(FEvents) then\n    FEvents.OnLoad;\nend;\n{------------------------------------------------------------------------------}\nprocedure TZipKit._OnNeedPassword(Sender : TObject; var NewPassword : AnsiString);\nvar\n  FNewPassword : WideString;\nbegin\n  FNewPassword := WideString(NewPassword);\n  if Assigned(FEvents) then\n    FEvents.OnNeedPassword(FNewPassword);\n  NewPassword := AnsiString(FNewPassword);\nend;\n{------------------------------------------------------------------------------}\nprocedure TZipKit._OnProcessItemFailure(Sender : TObject; Item : TAbArchiveItem;\n                   ProcessType : TAbProcessType; ErrorClass : TAbErrorClass;\n                   ErrorCode : Integer);\nbegin\n  if Assigned(FEvents) then begin\n    if ((FOwner as TAbBaseBrowser).ArchiveType = atZip) then\n      FEvents.OnProcessItemFailure(TZipItem.Create(TAbZipItem(Item), FOwner),\n              TProcessType(ProcessType), TErrorClass(ErrorClass),\n              TErrorCode(ErrorCode), AbStrRes(ErrorCode))\n    else if ((FOwner as TAbBaseBrowser).ArchiveType = atTar) then\n      FEvents.OnProcessItemFailure(TTarItem.Create(TAbTarItem(Item), FOwner),\n              TProcessType(ProcessType), TErrorClass(ErrorClass),\n              TErrorCode(ErrorCode),AbStrRes(ErrorCode))\n    else if ((FOwner as TAbBaseBrowser).ArchiveType = atGZip) then\n      FEvents.OnProcessItemFailure(TGZipItem.Create(TAbGZipItem(Item), FOwner),\n              TProcessType(ProcessType),  TErrorClass(ErrorClass),\n              TErrorCode(ErrorCode),AbStrRes(ErrorCode));\n  end;\nend;\n{------------------------------------------------------------------------------}\nprocedure TZipKit._OnRequestBlankDisk(Sender : TObject; var Abort : Boolean);\nvar\n  FAbort : WordBool;\nbegin\n  FAbort := Abort;\n  if Assigned(FEvents) then\n    FEvents.OnRequestBlankDisk(FAbort);\n  Abort := FAbort;\nend;\n{------------------------------------------------------------------------------}\nprocedure TZipKit._OnRequestImage(Sender : TObject; ImageNumber : Integer; var ImageName : string; var Abort : Boolean);\nvar\n  FImageName : WideString;\n  FAbort     : WordBool;\nbegin\n  FImageName := ImageName;\n  FAbort := Abort;\n  if Assigned(FEvents) then\n    FEvents.OnRequestImage(ImageNumber, FImageName, FAbort);\n  Abort := FAbort;\n  ImageName := FImageName;\nend;\n{------------------------------------------------------------------------------}\nprocedure TZipKit._OnRequestLastDisk(Sender : TObject; var Abort : Boolean);\nvar\n  FAbort : WordBool;\nbegin\n  FAbort := Abort;\n  if Assigned(FEvents) then\n    FEvents.OnRequestLastDisk(FAbort);\n  Abort := FAbort;\nend;\n{------------------------------------------------------------------------------}\nprocedure TZipKit._OnRequestNthDisk(Sender : TObject; DiskNumber : Byte; var Abort : Boolean);\nvar\n  FAbort : WordBool;\nbegin\n  FAbort := Abort;\n  if Assigned(FEvents) then\n    FEvents.OnRequestNthDisk(DiskNumber, FAbort);\n  Abort := FAbort;\nend;\n{------------------------------------------------------------------------------}\nprocedure TZipKit._OnSave(Sender : TObject);\nbegin\n  if Assigned(FEvents) then\n    FEvents.OnSave;\nend;\n{------------------------------------------------------------------------------}\nprocedure TZipKit.Initialize;\nbegin\n  inherited Initialize;\n  FConnectionPoints := TConnectionPoints.Create(Self);\n  if AutoFactory.EventTypeInfo <> nil then\n    FConnectionPoints.CreateConnectionPoint(AutoFactory.EventIID,\n      ckSingle, EventConnect);\n  FOwner := AbZipKit.TAbZipKit.Create(nil);\n  FOwner.OnArchiveItemProgress := _OnArchiveItemProgress;\n  FOwner.OnArchiveProgress     := _OnArchiveProgress;\n  FOwner.OnChange              := _OnChange;\n  FOwner.OnConfirmOverwrite    := _OnConfirmOverwrite;\n  FOwner.OnConfirmProcessItem  := _OnConfirmProcessItem;\n  FOwner.OnConfirmSave         := _OnConfirmSave;\n  FOwner.OnLoad                := _OnLoad;\n  FOwner.OnNeedPassword        := _OnNeedPassword;\n  FOwner.OnProcessItemFailure  := _OnProcessItemFailure;\n  FOwner.OnRequestBlankDisk    := _OnRequestBlankDisk;\n  FOwner.OnRequestImage        := _OnRequestImage;\n  FOwner.OnRequestLastDisk     := _OnRequestLastDisk;\n  FOwner.OnRequestNthDisk      := _OnRequestNthDisk;\n  FOwner.OnSave                := _OnSave;\n  FEnumPos := 0;\nend;\n{------------------------------------------------------------------------------}\ndestructor TZipKit.Destroy;\nbegin\n  FOwner.Free;\n  inherited Destroy;\nend;\n{------------------------------------------------------------------------------}\n\ninitialization\n  TAutoObjectFactory.Create(ComServer, TZipKit, Class_ZipKit, ciMultiInstance, tmBoth);\n\n\nend.\n"
  },
  {
    "path": "lib/mte/CRC32.pas",
    "content": "unit CRC32;\n\ninterface\ntype\n  Long = record\n    LoWord: Word;\n    HiWord: Word;\n  end;\n\n  // exported functions\n  function FileCRC32(FileName: string): string;\n  function StrCRC32(input: string): string;\n\nconst\n  CRCPOLY = $EDB88320;\n\nvar\n  CRCTable: array[0..512] Of Longint;\n\nimplementation\n{$WARNINGS OFF}\n\nuses\n  SysUtils;\n\nprocedure BuildCRCTable;\nvar\n  i, j: Word;\n  r: Longint;\nbegin\n  FillChar(CRCTable, SizeOf(CRCTable), 0);\n  for i := 0 to 255 do\n  begin\n    r := i shl 1;\n    for j := 8 downto 0 do\n      if (r and 1) <> 0 then\n        r := (r Shr 1) xor CRCPOLY\n      else\n        r := r shr 1;\n    CRCTable[i] := r;\n   end;\nend;\n\nfunction RecountCRC(b: byte; CrcOld: Longint): Longint;\nbegin\n  RecountCRC := CRCTable[byte(CrcOld xor Longint(b))] xor ((CrcOld shr 8) and $00FFFFFF)\nend;\n\nfunction HextW(w: Word): string;\nconst\n  h: array[0..15] Of char = '0123456789ABCDEF';\nbegin\n  HextW := '';\n  HextW := h[Hi(w) shr 4] + h[Hi(w) and $F] + h[Lo(w) shr 4]+h[Lo(w) and $F];\nend;\n\nfunction HextL(l: Longint): string;\nbegin\n  with Long(l) do\n    HextL := HextW(HiWord) + HextW(LoWord);\nend;\n\nfunction FileCRC32(FileName: string): string;\nvar\n  Buffer: PChar;\n  F: File of Byte;\n  B: array[0..255] of Byte;\n  CRC: Longint;\n  e, i: Integer;\nbegin\n  BuildCRCTable;\n  CRC := $FFFFFFFF;\n  AssignFile(F, FileName);\n  FileMode := 0;\n  Reset(F);\n  GetMem(Buffer, SizeOf(B));\n  repeat\n    FillChar(B, SizeOf(B), 0);\n    BlockRead(F, B, SizeOf(B), e);\n    for i := 0 to (e-1) do\n      CRC := RecountCRC(b[i], CRC);\n  until (e < 255) or (IOresult <> 0);\n  FreeMem(Buffer, SizeOf(B));\n  CloseFile(F);\n  CRC := Not CRC;\n  Result := HextL(CRC);\nend;\n\nfunction StrCRC32(input: string): string;\nvar\n  B: TArray<Byte>;\n  CRC: Longint;\n  i: Integer;\nbegin\n  BuildCRCTable;\n  CRC := $FFFFFFFF;\n  B := TEncoding.UTF8.GetBytes(input);\n  for i := 0 to Pred(Length(B)) do\n    CRC := RecountCRC(B[i], CRC);\n  CRC := Not CRC;\n  Result := HextL(CRC);\nend;\n\nend.\n"
  },
  {
    "path": "lib/mte/RttiIni.pas",
    "content": "unit RttiIni;\n\ninterface\n\nuses\n  SysUtils, Classes, Rtti, TypInfo, IniFiles;\n\ntype\n  IniSectionAttribute = class(TCustomAttribute)\n  private\n    FSection: string;\n  public\n    constructor Create(const aSection: String);\n    property Section: string read FSection write FSection;\n  end;\n\n  TRttiIni = class (TObject)\n  private\n    class function ReadValue(section: string; var ini: TMemIniFile;\n      field: TRttiField): TValue;\n    class procedure WriteValue(section: string; var ini: TMemIniFile;\n      field: TRttiField; aValue: TValue);\n    class function GetIniAttribute(Obj: TRttiObject): IniSectionAttribute;\n  public\n    class procedure Load(filename: string; obj: TObject);\n    class procedure Save(filename: string; obj: TObject);\n  end;\n\nimplementation\n\n{ TIniSection }\nconstructor IniSectionAttribute.Create(const aSection: String);\nbegin\n  FSection := aSection;\nend;\n\n{ TIniPersist }\nclass function TRttiIni.GetIniAttribute(Obj: TRttiObject): IniSectionAttribute;\nvar\n Attr: TCustomAttribute;\nbegin\n  for Attr in Obj.GetAttributes do begin\n    if Attr is IniSectionAttribute then\n      exit(IniSectionAttribute(Attr));\n  end;\n  result := nil;\nend;\n\nclass procedure TRttiIni.Load(filename: string; obj: TObject);\nvar\n  ctx: TRttiContext;\n  objType: TRttiType;\n  Field: TRttiField;\n  IniSection: IniSectionAttribute;\n  Ini: TMemIniFile;\n  CurrentSection: string;\n  value: TValue;\nbegin\n  ctx := TRttiContext.Create;\n  try\n    Ini := TMemIniFile.Create(FileName);\n    try\n      objType := ctx.GetType(Obj.ClassInfo);\n      for Field in objType.GetFields do begin\n        IniSection := GetIniAttribute(Field);\n        if Assigned(IniSection) then\n          CurrentSection := IniSection.Section;\n        value := ReadValue(CurrentSection, ini, Field);\n        if not value.IsEmpty then\n           field.SetValue(obj, value);\n      end;\n    finally\n      Ini.Free;\n    end;\n  finally\n    ctx.Free;\n  end;\nend;\n\nclass function TRttiIni.ReadValue(section: string; var ini: TMemIniFile;\n  field: TRttiField): TValue;\nvar\n  fieldType: string;\nbegin\n  Result := TValue.Empty;\n  fieldType := field.FieldType.Name;\n\n  // exit if value doesn't exist in ini being loaded\n  // this allows us to use default values from the object's constructor\n  if not ini.ValueExists(section, field.Name) then\n    exit;\n\n  // load string, Integer, and Boolean fields from ini\n  if fieldType = 'string' then\n    Result := TValue.From(ini.ReadString(section, field.Name, ''))\n  else if fieldType = 'Integer' then\n    Result := TValue.From(ini.ReadInteger(section, field.Name, 0))\n  else if fieldType = 'Int64' then\n    Result := TValue.From(ini.ReadInteger(section, field.Name, 0))\n  else if fieldType = 'TDateTime' then\n    Result := TValue.From(ini.ReadFloat(section, field.Name, 0))\n  else if fieldType = 'Boolean' then\n    Result := TValue.From(ini.ReadBool(section, field.Name, false));\nend;\n\nclass procedure TRttiIni.WriteValue(section: string; var ini: TMemIniFile;\n  field: TRttiField; aValue: TValue);\nvar\n  fieldType: string;\nbegin\n  fieldType := field.FieldType.Name;\n  if fieldType = 'string' then\n    ini.WriteString(section, field.Name, aValue.AsString)\n  else if fieldType = 'Integer' then\n    ini.WriteInteger(section, field.Name, aValue.AsInteger)\n  else if fieldType = 'Int64' then\n    ini.WriteInteger(section, field.Name, aValue.AsInt64)\n  else if fieldType = 'TDateTime' then\n    ini.WriteFloat(section, field.Name, aValue.AsType<TDateTime>)\n  else if fieldType = 'Boolean' then\n    ini.WriteBool(section, field.Name, aValue.AsBoolean)\nend;\n\nclass procedure TRttiIni.Save(filename: string; obj: TObject);\nvar\n ctx: TRttiContext;\n objType: TRttiType;\n field: TRttiField;\n IniSection: IniSectionAttribute;\n ini: TMemIniFile;\n CurrentSection: string;\nbegin\n  ctx := TRttiContext.Create;\n  try\n    ini := TMemIniFile.Create(FileName);\n    try\n      objType := ctx.GetType(Obj.ClassInfo);\n      for field in objType.GetFields do begin\n        IniSection := GetIniAttribute(Field);\n        if Assigned(IniSection) then\n          CurrentSection := IniSection.Section;\n        WriteValue(CurrentSection, ini, field, Field.GetValue(obj));\n      end;\n    finally\n      Ini.UpdateFile;\n      Ini.Free;\n    end;\n  finally\n    ctx.Free;\n  end;\nend;\n\nend.\n"
  },
  {
    "path": "lib/mte/RttiJson.pas",
    "content": "unit RttiJson;\n\ninterface\n\nuses\n  SysUtils, Rtti,\n  // superobject json library\n  superobject;\n  \ntype\n  TRttiJson = class (TObject)\n  public\n    class function ToJson(obj: TObject): string;\n    class function FromJson(json: string; classType: TClass): TObject;\n  end;\n\nimplementation\n\nclass function TRttiJson.ToJson(obj: TObject): string;\nvar\n  rtype: TRTTIType;\n  field: TRTTIField;\n  fieldType: string;\n  jsonObj: ISuperObject;\n  date: TDateTime;\nbegin\n  jsonObj := SO;\n  rtype := TRTTIContext.Create.GetType(obj.ClassType);\n\n  // loop through fields\n  for field in rType.GetFields do begin\n    fieldType := field.FieldType.ToString;\n    // handle datatypes I use\n    if (fieldType = 'string') then\n      jsonObj.S[field.Name] := field.GetValue(obj).ToString\n    else if (fieldType = 'Integer') then\n      jsonObj.I[field.Name] := field.GetValue(obj).AsInteger\n    else if (fieldType = 'TDateTime') then begin\n      date := StrToFloat(field.GetValue(obj).ToString);\n      jsonObj.S[field.Name] := DateTimeToStr(date);\n    end;\n  end;\n\n  Result := jsonObj.AsJSon;\nend;\n\n{\n  Example usage:\n  report := TReport(FromJson(reportJson, TReport));\n}\nclass function TRttiJson.FromJson(json: string; classType: TClass): TObject;\nvar\n  rtype: TRTTIType;\n  field: TRTTIField;\n  fieldType: string;\n  context: TRTTIContext;\n  jsonObj: ISuperObject;\n  date: TDateTime;\nbegin\n  jsonObj := SO(PChar(json));\n  context := TRTTIContext.Create;\n  rtype := context.GetType(classType);\n  Result := classType.Create;\n\n  // loop through fields\n  for field in rType.GetFields do begin\n    fieldType := field.FieldType.ToString;\n    // handle datatypes I use\n    if (fieldType = 'string') then\n      field.SetValue(Result, jsonObj.S[field.Name])\n    else if (fieldType = 'Integer') then\n      field.SetValue(Result, jsonObj.I[field.Name])\n    else if (fieldType = 'TDateTime') then begin\n      date := StrToDateTime(jsonObj.S[field.Name]);\n      field.SetValue(Result, TValue.From<TDateTime>(date));\n    end;\n  end;\n\n  context.Free;\nend;\n\nend."
  },
  {
    "path": "lib/mte/RttiTranslation.pas",
    "content": "unit RttiTranslation;\n\ninterface\n\nuses\n  SysUtils, Classes, StdCtrls, ComCtrls, Buttons, Menus, Rtti, TypInfo;\n\ntype\n  FormPrefixAttribute = class(TCustomAttribute)\n  private\n    FPrefix: string;\n  public\n    constructor Create(const aPrefix: String);\n    property Prefix: string read FPrefix write FPrefix;\n  end;\n\n  FormSectionAttribute = class(TCustomAttribute)\n  private\n    FSection: string;\n  public\n    constructor Create(const aSection: String);\n    property Section: string read FSection write FSection;\n  end;\n\n  TRttiTranslation = class (TObject)\n  private\n    class function ReadValue(section: string; var sl: TStringList;\n      field: TRttiField; subfield: string): string;\n    class procedure WriteValue(section: string; value: string; var sl: TStringList;\n      field: TRttiField; subfield: string);\n    class function GetPrefixAttribute(Obj: TRttiObject): FormPrefixAttribute;\n    class function GetSectionAttribute(Obj: TRttiObject): FormSectionAttribute;\n  public\n    class procedure Load(filename: string; obj: TObject); overload;\n    class procedure Load(var sl: TStringList; obj: TObject); overload;\n    class procedure Save(filename: string; obj: TObject);\n  end;\n\nimplementation\n\n{ FormPrefixAttribute }\nconstructor FormPrefixAttribute.Create(const aPrefix: String);\nbegin\n  FPrefix := aPrefix;\nend;\n\n{ FormSectionAttribute }\nconstructor FormSectionAttribute.Create(const aSection: String);\nbegin\n  FSection := aSection;\nend;\n\n{ TRttiTranslation }\nclass function TRttiTranslation.GetPrefixAttribute(Obj: TRttiObject): FormPrefixAttribute;\nvar\n  Attr: TCustomAttribute;\nbegin\n  for Attr in Obj.GetAttributes do begin\n    if Attr is FormPrefixAttribute then\n      exit(FormPrefixAttribute(Attr));\n  end;\n  result := nil;\nend;\n\nclass function TRttiTranslation.GetSectionAttribute(Obj: TRttiObject): FormSectionAttribute;\nvar\n  Attr: TCustomAttribute;\nbegin\n  for Attr in Obj.GetAttributes do begin\n    if Attr is FormSectionAttribute then\n      exit(FormSectionAttribute(Attr));\n  end;\n  result := nil;\nend;\n\nclass procedure TRttiTranslation.Load(filename: string; obj: TObject);\nvar\n  sl: TStringList;\nbegin\n  sl := TStringList.Create;\n  try\n    sl.LoadFromFile(filename);\n    TRttiTranslation.Load(sl, obj);\n  finally\n    sl.Free;\n  end;\nend;\n\nclass procedure TRttiTranslation.Load(var sl: TStringList; obj: TObject);\nvar\n  ctx: TRttiContext;\n  objType: TRttiType;\n  Field: TRttiField;\n  FormPrefix: FormPrefixAttribute;\n  FormSection: FormSectionAttribute;\n  CurrentPrefix, CurrentSection, FieldName, value: string;\n  aCheckBox: TCheckBox;\n  aButton: TButton;\n  aLabel: TLabel;\n  aTabSheet: TTabSheet;\n  aGroupBox: TGroupBox;\n  aSpeedButton: TSpeedButton;\n  aMenuItem: TMenuItem;\n  aComboBox: TComboBox;\n  aListView: TListView;\n  i: Integer;\nbegin\n  FormPrefix := nil;\n  ctx := TRttiContext.Create;\n  try\n    objType := ctx.GetType(Obj.ClassInfo);\n    for Field in objType.GetFields do begin\n      // START BY FINDING FORM PREFIX, SKIP FIELDS UNTIL FOUND\n      if not Assigned(FormPrefix) then begin\n        FormPrefix := GetPrefixAttribute(Field);\n        if Assigned(FormPrefix) then\n          CurrentPrefix := FormPrefix.Prefix\n        else\n          continue;\n      end;\n\n      // IF FORM SECTION, DUMP SECTION\n      FormSection := GetSectionAttribute(Field);\n      if Assigned(FormSection) then\n        CurrentSection := FormSection.Section;\n\n      // SKIP ALL ITEMS IN 'DontTranslate' SECTION\n      if CurrentSection = 'DontTranslate' then\n        continue;\n\n      // LOAD VALUES\n      FieldName := Field.FieldType.Name;\n      if FieldName = 'TCheckBox' then begin\n        aCheckBox := TCheckBox(field.GetValue(obj).AsType<TCheckBox>);\n        if Assigned(aCheckBox) then begin\n          value := ReadValue(CurrentPrefix, sl, Field, 'Caption');\n          if value <> '' then aCheckBox.Caption := value;\n          value := ReadValue(CurrentPrefix, sl, Field, 'Hint');\n          aCheckBox.ShowHint := value <> '';\n          if aCheckBox.ShowHint then aCheckBox.Hint := value;\n        end;\n      end\n      else if FieldName = 'TButton' then begin\n        aButton := TButton(field.GetValue(obj).AsType<TButton>);\n        if Assigned(aButton) then begin\n          value := ReadValue(CurrentPrefix, sl, Field, 'Caption');\n          if value <> '' then aButton.Caption := value;\n          value := ReadValue(CurrentPrefix, sl, Field, 'Hint');\n          aButton.ShowHint := value <> '';\n          if aButton.ShowHint then aButton.Hint := value;\n        end;\n      end\n      else if FieldName = 'TLabel' then begin\n        aLabel := TLabel(field.GetValue(obj).AsType<TLabel>);\n        if Assigned(aLabel) then begin\n          value := ReadValue(CurrentPrefix, sl, Field, 'Caption');\n          if value <> '' then aLabel.Caption := value;\n          value := ReadValue(CurrentPrefix, sl, Field, 'Hint');\n          aLabel.ShowHint := value <> '';\n          if aLabel.ShowHint then aLabel.Hint := value;\n        end;\n      end\n      else if FieldName = 'TTabSheet' then begin\n        aTabSheet := TTabSheet(field.GetValue(obj).AsType<TTabSheet>);\n        if Assigned(aTabSheet) then begin\n          value := ReadValue(CurrentPrefix, sl, Field, 'Caption');\n          if value <> '' then aTabSheet.Caption := value;\n          value := ReadValue(CurrentPrefix, sl, Field, 'Hint');\n          aTabSheet.ShowHint := value <> '';\n          if aTabSheet.ShowHint then aTabSheet.Hint := value;\n        end;\n      end\n      else if FieldName = 'TGroupBox' then begin\n        aGroupBox := TGroupBox(field.GetValue(obj).AsType<TGroupBox>);\n        if Assigned(aGroupBox) then begin\n          value := ReadValue(CurrentPrefix, sl, Field, 'Caption');\n          if value <> '' then aGroupBox.Caption := value;\n          value := ReadValue(CurrentPrefix, sl, Field, 'Hint');\n          aGroupBox.ShowHint := value <> '';\n          if aGroupBox.ShowHint then aGroupBox.Hint := value;\n        end;\n      end\n      else if FieldName = 'TSpeedButton' then begin\n        aSpeedButton := TSpeedButton(field.GetValue(obj).AsType<TSpeedButton>);\n        if Assigned(aSpeedButton) then begin\n          value := ReadValue(CurrentPrefix, sl, Field, 'Hint');\n          aSpeedButton.ShowHint := value <> '';\n          if aSpeedButton.ShowHint then aSpeedButton.Hint := value;\n        end;\n      end\n      else if FieldName = 'TMenuItem' then begin\n        aMenuItem := TMenuItem(field.GetValue(obj).AsType<TMenuItem>);\n        if Assigned(aMenuItem) then begin\n          value := ReadValue(CurrentPrefix, sl, Field, 'Caption');\n          if value <> '' then aMenuItem.Caption := value;\n        end;\n      end\n      else if FieldName = 'TComboBox' then begin\n        aComboBox := TComboBox(field.GetValue(obj).AsType<TComboBox>);\n        if Assigned(aComboBox) then begin\n          for i := 0 to Pred(aComboBox.Items.Count) do begin\n            value := ReadValue(CurrentPrefix, sl, Field, 'Item'+IntToStr(i));\n            if value <> '' then aComboBox.Items[i] := value;\n          end;\n        end;\n      end\n      else if FieldName = 'TListView' then begin\n        aListView := TListView(field.GetValue(obj).AsType<TListView>);\n        if Assigned(aListView) then begin\n          if not aListView.ShowColumnHeaders then\n            continue;\n          for i := 0 to Pred(aListView.Columns.Count) do begin\n            value := ReadValue(CurrentPrefix, sl, Field, 'Column'+IntToStr(i));\n            if value <> '' then aListView.Columns[i].Caption := value;\n          end;\n        end;\n      end;\n    end;\n  finally\n    ctx.Free;\n  end;\nend;\n\nclass function TRttiTranslation.ReadValue(section: string; var sl: TStringList;\n  field: TRttiField; subfield: string): string;\nvar\n  name: string;\nbegin\n  // load value from stringlist\n  name := Format('%s_%s_%s', [section, field.Name, subfield]);\n  Result := StringReplace(sl.Values[name], '#13#10', #13#10, [rfReplaceAll]);\nend;\n\nclass procedure TRttiTranslation.WriteValue(section: string; value: string; var sl: TStringList;\n  field: TRttiField; subfield: string);\nvar\n  name: string;\nbegin\n  if value = '' then\n    exit;\n  name := Format('%s_%s_%s', [section, field.Name, subfield]);\n  sl.Values[name] := StringReplace(value, #13#10, '#13#10', [rfReplaceAll]);\nend;\n\nclass procedure TRttiTranslation.Save(filename: string; obj: TObject);\nvar\n  ctx: TRttiContext;\n  objType: TRttiType;\n  Field: TRttiField;\n  FormPrefix: FormPrefixAttribute;\n  FormSection: FormSectionAttribute;\n  sl: TStringList;\n  i: Integer;\n  Header, CurrentPrefix, CurrentSection, FieldName: string;\n  bNewObject: boolean;\n  aCheckBox: TCheckBox;\n  aButton: TButton;\n  aLabel: TLabel;\n  aTabSheet: TTabSheet;\n  aGroupBox: TGroupBox;\n  aSpeedButton: TSpeedButton;\n  aMenuItem: TMenuItem;\n  aComboBox: TComboBox;\n  aListView: TListView;\nbegin\n  FormPrefix := nil;\n  ctx := TRttiContext.Create;\n  try\n    // LOAD FILE IF IT EXISTS\n    sl := TStringList.Create;\n    if FileExists(filename) then\n      sl.LoadFromFile(filename);\n\n    // ADD HEADER IF NEW OBJECT\n    Header := Format('{ %s }', [obj.ClassName]);\n    bNewObject := sl.IndexOf(Header) = -1;\n    if bNewObject then sl.Add(Header);\n\n    try\n      objType := ctx.GetType(Obj.ClassInfo);\n      for Field in objType.GetFields do begin\n        // START BY FINDING FORM PREFIX, SKIP FIELDS UNTIL FOUND\n        if not Assigned(FormPrefix) then begin\n          FormPrefix := GetPrefixAttribute(Field);\n          if Assigned(FormPrefix) then\n            CurrentPrefix := FormPrefix.Prefix\n          else\n            continue;\n        end;\n\n        // IF FORM SECTION, DUMP SECTION\n        FormSection := GetSectionAttribute(Field);\n        if Assigned(FormSection) then begin\n          CurrentSection := FormSection.Section;\n          if CurrentSection = 'DontTranslate' then\n            continue;\n          Header := Format('{ ## %s ## }', [FormSection.Section]);\n          if (sl.IndexOf(Header) = -1) then sl.Add(Header);\n        end;\n\n        // SKIP ALL ITEMS IN 'DontTranslate' SECTION\n        if CurrentSection = 'DontTranslate' then\n          continue;\n\n        // HANDLE COMPONENTS\n        FieldName := Field.FieldType.Name;\n        // Handle TCheckBox\n        if FieldName = 'TCheckBox' then begin\n          aCheckBox := TCheckBox(field.GetValue(obj).AsType<TCheckBox>);\n          if Assigned(aCheckBox) then begin\n            WriteValue(CurrentPrefix, aCheckBox.Caption, sl, field, 'Caption');\n            WriteValue(CurrentPrefix, aCheckBox.Hint, sl, field, 'Hint');\n          end;\n        end\n        // Handle TButton\n        else if FieldName = 'TButton' then begin\n          aButton := TButton(field.GetValue(obj).AsType<TButton>);\n          if Assigned(aButton) then begin\n            WriteValue(CurrentPrefix, aButton.Caption, sl, field, 'Caption');\n            WriteValue(CurrentPrefix, aButton.Hint, sl, field, 'Hint');\n          end;\n        end\n        // Handle TLabel\n        else if FieldName = 'TLabel' then begin\n          aLabel := TLabel(field.GetValue(obj).AsType<TLabel>);\n          if Assigned(aLabel) then begin\n            WriteValue(CurrentPrefix, aLabel.Caption, sl, field, 'Caption');\n            WriteValue(CurrentPrefix, aLabel.Hint, sl, field, 'Hint');\n          end;\n        end\n        // Handle TTabSheet\n        else if FieldName = 'TTabSheet' then begin\n          aTabSheet := TTabSheet(field.GetValue(obj).AsType<TTabSheet>);\n          if Assigned(aTabSheet) then begin\n            WriteValue(CurrentPrefix, aTabSheet.Caption, sl, field, 'Caption');\n            WriteValue(CurrentPrefix, aTabSheet.Hint, sl, field, 'Hint');\n          end;\n        end\n        // Handle TGroupBox\n        else if FieldName = 'TGroupBox' then begin\n          aGroupBox := TGroupBox(field.GetValue(obj).AsType<TGroupBox>);\n          if Assigned(aGroupBox) then begin\n            WriteValue(CurrentPrefix, aGroupBox.Caption, sl, field, 'Caption');\n            WriteValue(CurrentPrefix, aGroupBox.Hint, sl, field, 'Hint');\n          end;\n        end\n        // Handle TSpeedButton\n        else if FieldName = 'TSpeedButton' then begin\n          aSpeedButton := TSpeedButton(field.GetValue(obj).AsType<TSpeedButton>);\n          if Assigned(aSpeedButton) then begin\n            WriteValue(CurrentPrefix, aSpeedButton.Caption, sl, field, 'Caption');\n            WriteValue(CurrentPrefix, aSpeedButton.Hint, sl, field, 'Hint');\n          end;\n        end\n        // Handle TMenuItem\n        else if FieldName = 'TMenuItem' then begin\n          aMenuItem := TMenuItem(field.GetValue(obj).AsType<TMenuItem>);\n          if Assigned(aMenuItem) then\n            WriteValue(CurrentPrefix, aMenuItem.Caption, sl, field, 'Caption');\n        end\n        // Handle TComboBox\n        else if FieldName = 'TComboBox' then begin\n          aComboBox := TComboBox(field.GetValue(obj).AsType<TComboBox>);\n          if Assigned(aComboBox) then\n            for i := 0 to Pred(aComboBox.Items.Count) do\n              WriteValue(CurrentPrefix, aComboBox.Items[i], sl, field, 'Item'+IntToStr(i));\n        end\n        // Handle TListView\n        else if FieldName = 'TListView' then begin\n          aListView := TListView(field.GetValue(obj).AsType<TListView>);\n          if Assigned(aListView) then begin\n            if not aListView.ShowColumnHeaders then\n              continue;\n            for i := 0 to Pred(aListView.Columns.Count) do\n              WriteValue(CurrentPrefix, aListView.Columns[i].Caption, sl, field, 'Column'+IntToStr(i));\n          end;\n        end;\n      end;\n    finally\n      if bNewObject then sl.Add(' ');\n      ForceDirectories(ExtractFilePath(filename));\n      sl.SaveToFile(fileName);\n      sl.Free;\n    end;\n  finally\n    ctx.Free;\n  end;\nend;\n\nend.\n"
  },
  {
    "path": "lib/mte/W7Taskbar.pas",
    "content": "unit W7Taskbar;\n\ninterface\n\nuses\n  Forms, Types, Windows, SysUtils, ComObj, Controls, Graphics;\n\ntype\n  TTaskBarProgressState = (tbpsNone, tbpsIndeterminate, tbpsNormal, tbpsError,\n    tbpsPaused);\n\n  function InitializeTaskbarAPI: boolean;\n  function SetTaskbarProgressState(const AState: TTaskBarProgressState): boolean;\n  function SetTaskbarProgressValue(const ACurrent: UInt64; const AMax: UInt64): boolean;\n  function SetTaskbarOverlayIcon(const AIcon: THandle; const ADescription: String): boolean;\n\nimplementation\n\nconst\n  TASKBAR_CID: TGUID = '{56FDF344-FD6D-11d0-958A-006097C9A090}';\n  TBPF_NOPROGRESS = 0;\n  TBPF_INDETERMINATE = 1;\n  TBPF_NORMAL = 2;\n  TBPF_ERROR = 4;\n  TBPF_PAUSED = 8;\n\ntype\n  ITaskBarList3 = interface(IUnknown)\n  ['{EA1AFB91-9E28-4B86-90E9-9E9F8A5EEFAF}']\n    function HrInit(): HRESULT; stdcall;\n    function AddTab(hwnd: THandle): HRESULT; stdcall;\n    function DeleteTab(hwnd: THandle): HRESULT; stdcall;\n    function ActivateTab(hwnd: THandle): HRESULT; stdcall;\n    function SetActiveAlt(hwnd: THandle): HRESULT; stdcall;\n    function MarkFullscreenWindow(hwnd: THandle; fFullscreen: Boolean): HRESULT; stdcall;\n    function SetProgressValue(hwnd: THandle; ullCompleted: UInt64; ullTotal: UInt64): HRESULT; stdcall;\n    function SetProgressState(hwnd: THandle; tbpFlags: Cardinal): HRESULT; stdcall;\n    function RegisterTab(hwnd: THandle; hwndMDI: THandle): HRESULT; stdcall;\n    function UnregisterTab(hwndTab: THandle): HRESULT; stdcall;\n    function SetTabOrder(hwndTab: THandle; hwndInsertBefore: THandle): HRESULT; stdcall;\n    function SetTabActive(hwndTab: THandle; hwndMDI: THandle; tbatFlags: Cardinal): HRESULT; stdcall;\n    function ThumbBarAddButtons(hwnd: THandle; cButtons: Cardinal; pButtons: Pointer): HRESULT; stdcall;\n    function ThumbBarUpdateButtons(hwnd: THandle; cButtons: Cardinal; pButtons: Pointer): HRESULT; stdcall;\n    function ThumbBarSetImageList(hwnd: THandle; himl: THandle): HRESULT; stdcall;\n    function SetOverlayIcon(hwnd: THandle; hIcon: THandle; pszDescription: PChar): HRESULT; stdcall;\n    function SetThumbnailTooltip(hwnd: THandle; pszDescription: PChar): HRESULT; stdcall;\n    function SetThumbnailClip(hwnd: THandle; var prcClip: TRect): HRESULT; stdcall;\n  end;\n\nvar\n  TaskBarInterface: ITaskBarList3;\n\nfunction InitializeTaskbarAPI: Boolean;\nvar\n  Unknown: IInterface;\n  Temp: ITaskBarList3;\nbegin\n  // return true and exit if already initialized\n  if Assigned(TaskBarInterface) then begin\n    Result := True;\n    Exit;\n  end;\n\n  // create COM object for taskbar CID\n  try\n    Unknown := CreateComObject(TASKBAR_CID);\n    if Assigned(Unknown) then begin\n      Temp := Unknown as ITaskBarList3;\n      if Temp.HrInit() = S_OK then\n        TaskBarInterface := Temp;\n    end;\n  except\n    TaskBarInterface := nil;\n  end;\n\n  // if we got the interface, return true\n  Result := Assigned(TaskBarInterface);\nend;\n\n{ Check to see if the API has been initialized }\nfunction CheckAPI: boolean;\nbegin\n  Result := Assigned(TaskBarInterface);\nend;\n\nfunction SetTaskbarProgressState(const AState: TTaskBarProgressState): boolean;\nvar\n  Flag: Cardinal;\nbegin\n  Result := False;\n\n  // exit if api not initialized\n  if not CheckAPI then\n    exit;\n\n  // check if state is valid, else use no progress\n  case AState of\n    tbpsIndeterminate: Flag := TBPF_INDETERMINATE;\n    tbpsNormal: Flag := TBPF_NORMAL;\n    tbpsError: Flag := TBPF_ERROR;\n    tbpsPaused: Flag := TBPF_PAUSED;\n  else\n    Flag := TBPF_NOPROGRESS;\n  end;\n\n  // set progress state\n  Result := TaskBarInterface.SetProgressState(Application.Handle, Flag) = S_OK;\nend;\n\nfunction SetTaskbarProgressValue(const ACurrent:UInt64; const AMax: UInt64): boolean;\nbegin\n  Result := False;\n\n  // exit if api not initialized\n  if not CheckAPI then\n    exit;\n\n  // set progress value\n  Result := TaskBarInterface.SetProgressValue(Application.Handle, ACurrent, AMax) = S_OK;\nend;\n\nfunction SetTaskbarOverlayIcon(const AIcon: THandle; const ADescription: String): boolean;\nbegin\n  Result := False;\n\n  // exit if api not initialized\n  if not CheckAPI then\n    exit;\n\n  // set icon\n  Result := TaskBarInterface.SetOverlayIcon(Application.Handle, AIcon, PWideChar(ADescription)) = S_OK;\nend;\n\ninitialization\n  TaskBarInterface := nil;\n\nfinalization\n  TaskBarInterface := nil;\n\nend.\n"
  },
  {
    "path": "lib/mte/mteBase.pas",
    "content": "unit mteBase;\n\ninterface\n\nuses\n  Classes, Menus,\n  // third party libraries\n  superobject,\n  // mte units\n  mteTracker,\n  // xEdit units\n  wbHelpers, wbInterface, wbImplementation;\n\ntype\n  TSmashType = ( stUnknown, stRecord, stString, stInteger, stFlag, stFloat,\n    stStruct, stUnsortedArray, stUnsortedStructArray, stSortedArray,\n    stSortedStructArray, stByteArray, stUnion );\n  TBasePlugin = class(TObject)\n  public\n    _File: IwbFile;\n    hasData: boolean;\n    hash: string;\n    fileSize: Int64;\n    dateModified: string;\n    filename: string;\n    numRecords: Integer;\n    numOverrides: Integer;\n    author: string;\n    dataPath: string;\n    description: TStringList;\n    masters: TStringList;\n    requiredBy: TStringList;\n    constructor Create; virtual;\n    destructor Destroy; override;\n    procedure GetData(var lst: TList);\n    procedure UpdateData; virtual;\n    procedure GetHash;\n    function GetFormIndex: Integer;\n  end;\n  TPluginHelpers = class\n    class function CreateNewBasePlugin(var list: TList; filename: string): TBasePlugin;\n    class function BasePluginByFilename(var list: TList; filename: string): TBasePlugin;\n    class function BasePluginLoadOrder(var list: TList; filename: string): integer;\n  end;\n  THeaderHelpers = class\n    class procedure LoadPluginHeaders(var sl: TStringList);\n    class procedure GetPluginMasters(filename: string; var sl: TStringList);\n    class procedure GetPluginDependencies(filename: string; var sl: TStringList);\n  end;\n\n  { General Helper Functions }\n  function etToString(et: TwbElementType): string;\n  function dtToString(dt: TwbDefType): string;\n  function ctToString(ct: TConflictThis): string;\n  function stToString(st: TSmashType): string;\n  function SmashType(def: IwbNamedDef): TSmashtype;\n  function GetSmashType(element: IwbElement): TSmashType;\n  function ElementByIndexedPath(e: IwbElement; ip: string): IwbElement;\n  function IndexedPath(e: IwbElement): string;\n  function GetAllValues(e: IwbElement): string;\n  function IsSortedDef(def: IwbNamedDef): boolean;\n  function IsSorted(e: IwbElement): boolean;\n  function HasStructChildren(e: IwbElement): boolean;\n  function HasStructChildrenDef(def: IwbNamedDef): boolean;\n  function WinningOverrideInFiles(rec: IwbMainRecord;\n    var sl: TStringList): IwbMainRecord;\n  function IsOverride(aRecord: IwbMainRecord): boolean;\n  function ExtractFormID(filename: string): string;\n  function RemoveFileIndex(formID: string): string;\n  function LocalFormID(aRecord: IwbMainRecord): integer;\n  function LoadOrderPrefix(aRecord: IwbMainRecord): integer;\n  function CountOverrides(aFile: IwbFile): integer;\n  function OverrideCountInFiles(rec: IwbMainRecord; var files: TStringList): Integer;\n  procedure AddRequiredBy(var lst: TList; filename: string;\n    var masters: TStringList);\n  procedure GetMasters(aFile: IwbFile; var sl: TStringList);\n  procedure AddMasters(aFile: IwbFile; var sl: TStringList);\n  function RemoveSelfOrContainer(const aElement: IwbElement): boolean;\n  procedure UndeleteAndDisable(const aRecord: IwbMainRecord);\n  function LoadOrderCompare(List: TStringList; Index1, Index2: Integer): Integer;\n\n  { Record Prototyping Functions }\n  function GetElementObj(var obj: ISuperObject; name: string): ISuperObject;\n  function CreateRecordObj(var tree: ISuperObject; rec: IwbMainRecord): ISuperObject;\n  function GetRecordObj(var tree: ISuperObject; name: string): ISuperObject;\n  function GetRecordDef(sig: TwbSignature): TwbRecordDefEntry;\n  function BuildDef(def: IwbNamedDef; name: string): ISuperObject;\n  function BuildRecordDef(sName: string; mrDef: IwbRecordDef; out recObj: ISuperObject): boolean; overload;\n  function BuildRecordDef(sName: string; out recObj: ISuperObject): boolean; overload;\n  function GetEditableFileContainer: IwbContainerElementRef;\n\n  { Plugin Error Functions }\n  function FixErrors(const aElement: IwbElement; lastRecord: IwbMainRecord;\n    var errors: TStringList): IwbMainRecord;\n  function CheckForErrors(const aElement: IwbElement; lastRecord: IwbMainRecord;\n    var errors: TStringList): IwbMainRecord;\n\n  { Asset Handling Functions }\n  procedure ExtractBSA(ContainerName, folder, destination: string); overload;\n  procedure ExtractBSA(ContainerName, destination: string; var ignore: TStringList); overload;\n  function BSAExists(filename: string): boolean;\n  function INIExists(filename: string): boolean;\n  function TranslationExists(filename: string): boolean;\n  function FaceDataExists(filename: string): boolean;\n  function VoiceDataExists(filename: string): boolean;\n  function FragmentsExist(f: IwbFile): boolean;\n  function ReferencesSelf(f: IwbFile): boolean;\n\nvar\n  PluginsList: TList;\n  HeaderList: TList;\n\nimplementation\n\nuses\n  SysUtils, Dialogs,\n  mteHelpers,\n  msConfiguration;\n\nconstructor TBasePlugin.Create;\nbegin\n  hasData := false;\n  dataPath := wbDataPath;\n  description := TStringList.Create;\n  masters := TStringList.Create;\n  requiredBy := TStringList.Create;\nend;\n\ndestructor TBasePlugin.Destroy;\nbegin\n  description.Free;\n  masters.Free;\n  requiredBy.Free;\nend;\n\nprocedure TBasePlugin.GetData(var lst: TList);\nvar\n  Container: IwbContainer;\n  s: string;\nbegin\n  hasData := true;\n\n  // get data\n  filename := _File.FileName;\n  Container := _File as IwbContainer;\n  Container := Container.Elements[0] as IwbContainer;\n  author := Container.GetElementEditValue('CNAM - Author');\n  // we have to subtract 1 because this count includes the\n  // file header for some reason\n  numRecords := Container.GetElementNativeValue('HEDR - Header\\Number of Records') - 1;\n\n  // get masters, required by\n  GetMasters(_File, masters);\n  AddRequiredBy(lst, filename, masters);\n\n  // get description\n  s := Container.GetElementEditValue('SNAM - Description');\n  description.Text := Wordwrap(s, 80);\n\n  // get file attributes\n  fileSize := GetFileSize(wbDataPath + filename);\n  dateModified := DateTimeToStr(GetLastModified(wbDataPath + filename));\nend;\n\nprocedure TBasePlugin.UpdateData;\nbegin\n  // virtual method to be overridden\nend;\n\nprocedure TBasePlugin.GetHash;\nbegin\n  hash := IntToHex(wbCRC32File(wbDataPath + filename), 8);\nend;\n\nfunction TBasePlugin.GetFormIndex: Integer;\nvar\n  Container, MasterFiles: IwbContainer;\nbegin\n  Result := 0;\n  Container := self._File as IwbContainer;\n  Container := Container.Elements[0] as IwbContainer;\n  if Container.ElementExists['Master Files'] then begin\n    MasterFiles := Container.ElementByPath['Master Files'] as IwbContainer;\n    Result := MasterFiles.ElementCount;\n  end;\nend;\n\n\n{*****************************************************************************}\n{ PLUGIN HELPERS\n  Helper methods for dealing with TBasePlugins.\n}\n{*****************************************************************************}\n\n{ Create a new plugin }\nclass function TPluginHelpers.CreateNewBasePlugin(var list: TList; filename: string): TBasePlugin;\nvar\n  aFile: IwbFile;\n  LoadOrder: integer;\n  plugin: TBasePlugin;\nbegin\n  Result := nil;\n  LoadOrder := PluginsList.Count + 1;\n  // fail if maximum load order reached\n  if LoadOrder > 254 then begin\n    Tracker.Write('Maximum load order reached!  Can''t create file '+filename);\n    exit;\n  end;\n\n  // create new plugin file\n  SysUtils.FormatSettings.DecimalSeparator := '.';\n  aFile := wbNewFile(wbDataPath + filename, LoadOrder);\n  aFile._AddRef;\n\n  // create new plugin object\n  plugin := TBasePlugin.Create;\n  plugin.filename := filename;\n  plugin._File := aFile;\n  Result := plugin;\nend;\n\n{ Gets the load order of the plugin matching the given name }\nclass function TPluginHelpers.BasePluginLoadOrder(var list: TList; filename: string): integer;\nvar\n  i: integer;\n  plugin: TBasePlugin;\nbegin\n  Result := -1;\n  for i := 0 to Pred(list.Count) do begin\n    plugin := TBasePlugin(list[i]);\n    if plugin.filename = filename then begin\n      Result := i;\n      exit;\n    end;\n  end;\nend;\n\n{ Gets a plugin matching the given name. }\nclass function TPluginHelpers.BasePluginByFilename(var list: TList; filename: string): TBasePlugin;\nvar\n  i: integer;\n  plugin: TBasePlugin;\nbegin\n  Result := nil;\n  for i := 0 to Pred(list.count) do begin\n    plugin := TBasePlugin(list[i]);\n    if plugin.filename = filename then begin\n      Result := plugin;\n      exit;\n    end;\n  end;\nend;\n\nclass procedure THeaderHelpers.LoadPluginHeaders(var sl: TStringList);\nvar\n  i: Integer;\n  aFile: IwbFile;\n  plugin: TBasePlugin;\nbegin\n  // create header list\n  HeaderList := TList.Create;\n\n  // load plugin headers for each plugin in @sl\n  for i := 0 to Pred(sl.Count) do try\n    aFile := wbFile(wbDataPath + sl[i], -1, '', False, True);\n    plugin := TBasePlugin.Create;\n    plugin._File := aFile;\n    HeaderList.Add(plugin);\n  except\n    on x: Exception do begin\n      Tracker.Write('Failed to load '+sl[i]);\n    end;\n  end;\n\n  // get data for each plugin in the header list\n  for i := 0 to Pred(HeaderList.Count) do begin\n    plugin := TBasePlugin(HeaderList[i]);\n    plugin.GetData(HeaderList);\n  end;\nend;\n\nclass procedure THeaderHelpers.GetPluginMasters(filename: string;\n  var sl: TStringList);\nvar\n  plugin: TBasePlugin;\n  i: integer;\nbegin\n  // get plugin\n  plugin := TPluginHelpers.BasePluginByFilename(HeaderList, filename);\n  if not Assigned(plugin) then exit;\n  // add its masters to @sl\n  for i := 0 to Pred(plugin.masters.Count) do begin\n    if sl.IndexOf(plugin.masters[i]) > -1 then continue;\n    sl.Add(plugin.masters[i]);\n    GetPluginMasters(plugin.masters[i], sl);\n  end;\nend;\n\nclass procedure THeaderHelpers.GetPluginDependencies(filename: string;\n  var sl: TStringList);\nvar\n  plugin: TBasePlugin;\n  i: integer;\nbegin\n  // get plugin\n  plugin := TPluginHelpers.BasePluginByFilename(HeaderList, filename);\n  if not Assigned(plugin) then exit;\n  // add its required by to @sl\n  for i := 0 to Pred(plugin.requiredBy.Count) do begin\n    if sl.IndexOf(plugin.requiredBy[i]) > -1 then continue;\n    sl.Add(plugin.requiredBy[i]);\n    GetPluginDependencies(plugin.requiredBy[i], sl);\n  end;\nend;\n\n\n{******************************************************************************}\n{ General Helper Functions\n  Set of functions that read bethesda plugin files for various attributes.\n\n  List of functions:\n  - etToString\n  - dtToString\n  - ctToString\n  - stToString\n  - GetSmashType\n  - ElementByIndexedPath\n  - IndexedPath\n  - GetAllValues\n  - IsSorted\n  - HasStructChildren\n  - WinningOverrideInFiles\n  - IsOverride\n  - LocalFormID\n   -LoadOrderPrefix\n  - CountOverrides\n  - GetMasters\n  - AddMasters\n  - BSAExists\n  - TranslationExists\n  - FaceDataExists\n  - VoiceDataExists\n  - FragmentsExist\n  - ExtractBSA\n  - CheckForErorrsLinear\n  - CheckForErrors\n  - PluginsModified\n  - CreatSEQFile\n}\n{*****************************************************************************}\n\n{ Converts a TwbElementType to a string }\nfunction etToString(et: TwbElementType): string;\nbegin\n  case Ord(et) of\n    Ord(etFile): Result := 'etFile';\n    Ord(etMainRecord): Result := 'etMainRecord';\n    Ord(etGroupRecord): Result := 'etGroupRecord';\n    Ord(etSubRecord): Result := 'etSubRecord';\n    Ord(etSubRecordStruct): Result := 'etSubRecordStruct';\n    Ord(etSubRecordArray): Result := 'etSubRecordArray';\n    Ord(etSubRecordUnion): Result := 'etSubRecordUnion';\n    Ord(etArray): Result := 'etArray';\n    Ord(etStruct): Result := 'etStruct';\n    Ord(etValue): Result := 'etValue';\n    Ord(etFlag): Result := 'etFlag';\n    Ord(etStringListTerminator): Result := 'etStringListTerminator';\n    Ord(etUnion): Result := 'etUnion';\n  end;\nend;\n\n{ Converts a TwbDefType to a string }\nfunction dtToString(dt: TwbDefType): string;\nbegin\n  case Ord(dt) of\n    Ord(dtRecord): Result := 'dtRecord';\n    Ord(dtSubRecord): Result := 'dtSubRecord';\n    Ord(dtSubRecordArray): Result := 'dtSubRecordArray';\n    Ord(dtSubRecordStruct): Result := 'dtSubRecordStruct';\n    Ord(dtSubRecordUnion): Result := 'dtSubRecordUnion';\n    Ord(dtString): Result := 'dtString';\n    Ord(dtLString): Result := 'dtLString';\n    Ord(dtLenString): Result := 'dtLenString';\n    Ord(dtByteArray): Result := 'dtByteArray';\n    Ord(dtInteger): Result := 'dtInteger';\n    Ord(dtIntegerFormater): Result := 'dtIntegerFormatter';\n    Ord(dtFloat): Result := 'dtFloat';\n    Ord(dtArray): Result := 'dtArray';\n    Ord(dtStruct): Result := 'dtStruct';\n    Ord(dtUnion): Result := 'dtUnion';\n    Ord(dtEmpty): Result := 'dtEmpty';\n  end;\nend;\n\nfunction ctToString(ct: TConflictThis): string;\nbegin\n  case Ord(ct) of\n    Ord(ctUnknown): Result := 'ctUnknown';\n    Ord(ctIgnored): Result := 'ctIgnored';\n    Ord(ctNotDefined): Result := 'ctNotDefined';\n    Ord(ctIdenticalToMaster): Result := 'ctIdenticalToMaster';\n    Ord(ctOnlyOne): Result := 'ctOnlyOne';\n    Ord(ctHiddenByModGroup): Result := 'ctHiddenByModGroup';\n    Ord(ctMaster): Result := 'ctMaster';\n    Ord(ctConflictBenign): Result := 'ctConflictBenign';\n    Ord(ctOverride): Result := 'ctOverride';\n    Ord(ctIdenticalToMasterWinsConflict): Result := 'ctIdenticalToMasterWinsConflict';\n    Ord(ctConflictWins): Result := 'ctConflictWins';\n    Ord(ctConflictLoses): Result := 'ctConflictLoses';\n  end;\nend;\n\nfunction stToString(st: TSmashType): string;\nbegin\n  case Ord(st) of\n    Ord(stUnknown): Result := 'Unknown';\n    Ord(stRecord): Result := 'Record';\n    Ord(stString): Result := 'String';\n    Ord(stInteger): Result := 'Integer';\n    Ord(stFlag): Result := 'Flag';\n    Ord(stFloat): Result := 'Float';\n    Ord(stStruct): Result := 'Struct';\n    Ord(stUnsortedArray): Result := 'Unsorted Array';\n    Ord(stUnsortedStructArray): Result := 'Unsorted Struct Array';\n    Ord(stSortedArray): Result := 'Sorted Array';\n    Ord(stSortedStructArray): Result := 'Sorted Struct Array';\n    Ord(stByteArray): Result := 'Byte Array';\n    Ord(stUnion): Result := 'Union';\n    else Result := 'Unknown';\n  end;\nend;\n\nfunction SmashType(def: IwbNamedDef): TSmashtype;\nvar\n  subDef: IwbSubRecordDef;\n  dt: TwbDefType;\n  bIsSorted, bHasStructChildren: boolean;\nbegin\n  dt := def.DefType;\n  if Supports(def, IwbSubrecordDef, subDef) then\n    dt := subDef.GetValue.DefType;\n  case Ord(dt) of\n    Ord(dtRecord): Result := stRecord;\n    Ord(dtSubRecord): Result := stUnknown;\n    Ord(dtSubRecordStruct): Result := stStruct;\n    Ord(dtSubRecordUnion): Result := stUnion;\n    Ord(dtString): Result := stString;\n    Ord(dtLString): Result := stString;\n    Ord(dtLenString): Result := stString;\n    Ord(dtByteArray): Result := stByteArray;\n    Ord(dtInteger): Result := stInteger;\n    Ord(dtIntegerFormater): Result := stInteger;\n    Ord(dtIntegerFormaterUnion): Result := stInteger;\n    Ord(dtFlag): Result := stFlag;\n    Ord(dtFloat): Result := stFloat;\n    Ord(dtSubRecordArray), Ord(dtArray): begin\n      bIsSorted := IsSortedDef(def);\n      bHasStructChildren := HasStructChildrenDef(def);\n      if bIsSorted then begin\n        if bHasStructChildren then\n          Result := stSortedStructArray\n        else\n          Result := stSortedArray;\n      end\n      else begin\n        if bHasStructChildren then\n          Result := stUnsortedStructArray\n        else\n          Result := stUnsortedArray;\n      end;\n    end;\n    Ord(dtStruct): Result := stStruct;\n    Ord(dtUnion): Result := stUnion;\n    Ord(dtEmpty): Result := stUnknown;\n    Ord(dtStructChapter): Result := stStruct;\n    else Result := stUnknown;\n  end;\nend;\n\nfunction GetSmashType(element: IwbElement): TSmashType;\nbegin\n  Result := SmashType(element.Def);\nend;\n\nfunction ElementByIndexedPath(e: IwbElement; ip: string): IwbElement;\nvar\n  i, index: integer;\n  path: TStringList;\n  c: IwbContainerElementRef;\nbegin\n  // replace forward slashes with backslashes\n  ip := StringReplace(ip, '/', '\\', [rfReplaceAll]);\n\n  // prepare path stringlist delimited by backslashes\n  path := TStringList.Create;\n  path.Delimiter := '\\';\n  path.StrictDelimiter := true;\n  path.DelimitedText := ip;\n\n  // treat e as a container\n  if not Supports(e, IwbContainerElementRef, c) then\n    exit;\n\n  // traverse path\n  for i := 0 to Pred(path.count) do begin\n    if Pos('[', path[i]) > 0 then begin\n      index := StrToInt(GetTextIn(path[i], '[', ']'));\n      e := c.Elements[index];\n      if not Supports(e, IwbContainerElementRef, c) then\n        exit;\n    end\n    else begin\n      e := c.ElementByPath[path[i]];\n      if not Supports(e, IwbContainerElementRef, c) then\n        exit;\n    end;\n  end;\n\n  // set result\n  Result := e;\nend;\n\nfunction IndexedPath(e: IwbElement): string;\nvar\n  c: IwbContainer;\n  a: string;\nbegin\n  c := e.Container;\n  while (e.ElementType <> etMainRecord) do begin\n    if c.ElementType = etSubRecordArray then\n      a := '['+IntToStr(c.IndexOf(e))+']'\n    else\n      a := e.Name;\n    if Result <> '' then\n      Result := a + '\\' + Result\n    else\n      Result := a;\n    e := c;\n    c := e.Container;\n  end;\nend;\n\n{ Returns a string hash of all of the values contained in an element }\nfunction GetAllValues(e: IwbElement): string;\nvar\n  i: integer;\n  c: IwbContainerElementRef;\nbegin\n  Result := e.EditValue;\n  if not Supports(e, IwbContainerElementRef, c) then\n    exit;\n\n  // loop through children elements\n  for i := 0 to Pred(c.ElementCount) do begin\n    if (Result <> '') then\n      Result := Result + ';' + GetAllValues(c.Elements[i])\n    else\n      Result := GetAllValues(c.Elements[i]);\n  end;\nend;\n\nfunction IsSortedDef(def: IwbNamedDef): boolean;\nvar\n  sraDef: IwbSubRecordArrayDef;\n  arDef: IwbArrayDef;\nbegin\n  Result := false;\n  if Supports(def, IwbSubRecordArrayDef, sraDef) then\n    Result := Supports(sraDef.Element, IwbHasSortKeyDef)\n  else if Supports(def, IwbArrayDef, arDef) then\n    Result := Supports(arDef.Element, IwbHasSortKeyDef);\nend;\n\n{ Returns true if @e is a sorted container }\nfunction IsSorted(e: IwbElement): boolean;\nvar\n  Container: IwbSortableContainer;\nbegin\n  Result := false;\n  if Supports(e, IwbSortableContainer, Container) then\n    Result := Container.Sorted;\nend;\n\nfunction HasStructChildrenDef(def: IwbNamedDef): boolean;\nbegin\n  Result := Supports(def, IwbSubRecordArrayDef);\nend;\n\n{ Returns true if @e is a container with struct children }\nfunction HasStructChildren(e: IwbElement): boolean;\nvar\n  Container: IwbContainerElementRef;\nbegin\n  Result := false;\n  if Supports(e, IwbContainerElementRef, Container)\n  and (Container.ElementCount > 0) then\n    Result := GetSmashType(Container.Elements[0]) = stStruct;\nend;\n\n{ Returns the most-winning override of @rec from the\n  files listed in @sl }\nfunction WinningOverrideInFiles(rec: IwbMainRecord;\n  var sl: TStringList): IwbMainRecord;\nvar\n  i: Integer;\n  ovr: IwbMainRecord;\nbegin\n  Result := rec;\n  for i := Pred(rec.OverrideCount) downto 0 do begin\n    ovr := rec.Overrides[i];\n    if sl.IndexOf(ovr._file.FileName) > -1 then begin\n      Result := ovr;\n      exit;\n    end;\n  end;\nend;\n\n{ Returns true if the input record is an override record }\nfunction IsOverride(aRecord: IwbMainRecord): boolean;\nbegin\n  Result := not aRecord.IsMaster;\nend;\n\nfunction ExtractFormID(filename: string): string;\nconst\n  HexChars = ['0'..'9', 'A'..'F', 'a'..'f'];\nvar\n  i, counter: Integer;\nbegin\n  counter := 0;\n  // we loop from the back because the formID is usually at the\n  // end of the filename\n  for i := Length(filename) downto 1 do begin\n    if (filename[i] in HexChars) then\n      Inc(counter)\n    else\n      counter := 0;\n    // set result and exit if counter has reached 8\n    if counter = 8 then begin\n      Result := Copy(filename, i, 8);\n      exit;\n    end;\n  end;\nend;\n\nfunction RemoveFileIndex(formID: string): string;\nbegin\n  if Length(formID) <> 8 then\n    raise Exception.Create('RemoveFileIndex: FormID must be 8 characters long');\n  Result := '00' + Copy(formID, 3, 6);\nend;\n\n{ Gets the local formID of a record (so no load order prefix) }\nfunction LocalFormID(aRecord: IwbMainRecord): integer;\nbegin\n  Result := aRecord.LoadOrderFormID and $00FFFFFF;\nend;\n\n{ Gets the load order prefix from the FormID of a record }\nfunction LoadOrderPrefix(aRecord: IwbMainRecord): integer;\nbegin\n  Result := aRecord.LoadOrderFormID and $FF000000;\nend;\n\n{ Returns the number of override records in a file }\nfunction CountOverrides(aFile: IwbFile): integer;\nvar\n  i: Integer;\n  aRecord: IwbMainRecord;\nbegin\n  Result := 0;\n  for i := 0 to Pred(aFile.GetRecordCount) do begin\n    aRecord := aFile.GetRecord(i);\n    if IsOverride(aRecord) then\n      Inc(Result);\n  end;\nend;\n\n{ Returns the number of overrides of the specified record in the specified file set }\nfunction OverrideCountInFiles(rec: IwbMainRecord; var files: TStringList): Integer;\nvar\n  i: Integer;\n  ovr: IwbMainRecord;\nbegin\n  Result := 0;\n  for i := 0 to Pred(rec.OverrideCount) do begin\n    ovr := rec.Overrides[i];\n    if files.IndexOf(ovr._File.FileName) > -1 then\n      Inc(Result);\n  end;\nend;\n\n{ Populates required by field of @masters that are required by plugin\n  @filename }\nprocedure AddRequiredBy(var lst: TList; filename: string;\n  var masters: TStringList);\nvar\n  i: Integer;\n  plugin: TBasePlugin;\nbegin\n  for i := 0 to Pred(masters.Count) do begin\n    plugin := TPluginHelpers.BasePluginByFilename(lst, masters[i]);\n    if not Assigned(plugin) then\n      continue;\n    plugin.requiredBy.Add(filename);\n  end;\nend;\n\n{ Gets the masters in an IwbFile and puts them into a stringlist }\nprocedure GetMasters(aFile: IwbFile; var sl: TStringList);\nvar\n  Container, MasterFiles, MasterFile: IwbContainer;\n  i, iLoadOrder: integer;\n  filename: string;\nbegin\n  Container := aFile as IwbContainer;\n  Container := Container.Elements[0] as IwbContainer;\n  if Container.ElementExists['Master Files'] then begin\n    MasterFiles := Container.ElementByPath['Master Files'] as IwbContainer;\n    for i := 0 to MasterFiles.ElementCount - 1 do begin\n      MasterFile := MasterFiles.Elements[i] as IwbContainer;\n      filename := MasterFile.GetElementEditValue('MAST - Filename');\n      if sl.IndexOf(filename) = -1 then begin\n        iLoadOrder := TPluginHelpers.BasePluginLoadOrder(PluginsList, filename);\n        sl.AddObject(filename, TObject(iLoadOrder));\n      end;\n    end;\n  end;\nend;\n\n{ Gets the masters in an IwbFile and puts them into a stringlist }\nprocedure AddMasters(aFile: IwbFile; var sl: TStringList);\nvar\n  i: integer;\nbegin\n  for i := 0 to Pred(sl.Count) do begin\n    if Lowercase(aFile.FileName) = Lowercase(sl[i]) then\n      continue;\n    aFile.AddMasterIfMissing(sl[i]);\n  end;\nend;\n\n{ Checks if a BSA exists associated with the given filename }\nfunction BSAExists(filename: string): boolean;\nvar\n  bsaFilename, ContainerName: string;\nbegin\n  Result := false;\n  bsaFilename := ChangeFileExt(filename, '.bsa');\n  if FileExists(wbDataPath + bsaFilename) then begin\n    ContainerName := wbDataPath + bsaFilename;\n    if not wbContainerHandler.ContainerExists(ContainerName) then\n      wbContainerHandler.AddBSA(ContainerName);\n    Result := true;\n  end;\nend;\n\n{ Check if an INI exists associated with the given filename }\nfunction INIExists(filename: string): boolean;\nvar\n  iniFilename: string;\nbegin\n  iniFilename := ChangeFileExt(filename, '.ini');\n  Result := FileExists(wbDataPath + iniFilename);\nend;\n\n{ Returns true if a file exists at @path matching @filename }\nfunction MatchingFileExists(path: string; filename: string): boolean;\nvar\n  info: TSearchRec;\nbegin\n  Result := false;\n  filename := Lowercase(filename);\n  if FindFirst(path, faAnyFile, info) = 0 then begin\n    repeat\n      if Pos(filename, Lowercase(info.Name)) > 0 then begin\n        Result := true;\n        exit;\n      end;\n    until FindNext(info) <> 0;\n    FindClose(info);\n  end;\nend;\n\n{ Return true if MCM translation files for @filename are found }\nfunction TranslationExists(filename: string): boolean;\nvar\n  searchPath, bsaFilename, ContainerName: string;\n  ResourceList: TStringList;\nbegin\n  searchPath := wbDataPath + 'Interface\\translations\\*';\n  Result := MatchingFileExists(searchPath, ChangeFileExt(filename, ''));\n  if Result then exit;\n\n  // check in BSA\n  if BSAExists(filename) then begin\n    bsaFilename := ChangeFileExt(filename, '.bsa');\n    ContainerName := wbDataPath + bsaFilename;\n    ResourceList := TStringList.Create;\n    wbContainerHandler.ContainerResourceList(ContainerName, ResourceList, 'Interface\\translations');\n    Result := ResourceList.Count > 0;\n  end;\nend;\n\n{ Return true if file-specific FaceGenData files for @filename are found }\nfunction FaceDataExists(filename: string): boolean;\nvar\n  facetintDir, facegeomDir, bsaFilename, ContainerName: string;\n  ResourceList: TStringList;\n  facetint, facegeom: boolean;\nbegin\n  facetintDir := 'textures\\actors\\character\\facegendata\\facetint\\' + filename;\n  facegeomDir := 'meshes\\actors\\character\\facegendata\\facegeom\\' + filename;\n  facetint := DirectoryExists(wbDataPath + facetintDir);\n  facegeom := DirectoryExists(wbDataPath + facegeomDir);\n  Result := facetint or facegeom;\n  if Result then exit;\n\n  // check in BSA\n  if BSAExists(filename) then begin\n    bsaFilename := ChangeFileExt(filename, '.bsa');\n    ContainerName := wbDataPath + bsaFilename;\n    ResourceList := TStringList.Create;\n    wbContainerHandler.ContainerResourceList(ContainerName, ResourceList, facetintDir);\n    wbContainerHandler.ContainerResourceList(ContainerName, ResourceList, facegeomDir);\n    Result := ResourceList.Count > 0;\n  end;\nend;\n\n{ Return true if file-specific Voice files for @filename are found }\nfunction VoiceDataExists(filename: string): boolean;\nvar\n  voiceDir, bsaFilename, ContainerName: string;\n  ResourceList: TStringList;\nbegin\n  voiceDir := 'sound\\voice\\' + filename;\n  Result := DirectoryExists(wbDataPath + voiceDir);\n  if Result then exit;\n\n  // check in BSA\n  if BSAExists(filename) then begin\n    bsaFilename := ChangeFileExt(filename, '.bsa');\n    ContainerName := wbDataPath + bsaFilename;\n    ResourceList := TStringList.Create;\n    wbContainerHandler.ContainerResourceList(ContainerName, ResourceList, voiceDir);\n    Result := ResourceList.Count > 0;\n  end;\nend;\n\n{ Returns true if Topic Info Fragments exist in @f }\nfunction TopicInfoFragmentsExist(f: IwbFile): boolean;\nconst\n  infoFragmentsPath = 'VMAD - Virtual Machine Adapter\\Data\\Info VMAD\\Script Fragments Info';\nvar\n  rec: IwbMainRecord;\n  group: IwbGroupRecord;\n  subgroup, container: IwbContainer;\n  element, fragments: IwbElement;\n  i, j: Integer;\nbegin\n  Result := false;\n  // exit if no DIAL records in file\n  if not f.HasGroup('DIAL') then\n    exit;\n\n  // find all DIAL records\n  group := f.GroupBySignature['DIAL'];\n  for i := 0 to Pred(group.ElementCount) do begin\n    element := group.Elements[i];\n    // find all INFO records\n    if not Supports(element, IwbContainer, subgroup) then\n      continue;\n    for j := 0 to Pred(subgroup.ElementCount) do begin\n      if not Supports(subgroup.Elements[j], IwbMainRecord, rec) then\n        continue;\n      if not rec.IsMaster then\n        continue;\n      if not Supports(rec, IwbContainer, container) then\n        continue;\n      fragments := container.ElementByPath[infoFragmentsPath];\n      if not Assigned(fragments) then\n        continue;\n      Result := true;\n    end;\n  end;\nend;\n\n{ Returns true if Quest Fragments exist in @f }\nfunction QuestFragmentsExist(f: IwbFile): boolean;\nconst\n  questFragmentsPath = 'VMAD - Virtual Machine Adapter\\Data\\Quest VMAD\\Script Fragments Quest';\nvar\n  rec: IwbMainRecord;\n  group: IwbGroupRecord;\n  container: IwbContainer;\n  fragments: IwbElement;\n  i: Integer;\nbegin\n  Result := false;\n  // exit if no QUST records in file\n  if not f.HasGroup('QUST') then\n    exit;\n\n  // find all QUST records\n  group := f.GroupBySignature['QUST'];\n  for i := 0 to Pred(group.ElementCount) do begin\n    if not Supports(group.Elements[i], IwbMainRecord, rec) then\n      continue;\n    if not rec.IsMaster then\n      continue;\n    if not Supports(rec, IwbContainer, container) then\n      continue;\n    fragments := container.ElementByPath[questFragmentsPath];\n    if not Assigned(fragments) then\n      continue;\n    Result := true;\n  end;\nend;\n\n{ Returns true if Quest Fragments exist in @f }\nfunction SceneFragmentsExist(f: IwbFile): boolean;\nconst\n  sceneFragmentsPath = 'VMAD - Virtual Machine Adapter\\Data\\Quest VMAD\\Script Fragments Quest';\nvar\n  rec: IwbMainRecord;\n  group: IwbGroupRecord;\n  container: IwbContainer;\n  fragments: IwbElement;\n  i: Integer;\nbegin\n  Result := false;\n  // exit if no SCEN records in file\n  if not f.HasGroup('SCEN') then\n    exit;\n\n  // find all SCEN records\n  group := f.GroupBySignature['SCEN'];\n  for i := 0 to Pred(group.ElementCount) do begin\n    if not Supports(group.Elements[i], IwbMainRecord, rec) then\n      continue;\n    if not rec.IsMaster then\n      continue;\n    if not Supports(rec, IwbContainer, container) then\n      continue;\n    fragments := container.ElementByPath[sceneFragmentsPath];\n    if not Assigned(fragments) then\n      continue;\n    Result := true;\n  end;\nend;\n\n{ Returns true if file-specific Script Fragments for @f are found }\nfunction FragmentsExist(f: IwbFile): boolean;\nbegin\n  Result := TopicInfoFragmentsExist(f) or QuestFragmentsExist(f)\n    or SceneFragmentsExist(f);\nend;\n\n{ References self }\nfunction ReferencesSelf(f: IwbFile): boolean;\nvar\n  i: Integer;\n  filename, source: string;\n  scripts: IwbGroupRecord;\n  container: IwbContainerElementRef;\n  rec: IwbMainRecord;\nbegin\n  // exit if has no script records in file\n  Result := false;\n  if not f.HasGroup('SCPT') then\n    exit;\n\n  // get scripts, and check them all for self-reference\n  filename := f.FileName;\n  scripts := f.GroupBySignature['SCPT'];\n  if not Supports(scripts, IwbContainerElementRef, container) then\n    exit;\n  for i := 0 to Pred(container.ElementCount) do begin\n    if not Supports(container.Elements[i], IwbMainRecord, rec) then\n      continue;\n    source := rec.ElementEditValues['SCTX - Script Source'];\n    if Pos(filename, source) > 0 then begin\n      Result := true;\n      break;\n    end;\n  end;\nend;\n\n{ Extracts assets from @folder in the BSA @filename to @destination }\nprocedure ExtractBSA(ContainerName, folder, destination: string);\nvar\n  ResourceList: TStringList;\n  i: Integer;\nbegin\n  if not wbContainerHandler.ContainerExists(ContainerName) then begin\n    Tracker.Write('    '+ContainerName+' not loaded.');\n    exit;\n  end;\n  ResourceList := TStringList.Create;\n  wbContainerHandler.ContainerResourceList(ContainerName, ResourceList, folder);\n  for i := 0 to Pred(ResourceList.Count) do\n    wbContainerHandler.ResourceCopy(ContainerName, ResourceList[i], destination);\nend;\n\n{ Extracts assets from the BSA @filename to @destination, ignoring assets\n  matching items in @ignore }\nprocedure ExtractBSA(ContainerName, destination: string; var ignore: TStringList);\nvar\n  ResourceList: TStringList;\n  i, j: Integer;\n  skip: boolean;\nbegin\n  if not wbContainerHandler.ContainerExists(ContainerName) then begin\n    Tracker.Write('    '+ContainerName+' not loaded.');\n    exit;\n  end;\n  ResourceList := TStringList.Create;\n  wbContainerHandler.ContainerResourceList(ContainerName, ResourceList, '');\n  for i := 0 to Pred(ResourceList.Count) do begin\n    skip := false;\n    for j := 0 to Pred(ignore.Count) do begin\n      skip := Pos(ignore[j], ResourceList[i]) > 0;\n      if skip then break;\n    end;\n\n    if skip then continue;\n    wbContainerHandler.ResourceCopy(ContainerName, ResourceList[i], destination);\n  end;\nend;\n\nfunction RemoveSelfOrContainer(const aElement: IwbElement): Boolean;\nvar\n  cElement: IwbElement;\nbegin\n  Result := false;\n  if aElement.IsRemoveable then begin\n    aElement.Remove;\n    Result := true;\n  end\n  else begin\n    if not Assigned(aElement.Container) then begin\n      Tracker.Write('    Element has no container!');\n      exit;\n    end;\n    // if element isn't removable, try removing its container\n    if Supports(aElement.Container, IwbMainRecord) then begin\n      Tracker.Write('    Reached main record, cannot remove element');\n      exit;\n    end;\n    Tracker.Write('    Failed to remove '+aElement.Path+', removing container');\n    if Supports(aElement.Container, IwbElement, cElement) then\n      Result := RemoveSelfOrContainer(cElement);\n  end;\nend;\n\nprocedure UndeleteAndDisable(const aRecord: IwbMainRecord);\nvar\n  xesp: IwbElement;\n  sig: string;\n  container: IwbContainerElementRef;\nbegin\n  try\n    sig := aRecord.Signature;\n\n    // undelete\n    aRecord.IsDeleted := true;\n    aRecord.IsDeleted := false;\n\n    // set persistence flag depending on game\n    if (wbGameMode in [gmFO3,gmFNV,gmTES5])\n    and ((sig = 'ACHR') or (sig = 'ACRE')) then\n      aRecord.IsPersistent := true\n    else if wbGameMode = gmTES4 then\n      aRecord.IsPersistent := false;\n\n      // place it below the ground\n    if not aRecord.IsPersistent then\n      aRecord.ElementNativeValues['DATA\\Position\\Z'] := -30000;\n\n    // remove elements\n    aRecord.RemoveElement('Enable Parent');\n    aRecord.RemoveElement('XTEL');\n\n    // add enabled opposite of player (true - silent)\n    xesp := aRecord.Add('XESP', True);\n    if Assigned(xesp) and Supports(xesp, IwbContainerElementRef, container) then begin\n      container.ElementNativeValues['Reference'] := $14; // Player ref\n      container.ElementNativeValues['Flags'] := 1;  // opposite of parent flag\n    end;\n\n    // set to disable\n    aRecord.IsInitiallyDisabled := true;\n  except\n    on x: Exception do\n      Tracker.Write('    Exception: '+x.Message);\n  end;\nend;\n\n\nfunction FixErrors(const aElement: IwbElement; lastRecord: IwbMainRecord;\n  var errors: TStringList): IwbMainRecord;\nconst\n  cUDR = 'Record marked as deleted but contains:';\n  cUnresolved = '< Error: Could not be resolved >';\n  cNULL = 'Found a NULL reference, expected:';\nvar\n  Error: string;\n  Container: IwbContainerElementRef;\n  i: Integer;\nbegin\n  if Tracker.Cancel then\n    exit;\n\n  // update progress based on number of main records processed\n  if Supports(aElement, IwbMainRecord) then\n    Tracker.UpdateProgress(1);\n\n  Error := aElement.Check;\n  if Error <> '' then begin\n    Result := aElement.ContainingMainRecord;\n    // fix record marked as deleted errors (UDRs)\n    if Pos(cUDR, Error) = 1 then begin\n      if Assigned(Result) then begin\n        Tracker.Write('  Fixing UDR: '+Result.Name);\n        UndeleteAndDisable(Result);\n      end;\n    end\n    else begin\n      // fix unresolved FormID errors by NULLing them out\n      if Pos(cUnresolved, Error) > 0 then begin\n        Tracker.Write('  Fixing Unresolved FormID: '+aElement.Path);\n        aElement.NativeValue := 0;\n        // we may end up with an invalid NULL reference, so we Check again\n        Error := aElement.Check;\n        if Error = '' then exit;\n      end;\n\n      // fix invalid NULL references by removal\n      if Pos(cNULL, Error) = 1 then begin\n        Tracker.Write('  Removing NULL reference: '+aElement.Path);\n        if RemoveSelfOrContainer(aElement) then exit;\n      end;\n\n      // unhandled error\n      Tracker.Write(Format('  Unhandled error: %s -> %s', [aElement.Path, error]));\n      if Assigned(Result) and (lastRecord <> Result) then begin\n        lastRecord := Result;\n        errors.Add(Result.Name);\n      end;\n      errors.Add('  '+aElement.Path + ' -> ' + Error);\n    end;\n  end;\n\n  // done if element doesn't have children\n  if not Supports(aElement, IwbContainerElementRef, Container) then\n    exit;\n\n  // recurse through children elements\n  for i := Pred(Container.ElementCount) downto 0 do begin\n    Result := FixErrors(Container.Elements[i], Result, errors);\n    // break if container got deleted\n    if not Assigned(Container) then break;\n  end;\nend;\n\nfunction CheckForErrors(const aElement: IwbElement; lastRecord: IwbMainRecord;\n  var errors: TStringList): IwbMainRecord;\nvar\n  Error, msg: string;\n  Container: IwbContainerElementRef;\n  i: Integer;\nbegin\n  if Tracker.Cancel then\n    exit;\n\n  // update progress based on number of main records processed\n  if Supports(aElement, IwbMainRecord) then\n    Tracker.UpdateProgress(1);\n\n  Error := aElement.Check;\n  // log errors\n  if Error <> '' then begin\n    Result := aElement.ContainingMainRecord;\n    if Assigned(Result) and (Result <> LastRecord) then begin\n      Tracker.Write('  '+Result.Name);\n      errors.Add(Result.Name);\n    end;\n    msg := '  '+aElement.Path + ' -> ' + Error;\n    Tracker.Write('  '+msg);\n    errors.Add(msg);\n  end;\n\n  // recursion\n  if Supports(aElement, IwbContainerElementRef, Container) then\n    for i := Pred(Container.ElementCount) downto 0 do\n      Result := CheckForErrors(Container.Elements[i], Result, errors);\nend;\n\n{ Comparator for sorting plugins }\nfunction LoadOrderCompare(List: TStringList; Index1, Index2: Integer): Integer;\nvar\n  LO1, LO2: Integer;\nbegin\n  LO1 := Integer(List.Objects[Index1]);\n  LO2 := Integer(List.Objects[Index2]);\n  Result := LO1 - LO2;\nend;\n\n\n{******************************************************************************}\n{ Record Prototyping Functions\n  - GetElementObj\n  - CreateRecordObj\n  - GetRecordObj\n  - GetRecordDef\n  - BuildElementDef\n  - BuildRecordDef\n  - GetEditableFileContainer\n}\n{******************************************************************************}\n\n{\n  GetElementObj:\n  Gets the child json object from a node in a TSmashSetting tree\n  @obj matching @name.  Returns nil if a matching child is not\n  found.\n}\nfunction GetElementObj(var obj: ISuperObject; name: string): ISuperObject;\nvar\n  item: ISuperObject;\nbegin\n  Result := nil;\n  if not Assigned(obj) then\n    exit;\n  if not Assigned(obj['c']) then\n    exit;\n  for item in obj['c'] do begin\n    if item.S['n'] = name then begin\n      Result := item;\n      exit;\n    end;\n  end;\nend;\n\nfunction CreateRecordObj(var tree: ISuperObject; rec: IwbMainRecord): ISuperObject;\nvar\n  item: ISuperObject;\nbegin\n  item := SO;\n  item.S['n'] := rec.Signature;\n  item.I['t'] := Ord(stRecord);\n  tree.A['records'].Add(item);\n  Result := item;\nend;\n\nfunction GetRecordObj(var tree: ISuperObject; name: string): ISuperObject;\nvar\n  aSignature: TwbSignature;\n  item: ISuperObject;\nbegin\n  Result := nil;\n  aSignature := StrToSignature(name);\n  for item in tree['records'] do begin\n    if StrToSignature(item.S['n']) = aSignature then\n      Result := item;\n  end;\nend;\n\nfunction GetRecordDef(sig: TwbSignature): TwbRecordDefEntry;\nvar\n  i: Integer;\n  def: TwbRecordDefEntry;\nbegin\n  for i := Low(wbRecordDefs) to High(wbRecordDefs) do begin\n    def := wbRecordDefs[i];\n    if def.rdeSignature = sig then begin\n      Result := def;\n      exit;\n    end;\n  end;\nend;\n\nfunction BuildElementDef(element: IwbElement): ISuperObject;\nvar\n  container: IwbContainerElementRef;\n  i: Integer;\n  childElement: IwbElement;\nbegin\n  // release object if something goes wrong\n  Result := SO;\n  try\n    Result.S['n'] := element.Name;\n    Result.I['t'] := Ord(GetSmashType(element));\n\n    // populate element children, if it supports them\n    if not Supports(element, IwbContainerElementRef, container) then\n      exit;\n    // assign to container if it doesn't have element but can hold them\n    if (container.ElementCount = 0)\n    and container.CanAssign(High(Integer), nil, false) then try\n      container.Assign(High(Integer), nil, false);\n    except\n      // oops, container assignment failed\n      // this catches an assertion error when assigning to a DOBJ record\n      on x: Exception do\n        exit;\n    end;\n\n    // if we have children, make children array and recurse\n    if container.ElementCount > 0 then begin\n      Result.O['c'] := SA([]);\n      // traverse children\n      for i := 0 to Pred(container.ElementCount) do begin\n        childElement := container.Elements[i];\n        Result.A['c'].Add(BuildElementDef(childElement));\n      end;\n    end;\n  except\n    on x: Exception do begin\n      Result._Release;\n      raise x;\n    end;\n  end;\nend;\n\nfunction IsUnionDef(def: IwbNamedDef; out unionDef: IwbUnionDef): Boolean;\nvar\n  subDef: IwbSubRecordDef;\nbegin\n  if Supports(def, IwbSubRecordDef, subDef) then\n    Result := Supports(subDef.GetValue, IwbUnionDef, unionDef)\n  else\n    Result := Supports(def, IwbUnionDef, unionDef);\nend;\n\nfunction HasDef(recObj: ISuperObject; name: String): Boolean;\nvar\n  i: Integer;\nbegin\n  Result := False;\n  for i := 0 to Pred(recObj.A['c'].Length) do\n    if recObj.A['c'].O[i].S['n'] = name then begin\n      Result := True;\n      exit;\n    end;\nend;\n\nprocedure AddDefIfMissing(recObj: ISuperObject; def: IwbNamedDef; name: String);\nbegin\n  if not HasDef(recObj, name) then\n    recObj.A['c'].Add(BuildDef(def, name));\nend;\n\nfunction SigToStr(sig: TwbSignature): String;\nvar\n  i: Integer;\nbegin\n  for i := Low(sig) to High(sig) do\n    if Ord(sig[i]) < 32 then\n      sig[i] := AnsiChar(Ord('a') + Ord(sig[i]));\n  Result := sig;\nend;\n\nprocedure BuildChildDef(def: IwbNamedDef; recObj: ISuperObject);\nvar\n  i: Integer;\n  unionDef: IwbUnionDef;\n  sigDef: IwbSignatureDef;\n  recDef: IwbRecordDef;\n  name: String;\nbegin\n  if IsUnionDef(def, unionDef) then begin\n    for i := 0 to Pred(unionDef.MemberCount) do\n      BuildChildDef(unionDef.Members[i] as IwbNamedDef, recObj);\n  end\n  else if Supports(def, IwbSubRecordUnionDef) and Supports(def, IwbRecordDef, recDef) then begin\n    for i := 0 to Pred(recDef.MemberCount) do\n      BuildChildDef(recDef.Members[i] as IwbNamedDef, recObj);\n  end\n  else if Supports(def, IwbSignatureDef, sigDef) then begin\n    name := SigToStr(sigDef.DefaultSignature) + ' - ' + sigDef.Name;\n    AddDefIfMissing(recObj, def, name);\n  end\n  else\n    AddDefIfMissing(recObj, def, def.Name);\nend;\n\nprocedure BuildChildDefs(obj: ISuperObject; def: IwbNamedDef);\nvar\n  i: Integer;\n  subDef: IwbSubRecordDef;\n  recDef: IwbRecordDef;\n  unionDef: IwbUnionDef;\n  structDef: IwbStructDef;\n  intDef: IwbIntegerDefFormaterUnion;\n  sraDef: IwbSubRecordArrayDef;\n  aDef: IwbArrayDef;\nbegin\n  // try SubRecordDef ValueDef\n  if Supports(def, IwbSubRecordDef, subDef) then\n    BuildChildDefs(obj, subDef.GetValue as IwbNamedDef)\n  // try IwbRecordDef\n  else if Supports(def, IwbRecordDef, recDef) then begin\n    if recDef.MemberCount = 0 then exit;\n    obj.O['c'] := SA([]);\n    for i := 0 to Pred(recDef.MemberCount) do\n      BuildChildDef(recDef.Members[i] as IwbNamedDef, obj);\n  end\n  // try IwbUnionDef\n  else if Supports(def, IwbUnionDef, unionDef) then begin\n    if unionDef.MemberCount = 0 then exit;\n    obj.O['c'] := SA([]);\n    for i := 0 to Pred(unionDef.MemberCount) do\n      BuildChildDef(unionDef.Members[i] as IwbNamedDef, obj);\n  end\n  // try IwbStructDef\n  else if Supports(def, IwbStructDef, structDef) then begin\n    if structDef.MemberCount = 0 then exit;\n    obj.O['c'] := SA([]);\n    for i := 0 to Pred(structDef.MemberCount) do\n      BuildChildDef(structDef.Members[i] as IwbNamedDef, obj);\n  end\n  // try IwbIntegerDefFormaterUnion\n  else if Supports(def, IwbIntegerDefFormaterUnion, intDef) then begin\n    if intDef.MemberCount = 0 then exit;\n    obj.O['c'] := SA([]);\n    for i := 0 to Pred(intDef.MemberCount) do\n      BuildChildDef(intDef.Members[i] as IwbNamedDef, obj);\n  end\n  // try IwbSubRecordArrayDef\n  else if Supports(def, IwbSubRecordArrayDef, sraDef) then begin\n    obj.O['c'] := SA([]);\n    BuildChildDef(sraDef.Element as IwbNamedDef, obj);\n  end\n  // try IwbArrayDef\n  else if Supports(def, IwbArrayDef, aDef) then begin\n    obj.O['c'] := SA([]);\n    BuildChildDef(aDef.Element as IwbNamedDef, obj);\n  end;\nend;\n\nfunction BuildDef(def: IwbNamedDef; name: string): ISuperObject;\nbegin\n  // release object if something goes wrong\n  Result := SO;\n  try\n    Result.S['n'] := name;\n    Result.I['t'] := Ord(SmashType(def));\n    BuildChildDefs(Result, def);\n  except\n    on x: Exception do begin\n      Result._Release;\n      raise x;\n    end;\n  end;\nend;\n\nfunction BuildRecordDef(sName: string; mrDef: IwbRecordDef; out recObj: ISuperObject): boolean; overload;\nvar\n  i: Integer;\nbegin\n  recObj := SO;\n  try\n    recObj.S['n'] := sName;\n    recObj.I['t'] := Ord(stRecord);\n    recObj.O['c'] := SA([]);\n    for i := 0 to Pred(mrDef.MemberCount) do\n      BuildChildDef(mrDef.Members[i] as IwbNamedDef, recObj);\n  except\n    on x: Exception do begin\n      recObj._Release;\n      raise x;\n    end;\n  end;\n\n  // if everything completed, result is object we made\n  Result := true;\nend;\n\nfunction BuildRecordDef(sName: string; out recObj: ISuperObject): boolean;\nvar\n  def: TwbRecordDefEntry;\nbegin\n  def := GetRecordDef(StrToSignature(sName));\n  Result := BuildRecordDef(sName, def.rdeDef, recObj);\nend;\n\nfunction GetEditableFileContainer: IwbContainerElementRef;\nvar\n  i: Integer;\n  aPlugin: TBasePlugin;\n  aFile: IwbFile;\n  Container: IwbContainerElementRef;\nbegin\n  Result := nil;\n  i := 0;\n  repeat\n    // exit if max index reached\n    if i > Pred(PluginsList.Count) then\n      exit;\n\n    // get next plugin\n    aPlugin := TBasePlugin(PluginsList[i]);\n    Inc(i);\n\n    // exit if file is invalid\n    aFile := aPlugin._File;\n    if not Supports(aFile, IwbContainerElementRef, Container) then\n      exit;\n  until Container.IsElementEditable(nil);\n  Result := Container;\nend;\n\nprocedure PopulateAddList(var AddItem: TMenuItem; Event: TNotifyEvent);\nvar\n  i: Integer;\n  RecordDef: PwbRecordDef;\n  item: TMenuItem;\nbegin\n  // populate wbGroupOrder to additem\n  with TStringList.Create do try\n    Sorted := True;\n    Duplicates := dupIgnore;\n\n    // initialize list contents\n    AddStrings(wbGroupOrder);\n    Sorted := False;\n\n    // get record def names, if available\n    for i := Pred(Count) downto 0 do\n      if wbFindRecordDef(AnsiString(Strings[i]), RecordDef) then\n        Strings[i] := Strings[i] + ' - ' + RecordDef.Name\n      else\n        Delete(i);\n\n    // populate menu items\n    for i := 0 to Pred(Count) do begin\n      if Length(Strings[i]) < 4 then\n        continue;\n      item := TMenuItem.Create(AddItem);\n      item.Caption := Strings[i];\n      item.OnClick := Event;\n      AddItem.Add(item);\n    end;\n  finally\n    Free;\n  end;\nend;\n\ninitialization\nbegin\n  PluginsList := TList.Create;\nend;\n\nfinalization\nbegin\n  FreeList(PluginsList);\nend;\n\nend.\n"
  },
  {
    "path": "lib/mte/mteChangeLogForm.dfm",
    "content": "object ChangeLogForm: TChangeLogForm\n  Left = 0\n  Top = 0\n  Caption = 'Update Available'\n  ClientHeight = 342\n  ClientWidth = 366\n  Color = clBtnFace\n  Constraints.MaxHeight = 1000\n  Constraints.MaxWidth = 382\n  Constraints.MinHeight = 300\n  Constraints.MinWidth = 382\n  Font.Charset = DEFAULT_CHARSET\n  Font.Color = clWindowText\n  Font.Height = -11\n  Font.Name = 'Tahoma'\n  Font.Style = []\n  OldCreateOrder = False\n  Position = poScreenCenter\n  OnCreate = FormCreate\n  PixelsPerInch = 96\n  TextHeight = 13\n  object LabelPrompt: TLabel\n    Left = 8\n    Top = 8\n    Width = 51\n    Height = 13\n    Caption = 'Changelog'\n    WordWrap = True\n  end\n  object ScrollBox: TScrollBox\n    Left = 8\n    Top = 27\n    Width = 350\n    Height = 276\n    HorzScrollBar.Visible = False\n    VertScrollBar.Tracking = True\n    Align = alCustom\n    Anchors = [akLeft, akTop, akRight, akBottom]\n    TabOrder = 0\n  end\n  object ButtonInstall: TButton\n    Left = 202\n    Top = 309\n    Width = 75\n    Height = 25\n    Align = alCustom\n    Anchors = [akRight, akBottom]\n    Caption = 'Install'\n    ModalResult = 1\n    TabOrder = 1\n  end\n  object ButtonSkip: TButton\n    Left = 283\n    Top = 309\n    Width = 75\n    Height = 25\n    Align = alCustom\n    Anchors = [akRight, akBottom]\n    Caption = 'Skip'\n    ModalResult = 2\n    TabOrder = 2\n  end\nend\n"
  },
  {
    "path": "lib/mte/mteChangeLogForm.pas",
    "content": "unit mteChangeLogForm;\n\ninterface\n\nuses\n  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,\n  Dialogs, StdCtrls,\n  // mte units\n  mteHelpers, RttiTranslation, mteLogger;\n\ntype\n  TChangeLogForm = class(TForm)\n    [FormPrefix('mpCha')]\n      ScrollBox: TScrollBox;\n      LabelPrompt: TLabel;\n      ButtonInstall: TButton;\n      ButtonSkip: TButton;\n\n    procedure FormCreate(Sender: TObject);\n    procedure CreateVersionLabel(line: string; var top: Integer);\n    procedure CreateLabel(line: string; var top: Integer);\n    procedure DisplayChangelog;\n  private\n    { Private declarations }\n  public\n    { Public declarations }\n  end;\n\n  // public entry point\n  function ChangeLogPrompt(AOwner: TComponent): boolean;\n\nconst\n  spacing = 5;\n  bTranslationDump = false;\n\nvar\n  clChangeLogForm: TChangeLogForm;\n  clChangelog: TStringList;\n  clProgramVersion: string;\n\nimplementation\n\n{$R *.dfm}\n\nprocedure TChangeLogForm.FormCreate(Sender: TObject);\nbegin\n  {// do a translation dump?\n  if bTranslationDump then\n    TRttiTranslation.Save('lang\\english.lang', self);\n\n  // load translation\n  TRttiTranslation.Load(language, self);}\n\n  // display changelog\n  DisplayChangelog;\nend;\n\nfunction IsVersionLine(line: string): boolean;\nbegin\n  Result := Pos('Version ', line) = 1;\nend;\n\nprocedure TChangeLogForm.CreateVersionLabel(line: string; var top: Integer);\nvar\n  lbl: TLabel;\nbegin\n  // make version label\n  lbl := TLabel.Create(ScrollBox);\n  lbl.Parent := ScrollBox;\n  lbl.Autosize := true;\n  lbl.Top := top;\n  lbl.Left := 8;\n  lbl.Caption := line;\n  lbl.Font.Style := [fsBold];\n\n  // increment top for next label\n  Inc(top, lbl.Height + spacing);\nend;\n\nprocedure TChangeLogForm.CreateLabel(line: string; var top: Integer);\nvar\n  lbl: TLabel;\nbegin\n  // make label\n  lbl := TLabel.Create(ScrollBox);\n  lbl.Parent := ScrollBox;\n  lbl.AutoSize := true;\n  lbl.WordWrap := true;\n  lbl.Top := top;\n  lbl.Left := 20;\n  lbl.Width := ScrollBox.ClientWidth - 36;\n  lbl.Caption := Trim(line);\n\n  // increment top for next label\n  Inc(top, lbl.Height + spacing);\nend;\n\nprocedure TChangeLogForm.DisplayChangelog;\nvar\n  i, top, start: Integer;\n  line, lineVersion: string;\nbegin\n  // find start line\n  start := 0;\n  if not Assigned(clChangelog) then\n    exit;\n  for i := 0 to Pred(clChangelog.Count) do begin\n    line := clChangelog[i];\n    if not IsVersionLine(line) then\n      continue;\n\n    // identify start of changelog as first version newer than current version\n    lineVersion := Copy(line, 9, Length(line));\n    if VersionCompare(clProgramVersion, lineVersion) then begin\n      start := i;\n      break;\n    end;\n  end;\n\n  // loop through the changelog, creating labels in scrollbox\n  // as necessary to render text\n  top := 8;\n  for i := start to Pred(clChangelog.Count) do begin\n    line := clChangelog[i];\n    if IsVersionLine(line) then\n      CreateVersionLabel(line, top)\n    else\n      CreateLabel(line, top);\n  end;\nend;\n\nprocedure LoadChangelog(var changelog: TStringList);\nbegin\n  // load changelog\n  if not Assigned(changelog) then\n    changelog := TStringList.Create;\n\n  // don't attempt to load changelog if it doesn't exist\n  if not FileExists('changelog.txt') then begin\n    Logger.Write('GENERAL', 'Changelog', 'No changelog found');\n    exit;\n  end;\n\n  // load changelog\n  changelog.LoadFromFile('changelog.txt');\nend;\n\nfunction ChangeLogPrompt(AOwner: TComponent): boolean;\nvar\n  clForm: TChangeLogForm;\nbegin\n  Result := false;\n\n  // if we don't have a changelog, exit returning false\n  if not FileExists('changelog.txt') then\n    exit;\n\n  // create change log form\n  LoadChangelog(clChangelog);\n  clForm := TChangeLogForm.Create(AOwner);\n  Result := clForm.ShowModal = mrOK;\n  clForm.Free;\nend;\n\nend.\n"
  },
  {
    "path": "lib/mte/mteHelpers.pas",
    "content": "unit mteHelpers;\n\ninterface\n\nuses\n  Windows, SysUtils, Forms, Classes, ComCtrls, Grids, StdCtrls, Types;\n\ntype\n  TCallback = procedure of object;\n  TAppHelpers = class\n    class procedure GetHelp(var Msg: TMsg; var Handled: Boolean);\n    class function HandleHelp(Command: Word; Data: Integer; var CallHelp: Boolean): Boolean;\n  end;\n\n  { General functions }\n  function ShortenVersion(vs: string; numClauses: Integer): string;\n  function IfThenInt(AValue: boolean; ATrue: Integer = 1; AFalse: Integer = 0): Integer;\n  function TitleCase(sText: String): String;\n  function SentenceCase(sText: string): string;\n  function csvText(s: string): string;\n  function CopyFromTo(str: string; first, last: Integer): string;\n  function GetTextIn(str: string; open, close: char): string;\n  function FormatByteSize(const bytes: Int64): string;\n  function DateBuiltString(date: TDateTime): string;\n  function DateTimeToSQL(date: TDateTime): string;\n  function SQLToDateTime(date: string): TDateTime;\n  function RateStr(date: TDateTime): string;\n  function TimeStr(date: TDateTime): string;\n  function AppendIfMissing(str, substr: string): string;\n  function StrEndsWith(s1, s2: string): boolean;\n  function RemoveFromEnd(s1, s2: string): string;\n  function IntegerListSum(list: TStringList; maxIndex: integer): integer;\n  function Wordwrap(s: string; charCount: integer): string;\n  function ExtractPath(path: string; levels: integer): string;\n  function ContainsMatch(var sl: TStringList; const s: string): boolean;\n  procedure DeleteMatchingItems(item: string; var sl: TStringList);\n  function IsURL(s: string): boolean;\n  function IsDotFile(fn: string): boolean;\n  procedure SaveStringToFile(s: string; fn: string);\n  function ApplyTemplate(const template: string; var map: TStringList): string;\n  function VersionCompare(v1, v2: string): boolean;\n  procedure TryToFree(obj: TObject);\n  procedure FreeList(var lst: TList);\n  { Windows API functions }\n  procedure ForceForeground(hWnd: THandle);\n  function GetDriveList: TStringDynArray;\n  function DOSDrive(const sDrive: String ): Integer;\n  function DriveReady(const sDrive: String): Boolean;\n  function TryRegistryKeys(var keys: TStringList): string;\n  function FileNameValid(filename: string): boolean;\n  function DirectoryValid(dir: string): boolean;\n  function UpDirectory(sPath: string): string;\n  function DeleteToRecycleBin(const path: string; Confirm: Boolean): Boolean;\n  procedure ExecNewProcess(ProgramName: string; synchronous: Boolean);\n  procedure BrowseForFile(var ed: TEdit; filter, initDir: string);\n  procedure BrowseForFolder(var ed: TEdit; initDir: string);\n  function GetCSIDLShellFolder(CSIDLFolder: integer): string;\n  function GetFileSize(const aFilename: String): Int64;\n  function GetLastModified(const aFileName: String): TDateTime;\n  function SearchPathsForFile(sPaths, sFileName: string): string;\n  function MultFileSearch(paths, filenames, ignore: array of string;\n    maxDepth: integer): string;\n  function RecursiveFileSearch(aPath: string; filenames, ignore: array of string;\n   maxDepth: integer): string;\n  procedure CopyDirectory(src, dst: string; fIgnore, dIgnore: TStringList);\n  procedure GetFilesList(path: string; var fIgnore, dIgnore, list: TStringList);\n  procedure CopyFiles(src, dst: string; var list: TStringList);\n  function GetVersionMem: string;\n  function FileVersion(const FileName: string): String;\n  procedure DeleteDirectory(const path: string);\n  procedure PerformFileSystemTests(sBasePath: string);\n  { GUI Helper Functions }\n  procedure StringGrid_CorrectWidth(var sg: TStringGrid);\n  procedure ListView_CorrectWidth(var lv: TListView);\n  function ListView_NextMatch(ListView: TListView; sSearch: string;\n    iIndex: Integer): Integer;\n  procedure ListView_HandleMatch(ListView: TListView; iFoundIndex: Integer;\n    var sBuffer: string; sTempBuffer: string);\n\nconst\n  wndBorderSide = 8;\n  wndBorderTop = 30;\n\n  // TIME TRACKING\n  days = 1.0;\n  hours = 1.0 / 24.0;\n  minutes = hours / 60.0;\n  seconds = minutes / 60.0;\n\nvar\n  bAllowHelp: boolean;\n  enFormatSettings: TFormatSettings;\n\nimplementation\n\nuses\n  Controls, Masks, Dialogs, StrUtils, FileCtrl, ShellApi,\n  Messages, CommCtrl, DateUtils, shlObj, IOUtils, Registry;\n\n\n{******************************************************************************}\n{ Application Helpers\n  General helpers for applications\n}\n{******************************************************************************}\n\nclass procedure TAppHelpers.GetHelp(var Msg: TMsg; var Handled: Boolean);\nvar\n  control: TControl;\n  sKeyword: string;\nbegin\n  if (Msg.message = WM_KEYDOWN) and (LoWord(Msg.wParam) = VK_F1) then begin\n    Screen.Cursor := crHelp;\n    Handled := true;\n  end\n  else if (Msg.message = WM_LBUTTONDOWN) and (Screen.Cursor = crHelp) then begin\n    // get control the user clicked on\n    control := FindVCLWindow(Mouse.CursorPos);\n    // if we found a control, jump to help keyword for that control\n    if Assigned(control) then begin\n      bAllowHelp := true;\n      sKeyword := control.HelpKeyword;\n      while (sKeyword = '') and Assigned(control.Parent) do begin\n        control := control.Parent;\n        sKeyword := control.HelpKeyword;\n      end;\n      Application.HelpKeyword(sKeyword);\n      Screen.Cursor := crDefault;\n      Handled := true;\n    end;\n  end;\nend;\n\nclass function TAppHelpers.HandleHelp(Command: Word; Data: Integer;\n  var CallHelp: Boolean): Boolean;\nbegin\n  CallHelp := bAllowHelp;\n  bAllowHelp := false;\n  Result := true;\nend;\n\n\n{******************************************************************************}\n{ General functions\n  Set of functions that help with converting data types and handling strings.\n\n  List of functions:\n  - IfThenInt\n  - TitleCase\n  - SentenceCase\n  - csvText\n  - CopyFromTo\n  - GetTextIn\n  - FormatByteSize\n  - DateBuiltString\n  - DateTimeToSQL\n  - SQLToDateTime\n  - RateStr\n  - TimeStr\n  - AppendIfMissing\n  - StrEndsWith\n  - RemoveFromEnd\n  - IntegerListSum\n  - Wordwrap\n  - ExtractPath\n  - ContainsMatch\n  - IsURL\n  - IsDotFile\n  - SaveStringToFile\n  - ApplyTemplate\n}\n{*****************************************************************************}\n\nfunction ShortenVersion(vs: string; numClauses: Integer): string;\nvar\n  i, numDots: Integer;\nbegin\n  Result := '';\n  numDots := 0;\n  for i := 1 to Pred(Length(vs)) do begin\n    if vs[i] = '.' then\n      Inc(numDots);\n    if numDots = numClauses then\n      break;\n    Result := Result + vs[i];\n  end;\nend;\n\n{ Returns one of two integers based on a boolean argument.\n  Like IfThen from StrUtils, but returns an Integer. }\nfunction IfThenInt(AValue: boolean; ATrue: Integer = 1; AFalse: Integer = 0): Integer;\nbegin\n  if AValue then\n    Result := ATrue\n  else\n    Result := AFalse;\nend;\n\n{ Capitalizes the first letter of each word }\nfunction TitleCase(sText: String): String;\nconst\n  cDelimiters = [#9, #10, #13, ' ', ',', '.', ':', ';', '\"',\n                 '\\', '/', '(', ')', '[', ']', '{', '}'];\nvar\n  iLoop: Integer;\nbegin\n  Result := sText;\n  if (Result <> '') then begin\n    Result := LowerCase(Result);\n\n    Result[1] := UpCase(Result[1]);\n    for iLoop := 2 to Length(Result) do\n      if (Result[iLoop - 1] in cDelimiters) then\n        Result[iLoop] := UpCase(Result[iLoop]);\n  end;\nend;\n\n{ Capitalizes first character of each sentence }\nfunction SentenceCase(sText: string): string;\nconst\n  cTerminators = ['!', '.', '?'];\nvar\n  iLoop: Integer;\n  bTerminated: boolean;\nbegin\n  Result := sText;\n  if (Result <> '') then begin\n    Result := LowerCase(Result);\n\n    Result[1] := UpCase(Result[1]);\n    bTerminated := false;\n    for iLoop := 2 to Length(Result) do begin\n      if (Result[iLoop - 1] in cTerminators) then\n        bTerminated := true;\n      if bTerminated and (Result[iLoop] <> ' ') then\n        Result[iLoop] := UpCase(Result[iLoop]);\n    end;\n  end;\nend;\n\n{ Replaces newlines with a comma and space }\nfunction csvText(s: string): string;\nbegin\n  result := StringReplace(Trim(s), #13, ', ', [rfReplaceAll]);\nend;\n\n{ Copies a substring in a string between two indexes }\nfunction CopyFromTo(str: string; first, last: Integer): string;\nbegin\n  Result := Copy(str, first, (last - first) + 1);\nend;\n\n{ Returns a substring of @str between characters @open and @close }\nfunction GetTextIn(str: string; open, close: char): string;\nvar\n  i, openIndex: integer;\n  bOpen: boolean;\nbegin\n  Result := '';\n  bOpen := false;\n  openIndex := 0;\n  for i := 0 to Length(str) do begin\n    if not bOpen and (str[i] = open) then begin\n      openIndex := i;\n      bOpen := true;\n    end;\n    if bOpen and (str[i] = close) then begin\n      Result := CopyFromTo(str, openIndex + 1, i - 1);\n      break;\n    end;\n  end;\nend;\n\n{ Format file byte size }\nfunction FormatByteSize(const bytes: Int64): string;\nconst\n B = 1; //byte\n KB = 1024 * B; //kilobyte\n MB = 1024 * KB; //megabyte\n GB = 1024 * MB; //gigabyte\nbegin\n  if bytes > GB then\n    result := FormatFloat('#.## GB', bytes / GB)\n  else\n    if bytes > MB then\n      result := FormatFloat('#.## MB', bytes / MB)\n    else\n      if bytes > KB then\n        result := FormatFloat('#.## KB', bytes / KB)\n      else\n        if bytes > 0 then\n          result := FormatFloat('#.## bytes', bytes)\n        else\n          result := '0 bytes';\nend;\n\n{ Converts a TDateTime to a string, with 0 being the string 'Never' }\nfunction DateBuiltString(date: TDateTime): string;\nbegin\n  if date = 0 then\n    Result := 'Never'\n  else begin\n    Result := DateTimeToStr(date);\n  end;\nend;\n\nfunction DateTimeToSQL(date: TDateTime): string;\nbegin\n  Result := FormatDateTime('yyyy-mm-dd hh:mm:ss', date);\nend;\n\nfunction SQLToDateTime(date: string): TDateTime;\nvar\n  fs: TFormatSettings;\nbegin\n  GetLocaleFormatSettings(GetThreadLocale, fs);\n  fs.DateSeparator := '-';\n  fs.ShortDateFormat := 'yyyy-mm-dd';\n  fs.TimeSeparator := ':';\n  fs.LongTimeFormat := 'hh:nn:ss';\n  Result := StrToDateTime(date, fs);\nend;\n\n{ Converts a TDateTime to a rate string, e.g. Every 24.0 hours }\nfunction RateStr(date: TDateTime): string;\nbegin\n  if date > 1.0 then\n    Result := Format('Every %0.2f days', [date])\n  else if date * 24.0 > 1.0 then\n    Result := Format('Every %0.1f hours', [date * 24.0])\n  else if date * 24.0 * 60.0 > 1.0 then\n    Result := Format('Every %0.1f minutes', [date * 24.0 * 60.0])\n  else\n    Result := Format('Every %0.1f seconds', [date * 24.0 * 60.0 * 60.0]);\nend;\n\n{ Converts a TDateTime to a time string, e.g. 19d 20h 3m 30s }\nfunction TimeStr(date: TDateTime): string;\nbegin\n  Result := Format('%dd %dh %dm', [Trunc(date), HourOf(date), MinuteOf(date)]);\nend;\n\n{\n  StrEndsWith:\n  Checks to see if a string ends with an entered substring.\n\n  Example usage:\n  s := 'This is a sample string.';\n  if StrEndsWith(s, 'string.') then\n    AddMessage('It works!');\n}\nfunction StrEndsWith(s1, s2: string): boolean;\nvar\n  n1, n2: integer;\nbegin\n  Result := false;\n\n  n1 := Length(s1);\n  n2 := Length(s2);\n  if n1 < n2 then exit;\n\n  Result := (Copy(s1, n1 - n2 + 1, n2) = s2);\nend;\n\n{\n  AppendIfMissing:\n  Appends substr to the end of str if it's not already there.\n\n  Example usage:\n  s := 'This is a sample string.';\n  Logger.Write(AppendIfMissing(s, 'string.')); //'This is a sample string.'\n  Logger.Write(AppendIfMissing(s, '  Hello.')); //'This is a sample string.  Hello.'\n}\nfunction AppendIfMissing(str, substr: string): string;\nbegin\n  Result := str;\n  if not StrEndsWith(str, substr) then\n    Result := str + substr;\nend;\n\n{\n  RemoveFromEnd:\n  Creates a new string with s1 removed from the end of s2, if found.\n\n  Example usage:\n  s := 'This is a sample string.';\n  AddMessage(RemoveFromEnd(s, 'string.')); //'This is a sample '\n}\nfunction RemoveFromEnd(s1, s2: string): string;\nbegin\n  Result := s1;\n  if StrEndsWith(s1, s2) then\n    Result := Copy(s1, 1, Length(s1) - Length(s2));\nend;\n\n{ Calculates the integer sum of all values in a TStringList to maxIndex }\nfunction IntegerListSum(list: TStringList; maxIndex: integer): integer;\nvar\n  i: Integer;\nbegin\n  Result := 0;\n  for i := 0 to maxIndex do\n    Inc(result, StrToInt(list[i]));\nend;\n\n{ Inserts line breaks in string @s before @charCount has been exceeded }\nfunction Wordwrap(s: string; charCount: integer): string;\nvar\n  i, lastSpace, counter: Integer;\nbegin\n  counter := 0;\n  lastSpace := 0;\n  for i := 1 to Length(s) - 1 do begin\n    Inc(counter);\n    if (s[i] = ' ') or (s[i] = ',') then\n      lastSpace := i;\n    if (s[i] = #13) or (s[i] = #10)\n    or (s[i + 1] = #13) or (s[i + 1] = #10) then begin\n      lastSpace := 0;\n      counter := 0;\n    end;\n    if (counter = charCount) and (lastSpace > 0) then begin\n      Insert(#13#10, s, lastSpace + 1);\n      lastSpace := 0;\n      counter := 0;\n    end;\n  end;\n  Result := s;\nend;\n\n{ Like ExtractFilePath, but will allow the user to specify how many @levels\n  they want to traverse back.  Specifying @levels = 0 is equivalent to\n  ExtractFilePath.\n\n  Example usage:\n  path := 'C:\\Program Files (x86)\\Test\\Test.exe';\n  ShowMessage(ExtractPath(path, 0)); // 'C:\\Program Files (x86)\\Test\\'\n  ShowMessage(ExtractPath(path, 1)); // 'C:\\Program Files (x86)\\'\n  ShowMessage(ExtractPath(path, 2)); // 'C:\\'\n}\nfunction ExtractPath(path: string; levels: integer): string;\nvar\n  i, n: integer;\nbegin\n  n := 0;\n  for i := Length(path) downto 1 do\n    if IsPathDelimiter(path, i) then begin\n      if n = levels then\n        break\n      else\n        Inc(n);\n    end;\n  Result := Copy(path, 1, i);\nend;\n\n{ Checks to see if any mask in @sl matches the string @s }\nfunction ContainsMatch(var sl: TStringList; const s: string): boolean;\nvar\n  i: Integer;\nbegin\n  Result := false;\n  for i := 0 to Pred(sl.Count) do\n    if MatchesMask(s, sl[i]) then begin\n      Result := true;\n      break;\n    end;\nend;\n\n{ Deletes items from @sl that match the input string @item }\nprocedure DeleteMatchingItems(item: string; var sl: TStringList);\nvar\n  i: Integer;\nbegin\n  for i := Pred(sl.Count) downto 0 do begin\n    if sl[i] = item then\n      sl.Delete(i);\n  end;\nend;\n\n{ Returns true if the string is an http:// or https:// url }\nfunction IsURL(s: string): boolean;\nbegin\n  Result := (Pos('http://', s) = 1) or (Pos('https://', s) = 1);\nend;\n\n{ Returns true if @fn is . or .. }\nfunction IsDotFile(fn: string): boolean;\nbegin\n  Result := (fn = '.') or (fn = '..');\nend;\n\n{ Saves a string @s to a file at @fn }\nprocedure SaveStringToFile(s: string; fn: string);\nvar\n  sl: TStringList;\nbegin\n  sl := TStringList.Create;\n  sl.Text := s;\n  sl.SaveToFile(fn);\n  sl.Free;\nend;\n\nfunction ApplyTemplate(const template: string; var map: TStringList): string;\nconst\n  openTag = '{{';\n  closeTag = '}}';\nvar\n  i: Integer;\n  name, value: string;\nbegin\n  Result := template;\n  for i := 0 to Pred(map.Count) do begin\n    name := map.Names[i];\n    value := map.ValueFromIndex[i];\n    Result := StringReplace(Result, openTag + name + closeTag, value, [rfReplaceAll]);\n  end;\nend;\n\nfunction VersionCompare(v1, v2: string): boolean;\nvar\n  sl1, sl2: TStringList;\n  i, c1, c2: integer;\nbegin\n  Result := false;\n\n  // parse versions with . as delimiter\n  sl1 := TStringList.Create;\n  sl1.LineBreak := '.';\n  sl1.Text := v1;\n  sl2 := TStringList.Create;\n  sl2.LineBreak := '.';\n  sl2.Text := v2;\n\n  // look through each version clause and perform comparisons\n  i := 0;\n  while (i < sl1.Count) and (i < sl2.Count) do begin\n    c1 := StrToInt(sl1[i]);\n    c2 := StrToInt(sl2[i]);\n    if (c1 < c2) then begin\n      Result := true;\n      break;\n    end\n    else if (c1 > c2) then begin\n      Result := false;\n      break;\n    end;\n    Inc(i);\n  end;\n\n  // free ram\n  sl1.Free;\n  sl2.Free;\nend;\n\nprocedure TryToFree(obj: TObject);\nbegin\n  if Assigned(obj) then try\n    obj.Free;\n  except\n    on x: Exception do // nothing\n  end;\nend;\n\nprocedure FreeList(var lst: TList);\nvar\n  i: Integer;\n  obj: TObject;\nbegin\n  for i := Pred(lst.Count) downto 0 do begin\n    obj := TObject(lst[i]);\n    TryToFree(obj);\n  end;\n  lst.Free;\nend;\n\n\n{******************************************************************************}\n{ Windows API functions\n  Set of functions that help deal with the Windows File System.\n\n  List of functions:\n  - ForceForeground\n  - FileNameValid\n  - RecycleDirectory\n  - ExecNewProcess\n  - BrowseForFile\n  - BrowseForFolder\n  - GetCSIDLShellFolder\n  - GetFileSize\n  - GetLastModified\n  - MultFileSearch\n  - RecursiveFileSearch\n  - CopyDirectory\n  - GetFilesList\n  - CopyFiles\n  - CorrectListViewWidth\n  - GetVersionMem\n  - FileVersion\n  - DeleteDirectory\n}\n{******************************************************************************}\n\n{\n  ForceForeground:\n  Forces a hWnd to the foreground.\n}\nprocedure ForceForeground(hWnd: THandle);\nbegin\n  SetWindowPos(hWnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOSIZE or SWP_NOACTIVATE or SWP_NOMOVE);\n  SetWindowPos(hWnd, HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOSIZE or SWP_NOACTIVATE or SWP_NOMOVE);\nend;\n\n{\n  GetDriveList:\n  Returns an array filled wit the assigned\n  drive letters on the current computer.\n}\n\nfunction GetDriveList: TStringDynArray;\nvar\n  Buff: array[0..128] of Char;\n  ptr: PChar;\n  Idx: Integer;\nbegin\n  if (GetLogicalDriveStrings(Length(Buff), Buff) = 0) then\n    RaiseLastOSError;\n  // There can't be more than 26 lettered drives (A..Z).\n  SetLength(Result, 26);\n\n  Idx := 0;\n  ptr := @Buff;\n  while StrLen(ptr) > 0 do\n  begin\n    Result[Idx] := ptr;\n    ptr := StrEnd(ptr);\n    Inc(ptr);\n    Inc(Idx);\n  end;\n  SetLength(Result, Idx);\nend;\n\n{\n  DOSDrive:\n  Converts a drive letter into the integer drive #\n  required by DiskSize().\n}\nfunction DOSDrive( const sDrive: String ): Integer;\nbegin\n  if (Length(sDrive) < 1) then\n    Result := -1\n  else\n    Result := (Ord(UpCase(sDrive[1])) - 64);\nend;\n\n{\n  DriveReady:\n  Tests the status of a drive to see if it's ready\n  to access.\n}\nfunction DriveReady(const sDrive: String): Boolean;\nvar\n  ErrMode: Word;\nbegin\n  ErrMode := SetErrorMode(0);\n  SetErrorMode(ErrMode or SEM_FAILCRITICALERRORS);\n  try\n    Result := (DiskSize(DOSDrive(sDrive)) > -1);\n  finally\n    SetErrorMode(ErrMode);\n  end;\nend;\n\n{\n  TryRegistryKeys:\n  Tries to load various registry keys.\n}\nfunction TryRegistryKeys(var keys: TStringList): string;\nvar\n  i: Integer;\n  path, name: string;\nbegin\n  Result := '';\n  with TRegistry.Create do try\n    RootKey := HKEY_LOCAL_MACHINE;\n\n    // try all keys\n    for i := 0 to Pred(keys.Count) do begin\n      path := ExtractFilePath(keys[i]);\n      name := ExtractFileName(keys[i]);\n      if OpenKeyReadOnly(path) then begin\n        Result := ReadString(name);\n        break;\n      end;\n    end;\n  finally\n    Free;\n  end;\nend;\n\n{\n  DirectoryValid:\n  Returns true if the input directory path is valid.\n}\nfunction DirectoryValid(dir: string): boolean;\nbegin\n  Result := false;\n  if (dir = '') then\n    exit;\n\n  dir := ExcludeTrailingPathDelimiter(dir);\n{$IFDEF MSWINDOWS}\n  if (Length(dir) < 3) or (ExtractFilePath(dir) = dir) then\n    exit; // avoid 'xyz:\\' problem.\n{$ENDIF}\n{$IFDEF POSIX}\n  if (dir = '') then\n    exit;\n{$ENDIF POSIX};\n  Result := true;\nend;\n\n{\n  UpDirectory:\n  Returns the path of the directory holding a directory.\n}\nfunction UpDirectory(sPath: string): string;\nbegin\n  if not StrEndsWith(sPath, '\\') then\n    sPath := ExtractFilePath(sPath);\n  Result := ExtractFilePath(RemoveFromEnd(sPath, '\\'));\nend;\n\n{\n  FileNameValid:\n  Returns true if the input filename is valid.\n}\nfunction FileNameValid(filename: string): boolean;\nbegin\n  Result := (Length(Trim(filename)) > 0) and\n    TPath.HasValidFileNameChars(filename, false);\nend;\n\n{\n  ExecNewProcess:\n  Create a new synchronous or asynchronous process.\n}\nprocedure ExecNewProcess(ProgramName: string; synchronous: Boolean);\nvar\n  StartInfo : TStartupInfo;\n  ProcInfo : TProcessInformation;\n  CreateOK : Boolean;\nbegin\n  { fill with known state }\n  FillChar(StartInfo, SizeOf(TStartupInfo), #0);\n  FillChar(ProcInfo, SizeOf(TProcessInformation), #0);\n  StartInfo.cb := SizeOf(TStartupInfo);\n  CreateOK := CreateProcess(PChar(ProgramName), nil, nil, nil,False,\n              CREATE_NEW_PROCESS_GROUP+NORMAL_PRIORITY_CLASS,\n              nil, nil, StartInfo, ProcInfo);\n\n  // check if successful\n  if CreateOK then begin\n    if synchronous then\n      WaitForSingleObject(ProcInfo.hProcess, INFINITE);\n  end\n  else\n    ShowMessage('Unable to run '+ProgramName);\n\n  // close handles\n  CloseHandle(ProcInfo.hProcess);\n  CloseHandle(ProcInfo.hThread);\nend;\n\n{\n  BrowseForFile:\n  Links a file selection through a TOpenDialog to the text stored in @ed,\n  applying filter @filter.\n}\nprocedure BrowseForFile(var ed: TEdit; filter, initDir: string);\nvar\n  openDialog: TOpenDialog;\nbegin\n  openDialog := TOpenDialog.Create(ed.Parent);\n\n  if FileExists(ed.Text) then\n    openDialog.InitialDir := ExtractFilePath(ed.Text)\n  else if DirectoryExists(ed.Text) then\n    openDialog.InitialDir := ed.Text\n  else\n    openDialog.InitialDir := initDir;\n\n  openDialog.Filter := filter;\n  if openDialog.Execute then\n    ed.Text := openDialog.FileName;\nend;\n\n{\n  BrowseForFolder:\n  Links a file selection through a TOpenDialog to the text stored in @ed,\n  applying filter @filter\n}\nprocedure BrowseForFolder(var ed: TEdit; initDir: string);\nvar\n  s: string;\nbegin\n  // start in current directory value if valid\n  if DirectoryExists(ed.Text) then\n    s := ed.Text\n  else\n    s := initDir;\n  // prompt user to select a directory\n  SelectDirectory('Select a directory', '', s, []);\n\n  // save text to TEdit\n  if s <> '' then\n    ed.Text := AppendIfMissing(s, '\\');\nend;\n\n{\n  GetCSIDLShellFolder:\n  Gets a folder by its integer CSID.\n}\nfunction GetCSIDLShellFolder(CSIDLFolder: integer): string;\nbegin\n  SetLength(Result, MAX_PATH);\n  SHGetSpecialFolderPath(0, PChar(Result), CSIDLFolder, True);\n  SetLength(Result, StrLen(PChar(Result)));\n  if (Result <> '') then\n    Result := IncludeTrailingBackslash(Result);\nend;\n\n{\n  GetFileSize:\n  Gets the size of a file at @aFilename through the windows API.\n}\nfunction GetFileSize(const aFilename: String): Int64;\nvar\n  info: TWin32FileAttributeData;\nbegin\n  result := -1;\n\n  if NOT GetFileAttributesEx(PWideChar(aFileName), GetFileExInfoStandard, @info) then\n    EXIT;\n\n  result := Int64(info.nFileSizeLow) or Int64(info.nFileSizeHigh shl 32);\nend;\n\n{\n  GetLastModified:\n  Gets the last time a file was modified.\n}\nfunction GetLastModified(const aFileName: String): TDateTime;\nvar\n  info: TWin32FileAttributeData;\n  FileTime: TFileTime;\n  LocalTime, SystemTime: TSystemTime;\nbegin\n  result := 0;\n  // exit if can't get attributes\n  if not GetFileAttributesEx(PWideChar(aFileName), GetFileExInfoStandard, @info) then\n    exit;\n\n  // get last modified\n  FileTime := info.ftLastWriteTime;\n\n  // convert to system time\n  if not FileTimeToSystemTime(FileTime, SystemTime) then\n    RaiseLastOSError;\n  if not SystemTimeToTzSpecificLocalTime(nil, SystemTime, LocalTime) then\n    RaiseLastOSError;\n\n  Result := SystemTimeToDateTime(LocalTime);\nend;\n\n{\n  SearchPathsForFile:\n  Searches for a file @sFileName in each path in @sPaths.\n}\nfunction SearchPathsForFile(sPaths, sFileName: string): string;\nvar\n  slPaths: TStringList;\n  i: Integer;\n  info: TSearchRec;\nbegin\n  slPaths := TStringList.Create;\n  try\n    while (Pos(';', sPaths) > 0) do begin\n      slPaths.Add(Copy(sPaths, 1, Pos(';', sPaths) - 1));\n      sPaths := Copy(sPaths, Pos(';', sPaths) + 1, Length(sPaths));\n    end;\n    for i := 0 to slPaths.Count - 1 do begin\n      if FindFirst(slPaths[i] + '\\*', faDirectory, info) = 0 then begin\n        repeat\n          Result := FileSearch(sFileName, slPaths[i] + '\\' + info.Name);\n          if (Result <> '') then\n            break;\n        until FindNext(info) <> 0;\n        FindClose(info);\n        // break if we found it\n        if (Result <> '') then\n          break;\n      end;\n    end;\n  finally\n    slPaths.Free;\n  end;\nend;\n\n{\n  MultFileSearch:\n  Wraps around RecursiveFileSearch, allowing the searching of multiple paths.\n}\nfunction MultFileSearch(paths, filenames, ignore: array of string; maxDepth: integer): string;\nvar\n  i: Integer;\n  path: string;\nbegin\n  for i := Low(paths) to High(paths) do begin\n    path := RecursiveFileSearch(paths[i], filenames, ignore, maxDepth);\n    if path <> '' then\n      break;\n  end;\n  Result := path;\nend;\n\n{\n  RecursiveFileSearch:\n  Recursively searches a path for a file matching @filenames, ignoring\n  directories in @ignore, and not traversing deeper than maxDepth.\n\n  Example usage:\n  p := RecursiveFileSearch(GamePath, filenames, ignore, 1);\n  AddMessage(p);\n}\nfunction RecursiveFileSearch(aPath: string; filenames, ignore: array of string;\n  maxDepth: integer): string;\nvar\n  skip: boolean;\n  i: integer;\n  info: TSearchRec;\nbegin\n  Result := '';\n  aPath := AppendIfMissing(aPath, PathDelim);\n  if Result <> '' then exit;\n\n  // exit if no files in path\n  if FindFirst(aPath + '*', faAnyFile, info) <> 0 then\n    exit;\n  // else loop through all files in path\n  repeat\n    if IsDotFile(info.Name) then\n      continue; // skip . and ..\n    skip := false;\n    for i := Low(ignore) to High(ignore) do begin\n      skip := Lowercase(info.Name) = ignore[i];\n      if skip then\n        break;\n    end;\n    if not skip then begin\n      if ((info.attr and faDirectory) = faDirectory) and (maxDepth > 0) then begin\n        Result := RecursiveFileSearch(aPath+info.Name, filenames, ignore, maxDepth - 1);\n      end\n      else if MatchStr(info.Name, filenames) then\n        Result := aPath + info.Name;\n    end;\n    if (Result <> '') then break;\n  until FindNext(info) <> 0;\n  FindClose(info);\nend;\n\n{\n  CopyDirectory:\n  Recursively copies all of the contents of a directory.\n\n  Example usage:\n  slIgnore := TStringList.Create;\n  slIgnore.Add('mteFunctions.pas');\n  CopyDirectory(ScriptsPath, 'C:\\ScriptsBackup', slIgnore);\n}\nprocedure CopyDirectory(src, dst: string; fIgnore, dIgnore: TStringList);\nvar\n  info: TSearchRec;\n  isDirectory: boolean;\nbegin\n  src := AppendIfMissing(src, PathDelim);\n  dst := AppendIfMissing(dst, PathDelim);\n\n  // if no files in source path, exit\n  if (FindFirst(src + '*', faAnyFile, info) <> 0) then\n    exit;\n  repeat\n    isDirectory := (info.Attr and faDirectory = faDirectory);\n    // skip . and ..\n    if (info.Name = '.') or (info.Name = '..') then\n      continue;\n\n    // skip if ignored\n    if isDirectory and ContainsMatch(dIgnore, info.Name) then\n      continue\n    else if ContainsMatch(fIgnore, info.Name) then\n      continue;\n\n    // copy the file or recurse\n    ForceDirectories(dst);\n    if isDirectory then\n      CopyDirectory(src+info.Name, dst+info.Name, fIgnore, dIgnore)\n    else\n      CopyFile(PChar(src+info.Name), PChar(dst+info.Name), false);\n  until FindNext(info) <> 0;\n\n  FindClose(info);\nend;\n\n{\n  GetFilesList:\n  Searches @path, recursively traversing subdirectories that don't match a mask\n  in @dIgnore, adding files that don't match a mask in @fIgnore to @list.\n\n  Example usage:\n  FilesList := TStringList.Create;\n  fileIgnore := TStringList.Create;\n  fileIgnore.Add('*.esp');\n  dirIgnore := TStringList.Create;\n  dirIgnore.Add('translations');\n  GetFilesList(wbDataPath, fileIgnore, dirIgnore, FilesList);\n}\nprocedure GetFilesList(path: string; var fIgnore, dIgnore, list: TStringList);\nvar\n  info: TSearchRec;\n  isDirectory: boolean;\nbegin\n  path := AppendIfMissing(path, PathDelim);\n\n  // if no files in source path, exit\n  if (FindFirst(path + '*', faAnyFile, info) <> 0) then\n    exit;\n  repeat\n    isDirectory := (info.Attr and faDirectory = faDirectory);\n    // skip . and ..\n    if (info.Name = '.') or (info.Name = '..') then\n      continue;\n\n    // skip if ignored\n    if isDirectory then begin\n      if ContainsMatch(dIgnore, info.Name) then\n        continue;\n    end\n    else if ContainsMatch(fIgnore, info.Name) then\n      continue;\n\n    // copy the file or recurse\n    if isDirectory then\n      GetFilesList(path + info.Name, fIgnore, dIgnore, list)\n    else\n      list.Add(path + info.Name);\n  until FindNext(info) <> 0;\n\n  FindClose(info);\nend;\n\n{ Copies files in @list from @src to @dst }\nprocedure CopyFiles(src, dst: string; var list: TStringList);\nvar\n  i: Integer;\n  srcFile, dstFile: string;\nbegin\n  src := AppendIfMissing(src, PathDelim);\n  dst := AppendIfMissing(dst, PathDelim);\n  for i := 0 to Pred(list.Count) do begin\n    srcFile := list[i];\n    dstFile := StringReplace(srcFile, src, dst, []);\n    ForceDirectories(ExtractFilePath(dstFile));\n    CopyFile(PChar(srcFile), PChar(dstFile), false);\n  end;\nend;\n\n{ Get program version from memory }\nfunction GetVersionMem: string;\nvar\n  verblock: PVSFIXEDFILEINFO;\n  versionMS, versionLS, verlen: cardinal;\n  rs: TResourceStream;\n  m: TMemoryStream;\nbegin\n  m := TMemoryStream.Create;\n  try\n    rs := TResourceStream.CreateFromID(HInstance, 1, RT_VERSION);\n    try\n      m.CopyFrom(rs, rs.Size);\n    finally\n      rs.Free;\n    end;\n    m.Position := 0;\n    if VerQueryValue(m.Memory, '\\', Pointer(verblock), verlen) then begin\n      VersionMS := verblock.dwFileVersionMS;\n      VersionLS := verblock.dwFileVersionLS;\n      Result := Format('%s.%s.%s.%s', [IntToStr(versionMS shr 16),\n        IntToStr(versionMS and $FFFF), IntToStr(VersionLS shr 16),\n        IntToStr(VersionLS and $FFFF)]);\n    end;\n  finally\n    m.Free;\n  end;\nend;\n\n{ Get program version from disk }\nfunction FileVersion(const FileName: string): String;\nvar\n  VerInfoSize: Cardinal;\n  VerValueSize: Cardinal;\n  Dummy: Cardinal;\n  PVerInfo: Pointer;\n  PVerValue: PVSFixedFileInfo;\nbegin\n  Result := '';\n  VerInfoSize := GetFileVersionInfoSize(PChar(FileName), Dummy);\n  GetMem(PVerInfo, VerInfoSize);\n  try\n    if GetFileVersionInfo(PChar(FileName), 0, VerInfoSize, PVerInfo) then\n      if VerQueryValue(PVerInfo, '\\', Pointer(PVerValue), VerValueSize) then\n        with PVerValue^ do\n          Result := Format('%d.%d.%d.%d', [\n            HiWord(dwFileVersionMS), //Major\n            LoWord(dwFileVersionMS), //Minor\n            HiWord(dwFileVersionLS), //Release\n            LoWord(dwFileVersionLS)]); //Build\n  finally\n    FreeMem(PVerInfo, VerInfoSize);\n  end;\nend;\n\n{ Sends the file/directory at @path to the recycle bin }\nfunction DeleteToRecycleBin(const path: string; Confirm: Boolean): Boolean;\nvar\n  sh: TSHFileOpStruct;\nbegin\n  FillChar(sh, SizeOf(sh), 0);\n  with sh do begin\n    Wnd := 0;\n    wFunc := FO_DELETE;\n    pFrom := PChar(path + #0);\n    fFlags := FOF_SILENT or FOF_ALLOWUNDO;\n    if not Confirm then\n      fFlags := fFlags or FOF_NOCONFIRMATION;\n  end;\n  Result := SHFileOperation(sh) = 0;\nend;\n\n{ Deletes the directory at @path and all files it contains }\nprocedure DeleteDirectory(const path: string);\nvar\n  ShOp: TSHFileOpStruct;\nbegin\n  ShOp.Wnd := 0;\n  ShOp.wFunc := FO_DELETE;\n  ShOp.pFrom := PChar(path + #0);\n  ShOp.pTo := nil;\n  ShOp.fFlags := FOF_NOCONFIRMATION or FOF_ALLOWUNDO or FOF_NO_UI;\n  SHFileOperation(ShOp);\nend;\n\n{ Performs tests of directory creation and deletion, and file creation,\n  reading, writing, and deletion at the specified @sBasePath }\nprocedure PerformFileSystemTests(sBasePath: string);\nvar\n  sl1, sl2: TStringList;\n  sExceptionBase, sPath, sTask: string;\nbegin\n  // initialize stringlists\n  sl1 := TStringList.Create;\n  sl2 := TStringList.Create;\n  sExceptionBase := 'Could not %s at path \"%s\"';\n\n  try\n    // try to create a new directory\n    sTask := 'create directory';\n    sPath := sBasePath + 'test\\';\n    ForceDirectories(sPath);\n    if not DirectoryExists(sPath) then\n      raise Exception.Create(Format(sExceptionBase, [sTask, sPath]));\n\n    // try to create a new file\n    sTask := 'create file';\n    sPath := sBasePath + 'test\\Test.txt';\n    sl1.Text := sBasePath;\n    sl1.SaveToFile(sPath);\n\n    // if file doesn't exist after saving, raise an exception\n    if not FileExists(sPath) then\n      raise Exception.Create(Format(sExceptionBase, [sTask, sPath]));\n\n    // try to read the file\n    sTask := 'read file';\n    sl2.LoadFromFile(sPath);\n    if sl2.Text <> sl1.Text then\n      raise Exception.Create(Format(sExceptionBase, [sTask, sPath]));\n\n    // try to write to the file\n    sTask := 'write to file';\n    sl1.Text := 'Testing 123abc';\n    sl1.SaveToFile(sPath);\n    sl2.LoadFromFile(sPath);\n    if sl2.Text <> sl1.Text then\n      raise Exception.Create(Format(sExceptionBase, [sTask, sPath]));\n\n    // try to delete the file\n    sTask := 'delete file';\n    DeleteFile(sPath);\n    if FileExists(sPath) then\n      raise Exception.Create(Format(sExceptionBase, [sTask, sPath]));\n\n    // try to delete the directory\n    sTask := 'delete directory';\n    sPath := sBasePath + 'test\\';\n    DeleteDirectory(sPath);\n    if DirectoryExists(sPath) then\n      raise Exception.Create(Format(sExceptionBase, [sTask, sPath]));\n  finally\n    // always free memory\n    sl1.Free;\n    sl2.Free;\n  end;\nend;\n\n\n{******************************************************************************}\n{ GUI Helper Functions\n  - ListView_CorrectWidth\n  - ListView_FindNextMatch\n  - ListView_HandleMatch\n}\n{******************************************************************************}\n\nprocedure StringGrid_CorrectWidth(var sg: TStringGrid);\nvar\n  w: Integer;\nbegin\n  w := sg.ClientWidth;\n  Dec(w, sg.ColWidths[0]);\n  sg.ColWidths[1] := w;\nend;\n\n{ Fixes @lv's width to fit client width if it has autosizable columns,\n  which resolves an issue where autosize doesn't work on virtual vsReport\n  TListViews when a scroll bar becomes visible. }\nprocedure ListView_CorrectWidth(var lv: TListView);\nvar\n  i, w: Integer;\n  col: TListColumn;\n  AutoSizedColumns: TList;\nbegin\n  AutoSizedColumns := TList.Create;\n  w := lv.ClientWidth;\n\n  // loop through columns keeping track of remaining width\n  for i := 0 to Pred(lv.Columns.Count) do begin\n    col := lv.Columns[i];\n    if col.AutoSize then\n      AutoSizedColumns.Add(col)\n    else\n      Dec(w, ListView_GetColumnWidth(lv.Handle, i));\n  end;\n\n  // set auotsized columns to fit client width\n  for i := 0 to Pred(AutoSizedColumns.Count) do begin\n    col := TListColumn(AutoSizedColumns[i]);\n    col.Width := w div AutoSizedColumns.Count;\n  end;\n\n  // clean up\n  AutoSizedColumns.Free;\nend;\n\n{ If @iIndex = 0, returns the index of the next @ListView item\n  matching the input @sSearch string.  Else returns the index\n  of the next @ListView subitem at index @iIndex - 1 matching\n  the input @sSearch string. }\nfunction ListView_NextMatch(ListView: TListView; sSearch: string;\n  iIndex: Integer): Integer;\nvar\n  i, iStart: Integer;\n  ListItem: TListITem;\n  sCaption, sCompare: string;\nbegin\n  Result := -1;\n\n  // Start at selected item's index, if there\n  // is an item selected\n  if Assigned(ListView.Selected) then\n    iStart := ListView.Selected.Index\n  // Else start at 0, the first item\n  else\n    iStart := 0;\n\n  // Loop through items looking for a match\n  for i := iStart to Pred(ListView.Items.Count) do begin\n    ListItem := ListView.Items[i];\n    if iIndex = 0 then\n      sCaption := ListItem.Caption\n    else\n      sCaption := ListItem.SubItems[iIndex - 1];\n    sCompare := Copy(sCaption, 1, Length(sSearch));\n    if SameText(sSearch, sCompare) then begin\n      Result := i;\n      break;\n    end;\n  end;\nend;\n\n{ Sets @sBuffer to @sTempBuffer, then selects and jumps to the item\n  at @iFoundIndex in @ListView }\nprocedure ListView_HandleMatch(ListView: TListView; iFoundIndex: Integer;\n  var sBuffer: string; sTempBuffer: string);\nbegin\n  // Set the actual buffer to our temporary buffer\n  // and jump to the item we found\n  sBuffer := sTempBuffer;\n  if Assigned(ListView.Selected) then\n    ListView.ClearSelection;\n  ListView.Selected := ListView.Items[iFoundIndex];\n  ListView.Items[iFoundIndex].MakeVisible(false);\nend;\n\ninitialization\nbegin\n  bAllowHelp := false;\n  enFormatSettings := TFormatSettings.Create('en-us');\n  enFormatSettings.DecimalSeparator := '.';\n  enFormatSettings.ThousandSeparator := ',';\nend;\n\nend."
  },
  {
    "path": "lib/mte/mteLogger.pas",
    "content": "unit mteLogger;\n\ninterface\n\nuses Classes, SysUtils;\n\ntype\n  TLogEvent = procedure(const group, &label, text: string) of object;\n\n  TLogger = class\n  private\n    FLogEvent : TLogEvent;\n  public\n    procedure Write(const group, &label, text: string);\n    property OnLogEvent: TLogEvent read FLogEvent write FLogEvent;\n  end;\n\nvar Logger : TLogger;\n\nimplementation\n\nprocedure TLogger.Write(const group, &label, text: string);\nbegin\n if Assigned(FLogEvent) then\n   FLogEvent(group, &label, text);\nend;\n\ninitialization\n Logger := TLogger.Create;\n\nfinalization\n FreeAndNil(Logger);\n\nend.\n"
  },
  {
    "path": "lib/mte/mteLogging.pas",
    "content": "{\n  mteLogging\n  created by matortheeternal\n\n  This unit contains the TFilter and TLogMessage types which offer filterable\n  logging for Delphi VCL applications.  Log messages have a group and a label,\n  and filters can apply to groups or labels.\n}\n\nunit mteLogging;\n\ninterface\n\nuses\n  Classes, SysUtils, Forms,\n  // mte units\n  mteProgressForm, mteHelpers;\n\ntype\n  TFilter = class(TObject)\n  public\n    group: string;\n    &label: string;\n    enabled: boolean;\n    constructor Create(group: string; enabled: boolean); Overload;\n    constructor Create(group, &label: string; enabled: boolean); Overload;\n  end;\n  TLogMessage = class (TObject)\n  public\n    time: string;\n    appTime: string;\n    group: string;\n    &label: string;\n    text: string;\n    constructor Create(time, appTime, group, &label, text: string); Overload;\n  end;\n\n  { Log methods }\n  procedure RebuildLog;\n  procedure SaveLog(var Log: TList);\n  function MessageEnabled(msg: TLogMessage): boolean;\n  procedure ShowProgressForm(parent: TForm; var pf: TProgressForm;\n    sCaption, sLogSubPath: string);\n\nvar\n  BaseLog, Log, LabelFilters, GroupFilters: TList;\n  LogPath: string;\n  TimeCosts: TStringList;\n  AppStartTime: TDateTime;\n\nimplementation\n\n{ TFilter }\nconstructor TFilter.Create(group: string; enabled: boolean);\nbegin\n  self.group := group;\n  self.enabled := enabled;\nend;\n\nconstructor TFilter.Create(group, &label: string; enabled: boolean);\nbegin\n  self.group := group;\n  self.&label := &label;\n  self.enabled := enabled;\nend;\n\n{ TLogMessage }\nconstructor TLogMessage.Create(time, appTime, group, &label, text: string);\nbegin\n  self.time := time;\n  self.appTime := appTime;\n  self.group := group;\n  self.&label := &label;\n  self.text := text;\nend;\n\n{******************************************************************************}\n{ Log methods\n  Set of methods for logging\n\n  List of methods:\n  - InitLog\n  - RebuildLog\n  - SaveLog\n  - MessageGroupEnabled\n}\n{******************************************************************************}\n\nprocedure RebuildLog;\nvar\n  i: Integer;\n  msg: TLogMessage;\nbegin\n  Log.Clear;\n  for i := 0 to Pred(BaseLog.Count) do begin\n    msg := TLogMessage(BaseLog[i]);\n    if MessageEnabled(msg) then\n      Log.Add(msg);\n  end;\nend;\n\nprocedure SaveLog(var Log: TList);\nvar\n  sl: TStringList;\n  i: Integer;\n  msg: TLogMessage;\n  fdt: string;\nbegin\n  sl := TStringList.Create;\n  for i := 0 to Pred(Log.Count) do begin\n    msg := TLogMessage(Log[i]);\n    sl.Add(Format('[%s] (%s) %s: %s', [msg.time, msg.group, msg.&label, msg.text]));\n  end;\n  fdt := FormatDateTime('mmddyy_hhnnss', TDateTime(Now));\n  ForceDirectories(LogPath+'main\\');\n  sl.SaveToFile(LogPath+'main\\log_'+fdt+'.txt');\n  sl.Free;\nend;\n\nfunction GetGroupFilter(msg: TLogMessage): TFilter;\nvar\n  i: Integer;\n  filter: TFilter;\nbegin\n  Result := nil;\n  for i := 0 to Pred(GroupFilters.Count) do begin\n    filter := TFilter(GroupFilters[i]);\n    if filter.group = msg.group then begin\n      Result := filter;\n      exit;\n    end;\n  end;\nend;\n\nfunction GetLabelFilter(msg: TLogMessage): TFilter;\nvar\n  i: Integer;\n  filter: TFilter;\nbegin\n  Result := nil;\n  for i := 0 to Pred(LabelFilters.Count) do begin\n    filter := TFilter(LabelFilters[i]);\n    if (filter.&label = msg.&label) and (filter.group = msg.group) then begin\n      Result := filter;\n      exit;\n    end;\n  end;\nend;\n\nfunction MessageEnabled(msg: TLogMessage): boolean;\nvar\n  GroupFilter, LabelFilter: TFilter;\nbegin\n  Result := true;\n  GroupFilter := GetGroupFilter(msg);\n  LabelFilter := GetLabelFilter(msg);\n  if GroupFilter <> nil then\n    Result := Result and GroupFilter.enabled;\n  if LabelFilter <> nil then\n    Result := Result and LabelFilter.enabled;\nend;\n\nprocedure ShowProgressForm(parent: TForm; var pf: TProgressForm;\n  sCaption, sLogSubPath: string);\nbegin\n  pf := TProgressForm.Create(parent);\n  pf.pfLogPath := LogPath + sLogSubPath + '\\';\n  pf.PopupParent := parent;\n  pf.Caption := sCaption;\n  pf.SetMaxProgress(IntegerListSum(timeCosts, Pred(timeCosts.Count)));\n  pf.Show;\nend;\n\ninitialization\nbegin\n  BaseLog := TList.Create;\n  Log := TList.Create;\n  LabelFilters := TList.Create;\n  GroupFilters := TList.Create;\nend;\n\nfinalization\nbegin\n  FreeList(BaseLog);\n  Log.Free;\nend;\n\nend.\n"
  },
  {
    "path": "lib/mte/mtePluginSelectionForm.dfm",
    "content": "object PluginSelectionForm: TPluginSelectionForm\n  Left = 0\n  Top = 0\n  HelpType = htKeyword\n  HelpKeyword = 'Plugin Selection Window'\n  Caption = 'Plugin Selection'\n  ClientHeight = 647\n  ClientWidth = 504\n  Color = clBtnFace\n  Constraints.MinHeight = 400\n  Constraints.MinWidth = 400\n  Font.Charset = DEFAULT_CHARSET\n  Font.Color = clWindowText\n  Font.Height = -11\n  Font.Name = 'Tahoma'\n  Font.Style = []\n  OldCreateOrder = False\n  Position = poScreenCenter\n  OnClose = FormClose\n  OnShow = FormShow\n  PixelsPerInch = 96\n  TextHeight = 13\n  object lvPlugins: TListView\n    Left = 8\n    Top = 8\n    Width = 488\n    Height = 600\n    HelpType = htKeyword\n    HelpKeyword = 'Plugin Selection Styles'\n    Align = alCustom\n    Anchors = [akLeft, akTop, akRight, akBottom]\n    Columns = <>\n    ColumnClick = False\n    DoubleBuffered = True\n    MultiSelect = True\n    OwnerData = True\n    OwnerDraw = True\n    ReadOnly = True\n    RowSelect = True\n    ParentDoubleBuffered = False\n    ParentShowHint = False\n    PopupMenu = PluginsPopupMenu\n    ShowHint = False\n    StateImages = StateImages\n    TabOrder = 0\n    ViewStyle = vsReport\n    OnChange = lvPluginsChange\n    OnData = lvPluginsData\n    OnDrawItem = lvPluginsDrawItem\n    OnKeyPress = lvPluginsKeyPress\n    OnMouseDown = lvPluginsMouseDown\n    OnMouseMove = lvPluginsMouseMove\n  end\n  object btnCancel: TButton\n    Left = 421\n    Top = 614\n    Width = 75\n    Height = 25\n    HelpType = htKeyword\n    HelpKeyword = 'Plugin Selection Actions'\n    Align = alCustom\n    Anchors = [akRight, akBottom]\n    Caption = 'Cancel'\n    ModalResult = 2\n    TabOrder = 1\n  end\n  object btnOK: TButton\n    Left = 340\n    Top = 614\n    Width = 75\n    Height = 25\n    HelpType = htKeyword\n    HelpKeyword = 'Plugin Selection Actions'\n    Align = alCustom\n    Anchors = [akRight, akBottom]\n    Caption = 'OK'\n    Default = True\n    ModalResult = 1\n    TabOrder = 2\n    OnClick = btnOKClick\n  end\n  object PluginsPopupMenu: TPopupMenu\n    OnPopup = PluginsPopupMenuPopup\n    Left = 48\n    Top = 24\n    object CheckAllItem: TMenuItem\n      Caption = 'Check all'\n      OnClick = CheckAllItemClick\n    end\n    object UncheckAllItem: TMenuItem\n      Caption = 'Uncheck all'\n      OnClick = UncheckAllItemClick\n    end\n    object ToggleAllItem: TMenuItem\n      Caption = 'Toggle all'\n      OnClick = ToggleAllItemClick\n    end\n    object N1: TMenuItem\n      Caption = '-'\n    end\n    object MastersItem: TMenuItem\n      Caption = 'Masters'\n      object CheckMastersItem: TMenuItem\n        Caption = 'Check masters'\n        OnClick = CheckMastersItemClick\n      end\n      object UncheckMastersItem: TMenuItem\n        Caption = 'Uncheck masters'\n        OnClick = UncheckMastersItemClick\n      end\n    end\n    object DependenciesItem: TMenuItem\n      Caption = 'Dependencies'\n      object CheckDependenciesItem: TMenuItem\n        Caption = 'Check dependencies'\n        OnClick = CheckDependenciesItemClick\n      end\n      object UncheckDependenciesItem: TMenuItem\n        Caption = 'Uncheck dependencies'\n        OnClick = UncheckDependenciesItemClick\n      end\n    end\n  end\n  object StateImages: TImageList\n    Height = 17\n    Width = 17\n    Left = 136\n    Top = 24\n    Bitmap = {\n      494C010103003400600011001100FFFFFFFFFF10FFFFFFFFFFFFFFFF424D3600\n      0000000000003600000028000000440000001100000001002000000000001012\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      00000000000000000000000000000000000000000000000000008F8F8E008F8F\n      8E008F8F8E008F8F8E008F8F8E008F8F8E008F8F8E008F8F8E008F8F8E008F8F\n      8E008F8F8E008F8F8E008F8F8E00000000000000000000000000000000008F8F\n      8E008F8F8E008F8F8E008F8F8E008F8F8E008F8F8E008F8F8E008F8F8E008F8F\n      8E008F8F8E008F8F8E008F8F8E008F8F8E000000000000000000000000000000\n      00008F8F8E008F8F8E008F8F8E008F8F8E008F8F8E008F8F8E008F8F8E008F8F\n      8E008F8F8E008F8F8E008F8F8E008F8F8E008F8F8E0000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      000000000000000000008F8F8E00F4F4F400F4F4F400F4F4F400F5F5F500F9F9\n      F900F8F8F800F5F5F500F4F4F400F4F4F400F4F4F400F4F4F4008F8F8E000000\n      00000000000000000000000000008F8F8E00F4F4F400F4F4F400F4F4F400F5F5\n      F500F9F9F900F8F8F800F5F5F500F4F4F400F4F4F400F4F4F400F4F4F4008F8F\n      8E00000000000000000000000000000000008F8F8E00F4F4F400F4F4F400F4F4\n      F400F4F4F400F4F4F400F4F4F400F4F4F400F4F4F400F4F4F400F4F4F400F4F4\n      F4008F8F8E000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      00000000000000000000000000000000000000000000000000008F8F8E00F4F4\n      F400CCCBCA00DBDADA00E9E2DF00BA998C00BD9D9000F6F3F200EDEDEC00ECEB\n      EB00EAE9E900F4F4F4008F8F8E00000000000000000000000000000000008F8F\n      8E00F4F4F400CCCBCA00DBDADA00E9E2DF00BA998C00BD9D9000F6F3F200EDED\n      EC00ECEBEB00EAE9E900F4F4F4008F8F8E000000000000000000000000000000\n      00008F8F8E00F4F4F400CCCBCA00D5D4D400DCDBDB00E1E1E000E7E7E600EBEB\n      EA00ECECEB00ECEBEB00EAE9E900F4F4F4008F8F8E0000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      000000000000000000008F8F8E00F4F4F400CAC8C600F0ECEA00BB998B00975F\n      4A0098614C00D1B9B000F9F9F900F6F6F600E6E6E600F4F4F4008F8F8E000000\n      00000000000000000000000000008F8F8E00F4F4F400CAC8C600F0ECEA00BB99\n      8B00975F4A0098614C00D1B9B000F9F9F900F6F6F600E6E6E600F4F4F4008F8F\n      8E00000000000000000000000000000000008F8F8E00F4F4F400C6C4C200E9E9\n      E900EDEDED00F0F0F000F4F4F400F6F6F600F6F6F600F6F6F600E6E6E600F4F4\n      F4008F8F8E000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      00000000000000000000000000000000000000000000000000008F8F8E00F4F4\n      F400D1CFCD00E9E1DE00955D4800965F490097604B00A4736100FAF9F800F4F4\n      F400E2E2E100F4F4F4008F8F8E00000000000000000000000000000000008F8F\n      8E00F4F4F400D1CFCD00E9E1DE00955D4800965F490097604B00A4736100FAF9\n      F800F4F4F400E2E2E100F4F4F4008F8F8E000000000000000000000000000000\n      00008F8F8E00F4F4F400C2BFBC00E5E4E300E9E9E900EDEDED00F2F2F200F4F4\n      F400F5F5F500F4F4F400E2E2E100F4F4F4008F8F8E0000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      000000000000000000008F8F8E00F4F4F400E1E0DE00AA7F6E00945C4700E2D4\n      CF00A778670097604B00D5BFB700F6F6F600DEDDDC00F4F4F4008F8F8E000000\n      00000000000000000000000000008F8F8E00F4F4F400E1E0DE00AA7F6E00945C\n      4700E2D4CF00A778670097604B00D5BFB700F6F6F600DEDDDC00F4F4F4008F8F\n      8E00000000000000000000000000000000008F8F8E00F4F4F400BFBBB800E1DF\n      DD00E5E5E400EAEAEA00EFEFEF00F2F2F200F2F2F200F2F2F200DEDDDC00F4F4\n      F4008F8F8E000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      00000000000000000000000000000000000000000000000000008F8F8E00F4F4\n      F400CDC9C500DDCFC900C8AEA300EEEEED00D5C1BA00965E4900A5766400F8F8\n      F800D6D5D500F4F4F4008F8F8E00000000000000000000000000000000008F8F\n      8E00F4F4F400CDC9C500DDCFC900C8AEA300EEEEED00D5C1BA00965E4900A576\n      6400F8F8F800D6D5D500F4F4F4008F8F8E000000000000000000000000000000\n      00008F8F8E00F4F4F400BCB7B200DCD8D500DFDCDA00E3E1E000E8E8E800ECEC\n      EC00EDEDED00EDEDED00D6D5D400F4F4F4008F8F8E0000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      000000000000000000008F8F8E00F4F4F400B9B3AE00DDD9D500E5E2DF00DCD8\n      D500F4F3F200A1715E00945C4700D6C3BC00DCDCDB00F4F4F4008F8F8E000000\n      00000000000000000000000000008F8F8E00F4F4F400B9B3AE00DDD9D500E5E2\n      DF00DCD8D500F4F3F200A1715E00945C4700D6C3BC00DCDCDB00F4F4F4008F8F\n      8E00000000000000000000000000000000008F8F8E00F4F4F400B9B3AE00D7D1\n      CD00D9D4D000DBD7D400DFDDDB00E3E2E100E6E6E500E8E8E800CDCDCC00F4F4\n      F4008F8F8E000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      00000000000000000000000000000000000000000000000000008F8F8E00F4F4\n      F400B9B3AE00D5CFCB00D5CFCB00D6D1CD00E6E2E000CFB8AF00925A4500A577\n      6500E8E7E700F4F4F4008F8F8E00000000000000000000000000000000008F8F\n      8E00F4F4F400B9B3AE00D5CFCB00D5CFCB00D6D1CD00E6E2E000CFB8AF00925A\n      4500A5776500E8E7E700F4F4F4008F8F8E000000000000000000000000000000\n      00008F8F8E00F4F4F400B9B3AE00D5CFCB00D5CFCB00D6D1CD00DAD5D200DEDB\n      D800E1DFDD00E4E3E200C8C7C600F4F4F4008F8F8E0000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      000000000000000000008F8F8E00F4F4F400B9B3AE00D5CFCB00D5CFCB00D5CF\n      CB00D6D0CC00F1EEED009D6A5700925A4400D0BFB900F6F6F6008F8F8E000000\n      00000000000000000000000000008F8F8E00F4F4F400B9B3AE00D5CFCB00D5CF\n      CB00D5CFCB00D6D0CC00F1EEED009D6A5700925A4400D0BFB900F6F6F6008F8F\n      8E00000000000000000000000000000000008F8F8E00F4F4F400B9B3AE00D5CF\n      CB00D5CFCB00D5CFCB00D5CFCB00D8D3D000DCD8D500DFDDDB00C5C3C100F4F4\n      F4008F8F8E000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      00000000000000000000000000000000000000000000000000008F8F8E00F4F4\n      F400B9B3AE00B9B3AE00B9B3AE00B9B3AE00B9B3AE00D0CCC900C0A79D00AB86\n      7700E4DFDC00F5F5F5008F8F8E00000000000000000000000000000000008F8F\n      8E00F4F4F400B9B3AE00B9B3AE00B9B3AE00B9B3AE00B9B3AE00D0CCC900C0A7\n      9D00AB867700E4DFDC00F5F5F5008F8F8E000000000000000000000000000000\n      00008F8F8E00F4F4F400B9B3AE00B9B3AE00B9B3AE00B9B3AE00B9B3AE00B9B3\n      AE00BAB4AF00BDB9B400C1BEBB00F4F4F4008F8F8E0000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      000000000000000000008F8F8E00F4F4F400F4F4F400F4F4F400F4F4F400F4F4\n      F400F4F4F400F4F4F400F8F8F800F9F9F900F6F6F600F4F4F4008F8F8E000000\n      00000000000000000000000000008F8F8E00F4F4F400F4F4F400F4F4F400F4F4\n      F400F4F4F400F4F4F400F4F4F400F8F8F800F9F9F900F6F6F600F4F4F4008F8F\n      8E00000000000000000000000000000000008F8F8E00F4F4F400F4F4F400F4F4\n      F400F4F4F400F4F4F400F4F4F400F4F4F400F4F4F400F4F4F400F4F4F400F4F4\n      F4008F8F8E000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      00000000000000000000000000000000000000000000000000008F8F8E008F8F\n      8E008F8F8E008F8F8E008F8F8E008F8F8E008F8F8E008F8F8E008F8F8E008F8F\n      8E008F8F8E008F8F8E008F8F8E00000000000000000000000000000000008F8F\n      8E008F8F8E008F8F8E008F8F8E008F8F8E008F8F8E008F8F8E008F8F8E008F8F\n      8E008F8F8E008F8F8E008F8F8E008F8F8E000000000000000000000000000000\n      00008F8F8E008F8F8E008F8F8E008F8F8E008F8F8E008F8F8E008F8F8E008F8F\n      8E008F8F8E008F8F8E008F8F8E008F8F8E008F8F8E0000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000000000000000000000000000000000000000000000000000000000000000\n      0000424D3E000000000000003E00000028000000440000001100000001000100\n      00000000CC0000000000000000000000000000000000000000000000FFFFFF00\n      FFFFFFFFFFFFE00000000000FFFFFFFFFFFFE00000000000C001E000F0006000\n      00000000C001E000F000600000000000C001E000F000600000000000C001E000\n      F000600000000000C001E000F000600000000000C001E000F000600000000000\n      C001E000F000600000000000C001E000F000600000000000C001E000F0006000\n      00000000C001E000F000600000000000C001E000F000600000000000C001E000\n      F000600000000000C001E000F000600000000000FFFFFFFFFFFFE00000000000\n      FFFFFFFFFFFFE000000000000000000000000000000000000000000000000000\n      0000}\n  end\nend\n"
  },
  {
    "path": "lib/mte/mtePluginSelectionForm.pas",
    "content": "unit mtePluginSelectionForm;\n\ninterface\n\nuses\n  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,\n  Dialogs, StdCtrls, CommCtrl, Menus, ComCtrls, ImgList;\n\ntype\n  TPluginListItem = class(TObject)\n  public\n    StateIndex: Integer;\n    Fields: TStringList;\n    constructor Create; virtual;\n    destructor Destroy; override;\n  end;\n  TStringFunction = function(s: string): string of object;\n  TStringListProcedure = procedure(fn: string; var sl: TStringList) of object;\n  TPluginSelectionForm = class(TForm)\n    lvPlugins: TListView;\n    btnCancel: TButton;\n    btnOK: TButton;\n    PluginsPopupMenu: TPopupMenu;\n    CheckAllItem: TMenuItem;\n    UncheckAllItem: TMenuItem;\n    ToggleAllItem: TMenuItem;\n    StateImages: TImageList;\n    MastersItem: TMenuItem;\n    N1: TMenuItem;\n    CheckMastersItem: TMenuItem;\n    UncheckMastersItem: TMenuItem;\n    CheckDependenciesItem: TMenuItem;\n    UncheckDependenciesItem: TMenuItem;\n    DependenciesItem: TMenuItem;\n    procedure LoadFields(aListItem: TPluginListItem; sPlugin: string);\n    procedure UpdateDisabled;\n    procedure FormShow(Sender: TObject);\n    procedure btnOKClick(Sender: TObject);\n    procedure CheckAllItemClick(Sender: TObject);\n    procedure UncheckAllItemClick(Sender: TObject);\n    procedure ToggleAllItemClick(Sender: TObject);\n    procedure lvPluginsMouseDown(Sender: TObject; Button: TMouseButton;\n      Shift: TShiftState; X, Y: Integer);\n    procedure lvPluginsChange(Sender: TObject; Item: TListItem;\n      Change: TItemChange);\n    procedure lvPluginsKeyPress(Sender: TObject; var Key: Char);\n    procedure DrawCheckbox(aCanvas: TCanvas; var x, y: Integer; state: Integer);\n    procedure DrawSubItems(ListView: TListView; var R: TRect; Item: TListItem);\n    procedure DrawItem(ListView: TListView; var R: TRect; Item: TListItem);\n    procedure lvPluginsDrawItem(Sender: TCustomListView; Item: TListItem;\n      Rect: TRect; State: TOwnerDrawState);\n    procedure lvPluginsMouseMove(Sender: TObject; Shift: TShiftState; X,\n      Y: Integer);\n    function GetMasterStatus(filename: string): Integer;\n    procedure lvPluginsData(Sender: TObject; Item: TListItem);\n    procedure FormClose(Sender: TObject; var Action: TCloseAction);\n    procedure CheckMastersItemClick(Sender: TObject);\n    procedure UncheckMastersItemClick(Sender: TObject);\n    procedure CheckDependenciesItemClick(Sender: TObject);\n    procedure UncheckDependenciesItemClick(Sender: TObject);\n    procedure PluginsPopupMenuPopup(Sender: TObject);\n  private\n    { Private declarations }\n    slMasters, slDependencies, slMissing, slDisabled: TStringList;\n    ListItems: TList;\n    sLastHint: string;\n    sBuffer: string;\n    fLastBufferTime: TDateTime;\n  public\n    { Public declarations }\n    GetPluginInfo: TStringFunction;\n    GetPluginMasters: TStringListProcedure;\n    GetPluginDependencies: TStringListProcedure;\n    sColumns: string;\n    slAllPlugins, slCheckedPlugins: TStringList;\n  end;\n\nvar\n  PluginSelectionForm: TPluginSelectionForm;\n\nimplementation\n\nuses\n  mteHelpers;\n\nconst\n  // delay for clearing keystroke buffer when\n  // performing a text search on a list view\n  fBufferDelay = 1.1 * seconds;\n  // checkbox states\n  cChecked = 1;\n  cUnChecked = 2;\n  // master states\n  mstNone = 0;\n  mstMaster = 1;\n  mstDependency = 2;\n  mstBoth = 3;\n  mstMissing = 4;\n  mstDisabled = 5;\n\n{$R *.dfm}\n\nconstructor TPluginListItem.Create;\nbegin\n  StateIndex := cUnChecked;\n  Fields := TStringList.Create;\nend;\n\ndestructor TPluginListItem.Destroy;\nbegin\n  Fields.Free;\nend;\n\nprocedure TPluginSelectionForm.btnOKClick(Sender: TObject);\nvar\n  i: Integer;\n  ListItem: TListItem;\nbegin\n  // clear checked plugins list\n  slCheckedPlugins.Clear;\n  // add checked plugins to slCheckedPlugins\n  for i := 0 to Pred(lvPlugins.Items.Count) do begin\n    ListItem := lvPlugins.Items[i];\n    if ListItem.StateIndex = cChecked then\n      slCheckedPlugins.Add(ListItem.Caption);\n  end;\nend;\n\nprocedure TPluginSelectionForm.LoadFields(aListItem: TPluginListItem;\n  sPlugin: string);\nvar\n  sl: TStringList;\n  i: Integer;\nbegin\n  // add plugin filename\n  aListItem.fields.Add(sPlugin);\n\n  // get comma separated plugin info in a TStringList\n  sl := TStringList.Create;\n  sl.StrictDelimiter := true;\n  try\n    sl.CommaText := GetPluginInfo(sPlugin);\n    for i := 0 to Pred(sl.Count) do\n      aListItem.Fields.Add(sl[i]);\n  finally\n    sl.Free;\n  end;\nend;\n\nprocedure TPluginSelectionForm.UpdateDisabled;\nvar\n  i, j, index: Integer;\n  filename: string;\n  ListItem, MasterItem: TPluginListItem;\n  sl: TStringList;\nbegin\n  // update slDisabled\n  slDisabled.Clear;\n  sl := TStringList.Create;\n  try\n    for i := 0 to Pred(lvPlugins.Items.Count) do begin\n      ListItem := TPluginListItem(ListItems[i]);\n      filename := ListItem.Fields[0];\n      // if unchecked, skip\n      if ListItem.StateIndex = cUnChecked then\n        continue;\n      // if checked, make sure its masters are checked\n      GetPluginMasters(filename, sl);\n      for j := 0 to Pred(sl.Count) do begin\n        index := slAllPlugins.IndexOf(sl[j]);\n        // if master is not found, continue\n        if (index = -1) then\n          continue;\n        // if master is unchecked, add to slDisabled\n        MasterItem := TPluginListItem(ListItems[index]);\n        if MasterItem.StateIndex = cUnChecked then\n          slDisabled.Add(sl[j]);\n      end;\n      // clear masters\n      sl.Clear;\n    end;\n  finally\n    sl.Free;\n  end;\n\n  // disable OK button if there are any disabled masters\n  btnOK.Enabled := slDisabled.Count = 0;\nend;\n\nprocedure ToggleState(ListItem: TPluginListItem);\nbegin\n  case ListItem.StateIndex of\n    cChecked: ListItem.StateIndex := cUnChecked;\n    cUnChecked: ListItem.StateIndex := cChecked;\n  end;\nend;\n\nprocedure TPluginSelectionForm.lvPluginsChange(Sender: TObject; Item: TListItem;\n  Change: TItemChange);\nvar\n  i: Integer;\n  filename: string;\nbegin\n  // update slMasters and slDependencies\n  slMasters.Clear;\n  slDependencies.Clear;\n  for i := 0 to Pred(lvPlugins.Items.Count) do begin\n    filename := TPluginListItem(ListItems[i]).Fields[0];\n    with lvPlugins.Items[i] do\n      if Selected then begin\n        GetPluginMasters(filename, slMasters);\n        GetPluginDependencies(filename, slDependencies);\n      end;\n  end;\n\n  // repaint to update master/dependency colors\n  lvPlugins.Repaint;\nend;\n\nfunction TPluginSelectionForm.GetMasterStatus(filename: string): Integer;\nvar\n  bIsDependency, bIsMaster: boolean;\nbegin\n  // if file has masters that are missing from slAllPlugins,\n  // return mstMissing\n  if slMissing.IndexOf(filename) > -1 then begin\n    Result := mstMissing;\n    exit;\n  end;\n\n  // if file has masters that are disabled,\n  // return mstDisabled\n  if slDisabled.IndexOf(filename) > -1 then begin\n    Result := mstDisabled;\n    exit;\n  end;\n\n  // compute master or dependency status based on selection\n  bIsMaster := slMasters.IndexOf(filename) > -1;\n  bIsDependency := slDependencies.IndexOf(filename) > -1;\n  Result := IfThenInt(bIsMaster, 1, 0) + IfThenInt(bIsDependency, 2, 0);\nend;\n\nprocedure TPluginSelectionForm.lvPluginsData(Sender: TObject; Item: TListItem);\nvar\n  aListItem: TPluginListItem;\n  MasterStatus: Integer;\n  i: Integer;\nbegin\n  // get item data\n  aListItem := ListItems[Item.Index];\n  Item.Caption := aListItem.Fields[0];\n  Item.StateIndex := aListItem.StateIndex;\n  // get subitems\n  for i := 1 to Pred(aListItem.fields.Count) do\n    Item.SubItems.Add(aListItem.fields[i]);\n\n  // set font color based on master status of item\n  lvPlugins.Canvas.Font.Style := [fsBold];\n  MasterStatus := GetMasterStatus(Item.Caption);\n  case MasterStatus of\n    mstNone: begin\n      lvPlugins.Canvas.Font.Style := [];\n      lvPlugins.Canvas.Font.Color := clBlack;\n    end;\n    mstMaster: lvPlugins.Canvas.Font.Color := clGreen;\n    mstDependency: lvPlugins.Canvas.Font.Color := clMaroon;\n    mstBoth: lvPlugins.Canvas.Font.Color := clPurple;\n    mstMissing: begin\n      lvPlugins.Canvas.Font.Style := [fsItalic];\n      lvPlugins.Canvas.Font.Color := clGray;\n    end;\n    mstDisabled: begin\n      lvPlugins.Canvas.Font.Style := [fsItalic];\n      lvPlugins.Canvas.Font.Color := clRed;\n    end;\n  end;\nend;\n\nprocedure TPluginSelectionForm.DrawCheckbox(aCanvas: TCanvas; var x, y: Integer;\n  state: Integer);\nvar\n  icon: TIcon;\nbegin\n  if state = 0 then\n    exit;\n  icon := TIcon.Create;\n  StateImages.GetIcon(state, icon);\n  aCanvas.Draw(x, y, icon);\n  Inc(x, 17);\n  icon.Free;\nend;\n\nprocedure TPluginSelectionForm.DrawSubItems(ListView: TListView; var R: TRect;\n  Item: TListItem);\nvar\n  i: Integer;\nbegin\n  for i := 0 to Pred(Item.SubItems.Count) do begin\n    // redefine rect to draw in the space for the column\n    // use trailing padding to keep items lined up on columns\n    R.Left := R.Right;\n    R.Right := R.Left + ListView_GetColumnWidth(ListView.Handle, i) - 3;\n\n    // padding between items\n    Inc(R.Left, 3);\n\n    // draw text\n    ListView.Canvas.TextRect(R, R.Left, R.Top, Item.SubItems[i]);\n  end;\nend;\n\nprocedure TPluginSelectionForm.DrawItem(ListView: TListView; var R: TRect;\n  Item: TListItem);\nbegin\n  // redefine rect to draw until the end of the first column\n  // use trailing padding to keep items lined up on columns\n  R.Right := R.Left + ListView.Columns[0].Width - 3;\n\n  // draw the checkbox\n  DrawCheckbox(ListView.Canvas, R.Left, R.Top, Item.StateIndex);\n\n  // move text down 1 pixel\n  Inc(R.Top, 1);\n  // padding between checkbox and text\n  Inc(R.Left, 6);\n\n  // draw text\n  ListView.Canvas.TextRect(R, R.Left, R.Top, Item.Caption);\nend;\n\nprocedure TPluginSelectionForm.lvPluginsDrawItem(Sender: TCustomListView;\n  Item: TListItem; Rect: TRect; State: TOwnerDrawState);\nvar\n  ListView: TListView;\nbegin\n  // draw background color\n  ListView := TListView(Sender);\n  if Item.Selected then begin\n    ListView.Canvas.Brush.Color := $FFEEDD;\n    ListView.Canvas.FillRect(Rect);\n  end;\n\n  // draw item\n  DrawItem(ListView, Rect, Item);\n  // draw subitem\n  DrawSubItems(ListView, Rect, Item);\nend;\n\nprocedure TPluginSelectionForm.lvPluginsKeyPress(Sender: TObject;\n  var Key: Char);\nvar\n  i, iFoundIndex: Integer;\n  ListItem: TListItem;\n  fBufferDiff: Real;\n  sTempBuffer: string;\nbegin\n  // Calculate time between current keystroke and last\n  // keystroke we buffered\n  fBufferDiff := Now - fLastBufferTime;\n\n  // If we are within the buffer delay append the key to a\n  // temporary buffer and search for next item matching the\n  // buffer in the list view items.\n  if fBufferDiff < fBufferDelay then begin\n    fLastBufferTime := Now;\n    sTempBuffer := sBuffer + Key;\n    iFoundIndex := ListView_NextMatch(lvPlugins, sTempBuffer, 0);\n    // If we found a match, handle it\n    if iFoundIndex > -1 then begin\n      ListView_HandleMatch(lvPlugins, iFoundIndex, sBuffer, sTempBuffer);\n      Key := #0;\n    end;\n  end\n  else begin\n    // Allow user to use space to toggle checkbox state\n    // for all selected items\n    if Key = ' ' then begin\n      for i := 0 to Pred(lvPlugins.Items.Count) do begin\n        ListItem := lvPlugins.Items[i];\n        if ListItem.Selected then\n          if slMissing.IndexOf(slAllPlugins[i]) = -1 then\n            ToggleState(TPluginListItem(ListItems[i]));\n      end;\n      // repaint to show updated checkbox state and exit\n      UpdateDisabled;\n      lvPlugins.Repaint;\n      exit;\n    end;\n\n    // Restart buffering if we didn't have an active buffer\n    // or press space\n    fLastBufferTime := Now;\n    sTempBuffer := Key;\n    lvPlugins.ClearSelection;\n    iFoundIndex := ListView_NextMatch(lvPlugins, sTempBuffer, 0);\n    // If we found a match, handle it\n    if iFoundIndex > -1 then begin\n      ListView_HandleMatch(lvPlugins, iFoundIndex, sBuffer, sTempBuffer);\n      Key := #0;\n    end;\n  end;\nend;\n\nfunction OnStateIcon(X, Y: Integer): Boolean;\nbegin\n  Result := (x >= 2) and (x <= 14);\nend;\n\nprocedure TPluginSelectionForm.lvPluginsMouseDown(Sender: TObject;\n  Button: TMouseButton; Shift: TShiftState; X, Y: Integer);\nvar\n  ListItem: TListItem;\nbegin\n  // toggle checkbox state\n  ListItem := lvPlugins.GetItemAt(X, Y);\n  if OnStateIcon(X, Y) then begin\n    if slMissing.IndexOf(slAllPlugins[ListItem.Index]) = -1 then\n      ToggleState(TPluginListItem(ListItems[ListItem.Index]));\n\n    // repaint to show updated checkbox state\n    UpdateDisabled;\n    lvPlugins.Repaint;\n  end;\nend;\n\nprocedure TPluginSelectionForm.lvPluginsMouseMove(Sender: TObject;\n  Shift: TShiftState; X, Y: Integer);\nvar\n  pt: TPoint;\n  li : TListItem;\n  hint, str: string;\n  slTempMasters, slTempReq: TStringList;\n  i: Integer;\nbegin\n  // get list item at mouse position\n  li := lvPlugins.GetItemAt(X, Y);\n  // if mouse not over an item, exit\n  if not Assigned(li) then\n    exit;\n\n  slTempMasters := TStringList.Create;\n  try\n    GetPluginMasters(li.Caption, slTempMasters);\n    if slMissing.IndexOf(li.Caption) > -1 then begin\n      str := '';\n      for i := 0 to Pred(slTempMasters.Count) do\n        if slAllPlugins.IndexOf(slTempMasters[i]) = -1 then\n          str := str + slTempMasters[i] + #13#10;\n      hint := Format('Missing masters:'#13#10'%s', [str]);\n    end\n    else if slTempMasters.Count > 0 then\n      hint := Format('Masters:'#13#10'%s'#13#10, [slTempMasters.Text]);\n  finally\n    slTempMasters.Free;\n  end;\n\n  // get plugin dependencies and display them if they're present\n  slTempReq := TStringList.Create;\n  try\n    GetPluginDependencies(li.Caption, slTempReq);\n    if slTempReq.Count > 0 then\n      hint := hint + Format('Required By:'#13#10'%s', [slTempReq.Text]);\n  finally\n    slTempReq.Free;\n  end;\n\n  // trim the hint\n  hint := Trim(hint);\n\n  // activate hint if it differs from previously displayed hint\n  if (hint <> sLastHint) then begin\n    sLastHint := hint;\n    lvPlugins.ShowHint := True;\n    lvPlugins.Hint := hint;\n    Application.ActivateHint(Mouse.CursorPos);\n  end;\nend;\n\nprocedure TPluginSelectionForm.FormClose(Sender: TObject;\n  var Action: TCloseAction);\nbegin\n  slMasters.Free;\n  slDependencies.Free;\n  slMissing.Free;\n  slDisabled.Free;\n  ListItems.Free;\nend;\n\nprocedure TPluginSelectionForm.FormShow(Sender: TObject);\nvar\n  i, j, iColumnSize: Integer;\n  aListItem: TPluginListItem;\n  sPlugin: string;\n  sl: TStringList;\n  aColumn: TListColumn;\nbegin\n  // create lists\n  slMasters := TStringList.Create;\n  slDependencies := TStringList.Create;\n  slMissing := TStringList.Create;\n  slDisabled := TStringList.Create;\n  ListItems := TList.Create;\n\n  // create columns\n  sl := TStringList.Create;\n  try\n    sl.CommaText := sColumns;\n    iColumnSize := (lvPlugins.ClientWidth - 300) div (sl.Count - 1);\n    for i := 0 to Pred(sl.Count) do begin\n      aColumn := lvPlugins.Columns.Add;\n      aColumn.Caption := sl[i];\n      aColumn.Width := IfThenInt(i = 0, 300, iColumnSize);\n    end;\n    // make first column autosize\n    lvPlugins.Columns[0].AutoSize := true;\n  finally\n    sl.Free;\n  end;\n\n  // add plugin items to list\n  for i := 0 to Pred(slAllPlugins.Count) do begin\n    sPlugin := slAllPlugins[i];\n    aListItem := TPluginListItem.Create;\n    // check ListItem if it's in the CheckedPlugins list\n    if slCheckedPlugins.IndexOf(sPlugin) > -1 then\n      aListItem.StateIndex := cChecked;\n    // add patch subitems\n    LoadFields(aListItem, sPlugin);\n    ListItems.Add(aListItem);\n  end;\n\n  // determine which plugins can't be loaded because their masters\n  // are missing\n  sl := TStringList.Create;\n  try\n    for i := 0 to Pred(slAllPlugins.Count) do begin\n      sPlugin := slAllPlugins[i];\n      aListItem := TPluginListItem(ListItems[i]);\n      GetPluginMasters(sPlugin, sl);\n      for j := 0 to Pred(sl.Count) do\n        if slAllPlugins.IndexOf(sl[j]) = -1 then begin\n          slMissing.Add(sPlugin);\n          aListItem.StateIndex := cUnChecked;\n          break;\n        end;\n      sl.Clear;\n    end;\n  finally\n    sl.Free;\n  end;\n\n  // set plugin count for display\n  lvPlugins.Items.Count := slAllPlugins.Count;\n  ListView_CorrectWidth(lvPlugins);\n\n  // update disabled\n  UpdateDisabled;\n  lvPlugins.Repaint;\nend;\n\nprocedure TPluginSelectionForm.PluginsPopupMenuPopup(Sender: TObject);\nvar\n  bHasMasters, bHasDependencies: Boolean;\nbegin\n  bHasMasters := slMasters.Count > 0;\n  bHasDependencies := slDependencies.Count > 0;\n  MastersItem.Enabled := bHasMasters;\n  DependenciesItem.Enabled := bHasDependencies;\nend;\n\nprocedure TPluginSelectionForm.CheckAllItemClick(Sender: TObject);\nvar\n  i: Integer;\nbegin\n  for i := 0 to Pred(lvPlugins.Items.Count) do\n    if slMissing.IndexOf(slAllPlugins[i]) = -1 then\n      TPluginListItem(ListItems[i]).StateIndex := cChecked;\n\n  // repaint to show updated checkbox state\n  UpdateDisabled;\n  lvPlugins.Repaint;\nend;\n\nprocedure TPluginSelectionForm.UncheckAllItemClick(Sender: TObject);\nvar\n  i: Integer;\nbegin\n  for i := 0 to Pred(lvPlugins.Items.Count) do\n    TPluginListItem(ListItems[i]).StateIndex := cUnChecked;\n\n  // repaint to show updated checkbox state\n  UpdateDisabled;\n  lvPlugins.Repaint;\nend;\n\nprocedure TPluginSelectionForm.ToggleAllItemClick(Sender: TObject);\nvar\n  i: Integer;\nbegin\n  for i := 0 to Pred(lvPlugins.Items.Count) do\n    if slMissing.IndexOf(slAllPlugins[i]) = -1 then\n      ToggleState(TPluginListItem(ListItems[i]));\n\n  // repaint to show updated checkbox state\n  UpdateDisabled;\n  lvPlugins.Repaint;\nend;\n\nprocedure TPluginSelectionForm.CheckMastersItemClick(Sender: TObject);\nvar\n  i, index: Integer;\nbegin\n  // loop through masters of selected plugins\n  for i := 0 to Pred(slMasters.Count) do begin\n    index := slAllPlugins.IndexOf(slMasters[i]);\n    // if the masters isn't loaded, skip it\n    if index = -1 then\n      continue;\n    // else check it\n    TPluginListItem(ListItems[index]).StateIndex := cChecked;\n  end;\n\n  // repaint to show updated checkbox state\n  UpdateDisabled;\n  lvPlugins.Repaint;\nend;\n\nprocedure TPluginSelectionForm.UncheckMastersItemClick(Sender: TObject);\nvar\n  i, index: Integer;\nbegin\n  // loop through masters of selected plugins\n  for i := 0 to Pred(slMasters.Count) do begin\n    index := slAllPlugins.IndexOf(slMasters[i]);\n    // if the masters isn't loaded, skip it\n    if index = -1 then\n      continue;\n    // else uncheck it\n    TPluginListItem(ListItems[index]).StateIndex := cUnChecked;\n  end;\n\n  // repaint to show updated checkbox state\n  UpdateDisabled;\n  lvPlugins.Repaint;\nend;\n\nprocedure TPluginSelectionForm.CheckDependenciesItemClick(Sender: TObject);\nvar\n  i, index: Integer;\nbegin\n  // loop through dependencies of selected plugins\n  for i := 0 to Pred(slDependencies.Count) do begin\n    index := slAllPlugins.IndexOf(slDependencies[i]);\n    // check it\n    TPluginListItem(ListItems[index]).StateIndex := cChecked;\n  end;\n\n  // repaint to show updated checkbox state\n  UpdateDisabled;\n  lvPlugins.Repaint;\nend;\n\nprocedure TPluginSelectionForm.UncheckDependenciesItemClick(Sender: TObject);\nvar\n  i, index: Integer;\nbegin\n  // loop through dependencies of selected plugins\n  for i := 0 to Pred(slDependencies.Count) do begin\n    index := slAllPlugins.IndexOf(slDependencies[i]);\n    // uncheck it\n    TPluginListItem(ListItems[index]).StateIndex := cUnChecked;\n  end;\n\n  // repaint to show updated checkbox state\n  UpdateDisabled;\n  lvPlugins.Repaint;\nend;\n\nend.\n"
  },
  {
    "path": "lib/mte/mteProgressForm.dfm",
    "content": "object ProgressForm: TProgressForm\n  Left = 0\n  Top = 0\n  Caption = 'Progress'\n  ClientHeight = 342\n  ClientWidth = 624\n  Color = clBtnFace\n  DoubleBuffered = True\n  Font.Charset = DEFAULT_CHARSET\n  Font.Color = clWindowText\n  Font.Height = -11\n  Font.Name = 'Tahoma'\n  Font.Style = []\n  OldCreateOrder = False\n  Position = poMainFormCenter\n  OnClose = FormClose\n  OnCloseQuery = FormCloseQuery\n  OnCreate = FormCreate\n  OnShow = FormShow\n  PixelsPerInch = 96\n  TextHeight = 13\n  object ProgressLabel: TLabel\n    Left = 8\n    Top = 8\n    Width = 608\n    Height = 13\n    Align = alCustom\n    Anchors = [akLeft, akTop, akRight]\n    AutoSize = False\n    Caption = 'Progress message'\n  end\n  object DetailsMemo: TMemo\n    Left = 8\n    Top = 58\n    Width = 608\n    Height = 245\n    Align = alCustom\n    Anchors = [akLeft, akTop, akRight, akBottom]\n    ReadOnly = True\n    ScrollBars = ssVertical\n    TabOrder = 0\n  end\n  object DetailsButton: TButton\n    Left = 428\n    Top = 309\n    Width = 91\n    Height = 25\n    Align = alCustom\n    Anchors = [akRight, akBottom]\n    Caption = 'Hide details'\n    TabOrder = 1\n    OnClick = ToggleDetails\n  end\n  object ProgressBar: TProgressBar\n    Left = 8\n    Top = 27\n    Width = 608\n    Height = 25\n    Align = alCustom\n    Anchors = [akLeft, akTop, akRight]\n    TabOrder = 2\n  end\n  object CancelButton: TButton\n    Left = 525\n    Top = 309\n    Width = 91\n    Height = 25\n    Align = alCustom\n    Anchors = [akRight, akBottom]\n    Caption = 'Cancel'\n    TabOrder = 3\n    OnClick = CancelButtonClick\n  end\nend\n"
  },
  {
    "path": "lib/mte/mteProgressForm.pas",
    "content": "unit mteProgressForm;\n\ninterface\n\nuses\n  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,\n  Dialogs, StdCtrls, ComCtrls,\n  // mte components\n  W7Taskbar, mteTracker;\n\ntype\n  TProgressForm = class(TForm)\n    DetailsMemo: TMemo;\n    DetailsButton: TButton;\n    ProgressBar: TProgressBar;\n    ProgressLabel: TLabel;\n    CancelButton: TButton;\n    procedure UpdateProgress(const i: Integer);\n    procedure StatusMessage(const s: string);\n    procedure Write(const s: string);\n    procedure SaveLog;\n    procedure SetProgress(const i: Integer);\n    procedure SetMaxProgress(const i: Integer);\n    function GetProgress: Integer;\n    function GetMaxProgress: Integer;\n    procedure FormCreate(Sender: TObject);\n    procedure FormClose(Sender: TObject; var Action: TCloseAction);\n    procedure ToggleDetails(Sender: TObject);\n    procedure FormCloseQuery(Sender: TObject; var CanClose: Boolean);\n    procedure CancelButtonClick(Sender: TObject);\n    procedure FormShow(Sender: TObject);\n  private\n    { Private declarations }\n  public\n    bDetailsVisible: boolean;\n    pfLogPath: string;\n  end;\n\nimplementation\n\nvar\n  lastHeight: integer;\n\n{$R *.dfm}\n\nprocedure TProgressForm.ToggleDetails(Sender: TObject);\nbegin\n  bDetailsVisible := not bDetailsVisible;\n  if bDetailsVisible then begin\n    self.Height := lastHeight;\n    DetailsMemo.Visible := true;\n    DetailsButton.Caption := 'Hide details';\n    DetailsMemo.Height := self.Height - 135;\n  end\n  else begin\n    DetailsMemo.Visible := false;\n    DetailsButton.Caption := 'Show details';\n    lastHeight := self.Height;\n    self.Height := 129;\n  end;\nend;\n\nprocedure TProgressForm.CancelButtonClick(Sender: TObject);\nbegin\n  Close;\nend;\n\nprocedure TProgressForm.FormClose(Sender: TObject; var Action: TCloseAction);\nbegin\n  SetTaskbarProgressState(tbpsNone);\n  Tracker.OnSetMaxEvent := nil;\n  Tracker.OnUpdateEvent := nil;\n  Tracker.OnLogEvent := nil;\n  Tracker.OnSetEvent := nil;\n  Tracker.OnGetEvent := nil;\n  Tracker.OnGetMaxEvent := nil;\n  Tracker.OnStatusEvent := nil;\nend;\n\nprocedure TProgressForm.FormCloseQuery(Sender: TObject; var CanClose: Boolean);\nbegin\n  CanClose := (fsModal in FormState);\n  //Tracker.Write('CanClose = '+BoolToStr(CanClose, true));\n  if not (CanClose or Tracker.Cancel) then begin\n    Tracker.Write('Cancelling...');\n    SetTaskbarProgressState(tbpsError);\n    Tracker.Cancel := true;\n  end;\nend;\n\nprocedure TProgressForm.FormCreate(Sender: TObject);\nbegin\n  lastHeight := 380;\n  SetTaskbarProgressState(tbpsNormal);\n  bDetailsVisible := true;\n  DetailsMemo.ReadOnly := true;\n  Tracker.OnSetMaxEvent := SetMaxProgress;\n  Tracker.OnUpdateEvent := UpdateProgress;\n  Tracker.OnLogEvent := Write;\n  Tracker.OnSetEvent := SetProgress;\n  Tracker.OnStatusEvent := StatusMessage;\n  Tracker.OnGetEvent := GetProgress;\n  Tracker.OnGetMaxEvent := GetMaxProgress;\nend;\n\nprocedure TProgressForm.FormShow(Sender: TObject);\nbegin\n  if (fsModal in FormState) then begin\n    CancelButton.Caption := 'Close';\n    if not bDetailsVisible then\n      ToggleDetails(nil);\n  end\n  else if not bDetailsVisible then begin\n    bDetailsVisible := false;\n    DetailsMemo.Visible := false;\n    DetailsButton.Caption := 'Show details';\n    lastHeight := self.Height;\n    self.Height := 129;\n  end;\nend;\n\nprocedure TProgressForm.SetProgress(const i: Integer);\nbegin\n  ProgressBar.Position := i;\n  SetTaskbarProgressValue(ProgressBar.Position, ProgressBar.Max);\nend;\n\nprocedure TProgressForm.SetMaxProgress(const i: Integer);\nbegin\n  ProgressBar.Max := i;\nend;\n\nfunction TProgressForm.GetProgress: Integer;\nbegin\n  Result := ProgressBar.Position;\nend;\n\nfunction TProgressForm.GetMaxProgress: Integer;\nbegin\n  Result := ProgressBar.Max;\nend;\n\nprocedure TProgressForm.UpdateProgress(const i: Integer);\nbegin\n  ProgressBar.StepBy(i);\n  SetTaskbarProgressValue(ProgressBar.Position, ProgressBar.Max);\nend;\n\nprocedure TProgressForm.SaveLog;\nvar\n  fdt: string;\nbegin\n  try\n    ForceDirectories(pfLogPath);\n    fdt := FormatDateTime('mmddyy_hhnnss', TDateTime(Now));\n    DetailsMemo.Lines.SaveToFile(pfLogPath + 'log_'+fdt+'.txt');\n  except on Exception do\n    // nothing to do\n  end;\nend;\n\nprocedure TProgressForm.StatusMessage(const s: string);\nbegin\n  ProgressLabel.Caption := s;\nend;\n\nprocedure TProgressForm.Write(const s: string);\nbegin\n  if Pos(' ', s) <> 1 then\n    ProgressLabel.Caption := s;\n  DetailsMemo.SelLength := 0;\n  DetailsMemo.Lines.Add(s);\nend;\n\nend.\n"
  },
  {
    "path": "lib/mte/mteTaskHandler.pas",
    "content": "unit mteTaskHandler;\n\ninterface\n\nuses\n  Classes, SysUtils,\n  // mte components\n  mteLogger, mteHelpers;\n\ntype\n  TProcedure = procedure of object;\n  TTask = class (TObject)\n  private\n    FExecute : TProcedure;\n  public\n    name: string;\n    rate: real;\n    lastExecuted: TDateTime;\n    constructor Create(name: string; rate: real; FExecute: TProcedure); Overload;\n    property OnExecute: TProcedure read FExecute write FExecute;\n    procedure Execute;\n  end;\n  TTaskHandler = class(TObject)\n  public\n    TaskList: TList;\n    bExecutingTasks: boolean;\n    procedure RemoveTask(taskName: string);\n    procedure AddTask(task: TTask);\n    procedure ExecTasks;\n    constructor Create; Overload;\n  end;\n\nvar\n  bLogTasks: boolean;\n\nimplementation\n\nprocedure TTaskHandler.AddTask(task: TTask);\nbegin\n  TaskList.Add(task);\nend;\n\nprocedure TTaskHandler.RemoveTask(taskName: string);\nvar\n  i: Integer;\n  task: TTask;\nbegin\n  if not Assigned(TaskList) then\n    exit;\n\n  for i := Pred(TaskList.Count) downto 0 do begin\n    task := TTask(TaskList[i]);\n    if task.name = taskName then begin\n      TaskList.Delete(i);\n      break;\n    end;\n  end;\nend;\n\nprocedure TTaskHandler.ExecTasks;\nvar\n  i: Integer;\n  task: TTask;\nbegin\n  // exit if we're currently executing tasks\n  if bExecutingTasks then\n    exit;\n  bExecutingTasks := true;\n\n  // loop through task list, executing tasks that are ready to be executed\n  for i := Pred(TaskList.Count) downto 0 do begin\n    task := TTask(TaskList[i]);\n    if (Now - task.lastExecuted >= task.rate) then begin\n      if bLogTasks and (task.rate > 60.0 * seconds) then\n        Logger.Write('TASK', 'Execute', task.name);\n      task.lastExecuted := Now;\n      task.Execute;\n    end;\n  end;\n\n  // no longer executing tasks\n  bExecutingTasks := false;\nend;\n\nconstructor TTaskHandler.Create;\nbegin\n  TaskList := TList.Create;\nend;\n\n\n{******************************************************************************}\n{ Task methods\n  Object methods for TTask\n}\n{******************************************************************************}\n\nconstructor TTask.Create(name: string; rate: real; FExecute: TProcedure);\nbegin\n  if bLogTasks then\n    Logger.Write('TASK', 'Init', Format('%s, Rate: %s', [name, RateStr(rate)]));\n  self.name := name;\n  self.rate := rate;\n  self.FExecute := FExecute;\n  self.lastExecuted := Now;\nend;\n\nprocedure TTask.Execute;\nbegin\n if Assigned(FExecute) then\n   FExecute;\nend;\n\nend.\n\n"
  },
  {
    "path": "lib/mte/mteTracker.pas",
    "content": "unit mteTracker;\n\ninterface\n\nuses Classes, SysUtils;\n\ntype\n  TUpdateEvent = procedure(const i: integer) of object;\n  TReadEvent = function: Integer of object;\n  TLogEvent = procedure(const s: string) of object;\n\n  TProgressTracker = class\n  private\n    FUpdateEvent : TUpdateEvent;\n    FSetEvent : TUpdateEvent;\n    FGetEvent : TReadEvent;\n    FMaxEvent : TUpdateEvent;\n    FGetMaxEvent : TReadEvent;\n    FLogEvent : TLogEvent;\n    FStatusEvent : TLogEvent;\n  public\n    Cancel: boolean;\n    procedure SetMaxProgress(const i: integer);\n    property OnSetMaxEvent: TUpdateEvent read FMaxEvent write FMaxEvent;\n    procedure SetProgress(const i: integer);\n    property OnSetEvent: TUpdateEvent read FSetEvent write FSetEvent;\n    function GetProgress: Integer;\n    property OnGetEvent: TReadEvent read FGetEvent write FGetEvent;\n    function GetMaxProgress: Integer;\n    property OnGetMaxEvent: TReadEvent read FGetMaxEvent write FGetMaxEvent;\n    procedure UpdateProgress(const i: integer);\n    property OnUpdateEvent: TUpdateEvent read FUpdateEvent write FUpdateEvent;\n    procedure StatusMessage(const s: string);\n    property OnStatusEvent: TLogEvent read FStatusEvent write FStatusEvent;\n    procedure Write(const s: string);\n    property OnLogEvent: TLogEvent read FLogEvent write FLogEvent;\n  end;\n\nvar\n  Tracker: TProgressTracker;\n\nimplementation\n\n\nprocedure TProgressTracker.SetMaxProgress(const i: Integer);\nbegin\n  if Assigned(FMaxEvent) then\n    FMaxEvent(i);\nend;\n\nprocedure TProgressTracker.StatusMessage(const s: string);\nbegin\n  if Assigned(FStatusEvent) then\n    FStatusEvent(s);\nend;\n\nprocedure TProgressTracker.SetProgress(const i: integer);\nbegin\n  if Assigned(FSetEvent) then\n    FSetEvent(i);\nend;\n\nfunction TProgressTracker.GetProgress: Integer;\nbegin\n  Result := FGetEvent();\nend;\n\nfunction TProgressTracker.GetMaxProgress: Integer;\nbegin\n  Result := FGetMaxEvent();\nend;\n\nprocedure TProgressTracker.UpdateProgress(const i: integer);\nbegin\n  if Assigned(FUpdateEvent) then\n    FUpdateEvent(i);\nend;\n\nprocedure TProgressTracker.Write(const s: string);\nbegin\n  if s = '' then\n    exit;\n  if Assigned(FLogEvent) then\n    FLogEvent(s);\nend;\n\ninitialization\n  Tracker := TProgressTracker.Create;\n\nfinalization\n  FreeAndNil(Tracker);\n\nend.\n"
  },
  {
    "path": "lib/superobject/superobject.pas",
    "content": "(*\n *                         Super Object Toolkit\n *\n * Usage allowed under the restrictions of the Lesser GNU General Public License\n * or alternatively the restrictions of the Mozilla Public License 1.1\n *\n * Software distributed under the License is distributed on an \"AS IS\" basis,\n * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for\n * the specific language governing rights and limitations under the License.\n *\n * Unit owner : Henri Gourvest <hgourvest@gmail.com>\n * Web site   : http://www.progdigy.com\n *\n * This unit is inspired from the json c lib:\n *   Michael Clark <michael@metaparadigm.com>\n *   http://oss.metaparadigm.com/json-c/\n *\n *  CHANGES:\n *  v1.2\n *   + support of currency data type\n *   + right trim unquoted string\n *   + read Unicode Files and streams (Litle Endian with BOM)\n *   + Fix bug on javadate functions + windows nt compatibility\n *   + Now you can force to parse only the canonical syntax of JSON using the stric parameter\n *   + Delphi 2010 RTTI marshalling\n *  v1.1\n *   + Double licence MPL or LGPL.\n *   + Delphi 2009 compatibility & Unicode support.\n *   + AsString return a string instead of PChar.\n *   + Escaped and Unascaped JSON serialiser.\n *   + Missed FormFeed added \\f\n *   - Removed @ trick, uses forcepath() method instead.\n *   + Fixed parse error with uppercase E symbol in numbers.\n *   + Fixed possible buffer overflow when enlarging array.\n *   + Added \"delete\", \"pack\", \"insert\" methods for arrays and/or objects\n *   + Multi parametters when calling methods\n *   + Delphi Enumerator (for obj1 in obj2 do ...)\n *   + Format method ex: obj.format('<%name%>%tab[1]%</%name%>')\n *   + ParseFile and ParseStream methods\n *   + Parser now understand hexdecimal c syntax ex: \\xFF\n *   + Null Object Design Patern (ex: for obj in values.N['path'] do ...)\n *  v1.0\n *   + renamed class\n *   + interfaced object\n *   + added a new data type: the method\n *   + parser can now evaluate properties and call methods\n *   - removed obselet rpc class\n *   - removed \"find\" method, now you can use \"parse\" method instead\n *  v0.6\n *   + refactoring\n *  v0.5\n *   + new find method to get or set value using a path syntax\n *       ex: obj.s['obj.prop[1]'] := 'string value';\n *           obj.a['@obj.array'].b[n] := true; // @ -> create property if necessary\n *  v0.4\n *   + bug corrected: AVL tree badly balanced.\n *  v0.3\n *   + New validator partially based on the Kwalify syntax.\n *   + extended syntax to parse unquoted fields.\n *   + Freepascal compatibility win32/64 Linux32/64.\n *   + JavaToDelphiDateTime and DelphiToJavaDateTime improved for UTC.\n *   + new TJsonObject.Compare function.\n *  v0.2\n *   + Hashed string list replaced with a faster AVL tree\n *   + JsonInt data type can be changed to int64\n *   + JavaToDelphiDateTime and DelphiToJavaDateTime helper fonctions\n *   + from json-c v0.7\n *     + Add escaping of backslash to json output\n *     + Add escaping of foward slash on tokenizing and output\n *     + Changes to internal tokenizer from using recursion to\n *       using a depth state structure to allow incremental parsing\n *  v0.1\n *   + first release\n *)\n\n{$IFDEF FPC}\n  {$MODE OBJFPC}{$H+}\n{$ENDIF}\n\n{$DEFINE SUPER_METHOD}\n{$DEFINE WINDOWSNT_COMPATIBILITY}\n{.$DEFINE DEBUG} // track memory leack\n\nunit superobject;\n\ninterface\nuses\n  Classes\n{$IFDEF VER210}\n  ,Generics.Collections, RTTI, TypInfo\n{$ENDIF}\n  ;\n\ntype\n{$IFNDEF FPC}\n  PtrInt = longint;\n  PtrUInt = Longword;\n{$ENDIF}\n  SuperInt = Int64;\n\n{$if (sizeof(Char) = 1)}\n  SOChar = WideChar;\n  SOIChar = Word;\n  PSOChar = PWideChar;\n  SOString = WideString;\n{$else}\n  SOChar = Char;\n  SOIChar = Word;\n  PSOChar = PChar;\n  SOString = string;\n{$ifend}\n\nconst\n  SUPER_ARRAY_LIST_DEFAULT_SIZE = 32;\n  SUPER_TOKENER_MAX_DEPTH = 64;\n\n  SUPER_AVL_MAX_DEPTH = sizeof(longint) * 8;\n  SUPER_AVL_MASK_HIGH_BIT = not ((not longword(0)) shr 1);\n\ntype\n  // forward declarations\n  TSuperObject = class;\n  ISuperObject = interface;\n  TSuperArray = class;\n\n(* AVL Tree\n *  This is a \"special\" autobalanced AVL tree\n *  It use a hash value for fast compare\n *)\n\n{$IFDEF SUPER_METHOD}\n  TSuperMethod = procedure(const This, Params: ISuperObject; var Result: ISuperObject);\n{$ENDIF}\n\n\n  TSuperAvlBitArray = set of 0..SUPER_AVL_MAX_DEPTH - 1;\n\n  TSuperAvlSearchType = (stEQual, stLess, stGreater);\n  TSuperAvlSearchTypes = set of TSuperAvlSearchType;\n  TSuperAvlIterator = class;\n\n  TSuperAvlEntry = class\n  private\n    FGt, FLt: TSuperAvlEntry;\n    FBf: integer;\n    FHash: Cardinal;\n    FName: SOString;\n    FPtr: Pointer;\n    function GetValue: ISuperObject;\n    procedure SetValue(const val: ISuperObject);\n  public\n    class function Hash(const k: SOString): Cardinal; virtual;\n    constructor Create(const AName: SOString; Obj: Pointer); virtual;\n    property Name: SOString read FName;\n    property Ptr: Pointer read FPtr;\n    property Value: ISuperObject read GetValue write SetValue;\n  end;\n\n  TSuperAvlTree = class\n  private\n    FRoot: TSuperAvlEntry;\n    FCount: Integer;\n    function balance(bal: TSuperAvlEntry): TSuperAvlEntry;\n  protected\n    procedure doDeleteEntry(Entry: TSuperAvlEntry; all: boolean); virtual;\n    function CompareNodeNode(node1, node2: TSuperAvlEntry): integer; virtual;\n    function CompareKeyNode(const k: SOString; h: TSuperAvlEntry): integer; virtual;\n    function Insert(h: TSuperAvlEntry): TSuperAvlEntry; virtual;\n    function Search(const k: SOString; st: TSuperAvlSearchTypes = [stEqual]): TSuperAvlEntry; virtual;\n  public\n    constructor Create; virtual;\n    destructor Destroy; override;\n    function IsEmpty: boolean;\n    procedure Clear(all: boolean = false); virtual;\n    procedure Pack(all: boolean);\n    function Delete(const k: SOString): ISuperObject;\n    function GetEnumerator: TSuperAvlIterator;\n    property count: Integer read FCount;\n  end;\n\n  TSuperTableString = class(TSuperAvlTree)\n  protected\n    procedure doDeleteEntry(Entry: TSuperAvlEntry; all: boolean); override;\n    procedure PutO(const k: SOString; const value: ISuperObject);\n    function GetO(const k: SOString): ISuperObject;\n    procedure PutS(const k: SOString; const value: SOString);\n    function GetS(const k: SOString): SOString;\n    procedure PutI(const k: SOString; value: SuperInt);\n    function GetI(const k: SOString): SuperInt;\n    procedure PutD(const k: SOString; value: Double);\n    function GetD(const k: SOString): Double;\n    procedure PutB(const k: SOString; value: Boolean);\n    function GetB(const k: SOString): Boolean;\n{$IFDEF SUPER_METHOD}\n    procedure PutM(const k: SOString; value: TSuperMethod);\n    function GetM(const k: SOString): TSuperMethod;\n{$ENDIF}\n    procedure PutN(const k: SOString; const value: ISuperObject);\n    function GetN(const k: SOString): ISuperObject;\n    procedure PutC(const k: SOString; value: Currency);\n    function GetC(const k: SOString): Currency;\n  public\n    property O[const k: SOString]: ISuperObject read GetO write PutO; default;\n    property S[const k: SOString]: SOString read GetS write PutS;\n    property I[const k: SOString]: SuperInt read GetI write PutI;\n    property D[const k: SOString]: Double read GetD write PutD;\n    property B[const k: SOString]: Boolean read GetB write PutB;\n{$IFDEF SUPER_METHOD}\n    property M[const k: SOString]: TSuperMethod read GetM write PutM;\n{$ENDIF}\n    property N[const k: SOString]: ISuperObject read GetN write PutN;\n    property C[const k: SOString]: Currency read GetC write PutC;\n\n    function GetValues: ISuperObject;\n    function GetNames: ISuperObject;\n  end;\n\n  TSuperAvlIterator = class\n  private\n    FTree: TSuperAvlTree;\n    FBranch: TSuperAvlBitArray;\n    FDepth: LongInt;\n    FPath: array[0..SUPER_AVL_MAX_DEPTH - 2] of TSuperAvlEntry;\n  public\n    constructor Create(tree: TSuperAvlTree); virtual;\n    procedure Search(const k: SOString; st: TSuperAvlSearchTypes = [stEQual]);\n    procedure First;\n    procedure Last;\n    function GetIter: TSuperAvlEntry;\n    procedure Next;\n    procedure Prior;\n    // delphi enumerator\n    function MoveNext: Boolean;\n    property Current: TSuperAvlEntry read GetIter;\n  end;\n\n  TSuperObjectArray = array[0..(high(PtrInt) div sizeof(TSuperObject))-1] of ISuperObject;\n  PSuperObjectArray = ^TSuperObjectArray;\n\n  TSuperArray = class\n  private\n    FArray: PSuperObjectArray;\n    FLength: Integer;\n    FSize: Integer;\n    procedure Expand(max: Integer);\n  protected\n    function GetO(const index: integer): ISuperObject;\n    procedure PutO(const index: integer; const Value: ISuperObject);\n    function GetB(const index: integer): Boolean;\n    procedure PutB(const index: integer; Value: Boolean);\n    function GetI(const index: integer): SuperInt;\n    procedure PutI(const index: integer; Value: SuperInt);\n    function GetD(const index: integer): Double;\n    procedure PutD(const index: integer; Value: Double);\n    function GetC(const index: integer): Currency;\n    procedure PutC(const index: integer; Value: Currency);\n    function GetS(const index: integer): SOString;\n    procedure PutS(const index: integer; const Value: SOString);\n{$IFDEF SUPER_METHOD}\n    function GetM(const index: integer): TSuperMethod;\n    procedure PutM(const index: integer; Value: TSuperMethod);\n{$ENDIF}\n    function GetN(const index: integer): ISuperObject;\n    procedure PutN(const index: integer; const Value: ISuperObject);\n  public\n    constructor Create; virtual;\n    destructor Destroy; override;\n    function Add(const Data: ISuperObject): Integer;\n    function Delete(index: Integer): ISuperObject;\n    procedure Insert(index: Integer; const value: ISuperObject);\n    procedure Clear(all: boolean = false);\n    procedure Pack(all: boolean);\n    property Length: Integer read FLength;\n\n    property N[const index: integer]: ISuperObject read GetN write PutN;\n    property O[const index: integer]: ISuperObject read GetO write PutO; default;\n    property B[const index: integer]: boolean read GetB write PutB;\n    property I[const index: integer]: SuperInt read GetI write PutI;\n    property D[const index: integer]: Double read GetD write PutD;\n    property C[const index: integer]: Currency read GetC write PutC;\n    property S[const index: integer]: SOString read GetS write PutS;\n{$IFDEF SUPER_METHOD}\n    property M[const index: integer]: TSuperMethod read GetM write PutM;\n{$ENDIF}\n//    property A[const index: integer]: TSuperArray read GetA;\n  end;\n\n  TSuperWriter = class\n  public\n    // abstact methods to overide\n    function Append(buf: PSOChar; Size: Integer): Integer; overload; virtual; abstract;\n    function Append(buf: PSOChar): Integer; overload; virtual; abstract;\n    procedure Reset; virtual; abstract;\n  end;\n\n  TSuperWriterString = class(TSuperWriter)\n  private\n    FBuf: PSOChar;\n    FBPos: integer;\n    FSize: integer;\n  public\n    function Append(buf: PSOChar; Size: Integer): Integer; overload; override;\n    function Append(buf: PSOChar): Integer; overload; override;\n    procedure Reset; override;\n    procedure TrimRight;\n    constructor Create; virtual;\n    destructor Destroy; override;\n    function GetString: SOString;\n    property Data: PSOChar read FBuf;\n    property Size: Integer read FSize;\n    property Position: integer read FBPos;\n  end;\n\n  TSuperWriterStream = class(TSuperWriter)\n  private\n    FStream: TStream;\n  public\n    function Append(buf: PSOChar): Integer; override;\n    procedure Reset; override;\n    constructor Create(AStream: TStream); reintroduce; virtual;\n  end;\n\n  TSuperAnsiWriterStream = class(TSuperWriterStream)\n  public\n    function Append(buf: PSOChar; Size: Integer): Integer; override;\n  end;\n\n  TSuperUnicodeWriterStream = class(TSuperWriterStream)\n  public\n    function Append(buf: PSOChar; Size: Integer): Integer; override;\n  end;\n\n  TSuperWriterFake = class(TSuperWriter)\n  private\n    FSize: Integer;\n  public\n    function Append(buf: PSOChar; Size: Integer): Integer; override;\n    function Append(buf: PSOChar): Integer; override;\n    procedure Reset; override;\n    constructor Create; reintroduce; virtual;\n    property size: integer read FSize;\n  end;\n\n  TSuperWriterSock = class(TSuperWriter)\n  private\n    FSocket: longint;\n    FSize: Integer;\n  public\n    function Append(buf: PSOChar; Size: Integer): Integer; override;\n    function Append(buf: PSOChar): Integer; override;\n    procedure Reset; override;\n    constructor Create(ASocket: longint); reintroduce; virtual;\n    property Socket: longint read FSocket;\n    property Size: Integer read FSize;\n  end;\n\n  TSuperTokenizerError = (\n    teSuccess,\n    teContinue,\n    teDepth,\n    teParseEof,\n    teParseUnexpected,\n    teParseNull,\n    teParseBoolean,\n    teParseNumber,\n    teParseArray,\n    teParseObjectKeyName,\n    teParseObjectKeySep,\n    teParseObjectValueSep,\n    teParseString,\n    teParseComment,\n    teEvalObject,\n    teEvalArray,\n    teEvalMethod,\n    teEvalInt\n  );\n\n  TSuperTokenerState = (\n    tsEatws,\n    tsStart,\n    tsFinish,\n    tsNull,\n    tsCommentStart,\n    tsComment,\n    tsCommentEol,\n    tsCommentEnd,\n    tsString,\n    tsStringEscape,\n    tsIdentifier,\n    tsEscapeUnicode,\n    tsEscapeHexadecimal,\n    tsBoolean,\n    tsNumber,\n    tsArray,\n    tsArrayAdd,\n    tsArraySep,\n    tsObjectFieldStart,\n    tsObjectField,\n    tsObjectUnquotedField,\n    tsObjectFieldEnd,\n    tsObjectValue,\n    tsObjectValueAdd,\n    tsObjectSep,\n    tsEvalProperty,\n    tsEvalArray,\n    tsEvalMethod,\n    tsParamValue,\n    tsParamPut,\n    tsMethodValue,\n    tsMethodPut\n  );\n\n  PSuperTokenerSrec = ^TSuperTokenerSrec;\n  TSuperTokenerSrec = record\n    state, saved_state: TSuperTokenerState;\n    obj: ISuperObject;\n    current: ISuperObject;\n    field_name: SOString;\n    parent: ISuperObject;\n    gparent: ISuperObject;\n  end;\n\n  TSuperTokenizer = class\n  public\n    str: PSOChar;\n    pb: TSuperWriterString;\n    depth, is_double, floatcount, st_pos, char_offset: Integer;\n    err:  TSuperTokenizerError;\n    ucs_char: Word;\n    quote_char: SOChar;\n    stack: array[0..SUPER_TOKENER_MAX_DEPTH-1] of TSuperTokenerSrec;\n    line, col: Integer;\n  public\n    constructor Create; virtual;\n    destructor Destroy; override;\n    procedure ResetLevel(adepth: integer);\n    procedure Reset;\n  end;\n\n  // supported object types\n  TSuperType = (\n    stNull,\n    stBoolean,\n    stDouble,\n    stCurrency,\n    stInt,\n    stObject,\n    stArray,\n    stString\n{$IFDEF SUPER_METHOD}\n    ,stMethod\n{$ENDIF}\n  );\n\n  TSuperValidateError = (\n    veRuleMalformated,\n    veFieldIsRequired,\n    veInvalidDataType,\n    veFieldNotFound,\n    veUnexpectedField,\n    veDuplicateEntry,\n    veValueNotInEnum,\n    veInvalidLength,\n    veInvalidRange\n  );\n\n  TSuperFindOption = (\n    foCreatePath,\n    foPutValue,\n    foDelete\n{$IFDEF SUPER_METHOD}\n    ,foCallMethod\n{$ENDIF}\n  );\n\n  TSuperFindOptions = set of TSuperFindOption;\n  TSuperCompareResult = (cpLess, cpEqu, cpGreat, cpError);\n  TSuperOnValidateError = procedure(sender: Pointer; error: TSuperValidateError; const objpath: SOString);\n\n  TSuperEnumerator = class\n  private\n    FObj: ISuperObject;\n    FObjEnum: TSuperAvlIterator;\n    FCount: Integer;\n  public\n    constructor Create(const obj: ISuperObject); virtual;\n    destructor Destroy; override;\n    function MoveNext: Boolean;\n    function GetCurrent: ISuperObject;\n    property Current: ISuperObject read GetCurrent;\n  end;\n\n  ISuperObject = interface\n  ['{4B86A9E3-E094-4E5A-954A-69048B7B6327}']\n    function GetEnumerator: TSuperEnumerator;\n    function GetDataType: TSuperType;\n    function GetProcessing: boolean;\n    procedure SetProcessing(value: boolean);\n    function ForcePath(const path: SOString; dataType: TSuperType = stObject): ISuperObject;\n    function Format(const str: SOString; BeginSep: SOChar = '%'; EndSep: SOChar = '%'): SOString;\n\n    function GetO(const path: SOString): ISuperObject;\n    procedure PutO(const path: SOString; const Value: ISuperObject);\n    function GetB(const path: SOString): Boolean;\n    procedure PutB(const path: SOString; Value: Boolean);\n    function GetI(const path: SOString): SuperInt;\n    procedure PutI(const path: SOString; Value: SuperInt);\n    function GetD(const path: SOString): Double;\n    procedure PutC(const path: SOString; Value: Currency);\n    function GetC(const path: SOString): Currency;\n    procedure PutD(const path: SOString; Value: Double);\n    function GetS(const path: SOString): SOString;\n    procedure PutS(const path: SOString; const Value: SOString);\n{$IFDEF SUPER_METHOD}\n    function GetM(const path: SOString): TSuperMethod;\n    procedure PutM(const path: SOString; Value: TSuperMethod);\n{$ENDIF}\n    function GetA(const path: SOString): TSuperArray;\n\n    // Null Object Design patern\n    function GetN(const path: SOString): ISuperObject;\n    procedure PutN(const path: SOString; const Value: ISuperObject);\n\n    // Writers\n    function Write(writer: TSuperWriter; indent: boolean; escape: boolean; level: integer): Integer;\n    function SaveTo(stream: TStream; indent: boolean = false; escape: boolean = true): integer; overload;\n    function SaveTo(const FileName: string; indent: boolean = false; escape: boolean = true): integer; overload;\n    function SaveTo(socket: longint; indent: boolean = false; escape: boolean = true): integer; overload;\n    function CalcSize(indent: boolean = false; escape: boolean = true): integer;\n\n    // convert\n    function AsBoolean: Boolean;\n    function AsInteger: SuperInt;\n    function AsDouble: Double;\n    function AsCurrency: Currency;\n    function AsString: SOString;\n    function AsArray: TSuperArray;\n    function AsObject: TSuperTableString;\n{$IFDEF SUPER_METHOD}\n    function AsMethod: TSuperMethod;\n{$ENDIF}\n    function AsJSon(indent: boolean = false; escape: boolean = true): SOString;\n\n    procedure Clear(all: boolean = false);\n    procedure Pack(all: boolean = false);\n\n    property N[const path: SOString]: ISuperObject read GetN write PutN;\n    property O[const path: SOString]: ISuperObject read GetO write PutO; default;\n    property B[const path: SOString]: boolean read GetB write PutB;\n    property I[const path: SOString]: SuperInt read GetI write PutI;\n    property D[const path: SOString]: Double read GetD write PutD;\n    property C[const path: SOString]: Currency read GetC write PutC;\n    property S[const path: SOString]: SOString read GetS write PutS;\n{$IFDEF SUPER_METHOD}\n    property M[const path: SOString]: TSuperMethod read GetM write PutM;\n{$ENDIF}\n    property A[const path: SOString]: TSuperArray read GetA;\n\n{$IFDEF SUPER_METHOD}\n    function call(const path: SOString; const param: ISuperObject = nil): ISuperObject; overload;\n    function call(const path, param: SOString): ISuperObject; overload;\n{$ENDIF}\n    // clone a node\n    function Clone: ISuperObject;\n    function Delete(const path: SOString): ISuperObject;\n    // merges tow objects of same type, if reference is true then nodes are not cloned\n    procedure Merge(const obj: ISuperObject; reference: boolean = false); overload;\n    procedure Merge(const str: SOString); overload;\n\n    // validate methods\n    function Validate(const rules: SOString; const defs: SOString = ''; callback: TSuperOnValidateError = nil; sender: Pointer = nil): boolean; overload;\n    function Validate(const rules: ISuperObject; const defs: ISuperObject = nil; callback: TSuperOnValidateError = nil; sender: Pointer = nil): boolean; overload;\n\n    // compare\n    function Compare(const obj: ISuperObject): TSuperCompareResult; overload;\n    function Compare(const str: SOString): TSuperCompareResult; overload;\n\n    // the data type\n    function IsType(AType: TSuperType): boolean;\n    property DataType: TSuperType read GetDataType;\n    property Processing: boolean read GetProcessing write SetProcessing;\n\n    function GetDataPtr: Pointer;\n    procedure SetDataPtr(const Value: Pointer);\n    property DataPtr: Pointer read GetDataPtr write SetDataPtr;\n  end;\n\n  TSuperObject = class(TObject, ISuperObject)\n  private\n    FRefCount: Integer;\n    FProcessing: boolean;\n    FDataType: TSuperType;\n    FDataPtr: Pointer;\n{.$if true}\n    FO: record\n      case TSuperType of\n        stBoolean: (c_boolean: boolean);\n        stDouble: (c_double: double);\n        stCurrency: (c_currency: Currency);\n        stInt: (c_int: SuperInt);\n        stObject: (c_object: TSuperTableString);\n        stArray: (c_array: TSuperArray);\n{$IFDEF SUPER_METHOD}\n        stMethod: (c_method: TSuperMethod);\n{$ENDIF}\n      end;\n{.$ifend}\n    FOString: SOString;\n    function GetDataType: TSuperType;\n    function GetDataPtr: Pointer;\n    procedure SetDataPtr(const Value: Pointer);\n  protected\n    function QueryInterface(const IID: TGUID; out Obj): HResult; virtual; stdcall;\n    function _AddRef: Integer; virtual; stdcall;\n    function _Release: Integer; virtual; stdcall;\n\n    function GetO(const path: SOString): ISuperObject;\n    procedure PutO(const path: SOString; const Value: ISuperObject);\n    function GetB(const path: SOString): Boolean;\n    procedure PutB(const path: SOString; Value: Boolean);\n    function GetI(const path: SOString): SuperInt;\n    procedure PutI(const path: SOString; Value: SuperInt);\n    function GetD(const path: SOString): Double;\n    procedure PutD(const path: SOString; Value: Double);\n    procedure PutC(const path: SOString; Value: Currency);\n    function GetC(const path: SOString): Currency;\n    function GetS(const path: SOString): SOString;\n    procedure PutS(const path: SOString; const Value: SOString);\n{$IFDEF SUPER_METHOD}\n    function GetM(const path: SOString): TSuperMethod;\n    procedure PutM(const path: SOString; Value: TSuperMethod);\n{$ENDIF}\n    function GetA(const path: SOString): TSuperArray;\n    function Write(writer: TSuperWriter; indent: boolean; escape: boolean; level: integer): Integer; virtual;\n  public\n    function GetEnumerator: TSuperEnumerator;\n    procedure AfterConstruction; override;\n    procedure BeforeDestruction; override;\n    class function NewInstance: TObject; override;\n    property RefCount: Integer read FRefCount;\n\n    function GetProcessing: boolean;\n    procedure SetProcessing(value: boolean);\n\n    // Writers\n    function SaveTo(stream: TStream; indent: boolean = false; escape: boolean = true): integer; overload;\n    function SaveTo(const FileName: string; indent: boolean = false; escape: boolean = true): integer; overload;\n    function SaveTo(socket: longint; indent: boolean = false; escape: boolean = true): integer; overload;\n    function CalcSize(indent: boolean = false; escape: boolean = true): integer;\n    function AsJSon(indent: boolean = false; escape: boolean = true): SOString;\n\n    // parser  ... owned!\n    class function ParseString(s: PSOChar; strict: Boolean; partial: boolean = true; const this: ISuperObject = nil; options: TSuperFindOptions = [];\n       const put: ISuperObject = nil; dt: TSuperType = stNull): ISuperObject;\n    class function ParseStream(stream: TStream; strict: Boolean; partial: boolean = true; const this: ISuperObject = nil; options: TSuperFindOptions = [];\n       const put: ISuperObject = nil; dt: TSuperType = stNull): ISuperObject;\n    class function ParseFile(const FileName: string; strict: Boolean; partial: boolean = true; const this: ISuperObject = nil; options: TSuperFindOptions = [];\n       const put: ISuperObject = nil; dt: TSuperType = stNull): ISuperObject;\n    class function ParseEx(tok: TSuperTokenizer; str: PSOChar; len: integer; strict: Boolean; const this: ISuperObject = nil;\n      options: TSuperFindOptions = []; const put: ISuperObject = nil; dt: TSuperType = stNull): ISuperObject;\n\n    // constructors / destructor\n    constructor Create(jt: TSuperType = stObject); overload; virtual;\n    constructor Create(b: boolean); overload; virtual;\n    constructor Create(i: SuperInt); overload; virtual;\n    constructor Create(d: double); overload; virtual;\n    constructor CreateCurrency(c: Currency); overload; virtual;\n    constructor Create(const s: SOString); overload; virtual;\n{$IFDEF SUPER_METHOD}\n    constructor Create(m: TSuperMethod); overload; virtual;\n{$ENDIF}\n    destructor Destroy; override;\n\n    // convert\n    function AsBoolean: Boolean; virtual;\n    function AsInteger: SuperInt; virtual;\n    function AsDouble: Double; virtual;\n    function AsCurrency: Currency; virtual;\n    function AsString: SOString; virtual;\n    function AsArray: TSuperArray; virtual;\n    function AsObject: TSuperTableString; virtual;\n{$IFDEF SUPER_METHOD}\n    function AsMethod: TSuperMethod; virtual;\n{$ENDIF}\n    procedure Clear(all: boolean = false); virtual;\n    procedure Pack(all: boolean = false); virtual;\n    function GetN(const path: SOString): ISuperObject;\n    procedure PutN(const path: SOString; const Value: ISuperObject);\n    function ForcePath(const path: SOString; dataType: TSuperType = stObject): ISuperObject;\n    function Format(const str: SOString; BeginSep: SOChar = '%'; EndSep: SOChar = '%'): SOString;\n\n    property N[const path: SOString]: ISuperObject read GetN write PutN;\n    property O[const path: SOString]: ISuperObject read GetO write PutO; default;\n    property B[const path: SOString]: boolean read GetB write PutB;\n    property I[const path: SOString]: SuperInt read GetI write PutI;\n    property D[const path: SOString]: Double read GetD write PutD;\n    property C[const path: SOString]: Currency read GetC write PutC;\n    property S[const path: SOString]: SOString read GetS write PutS;\n{$IFDEF SUPER_METHOD}\n    property M[const path: SOString]: TSuperMethod read GetM write PutM;\n{$ENDIF}\n    property A[const path: SOString]: TSuperArray read GetA;\n\n{$IFDEF SUPER_METHOD}\n    function call(const path: SOString; const param: ISuperObject = nil): ISuperObject; overload; virtual;\n    function call(const path, param: SOString): ISuperObject; overload; virtual;\n{$ENDIF}\n    // clone a node\n    function Clone: ISuperObject; virtual;\n    function Delete(const path: SOString): ISuperObject;\n    // merges tow objects of same type, if reference is true then nodes are not cloned\n    procedure Merge(const obj: ISuperObject; reference: boolean = false); overload;\n    procedure Merge(const str: SOString); overload;\n\n    // validate methods\n    function Validate(const rules: SOString; const defs: SOString = ''; callback: TSuperOnValidateError = nil; sender: Pointer = nil): boolean; overload;\n    function Validate(const rules: ISuperObject; const defs: ISuperObject = nil; callback: TSuperOnValidateError = nil; sender: Pointer = nil): boolean; overload;\n\n    // compare\n    function Compare(const obj: ISuperObject): TSuperCompareResult; overload;\n    function Compare(const str: SOString): TSuperCompareResult; overload;\n\n    // the data type\n    function IsType(AType: TSuperType): boolean;\n    property DataType: TSuperType read GetDataType;\n    // a data pointer to link to something ele, a treeview for example\n    property DataPtr: Pointer read GetDataPtr write SetDataPtr;\n    property Processing: boolean read GetProcessing;\n  end;\n\n{$IFDEF VER210}\n  TSuperRttiContext = class;\n\n  TSerialFromJson = function(ctx: TSuperRttiContext; const obj: ISuperObject; var Value: TValue): Boolean;\n  TSerialToJson = function(ctx: TSuperRttiContext; var value: TValue; const index: ISuperObject): ISuperObject;\n\n  TSuperAttribute = class(TCustomAttribute)\n  private\n    FName: string;\n  public\n    constructor Create(const AName: string);\n    property Name: string read FName;\n  end;\n\n  SOName = class(TSuperAttribute);\n  SODefault = class(TSuperAttribute);\n\n\n  TSuperRttiContext = class\n  private\n    class function GetFieldName(r: TRttiField): string;\n    class function GetFieldDefault(r: TRttiField; const obj: ISuperObject): ISuperObject;\n  public\n    Context: TRttiContext;\n    SerialFromJson: TDictionary<PTypeInfo, TSerialFromJson>;\n    SerialToJson: TDictionary<PTypeInfo, TSerialToJson>;\n    constructor Create; virtual;\n    destructor Destroy; override;\n    function FromJson(TypeInfo: PTypeInfo; const obj: ISuperObject; var Value: TValue): Boolean; virtual;\n    function ToJson(var value: TValue; const index: ISuperObject): ISuperObject; virtual;\n    function AsType<T>(const obj: ISuperObject): T;\n    function AsJson<T>(const obj: T; const index: ISuperObject = nil): ISuperObject;\n  end;\n\n  TSuperObjectHelper = class helper for TObject\n  public\n    function ToJson(ctx: TSuperRttiContext = nil): ISuperObject;\n    constructor FromJson(const obj: ISuperObject; ctx: TSuperRttiContext = nil); overload;\n    constructor FromJson(const str: string; ctx: TSuperRttiContext = nil); overload;\n  end;\n{$ENDIF}\n\n  TSuperObjectIter = record\n    key: SOString;\n    val: ISuperObject;\n    Ite: TSuperAvlIterator;\n  end;\n\nfunction ObjectIsError(obj: TSuperObject): boolean;\nfunction ObjectIsType(const obj: ISuperObject; typ: TSuperType): boolean;\nfunction ObjectGetType(const obj: ISuperObject): TSuperType;\n\nfunction ObjectFindFirst(const obj: ISuperObject; var F: TSuperObjectIter): boolean;\nfunction ObjectFindNext(var F: TSuperObjectIter): boolean;\nprocedure ObjectFindClose(var F: TSuperObjectIter);\n\nfunction SO(const s: SOString = '{}'): ISuperObject; overload;\nfunction SO(const value: Variant): ISuperObject; overload;\nfunction SO(const Args: array of const): ISuperObject; overload;\n\nfunction SA(const Args: array of const): ISuperObject; overload;\n\nfunction JavaToDelphiDateTime(const dt: int64): TDateTime;\nfunction DelphiToJavaDateTime(const dt: TDateTime): int64;\n\n{$IFDEF VER210}\n\ntype\n  TSuperInvokeResult = (\n    irSuccess,\n    irMethothodError,  // method don't exist\n    irParamError,     // invalid parametters\n    irError            // other error\n  );\n\nfunction TrySOInvoke(var ctx: TSuperRttiContext; const obj: TValue; const method: string; const params: ISuperObject; var Return: ISuperObject): TSuperInvokeResult; overload;\nfunction SOInvoke(const obj: TValue; const method: string; const params: ISuperObject; ctx: TSuperRttiContext = nil): ISuperObject; overload;\nfunction SOInvoke(const obj: TValue; const method: string; const params: string; ctx: TSuperRttiContext = nil): ISuperObject; overload;\n{$ENDIF}\n\nimplementation\nuses sysutils,\n{$IFDEF UNIX}\n  baseunix, unix, DateUtils\n{$ELSE}\n  Windows\n{$ENDIF}\n{$IFDEF FPC}\n  ,sockets\n{$ELSE}\n  ,WinSock\n{$ENDIF};\n\n{$IFDEF DEBUG}\nvar\n  debugcount: integer = 0;\n{$ENDIF}\n\nconst\n  super_number_chars_set = ['0'..'9','.','+','-','e','E'];\n  super_hex_chars: PSOChar = '0123456789abcdef';\n  super_hex_chars_set = ['0'..'9','a'..'f','A'..'F'];\n\n  ESC_BS: PSOChar = '\\b';\n  ESC_LF: PSOChar = '\\n';\n  ESC_CR: PSOChar = '\\r';\n  ESC_TAB: PSOChar = '\\t';\n  ESC_FF: PSOChar = '\\f';\n  ESC_QUOT: PSOChar = '\\\"';\n  ESC_SL: PSOChar = '\\\\';\n  ESC_SR: PSOChar = '\\/';\n  ESC_ZERO: PSOChar = '\\u0000';\n\n  TOK_CRLF: PSOChar = #13#10;\n  TOK_SP: PSOChar = #32;\n  TOK_BS: PSOChar = #8;\n  TOK_TAB: PSOChar = #9;\n  TOK_LF: PSOChar = #10;\n  TOK_FF: PSOChar = #12;\n  TOK_CR: PSOChar = #13;\n//  TOK_SL: PSOChar = '\\';\n//  TOK_SR: PSOChar = '/';\n  TOK_NULL: PSOChar = 'null';\n  TOK_CBL: PSOChar = '{'; // curly bracket left\n  TOK_CBR: PSOChar = '}'; // curly bracket right\n  TOK_ARL: PSOChar = '[';\n  TOK_ARR: PSOChar = ']';\n  TOK_ARRAY: PSOChar = '[]';\n  TOK_OBJ: PSOChar = '{}'; // empty object\n  TOK_COM: PSOChar = ','; // Comma\n  TOK_DQT: PSOChar = '\"'; // Double Quote\n  TOK_TRUE: PSOChar = 'true';\n  TOK_FALSE: PSOChar = 'false';\n\n{$if (sizeof(Char) = 1)}\nfunction StrLComp(const Str1, Str2: PSOChar; MaxLen: Cardinal): Integer;\nvar\n  P1, P2: PWideChar;\n  I: Cardinal;\n  C1, C2: WideChar;\nbegin\n  P1 := Str1;\n  P2 := Str2;\n  I := 0;\n  while I < MaxLen do\n  begin\n    C1 := P1^;\n    C2 := P2^;\n\n    if (C1 <> C2) or (C1 = #0) then\n    begin\n      Result := Ord(C1) - Ord(C2);\n      Exit;\n    end;\n\n    Inc(P1);\n    Inc(P2);\n    Inc(I);\n  end;\n  Result := 0;\nend;\n\nfunction StrComp(const Str1, Str2: PSOChar): Integer;\nvar\n  P1, P2: PWideChar;\n  C1, C2: WideChar;\nbegin\n  P1 := Str1;\n  P2 := Str2;\n  while True do\n  begin\n    C1 := P1^;\n    C2 := P2^;\n\n    if (C1 <> C2) or (C1 = #0) then\n    begin\n      Result := Ord(C1) - Ord(C2);\n      Exit;\n    end;\n\n    Inc(P1);\n    Inc(P2);\n  end;\nend;\n\nfunction StrLen(const Str: PSOChar): Cardinal;\nvar\n  p: PSOChar;\nbegin\n  Result := 0;\n  if Str <> nil then\n  begin\n    p := Str;\n    while p^ <> #0 do inc(p);\n    Result := (p - Str);\n  end;\nend;\n{$ifend}\n\nfunction CurrToStr(c: Currency): SOString;\nvar\n  p: PSOChar;\n  i, len: Integer;\nbegin\n  Result := IntToStr(Abs(PInt64(@c)^));\n  len := Length(Result);\n  SetLength(Result, len+1);\n  if c <> 0 then\n  begin\n    while len <= 4 do\n    begin\n      Result := '0' + Result;\n      inc(len);\n    end;\n\n    p := PSOChar(Result);\n    inc(p, len-1);\n    i := 0;\n    repeat\n      if p^ <> '0' then\n      begin\n        len := len - i + 1;\n        repeat\n          p[1] := p^;\n          dec(p);\n          inc(i);\n        until i > 3;\n        Break;\n      end;\n      dec(p);\n      inc(i);\n      if i > 3 then\n      begin\n        len := len - i + 1;\n        Break;\n      end;\n    until false;\n    p[1] := '.';\n    SetLength(Result, len);\n    if c < 0 then\n      Result := '-' + Result;\n  end;\nend;\n\n{$IFDEF UNIX}\n  {$linklib c}\n{$ENDIF}\nfunction gcvt(value: Double; ndigit: longint; buf: PAnsiChar): PAnsiChar; cdecl;\n  external {$IFDEF MSWINDOWS} 'msvcrt.dll' name '_gcvt'{$ENDIF};\n\n{$IFDEF UNIX}\ntype\n  ptm = ^tm;\n  tm = record\n    tm_sec: Integer;\t\t(* Seconds: 0-59 (K&R says 0-61?) *)\n    tm_min: Integer;\t\t(* Minutes: 0-59 *)\n    tm_hour: Integer;\t(* Hours since midnight: 0-23 *)\n    tm_mday: Integer;\t(* Day of the month: 1-31 *)\n    tm_mon: Integer;\t\t(* Months *since* january: 0-11 *)\n    tm_year: Integer;\t(* Years since 1900 *)\n    tm_wday: Integer;\t(* Days since Sunday (0-6) *)\n    tm_yday: Integer;\t(* Days since Jan. 1: 0-365 *)\n    tm_isdst: Integer;\t(* +1 Daylight Savings Time, 0 No DST, -1 don't know *)\n  end;\n\nfunction mktime(p: ptm): LongInt; cdecl; external;\nfunction gmtime(const t: PLongint): ptm; cdecl; external;\nfunction localtime (const t: PLongint): ptm; cdecl; external;\n\nfunction DelphiToJavaDateTime(const dt: TDateTime): Int64;\nvar\n  p: ptm;\n  l, ms: Integer;\n  v: Int64;\nbegin\n  v := Round((dt - 25569) * 86400000);\n  ms := v mod 1000;\n  l := v div 1000;\n  p := localtime(@l);\n  Result := Int64(mktime(p)) * 1000 + ms;\nend;\n\nfunction JavaToDelphiDateTime(const dt: int64): TDateTime;\nvar\n  p: ptm;\n  l, ms: Integer;\nbegin\n  l := dt div 1000;\n  ms := dt mod 1000;\n  p := gmtime(@l);\n  Result := EncodeDateTime(p^.tm_year+1900, p^.tm_mon+1, p^.tm_mday, p^.tm_hour, p^.tm_min, p^.tm_sec, ms);\nend;\n{$ELSE}\n\n{$IFDEF WINDOWSNT_COMPATIBILITY}\nfunction DayLightCompareDate(const date: PSystemTime;\n  const compareDate: PSystemTime): Integer;\nvar\n  limit_day, dayinsecs, weekofmonth: Integer;\n  First: Word;\nbegin\n  if (date^.wMonth < compareDate^.wMonth) then\n  begin\n    Result := -1; (* We are in a month before the date limit. *)\n    Exit;\n  end;\n\n  if (date^.wMonth > compareDate^.wMonth) then\n  begin\n    Result := 1; (* We are in a month after the date limit. *)\n    Exit;\n  end;\n\n  (* if year is 0 then date is in day-of-week format, otherwise\n   * it's absolute date.\n   *)\n  if (compareDate^.wYear = 0) then\n  begin\n    (* compareDate.wDay is interpreted as number of the week in the month\n     * 5 means: the last week in the month *)\n    weekofmonth := compareDate^.wDay;\n    (* calculate the day of the first DayOfWeek in the month *)\n    First := (6 + compareDate^.wDayOfWeek - date^.wDayOfWeek + date^.wDay) mod 7 + 1;\n    limit_day := First + 7 * (weekofmonth - 1);\n    (* check needed for the 5th weekday of the month *)\n    if (limit_day > MonthDays[(date^.wMonth=2) and IsLeapYear(date^.wYear)][date^.wMonth - 1]) then\n      dec(limit_day, 7);\n  end\n  else\n    limit_day := compareDate^.wDay;\n\n  (* convert to seconds *)\n  limit_day := ((limit_day * 24  + compareDate^.wHour) * 60 + compareDate^.wMinute ) * 60;\n  dayinsecs := ((date^.wDay * 24  + date^.wHour) * 60 + date^.wMinute ) * 60 + date^.wSecond;\n  (* and compare *)\n\n  if dayinsecs < limit_day then\n    Result :=  -1 else\n    if dayinsecs > limit_day then\n      Result :=  1 else\n      Result :=  0; (* date is equal to the date limit. *)\nend;\n\nfunction CompTimeZoneID(const pTZinfo: PTimeZoneInformation;\n  lpFileTime: PFileTime; islocal: Boolean): LongWord;\nvar\n  ret: Integer;\n  beforeStandardDate, afterDaylightDate: Boolean;\n  llTime: Int64;\n  SysTime: TSystemTime;\n  ftTemp: TFileTime;\nbegin\n  llTime := 0;\n\n  if (pTZinfo^.DaylightDate.wMonth <> 0) then\n  begin\n    (* if year is 0 then date is in day-of-week format, otherwise\n     * it's absolute date.\n     *)\n    if ((pTZinfo^.StandardDate.wMonth = 0) or\n        ((pTZinfo^.StandardDate.wYear = 0) and\n        ((pTZinfo^.StandardDate.wDay < 1) or\n        (pTZinfo^.StandardDate.wDay > 5) or\n        (pTZinfo^.DaylightDate.wDay < 1) or\n        (pTZinfo^.DaylightDate.wDay > 5)))) then\n    begin\n      SetLastError(ERROR_INVALID_PARAMETER);\n      Result := TIME_ZONE_ID_INVALID;\n      Exit;\n    end;\n\n    if (not islocal) then\n    begin\n      llTime := PInt64(lpFileTime)^;\n      dec(llTime, Int64(pTZinfo^.Bias + pTZinfo^.DaylightBias) * 600000000);\n      PInt64(@ftTemp)^ := llTime;\n      lpFileTime := @ftTemp;\n    end;\n\n    FileTimeToSystemTime(lpFileTime^, SysTime);\n\n    (* check for daylight savings *)\n    ret := DayLightCompareDate(@SysTime, @pTZinfo^.StandardDate);\n    if (ret = -2) then\n    begin\n      Result := TIME_ZONE_ID_INVALID;\n      Exit;\n    end;\n\n    beforeStandardDate := ret < 0;\n\n    if (not islocal) then\n    begin\n      dec(llTime, Int64(pTZinfo^.StandardBias - pTZinfo^.DaylightBias) * 600000000);\n      PInt64(@ftTemp)^ := llTime;\n      FileTimeToSystemTime(lpFileTime^, SysTime);\n    end;\n\n    ret := DayLightCompareDate(@SysTime, @pTZinfo^.DaylightDate);\n    if (ret = -2) then\n    begin\n      Result := TIME_ZONE_ID_INVALID;\n      Exit;\n    end;\n\n    afterDaylightDate := ret >= 0;\n\n    Result := TIME_ZONE_ID_STANDARD;\n    if( pTZinfo^.DaylightDate.wMonth < pTZinfo^.StandardDate.wMonth ) then\n    begin\n      (* Northern hemisphere *)\n      if( beforeStandardDate and afterDaylightDate) then\n        Result := TIME_ZONE_ID_DAYLIGHT;\n    end else    (* Down south *)\n      if( beforeStandardDate or afterDaylightDate) then\n        Result := TIME_ZONE_ID_DAYLIGHT;\n  end else\n    (* No transition date *)\n    Result := TIME_ZONE_ID_UNKNOWN;\nend;\n\nfunction GetTimezoneBias(const pTZinfo: PTimeZoneInformation;\n  lpFileTime: PFileTime; islocal: Boolean; pBias: PLongint): Boolean;\nvar\n  bias: LongInt;\n  tzid: LongWord;\nbegin\n  bias := pTZinfo^.Bias;\n  tzid := CompTimeZoneID(pTZinfo, lpFileTime, islocal);\n\n  if( tzid = TIME_ZONE_ID_INVALID) then\n  begin\n    Result := False;\n    Exit;\n  end;\n  if (tzid = TIME_ZONE_ID_DAYLIGHT) then\n    inc(bias, pTZinfo^.DaylightBias)\n  else if (tzid = TIME_ZONE_ID_STANDARD) then\n    inc(bias, pTZinfo^.StandardBias);\n  pBias^ := bias;\n  Result := True;\nend;\n\nfunction SystemTimeToTzSpecificLocalTime(\n  lpTimeZoneInformation: PTimeZoneInformation;\n  lpUniversalTime, lpLocalTime: PSystemTime): BOOL;\nvar\n  ft: TFileTime;\n  lBias: LongInt;\n  llTime: Int64;\n  tzinfo: TTimeZoneInformation;\nbegin\n  if (lpTimeZoneInformation <> nil) then\n    tzinfo := lpTimeZoneInformation^ else\n    if (GetTimeZoneInformation(tzinfo) = TIME_ZONE_ID_INVALID) then\n    begin\n      Result := False;\n      Exit;\n    end;\n\n  if (not SystemTimeToFileTime(lpUniversalTime^, ft)) then\n  begin\n    Result := False;\n    Exit;\n  end;\n  llTime := PInt64(@ft)^;\n  if (not GetTimezoneBias(@tzinfo, @ft, False, @lBias)) then\n  begin\n    Result := False;\n    Exit;\n  end;\n  (* convert minutes to 100-nanoseconds-ticks *)\n  dec(llTime, Int64(lBias) * 600000000);\n  PInt64(@ft)^ := llTime;\n  Result := FileTimeToSystemTime(ft, lpLocalTime^);\nend;\n\nfunction TzSpecificLocalTimeToSystemTime(\n    const lpTimeZoneInformation: PTimeZoneInformation;\n    const lpLocalTime: PSystemTime; lpUniversalTime: PSystemTime): BOOL;\nvar\n  ft: TFileTime;\n  lBias: LongInt;\n  t: Int64;\n  tzinfo: TTimeZoneInformation;\nbegin\n  if (lpTimeZoneInformation <> nil) then\n    tzinfo := lpTimeZoneInformation^\n  else\n    if (GetTimeZoneInformation(tzinfo) = TIME_ZONE_ID_INVALID) then\n    begin\n      Result := False;\n      Exit;\n    end;\n\n  if (not SystemTimeToFileTime(lpLocalTime^, ft)) then\n  begin\n    Result := False;\n    Exit;\n  end;\n  t := PInt64(@ft)^;\n  if (not GetTimezoneBias(@tzinfo, @ft, True, @lBias)) then\n  begin\n    Result := False;\n    Exit;\n  end;\n  (* convert minutes to 100-nanoseconds-ticks *)\n  inc(t, Int64(lBias) * 600000000);\n  PInt64(@ft)^ := t;\n  Result := FileTimeToSystemTime(ft, lpUniversalTime^);\nend;\n{$ELSE}\nfunction TzSpecificLocalTimeToSystemTime(\n  lpTimeZoneInformation: PTimeZoneInformation;\n  lpLocalTime, lpUniversalTime: PSystemTime): BOOL; stdcall; external 'kernel32.dll';\n\nfunction SystemTimeToTzSpecificLocalTime(\n  lpTimeZoneInformation: PTimeZoneInformation;\n  lpUniversalTime, lpLocalTime: PSystemTime): BOOL; stdcall; external 'kernel32.dll';\n{$ENDIF}\n\nfunction JavaToDelphiDateTime(const dt: int64): TDateTime;\nvar\n  t: TSystemTime;\nbegin\n  DateTimeToSystemTime(25569 + (dt / 86400000), t);\n  SystemTimeToTzSpecificLocalTime(nil, @t, @t);\n  Result := SystemTimeToDateTime(t);\nend;\n\nfunction DelphiToJavaDateTime(const dt: TDateTime): int64;\nvar\n  t: TSystemTime;\nbegin\n  DateTimeToSystemTime(dt, t);\n  TzSpecificLocalTimeToSystemTime(nil, @t, @t);\n  Result := Round((SystemTimeToDateTime(t) - 25569) * 86400000)\nend;\n{$ENDIF}\n\n\nfunction SO(const s: SOString): ISuperObject; overload;\nbegin\n  Result := TSuperObject.ParseString(PSOChar(s), False);\nend;\n\nfunction SA(const Args: array of const): ISuperObject; overload;\ntype\n  TByteArray = array[0..sizeof(integer) - 1] of byte;\n  PByteArray = ^TByteArray;\nvar\n  j: Integer;\n  intf: IInterface;\nbegin\n  Result := TSuperObject.Create(stArray);\n  for j := 0 to length(Args) - 1 do\n    with Result.AsArray do\n    case TVarRec(Args[j]).VType of\n      vtInteger : Add(TSuperObject.Create(TVarRec(Args[j]).VInteger));\n      vtInt64   : Add(TSuperObject.Create(TVarRec(Args[j]).VInt64^));\n      vtBoolean : Add(TSuperObject.Create(TVarRec(Args[j]).VBoolean));\n      vtChar    : Add(TSuperObject.Create(SOString(TVarRec(Args[j]).VChar)));\n      vtWideChar: Add(TSuperObject.Create(SOChar(TVarRec(Args[j]).VWideChar)));\n      vtExtended: Add(TSuperObject.Create(TVarRec(Args[j]).VExtended^));\n      vtCurrency: Add(TSuperObject.CreateCurrency(TVarRec(Args[j]).VCurrency^));\n      vtString  : Add(TSuperObject.Create(SOString(TVarRec(Args[j]).VString^)));\n      vtPChar   : Add(TSuperObject.Create(SOString(TVarRec(Args[j]).VPChar^)));\n      vtAnsiString: Add(TSuperObject.Create(SOString(AnsiString(TVarRec(Args[j]).VAnsiString))));\n      vtWideString: Add(TSuperObject.Create(SOString(PWideChar(TVarRec(Args[j]).VWideString))));\n      vtInterface:\n        if TVarRec(Args[j]).VInterface = nil then\n          Add(nil) else\n          if IInterface(TVarRec(Args[j]).VInterface).QueryInterface(ISuperObject, intf) = 0 then\n            Add(ISuperObject(intf)) else\n            Add(nil);\n      vtPointer :\n        if TVarRec(Args[j]).VPointer = nil then\n          Add(nil) else\n          Add(TSuperObject.Create(PtrInt(TVarRec(Args[j]).VPointer)));\n      vtVariant:\n        Add(SO(TVarRec(Args[j]).VVariant^));\n      vtObject:\n        if TVarRec(Args[j]).VPointer = nil then\n          Add(nil) else\n          Add(TSuperObject.Create(PtrInt(TVarRec(Args[j]).VPointer)));\n      vtClass:\n        if TVarRec(Args[j]).VPointer = nil then\n          Add(nil) else\n          Add(TSuperObject.Create(PtrInt(TVarRec(Args[j]).VPointer)));\n{$if declared(vtUnicodeString)}\n      vtUnicodeString:\n          Add(TSuperObject.Create(SOString(string(TVarRec(Args[j]).VUnicodeString))));\n{$ifend}\n    else\n      assert(false);\n    end;\nend;\n\nfunction SO(const Args: array of const): ISuperObject; overload;\nvar\n  j: Integer;\n  arr: ISuperObject;\nbegin\n  Result := TSuperObject.Create(stObject);\n  arr := SA(Args);\n  with arr.AsArray do\n    for j := 0 to (Length div 2) - 1 do\n      Result.AsObject.PutO(O[j*2].AsString, O[(j*2) + 1]);\nend;\n\nfunction SO(const value: Variant): ISuperObject; overload;\nbegin\n  with TVarData(value) do\n  case VType of\n    varNull:     Result := nil;\n    varEmpty:    Result := nil;\n    varSmallInt: Result := TSuperObject.Create(VSmallInt);\n    varInteger:  Result := TSuperObject.Create(VInteger);\n    varSingle:   Result := TSuperObject.Create(VSingle);\n    varDouble:   Result := TSuperObject.Create(VDouble);\n    varCurrency: Result := TSuperObject.CreateCurrency(VCurrency);\n    varDate:     Result := TSuperObject.Create(DelphiToJavaDateTime(vDate));\n    varOleStr:   Result := TSuperObject.Create(SOString(VOleStr));\n    varBoolean:  Result := TSuperObject.Create(VBoolean);\n    varShortInt: Result := TSuperObject.Create(VShortInt);\n    varByte:     Result := TSuperObject.Create(VByte);\n    varWord:     Result := TSuperObject.Create(VWord);\n    varLongWord: Result := TSuperObject.Create(VLongWord);\n    varInt64:    Result := TSuperObject.Create(VInt64);\n    varString:   Result := TSuperObject.Create(SOString(AnsiString(VString)));\n{$if declared(varUString)}\n    varUString:  Result := TSuperObject.Create(SOString(string(VUString)));\n{$ifend}\n  else\n    raise Exception.CreateFmt('Unsuported variant data type: %d', [VType]);\n  end;\nend;\n\nfunction ObjectIsError(obj: TSuperObject): boolean;\nbegin\n  Result := PtrUInt(obj) > PtrUInt(-4000);\nend;\n\nfunction ObjectIsType(const obj: ISuperObject; typ: TSuperType): boolean;\nbegin\n  if obj <> nil then\n    Result := typ = obj.DataType else\n    Result := typ = stNull;\nend;\n\nfunction ObjectGetType(const obj: ISuperObject): TSuperType;\nbegin\n  if obj <> nil then\n    Result := obj.DataType else\n    Result := stNull;\nend;\n\nfunction ObjectFindFirst(const obj: ISuperObject; var F: TSuperObjectIter): boolean;\nvar\n  i: TSuperAvlEntry;\nbegin\n  if ObjectIsType(obj, stObject) then\n  begin\n    F.Ite := TSuperAvlIterator.Create(obj.AsObject);\n    F.Ite.First;\n    i := F.Ite.GetIter;\n    if i <> nil then\n    begin\n      f.key := i.Name;\n      f.val := i.Value;\n      Result := true;\n    end else\n      Result := False;\n  end else\n    Result := False;\nend;\n\nfunction ObjectFindNext(var F: TSuperObjectIter): boolean;\nvar\n  i: TSuperAvlEntry;\nbegin\n  F.Ite.Next;\n  i := F.Ite.GetIter;\n  if i <> nil then\n  begin\n    f.key := i.FName;\n    f.val := i.Value;\n    Result := true;\n  end else\n    Result := False;\nend;\n\nprocedure ObjectFindClose(var F: TSuperObjectIter);\nbegin\n  F.Ite.Free;\n  F.val := nil;\nend;\n\n{$IFDEF VER210}\n\nfunction serialtoboolean(ctx: TSuperRttiContext; var value: TValue; const index: ISuperObject): ISuperObject;\nbegin\n  Result := TSuperObject.Create(TValueData(value).FAsSLong <> 0);\nend;\n\nfunction serialtodatetime(ctx: TSuperRttiContext; var value: TValue; const index: ISuperObject): ISuperObject;\nbegin\n  Result := TSuperObject.Create(DelphiToJavaDateTime(TValueData(value).FAsDouble));\nend;\n\nfunction serialtoguid(ctx: TSuperRttiContext; var value: TValue; const index: ISuperObject): ISuperObject;\nvar\n  g: TGUID;\nbegin\n  value.ExtractRawData(@g);\n  Result := TSuperObject.Create(\n    format('%.8x-%.4x-%.4x-%.2x%.2x-%.2x%.2x%.2x%.2x%.2x%.2x',\n              [g.D1, g.D2, g.D3,\n               g.D4[0], g.D4[1], g.D4[2],\n               g.D4[3], g.D4[4], g.D4[5],\n               g.D4[6], g.D4[7]])\n  );\nend;\n\nfunction serialfromboolean(ctx: TSuperRttiContext; const obj: ISuperObject; var Value: TValue): Boolean;\nvar\n  o: ISuperObject;\nbegin\n  case ObjectGetType(obj) of\n  stBoolean:\n    begin\n      TValueData(Value).FAsSLong := obj.AsInteger;\n      Result := True;\n    end;\n  stInt:\n    begin\n      TValueData(Value).FAsSLong := ord(obj.AsInteger <> 0);\n      Result := True;\n    end;\n  stString:\n    begin\n      o := SO(obj.AsString);\n      if not ObjectIsType(o, stString) then\n        Result := serialfromboolean(ctx, SO(obj.AsString), Value) else\n        Result := False;\n    end;\n  else\n    Result := False;\n  end;\nend;\n\nfunction serialfromdatetime(ctx: TSuperRttiContext; const obj: ISuperObject; var Value: TValue): Boolean;\nvar\n  dt: TDateTime;\nbegin\n  case ObjectGetType(obj) of\n  stInt:\n    begin\n      TValueData(Value).FAsDouble := JavaToDelphiDateTime(obj.AsInteger);\n      Result := True;\n    end;\n  stString:\n    begin\n      if TryStrToDateTime(obj.AsString, dt) then\n      begin\n        TValueData(Value).FAsDouble := dt;\n        Result := True;\n      end else\n        Result := False;\n    end;\n  else\n    Result := False;\n  end;\nend;\n\nfunction UuidFromString(const s: PSOChar; Uuid: PGUID): Boolean;\nconst\n  hex2bin: array[#0..#102] of short = (\n    -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,        (* 0x00 *)\n    -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,        (* 0x10 *)\n    -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,        (* 0x20 *)\n     0, 1, 2, 3, 4, 5, 6, 7, 8, 9,-1,-1,-1,-1,-1,-1,        (* 0x30 *)\n    -1,10,11,12,13,14,15,-1,-1,-1,-1,-1,-1,-1,-1,-1,        (* 0x40 *)\n    -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,        (* 0x50 *)\n    -1,10,11,12,13,14,15);                                  (* 0x60 *)\nvar\n  i: Integer;\nbegin\n  if (strlen(s) <> 36) then Exit(False);\n\n  if ((s[8] <> '-') or (s[13] <> '-') or (s[18] <> '-') or (s[23] <> '-')) then\n     Exit(False);\n\n  for i := 0 to 35 do\n  begin\n    if not i in [8,13,18,23] then\n      if ((s[i] > 'f') or ((hex2bin[s[i]] = -1) and (s[i] <> ''))) then\n        Exit(False);\n  end;\n\n  uuid.D1 := ((hex2bin[s[0]] shl 28) or (hex2bin[s[1]] shl 24) or (hex2bin[s[2]] shl 20) or (hex2bin[s[3]] shl 16) or\n                (hex2bin[s[4]] shl 12) or (hex2bin[s[5]] shl 8) or (hex2bin[s[6]]  shl 4) or hex2bin[s[7]]);\n  uuid.D2 := (hex2bin[s[9]] shl 12) or (hex2bin[s[10]] shl 8) or (hex2bin[s[11]] shl 4) or hex2bin[s[12]];\n  uuid.D3 := (hex2bin[s[14]] shl 12) or (hex2bin[s[15]] shl 8) or (hex2bin[s[16]] shl 4) or hex2bin[s[17]];\n\n  uuid.D4[0] := (hex2bin[s[19]] shl 4) or hex2bin[s[20]];\n  uuid.D4[1] := (hex2bin[s[21]] shl 4) or hex2bin[s[22]];\n  uuid.D4[2] := (hex2bin[s[24]] shl 4) or hex2bin[s[25]];\n  uuid.D4[3] := (hex2bin[s[26]] shl 4) or hex2bin[s[27]];\n  uuid.D4[4] := (hex2bin[s[28]] shl 4) or hex2bin[s[29]];\n  uuid.D4[5] := (hex2bin[s[30]] shl 4) or hex2bin[s[31]];\n  uuid.D4[6] := (hex2bin[s[32]] shl 4) or hex2bin[s[33]];\n  uuid.D4[7] := (hex2bin[s[34]] shl 4) or hex2bin[s[35]];\n  Result := True;\nend;\n\nfunction serialfromguid(ctx: TSuperRttiContext; const obj: ISuperObject; var Value: TValue): Boolean;\nbegin\n  case ObjectGetType(obj) of\n    stNull:\n      begin\n        FillChar(Value.GetReferenceToRawData^, SizeOf(TGUID), 0);\n        Result := True;\n      end;\n    stString: Result := UuidFromString(PSOChar(obj.AsString), Value.GetReferenceToRawData);\n  else\n    Result := False;\n  end;\nend;\n\nfunction SOInvoke(const obj: TValue; const method: string; const params: ISuperObject; ctx: TSuperRttiContext): ISuperObject; overload;\nvar\n  owned: Boolean;\nbegin\n  if ctx = nil then\n  begin\n    ctx := TSuperRttiContext.Create;\n    owned := True;\n  end else\n    owned := False;\n  try\n    if TrySOInvoke(ctx, obj, method, params, Result) <> irSuccess then\n      raise Exception.Create('Invalid method call');\n  finally\n    if owned then\n      ctx.Free;\n  end;\nend;\n\nfunction SOInvoke(const obj: TValue; const method: string; const params: string; ctx: TSuperRttiContext): ISuperObject; overload;\nbegin\n  Result := SOInvoke(obj, method, so(params), ctx)\nend;\n\nfunction TrySOInvoke(var ctx: TSuperRttiContext; const obj: TValue;\n  const method: string; const params: ISuperObject;\n  var Return: ISuperObject): TSuperInvokeResult;\nvar\n  t: TRttiInstanceType;\n  m: TRttiMethod;\n  a: TArray<TValue>;\n  ps: TArray<TRttiParameter>;\n  v: TValue;\n  index: ISuperObject;\n\n  function GetParams: Boolean;\n  var\n    i: Integer;\n  begin\n    case ObjectGetType(params) of\n      stArray:\n        for i := 0 to Length(ps) - 1 do\n          if (pfOut in ps[i].Flags) then\n            TValue.Make(nil, ps[i].ParamType.Handle, a[i]) else\n            if not ctx.FromJson(ps[i].ParamType.Handle, params.AsArray[i], a[i]) then\n              Exit(False);\n      stObject:\n        for i := 0 to Length(ps) - 1 do\n          if (pfOut in ps[i].Flags) then\n            TValue.Make(nil, ps[i].ParamType.Handle, a[i]) else\n            if not ctx.FromJson(ps[i].ParamType.Handle, params.AsObject[ps[i].Name], a[i]) then\n              Exit(False);\n      stNull: ;\n    else\n      Exit(False);\n    end;\n    Result := True;\n  end;\n\n  procedure SetParams;\n  var\n    i: Integer;\n  begin\n    case ObjectGetType(params) of\n      stArray:\n        for i := 0 to Length(ps) - 1 do\n          if (ps[i].Flags * [pfVar, pfOut]) <> [] then\n            params.AsArray[i] := ctx.ToJson(a[i], index);\n      stObject:\n        for i := 0 to Length(ps) - 1 do\n          if (ps[i].Flags * [pfVar, pfOut]) <> [] then\n            params.AsObject[ps[i].Name] := ctx.ToJson(a[i], index);\n    end;\n  end;\n\nbegin\n  Result := irSuccess;\n  index := SO;\n  case obj.Kind of\n    tkClass:\n      begin\n        t := TRttiInstanceType(ctx.Context.GetType(obj.AsObject.ClassType));\n        m := t.GetMethod(method);\n        if m = nil then Exit(irMethothodError);\n        ps := m.GetParameters;\n        SetLength(a, Length(ps));\n        if not GetParams then Exit(irParamError);\n        if m.IsClassMethod then\n        begin\n          v := m.Invoke(obj.AsObject.ClassType, a);\n          Return := ctx.ToJson(v, index);\n          SetParams;\n        end else\n        begin\n          v := m.Invoke(obj, a);\n          Return := ctx.ToJson(v, index);\n          SetParams;\n        end;\n      end;\n    tkClassRef:\n      begin\n        t := TRttiInstanceType(ctx.Context.GetType(obj.AsClass));\n        m := t.GetMethod(method);\n        if m = nil then Exit(irMethothodError);\n        ps := m.GetParameters;\n        SetLength(a, Length(ps));\n\n        if not GetParams then Exit(irParamError);\n        if m.IsClassMethod then\n        begin\n          v := m.Invoke(obj, a);\n          Return := ctx.ToJson(v, index);\n          SetParams;\n        end else\n          Exit(irError);\n      end;\n  else\n    Exit(irError);\n  end;\nend;\n\n{$ENDIF}\n\n{ TSuperEnumerator }\n\nconstructor TSuperEnumerator.Create(const obj: ISuperObject);\nbegin\n  FObj := obj;\n  FCount := -1;\n  if ObjectIsType(FObj, stObject) then\n    FObjEnum := FObj.AsObject.GetEnumerator else\n    FObjEnum := nil;\nend;\n\ndestructor TSuperEnumerator.Destroy;\nbegin\n  if FObjEnum <> nil then\n    FObjEnum.Free;\nend;\n\nfunction TSuperEnumerator.MoveNext: Boolean;\nbegin\n  case ObjectGetType(FObj) of\n    stObject: Result := FObjEnum.MoveNext;\n    stArray:\n      begin\n        inc(FCount);\n        if FCount < FObj.AsArray.Length then\n          Result := True else\n          Result := False;\n      end;\n  else\n    Result := false;\n  end;\nend;\n\nfunction TSuperEnumerator.GetCurrent: ISuperObject;\nbegin\n  case ObjectGetType(FObj) of\n    stObject: Result := FObjEnum.Current.Value;\n    stArray: Result := FObj.AsArray.GetO(FCount);\n  else\n    Result := FObj;\n  end;\nend;\n\n{ TSuperObject }\n\nconstructor TSuperObject.Create(jt: TSuperType);\nbegin\n  inherited Create;\n{$IFDEF DEBUG}\n  InterlockedIncrement(debugcount);\n{$ENDIF}\n\n  FProcessing := false;\n  FDataPtr := nil;\n  FDataType := jt;\n  case FDataType of\n    stObject: FO.c_object := TSuperTableString.Create;\n    stArray: FO.c_array := TSuperArray.Create;\n    stString: FOString := '';\n  else\n    FO.c_object := nil;\n  end;\nend;\n\nconstructor TSuperObject.Create(b: boolean);\nbegin\n  Create(stBoolean);\n  FO.c_boolean := b;\nend;\n\nconstructor TSuperObject.Create(i: SuperInt);\nbegin\n  Create(stInt);\n  FO.c_int := i;\nend;\n\nconstructor TSuperObject.Create(d: double);\nbegin\n  Create(stDouble);\n  FO.c_double := d;\nend;\n\nconstructor TSuperObject.CreateCurrency(c: Currency);\nbegin\n  Create(stCurrency);\n  FO.c_currency := c;\nend;\n\ndestructor TSuperObject.Destroy;\nbegin\n{$IFDEF DEBUG}\n  InterlockedDecrement(debugcount);\n{$ENDIF}\n  case FDataType of\n    stObject: FO.c_object.Free;\n    stArray: FO.c_array.Free;\n  end;\n  inherited;\nend;\n\nfunction TSuperObject.Write(writer: TSuperWriter; indent: boolean; escape: boolean; level: integer): Integer;\nfunction DoEscape(str: PSOChar; len: Integer): Integer;\nvar\n  pos, start_offset: Integer;\n  c: SOChar;\n  buf: array[0..5] of SOChar;\ntype\n  TByteChar = record\n  case integer of\n    0: (a, b: Byte);\n    1: (c: WideChar);\n  end;\n  begin\n    if str = nil then\n    begin\n      Result := 0;\n      exit;\n    end;\n    pos := 0; start_offset := 0;\n    with writer do\n    while pos < len do\n    begin\n      c := str[pos];\n      case c of\n        #8,#9,#10,#12,#13,'\"','\\','/':\n          begin\n            if(pos - start_offset > 0) then\n              Append(str + start_offset, pos - start_offset);\n\n            if(c = #8) then Append(ESC_BS, 2)\n            else if (c = #9) then Append(ESC_TAB, 2)\n            else if (c = #10) then Append(ESC_LF, 2)\n            else if (c = #12) then Append(ESC_FF, 2)\n            else if (c = #13) then Append(ESC_CR, 2)\n            else if (c = '\"') then Append(ESC_QUOT, 2)\n            else if (c = '\\') then Append(ESC_SL, 2)\n            else if (c = '/') then Append(ESC_SR, 2);\n            inc(pos);\n            start_offset := pos;\n          end;\n      else\n        if (SOIChar(c) > 255) then\n        begin\n          if(pos - start_offset > 0) then\n            Append(str + start_offset, pos - start_offset);\n          buf[0] := '\\';\n          buf[1] := 'u';\n          buf[2] := super_hex_chars[TByteChar(c).b shr 4];\n          buf[3] := super_hex_chars[TByteChar(c).b and $f];\n          buf[4] := super_hex_chars[TByteChar(c).a shr 4];\n          buf[5] := super_hex_chars[TByteChar(c).a and $f];\n          Append(@buf, 6);\n          inc(pos);\n          start_offset := pos;\n        end else\n        if (c < #32) or (c > #127) then\n        begin\n          if(pos - start_offset > 0) then\n            Append(str + start_offset, pos - start_offset);\n          buf[0] := '\\';\n          buf[1] := 'u';\n          buf[2] := '0';\n          buf[3] := '0';\n          buf[4] := super_hex_chars[ord(c) shr 4];\n          buf[5] := super_hex_chars[ord(c) and $f];\n          Append(buf, 6);\n          inc(pos);\n          start_offset := pos;\n        end else\n          inc(pos);\n      end;\n    end;\n    if(pos - start_offset > 0) then\n      writer.Append(str + start_offset, pos - start_offset);\n    Result := 0;\n  end;\n\nfunction DoMinimalEscape(str: PSOChar; len: Integer): Integer;\nvar\n  pos, start_offset: Integer;\n  c: SOChar;\ntype\n  TByteChar = record\n  case integer of\n    0: (a, b: Byte);\n    1: (c: WideChar);\n  end;\n  begin\n    if str = nil then\n    begin\n      Result := 0;\n      exit;\n    end;\n    pos := 0; start_offset := 0;\n    with writer do\n    while pos < len do\n    begin\n      c := str[pos];\n      case c of\n        #0:\n          begin\n            if(pos - start_offset > 0) then\n              Append(str + start_offset, pos - start_offset);\n            Append(ESC_ZERO, 6);\n            inc(pos);\n            start_offset := pos;\n          end;\n        '\"':\n          begin\n            if(pos - start_offset > 0) then\n              Append(str + start_offset, pos - start_offset);\n            Append(ESC_QUOT, 2);\n            inc(pos);\n            start_offset := pos;\n          end;\n        '\\':\n          begin\n            if(pos - start_offset > 0) then\n              Append(str + start_offset, pos - start_offset);\n            Append(ESC_SL, 2);\n            inc(pos);\n            start_offset := pos;\n          end;\n        '/':\n          begin\n            if(pos - start_offset > 0) then\n              Append(str + start_offset, pos - start_offset);\n            Append(ESC_SR, 2);\n            inc(pos);\n            start_offset := pos;\n          end;\n      else\n        inc(pos);\n      end;\n    end;\n    if(pos - start_offset > 0) then\n      writer.Append(str + start_offset, pos - start_offset);\n    Result := 0;\n  end;\n\n\n  procedure _indent(i: shortint; r: boolean);\n  begin\n    inc(level, i);\n    if r then\n      with writer do\n      begin\n{$IFDEF MSWINDOWS}\n        Append(TOK_CRLF, 2);\n{$ELSE}\n        Append(TOK_LF, 1);\n{$ENDIF}\n        for i := 0 to level - 1 do\n          Append(TOK_SP, 1);\n      end;\n  end;\nvar\n  k,j: Integer;\n  iter: TSuperObjectIter;\n  st: AnsiString;\n  val: ISuperObject;\n  fbuffer: array[0..31] of AnsiChar;\nconst\n  ENDSTR_A: PSOChar = '\": ';\n  ENDSTR_B: PSOChar = '\":';\nbegin\n\n  if FProcessing then\n  begin\n    Result := writer.Append(TOK_NULL, 4);\n    Exit;\n  end;\n\n  FProcessing := true;\n  with writer do\n  try\n    case FDataType of\n      stObject:\n        if FO.c_object.FCount > 0 then\n        begin\n          k := 0;\n          Append(TOK_CBL, 1);\n          if indent then _indent(1, false);\n          if ObjectFindFirst(Self, iter) then\n          repeat\n  {$IFDEF SUPER_METHOD}\n            if (iter.val = nil) or not ObjectIsType(iter.val, stMethod) then\n            begin\n  {$ENDIF}\n              if (iter.val = nil) or (not iter.val.Processing) then\n              begin\n                if(k <> 0) then\n                  Append(TOK_COM, 1);\n                if indent then _indent(0, true);\n                Append(TOK_DQT, 1);\n                if escape then\n                  doEscape(PSOChar(iter.key), Length(iter.key)) else\n                  DoMinimalEscape(PSOChar(iter.key), Length(iter.key));\n                if indent then\n                  Append(ENDSTR_A, 3) else\n                  Append(ENDSTR_B, 2);\n                if(iter.val = nil) then\n                  Append(TOK_NULL, 4) else\n                  iter.val.write(writer, indent, escape, level);\n                inc(k);\n              end;\n  {$IFDEF SUPER_METHOD}\n            end;\n  {$ENDIF}\n          until not ObjectFindNext(iter);\n          ObjectFindClose(iter);\n          if indent then _indent(-1, true);\n          Result := Append(TOK_CBR, 1);\n        end else\n          Result := Append(TOK_OBJ, 2);\n      stBoolean:\n        begin\n          if (FO.c_boolean) then\n            Result := Append(TOK_TRUE, 4) else\n            Result := Append(TOK_FALSE, 5);\n        end;\n      stInt:\n        begin\n          str(FO.c_int, st);\n          Result := Append(PSOChar(SOString(st)));\n        end;\n      stDouble:\n        Result := Append(PSOChar(SOString(gcvt(FO.c_double, 15, fbuffer))));\n      stCurrency:\n        begin\n          Result := Append(PSOChar(CurrToStr(FO.c_currency)));\n        end;\n      stString:\n        begin\n          Append(TOK_DQT, 1);\n          if escape then\n            doEscape(PSOChar(FOString), Length(FOString)) else\n            DoMinimalEscape(PSOChar(FOString), Length(FOString));\n          Append(TOK_DQT, 1);\n          Result := 0;\n        end;\n      stArray:\n        if FO.c_array.FLength > 0 then\n        begin\n          Append(TOK_ARL, 1);\n          if indent then _indent(1, true);\n          k := 0;\n          j := 0;\n          while k < FO.c_array.FLength do\n          begin\n\n            val :=  FO.c_array.GetO(k);\n  {$IFDEF SUPER_METHOD}\n            if not ObjectIsType(val, stMethod) then\n            begin\n  {$ENDIF}\n              if (val = nil) or (not val.Processing) then\n              begin\n                if (j <> 0) then\n                  Append(TOK_COM, 1);\n                if(val = nil) then\n                  Append(TOK_NULL, 4) else\n                  val.write(writer, indent, escape, level);\n                inc(j);\n              end;\n  {$IFDEF SUPER_METHOD}\n            end;\n  {$ENDIF}\n            inc(k);\n          end;\n          if indent then _indent(-1, false);\n          Result := Append(TOK_ARR, 1);\n        end else\n          Result := Append(TOK_ARRAY, 2);\n      stNull:\n          Result := Append(TOK_NULL, 4);\n    else\n      Result := 0;\n    end;\n  finally\n    FProcessing := false;\n  end;\nend;\n\nfunction TSuperObject.IsType(AType: TSuperType): boolean;\nbegin\n  Result := AType = FDataType;\nend;\n\nfunction TSuperObject.AsBoolean: boolean;\nbegin\n  case FDataType of\n    stBoolean: Result := FO.c_boolean;\n    stInt: Result := (FO.c_int <> 0);\n    stDouble: Result := (FO.c_double <> 0);\n    stCurrency: Result := (FO.c_currency <> 0);\n    stString: Result := (Length(FOString) <> 0);\n    stNull: Result := False;\n  else\n    Result := True;\n  end;\nend;\n\nfunction TSuperObject.AsInteger: SuperInt;\nvar\n  code: integer;\n  cint: SuperInt;\nbegin\n  case FDataType of\n    stInt: Result := FO.c_int;\n    stDouble: Result := round(FO.c_double);\n    stCurrency: Result := round(FO.c_currency);\n    stBoolean: Result := ord(FO.c_boolean);\n    stString:\n      begin\n        Val(FOString, cint, code);\n        if code = 0 then\n          Result := cint else\n          Result := 0;\n      end;\n  else\n    Result := 0;\n  end;\nend;\n\nfunction TSuperObject.AsDouble: Double;\nvar\n  code: integer;\n  cdouble: double;\nbegin\n  case FDataType of\n    stDouble: Result := FO.c_double;\n    stCurrency: Result := FO.c_currency;\n    stInt: Result := FO.c_int;\n    stBoolean: Result := ord(FO.c_boolean);\n    stString:\n      begin\n        Val(FOString, cdouble, code);\n        if code = 0 then\n          Result := cdouble else\n          Result := 0.0;\n      end;\n  else\n    Result := 0.0;\n  end;\nend;\n\nfunction TSuperObject.AsCurrency: Currency;\nvar\n  code: integer;\n  cdouble: double;\nbegin\n  case FDataType of\n    stDouble: Result := FO.c_double;\n    stCurrency: Result := FO.c_currency;\n    stInt: Result := FO.c_int;\n    stBoolean: Result := ord(FO.c_boolean);\n    stString:\n      begin\n        Val(FOString, cdouble, code);\n        if code = 0 then\n          Result := cdouble else\n          Result := 0.0;\n      end;\n  else\n    Result := 0.0;\n  end;\nend;\n\nfunction TSuperObject.AsString: SOString;\nbegin\n  if FDataType = stString then\n    Result := FOString else\n    Result := AsJSon(false, false);\nend;\n\nfunction TSuperObject.GetEnumerator: TSuperEnumerator;\nbegin\n  Result := TSuperEnumerator.Create(Self);\nend;\n\nprocedure TSuperObject.AfterConstruction;\nbegin\n  InterlockedDecrement(FRefCount);\nend;\n\nprocedure TSuperObject.BeforeDestruction;\nbegin\n  if RefCount <> 0 then\n    raise Exception.Create('Invalid pointer');\nend;\n\nfunction TSuperObject.AsArray: TSuperArray;\nbegin\n  if FDataType = stArray then\n    Result := FO.c_array else\n    Result := nil;\nend;\n\nfunction TSuperObject.AsObject: TSuperTableString;\nbegin\n  if FDataType = stObject then\n    Result := FO.c_object else\n    Result := nil;\nend;\n\nfunction TSuperObject.AsJSon(indent, escape: boolean): SOString;\nvar\n  pb: TSuperWriterString;\nbegin\n  pb := TSuperWriterString.Create;\n  try\n    if(Write(pb, indent, escape, 0) < 0) then\n    begin\n      Result := '';\n      Exit;\n    end;\n    if pb.FBPos > 0 then\n      Result := pb.FBuf else\n      Result := '';\n  finally\n    pb.Free;\n  end;\nend;\n\nclass function TSuperObject.ParseString(s: PSOChar; strict: Boolean; partial: boolean; const this: ISuperObject;\n  options: TSuperFindOptions; const put: ISuperObject; dt: TSuperType): ISuperObject;\nvar\n  tok: TSuperTokenizer;\n  obj: ISuperObject;\nbegin\n  tok := TSuperTokenizer.Create;\n  obj := ParseEx(tok, s, -1, strict, this, options, put, dt);\n  if(tok.err <> teSuccess) or (not partial and (s[tok.char_offset] <> #0)) then\n    Result := nil else\n    Result := obj;\n  tok.Free;\nend;\n\nclass function TSuperObject.ParseStream(stream: TStream; strict: Boolean;\n  partial: boolean; const this: ISuperObject; options: TSuperFindOptions;\n   const put: ISuperObject; dt: TSuperType): ISuperObject;\nconst\n  BUFFER_SIZE = 1024;\nvar\n  tok: TSuperTokenizer;\n  buffera: array[0..BUFFER_SIZE-1] of AnsiChar;\n  bufferw: array[0..BUFFER_SIZE-1] of SOChar;\n  bom: array[0..1] of byte;\n  unicode: boolean;\n  j, size: Integer;\n  st: string;\nbegin\n  st := '';\n  tok := TSuperTokenizer.Create;\n\n  if (stream.Read(bom, sizeof(bom)) = 2) and (bom[0] = $FF) and (bom[1] = $FE) then\n  begin\n    unicode := true;\n    size := stream.Read(bufferw, BUFFER_SIZE * SizeOf(SoChar)) div SizeOf(SoChar);\n  end else\n    begin\n      unicode := false;\n      stream.Seek(0, soFromBeginning);\n      size := stream.Read(buffera, BUFFER_SIZE);\n    end;\n\n  while size > 0 do\n  begin\n    if not unicode then\n      for j := 0 to size - 1 do\n        bufferw[j] := SOChar(buffera[j]);\n    ParseEx(tok, bufferw, size, strict, this, options, put, dt);\n\n    if tok.err = teContinue then\n      begin\n        if not unicode then\n          size := stream.Read(buffera, BUFFER_SIZE) else\n          size := stream.Read(bufferw, BUFFER_SIZE * SizeOf(SoChar)) div SizeOf(SoChar);\n      end else\n      Break;\n  end;\n  if(tok.err <> teSuccess) or (not partial and (st[tok.char_offset] <> #0)) then\n    Result := nil else\n    Result := tok.stack[tok.depth].current;\n  tok.Free;\nend;\n\nclass function TSuperObject.ParseFile(const FileName: string; strict: Boolean;\n  partial: boolean; const this: ISuperObject; options: TSuperFindOptions;\n  const put: ISuperObject; dt: TSuperType): ISuperObject;\nvar\n  stream: TFileStream;\nbegin\n  stream := TFileStream.Create(FileName, fmOpenRead, fmShareDenyWrite);\n  try\n    Result := ParseStream(stream, strict, partial, this, options, put, dt);\n  finally\n    stream.Free;\n  end;\nend;\n\nclass function TSuperObject.ParseEx(tok: TSuperTokenizer; str: PSOChar; len: integer;\n  strict: Boolean; const this: ISuperObject; options: TSuperFindOptions; const put: ISuperObject; dt: TSuperType): ISuperObject;\n\nconst\n  spaces = [#32,#8,#9,#10,#12,#13];\n  delimiters = ['\"', '.', '[', ']', '{', '}', '(', ')', ',', ':', #0];\n  reserved = delimiters + spaces;\n  path = ['a'..'z', 'A'..'Z', '.', '_'];\n\n  function hexdigit(x: SOChar): byte;\n  begin\n    if x <= '9' then\n      Result := byte(x) - byte('0') else\n      Result := (byte(x) and 7) + 9;\n  end;\n  function min(v1, v2: integer): integer; begin if v1 < v2 then result := v1 else result := v2 end;\n\nvar\n  obj: ISuperObject;\n  v: SOChar;\n{$IFDEF SUPER_METHOD}\n  sm: TSuperMethod;\n{$ENDIF}\n  numi: SuperInt;\n  numd: Double;\n  code: integer;\n  TokRec: PSuperTokenerSrec;\n  evalstack: integer;\n  p: PSOChar;\n\n  function IsEndDelimiter(v: AnsiChar): Boolean;\n  begin\n    if tok.depth > 0 then\n      case tok.stack[tok.depth - 1].state of\n        tsArrayAdd: Result := v in [',', ']', #0];\n        tsObjectValueAdd: Result := v in [',', '}', #0];\n      else\n        Result := v = #0;\n      end else\n        Result := v = #0;\n  end;\n\nlabel out, redo_char;\nbegin\n  evalstack := 0;\n  obj := nil;\n  Result := nil;\n  TokRec := @tok.stack[tok.depth];\n\n  tok.char_offset := 0;\n  tok.err := teSuccess;\n\n  repeat\n    if (tok.char_offset = len) then\n    begin\n      if (tok.depth = 0) and (TokRec^.state = tsEatws) and\n         (TokRec^.saved_state = tsFinish) then\n        tok.err := teSuccess else\n        tok.err := teContinue;\n      goto out;\n    end;\n\n    v := str^;\n\n    case v of\n    #10:\n      begin\n        inc(tok.line);\n        tok.col := 0;\n      end;\n    #9: inc(tok.col, 4);\n    else\n      inc(tok.col);\n    end;\n\nredo_char:\n    case TokRec^.state of\n    tsEatws:\n      begin\n        if (SOIChar(v) < 256) and (AnsiChar(v) in spaces) then {nop} else\n        if (v = '/') then\n        begin\n          tok.pb.Reset;\n          tok.pb.Append(@v, 1);\n          TokRec^.state := tsCommentStart;\n        end else begin\n          TokRec^.state := TokRec^.saved_state;\n          goto redo_char;\n        end\n      end;\n\n    tsStart:\n      case v of\n      '\"',\n      '''':\n        begin\n          TokRec^.state := tsString;\n          tok.pb.Reset;\n          tok.quote_char := v;\n        end;\n      '-':\n        begin\n          TokRec^.state := tsNumber;\n          tok.pb.Reset;\n          tok.is_double := 0;\n          tok.floatcount := -1;\n          goto redo_char;\n        end;\n\n      '0'..'9':\n        begin\n          if (tok.depth = 0) then\n            case ObjectGetType(this) of\n            stObject:\n              begin\n                TokRec^.state := tsIdentifier;\n                TokRec^.current := this;\n                goto redo_char;\n              end;\n          end;\n          TokRec^.state := tsNumber;\n          tok.pb.Reset;\n          tok.is_double := 0;\n          tok.floatcount := -1;\n          goto redo_char;\n        end;\n      '{':\n        begin\n          TokRec^.state := tsEatws;\n          TokRec^.saved_state := tsObjectFieldStart;\n          TokRec^.current := TSuperObject.Create(stObject);\n        end;\n      '[':\n        begin\n          TokRec^.state := tsEatws;\n          TokRec^.saved_state := tsArray;\n          TokRec^.current := TSuperObject.Create(stArray);\n        end;\n{$IFDEF SUPER_METHOD}\n      '(':\n        begin\n          if (tok.depth = 0) and ObjectIsType(this, stMethod) then\n          begin\n            TokRec^.current := this;\n            TokRec^.state := tsParamValue;\n          end;\n        end;\n{$ENDIF}\n      'N',\n      'n':\n        begin\n          TokRec^.state := tsNull;\n          tok.pb.Reset;\n          tok.st_pos := 0;\n          goto redo_char;\n        end;\n      'T',\n      't',\n      'F',\n      'f':\n        begin\n          TokRec^.state := tsBoolean;\n          tok.pb.Reset;\n          tok.st_pos := 0;\n          goto redo_char;\n        end;\n      else\n        TokRec^.state := tsIdentifier;\n        tok.pb.Reset;\n        goto redo_char;\n      end;\n\n    tsFinish:\n      begin\n        if(tok.depth = 0) then goto out;\n        obj := TokRec^.current;\n        tok.ResetLevel(tok.depth);\n        dec(tok.depth);\n        TokRec := @tok.stack[tok.depth];\n        goto redo_char;\n      end;\n\n    tsNull:\n      begin\n        tok.pb.Append(@v, 1);\n        if (StrLComp(TOK_NULL, PSOChar(tok.pb.FBuf), min(tok.st_pos + 1, 4)) = 0) then\n        begin\n          if (tok.st_pos = 4) then\n          if (((SOIChar(v) < 256) and (AnsiChar(v) in path)) or (SOIChar(v) >= 256)) then\n            TokRec^.state := tsIdentifier else\n          begin\n            TokRec^.current := TSuperObject.Create(stNull);\n            TokRec^.saved_state := tsFinish;\n            TokRec^.state := tsEatws;\n            goto redo_char;\n          end;\n        end else\n        begin\n          TokRec^.state := tsIdentifier;\n          tok.pb.FBuf[tok.st_pos] := #0;\n          dec(tok.pb.FBPos);\n          goto redo_char;\n        end;\n        inc(tok.st_pos);\n      end;\n\n    tsCommentStart:\n      begin\n        if(v = '*') then\n        begin\n          TokRec^.state := tsComment;\n        end else\n        if (v = '/') then\n        begin\n          TokRec^.state := tsCommentEol;\n        end else\n        begin\n          tok.err := teParseComment;\n          goto out;\n        end;\n        tok.pb.Append(@v, 1);\n      end;\n\n    tsComment:\n      begin\n        if(v = '*') then\n          TokRec^.state := tsCommentEnd;\n        tok.pb.Append(@v, 1);\n      end;\n\n    tsCommentEol:\n      begin\n        if (v = #10) then\n          TokRec^.state := tsEatws else\n          tok.pb.Append(@v, 1);\n      end;\n\n    tsCommentEnd:\n      begin\n        tok.pb.Append(@v, 1);\n        if (v = '/') then\n          TokRec^.state := tsEatws else\n          TokRec^.state := tsComment;\n      end;\n\n    tsString:\n      begin\n        if (v = tok.quote_char) then\n        begin\n          TokRec^.current := TSuperObject.Create(SOString(tok.pb.GetString));\n          TokRec^.saved_state := tsFinish;\n          TokRec^.state := tsEatws;\n        end else\n        if (v = '\\') then\n        begin\n          TokRec^.saved_state := tsString;\n          TokRec^.state := tsStringEscape;\n        end else\n        begin\n          tok.pb.Append(@v, 1);\n        end\n      end;\n\n    tsEvalProperty:\n      begin\n        if (TokRec^.current = nil) and (foCreatePath in options) then\n        begin\n          TokRec^.current := TSuperObject.Create(stObject);\n          TokRec^.parent.AsObject.PutO(tok.pb.Fbuf, TokRec^.current)\n        end else\n        if not ObjectIsType(TokRec^.current, stObject) then\n        begin\n          tok.err := teEvalObject;\n          goto out;\n        end;\n        tok.pb.Reset;\n        TokRec^.state := tsIdentifier;\n        goto redo_char;\n      end;\n\n    tsEvalArray:\n      begin\n        if (TokRec^.current = nil) and (foCreatePath in options) then\n        begin\n          TokRec^.current := TSuperObject.Create(stArray);\n          TokRec^.parent.AsObject.PutO(tok.pb.Fbuf, TokRec^.current)\n        end else\n        if not ObjectIsType(TokRec^.current, stArray) then\n        begin\n          tok.err := teEvalArray;\n          goto out;\n        end;\n        tok.pb.Reset;\n        TokRec^.state := tsParamValue;\n        goto redo_char;\n      end;\n{$IFDEF SUPER_METHOD}\n    tsEvalMethod:\n      begin\n        if ObjectIsType(TokRec^.current, stMethod) and assigned(TokRec^.current.AsMethod) then\n        begin\n          tok.pb.Reset;\n          TokRec^.obj := TSuperObject.Create(stArray);\n          TokRec^.state := tsMethodValue;\n          goto redo_char;\n        end else\n        begin\n          tok.err := teEvalMethod;\n          goto out;\n        end;\n      end;\n\n    tsMethodValue:\n      begin\n        case v of\n        ')':\n            TokRec^.state := tsIdentifier;\n        else\n          if (tok.depth >= SUPER_TOKENER_MAX_DEPTH-1) then\n          begin\n            tok.err := teDepth;\n            goto out;\n          end;\n          inc(evalstack);\n          TokRec^.state := tsMethodPut;\n          inc(tok.depth);\n          tok.ResetLevel(tok.depth);\n          TokRec := @tok.stack[tok.depth];\n          goto redo_char;\n        end;\n      end;\n\n    tsMethodPut:\n      begin\n        TokRec^.obj.AsArray.Add(obj);\n        case v of\n          ',':\n            begin\n              tok.pb.Reset;\n              TokRec^.saved_state := tsMethodValue;\n              TokRec^.state := tsEatws;\n            end;\n          ')':\n            begin\n              if TokRec^.obj.AsArray.Length = 1 then\n                TokRec^.obj := TokRec^.obj.AsArray.GetO(0);\n              dec(evalstack);\n              tok.pb.Reset;\n              TokRec^.saved_state := tsIdentifier;\n              TokRec^.state := tsEatws;\n            end;\n        else\n          tok.err := teEvalMethod;\n          goto out;\n        end;\n      end;\n{$ENDIF}\n    tsParamValue:\n      begin\n        case v of\n        ']':\n            TokRec^.state := tsIdentifier;\n        else\n          if (tok.depth >= SUPER_TOKENER_MAX_DEPTH-1) then\n          begin\n            tok.err := teDepth;\n            goto out;\n          end;\n          inc(evalstack);\n          TokRec^.state := tsParamPut;\n          inc(tok.depth);\n          tok.ResetLevel(tok.depth);\n          TokRec := @tok.stack[tok.depth];\n          goto redo_char;\n        end;\n      end;\n\n    tsParamPut:\n      begin\n        dec(evalstack);\n        TokRec^.obj := obj;\n        tok.pb.Reset;\n        TokRec^.saved_state := tsIdentifier;\n        TokRec^.state := tsEatws;\n        if v <> ']' then\n        begin\n          tok.err := teEvalArray;\n          goto out;\n        end;\n      end;\n\n    tsIdentifier:\n      begin\n        if (this = nil) then\n        begin\n          if (SOIChar(v) < 256) and IsEndDelimiter(AnsiChar(v)) then\n          begin\n            if not strict then\n            begin\n              tok.pb.TrimRight;\n              TokRec^.current := TSuperObject.Create(tok.pb.Fbuf);\n              TokRec^.saved_state := tsFinish;\n              TokRec^.state := tsEatws;\n              goto redo_char;\n            end else\n            begin\n              tok.err := teParseString;\n              goto out;\n            end;\n          end else\n          if (v = '\\') then\n          begin\n            TokRec^.saved_state := tsIdentifier;\n            TokRec^.state := tsStringEscape;\n          end else\n            tok.pb.Append(@v, 1);\n        end else\n        begin\n         if (SOIChar(v) < 256) and (AnsiChar(v) in reserved) then\n         begin\n           TokRec^.gparent := TokRec^.parent;\n           if TokRec^.current = nil then\n             TokRec^.parent := this else\n             TokRec^.parent := TokRec^.current;\n\n             case ObjectGetType(TokRec^.parent) of\n               stObject:\n                 case v of\n                   '.':\n                     begin\n                       TokRec^.state := tsEvalProperty;\n                       if tok.pb.FBPos > 0 then\n                         TokRec^.current := TokRec^.parent.AsObject.GetO(tok.pb.Fbuf);\n                     end;\n                   '[':\n                     begin\n                       TokRec^.state := tsEvalArray;\n                       if tok.pb.FBPos > 0 then\n                         TokRec^.current := TokRec^.parent.AsObject.GetO(tok.pb.Fbuf);\n                     end;\n                   '(':\n                     begin\n                       TokRec^.state := tsEvalMethod;\n                       if tok.pb.FBPos > 0 then\n                         TokRec^.current := TokRec^.parent.AsObject.GetO(tok.pb.Fbuf);\n                     end;\n                 else\n                   if tok.pb.FBPos > 0 then\n                     TokRec^.current := TokRec^.parent.AsObject.GetO(tok.pb.Fbuf);\n                   if (foPutValue in options) and (evalstack = 0) then\n                   begin\n                     TokRec^.parent.AsObject.PutO(tok.pb.Fbuf, put);\n                     TokRec^.current := put\n                   end else\n                   if (foDelete in options) and (evalstack = 0) then\n                   begin\n                     TokRec^.current := TokRec^.parent.AsObject.Delete(tok.pb.Fbuf);\n                   end else\n                   if (TokRec^.current = nil) and (foCreatePath in options) then\n                   begin\n                     TokRec^.current := TSuperObject.Create(dt);\n                     TokRec^.parent.AsObject.PutO(tok.pb.Fbuf, TokRec^.current);\n                   end;\n                   TokRec^.current := TokRec^.parent.AsObject.GetO(tok.pb.Fbuf);\n                   TokRec^.state := tsFinish;\n                   goto redo_char;\n                 end;\n               stArray:\n                 begin\n                   if TokRec^.obj <> nil then\n                   begin\n                     if not ObjectIsType(TokRec^.obj, stInt) or (TokRec^.obj.AsInteger < 0) then\n                     begin\n                       tok.err := teEvalInt;\n                       TokRec^.obj := nil;\n                       goto out;\n                     end;\n                     numi := TokRec^.obj.AsInteger;\n                     TokRec^.obj := nil;\n\n                     TokRec^.current := TokRec^.parent.AsArray.GetO(numi);\n                     case v of\n                       '.':\n                         if (TokRec^.current = nil) and (foCreatePath in options) then\n                         begin\n                           TokRec^.current := TSuperObject.Create(stObject);\n                           TokRec^.parent.AsArray.PutO(numi, TokRec^.current);\n                         end else\n                         if (TokRec^.current = nil) then\n                         begin\n                           tok.err := teEvalObject;\n                           goto out;\n                         end;\n                       '[':\n                         begin\n                           if (TokRec^.current = nil) and (foCreatePath in options) then\n                           begin\n                             TokRec^.current := TSuperObject.Create(stArray);\n                             TokRec^.parent.AsArray.Add(TokRec^.current);\n                           end else\n                           if (TokRec^.current = nil) then\n                           begin\n                             tok.err := teEvalArray;\n                             goto out;\n                           end;\n                           TokRec^.state := tsEvalArray;\n                         end;\n                       '(': TokRec^.state := tsEvalMethod;\n                     else\n                       if (foPutValue in options) and (evalstack = 0) then\n                       begin\n                         TokRec^.parent.AsArray.PutO(numi, put);\n                         TokRec^.current := put;\n                       end else\n                       if (foDelete in options) and (evalstack = 0) then\n                       begin\n                         TokRec^.current := TokRec^.parent.AsArray.Delete(numi);\n                       end else\n                         TokRec^.current := TokRec^.parent.AsArray.GetO(numi);\n                       TokRec^.state := tsFinish;\n                       goto redo_char\n                     end;\n                   end else\n                   begin\n                     case v of\n                       '.':\n                         begin\n                           if (foPutValue in options) then\n                           begin\n                             TokRec^.current := TSuperObject.Create(stObject);\n                             TokRec^.parent.AsArray.Add(TokRec^.current);\n                           end else\n                             TokRec^.current := TokRec^.parent.AsArray.GetO(TokRec^.parent.AsArray.FLength - 1);\n                         end;\n                       '[':\n                         begin\n                           if (foPutValue in options) then\n                           begin\n                             TokRec^.current := TSuperObject.Create(stArray);\n                             TokRec^.parent.AsArray.Add(TokRec^.current);\n                           end else\n                             TokRec^.current := TokRec^.parent.AsArray.GetO(TokRec^.parent.AsArray.FLength - 1);\n                           TokRec^.state := tsEvalArray;\n                         end;\n                       '(':\n                         begin\n                           if not (foPutValue in options) then\n                             TokRec^.current := TokRec^.parent.AsArray.GetO(TokRec^.parent.AsArray.FLength - 1) else\n                             TokRec^.current := nil;\n\n                           TokRec^.state := tsEvalMethod;\n                         end;\n                     else\n                       if (foPutValue in options) and (evalstack = 0) then\n                       begin\n                         TokRec^.parent.AsArray.Add(put);\n                         TokRec^.current := put;\n                       end else\n                         if tok.pb.FBPos = 0 then\n                           TokRec^.current := TokRec^.parent.AsArray.GetO(TokRec^.parent.AsArray.FLength - 1);\n                       TokRec^.state := tsFinish;\n                       goto redo_char\n                     end;\n                   end;\n                 end;\n{$IFDEF SUPER_METHOD}\n               stMethod:\n                 case v of\n                   '.':\n                     begin\n                       TokRec^.current := nil;\n                       sm := TokRec^.parent.AsMethod;\n                       sm(TokRec^.gparent, TokRec^.obj, TokRec^.current);\n                       TokRec^.obj := nil;\n                     end;\n                   '[':\n                     begin\n                       TokRec^.current := nil;\n                       sm := TokRec^.parent.AsMethod;\n                       sm(TokRec^.gparent, TokRec^.obj, TokRec^.current);\n                       TokRec^.state := tsEvalArray;\n                       TokRec^.obj := nil;\n                     end;\n                   '(':\n                     begin\n                       TokRec^.current := nil;\n                       sm := TokRec^.parent.AsMethod;\n                       sm(TokRec^.gparent, TokRec^.obj, TokRec^.current);\n                       TokRec^.state := tsEvalMethod;\n                       TokRec^.obj := nil;\n                     end;\n                 else\n                   if not (foPutValue in options) or (evalstack > 0) then\n                   begin\n                     TokRec^.current := nil;\n                     sm := TokRec^.parent.AsMethod;\n                     sm(TokRec^.gparent, TokRec^.obj, TokRec^.current);\n                     TokRec^.obj := nil;\n                     TokRec^.state := tsFinish;\n                     goto redo_char\n                   end else\n                   begin\n                     tok.err := teEvalMethod;\n                     TokRec^.obj := nil;\n                     goto out;\n                   end;\n                 end;\n{$ENDIF}\n             end;\n          end else\n            tok.pb.Append(@v, 1);\n        end;\n      end;\n\n    tsStringEscape:\n      case v of\n      'b',\n      'n',\n      'r',\n      't',\n      'f':\n        begin\n          if(v = 'b') then tok.pb.Append(TOK_BS, 1)\n          else if(v = 'n') then tok.pb.Append(TOK_LF, 1)\n          else if(v = 'r') then tok.pb.Append(TOK_CR, 1)\n          else if(v = 't') then tok.pb.Append(TOK_TAB, 1)\n          else if(v = 'f') then tok.pb.Append(TOK_FF, 1);\n          TokRec^.state := TokRec^.saved_state;\n        end;\n      'u':\n        begin\n          tok.ucs_char := 0;\n          tok.st_pos := 0;\n          TokRec^.state := tsEscapeUnicode;\n        end;\n      'x':\n        begin\n          tok.ucs_char := 0;\n          tok.st_pos := 0;\n          TokRec^.state := tsEscapeHexadecimal;\n        end\n      else\n        tok.pb.Append(@v, 1);\n        TokRec^.state := TokRec^.saved_state;\n      end;\n\n    tsEscapeUnicode:\n      begin\n        if ((SOIChar(v) < 256) and (AnsiChar(v) in super_hex_chars_set)) then\n        begin\n          inc(tok.ucs_char, (Word(hexdigit(v)) shl ((3-tok.st_pos)*4)));\n          inc(tok.st_pos);\n          if (tok.st_pos = 4) then\n          begin\n            tok.pb.Append(@tok.ucs_char, 1);\n            TokRec^.state := TokRec^.saved_state;\n          end\n        end else\n        begin\n          tok.err := teParseString;\n          goto out;\n        end\n      end;\n    tsEscapeHexadecimal:\n      begin\n        if ((SOIChar(v) < 256) and (AnsiChar(v) in super_hex_chars_set)) then\n        begin\n          inc(tok.ucs_char, (Word(hexdigit(v)) shl ((1-tok.st_pos)*4)));\n          inc(tok.st_pos);\n          if (tok.st_pos = 2) then\n          begin\n            tok.pb.Append(@tok.ucs_char, 1);\n            TokRec^.state := TokRec^.saved_state;\n          end\n        end else\n        begin\n          tok.err := teParseString;\n          goto out;\n        end\n      end;\n    tsBoolean:\n      begin\n        tok.pb.Append(@v, 1);\n        if (StrLComp('true', PSOChar(tok.pb.FBuf), min(tok.st_pos + 1, 4)) = 0) then\n        begin\n          if (tok.st_pos = 4) then\n          if (((SOIChar(v) < 256) and (AnsiChar(v) in path)) or (SOIChar(v) >= 256)) then\n            TokRec^.state := tsIdentifier else\n          begin\n            TokRec^.current := TSuperObject.Create(true);\n            TokRec^.saved_state := tsFinish;\n            TokRec^.state := tsEatws;\n            goto redo_char;\n          end\n        end else\n        if (StrLComp('false', PSOChar(tok.pb.FBuf), min(tok.st_pos + 1, 5)) = 0) then\n        begin\n          if (tok.st_pos = 5) then\n          if (((SOIChar(v) < 256) and (AnsiChar(v) in path)) or (SOIChar(v) >= 256)) then\n            TokRec^.state := tsIdentifier else\n          begin\n            TokRec^.current := TSuperObject.Create(false);\n            TokRec^.saved_state := tsFinish;\n            TokRec^.state := tsEatws;\n            goto redo_char;\n          end\n        end else\n        begin\n          TokRec^.state := tsIdentifier;\n          tok.pb.FBuf[tok.st_pos] := #0;\n          dec(tok.pb.FBPos);\n          goto redo_char;\n        end;\n        inc(tok.st_pos);\n      end;\n\n    tsNumber:\n      begin\n        if (SOIChar(v) < 256) and (AnsiChar(v) in super_number_chars_set) then\n        begin\n          tok.pb.Append(@v, 1);\n          if (SOIChar(v) < 256) then\n          case v of\n          '.': begin\n                 tok.is_double := 1;\n                 tok.floatcount := 0;\n               end;\n          'e','E':\n            begin\n              tok.is_double := 1;\n              tok.floatcount := -1;\n            end;\n          '0'..'9':\n            begin\n\n              if (tok.is_double = 1) and (tok.floatcount >= 0) then\n              begin\n                inc(tok.floatcount);\n                if tok.floatcount > 4 then\n                  tok.floatcount := -1;\n              end;\n            end;\n          end;\n        end else\n        begin\n          if (tok.is_double = 0) then\n          begin\n            val(tok.pb.FBuf, numi, code);\n            if ObjectIsType(this, stArray) then\n            begin\n              if (foPutValue in options) and (evalstack = 0) then\n              begin\n                this.AsArray.PutO(numi, put);\n                TokRec^.current := put;\n              end else\n              if (foDelete in options) and (evalstack = 0) then\n                TokRec^.current := this.AsArray.Delete(numi) else\n                TokRec^.current := this.AsArray.GetO(numi);\n            end else\n              TokRec^.current := TSuperObject.Create(numi);\n\n          end else\n          if (tok.is_double <> 0) then\n          begin\n            if tok.floatcount >= 0 then\n            begin\n              p := tok.pb.FBuf;\n              while p^ <> '.' do inc(p);\n              for code := 0 to tok.floatcount - 1 do\n              begin\n                p^ := p[1];\n                inc(p);\n              end;\n              p^ := #0;\n              val(tok.pb.FBuf, numi, code);\n              case tok.floatcount of\n                0: numi := numi * 10000;\n                1: numi := numi * 1000;\n                2: numi := numi * 100;\n                3: numi := numi * 10;\n              end;\n              TokRec^.current := TSuperObject.CreateCurrency(PCurrency(@numi)^);\n            end else\n            begin\n              val(tok.pb.FBuf, numd, code);\n              TokRec^.current := TSuperObject.Create(numd);\n            end;\n          end else\n          begin\n            tok.err := teParseNumber;\n            goto out;\n          end;\n          TokRec^.saved_state := tsFinish;\n          TokRec^.state := tsEatws;\n          goto redo_char;\n        end\n      end;\n\n    tsArray:\n      begin\n        if (v = ']') then\n        begin\n          TokRec^.saved_state := tsFinish;\n          TokRec^.state := tsEatws;\n        end else\n        begin\n          if(tok.depth >= SUPER_TOKENER_MAX_DEPTH-1) then\n          begin\n            tok.err := teDepth;\n            goto out;\n          end;\n          TokRec^.state := tsArrayAdd;\n          inc(tok.depth);\n          tok.ResetLevel(tok.depth);\n          TokRec := @tok.stack[tok.depth];\n          goto redo_char;\n        end\n      end;\n\n    tsArrayAdd:\n      begin\n        TokRec^.current.AsArray.Add(obj);\n        TokRec^.saved_state := tsArraySep;\n        TokRec^.state := tsEatws;\n        goto redo_char;\n      end;\n\n    tsArraySep:\n      begin\n        if (v = ']') then\n        begin\n          TokRec^.saved_state := tsFinish;\n          TokRec^.state := tsEatws;\n        end else\n        if (v = ',') then\n        begin\n          TokRec^.saved_state := tsArray;\n          TokRec^.state := tsEatws;\n        end else\n        begin\n          tok.err := teParseArray;\n          goto out;\n        end\n      end;\n\n    tsObjectFieldStart:\n      begin\n        if (v = '}') then\n        begin\n          TokRec^.saved_state := tsFinish;\n          TokRec^.state := tsEatws;\n        end else\n        if (SOIChar(v) < 256) and (AnsiChar(v) in ['\"', '''']) then\n        begin\n          tok.quote_char := v;\n          tok.pb.Reset;\n          TokRec^.state := tsObjectField;\n        end else\n        if not((SOIChar(v) < 256) and ((AnsiChar(v) in reserved) or strict)) then\n        begin\n          TokRec^.state := tsObjectUnquotedField;\n          tok.pb.Reset;\n          goto redo_char;\n        end else\n        begin\n          tok.err := teParseObjectKeyName;\n          goto out;\n        end\n      end;\n\n    tsObjectField:\n      begin\n        if (v = tok.quote_char) then\n        begin\n          TokRec^.field_name := tok.pb.FBuf;\n          TokRec^.saved_state := tsObjectFieldEnd;\n          TokRec^.state := tsEatws;\n        end else\n        if (v = '\\') then\n        begin\n          TokRec^.saved_state := tsObjectField;\n          TokRec^.state := tsStringEscape;\n        end else\n        begin\n          tok.pb.Append(@v, 1);\n        end\n      end;\n\n    tsObjectUnquotedField:\n      begin\n        if (SOIChar(v) < 256) and (AnsiChar(v) in [':', #0]) then\n        begin\n          TokRec^.field_name := tok.pb.FBuf;\n          TokRec^.saved_state := tsObjectFieldEnd;\n          TokRec^.state := tsEatws;\n          goto redo_char;\n        end else\n        if (v = '\\') then\n        begin\n          TokRec^.saved_state := tsObjectUnquotedField;\n          TokRec^.state := tsStringEscape;\n        end else\n          tok.pb.Append(@v, 1);\n      end;\n\n    tsObjectFieldEnd:\n      begin\n        if (v = ':') then\n        begin\n          TokRec^.saved_state := tsObjectValue;\n          TokRec^.state := tsEatws;\n        end else\n        begin\n          tok.err := teParseObjectKeySep;\n          goto out;\n        end\n      end;\n\n    tsObjectValue:\n      begin\n        if (tok.depth >= SUPER_TOKENER_MAX_DEPTH-1) then\n        begin\n          tok.err := teDepth;\n          goto out;\n        end;\n        TokRec^.state := tsObjectValueAdd;\n        inc(tok.depth);\n        tok.ResetLevel(tok.depth);\n        TokRec := @tok.stack[tok.depth];\n        goto redo_char;\n      end;\n\n    tsObjectValueAdd:\n      begin\n        TokRec^.current.AsObject.PutO(TokRec^.field_name, obj);\n        TokRec^.field_name := '';\n        TokRec^.saved_state := tsObjectSep;\n        TokRec^.state := tsEatws;\n        goto redo_char;\n      end;\n\n    tsObjectSep:\n      begin\n        if (v = '}') then\n        begin\n          TokRec^.saved_state := tsFinish;\n          TokRec^.state := tsEatws;\n        end else\n        if (v = ',') then\n        begin\n          TokRec^.saved_state := tsObjectFieldStart;\n          TokRec^.state := tsEatws;\n        end else\n        begin\n          tok.err := teParseObjectValueSep;\n          goto out;\n        end\n      end;\n    end;\n    inc(str);\n    inc(tok.char_offset);\n  until v = #0;\n\n  if(TokRec^.state <> tsFinish) and\n     (TokRec^.saved_state <> tsFinish) then\n    tok.err := teParseEof;\n\n out:\n  if(tok.err in [teSuccess]) then\n  begin\n{$IFDEF SUPER_METHOD}\n    if (foCallMethod in options) and ObjectIsType(TokRec^.current, stMethod) and assigned(TokRec^.current.AsMethod) then\n    begin\n      sm := TokRec^.current.AsMethod;\n      sm(TokRec^.parent, put, Result);\n    end else\n{$ENDIF}\n    Result := TokRec^.current;\n  end else\n    Result := nil;\nend;\n\nprocedure TSuperObject.PutO(const path: SOString; const Value: ISuperObject);\nbegin\n  ParseString(PSOChar(path), true, False, self, [foCreatePath, foPutValue], Value);\nend;\n\nprocedure TSuperObject.PutB(const path: SOString; Value: Boolean);\nbegin\n  ParseString(PSOChar(path), true, False, self, [foCreatePath, foPutValue], TSuperObject.Create(Value));\nend;\n\nprocedure TSuperObject.PutD(const path: SOString; Value: Double);\nbegin\n  ParseString(PSOChar(path), true, False, self, [foCreatePath, foPutValue], TSuperObject.Create(Value));\nend;\n\nprocedure TSuperObject.PutC(const path: SOString; Value: Currency);\nbegin\n  ParseString(PSOChar(path), true, False, self, [foCreatePath, foPutValue], TSuperObject.CreateCurrency(Value));\nend;\n\nprocedure TSuperObject.PutI(const path: SOString; Value: SuperInt);\nbegin\n  ParseString(PSOChar(path), true, False, self, [foCreatePath, foPutValue], TSuperObject.Create(Value));\nend;\n\nprocedure TSuperObject.PutS(const path: SOString; const Value: SOString);\nbegin\n  ParseString(PSOChar(path), true, False, self, [foCreatePath, foPutValue], TSuperObject.Create(Value));\nend;\n\nfunction TSuperObject.QueryInterface(const IID: TGUID; out Obj): HResult; stdcall;\nbegin\n  if GetInterface(IID, Obj) then\n    Result := 0\n  else\n    Result := E_NOINTERFACE;\nend;\n\nfunction TSuperObject.SaveTo(stream: TStream; indent, escape: boolean): integer;\nvar\n  pb: TSuperWriterStream;\nbegin\n  if escape then\n    pb := TSuperAnsiWriterStream.Create(stream) else\n    pb := TSuperUnicodeWriterStream.Create(stream);\n\n  if(Write(pb, indent, escape, 0) < 0) then\n  begin\n    pb.Reset;\n    pb.Free;\n    Result := 0;\n    Exit;\n  end;\n  Result := stream.Size;\n  pb.Free;\nend;\n\nfunction TSuperObject.CalcSize(indent, escape: boolean): integer;\nvar\n  pb: TSuperWriterFake;\nbegin\n  pb := TSuperWriterFake.Create;\n  if(Write(pb, indent, escape, 0) < 0) then\n  begin\n    pb.Free;\n    Result := 0;\n    Exit;\n  end;\n  Result := pb.FSize;\n  pb.Free;\nend;\n\nfunction TSuperObject.SaveTo(socket: Integer; indent, escape: boolean): integer;\nvar\n  pb: TSuperWriterSock;\nbegin\n  pb := TSuperWriterSock.Create(socket);\n  if(Write(pb, indent, escape, 0) < 0) then\n  begin\n    pb.Free;\n    Result := 0;\n    Exit;\n  end;\n  Result := pb.FSize;\n  pb.Free;\nend;\n\nconstructor TSuperObject.Create(const s: SOString);\nbegin\n  Create(stString);\n  FOString := s;\nend;\n\nprocedure TSuperObject.Clear(all: boolean);\nbegin\n  if FProcessing then exit;\n  FProcessing := true;\n  try\n    case FDataType of\n      stBoolean: FO.c_boolean := false;\n      stDouble: FO.c_double := 0.0;\n      stCurrency: FO.c_currency := 0.0;\n      stInt: FO.c_int := 0;\n      stObject: FO.c_object.Clear(all);\n      stArray: FO.c_array.Clear(all);\n      stString: FOString := '';\n{$IFDEF SUPER_METHOD}\n      stMethod: FO.c_method := nil;\n{$ENDIF}\n    end;\n  finally\n    FProcessing := false;\n  end;\nend;\n\nprocedure TSuperObject.Pack(all: boolean = false);\nbegin\n  if FProcessing then exit;\n  FProcessing := true;\n  try\n    case FDataType of\n      stObject: FO.c_object.Pack(all);\n      stArray: FO.c_array.Pack(all);\n    end;\n  finally\n    FProcessing := false;\n  end;\nend;\n\nfunction TSuperObject.GetN(const path: SOString): ISuperObject;\nbegin\n  Result := ParseString(PSOChar(path), False, true, self);\n  if Result = nil then\n    Result := TSuperObject.Create(stNull);\nend;\n\nprocedure TSuperObject.PutN(const path: SOString; const Value: ISuperObject);\nbegin\n  if Value = nil then\n    ParseString(PSOChar(path), False, True, self, [foCreatePath, foPutValue], TSuperObject.Create(stNull)) else\n    ParseString(PSOChar(path), False, True, self, [foCreatePath, foPutValue], Value);\nend;\n\nfunction TSuperObject.Delete(const path: SOString): ISuperObject;\nbegin\n  Result := ParseString(PSOChar(path), False, true, self, [foDelete]);\nend;\n\nfunction TSuperObject.Clone: ISuperObject;\nvar\n  ite: TSuperObjectIter;\n  arr: TSuperArray;\n  j: integer;\nbegin\n  case FDataType of\n    stBoolean: Result := TSuperObject.Create(FO.c_boolean);\n    stDouble: Result := TSuperObject.Create(FO.c_double);\n    stCurrency: Result := TSuperObject.CreateCurrency(FO.c_currency);\n    stInt: Result := TSuperObject.Create(FO.c_int);\n    stString: Result := TSuperObject.Create(FOString);\n{$IFDEF SUPER_METHOD}\n    stMethod: Result := TSuperObject.Create(FO.c_method);\n{$ENDIF}\n    stObject:\n      begin\n        Result := TSuperObject.Create(stObject);\n        if ObjectFindFirst(self, ite) then\n        with Result.AsObject do\n        repeat\n          PutO(ite.key, ite.val.Clone);\n        until not ObjectFindNext(ite);\n        ObjectFindClose(ite);\n      end;\n    stArray:\n      begin\n        Result := TSuperObject.Create(stArray);\n        arr := AsArray;\n        with Result.AsArray do\n        for j := 0 to arr.Length - 1 do\n          Add(arr.GetO(j).Clone);\n      end;\n  else\n    Result := nil;\n  end;\nend;\n\nprocedure TSuperObject.Merge(const obj: ISuperObject; reference: boolean);\nvar\n  prop1, prop2: ISuperObject;\n  ite: TSuperObjectIter;\n  arr: TSuperArray;\n  j: integer;\nbegin\n  if ObjectIsType(obj, FDataType) then\n  case FDataType of\n    stBoolean: FO.c_boolean := obj.AsBoolean;\n    stDouble: FO.c_double := obj.AsDouble;\n    stCurrency: FO.c_currency := obj.AsCurrency;\n    stInt: FO.c_int := obj.AsInteger;\n    stString: FOString := obj.AsString;\n{$IFDEF SUPER_METHOD}\n    stMethod: FO.c_method := obj.AsMethod;\n{$ENDIF}\n    stObject:\n      begin\n        if ObjectFindFirst(obj, ite) then\n        with FO.c_object do\n        repeat\n          prop1 := FO.c_object.GetO(ite.key);\n          if (prop1 <> nil) and (ite.val <> nil) and (prop1.DataType = ite.val.DataType) then\n            prop1.Merge(ite.val) else\n            if reference then\n              PutO(ite.key, ite.val) else\n              PutO(ite.key, ite.val.Clone);\n        until not ObjectFindNext(ite);\n        ObjectFindClose(ite);\n      end;\n    stArray:\n      begin\n        arr := obj.AsArray;\n        with FO.c_array do\n        for j := 0 to arr.Length - 1 do\n        begin\n          prop1 := GetO(j);\n          prop2 := arr.GetO(j);\n          if (prop1 <> nil) and (prop2 <> nil) and (prop1.DataType = prop2.DataType) then\n            prop1.Merge(prop2) else\n            if reference then\n              PutO(j, prop2) else\n              PutO(j, prop2.Clone);\n        end;\n      end;\n  end;\nend;\n\nprocedure TSuperObject.Merge(const str: SOString);\nbegin\n  Merge(TSuperObject.ParseString(PSOChar(str), False), true);\nend;\n\nclass function TSuperObject.NewInstance: TObject;\nbegin\n  Result := inherited NewInstance;\n  TSuperObject(Result).FRefCount := 1;\nend;\n\nfunction TSuperObject.ForcePath(const path: SOString; dataType: TSuperType = stObject): ISuperObject;\nbegin\n  Result := ParseString(PSOChar(path), False, True, Self, [foCreatePath], nil, dataType);\nend;\n\nfunction TSuperObject.Format(const str: SOString; BeginSep: SOChar; EndSep: SOChar): SOString;\nvar\n  p1, p2: PSOChar;\nbegin\n  Result := '';\n  p2 := PSOChar(str);\n  p1 := p2;\n  while true do\n    if p2^ = BeginSep then\n      begin\n        if p2 > p1 then\n          Result := Result + Copy(p1, 0, p2-p1);\n        inc(p2);\n        p1 := p2;\n        while true do\n          if p2^ = EndSep then Break else\n          if p2^ = #0     then Exit else\n            inc(p2);\n        Result := Result + GetS(copy(p1, 0, p2-p1));\n        inc(p2);\n        p1 := p2;\n      end\n    else if p2^ = #0 then\n      begin\n        if p2 > p1 then\n          Result := Result + Copy(p1, 0, p2-p1);\n        Break;\n      end else\n        inc(p2);\nend;\n\nfunction TSuperObject.GetO(const path: SOString): ISuperObject;\nbegin\n  Result := ParseString(PSOChar(path), False, True, Self);\nend;\n\nfunction TSuperObject.GetA(const path: SOString): TSuperArray;\nvar\n  obj: ISuperObject;\nbegin\n  obj := ParseString(PSOChar(path), False, True, Self);\n  if obj <> nil then\n    Result := obj.AsArray else\n    Result := nil;\nend;\n\nfunction TSuperObject.GetB(const path: SOString): Boolean;\nvar\n  obj: ISuperObject;\nbegin\n  obj := GetO(path);\n  if obj <> nil then\n    Result := obj.AsBoolean else\n    Result := false;\nend;\n\nfunction TSuperObject.GetD(const path: SOString): Double;\nvar\n  obj: ISuperObject;\nbegin\n  obj := GetO(path);\n  if obj <> nil then\n    Result := obj.AsDouble else\n    Result := 0.0;\nend;\n\nfunction TSuperObject.GetC(const path: SOString): Currency;\nvar\n  obj: ISuperObject;\nbegin\n  obj := GetO(path);\n  if obj <> nil then\n    Result := obj.AsCurrency else\n    Result := 0.0;\nend;\n\nfunction TSuperObject.GetI(const path: SOString): SuperInt;\nvar\n  obj: ISuperObject;\nbegin\n  obj := GetO(path);\n  if obj <> nil then\n    Result := obj.AsInteger else\n    Result := 0;\nend;\n\nfunction TSuperObject.GetDataPtr: Pointer;\nbegin\n  Result := FDataPtr;\nend;\n\nfunction TSuperObject.GetDataType: TSuperType;\nbegin\n  Result := FDataType\nend;\n\nfunction TSuperObject.GetS(const path: SOString): SOString;\nvar\n  obj: ISuperObject;\nbegin\n  obj := GetO(path);\n  if obj <> nil then\n    Result := obj.AsString else\n    Result := '';\nend;\n\nfunction TSuperObject.SaveTo(const FileName: string; indent, escape: boolean): integer;\nvar\n  stream: TFileStream;\nbegin\n  stream := TFileStream.Create(FileName, fmCreate);\n  try\n    Result := SaveTo(stream, indent, escape);\n  finally\n    stream.Free;\n  end;\nend;\n\nfunction TSuperObject.Validate(const rules: SOString; const defs: SOString = ''; callback: TSuperOnValidateError = nil; sender: Pointer = nil): boolean;\nbegin\n  Result := Validate(TSuperObject.ParseString(PSOChar(rules), False), TSuperObject.ParseString(PSOChar(defs), False), callback, sender);\nend;\n\nfunction TSuperObject.Validate(const rules: ISuperObject; const defs: ISuperObject = nil; callback: TSuperOnValidateError = nil; sender: Pointer = nil): boolean;\ntype\n  TDataType = (dtUnknown, dtStr, dtInt, dtFloat, dtNumber, dtText, dtBool,\n               dtMap, dtSeq, dtScalar, dtAny);\nvar\n  datatypes: ISuperObject;\n  names: ISuperObject;\n\n  function FindInheritedProperty(const prop: PSOChar; p: ISuperObject): ISuperObject;\n  var\n    o: ISuperObject;\n    e: TSuperAvlEntry;\n  begin\n    o := p[prop];\n    if o <> nil then\n      result := o else\n      begin\n        o := p['inherit'];\n        if (o <> nil) and ObjectIsType(o, stString) then\n          begin\n            e := names.AsObject.Search(o.AsString);\n            if (e <> nil) then\n              Result := FindInheritedProperty(prop, e.Value) else\n              Result := nil;\n          end else\n            Result := nil;\n      end;\n  end;\n\n  function FindDataType(o: ISuperObject): TDataType;\n  var\n    e: TSuperAvlEntry;\n    obj: ISuperObject;\n  begin\n    obj := FindInheritedProperty('type', o);\n    if obj <> nil then\n    begin\n      e := datatypes.AsObject.Search(obj.AsString);\n      if  e <> nil then\n        Result := TDataType(e.Value.AsInteger) else\n        Result := dtUnknown;\n    end else\n      Result := dtUnknown;\n  end;\n\n  procedure GetNames(o: ISuperObject);\n  var\n    obj: ISuperObject;\n    f: TSuperObjectIter;\n  begin\n    obj := o['name'];\n    if ObjectIsType(obj, stString) then\n      names[obj.AsString] := o;\n\n    case FindDataType(o) of\n      dtMap:\n        begin\n          obj := o['mapping'];\n          if ObjectIsType(obj, stObject) then\n          begin\n            if ObjectFindFirst(obj, f) then\n            repeat\n              if ObjectIsType(f.val, stObject) then\n                GetNames(f.val);\n            until not ObjectFindNext(f);\n            ObjectFindClose(f);\n          end;\n        end;\n      dtSeq:\n        begin\n          obj := o['sequence'];\n          if ObjectIsType(obj, stObject) then\n            GetNames(obj);\n        end;\n    end;\n  end;\n\n  function FindInheritedField(const prop: SOString; p: ISuperObject): ISuperObject;\n  var\n    o: ISuperObject;\n    e: TSuperAvlEntry;\n  begin\n    o := p['mapping'];\n    if ObjectIsType(o, stObject) then\n    begin\n      o := o.AsObject.GetO(prop);\n      if o <> nil then\n      begin\n        Result := o;\n        Exit;\n      end;\n    end;\n\n    o := p['inherit'];\n    if ObjectIsType(o, stString) then\n    begin\n      e := names.AsObject.Search(o.AsString);\n      if (e <> nil) then\n        Result := FindInheritedField(prop, e.Value) else\n        Result := nil;\n    end else\n      Result := nil;\n  end;\n\n  function InheritedFieldExist(const obj: ISuperObject; p: ISuperObject; const name: SOString = ''): boolean;\n  var\n   o: ISuperObject;\n   e: TSuperAvlEntry;\n   j: TSuperAvlIterator;\n  begin\n    Result := true;\n    o := p['mapping'];\n    if ObjectIsType(o, stObject) then\n    begin\n      j := TSuperAvlIterator.Create(o.AsObject);\n      try\n        j.First;\n        e := j.GetIter;\n        while e <> nil do\n        begin\n          if obj.AsObject.Search(e.Name) = nil then\n          begin\n            Result := False;\n            if assigned(callback) then\n              callback(sender, veFieldNotFound, name + '.' + e.Name);\n          end;\n          j.Next;\n          e := j.GetIter;\n        end;\n\n      finally\n        j.Free;\n      end;\n    end;\n\n    o := p['inherit'];\n    if ObjectIsType(o, stString) then\n    begin\n      e := names.AsObject.Search(o.AsString);\n      if (e <> nil) then\n        Result := InheritedFieldExist(obj, e.Value, name) and Result;\n    end;\n  end;\n\n  function getInheritedBool(f: PSOChar; p: ISuperObject; default: boolean = false): boolean;\n  var\n    o: ISuperObject;\n  begin\n    o := FindInheritedProperty(f, p);\n    case ObjectGetType(o) of\n      stBoolean: Result := o.AsBoolean;\n      stNull: Result := Default;\n    else\n      Result := default;\n      if assigned(callback) then\n        callback(sender, veRuleMalformated, f);\n    end;\n  end;\n\n  procedure GetInheritedFieldList(list: ISuperObject; p: ISuperObject);\n  var\n   o: ISuperObject;\n   e: TSuperAvlEntry;\n   i: TSuperAvlIterator;\n  begin\n    Result := true;\n    o := p['mapping'];\n    if ObjectIsType(o, stObject) then\n    begin\n      i := TSuperAvlIterator.Create(o.AsObject);\n      try\n        i.First;\n        e := i.GetIter;\n        while e <> nil do\n        begin\n          if list.AsObject.Search(e.Name) = nil then\n            list[e.Name] := e.Value;\n          i.Next;\n          e := i.GetIter;\n        end;\n\n      finally\n        i.Free;\n      end;\n    end;\n\n    o := p['inherit'];\n    if ObjectIsType(o, stString) then\n    begin\n      e := names.AsObject.Search(o.AsString);\n      if (e <> nil) then\n        GetInheritedFieldList(list, e.Value);\n    end;\n  end;\n\n  function CheckEnum(o: ISuperObject; p: ISuperObject; name: SOString = ''): boolean;\n  var\n    enum: ISuperObject;\n    i: integer;\n  begin\n    Result := false;\n    enum := FindInheritedProperty('enum', p);\n    case ObjectGetType(enum) of\n      stArray:\n        for i := 0 to enum.AsArray.Length - 1 do\n          if (o.AsString = enum.AsArray[i].AsString) then\n          begin\n            Result := true;\n            exit;\n          end;\n      stNull: Result := true;\n    else\n      Result := false;\n      if assigned(callback) then\n        callback(sender, veRuleMalformated, '');\n      Exit;\n    end;\n\n    if (not Result) and assigned(callback) then\n      callback(sender, veValueNotInEnum, name);\n  end;\n\n  function CheckLength(len: integer; p: ISuperObject; const objpath: SOString): boolean;\n  var\n    length, o: ISuperObject;\n  begin\n    result := true;\n    length := FindInheritedProperty('length', p);\n    case ObjectGetType(length) of\n      stObject:\n        begin\n          o := length.AsObject.GetO('min');\n          if (o <> nil) and (o.AsInteger > len) then\n          begin\n            Result := false;\n            if assigned(callback) then\n              callback(sender, veInvalidLength, objpath);\n          end;\n          o := length.AsObject.GetO('max');\n          if (o <> nil) and (o.AsInteger < len) then\n          begin\n            Result := false;\n            if assigned(callback) then\n              callback(sender, veInvalidLength, objpath);\n          end;\n          o := length.AsObject.GetO('minex');\n          if (o <> nil) and (o.AsInteger >= len) then\n          begin\n            Result := false;\n            if assigned(callback) then\n              callback(sender, veInvalidLength, objpath);\n          end;\n          o := length.AsObject.GetO('maxex');\n          if (o <> nil) and (o.AsInteger <= len) then\n          begin\n            Result := false;\n            if assigned(callback) then\n              callback(sender, veInvalidLength, objpath);\n          end;\n        end;\n      stNull: ;\n    else\n      Result := false;\n      if assigned(callback) then\n        callback(sender, veRuleMalformated, '');\n    end;\n  end;\n\n  function CheckRange(obj: ISuperObject; p: ISuperObject; const objpath: SOString): boolean;\n  var\n    length, o: ISuperObject;\n  begin\n    result := true;\n    length := FindInheritedProperty('range', p);\n    case ObjectGetType(length) of\n      stObject:\n        begin\n          o := length.AsObject.GetO('min');\n          if (o <> nil) and (o.Compare(obj) = cpGreat) then\n          begin\n            Result := false;\n            if assigned(callback) then\n              callback(sender, veInvalidRange, objpath);\n          end;\n          o := length.AsObject.GetO('max');\n          if (o <> nil) and (o.Compare(obj) = cpLess) then\n          begin\n            Result := false;\n            if assigned(callback) then\n              callback(sender, veInvalidRange, objpath);\n          end;\n          o := length.AsObject.GetO('minex');\n          if (o <> nil) and (o.Compare(obj) in [cpGreat, cpEqu]) then\n          begin\n            Result := false;\n            if assigned(callback) then\n              callback(sender, veInvalidRange, objpath);\n          end;\n          o := length.AsObject.GetO('maxex');\n          if (o <> nil) and (o.Compare(obj) in [cpLess, cpEqu]) then\n          begin\n            Result := false;\n            if assigned(callback) then\n              callback(sender, veInvalidRange, objpath);\n          end;\n        end;\n      stNull: ;\n    else\n      Result := false;\n      if assigned(callback) then\n        callback(sender, veRuleMalformated, '');\n    end;\n  end;\n\n\n  function process(o: ISuperObject; p: ISuperObject; objpath: SOString = ''): boolean;\n  var\n    ite: TSuperAvlIterator;\n    ent: TSuperAvlEntry;\n    p2, o2, sequence: ISuperObject;\n    s: SOString;\n    i: integer;\n    uniquelist, fieldlist: ISuperObject;\n  begin\n    Result := true;\n    if (o = nil) then\n    begin\n      if getInheritedBool('required', p) then\n      begin\n        if assigned(callback) then\n          callback(sender, veFieldIsRequired, objpath);\n        result := false;\n      end;\n    end else\n      case FindDataType(p) of\n        dtStr:\n          case ObjectGetType(o) of\n            stString:\n              begin\n                Result := Result and CheckLength(Length(o.AsString), p, objpath);\n                Result := Result and CheckRange(o, p, objpath);\n              end;\n          else\n            if assigned(callback) then\n              callback(sender, veInvalidDataType, objpath);\n            result := false;\n          end;\n        dtBool:\n          case ObjectGetType(o) of\n            stBoolean:\n              begin\n                Result := Result and CheckRange(o, p, objpath);\n              end;\n          else\n            if assigned(callback) then\n              callback(sender, veInvalidDataType, objpath);\n            result := false;\n          end;\n        dtInt:\n          case ObjectGetType(o) of\n            stInt:\n              begin\n                Result := Result and CheckRange(o, p, objpath);\n              end;\n          else\n            if assigned(callback) then\n              callback(sender, veInvalidDataType, objpath);\n            result := false;\n          end;\n        dtFloat:\n          case ObjectGetType(o) of\n            stDouble, stCurrency:\n              begin\n                Result := Result and CheckRange(o, p, objpath);\n              end;\n          else\n            if assigned(callback) then\n              callback(sender, veInvalidDataType, objpath);\n            result := false;\n          end;\n        dtMap:\n          case ObjectGetType(o) of\n            stObject:\n              begin\n                // all objects have and match a rule ?\n                ite := TSuperAvlIterator.Create(o.AsObject);\n                try\n                  ite.First;\n                  ent := ite.GetIter;\n                  while ent <> nil do\n                  begin\n                    p2 :=  FindInheritedField(ent.Name, p);\n                    if ObjectIsType(p2, stObject) then\n                      result := process(ent.Value, p2, objpath + '.' + ent.Name) and result else\n                    begin\n                      if assigned(callback) then\n                        callback(sender, veUnexpectedField, objpath + '.' + ent.Name);\n                      result := false; // field have no rule\n                    end;\n                    ite.Next;\n                    ent := ite.GetIter;\n                  end;\n                finally\n                  ite.Free;\n                end;\n\n                // all expected field exists ?\n                Result :=  InheritedFieldExist(o, p, objpath) and Result;\n              end;\n            stNull: {nop};\n          else\n            result := false;\n            if assigned(callback) then\n              callback(sender, veRuleMalformated, objpath);\n          end;\n        dtSeq:\n          case ObjectGetType(o) of\n            stArray:\n              begin\n                sequence := FindInheritedProperty('sequence', p);\n                if sequence <> nil then\n                case ObjectGetType(sequence) of\n                  stObject:\n                    begin\n                      for i := 0 to o.AsArray.Length - 1 do\n                        result := process(o.AsArray.GetO(i), sequence, objpath + '[' + IntToStr(i) + ']') and result;\n                      if getInheritedBool('unique', sequence) then\n                      begin\n                        // type is unique ?\n                        uniquelist := TSuperObject.Create(stObject);\n                        try\n                          for i := 0 to o.AsArray.Length - 1 do\n                          begin\n                            s := o.AsArray.GetO(i).AsString;\n                            if (s <> '') then\n                            begin\n                              if uniquelist.AsObject.Search(s) = nil then\n                                uniquelist[s] := nil else\n                                begin\n                                  Result := False;\n                                  if Assigned(callback) then\n                                    callback(sender, veDuplicateEntry, objpath + '[' + IntToStr(i) + ']');\n                                end;\n                            end;\n                          end;\n                        finally\n                          uniquelist := nil;\n                        end;\n                      end;\n\n                      // field is unique ?\n                      if (FindDataType(sequence) = dtMap) then\n                      begin\n                        fieldlist := TSuperObject.Create(stObject);\n                        try\n                          GetInheritedFieldList(fieldlist, sequence);\n                          ite := TSuperAvlIterator.Create(fieldlist.AsObject);\n                          try\n                            ite.First;\n                            ent := ite.GetIter;\n                            while ent <> nil do\n                            begin\n                              if getInheritedBool('unique', ent.Value) then\n                              begin\n                                uniquelist := TSuperObject.Create(stObject);\n                                try\n                                  for i := 0 to o.AsArray.Length - 1 do\n                                  begin\n                                    o2 := o.AsArray.GetO(i);\n                                    if o2 <> nil then\n                                    begin\n                                      s := o2.AsObject.GetO(ent.Name).AsString;\n                                      if (s <> '') then\n                                      if uniquelist.AsObject.Search(s) = nil then\n                                        uniquelist[s] := nil else\n                                        begin\n                                          Result := False;\n                                          if Assigned(callback) then\n                                            callback(sender, veDuplicateEntry, objpath + '[' + IntToStr(i) + '].' + ent.name);\n                                        end;\n                                    end;\n                                  end;\n                                finally\n                                  uniquelist := nil;\n                                end;\n                              end;\n                              ite.Next;\n                              ent := ite.GetIter;\n                            end;\n                          finally\n                            ite.Free;\n                          end;\n                        finally\n                          fieldlist := nil;\n                        end;\n                      end;\n\n\n                    end;\n                  stNull: {nop};\n                else\n                  result := false;\n                  if assigned(callback) then\n                    callback(sender, veRuleMalformated, objpath);\n                end;\n                Result := Result and CheckLength(o.AsArray.Length, p, objpath);\n\n              end;\n          else\n            result := false;\n            if assigned(callback) then\n              callback(sender, veRuleMalformated, objpath);\n          end;\n        dtNumber:\n          case ObjectGetType(o) of\n            stInt,\n            stDouble, stCurrency:\n              begin\n                Result := Result and CheckRange(o, p, objpath);\n              end;\n          else\n            if assigned(callback) then\n              callback(sender, veInvalidDataType, objpath);\n            result := false;\n          end;\n        dtText:\n          case ObjectGetType(o) of\n            stInt,\n            stDouble,\n            stCurrency,\n            stString:\n              begin\n                result := result and CheckLength(Length(o.AsString), p, objpath);\n                Result := Result and CheckRange(o, p, objpath);\n              end;\n          else\n            if assigned(callback) then\n              callback(sender, veInvalidDataType, objpath);\n            result := false;\n          end;\n        dtScalar:\n          case ObjectGetType(o) of\n            stBoolean,\n            stDouble,\n            stCurrency,\n            stInt,\n            stString:\n              begin\n                result := result and CheckLength(Length(o.AsString), p, objpath);\n                Result := Result and CheckRange(o, p, objpath);\n              end;\n          else\n            if assigned(callback) then\n              callback(sender, veInvalidDataType, objpath);\n            result := false;\n          end;\n        dtAny:;\n      else\n        if assigned(callback) then\n          callback(sender, veRuleMalformated, objpath);\n        result := false;\n      end;\n      Result := Result and CheckEnum(o, p, objpath)\n\n  end;\nvar\n  j: integer;\n\nbegin\n  Result := False;\n  datatypes := TSuperObject.Create(stObject);\n  names := TSuperObject.Create;\n  try\n    datatypes.I['str'] := ord(dtStr);\n    datatypes.I['int'] := ord(dtInt);\n    datatypes.I['float'] := ord(dtFloat);\n    datatypes.I['number'] := ord(dtNumber);\n    datatypes.I['text'] := ord(dtText);\n    datatypes.I['bool'] := ord(dtBool);\n    datatypes.I['map'] := ord(dtMap);\n    datatypes.I['seq'] := ord(dtSeq);\n    datatypes.I['scalar'] := ord(dtScalar);\n    datatypes.I['any'] := ord(dtAny);\n\n    if ObjectIsType(defs, stArray) then\n      for j := 0 to defs.AsArray.Length - 1 do\n        if ObjectIsType(defs.AsArray[j], stObject) then\n          GetNames(defs.AsArray[j]) else\n          begin\n            if assigned(callback) then\n              callback(sender, veRuleMalformated, '');\n            Exit;\n          end;\n\n\n    if ObjectIsType(rules, stObject) then\n      GetNames(rules) else\n      begin\n        if assigned(callback) then\n          callback(sender, veRuleMalformated, '');\n        Exit;\n      end;\n\n    Result := process(self, rules);\n\n  finally\n    datatypes := nil;\n    names := nil;\n  end;\nend;\n\nfunction TSuperObject._AddRef: Integer; stdcall;\nbegin\n  Result := InterlockedIncrement(FRefCount);\nend;\n\nfunction TSuperObject._Release: Integer; stdcall;\nbegin\n  Result := InterlockedDecrement(FRefCount);\n  if Result = 0 then\n    Destroy;\nend;\n\nfunction TSuperObject.Compare(const str: SOString): TSuperCompareResult;\nbegin\n  Result := Compare(TSuperObject.ParseString(PSOChar(str), False));\nend;\n\nfunction TSuperObject.Compare(const obj: ISuperObject): TSuperCompareResult;\n  function GetIntCompResult(const i: int64): TSuperCompareResult;\n  begin\n    if i < 0 then result := cpLess else\n    if i = 0 then result := cpEqu else\n      Result := cpGreat;\n  end;\n\n  function GetDblCompResult(const d: double): TSuperCompareResult;\n  begin\n    if d < 0 then result := cpLess else\n    if d = 0 then result := cpEqu else\n      Result := cpGreat;\n  end;\n\nbegin\n  case DataType of\n    stBoolean:\n      case ObjectGetType(obj) of\n        stBoolean: Result := GetIntCompResult(ord(FO.c_boolean) - ord(obj.AsBoolean));\n        stDouble:  Result := GetDblCompResult(ord(FO.c_boolean) - obj.AsDouble);\n        stCurrency:Result := GetDblCompResult(ord(FO.c_boolean) - obj.AsCurrency);\n        stInt:     Result := GetIntCompResult(ord(FO.c_boolean) - obj.AsInteger);\n        stString:  Result := GetIntCompResult(StrComp(PSOChar(AsString), PSOChar(obj.AsString)));\n      else\n        Result := cpError;\n      end;\n    stDouble:\n      case ObjectGetType(obj) of\n        stBoolean: Result := GetDblCompResult(FO.c_double - ord(obj.AsBoolean));\n        stDouble:  Result := GetDblCompResult(FO.c_double - obj.AsDouble);\n        stCurrency:Result := GetDblCompResult(FO.c_double - obj.AsCurrency);\n        stInt:     Result := GetDblCompResult(FO.c_double - obj.AsInteger);\n        stString:  Result := GetIntCompResult(StrComp(PSOChar(AsString), PSOChar(obj.AsString)));\n      else\n        Result := cpError;\n      end;\n    stCurrency:\n      case ObjectGetType(obj) of\n        stBoolean: Result := GetDblCompResult(FO.c_currency - ord(obj.AsBoolean));\n        stDouble:  Result := GetDblCompResult(FO.c_currency - obj.AsDouble);\n        stCurrency:Result := GetDblCompResult(FO.c_currency - obj.AsCurrency);\n        stInt:     Result := GetDblCompResult(FO.c_currency - obj.AsInteger);\n        stString:  Result := GetIntCompResult(StrComp(PSOChar(AsString), PSOChar(obj.AsString)));\n      else\n        Result := cpError;\n      end;\n    stInt:\n      case ObjectGetType(obj) of\n        stBoolean: Result := GetIntCompResult(FO.c_int - ord(obj.AsBoolean));\n        stDouble:  Result := GetDblCompResult(FO.c_int - obj.AsDouble);\n        stCurrency:Result := GetDblCompResult(FO.c_int - obj.AsCurrency);\n        stInt:     Result := GetIntCompResult(FO.c_int - obj.AsInteger);\n        stString:  Result := GetIntCompResult(StrComp(PSOChar(AsString), PSOChar(obj.AsString)));\n      else\n        Result := cpError;\n      end;\n    stString:\n      case ObjectGetType(obj) of\n        stBoolean,\n        stDouble,\n        stCurrency,\n        stInt,\n        stString:  Result := GetIntCompResult(StrComp(PSOChar(AsString), PSOChar(obj.AsString)));\n      else\n        Result := cpError;\n      end;\n  else\n    Result := cpError;\n  end;\nend;\n\n{$IFDEF SUPER_METHOD}\nfunction TSuperObject.AsMethod: TSuperMethod;\nbegin\n  if FDataType = stMethod then\n    Result := FO.c_method else\n    Result := nil;\nend;\n{$ENDIF}\n\n{$IFDEF SUPER_METHOD}\nconstructor TSuperObject.Create(m: TSuperMethod);\nbegin\n  Create(stMethod);\n  FO.c_method := m;\nend;\n{$ENDIF}\n\n{$IFDEF SUPER_METHOD}\nfunction TSuperObject.GetM(const path: SOString): TSuperMethod;\nvar\n  v: ISuperObject;\nbegin\n  v := ParseString(PSOChar(path), False, True, Self);\n  if (v <> nil) and (ObjectGetType(v) = stMethod) then\n    Result := v.AsMethod else\n    Result := nil;\nend;\n{$ENDIF}\n\n{$IFDEF SUPER_METHOD}\nprocedure TSuperObject.PutM(const path: SOString; Value: TSuperMethod);\nbegin\n  ParseString(PSOChar(path), False, True, Self, [foCreatePath, foPutValue], TSuperObject.Create(Value));\nend;\n{$ENDIF}\n\n{$IFDEF SUPER_METHOD}\nfunction TSuperObject.call(const path: SOString; const param: ISuperObject): ISuperObject;\nbegin\n  Result := ParseString(PSOChar(path), False, True, Self, [foCallMethod], param);\nend;\n{$ENDIF}\n\n{$IFDEF SUPER_METHOD}\nfunction TSuperObject.call(const path, param: SOString): ISuperObject;\nbegin\n  Result := ParseString(PSOChar(path), False, True, Self, [foCallMethod], TSuperObject.ParseString(PSOChar(param), False));\nend;\n{$ENDIF}\n\nfunction TSuperObject.GetProcessing: boolean;\nbegin\n  Result := FProcessing;\nend;\n\nprocedure TSuperObject.SetDataPtr(const Value: Pointer);\nbegin\n  FDataPtr := Value;\nend;\n\nprocedure TSuperObject.SetProcessing(value: boolean);\nbegin\n  FProcessing := value;\nend;\n\n{ TSuperArray }\n\nfunction TSuperArray.Add(const Data: ISuperObject): Integer;\nbegin\n  Result := FLength;\n  PutO(Result, data);\nend;\n\nfunction TSuperArray.Delete(index: Integer): ISuperObject;\nbegin\n  if (Index >= 0) and (Index < FLength) then\n  begin\n    Result := FArray^[index];\n    FArray^[index] := nil;\n    Dec(FLength);\n    if Index < FLength then\n    begin\n      Move(FArray^[index + 1], FArray^[index],\n        (FLength - index) * SizeOf(Pointer));\n      Pointer(FArray^[FLength]) := nil;\n    end;\n  end;\nend;\n\nprocedure TSuperArray.Insert(index: Integer; const value: ISuperObject);\nbegin\n  if (Index >= 0) then\n  if (index < FLength) then\n  begin\n    if FLength = FSize then\n      Expand(index);\n    if Index < FLength then\n      Move(FArray^[index], FArray^[index + 1],\n        (FLength - index) * SizeOf(Pointer));\n    Pointer(FArray^[index]) := nil;\n    FArray^[index] := value;\n    Inc(FLength);\n  end else\n    PutO(index, value);\nend;\n\nprocedure TSuperArray.Clear(all: boolean);\nvar\n  j: Integer;\nbegin\n  for j := 0 to FLength - 1 do\n    if FArray^[j] <> nil then\n    begin\n      if all then\n        FArray^[j].Clear(all);\n      FArray^[j] := nil;\n    end;\n  FLength := 0;\nend;\n\nprocedure TSuperArray.Pack(all: boolean);\nvar\n  PackedCount, StartIndex, EndIndex, j: Integer;\nbegin\n  if FLength > 0 then\n  begin\n    PackedCount := 0;\n    StartIndex := 0;\n    repeat\n      while (StartIndex < FLength) and (FArray^[StartIndex] = nil) do\n        Inc(StartIndex);\n      if StartIndex < FLength then\n        begin\n          EndIndex := StartIndex;\n          while (EndIndex < FLength) and  (FArray^[EndIndex] <> nil) do\n            Inc(EndIndex);\n\n          Dec(EndIndex);\n\n          if StartIndex > PackedCount then\n            Move(FArray^[StartIndex], FArray^[PackedCount], (EndIndex - StartIndex + 1) * SizeOf(Pointer));\n\n          Inc(PackedCount, EndIndex - StartIndex + 1);\n          StartIndex := EndIndex + 1;\n        end;\n    until StartIndex >= FLength;\n    FillChar(FArray^[PackedCount], (FLength - PackedCount) * sizeof(Pointer), 0);\n    FLength := PackedCount;\n    if all then\n      for j := 0 to FLength - 1 do\n        FArray^[j].Pack(all);\n  end;\nend;\n\nconstructor TSuperArray.Create;\nbegin\n  inherited Create;\n  FSize := SUPER_ARRAY_LIST_DEFAULT_SIZE;\n  FLength := 0;\n  GetMem(FArray, sizeof(Pointer) * FSize);\n  FillChar(FArray^, sizeof(Pointer) * FSize, 0);\nend;\n\ndestructor TSuperArray.Destroy;\nbegin\n  Clear;\n  FreeMem(FArray);\n  inherited;\nend;\n\nprocedure TSuperArray.Expand(max: Integer);\nvar\n  new_size: Integer;\nbegin\n  if (max < FSize) then\n    Exit;\n  if max < (FSize shl 1) then\n    new_size := (FSize shl 1) else\n    new_size := max + 1;\n  ReallocMem(FArray, new_size * sizeof(Pointer));\n  FillChar(FArray^[FSize], (new_size - FSize) * sizeof(Pointer), 0);\n  FSize := new_size;\nend;\n\nfunction TSuperArray.GetO(const index: Integer): ISuperObject;\nbegin\n  if(index >= FLength) then\n    Result := nil else\n    Result := FArray^[index];\nend;\n\nfunction TSuperArray.GetB(const index: integer): Boolean;\nvar\n  obj: ISuperObject;\nbegin\n  obj := GetO(index);\n  if obj <> nil then\n    Result := obj.AsBoolean else\n    Result := false;\nend;\n\nfunction TSuperArray.GetD(const index: integer): Double;\nvar\n  obj: ISuperObject;\nbegin\n  obj := GetO(index);\n  if obj <> nil then\n    Result := obj.AsDouble else\n    Result := 0.0;\nend;\n\nfunction TSuperArray.GetI(const index: integer): SuperInt;\nvar\n  obj: ISuperObject;\nbegin\n  obj := GetO(index);\n  if obj <> nil then\n    Result := obj.AsInteger else\n    Result := 0;\nend;\n\nfunction TSuperArray.GetS(const index: integer): SOString;\nvar\n  obj: ISuperObject;\nbegin\n  obj := GetO(index);\n  if obj <> nil then\n    Result := obj.AsString else\n    Result := '';\nend;\n\nprocedure TSuperArray.PutO(const index: Integer; const Value: ISuperObject);\nbegin\n  Expand(index);\n  FArray^[index] := value;\n  if(FLength <= index) then FLength := index + 1;\nend;\n\nfunction TSuperArray.GetN(const index: integer): ISuperObject;\nbegin\n  Result := GetO(index);\n  if Result = nil then\n    Result := TSuperObject.Create(stNull);\nend;\n\nprocedure TSuperArray.PutN(const index: integer; const Value: ISuperObject);\nbegin\n  if Value <> nil then\n    PutO(index, Value) else\n    PutO(index, TSuperObject.Create(stNull));\nend;\n\nprocedure TSuperArray.PutB(const index: integer; Value: Boolean);\nbegin\n  PutO(index, TSuperObject.Create(Value));\nend;\n\nprocedure TSuperArray.PutD(const index: integer; Value: Double);\nbegin\n  PutO(index, TSuperObject.Create(Value));\nend;\n\nfunction TSuperArray.GetC(const index: integer): Currency;\nvar\n  obj: ISuperObject;\nbegin\n  obj := GetO(index);\n  if obj <> nil then\n    Result := obj.AsCurrency else\n    Result := 0.0;\nend;\n\nprocedure TSuperArray.PutC(const index: integer; Value: Currency);\nbegin\n  PutO(index, TSuperObject.CreateCurrency(Value));\nend;\n\nprocedure TSuperArray.PutI(const index: integer; Value: SuperInt);\nbegin\n  PutO(index, TSuperObject.Create(Value));\nend;\n\nprocedure TSuperArray.PutS(const index: integer; const Value: SOString);\nbegin\n  PutO(index, TSuperObject.Create(Value));\nend;\n\n{$IFDEF SUPER_METHOD}\nfunction TSuperArray.GetM(const index: integer): TSuperMethod;\nvar\n  v: ISuperObject;\nbegin\n  v := GetO(index);\n  if (ObjectGetType(v) = stMethod) then\n    Result := v.AsMethod else\n    Result := nil;\nend;\n{$ENDIF}\n\n{$IFDEF SUPER_METHOD}\nprocedure TSuperArray.PutM(const index: integer; Value: TSuperMethod);\nbegin\n  PutO(index, TSuperObject.Create(Value));\nend;\n{$ENDIF}\n\n{ TSuperWriterString }\n\nfunction TSuperWriterString.Append(buf: PSOChar; Size: Integer): Integer;\n  function max(a, b: Integer): integer; begin if a > b then  Result := a else Result := b end;\nbegin\n  Result := size;\n  if Size > 0 then\n  begin\n    if (FSize - FBPos <= size) then\n    begin\n      FSize := max(FSize * 2, FBPos + size + 8);\n      ReallocMem(FBuf, FSize * SizeOf(SOChar));\n    end;\n    // fast move\n    case size of\n    1: FBuf[FBPos] := buf^;\n    2: PInteger(@FBuf[FBPos])^ := PInteger(buf)^;\n    4: PInt64(@FBuf[FBPos])^ := PInt64(buf)^;\n    else\n      move(buf^, FBuf[FBPos], size * SizeOf(SOChar));\n    end;\n    inc(FBPos, size);\n    FBuf[FBPos] := #0;\n  end;\nend;\n\nfunction TSuperWriterString.Append(buf: PSOChar): Integer;\nbegin\n  Result := Append(buf, strlen(buf));\nend;\n\nconstructor TSuperWriterString.Create;\nbegin\n  inherited;\n  FSize := 32;\n  FBPos := 0;\n  GetMem(FBuf, FSize * SizeOf(SOChar));\nend;\n\ndestructor TSuperWriterString.Destroy;\nbegin\n  inherited;\n  if FBuf <> nil then\n    FreeMem(FBuf)\nend;\n\nfunction TSuperWriterString.GetString: SOString;\nbegin\n  SetString(Result, FBuf, FBPos);\nend;\n\nprocedure TSuperWriterString.Reset;\nbegin\n  FBuf[0] := #0;\n  FBPos := 0;\nend;\n\nprocedure TSuperWriterString.TrimRight;\nbegin\n  while (FBPos > 0) and (FBuf[FBPos-1] < #256) and (AnsiChar(FBuf[FBPos-1]) in [#32, #13, #10]) do\n  begin\n    dec(FBPos);\n    FBuf[FBPos] := #0;\n  end;\nend;\n\n{ TSuperWriterStream }\n\nfunction TSuperWriterStream.Append(buf: PSOChar): Integer;\nbegin\n  Result := Append(buf, StrLen(buf));\nend;\n\nconstructor TSuperWriterStream.Create(AStream: TStream);\nbegin\n  inherited Create;\n  FStream := AStream;\nend;\n\nprocedure TSuperWriterStream.Reset;\nbegin\n  FStream.Size := 0;\nend;\n\n{ TSuperWriterStream }\n\nfunction TSuperAnsiWriterStream.Append(buf: PSOChar; Size: Integer): Integer;\nvar\n  Buffer: array[0..1023] of AnsiChar;\n  pBuffer: PAnsiChar;\n  i: Integer;\nbegin\n  if Size = 1 then\n    Result := FStream.Write(buf^, Size) else\n  begin\n    if Size > SizeOf(Buffer) then\n      GetMem(pBuffer, Size) else\n      pBuffer := @Buffer;\n    try\n      for i :=  0 to Size - 1 do\n        pBuffer[i] := AnsiChar(buf[i]);\n      Result := FStream.Write(pBuffer^, Size);\n    finally\n      if pBuffer <> @Buffer then\n        FreeMem(pBuffer);\n    end;\n  end;\nend;\n\n{ TSuperUnicodeWriterStream }\n\nfunction TSuperUnicodeWriterStream.Append(buf: PSOChar; Size: Integer): Integer;\nbegin\n  Result := FStream.Write(buf^, Size * 2);\nend;\n\n{ TSuperWriterFake }\n\nfunction TSuperWriterFake.Append(buf: PSOChar; Size: Integer): Integer;\nbegin\n  inc(FSize, Size);\n  Result := FSize;\nend;\n\nfunction TSuperWriterFake.Append(buf: PSOChar): Integer;\nbegin\n  inc(FSize, Strlen(buf));\n  Result := FSize;\nend;\n\nconstructor TSuperWriterFake.Create;\nbegin\n  inherited Create;\n  FSize := 0;\nend;\n\nprocedure TSuperWriterFake.Reset;\nbegin\n  FSize := 0;\nend;\n\n{ TSuperWriterSock }\n\nfunction TSuperWriterSock.Append(buf: PSOChar; Size: Integer): Integer;\nvar\n  Buffer: array[0..1023] of AnsiChar;\n  pBuffer: PAnsiChar;\n  i: Integer;\nbegin\n  if Size = 1 then\n{$IFDEF FPC}\n    Result := fpsend(FSocket, buf, size, 0) else\n{$ELSE}\n    Result := send(FSocket, buf^, size, 0) else\n{$ENDIF}\n  begin\n    if Size > SizeOf(Buffer) then\n      GetMem(pBuffer, Size) else\n      pBuffer := @Buffer;\n    try\n      for i :=  0 to Size - 1 do\n        pBuffer[i] := AnsiChar(buf[i]);\n{$IFDEF FPC}\n      Result := fpsend(FSocket, pBuffer, size, 0);\n{$ELSE}\n      Result := send(FSocket, pBuffer^, size, 0);\n{$ENDIF}\n    finally\n      if pBuffer <> @Buffer then\n        FreeMem(pBuffer);\n    end;\n  end;\n  inc(FSize, Result);\nend;\n\nfunction TSuperWriterSock.Append(buf: PSOChar): Integer;\nbegin\n  Result := Append(buf, StrLen(buf));\nend;\n\nconstructor TSuperWriterSock.Create(ASocket: Integer);\nbegin\n  inherited Create;\n  FSocket := ASocket;\n  FSize := 0;\nend;\n\nprocedure TSuperWriterSock.Reset;\nbegin\n  FSize := 0;\nend;\n\n{ TSuperTokenizer }\n\nconstructor TSuperTokenizer.Create;\nbegin\n  pb := TSuperWriterString.Create;\n  line := 1;\n  col := 0;\n  Reset;\nend;\n\ndestructor TSuperTokenizer.Destroy;\nbegin\n  Reset;\n  pb.Free;\n  inherited;\nend;\n\nprocedure TSuperTokenizer.Reset;\nvar\n  i: integer;\nbegin\n  for i := depth downto 0 do\n    ResetLevel(i);\n  depth := 0;\n  err := teSuccess;\nend;\n\nprocedure TSuperTokenizer.ResetLevel(adepth: integer);\nbegin\n  stack[adepth].state := tsEatws;\n  stack[adepth].saved_state := tsStart;\n  stack[adepth].current := nil;\n  stack[adepth].field_name := '';\n  stack[adepth].obj := nil;\n  stack[adepth].parent := nil;\n  stack[adepth].gparent := nil;\nend;\n\n{ TSuperAvlTree }\n\nconstructor TSuperAvlTree.Create;\nbegin\n  FRoot := nil;\n  FCount := 0;\nend;\n\ndestructor TSuperAvlTree.Destroy;\nbegin\n  Clear;\n  inherited;\nend;\n\nfunction TSuperAvlTree.IsEmpty: boolean;\nbegin\n  result := FRoot = nil;\nend;\n\nfunction TSuperAvlTree.balance(bal: TSuperAvlEntry): TSuperAvlEntry;\nvar\n  deep, old: TSuperAvlEntry;\n  bf: integer;\nbegin\n  if (bal.FBf > 0) then\n  begin\n    deep := bal.FGt;\n    if (deep.FBf < 0) then\n    begin\n      old := bal;\n      bal := deep.FLt;\n      old.FGt := bal.FLt;\n      deep.FLt := bal.FGt;\n      bal.FLt := old;\n      bal.FGt := deep;\n      bf := bal.FBf;\n      if (bf <> 0) then\n      begin\n        if (bf > 0) then\n        begin\n          old.FBf := -1;\n          deep.FBf := 0;\n        end else\n        begin\n          deep.FBf := 1;\n          old.FBf := 0;\n        end;\n        bal.FBf := 0;\n      end else\n      begin\n        old.FBf := 0;\n        deep.FBf := 0;\n      end;\n    end else\n    begin\n      bal.FGt := deep.FLt;\n      deep.FLt := bal;\n      if (deep.FBf = 0) then\n      begin\n        deep.FBf := -1;\n        bal.FBf := 1;\n      end else\n      begin\n        deep.FBf := 0;\n        bal.FBf := 0;\n      end;\n      bal := deep;\n    end;\n  end else\n  begin\n    (* \"Less than\" subtree is deeper. *)\n\n    deep := bal.FLt;\n    if (deep.FBf > 0) then\n    begin\n      old := bal;\n      bal := deep.FGt;\n      old.FLt := bal.FGt;\n      deep.FGt := bal.FLt;\n      bal.FGt := old;\n      bal.FLt := deep;\n\n      bf := bal.FBf;\n      if (bf <> 0) then\n      begin\n        if (bf < 0) then\n        begin\n          old.FBf := 1;\n          deep.FBf := 0;\n        end else\n        begin\n          deep.FBf := -1;\n          old.FBf := 0;\n        end;\n        bal.FBf := 0;\n      end else\n      begin\n        old.FBf := 0;\n        deep.FBf := 0;\n      end;\n    end else\n    begin\n      bal.FLt := deep.FGt;\n      deep.FGt := bal;\n      if (deep.FBf = 0) then\n      begin\n        deep.FBf := 1;\n        bal.FBf := -1;\n      end else\n      begin\n        deep.FBf := 0;\n        bal.FBf := 0;\n      end;\n      bal := deep;\n    end;\n  end;\n  Result := bal;\nend;\n\nfunction TSuperAvlTree.Insert(h: TSuperAvlEntry): TSuperAvlEntry;\nvar\n  unbal, parentunbal, hh, parent: TSuperAvlEntry;\n  depth, unbaldepth: longint;\n  cmp: integer;\n  unbalbf: integer;\n  branch: TSuperAvlBitArray;\n  p: Pointer;\nbegin\n  inc(FCount);\n  h.FLt := nil;\n  h.FGt := nil;\n  h.FBf := 0;\n  branch := [];\n\n  if (FRoot = nil) then\n    FRoot := h\n  else\n  begin\n    unbal := nil;\n    parentunbal := nil;\n    depth := 0;\n    unbaldepth := 0;\n    hh := FRoot;\n    parent := nil;\n    repeat\n      if (hh.FBf <> 0) then\n      begin\n        unbal := hh;\n        parentunbal := parent;\n        unbaldepth := depth;\n      end;\n      if hh.FHash <> h.FHash then\n      begin\n        if hh.FHash < h.FHash then cmp := -1 else\n        if hh.FHash > h.FHash then cmp := 1 else\n          cmp := 0;\n      end else\n        cmp := CompareNodeNode(h, hh);\n      if (cmp = 0) then\n      begin\n        Result := hh;\n        //exchange data\n        p := hh.Ptr;\n        hh.FPtr := h.Ptr;\n        h.FPtr := p;\n        doDeleteEntry(h, false);\n        dec(FCount);\n        exit;\n      end;\n      parent := hh;\n      if (cmp > 0) then\n      begin\n        hh := hh.FGt;\n        include(branch, depth);\n      end else\n      begin\n        hh := hh.FLt;\n        exclude(branch, depth);\n      end;\n      inc(depth);\n    until (hh = nil);\n\n    if (cmp < 0) then\n      parent.FLt := h else\n      parent.FGt := h;\n\n    depth := unbaldepth;\n\n    if (unbal = nil) then\n      hh := FRoot\n    else\n    begin\n      if depth in branch then\n        cmp := 1 else\n        cmp := -1;\n      inc(depth);\n      unbalbf := unbal.FBf;\n      if (cmp < 0) then\n        dec(unbalbf) else\n        inc(unbalbf);\n      if cmp < 0 then\n        hh := unbal.FLt else\n        hh := unbal.FGt;\n      if ((unbalbf <> -2) and (unbalbf <> 2)) then\n      begin\n        unbal.FBf := unbalbf;\n        unbal := nil;\n      end;\n    end;\n\n    if (hh <> nil) then\n      while (h <> hh) do\n      begin\n        if depth in branch then\n          cmp := 1 else\n          cmp := -1;\n        inc(depth);\n        if (cmp < 0) then\n        begin\n          hh.FBf := -1;\n          hh := hh.FLt;\n        end else (* cmp > 0 *)\n        begin\n          hh.FBf := 1;\n          hh := hh.FGt;\n        end;\n      end;\n\n    if (unbal <> nil) then\n    begin\n      unbal := balance(unbal);\n      if (parentunbal = nil) then\n        FRoot := unbal\n      else\n      begin\n        depth := unbaldepth - 1;\n        if depth in branch then\n          cmp := 1 else\n          cmp := -1;\n        if (cmp < 0) then\n          parentunbal.FLt := unbal else\n          parentunbal.FGt := unbal;\n      end;\n    end;\n  end;\n  result := h;\nend;\n\nfunction TSuperAvlTree.Search(const k: SOString; st: TSuperAvlSearchTypes): TSuperAvlEntry;\nvar\n  cmp, target_cmp: integer;\n  match_h, h: TSuperAvlEntry;\n  ha: Cardinal;\nbegin\n  ha := TSuperAvlEntry.Hash(k);\n\n  match_h := nil;\n  h := FRoot;\n\n  if (stLess in st) then\n    target_cmp := 1 else\n    if (stGreater in st) then\n      target_cmp := -1 else\n      target_cmp := 0;\n\n  while (h <> nil) do\n  begin\n    if h.FHash < ha then cmp := -1 else\n    if h.FHash > ha then cmp := 1 else\n      cmp := 0;\n\n    if cmp = 0 then\n      cmp := CompareKeyNode(PSOChar(k), h);\n    if (cmp = 0) then\n    begin\n      if (stEqual in st) then\n      begin\n        match_h := h;\n        break;\n      end;\n      cmp := -target_cmp;\n    end\n    else\n    if (target_cmp <> 0) then\n      if ((cmp xor target_cmp) and SUPER_AVL_MASK_HIGH_BIT) = 0 then\n        match_h := h;\n    if cmp < 0 then\n      h := h.FLt else\n      h := h.FGt;\n  end;\n  result := match_h;\nend;\n\nfunction TSuperAvlTree.Delete(const k: SOString): ISuperObject;\nvar\n  depth, rm_depth: longint;\n  branch: TSuperAvlBitArray;\n  h, parent, child, path, rm, parent_rm: TSuperAvlEntry;\n  cmp, cmp_shortened_sub_with_path, reduced_depth, bf: integer;\n  ha: Cardinal;\nbegin\n  ha := TSuperAvlEntry.Hash(k);\n  cmp_shortened_sub_with_path := 0;\n  branch := [];\n\n  depth := 0;\n  h := FRoot;\n  parent := nil;\n  while true do\n  begin\n    if (h = nil) then\n      exit;\n    if h.FHash < ha then cmp := -1 else\n    if h.FHash > ha then cmp := 1 else\n      cmp := 0;\n\n    if cmp = 0 then\n      cmp := CompareKeyNode(k, h);\n    if (cmp = 0) then\n      break;\n    parent := h;\n    if (cmp > 0) then\n    begin\n      h := h.FGt;\n      include(branch, depth)\n    end else\n    begin\n      h := h.FLt;\n      exclude(branch, depth)\n    end;\n    inc(depth);\n    cmp_shortened_sub_with_path := cmp;\n  end;\n  rm := h;\n  parent_rm := parent;\n  rm_depth := depth;\n\n  if (h.FBf < 0) then\n  begin\n    child := h.FLt;\n    exclude(branch, depth);\n    cmp := -1;\n  end else\n  begin\n    child := h.FGt;\n    include(branch, depth);\n    cmp := 1;\n  end;\n  inc(depth);\n\n  if (child <> nil) then\n  begin\n    cmp := -cmp;\n    repeat\n      parent := h;\n      h := child;\n      if (cmp < 0) then\n      begin\n        child := h.FLt;\n        exclude(branch, depth);\n      end else\n      begin\n        child := h.FGt;\n        include(branch, depth);\n      end;\n      inc(depth);\n    until (child = nil);\n\n    if (parent = rm) then\n      cmp_shortened_sub_with_path := -cmp else\n      cmp_shortened_sub_with_path := cmp;\n\n    if cmp > 0 then\n      child := h.FLt else\n      child := h.FGt;\n  end;\n\n  if (parent = nil) then\n    FRoot := child else\n    if (cmp_shortened_sub_with_path < 0) then\n      parent.FLt := child else\n      parent.FGt := child;\n\n  if parent = rm then\n    path := h else\n    path := parent;\n\n  if (h <> rm) then\n  begin\n    h.FLt := rm.FLt;\n    h.FGt := rm.FGt;\n    h.FBf := rm.FBf;\n    if (parent_rm = nil) then\n      FRoot := h\n    else\n    begin\n      depth := rm_depth - 1;\n      if (depth in branch) then\n        parent_rm.FGt := h else\n        parent_rm.FLt := h;\n    end;\n  end;\n\n  if (path <> nil) then\n  begin\n    h := FRoot;\n    parent := nil;\n    depth := 0;\n    while (h <> path) do\n    begin\n      if (depth in branch) then\n      begin\n        child := h.FGt;\n        h.FGt := parent;\n      end else\n      begin\n        child := h.FLt;\n        h.FLt := parent;\n      end;\n      inc(depth);\n      parent := h;\n      h := child;\n    end;\n\n    reduced_depth := 1;\n    cmp := cmp_shortened_sub_with_path;\n    while true do\n    begin\n      if (reduced_depth <> 0) then\n      begin\n        bf := h.FBf;\n        if (cmp < 0) then\n          inc(bf) else\n          dec(bf);\n        if ((bf = -2) or (bf = 2)) then\n        begin\n          h := balance(h);\n          bf := h.FBf;\n        end else\n          h.FBf := bf;\n        reduced_depth := integer(bf = 0);\n      end;\n      if (parent = nil) then\n        break;\n      child := h;\n      h := parent;\n      dec(depth);\n      if depth in branch then\n        cmp := 1 else\n        cmp := -1;\n      if (cmp < 0) then\n      begin\n        parent := h.FLt;\n        h.FLt := child;\n      end else\n      begin\n        parent := h.FGt;\n        h.FGt := child;\n      end;\n    end;\n    FRoot := h;\n  end;\n  if rm <> nil then\n  begin\n    Result := rm.GetValue;\n    doDeleteEntry(rm, false);\n    dec(FCount);\n  end;\nend;\n\nprocedure TSuperAvlTree.Pack(all: boolean);\nvar\n  node1, node2: TSuperAvlEntry;\n  list: TList;\n  i: Integer;\nbegin\n  node1 := FRoot;\n  list := TList.Create;\n  while node1 <> nil do\n  begin\n    if (node1.FLt = nil) then\n    begin\n      node2 := node1.FGt;\n      if (node1.FPtr = nil) then\n        list.Add(node1) else\n        if all then\n          node1.Value.Pack(all);\n    end\n    else\n    begin\n      node2 := node1.FLt;\n      node1.FLt := node2.FGt;\n      node2.FGt := node1;\n    end;\n    node1 := node2;\n  end;\n  for i := 0 to list.Count - 1 do\n    Delete(TSuperAvlEntry(list[i]).FName);\n  list.Free;\nend;\n\nprocedure TSuperAvlTree.Clear(all: boolean);\nvar\n  node1, node2: TSuperAvlEntry;\nbegin\n  node1 := FRoot;\n  while node1 <> nil do\n  begin\n    if (node1.FLt = nil) then\n    begin\n      node2 := node1.FGt;\n      doDeleteEntry(node1, all);\n    end\n    else\n    begin\n      node2 := node1.FLt;\n      node1.FLt := node2.FGt;\n      node2.FGt := node1;\n    end;\n    node1 := node2;\n  end;\n  FRoot := nil;\n  FCount := 0;\nend;\n\nfunction TSuperAvlTree.CompareKeyNode(const k: SOString; h: TSuperAvlEntry): integer;\nbegin\n  Result := StrComp(PSOChar(k), PSOChar(h.FName));\nend;\n\nfunction TSuperAvlTree.CompareNodeNode(node1, node2: TSuperAvlEntry): integer;\nbegin\n  Result := StrComp(PSOChar(node1.FName), PSOChar(node2.FName));\nend;\n\n{ TSuperAvlIterator }\n\n(* Initialize depth to invalid value, to indicate iterator is\n** invalid.   (Depth is zero-base.)  It's not necessary to initialize\n** iterators prior to passing them to the \"start\" function.\n*)\n\nconstructor TSuperAvlIterator.Create(tree: TSuperAvlTree);\nbegin\n  FDepth := not 0;\n  FTree := tree;\nend;\n\nprocedure TSuperAvlIterator.Search(const k: SOString; st: TSuperAvlSearchTypes);\nvar\n  h: TSuperAvlEntry;\n  d: longint;\n  cmp, target_cmp: integer;\n  ha: Cardinal;\nbegin\n  ha := TSuperAvlEntry.Hash(k);\n  h := FTree.FRoot;\n  d := 0;\n  FDepth := not 0;\n  if (h = nil) then\n    exit;\n\n  if (stLess in st) then\n    target_cmp := 1 else\n      if (stGreater in st) then\n        target_cmp := -1 else\n          target_cmp := 0;\n\n  while true do\n  begin\n    if h.FHash < ha then cmp := -1 else\n    if h.FHash > ha then cmp := 1 else\n      cmp := 0;\n\n    if cmp = 0 then\n      cmp := FTree.CompareKeyNode(k, h);\n    if (cmp = 0) then\n    begin\n      if (stEqual in st) then\n      begin\n        FDepth := d;\n        break;\n      end;\n      cmp := -target_cmp;\n    end\n    else\n    if (target_cmp <> 0) then\n      if ((cmp xor target_cmp) and SUPER_AVL_MASK_HIGH_BIT) = 0 then\n        FDepth := d;\n    if cmp < 0 then\n      h := h.FLt else\n      h := h.FGt;\n    if (h = nil) then\n      break;\n    if (cmp > 0) then\n      include(FBranch, d) else\n      exclude(FBranch, d);\n    FPath[d] := h;\n    inc(d);\n  end;\nend;\n\nprocedure TSuperAvlIterator.First;\nvar\n  h: TSuperAvlEntry;\nbegin\n  h := FTree.FRoot;\n  FDepth := not 0;\n  FBranch := [];\n  while (h <> nil) do\n  begin\n    if (FDepth <> not 0) then\n      FPath[FDepth] := h;\n    inc(FDepth);\n    h := h.FLt;\n  end;\nend;\n\nprocedure TSuperAvlIterator.Last;\nvar\n  h: TSuperAvlEntry;\nbegin\n  h := FTree.FRoot;\n  FDepth := not 0;\n  FBranch := [0..SUPER_AVL_MAX_DEPTH - 1];\n  while (h <> nil) do\n  begin\n    if (FDepth <> not 0) then\n      FPath[FDepth] := h;\n    inc(FDepth);\n    h := h.FGt;\n  end;\nend;\n\nfunction TSuperAvlIterator.MoveNext: boolean;\nbegin\n  if FDepth = not 0 then\n    First else\n    Next;\n  Result := GetIter <> nil;\nend;\n\nfunction TSuperAvlIterator.GetIter: TSuperAvlEntry;\nbegin\n  if (FDepth = not 0) then\n  begin\n    result := nil;\n    exit;\n  end;\n  if FDepth = 0 then\n    Result := FTree.FRoot else\n    Result := FPath[FDepth - 1];\nend;\n\nprocedure TSuperAvlIterator.Next;\nvar\n  h: TSuperAvlEntry;\nbegin\n  if (FDepth <> not 0) then\n  begin\n    if FDepth = 0 then\n      h := FTree.FRoot.FGt else\n      h := FPath[FDepth - 1].FGt;\n\n    if (h = nil) then\n      repeat\n        if (FDepth = 0) then\n        begin\n          FDepth := not 0;\n          break;\n        end;\n        dec(FDepth);\n      until (not (FDepth in FBranch))\n    else\n    begin\n      include(FBranch, FDepth);\n      FPath[FDepth] := h;\n      inc(FDepth);\n      while true do\n      begin\n        h := h.FLt;\n        if (h = nil) then\n          break;\n        exclude(FBranch, FDepth);\n        FPath[FDepth] := h;\n        inc(FDepth);\n      end;\n    end;\n  end;\nend;\n\nprocedure TSuperAvlIterator.Prior;\nvar\n  h: TSuperAvlEntry;\nbegin\n  if (FDepth <> not 0) then\n  begin\n    if FDepth = 0 then\n      h := FTree.FRoot.FLt else\n      h := FPath[FDepth - 1].FLt;\n    if (h = nil) then\n      repeat\n        if (FDepth = 0) then\n        begin\n          FDepth := not 0;\n          break;\n        end;\n        dec(FDepth);\n      until (FDepth in FBranch)\n    else\n    begin\n      exclude(FBranch, FDepth);\n      FPath[FDepth] := h;\n      inc(FDepth);\n      while true do\n      begin\n        h := h.FGt;\n        if (h = nil) then\n          break;\n        include(FBranch, FDepth);\n        FPath[FDepth] := h;\n        inc(FDepth);\n      end;\n    end;\n  end;\nend;\n\nprocedure TSuperAvlTree.doDeleteEntry(Entry: TSuperAvlEntry; all: boolean);\nbegin\n  Entry.Free;\nend;\n\nfunction TSuperAvlTree.GetEnumerator: TSuperAvlIterator;\nbegin\n  Result := TSuperAvlIterator.Create(Self);\nend;\n\n{ TSuperAvlEntry }\n\nconstructor TSuperAvlEntry.Create(const AName: SOString; Obj: Pointer);\nbegin\n  FName := AName;\n  FPtr := Obj;\n  FHash := Hash(FName);\nend;\n\nfunction TSuperAvlEntry.GetValue: ISuperObject;\nbegin\n  Result := ISuperObject(FPtr)\nend;\n\nclass function TSuperAvlEntry.Hash(const k: SOString): Cardinal;\nvar\n  h: cardinal;\n  i: Integer;\nbegin\n  h := 0;\n{$Q-}\n  for i := 1 to Length(k) do\n    h := h*129 + ord(k[i]) + $9e370001;\n{$Q+}\n  Result := h;\nend;\n\nprocedure TSuperAvlEntry.SetValue(const val: ISuperObject);\nbegin\n  ISuperObject(FPtr) := val;\nend;\n\n{ TSuperTableString }\n\nfunction TSuperTableString.GetValues: ISuperObject;\nvar\n  ite: TSuperAvlIterator;\n  obj: TSuperAvlEntry;\nbegin\n  Result := TSuperObject.Create(stArray);\n  ite := TSuperAvlIterator.Create(Self);\n  try\n    ite.First;\n    obj := ite.GetIter;\n    while obj <> nil do\n    begin\n      Result.AsArray.Add(obj.Value);\n      ite.Next;\n      obj := ite.GetIter;\n    end;\n  finally\n    ite.Free;\n  end;\nend;\n\nfunction TSuperTableString.GetNames: ISuperObject;\nvar\n  ite: TSuperAvlIterator;\n  obj: TSuperAvlEntry;\nbegin\n  Result := TSuperObject.Create(stArray);\n  ite := TSuperAvlIterator.Create(Self);\n  try\n    ite.First;\n    obj := ite.GetIter;\n    while obj <> nil do\n    begin\n      Result.AsArray.Add(TSuperObject.Create(obj.FName));\n      ite.Next;\n      obj := ite.GetIter;\n    end;\n  finally\n    ite.Free;\n  end;\nend;\n\nprocedure TSuperTableString.doDeleteEntry(Entry: TSuperAvlEntry; all: boolean);\nbegin\n  if Entry.Ptr <> nil then\n  begin\n    if all then Entry.Value.Clear(true);\n    Entry.Value := nil;\n  end;\n  inherited;\nend;\n\nfunction TSuperTableString.GetO(const k: SOString): ISuperObject;\nvar\n  e: TSuperAvlEntry;\nbegin\n  e := Search(k);\n  if e <> nil then\n    Result := e.Value else\n    Result := nil\nend;\n\nprocedure TSuperTableString.PutO(const k: SOString; const value: ISuperObject);\nvar\n  entry: TSuperAvlEntry;\nbegin\n  entry := Insert(TSuperAvlEntry.Create(k, Pointer(value)));\n  if entry.FPtr <> nil then\n    ISuperObject(entry.FPtr)._AddRef;\nend;\n\nprocedure TSuperTableString.PutS(const k: SOString; const value: SOString);\nbegin\n  PutO(k, TSuperObject.Create(Value));\nend;\n\nfunction TSuperTableString.GetS(const k: SOString): SOString;\nvar\n  obj: ISuperObject;\nbegin\n obj := GetO(k);\n if obj <> nil then\n   Result := obj.AsString else\n   Result := '';\nend;\n\nprocedure TSuperTableString.PutI(const k: SOString; value: SuperInt);\nbegin\n  PutO(k, TSuperObject.Create(Value));\nend;\n\nfunction TSuperTableString.GetI(const k: SOString): SuperInt;\nvar\n  obj: ISuperObject;\nbegin\n obj := GetO(k);\n if obj <> nil then\n   Result := obj.AsInteger else\n   Result := 0;\nend;\n\nprocedure TSuperTableString.PutD(const k: SOString; value: Double);\nbegin\n  PutO(k, TSuperObject.Create(Value));\nend;\n\nprocedure TSuperTableString.PutC(const k: SOString; value: Currency);\nbegin\n  PutO(k, TSuperObject.CreateCurrency(Value));\nend;\n\nfunction TSuperTableString.GetC(const k: SOString): Currency;\nvar\n  obj: ISuperObject;\nbegin\n obj := GetO(k);\n if obj <> nil then\n   Result := obj.AsCurrency else\n   Result := 0.0;\nend;\n\nfunction TSuperTableString.GetD(const k: SOString): Double;\nvar\n  obj: ISuperObject;\nbegin\n obj := GetO(k);\n if obj <> nil then\n   Result := obj.AsDouble else\n   Result := 0.0;\nend;\n\nprocedure TSuperTableString.PutB(const k: SOString; value: Boolean);\nbegin\n  PutO(k, TSuperObject.Create(Value));\nend;\n\nfunction TSuperTableString.GetB(const k: SOString): Boolean;\nvar\n  obj: ISuperObject;\nbegin\n obj := GetO(k);\n if obj <> nil then\n   Result := obj.AsBoolean else\n   Result := False;\nend;\n\n{$IFDEF SUPER_METHOD}\nprocedure TSuperTableString.PutM(const k: SOString; value: TSuperMethod);\nbegin\n  PutO(k, TSuperObject.Create(Value));\nend;\n{$ENDIF}\n\n{$IFDEF SUPER_METHOD}\nfunction TSuperTableString.GetM(const k: SOString): TSuperMethod;\nvar\n  obj: ISuperObject;\nbegin\n obj := GetO(k);\n if obj <> nil then\n   Result := obj.AsMethod else\n   Result := nil;\nend;\n{$ENDIF}\n\nprocedure TSuperTableString.PutN(const k: SOString; const value: ISuperObject);\nbegin\n  if value <> nil then\n    PutO(k, TSuperObject.Create(stNull)) else\n    PutO(k, value);\nend;\n\nfunction TSuperTableString.GetN(const k: SOString): ISuperObject;\nvar\n  obj: ISuperObject;\nbegin\n obj := GetO(k);\n if obj <> nil then\n   Result := obj else\n   Result := TSuperObject.Create(stNull);\nend;\n\n\n{$IFDEF VER210}\n\n{ TSuperAttribute }\n\nconstructor TSuperAttribute.Create(const AName: string);\nbegin\n  FName := AName;\nend;\n\n{ TSuperRttiContext }\n\nconstructor TSuperRttiContext.Create;\nbegin\n  Context := TRttiContext.Create;\n  SerialFromJson := TDictionary<PTypeInfo, TSerialFromJson>.Create;\n  SerialToJson := TDictionary<PTypeInfo, TSerialToJson>.Create;\n\n  SerialFromJson.Add(TypeInfo(Boolean), serialfromboolean);\n  SerialFromJson.Add(TypeInfo(TDateTime), serialfromdatetime);\n  SerialFromJson.Add(TypeInfo(TGUID), serialfromguid);\n  SerialToJson.Add(TypeInfo(Boolean), serialtoboolean);\n  SerialToJson.Add(TypeInfo(TDateTime), serialtodatetime);\n  SerialToJson.Add(TypeInfo(TGUID), serialtoguid);\nend;\n\ndestructor TSuperRttiContext.Destroy;\nbegin\n  SerialFromJson.Free;\n  SerialToJson.Free;\n  Context.Free;\nend;\n\nclass function TSuperRttiContext.GetFieldName(r: TRttiField): string;\nvar\n  o: TCustomAttribute;\nbegin\n  for o in r.GetAttributes do\n    if o is SOName then\n      Exit(SOName(o).Name);\n  Result := r.Name;\nend;\n\nclass function TSuperRttiContext.GetFieldDefault(r: TRttiField; const obj: ISuperObject): ISuperObject;\nvar\n  o: TCustomAttribute;\nbegin\n  if not ObjectIsType(obj, stNull) then Exit(obj);\n  for o in r.GetAttributes do\n    if o is SODefault then\n      Exit(SO(SODefault(o).Name));\n  Result := obj;\nend;\n\nfunction TSuperRttiContext.AsType<T>(const obj: ISuperObject): T;\nvar\n  ret: TValue;\nbegin\n  if FromJson(TypeInfo(T), obj, ret) then\n    Result := ret.AsType<T> else\n    raise exception.Create('Marshalling error');\nend;\n\nfunction TSuperRttiContext.AsJson<T>(const obj: T; const index: ISuperObject = nil): ISuperObject;\nvar\n  v: TValue;\nbegin\n  TValue.MakeWithoutCopy(@obj, TypeInfo(T), v);\n  if index <> nil then\n    Result := ToJson(v, index) else\n    Result := ToJson(v, so);\nend;\n\nfunction TSuperRttiContext.FromJson(TypeInfo: PTypeInfo; const obj: ISuperObject;\n  var Value: TValue): Boolean;\n\n  procedure FromChar;\n  begin\n    if ObjectIsType(obj, stString) and (Length(obj.AsString) = 1) then\n      begin\n        Value := string(AnsiString(obj.AsString)[1]);\n        Result := True;\n      end else\n        Result := False;\n  end;\n\n  procedure FromWideChar;\n  begin\n    if ObjectIsType(obj, stString) and (Length(obj.AsString) = 1) then\n    begin\n      Value := obj.AsString[1];\n      Result := True;\n    end else\n      Result := False;\n  end;\n\n  procedure FromInt64;\n  var\n    i: Int64;\n  begin\n    case ObjectGetType(obj) of\n    stInt:\n      begin\n        TValue.Make(nil, TypeInfo, Value);\n        TValueData(Value).FAsSInt64 := obj.AsInteger;\n        Result := True;\n      end;\n    stString:\n      begin\n        if TryStrToInt64(obj.AsString, i) then\n        begin\n          TValue.Make(nil, TypeInfo, Value);\n          TValueData(Value).FAsSInt64 := i;\n          Result := True;\n        end else\n          Result := False;\n      end;\n    else\n      Result := False;\n    end;\n  end;\n\n  procedure FromInt(const obj: ISuperObject);\n  var\n    TypeData: PTypeData;\n    i: Integer;\n    o: ISuperObject;\n  begin\n    case ObjectGetType(obj) of\n    stInt, stBoolean:\n      begin\n        i := obj.AsInteger;\n        TypeData := GetTypeData(TypeInfo);\n        Result := (i >= TypeData.MinValue) and (i <= TypeData.MaxValue);\n        if Result then\n          TValue.Make(@i, TypeInfo, Value);\n      end;\n    stString:\n      begin\n        o := SO(obj.AsString);\n        if not ObjectIsType(o, stString) then\n          FromInt(o) else\n          Result := False;\n      end;\n    else\n      Result := False;\n    end;\n  end;\n\n  procedure fromSet;\n  begin\n    if ObjectIsType(obj, stInt) then\n    begin\n      TValue.Make(nil, TypeInfo, Value);\n      TValueData(Value).FAsSLong := obj.AsInteger;\n      Result := True;\n    end else\n      Result := False;\n  end;\n\n  procedure FromFloat(const obj: ISuperObject);\n  var\n    o: ISuperObject;\n  begin\n    case ObjectGetType(obj) of\n    stInt, stDouble, stCurrency:\n      begin\n        TValue.Make(nil, TypeInfo, Value);\n        case GetTypeData(TypeInfo).FloatType of\n          ftSingle: TValueData(Value).FAsSingle := obj.AsDouble;\n          ftDouble: TValueData(Value).FAsDouble := obj.AsDouble;\n          ftExtended: TValueData(Value).FAsExtended := obj.AsDouble;\n          ftComp: TValueData(Value).FAsSInt64 := obj.AsInteger;\n          ftCurr: TValueData(Value).FAsCurr := obj.AsCurrency;\n        end;\n        Result := True;\n      end;\n    stString:\n      begin\n        o := SO(obj.AsString);\n        if not ObjectIsType(o, stString) then\n          FromFloat(o) else\n          Result := False;\n      end\n    else\n       Result := False;\n    end;\n  end;\n\n  procedure FromString;\n  begin\n    case ObjectGetType(obj) of\n    stObject, stArray:\n      Result := False;\n    stnull:\n      begin\n        Value := '';\n        Result := True;\n      end;\n    else\n      Value := obj.AsString;\n      Result := True;\n    end;\n  end;\n\n  procedure FromClass;\n  var\n    f: TRttiField;\n    v: TValue;\n  begin\n    case ObjectGetType(obj) of\n      stObject:\n        begin\n          Result := True;\n          if Value.Kind <> tkClass then\n            Value := GetTypeData(TypeInfo).ClassType.Create;\n          for f in Context.GetType(Value.AsObject.ClassType).GetFields do\n            if f.FieldType <> nil then\n            begin\n              Result := FromJson(f.FieldType.Handle, GetFieldDefault(f, obj.AsObject[GetFieldName(f)]), v);\n              if Result then\n                f.SetValue(Value.AsObject, v) else\n                Exit;\n            end;\n        end;\n      stNull:\n        begin\n          Value := nil;\n          Result := True;\n        end\n    else\n      // error\n      Value := nil;\n      Result := False;\n    end;\n  end;\n\n  procedure FromRecord;\n  var\n    f: TRttiField;\n    p: Pointer;\n    v: TValue;\n  begin\n    Result := True;\n    TValue.Make(nil, TypeInfo, Value);\n    for f in Context.GetType(TypeInfo).GetFields do\n    begin\n      if ObjectIsType(obj, stObject) and (f.FieldType <> nil) then\n      begin\n        p := IValueData(TValueData(Value).FHeapData).GetReferenceToRawData;\n        Result := FromJson(f.FieldType.Handle, GetFieldDefault(f, obj.AsObject[GetFieldName(f)]), v);\n        if Result then\n          f.SetValue(p, v) else\n          Exit;\n      end else\n      begin\n        Result := False;\n        Exit;\n      end;\n    end;\n  end;\n\n  procedure FromDynArray;\n  var\n    i: Integer;\n    p: Pointer;\n    pb: PByte;\n    val: TValue;\n    typ: PTypeData;\n    el: PTypeInfo;\n  begin\n    case ObjectGetType(obj) of\n    stArray:\n      begin\n        i := obj.AsArray.Length;\n        p := nil;\n        DynArraySetLength(p, TypeInfo, 1, @i);\n        pb := p;\n        typ := GetTypeData(TypeInfo);\n        if typ.elType <> nil then\n          el := typ.elType^ else\n          el := typ.elType2^;\n\n        Result := True;\n        for i := 0 to i - 1 do\n        begin\n          Result := FromJson(el, obj.AsArray[i], val);\n          if not Result then\n            Break;\n          val.ExtractRawData(pb);\n          val := TValue.Empty;\n          Inc(pb, typ.elSize);\n        end;\n        if Result then\n          TValue.MakeWithoutCopy(@p, TypeInfo, Value) else\n          DynArrayClear(p, TypeInfo);\n      end;\n    stNull:\n      begin\n        TValue.MakeWithoutCopy(nil, TypeInfo, Value);\n        Result := True;\n      end;\n    else\n      i := 1;\n      p := nil;\n      DynArraySetLength(p, TypeInfo, 1, @i);\n      pb := p;\n      typ := GetTypeData(TypeInfo);\n      if typ.elType <> nil then\n        el := typ.elType^ else\n        el := typ.elType2^;\n\n      Result := FromJson(el, obj, val);\n      val.ExtractRawData(pb);\n      val := TValue.Empty;\n\n      if Result then\n        TValue.MakeWithoutCopy(@p, TypeInfo, Value) else\n        DynArrayClear(p, TypeInfo);\n    end;\n  end;\n\n  procedure FromArray;\n  var\n    ArrayData: PArrayTypeData;\n    idx: Integer;\n    function ProcessDim(dim: Byte; const o: ISuperobject): Boolean;\n    var\n      i: Integer;\n      v: TValue;\n      a: PTypeData;\n    begin\n      if ObjectIsType(o, stArray) and (ArrayData.Dims[dim-1] <> nil) then\n      begin\n        a := @GetTypeData(ArrayData.Dims[dim-1]^).ArrayData;\n        if (a.MaxValue - a.MinValue + 1) <> o.AsArray.Length then\n        begin\n          Result := False;\n          Exit;\n        end;\n        Result := True;\n        if dim = ArrayData.DimCount then\n          for i := a.MinValue to a.MaxValue do\n          begin\n            Result := FromJson(ArrayData.ElType^, o.AsArray[i], v);\n            if not Result then\n              Exit;\n            Value.SetArrayElement(idx, v);\n            inc(idx);\n          end\n        else\n          for i := a.MinValue to a.MaxValue do\n          begin\n            Result := ProcessDim(dim + 1, o.AsArray[i]);\n            if not Result then\n              Exit;\n          end;\n      end else\n        Result := False;\n    end;\n  var\n    i: Integer;\n    v: TValue;\n  begin\n    TValue.Make(nil, TypeInfo, Value);\n    ArrayData := @GetTypeData(TypeInfo).ArrayData;\n    idx := 0;\n    if ArrayData.DimCount = 1 then\n    begin\n      if ObjectIsType(obj, stArray) and (obj.AsArray.Length = ArrayData.ElCount) then\n      begin\n        Result := True;\n        for i := 0 to ArrayData.ElCount - 1 do\n        begin\n          Result := FromJson(ArrayData.ElType^, obj.AsArray[i], v);\n          if not Result then\n            Exit;\n          Value.SetArrayElement(idx, v);\n          v := TValue.Empty;\n          inc(idx);\n        end;\n      end else\n        Result := False;\n    end else\n      Result := ProcessDim(1, obj);\n  end;\n\n  procedure FromClassRef;\n  var\n    r: TRttiType;\n  begin\n    if ObjectIsType(obj, stString) then\n    begin\n      r := Context.FindType(obj.AsString);\n      if r <> nil then\n      begin\n        Value := TRttiInstanceType(r).MetaclassType;\n        Result := True;\n      end else\n        Result := False;\n    end else\n      Result := False;\n  end;\n\n  procedure FromUnknown;\n  begin\n    case ObjectGetType(obj) of\n      stBoolean:\n        begin\n          Value := obj.AsBoolean;\n          Result := True;\n        end;\n      stDouble:\n        begin\n          Value := obj.AsDouble;\n          Result := True;\n        end;\n      stCurrency:\n        begin\n          Value := obj.AsCurrency;\n          Result := True;\n        end;\n      stInt:\n        begin\n          Value := obj.AsInteger;\n          Result := True;\n        end;\n      stString:\n        begin\n          Value := obj.AsString;\n          Result := True;\n        end\n    else\n      Value := nil;\n      Result := False;\n    end;\n  end;\n\n  procedure FromInterface;\n  const soguid: TGuid = '{4B86A9E3-E094-4E5A-954A-69048B7B6327}';\n  var\n    o: ISuperObject;\n  begin\n    if CompareMem(@GetTypeData(TypeInfo).Guid, @soguid, SizeOf(TGUID)) then\n    begin\n      if obj <> nil then\n        TValue.Make(@obj, TypeInfo, Value) else\n        begin\n          o := TSuperObject.Create(stNull);\n          TValue.Make(@o, TypeInfo, Value);\n        end;\n      Result := True;\n    end else\n      Result := False;\n  end;\nvar\n  Serial: TSerialFromJson;\nbegin\n  if TypeInfo <> nil then\n  begin\n    if not SerialFromJson.TryGetValue(TypeInfo, Serial) then\n      case TypeInfo.Kind of\n        tkChar: FromChar;\n        tkInt64: FromInt64;\n        tkEnumeration, tkInteger: FromInt(obj);\n        tkSet: fromSet;\n        tkFloat: FromFloat(obj);\n        tkString, tkLString, tkUString, tkWString: FromString;\n        tkClass: FromClass;\n        tkMethod: ;\n        tkWChar: FromWideChar;\n        tkRecord: FromRecord;\n        tkPointer: ;\n        tkInterface: FromInterface;\n        tkArray: FromArray;\n        tkDynArray: FromDynArray;\n        tkClassRef: FromClassRef;\n      else\n        FromUnknown\n      end else\n      begin\n        TValue.Make(nil, TypeInfo, Value);\n        Result := Serial(Self, obj, Value);\n      end;\n  end else\n    Result := False;\nend;\n\nfunction TSuperRttiContext.ToJson(var value: TValue; const index: ISuperObject): ISuperObject;\n  procedure ToInt64;\n  begin\n    Result := TSuperObject.Create(SuperInt(Value.AsInt64));\n  end;\n\n  procedure ToChar;\n  begin\n    Result := TSuperObject.Create(string(Value.AsType<AnsiChar>));\n  end;\n\n  procedure ToInteger;\n  begin\n    Result := TSuperObject.Create(TValueData(Value).FAsSLong);\n  end;\n\n  procedure ToFloat;\n  begin\n    case Value.TypeData.FloatType of\n      ftSingle: Result := TSuperObject.Create(TValueData(Value).FAsSingle);\n      ftDouble: Result := TSuperObject.Create(TValueData(Value).FAsDouble);\n      ftExtended: Result := TSuperObject.Create(TValueData(Value).FAsExtended);\n      ftComp: Result := TSuperObject.Create(TValueData(Value).FAsSInt64);\n      ftCurr: Result := TSuperObject.CreateCurrency(TValueData(Value).FAsCurr);\n    end;\n  end;\n\n  procedure ToString;\n  begin\n    Result := TSuperObject.Create(string(Value.AsType<string>));\n  end;\n\n  procedure ToClass;\n  var\n    o: ISuperObject;\n    f: TRttiField;\n    v: TValue;\n  begin\n    if TValueData(Value).FAsObject <> nil then\n    begin\n      o := index[IntToStr(Integer(Value.AsObject))];\n      if o = nil then\n      begin\n        Result := TSuperObject.Create(stObject);\n        index[IntToStr(Integer(Value.AsObject))] := Result;\n        for f in Context.GetType(Value.AsObject.ClassType).GetFields do\n          if f.FieldType <> nil then\n          begin\n            v := f.GetValue(Value.AsObject);\n            Result.AsObject[GetFieldName(f)] := ToJson(v, index);\n          end\n      end else\n        Result := o;\n    end else\n      Result := nil;\n  end;\n\n  procedure ToWChar;\n  begin\n    Result :=  TSuperObject.Create(string(Value.AsType<WideChar>));\n  end;\n\n  procedure ToVariant;\n  begin\n    Result := SO(Value.AsVariant);\n  end;\n\n  procedure ToRecord;\n  var\n    f: TRttiField;\n    v: TValue;\n  begin\n    Result := TSuperObject.Create(stObject);\n    for f in Context.GetType(Value.TypeInfo).GetFields do\n    begin\n      v := f.GetValue(IValueData(TValueData(Value).FHeapData).GetReferenceToRawData);\n      Result.AsObject[GetFieldName(f)] := ToJson(v, index);\n    end;\n  end;\n\n  procedure ToArray;\n  var\n    idx: Integer;\n    ArrayData: PArrayTypeData;\n\n    procedure ProcessDim(dim: Byte; const o: ISuperObject);\n    var\n      dt: PTypeData;\n      i: Integer;\n      o2: ISuperObject;\n      v: TValue;\n    begin\n      if ArrayData.Dims[dim-1] = nil then Exit;\n      dt := GetTypeData(ArrayData.Dims[dim-1]^);\n      if Dim = ArrayData.DimCount then\n        for i := dt.MinValue to dt.MaxValue do\n        begin\n          v := Value.GetArrayElement(idx);\n          o.AsArray.Add(toJSon(v, index));\n          inc(idx);\n        end\n      else\n        for i := dt.MinValue to dt.MaxValue do\n        begin\n          o2 := TSuperObject.Create(stArray);\n          o.AsArray.Add(o2);\n          ProcessDim(dim + 1, o2);\n        end;\n    end;\n  var\n    i: Integer;\n    v: TValue;\n  begin\n    Result := TSuperObject.Create(stArray);\n    ArrayData := @Value.TypeData.ArrayData;\n    idx := 0;\n    if ArrayData.DimCount = 1 then\n      for i := 0 to ArrayData.ElCount - 1 do\n      begin\n        v := Value.GetArrayElement(i);\n        Result.AsArray.Add(toJSon(v, index))\n      end\n    else\n      ProcessDim(1, Result);\n  end;\n\n  procedure ToDynArray;\n  var\n    i: Integer;\n    v: TValue;\n  begin\n    Result := TSuperObject.Create(stArray);\n    for i := 0 to Value.GetArrayLength - 1 do\n    begin\n      v := Value.GetArrayElement(i);\n      Result.AsArray.Add(toJSon(v, index));\n    end;\n  end;\n\n  procedure ToClassRef;\n  begin\n    if TValueData(Value).FAsClass <> nil then\n      Result :=  TSuperObject.Create(string(\n        TValueData(Value).FAsClass.UnitName + '.' +\n        TValueData(Value).FAsClass.ClassName)) else\n      Result := nil;\n  end;\n\n  procedure ToInterface;\n  begin\n    if TValueData(Value).FHeapData <> nil then\n      TValueData(Value).FHeapData.QueryInterface(ISuperObject, Result) else\n      Result := nil;\n  end;\n\nvar\n  Serial: TSerialToJson;\nbegin\n  if not SerialToJson.TryGetValue(value.TypeInfo, Serial) then\n    case Value.Kind of\n      tkInt64: ToInt64;\n      tkChar: ToChar;\n      tkSet, tkInteger, tkEnumeration: ToInteger;\n      tkFloat: ToFloat;\n      tkString, tkLString, tkUString, tkWString: ToString;\n      tkClass: ToClass;\n      tkWChar: ToWChar;\n      tkVariant: ToVariant;\n      tkRecord: ToRecord;\n      tkArray: ToArray;\n      tkDynArray: ToDynArray;\n      tkClassRef: ToClassRef;\n      tkInterface: ToInterface;\n    else\n      result := nil;\n    end else\n      Result := Serial(Self, value, index);\nend;\n\n{ TSuperObjectHelper }\n\nconstructor TSuperObjectHelper.FromJson(const obj: ISuperObject; ctx: TSuperRttiContext = nil);\nvar\n  v: TValue;\n  ctxowned: Boolean;\nbegin\n  if ctx = nil then\n  begin\n    ctx := TSuperRttiContext.Create;\n    ctxowned := True;\n  end else\n    ctxowned := False;\n  try\n    v := Self;\n    if not ctx.FromJson(v.TypeInfo, obj, v) then\n      raise Exception.Create('Invalid object');\n  finally\n    if ctxowned then\n      ctx.Free;\n  end;\nend;\n\nconstructor TSuperObjectHelper.FromJson(const str: string; ctx: TSuperRttiContext = nil);\nbegin\n  FromJson(SO(str), ctx);\nend;\n\nfunction TSuperObjectHelper.ToJson(ctx: TSuperRttiContext = nil): ISuperObject;\nvar\n  v: TValue;\n  ctxowned: boolean;\nbegin\n  if ctx = nil then\n  begin\n    ctx := TSuperRttiContext.Create;\n    ctxowned := True;\n  end else\n    ctxowned := False;\n  try\n    v := Self;\n    Result := ctx.ToJson(v, SO);\n  finally\n    if ctxowned then\n      ctx.Free;\n  end;\nend;\n\n{$ENDIF}\n\n{$IFDEF DEBUG}\ninitialization\n\nfinalization\n  Assert(debugcount = 0, 'Memory leak');\n{$ENDIF}\nend.\n\n"
  },
  {
    "path": "lib/xedit/lz4/lz4.pas",
    "content": "(*\n  LZ4Delphi\n  Copyright (C) 2015, Jose Pascoa (atelierwebgm@gmail.com)\n  BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php)\n\n  *************************************************************************\n  LZ4 - Fast LZ compression algorithm\n  xxHash - Fast Hash algorithm\n  LZ4 source repository : http://code.google.com/p/lz4/\n  xxHash source repository : http://code.google.com/p/xxhash/\n  Copyright (c) 2011-2014, Yann Collet\n  BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php)\n\n  \n  Redistribution and use in source and binary forms, with or without\n  modification, are permitted provided that the following conditions are\n  met:\n\n  * Redistributions of source code must retain the above copyright\n  notice, this list of conditions and the following disclaimer.\n  * Redistributions in binary form must reproduce the above\n  copyright notice, this list of conditions and the following disclaimer\n  in the documentation and/or other materials provided with the\n  distribution.\n\n  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n  \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n ******************************************************************************\n*)\nunit lz4;\n{$POINTERMATH ON}\n\ninterface\n\nuses Windows, lz4Common;\n\nconst\n    LZ4_VERSION_MAJOR = 1;\n    LZ4_VERSION_MINOR = 5;\n    LZ4_VERSION_RELEASE = 0;\n    LZ4_MEMORY_USAGE = 14;\n    LZ4_STREAMSIZE_U64 = (1 shl (LZ4_MEMORY_USAGE - 3)) + 4;\n    LZ4_STREAMSIZE = LZ4_STREAMSIZE_U64 * sizeof(int64);\n    LZ4_MAX_INPUT_SIZE = $7E000000;\n    LZ4_UNALIGNED_ACCESS = 1;\n    LZ4_STREAMDECODESIZE_U64 = 4;\n\ntype\n    PLZ4_stream_t = ^LZ4_stream_t;\n\n    LZ4_stream_t = record\n        table: array [0 .. LZ4_STREAMSIZE_U64 - 1] of int64;\n    end;\n\n    PLZ4_streamDecode_t = ^LZ4_streamDecode_t;\n\n    LZ4_streamDecode_t = record\n        table: array [0 .. LZ4_STREAMDECODESIZE_U64 - 1] of int64;\n    end;\n\nfunction LZ4_versionNumber: integer;\nfunction LZ4_compressBound(iSize: cardinal): cardinal;\nfunction LZ4_create(inputBuffer: pAnsiChar): pointer;\nfunction LZ4_createStream: PLZ4_stream_t;\nprocedure LZ4_freeStream(LZ4_streamPtr: PLZ4_stream_t);\nfunction LZ4_createStreamDecode: PLZ4_streamDecode_t;\nprocedure LZ4_freeStreamDecode(LZ4_stream: PLZ4_streamDecode_t);\nfunction LZ4_compress(source: pAnsiChar; dest: pAnsiChar; sourceSize: integer): integer;\nfunction LZ4_decompress_safe(source: pAnsiChar; dest: pAnsiChar; compressedSize: integer; maxDecompressedSize: integer): integer;\nfunction LZ4_compress_continue(LZ4_stream: pointer; const ASource: pointer; ADestination: pointer; AInputSize: integer): integer;\nfunction LZ4_saveDict(LZ4_streamPtr: PLZ4_stream_t; safeBuffer: pointer; dictSize: integer): integer;\nfunction LZ4_decompress_safe_continue(LZ4_streamDecode: PLZ4_streamDecode_t; source: pointer; dest: pointer; compressedSize: integer;\n  maxDecompressedSize: integer): integer;\nfunction LZ4_compress_limitedOutput(const source: pAnsiChar; dest: pAnsiChar; inputSize: integer; maxOutputSize: integer): integer;\nfunction LZ4_compress_withState(state: pointer; const source: pAnsiChar; dest: pAnsiChar; inputSize: integer): integer;\nfunction LZ4_compress_limitedOutput_withState(state: pointer; const source: pAnsiChar; dest: pAnsiChar; inputSize: integer;\n  maxOutputSize: integer): integer;\nfunction LZ4_compress_limitedOutput_continue(LZ4_stream: PLZ4_stream_t; const source: pAnsiChar; dest: pAnsiChar; inputSize: integer;\n  maxOutputSize: integer): integer;\nprocedure LZ4_resetStream(LZ4_stream: PLZ4_stream_t);\nfunction LZ4_loadDict(LZ4_dict: PLZ4_stream_t; dictionary: pAnsiChar; dictSize: integer): integer;\n// debug function\nfunction LZ4_compress_forceExtDict(LZ4_dict: PLZ4_stream_t; const source: pAnsiChar; dest: pAnsiChar; inputSize: integer): integer;\nfunction LZ4_decompress_fast(source: pAnsiChar; dest: pAnsiChar; originalSize: integer): integer;\nfunction LZ4_decompress_fast_withPrefix64k(source: pAnsiChar; dest: pAnsiChar; originalSize: integer): integer;\nfunction LZ4_decompress_fast_usingDict(source: pAnsiChar; dest: pAnsiChar; originalSize: integer; const dictStart: pAnsiChar;\n  dictSize: integer): integer;\nfunction LZ4_decompress_safe_withPrefix64k(source: pAnsiChar; dest: pAnsiChar; compressedSize: integer; maxOutputSize: integer): integer;\nfunction LZ4_decompress_safe_usingDict(const source: pAnsiChar; dest: pAnsiChar; compressedSize: integer; maxOutputSize: integer;\n  const dictStart: pAnsiChar; dictSize: integer): integer;\nfunction LZ4_decompress_safe_partial(const source: pAnsiChar; dest: pAnsiChar; compressedSize: integer; targetOutputSize: integer;\n  maxDecompressedSize: integer): integer;\nfunction LZ4_decompress_safe_forceExtDict(source: pAnsiChar; dest: pAnsiChar; compressedSize: integer; maxOutputSize: integer;\n  const dictStart: pAnsiChar; dictSize: integer): integer;\n\n// replaced with move(source^, dest^, count)\n// procedure memmove(dest, source: pointer; count: integer); cdecl; external 'msvcrt.dll' name 'memmove';\n\nimplementation\n\nconst\n    LZ4_HASHLOG = LZ4_MEMORY_USAGE - 2;\n    HASHTABLESIZE = 1 shl LZ4_MEMORY_USAGE;\n    HASH_SIZE_U32 = 1 shl LZ4_HASHLOG;\n\ntype\n    limitedOutput_directive = (notLimited = 0, limitedOutput = 1);\n    tableType_t = (byPtr, byU32, byU16);\n    dict_directive = (noDict = 0, withPrefix64k, usingExtDict);\n    dictIssue_directive = (noDictIssue = 0, dictSmall);\n    endCondition_directive = (endOnOutputSize = 0, endOnInputSize = 1);\n    earlyEnd_directive = (full = 0, partial = 1);\n\n    PLZ4_stream_t_internal = ^LZ4_stream_t_internal;\n\n    LZ4_stream_t_internal = record\n        hashTable: array [0 .. HASH_SIZE_U32 - 1] of cardinal;\n        currentOffset: cardinal;\n        initCheck: cardinal;\n        dictionary: pByte;\n        bufferStart: pByte;\n        dictSize: cardinal;\n    end;\n\n    PLZ4_streamDecode_t_internal = ^LZ4_streamDecode_t_internal;\n\n    LZ4_streamDecode_t_internal = record\n        externalDict: pByte;\n        extDictSize: size_t;\n        prefixEnd: pByte;\n        prefixSize: size_t;\n    end;\n\nvar\n    LZ4_64Klimit: integer = 65536 + _MFLIMIT - 1;\n    LZ4_skipTrigger: cardinal = 6;\n    LZ4_minLength: integer = (_MFLIMIT + 1);\n\nfunction LZ4_versionNumber: integer;\nbegin\n    result := LZ4_VERSION_MAJOR * 100 * 100 + LZ4_VERSION_MINOR * 100 + LZ4_VERSION_RELEASE;\nend;\n\nfunction LZ4_compressBound(iSize: cardinal): cardinal;\nbegin\n    if (iSize) > cardinal(LZ4_MAX_INPUT_SIZE) then\n        result := 0\n    else\n        result := iSize + (iSize div 255 + 16)\nend;\n\nprocedure LZ4_copy8(const dstPtr: pointer; const srcPtr: pointer); inline;\nbegin\n{$IFDEF WIN64}\n    pUint64(dstPtr)^ := pUint64(srcPtr)^;\n{$ELSE}\n    pCardinal(dstPtr)[0] := pCardinal(srcPtr)[0];\n    pCardinal(dstPtr)[1] := pCardinal(srcPtr)[1];\n{$ENDIF}\nend;\n\nfunction LZ4_hashSequence(sequence: cardinal; tableType: tableType_t): cardinal; inline;\nconst\n    SHL1 = (MINMATCH * 8) - (LZ4_HASHLOG + 1);\n    SHL2 = ((MINMATCH * 8) - LZ4_HASHLOG);\nbegin\n    if (tableType = byU16) then\n        result := (sequence * 2654435761) shr SHL1\n    else\n        result := (sequence * 2654435761) shr SHL2;\nend;\n\nfunction LZ4_hashPosition(const p: pByte; tableType: tableType_t): cardinal; inline;\nbegin\n    result := LZ4_hashSequence(pCardinal(p)^, tableType);\nend;\n\nprocedure LZ4_putPositionOnHash(const p: pByte; h: cardinal; tableBase: pointer; tableType: tableType_t; const srcBase: pByte); inline;\nbegin\n    case tableType of\n        byPtr: ppByte(tableBase)[h] := p;\n        byU32: pCardinal(tableBase)[h] := cardinal(p - srcBase);\n        byU16: pWord(tableBase)[h] := word(p - srcBase);\n    end;\nend;\n\nfunction LZ4_getPositionOnHash(h: cardinal; tableBase: pointer; tableType: tableType_t; const srcBase: pByte): pByte; inline;\nbegin\n    if (tableType = byPtr) then\n        result := ppByte(tableBase)[h]\n    else if (tableType = byU32) then\n        result := pCardinal(tableBase)[h] + srcBase\n    else\n        result := pWord(tableBase)[h] + srcBase;\nend;\n\nfunction LZ4_getPosition(const p: pByte; tableBase: pointer; tableType: tableType_t; const srcBase: pByte): pByte; inline;\nvar\n    h: cardinal;\nbegin\n    h := LZ4_hashPosition(p, tableType);\n    result := LZ4_getPositionOnHash(h, tableBase, tableType, srcBase);\nend;\n\nprocedure LZ4_putPosition(const p: pByte; tableBase: pointer; tableType: tableType_t; const srcBase: pByte); inline;\nvar\n    h: cardinal;\nbegin\n    h := LZ4_hashPosition(p, tableType);\n    LZ4_putPositionOnHash(p, h, tableBase, tableType, srcBase);\nend;\n\nfunction LZ4_compress_generic(ctx: pointer; const source: pointer; dest: pointer; inputSize: integer; maxOutputSize: integer;\n  outputLimited: limitedOutput_directive; tableType: tableType_t; dict: dict_directive; dictIssue: dictIssue_directive): integer; inline;\nvar\n    lowRefLimit: pByte;\n    match: pByte;\n    refDelta: size_t;\n    ip: pByte;\n\n    dictPtr: PLZ4_stream_t_internal;\n    base: pByte;\n    lowLimit: pByte;\n    dictionary: pByte;\n    dictEnd: pByte;\n    dictDelta: size_t;\n    anchor: pByte;\n    iend: pByte;\n    mflimit: pByte;\n    matchlimit: pByte;\n    op: pByte;\n    olimit: pByte;\n    forwardH: cardinal;\n    lastRun: integer;\n    token: pByte;\n    forwardIp: pByte;\n    step: cardinal;\n    searchMatchNb: cardinal;\n    h: cardinal;\n    litLength: cardinal;\n    len: integer;\n    matchLength: cardinal;\n    limit: pByte;\n    more: cardinal;\n    booleanValue: boolean;\nlabel\n    _last_literals, _next_match;\nbegin\n    match := nil;\n    dictPtr := ctx;\n    ip := pByte(source);\n    lowRefLimit := ip - dictPtr.dictSize;\n    dictionary := dictPtr.dictionary;\n    dictEnd := dictionary + dictPtr.dictSize;\n    dictDelta := dictEnd - pByte(source);\n    anchor := pByte(source);\n    iend := ip + inputSize;\n    mflimit := iend - _MFLIMIT;\n    matchlimit := iend - LASTLITERALS;\n\n    op := pByte(dest);\n    olimit := op + maxOutputSize;\n    refDelta := 0;\n\n    if cardinal(inputSize) > cardinal(LZ4_MAX_INPUT_SIZE) then\n        exit(0);\n\n    case dict of\n        withPrefix64k:\n            begin\n                base := pByte(source) - dictPtr.currentOffset;\n                lowLimit := pByte(source) - dictPtr.dictSize;\n            end;\n        usingExtDict:\n            begin\n                base := pByte(source) - dictPtr.currentOffset;\n                lowLimit := pByte(source);\n            end;\n    else\n        begin\n            base := pByte(source);\n            lowLimit := pByte(source);\n        end;\n    end;\n\n    if ((tableType = byU16) and (inputSize >= LZ4_64Klimit)) then\n        exit(0);\n    if (inputSize < LZ4_minLength) then\n        goto _last_literals;\n\n    LZ4_putPosition(ip, ctx, tableType, base);\n    inc(ip);\n    forwardH := LZ4_hashPosition(ip, tableType);\n\n    while true do\n    begin\n        forwardIp := ip;\n        step := 1;\n        searchMatchNb := (1 shl LZ4_skipTrigger);\n        while true do\n        begin\n            h := forwardH;\n            ip := forwardIp;\n            inc(forwardIp, step);\n            step := searchMatchNb shr LZ4_skipTrigger;\n            inc(searchMatchNb);\n\n            if forwardIp > mflimit then\n                goto _last_literals;\n\n            match := LZ4_getPositionOnHash(h, ctx, tableType, base);\n            if (dict = usingExtDict) then\n            begin\n                if match < pByte(source) then\n                begin\n                    refDelta := dictDelta;\n                    lowLimit := dictionary;\n                end\n                else\n                begin\n                    refDelta := 0;\n                    lowLimit := pByte(source);\n                end;\n            end;\n            forwardH := LZ4_hashPosition(forwardIp, tableType);\n            LZ4_putPositionOnHash(ip, h, ctx, tableType, base);\n            if (dictIssue = dictSmall) and (match < lowRefLimit) then\n                continue;\n            if not(tableType = byU16) and (match + MAX_DISTANCE < ip) then\n                continue;\n            if (pCardinal(match + refDelta)^ <> pCardinal(ip)^) then\n                continue;\n            break;\n        end;\n\n        while (ip > anchor) and (match + refDelta > lowLimit) and (ip[-1] = match[refDelta - 1]) do\n        begin\n            dec(ip);\n            dec(match);\n        end;\n        litLength := cardinal(ip - anchor);\n        token := op;\n        inc(op);\n        if (outputLimited <> notLimited) and (op + litLength + (2 + 1 + LASTLITERALS) + (litLength div 255) > olimit) then\n            exit(0);\n        if (litLength >= RUN_MASK) then\n        begin\n            len := integer(litLength - RUN_MASK);\n            token^ := (RUN_MASK shl ML_BITS);\n            while len >= 255 do\n            begin\n                op^ := 255;\n                inc(op);\n                dec(len, 255);\n            end;\n            op^ := BYTE(len);\n            inc(op);\n        end\n        else\n            token^ := BYTE(litLength shl ML_BITS);\n        LZ4_wildCopy(op, anchor, op + litLength);\n        inc(op, litLength);\n    _next_match:\n        pWord(op)^ := word(ip - match);\n        inc(op, 2);\n\n        if (dict = usingExtDict) and (lowLimit = dictionary) then\n        begin\n            inc(match, refDelta);\n            limit := ip + (dictEnd - match);\n            if (limit > matchlimit) then\n                limit := matchlimit;\n            matchLength := LZ4_count(ip + MINMATCH, match + MINMATCH, limit);\n            inc(ip, MINMATCH + matchLength);\n            if (ip = limit) then\n            begin\n                more := LZ4_count(ip, pByte(source), matchlimit);\n                inc(matchLength, more);\n                inc(ip, more);\n            end;\n        end\n        else\n        begin\n            matchLength := LZ4_count(ip + MINMATCH, match + MINMATCH, matchlimit);\n            inc(ip, MINMATCH + matchLength);\n        end;\n        if (outputLimited <> notLimited) and (op + (1 + LASTLITERALS) + (matchLength shr 8) > olimit) then\n            exit(0);\n        if (matchLength >= ML_MASK) then\n        begin\n            inc(token^, ML_MASK);\n            dec(matchLength, ML_MASK);\n            while matchLength >= 510 do\n            begin\n                pWord(op)^ := $FFFF;\n                inc(op, 2);\n                // op^ := 255;\n                // inc(op);\n                // op^ := 255;\n                // inc(op);\n                dec(matchLength, 510);\n            end;\n            if (matchLength >= 255) then\n            begin\n                dec(matchLength, 255);\n                op^ := 255;\n                inc(op);\n            end;\n            op^ := BYTE(matchLength);\n            inc(op);\n        end\n        else\n            inc(token^, BYTE(matchLength));\n\n        anchor := ip;\n        if (ip > mflimit) then\n            break;\n        LZ4_putPosition(ip - 2, ctx, tableType, base);\n        match := LZ4_getPosition(ip, ctx, tableType, base);\n        if (dict = usingExtDict) then\n        begin\n            if match < pByte(source) then\n            begin\n                refDelta := dictDelta;\n                lowLimit := dictionary;\n            end\n            else\n            begin\n                refDelta := 0;\n                lowLimit := pByte(source);\n            end;\n        end;\n        LZ4_putPosition(ip, ctx, tableType, base);\n\n        if dictIssue = dictSmall then\n            booleanValue := match >= lowRefLimit\n        else\n            booleanValue := true;\n        if (booleanValue and (match + MAX_DISTANCE >= ip)\n          and (pCardinal(match + refDelta)^ = pCardinal(ip)^)) then\n        begin\n            token := op;\n            inc(op);\n            token^ := 0;\n            goto _next_match;\n        end;\n        inc(ip);\n        forwardH := LZ4_hashPosition(ip, tableType);\n    end;\n\n_last_literals:\n    lastRun := integer(iend - anchor);\n    if (outputLimited <> notLimited) and ((op - pByte(dest)) + lastRun + 1 + ((lastRun + 255 - RUN_MASK) div 255) >\n      maxOutputSize)\n    then\n        exit(0);\n    if lastRun >= integer(RUN_MASK) then\n    begin\n        op^ := (RUN_MASK shl ML_BITS);\n        inc(op);\n        dec(lastRun, RUN_MASK);\n        while lastRun >= 255 do\n        begin\n            op^ := 255;\n            inc(op);\n            dec(lastRun, 255);\n        end;\n        op^ := BYTE(lastRun);\n        inc(op);\n    end\n    else\n    begin\n        op^ := BYTE(lastRun shl ML_BITS);\n        inc(op);\n    end;\n    move(anchor^, op^, iend - anchor);\n    inc(op, iend - anchor);\n\n    result := integer(op - pByte(dest));\nend;\n\nfunction LZ4_compress(source: pAnsiChar; dest: pAnsiChar; sourceSize: integer): integer;\nvar\n    ctx: array [0 .. LZ4_STREAMSIZE_U64 - 1] of uint64;\nbegin\n    fillchar(ctx, sizeof(ctx), 0);\n    if sourceSize < LZ4_64Klimit then\n        result := LZ4_compress_generic(@ctx, source, dest, sourceSize, 0, notLimited, byU16, noDict, noDictIssue)\n    else\n    begin\n{$IFDEF WIN64}\n        result := LZ4_compress_generic(@ctx, source, dest, sourceSize, 0, notLimited, byU32, noDict,\n          noDictIssue)\n{$ELSE}\n        result := LZ4_compress_generic(@ctx, source, dest, sourceSize, 0, notLimited, byPtr, noDict, noDictIssue);\n{$ENDIF}\n    end;\nend;\n\nfunction LZ4_decompress_generic(const source: pointer; const dest: pointer; inputSize: integer; outputSize: integer;\n  endOnInput: integer; partialDecoding: integer; targetOutputSize: integer; dict: integer;\n  const lowPrefix: pByte; const dictStart: pByte; const dictSize: size_t): integer; inline;\nvar\n    ip: pByte;\n    iend: pByte;\n    op: pByte;\n    oend: pByte;\n    cpy: pByte;\n    oexit: pByte;\n    lowLimit: pByte;\n    dictEnd: pByte;\n    safeDecode: boolean;\n    checkOffset: boolean;\n    token: cardinal;\n    length: size_t;\n    match: pByte;\n    s: cardinal;\n    booleantest: boolean;\n    copySize: size_t;\n    endOfMatch: pByte;\n    copyFrom: pByte;\n    dec64: size_t;\nconst\n    dec32table: array [0 .. 7] of size_t = (4, 1, 2, 1, 4, 4, 4, 4);\n    dec64table: array [0 .. 7] of size_t = (0, 0, 0, size_t(-1), 0, 1, 2, 3);\nlabel\n    _output_error;\nbegin\n    ip := pByte(source);\n    iend := ip + inputSize;\n    op := pByte(dest);\n    oend := op + outputSize;\n    oexit := op + targetOutputSize;\n    lowLimit := lowPrefix - dictSize;\n    dictEnd := pByte(dictStart) + dictSize;\n    safeDecode := (endOnInput = integer(endOnInputSize));\n    checkOffset := ((safeDecode) and (dictSize < 65536));\n\n    if (partialDecoding <> 0) and (oexit > oend - _MFLIMIT) then\n        oexit := oend - _MFLIMIT;\n    if (endOnInput <> 0) and (outputSize = 0) then\n    begin\n        if (inputSize = 1) and (ip^ = 0) then\n            exit(0)\n        else\n            exit(-1);\n    end;\n    if (endOnInput = 0) and (outputSize = 0) then\n    begin\n        if ip^ = 0 then\n            exit(1)\n        else\n            exit(-1);\n    end;\n\n    while true do\n    begin\n        token := ip^;\n        inc(ip);\n        length := token shr ML_BITS;\n        if length = RUN_MASK then\n        begin\n            while true do\n            begin\n                s := ip^;\n                inc(ip);\n                inc(length, s);\n                if endOnInput <> 0 then\n                begin\n                    if not(ip < iend - RUN_MASK) then\n                        break;\n                end;\n                if s <> 255 then\n                    break;\n            end;\n            if safeDecode and (size_t(op + length) < size_t(op)) then\n                goto _output_error;\n            if safeDecode and (size_t(ip + length) < size_t(ip)) then\n                goto _output_error;\n        end;\n        cpy := op + length;\n        if partialDecoding <> 0 then\n            booleantest := cpy > oexit\n        else\n            booleantest := cpy > oend - _MFLIMIT;\n\n        if ((endOnInput <> 0) and ((booleantest) or (ip + length > iend - (2 + 1 + LASTLITERALS))))\n          or ((endOnInput = 0) and (cpy > oend - COPYLENGTH)) then\n        begin\n            if partialDecoding <> 0 then\n            begin\n                if (cpy > oend) then\n                    goto _output_error;\n                if ((endOnInput <> 0) and (ip + length > iend)) then\n                    goto _output_error;\n            end\n            else\n            begin\n                if ((endOnInput = 0) and (cpy <> oend)) then\n                    goto _output_error;\n                if ((endOnInput <> 0) and ((ip + length <> iend) or (cpy > oend))) then\n                    goto _output_error;\n            end;\n            move(ip^, op^, length);\n            inc(ip, length);\n            inc(op, length);\n            break;\n        end;\n        LZ4_wildCopy(op, ip, cpy);\n        inc(ip, length);\n        op := cpy;\n        match := cpy - LZ4_read16(ip); // LZ4_readLE16 = LZ4_read16 for unaligned\n        inc(ip, 2);\n\n        if checkOffset and (match < lowLimit) then\n            goto _output_error;\n\n        length := token and ML_MASK;\n        if length = ML_MASK then\n        begin\n            while true do\n            begin\n                if ((endOnInput <> 0) and (ip > iend - LASTLITERALS)) then\n                    goto _output_error;\n                s := ip^;\n                inc(ip);\n                inc(length, s);\n                if s <> 255 then\n                    break;\n            end;\n            if safeDecode and (size_t(op + length) < size_t(op)) then\n                goto _output_error;\n        end;\n        inc(length, MINMATCH);\n        if (dict = integer(usingExtDict)) and (match < lowPrefix) then\n        begin\n            if op + length > oend - LASTLITERALS then\n                goto _output_error;\n            if (length <= size_t(lowPrefix - match)) then\n            begin\n                match := dictEnd - (lowPrefix - match);\n                move(match^, op^, length);\n                inc(op, length);\n            end\n            else\n            begin\n                copySize := size_t(lowPrefix - match);\n                move((dictEnd - copySize)^, op^, copySize);\n                inc(op, copySize);\n                copySize := length - copySize;\n                if copySize > size_t(op - lowPrefix) then\n                begin\n                    endOfMatch := op + copySize;\n                    copyFrom := lowPrefix;\n                    while (op < endOfMatch) do\n                    begin\n                        op^ := copyFrom^;\n                        inc(op);\n                        inc(copyFrom);\n                    end;\n                end\n                else\n                begin\n                    move(lowPrefix^, op^, copySize);\n                    inc(op, copySize);\n                end;\n            end;\n            continue;\n        end;\n        cpy := op + length;\n        if (op - match) < 8 then\n        begin\n            dec64 := dec64table[op - match];\n            op[0] := match[0];\n            op[1] := match[1];\n            op[2] := match[2];\n            op[3] := match[3];\n            inc(match, dec32table[op - match]);\n            pCardinal(op + 4)^ := pCardinal(match)^;\n            inc(op, 8);\n            dec(match, dec64);\n        end\n        else\n        begin\n{$IFDEF WIN64}\n            pUint64(op)^ := pUint64(match)^;\n{$ELSE}\n            pCardinal(op)[0] := pCardinal(match)[0];\n            pCardinal(op)[1] := pCardinal(match)[1];\n{$ENDIF}\n            inc(op, 8);\n            inc(match, 8);\n        end;\n\n        if cpy > oend - 12 then\n        begin\n            if (cpy > oend - LASTLITERALS) then\n                goto _output_error;\n            if (op < oend - 8) then\n            begin\n                LZ4_wildCopy(op, match, oend - 8);\n                inc(match, (oend - 8) - op);\n                op := oend - 8;\n            end;\n            while (op < cpy) do\n            begin\n                op^ := match^;\n                inc(op);\n                inc(match);\n            end;\n        end\n        else\n            LZ4_wildCopy(op, match, cpy);\n        op := cpy;\n    end;\n    if (endOnInput <> 0) then\n        result := integer(op - pByte(dest))\n    else\n        result := integer(ip - pByte(source));\n    exit;\n_output_error:\n    result := -(ip - pByte(source)) - 1;\nend;\n\nfunction LZ4_decompress_safe(source: pAnsiChar; dest: pAnsiChar; compressedSize: integer; maxDecompressedSize: integer): integer;\nbegin\n    result := LZ4_decompress_generic(source, dest, compressedSize, maxDecompressedSize, integer(endOnInputSize), integer(full), 0,\n      integer(noDict), pByte(dest), nil, 0);\nend;\n\nfunction LZ4_createStream: PLZ4_stream_t;\nbegin\n    result := allocmem(8 * LZ4_STREAMSIZE_U64);\nend;\n\nprocedure LZ4_freeStream(LZ4_streamPtr: PLZ4_stream_t);\nbegin\n    freemem(LZ4_streamPtr);\nend;\n\nfunction LZ4_createStreamDecode: PLZ4_streamDecode_t;\nbegin\n    result := allocmem(sizeof(uint64) * LZ4_STREAMDECODESIZE_U64);\nend;\n\nprocedure LZ4_freeStreamDecode(LZ4_stream: PLZ4_streamDecode_t);\nbegin\n    freemem(LZ4_stream);\nend;\n\nprocedure LZ4_renormDictT(LZ4_dict: PLZ4_stream_t_internal; src: pByte);\nvar\n    delta: cardinal;\n    dictEnd: pByte;\n    i: integer;\nbegin\n    if (LZ4_dict.currentOffset > $80000000) or\n      (size_t(LZ4_dict.currentOffset) > size_t(src)) then\n    begin\n        delta := LZ4_dict.currentOffset - 65536;\n        dictEnd := LZ4_dict.dictionary + LZ4_dict.dictSize;\n        for i := 0 to HASH_SIZE_U32 - 1 do\n        begin\n            if (LZ4_dict.hashTable[i] < delta) then\n                LZ4_dict.hashTable[i] := 0\n            else\n                dec(LZ4_dict.hashTable[i], delta);\n        end;\n        LZ4_dict.currentOffset := 65536;\n        if (LZ4_dict.dictSize > 65536) then\n            LZ4_dict.dictSize := 65536;\n        LZ4_dict.dictionary := dictEnd - LZ4_dict.dictSize;\n    end;\nend;\n\nfunction LZ4_compress_continue_generic(LZ4_stream: pointer; source: pointer; dest: pointer; inputSize: integer; maxOutputSize: integer;\n  limit: limitedOutput_directive): integer; inline;\nvar\n    streamPtr: PLZ4_stream_t_internal;\n    dictEnd: pByte;\n    smallest: pByte;\n    sourceEnd: pByte;\n    res: integer;\nbegin\n    streamPtr := PLZ4_stream_t_internal(LZ4_stream);\n    dictEnd := streamPtr.dictionary + streamPtr.dictSize;\n    smallest := pByte(source);\n    if (streamPtr.initCheck <> 0) then\n        exit(0);\n    if (streamPtr.dictSize > 0) and (smallest > dictEnd) then\n        smallest := dictEnd;\n    LZ4_renormDictT(streamPtr, smallest);\n    sourceEnd := pByte(source) + inputSize;\n    if (sourceEnd > streamPtr.dictionary) and (sourceEnd < dictEnd) then\n    begin\n        streamPtr.dictSize := cardinal(dictEnd - sourceEnd);\n        if (streamPtr.dictSize > 65536) then\n            streamPtr.dictSize := 65536;\n        if (streamPtr.dictSize < 4) then\n            streamPtr.dictSize := 0;\n        streamPtr.dictionary := dictEnd - streamPtr.dictSize;\n    end;\n    if dictEnd = pByte(source) then\n    begin\n        if (streamPtr.dictSize < 65536) and (streamPtr.dictSize < streamPtr.currentOffset) then\n            res := LZ4_compress_generic(LZ4_stream, source, dest, inputSize, maxOutputSize, limit, byU32, withPrefix64k, dictSmall)\n        else\n            res := LZ4_compress_generic(LZ4_stream, source, dest, inputSize, maxOutputSize, limit, byU32, withPrefix64k, noDictIssue);\n        inc(streamPtr.dictSize, cardinal(inputSize));\n        inc(streamPtr.currentOffset, cardinal(inputSize));\n        exit(res);\n    end;\n    if (streamPtr.dictSize < 65536) and (streamPtr.dictSize < streamPtr.currentOffset) then\n        res := LZ4_compress_generic(LZ4_stream, source, dest, inputSize, maxOutputSize, limit, byU32, usingExtDict, dictSmall)\n    else\n        res := LZ4_compress_generic(LZ4_stream, source, dest, inputSize, maxOutputSize, limit, byU32, usingExtDict, noDictIssue);\n    streamPtr.dictionary := pByte(source);\n    streamPtr.dictSize := cardinal(inputSize);\n    inc(streamPtr.currentOffset, cardinal(inputSize));\n    result := res;\nend;\n\nfunction LZ4_compress_continue(LZ4_stream: pointer; const ASource: pointer; ADestination: pointer; AInputSize: integer): integer;\nbegin\n    result := LZ4_compress_continue_generic(LZ4_stream, ASource, ADestination, AInputSize, 0, notLimited);\nend;\n\nfunction LZ4_saveDict(LZ4_streamPtr: PLZ4_stream_t; safeBuffer: pointer; dictSize: integer): integer;\nvar\n    dict: PLZ4_stream_t_internal;\n    previousDictEnd: pByte;\nbegin\n    dict := PLZ4_stream_t_internal(LZ4_streamPtr);\n    previousDictEnd := dict.dictionary + dict.dictSize;\n    if cardinal(dictSize) > 65536 then\n        dictSize := 65536;\n    if cardinal(dictSize) > dict.dictSize then\n        dictSize := dict.dictSize;\n    move((previousDictEnd - dictSize)^, safeBuffer^, dictSize);\n    // memmove(safeBuffer, (previousDictEnd - dictSize), dictSize);\n    dict.dictionary := pByte(safeBuffer);\n    dict.dictSize := cardinal(dictSize);\n    result := dictSize;\nend;\n\nfunction LZ4_decompress_safe_continue(LZ4_streamDecode: PLZ4_streamDecode_t; source: pointer; dest: pointer; compressedSize: integer;\n  maxDecompressedSize: integer): integer;\nvar\n    lz4sd: PLZ4_streamDecode_t_internal;\n    res: integer;\nbegin\n    lz4sd := PLZ4_streamDecode_t_internal(LZ4_streamDecode);\n    if lz4sd.prefixEnd = pByte(dest) then\n    begin\n        res := LZ4_decompress_generic(source, dest, compressedSize, maxDecompressedSize,\n          integer(endOnInputSize), integer(full), 0,\n          integer(usingExtDict), lz4sd.prefixEnd - lz4sd.prefixSize, lz4sd.externalDict, lz4sd.extDictSize);\n        if (res <= 0) then\n            exit(res);\n        inc(lz4sd.prefixSize, res);\n        inc(lz4sd.prefixEnd, res);\n    end\n    else\n    begin\n        lz4sd.extDictSize := lz4sd.prefixSize;\n        lz4sd.externalDict := lz4sd.prefixEnd - lz4sd.extDictSize;\n        res := LZ4_decompress_generic(source, dest, compressedSize, maxDecompressedSize,\n          integer(endOnInputSize), integer(full), 0,\n          integer(usingExtDict), pByte(dest), lz4sd.externalDict, lz4sd.extDictSize);\n        if (res <= 0) then\n            exit(res);\n        lz4sd.prefixSize := res;\n        lz4sd.prefixEnd := pByte(dest) + res;\n    end;\n    result := res;\nend;\n\nprocedure LZ4_init(lz4ds: PLZ4_stream_t_internal; base: pByte);\nbegin\n    fillchar(lz4ds^, LZ4_STREAMSIZE, 0);\n    lz4ds.bufferStart := base;\nend;\n\nfunction LZ4_create(inputBuffer: pAnsiChar): pointer;\nvar\n    lz4ds: pointer;\nbegin\n    lz4ds := allocmem(8 * LZ4_STREAMSIZE_U64);\n    LZ4_init(PLZ4_stream_t_internal(lz4ds), pByte(inputBuffer));\n    result := lz4ds;\nend;\n\nfunction LZ4_compress_limitedOutput(const source: pAnsiChar; dest: pAnsiChar; inputSize: integer; maxOutputSize: integer): integer;\nvar\n    ctx: array [0 .. LZ4_STREAMSIZE_U64 - 1] of uint64;\nbegin\n    fillchar(ctx, sizeof(ctx), 0);\n    if inputSize < LZ4_64Klimit then\n        result := LZ4_compress_generic(@ctx, source, dest, inputSize, maxOutputSize, limitedOutput, byU16, noDict, noDictIssue)\n    else\n    begin\n{$IFDEF WIN64}\n        result := LZ4_compress_generic(@ctx, source, dest, inputSize, maxOutputSize, limitedOutput, byU32, noDict, noDictIssue);\n{$ELSE}\n        result := LZ4_compress_generic(@ctx, source, dest, inputSize, maxOutputSize, limitedOutput, byPtr, noDict, noDictIssue);\n{$ENDIF}\n    end;\nend;\n\nfunction LZ4_compress_withState(state: pointer; const source: pAnsiChar; dest: pAnsiChar; inputSize: integer): integer;\nbegin\n    if ((size_t(state) and 3) <> 0) then\n        exit(0); // Error : state is not aligned on 4-bytes boundary\n    fillchar(state^, LZ4_STREAMSIZE, 0);\n    if inputSize < LZ4_64Klimit then\n        result := LZ4_compress_generic(state, source, dest, inputSize, 0, notLimited, byU16, noDict, noDictIssue)\n    else\n    begin\n{$IFDEF WIN64}\n        result := LZ4_compress_generic(state, source, dest, inputSize, 0, notLimited, byU32, noDict, noDictIssue);\n{$ELSE}\n        result := LZ4_compress_generic(state, source, dest, inputSize, 0, notLimited, byPtr, noDict, noDictIssue);\n{$ENDIF}\n    end;\nend;\n\nfunction LZ4_compress_limitedOutput_withState(state: pointer; const source: pAnsiChar; dest: pAnsiChar; inputSize: integer;\n  maxOutputSize: integer): integer;\nbegin\n    if ((size_t(state) and 3) <> 0) then\n        exit(0); // Error : state is not aligned on 4-bytes boundary\n    fillchar(state^, LZ4_STREAMSIZE, 0);\n    if inputSize < LZ4_64Klimit then\n        result := LZ4_compress_generic(state, source, dest, inputSize, maxOutputSize, limitedOutput, byU16, noDict, noDictIssue)\n    else\n    begin\n{$IFDEF WIN64}\n        result := LZ4_compress_generic(state, source, dest, inputSize, maxOutputSize, limitedOutput, byU32, noDict, noDictIssue);\n{$ELSE}\n        result := LZ4_compress_generic(state, source, dest, inputSize, maxOutputSize, limitedOutput, byPtr, noDict, noDictIssue);\n{$ENDIF}\n    end;\nend;\n\nfunction LZ4_compress_limitedOutput_continue(LZ4_stream: PLZ4_stream_t; const source: pAnsiChar; dest: pAnsiChar; inputSize: integer;\n  maxOutputSize: integer): integer;\nbegin\n    result := LZ4_compress_continue_generic(LZ4_stream, source, dest, inputSize, maxOutputSize, limitedOutput);\nend;\n\nfunction LZ4_compress_forceExtDict(LZ4_dict: PLZ4_stream_t; const source: pAnsiChar; dest: pAnsiChar; inputSize: integer): integer;\nvar\n    streamPtr: PLZ4_stream_t_internal;\n    dictEnd: pByte;\n    smallest: pByte;\nbegin\n    streamPtr := PLZ4_stream_t_internal(LZ4_dict);\n    dictEnd := streamPtr.dictionary + streamPtr.dictSize;\n    smallest := dictEnd;\n    if smallest > pByte(source) then\n        smallest := pByte(source);\n    LZ4_renormDictT(PLZ4_stream_t_internal(LZ4_dict), smallest);\n    result := LZ4_compress_generic(LZ4_dict, source, dest, inputSize, 0, notLimited, byU32, usingExtDict, noDictIssue);\n    streamPtr.dictionary := pByte(source);\n    streamPtr.dictSize := cardinal(inputSize);\n    inc(streamPtr.currentOffset, cardinal(inputSize));\nend;\n\nprocedure LZ4_resetStream(LZ4_stream: PLZ4_stream_t);\nbegin\n    fillchar(LZ4_stream^, sizeof(LZ4_stream_t), 0);\nend;\n\nfunction LZ4_loadDict(LZ4_dict: PLZ4_stream_t; dictionary: pAnsiChar; dictSize: integer): integer;\nvar\n    dict: PLZ4_stream_t_internal;\n    p: pByte;\n    dictEnd: pByte;\n    base: pByte;\nbegin\n    dict := PLZ4_stream_t_internal(LZ4_dict);\n    p := pByte(dictionary);\n    dictEnd := p + dictSize;\n    if (dict.initCheck <> 0) then\n        LZ4_resetStream(LZ4_dict); // Uninitialized structure detected\n    if dictSize < MINMATCH then\n    begin\n        dict.dictionary := Nil;\n        dict.dictSize := 0;\n        exit(0);\n    end;\n    if (p <= dictEnd - 65536) then\n        p := dictEnd - 65536;\n    base := p - dict.currentOffset;\n    dict.dictionary := p;\n    dict.dictSize := cardinal(dictEnd - p);\n    inc(dict.currentOffset, dict.dictSize);\n    while (p <= dictEnd - MINMATCH) do\n    begin\n        LZ4_putPosition(p, dict, byU32, base);\n        inc(p, 3);\n    end;\n\n    result := dict.dictSize;\nend;\n\nfunction LZ4_decompress_fast(source: pAnsiChar; dest: pAnsiChar; originalSize: integer): integer;\nbegin\n    result := LZ4_decompress_generic(source, dest, 0, originalSize, integer(endOnOutputSize), integer(full), 0, integer(withPrefix64k),\n      pByte(dest - 65536), Nil, 65536);\nend;\n\nfunction LZ4_decompress_fast_withPrefix64k(source: pAnsiChar; dest: pAnsiChar; originalSize: integer): integer;\nbegin\n    result := LZ4_decompress_generic(source, dest, 0, originalSize, integer(endOnOutputSize), integer(full), 0, integer(withPrefix64k),\n      pByte(dest) - 65536, Nil, 65536);\nend;\n\nfunction LZ4_decompress_usingDict_generic(source: pAnsiChar; dest: pAnsiChar; compressedSize: integer; maxOutputSize: integer;\n  safe: integer; dictStart: pAnsiChar; dictSize: integer): integer; inline;\nbegin\n    if dictSize = 0 then\n        exit(LZ4_decompress_generic(source, dest, compressedSize, maxOutputSize, safe, integer(full), 0, integer(noDict),\n          pByte(dest), Nil, 0));\n    if (dictStart + dictSize = dest) then\n    begin\n        if dictSize >= integer(65536 - 1) then\n            exit(LZ4_decompress_generic(source, dest, compressedSize, maxOutputSize, safe, integer(full), 0, integer(withPrefix64k),\n              pByte(dest) - 65536, Nil, 0));\n        exit(LZ4_decompress_generic(source, dest, compressedSize, maxOutputSize, safe, integer(full), 0, integer(noDict),\n          pByte(dest) - dictSize, Nil, 0));\n    end;\n    result := LZ4_decompress_generic(source, dest, compressedSize, maxOutputSize, safe, integer(full), 0, integer(usingExtDict),\n      pByte(dest), pByte(dictStart), dictSize);\nend;\n\nfunction LZ4_decompress_fast_usingDict(source: pAnsiChar; dest: pAnsiChar; originalSize: integer; const dictStart: pAnsiChar;\n  dictSize: integer): integer;\nbegin\n    result := LZ4_decompress_usingDict_generic(source, dest, 0, originalSize, 0, dictStart, dictSize);\nend;\n\nfunction LZ4_decompress_safe_withPrefix64k(source: pAnsiChar; dest: pAnsiChar; compressedSize: integer; maxOutputSize: integer): integer;\nbegin\n    result := LZ4_decompress_generic(source, dest, compressedSize, maxOutputSize, integer(endOnInputSize), integer(full), 0,\n      integer(withPrefix64k), pByte(dest) - 65536, Nil, 65536);\nend;\n\nfunction LZ4_decompress_safe_usingDict(const source: pAnsiChar; dest: pAnsiChar; compressedSize: integer; maxOutputSize: integer;\n  const dictStart: pAnsiChar; dictSize: integer): integer;\nbegin\n    result := LZ4_decompress_usingDict_generic(source, dest, compressedSize, maxOutputSize, 1, dictStart, dictSize);\nend;\n\nfunction LZ4_decompress_safe_partial(const source: pAnsiChar; dest: pAnsiChar; compressedSize: integer; targetOutputSize: integer;\n  maxDecompressedSize: integer): integer;\nbegin\n    result := LZ4_decompress_generic(source, dest, compressedSize, maxDecompressedSize, integer(endOnInputSize), integer(partial),\n      targetOutputSize, integer(noDict), pByte(dest), Nil, 0);\nend;\n\nfunction LZ4_decompress_safe_forceExtDict(source: pAnsiChar; dest: pAnsiChar; compressedSize: integer; maxOutputSize: integer;\n  const dictStart: pAnsiChar; dictSize: integer): integer;\nbegin\n    result := LZ4_decompress_generic(source, dest, compressedSize, maxOutputSize, integer(endOnInputSize), integer(full), 0,\n      integer(usingExtDict), pByte(dest), pByte(dictStart), dictSize);\nend;\n\nend.\n"
  },
  {
    "path": "lib/xedit/lz4/lz4Common.pas",
    "content": "(*\n  LZ4Delphi\n  Copyright (C) 2015, Jose Pascoa (atelierwebgm@gmail.com)\n  BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php)\n\n  *************************************************************************\n  LZ4 - Fast LZ compression algorithm\n  xxHash - Fast Hash algorithm\n  LZ4 source repository : http://code.google.com/p/lz4/\n  xxHash source repository : http://code.google.com/p/xxhash/\n  Copyright (c) 2011-2014, Yann Collet\n  BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php)\n\n  Redistribution and use in source and binary forms, with or without\n  modification, are permitted provided that the following conditions are\n  met:\n\n  * Redistributions of source code must retain the above copyright\n  notice, this list of conditions and the following disclaimer.\n  * Redistributions in binary form must reproduce the above\n  copyright notice, this list of conditions and the following disclaimer\n  in the documentation and/or other materials provided with the\n  distribution.\n\n  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n  \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n ******************************************************************************\n*)\n\nunit lz4common;\n{$POINTERMATH ON}\n\ninterface\n\nuses Windows;\n\ntype\n    ppByte = ^pByte;\n    {$IFDEF WIN32}\n    size_t = Cardinal;\n    {$ENDIF WIN32}\n    {$IFDEF WIN64}\n    size_t = UInt64;\n    {$ENDIF WIN64}\n    psize_t = ^size_t;\n\nconst\n    MINMATCH = 4;\n    COPYLENGTH = 8;\n    LASTLITERALS = 5;\n    _MFLIMIT = COPYLENGTH + MINMATCH;\n    MAXD_LOG = 16;\n    MAX_DISTANCE = (1 shl MAXD_LOG) - 1;\n    STEPSIZE = sizeof(size_t);\n    ML_BITS = 4;\n    ML_MASK = (1 shl ML_BITS) - 1;\n    RUN_BITS = 8 - ML_BITS;\n    RUN_MASK = (1 shl RUN_BITS) - 1;\n\nfunction LZ4_read32(const memPtr: pointer): cardinal;\nfunction LZ4_read64(const memPtr: pointer): uint64; inline;\nfunction LZ4_count(pIn: pByte; pMatch: pByte; const pInLimit: pByte): cardinal;\nfunction LZ4_read_ARCH(const p: pointer): size_t; inline;\nfunction LZ4_read16(const memPtr: pointer): word; inline;\nprocedure LZ4_writeLE16(memPtr: pointer; value: word); inline;\nprocedure LZ4_wildCopy(dstPtr: pointer; const srcPtr: pointer; dstEnd: pointer);\n\nimplementation\n\nfunction LZ4_read32(const memPtr: pointer): cardinal;\nbegin\n    result := pCardinal(memPtr)^;\nend;\n\n{$IFDEF WIN64}\n\n\nfunction LZ4_NbCommonBytesx64(value: size_t): cardinal;\nasm\n    bsf rax, rcx // value comes in rcx register\n    shr eax, 3\nend;\n{$ENDIF}\n\n\nfunction LZ4_count(pIn: pByte; pMatch: pByte; const pInLimit: pByte): cardinal;\nvar\n    pStart: pByte;\n    diff: size_t;\n    incValue: cardinal;\n\n    calcedPByte: pByte;\nbegin\n    pStart := pIn;\n    calcedPByte := pInLimit - (STEPSIZE - 1);\n\n    while pIn < calcedPByte do\n    begin\n        diff := LZ4_read_ARCH(pMatch) xor LZ4_read_ARCH(pIn);\n        if (diff = 0) then\n        begin\n            inc(pIn, STEPSIZE);\n            inc(pMatch, STEPSIZE);\n            continue;\n        end;\n{$IFDEF WIN32}\n        asm\n            bsf eax, diff\n            shr eax, 3\n            mov incValue, eax\n        end;\n{$ELSE}\n        incValue := LZ4_NbCommonBytesx64(diff); // x64 mode does not allow asm inline\n{$ENDIF}\n        inc(pIn, incValue);\n        exit(cardinal(pIn - pStart));\n    end;\n{$IFDEF WIN64}\n    if (pIn < (pInLimit - 3)) and (pCardinal(pMatch)^ = pCardinal(pIn)^) then\n    begin\n        inc(pIn, 4);\n        inc(pMatch, 4);\n    end;\n{$ENDIF}\n    if ((pIn < (pInLimit - 1)) and (pWord(pMatch)^ = pWord(pIn)^)) then\n    begin\n        inc(pIn, 2);\n        inc(pMatch, 2);\n    end;\n    if ((pIn < pInLimit) and (pMatch^ = pIn^)) then\n        inc(pIn);\n    result := cardinal(pIn - pStart);\nend;\n\nfunction LZ4_read_ARCH(const p: pointer): size_t; inline;\nbegin\n{$IFDEF WIN64}\n    result := size_t(pUint64(p)^)\n{$ELSE}\n    result := size_t(pCardinal(p)^);\n{$ENDIF}\nend;\n\nfunction LZ4_read16(const memPtr: pointer): word; inline;\nbegin\n    result := pWord(memPtr)^;\nend;\n\nfunction LZ4_read64(const memPtr: pointer): uint64; inline;\nbegin\n    result := pUint64(memPtr)^;\nend;\n\n{$IFDEF WILDCOPY_ASM}\n{$IFDEF WIN32}\n\n\nprocedure LZ4_wildCopy; // (dstPtr: pointer; const srcPtr: pointer; dstEnd: pointer);\nasm\n    push edi\n    push esi\n    mov edi, eax\n    mov esi, edx\n    // copyCount := (((e - d) - 1) div 8) * 8 + 8;\n    sub ecx, eax // (e - d)\n    dec ecx\t\t // e - d) - 1)\n    shr ecx, 3   // ((e - d) - 1) div 8)\n    shl ecx, 3\t // ((e - d) - 1) div 8) * 8\n    add ecx, 8   // ((e - d) - 1) div 8) * 8 + 8\n\n    // if copyCount <= 0 then\n    // copyCount := 8;\n    mov eax, 8\n    cmp ecx, 0\n    cmovbe ecx, eax\n    shr ecx, 2\n    rep movsd\n    pop esi\n    pop edi\nend;\n\n{$ELSE}\n\n\nprocedure LZ4_wildCopy; // (dstPtr: pointer; const srcPtr: pointer; dstEnd: pointer);\nasm\n    mov r10, rdi\n    mov r11, rsi\n    mov rdi, rcx\n    mov rsi, rdx\n    // copyCount := (((e - d) - 1) div 8) * 8 + 8;\n    sub r8, rcx  // (dstEnd - dest)\n    mov rax, 8\n    dec r8\t\t // e - d) - 1)\n    shr r8, 3\t // ((e - d) - 1) div 8)\n    shl r8, 3\t // ((e - d) - 1) div 8) * 8\n    add r8, rax\t // ((e - d) - 1) div 8) * 8 + 8\n    cmp r8, 0\n    cmovbe r8, rax\n    mov rcx, r8\n    shr rcx, 3\n    rep movsq\n    mov rdi, r10\n    mov rsi, r11\nend;\n{$ENDIF}\n{$ELSE}\n\n\nprocedure LZ4_wildCopy(dstPtr: pointer; const srcPtr: pointer; dstEnd: pointer); inline;\nvar\n    d: pByte;\n    s: pByte;\n    e: pByte;\nbegin\n    d := dstPtr;\n    s := srcPtr;\n    e := dstEnd;\n    repeat\n{$IFDEF WIN32}\n        pCardinal(d)[0] := pCardinal(s)[0];\n        pCardinal(d)[1] := pCardinal(s)[1];\n{$ELSE}\n        pUint64(d)^ := pUint64(s)^;\n{$ENDIF}\n        inc(d, 8);\n        inc(s, 8);\n    until not(d < e);\nend;\n\n{$ENDIF}\n\n\nprocedure LZ4_writeLE16(memPtr: pointer; value: word); inline;\nbegin\n    pWord(memPtr)^ := value;\n\nend;\n\nend.\n"
  },
  {
    "path": "lib/xedit/lz4/lz4HC.pas",
    "content": "(*\n  LZ4Delphi\n  Copyright (C) 2015, Jose Pascoa (atelierwebgm@gmail.com)\n  BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php)\n\n  *************************************************************************\n  LZ4 - Fast LZ compression algorithm\n  xxHash - Fast Hash algorithm\n  LZ4 source repository : http://code.google.com/p/lz4/\n  xxHash source repository : http://code.google.com/p/xxhash/\n  Copyright (c) 2011-2014, Yann Collet\n  BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php)\n\n  Redistribution and use in source and binary forms, with or without\n  modification, are permitted provided that the following conditions are\n  met:\n\n  * Redistributions of source code must retain the above copyright\n  notice, this list of conditions and the following disclaimer.\n  * Redistributions in binary form must reproduce the above\n  copyright notice, this list of conditions and the following disclaimer\n  in the documentation and/or other materials provided with the\n  distribution.\n\n  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n  \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n ******************************************************************************\n*)\n\nunit lz4HC;\n{$POINTERMATH ON}\n\ninterface\n\nuses Windows, lz4Common;\n\nconst\n    LZ4_STREAMHCSIZE_U64 = 32774;\n\ntype\n    PLZ4_streamHC_t = ^LZ4_streamHC_t;\n\n    LZ4_streamHC_t = record\n        table: array [0 .. LZ4_STREAMHCSIZE_U64 - 1] of uint64;\n    end;\n\nfunction LZ4_createStreamHC: PLZ4_streamHC_t;\nprocedure LZ4_freeStreamHC(LZ4_streamHCPtr: PLZ4_streamHC_t);\nfunction LZ4_compressHC2(const source: pAnsiChar; dest: pAnsiChar; inputSize: integer; compressionLevel: integer): integer;\nfunction LZ4_compressHC(source: pAnsiChar; dest: pAnsiChar; inputSize: integer): integer;\nfunction LZ4_compressHC_limitedOutput(const source: pAnsiChar; dest: pAnsiChar; inputSize: integer; maxOutputSize: integer): integer;\nfunction LZ4_compressHC2_limitedOutput(const source: pAnsiChar; dest: pAnsiChar; inputSize: integer; maxOutputSize: integer;\n  compressionLevel: integer): integer;\nfunction LZ4_compressHC_withStateHC(state: pointer; const source: pAnsiChar; dest: pAnsiChar; inputSize: integer): integer;\nfunction LZ4_compressHC2_withStateHC(state: pointer; const source: pAnsiChar; dest: pAnsiChar; inputSize: integer;\n  compressionLevel: integer): integer;\nfunction LZ4_compressHC_limitedOutput_withStateHC(state: pointer; const source: pAnsiChar; dest: pAnsiChar; inputSize: integer;\n  maxOutputSize: integer): integer;\nfunction LZ4_compressHC2_limitedOutput_withStateHC(state: pointer; const source: pAnsiChar; dest: pAnsiChar; inputSize: integer;\n  maxOutputSize: integer; compressionLevel: integer): integer;\nfunction LZ4_createHC(inputBuffer: pAnsiChar): pointer;\nfunction LZ4_compressHC_continue(LZ4_streamHCPtr: PLZ4_streamHC_t; const source: pAnsiChar; dest: pAnsiChar; inputSize: integer): integer;\nfunction LZ4_loadDictHC(LZ4_streamHCPtr: PLZ4_streamHC_t; dictionary: pAnsiChar; dictSize: integer): integer;\nfunction LZ4_compressHC_limitedOutput_continue(LZ4_streamHCPtr: PLZ4_streamHC_t; const source: pAnsiChar; dest: pAnsiChar;\n  inputSize: integer; maxOutputSize: integer): integer;\nprocedure LZ4_resetStreamHC(LZ4_streamHCPtr: PLZ4_streamHC_t; compressionLevel: integer);\nfunction LZ4_saveDictHC(LZ4_streamHCPtr: PLZ4_streamHC_t; safeBuffer: pAnsiChar; dictSize: integer): integer;\n\nimplementation\n\nconst\n    DICTIONARY_LOGSIZE = 16;\n    MAXD = (1 shl DICTIONARY_LOGSIZE);\n    HASH_LOG = (DICTIONARY_LOGSIZE - 1);\n    HASHTABLESIZE = (1 shl HASH_LOG);\n    OPTIMAL_ML = integer((ML_MASK - 1) + MINMATCH);\n\n    g_maxCompressionLevel: integer = 16;\n    LZ4HC_compressionLevel_default: integer = 8;\n\ntype\n    PLZ4HC_Data_Structure = ^LZ4HC_Data_Structure;\n\n    LZ4HC_Data_Structure = record\n        hashTable: array [0 .. HASHTABLESIZE - 1] of cardinal;\n        chainTable: array [0 .. MAXD - 1] of word;\n        _end: pByte;\n        base: pByte;\n        dictBase: pByte;\n        inputBuffer: pByte;\n        dictLimit: cardinal;\n        lowLimit: cardinal;\n        nextToUpdate: cardinal;\n        compressionLevel: cardinal;\n    end;\n\n    limitedOutput_directive = (noLimit = 0, limitedOutput = 1);\n\nfunction LZ4_createStreamHC: PLZ4_streamHC_t;\nbegin\n    result := allocmem(sizeof(LZ4_streamHC_t));\nend;\n\nprocedure LZ4_freeStreamHC(LZ4_streamHCPtr: PLZ4_streamHC_t);\nbegin\n    freemem(LZ4_streamHCPtr);\nend;\n\nprocedure LZ4HC_init(hc4: PLZ4HC_Data_Structure; const start: pByte);\nbegin\n    fillchar(hc4.hashTable, sizeof(hc4.hashTable), 0);\n    fillchar(hc4.chainTable, sizeof(hc4.chainTable), 255);\n    hc4.nextToUpdate := 65536;\n    hc4.base := start - 65536;\n    hc4.inputBuffer := start;\n    hc4._end := start;\n    hc4.dictBase := start - 65536;\n    hc4.dictLimit := 65536;\n    hc4.lowLimit := 65536;\nend;\n\nfunction HASH_FUNCTION(i: cardinal): cardinal; inline;\nbegin\n    result := (i * 2654435761) shr ((MINMATCH * 8) - HASH_LOG);\nend;\n\nfunction LZ4HC_hashPtr(const ptr: pointer): cardinal; inline;\nbegin\n    result := HASH_FUNCTION(pCardinal(ptr)^);\nend;\n\nprocedure LZ4HC_Insert(hc4: PLZ4HC_Data_Structure; const ip: pByte); inline;\nvar\n    chainTable: pWord;\n    hashTable: pCardinal;\n    base: pByte;\n    target: cardinal;\n    idx: cardinal;\n    h: cardinal;\n    delta: size_t;\nbegin\n    chainTable := @hc4.chainTable;\n    hashTable := @hc4.hashTable;\n    base := hc4.base;\n    target := cardinal(ip - base);\n    idx := hc4.nextToUpdate;\n\n    while idx < target do\n    begin\n        h := LZ4HC_hashPtr(base + idx);\n        delta := idx - hashTable[h];\n        if (delta > MAX_DISTANCE) then\n            delta := MAX_DISTANCE;\n        chainTable[idx and $FFFF] := word(delta);\n        hashTable[h] := idx;\n        inc(idx);\n    end;\n    hc4.nextToUpdate := target;\nend;\n\nfunction LZ4HC_InsertAndFindBestMatch(hc4: PLZ4HC_Data_Structure; const ip: pByte; const iLimit: pByte;\n  const matchpos: ppByte; const maxNbAttempts: integer): integer; inline;\nvar\n    chainTable: pWord;\n    hashTable: pCardinal;\n    base: pByte;\n    dictBase: pByte;\n    dictLimit: cardinal;\n    lowLimit: cardinal;\n    matchIndex: cardinal;\n    match: pByte;\n    nbAttempts: integer;\n    ml: size_t;\n    mlt: size_t;\n    vLimit: pByte;\nbegin\n    chainTable := @hc4.chainTable;\n    hashTable := @hc4.hashTable;\n    base := hc4.base;\n    dictBase := hc4.dictBase;\n    dictLimit := hc4.dictLimit;\n    if hc4.lowLimit + 65536 > cardinal(ip - base) then\n        lowLimit := hc4.lowLimit\n    else\n        lowLimit := cardinal(ip - base) - 65535;\n    nbAttempts := maxNbAttempts;\n    ml := 0;\n    LZ4HC_Insert(hc4, ip);\n    matchIndex := hashTable[LZ4HC_hashPtr(ip)];\n    while (matchIndex >= lowLimit) and (nbAttempts > 0) do\n    begin\n        dec(nbAttempts);\n        if matchIndex >= dictLimit then\n        begin\n            match := base + matchIndex;\n            if ((match + ml)^ = (ip + ml)^) and (pCardinal(match)^ = pCardinal(ip)^) then\n            begin\n                mlt := LZ4_count(ip + MINMATCH, match + MINMATCH, iLimit) + MINMATCH;\n                if mlt > ml then\n                begin\n                    ml := mlt;\n                    matchpos^ := match;\n                end;\n            end;\n        end\n        else\n        begin\n            match := dictBase + matchIndex;\n            if pCardinal(match)^ = pCardinal(ip)^ then\n            begin\n                vLimit := ip + (dictLimit - matchIndex);\n                if (vLimit > iLimit) then\n                    vLimit := iLimit;\n                mlt := LZ4_count(ip + MINMATCH, match + MINMATCH, vLimit) + MINMATCH;\n                if ((ip + mlt = vLimit) and (vLimit < iLimit)) then\n                    inc(mlt, LZ4_count(ip + mlt, base + dictLimit, iLimit));\n                if (mlt > ml) then\n                begin\n                    ml := mlt;\n                    matchpos^ := base + matchIndex;\n                end; // virtual matchpos\n            end;\n        end;\n        dec(matchIndex, chainTable[matchIndex and $FFFF]);\n    end;\n    result := integer(ml);\nend;\n\nfunction LZ4HC_InsertAndGetWiderMatch(hc4: PLZ4HC_Data_Structure; const ip: pByte; const iLowLimit: pByte;\n  const iHighLimit: pByte; longest: integer; const matchpos: ppByte; const startpos: ppByte; const maxNbAttempts: integer): integer; inline;\nvar\n    chainTable: pWord;\n    hashTable: pCardinal;\n    base: pByte;\n    dictLimit: cardinal;\n    lowLimit: cardinal;\n    dictBase: pByte;\n    match: pByte;\n    matchIndex: cardinal;\n    nbAttempts: integer;\n    delta: integer;\n    startt: pByte;\n    tmpMatch: pByte;\n    matchEnd: pByte;\n    mlt: size_t;\n    back: integer;\n    vLimit: pByte;\nbegin\n    chainTable := @hc4.chainTable;\n    hashTable := @hc4.hashTable;\n    base := hc4.base;\n    dictLimit := hc4.dictLimit;\n    if (hc4.lowLimit + 65536 > cardinal(ip - base)) then\n        lowLimit := hc4.lowLimit\n    else\n        lowLimit := cardinal(ip - base) - 65535;\n    dictBase := hc4.dictBase;\n    nbAttempts := maxNbAttempts;\n    delta := integer(ip - iLowLimit);\n    LZ4HC_Insert(hc4, ip);\n    matchIndex := hashTable[LZ4HC_hashPtr(ip)];\n    while (matchIndex >= lowLimit) and (nbAttempts > 0) do\n    begin\n        dec(nbAttempts);\n        if matchIndex >= dictLimit then\n        begin\n            match := base + matchIndex;\n            if ((iLowLimit + longest)^ = (match - delta + longest)^) then\n                if pCardinal(match)^ = pCardinal(ip)^ then\n                begin\n                    startt := ip;\n                    tmpMatch := match;\n                    matchEnd := ip + MINMATCH + LZ4_count(ip + MINMATCH, match + MINMATCH, iHighLimit);\n                    while (startt > iLowLimit) and (tmpMatch > iLowLimit) and (startt[-1] = tmpMatch[-1]) do\n                    begin\n                        dec(startt);\n                        dec(tmpMatch);\n                    end;\n                    if (matchEnd - startt) > longest then\n                    begin\n                        longest := integer(matchEnd - startt);\n                        matchpos^ := tmpMatch;\n                        startpos^ := startt;\n                    end;\n                end;\n        end\n        else\n        begin\n            match := dictBase + matchIndex;\n            if pCardinal(match)^ = pCardinal(ip)^ then\n            begin\n                back := 0;\n                vLimit := ip + (dictLimit - matchIndex);\n                if vLimit > iHighLimit then\n                    vLimit := iHighLimit;\n                mlt := LZ4_count(ip + MINMATCH, match + MINMATCH, vLimit) + MINMATCH;\n                if (ip + mlt = vLimit) and (vLimit < iHighLimit) then\n                    inc(mlt, LZ4_count(ip + mlt, base + dictLimit, iHighLimit));\n                while ((ip + back > iLowLimit) and (matchIndex + cardinal(back) > lowLimit) and (ip[back - 1] = match[back - 1])) do\n                    dec(back);\n                dec(mlt, back);\n                if integer(mlt) > longest then\n                begin\n                    longest := integer(mlt);\n                    matchpos^ := base + matchIndex + back;\n                    startpos^ := ip + back;\n                end;\n            end;\n        end;\n        dec(matchIndex, chainTable[matchIndex and $FFFF]);\n    end;\n    result := longest;\nend;\n\nfunction LZ4HC_encodeSequence(const ip: ppByte; op: ppByte; const anchor: ppByte; matchLength: integer;\n  const match: pByte; limitedOutputBuffer: limitedOutput_directive; oend: pByte): integer; inline;\nvar\n    length: integer;\n    token: pByte;\n    len: integer;\nbegin\n    length := integer(ip^ - anchor^);\n    token := op^;\n    inc(op^);\n    if (limitedOutputBuffer <> noLimit) and ((op^ + (length shr 8) + length + (2 + 1 + LASTLITERALS)) > oend) then\n        exit(1);\n\n    if length >= integer(RUN_MASK) then\n    begin\n        token^ := (RUN_MASK shl ML_BITS);\n        len := length - RUN_MASK;\n        while len > 254 do\n        begin\n            op^^ := 255;\n            inc(op^);\n            dec(len, 255)\n        end;\n        op^^ := byte(len);\n        inc(op^);\n    end\n    else\n        token^ := byte(length shl ML_BITS);\n\n    LZ4_wildCopy(op^, anchor^, op^ + length);\n\n    inc(op^, length);\n    pWord(op^)^ := word(ip^ - match); // ?\n    inc(op^, 2);\n\n    length := integer(matchLength - MINMATCH);\n    if (limitedOutputBuffer <> noLimit) and (op^ + (length shr 8) + (1 + LASTLITERALS) > oend) then\n        exit(1);\n    if length >= integer(ML_MASK) then\n    begin\n        inc(token^, ML_MASK);\n        dec(length, ML_MASK);\n        while length > 509 do\n        begin\n            op^^ := 255;\n            inc(op^);\n            op^^ := 255;\n            inc(op^);\n            dec(length, 510);\n        end;\n        if (length > 254) then\n        begin\n            dec(length, 255);\n            op^^ := 255;\n            inc(op^);\n        end;\n        op^^ := byte(length);\n        inc(op^);\n    end\n    else\n        inc(token^, byte(length));\n    inc(ip^, matchLength);\n    anchor^ := ip^;\n    result := 0;\nend;\n\nfunction LZ4HC_compress_generic(ctxvoid: pointer; const source: pAnsiChar; dest: pAnsiChar; inputSize: integer;\n  maxOutputSize: integer; compressionLevel: integer; limit: limitedOutput_directive): integer;\nvar\n    ctx: PLZ4HC_Data_Structure;\n    ip: pByte;\n    anchor: pByte;\n    iend: pByte;\n    mflimit: pByte;\n    matchlimit: pByte;\n    op: pByte;\n    oend: pByte;\n    maxNbAttempts: cardinal;\n    ml, ml2, ml3, ml0: integer;\n    ref: pByte;\n    start2: pByte;\n    ref2: pByte;\n    start3: pByte;\n    ref3: pByte;\n    start0: pByte;\n    ref0: pByte;\n    correction: integer;\n    new_ml: integer;\n    lastRun: integer;\nlabel\n    _Search2, _Search3;\nbegin\n    ctx := ctxvoid;\n    ip := pByte(source);\n    anchor := ip;\n    iend := ip + inputSize;\n    mflimit := iend - _MFLIMIT;\n    matchlimit := (iend - LASTLITERALS);\n    op := pByte(dest);\n    oend := op + maxOutputSize;\n    ref := nil;\n    start2 := nil;\n    ref2 := nil;\n    start3 := nil;\n    ref3 := nil;\n\n    // init\n    if compressionLevel > g_maxCompressionLevel then\n        compressionLevel := g_maxCompressionLevel;\n    if (compressionLevel < 1) then\n        compressionLevel := LZ4HC_compressionLevel_default;\n    maxNbAttempts := 1 shl (compressionLevel - 1);\n    inc(ctx._end, inputSize);\n    inc(ip);\n\n    // Main Loop\n    while ip < mflimit do\n    begin\n        ml := LZ4HC_InsertAndFindBestMatch(ctx, ip, matchlimit, (@ref), maxNbAttempts);\n        if (ml = 0) then\n        begin\n            inc(ip);\n            continue;\n        end;\n\n        // saved, in case we would skip too much\n        start0 := ip;\n        ref0 := ref;\n        ml0 := ml;\n    _Search2:\n\n        if ip + ml < mflimit then\n            ml2 := LZ4HC_InsertAndGetWiderMatch(ctx, ip + ml - 2, ip + 1, matchlimit, ml, @ref2, @start2, maxNbAttempts)\n        else\n            ml2 := ml;\n\n        if (ml2 = ml) then // No better match\n        begin\n            if LZ4HC_encodeSequence(@ip, @op, @anchor, ml, ref, limit, oend) > 0 then\n                exit(0);\n            continue;\n        end;\n\n        if start0 < ip then\n        begin\n            if start2 < ip + ml0 then // empirical\n            begin\n                ip := start0;\n                ref := ref0;\n                ml := ml0;\n            end;\n        end;\n\n        // Here, start0==ip\n        if ((start2 - ip) < 3) then // First Match too small : removed\n        begin\n            ml := ml2;\n            ip := start2;\n            ref := ref2;\n            goto _Search2;\n        end;\n\n    _Search3:\n\n        if (start2 - ip) < OPTIMAL_ML then\n        begin\n            new_ml := ml;\n            if new_ml > OPTIMAL_ML then\n                new_ml := OPTIMAL_ML;\n            if ip + new_ml > start2 + ml2 - MINMATCH then\n                new_ml := integer(start2 - ip) + ml2 - MINMATCH;\n            correction := new_ml - integer(start2 - ip);\n            if (correction > 0) then\n            begin\n                inc(start2, correction);\n                inc(ref2, correction);\n                dec(ml2, correction);\n            end;\n        end;\n        // Now, we have start2 = ip+new_ml, with new_ml = min(ml, OPTIMAL_ML=18)\n\n        if start2 + ml2 < mflimit then\n            ml3 := LZ4HC_InsertAndGetWiderMatch(ctx, start2 + ml2 - 3, start2, matchlimit, ml2, @ref3, @start3, maxNbAttempts)\n        else\n            ml3 := ml2;\n\n        if (ml3 = ml2) then // No better match : 2 sequences to encode\n        begin\n            // ip & ref are known; Now for ml\n            if start2 < ip + ml then\n                ml := integer(start2 - ip);\n            // Now, encode 2 sequences\n            if LZ4HC_encodeSequence(@ip, @op, @anchor, ml, ref, limit, oend) <> 0 then\n                exit(0);\n            ip := start2;\n            if LZ4HC_encodeSequence(@ip, @op, @anchor, ml2, ref2, limit, oend) <> 0 then\n                exit(0);\n            continue;\n        end;\n\n        if start3 < ip + ml + 3 then // Not enough space for match 2 : remove it\n        begin\n            if start3 >= (ip + ml) then // can write Seq1 immediately ==> Seq2 is removed, so Seq3 becomes Seq1\n            begin\n                if start2 < ip + ml then\n                begin\n                    correction := integer(ip + ml - start2);\n                    inc(start2, correction);\n                    inc(ref2, correction);\n                    dec(ml2, correction);\n                    if ml2 < MINMATCH then\n                    begin\n                        start2 := start3;\n                        ref2 := ref3;\n                        ml2 := ml3;\n                    end;\n                end;\n                if LZ4HC_encodeSequence(@ip, @op, @anchor, ml, ref, limit, oend) <> 0 then\n                    exit(0);\n                ip := start3;\n                ref := ref3;\n                ml := ml3;\n\n                start0 := start2;\n                ref0 := ref2;\n                ml0 := ml2;\n                goto _Search2;\n            end;\n            start2 := start3;\n            ref2 := ref3;\n            ml2 := ml3;\n            goto _Search3;\n        end;\n\n        (*\n          * OK, now we have 3 ascending matches; let's write at least the first one\n          * ip & ref are known; Now for ml\n        *)\n        if start2 < ip + ml then\n        begin\n            if (start2 - ip) < integer(ML_MASK) then\n            begin\n                if ml > OPTIMAL_ML then\n                    ml := OPTIMAL_ML;\n                if ip + ml > start2 + ml2 - MINMATCH then\n                    ml := integer(start2 - ip) + ml2 - MINMATCH;\n                correction := ml - integer(start2 - ip);\n                if correction > 0 then\n                begin\n                    inc(start2, correction);\n                    inc(ref2, correction);\n                    dec(ml2, correction);\n                end;\n            end\n            else\n                ml := integer(start2 - ip);\n        end;\n        if LZ4HC_encodeSequence(@ip, @op, @anchor, ml, ref, limit, oend) <> 0 then\n            exit(0);\n\n        ip := start2;\n        ref := ref2;\n        ml := ml2;\n\n        start2 := start3;\n        ref2 := ref3;\n        ml2 := ml3;\n\n        goto _Search3;\n    end;\n\n    lastRun := integer(iend - anchor);\n    if (limit <> noLimit) and ((op - pByte(dest)) + lastRun + 1 + ((lastRun + 255 - RUN_MASK) div 255) > maxOutputSize) then\n        exit(0);\n    if lastRun >= integer(RUN_MASK) then\n    begin\n        op^ := RUN_MASK shl ML_BITS;\n        inc(op);\n        dec(lastRun, RUN_MASK);\n        while lastRun > 254 do\n        begin\n            op^ := 255;\n            inc(op);\n            dec(lastRun, 255);\n        end;\n        op^ := byte(lastRun);\n        inc(op);\n    end\n    else\n    begin\n        op^ := byte(lastRun shl ML_BITS);\n        inc(op);\n    end;\n    move(anchor^, op^, iend - anchor);\n    inc(op, iend - anchor);\n    result := integer(op - pByte(dest));\nend;\n\nfunction LZ4_compressHC2(const source: pAnsiChar; dest: pAnsiChar; inputSize: integer; compressionLevel: integer): integer;\nvar\n    ctx: LZ4HC_Data_Structure;\nbegin\n    fillchar(ctx, sizeof(LZ4HC_Data_Structure), 0);\n    LZ4HC_init(@ctx, pByte(source));\n    result := LZ4HC_compress_generic(@ctx, source, dest, inputSize, 0, compressionLevel, noLimit);\nend;\n\nfunction LZ4_compressHC(source: pAnsiChar; dest: pAnsiChar; inputSize: integer): integer;\nbegin\n    result := LZ4_compressHC2(source, dest, inputSize, 0);\nend;\n\nfunction LZ4_compressHC_limitedOutput(const source: pAnsiChar; dest: pAnsiChar; inputSize: integer; maxOutputSize: integer): integer;\nbegin\n    result := LZ4_compressHC2_limitedOutput(source, dest, inputSize, maxOutputSize, 0);\nend;\n\nfunction LZ4_compressHC2_limitedOutput(const source: pAnsiChar; dest: pAnsiChar; inputSize: integer; maxOutputSize: integer;\n  compressionLevel: integer): integer;\nvar\n    ctx: LZ4HC_Data_Structure;\nbegin\n    fillchar(ctx, sizeof(LZ4HC_Data_Structure), 0);\n    LZ4HC_init(@ctx, pByte(source));\n    result := LZ4HC_compress_generic(@ctx, source, dest, inputSize, maxOutputSize, compressionLevel, limitedOutput);\nend;\n\nfunction LZ4_compressHC_withStateHC(state: pointer; const source: pAnsiChar; dest: pAnsiChar; inputSize: integer): integer;\nbegin\n    result := LZ4_compressHC2_withStateHC(state, source, dest, inputSize, 0);\nend;\n\nfunction LZ4_compressHC2_withStateHC(state: pointer; const source: pAnsiChar; dest: pAnsiChar; inputSize: integer;\n  compressionLevel: integer): integer;\nbegin\n    if (size_t(state) and (sizeof(pointer) - 1)) <> 0 then\n        exit(0); // Error : : state is not aligned for pointers (32 or 64 bits) */\n    LZ4HC_init(PLZ4HC_Data_Structure(state), pByte(source));\n    result := LZ4HC_compress_generic(state, source, dest, inputSize, 0, compressionLevel, noLimit);\nend;\n\nfunction LZ4_compressHC_limitedOutput_withStateHC(state: pointer; const source: pAnsiChar; dest: pAnsiChar; inputSize: integer;\n  maxOutputSize: integer): integer;\nbegin\n    result := LZ4_compressHC2_limitedOutput_withStateHC(state, source, dest, inputSize, maxOutputSize, 0);\nend;\n\nfunction LZ4_compressHC2_limitedOutput_withStateHC(state: pointer; const source: pAnsiChar; dest: pAnsiChar; inputSize: integer;\n  maxOutputSize: integer; compressionLevel: integer): integer;\nbegin\n    if (size_t(state) and (sizeof(pointer) - 1)) <> 0 then\n        exit(0); // Error : : state is not aligned for pointers (32 or 64 bits) */\n    LZ4HC_init(PLZ4HC_Data_Structure(state), pByte(source));\n    result := LZ4HC_compress_generic(state, source, dest, inputSize, maxOutputSize, compressionLevel, limitedOutput);\nend;\n\nfunction LZ4_createHC(inputBuffer: pAnsiChar): pointer;\nvar\n    hc4: pointer;\nbegin\n    hc4 := allocmem(sizeof(LZ4HC_Data_Structure));\n    LZ4HC_init(PLZ4HC_Data_Structure(hc4), pByte(inputBuffer));\n    result := hc4;\nend;\n\nprocedure LZ4HC_setExternalDict(ctxPtr: PLZ4HC_Data_Structure; const newBlock: pByte);\nbegin\n    if ctxPtr._end >= ctxPtr.base + 4 then\n        LZ4HC_Insert(ctxPtr, ctxPtr._end - 3); // Referencing remaining dictionary content\n    // Only one memory segment for extDict, so any previous extDict is lost at this stage\n    ctxPtr.lowLimit := ctxPtr.dictLimit;\n    ctxPtr.dictLimit := cardinal(ctxPtr._end - ctxPtr.base);\n    ctxPtr.dictBase := ctxPtr.base;\n    ctxPtr.base := newBlock - ctxPtr.dictLimit;\n    ctxPtr._end := newBlock;\n    ctxPtr.nextToUpdate := ctxPtr.dictLimit; // match referencing will resume from there\nend;\n\nfunction LZ4_compressHC_continue_generic(ctxPtr: PLZ4HC_Data_Structure;\n  const source: pAnsiChar; dest: pAnsiChar;\n  inputSize: integer; maxOutputSize: integer; limit: limitedOutput_directive): integer;\nvar\n    dictSize: size_t;\n    sourceEnd: pByte;\n    dictBegin: pByte;\n    dictEnd: pByte;\nbegin\n    // auto-init if forgotten\n    if (ctxPtr.base = Nil) then\n        LZ4HC_init(ctxPtr, pByte(source));\n\n    // Check overflow\n    if size_t(ctxPtr._end - ctxPtr.base) > 2147483648 then\n    begin\n        dictSize := size_t(ctxPtr._end - ctxPtr.base) - ctxPtr.dictLimit;\n        if (dictSize > 65536) then\n            dictSize := 65536;\n        LZ4_loadDictHC(PLZ4_streamHC_t(ctxPtr), pAnsiChar(ctxPtr._end) - dictSize, integer(dictSize));\n    end;\n\n    // Check if blocks follow each other\n    if (pByte(source) <> ctxPtr._end) then\n        LZ4HC_setExternalDict(ctxPtr, pByte(source));\n\n    // Check overlapping input/dictionary space\n    sourceEnd := pByte(source) + inputSize;\n    dictBegin := ctxPtr.dictBase + ctxPtr.lowLimit;\n    dictEnd := ctxPtr.dictBase + ctxPtr.dictLimit;\n    if (sourceEnd > dictBegin) and (pByte(source) < dictEnd) then\n    begin\n        if sourceEnd > dictEnd then\n            sourceEnd := dictEnd;\n        ctxPtr.lowLimit := cardinal(sourceEnd - ctxPtr.dictBase);\n        if ctxPtr.dictLimit - ctxPtr.lowLimit < 4 then\n            ctxPtr.lowLimit := ctxPtr.dictLimit;\n    end;\n    result := LZ4HC_compress_generic(ctxPtr, source, dest, inputSize, maxOutputSize, ctxPtr.compressionLevel, limit);\nend;\n\nfunction LZ4_compressHC_continue(LZ4_streamHCPtr: PLZ4_streamHC_t; const source: pAnsiChar; dest: pAnsiChar; inputSize: integer): integer;\nbegin\n    result := LZ4_compressHC_continue_generic(PLZ4HC_Data_Structure(LZ4_streamHCPtr), source, dest, inputSize, 0, noLimit);\nend;\n\nfunction LZ4_loadDictHC(LZ4_streamHCPtr: PLZ4_streamHC_t; dictionary: pAnsiChar; dictSize: integer): integer;\nvar\n    ctxPtr: PLZ4HC_Data_Structure;\nbegin\n    ctxPtr := PLZ4HC_Data_Structure(LZ4_streamHCPtr);\n    if dictSize > 65536 then\n    begin\n        inc(dictionary, dictSize - 65536);\n        dictSize := 65536;\n    end;\n    LZ4HC_init(ctxPtr, pByte(dictionary));\n    if (dictSize >= 4) then\n        LZ4HC_Insert(ctxPtr, pByte(dictionary) + (dictSize - 3));\n    ctxPtr._end := pByte(dictionary) + dictSize;\n    result := dictSize;\nend;\n\nfunction LZ4_compressHC_limitedOutput_continue(LZ4_streamHCPtr: PLZ4_streamHC_t; const source: pAnsiChar; dest: pAnsiChar;\n  inputSize: integer; maxOutputSize: integer): integer;\nbegin\n    result := LZ4_compressHC_continue_generic(PLZ4HC_Data_Structure(LZ4_streamHCPtr), source, dest, inputSize, maxOutputSize,\n      limitedOutput);\nend;\n\nprocedure LZ4_resetStreamHC(LZ4_streamHCPtr: PLZ4_streamHC_t; compressionLevel: integer);\nbegin\n    PLZ4HC_Data_Structure(LZ4_streamHCPtr).base := Nil;\n    PLZ4HC_Data_Structure(LZ4_streamHCPtr).compressionLevel := cardinal(compressionLevel);\nend;\n\nfunction LZ4_saveDictHC(LZ4_streamHCPtr: PLZ4_streamHC_t; safeBuffer: pAnsiChar; dictSize: integer): integer;\nvar\n    streamPtr: PLZ4HC_Data_Structure;\n    prefixSize: integer;\n    endIndex: cardinal;\nbegin\n    streamPtr := PLZ4HC_Data_Structure(LZ4_streamHCPtr);\n    prefixSize := integer((streamPtr._end - (streamPtr.base + streamPtr.dictLimit)));\n    if dictSize > 65536 then\n        dictSize := 65536;\n    if dictSize < 4 then\n        dictSize := 0;\n    if (dictSize > prefixSize) then\n        dictSize := prefixSize;\n    move((streamPtr._end - dictSize)^, safeBuffer^, dictSize);\n    endIndex := cardinal(streamPtr._end - streamPtr.base);\n    streamPtr._end := pByte(safeBuffer) + dictSize;\n    streamPtr.base := streamPtr._end - endIndex;\n    streamPtr.dictLimit := endIndex - cardinal(dictSize);\n    streamPtr.lowLimit := endIndex - cardinal(dictSize);\n    if streamPtr.nextToUpdate < streamPtr.dictLimit then\n        streamPtr.nextToUpdate := streamPtr.dictLimit;\n    result:=dictSize;\nend;\n\nend.\n"
  },
  {
    "path": "lib/xedit/lz4/lz4frame.pas",
    "content": "(*\n  LZ4Delphi\n  Copyright (C) 2015, Jose Pascoa (atelierwebgm@gmail.com)\n  BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php)\n\n  *************************************************************************\n  LZ4 - Fast LZ compression algorithm\n  xxHash - Fast Hash algorithm\n  LZ4 source repository : http://code.google.com/p/lz4/\n  xxHash source repository : http://code.google.com/p/xxhash/\n  Copyright (c) 2011-2014, Yann Collet\n  BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php)\n\n  Redistribution and use in source and binary forms, with or without\n  modification, are permitted provided that the following conditions are\n  met:\n\n  * Redistributions of source code must retain the above copyright\n  notice, this list of conditions and the following disclaimer.\n  * Redistributions in binary form must reproduce the above\n  copyright notice, this list of conditions and the following disclaimer\n  in the documentation and/or other materials provided with the\n  distribution.\n\n  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n  \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n ******************************************************************************\n*)\nunit lz4frame;\n{$POINTERMATH ON}\n\ninterface\n\nuses Windows, xxHash, lz4frame_static, lz4, lz4HC, lz4common;\n\nconst\n    LZ4F_VERSION = 100;\n    LZ4F_MAGICNUMBER = $184D2204;\n    _1BIT = $01;\n    _2BITS = $03;\n    _3BITS = $07;\n    _4BITS = $0F;\n    _8BITS = $FF;\n    LZ4F_BLOCKUNCOMPRESSED_FLAG: cardinal = $80000000;\n\ntype\n    LZ4F_errorCode_t = size_t;\n    PLZ4F_decompressionContext_t = pointer;\n    PLZ4F_compressionContext_t = pointer;\n    blockSizeID_t = (LZ4F_default = 0, max64KB = 4, max256KB = 5, max1MB = 6, max4MB = 7);\n    blockMode_t = (blockLinked = 0, blockIndependent);\n    contentChecksum_t = (noContentChecksum = 0, contentChecksumEnabled);\n    LZ4F_lastBlockStatus = (notDone, fromTmpBuffer, fromSrcBuffer);\n\n    PLZ4F_frameInfo_t = ^LZ4F_frameInfo_t;\n\n    LZ4F_frameInfo_t = record\n        blockSizeID: blockSizeID_t;\n        blockMode: blockMode_t;\n        contentChecksumFlag: contentChecksum_t;\n        reserved: array [0 .. 4] of cardinal;\n    end;\n\n    PLZ4F_preferences_t = ^LZ4F_preferences_t;\n\n    LZ4F_preferences_t = record\n        frameInfo: LZ4F_frameInfo_t;\n        compressionLevel: cardinal;\n        autoFlush: cardinal;\n        reserved: array [0 .. 3] of cardinal;\n    end;\n\n    PLZ4F_compressOptions_t = ^LZ4F_compressOptions_t;\n\n    LZ4F_compressOptions_t = record\n        stableSrc: cardinal;\n        reserved: array [0 .. 2] of cardinal;\n    end;\n\n    PLZ4F_cctx_internal_t = ^LZ4F_cctx_internal_t;\n\n    LZ4F_cctx_internal_t = record\n        prefs: LZ4F_preferences_t;\n        version: cardinal;\n        cStage: cardinal;\n        maxBlockSize: size_t;\n        maxBufferSize: size_t;\n        tmpBuff: pByte;\n        tmpIn: pByte;\n        tmpInSize: size_t;\n        xxh: XXH32_state_t;\n        lz4CtxPtr: pointer;\n        lz4CtxLevel: cardinal;\n    end;\n\n    PLZ4F_dctx_internal_t = ^LZ4F_dctx_internal_t;\n\n    LZ4F_dctx_internal_t = record\n        frameInfo: LZ4F_frameInfo_t;\n        version: cardinal;\n        dStage: cardinal;\n        maxBlockSize: size_t;\n        maxBufferSize: size_t;\n        srcExpect: pByte;\n        tmpIn: pByte;\n        tmpInSize: size_t;\n        tmpInTarget: size_t;\n        tmpOutBuffer: pByte;\n        dict: pByte;\n        dictSize: size_t;\n        tmpOut: pByte;\n        tmpOutSize: size_t;\n        tmpOutStart: size_t;\n        xxh: XXH32_state_t;\n        header: array [0 .. 7] of byte;\n    end;\n\n    PLZ4F_decompressOptions_t = ^LZ4F_decompressOptions_t;\n\n    LZ4F_decompressOptions_t = record\n        stableDst: cardinal;\n        reserved: array [0 .. 2] of cardinal;\n    end;\n\nconst\n    LZ4F_BLOCKSIZEID_DEFAULT = max64KB;\n    LZ4F_MAXHEADERFRAME_SIZE = 7;\n\nfunction LZ4F_createDecompressionContext(var LZ4F_decompressionContextPtr: PLZ4F_compressionContext_t; versionNumber: cardinal)\n  : LZ4F_errorCode_t;\nfunction LZ4F_isError(code: LZ4F_errorCode_t): boolean;\nfunction LZ4F_compressFrame(dstBuffer: pointer; dstMaxSize: size_t; const srcBuffer: pointer; srcSize: size_t;\n  const preferencesPtr: PLZ4F_preferences_t): size_t;\nfunction LZ4F_compressBound(srcSize: size_t; const preferencesPtr: PLZ4F_preferences_t): size_t;\nfunction LZ4F_compressFrameBound(srcSize: size_t; const preferencesPtr: PLZ4F_preferences_t): size_t;\nfunction LZ4F_compressBegin(compressionContext: PLZ4F_compressionContext_t; dstBuffer: pointer; dstMaxSize: size_t;\n  preferencesPtr: PLZ4F_preferences_t): size_t;\nfunction LZ4F_compressUpdate(compressionContext: PLZ4F_compressionContext_t; dstBuffer: pointer; dstMaxSize: size_t;\n  const srcBuffer: pointer; srcSize: size_t; compressOptionsPtr: PLZ4F_compressOptions_t): size_t;\nfunction LZ4F_compressEnd(compressionContext: PLZ4F_compressionContext_t; dstBuffer: pointer; dstMaxSize: size_t;\n  const compressOptionsPtr: PLZ4F_compressOptions_t): size_t;\nfunction LZ4F_flush(compressionContext: PLZ4F_compressionContext_t; dstBuffer: pointer; dstMaxSize: size_t;\n  compressOptionsPtr: PLZ4F_compressOptions_t): size_t;\nfunction LZ4F_decompress(decompressionContext: PLZ4F_decompressionContext_t;\n  dstBuffer: pointer; dstSizePtr: psize_t; const srcBuffer: pointer; srcSizePtr: psize_t;\n  decompressOptionsPtr: PLZ4F_decompressOptions_t): size_t;\nfunction LZ4F_createCompressionContext(var LZ4F_compressionContextPtr: PLZ4F_compressionContext_t; version: cardinal): LZ4F_errorCode_t;\nfunction LZ4F_freeCompressionContext(LZ4F_compressionContext: PLZ4F_compressionContext_t): LZ4F_errorCode_t;\nfunction LZ4F_getFrameInfo(decompressionContext: PLZ4F_decompressionContext_t; frameInfoPtr: PLZ4F_frameInfo_t; const srcBuffer: pointer;\n  srcSizePtr: psize_t): LZ4F_errorCode_t;\nfunction LZ4F_freeDecompressionContext(LZ4F_decompressionContext: PLZ4F_decompressionContext_t): LZ4F_errorCode_t;\nfunction LZ4F_getErrorName(code : LZ4F_errorCode_t ): pAnsiChar;\n\nimplementation\n\nvar\n    minHClevel: cardinal = 3;\n\ntype\n    dStage_t = (dstage_getHeader = 0, dstage_storeHeader, dstage_decodeHeader,\n      dstage_getCBlockSize, dstage_storeCBlockSize, dstage_decodeCBlockSize,\n      dstage_copyDirect,\n      dstage_getCBlock, dstage_storeCBlock, dstage_decodeCBlock,\n      dstage_decodeCBlock_intoDst, dstage_decodeCBlock_intoTmp, dstage_flushOut,\n      dstage_getSuffix, dstage_storeSuffix, dstage_checkSuffix);\n\nfunction LZ4F_getBlockSize(blockSizeID: cardinal): size_t; forward;\n\nfunction LZ4F_createDecompressionContext(var LZ4F_decompressionContextPtr: PLZ4F_compressionContext_t; versionNumber: cardinal)\n  : LZ4F_errorCode_t;\nvar\n    dctxPtr: PLZ4F_dctx_internal_t;\nbegin\n    dctxPtr := allocmem(sizeof(LZ4F_dctx_internal_t));\n    if dctxPtr = nil then\n        exit(LZ4F_errorCode_t(-integer(ERROR_GENERIC)));\n    dctxPtr.version := versionNumber;\n    LZ4F_decompressionContextPtr := dctxPtr;\n    result := LZ4F_errorCode_t(OK_NoError);\nend;\n\nfunction LZ4F_isError(code: LZ4F_errorCode_t): boolean;\nbegin\n    result := code > LZ4F_errorCode_t(-integer(ERROR_maxCode));\nend;\n\nfunction LZ4F_getErrorName(code : LZ4F_errorCode_t ): pAnsiChar;\nbegin\n      result:=  'Unspecified error code';\n      if LZ4F_isError(code) then exit (pAnsiChar(LZ4F_errorStrings[-integer(code)]));\nend;\n\nfunction LZ4F_compressFrameBound(srcSize: size_t; const preferencesPtr: PLZ4F_preferences_t): size_t;\nvar\n    prefs: LZ4F_preferences_t;\n    headerSize: size_t;\n    streamSize: size_t;\n    proposedBSID: blockSizeID_t;\n    maxBlockSize: size_t;\nbegin\n    fillchar(prefs, sizeof(LZ4F_preferences_t), 0);\n    if (preferencesPtr <> Nil) then\n        prefs := preferencesPtr^;\n    proposedBSID := max64KB;\n    maxBlockSize := 65536;\n    while (prefs.frameInfo.blockSizeID > proposedBSID) do\n    begin\n        if srcSize <= maxBlockSize then\n        begin\n            prefs.frameInfo.blockSizeID := proposedBSID;\n            break;\n        end;\n        inc(proposedBSID);\n        maxBlockSize := maxBlockSize shl 2;\n    end;\n    prefs.autoFlush := 1;\n    headerSize := 7; // basic header size (no option) including magic number\n    streamSize := LZ4F_compressBound(srcSize, @prefs);\n    result := headerSize + streamSize;\nend;\n\nfunction LZ4F_compressFrame(dstBuffer: pointer; dstMaxSize: size_t; const srcBuffer: pointer; srcSize: size_t;\n  const preferencesPtr: PLZ4F_preferences_t): size_t;\nvar\n    cctxI: LZ4F_cctx_internal_t;\n    prefs: LZ4F_preferences_t;\n    options: LZ4F_compressOptions_t;\n    errorCode: LZ4F_errorCode_t;\n    dstStart: pByte;\n    dstPtr: pByte;\n    dstEnd: pByte;\n    proposedBSID: blockSizeID_t;\n    maxBlockSize: size_t;\nbegin\n    fillchar(cctxI, sizeof(LZ4F_cctx_internal_t), 0);\n    fillchar(prefs, sizeof(LZ4F_preferences_t), 0);\n    fillchar(options, sizeof(LZ4F_compressOptions_t), 0);\n    dstStart := pByte(dstBuffer);\n    dstPtr := dstStart;\n    dstEnd := dstStart + dstMaxSize;\n    cctxI.version := LZ4F_VERSION;\n    cctxI.maxBufferSize := 5 * 1048576;\n    if (preferencesPtr <> Nil) then\n        prefs := preferencesPtr^;\n    proposedBSID := max64KB;\n    maxBlockSize := 65536;\n    while (prefs.frameInfo.blockSizeID > proposedBSID) do\n    begin\n        if (srcSize <= maxBlockSize) then\n        begin\n            prefs.frameInfo.blockSizeID := proposedBSID;\n            break;\n        end;\n        inc(proposedBSID);\n        maxBlockSize := maxBlockSize shl 2;\n    end;\n    prefs.autoFlush := 1;\n    if (srcSize <= LZ4F_getBlockSize(cardinal(prefs.frameInfo.blockSizeID))) then\n        prefs.frameInfo.blockMode := blockIndependent; // no need for linked blocks\n\n    options.stableSrc := 1;\n\n    if (dstMaxSize < LZ4F_compressFrameBound(srcSize, @prefs)) then\n        exit(size_t(-integer(ERROR_dstMaxSize_tooSmall)));\n\n    errorCode := LZ4F_compressBegin(@cctxI, dstBuffer, dstMaxSize, @prefs); // write header\n    if (LZ4F_isError(errorCode)) then\n        exit(errorCode);\n    inc(dstPtr, errorCode); // header size\n\n    dec(dstMaxSize, errorCode);\n    errorCode := LZ4F_compressUpdate(@cctxI, dstPtr, dstMaxSize, srcBuffer, srcSize, @options);\n    if (LZ4F_isError(errorCode)) then\n        exit(errorCode);\n    inc(dstPtr, errorCode);\n    errorCode := LZ4F_compressEnd(@cctxI, dstPtr, dstEnd - dstPtr, @options); // flush last block, and generate suffix\n    if LZ4F_isError(errorCode) then\n        exit(errorCode);\n    inc(dstPtr, errorCode);\n\n    freemem(cctxI.lz4CtxPtr);\n\n    result := dstPtr - dstStart;\nend;\n\nfunction LZ4F_getBlockSize(blockSizeID: cardinal): size_t;\nconst\n    blockSizes: array [0 .. 3] of size_t = (65536, 4 * 65536, 16 * 65536, 64 * 65536);\nbegin\n    if (blockSizeID = 0) then\n        blockSizeID := cardinal(LZ4F_BLOCKSIZEID_DEFAULT);\n    dec(blockSizeID, 4);\n    if (blockSizeID > 3) then\n        exit(size_t(-integer(ERROR_maxBlockSize_invalid)));\n    result := blockSizes[blockSizeID];\nend;\n\nfunction LZ4F_compressBound(srcSize: size_t; const preferencesPtr: PLZ4F_preferences_t): size_t;\nvar\n    prefsNull: LZ4F_preferences_t;\n    prefsPtr: PLZ4F_preferences_t;\n    bid: blockSizeID_t;\n    blockSize: size_t;\n    nbBlocks: cardinal;\n    lastBlockSize: size_t;\n    blockInfo: size_t;\n    frameEnd: size_t;\nbegin\n    fillchar(prefsNull, sizeof(LZ4F_preferences_t), 0);\n    if preferencesPtr = Nil then\n        prefsPtr := @prefsNull\n    else\n        prefsPtr := preferencesPtr;\n    bid := prefsPtr.frameInfo.blockSizeID;\n    blockSize := LZ4F_getBlockSize(cardinal(bid));\n    nbBlocks := cardinal(srcSize div blockSize) + 1;\n    if prefsPtr.autoFlush <> 0 then\n        lastBlockSize := srcSize mod blockSize\n    else\n        lastBlockSize := blockSize;\n    blockInfo := 4; // default, without block CRC option\n    frameEnd := 4 + (cardinal(prefsPtr.frameInfo.contentChecksumFlag) * 4);\n    result := (blockInfo * nbBlocks) + (blockSize * (nbBlocks - 1)) + lastBlockSize + frameEnd;\nend;\n\nprocedure LZ4F_writeLE32(dstPtr: pByte; value32: cardinal);\nbegin\n    dstPtr[0] := byte(value32);\n    dstPtr[1] := byte(value32 shr 8);\n    dstPtr[2] := byte(value32 shr 16);\n    dstPtr[3] := byte(value32 shr 24);\nend;\n\nfunction LZ4F_headerChecksum(const header: pByte; length: size_t): byte;\nvar\n    xxh: cardinal;\nbegin\n    xxh := XXH32(header, cardinal(length), 0);\n    result := byte(xxh shr 8);\nend;\n\nfunction LZ4F_compressBegin(compressionContext: PLZ4F_compressionContext_t; dstBuffer: pointer; dstMaxSize: size_t;\n  preferencesPtr: PLZ4F_preferences_t): size_t;\nvar\n    prefNull: LZ4F_preferences_t;\n    cctxPtr: PLZ4F_cctx_internal_t;\n    dstStart: pByte;\n    dstPtr: pByte;\n    headerStart: pByte;\n    requiredBuffSize: size_t;\n    targetCtxLevel: cardinal;\nbegin\n    fillchar(prefNull, sizeof(LZ4F_preferences_t), 0);\n    cctxPtr := PLZ4F_cctx_internal_t(compressionContext);\n    dstStart := pByte(dstBuffer);\n    dstPtr := dstStart;\n    if (dstMaxSize < LZ4F_MAXHEADERFRAME_SIZE) then\n        exit(size_t(-integer(ERROR_dstMaxSize_tooSmall)));\n    if (cctxPtr.cStage <> 0) then\n        exit(size_t(-integer(ERROR_GENERIC)));\n    if (preferencesPtr = Nil) then\n        preferencesPtr := @prefNull;\n    cctxPtr.prefs := preferencesPtr^;\n    // ctx Management\n    if cctxPtr.prefs.compressionLevel < minHClevel then\n        targetCtxLevel := 1\n    else\n        targetCtxLevel := 2;\n    if cctxPtr.lz4CtxLevel < targetCtxLevel then\n    begin\n        freemem(cctxPtr.lz4CtxPtr);\n        if (cctxPtr.prefs.compressionLevel < minHClevel) then\n            cctxPtr.lz4CtxPtr := LZ4_createStream()\n        else\n            cctxPtr.lz4CtxPtr := LZ4_createStreamHC();\n        cctxPtr.lz4CtxLevel := targetCtxLevel;\n    end;\n    // Buffer Management\n    if cardinal(cctxPtr.prefs.frameInfo.blockSizeID) = 0 then\n        cctxPtr.prefs.frameInfo.blockSizeID := LZ4F_BLOCKSIZEID_DEFAULT;\n    cctxPtr.maxBlockSize := LZ4F_getBlockSize(cardinal(cctxPtr.prefs.frameInfo.blockSizeID));\n\n    requiredBuffSize := cctxPtr.maxBlockSize + (cardinal(cctxPtr.prefs.frameInfo.blockMode = blockLinked) * 131072);\n    if preferencesPtr.autoFlush <> 0 then\n        requiredBuffSize := cardinal(cctxPtr.prefs.frameInfo.blockMode = blockLinked) * 65536; // just needs dict\n\n    if (cctxPtr.maxBufferSize < requiredBuffSize) then\n    begin\n        cctxPtr.maxBufferSize := requiredBuffSize;\n        freemem(cctxPtr.tmpBuff);\n        cctxPtr.tmpBuff := allocmem(requiredBuffSize);\n        if (cctxPtr.tmpBuff = Nil) then\n            exit(size_t(-integer(ERROR_allocation_failed)));\n    end;\n    cctxPtr.tmpIn := cctxPtr.tmpBuff;\n    cctxPtr.tmpInSize := 0;\n    XXH32_reset(@cctxPtr.xxh, 0);\n    if cctxPtr.prefs.compressionLevel < minHClevel then\n        LZ4_resetStream(PLZ4_stream_t(cctxPtr.lz4CtxPtr))\n    else\n        LZ4_resetStreamHC(cctxPtr.lz4CtxPtr, cctxPtr.prefs.compressionLevel);\n\n    // Magic Number\n    LZ4F_writeLE32(dstPtr, LZ4F_MAGICNUMBER);\n    inc(dstPtr, 4);\n    headerStart := dstPtr;\n    // FLG Byte\n    dstPtr^ := ((1 and _2BITS) shl 6) // Version('01')\n      + ((cardinal(cctxPtr.prefs.frameInfo.blockMode) and _1BIT) shl 5) // Block mode\n      + byte((cardinal(cctxPtr.prefs.frameInfo.contentChecksumFlag) and _1BIT) shl 2); // Stream checksum\n\n    inc(dstPtr);\n\n    // BD Byte\n    dstPtr^ := byte((cardinal(cctxPtr.prefs.frameInfo.blockSizeID) and _3BITS) shl 4);\n    inc(dstPtr);\n\n    // *CRC Byte\n    dstPtr^ := LZ4F_headerChecksum(headerStart, 2);\n    inc(dstPtr);\n    cctxPtr.cStage := 1; // header written, wait for data block\n    result := dstPtr - dstStart;\nend;\n\ntype\n    compressFunc_t = function(ctx: pointer; const src: pAnsiChar; dst: pAnsiChar; srcSize: integer; dstSize: integer;\n      level: integer): integer;\n\nfunction LZ4F_localLZ4_compress_limitedOutput_withState(ctx: pointer; const src: pAnsiChar; dst: pAnsiChar; srcSize: integer;\n  dstSize: integer; level: integer): integer;\nbegin\n    result := LZ4_compress_limitedOutput_withState(ctx, src, dst, srcSize, dstSize);\nend;\n\nfunction LZ4F_localLZ4_compress_limitedOutput_continue(ctx: pointer; const src: pAnsiChar; dst: pAnsiChar; srcSize: integer;\n  dstSize: integer; level: integer): integer;\nbegin\n    result := LZ4_compress_limitedOutput_continue(PLZ4_stream_t(ctx), src, dst, srcSize, dstSize);\nend;\n\nfunction LZ4F_localLZ4_compressHC_limitedOutput_continue(ctx: pointer; const src: pAnsiChar; dst: pAnsiChar; srcSize: integer;\n  dstSize: integer; level: integer): integer;\nbegin\n    result := LZ4_compressHC_limitedOutput_continue(PLZ4_streamHC_t(ctx), src, dst, srcSize, dstSize);\nend;\n\nfunction LZ4F_localSaveDict(cctxPtr: PLZ4F_cctx_internal_t): integer;\nbegin\n    if cctxPtr.prefs.compressionLevel < minHClevel then\n        result := LZ4_saveDict(PLZ4_stream_t(cctxPtr.lz4CtxPtr), pAnsiChar(cctxPtr.tmpBuff), 65536)\n    else\n        result := LZ4_saveDictHC(PLZ4_streamHC_t(cctxPtr.lz4CtxPtr), pAnsiChar(cctxPtr.tmpBuff), 65536);\nend;\n\nfunction LZ4F_selectCompression(blockMode: blockMode_t; level: cardinal): compressFunc_t;\nbegin\n    if level < minHClevel then\n    begin\n        if (blockMode = blockIndependent) then\n            exit(@LZ4F_localLZ4_compress_limitedOutput_withState);\n        exit(@LZ4F_localLZ4_compress_limitedOutput_continue);\n    end;\n    if (blockMode = blockIndependent) then\n        exit(@LZ4_compressHC2_limitedOutput_withStateHC);\n    exit(@LZ4F_localLZ4_compressHC_limitedOutput_continue);\nend;\n\nfunction LZ4F_compressBlock(dst: pointer; const src: pointer; srcSize: size_t; compress: compressFunc_t; lz4ctx: pointer;\n  level: integer): integer;\nvar\n    cSizePtr: pByte;\n    cSize: cardinal;\nbegin\n    cSizePtr := dst;\n    cSize := cardinal(compress(lz4ctx, src, pAnsiChar(cSizePtr + 4), integer(srcSize), integer(srcSize - 1), level));\n    LZ4F_writeLE32(cSizePtr, cSize);\n    if (cSize = 0) then // compression failed\n    begin\n        cSize := srcSize;\n        LZ4F_writeLE32(cSizePtr, cSize + LZ4F_BLOCKUNCOMPRESSED_FLAG);\n        move(src^, (cSizePtr + 4)^, srcSize);\n    end;\n    result := cSize + 4;\nend;\n\nfunction LZ4F_compressUpdate(compressionContext: PLZ4F_compressionContext_t; dstBuffer: pointer; dstMaxSize: size_t;\n  const srcBuffer: pointer; srcSize: size_t; compressOptionsPtr: PLZ4F_compressOptions_t): size_t;\nvar\n    cOptionsNull: LZ4F_compressOptions_t;\n    cctxPtr: PLZ4F_cctx_internal_t;\n    blockSize: size_t;\n    srcPtr: pByte;\n    srcEnd: pByte;\n    dstStart: pByte;\n    dstPtr: pByte;\n    lastBlockCompressed: LZ4F_lastBlockStatus;\n    compress: compressFunc_t;\n    sizeToCopy: size_t;\n    realDictSize: integer;\nbegin\n    fillchar(cOptionsNull, sizeof(LZ4F_compressOptions_t), 0);\n    cctxPtr := PLZ4F_cctx_internal_t(compressionContext);\n    blockSize := cctxPtr.maxBlockSize;\n    srcPtr := srcBuffer;\n    srcEnd := srcPtr + srcSize;\n    dstStart := dstBuffer;\n    dstPtr := dstStart;\n    lastBlockCompressed := notDone;\n    if cctxPtr.cStage <> 1 then\n        exit(size_t(-integer(ERROR_GENERIC)));\n    if dstMaxSize < LZ4F_compressBound(srcSize, @(cctxPtr.prefs)) then\n        exit(size_t(-integer(ERROR_dstMaxSize_tooSmall)));\n    if compressOptionsPtr = Nil then\n        compressOptionsPtr := @cOptionsNull;\n    // select compression function\n    compress := LZ4F_selectCompression(cctxPtr.prefs.frameInfo.blockMode, cctxPtr.prefs.compressionLevel);\n    // complete tmp buffer\n    if cctxPtr.tmpInSize > 0 then // some data already within tmp buffer\n    begin\n        sizeToCopy := blockSize - cctxPtr.tmpInSize;\n        if sizeToCopy > srcSize then\n        begin\n            // add src to tmpIn buffer\n            move(srcBuffer^, (cctxPtr.tmpIn + cctxPtr.tmpInSize)^, srcSize);\n            srcPtr := srcEnd;\n            inc(cctxPtr.tmpInSize, srcSize);\n            // still needs some CRC\n        end\n        else\n        begin\n            // complete tmpIn block and then compress it\n            lastBlockCompressed := fromTmpBuffer;\n            move(srcBuffer^, (cctxPtr.tmpIn + cctxPtr.tmpInSize)^, sizeToCopy);\n            inc(srcPtr, sizeToCopy);\n            inc(dstPtr, LZ4F_compressBlock(dstPtr, cctxPtr.tmpIn, blockSize, compress, cctxPtr.lz4CtxPtr, cctxPtr.prefs.compressionLevel));\n\n            if (cctxPtr.prefs.frameInfo.blockMode = blockLinked) then\n                inc(cctxPtr.tmpIn, blockSize);\n            cctxPtr.tmpInSize := 0;\n        end;\n    end;\n    while size_t(srcEnd - srcPtr) >= blockSize do\n    begin\n        // compress full block\n        lastBlockCompressed := fromSrcBuffer;\n        inc(dstPtr, LZ4F_compressBlock(dstPtr, srcPtr, blockSize, compress, cctxPtr.lz4CtxPtr, cctxPtr.prefs.compressionLevel));\n        inc(srcPtr, blockSize);\n    end;\n    if ((cctxPtr.prefs.autoFlush <> 0) and (srcPtr < srcEnd)) then\n    begin\n        // compress remaining input < blockSize\n        lastBlockCompressed := fromSrcBuffer;\n        inc(dstPtr, LZ4F_compressBlock(dstPtr, srcPtr, srcEnd - srcPtr, compress, cctxPtr.lz4CtxPtr, cctxPtr.prefs.compressionLevel));\n        srcPtr := srcEnd;\n    end;\n\n    // preserve dictionary if necessary\n    if ((cctxPtr.prefs.frameInfo.blockMode = blockLinked) and (lastBlockCompressed = fromSrcBuffer)) then\n    begin\n        if compressOptionsPtr.stableSrc <> 0 then\n            cctxPtr.tmpIn := cctxPtr.tmpBuff\n        else\n        begin\n            realDictSize := LZ4F_localSaveDict(cctxPtr);\n            if (realDictSize = 0) then\n                exit(size_t(-integer(ERROR_GENERIC)));\n            cctxPtr.tmpIn := cctxPtr.tmpBuff + realDictSize;\n        end;\n    end;\n    // keep tmpIn within limits\n    if ((cctxPtr.tmpIn + blockSize) > (cctxPtr.tmpBuff + cctxPtr.maxBufferSize))\n    // necessarily blockLinked && lastBlockCompressed==fromTmpBuffer\n      and (cctxPtr.prefs.autoFlush = 0) then\n    begin\n        LZ4F_localSaveDict(cctxPtr);\n        cctxPtr.tmpIn := cctxPtr.tmpBuff + 65536;\n    end;\n    // some input data left, necessarily < blockSize\n    if srcPtr < srcEnd then\n    begin\n        // fill tmp buffer\n        sizeToCopy := srcEnd - srcPtr;\n        move(srcPtr^, (cctxPtr.tmpIn)^, sizeToCopy);\n        cctxPtr.tmpInSize := sizeToCopy;\n    end;\n    if (cctxPtr.prefs.frameInfo.contentChecksumFlag = contentChecksumEnabled) then\n        XXH32_update(@(cctxPtr.xxh), srcBuffer, cardinal(srcSize));\n    result := dstPtr - dstStart;\nend;\n\nfunction LZ4F_flush(compressionContext: PLZ4F_compressionContext_t; dstBuffer: pointer; dstMaxSize: size_t;\n  compressOptionsPtr: PLZ4F_compressOptions_t): size_t;\nvar\n    cOptionsNull: LZ4F_compressOptions_t;\n    cctxPtr: PLZ4F_cctx_internal_t;\n    dstStart: pByte;\n    dstPtr: pByte;\n    compress: compressFunc_t;\nbegin\n    fillchar(cOptionsNull, sizeof(LZ4F_compressOptions_t), 0);\n    cctxPtr := PLZ4F_cctx_internal_t(compressionContext);\n    dstStart := pByte(dstBuffer);\n    dstPtr := dstStart;\n    if cctxPtr.tmpInSize = 0 then\n        exit(0); // nothing to flush\n    if cctxPtr.cStage <> 1 then\n        exit(size_t(-integer(ERROR_GENERIC)));\n    if (dstMaxSize < (cctxPtr.tmpInSize + 16)) then\n        exit(size_t(-integer(ERROR_dstMaxSize_tooSmall)));\n        (* Not used\n    if (compressOptionsPtr = Nil) then\n        compressOptionsPtr := @cOptionsNull;\n        *)\n    // select compression function\n    compress := LZ4F_selectCompression(cctxPtr.prefs.frameInfo.blockMode, cctxPtr.prefs.compressionLevel);\n    // compress tmp buffer\n    inc(dstPtr, LZ4F_compressBlock(dstPtr, cctxPtr.tmpIn, cctxPtr.tmpInSize, compress, cctxPtr.lz4CtxPtr, cctxPtr.prefs.compressionLevel));\n    if (cctxPtr.prefs.frameInfo.blockMode = blockLinked) then\n        inc(cctxPtr.tmpIn, cctxPtr.tmpInSize);\n    cctxPtr.tmpInSize := 0;\n    // keep tmpIn within limits\n    if ((cctxPtr.tmpIn + cctxPtr.maxBlockSize) > (cctxPtr.tmpBuff + cctxPtr.maxBufferSize)) then // necessarily blockLinked\n    begin\n        LZ4F_localSaveDict(cctxPtr);\n        cctxPtr.tmpIn := cctxPtr.tmpBuff + 65536;\n    end;\n    result := dstPtr - dstStart;\nend;\n\nfunction LZ4F_compressEnd(compressionContext: PLZ4F_compressionContext_t; dstBuffer: pointer; dstMaxSize: size_t;\n  const compressOptionsPtr: PLZ4F_compressOptions_t): size_t;\nvar\n    cctxPtr: PLZ4F_cctx_internal_t;\n    dstStart: pByte;\n    dstPtr: pByte;\n    errorCode: size_t;\n    xxh: cardinal;\nbegin\n    cctxPtr := PLZ4F_cctx_internal_t(compressionContext);\n    dstStart := pByte(dstBuffer);\n    dstPtr := dstStart;\n    errorCode := LZ4F_flush(compressionContext, dstBuffer, dstMaxSize, compressOptionsPtr);\n    if LZ4F_isError(errorCode) then\n        exit(errorCode);\n    inc(dstPtr, errorCode);\n    LZ4F_writeLE32(dstPtr, 0);\n    inc(dstPtr, 4); // endMark\n    if cctxPtr.prefs.frameInfo.contentChecksumFlag = contentChecksumEnabled then\n    begin\n        xxh := XXH32_digest(@(cctxPtr.xxh));\n        LZ4F_writeLE32(dstPtr, xxh);\n        inc(dstPtr, 4); // content Checksum\n    end;\n    cctxPtr.cStage := 0; // state is now re-usable (with identical preferences)\n\n    result := dstPtr - dstStart;\nend;\n\nfunction LZ4F_readLE32(const srcPtr: pByte): cardinal;\nvar\n    value32: cardinal;\nbegin\n    value32 := srcPtr[0];\n    inc(value32, (srcPtr[1] shl 8));\n    inc(value32, (srcPtr[2] shl 16));\n    inc(value32, (srcPtr[3] shl 24));\n    result := value32;\nend;\n\nfunction LZ4F_decodeHeader(dctxPtr: PLZ4F_dctx_internal_t; srcPtr: pByte; srcSize: size_t): size_t;\nvar\n    FLG, BD, HC: byte;\n    version, blockMode, blockChecksumFlag, contentSizeFlag, contentChecksumFlag, dictFlag, blockSizeID: cardinal;\n    bufferNeeded: size_t;\nbegin\n    // need to decode header to get frameInfo\n    if srcSize < 7 then\n        exit(size_t(-integer(ERROR_GENERIC))); // minimal header size\n    // control magic number\n    if (LZ4F_readLE32(srcPtr) <> LZ4F_MAGICNUMBER) then\n        exit(size_t(-integer(ERROR_GENERIC)));\n    inc(srcPtr, 4);\n    // Flags\n    FLG := srcPtr[0];\n    version := (FLG shr 6) and _2BITS;\n    blockMode := (FLG shr 5) and _1BIT;\n    blockChecksumFlag := (FLG shr 4) and _1BIT;\n    contentSizeFlag := (FLG shr 3) and _1BIT;\n    contentChecksumFlag := (FLG shr 2) and _1BIT;\n    dictFlag := (FLG shr 0) and _1BIT;\n    BD := srcPtr[1];\n    blockSizeID := (BD shr 4) and _3BITS;\n    // check\n    HC := LZ4F_headerChecksum(srcPtr, 2);\n    if (HC <> srcPtr[2]) then\n        exit(size_t(-integer(ERROR_GENERIC))); // Bad header checksum error\n\n    // validate\n    if version <> 1 then\n        exit(size_t(-integer(ERROR_GENERIC))); // Version Number, only supported value\n    if blockChecksumFlag <> 0 then\n        exit(size_t(-integer(ERROR_GENERIC))); // Only supported value for the time being\n    if contentSizeFlag <> 0 then\n        exit(size_t(-integer(ERROR_GENERIC))); // Only supported value for the time being\n    if ((FLG shr 1) and _1BIT) <> 0 then\n        exit(size_t(-integer(ERROR_GENERIC)));\n    /// Reserved bit\n    if dictFlag <> 0 then\n        exit(size_t(-integer(ERROR_GENERIC))); // Only supported value for the time being\n    if (BD shr 7) and _1BIT <> 0 then\n        exit(size_t(-integer(ERROR_GENERIC)));\n    /// Reserved bit\n    if blockSizeID < 4 then\n        exit(size_t(-integer(ERROR_GENERIC))); // Only supported values for the time being\n    if (((BD shr 0) and _4BITS) <> 0) then\n        exit(size_t(-integer(ERROR_GENERIC))); // Reserved bits\n    // save\n    dctxPtr.frameInfo.blockMode := blockMode_t(blockMode);\n    dctxPtr.frameInfo.contentChecksumFlag := contentChecksum_t(contentChecksumFlag);\n    dctxPtr.frameInfo.blockSizeID := blockSizeID_t(blockSizeID);\n    dctxPtr.maxBlockSize := LZ4F_getBlockSize(blockSizeID);\n\n    // init\n    if (contentChecksumFlag <> 0) then\n        XXH32_reset(@(dctxPtr.xxh), 0);\n\n    // alloc\n    bufferNeeded := dctxPtr.maxBlockSize + size_t (integer(dctxPtr.frameInfo.blockMode = blockLinked) * 131072);\n\n    if bufferNeeded > dctxPtr.maxBufferSize then // tmp buffers too small\n    begin\n        freemem(dctxPtr.tmpIn);\n        freemem(dctxPtr.tmpOutBuffer);\n        dctxPtr.maxBufferSize := bufferNeeded;\n        dctxPtr.tmpIn := allocmem(dctxPtr.maxBlockSize);\n        if dctxPtr.tmpIn = Nil then\n            exit(size_t(-integer(ERROR_GENERIC)));\n        dctxPtr.tmpOutBuffer := allocmem(dctxPtr.maxBufferSize);\n        if dctxPtr.tmpOutBuffer = Nil then\n            exit(size_t(-integer(ERROR_GENERIC)));\n    end;\n    dctxPtr.tmpInSize := 0;\n    dctxPtr.tmpInTarget := 0;\n    dctxPtr.dict := dctxPtr.tmpOutBuffer;\n    dctxPtr.dictSize := 0;\n    dctxPtr.tmpOut := dctxPtr.tmpOutBuffer;\n    dctxPtr.tmpOutStart := 0;\n    dctxPtr.tmpOutSize := 0;\n\n    result := 7;\nend;\n\nprocedure LZ4F_updateDict(dctxPtr: PLZ4F_dctx_internal_t; const dstPtr: pByte; dstSize: size_t; const dstPtr0: pByte; withinTmp: cardinal);\nvar\n    preserveSize: size_t;\n    copySize: size_t;\n    oldDictEnd: pByte;\nbegin\n    if dctxPtr.dictSize = 0 then\n        dctxPtr.dict := pByte(dstPtr); // priority to dictionary continuity\n\n    if dctxPtr.dict + dctxPtr.dictSize = dstPtr then // dictionary continuity\n    begin\n        inc(dctxPtr.dictSize, dstSize);\n        exit;\n    end;\n\n    if size_t(dstPtr - dstPtr0) + dstSize >= 65536 then // dstBuffer large enough to become dictionary\n    begin\n        dctxPtr.dict := pByte(dstPtr0);\n        dctxPtr.dictSize := size_t(dstPtr - dstPtr0) + dstSize;\n        exit;\n    end;\n\n    if ((withinTmp <> 0) and (dctxPtr.dict = dctxPtr.tmpOutBuffer)) then\n    begin\n        // assumption : dctxPtr->dict + dctxPtr->dictSize == dctxPtr->tmpOut + dctxPtr->tmpOutStart\n        inc(dctxPtr.dictSize, dstSize);\n        exit;\n    end;\n\n    if withinTmp <> 0 then // copy relevant dict portion in front of tmpOut within tmpOutBuffer\n    begin\n        preserveSize := dctxPtr.tmpOut - dctxPtr.tmpOutBuffer;\n        copySize := 65536 - dctxPtr.tmpOutSize;\n        oldDictEnd := dctxPtr.dict + dctxPtr.dictSize - dctxPtr.tmpOutStart;\n        if dctxPtr.tmpOutSize > 65536 then\n            copySize := 0;\n        if copySize > preserveSize then\n            copySize := preserveSize;\n\n        move((oldDictEnd - copySize)^, (dctxPtr.tmpOutBuffer + preserveSize - copySize)^, copySize);\n\n        dctxPtr.dict := dctxPtr.tmpOutBuffer;\n        dctxPtr.dictSize := preserveSize + dctxPtr.tmpOutStart + dstSize;\n        exit;\n    end;\n\n    if dctxPtr.dict = dctxPtr.tmpOutBuffer then // copy dst into tmp to complete dict\n    begin\n        if dctxPtr.dictSize + dstSize > dctxPtr.maxBufferSize then // tmp buffer not large enough\n        begin\n            preserveSize := 65536 - dstSize; // note : dstSize < 64 KB\n            move((dctxPtr.dict + dctxPtr.dictSize - preserveSize)^, (dctxPtr.dict)^, preserveSize);\n            dctxPtr.dictSize := preserveSize;\n        end;\n        move(dstPtr^, (dctxPtr.dict + dctxPtr.dictSize)^, dstSize);\n        inc(dctxPtr.dictSize, dstSize);\n        exit;\n    end;\n    // join dict & dest into tmp\n\n    preserveSize := 65536 - dstSize; // note : dstSize < 64 KB\n    if preserveSize > dctxPtr.dictSize then\n        preserveSize := dctxPtr.dictSize;\n    move((dctxPtr.dict + dctxPtr.dictSize - preserveSize)^, dctxPtr.tmpOutBuffer^, preserveSize);\n    move(dstPtr^, (dctxPtr.tmpOutBuffer + preserveSize)^, dstSize);\n    dctxPtr.dict := dctxPtr.tmpOutBuffer;\n    dctxPtr.dictSize := preserveSize + dstSize;\nend;\n\nfunction LZ4F_decompress_safe(const source: pAnsiChar; dest: pAnsiChar; compressedSize: integer; maxDecompressedSize: integer;\n  const dictStart: pAnsiChar; dictSize: integer): integer;\nbegin\n    result := LZ4_decompress_safe(source, dest, compressedSize, maxDecompressedSize);\nend;\n\nfunction LZ4F_decompress(decompressionContext: PLZ4F_decompressionContext_t;\n  dstBuffer: pointer; dstSizePtr: psize_t;\n  const srcBuffer: pointer; srcSizePtr: psize_t;\n  decompressOptionsPtr: PLZ4F_decompressOptions_t): size_t;\ntype\n    Tdecoder = function(const c1: pAnsiChar; c2: pAnsiChar; c3: integer; c4: integer; const c5: pAnsiChar; c6: integer): integer;\nvar\n    dctxPtr: PLZ4F_dctx_internal_t;\n    optionsNull: LZ4F_decompressOptions_t;\n    srcStart: pByte;\n    srcEnd: pByte;\n    srcPtr: pByte;\n    dstStart: pByte;\n    dstEnd: pByte;\n    dstPtr: pByte;\n    selectedIn: pByte;\n    doAnotherStage: cardinal;\n    nextSrcSizeHint: size_t;\n    sizeToCopy: size_t;\n    errorCode: LZ4F_errorCode_t;\n    nextCBlockSize: size_t;\n    decodedSize: integer;\n    decoder: Tdecoder;\n    reservedDictSpace: size_t;\n    suffixSize: size_t;\n    readCRC: cardinal;\n    resultCRC: cardinal;\n    preserveSize: size_t;\n    copySize: size_t;\n    oldDictEnd: pByte;\n    newDictSize: size_t;\nbegin\n    dctxPtr := PLZ4F_dctx_internal_t(decompressionContext);\n    fillchar(optionsNull, sizeof(LZ4F_decompressOptions_t), 0);\n    srcStart := pByte(srcBuffer);\n    srcEnd := srcStart + srcSizePtr^;\n    srcPtr := srcStart;\n    dstStart := pByte(dstBuffer);\n    dstEnd := dstStart + dstSizePtr^;\n    dstPtr := dstStart;\n    selectedIn := Nil;\n    doAnotherStage := 1;\n    nextSrcSizeHint := 1;\n\n    if decompressOptionsPtr = Nil then\n        decompressOptionsPtr := @optionsNull;\n\n    srcSizePtr^ := 0;\n    dstSizePtr^ := 0;\n\n    // expect to continue decoding src buffer where it left previously\n    if dctxPtr.srcExpect <> Nil then\n    begin\n        if (srcStart <> dctxPtr.srcExpect) then\n            exit(size_t(-integer(ERROR_GENERIC)));\n    end;\n\n    // programmed as a state machine\n\n    while (doAnotherStage <> 0) do\n    begin\n        case dctxPtr.dStage of\n            cardinal(dstage_getHeader):\n                begin\n                    if srcEnd - srcPtr >= 7 then\n                    begin\n                        selectedIn := srcPtr;\n                        inc(srcPtr, 7);\n                        dctxPtr.dStage := cardinal(dstage_decodeHeader);\n                    end\n                    else\n                    begin\n                        dctxPtr.tmpInSize := 0;\n                        dctxPtr.dStage := cardinal(dstage_storeHeader);\n                    end;\n                end;\n            cardinal(dstage_storeHeader):\n                begin\n                    sizeToCopy := 7 - dctxPtr.tmpInSize;\n                    if sizeToCopy > size_t(srcEnd - srcPtr) then\n                        sizeToCopy := srcEnd - srcPtr;\n                    move(srcPtr^, (pByte(@dctxPtr.header) + dctxPtr.tmpInSize)^, sizeToCopy);\n                    inc(dctxPtr.tmpInSize, sizeToCopy);\n                    inc(srcPtr, sizeToCopy);\n                    if (dctxPtr.tmpInSize < 7) then\n                    begin\n                        nextSrcSizeHint := (7 - dctxPtr.tmpInSize) + 4;\n                        doAnotherStage := 0; // no enough src, wait to get some more\n                    end\n                    else\n                    begin\n                        selectedIn := @dctxPtr.header;\n                        dctxPtr.dStage := cardinal(dstage_decodeHeader);\n                    end;\n                end;\n            cardinal(dstage_decodeHeader):\n                begin\n                    errorCode := LZ4F_decodeHeader(dctxPtr, selectedIn, 7);\n                    if LZ4F_isError(errorCode) then\n                        exit(errorCode);\n                    dctxPtr.dStage := cardinal(dstage_getCBlockSize);\n                end;\n            cardinal(dstage_getCBlockSize):\n                begin\n                    if (srcEnd - srcPtr) >= 4 then\n                    begin\n                        selectedIn := srcPtr;\n                        inc(srcPtr, 4);\n                        dctxPtr.dStage := cardinal(dstage_decodeCBlockSize);\n                    end\n                    else\n                    begin\n                        // not enough input to read cBlockSize field\n                        dctxPtr.tmpInSize := 0;\n                        dctxPtr.dStage := cardinal(dstage_storeCBlockSize);\n                    end;\n                end;\n            cardinal(dstage_storeCBlockSize):\n                begin\n                    sizeToCopy := 4 - dctxPtr.tmpInSize;\n                    if sizeToCopy > size_t(srcEnd - srcPtr) then\n                        sizeToCopy := srcEnd - srcPtr;\n                    move(srcPtr^, (dctxPtr.tmpIn + dctxPtr.tmpInSize)^, sizeToCopy);\n                    inc(srcPtr, sizeToCopy);\n                    inc(dctxPtr.tmpInSize, sizeToCopy);\n                    if dctxPtr.tmpInSize < 4 then // not enough input to get full cBlockSize; wait for more\n                    begin\n                        nextSrcSizeHint := 4 - dctxPtr.tmpInSize;\n                        doAnotherStage := 0;\n                    end\n                    else\n                    begin\n                        selectedIn := dctxPtr.tmpIn;\n                        dctxPtr.dStage := cardinal(dstage_decodeCBlockSize);\n                    end;\n                end;\n            cardinal(dstage_decodeCBlockSize):\n                begin\n                    nextCBlockSize := LZ4F_readLE32(selectedIn) and $7FFFFFFF;\n                    if (nextCBlockSize = 0) then\n                        dctxPtr.dStage := cardinal(dstage_getSuffix)\n                    else\n                    begin\n                        if (nextCBlockSize > dctxPtr.maxBlockSize) then\n                            exit(size_t(-integer(ERROR_GENERIC))); // invalid cBlockSize\n                        dctxPtr.tmpInTarget := nextCBlockSize;\n                        if (LZ4F_readLE32(selectedIn) and LZ4F_BLOCKUNCOMPRESSED_FLAG) <> 0 then\n                            dctxPtr.dStage := cardinal(dstage_copyDirect)\n                        else\n                        begin\n                            dctxPtr.dStage := cardinal(dstage_getCBlock);\n                            if dstPtr = dstEnd then\n                            begin\n                                nextSrcSizeHint := nextCBlockSize + 4;\n                                doAnotherStage := 0;\n                            end;\n                        end;\n                    end;\n                end;\n            cardinal(dstage_copyDirect): // uncompressed block\n                begin\n                    sizeToCopy := dctxPtr.tmpInTarget;\n                    if size_t(srcEnd - srcPtr) < sizeToCopy then\n                        sizeToCopy := srcEnd - srcPtr; // not enough input to read full block\n                    if size_t(dstEnd - dstPtr) < sizeToCopy then\n                        sizeToCopy := dstEnd - dstPtr;\n                    move(srcPtr^, dstPtr^, sizeToCopy);\n                    if (dctxPtr.frameInfo.contentChecksumFlag <> noContentChecksum) then\n                        XXH32_update(@(dctxPtr.xxh), srcPtr, cardinal(sizeToCopy));\n                    // dictionary management\n                    if (dctxPtr.frameInfo.blockMode = blockLinked) then\n                        LZ4F_updateDict(dctxPtr, dstPtr, sizeToCopy, dstStart, 0);\n                    inc(srcPtr, sizeToCopy);\n                    inc(dstPtr, sizeToCopy);\n                    if sizeToCopy = dctxPtr.tmpInTarget then // all copied\n                        dctxPtr.dStage := cardinal(dstage_getCBlockSize)\n                    else\n                    begin\n                        dec(dctxPtr.tmpInTarget, sizeToCopy); // still need to copy more\n                        nextSrcSizeHint := dctxPtr.tmpInTarget + 4;\n                        doAnotherStage := 0;\n                    end;\n                end;\n            cardinal(dstage_getCBlock):\n                begin\n                    if size_t(srcEnd - srcPtr) < dctxPtr.tmpInTarget then\n                    begin\n                        dctxPtr.tmpInSize := 0;\n                        dctxPtr.dStage := cardinal(dstage_storeCBlock);\n                    end\n                    else\n                    begin\n                        selectedIn := srcPtr;\n                        inc(srcPtr, dctxPtr.tmpInTarget);\n                        dctxPtr.dStage := cardinal(dstage_decodeCBlock);\n                    end;\n                end;\n            cardinal(dstage_storeCBlock):\n                begin\n                    sizeToCopy := dctxPtr.tmpInTarget - dctxPtr.tmpInSize;\n                    if sizeToCopy > size_t(srcEnd - srcPtr) then\n                        sizeToCopy := srcEnd - srcPtr;\n\n                    move(srcPtr^, (dctxPtr.tmpIn + dctxPtr.tmpInSize)^, sizeToCopy);\n                    inc(dctxPtr.tmpInSize, sizeToCopy);\n                    inc(srcPtr, sizeToCopy);\n                    if (dctxPtr.tmpInSize < dctxPtr.tmpInTarget) then // need more input\n                    begin\n                        nextSrcSizeHint := (dctxPtr.tmpInTarget - dctxPtr.tmpInSize) + 4;\n                        doAnotherStage := 0;\n                    end\n                    else\n                    begin\n                        selectedIn := dctxPtr.tmpIn;\n                        dctxPtr.dStage := cardinal(dstage_decodeCBlock);\n                    end;\n                end;\n            cardinal(dstage_decodeCBlock):\n                begin\n                    if (size_t(dstEnd - dstPtr) < dctxPtr.maxBlockSize) then // not enough place into dst : decode into tmpOut\n                        dctxPtr.dStage := cardinal(dstage_decodeCBlock_intoTmp)\n                    else\n                        dctxPtr.dStage := cardinal(dstage_decodeCBlock_intoDst);\n                end;\n\n            cardinal(dstage_decodeCBlock_intoDst):\n                begin\n                    if (dctxPtr.frameInfo.blockMode = blockLinked) then\n                        decoder := LZ4_decompress_safe_usingDict\n                    else\n                        decoder := LZ4F_decompress_safe;\n\n                    decodedSize := decoder(pAnsiChar(selectedIn), pAnsiChar(dstPtr), integer(dctxPtr.tmpInTarget),\n                      integer(dctxPtr.maxBlockSize), pAnsiChar(dctxPtr.dict), integer(dctxPtr.dictSize));\n                    if (decodedSize < 0) then\n                        exit(size_t(-integer(ERROR_GENERIC))); // decompression failed\n                    if (dctxPtr.frameInfo.contentChecksumFlag <> noContentChecksum) then\n                        XXH32_update(@(dctxPtr.xxh), dstPtr, decodedSize);\n                    // dictionary management\n                    if (dctxPtr.frameInfo.blockMode = blockLinked) then\n                        LZ4F_updateDict(dctxPtr, dstPtr, decodedSize, dstStart, 0);\n\n                    inc(dstPtr, decodedSize);\n                    dctxPtr.dStage := cardinal(dstage_getCBlockSize);\n                end;\n            cardinal(dstage_decodeCBlock_intoTmp):\n                begin\n                    if (dctxPtr.frameInfo.blockMode = blockLinked) then\n                        decoder := LZ4_decompress_safe_usingDict\n                    else\n                        decoder := LZ4F_decompress_safe;\n                    // ensure enough place for tmpOut\n                    if dctxPtr.frameInfo.blockMode = blockLinked then\n                    begin\n                        if (dctxPtr.dict = dctxPtr.tmpOutBuffer) then\n                        begin\n                            if (dctxPtr.dictSize > 131072) then\n                            begin\n                                move((dctxPtr.dict + dctxPtr.dictSize - 65536)^, dctxPtr.dict^, 65536);\n                                dctxPtr.dictSize := 65536;\n                            end;\n                            dctxPtr.tmpOut := dctxPtr.dict + dctxPtr.dictSize;\n                        end\n                        else // dict not within tmp\n                        begin\n                            reservedDictSpace := dctxPtr.dictSize;\n                            if (reservedDictSpace > 65536) then\n                                reservedDictSpace := 65536;\n                            dctxPtr.tmpOut := dctxPtr.tmpOutBuffer + reservedDictSpace;\n                        end;\n                    end;\n                    // Decode\n                    decodedSize := decoder(pAnsiChar(selectedIn), pAnsiChar(dctxPtr.tmpOut), integer(dctxPtr.tmpInTarget),\n                      integer(dctxPtr.maxBlockSize), pAnsiChar(dctxPtr.dict), integer(dctxPtr.dictSize));\n                    if decodedSize < 0 then\n                        exit(size_t(-integer(ERROR_decompressionFailed))); // decompression failed\n                    if (dctxPtr.frameInfo.contentChecksumFlag <> noContentChecksum) then\n                        XXH32_update(@(dctxPtr.xxh), dctxPtr.tmpOut, decodedSize);\n                    dctxPtr.tmpOutSize := decodedSize;\n                    dctxPtr.tmpOutStart := 0;\n                    dctxPtr.dStage := cardinal(dstage_flushOut);\n                end;\n            cardinal(dstage_flushOut): // flush decoded data from tmpOut to dstBuffer\n                begin\n                    sizeToCopy := dctxPtr.tmpOutSize - dctxPtr.tmpOutStart;\n                    if (sizeToCopy > size_t(dstEnd - dstPtr)) then\n                        sizeToCopy := dstEnd - dstPtr;\n                    move((dctxPtr.tmpOut + dctxPtr.tmpOutStart)^, dstPtr^, sizeToCopy);\n                    // dictionary management\n                    if (dctxPtr.frameInfo.blockMode = blockLinked) then\n                        LZ4F_updateDict(dctxPtr, dstPtr, sizeToCopy, dstStart, 1);\n\n                    inc(dctxPtr.tmpOutStart, sizeToCopy);\n                    inc(dstPtr, sizeToCopy);\n                    // end of flush ?\n                    if (dctxPtr.tmpOutStart = dctxPtr.tmpOutSize) then\n                        dctxPtr.dStage := cardinal(dstage_getCBlockSize)\n                    else\n                    begin\n                        nextSrcSizeHint := 4;\n                        doAnotherStage := 0; // still some data to flush\n                    end;\n                end;\n            cardinal(dstage_getSuffix):\n                begin\n                    suffixSize := cardinal(dctxPtr.frameInfo.contentChecksumFlag) * 4;\n                    if (suffixSize = 0) then // frame completed\n                    begin\n                        nextSrcSizeHint := 0;\n                        dctxPtr.dStage := cardinal(dstage_getHeader);\n                        doAnotherStage := 0;\n                    end\n                    else\n                    begin\n                        if ((srcEnd - srcPtr) >= 4) then // CRC present\n                        begin\n                            selectedIn := srcPtr;\n                            inc(srcPtr, 4);\n                            dctxPtr.dStage := cardinal(dstage_checkSuffix);\n                        end\n                        else\n                        begin\n                            dctxPtr.tmpInSize := 0;\n                            dctxPtr.dStage := cardinal(dstage_storeSuffix);\n                        end;\n                    end;\n                end;\n            cardinal(dstage_storeSuffix):\n                begin\n                    sizeToCopy := 4 - dctxPtr.tmpInSize;\n                    if (sizeToCopy > size_t(srcEnd - srcPtr)) then\n                        sizeToCopy := srcEnd - srcPtr;\n                    move(srcPtr^, (dctxPtr.tmpIn + dctxPtr.tmpInSize)^, sizeToCopy);\n                    inc(srcPtr, sizeToCopy);\n                    inc(dctxPtr.tmpInSize, sizeToCopy);\n                    if (dctxPtr.tmpInSize < 4) then // not enough input to read complete suffix\n                    begin\n                        nextSrcSizeHint := 4 - dctxPtr.tmpInSize;\n                        doAnotherStage := 0;\n                    end\n                    else\n                    begin\n                        selectedIn := dctxPtr.tmpIn;\n                        dctxPtr.dStage := cardinal(dstage_checkSuffix);\n                    end;\n                end;\n            cardinal(dstage_checkSuffix):\n                begin\n                    readCRC := LZ4F_readLE32(selectedIn);\n                    resultCRC := XXH32_digest(@(dctxPtr.xxh));\n                    if (readCRC <> resultCRC) then\n                        exit(size_t(-integer(ERROR_checksum_invalid)));\n                    nextSrcSizeHint := 0;\n                    dctxPtr.dStage := cardinal(dstage_getHeader);\n                    doAnotherStage := 0;\n                end;\n        end;\n    end;\n    // preserve dictionary within tmp if necessary\n    if (dctxPtr.frameInfo.blockMode = blockLinked)\n      and (dctxPtr.dict <> dctxPtr.tmpOutBuffer)\n      and (decompressOptionsPtr.stableDst = 0)\n      and (cardinal(dctxPtr.dStage - 1) < cardinal(cardinal(dstage_getSuffix) - 1)) then\n    begin\n        if dctxPtr.dStage = cardinal(dstage_flushOut) then\n        begin\n            preserveSize := dctxPtr.tmpOut - dctxPtr.tmpOutBuffer;\n            copySize := 65536 - dctxPtr.tmpOutSize;\n            oldDictEnd := dctxPtr.dict + dctxPtr.dictSize - dctxPtr.tmpOutStart;\n            if dctxPtr.tmpOutSize > 65536 then\n                copySize := 0;\n            if copySize > preserveSize then\n                copySize := preserveSize;\n            move((oldDictEnd - copySize)^, (dctxPtr.tmpOutBuffer + preserveSize - copySize)^, copySize);\n\n            dctxPtr.dict := dctxPtr.tmpOutBuffer;\n            dctxPtr.dictSize := preserveSize + dctxPtr.tmpOutStart;\n        end\n        else\n        begin\n            newDictSize := dctxPtr.dictSize;\n            oldDictEnd := dctxPtr.dict + dctxPtr.dictSize;\n            if newDictSize > 65536 then\n                newDictSize := 65536;\n\n            move((oldDictEnd - newDictSize)^, (dctxPtr.tmpOutBuffer)^, newDictSize);\n\n            dctxPtr.dict := dctxPtr.tmpOutBuffer;\n            dctxPtr.dictSize := newDictSize;\n            dctxPtr.tmpOut := dctxPtr.tmpOutBuffer + newDictSize;\n        end;\n    end;\n    if (srcPtr < srcEnd) then // function must be called again with following source data\n        dctxPtr.srcExpect := srcPtr\n    else\n        dctxPtr.srcExpect := Nil;\n    srcSizePtr^ := (srcPtr - srcStart);\n    dstSizePtr^ := (dstPtr - dstStart);\n    result := nextSrcSizeHint;\nend;\n\nfunction LZ4F_createCompressionContext(var LZ4F_compressionContextPtr: PLZ4F_compressionContext_t; version: cardinal): LZ4F_errorCode_t;\nvar\n    cctxPtr: PLZ4F_cctx_internal_t;\nbegin\n    cctxPtr := allocmem(sizeof(LZ4F_cctx_internal_t));\n    if cctxPtr = Nil then\n        exit(LZ4F_errorCode_t(-integer(ERROR_allocation_failed)));\n\n    cctxPtr.version := version;\n    cctxPtr.cStage := 0; // Next stage : write header\n\n    LZ4F_compressionContextPtr := PLZ4F_compressionContext_t(cctxPtr);\n    result := cardinal(OK_NoError);\nend;\n\nfunction LZ4F_freeCompressionContext(LZ4F_compressionContext: PLZ4F_compressionContext_t): LZ4F_errorCode_t;\nvar\n    cctxPtr: PLZ4F_cctx_internal_t;\nbegin\n    cctxPtr := PLZ4F_cctx_internal_t(LZ4F_compressionContext);\n    freemem(cctxPtr.lz4CtxPtr);\n    freemem(cctxPtr.tmpBuff);\n    freemem(LZ4F_compressionContext);\n    result := cardinal(OK_NoError);\nend;\n\nfunction LZ4F_getFrameInfo(decompressionContext: PLZ4F_decompressionContext_t; frameInfoPtr: PLZ4F_frameInfo_t; const srcBuffer: pointer;\n  srcSizePtr: psize_t): LZ4F_errorCode_t;\nvar\n    dctxPtr: PLZ4F_dctx_internal_t;\n    errorCode: LZ4F_errorCode_t;\nbegin\n    dctxPtr := PLZ4F_dctx_internal_t(decompressionContext);\n    if dctxPtr.dStage = cardinal(dstage_getHeader) then\n    begin\n        errorCode := LZ4F_decodeHeader(dctxPtr, srcBuffer, srcSizePtr^);\n        if LZ4F_isError(errorCode) then\n            exit(errorCode);\n        srcSizePtr^ := errorCode;\n        frameInfoPtr^ := dctxPtr.frameInfo;\n        dctxPtr.srcExpect := Nil;\n        dctxPtr.dStage := cardinal(dstage_getCBlockSize);\n        exit(4);\n    end;\n    srcSizePtr^ := 0;\n    frameInfoPtr^ := dctxPtr.frameInfo;\n    result := 0;\nend;\n\nfunction LZ4F_freeDecompressionContext(LZ4F_decompressionContext: PLZ4F_decompressionContext_t): LZ4F_errorCode_t;\nvar\n    dctxPtr: PLZ4F_dctx_internal_t;\nbegin\n    dctxPtr := PLZ4F_dctx_internal_t(LZ4F_decompressionContext);\n    freemem(dctxPtr.tmpIn);\n    freemem(dctxPtr.tmpOutBuffer);\n    freemem(dctxPtr);\n    result := cardinal(OK_NoError);\nend;\n\nend.\n"
  },
  {
    "path": "lib/xedit/lz4/lz4frame_static.pas",
    "content": "(*\n  LZ4Delphi\n  Copyright (C) 2015, Jose Pascoa (atelierwebgm@gmail.com)\n  BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php)\n\n  *************************************************************************\n  LZ4 - Fast LZ compression algorithm\n  xxHash - Fast Hash algorithm\n  LZ4 source repository : http://code.google.com/p/lz4/\n  xxHash source repository : http://code.google.com/p/xxhash/\n  Copyright (c) 2011-2014, Yann Collet\n  BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php)\n\n   Redistribution and use in source and binary forms, with or without\n  modification, are permitted provided that the following conditions are\n  met:\n\n  * Redistributions of source code must retain the above copyright\n  notice, this list of conditions and the following disclaimer.\n  * Redistributions in binary form must reproduce the above\n  copyright notice, this list of conditions and the following disclaimer\n  in the documentation and/or other materials provided with the\n  distribution.\n\n  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n  \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n ******************************************************************************\n*)\n\nunit lz4frame_static;\n{$POINTERMATH ON}\n\ninterface\n\nuses Windows;\n\ntype\n    LZ4F_LIST_ERRORS = (\n      OK_NoError = 0,\n      ERROR_GENERIC,\n      ERROR_maxBlockSize_invalid,\n      ERROR_blockMode_invalid,\n      ERROR_contentChecksumFlag_invalid,\n      ERROR_compressionLevel_invalid,\n      ERROR_allocation_failed,\n      ERROR_srcSize_tooLarge,\n      ERROR_dstMaxSize_tooSmall,\n      ERROR_decompressionFailed,\n      ERROR_checksum_invalid,\n      ERROR_maxCode);\n\nconst\n     LZ4F_errorStrings : array[0..11] of AnsiString =\n     (\n       'OK_NoError',\n       'ERROR_GENERIC',\n       'ERROR_maxBlockSize_invalid',\n       'ERROR_blockMode_invalid',\n       'ERROR_contentChecksumFlag_invalid',\n       'ERROR_compressionLevel_invalid',\n       'ERROR_allocation_failed',\n       'ERROR_srcSize_tooLarge',\n       'ERROR_dstMaxSize_tooSmall',\n       'ERROR_decompressionFailed',\n        'ERROR_checksum_invalid',\n       'ERROR_maxCode'\n     );\n\nimplementation\n\nend.\n"
  },
  {
    "path": "lib/xedit/lz4/lz4io.pas",
    "content": "(*\n  LZ4Delphi\n  Copyright (C) 2015, Jose Pascoa (atelierwebgm@gmail.com)\n  BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php)\n\n  *************************************************************************\n  LZ4 - Fast LZ compression algorithm\n  xxHash - Fast Hash algorithm\n  LZ4 source repository : http://code.google.com/p/lz4/\n  xxHash source repository : http://code.google.com/p/xxhash/\n  Copyright (c) 2011-2014, Yann Collet\n  BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php)\n\n  Redistribution and use in source and binary forms, with or without\n  modification, are permitted provided that the following conditions are\n  met:\n\n  * Redistributions of source code must retain the above copyright\n  notice, this list of conditions and the following disclaimer.\n  * Redistributions in binary form must reproduce the above\n  copyright notice, this list of conditions and the following disclaimer\n  in the documentation and/or other materials provided with the\n  distribution.\n\n  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n  \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n ******************************************************************************\n*)\n\n\nunit lz4io;\n{$POINTERMATH ON}\n\ninterface\n\nuses Windows, Classes, SysUtils, Math, lz4frame_static, xxHash, lz4, lz4common, lz4frame, lz4HC;\n\n\nconst\n    LZ4_BLOCKSIZEID_DEFAULT = 7;\n    ENDOFSTREAM = uint64(-1);\n    LZ4S_MAGICNUMBER = $184D2204;\n    LZ4S_SKIPPABLE0 = $184D2A50;\n    LZ4S_SKIPPABLEMASK = $FFFFFFF0;\n    LEGACY_MAGICNUMBER = $184C2102;\n    MAGICNUMBER_SIZE = 4;\n    LEGACY_BLOCKSIZE = 8388608;\n    MIN_STREAM_BUFSIZE = 196608;\n\nvar\n    lz4_overwrite_file: boolean = true;\n    globalblockSizeID: integer = LZ4_BLOCKSIZEID_DEFAULT;\n    blockIndependence: integer = 1;\n    streamChecksum: integer = 1;\n\nfunction LZ4IO_compressFilename_Legacy(input_filename: string; output_filename: string; compressionLevel: integer): integer;\nfunction LZ4IO_compressFilename(input_filename: string; output_filename: string; compressionLevel: integer): integer;\nfunction LZ4IO_decompressFilename(input_filename: string; output_filename: string): integer;\nprocedure lz4DecompressToUserBuf(const InBuf: Pointer; InBytes: Integer;\n  const OutBuf: Pointer; BufSize: Integer);\n\nimplementation\n\nconst\n    minBlockSizeID: integer = 4;\n    maxBlockSizeID: integer = 7;\n\nfunction reportError(err: string): integer;\nbegin\n    //LZ4Client.Memo.Lines.Add(err);\n    result := 0;\nend;\n\nprocedure LZ4IO_writeLE32(p: pointer; value32: cardinal);\nvar\n    dstPtr: pByte;\nbegin\n    dstPtr := p;\n    dstPtr[0] := byte(value32);\n    dstPtr[1] := byte(value32 shr 8);\n    dstPtr[2] := byte(value32 shr 16);\n    dstPtr[3] := byte(value32 shr 24);\nend;\n\nfunction LZ4IO_compressFilename_Legacy(input_filename: string; output_filename: string; compressionLevel: integer): integer;\ntype\n    TCompressionFunction =\n      function(c1: pAnsiChar; c2: pAnsiChar; c3: integer): integer;\nvar\n    compressionFunction: TCompressionFunction;\n    filesize: uint64;\n    compressedfilesize: uint64;\n    in_buff: pAnsiChar;\n    out_buff: pAnsiChar;\n    fileIn: TFileSTream;\n    fileOut: TFileSTream;\n    sizeCheck: size_t;\n    outSize, inSize: cardinal;\nbegin\n    filesize := 0;\n    compressedfilesize := MAGICNUMBER_SIZE;\n\n    if (compressionLevel < 3) then\n        compressionFunction := LZ4_compress\n    else\n        compressionFunction := LZ4_compressHC;\n    fileIn := TFileSTream.Create(input_filename, fmOpenRead);\n    fileOut := TFileSTream.Create(output_filename, fmCreate);\n\n    in_buff := allocmem(LEGACY_BLOCKSIZE);\n    out_buff := allocmem(LZ4_compressBound(LEGACY_BLOCKSIZE));\n    try\n        if (in_buff = nil) or (out_buff = nil) then\n            exit(reportError('Allocation error : not enough memory'));\n        LZ4IO_writeLE32(out_buff, LEGACY_MAGICNUMBER);\n        sizeCheck := fileOut.Write(out_buff^, MAGICNUMBER_SIZE);\n        if sizeCheck <> MAGICNUMBER_SIZE then\n            exit(reportError('Write error : cannot write header'));\n        while true do\n        begin\n            inSize := fileIn.Read(in_buff^, LEGACY_BLOCKSIZE);\n            if inSize <= 0 then\n                break;\n            inc(filesize, inSize);\n            outSize := compressionFunction(in_buff, out_buff + 4, inSize);\n            inc(compressedfilesize, outSize + 4);\n            LZ4IO_writeLE32(out_buff, outSize);\n            sizeCheck := fileOut.Write(out_buff^, outSize + 4);\n            if sizeCheck <> size_t(outSize + 4) then\n                exit(reportError('Write error : cannot write compressed block'));\n        end;\n    finally\n        if in_buff <> nil then\n            freemem(in_buff);\n        if out_buff <> nil then\n            freemem(out_buff);\n        fileIn.Free;\n        fileOut.Free;\n        result := 0;\n    end;\nend;\n\nfunction LZ4IO_setBlockSizeID(bsid: integer): integer;\nconst\n    blockSizeTable: array [0 .. 3] of integer = (65536, 262144, 1048576, 4194304);\nbegin\n    if (bsid < minBlockSizeID) or (bsid > maxBlockSizeID) then\n        exit(-1);\n    globalblockSizeID := bsid;\n    result := blockSizeTable[globalblockSizeID - minBlockSizeID];\nend;\n\nfunction LZ4IO_compressFilename(input_filename: string; output_filename: string; compressionLevel: integer): integer;\nvar\n    filesize: uint64;\n    errorCode: LZ4F_errorCode_t;\n    ctx: PLZ4F_compressionContext_t;\n    blockSize: integer;\n    fileIn: TFileSTream;\n    fileOut: TFileSTream;\n    prefs: LZ4F_preferences_t;\n    in_buff: pAnsiChar;\n    out_buff: pAnsiChar;\n    outBuffSize: size_t;\n    headerSize: size_t;\n    sizeCheck: size_t;\n    readSize: size_t;\n    outSize: size_t;\nbegin\n    result := 0;\n    filesize := 0;\n    errorCode := LZ4F_createCompressionContext(ctx, LZ4F_VERSION);\n    if (LZ4F_isError(errorCode)) then\n        exit(reportError(format('Allocation error : can''t create LZ4F context: %s', [LZ4F_getErrorName(errorCode)])));\n    fileIn := TFileSTream.Create(input_filename, fmOpenRead);\n    fileOut := TFileSTream.Create(output_filename, fmCreate);\n    blockSize := 1 shl (8 + 2 * globalblockSizeID);\n    fillchar(prefs, sizeof(LZ4F_preferences_t), 0);\n\n    prefs.autoFlush := 1;\n    prefs.compressionLevel := compressionLevel;\n    prefs.frameInfo.blockMode := blockMode_t(blockIndependence);\n    prefs.frameInfo.blockSizeID := blockSizeID_t(globalblockSizeID);\n    prefs.frameInfo.contentChecksumFlag := contentChecksum_t(streamChecksum);\n\n    // Allocate Memory\n    in_buff := allocmem(blockSize);\n    outBuffSize := LZ4F_compressBound(blockSize, @prefs);\n    out_buff := allocmem(outBuffSize);\n    try\n        if (in_buff = nil) or (out_buff = nil) then\n            exit(reportError('Allocation error : not enough memory'));\n        // Write Archive Header\n        headerSize := LZ4F_compressBegin(ctx, out_buff, outBuffSize, @prefs);\n        if (LZ4F_isError(headerSize)) then\n            exit(reportError(format('File header generation failed: %s', [LZ4F_getErrorName(errorCode)])));\n        sizeCheck := fileOut.Write(out_buff^, headerSize);\n        if sizeCheck <> headerSize then\n            exit(reportError('Write error : cannot write header'));\n\n        readSize := fileIn.Read(in_buff^, blockSize);\n        inc(filesize, readSize);\n        while readSize > 0 do\n        begin\n            outSize := LZ4F_compressUpdate(ctx, out_buff, outBuffSize, in_buff, readSize, Nil);\n            if (LZ4F_isError(outSize)) then\n                exit(reportError(format('Compression failed: %s', [LZ4F_getErrorName(errorCode)])));\n            sizeCheck := fileOut.Write(out_buff^, outSize);\n            if sizeCheck <> outSize then\n                exit(reportError('Write error : cannot write compressed block'));\n            readSize := fileIn.Read(in_buff^, blockSize);\n            inc(filesize, readSize);\n        end;\n        // End of Stream mark\n        headerSize := LZ4F_compressEnd(ctx, out_buff, outBuffSize, Nil);\n        if LZ4F_isError(headerSize) then\n            exit(reportError(format('End of file generation failed: %s', [LZ4F_getErrorName(errorCode)])));\n        sizeCheck := fileOut.Write(out_buff^, headerSize);\n        if sizeCheck <> headerSize then\n            exit(reportError('Write error : cannot write end of stream'));\n        errorCode := LZ4F_freeCompressionContext(ctx);\n        if LZ4F_isError(errorCode) then\n            exit(reportError(format('Error : can''t free LZ4F context resource: %s', [LZ4F_getErrorName(errorCode)])));\n    finally\n        if in_buff <> nil then\n            freemem(in_buff);\n        if out_buff <> nil then\n            freemem(out_buff);\n        fileIn.Free;;\n        fileOut.Free;\n    end;\nend;\n\nfunction LZ4IO_readLE32(s: pointer): cardinal;\nvar\n    srcPtr: pByte;\n    value32: cardinal;\nbegin\n    srcPtr := s;\n    value32 := srcPtr[0];\n    inc(value32, (srcPtr[1] shl 8));\n    inc(value32, (srcPtr[2] shl 16));\n    inc(value32, (srcPtr[3] shl 24));\n    result := value32;\nend;\n\nfunction LZ4S_isSkippableMagicNumber(magic: cardinal): boolean;\nbegin\n    result := (magic and LZ4S_SKIPPABLEMASK) = LZ4S_SKIPPABLE0;\nend;\n\nfunction decodeLZ4S(finput, foutput: TSTream): uint64;\nconst\n    HEADERMAX = 20;\nvar\n    filesize: uint64;\n    inBuff: pAnsiChar;\n    outBuff: pAnsiChar;\n    headerBuff: array [0 .. HEADERMAX - 1] of ansiChar;\n    sizeCheck, nextToRead, outBuffSize, inBuffSize: size_t;\n    ctx: PLZ4F_decompressionContext_t;\n    errorCode: LZ4F_errorCode_t;\n    frameInfo: LZ4F_frameInfo_t;\n    decodedBytes: size_t;\nbegin\n    filesize := 0;\n    errorCode := LZ4F_createDecompressionContext(ctx, LZ4F_VERSION);\n    if LZ4F_isError(errorCode) then\n        exit(reportError(format('Allocation error : can''t create context: %s', [LZ4F_getErrorName(errorCode)])));\n    LZ4IO_writeLE32(@headerBuff, LZ4S_MAGICNUMBER);\n    outBuffSize := 0;\n    inBuffSize := 0;\n    sizeCheck := MAGICNUMBER_SIZE;\n    nextToRead := LZ4F_decompress(ctx, Nil, @outBuffSize, @headerBuff, @sizeCheck, Nil);\n    if LZ4F_isError(nextToRead) then\n        exit(reportError(format('Decompression error: %s', [LZ4F_getErrorName(errorCode)])));\n    if nextToRead > HEADERMAX then\n        exit(reportError(format('Header too large (%d>%d)', [integer(nextToRead), HEADERMAX])));\n    sizeCheck := finput.Read(headerBuff, nextToRead);\n    if sizeCheck <> nextToRead then\n        exit(reportError('Read error'));\n    nextToRead := LZ4F_decompress(ctx, Nil, @outBuffSize, @headerBuff, @sizeCheck, Nil);\n    errorCode := LZ4F_getFrameInfo(ctx, @frameInfo, Nil, @inBuffSize);\n    if LZ4F_isError(errorCode) then\n        exit(reportError(format('can''t decode frame header: %s', [LZ4F_getErrorName(errorCode)])));\n    outBuffSize := LZ4IO_setBlockSizeID(integer(frameInfo.blockSizeID));\n    inBuffSize := outBuffSize + 4;\n    inBuff := allocmem(inBuffSize);\n    outBuff := allocmem(outBuffSize);\n    try\n        if (inBuff = nil) or (outBuff = nil) then\n            exit(reportError('Allocation error : not enough memory'));\n        while (nextToRead <> 0) do\n        begin\n            decodedBytes := outBuffSize;\n            sizeCheck := finput.Read(inBuff^, nextToRead);\n            if sizeCheck <> nextToRead then\n                exit(reportError('Read error'));\n            errorCode := LZ4F_decompress(ctx, outBuff, @decodedBytes, inBuff, @sizeCheck, Nil);\n            if LZ4F_isError(errorCode) then\n                exit(reportError(format('Decompression error: %s', [LZ4F_getErrorName(errorCode)])));\n            if sizeCheck <> nextToRead then\n                exit(reportError('Synchronization error'));\n            nextToRead := errorCode;\n            inc(filesize, decodedBytes);\n            sizeCheck := foutput.Write(outBuff^, decodedBytes);\n            if sizeCheck <> decodedBytes then\n                exit(reportError('Write error : cannot write decoded block'));\n        end;\n        errorCode := LZ4F_freeDecompressionContext(ctx);\n        if LZ4F_isError(errorCode) then\n            exit(reportError(format('Error : can''t free LZ4F context resource: %s', [LZ4F_getErrorName(errorCode)])));\n    finally\n        if inBuff <> nil then\n            freemem(inBuff);\n        if outBuff <> nil then\n            freemem(outBuff);\n        result := filesize;\n    end;\nend;\n\nfunction decodeLegacyStream(finput, foutput: TSTream): uint64;\nvar\n    filesize: uint64;\n    in_buff: pAnsiChar;\n    out_buff: pAnsiChar;\n    decodeSize: integer;\n    sizeCheck: size_t;\n    blockSize: cardinal;\nbegin\n    filesize := 0;\n    in_buff := allocmem(LZ4_compressBound(LEGACY_BLOCKSIZE));\n    out_buff := allocmem(LEGACY_BLOCKSIZE);\n    try\n        if (in_buff = nil) or (out_buff = nil) then\n            exit(reportError('Allocation error : not enough memory'));\n        while true do\n        begin\n            sizeCheck := finput.Read(in_buff^, 4);\n            if sizeCheck = 0 then\n                break;\n            blockSize := LZ4IO_readLE32(in_buff);\n            if blockSize > LZ4_compressBound(LEGACY_BLOCKSIZE) then\n            begin\n                finput.Seek(-4, soFromCurrent);\n                break;\n            end;\n            sizeCheck := finput.Read(in_buff^, blockSize);\n            if sizeCheck <> blockSize then\n                exit(reportError('Error reading input file'));\n            decodeSize := LZ4_decompress_safe(in_buff, out_buff, blockSize, LEGACY_BLOCKSIZE);\n            if (decodeSize < 0) then\n                exit(reportError('Decoding Failed ! Corrupted input detected'));\n            inc(filesize, decodeSize);\n            sizeCheck := foutput.Write(out_buff^, decodeSize);\n            if sizeCheck <> size_t(decodeSize) then\n                exit(reportError('Write error : cannot write decoded block into output'));\n        end;\n    finally\n        if in_buff <> nil then\n            freemem(in_buff);\n        if out_buff <> nil then\n            freemem(out_buff);\n        result := filesize;\n    end;\nend;\n\nfunction selectDecoder(finput, foutput: TSTream): uint64;\nvar\n    nbReadBytes: size_t;\n    U32Store: array [0 .. MAGICNUMBER_SIZE - 1] of byte;\n    magicNumber, Size: cardinal;\n    newPos: uint64;\nbegin\n    nbReadBytes := finput.Read(U32Store, MAGICNUMBER_SIZE);\n    if nbReadBytes = 0 then\n        exit(ENDOFSTREAM);\n    if nbReadBytes <> MAGICNUMBER_SIZE then\n        exit(reportError('Unrecognized header : Magic Number unreadable'));\n    magicNumber := LZ4IO_readLE32(@U32Store);\n    if LZ4S_isSkippableMagicNumber(magicNumber) then\n        magicNumber := LZ4S_SKIPPABLE0;\n\n    case magicNumber of\n        LZ4S_MAGICNUMBER: result := decodeLZ4S(finput, foutput);\n        LEGACY_MAGICNUMBER:\n            begin\n                result := decodeLegacyStream(finput, foutput);\n            end;\n        LZ4S_SKIPPABLE0:\n            begin\n                nbReadBytes := finput.Read(U32Store, 4);\n                if (nbReadBytes <> 4) then\n                    exit(reportError('Stream error : skippable size unreadable'));\n                Size := LZ4IO_readLE32(@U32Store);\n                newPos := finput.Seek(Size, soFromCurrent);\n                if newPos <> finput.Position then\n                    exit(reportError('Stream error : cannot skip skippable area'));\n                result := selectDecoder(finput, foutput);\n            end;\n    else\n        begin\n            if finput.Position = MAGICNUMBER_SIZE then\n                exit(reportError('Unrecognized header : file cannot be decoded'));\n            reportError('Stream followed by unrecognized data');\n            result := ENDOFSTREAM;\n        end;\n    end;\nend;\n\nfunction LZ4IO_decompressFilename(input_filename: string; output_filename: string): integer;\nvar\n  fileIn: TFileSTream;\n  fileOut: TFileSTream;\n  decodedSize: int64;\n  filesize: int64;\nbegin\n  result := 0;\n  filesize := 0;\n  fileIn := TFileSTream.Create(input_filename, fmOpenRead);\n  fileOut := TFileSTream.Create(output_filename, fmCreate);\n  repeat\n      decodedSize := selectDecoder(fileIn, fileOut);\n      if decodedSize <> ENDOFSTREAM then\n          inc(filesize, decodedSize);\n  until decodedSize = ENDOFSTREAM;\n  fileIn.Free;;\n  fileOut.Free;\nend;\n\ntype\n  TPreallocatedMemoryStream = class(TCustomMemoryStream)\n  public\n    constructor Create(Ptr: Pointer; Size: Int64);\n    function Write(const Buffer; Count: Longint): Longint; override;\n  end;\n\nconstructor TPreallocatedMemoryStream.Create(Ptr: Pointer; Size: Int64);\nbegin\n  inherited Create;\n  SetPointer(Ptr, Size);\nend;\n\nfunction TPreallocatedMemoryStream.Write(const Buffer; Count: Integer): Longint;\nbegin\n  Result := Min(Count, Size-Position);\n  System.Move(Buffer, Pointer(PByte(Memory) + Position)^, Result);\n  Seek(Result, soCurrent);\nend;\n\nprocedure lz4DecompressToUserBuf(const InBuf: Pointer; InBytes: Integer;\n  const OutBuf: Pointer; BufSize: Integer);\nvar\n  stin, stout: TPreallocatedMemoryStream;\n  decodedSize: int64;\n  decompressedSize: int64;\nbegin\n  stin := TPreallocatedMemoryStream.Create(InBuf, InBytes);\n  stout := TPreallocatedMemoryStream.Create(OutBuf, BufSize);\n  try\n    decompressedSize := 0;\n    repeat\n      decodedSize := selectDecoder(stin, stout);\n      if decodedSize <> ENDOFSTREAM then\n        Inc(decompressedSize, decodedSize);\n    until decodedSize = ENDOFSTREAM;\n\n    if decompressedSize <> BufSize then\n      Exception.Create('lz4 decompression size mismatch');\n\n    //Move(stout.Memory^, OutBuf^, BufSize);\n  finally\n    stin.Free;\n    stout.Free;\n  end;\nend;\n\nend.\n"
  },
  {
    "path": "lib/xedit/lz4/xxHash.pas",
    "content": "(*\n  LZ4Delphi\n  Copyright (C) 2015, Jose Pascoa (atelierwebgm@gmail.com)\n  BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php)\n\n  *************************************************************************\n  LZ4 - Fast LZ compression algorithm\n  xxHash - Fast Hash algorithm\n  LZ4 source repository : http://code.google.com/p/lz4/\n  xxHash source repository : http://code.google.com/p/xxhash/\n  Copyright (c) 2011-2014, Yann Collet\n  BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php)\n\n  \n  Redistribution and use in source and binary forms, with or without\n  modification, are permitted provided that the following conditions are\n  met:\n\n  * Redistributions of source code must retain the above copyright\n  notice, this list of conditions and the following disclaimer.\n  * Redistributions in binary form must reproduce the above\n  copyright notice, this list of conditions and the following disclaimer\n  in the documentation and/or other materials provided with the\n  distribution.\n\n  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n  \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n ******************************************************************************\n*)\n\nunit xxHash;\n{$POINTERMATH ON}\n\ninterface\n\nuses Windows, lz4common;\n\nconst\n    PRIME32_1: cardinal = 2654435761;\n    PRIME32_2: cardinal = 2246822519;\n    PRIME32_3: cardinal = 3266489917;\n    PRIME32_4: cardinal = 668265263;\n    PRIME32_5: cardinal = 374761393;\n    PRIME64_1: uint64 = 11400714785074694791;\n    PRIME64_2: uint64 = 14029467366897019727;\n    PRIME64_3: uint64 = 1609587929392839161;\n    PRIME64_4: uint64 = 9650029242287828579;\n    PRIME64_5: uint64 = 2870177450012600261;\n\ntype\n    XXH_errorcode = (XXH_OK = 0, XXH_ERROR);\n    XXH_endianess = (XXH_bigEndian = 0, XXH_littleEndian = 1);\n    XXH_alignment = (XXH_aligned, XXH_unaligned);\n\n    PXXH32_state_t = ^XXH32_state_t;\n\n    XXH32_state_t = record\n        ll: array [0 .. 5] of int64;\n    end;\n\n    PXXH_istate32_t = ^XXH_istate32_t;\n\n    XXH_istate32_t = record\n        total_len: uint64;\n        seed: cardinal;\n        v1: cardinal;\n        v2: cardinal;\n        v3: cardinal;\n        v4: cardinal;\n        mem32: array [0 .. 3] of cardinal;\n        memsize: cardinal;\n    end;\n\n    PXXH64_state_t = ^XXH64_state_t;\n\n    XXH64_state_t = record\n        ll: array [0 .. 10] of int64;\n    end;\n\n    PXXH_istate64_t = ^XXH_istate64_t;\n\n    XXH_istate64_t = record\n        total_len: uint64;\n        seed: uint64;\n        v1: uint64;\n        v2: uint64;\n        v3: uint64;\n        v4: uint64;\n        mem64: array [0 .. 3] of uint64;\n        memsize: cardinal;\n    end;\n\nfunction XXH32(input: pointer; len: size_t; seed: cardinal): cardinal;\n\nfunction XXH32_reset(statePtr: PXXH32_state_t; seed: cardinal): XXH_errorcode;\nfunction XXH32_update(statePtr: PXXH32_state_t; Ainput: pointer; ALength: size_t): XXH_errorcode;\nfunction XXH32_digest(statePtr: PXXH32_state_t): cardinal;\nfunction XXH32_createState: PXXH32_state_t;\nprocedure XXH32_freeState(statePtr: PXXH32_state_t);\n// Obsolet in recent release\nfunction XXH32_init(seed: cardinal): PXXH32_state_t;\n\nfunction XXH64_reset(statePtr: PXXH64_state_t; seed: uint64): XXH_errorcode;\nfunction XXH64_update(statePtr: PXXH64_state_t; Ainput: pointer; ALength: size_t): XXH_errorcode;\nfunction XXH64_digest(statePtr: PXXH64_state_t): uint64;\nfunction XXH64_createState: PXXH64_state_t;\nprocedure XXH64_freeState(statePtr: PXXH64_state_t);\n// Obsolet in recent release\nfunction XXH64_init(seed: uint64): PXXH64_state_t;\n\nimplementation\n\ntype\n    PU32_S = ^U32_S;\n\n    U32_S = packed record\n        v: cardinal;\n    end;\n\n    PU64_S = ^U64_S;\n\n    U64_S = packed record\n        v: uint64;\n    end;\n\nfunction XXH_rotl32(x, r: cardinal): cardinal;\nasm\n    mov eax, x\n    mov ecx, r\n    rol eax, cl\nend;\n\n(*  Alternative\nfunction XXH_rotl32(x, r: cardinal): cardinal; inline;\nvar\n    temp: cardinal;\nbegin\n    temp := x;\n    result := (x shl r) or (temp shr (32 - r));\nend;\n*)\n{$IFDEF CPUX64}\n\nfunction XXH_rotl64(x: uint64; r: cardinal): uint64;\nasm\n    mov rax, x\n    mov ecx, r\n    rol rax, cl\nend;\n{$ELSE}\n\nfunction XXH_rotl64(x: uint64; r: cardinal): uint64; inline\nvar\n    temp: uint64;\nbegin\n    temp := x;\n    result := (x shl r) or (temp shr (64 - r));\nend;\n\n{$ENDIF}\n\nfunction A32(x: pointer): cardinal; inline;\nbegin\n    result := PU32_S(x).v;\nend;\n\nfunction A64(x: pointer): uint64; inline;\nbegin\n    result := PU64_S(x).v;\nend;\n\nfunction XXH_readLE32_align(ptr: pointer; endian: XXH_endianess; align: XXH_alignment): cardinal; inline;\nbegin\n    if align = XXH_unaligned then\n        result := A32(ptr)\n    else\n        result := pcardinal(ptr)^;\nend;\n\nfunction XXH_readLE32(ptr: pointer): cardinal; inline;\nbegin\n    result := XXH_readLE32_align(ptr, XXH_littleEndian, XXH_unaligned);\nend;\n\nfunction XXH_readLE64_align(ptr: pointer; endian: XXH_endianess; align: XXH_alignment): uint64; inline;\nbegin\n    if align = XXH_unaligned then\n        result := A64(ptr)\n    else\n        result := puint64(ptr)^;\nend;\n\nfunction XXH_readLE64(ptr: pointer): uint64; inline;\nbegin\n    result := XXH_readLE64_align(ptr, XXH_littleEndian, XXH_unaligned);\nend;\n\nfunction XXH32_reset(statePtr: PXXH32_state_t; seed: cardinal): XXH_errorcode;\nvar\n    state: PXXH_istate32_t;\nbegin\n    state := PXXH_istate32_t(statePtr);\n    state.seed := seed;\n    state.v1 := seed + PRIME32_1 + PRIME32_2;\n    state.v2 := seed + PRIME32_2;\n    state.v3 := seed + 0;\n    state.v4 := seed - PRIME32_1;\n    state.total_len := 0;\n    state.memsize := 0;\n    result := XXH_OK;\nend;\n\nfunction XXH64_reset(statePtr: PXXH64_state_t; seed: uint64): XXH_errorcode;\nvar\n    state: PXXH_istate64_t;\nbegin\n    state := PXXH_istate64_t(statePtr);\n    state.seed := seed;\n    state.v1 := seed + PRIME64_1 + PRIME64_2;\n    state.v2 := seed + PRIME64_2;\n    state.v3 := seed + 0;\n    state.v4 := seed - PRIME64_1;\n    state.total_len := 0;\n    state.memsize := 0;\n    result := XXH_OK;\nend;\n\nfunction XXH32_update(statePtr: PXXH32_state_t; Ainput: pointer; ALength: size_t): XXH_errorcode;\nvar\n    state: PXXH_istate32_t;\n    p: pByte;\n    bEnd: pByte;\n    p32: pcardinal;\n    limit: pByte;\n    v1, v2, v3, v4: cardinal;\nbegin\n    state := PXXH_istate32_t(statePtr);\n    p := Ainput;\n    bEnd := p + ALength;\n    inc(state.total_len, ALength);\n\n    if (state.memsize + ALength < 16) then\n    begin\n        move(Ainput^, (pByte(@state.mem32) + state.memsize)^, ALength);\n        inc(state.memsize, cardinal(ALength));\n        exit(XXH_OK);\n    end;\n    if state.memsize > 0 then\n    begin\n        move(Ainput^, (pByte(@state.mem32) + state.memsize)^, 16 - state.memsize);\n        p32 := @state.mem32;\n        inc(state.v1, XXH_readLE32(p32) * PRIME32_2);\n        state.v1 := XXH_rotl32(state.v1, 13);\n        state.v1 := state.v1 * PRIME32_1;\n        inc(p32);\n        inc(state.v2, XXH_readLE32(p32) * PRIME32_2);\n        state.v2 := XXH_rotl32(state.v2, 13);\n        state.v2 := state.v2 * PRIME32_1;\n        inc(p32);\n        inc(state.v3, XXH_readLE32(p32) * PRIME32_2);\n        state.v3 := XXH_rotl32(state.v3, 13);\n        state.v3 := state.v3 * PRIME32_1;\n        inc(p32);\n        inc(state.v4, XXH_readLE32(p32) * PRIME32_2);\n        state.v4 := XXH_rotl32(state.v4, 13);\n        state.v4 := state.v4 * PRIME32_1;\n//        inc(p32);\n        inc(p, 16 - state.memsize);\n        state.memsize := 0;\n    end;\n\n    if p <= (bEnd - 16) then\n    begin\n        limit := bEnd - 16;\n        v1 := state.v1;\n        v2 := state.v2;\n        v3 := state.v3;\n        v4 := state.v4;\n        repeat\n            inc(v1, XXH_readLE32(p) * PRIME32_2);\n            v1 := XXH_rotl32(v1, 13);\n            v1 := v1 * PRIME32_1;\n            inc(p, 4);\n            inc(v2, XXH_readLE32(p) * PRIME32_2);\n            v2 := XXH_rotl32(v2, 13);\n            v2 := v2 * PRIME32_1;\n            inc(p, 4);\n            inc(v3, XXH_readLE32(p) * PRIME32_2);\n            v3 := XXH_rotl32(v3, 13);\n            v3 := v3 * PRIME32_1;\n            inc(p, 4);\n            inc(v4, XXH_readLE32(p) * PRIME32_2);\n            v4 := XXH_rotl32(v4, 13);\n            v4 := v4 * PRIME32_1;\n            inc(p, 4);\n        until p > limit;\n        state.v1 := v1;\n        state.v2 := v2;\n        state.v3 := v3;\n        state.v4 := v4;\n    end;\n\n    if p < bEnd then\n    begin\n        move(p^, state.mem32, bEnd - p);\n        state.memsize := integer(bEnd - p);\n    end;\n    result := XXH_OK;\nend;\n\nfunction XXH64_update(statePtr: PXXH64_state_t; Ainput: pointer; ALength: size_t): XXH_errorcode;\nvar\n    state: PXXH_istate64_t;\n    p: pByte;\n    bEnd: pByte;\n    p64: puint64;\n    limit: pByte;\n    v1, v2, v3, v4: uint64;\nbegin\n    state := PXXH_istate64_t(statePtr);\n    p := Ainput;\n    bEnd := p + ALength;\n    inc(state.total_len, ALength);\n\n    if (state.memsize + ALength < 32) then\n    begin\n        move(Ainput^, (pByte(@state.mem64) + state.memsize)^, ALength);\n        inc(state.memsize, cardinal(ALength));\n        exit(XXH_OK);\n    end;\n\n    if state.memsize > 0 then\n    begin\n        move(Ainput^, (pByte(@state.mem64) + state.memsize)^, 32 - state.memsize);\n        p64 := @state.mem64;\n        inc(state.v1, XXH_readLE64(p64) * PRIME64_2);\n        state.v1 := XXH_rotl64(state.v1, 31);\n        state.v1 := state.v1 * PRIME64_1;\n        inc(p64);\n        inc(state.v2, XXH_readLE64(p64) * PRIME64_2);\n        state.v2 := XXH_rotl64(state.v2, 31);\n        state.v2 := state.v2 * PRIME64_1;\n        inc(p64);\n        inc(state.v3, XXH_readLE64(p64) * PRIME64_2);\n        state.v3 := XXH_rotl64(state.v3, 31);\n        state.v3 := state.v3 * PRIME64_1;\n        inc(p64);\n        inc(state.v4, XXH_readLE64(p64) * PRIME64_2);\n        state.v4 := XXH_rotl64(state.v4, 31);\n        state.v4 := state.v4 * PRIME64_1;\n        inc(p, 32 - state.memsize);\n        state.memsize := 0;\n    end;\n\n    if (p + 32) <= bEnd then\n    begin\n        limit := bEnd - 32;\n        v1 := state.v1;\n        v2 := state.v2;\n        v3 := state.v3;\n        v4 := state.v4;\n        repeat\n            inc(v1, XXH_readLE64(p) * PRIME64_2);\n            v1 := XXH_rotl64(v1, 31);\n            v1 := v1 * PRIME64_1;\n            inc(p, 8);\n            inc(v2, XXH_readLE64(p) * PRIME64_2);\n            v2 := XXH_rotl64(v2, 31);\n            v2 := v2 * PRIME64_1;\n            inc(p, 8);\n            inc(v3, XXH_readLE64(p) * PRIME64_2);\n            v3 := XXH_rotl64(v3, 31);\n            v3 := v3 * PRIME64_1;\n            inc(p, 8);\n            inc(v4, XXH_readLE64(p) * PRIME64_2);\n            v4 := XXH_rotl64(v4, 31);\n            v4 := v4 * PRIME64_1;\n            inc(p, 8);\n        until p > limit;\n        state.v1 := v1;\n        state.v2 := v2;\n        state.v3 := v3;\n        state.v4 := v4;\n    end;\n\n    if p < bEnd then\n    begin\n        move(p^, state.mem64, bEnd - p);\n        state.memsize := integer(bEnd - p);\n    end;\n    result := XXH_OK;\nend;\n\nfunction XXH32_digest(statePtr: PXXH32_state_t): cardinal;\nvar\n    state: PXXH_istate32_t;\n    p: pByte;\n    bEnd: pByte;\n    h32: cardinal;\nbegin\n    state := PXXH_istate32_t(statePtr);\n    p := @state.mem32;\n    bEnd := pByte(@state.mem32) + state.memsize;\n\n    if (state.total_len >= 16) then\n        h32 := XXH_rotl32(state.v1, 1) + XXH_rotl32(state.v2, 7) + XXH_rotl32(state.v3, 12) + XXH_rotl32(state.v4, 18)\n    else\n        h32 := state.seed + PRIME32_5;\n\n    inc(h32, state.total_len);\n\n    while (p + 4) <= bEnd do\n    begin\n        inc(h32, XXH_readLE32(p) * PRIME32_3);\n        h32 := XXH_rotl32(h32, 17) * PRIME32_4;\n        inc(p, 4);\n    end;\n\n    while p < bEnd do\n    begin\n        inc(h32, p^ * PRIME32_5);\n        h32 := XXH_rotl32(h32, 11) * PRIME32_1;\n        inc(p);\n    end;\n    h32 := h32 xor (h32 shr 15);\n    h32 := h32 * PRIME32_2;\n    h32 := h32 xor (h32 shr 13);\n    h32 := h32 * PRIME32_3;\n    h32 := h32 xor (h32 shr 16);\n    result := h32;\nend;\n\nfunction XXH64_digest(statePtr: PXXH64_state_t): uint64;\nvar\n    state: PXXH_istate64_t;\n    p: pByte;\n    bEnd: pByte;\n    h64: uint64;\n    v1, v2, v3, v4: uint64;\n    k1: uint64;\nbegin\n    state := PXXH_istate64_t(statePtr);\n    p := @state.mem64;\n    bEnd := pByte(@state.mem64) + state.memsize;\n\n    if state.total_len >= 32 then\n    begin\n        v1 := state.v1;\n        v2 := state.v2;\n        v3 := state.v3;\n        v4 := state.v4;\n        h64 := XXH_rotl64(v1, 1) + XXH_rotl64(v2, 7) + XXH_rotl64(v3, 12) + XXH_rotl64(v4, 18);\n        v1 := v1 * PRIME64_2;\n        v1 := XXH_rotl64(v1, 31);\n        v1 := v1 * PRIME64_1;\n        h64 := h64 xor v1;\n        h64 := h64 * PRIME64_1 + PRIME64_4;\n\n        v2 := v2 * PRIME64_2;\n        v2 := XXH_rotl64(v2, 31);\n        v2 := v2 * PRIME64_1;\n        h64 := h64 xor v2;\n        h64 := h64 * PRIME64_1 + PRIME64_4;\n\n        v3 := v3 * PRIME64_2;\n        v3 := XXH_rotl64(v3, 31);\n        v3 := v3 * PRIME64_1;\n        h64 := h64 xor v3;\n        h64 := h64 * PRIME64_1 + PRIME64_4;\n\n        v4 := v4 * PRIME64_2;\n        v4 := XXH_rotl64(v4, 31);\n        v4 := v4 * PRIME64_1;\n        h64 := h64 xor v4;\n        h64 := h64 * PRIME64_1 + PRIME64_4;\n    end\n    else\n        h64 := state.seed + PRIME64_5;\n    inc(h64, state.total_len);\n\n    while (p + 8) <= bEnd do\n    begin\n        k1 := XXH_readLE64(p);\n        k1 := k1 * PRIME64_2;\n        k1 := XXH_rotl64(k1, 31);\n        k1 := k1 * PRIME64_1;\n        h64 := h64 xor k1;\n        h64 := XXH_rotl64(h64, 27) * PRIME64_1 + PRIME64_4;\n        inc(p, 8);\n    end;\n    if (p + 4) <= bEnd then\n    begin\n        h64 := h64 xor (uint64(XXH_readLE32(p)) * PRIME64_1);\n        h64 := XXH_rotl64(h64, 23) * PRIME64_2 + PRIME64_3;\n        inc(p, 4);\n    end;\n\n    while (p < bEnd) do\n    begin\n        h64 := h64 xor (p^ * PRIME64_5);\n        h64 := XXH_rotl64(h64, 11) * PRIME64_1;\n        inc(p);\n    end;\n\n    h64 := h64 xor (h64 shr 33);\n    h64 := h64 * PRIME64_2;\n    h64 := h64 xor (h64 shr 29);\n    h64 := h64 * PRIME64_3;\n    h64 := h64 xor (h64 shr 32);\n\n    result := h64;\nend;\n\nfunction XXH32_createState: PXXH32_state_t;\nbegin\n    result := allocmem(sizeof(XXH32_state_t));\nend;\n\nfunction XXH64_createState: PXXH64_state_t;\nbegin\n    result := allocmem(sizeof(XXH64_state_t));\nend;\n\nprocedure XXH32_freeState(statePtr: PXXH32_state_t);\nbegin\n    freemem(statePtr);\nend;\n\nprocedure XXH64_freeState(statePtr: PXXH64_state_t);\nbegin\n    freemem(statePtr);\nend;\n\nfunction XXH32_init(seed: cardinal): PXXH32_state_t;\nbegin\n    result := XXH32_createState;\n    XXH32_reset(result, seed);\nend;\n\nfunction XXH64_init(seed: uint64): PXXH64_state_t;\nbegin\n    result := XXH64_createState;\n    XXH64_reset(result, seed);\nend;\n\nfunction XXH32_endian_align(input: pointer; len: size_t; seed: cardinal; endian: XXH_endianess; align: XXH_alignment): cardinal;\n    function XXH_get32bits(p: pByte): cardinal;\n    begin\n        result := XXH_readLE32_align(p, endian, align);\n    end;\n\nvar\n    p: pByte;\n    bEnd: pByte;\n    h32: cardinal;\n    limit: pByte;\n    v1, v2, v3, v4: cardinal;\nbegin\n    p := input;\n    bEnd := p + len;\n    if (len >= 16) then\n    begin\n        limit := bEnd - 16;\n        v1 := seed + PRIME32_1 + PRIME32_2;\n        v2 := seed + PRIME32_2;\n        v3 := seed + 0;\n        v4 := seed - PRIME32_1;\n        while true do\n        begin\n            inc(v1, XXH_get32bits(p) * PRIME32_2);\n            v1 := XXH_rotl32(v1, 13);\n            v1 := v1 * PRIME32_1;\n            inc(p, 4);\n\n            inc(v2, XXH_get32bits(p) * PRIME32_2);\n            v2 := XXH_rotl32(v2, 13);\n            v2 := v2 * PRIME32_1;\n            inc(p, 4);\n\n            inc(v3, XXH_get32bits(p) * PRIME32_2);\n            v3 := XXH_rotl32(v3, 13);\n            v3 := v3 * PRIME32_1;\n            inc(p, 4);\n\n            inc(v4, XXH_get32bits(p) * PRIME32_2);\n            v4 := XXH_rotl32(v4, 13);\n            v4 := v4 * PRIME32_1;\n            inc(p, 4);\n            if p > limit then\n                break;\n        end;\n        h32 := XXH_rotl32(v1, 1) + XXH_rotl32(v2, 7) + XXH_rotl32(v3, 12) + XXH_rotl32(v4, 18);\n    end\n    else\n        h32 := seed + PRIME32_5;\n\n    inc(h32, cardinal(len));\n    while (p + 4 <= bEnd) do\n    begin\n        inc(h32, XXH_get32bits(p) * PRIME32_3);\n        h32 := XXH_rotl32(h32, 17) * PRIME32_4;\n        inc(p, 4);\n    end;\n\n    while (p < bEnd) do\n    begin\n        inc(h32, p^ * PRIME32_5);\n        h32 := XXH_rotl32(h32, 11) * PRIME32_1;\n        inc(p);\n    end;\n\n    h32 := h32 xor (h32 shr 15);\n    h32 := h32 * PRIME32_2;\n    h32 := h32 xor (h32 shr 13);\n    h32 := h32 * PRIME32_3;\n    h32 := h32 xor (h32 shr 16);\n\n    result := h32;\nend;\n\nfunction XXH32(input: pointer; len: size_t; seed: cardinal): cardinal;\nbegin\n    result := XXH32_endian_align(input, len, seed, XXH_littleEndian, XXH_unaligned);\nend;\n\nend.\n\n"
  },
  {
    "path": "lib/xedit/wbBSA.pas",
    "content": "{*******************************************************************************\n\n     The contents of this file are subject to the Mozilla Public License\n     Version 1.1 (the \"License\"); you may not use this file except in\n     compliance with the License. You may obtain a copy of the License at\n     http://www.mozilla.org/MPL/\n\n     Software distributed under the License is distributed on an \"AS IS\"\n     basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the\n     License for the specific language governing rights and limitations\n     under the License.\n\n*******************************************************************************}\n\nunit wbBSA;\n\n{$I wbDefines.inc}\n\ninterface\n\nuses\n  Classes, SysUtils, IOUtils,\n  wbInterface,\n  ImagingDds;\n\nfunction wbCreateContainerHandler: IwbContainerHandler;\n\nimplementation\n\nuses\n  wbStreams,\n  zlibEx,\n  lz4io;\n\nconst\n  { https://github.com/Ethatron/bsaopt/blob/master/io/bsa.C }\n  BSAHEADER_VERSION_OB = $67; // Oblivion\n  BSAHEADER_VERSION_SK = $68; // Fallout3, Skyrim\n  BSAHEADER_VERSION_SSE = $69; // Skyrim Special Edition\n  BSAARCHIVE_COMPRESSFILES = $0004; // Whether the files are compressed in archive (invert file's compression flag)\n  BSAARCHIVE_PREFIXFULLFILENAMES = $0100; // Whether the name is prefixed to the data?\n  BSAFILE_COMPRESS = $40000000; // Whether the file is compressed\n  { https://github.com/jonwd7/bae/blob/master/src/bsa.h }\n  BA2HEADER_VERSION_FO4 = $01; // Fallout 4\n\ntype\n  TwbContainerHandler = class(TInterfacedObject, IwbContainerHandler)\n  private\n    chContainers: array of IwbResourceContainer;\n  protected\n    procedure AddContainer(const aContainer: IwbResourceContainer);\n\n    {---IwbContainerHandler---}\n    procedure AddFolder(const aPath: string);\n    procedure AddBSA(const aFileName: string);\n    procedure AddBA2(const aFileName: string);\n\n    function OpenResource(const aFileName: string): TDynResources;\n    function OpenResourceData(const aContainerName, aFileName: string): TBytes;\n    function ContainerExists(aContainerName: string): Boolean;\n    procedure ContainerList(const aList: TStrings);\n    procedure ContainerResourceList(const aContainerName: string; const aList: TStrings;\n      const aFolder: string = '');\n    function ResourceExists(const aFileName: string): Boolean;\n    function ResolveHash(const aHash: Int64): TDynStrings;\n    function ResourceCount(const aFileName: string; aContainers: TStrings = nil): Integer;\n    procedure ResourceCopy(const aContainerName, aFileName, aPathOut: string);\n  end;\n\n  TwbBSAFileRec = record\n    Name   : string;\n    Hash   : Int64;\n    Size   : Cardinal;\n    Offset : Cardinal;\n  end;\n\n  TwbBSAFolderRec = record\n    Name  : string;\n    Hash  : Int64;\n    Files : array of TwbBSAFileRec;\n    Map   : TStringList;\n  end;\n\n  IwbBSAFileInternal = interface(IwbBSAFile)\n    ['{A360B348-8F6B-4FC1-A869-9D5B833DCA5F}']\n    function GetData(aOffset, aSize: Cardinal): TBytes;\n  end;\n\n  TwbBSAFile = class(TInterfacedObject, IwbResourceContainer, IwbBSAFile, IwbBSAFileInternal)\n  private\n    bfStream      : TwbReadOnlyCachedFileStream;\n    bfFileName    : string;\n    bfVersion     : Cardinal;\n    bfOffset      : Cardinal;\n    bfFlags       : Cardinal;\n    bfFileFlags   : Cardinal;\n    bfFolders     : array of TwbBSAFolderRec;\n    bfFolderMap   : TStringList;\n\n    procedure ReadDirectory;\n  protected\n    {---IwbResourceContainer---}\n    function GetName: string;\n    function OpenResource(const aFileName: string): IwbResource;\n    function ResourceExists(const aFileName: string): Boolean;\n    procedure ResourceList(const aList: TStrings; const aFolder: string = '');\n    procedure ResolveHash(const aHash: Int64; var Results: TDynStrings);\n\n    {---IwbBSAFile---}\n    function GetFileName: string;\n\n    {---IwbBSAFileInternal---}\n    function GetData(aOffset, aSize: Cardinal):TBytes;\n  public\n    constructor Create(const aFileName: string);\n    destructor Destroy; override;\n  end;\n\n  TwbBSAResource = class(TInterfacedObject, IwbResource)\n    brFile   : IwbBSAFileInternal;\n    brOffset : Cardinal;\n    brSize   : Cardinal;\n  protected\n    {---IwbResource---}\n    function GetContainer: IwbResourceContainer;\n    function GetData: TBytes;\n  public\n    constructor Create(aFile: TwbBSAFile; aSize, aOffset: Cardinal);\n  end;\n\n\n  TwbBA2TexChunkRec = record\n    Size       : Cardinal;\n    PackedSize : Cardinal;\n    Offset     : Int64;\n    StartMip   : Word;\n    EndMip     : Word;\n  end;\n\n  TwbBA2FileRec = record\n    Name       : string;\n    NameHash   : Cardinal;\n    DirHash    : Cardinal;\n    Size       : Cardinal;\n    PackedSize : Cardinal;\n    Offset     : Int64;\n    Height     : Word;\n    Width      : Word;\n    NumMips    : Byte;\n    DXGIFormat : Byte;\n    CubeMaps   : Word;\n    TexChunks  : array of TwbBA2TexChunkRec;\n  end;\n\n  IwbBA2FileInternal = interface(IwbBA2File)\n    ['{87D66150-746E-4B37-B295-45C4221CDCBE}']\n    procedure ReadData(var Buffer; Offset: Int64; Count: Longint);\n  end;\n\n  TwbBA2File = class(TInterfacedObject, IwbResourceContainer, IwbBA2File, IwbBA2FileInternal)\n  private\n    bfStream      : TwbReadOnlyCachedFileStream;\n    bfFileName    : string;\n    bfVersion     : Cardinal;\n    bfType        : TwbSignature;\n    bfFiles       : array of TwbBA2FileRec;\n    bfFolderMap   : TStringList;\n\n    procedure ReadDirectory;\n  protected\n    {---IwbResourceContainer---}\n    function GetName: string;\n    function OpenResource(const aFileName: string): IwbResource;\n    function ResourceExists(const aFileName: string): Boolean;\n    procedure ResourceList(const aList: TStrings; const aFolder: string = '');\n    procedure ResolveHash(const aHash: Int64; var Results: TDynStrings);\n\n    {---IwbBA2File---}\n    function GetFileName: string;\n\n    {---IwbBA2FileInternal---}\n    procedure ReadData(var Buffer; Offset: Int64; Count: Longint);\n  public\n    constructor Create(const aFileName: string);\n    destructor Destroy; override;\n  end;\n\n  TwbBA2Resource = class(TInterfacedObject, IwbResource)\n    brFile    : IwbBA2FileInternal;\n    brFileRec : TwbBA2FileRec;\n  protected\n    {---IwbResource---}\n    function GetContainer: IwbResourceContainer;\n    function GetData: TBytes;\n  public\n    constructor Create(aFile: TwbBA2File; var aFileRec: TwbBA2FileRec);\n  end;\n\n\n  IwbFolderInternal = interface(IwbFolder)\n    ['{6DF2B964-5AF7-4732-BD28-CD7600407A83}']\n  end;\n\n  TwbFolder = class(TInterfacedObject, IwbResourceContainer, IwbFolder, IwbFolderInternal)\n  private\n    fPath : string;\n  protected\n    {---IwbResourceContainer---}\n    function GetName: string;\n    function OpenResource(const aFileName: string): IwbResource;\n    function ResourceExists(const aFileName: string): Boolean;\n    procedure ResourceList(const aList: TStrings; const aFolder: string = '');\n    procedure ResolveHash(const aHash: Int64; var Results: TDynStrings);\n\n    {---IwbFolder---}\n    function GetPathName: string;\n  public\n    constructor Create(const aPath: string);\n    destructor Destroy; override;\n  end;\n\n  TwbFolderResource = class(TInterfacedObject, IwbResource)\n    frFolder   : IwbFolderInternal;\n    frFileName : string;\n  protected\n    {---IwbResource---}\n    function GetContainer: IwbResourceContainer;\n    function GetData: TBytes;\n  public\n    constructor Create(aFolder: IwbFolderInternal; const aFileName: string);\n    destructor Destroy; override;\n  end;\n\n\nfunction wbCreateContainerHandler: IwbContainerHandler;\nbegin\n  Result := TwbContainerHandler.Create;\nend;\n\n{ TwbContainerHandler }\n\nprocedure TwbContainerHandler.AddContainer(const aContainer: IwbResourceContainer);\nbegin\n  SetLength(chContainers, Succ(Length(chContainers)));\n  chContainers[High(chContainers)] := aContainer;\nend;\n\nfunction TwbContainerHandler.ContainerExists(aContainerName: string): Boolean;\nvar\n  i: Integer;\nbegin\n  Result := True;\n  for i := Low(chContainers) to High(chContainers) do\n    if SameText(chContainers[i].Name, aContainerName) then\n      Exit;\n  Result := False;\nend;\n\nprocedure TwbContainerHandler.AddBSA(const aFileName: string);\nbegin\n  if not ContainerExists(aFileName) then\n    AddContainer(TwbBSAFile.Create(aFileName));\nend;\n\nprocedure TwbContainerHandler.AddBA2(const aFileName: string);\nbegin\n  if not ContainerExists(aFileName) then\n    AddContainer(TwbBA2File.Create(aFileName));\nend;\n\nprocedure TwbContainerHandler.AddFolder(const aPath: string);\nbegin\n  if not ContainerExists(aPath) then\n    AddContainer(TwbFolder.Create(aPath));\nend;\n\nfunction TwbContainerHandler.OpenResource(const aFileName: string): TDynResources;\nvar\n  i, j: Integer;\nbegin\n  SetLength(Result, Length(chContainers));\n  j := 0;\n  for i := Low(chContainers) to High(chContainers) do begin\n    Result[j] := chContainers[i].OpenResource(aFileName);\n    if Assigned(Result[j]) then\n      Inc(j);\n  end;\n  SetLength(Result, j);\nend;\n\nfunction TwbContainerHandler.OpenResourceData(const aContainerName, aFileName: string): TBytes;\nvar\n  Res : TDynResources;\n  i   : Integer;\nbegin\n  Res := OpenResource(aFileName);\n\n  if Length(Res) = 0 then\n    Exit;\n\n  for i := High(Res) downto Low(Res) do\n    if (aContainerName = '') or SameText(Res[i].Container.Name, aContainerName) then begin\n      Result := Res[i].GetData;\n      Break;\n    end;\nend;\n\nprocedure TwbContainerHandler.ContainerList(const aList: TStrings);\nvar\n  i: Integer;\nbegin\n  if not Assigned(aList) then\n    Exit;\n\n  for i := Low(chContainers) to High(chContainers) do\n    aList.Add(chContainers[i].Name);\nend;\n\nprocedure TwbContainerHandler.ContainerResourceList(const aContainerName: string; const aList: TStrings;\n  const aFolder: string = '');\nvar\n  i: Integer;\nbegin\n  for i := Low(chContainers) to High(chContainers) do\n    if SameText(chContainers[i].Name, aContainerName) then begin\n      chContainers[i].ResourceList(aList, aFolder);\n      Break;\n    end;\nend;\n\nfunction TwbContainerHandler.ResourceExists(const aFileName: string): Boolean;\nvar\n  i: Integer;\nbegin\n  Result := False;\n  for i := Low(chContainers) to High(chContainers) do\n    if chContainers[i].ResourceExists(aFileName) then begin\n      Result := True;\n      Exit;\n    end;\nend;\n\nfunction TwbContainerHandler.ResolveHash(const aHash: Int64): TDynStrings;\nvar\n  i: Integer;\nbegin\n  Result := nil;\n  for i := Low(chContainers) to High(chContainers) do\n    chContainers[i].ResolveHash(aHash, Result);\nend;\n\nfunction TwbContainerHandler.ResourceCount(const aFileName: string; aContainers: TStrings = nil): Integer;\nvar\n  i: Integer;\nbegin\n  Result := 0;\n  for i := Low(chContainers) to High(chContainers) do\n    if chContainers[i].ResourceExists(aFileName) then begin\n      Inc(Result);\n      if Assigned(aContainers) then\n        aContainers.Add(chContainers[i].Name);\n    end;\nend;\n\nprocedure TwbContainerHandler.ResourceCopy(const aContainerName, aFileName, aPathOut: string);\nvar\n  fn, dir    : string;\n  aData      : TBytes;\n  res        : TDynResources;\n  i, residx  : integer;\nbegin\n  if aPathOut = '' then\n    raise Exception.Create('Destination path is not specified');\n\n  res := OpenResource(aFileName);\n\n  if Length(res) = 0 then\n    raise Exception.Create('Resource doesn''t exist');\n\n  residx := High(res);\n  for i := High(res) to Low(res) do\n    if (aContainerName = '') or SameText(res[i].Container.Name, aContainerName) then begin\n      residx := i;\n      Break;\n    end;\n\n  // file name is provided instead of path\n  if TPath.HasExtension(aPathOut) then\n    fn := aPathOut\n  // destination path is provided\n  else\n    fn := IncludeTrailingPathDelimiter(aPathOut) + aFileName;\n\n  // create distination directory\n  dir := ExtractFilePath(fn);\n  if not DirectoryExists(dir) then\n    if not ForceDirectories(dir) then\n      raise Exception.Create('Unable to create destination directory ' + dir);\n\n  // direct copy if file is loose, with overwriting\n  if ExtractFileExt(res[residx].Container.Name) = '' then begin\n    TFile.Copy(res[residx].Container.Name + aFileName, fn, True);\n  end\n  // otherwise extract from BSA\n  else begin\n    aData := res[residx].GetData;\n    // exception handled outside\n    with TFileStream.Create(fn, fmCreate) do try\n      WriteBuffer(aData[0], Length(aData));\n    finally\n      Free;\n    end;\n  end;\nend;\n\n\n{ TwbBSAFile }\n\nconstructor TwbBSAFile.Create(const aFileName: string);\nbegin\n  bfFileName := aFileName;\n  bfStream := TwbReadOnlyCachedFileStream.Create(aFileName);\n  ReadDirectory;\nend;\n\ndestructor TwbBSAFile.Destroy;\nvar\n  i: Integer;\nbegin\n  FreeAndNil(bfStream);\n  for i := Low(bfFolders) to High(bfFolders) do with bfFolders[i] do\n    FreeAndNil(Map);\n  FreeAndNil(bfFolderMap);\n  inherited;\nend;\n\nfunction TwbBSAFile.GetData(aOffset, aSize: Cardinal): TBytes;\nvar\n  IsCompressed : Boolean;\n  Buffer       : TBytes;\nbegin\n  IsCompressed := (aSize and BSAFILE_COMPRESS) <> 0;\n  if IsCompressed then\n    aSize := aSize and not BSAFILE_COMPRESS;\n  if (bfFlags and BSAARCHIVE_COMPRESSFILES) <> 0 then\n    IsCompressed := not IsCompressed;\n  bfStream.Position := aOffset;\n  if (bfVersion >= BSAHEADER_VERSION_SK) and ((bfFlags and BSAARCHIVE_PREFIXFULLFILENAMES) <> 0) then\n    // size - file name length (no terminator) - string length prefix\n    aSize := aSize - Length(bfStream.ReadStringLen(False)) - 1;\n  if IsCompressed then begin\n    SetLength(Result, bfStream.ReadCardinal);\n    aSize := aSize - 4;\n    if (Length(Result) > 0) and (aSize > 0) then begin\n      SetLength(Buffer, aSize);\n      bfStream.ReadBuffer(Buffer[0], Length(Buffer));\n      if bfVersion = BSAHEADER_VERSION_SSE then\n        lz4DecompressToUserBuf(@Buffer[0], Length(Buffer), @Result[0], Length(Result))\n      else\n        DecompressToUserBuf(@Buffer[0], Length(Buffer), @Result[0], Length(Result));\n    end;\n  end else begin\n    SetLength(Result, aSize);\n    if aSize > 0 then\n      bfStream.ReadBuffer(Result[0], aSize);\n  end;\nend;\n\nfunction TwbBSAFile.GetFileName: string;\nbegin\n  Result := bfFileName;\nend;\n\nfunction TwbBSAFile.GetName: string;\nbegin\n  Result := GetFileName;\nend;\n\nfunction TwbBSAFile.OpenResource(const aFileName: string): IwbResource;\nvar\n  lPath, lName: string;\n  i, j: Integer;\nbegin\n  Result := nil;\n  lPath := ExtractFilePath(aFileName);\n  SetLength(lPath, Pred(Length(lPath)));\n  lName := ExtractFileName(aFileName);\n  if bfFolderMap.Find(lPath, i) then\n    with bfFolders[Integer(bfFolderMap.Objects[i])] do\n      if Map.Find(lName, j) then\n        with Files[Integer(Map.Objects[j])] do\n          Result := TwbBSAResource.Create(Self, Size, Offset);\nend;\n\nfunction TwbBSAFile.ResourceExists(const aFileName: string): Boolean;\nvar\n  lPath, lName: string;\n  i: Integer;\nbegin\n  Result := False;\n  lPath := ExtractFilePath(aFileName);\n  SetLength(lPath, Pred(Length(lPath)));\n  lName := ExtractFileName(aFileName);\n  if bfFolderMap.Find(lPath, i) then\n    Result := bfFolders[Integer(bfFolderMap.Objects[i])].Map.IndexOf(lName) <> -1;\nend;\n\nprocedure TwbBSAFile.ResourceList(const aList: TStrings; const aFolder: string = '');\nvar\n  i, j: Integer;\n  Folder: string;\nbegin\n  if not Assigned(aList) then\n    Exit;\n  Folder := ExcludeTrailingPathDelimiter(aFolder);\n  for i := Low(bfFolders) to High(bfFolders) do with bfFolders[i] do\n    if (aFolder = '') or SameText(Folder, Name) then\n      for j := Low(Files) to High(Files) do\n        aList.Add(Name + '\\' + Files[j].Name);\nend;\n\nprocedure TwbBSAFile.ReadDirectory;\nvar\n  i, j   : Integer;\n  OldPos : Int64;\n  NewPos : Int64;\n//  FileCount : Cardinal;\n//  totalFolderNameLength : Cardinal;\n  totalFileNameLength : Cardinal;\nbegin\n  if bfStream.ReadSignature <> 'BSA' then\n    raise Exception.Create(bfFileName + ' is not a valid BSA file');\n  bfVersion := bfStream.ReadCardinal;\n  if not (bfVersion in [BSAHEADER_VERSION_OB, BSAHEADER_VERSION_SK, BSAHEADER_VERSION_SSE]) then\n    raise Exception.Create(bfFileName + ' has unknown version: ' + IntToStr(bfVersion) );\n  bfOffset := bfStream.ReadCardinal;\n  if bfOffset <> $24 then\n    raise Exception.Create(bfFileName + ' has unexpected Offset: ' + IntToStr(bfOffset) );\n  bfFlags := bfStream.ReadCardinal;\n  SetLength(bfFolders, bfStream.ReadCardinal);\n  {FileCount := } bfStream.ReadCardinal; //skip file count\n  {totalFolderNameLength := } bfStream.ReadCardinal; //skip totalFolderNameLength\n  totalFileNameLength := bfStream.ReadCardinal; //skip totalFileNameLength\n  bfFileFlags := bfStream.ReadCardinal;\n  OldPos := bfStream.Position;\n  for i := Low(bfFolders) to High(bfFolders) do with bfFolders[i] do begin\n    bfStream.Position := OldPos;\n    Hash := bfStream.ReadInt64; // skip hash\n    SetLength(Files, bfStream.ReadCardinal);\n    if bfVersion = BSAHEADER_VERSION_SSE then begin\n      bfStream.ReadCardinal; // skip unk32\n      NewPos := bfStream.ReadInt64;\n    end else\n      NewPos := bfStream.ReadCardinal;\n    OldPos := bfStream.Position;\n    bfStream.Position := NewPos - totalFileNameLength;\n    Name := bfStream.ReadStringLen;\n    for j := Low(Files) to High(Files) do with Files[j] do begin\n      Hash := bfStream.ReadInt64; // skip hash\n      Size := bfStream.ReadCardinal;\n      Offset := bfStream.ReadCardinal;\n    end;\n  end;\n  bfFolderMap := TwbFastStringList.Create;\n  for i := Low(bfFolders) to High(bfFolders) do with bfFolders[i] do begin\n    bfFolderMap.AddObject(Name, TObject(i));\n    Map := TwbFastStringList.Create;\n    for j := Low(Files) to High(Files) do with Files[j] do begin\n      Name := bfStream.ReadStringTerm;\n      Map.AddObject(Name, TObject(j));\n    end;\n    Map.Sorted := True;\n  end;\n  bfFolderMap.Sorted := True;\nend;\n\nprocedure TwbBSAFile.ResolveHash(const aHash: Int64; var Results: TDynStrings);\nvar\n  i, j: Integer;\nbegin\n  for i := Low(bfFolders) to High(bfFolders) do with bfFolders[i] do begin\n    if Hash = aHash then begin\n      SetLength(Results, Succ(Length(Results)));\n      Results[High(Results)] := Name;\n    end;\n    for j := Low(Files) to High(Files) do with Files[j] do begin\n      if Hash = aHash then begin\n        SetLength(Results, Succ(Length(Results)));\n        Results[High(Results)] := Name;\n      end;\n    end;\n  end;\nend;\n\n{ TwbBSAResource }\n\nconstructor TwbBSAResource.Create(aFile: TwbBSAFile; aSize, aOffset: Cardinal);\nbegin\n  brFile := aFile;\n  brOffset := aOffset;\n  brSize := aSize;\nend;\n\nfunction TwbBSAResource.GetContainer: IwbResourceContainer;\nbegin\n  Result := brFile;\nend;\n\nfunction TwbBSAResource.GetData: TBytes;\nbegin\n  Result := brFile.GetData(brOffset, brSize);\nend;\n\n\n{ TwbBA2File }\n\nconstructor TwbBA2File.Create(const aFileName: string);\nbegin\n  bfFileName := aFileName;\n  bfStream := TwbReadOnlyCachedFileStream.Create(aFileName);\n  ReadDirectory;\nend;\n\ndestructor TwbBA2File.Destroy;\nvar\n  i: integer;\nbegin\n  FreeAndNil(bfStream);\n  for i := 0 to Pred(bfFolderMap.Count) do\n    TStringList(bfFolderMap.Objects[i]).Free;\n  FreeAndNil(bfFolderMap);\n  inherited;\nend;\n\nprocedure TwbBA2File.ReadDirectory;\nvar\n  i, j   : Integer;\n  OldPos : Int64;\n  FileCount : Cardinal;\n  FileTablePosition: Int64;\n  NumChunks: Byte;\n  folder: string;\nbegin\n  if bfStream.ReadSignature <> 'BTDX' then\n    raise Exception.Create(bfFileName + ' is not a valid BA2 file');\n  bfVersion := bfStream.ReadCardinal;\n  if bfVersion <> BA2HEADER_VERSION_FO4 then\n    raise Exception.Create(bfFileName + ' has unknown version: ' + IntToStr(bfVersion) );\n  bfType := bfStream.ReadSignature;\n  if (bfType <> 'GNRL') and (bfType <> 'DX10') then\n    raise Exception.Create(bfFileName + ' has unknown type: ' + String(bfType));\n  FileCount := bfStream.ReadCardinal;\n  FileTablePosition := bfStream.ReadInt64;\n  OldPos := bfStream.Position;\n  bfStream.Position := FileTablePosition;\n  SetLength(bfFiles, FileCount);\n  for i := Low(bfFiles) to High(bfFiles) do begin\n    bfFiles[i].Name := bfStream.ReadStringLen16;\n  end;\n  bfStream.Position := OldPos;\n\n  if bfType = 'GNRL' then begin\n    for i := Low(bfFiles) to High(bfFiles) do begin\n      bfFiles[i].NameHash := bfStream.ReadCardinal;\n      bfStream.ReadCardinal; // skip ext\n      bfFiles[i].DirHash := bfStream.ReadCardinal;\n      bfStream.ReadCardinal; // skip unk0C\n      bfFiles[i].Offset := bfStream.ReadInt64;\n      bfFiles[i].PackedSize := bfStream.ReadCardinal;\n      bfFiles[i].Size := bfStream.ReadCardinal;\n      bfStream.ReadCardinal; // skip BAADF00D\n    end;\n  end\n  else if bfType = 'DX10' then begin\n    for i := Low(bfFiles) to High(bfFiles) do begin\n      bfFiles[i].NameHash := bfStream.ReadCardinal;\n      bfStream.ReadCardinal; // skip ext\n      bfFiles[i].DirHash := bfStream.ReadCardinal;\n      bfStream.ReadByte; // skip unk0C\n      NumChunks := bfStream.ReadByte;\n      bfStream.ReadWord; // skip chunkHeaderSize\n      bfFiles[i].Height := bfStream.ReadWord;\n      bfFiles[i].Width := bfStream.ReadWord;\n      bfFiles[i].NumMips := bfStream.ReadByte;\n      bfFiles[i].DXGIFormat := bfStream.ReadByte;\n      bfFiles[i].CubeMaps := bfStream.ReadWord;\n      SetLength(bfFiles[i].TexChunks, NumChunks);\n      for j := Low(bfFiles[i].TexChunks) to High(bfFiles[i].TexChunks) do\n        with bfFiles[i].TexChunks[j] do begin\n          Offset := bfStream.ReadInt64;\n          PackedSize := bfStream.ReadCardinal;\n          Size := bfStream.ReadCardinal;\n          StartMip := bfStream.ReadWord;\n          EndMip := bfStream.ReadWord;\n          bfStream.ReadCardinal; // skip BAADF00D\n        end;\n    end;\n  end;\n\n  bfFolderMap := TwbFastStringList.Create;\n  bfFolderMap.Sorted := True;\n  for i := Low(bfFiles) to High(bfFiles) do begin\n    folder := LowerCase(ExtractFilePath(bfFiles[i].Name));\n    SetLength(folder, Pred(Length(folder)));\n    j := bfFolderMap.IndexOf(folder);\n    if not bfFolderMap.Find(folder, j) then begin\n      bfFolderMap.AddObject(folder, TwbFastStringList.Create);\n      if not bfFolderMap.Find(folder, j) then\n        raise Exception.Create('Indexing error');\n    end;\n    TStringList(bfFolderMap.Objects[j]).AddObject(LowerCase(ExtractFileName(bfFiles[i].Name)), TObject(i));\n  end;\n  for i := 0 to Pred(bfFolderMap.Count) do\n    TStringList(bfFolderMap.Objects[i]).Sorted := True;\nend;\n\nfunction TwbBA2File.GetFileName: string;\nbegin\n  Result := bfFileName;\nend;\n\nfunction TwbBA2File.GetName: string;\nbegin\n  Result := GetFileName;\nend;\n\nprocedure TwbBA2File.ReadData(var Buffer; Offset: Int64; Count: Longint);\nbegin\n  bfStream.Position := Offset;\n  bfStream.ReadBuffer(Buffer, Count);\nend;\n\nfunction TwbBA2File.OpenResource(const aFileName: string): IwbResource;\nvar\n  lPath, lName: string;\n  i, j: Integer;\nbegin\n  lPath := LowerCase(ExtractFilePath(aFileName));\n  SetLength(lPath, Pred(Length(lPath)));\n  lName := LowerCase(ExtractFileName(aFileName));\n  if bfFolderMap.Find(lPath, i) then with TStringList(bfFolderMap.Objects[i]) do\n    if Find(lName, j) then\n      Result := TwbBA2Resource.Create(Self, bfFiles[Integer(Objects[j])]);\nend;\n\nprocedure TwbBA2File.ResolveHash(const aHash: Int64; var Results: TDynStrings);\nbegin\n  // ...\nend;\n\nfunction TwbBA2File.ResourceExists(const aFileName: string): Boolean;\nvar\n  lPath, lName: string;\n  i: Integer;\nbegin\n  Result := False;\n  lPath := LowerCase(ExtractFilePath(aFileName));\n  SetLength(lPath, Pred(Length(lPath)));\n  lName := LowerCase(ExtractFileName(aFileName));\n  if bfFolderMap.Find(lPath, i) then\n    Result := TStringList(bfFolderMap.Objects[i]).IndexOf(lName) <> -1;\nend;\n\nprocedure TwbBA2File.ResourceList(const aList: TStrings; const aFolder: string = '');\nvar\n  i: Integer;\nbegin\n  if not Assigned(aList) then\n    Exit;\n  for i := Low(bfFiles) to High(bfFiles) do\n    aList.Add(LowerCase(bfFiles[i].Name));\nend;\n\n\n{ TwbBA2Resource }\n\nconstructor TwbBA2Resource.Create(aFile: TwbBA2File; var aFileRec: TwbBA2FileRec);\nbegin\n  brFile := aFile;\n  brFileRec := aFileRec;\nend;\n\nfunction TwbBA2Resource.GetContainer: IwbResourceContainer;\nbegin\n  Result := brFile;\nend;\n\nfunction TwbBA2Resource.GetData: TBytes;\nconst\n  FOURCC_BC7 = LongWord(Byte('B') or (Byte('C') shl 8) or (Byte('7') shl 16) or\n    (Byte(0) shl 24));\nvar\n  Buffer       : TBytes;\n  Hdr: ^TDDSFileHeader;\n  TexSize, i: integer;\nbegin\n  // GNRL resource\n  if (brFileRec.Size <> 0) and (Length(brFileRec.TexChunks) = 0) then begin\n    if brFileRec.PackedSize <> 0 then begin\n      SetLength(Buffer, brFileRec.PackedSize);\n      brFile.ReadData(Buffer[0], brFileRec.Offset, Length(Buffer));\n      SetLength(Result, brFileRec.Size);\n      DecompressToUserBuf(@Buffer[0], Length(Buffer), @Result[0], Length(Result));\n    end\n    else begin\n      SetLength(Result, brFileRec.Size);\n      brFile.ReadData(Result[0], brFileRec.Offset, Length(Result));\n    end;\n  end\n  // DX10 texture\n  else if Length(brFileRec.TexChunks) <> 0 then begin\n    // calculate texture size including header\n    TexSize := SizeOf(TDDSFileHeader);\n    for i := Low(brFileRec.TexChunks) to High(brFileRec.TexChunks) do\n      Inc(TexSize, brFileRec.TexChunks[i].Size);\n    SetLength(Result, TexSize);\n    // fill DDS header\n    Hdr := @Result[0];\n    hdr.Magic := DDSMagic;\n    hdr.Desc.Size := SizeOf(hdr.Desc);\n    hdr.Desc.Width := brFileRec.Width;\n    hdr.Desc.Height := brFileRec.Height;\n    hdr.Desc.Flags := DDS_SAVE_FLAGS or DDSD_MIPMAPCOUNT;\n    hdr.Desc.Caps.Caps1 := DDSCAPS_TEXTURE or DDSCAPS_MIPMAP;\n    hdr.Desc.MipMaps := brFileRec.NumMips;\n    if brFileRec.CubeMaps = 2049 then\n      hdr.Desc.Caps.Caps2 := DDSCAPS2_POSITIVEX or DDSCAPS2_NEGATIVEX\n                          or DDSCAPS2_POSITIVEY or DDSCAPS2_NEGATIVEY\n                          or DDSCAPS2_POSITIVEZ or DDSCAPS2_NEGATIVEZ\n                          or DDSCAPS2_CUBEMAP;\n    hdr.Desc.PixelFormat.Size := SizeOf(hdr.Desc.PixelFormat);\n    case TDXGIFormat(brFileRec.DXGIFormat) of\n      DXGI_FORMAT_BC1_UNORM: begin\n        hdr.Desc.PixelFormat.Flags := DDPF_FOURCC;\n        hdr.Desc.PixelFormat.FourCC := FOURCC_DXT1;\n        hdr.Desc.PitchOrLinearSize := brFileRec.Width * brFileRec.Height div 4;\n      end;\n      DXGI_FORMAT_BC2_UNORM: begin\n        hdr.Desc.PixelFormat.Flags := DDPF_FOURCC;\n        hdr.Desc.PixelFormat.FourCC := FOURCC_DXT3;\n        hdr.Desc.PitchOrLinearSize := brFileRec.Width * brFileRec.Height;\n      end;\n      DXGI_FORMAT_BC3_UNORM: begin\n        hdr.Desc.PixelFormat.Flags := DDPF_FOURCC;\n        hdr.Desc.PixelFormat.FourCC := FOURCC_DXT5;\n        hdr.Desc.PitchOrLinearSize := brFileRec.Width * brFileRec.Height;\n      end;\n      DXGI_FORMAT_BC5_UNORM: begin\n        hdr.Desc.PixelFormat.Flags := DDPF_FOURCC;\n        hdr.Desc.PixelFormat.FourCC := FOURCC_ATI2;\n        hdr.Desc.PitchOrLinearSize := brFileRec.Width * brFileRec.Height;\n      end;\n      DXGI_FORMAT_BC7_UNORM: begin\n        hdr.Desc.PixelFormat.Flags := DDPF_FOURCC;\n        hdr.Desc.PixelFormat.FourCC := FOURCC_BC7;\n        hdr.Desc.PitchOrLinearSize := brFileRec.Width * brFileRec.Height;\n      end;\n      DXGI_FORMAT_B8G8R8A8_UNORM: begin\n        hdr.Desc.PixelFormat.Flags := DDPF_RGB;\n        hdr.Desc.PixelFormat.BitCount := 32;\n        hdr.Desc.PixelFormat.RedMask   := $00FF0000;\n        hdr.Desc.PixelFormat.GreenMask := $0000FF00;\n        hdr.Desc.PixelFormat.BlueMask  := $000000FF;\n        hdr.Desc.PitchOrLinearSize := brFileRec.Width * brFileRec.Height * 4;\n      end;\n      DXGI_FORMAT_R8_UNORM: begin\n        hdr.Desc.PixelFormat.Flags := DDPF_RGB;\n        hdr.Desc.PixelFormat.BitCount := 8;\n        hdr.Desc.PixelFormat.RedMask   := $FF;\n        hdr.Desc.PitchOrLinearSize := brFileRec.Width * brFileRec.Height;\n      end;\n    end;\n    // append chunks\n    TexSize := SizeOf(TDDSFileHeader);\n    for i := Low(brFileRec.TexChunks) to High(brFileRec.TexChunks) do with brFileRec.TexChunks[i] do begin\n      // compressed chunk\n      if PackedSize <> 0 then begin\n        SetLength(Buffer, PackedSize);\n        brFile.ReadData(Buffer[0], Offset, Length(Buffer));\n        DecompressToUserBuf(@Buffer[0], Length(Buffer), @Result[TexSize], Size);\n      end\n      // uncompressed chunk\n      else\n        brFile.ReadData(Result[TexSize], Offset, Size);\n      Inc(TexSize, Size);\n    end;\n  end;\nend;\n\n\n{ TwbFolder }\n\nconstructor TwbFolder.Create(const aPath: string);\nbegin\n  fPath := IncludeTrailingPathDelimiter(aPath);\nend;\n\ndestructor TwbFolder.Destroy;\nbegin\n\n  inherited;\nend;\n\nfunction TwbFolder.GetPathName: string;\nbegin\n  Result := fPath;\nend;\n\nfunction TwbFolder.GetName: string;\nbegin\n  Result := GetPathName;\nend;\n\nfunction TwbFolder.OpenResource(const aFileName: string): IwbResource;\nvar\n  s: string;\nbegin\n  s := fPath + aFileName;\n  if FileExists(s) then\n    Result := TwbFolderResource.Create(Self, s);\nend;\n\nfunction TwbFolder.ResourceExists(const aFileName: string): Boolean;\nbegin\n  Result := FileExists(fPath + aFileName);\nend;\n\nprocedure TwbFolder.ResourceList(const aList: TStrings; const aFolder: string = '');\nvar\n  FileName: string;\nbegin\n  if not Assigned(aList) then\n    Exit;\n  if TDirectory.Exists(fPath + aFolder) then\n    for FileName in TDirectory.GetFiles(fPath + aFolder, '*.*', TSearchOption.soAllDirectories) do\n      aList.Add(LowerCase(Copy(FileName, Length(fPath) + 1, Length(FileName))));\nend;\n\nprocedure TwbFolder.ResolveHash(const aHash: Int64; var Results: TDynStrings);\nbegin\n  //...\nend;\n\n{ TwbFolderResource }\n\nconstructor TwbFolderResource.Create(aFolder: IwbFolderInternal; const aFileName: string);\nbegin\n  frFolder := aFolder;\n  frFileName := aFileName;\nend;\n\ndestructor TwbFolderResource.Destroy;\nbegin\n\n  inherited;\nend;\n\nfunction TwbFolderResource.GetContainer: IwbResourceContainer;\nbegin\n  Result := frFolder;\nend;\n\nfunction TwbFolderResource.GetData: TBytes;\nbegin\n  with TFileStream.Create(frFileName, fmOpenRead or fmShareDenyWrite) do try\n    SetLength(Result, Size);\n    if Length(Result) > 0 then\n      ReadBuffer(Result[0], Length(Result));\n  finally\n    Free;\n  end;\nend;\n\nend.\n"
  },
  {
    "path": "lib/xedit/wbDefines.inc",
    "content": "{*******************************************************************************\n\n     The contents of this file are subject to the Mozilla Public License\n     Version 1.1 (the \"License\"); you may not use this file except in\n     compliance with the License. You may obtain a copy of the License at\n     http://www.mozilla.org/MPL/\n\n     Software distributed under the License is distributed on an \"AS IS\"\n     basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the\n     License for the specific language governing rights and limitations\n     under the License.\n\n*******************************************************************************}\n\n{.$DEFINE USE_CODESITE}"
  },
  {
    "path": "lib/xedit/wbDefinitionsFNV.pas",
    "content": "{*******************************************************************************\n\n     The contents of this file are subject to the Mozilla Public License\n     Version 1.1 (the \"License\"); you may not use this file except in\n     compliance with the License. You may obtain a copy of the License at\n     http://www.mozilla.org/MPL/\n\n     Software distributed under the License is distributed on an \"AS IS\"\n     basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the\n     License for the specific language governing rights and limitations\n     under the License.\n\n*******************************************************************************}\n\nunit wbDefinitionsFNV;\n\n{$I wbDefines.inc}\n\ninterface\n\nuses\n  wbInterface;\n\nvar\n\twbAggroRadiusFlags: IwbFlagsDef;\n\twbPKDTFlags: IwbFlagsDef;\n\twbRecordFlagsFlags: IwbFlagsDef;\n\twbServiceFlags: IwbFlagsDef;\n\twbTemplateFlags: IwbFlagsDef;\n\n\twbAgressionEnum: IwbEnumDef;\n\twbAlignmentEnum: IwbEnumDef;\n\twbArchtypeEnum: IwbEnumDef;\n\twbAssistanceEnum: IwbEnumDef;\n\twbAttackAnimationEnum: IwbEnumDef;\n\twbAxisEnum: IwbEnumDef;\n\twbBlendModeEnum: IwbEnumDef;\n\twbBlendOpEnum: IwbEnumDef;\n\twbBodyLocationEnum: IwbEnumDef;\n\twbBodyPartIndexEnum: IwbEnumDef;\n\twbConfidenceEnum: IwbEnumDef;\n\twbCreatureTypeEnum: IwbEnumDef;\n\twbCrimeTypeEnum: IwbEnumDef;\n\twbCriticalStageEnum: IwbEnumDef;\n\twbEquipTypeEnum: IwbEnumDef;\n\twbFormTypeEnum: IwbEnumDef;\n\twbFunctionsEnum: IwbEnumDef;\n\twbHeadPartIndexEnum: IwbEnumDef;\n\twbImpactMaterialTypeEnum: IwbEnumDef;\n\twbMenuModeEnum: IwbEnumDef;\n\twbMiscStatEnum: IwbEnumDef;\n\twbModEffectEnum: IwbEnumDef;\n\twbMoodEnum: IwbEnumDef;\n\twbMusicEnum: IwbEnumDef;\n\twbObjectTypeEnum: IwbEnumDef;\n\twbPKDTType: IwbEnumDef;\n\twbPlayerActionEnum: IwbEnumDef;\n\twbQuadrantEnum: IwbEnumDef;\n\twbReloadAnimEnum: IwbEnumDef;\n\twbSexEnum: IwbEnumDef;\n\twbSkillEnum: IwbEnumDef;\n\twbSoundLevelEnum: IwbEnumDef;\n\twbSpecializationEnum: IwbEnumDef;\n\twbVatsValueFunctionEnum: IwbEnumDef;\n\twbWeaponAnimTypeEnum: IwbEnumDef;\n\twbZTestFuncEnum: IwbEnumDef;\n\nfunction wbCreaLevelDecider(aBasePtr: Pointer; aEndPtr: Pointer; const aElement: IwbElement): Integer;\n\nprocedure DefineFNV;\n\nimplementation\n\nuses\n  Types,\n  Classes,\n  SysUtils,\n  Math,\n  Variants,\n  wbHelpers;\n\nconst\n  _00_IAD: TwbSignature = #$00'IAD';\n  _40_IAD: TwbSignature = #$40'IAD';\n  _01_IAD: TwbSignature = #$01'IAD';\n  _41_IAD: TwbSignature = #$41'IAD';\n  _02_IAD: TwbSignature = #$02'IAD';\n  _42_IAD: TwbSignature = #$42'IAD';\n  _03_IAD: TwbSignature = #$03'IAD';\n  _43_IAD: TwbSignature = #$43'IAD';\n  _04_IAD: TwbSignature = #$04'IAD';\n  _44_IAD: TwbSignature = #$44'IAD';\n  _05_IAD: TwbSignature = #$05'IAD';\n  _45_IAD: TwbSignature = #$45'IAD';\n  _06_IAD: TwbSignature = #$06'IAD';\n  _46_IAD: TwbSignature = #$46'IAD';\n  _07_IAD: TwbSignature = #$07'IAD';\n  _47_IAD: TwbSignature = #$47'IAD';\n  _08_IAD: TwbSignature = #$08'IAD';\n  _48_IAD: TwbSignature = #$48'IAD';\n  _09_IAD: TwbSignature = #$09'IAD';\n  _49_IAD: TwbSignature = #$49'IAD';\n  _0A_IAD: TwbSignature = #$0A'IAD';\n  _4A_IAD: TwbSignature = #$4A'IAD';\n  _0B_IAD: TwbSignature = #$0B'IAD';\n  _4B_IAD: TwbSignature = #$4B'IAD';\n  _0C_IAD: TwbSignature = #$0C'IAD';\n  _4C_IAD: TwbSignature = #$4C'IAD';\n  _0D_IAD: TwbSignature = #$0D'IAD';\n  _4D_IAD: TwbSignature = #$4D'IAD';\n  _0E_IAD: TwbSignature = #$0E'IAD';\n  _4E_IAD: TwbSignature = #$4E'IAD';\n  _0F_IAD: TwbSignature = #$0F'IAD';\n  _4F_IAD: TwbSignature = #$4F'IAD';\n  _10_IAD: TwbSignature = #$10'IAD';\n  _50_IAD: TwbSignature = #$50'IAD';\n  _11_IAD: TwbSignature = #$11'IAD';\n  _51_IAD: TwbSignature = #$51'IAD';\n  _12_IAD: TwbSignature = #$12'IAD';\n  _52_IAD: TwbSignature = #$52'IAD';\n  _13_IAD: TwbSignature = #$13'IAD';\n  _53_IAD: TwbSignature = #$53'IAD';\n  _14_IAD: TwbSignature = #$14'IAD';\n  _54_IAD: TwbSignature = #$54'IAD';\n\n  _0_IAD : TwbSignature = #0'IAD';\n  _1_IAD : TwbSignature = #1'IAD';\n  _2_IAD : TwbSignature = #2'IAD';\n  _3_IAD : TwbSignature = #3'IAD';\n  _4_IAD : TwbSignature = #4'IAD';\n  _5_IAD : TwbSignature = #5'IAD';\n  ACBS : TwbSignature = 'ACBS';\n  ACHR : TwbSignature = 'ACHR';\n  ACRE : TwbSignature = 'ACRE';\n  ACTI : TwbSignature = 'ACTI';\n  ADDN : TwbSignature = 'ADDN';\n  AIDT : TwbSignature = 'AIDT';\n  ALCH : TwbSignature = 'ALCH';\n  AMMO : TwbSignature = 'AMMO';\n  ANAM : TwbSignature = 'ANAM';\n  ANIO : TwbSignature = 'ANIO';\n  ARMA : TwbSignature = 'ARMA';\n  ARMO : TwbSignature = 'ARMO';\n  ASPC : TwbSignature = 'ASPC';\n  ATTR : TwbSignature = 'ATTR';\n  ATXT : TwbSignature = 'ATXT';\n  AVIF : TwbSignature = 'AVIF';\n  BIPL : TwbSignature = 'BIPL';\n  BMCT : TwbSignature = 'BMCT';\n  BMDT : TwbSignature = 'BMDT';\n  BNAM : TwbSignature = 'BNAM';\n  BOOK : TwbSignature = 'BOOK';\n  BPND : TwbSignature = 'BPND';\n  BPNI : TwbSignature = 'BPNI';\n  BPNN : TwbSignature = 'BPNN';\n  BPNT : TwbSignature = 'BPNT';\n  BPTD : TwbSignature = 'BPTD';\n  BPTN : TwbSignature = 'BPTN';\n  BTXT : TwbSignature = 'BTXT';\n  CAMS : TwbSignature = 'CAMS';\n  CELL : TwbSignature = 'CELL';\n  CLAS : TwbSignature = 'CLAS';\n  CLMT : TwbSignature = 'CLMT';\n  CNAM : TwbSignature = 'CNAM';\n  MMRK : TwbSignature = 'MMRK';\n  CNTO : TwbSignature = 'CNTO';\n  COBJ : TwbSignature = 'COBJ';\n  COED : TwbSignature = 'COED';\n  CONT : TwbSignature = 'CONT';\n  CPTH : TwbSignature = 'CPTH';\n  CRDT : TwbSignature = 'CRDT';\n  CREA : TwbSignature = 'CREA';\n  CSAD : TwbSignature = 'CSAD';\n  CSCR : TwbSignature = 'CSCR';\n  CSDC : TwbSignature = 'CSDC';\n  CSDI : TwbSignature = 'CSDI';\n  CSDT : TwbSignature = 'CSDT';\n  CSSD : TwbSignature = 'CSSD';\n  CSTD : TwbSignature = 'CSTD';\n  CSTY : TwbSignature = 'CSTY';\n  CTDA : TwbSignature = 'CTDA';\n  DATA : TwbSignature = 'DATA';\n  DAT2 : TwbSignature = 'DAT2';\n  DEBR : TwbSignature = 'DEBR';\n  DELE : TwbSignature = 'DELE';\n  DESC : TwbSignature = 'DESC';\n  DEST : TwbSignature = 'DEST';\n  DIAL : TwbSignature = 'DIAL';\n  DMDL : TwbSignature = 'DMDL';\n  DMDT : TwbSignature = 'DMDT';\n  DNAM : TwbSignature = 'DNAM';\n  DOBJ : TwbSignature = 'DOBJ';\n  DODT : TwbSignature = 'DODT';\n  DOOR : TwbSignature = 'DOOR';\n  DSTD : TwbSignature = 'DSTD';\n  DSTF : TwbSignature = 'DSTF';\n  EAMT : TwbSignature = 'EAMT';\n  ECZN : TwbSignature = 'ECZN';\n  EDID : TwbSignature = 'EDID';\n  EFID : TwbSignature = 'EFID';\n  EFIT : TwbSignature = 'EFIT';\n  EFSD : TwbSignature = 'EFSD';\n  EFSH : TwbSignature = 'EFSH';\n  EITM : TwbSignature = 'EITM';\n  ENAM : TwbSignature = 'ENAM';\n  ENCH : TwbSignature = 'ENCH';\n  ENIT : TwbSignature = 'ENIT';\n  EPF2 : TwbSignature = 'EPF2';\n  EPF3 : TwbSignature = 'EPF3';\n  EPFD : TwbSignature = 'EPFD';\n  EPFT : TwbSignature = 'EPFT';\n  ESCE : TwbSignature = 'ESCE';\n  ETYP : TwbSignature = 'ETYP';\n  EXPL : TwbSignature = 'EXPL';\n  EYES : TwbSignature = 'EYES';\n  FACT : TwbSignature = 'FACT';\n  FGGA : TwbSignature = 'FGGA';\n  FGGS : TwbSignature = 'FGGS';\n  FGTS : TwbSignature = 'FGTS';\n  FLST : TwbSignature = 'FLST';\n  FLTV : TwbSignature = 'FLTV';\n  FNAM : TwbSignature = 'FNAM';\n  FULL : TwbSignature = 'FULL';\n  FURN : TwbSignature = 'FURN';\n  GLOB : TwbSignature = 'GLOB';\n  RDID : TwbSignature = 'RDID';\n  RDSI : TwbSignature = 'RDSI';\n  RDSB : TwbSignature = 'RDSB';\n  GMST : TwbSignature = 'GMST';\n  GNAM : TwbSignature = 'GNAM';\n  GRAS : TwbSignature = 'GRAS';\n  HAIR : TwbSignature = 'HAIR';\n  HCLR : TwbSignature = 'HCLR';\n  HDPT : TwbSignature = 'HDPT';\n  HEDR : TwbSignature = 'HEDR';\n  HNAM : TwbSignature = 'HNAM';\n  ICO2 : TwbSignature = 'ICO2';\n  ICON : TwbSignature = 'ICON';\n  IDLA : TwbSignature = 'IDLA';\n  IDLB : TwbSignature = 'IDLB';\n  IDLC : TwbSignature = 'IDLC';\n  IDLE : TwbSignature = 'IDLE';\n  IDLF : TwbSignature = 'IDLF';\n  IDLM : TwbSignature = 'IDLM';\n  IDLT : TwbSignature = 'IDLT';\n  IMAD : TwbSignature = 'IMAD';\n  IMGS : TwbSignature = 'IMGS';\n  INAM : TwbSignature = 'INAM';\n  INDX : TwbSignature = 'INDX';\n  INFO : TwbSignature = 'INFO';\n  INGR : TwbSignature = 'INGR';\n  IPCT : TwbSignature = 'IPCT';\n  IPDS : TwbSignature = 'IPDS';\n  ITXT : TwbSignature = 'ITXT';\n  JNAM : TwbSignature = 'JNAM';\n  KEYM : TwbSignature = 'KEYM';\n  KFFZ : TwbSignature = 'KFFZ';\n  KNAM : TwbSignature = 'KNAM';\n  LAND : TwbSignature = 'LAND';\n  LGTM : TwbSignature = 'LGTM';\n  LIGH : TwbSignature = 'LIGH';\n  LNAM : TwbSignature = 'LNAM';\n  LSCR : TwbSignature = 'LSCR';\n  LTEX : TwbSignature = 'LTEX';\n  LTMP : TwbSignature = 'LTMP';\n  LVLC : TwbSignature = 'LVLC';\n  LVLD : TwbSignature = 'LVLD';\n  LVLF : TwbSignature = 'LVLF';\n  LVLG : TwbSignature = 'LVLG';\n  LVLI : TwbSignature = 'LVLI';\n  LVLN : TwbSignature = 'LVLN';\n  LVLO : TwbSignature = 'LVLO';\n  MAST : TwbSignature = 'MAST';\n  MESG : TwbSignature = 'MESG';\n  MGEF : TwbSignature = 'MGEF';\n  MICN : TwbSignature = 'MICN';\n  MICO : TwbSignature = 'MICO';\n  MIC2 : TwbSignature = 'MIC2';\n  MISC : TwbSignature = 'MISC';\n  MNAM : TwbSignature = 'MNAM';\n  MO2B : TwbSignature = 'MO2B';\n  MO2S : TwbSignature = 'MO2S';\n  MO2T : TwbSignature = 'MO2T';\n  MO3B : TwbSignature = 'MO3B';\n  MO3S : TwbSignature = 'MO3S';\n  MO3T : TwbSignature = 'MO3T';\n  MO4B : TwbSignature = 'MO4B';\n  MO4S : TwbSignature = 'MO4S';\n  MO4T : TwbSignature = 'MO4T';\n  MOD2 : TwbSignature = 'MOD2';\n  VANM : TwbSignature = 'VANM';\n  MOD3 : TwbSignature = 'MOD3';\n  MOD4 : TwbSignature = 'MOD4';\n  MODB : TwbSignature = 'MODB';\n  MODD : TwbSignature = 'MODD';\n  MODL : TwbSignature = 'MODL';\n  MODS : TwbSignature = 'MODS';\n  MODT : TwbSignature = 'MODT';\n  MOSD : TwbSignature = 'MOSD';\n  MSTT : TwbSignature = 'MSTT';\n  MUSC : TwbSignature = 'MUSC';\n  IMPS : TwbSignature = 'IMPS';\n  IMPF : TwbSignature = 'IMPF';\n  NAM0 : TwbSignature = 'NAM0';\n  NAM1 : TwbSignature = 'NAM1';\n  NAM2 : TwbSignature = 'NAM2';\n  NAM3 : TwbSignature = 'NAM3';\n  NAM4 : TwbSignature = 'NAM4';\n  NAM5 : TwbSignature = 'NAM5';\n  NAM6 : TwbSignature = 'NAM6';\n  NAM7 : TwbSignature = 'NAM7';\n  NAM8 : TwbSignature = 'NAM8';\n  NAM9 : TwbSignature = 'NAM9';\n  NAME : TwbSignature = 'NAME';\n  NAVI : TwbSignature = 'NAVI';\n  NAVM : TwbSignature = 'NAVM';\n  NEXT : TwbSignature = 'NEXT';\n  NIFT : TwbSignature = 'NIFT';\n  NIFZ : TwbSignature = 'NIFZ';\n  NNAM : TwbSignature = 'NNAM';\n  XSRF : TwbSignature = 'XSRF';\n  XSRD : TwbSignature = 'XSRD';\n  MWD1 : TwbSignature = 'MWD1';\n  MWD2 : TwbSignature = 'MWD2';\n  MWD3 : TwbSignature = 'MWD3';\n  MWD4 : TwbSignature = 'MWD4';\n  MWD5 : TwbSignature = 'MWD5';\n  MWD6 : TwbSignature = 'MWD6';\n  MWD7 : TwbSignature = 'MWD7';\n  WNM1 : TwbSignature = 'WNM1';\n  WNM2 : TwbSignature = 'WNM2';\n  WNM3 : TwbSignature = 'WNM3';\n  WNM4 : TwbSignature = 'WNM4';\n  WNM5 : TwbSignature = 'WNM5';\n  WNM6 : TwbSignature = 'WNM6';\n  WNM7 : TwbSignature = 'WNM7';\n  WMI1 : TwbSignature = 'WMI1';\n  WMI2 : TwbSignature = 'WMI2';\n  WMI3 : TwbSignature = 'WMI3';\n  WMS1 : TwbSignature = 'WMS1';\n  WMS2 : TwbSignature = 'WMS2';\n  NOTE : TwbSignature = 'NOTE';\n  NPC_ : TwbSignature = 'NPC_';\n  NULL : TwbSignature = 'NULL';\n  NVCA : TwbSignature = 'NVCA';\n  NVCI : TwbSignature = 'NVCI';\n  NVDP : TwbSignature = 'NVDP';\n  NVER : TwbSignature = 'NVER';\n  NVEX : TwbSignature = 'NVEX';\n  NVGD : TwbSignature = 'NVGD';\n  NVMI : TwbSignature = 'NVMI';\n  NVTR : TwbSignature = 'NVTR';\n  NVVX : TwbSignature = 'NVVX';\n  OBND : TwbSignature = 'OBND';\n  OFST : TwbSignature = 'OFST';\n  ONAM : TwbSignature = 'ONAM';\n  PACK : TwbSignature = 'PACK';\n  PBEA : TwbSignature = 'PBEA';\n  PERK : TwbSignature = 'PERK';\n  PFIG : TwbSignature = 'PFIG';\n  PFPC : TwbSignature = 'PFPC';\n  PGAG : TwbSignature = 'PGAG';\n  PGRE : TwbSignature = 'PGRE';\n  PMIS : TwbSignature = 'PMIS';\n  TRGT : TwbSignature = 'TRGT';\n  PGRI : TwbSignature = 'PGRI';\n  PGRL : TwbSignature = 'PGRL';\n  PGRP : TwbSignature = 'PGRP';\n  PGRR : TwbSignature = 'PGRR';\n  PKAM : TwbSignature = 'PKAM';\n  PKDD : TwbSignature = 'PKDD';\n  PKDT : TwbSignature = 'PKDT';\n  PKE2 : TwbSignature = 'PKE2';\n  PKED : TwbSignature = 'PKED';\n  PKFD : TwbSignature = 'PKFD';\n  PKID : TwbSignature = 'PKID';\n  PKPT : TwbSignature = 'PKPT';\n  PKW3 : TwbSignature = 'PKW3';\n  PLD2 : TwbSignature = 'PLD2';\n  PLDT : TwbSignature = 'PLDT';\n  PLYR : TwbSignature = 'PLYR';\n  PNAM : TwbSignature = 'PNAM';\n  TDUM : TwbSignature = 'TDUM';\n  POBA : TwbSignature = 'POBA';\n  POCA : TwbSignature = 'POCA';\n  POEA : TwbSignature = 'POEA';\n  PRKC : TwbSignature = 'PRKC';\n  PRKE : TwbSignature = 'PRKE';\n  PRKF : TwbSignature = 'PRKF';\n  PROJ : TwbSignature = 'PROJ';\n  PSDT : TwbSignature = 'PSDT';\n  PTD2 : TwbSignature = 'PTD2';\n  PTDT : TwbSignature = 'PTDT';\n  PUID : TwbSignature = 'PUID';\n  PWAT : TwbSignature = 'PWAT';\n  QNAM : TwbSignature = 'QNAM';\n  RCIL : TwbSignature = 'RCIL';\n  RCQY : TwbSignature = 'RCQY';\n  RCOD : TwbSignature = 'RCOD';\n  QOBJ : TwbSignature = 'QOBJ';\n  QSDT : TwbSignature = 'QSDT';\n  QSTA : TwbSignature = 'QSTA';\n  QSTI : TwbSignature = 'QSTI';\n  TPIC : TwbSignature = 'TPIC';\n  QSTR : TwbSignature = 'QSTR';\n  INFC : TwbSignature = 'INFC';\n  INFX : TwbSignature = 'INFX';\n  QUST : TwbSignature = 'QUST';\n  RACE : TwbSignature = 'RACE';\n  RADS : TwbSignature = 'RADS';\n  RAFB : TwbSignature = 'RAFB';\n  RAFD : TwbSignature = 'RAFD';\n  RAGA : TwbSignature = 'RAGA';\n  RAPS : TwbSignature = 'RAPS';\n  RCLR : TwbSignature = 'RCLR';\n  RDAT : TwbSignature = 'RDAT';\n  RDMD : TwbSignature = 'RDMD';\n  RDMO : TwbSignature = 'RDMO';\n  RDMP : TwbSignature = 'RDMP';\n  RDGS : TwbSignature = 'RDGS';\n  RDOT : TwbSignature = 'RDOT';\n  RDSD : TwbSignature = 'RDSD';\n  RDWT : TwbSignature = 'RDWT';\n  REFR : TwbSignature = 'REFR';\n  REGN : TwbSignature = 'REGN';\n  REPL : TwbSignature = 'REPL';\n  RGDL : TwbSignature = 'RGDL';\n  RNAM : TwbSignature = 'RNAM';\n  RPLD : TwbSignature = 'RPLD';\n  RPLI : TwbSignature = 'RPLI';\n  SCDA : TwbSignature = 'SCDA';\n  SCHR : TwbSignature = 'SCHR';\n  SCOL : TwbSignature = 'SCOL';\n  SCPT : TwbSignature = 'SCPT';\n  SCRI : TwbSignature = 'SCRI';\n  SCRN : TwbSignature = 'SCRN';\n  SCRO : TwbSignature = 'SCRO';\n  SCRV : TwbSignature = 'SCRV';\n  SCTX : TwbSignature = 'SCTX';\n  SCVR : TwbSignature = 'SCVR';\n  SLCP : TwbSignature = 'SLCP';\n  SLSD : TwbSignature = 'SLSD';\n  SNAM : TwbSignature = 'SNAM';\n  SNDD : TwbSignature = 'SNDD';\n  SNDX : TwbSignature = 'SNDX';\n  SOUL : TwbSignature = 'SOUL';\n  SOUN : TwbSignature = 'SOUN';\n  SPEL : TwbSignature = 'SPEL';\n  SPIT : TwbSignature = 'SPIT';\n  SPLO : TwbSignature = 'SPLO';\n  STAT : TwbSignature = 'STAT';\n  BRUS : TwbSignature = 'BRUS';\n  TACT : TwbSignature = 'TACT';\n  TCLF : TwbSignature = 'TCLF';\n  TCFU : TwbSignature = 'TCFU';\n  TCLT : TwbSignature = 'TCLT';\n  TERM : TwbSignature = 'TERM';\n  TES4 : TwbSignature = 'TES4';\n  TNAM : TwbSignature = 'TNAM';\n  TPLT : TwbSignature = 'TPLT';\n  TRDT : TwbSignature = 'TRDT';\n  TREE : TwbSignature = 'TREE';\n  TX00 : TwbSignature = 'TX00';\n  TX01 : TwbSignature = 'TX01';\n  INTV : TwbSignature = 'INTV';\n  TX02 : TwbSignature = 'TX02';\n  TX03 : TwbSignature = 'TX03';\n  TX04 : TwbSignature = 'TX04';\n  TX05 : TwbSignature = 'TX05';\n  TXST : TwbSignature = 'TXST';\n  UNAM : TwbSignature = 'UNAM';\n  VATS : TwbSignature = 'VATS';\n  VCLR : TwbSignature = 'VCLR';\n  VHGT : TwbSignature = 'VHGT';\n  VNAM : TwbSignature = 'VNAM';\n  VNML : TwbSignature = 'VNML';\n  VTCK : TwbSignature = 'VTCK';\n  VTEX : TwbSignature = 'VTEX';\n  VTXT : TwbSignature = 'VTXT';\n  VTYP : TwbSignature = 'VTYP';\n  WATR : TwbSignature = 'WATR';\n  WEAP : TwbSignature = 'WEAP';\n  WLST : TwbSignature = 'WLST';\n  WNAM : TwbSignature = 'WNAM';\n  XATO : TwbSignature = 'XATO';\n  WRLD : TwbSignature = 'WRLD';\n  WTHR : TwbSignature = 'WTHR';\n  XACT : TwbSignature = 'XACT';\n  XAMC : TwbSignature = 'XAMC';\n  XAMT : TwbSignature = 'XAMT';\n  XAPD : TwbSignature = 'XAPD';\n  XAPR : TwbSignature = 'XAPR';\n  XCAS : TwbSignature = 'XCAS';\n  XCCM : TwbSignature = 'XCCM';\n  XCET : TwbSignature = 'XCET';\n  XCHG : TwbSignature = 'XCHG';\n  XCIM : TwbSignature = 'XCIM';\n  XCLC : TwbSignature = 'XCLC';\n  XCLL : TwbSignature = 'XCLL';\n  XCLP : TwbSignature = 'XCLP';\n  XCLR : TwbSignature = 'XCLR';\n  XCLW : TwbSignature = 'XCLW';\n  XCMO : TwbSignature = 'XCMO';\n  XCMT : TwbSignature = 'XCMT';\n  XCNT : TwbSignature = 'XCNT';\n  XCWT : TwbSignature = 'XCWT';\n  XEMI : TwbSignature = 'XEMI';\n  XESP : TwbSignature = 'XESP';\n  XEZN : TwbSignature = 'XEZN';\n  XGLB : TwbSignature = 'XGLB';\n  XHLP : TwbSignature = 'XHLP';\n  XDCR : TwbSignature = 'XDCR';\n  XHLT : TwbSignature = 'XHLT';\n  XIBS : TwbSignature = 'XIBS';\n  XLCM : TwbSignature = 'XLCM';\n  XLKR : TwbSignature = 'XLKR';\n  XLOC : TwbSignature = 'XLOC';\n  XLOD : TwbSignature = 'XLOD';\n  XLRM : TwbSignature = 'XLRM';\n  XLTW : TwbSignature = 'XLTW';\n  XMBO : TwbSignature = 'XMBO';\n  XMBP : TwbSignature = 'XMBP';\n  XMBR : TwbSignature = 'XMBR';\n  XMRC : TwbSignature = 'XMRC';\n  XMRK : TwbSignature = 'XMRK';\n  XNAM : TwbSignature = 'XNAM';\n  XNDP : TwbSignature = 'XNDP';\n  XOCP : TwbSignature = 'XOCP';\n  XORD : TwbSignature = 'XORD';\n  XOWN : TwbSignature = 'XOWN';\n  XPOD : TwbSignature = 'XPOD';\n  XPTL : TwbSignature = 'XPTL';\n  XPPA : TwbSignature = 'XPPA';\n  XPRD : TwbSignature = 'XPRD';\n  XPRM : TwbSignature = 'XPRM';\n  XPWR : TwbSignature = 'XPWR';\n  XRAD : TwbSignature = 'XRAD';\n  XRDO : TwbSignature = 'XRDO';\n  XRDS : TwbSignature = 'XRDS';\n  XRGB : TwbSignature = 'XRGB';\n  XRGD : TwbSignature = 'XRGD';\n  XRMR : TwbSignature = 'XRMR';\n  XRNK : TwbSignature = 'XRNK';\n  XRTM : TwbSignature = 'XRTM';\n  XSCL : TwbSignature = 'XSCL';\n  XSED : TwbSignature = 'XSED';\n  XTEL : TwbSignature = 'XTEL';\n  XTRG : TwbSignature = 'XTRG';\n  XTRI : TwbSignature = 'XTRI';\n  XXXX : TwbSignature = 'XXXX';\n  YNAM : TwbSignature = 'YNAM';\n  ZNAM : TwbSignature = 'ZNAM';\n  IMOD : TwbSignature = 'IMOD';\n  REPU : TwbSignature = 'REPU';\n  RCPE : TwbSignature = 'RCPE';\n  RCCT : TwbSignature = 'RCCT';\n  CHIP : TwbSignature = 'CHIP';\n  CSNO : TwbSignature = 'CSNO';\n  LSCT : TwbSignature = 'LSCT';\n  MSET : TwbSignature = 'MSET';\n  ALOC : TwbSignature = 'ALOC';\n  CHAL : TwbSignature = 'CHAL';\n  AMEF : TwbSignature = 'AMEF';\n  CCRD : TwbSignature = 'CCRD';\n  CARD : TwbSignature = 'CARD';\n  CMNY : TwbSignature = 'CMNY';\n  CDCK : TwbSignature = 'CDCK';\n  DEHY : TwbSignature = 'DEHY';\n  HUNG : TwbSignature = 'HUNG';\n  SLPD : TwbSignature = 'SLPD';\n\nvar\n  wbPKDTSpecificFlagsUnused : Boolean;\n  wbEDID: IwbSubRecordDef;\n  wbEDIDReq: IwbSubRecordDef;\n  wbBMDT: IwbSubRecordDef;\n  wbYNAM: IwbSubRecordDef;\n  wbZNAM: IwbSubRecordDef;\n  wbCOED: IwbSubRecordDef;\n  wbXLCM: IwbSubRecordDef;\n  wbEITM: IwbSubRecordDef;\n  wbREPL: IwbSubRecordDef;\n  wbBIPL: IwbSubRecordDef;\n  wbOBND: IwbSubRecordDef;\n  wbOBNDReq: IwbSubRecordDef;\n  wbDEST: IwbSubRecordStructDef;\n  wbDESTActor: IwbSubRecordStructDef;\n  wbDODT: IwbSubRecordDef;\n  wbXOWN: IwbSubRecordDef;\n  wbXGLB: IwbSubRecordDef;\n  wbXRGD: IwbSubRecordDef;\n  wbXRGB: IwbSubRecordDef;\n  wbSLSD: IwbSubRecordDef;\n  wbSPLO: IwbSubRecordDef;\n  wbSPLOs: IwbSubRecordArrayDef;\n  wbCNTO: IwbSubRecordStructDef;\n  wbCNTOs: IwbSubRecordArrayDef;\n  wbAIDT: IwbSubRecordDef;\n  wbCSDT: IwbSubRecordStructDef;\n  wbCSDTs: IwbSubRecordArrayDef;\n  wbFULL: IwbSubRecordDef;\n  wbFULLActor: IwbSubRecordDef;\n  wbFULLReq: IwbSubRecordDef;\n  wbXNAM: IwbSubRecordDef;\n  wbXNAMs: IwbSubRecordArrayDef;\n  wbDESC: IwbSubRecordDef;\n  wbDESCReq: IwbSubRecordDef;\n  wbXSCL: IwbSubRecordDef;\n  wbDATAPosRot : IwbSubRecordDef;\n  wbPosRot : IwbStructDef;\n  wbMODD: IwbSubRecordDef;\n  wbMOSD: IwbSubRecordDef;\n  wbMODL: IwbSubRecordStructDef;\n  wbMODS: IwbSubRecordDef;\n  wbMO2S: IwbSubRecordDef;\n  wbMO3S: IwbSubRecordDef;\n  wbMO4S: IwbSubRecordDef;\n  wbMODLActor: IwbSubRecordStructDef;\n  wbMODLReq: IwbSubRecordStructDef;\n  wbCTDA: IwbSubRecordDef;\n  wbSCHRReq: IwbSubRecordDef;\n  wbCTDAs: IwbSubRecordArrayDef;\n  wbCTDAsReq: IwbSubRecordArrayDef;\n  wbSCROs: IwbSubRecordArrayDef;\n  wbPGRP: IwbSubRecordDef;\n  wbEmbeddedScript: IwbSubRecordStructDef;\n  wbEmbeddedScriptPerk: IwbSubRecordStructDef;\n  wbEmbeddedScriptReq: IwbSubRecordStructDef;\n  wbSCRI: IwbSubRecordDef;\n  wbSCRIActor: IwbSubRecordDef;\n  wbFaceGen: IwbSubRecordStructDef;\n  wbFaceGenNPC: IwbSubRecordStructDef;\n  wbENAM: IwbSubRecordDef;\n  wbFGGS: IwbSubRecordDef;\n  wbXLOD: IwbSubRecordDef;\n  wbXESP: IwbSubRecordDef;\n  wbICON: IwbSubRecordStructDef;\n  wbICONReq: IwbSubRecordStructDef;\n  wbActorValue: IwbIntegerDef;\n  wbETYP: IwbSubRecordDef;\n  wbETYPReq: IwbSubRecordDef;\n  wbEFID: IwbSubRecordDef;\n  wbEFIT: IwbSubRecordDef;\n  wbEffects: IwbSubRecordArrayDef;\n  wbEffectsReq: IwbSubRecordArrayDef;\n  wbBPNDStruct: IwbSubRecordDef;\n  wbTimeInterpolator: IwbStructDef;\n  wbColorInterpolator: IwbStructDef;\n\nfunction wbNVTREdgeToStr(aInt: Int64; const aElement: IwbElement; aType: TwbCallbackType): string;\nvar\n  Index      : Integer;\n  Flags      : Cardinal;\n  IsExternal : Boolean;\n  Container  : IwbContainerElementRef;\nbegin\n  Result := '';\n  IsExternal := False;\n  if Supports(aElement, IwbContainerElementRef, Container) then begin\n    Index := StrToIntDef(Copy(Container.Name, 11, 1), -1);\n    if (Index >= 0) and (Index <= 2) then begin\n      Flags := Container.ElementNativeValues['..\\..\\Flags'];\n      IsExternal := Flags and (Cardinal(1) shl Index) <> 0;\n    end;\n  end;\n\n  if IsExternal then begin\n    case aType of\n      ctToStr: begin\n        Result := IntToStr(aInt);\n        if Container.ElementExists['..\\..\\..\\..\\NVEX\\Connection #' + IntToStr(aInt)] then\n          Result := Result + ' (Triangle #' +\n            Container.ElementValues['..\\..\\..\\..\\NVEX\\Connection #' + IntToStr(aInt) + '\\Triangle'] + ' in ' +\n            Container.ElementValues['..\\..\\..\\..\\NVEX\\Connection #' + IntToStr(aInt) + '\\Navigation Mesh'] + ')'\n        else\n          Result := Result + ' <Error: NVEX\\Connection #' + IntToStr(aInt) + ' is missing>';\n      end;\n      ctToSortKey:\n        if Container.ElementExists['..\\..\\..\\..\\NVEX\\Connection #' + IntToStr(aInt)] then\n          Result :=\n            Container.ElementSortKeys['..\\..\\..\\..\\NVEX\\Connection #' + IntToStr(aInt) + '\\Navigation Mesh', True] + '|' +\n            Container.ElementSortKeys['..\\..\\..\\..\\NVEX\\Connection #' + IntToStr(aInt) + '\\Triangle', True];\n      ctCheck:\n        if Container.ElementExists['..\\..\\..\\..\\NVEX\\Connection #' + IntToStr(aInt)] then\n          Result := ''\n        else\n          Result := 'NVEX\\Connection #' + IntToStr(aInt) + ' is missing';\n    end\n  end else\n    case aType of\n      ctToStr: Result := IntToStr(aInt);\n    end;\nend;\n\nfunction wbNVTREdgeToInt(const aString: string; const aElement: IwbElement): Int64;\nbegin\n  Result := StrToInt64(aString);\nend;\n\n\nfunction wbEPFDActorValueToStr(aInt: Int64; const aElement: IwbElement; aType: TwbCallbackType): string;\nvar\n  AsCardinal : Cardinal;\n  AsFloat    : Single;\nbegin\n  AsCardinal := aInt;\n  AsFloat := PSingle(@AsCardinal)^;\n  aInt := Round(AsFloat);\n  case aType of\n    ctToStr: Result := wbActorValueEnum.ToString(aInt, aElement);\n    ctToSortKey: Result := wbActorValueEnum.ToSortKey(aInt, aElement);\n    ctCheck: Result := wbActorValueEnum.Check(aInt, aElement);\n    ctToEditValue: Result := wbActorValueEnum.ToEditValue(aInt, aElement);\n    ctEditType: Result := 'ComboBox';\n    ctEditInfo: Result := wbActorValueEnum.EditInfo[aInt, aElement];\n  end;\nend;\n\nfunction wbEPFDActorValueToInt(const aString: string; const aElement: IwbElement): Int64;\nvar\n  AsCardinal : Cardinal;\n  AsFloat    : Single;\nbegin\n  AsFloat := wbActorValueEnum.FromEditValue(aString, aElement);\n  PSingle(@AsCardinal)^ := AsFloat;\n  Result := AsCardinal;\nend;\n\nfunction wbCTDAParam2VariableNameToStr(aInt: Int64; const aElement: IwbElement; aType: TwbCallbackType): string;\nvar\n  Container  : IwbContainerElementRef;\n  //Container2 : IwbContainerElementRef;\n  Param1     : IwbElement;\n  MainRecord : IwbMainRecord;\n  BaseRecord : IwbMainRecord;\n  ScriptRef  : IwbElement;\n  Script     : IwbMainRecord;\n  Variables  : TStringList;\n  LocalVars  : IwbContainerElementRef;\n  LocalVar   : IwbContainerElementRef;\n  i, j       : Integer;\n  s          : string;\nbegin\n  case aType of\n    ctToStr: Result := IntToStr(aInt) + ' <Warning: Could not resolve Parameter 1>';\n    ctToEditValue: Result := IntToStr(aInt);\n    ctToSortKey: begin\n      Result := IntToHex64(aInt, 8);\n      Exit;\n    end;\n    ctCheck: Result := '<Warning: Could not resolve Parameter 1>';\n    ctEditType: Result := '';\n    ctEditInfo: Result := '';\n  end;\n\n  if not Assigned(aElement) then Exit;\n  Container := GetContainerRefFromUnionOrValue(aElement);\n  if not Assigned(Container) then Exit;\n\n  Param1 := Container.ElementByName['Parameter #1'];\n\n  if not Assigned(Param1) then\n    Exit;\n\n  MainRecord := nil;\n  if not Supports(Param1.LinksTo, IwbMainRecord, MainRecord) then\n    Exit;\n{    if Param1.NativeValue = 0 then\n      if Supports(Container.Container, IwbContainerElementRef, Container) then\n        for i := 0 to Pred(Container.ElementCount) do\n          if Supports(Container.Elements[i], IwbContainerElementRef, Container2) then\n            if SameText(Container2.ElementValues['Function'], 'GetIsID') then begin\n              Param1 := Container2.ElementByName['Parameter #1'];\n              if Supports(Param1.LinksTo, IwbMainRecord, MainRecord) then\n                Break;\n            end;}\n\n  if not Assigned(MainRecord) then\n    Exit;\n\n  BaseRecord := MainRecord.BaseRecord;\n  if Assigned(BaseRecord) then\n    MainRecord := BaseRecord;\n\n  ScriptRef := MainRecord.RecordBySignature['SCRI'];\n\n  if not Assigned(ScriptRef) then begin\n    case aType of\n      ctToStr: Result := IntToStr(aInt) + ' <Warning: \"'+MainRecord.ShortName+'\" does not contain a SCRI subrecord>';\n      ctCheck: Result := '<Warning: \"'+MainRecord.ShortName+'\" does not contain a SCRI subrecord>';\n    end;\n    Exit;\n  end;\n\n  if not Supports(ScriptRef.LinksTo, IwbMainRecord, Script) then begin\n    case aType of\n      ctToStr: Result := IntToStr(aInt) + ' <Warning: \"'+MainRecord.ShortName+'\" does not have a valid script>';\n      ctCheck: Result := '<Warning: \"'+MainRecord.ShortName+'\" does not have a valid script>';\n    end;\n    Exit;\n  end;\n\n  Script := Script.HighestOverrideOrSelf[aElement._File.LoadOrder];\n\n  case aType of\n    ctEditType: begin\n      Result := 'ComboBox';\n      Exit;\n    end;\n    ctEditInfo:\n      Variables := TStringList.Create;\n  else\n    Variables := nil;\n  end;\n  try\n    if Supports(Script.ElementByName['Local Variables'], IwbContainerElementRef, LocalVars) then begin\n      for i := 0 to Pred(LocalVars.ElementCount) do\n        if Supports(LocalVars.Elements[i], IwbContainerElementRef, LocalVar) then begin\n          j := LocalVar.ElementNativeValues['SLSD\\Index'];\n          s := LocalVar.ElementNativeValues['SCVR'];\n          if Assigned(Variables) then\n            Variables.AddObject(s, TObject(j))\n          else if j = aInt then begin\n            case aType of\n              ctToStr, ctToEditValue: Result := s;\n              ctCheck: Result := '';\n            end;\n            Exit;\n          end;\n        end;\n    end;\n\n    case aType of\n      ctToStr: Result := IntToStr(aInt) + ' <Warning: Variable Index not found in \"' + Script.Name + '\">';\n      ctCheck: Result := '<Warning: Variable Index not found in \"' + Script.Name + '\">';\n      ctEditInfo: begin\n        Variables.Sort;\n        Result := Variables.CommaText;\n      end;\n    end;\n  finally\n    FreeAndNil(Variables);\n  end;\nend;\n\nfunction wbCTDAParam2VariableNameToInt(const aString: string; const aElement: IwbElement): Int64;\nvar\n  Container  : IwbContainerElementRef;\n  Param1     : IwbElement;\n  MainRecord : IwbMainRecord;\n  BaseRecord : IwbMainRecord;\n  ScriptRef  : IwbElement;\n  Script     : IwbMainRecord;\n  LocalVars  : IwbContainerElementRef;\n  LocalVar   : IwbContainerElementRef;\n  i, j       : Integer;\n  s          : string;\nbegin\n  Result := StrToInt64Def(aString, Low(Cardinal));\n  if Result <> Low(Cardinal) then\n    Exit;\n\n  if not Assigned(aElement) then\n    raise Exception.Create('aElement not specified');\n\n  Container := GetContainerRefFromUnionOrValue(aElement);\n\n  if not Assigned(Container) then\n    raise Exception.Create('Container not assigned');\n\n  Param1 := Container.ElementByName['Parameter #1'];\n\n  if not Assigned(Param1) then\n    raise Exception.Create('Could not find \"Parameter #1\"');\n\n  if not Supports(Param1.LinksTo, IwbMainRecord, MainRecord) then\n    raise Exception.Create('\"Parameter #1\" does not reference a valid main record');\n\n  BaseRecord := MainRecord.BaseRecord;\n  if Assigned(BaseRecord) then\n    MainRecord := BaseRecord;\n\n  ScriptRef := MainRecord.RecordBySignature['SCRI'];\n\n  if not Assigned(ScriptRef) then\n    raise Exception.Create('\"'+MainRecord.ShortName+'\" does not contain a SCRI subrecord');\n\n  if not Supports(ScriptRef.LinksTo, IwbMainRecord, Script) then\n    raise Exception.Create('\"'+MainRecord.ShortName+'\" does not have a valid script');\n\n  Script := Script.HighestOverrideOrSelf[aElement._File.LoadOrder];\n\n  if Supports(Script.ElementByName['Local Variables'], IwbContainerElementRef, LocalVars) then begin\n    for i := 0 to Pred(LocalVars.ElementCount) do\n      if Supports(LocalVars.Elements[i], IwbContainerElementRef, LocalVar) then begin\n        j := LocalVar.ElementNativeValues['SLSD\\Index'];\n        s := LocalVar.ElementNativeValues['SCVR'];\n        if SameText(s, Trim(aString)) then begin\n          Result := j;\n          Exit;\n        end;\n      end;\n  end;\n\n  raise Exception.Create('Variable \"'+aString+'\" was not found in \"'+MainRecord.ShortName+'\"');\nend;\n\nfunction wbCTDAParam2QuestStageToStr(aInt: Int64; const aElement: IwbElement; aType: TwbCallbackType): string;\nvar\n  Container  : IwbContainerElementRef;\n  Param1     : IwbElement;\n  MainRecord : IwbMainRecord;\n  EditInfos  : TStringList;\n  Stages     : IwbContainerElementRef;\n  Stage      : IwbContainerElementRef;\n  i, j       : Integer;\n  s, t       : string;\nbegin\n  case aType of\n    ctToStr: Result := IntToStr(aInt) + ' <Warning: Could not resolve Parameter 1>';\n    ctToEditValue: Result := IntToStr(aInt);\n    ctToSortKey: begin\n      Result := IntToHex64(aInt, 8);\n      Exit;\n    end;\n    ctCheck: Result := '<Warning: Could not resolve Parameter 1>';\n    ctEditType: Result := '';\n    ctEditInfo: Result := '';\n  end;\n\n  if not Assigned(aElement) then Exit;\n  Container := GetContainerRefFromUnionOrValue(aElement);\n  if not Assigned(Container) then Exit;\n\n  Param1 := Container.ElementByName['Parameter #1'];\n\n  if not Assigned(Param1) then\n    Exit;\n\n  if not Supports(Param1.LinksTo, IwbMainRecord, MainRecord) then\n    Exit;\n\n  MainRecord := MainRecord.WinningOverride;\n\n  if MainRecord.Signature <> QUST then begin\n    case aType of\n      ctToStr: Result := IntToStr(aInt) + ' <Warning: \"'+MainRecord.ShortName+'\" is not a Quest record>';\n      ctCheck: Result := '<Warning: \"'+MainRecord.ShortName+'\" is not a Quest record>';\n    end;\n    Exit;\n  end;\n\n  case aType of\n    ctEditType: begin\n      Result := 'ComboBox';\n      Exit;\n    end;\n    ctEditInfo:\n      EditInfos := TStringList.Create;\n  else\n    EditInfos := nil;\n  end;\n  try\n    if Supports(MainRecord.ElementByName['Stages'], IwbContainerElementRef, Stages) then begin\n      for i := 0 to Pred(Stages.ElementCount) do\n        if Supports(Stages.Elements[i], IwbContainerElementRef, Stage) then begin\n          j := Stage.ElementNativeValues['INDX'];\n          s := Trim(Stage.ElementValues['Log Entries\\Log Entry\\CNAM']);\n          t := IntToStr(j);\n          while Length(t) < 3 do\n            t := '0' + t;\n          if s <> '' then\n            t := t + ' ' + s;\n          if Assigned(EditInfos) then\n            EditInfos.AddObject(t, TObject(j))\n          else if j = aInt then begin\n            case aType of\n              ctToStr, ctToEditValue: Result := t;\n              ctCheck: Result := '';\n            end;\n            Exit;\n          end;\n        end;\n    end;\n\n    case aType of\n      ctToStr: Result := IntToStr(aInt) + ' <Warning: Quest Stage not found in \"' + MainRecord.Name + '\">';\n      ctCheck: Result := '<Warning: Quest Stage not found in \"' + MainRecord.Name + '\">';\n      ctEditInfo: begin\n        EditInfos.Sort;\n        Result := EditInfos.CommaText;\n      end;\n    end;\n  finally\n    FreeAndNil(EditInfos);\n  end;\nend;\n\nfunction wbPerkDATAQuestStageToStr(aInt: Int64; const aElement: IwbElement; aType: TwbCallbackType): string;\nvar\n  Container  : IwbContainerElementRef;\n  Param1     : IwbElement;\n  MainRecord : IwbMainRecord;\n  EditInfos  : TStringList;\n  Stages     : IwbContainerElementRef;\n  Stage      : IwbContainerElementRef;\n  i, j       : Integer;\n  s, t       : string;\nbegin\n  case aType of\n    ctToStr: Result := IntToStr(aInt) + ' <Warning: Could not resolve Quest>';\n    ctToEditValue: Result := IntToStr(aInt);\n    ctToSortKey: begin\n      Result := IntToHex64(aInt, 8);\n      Exit;\n    end;\n    ctCheck: Result := '<Warning: Could not resolve Quest>';\n    ctEditType: Result := '';\n    ctEditInfo: Result := '';\n  end;\n\n  if not Assigned(aElement) then Exit;\n  Container := GetContainerRefFromUnionOrValue(aElement);\n  if not Assigned(Container) then Exit;\n\n  Param1 := Container.ElementByName['Quest'];\n\n  if not Assigned(Param1) then\n    Exit;\n\n  if not Supports(Param1.LinksTo, IwbMainRecord, MainRecord) then\n    Exit;\n\n  MainRecord := MainRecord.WinningOverride;\n\n  if MainRecord.Signature <> QUST then begin\n    case aType of\n      ctToStr: Result := IntToStr(aInt) + ' <Warning: \"'+MainRecord.ShortName+'\" is not a Quest record>';\n      ctCheck: Result := '<Warning: \"'+MainRecord.ShortName+'\" is not a Quest record>';\n    end;\n    Exit;\n  end;\n\n  case aType of\n    ctEditType: begin\n      Result := 'ComboBox';\n      Exit;\n    end;\n    ctEditInfo:\n      EditInfos := TStringList.Create;\n  else\n    EditInfos := nil;\n  end;\n  try\n    if Supports(MainRecord.ElementByName['Stages'], IwbContainerElementRef, Stages) then begin\n      for i := 0 to Pred(Stages.ElementCount) do\n        if Supports(Stages.Elements[i], IwbContainerElementRef, Stage) then begin\n          j := Stage.ElementNativeValues['INDX'];\n          s := Trim(Stage.ElementValues['Log Entries\\Log Entry\\CNAM']);\n          t := IntToStr(j);\n          while Length(t) < 3 do\n            t := '0' + t;\n          if s <> '' then\n            t := t + ' ' + s;\n          if Assigned(EditInfos) then\n            EditInfos.AddObject(t, TObject(j))\n          else if j = aInt then begin\n            case aType of\n              ctToStr, ctToEditValue: Result := t;\n              ctCheck: Result := '';\n            end;\n            Exit;\n          end;\n        end;\n    end;\n\n    case aType of\n      ctToStr: Result := IntToStr(aInt) + ' <Warning: Quest Stage not found in \"' + MainRecord.Name + '\">';\n      ctCheck: Result := '<Warning: Quest Stage not found in \"' + MainRecord.Name + '\">';\n      ctEditInfo: begin\n        EditInfos.Sort;\n        Result := EditInfos.CommaText;\n      end;\n    end;\n  finally\n    FreeAndNil(EditInfos);\n  end;\nend;\n\nfunction wbCTDAParam2QuestObjectiveToStr(aInt: Int64; const aElement: IwbElement; aType: TwbCallbackType): string;\nvar\n  Container  : IwbContainerElementRef;\n  Param1     : IwbElement;\n  MainRecord : IwbMainRecord;\n  EditInfos  : TStringList;\n  Objectives     : IwbContainerElementRef;\n  Objective      : IwbContainerElementRef;\n  i, j       : Integer;\n  s, t       : string;\nbegin\n  case aType of\n    ctToStr: Result := IntToStr(aInt) + ' <Warning: Could not resolve Parameter 1>';\n    ctToEditValue: Result := IntToStr(aInt);\n    ctToSortKey: begin\n      Result := IntToHex64(aInt, 8);\n      Exit;\n    end;\n    ctCheck: Result := '<Warning: Could not resolve Parameter 1>';\n    ctEditType: Result := '';\n    ctEditInfo: Result := '';\n  end;\n\n  if not Assigned(aElement) then Exit;\n  Container := GetContainerRefFromUnionOrValue(aElement);\n  if not Assigned(Container) then Exit;\n\n  Param1 := Container.ElementByName['Parameter #1'];\n\n  if not Assigned(Param1) then\n    Exit;\n\n  if not Supports(Param1.LinksTo, IwbMainRecord, MainRecord) then\n    Exit;\n\n  MainRecord := MainRecord.WinningOverride;\n\n  if MainRecord.Signature <> QUST then begin\n    case aType of\n      ctToStr: Result := IntToStr(aInt) + ' <Warning: \"'+MainRecord.ShortName+'\" is not a Quest record>';\n      ctCheck: Result := '<Warning: \"'+MainRecord.ShortName+'\" is not a Quest record>';\n    end;\n    Exit;\n  end;\n\n  case aType of\n    ctEditType: begin\n      Result := 'ComboBox';\n      Exit;\n    end;\n    ctEditInfo:\n      EditInfos := TStringList.Create;\n  else\n    EditInfos := nil;\n  end;\n  try\n    if Supports(MainRecord.ElementByName['Objectives'], IwbContainerElementRef, Objectives) then begin\n      for i := 0 to Pred(Objectives.ElementCount) do\n        if Supports(Objectives.Elements[i], IwbContainerElementRef, Objective) then begin\n          j := Objective.ElementNativeValues['QOBJ'];\n          s := Trim(Objective.ElementValues['NNAM']);\n          t := IntToStr(j);\n          while Length(t) < 3 do\n            t := '0' + t;\n          if s <> '' then\n            t := t + ' ' + s;\n          if Assigned(EditInfos) then\n            EditInfos.AddObject(t, TObject(j))\n          else if j = aInt then begin\n            case aType of\n              ctToStr, ctToEditValue: Result := t;\n              ctCheck: Result := '';\n            end;\n            Exit;\n          end;\n        end;\n    end;\n\n    case aType of\n      ctToStr: Result := IntToStr(aInt) + ' <Warning: Quest Objective not found in \"' + MainRecord.Name + '\">';\n      ctCheck: Result := '<Warning: Quest Objective not found in \"' + MainRecord.Name + '\">';\n      ctEditInfo: begin\n        EditInfos.Sort;\n        Result := EditInfos.CommaText;\n      end;\n    end;\n  finally\n    FreeAndNil(EditInfos);\n  end;\nend;\n\nfunction wbCTDAParam2QuestStageToInt(const aString: string; const aElement: IwbElement): Int64;\nvar\n  i    : Integer;\n  s    : string;\nbegin\n  i := 1;\n  s := Trim(aString);\n  while (i <= Length(s)) and (s[i] in ['0'..'9']) do\n    Inc(i);\n  s := Copy(s, 1, Pred(i));\n\n  Result := StrToInt(s);\nend;\n\nfunction wbCTDAParam2QuestObjectiveToInt(const aString: string; const aElement: IwbElement): Int64;\nvar\n  i    : Integer;\n  s    : string;\nbegin\n  i := 1;\n  s := Trim(aString);\n  while (i <= Length(s)) and (s[i] in ['0'..'9']) do\n    Inc(i);\n  s := Copy(s, 1, Pred(i));\n\n  Result := StrToInt(s);\nend;\n\n\nfunction wbClmtMoonsPhaseLength(aInt: Int64; const aElement: IwbElement; aType: TwbCallbackType): string;\nvar\n  PhaseLength : Byte;\n  Masser      : Boolean;\n  Secunda     : Boolean;\nbegin\n  Result := '';\n  if aType = ctToSortKey then begin\n    Result := IntToHex64(aInt, 2);\n  end else if aType = ctToStr then begin\n    PhaseLength := aInt mod 64;\n    Masser := (aInt and 64) <> 0;\n    Secunda := (aInt and 128) <> 0;\n    if Masser then\n      if Secunda then\n        Result := 'Masser, Secunda / '\n      else\n        Result := 'Masser / '\n    else\n      if Secunda then\n        Result := 'Secunda / '\n      else\n        Result := 'No Moon / ';\n    Result := Result + IntToStr(PhaseLength);\n  end;\nend;\n\nfunction wbClmtTime(aInt: Int64; const aElement: IwbElement; aType: TwbCallbackType): string;\nbegin\n  if aType = ctToSortKey then\n    Result := IntToHex64(aInt, 4)\n  else if aType = ctToStr then\n    Result := TimeToStr( EncodeTime(aInt div 6, (aInt mod 6) * 10, 0, 0) )\n  else\n    Result := '';\nend;\n\nfunction wbAlocTime(aInt: Int64; const aElement: IwbElement; aType: TwbCallbackType): string;\nbegin\n  if aType = ctToSortKey then\n    Result := IntToHex64(aInt, 4)\n  else if aType = ctToStr then\n    Result := TimeToStr( aInt / 256 )\n  else\n    Result := '';\nend;\n\nfunction wbREFRNavmeshTriangleToStr(aInt: Int64; const aElement: IwbElement; aType: TwbCallbackType): string;\nvar\n  Container  : IwbContainerElementRef;\n  Navmesh    : IwbElement;\n  MainRecord : IwbMainRecord;\n  Triangles  : IwbContainerElementRef;\nbegin\n  case aType of\n    ctToStr: Result := IntToStr(aInt);\n    ctToEditValue: Result := IntToStr(aInt);\n    ctToSortKey: begin\n      Result := IntToHex64(aInt, 8);\n      Exit;\n    end;\n    ctCheck: Result := '';\n    ctEditType: Result := '';\n    ctEditInfo: Result := '';\n  end;\n\n  if not Assigned(aElement) then Exit;\n  Container := GetContainerRefFromUnionOrValue(aElement);\n  if not Assigned(Container) then Exit;\n\n  Navmesh := Container.Elements[0];\n\n  if not Assigned(Navmesh) then\n    Exit;\n\n  if not Supports(Navmesh.LinksTo, IwbMainRecord, MainRecord) then\n    Exit;\n\n  MainRecord := MainRecord.WinningOverride;\n\n  if MainRecord.Signature <> NAVM then begin\n    case aType of\n      ctToStr: Result := IntToStr(aInt) + ' <Warning: \"'+MainRecord.ShortName+'\" is not a Navmesh record>';\n      ctCheck: Result := '<Warning: \"'+MainRecord.ShortName+'\" is not a Navmesh record>';\n    end;\n    Exit;\n  end;\n\n  if not wbSimpleRecords and (aType = ctCheck) and Supports(MainRecord.ElementByPath['NVTR'], IwbContainerElementRef, Triangles) then\n    if aInt >= Triangles.ElementCount then\n      Result := '<Warning: Navmesh triangle not found in \"' + MainRecord.Name + '\">';\nend;\n\nfunction wbStringToInt(const aString: string; const aElement: IwbElement): Int64;\nbegin\n  Result := StrToIntDef(aString, 0);\nend;\n\n\nvar\n  wbCtdaTypeFlags : IwbFlagsDef;\n\nfunction wbCtdaTypeToStr(aInt: Int64; const aElement: IwbElement; aType: TwbCallbackType): string;\nvar\n  s: string;\nbegin\n  Result := '';\n  case aType of\n    ctEditType:\n      Result := 'CheckComboBox';\n    ctEditInfo:\n      Result := 'Equal,Greater,Lesser,Or,\"Use Global\",\"Run on Target\"';\n    ctToEditValue: begin\n      Result := '000000';\n      case aInt and $F0 of\n        $00 : Result[1] := '1';\n        $40 : Result[2] := '1';\n        $60 : begin\n                Result[1] := '1';\n                Result[2] := '1';\n              end;\n        $80 : Result[3] := '1';\n        $A0 : begin\n                Result[1] := '1';\n                Result[3] := '1';\n              end;\n      end;\n      if (aInt and $01) <> 0 then\n        Result[4] := '1';\n      if (aInt and $02) <> 0 then\n        Result[6] := '1';\n      if (aInt and $04) <> 0 then\n        Result[5] := '1';\n    end;\n    ctToStr: begin\n      case aInt and $F0 of\n        $00 : Result := 'Equal to';\n        $20 : Result := 'Not equal to';\n        $40 : Result := 'Greater than';\n        $60 : Result := 'Greater than or equal to';\n        $80 : Result := 'Less than';\n        $A0 : Result := 'Less than or equal to';\n      else\n        Result := '<Unknown Compare operator>'\n      end;\n\n      if not Assigned(wbCtdaTypeFlags) then\n        wbCtdaTypeFlags := wbFlags([\n          {0x01} 'Or',\n          {0x02} 'Run on target',\n          {0x04} 'Use global'\n        ]);\n\n      s := wbCtdaTypeFlags.ToString(aInt and $0F, aElement);\n\n      if s <> '' then\n        Result := Result + ' / ' + s;\n    end;\n    ctToSortKey: begin\n      Result := IntToHex64(aInt, 2);\n      Exit;\n    end;\n    ctCheck: begin\n      case aInt and $F0 of\n        $00, $20, $40, $60, $80, $A0 : Result := '';\n      else\n        Result := '<Unknown Compare operator>'\n      end;\n\n      if not Assigned(wbCtdaTypeFlags) then\n        wbCtdaTypeFlags := wbFlags([\n          {0x01} 'Or',\n          {0x02} 'Run on target',\n          {0x04} 'Use global'\n        ]);\n\n      s := wbCtdaTypeFlags.Check(aInt and $0F, aElement);\n\n      if s <> '' then\n        Result := Result + ' / ' + s;\n    end;\n  end;\nend;\n\nfunction wbCtdaTypeToInt(const aString: string; const aElement: IwbElement): Int64;\nvar\n  s: string;\nbegin\n  s := aString + '000000';\n//  Result := 0;\n  if s[1] = '1' then begin\n    if s[2] = '1' then begin\n      if s[3] = '1' then begin\n        Result := $00;\n      end else begin\n        Result := $60;\n      end;\n    end else begin\n      if s[3] = '1' then begin\n        Result := $A0;\n      end else begin\n        Result := $00;\n      end;\n    end;\n  end else begin\n    if s[2] = '1' then begin\n      if s[3] = '1' then begin\n        Result := $20;\n      end else begin\n        Result := $40;\n      end;\n    end else begin\n      if s[3] = '1' then begin\n        Result := $80;\n      end else begin\n        Result := $20;\n      end;\n    end;\n  end;\n  if s[4] = '1' then\n    Result := Result or $01;\n  if s[6] = '1' then\n    Result := Result or $02;\n  if s[5] = '1' then\n    Result := Result or $04;\nend;\n\nprocedure wbHeadPartsAfterSet(const aElement: IwbElement; const aOldValue, aNewValue: Variant);\nvar\n  Container : IwbContainerElementRef;\nbegin\n  if wbBeginInternalEdit then try\n    if Supports(aElement, IwbContainerElementRef, Container) then\n      if (Container.Elements[0].NativeValue = 1) and (Container.ElementCount > 2) then\n        Container.RemoveElement(1);\n  finally\n    wbEndInternalEdit;\n  end;\nend;\n\nprocedure wbMESGDNAMAfterSet(const aElement: IwbElement; const aOldValue, aNewValue: Variant);\nvar\n  OldValue, NewValue : Integer;\n  Container          : IwbContainerElementRef;\nbegin\n  if VarSameValue(aOldValue, aNewValue) then\n    Exit;\n  if Supports(aElement.Container, IwbContainerElementRef, Container) then begin\n    OldValue := Integer(aOldValue) and 1;\n    NewValue := Integer(aNewValue) and 1;\n    if NewValue = OldValue then\n      Exit;\n    if NewValue = 1 then\n      Container.RemoveElement('TNAM')\n    else\n      Container.Add('TNAM', True);\n  end;\nend;\n\nprocedure wbGMSTEDIDAfterSet(const aElement: IwbElement; const aOldValue, aNewValue: Variant);\nvar\n  OldValue, NewValue : string;\n  Container          : IwbContainerElementRef;\nbegin\n  if VarSameValue(aOldValue, aNewValue) then\n    Exit;\n  if Supports(aElement.Container, IwbContainerElementRef, Container) then begin\n    OldValue := aOldValue;\n    NewValue := aNewValue;\n    if (Length(OldValue) < 1) or (Length(OldValue) < 1) or (OldValue[1] <> NewValue[1]) then begin\n      Container.RemoveElement('DATA');\n      Container.Add('DATA', True);\n    end;\n  end;\nend;\n\nprocedure wbFLSTEDIDAfterSet(const aElement: IwbElement; const aOldValue, aNewValue: Variant);\nvar\n  OldValue, NewValue     : string;\n  OldOrdered, NewOrdered : Boolean;\n  Container              : IwbContainerElementRef;\nconst\n  OrderedList = 'OrderedList';\nbegin\n  if VarSameValue(aOldValue, aNewValue) then\n    Exit;\n  if Supports(aElement.Container, IwbContainerElementRef, Container) then begin\n    OldValue := aOldValue;\n    NewValue := aNewValue;\n\n    if Length(OldValue) > Length(OrderedList) then\n      Delete(OldValue, 1, Length(OldValue)-Length(OrderedList));\n    if Length(NewValue) > Length(OrderedList) then\n      Delete(NewValue, 1, Length(NewValue)-Length(OrderedList));\n\n    OldOrdered := SameText(OldValue, OrderedList);\n    NewOrdered := SameText(NewValue, OrderedList);\n\n    if OldOrdered <> NewOrdered then\n      Container.RemoveElement('FormIDs');\n  end;\nend;\n\nprocedure wbCtdaTypeAfterSet(const aElement: IwbElement; const aOldValue, aNewValue: Variant);\nvar\n  OldValue, NewValue: Integer;\n  Container: IwbContainerElementRef;\nbegin\n  if VarSameValue(aOldValue, aNewValue) then\n    Exit;\n  if not Supports(aElement, IwbContainerElementRef, Container) then\n    Exit;\n\n  OldValue := aOldValue and $04;\n  NewValue := aNewValue and $04;\n  if OldValue <> NewValue then\n    Container.ElementNativeValues['..\\Comparison Value'] := 0;\n\n  if aNewValue and $02 then begin\n    Container.ElementNativeValues['..\\Run On'] := 1;\n    if Integer(Container.ElementNativeValues['..\\Run On']) = 1 then\n      aElement.NativeValue := Byte(aNewValue) and not $02;\n  end;\nend;\n\nfunction wbMODTCallback(aInt: Int64; const aElement: IwbElement; aType: TwbCallbackType): string;\nvar\n  Strings: TDynStrings;\n  i: Integer;\nbegin\n  Result := '';\n  if wbLoaderDone and (aType in [ctToStr, ctToSortKey] ) then begin\n    Strings := wbContainerHandler.ResolveHash(aInt);\n    for i := Low(Strings) to High(Strings) do\n      Result := Result + Strings[i] + ', ';\n    SetLength(Result, Length(Result) -2 );\n  end;\nend;\n\n\nfunction wbIdleAnam(aInt: Int64; const aElement: IwbElement; aType: TwbCallbackType): string;\nbegin\n  Result := '';\n  case aType of\n    ctToStr: begin\n      case aInt and not $C0 of\n        0: Result := 'Idle';\n        1: Result := 'Movement';\n        2: Result := 'Left Arm';\n        3: Result := 'Left Hand';\n        4: Result := 'Weapon';\n        5: Result := 'Weapon Up';\n        6: Result := 'Weapon Down';\n        7: Result := 'Special Idle';\n       20: Result := 'Whole Body';\n       21: Result := 'Upper Body';\n      else\n        Result := '<Unknown: '+IntToStr(aInt and not $C0)+'>';\n      end;\n\n      if (aInt and $80) = 0 then\n        Result := Result + ', Must return a file';\n      if (aInt and $40) = 1 then\n        Result := Result + ', Unknown Flag';\n    end;\n    ctToSortKey: begin\n      Result := IntToHex64(aInt, 2);\n    end;\n    ctCheck: begin\n      case aInt and not $C0 of\n        0..7, 20, 21: Result := '';\n      else\n        Result := '<Unknown: '+IntToStr(aInt and not $C0)+'>';\n      end;\n    end;\n  end;\nend;\n\nfunction wbScaledInt4ToStr(aInt: Int64; const aElement: IwbElement; aType: TwbCallbackType): string;\nconst\n  PlusMinus : array[Boolean] of string = ('+', '-');\nbegin\n  Result := '';\n  case aType of\n    ctToStr, ctToEditValue: Result := FloatToStrF(aInt / 10000, ffFixed, 99, 4);\n    ctToSortKey: begin\n      Result := FloatToStrF(aInt / 10000, ffFixed, 99, 4);\n      if Length(Result) < 22 then\n        Result := StringOfChar('0', 22 - Length(Result)) + Result;\n      Result := PlusMinus[aInt < 0] + Result;\n    end;\n    ctCheck: Result := '';\n  end;\nend;\n\nfunction wbScaledInt4ToInt(const aString: string; const aElement: IwbElement): Int64;\nvar\n  f: Extended;\nbegin\n  f := StrToFloat(aString);\n  f := f * 10000;\n  Result := Round(f);\nend;\n\nfunction wbHideFFFF(aInt: Int64; const aElement: IwbElement; aType: TwbCallbackType): string;\nbegin\n  Result := '';\n  if aType = ctToSortKey then\n    Result := IntToHex64(aInt, 4)\n  else if aType = ctToStr then\n    if aInt = $FFFF then\n      Result := 'None'\n    else\n      Result := IntToStr(aInt);\nend;\n\nfunction wbAtxtPosition(aInt: Int64; const aElement: IwbElement; aType: TwbCallbackType): string;\nbegin\n  Result := '';\n  if aType = ctToSortKey then\n    Result := IntToHex64(aInt div 17, 2) + IntToHex64(aInt mod 17, 2)\n  else if aType = ctCheck then begin\n    if (aInt < 0) or (aInt > 288) then\n      Result := '<Out of range: '+IntToStr(aInt)+'>'\n    else\n      Result := '';\n  end else if aType = ctToStr then\n    Result := IntToStr(aInt) + ' -> ' + IntToStr(aInt div 17) + ':' + IntToStr(aInt mod 17);\nend;\n\nfunction wbGLOBFNAM(aInt: Int64; const aElement: IwbElement; aType: TwbCallbackType): string;\nbegin\n  Result := '';\n  case aType of\n    ctToStr: begin\n      case aInt of\n        Ord('s'): Result := 'Short';\n        Ord('l'): Result := 'Long';\n        Ord('f'): Result := 'Float';\n      else\n        Result := '<Unknown: '+IntToStr(aInt)+'>';\n      end;\n    end;\n    ctToSortKey: Result := Chr(aInt);\n    ctCheck: begin\n      case aInt of\n        Ord('s'), Ord('l'), Ord('f'): Result := '';\n      else\n        Result := '<Unknown: '+IntToStr(aInt)+'>';\n      end;\n    end;\n  end;\nend;\n\nfunction wbPlacedAddInfo(const aMainRecord: IwbMainRecord): string;\nvar\n  Rec: IwbRecord;\n  Container: IwbContainer;\n  s: string;\n  Cell: IwbMainRecord;\n  Position: TwbVector;\n  Grid: TwbGridCell;\nbegin\n  Result := '';\n\n  Rec := aMainRecord.RecordBySignature['NAME'];\n  if Assigned(Rec) then begin\n    s := Trim(Rec.Value);\n    if s <> '' then\n      Result := 'places ' + s;\n  end;\n\n  Container := aMainRecord.Container;\n  while Assigned(Container) and (Container.ElementType <> etGroupRecord) do\n    Container := Container.Container;\n\n  if Assigned(Container) then begin\n    s := Trim(Container.Name);\n    if s <> '' then begin\n      if Result <> '' then\n        Result := Result + ' ';\n      Result := Result + 'in ' + s;\n\n      // grid position of persistent reference in exterior persistent cell (interior cells are not persistent)\n      if Supports(aMainRecord.Container, IwbGroupRecord, Container) then\n        Cell := IwbGroupRecord(Container).ChildrenOf;\n      if Assigned(Cell) and Cell.IsPersistent and (Cell.Signature = 'CELL') then\n        if aMainRecord.GetPosition(Position) then begin\n          Grid := wbPositionToGridCell(Position);\n          Result := Result + ' at ' + IntToStr(Grid.x) + ',' + IntToStr(Grid.y);\n        end;\n    end;\n  end;\nend;\n\nfunction wbINFOAddInfo(const aMainRecord: IwbMainRecord): string;\nvar\n  Container: IwbContainer;\n  s: string;\nbegin\n  Result := Trim(aMainRecord.ElementValues['Responses\\Response\\NAM1']);\n  if Result <> '' then\n    Result := '''' + Result + '''';\n\n  Container := aMainRecord.Container;\n  while Assigned(Container) and (Container.ElementType <> etGroupRecord) do\n    Container := Container.Container;\n\n  if Assigned(Container) then begin\n    s := Trim(Container.Name);\n    if s <> '' then begin\n      if Result <> '' then\n        Result := Result + ' ';\n      Result := Result + 'in ' + s;\n    end;\n  end;\n\n  s := Trim(aMainRecord.ElementValues['QSTI']);\n  if s <> '' then begin\n    if Result <> '' then\n      Result := Result + ' ';\n    Result := Result + 'for ' + s;\n  end;\nend;\n\nfunction wbNAVMAddInfo(const aMainRecord: IwbMainRecord): string;\nvar\n  Rec        : IwbRecord;\n  Element    : IwbElement;\n  s          : string;\nbegin\n  Result := '';\n\n  Rec := aMainRecord.RecordBySignature['DATA'];\n  if Assigned(Rec) then begin\n    Element := Rec.ElementByName['Cell'];\n    if Assigned(Element) then\n      Element := Element.LinksTo;\n    if Assigned(Element) then\n      s := Trim(Element.Name);\n    if s <> '' then\n      Result := 'for ' + s;\n  end;\nend;\n\nfunction wbCellAddInfo(const aMainRecord: IwbMainRecord): string;\nvar\n  Rec: IwbRecord;\n  Container: IwbContainer;\n  GroupRecord : IwbGroupRecord;\n  s: string;\nbegin\n  Result := '';\n\n  if not aMainRecord.IsPersistent then begin\n    Rec := aMainRecord.RecordBySignature['XCLC'];\n    if Assigned(Rec) then\n      Result := 'at ' + Rec.Elements[0].Value + ',' + Rec.Elements[1].Value;\n  end;\n\n  Container := aMainRecord.Container;\n  while Assigned(Container) and not\n    (Supports(Container, IwbGroupRecord, GroupRecord) and (GroupRecord.GroupType = 1))  do\n    Container := Container.Container;\n\n  if Assigned(Container) then begin\n    s := wbFormID.ToString(GroupRecord.GroupLabel, aMainRecord);\n    if s <> '' then begin\n      if Result <> '' then\n        s := s + ' ';\n      Result := 'in ' + s + Result;\n    end;\n  end;\nend;\n\nfunction wbWthrDataClassification(aInt: Int64; const aElement: IwbElement; aType: TwbCallbackType): string;\nbegin\n  Result := '';\n  case aType of\n    ctToStr: begin\n      case aInt and not 192 of\n        0: Result := 'None';\n        1: Result := 'Pleasant';\n        2: Result := 'Cloudy';\n        4: Result := 'Rainy';\n        8: Result := 'Snow';\n      else\n        Result := '<Unknown: '+IntToStr(aInt and not 192)+'>';\n      end;\n    end;\n    ctToSortKey: begin\n      Result := IntToHex64(aInt, 2)\n    end;\n    ctCheck: begin\n      case aInt and not 192 of\n        0, 1, 2, 4, 8: Result := '';\n      else\n        Result := '<Unknown: '+IntToStr(aInt and not 192)+'>';\n      end;\n    end;\n  end;\nend;\n\nfunction wbNOTETNAMDecide(aBasePtr: Pointer; aEndPtr: Pointer; const aElement: IwbElement): Integer;\nvar\n  rDATA: IwbRecord;\nbegin\n  Result := 0;\n  rDATA := aElement.Container.RecordBySignature[DATA];\n  if Assigned(rDATA) then\n    if rDATA.NativeValue = 3 then //Voice\n      Result := 1;\nend;\n\nfunction wbNOTESNAMDecide(aBasePtr: Pointer; aEndPtr: Pointer; const aElement: IwbElement): Integer;\nvar\n  rDATA: IwbRecord;\nbegin\n  Result := 0;\n  rDATA := aElement.Container.RecordBySignature[DATA];\n  if Assigned(rDATA) then\n    if rDATA.NativeValue = 3 then //Voice\n      Result := 1;\nend;\n\nfunction wbIPDSDATACount(aBasePtr: Pointer; aEndPtr: Pointer; const aElement: IwbElement): Integer;\nbegin\n  if Assigned(aBasePtr) and Assigned(aEndPtr) then\n    Result := (Cardinal(aBasePtr) - Cardinal(aBasePtr)) div 4\n  else\n    Result := 12;\nend;\n\nfunction wbNAVINAVMGetCount1(aBasePtr: Pointer; aEndPtr: Pointer; const aElement: IwbElement): Integer;\nvar\n  DataContainer : IwbDataContainer;\nbegin\n  Result := 0;\n\n  if Supports(aElement, IwbDataContainer, DataContainer) then begin\n    if DataContainer.ElementType = etArray then\n      if not Supports(DataContainer.Container, IwbDataContainer, DataContainer) then\n        Exit;\n    Assert(DataContainer.Name = 'Data');\n    Result := PWord(Cardinal(DataContainer.DataBasePtr) + 3*3*4)^;\n  end;\nend;\n\nfunction wbNAVINAVMGetCount2(aBasePtr: Pointer; aEndPtr: Pointer; const aElement: IwbElement): Integer;\nvar\n  DataContainer : IwbDataContainer;\nbegin\n  Result := 0;\n\n  if Supports(aElement, IwbDataContainer, DataContainer) then begin\n    if DataContainer.ElementType = etArray then\n      if not Supports(DataContainer.Container, IwbDataContainer, DataContainer) then\n        Exit;\n    Assert(DataContainer.Name = 'Data');\n    Result := PWord(Cardinal(DataContainer.DataBasePtr) + 3*3*4 + 2)^;\n  end;\nend;\n\nprocedure wbCTDARunOnAfterSet(const aElement: IwbElement; const aOldValue, aNewValue: Variant);\nbegin\n  if aOldValue <> aNewValue then\n    if aNewValue <> 2 then\n      aElement.Container.ElementNativeValues['Reference'] := 0;\nend;\n\nprocedure wbPERKPRKETypeAfterSet(const aElement: IwbElement; const aOldValue, aNewValue: Variant);\nvar\n  Container : IwbContainerElementRef;\n//  rDATA     : IwbRecord;\nbegin\n  if aOldValue <> aNewValue then\n    if Supports(aElement.Container, IwbContainerElementRef, Container) then begin\n      if Supports(Container.Container, IwbContainerElementRef, Container) then begin\n        Container.RemoveElement('DATA');\n        Container.Add('DATA', True);\n        Container.RemoveElement('Perk Conditions');\n        Container.RemoveElement('Entry Point Function Parameters');\n        if aNewValue = 2 then begin\n          Container.Add('EPFT', True);\n          Container.ElementNativeValues['DATA\\Entry Point\\Function'] := 2;\n        end;\n      end;\n    end;\nend;\n\nfunction wbMGEFFAssocItemDecider(aBasePtr: Pointer; aEndPtr: Pointer; const aElement: IwbElement): Integer;\nvar\n  Container     : IwbContainer;\n  Archtype      : Variant;\n  DataContainer : IwbDataContainer;\n  Element       : IwbElement;\nconst\n  OffsetArchtype = 56;\n\nbegin\n  Result := 1;\n  if not Assigned(aElement) then Exit;\n  Container := GetContainerFromUnion(aElement);\n  if not Assigned(Container) then Exit;\n\n  VarClear(ArchType);\n  Element := Container.ElementByName['Archtype'];\n  if Assigned(Element) then\n    ArchType := Element.NativeValue\n  else if Supports(Container, IwbDataContainer, DataContainer) and\n          DataContainer.IsValidOffset(aBasePtr, aEndPtr, OffsetArchtype) then\n    begin // we are part of a proper structure\n      aBasePtr := Pointer(Cardinal(aBasePtr) + OffsetArchtype);\n      ArchType := PCardinal(aBasePtr)^;\n    end;\n\n  if not VarIsEmpty(ArchType) then\n    case Integer(ArchType) of\n      01: Result := 2;//Script\n      18: Result := 3;//Bound Item\n      19: Result := 4;//Summon Creature\n    else\n      Result := 0;\n    end;\nend;\n\nprocedure wbMGEFFAssocItemAfterSet(const aElement: IwbElement; const aOldValue, aNewValue: Variant);\nvar\n  Container : IwbContainer;\n  Element   : IwbElement;\nbegin\n  if not Assigned(aElement) then Exit;\n  Container := GetContainerFromUnion(aElement);\n  if not Assigned(Container) then Exit;\n  if (aNewValue <> 0) then begin\n    Element := Container.ElementByName['Archtype'];\n    if Assigned(Element) and Element.NativeValue = 0 then\n        Element.NativeValue := $FF; // Signals ArchType that it should not mess with us on the next change!\n  end;\nend;\n\nprocedure wbMGEFArchtypeAfterSet(const aElement: IwbElement; const aOldValue, aNewValue: Variant);\nvar\n  Container: IwbContainerElementRef;\nbegin\n  if VarSameValue(aOldValue, aNewValue) then\n    Exit;\n  if not Supports(aElement, IwbContainerElementRef, Container) then\n    Exit;\n  if (aNewValue < $FF) and (aOldValue < $FF) then begin\n    Container.ElementNativeValues['..\\Assoc. Item'] := 0;\n    case Integer(aNewValue) of\n      11: Container.ElementNativeValues['..\\Actor Value'] := 48;//Invisibility\n      12: Container.ElementNativeValues['..\\Actor Value'] := 49;//Chameleon\n      24: Container.ElementNativeValues['..\\Actor Value'] := 47;//Paralysis\n      36: Container.ElementNativeValues['..\\Actor Value'] := 51;//Turbo\n    else\n      Container.ElementNativeValues['..\\Actor Value'] := -1;\n    end;\n  end;\nend;\n\nprocedure wbCounterEffectsAfterSet(const aElement: IwbElement; const aOldValue, aNewValue: Variant);\nbegin\n  wbCounterByPathAfterSet('DATA - Data\\Counter effect count', aElement);\nend;\n\nprocedure wbMGEFAfterSet(const aElement: IwbElement; const aOldValue, aNewValue: Variant);\nbegin\n  wbCounterContainerByPathAfterSet('DATA - Data\\Counter effect count', 'Counter Effects', aElement);\nend;\n\nfunction wbCTDAReferenceDecider(aBasePtr: Pointer; aEndPtr: Pointer; const aElement: IwbElement): Integer;\nvar\n  Container     : IwbContainer;\nbegin\n  Result := 0;\n  if not Assigned(aElement) then Exit;\n  Container := GetContainerFromUnion(aElement);\n  if not Assigned(Container) then Exit;\n\n  if Integer(Container.ElementNativeValues['Run On']) = 2 then\n    Result := 1;\nend;\n\nfunction wbNAVINVMIDecider(aBasePtr: Pointer; aEndPtr: Pointer; const aElement: IwbElement): Integer;\nvar\n  Container     : IwbContainer;\nbegin\n  Result := 0;\n  if not Assigned(aElement) then Exit;\n  Container := GetContainerFromUnion(aElement);\n  if not Assigned(Container) then Exit;\n\n  case Integer(Container.ElementNativeValues['Type']) of\n    $00: Result :=1;\n    $20: Result :=2;\n    $30: Result :=3;\n  end;\nend;\n\nfunction wbIMGSSkinDimmerDecider(aBasePtr: Pointer; aEndPtr: Pointer; const aElement: IwbElement): Integer;\nvar\n  Container : IwbContainer;\n  SubRecord : IwbSubRecord;\nbegin\n  Result := 0;\n  if not Assigned(aElement) then Exit;\n  Container := GetContainerFromUnion(aElement);\n  if not Assigned(Container) then Exit;\n  if Supports(Container, IwbSubRecord, SubRecord) then\n    if SubRecord.SubRecordHeaderSize in [132, 148] then\n      Result := 1;\nend;\n\nfunction wbCOEDOwnerDecider(aBasePtr: Pointer; aEndPtr: Pointer; const aElement: IwbElement): Integer;\nvar\n  Container  : IwbContainer;\n  LinksTo    : IwbElement;\n  MainRecord : IwbMainRecord;\nbegin\n  Result := 0;\n  if not Assigned(aElement) then Exit;\n  Container := GetContainerFromUnion(aElement);\n  if not Assigned(Container) then Exit;\n\n  LinksTo := Container.ElementByName['Owner'].LinksTo;\n\n  if Supports(LinksTo, IwbMainRecord, MainRecord) then\n    if MainRecord.Signature = 'NPC_' then\n      Result := 1\n    else if MainRecord.Signature = 'FACT' then\n      Result := 2;\nend;\n\nfunction wbCreaLevelDecider(aBasePtr: Pointer; aEndPtr: Pointer; const aElement: IwbElement): Integer;\nvar\n  Container: IwbContainer;\n  i: Int64;\nbegin\n  Result := 0;\n  if not Assigned(aElement) then Exit;\n  Container := GetContainerFromUnion(aElement);\n  if not Assigned(Container) then Exit;\n  i := Container.ElementByName['Flags'].NativeValue;\n  if i and $00000080 <> 0 then\n    Result := 1;\nend;\n\n\nfunction wbGMSTUnionDecider(aBasePtr: Pointer; aEndPtr: Pointer; const aElement: IwbElement): Integer;\nvar\n  rEDID: IwbRecord;\n  s: string;\nbegin\n  Result := 1;\n  rEDID := aElement.Container.RecordBySignature[EDID];\n  if Assigned(rEDID) then begin\n    s := rEDID.Value;\n    if Length(s) > 0 then\n      case s[1] of\n        's': Result := 0;\n        'f': Result := 2;\n      end;\n  end;\nend;\n\nfunction wbFLSTLNAMIsSorted(const aContainer: IwbContainer): Boolean;\nvar\n  rEDID      : IwbRecord;\n  s          : string;\n  _File      : IwbFile;\n  MainRecord : IwbMainRecord;\nconst\n  OrderedList = 'OrderedList';\nbegin\n  Result := wbSortFLST; {>>> Should not be sorted according to Arthmoor and JustinOther, left as sorted for compatibility <<<}\n  rEDID := aContainer.RecordBySignature[EDID];\n  if Assigned(rEDID) then begin\n    s := rEDID.Value;\n    if Length(s) > Length(OrderedList) then\n      Delete(s, 1, Length(s)-Length(OrderedList));\n    if SameText(s, OrderedList) then\n      Result := False;\n  end;\n  if Result then begin\n    MainRecord := aContainer.ContainingMainRecord;\n    if not Assigned(MainRecord) then\n      Exit;\n    MainRecord := MainRecord.MasterOrSelf;\n    if not Assigned(MainRecord) then\n      Exit;\n    _File := MainRecord._File;\n    if not Assigned(_File) then\n      Exit;\n    if not SameText(_File.FileName, 'WeaponModKits.esp') then\n      Exit;\n    case (MainRecord.FormID and $FFFFFF) of\n      $0130EB, $0130ED, $01522D, $01522E, $0158D5, $0158D6, $0158D7, $0158D8, $0158D9, $0158DA, $0158DC, $0158DD, $018E20:\n        Result := False;\n    end;\n  end;\nend;\n\nfunction wbPerkDATADecider(aBasePtr: Pointer; aEndPtr: Pointer; const aElement: IwbElement): Integer;\nvar\n  rPRKE: IwbRecord;\n  eType: IwbElement;\nbegin\n  Result := 0;\n  rPRKE := aElement.Container.RecordBySignature[PRKE];\n  if Assigned(rPRKE) then begin\n    eType := rPRKE.ElementByName['Type'];\n    if Assigned(eType) then begin\n      Result := eType.NativeValue;\n    end;\n  end;\nend;\n\nfunction wbEPFDDecider(aBasePtr: Pointer; aEndPtr: Pointer; const aElement: IwbElement): Integer;\nvar\n  Container: IwbContainerElementRef;\nbegin\n  Result := 0;\n  if not Assigned(aElement) then\n    Exit;\n  if not Supports(aElement.Container, IwbContainerElementRef, Container) then\n    Exit;\n  Result := Container.ElementNativeValues['EPFT'];\n  if Result = 2 then\n    if Integer(Container.ElementNativeValues['..\\DATA\\Entry Point\\Function']) = 5 then\n      Result := 5;\nend;\n\ntype\n  TCTDAFunctionParamType = (\n    ptNone,\n    ptInteger,\n    ptVariableName,  //Integer\n    ptSex,           //Enum: Male, Female\n    ptActorValue,    //Enum: wbActorValue\n    ptCrimeType,     //?? Enum\n    ptAxis,          //?? Char\n    ptQuestStage,    //?? Integer\n    ptMiscStat,      //?? Enum\n    ptAlignment,     //?? Enum\n    ptEquipType,     //?? Enum\n    ptFormType,      //?? Enum\n    ptCriticalStage, //?? Enum\n\n    ptObjectReference,    //REFR, ACHR, ACRE, PGRE\n    ptInventoryObject,    //ARMO, BOOK, MISC, WEAP, AMMO, KEYM, ALCH, NOTE, ARMA\n    ptActor,              //ACHR, ACRE\n    ptVoiceType,          //VTYP\n    ptIdleForm,           //IDLE\n    ptFormList,           //FLST\n    ptNote,               //NOTE\n    ptQuest,              //QUST\n    ptFaction,            //FACT\n    ptWeapon,             //WEAP\n    ptCell,               //CELL\n    ptClass,              //CLAS\n    ptRace,               //RACE\n    ptActorBase,          //NPC_, CREA\n    ptGlobal,             //GLOB\n    ptWeather,            //WTHR\n    ptPackage,            //PACK\n    ptEncounterZone,      //ECZN\n    ptPerk,               //PERK\n    ptOwner,              //FACT, NPC_\n    ptFurniture,          //FURN\n    ptMagicItem,          //SPEL\n    ptMagicEffect,        //MGEF\n    ptWorldspace,         //WRLD\n    ptVATSValueFunction,\n    ptVATSValueParam,\n    ptCreatureType,\n    ptMenuMode,\n    ptPlayerAction,\n    ptBodyLocation,\n    ptReferencableObject, //TREE, SOUN, ACTI, DOOR, STAT, FURN, CONT, ARMO, AMMO, MISC, WEAP, BOOK, KEYM, ALCH, LIGH, GRAS, ASPC, IDLM, ARMA, MSTT, NOTE, PWAT, SCOL, TACT, TERM\n    ptQuestObjective,     //?? Integer\n    ptReputation,         //REPU\n    ptRegion,             //REGN\n    ptChallenge,          //CHAL\n    ptCasino,             //CSNO\n    ptAnyForm             // Any form\n  );\n\n  PCTDAFunction = ^TCTDAFunction;\n  TCTDAFunction = record\n    Index: Integer;\n    Name: string;\n    ParamType1: TCTDAFunctionParamType;\n    ParamType2: TCTDAFunctionParamType;\n  end;\n\nconst\n  wbCTDAFunctions : array[0..288] of TCTDAFunction = (\n    (Index:   1; Name: 'GetDistance'; ParamType1: ptObjectReference),\n    (Index:   5; Name: 'GetLocked'),\n    (Index:   6; Name: 'GetPos'; ParamType1: ptAxis),\n    (Index:   8; Name: 'GetAngle'; ParamType1: ptAxis),\n    (Index:  10; Name: 'GetStartingPos'; ParamType1: ptAxis),\n    (Index:  11; Name: 'GetStartingAngle'; ParamType1: ptAxis),\n    (Index:  12; Name: 'GetSecondsPassed'),\n    (Index:  14; Name: 'GetActorValue'; ParamType1: ptActorValue),\n    (Index:  18; Name: 'GetCurrentTime'),\n    (Index:  24; Name: 'GetScale'),\n    (Index:  25; Name: 'IsMoving'),\n    (Index:  26; Name: 'IsTurning'),\n    (Index:  27; Name: 'GetLineOfSight'; ParamType1: ptObjectReference),\n    (Index:  32; Name: 'GetInSameCell'; ParamType1: ptObjectReference),\n    (Index:  35; Name: 'GetDisabled'),\n    (Index:  36; Name: 'MenuMode'; ParamType1: ptMenuMode),\n    (Index:  39; Name: 'GetDisease'),\n    (Index:  40; Name: 'GetVampire'),\n    (Index:  41; Name: 'GetClothingValue'),\n    (Index:  42; Name: 'SameFaction'; ParamType1: ptActor),\n    (Index:  43; Name: 'SameRace'; ParamType1: ptActor),\n    (Index:  44; Name: 'SameSex'; ParamType1: ptActor),\n    (Index:  45; Name: 'GetDetected'; ParamType1: ptActor),\n    (Index:  46; Name: 'GetDead'),\n    (Index:  47; Name: 'GetItemCount'; ParamType1: ptInventoryObject),\n    (Index:  48; Name: 'GetGold'),\n    (Index:  49; Name: 'GetSleeping'),\n    (Index:  50; Name: 'GetTalkedToPC'),\n    (Index:  53; Name: 'GetScriptVariable'; ParamType1: ptObjectReference; ParamType2: ptVariableName),\n    (Index:  56; Name: 'GetQuestRunning'; ParamType1: ptQuest),\n    (Index:  58; Name: 'GetStage'; ParamType1: ptQuest),\n    (Index:  59; Name: 'GetStageDone'; ParamType1: ptQuest; ParamType2: ptQuestStage),\n    (Index:  60; Name: 'GetFactionRankDifference'; ParamType1: ptFaction; ParamType2: ptActor),\n    (Index:  61; Name: 'GetAlarmed'),\n    (Index:  62; Name: 'IsRaining'),\n    (Index:  63; Name: 'GetAttacked'),\n    (Index:  64; Name: 'GetIsCreature'),\n    (Index:  65; Name: 'GetLockLevel'),\n    (Index:  66; Name: 'GetShouldAttack'; ParamType1: ptActor),\n    (Index:  67; Name: 'GetInCell'; ParamType1: ptCell),\n    (Index:  68; Name: 'GetIsClass'; ParamType1: ptClass),\n    (Index:  69; Name: 'GetIsRace'; ParamType1: ptRace),\n    (Index:  70; Name: 'GetIsSex'; ParamType1: ptSex),\n    (Index:  71; Name: 'GetInFaction'; ParamType1: ptFaction),\n    (Index:  72; Name: 'GetIsID'; ParamType1: ptReferencableObject),\n    (Index:  73; Name: 'GetFactionRank'; ParamType1: ptFaction),\n    (Index:  74; Name: 'GetGlobalValue'; ParamType1: ptGlobal),\n    (Index:  75; Name: 'IsSnowing'),\n    (Index:  76; Name: 'GetDisposition'; ParamType1: ptActor),\n    (Index:  77; Name: 'GetRandomPercent'),\n    (Index:  79; Name: 'GetQuestVariable'; ParamType1: ptQuest; ParamType2: ptVariableName),\n    (Index:  80; Name: 'GetLevel'),\n    (Index:  81; Name: 'GetArmorRating'),\n    (Index:  84; Name: 'GetDeadCount'; ParamType1: ptActorBase),\n    (Index:  91; Name: 'GetIsAlerted'),\n    (Index:  98; Name: 'GetPlayerControlsDisabled'; ParamType1: ptInteger; ParamType2: ptInteger{; ParamType3: ptInteger; ParamType4: ptInteger; ParamType5: ptInteger; ParamType6: ptInteger; ParamType7: ptInteger}),\n    (Index:  99; Name: 'GetHeadingAngle'; ParamType1: ptObjectReference),\n    (Index: 101; Name: 'IsWeaponOut'),\n    (Index: 102; Name: 'IsTorchOut'),\n    (Index: 103; Name: 'IsShieldOut'),\n    (Index: 106; Name: 'IsFacingUp'),\n    (Index: 107; Name: 'GetKnockedState'),\n    (Index: 108; Name: 'GetWeaponAnimType'),\n    (Index: 109; Name: 'IsWeaponSkillType'; ParamType1: ptActorValue),\n    (Index: 110; Name: 'GetCurrentAIPackage'),\n    (Index: 111; Name: 'IsWaiting'),\n    (Index: 112; Name: 'IsIdlePlaying'),\n    (Index: 116; Name: 'GetMinorCrimeCount'),\n    (Index: 117; Name: 'GetMajorCrimeCount'),\n    (Index: 118; Name: 'GetActorAggroRadiusViolated'),\n    (Index: 122; Name: 'GetCrime'; ParamType1: ptActor; ParamType2: ptCrimeType),\n    (Index: 123; Name: 'IsGreetingPlayer'),\n    (Index: 125; Name: 'IsGuard'),\n    (Index: 127; Name: 'HasBeenEaten'),\n    (Index: 128; Name: 'GetFatiguePercentage'),\n    (Index: 129; Name: 'GetPCIsClass'; ParamType1: ptClass),\n    (Index: 130; Name: 'GetPCIsRace'; ParamType1: ptRace),\n    (Index: 131; Name: 'GetPCIsSex'; ParamType1: ptSex),\n    (Index: 132; Name: 'GetPCInFaction'; ParamType1: ptFaction),\n    (Index: 133; Name: 'SameFactionAsPC'),\n    (Index: 134; Name: 'SameRaceAsPC'),\n    (Index: 135; Name: 'SameSexAsPC'),\n    (Index: 136; Name: 'GetIsReference'; ParamType1: ptObjectReference),\n    (Index: 141; Name: 'IsTalking'),\n    (Index: 142; Name: 'GetWalkSpeed'),\n    (Index: 143; Name: 'GetCurrentAIProcedure'),\n    (Index: 144; Name: 'GetTrespassWarningLevel'),\n    (Index: 145; Name: 'IsTrespassing'),\n    (Index: 146; Name: 'IsInMyOwnedCell'),\n    (Index: 147; Name: 'GetWindSpeed'),\n    (Index: 148; Name: 'GetCurrentWeatherPercent'),\n    (Index: 149; Name: 'GetIsCurrentWeather'; ParamType1: ptWeather),\n    (Index: 150; Name: 'IsContinuingPackagePCNear'),\n    (Index: 153; Name: 'CanHaveFlames'),\n    (Index: 154; Name: 'HasFlames'),\n    (Index: 157; Name: 'GetOpenState'),\n    (Index: 159; Name: 'GetSitting'),\n    (Index: 160; Name: 'GetFurnitureMarkerID'),\n    (Index: 161; Name: 'GetIsCurrentPackage'; ParamType1: ptPackage),\n    (Index: 162; Name: 'IsCurrentFurnitureRef'; ParamType1: ptObjectReference),\n    (Index: 163; Name: 'IsCurrentFurnitureObj'; ParamType1: ptFurniture),\n    (Index: 170; Name: 'GetDayOfWeek'),\n    (Index: 172; Name: 'GetTalkedToPCParam'; ParamType1: ptActor),\n    (Index: 175; Name: 'IsPCSleeping'),\n    (Index: 176; Name: 'IsPCAMurderer'),\n    (Index: 180; Name: 'GetDetectionLevel'; ParamType1: ptActor),\n    (Index: 182; Name: 'GetEquipped'; ParamType1: ptInventoryObject),\n    (Index: 185; Name: 'IsSwimming'),\n    (Index: 190; Name: 'GetAmountSoldStolen'),\n    (Index: 192; Name: 'GetIgnoreCrime'),\n    (Index: 193; Name: 'GetPCExpelled'; ParamType1: ptFaction),\n    (Index: 195; Name: 'GetPCFactionMurder'; ParamType1: ptFaction),\n    (Index: 197; Name: 'GetPCEnemyofFaction'; ParamType1: ptFaction),\n    (Index: 199; Name: 'GetPCFactionAttack'; ParamType1: ptFaction),\n    (Index: 203; Name: 'GetDestroyed'),\n    (Index: 214; Name: 'HasMagicEffect'; ParamType1: ptMagicEffect),\n    (Index: 215; Name: 'GetDefaultOpen'),\n    (Index: 219; Name: 'GetAnimAction'),\n    (Index: 223; Name: 'IsSpellTarget'; ParamType1: ptMagicItem),\n    (Index: 224; Name: 'GetVATSMode'),\n    (Index: 225; Name: 'GetPersuasionNumber'),\n    (Index: 226; Name: 'GetSandman'),\n    (Index: 227; Name: 'GetCannibal'),\n    (Index: 228; Name: 'GetIsClassDefault'; ParamType1: ptClass),\n    (Index: 229; Name: 'GetClassDefaultMatch'),\n    (Index: 230; Name: 'GetInCellParam'; ParamType1: ptCell; ParamType2: ptObjectReference),\n    (Index: 235; Name: 'GetVatsTargetHeight'),\n    (Index: 237; Name: 'GetIsGhost'),\n    (Index: 242; Name: 'GetUnconscious'),\n    (Index: 244; Name: 'GetRestrained'),\n    (Index: 246; Name: 'GetIsUsedItem'; ParamType1: ptReferencableObject),\n    (Index: 247; Name: 'GetIsUsedItemType'; ParamType1: ptFormType),\n    (Index: 254; Name: 'GetIsPlayableRace'),\n    (Index: 255; Name: 'GetOffersServicesNow'),\n    (Index: 258; Name: 'GetUsedItemLevel'),\n    (Index: 259; Name: 'GetUsedItemActivate'),\n    (Index: 264; Name: 'GetBarterGold'),\n    (Index: 265; Name: 'IsTimePassing'),\n    (Index: 266; Name: 'IsPleasant'),\n    (Index: 267; Name: 'IsCloudy'),\n    (Index: 274; Name: 'GetArmorRatingUpperBody'),\n    (Index: 277; Name: 'GetBaseActorValue'; ParamType1: ptActorValue),\n    (Index: 278; Name: 'IsOwner'; ParamType1: ptOwner),\n    (Index: 280; Name: 'IsCellOwner'; ParamType1: ptCell; ParamType2: ptOwner),\n    (Index: 282; Name: 'IsHorseStolen'),\n    (Index: 285; Name: 'IsLeftUp'),\n    (Index: 286; Name: 'IsSneaking'),\n    (Index: 287; Name: 'IsRunning'),\n    (Index: 288; Name: 'GetFriendHit'),\n    (Index: 289; Name: 'IsInCombat'),\n    (Index: 300; Name: 'IsInInterior'),\n    (Index: 304; Name: 'IsWaterObject'),\n    (Index: 306; Name: 'IsActorUsingATorch'),\n    (Index: 309; Name: 'IsXBox'),\n    (Index: 310; Name: 'GetInWorldspace'; ParamType1: ptWorldSpace),\n    (Index: 312; Name: 'GetPCMiscStat'; ParamType1: ptMiscStat),\n    (Index: 313; Name: 'IsActorEvil'),\n    (Index: 314; Name: 'IsActorAVictim'),\n    (Index: 315; Name: 'GetTotalPersuasionNumber'),\n    (Index: 318; Name: 'GetIdleDoneOnce'),\n    (Index: 320; Name: 'GetNoRumors'),\n    (Index: 323; Name: 'WhichServiceMenu'),\n    (Index: 327; Name: 'IsRidingHorse'),\n    (Index: 332; Name: 'IsInDangerousWater'),\n    (Index: 338; Name: 'GetIgnoreFriendlyHits'),\n    (Index: 339; Name: 'IsPlayersLastRiddenHorse'),\n    (Index: 353; Name: 'IsActor'),\n    (Index: 354; Name: 'IsEssential'),\n    (Index: 358; Name: 'IsPlayerMovingIntoNewSpace'),\n    (Index: 361; Name: 'GetTimeDead'),\n    (Index: 362; Name: 'GetPlayerHasLastRiddenHorse'),\n    (Index: 365; Name: 'IsChild'),\n    (Index: 367; Name: 'GetLastPlayerAction'),\n    (Index: 368; Name: 'IsPlayerActionActive'; ParamType1: ptPlayerAction),\n    (Index: 370; Name: 'IsTalkingActivatorActor'; ParamType1: ptActor),\n    (Index: 372; Name: 'IsInList'; ParamType1: ptFormList),\n    (Index: 382; Name: 'GetHasNote'; ParamType1: ptNote),\n    (Index: 391; Name: 'GetHitLocation'),\n    (Index: 392; Name: 'IsPC1stPerson'),\n    (Index: 397; Name: 'GetCauseofDeath'),\n    (Index: 398; Name: 'IsLimbGone'; ParamType1: ptBodyLocation),\n    (Index: 399; Name: 'IsWeaponInList'; ParamType1: ptFormList),\n    (Index: 403; Name: 'HasFriendDisposition'),\n    (Index: 408; Name: 'GetVATSValue'; ParamType1: ptVATSValueFunction; ParamType2: ptVATSValueParam),\n    (Index: 409; Name: 'IsKiller'; ParamType1: ptActor),\n    (Index: 410; Name: 'IsKillerObject'; ParamType1: ptFormList),\n    (Index: 411; Name: 'GetFactionCombatReaction'; ParamType1: ptFaction; ParamType2: ptFaction),\n    (Index: 415; Name: 'Exists'; ParamType1: ptObjectReference),\n    (Index: 416; Name: 'GetGroupMemberCount'),\n    (Index: 417; Name: 'GetGroupTargetCount'),\n    (Index: 420; Name: 'GetObjectiveCompleted'; ParamType1: ptQuest; ParamType2: ptQuestObjective),\n    (Index: 421; Name: 'GetObjectiveDisplayed'; ParamType1: ptQuest; ParamType2: ptQuestObjective),\n    (Index: 427; Name: 'GetIsVoiceType'; ParamType1: ptVoiceType),\n    (Index: 428; Name: 'GetPlantedExplosive'),\n    (Index: 430; Name: 'IsActorTalkingThroughActivator'),\n    (Index: 431; Name: 'GetHealthPercentage'),\n    (Index: 433; Name: 'GetIsObjectType'; ParamType1: ptFormType),\n    (Index: 435; Name: 'GetDialogueEmotion'),\n    (Index: 436; Name: 'GetDialogueEmotionValue'),\n    (Index: 438; Name: 'GetIsCreatureType'; ParamType1: ptCreatureType),\n    (Index: 446; Name: 'GetInZone'; ParamType1: ptEncounterZone),\n    (Index: 449; Name: 'HasPerk'; ParamType1: ptPerk; ParamType2: ptInteger {boolean Alt}),\t// PlayerCharacter has 2 lists of perks\n    (Index: 450; Name: 'GetFactionRelation'; ParamType1: ptActor),\n    (Index: 451; Name: 'IsLastIdlePlayed'; ParamType1: ptIdleForm),\n    (Index: 454; Name: 'GetPlayerTeammate'),\n    (Index: 455; Name: 'GetPlayerTeammateCount'),\n    (Index: 459; Name: 'GetActorCrimePlayerEnemy'),\n    (Index: 460; Name: 'GetActorFactionPlayerEnemy'),\n    (Index: 462; Name: 'IsPlayerTagSkill'; ParamType1: ptActorValue),\n    (Index: 464; Name: 'IsPlayerGrabbedRef'; ParamType1: ptObjectReference),\n    (Index: 471; Name: 'GetDestructionStage'),\n    (Index: 474; Name: 'GetIsAlignment'; ParamType1: ptAlignment),\n    (Index: 478; Name: 'GetThreatRatio'; ParamType1: ptActor),\n    (Index: 480; Name: 'GetIsUsedItemEquipType'; ParamType1: ptEquipType),\n    (Index: 489; Name: 'GetConcussed'),\n    (Index: 492; Name: 'GetMapMarkerVisible'),\n    (Index: 495; Name: 'GetPermanentActorValue'; ParamType1: ptActorValue),\n    (Index: 496; Name: 'GetKillingBlowLimb'),\n    (Index: 500; Name: 'GetWeaponHealthPerc'),\n    (Index: 503; Name: 'GetRadiationLevel'),\n    (Index: 510; Name: 'GetLastHitCritical'),\n    (Index: 515; Name: 'IsCombatTarget'; ParamType1: ptActor),\n    (Index: 518; Name: 'GetVATSRightAreaFree'; ParamType1: ptObjectReference),\n    (Index: 519; Name: 'GetVATSLeftAreaFree'; ParamType1: ptObjectReference),\n    (Index: 520; Name: 'GetVATSBackAreaFree'; ParamType1: ptObjectReference),\n    (Index: 521; Name: 'GetVATSFrontAreaFree'; ParamType1: ptObjectReference),\n    (Index: 522; Name: 'GetIsLockBroken'),\n    (Index: 523; Name: 'IsPS3'),\n    (Index: 524; Name: 'IsWin32'),\n    (Index: 525; Name: 'GetVATSRightTargetVisible'; ParamType1: ptObjectReference),\n    (Index: 526; Name: 'GetVATSLeftTargetVisible'; ParamType1: ptObjectReference),\n    (Index: 527; Name: 'GetVATSBackTargetVisible'; ParamType1: ptObjectReference),\n    (Index: 528; Name: 'GetVATSFrontTargetVisible'; ParamType1: ptObjectReference),\n    (Index: 531; Name: 'IsInCriticalStage'; ParamType1: ptCriticalStage),\n    (Index: 533; Name: 'GetXPForNextLevel'),\n    (Index: 546; Name: 'GetQuestCompleted'; ParamType1: ptQuest),\n    (Index: 550; Name: 'IsGoreDisabled'),\n    (Index: 555; Name: 'GetSpellUsageNum'; ParamType1: ptMagicItem),\n    (Index: 557; Name: 'GetActorsInHigh'),\n    (Index: 558; Name: 'HasLoaded3D'),\n    (Index: 573; Name: 'GetReputation'; ParamType1: ptReputation; ParamType2: ptInteger),\n    (Index: 574; Name: 'GetReputationPct'; ParamType1: ptReputation; ParamType2: ptInteger),\n    (Index: 575; Name: 'GetReputationThreshold'; ParamType1: ptReputation; ParamType2: ptInteger),\n    (Index: 586; Name: 'IsHardcore'),\n    (Index: 601; Name: 'GetForceHitReaction'),\n    (Index: 607; Name: 'ChallengeLocked'; ParamType1: ptChallenge),\n    (Index: 610; Name: 'GetCasinoWinningStage'; ParamType1: ptCasino),\n    (Index: 612; Name: 'PlayerInRegion'; ParamType1: ptRegion),\n    (Index: 614; Name: 'GetChallengeCompleted'; ParamType1: ptChallenge),\n    (Index: 619; Name: 'IsAlwaysHardcore'),\n\n    // Added by NVSE\n    (Index: 1024; Name: 'GetNVSEVersion'; ),\n    (Index: 1025; Name: 'GetNVSERevision'; ),\n    (Index: 1026; Name: 'GetNVSEBeta'; ),\n    (Index: 1028; Name: 'GetWeight'; ParamType1: ptInventoryObject; ),\n    (Index: 1076; Name: 'GetWeaponHasScope'; ParamType1: ptInventoryObject; ),\n    (Index: 1089; Name: 'ListGetFormIndex'; ParamType1: ptFormList; ParamType2: ptFormType;),\n    (Index: 1107; Name: 'IsKeyPressed'; ParamType1: ptInteger; ParamType2: ptInteger;),\n    (Index: 1131; Name: 'IsControlPressed'; ParamType1: ptInteger; ),\n    (Index: 1271; Name: 'HasOwnership'; ParamType1: ptObjectReference; ),\n    (Index: 1272; Name: 'IsOwned'; ParamType1: ptActor ),\n    (Index: 1274; Name: 'GetDialogueTarget'; ParamType1: ptActor; ),\n    (Index: 1275; Name: 'GetDialogueSubject'; ParamType1: ptActor; ),\n    (Index: 1276; Name: 'GetDialogueSpeaker'; ParamType1: ptActor; ),\n    (Index: 1278; Name: 'GetAgeClass'; ParamType1: ptActorBase; ),\n    (Index: 1286; Name: 'GetTokenValue'; ParamType1: ptFormType; ),\n    (Index: 1288; Name: 'GetTokenRef'; ParamType1: ptFormType; ),\n    (Index: 1291; Name: 'GetPaired'; ParamType1: ptInventoryObject; ParamType2: ptActorBase;),\n    (Index: 1292; Name: 'GetRespawn'; ParamType1: ptACtorBase; ),\n    (Index: 1294; Name: 'GetPermanent'; ParamType1: ptObjectReference; ),\n    (Index: 1297; Name: 'IsRefInList'; ParamType1: ptFormList; ParamType2: ptFormType;),\n    (Index: 1301; Name: 'GetPackageCount'; ParamType1: ptObjectReference; ),\n    (Index: 1440; Name: 'IsPlayerSwimming'; ),\n    (Index: 1441; Name: 'GetTFC'; ),\n    (Index: 1475; Name: 'GetPerkRank'; ParamType1: ptPerk; ParamType2: ptActor;),\n    (Index: 1476; Name: 'GetAltPerkRank'; ParamType1: ptPerk; ParamType2: ptActor;),\n    (Index: 1541; Name: 'GetActorFIKstatus'; ),\n\n    // Added by nvse_plugin_ExtendedActorVariable\n    (Index: 4352; Name: 'GetExtendedActorVariable'; ParamType1: ptInventoryObject; ),\n    (Index: 4353; Name: 'GetBaseExtendedActorVariable'; ParamType1: ptInventoryObject; ),\n    (Index: 4355; Name: 'GetModExtendedActorVariable'; ParamType1: ptInventoryObject; ),\n\n    // Added by nvse_extender\n    (Index: 4420; Name: 'NX_GetEVFl'; ParamType1: ptNone; ),  // Actually ptString, but it cannot be used in GECK\n    (Index: 4426; Name: 'NX_GetQVEVFl'; ParamType1: ptQuest; ParamType2: ptInteger;),\n\n    // Added by lutana_nvse\n    (Index: 4708; Name: 'GetArmorClass'; ParamType1: ptAnyForm; ),\n    (Index: 4709; Name: 'IsRaceInList'; ParamType1: ptFormList; ),\n    (Index: 4822; Name: 'GetReferenceFlag'; ParamType1: ptInteger; ),\n\n    // Added by JIP NVSE Plugin\n    (Index: 5637; Name: 'GetIsPoisoned'; ),\n    (Index: 5708; Name: 'IsEquippedWeaponSilenced'; ),\n    (Index: 5709; Name: 'IsEquippedWeaponScoped'; ),\n    (Index: 5953; Name: 'GetPCInRegion'; ParamType1: ptRegion; ),\n    (Index: 5962; Name: 'GetPCDetectionState'; )\n  );\n\nvar\n  wbCTDAFunctionEditInfo: string;\n\nfunction wbCTDAParamDescFromIndex(aIndex: Integer): PCTDAFunction;\nvar\n  L, H, I, C: Integer;\nbegin\n  Result := nil;\n\n  L := Low(wbCTDAFunctions);\n  H := High(wbCTDAFunctions);\n  while L <= H do begin\n    I := (L + H) shr 1;\n    C := CmpW32(wbCTDAFunctions[I].Index, aIndex);\n    if C < 0 then\n      L := I + 1\n    else begin\n      H := I - 1;\n      if C = 0 then begin\n        L := I;\n        Result := @wbCTDAFunctions[L];\n      end;\n    end;\n  end;\nend;\n\nfunction wbCTDACompValueDecider(aBasePtr: Pointer; aEndPtr: Pointer; const aElement: IwbElement): Integer;\nvar\n  Container: IwbContainer;\nbegin\n  Result := 0;\n  if not Assigned(aElement) then Exit;\n  Container := GetContainerFromUnion(aElement);\n  if not Assigned(Container) then Exit;\n  if Integer(Container.ElementByName['Type'].NativeValue) and $04 <> 0 then\n    Result := 1;\nend;\n\nfunction wbCTDAParam1Decider(aBasePtr: Pointer; aEndPtr: Pointer; const aElement: IwbElement): Integer;\nvar\n  Desc: PCTDAFunction;\n  Container: IwbContainer;\nbegin\n  Result := 0;\n  if not Assigned(aElement) then Exit;\n  Container := GetContainerFromUnion(aElement);\n  if not Assigned(Container) then Exit;\n  Desc := wbCTDAParamDescFromIndex(Container.ElementByName['Function'].NativeValue);\n  if Assigned(Desc) then\n    Result := Succ(Integer(Desc.ParamType1));\nend;\n\nfunction wbCTDAParam2VATSValueParam(aBasePtr: Pointer; aEndPtr: Pointer; const aElement: IwbElement): Integer;\nvar\n  Container : IwbContainer;\nbegin\n  Result := 0;\n  if not Assigned(aElement) then Exit;\n  Container := GetContainerFromUnion(aElement);\n  if not Assigned(Container) then Exit;\n  Result := Container.ElementByName['Parameter #1'].NativeValue;\nend;\n\nfunction wbCTDAParam2Decider(aBasePtr: Pointer; aEndPtr: Pointer; const aElement: IwbElement): Integer;\nvar\n  Desc: PCTDAFunction;\n  Container: IwbContainer;\nbegin\n  Result := 0;\n  if not Assigned(aElement) then Exit;\n  Container := GetContainerFromUnion(aElement);\n  if not Assigned(Container) then Exit;\n  Desc := wbCTDAParamDescFromIndex(Container.ElementByName['Function'].NativeValue);\n  if Assigned(Desc) then\n    Result := Succ(Integer(Desc.ParamType2));\nend;\n\nfunction wbCTDAFunctionToStr(aInt: Int64; const aElement: IwbElement; aType: TwbCallbackType): string;\nvar\n  Desc : PCTDAFunction;\n  i    : Integer;\nbegin\n  Result := '';\n  case aType of\n    ctToStr, ctToEditValue: begin\n      Desc := wbCTDAParamDescFromIndex(aInt);\n      if Assigned(Desc) then\n        Result := Desc.Name\n      else if aType = ctToEditValue then\n        Result := IntToStr(aInt)\n      else\n        Result := '<Unknown: '+IntToStr(aInt)+'>';\n    end;\n    ctToSortKey: Result := IntToHex(aInt, 8);\n    ctCheck: begin\n      Desc := wbCTDAParamDescFromIndex(aInt);\n      if Assigned(Desc) then\n        Result := ''\n      else\n        Result := '<Unknown: '+IntToStr(aInt)+'>';\n    end;\n    ctEditType:\n      Result := 'ComboBox';\n    ctEditInfo: begin\n      Result := wbCTDAFunctionEditInfo;\n      if Result = '' then begin\n        with TStringList.Create do try\n          for i := Low(wbCTDAFunctions) to High(wbCTDAFunctions) do\n            Add(wbCTDAFunctions[i].Name);\n          Sort;\n          Result := CommaText;\n        finally\n          Free;\n        end;\n        wbCTDAFunctionEditInfo := Result;\n      end;\n    end;\n  end;\nend;\n\nfunction wbCTDAFunctionToInt(const aString: string; const aElement: IwbElement): Int64;\nvar\n  i: Integer;\nbegin\n  for i := Low(wbCTDAFunctions) to High(wbCTDAFunctions) do\n    with wbCTDAFunctions[i] do\n      if SameText(Name, aString) then begin\n        Result := Index;\n        Exit;\n      end;\n  Result := StrToInt64(aString);\nend;\n\ntype\n  TPERKEntryPointConditionType = (\n    epcDefault,\n    epcItem,\n    epcWeapon,\n    epcWeaponTarget,\n    epcTarget,\n    epcAttacker,\n    epcAttackerAttackee,\n    epcAttackerAttackerWeapon\n  );\n\n  TPERKEntryPointFunctionType = (\n    epfFloat,\n    epfLeveledItem,\n    epfScript,\n    epfUnknown\n  );\n\n  TPERKEntryPointFunctionParamType = (\n    epfpNone,\n    epfpFloat,\n    epfpFloatFloat,\n    epfpLeveledItem,\n    epfpScript\n  );\n\n  PPERKEntryPoint = ^TPERKEntryPoint;\n  TPERKEntryPoint = record\n    Name         : string;\n    Condition   : TPERKEntryPointConditionType;\n    FunctionType : TPERKEntryPointFunctionType;\n  end;\n\n  PPERKCondition = ^TPERKCondition;\n  TPERKCondition = record\n    Count    : Integer;\n    Caption1 : string;\n    Caption2 : string;\n    Caption3 : string;\n  end;\n\n  PPERKFunction = ^TPERKFunction;\n  TPERKFunction = record\n    Name         : string;\n    FunctionType : TPERKEntryPointFunctionType;\n    ParamType    : TPERKEntryPointFunctionParamType;\n  end;\n\nconst\n  wbPERKCondition : array[TPERKEntryPointConditionType] of TPERKCondition = (\n    (Count: 1; Caption1: 'Perk Owner'),\n    (Count: 2; Caption1: 'Perk Owner'; Caption2: 'Item'),\n    (Count: 2; Caption1: 'Perk Owner'; Caption2: 'Weapon'),\n    (Count: 3; Caption1: 'Perk Owner'; Caption2: 'Weapon'; Caption3: 'Target'),\n    (Count: 2; Caption1: 'Perk Owner'; Caption2: 'Target'),\n    (Count: 2; Caption1: 'Perk Owner'; Caption2: 'Attacker'),\n    (Count: 3; Caption1: 'Perk Owner'; Caption2: 'Attacker'; Caption3: 'Attackee'),\n    (Count: 3; Caption1: 'Perk Owner'; Caption2: 'Attacker'; Caption3: 'Attacker Weapon')\n  );\n\n  wbPERKFunctions : array[0..9] of TPERKFunction = (\n    (Name: ''; FunctionType: epfUnknown; ParamType: epfpNone),\n    (Name: 'Set Value'; FunctionType: epfFloat; ParamType: epfpFloat),\n    (Name: 'Add Value'; FunctionType: epfFloat; ParamType: epfpFloat),\n    (Name: 'Multiply Value'; FunctionType: epfFloat; ParamType: epfpFloat),\n    (Name: 'Add Range To Value'; FunctionType: epfFloat; ParamType: epfpFloatFloat),\n    (Name: 'Add Actor Value Mult'; FunctionType: epfFloat; ParamType: epfpFloatFloat),\n    (Name: 'Absolute Value'; FunctionType: epfFloat; ParamType: epfpNone),\n    (Name: 'Negative Absolute Value'; FunctionType: epfFloat; ParamType: epfpNone),\n    (Name: 'Add Leveled List'; FunctionType: epfLeveledItem; ParamType: epfpLeveledItem),\n    (Name: 'Add Activate Choice'; FunctionType: epfScript; ParamType: epfpScript)\n  );\n\n  wbPERKEntryPoints : array[0..73] of TPERKEntryPoint = (\n    (Name: 'Calculate Weapon Damage'; Condition: epcWeaponTarget),\n    (Name: 'Calculate My Critical Hit Chance'; Condition: epcWeaponTarget),\n    (Name: 'Calculate My Critical Hit Damage'; Condition: epcWeaponTarget),\n    (Name: 'Calculate Weapon Attack AP Cost'; Condition: epcWeapon),\n    (Name: 'Calculate Mine Explode Chance'; Condition: epcItem),\n    (Name: 'Adjust Range Penalty'; Condition: epcWeapon),\n    (Name: 'Adjust Limb Damage'; Condition: epcAttackerAttackerWeapon),\n    (Name: 'Calculate Weapon Range'; Condition: epcWeapon),\n    (Name: 'Calculate To Hit Chance'; Condition: epcWeaponTarget),\n    (Name: 'Adjust Experience Points'),\n    (Name: 'Adjust Gained Skill Points'),\n    (Name: 'Adjust Book Skill Points'),\n    (Name: 'Modify Recovered Health'),\n    (Name: 'Calculate Inventory AP Cost'),\n    (Name: 'Get Disposition'; Condition: epcTarget),\n    (Name: 'Get Should Attack'; Condition: epcAttacker),\n    (Name: 'Get Should Assist'; Condition: epcAttackerAttackee),\n    (Name: 'Calculate Buy Price'; Condition: epcItem),\n    (Name: 'Get Bad Karma'),\n    (Name: 'Get Good Karma'),\n    (Name: 'Ignore Locked Terminal'),\n    (Name: 'Add Leveled List On Death'; Condition: epcTarget; FunctionType: epfLeveledItem),\n    (Name: 'Get Max Carry Weight'),\n    (Name: 'Modify Addiction Chance'),\n    (Name: 'Modify Addiction Duration'),\n    (Name: 'Modify Positive Chem Duration'),\n    (Name: 'Adjust Drinking Radiation'),\n    (Name: 'Activate'; Condition: epcTarget; FunctionType: epfScript),\n    (Name: 'Mysterious Stranger'),\n    (Name: 'Has Paralyzing Palm'),\n    (Name: 'Hacking Science Bonus'),\n    (Name: 'Ignore Running During Detection'),\n    (Name: 'Ignore Broken Lock'),\n    (Name: 'Has Concentrated Fire'),\n    (Name: 'Calculate Gun Spread'; Condition: epcWeapon),\n    (Name: 'Player Kill AP Reward'; Condition: epcWeaponTarget),\n{36}(Name: 'Modify Enemy Critical Hit Chance'; Condition: epcWeaponTarget),\n{37}(Name: 'Reload Speed'; Condition: epcWeapon),\n{38}(Name: 'Equip Speed'; Condition: epcWeapon),\n{39}(Name: 'Action Point Regen'; Condition: epcWeapon),\n{40}(Name: 'Action Point Cost'; Condition: epcWeapon),\n{41}(Name: 'Miss Fortune'; Condition: epcDefault),\n{42}(Name: 'Modify Run Speed'; Condition: epcDefault),\n{43}(Name: 'Modify Attack Speed'; Condition: epcWeapon),\n{44}(Name: 'Modify Radiation Consumed'; Condition: epcDefault),\n{45}(Name: 'Has Pip Hacker'; Condition: epcDefault),\n{46}(Name: 'Has Meltdown'; Condition: epcDefault),\n{47}(Name: 'See Enemy Health'; Condition: epcDefault),\n{48}(Name: 'Has Jury Rigging'; Condition: epcDefault),\n{49}(Name: 'Modify Threat Range'; Condition: epcWeapon),\n{50}(Name: 'Modify Thread'; Condition: epcWeapon),\n{51}(Name: 'Has Fast Travel Always'; Condition: epcDefault),\n{52}(Name: 'Knockdown Chance'; Condition: epcWeapon),\n{53}(Name: 'Modify Weapon Strength Req'; Condition: epcWeapon),\n{54}(Name: 'Modify Aiming Move Speed'; Condition: epcWeapon),\n{55}(Name: 'Modify Light Items'; Condition: epcDefault),\n{56}(Name: 'Modify Damage Threshold (defender)'; Condition: epcWeaponTarget),\n{57}(Name: 'Modify Chance for Ammo Item'; Condition: epcWeapon),\n{58}(Name: 'Modify Damage Threshold (attacker)'; Condition: epcWeaponTarget),\n{59}(Name: 'Modify Throwing Velocity'; Condition: epcWeapon),\n{60}(Name: 'Chance for Item on Fire'; Condition: epcWeapon),\n{61}(Name: 'Has Unarmed Forward Power Attack'; Condition: epcDefault),\n{62}(Name: 'Has Unarmed Back Power Attack'; Condition: epcWeaponTarget),\n{63}(Name: 'Has Unarmed Crouched Power Attack'; Condition: epcDefault),\n{64}(Name: 'Has Unarmed Counter Attack'; Condition: epcWeaponTarget),\n{65}(Name: 'Has Unarmed Left Power Attack'; Condition: epcDefault),\n{66}(Name: 'Has Unarmed Right Power Attack'; Condition: epcDefault),\n{67}(Name: 'VATS HelperChance'; Condition: epcDefault),\n{68}(Name: 'Modify Item Damage'; Condition: epcDefault),\n{69}(Name: 'Has Improved Detection'; Condition: epcDefault),\n{70}(Name: 'Has Improved Spotting'; Condition: epcDefault),\n{71}(Name: 'Has Improved Item Detection'; Condition: epcDefault),\n{72}(Name: 'Adjust Explosion Radius'; Condition: epcWeapon),\n{73}(Name: 'Reserved'; Condition: epcWeapon)\n  );\n\n  wbPERKFunctionParams: array[TPERKEntryPointFunctionParamType] of string = (\n    'None',\n    'Float',\n    'Float, Float',\n    'Leveled Item',\n    'Script'\n  );\n\nprocedure wbPERKEntryPointAfterSet(const aElement: IwbElement; const aOldValue, aNewValue: Variant);\nvar\n  OldEntryPoint   : PPERKEntryPoint;\n  NewEntryPoint   : PPERKEntryPoint;\n  OldCondition    : PPERKCondition;\n  NewCondition    : PPERKCondition;\n  OldFunction     : PPERKFunction;\n  EntryPoint      : IwbContainerElementRef;\n  Effect          : IwbContainerElementRef;\n  PerkConditions  : IwbContainerElementRef;\n  PerkCondition   : IwbContainerElementRef;\n  Container       : IwbContainerElementRef;\n  i               : Integer;\nbegin\n  if aOldValue <> aNewValue then begin\n    OldEntryPoint := @wbPERKEntryPoints[Integer(aOldValue)];\n    NewEntryPoint := @wbPERKEntryPoints[Integer(aNewValue)];\n    OldCondition := @wbPERKCondition[OldEntryPoint.Condition];\n    NewCondition := @wbPERKCondition[NewEntryPoint.Condition];\n    if not Assigned(aElement) then\n      Exit;\n    if not Supports(aElement.Container, IwbContainerElementRef, EntryPoint) then\n      Exit;\n    i := EntryPoint.ElementNativeValues['Function'];\n    if (i >= Low(wbPERKFunctions)) and (i <= High(wbPERKFunctions)) then\n      OldFunction := @wbPERKFunctions[i]\n    else\n      OldFunction := nil;\n    if not Assigned(OldFunction) or (OldFunction.FunctionType <> NewEntryPoint.FunctionType) then\n      for i := Low(wbPERKFunctions) to High(wbPERKFunctions) do\n        with wbPERKFunctions[i] do\n          if FunctionType = NewEntryPoint.FunctionType then begin\n            EntryPoint.ElementNativeValues['Function'] := i;\n            Break;\n          end;\n    EntryPoint.ElementNativeValues['Perk Condition Tab Count'] := NewCondition.Count;\n\n    if not Supports(EntryPoint.Container, IwbContainerElementRef, Container) then\n      Exit;\n    if not Supports(Container.Container, IwbContainerElementRef, Effect) then\n      Exit;\n\n    if not Supports(Effect.ElementByName['Perk Conditions'], IwbContainerElementRef, PerkConditions) then\n      Exit;\n\n    for i := Pred(PerkConditions.ElementCount) downto 0 do\n      if Supports(PerkConditions.Elements[i], IwbContainerElementRef, PerkCondition) then\n        if Integer(PerkCondition.ElementNativeValues['PRKC']) >= NewCondition.Count then\n          PerkCondition.Remove\n        else\n          case Integer(PerkCondition.ElementNativeValues['PRKC']) of\n            2: if OldCondition.Caption2 <> NewCondition.Caption2 then\n                 PerkCondition.Remove;\n            3: if OldCondition.Caption3 <> NewCondition.Caption3 then\n                 PerkCondition.Remove;\n          end;\n  end;\nend;\n\nfunction wbPRKCToStr(aInt: Int64; const aElement: IwbElement; aType: TwbCallbackType): string;\nvar\n  Container     : IwbContainerElementRef;\n  EntryPointVar : Variant;\n  EntryPoint    : Integer;\nbegin\n  case aType of\n    ctToStr: Result := IntToStr(aInt) + ' <Warning: Could not resolve Entry Point>';\n    ctToEditValue: Result := IntToStr(aInt);\n    ctToSortKey: begin\n      Result := IntToHex64(aInt, 2);\n      Exit;\n    end;\n    ctCheck: Result := '<Warning: Could not resolve Entry Point>';\n    ctEditType: Result := '';\n    ctEditInfo: Result := '';\n  end;\n\n  if not Supports(aElement, IwbContainerElementRef, Container) then\n    Exit;\n  EntryPointVar := Container.ElementNativeValues['..\\..\\..\\DATA\\Entry Point\\Entry Point'];\n  if VarIsNull(EntryPointVar) or VarIsClear(EntryPointVar) then\n    Exit;\n  EntryPoint := EntryPointVar;\n  if (EntryPoint < Low(wbPERKEntryPoints)) or (EntryPoint > High(wbPERKEntryPoints)) then begin\n    case aType of\n      ctToStr: Result := IntToStr(aInt) + ' <Warning: Unknown Entry Point #'+IntToStr(EntryPoint)+'>';\n      ctCheck: Result := '<Warning: Unknown Entry Point #'+IntToStr(EntryPoint)+'>';\n    end;\n    Exit;\n  end;\n\n  with wbPERKEntryPoints[EntryPoint] do begin\n    with wbPERKCondition[Condition] do begin\n      case aType of\n        ctEditType: Result := 'ComboBox';\n        ctEditInfo: with TStringList.Create do try\n          if Caption1 <> '' then\n            Add(Caption1);\n          if Caption2 <> '' then\n            Add(Caption2);\n          if Caption3 <> '' then\n            Add(Caption3);\n          Sort;\n          Result := CommaText;\n        finally\n          Free;\n        end;\n      else\n        if (aInt < 0) or (aInt >= Count) then\n          case aType of\n            ctToStr: Result := IntToStr(aInt) + ' <Warning: Value out of Bounds for this Entry Point>';\n            ctCheck: Result := '<Warning: Value out of Bounds for this Entry Point>';\n          end\n        else\n          case aType of\n            ctToStr, ctToEditValue: case Integer(aInt) of\n              0: Result := Caption1;\n              1: Result := Caption2;\n              2: Result := Caption3;\n            end;\n            ctCheck: Result := '';\n          end;\n      end;\n    end;\n  end;\nend;\n\nfunction wbPRKCToInt(const aString: string; const aElement: IwbElement): Int64;\nvar\n  Container     : IwbContainerElementRef;\n  EntryPointVar : Variant;\n  EntryPoint    : Integer;\n  s             : string;\nbegin\n  s := Trim(aString);\n\n  Result := StrToInt64Def(s, Low(Integer));\n  if Result <> Low(Integer) then\n    Exit;\n  if s = '' then begin\n    Result := 0;\n    Exit;\n  end;\n\n  if not Supports(aElement, IwbContainerElementRef, Container) then\n    raise Exception.Create('Could not resolve Entry Point');\n  EntryPointVar := Container.ElementNativeValues['..\\..\\..\\DATA\\Entry Point\\Entry Point'];\n  if VarIsNull(EntryPointVar) or VarIsClear(EntryPointVar) then\n    raise Exception.Create('Could not resolve Entry Point');\n\n  EntryPoint := EntryPointVar;\n  if (EntryPoint < Low(wbPERKEntryPoints)) or (EntryPoint > High(wbPERKEntryPoints)) then\n    raise Exception.Create('Unknown Entry Point #'+IntToStr(EntryPoint));\n\n  with wbPERKEntryPoints[EntryPoint] do\n    with wbPERKCondition[Condition] do\n      if SameText(aString, Caption1) then\n        Result := 0\n      else if SameText(aString, Caption2) then\n        Result := 1\n      else if SameText(aString, Caption3) then\n        Result := 2\n      else\n        raise Exception.Create('\"'+s+'\" is not valid for this Entry Point');\nend;\n\nfunction wbNeverShow(const aElement: IwbElement): Boolean;\nbegin\n  Result := wbHideNeverShow;\nend;\n\nfunction GetREGNType(aElement: IwbElement): Integer;\nvar\n  Container: IwbContainerElementRef;\nbegin\n  Result := -1;\n  if not Assigned(aElement) then\n    Exit;\n  while aElement.Name <> 'Region Data Entry' do begin\n    aElement := aElement.Container;\n    if not Assigned(aElement) then\n      Exit;\n  end;\n  if not Supports(aElement, IwbContainerElementRef, Container) then\n    Exit;\n  Result := Container.ElementNativeValues['RDAT\\Type'];\nend;\n\nfunction wbREGNObjectsDontShow(const aElement: IwbElement): Boolean;\nbegin\n  Result := GetREGNType(aElement) <> 2;\nend;\n\nfunction wbREGNWeatherDontShow(const aElement: IwbElement): Boolean;\nbegin\n  Result := GetREGNType(aElement) <> 3;\nend;\n\nfunction wbREGNMapDontShow(const aElement: IwbElement): Boolean;\nbegin\n  Result := GetREGNType(aElement) <> 4;\nend;\n\nfunction wbREGNLandDontShow(const aElement: IwbElement): Boolean;\nbegin\n  Result := GetREGNType(aElement) <> 5;\nend;\n\nfunction wbREGNGrassDontShow(const aElement: IwbElement): Boolean;\nbegin\n  Result := GetREGNType(aElement) <> 6;\nend;\n\nfunction wbREGNSoundDontShow(const aElement: IwbElement): Boolean;\nbegin\n  Result := GetREGNType(aElement) <> 7;\nend;\n\nfunction wbREGNImposterDontShow(const aElement: IwbElement): Boolean;\nbegin\n  Result := GetREGNType(aElement) <> 8;\nend;\n\nfunction wbMESGTNAMDontShow(const aElement: IwbElement): Boolean;\nvar\n  Container  : IwbContainerElementRef;\n  MainRecord : IwbMainRecord;\nbegin\n  Result := False;\n  if not Supports(aElement, IwbMainRecord, MainRecord) then\n    Exit;\n  if not Supports(aElement, IwbContainerElementRef, Container) then\n    Exit;\n  if Integer(Container.ElementNativeValues['DNAM']) and 1 <> 0 then\n    Result := True;\nend;\n\nfunction wbEPFDDontShow(const aElement: IwbElement): Boolean;\nvar\n  Container: IwbContainerElementRef;\nbegin\n  Result := False;\n  if aElement.Name <> 'Entry Point Function Parameters' then\n    Exit;\n  if not Supports(aElement, IwbContainerElementRef, Container) then\n    Exit;\n  if not (Integer(Container.ElementNativeValues['EPFT']) in [1..3]) then\n    Result := True;\nend;\n\nfunction wbTES4ONAMDontShow(const aElement: IwbElement): Boolean;\nvar\n  MainRecord : IwbMainRecord;\nbegin\n  Result := False;\n  if not Assigned(aElement) then\n    Exit;\n  MainRecord := aElement.ContainingMainRecord;\n  if not Assigned(MainRecord) then\n    Exit;\n  if not MainRecord.IsESM then\n    Result := True;\nend;\n\n\nfunction wbEPF2DontShow(const aElement: IwbElement): Boolean;\nvar\n  Container: IwbContainerElementRef;\nbegin\n  Result := False;\n  if aElement.Name <> 'Entry Point Function Parameters' then\n    Exit;\n  if not Supports(aElement, IwbContainerElementRef, Container) then\n    Exit;\n  if not (Integer(Container.ElementNativeValues['EPFT']) in [4]) then\n    Result := True;\nend;\n\nfunction wbPERKPRKCDontShow(const aElement: IwbElement): Boolean;\nvar\n  Container: IwbContainerElementRef;\nbegin\n  Result := False;\n  if aElement.Name <> 'Effect' then\n    Exit;\n  if not Supports(aElement, IwbContainerElementRef, Container) then\n    Exit;\n  if Integer(Container.ElementNativeValues['PRKE\\Type']) <> 2 then\n    Result := True;\nend;\n\nfunction wbPerkDATAFunctionToStr(aInt: Int64; const aElement: IwbElement; aType: TwbCallbackType): string;\nvar\n  Container     : IwbContainerElementRef;\n  EntryPointVar : Variant;\n  EntryPoint    : Integer;\n  i             : Integer;\nbegin\n  case aType of\n    ctToStr: Result := IntToStr(aInt) + ' <Warning: Could not resolve Entry Point>';\n    ctToEditValue: Result := IntToStr(aInt);\n    ctToSortKey: begin\n      Result := IntToHex64(aInt, 2);\n      Exit;\n    end;\n    ctCheck: Result := '<Warning: Could not resolve Entry Point>';\n    ctEditType: Result := '';\n    ctEditInfo: Result := '';\n  end;\n\n  if not Supports(aElement, IwbContainerElementRef, Container) then\n    Exit;\n  EntryPointVar := Container.ElementNativeValues['..\\Entry Point'];\n  if VarIsNull(EntryPointVar) or VarIsClear(EntryPointVar) then\n    Exit;\n  EntryPoint := EntryPointVar;\n  if (EntryPoint < Low(wbPERKEntryPoints)) or (EntryPoint > High(wbPERKEntryPoints)) then begin\n    case aType of\n      ctToStr: Result := IntToStr(aInt) + ' <Warning: Unknown Entry Point #'+IntToStr(EntryPoint)+'>';\n      ctCheck: Result := '<Warning: Unknown Entry Point #'+IntToStr(EntryPoint)+'>';\n    end;\n    Exit;\n  end;\n\n  with wbPERKEntryPoints[EntryPoint] do begin\n    case aType of\n      ctEditType: Result := 'ComboBox';\n      ctEditInfo: with TStringList.Create do try\n        for i := Low(wbPERKFunctions) to High(wbPERKFunctions) do\n          if wbPERKFunctions[i].FunctionType = FunctionType then\n            if (wbPERKFunctions[i].Name <> '') then\n              Add(wbPERKFunctions[i].Name);\n        Sort;\n        Result := CommaText;\n      finally\n        Free;\n      end;\n    else\n      if (aInt < Low(wbPERKFunctions)) or (aInt > High(wbPERKFunctions)) then\n        case aType of\n          ctToStr: Result := IntToStr(aInt) + ' <Warning: Unknown Function>';\n          ctCheck: Result := '<Warning: Unknown Function>';\n        end\n      else\n        case aType of\n          ctToStr, ctToEditValue: begin\n            Result := wbPERKFunctions[Integer(aInt)].Name;\n            if (aType = ctToStr) and (wbPERKFunctions[Integer(aInt)].FunctionType <> FunctionType) then\n              Result := Result + ' <Warning: Value out of Bounds for this Entry Point>';\n          end;\n          ctCheck:\n            if wbPERKFunctions[Integer(aInt)].FunctionType <> FunctionType then\n              Result := '<Warning: Value out of Bounds for this Entry Point>'\n            else\n              Result := '';\n        end;\n    end;\n  end;\nend;\n\nfunction wbPerkDATAFunctionToInt(const aString: string; const aElement: IwbElement): Int64;\nvar\n  Container     : IwbContainerElementRef;\n  EntryPointVar : Variant;\n  EntryPoint    : Integer;\n  s             : string;\n  i             : Integer;\nbegin\n  s := Trim(aString);\n\n  Result := StrToInt64Def(s, Low(Integer));\n  if Result <> Low(Integer) then\n    Exit;\n  if s = '' then\n    raise Exception.Create('\"\" is not a valid value for this field');\n\n  if not Supports(aElement, IwbContainerElementRef, Container) then\n    raise Exception.Create('Could not resolve Entry Point');\n  EntryPointVar := Container.ElementNativeValues['..\\Entry Point'];\n  if VarIsNull(EntryPointVar) or VarIsClear(EntryPointVar) then\n    raise Exception.Create('Could not resolve Entry Point');\n\n  EntryPoint := EntryPointVar;\n  if (EntryPoint < Low(wbPERKEntryPoints)) or (EntryPoint > High(wbPERKEntryPoints)) then\n    raise Exception.Create('Unknown Entry Point #'+IntToStr(EntryPoint));\n\n  with wbPERKEntryPoints[EntryPoint] do\n    for i := Low(wbPERKFunctions) to High(wbPERKFunctions) do\n      if wbPERKFunctions[i].FunctionType = FunctionType then\n        if SameText(s, wbPERKFunctions[i].Name) then begin\n          Result := i;\n          Exit;\n        end;\n\n  raise Exception.Create('\"'+s+'\" is not valid for this Entry Point');\nend;\n\nprocedure wbPerkDATAFunctionAfterSet(const aElement: IwbElement; const aOldValue, aNewValue: Variant);\nvar\n  NewFunction : Integer;\n  Container   : IwbContainerElementRef;\n  OldParamType: Integer;\n  NewParamType: Integer;\nbegin\n  NewFunction := aNewValue;\n  if (NewFunction < Low(wbPERKFunctions)) or (NewFunction > High(wbPERKFunctions)) then\n    Exit;\n  if not Supports(aElement, IwbContainerElementRef, Container) then\n    Exit;\n  OldParamType := Container.ElementNativeValues['..\\..\\..\\Entry Point Function Parameters\\EPFT'];\n  NewParamType := Ord(wbPERKFunctions[NewFunction].ParamType);\n  if (OldParamType = NewParamType) and not VarSameValue(aOldValue, aNewValue) and (NewFunction in [4,5]) then\n    Container.ElementNativeValues['..\\..\\..\\Entry Point Function Parameters\\EPFT'] := 0;\n  Container.ElementNativeValues['..\\..\\..\\Entry Point Function Parameters\\EPFT'] := NewParamType;\nend;\n\nfunction wbPerkEPFTToStr(aInt: Int64; const aElement: IwbElement; aType: TwbCallbackType): string;\nvar\n  Container       : IwbContainerElementRef;\n  FunctionTypeVar : Variant;\n  FunctionType    : Integer;\n//  i               : Integer;\nbegin\n  case aType of\n    ctToStr: Result := IntToStr(aInt) + ' <Warning: Could not resolve Function>';\n    ctToEditValue: Result := IntToStr(aInt);\n    ctToSortKey: begin\n      Result := IntToHex64(aInt, 2);\n      Exit;\n    end;\n    ctCheck: Result := '<Warning: Could not resolve Function>';\n    ctEditType: Result := '';\n    ctEditInfo: Result := '';\n  end;\n\n  if not Supports(aElement, IwbContainerElementRef, Container) then\n    Exit;\n  FunctionTypeVar := Container.ElementNativeValues['..\\..\\DATA\\Entry Point\\Function'];\n  if VarIsNull(FunctionTypeVar) or VarIsClear(FunctionTypeVar) then\n    Exit;\n  FunctionType := FunctionTypeVar;\n  if (FunctionType < Low(wbPERKFunctions)) or (FunctionType > High(wbPERKFunctions)) then begin\n    case aType of\n      ctToStr: Result := IntToStr(aInt) + ' <Warning: Unknown Function #'+IntToStr(FunctionType)+'>';\n      ctCheck: Result := '<Warning: Unknown Function #'+IntToStr(FunctionType)+'>';\n    end;\n    Exit;\n  end;\n\n  with wbPERKFunctions[FunctionType] do begin\n    case aType of\n      ctEditType: Result := 'ComboBox';\n      ctEditInfo: Result := '\"' + wbPERKFunctionParams[ParamType] + '\"';\n    else\n      if (aInt < Ord(Low(wbPERKFunctionParams))) or (aInt > Ord(High(wbPERKFunctionParams))) then\n        case aType of\n          ctToStr: Result := IntToStr(aInt) + ' <Warning: Unknown Function Param Type>';\n          ctCheck: Result := '<Warning: Unknown Function Param Type>';\n        end\n      else\n        case aType of\n          ctToStr, ctToEditValue: begin\n            Result := wbPERKFunctionParams[TPERKEntryPointFunctionParamType(aInt)];\n            if (aType = ctToStr) and (TPERKEntryPointFunctionParamType(aInt) <> ParamType) then\n              Result := Result + ' <Warning: Value out of Bounds for this Function>';\n          end;\n          ctCheck:\n            if TPERKEntryPointFunctionParamType(aInt) <> ParamType then\n              Result := Result + ' <Warning: Value out of Bounds for this Function>'\n            else\n              Result := '';\n        end;\n    end;\n  end;\nend;\n\nfunction wbPerkEPFTToInt(const aString: string; const aElement: IwbElement): Int64;\nvar\n  Container       : IwbContainerElementRef;\n  FunctionTypeVar : Variant;\n  FunctionType    : Integer;\n  s               : string;\n//  i               : Integer;\n  j               : TPERKEntryPointFunctionParamType;\nbegin\n  s := Trim(aString);\n\n  Result := StrToInt64Def(s, Low(Integer));\n  if Result <> Low(Integer) then\n    Exit;\n  if s = '' then\n    raise Exception.Create('\"\" is not a valid value for this field');\n\n  if not Supports(aElement, IwbContainerElementRef, Container) then\n    raise Exception.Create('Could not resolve Function');\n  FunctionTypeVar := Container.ElementNativeValues['..\\..\\DATA\\Entry Point\\Function'];\n  if VarIsNull(FunctionTypeVar) or VarIsClear(FunctionTypeVar) then\n    raise Exception.Create('Could not resolve Function');\n\n  FunctionType := FunctionTypeVar;\n  if (FunctionType < Low(wbPERKFunctions)) or (FunctionType > High(wbPERKFunctions)) then\n    raise Exception.Create('Unknown Function #'+IntToStr(FunctionType));\n\n  with wbPERKFunctions[FunctionType] do begin\n    for j := Low(wbPERKFunctionParams) to High(wbPERKFunctionParams) do\n      if SameText(s, wbPERKFunctionParams[j]) then begin\n        if j <> ParamType then\n          raise Exception.Create('\"'+s+'\" is not a valid Parameter Type for Function \"'+Name+'\"');\n        Result := Ord(j);\n        Exit;\n      end;\n  end;\n\n  raise Exception.Create('\"'+s+'\" is not a valid Parameter Type');\nend;\n\nprocedure wbPerkEPFTAfterSet(const aElement: IwbElement; const aOldValue, aNewValue: Variant);\nvar\n  i: Integer;\n  Container: IwbContainerElementRef;\nbegin\n  if VarSameValue(aOldValue, aNewValue) then\n    Exit;\n  i := aNewValue;\n  if (i < Ord(Low(wbPERKFunctionParams))) or (i> Ord(High(wbPERKFunctionParams))) then\n    Exit;\n  if not Supports(aElement.Container, IwbContainerElementRef, Container) then\n    Exit;\n  Container.RemoveElement('EPFD');\n  Container.RemoveElement('EPF2');\n  Container.RemoveElement('EPF3');\n  Container.RemoveElement('Embedded Script');\n  case TPERKEntryPointFunctionParamType(i) of\n    epfpFloat, epfpFloatFloat, epfpLeveledItem:\n      Container.Add('EPFD', True);\n    epfpScript: begin\n      Container.Add('EPF2', True);\n      Container.Add('EPF3', True);\n      Container.Add('SCHR', True);\n    end;\n  end;\nend;\n\nprocedure wbRemoveOFST(const aElement: IwbElement);\nvar\n  Container: IwbContainer;\n  rOFST: IwbRecord;\nbegin\n  if not wbRemoveOffsetData then\n    Exit;\n\n  if Supports(aElement, IwbContainer, Container) then begin\n    if wbBeginInternalEdit then try\n      Container.RemoveElement(OFST);\n    finally\n      wbEndInternalEdit;\n    end else begin\n      rOFST := Container.RecordBySignature[OFST];\n      if Assigned(rOFST) then\n        Container.RemoveElement(rOFST);\n    end;\n  end;\nend;\n\nfunction wbActorTemplateUseTraits(const aElement: IwbElement): Boolean;\nvar\n  Element    : IwbElement;\n  MainRecord : IwbMainRecord;\n  i          : Int64;\nbegin\n  Result := False;\n  if not wbActorTemplateHide then Exit;\n  Element := GetElementFromUnion(aElement);\n  MainRecord := nil;\n  while Assigned(Element) and not Supports(Element, IwbMainRecord, MainRecord) do\n    Element := Element.Container;\n  if Assigned(MainRecord) then begin\n    i := MainRecord.ElementNativeValues['ACBS\\Template Flags'];\n    Result := (i and $00000001) <> 0;\n  end;\nend;\n\nfunction wbActorTemplateUseStats(const aElement: IwbElement): Boolean;\nvar\n  Element    : IwbElement;\n  MainRecord : IwbMainRecord;\n  i          : Int64;\nbegin\n  Result := False;\n  if not wbActorTemplateHide then Exit;\n  Element := GetElementFromUnion(aElement);\n  MainRecord := nil;\n  while Assigned(Element) and not Supports(Element, IwbMainRecord, MainRecord) do\n    Element := Element.Container;\n  if Assigned(MainRecord) then begin\n    i := MainRecord.ElementNativeValues['ACBS\\Template Flags'];\n    Result := (i and $00000002) <> 0;\n  end;\nend;\n\nfunction wbActorAutoCalcDontShow(const aElement: IwbElement): Boolean;\nvar\n  Element    : IwbElement;\n  MainRecord : IwbMainRecord;\n  i          : Int64;\nbegin\n  Result := False;\n  if not wbActorTemplateHide then Exit;\n  Element := GetElementFromUnion(aElement);\n  MainRecord := nil;\n  while Assigned(Element) and not Supports(Element, IwbMainRecord, MainRecord) do\n    Element := Element.Container;\n  if Assigned(MainRecord) then begin\n    i := MainRecord.ElementNativeValues['ACBS\\Flags'];\n    Result := (i and $00000010) <> 0;\n  end;\nend;\n\nfunction wbActorTemplateUseStatsAutoCalc(const aElement: IwbElement): Boolean;\nbegin\n  if not wbActorTemplateHide then\n    Result := False\n  else\n    Result := wbActorTemplateUseStats(aElement) or wbActorAutoCalcDontShow(aElement);\nend;\n\nfunction wbActorTemplateUseFactions(const aElement: IwbElement): Boolean;\nvar\n  Element    : IwbElement;\n  MainRecord : IwbMainRecord;\n  i          : Int64;\nbegin\n  Result := False;\n  if not wbActorTemplateHide then Exit;\n  Element := GetElementFromUnion(aElement);\n  MainRecord := nil;\n  while Assigned(Element) and not Supports(Element, IwbMainRecord, MainRecord) do\n    Element := Element.Container;\n  if Assigned(MainRecord) then begin\n    i := MainRecord.ElementNativeValues['ACBS\\Template Flags'];\n    Result := (i and $00000004) <> 0;\n  end;\nend;\n\nfunction wbActorTemplateUseActorEffectList(const aElement: IwbElement): Boolean;\nvar\n  Element    : IwbElement;\n  MainRecord : IwbMainRecord;\n  i          : Int64;\nbegin\n  Result := False;\n  if not wbActorTemplateHide then Exit;\n  Element := GetElementFromUnion(aElement);\n  MainRecord := nil;\n  while Assigned(Element) and not Supports(Element, IwbMainRecord, MainRecord) do\n    Element := Element.Container;\n  if Assigned(MainRecord) then begin\n    i := MainRecord.ElementNativeValues['ACBS\\Template Flags'];\n    Result := (i and $00000008) <> 0;\n  end;\nend;\n\nfunction wbActorTemplateUseAIData(const aElement: IwbElement): Boolean;\nvar\n  Element    : IwbElement;\n  MainRecord : IwbMainRecord;\n  i          : Int64;\nbegin\n  Result := False;\n  if not wbActorTemplateHide then Exit;\n  Element := GetElementFromUnion(aElement);\n  MainRecord := nil;\n  while Assigned(Element) and not Supports(Element, IwbMainRecord, MainRecord) do\n    Element := Element.Container;\n  if Assigned(MainRecord) then begin\n    i := MainRecord.ElementNativeValues['ACBS\\Template Flags'];\n    Result := (i and $00000010) <> 0;\n  end;\nend;\n\nfunction wbActorTemplateUseAIPackages(const aElement: IwbElement): Boolean;\nvar\n  Element    : IwbElement;\n  MainRecord : IwbMainRecord;\n  i          : Int64;\nbegin\n  Result := False;\n  if not wbActorTemplateHide then Exit;\n  Element := GetElementFromUnion(aElement);\n  MainRecord := nil;\n  while Assigned(Element) and not Supports(Element, IwbMainRecord, MainRecord) do\n    Element := Element.Container;\n  if Assigned(MainRecord) then begin\n    i := MainRecord.ElementNativeValues['ACBS\\Template Flags'];\n    Result := (i and $00000020) <> 0;\n  end;\nend;\n\nfunction wbActorTemplateUseModelAnimation(const aElement: IwbElement): Boolean;\nvar\n  Element    : IwbElement;\n  MainRecord : IwbMainRecord;\n  i          : Int64;\nbegin\n  Result := False;\n  if not wbActorTemplateHide then Exit;\n  Element := GetElementFromUnion(aElement);\n  MainRecord := nil;\n  while Assigned(Element) and not Supports(Element, IwbMainRecord, MainRecord) do\n    Element := Element.Container;\n  if Assigned(MainRecord) then begin\n    i := MainRecord.ElementNativeValues['ACBS\\Template Flags'];\n    Result := (i and $00000040) <> 0;\n  end;\nend;\n\nfunction wbActorTemplateUseBaseData(const aElement: IwbElement): Boolean;\nvar\n  Element    : IwbElement;\n  MainRecord : IwbMainRecord;\n  i          : Int64;\nbegin\n  Result := False;\n  if not wbActorTemplateHide then Exit;\n  Element := GetElementFromUnion(aElement);\n  MainRecord := nil;\n  while Assigned(Element) and not Supports(Element, IwbMainRecord, MainRecord) do\n    Element := Element.Container;\n  if Assigned(MainRecord) then begin\n    i := MainRecord.ElementNativeValues['ACBS\\Template Flags'];\n    Result := (i and $00000080) <> 0;\n  end;\nend;\n\nfunction wbActorTemplateUseInventory(const aElement: IwbElement): Boolean;\nvar\n  Element    : IwbElement;\n  MainRecord : IwbMainRecord;\n  i          : Int64;\nbegin\n  Result := False;\n  if not wbActorTemplateHide then Exit;\n  Element := GetElementFromUnion(aElement);\n  MainRecord := nil;\n  while Assigned(Element) and not Supports(Element, IwbMainRecord, MainRecord) do\n    Element := Element.Container;\n  if Assigned(MainRecord) then begin\n    i := MainRecord.ElementNativeValues['ACBS\\Template Flags'];\n    Result := (i and $00000100) <> 0;\n  end;\nend;\n\nfunction wbActorTemplateUseScript(const aElement: IwbElement): Boolean;\nvar\n  Element    : IwbElement;\n  MainRecord : IwbMainRecord;\n  i          : Int64;\nbegin\n  Result := False;\n  if not wbActorTemplateHide then Exit;\n  Element := GetElementFromUnion(aElement);\n  MainRecord := nil;\n  while Assigned(Element) and not Supports(Element, IwbMainRecord, MainRecord) do\n    Element := Element.Container;\n  if Assigned(MainRecord) then begin\n    i := MainRecord.ElementNativeValues['ACBS\\Template Flags'];\n    Result := (i and $00000200) <> 0;\n  end;\nend;\n\nprocedure wbCTDAAfterLoad(const aElement: IwbElement);\nvar\n  Container  : IwbContainerElementRef;\n  //Size       : Cardinal;\n  TypeFlags  : Cardinal;\nbegin\n  if wbBeginInternalEdit then try\n    if not Supports(aElement, IwbContainerElementRef, Container) then\n      Exit;\n\n    if Container.ElementCount < 1 then\n      Exit;\n\n    TypeFlags := Container.ElementNativeValues['Type'];\n    if (TypeFlags and $02) <> 0 then begin\n      if Container.DataSize = 20 then\n        Container.DataSize := 28;\n      Container.ElementNativeValues['Type'] := TypeFlags and not $02;\n      Container.ElementEditValues['Run On'] := 'Target';\n    end;\n  finally\n    wbEndInternalEdit;\n  end;\nend;\n\nprocedure wbMGEFAfterLoad(const aElement: IwbElement);\nvar\n  Container     : IwbContainerElementRef;\n  MainRecord    : IwbMainRecord;\n  OldActorValue : Integer;\n  NewActorValue : Integer;\nbegin\n  if wbBeginInternalEdit then try\n    if not Supports(aElement, IwbContainerElementRef, Container) then\n      Exit;\n\n    if Container.ElementCount < 1 then\n      Exit;\n\n    if not Supports(aElement, IwbMainRecord, MainRecord) then\n      Exit;\n\n    if MainRecord.IsDeleted then\n      Exit;\n\n    OldActorValue := Container.ElementNativeValues['DATA - Data\\Actor Value'];\n    NewActorValue := OldActorValue;\n    case Integer(Container.ElementNativeValues['DATA - Data\\Archtype']) of\n      01, //Script\n      02, //Dispel\n      03, //Cure Disease\n      13, //Light\n      16, //Lock\n      17, //Open\n      18, //Bound Item\n      19, //Summon Creature\n      30, //Cure Paralysis\n      31, //Cure Addiction\n      32, //Cure Poison\n      33, //Concussion\n      35: //Limb Condition\n        NewActorValue := -1;\n      11: //Invisibility\n        NewActorValue := 48; //Invisibility\n      12: //Chameleon\n        NewActorValue := 49; //Chameleon\n      24: //Paralysis\n        NewActorValue := 47; //Paralysis\n      36: //Turbo\n        NewActorValue := 51; //Turbo\n    end;\n    if OldActorValue <> NewActorValue then\n      Container.ElementNativeValues['DATA - Data\\Actor Value'] := NewActorValue;\n  finally\n    wbEndInternalEdit;\n  end;\nend;\n\nprocedure wbPACKAfterLoad(const aElement: IwbElement);\nvar\n  Container     : IwbContainerElementRef;\n  MainRecord    : IwbMainRecord;\n//  OldContainer  : IwbContainerElementRef;\n  NewContainer  : IwbContainerElementRef;\n//  NewContainer2 : IwbContainerElementRef;\nbegin\n  if wbBeginInternalEdit then try\n    if not Supports(aElement, IwbContainerElementRef, Container) then\n      Exit;\n\n    if Container.ElementCount < 1 then\n      Exit;\n\n    if not Supports(aElement, IwbMainRecord, MainRecord) then\n      Exit;\n\n    if MainRecord.IsDeleted then\n      Exit;\n\n    case Integer(Container.ElementNativeValues['PKDT - General\\Type']) of\n       0: begin {Find}\n         Container.Add('PTDT');\n       end;\n       1: begin {Follow}\n         Container.Add('PKFD');\n       end;\n       2: begin {Escort}\n       end;\n       3: begin {Eat}\n         Container.Add('PTDT');\n         Container.Add('PKED');\n       end;\n       4: begin {Sleep}\n         if not Container.ElementExists['Locations'] then\n           if Supports(Container.Add('Locations'), IwbContainerElementRef, NewContainer) then\n             NewContainer.ElementEditValues['PLDT - Location 1\\Type'] := 'Near editor location';\n       end;\n       5: begin {Wander}\n       end;\n       6: begin {Travel}\n       end;\n       7: begin {Accompany}\n       end;\n       8: begin {Use Item At}\n       end;\n       9: begin {Ambush}\n       end;\n      10: begin {Flee Not Combat}\n      end;\n      12: begin {Sandbox}\n      end;\n      13: begin {Patrol}\n         if not Container.ElementExists['Locations'] then\n           if Supports(Container.Add('Locations'), IwbContainerElementRef, NewContainer) then\n             NewContainer.ElementEditValues['PLDT - Location 1\\Type'] := 'Near linked reference';\n        Container.Add('PKPT');\n      end;\n      14: begin {Guard}\n      end;\n      15: begin {Dialogue}\n      end;\n      16: begin {Use Weapon}\n      end;\n    end;\n\n  finally\n    wbEndInternalEdit;\n  end;\nend;\n\nprocedure wbNPCAfterLoad(const aElement: IwbElement);\nvar\n  Container  : IwbContainerElementRef;\n  MainRecord : IwbMainRecord;\n//  BaseRecord : IwbMainRecord;\nbegin\n  if wbBeginInternalEdit then try\n    if not Supports(aElement, IwbContainerElementRef, Container) then\n      Exit;\n\n    if Container.ElementCount < 1 then\n      Exit;\n\n    if not Supports(aElement, IwbMainRecord, MainRecord) then\n      Exit;\n\n    if MainRecord.IsDeleted then\n      Exit;\n\n    if Container.ElementNativeValues['NAM5'] > 255 then\n      Container.ElementNativeValues['NAM5'] := 255;\n  finally\n    wbEndInternalEdit;\n  end;\nend;\n\nprocedure wbREFRAfterLoad(const aElement: IwbElement);\nvar\n  Container  : IwbContainerElementRef;\n  MainRecord : IwbMainRecord;\n  BaseRecord : IwbMainRecord;\nbegin\n  if wbBeginInternalEdit then try\n    if not Supports(aElement, IwbContainerElementRef, Container) then\n      Exit;\n\n    if Container.ElementCount < 1 then\n      Exit;\n\n    if not Supports(aElement, IwbMainRecord, MainRecord) then\n      Exit;\n\n    if MainRecord.IsDeleted then\n      Exit;\n\n    Container.RemoveElement('RCLR');\n\n    if Container.ElementExists['Ammo'] then begin\n      BaseRecord := MainRecord.BaseRecord;\n      if Assigned(BaseRecord) and (BaseRecord.Signature <> 'WEAP') then\n        Container.RemoveElement('Ammo');\n    end;\n  finally\n    wbEndInternalEdit;\n  end;\nend;\n\nprocedure wbINFOAfterLoad(const aElement: IwbElement);\nvar\n  Container  : IwbContainerElementRef;\n  MainRecord : IwbMainRecord;\nbegin\n  if wbBeginInternalEdit then try\n    if not Supports(aElement, IwbContainerElementRef, Container) then\n      Exit;\n\n    if Container.ElementCount < 1 then\n      Exit;\n\n    if not Supports(aElement, IwbMainRecord, MainRecord) then\n      Exit;\n\n    if MainRecord.IsDeleted then\n      Exit;\n\n    if (Integer(Container.ElementNativeValues['DATA\\Flags 1']) and $80) = 0 then\n      Container.RemoveElement('DNAM');\n\n    Container.RemoveElement('SNDD');\n\n    if Container.ElementNativeValues['DATA\\Type'] = 3 {Persuasion} then\n      Container.ElementNativeValues['DATA\\Type'] := 0 {Topic};\n  finally\n    wbEndInternalEdit;\n  end;\nend;\n\nprocedure wbCELLAfterLoad(const aElement: IwbElement);\nvar\n  Container    : IwbContainerElementRef;\n//  Container2   : IwbContainerElementRef;\n  MainRecord   : IwbMainRecord;\n//  i            : Integer;\nbegin\n  if wbBeginInternalEdit then try\n    if not Supports(aElement, IwbContainerElementRef, Container) then\n      Exit;\n\n    if Container.ElementCount < 1 then\n      Exit;\n\n    if not Supports(aElement, IwbMainRecord, MainRecord) then\n      Exit;\n\n    if MainRecord.IsDeleted then\n      Exit;\n\n    if (not Container.ElementExists['XCLW']) and ((Integer(Container.ElementNativeValues['DATA']) and $02) <> 0) then begin\n      Container.Add('XCLW', True);\n      Container.ElementEditValues['XCLW'] := 'Default';\n    end;\n\n    if (not Container.ElementExists['XNAM']) and ((Integer(Container.ElementNativeValues['DATA']) and $02) <> 0) then\n      Container.Add('XNAM', True);\n\n//    if Supports(Container.ElementBySignature[XCLR], IwbContainerElementRef, Container2) then begin\n//      for i:= Pred(Container2.ElementCount) downto 0 do\n//        if not Supports(Container2.Elements[i].LinksTo, IwbMainRecord, MainRecord) or (MainRecord.Signature <> 'REGN') then\n//          Container2.RemoveElement(i);\n//      if Container2.ElementCount < 1 then\n//        Container2.Remove;\n//    end;\n  finally\n    wbEndInternalEdit;\n  end;\nend;\n\nprocedure wbEmbeddedScriptAfterLoad(const aElement: IwbElement);\nvar\n  Container: IwbContainerElementRef;\nbegin\n  if wbBeginInternalEdit then try\n    if not Supports(aElement, IwbContainerElementRef, Container) then\n      Exit;\n\n    if Container.ElementCount < 1 then\n      Exit;\n\n    if Container.ElementEditValues['SCHR\\Type'] = 'Quest' then\n      Container.ElementEditValues['SCHR\\Type'] := 'Object';\n  finally\n    wbEndInternalEdit;\n  end;\nend;\n\n\nprocedure wbSOUNAfterLoad(const aElement: IwbElement);\nvar\n  Container: IwbContainerElementRef;\n  MainRecord   : IwbMainRecord;\n  OldCntr: IwbContainerElementRef;\n  NewCntr: IwbContainerElementRef;\n  NewCntr2: IwbContainerElementRef;\n  i: Integer;\nbegin\n  if wbBeginInternalEdit then try\n    if not Supports(aElement, IwbContainerElementRef, Container) then\n      Exit;\n\n    if Container.ElementCount < 1 then\n      Exit;\n\n    if not Supports(aElement, IwbMainRecord, MainRecord) then\n      Exit;\n\n    if MainRecord.IsDeleted then\n      Exit;\n\n    if Container.ElementExists['SNDD'] then\n      Exit;\n\n    if not Supports(Container.RemoveElement('SNDX - Sound Data'), IwbContainerElementRef, OldCntr) then\n      Exit;\n    if not Supports(Container.Add('SNDD', True), IwbContainerElementRef, NewCntr) then\n      Exit;\n    for i := 0 to Pred(Min(OldCntr.ElementCount, NewCntr.ElementCount)) do\n      NewCntr.Elements[i].Assign(Low(Integer), OldCntr.Elements[i], False);\n\n    if not Supports(NewCntr.ElementByName['Attenuation Curve'], IwbContainerElementRef, NewCntr2) then\n      Assert(False);\n    Assert(NewCntr2.ElementCount = 5);\n\n    if Supports(Container.RemoveElement('ANAM'), IwbContainerElementRef, OldCntr) then begin\n      Assert(OldCntr.ElementCount = 5);\n      for i := 0 to Pred(Min(OldCntr.ElementCount, NewCntr2.ElementCount)) do\n        NewCntr2.Elements[i].Assign(Low(Integer), OldCntr.Elements[i], False);\n    end else begin\n      NewCntr2.Elements[0].NativeValue := 100;\n      NewCntr2.Elements[1].NativeValue := 50;\n      NewCntr2.Elements[2].NativeValue := 20;\n      NewCntr2.Elements[3].NativeValue := 5;\n      NewCntr2.Elements[4].NativeValue := 0;\n    end;\n\n    if not Supports(NewCntr.ElementByName['Reverb Attenuation Control'], IwbContainerElementRef, NewCntr2) then\n      Assert(False);\n\n    if Supports(Container.RemoveElement('GNAM'), IwbContainerElementRef, OldCntr) then\n      NewCntr2.Assign(Low(Integer), OldCntr, False)\n    else\n      NewCntr2.NativeValue := 80;\n\n    if not Supports(NewCntr.ElementByName['Priority'], IwbContainerElementRef, NewCntr2) then\n      Assert(False);\n\n    if Supports(Container.RemoveElement('HNAM'), IwbContainerElementRef, OldCntr) then\n      NewCntr2.Assign(Low(Integer), OldCntr, False)\n    else\n      NewCntr2.NativeValue := 128;\n\n  finally\n    wbEndInternalEdit;\n  end;\nend;\n\nprocedure wbWATRAfterLoad(const aElement: IwbElement);\nvar\n  Container: IwbContainerElementRef;\n  MainRecord   : IwbMainRecord;\n//  AnimationMultiplier : Extended;\n//  AnimationAttackMultiplier : Extended;\n  OldCntr: IwbContainerElementRef;\n  NewCntr: IwbContainerElementRef;\n  i: Integer;\nbegin\n  if wbBeginInternalEdit then try\n    if not Supports(aElement, IwbContainerElementRef, Container) then\n      Exit;\n\n    if Container.ElementCount < 1 then\n      Exit;\n\n    if not Supports(aElement, IwbMainRecord, MainRecord) then\n      Exit;\n\n    if MainRecord.IsDeleted then\n      Exit;\n\n    if Container.ElementExists['DNAM'] then\n      Exit;\n\n    if not Supports(Container.RemoveElement('DATA - Visual Data'), IwbContainerElementRef, OldCntr) then\n      Exit;\n    if not Supports(Container.Add('DNAM', True), IwbContainerElementRef, NewCntr) then\n      Exit;\n    for i := 0 to Pred(Min(OldCntr.ElementCount, NewCntr.ElementCount)) do\n      if OldCntr.Elements[i].Name = 'Damage (Old Format)' then\n        Container.ElementNativeValues['DATA - Damage'] := OldCntr.Elements[i].NativeValue\n      else\n        NewCntr.Elements[i].Assign(Low(Integer), OldCntr.Elements[i], False);\n\n    NewCntr.ElementNativeValues['Noise Properties - Noise Layer One - Amplitude Scale'] := 1.0;\n    NewCntr.ElementNativeValues['Noise Properties - Noise Layer Two - Amplitude Scale'] := 0.5;\n    NewCntr.ElementNativeValues['Noise Properties - Noise Layer Three - Amplitude Scale'] := 0.25;\n  finally\n    wbEndInternalEdit;\n  end;\nend;\n\n\nprocedure wbWEAPAfterLoad(const aElement: IwbElement);\nvar\n  Container: IwbContainerElementRef;\n  MainRecord   : IwbMainRecord;\nbegin\n  if wbBeginInternalEdit then try\n    if not Supports(aElement, IwbContainerElementRef, Container) then\n      Exit;\n\n    if Container.ElementCount < 1 then\n      Exit;\n\n    if not Supports(aElement, IwbMainRecord, MainRecord) then\n      Exit;\n\n    if MainRecord.IsDeleted then\n      Exit;\n\n    if not Container.ElementExists['DNAM'] then\n      Exit;\n\n    if Container.ElementNativeValues['DNAM\\Animation Multiplier'] = 0.0 then\n      Container.ElementNativeValues['DNAM\\Animation Multiplier'] := 1.0;\n    if Container.ElementNativeValues['DNAM\\Animation Attack Multiplier'] = 0.0 then\n      Container.ElementNativeValues['DNAM\\Animation Attack Multiplier'] := 1.0;\n  finally\n    wbEndInternalEdit;\n  end;\nend;\n\nprocedure wbMESGAfterLoad(const aElement: IwbElement);\nvar\n  Container    : IwbContainerElementRef;\n  MainRecord   : IwbMainRecord;\n  IsMessageBox : Boolean;\n  HasTimeDelay : Boolean;\nbegin\n  if wbBeginInternalEdit then try\n    if not Supports(aElement, IwbContainerElementRef, Container) then\n      Exit;\n\n    if Container.ElementCount < 1 then\n      Exit;\n\n    if not Supports(aElement, IwbMainRecord, MainRecord) then\n      Exit;\n\n    if MainRecord.IsDeleted then\n      Exit;\n\n    IsMessageBox := (Integer(Container.ElementNativeValues['DNAM']) and 1) = 1;\n    HasTimeDelay := Container.ElementExists['TNAM'];\n\n    if IsMessageBox = HasTimeDelay then\n      if IsMessageBox then\n        Container.RemoveElement('TNAM')\n      else begin\n        if not Container.ElementExists['DNAM'] then\n          Container.Add('DNAM', True);\n        Container.ElementNativeValues['DNAM'] := Integer(Container.ElementNativeValues['DNAM']) or 1;\n      end;\n\n  finally\n    wbEndInternalEdit;\n  end;\nend;\n\n\nprocedure wbEFSHAfterLoad(const aElement: IwbElement);\nvar\n  Container: IwbContainerElementRef;\n  MainRecord   : IwbMainRecord;\n  FullParticleBirthRatio : Extended;\n  PersistantParticleBirthRatio : Extended;\nbegin\n  if wbBeginInternalEdit then try\n    if not Supports(aElement, IwbContainerElementRef, Container) then\n      Exit;\n\n    if Container.ElementCount < 1 then\n      Exit;\n\n    if not Supports(aElement, IwbMainRecord, MainRecord) then\n      Exit;\n\n    if MainRecord.IsDeleted then\n      Exit;\n\n    if not Container.ElementExists['DATA'] then\n      Exit;\n\n    FullParticleBirthRatio := Container.ElementNativeValues['DATA\\Particle Shader - Full Particle Birth Ratio'];\n    PersistantParticleBirthRatio := Container.ElementNativeValues['DATA\\Particle Shader - Persistant Particle Birth Ratio'];\n\n    if ((FullParticleBirthRatio <> 0) and (FullParticleBirthRatio <= 1)) then begin\n      FullParticleBirthRatio := FullParticleBirthRatio * 78.0;\n      Container.ElementNativeValues['DATA\\Particle Shader - Full Particle Birth Ratio'] := FullParticleBirthRatio;\n    end;\n\n    if ((PersistantParticleBirthRatio <> 0) and (PersistantParticleBirthRatio <= 1)) then begin\n      PersistantParticleBirthRatio := PersistantParticleBirthRatio * 78.0;\n      Container.ElementNativeValues['DATA\\Particle Shader - Persistant Particle Birth Ratio'] := PersistantParticleBirthRatio;\n    end;\n\n  finally\n    wbEndInternalEdit;\n  end;\nend;\n\nprocedure wbFACTAfterLoad(const aElement: IwbElement);\nvar\n  Container: IwbContainerElementRef;\n  MainRecord   : IwbMainRecord;\nbegin\n  if wbBeginInternalEdit then try\n    if not Supports(aElement, IwbContainerElementRef, Container) then\n      Exit;\n\n    if Container.ElementCount < 1 then\n      Exit;\n\n    if not Container.ElementExists['CNAM'] then\n      Exit;\n\n    if not Supports(aElement, IwbMainRecord, MainRecord) then\n      Exit;\n\n    if MainRecord.IsDeleted then\n      Exit;\n\n    Container.RemoveElement('CNAM');\n  finally\n    wbEndInternalEdit;\n  end;\nend;\n\nprocedure wbLIGHAfterLoad(const aElement: IwbElement);\nvar\n  Container: IwbContainerElementRef;\n  MainRecord   : IwbMainRecord;\nbegin\n  if wbBeginInternalEdit then try\n    if not Supports(aElement, IwbContainerElementRef, Container) then\n      Exit;\n\n    if Container.ElementCount < 1 then\n      Exit;\n\n    if not Supports(aElement, IwbMainRecord, MainRecord) then\n      Exit;\n\n    if MainRecord.IsDeleted then\n      Exit;\n\n    if not Container.ElementExists['FNAM'] then begin\n      Container.Add('FNAM', True);\n      Container.ElementNativeValues['FNAM'] := 1.0;\n    end;\n\n    if Container.ElementExists['DATA'] then begin\n      if SameValue(Container.ElementNativeValues['DATA\\Falloff Exponent'], 0.0) then\n        Container.ElementNativeValues['DATA\\Falloff Exponent'] := 1.0;\n      if SameValue(Container.ElementNativeValues['DATA\\FOV'], 0.0) then\n        Container.ElementNativeValues['DATA\\FOV'] := 90.0;\n    end;\n\n  finally\n    wbEndInternalEdit;\n  end;\nend;\n\nprocedure wbEFITAfterLoad(const aElement: IwbElement);\nvar\n  Container : IwbContainerElementRef;\n  Element   : IwbElement;\n  ActorValue: Variant;\n  MainRecord: IwbMainRecord;\nbegin\n  if wbBeginInternalEdit then try\n    if not Supports(aElement, IwbContainerElementRef, Container) then\n      Exit;\n\n    if Container.ElementCount < 1 then\n      Exit;\n\n    MainRecord := Container.ContainingMainRecord;\n    if not Assigned(MainRecord) or MainRecord.IsDeleted then\n      Exit;\n\n    Element := Container.ElementByPath['..\\EFID'];\n    if not Assigned(Element) then\n      Exit;\n    if not Supports(Element.LinksTo, IwbMainRecord, MainRecord) then\n      Exit;\n    if MainRecord.Signature <> 'MGEF' then\n      Exit;\n    ActorValue := MainRecord.ElementNativeValues['DATA - Data\\Actor Value'];\n    if VarIsNull(ActorValue) or VarIsClear(ActorValue) then\n      Exit;\n    if VarCompareValue(ActorValue, Container.ElementNativeValues['Actor Value']) <> vrEqual then\n      Container.ElementNativeValues['Actor Value'] := ActorValue;\n  finally\n    wbEndInternalEdit;\n  end;\nend;\n\nprocedure wbRPLDAfterLoad(const aElement: IwbElement);\nvar\n  Container: IwbContainer;\n  a, b: Single;\n  NeedsFlip: Boolean;\nbegin\n  if wbBeginInternalEdit then try\n    if Supports(aElement, IwbContainer, Container) then begin\n      NeedsFlip := False;\n      if Container.ElementCount > 1 then begin\n        a := StrToFloat((Container.Elements[0] as IwbContainer).Elements[0].Value);\n        b := StrToFloat((Container.Elements[Pred(Container.ElementCount)] as IwbContainer).Elements[0].Value);\n        case CompareValue(a, b) of\n          EqualsValue: begin\n            a := StrToFloat((Container.Elements[0] as IwbContainer).Elements[1].Value);\n            b := StrToFloat((Container.Elements[Pred(Container.ElementCount)] as IwbContainer).Elements[1].Value);\n            NeedsFlip := CompareValue(a, b) = GreaterThanValue;\n          end;\n          GreaterThanValue:\n            NeedsFlip := True;\n        end;\n      end;\n      if NeedsFlip then\n        Container.ReverseElements;\n    end;\n  finally\n    wbEndInternalEdit;\n  end;\nend;\n\nfunction wbPxDTLocationDecider(aBasePtr: Pointer; aEndPtr: Pointer; const aElement: IwbElement): Integer;\nvar\n  Container: IwbContainer;\nbegin\n  Result := 0;\n  if not Assigned(aElement) then Exit;\n  Container := GetContainerFromUnion(aElement);\n  if not Assigned(Container) then Exit;\n  Result := Container.ElementByName['Type'].NativeValue;\nend;\n\nfunction wbPKDTFalloutBehaviorFlagsDecider(aBasePtr: Pointer; aEndPtr: Pointer; const aElement: IwbElement): Integer;\nvar\n  Container : IwbContainer;\n  SubRecord : IwbSubRecord;\nbegin\n  Result := 0;\n  if not Assigned(aElement) then Exit;\n  Container := GetContainerFromUnion(aElement);\n  if not Assigned(Container) then Exit;\n  if Supports(Container, IwbSubRecord, SubRecord) then\n    if SubRecord.SubRecordHeaderSize = 8 then\n      Result := 1;\nend;\n\nfunction wbPKDTSpecificFlagsDecider(aBasePtr: Pointer; aEndPtr: Pointer; const aElement: IwbElement): Integer;\nvar\n  Container : IwbContainer;\n  SubRecord : IwbSubRecord;\nbegin\n  Result := 0;\n  if not Assigned(aElement) then Exit;\n  Container := GetContainerFromUnion(aElement);\n  if not Assigned(Container) then Exit;\n  if Supports(Container, IwbSubRecord, SubRecord) then\n    if SubRecord.SubRecordHeaderSize = 8 then\n      Exit;\n  Result := Container.ElementByName['Type'].NativeValue + 1;\nend;\n\nprocedure wbIDLAsAfterSet(const aElement: IwbElement; const aOldValue, aNewValue: Variant);\nvar\n  Element         : IwbElement;\n  Container       : IwbContainer;\n  SelfAsContainer : IwbContainer;\nbegin\n  if wbBeginInternalEdit then try\n//    if not wbCounterAfterSet('IDLC - Animation Count', aElement) then\n      if Supports(aElement.Container, IwbContainer, Container) then begin\n        Element := Container.ElementByPath['IDLC\\Animation Count'];\n        if Assigned(Element) and Supports(aElement, IwbContainer, SelfAsContainer) and\n          (Element.GetNativeValue<>SelfAsContainer.GetElementCount) then\n          Element.SetNativeValue(SelfAsContainer.GetElementCount);\n      end;\n  finally\n    wbEndInternalEdit;\n  end;\nend;\n\nprocedure wbAnimationsAfterSet(const aElement: IwbElement; const aOldValue, aNewValue: Variant);\nvar\n  Element         : IwbElement;\n  Elems           : IwbElement;\n  Container       : IwbContainer;\nbegin\n  if wbBeginInternalEdit then try\n//    if not wbCounterContainerAfterSet('IDLC - Animation Count', 'IDLA - Animations', aElement) then\n      if Supports(aElement, IwbContainer, Container) then begin\n        Element := Container.ElementByPath['IDLC\\Animation Count'];\n        Elems   := Container.ElementByName['IDLA - Animations'];\n        if Assigned(Element) and not Assigned(Elems) then\n          if Element.GetNativeValue<>0 then\n            Element.SetNativeValue(0);\n      end;\n  finally\n    wbEndInternalEdit;\n  end;\nend;\n\nfunction wbOffsetDataColsCounter(aBasePtr: Pointer; aEndPtr: Pointer; const aElement: IwbElement): Cardinal;\nvar\n  Container : IwbDataContainer;\n  Element   : IwbElement;\n  fResult   : Extended;\nbegin\n  Result := 0;\n\n  if Supports(aElement.Container, IwbDataContainer, Container) and (Container.Name = 'OFST - Offset Data') and\n     Supports(Container.Container, IwbDataContainer, Container) then begin\n    Element := Container.ElementByPath['Object Bounds\\NAM0 - Min\\X'];\n    if Assigned(Element) then begin\n      fResult :=  Element.NativeValue;\n      if fResult >= MaxInt then\n        Result := 0\n      else\n        Result := Trunc(fResult);\n      Element := Container.ElementByPath['Object Bounds\\NAM9 - Max\\X'];\n      if Assigned(Element) then begin\n        fResult :=  Element.NativeValue;\n        if fResult >= MaxInt then\n          Result := 1\n        else\n          Result := Trunc(fResult) - Result + 1;\n      end;\n    end;\n  end;\nend;\n\nprocedure DefineFNVa;\nbegin\n  wbRecordFlags := wbInteger('Record Flags', itU32, wbFlags([\n    {0x00000001}'ESM',\n    {0x00000002}'',\n    {0x00000004}'',   // Plugin selected (Editor)\n    {0x00000008}'Form initialized (Runtime only)',   // Form cannot be saved (Runtime)/Plugin active (Editor)\n    {0x00000010}'',  // Plugin cannot be active or selected (Editor)\n    {0x00000020}'Deleted',\n    {0x00000040}'Border Region / Has Tree LOD / Constant / Hidden From Local Map / Plugin Endian',\n    {0x00000080}'Turn Off Fire',\n    {0x00000100}'Inaccessible',\n    {0x00000200}'Casts shadows / On Local Map / Motion Blur',\n    {0x00000400}'Quest item / Persistent reference',\n    {0x00000800}'Initially disabled',\n    {0x00001000}'Ignored',\n    {0x00002000}'No Voice Filter',\n    {0x00004000}'Cannot Save (Runtime only)',\n    {0x00008000}'Visible when distant',\n    {0x00010000}'Random Anim Start / High Priority LOD',\n    {0x00020000}'Dangerous / Off limits (Interior cell) / Radio Station (Talking Activator)',\n    {0x00040000}'Compressed',\n    {0x00080000}'Can''t wait / Platform Specific Texture / Dead',\n    {0x00100000}'Unknown 21',\n    {0x00200000}'Load Started (Runtime Only)', // set when beginning to load the form from save\n    {0x00400000}'Unknown 23',\n    {0x00800000}'Unknown 24',   // Runtime might use it for \"Not dead\" on non actors.\n    {0x01000000}'Destructible (Runtime only)',\n    {0x02000000}'Obstacle / No AI Acquire',\n    {0x03000000}'NavMesh Generation - Filter',\n    {0x08000000}'NavMesh Generation - Bounding Box',\n    {0x10000000}'Non-Pipboy / Reflected by Auto Water',\n    {0x20000000}'Child Can Use / Refracted by Auto Water',\n    {0x40000000}'NavMesh Generation - Ground',\n    {0x80000000}'Multibound'\n  ]));\n\n(*   wbInteger('Record Flags 2', itU32, wbFlags([\n    {0x00000001}'Unknown 1',\n    {0x00000002}'Unknown 2',\n    {0x00000004}'Unknown 3',\n    {0x00000008}'Unknown 4',\n    {0x00000010}'Unknown 5',\n    {0x00000020}'Unknown 6',\n    {0x00000040}'Unknown 7',\n    {0x00000080}'Unknown 8',\n    {0x00000100}'Unknown 9',\n    {0x00000200}'Unknown 10',\n    {0x00000400}'Unknown 11',\n    {0x00000800}'Unknown 12',\n    {0x00001000}'Unknown 13',\n    {0x00002000}'Unknown 14',\n    {0x00004000}'Unknown 15',\n    {0x00008000}'Unknown 16',\n    {0x00010000}'Unknown 17',\n    {0x00020000}'Unknown 18',\n    {0x00040000}'Unknown 19',\n    {0x00080000}'Unknown 20',\n    {0x00100000}'Unknown 21',\n    {0x00200000}'Unknown 22',\n    {0x00400000}'Unknown 23',\n    {0x00800000}'Unknown 24',\n    {0x01000000}'Unknown 25',\n    {0x02000000}'Unknown 26',\n    {0x03000000}'Unknown 27',\n    {0x08000000}'Unknown 28',\n    {0x10000000}'Unknown 29',\n    {0x20000000}'Unknown 30',\n    {0x40000000}'Unknown 31',\n    {0x80000000}'Unknown 32'\n  ]));                (**)\n\n  wbMainRecordHeader := wbStruct('Record Header', [\n    wbString('Signature', 4, cpCritical),\n    wbInteger('Data Size', itU32, nil, cpIgnore),\n    wbRecordFlags,\n    wbFormID('FormID', cpFormID),\n    wbInteger('Version Control Master FormID', itU32, nil, cpIgnore),\n    wbInteger('Form Version', itU16, nil, cpIgnore),\n    wbInteger('Version Control Info 2', itU16, nil, cpIgnore)  // limited to values from 0 to 0xF\n  ]);\n\n  wbSizeOfMainRecordStruct := 24;\n\n  wbIgnoreRecords.Add(XXXX);\n\n  wbXRGD := wbByteArray(XRGD, 'Ragdoll Data');\n  wbXRGB := wbByteArray(XRGB, 'Ragdoll Biped Data');\n\n  wbMusicEnum := wbEnum(['Default', 'Public', 'Dungeon']);\n  wbSoundLevelEnum := wbEnum([\n     'Loud',\n     'Normal',\n     'Silent'\n    ]);\n\n  wbWeaponAnimTypeEnum := wbEnum([\n    {00} 'Hand to Hand',\n    {01} 'Melee (1 Hand)',\n    {02} 'Melee (2 Hand)',\n    {03} 'Pistol - Balistic (1 Hand)',\n    {04} 'Pistol - Energy (1 Hand)',\n    {05} 'Rifle - Balistic (2 Hand)',\n    {06} 'Rifle - Automatic (2 Hand)',\n    {07} 'Rifle - Energy (2 Hand)',\n    {08} 'Handle (2 Hand)',\n    {09} 'Launcher (2 Hand)',\n    {10} 'Grenade Throw (1 Hand)',\n    {11} 'Land Mine (1 Hand)',\n    {12} 'Mine Drop (1 Hand)',\n    {13} 'Thrown (1 Hand)'\n  ]);\n\n  wbReloadAnimEnum := wbEnum([\n    'ReloadA',\n    'ReloadB',\n    'ReloadC',\n    'ReloadD',\n    'ReloadE',\n    'ReloadF',\n    'ReloadG',\n    'ReloadH',\n    'ReloadI',\n    'ReloadJ',\n    'ReloadK',\n    'ReloadL',\n    'ReloadM',\n    'ReloadN',\n    'ReloadO',\n    'ReloadP',\n    'ReloadQ',\n    'ReloadR',\n    'ReloadS',\n//    'ReloadT',\n//    'ReloadU',\n//    'ReloadV',\n    'ReloadW',\n    'ReloadX',\n    'ReloadY',\n    'ReloadZ'\n  ],[255, 'None']);   // 255 seen in DLC, though Geck converts to 0\n\n  wbEDID := wbString(EDID, 'Editor ID', 0, cpNormal); // not cpBenign according to Arthmoor\n  wbEDIDReq := wbString(EDID, 'Editor ID', 0, cpNormal, True); // not cpBenign according to Arthmoor\n  wbFULL := wbString(FULL, 'Name', 0, cpTranslate);\n  wbFULLActor := wbString(FULL, 'Name', 0, cpTranslate, False, wbActorTemplateUseBaseData);\n  wbFULLReq := wbString(FULL, 'Name', 0, cpNormal, True);\n  wbDESC := wbString(DESC, 'Description', 0, cpTranslate);\n  wbDESCReq := wbString(DESC, 'Description', 0, cpTranslate, True);\n  wbXSCL := wbFloat(XSCL, 'Scale');\n  wbOBND := wbStruct(OBND, 'Object Bounds', [\n    wbInteger('X1', itS16),\n    wbInteger('Y1', itS16),\n    wbInteger('Z1', itS16),\n    wbInteger('X2', itS16),\n    wbInteger('Y2', itS16),\n    wbInteger('Z2', itS16)\n  ]);\n  wbOBNDReq := wbStruct(OBND, 'Object Bounds', [\n    wbInteger('X1', itS16),\n    wbInteger('Y1', itS16),\n    wbInteger('Z1', itS16),\n    wbInteger('X2', itS16),\n    wbInteger('Y2', itS16),\n    wbInteger('Z2', itS16)\n  ], cpNormal, True);\n  wbREPL := wbFormIDCkNoReach(REPL, 'Repair List', [FLST]);\n  wbEITM := wbFormIDCk(EITM, 'Object Effect', [ENCH, SPEL]);\n  wbBIPL := wbFormIDCk(BIPL, 'Biped Model List', [FLST]);\n  wbCOED := wbStructExSK(COED, [2], [0, 1], 'Extra Data', [\n    {00} wbFormIDCkNoReach('Owner', [NPC_, FACT, NULL]),\n    {04} wbUnion('Global Variable / Required Rank', wbCOEDOwnerDecider, [\n           wbByteArray('Unused', 4, cpIgnore),\n           wbFormIDCk('Global Variable', [GLOB, NULL]),\n           wbInteger('Required Rank', itS32)\n         ]),\n    {08} wbFloat('Item Condition')\n  ]);\n\n  wbYNAM := wbFormIDCk(YNAM, 'Sound - Pick Up', [SOUN]);\n  wbZNAM := wbFormIDCk(ZNAM, 'Sound - Drop', [SOUN]);\n\n  wbPosRot :=\n    wbStruct('Position/Rotation', [\n      wbStruct('Position', [\n        wbFloat('X'),\n        wbFloat('Y'),\n        wbFloat('Z')\n      ]),\n      wbStruct('Rotation', [\n        wbFloat('X', cpNormal, True, wbRotationFactor, wbRotationScale, nil, RadiansNormalize),\n        wbFloat('Y', cpNormal, True, wbRotationFactor, wbRotationScale, nil, RadiansNormalize),\n        wbFloat('Z', cpNormal, True, wbRotationFactor, wbRotationScale, nil, RadiansNormalize)\n      ])\n    ]);\n\n  wbDATAPosRot :=\n    wbStruct(DATA, 'Position/Rotation', [\n      wbStruct('Position', [\n        wbFloat('X'),\n        wbFloat('Y'),\n        wbFloat('Z')\n      ]),\n      wbStruct('Rotation', [\n        wbFloat('X', cpNormal, True, wbRotationFactor, wbRotationScale, nil, RadiansNormalize),\n        wbFloat('Y', cpNormal, True, wbRotationFactor, wbRotationScale, nil, RadiansNormalize),\n        wbFloat('Z', cpNormal, True, wbRotationFactor, wbRotationScale, nil, RadiansNormalize)\n      ])\n    ], cpNormal, True);\n\n  wbMODS :=\n    wbArrayS(MODS, 'Alternate Textures',\n      wbStructSK([0, 2], 'Alternate Texture', [\n        wbLenString('3D Name'),\n        wbFormIDCk('New Texture', [TXST]),\n        wbInteger('3D Index', itS32)\n      ]),\n    -1);\n  wbMO2S :=\n    wbArrayS(MO2S, 'Alternate Textures',\n      wbStructSK([0, 2], 'Alternate Texture', [\n        wbLenString('3D Name'),\n        wbFormIDCk('New Texture', [TXST]),\n        wbInteger('3D Index', itS32)\n      ]),\n    -1);\n  wbMO3S :=\n    wbArrayS(MO3S, 'Alternate Textures',\n      wbStructSK([0, 2], 'Alternate Texture', [\n        wbLenString('3D Name'),\n        wbFormIDCk('New Texture', [TXST]),\n        wbInteger('3D Index', itS32)\n      ]),\n    -1);\n  wbMO4S :=\n    wbArrayS(MO4S, 'Alternate Textures',\n      wbStructSK([0, 2], 'Alternate Texture', [\n        wbLenString('3D Name'),\n        wbFormIDCk('New Texture', [TXST]),\n        wbInteger('3D Index', itS32)\n      ]),\n    -1);\n\n  wbMODD :=\n    wbInteger(MODD, 'FaceGen Model Flags', itU8, wbFlags([\n      'Head',\n      'Torso',\n      'Right Hand',\n      'Left Hand'\n    ]));\n  wbMOSD :=\n    wbInteger(MOSD, 'FaceGen Model Flags', itU8, wbFlags([\n      'Head',\n      'Torso',\n      'Right Hand',\n      'Left Hand'\n    ]));\n\n  wbMODL :=\n    wbRStructSK([0], 'Model', [\n      wbString(MODL, 'Model Filename', 0, cpNormal, True),\n      wbByteArray(MODB, 'Unknown', 4, cpIgnore),\n      wbByteArray(MODT, 'Texture Files Hashes', 0, cpIgnore),\n//      wbArray(MODT, 'Texture Files Hashes',\n//        wbByteArray('Unknown', 24, cpBenign),\n//        wbArray('Hashes', wbInteger('Hash', itU64, wbMODTCallback), 3),\n//      0, nil, nil, cpBenign),\n      wbMODS,\n      wbMODD\n    ], [], cpNormal, False, nil, True);\n\n  wbMODLActor :=\n    wbRStructSK([0], 'Model', [\n      wbString(MODL, 'Model Filename', 0, cpNormal, True),\n      wbByteArray(MODB, 'Unknown', 4, cpIgnore),\n      wbByteArray(MODT, 'Texture Files Hashes', 0, cpIgnore),\n//      wbArray(MODT, 'Texture Files Hashes',\n//        wbByteArray('Unknown', 24, cpBenign),\n//        wbArray('Hashes', wbInteger('Hash', itU64, wbMODTCallback), 3),\n//      0, nil, nil, cpBenign),\n      wbMODS,\n      wbMODD\n    ], [], cpNormal, False, wbActorTemplateUseModelAnimation, True);\n\n  wbMODLReq :=\n    wbRStructSK([0], 'Model', [\n      wbString(MODL, 'Model Filename', 0, cpNormal, True),\n      wbByteArray(MODB, 'Unknown', 4, cpIgnore),\n      wbByteArray(MODT, 'Texture Files Hashes', 0, cpIgnore),\n//      wbArray(MODT, 'Texture Files',\n//        wbByteArray('Unknown', 24, cpBenign),\n//        wbArray('Hashes', wbInteger('Hash', itU64, wbMODTCallback), 3),\n//      0, nil, nil, cpBenign),\n      wbMODS,\n      wbMODD\n    ], [], cpNormal, True, nil, True);\n\n\n  wbDEST := wbRStruct('Destructable', [\n    wbStruct(DEST, 'Header', [\n      wbInteger('Health', itS32),\n      wbInteger('Count', itU8),\n      wbInteger('Flags', itU8, wbFlags([\n        'VATS Targetable'\n      ], True)),\n      wbByteArray('Unused', 2)\n    ]),\n    wbRArray('Stages',\n      wbRStruct('Stage', [\n        wbStruct(DSTD, 'Destruction Stage Data', [\n          wbInteger('Health %', itU8),\n          wbInteger('Index', itU8),\n          wbInteger('Damage Stage', itU8),\n          wbInteger('Flags', itU8, wbFlags([\n            'Cap Damage',\n            'Disable',\n            'Destroy'\n          ])),\n          wbInteger('Self Damage per Second', itS32),\n          wbFormIDCk('Explosion', [EXPL, NULL]),\n          wbFormIDCk('Debris', [DEBR, NULL]),\n          wbInteger('Debris Count', itS32)\n        ], cpNormal, True),\n        wbRStructSK([0], 'Model', [\n          wbString(DMDL, 'Model Filename'),\n          wbByteArray(DMDT, 'Texture Files Hashes', 0, cpIgnore)\n//          wbArray(DMDT, 'Unknown',\n//            wbByteArray('Unknown', 24, cpBenign),\n//          0, nil, nil, cpBenign)\n        ], []),\n        wbEmpty(DSTF, 'End Marker', cpNormal, True)\n      ], [])\n    )\n  ], []);\n\n  wbDESTActor := wbRStruct('Destructable', [\n    wbStruct(DEST, 'Header', [\n      wbInteger('Health', itS32),\n      wbInteger('Count', itU8),\n      wbInteger('Flags', itU8, wbFlags([\n        'VATS Targetable'\n      ])),\n      wbByteArray('Unused', 2)\n    ]),\n    wbRArray('Stages',\n      wbRStruct('Stage', [\n        wbStruct(DSTD, 'Destruction Stage Data', [\n          wbInteger('Health %', itU8),\n          wbInteger('Index', itU8),\n          wbInteger('Damage Stage', itU8),\n          wbInteger('Flags', itU8, wbFlags([\n            'Cap Damage',\n            'Disable',\n            'Destroy'\n          ])),\n          wbInteger('Self Damage per Second', itS32),\n          wbFormIDCk('Explosion', [EXPL, NULL]),\n          wbFormIDCk('Debris', [DEBR, NULL]),\n          wbInteger('Debris Count', itS32)\n        ], cpNormal, True),\n        wbRStructSK([0], 'Model', [\n          wbString(DMDL, 'Model Filename'),\n          wbByteArray(DMDT, 'Texture Files Hashes', 0, cpIgnore)\n//          wbArray(DMDT, 'Unknown',\n//            wbByteArray('Unknown', 24, cpBenign),\n//          0, nil, nil, cpBenign)\n        ], []),\n        wbEmpty(DSTF, 'End Marker', cpNormal, True)\n      ], [])\n    )\n  ], [], cpNormal, False, wbActorTemplateUseModelAnimation);\n\n  wbSCRI := wbFormIDCk(SCRI, 'Script', [SCPT]);\n  wbSCRIActor := wbFormIDCk(SCRI, 'Script', [SCPT], False, cpNormal, False, wbActorTemplateUseScript);\n  wbENAM := wbFormIDCk(ENAM, 'Object Effect', [ENCH]);\n\n  wbXLOD := wbArray(XLOD, 'Distant LOD Data', wbFloat('Unknown'), 3);\n\n  wbXESP := wbStruct(XESP, 'Enable Parent', [\n    wbFormIDCk('Reference', [PLYR, REFR, ACRE, ACHR, PGRE, PMIS, PBEA]),\n    wbInteger('Flags', itU8, wbFlags([\n      'Set Enable State to Opposite of Parent',\n      'Pop In'\n    ])),\n    wbByteArray('Unused', 3)\n  ]);\n\n  wbSCHRReq := wbStruct(SCHR, 'Basic Script Data', [\n    wbByteArray('Unused', 4),\n    wbInteger('RefCount', itU32),\n    wbInteger('CompiledSize', itU32),\n    wbInteger('VariableCount', itU32),\n    wbInteger('Type', itU16, wbEnum([\n      'Object',\n      'Quest'\n    ], [\n      $100, 'Effect'\n    ])),\n    wbInteger('Flags', itU16, wbFlags([\n      'Enabled'\n    ]), cpNormal, False, nil, nil, 1)\n  ], cpNormal, True);\n\n  wbSCROs :=\n    wbRArray('References',\n      wbRUnion('', [\n        wbFormID(SCRO, 'Global Reference'),\n//        wbFormIDCk(SCRO, 'Global Reference',\n//          [ACTI, DOOR, STAT, FURN, CREA, SPEL, NPC_, CONT, ARMO, AMMO, MISC, WEAP, IMAD,\n//           BOOK, KEYM, ALCH, LIGH, QUST, PLYR, PACK, LVLI, ECZN, EXPL, FLST, IDLM, PMIS,\n//           FACT, ACHR, REFR, ACRE, GLOB, DIAL, CELL, SOUN, MGEF, WTHR, CLAS, EFSH, RACE,\n//           LVLC, CSTY, WRLD, SCPT, IMGS, MESG, MSTT, MUSC, NOTE, PERK, PGRE, PROJ, LVLN,\n//           WATR, ENCH, TREE, REPU, REGN, CSNO, CHAL, IMOD, RCCT, CMNY, CDCK, CHIP, CCRD,\n//           TERM, HAIR, EYES, ADDN, RCPE, NULL]),\n        wbInteger(SCRV, 'Local Variable', itU32)\n      ], [])\n    );\n\n  wbSLSD := wbStructSK(SLSD, [0], 'Local Variable Data', [\n    wbInteger('Index', itU32),\n    wbByteArray('Unused', 12),\n    wbInteger('Flags', itU8, wbFlags(['IsLongOrShort']), cpCritical),\n    wbByteArray('Unused', 7)\n  ]);\n\n  wbEmbeddedScript := wbRStruct('Embedded Script', [\n    wbSCHRReq,\n    wbByteArray(SCDA, 'Compiled Embedded Script', 0, cpNormal{, True}),\n    wbStringScript(SCTX, 'Embedded Script Source', 0, cpNormal{, True}),\n    wbRArrayS('Local Variables', wbRStructSK([0], 'Local Variable', [\n      wbSLSD,\n      wbString(SCVR, 'Name', 0, cpCritical, True)\n    ], [])),\n    wbSCROs\n  ], [], cpNormal, False, nil, False, wbEmbeddedScriptAfterLoad);\n\n  wbEmbeddedScriptPerk := wbRStruct('Embedded Script', [\n    wbSCHRReq,\n    wbByteArray(SCDA, 'Compiled Embedded Script', 0, cpNormal, True),\n    wbStringScript(SCTX, 'Embedded Script Source', 0, cpNormal, True),\n    wbRArrayS('Local Variables', wbRStructSK([0], 'Local Variable', [\n      wbSLSD,\n      wbString(SCVR, 'Name', 0, cpCritical, True)\n    ], [])),\n    wbSCROs\n  ], [], cpNormal, False, wbEPF2DontShow, False, wbEmbeddedScriptAfterLoad);\n\n  wbEmbeddedScriptReq := wbRStruct('Embedded Script', [\n    wbSCHRReq,\n    wbByteArray(SCDA, 'Compiled Embedded Script', 0, cpNormal{, True}),\n    wbStringScript(SCTX, 'Embedded Script Source', 0, cpNormal{, True}),\n    wbRArrayS('Local Variables', wbRStructSK([0], 'Local Variable', [\n      wbSLSD,\n      wbString(SCVR, 'Name', 0, cpCritical, True)\n    ], [])),\n    wbSCROs\n  ], [], cpNormal, True, nil, False, wbEmbeddedScriptAfterLoad);\n\n\n  wbXLCM := wbInteger(XLCM, 'Level Modifier', itS32);\n\n  wbRecord(ACHR, 'Placed NPC', [\n    wbEDID,\n    wbFormIDCk(NAME, 'Base', [NPC_], False, cpNormal, True),\n    wbFormIDCk(XEZN, 'Encounter Zone', [ECZN]),\n\n    {--- Ragdoll ---}\n    wbXRGD,\n    wbXRGB,\n\n    {--- Patrol Data ---}\n    wbRStruct('Patrol Data', [\n      wbFloat(XPRD, 'Idle Time', cpNormal, True),\n      wbEmpty(XPPA, 'Patrol Script Marker', cpNormal, True),\n      wbFormIDCk(INAM, 'Idle', [IDLE, NULL], False, cpNormal, True),\n      wbEmbeddedScriptReq,\n      wbFormIDCk(TNAM, 'Topic', [DIAL, NULL], False, cpNormal, True)\n    ], []),\n\n    {--- Leveled Actor ----}\n    wbXLCM,\n\n    {--- Merchant Container ----}\n    wbFormIDCk(XMRC, 'Merchant Container', [REFR], True),\n\n    {--- Extra ---}\n    wbInteger(XCNT, 'Count', itS32),\n    wbFloat(XRDS, 'Radius'),\n    wbFloat(XHLP, 'Health'),\n\n    {--- Decals ---}\n    wbRArrayS('Linked Decals',\n      wbStructSK(XDCR, [0], 'Decal', [\n        wbFormIDCk('Reference', [REFR]),\n        wbUnknown\n      ])\n    ),\n\n    {--- Linked Ref ---}\n    wbFormIDCk(XLKR, 'Linked Reference', [REFR, ACRE, ACHR, PGRE, PMIS, PBEA, PLYR]),\n    wbStruct(XCLP, 'Linked Reference Color', [\n      wbStruct('Link Start Color', [\n        wbInteger('Red', itU8),\n        wbInteger('Green', itU8),\n        wbInteger('Blue', itU8),\n        wbByteArray('Unused', 1)\n      ]),\n      wbStruct('Link End Color', [\n        wbInteger('Red', itU8),\n        wbInteger('Green', itU8),\n        wbInteger('Blue', itU8),\n        wbByteArray('Unused', 1)\n      ])\n    ]),\n\n    {--- Activate Parents ---}\n    wbRStruct('Activate Parents', [\n      wbInteger(XAPD, 'Flags', itU8, wbFlags([\n        'Parent Activate Only'\n      ], True)),\n      wbRArrayS('Activate Parent Refs',\n        wbStructSK(XAPR, [0], 'Activate Parent Ref', [\n          wbFormIDCk('Reference', [REFR, ACRE, ACHR, PGRE, PMIS, PBEA, PLYR]),\n          wbFloat('Delay')\n        ])\n      )\n    ], []),\n\n    wbString(XATO, 'Activation Prompt'),\n\n    {--- Enable Parent ---}\n    wbXESP,\n\n    {--- Emittance ---}\n    wbFormIDCk(XEMI, 'Emittance', [LIGH, REGN]),\n\n    {--- MultiBound ---}\n    wbFormIDCk(XMBR, 'MultiBound Reference', [REFR]),\n\n    {--- Flags ---}\n    wbEmpty(XIBS, 'Ignored By Sandbox'),\n\n    {--- 3D Data ---}\n    wbXSCL,\n    wbDATAPosRot\n  ], True, wbPlacedAddInfo);\n\n  wbXOWN := wbFormIDCkNoReach(XOWN, 'Owner', [FACT, ACHR, CREA, NPC_]); // Ghouls can own too aparently !\n  wbXGLB := wbFormIDCk(XGLB, 'Global variable', [GLOB]);\n\n  wbRecord(ACRE, 'Placed Creature', [\n    wbEDID,\n    wbFormIDCk(NAME, 'Base', [CREA], False, cpNormal, True),\n    wbFormIDCk(XEZN, 'Encounter Zone', [ECZN]),\n\n    wbXRGD,\n    wbXRGB,\n\n    {--- Patrol Data ---}\n    wbRStruct('Patrol Data', [\n      wbFloat(XPRD, 'Idle Time', cpNormal, True),\n      wbEmpty(XPPA, 'Patrol Script Marker', cpNormal, True),\n      wbFormIDCk(INAM, 'Idle', [IDLE, NULL], False, cpNormal, True),\n      wbEmbeddedScriptReq,\n      wbFormIDCk(TNAM, 'Topic', [DIAL, NULL], False, cpNormal, True)\n    ], []),\n\n    {--- Leveled Actor ----}\n    wbXLCM,\n\n    {--- Ownership ---}\n    wbRStruct('Ownership', [\n      wbXOWN,\n      wbInteger(XRNK, 'Faction rank', itS32)\n    ], [XCMT, XCMO]),\n\n    {--- Merchant Container ----}\n    wbFormIDCk(XMRC, 'Merchant Container', [REFR], True),\n\n    {--- Extra ---}\n    wbInteger(XCNT, 'Count', itS32),\n    wbFloat(XRDS, 'Radius'),\n    wbFloat(XHLP, 'Health'),\n\n    {--- Decals ---}\n    wbRArrayS('Linked Decals',\n      wbStructSK(XDCR, [0], 'Decal', [\n        wbFormIDCk('Reference', [REFR, ACRE, ACHR, PGRE, PMIS, PBEA]),\n        wbUnknown\n      ])\n    ),\n\n    {--- Linked Ref ---}\n    wbFormIDCk(XLKR, 'Linked Reference', [REFR, ACRE, ACHR, PGRE, PMIS, PBEA, PLYR]),\n    wbStruct(XCLP, 'Linked Reference Color', [\n      wbStruct('Link Start Color', [\n        wbInteger('Red', itU8),\n        wbInteger('Green', itU8),\n        wbInteger('Blue', itU8),\n        wbByteArray('Unused', 1)\n      ]),\n      wbStruct('Link End Color', [\n        wbInteger('Red', itU8),\n        wbInteger('Green', itU8),\n        wbInteger('Blue', itU8),\n        wbByteArray('Unused', 1)\n      ])\n    ]),\n\n    {--- Activate Parents ---}\n    wbRStruct('Activate Parents', [\n      wbInteger(XAPD, 'Flags', itU8, wbFlags([\n        'Parent Activate Only'\n      ], True)),\n      wbRArrayS('Activate Parent Refs',\n        wbStructSK(XAPR, [0], 'Activate Parent Ref', [\n          wbFormIDCk('Reference', [REFR, ACRE, ACHR, PGRE, PMIS, PBEA, PLYR]),\n          wbFloat('Delay')\n        ])\n      )\n    ], []),\n\n    wbString(XATO, 'Activation Prompt'),\n\n    {--- Enable Parent ---}\n    wbXESP,\n\n    {--- Emittance ---}\n    wbFormIDCk(XEMI, 'Emittance', [LIGH, REGN]),\n\n    {--- MultiBound ---}\n    wbFormIDCk(XMBR, 'MultiBound Reference', [REFR]),\n\n    {--- Flags ---}\n    wbEmpty(XIBS, 'Ignored By Sandbox'),\n\n    {--- 3D Data ---}\n    wbXSCL,\n    wbDATAPosRot\n  ], True, wbPlacedAddInfo);\n\n  wbRecord(ACTI, 'Activator', [\n    wbEDIDReq,\n    wbOBNDReq,\n    wbFULL,\n    wbMODL,\n    wbSCRI,\n    wbDEST,\n    wbFormIDCk(SNAM, 'Sound - Looping', [SOUN]),\n    wbFormIDCk(VNAM, 'Sound - Activation', [SOUN]),\n    wbFormIDCk(INAM, 'Radio Template', [SOUN]),\n    wbFormIDCk(RNAM, 'Radio Station', [TACT]),\n    wbFormIDCk(WNAM, 'Water Type', [WATR]),\n    wbString(XATO, 'Activation Prompt')\n  ]);\n\n  wbICON := wbRStruct('Icon', [\n    wbString(ICON, 'Large Icon filename', 0, cpNormal, True),\n    wbString(MICO, 'Small Icon filename')\n  ], [], cpNormal, False, nil, True);\n\n  wbICONReq := wbRStruct('Icon', [\n    wbString(ICON, 'Large Icon filename', 0, cpNormal, True),\n    wbString(MICO, 'Small Icon filename')\n  ], [], cpNormal, True, nil, True);\n\n  wbVatsValueFunctionEnum :=\n    wbEnum([\n      'Weapon Is',\n      'Weapon In List',\n      'Target Is',\n      'Target In List',\n      'Target Distance',\n      'Target Part',\n      'VATS Action',\n      'Is Success',\n      'Is Critical',\n      'Critical Effect Is',\n      'Critical Effect In List',\n      'Is Fatal',\n      'Explode Part',\n      'Dismember Part',\n      'Cripple Part',\n      'Weapon Type Is',\n      'Is Stranger',\n      'Is Paralyzing Palm'\n    ]);\n\n  wbActorValueEnum :=\n    wbEnum([\n        {00} 'Aggresion',\n        {01} 'Confidence',\n        {02} 'Energy',\n        {03} 'Responsibility',\n        {04} 'Mood',\n        {05} 'Strength',\n        {06} 'Perception',\n        {07} 'Endurance',\n        {08} 'Charisma',\n        {09} 'Intelligence',\n        {10} 'Agility',\n        {11} 'Luck',\n        {12} 'Action Points',\n        {13} 'Carry Weight',\n        {14} 'Critical Chance',\n        {15} 'Heal Rate',\n        {16} 'Health',\n        {17} 'Melee Damage',\n        {18} 'Damage Resistance',\n        {19} 'Poison Resistance',\n        {20} 'Rad Resistance',\n        {21} 'Speed Multiplier',\n        {22} 'Fatigue',\n        {23} 'Karma',\n        {24} 'XP',\n        {25} 'Perception Condition',\n        {26} 'Endurance Condition',\n        {27} 'Left Attack Condition',\n        {28} 'Right Attack Condition',\n        {29} 'Left Mobility Condition',\n        {30} 'Right Mobility Condition',\n        {31} 'Brain Condition',\n        {32} 'Barter',\n        {33} 'Big Guns (obsolete)',\n        {34} 'Energy Weapons',\n        {35} 'Explosives',\n        {36} 'Lockpick',\n        {37} 'Medicine',\n        {38} 'Melee Weapons',\n        {39} 'Repair',\n        {40} 'Science',\n        {41} 'Guns',\n        {42} 'Sneak',\n        {43} 'Speech',\n        {44} 'Survival',\n        {45} 'Unarmed',\n        {46} 'Inventory Weight',\n        {47} 'Paralysis',\n        {48} 'Invisibility',\n        {49} 'Chameleon',\n        {50} 'Night Eye',\n        {51} 'Turbo',\n        {52} 'Fire Resistance',\n        {53} 'Water Breathing',\n        {54} 'Rad Level',\n        {55} 'Bloody Mess',\n        {56} 'Unarmed Damage',\n        {57} 'Assistance',\n        {58} 'Electric Resistance',\n        {59} 'Frost Resistance',\n        {60} 'Energy Resistance',\n        {61} 'EMP Resistance',\n        {62} 'Variable01',\n        {63} 'Variable02',\n        {64} 'Variable03',\n        {65} 'Variable04',\n        {66} 'Variable05',\n        {67} 'Variable06',\n        {68} 'Variable07',\n        {79} 'Variable08',\n        {70} 'Variable09',\n        {71} 'Variable10',\n        {72} 'Ignore Crippled Limbs',\n        {73} 'Dehydration',\n        {74} 'Hunger',\n        {75} 'Sleep Deprivation',\n        {76} 'Damage Threshold'\n      ], [\n        -1, 'None'\n      ]);\n\n  wbModEffectEnum :=\n    wbEnum([\n      {00} 'None',\n      {01} 'Increase Weapon Damage',\n      {02} 'Increase Clip Capacity',\n      {03} 'Decrease Spread',\n      {04} 'Decrease Weight',\n      {05} 'Regenerate Ammo (shots)',\n      {06} 'Regenerate Ammo (seconds)',\n      {07} 'Decrease Equip Time',\n      {08} 'Increase Rate of Fire',\n      {09} 'Increase Projectile Speed',\n      {10} 'Increase Max. Condition',\n      {11} 'Silence',\n      {12} 'Split Beam',\n      {13} 'VATS Bonus',\n      {14} 'Increase Zoom',\n      {15} 'Decrease Equip Time',\n      {16} 'Suppressor'\n    ]);\n\n  wbSkillEnum :=\n    wbEnum([\n      'Barter',\n      'Big Guns (obsolete)',\n      'Energy Weapons',\n      'Explosives',\n      'Lockpick',\n      'Medicine',\n      'Melee Weapons',\n      'Repair',\n      'Science',\n      'Guns',\n      'Sneak',\n      'Speech',\n      'Survival',\n      'Unarmed'\n    ], [\n      -1, 'None'\n    ]);\n\n  wbCrimeTypeEnum :=\n    wbEnum([\n      'Steal',\n      'Pickpocket',\n      'Trespass',\n      'Attack',\n      'Murder'\n    ], [\n      -1, 'None'\n    ]);\n\n  wbActorValue := wbInteger('Actor Value', itS32, wbActorValueEnum);\n\n  wbEquipTypeEnum :=\n    wbEnum([\n        {00} 'Big Guns',\n        {01} 'Energy Weapons',\n        {02} 'Small Guns',\n        {03} 'Melee Weapons',\n        {04} 'Unarmed Weapon',\n        {05} 'Thrown Weapons',\n        {06} 'Mine',\n        {07} 'Body Wear',\n        {08} 'Head Wear',\n        {09} 'Hand Wear',\n        {10} 'Chems',\n        {11} 'Stimpack',\n        {12} 'Food',\n        {13} 'Alcohol'\n      ], [\n        -1, 'None'\n      ]);\n\n  wbETYP := wbInteger(ETYP, 'Equiptment Type', itS32, wbEquipTypeEnum);\n  wbETYPReq := wbInteger(ETYP, 'Equiptment Type', itS32, wbEquipTypeEnum, cpNormal, True);\n\n  wbFormTypeEnum :=\n    wbEnum([], [\n      $04, 'Texture Set',\n      $05, 'Menu Icon',\n      $06, 'Global',\n      $07, 'Class',\n      $08, 'Faction',\n      $09, 'Head Part',\n      $0A, 'Hair',\n      $0B, 'Eyes',\n      $0C, 'Race',\n      $0D, 'Sound',\n      $0E, 'Acoustic Space',\n      $0F, 'Skill',\n      $10, 'Base Effect',\n      $11, 'Script',\n      $12, 'Landscape Texture',\n      $13, 'Object Effect',\n      $14, 'Actor Effect',\n      $15, 'Activator',\n      $16, 'Talking Activator',\n      $17, 'Terminal',\n      $18, 'Armor',\n      $19, 'Book',\n      $1A, 'Clothing',\n      $1B, 'Container',\n      $1C, 'Door',\n      $1D, 'Ingredient',\n      $1E, 'Light',\n      $1F, 'Misc',\n      $20, 'Static',\n      $21, 'Static Collection',\n      $22, 'Movable Static',\n      $23, 'Placeable Water',\n      $24, 'Grass',\n      $25, 'Tree',\n      $26, 'Flora',\n      $27, 'Furniture',\n      $28, 'Weapon',\n      $29, 'Ammo',\n      $2A, 'NPC',\n      $2B, 'Creature',\n      $2C, 'Leveled Creature',\n      $2D, 'Leveled NPC',\n      $2E, 'Key',\n      $2F, 'Ingestible',\n      $30, 'Idle Marker',\n      $31, 'Note',\n      $32, 'Constructible Object',\n      $33, 'Projectile',\n      $34, 'Leveled Item',\n      $35, 'Weather',\n      $36, 'Climate',\n      $37, 'Region',\n      $39, 'Cell',\n      $3A, 'Placed Object',\n      $3B, 'Placed Character',\n      $3C, 'Placed Creature',\n      $3E, 'Placed Grenade',\n      $41, 'Worldspace',\n      $42, 'Landscape',\n      $43, 'Navigation Mesh',\n      $45, 'Dialog Topic',\n      $46, 'Dialog Response',\n      $47, 'Quest',\n      $48, 'Idle Animation',\n      $49, 'Package',\n      $4A, 'Combat Style',\n      $4B, 'Load Screen',\n      $4C, 'Leveled Spell',\n      $4D, 'Animated Object',\n      $4E, 'Water',\n      $4F, 'Effect Shader',\n      $51, 'Explosion',\n      $52, 'Debris',\n      $53, 'Image Space',\n      $54, 'Image Space Modifier',\n      $55, 'FormID List',\n      $56, 'Perk',\n      $57, 'Body Part Data',\n      $58, 'Addon Node',\n      $59, 'Actor Value Info',\n      $5A, 'Radiation Stage',\n      $5B, 'Camera Shot',\n      $5C, 'Camera Path',\n      $5D, 'Voice Type',\n      $5E, 'Impact Data',\n      $5F, 'Impact DataSet',\n      $60, 'Armor Addon',\n      $61, 'Encounter Zone',\n      $62, 'Message',\n      $63, 'Ragdoll',\n      $64, 'Default Object Manager',\n      $65, 'Lighting Template',\n      $66, 'Music Type',\n      $67, 'Item Mod',\n      $68, 'Reputation',\n      $69, '?PCBE', //no such records in FalloutNV.esm\n      $6A, 'Recipe',\n      $6B, 'Recipe Category',\n      $6C, 'Casino Chip',\n      $6D, 'Casino',\n      $6E, 'Load Screen Type',\n      $6F, 'Media Set',\n      $70, 'Media Location Controller',\n      $71, 'Challenge',\n      $72, 'Ammo Effect',\n      $73, 'Caravan Card',\n      $74, 'Caravan Money',\n      $75, 'Caravan Deck',\n      $76, 'Dehydration Stages',\n      $77, 'Hunger Stages',\n      $78, 'Sleep Deprivation Stages'\n  ]);\n\n  wbMenuModeEnum :=\n    wbEnum([],[\n      1, 'Type: Character Interface',\n      2, 'Type: Other',\n      3, 'Type: Console',\n      1001, 'Specific: Message',\n      1002, 'Specific: Inventory',\n      1003, 'Specific: Stats',\n      1004, 'Specific: HUDMainMenu',\n      1007, 'Specific: Loading',\n      1008, 'Specific: Container',\n      1009, 'Specific: Dialog',\n      1012, 'Specific: Sleep/Wait',\n      1013, 'Specific: Pause',\n      1014, 'Specific: LockPick',\n      1016, 'Specific: Quantity',\n      1027, 'Specific: Level Up',\n      1035, 'Specific: Pipboy Repair',\n      1036, 'Specific: Race / Sex',\n      1047, 'Specific: Credits',\n      1048, 'Specific: CharGen',\n      1051, 'Specific: TextEdit',\n      1053, 'Specific: Barter',\n      1054, 'Specific: Surgery',\n      1055, 'Specific: Hacking',\n      1056, 'Specific: VATS',\n      1057, 'Specific: Computers',\n      1058, 'Specific: Vendor Repair',\n      1059, 'Specific: Tutorial',\n      1060, 'Specific: You''re SPECIAL book'\n    ]);\nend;\n\nprocedure DefineFNVb;\nbegin\n  wbMiscStatEnum :=\n    wbEnum([\n      'Quests Completed',\n      'Locations Discovered',\n      'People Killed',\n      'Creatures Killed',\n      'Locks Picked',\n      'Computers Hacked',\n      'Stimpaks Taken',\n      'Rad-X Taken',\n      'RadAway Taken',\n      'Chems Taken',\n      'Times Addicted',\n      'Mines Disarmed',\n      'Speech Successes',\n      'Pockets Picked',\n      'Pants Exploded',\n      'Books Read',\n      'Bobbleheads Found',\n      'Weapons Created',\n      'People Mezzed',\n      'Captives Rescued',\n      'Sandman Kills',\n      'Paralyzing Punches',\n      'Robots Disabled',\n      'Contracts Completed',\n      'Corpses Eaten',\n      'Mysterious Stranger Visits',\n      'Doctor Bags Used',\n      'Challenges Completed',\n      'Miss Fortunate Occurrences',\n      'Disintegrations',\n      'Have Limbs Crippled',\n      'Speech Failures',\n      'Items Crafted',\n      'Weapon Modifications',\n      'Items Repaired',\n      'Total Things Killed',\n      'Dismembered Limbs',\n      'Caravan Games Won',\n      'Caravan Games Lost',\n      'Barter Amount Traded',\n      'Roulette Games Played',\n      'Blackjack Games Played',\n      'Slots Games Played'\n    ]);\n\n  wbAlignmentEnum :=\n    wbEnum([\n      'Good',\n      'Neutral',\n      'Evil',\n      'Very Good',\n      'Very Evil'\n    ]);\n\n  wbAxisEnum :=\n    wbEnum([], [\n      88, 'X',\n      89, 'Y',\n      90, 'Z'\n    ]);\n\n  wbCriticalStageEnum :=\n    wbEnum([\n      'None',\n      'Goo Start',\n      'Goo End',\n      'Disintegrate Start',\n      'Disintegrate End'\n    ]);\n\n  wbSexEnum :=\n    wbEnum(['Male','Female']);\n\n  wbCreatureTypeEnum :=\n    wbEnum([\n      'Animal',\n      'Mutated Animal',\n      'Mutated Insect',\n      'Abomination',\n      'Super Mutant',\n      'Feral Ghoul',\n      'Robot',\n      'Giant'\n    ]);\n\n  wbPlayerActionEnum :=\n    wbEnum([\n      '',\n      'Swinging Melee Weapon',\n      'Throwing Grenade',\n      'Fire Weapon',\n      'Lay Mine',\n      'Z Key Object',\n      'Jumping',\n      'Knocking over Objects',\n      'Stand on Table/Chair',\n      'Iron Sites',\n      'Destroying Object'\n    ]);\n\n  wbBodyLocationEnum :=\n    wbEnum([\n      'Torso',\n      'Head 1',\n      'Head 2',\n      'Left Arm 1',\n      'Left Arm 2',\n      'Right Arm 1',\n      'Right Arm 2',\n      'Left Leg 1',\n      'Left Leg 2',\n      'Left Leg 3',\n      'Right Leg 1',\n      'Right Leg 2',\n      'Right Leg 3',\n      'Brain'\n    ], [\n      -1, 'None'\n    ]);\n\n\n  wbEFID := wbFormIDCk(EFID, 'Base Effect', [MGEF]);\n\n  wbEFIT :=\n    wbStructSK(EFIT, [3, 4], '', [\n      wbInteger('Magnitude', itU32),\n      wbInteger('Area', itU32),\n      wbInteger('Duration', itU32),\n      wbInteger('Type', itU32, wbEnum(['Self', 'Touch', 'Target'])),\n      wbActorValue\n    ], cpNormal, True, nil, -1, wbEFITAfterLoad);\n\n  wbCTDA :=\n    wbStruct(CTDA, 'Condition', [\n      wbInteger('Type', itU8, wbCtdaTypeToStr, wbCtdaTypeToInt, cpNormal, False, nil, wbCtdaTypeAfterSet),\n      wbByteArray('Unused', 3),\n      wbUnion('Comparison Value', wbCTDACompValueDecider, [\n        wbFloat('Comparison Value - Float'),\n        wbFormIDCk('Comparison Value - Global', [GLOB])\n      ]),\n      wbInteger('Function', itU32, wbCTDAFunctionToStr, wbCTDAFunctionToInt),   // Limited to itu16\n      wbUnion('Parameter #1', wbCTDAParam1Decider, [\n        {00} wbByteArray('Unknown', 4),\n        {01} wbByteArray('None', 4, cpIgnore),\n        {02} wbInteger('Integer', itS32),\n        {03} wbInteger('Variable Name (INVALID)', itS32),\n        {04} wbInteger('Sex', itU32, wbSexEnum),\n        {05} wbInteger('Actor Value', itS32, wbActorValueEnum),\n        {06} wbInteger('Crime Type', itU32, wbCrimeTypeEnum),\n        {07} wbInteger('Axis', itU32, wbAxisEnum),\n        {08} wbInteger('Quest Stage (INVALID)', itS32),\n        {09} wbInteger('Misc Stat', itU32, wbMiscStatEnum),\n        {10} wbInteger('Alignment', itU32, wbAlignmentEnum),\n        {11} wbInteger('Equip Type', itU32, wbEquipTypeEnum),\n        {12} wbInteger('Form Type', itU32, wbFormTypeEnum),\n        {13} wbInteger('Critical Stage', itU32, wbCriticalStageEnum),\n        {14} wbFormIDCkNoReach('Object Reference', [PLYR, REFR, ACHR, ACRE, PGRE, PMIS, PBEA, TRGT], True),\n        {16} wbFormIDCkNoReach('Inventory Object', [ARMO, BOOK, MISC, WEAP, AMMO, KEYM, ALCH, NOTE, FLST, CHIP, CMNY, IMOD]),\n        {17} wbFormIDCkNoReach('Actor', [PLYR, ACHR, ACRE, TRGT], True),\n        {18} wbFormIDCkNoReach('Voice Type', [VTYP]),\n        {19} wbFormIDCkNoReach('Idle', [IDLE]),\n        {20} wbFormIDCkNoReach('Form List', [FLST]),\n        {21} wbFormIDCkNoReach('Note', [NOTE]),\n        {22} wbFormIDCkNoReach('Quest', [QUST]),\n        {23} wbFormIDCkNoReach('Faction', [FACT]),\n        {24} wbFormIDCkNoReach('Weapon', [WEAP]),\n        {25} wbFormIDCkNoReach('Cell', [CELL]),\n        {26} wbFormIDCkNoReach('Class', [CLAS]),\n        {27} wbFormIDCkNoReach('Race', [RACE]),\n        {28} wbFormIDCkNoReach('Actor Base', [NPC_, CREA, ACTI, TACT, NULL]),\n        {29} wbFormIDCkNoReach('Global', [GLOB]),\n        {30} wbFormIDCkNoReach('Weather', [WTHR]),\n        {31} wbFormIDCkNoReach('Package', [PACK]),\n        {32} wbFormIDCkNoReach('Encounter Zone', [ECZN]),\n        {33} wbFormIDCkNoReach('Perk', [PERK]),\n        {34} wbFormIDCkNoReach('Owner', [FACT, NPC_]),\n        {35} wbFormIDCkNoReach('Furniture', [FURN, FLST]),\n        {36} wbFormIDCkNoReach('Effect Item', [SPEL, ENCH, ALCH, INGR]),\n        {37} wbFormIDCkNoReach('Base Effect', [MGEF]),\n        {38} wbFormIDCkNoReach('Worldspace', [WRLD]),\n        {39} wbInteger('VATS Value Function', itU32, wbVATSValueFunctionEnum),\n        {40} wbInteger('VATS Value Param (INVALID)', itU32),\n        {41} wbInteger('Creature Type', itU32, wbCreatureTypeEnum),\n        {42} wbInteger('Menu Mode', itU32, wbMenuModeEnum),\n        {43} wbInteger('Player Action', itU32, wbPlayerActionEnum),\n        {44} wbInteger('Body Location', itS32, wbBodyLocationEnum),\n        {45} wbFormIDCkNoReach('Referenceable Object', [CREA, NPC_, PROJ, TREE, SOUN, ACTI, DOOR, STAT, FURN, CONT, ARMO, AMMO, MISC, WEAP, BOOK, KEYM, ALCH, LIGH, GRAS, ASPC, IDLM, ARMA, MSTT, NOTE, PWAT, SCOL, TACT, TERM, FLST, CHIP, CMNY, CCRD, IMOD, LVLC, LVLN],\n                                                [CREA, NPC_, PROJ, TREE, SOUN, ACTI, DOOR, STAT, FURN, CONT, ARMO, AMMO, MISC, WEAP, BOOK, KEYM, ALCH, LIGH, GRAS, ASPC, IDLM, ARMA, MSTT, NOTE, PWAT, SCOL, TACT, TERM, CHIP, CMNY, CCRD, IMOD, LVLC, LVLN]),\n        {46} wbInteger('Quest Objective (INVALID)', itS32),\n        {47} wbFormIDCkNoReach('Reputation', [REPU]),\n        {48} wbFormIDCkNoReach('Region', [REGN]),\n        {49} wbFormIDCkNoReach('Challenge', [CHAL]),\n        {50} wbFormIDCkNoReach('Casino', [CSNO]),\n        {51} wbFormID('Form')\n      ]),\n      wbUnion('Parameter #2', wbCTDAParam2Decider, [\n        {00} wbByteArray('Unknown', 4),\n        {01} wbByteArray('None', 4, cpIgnore),\n        {02} wbInteger('Integer', itS32),\n        {03} wbInteger('Variable Name', itS32, wbCTDAParam2VariableNameToStr, wbCTDAParam2VariableNameToInt),\n        {04} wbInteger('Sex', itU32, wbSexEnum),\n        {05} wbInteger('Actor Value', itS32, wbActorValueEnum),\n        {06} wbInteger('Crime Type', itU32, wbCrimeTypeEnum),\n        {07} wbInteger('Axis', itU32, wbAxisEnum),\n        {08} wbInteger('Quest Stage', itS32, wbCTDAParam2QuestStageToStr, wbCTDAParam2QuestStageToInt),\n        {09} wbInteger('Misc Stat', itU32, wbMiscStatEnum),\n        {10} wbInteger('Alignment', itU32, wbAlignmentEnum),\n        {11} wbInteger('Equip Type', itU32, wbEquipTypeEnum),\n        {12} wbInteger('Form Type', itU32, wbFormTypeEnum),\n        {13} wbInteger('Critical Stage', itU32, wbCriticalStageEnum),\n        {14} wbFormIDCkNoReach('Object Reference', [PLYR, REFR, PMIS, PBEA, ACHR, ACRE, PGRE, TRGT], True),\n        {16} wbFormIDCkNoReach('Inventory Object', [ARMO, BOOK, MISC, WEAP, AMMO, KEYM, ALCH, NOTE, FLST, CHIP, CMNY, CCRD, IMOD]),\n        {17} wbFormIDCkNoReach('Actor', [PLYR, ACHR, ACRE, TRGT], True),\n        {18} wbFormIDCkNoReach('Voice Type', [VTYP]),\n        {19} wbFormIDCkNoReach('Idle', [IDLE]),\n        {20} wbFormIDCkNoReach('Form List', [FLST]),\n        {21} wbFormIDCkNoReach('Note', [NOTE]),\n        {22} wbFormIDCkNoReach('Quest', [QUST]),\n        {23} wbFormIDCkNoReach('Faction', [FACT]),\n        {24} wbFormIDCkNoReach('Weapon', [WEAP]),\n        {25} wbFormIDCkNoReach('Cell', [CELL]),\n        {26} wbFormIDCkNoReach('Class', [CLAS]),\n        {27} wbFormIDCkNoReach('Race', [RACE]),\n        {28} wbFormIDCkNoReach('Actor Base', [NPC_, CREA, ACTI, TACT]),\n        {29} wbFormIDCkNoReach('Global', [GLOB]),\n        {30} wbFormIDCkNoReach('Weather', [WTHR]),\n        {31} wbFormIDCkNoReach('Package', [PACK]),\n        {32} wbFormIDCkNoReach('Encounter Zone', [ECZN]),\n        {33} wbFormIDCkNoReach('Perk', [PERK]),\n        {34} wbFormIDCkNoReach('Owner', [FACT, NPC_]),\n        {35} wbFormIDCkNoReach('Furniture', [FURN, FLST]),\n        {36} wbFormIDCkNoReach('Effect Item', [SPEL, ENCH, ALCH, INGR]),\n        {37} wbFormIDCkNoReach('Base Effect', [MGEF]),\n        {38} wbFormIDCkNoReach('Worldspace', [WRLD]),\n        {39} wbInteger('VATS Value Function (INVALID)', itU32),\n        {40} wbUnion('VATS Value Param', wbCTDAParam2VATSValueParam, [\n               wbFormIDCkNoReach('Weapon', [WEAP]),\n               wbFormIDCkNoReach('Weapon List', [FLST], [WEAP]),\n               wbFormIDCkNoReach('Target', [NPC_, CREA]),\n               wbFormIDCkNoReach('Target List', [FLST], [NPC_, CREA]),\n               wbByteArray('Unused', 4, cpIgnore),\n               wbInteger('Target Part', itS32, wbActorValueEnum),\n               wbInteger('VATS Action', itU32, wbEnum([\n                 'Unarmed Attack',\n                 'One Hand Melee Attack',\n                 'Two Hand Melee Attack',\n                 'Fire Pistol',\n                 'Fire Rifle',\n                 'Fire Handle Weapon',\n                 'Fire Launcher',\n                 'Throw Grenade',\n                 'Place Mine',\n                 'Reload',\n                 'Crouch',\n                 'Stand',\n                 'Switch Weapon',\n                 'Toggle Weapon Drawn',\n                 'Heal',\n                 'Player Death',\n                 'Special Weapon Attack',\n                 'Special Unarmed Attack',\n                 'Kill Camera Shot',\n                 'Throw Weapon'\n               ])),\n               wbByteArray('Unused', 4, cpIgnore),\n               wbByteArray('Unused', 4, cpIgnore),\n               wbFormIDCkNoReach('Critical Effect', [SPEL]),\n               wbFormIDCkNoReach('Critical Effect List', [FLST], [SPEL]),\n               wbByteArray('Unused', 4, cpIgnore),\n               wbByteArray('Unused', 4, cpIgnore),\n               wbByteArray('Unused', 4, cpIgnore),\n               wbByteArray('Unused', 4, cpIgnore),\n               wbInteger('Weapon Type', itU32, wbWeaponAnimTypeEnum),\n               wbByteArray('Unused', 4, cpIgnore),\n               wbByteArray('Unused', 4, cpIgnore)\n             ]),\n        {41} wbInteger('Creature Type', itU32, wbCreatureTypeEnum),\n        {42} wbInteger('Menu Mode', itU32, wbMenuModeEnum),\n        {43} wbInteger('Player Action', itU32, wbPlayerActionEnum),\n        {44} wbInteger('Body Location', itS32, wbBodyLocationEnum),\n        {45} wbFormIDCkNoReach('Referenceable Object', [CREA, NPC_, PROJ, TREE, SOUN, ACTI, DOOR, STAT, FURN, CONT, ARMO, AMMO, MISC, WEAP, BOOK, KEYM, ALCH, LIGH, GRAS, ASPC, IDLM, ARMA, MSTT, NOTE, PWAT, SCOL, TACT, TERM, FLST, CHIP, CMNY, CCRD, IMOD, LVLC, LVLN],\n                                                [CREA, NPC_, PROJ, TREE, SOUN, ACTI, DOOR, STAT, FURN, CONT, ARMO, AMMO, MISC, WEAP, BOOK, KEYM, ALCH, LIGH, GRAS, ASPC, IDLM, ARMA, MSTT, NOTE, PWAT, SCOL, TACT, TERM, CHIP, CMNY, CCRD, IMOD, LVLC, LVLN]),\n        {46} wbInteger('Quest Objective', itS32, wbCTDAParam2QuestObjectiveToStr, wbCTDAParam2QuestObjectiveToInt),\n        {47} wbFormIDCkNoReach('Reputation', [REPU]),\n        {48} wbFormIDCkNoReach('Region', [REGN]),\n        {49} wbFormIDCkNoReach('Challenge', [CHAL]),\n        {50} wbFormIDCkNoReach('Casino', [CSNO]),\n        {51} wbFormID('Form')\n      ]),\n      wbInteger('Run On', itU32, wbEnum([\n        'Subject',\n        'Target',\n        'Reference',\n        'Combat Target',\n        'Linked Reference'\n      ]), cpNormal, False, nil, wbCTDARunOnAfterSet),\n      wbUnion('Reference', wbCTDAReferenceDecider, [\n        wbInteger('Unused', itU32, nil, cpIgnore),\n        wbFormIDCkNoReach('Reference', [PLYR, ACHR, ACRE, REFR, PMIS, PBEA, PGRE, NULL], True)    // Can end up NULL if the original function requiring a reference is replaced by another who has no Run on prerequisite\n      ])\n    ], cpNormal, False, nil, 6, wbCTDAAfterLoad);\n  wbCTDAs := wbRArray('Conditions', wbCTDA);\n  wbCTDAsReq := wbRArray('Conditions', wbCTDA, cpNormal, True);\n\n  wbEffects :=\n    wbRStructs('Effects','Effect', [\n      wbEFID,\n      wbEFIT,\n      wbCTDAs\n    ], []);\n\n  wbEffectsReq :=\n    wbRStructs('Effects','Effect', [\n      wbEFID,\n      wbEFIT,\n      wbCTDAs\n    ], [], cpNormal, True);\n\n\n  wbRecord(ALCH, 'Ingestible', [\n    wbEDIDReq,\n    wbOBNDReq,\n    wbFULLReq,\n    wbMODL,\n    wbICON,\n    wbSCRI,\n    wbDEST,\n    wbYNAM,\n    wbZNAM,\n    wbETYPReq,\n    wbFloat(DATA, 'Weight', cpNormal, True),\n    wbStruct(ENIT, 'Effect Data', [\n      wbInteger('Value', itS32),\n      wbInteger('Flags?', itU8, wbFlags([\n        'No Auto-Calc (Unused)',\n        'Food Item',\n        'Medicine'\n      ])),\n      wbByteArray('Unused', 3),\n      wbFormIDCk('Withdrawal Effect', [SPEL, NULL]),\n      wbFloat('Addiction Chance'),\n      wbFormIDCk('Sound - Consume', [SOUN, NULL])\n    ], cpNormal, True),\n    wbEffectsReq\n  ]);\n\n  wbRecord(AMMO, 'Ammunition', [\n    wbEDIDReq,\n    wbOBNDReq,\n    wbFULLReq,\n    wbMODL,\n    wbICON,\n    wbSCRI,\n    wbDEST,\n    wbYNAM,\n    wbZNAM,\n    wbStruct(DATA, 'Data', [\n      wbFloat('Speed'),\n      wbInteger('Flags', itU8, wbFlags([\n        'Ignores Normal Weapon Resistance',\n        'Non-Playable'\n      ])),\n      wbByteArray('Unused', 3),\n      wbInteger('Value', itS32),\n      wbInteger('Clip Rounds', itU8)\n    ], cpNormal, True),\n    wbStruct(DAT2, 'Data 2', [\n      wbInteger('Proj. per Shot', itU32),\n      wbFormIDCk('Projectile', [PROJ, NULL]),\n      wbFloat('Weight'),\n      wbFormIDCk('Consumed Ammo', [AMMO, MISC, NULL]),\n      wbFloat('Consumed Percentage')\n    ], cpNormal, False, nil, 3),\n    wbString(ONAM, 'Short Name'),\n    wbString(QNAM, 'Abbrev.'),\n    wbRArray('Ammo Effects',\n      wbFormIDCk(RCIL, 'Effect', [AMEF])\n    )\n  ]);\n\n  wbRecord(ANIO, 'Animated Object', [\n    wbEDIDReq,\n    wbMODLReq,\n    wbFormIDCk(DATA, 'Animation', [IDLE], False, cpNormal, True)\n  ]);\n\n  wbBMDT := wbStruct(BMDT, 'Biped Data', [\n      wbInteger('Biped Flags', itU32, wbFlags([\n        {0x00000001} 'Head',\n        {0x00000002} 'Hair',\n        {0x00000004} 'Upper Body',\n        {0x00000008} 'Left Hand',\n        {0x00000010} 'Right Hand',\n        {0x00000020} 'Weapon',\n        {0x00000040} 'PipBoy',\n        {0x00000080} 'Backpack',\n        {0x00000100} 'Necklace',\n        {0x00000200} 'Headband',\n        {0x00000400} 'Hat',\n        {0x00000800} 'Eye Glasses',\n        {0x00001000} 'Nose Ring',\n        {0x00002000} 'Earrings',\n        {0x00004000} 'Mask',\n        {0x00008000} 'Choker',\n        {0x00010000} 'Mouth Object',\n        {0x00020000} 'Body AddOn 1',\n        {0x00040000} 'Body AddOn 2',\n        {0x00080000} 'Body AddOn 3'\n      ])),\n      wbInteger('General Flags', itU8, wbFlags([\n        {0x0001} '1',\n        {0x0002} '2',\n        {0x0004} 'Has Backpack',\n        {0x0008} 'Medium',\n        {0x0010} '5',\n        {0x0020} 'Power Armor',\n        {0x0040} 'Non-Playable',\n        {0x0080} 'Heavy'\n      ], True)),\n      wbByteArray('Unused')\n    ], cpNormal, True);\n\n  wbRecord(ARMO, 'Armor', [\n    wbEDIDReq,\n    wbOBNDReq,\n    wbFULL,\n    wbSCRI,\n    wbEITM,\n    wbBMDT,\n    wbRStruct('Male biped model', [\n      wbString(MODL, 'Model Filename', 0, cpNormal, True),\n      wbByteArray(MODT, 'Texture Files Hashes', 0, cpIgnore),\n      wbMODS,\n      wbMODD\n    ], [], cpNormal, False, nil, True),\n    wbRStruct('Male world model', [\n      wbString(MOD2, 'Model Filename'),\n      wbByteArray(MO2T, 'Texture Files Hashes', 0, cpIgnore),\n      wbMO2S\n    ], []),\n    wbString(ICON, 'Male icon filename'),\n    wbString(MICO, 'Male mico filename'),\n    wbRStruct('Female biped model', [\n      wbString(MOD3, 'Model Filename', 0, cpNormal, True),\n      wbByteArray(MO3T, 'Texture Files Hashes', 0, cpIgnore),\n      wbMO3S,\n      wbMOSD\n    ], [], cpNormal, False, nil, True),\n    wbRStruct('Female world model', [\n      wbString(MOD4, 'Model Filename'),\n      wbByteArray(MO4T, 'Texture Files Hashes', 0, cpIgnore),\n      wbMO4S\n    ], []),\n    wbString(ICO2, 'Female icon filename'),\n    wbString(MIC2, 'Female mico filename'),\n    wbString(BMCT, 'Ragdoll Constraint Template'),\n    wbREPL,\n    wbBIPL,\n    wbETYPReq,\n    wbYNAM,\n    wbZNAM,\n    wbStruct(DATA, 'Data', [\n      wbInteger('Value', itS32),\n      wbInteger('Health', itS32),\n      wbFloat('Weight')\n    ], cpNormal, True),\n    wbStruct(DNAM, '', [\n      wbInteger('AR', itS16, wbDiv(100)),\n      wbInteger('Flags', itU16, wbFlags([\n        'Modulates Voice'\n      ])),\n      wbFloat('DT'),\n      wbByteArray('?', 4)\n    ], cpNormal, True, nil, 2),\n    wbInteger(BNAM, 'Overrides Animation Sounds', itU32, wbEnum(['No', 'Yes'])),\n    wbRArray('Animation Sounds',\n      wbStruct(SNAM, 'Animation Sound', [\n        wbFormIDCk('Sound', [SOUN]),\n        wbInteger('Chance', itU8),\n        wbByteArray('Unused', 3),\n        wbInteger('Type', itU32, wbEnum([], [\n          19, 'Run',\n          21, 'Run (Armor)',\n          18, 'Sneak',\n          20, 'Sneak (Armor)',\n          17, 'Walk',\n          22, 'Walk (Armor)'\n        ]))\n      ])\n    ),\n    wbFormIDCk(TNAM, 'Animation Sounds Template', [ARMO])\n  ]);\n\n  wbRecord(ARMA, 'Armor Addon', [\n    wbEDIDReq,\n    wbOBNDReq,\n    wbFULL,\n    wbBMDT,\n    wbRStruct('Male biped model', [\n      wbString(MODL, 'Model Filename', 0, cpNormal, True),\n      wbByteArray(MODT, 'Texture Files Hashes', 0, cpIgnore),\n      wbMODS,\n      wbMODD\n    ], [], cpNormal, False, nil, True),\n    wbRStruct('Male world model', [\n      wbString(MOD2, 'Model Filename'),\n      wbByteArray(MO2T, 'Texture Files Hashes', 0, cpIgnore),\n      wbMO2S\n    ], []),\n    wbString(ICON, 'Male icon filename'),\n    wbString(MICO, 'Male mico filename'),\n    wbRStruct('Female biped model', [\n      wbString(MOD3, 'Model Filename', 0, cpNormal, True),\n      wbByteArray(MO3T, 'Texture Files Hashes', 0, cpIgnore),\n      wbMO3S,\n      wbMOSD\n    ], [], cpNormal, False, nil, True),\n    wbRStruct('Female world model', [\n      wbString(MOD4, 'Model Filename'),\n      wbByteArray(MO4T, 'Texture Files Hashes', 0, cpIgnore),\n      wbMO4S\n    ], []),\n    wbString(ICO2, 'Female icon filename'),\n    wbString(MIC2, 'Female mico filename'),\n    wbETYPReq,\n    wbStruct(DATA, 'Data', [\n      wbInteger('Value', itS32),\n      wbInteger('Max Condition', itS32),\n      wbFloat('Weight')\n    ], cpNormal, True),\n    wbStruct(DNAM, '', [\n      wbInteger('AR', itS16, wbDiv(100)),\n      wbInteger('Flags', itU16, wbFlags([ // Only a byte or 2 distincts byte\n        'Modulates Voice'\n      ])),\n      wbFloat('DT'),\n      wbByteArray('Unused', 4)\n    ], cpNormal, True, nil, 2)\n  ]);\n\n  wbRecord(BOOK, 'Book', [\n    wbEDIDReq,\n    wbOBNDReq,\n    wbFULL,\n    wbMODL,\n    wbICON,\n    wbSCRI,\n    wbDESCReq,\n    wbDEST,\n    wbYNAM,\n    wbZNAM,\n    wbStruct(DATA, 'Data', [\n      wbInteger('Flags', itU8, wbFlags([\n        '',\n        'Can''t be Taken'\n      ])),\n      wbInteger('Skill', itS8, wbSkillEnum),\n      wbInteger('Value', itS32),\n      wbFloat('Weight')\n    ], cpNormal, True)\n  ]);\n\n  wbSPLO := wbFormIDCk(SPLO, 'Actor Effect', [SPEL]);\n  wbSPLOs := wbRArrayS('Actor Effects', wbSPLO, cpNormal, False, nil, nil, wbActorTemplateUseActorEffectList);\n\n  wbRecord(CELL, 'Cell', [\n    wbEDID,\n    wbFULL,\n    wbInteger(DATA, 'Flags', itU8, wbFlags([\n      {0x01} 'Is Interior Cell',\n      {0x02} 'Has water',\n      {0x04} 'Invert Fast Travel behavior',\n      {0x08} 'No LOD Water',\n      {0x10} '',\n      {0x20} 'Public place',\n      {0x40} 'Hand changed',\n      {0x80} 'Behave like exterior'\n    ]), cpNormal, True),\n    wbStruct(XCLC, 'Grid', [\n      wbInteger('X', itS32),\n      wbInteger('Y', itS32),\n      wbInteger('Force Hide Land', itU32, wbFlags([\n        'Quad 1',\n        'Quad 2',\n        'Quad 3',\n        'Quad 4'\n      ], True))\n    ], cpNormal, False, nil, 2),\n    wbStruct(XCLL, 'Lighting', [\n      wbStruct('Ambient Color', [\n        wbInteger('Red', itU8),\n        wbInteger('Green', itU8),\n        wbInteger('Blue', itU8),\n        wbByteArray('Unused', 1)\n      ]),\n      wbStruct('Directional Color', [\n        wbInteger('Red', itU8),\n        wbInteger('Green', itU8),\n        wbInteger('Blue', itU8),\n        wbByteArray('Unused', 1)\n      ]),\n      wbStruct('Fog Color', [\n        wbInteger('Red', itU8),\n        wbInteger('Green', itU8),\n        wbInteger('Blue', itU8),\n        wbByteArray('Unused', 1)\n      ]),\n      wbFloat('Fog Near'),\n      wbFloat('Fog Far'),\n      wbInteger('Directional Rotation XY', itS32),\n      wbInteger('Directional Rotation Z', itS32),\n      wbFloat('Directional Fade'),\n      wbFloat('Fog Clip Dist'),\n      wbFloat('Fog Power')\n    ], cpNormal, False, nil, 7),\n    wbArray(IMPF, 'Footstep Materials', wbString('Unknown', 30), [\n      'ConcSolid',\n      'ConcBroken',\n      'MetalSolid',\n      'MetalHollow',\n      'MetalSheet',\n      'Wood',\n      'Sand',\n      'Dirt',\n      'Grass',\n      'Water'\n    ]),\n    wbRStruct('Light Template', [\n      wbFormIDCk(LTMP, 'Template', [LGTM, NULL]),\n      wbInteger(LNAM, 'Inherit', itU32, wbFlags([\n        {0x00000001}'Ambient Color',\n        {0x00000002}'Directional Color',\n        {0x00000004}'Fog Color',\n        {0x00000008}'Fog Near',\n        {0x00000010}'Fog Far',\n        {0x00000020}'Directional Rotation',\n        {0x00000040}'Directional Fade',\n        {0x00000080}'Clip Distance',\n        {0x00000100}'Fog Power'\n      ]), cpNormal, True)\n    ], [], cpNormal, True ),\n    wbFloat(XCLW, 'Water Height'),\n    wbString(XNAM, 'Water Noise Texture'),\n    wbArrayS(XCLR, 'Regions', wbFormIDCk('Region', [REGN])),\n    wbFormIDCk(XCIM, 'Image Space', [IMGS]),\n    wbByteArray(XCET, 'Unknown', 1, cpIgnore),\n    wbFormIDCk(XEZN, 'Encounter Zone', [ECZN]),\n    wbFormIDCk(XCCM, 'Climate', [CLMT]),\n    wbFormIDCk(XCWT, 'Water', [WATR]),\n    wbRStruct('Ownership', [\n      wbXOWN,\n      wbInteger(XRNK, 'Faction rank', itS32)\n    ], [XCMT, XCMO]),\n    wbFormIDCk(XCAS, 'Acoustic Space', [ASPC]),\n    wbByteArray(XCMT, 'Unused', 1, cpIgnore),\n    wbFormIDCk(XCMO, 'Music Type', [MUSC])\n  ], True, wbCellAddInfo, cpNormal, False, wbCELLAfterLoad);\n\n  wbServiceFlags :=\n    wbFlags([\n      {0x00000001} 'Weapons',\n      {0x00000002} 'Armor',\n      {0x00000004} 'Alcohol',\n      {0x00000008} 'Books',\n      {0x00000010} 'Food',\n      {0x00000020} 'Chems',\n      {0x00000040} 'Stimpacks',\n      {0x00000080} 'Lights?',\n      {0x00000100} '',\n      {0x00000200} '',\n      {0x00000400} 'Miscellaneous',\n      {0x00000800} '',\n      {0x00001000} '',\n      {0x00002000} 'Potions?',\n      {0x00004000} 'Training',\n      {0x00008000} '',\n      {0x00010000} 'Recharge',\n      {0x00020000} 'Repair'\n    ]);\n\n  wbSpecializationEnum := wbEnum(['Combat', 'Magic', 'Stealth']);\n\n  wbRecord(CLAS, 'Class', [\n    wbEDIDReq,\n    wbFULLReq,\n    wbDESCReq,\n    wbICON,\n    wbStruct(DATA, '', [\n      wbArray('Tag Skills', wbInteger('Tag Skill', itS32, wbActorValueEnum), 4),\n      wbInteger('Flags', itU32, wbFlags(['Playable', 'Guard'], True)),\n      wbInteger('Buys/Sells and Services', itU32, wbServiceFlags),\n      wbInteger('Teaches', itS8, wbSkillEnum),\n      wbInteger('Maximum training level', itU8),\n      wbByteArray('Unused', 2)\n    ], cpNormal, True),\n    wbArray(ATTR, 'Attributes', wbInteger('Attribute', itU8), [\n      'Strength',\n      'Perception',\n      'Endurance',\n      'Charisma',\n      'Intelligence',\n      'Agility',\n      'Luck'\n    ], cpNormal, True)\n  ]);\nend;\n\nprocedure DefineFNVc;\nbegin\n  wbRecord(CLMT, 'Climate', [\n    wbEDIDReq,\n    wbArrayS(WLST, 'Weather Types', wbStructSK([0], 'Weather Type', [\n      wbFormIDCk('Weather', [WTHR, NULL]),\n      wbInteger('Chance', itS32),\n      wbFormIDCk('Global', [GLOB, NULL])\n    ])),\n    wbString(FNAM, 'Sun Texture'),\n    wbString(GNAM, 'Sun Glare Texture'),\n    wbMODL,\n    wbStruct(TNAM, 'Timing', [\n      wbStruct('Sunrise', [\n        wbInteger('Begin', itU8, wbClmtTime),\n        wbInteger('End', itU8, wbClmtTime)\n      ]),\n      wbStruct('Sunset', [\n        wbInteger('Begin', itU8, wbClmtTime),\n        wbInteger('End', itU8, wbClmtTime)\n      ]),\n      wbInteger('Volatility', itU8),\n      wbInteger('Moons / Phase Length', itU8, wbClmtMoonsPhaseLength)\n    ], cpNormal, True)\n  ]);\n\n  wbCNTO :=\n    wbRStructExSK([0], [1], 'Item', [\n      wbStructExSK(CNTO, [0], [1], 'Item', [\n        wbFormIDCk('Item', [ARMO, AMMO, MISC, WEAP, BOOK, LVLI, KEYM, ALCH, NOTE, IMOD, CMNY, CCRD, LIGH, CHIP{, MSTT{?}{, STAT{?}]),\n        wbInteger('Count', itS32)\n      ]),\n      wbCOED\n    ], []);\n\n  wbCNTOs := wbRArrayS('Items', wbCNTO);\n\n  wbRecord(CONT, 'Container', [\n    wbEDIDReq,\n    wbOBNDReq,\n    wbFULL,\n    wbMODL,\n    wbSCRI,\n    wbCNTOs,\n    wbDEST,\n    wbStruct(DATA, '', [\n      wbInteger('Flags', itU8, wbFlags(['', 'Respawns'])),\n      wbFloat('Weight')\n    ], cpNormal, True),\n    wbFormIDCk(SNAM, 'Sound - Open', [SOUN]),\n    wbFormIDCk(QNAM, 'Sound - Close', [SOUN]),\n    wbFormIDCk(RNAM, 'Sound - Random/Looping', [SOUN])\n  ], True);\n\n  wbCSDT := wbRStructSK([0], 'Sound Type', [\n    wbInteger(CSDT, 'Type', itU32,wbEnum([\n      {00} 'Left Foot',\n      {01} 'Right Foot',\n      {02} 'Left Back Foot',\n      {03} 'Right Back Foot',\n      {04} 'Idle',\n      {05} 'Aware',\n      {06} 'Attack',\n      {07} 'Hit',\n      {08} 'Death',\n      {09} 'Weapon',\n      {10} 'Movement Loop',\n      {11} 'Conscious Loop',\n      {12} 'Auxiliary 1',\n      {13} 'Auxiliary 2',\n      {14} 'Auxiliary 3',\n      {15} 'Auxiliary 4',\n      {16} 'Auxiliary 5',\n      {17} 'Auxiliary 6',\n      {18} 'Auxiliary 7',\n      {19} 'Auxiliary 8',\n      {19} 'Auxiliary 8',\n      {20} 'Jump',\n      {21} 'PlayRandom/Loop'\n    ])),\n    wbRArrayS('Sounds', wbRStructSK([0], 'Sound', [\n      wbFormIDCk(CSDI, 'Sound', [SOUN, NULL], False, cpNormal, True),\n      wbInteger(CSDC, 'Sound Chance', itU8, nil, cpNormal, True)\n    ], []), cpNormal, True)\n  ], []);\n\n  wbCSDTs := wbRArrayS('Sound Types', wbCSDT, cpNormal, False, nil, nil, wbActorTemplateUseModelAnimation);\n\n  wbAgressionEnum := wbEnum([\n    'Unaggressive',\n    'Aggressive',\n    'Very Aggressive',\n    'Frenzied'\n  ]);\n\n  wbConfidenceEnum := wbEnum([\n    'Cowardly',\n    'Cautious',\n    'Average',\n    'Brave',\n    'Foolhardy'\n  ]);\n\n  wbMoodEnum := wbEnum([\n    'Neutral',\n    'Afraid',\n    'Annoyed',\n    'Cocky',\n    'Drugged',\n    'Pleasant',\n    'Angry',\n    'Sad'\n  ]);\n\n  wbAssistanceEnum := wbEnum([\n    'Helps Nobody',\n    'Helps Allies',\n    'Helps Friends and Allies'\n  ]);\n\n  wbAggroRadiusFlags := wbFlags([\n    'Aggro Radius Behavior'\n  ]);\n\n  wbAIDT :=\n    wbStruct(AIDT, 'AI Data', [\n     {00} wbInteger('Aggression', itU8, wbAgressionEnum),\n     {01} wbInteger('Confidence', itU8, wbConfidenceEnum),\n     {02} wbInteger('Energy Level', itU8),\n     {03} wbInteger('Responsibility', itU8),\n     {04} wbInteger('Mood', itU8, wbMoodEnum),\n     {05} wbByteArray('Unused', 3),   // Mood is stored as a DWord as shown by endianSwapping but is truncated to byte during load :)\n     {08} wbInteger('Buys/Sells and Services', itU32, wbServiceFlags),\n     {0C} wbInteger('Teaches', itS8, wbSkillEnum),\n     {0D} wbInteger('Maximum training level', itU8),\n     {0E} wbInteger('Assistance', itS8, wbAssistanceEnum),\n     {0F} wbInteger('Aggro Radius Behavior', itU8, wbAggroRadiusFlags),\n     {10} wbInteger('Aggro Radius', itS32)\n    ], cpNormal, True, wbActorTemplateUseAIData);\n\n  wbAttackAnimationEnum :=\n    wbEnum([\n    ], [\n       26, 'AttackLeft',\n       27, 'AttackLeftUp',\n       28, 'AttackLeftDown',\n       29, 'AttackLeftIS',\n       30, 'AttackLeftISUp',\n       31, 'AttackLeftISDown',\n       32, 'AttackRight',\n       33, 'AttackRightUp',\n       34, 'AttackRightDown',\n       35, 'AttackRightIS',\n       36, 'AttackRightISUp',\n       37, 'AttackRightISDown',\n       38, 'Attack3',\n       39, 'Attack3Up',\n       40, 'Attack3Down',\n       41, 'Attack3IS',\n       42, 'Attack3ISUp',\n       43, 'Attack3ISDown',\n       44, 'Attack4',\n       45, 'Attack4Up',\n       46, 'Attack4Down',\n       47, 'Attack4IS',\n       48, 'Attack4ISUp',\n       49, 'Attack4ISDown',\n       50, 'Attack5',\n       51, 'Attack5Up',\n       52, 'Attack5Down',\n       53, 'Attack5IS',\n       54, 'Attack5ISUp',\n       55, 'Attack5ISDown',\n       56, 'Attack6',\n       57, 'Attack6Up',\n       58, 'Attack6Down',\n       59, 'Attack6IS',\n       60, 'Attack6ISUp',\n       61, 'Attack6ISDown',\n       62, 'Attack7',\n       63, 'Attack7Up',\n       64, 'Attack7Down',\n       65, 'Attack7IS',\n       66, 'Attack7ISUp',\n       67, 'Attack7ISDown',\n       68, 'Attack8',\n       69, 'Attack8Up',\n       70, 'Attack8Down',\n       71, 'Attack8IS',\n       72, 'Attack8ISUp',\n       73, 'Attack8ISDown',\n       74, 'AttackLoop',\n       75, 'AttackLoopUp',\n       76, 'AttackLoopDown',\n       77, 'AttackLoopIS',\n       78, 'AttackLoopISUp',\n       79, 'AttackLoopISDown',\n       80, 'AttackSpin',\n       81, 'AttackSpinUp',\n       82, 'AttackSpinDown',\n       83, 'AttackSpinIS',\n       84, 'AttackSpinISUp',\n       85, 'AttackSpinISDown',\n       86, 'AttackSpin2',\n       87, 'AttackSpin2Up',\n       88, 'AttackSpin2Down',\n       89, 'AttackSpin2IS',\n       90, 'AttackSpin2ISUp',\n       91, 'AttackSpin2ISDown',\n       92, 'AttackPower',\n       93, 'AttackForwardPower',\n       94, 'AttackBackPower',\n       95, 'AttackLeftPower',\n       96, 'AttackRightPower',\n       97, 'PlaceMine',\n       98, 'PlaceMineUp',\n       99, 'PlaceMineDown',\n      100, 'PlaceMineIS',\n      101, 'PlaceMineISUp',\n      102, 'PlaceMineISDown',\n      103, 'PlaceMine2',\n      104, 'PlaceMine2Up',\n      105, 'PlaceMine2Down',\n      106, 'PlaceMine2IS',\n      107, 'PlaceMine2ISUp',\n      108, 'PlaceMine2ISDown',\n      109, 'AttackThrow',\n      110, 'AttackThrowUp',\n      111, 'AttackThrowDown',\n      112, 'AttackThrowIS',\n      113, 'AttackThrowISUp',\n      114, 'AttackThrowISDown',\n      115, 'AttackThrow2',\n      116, 'AttackThrow2Up',\n      117, 'AttackThrow2Down',\n      118, 'AttackThrow2IS',\n      119, 'AttackThrow2ISUp',\n      120, 'AttackThrow2ISDown',\n      121, 'AttackThrow3',\n      122, 'AttackThrow3Up',\n      123, 'AttackThrow3Down',\n      124, 'AttackThrow3IS',\n      125, 'AttackThrow3ISUp',\n      126, 'AttackThrow3ISDown',\n      127, 'AttackThrow4',\n      128, 'AttackThrow4Up',\n      129, 'AttackThrow4Down',\n      130, 'AttackThrow4IS',\n      131, 'AttackThrow4ISUp',\n      132, 'AttackThrow4ISDown',\n      133, 'AttackThrow5',\n      134, 'AttackThrow5Up',\n      135, 'AttackThrow5Down',\n      136, 'AttackThrow5IS',\n      137, 'AttackThrow5ISUp',\n      138, 'AttackThrow5ISDown',\n\n      167, 'PipBoy',\n      178, 'PipBoyChild',\n\n      255, ' ANY'\n    ]);\n\n  wbImpactMaterialTypeEnum :=\n    wbEnum([\n      'Stone',\n      'Dirt',\n      'Grass',\n      'Glass',\n      'Metal',\n      'Wood',\n      'Organic',\n      'Cloth',\n      'Water',\n      'Hollow Metal',\n      'Organic Bug',\n      'Organic Glow'\n    ]);\n\n  wbTemplateFlags := wbFlags([\n    'Use Traits',\n    'Use Stats',\n    'Use Factions',\n    'Use Actor Effect List',\n    'Use AI Data',\n    'Use AI Packages',\n    'Use Model/Animation',\n    'Use Base Data',\n    'Use Inventory',\n    'Use Script'\n  ]);\n\n  wbRecord(CREA, 'Creature', [\n    wbEDIDReq,\n    wbOBNDReq,\n    wbFULLActor,\n    wbMODLActor,\n    wbSPLOs,\n    wbFormIDCk(EITM, 'Unarmed Attack Effect', [ENCH, SPEL], False, cpNormal, False, wbActorTemplateUseActorEffectList),\n    wbInteger(EAMT, 'Unarmed Attack Animation', itU16, wbAttackAnimationEnum, cpNormal, True, False, wbActorTemplateUseActorEffectList),\n    wbArrayS(NIFZ, 'Model List', wbStringLC('Model'), 0, cpNormal, False, nil, nil, wbActorTemplateUseModelAnimation),\n    wbByteArray(NIFT, 'Texture Files Hashes', 0, cpIgnore, False, False, wbActorTemplateUseModelAnimation),\n    wbStruct(ACBS, 'Configuration', [\n      {00} wbInteger('Flags', itU32, wbFlags([\n             {0x000001} 'Biped',\n             {0x000002} 'Essential',\n             {0x000004} 'Weapon & Shield?',\n             {0x000008} 'Respawn',\n             {0x000010} 'Swims',\n             {0x000020} 'Flies',\n             {0x000040} 'Walks',\n             {0x000080} 'PC Level Mult',\n             {0x000100} 'Unknown 8',\n             {0x000200} 'No Low Level Processing',\n             {0x000400} '',\n             {0x000800} 'No Blood Spray',\n             {0x001000} 'No Blood Decal',\n             {0x002000} '',\n             {0x004000} '',\n             {0x008000} 'No Head',\n             {0x010000} 'No Right Arm',\n             {0x020000} 'No Left Arm',\n             {0x040000} 'No Combat in Water',\n             {0x080000} 'No Shadow',\n             {0x100000} 'No VATS Melee',\n           {0x00200000} 'Allow PC Dialogue',\n           {0x00400000} 'Can''t Open Doors',\n           {0x00800000} 'Immobile',\n           {0x01000000} 'Tilt Front/Back',\n           {0x02000000} 'Tilt Left/Right',\n           {0x03000000} 'No Knockdowns',\n           {0x08000000} 'Not Pushable',\n           {0x10000000} 'Allow Pickpocket',\n           {0x20000000} 'Is Ghost',\n           {0x40000000} 'No Rotating To Head-track',\n           {0x80000000} 'Invulnerable'\n           ], [\n             {0x000001 Biped} wbActorTemplateUseModelAnimation,\n             {0x000002 Essential} wbActorTemplateUseBaseData,\n             {0x000004 Weapon & Shield} nil,\n             {0x000008 Respawn} wbActorTemplateUseBaseData,\n             {0x000010 Swims} wbActorTemplateUseModelAnimation,\n             {0x000020 Flies} wbActorTemplateUseModelAnimation,\n             {0x000040 Walks} wbActorTemplateUseModelAnimation,\n             {0x000080 PC Level Mult} wbActorTemplateUseStats,\n             {0x000100 Unknown 8} nil,\n             {0x000200 No Low Level Processing} wbActorTemplateUseBaseData,\n             {0x000400 } nil,\n             {0x000800 No Blood Spray} wbActorTemplateUseModelAnimation,\n             {0x001000 No Blood Decal} wbActorTemplateUseModelAnimation,\n             {0x002000 } nil,\n             {0x004000 } nil,\n             {0x008000 No Head} wbActorTemplateUseModelAnimation,\n             {0x010000 No Right Arm} wbActorTemplateUseModelAnimation,\n             {0x020000 No Left Arm} wbActorTemplateUseModelAnimation,\n             {0x040000 No Combat in Water} wbActorTemplateUseModelAnimation,\n             {0x080000 No Shadow} wbActorTemplateUseModelAnimation,\n             {0x100000 No VATS Melee} nil,\n           {0x00200000 Allow PC Dialogue} wbActorTemplateUseBaseData,\n           {0x00400000 Can''t Open Doors} wbActorTemplateUseBaseData,\n           {0x00800000 Immobile} wbActorTemplateUseModelAnimation,\n           {0x01000000 Tilt Front/Back} wbActorTemplateUseModelAnimation,\n           {0x02000000 Tilt Left/Right} wbActorTemplateUseModelAnimation,\n           {0x03000000 No Knockdowns} nil,\n           {0x08000000 Not Pushable} wbActorTemplateUseModelAnimation,\n           {0x10000000 Allow Pickpocket} wbActorTemplateUseBaseData,\n           {0x20000000 Is Ghost} nil,\n           {0x40000000 No Rotating To Head-track} wbActorTemplateUseModelAnimation,\n           {0x80000000 Invulnerable} nil\n           ])),\n      {04} wbInteger('Fatigue', itU16, nil, cpNormal, False, wbActorTemplateUseStats),\n      {06} wbInteger('Barter gold', itU16, nil, cpNormal, False, wbActorTemplateUseAIData),\n      {08} wbUnion('Level', wbCreaLevelDecider, [\n             wbInteger('Level', itS16, nil, cpNormal, False, wbActorTemplateUseStats),\n             wbInteger('Level Mult', itS16, wbDiv(1000), cpNormal, False, wbActorTemplateUseStats)\n           ], cpNormal, False, wbActorTemplateUseStats),\n      {10} wbInteger('Calc min', itU16, nil, cpNormal, False, wbActorTemplateUseStats),\n      {12} wbInteger('Calc max', itU16, nil, cpNormal, False, wbActorTemplateUseStats),\n      {14} wbInteger('Speed Multiplier', itU16, nil, cpNormal, False, wbActorTemplateUseStats),\n      {16} wbFloat('Karma (Alignment)', cpNormal, False, 1, -1, wbActorTemplateUseTraits),\n      {20} wbInteger('Disposition Base', itS16, nil, cpNormal, False, wbActorTemplateUseTraits),\n      {22} wbInteger('Template Flags', itU16, wbTemplateFlags)\n    ], cpNormal, True),\n    wbRArrayS('Factions',\n      wbStructSK(SNAM, [0], 'Faction', [\n        wbFormIDCk('Faction', [FACT]),\n        wbInteger('Rank', itU8),\n        wbByteArray('Unused', 3)\n      ]),\n    cpNormal, False, nil, nil, wbActorTemplateUseFactions),\n    wbFormIDCk(INAM, 'Death item', [LVLI], False, cpNormal, False, wbActorTemplateUseTraits),\n    wbFormIDCk(VTCK, 'Voice', [VTYP], False, cpNormal, False, wbActorTemplateUseTraits),\n    wbFormIDCk(TPLT, 'Template', [CREA, LVLC]),\n    wbDESTActor,\n    wbSCRIActor,\n    wbRArrayS('Items', wbCNTO, cpNormal, False, nil, nil, wbActorTemplateUseInventory),\n    wbAIDT,\n    wbRArray('Packages', wbFormIDCk(PKID, 'Package', [PACK]), cpNormal, False, nil, nil, wbActorTemplateUseAIPackages),\n    wbArrayS(KFFZ, 'Animations', wbStringLC('Animation'), 0, cpNormal, False, nil, nil, wbActorTemplateUseModelAnimation),\n    wbStruct(DATA, '', [\n      {00} wbInteger('Type', itU8, wbCreatureTypeEnum, cpNormal, False, wbActorTemplateUseTraits),\n      {01} wbInteger('Combat Skill', itU8, nil, cpNormal, False, wbActorTemplateUseStats),\n      {02} wbInteger('Magic Skill', itU8, nil, cpNormal, False, wbActorTemplateUseStats),\n      {03} wbInteger('Stealth Skill', itU8, nil, cpNormal, False, wbActorTemplateUseStats),\n      {04} wbInteger('Health', itS16, nil, cpNormal, False, wbActorTemplateUseStats),\n      {06} wbByteArray('Unused', 2),\n      {08} wbInteger('Damage', itS16, nil, cpNormal, False, wbActorTemplateUseStats),\n      {10} wbArray('Attributes', wbInteger('Attribute', itU8), [\n            'Strength',\n            'Perception',\n            'Endurance',\n            'Charisma',\n            'Intelligence',\n            'Agility',\n            'Luck'\n          ], cpNormal, False, wbActorTemplateUseStats)\n    ], cpNormal, True),\n    wbInteger(RNAM, 'Attack reach', itU8, nil, cpNormal, True, False, wbActorTemplateUseTraits),\n    wbFormIDCk(ZNAM, 'Combat Style', [CSTY], False, cpNormal, False, wbActorTemplateUseTraits),\n    wbFormIDCk(PNAM, 'Body Part Data', [BPTD], False, cpNormal, True, wbActorTemplateUseModelAnimation),\n    wbFloat(TNAM, 'Turning Speed', cpNormal, True, 1, -1, wbActorTemplateUseStats),\n    wbFloat(BNAM, 'Base Scale', cpNormal, True, 1, -1, wbActorTemplateUseStats),\n    wbFloat(WNAM, 'Foot Weight', cpNormal, True, 1, -1, wbActorTemplateUseStats),\n    wbInteger(NAM4, 'Impact Material Type', itU32, wbImpactMaterialTypeEnum, cpNormal, True, False, wbActorTemplateUseModelAnimation),\n    wbInteger(NAM5, 'Sound Level', itU32, wbSoundLevelEnum, cpNormal, True, False, wbActorTemplateUseModelAnimation),\n    wbFormIDCk(CSCR, 'Inherits Sounds from', [CREA], False, cpNormal, False, wbActorTemplateUseModelAnimation),\n    wbCSDTs,\n    wbFormIDCk(CNAM, 'Impact Dataset', [IPDS], False, cpNormal, False, wbActorTemplateUseModelAnimation),\n    wbFormIDCk(LNAM, 'Melee Weapon List', [FLST], False, cpNormal, False, wbActorTemplateUseTraits)\n  ], True);\n\nend;\n\nprocedure DefineFNVd;\nbegin\n  wbRecord(CSTY, 'Combat Style', [\n    wbEDIDReq,\n    wbStruct(CSTD, 'Advanced - Standard', [\n      {000}wbInteger('Maneuver Decision - Dodge % Chance', itU8),\n      {001}wbInteger('Maneuver Decision - Left/Right % Chance', itU8),\n      {002}wbByteArray('Unused', 2),\n      {004}wbFloat('Maneuver Decision - Dodge L/R Timer (min)'),\n      {008}wbFloat('Maneuver Decision - Dodge L/R Timer (max)'),\n      {012}wbFloat('Maneuver Decision - Dodge Forward Timer (min)'),\n      {016}wbFloat('Maneuver Decision - Dodge Forward Timer (max)'),\n      {020}wbFloat('Maneuver Decision - Dodge Back Timer Min'),\n      {024}wbFloat('Maneuver Decision - Dodge Back Timer Max'),\n      {028}wbFloat('Maneuver Decision - Idle Timer min'),\n      {032}wbFloat('Maneuver Decision - Idle Timer max'),\n      {036}wbInteger('Melee Decision - Block % Chance', itU8),\n      {037}wbInteger('Melee Decision - Attack % Chance', itU8),\n      {038}wbByteArray('Unused', 2),\n      {040}wbFloat('Melee Decision - Recoil/Stagger Bonus to Attack'),\n      {044}wbFloat('Melee Decision - Unconscious Bonus to Attack'),\n      {048}wbFloat('Melee Decision - Hand-To-Hand Bonus to Attack'),\n      {052}wbInteger('Melee Decision - Power Attacks - Power Attack % Chance', itU8),\n      {053}wbByteArray('Unused', 3),\n      {056}wbFloat('Melee Decision - Power Attacks - Recoil/Stagger Bonus to Power'),\n      {060}wbFloat('Melee Decision - Power Attacks - Unconscious Bonus to Power Attack'),\n      {064}wbInteger('Melee Decision - Power Attacks - Normal', itU8),\n      {065}wbInteger('Melee Decision - Power Attacks - Forward', itU8),\n      {066}wbInteger('Melee Decision - Power Attacks - Back', itU8),\n      {067}wbInteger('Melee Decision - Power Attacks - Left', itU8),\n      {068}wbInteger('Melee Decision - Power Attacks - Right', itU8),\n      {069}wbByteArray('Unused', 3),\n      {072}wbFloat('Melee Decision - Hold Timer (min)'),\n      {076}wbFloat('Melee Decision - Hold Timer (max)'),\n      {080}wbInteger('Flags', itU16, wbFlags([\n             'Choose Attack using % Chance',\n             'Melee Alert OK',\n             'Flee Based on Personal Survival',\n             '',\n             'Ignore Threats',\n             'Ignore Damaging Self',\n             'Ignore Damaging Group',\n             'Ignore Damaging Spectators',\n             'Cannot Use Stealthboy'\n           ])),\n      {082}wbByteArray('Unused', 2),\n      {085}wbInteger('Maneuver Decision - Acrobatic Dodge % Chance', itU8),\n      {085}wbInteger('Melee Decision - Power Attacks - Rushing Attack % Chance', itU8),\n      {086}wbByteArray('Unused', 2),\n      {088}wbFloat('Melee Decision - Power Attacks - Rushing Attack Distance Mult')\n    ], cpNormal, True),\n    wbStruct(CSAD, 'Advanced - Advanced', [\n      wbFloat('Dodge Fatigue Mod Mult'),\n      wbFloat('Dodge Fatigue Mod Base'),\n      wbFloat('Encumb. Speed Mod Base'),\n      wbFloat('Encumb. Speed Mod Mult'),\n      wbFloat('Dodge While Under Attack Mult'),\n      wbFloat('Dodge Not Under Attack Mult'),\n      wbFloat('Dodge Back While Under Attack Mult'),\n      wbFloat('Dodge Back Not Under Attack Mult'),\n      wbFloat('Dodge Forward While Attacking Mult'),\n      wbFloat('Dodge Forward Not Attacking Mult'),\n      wbFloat('Block Skill Modifier Mult'),\n      wbFloat('Block Skill Modifier Base'),\n      wbFloat('Block While Under Attack Mult'),\n      wbFloat('Block Not Under Attack Mult'),\n      wbFloat('Attack Skill Modifier Mult'),\n      wbFloat('Attack Skill Modifier Base'),\n      wbFloat('Attack While Under Attack Mult'),\n      wbFloat('Attack Not Under Attack Mult'),\n      wbFloat('Attack During Block Mult'),\n      wbFloat('Power Att. Fatigue Mod Base'),\n      wbFloat('Power Att. Fatigue Mod Mult')\n    ], cpNormal, True),\n    wbStruct(CSSD, 'Simple', [\n      {00} wbFloat('Cover Search Radius'),\n      {04} wbFloat('Take Cover Chance'),\n      {08} wbFloat('Wait Timer (min)'),\n      {12} wbFloat('Wait Timer (max)'),\n      {16} wbFloat('Wait to Fire Timer (min)'),\n      {20} wbFloat('Wait to Fire Timer (max)'),\n      {24} wbFloat('Fire Timer (min)'),\n      {28} wbFloat('Fire Timer (max)'),\n      {32} wbFloat('Ranged Weapon Range Mult (min)'),\n      {36} wbByteArray('Unused', 4),\n      {40} wbInteger('Weapon Restrictions', itU32, wbEnum([\n        'None',\n        'Melee Only',\n        'Ranged Only'\n      ])),\n      {44} wbFloat('Ranged Weapon Range Mult (max)'),\n      {48} wbFloat('Max Targeting FOV'),\n      {52} wbFloat('Combat Radius'),\n      {56} wbFloat('Semi-Auto Firing Delay Mult (min)'),\n      {60} wbFloat('Semi-Auto Firing Delay Mult (max)')\n    ], cpNormal, True)\n  ]);\n\n  wbRecord(DIAL, 'Dialog Topic', [\n    wbEDIDReq,\n    wbRArrayS('Added Quests', wbRStructSK([0], 'Added Quest', [\n      wbFormIDCkNoReach(QSTI, 'Quest', [QUST], False, cpBenign),\n      wbRArray('Shared Infos', wbRStruct('Shared Info', [\n        wbFormIDCk(INFC, 'Info Connection', [INFO], False, cpBenign),\n        wbInteger(INFX, 'Info Index', itS32, nil, cpBenign)\n      ], []))\n    ], [])),\n    // no QSTR in FNV, but keep it just in case\n    wbRArrayS('Removed Quests', wbRStructSK([0], 'Removed Quest', [\n      wbFormIDCkNoReach(QSTR, 'Quest', [QUST], False, cpBenign)\n    ], [])),\n    // some records have INFC INFX (with absent formids) but no QSTI, probably error in GECK\n    // i.e. [DIAL:001287C6] and [DIAL:000E9084]\n    wbRArray('Unused', wbRStruct('Unused', [\n      wbUnknown(INFC, cpIgnore),\n      wbUnknown(INFX, cpIgnore)\n    ], []), cpIgnore, False, nil, nil, wbNeverShow),\n    wbFULL,\n    wbFloat(PNAM, 'Priority', cpNormal, True, 1, -1, nil, nil, 50.0),\n    wbString(TDUM, 'Dumb Response'),\n    wbStruct(DATA, '', [\n      wbInteger('Type', itU8, wbEnum([\n        {0} 'Topic',\n        {1} 'Conversation',\n        {2} 'Combat',\n        {3} 'Persuasion',\n        {4} 'Detection',\n        {5} 'Service',\n        {6} 'Miscellaneous',\n        {7} 'Radio'\n      ])),\n      wbInteger('Flags', itU8, wbFlags([\n        'Rumors',\n        'Top-level'\n      ]))\n    ], cpNormal, True, nil, 1)\n  ], True);\n\n  wbRecord(DOOR, 'Door', [\n    wbEDIDReq,\n    wbOBNDReq,\n    wbFULL,\n    wbMODLReq,\n    wbSCRI,\n    wbDEST,\n    wbFormIDCk(SNAM, 'Sound - Open', [SOUN]),\n    wbFormIDCk(ANAM, 'Sound - Close', [SOUN]),\n    wbFormIDCk(BNAM, 'Sound - Looping', [SOUN]),\n    wbInteger(FNAM, 'Flags', itU8, wbFlags([\n      '',\n      'Automatic Door',\n      'Hidden',\n      'Minimal Use',\n      'Sliding Door'\n    ]), cpNormal, True)\n  ]);\n\n  wbBlendModeEnum := wbEnum([\n    '',\n    'Zero',\n    'One',\n    'Source Color',\n    'Source Inverse Color',\n    'Source Alpha',\n    'Source Inverted Alpha',\n    'Dest Alpha',\n    'Dest Inverted Alpha',\n    'Dest Color',\n    'Dest Inverse Color',\n    'Source Alpha SAT'\n  ]);\n\n  wbBlendOpEnum := wbEnum([\n    '',\n    'Add',\n    'Subtract',\n    'Reverse Subtract',\n    'Minimum',\n    'Maximum'\n  ]);\n  wbZTestFuncEnum := wbEnum([\n    '',\n    '',\n    '',\n    'Equal To',\n    'Normal',\n    'Greater Than',\n    '',\n    'Greater Than or Equal Than',\n    'Always Show'\n  ]);\n\n  wbRecord(EFSH, 'Effect Shader', [\n    wbEDID,\n    wbString(ICON, 'Fill Texture'),\n    wbString(ICO2, 'Particle Shader Texture'),\n    wbString(NAM7, 'Holes Texture'),\n    wbStruct(DATA, '', [\n      wbInteger('Flags', itU8, wbFlags([\n        {0} 'No Membrane Shader',\n        {1} '',\n        {2} '',\n        {3} 'No Particle Shader',\n        {4} 'Edge Effect - Inverse',\n        {5} 'Membrane Shader - Affect Skin Only'\n      ])),\n      wbByteArray('Unused', 3),\n      wbInteger('Membrane Shader - Source Blend Mode', itU32, wbBlendModeEnum),\n      wbInteger('Membrane Shader - Blend Operation', itU32, wbBlendOpEnum),\n      wbInteger('Membrane Shader - Z Test Function', itU32, wbZTestFuncEnum),\n      wbStruct('Fill/Texture Effect - Color', [\n        wbInteger('Red', itU8),\n        wbInteger('Green', itU8),\n        wbInteger('Blue', itU8),\n        wbByteArray('Unused', 1)\n      ]),\n      wbFloat('Fill/Texture Effect - Alpha Fade In Time'),\n      wbFloat('Fill/Texture Effect - Full Alpha Time'),\n      wbFloat('Fill/Texture Effect - Alpha Fade Out Time'),\n      wbFloat('Fill/Texture Effect - Presistent Alpha Ratio'),\n      wbFloat('Fill/Texture Effect - Alpha Pulse Amplitude'),\n      wbFloat('Fill/Texture Effect - Alpha Pulse Frequency'),\n      wbFloat('Fill/Texture Effect - Texture Animation Speed (U)'),\n      wbFloat('Fill/Texture Effect - Texture Animation Speed (V)'),\n      wbFloat('Edge Effect - Fall Off'),\n      wbStruct('Edge Effect - Color', [\n        wbInteger('Red', itU8),\n        wbInteger('Green', itU8),\n        wbInteger('Blue', itU8),\n        wbByteArray('Unused', 1)\n      ]),\n      wbFloat('Edge Effect - Alpha Fade In Time'),\n      wbFloat('Edge Effect - Full Alpha Time'),\n      wbFloat('Edge Effect - Alpha Fade Out Time'),\n      wbFloat('Edge Effect - Persistent Alpha Ratio'),\n      wbFloat('Edge Effect - Alpha Pulse Amplitude'),\n      wbFloat('Edge Effect - Alpha Pusle Frequence'),\n      wbFloat('Fill/Texture Effect - Full Alpha Ratio'),\n      wbFloat('Edge Effect - Full Alpha Ratio'),\n      wbInteger('Membrane Shader - Dest Blend Mode', itU32, wbBlendModeEnum),\n      wbInteger('Particle Shader - Source Blend Mode', itU32, wbBlendModeEnum),\n      wbInteger('Particle Shader - Blend Operation', itU32, wbBlendOpEnum),\n      wbInteger('Particle Shader - Z Test Function', itU32, wbZTestFuncEnum),\n      wbInteger('Particle Shader - Dest Blend Mode', itU32, wbBlendModeEnum),\n      wbFloat('Particle Shader - Particle Birth Ramp Up Time'),\n      wbFloat('Particle Shader - Full Particle Birth Time'),\n      wbFloat('Particle Shader - Particle Birth Ramp Down Time'),\n      wbFloat('Particle Shader - Full Particle Birth Ratio'),\n      wbFloat('Particle Shader - Persistant Particle Birth Ratio'),\n      wbFloat('Particle Shader - Particle Lifetime'),\n      wbFloat('Particle Shader - Particle Lifetime +/-'),\n      wbFloat('Particle Shader - Initial Speed Along Normal'),\n      wbFloat('Particle Shader - Acceleration Along Normal'),\n      wbFloat('Particle Shader - Initial Velocity #1'),\n      wbFloat('Particle Shader - Initial Velocity #2'),\n      wbFloat('Particle Shader - Initial Velocity #3'),\n      wbFloat('Particle Shader - Acceleration #1'),\n      wbFloat('Particle Shader - Acceleration #2'),\n      wbFloat('Particle Shader - Acceleration #3'),\n      wbFloat('Particle Shader - Scale Key 1'),\n      wbFloat('Particle Shader - Scale Key 2'),\n      wbFloat('Particle Shader - Scale Key 1 Time'),\n      wbFloat('Particle Shader - Scale Key 2 Time'),\n      wbStruct('Color Key 1 - Color', [\n        wbInteger('Red', itU8),\n        wbInteger('Green', itU8),\n        wbInteger('Blue', itU8),\n        wbByteArray('Unused', 1)\n      ]),\n      wbStruct('Color Key 2 - Color', [\n        wbInteger('Red', itU8),\n        wbInteger('Green', itU8),\n        wbInteger('Blue', itU8),\n        wbByteArray('Unused', 1)\n      ]),\n      wbStruct('Color Key 3 - Color', [\n        wbInteger('Red', itU8),\n        wbInteger('Green', itU8),\n        wbInteger('Blue', itU8),\n        wbByteArray('Unused', 1)\n      ]),\n      wbFloat('Color Key 1 - Color Alpha'),\n      wbFloat('Color Key 2 - Color Alpha'),\n      wbFloat('Color Key 3 - Color Alpha'),\n      wbFloat('Color Key 1 - Color Key Time'),\n      wbFloat('Color Key 2 - Color Key Time'),\n      wbFloat('Color Key 3 - Color Key Time'),\n      wbFloat('Particle Shader - Initial Speed Along Normal +/-'),\n      wbFloat('Particle Shader - Initial Rotation (deg)'),\n      wbFloat('Particle Shader - Initial Rotation (deg) +/-'),\n      wbFloat('Particle Shader - Rotation Speed (deg/sec)'),\n      wbFloat('Particle Shader - Rotation Speed (deg/sec) +/-'),\n      wbFormIDCk('Addon Models', [DEBR, NULL]),\n      wbFloat('Holes - Start Time'),\n      wbFloat('Holes - End Time'),\n      wbFloat('Holes - Start Val'),\n      wbFloat('Holes - End Val'),\n      wbFloat('Edge Width (alpha units)'),\n      wbStruct('Edge Color', [\n        wbInteger('Red', itU8),\n        wbInteger('Green', itU8),\n        wbInteger('Blue', itU8),\n        wbByteArray('Unused', 1)\n      ]),\n      wbFloat('Explosion Wind Speed'),\n      wbInteger('Texture Count U', itU32),\n      wbInteger('Texture Count V', itU32),\n      wbFloat('Addon Models - Fade In Time'),\n      wbFloat('Addon Models - Fade Out Time'),\n      wbFloat('Addon Models - Scale Start'),\n      wbFloat('Addon Models - Scale End'),\n      wbFloat('Addon Models - Scale In Time'),\n      wbFloat('Addon Models - Scale Out Time')\n    ], cpNormal, True, nil, 57)\n  ], False, nil, cpNormal, False, wbEFSHAfterLoad);\n\n  wbRecord(ENCH, 'Object Effect', [\n    wbEDIDReq,\n    wbFULL,\n    wbStruct(ENIT, 'Effect Data', [\n      wbInteger('Type', itU32, wbEnum([\n        {0} '',\n        {1} '',\n        {2} 'Weapon',\n        {3} 'Apparel'\n      ])),\n      wbByteArray('Unused', 4),\n      wbByteArray('Unused', 4),\n      wbInteger('Flags', itU8, wbFlags([\n        'No Auto-Calc',\n        'Auto Calculate',\n        'Hide Effect'\n      ])),\n      wbByteArray('Unused', 3)\n    ], cpNormal, True),\n    wbEffectsReq\n  ]);\n\n  wbRecord(EYES, 'Eyes', [\n    wbEDIDReq,\n    wbFULLReq,\n    wbString(ICON, 'Texture', 0{, cpNormal, True??}),\n    wbInteger(DATA, 'Flags', itU8, wbFlags([\n      'Playable',\n      'Not Male',\n      'Not Female'\n    ]), cpNormal, True)\n  ]);\n\n  wbXNAM :=\n    wbStructSK(XNAM, [0], 'Relation', [\n      wbFormIDCkNoReach('Faction', [FACT, RACE]),\n      wbInteger('Modifier', itS32),\n      wbInteger('Group Combat Reaction', itU32, wbEnum([\n        'Neutral',\n        'Enemy',\n        'Ally',\n        'Friend'\n      ]))\n    ]);\n\n  wbXNAMs := wbRArrayS('Relations', wbXNAM);\n\n  wbRecord(FACT, 'Faction', [\n    wbEDIDReq,\n    wbFULL,\n    wbXNAMs,\n    wbStruct(DATA, '', [\n      wbInteger('Flags 1', itU8, wbFlags([\n        'Hidden from PC',\n        'Evil',\n        'Special Combat'\n      ])),\n      wbInteger('Flags 2', itU8, wbFlags([\n        'Track Crime',\n        'Allow Sell'\n      ])),\n      wbByteArray('Unused', 2)\n    ], cpNormal, True, nil, 1),\n    wbFloat(CNAM, 'Unused'),\n    wbRStructsSK('Ranks', 'Rank', [0], [\n      wbInteger(RNAM, 'Rank#', itS32),\n      wbString(MNAM, 'Male', 0, cpTranslate),\n      wbString(FNAM, 'Female', 0, cpTranslate),\n      wbString(INAM, 'Insignia (Unused)')\n    ], []),\n    wbFormIDCk(WMI1, 'Reputation', [REPU])\n  ], False, nil, cpNormal, False, wbFACTAfterLoad);\n\n  wbRecord(FURN, 'Furniture', [\n    wbEDIDReq,\n    wbOBNDReq,\n    wbFULL,\n    wbMODLReq,\n    wbSCRI,\n    wbDEST,\n    wbByteArray(MNAM, 'Marker Flags', 0, cpNormal, True)\n  ]);\n\n  wbRecord(GLOB, 'Global', [\n    wbEDIDReq,\n    wbInteger(FNAM, 'Type', itU8, wbGLOBFNAM, nil, cpNormal, True),\n    wbFloat(FLTV, 'Value', cpNormal, True)\n  ]);\n\n\n  wbRecord(GMST, 'Game Setting', [\n    wbString(EDID, 'Editor ID', 0, cpCritical, True, nil, wbGMSTEDIDAfterSet),\n    wbUnion(DATA, 'Value', wbGMSTUnionDecider, [\n      wbString('', 0, cpTranslate),\n      wbInteger('', itS32),\n      wbFloat('')\n    ], cpNormal, True)\n  ]);\n\n  wbDODT := wbStruct(DODT, 'Decal Data', [\n              wbFloat('Min Width'),\n              wbFloat('Max Width'),\n              wbFloat('Min Height'),\n              wbFloat('Max Height'),\n              wbFloat('Depth'),\n              wbFloat('Shininess'),\n              wbStruct('Parallax', [\n                wbFloat('Scale'),\n                wbInteger('Passes', itU8)\n              ]),\n              wbInteger('Flags', itU8, wbFlags([\n                'Parallax',\n                'Alpha - Blending',\n                'Alpha - Testing'\n              ], True)),\n              wbByteArray('Unused', 2),\n              wbStruct('Color', [\n                wbInteger('Red', itU8),\n                wbInteger('Green', itU8),\n                wbInteger('Blue', itU8),\n                wbByteArray('Unused', 1)\n              ])\n            ]);\n\n  wbRecord(TXST, 'Texture Set', [\n    wbEDIDReq,\n    wbOBNDReq,\n    wbRStruct('Textures (RGB/A)', [\n      wbString(TX00,'Base Image / Transparency'),\n      wbString(TX01,'Normal Map / Specular'),\n      wbString(TX02,'Environment Map Mask / ?'),\n      wbString(TX03,'Glow Map / Unused'),\n      wbString(TX04,'Parallax Map / Unused'),\n      wbString(TX05,'Environment Map / Unused')\n    ], []),\n    wbDODT,\n    wbInteger(DNAM, 'Flags', itU16, wbFlags([\n      'No Specular Map'\n    ]), cpNormal, True)\n  ]);\n\n  wbRecord(MICN, 'Menu Icon', [\n    wbEDIDReq,\n    wbICONReq\n  ]);\n\n  wbRecord(HDPT, 'Head Part', [\n    wbEDIDReq,\n    wbFULLReq,\n    wbMODL,\n    wbInteger(DATA, 'Flags', itU8, wbFlags([\n      'Playable'\n    ]), cpNormal, True),\n    wbRArrayS('Extra Parts',\n      wbFormIDCk(HNAM, 'Part', [HDPT])\n    )\n  ]);\n\n  wbRecord(ASPC, 'Acoustic Space', [\n    wbEDIDReq,\n    wbOBNDReq,\n\n    wbFormIDCk(SNAM, 'Dawn / Default Loop', [NULL, SOUN], False, cpNormal, True),\n    wbFormIDCk(SNAM, 'Afternoon', [NULL, SOUN], False, cpNormal, True),\n    wbFormIDCk(SNAM, 'Dusk', [NULL, SOUN], False, cpNormal, True),\n    wbFormIDCk(SNAM, 'Night', [NULL, SOUN], False, cpNormal, True),\n    wbFormIDCk(SNAM, 'Walla', [NULL, SOUN], False, cpNormal, True),\n\n    wbInteger(WNAM, 'Walla Trigger Count', itU32, nil, cpNormal, True),\n    wbFormIDCk(RDAT, 'Use Sound from Region (Interiors Only)', [REGN]),\n    wbInteger(ANAM, 'Environment Type', itU32, wbEnum([\n      'None',\n      'Default',\n      'Generic',\n      'Padded Cell',\n      'Room',\n      'Bathroom',\n      'Livingroom',\n      'Stone Room',\n      'Auditorium',\n      'Concerthall',\n      'Cave',\n      'Arena',\n      'Hangar',\n      'Carpeted Hallway',\n      'Hallway',\n      'Stone Corridor',\n      'Alley',\n      'Forest',\n      'City',\n      'Mountains',\n      'Quarry',\n      'Plain',\n      'Parkinglot',\n      'Sewerpipe',\n      'Underwater',\n      'Small Room',\n      'Medium Room',\n      'Large Room',\n      'Medium Hall',\n      'Large Hall',\n      'Plate'\n    ]), cpNormal, True),\n    wbInteger(INAM, 'Is Interior', itU32, wbEnum(['No', 'Yes']), cpNormal, True)\n  ]);\n\n  wbRecord(TACT, 'Talking Activator', [\n    wbEDIDReq,\n    wbOBNDReq,\n    wbFULL,\n    wbMODLReq,\n    wbSCRI,\n    wbDEST,\n    wbFormIDCk(SNAM, 'Looping Sound', [SOUN]),\n    wbFormIDCk(VNAM, 'Voice Type', [VTYP]),\n    wbFormIDCk(INAM, 'Radio Template', [SOUN])\n  ]);\n\n  wbRecord(SCPT, 'Script', [\n    wbEDIDReq,\n    wbSCHRReq,\n    wbByteArray(SCDA, 'Compiled Script'),\n    wbStringScript(SCTX, 'Script Source', 0, cpNormal{, True}),\n    wbRArrayS('Local Variables', wbRStructSK([0], 'Local Variable', [\n      wbSLSD,\n      wbString(SCVR, 'Name', 0, cpCritical, True)\n    ], [])),\n    wbSCROs\n  ]);\n\n  wbRecord(TERM, 'Terminal', [\n    wbEDIDReq,\n    wbOBNDReq,\n    wbFULL,\n    wbMODL,\n    wbSCRI,\n    wbDEST,\n    wbDESCReq,\n    wbFormIDCk(SNAM, 'Sound - Looping', [SOUN]),\n    wbFormIDCk(PNAM, 'Password Note', [NOTE]),\n    wbStruct(DNAM, '', [\n      wbInteger('Base Hacking Difficulty', itU8, wbEnum([\n        'Very Easy',\n        'Easy',\n        'Average',\n        'Hard',\n        'Very Hard',\n        'Requires Key'\n      ])),\n      wbInteger('Flags', itU8, wbFlags([\n        'Leveled',\n        'Unlocked',\n        'Alternate Colors',\n        'Hide Welcome Text when displaying Image'\n      ])),\n      wbInteger('ServerType', itU8, wbEnum([\n        '-Server 1-',\n        '-Server 2-',\n        '-Server 3-',\n        '-Server 4-',\n        '-Server 5-',\n        '-Server 6-',\n        '-Server 7-',\n        '-Server 8-',\n        '-Server 9-',\n        '-Server 10-'\n      ])),\n      wbByteArray('Unused', 1)\n    ], cpNormal, True),\n    wbRArray('Menu Items',\n      wbRStruct('Menu Item', [\n        wbString(ITXT, 'Item Text'),\n        wbString(RNAM, 'Result Text', 0, cpNormal, True),\n        wbInteger(ANAM, 'Flags', itU8, wbFlags([\n          'Add Note',\n          'Force Redraw'\n        ]), cpNormal, True),\n        wbFormIDCk(INAM, 'Display Note', [NOTE]),\n        wbFormIDCk(TNAM, 'Sub Menu', [TERM]),\n        wbEmbeddedScriptReq,\n        wbCTDAs\n      ], [])\n    )\n  ]);\n\n  wbRecord(SCOL, 'Static Collection', [\n    wbEDIDReq,\n    wbOBNDReq,\n    wbMODLReq,\n    wbRStructsSK('Parts', 'Part', [0], [\n      wbFormIDCk(ONAM, 'Static', [STAT]),\n      wbArrayS(DATA, 'Placements', wbStruct('Placement', [\n        wbStruct('Position', [\n          wbFloat('X'),\n          wbFloat('Y'),\n          wbFloat('Z')\n        ]),\n        wbStruct('Rotation', [\n          wbFloat('X', cpNormal, True, wbRotationFactor, wbRotationScale, nil, RadiansNormalize),\n          wbFloat('Y', cpNormal, True, wbRotationFactor, wbRotationScale, nil, RadiansNormalize),\n          wbFloat('Z', cpNormal, True, wbRotationFactor, wbRotationScale, nil, RadiansNormalize)\n        ]),\n        wbFloat('Scale')\n      ]), 0, cpNormal, True)\n    ], [], cpNormal, True)\n  ]);\n\n  wbRecord(MSTT, 'Moveable Static', [\n    wbEDIDReq,\n    wbOBNDReq,\n    wbFULL,\n    wbMODLReq,\n    wbDEST,\n    wbByteArray(DATA, 'Unknown', 1, cpNormal, True),\n    wbFormIDCk(SNAM, 'Sound', [SOUN])\n  ]);\n\n  wbRecord(PWAT, 'Placeable Water', [\n    wbEDIDReq,\n    wbOBNDReq,\n    wbMODLReq,\n    wbStruct(DNAM, '', [\n      wbInteger('Flags', itU32, wbFlags([\n        {0x00000001}'Reflects',\n        {0x00000002}'Reflects - Actors',\n        {0x00000004}'Reflects - Land',\n        {0x00000008}'Reflects - LOD Land',\n        {0x00000010}'Reflects - LOD Buildings',\n        {0x00000020}'Reflects - Trees',\n        {0x00000040}'Reflects - Sky',\n        {0x00000080}'Reflects - Dynamic Objects',\n        {0x00000100}'Reflects - Dead Bodies',\n        {0x00000200}'Refracts',\n        {0x00000400}'Refracts - Actors',\n        {0x00000800}'Refracts - Land',\n        {0x00001000}'',\n        {0x00002000}'',\n        {0x00004000}'',\n        {0x00008000}'',\n        {0x00010000}'Refracts - Dynamic Objects',\n        {0x00020000}'Refracts - Dead Bodies',\n        {0x00040000}'Silhouette Reflections',\n        {0x00080000}'',\n        {0x00100000}'',\n        {0x00200000}'',\n        {0x00400000}'',\n        {0x00800000}'',\n        {0x01000000}'',\n        {0x02000000}'',\n        {0x03000000}'',\n        {0x08000000}'',\n        {0x10000000}'Depth',\n        {0x20000000}'Object Texture Coordinates',\n        {0x40000000}'',\n        {0x80000000}'No Underwater Fog'\n      ])),\n      wbFormIDCk('Water', [WATR])\n    ], cpNormal, True)\n  ]);\n\n  wbRecord(IDLM, 'Idle Marker', [\n    wbEDIDReq,\n    wbOBNDReq,\n    wbInteger(IDLF, 'Flags', itU8, wbFlags([\n      'Run in Sequence',\n      '',\n      'Do Once'\n    ]), cpNormal, True),\n    wbStruct(IDLC, '', [\n      wbInteger('Animation Count', itU8),\n      wbByteArray('Unused', 3)\n    ], cpNormal, True, nil, 1),\n    wbFloat(IDLT, 'Idle Timer Setting', cpNormal, True),\n    wbArray(IDLA, 'Animations', wbFormIDCk('Animation', [IDLE, NULL]), 0, nil, wbIDLAsAfterSet, cpNormal, True)  // NULL looks valid if IDLS\\Animation Count is 0\n  ], False, nil, cpNormal, False, nil, wbAnimationsAfterSet);\n\n  wbRecord(NOTE, 'Note', [\n    wbEDIDReq,\n    wbOBNDReq,\n    wbFULL,\n    wbMODL,\n    wbICON,\n    wbYNAM,\n    wbZNAM,\n    wbInteger(DATA, 'Type', itU8, wbEnum([\n      'Sound',\n      'Text',\n      'Image',\n      'Voice'\n    ]), cpNormal, True),\n    wbRArrayS('Quests',\n      wbFormIDCkNoReach(ONAM, 'Quest', [QUST])\n    ),\n    wbString(XNAM, 'Texture'),\n    wbUnion(TNAM, 'Text / Topic', wbNOTETNAMDecide, [\n      wbString('Text'),\n      wbFormIDCk('Topic', [DIAL])\n    ]),\n    wbUnion(SNAM, 'Sound / NPC', wbNOTESNAMDecide, [\n      wbFormIDCk('Sound', [SOUN]),\n      wbFormIDCk('Actor', [NPC_, CREA])\n    ])\n  ]);\n\nend;\n\nprocedure DefineFNVe;\nbegin\n  wbRecord(PROJ, 'Projectile', [\n    wbEDIDReq,\n    wbOBNDReq,\n    wbFULL,\n    wbMODLReq,\n    wbDEST,\n    wbStruct(DATA, 'Data', [\n      {00} wbInteger('Flags', itU16, wbFlags([\n        'Hitscan',\n        'Explosion',\n        'Alt. Trigger',\n        'Muzzle Flash',\n        '',\n        'Can Be Disabled',\n        'Can Be Picked Up',\n        'Supersonic',\n        'Pins Limbs',\n        'Pass Through Small Transparent',\n        'Detonates',\n        'Rotation'\n      ])),\n      {02} wbInteger('Type', itU16, wbEnum([\n        {00} '',\n        {01} 'Missile',\n        {02} 'Lobber',\n        {03} '',\n        {04} 'Beam',\n        {05} '',\n        {06} '',\n        {07} '',\n        {08} 'Flame',\n        {09} '',\n        {10} '',\n        {11} '',\n        {12} '',\n        {13} '',\n        {14} '',\n        {15} '',\n        {16} 'Continuous Beam'\n      ])),\n      {04} wbFloat('Gravity'),\n      {08} wbFloat('Speed'),\n      {12} wbFloat('Range'),\n      {16} wbFormIDCk('Light', [LIGH, NULL]),\n      {20} wbFormIDCk('Muzzle Flash - Light', [LIGH, NULL]),\n      {24} wbFloat('Tracer Chance'),\n      {28} wbFloat('Explosion - Alt. Trigger - Proximity'),\n      {32} wbFloat('Explosion - Alt. Trigger - Timer'),\n      {36} wbFormIDCk('Explosion', [EXPL, NULL]),\n      {40} wbFormIDCk('Sound', [SOUN, NULL]),\n      {44} wbFloat('Muzzle Flash - Duration'),\n      {48} wbFloat('Fade Duration'),\n      {52} wbFloat('Impact Force'),\n      {56} wbFormIDCk('Sound - Countdown', [SOUN, NULL]),\n      {60} wbFormIDCk('Sound - Disable', [SOUN, NULL]),\n      {64} wbFormIDCk('Default Weapon Source', [WEAP, NULL]),\n      {68} wbStruct('Rotation', [\n      {68}   wbFloat('X'),\n      {72}   wbFloat('Y'),\n      {76}   wbFloat('Z')\n           ]),\n      {80} wbFloat('Bouncy Mult')\n    ], cpNormal, True),\n    wbRStructSK([0], 'Muzzle Flash Model', [\n      wbString(NAM1, 'Model Filename'),\n      wbByteArray(NAM2, 'Texture Files Hashes', 0, cpIgnore)\n    ], [], cpNormal, True),\n    wbInteger(VNAM, 'Sound Level', itU32, wbSoundLevelEnum, cpNormal, True)\n  ]);\n\n  wbRecord(NAVI, 'Navigation Mesh Info Map', [\n    wbEDID,\n    wbInteger(NVER, 'Version', itU32),\n    wbRArray('Navigation Map Infos',\n      wbStruct(NVMI, 'Navigation Map Info', [\n        wbByteArray('Unknown', 4),\n        wbFormIDCk('Navigation Mesh', [NAVM]),\n        wbFormIDCk('Location', [CELL, WRLD]),\n        wbStruct('Grid', [\n          wbInteger('X', itS16),\n          wbInteger('Y', itS16)\n        ]),\n        wbUnknown\n{        wbUnion('Data', wbNAVINVMIDecider, [\n          wbStruct('Data', [\n            wbUnknown\n          ]),\n          wbStruct('Data', [\n            wbArray('Unknown', wbFloat('Unknown'), 3),\n            wbByteArray('Unknown', 4)\n          ]),\n          wbStruct('Data', [\n            wbArray('Unknown', wbArray('Unknown', wbFloat('Unknown'), 3), 3),\n            wbInteger('Count 1', itU16),\n            wbInteger('Count 2', itU16),\n            wbArray('Unknown', wbArray('Unknown', wbFloat('Unknown'), 3), [], wbNAVINAVMGetCount1),\n            wbUnknown\n          ]),\n          wbStruct('Data', [\n            wbUnknown\n          ])\n        ])}\n      ])\n    ),\n    wbRArray('Unknown',\n      wbStruct(NVCI, 'Unknown', [\n        wbFormIDCk('Unknown', [NAVM]),\n        wbArray('Unknown', wbFormIDCk('Unknown', [NAVM]), -1),\n        wbArray('Unknown', wbFormIDCk('Unknown', [NAVM]), -1),\n        wbArray('Doors', wbFormIDCk('Door', [REFR]), -1)\n      ])\n    )\n  ]);\n\n  if wbSimpleRecords then begin\n\n    wbRecord(NAVM, 'Navigation Mesh', [\n      wbEDID,\n      wbInteger(NVER, 'Version', itU32),\n      wbStruct(DATA, '', [\n        wbFormIDCk('Cell', [CELL]),\n        wbInteger('Vertex Count', itU32),\n        wbInteger('Triangle Count', itU32),\n        wbInteger('External Connections Count', itU32),\n        wbInteger('NVCA Count', itU32),\n        wbInteger('Doors Count', itU32)\n      ]),\n      wbByteArray(NVVX, 'Vertices'),\n      wbByteArray(NVTR, 'Triangles'),\n      wbByteArray(NVCA, 'Unknown'),\n      wbArray(NVDP, 'Doors', wbStruct('Door', [\n        wbFormIDCk('Reference', [REFR]),\n        wbInteger('Triangle', itU16),\n        wbByteArray('Unused', 2)\n      ])),\n      wbByteArray(NVGD, 'Unknown'),\n      wbArray(NVEX, 'External Connections', wbStruct('Connection', [\n        wbByteArray('Unknown', 4),\n        wbFormIDCk('Navigation Mesh', [NAVM], False, cpNormal),\n        wbInteger('Triangle', itU16, nil, cpNormal)\n      ]))\n    ], False, wbNAVMAddInfo);\n\n  end else begin\n\n    wbRecord(NAVM, 'Navigation Mesh', [\n      wbEDID,\n      wbInteger(NVER, 'Version', itU32),\n      wbStruct(DATA, '', [\n        wbFormIDCk('Cell', [CELL]),\n        wbInteger('Vertex Count', itU32),\n        wbInteger('Triangle Count', itU32),\n        wbInteger('External Connections Count', itU32),\n        wbInteger('NVCA Count', itU32),\n        wbInteger('Doors Count', itU32) // as of version = 5 (earliest NavMesh version I saw (Fallout3 1.7) is already 11)\n      ]),\n      wbArray(NVVX, 'Vertices', wbStruct('Vertex', [\n        wbFloat('X'),\n        wbFloat('Y'),\n        wbFloat('Z')\n      ])),\n      wbArray(NVTR, 'Triangles', wbStruct('Triangle', [\n        wbArray('Vertices', wbInteger('Vertex', itS16), 3),\n        wbArray('Edges', wbInteger('Triangle', itS16, wbNVTREdgeToStr, wbNVTREdgeToInt), [\n          '0 <-> 1',\n          '1 <-> 2',\n          '2 <-> 0'\n        ]),\n        wbInteger('Flags', itU32, wbFlags([\n          'Triangle #0 Is External',\n          'Triangle #1 Is External',\n          'Triangle #2 Is External',\n          'Unknown 4',\n          'Unknown 5',\n          'Unknown 6',\n          'Preferred pathing',\n          'Unknown 8',\n          'Unknown 9',\n          'Water',\n          'Contains door',\n          'Unknown 12',\n          'Unknown 13', // Cleared on LoadForm\n          'Unknown 14', // Cleared on LoadForm\n          'Unknown 15', // Cleared on LoadForm\n          'Unknown 16',\n          'Unknown 17',\n          'Unknown 18',\n          'Unknown 19',\n          'Unknown 20',\n          'Unknown 21',\n          'Unknown 22',\n          'Unknown 23',\n          'Unknown 24',\n          'Unknown 25',\n          'Unknown 26',\n          'Unknown 27',\n          'Unknown 28',\n          'Unknown 29',\n          'Unknown 30',\n          'Unknown 31',\n          'Unknown 32'\n        ]))\n      ])),\n      wbArray(NVCA, 'Unknown', wbInteger('Triangle', itS16)),  // Assumed triangle as the value fits the triangle id's\n      wbArray(NVDP, 'Doors', wbStruct('Door', [\n        wbFormIDCk('Reference', [REFR]),\n        wbInteger('Triangle', itU16),\n        wbByteArray('Unused', 2)\n      ])),\n      wbStruct(NVGD, 'NavMesh Grid', [\n        wbInteger('NavMeshGrid Divisor', itU32),\n        wbFloat('Max X Distance'),                // Floats named after TES5 definition\n        wbFloat('Max Y Distance'),\n        wbFloat('Min X'),\n        wbFloat('Min Y'),\n        wbFloat('Min Z'),\n        wbFloat('Max X'),\n        wbFloat('Max Y'),\n        wbFloat('Max Z'),\n        wbArray('Cells', wbArray('Cell', wbInteger('Triangle', itS16), -2)) // Divisor is row count , assumed triangle as the values fit the triangle id's\n      ]),\n      wbArray(NVEX, 'External Connections', wbStruct('Connection', [\n        wbByteArray('Unknown', 4),  // absent in ver<9, not endian swap in ver>=9, so char or byte array\n        wbFormIDCk('Navigation Mesh', [NAVM, NULL], False, cpNormal),  // NULL values are ignored silently.\n        wbInteger('Triangle', itU16, nil, cpNormal)\n      ]))  // Different if ver<5: Length = $2E/$30 and contains other data between NavMesh and Triangle\n    ], False, wbNAVMAddInfo);\n\n  end;\n\n  wbRecord(PGRE, 'Placed Grenade', [\n    wbEDID,\n    wbFormIDCk(NAME, 'Base', [PROJ], False, cpNormal, True),\n    wbFormIDCk(XEZN, 'Encounter Zone', [ECZN]),\n\n    wbXRGD,\n    wbXRGB,\n\n    {--- Patrol Data ---}\n    wbRStruct('Patrol Data', [\n      wbFloat(XPRD, 'Idle Time', cpNormal, True),\n      wbEmpty(XPPA, 'Patrol Script Marker', cpNormal, True),\n      wbFormIDCk(INAM, 'Idle', [IDLE, NULL], False, cpNormal, True),\n      wbEmbeddedScriptReq,\n      wbFormIDCk(TNAM, 'Topic', [DIAL, NULL], False, cpNormal, True)\n    ], []),\n\n    {--- Ownership ---}\n    wbRStruct('Ownership', [\n      wbXOWN,\n      wbInteger(XRNK, 'Faction rank', itS32)\n    ], [XCMT, XCMO]),\n\n    {--- Extra ---}\n    wbInteger(XCNT, 'Count', itS32),\n    wbFloat(XRDS, 'Radius'),\n    wbFloat(XHLP, 'Health'),\n\n    {--- Reflected By / Refracted By ---}\n    wbRArrayS('Reflected/Refracted By',\n      wbStructSK(XPWR, [0], 'Water', [\n        wbFormIDCk('Reference', [REFR]),\n        wbInteger('Type', itU32, wbFlags([\n          'Reflection',\n          'Refraction'\n        ]))\n      ])\n    ),\n\n    {--- Decals ---}\n    wbRArrayS('Linked Decals',\n      wbStructSK(XDCR, [0], 'Decal', [\n        wbFormIDCk('Reference', [REFR]),\n        wbUnknown\n      ])\n    ),\n\n    {--- Linked Ref ---}\n    wbFormIDCk(XLKR, 'Linked Reference', [REFR, ACRE, ACHR, PGRE, PMIS, PBEA, PLYR]),\n    wbStruct(XCLP, 'Linked Reference Color', [\n      wbStruct('Link Start Color', [\n        wbInteger('Red', itU8),\n        wbInteger('Green', itU8),\n        wbInteger('Blue', itU8),\n        wbByteArray('Unused', 1)\n      ]),\n      wbStruct('Link End Color', [\n        wbInteger('Red', itU8),\n        wbInteger('Green', itU8),\n        wbInteger('Blue', itU8),\n        wbByteArray('Unused', 1)\n      ])\n    ]),\n\n    {--- Activate Parents ---}\n    wbRStruct('Activate Parents', [\n      wbInteger(XAPD, 'Flags', itU8, wbFlags([\n        'Parent Activate Only'\n      ], True)),\n      wbRArrayS('Activate Parent Refs',\n        wbStructSK(XAPR, [0], 'Activate Parent Ref', [\n          wbFormIDCk('Reference', [REFR, ACRE, ACHR, PGRE, PMIS, PBEA, PLYR]),\n          wbFloat('Delay')\n        ])\n      )\n    ], []),\n\n    wbString(XATO, 'Activation Prompt'),\n\n    {--- Enable Parent ---}\n    wbXESP,\n\n    {--- Emittance ---}\n    wbFormIDCk(XEMI, 'Emittance', [LIGH, REGN]),\n\n    {--- MultiBound ---}\n    wbFormIDCk(XMBR, 'MultiBound Reference', [REFR]),\n\n    {--- Flags ---}\n    wbEmpty(XIBS, 'Ignored By Sandbox'),\n\n    {--- 3D Data ---}\n    wbXSCL,\n    wbDATAPosRot\n  ], True, wbPlacedAddInfo);\n\n  wbRecord(PMIS, 'Placed Missile', [\n    wbEDID,\n    wbFormIDCk(NAME, 'Base', [PROJ], False, cpNormal, True),\n    wbFormIDCk(XEZN, 'Encounter Zone', [ECZN]),\n\n    wbXRGD,\n    wbXRGB,\n\n    {--- Patrol Data ---}\n    wbRStruct('Patrol Data', [\n      wbFloat(XPRD, 'Idle Time', cpNormal, True),\n      wbEmpty(XPPA, 'Patrol Script Marker', cpNormal, True),\n      wbFormIDCk(INAM, 'Idle', [IDLE, NULL], False, cpNormal, True),\n      wbEmbeddedScriptReq,\n      wbFormIDCk(TNAM, 'Topic', [DIAL, NULL], False, cpNormal, True)\n    ], []),\n\n    {--- Ownership ---}\n    wbRStruct('Ownership', [\n      wbXOWN,\n      wbInteger(XRNK, 'Faction rank', itS32)\n    ], [XCMT, XCMO]),\n\n    {--- Extra ---}\n    wbInteger(XCNT, 'Count', itS32),\n    wbFloat(XRDS, 'Radius'),\n    wbFloat(XHLP, 'Health'),\n\n    {--- Reflected By / Refracted By ---}\n    wbRArrayS('Reflected/Refracted By',\n      wbStructSK(XPWR, [0], 'Water', [\n        wbFormIDCk('Reference', [REFR]),\n        wbInteger('Type', itU32, wbFlags([\n          'Reflection',\n          'Refraction'\n        ]))\n      ])\n    ),\n\n    {--- Decals ---}\n    wbRArrayS('Linked Decals',\n      wbStructSK(XDCR, [0], 'Decal', [\n        wbFormIDCk('Reference', [REFR]),\n        wbUnknown\n      ])\n    ),\n\n    {--- Linked Ref ---}\n    wbFormIDCk(XLKR, 'Linked Reference', [REFR, ACRE, ACHR, PGRE, PMIS, PBEA, PLYR]),\n    wbStruct(XCLP, 'Linked Reference Color', [\n      wbStruct('Link Start Color', [\n        wbInteger('Red', itU8),\n        wbInteger('Green', itU8),\n        wbInteger('Blue', itU8),\n        wbByteArray('Unused', 1)\n      ]),\n      wbStruct('Link End Color', [\n        wbInteger('Red', itU8),\n        wbInteger('Green', itU8),\n        wbInteger('Blue', itU8),\n        wbByteArray('Unused', 1)\n      ])\n    ]),\n\n    {--- Activate Parents ---}\n    wbRStruct('Activate Parents', [\n      wbInteger(XAPD, 'Flags', itU8, wbFlags([\n        'Parent Activate Only'\n      ], True)),\n      wbRArrayS('Activate Parent Refs',\n        wbStructSK(XAPR, [0], 'Activate Parent Ref', [\n          wbFormIDCk('Reference', [REFR, ACRE, ACHR, PGRE, PMIS, PBEA, PLYR]),\n          wbFloat('Delay')\n        ])\n      )\n    ], []),\n\n    wbString(XATO, 'Activation Prompt'),\n\n    {--- Enable Parent ---}\n    wbXESP,\n\n    {--- Emittance ---}\n    wbFormIDCk(XEMI, 'Emittance', [LIGH, REGN]),\n\n    {--- MultiBound ---}\n    wbFormIDCk(XMBR, 'MultiBound Reference', [REFR]),\n\n    {--- Flags ---}\n    wbEmpty(XIBS, 'Ignored By Sandbox'),\n\n    {--- 3D Data ---}\n    wbXSCL,\n    wbDATAPosRot\n  ], True, wbPlacedAddInfo);\n\n  wbRecord(PBEA, 'Placed Beam', [\n    wbEDID,\n    wbFormIDCk(NAME, 'Base', [PROJ], False, cpNormal, True),\n    wbFormIDCk(XEZN, 'Encounter Zone', [ECZN]),\n\n    wbXRGD,\n    wbXRGB,\n\n    {--- Patrol Data ---}\n    wbRStruct('Patrol Data', [\n      wbFloat(XPRD, 'Idle Time', cpNormal, True),\n      wbEmpty(XPPA, 'Patrol Script Marker', cpNormal, True),\n      wbFormIDCk(INAM, 'Idle', [IDLE, NULL], False, cpNormal, True),\n      wbEmbeddedScriptReq,\n      wbFormIDCk(TNAM, 'Topic', [DIAL, NULL], False, cpNormal, True)\n    ], []),\n\n    {--- Ownership ---}\n    wbRStruct('Ownership', [\n      wbXOWN,\n      wbInteger(XRNK, 'Faction rank', itS32)\n    ], [XCMT, XCMO]),\n\n    {--- Extra ---}\n    wbInteger(XCNT, 'Count', itS32),\n    wbFloat(XRDS, 'Radius'),\n    wbFloat(XHLP, 'Health'),\n\n    {--- Reflected By / Refracted By ---}\n    wbRArrayS('Reflected/Refracted By',\n      wbStructSK(XPWR, [0], 'Water', [\n        wbFormIDCk('Reference', [REFR]),\n        wbInteger('Type', itU32, wbFlags([\n          'Reflection',\n          'Refraction'\n        ]))\n      ])\n    ),\n\n    {--- Decals ---}\n    wbRArrayS('Linked Decals',\n      wbStructSK(XDCR, [0], 'Decal', [\n        wbFormIDCk('Reference', [REFR]),\n        wbUnknown\n      ])\n    ),\n\n    {--- Linked Ref ---}\n    wbFormIDCk(XLKR, 'Linked Reference', [REFR, ACRE, ACHR, PGRE, PMIS, PBEA, PLYR]),\n    wbStruct(XCLP, 'Linked Reference Color', [\n      wbStruct('Link Start Color', [\n        wbInteger('Red', itU8),\n        wbInteger('Green', itU8),\n        wbInteger('Blue', itU8),\n        wbByteArray('Unused', 1)\n      ]),\n      wbStruct('Link End Color', [\n        wbInteger('Red', itU8),\n        wbInteger('Green', itU8),\n        wbInteger('Blue', itU8),\n        wbByteArray('Unused', 1)\n      ])\n    ]),\n\n    {--- Activate Parents ---}\n    wbRStruct('Activate Parents', [\n      wbInteger(XAPD, 'Flags', itU8, wbFlags([\n        'Parent Activate Only'\n      ], True)),\n      wbRArrayS('Activate Parent Refs',\n        wbStructSK(XAPR, [0], 'Activate Parent Ref', [\n          wbFormIDCk('Reference', [REFR, ACRE, ACHR, PGRE, PMIS, PBEA, PLYR]),\n          wbFloat('Delay')\n        ])\n      )\n    ], []),\n\n    wbString(XATO, 'Activation Prompt'),\n\n    {--- Enable Parent ---}\n    wbXESP,\n\n    {--- Emittance ---}\n    wbFormIDCk(XEMI, 'Emittance', [LIGH, REGN]),\n\n    {--- MultiBound ---}\n    wbFormIDCk(XMBR, 'MultiBound Reference', [REFR]),\n\n    {--- Flags ---}\n    wbEmpty(XIBS, 'Ignored By Sandbox'),\n\n    {--- 3D Data ---}\n    wbXSCL,\n    wbDATAPosRot\n  ], True, wbPlacedAddInfo);\n\n   wbRecord(EXPL, 'Explosion', [\n    wbEDIDReq,\n    wbOBNDReq,\n    wbFULL,\n    wbMODL,\n    wbEITM,\n    wbFormIDCk(MNAM, 'Image Space Modifier', [IMAD]),\n    wbStruct(DATA, 'Data', [\n      {00} wbFloat('Force'),\n      {04} wbFloat('Damage'),\n      {08} wbFloat('Radius'),\n      {12} wbFormIDCk('Light', [LIGH, NULL]),\n      {16} wbFormIDCk('Sound 1', [SOUN, NULL]),\n      {20} wbInteger('Flags', itU32, wbFlags([\n             {0x00000001}'Unknown 1',\n             {0x00000002}'Always Uses World Orientation',\n             {0x00000004}'Knock Down - Always',\n             {0x00000008}'Knock Down - By Formula',\n             {0x00000010}'Ignore LOS Check',\n             {0x00000020}'Push Explosion Source Ref Only',\n             {0x00000040}'Ignore Image Space Swap'\n           ])),\n      {24} wbFloat('IS Radius'),\n      {28} wbFormIDCk('Impact DataSet', [IPDS, NULL]),\n      {32} wbFormIDCk('Sound 2', [SOUN, NULL]),\n           wbStruct('Radiation', [\n             {36} wbFloat('Level'),\n             {40} wbFloat('Dissipation Time'),\n             {44} wbFloat('Radius')\n           ]),\n      {48} wbInteger('Sound Level', itU32, wbSoundLevelEnum, cpNormal, True)\n    ], cpNormal, True),\n    wbFormIDCk(INAM, 'Placed Impact Object', [TREE, SOUN, ACTI, DOOR, STAT, FURN,\n          CONT, ARMO, AMMO, LVLN, LVLC, MISC, WEAP, BOOK, KEYM, ALCH, LIGH, GRAS,\n          ASPC, IDLM, ARMA, MSTT, NOTE, PWAT, SCOL, TACT, TERM, TXST, CHIP, CMNY,\n          CCRD, IMOD])\n  ]);\n\n  wbRecord(DEBR, 'Debris', [\n    wbEDIDReq,\n    wbRStructs('Models', 'Model', [\n      wbStruct(DATA, 'Data', [\n        wbInteger('Percentage', itU8),\n        wbString('Model Filename'),\n        wbInteger('Flags', itU8, wbFlags([\n          'Has Collission Data'\n        ]))\n      ], cpNormal, True),\n      wbByteArray(MODT, 'Texture Files Hashes', 0, cpIgnore)\n    ], [], cpNormal, True)\n  ]);\n\n  wbRecord(IMGS, 'Image Space', [\n    wbEDIDReq,\n    wbStruct(DNAM, '', [\n      wbStruct('HDR', [\n        {00} wbFloat('Eye Adapt Speed'),\n        {04} wbFloat('Blur Radius'),\n        {08} wbFloat('Blur Passes'),\n        {12} wbFloat('Emissive Mult'),\n        {16} wbFloat('Target LUM'),\n        {20} wbFloat('Upper LUM Clamp'),\n        {24} wbFloat('Bright Scale'),\n        {28} wbFloat('Bright Clamp'),\n        {32} wbFloat('LUM Ramp No Tex'),\n        {36} wbFloat('LUM Ramp Min'),\n        {40} wbFloat('LUM Ramp Max'),\n        {44} wbFloat('Sunlight Dimmer'),\n        {48} wbFloat('Grass Dimmer'),\n        {52} wbFloat('Tree Dimmer'),\n        {56} wbUnion('Skin Dimmer', wbIMGSSkinDimmerDecider, [\n               wbFloat('Skin Dimmer'),\n               wbEmpty('Skin Dimmer', cpIgnore)\n             ])\n      ], cpNormal, False, nil, 14),\n      wbStruct('Bloom', [\n        {60} wbFloat('Blur Radius'),\n        {64} wbFloat('Alpha Mult Interior'),\n        {68} wbFloat('Alpha Mult Exterior')\n      ]),\n      wbStruct('Get Hit', [\n        {72} wbFloat('Blur Radius'),\n        {76} wbFloat('Blur Damping Constant'),\n        {80} wbFloat('Damping Constant')\n      ]),\n      wbStruct('Night Eye', [\n        wbStruct('Tint Color', [\n          {84} wbFloat('Red', cpNormal, False, 255, 0),\n          {88} wbFloat('Green', cpNormal, False, 255, 0),\n          {92} wbFloat('Blue', cpNormal, False, 255, 0)\n        ]),\n      {96} wbFloat('Brightness')\n      ]),\n      wbStruct('Cinematic', [\n        {100} wbFloat('Saturation'),\n        wbStruct('Contrast', [\n          {104} wbFloat('Avg Lum Value'),\n          {108} wbFloat('Value')\n        ]),\n        {112} wbFloat('Cinematic - Brightness - Value'),\n        wbStruct('Tint', [\n          wbStruct('Color', [\n            {116} wbFloat('Red', cpNormal, False, 255, 0),\n            {120} wbFloat('Green', cpNormal, False, 255, 0),\n            {124} wbFloat('Blue', cpNormal, False, 255, 0)\n          ]),\n        {128} wbFloat('Value')\n        ])\n      ]),\n      wbByteArray('Unused', 4),\n      wbByteArray('Unused', 4),\n      wbByteArray('Unused', 4),\n      wbByteArray('Unused', 4),\n      wbInteger('Flags', itU8, wbFlags([\n        'Saturation',\n        'Contrast',\n        'Tint',\n        'Brightness'\n      ], True)),\n      wbByteArray('Unused', 3)\n    ], cpNormal, True, nil, 5)\n  ]);\n\n  wbTimeInterpolator := wbStruct('Data', [\n    wbFloat('Time'),\n    wbFloat('Value')\n  ]);\n\n  wbColorInterpolator := wbStruct('Data', [\n    wbFloat('Time'),\n    wbFloat('Red', cpNormal, False, 255, 0),\n    wbFloat('Green', cpNormal, False, 255, 0),\n    wbFloat('Blue', cpNormal, False, 255, 0),\n    wbFloat('Alpha', cpNormal, False, 255, 0)\n  ]);\n\n  wbRecord(IMAD, 'Image Space Adapter', [\n    wbEDID,\n    wbStruct(DNAM, 'Data Count', [\n      wbInteger('Flags', itU32, wbFlags(['Animatable'])),\n      wbFloat('Duration'),\n      wbStruct('HDR', [\n        wbInteger('Eye Adapt Speed Mult', itU32),\n        wbInteger('Eye Adapt Speed Add', itU32),\n        wbInteger('Bloom Blur Radius Mult', itU32),\n        wbInteger('Bloom Blur Radius Add', itU32),\n        wbInteger('Bloom Threshold Mult', itU32),\n        wbInteger('Bloom Threshold Add', itU32),\n        wbInteger('Bloom Scale Mult', itU32),\n        wbInteger('Bloom Scale Add', itU32),\n        wbInteger('Target Lum Min Mult', itU32),\n        wbInteger('Target Lum Min Add', itU32),\n        wbInteger('Target Lum Max Mult', itU32),\n        wbInteger('Target Lum Max Add', itU32),\n        wbInteger('Sunlight Scale Mult', itU32),\n        wbInteger('Sunlight Scale Add', itU32),\n        wbInteger('Sky Scale Mult', itU32),\n        wbInteger('Sky Scale Add', itU32)\n      ]),\n      wbInteger('Unknown08 Mult', itU32),\n      wbInteger('Unknown48 Add', itU32),\n      wbInteger('Unknown09 Mult', itU32),\n      wbInteger('Unknown49 Add', itU32),\n      wbInteger('Unknown0A Mult', itU32),\n      wbInteger('Unknown4A Add', itU32),\n      wbInteger('Unknown0B Mult', itU32),\n      wbInteger('Unknown4B Add', itU32),\n      wbInteger('Unknown0C Mult', itU32),\n      wbInteger('Unknown4C Add', itU32),\n      wbInteger('Unknown0D Mult', itU32),\n      wbInteger('Unknown4D Add', itU32),\n      wbInteger('Unknown0E Mult', itU32),\n      wbInteger('Unknown4E Add', itU32),\n      wbInteger('Unknown0F Mult', itU32),\n      wbInteger('Unknown4F Add', itU32),\n      wbInteger('Unknown10 Mult', itU32),\n      wbInteger('Unknown50 Add', itU32),\n      wbStruct('Cinematic', [\n        wbInteger('Saturation Mult', itU32),\n        wbInteger('Saturation Add', itU32),\n        wbInteger('Brightness Mult', itU32),\n        wbInteger('Brightness Add', itU32),\n        wbInteger('Contrast Mult', itU32),\n        wbInteger('Contrast Add', itU32)\n      ]),\n      wbInteger('Unknown14 Mult', itU32),\n      wbInteger('Unknown54 Add', itU32),\n      wbInteger('Tint Color', itU32),\n      wbInteger('Blur Radius', itU32),\n      wbInteger('Double Vision Strength', itU32),\n      wbInteger('Radial Blur Strength', itU32),\n      wbInteger('Radial Blur Ramp Up', itU32),\n      wbInteger('Radial Blur Start', itU32),\n      wbInteger('Radial Blur Flags', itU32, wbFlags(['Use Target'])),\n      wbFloat('Radial Blur Center X'),\n      wbFloat('Radial Blur Center Y'),\n      wbInteger('DoF Strength', itU32),\n      wbInteger('DoF Distance', itU32),\n      wbInteger('DoF Range', itU32),\n      wbInteger('DoF Flags', itU32, wbFlags(['Use Target'])),\n      wbInteger('Radial Blur Ramp Down', itU32),\n      wbInteger('Radial Blur Down Start', itU32),\n      wbInteger('Fade Color', itU32),\n      wbInteger('Motion Blur Strength', itU32)\n    ], cpNormal, True, nil, 26),\n    wbArray(BNAM, 'Blur Radius', wbTimeInterpolator),\n    wbArray(VNAM, 'Double Vision Strength', wbTimeInterpolator),\n    wbArray(TNAM, 'Tint Color', wbColorInterpolator),\n    wbArray(NAM3, 'Fade Color', wbColorInterpolator),\n    wbArray(RNAM, 'Radial Blur Strength', wbTimeInterpolator),\n    wbArray(SNAM, 'Radial Blur Ramp Up', wbTimeInterpolator),\n    wbArray(UNAM, 'Radial Blur Start', wbTimeInterpolator),\n    wbArray(NAM1, 'Radial Blur Ramp Down', wbTimeInterpolator),\n    wbArray(NAM2, 'Radial Blur Down Start', wbTimeInterpolator),\n    wbArray(WNAM, 'DoF Strength', wbTimeInterpolator),\n    wbArray(XNAM, 'DoF Distance', wbTimeInterpolator),\n    wbArray(YNAM, 'DoF Range', wbTimeInterpolator),\n    wbArray(NAM4, 'Motion Blur Strength', wbTimeInterpolator),\n    wbRStruct('HDR', [\n      wbArray(_00_IAD, 'Eye Adapt Speed Mult', wbTimeInterpolator),\n      wbArray(_40_IAD, 'Eye Adapt Speed Add', wbTimeInterpolator),\n      wbArray(_01_IAD, 'Bloom Blur Radius Mult', wbTimeInterpolator),\n      wbArray(_41_IAD, 'Bloom Blur Radius Add', wbTimeInterpolator),\n      wbArray(_02_IAD, 'Bloom Threshold Mult', wbTimeInterpolator),\n      wbArray(_42_IAD, 'Bloom Threshold Add', wbTimeInterpolator),\n      wbArray(_03_IAD, 'Bloom Scale Mult', wbTimeInterpolator),\n      wbArray(_43_IAD, 'Bloom Scale Add', wbTimeInterpolator),\n      wbArray(_04_IAD, 'Target Lum Min Mult', wbTimeInterpolator),\n      wbArray(_44_IAD, 'Target Lum Min Add', wbTimeInterpolator),\n      wbArray(_05_IAD, 'Target Lum Max Mult', wbTimeInterpolator),\n      wbArray(_45_IAD, 'Target Lum Max Add', wbTimeInterpolator),\n      wbArray(_06_IAD, 'Sunlight Scale Mult', wbTimeInterpolator),\n      wbArray(_46_IAD, 'Sunlight Scale Add', wbTimeInterpolator),\n      wbArray(_07_IAD, 'Sky Scale Mult', wbTimeInterpolator),\n      wbArray(_47_IAD, 'Sky Scale Add', wbTimeInterpolator)\n    ], []),\n    wbUnknown(_08_IAD),\n    wbUnknown(_48_IAD),\n    wbUnknown(_09_IAD),\n    wbUnknown(_49_IAD),\n    wbUnknown(_0A_IAD),\n    wbUnknown(_4A_IAD),\n    wbUnknown(_0B_IAD),\n    wbUnknown(_4B_IAD),\n    wbUnknown(_0C_IAD),\n    wbUnknown(_4C_IAD),\n    wbUnknown(_0D_IAD),\n    wbUnknown(_4D_IAD),\n    wbUnknown(_0E_IAD),\n    wbUnknown(_4E_IAD),\n    wbUnknown(_0F_IAD),\n    wbUnknown(_4F_IAD),\n    wbUnknown(_10_IAD),\n    wbUnknown(_50_IAD),\n    wbRStruct('Cinematic', [\n      wbArray(_11_IAD, 'Saturation Mult', wbTimeInterpolator),\n      wbArray(_51_IAD, 'Saturation Add', wbTimeInterpolator),\n      wbArray(_12_IAD, 'Brightness Mult', wbTimeInterpolator),\n      wbArray(_52_IAD, 'Brightness Add', wbTimeInterpolator),\n      wbArray(_13_IAD, 'Contrast Mult', wbTimeInterpolator),\n      wbArray(_53_IAD, 'Contrast Add', wbTimeInterpolator)\n    ], []),\n    wbUnknown(_14_IAD),\n    wbUnknown(_54_IAD),\n    wbFormIDCk(RDSD, 'Sound - Intro', [SOUN]),\n    wbFormIDCk(RDSI, 'Sound - Outro', [SOUN])\n  ]);\n\n  wbRecord(FLST, 'FormID List', [\n    wbString(EDID, 'Editor ID', 0, cpBenign, True, nil, wbFLSTEDIDAfterSet),\n    wbRArrayS('FormIDs', wbFormID(LNAM, 'FormID'), cpNormal, False, nil, nil, nil, wbFLSTLNAMIsSorted)\n  ]);\n\n  wbRecord(PERK, 'Perk', [\n    wbEDIDReq,\n    wbFULL,\n    wbDESCReq,\n    wbICON,\n    wbCTDAs,\n    wbStruct(DATA, 'Data', [\n      wbInteger('Trait', itU8, wbEnum(['No', 'Yes'])),\n      wbInteger('Min Level', itU8),\n      wbInteger('Ranks', itU8),\n      wbInteger('Playable', itU8, wbEnum(['No', 'Yes'])),\n      wbInteger('Hidden', itU8, wbEnum(['No', 'Yes']))\n    ], cpNormal, True, nil, 4),\n    wbRStructsSK('Effects', 'Effect', [0, 1], [\n      wbStructSK(PRKE, [1, 2, 0], 'Header', [\n        wbInteger('Type', itU8, wbEnum([\n          'Quest + Stage',\n          'Ability',\n          'Entry Point'\n        ]), cpNormal, False, nil, wbPERKPRKETypeAfterSet),\n        wbInteger('Rank', itU8),\n        wbInteger('Priority', itU8)\n      ]),\n      wbUnion(DATA, 'Effect Data', wbPerkDATADecider, [\n        wbStructSK([0, 1], 'Quest + Stage', [\n          wbFormIDCk('Quest', [QUST]),\n          wbInteger('Quest Stage', itU8, wbPerkDATAQuestStageToStr, wbCTDAParam2QuestStageToInt),\n          wbByteArray('Unused', 3)\n        ]),\n        wbFormIDCk('Ability', [SPEL]),\n        wbStructSK([0, 1], 'Entry Point', [\n          wbInteger('Entry Point', itU8, wbEnum([\n           {00} 'Calculate Weapon Damage',\n           {01} 'Calculate My Critical Hit Chance',\n           {02} 'Calculate My Critical Hit Damage',\n           {03} 'Calculate Weapon Attack AP Cost',\n           {04} 'Calculate Mine Explode Chance',\n           {05} 'Adjust Range Penalty',\n           {06} 'Adjust Limb Damage',\n           {07} 'Calculate Weapon Range',\n           {08} 'Calculate To Hit Chance',\n           {09} 'Adjust Experience Points',\n           {10} 'Adjust Gained Skill Points',\n           {11} 'Adjust Book Skill Points',\n           {12} 'Modify Recovered Health',\n           {13} 'Calculate Inventory AP Cost',\n           {14} 'Get Disposition',\n           {15} 'Get Should Attack',\n           {16} 'Get Should Assist',\n           {17} 'Calculate Buy Price',\n           {18} 'Get Bad Karma',\n           {19} 'Get Good Karma',\n           {20} 'Ignore Locked Terminal',\n           {21} 'Add Leveled List On Death',\n           {22} 'Get Max Carry Weight',\n           {23} 'Modify Addiction Chance',\n           {24} 'Modify Addiction Duration',\n           {25} 'Modify Positive Chem Duration',\n           {26} 'Adjust Drinking Radiation',\n           {27} 'Activate',\n           {28} 'Mysterious Stranger',\n           {29} 'Has Paralyzing Palm',\n           {30} 'Hacking Science Bonus',\n           {31} 'Ignore Running During Detection',\n           {32} 'Ignore Broken Lock',\n           {33} 'Has Concentrated Fire',\n           {34} 'Calculate Gun Spread',\n           {35} 'Player Kill AP Reward',\n           {36} 'Modify Enemy Critical Hit Chance',\n           {37} 'Reload Speed',\n           {38} 'Equip Speed',\n           {39} 'Action Point Regen',\n           {40} 'Action Point Cost',\n           {41} 'Miss Fortune',\n           {42} 'Modify Run Speed',\n           {43} 'Modify Attack Speed',\n           {44} 'Modify Radiation Consumed',\n           {45} 'Has Pip Hacker',\n           {46} 'Has Meltdown',\n           {47} 'See Enemy Health',\n           {48} 'Has Jury Rigging',\n           {49} 'Modify Threat Range',\n           {50} 'Modify Thread',\n           {51} 'Has Fast Travel Always',\n           {52} 'Knockdown Chance',\n           {53} 'Modify Weapon Strength Req',\n           {54} 'Modify Aiming Move Speed',\n           {55} 'Modify Light Items',\n           {56} 'Modify Damage Threshold (defender)',\n           {57} 'Modify Chance for Ammo Item',\n           {58} 'Modify Damage Threshold (attacker)',\n           {59} 'Modify Throwing Velocity',\n           {60} 'Chance for Item on Fire',\n           {61} 'Has Unarmed Forward Power Attack',\n           {62} 'Has Unarmed Back Power Attack',\n           {63} 'Has Unarmed Crouched Power Attack',\n           {64} 'Has Unarmed Counter Attack',\n           {65} 'Has Unarmed Left Power Attack',\n           {66} 'Has Unarmed Right Power Attack',\n           {67} 'VATS HelperChance',\n           {68} 'Modify Item Damage',\n           {69} 'Has Improved Detection',\n           {70} 'Has Improved Spotting',\n           {71} 'Has Improved Item Detection',\n           {72} 'Adjust Explosion Radius',\n           {73} 'Reserved'\n          ]), cpNormal, True, nil, wbPERKEntryPointAfterSet),\n          wbInteger('Function', itU8, wbPerkDATAFunctionToStr, wbPerkDATAFunctionToInt, cpNormal, False, nil, wbPerkDATAFunctionAfterSet),\n          wbInteger('Perk Condition Tab Count', itU8, nil, cpIgnore)\n        ])\n      ], cpNormal, True),\n      wbRStructsSK('Perk Conditions', 'Perk Condition', [0], [\n        wbInteger(PRKC, 'Run On', itS8, wbPRKCToStr, wbPRKCToInt),\n        wbCTDAsReq\n      ], [], cpNormal, False, nil, nil, wbPERKPRKCDontShow),\n      wbRStruct('Entry Point Function Parameters', [\n        wbInteger(EPFT, 'Type', itU8, wbPerkEPFTToStr, wbPerkEPFTToInt, cpIgnore, False, nil, wbPerkEPFTAfterSet),\n        wbUnion(EPFD, 'Data', wbEPFDDecider, [\n          wbByteArray('Unknown'),\n          wbFloat('Float'),\n          wbStruct('Float, Float', [\n            wbFloat('Float 1'),\n            wbFloat('Float 2')\n          ]),\n          wbFormIDCk('Leveled Item', [LVLI]),\n          wbEmpty('None (Script)'),\n          wbStruct('Actor Value, Float', [\n            wbInteger('Actor Value', itU32, wbEPFDActorValueToStr, wbEPFDActorValueToInt),\n            wbFloat('Float')\n          ])\n        ], cpNormal, False, wbEPFDDontShow),\n        wbString(EPF2, 'Button Label', 0, cpNormal, False, wbEPF2DontShow),\n        wbInteger(EPF3, 'Script Flags', itU16, wbFlags([\n          'Run Immediately'\n        ]), cpNormal, False, False, wbEPF2DontShow),\n        wbEmbeddedScriptPerk\n      ], [], cpNormal, False, wbPERKPRKCDontShow),\n      wbEmpty(PRKF, 'End Marker', cpIgnore, True)\n    ], [])\n  ]);\n\n  wbBPNDStruct := wbStruct(BPND, '', [\n    {00} wbFloat('Damage Mult'),\n    {04} wbInteger('Flags', itU8, wbFlags([\n      'Severable',\n      'IK Data',\n      'IK Data - Biped Data',\n      'Explodable',\n      'IK Data - Is Head',\n      'IK Data - Headtracking',\n      'To Hit Chance - Absolute'\n    ])),\n    {05} wbInteger('Part Type', itU8, wbEnum([\n           'Torso',\n           'Head 1',\n           'Head 2',\n           'Left Arm 1',\n           'Left Arm 2',\n           'Right Arm 1',\n           'Right Arm 2',\n           'Left Leg 1',\n           'Left Leg 2',\n           'Left Leg 3',\n           'Right Leg 1',\n           'Right Leg 2',\n           'Right Leg 3',\n           'Brain',\n           'Weapon'\n         ])),\n    {06} wbInteger('Health Percent', itU8),\n    {07} wbInteger('Actor Value', itS8, wbActorValueEnum),\n    {08} wbInteger('To Hit Chance', itU8),\n    {09} wbInteger('Explodable - Explosion Chance %', itU8),\n    {10} wbInteger('Explodable - Debris Count', itU16),\n    {12} wbFormIDCk('Explodable - Debris', [DEBR, NULL]),\n    {16} wbFormIDCk('Explodable - Explosion', [EXPL, NULL]),\n    {20} wbFloat('Tracking Max Angle'),\n    {24} wbFloat('Explodable - Debris Scale'),\n    {28} wbInteger('Severable - Debris Count', itS32),\n    {32} wbFormIDCk('Severable - Debris', [DEBR, NULL]),\n    {36} wbFormIDCk('Severable - Explosion', [EXPL, NULL]),\n    {40} wbFloat('Severable - Debris Scale'),\n    wbStruct('Gore Effects Positioning', [\n      wbStruct('Translate', [\n        {44} wbFloat('X'),\n        {48} wbFloat('Y'),\n        {52} wbFloat('Z')\n      ]),\n      wbStruct('Rotation', [\n        {56} wbFloat('X', cpNormal, True, wbRotationFactor, wbRotationScale, nil, RadiansNormalize),\n        {60} wbFloat('Y', cpNormal, True, wbRotationFactor, wbRotationScale, nil, RadiansNormalize),\n        {64} wbFloat('Z', cpNormal, True, wbRotationFactor, wbRotationScale, nil, RadiansNormalize)\n      ])\n    ]),\n    {68} wbFormIDCk('Severable - Impact DataSet', [IPDS, NULL]),\n    {72} wbFormIDCk('Explodable - Impact DataSet', [IPDS, NULL]),\n    {28} wbInteger('Severable - Decal Count', itU8),\n    {28} wbInteger('Explodable - Decal Count', itU8),\n    {76} wbByteArray('Unused', 2),\n    {80} wbFloat('Limb Replacement Scale')\n  ], cpNormal, True);\n\n  wbRecord(BPTD, 'Body Part Data', [\n    wbEDIDReq,\n    wbMODLReq,\n    wbRStructS('Body Parts', 'Body Part', [ // When the Part Name is provided\n      wbString(BPTN, 'Part Name', 0, cpNormal, True),\n      wbString(BPNN, 'Part Node', 0, cpNormal, True),\n      wbString(BPNT, 'VATS Target', 0, cpNormal, True),\n      wbString(BPNI, 'IK Data - Start Node', 0, cpNormal, True),\n      wbBPNDStruct,\n      wbString(NAM1, 'Limb Replacement Model', 0, cpNormal, True),\n      wbString(NAM4, 'Gore Effects - Target Bone', 0, cpNormal, True),\n      wbByteArray(NAM5, 'Texture Files Hashes', 0, cpIgnore)\n    ], [], cpNormal, False),\n    wbRStructS('Unnamed Body Parts', 'Body Part', [ // When the Part Name is not provided\n      wbString(BPNN, 'Part Node', 0, cpNormal, True),\n      wbString(BPNT, 'VATS Target', 0, cpNormal, True),\n      wbString(BPNI, 'IK Data - Start Node', 0, cpNormal, True),\n      wbBPNDStruct,\n      wbString(NAM1, 'Limb Replacement Model', 0, cpNormal, True),\n      wbString(NAM4, 'Gore Effects - Target Bone', 0, cpNormal, True),\n      wbByteArray(NAM5, 'Texture Files Hashes', 0, cpIgnore)\n    ], [], cpNormal, False),\n    wbFormIDCk(RAGA, 'Ragdoll', [RGDL])\n  ]);\n\n  wbRecord(ADDN, 'Addon Node', [\n    wbEDIDReq,\n    wbOBNDReq,\n    wbMODLReq,\n    wbInteger(DATA, 'Node Index', itS32, nil, cpNormal, True),\n    wbFormIDCk(SNAM, 'Sound', [SOUN]),\n    wbStruct(DNAM, 'Data', [\n      wbInteger('Master Particle System Cap', itU16),\n      wbByteArray('Unknown', 2)\n    ], cpNormal, True)\n  ]);\n\n  wbRecord(AVIF, 'ActorValue Information', [\n    wbEDIDReq,\n    wbFULL,\n    wbDESCReq,\n    wbICON,\n    wbString(ANAM, 'Short Name')\n  ]);\n\n  wbRecord(RADS, 'Radiation Stage', [\n    wbEDIDReq,\n    wbStruct(DATA, '', [\n      wbInteger('Trigger Threshold', itU32),\n      wbFormIDCk('Actor Effect', [SPEL])\n    ], cpNormal, True)\n  ]);\n\n  wbRecord(CAMS, 'Camera Shot', [\n    wbEDIDReq,\n    wbMODL,\n    wbStruct(DATA, 'Data', [\n      {00} wbInteger('Action', itU32, wbEnum([\n        'Shoot',\n        'Fly',\n        'Hit',\n        'Zoom'\n      ])),\n      {04} wbInteger('Location', itU32, wbEnum([\n        'Attacker',\n        'Projectile',\n        'Target'\n      ])),\n      {08} wbInteger('Target', itU32, wbEnum([\n        'Attacker',\n        'Projectile',\n        'Target'\n      ])),\n      {12} wbInteger('Flags', itU32, wbFlags([\n        'Position Follows Location',\n        'Rotation Follows Target',\n        'Don''t Follow Bone',\n        'First Person Camera',\n        'No Tracer',\n        'Start At Time Zero'\n      ])),\n      wbStruct('Time Multipliers', [\n        {16} wbFloat('Player'),\n        {20} wbFloat('Target'),\n        {24} wbFloat('Global')\n      ]),\n      {28} wbFloat('Max Time'),\n      {32} wbFloat('Min Time'),\n      {36} wbFloat('Target % Between Actors')\n    ], cpNormal, True, nil, 7),\n    wbFormIDCk(MNAM, 'Image Space Modifier', [IMAD])\n  ]);\n\n  wbRecord(CPTH, 'Camera Path', [\n    wbEDIDReq,\n    wbCTDAs,\n    wbArray(ANAM, 'Related Camera Paths', wbFormIDCk('Related Camera Path', [CPTH, NULL]), ['Parent', 'Previous Sibling'], cpNormal, True),\n    wbInteger(DATA, 'Camera Zoom', itU8, wbEnum([\n      'Default',\n      'Disable',\n      'Shot List'\n    ]), cpNormal, True),\n    wbRArray('Camera Shots', wbFormIDCk(SNAM, 'Camera Shot', [CAMS]))\n  ]);\n\n  wbRecord(VTYP, 'Voice Type', [\n    wbEDIDReq,\n    wbInteger(DNAM, 'Flags', itU8, wbFlags([\n      'Allow Default Dialog',\n      'Female'\n    ]), cpNormal, False)\n  ]);\n\n  wbRecord(IPCT, 'Impact', [\n    wbEDIDReq,\n    wbMODL,\n    wbStruct(DATA, '', [\n      wbFloat('Effect - Duration'),\n      wbInteger('Effect - Orientation', itU32, wbEnum([\n        'Surface Normal',\n        'Projectile Vector',\n        'Projectile Reflection'\n      ])),\n      wbFloat('Angle Threshold'),\n      wbFloat('Placement Radius'),\n      wbInteger('Sound Level', itU32, wbSoundLevelEnum),\n      wbInteger('Flags', itU32, wbFlags([\n        'No Decal Data'\n      ]))\n    ], cpNormal, True),\n    wbDODT,\n    wbFormIDCk(DNAM, 'Texture Set', [TXST]),\n    wbFormIDCk(SNAM, 'Sound 1', [SOUN]),\n    wbFormIDCk(NAM1, 'Sound 2', [SOUN])\n  ]);\n\n  wbRecord(IPDS, 'Impact DataSet', [\n    wbEDIDReq,\n    wbStruct(DATA, 'Impacts', [\n      wbFormIDCk('Stone', [IPCT, NULL]),\n      wbFormIDCk('Dirt', [IPCT, NULL]),\n      wbFormIDCk('Grass', [IPCT, NULL]),\n      wbFormIDCk('Glass', [IPCT, NULL]),\n      wbFormIDCk('Metal', [IPCT, NULL]),\n      wbFormIDCk('Wood', [IPCT, NULL]),\n      wbFormIDCk('Organic', [IPCT, NULL]),\n      wbFormIDCk('Cloth', [IPCT, NULL]),\n      wbFormIDCk('Water', [IPCT, NULL]),\n      wbFormIDCk('Hollow Metal', [IPCT, NULL]),\n      wbFormIDCk('Organic Bug', [IPCT, NULL]),\n      wbFormIDCk('Organic Glow', [IPCT, NULL])\n    ], cpNormal, True, nil, 9)\n  ]);\n\n  wbRecord(ECZN, 'Encounter Zone', [\n    wbEDIDReq,\n    wbStruct(DATA, '', [\n      wbFormIDCkNoReach('Owner', [NPC_, FACT, NULL]),\n      wbInteger('Rank', itS8),\n      wbInteger('Minimum Level', itS8),\n      wbInteger('Flags', itU8, wbFlags([\n        'Never Resets',\n        'Match PC Below Minimum Level'\n      ])),\n      wbByteArray('Unused', 1)\n    ], cpNormal, True)\n  ]);\n\n  wbRecord(MESG, 'Message', [\n    wbEDIDReq,\n    wbDESCReq,\n    wbFULL,\n    wbFormIDCk(INAM, 'Icon', [MICN, NULL], False, cpNormal, True),\n    wbByteArray(NAM0, 'Unused', 0, cpIgnore),\n    wbByteArray(NAM1, 'Unused', 0, cpIgnore),\n    wbByteArray(NAM2, 'Unused', 0, cpIgnore),\n    wbByteArray(NAM3, 'Unused', 0, cpIgnore),\n    wbByteArray(NAM4, 'Unused', 0, cpIgnore),\n    wbByteArray(NAM5, 'Unused', 0, cpIgnore),\n    wbByteArray(NAM6, 'Unused', 0, cpIgnore),\n    wbByteArray(NAM7, 'Unused', 0, cpIgnore),\n    wbByteArray(NAM8, 'Unused', 0, cpIgnore),\n    wbByteArray(NAM9, 'Unused', 0, cpIgnore),\n    wbInteger(DNAM, 'Flags', itU32, wbFlags([\n      'Message Box',\n      'Auto Display'\n    ]), cpNormal, True, False, nil, wbMESGDNAMAfterSet),\n    wbInteger(TNAM, 'Display Time', itU32, nil, cpNormal, False, False, wbMESGTNAMDontShow),\n    wbRStructs('Menu Buttons', 'Menu Button', [\n      wbString(ITXT, 'Button Text'),\n      wbCTDAs\n    ], [])\n  ], False, nil, cpNormal, False, wbMESGAfterLoad);\n\n  wbRecord(RGDL, 'Ragdoll', [\n    wbEDIDReq,\n    wbInteger(NVER, 'Version', itU32, nil, cpNormal, True),\n    wbStruct(DATA, 'General Data', [\n      wbInteger('Dynamic Bone Count', itU32),\n      wbByteArray('Unused', 4),\n      wbStruct('Enabled', [\n        wbInteger('Feedback', itU8, wbEnum(['No', 'Yes'])),\n        wbInteger('Foot IK (broken, don''t use)', itU8, wbEnum(['No', 'Yes'])),\n        wbInteger('Look IK (broken, don''t use)', itU8, wbEnum(['No', 'Yes'])),\n        wbInteger('Grab IK (broken, don''t use)', itU8, wbEnum(['No', 'Yes'])),\n        wbInteger('Pose Matching', itU8, wbEnum(['No', 'Yes']))\n      ]),\n      wbByteArray('Unused', 1)\n    ], cpNormal, True),\n    wbFormIDCk(XNAM, 'Actor Base', [CREA, NPC_], False, cpNormal, True),\n    wbFormIDCk(TNAM, 'Body Part Data', [BPTD], False, cpNormal, True),\n    wbStruct(RAFD, 'Feedback Data', [\n    {00} wbFloat('Dynamic/Keyframe Blend Amount'),\n    {04} wbFloat('Hierarchy Gain'),\n    {08} wbFloat('Position Gain'),\n    {12} wbFloat('Velocity Gain'),\n    {16} wbFloat('Acceleration Gain'),\n    {20} wbFloat('Snap Gain'),\n    {24} wbFloat('Velocity Damping'),\n         wbStruct('Snap Max Settings', [\n           {28} wbFloat('Linear Velocity'),\n           {32} wbFloat('Angular Velocity'),\n           {36} wbFloat('Linear Distance'),\n           {40} wbFloat('Angular Distance')\n         ]),\n         wbStruct('Position Max Velocity', [\n           {44} wbFloat('Linear'),\n           {48} wbFloat('Angular')\n         ]),\n         wbStruct('Position Max Velocity', [\n           {52} wbInteger('Projectile', itS32, wbDiv(1000)),\n           {56} wbInteger('Melee', itS32, wbDiv(1000))\n         ])\n    ], cpNormal, False),\n    wbArray(RAFB, 'Feedback Dynamic Bones', wbInteger('Bone', itU16), 0, nil, nil, cpNormal, False),\n    wbStruct(RAPS, 'Pose Matching Data', [\n    {00} wbArray('Match Bones', wbInteger('Bone', itU16, wbHideFFFF), 3),\n    {06} wbInteger('Flags', itU8, wbFlags([\n           'Disable On Move'\n         ])),\n    {07} wbByteArray('Unused', 1),\n    {08} wbFloat('Motors Strength'),\n    {12} wbFloat('Pose Activation Delay Time'),\n    {16} wbFloat('Match Error Allowance'),\n    {20} wbFloat('Displacement To Disable')\n    ], cpNormal, True),\n    wbString(ANAM, 'Death Pose')\n  ]);\n\n  wbRecord(DOBJ, 'Default Object Manager', [\n    wbEDIDReq,\n    wbArray(DATA, 'Default Objects', wbFormID('Default Object'), [\n      'Stimpack',\n      'SuperStimpack',\n      'RadX',\n      'RadAway',\n      'Morphine',\n      'Perk Paralysis',\n      'Player Faction',\n      'Mysterious Stranger NPC',\n      'Mysterious Stranger Faction',\n      'Default Music',\n      'Battle Music',\n      'Death Music',\n      'Success Music',\n      'Level Up Music',\n      'Player Voice (Male)',\n      'Player Voice (Male Child)',\n      'Player Voice (Female)',\n      'Player Voice (Female Child)',\n      'Eat Package Default Food',\n      'Every Actor Ability',\n      'Drug Wears Off Image Space',\n      'Doctor''s Bag',\n      'Miss Fortune NPC',\n      'Miss Fortune Faction',\n      'Meltdown Explosion',\n      'Unarmed Forward PA',\n      'Unarmed Backward PA',\n      'Unarmed Left PA',\n      'Unarmed Right PA',\n      'Unarmed Crouch PA',\n      'Unarmed Counter PA',\n      'Spotter Effect',\n      'Item Detected Effect',\n      'Cateye Mobile Effect (NYI)'\n    ], cpNormal, True)\n  ]);\n\n  wbRecord(LGTM, 'Lighting Template', [\n    wbEDIDReq,\n    wbStruct(DATA, 'Lighting', [\n      wbStruct('Ambient Color', [\n        wbInteger('Red', itU8),\n        wbInteger('Green', itU8),\n        wbInteger('Blue', itU8),\n        wbByteArray('Unused', 1)\n      ]),\n      wbStruct('Directional Color', [\n        wbInteger('Red', itU8),\n        wbInteger('Green', itU8),\n        wbInteger('Blue', itU8),\n        wbByteArray('Unused', 1)\n      ]),\n      wbStruct('Fog Color', [\n        wbInteger('Red', itU8),\n        wbInteger('Green', itU8),\n        wbInteger('Blue', itU8),\n        wbByteArray('Unused', 1)\n      ]),\n      wbFloat('Fog Near'),\n      wbFloat('Fog Far'),\n      wbInteger('Directional Rotation XY', itS32),\n      wbInteger('Directional Rotation Z', itS32),\n      wbFloat('Directional Fade'),\n      wbFloat('Fog Clip Dist'),\n      wbFloat('Fog Power')\n    ], cpNormal, True)\n  ]);\n\n  wbRecord(MUSC, 'Music Type', [\n    wbEDIDReq,\n    wbString(FNAM, 'Filename'),\n    wbFloat(ANAM, 'dB (positive = Loop)')\n  ]);\n\n  wbRecord(GRAS, 'Grass', [\n    wbEDIDReq,\n    wbOBNDReq,\n    wbMODLReq,\n    wbStruct(DATA, '', [\n      wbInteger('Density', itU8),\n      wbInteger('Min Slope', itU8),\n      wbInteger('Max Slope', itU8),\n      wbByteArray('Unused', 1),\n      wbInteger('Unit from water amount', itU16),\n      wbByteArray('Unused', 2),\n      wbInteger('Unit from water type', itU32, wbEnum([\n        'Above - At Least',\n        'Above - At Most',\n        'Below - At Least',\n        'Below - At Most',\n        'Either - At Least',\n        'Either - At Most',\n        'Either - At Most Above',\n        'Either - At Most Below'\n      ])),\n      wbFloat('Position Range'),\n      wbFloat('Height Range'),\n      wbFloat('Color Range'),\n      wbFloat('Wave Period'),\n      wbInteger('Flags', itU8, wbFlags([\n        'Vertex Lighting',\n        'Uniform Scaling',\n        'Fit to Slope'\n      ])),\n      wbByteArray('Unused', 3)\n    ], cpNormal, True)\n  ]);\n\n  wbRecord(HAIR, 'Hair', [\n    wbEDIDReq,\n    wbFULLReq,\n    wbMODLReq,\n    wbString(ICON, 'Texture', 0, cpNormal, True),\n    wbInteger(DATA, 'Flags', itU8, wbFlags([\n      'Playable',\n      'Not Male',\n      'Not Female',\n      'Fixed'\n    ]), cpNormal, True)\n  ]);\n\n  wbRecord(IDLE, 'Idle Animation', [\n    wbEDID,\n    wbMODLReq,\n    wbCTDAs,\n    wbArray(ANAM, 'Related Idle Animations', wbFormIDCk('Related Idle Animation', [IDLE, NULL]), ['Parent', 'Previous Sibling'], cpNormal, True),\n    wbStruct(DATA, '', [\n      wbInteger('Animation Group Section', itU8, wbIdleAnam),\n      wbStruct('Looping', [\n        wbInteger('Min', itU8),\n        wbInteger('Max', itU8)\n      ]),\n      wbByteArray('Unused', 1),\n      wbInteger('Replay Delay', itS16),\n      wbInteger('Flags', itU8, wbFlags([\n        'No attacking'\n      ])),\n      wbByteArray('Unused', 1)\n    ], cpNormal, True, nil, 4)\n  ]);\n\n  wbRecord(INFO, 'Dialog response', [\n    wbStruct(DATA, '', [\n      wbInteger('Type', itU8, wbEnum([\n        {0} 'Topic',\n        {1} 'Conversation',\n        {2} 'Combat',\n        {3} 'Persuasion',\n        {4} 'Detection',\n        {5} 'Service',\n        {6} 'Miscellaneous',\n        {7} 'Radio'\n      ])),\n      wbInteger('Next Speaker', itU8, wbEnum([\n        {0} 'Target',\n        {1} 'Self',\n        {2} 'Either'\n      ])),\n      wbInteger('Flags 1', itU8, wbFlags([\n        {0x01} 'Goodbye',\n        {0x02} 'Random',\n        {0x04} 'Say Once',\n        {0x08} 'Run Immediately',\n        {0x10} 'Info Refusal',\n        {0x20} 'Random End',\n        {0x40} 'Run for Rumors',\n        {0x80} 'Speech Challenge'\n      ])),\n      wbInteger('Flags 2', itU8, wbFlags([\n        {0x01} 'Say Once a Day',\n        {0x02} 'Always Darken',\n        {0x04} 'Unknown 2',\n        {0x08} 'Unknown 3',\n        {0x10} 'Low Intelligence',\n        {0x20} 'High Intelligence'\n      ]))\n    ], cpNormal, True, nil, 3),\n    wbFormIDCkNoReach(QSTI, 'Quest', [QUST], False, cpNormal, True),\n    wbFormIDCk(TPIC, 'Topic', [DIAL]),  // The GECK ignores it for ESM\n    wbFormIDCkNoReach(PNAM, 'Previous INFO', [INFO, NULL]),\n    wbRArray('Add Topics', wbFormIDCk(NAME, 'Topic', [DIAL])),\n    wbRArray('Responses',\n      wbRStruct('Response', [\n        wbStruct(TRDT, 'Response Data', [\n          wbInteger('Emotion Type', itU32, wbEnum([\n            {0} 'Neutral',\n            {1} 'Anger',\n            {2} 'Disgust',\n            {3} 'Fear',\n            {4} 'Sad',\n            {5} 'Happy',\n            {6} 'Surprise',\n            {7} 'Pained'\n          ])),\n          wbInteger('Emotion Value', itS32),\n          wbByteArray('Unused', 4),\n          wbInteger('Response number', itU8),\n          wbByteArray('Unused', 3),\n          wbFormIDCk('Sound', [SOUN, NULL]),\n          wbInteger('Flags', itU8, wbFlags([\n            'Use Emotion Animation'\n          ])),\n          wbByteArray('Unused', 3)\n        ], cpNormal, False, nil, 5),\n        wbStringKC(NAM1, 'Response Text', 0, cpTranslate, True),\n        wbString(NAM2, 'Script Notes', 0, cpTranslate, True),\n        wbString(NAM3, 'Edits'),\n        wbFormIDCk(SNAM, 'Speaker Animation', [IDLE]),\n        wbFormIDCk(LNAM, 'Listener Animation', [IDLE])\n      ], [])\n    ),\n    wbCTDAs,\n    wbRArray('Choices', wbFormIDCk(TCLT, 'Choice', [DIAL])),\n    wbRArray('Link From', wbFormIDCk(TCLF, 'Topic', [DIAL])),\n    wbRArray('Unknown', wbFormIDCk(TCFU, 'Info', [INFO] )),\n    wbRStruct('Script (Begin)', [\n      wbEmbeddedScriptReq\n    ], [], cpNormal, True),\n    wbRStruct('Script (End)', [\n      wbEmpty(NEXT, 'Marker'),\n      wbEmbeddedScriptReq\n    ], [], cpNormal, True),\n    wbFormIDCk(SNDD, 'Unused', [SOUN]),\n    wbString(RNAM, 'Prompt'),\n    wbFormIDCk(ANAM, 'Speaker', [CREA, NPC_]),\n    wbFormIDCk(KNAM, 'ActorValue/Perk', [AVIF, PERK]),\n    wbInteger(DNAM, 'Speech Challenge', itU32, wbEnum([\n      '---',\n      'Very Easy',\n      'Easy',\n      'Average',\n      'Hard',\n      'Very Hard'\n    ]))\n  ], False, wbINFOAddInfo, cpNormal, False, wbINFOAfterLoad);\n\n  wbRecord(INGR, 'Ingredient', [\n    wbEDIDReq,\n    wbOBNDReq,\n    wbFULL,\n    wbMODL,\n    wbICON,\n    wbSCRI,\n    wbETYPReq,\n    wbFloat(DATA, 'Weight', cpNormal, True),\n    wbStruct(ENIT, 'Effect Data', [\n      wbInteger('Value', itS32),\n      wbInteger('Flags', itU8, wbFlags(['No auto-calculation', 'Food item'])),\n      wbByteArray('Unused', 3)\n    ], cpNormal, True),\n    wbEffectsReq\n  ]);\n\n  wbRecord(KEYM, 'Key', [\n    wbEDIDReq,\n    wbOBNDReq,\n    wbFULLReq,\n    wbMODL,\n    wbICONReq,\n    wbSCRI,\n    wbDEST,\n    wbYNAM,\n    wbZNAM,\n    wbStruct(DATA, '', [\n      wbInteger('Value', itS32),\n      wbFloat('Weight')\n    ], cpNormal, True),\n    wbFormIDCk(RNAM, 'Sound - Random/Looping', [SOUN])\n  ]);\n\n  wbQuadrantEnum := wbEnum([\n    {0} 'Bottom Left',\n    {1} 'Bottom Right',\n    {2} 'Top Left',\n    {3} 'Top Right'\n  ]);\n\n  if wbSimpleRecords then begin\n\n    wbRecord(LAND, 'Landscape', [\n      wbByteArray(DATA, 'Unknown'),\n      wbByteArray(VNML, 'Vertex Normals'),\n      wbByteArray(VHGT, 'Vertext Height Map'),\n      wbByteArray(VCLR, 'Vertex Colours'),\n\n      wbRArrayS('Layers', wbRUnion('Layer', [\n        wbRStructSK([0],'Base Layer', [\n          wbStructSK(BTXT, [1, 3], 'Base Layer Header', [\n            wbFormIDCk('Texture', [LTEX, NULL]),\n            wbInteger('Quadrant', itU8, wbQuadrantEnum),\n            wbByteArray('Unused', 1),\n            wbInteger('Layer', itS16)\n          ])\n        ], []),\n        wbRStructSK([0],'Alpha Layer', [\n          wbStructSK(ATXT, [1, 3], 'Alpha Layer Header', [\n            wbFormIDCk('Texture', [LTEX, NULL]),\n            wbInteger('Quadrant', itU8, wbQuadrantEnum),\n            wbByteArray('Unused', 1),\n            wbInteger('Layer', itS16)\n          ]),\n          wbByteArray(VTXT, 'Alpha Layer Data')\n        ], [])\n      ], [])),\n\n      wbArray(VTEX, 'Textures', wbFormIDCk('Texture', [LTEX, NULL]))\n    ]);\n\n  end else begin\n\n    wbRecord(LAND, 'Landscape', [\n      wbByteArray(DATA, 'Unknown'),\n      wbArray(VNML, 'Vertex Normals', wbStruct('Row', [\n        wbArray('Columns', wbStruct('Column', [\n          wbInteger('X', itU8),\n          wbInteger('Y', itU8),\n          wbInteger('Z', itU8)\n        ]), 33)\n      ]), 33),\n      wbStruct(VHGT, 'Vertext Height Map', [\n        wbFloat('Offset'),\n        wbArray('Rows', wbStruct('Row', [\n          wbArray('Columns', wbInteger('Column', itU8), 33)\n        ]), 33),\n        wbByteArray('Unused', 3)\n      ]),\n      wbArray(VCLR, 'Vertex Colours', wbStruct('Row', [\n        wbArray('Columns', wbStruct('Column', [\n          wbInteger('X', itU8),\n          wbInteger('Y', itU8),\n          wbInteger('Z', itU8)\n        ]), 33)\n      ]), 33),\n\n      wbRArrayS('Layers', wbRUnion('Layer', [\n        wbRStructSK([0],'Base Layer', [\n          wbStructSK(BTXT, [1, 3], 'Base Layer Header', [\n            wbFormIDCk('Texture', [LTEX, NULL]),\n            wbInteger('Quadrant', itU8, wbQuadrantEnum),\n            wbByteArray('Unused', 1),\n            wbInteger('Layer', itS16)\n          ])\n        ], []),\n        wbRStructSK([0],'Alpha Layer', [\n          wbStructSK(ATXT, [1, 3], 'Alpha Layer Header', [\n            wbFormIDCk('Texture', [LTEX, NULL]),\n            wbInteger('Quadrant', itU8, wbQuadrantEnum),\n            wbByteArray('Unused', 1),\n            wbInteger('Layer', itS16)\n          ]),\n          wbArrayS(VTXT, 'Alpha Layer Data', wbStructSK([0], 'Cell', [\n            wbInteger('Position', itU16, wbAtxtPosition),\n            wbByteArray('Unused', 2),\n            wbFloat('Opacity')\n          ]))\n        ], [])\n      ], [])),\n\n      wbArray(VTEX, 'Textures', wbFormIDCk('Texture', [LTEX, NULL]))\n    ]);\n\n  end;\n\n  wbRecord(LIGH, 'Light', [\n    wbEDIDReq,\n    wbOBNDReq,\n    wbMODL,\n    wbSCRI,\n    wbDEST,\n    wbFULL,\n    wbICON,\n    wbStruct(DATA, '', [\n      wbInteger('Time', itS32),\n      wbInteger('Radius', itU32),\n      wbStruct('Color', [\n        wbInteger('Red', itU8),\n        wbInteger('Green', itU8),\n        wbInteger('Blue', itU8),\n        wbInteger('Unused', itU8)\n      ]),\n      wbInteger('Flags', itU32, wbFlags([\n        {0x00000001} 'Dynamic',\n        {0x00000002} 'Can be Carried',\n        {0x00000004} 'Negative',\n        {0x00000008} 'Flicker',\n        {0x00000010} 'Unused',\n        {0x00000020} 'Off By Default',\n        {0x00000040} 'Flicker Slow',\n        {0x00000080} 'Pulse',\n        {0x00000100} 'Pulse Slow',\n        {0x00000200} 'Spot Light',\n        {0x00000400} 'Spot Shadow'\n      ])),\n      wbFloat('Falloff Exponent'),\n      wbFloat('FOV'),\n      wbInteger('Value', itU32),\n      wbFloat('Weight')\n    ], cpNormal, True),\n    wbFloat(FNAM, 'Fade value', cpNormal, True),\n    wbFormIDCk(SNAM, 'Sound', [SOUN])\n  ], False, nil, cpNormal, False, wbLIGHAfterLoad);\n\n  wbRecord(LSCR, 'Load Screen', [\n    wbEDIDReq,\n    wbICONReq,\n    wbDESCReq,\n    wbRArrayS('Locations', wbStructSK(LNAM, [0, 1], 'Location', [\n      wbFormIDCk('Direct', [CELL, WRLD, NULL]),\n      wbStructSK([0, 1], 'Indirect', [\n        wbFormIDCk('World', [NULL, WRLD]),\n        wbStructSK([0,1], 'Grid', [\n          wbInteger('Y', itS16),\n          wbInteger('X', itS16)\n        ])\n      ])\n    ])),\n    wbFormIDCk(WMI1, 'Load Screen Type', [LSCT])\n  ]);\n\n  wbRecord(LTEX, 'Landscape Texture', [\n    wbEDIDReq,\n    wbICON,\n    wbFormIDCk(TNAM, 'Texture', [TXST], False, cpNormal, True),\n    wbStruct(HNAM, 'Havok Data', [\n      wbInteger('Material Type', itU8, wbEnum([\n        {00} 'STONE',\n        {01} 'CLOTH',\n        {02} 'DIRT',\n        {03} 'GLASS',\n        {04} 'GRASS',\n        {05} 'METAL',\n        {06} 'ORGANIC',\n        {07} 'SKIN',\n        {08} 'WATER',\n        {09} 'WOOD',\n        {10} 'HEAVY STONE',\n        {11} 'HEAVY METAL',\n        {12} 'HEAVY WOOD',\n        {13} 'CHAIN',\n        {14} 'SNOW',\n        {15} 'ELEVATOR',\n        {16} 'HOLLOW METAL',\n        {17} 'SHEET METAL',\n        {18} 'SAND',\n        {19} 'BRIKEN CONCRETE',\n        {20} 'VEHILCE BODY',\n        {21} 'VEHILCE PART SOLID',\n        {22} 'VEHILCE PART HOLLOW',\n        {23} 'BARREL',\n        {24} 'BOTTLE',\n        {25} 'SODA CAN',\n        {26} 'PISTOL',\n        {27} 'RIFLE',\n        {28} 'SHOPPING CART',\n        {29} 'LUNCHBOX',\n        {30} 'BABY RATTLE',\n        {31} 'RUBER BALL'\n      ])),\n      wbInteger('Friction', itU8),\n      wbInteger('Restitution', itU8)\n    ], cpNormal, True),\n    wbInteger(SNAM, 'Texture Specular Exponent', itU8, nil, cpNormal, True),\n    wbRArrayS('Grasses', wbFormIDCk(GNAM, 'Grass', [GRAS]))\n  ]);\n\n  wbRecord(LVLC, 'Leveled Creature', [\n    wbEDIDReq,\n    wbOBNDReq,\n    wbInteger(LVLD, 'Chance none', itU8, nil, cpNormal, True),\n    wbInteger(LVLF, 'Flags', itU8, wbFlags([\n      {0x01} 'Calculate from all levels <= player''s level',\n      {0x02} 'Calculate for each item in count'\n    ]), cpNormal, True),\n    wbRArrayS('Leveled List Entries',\n      wbRStructExSK([0], [1], 'Leveled List Entry', [\n        wbStructExSK(LVLO , [0, 2], [3], 'Base Data', [\n          wbInteger('Level', itS16),\n          wbByteArray('Unused', 2),\n          wbFormIDCk('Reference', [CREA, LVLC]),\n          wbInteger('Count', itS16),\n          wbByteArray('Unused', 2)\n        ]),\n        wbCOED\n      ], []),\n    cpNormal, True),\n    wbMODL\n  ]);\n\n  wbRecord(LVLN, 'Leveled NPC', [\n    wbEDIDReq,\n    wbOBNDReq,\n    wbInteger(LVLD, 'Chance none', itU8, nil, cpNormal, True),\n    wbInteger(LVLF, 'Flags', itU8, wbFlags([\n      {0x01} 'Calculate from all levels <= player''s level',\n      {0x02} 'Calculate for each item in count'\n    ]), cpNormal, True),\n    wbRArrayS('Leveled List Entries',\n      wbRStructExSK([0], [1], 'Leveled List Entry', [\n        wbStructExSK(LVLO , [0, 2], [3], 'Base Data', [\n          wbInteger('Level', itS16),\n          wbByteArray('Unused', 2),\n          wbFormIDCk('Reference', [NPC_, LVLN]),\n          wbInteger('Count', itS16),\n          wbByteArray('Unused', 2)\n        ]),\n        wbCOED\n      ], []),\n    cpNormal, True),\n    wbMODL\n  ]);\n\n   wbRecord(LVLI, 'Leveled Item', [\n    wbEDIDReq,\n    wbOBNDReq,\n    wbInteger(LVLD, 'Chance none', itU8, nil, cpNormal, True),\n    wbInteger(LVLF, 'Flags', itU8, wbFlags([\n      {0x01} 'Calculate from all levels <= player''s level',\n      {0x02} 'Calculate for each item in count',\n      {0x04} 'Use All'\n    ]), cpNormal, True),\n    wbFormIDCk(LVLG, 'Global', [GLOB]),\n    wbRArrayS('Leveled List Entries',\n      wbRStructExSK([0], [1], 'Leveled List Entry', [\n        wbStructExSK(LVLO , [0, 2], [3], 'Base Data', [\n          wbInteger('Level', itS16),\n          wbByteArray('Unused', 2),\n          wbFormIDCk('Reference', [ARMO, AMMO, MISC, WEAP, BOOK, LVLI, KEYM, ALCH, NOTE, IMOD, CMNY, CCRD, CHIP]),\n          wbInteger('Count', itS16),\n          wbByteArray('Unused', 2)\n        ]),\n        wbCOED\n      ], [])\n    )\n  ]);\n\n  wbArchtypeEnum := wbEnum([\n    {00} 'Value Modifier',\n    {01} 'Script',\n    {02} 'Dispel',\n    {03} 'Cure Disease',\n    {04} '',\n    {05} '',\n    {06} '',\n    {07} '',\n    {08} '',\n    {09} '',\n    {10} '',\n    {11} 'Invisibility',\n    {12} 'Chameleon',\n    {13} 'Light',\n    {14} '',\n    {15} '',\n    {16} 'Lock',\n    {17} 'Open',\n    {18} 'Bound Item',\n    {19} 'Summon Creature',\n    {20} '',\n    {21} '',\n    {22} '',\n    {23} '',\n    {24} 'Paralysis',\n    {25} '',\n    {26} '',\n    {27} '',\n    {28} '',\n    {29} '',\n    {30} 'Cure Paralysis',\n    {31} 'Cure Addiction',\n    {32} 'Cure Poison',\n    {33} 'Concussion',\n    {34} 'Value And Parts',\n    {35} 'Limb Condition',\n    {36} 'Turbo'\n  ]);\n\n  wbRecord(MGEF, 'Base Effect', [\n    wbEDIDReq,\n    wbFULL,\n    wbDESCReq,\n    wbICON,\n    wbMODL,\n    wbStruct(DATA, 'Data', [\n      wbInteger('Flags', itU32, wbFlags([\n        {0x00000001} 'Hostile',\n        {0x00000002} 'Recover',\n        {0x00000004} 'Detrimental',\n        {0x00000008} '',\n        {0x00000010} 'Self',\n        {0x00000020} 'Touch',\n        {0x00000040} 'Target',\n        {0x00000080} 'No Duration',\n        {0x00000100} 'No Magnitude',\n        {0x00000200} 'No Area',\n        {0x00000400} 'FX Persist',\n        {0x00000800} '',\n        {0x00001000} 'Gory Visuals',\n        {0x00002000} 'Display Name Only',\n        {0x00004000} '',\n        {0x00008000} 'Radio Broadcast ??',\n        {0x00010000} '',\n        {0x00020000} '',\n        {0x00040000} '',\n        {0x00080000} 'Use skill',\n        {0x00100000} 'Use attribute',\n        {0x00200000} '',\n        {0x00400000} '',\n        {0x00800000} '',\n        {0x01000000} 'Painless',\n        {0x02000000} 'Spray projectile type (or Fog if Bolt is specified as well)',\n        {0x04000000} 'Bolt projectile type (or Fog if Spray is specified as well)',\n        {0x08000000} 'No Hit Effect',\n        {0x10000000} 'No Death Dispel',\n        {0x20000000} '????'\n      ])),\n      {04} wbFloat('Base cost (Unused)'),\n      {08} wbUnion('Assoc. Item', wbMGEFFAssocItemDecider, [\n             wbFormID('Unused', cpIgnore),\n             wbFormID('Assoc. Item'),\n             wbFormIDCk('Assoc. Script', [SCPT, NULL]), //Script\n             wbFormIDCk('Assoc. Item', [WEAP, ARMO, NULL]), //Bound Item\n             wbFormIDCk('Assoc. Creature', [CREA]) //Summon Creature\n           ], cpNormal, false, nil, wbMGEFFAssocItemAfterSet),\n      {12} wbInteger('Magic School (Unused)', itS32, wbEnum([\n      ], [\n        -1, 'None'\n      ])),\n      {16} wbInteger('Resistance Type', itS32, wbActorValueEnum),\n      {20} wbInteger('Counter effect count', itU16),\n      {22} wbByteArray('Unused', 2),\n      {24} wbFormIDCk('Light', [LIGH, NULL]),\n      {28} wbFloat('Projectile speed'),\n      {32} wbFormIDCk('Effect Shader', [EFSH, NULL]),\n      {36} wbFormIDCk('Object Display Shader', [EFSH, NULL]),\n      {40} wbFormIDCk('Effect sound', [NULL, SOUN]),\n      {44} wbFormIDCk('Bolt sound', [NULL, SOUN]),\n      {48} wbFormIDCk('Hit sound', [NULL, SOUN]),\n      {52} wbFormIDCk('Area sound', [NULL, SOUN]),\n      {56} wbFloat('Constant Effect enchantment factor  (Unused)'),\n      {60} wbFloat('Constant Effect barter factor (Unused)'),\n      {64} wbInteger('Archtype', itU32, wbArchtypeEnum, cpNormal, False, nil, wbMGEFArchtypeAfterSet),\n      {68} wbActorValue\n    ], cpNormal, True),\n    wbRArrayS('Counter Effects', wbFormIDCk(ESCE, 'Effect', [MGEF]), cpNormal, False, nil, wbCounterEffectsAfterSet)\n  ], False, nil, cpNormal, False, wbMGEFAfterLoad, wbMGEFAfterSet);\n\n  wbRecord(MISC, 'Misc. Item', [\n    wbEDIDReq,\n    wbOBNDReq,\n    wbFULL,\n    wbMODL,\n    wbICON,\n    wbSCRI,\n    wbDEST,\n    wbYNAM,\n    wbZNAM,\n    wbStruct(DATA, '', [\n      wbInteger('Value', itS32),\n      wbFloat('Weight')\n    ], cpNormal, True),\n    wbFormIDCk(RNAM, 'Sound - Random/Looping', [SOUN])\n  ]);\n\n  wbRecord(COBJ, 'Constructible Object', [\n    wbEDID,\n    wbOBND,\n    wbFULL,\n    wbMODL,\n    wbICON,\n    wbSCRI,\n    wbYNAM,\n    wbZNAM,\n    wbStruct(DATA, '', [\n      wbInteger('Value', itS32),\n      wbFloat('Weight')\n    ], cpNormal, True)\n  ]);\n\n  // floats are reported to change faces after copying\n  if True {wbSimpleRecords} then begin\n    wbFaceGen := wbRStruct('FaceGen Data', [\n      wbByteArray(FGGS, 'FaceGen Geometry-Symmetric', 0, cpNormal, True),\n      wbByteArray(FGGA, 'FaceGen Geometry-Asymmetric', 0, cpNormal, True),\n      wbByteArray(FGTS, 'FaceGen Texture-Symmetric', 0, cpNormal, True)\n    ], [], cpNormal, True);\n\n    wbFaceGenNPC := wbRStruct('FaceGen Data', [  // Arrays of 4bytes elements\n      wbByteArray(FGGS, 'FaceGen Geometry-Symmetric', 0, cpNormal, True),\n      wbByteArray(FGGA, 'FaceGen Geometry-Asymmetric', 0, cpNormal, True),\n      wbByteArray(FGTS, 'FaceGen Texture-Symmetric', 0, cpNormal, True)\n    ], [], cpNormal, True, wbActorTemplateUseModelAnimation);\n  end else begin\n    wbFaceGen := wbRStruct('FaceGen Data', [\n      wbArray(FGGS, 'FaceGen Geometry-Symmetric',  wbFloat('Value'), [], cpNormal, True),\n      wbArray(FGGA, 'FaceGen Geometry-Asymmetric', wbFloat('Value'), [], cpNormal, True),\n      wbArray(FGTS, 'FaceGen Texture-Symmetric',   wbFloat('Value'), [], cpNormal, True)\n    ], [], cpNormal, True);\n\n    wbFaceGenNPC := wbRStruct('FaceGen Data', [\n      wbArray(FGGS, 'FaceGen Geometry-Symmetric',  wbFloat('Value'), [], cpNormal, True),\n      wbArray(FGGA, 'FaceGen Geometry-Asymmetric', wbFloat('Value'), [], cpNormal, True),\n      wbArray(FGTS, 'FaceGen Texture-Symmetric',   wbFloat('Value'), [], cpNormal, True)\n    ], [], cpNormal, True, wbActorTemplateUseModelAnimation);\n  end;\n\n  wbRecord(NPC_, 'Non-Player Character', [\n    wbEDIDReq,\n    wbOBNDReq,\n    wbFULLActor,\n    wbMODLActor,\n    wbStruct(ACBS, 'Configuration', [\n      {00} wbInteger('Flags', itU32, wbFlags([\n             {0x000001} 'Female',\n             {0x000002} 'Essential',\n             {0x000004} 'Is CharGen Face Preset',\n             {0x000008} 'Respawn',\n             {0x000010} 'Auto-calc stats',\n             {0x000020} '',\n             {0x000040} '',\n             {0x000080} 'PC Level Mult',\n             {0x000100} 'Use Template',\n             {0x000200} 'No Low Level Processing',\n             {0x000400} '',\n             {0x000800} 'No Blood Spray',\n             {0x001000} 'No Blood Decal',\n             {0x002000} '',\n             {0x004000} '',\n             {0x008000} '',\n             {0x010000} '',\n             {0x020000} '',\n             {0x040000} '',\n             {0x080000} '',\n             {0x100000} 'No VATS Melee',\n           {0x00200000} '',\n           {0x00400000} 'Can be all races',\n           {0x00800000} 'Autocalc Service',\n           {0x01000000} '',\n           {0x02000000} '',\n           {0x04000000} 'No Knockdowns',\n           {0x08000000} 'Not Pushable',\n           {0x10000000} 'Unknown 28',\n           {0x20000000} '',\n           {0x40000000} 'No Rotating To Head-track',\n           {0x80000000} ''\n           ], [\n             {0x000001 Female} wbActorTemplateUseTraits,\n             {0x000002 Essential} wbActorTemplateUseBaseData,\n             {0x000004 Is CharGen Face Preset} nil,\n             {0x000008 Respawn} wbActorTemplateUseBaseData,\n             {0x000010 Auto-calc stats} wbActorTemplateUseStats,\n             {0x000020 } nil,\n             {0x000040 } nil,\n             {0x000080 PC Level Mult} wbActorTemplateUseStats,\n             {0x000100 Use Template} nil,\n             {0x000200 No Low Level Processing} wbActorTemplateUseBaseData,\n             {0x000400 } nil,\n             {0x000800 No Blood Spray} wbActorTemplateUseModelAnimation,\n             {0x001000 No Blood Decal} wbActorTemplateUseModelAnimation,\n             {0x002000 } nil,\n             {0x004000 } nil,\n             {0x008000 } nil,\n             {0x010000 } nil,\n             {0x020000 } nil,\n             {0x040000 } nil,\n             {0x080000 } nil,\n             {0x100000 No VATS Melee} nil,\n           {0x00200000 } nil,\n           {0x00400000 Can be all races} nil,\n           {0x00800000 } nil,\n           {0x01000000 } nil,\n           {0x02000000 } nil,\n           {0x04000000 No Knockdowns} nil,\n           {0x08000000 Not Pushable} wbActorTemplateUseModelAnimation,\n           {0x10000000 } nil,\n           {0x20000000 } nil,\n           {0x40000000 No Rotating To Head-track} wbActorTemplateUseModelAnimation,\n           {0x80000000 } nil\n           ])),\n      {04} wbInteger('Fatigue', itU16, nil, cpNormal, True, wbActorTemplateUseStats),\n      {06} wbInteger('Barter gold', itU16, nil, cpNormal, False, wbActorTemplateUseAIData),\n      {08} wbUnion('Level', wbCreaLevelDecider, [\n             wbInteger('Level', itS16, nil, cpNormal, True, wbActorTemplateUseStats),\n             wbInteger('Level Mult', itS16, wbDiv(1000), cpNormal, True, wbActorTemplateUseStats)\n           ], cpNormal, True, wbActorTemplateUseStats),\n      {10} wbInteger('Calc min', itU16, nil, cpNormal, True, wbActorTemplateUseStats),\n      {12} wbInteger('Calc max', itU16, nil, cpNormal, True, wbActorTemplateUseStats),\n      {14} wbInteger('Speed Multiplier', itU16, nil, cpNormal, True, wbActorTemplateUseStats),\n      {16} wbFloat('Karma (Alignment)', cpNormal, False, 1, -1, wbActorTemplateUseTraits),\n      {20} wbInteger('Disposition Base', itS16, nil, cpNormal, False, wbActorTemplateUseTraits),\n      {22} wbInteger('Template Flags', itU16, wbTemplateFlags)\n    ], cpNormal, True),\n    wbRArrayS('Factions',\n      wbStructSK(SNAM, [0], 'Faction', [\n        wbFormIDCk('Faction', [FACT]),\n        wbInteger('Rank', itU8),\n        wbByteArray('Unused', 3)\n      ]),\n    cpNormal, False, nil, nil, wbActorTemplateUseFactions),\n    wbFormIDCk(INAM, 'Death item', [LVLI], False, cpNormal, False, wbActorTemplateUseTraits),\n    wbFormIDCk(VTCK, 'Voice', [VTYP], False, cpNormal, True, wbActorTemplateUseTraits),\n    wbFormIDCk(TPLT, 'Template', [LVLN, NPC_]),\n    wbFormIDCk(RNAM, 'Race', [RACE], False, cpNormal, True, wbActorTemplateUseTraits),\n    wbSPLOs,\n    wbFormIDCk(EITM, 'Unarmed Attack Effect', [ENCH, SPEL], False, cpNormal, False, wbActorTemplateUseActorEffectList),\n    wbInteger(EAMT, 'Unarmed Attack Animation', itU16, wbAttackAnimationEnum, cpNormal, True, False, wbActorTemplateUseActorEffectList),\n    wbDESTActor,\n    wbSCRIActor,\n    wbRArrayS('Items', wbCNTO, cpNormal, False, nil, nil, wbActorTemplateUseInventory),\n    wbAIDT,\n    wbRArray('Packages', wbFormIDCk(PKID, 'Package', [PACK]), cpNormal, False, nil, nil, wbActorTemplateUseAIPackages),\n    wbArrayS(KFFZ, 'Animations', wbStringLC('Animation'), 0, cpNormal, False, nil, nil, wbActorTemplateUseModelAnimation),\n    wbFormIDCk(CNAM, 'Class', [CLAS], False, cpNormal, True, wbActorTemplateUseTraits),\n    wbStruct(DATA, '', [\n      {00} wbInteger('Base Health', itS32),\n      {04} wbArray('Attributes', wbInteger('Attribute', itU8), [\n            'Strength',\n            'Perception',\n            'Endurance',\n            'Charisma',\n            'Intelligence',\n            'Agility',\n            'Luck'\n          ], cpNormal, False, wbActorAutoCalcDontShow),\n          wbByteArray('Unused'{, 14 - only present in old record versions})\n    ], cpNormal, True, wbActorTemplateUseStats),\n    wbStruct(DNAM, '', [\n      {00} wbArray('Skill Values', wbInteger('Skill', itU8), [\n             'Barter',\n             'Big Guns (obsolete)',\n             'Energy Weapons',\n             'Explosives',\n             'Lockpick',\n             'Medicine',\n             'Melee Weapons',\n             'Repair',\n             'Science',\n             'Guns',\n             'Sneak',\n             'Speech',\n             'Survival',\n             'Unarmed'\n           ]),\n      {14} wbArray('Skill Offsets', wbInteger('Skill', itU8), [\n             'Barter',\n             'Big Guns (obsolete)',\n             'Energy Weapons',\n             'Explosives',\n             'Lockpick',\n             'Medicine',\n             'Melee Weapons',\n             'Repair',\n             'Science',\n             'Guns',\n             'Sneak',\n             'Speech',\n             'Survival',\n             'Unarmed'\n           ])\n    ], cpNormal, False, wbActorTemplateUseStatsAutoCalc),\n    wbRArrayS('Head Parts',\n      wbFormIDCk(PNAM, 'Head Part', [HDPT]),\n    cpNormal, False, nil, nil, wbActorTemplateUseModelAnimation),\n    wbFormIDCk(HNAM, 'Hair', [HAIR], False, cpNormal, False, wbActorTemplateUseModelAnimation),\n    wbFloat(LNAM, 'Hair length', cpNormal, False, 1, -1, wbActorTemplateUseModelAnimation),\n    wbFormIDCk(ENAM, 'Eyes', [EYES], False, cpNormal, False, wbActorTemplateUseModelAnimation),\n    wbStruct(HCLR, 'Hair color', [\n      wbInteger('Red', itU8),\n      wbInteger('Green', itU8),\n      wbInteger('Blue', itU8),\n      wbByteArray('Unused', 1)\n    ], cpNormal, True, wbActorTemplateUseModelAnimation),\n    wbFormIDCk(ZNAM, 'Combat Style', [CSTY], False, cpNormal, False, wbActorTemplateUseTraits),\n    wbInteger(NAM4, 'Impact Material Type', itU32, wbImpactMaterialTypeEnum, cpNormal, True, False, wbActorTemplateUseModelAnimation),\n    wbFaceGenNPC,\n    wbInteger(NAM5, 'Unknown', itU16, nil, cpNormal, True, False, nil, nil, 255),\n    wbFloat(NAM6, 'Height', cpNormal, True, 1, -1, wbActorTemplateUseTraits),\n    wbFloat(NAM7, 'Weight', cpNormal, True, 1, -1, wbActorTemplateUseTraits)\n  ], True, nil, cpNormal, False, wbNPCAfterLoad);\n\n  wbPKDTFlags := wbFlags([\n          {0x00000001} 'Offers Services',\n          {0x00000002} 'Must reach location',\n          {0x00000004} 'Must complete',\n          {0x00000008} 'Lock doors at package start',\n          {0x00000010} 'Lock doors at package end',\n          {0x00000020} 'Lock doors at location',\n          {0x00000040} 'Unlock doors at package start',\n          {0x00000080} 'Unlock doors at package end',\n          {0x00000100} 'Unlock doors at location',\n          {0x00000200} 'Continue if PC near',\n          {0x00000400} 'Once per day',\n          {0x00000800} '',\n          {0x00001000} 'Skip fallout behavior',\n          {0x00002000} 'Always run',\n          {0x00004000} '',\n          {0x00008000} '',\n          {0x00010000} '',\n          {0x00020000} 'Always sneak',\n          {0x00040000} 'Allow swimming',\n          {0x00080000} 'Allow falls',\n          {0x00100000} 'Head-Tracking off',\n          {0x00200000} 'Weapons unequipped',\n          {0x00400000} 'Defensive combat',\n          {0x00800000} 'Weapon Drawn',\n          {0x01000000} 'No idle anims',\n          {0x02000000} 'Pretend In Combat',\n          {0x04000000} 'Continue During Combat',\n          {0x08000000} 'No Combat Alert',\n          {0x10000000} 'No Warn/Attack Behaviour',\n          {0x20000000} '',\n          {0x40000000} '',\n          {0x80000000} ''\n        ]);\n\n  wbPKDTType := wbEnum([\n           {0} 'Find',\n           {1} 'Follow',\n           {2} 'Escort',\n           {3} 'Eat',\n           {4} 'Sleep',\n           {5} 'Wander',\n           {6} 'Travel',\n           {7} 'Accompany',\n           {8} 'Use Item At',\n           {9} 'Ambush',\n          {10} 'Flee Not Combat',\n          {11} 'Package Type 11',\n          {12} 'Sandbox',\n          {13} 'Patrol',\n          {14} 'Guard',\n          {15} 'Dialogue',\n          {16} 'Use Weapon',\n          {17} 'Package Type 17',\n          {18} 'Combat Controller',\n          {19} 'Package Type 19',\n          {20} 'Package Type 20',\n          {21} 'Alarm',\n          {22} 'Flee',\n          {23} 'TressPass',\n          {24} 'Spectator',\n          {25} 'Package Type 25',\n          {26} 'Package Type 26',\n          {27} 'Package Type 27',\n          {28} 'Dialogue 2',\n          {29} 'Package Type 29',\n          {30} 'Package Type 30',\n          {31} 'Package Type 31',\n          {32} 'Package Type 32',\n          {33} 'Package Type 33',\n          {34} 'Package Type 34',\n          {35} 'Package Type 35',\n          {36} 'Package Type 36',\n          {37} 'Package Type 37',\n          {38} 'Package Type 38',\n          {39} 'Package Type 39',\n          {40} 'Package Type 40'\n        ]);\n\n  wbObjectTypeEnum := wbEnum([\n          ' NONE',\n          'Activators',\n          'Armor',\n          'Books',\n          'Clothing',\n          'Containers',\n          'Doors',\n          'Ingredients',\n          'Lights',\n          'Misc',\n          'Flora',\n          'Furniture',\n          'Weapons: Any',\n          'Ammo',\n          'NPCs',\n          'Creatures',\n          'Keys',\n          'Alchemy',\n          'Food',\n          ' All: Combat Wearable',\n          ' All: Wearable',\n          'Weapons: Ranged',\n          'Weapons: Melee',\n          'Weapons: NONE',\n          'Actor Effects: Any',\n          'Actor Effects: Range Target',\n          'Actor Effects: Range Touch',\n          'Actor Effects: Range Self',\n//          '',\n          'Actors: Any'\n        ]);\n\n\n  wbPKDTSpecificFlagsUnused := True;\n\n  wbRecord(PACK, 'Package', [\n    wbEDIDReq,\n    wbStruct(PKDT, 'General', [\n      wbInteger('General Flags', itU32, wbPKDTFlags),\n      wbInteger('Type', itU8, wbPKDTType),\n      wbByteArray('Unused', 1),\n      wbInteger('Fallout Behavior Flags', itU16, wbFlags([\n        {0x00000001}'Hellos To Player',\n        {0x00000002}'Random Conversations',\n        {0x00000004}'Observe Combat Behavior',\n        {0x00000008}'Unknown 4',\n        {0x00000010}'Reaction To Player Actions',\n        {0x00000020}'Friendly Fire Comments',\n        {0x00000040}'Aggro Radius Behavior',\n        {0x00000080}'Allow Idle Chatter',\n        {0x00000100}'Avoid Radiation'\n      ], True)),\n      wbUnion('Type Specific Flags', wbPKDTSpecificFlagsDecider, [\n        wbEmpty('Type Specific Flags (missing)', cpIgnore, False, nil, True),\n        wbInteger('Type Specific Flags - Find', itU16, wbFlags([\n          {0x00000001}'',\n          {0x00000002}'',\n          {0x00000004}'',\n          {0x00000008}'',\n          {0x00000010}'',\n          {0x00000020}'',\n          {0x00000040}'',\n          {0x00000080}'',\n          {0x00000100}'Find - Allow Buying',\n          {0x00000200}'Find - Allow Killing',\n          {0x00000400}'Find - Allow Stealing'\n        ], wbPKDTSpecificFlagsUnused)),\n        wbInteger('Type Specific Flags - Follow', itU16, wbFlags([], wbPKDTSpecificFlagsUnused)),\n        wbInteger('Type Specific Flags - Escort', itU16, wbFlags([\n          {0x00000001}'',\n          {0x00000002}'',\n          {0x00000004}'',\n          {0x00000008}'',\n          {0x00000010}'',\n          {0x00000020}'',\n          {0x00000040}'',\n          {0x00000080}'',\n          {0x00000100}'Escort - Allow Buying',\n          {0x00000200}'Escort - Allow Killing',\n          {0x00000400}'Escort - Allow Stealing'\n        ], wbPKDTSpecificFlagsUnused)),\n        wbInteger('Type Specific Flags - Eat', itU16, wbFlags([\n          {0x00000001}'',\n          {0x00000002}'',\n          {0x00000004}'',\n          {0x00000008}'',\n          {0x00000010}'',\n          {0x00000020}'',\n          {0x00000040}'',\n          {0x00000080}'',\n          {0x00000100}'Eat - Allow Buying',\n          {0x00000200}'Eat - Allow Killing',\n          {0x00000400}'Eat - Allow Stealing'\n        ], wbPKDTSpecificFlagsUnused)),\n        wbInteger('Type Specific Flags - Sleep', itU16, wbFlags([], wbPKDTSpecificFlagsUnused)),\n        wbInteger('Type Specific Flags - Wander', itU16, wbFlags([\n          {0x00000001}'Wander - No Eating',\n          {0x00000002}'Wander - No Sleeping',\n          {0x00000004}'Wander - No Conversation',\n          {0x00000008}'Wander - No Idle Markers',\n          {0x00000010}'Wander - No Furniture',\n          {0x00000020}'Wander - No Wandering'\n        ], wbPKDTSpecificFlagsUnused)),\n        wbInteger('Type Specific Flags - Travel', itU16, wbFlags([], wbPKDTSpecificFlagsUnused)),\n        wbInteger('Type Specific Flags - Accompany', itU16, wbFlags([], wbPKDTSpecificFlagsUnused)),\n        wbInteger('Type Specific Flags - Use Item At', itU16, wbFlags([\n          {0x00000001}'',\n          {0x00000002}'Use Item At - Sit Down',\n          {0x00000004}'',\n          {0x00000008}'',\n          {0x00000010}'',\n          {0x00000020}'',\n          {0x00000040}'',\n          {0x00000080}'',\n          {0x00000100}'Use Item At - Allow Buying',\n          {0x00000200}'Use Item At - Allow Killing',\n          {0x00000400}'Use Item At - Allow Stealing'\n        ], wbPKDTSpecificFlagsUnused)),\n        wbInteger('Type Specific Flags - Ambush', itU16, wbFlags([\n          {0x00000001}'Ambush - Hide While Ambushing'\n        ], wbPKDTSpecificFlagsUnused)),\n        wbInteger('Type Specific Flags - Flee Not Combat', itU16, wbFlags([], wbPKDTSpecificFlagsUnused)),\n        wbInteger('Type Specific Flags - ?', itU16, wbFlags([], wbPKDTSpecificFlagsUnused)),\n        wbInteger('Type Specific Flags - Sandbox', itU16, wbFlags([\n          {0x00000001}'Sandbox - No Eating',\n          {0x00000002}'Sandbox - No Sleeping',\n          {0x00000004}'Sandbox - No Conversation',\n          {0x00000008}'Sandbox - No Idle Markers',\n          {0x00000010}'Sandbox - No Furniture',\n          {0x00000020}'Sandbox - No Wandering'\n        ], wbPKDTSpecificFlagsUnused)),\n        wbInteger('Type Specific Flags - Patrol', itU16, wbFlags([], wbPKDTSpecificFlagsUnused)),\n        wbInteger('Type Specific Flags - Guard', itU16, wbFlags([\n          {0x00000001}'',\n          {0x00000002}'',\n          {0x00000004}'Guard - Remain Near Reference to Guard'\n        ], wbPKDTSpecificFlagsUnused)),\n        wbInteger('Type Specific Flags - Dialogue', itU16, wbFlags([], wbPKDTSpecificFlagsUnused)),\n        wbInteger('Type Specific Flags - Use Weapon', itU16, wbFlags([], wbPKDTSpecificFlagsUnused))\n      ]),\n      wbByteArray('Unused', 2)\n    ], cpNormal, True, nil, 2),\n    wbRStruct('Locations', [\n      wbStruct(PLDT, 'Location 1', [\n        wbInteger('Type', itS32, wbEnum([     // Byte + filler\n          {0} 'Near reference',\n          {1} 'In cell',\n          {2} 'Near current location',\n          {3} 'Near editor location',\n          {4} 'Object ID',\n          {5} 'Object Type',\n          {6} 'Near linked reference',\n          {7} 'At package location'\n        ])),\n        wbUnion('Location', wbPxDTLocationDecider, [\n          wbFormIDCkNoReach('Reference', [REFR, PGRE, PMIS, PBEA, ACHR, ACRE, PLYR], True),\n          wbFormIDCkNoReach('Cell', [CELL]),\n          wbByteArray('Unused', 4, cpIgnore),\n          wbByteArray('Unused', 4, cpIgnore),\n          wbFormIDCkNoReach('Object ID', [ACTI, DOOR, STAT, FURN, CREA, SPEL, NPC_, CONT, ARMO, AMMO, MISC, WEAP, BOOK, KEYM, ALCH, LIGH, CHIP, CMNY, CCRD, IMOD]),\n          wbInteger('Object Type', itU32, wbObjectTypeEnum),\n          wbByteArray('Unused', 4, cpIgnore),\n          wbByteArray('Unused', 4, cpIgnore)\n        ]),\n        wbInteger('Radius', itS32)\n      ], cpNormal, True),\n      wbStruct(PLD2, 'Location 2', [\n        wbInteger('Type', itS32, wbEnum([\n          {0} 'Near reference',\n          {1} 'In cell',\n          {2} 'Near current location',\n          {3} 'Near editor location',\n          {4} 'Object ID',\n          {5} 'Object Type',\n          {6} 'Near linked reference',\n          {7} 'At package location'\n        ])),\n        wbUnion('Location', wbPxDTLocationDecider, [\n          wbFormIDCkNoReach('Reference', [REFR, PGRE, PMIS, PBEA, ACHR, ACRE, PLYR], True),\n          wbFormIDCkNoReach('Cell', [CELL]),\n          wbByteArray('Unused', 4, cpIgnore),\n          wbByteArray('Unused', 4, cpIgnore),\n          wbFormIDCkNoReach('Object ID', [ACTI, DOOR, STAT, FURN, CREA, SPEL, NPC_, CONT, ARMO, AMMO, MISC, WEAP, BOOK, KEYM, ALCH, LIGH, CHIP, CMNY, CCRD, IMOD]),\n          wbInteger('Object Type', itU32, wbObjectTypeEnum),\n          wbByteArray('Unused', 4, cpIgnore),\n          wbByteArray('Unused', 4, cpIgnore)\n        ]),\n        wbInteger('Radius', itS32)\n      ])\n    ], [], cpNormal, False, nil, True),\n    wbStruct(PSDT, 'Schedule', [\n      wbInteger('Month', itS8),\n      wbInteger('Day of week', itS8, wbEnum([\n        'Sunday',\n        'Monday',\n        'Tuesday',\n        'Wednesday',\n        'Thursday',\n        'Friday',\n        'Saturday',\n        'Weekdays',\n        'Weekends',\n        'Monday, Wednesday, Friday',\n        'Tuesday, Thursday'\n      ], [\n        -1, 'Any'\n      ])),\n      wbInteger('Date', itU8),\n      wbInteger('Time', itS8),\n      wbInteger('Duration', itS32)\n    ], cpNormal, True),\n    wbStruct(PTDT, 'Target 1', [\n      wbInteger('Type', itS32, wbEnum([\n        {0} 'Specific Reference',\n        {1} 'Object ID',\n        {2} 'Object Type',\n        {3} 'Linked Reference'\n      ]), cpNormal, False, nil, nil, 2),\n      wbUnion('Target', wbPxDTLocationDecider, [\n        wbFormIDCkNoReach('Reference', [ACHR, ACRE, REFR, PGRE, PMIS, PBEA, PLYR], True),\n        wbFormIDCkNoReach('Object ID', [ACTI, DOOR, STAT, FURN, CREA, SPEL, NPC_, LVLN, LVLC, CONT, ARMO, AMMO, MISC, WEAP, BOOK, KEYM, ALCH, LIGH, FACT, FLST, IDLM, CHIP, CMNY, CCRD, IMOD]),\n        wbInteger('Object Type', itU32, wbObjectTypeEnum),\n        wbByteArray('Unused', 4, cpIgnore)\n      ]),\n      wbInteger('Count / Distance', itS32),\n      wbFloat('Unknown')\n    ], cpNormal, False, nil, 3),\n    wbCTDAs,\n    wbRStruct('Idle Animations', [\n      wbInteger(IDLF, 'Flags', itU8, wbFlags([\n        'Run in Sequence',\n        '',\n        'Do Once'\n      ]), cpNormal, True),\n      wbStruct(IDLC, '', [\n        wbInteger( 'Animation Count', itU8),\n        wbByteArray('Unused', 3)\n      ], cpNormal, True, nil, 1),\n      wbFloat(IDLT, 'Idle Timer Setting', cpNormal, True),\n      wbArray(IDLA, 'Animations', wbFormIDCk('Animation', [IDLE]), 0, nil, wbIDLAsAfterSet, cpNormal, True),\n      wbByteArray(IDLB, 'Unused', 4, cpIgnore)\n    ], [], cpNormal, False, nil, False, nil {cannot be totally removed , wbAnimationsAfterSet}),\n    wbFormIDCk(CNAM, 'Combat Style', [CSTY]),\n    wbEmpty(PKED, 'Eat Marker'),\n    wbInteger(PKE2, 'Escort Distance', itU32),\n    wbFloat(PKFD, 'Follow - Start Location - Trigger Radius'),\n    wbStruct(PKPT, 'Patrol Flags', [\n      wbInteger('Repeatable', itU8, wbEnum(['No', 'Yes']), cpNormal, False, nil, nil, 1),\n      wbByteArray('Unused', 1)\n    ], cpNormal, False, nil, 1),\n    wbStruct(PKW3, 'Use Weapon Data', [\n      wbInteger('Flags', itU32, wbFlags([\n        'Always Hit',\n        '',\n        '',\n        '',\n        '',\n        '',\n        '',\n        '',\n        'Do No Damage',\n        '',\n        '',\n        '',\n        '',\n        '',\n        '',\n        '',\n        'Crouch To Reload',\n        '',\n        '',\n        '',\n        '',\n        '',\n        '',\n        '',\n        'Hold Fire When Blocked'\n      ])),\n      wbInteger('Fire Rate', itU8, wbEnum([\n        'Auto Fire',\n        'Volley Fire'\n      ])),\n      wbInteger('Fire Count', itU8, wbEnum([\n        'Number of Bursts',\n        'Repeat Fire'\n      ])),\n      wbInteger('Number of Bursts', itU16),\n      wbStruct('Shoots Per Volleys', [\n        wbInteger('Min', itU16),\n        wbInteger('Max', itU16)\n      ]),\n      wbStruct('Pause Between Volleys', [\n        wbFloat('Min'),\n        wbFloat('Max')\n      ]),\n      wbByteArray('Unused', 4)\n    ]),\n    wbStruct(PTD2, 'Target 2', [\n      wbInteger('Type', itS32, wbEnum([\n        {0} 'Specific reference',\n        {1} 'Object ID',\n        {2} 'Object Type',\n        {3} 'Linked Reference'\n      ])),\n      wbUnion('Target', wbPxDTLocationDecider, [\n        wbFormIDCkNoReach('Reference', [ACHR, ACRE, REFR, PGRE, PMIS, PBEA, PLYR], True),\n        wbFormIDCkNoReach('Object ID', [ACTI, DOOR, STAT, FURN, CREA, SPEL, NPC_, LVLN, LVLC, CONT, ARMO, AMMO, MISC, WEAP, BOOK, KEYM, ALCH, LIGH, FACT, FLST, CHIP, CMNY, CCRD, IMOD]),\n        wbInteger('Object Type', itU32, wbObjectTypeEnum),\n        wbByteArray('Unused', 4, cpIgnore)\n      ]),\n      wbInteger('Count / Distance', itS32),\n      wbFloat('Unknown')\n    ], cpNormal, False, nil, 3),\n    wbEmpty(PUID, 'Use Item Marker'),\n    wbEmpty(PKAM, 'Ambush Marker'),\n    wbStruct(PKDD, 'Dialogue Data', [\n      wbFloat('FOV'),\n      wbFormIDCk('Topic', [DIAL, NULL]),\n      wbInteger('Flags', itU32, wbFlags([\n        'No Headtracking',\n        '',\n        '',\n        '',\n        '',\n        '',\n        '',\n        '',\n        'Don''t Control Target Movement'\n      ])),\n      wbByteArray('Unused', 4),\n      wbInteger('Dialogue Type', itU32, wbEnum([\n        'Conversation',\n        'Say To'\n      ])),\n      wbByteArray('Unknown', 4)\n    ], cpNormal, False, nil, 3),\n    wbStruct(PLD2, 'Location 2 (again??)', [\n      wbInteger('Type', itS32, wbEnum([\n        {0} 'Near reference',\n        {1} 'In cell',\n        {2} 'Near current location',\n        {3} 'Near editor location',\n        {4} 'Object ID',\n        {5} 'Object Type',\n        {6} 'Near linked reference',\n        {7} 'At package location'\n      ])),\n      wbUnion('Location', wbPxDTLocationDecider, [\n        wbFormIDCkNoReach('Reference', [REFR, PGRE, PMIS, PBEA, ACHR, ACRE, PLYR], True),\n        wbFormIDCkNoReach('Cell', [CELL]),\n        wbByteArray('Unused', 4, cpIgnore),\n        wbByteArray('Unused', 4, cpIgnore),\n        wbFormIDCkNoReach('Object ID', [ACTI, DOOR, STAT, FURN, CREA, SPEL, NPC_, CONT, ARMO, AMMO, MISC, WEAP, BOOK, KEYM, ALCH, LIGH, CHIP, CMNY, CCRD, IMOD]),\n        wbInteger('Object Type', itU32, wbObjectTypeEnum),\n        wbByteArray('Unused', 4, cpIgnore),\n        wbByteArray('Unused', 4, cpIgnore)\n      ]),\n      wbInteger('Radius', itS32)\n    ]),\n    wbRStruct('OnBegin', [\n      wbEmpty(POBA, 'OnBegin Marker', cpNormal, True),\n      wbFormIDCk(INAM, 'Idle', [IDLE, NULL], False, cpNormal, True),\n      wbEmbeddedScriptReq,\n      wbFormIDCk(TNAM, 'Topic', [DIAL, NULL], False, cpNormal, True)\n    ], [], cpNormal, True),\n    wbRStruct('OnEnd', [\n      wbEmpty(POEA, 'OnEnd Marker', cpNormal, True),\n      wbFormIDCk(INAM, 'Idle', [IDLE, NULL], False, cpNormal, True),\n      wbEmbeddedScriptReq,\n      wbFormIDCk(TNAM, 'Topic', [DIAL, NULL], False, cpNormal, True)\n    ], [], cpNormal, True),\n    wbRStruct('OnChange', [\n      wbEmpty(POCA, 'OnChange Marker', cpNormal, True),\n      wbFormIDCk(INAM, 'Idle', [IDLE, NULL], False, cpNormal, True),\n      wbEmbeddedScriptReq,\n      wbFormIDCk(TNAM, 'Topic', [DIAL, NULL], False, cpNormal, True)\n    ], [], cpNormal, True)\n  ], False, nil, cpNormal, False, wbPACKAfterLoad);\n\n  wbRecord(QUST, 'Quest', [\n    wbEDIDReq,\n    wbSCRI,\n    wbFULL,\n    wbICON,\n    wbStruct(DATA, 'General', [\n      wbInteger('Flags', itU8, wbFlags([\n        {0x01} 'Start game enabled',\n        {0x02} '',\n        {0x04} 'Allow repeated conversation topics',\n        {0x08} 'Allow repeated stages',\n        {0x10} 'Unknown 4'\n      ])),\n      wbInteger('Priority', itU8),\n      wbByteArray('Unused', 2),\n      wbFloat('Quest Delay')\n    ], cpNormal, True, nil, 3),\n    wbCTDAs,\n    wbRArrayS('Stages', wbRStructSK([0], 'Stage', [\n      wbInteger(INDX, 'Stage Index', itS16),\n      wbRArray('Log Entries', wbRStruct('Log Entry', [\n        wbInteger(QSDT, 'Stage Flags', itU8, wbFlags([\n          {0x01} 'Complete Quest',\n          {0x02} 'Fail Quest'\n        ])),\n        wbCTDAs,\n        wbString(CNAM, 'Log Entry', 0, cpTranslate),\n        wbEmbeddedScriptReq,\n        wbFormIDCk(NAM0, 'Next Quest', [QUST])\n      ], []))\n    ], [])),\n    wbRArray('Objectives', wbRStruct('Objective', [\n      wbInteger(QOBJ, 'Objective Index', itS32),\n      wbString(NNAM, 'Description', 0, cpNormal, True),\n      wbRArray('Targets', wbRStruct('Target', [\n        wbStruct(QSTA, 'Target', [\n          wbFormIDCkNoReach('Target', [REFR, PGRE, PMIS, PBEA, ACRE, ACHR], True),\n          wbInteger('Flags', itU8, wbFlags([\n            {0x01} 'Compass Marker Ignores Locks'\n          ])),\n          wbByteArray('Unused', 3)\n        ]),\n        wbCTDAs\n      ], []))\n    ], []))\n  ]);\n\n  wbHeadPartIndexEnum := wbEnum([\n    'Head',\n    'Ears',\n    'Mouth',\n    'Teeth Lower',\n    'Teeth Upper',\n    'Tongue',\n    'Left Eye',\n    'Right Eye'\n  ]);\n\n  wbBodyPartIndexEnum := wbEnum([\n    'Upper Body',\n    'Left Hand',\n    'Right Hand',\n    'Upper Body Texture'\n  ]);\n\n  wbRecord(RACE, 'Race', [\n    wbEDIDReq,\n    wbFULLReq,\n    wbDESCReq,\n    wbXNAMs,\n    wbStruct(DATA, '', [\n      wbArrayS('Skill Boosts', wbStructSK([0], 'Skill Boost', [\n        wbInteger('Skill', itS8, wbActorValueEnum),\n        wbInteger('Boost', itS8)\n      ]), 7),\n      wbByteArray('Unused', 2),\n      wbFloat('Male Height'),\n      wbFloat('Female Height'),\n      wbFloat('Male Weight'),\n      wbFloat('Female Weight'),\n      wbInteger('Flags', itU32, wbFlags([\n        'Playable',\n        '',\n        'Child'\n      ]))\n    ], cpNormal, True),\n    wbFormIDCk(ONAM, 'Older', [RACE]),\n    wbFormIDCk(YNAM, 'Younger', [RACE]),\n    wbEmpty(NAM2, 'Unknown Marker', cpNormal, True),\n    wbArray(VTCK, 'Voices', wbFormIDCk('Voice', [VTYP]), ['Male', 'Female'], cpNormal, True),\n    wbArray(DNAM, 'Default Hair Styles', wbFormIDCk('Default Hair Style', [HAIR, NULL]), ['Male', 'Female'], cpNormal, True),\n    wbArray(CNAM, 'Default Hair Colors', wbInteger('Default Hair Color', itU8, wbEnum([\n      'Bleached',\n      'Brown',\n      'Chocolate',\n      'Platinum',\n      'Cornsilk',\n      'Suede',\n      'Pecan',\n      'Auburn',\n      'Ginger',\n      'Honey',\n      'Gold',\n      'Rosewood',\n      'Black',\n      'Chestnut',\n      'Steel',\n      'Champagne'\n    ])), ['Male', 'Female'], cpNormal, True),\n    wbFloat(PNAM, 'FaceGen - Main clamp', cpNormal, True),\n    wbFloat(UNAM, 'FaceGen - Face clamp', cpNormal, True),\n    wbByteArray(ATTR, 'Unused', 0, cpNormal, True),\n    wbRStruct('Head Data', [\n      wbEmpty(NAM0, 'Head Data Marker', cpNormal, True),\n      wbRStruct('Male Head Data', [\n        wbEmpty(MNAM, 'Male Data Marker', cpNormal, True),\n        wbRArrayS('Parts', wbRStructSK([0], 'Part', [\n          wbInteger(INDX, 'Index', itU32, wbHeadPartIndexEnum),\n          wbMODLReq,\n          wbICON\n        ], [], cpNormal, False, nil, False, nil, wbHeadPartsAfterSet), cpNormal, True)\n      ], [], cpNormal, True),\n      wbRStruct('Female Head Data', [\n        wbEmpty(FNAM, 'Female Data Marker', cpNormal, True),\n        wbRArrayS('Parts', wbRStructSK([0], 'Part', [\n          wbInteger(INDX, 'Index', itU32, wbHeadPartIndexEnum),\n          wbMODLReq,\n          wbICON\n        ], [], cpNormal, False, nil, False, nil, wbHeadPartsAfterSet), cpNormal, True)\n      ], [], cpNormal, True)\n    ], [], cpNormal, True),\n    wbRStruct('Body Data', [\n      wbEmpty(NAM1, 'Body Data Marker', cpNormal, True),\n      wbRStruct('Male Body Data', [\n        wbEmpty(MNAM, 'Male Data Marker'),\n        wbRArrayS('Parts', wbRStructSK([0], 'Part', [\n          wbInteger(INDX, 'Index', itU32, wbBodyPartIndexEnum),\n          wbICON,\n          wbMODLReq\n        ], []), cpNormal, True)\n      ], [], cpNormal, True),\n      wbRStruct('Female Body Data', [\n        wbEmpty(FNAM, 'Female Data Marker', cpNormal, True),\n        wbRArrayS('Parts', wbRStructSK([0], 'Part', [\n          wbInteger(INDX, 'Index', itU32, wbBodyPartIndexEnum),\n          wbICON,\n          wbMODLReq\n        ], []), cpNormal, True)\n      ], [], cpNormal, True)\n    ], [], cpNormal, True),\n    wbArrayS(HNAM, 'Hairs', wbFormIDCk('Hair', [HAIR]), 0, cpNormal, True),\n    wbArrayS(ENAM, 'Eyes', wbFormIDCk('Eye', [EYES]),  0,  cpNormal, True),\n    wbRStruct('FaceGen Data', [\n      wbRStruct('Male FaceGen Data', [\n        wbEmpty(MNAM, 'Male Data Marker', cpNormal, True),\n        wbFaceGen,\n        wbInteger(SNAM, 'Unknown', itU16, nil, cpNormal, True)\n      ], [], cpNormal, True),\n      wbRStruct('Female FaceGen Data', [\n        wbEmpty(FNAM, 'Female Data Marker', cpNormal, True),\n        wbFaceGen,\n        wbInteger(SNAM, 'Unknown', itU16, nil, cpNormal, True)\t// will effectivly overwrite the SNAM from the male :)\n      ], [], cpNormal, True)\n    ], [], cpNormal, True)\n  ]);\n\n  wbRecord(REFR, 'Placed Object', [\n    wbEDID,\n    {\n    wbStruct(RCLR, 'Linked Reference Color (Old Format?)', [\n      wbStruct('Link Start Color', [\n        wbInteger('Red', itU8),\n        wbInteger('Green', itU8),\n        wbInteger('Blue', itU8),\n        wbByteArray('Unused', 1)\n      ]),\n      wbStruct('Link End Color', [\n        wbInteger('Red', itU8),\n        wbInteger('Green', itU8),\n        wbInteger('Blue', itU8),\n        wbByteArray('Unused', 1)\n      ])\n    ], cpIgnore),}\n    wbByteArray(RCLR, 'Unused', 0, cpIgnore),\n    wbFormIDCk(NAME, 'Base', [TREE, SOUN, ACTI, DOOR, STAT, FURN, CONT, ARMO, AMMO, LVLN, LVLC,\n                              MISC, WEAP, BOOK, KEYM, ALCH, LIGH, GRAS, ASPC, IDLM, ARMA, CHIP,\n                              MSTT, NOTE, PWAT, SCOL, TACT, TERM, TXST, CCRD, IMOD, CMNY], False, cpNormal, True),\n    wbFormIDCk(XEZN, 'Encounter Zone', [ECZN]),\n\n    {--- ?? ---}\n    wbXRGD,\n    wbXRGB,\n\n    {--- Primitive ---}\n    wbStruct(XPRM, 'Primitive', [\n      wbStruct('Bounds', [\n        wbFloat('X', cpNormal, True, 2, 4),\n        wbFloat('Y', cpNormal, True, 2, 4),\n        wbFloat('Z', cpNormal, True, 2, 4)\n      ]),\n      wbStruct('Color', [\n        {84} wbFloat('Red', cpNormal, False, 255, 0),\n        {88} wbFloat('Green', cpNormal, False, 255, 0),\n        {92} wbFloat('Blue', cpNormal, False, 255, 0)\n      ]),\n      wbFloat('Unknown'),\n      wbInteger('Type', itU32, wbEnum([\n        'None',\n        'Box',\n        'Sphere',\n        'Portal Box'\n      ]))\n    ]),\n    wbInteger(XTRI, 'Collision Layer', itU32, wbEnum([\n      'Unidentified',\n      'Static',\n      'AnimStatic',\n      'Transparent',\n      'Clutter',\n      'Weapon',\n      'Projectile',\n      'Spell',\n      'Biped',\n      'Trees',\n      'Props',\n      'Water',\n      'Trigger',\n      'Terrain',\n      'Trap',\n      'Non Collidable',\n      'Cloud Trap',\n      'Ground',\n      'Portal',\n      'Debris Small',\n      'Debris Large',\n      'Acustic Space',\n      'Actor Zone',\n      'Projectile Zone',\n      'Gas Trap',\n      'Shell Casing',\n      'Transparent Small',\n      'Invisible Wall',\n      'Transparent Small Anim',\n      'Dead Bip',\n      'Char Controller',\n      'Avoid Box',\n      'Collision Box',\n      'Camera Sphere',\n      'Door Detection',\n      'Camera Pick',\n      'Item Pick',\n      'Line Of Sight',\n      'Path Pick',\n      'Custom Pick 1',\n      'Custom Pick 2',\n      'Spell Explosion',\n      'Dropping Pick'\n    ])),\n    wbEmpty(XMBP, 'MultiBound Primitive Marker'),\n\n    {--- Bound Contents ---}\n\n    {--- Bound Data ---}\n    wbStruct(XMBO, 'Bound Half Extents', [\n      wbFloat('X'),\n      wbFloat('Y'),\n      wbFloat('Z')\n    ]),\n\n    {--- Teleport ---}\n    wbStruct(XTEL, 'Teleport Destination', [\n      wbFormIDCk('Door', [REFR], True),\n      wbPosRot,\n      wbInteger('Flags', itU32, wbFlags([\n        'No Alarm'\n      ]))\n    ]),\n\n    {--- Map Data ---}\n    wbRStruct('Map Marker', [\n      wbEmpty(XMRK, 'Map Marker Data'),\n      wbInteger(FNAM, 'Flags', itU8, wbFlags([\n        {0x01} 'Visible',\n        {0x02} 'Can Travel To',\n        {0x04} '\"Show All\" Hidden'\n      ]), cpNormal, True),\n      wbFULLReq,\n      wbStruct(TNAM, '', [\n        wbInteger('Type', itU8, wbEnum([\n          'None',\n          'City',\n          'Settlement',\n          'Encampment',\n          'Natural Landmark',\n          'Cave',\n          'Factory',\n          'Monument',\n          'Military',\n          'Office',\n          'Town Ruins',\n          'Urban Ruins',\n          'Sewer Ruins',\n          'Metro',\n          'Vault'\n        ])),\n        wbByteArray('Unused', 1)\n      ], cpNormal, True),\n      wbFormIDCk(WMI1, 'Reputation', [REPU])\n    ], []),\n\n    {--- Audio Data ---}\n    wbRStruct('Audio Data', [\n      wbEmpty(MMRK, 'Audio Marker'),\n      wbUnknown(FULL),\n      wbFormIDCk(CNAM, 'Audio Location', [ALOC]),\n      wbInteger(BNAM, 'Flags', itU32, wbFlags(['Use Controller Values'])),\n      wbFloat(MNAM, 'Layer 2 Trigger %', cpNormal, True, 100),\n      wbFloat(NNAM, 'Layer 3 Trigger %', cpNormal, True, 100)\n    ], []),\n\n    wbInteger(XSRF, 'Special Rendering Flags', itU32, wbFlags([\n      'Unknown 0',\n      'Imposter',\n      'Use Full Shader in LOD'\n    ])),\n    wbByteArray(XSRD, 'Special Rendering Data', 4),\n\n    {--- X Target Data ---}\n    wbFormIDCk(XTRG, 'Target', [REFR, ACRE, ACHR, PGRE, PMIS, PBEA], True),\n\n    {--- Leveled Actor ----}\n    wbXLCM,\n\n    {--- Patrol Data ---}\n    wbRStruct('Patrol Data', [\n      wbFloat(XPRD, 'Idle Time', cpNormal, True),\n      wbEmpty(XPPA, 'Patrol Script Marker', cpNormal, True),\n      wbFormIDCk(INAM, 'Idle', [IDLE, NULL], False, cpNormal, True),\n      wbEmbeddedScriptReq,\n      wbFormIDCk(TNAM, 'Topic', [DIAL, NULL], False, cpNormal, True)\n    ], []),\n\n    {--- Radio ---}\n    wbStruct(XRDO, 'Radio Data', [\n      wbFloat('Range Radius'),\n      wbInteger('Broadcast Range Type', itU32, wbEnum([\n        'Radius',\n        'Everywhere',\n        'Worldspace and Linked Interiors',\n        'Linked Interiors',\n        'Current Cell Only'\n      ])),\n      wbFloat('Static Percentage'),\n      wbFormIDCkNoReach('Position Reference', [REFR, ACRE, ACHR, PGRE, PMIS, PBEA, NULL])\n    ]),\n\n    {--- Ownership ---}\n    wbRStruct('Ownership', [\n      wbXOWN,\n      wbInteger(XRNK, 'Faction rank', itS32)\n    ], [XCMT, XCMO]),\n\n    {--- Lock ---}\n    wbStruct(XLOC, 'Lock Data', [\n      wbInteger('Level', itU8),\n      wbByteArray('Unused', 3),\n      wbFormIDCkNoReach('Key', [KEYM, NULL]),\n      wbInteger('Flags', itU8, wbFlags(['', '', 'Leveled Lock'])),\n      wbByteArray('Unused', 3),\n      wbByteArray('Unknown', 8)\n    ], cpNormal, False, nil, 5),\n\n    {--- Extra ---}\n    wbInteger(XCNT, 'Count', itS32),\n    wbFloat(XRDS, 'Radius'),\n    wbFloat(XHLP, 'Health'),\n    wbFloat(XRAD, 'Radiation'),\n    wbFloat(XCHG, 'Charge'),\n    wbRStruct('Ammo', [\n      wbFormIDCk(XAMT, 'Type', [AMMO], False, cpNormal, True),\n      wbInteger(XAMC, 'Count', itS32, nil, cpNormal, True)\n    ], []),\n\n    {--- Reflected By / Refracted By ---}\n    wbRArrayS('Reflected/Refracted By',\n      wbStructSK(XPWR, [0], 'Water', [\n        wbFormIDCk('Reference', [REFR]),\n        wbInteger('Type', itU32, wbFlags([\n          'Reflection',\n          'Refraction'\n        ]))\n      ])\n    ),\n\n    {--- Lit Water ---}\n    wbRArrayS('Lit Water',\n      wbFormIDCk(XLTW, 'Water', [REFR])\n    ),\n\n    {--- Decals ---}\n    wbRArrayS('Linked Decals',\n      wbStructSK(XDCR, [0], 'Decal', [\n        wbFormIDCk('Reference', [REFR]),\n        wbUnknown\n      ])\n    ),\n\n    {--- Linked Ref ---}\n    wbFormIDCk(XLKR, 'Linked Reference', [REFR, ACRE, ACHR, PGRE, PMIS, PBEA, PLYR]),\n    wbStruct(XCLP, 'Linked Reference Color', [\n      wbStruct('Link Start Color', [\n        wbInteger('Red', itU8),\n        wbInteger('Green', itU8),\n        wbInteger('Blue', itU8),\n        wbByteArray('Unused', 1)\n      ]),\n      wbStruct('Link End Color', [\n        wbInteger('Red', itU8),\n        wbInteger('Green', itU8),\n        wbInteger('Blue', itU8),\n        wbByteArray('Unused', 1)\n      ])\n    ]),\n\n    {--- Activate Parents ---}\n    wbRStruct('Activate Parents', [\n      wbInteger(XAPD, 'Flags', itU8, wbFlags([\n        'Parent Activate Only'\n      ], True)),\n      wbRArrayS('Activate Parent Refs',\n        wbStructSK(XAPR, [0], 'Activate Parent Ref', [\n          wbFormIDCk('Reference', [REFR, ACRE, ACHR, PGRE, PMIS, PBEA, PLYR]),\n          wbFloat('Delay')\n        ])\n      )\n    ], []),\n\n    wbString(XATO, 'Activation Prompt'),\n\n    {--- Enable Parent ---}\n    wbXESP,\n\n    {--- Emittance ---}\n    wbFormIDCk(XEMI, 'Emittance', [LIGH, REGN]),\n\n    {--- MultiBound ---}\n    wbFormIDCk(XMBR, 'MultiBound Reference', [REFR]),\n\n    {--- Flags ---}\n    wbInteger(XACT, 'Action Flag', itU32, wbFlags([\n      'Use Default',\n      'Activate',\n      'Open',\n      'Open by Default'\n    ])),\n    wbEmpty(ONAM, 'Open by Default'),\n    wbEmpty(XIBS, 'Ignored By Sandbox'),\n\n    {--- Generated Data ---}\n    wbStruct(XNDP, 'Navigation Door Link', [\n      wbFormIDCk('Navigation Mesh', [NAVM]),\n      wbInteger('Teleport Marker Triangle', itS16, wbREFRNavmeshTriangleToStr, wbStringToInt),\n      wbByteArray('Unused', 2)\n    ]),\n\n    wbArray(XPOD, 'Portal Data', wbFormIDCk('Room', [REFR, NULL]), 2),\n    wbStruct(XPTL, 'Portal Data', [\n      wbStruct('Size', [\n        wbFloat('Width', cpNormal, False, 2),\n        wbFloat('Height', cpNormal, False, 2)\n      ]),\n      wbStruct('Position', [\n        wbFloat('X'),\n        wbFloat('Y'),\n        wbFloat('Z')\n      ]),\n      wbStruct('Rotation (Quaternion?)', [\n        wbFloat('q1'),\n        wbFloat('q2'),\n        wbFloat('q3'),\n        wbFloat('q4')\n      ])\n    ]),\n\n    wbInteger(XSED, 'SpeedTree Seed', itU8),\n\n    wbRStruct('Room Data', [\n      wbStruct(XRMR, 'Header', [\n        wbInteger('Linked Rooms Count', itU16),\n        wbByteArray('Unknown', 2)\n      ]),\n      wbRArrayS('Linked Rooms',\n        wbFormIDCk(XLRM, 'Linked Room', [REFR])\n      )\n    ], []),\n\n    wbStruct(XOCP, 'Occlusion Plane Data', [\n      wbStruct('Size', [\n        wbFloat('Width', cpNormal, False, 2),\n        wbFloat('Height', cpNormal, False, 2)\n      ]),\n      wbStruct('Position', [\n        wbFloat('X'),\n        wbFloat('Y'),\n        wbFloat('Z')\n      ]),\n      wbStruct('Rotation (Quaternion?)', [\n        wbFloat('q1'),\n        wbFloat('q2'),\n        wbFloat('q3'),\n        wbFloat('q4')\n      ])\n    ]),\n    wbArray(XORD, 'Linked Occlusion Planes', wbFormIDCk('Plane', [REFR, NULL]), [\n      'Right',\n      'Left',\n      'Bottom',\n      'Top'\n    ]),\n\n    wbXLOD,\n\n    {--- 3D Data ---}\n    wbXSCL,\n    wbDATAPosRot\n  ], True, wbPlacedAddInfo, cpNormal, False, wbREFRAfterLoad);\n\n\n  wbRecord(REGN, 'Region', [\n    wbEDID,\n    wbICON,\n    wbStruct(RCLR, 'Map Color', [\n      wbInteger('Red', itU8),\n      wbInteger('Green', itU8),\n      wbInteger('Blue', itU8),\n      wbByteArray('Unused', 1)\n    ], cpNormal, True),\n    wbFormIDCkNoReach(WNAM, 'Worldspace', [WRLD]),\n\n    wbRArray('Region Areas', wbRStruct('Region Area', [\n      wbInteger(RPLI, 'Edge Fall-off', itU32),\n      wbArray(RPLD, 'Region Point List Data', wbStruct('Point', [\n        wbFloat('X'),\n        wbFloat('Y')\n      ]), 0, wbRPLDAfterLoad)\n    ], [])),\n\n    wbRArrayS('Region Data Entries', wbRStructSK([0], 'Region Data Entry', [\n      {always starts with an RDAT}\n      wbStructSK(RDAT, [0], 'Data Header', [\n        wbInteger('Type', itU32, wbEnum([\n          {0}'',\n          {1}'',\n          {2}'Objects',\n          {3}'Weather',\n          {4}'Map',\n          {5}'Land',\n          {6}'Grass',\n          {7}'Sound',\n          {8}'Imposter',\n          {9}''\n        ])),\n        wbInteger('Flags', itU8, wbFlags([\n          'Override'\n        ])),\n        wbInteger('Priority', itU8),\n        wbByteArray('Unused')\n      ], cpNormal, True),\n\n      {followed by one of these: }\n\n      {--- Objects ---}\n      wbArray(RDOT, 'Objects', wbStruct('Object', [\n        wbFormIDCk('Object', [TREE, STAT, LTEX]),\n        wbInteger('Parent Index', itU16, wbHideFFFF),\n        wbByteArray('Unused', 2),\n        wbFloat('Density'),\n        wbInteger('Clustering', itU8),\n        wbInteger('Min Slope', itU8),\n        wbInteger('Max Slope', itU8),\n        wbInteger('Flags', itU8, wbFlags([\n          {0}'Conform to slope',\n          {1}'Paint Vertices',\n          {2}'Size Variance +/-',\n          {3}'X +/-',\n          {4}'Y +/-',\n          {5}'Z +/-',\n          {6}'Tree',\n          {7}'Huge Rock'\n        ])),\n        wbInteger('Radius wrt Parent', itU16),\n        wbInteger('Radius', itU16),\n        wbFloat('Min Height'),\n        wbFloat('Max Height'),\n        wbFloat('Sink'),\n        wbFloat('Sink Variance'),\n        wbFloat('Size Variance'),\n        wbStruct('Angle Variance', [\n          wbInteger('X', itU16),\n          wbInteger('Y', itU16),\n          wbInteger('Z', itU16)\n        ]),\n        wbByteArray('Unused', 2),\n        wbByteArray('Unknown', 4)\n      ]), 0, nil, nil, cpNormal, False, wbREGNObjectsDontShow),\n\n      {--- Map ---}\n      wbString(RDMP, 'Map Name', 0, cpTranslate, False, wbREGNMapDontShow),\n\n      {--- Grass ---}\n      wbArrayS(RDGS, 'Grasses', wbStructSK([0], 'Grass', [\n        wbFormIDCk('Grass', [GRAS]),\n        wbByteArray('Unknown',4)\n      ]), 0, cpNormal, False, nil, nil, wbREGNGrassDontShow),\n\n      {--- Sound ---}\n      wbInteger(RDMD, 'Music Type', itU32, wbMusicEnum, cpIgnore, False, False, wbNeverShow),\n      wbFormIDCk(RDMO, 'Music', [MUSC], False, cpNormal, False, wbREGNSoundDontShow),\n      wbFormIDCk(RDSI, 'Incidental MediaSet', [MSET], False, cpNormal, False, wbREGNSoundDontShow),\n      wbRArray('Battle MediaSets', wbFormIDCk(RDSB, 'Battle MediaSet', [MSET]), cpNormal, False, nil, nil, wbREGNSoundDontShow),\n      wbArrayS(RDSD, 'Sounds', wbStructSK([0], 'Sound', [\n        wbFormIDCk('Sound', [SOUN]),\n        wbInteger('Flags', itU32, wbFlags([\n          'Pleasant',\n          'Cloudy',\n          'Rainy',\n          'Snowy'\n        ])),\n        wbInteger('Chance', itU32, wbScaledInt4ToStr, wbScaledInt4ToInt)\n      ]), 0, cpNormal, False, nil, nil, wbREGNSoundDontShow),\n\n      {--- Weather ---}\n      wbArrayS(RDWT, 'Weather Types', wbStructSK([0], 'Weather Type', [\n        wbFormIDCk('Weather', [WTHR]),\n        wbInteger('Chance', itU32),\n        wbFormIDCk('Global', [GLOB, NULL])\n      ]), 0, cpNormal, False, nil, nil, wbREGNWeatherDontShow),\n\n      {--- Imposter ---}\n      wbArrayS(RDID, 'Imposters', wbFormIDCk('Imposter', [REFR]), 0, cpNormal, False, nil, nil, wbREGNImposterDontShow)\n    ], []))\n  ], True);\n\n  wbRecord(SOUN, 'Sound', [\n    wbEDIDReq,\n    wbOBNDReq,\n    wbString(FNAM, 'Sound Filename'),\n    wbInteger(RNAM, 'Random Chance %', itU8),\n    wbRUnion('Sound Data', [\n      wbStruct(SNDD, 'Sound Data', [\n        wbInteger('Minimum Attentuation Distance', itU8, wbMul(5)),\n        wbInteger('Maximum Attentuation Distance', itU8, wbMul(100)),\n        wbInteger('Frequency Adjustment %', itS8),\n        wbByteArray('Unused', 1),\n        wbInteger('Flags', itU32, wbFlags([\n          {0x0001} 'Random Frequency Shift',\n          {0x0002} 'Play At Random',\n          {0x0004} 'Environment Ignored',\n          {0x0008} 'Random Location',\n          {0x0010} 'Loop',\n          {0x0020} 'Menu Sound',\n          {0x0040} '2D',\n          {0x0080} '360 LFE',\n          {0x0100} 'Dialogue Sound',\n          {0x0200} 'Envelope Fast',\n          {0x0400} 'Envelope Slow',\n          {0x0800} '2D Radius',\n          {0x1000} 'Mute When Submerged',\n          {0x2000} 'Start at Random Position'\n        ])),\n        wbInteger('Static attentuation cdB', itS16),\n        wbInteger('Stop time ', itU8),\n        wbInteger('Start time ', itU8),\n        wbArray('Attenuation Curve', wbInteger('Point', itS16), 5),\n        wbInteger('Reverb Attenuation Control', itS16),\n        wbInteger('Priority', itS32),\n//        wbByteArray('Unknown', 8)\n        wbInteger('x', itS32),\n        wbInteger('y', itS32)\n\n      ], cpNormal, True),\n      wbStruct(SNDX, 'Sound Data', [\n        wbInteger('Minimum attentuation distance', itU8, wbMul(5)),\n        wbInteger('Maximum attentuation distance', itU8, wbMul(100)),\n        wbInteger('Frequency adjustment %', itS8),\n        wbByteArray('Unused', 1),\n        wbInteger('Flags', itU32, wbFlags([\n          {0x0001} 'Random Frequency Shift',\n          {0x0002} 'Play At Random',\n          {0x0004} 'Environment Ignored',\n          {0x0008} 'Random Location',\n          {0x0010} 'Loop',\n          {0x0020} 'Menu Sound',\n          {0x0040} '2D',\n          {0x0080} '360 LFE',\n          {0x0100} 'Dialogue Sound',\n          {0x0200} 'Envelope Fast',\n          {0x0400} 'Envelope Slow',\n          {0x0800} '2D Radius',\n          {0x1000} 'Mute When Submerged'\n        ])),\n        wbInteger('Static attentuation cdB', itS16),\n        wbInteger('Stop time ', itU8),\n        wbInteger('Start time ', itU8)\n      ], cpNormal, True)\n    ], [], cpNormal, True),\n    wbArray(ANAM, 'Attenuation Curve', wbInteger('Point', itS16), 5, nil, nil, cpNormal, False, wbNeverShow),\n    wbInteger(GNAM, 'Reverb Attenuation Control', itS16, nil, cpNormal, False, False, wbNeverShow),\n    wbInteger(HNAM, 'Priority', itS32, nil, cpNormal, False, False, wbNeverShow)\n  ], False, nil, cpNormal, False, wbSOUNAfterLoad);\n\n  wbRecord(SPEL, 'Actor Effect', [\n    wbEDIDReq,\n    wbFULL,\n    wbStruct(SPIT, '', [\n      wbInteger('Type', itU32, wbEnum([\n        {0} 'Actor Effect',\n        {1} 'Disease',\n        {2} 'Power',\n        {3} 'Lesser Power',\n        {4} 'Ability',\n        {5} 'Poison',\n        {6} '',\n        {7} '',\n        {8} '',\n        {9} '',\n       {10} 'Addiction'\n      ])),\n      wbInteger('Cost (Unused)', itU32),\n      wbInteger('Level (Unused)', itU32, wbEnum([\n        {0} 'Unused'\n      ])),\n      wbInteger('Flags', itU8, wbFlags([\n        {0x00000001} 'No Auto-Calc',\n        {0x00000002} 'Immune to Silence 1?',\n        {0x00000004} 'PC Start Effect',\n        {0x00000008} 'Immune to Silence 2?',\n        {0x00000010} 'Area Effect Ignores LOS',\n        {0x00000020} 'Script Effect Always Applies',\n        {0x00000040} 'Disable Absorb/Reflect',\n        {0x00000080} 'Force Touch Explode'\n      ])),\n      wbByteArray('Unused', 3)\n    ], cpNormal, True),\n    wbEffectsReq\n  ]);\n\n  wbRecord(STAT, 'Static', [\n    wbEDIDReq,\n    wbOBNDReq,\n    wbMODL,\n    wbInteger(BRUS, 'Passthrough Sound', itS8, wbEnum([\n      'BushA',\n      'BushB',\n      'BushC',\n      'BushD',\n      'BushE',\n      'BushF',\n      'BushG',\n      'BushH',\n      'BushI',\n      'BushJ'\n    ], [\n      -1, 'NONE'\n    ])),\n    wbFormIDCk(RNAM, 'Sound - Looping/Random', [SOUN])\n  ]);\n\n  wbRecord(TES4, 'Main File Header', [\n    wbStruct(HEDR, 'Header', [\n      wbFloat('Version'),\n      wbInteger('Number of Records', itU32),\n      wbInteger('Next Object ID', itU32)\n    ], cpNormal, True),\n    wbByteArray(OFST, 'Unknown', 0, cpIgnore),\n    wbByteArray(DELE, 'Unknown', 0, cpIgnore),\n    wbString(CNAM, 'Author', 0, cpTranslate, True),\n    wbString(SNAM, 'Description', 0, cpTranslate),\n    wbRArray('Master Files', wbRStruct('Master File', [\n      wbString(MAST, 'Filename', 0, cpNormal, True),\n      wbByteArray(DATA, 'Unused', 8, cpIgnore, True)\n    ], [ONAM])),\n    wbArray(ONAM, 'Overriden Forms', wbFormIDCk('Form', [REFR, ACHR, ACRE, PMIS, PBEA, PGRE, LAND, NAVM]), 0, nil, nil, cpNormal, False, wbTES4ONAMDontShow),\n    wbByteArray(SCRN, 'Screenshot')\n  ], True, nil, cpNormal, True, wbRemoveOFST);\n\n  wbRecord(TREE, 'Tree', [\n    wbEDIDReq,\n    wbOBNDReq,\n    wbMODLReq,\n    wbICONReq,\n    wbArrayS(SNAM, 'SpeedTree Seeds', wbInteger('SpeedTree Seed', itU32), 0, cpNormal, True),\n    wbStruct(CNAM, 'Tree Data', [\n      wbFloat('Leaf Curvature'),\n      wbFloat('Minimum Leaf Angle'),\n      wbFloat('Maximum Leaf Angle'),\n      wbFloat('Branch Dimming Value'),\n      wbFloat('Leaf Dimming Value'),\n      wbInteger('Shadow Radius', itS32),\n      wbFloat('Rock Speed'),\n      wbFloat('Rustle Speed')\n    ], cpNormal, True),\n    wbStruct(BNAM, 'Billboard Dimensions', [\n      wbFloat('Width'),\n      wbFloat('Height')\n    ], cpNormal, True)\n  ]);\nend;\n\nprocedure DefineFNVf;\nbegin\n  wbRecord(WATR, 'Water', [\n    wbEDIDReq,\n    wbFULL,\n    wbString(NNAM, 'Noise Map', 0, cpNormal, True),\n    wbInteger(ANAM, 'Opacity', itU8, nil, cpNormal, True),\n    wbInteger(FNAM, 'Flags', itU8, wbFlags([\n      {0}'Causes Damage',\n      {1}'Reflective'\n    ]), cpNormal, True),\n    wbString(MNAM, 'Material ID', 0, cpNormal, True),\n    wbFormIDCk(SNAM, 'Sound', [SOUN]),\n    wbFormIDCk(XNAM, 'Actor Effect', [SPEL]),\n    wbInteger(DATA, 'Damage', itU16, nil, cpNormal, True, True),\n    wbRUnion('Visual Data', [\n      wbStruct(DNAM, 'Visual Data', [\n        wbFloat('Unknown'),\n        wbFloat('Unknown'),\n        wbFloat('Unknown'),\n        wbFloat('Unknown'),\n        wbFloat('Water Properties - Sun Power'),\n        wbFloat('Water Properties - Reflectivity Amount'),\n        wbFloat('Water Properties - Fresnel Amount'),\n        wbByteArray('Unused', 4),\n        wbFloat('Fog Properties - Above Water - Fog Distance - Near Plane'),\n        wbFloat('Fog Properties - Above Water - Fog Distance - Far Plane'),\n        wbStruct('Shallow Color', [\n          wbInteger('Red', itU8),\n          wbInteger('Green', itU8),\n          wbInteger('Blue', itU8),\n          wbByteArray('Unused', 1)\n        ]),\n        wbStruct('Deep Color', [\n          wbInteger('Red', itU8),\n          wbInteger('Green', itU8),\n          wbInteger('Blue', itU8),\n          wbByteArray('Unused', 1)\n        ]),\n        wbStruct('Reflection Color', [\n          wbInteger('Red', itU8),\n          wbInteger('Green', itU8),\n          wbInteger('Blue', itU8),\n          wbByteArray('Unused', 1)\n        ]),\n        wbByteArray('Unused', 4),\n        wbFloat('Rain Simulator - Force'),\n        wbFloat('Rain Simulator - Velocity'),\n        wbFloat('Rain Simulator - Falloff'),\n        wbFloat('Rain Simulator - Dampner'),\n        wbFloat('Displacement Simulator - Starting Size'),\n        wbFloat('Displacement Simulator - Force'),\n        wbFloat('Displacement Simulator - Velocity'),\n        wbFloat('Displacement Simulator - Falloff'),\n        wbFloat('Displacement Simulator - Dampner'),\n        wbFloat('Rain Simulator - Starting Size'),\n        wbFloat('Noise Properties - Normals - Noise Scale'),\n        wbFloat('Noise Properties - Noise Layer One - Wind Direction'),\n        wbFloat('Noise Properties - Noise Layer Two - Wind Direction'),\n        wbFloat('Noise Properties - Noise Layer Three - Wind Direction'),\n        wbFloat('Noise Properties - Noise Layer One - Wind Speed'),\n        wbFloat('Noise Properties - Noise Layer Two - Wind Speed'),\n        wbFloat('Noise Properties - Noise Layer Three - Wind Speed'),\n        wbFloat('Noise Properties - Normals - Depth Falloff Start'),\n        wbFloat('Noise Properties - Normals - Depth Falloff End'),\n        wbFloat('Fog Properties - Above Water - Fog Amount'),\n        wbFloat('Noise Properties - Normals - UV Scale'),\n        wbFloat('Fog Properties - Under Water - Fog Amount'),\n        wbFloat('Fog Properties - Under Water - Fog Distance - Near Plane'),\n        wbFloat('Fog Properties - Under Water - Fog Distance - Far Plane'),\n        wbFloat('Water Properties - Distortion Amount'),\n        wbFloat('Water Properties - Shininess'),\n        wbFloat('Water Properties - Reflection HDR Multiplier'),\n        wbFloat('Water Properties - Light Radius'),\n        wbFloat('Water Properties - Light Brightness'),\n        wbFloat('Noise Properties - Noise Layer One - UV Scale'),\n        wbFloat('Noise Properties - Noise Layer Two - UV Scale'),\n        wbFloat('Noise Properties - Noise Layer Three - UV Scale'),\n        wbFloat('Noise Properties - Noise Layer One - Amplitude Scale'),\n        wbFloat('Noise Properties - Noise Layer Two - Amplitude Scale'),\n        wbFloat('Noise Properties - Noise Layer Three - Amplitude Scale')\n      ], cpNormal, True, nil, 46),\n      wbStruct(DATA, 'Visual Data', [\n        wbFloat('Unknown'),\n        wbFloat('Unknown'),\n        wbFloat('Unknown'),\n        wbFloat('Unknown'),\n        wbFloat('Water Properties - Sun Power'),\n        wbFloat('Water Properties - Reflectivity Amount'),\n        wbFloat('Water Properties - Fresnel Amount'),\n        wbByteArray('Unused', 4),\n        wbFloat('Fog Properties - Above Water - Fog Distance - Near Plane'),\n        wbFloat('Fog Properties - Above Water - Fog Distance - Far Plane'),\n        wbStruct('Shallow Color', [\n          wbInteger('Red', itU8),\n          wbInteger('Green', itU8),\n          wbInteger('Blue', itU8),\n          wbByteArray('Unused', 1)\n        ]),\n        wbStruct('Deep Color', [\n          wbInteger('Red', itU8),\n          wbInteger('Green', itU8),\n          wbInteger('Blue', itU8),\n          wbByteArray('Unused', 1)\n        ]),\n        wbStruct('Reflection Color', [\n          wbInteger('Red', itU8),\n          wbInteger('Green', itU8),\n          wbInteger('Blue', itU8),\n          wbByteArray('Unused', 1)\n        ]),\n        wbByteArray('Unused', 4),\n        wbFloat('Rain Simulator - Force'),\n        wbFloat('Rain Simulator - Velocity'),\n        wbFloat('Rain Simulator - Falloff'),\n        wbFloat('Rain Simulator - Dampner'),\n        wbFloat('Displacement Simulator - Starting Size'),\n        wbFloat('Displacement Simulator - Force'),\n        wbFloat('Displacement Simulator - Velocity'),\n        wbFloat('Displacement Simulator - Falloff'),\n        wbFloat('Displacement Simulator - Dampner'),\n        wbFloat('Rain Simulator - Starting Size'),\n        wbFloat('Noise Properties - Normals - Noise Scale'),\n        wbFloat('Noise Properties - Noise Layer One - Wind Direction'),\n        wbFloat('Noise Properties - Noise Layer Two - Wind Direction'),\n        wbFloat('Noise Properties - Noise Layer Three - Wind Direction'),\n        wbFloat('Noise Properties - Noise Layer One - Wind Speed'),\n        wbFloat('Noise Properties - Noise Layer Two - Wind Speed'),\n        wbFloat('Noise Properties - Noise Layer Three - Wind Speed'),\n        wbFloat('Noise Properties - Normals - Depth Falloff Start'),\n        wbFloat('Noise Properties - Normals - Depth Falloff End'),\n        wbFloat('Fog Properties - Above Water - Fog Amount'),\n        wbFloat('Noise Properties - Normals - UV Scale'),\n        wbFloat('Fog Properties - Under Water - Fog Amount'),\n        wbFloat('Fog Properties - Under Water - Fog Distance - Near Plane'),\n        wbFloat('Fog Properties - Under Water - Fog Distance - Far Plane'),\n        wbFloat('Water Properties - Distortion Amount'),\n        wbFloat('Water Properties - Shininess'),\n        wbFloat('Water Properties - Reflection HDR Multiplier'),\n        wbFloat('Water Properties - Light Radius'),\n        wbFloat('Water Properties - Light Brightness'),\n        wbFloat('Noise Properties - Noise Layer One - UV Scale'),\n        wbFloat('Noise Properties - Noise Layer Two - UV Scale'),\n        wbFloat('Noise Properties - Noise Layer Three - UV Scale'),\n        wbEmpty('Noise Properties - Noise Layer One - Amplitude Scale'),\n        wbEmpty('Noise Properties - Noise Layer Two - Amplitude Scale'),\n        wbEmpty('Noise Properties - Noise Layer Three - Amplitude Scale'),\n        wbInteger('Damage (Old Format)', itU16)\n      ], cpNormal, True)\n    ], [], cpNormal, True),\n    wbStruct(GNAM, 'Related Waters (Unused)', [\n      wbFormIDCk('Daytime', [WATR, NULL]),\n      wbFormIDCk('Nighttime', [WATR, NULL]),\n      wbFormIDCk('Underwater', [WATR, NULL])\n    ], cpNormal, True)\n  ], False, nil, cpNormal, False, wbWATRAfterLoad);\n\n  wbRecord(WEAP, 'Weapon', [\n    wbEDIDReq,\n    wbOBNDReq,\n    wbFULL,\n    wbMODL,\n    wbICON,\n    wbSCRI,\n    wbEITM,\n    wbInteger(EAMT, 'Enchantment Charge Amount', itS16),\n    wbFormIDCkNoReach(NAM0, 'Ammo', [AMMO, FLST]),\n    wbDEST,\n    wbREPL,\n    wbETYPReq,\n    wbBIPL,\n    wbYNAM,\n    wbZNAM,\n    wbRStruct('Shell Casing Model', [\n      wbString(MOD2, 'Model Filename'),\n      wbByteArray(MO2T, 'Texture Files Hashes', 0, cpIgnore),\n      wbMO2S\n    ], []),\n    wbRStruct('Scope Model', [\n      wbString(MOD3, 'Model Filename'),\n      wbByteArray(MO3T, 'Texture Files Hashes', 0, cpIgnore),\n      wbMO3S\n    ], []),\n    wbFormIDCK(EFSD, 'Scope Effect', [EFSH]),\n    wbRStruct('World Model', [\n      wbString(MOD4, 'Model Filename'),\n      wbByteArray(MO4T, 'Texture Files Hashes', 0, cpIgnore),\n      wbMO4S\n    ], []),\n    wbString(MWD1, 'Model - Mod 1'),\n    wbString(MWD2, 'Model - Mod 2'),\n    wbString(MWD3, 'Model - Mod 1 and 2'),\n    wbString(MWD4, 'Model - Mod 3'),\n    wbString(MWD5, 'Model - Mod 1 and 3'),\n    wbString(MWD6, 'Model - Mod 2 and 3'),\n    wbString(MWD7, 'Model - Mod 1, 2 and 3'),\n    {wbRStruct( 'Model with Mods', [\n      wbString(MWD1, 'Mod 1'),\n      wbString(MWD2, 'Mod 2'),\n      wbString(MWD3, 'Mod 1 and 2'),\n      wbString(MWD4, 'Mod 3'),\n      wbString(MWD5, 'Mod 1 and 3'),\n      wbString(MWD6, 'Mod 2 and 3'),\n      wbString(MWD7, 'Mod 1, 2 and 3')\n    ], [], cpNormal, False, nil, True),}\n\n    wbString(VANM, 'VATS Attack Name'),\n    wbString(NNAM, 'Embedded Weapon Node'),\n\n    wbFormIDCk(INAM, 'Impact DataSet', [IPDS]),\n    wbFormIDCk(WNAM, '1st Person Model', [STAT]),\n    wbFormIDCk(WNM1, '1st Person Model - Mod 1', [STAT]),\n    wbFormIDCk(WNM2, '1st Person Model - Mod 2', [STAT]),\n    wbFormIDCk(WNM3, '1st Person Model - Mod 1 and 2', [STAT]),\n    wbFormIDCk(WNM4, '1st Person Model - Mod 3', [STAT]),\n    wbFormIDCk(WNM5, '1st Person Model - Mod 1 and 3', [STAT]),\n    wbFormIDCk(WNM6, '1st Person Model - Mod 2 and 3', [STAT]),\n    wbFormIDCk(WNM7, '1st Person Model - Mod 1, 2 and 3', [STAT]),\n    {wbRStruct('1st Person Models with Mods', [\n      wbFormIDCk(WNM1, 'Mod 1', [STAT]),\n      wbFormIDCk(WNM2, 'Mod 2', [STAT]),\n      wbFormIDCk(WNM3, 'Mod 1 and 2', [STAT]),\n      wbFormIDCk(WNM4, 'Mod 3', [STAT]),\n      wbFormIDCk(WNM5, 'Mod 1 and 3', [STAT]),\n      wbFormIDCk(WNM6, 'Mod 2 and 3', [STAT]),\n      wbFormIDCk(WNM7, 'Mod 1, 2 and 3', [STAT])\n    ], [], cpNormal, False, nil, True),}\n    wbFormIDCk(WMI1, 'Weapon Mod 1', [IMOD]),\n    wbFormIDCk(WMI2, 'Weapon Mod 2', [IMOD]),\n    wbFormIDCk(WMI3, 'Weapon Mod 3', [IMOD]),\n    {wbRStruct('Weapon Mods', [\n      wbFormIDCk(WMI1, 'Mod 1', [IMOD]),\n      wbFormIDCk(WMI2, 'Mod 2', [IMOD]),\n      wbFormIDCk(WMI3, 'Mod 3', [IMOD])\n    ], [], cpNormal, False, nil, True),}\n    wbRStruct('Sound - Gun', [\n      wbFormIDCk(SNAM, 'Shoot 3D', [SOUN]),\n      wbFormIDCk(SNAM, 'Shoot Dist', [SOUN])\n    ], []),\n    //wbFormIDCk(SNAM, 'Sound - Gun - Shoot 3D', [SOUN]),\n    //wbFormIDCk(SNAM, 'Sound - Gun - Shoot Dist', [SOUN]),\n    wbFormIDCk(XNAM, 'Sound - Gun - Shoot 2D', [SOUN]),\n    wbFormIDCk(NAM7, 'Sound - Gun - Shoot 3D Looping', [SOUN]),\n    wbFormIDCk(TNAM, 'Sound - Melee - Swing / Gun - No Ammo', [SOUN]),\n    wbFormIDCk(NAM6, 'Sound - Block', [SOUN]),\n    wbFormIDCk(UNAM, 'Sound - Idle', [SOUN]),\n    wbFormIDCk(NAM9, 'Sound - Equip', [SOUN]),\n    wbFormIDCk(NAM8, 'Sound - Unequip', [SOUN]),\n    wbRStruct('Sound - Mod 1', [\n      wbFormIDCk(WMS1, 'Shoot 3D', [SOUN]),\n      wbFormIDCk(WMS1, 'Shoot Dist', [SOUN])\n    ], []),\n    //wbFormIDCk(WMS1, 'Sound - Mod 1 - Shoot 3D', [SOUN]),\n    //wbFormIDCk(WMS1, 'Sound - Mod 1 - Shoot Dist', [SOUN]),\n    wbFormIDCk(WMS2, 'Sound - Mod 1 - Shoot 2D', [SOUN]),\n    wbStruct(DATA, '', [\n      wbInteger('Value', itS32),\n      wbInteger('Health', itS32),\n      wbFloat('Weight'),\n      wbInteger('Base Damage', itS16),\n      wbInteger('Clip Size', itU8)\n    ], cpNormal, True),\n    wbStruct(DNAM, '', [\n      {00} wbInteger('Animation Type', itU32, wbWeaponAnimTypeEnum),\n      {04} wbFloat('Animation Multiplier'),\n      {08} wbFloat('Reach'),\n      {12} wbInteger('Flags 1', itU8, wbFlags([\n        'Ignores Normal Weapon Resistance',\n        'Is Automatic',\n        'Has Scope',\n        'Can''t Drop',\n        'Hide Backpack',\n        'Embedded Weapon',\n        'Don''t Use 1st Person IS Animations',\n        'Non-Playable'\n      ])),\n      {13} wbInteger('Grip Animation', itU8, wbEnum([\n      ], [\n        230, 'HandGrip1',\n        231, 'HandGrip2',\n        232, 'HandGrip3',\n        233, 'HandGrip4',\n        234, 'HandGrip5',\n        235, 'HandGrip6',\n        255, 'DEFAULT'\n      ])),\n      {14} wbInteger('Ammo Use', itU8),\n      {15} wbInteger('Reload Animation', itU8, wbReloadAnimEnum),\n      {16} wbFloat('Min Spread'),\n      {20} wbFloat('Spread'),\n      {24} wbFloat('Unknown'),\n      {28} wbFloat('Sight FOV'),\n      {32} wbFloat,\n      {36} wbFormIDCk('Projectile', [PROJ, NULL]),\n      {40} wbInteger('Base VATS To-Hit Chance', itU8),\n      {41} wbInteger('Attack Animation', itU8, wbEnum([\n           ], [\n             26, 'AttackLeft',\n             32, 'AttackRight',\n             38, 'Attack3',\n             44, 'Attack4',\n             50, 'Attack5',\n             56, 'Attack6',\n             62, 'Attack7',\n             68, 'Attack8',\n            144, 'Attack9',\n             74, 'AttackLoop',\n             80, 'AttackSpin',\n             86, 'AttackSpin2',\n            114, 'AttackThrow',\n            120, 'AttackThrow2',\n            126, 'AttackThrow3',\n            132, 'AttackThrow4',\n            138, 'AttackThrow5',\n            150, 'AttackThrow6',\n            156, 'AttackThrow7',\n            162, 'AttackThrow8',\n            102, 'PlaceMine',\n            108, 'PlaceMine2',\n            255, 'DEFAULT'\n           ])),\n      {42} wbInteger('Projectile Count', itU8),\n      {43} wbInteger('Embedded Weapon - Actor Value', itU8, wbEnum([\n        {00} 'Perception',\n        {01} 'Endurance',\n        {02} 'Left Attack',\n        {03} 'Right Attack',\n        {04} 'Left Mobility',\n        {05} 'Right Mobilty',\n        {06} 'Brain'\n      ])),\n      {44} wbFloat('Min Range'),\n      {48} wbFloat('Max Range'),\n      {52} wbInteger('On Hit', itU32, wbEnum([\n        'Normal formula behavior',\n        'Dismember Only',\n        'Explode Only',\n        'No Dismember/Explode'\n      ])),\n      {56} wbInteger('Flags 2', itU32, wbFlags([\n        {0x00000001}'Player Only',\n        {0x00000002}'NPCs Use Ammo',\n        {0x00000004}'No Jam After Reload',\n        {0x00000008}'Override - Action Points',\n        {0x00000010}'Minor Crime',\n        {0x00000020}'Range - Fixed',\n        {0x00000040}'Not Used In Normal Combat',\n        {0x00000080}'Override - Damage to Weapon Mult',\n        {0x00000100}'Don''t Use 3rd Person IS Animations',\n        {0x00000200}'Short Burst',\n        {0x00000400}'Rumble Alternate',\n        {0x00000800}'Long Burst',\n        {0x00001000}'Scope has NightVision',\n        {0x00002000}'Scope from Mod'\n      ])),\n      {60} wbFloat('Animation Attack Multiplier'),\n      {64} wbFloat('Fire Rate'),\n      {68} wbFloat('Override - Action Points'),\n      {72} wbFloat('Rumble - Left Motor Strength'),\n      {76} wbFloat('Rumble - Right Motor Strength'),\n      {80} wbFloat('Rumble - Duration'),\n      {84} wbFloat('Override - Damage to Weapon Mult'),\n      {88} wbFloat('Attack Shots/Sec'),\n      {92} wbFloat('Reload Time'),\n      {96} wbFloat('Jam Time'),\n     {100} wbFloat('Aim Arc'),\n     {104} wbInteger('Skill', itS32, wbActorValueEnum),\n     {108} wbInteger('Rumble - Pattern', itU32, wbEnum([\n       'Constant',\n       'Square',\n       'Triangle',\n       'Sawtooth'\n     ])),\n     {112} wbFloat('Rumble - Wavelength'),\n     {116} wbFloat('Limb Dmg Mult'),\n     {120} wbInteger('Resist Type', itS32, wbActorValueEnum),\n     {124} wbFloat('Sight Usage'),\n     {128} wbFloat('Semi-Automatic Fire Delay Min'),\n     {132} wbFloat('Semi-Automatic Fire Delay Max'),\n     wbFloat,\n     wbInteger('Effect - Mod 1', itU32, wbModEffectEnum),\n     wbInteger('Effect - Mod 2', itU32, wbModEffectEnum),\n     wbInteger('Effect - Mod 3', itU32, wbModEffectEnum),\n     wbFloat('Value A - Mod 1'),\n     wbFloat('Value A - Mod 2'),\n     wbFloat('Value A - Mod 3'),\n     wbInteger('Power Attack Animation Override', itU32, wbEnum([\n     ], [\n        0, '0?',\n       97, 'AttackCustom1Power',\n       98, 'AttackCustom2Power',\n       99, 'AttackCustom3Power',\n      100, 'AttackCustom4Power',\n      101, 'AttackCustom5Power',\n      255, 'DEFAULT'\n     ])),\n     wbInteger('Strength Req', itU32),\n     wbByteArray('Unknown', 1),\n     wbInteger('Reload Animation - Mod', itU8, wbReloadAnimEnum),\n     wbByteArray('Unknown', 2),\n     wbFloat('Regen Rate'),\n     wbFloat('Kill Impulse'),\n     wbFloat('Value B - Mod 1'),\n     wbFloat('Value B - Mod 2'),\n     wbFloat('Value B - Mod 3'),\n     wbFloat('Impulse Dist'),\n     wbInteger('Skill Req', itU32)\n    ], cpNormal, True, nil, 36),\n\n   wbStruct(CRDT, 'Critical Data', [\n      {00} wbInteger('Critical Damage', itU16),\n      {09} wbByteArray('Unused', 2),\n      {04} wbFloat('Crit % Mult'),\n      {08} wbInteger('Flags', itU8, wbFlags([\n        'On Death'\n      ])),\n      {09} wbByteArray('Unused', 3),\n      {12} wbFormIDCk('Effect', [SPEL, NULL])\n    ], cpNormal, True),\n    wbStruct(VATS, 'VATS', [\n     wbFormIDCk('Effect',[SPEL, NULL]),\n     wbFloat('Skill'),\n     wbFloat('Dam. Mult'),\n     wbFloat('AP'),\n     wbInteger('Silent', itU8, wbEnum(['No', 'Yes'])),\n     wbInteger('Mod Required', itU8, wbEnum(['No', 'Yes'])),\n     wbByteArray('Unused', 2)\n    ]),\n    wbInteger(VNAM, 'Sound Level', itU32, wbSoundLevelEnum, cpNormal, True)\n  ], True, nil, cpNormal, False, wbWEAPAfterLoad);\n\n  if wbSimpleRecords then\n    wbRecord(WRLD, 'Worldspace', [\n      wbEDIDReq,\n      wbFULL,\n      wbFormIDCk(XEZN, 'Encounter Zone', [ECZN]),\n      wbRStruct('Parent', [\n        wbFormIDCk(WNAM, 'Worldspace', [WRLD]),\n        wbInteger(PNAM, 'Flags', itU16, wbFlags([\n          {0x00000001}'Use Land Data',\n          {0x00000002}'Use LOD Data',\n          {0x00000004}'Use Map Data',\n          {0x00000008}'Use Water Data',\n          {0x00000010}'Use Climate Data',\n          {0x00000020}'Use Image Space Data'\n          ], True), cpNormal, True)\n      ], []),\n      wbFormIDCk(CNAM, 'Climate', [CLMT]),\n      wbFormIDCk(NAM2, 'Water', [WATR]),\n      wbFormIDCk(NAM3, 'LOD Water Type', [WATR]),\n      wbFloat(NAM4, 'LOD Water Height'),\n      wbStruct(DNAM, 'Land Data', [\n        wbFloat('Default Land Height'),\n        wbFloat('Default Water Height')\n      ]),\n      wbICON,\n      wbStruct(MNAM, 'Map Data', [\n        wbStruct('Usable Dimensions', [\n          wbInteger('X', itS32),\n          wbInteger('Y', itS32)\n        ]),\n        wbStruct('Cell Coordinates', [\n          wbStruct('NW Cell', [\n            wbInteger('X', itS16),\n            wbInteger('Y', itS16)\n          ]),\n          wbStruct('SE Cell', [\n            wbInteger('X', itS16),\n            wbInteger('Y', itS16)\n          ])\n        ])\n      ]),\n      wbStruct(ONAM, 'World Map Offset Data', [\n        wbFloat('World Map Scale'),\n        wbFloat('Cell X Offset'),\n        wbFloat('Cell Y Offset')\n      ], cpNormal, True),\n      wbFormIDCk(INAM, 'Image Space', [IMGS]),\n      wbInteger(DATA, 'Flags', itU8, wbFlags([  // LoadForm supports a DWord here, but only first byte would be used.\n        {0x01} 'Small World',\n        {0x02} 'Can''t Fast Travel',\n        {0x04} '',\n        {0x08} '',\n        {0x10} 'No LOD Water',\n        {0x20} 'No LOD Noise',\n        {0x40} 'Don''t Allow NPC Fall Damage',\n        {0x80} 'Needs Water Adjustment'\n      ]), cpNormal, True),\n      wbRStruct('Object Bounds', [\n        wbStruct(NAM0, 'Min', [\n          wbFloat('X', cpNormal, False, 1/4096),\n          wbFloat('Y', cpNormal, False, 1/4096)\n        ], cpIgnore, True),\n        wbStruct(NAM9, 'Max', [\n          wbFloat('X', cpNormal, False, 1/4096),\n          wbFloat('Y', cpNormal, False, 1/4096)\n        ], cpIgnore, True)\n      ], []),\n      wbFormIDCk(ZNAM, 'Music', [MUSC]),\n      wbString(NNAM, 'Canopy Shadow', 0, cpNormal, True),\n      wbString(XNAM, 'Water Noise Texture', 0, cpNormal, True),\n      wbRArrayS('Swapped Impacts', wbStructExSK(IMPS, [0, 1], [2], 'Swapped Impact', [\n        wbInteger('Material Type', itU32, wbImpactMaterialTypeEnum),\n        wbFormIDCkNoReach('Old', [IPCT]),\n        wbFormIDCk('New', [IPCT, NULL])\n      ])),\n      wbArray(IMPF, 'Footstep Materials', wbString('Unknown', 30), [\n        'ConcSolid',\n        'ConcBroken',\n        'MetalSolid',\n        'MetalHollow',\n        'MetalSheet',\n        'Wood',\n        'Sand',\n        'Dirt',\n        'Grass',\n        'Water'\n      ]),\n      wbByteArray(OFST, 'Offset Data')\n    ], False, nil, cpNormal, False, wbRemoveOFST)\n  else\n    wbRecord(WRLD, 'Worldspace', [\n      wbEDIDReq,\n      wbFULL,\n      wbFormIDCk(XEZN, 'Encounter Zone', [ECZN]),\n      wbRStruct('Parent', [\n        wbFormIDCk(WNAM, 'Worldspace', [WRLD]),\n        wbInteger(PNAM, 'Flags', itU16, wbFlags([\n          {0x00000001}'Use Land Data',\n          {0x00000002}'Use LOD Data',\n          {0x00000004}'Use Map Data',\n          {0x00000008}'Use Water Data',\n          {0x00000010}'Use Climate Data',\n          {0x00000020}'Use Image Space Data'  // in order to use this \"Image Space\" needs to be NULL.\n                                              //  Other parent flags are checked before the form value.\n          ], True), cpNormal, True)\n      ], []),\n      wbFormIDCk(CNAM, 'Climate', [CLMT]),\n      wbFormIDCk(NAM2, 'Water', [WATR]),\n      wbFormIDCk(NAM3, 'LOD Water Type', [WATR]),\n      wbFloat(NAM4, 'LOD Water Height'),\n      wbStruct(DNAM, 'Land Data', [\n        wbFloat('Default Land Height'),\n        wbFloat('Default Water Height')\n      ]),\n      wbICON,\n      wbStruct(MNAM, 'Map Data', [\n        wbStruct('Usable Dimensions', [\n          wbInteger('X', itS32),\n          wbInteger('Y', itS32)\n        ]),\n        wbStruct('Cell Coordinates', [\n          wbStruct('NW Cell', [\n            wbInteger('X', itS16),\n            wbInteger('Y', itS16)\n          ]),\n          wbStruct('SE Cell', [\n            wbInteger('X', itS16),\n            wbInteger('Y', itS16)\n          ])\n        ])\n      ]),\n      wbStruct(ONAM, 'World Map Offset Data', [\n        wbFloat('World Map Scale'),\n        wbFloat('Cell X Offset'),\n        wbFloat('Cell Y Offset')\n      ], cpNormal, True),\n      wbFormIDCk(INAM, 'Image Space', [IMGS]),\n      wbInteger(DATA, 'Flags', itU8, wbFlags([  // LoadForm supports a DWord here, but only first byte would be used.\n        {0x01} 'Small World',\n        {0x02} 'Can''t Fast Travel',\n        {0x04} '',\n        {0x08} '',\n        {0x10} 'No LOD Water',\n        {0x20} 'No LOD Noise',\n        {0x40} 'Don''t Allow NPC Fall Damage',\n        {0x80} 'Needs Water Adjustment'\n      ]), cpNormal, True),\n      wbRStruct('Object Bounds', [\n        wbStruct(NAM0, 'Min', [\n          wbFloat('X', cpNormal, False, 1/4096),\n          wbFloat('Y', cpNormal, False, 1/4096)\n        ], cpIgnore, True),\n        wbStruct(NAM9, 'Max', [\n          wbFloat('X', cpNormal, False, 1/4096),\n          wbFloat('Y', cpNormal, False, 1/4096)\n        ], cpIgnore, True)\n      ], []),\n      wbFormIDCk(ZNAM, 'Music', [MUSC]),\n      wbString(NNAM, 'Canopy Shadow', 0, cpNormal, True),\n      wbString(XNAM, 'Water Noise Texture', 0, cpNormal, True),\n      wbRArrayS('Swapped Impacts', wbStructExSK(IMPS, [0, 1], [2], 'Swapped Impact', [\n        wbInteger('Material Type', itU32, wbImpactMaterialTypeEnum),\n        wbFormIDCkNoReach('Old', [IPCT]),\n        wbFormIDCk('New', [IPCT, NULL])\n      ])),\n      wbArray(IMPF, 'Footstep Materials', wbString('Unknown', 30), [\n        'ConcSolid',\n        'ConcBroken',\n        'MetalSolid',\n        'MetalHollow',\n        'MetalSheet',\n        'Wood',\n        'Sand',\n        'Dirt',\n        'Grass',\n        'Water'\n      ]),\n      wbArray(OFST, 'Offset Data', wbArray('Rows', wbInteger('Offset', itU32), wbOffsetDataColsCounter), 0) // cannot be saved by GECK\n    ], False, nil, cpNormal, False, wbRemoveOFST);\n\n  wbRecord(WTHR, 'Weather', [\n    wbEDIDReq,\n    wbFormIDCk(_0_IAD, 'Sunrise Image Space Modifier', [IMAD]),\n    wbFormIDCk(_1_IAD, 'Day Image Space Modifier', [IMAD]),\n    wbFormIDCk(_2_IAD, 'Sunset Image Space Modifier', [IMAD]),\n    wbFormIDCk(_3_IAD, 'Night Image Space Modifier', [IMAD]),\n    wbFormIDCk(_4_IAD, 'Unknown', [IMAD]),\n    wbFormIDCk(_5_IAD, 'Unknown', [IMAD]),\n    wbString(DNAM, 'Cloud Textures - Layer 0', 0, cpNormal, True),\n    wbString(CNAM, 'Cloud Textures - Layer 1', 0, cpNormal, True),\n    wbString(ANAM, 'Cloud Textures - Layer 2', 0, cpNormal, True),\n    wbString(BNAM, 'Cloud Textures - Layer 3', 0, cpNormal, True),\n    wbMODL,\n    wbByteArray(LNAM, 'Unknown', 4, cpNormal, True),\n    wbArray(ONAM, 'Cloud Speed', wbInteger('Layer', itU8{, wbDiv(2550)}), 4, nil, nil, cpNormal, True),\n    wbArray(PNAM, 'Cloud Layer Colors',\n      wbArray('Layer',\n        wbStruct('Color', [\n          wbInteger('Red', itU8),\n          wbInteger('Green', itU8),\n          wbInteger('Blue', itU8),\n          wbByteArray('Unused', 1)\n        ]),\n        ['Sunrise', 'Day', 'Sunset', 'Night', 'High Noon', 'Midnight']\n      ),\n    4),\n    wbArray(NAM0, 'Colors by Types/Times',\n      wbArray('Type',\n        wbStruct('Time', [\n          wbInteger('Red', itU8),\n          wbInteger('Green', itU8),\n          wbInteger('Blue', itU8),\n          wbByteArray('Unused', 1)\n        ]),\n        ['Sunrise', 'Day', 'Sunset', 'Night', 'High Noon', 'Midnight']\n      ),\n      ['Sky-Upper','Fog','Unused','Ambient','Sunlight','Sun','Stars','Sky-Lower','Horizon','Unused']\n    , cpNormal, True),\n    wbStruct(FNAM, 'Fog Distance', [\n      wbFloat('Day - Near'),\n      wbFloat('Day - Far'),\n      wbFloat('Night - Near'),\n      wbFloat('Night - Far'),\n      wbFloat('Day - Power'),\n      wbFloat('Night - Fower')\n    ], cpNormal, True),\n    wbByteArray(INAM, 'Unused', 304, cpIgnore, True),\n    wbStruct(DATA, '', [\n      wbInteger('Wind Speed', itU8),\n      wbInteger('Cloud Speed (Lower)', itU8),\n      wbInteger('Cloud Speed (Upper)', itU8),\n      wbInteger('Trans Delta', itU8),\n      wbInteger('Sun Glare', itU8),\n      wbInteger('Sun Damage', itU8),\n      wbInteger('Precipitation - Begin Fade In', itU8),\n      wbInteger('Precipitation - End Fade Out', itU8),\n      wbInteger('Thunder/Lightning - Begin Fade In', itU8),\n      wbInteger('Thunder/Lightning - End Fade Out', itU8),\n      wbInteger('Thunder/Lightning - Frequency', itU8),\n      wbInteger('Weather Classification', itU8, wbWthrDataClassification),\n      wbStruct('Lightning Color', [\n        wbInteger('Red', itU8),\n        wbInteger('Green', itU8),\n        wbInteger('Blue', itU8)\n      ])\n    ], cpNormal, True),\n    wbRArray('Sounds', wbStruct(SNAM, 'Sound', [\n      wbFormIDCk('Sound', [SOUN]),\n      wbInteger('Type', itU32, wbEnum([\n       {0}'Default',\n       {1}'Precip',\n       {2}'Wind',\n       {3}'Thunder'\n      ]))\n    ]))\n  ]);\n\n  wbRecord(IMOD, 'Item Mod', [\n    wbEDIDReq,\n    wbOBNDReq,\n    wbFULL,\n    wbMODL,\n    wbICON,\n    wbSCRI,\n    wbDESC,\n    wbDEST,\n    wbYNAM,\n    wbZNAM,\n    wbStruct(DATA, 'Data', [\n      wbInteger('Value', itU32),\n      wbFloat('Weight')\n    ])\n  ]);\n\n  wbRecord(ALOC, 'Media Location Controller', [\n    wbEDIDReq,\n    wbFULL,\n    wbByteArray(NAM1, 'Flags and Enums, messily combined'),\n    wbUnknown(NAM2),\n    wbUnknown(NAM3),\n    wbFloat(NAM4, 'Location Delay'),\n    wbInteger(NAM5, 'Day Start', itU32, wbAlocTime),\n    wbInteger(NAM6, 'Night Start', itU32, wbAlocTime),\n    wbFloat(NAM7, 'Retrigger Delay'),\n    wbRArrayS('Neutral Sets',\n      wbFormIDCk(HNAM, 'Media Set', [MSET])\n    ),\n    wbRArrayS('Ally Sets',\n      wbFormIDCk(ZNAM, 'Media Set', [MSET])\n    ),\n    wbRArrayS('Friend Sets',\n      wbFormIDCk(XNAM, 'Media Set', [MSET])\n    ),\n    wbRArrayS('Enemy Sets',\n      wbFormIDCk(YNAM, 'Media Set', [MSET])\n    ),\n    wbRArrayS('Location Sets',\n      wbFormIDCk(LNAM, 'Media Set', [MSET])\n    ),\n    wbRArrayS('Battle Sets',\n      wbFormIDCk(GNAM, 'Media Set', [MSET])\n    ),\n    wbFormIDCk(RNAM, 'Conditional Faction', [FACT]),\n    wbUnknown(FNAM)\n  ]);\n\n  wbRecord(MSET, 'Media Set', [\n    wbEDIDReq,\n    wbFULL,\n    wbInteger(NAM1, 'Type', itU32, wbEnum([\n      'Battle Set',\n      'Location Set',\n      'Dungeon Set',\n      'Incidental Set'\n    ], [\n      -1, 'No Set'\n    ])),\n    wbString(NAM2, 'Loop (B) / Battle (D) / Day Outer (L)'),\n    wbString(NAM3, 'Explore (D) / Day Middle (L)'),\n    wbString(NAM4, 'Suspense (D) / Day Inner (L)'),\n    wbString(NAM5, 'Night Outer (L)'),\n    wbString(NAM6, 'Night Middle (L)'),\n    wbString(NAM7, 'Night Inner (L)'),\n    wbFloat(NAM8, 'Loop dB (B) / Battle dB (D) / Day Outer dB (L)'),\n    wbFloat(NAM9, 'Explore dB (D) / Day Middle dB (L)'),\n    wbFloat(NAM0, 'Suspense dB (D) / Day Inner dB (L)'),\n    wbFloat(ANAM, 'Night Outer dB (L)'),\n    wbFloat(BNAM, 'Night Middle dB (L)'),\n    wbFloat(CNAM, 'Night Inner dB (L)'),\n    wbFloat(JNAM, 'Day Outer Boundary % (L)'),\n    wbFloat(KNAM, 'Day Middle Boundary % (L)'),\n    wbFloat(LNAM, 'Day Inner Boundary % (L)'),\n    wbFloat(MNAM, 'Night Outer Boundary % (L)'),\n    wbFloat(NNAM, 'Night Middle Boundary % (L)'),\n    wbFloat(ONAM, 'Night Inner Boundary % (L)'),\n    wbInteger(PNAM, 'Enable Flags', itU8, wbFlags([\n      {0x01} 'Day Outer',\n      {0x02} 'Day Middle',\n      {0x04} 'Day Inner',\n      {0x08} 'Night Outer',\n      {0x10} 'Night Middle',\n      {0x20} 'Night Inner'\n    ])),\n    wbFloat(DNAM, 'Wait Time (B) / Minimum Time On (D,L) / Daytime Min (I)'),\n    wbFloat(ENAM, 'Loop Fade Out (B) / Looping/Random Crossfade Overlap (D,L) / Nighttime Min (I)'),\n    wbFloat(FNAM, 'Recovery Time (B) / Layer Crossfade Time (D,L) / Daytime Max (I)'),\n    wbFloat(GNAM, 'Nighttime Max (I)'),\n    wbFormIDCk(HNAM, 'Intro (B,D) / Daytime (I)', [SOUN]),\n    wbFormIDCk(INAM, 'Outro (B,D) / Nighttime (I)', [SOUN]),\n    wbUnknown(DATA)\n  ]);\n\n  wbRecord(AMEF, 'Ammo Effect', [\n    wbEDIDReq,\n    wbFULL,\n    wbStruct(DATA, 'Data', [\n      wbInteger('Type', itU32, wbEnum([\n        'Damage Mod',\n        'DR Mod',\n        'DT Mod',\n        'Spread Mod',\n        'Weapon Condition Mod',\n        'Fatigue Mod'\n      ])),\n      wbInteger('Operation', itU32, wbEnum([\n        'Add',\n        'Multiply',\n        'Subtract'\n      ])),\n      wbFloat('Value')\n    ])\n  ]);\n\n  wbRecord(CCRD, 'Caravan Card', [\n    wbEDIDReq,\n    wbOBNDReq,\n    wbFULL,\n    wbMODL,\n    wbICON,\n    wbSCRI,\n    wbYNAM,\n    wbZNAM,\n    wbRStruct('High Res Image', [\n      wbString(TX00, 'Face'),\n      wbString(TX01, 'Back')\n    ], []),\n    wbRStruct('Card', [\n      wbInteger(INTV, 'Suit', itU32, wbEnum([\n        '',\n        'Hearts',\n        'Spades',\n        'Diamonds',\n        'Clubs',\n        'Joker'\n      ])),\n      wbInteger(INTV, 'Value', itU32, wbEnum([\n        '',\n        'Ace',\n        '2',\n        '3',\n        '4',\n        '5',\n        '6',\n        '7',\n        '8',\n        '9',\n        '10',\n        '',\n        'Jack',\n        'Queen',\n        'King',\n        'Joker'\n      ]))\n    ], []),\n    wbInteger(DATA, 'Value', itU32)\n  ]);\n\n  wbRecord(CDCK, 'Caravan Deck', [\n    wbEDIDReq,\n    wbFULL,\n    wbRArrayS('Cards',\n      wbFormIDCk(CARD, 'Card', [CCRD])\n    ),\n    wbInteger(DATA, 'Count (broken)', itU32)\n  ]);\n\n  wbRecord(CHAL, 'Challenge', [\n    wbEDIDReq,\n    wbFULL,\n    wbICON,\n    wbSCRI,\n    wbDESC,\n    wbStruct(DATA, 'Data', [\n      wbInteger('Type', itU32, wbEnum([\n        {00} 'Kill from a Form List',\n        {01} 'Kill a specific FormID',\n        {02} 'Kill any in a category',\n        {03} 'Hit an Enemy',\n        {04} 'Discover a Map Marker',\n        {05} 'Use an Item',\n        {06} 'Acquire an Item',\n        {07} 'Use a Skill',\n        {08} 'Do Damage',\n        {09} 'Use an Item from a List',\n        {10} 'Acquire an Item from a List',\n        {11} 'Miscellaneous Stat',\n        {12} 'Craft Using an Item',\n        {13} 'Scripted Challenge'\n      ])),\n      wbInteger('Threshold', itU32),\n      wbInteger('Flags', itU32, wbFlags([\n        'Start Disabled',\n        'Recurring',\n        'Show Zero Progress'\n      ])),\n      wbInteger('Interval', itU32),\n      wbByteArray('(depends on type)', 2),\n      wbByteArray('(depends on type)', 2),\n      wbByteArray('(depends on type)', 4)\n    ]),\n    wbFormID(SNAM, '(depends on type)'),\n    wbFormID(XNAM, '(depends on type)')\n  ]);\n\n  wbRecord(CHIP, 'Casino Chip', [\n    wbEDIDReq,\n    wbOBNDReq,\n    wbFULL,\n    wbMODL,\n    wbICON,\n    wbDEST,\n    wbYNAM,\n    wbZNAM\n  ]);\n\n  wbRecord(CMNY, 'Caravan Money', [\n    wbEDIDReq,\n    wbOBNDReq,\n    wbFULL,\n    wbMODL,\n    wbICON,\n    wbYNAM,\n    wbZNAM,\n    wbInteger(DATA, 'Absolute Value', itU32)\n  ]);\n\n  wbRecord(CSNO, 'Casino', [\n    wbEDIDReq,\n    wbFULL,\n    wbStruct(DATA, 'Data', [\n      wbFloat('Decks % Before Shuffle'),\n      wbFloat('BlackJack Payout Ratio'),\n      wbArray('Slot Reel Stops', wbInteger('Reel', itU32),[\n        'Symbol 1',\n        'Symbol 2',\n        'Symbol 3',\n        'Symbol 4',\n        'Symbol 5',\n        'Symbol 6',\n        'Symbol W'\n      ]),\n      wbInteger('Number of Decks', itU32),\n      wbInteger('Max Winnings', itU32),\n      wbFormIDCk('Currency', [CHIP]),\n      wbFormIDCk('Casino Winnings Quest', [QUST]),\n      wbInteger('Flags', itU32, wbFlags([\n        'Dealer Stay on Soft 17'\n      ]))\n    ]),\n    wbRStruct('Casino Chip Models', [\n      wbString(MODL, '$1 Chip'),\n      wbString(MODL, '$5 Chip'),\n      wbString(MODL, '$10 Chip'),\n      wbString(MODL, '$25 Chip'),\n      wbString(MODL, '$100 Chip'),\n      wbString(MODL, '$500 Chip'),\n      wbString(MODL, 'Roulette Chip')\n    ], []),\n    wbString(MODL, 'Slot Machine Model'),\n    wbString(MOD2, 'Slot Machine Model (again?)'),\n    wbString(MOD3, 'BlackJack Table Model'),\n    wbString(MODT, 'BlackJack Table Model related'),\n    wbString(MOD4, 'Roulette Table Model'),\n    wbRStruct('Slot Reel Textures', [\n      wbString(ICON, 'Symbol 1'),\n      wbString(ICON, 'Symbol 2'),\n      wbString(ICON, 'Symbol 3'),\n      wbString(ICON, 'Symbol 4'),\n      wbString(ICON, 'Symbol 5'),\n      wbString(ICON, 'Symbol 6'),\n      wbString(ICON, 'Symbol W')\n    ], []),\n      wbRStruct('BlackJack Decks', [\n      wbString(ICO2, 'Deck 1'),\n      wbString(ICO2, 'Deck 2'),\n      wbString(ICO2, 'Deck 3'),\n      wbString(ICO2, 'Deck 4')\n    ], [])\n  ]);\n\n  wbRecord(DEHY, 'Dehydration Stage', [\n    wbEDIDReq,\n    wbStruct(DATA, '', [\n      wbInteger('Trigger Threshold', itU32),\n      wbFormIDCk('Actor Effect', [SPEL])\n    ], cpNormal, True)\n  ]);\n\n  wbRecord(HUNG, 'Hunger Stage', [\n    wbEDIDReq,\n    wbStruct(DATA, '', [\n      wbInteger('Trigger Threshold', itU32),\n      wbFormIDCk('Actor Effect', [SPEL])\n    ], cpNormal, True)\n  ]);\n\n  wbRecord(LSCT, 'Load Screen Type', [\n    wbEDIDReq,\n    wbStruct(DATA, 'Data', [\n      wbInteger('Type', itU32, wbEnum([\n        'None',\n        'XP Progress',\n        'Objective',\n        'Tip',\n        'Stats'\n      ])),\n      wbStruct('Data 1', [\n        wbInteger('X', itU32),\n        wbInteger('Y', itU32),\n        wbInteger('Width', itU32),\n        wbInteger('Height', itU32),\n        wbFloat('Orientation', cpNormal, True, wbRotationFactor, wbRotationScale, nil, RadiansNormalize),\n        wbInteger('Font', itU32, wbEnum([\n          '',\n          '2',\n          '3',\n          '4',\n          '5',\n          '6',\n          '7',\n          '8'\n        ])),\n        wbStruct('Font Color', [\n          wbFloat('R'),\n          wbFloat('G'),\n          wbFloat('B')\n        ]),\n        wbInteger('Font', itU32, wbEnum([\n          '',\n          'Left',\n          'Center',\n          '',\n          'Right'\n        ]))\n      ]),\n      wbByteArray('Unknown', 20),\n      wbStruct('Data 2', [\n        wbInteger('Font', itU32, wbEnum([\n          '',\n          '2',\n          '3',\n          '4',\n          '5',\n          '6',\n          '7',\n          '8'\n        ])),\n        wbStruct('Font Color', [\n          wbFloat('R'),\n          wbFloat('G'),\n          wbFloat('B')\n        ]),\n        wbByteArray('', 4),\n        wbInteger('Stats', itU32, wbEnum([\n          '',\n          '2',\n          '3',\n          '4',\n          '5',\n          '6',\n          '7',\n          '8'\n        ]))\n      ])\n    ])\n  ]);\n\n  wbRecord(RCCT, 'Recipe Category', [\n    wbEDIDReq,\n    wbFULL,\n    wbInteger(DATA, 'Flags', itU8, wbFlags([\n      'Subcategory?',\n      '',\n      '',\n      '',\n      '',\n      '',\n      '',\n      ''\n    ]))\n  ]);\n\n  wbRecord(RCPE, 'Recipe', [\n    wbEDIDReq,\n    wbFULL,\n    wbCTDAs,\n    wbStruct(DATA, 'Data', [\n      wbInteger('Skill', itS32, wbActorValueEnum),\n      wbInteger('Level', itU32),\n      wbFormIDCk('Category', [RCCT, NULL]),   // Some of DeadMoney are NULL\n      wbFormIDCk('Sub-Category', [RCCT])\n    ]),\n    wbRStructs('Ingredients', 'Ingredient', [\n      wbFormIDCk(RCIL, 'Item', [ARMO, AMMO, MISC, WEAP, BOOK, KEYM, ALCH, NOTE, IMOD, CMNY, CCRD, CHIP, LIGH], False, cpNormal, True),\n      wbInteger(RCQY, 'Quantity', itU32, nil, cpNormal, True)\n    ], []),\n    wbRStructs('Outputs', 'Output', [\n      wbFormIDCk(RCOD, 'Item', [ARMO, AMMO, MISC, WEAP, BOOK, KEYM, ALCH, NOTE, IMOD, CMNY, CCRD, CHIP, LIGH], False, cpNormal, True),\n      wbInteger(RCQY, 'Quantity', itU32, nil, cpNormal, True)\n    ], [])\n  ]);\n\n  wbRecord(REPU, 'Reputation', [\n    wbEDIDReq,\n    wbFULL,\n    wbICON,\n    wbFloat(DATA, 'Value')\n  ]);\n\n  wbRecord(SLPD, 'Sleep Deprivation Stage', [\n    wbEDIDReq,\n    wbStruct(DATA, '', [\n      wbInteger('Trigger Threshold', itU32),\n      wbFormIDCk('Actor Effect', [SPEL])\n    ], cpNormal, True)\n  ]);\n\n  wbAddGroupOrder(GMST);\n  wbAddGroupOrder(TXST);\n  wbAddGroupOrder(MICN);\n  wbAddGroupOrder(GLOB);\n  wbAddGroupOrder(CLAS);\n  wbAddGroupOrder(FACT);\n  wbAddGroupOrder(HDPT);\n  wbAddGroupOrder(HAIR);\n  wbAddGroupOrder(EYES);\n  wbAddGroupOrder(RACE);\n  wbAddGroupOrder(SOUN);\n  wbAddGroupOrder(ASPC);\n  wbAddGroupOrder(MGEF);\n  wbAddGroupOrder(SCPT);\n  wbAddGroupOrder(LTEX);\n  wbAddGroupOrder(ENCH);\n  wbAddGroupOrder(SPEL);\n  wbAddGroupOrder(ACTI);\n  wbAddGroupOrder(TACT);\n  wbAddGroupOrder(TERM);\n  wbAddGroupOrder(ARMO);\n  wbAddGroupOrder(BOOK);\n  wbAddGroupOrder(CONT);\n  wbAddGroupOrder(DOOR);\n  wbAddGroupOrder(INGR);\n  wbAddGroupOrder(LIGH);\n  wbAddGroupOrder(MISC);\n  wbAddGroupOrder(STAT);\n  wbAddGroupOrder(SCOL);\n  wbAddGroupOrder(MSTT);\n  wbAddGroupOrder(PWAT);\n  wbAddGroupOrder(GRAS);\n  wbAddGroupOrder(TREE);\n  wbAddGroupOrder(FURN);\n  wbAddGroupOrder(WEAP);\n  wbAddGroupOrder(AMMO);\n  wbAddGroupOrder(NPC_);\n  wbAddGroupOrder(CREA);\n  wbAddGroupOrder(LVLC);\n  wbAddGroupOrder(LVLN);\n  wbAddGroupOrder(KEYM);\n  wbAddGroupOrder(ALCH);\n  wbAddGroupOrder(IDLM);\n  wbAddGroupOrder(NOTE);\n  wbAddGroupOrder(COBJ);\n  wbAddGroupOrder(PROJ);\n  wbAddGroupOrder(LVLI);\n  wbAddGroupOrder(WTHR);\n  wbAddGroupOrder(CLMT);\n  wbAddGroupOrder(REGN);\n  wbAddGroupOrder(NAVI);\n  wbAddGroupOrder(DIAL);\n  wbAddGroupOrder(QUST);\n  wbAddGroupOrder(IDLE);\n  wbAddGroupOrder(PACK);\n  wbAddGroupOrder(CSTY);\n  wbAddGroupOrder(LSCR);\n  wbAddGroupOrder(ANIO);\n  wbAddGroupOrder(WATR);\n  wbAddGroupOrder(EFSH);\n  wbAddGroupOrder(EXPL);\n  wbAddGroupOrder(DEBR);\n  wbAddGroupOrder(IMGS);\n  wbAddGroupOrder(IMAD);\n  wbAddGroupOrder(FLST);\n  wbAddGroupOrder(PERK);\n  wbAddGroupOrder(BPTD);\n  wbAddGroupOrder(ADDN);\n  wbAddGroupOrder(AVIF);\n  wbAddGroupOrder(RADS);\n  wbAddGroupOrder(CAMS);\n  wbAddGroupOrder(CPTH);\n  wbAddGroupOrder(VTYP);\n  wbAddGroupOrder(IPCT);\n  wbAddGroupOrder(IPDS);\n  wbAddGroupOrder(ARMA);\n  wbAddGroupOrder(ECZN);\n  wbAddGroupOrder(MESG);\n  wbAddGroupOrder(RGDL);\n  wbAddGroupOrder(DOBJ);\n  wbAddGroupOrder(LGTM);\n  wbAddGroupOrder(MUSC);\n  wbAddGroupOrder(IMOD);\n  wbAddGroupOrder(REPU);\n  wbAddGroupOrder(RCPE);\n  wbAddGroupOrder(RCCT);\n  wbAddGroupOrder(CHIP);\n  wbAddGroupOrder(CSNO);\n  wbAddGroupOrder(LSCT);\n  wbAddGroupOrder(MSET);\n  wbAddGroupOrder(ALOC);\n  wbAddGroupOrder(CHAL);\n  wbAddGroupOrder(AMEF);\n  wbAddGroupOrder(CCRD);\n  wbAddGroupOrder(CMNY);\n  wbAddGroupOrder(CDCK);\n  wbAddGroupOrder(DEHY);\n  wbAddGroupOrder(HUNG);\n  wbAddGroupOrder(SLPD);\n  // Forced at the end.\n  wbAddGroupOrder(CELL);\n  wbAddGroupOrder(WRLD);\nend;\n\nprocedure DefineFNV;\nbegin\n  DefineFNVa;\n  DefineFNVb;\n  DefineFNVc;\n  DefineFNVd;\n  DefineFNVe;\n  DefineFNVf;\nend;\n\nend.\n"
  },
  {
    "path": "lib/xedit/wbDefinitionsFO3.pas",
    "content": "{*******************************************************************************\n\n     The contents of this file are subject to the Mozilla Public License\n     Version 1.1 (the \"License\"); you may not use this file except in\n     compliance with the License. You may obtain a copy of the License at\n     http://www.mozilla.org/MPL/\n\n     Software distributed under the License is distributed on an \"AS IS\"\n     basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the\n     License for the specific language governing rights and limitations\n     under the License.\n\n*******************************************************************************}\n\nunit wbDefinitionsFO3;\n\n{$I wbDefines.inc}\n\ninterface\n\nuses\n  wbInterface;\n\nvar\n\twbAggroRadiusFlags: IwbFlagsDef;\n  wbPKDTFlags: IwbFlagsDef;\n\twbRecordFlagsFlags: IwbFlagsDef;\n\twbServiceFlags: IwbFlagsDef;\n\twbTemplateFlags: IwbFlagsDef;\n\n\twbAgressionEnum: IwbEnumDef;\n\twbAlignmentEnum: IwbEnumDef;\n\twbArchtypeEnum: IwbEnumDef;\n\twbAssistanceEnum: IwbEnumDef;\n\twbAttackAnimationEnum: IwbEnumDef;\n\twbAxisEnum: IwbEnumDef;\n\twbBlendModeEnum: IwbEnumDef;\n\twbBlendOpEnum: IwbEnumDef;\n\twbBodyLocationEnum: IwbEnumDef;\n\twbBodyPartIndexEnum: IwbEnumDef;\n\twbConfidenceEnum: IwbEnumDef;\n\twbCreatureTypeEnum: IwbEnumDef;\n\twbCrimeTypeEnum: IwbEnumDef;\n\twbCriticalStageEnum: IwbEnumDef;\n\twbEquipTypeEnum: IwbEnumDef;\n\twbFormTypeEnum: IwbEnumDef;\n\twbFunctionsEnum: IwbEnumDef;\n\twbHeadPartIndexEnum: IwbEnumDef;\n\twbImpactMaterialTypeEnum: IwbEnumDef;\n\twbMenuModeEnum: IwbEnumDef;\n\twbMiscStatEnum: IwbEnumDef;\n\twbModEffectEnum: IwbEnumDef;\n\twbMoodEnum: IwbEnumDef;\n\twbMusicEnum: IwbEnumDef;\n\twbObjectTypeEnum: IwbEnumDef;\n\twbPKDTType: IwbEnumDef;\n\twbPlayerActionEnum: IwbEnumDef;\n\twbQuadrantEnum: IwbEnumDef;\n\twbReloadAnimEnum: IwbEnumDef;\n\twbSexEnum: IwbEnumDef;\n\twbSkillEnum: IwbEnumDef;\n\twbSoundLevelEnum: IwbEnumDef;\n\twbSpecializationEnum: IwbEnumDef;\n\twbVatsValueFunctionEnum: IwbEnumDef;\n\twbWeaponAnimTypeEnum: IwbEnumDef;\n\twbZTestFuncEnum: IwbEnumDef;\n\nprocedure DefineFO3;\n\nimplementation\n\nuses\n  Types,\n  Classes,\n  SysUtils,\n  Math,\n  Variants,\n  wbHelpers;\n\nconst\n  _00_IAD: TwbSignature = #$00'IAD';\n  _40_IAD: TwbSignature = #$40'IAD';\n  _01_IAD: TwbSignature = #$01'IAD';\n  _41_IAD: TwbSignature = #$41'IAD';\n  _02_IAD: TwbSignature = #$02'IAD';\n  _42_IAD: TwbSignature = #$42'IAD';\n  _03_IAD: TwbSignature = #$03'IAD';\n  _43_IAD: TwbSignature = #$43'IAD';\n  _04_IAD: TwbSignature = #$04'IAD';\n  _44_IAD: TwbSignature = #$44'IAD';\n  _05_IAD: TwbSignature = #$05'IAD';\n  _45_IAD: TwbSignature = #$45'IAD';\n  _06_IAD: TwbSignature = #$06'IAD';\n  _46_IAD: TwbSignature = #$46'IAD';\n  _07_IAD: TwbSignature = #$07'IAD';\n  _47_IAD: TwbSignature = #$47'IAD';\n  _08_IAD: TwbSignature = #$08'IAD';\n  _48_IAD: TwbSignature = #$48'IAD';\n  _09_IAD: TwbSignature = #$09'IAD';\n  _49_IAD: TwbSignature = #$49'IAD';\n  _0A_IAD: TwbSignature = #$0A'IAD';\n  _4A_IAD: TwbSignature = #$4A'IAD';\n  _0B_IAD: TwbSignature = #$0B'IAD';\n  _4B_IAD: TwbSignature = #$4B'IAD';\n  _0C_IAD: TwbSignature = #$0C'IAD';\n  _4C_IAD: TwbSignature = #$4C'IAD';\n  _0D_IAD: TwbSignature = #$0D'IAD';\n  _4D_IAD: TwbSignature = #$4D'IAD';\n  _0E_IAD: TwbSignature = #$0E'IAD';\n  _4E_IAD: TwbSignature = #$4E'IAD';\n  _0F_IAD: TwbSignature = #$0F'IAD';\n  _4F_IAD: TwbSignature = #$4F'IAD';\n  _10_IAD: TwbSignature = #$10'IAD';\n  _50_IAD: TwbSignature = #$50'IAD';\n  _11_IAD: TwbSignature = #$11'IAD';\n  _51_IAD: TwbSignature = #$51'IAD';\n  _12_IAD: TwbSignature = #$12'IAD';\n  _52_IAD: TwbSignature = #$52'IAD';\n  _13_IAD: TwbSignature = #$13'IAD';\n  _53_IAD: TwbSignature = #$53'IAD';\n  _14_IAD: TwbSignature = #$14'IAD';\n  _54_IAD: TwbSignature = #$54'IAD';\n\n  _0_IAD : TwbSignature = #0'IAD';\n  _1_IAD : TwbSignature = #1'IAD';\n  _2_IAD : TwbSignature = #2'IAD';\n  _3_IAD : TwbSignature = #3'IAD';\n  ACBS : TwbSignature = 'ACBS';\n  ACHR : TwbSignature = 'ACHR';\n  ACRE : TwbSignature = 'ACRE';\n  ACTI : TwbSignature = 'ACTI';\n  ADDN : TwbSignature = 'ADDN';\n  AIDT : TwbSignature = 'AIDT';\n  ALCH : TwbSignature = 'ALCH';\n  AMMO : TwbSignature = 'AMMO';\n  ANAM : TwbSignature = 'ANAM';\n  ANIO : TwbSignature = 'ANIO';\n  ARMA : TwbSignature = 'ARMA';\n  ARMO : TwbSignature = 'ARMO';\n  ASPC : TwbSignature = 'ASPC';\n  ATTR : TwbSignature = 'ATTR';\n  ATXT : TwbSignature = 'ATXT';\n  AVIF : TwbSignature = 'AVIF';\n  BIPL : TwbSignature = 'BIPL';\n  BMCT : TwbSignature = 'BMCT';\n  BMDT : TwbSignature = 'BMDT';\n  BNAM : TwbSignature = 'BNAM';\n  BOOK : TwbSignature = 'BOOK';\n  BPND : TwbSignature = 'BPND';\n  BPNI : TwbSignature = 'BPNI';\n  BPNN : TwbSignature = 'BPNN';\n  BPNT : TwbSignature = 'BPNT';\n  BPTD : TwbSignature = 'BPTD';\n  BPTN : TwbSignature = 'BPTN';\n  BTXT : TwbSignature = 'BTXT';\n  CAMS : TwbSignature = 'CAMS';\n  CELL : TwbSignature = 'CELL';\n  CLAS : TwbSignature = 'CLAS';\n  CLMT : TwbSignature = 'CLMT';\n  CNAM : TwbSignature = 'CNAM';\n  CNTO : TwbSignature = 'CNTO';\n  COBJ : TwbSignature = 'COBJ';\n  COED : TwbSignature = 'COED';\n  CONT : TwbSignature = 'CONT';\n  CPTH : TwbSignature = 'CPTH';\n  CRDT : TwbSignature = 'CRDT';\n  CREA : TwbSignature = 'CREA';\n  CSAD : TwbSignature = 'CSAD';\n  CSCR : TwbSignature = 'CSCR';\n  CSDC : TwbSignature = 'CSDC';\n  CSDI : TwbSignature = 'CSDI';\n  CSDT : TwbSignature = 'CSDT';\n  CSSD : TwbSignature = 'CSSD';\n  CSTD : TwbSignature = 'CSTD';\n  CSTY : TwbSignature = 'CSTY';\n  CTDA : TwbSignature = 'CTDA';\n  DATA : TwbSignature = 'DATA';\n  DEBR : TwbSignature = 'DEBR';\n  DELE : TwbSignature = 'DELE';\n  DESC : TwbSignature = 'DESC';\n  DEST : TwbSignature = 'DEST';\n  DIAL : TwbSignature = 'DIAL';\n  DMDL : TwbSignature = 'DMDL';\n  DMDT : TwbSignature = 'DMDT';\n  DNAM : TwbSignature = 'DNAM';\n  DOBJ : TwbSignature = 'DOBJ';\n  DODT : TwbSignature = 'DODT';\n  DOOR : TwbSignature = 'DOOR';\n  DSTD : TwbSignature = 'DSTD';\n  DSTF : TwbSignature = 'DSTF';\n  EAMT : TwbSignature = 'EAMT';\n  ECZN : TwbSignature = 'ECZN';\n  EDID : TwbSignature = 'EDID';\n  EFID : TwbSignature = 'EFID';\n  EFIT : TwbSignature = 'EFIT';\n  EFSD : TwbSignature = 'EFSD';\n  EFSH : TwbSignature = 'EFSH';\n  EITM : TwbSignature = 'EITM';\n  ENAM : TwbSignature = 'ENAM';\n  ENCH : TwbSignature = 'ENCH';\n  ENIT : TwbSignature = 'ENIT';\n  EPF2 : TwbSignature = 'EPF2';\n  EPF3 : TwbSignature = 'EPF3';\n  EPFD : TwbSignature = 'EPFD';\n  EPFT : TwbSignature = 'EPFT';\n  ESCE : TwbSignature = 'ESCE';\n  ETYP : TwbSignature = 'ETYP';\n  EXPL : TwbSignature = 'EXPL';\n  EYES : TwbSignature = 'EYES';\n  FACT : TwbSignature = 'FACT';\n  FGGA : TwbSignature = 'FGGA';\n  FGGS : TwbSignature = 'FGGS';\n  FGTS : TwbSignature = 'FGTS';\n  FLST : TwbSignature = 'FLST';\n  FLTV : TwbSignature = 'FLTV';\n  FNAM : TwbSignature = 'FNAM';\n  FULL : TwbSignature = 'FULL';\n  FURN : TwbSignature = 'FURN';\n  GLOB : TwbSignature = 'GLOB';\n  GMST : TwbSignature = 'GMST';\n  GNAM : TwbSignature = 'GNAM';\n  GRAS : TwbSignature = 'GRAS';\n  HAIR : TwbSignature = 'HAIR';\n  HCLR : TwbSignature = 'HCLR';\n  HDPT : TwbSignature = 'HDPT';\n  HEDR : TwbSignature = 'HEDR';\n  HNAM : TwbSignature = 'HNAM';\n  ICO2 : TwbSignature = 'ICO2';\n  ICON : TwbSignature = 'ICON';\n  IDLA : TwbSignature = 'IDLA';\n  IDLB : TwbSignature = 'IDLB';\n  IDLC : TwbSignature = 'IDLC';\n  IDLE : TwbSignature = 'IDLE';\n  IDLF : TwbSignature = 'IDLF';\n  IDLM : TwbSignature = 'IDLM';\n  IDLT : TwbSignature = 'IDLT';\n  IMAD : TwbSignature = 'IMAD';\n  IMGS : TwbSignature = 'IMGS';\n  INAM : TwbSignature = 'INAM';\n  INDX : TwbSignature = 'INDX';\n  INFO : TwbSignature = 'INFO';\n  INGR : TwbSignature = 'INGR';\n  IPCT : TwbSignature = 'IPCT';\n  IPDS : TwbSignature = 'IPDS';\n  ITXT : TwbSignature = 'ITXT';\n  JNAM : TwbSignature = 'JNAM';\n  KEYM : TwbSignature = 'KEYM';\n  KFFZ : TwbSignature = 'KFFZ';\n  KNAM : TwbSignature = 'KNAM';\n  LAND : TwbSignature = 'LAND';\n  LGTM : TwbSignature = 'LGTM';\n  LIGH : TwbSignature = 'LIGH';\n  LNAM : TwbSignature = 'LNAM';\n  LSCR : TwbSignature = 'LSCR';\n  LTEX : TwbSignature = 'LTEX';\n  LTMP : TwbSignature = 'LTMP';\n  LVLC : TwbSignature = 'LVLC';\n  LVLD : TwbSignature = 'LVLD';\n  LVLF : TwbSignature = 'LVLF';\n  LVLG : TwbSignature = 'LVLG';\n  LVLI : TwbSignature = 'LVLI';\n  LVLN : TwbSignature = 'LVLN';\n  LVLO : TwbSignature = 'LVLO';\n  MAST : TwbSignature = 'MAST';\n  MESG : TwbSignature = 'MESG';\n  MGEF : TwbSignature = 'MGEF';\n  MICN : TwbSignature = 'MICN';\n  MICO : TwbSignature = 'MICO';\n  MIC2 : TwbSignature = 'MIC2';\n  MISC : TwbSignature = 'MISC';\n  MNAM : TwbSignature = 'MNAM';\n  MO2B : TwbSignature = 'MO2B';\n  MO2S : TwbSignature = 'MO2S';\n  MO2T : TwbSignature = 'MO2T';\n  MO3B : TwbSignature = 'MO3B';\n  MO3S : TwbSignature = 'MO3S';\n  MO3T : TwbSignature = 'MO3T';\n  MO4B : TwbSignature = 'MO4B';\n  MO4S : TwbSignature = 'MO4S';\n  MO4T : TwbSignature = 'MO4T';\n  MOD2 : TwbSignature = 'MOD2';\n  MOD3 : TwbSignature = 'MOD3';\n  MOD4 : TwbSignature = 'MOD4';\n  MODB : TwbSignature = 'MODB';\n  MODD : TwbSignature = 'MODD';\n  MODL : TwbSignature = 'MODL';\n  MODS : TwbSignature = 'MODS';\n  MODT : TwbSignature = 'MODT';\n  MOSD : TwbSignature = 'MOSD';\n  MSTT : TwbSignature = 'MSTT';\n  MUSC : TwbSignature = 'MUSC';\n  IMPS : TwbSignature = 'IMPS';\n  IMPF : TwbSignature = 'IMPF';\n  NAM0 : TwbSignature = 'NAM0';\n  NAM1 : TwbSignature = 'NAM1';\n  NAM2 : TwbSignature = 'NAM2';\n  NAM3 : TwbSignature = 'NAM3';\n  NAM4 : TwbSignature = 'NAM4';\n  NAM5 : TwbSignature = 'NAM5';\n  NAM6 : TwbSignature = 'NAM6';\n  NAM7 : TwbSignature = 'NAM7';\n  NAM8 : TwbSignature = 'NAM8';\n  NAM9 : TwbSignature = 'NAM9';\n  NAME : TwbSignature = 'NAME';\n  NAVI : TwbSignature = 'NAVI';\n  NAVM : TwbSignature = 'NAVM';\n  NEXT : TwbSignature = 'NEXT';\n  NIFT : TwbSignature = 'NIFT';\n  NIFZ : TwbSignature = 'NIFZ';\n  NNAM : TwbSignature = 'NNAM';\n  NOTE : TwbSignature = 'NOTE';\n  NPC_ : TwbSignature = 'NPC_';\n  NULL : TwbSignature = 'NULL';\n  NVCA : TwbSignature = 'NVCA';\n  NVCI : TwbSignature = 'NVCI';\n  NVDP : TwbSignature = 'NVDP';\n  NVER : TwbSignature = 'NVER';\n  NVEX : TwbSignature = 'NVEX';\n  NVGD : TwbSignature = 'NVGD';\n  NVMI : TwbSignature = 'NVMI';\n  NVTR : TwbSignature = 'NVTR';\n  NVVX : TwbSignature = 'NVVX';\n  OBND : TwbSignature = 'OBND';\n  OFST : TwbSignature = 'OFST';\n  ONAM : TwbSignature = 'ONAM';\n  PACK : TwbSignature = 'PACK';\n  PBEA : TwbSignature = 'PBEA';\n  PERK : TwbSignature = 'PERK';\n  PFIG : TwbSignature = 'PFIG';\n  PFPC : TwbSignature = 'PFPC';\n  PGAG : TwbSignature = 'PGAG';\n  PGRE : TwbSignature = 'PGRE';\n  PMIS : TwbSignature = 'PMIS';\n  TRGT : TwbSignature = 'TRGT';\n  PGRI : TwbSignature = 'PGRI';\n  PGRL : TwbSignature = 'PGRL';\n  PGRP : TwbSignature = 'PGRP';\n  PGRR : TwbSignature = 'PGRR';\n  PKAM : TwbSignature = 'PKAM';\n  PKDD : TwbSignature = 'PKDD';\n  PKDT : TwbSignature = 'PKDT';\n  PKE2 : TwbSignature = 'PKE2';\n  PKED : TwbSignature = 'PKED';\n  PKFD : TwbSignature = 'PKFD';\n  PKID : TwbSignature = 'PKID';\n  PKPT : TwbSignature = 'PKPT';\n  PKW3 : TwbSignature = 'PKW3';\n  PLD2 : TwbSignature = 'PLD2';\n  PLDT : TwbSignature = 'PLDT';\n  PLYR : TwbSignature = 'PLYR';\n  PNAM : TwbSignature = 'PNAM';\n  POBA : TwbSignature = 'POBA';\n  POCA : TwbSignature = 'POCA';\n  POEA : TwbSignature = 'POEA';\n  PRKC : TwbSignature = 'PRKC';\n  PRKE : TwbSignature = 'PRKE';\n  PRKF : TwbSignature = 'PRKF';\n  PROJ : TwbSignature = 'PROJ';\n  PSDT : TwbSignature = 'PSDT';\n  PTD2 : TwbSignature = 'PTD2';\n  PTDT : TwbSignature = 'PTDT';\n  PUID : TwbSignature = 'PUID';\n  PWAT : TwbSignature = 'PWAT';\n  QNAM : TwbSignature = 'QNAM';\n  QOBJ : TwbSignature = 'QOBJ';\n  QSDT : TwbSignature = 'QSDT';\n  QSTA : TwbSignature = 'QSTA';\n  QSTI : TwbSignature = 'QSTI';\n  TPIC : TwbSignature = 'TPIC';\n  QSTR : TwbSignature = 'QSTR';\n  QUST : TwbSignature = 'QUST';\n  RACE : TwbSignature = 'RACE';\n  RADS : TwbSignature = 'RADS';\n  RAFB : TwbSignature = 'RAFB';\n  RAFD : TwbSignature = 'RAFD';\n  RAGA : TwbSignature = 'RAGA';\n  RAPS : TwbSignature = 'RAPS';\n  RCLR : TwbSignature = 'RCLR';\n  RDAT : TwbSignature = 'RDAT';\n  RDMD : TwbSignature = 'RDMD';\n  RDMO : TwbSignature = 'RDMO';\n  RDMP : TwbSignature = 'RDMP';\n  RDGS : TwbSignature = 'RDGS';\n  RDOT : TwbSignature = 'RDOT';\n  RDSD : TwbSignature = 'RDSD';\n  RDWT : TwbSignature = 'RDWT';\n  REFR : TwbSignature = 'REFR';\n  REGN : TwbSignature = 'REGN';\n  REPL : TwbSignature = 'REPL';\n  RGDL : TwbSignature = 'RGDL';\n  RNAM : TwbSignature = 'RNAM';\n  RPLD : TwbSignature = 'RPLD';\n  RPLI : TwbSignature = 'RPLI';\n  SCDA : TwbSignature = 'SCDA';\n  SCHR : TwbSignature = 'SCHR';\n  SCOL : TwbSignature = 'SCOL';\n  SCPT : TwbSignature = 'SCPT';\n  SCRI : TwbSignature = 'SCRI';\n  SCRN : TwbSignature = 'SCRN';\n  SCRO : TwbSignature = 'SCRO';\n  SCRV : TwbSignature = 'SCRV';\n  SCTX : TwbSignature = 'SCTX';\n  SCVR : TwbSignature = 'SCVR';\n  SLCP : TwbSignature = 'SLCP';\n  SLSD : TwbSignature = 'SLSD';\n  SNAM : TwbSignature = 'SNAM';\n  SNDD : TwbSignature = 'SNDD';\n  SNDX : TwbSignature = 'SNDX';\n  SOUL : TwbSignature = 'SOUL';\n  SOUN : TwbSignature = 'SOUN';\n  SPEL : TwbSignature = 'SPEL';\n  SPIT : TwbSignature = 'SPIT';\n  SPLO : TwbSignature = 'SPLO';\n  STAT : TwbSignature = 'STAT';\n  TACT : TwbSignature = 'TACT';\n  TCLF : TwbSignature = 'TCLF';\n  TCLT : TwbSignature = 'TCLT';\n  TERM : TwbSignature = 'TERM';\n  TES4 : TwbSignature = 'TES4';\n  TNAM : TwbSignature = 'TNAM';\n  TPLT : TwbSignature = 'TPLT';\n  TRDT : TwbSignature = 'TRDT';\n  TREE : TwbSignature = 'TREE';\n  TX00 : TwbSignature = 'TX00';\n  TX01 : TwbSignature = 'TX01';\n  TX02 : TwbSignature = 'TX02';\n  TX03 : TwbSignature = 'TX03';\n  TX04 : TwbSignature = 'TX04';\n  TX05 : TwbSignature = 'TX05';\n  TXST : TwbSignature = 'TXST';\n  UNAM : TwbSignature = 'UNAM';\n  VCLR : TwbSignature = 'VCLR';\n  VHGT : TwbSignature = 'VHGT';\n  VNAM : TwbSignature = 'VNAM';\n  VNML : TwbSignature = 'VNML';\n  VTCK : TwbSignature = 'VTCK';\n  VTEX : TwbSignature = 'VTEX';\n  VTXT : TwbSignature = 'VTXT';\n  VTYP : TwbSignature = 'VTYP';\n  WATR : TwbSignature = 'WATR';\n  WEAP : TwbSignature = 'WEAP';\n  WLST : TwbSignature = 'WLST';\n  WNAM : TwbSignature = 'WNAM';\n  WRLD : TwbSignature = 'WRLD';\n  WTHR : TwbSignature = 'WTHR';\n  XACT : TwbSignature = 'XACT';\n  XAMC : TwbSignature = 'XAMC';\n  XAMT : TwbSignature = 'XAMT';\n  XAPD : TwbSignature = 'XAPD';\n  XAPR : TwbSignature = 'XAPR';\n  XCAS : TwbSignature = 'XCAS';\n  XCCM : TwbSignature = 'XCCM';\n  XCET : TwbSignature = 'XCET';\n  XCHG : TwbSignature = 'XCHG';\n  XCIM : TwbSignature = 'XCIM';\n  XCLC : TwbSignature = 'XCLC';\n  XCLL : TwbSignature = 'XCLL';\n  XCLP : TwbSignature = 'XCLP';\n  XCLR : TwbSignature = 'XCLR';\n  XCLW : TwbSignature = 'XCLW';\n  XCMO : TwbSignature = 'XCMO';\n  XCMT : TwbSignature = 'XCMT';\n  XCNT : TwbSignature = 'XCNT';\n  XCWT : TwbSignature = 'XCWT';\n  XEMI : TwbSignature = 'XEMI';\n  XESP : TwbSignature = 'XESP';\n  XEZN : TwbSignature = 'XEZN';\n  XGLB : TwbSignature = 'XGLB';\n  XHLP : TwbSignature = 'XHLP';\n  XDCR : TwbSignature = 'XDCR';\n  XHLT : TwbSignature = 'XHLT';\n  XIBS : TwbSignature = 'XIBS';\n  XLCM : TwbSignature = 'XLCM';\n  XLKR : TwbSignature = 'XLKR';\n  XLOC : TwbSignature = 'XLOC';\n  XLOD : TwbSignature = 'XLOD';\n  XLRM : TwbSignature = 'XLRM';\n  XLTW : TwbSignature = 'XLTW';\n  XMBO : TwbSignature = 'XMBO';\n  XMBP : TwbSignature = 'XMBP';\n  XMBR : TwbSignature = 'XMBR';\n  XMRC : TwbSignature = 'XMRC';\n  XMRK : TwbSignature = 'XMRK';\n  XNAM : TwbSignature = 'XNAM';\n  XNDP : TwbSignature = 'XNDP';\n  XOCP : TwbSignature = 'XOCP';\n  XORD : TwbSignature = 'XORD';\n  XOWN : TwbSignature = 'XOWN';\n  XPOD : TwbSignature = 'XPOD';\n  XPTL : TwbSignature = 'XPTL';\n  XPPA : TwbSignature = 'XPPA';\n  XPRD : TwbSignature = 'XPRD';\n  XPRM : TwbSignature = 'XPRM';\n  XPWR : TwbSignature = 'XPWR';\n  XRAD : TwbSignature = 'XRAD';\n  XRDO : TwbSignature = 'XRDO';\n  XRDS : TwbSignature = 'XRDS';\n  XRGB : TwbSignature = 'XRGB';\n  XRGD : TwbSignature = 'XRGD';\n  XRMR : TwbSignature = 'XRMR';\n  XRNK : TwbSignature = 'XRNK';\n  XRTM : TwbSignature = 'XRTM';\n  XSCL : TwbSignature = 'XSCL';\n  XSED : TwbSignature = 'XSED';\n  XSRF : TwbSignature = 'XSRF';\n  XSRD : TwbSignature = 'XSRD';\n  XTEL : TwbSignature = 'XTEL';\n  XTRG : TwbSignature = 'XTRG';\n  XTRI : TwbSignature = 'XTRI';\n  XXXX : TwbSignature = 'XXXX';\n  YNAM : TwbSignature = 'YNAM';\n  ZNAM : TwbSignature = 'ZNAM';\n\nvar\n  wbPKDTSpecificFlagsUnused : Boolean;\n  wbEDID: IwbSubRecordDef;\n  wbEDIDReq: IwbSubRecordDef;\n  wbBMDT: IwbSubRecordDef;\n  wbYNAM: IwbSubRecordDef;\n  wbZNAM: IwbSubRecordDef;\n  wbCOED: IwbSubRecordDef;\n  wbXLCM: IwbSubRecordDef;\n  wbEITM: IwbSubRecordDef;\n  wbREPL: IwbSubRecordDef;\n  wbBIPL: IwbSubRecordDef;\n  wbOBND: IwbSubRecordDef;\n  wbOBNDReq: IwbSubRecordDef;\n  wbDEST: IwbSubRecordStructDef;\n  wbDESTActor: IwbSubRecordStructDef;\n  wbDODT: IwbSubRecordDef;\n  wbXOWN: IwbSubRecordDef;\n  wbXGLB: IwbSubRecordDef;\n  wbXRGD: IwbSubRecordDef;\n  wbXRGB: IwbSubRecordDef;\n  wbSLSD: IwbSubRecordDef;\n  wbSPLO: IwbSubRecordDef;\n  wbSPLOs: IwbSubRecordArrayDef;\n  wbCNTO: IwbSubRecordStructDef;\n  wbCNTOs: IwbSubRecordArrayDef;\n  wbAIDT: IwbSubRecordDef;\n  wbCSDT: IwbSubRecordStructDef;\n  wbCSDTs: IwbSubRecordArrayDef;\n  wbFULL: IwbSubRecordDef;\n  wbFULLActor: IwbSubRecordDef;\n  wbFULLReq: IwbSubRecordDef;\n  wbXNAM: IwbSubRecordDef;\n  wbXNAMs: IwbSubRecordArrayDef;\n  wbDESC: IwbSubRecordDef;\n  wbDESCReq: IwbSubRecordDef;\n  wbXSCL: IwbSubRecordDef;\n  wbDATAPosRot : IwbSubRecordDef;\n  wbPosRot : IwbStructDef;\n  wbMODD: IwbSubRecordDef;\n  wbMOSD: IwbSubRecordDef;\n  wbMODL: IwbSubRecordStructDef;\n  wbMODS: IwbSubRecordDef;\n  wbMO2S: IwbSubRecordDef;\n  wbMO3S: IwbSubRecordDef;\n  wbMO4S: IwbSubRecordDef;\n  wbMODLActor: IwbSubRecordStructDef;\n  wbMODLReq: IwbSubRecordStructDef;\n  wbCTDA: IwbSubRecordDef;\n  wbSCHRReq: IwbSubRecordDef;\n  wbCTDAs: IwbSubRecordArrayDef;\n  wbCTDAsReq: IwbSubRecordArrayDef;\n  wbSCROs: IwbSubRecordArrayDef;\n  wbPGRP: IwbSubRecordDef;\n  wbEmbeddedScript: IwbSubRecordStructDef;\n  wbEmbeddedScriptPerk: IwbSubRecordStructDef;\n  wbEmbeddedScriptReq: IwbSubRecordStructDef;\n  wbSCRI: IwbSubRecordDef;\n  wbSCRIActor: IwbSubRecordDef;\n  wbFaceGen: IwbSubRecordStructDef;\n  wbFaceGenNPC: IwbSubRecordStructDef;\n  wbENAM: IwbSubRecordDef;\n  wbFGGS: IwbSubRecordDef;\n  wbXLOD: IwbSubRecordDef;\n  wbXESP: IwbSubRecordDef;\n  wbICON: IwbSubRecordStructDef;\n  wbICONReq: IwbSubRecordStructDef;\n  wbActorValue: IwbIntegerDef;\n  wbETYP: IwbSubRecordDef;\n  wbETYPReq: IwbSubRecordDef;\n  wbEFID: IwbSubRecordDef;\n  wbEFIT: IwbSubRecordDef;\n  wbEffects: IwbSubRecordArrayDef;\n  wbEffectsReq: IwbSubRecordArrayDef;\n  wbBPNDStruct: IwbSubRecordDef;\n  wbTimeInterpolator: IwbStructDef;\n  wbColorInterpolator: IwbStructDef;\n\nfunction wbNVTREdgeToStr(aInt: Int64; const aElement: IwbElement; aType: TwbCallbackType): string;\nvar\n  Index      : Integer;\n  Flags      : Cardinal;\n  IsExternal : Boolean;\n  Container  : IwbContainerElementRef;\nbegin\n  Result := '';\n  IsExternal := False;\n  if Supports(aElement, IwbContainerElementRef, Container) then begin\n    Index := StrToIntDef(Copy(Container.Name, 11, 1), -1);\n    if (Index >= 0) and (Index <= 2) then begin\n      Flags := Container.ElementNativeValues['..\\..\\Flags'];\n      IsExternal := Flags and (Cardinal(1) shl Index) <> 0;\n    end;\n  end;\n\n  if IsExternal then begin\n    case aType of\n      ctToStr: begin\n        Result := IntToStr(aInt);\n        if Container.ElementExists['..\\..\\..\\..\\NVEX\\Connection #' + IntToStr(aInt)] then\n          Result := Result + ' (Triangle #' +\n            Container.ElementValues['..\\..\\..\\..\\NVEX\\Connection #' + IntToStr(aInt) + '\\Triangle'] + ' in ' +\n            Container.ElementValues['..\\..\\..\\..\\NVEX\\Connection #' + IntToStr(aInt) + '\\Navigation Mesh'] + ')'\n        else\n          Result := Result + ' <Error: NVEX\\Connection #' + IntToStr(aInt) + ' is missing>';\n      end;\n      ctToSortKey:\n        if Container.ElementExists['..\\..\\..\\..\\NVEX\\Connection #' + IntToStr(aInt)] then\n          Result :=\n            Container.ElementSortKeys['..\\..\\..\\..\\NVEX\\Connection #' + IntToStr(aInt) + '\\Navigation Mesh', True] + '|' +\n            Container.ElementSortKeys['..\\..\\..\\..\\NVEX\\Connection #' + IntToStr(aInt) + '\\Triangle', True];\n      ctCheck:\n        if Container.ElementExists['..\\..\\..\\..\\NVEX\\Connection #' + IntToStr(aInt)] then\n          Result := ''\n        else\n          Result := 'NVEX\\Connection #' + IntToStr(aInt) + ' is missing';\n    end\n  end else\n    case aType of\n      ctToStr: Result := IntToStr(aInt);\n    end;\nend;\n\nfunction wbNVTREdgeToInt(const aString: string; const aElement: IwbElement): Int64;\nbegin\n  Result := StrToInt64(aString);\nend;\n\n\nfunction wbEPFDActorValueToStr(aInt: Int64; const aElement: IwbElement; aType: TwbCallbackType): string;\nvar\n  AsCardinal : Cardinal;\n  AsFloat    : Single;\nbegin\n  AsCardinal := aInt;\n  AsFloat := PSingle(@AsCardinal)^;\n  aInt := Round(AsFloat);\n  case aType of\n    ctToStr: Result := wbActorValueEnum.ToString(aInt, aElement);\n    ctToSortKey: Result := wbActorValueEnum.ToSortKey(aInt, aElement);\n    ctCheck: Result := wbActorValueEnum.Check(aInt, aElement);\n    ctToEditValue: Result := wbActorValueEnum.ToEditValue(aInt, aElement);\n    ctEditType: Result := 'ComboBox';\n    ctEditInfo: Result := wbActorValueEnum.EditInfo[aInt, aElement];\n  end;\nend;\n\nfunction wbEPFDActorValueToInt(const aString: string; const aElement: IwbElement): Int64;\nvar\n  AsCardinal : Cardinal;\n  AsFloat    : Single;\nbegin\n  AsFloat := wbActorValueEnum.FromEditValue(aString, aElement);\n  PSingle(@AsCardinal)^ := AsFloat;\n  Result := AsCardinal;\nend;\n\nfunction wbCTDAParam2VariableNameToStr(aInt: Int64; const aElement: IwbElement; aType: TwbCallbackType): string;\nvar\n  Container  : IwbContainerElementRef;\n  //Container2 : IwbContainerElementRef;\n  Param1     : IwbElement;\n  MainRecord : IwbMainRecord;\n  BaseRecord : IwbMainRecord;\n  ScriptRef  : IwbElement;\n  Script     : IwbMainRecord;\n  Variables  : TStringList;\n  LocalVars  : IwbContainerElementRef;\n  LocalVar   : IwbContainerElementRef;\n  i, j       : Integer;\n  s          : string;\nbegin\n  case aType of\n    ctToStr: Result := IntToStr(aInt) + ' <Warning: Could not resolve Parameter 1>';\n    ctToEditValue: Result := IntToStr(aInt);\n    ctToSortKey: begin\n      Result := IntToHex64(aInt, 8);\n      Exit;\n    end;\n    ctCheck: Result := '<Warning: Could not resolve Parameter 1>';\n    ctEditType: Result := '';\n    ctEditInfo: Result := '';\n  end;\n\n  if not Assigned(aElement) then Exit;\n  Container := GetContainerRefFromUnionOrValue(aElement);\n  if not Assigned(Container) then Exit;\n\n  Param1 := Container.ElementByName['Parameter #1'];\n\n  if not Assigned(Param1) then\n    Exit;\n\n  MainRecord := nil;\n  if not Supports(Param1.LinksTo, IwbMainRecord, MainRecord) then\n    Exit;\n{    if Param1.NativeValue = 0 then\n      if Supports(Container.Container, IwbContainerElementRef, Container) then\n        for i := 0 to Pred(Container.ElementCount) do\n          if Supports(Container.Elements[i], IwbContainerElementRef, Container2) then\n            if SameText(Container2.ElementValues['Function'], 'GetIsID') then begin\n              Param1 := Container2.ElementByName['Parameter #1'];\n              if Supports(Param1.LinksTo, IwbMainRecord, MainRecord) then\n                Break;\n            end;}\n\n  if not Assigned(MainRecord) then\n    Exit;\n\n  BaseRecord := MainRecord.BaseRecord;\n  if Assigned(BaseRecord) then\n    MainRecord := BaseRecord;\n\n  ScriptRef := MainRecord.RecordBySignature['SCRI'];\n\n  if not Assigned(ScriptRef) then begin\n    case aType of\n      ctToStr: Result := IntToStr(aInt) + ' <Warning: \"'+MainRecord.ShortName+'\" does not contain a SCRI subrecord>';\n      ctCheck: Result := '<Warning: \"'+MainRecord.ShortName+'\" does not contain a SCRI subrecord>';\n    end;\n    Exit;\n  end;\n\n  if not Supports(ScriptRef.LinksTo, IwbMainRecord, Script) then begin\n    case aType of\n      ctToStr: Result := IntToStr(aInt) + ' <Warning: \"'+MainRecord.ShortName+'\" does not have a valid script>';\n      ctCheck: Result := '<Warning: \"'+MainRecord.ShortName+'\" does not have a valid script>';\n    end;\n    Exit;\n  end;\n\n  Script := Script.HighestOverrideOrSelf[aElement._File.LoadOrder];\n\n  case aType of\n    ctEditType: begin\n      Result := 'ComboBox';\n      Exit;\n    end;\n    ctEditInfo:\n      Variables := TStringList.Create;\n  else\n    Variables := nil;\n  end;\n  try\n    if Supports(Script.ElementByName['Local Variables'], IwbContainerElementRef, LocalVars) then begin\n      for i := 0 to Pred(LocalVars.ElementCount) do\n        if Supports(LocalVars.Elements[i], IwbContainerElementRef, LocalVar) then begin\n          j := LocalVar.ElementNativeValues['SLSD\\Index'];\n          s := LocalVar.ElementNativeValues['SCVR'];\n          if Assigned(Variables) then\n            Variables.AddObject(s, TObject(j))\n          else if j = aInt then begin\n            case aType of\n              ctToStr, ctToEditValue: Result := s;\n              ctCheck: Result := '';\n            end;\n            Exit;\n          end;\n        end;\n    end;\n\n    case aType of\n      ctToStr: Result := IntToStr(aInt) + ' <Warning: Variable Index not found in \"' + Script.Name + '\">';\n      ctCheck: Result := '<Warning: Variable Index not found in \"' + Script.Name + '\">';\n      ctEditInfo: begin\n        Variables.Sort;\n        Result := Variables.CommaText;\n      end;\n    end;\n  finally\n    FreeAndNil(Variables);\n  end;\nend;\n\nfunction wbCTDAParam2VariableNameToInt(const aString: string; const aElement: IwbElement): Int64;\nvar\n  Container  : IwbContainerElementRef;\n  Param1     : IwbElement;\n  MainRecord : IwbMainRecord;\n  BaseRecord : IwbMainRecord;\n  ScriptRef  : IwbElement;\n  Script     : IwbMainRecord;\n  LocalVars  : IwbContainerElementRef;\n  LocalVar   : IwbContainerElementRef;\n  i, j       : Integer;\n  s          : string;\nbegin\n  Result := StrToInt64Def(aString, Low(Cardinal));\n  if Result <> Low(Cardinal) then\n    Exit;\n\n  if not Assigned(aElement) then\n    raise Exception.Create('aElement not specified');\n\n  Container := GetContainerRefFromUnionOrValue(aElement);\n\n  if not Assigned(Container) then\n    raise Exception.Create('Container not assigned');\n\n  Param1 := Container.ElementByName['Parameter #1'];\n\n  if not Assigned(Param1) then\n    raise Exception.Create('Could not find \"Parameter #1\"');\n\n  if not Supports(Param1.LinksTo, IwbMainRecord, MainRecord) then\n    raise Exception.Create('\"Parameter #1\" does not reference a valid main record');\n\n  BaseRecord := MainRecord.BaseRecord;\n  if Assigned(BaseRecord) then\n    MainRecord := BaseRecord;\n\n  ScriptRef := MainRecord.RecordBySignature['SCRI'];\n\n  if not Assigned(ScriptRef) then\n    raise Exception.Create('\"'+MainRecord.ShortName+'\" does not contain a SCRI subrecord');\n\n  if not Supports(ScriptRef.LinksTo, IwbMainRecord, Script) then\n    raise Exception.Create('\"'+MainRecord.ShortName+'\" does not have a valid script');\n\n  Script := Script.HighestOverrideOrSelf[aElement._File.LoadOrder];\n\n  if Supports(Script.ElementByName['Local Variables'], IwbContainerElementRef, LocalVars) then begin\n    for i := 0 to Pred(LocalVars.ElementCount) do\n      if Supports(LocalVars.Elements[i], IwbContainerElementRef, LocalVar) then begin\n        j := LocalVar.ElementNativeValues['SLSD\\Index'];\n        s := LocalVar.ElementNativeValues['SCVR'];\n        if SameText(s, Trim(aString)) then begin\n          Result := j;\n          Exit;\n        end;\n      end;\n  end;\n\n  raise Exception.Create('Variable \"'+aString+'\" was not found in \"'+MainRecord.ShortName+'\"');\nend;\n\nfunction wbCTDAParam2QuestStageToStr(aInt: Int64; const aElement: IwbElement; aType: TwbCallbackType): string;\nvar\n  Container  : IwbContainerElementRef;\n  Param1     : IwbElement;\n  MainRecord : IwbMainRecord;\n  EditInfos  : TStringList;\n  Stages     : IwbContainerElementRef;\n  Stage      : IwbContainerElementRef;\n  i, j       : Integer;\n  s, t       : string;\nbegin\n  case aType of\n    ctToStr: Result := IntToStr(aInt) + ' <Warning: Could not resolve Parameter 1>';\n    ctToEditValue: Result := IntToStr(aInt);\n    ctToSortKey: begin\n      Result := IntToHex64(aInt, 8);\n      Exit;\n    end;\n    ctCheck: Result := '<Warning: Could not resolve Parameter 1>';\n    ctEditType: Result := '';\n    ctEditInfo: Result := '';\n  end;\n\n  if not Assigned(aElement) then Exit;\n  Container := GetContainerRefFromUnionOrValue(aElement);\n  if not Assigned(Container) then Exit;\n\n  Param1 := Container.ElementByName['Parameter #1'];\n\n  if not Assigned(Param1) then\n    Exit;\n\n  if not Supports(Param1.LinksTo, IwbMainRecord, MainRecord) then\n    Exit;\n\n  MainRecord := MainRecord.WinningOverride;\n\n  if MainRecord.Signature <> QUST then begin\n    case aType of\n      ctToStr: Result := IntToStr(aInt) + ' <Warning: \"'+MainRecord.ShortName+'\" is not a Quest record>';\n      ctCheck: Result := '<Warning: \"'+MainRecord.ShortName+'\" is not a Quest record>';\n    end;\n    Exit;\n  end;\n\n  case aType of\n    ctEditType: begin\n      Result := 'ComboBox';\n      Exit;\n    end;\n    ctEditInfo:\n      EditInfos := TStringList.Create;\n  else\n    EditInfos := nil;\n  end;\n  try\n    if Supports(MainRecord.ElementByName['Stages'], IwbContainerElementRef, Stages) then begin\n      for i := 0 to Pred(Stages.ElementCount) do\n        if Supports(Stages.Elements[i], IwbContainerElementRef, Stage) then begin\n          j := Stage.ElementNativeValues['INDX'];\n          s := Trim(Stage.ElementValues['Log Entries\\Log Entry\\CNAM']);\n          t := IntToStr(j);\n          while Length(t) < 3 do\n            t := '0' + t;\n          if s <> '' then\n            t := t + ' ' + s;\n          if Assigned(EditInfos) then\n            EditInfos.AddObject(t, TObject(j))\n          else if j = aInt then begin\n            case aType of\n              ctToStr, ctToEditValue: Result := t;\n              ctCheck: Result := '';\n            end;\n            Exit;\n          end;\n        end;\n    end;\n\n    case aType of\n      ctToStr: Result := IntToStr(aInt) + ' <Warning: Quest Stage not found in \"' + MainRecord.Name + '\">';\n      ctCheck: Result := '<Warning: Quest Stage not found in \"' + MainRecord.Name + '\">';\n      ctEditInfo: begin\n        EditInfos.Sort;\n        Result := EditInfos.CommaText;\n      end;\n    end;\n  finally\n    FreeAndNil(EditInfos);\n  end;\nend;\n\nfunction wbPerkDATAQuestStageToStr(aInt: Int64; const aElement: IwbElement; aType: TwbCallbackType): string;\nvar\n  Container  : IwbContainerElementRef;\n  Param1     : IwbElement;\n  MainRecord : IwbMainRecord;\n  EditInfos  : TStringList;\n  Stages     : IwbContainerElementRef;\n  Stage      : IwbContainerElementRef;\n  i, j       : Integer;\n  s, t       : string;\nbegin\n  case aType of\n    ctToStr: Result := IntToStr(aInt) + ' <Warning: Could not resolve Quest>';\n    ctToEditValue: Result := IntToStr(aInt);\n    ctToSortKey: begin\n      Result := IntToHex64(aInt, 8);\n      Exit;\n    end;\n    ctCheck: Result := '<Warning: Could not resolve Quest>';\n    ctEditType: Result := '';\n    ctEditInfo: Result := '';\n  end;\n\n  if not Assigned(aElement) then Exit;\n  Container := GetContainerRefFromUnionOrValue(aElement);\n  if not Assigned(Container) then Exit;\n\n  Param1 := Container.ElementByName['Quest'];\n\n  if not Assigned(Param1) then\n    Exit;\n\n  if not Supports(Param1.LinksTo, IwbMainRecord, MainRecord) then\n    Exit;\n\n  MainRecord := MainRecord.WinningOverride;\n\n  if MainRecord.Signature <> QUST then begin\n    case aType of\n      ctToStr: Result := IntToStr(aInt) + ' <Warning: \"'+MainRecord.ShortName+'\" is not a Quest record>';\n      ctCheck: Result := '<Warning: \"'+MainRecord.ShortName+'\" is not a Quest record>';\n    end;\n    Exit;\n  end;\n\n  case aType of\n    ctEditType: begin\n      Result := 'ComboBox';\n      Exit;\n    end;\n    ctEditInfo:\n      EditInfos := TStringList.Create;\n  else\n    EditInfos := nil;\n  end;\n  try\n    if Supports(MainRecord.ElementByName['Stages'], IwbContainerElementRef, Stages) then begin\n      for i := 0 to Pred(Stages.ElementCount) do\n        if Supports(Stages.Elements[i], IwbContainerElementRef, Stage) then begin\n          j := Stage.ElementNativeValues['INDX'];\n          s := Trim(Stage.ElementValues['Log Entries\\Log Entry\\CNAM']);\n          t := IntToStr(j);\n          while Length(t) < 3 do\n            t := '0' + t;\n          if s <> '' then\n            t := t + ' ' + s;\n          if Assigned(EditInfos) then\n            EditInfos.AddObject(t, TObject(j))\n          else if j = aInt then begin\n            case aType of\n              ctToStr, ctToEditValue: Result := t;\n              ctCheck: Result := '';\n            end;\n            Exit;\n          end;\n        end;\n    end;\n\n    case aType of\n      ctToStr: Result := IntToStr(aInt) + ' <Warning: Quest Stage not found in \"' + MainRecord.Name + '\">';\n      ctCheck: Result := '<Warning: Quest Stage not found in \"' + MainRecord.Name + '\">';\n      ctEditInfo: begin\n        EditInfos.Sort;\n        Result := EditInfos.CommaText;\n      end;\n    end;\n  finally\n    FreeAndNil(EditInfos);\n  end;\nend;\n\nfunction wbCTDAParam2QuestObjectiveToStr(aInt: Int64; const aElement: IwbElement; aType: TwbCallbackType): string;\nvar\n  Container  : IwbContainerElementRef;\n  Param1     : IwbElement;\n  MainRecord : IwbMainRecord;\n  EditInfos  : TStringList;\n  Objectives     : IwbContainerElementRef;\n  Objective      : IwbContainerElementRef;\n  i, j       : Integer;\n  s, t       : string;\nbegin\n  case aType of\n    ctToStr: Result := IntToStr(aInt) + ' <Warning: Could not resolve Parameter 1>';\n    ctToEditValue: Result := IntToStr(aInt);\n    ctToSortKey: begin\n      Result := IntToHex64(aInt, 8);\n      Exit;\n    end;\n    ctCheck: Result := '<Warning: Could not resolve Parameter 1>';\n    ctEditType: Result := '';\n    ctEditInfo: Result := '';\n  end;\n\n  if not Assigned(aElement) then Exit;\n  Container := GetContainerRefFromUnionOrValue(aElement);\n  if not Assigned(Container) then Exit;\n\n  Param1 := Container.ElementByName['Parameter #1'];\n\n  if not Assigned(Param1) then\n    Exit;\n\n  if not Supports(Param1.LinksTo, IwbMainRecord, MainRecord) then\n    Exit;\n\n  MainRecord := MainRecord.WinningOverride;\n\n  if MainRecord.Signature <> QUST then begin\n    case aType of\n      ctToStr: Result := IntToStr(aInt) + ' <Warning: \"'+MainRecord.ShortName+'\" is not a Quest record>';\n      ctCheck: Result := '<Warning: \"'+MainRecord.ShortName+'\" is not a Quest record>';\n    end;\n    Exit;\n  end;\n\n  case aType of\n    ctEditType: begin\n      Result := 'ComboBox';\n      Exit;\n    end;\n    ctEditInfo:\n      EditInfos := TStringList.Create;\n  else\n    EditInfos := nil;\n  end;\n  try\n    if Supports(MainRecord.ElementByName['Objectives'], IwbContainerElementRef, Objectives) then begin\n      for i := 0 to Pred(Objectives.ElementCount) do\n        if Supports(Objectives.Elements[i], IwbContainerElementRef, Objective) then begin\n          j := Objective.ElementNativeValues['QOBJ'];\n          s := Trim(Objective.ElementValues['NNAM']);\n          t := IntToStr(j);\n          while Length(t) < 3 do\n            t := '0' + t;\n          if s <> '' then\n            t := t + ' ' + s;\n          if Assigned(EditInfos) then\n            EditInfos.AddObject(t, TObject(j))\n          else if j = aInt then begin\n            case aType of\n              ctToStr, ctToEditValue: Result := t;\n              ctCheck: Result := '';\n            end;\n            Exit;\n          end;\n        end;\n    end;\n\n    case aType of\n      ctToStr: Result := IntToStr(aInt) + ' <Warning: Quest Objective not found in \"' + MainRecord.Name + '\">';\n      ctCheck: Result := '<Warning: Quest Objective not found in \"' + MainRecord.Name + '\">';\n      ctEditInfo: begin\n        EditInfos.Sort;\n        Result := EditInfos.CommaText;\n      end;\n    end;\n  finally\n    FreeAndNil(EditInfos);\n  end;\nend;\n\nfunction wbCTDAParam2QuestStageToInt(const aString: string; const aElement: IwbElement): Int64;\nvar\n  i    : Integer;\n  s    : string;\nbegin\n  i := 1;\n  s := Trim(aString);\n  while (i <= Length(s)) and (s[i] in ['0'..'9']) do\n    Inc(i);\n  s := Copy(s, 1, Pred(i));\n\n  Result := StrToInt(s);\nend;\n\nfunction wbCTDAParam2QuestObjectiveToInt(const aString: string; const aElement: IwbElement): Int64;\nvar\n  i    : Integer;\n  s    : string;\nbegin\n  i := 1;\n  s := Trim(aString);\n  while (i <= Length(s)) and (s[i] in ['0'..'9']) do\n    Inc(i);\n  s := Copy(s, 1, Pred(i));\n\n  Result := StrToInt(s);\nend;\n\n\nfunction wbClmtMoonsPhaseLength(aInt: Int64; const aElement: IwbElement; aType: TwbCallbackType): string;\nvar\n  PhaseLength : Byte;\n  Masser      : Boolean;\n  Secunda     : Boolean;\nbegin\n  Result := '';\n  if aType = ctToSortKey then begin\n    Result := IntToHex64(aInt, 2);\n  end else if aType = ctToStr then begin\n    PhaseLength := aInt mod 64;\n    Masser := (aInt and 64) <> 0;\n    Secunda := (aInt and 128) <> 0;\n    if Masser then\n      if Secunda then\n        Result := 'Masser, Secunda / '\n      else\n        Result := 'Masser / '\n    else\n      if Secunda then\n        Result := 'Secunda / '\n      else\n        Result := 'No Moon / ';\n    Result := Result + IntToStr(PhaseLength);\n  end;\nend;\n\nfunction wbClmtTime(aInt: Int64; const aElement: IwbElement; aType: TwbCallbackType): string;\nbegin\n  if aType = ctToSortKey then\n    Result := IntToHex64(aInt, 4)\n  else if aType = ctToStr then\n    Result := TimeToStr( EncodeTime(aInt div 6, (aInt mod 6) * 10, 0, 0) )\n  else\n    Result := '';\nend;\n\nfunction wbREFRNavmeshTriangleToStr(aInt: Int64; const aElement: IwbElement; aType: TwbCallbackType): string;\nvar\n  Container  : IwbContainerElementRef;\n  Navmesh    : IwbElement;\n  MainRecord : IwbMainRecord;\n  Triangles  : IwbContainerElementRef;\nbegin\n  case aType of\n    ctToStr: Result := IntToStr(aInt);\n    ctToEditValue: Result := IntToStr(aInt);\n    ctToSortKey: begin\n      Result := IntToHex64(aInt, 8);\n      Exit;\n    end;\n    ctCheck: Result := '';\n    ctEditType: Result := '';\n    ctEditInfo: Result := '';\n  end;\n\n  if not Assigned(aElement) then Exit;\n  Container := GetContainerRefFromUnionOrValue(aElement);\n  if not Assigned(Container) then Exit;\n\n  Navmesh := Container.Elements[0];\n\n  if not Assigned(Navmesh) then\n    Exit;\n\n  if not Supports(Navmesh.LinksTo, IwbMainRecord, MainRecord) then\n    Exit;\n\n  MainRecord := MainRecord.WinningOverride;\n\n  if MainRecord.Signature <> NAVM then begin\n    case aType of\n      ctToStr: Result := IntToStr(aInt) + ' <Warning: \"'+MainRecord.ShortName+'\" is not a Navmesh record>';\n      ctCheck: Result := '<Warning: \"'+MainRecord.ShortName+'\" is not a Navmesh record>';\n    end;\n    Exit;\n  end;\n\n  if not wbSimpleRecords and (aType = ctCheck) and Supports(MainRecord.ElementByPath['NVTR'], IwbContainerElementRef, Triangles) then\n    if aInt >= Triangles.ElementCount then\n      Result := '<Warning: Navmesh triangle not found in \"' + MainRecord.Name + '\">';\nend;\n\nfunction wbStringToInt(const aString: string; const aElement: IwbElement): Int64;\nbegin\n  Result := StrToIntDef(aString, 0);\nend;\n\n\nvar\n  wbCtdaTypeFlags : IwbFlagsDef;\n\nfunction wbCtdaTypeToStr(aInt: Int64; const aElement: IwbElement; aType: TwbCallbackType): string;\nvar\n  s: string;\nbegin\n  Result := '';\n  case aType of\n    ctEditType:\n      Result := 'CheckComboBox';\n    ctEditInfo:\n      Result := 'Equal,Greater,Lesser,Or,\"Use Global\",\"Run on Target\"';\n    ctToEditValue: begin\n      Result := '000000';\n      case aInt and $F0 of\n        $00 : Result[1] := '1';\n        $40 : Result[2] := '1';\n        $60 : begin\n                Result[1] := '1';\n                Result[2] := '1';\n              end;\n        $80 : Result[3] := '1';\n        $A0 : begin\n                Result[1] := '1';\n                Result[3] := '1';\n              end;\n      end;\n      if (aInt and $01) <> 0 then\n        Result[4] := '1';\n      if (aInt and $02) <> 0 then\n        Result[6] := '1';\n      if (aInt and $04) <> 0 then\n        Result[5] := '1';\n    end;\n    ctToStr: begin\n      case aInt and $F0 of\n        $00 : Result := 'Equal to';\n        $20 : Result := 'Not equal to';\n        $40 : Result := 'Greater than';\n        $60 : Result := 'Greater than or equal to';\n        $80 : Result := 'Less than';\n        $A0 : Result := 'Less than or equal to';\n      else\n        Result := '<Unknown Compare operator>'\n      end;\n\n      if not Assigned(wbCtdaTypeFlags) then\n        wbCtdaTypeFlags := wbFlags([\n          {0x01} 'Or',\n          {0x02} 'Run on target',\n          {0x04} 'Use global'\n        ]);\n\n      s := wbCtdaTypeFlags.ToString(aInt and $0F, aElement);\n\n      if s <> '' then\n        Result := Result + ' / ' + s;\n    end;\n    ctToSortKey: begin\n      Result := IntToHex64(aInt, 2);\n      Exit;\n    end;\n    ctCheck: begin\n      case aInt and $F0 of\n        $00, $20, $40, $60, $80, $A0 : Result := '';\n      else\n        Result := '<Unknown Compare operator>'\n      end;\n\n      if not Assigned(wbCtdaTypeFlags) then\n        wbCtdaTypeFlags := wbFlags([\n          {0x01} 'Or',\n          {0x02} 'Run on target',\n          {0x04} 'Use global'\n        ]);\n\n      s := wbCtdaTypeFlags.Check(aInt and $0F, aElement);\n\n      if s <> '' then\n        Result := Result + ' / ' + s;\n    end;\n  end;\nend;\n\nfunction wbCtdaTypeToInt(const aString: string; const aElement: IwbElement): Int64;\nvar\n  s: string;\nbegin\n  s := aString + '000000';\n//  Result := 0;\n  if s[1] = '1' then begin\n    if s[2] = '1' then begin\n      if s[3] = '1' then begin\n        Result := $00;\n      end else begin\n        Result := $60;\n      end;\n    end else begin\n      if s[3] = '1' then begin\n        Result := $A0;\n      end else begin\n        Result := $00;\n      end;\n    end;\n  end else begin\n    if s[2] = '1' then begin\n      if s[3] = '1' then begin\n        Result := $20;\n      end else begin\n        Result := $40;\n      end;\n    end else begin\n      if s[3] = '1' then begin\n        Result := $80;\n      end else begin\n        Result := $20;\n      end;\n    end;\n  end;\n  if s[4] = '1' then\n    Result := Result or $01;\n  if s[6] = '1' then\n    Result := Result or $02;\n  if s[5] = '1' then\n    Result := Result or $04;\nend;\n\nprocedure wbHeadPartsAfterSet(const aElement: IwbElement; const aOldValue, aNewValue: Variant);\nvar\n  Container : IwbContainerElementRef;\nbegin\n  if wbBeginInternalEdit then try\n    if Supports(aElement, IwbContainerElementRef, Container) then\n      if (Container.Elements[0].NativeValue = 1) and (Container.ElementCount > 2) then\n        Container.RemoveElement(1);\n  finally\n    wbEndInternalEdit;\n  end;\nend;\n\nprocedure wbMESGDNAMAfterSet(const aElement: IwbElement; const aOldValue, aNewValue: Variant);\nvar\n  OldValue, NewValue : Integer;\n  Container          : IwbContainerElementRef;\nbegin\n  if VarSameValue(aOldValue, aNewValue) then\n    Exit;\n  if Supports(aElement.Container, IwbContainerElementRef, Container) then begin\n    OldValue := Integer(aOldValue) and 1;\n    NewValue := Integer(aNewValue) and 1;\n    if NewValue = OldValue then\n      Exit;\n    if NewValue = 1 then\n      Container.RemoveElement('TNAM')\n    else\n      Container.Add('TNAM', True);\n  end;\nend;\n\nprocedure wbGMSTEDIDAfterSet(const aElement: IwbElement; const aOldValue, aNewValue: Variant);\nvar\n  OldValue, NewValue : string;\n  Container          : IwbContainerElementRef;\nbegin\n  if VarSameValue(aOldValue, aNewValue) then\n    Exit;\n  if Supports(aElement.Container, IwbContainerElementRef, Container) then begin\n    OldValue := aOldValue;\n    NewValue := aNewValue;\n    if (Length(OldValue) < 1) or (Length(OldValue) < 1) or (OldValue[1] <> NewValue[1]) then begin\n      Container.RemoveElement('DATA');\n      Container.Add('DATA', True);\n    end;\n  end;\nend;\n\nprocedure wbFLSTEDIDAfterSet(const aElement: IwbElement; const aOldValue, aNewValue: Variant);\nvar\n  OldValue, NewValue     : string;\n  OldOrdered, NewOrdered : Boolean;\n  Container              : IwbContainerElementRef;\nconst\n  OrderedList = 'OrderedList';\nbegin\n  if VarSameValue(aOldValue, aNewValue) then\n    Exit;\n  if Supports(aElement.Container, IwbContainerElementRef, Container) then begin\n    OldValue := aOldValue;\n    NewValue := aNewValue;\n\n    if Length(OldValue) > Length(OrderedList) then\n      Delete(OldValue, 1, Length(OldValue)-Length(OrderedList));\n    if Length(NewValue) > Length(OrderedList) then\n      Delete(NewValue, 1, Length(NewValue)-Length(OrderedList));\n\n    OldOrdered := SameText(OldValue, OrderedList);\n    NewOrdered := SameText(NewValue, OrderedList);\n\n    if OldOrdered <> NewOrdered then\n      Container.RemoveElement('FormIDs');\n  end;\nend;\n\nprocedure wbCtdaTypeAfterSet(const aElement: IwbElement; const aOldValue, aNewValue: Variant);\nvar\n  OldValue, NewValue: Integer;\n  Container: IwbContainerElementRef;\nbegin\n  if VarSameValue(aOldValue, aNewValue) then\n    Exit;\n  if not Supports(aElement, IwbContainerElementRef, Container) then\n    Exit;\n\n  OldValue := aOldValue and $04;\n  NewValue := aNewValue and $04;\n  if OldValue <> NewValue then\n    Container.ElementNativeValues['..\\Comparison Value'] := 0;\n\n  if aNewValue and $02 then begin\n    Container.ElementNativeValues['..\\Run On'] := 1;\n    if Integer(Container.ElementNativeValues['..\\Run On']) = 1 then\n      aElement.NativeValue := Byte(aNewValue) and not $02;\n  end;\nend;\n\nfunction wbMODTCallback(aInt: Int64; const aElement: IwbElement; aType: TwbCallbackType): string;\nvar\n  Strings: TDynStrings;\n  i: Integer;\nbegin\n  Result := '';\n  if wbLoaderDone and (aType in [ctToStr, ctToSortKey] ) then begin\n    Strings := wbContainerHandler.ResolveHash(aInt);\n    for i := Low(Strings) to High(Strings) do\n      Result := Result + Strings[i] + ', ';\n    SetLength(Result, Length(Result) -2 );\n  end;\nend;\n\n\nfunction wbIdleAnam(aInt: Int64; const aElement: IwbElement; aType: TwbCallbackType): string;\nbegin\n  Result := '';\n  case aType of\n    ctToStr: begin\n      case aInt and not $C0 of\n        0: Result := 'Idle';\n        1: Result := 'Movement';\n        2: Result := 'Left Arm';\n        3: Result := 'Left Hand';\n        4: Result := 'Weapon';\n        5: Result := 'Weapon Up';\n        6: Result := 'Weapon Down';\n        7: Result := 'Special Idle';\n       20: Result := 'Whole Body';\n       21: Result := 'Upper Body';\n      else\n        Result := '<Unknown: '+IntToStr(aInt and not $C0)+'>';\n      end;\n\n      if (aInt and $80) = 0 then\n        Result := Result + ', Must return a file';\n      if (aInt and $40) = 1 then\n        Result := Result + ', Unknown Flag';\n    end;\n    ctToSortKey: begin\n      Result := IntToHex64(aInt, 2);\n    end;\n    ctCheck: begin\n      case aInt and not $C0 of\n        0..7, 20, 21: Result := '';\n      else\n        Result := '<Unknown: '+IntToStr(aInt and not $C0)+'>';\n      end;\n    end;\n  end;\nend;\n\nfunction wbScaledInt4ToStr(aInt: Int64; const aElement: IwbElement; aType: TwbCallbackType): string;\nconst\n  PlusMinus : array[Boolean] of string = ('+', '-');\nbegin\n  Result := '';\n  case aType of\n    ctToStr, ctToEditValue: Result := FloatToStrF(aInt / 10000, ffFixed, 99, 4);\n    ctToSortKey: begin\n      Result := FloatToStrF(aInt / 10000, ffFixed, 99, 4);\n      if Length(Result) < 22 then\n        Result := StringOfChar('0', 22 - Length(Result)) + Result;\n      Result := PlusMinus[aInt < 0] + Result;\n    end;\n    ctCheck: Result := '';\n  end;\nend;\n\nfunction wbScaledInt4ToInt(const aString: string; const aElement: IwbElement): Int64;\nvar\n  f: Extended;\nbegin\n  f := StrToFloat(aString);\n  f := f * 10000;\n  Result := Round(f);\nend;\n\nfunction wbHideFFFF(aInt: Int64; const aElement: IwbElement; aType: TwbCallbackType): string;\nbegin\n  Result := '';\n  if aType = ctToSortKey then\n    Result := IntToHex64(aInt, 4)\n  else if aType = ctToStr then\n    if aInt = $FFFF then\n      Result := 'None'\n    else\n      Result := IntToStr(aInt);\nend;\n\nfunction wbAtxtPosition(aInt: Int64; const aElement: IwbElement; aType: TwbCallbackType): string;\nbegin\n  Result := '';\n  if aType = ctToSortKey then\n    Result := IntToHex64(aInt div 17, 2) + IntToHex64(aInt mod 17, 2)\n  else if aType = ctCheck then begin\n    if (aInt < 0) or (aInt > 288) then\n      Result := '<Out of range: '+IntToStr(aInt)+'>'\n    else\n      Result := '';\n  end else if aType = ctToStr then\n    Result := IntToStr(aInt) + ' -> ' + IntToStr(aInt div 17) + ':' + IntToStr(aInt mod 17);\nend;\n\nfunction wbGLOBFNAM(aInt: Int64; const aElement: IwbElement; aType: TwbCallbackType): string;\nbegin\n  Result := '';\n  case aType of\n    ctToStr: begin\n      case aInt of\n        Ord('s'): Result := 'Short';\n        Ord('l'): Result := 'Long';\n        Ord('f'): Result := 'Float';\n      else\n        Result := '<Unknown: '+IntToStr(aInt)+'>';\n      end;\n    end;\n    ctToSortKey: Result := Chr(aInt);\n    ctCheck: begin\n      case aInt of\n        Ord('s'), Ord('l'), Ord('f'): Result := '';\n      else\n        Result := '<Unknown: '+IntToStr(aInt)+'>';\n      end;\n    end;\n  end;\nend;\n\nfunction wbPlacedAddInfo(const aMainRecord: IwbMainRecord): string;\nvar\n  Rec: IwbRecord;\n  Container: IwbContainer;\n  s: string;\n  Cell: IwbMainRecord;\n  Position: TwbVector;\n  Grid: TwbGridCell;\nbegin\n  Result := '';\n\n  Rec := aMainRecord.RecordBySignature['NAME'];\n  if Assigned(Rec) then begin\n    s := Trim(Rec.Value);\n    if s <> '' then\n      Result := 'places ' + s;\n  end;\n\n  Container := aMainRecord.Container;\n  while Assigned(Container) and (Container.ElementType <> etGroupRecord) do\n    Container := Container.Container;\n\n  if Assigned(Container) then begin\n    s := Trim(Container.Name);\n    if s <> '' then begin\n      if Result <> '' then\n        Result := Result + ' ';\n      Result := Result + 'in ' + s;\n\n      // grid position of persistent reference in exterior persistent cell (interior cells are not persistent)\n      if Supports(aMainRecord.Container, IwbGroupRecord, Container) then\n        Cell := IwbGroupRecord(Container).ChildrenOf;\n      if Assigned(Cell) and Cell.IsPersistent and (Cell.Signature = 'CELL') then\n        if aMainRecord.GetPosition(Position) then begin\n          Grid := wbPositionToGridCell(Position);\n          Result := Result + ' at ' + IntToStr(Grid.x) + ',' + IntToStr(Grid.y);\n        end;\n    end;\n  end;\nend;\n\nfunction wbINFOAddInfo(const aMainRecord: IwbMainRecord): string;\nvar\n  Container: IwbContainer;\n  s: string;\nbegin\n  Result := Trim(aMainRecord.ElementValues['Responses\\Response\\NAM1']);\n  if Result <> '' then\n    Result := '''' + Result + '''';\n\n  Container := aMainRecord.Container;\n  while Assigned(Container) and (Container.ElementType <> etGroupRecord) do\n    Container := Container.Container;\n\n  if Assigned(Container) then begin\n    s := Trim(Container.Name);\n    if s <> '' then begin\n      if Result <> '' then\n        Result := Result + ' ';\n      Result := Result + 'in ' + s;\n    end;\n  end;\n\n  s := Trim(aMainRecord.ElementValues['QSTI']);\n  if s <> '' then begin\n    if Result <> '' then\n      Result := Result + ' ';\n    Result := Result + 'for ' + s;\n  end;\nend;\n\nfunction wbNAVMAddInfo(const aMainRecord: IwbMainRecord): string;\nvar\n  Rec        : IwbRecord;\n  Element    : IwbElement;\n  s          : string;\nbegin\n  Result := '';\n\n  Rec := aMainRecord.RecordBySignature['DATA'];\n  if Assigned(Rec) then begin\n    Element := Rec.ElementByName['Cell'];\n    if Assigned(Element) then\n      Element := Element.LinksTo;\n    if Assigned(Element) then\n      s := Trim(Element.Name);\n    if s <> '' then\n      Result := 'for ' + s;\n  end;\nend;\n\nfunction wbCellAddInfo(const aMainRecord: IwbMainRecord): string;\nvar\n  Rec: IwbRecord;\n  Container: IwbContainer;\n  GroupRecord : IwbGroupRecord;\n  s: string;\nbegin\n  Result := '';\n\n  if not aMainRecord.IsPersistent then begin\n    Rec := aMainRecord.RecordBySignature['XCLC'];\n    if Assigned(Rec) then\n      Result := 'at ' + Rec.Elements[0].Value + ',' + Rec.Elements[1].Value;\n  end;\n\n  Container := aMainRecord.Container;\n  while Assigned(Container) and not\n    (Supports(Container, IwbGroupRecord, GroupRecord) and (GroupRecord.GroupType = 1))  do\n    Container := Container.Container;\n\n  if Assigned(Container) then begin\n    s := wbFormID.ToString(GroupRecord.GroupLabel, aMainRecord);\n    if s <> '' then begin\n      if Result <> '' then\n        s := s + ' ';\n      Result := 'in ' + s + Result;\n    end;\n  end;\nend;\n\nfunction wbWthrDataClassification(aInt: Int64; const aElement: IwbElement; aType: TwbCallbackType): string;\nbegin\n  Result := '';\n  case aType of\n    ctToStr: begin\n      case aInt and not 192 of\n        0: Result := 'None';\n        1: Result := 'Pleasant';\n        2: Result := 'Cloudy';\n        4: Result := 'Rainy';\n        8: Result := 'Snow';\n      else\n        Result := '<Unknown: '+IntToStr(aInt and not 192)+'>';\n      end;\n    end;\n    ctToSortKey: begin\n      Result := IntToHex64(aInt, 2)\n    end;\n    ctCheck: begin\n      case aInt and not 192 of\n        0, 1, 2, 4, 8: Result := '';\n      else\n        Result := '<Unknown: '+IntToStr(aInt and not 192)+'>';\n      end;\n    end;\n  end;\nend;\n\nfunction wbNOTETNAMDecide(aBasePtr: Pointer; aEndPtr: Pointer; const aElement: IwbElement): Integer;\nvar\n  rDATA: IwbRecord;\nbegin\n  Result := 0;\n  rDATA := aElement.Container.RecordBySignature[DATA];\n  if Assigned(rDATA) then\n    if rDATA.NativeValue = 3 then //Voice\n      Result := 1;\nend;\n\nfunction wbNOTESNAMDecide(aBasePtr: Pointer; aEndPtr: Pointer; const aElement: IwbElement): Integer;\nvar\n  rDATA: IwbRecord;\nbegin\n  Result := 0;\n  rDATA := aElement.Container.RecordBySignature[DATA];\n  if Assigned(rDATA) then\n    if rDATA.NativeValue = 3 then //Voice\n      Result := 1;\nend;\n\nfunction wbIPDSDATACount(aBasePtr: Pointer; aEndPtr: Pointer; const aElement: IwbElement): Integer;\nbegin\n  if Assigned(aBasePtr) and Assigned(aEndPtr) then\n    Result := (Cardinal(aBasePtr) - Cardinal(aBasePtr)) div 4\n  else\n    Result := 12;\nend;\n\nfunction wbNAVINAVMGetCount1(aBasePtr: Pointer; aEndPtr: Pointer; const aElement: IwbElement): Integer;\nvar\n  DataContainer : IwbDataContainer;\nbegin\n  Result := 0;\n\n  if Supports(aElement, IwbDataContainer, DataContainer) then begin\n    if DataContainer.ElementType = etArray then\n      if not Supports(DataContainer.Container, IwbDataContainer, DataContainer) then\n        Exit;\n    Assert(DataContainer.Name = 'Data');\n    Result := PWord(Cardinal(DataContainer.DataBasePtr) + 3*3*4)^;\n  end;\nend;\n\nfunction wbNAVINAVMGetCount2(aBasePtr: Pointer; aEndPtr: Pointer; const aElement: IwbElement): Integer;\nvar\n  DataContainer : IwbDataContainer;\nbegin\n  Result := 0;\n\n  if Supports(aElement, IwbDataContainer, DataContainer) then begin\n    if DataContainer.ElementType = etArray then\n      if not Supports(DataContainer.Container, IwbDataContainer, DataContainer) then\n        Exit;\n    Assert(DataContainer.Name = 'Data');\n    Result := PWord(Cardinal(DataContainer.DataBasePtr) + 3*3*4 + 2)^;\n  end;\nend;\n\nprocedure wbCTDARunOnAfterSet(const aElement: IwbElement; const aOldValue, aNewValue: Variant);\nbegin\n  if aOldValue <> aNewValue then\n    if aNewValue <> 2 then\n      aElement.Container.ElementNativeValues['Reference'] := 0;\nend;\n\nprocedure wbPERKPRKETypeAfterSet(const aElement: IwbElement; const aOldValue, aNewValue: Variant);\nvar\n  Container : IwbContainerElementRef;\n//  rDATA     : IwbRecord;\nbegin\n  if aOldValue <> aNewValue then\n    if Supports(aElement.Container, IwbContainerElementRef, Container) then begin\n      if Supports(Container.Container, IwbContainerElementRef, Container) then begin\n        Container.RemoveElement('DATA');\n        Container.Add('DATA', True);\n        Container.RemoveElement('Perk Conditions');\n        Container.RemoveElement('Entry Point Function Parameters');\n        if aNewValue = 2 then begin\n          Container.Add('EPFT', True);\n          Container.ElementNativeValues['DATA\\Entry Point\\Function'] := 2;\n        end;\n      end;\n    end;\nend;\n\nfunction wbMGEFFAssocItemDecider(aBasePtr: Pointer; aEndPtr: Pointer; const aElement: IwbElement): Integer;\nvar\n  Container     : IwbContainer;\n  Archtype      : Variant;\n  DataContainer : IwbDataContainer;\n  Element       : IwbElement;\nconst\n  OffsetArchtype = 56;\n\nbegin\n  Result := 1;\n  if not Assigned(aElement) then Exit;\n  Container := GetContainerFromUnion(aElement);\n  if not Assigned(Container) then Exit;\n\n  VarClear(ArchType);\n  Element := Container.ElementByName['Archtype'];\n  if Assigned(Element) then\n    ArchType := Element.NativeValue\n  else if Supports(Container, IwbDataContainer, DataContainer) and\n          DataContainer.IsValidOffset(aBasePtr, aEndPtr, OffsetArchtype) then\n  \tbegin // we are part of a proper structure\n      aBasePtr := Pointer(Cardinal(aBasePtr) + OffsetArchtype);\n      ArchType := PCardinal(aBasePtr)^;\n    end;\n\n  if not VarIsEmpty(ArchType) then\n    case Integer(ArchType) of\n      01: Result := 2;//Script\n      18: Result := 3;//Bound Item\n      19: Result := 4;//Summon Creature\n    else\n      Result := 0;\n    end;\nend;\n\nprocedure wbMGEFFAssocItemAfterSet(const aElement: IwbElement; const aOldValue, aNewValue: Variant);\nvar\n  Container : IwbContainer;\n  Element   : IwbElement;\nbegin\n  if not Assigned(aElement) then Exit;\n  Container := GetContainerFromUnion(aElement);\n  if not Assigned(Container) then Exit;\n  if (aNewValue <> 0) then begin\n    Element := Container.ElementByName['Archtype'];\n    if Assigned(Element) and Element.NativeValue = 0 then\n        Element.NativeValue := $FF; // Signals ArchType that it should not mess with us on the next change!\n  end;\nend;\n\nprocedure wbMGEFArchtypeAfterSet(const aElement: IwbElement; const aOldValue, aNewValue: Variant);\nvar\n  Container: IwbContainerElementRef;\nbegin\n  if VarSameValue(aOldValue, aNewValue) then\n    Exit;\n  if not Supports(aElement, IwbContainerElementRef, Container) then\n    Exit;\n  if (aNewValue < $FF) and (aOldValue < $FF) then begin\n    Container.ElementNativeValues['..\\Assoc. Item'] := 0;\n    case Integer(aNewValue) of\n      11: Container.ElementNativeValues['..\\Actor Value'] := 48;//Invisibility\n      12: Container.ElementNativeValues['..\\Actor Value'] := 49;//Chameleon\n      24: Container.ElementNativeValues['..\\Actor Value'] := 47;//Paralysis\n    else\n      Container.ElementNativeValues['..\\Actor Value'] := -1;\n    end;\n  end;\nend;\n\nprocedure wbCounterEffectsAfterSet(const aElement: IwbElement; const aOldValue, aNewValue: Variant);\nbegin\n  wbCounterByPathAfterSet('DATA - Data\\Counter effect count', aElement);\nend;\n\nprocedure wbMGEFAfterSet(const aElement: IwbElement; const aOldValue, aNewValue: Variant);\nbegin\n  wbCounterContainerByPathAfterSet('DATA - Data\\Counter effect count', 'Counter Effects', aElement);\nend;\n\nfunction wbCTDAReferenceDecider(aBasePtr: Pointer; aEndPtr: Pointer; const aElement: IwbElement): Integer;\nvar\n  Container     : IwbContainer;\nbegin\n  Result := 0;\n  if not Assigned(aElement) then Exit;\n  Container := GetContainerFromUnion(aElement);\n  if not Assigned(Container) then Exit;\n\n  if Integer(Container.ElementNativeValues['Run On']) = 2 then\n    Result := 1;\nend;\n\nfunction wbNAVINVMIDecider(aBasePtr: Pointer; aEndPtr: Pointer; const aElement: IwbElement): Integer;\nvar\n  Container     : IwbContainer;\nbegin\n  Result := 0;\n  if not Assigned(aElement) then Exit;\n  Container := GetContainerFromUnion(aElement);\n  if not Assigned(Container) then Exit;\n\n  case Integer(Container.ElementNativeValues['Type']) of\n    $00: Result :=1;\n    $20: Result :=2;\n    $30: Result :=3;\n  end;\nend;\n\nfunction wbIMGSSkinDimmerDecider(aBasePtr: Pointer; aEndPtr: Pointer; const aElement: IwbElement): Integer;\nvar\n  Container : IwbContainer;\n  SubRecord : IwbSubRecord;\nbegin\n  Result := 0;\n  if not Assigned(aElement) then Exit;\n  Container := GetContainerFromUnion(aElement);\n  if not Assigned(Container) then Exit;\n\n  if Supports(Container, IwbSubRecord, SubRecord) then\n    if SubRecord.SubRecordHeaderSize in [132, 148] then\n      Result := 1;\nend;\n\nfunction wbCOEDOwnerDecider(aBasePtr: Pointer; aEndPtr: Pointer; const aElement: IwbElement): Integer;\nvar\n  Container  : IwbContainer;\n  LinksTo    : IwbElement;\n  MainRecord : IwbMainRecord;\nbegin\n  Result := 0;\n  if not Assigned(aElement) then Exit;\n  Container := GetContainerFromUnion(aElement);\n  if not Assigned(Container) then Exit;\n\n  LinksTo := Container.ElementByName['Owner'].LinksTo;\n\n  if Supports(LinksTo, IwbMainRecord, MainRecord) then\n    if MainRecord.Signature = 'NPC_' then\n      Result := 1\n    else if MainRecord.Signature = 'FACT' then\n      Result := 2;\nend;\n\nfunction wbCreaLevelDecider(aBasePtr: Pointer; aEndPtr: Pointer; const aElement: IwbElement): Integer;\nvar\n  Container: IwbContainer;\n  i: Int64;\nbegin\n  Result := 0;\n  if not Assigned(aElement) then Exit;\n  Container := GetContainerFromUnion(aElement);\n  if not Assigned(Container) then Exit;\n\n  i := Container.ElementByName['Flags'].NativeValue;\n  if i and $00000080 <> 0 then\n    Result := 1;\nend;\n\n\nfunction wbGMSTUnionDecider(aBasePtr: Pointer; aEndPtr: Pointer; const aElement: IwbElement): Integer;\nvar\n  rEDID: IwbRecord;\n  s: string;\nbegin\n  Result := 1;\n  rEDID := aElement.Container.RecordBySignature[EDID];\n  if Assigned(rEDID) then begin\n    s := rEDID.Value;\n    if Length(s) > 0 then\n      case s[1] of\n        's': Result := 0;\n        'f': Result := 2;\n      end;\n  end;\nend;\n\nfunction wbFLSTLNAMIsSorted(const aContainer: IwbContainer): Boolean;\nvar\n  rEDID      : IwbRecord;\n  s          : string;\n  _File      : IwbFile;\n  MainRecord : IwbMainRecord;\nconst\n  OrderedList = 'OrderedList';\nbegin\n  Result := wbSortFLST; {>>> Should not be sorted according to Arthmoor and JustinOther, left as sorted for compatibility <<<}\n  rEDID := aContainer.RecordBySignature[EDID];\n  if Assigned(rEDID) then begin\n    s := rEDID.Value;\n    if Length(s) > Length(OrderedList) then\n      Delete(s, 1, Length(s)-Length(OrderedList));\n    if SameText(s, OrderedList) then\n      Result := False;\n  end;\n  if Result then begin\n    MainRecord := aContainer.ContainingMainRecord;\n    if not Assigned(MainRecord) then\n      Exit;\n    MainRecord := MainRecord.MasterOrSelf;\n    if not Assigned(MainRecord) then\n      Exit;\n    _File := MainRecord._File;\n    if not Assigned(_File) then\n      Exit;\n    if not SameText(_File.FileName, 'WeaponModKits.esp') then\n      Exit;\n    case (MainRecord.FormID and $FFFFFF) of\n      $0130EB, $0130ED, $01522D, $01522E, $0158D5, $0158D6, $0158D7, $0158D8, $0158D9, $0158DA, $0158DC, $0158DD, $018E20:\n        Result := False;\n    end;\n  end;\nend;\n\nfunction wbPerkDATADecider(aBasePtr: Pointer; aEndPtr: Pointer; const aElement: IwbElement): Integer;\nvar\n  rPRKE: IwbRecord;\n  eType: IwbElement;\nbegin\n  Result := 0;\n  rPRKE := aElement.Container.RecordBySignature[PRKE];\n  if Assigned(rPRKE) then begin\n    eType := rPRKE.ElementByName['Type'];\n    if Assigned(eType) then begin\n      Result := eType.NativeValue;\n    end;\n  end;\nend;\n\nfunction wbEPFDDecider(aBasePtr: Pointer; aEndPtr: Pointer; const aElement: IwbElement): Integer;\nvar\n  Container: IwbContainerElementRef;\nbegin\n  Result := 0;\n  if not Assigned(aElement) then\n    Exit;\n  if not Supports(aElement.Container, IwbContainerElementRef, Container) then\n    Exit;\n  Result := Container.ElementNativeValues['EPFT'];\n  if Result = 2 then\n    if Integer(Container.ElementNativeValues['..\\DATA\\Entry Point\\Function']) = 5 then\n      Result := 5;\nend;\n\ntype\n  TCTDAFunctionParamType = (\n    ptNone,\n    ptInteger,\n    ptVariableName,  //Integer\n    ptSex,           //Enum: Male, Female\n    ptActorValue,    //Enum: wbActorValue\n    ptCrimeType,     //?? Enum\n    ptAxis,          //?? Char\n    ptQuestStage,    //?? Integer\n    ptMiscStat,      //?? Enum\n    ptAlignment,     //?? Enum\n    ptEquipType,     //?? Enum\n    ptFormType,      //?? Enum\n    ptCriticalStage, //?? Enum\n\n    ptObjectReference,    //REFR, ACHR, ACRE, PGRE\n    ptInventoryObject,    //ARMO, BOOK, MISC, WEAP, AMMO, KEYM, ALCH, NOTE, ARMA\n    ptActor,              //ACHR, ACRE\n    ptVoiceType,          //VTYP\n    ptIdleForm,           //IDLE\n    ptFormList,           //FLST\n    ptNote,               //NOTE\n    ptQuest,              //QUST\n    ptFaction,            //FACT\n    ptWeapon,             //WEAP\n    ptCell,               //CELL\n    ptClass,              //CLAS\n    ptRace,               //RACE\n    ptActorBase,          //NPC_, CREA\n    ptGlobal,             //GLOB\n    ptWeather,            //WTHR\n    ptPackage,            //PACK\n    ptEncounterZone,      //ECZN\n    ptPerk,               //PERK\n    ptOwner,              //FACT, NPC_\n    ptFurniture,          //FURN\n    ptMagicItem,          //SPEL\n    ptMagicEffect,        //MGEF\n    ptWorldspace,         //WRLD\n    ptVATSValueFunction,\n    ptVATSValueParam,\n    ptCreatureType,\n    ptMenuMode,\n    ptPlayerAction,\n    ptBodyLocation,\n    ptReferencableObject  //TREE, SOUN, ACTI, DOOR, STAT, FURN, CONT, ARMO, AMMO, MISC, WEAP, BOOK, KEYM, ALCH, LIGH, GRAS, ASPC, IDLM, ARMA, MSTT, NOTE, PWAT, SCOL, TACT, TERM\n  );\n\n  PCTDAFunction = ^TCTDAFunction;\n  TCTDAFunction = record\n    Index: Integer;\n    Name: string;\n    ParamType1: TCTDAFunctionParamType;\n    ParamType2: TCTDAFunctionParamType;\n  end;\n\nconst\n  wbCTDAFunctions : array[0..243] of TCTDAFunction = (\n    (Index:   1; Name: 'GetDistance'; ParamType1: ptObjectReference),\n    (Index:   5; Name: 'GetLocked'),\n    (Index:   6; Name: 'GetPos'; ParamType1: ptAxis),\n    (Index:   8; Name: 'GetAngle'; ParamType1: ptAxis),\n    (Index:  10; Name: 'GetStartingPos'; ParamType1: ptAxis),\n    (Index:  11; Name: 'GetStartingAngle'; ParamType1: ptAxis),\n    (Index:  12; Name: 'GetSecondsPassed'),\n    (Index:  14; Name: 'GetActorValue'; ParamType1: ptActorValue),\n    (Index:  18; Name: 'GetCurrentTime'),\n    (Index:  24; Name: 'GetScale'),\n    (Index:  25; Name: 'IsMoving'),\n    (Index:  26; Name: 'IsTurning'),\n    (Index:  27; Name: 'GetLineOfSight'; ParamType1: ptObjectReference),\n    (Index:  32; Name: 'GetInSameCell'; ParamType1: ptObjectReference),\n    (Index:  35; Name: 'GetDisabled'),\n    (Index:  36; Name: 'MenuMode'; ParamType1: ptMenuMode),\n    (Index:  39; Name: 'GetDisease'),\n    (Index:  40; Name: 'GetVampire'),\n    (Index:  41; Name: 'GetClothingValue'),\n    (Index:  42; Name: 'SameFaction'; ParamType1: ptActor),\n    (Index:  43; Name: 'SameRace'; ParamType1: ptActor),\n    (Index:  44; Name: 'SameSex'; ParamType1: ptActor),\n    (Index:  45; Name: 'GetDetected'; ParamType1: ptActor),\n    (Index:  46; Name: 'GetDead'),\n    (Index:  47; Name: 'GetItemCount'; ParamType1: ptInventoryObject),\n    (Index:  48; Name: 'GetGold'),\n    (Index:  49; Name: 'GetSleeping'),\n    (Index:  50; Name: 'GetTalkedToPC'),\n    (Index:  53; Name: 'GetScriptVariable'; ParamType1: ptObjectReference; ParamType2: ptVariableName),\n    (Index:  56; Name: 'GetQuestRunning'; ParamType1: ptQuest),\n    (Index:  58; Name: 'GetStage'; ParamType1: ptQuest),\n    (Index:  59; Name: 'GetStageDone'; ParamType1: ptQuest; ParamType2: ptQuestStage),\n    (Index:  60; Name: 'GetFactionRankDifference'; ParamType1: ptFaction; ParamType2: ptActor),\n    (Index:  61; Name: 'GetAlarmed'),\n    (Index:  62; Name: 'IsRaining'),\n    (Index:  63; Name: 'GetAttacked'),\n    (Index:  64; Name: 'GetIsCreature'),\n    (Index:  65; Name: 'GetLockLevel'),\n    (Index:  66; Name: 'GetShouldAttack'; ParamType1: ptActor),\n    (Index:  67; Name: 'GetInCell'; ParamType1: ptCell),\n    (Index:  68; Name: 'GetIsClass'; ParamType1: ptClass),\n    (Index:  69; Name: 'GetIsRace'; ParamType1: ptRace),\n    (Index:  70; Name: 'GetIsSex'; ParamType1: ptSex),\n    (Index:  71; Name: 'GetInFaction'; ParamType1: ptFaction),\n    (Index:  72; Name: 'GetIsID'; ParamType1: ptReferencableObject),\n    (Index:  73; Name: 'GetFactionRank'; ParamType1: ptFaction),\n    (Index:  74; Name: 'GetGlobalValue'; ParamType1: ptGlobal),\n    (Index:  75; Name: 'IsSnowing'),\n    (Index:  76; Name: 'GetDisposition'; ParamType1: ptActor),\n    (Index:  77; Name: 'GetRandomPercent'),\n    (Index:  79; Name: 'GetQuestVariable'; ParamType1: ptQuest; ParamType2: ptVariableName),\n    (Index:  80; Name: 'GetLevel'),\n    (Index:  81; Name: 'GetArmorRating'),\n    (Index:  84; Name: 'GetDeadCount'; ParamType1: ptActorBase),\n    (Index:  91; Name: 'GetIsAlerted'),\n    (Index:  98; Name: 'GetPlayerControlsDisabled'; ParamType1: ptInteger; ParamType2: ptInteger{; ParamType3: ptInteger; ParamType4: ptInteger; ParamType5: ptInteger; ParamType6: ptInteger; ParamType7: ptInteger}),\n    (Index:  99; Name: 'GetHeadingAngle'; ParamType1: ptObjectReference),\n    (Index: 101; Name: 'IsWeaponOut'),\n    (Index: 102; Name: 'IsTorchOut'),\n    (Index: 103; Name: 'IsShieldOut'),\n    (Index: 106; Name: 'IsFacingUp'),\n    (Index: 107; Name: 'GetKnockedState'),\n    (Index: 108; Name: 'GetWeaponAnimType'),\n    (Index: 109; Name: 'IsWeaponSkillType'; ParamType1: ptActorValue),\n    (Index: 110; Name: 'GetCurrentAIPackage'),\n    (Index: 111; Name: 'IsWaiting'),\n    (Index: 112; Name: 'IsIdlePlaying'),\n    (Index: 116; Name: 'GetMinorCrimeCount'),\n    (Index: 117; Name: 'GetMajorCrimeCount'),\n    (Index: 118; Name: 'GetActorAggroRadiusViolated'),\n    (Index: 122; Name: 'GetCrime'; ParamType1: ptActor; ParamType2: ptCrimeType),\n    (Index: 123; Name: 'IsGreetingPlayer'),\n    (Index: 125; Name: 'IsGuard'),\n    (Index: 127; Name: 'HasBeenEaten'),\n    (Index: 128; Name: 'GetFatiguePercentage'),\n    (Index: 129; Name: 'GetPCIsClass'; ParamType1: ptClass),\n    (Index: 130; Name: 'GetPCIsRace'; ParamType1: ptRace),\n    (Index: 131; Name: 'GetPCIsSex'; ParamType1: ptSex),\n    (Index: 132; Name: 'GetPCInFaction'; ParamType1: ptFaction),\n    (Index: 133; Name: 'SameFactionAsPC'),\n    (Index: 134; Name: 'SameRaceAsPC'),\n    (Index: 135; Name: 'SameSexAsPC'),\n    (Index: 136; Name: 'GetIsReference'; ParamType1: ptObjectReference),\n    (Index: 141; Name: 'IsTalking'),\n    (Index: 142; Name: 'GetWalkSpeed'),\n    (Index: 143; Name: 'GetCurrentAIProcedure'),\n    (Index: 144; Name: 'GetTrespassWarningLevel'),\n    (Index: 145; Name: 'IsTrespassing'),\n    (Index: 146; Name: 'IsInMyOwnedCell'),\n    (Index: 147; Name: 'GetWindSpeed'),\n    (Index: 148; Name: 'GetCurrentWeatherPercent'),\n    (Index: 149; Name: 'GetIsCurrentWeather'; ParamType1: ptWeather),\n    (Index: 150; Name: 'IsContinuingPackagePCNear'),\n    (Index: 153; Name: 'CanHaveFlames'),\n    (Index: 154; Name: 'HasFlames'),\n    (Index: 157; Name: 'GetOpenState'),\n    (Index: 159; Name: 'GetSitting'),\n    (Index: 160; Name: 'GetFurnitureMarkerID'),\n    (Index: 161; Name: 'GetIsCurrentPackage'; ParamType1: ptPackage),\n    (Index: 162; Name: 'IsCurrentFurnitureRef'; ParamType1: ptObjectReference),\n    (Index: 163; Name: 'IsCurrentFurnitureObj'; ParamType1: ptFurniture),\n    (Index: 170; Name: 'GetDayOfWeek'),\n    (Index: 172; Name: 'GetTalkedToPCParam'; ParamType1: ptActor),\n    (Index: 175; Name: 'IsPCSleeping'),\n    (Index: 176; Name: 'IsPCAMurderer'),\n    (Index: 180; Name: 'GetDetectionLevel'; ParamType1: ptActor),\n    (Index: 182; Name: 'GetEquipped'; ParamType1: ptInventoryObject),\n    (Index: 185; Name: 'IsSwimming'),\n    (Index: 190; Name: 'GetAmountSoldStolen'),\n    (Index: 192; Name: 'GetIgnoreCrime'),\n    (Index: 193; Name: 'GetPCExpelled'; ParamType1: ptFaction),\n    (Index: 195; Name: 'GetPCFactionMurder'; ParamType1: ptFaction),\n    (Index: 197; Name: 'GetPCEnemyofFaction'; ParamType1: ptFaction),\n    (Index: 199; Name: 'GetPCFactionAttack'; ParamType1: ptFaction),\n    (Index: 203; Name: 'GetDestroyed'),\n    (Index: 214; Name: 'HasMagicEffect'; ParamType1: ptMagicEffect),\n    (Index: 215; Name: 'GetDefaultOpen'),\n    (Index: 219; Name: 'GetAnimAction'),\n    (Index: 223; Name: 'IsSpellTarget'; ParamType1: ptMagicItem),\n    (Index: 224; Name: 'GetVATSMode'),\n    (Index: 225; Name: 'GetPersuasionNumber'),\n    (Index: 226; Name: 'GetSandman'),\n    (Index: 227; Name: 'GetCannibal'),\n    (Index: 228; Name: 'GetIsClassDefault'; ParamType1: ptClass),\n    (Index: 229; Name: 'GetClassDefaultMatch'),\n    (Index: 230; Name: 'GetInCellParam'; ParamType1: ptCell; ParamType2: ptObjectReference),\n    (Index: 235; Name: 'GetVatsTargetHeight'),\n    (Index: 237; Name: 'GetIsGhost'),\n    (Index: 242; Name: 'GetUnconscious'),\n    (Index: 244; Name: 'GetRestrained'),\n    (Index: 246; Name: 'GetIsUsedItem'; ParamType1: ptReferencableObject),\n    (Index: 247; Name: 'GetIsUsedItemType'; ParamType1: ptFormType),\n    (Index: 254; Name: 'GetIsPlayableRace'),\n    (Index: 255; Name: 'GetOffersServicesNow'),\n    (Index: 258; Name: 'GetUsedItemLevel'),\n    (Index: 259; Name: 'GetUsedItemActivate'),\n    (Index: 264; Name: 'GetBarterGold'),\n    (Index: 265; Name: 'IsTimePassing'),\n    (Index: 266; Name: 'IsPleasant'),\n    (Index: 267; Name: 'IsCloudy'),\n    (Index: 274; Name: 'GetArmorRatingUpperBody'),\n    (Index: 277; Name: 'GetBaseActorValue'; ParamType1: ptActorValue),\n    (Index: 278; Name: 'IsOwner'; ParamType1: ptOwner),\n    (Index: 280; Name: 'IsCellOwner'; ParamType1: ptCell; ParamType2: ptOwner),\n    (Index: 282; Name: 'IsHorseStolen'),\n    (Index: 285; Name: 'IsLeftUp'),\n    (Index: 286; Name: 'IsSneaking'),\n    (Index: 287; Name: 'IsRunning'),\n    (Index: 288; Name: 'GetFriendHit'),\n    (Index: 289; Name: 'IsInCombat'),\n    (Index: 300; Name: 'IsInInterior'),\n    (Index: 304; Name: 'IsWaterObject'),\n    (Index: 306; Name: 'IsActorUsingATorch'),\n    (Index: 309; Name: 'IsXBox'),\n    (Index: 310; Name: 'GetInWorldspace'; ParamType1: ptWorldSpace),\n    (Index: 312; Name: 'GetPCMiscStat'; ParamType1: ptMiscStat),\n    (Index: 313; Name: 'IsActorEvil'),\n    (Index: 314; Name: 'IsActorAVictim'),\n    (Index: 315; Name: 'GetTotalPersuasionNumber'),\n    (Index: 318; Name: 'GetIdleDoneOnce'),\n    (Index: 320; Name: 'GetNoRumors'),\n    (Index: 323; Name: 'WhichServiceMenu'),\n    (Index: 327; Name: 'IsRidingHorse'),\n    (Index: 332; Name: 'IsInDangerousWater'),\n    (Index: 338; Name: 'GetIgnoreFriendlyHits'),\n    (Index: 339; Name: 'IsPlayersLastRiddenHorse'),\n    (Index: 353; Name: 'IsActor'),\n    (Index: 354; Name: 'IsEssential'),\n    (Index: 358; Name: 'IsPlayerMovingIntoNewSpace'),\n    (Index: 361; Name: 'GetTimeDead'),\n    (Index: 362; Name: 'GetPlayerHasLastRiddenHorse'),\n    (Index: 365; Name: 'IsChild'),\n    (Index: 367; Name: 'GetLastPlayerAction'),\n    (Index: 368; Name: 'IsPlayerActionActive'; ParamType1: ptPlayerAction),\n    (Index: 370; Name: 'IsTalkingActivatorActor'; ParamType1: ptActor),\n    (Index: 372; Name: 'IsInList'; ParamType1: ptFormList),\n    (Index: 382; Name: 'GetHasNote'; ParamType1: ptNote),\n    (Index: 391; Name: 'GetHitLocation'),\n    (Index: 392; Name: 'IsPC1stPerson'),\n    (Index: 397; Name: 'GetCauseofDeath'),\n    (Index: 398; Name: 'IsLimbGone'; ParamType1: ptBodyLocation),\n    (Index: 399; Name: 'IsWeaponInList'; ParamType1: ptFormList),\n    (Index: 403; Name: 'HasFriendDisposition'),\n    (Index: 408; Name: 'GetVATSValue'; ParamType1: ptVATSValueFunction; ParamType2: ptVATSValueParam),\n    (Index: 409; Name: 'IsKiller'; ParamType1: ptActor),\n    (Index: 410; Name: 'IsKillerObject'; ParamType1: ptFormList),\n    (Index: 411; Name: 'GetFactionCombatReaction'; ParamType1: ptFaction; ParamType2: ptFaction),\n    (Index: 415; Name: 'Exists'; ParamType1: ptObjectReference),\n    (Index: 416; Name: 'GetGroupMemberCount'),\n    (Index: 417; Name: 'GetGroupTargetCount'),\n    (Index: 427; Name: 'GetIsVoiceType'; ParamType1: ptVoiceType),\n    (Index: 428; Name: 'GetPlantedExplosive'),\n    (Index: 430; Name: 'IsActorTalkingThroughActivator'),\n    (Index: 431; Name: 'GetHealthPercentage'),\n    (Index: 433; Name: 'GetIsObjectType'; ParamType1: ptFormType),\n    (Index: 435; Name: 'GetDialogueEmotion'),\n    (Index: 436; Name: 'GetDialogueEmotionValue'),\n    (Index: 438; Name: 'GetIsCreatureType'; ParamType1: ptCreatureType),\n    (Index: 446; Name: 'GetInZone'; ParamType1: ptEncounterZone),\n    (Index: 449; Name: 'HasPerk'; ParamType1: ptPerk),\n    (Index: 450; Name: 'GetFactionRelation'; ParamType1: ptActor),\n    (Index: 451; Name: 'IsLastIdlePlayed'; ParamType1: ptIdleForm),\n    (Index: 454; Name: 'GetPlayerTeammate'),\n    (Index: 455; Name: 'GetPlayerTeammateCount'),\n    (Index: 459; Name: 'GetActorCrimePlayerEnemy'),\n    (Index: 460; Name: 'GetActorFactionPlayerEnemy'),\n    (Index: 464; Name: 'IsPlayerGrabbedRef'; ParamType1: ptObjectReference),\n    (Index: 471; Name: 'GetDestructionStage'),\n    (Index: 474; Name: 'GetIsAlignment'; ParamType1: ptAlignment),\n    (Index: 478; Name: 'GetThreatRatio'; ParamType1: ptActor),\n    (Index: 480; Name: 'GetIsUsedItemEquipType'; ParamType1: ptEquipType),\n    (Index: 489; Name: 'GetConcussed'),\n    (Index: 492; Name: 'GetMapMarkerVisible'),\n    (Index: 495; Name: 'GetPermanentActorValue'; ParamType1: ptActorValue),\n    (Index: 496; Name: 'GetKillingBlowLimb'),\n    (Index: 500; Name: 'GetWeaponHealthPerc'),\n    (Index: 503; Name: 'GetRadiationLevel'),\n    (Index: 510; Name: 'GetLastHitCritical'),\n    (Index: 515; Name: 'IsCombatTarget'; ParamType1: ptActor),\n    (Index: 518; Name: 'GetVATSRightAreaFree'; ParamType1: ptObjectReference),\n    (Index: 519; Name: 'GetVATSLeftAreaFree'; ParamType1: ptObjectReference),\n    (Index: 520; Name: 'GetVATSBackAreaFree'; ParamType1: ptObjectReference),\n    (Index: 521; Name: 'GetVATSFrontAreaFree'; ParamType1: ptObjectReference),\n    (Index: 522; Name: 'GetIsLockBroken'),\n    (Index: 523; Name: 'IsPS3'),\n    (Index: 524; Name: 'IsWin32'),\n    (Index: 525; Name: 'GetVATSRightTargetVisible'; ParamType1: ptObjectReference),\n    (Index: 526; Name: 'GetVATSLeftTargetVisible'; ParamType1: ptObjectReference),\n    (Index: 527; Name: 'GetVATSBackTargetVisible'; ParamType1: ptObjectReference),\n    (Index: 528; Name: 'GetVATSFrontTargetVisible'; ParamType1: ptObjectReference),\n    (Index: 531; Name: 'IsInCriticalStage'; ParamType1: ptCriticalStage),\n    (Index: 533; Name: 'GetXPForNextLevel'),\n    (Index: 546; Name: 'GetQuestCompleted'; ParamType1: ptQuest),\n    (Index: 550; Name: 'IsGoreDisabled'),\n    (Index: 555; Name: 'GetSpellUsageNum'; ParamType1: ptMagicItem),\n    (Index: 557; Name: 'GetActorsInHigh'),\n    (Index: 558; Name: 'HasLoaded3D'),\n\n    // Added by FOSE:\n    (Index: 1024; Name: 'GetFOSEVersion'; ),\n    (Index: 1025; Name: 'GetFOSERevision'; ),\n    (Index: 1028; Name: 'GetWeight'; ParamType1: ptInventoryObject; ),\n    (Index: 1082; Name: 'IsKeyPressed'; ParamType1: ptInteger;),\n    (Index: 1165; Name: 'GetWeaponHasScope'; ParamType1: ptInventoryObject; ),\n    (Index: 1166; Name: 'IsControlPressed'; ParamType1: ptInteger; ),\n    (Index: 1213; Name: 'GetFOSEBeta'; )\n  );\nvar\n  wbCTDAFunctionEditInfo: string;\n\nfunction wbCTDAParamDescFromIndex(aIndex: Integer): PCTDAFunction;\nvar\n  L, H, I, C: Integer;\nbegin\n  Result := nil;\n\n  L := Low(wbCTDAFunctions);\n  H := High(wbCTDAFunctions);\n  while L <= H do begin\n    I := (L + H) shr 1;\n    C := CmpW32(wbCTDAFunctions[I].Index, aIndex);\n    if C < 0 then\n      L := I + 1\n    else begin\n      H := I - 1;\n      if C = 0 then begin\n        L := I;\n        Result := @wbCTDAFunctions[L];\n      end;\n    end;\n  end;\nend;\n\nfunction wbCTDACompValueDecider(aBasePtr: Pointer; aEndPtr: Pointer; const aElement: IwbElement): Integer;\nvar\n  Container: IwbContainer;\nbegin\n  Result := 0;\n  if not Assigned(aElement) then Exit;\n  Container := GetContainerFromUnion(aElement);\n  if not Assigned(Container) then Exit;\n\n  if Integer(Container.ElementByName['Type'].NativeValue) and $04 <> 0 then\n    Result := 1;\nend;\n\nfunction wbCTDAParam1Decider(aBasePtr: Pointer; aEndPtr: Pointer; const aElement: IwbElement): Integer;\nvar\n  Desc: PCTDAFunction;\n  Container: IwbContainer;\nbegin\n  Result := 0;\n  if not Assigned(aElement) then Exit;\n  Container := GetContainerFromUnion(aElement);\n  if not Assigned(Container) then Exit;\n\n  Desc := wbCTDAParamDescFromIndex(Container.ElementByName['Function'].NativeValue);\n  if Assigned(Desc) then\n    Result := Succ(Integer(Desc.ParamType1));\nend;\n\nfunction wbCTDAParam2VATSValueParam(aBasePtr: Pointer; aEndPtr: Pointer; const aElement: IwbElement): Integer;\nvar\n  Container : IwbContainer;\nbegin\n  Result := 0;\n  if not Assigned(aElement) then Exit;\n  Container := GetContainerFromUnion(aElement);\n  if not Assigned(Container) then Exit;\n\n  Result := Container.ElementByName['Parameter #1'].NativeValue;\nend;\n\nfunction wbCTDAParam2Decider(aBasePtr: Pointer; aEndPtr: Pointer; const aElement: IwbElement): Integer;\nvar\n  Desc: PCTDAFunction;\n  Container: IwbContainer;\nbegin\n  Result := 0;\n  if not Assigned(aElement) then Exit;\n  Container := GetContainerFromUnion(aElement);\n  if not Assigned(Container) then Exit;\n\n  Desc := wbCTDAParamDescFromIndex(Container.ElementByName['Function'].NativeValue);\n  if Assigned(Desc) then\n    Result := Succ(Integer(Desc.ParamType2));\nend;\n\nfunction wbCTDAFunctionToStr(aInt: Int64; const aElement: IwbElement; aType: TwbCallbackType): string;\nvar\n  Desc : PCTDAFunction;\n  i    : Integer;\nbegin\n  Result := '';\n  case aType of\n    ctToStr, ctToEditValue: begin\n      Desc := wbCTDAParamDescFromIndex(aInt);\n      if Assigned(Desc) then\n        Result := Desc.Name\n      else if aType = ctToEditValue then\n        Result := IntToStr(aInt)\n      else\n        Result := '<Unknown: '+IntToStr(aInt)+'>';\n    end;\n    ctToSortKey: Result := IntToHex(aInt, 8);\n    ctCheck: begin\n      Desc := wbCTDAParamDescFromIndex(aInt);\n      if Assigned(Desc) then\n        Result := ''\n      else\n        Result := '<Unknown: '+IntToStr(aInt)+'>';\n    end;\n    ctEditType:\n      Result := 'ComboBox';\n    ctEditInfo: begin\n      Result := wbCTDAFunctionEditInfo;\n      if Result = '' then begin\n        with TStringList.Create do try\n          for i := Low(wbCTDAFunctions) to High(wbCTDAFunctions) do\n            Add(wbCTDAFunctions[i].Name);\n          Sort;\n          Result := CommaText;\n        finally\n          Free;\n        end;\n        wbCTDAFunctionEditInfo := Result;\n      end;\n    end;\n  end;\nend;\n\nfunction wbCTDAFunctionToInt(const aString: string; const aElement: IwbElement): Int64;\nvar\n  i: Integer;\nbegin\n  for i := Low(wbCTDAFunctions) to High(wbCTDAFunctions) do\n    with wbCTDAFunctions[i] do\n      if SameText(Name, aString) then begin\n        Result := Index;\n        Exit;\n      end;\n  Result := StrToInt64(aString);\nend;\n\ntype\n  TPERKEntryPointConditionType = (\n    epcDefault,\n    epcItem,\n    epcWeapon,\n    epcWeaponTarget,\n    epcTarget,\n    epcAttacker,\n    epcAttackerAttackee,\n    epcAttackerAttackerWeapon\n  );\n\n  TPERKEntryPointFunctionType = (\n    epfFloat,\n    epfLeveledItem,\n    epfScript,\n    epfUnknown\n  );\n\n  TPERKEntryPointFunctionParamType = (\n    epfpNone,\n    epfpFloat,\n    epfpFloatFloat,\n    epfpLeveledItem,\n    epfpScript\n  );\n\n  PPERKEntryPoint = ^TPERKEntryPoint;\n  TPERKEntryPoint = record\n    Name         : string;\n    Condition   : TPERKEntryPointConditionType;\n    FunctionType : TPERKEntryPointFunctionType;\n  end;\n\n  PPERKCondition = ^TPERKCondition;\n  TPERKCondition = record\n    Count    : Integer;\n    Caption1 : string;\n    Caption2 : string;\n    Caption3 : string;\n  end;\n\n  PPERKFunction = ^TPERKFunction;\n  TPERKFunction = record\n    Name         : string;\n    FunctionType : TPERKEntryPointFunctionType;\n    ParamType    : TPERKEntryPointFunctionParamType;\n  end;\n\nconst\n  wbPERKCondition : array[TPERKEntryPointConditionType] of TPERKCondition = (\n    (Count: 1; Caption1: 'Perk Owner'),\n    (Count: 2; Caption1: 'Perk Owner'; Caption2: 'Item'),\n    (Count: 2; Caption1: 'Perk Owner'; Caption2: 'Weapon'),\n    (Count: 3; Caption1: 'Perk Owner'; Caption2: 'Weapon'; Caption3: 'Target'),\n    (Count: 2; Caption1: 'Perk Owner'; Caption2: 'Target'),\n    (Count: 2; Caption1: 'Perk Owner'; Caption2: 'Attacker'),\n    (Count: 3; Caption1: 'Perk Owner'; Caption2: 'Attacker'; Caption3: 'Attackee'),\n    (Count: 3; Caption1: 'Perk Owner'; Caption2: 'Attacker'; Caption3: 'Attacker Weapon')\n  );\n\n  wbPERKFunctions : array[0..9] of TPERKFunction = (\n    (Name: ''; FunctionType: epfUnknown; ParamType: epfpNone),\n    (Name: 'Set Value'; FunctionType: epfFloat; ParamType: epfpFloat),\n    (Name: 'Add Value'; FunctionType: epfFloat; ParamType: epfpFloat),\n    (Name: 'Multiply Value'; FunctionType: epfFloat; ParamType: epfpFloat),\n    (Name: 'Add Range To Value'; FunctionType: epfFloat; ParamType: epfpFloatFloat),\n    (Name: 'Add Actor Value Mult'; FunctionType: epfFloat; ParamType: epfpFloatFloat),\n    (Name: ''; FunctionType: epfUnknown; ParamType: epfpNone),\n    (Name: ''; FunctionType: epfUnknown; ParamType: epfpNone),\n    (Name: 'Add Leveled List'; FunctionType: epfLeveledItem; ParamType: epfpLeveledItem),\n    (Name: 'Add Activate Choice'; FunctionType: epfScript; ParamType: epfpScript)\n  );\n\n  wbPERKEntryPoints : array[0..36] of TPERKEntryPoint = (\n    (Name: 'Calculate Weapon Damage'; Condition: epcWeaponTarget),\n    (Name: 'Calculate My Critical Hit Chance'; Condition: epcWeaponTarget),\n    (Name: 'Calculate My Critical Hit Damage'; Condition: epcWeaponTarget),\n    (Name: 'Calculate Weapon Attack AP Cost'; Condition: epcWeapon),\n    (Name: 'Calculate Mine Explode Chance'; Condition: epcItem),\n    (Name: 'Adjust Range Penalty'; Condition: epcWeapon),\n    (Name: 'Adjust Limb Damage'; Condition: epcAttackerAttackerWeapon),\n    (Name: 'Calculate Weapon Range'; Condition: epcWeapon),\n    (Name: 'Calculate To Hit Chance'; Condition: epcWeaponTarget),\n    (Name: 'Adjust Experience Points'),\n    (Name: 'Adjust Gained Skill Points'),\n    (Name: 'Adjust Book Skill Points'),\n    (Name: 'Modify Recovered Health'),\n    (Name: 'Calculate Inventory AP Cost'),\n    (Name: 'Get Disposition'; Condition: epcTarget),\n    (Name: 'Get Should Attack'; Condition: epcAttacker),\n    (Name: 'Get Should Assist'; Condition: epcAttackerAttackee),\n    (Name: 'Calculate Buy Price'; Condition: epcItem),\n    (Name: 'Get Bad Karma'),\n    (Name: 'Get Good Karma'),\n    (Name: 'Ignore Locked Terminal'),\n    (Name: 'Add Leveled List On Death'; Condition: epcTarget; FunctionType: epfLeveledItem),\n    (Name: 'Get Max Carry Weight'),\n    (Name: 'Modify Addiction Chance'),\n    (Name: 'Modify Addiction Duration'),\n    (Name: 'Modify Positive Chem Duration'),\n    (Name: 'Adjust Drinking Radiation'),\n    (Name: 'Activate'; Condition: epcTarget; FunctionType: epfScript),\n    (Name: 'Mysterious Stranger'),\n    (Name: 'Has Paralyzing Palm'),\n    (Name: 'Hacking Science Bonus'),\n    (Name: 'Ignore Running During Detection'),\n    (Name: 'Ignore Broken Lock'),\n    (Name: 'Has Concentrated Fire'),\n    (Name: 'Calculate Gun Spread'; Condition: epcWeapon),\n    (Name: 'Player Kill AP Reward'; Condition: epcWeaponTarget),\n    (Name: 'Modify Enemy Critical Hit Chance'; Condition: epcWeaponTarget)\n  );\n\n  wbPERKFunctionParams: array[TPERKEntryPointFunctionParamType] of string = (\n    'None',\n    'Float',\n    'Float, Float',\n    'Leveled Item',\n    'Script'\n  );\n\nprocedure wbPERKEntryPointAfterSet(const aElement: IwbElement; const aOldValue, aNewValue: Variant);\nvar\n  OldEntryPoint   : PPERKEntryPoint;\n  NewEntryPoint   : PPERKEntryPoint;\n  OldCondition    : PPERKCondition;\n  NewCondition    : PPERKCondition;\n  OldFunction     : PPERKFunction;\n  EntryPoint      : IwbContainerElementRef;\n  Effect          : IwbContainerElementRef;\n  PerkConditions  : IwbContainerElementRef;\n  PerkCondition   : IwbContainerElementRef;\n  Container       : IwbContainerElementRef;\n  i               : Integer;\nbegin\n  if aOldValue <> aNewValue then begin\n    OldEntryPoint := @wbPERKEntryPoints[Integer(aOldValue)];\n    NewEntryPoint := @wbPERKEntryPoints[Integer(aNewValue)];\n    OldCondition := @wbPERKCondition[OldEntryPoint.Condition];\n    NewCondition := @wbPERKCondition[NewEntryPoint.Condition];\n    if not Assigned(aElement) then\n      Exit;\n    if not Supports(aElement.Container, IwbContainerElementRef, EntryPoint) then\n      Exit;\n    i := EntryPoint.ElementNativeValues['Function'];\n    if (i >= Low(wbPERKFunctions)) and (i <= High(wbPERKFunctions)) then\n      OldFunction := @wbPERKFunctions[i]\n    else\n      OldFunction := nil;\n    if not Assigned(OldFunction) or (OldFunction.FunctionType <> NewEntryPoint.FunctionType) then\n      for i := Low(wbPERKFunctions) to High(wbPERKFunctions) do\n        with wbPERKFunctions[i] do\n          if FunctionType = NewEntryPoint.FunctionType then begin\n            EntryPoint.ElementNativeValues['Function'] := i;\n            Break;\n          end;\n    EntryPoint.ElementNativeValues['Perk Condition Tab Count'] := NewCondition.Count;\n\n    if not Supports(EntryPoint.Container, IwbContainerElementRef, Container) then\n      Exit;\n    if not Supports(Container.Container, IwbContainerElementRef, Effect) then\n      Exit;\n\n    if not Supports(Effect.ElementByName['Perk Conditions'], IwbContainerElementRef, PerkConditions) then\n      Exit;\n\n    for i := Pred(PerkConditions.ElementCount) downto 0 do\n      if Supports(PerkConditions.Elements[i], IwbContainerElementRef, PerkCondition) then\n        if Integer(PerkCondition.ElementNativeValues['PRKC']) >= NewCondition.Count then\n          PerkCondition.Remove\n        else\n          case Integer(PerkCondition.ElementNativeValues['PRKC']) of\n            2: if OldCondition.Caption2 <> NewCondition.Caption2 then\n                 PerkCondition.Remove;\n            3: if OldCondition.Caption3 <> NewCondition.Caption3 then\n                 PerkCondition.Remove;\n          end;\n  end;\nend;\n\nfunction wbPRKCToStr(aInt: Int64; const aElement: IwbElement; aType: TwbCallbackType): string;\nvar\n  Container     : IwbContainerElementRef;\n  EntryPointVar : Variant;\n  EntryPoint    : Integer;\nbegin\n  case aType of\n    ctToStr: Result := IntToStr(aInt) + ' <Warning: Could not resolve Entry Point>';\n    ctToEditValue: Result := IntToStr(aInt);\n    ctToSortKey: begin\n      Result := IntToHex64(aInt, 2);\n      Exit;\n    end;\n    ctCheck: Result := '<Warning: Could not resolve Entry Point>';\n    ctEditType: Result := '';\n    ctEditInfo: Result := '';\n  end;\n\n  if not Supports(aElement, IwbContainerElementRef, Container) then\n    Exit;\n  EntryPointVar := Container.ElementNativeValues['..\\..\\..\\DATA\\Entry Point\\Entry Point'];\n  if VarIsNull(EntryPointVar) or VarIsClear(EntryPointVar) then\n    Exit;\n  EntryPoint := EntryPointVar;\n  if (EntryPoint < Low(wbPERKEntryPoints)) or (EntryPoint > High(wbPERKEntryPoints)) then begin\n    case aType of\n      ctToStr: Result := IntToStr(aInt) + ' <Warning: Unknown Entry Point #'+IntToStr(EntryPoint)+'>';\n      ctCheck: Result := '<Warning: Unknown Entry Point #'+IntToStr(EntryPoint)+'>';\n    end;\n    Exit;\n  end;\n\n  with wbPERKEntryPoints[EntryPoint] do begin\n    with wbPERKCondition[Condition] do begin\n      case aType of\n        ctEditType: Result := 'ComboBox';\n        ctEditInfo: with TStringList.Create do try\n          if Caption1 <> '' then\n            Add(Caption1);\n          if Caption2 <> '' then\n            Add(Caption2);\n          if Caption3 <> '' then\n            Add(Caption3);\n          Sort;\n          Result := CommaText;\n        finally\n          Free;\n        end;\n      else\n        if (aInt < 0) or (aInt >= Count) then\n          case aType of\n            ctToStr: Result := IntToStr(aInt) + ' <Warning: Value out of Bounds for this Entry Point>';\n            ctCheck: Result := '<Warning: Value out of Bounds for this Entry Point>';\n          end\n        else\n          case aType of\n            ctToStr, ctToEditValue: case Integer(aInt) of\n              0: Result := Caption1;\n              1: Result := Caption2;\n              2: Result := Caption3;\n            end;\n            ctCheck: Result := '';\n          end;\n      end;\n    end;\n  end;\nend;\n\nfunction wbPRKCToInt(const aString: string; const aElement: IwbElement): Int64;\nvar\n  Container     : IwbContainerElementRef;\n  EntryPointVar : Variant;\n  EntryPoint    : Integer;\n  s             : string;\nbegin\n  s := Trim(aString);\n\n  Result := StrToInt64Def(s, Low(Integer));\n  if Result <> Low(Integer) then\n    Exit;\n  if s = '' then begin\n    Result := 0;\n    Exit;\n  end;\n\n  if not Supports(aElement, IwbContainerElementRef, Container) then\n    raise Exception.Create('Could not resolve Entry Point');\n  EntryPointVar := Container.ElementNativeValues['..\\..\\..\\DATA\\Entry Point\\Entry Point'];\n  if VarIsNull(EntryPointVar) or VarIsClear(EntryPointVar) then\n    raise Exception.Create('Could not resolve Entry Point');\n\n  EntryPoint := EntryPointVar;\n  if (EntryPoint < Low(wbPERKEntryPoints)) or (EntryPoint > High(wbPERKEntryPoints)) then\n    raise Exception.Create('Unknown Entry Point #'+IntToStr(EntryPoint));\n\n  with wbPERKEntryPoints[EntryPoint] do\n    with wbPERKCondition[Condition] do\n      if SameText(aString, Caption1) then\n        Result := 0\n      else if SameText(aString, Caption2) then\n        Result := 1\n      else if SameText(aString, Caption3) then\n        Result := 2\n      else\n        raise Exception.Create('\"'+s+'\" is not valid for this Entry Point');\nend;\n\nfunction wbNeverShow(const aElement: IwbElement): Boolean;\nbegin\n  Result := wbHideNeverShow;\nend;\n\nfunction GetREGNType(aElement: IwbElement): Integer;\nvar\n  Container: IwbContainerElementRef;\nbegin\n  Result := -1;\n  if not Assigned(aElement) then\n    Exit;\n  while aElement.Name <> 'Region Data Entry' do begin\n    aElement := aElement.Container;\n    if not Assigned(aElement) then\n      Exit;\n  end;\n  if not Supports(aElement, IwbContainerElementRef, Container) then\n    Exit;\n  Result := Container.ElementNativeValues['RDAT\\Type'];\nend;\n\nfunction wbREGNObjectsDontShow(const aElement: IwbElement): Boolean;\nbegin\n  Result := GetREGNType(aElement) <> 2;\nend;\n\nfunction wbREGNWeatherDontShow(const aElement: IwbElement): Boolean;\nbegin\n  Result := GetREGNType(aElement) <> 3;\nend;\n\nfunction wbREGNMapDontShow(const aElement: IwbElement): Boolean;\nbegin\n  Result := GetREGNType(aElement) <> 4;\nend;\n\nfunction wbREGNLandDontShow(const aElement: IwbElement): Boolean;\nbegin\n  Result := GetREGNType(aElement) <> 5;\nend;\n\nfunction wbREGNGrassDontShow(const aElement: IwbElement): Boolean;\nbegin\n  Result := GetREGNType(aElement) <> 6;\nend;\n\nfunction wbREGNSoundDontShow(const aElement: IwbElement): Boolean;\nbegin\n  Result := GetREGNType(aElement) <> 7;\nend;\n\nfunction wbMESGTNAMDontShow(const aElement: IwbElement): Boolean;\nvar\n  Container  : IwbContainerElementRef;\n  MainRecord : IwbMainRecord;\nbegin\n  Result := False;\n  if not Supports(aElement, IwbMainRecord, MainRecord) then\n    Exit;\n  if not Supports(aElement, IwbContainerElementRef, Container) then\n    Exit;\n  if Integer(Container.ElementNativeValues['DNAM']) and 1 <> 0 then\n    Result := True;\nend;\n\nfunction wbEPFDDontShow(const aElement: IwbElement): Boolean;\nvar\n  Container: IwbContainerElementRef;\nbegin\n  Result := False;\n  if aElement.Name <> 'Entry Point Function Parameters' then\n    Exit;\n  if not Supports(aElement, IwbContainerElementRef, Container) then\n    Exit;\n  if not (Integer(Container.ElementNativeValues['EPFT']) in [1..3]) then\n    Result := True;\nend;\n\nfunction wbTES4ONAMDontShow(const aElement: IwbElement): Boolean;\nvar\n  MainRecord : IwbMainRecord;\nbegin\n  Result := False;\n  if not Assigned(aElement) then\n    Exit;\n  MainRecord := aElement.ContainingMainRecord;\n  if not Assigned(MainRecord) then\n    Exit;\n  if not MainRecord.IsESM then\n    Result := True;\nend;\n\n\nfunction wbEPF2DontShow(const aElement: IwbElement): Boolean;\nvar\n  Container: IwbContainerElementRef;\nbegin\n  Result := False;\n  if aElement.Name <> 'Entry Point Function Parameters' then\n    Exit;\n  if not Supports(aElement, IwbContainerElementRef, Container) then\n    Exit;\n  if not (Integer(Container.ElementNativeValues['EPFT']) in [4]) then\n    Result := True;\nend;\n\nfunction wbPERKPRKCDontShow(const aElement: IwbElement): Boolean;\nvar\n  Container: IwbContainerElementRef;\nbegin\n  Result := False;\n  if aElement.Name <> 'Effect' then\n    Exit;\n  if not Supports(aElement, IwbContainerElementRef, Container) then\n    Exit;\n  if Integer(Container.ElementNativeValues['PRKE\\Type']) <> 2 then\n    Result := True;\nend;\n\nfunction wbPerkDATAFunctionToStr(aInt: Int64; const aElement: IwbElement; aType: TwbCallbackType): string;\nvar\n  Container     : IwbContainerElementRef;\n  EntryPointVar : Variant;\n  EntryPoint    : Integer;\n  i             : Integer;\nbegin\n  case aType of\n    ctToStr: Result := IntToStr(aInt) + ' <Warning: Could not resolve Entry Point>';\n    ctToEditValue: Result := IntToStr(aInt);\n    ctToSortKey: begin\n      Result := IntToHex64(aInt, 2);\n      Exit;\n    end;\n    ctCheck: Result := '<Warning: Could not resolve Entry Point>';\n    ctEditType: Result := '';\n    ctEditInfo: Result := '';\n  end;\n\n  if not Supports(aElement, IwbContainerElementRef, Container) then\n    Exit;\n  EntryPointVar := Container.ElementNativeValues['..\\Entry Point'];\n  if VarIsNull(EntryPointVar) or VarIsClear(EntryPointVar) then\n    Exit;\n  EntryPoint := EntryPointVar;\n  if (EntryPoint < Low(wbPERKEntryPoints)) or (EntryPoint > High(wbPERKEntryPoints)) then begin\n    case aType of\n      ctToStr: Result := IntToStr(aInt) + ' <Warning: Unknown Entry Point #'+IntToStr(EntryPoint)+'>';\n      ctCheck: Result := '<Warning: Unknown Entry Point #'+IntToStr(EntryPoint)+'>';\n    end;\n    Exit;\n  end;\n\n  with wbPERKEntryPoints[EntryPoint] do begin\n    case aType of\n      ctEditType: Result := 'ComboBox';\n      ctEditInfo: with TStringList.Create do try\n        for i := Low(wbPERKFunctions) to High(wbPERKFunctions) do\n          if wbPERKFunctions[i].FunctionType = FunctionType then\n            if (wbPERKFunctions[i].Name <> '') then\n              Add(wbPERKFunctions[i].Name);\n        Sort;\n        Result := CommaText;\n      finally\n        Free;\n      end;\n    else\n      if (aInt < Low(wbPERKFunctions)) or (aInt > High(wbPERKFunctions)) then\n        case aType of\n          ctToStr: Result := IntToStr(aInt) + ' <Warning: Unknown Function>';\n          ctCheck: Result := '<Warning: Unknown Function>';\n        end\n      else\n        case aType of\n          ctToStr, ctToEditValue: begin\n            Result := wbPERKFunctions[Integer(aInt)].Name;\n            if (aType = ctToStr) and (wbPERKFunctions[Integer(aInt)].FunctionType <> FunctionType) then\n              Result := Result + ' <Warning: Value out of Bounds for this Entry Point>';\n          end;\n          ctCheck:\n            if wbPERKFunctions[Integer(aInt)].FunctionType <> FunctionType then\n              Result := '<Warning: Value out of Bounds for this Entry Point>'\n            else\n              Result := '';\n        end;\n    end;\n  end;\nend;\n\nfunction wbPerkDATAFunctionToInt(const aString: string; const aElement: IwbElement): Int64;\nvar\n  Container     : IwbContainerElementRef;\n  EntryPointVar : Variant;\n  EntryPoint    : Integer;\n  s             : string;\n  i             : Integer;\nbegin\n  s := Trim(aString);\n\n  Result := StrToInt64Def(s, Low(Integer));\n  if Result <> Low(Integer) then\n    Exit;\n  if s = '' then\n    raise Exception.Create('\"\" is not a valid value for this field');\n\n  if not Supports(aElement, IwbContainerElementRef, Container) then\n    raise Exception.Create('Could not resolve Entry Point');\n  EntryPointVar := Container.ElementNativeValues['..\\Entry Point'];\n  if VarIsNull(EntryPointVar) or VarIsClear(EntryPointVar) then\n    raise Exception.Create('Could not resolve Entry Point');\n\n  EntryPoint := EntryPointVar;\n  if (EntryPoint < Low(wbPERKEntryPoints)) or (EntryPoint > High(wbPERKEntryPoints)) then\n    raise Exception.Create('Unknown Entry Point #'+IntToStr(EntryPoint));\n\n  with wbPERKEntryPoints[EntryPoint] do\n    for i := Low(wbPERKFunctions) to High(wbPERKFunctions) do\n      if wbPERKFunctions[i].FunctionType = FunctionType then\n        if SameText(s, wbPERKFunctions[i].Name) then begin\n          Result := i;\n          Exit;\n        end;\n\n  raise Exception.Create('\"'+s+'\" is not valid for this Entry Point');\nend;\n\nprocedure wbPerkDATAFunctionAfterSet(const aElement: IwbElement; const aOldValue, aNewValue: Variant);\nvar\n  NewFunction : Integer;\n  Container   : IwbContainerElementRef;\n  OldParamType: Integer;\n  NewParamType: Integer;\nbegin\n  NewFunction := aNewValue;\n  if (NewFunction < Low(wbPERKFunctions)) or (NewFunction > High(wbPERKFunctions)) then\n    Exit;\n  if not Supports(aElement, IwbContainerElementRef, Container) then\n    Exit;\n  OldParamType := Container.ElementNativeValues['..\\..\\..\\Entry Point Function Parameters\\EPFT'];\n  NewParamType := Ord(wbPERKFunctions[NewFunction].ParamType);\n  if (OldParamType = NewParamType) and not VarSameValue(aOldValue, aNewValue) and (NewFunction in [4,5]) then\n    Container.ElementNativeValues['..\\..\\..\\Entry Point Function Parameters\\EPFT'] := 0;\n  Container.ElementNativeValues['..\\..\\..\\Entry Point Function Parameters\\EPFT'] := NewParamType;\nend;\n\nfunction wbPerkEPFTToStr(aInt: Int64; const aElement: IwbElement; aType: TwbCallbackType): string;\nvar\n  Container       : IwbContainerElementRef;\n  FunctionTypeVar : Variant;\n  FunctionType    : Integer;\n//  i               : Integer;\nbegin\n  case aType of\n    ctToStr: Result := IntToStr(aInt) + ' <Warning: Could not resolve Function>';\n    ctToEditValue: Result := IntToStr(aInt);\n    ctToSortKey: begin\n      Result := IntToHex64(aInt, 2);\n      Exit;\n    end;\n    ctCheck: Result := '<Warning: Could not resolve Function>';\n    ctEditType: Result := '';\n    ctEditInfo: Result := '';\n  end;\n\n  if not Supports(aElement, IwbContainerElementRef, Container) then\n    Exit;\n  FunctionTypeVar := Container.ElementNativeValues['..\\..\\DATA\\Entry Point\\Function'];\n  if VarIsNull(FunctionTypeVar) or VarIsClear(FunctionTypeVar) then\n    Exit;\n  FunctionType := FunctionTypeVar;\n  if (FunctionType < Low(wbPERKFunctions)) or (FunctionType > High(wbPERKFunctions)) then begin\n    case aType of\n      ctToStr: Result := IntToStr(aInt) + ' <Warning: Unknown Function #'+IntToStr(FunctionType)+'>';\n      ctCheck: Result := '<Warning: Unknown Function #'+IntToStr(FunctionType)+'>';\n    end;\n    Exit;\n  end;\n\n  with wbPERKFunctions[FunctionType] do begin\n    case aType of\n      ctEditType: Result := 'ComboBox';\n      ctEditInfo: Result := '\"' + wbPERKFunctionParams[ParamType] + '\"';\n    else\n      if (aInt < Ord(Low(wbPERKFunctionParams))) or (aInt > Ord(High(wbPERKFunctionParams))) then\n        case aType of\n          ctToStr: Result := IntToStr(aInt) + ' <Warning: Unknown Function Param Type>';\n          ctCheck: Result := '<Warning: Unknown Function Param Type>';\n        end\n      else\n        case aType of\n          ctToStr, ctToEditValue: begin\n            Result := wbPERKFunctionParams[TPERKEntryPointFunctionParamType(aInt)];\n            if (aType = ctToStr) and (TPERKEntryPointFunctionParamType(aInt) <> ParamType) then\n              Result := Result + ' <Warning: Value out of Bounds for this Function>';\n          end;\n          ctCheck:\n            if TPERKEntryPointFunctionParamType(aInt) <> ParamType then\n              Result := Result + ' <Warning: Value out of Bounds for this Function>'\n            else\n              Result := '';\n        end;\n    end;\n  end;\nend;\n\nfunction wbPerkEPFTToInt(const aString: string; const aElement: IwbElement): Int64;\nvar\n  Container       : IwbContainerElementRef;\n  FunctionTypeVar : Variant;\n  FunctionType    : Integer;\n  s               : string;\n//  i               : Integer;\n  j               : TPERKEntryPointFunctionParamType;\nbegin\n  s := Trim(aString);\n\n  Result := StrToInt64Def(s, Low(Integer));\n  if Result <> Low(Integer) then\n    Exit;\n  if s = '' then\n    raise Exception.Create('\"\" is not a valid value for this field');\n\n  if not Supports(aElement, IwbContainerElementRef, Container) then\n    raise Exception.Create('Could not resolve Function');\n  FunctionTypeVar := Container.ElementNativeValues['..\\..\\DATA\\Entry Point\\Function'];\n  if VarIsNull(FunctionTypeVar) or VarIsClear(FunctionTypeVar) then\n    raise Exception.Create('Could not resolve Function');\n\n  FunctionType := FunctionTypeVar;\n  if (FunctionType < Low(wbPERKFunctions)) or (FunctionType > High(wbPERKFunctions)) then\n    raise Exception.Create('Unknown Function #'+IntToStr(FunctionType));\n\n  with wbPERKFunctions[FunctionType] do begin\n    for j := Low(wbPERKFunctionParams) to High(wbPERKFunctionParams) do\n      if SameText(s, wbPERKFunctionParams[j]) then begin\n        if j <> ParamType then\n          raise Exception.Create('\"'+s+'\" is not a valid Parameter Type for Function \"'+Name+'\"');\n        Result := Ord(j);\n        Exit;\n      end;\n  end;\n\n  raise Exception.Create('\"'+s+'\" is not a valid Parameter Type');\nend;\n\nprocedure wbPerkEPFTAfterSet(const aElement: IwbElement; const aOldValue, aNewValue: Variant);\nvar\n  i: Integer;\n  Container: IwbContainerElementRef;\nbegin\n  if VarSameValue(aOldValue, aNewValue) then\n    Exit;\n  i := aNewValue;\n  if (i < Ord(Low(wbPERKFunctionParams))) or (i> Ord(High(wbPERKFunctionParams))) then\n    Exit;\n  if not Supports(aElement.Container, IwbContainerElementRef, Container) then\n    Exit;\n  Container.RemoveElement('EPFD');\n  Container.RemoveElement('EPF2');\n  Container.RemoveElement('EPF3');\n  Container.RemoveElement('Embedded Script');\n  case TPERKEntryPointFunctionParamType(i) of\n    epfpFloat, epfpFloatFloat, epfpLeveledItem:\n      Container.Add('EPFD', True);\n    epfpScript: begin\n      Container.Add('EPF2', True);\n      Container.Add('EPF3', True);\n      Container.Add('SCHR', True);\n    end;\n  end;\nend;\n\nprocedure wbRemoveOFST(const aElement: IwbElement);\nvar\n  Container: IwbContainer;\n  rOFST: IwbRecord;\nbegin\n  if not wbRemoveOffsetData then\n    Exit;\n\n  if Supports(aElement, IwbContainer, Container) then begin\n    if wbBeginInternalEdit then try\n      Container.RemoveElement(OFST);\n    finally\n      wbEndInternalEdit;\n    end else begin\n      rOFST := Container.RecordBySignature[OFST];\n      if Assigned(rOFST) then\n        Container.RemoveElement(rOFST);\n    end;\n  end;\nend;\n\nfunction wbActorTemplateUseTraits(const aElement: IwbElement): Boolean;\nvar\n  Element    : IwbElement;\n  MainRecord : IwbMainRecord;\n  i          : Int64;\nbegin\n  Result := False;\n  if not wbActorTemplateHide then Exit;\n  Element := GetElementFromUnion(aElement);\n  MainRecord := nil;\n  while Assigned(Element) and not Supports(Element, IwbMainRecord, MainRecord) do\n    Element := Element.Container;\n  if Assigned(MainRecord) then begin\n    i := MainRecord.ElementNativeValues['ACBS\\Template Flags'];\n    Result := (i and $00000001) <> 0;\n  end;\nend;\n\nfunction wbActorTemplateUseStats(const aElement: IwbElement): Boolean;\nvar\n  Element    : IwbElement;\n  MainRecord : IwbMainRecord;\n  i          : Int64;\nbegin\n  Result := False;\n  if not wbActorTemplateHide then Exit;\n  Element := GetElementFromUnion(aElement);\n  MainRecord := nil;\n  while Assigned(Element) and not Supports(Element, IwbMainRecord, MainRecord) do\n    Element := Element.Container;\n  if Assigned(MainRecord) then begin\n    i := MainRecord.ElementNativeValues['ACBS\\Template Flags'];\n    Result := (i and $00000002) <> 0;\n  end;\nend;\n\nfunction wbActorAutoCalcDontShow(const aElement: IwbElement): Boolean;\nvar\n  Element    : IwbElement;\n  MainRecord : IwbMainRecord;\n  i          : Int64;\nbegin\n  Result := False;\n  if not wbActorTemplateHide then Exit;\n  Element := GetElementFromUnion(aElement);\n  MainRecord := nil;\n  while Assigned(Element) and not Supports(Element, IwbMainRecord, MainRecord) do\n    Element := Element.Container;\n  if Assigned(MainRecord) then begin\n    i := MainRecord.ElementNativeValues['ACBS\\Flags'];\n    Result := (i and $00000010) <> 0;\n  end;\nend;\n\nfunction wbActorTemplateUseStatsAutoCalc(const aElement: IwbElement): Boolean;\nbegin\n  if not wbActorTemplateHide then\n    Result := False\n  else\n    Result := wbActorTemplateUseStats(aElement) or wbActorAutoCalcDontShow(aElement);\nend;\n\nfunction wbActorTemplateUseFactions(const aElement: IwbElement): Boolean;\nvar\n  Element    : IwbElement;\n  MainRecord : IwbMainRecord;\n  i          : Int64;\nbegin\n  Result := False;\n  if not wbActorTemplateHide then Exit;\n  Element := GetElementFromUnion(aElement);\n  MainRecord := nil;\n  while Assigned(Element) and not Supports(Element, IwbMainRecord, MainRecord) do\n    Element := Element.Container;\n  if Assigned(MainRecord) then begin\n    i := MainRecord.ElementNativeValues['ACBS\\Template Flags'];\n    Result := (i and $00000004) <> 0;\n  end;\nend;\n\nfunction wbActorTemplateUseActorEffectList(const aElement: IwbElement): Boolean;\nvar\n  Element    : IwbElement;\n  MainRecord : IwbMainRecord;\n  i          : Int64;\nbegin\n  Result := False;\n  if not wbActorTemplateHide then Exit;\n  Element := GetElementFromUnion(aElement);\n  MainRecord := nil;\n  while Assigned(Element) and not Supports(Element, IwbMainRecord, MainRecord) do\n    Element := Element.Container;\n  if Assigned(MainRecord) then begin\n    i := MainRecord.ElementNativeValues['ACBS\\Template Flags'];\n    Result := (i and $00000008) <> 0;\n  end;\nend;\n\nfunction wbActorTemplateUseAIData(const aElement: IwbElement): Boolean;\nvar\n  Element    : IwbElement;\n  MainRecord : IwbMainRecord;\n  i          : Int64;\nbegin\n  Result := False;\n  if not wbActorTemplateHide then Exit;\n  Element := GetElementFromUnion(aElement);\n  MainRecord := nil;\n  while Assigned(Element) and not Supports(Element, IwbMainRecord, MainRecord) do\n    Element := Element.Container;\n  if Assigned(MainRecord) then begin\n    i := MainRecord.ElementNativeValues['ACBS\\Template Flags'];\n    Result := (i and $00000010) <> 0;\n  end;\nend;\n\nfunction wbActorTemplateUseAIPackages(const aElement: IwbElement): Boolean;\nvar\n  Element    : IwbElement;\n  MainRecord : IwbMainRecord;\n  i          : Int64;\nbegin\n  Result := False;\n  if not wbActorTemplateHide then Exit;\n  Element := GetElementFromUnion(aElement);\n  MainRecord := nil;\n  while Assigned(Element) and not Supports(Element, IwbMainRecord, MainRecord) do\n    Element := Element.Container;\n  if Assigned(MainRecord) then begin\n    i := MainRecord.ElementNativeValues['ACBS\\Template Flags'];\n    Result := (i and $00000020) <> 0;\n  end;\nend;\n\nfunction wbActorTemplateUseModelAnimation(const aElement: IwbElement): Boolean;\nvar\n  Element    : IwbElement;\n  MainRecord : IwbMainRecord;\n  i          : Int64;\nbegin\n  Result := False;\n  if not wbActorTemplateHide then Exit;\n  Element := GetElementFromUnion(aElement);\n  MainRecord := nil;\n  while Assigned(Element) and not Supports(Element, IwbMainRecord, MainRecord) do\n    Element := Element.Container;\n  if Assigned(MainRecord) then begin\n    i := MainRecord.ElementNativeValues['ACBS\\Template Flags'];\n    Result := (i and $00000040) <> 0;\n  end;\nend;\n\nfunction wbActorTemplateUseBaseData(const aElement: IwbElement): Boolean;\nvar\n  Element    : IwbElement;\n  MainRecord : IwbMainRecord;\n  i          : Int64;\nbegin\n  Result := False;\n  if not wbActorTemplateHide then Exit;\n  Element := GetElementFromUnion(aElement);\n  MainRecord := nil;\n  while Assigned(Element) and not Supports(Element, IwbMainRecord, MainRecord) do\n    Element := Element.Container;\n  if Assigned(MainRecord) then begin\n    i := MainRecord.ElementNativeValues['ACBS\\Template Flags'];\n    Result := (i and $00000080) <> 0;\n  end;\nend;\n\nfunction wbActorTemplateUseInventory(const aElement: IwbElement): Boolean;\nvar\n  Element    : IwbElement;\n  MainRecord : IwbMainRecord;\n  i          : Int64;\nbegin\n  Result := False;\n  if not wbActorTemplateHide then Exit;\n  Element := GetElementFromUnion(aElement);\n  MainRecord := nil;\n  while Assigned(Element) and not Supports(Element, IwbMainRecord, MainRecord) do\n    Element := Element.Container;\n  if Assigned(MainRecord) then begin\n    i := MainRecord.ElementNativeValues['ACBS\\Template Flags'];\n    Result := (i and $00000100) <> 0;\n  end;\nend;\n\nfunction wbActorTemplateUseScript(const aElement: IwbElement): Boolean;\nvar\n  Element    : IwbElement;\n  MainRecord : IwbMainRecord;\n  i          : Int64;\nbegin\n  Result := False;\n  if not wbActorTemplateHide then Exit;\n  Element := GetElementFromUnion(aElement);\n  MainRecord := nil;\n  while Assigned(Element) and not Supports(Element, IwbMainRecord, MainRecord) do\n    Element := Element.Container;\n  if Assigned(MainRecord) then begin\n    i := MainRecord.ElementNativeValues['ACBS\\Template Flags'];\n    Result := (i and $00000200) <> 0;\n  end;\nend;\n\nprocedure wbCTDAAfterLoad(const aElement: IwbElement);\nvar\n  Container  : IwbContainerElementRef;\n  //Size       : Cardinal;\n  TypeFlags  : Cardinal;\nbegin\n  if wbBeginInternalEdit then try\n    if not Supports(aElement, IwbContainerElementRef, Container) then\n      Exit;\n\n    if Container.ElementCount < 1 then\n      Exit;\n\n    TypeFlags := Container.ElementNativeValues['Type'];\n    if (TypeFlags and $02) <> 0 then begin\n      if Container.DataSize = 20 then\n        Container.DataSize := 28;\n      Container.ElementNativeValues['Type'] := TypeFlags and not $02;\n      Container.ElementEditValues['Run On'] := 'Target';\n    end;\n  finally\n    wbEndInternalEdit;\n  end;\nend;\n\nprocedure wbMGEFAfterLoad(const aElement: IwbElement);\nvar\n  Container     : IwbContainerElementRef;\n  MainRecord    : IwbMainRecord;\n  OldActorValue : Integer;\n  NewActorValue : Integer;\nbegin\n  if wbBeginInternalEdit then try\n    if not Supports(aElement, IwbContainerElementRef, Container) then\n      Exit;\n\n    if Container.ElementCount < 1 then\n      Exit;\n\n    if not Supports(aElement, IwbMainRecord, MainRecord) then\n      Exit;\n\n    if MainRecord.IsDeleted then\n      Exit;\n\n    OldActorValue := Container.ElementNativeValues['DATA - Data\\Actor Value'];\n    NewActorValue := OldActorValue;\n    case Integer(Container.ElementNativeValues['DATA - Data\\Archtype']) of\n      01, //Script\n      02, //Dispel\n      03, //Cure Disease\n      13, //Light\n      16, //Lock\n      17, //Open\n      18, //Bound Item\n      19, //Summon Creature\n      30, //Cure Paralysis\n      31, //Cure Addiction\n      32, //Cure Poison\n      33: //Concussion\n        NewActorValue := -1;\n      11: //Invisibility\n        NewActorValue := 48; //Invisibility\n      12: //Chameleon\n        NewActorValue := 49; //Chameleon\n      24: //Paralysis\n        NewActorValue := 47; //Paralysis\n    end;\n    if OldActorValue <> NewActorValue then\n      Container.ElementNativeValues['DATA - Data\\Actor Value'] := NewActorValue;\n  finally\n    wbEndInternalEdit;\n  end;\nend;\n\nprocedure wbPACKAfterLoad(const aElement: IwbElement);\nvar\n  Container     : IwbContainerElementRef;\n  MainRecord    : IwbMainRecord;\n  NewContainer  : IwbContainerElementRef;\nbegin\n  if wbBeginInternalEdit then try\n    if not Supports(aElement, IwbContainerElementRef, Container) then\n      Exit;\n\n    if Container.ElementCount < 1 then\n      Exit;\n\n    if not Supports(aElement, IwbMainRecord, MainRecord) then\n      Exit;\n\n    if MainRecord.IsDeleted then\n      Exit;\n\n    case Integer(Container.ElementNativeValues['PKDT - General\\Type']) of\n       0: begin {Find}\n         Container.Add('PTDT');\n       end;\n       1: begin {Follow}\n         Container.Add('PKFD');\n       end;\n       2: begin {Escort}\n       end;\n       3: begin {Eat}\n         Container.Add('PTDT');\n         Container.Add('PKED');\n       end;\n       4: begin {Sleep}\n         if not Container.ElementExists['Locations'] then\n           if Supports(Container.Add('Locations'), IwbContainerElementRef, NewContainer) then\n             NewContainer.ElementEditValues['PLDT - Location 1\\Type'] := 'Near editor location';\n       end;\n       5: begin {Wander}\n       end;\n       6: begin {Travel}\n       end;\n       7: begin {Accompany}\n       end;\n       8: begin {Use Item At}\n       end;\n       9: begin {Ambush}\n       end;\n      10: begin {Flee Not Combat}\n      end;\n      12: begin {Sandbox}\n      end;\n      13: begin {Patrol}\n         if not Container.ElementExists['Locations'] then\n           if Supports(Container.Add('Locations'), IwbContainerElementRef, NewContainer) then\n             NewContainer.ElementEditValues['PLDT - Location 1\\Type'] := 'Near linked reference';\n        Container.Add('PKPT');\n      end;\n      14: begin {Guard}\n      end;\n      15: begin {Dialogue}\n      end;\n      16: begin {Use Weapon}\n      end;\n    end;\n\n  finally\n    wbEndInternalEdit;\n  end;\nend;\n\nprocedure wbNPCAfterLoad(const aElement: IwbElement);\nvar\n  Container  : IwbContainerElementRef;\n  MainRecord : IwbMainRecord;\n//  BaseRecord : IwbMainRecord;\nbegin\n  if wbBeginInternalEdit then try\n    if not Supports(aElement, IwbContainerElementRef, Container) then\n      Exit;\n\n    if Container.ElementCount < 1 then\n      Exit;\n\n    if not Supports(aElement, IwbMainRecord, MainRecord) then\n      Exit;\n\n    if MainRecord.IsDeleted then\n      Exit;\n\n    if Container.ElementNativeValues['NAM5'] > 255 then\n      Container.ElementNativeValues['NAM5'] := 255;\n  finally\n    wbEndInternalEdit;\n  end;\nend;\n\nprocedure wbREFRAfterLoad(const aElement: IwbElement);\nvar\n  Container  : IwbContainerElementRef;\n  MainRecord : IwbMainRecord;\n  BaseRecord : IwbMainRecord;\nbegin\n  if wbBeginInternalEdit then try\n    if not Supports(aElement, IwbContainerElementRef, Container) then\n      Exit;\n\n    if Container.ElementCount < 1 then\n      Exit;\n\n    if not Supports(aElement, IwbMainRecord, MainRecord) then\n      Exit;\n\n    if MainRecord.IsDeleted then\n      Exit;\n\n    Container.RemoveElement('RCLR');\n\n    if Container.ElementExists['Ammo'] then begin\n      BaseRecord := MainRecord.BaseRecord;\n      if Assigned(BaseRecord) and (BaseRecord.Signature <> 'WEAP') then\n        Container.RemoveElement('Ammo');\n    end;\n  finally\n    wbEndInternalEdit;\n  end;\nend;\n\nprocedure wbINFOAfterLoad(const aElement: IwbElement);\nvar\n  Container  : IwbContainerElementRef;\n  MainRecord : IwbMainRecord;\nbegin\n  if wbBeginInternalEdit then try\n    if not Supports(aElement, IwbContainerElementRef, Container) then\n      Exit;\n\n    if Container.ElementCount < 1 then\n      Exit;\n\n    if not Supports(aElement, IwbMainRecord, MainRecord) then\n      Exit;\n\n    if MainRecord.IsDeleted then\n      Exit;\n\n    if (Integer(Container.ElementNativeValues['DATA\\Flags 1']) and $80) = 0 then\n      Container.RemoveElement('DNAM');\n\n    Container.RemoveElement('SNDD');\n\n    if Container.ElementNativeValues['DATA\\Type'] = 3 {Persuasion} then\n      Container.ElementNativeValues['DATA\\Type'] := 0 {Topic};\n  finally\n    wbEndInternalEdit;\n  end;\nend;\n\nprocedure wbCELLAfterLoad(const aElement: IwbElement);\nvar\n  Container    : IwbContainerElementRef;\n//  Container2   : IwbContainerElementRef;\n  MainRecord   : IwbMainRecord;\n//  i            : Integer;\nbegin\n  if wbBeginInternalEdit then try\n    if not Supports(aElement, IwbContainerElementRef, Container) then\n      Exit;\n\n    if Container.ElementCount < 1 then\n      Exit;\n\n    if not Supports(aElement, IwbMainRecord, MainRecord) then\n      Exit;\n\n    if MainRecord.IsDeleted then\n      Exit;\n\n    if (not Container.ElementExists['XCLW']) and ((Integer(Container.ElementNativeValues['DATA']) and $02) <> 0) then begin\n      Container.Add('XCLW', True);\n      Container.ElementEditValues['XCLW'] := 'Default';\n    end;\n\n    if (not Container.ElementExists['XNAM']) and ((Integer(Container.ElementNativeValues['DATA']) and $02) <> 0) then\n      Container.Add('XNAM', True);\n\n//    if Supports(Container.ElementBySignature[XCLR], IwbContainerElementRef, Container2) then begin\n//      for i:= Pred(Container2.ElementCount) downto 0 do\n//        if not Supports(Container2.Elements[i].LinksTo, IwbMainRecord, MainRecord) or (MainRecord.Signature <> 'REGN') then\n//          Container2.RemoveElement(i);\n//      if Container2.ElementCount < 1 then\n//        Container2.Remove;\n//    end;\n  finally\n    wbEndInternalEdit;\n  end;\nend;\n\nprocedure wbEmbeddedScriptAfterLoad(const aElement: IwbElement);\nvar\n  Container: IwbContainerElementRef;\nbegin\n  if wbBeginInternalEdit then try\n    if not Supports(aElement, IwbContainerElementRef, Container) then\n      Exit;\n\n    if Container.ElementCount < 1 then\n      Exit;\n\n    if Container.ElementEditValues['SCHR\\Type'] = 'Quest' then\n      Container.ElementEditValues['SCHR\\Type'] := 'Object';\n  finally\n    wbEndInternalEdit;\n  end;\nend;\n\n\nprocedure wbSOUNAfterLoad(const aElement: IwbElement);\nvar\n  Container: IwbContainerElementRef;\n  MainRecord   : IwbMainRecord;\n  OldCntr: IwbContainerElementRef;\n  NewCntr: IwbContainerElementRef;\n  NewCntr2: IwbContainerElementRef;\n  i: Integer;\nbegin\n  if wbBeginInternalEdit then try\n    if not Supports(aElement, IwbContainerElementRef, Container) then\n      Exit;\n\n    if Container.ElementCount < 1 then\n      Exit;\n\n    if not Supports(aElement, IwbMainRecord, MainRecord) then\n      Exit;\n\n    if MainRecord.IsDeleted then\n      Exit;\n\n    if Container.ElementExists['SNDD'] then\n      Exit;\n\n    if not Supports(Container.RemoveElement('SNDX - Sound Data'), IwbContainerElementRef, OldCntr) then\n      Exit;\n    if not Supports(Container.Add('SNDD', True), IwbContainerElementRef, NewCntr) then\n      Exit;\n    for i := 0 to Pred(Min(OldCntr.ElementCount, NewCntr.ElementCount)) do\n      NewCntr.Elements[i].Assign(Low(Integer), OldCntr.Elements[i], False);\n\n    if not Supports(NewCntr.ElementByName['Attenuation Curve'], IwbContainerElementRef, NewCntr2) then\n      Assert(False);\n    Assert(NewCntr2.ElementCount = 5);\n\n    if Supports(Container.RemoveElement('ANAM'), IwbContainerElementRef, OldCntr) then begin\n      Assert(OldCntr.ElementCount = 5);\n      for i := 0 to Pred(Min(OldCntr.ElementCount, NewCntr2.ElementCount)) do\n        NewCntr2.Elements[i].Assign(Low(Integer), OldCntr.Elements[i], False);\n    end else begin\n      NewCntr2.Elements[0].NativeValue := 100;\n      NewCntr2.Elements[1].NativeValue := 50;\n      NewCntr2.Elements[2].NativeValue := 20;\n      NewCntr2.Elements[3].NativeValue := 5;\n      NewCntr2.Elements[4].NativeValue := 0;\n    end;\n\n    if not Supports(NewCntr.ElementByName['Reverb Attenuation Control'], IwbContainerElementRef, NewCntr2) then\n      Assert(False);\n\n    if Supports(Container.RemoveElement('GNAM'), IwbContainerElementRef, OldCntr) then\n      NewCntr2.Assign(Low(Integer), OldCntr, False)\n    else\n      NewCntr2.NativeValue := 80;\n\n    if not Supports(NewCntr.ElementByName['Priority'], IwbContainerElementRef, NewCntr2) then\n      Assert(False);\n\n    if Supports(Container.RemoveElement('HNAM'), IwbContainerElementRef, OldCntr) then\n      NewCntr2.Assign(Low(Integer), OldCntr, False)\n    else\n      NewCntr2.NativeValue := 128;\n\n  finally\n    wbEndInternalEdit;\n  end;\nend;\n\nprocedure wbWATRAfterLoad(const aElement: IwbElement);\nvar\n  Container: IwbContainerElementRef;\n  MainRecord   : IwbMainRecord;\n//  AnimationMultiplier : Extended;\n//  AnimationAttackMultiplier : Extended;\n  OldCntr: IwbContainerElementRef;\n  NewCntr: IwbContainerElementRef;\n  i: Integer;\nbegin\n  if wbBeginInternalEdit then try\n    if not Supports(aElement, IwbContainerElementRef, Container) then\n      Exit;\n\n    if Container.ElementCount < 1 then\n      Exit;\n\n    if not Supports(aElement, IwbMainRecord, MainRecord) then\n      Exit;\n\n    if MainRecord.IsDeleted then\n      Exit;\n\n    if Container.ElementExists['DNAM'] then\n      Exit;\n\n    if not Supports(Container.RemoveElement('DATA - Visual Data'), IwbContainerElementRef, OldCntr) then\n      Exit;\n    if not Supports(Container.Add('DNAM', True), IwbContainerElementRef, NewCntr) then\n      Exit;\n    for i := 0 to Pred(Min(OldCntr.ElementCount, NewCntr.ElementCount)) do\n      if OldCntr.Elements[i].Name = 'Damage (Old Format)' then\n        Container.ElementNativeValues['DATA - Damage'] := OldCntr.Elements[i].NativeValue\n      else\n        NewCntr.Elements[i].Assign(Low(Integer), OldCntr.Elements[i], False);\n\n    NewCntr.ElementNativeValues['Noise Properties - Noise Layer One - Amplitude Scale'] := 1.0;\n    NewCntr.ElementNativeValues['Noise Properties - Noise Layer Two - Amplitude Scale'] := 0.5;\n    NewCntr.ElementNativeValues['Noise Properties - Noise Layer Three - Amplitude Scale'] := 0.25;\n  finally\n    wbEndInternalEdit;\n  end;\nend;\n\n\nprocedure wbWEAPAfterLoad(const aElement: IwbElement);\nvar\n  Container: IwbContainerElementRef;\n  MainRecord   : IwbMainRecord;\nbegin\n  if wbBeginInternalEdit then try\n    if not Supports(aElement, IwbContainerElementRef, Container) then\n      Exit;\n\n    if Container.ElementCount < 1 then\n      Exit;\n\n    if not Supports(aElement, IwbMainRecord, MainRecord) then\n      Exit;\n\n    if MainRecord.IsDeleted then\n      Exit;\n\n    if not Container.ElementExists['DNAM'] then\n      Exit;\n\n    if Container.ElementNativeValues['DNAM\\Animation Multiplier'] = 0.0 then\n      Container.ElementNativeValues['DNAM\\Animation Multiplier'] := 1.0;\n    if Container.ElementNativeValues['DNAM\\Animation Attack Multiplier'] = 0.0 then\n      Container.ElementNativeValues['DNAM\\Animation Attack Multiplier'] := 1.0;\n  finally\n    wbEndInternalEdit;\n  end;\nend;\n\nprocedure wbMESGAfterLoad(const aElement: IwbElement);\nvar\n  Container    : IwbContainerElementRef;\n  MainRecord   : IwbMainRecord;\n  IsMessageBox : Boolean;\n  HasTimeDelay : Boolean;\nbegin\n  if wbBeginInternalEdit then try\n    if not Supports(aElement, IwbContainerElementRef, Container) then\n      Exit;\n\n    if Container.ElementCount < 1 then\n      Exit;\n\n    if not Supports(aElement, IwbMainRecord, MainRecord) then\n      Exit;\n\n    if MainRecord.IsDeleted then\n      Exit;\n\n    IsMessageBox := (Integer(Container.ElementNativeValues['DNAM']) and 1) = 1;\n    HasTimeDelay := Container.ElementExists['TNAM'];\n\n    if IsMessageBox = HasTimeDelay then\n      if IsMessageBox then\n        Container.RemoveElement('TNAM')\n      else begin\n        if not Container.ElementExists['DNAM'] then\n          Container.Add('DNAM', True);\n        Container.ElementNativeValues['DNAM'] := Integer(Container.ElementNativeValues['DNAM']) or 1;\n      end;\n\n  finally\n    wbEndInternalEdit;\n  end;\nend;\n\n\nprocedure wbEFSHAfterLoad(const aElement: IwbElement);\nvar\n  Container: IwbContainerElementRef;\n  MainRecord   : IwbMainRecord;\n  FullParticleBirthRatio : Extended;\n  PersistantParticleBirthRatio : Extended;\nbegin\n  if wbBeginInternalEdit then try\n    if not Supports(aElement, IwbContainerElementRef, Container) then\n      Exit;\n\n    if Container.ElementCount < 1 then\n      Exit;\n\n    if not Supports(aElement, IwbMainRecord, MainRecord) then\n      Exit;\n\n    if MainRecord.IsDeleted then\n      Exit;\n\n    if not Container.ElementExists['DATA'] then\n      Exit;\n\n    FullParticleBirthRatio := Container.ElementNativeValues['DATA\\Particle Shader - Full Particle Birth Ratio'];\n    PersistantParticleBirthRatio := Container.ElementNativeValues['DATA\\Particle Shader - Persistant Particle Birth Ratio'];\n\n    if ((FullParticleBirthRatio <> 0) and (FullParticleBirthRatio <= 1)) then begin\n      FullParticleBirthRatio := FullParticleBirthRatio * 78.0;\n      Container.ElementNativeValues['DATA\\Particle Shader - Full Particle Birth Ratio'] := FullParticleBirthRatio;\n    end;\n\n    if ((PersistantParticleBirthRatio <> 0) and (PersistantParticleBirthRatio <= 1)) then begin\n      PersistantParticleBirthRatio := PersistantParticleBirthRatio * 78.0;\n      Container.ElementNativeValues['DATA\\Particle Shader - Persistant Particle Birth Ratio'] := PersistantParticleBirthRatio;\n    end;\n\n  finally\n    wbEndInternalEdit;\n  end;\nend;\n\nprocedure wbFACTAfterLoad(const aElement: IwbElement);\nvar\n  Container: IwbContainerElementRef;\n  MainRecord   : IwbMainRecord;\nbegin\n  if wbBeginInternalEdit then try\n    if not Supports(aElement, IwbContainerElementRef, Container) then\n      Exit;\n\n    if Container.ElementCount < 1 then\n      Exit;\n\n    if not Container.ElementExists['CNAM'] then\n      Exit;\n\n    if not Supports(aElement, IwbMainRecord, MainRecord) then\n      Exit;\n\n    if MainRecord.IsDeleted then\n      Exit;\n\n    Container.RemoveElement('CNAM');\n  finally\n    wbEndInternalEdit;\n  end;\nend;\n\nprocedure wbLIGHAfterLoad(const aElement: IwbElement);\nvar\n  Container: IwbContainerElementRef;\n  MainRecord   : IwbMainRecord;\nbegin\n  if wbBeginInternalEdit then try\n    if not Supports(aElement, IwbContainerElementRef, Container) then\n      Exit;\n\n    if Container.ElementCount < 1 then\n      Exit;\n\n    if not Supports(aElement, IwbMainRecord, MainRecord) then\n      Exit;\n\n    if MainRecord.IsDeleted then\n      Exit;\n\n    if not Container.ElementExists['FNAM'] then begin\n      Container.Add('FNAM', True);\n      Container.ElementNativeValues['FNAM'] := 1.0;\n    end;\n\n    if Container.ElementExists['DATA'] then begin\n      if SameValue(Container.ElementNativeValues['DATA\\Falloff Exponent'], 0.0) then\n        Container.ElementNativeValues['DATA\\Falloff Exponent'] := 1.0;\n      if SameValue(Container.ElementNativeValues['DATA\\FOV'], 0.0) then\n        Container.ElementNativeValues['DATA\\FOV'] := 90.0;\n    end;\n\n  finally\n    wbEndInternalEdit;\n  end;\nend;\n\nprocedure wbEFITAfterLoad(const aElement: IwbElement);\nvar\n  Container : IwbContainerElementRef;\n  Element   : IwbElement;\n  ActorValue: Variant;\n  MainRecord: IwbMainRecord;\nbegin\n  if wbBeginInternalEdit then try\n    if not Supports(aElement, IwbContainerElementRef, Container) then\n      Exit;\n\n    if Container.ElementCount < 1 then\n      Exit;\n\n    MainRecord := Container.ContainingMainRecord;\n    if not Assigned(MainRecord) or MainRecord.IsDeleted then\n      Exit;\n\n    Element := Container.ElementByPath['..\\EFID'];\n    if not Assigned(Element) then\n      Exit;\n    if not Supports(Element.LinksTo, IwbMainRecord, MainRecord) then\n      Exit;\n    if MainRecord.Signature <> 'MGEF' then\n      Exit;\n    ActorValue := MainRecord.ElementNativeValues['DATA - Data\\Actor Value'];\n    if VarIsNull(ActorValue) or VarIsClear(ActorValue) then\n      Exit;\n    if VarCompareValue(ActorValue, Container.ElementNativeValues['Actor Value']) <> vrEqual then\n      Container.ElementNativeValues['Actor Value'] := ActorValue;\n  finally\n    wbEndInternalEdit;\n  end;\nend;\n\nprocedure wbRPLDAfterLoad(const aElement: IwbElement);\nvar\n  Container: IwbContainer;\n  a, b: Single;\n  NeedsFlip: Boolean;\nbegin\n  if wbBeginInternalEdit then try\n    if Supports(aElement, IwbContainer, Container) then begin\n      NeedsFlip := False;\n      if Container.ElementCount > 1 then begin\n        a := StrToFloat((Container.Elements[0] as IwbContainer).Elements[0].Value);\n        b := StrToFloat((Container.Elements[Pred(Container.ElementCount)] as IwbContainer).Elements[0].Value);\n        case CompareValue(a, b) of\n          EqualsValue: begin\n            a := StrToFloat((Container.Elements[0] as IwbContainer).Elements[1].Value);\n            b := StrToFloat((Container.Elements[Pred(Container.ElementCount)] as IwbContainer).Elements[1].Value);\n            NeedsFlip := CompareValue(a, b) = GreaterThanValue;\n          end;\n          GreaterThanValue:\n            NeedsFlip := True;\n        end;\n      end;\n      if NeedsFlip then\n        Container.ReverseElements;\n    end;\n  finally\n    wbEndInternalEdit;\n  end;\nend;\n\nfunction wbPxDTLocationDecider(aBasePtr: Pointer; aEndPtr: Pointer; const aElement: IwbElement): Integer;\nvar\n  Container: IwbContainer;\nbegin\n  Result := 0;\n  if not Assigned(aElement) then Exit;\n  Container := GetContainerFromUnion(aElement);\n  if not Assigned(Container) then Exit;\n\n  Result := Container.ElementByName['Type'].NativeValue;\nend;\n\nfunction wbPKDTFalloutBehaviorFlagsDecider(aBasePtr: Pointer; aEndPtr: Pointer; const aElement: IwbElement): Integer;\nvar\n  Container : IwbContainer;\n  SubRecord : IwbSubRecord;\nbegin\n  Result := 0;\n  if not Assigned(aElement) then Exit;\n  Container := GetContainerFromUnion(aElement);\n  if not Assigned(Container) then Exit;\n\n  if Supports(Container, IwbSubRecord, SubRecord) then\n    if SubRecord.SubRecordHeaderSize = 8 then\n      Result := 1;\nend;\n\nfunction wbPKDTSpecificFlagsDecider(aBasePtr: Pointer; aEndPtr: Pointer; const aElement: IwbElement): Integer;\nvar\n  Container : IwbContainer;\n  SubRecord : IwbSubRecord;\nbegin\n  Result := 0;\n  if not Assigned(aElement) then Exit;\n  Container := GetContainerFromUnion(aElement);\n  if not Assigned(Container) then Exit;\n\n  if Supports(Container, IwbSubRecord, SubRecord) then\n    if SubRecord.SubRecordHeaderSize = 8 then\n      Exit;\n  Result := Container.ElementByName['Type'].NativeValue + 1;\nend;\n\nprocedure wbIDLAsAfterSet(const aElement: IwbElement; const aOldValue, aNewValue: Variant);\nvar\n  Element         : IwbElement;\n  Container       : IwbContainer;\n  SelfAsContainer : IwbContainer;\nbegin\n  if wbBeginInternalEdit then try\n//    if not wbCounterAfterSet('IDLC - Animation Count', aElement) then\n      if Supports(aElement.Container, IwbContainer, Container) then begin\n        Element := Container.ElementByPath['IDLC\\Animation Count'];\n        if Assigned(Element) and Supports(aElement, IwbContainer, SelfAsContainer) and\n          (Element.GetNativeValue<>SelfAsContainer.GetElementCount) then\n          Element.SetNativeValue(SelfAsContainer.GetElementCount);\n      end;\n  finally\n    wbEndInternalEdit;\n  end;\nend;\n\nprocedure wbAnimationsAfterSet(const aElement: IwbElement; const aOldValue, aNewValue: Variant);\nvar\n  Element         : IwbElement;\n  Elems           : IwbElement;\n  Container       : IwbContainer;\nbegin\n  if wbBeginInternalEdit then try\n//    if not wbCounterContainerAfterSet('IDLC - Animation Count', 'IDLA - Animations', aElement) then\n      if Supports(aElement, IwbContainer, Container) then begin\n        Element := Container.ElementByPath['IDLC\\Animation Count'];\n        Elems   := Container.ElementByName['IDLA - Animations'];\n        if Assigned(Element) and not Assigned(Elems) then\n          if Element.GetNativeValue<>0 then\n            Element.SetNativeValue(0);\n      end;\n  finally\n    wbEndInternalEdit;\n  end;\nend;\n\nfunction wbOffsetDataColsCounter(aBasePtr: Pointer; aEndPtr: Pointer; const aElement: IwbElement): Cardinal;\nvar\n  Container : IwbDataContainer;\n  Element   : IwbElement;\n  fResult   : Extended;\nbegin\n  Result := 0;\n\n  if Supports(aElement.Container, IwbDataContainer, Container) and (Container.Name = 'OFST - Offset Data') and\n     Supports(Container.Container, IwbDataContainer, Container) then begin\n    Element := Container.ElementByPath['Object Bounds\\NAM0 - Min\\X'];\n    if Assigned(Element) then begin\n      fResult :=  Element.NativeValue;\n      if fResult >= MaxInt then\n        Result := 0\n      else\n        Result := Trunc(fResult);\n      Element := Container.ElementByPath['Object Bounds\\NAM9 - Max\\X'];\n      if Assigned(Element) then begin\n        fResult :=  Element.NativeValue;\n        if fResult >= MaxInt then\n          Result := 1\n        else\n          Result := Trunc(fResult) - Result + 1;\n      end;\n    end;\n  end;\nend;\n\nprocedure DefineFO3a;\nbegin\n  wbRecordFlags := wbInteger('Record Flags', itU32, wbFlags([\n    {0x00000001}'ESM',\n    {0x00000002}'',\n    {0x00000004}'',   // Plugin selected (Editor)\n    {0x00000008}'',   // Form cannot be saved (Runtime)/Plugin active (Editor)\n    {0x00000010}'Form initialized (Runtime only)',  // Plugin cannot be active or selected (Editor)\n    {0x00000020}'Deleted',\n    {0x00000040}'Border Region / Has Tree LOD / Constant / Hidden From Local Map',\n    {0x00000080}'Turn Off Fire',\n    {0x00000100}'Inaccessible',\n    {0x00000200}'Casts shadows / On Local Map / Motion Blur',\n    {0x00000400}'Quest item / Persistent reference',\n    {0x00000800}'Initially disabled',\n    {0x00001000}'Ignored',\n    {0x00002000}'No Voice Filter',\n    {0x00004000}'Cannot Save (Runtime only)',\n    {0x00008000}'Visible when distant',\n    {0x00010000}'Random Anim Start / High Priority LOD',\n    {0x00020000}'Dangerous / Off limits (Interior cell) / Radio Station (Talking Activator)',\n    {0x00040000}'Compressed',\n    {0x00080000}'Can''t wait / Platform Specific Texture / Dead',\n    {0x00100000}'Unknown 21',\n    {0x00200000}'Load Started', // set when beginning to load the form from save\n    {0x00400000}'Unknown 23',\n    {0x00800000}'Unknown 24',\n    {0x01000000}'Destructible (Runtime only)',\n    {0x02000000}'Obstacle / No AI Acquire',\n    {0x03000000}'NavMesh Generation - Filter',\n    {0x08000000}'NavMesh Generation - Bounding Box',\n    {0x10000000}'Non-Pipboy / Reflected by Auto Water',\n    {0x20000000}'Child Can Use / Refracted by Auto Water',\n    {0x40000000}'NavMesh Generation - Ground',\n    {0x80000000}'Multibound'\n  ]));\n\n(*   wbInteger('Record Flags 2', itU32, wbFlags([\n    {0x00000001}'Unknown 1',\n    {0x00000002}'Unknown 2',\n    {0x00000004}'Unknown 3',\n    {0x00000008}'Unknown 4',\n    {0x00000010}'Unknown 5',\n    {0x00000020}'Unknown 6',\n    {0x00000040}'Unknown 7',\n    {0x00000080}'Unknown 8',\n    {0x00000100}'Unknown 9',\n    {0x00000200}'Unknown 10',\n    {0x00000400}'Unknown 11',\n    {0x00000800}'Unknown 12',\n    {0x00001000}'Unknown 13',\n    {0x00002000}'Unknown 14',\n    {0x00004000}'Unknown 15',\n    {0x00008000}'Unknown 16',\n    {0x00010000}'Unknown 17',\n    {0x00020000}'Unknown 18',\n    {0x00040000}'Unknown 19',\n    {0x00080000}'Unknown 20',\n    {0x00100000}'Unknown 21',\n    {0x00200000}'Unknown 22',\n    {0x00400000}'Unknown 23',\n    {0x00800000}'Unknown 24',\n    {0x01000000}'Unknown 25',\n    {0x02000000}'Unknown 26',\n    {0x03000000}'Unknown 27',\n    {0x08000000}'Unknown 28',\n    {0x10000000}'Unknown 29',\n    {0x20000000}'Unknown 30',\n    {0x40000000}'Unknown 31',\n    {0x80000000}'Unknown 32'\n  ]));                (**)\n\n  wbMainRecordHeader := wbStruct('Record Header', [\n    wbString('Signature', 4, cpCritical),\n    wbInteger('Data Size', itU32, nil, cpIgnore),\n    wbRecordFlags,\n    wbFormID('FormID', cpFormID),\n    wbByteArray('Version Control Info 1', 4, cpIgnore),\n    wbInteger('Form Version', itU16, nil, cpIgnore),\n    wbByteArray('Version Control Info 2', 2, cpIgnore)\n  ]);\n\n  wbSizeOfMainRecordStruct := 24;\n\n  wbIgnoreRecords.Add(XXXX);\n\n  wbXRGD := wbByteArray(XRGD, 'Ragdoll Data');\n  wbXRGB := wbByteArray(XRGB, 'Ragdoll Biped Data');\n\n  wbMusicEnum := wbEnum(['Default', 'Public', 'Dungeon']);\n  wbSoundLevelEnum := wbEnum([\n     'Loud',\n     'Normal',\n     'Silent'\n    ]);\n\n  wbWeaponAnimTypeEnum := wbEnum([\n    {00} 'Hand to Hand',\n    {01} 'Melee (1 Hand)',\n    {02} 'Melee (2 Hand)',\n    {03} 'Pistol - Balistic (1 Hand)',\n    {04} 'Pistol - Energy (1 Hand)',\n    {05} 'Rifle - Balistic (2 Hand)',\n    {06} 'Rifle - Automatic (2 Hand)',\n    {07} 'Rifle - Energy (2 Hand)',\n    {08} 'Handle (2 Hand)',\n    {09} 'Launcher (2 Hand)',\n    {10} 'Grenade Throw (1 Hand)',\n    {11} 'Land Mine (1 Hand)',\n    {12} 'Mine Drop (1 Hand)'\n  ]);\n\n  wbReloadAnimEnum := wbEnum([\n    'ReloadA',\n    'ReloadB',\n    'ReloadC',\n    'ReloadD',\n    'ReloadE',\n    'ReloadF',\n    'ReloadG',\n    'ReloadH',\n    'ReloadI',\n    'ReloadJ',\n    'ReloadK'\n  ],[255, 'None']);\n\n  wbEDID := wbString(EDID, 'Editor ID', 0, cpNormal); // not cpBenign according to Arthmoor\n  wbEDIDReq := wbString(EDID, 'Editor ID', 0, cpNormal, True); // not cpBenign according to Arthmoor\n  wbFULL := wbString(FULL, 'Name', 0, cpTranslate);\n  wbFULLActor := wbString(FULL, 'Name', 0, cpTranslate, False, wbActorTemplateUseBaseData);\n  wbFULLReq := wbString(FULL, 'Name', 0, cpNormal, True);\n  wbDESC := wbString(DESC, 'Description', 0, cpTranslate);\n  wbDESCReq := wbString(DESC, 'Description', 0, cpTranslate, True);\n  wbXSCL := wbFloat(XSCL, 'Scale');\n  wbOBND := wbStruct(OBND, 'Object Bounds', [\n    wbInteger('X1', itS16),\n    wbInteger('Y1', itS16),\n    wbInteger('Z1', itS16),\n    wbInteger('X2', itS16),\n    wbInteger('Y2', itS16),\n    wbInteger('Z2', itS16)\n  ]);\n  wbOBNDReq := wbStruct(OBND, 'Object Bounds', [\n    wbInteger('X1', itS16),\n    wbInteger('Y1', itS16),\n    wbInteger('Z1', itS16),\n    wbInteger('X2', itS16),\n    wbInteger('Y2', itS16),\n    wbInteger('Z2', itS16)\n  ], cpNormal, True);\n  wbREPL := wbFormIDCkNoReach(REPL, 'Repair List', [FLST]);\n  wbEITM := wbFormIDCk(EITM, 'Object Effect', [ENCH, SPEL]);\n  wbBIPL := wbFormIDCk(BIPL, 'Biped Model List', [FLST]);\n  wbCOED := wbStructExSK(COED, [2], [0, 1], 'Extra Data', [\n    {00} wbFormIDCkNoReach('Owner', [NPC_, FACT, NULL]),\n    {04} wbUnion('Global Variable / Required Rank', wbCOEDOwnerDecider, [\n           wbByteArray('Unused', 4, cpIgnore),\n           wbFormIDCk('Global Variable', [GLOB, NULL]),\n           wbInteger('Required Rank', itU32)\n         ]),\n    {08} wbFloat('Item Condition')\n  ]);\n\n  wbYNAM := wbFormIDCk(YNAM, 'Sound - Pick Up', [SOUN]);\n  wbZNAM := wbFormIDCk(ZNAM, 'Sound - Drop', [SOUN]);\n\n  wbPosRot :=\n    wbStruct('Position/Rotation', [\n      wbStruct('Position', [\n        wbFloat('X'),\n        wbFloat('Y'),\n        wbFloat('Z')\n      ]),\n      wbStruct('Rotation', [\n        wbFloat('X', cpNormal, True, wbRotationFactor, wbRotationScale, nil, RadiansNormalize),\n        wbFloat('Y', cpNormal, True, wbRotationFactor, wbRotationScale, nil, RadiansNormalize),\n        wbFloat('Z', cpNormal, True, wbRotationFactor, wbRotationScale, nil, RadiansNormalize)\n      ])\n    ]);\n\n  wbDATAPosRot :=\n    wbStruct(DATA, 'Position/Rotation', [\n      wbStruct('Position', [\n        wbFloat('X'),\n        wbFloat('Y'),\n        wbFloat('Z')\n      ]),\n      wbStruct('Rotation', [\n        wbFloat('X', cpNormal, True, wbRotationFactor, wbRotationScale, nil, RadiansNormalize),\n        wbFloat('Y', cpNormal, True, wbRotationFactor, wbRotationScale, nil, RadiansNormalize),\n        wbFloat('Z', cpNormal, True, wbRotationFactor, wbRotationScale, nil, RadiansNormalize)\n      ])\n    ], cpNormal, True);\n\n  wbMODS :=\n    wbArrayS(MODS, 'Alternate Textures',\n      wbStructSK([0, 2], 'Alternate Texture', [\n        wbLenString('3D Name'),\n        wbFormIDCk('New Texture', [TXST]),\n        wbInteger('3D Index', itS32)\n      ]),\n    -1);\n  wbMO2S :=\n    wbArrayS(MO2S, 'Alternate Textures',\n      wbStructSK([0, 2], 'Alternate Texture', [\n        wbLenString('3D Name'),\n        wbFormIDCk('New Texture', [TXST]),\n        wbInteger('3D Index', itS32)\n      ]),\n    -1);\n  wbMO3S :=\n    wbArrayS(MO3S, 'Alternate Textures',\n      wbStructSK([0, 2], 'Alternate Texture', [\n        wbLenString('3D Name'),\n        wbFormIDCk('New Texture', [TXST]),\n        wbInteger('3D Index', itS32)\n      ]),\n    -1);\n  wbMO4S :=\n    wbArrayS(MO4S, 'Alternate Textures',\n      wbStructSK([0, 2], 'Alternate Texture', [\n        wbLenString('3D Name'),\n        wbFormIDCk('New Texture', [TXST]),\n        wbInteger('3D Index', itS32)\n      ]),\n    -1);\n\n  wbMODD :=\n    wbInteger(MODD, 'FaceGen Model Flags', itU8, wbFlags([\n      'Head',\n      'Torso',\n      'Right Hand',\n      'Left Hand'\n    ]));\n  wbMOSD :=\n    wbInteger(MOSD, 'FaceGen Model Flags', itU8, wbFlags([\n      'Head',\n      'Torso',\n      'Right Hand',\n      'Left Hand'\n    ]));\n\n  wbMODL :=\n    wbRStructSK([0], 'Model', [\n      wbString(MODL, 'Model Filename', 0, cpNormal, True),\n      wbByteArray(MODB, 'Unknown', 4, cpIgnore),\n      wbByteArray(MODT, 'Texture Files Hashes', 0, cpIgnore),\n//      wbArray(MODT, 'Texture Files Hashes',\n//        wbByteArray('Unknown', 24, cpBenign),\n//        wbArray('Hashes', wbInteger('Hash', itU64, wbMODTCallback), 3),\n//      0, nil, nil, cpBenign),\n      wbMODS,\n      wbMODD\n    ], [], cpNormal, False, nil, True);\n\n  wbMODLActor :=\n    wbRStructSK([0], 'Model', [\n      wbString(MODL, 'Model Filename', 0, cpNormal, True),\n      wbByteArray(MODB, 'Unknown', 4, cpIgnore),\n      wbByteArray(MODT, 'Texture Files Hashes', 0, cpIgnore),\n//      wbArray(MODT, 'Texture Files Hashes',\n//        wbByteArray('Unknown', 24, cpBenign),\n//        wbArray('Hashes', wbInteger('Hash', itU64, wbMODTCallback), 3),\n//      0, nil, nil, cpBenign),\n      wbMODS,\n      wbMODD\n    ], [], cpNormal, False, wbActorTemplateUseModelAnimation, True);\n\n  wbMODLReq :=\n    wbRStructSK([0], 'Model', [\n      wbString(MODL, 'Model Filename', 0, cpNormal, True),\n      wbByteArray(MODB, 'Unknown', 4, cpIgnore),\n      wbByteArray(MODT, 'Texture Files Hashes', 0, cpIgnore),\n//      wbArray(MODT, 'Texture Files',\n//        wbByteArray('Unknown', 24, cpBenign),\n//        wbArray('Hashes', wbInteger('Hash', itU64, wbMODTCallback), 3),\n//      0, nil, nil, cpBenign),\n      wbMODS,\n      wbMODD\n    ], [], cpNormal, True, nil, True);\n\n\n  wbDEST := wbRStruct('Destructable', [\n    wbStruct(DEST, 'Header', [\n      wbInteger('Health', itS32),\n      wbInteger('Count', itU8),\n      wbInteger('Flags', itU8, wbFlags([\n        'VATS Targetable'\n      ], True)),\n      wbByteArray('Unused', 2)\n    ]),\n    wbRArray('Stages',\n      wbRStruct('Stage', [\n        wbStruct(DSTD, 'Destruction Stage Data', [\n          wbInteger('Health %', itU8),\n          wbInteger('Index', itU8),\n          wbInteger('Damage Stage', itU8),\n          wbInteger('Flags', itU8, wbFlags([\n            'Cap Damage',\n            'Disable',\n            'Destroy'\n          ])),\n          wbInteger('Self Damage per Second', itS32),\n          wbFormIDCk('Explosion', [EXPL, NULL]),\n          wbFormIDCk('Debris', [DEBR, NULL]),\n          wbInteger('Debris Count', itS32)\n        ], cpNormal, True),\n        wbRStructSK([0], 'Model', [\n          wbString(DMDL, 'Model Filename'),\n          wbByteArray(DMDT, 'Texture Files Hashes', 0, cpIgnore)\n//          wbArray(DMDT, 'Unknown',\n//            wbByteArray('Unknown', 24, cpBenign),\n//          0, nil, nil, cpBenign)\n        ], []),\n        wbEmpty(DSTF, 'End Marker', cpNormal, True)\n      ], [])\n    )\n  ], []);\n\n  wbDESTActor := wbRStruct('Destructable', [\n    wbStruct(DEST, 'Header', [\n      wbInteger('Health', itS32),\n      wbInteger('Count', itU8),\n      wbInteger('Flags', itU8, wbFlags([\n        'VATS Targetable'\n      ])),\n      wbByteArray('Unused', 2)\n    ]),\n    wbRArray('Stages',\n      wbRStruct('Stage', [\n        wbStruct(DSTD, 'Destruction Stage Data', [\n          wbInteger('Health %', itU8),\n          wbInteger('Index', itU8),\n          wbInteger('Damage Stage', itU8),\n          wbInteger('Flags', itU8, wbFlags([\n            'Cap Damage',\n            'Disable',\n            'Destroy'\n          ])),\n          wbInteger('Self Damage per Second', itS32),\n          wbFormIDCk('Explosion', [EXPL, NULL]),\n          wbFormIDCk('Debris', [DEBR, NULL]),\n          wbInteger('Debris Count', itS32)\n        ], cpNormal, True),\n        wbRStructSK([0], 'Model', [\n          wbString(DMDL, 'Model Filename'),\n          wbByteArray(DMDT, 'Texture Files Hashes', 0, cpIgnore)\n//          wbArray(DMDT, 'Unknown',\n//            wbByteArray('Unknown', 24, cpBenign),\n//          0, nil, nil, cpBenign)\n        ], []),\n        wbEmpty(DSTF, 'End Marker', cpNormal, True)\n      ], [])\n    )\n  ], [], cpNormal, False, wbActorTemplateUseModelAnimation);\n\n  wbSCRI := wbFormIDCk(SCRI, 'Script', [SCPT]);\n  wbSCRIActor := wbFormIDCk(SCRI, 'Script', [SCPT], False, cpNormal, False, wbActorTemplateUseScript);\n  wbENAM := wbFormIDCk(ENAM, 'Object Effect', [ENCH]);\n\n  wbXLOD := wbArray(XLOD, 'Distant LOD Data', wbFloat('Unknown'), 3);\n\n  wbXESP := wbStruct(XESP, 'Enable Parent', [\n    wbFormIDCk('Reference', [PLYR, REFR, ACRE, ACHR, PGRE, PMIS, PBEA]),\n    wbInteger('Flags', itU8, wbFlags([\n      'Set Enable State to Opposite of Parent',\n      'Pop In'\n    ])),\n    wbByteArray('Unused', 3)\n  ]);\n\n  wbSCHRReq := wbStruct(SCHR, 'Basic Script Data', [\n    wbByteArray('Unused', 4),\n    wbInteger('RefCount', itU32),\n    wbInteger('CompiledSize', itU32),\n    wbInteger('VariableCount', itU32),\n    wbInteger('Type', itU16, wbEnum([\n      'Object',\n      'Quest'\n    ], [\n      $100, 'Effect'\n    ])),\n    wbInteger('Flags', itU16, wbFlags([\n      'Enabled'\n    ]), cpNormal, False, nil, nil, 1)\n  ], cpNormal, True);\n\n  wbSCROs :=\n    wbRArray('References',\n      wbRUnion('', [\n        wbFormID(SCRO, 'Global Reference'),\n//        wbFormIDCk(SCRO, 'Global Reference',\n//          [ACTI, DOOR, STAT, FURN, CREA, SPEL, NPC_, CONT, ARMO, AMMO, MISC, WEAP, IMAD,\n//           BOOK, KEYM, ALCH, LIGH, QUST, PLYR, PACK, LVLI, ECZN, EXPL, FLST, IDLM, PMIS,\n//           FACT, ACHR, REFR, ACRE, GLOB, DIAL, CELL, SOUN, MGEF, WTHR, CLAS, EFSH, RACE,\n//           LVLC, CSTY, WRLD, SCPT, IMGS, MESG, MSTT, MUSC, NOTE, PERK, PGRE, PROJ, LVLN,\n//           WATR, ENCH, TREE, TERM, HAIR, EYES, ADDN, NULL]),\n        wbInteger(SCRV, 'Local Variable', itU32)\n      ], [])\n    );\n\n  wbSLSD := wbStructSK(SLSD, [0], 'Local Variable Data', [\n    wbInteger('Index', itU32),\n    wbByteArray('Unused', 12),\n    wbInteger('Flags', itU8, wbFlags(['IsLongOrShort']), cpCritical),\n    wbByteArray('Unused', 7)\n  ]);\n\n  wbEmbeddedScript := wbRStruct('Embedded Script', [\n    wbSCHRReq,\n    wbByteArray(SCDA, 'Compiled Embedded Script', 0, cpNormal{, True}),\n    wbStringScript(SCTX, 'Embedded Script Source', 0, cpNormal{, True}),\n    wbRArrayS('Local Variables', wbRStructSK([0], 'Local Variable', [\n      wbSLSD,\n      wbString(SCVR, 'Name', 0, cpCritical, True)\n    ], [])),\n    wbSCROs\n  ], [], cpNormal, False, nil, False, wbEmbeddedScriptAfterLoad);\n\n  wbEmbeddedScriptPerk := wbRStruct('Embedded Script', [\n    wbSCHRReq,\n    wbByteArray(SCDA, 'Compiled Embedded Script', 0, cpNormal, True),\n    wbStringScript(SCTX, 'Embedded Script Source', 0, cpNormal, True),\n    wbRArrayS('Local Variables', wbRStructSK([0], 'Local Variable', [\n      wbSLSD,\n      wbString(SCVR, 'Name', 0, cpCritical, True)\n    ], [])),\n    wbSCROs\n  ], [], cpNormal, False, wbEPF2DontShow, False, wbEmbeddedScriptAfterLoad);\n\n  wbEmbeddedScriptReq := wbRStruct('Embedded Script', [\n    wbSCHRReq,\n    wbByteArray(SCDA, 'Compiled Embedded Script', 0, cpNormal{, True}),\n    wbStringScript(SCTX, 'Embedded Script Source', 0, cpNormal{, True}),\n    wbRArrayS('Local Variables', wbRStructSK([0], 'Local Variable', [\n      wbSLSD,\n      wbString(SCVR, 'Name', 0, cpCritical, True)\n    ], [])),\n    wbSCROs\n  ], [], cpNormal, True, nil, False, wbEmbeddedScriptAfterLoad);\n\n\n  wbXLCM := wbInteger(XLCM, 'Level Modifier', itS32);\n\n  wbRecord(ACHR, 'Placed NPC', [\n    wbEDID,\n    wbFormIDCk(NAME, 'Base', [NPC_], False, cpNormal, True),\n    wbFormIDCk(XEZN, 'Encounter Zone', [ECZN]),\n\n    {--- Ragdoll ---}\n    wbXRGD,\n    wbXRGB,\n\n    {--- Patrol Data ---}\n    wbRStruct('Patrol Data', [\n      wbFloat(XPRD, 'Idle Time', cpNormal, True),\n      wbEmpty(XPPA, 'Patrol Script Marker', cpNormal, True),\n      wbFormIDCk(INAM, 'Idle', [IDLE, NULL], False, cpNormal, True),\n      wbEmbeddedScriptReq,\n      wbFormIDCk(TNAM, 'Topic', [DIAL, NULL], False, cpNormal, True)\n    ], []),\n\n    {--- Leveled Actor ----}\n    wbXLCM,\n\n    {--- Merchant Container ----}\n    wbFormIDCk(XMRC, 'Merchant Container', [REFR], True),\n\n    {--- Extra ---}\n    wbInteger(XCNT, 'Count', itS32),\n    wbFloat(XRDS, 'Radius'),\n    wbFloat(XHLP, 'Health'),\n\n    {--- Decals ---}\n    wbRArrayS('Linked Decals',\n      wbStructSK(XDCR, [0], 'Decal', [\n        wbFormIDCk('Reference', [REFR]),\n        wbUnknown\n      ])\n    ),\n\n    {--- Linked Ref ---}\n    wbFormIDCk(XLKR, 'Linked Reference', [REFR, ACRE, ACHR, PGRE, PMIS, PBEA, PLYR]),\n    wbStruct(XCLP, 'Linked Reference Color', [\n      wbStruct('Link Start Color', [\n        wbInteger('Red', itU8),\n        wbInteger('Green', itU8),\n        wbInteger('Blue', itU8),\n        wbByteArray('Unused', 1)\n      ]),\n      wbStruct('Link End Color', [\n        wbInteger('Red', itU8),\n        wbInteger('Green', itU8),\n        wbInteger('Blue', itU8),\n        wbByteArray('Unused', 1)\n      ])\n    ]),\n\n    {--- Activate Parents ---}\n    wbRStruct('Activate Parents', [\n      wbInteger(XAPD, 'Flags', itU8, wbFlags([\n        'Parent Activate Only'\n      ], True)),\n      wbRArrayS('Activate Parent Refs',\n        wbStructSK(XAPR, [0], 'Activate Parent Ref', [\n          wbFormIDCk('Reference', [REFR, ACRE, ACHR, PGRE, PMIS, PBEA, PLYR]),\n          wbFloat('Delay')\n        ])\n      )\n    ], []),\n\n    {--- Enable Parent ---}\n    wbXESP,\n\n    {--- Emittance ---}\n    wbFormIDCk(XEMI, 'Emittance', [LIGH, REGN]),\n\n    {--- MultiBound ---}\n    wbFormIDCk(XMBR, 'MultiBound Reference', [REFR]),\n\n    {--- Flags ---}\n    wbEmpty(XIBS, 'Ignored By Sandbox'),\n\n    {--- 3D Data ---}\n    wbXSCL,\n    wbDATAPosRot\n  ], True, wbPlacedAddInfo);\n\n  wbXOWN := wbFormIDCkNoReach(XOWN, 'Owner', [FACT, ACHR, CREA, NPC_]); // Ghouls can own too aparently !\n  wbXGLB := wbFormIDCk(XGLB, 'Global variable', [GLOB]);\n\n  wbRecord(ACRE, 'Placed Creature', [\n    wbEDID,\n    wbFormIDCk(NAME, 'Base', [CREA], False, cpNormal, True),\n    wbFormIDCk(XEZN, 'Encounter Zone', [ECZN]),\n\n    wbXRGD,\n    wbXRGB,\n\n    {--- Patrol Data ---}\n    wbRStruct('Patrol Data', [\n      wbFloat(XPRD, 'Idle Time', cpNormal, True),\n      wbEmpty(XPPA, 'Patrol Script Marker', cpNormal, True),\n      wbFormIDCk(INAM, 'Idle', [IDLE, NULL], False, cpNormal, True),\n      wbEmbeddedScriptReq,\n      wbFormIDCk(TNAM, 'Topic', [DIAL, NULL], False, cpNormal, True)\n    ], []),\n\n    {--- Leveled Actor ----}\n    wbXLCM,\n\n    {--- Ownership ---}\n    wbRStruct('Ownership', [\n      wbXOWN,\n      wbInteger(XRNK, 'Faction rank', itS32)\n    ], [XCMT, XCMO]),\n\n    {--- Merchant Container ----}\n    wbFormIDCk(XMRC, 'Merchant Container', [REFR], True),\n\n    {--- Extra ---}\n    wbInteger(XCNT, 'Count', itS32),\n    wbFloat(XRDS, 'Radius'),\n    wbFloat(XHLP, 'Health'),\n\n    {--- Decals ---}\n    wbRArrayS('Linked Decals',\n      wbStructSK(XDCR, [0], 'Decal', [\n        wbFormIDCk('Reference', [REFR, ACRE, ACHR, PGRE, PMIS, PBEA]),\n        wbUnknown\n      ])\n    ),\n\n    {--- Linked Ref ---}\n    wbFormIDCk(XLKR, 'Linked Reference', [REFR, ACRE, ACHR, PGRE, PMIS, PBEA, PLYR]),\n    wbStruct(XCLP, 'Linked Reference Color', [\n      wbStruct('Link Start Color', [\n        wbInteger('Red', itU8),\n        wbInteger('Green', itU8),\n        wbInteger('Blue', itU8),\n        wbByteArray('Unused', 1)\n      ]),\n      wbStruct('Link End Color', [\n        wbInteger('Red', itU8),\n        wbInteger('Green', itU8),\n        wbInteger('Blue', itU8),\n        wbByteArray('Unused', 1)\n      ])\n    ]),\n\n    {--- Activate Parents ---}\n    wbRStruct('Activate Parents', [\n      wbInteger(XAPD, 'Flags', itU8, wbFlags([\n        'Parent Activate Only'\n      ], True)),\n      wbRArrayS('Activate Parent Refs',\n        wbStructSK(XAPR, [0], 'Activate Parent Ref', [\n          wbFormIDCk('Reference', [REFR, ACRE, ACHR, PGRE, PMIS, PBEA, PLYR]),\n          wbFloat('Delay')\n        ])\n      )\n    ], []),\n\n    {--- Enable Parent ---}\n    wbXESP,\n\n    {--- Emittance ---}\n    wbFormIDCk(XEMI, 'Emittance', [LIGH, REGN]),\n\n    {--- MultiBound ---}\n    wbFormIDCk(XMBR, 'MultiBound Reference', [REFR]),\n\n    {--- Flags ---}\n    wbEmpty(XIBS, 'Ignored By Sandbox'),\n\n    {--- 3D Data ---}\n    wbXSCL,\n    wbDATAPosRot\n  ], True, wbPlacedAddInfo);\n\n  wbRecord(ACTI, 'Activator', [\n    wbEDIDReq,\n    wbOBNDReq,\n    wbFULL,\n    wbMODL,\n    wbSCRI,\n    wbDEST,\n    wbFormIDCk(SNAM, 'Sound - Looping', [SOUN]),\n    wbFormIDCk(VNAM, 'Sound - Activation', [SOUN]),\n    wbFormIDCk(RNAM, 'Radio Station', [TACT]),\n    wbFormIDCk(WNAM, 'Water Type', [WATR])\n  ]);\n\n  wbICON := wbRStruct('Icon', [\n    wbString(ICON, 'Large Icon filename'),\n    wbString(MICO, 'Small Icon filename')\n  ], []);\n\n  wbICONReq := wbRStruct('Icon', [\n    wbString(ICON, 'Large Icon filename'),\n    wbString(MICO, 'Small Icon filename')\n  ], [], cpNormal, True);\n\n  wbVatsValueFunctionEnum :=\n    wbEnum([\n      'Weapon Is',\n      'Weapon In List',\n      'Target Is',\n      'Target In List',\n      'Target Distance',\n      'Target Part',\n      'VATS Action',\n      'Is Success',\n      'Is Critical',\n      'Critical Effect Is',\n      'Critical Effect In List',\n      'Is Fatal',\n      'Explode Part',\n      'Dismember Part',\n      'Cripple Part',\n      'Weapon Type Is',\n      'Is Stranger',\n      'Is Paralyzing Palm'\n    ]);\n\n  wbActorValueEnum :=\n    wbEnum([\n        {00} 'Aggresion',\n        {01} 'Confidence',\n        {02} 'Energy',\n        {03} 'Responsibility',\n        {04} 'Mood',\n        {05} 'Strength',\n        {06} 'Perception',\n        {07} 'Endurance',\n        {08} 'Charisma',\n        {09} 'Intelligence',\n        {10} 'Agility',\n        {11} 'Luck',\n        {12} 'Action Points',\n        {13} 'Carry Weight',\n        {14} 'Critical Chance',\n        {15} 'Heal Rate',\n        {16} 'Health',\n        {17} 'Melee Damage',\n        {18} 'Damage Resistance',\n        {19} 'Poison Resistance',\n        {20} 'Rad Resistance',\n        {21} 'Speed Multiplier',\n        {22} 'Fatigue',\n        {23} 'Karma',\n        {24} 'XP',\n        {25} 'Perception Condition',\n        {26} 'Endurance Condition',\n        {27} 'Left Attack Condition',\n        {28} 'Right Attack Condition',\n        {29} 'Left Mobility Condition',\n        {30} 'Right Mobility Condition',\n        {31} 'Brain Condition',\n        {32} 'Barter',\n        {33} 'Big Guns',\n        {34} 'Energy Weapons',\n        {35} 'Explosives',\n        {36} 'Lockpick',\n        {37} 'Medicine',\n        {38} 'Melee Weapons',\n        {39} 'Repair',\n        {40} 'Science',\n        {41} 'Small Guns',\n        {42} 'Sneak',\n        {43} 'Speech',\n        {44} 'Throwing (unused)',\n        {45} 'Unarmed',\n        {46} 'Inventory Weight',\n        {47} 'Paralysis',\n        {48} 'Invisibility',\n        {49} 'Chameleon',\n        {50} 'Night Eye',\n        {51} 'Detect Life Range',\n        {52} 'Fire Resistance',\n        {53} 'Water Breathing',\n        {54} 'Rad Level',\n        {55} 'Bloody Mess',\n        {56} 'Unarmed Damage',\n        {57} 'Assistance',\n        {58} 'Electric Resistance',\n        {59} 'Frost Resistance',\n        {60} 'Energy Resistance',\n        {61} 'EMP Resistance',\n        {62} 'Variable01',\n        {63} 'Variable02',\n        {64} 'Variable03',\n        {65} 'Variable04',\n        {66} 'Variable05',\n        {67} 'Variable06',\n        {68} 'Variable07',\n        {79} 'Variable08',\n        {70} 'Variable09',\n        {71} 'Variable10',\n        {72} 'Ignore Negative Effects'\n      ], [\n        -1, 'None'\n      ]);\n\n  wbSkillEnum :=\n    wbEnum([\n      'Barter',\n      'Big Guns',\n      'Energy Weapons',\n      'Explosives',\n      'Lockpick',\n      'Medicine',\n      'Melee Weapons',\n      'Repair',\n      'Science',\n      'Small Guns',\n      'Sneak',\n      'Speech',\n      'Throwing (unused)',\n      'Unarmed'\n    ], [\n      -1, 'None'\n    ]);\n\n  wbCrimeTypeEnum :=\n    wbEnum([\n      'Steal',\n      'Pickpocket',\n      'Trespass',\n      'Attack',\n      'Murder'\n    ], [\n      -1, 'None'\n    ]);\n\n  wbActorValue := wbInteger('Actor Value', itS32, wbActorValueEnum);\n\n  wbEquipTypeEnum :=\n    wbEnum([\n        {00} 'Big Guns',\n        {01} 'Energy Weapons',\n        {02} 'Small Guns',\n        {03} 'Melee Weapons',\n        {04} 'Unarmed Weapon',\n        {05} 'Thrown Weapons',\n        {06} 'Mine',\n        {07} 'Body Wear',\n        {08} 'Head Wear',\n        {09} 'Hand Wear',\n        {10} 'Chems',\n        {11} 'Stimpack',\n        {12} 'Food',\n        {13} 'Alcohol'\n      ], [\n        -1, 'None'\n      ]);\n\n  wbETYP := wbInteger(ETYP, 'Equiptment Type', itS32, wbEquipTypeEnum);\n  wbETYPReq := wbInteger(ETYP, 'Equiptment Type', itS32, wbEquipTypeEnum, cpNormal, True);\n\n  wbFormTypeEnum :=\n    wbEnum([], [\n      $04, 'Texture Set',\n      $05, 'Menu Icon',\n      $06, 'Global',\n      $07, 'Class',\n      $08, 'Faction',\n      $09, 'Head Part',\n      $0A, 'Hair',\n      $0B, 'Eyes',\n      $0C, 'Race',\n      $0D, 'Sound',\n      $0E, 'Acoustic Space',\n      $0F, 'Skill',\n      $10, 'Base Effect',\n      $11, 'Script',\n      $12, 'Landscape Texture',\n      $13, 'Object Effect',\n      $14, 'Actor Effect',\n      $15, 'Activator',\n      $16, 'Talking Activator',\n      $17, 'Terminal',\n      $18, 'Armor',\n      $19, 'Book',\n      $1A, 'Clothing',\n      $1B, 'Container',\n      $1C, 'Door',\n      $1D, 'Ingredient',\n      $1E, 'Light',\n      $1F, 'Misc',\n      $20, 'Static',\n      $21, 'Static Collection',\n      $22, 'Movable Static',\n      $23, 'Placeable Water',\n      $24, 'Grass',\n      $25, 'Tree',\n      $26, 'Flora',\n      $27, 'Furniture',\n      $28, 'Weapon',\n      $29, 'Ammo',\n      $2A, 'NPC',\n      $2B, 'Creature',\n      $2C, 'Leveled Creature',\n      $2D, 'Leveled NPC',\n      $2E, 'Key',\n      $2F, 'Ingestible',\n      $30, 'Idle Marker',\n      $31, 'Note',\n      $32, 'Constructible Object',\n      $33, 'Projectile',\n      $34, 'Leveled Item',\n      $35, 'Weather',\n      $36, 'Climate',\n      $37, 'Region',\n      $39, 'Cell',\n      $3A, 'Placed Object',\n      $3B, 'Placed Character',\n      $3C, 'Placed Creature',\n      $3E, 'Placed Grenade',\n      $41, 'Worldspace',\n      $42, 'Landscape',\n      $43, 'Navigation Mesh',\n      $45, 'Dialog Topic',\n      $46, 'Dialog Response',\n      $47, 'Quest',\n      $48, 'Idle Animation',\n      $49, 'Package',\n      $4A, 'Combat Style',\n      $4B, 'Load Screen',\n      $4C, 'Leveled Spell',\n      $4D, 'Animated Object',\n      $4E, 'Water',\n      $4F, 'Effect Shader',\n      $51, 'Explosion',\n      $52, 'Debris',\n      $53, 'Image Space',\n      $54, 'Image Space Modifier',\n      $55, 'FormID List',\n      $56, 'Perk',\n      $57, 'Body Part Data',\n      $58, 'Addon Node',\n      $59, 'Actor Value Info',\n      $5A, 'Radiation Stage',\n      $5B, 'Camera Shot',\n      $5C, 'Camera Path',\n      $5D, 'Voice Type',\n      $5E, 'Impact Data',\n      $5F, 'Impact DataSet',\n      $60, 'Armor Addon',\n      $61, 'Encounter Zone',\n      $62, 'Message',\n      $63, 'Ragdoll',\n      $64, 'Default Object Manager',\n      $65, 'Lighting Template',\n      $66, 'Music Type'\n  ]);\n\n  wbMenuModeEnum :=\n    wbEnum([],[\n      1, 'Type: Character Interface',\n      2, 'Type: Other',\n      3, 'Type: Console',\n      1001, 'Specific: Message',\n      1002, 'Specific: Inventory',\n      1003, 'Specific: Stats',\n      1004, 'Specific: HUDMainMenu',\n      1007, 'Specific: Loading',\n      1008, 'Specific: Container',\n      1009, 'Specific: Dialog',\n      1012, 'Specific: Sleep/Wait',\n      1013, 'Specific: Pause',\n      1014, 'Specific: LockPick',\n      1016, 'Specific: Quantity',\n      1027, 'Specific: Level Up',\n      1035, 'Specific: Pipboy Repair',\n      1036, 'Specific: Race / Sex',\n      1047, 'Specific: Credits',\n      1048, 'Specific: CharGen',\n      1051, 'Specific: TextEdit',\n      1053, 'Specific: Barter',\n      1054, 'Specific: Surgery',\n      1055, 'Specific: Hacking',\n      1056, 'Specific: VATS',\n      1057, 'Specific: Computers',\n      1058, 'Specific: Vendor Repair',\n      1059, 'Specific: Tutorial',\n      1060, 'Specific: You''re SPECIAL book'\n    ]);\nend;\n\nprocedure DefineFO3b;\nbegin\n  wbMiscStatEnum :=\n    wbEnum([\n      'Quests Completed',\n      'Locations Discovered',\n      'People Killed',\n      'Creatures Killed',\n      'Locks Picked',\n      'Computers Hacked',\n      'Stimpaks Taken',\n      'Rad-X Taken',\n      'RadAway Taken',\n      'Chems Taken',\n      'Times Addicted',\n      'Mines Disarmed',\n      'Speech Successes',\n      'Pockets Picked',\n      'Pants Exploded',\n      'Books Read',\n      'Bobbleheads Found',\n      'Weapons Created',\n      'People Mezzed',\n      'Captives Rescued',\n      'Sandman Kills',\n      'Paralyzing Punches',\n      'Robots Disabled',\n      'Contracts Completed',\n      'Corpses Eaten',\n      'Mysterious Stranger Visits'\n    ]);\n\n  wbAlignmentEnum :=\n    wbEnum([\n      'Good',\n      'Neutral',\n      'Evil',\n      'Very Good',\n      'Very Evil'\n    ]);\n\n  wbAxisEnum :=\n    wbEnum([], [\n      88, 'X',\n      89, 'Y',\n      90, 'Z'\n    ]);\n\n  wbCriticalStageEnum :=\n    wbEnum([\n      'None',\n      'Goo Start',\n      'Goo End',\n      'Disintegrate Start',\n      'Disintegrate End'\n    ]);\n\n  wbSexEnum :=\n    wbEnum(['Male','Female']);\n\n  wbCreatureTypeEnum :=\n    wbEnum([\n      'Animal',\n      'Mutated Animal',\n      'Mutated Insect',\n      'Abomination',\n      'Super Mutant',\n      'Feral Ghoul',\n      'Robot',\n      'Giant'\n    ]);\n\n  wbPlayerActionEnum :=\n    wbEnum([\n      '',\n      'Swinging Melee Weapon',\n      'Throwing Grenade',\n      'Fire Weapon',\n      'Lay Mine',\n      'Z Key Object',\n      'Jumping',\n      'Knocking over Objects',\n      'Stand on Table/Chair',\n      'Iron Sites',\n      'Destroying Object'\n    ]);\n\n  wbBodyLocationEnum :=\n    wbEnum([\n      'Torso',\n      'Head 1',\n      'Head 2',\n      'Left Arm 1',\n      'Left Arm 2',\n      'Right Arm 1',\n      'Right Arm 2',\n      'Left Leg 1',\n      'Left Leg 2',\n      'Left Leg 3',\n      'Right Leg 1',\n      'Right Leg 2',\n      'Right Leg 3',\n      'Brain'\n    ], [\n      -1, 'None'\n    ]);\n\n\n  wbEFID := wbFormIDCk(EFID, 'Base Effect', [MGEF]);\n\n  wbEFIT :=\n    wbStructSK(EFIT, [3, 4], '', [\n      wbInteger('Magnitude', itU32),\n      wbInteger('Area', itU32),\n      wbInteger('Duration', itU32),\n      wbInteger('Type', itU32, wbEnum(['Self', 'Touch', 'Target'])),\n      wbActorValue\n    ], cpNormal, True, nil, -1, wbEFITAfterLoad);\n\n  wbCTDA :=\n    wbStruct(CTDA, 'Condition', [\n      wbInteger('Type', itU8, wbCtdaTypeToStr, wbCtdaTypeToInt, cpNormal, False, nil, wbCtdaTypeAfterSet),\n      wbByteArray('Unused', 3),\n      wbUnion('Comparison Value', wbCTDACompValueDecider, [\n        wbFloat('Comparison Value - Float'),\n        wbFormIDCk('Comparison Value - Global', [GLOB])\n      ]),\n      wbInteger('Function', itU32, wbCTDAFunctionToStr, wbCTDAFunctionToInt),   // Limited to itu16\n      wbUnion('Parameter #1', wbCTDAParam1Decider, [\n        {00} wbByteArray('Unknown', 4),\n        {01} wbByteArray('None', 4, cpIgnore),\n        {02} wbInteger('Integer', itS32),\n        {03} wbInteger('Variable Name (INVALID)', itS32),\n        {04} wbInteger('Sex', itU32, wbSexEnum),\n        {05} wbInteger('Actor Value', itS32, wbActorValueEnum),\n        {06} wbInteger('Crime Type', itU32, wbCrimeTypeEnum),\n        {07} wbInteger('Axis', itU32, wbAxisEnum),\n        {08} wbInteger('Quest Stage (INVALID)', itS32),\n        {09} wbInteger('Misc Stat', itU32, wbMiscStatEnum),\n        {10} wbInteger('Alignment', itU32, wbAlignmentEnum),\n        {11} wbInteger('Equip Type', itU32, wbEquipTypeEnum),\n        {12} wbInteger('Form Type', itU32, wbFormTypeEnum),\n        {13} wbInteger('Critical Stage', itU32, wbCriticalStageEnum),\n        {14} wbFormIDCkNoReach('Object Reference', [PLYR, REFR, ACHR, ACRE, PGRE, PMIS, PBEA, TRGT], True),\n        {16} wbFormIDCkNoReach('Inventory Object', [ARMO, BOOK, MISC, WEAP, AMMO, KEYM, ALCH, NOTE, FLST]),\n        {17} wbFormIDCkNoReach('Actor', [PLYR, ACHR, ACRE, TRGT], True),\n        {18} wbFormIDCkNoReach('Voice Type', [VTYP]),\n        {19} wbFormIDCkNoReach('Idle', [IDLE]),\n        {20} wbFormIDCkNoReach('Form List', [FLST]),\n        {21} wbFormIDCkNoReach('Note', [NOTE]),\n        {22} wbFormIDCkNoReach('Quest', [QUST]),\n        {23} wbFormIDCkNoReach('Faction', [FACT]),\n        {24} wbFormIDCkNoReach('Weapon', [WEAP]),\n        {25} wbFormIDCkNoReach('Cell', [CELL]),\n        {26} wbFormIDCkNoReach('Class', [CLAS]),\n        {27} wbFormIDCkNoReach('Race', [RACE]),\n        {28} wbFormIDCkNoReach('Actor Base', [NPC_, CREA, ACTI, TACT]),\n        {29} wbFormIDCkNoReach('Global', [GLOB]),\n        {30} wbFormIDCkNoReach('Weather', [WTHR]),\n        {31} wbFormIDCkNoReach('Package', [PACK]),\n        {32} wbFormIDCkNoReach('Encounter Zone', [ECZN]),\n        {33} wbFormIDCkNoReach('Perk', [PERK]),\n        {34} wbFormIDCkNoReach('Owner', [FACT, NPC_]),\n        {35} wbFormIDCkNoReach('Furniture', [FURN, FLST]),\n        {36} wbFormIDCkNoReach('Effect Item', [SPEL, ENCH, ALCH, INGR]),\n        {37} wbFormIDCkNoReach('Base Effect', [MGEF]),\n        {38} wbFormIDCkNoReach('Worldspace', [WRLD]),\n        {39} wbInteger('VATS Value Function', itU32, wbVATSValueFunctionEnum),\n        {40} wbInteger('VATS Value Param (INVALID)', itU32),\n        {41} wbInteger('Creature Type', itU32, wbCreatureTypeEnum),\n        {42} wbInteger('Menu Mode', itU32, wbMenuModeEnum),\n        {43} wbInteger('Player Action', itU32, wbPlayerActionEnum),\n        {44} wbInteger('Body Location', itS32, wbBodyLocationEnum),\n        {45} wbFormIDCkNoReach('Referenceable Object', [CREA, NPC_, PROJ, TREE, SOUN, ACTI, DOOR, STAT, FURN, CONT, ARMO, AMMO, MISC, WEAP, BOOK, KEYM, ALCH, LIGH, GRAS, ASPC, IDLM, ARMA, MSTT, NOTE, PWAT, SCOL, TACT, TERM, FLST, LVLC, LVLN],\n                                                [CREA, NPC_, PROJ, TREE, SOUN, ACTI, DOOR, STAT, FURN, CONT, ARMO, AMMO, MISC, WEAP, BOOK, KEYM, ALCH, LIGH, GRAS, ASPC, IDLM, ARMA, MSTT, NOTE, PWAT, SCOL, TACT, TERM, LVLC, LVLN])\n      ]),\n      wbUnion('Parameter #2', wbCTDAParam2Decider, [\n        {00} wbByteArray('Unknown', 4),\n        {01} wbByteArray('None', 4, cpIgnore),\n        {02} wbInteger('Integer', itS32),\n        {03} wbInteger('Variable Name', itS32, wbCTDAParam2VariableNameToStr, wbCTDAParam2VariableNameToInt),\n        {04} wbInteger('Sex', itU32, wbSexEnum),\n        {05} wbInteger('Actor Value', itS32, wbActorValueEnum),\n        {06} wbInteger('Crime Type', itU32, wbCrimeTypeEnum),\n        {07} wbInteger('Axis', itU32, wbAxisEnum),\n        {08} wbInteger('Quest Stage', itS32, wbCTDAParam2QuestStageToStr, wbCTDAParam2QuestStageToInt),\n        {09} wbInteger('Misc Stat', itU32, wbMiscStatEnum),\n        {10} wbInteger('Alignment', itU32, wbAlignmentEnum),\n        {11} wbInteger('Equip Type', itU32, wbEquipTypeEnum),\n        {12} wbInteger('Form Type', itU32, wbFormTypeEnum),\n        {13} wbInteger('Critical Stage', itU32, wbCriticalStageEnum),\n        {14} wbFormIDCkNoReach('Object Reference', [PLYR, REFR, PMIS, PBEA, ACHR, ACRE, PGRE, TRGT], True),\n        {16} wbFormIDCkNoReach('Inventory Object', [ARMO, BOOK, MISC, WEAP, AMMO, KEYM, ALCH, NOTE, FLST]),\n        {17} wbFormIDCkNoReach('Actor', [PLYR, ACHR, ACRE, TRGT], True),\n        {18} wbFormIDCkNoReach('Voice Type', [VTYP]),\n        {19} wbFormIDCkNoReach('Idle', [IDLE]),\n        {20} wbFormIDCkNoReach('Form List', [FLST]),\n        {21} wbFormIDCkNoReach('Note', [NOTE]),\n        {22} wbFormIDCkNoReach('Quest', [QUST]),\n        {23} wbFormIDCkNoReach('Faction', [FACT]),\n        {24} wbFormIDCkNoReach('Weapon', [WEAP]),\n        {25} wbFormIDCkNoReach('Cell', [CELL]),\n        {26} wbFormIDCkNoReach('Class', [CLAS]),\n        {27} wbFormIDCkNoReach('Race', [RACE]),\n        {28} wbFormIDCkNoReach('Actor Base', [NPC_, CREA, ACTI, TACT]),\n        {29} wbFormIDCkNoReach('Global', [GLOB]),\n        {30} wbFormIDCkNoReach('Weather', [WTHR]),\n        {31} wbFormIDCkNoReach('Package', [PACK]),\n        {32} wbFormIDCkNoReach('Encounter Zone', [ECZN]),\n        {33} wbFormIDCkNoReach('Perk', [PERK]),\n        {34} wbFormIDCkNoReach('Owner', [FACT, NPC_]),\n        {35} wbFormIDCkNoReach('Furniture', [FURN, FLST]),\n        {36} wbFormIDCkNoReach('Effect Item', [SPEL, ENCH, ALCH, INGR]),\n        {37} wbFormIDCkNoReach('Base Effect', [MGEF]),\n        {38} wbFormIDCkNoReach('Worldspace', [WRLD]),\n        {39} wbInteger('VATS Value Function (INVALID)', itU32),\n        {40} wbUnion('VATS Value Param', wbCTDAParam2VATSValueParam, [\n               wbFormIDCkNoReach('Weapon', [WEAP]),\n               wbFormIDCkNoReach('Weapon List', [FLST], [WEAP]),\n               wbFormIDCkNoReach('Target', [NPC_, CREA]),\n               wbFormIDCkNoReach('Target List', [FLST], [NPC_, CREA]),\n               wbByteArray('Unused', 4, cpIgnore),\n               wbInteger('Target Part', itS32, wbActorValueEnum),\n               wbInteger('VATS Action', itU32, wbEnum([\n                 'Unarmed Attack',\n                 'One Hand Melee Attack',\n                 'Two Hand Melee Attack',\n                 'Fire Pistol',\n                 'Fire Rifle',\n                 'Fire Handle Weapon',\n                 'Fire Launcher',\n                 'Throw Grenade',\n                 'Place Mine',\n                 'Reload',\n                 'Crouch',\n                 'Stand',\n                 'Switch Weapon',\n                 'Toggle Weapon Drawn',\n                 'Heal',\n                 'Player Death'\n               ])),\n               wbByteArray('Unused', 4, cpIgnore),\n               wbByteArray('Unused', 4, cpIgnore),\n               wbFormIDCkNoReach('Critical Effect', [SPEL]),\n               wbFormIDCkNoReach('Critical Effect List', [FLST], [SPEL]),\n               wbByteArray('Unused', 4, cpIgnore),\n               wbByteArray('Unused', 4, cpIgnore),\n               wbByteArray('Unused', 4, cpIgnore),\n               wbByteArray('Unused', 4, cpIgnore),\n               wbInteger('Weapon Type', itU32, wbWeaponAnimTypeEnum),\n               wbByteArray('Unused', 4, cpIgnore),\n               wbByteArray('Unused', 4, cpIgnore)\n             ]),\n        {41} wbInteger('Creature Type', itU32, wbCreatureTypeEnum),\n        {42} wbInteger('Menu Mode', itU32, wbMenuModeEnum),\n        {43} wbInteger('Player Action', itU32, wbPlayerActionEnum),\n        {44} wbInteger('Body Location', itS32, wbBodyLocationEnum),\n        {45} wbFormIDCkNoReach('Referenceable Object', [CREA, NPC_, PROJ, TREE, SOUN, ACTI, DOOR, STAT, FURN, CONT, ARMO, AMMO, MISC, WEAP, BOOK, KEYM, ALCH, LIGH, GRAS, ASPC, IDLM, ARMA, MSTT, NOTE, PWAT, SCOL, TACT, TERM, FLST, LVLC, LVLN],\n                                                [CREA, NPC_, PROJ, TREE, SOUN, ACTI, DOOR, STAT, FURN, CONT, ARMO, AMMO, MISC, WEAP, BOOK, KEYM, ALCH, LIGH, GRAS, ASPC, IDLM, ARMA, MSTT, NOTE, PWAT, SCOL, TACT, TERM, LVLC, LVLN])\n      ]),\n      wbInteger('Run On', itU32, wbEnum([\n        'Subject',\n        'Target',\n        'Reference',\n        'Combat Target',\n        'Linked Reference'\n      ]), cpNormal, False, nil, wbCTDARunOnAfterSet),\n      wbUnion('Reference', wbCTDAReferenceDecider, [\n        wbInteger('Unused', itU32, nil, cpIgnore),\n        wbFormIDCkNoReach('Reference', [PLYR, ACHR, ACRE, REFR, PMIS, PBEA, PGRE], True)\n      ])\n    ], cpNormal, False, nil, 6, wbCTDAAfterLoad);\n  wbCTDAs := wbRArray('Conditions', wbCTDA);\n  wbCTDAsReq := wbRArray('Conditions', wbCTDA, cpNormal, True);\n\n  wbEffects :=\n    wbRStructs('Effects','Effect', [\n      wbEFID,\n      wbEFIT,\n      wbCTDAs\n    ], []);\n\n  wbEffectsReq :=\n    wbRStructs('Effects','Effect', [\n      wbEFID,\n      wbEFIT,\n      wbCTDAs\n    ], [], cpNormal, True);\n\n\n  wbRecord(ALCH, 'Ingestible', [\n    wbEDIDReq,\n    wbOBNDReq,\n    wbFULLReq,\n    wbMODL,\n    wbICON,\n    wbSCRI,\n    wbDEST,\n    wbYNAM,\n    wbZNAM,\n    wbETYPReq,\n    wbFloat(DATA, 'Weight', cpNormal, True),\n    wbStruct(ENIT, 'Effect Data', [\n      wbInteger('Value', itS32),\n      wbInteger('Flags?', itU8, wbFlags([\n        'No Auto-Calc (Unused)',\n        'Food Item',\n        'Medicine'\n      ])),\n      wbByteArray('Unused', 3),\n      wbFormIDCk('Withdrawal Effect', [SPEL, NULL]),\n      wbFloat('Addiction Chance'),\n      wbFormIDCk('Sound - Consume', [SOUN])\n    ], cpNormal, True),\n    wbEffectsReq\n  ]);\n\n  wbRecord(AMMO, 'Ammunition', [\n    wbEDIDReq,\n    wbOBNDReq,\n    wbFULLReq,\n    wbMODL,\n    wbICON,\n    wbDEST,\n    wbYNAM,\n    wbZNAM,\n    wbStruct(DATA, 'Data', [\n      wbFloat('Speed'),\n      wbInteger('Flags', itU8, wbFlags([\n        'Ignores Normal Weapon Resistance',\n        'Non-Playable'\n      ])),\n      wbByteArray('Unused', 3),\n      wbInteger('Value', itS32),\n      wbInteger('Clip Rounds', itU8)\n    ], cpNormal, True),\n    wbString(ONAM, 'Short Name')\n  ]);\n\n  wbRecord(ANIO, 'Animated Object', [\n    wbEDIDReq,\n    wbMODLReq,\n    wbFormIDCk(DATA, 'Animation', [IDLE], False, cpNormal, True)\n  ]);\n\n  wbBMDT := wbStruct(BMDT, 'Biped Data', [\n      wbInteger('Biped Flags', itU32, wbFlags([\n        {0x00000001} 'Head',\n        {0x00000002} 'Hair',\n        {0x00000004} 'Upper Body',\n        {0x00000008} 'Left Hand',\n        {0x00000010} 'Right Hand',\n        {0x00000020} 'Weapon',\n        {0x00000040} 'PipBoy',\n        {0x00000080} 'Backpack',\n        {0x00000100} 'Necklace',\n        {0x00000200} 'Headband',\n        {0x00000400} 'Hat',\n        {0x00000800} 'Eye Glasses',\n        {0x00001000} 'Nose Ring',\n        {0x00002000} 'Earrings',\n        {0x00004000} 'Mask',\n        {0x00008000} 'Choker',\n        {0x00010000} 'Mouth Object',\n        {0x00020000} 'Body AddOn 1',\n        {0x00040000} 'Body AddOn 2',\n        {0x00080000} 'Body AddOn 3'\n      ])),\n      wbInteger('General Flags', itU8, wbFlags([\n        {0x0001} '',\n        {0x0002} '',\n        {0x0004} '',\n        {0x0008} '',\n        {0x0010} '',\n        {0x0020} 'Power Armor',\n        {0x0040} 'Non-Playable',\n        {0x0080} 'Heavy'\n      ], True)),\n      wbByteArray('Unused', 3)\n    ], cpNormal, True);\n\n  wbRecord(ARMO, 'Armor', [\n    wbEDIDReq,\n    wbOBNDReq,\n    wbFULL,\n    wbSCRI,\n    wbEITM,\n    wbBMDT,\n    wbRStruct('Male biped model', [\n      wbString(MODL, 'Model Filename', 0, cpNormal, True),\n      wbByteArray(MODT, 'Texture Files Hashes', 0, cpIgnore),\n      wbMODS,\n      wbMODD\n    ], [], cpNormal, False, nil, True),\n    wbRStruct('Male world model', [\n      wbString(MOD2, 'Model Filename'),\n      wbByteArray(MO2T, 'Texture Files Hashes', 0, cpIgnore),\n      wbMO2S\n    ], []),\n    wbString(ICON, 'Male icon filename'),\n    wbString(MICO, 'Male mico filename'),\n    wbRStruct('Female biped model', [\n      wbString(MOD3, 'Model Filename', 0, cpNormal, True),\n      wbByteArray(MO3T, 'Texture Files Hashes', 0, cpIgnore),\n      wbMO3S,\n      wbMOSD\n    ], [], cpNormal, False, nil, True),\n    wbRStruct('Female world model', [\n      wbString(MOD4, 'Model Filename'),\n      wbByteArray(MO4T, 'Texture Files Hashes', 0, cpIgnore),\n      wbMO4S\n    ], []),\n    wbString(ICO2, 'Female icon filename'),\n    wbString(MIC2, 'Female mico filename'),\n    wbString(BMCT, 'Ragdoll Constraint Template'),\n    wbDEST,\n    wbREPL,\n    wbBIPL,\n    wbETYPReq,\n    wbYNAM,\n    wbZNAM,\n    wbStruct(DATA, 'Data', [\n      wbInteger('Value', itS32),\n      wbInteger('Max Condition', itS32),\n      wbFloat('Weight')\n    ], cpNormal, True),\n    wbStruct(DNAM, '', [\n      wbInteger('AR', itS16, wbDiv(100)),\n      wbInteger('Flags', itU16, wbFlags([\n        'Modulates Voice'\n      ]))\n    ], cpNormal, True)\n  ]);\n\n  wbRecord(ARMA, 'Armor Addon', [\n    wbEDIDReq,\n    wbOBNDReq,\n    wbFULL,\n    wbBMDT,\n    wbRStruct('Male biped model', [\n      wbString(MODL, 'Model Filename', 0, cpNormal, True),\n      wbByteArray(MODT, 'Texture Files Hashes', 0, cpIgnore),\n      wbMODS,\n      wbMODD\n    ], [], cpNormal, False, nil, True),\n    wbRStruct('Male world model', [\n      wbString(MOD2, 'Model Filename'),\n      wbByteArray(MO2T, 'Texture Files Hashes', 0, cpIgnore),\n      wbMO2S\n    ], []),\n    wbString(ICON, 'Male icon filename'),\n    wbString(MICO, 'Male mico filename'),\n    wbRStruct('Female biped model', [\n      wbString(MOD3, 'Model Filename', 0, cpNormal, True),\n      wbByteArray(MO3T, 'Texture Files Hashes', 0, cpIgnore),\n      wbMO3S,\n      wbMOSD\n    ], [], cpNormal, False, nil, True),\n    wbRStruct('Female world model', [\n      wbString(MOD4, 'Model Filename'),\n      wbByteArray(MO4T, 'Texture Files Hashes', 0, cpIgnore),\n      wbMO4S\n    ], []),\n    wbString(ICO2, 'Female icon filename'),\n    wbString(MIC2, 'Female mico filename'),\n    wbETYPReq,\n    wbStruct(DATA, 'Data', [\n      wbInteger('Value', itS32),\n      wbInteger('Max Condition', itS32),\n      wbFloat('Weight')\n    ], cpNormal, True),\n    wbStruct(DNAM, '', [\n      wbInteger('AR', itS16, wbDiv(100)),\n      wbInteger('Flags', itU16, wbFlags([\n        'Modulates Voice'\n      ]))\n    ], cpNormal, True)\n  ]);\n\n  wbRecord(BOOK, 'Book', [\n    wbEDIDReq,\n    wbOBNDReq,\n    wbFULL,\n    wbMODL,\n    wbICON,\n    wbSCRI,\n    wbDESCReq,\n    wbDEST,\n    wbYNAM,\n    wbZNAM,\n    wbStruct(DATA, 'Data', [\n      wbInteger('Flags', itU8, wbFlags([\n        '',\n        'Can''t be Taken'\n      ])),\n      wbInteger('Skill', itS8, wbSkillEnum),\n      wbInteger('Value', itS32),\n      wbFloat('Weight')\n    ], cpNormal, True)\n  ]);\n\n  wbSPLO := wbFormIDCk(SPLO, 'Actor Effect', [SPEL]);\n  wbSPLOs := wbRArrayS('Actor Effects', wbSPLO, cpNormal, False, nil, nil, wbActorTemplateUseActorEffectList);\n\n  wbRecord(CELL, 'Cell', [\n    wbEDID,\n    wbFULL,\n    wbInteger(DATA, 'Flags', itU8, wbFlags([\n      {0x01} 'Is Interior Cell',\n      {0x02} 'Has water',\n      {0x04} 'Invert Fast Travel behavior',\n      {0x08} 'No LOD Water',\n      {0x10} '',\n      {0x20} 'Public place',\n      {0x40} 'Hand changed',\n      {0x80} 'Behave like exterior'\n    ]), cpNormal, True),\n    wbStruct(XCLC, 'Grid', [\n      wbInteger('X', itS32),\n      wbInteger('Y', itS32),\n      wbInteger('Force Hide Land', itU32, wbFlags([\n        'Quad 1',\n        'Quad 2',\n        'Quad 3',\n        'Quad 4'\n      ], True))\n    ], cpNormal, False, nil, 2),\n    wbStruct(XCLL, 'Lighting', [\n      wbStruct('Ambient Color', [\n        wbInteger('Red', itU8),\n        wbInteger('Green', itU8),\n        wbInteger('Blue', itU8),\n        wbByteArray('Unused', 1)\n      ]),\n      wbStruct('Directional Color', [\n        wbInteger('Red', itU8),\n        wbInteger('Green', itU8),\n        wbInteger('Blue', itU8),\n        wbByteArray('Unused', 1)\n      ]),\n      wbStruct('Fog Color', [\n        wbInteger('Red', itU8),\n        wbInteger('Green', itU8),\n        wbInteger('Blue', itU8),\n        wbByteArray('Unused', 1)\n      ]),\n      wbFloat('Fog Near'),\n      wbFloat('Fog Far'),\n      wbInteger('Directional Rotation XY', itS32),\n      wbInteger('Directional Rotation Z', itS32),\n      wbFloat('Directional Fade'),\n      wbFloat('Fog Clip Dist'),\n      wbFloat('Fog Power')\n    ], cpNormal, False, nil, 7),\n    wbArray(IMPF, 'Footstep Materials', wbString('Unknown', 30), [\n      'ConcSolid',\n      'ConcBroken',\n      'MetalSolid',\n      'MetalHollow',\n      'MetalSheet',\n      'Wood',\n      'Sand',\n      'Dirt',\n      'Grass',\n      'Water'\n    ]),\n    wbRStruct('Light Template', [\n      wbFormIDCk(LTMP, 'Template', [LGTM, NULL]),\n      wbInteger(LNAM, 'Inherit', itU32, wbFlags([\n        {0x00000001}'Ambient Color',\n        {0x00000002}'Directional Color',\n        {0x00000004}'Fog Color',\n        {0x00000008}'Fog Near',\n        {0x00000010}'Fog Far',\n        {0x00000020}'Directional Rotation',\n        {0x00000040}'Directional Fade',\n        {0x00000080}'Clip Distance',\n        {0x00000100}'Fog Power'\n      ]), cpNormal, True)\n    ], [], cpNormal, True ),\n    wbFloat(XCLW, 'Water Height'),\n    wbString(XNAM, 'Water Noise Texture'),\n    wbArrayS(XCLR, 'Regions', wbFormIDCk('Region', [REGN])),\n    wbFormIDCk(XCIM, 'Image Space', [IMGS]),\n    wbByteArray(XCET, 'Unknown', 1, cpIgnore),\n    wbFormIDCk(XEZN, 'Encounter Zone', [ECZN]),\n    wbFormIDCk(XCCM, 'Climate', [CLMT]),\n    wbFormIDCk(XCWT, 'Water', [WATR]),\n    wbRStruct('Ownership', [\n      wbXOWN,\n      wbInteger(XRNK, 'Faction rank', itS32)\n    ], [XCMT, XCMO]),\n    wbFormIDCk(XCAS, 'Acoustic Space', [ASPC]),\n    wbByteArray(XCMT, 'Unused', 1, cpIgnore),\n    wbFormIDCk(XCMO, 'Music Type', [MUSC])\n  ], True, wbCellAddInfo, cpNormal, False, wbCELLAfterLoad);\n\n  wbServiceFlags :=\n    wbFlags([\n      {0x00000001} 'Weapons',\n      {0x00000002} 'Armor',\n      {0x00000004} 'Alcohol',\n      {0x00000008} 'Books',\n      {0x00000010} 'Food',\n      {0x00000020} 'Chems',\n      {0x00000040} 'Stimpacks',\n      {0x00000080} 'Lights?',\n      {0x00000100} '',\n      {0x00000200} '',\n      {0x00000400} 'Miscellaneous',\n      {0x00000800} '',\n      {0x00001000} '',\n      {0x00002000} 'Potions?',\n      {0x00004000} 'Training',\n      {0x00008000} '',\n      {0x00010000} 'Recharge',\n      {0x00020000} 'Repair'\n    ]);\n\n  wbSpecializationEnum := wbEnum(['Combat', 'Magic', 'Stealth']);\n\n  wbRecord(CLAS, 'Class', [\n    wbEDIDReq,\n    wbFULLReq,\n    wbDESCReq,\n    wbICON,\n    wbStruct(DATA, '', [\n      wbArray('Tag Skills', wbInteger('Tag Skill', itS32, wbActorValueEnum), 4),\n      wbInteger('Flags', itU32, wbFlags(['Playable', 'Guard'], True)),\n      wbInteger('Buys/Sells and Services', itU32, wbServiceFlags),\n      wbInteger('Teaches', itS8, wbSkillEnum),\n      wbInteger('Maximum training level', itU8),\n      wbByteArray('Unused', 2)\n    ], cpNormal, True),\n    wbArray(ATTR, 'Attributes', wbInteger('Attribute', itU8), [\n      'Strength',\n      'Perception',\n      'Endurance',\n      'Charisma',\n      'Intelligence',\n      'Agility',\n      'Luck'\n    ], cpNormal, True)\n  ]);\nend;\n\nprocedure DefineFO3c;\nbegin\n  wbRecord(CLMT, 'Climate', [\n    wbEDIDReq,\n    wbArrayS(WLST, 'Weather Types', wbStructSK([0], 'Weather Type', [\n      wbFormIDCk('Weather', [WTHR, NULL]),\n      wbInteger('Chance', itS32),\n      wbFormIDCk('Global', [GLOB, NULL])\n    ])),\n    wbString(FNAM, 'Sun Texture'),\n    wbString(GNAM, 'Sun Glare Texture'),\n    wbMODL,\n    wbStruct(TNAM, 'Timing', [\n      wbStruct('Sunrise', [\n        wbInteger('Begin', itU8, wbClmtTime),\n        wbInteger('End', itU8, wbClmtTime)\n      ]),\n      wbStruct('Sunset', [\n        wbInteger('Begin', itU8, wbClmtTime),\n        wbInteger('End', itU8, wbClmtTime)\n      ]),\n      wbInteger('Volatility', itU8),\n      wbInteger('Moons / Phase Length', itU8, wbClmtMoonsPhaseLength)\n    ], cpNormal, True)\n  ]);\n\n  wbCNTO :=\n    wbRStructExSK([0], [1], 'Item', [\n      wbStructExSK(CNTO, [0], [1], 'Item', [\n        wbFormIDCk('Item', [ARMO, AMMO, MISC, WEAP, BOOK, LVLI, KEYM, ALCH, NOTE, MSTT{?}, STAT{?}]),\n        wbInteger('Count', itS32)\n      ]),\n      wbCOED\n    ], []);\n\n  wbCNTOs := wbRArrayS('Items', wbCNTO);\n\n  wbRecord(CONT, 'Container', [\n    wbEDIDReq,\n    wbOBNDReq,\n    wbFULL,\n    wbMODL,\n    wbSCRI,\n    wbCNTOs,\n    wbDEST,\n    wbStruct(DATA, '', [\n      wbInteger('Flags', itU8, wbFlags(['', 'Respawns'])),\n      wbFloat('Weight')\n    ], cpNormal, True),\n    wbFormIDCk(SNAM, 'Sound - Open', [SOUN]),\n    wbFormIDCk(QNAM, 'Sound - Close', [SOUN])\n  ], True);\n\n  wbCSDT := wbRStructSK([0], 'Sound Type', [\n    wbInteger(CSDT, 'Type', itU32,wbEnum([\n      {0x00} 'Left Foot',\n      {0x01} 'Right Foot',\n      {0x02} 'Left Back Foot',\n      {0x03} 'Right Back Foot',\n      {0x04} 'Idle',\n      {0x05} 'Aware',\n      {0x06} 'Attack',\n      {0x07} 'Hit',\n      {0x08} 'Death',\n      {0x09} 'Weapon',\n      {0x0A} 'Movement',\n      {0x0B} 'Conscious'\n    ])),\n    wbRArrayS('Sounds', wbRStructSK([0], 'Sound', [\n      wbFormIDCk(CSDI, 'Sound', [SOUN], False, cpNormal, True),\n      wbInteger(CSDC, 'Sound Chance', itU8, nil, cpNormal, True)\n    ], []), cpNormal, True)\n  ], []);\n\n  wbCSDTs := wbRArrayS('Sound Types', wbCSDT, cpNormal, False, nil, nil, wbActorTemplateUseModelAnimation);\n\n  wbAgressionEnum := wbEnum([\n    'Unaggressive',\n    'Aggressive',\n    'Very Aggressive',\n    'Frenzied'\n  ]);\n\n  wbConfidenceEnum := wbEnum([\n    'Cowardly',\n    'Cautious',\n    'Average',\n    'Brave',\n    'Foolhardy'\n  ]);\n\n  wbMoodEnum := wbEnum([\n    'Neutral',\n    'Afraid',\n    'Annoyed',\n    'Cocky',\n    'Drugged',\n    'Pleasant',\n    'Angry',\n    'Sad'\n  ]);\n\n  wbAssistanceEnum := wbEnum([\n    'Helps Nobody',\n    'Helps Allies',\n    'Helps Friends and Allies'\n  ]);\n\n  wbAggroRadiusFlags := wbFlags([\n    'Aggro Radius Behavior'\n  ]);\n\n  wbAIDT :=\n    wbStruct(AIDT, 'AI Data', [\n     {00} wbInteger('Aggression', itU8, wbAgressionEnum),\n     {01} wbInteger('Confidence', itU8, wbConfidenceEnum),\n     {02} wbInteger('Energy Level', itU8),\n     {03} wbInteger('Responsibility', itU8),\n     {04} wbInteger('Mood', itU8, wbMoodEnum),\n          wbByteArray('Unused', 3),\n     {08} wbInteger('Buys/Sells and Services', itU32, wbServiceFlags),\n     {0C} wbInteger('Teaches', itS8, wbSkillEnum),\n     {0D} wbInteger('Maximum training level', itU8),\n     {0E} wbInteger('Assistance', itS8, wbAssistanceEnum),\n     {0F} wbInteger('Aggro Radius Behavior', itU8, wbAggroRadiusFlags),\n     {10} wbInteger('Aggro Radius', itS32)\n    ], cpNormal, True, wbActorTemplateUseAIData);\n\n  wbAttackAnimationEnum :=\n    wbEnum([\n    ], [\n       26, 'AttackLeft',\n       27, 'AttackLeftUp',\n       28, 'AttackLeftDown',\n       29, 'AttackLeftIS',\n       30, 'AttackLeftISUp',\n       31, 'AttackLeftISDown',\n       32, 'AttackRight',\n       33, 'AttackRightUp',\n       34, 'AttackRightDown',\n       35, 'AttackRightIS',\n       36, 'AttackRightISUp',\n       37, 'AttackRightISDown',\n       38, 'Attack3',\n       39, 'Attack3Up',\n       40, 'Attack3Down',\n       41, 'Attack3IS',\n       42, 'Attack3ISUp',\n       43, 'Attack3ISDown',\n       44, 'Attack4',\n       45, 'Attack4Up',\n       46, 'Attack4Down',\n       47, 'Attack4IS',\n       48, 'Attack4ISUp',\n       49, 'Attack4ISDown',\n       50, 'Attack5',\n       51, 'Attack5Up',\n       52, 'Attack5Down',\n       53, 'Attack5IS',\n       54, 'Attack5ISUp',\n       55, 'Attack5ISDown',\n       56, 'Attack6',\n       57, 'Attack6Up',\n       58, 'Attack6Down',\n       59, 'Attack6IS',\n       60, 'Attack6ISUp',\n       61, 'Attack6ISDown',\n       62, 'Attack7',\n       63, 'Attack7Up',\n       64, 'Attack7Down',\n       65, 'Attack7IS',\n       66, 'Attack7ISUp',\n       67, 'Attack7ISDown',\n       68, 'Attack8',\n       69, 'Attack8Up',\n       70, 'Attack8Down',\n       71, 'Attack8IS',\n       72, 'Attack8ISUp',\n       73, 'Attack8ISDown',\n       74, 'AttackLoop',\n       75, 'AttackLoopUp',\n       76, 'AttackLoopDown',\n       77, 'AttackLoopIS',\n       78, 'AttackLoopISUp',\n       79, 'AttackLoopISDown',\n       80, 'AttackSpin',\n       81, 'AttackSpinUp',\n       82, 'AttackSpinDown',\n       83, 'AttackSpinIS',\n       84, 'AttackSpinISUp',\n       85, 'AttackSpinISDown',\n       86, 'AttackSpin2',\n       87, 'AttackSpin2Up',\n       88, 'AttackSpin2Down',\n       89, 'AttackSpin2IS',\n       90, 'AttackSpin2ISUp',\n       91, 'AttackSpin2ISDown',\n       92, 'AttackPower',\n       93, 'AttackForwardPower',\n       94, 'AttackBackPower',\n       95, 'AttackLeftPower',\n       96, 'AttackRightPower',\n       97, 'PlaceMine',\n       98, 'PlaceMineUp',\n       99, 'PlaceMineDown',\n      100, 'PlaceMineIS',\n      101, 'PlaceMineISUp',\n      102, 'PlaceMineISDown',\n      103, 'PlaceMine2',\n      104, 'PlaceMine2Up',\n      105, 'PlaceMine2Down',\n      106, 'PlaceMine2IS',\n      107, 'PlaceMine2ISUp',\n      108, 'PlaceMine2ISDown',\n      109, 'AttackThrow',\n      110, 'AttackThrowUp',\n      111, 'AttackThrowDown',\n      112, 'AttackThrowIS',\n      113, 'AttackThrowISUp',\n      114, 'AttackThrowISDown',\n      115, 'AttackThrow2',\n      116, 'AttackThrow2Up',\n      117, 'AttackThrow2Down',\n      118, 'AttackThrow2IS',\n      119, 'AttackThrow2ISUp',\n      120, 'AttackThrow2ISDown',\n      121, 'AttackThrow3',\n      122, 'AttackThrow3Up',\n      123, 'AttackThrow3Down',\n      124, 'AttackThrow3IS',\n      125, 'AttackThrow3ISUp',\n      126, 'AttackThrow3ISDown',\n      127, 'AttackThrow4',\n      128, 'AttackThrow4Up',\n      129, 'AttackThrow4Down',\n      130, 'AttackThrow4IS',\n      131, 'AttackThrow4ISUp',\n      132, 'AttackThrow4ISDown',\n      133, 'AttackThrow5',\n      134, 'AttackThrow5Up',\n      135, 'AttackThrow5Down',\n      136, 'AttackThrow5IS',\n      137, 'AttackThrow5ISUp',\n      138, 'AttackThrow5ISDown',\n\n      167, 'PipBoy',\n      178, 'PipBoyChild',\n\n      255, ' ANY'\n    ]);\n\n  wbImpactMaterialTypeEnum :=\n    wbEnum([\n      'Stone',\n      'Dirt',\n      'Grass',\n      'Glass',\n      'Metal',\n      'Wood',\n      'Organic',\n      'Cloth',\n      'Water',\n      'Hollow Metal',\n      'Organic Bug',\n      'Organic Glow'\n    ]);\n\n  wbTemplateFlags := wbFlags([\n    'Use Traits',\n    'Use Stats',\n    'Use Factions',\n    'Use Actor Effect List',\n    'Use AI Data',\n    'Use AI Packages',\n    'Use Model/Animation',\n    'Use Base Data',\n    'Use Inventory',\n    'Use Script'\n  ]);\n\n  wbRecord(CREA, 'Creature', [\n    wbEDIDReq,\n    wbOBNDReq,\n    wbFULLActor,\n    wbMODLActor,\n    wbSPLOs,\n    wbFormIDCk(EITM, 'Unarmed Attack Effect', [ENCH, SPEL], False, cpNormal, False, wbActorTemplateUseActorEffectList),\n    wbInteger(EAMT, 'Unarmed Attack Animation', itU16, wbAttackAnimationEnum, cpNormal, True, False, wbActorTemplateUseActorEffectList),\n    wbArrayS(NIFZ, 'Model List', wbStringLC('Model'), 0, cpNormal, False, nil, nil, wbActorTemplateUseModelAnimation),\n    wbByteArray(NIFT, 'Texture Files Hashes', 0, cpIgnore, False, False, wbActorTemplateUseModelAnimation),\n    wbStruct(ACBS, 'Configuration', [\n      {00} wbInteger('Flags', itU32, wbFlags([\n             {0x000001} 'Biped',\n             {0x000002} 'Essential',\n             {0x000004} 'Weapon & Shield?',\n             {0x000008} 'Respawn',\n             {0x000010} 'Swims',\n             {0x000020} 'Flies',\n             {0x000040} 'Walks',\n             {0x000080} 'PC Level Mult',\n             {0x000100} 'Unknown 8',\n             {0x000200} 'No Low Level Processing',\n             {0x000400} '',\n             {0x000800} 'No Blood Spray',\n             {0x001000} 'No Blood Decal',\n             {0x002000} '',\n             {0x004000} '',\n             {0x008000} 'No Head',\n             {0x010000} 'No Right Arm',\n             {0x020000} 'No Left Arm',\n             {0x040000} 'No Combat in Water',\n             {0x080000} 'No Shadow',\n             {0x100000} 'No VATS Melee',\n           {0x00200000} 'Allow PC Dialogue',\n           {0x00400000} 'Can''t Open Doors',\n           {0x00800000} 'Immobile',\n           {0x01000000} 'Tilt Front/Back',\n           {0x02000000} 'Tilt Left/Right',\n           {0x03000000} 'No Knockdowns',\n           {0x08000000} 'Not Pushable',\n           {0x10000000} 'Allow Pickpocket',\n           {0x20000000} 'Is Ghost',\n           {0x40000000} 'No Rotating To Head-track',\n           {0x80000000} 'Invulnerable'\n           ], [\n             {0x000001 Biped} wbActorTemplateUseModelAnimation,\n             {0x000002 Essential} wbActorTemplateUseBaseData,\n             {0x000004 Weapon & Shield} nil,\n             {0x000008 Respawn} wbActorTemplateUseBaseData,\n             {0x000010 Swims} wbActorTemplateUseModelAnimation,\n             {0x000020 Flies} wbActorTemplateUseModelAnimation,\n             {0x000040 Walks} wbActorTemplateUseModelAnimation,\n             {0x000080 PC Level Mult} wbActorTemplateUseStats,\n             {0x000100 Unknown 8} nil,\n             {0x000200 No Low Level Processing} wbActorTemplateUseBaseData,\n             {0x000400 } nil,\n             {0x000800 No Blood Spray} wbActorTemplateUseModelAnimation,\n             {0x001000 No Blood Decal} wbActorTemplateUseModelAnimation,\n             {0x002000 } nil,\n             {0x004000 } nil,\n             {0x008000 No Head} wbActorTemplateUseModelAnimation,\n             {0x010000 No Right Arm} wbActorTemplateUseModelAnimation,\n             {0x020000 No Left Arm} wbActorTemplateUseModelAnimation,\n             {0x040000 No Combat in Water} wbActorTemplateUseModelAnimation,\n             {0x080000 No Shadow} wbActorTemplateUseModelAnimation,\n             {0x100000 No VATS Melee} nil,\n           {0x00200000 Allow PC Dialogue} wbActorTemplateUseBaseData,\n           {0x00400000 Can''t Open Doors} wbActorTemplateUseBaseData,\n           {0x00800000 Immobile} wbActorTemplateUseModelAnimation,\n           {0x01000000 Tilt Front/Back} wbActorTemplateUseModelAnimation,\n           {0x02000000 Tilt Left/Right} wbActorTemplateUseModelAnimation,\n           {0x03000000 No Knockdowns} nil,\n           {0x08000000 Not Pushable} wbActorTemplateUseModelAnimation,\n           {0x10000000 Allow Pickpocket} wbActorTemplateUseBaseData,\n           {0x20000000 Is Ghost} nil,\n           {0x40000000 No Rotating To Head-track} wbActorTemplateUseModelAnimation,\n           {0x80000000 Invulnerable} nil\n           ])),\n      {04} wbInteger('Fatigue', itU16, nil, cpNormal, False, wbActorTemplateUseStats),\n      {06} wbInteger('Barter gold', itU16, nil, cpNormal, False, wbActorTemplateUseAIData),\n      {08} wbUnion('Level', wbCreaLevelDecider, [\n             wbInteger('Level', itS16, nil, cpNormal, False, wbActorTemplateUseStats),\n             wbInteger('Level Mult', itS16, wbDiv(1000), cpNormal, False, wbActorTemplateUseStats)\n           ], cpNormal, False, wbActorTemplateUseStats),\n      {10} wbInteger('Calc min', itU16, nil, cpNormal, False, wbActorTemplateUseStats),\n      {12} wbInteger('Calc max', itU16, nil, cpNormal, False, wbActorTemplateUseStats),\n      {14} wbInteger('Speed Multiplier', itU16, nil, cpNormal, False, wbActorTemplateUseStats),\n      {16} wbFloat('Karma (Alignment)', cpNormal, False, 1, -1, wbActorTemplateUseTraits),\n      {20} wbInteger('Disposition Base', itS16, nil, cpNormal, False, wbActorTemplateUseTraits),\n      {22} wbInteger('Template Flags', itU16, wbTemplateFlags)\n    ], cpNormal, True),\n    wbRArrayS('Factions',\n      wbStructSK(SNAM, [0], 'Faction', [\n        wbFormIDCk('Faction', [FACT]),\n        wbInteger('Rank', itU8),\n        wbByteArray('Unused', 3)\n      ]),\n    cpNormal, False, nil, nil, wbActorTemplateUseFactions),\n    wbFormIDCk(INAM, 'Death item', [LVLI], False, cpNormal, False, wbActorTemplateUseTraits),\n    wbFormIDCk(VTCK, 'Voice', [VTYP], False, cpNormal, False, wbActorTemplateUseTraits),\n    wbFormIDCk(TPLT, 'Template', [CREA, LVLC]),\n    wbDESTActor,\n    wbSCRIActor,\n    wbRArrayS('Items', wbCNTO, cpNormal, False, nil, nil, wbActorTemplateUseInventory),\n    wbAIDT,\n    wbRArray('Packages', wbFormIDCk(PKID, 'Package', [PACK]), cpNormal, False, nil, nil, wbActorTemplateUseAIPackages),\n    wbArrayS(KFFZ, 'Animations', wbStringLC('Animation'), 0, cpNormal, False, nil, nil, wbActorTemplateUseModelAnimation),\n    wbStruct(DATA, '', [\n      {00} wbInteger('Type', itU8, wbCreatureTypeEnum, cpNormal, False, wbActorTemplateUseTraits),\n      {01} wbInteger('Combat Skill', itU8, nil, cpNormal, False, wbActorTemplateUseStats),\n      {02} wbInteger('Magic Skill', itU8, nil, cpNormal, False, wbActorTemplateUseStats),\n      {03} wbInteger('Stealth Skill', itU8, nil, cpNormal, False, wbActorTemplateUseStats),\n      {04} wbInteger('Health', itS16, nil, cpNormal, False, wbActorTemplateUseStats),\n      {06} wbByteArray('Unused', 2),\n      {08} wbInteger('Damage', itS16, nil, cpNormal, False, wbActorTemplateUseStats),\n      {10} wbArray('Attributes', wbInteger('Attribute', itU8), [\n            'Strength',\n            'Perception',\n            'Endurance',\n            'Charisma',\n            'Intelligence',\n            'Agility',\n            'Luck'\n          ], cpNormal, False, wbActorTemplateUseStats)\n    ], cpNormal, True),\n    wbInteger(RNAM, 'Attack reach', itU8, nil, cpNormal, True, False, wbActorTemplateUseTraits),\n    wbFormIDCk(ZNAM, 'Combat Style', [CSTY], False, cpNormal, False, wbActorTemplateUseTraits),\n    wbFormIDCk(PNAM, 'Body Part Data', [BPTD], False, cpNormal, True, wbActorTemplateUseModelAnimation),\n    wbFloat(TNAM, 'Turning Speed', cpNormal, True, 1, -1, wbActorTemplateUseStats),\n    wbFloat(BNAM, 'Base Scale', cpNormal, True, 1, -1, wbActorTemplateUseStats),\n    wbFloat(WNAM, 'Foot Weight', cpNormal, True, 1, -1, wbActorTemplateUseStats),\n    wbInteger(NAM4, 'Impact Material Type', itU32, wbImpactMaterialTypeEnum, cpNormal, True, False, wbActorTemplateUseModelAnimation),\n    wbInteger(NAM5, 'Sound Level', itU32, wbSoundLevelEnum, cpNormal, True, False, wbActorTemplateUseModelAnimation),\n    wbFormIDCk(CSCR, 'Inherits Sounds from', [CREA], False, cpNormal, False, wbActorTemplateUseModelAnimation),\n    wbCSDTs,\n    wbFormIDCk(CNAM, 'Impact Dataset', [IPDS], False, cpNormal, False, wbActorTemplateUseModelAnimation),\n    wbFormIDCk(LNAM, 'Melee Weapon List', [FLST], False, cpNormal, False, wbActorTemplateUseTraits)\n  ], True);\n\nend;\n\nprocedure DefineFO3d;\nbegin\n  wbRecord(CSTY, 'Combat Style', [\n    wbEDIDReq,\n    wbStruct(CSTD, 'Advanced - Standard', [\n      {000}wbInteger('Maneuver Decision - Dodge % Chance', itU8),\n      {001}wbInteger('Maneuver Decision - Left/Right % Chance', itU8),\n      {002}wbByteArray('Unused', 2),\n      {004}wbFloat('Maneuver Decision - Dodge L/R Timer (min)'),\n      {008}wbFloat('Maneuver Decision - Dodge L/R Timer (max)'),\n      {012}wbFloat('Maneuver Decision - Dodge Forward Timer (min)'),\n      {016}wbFloat('Maneuver Decision - Dodge Forward Timer (max)'),\n      {020}wbFloat('Maneuver Decision - Dodge Back Timer Min'),\n      {024}wbFloat('Maneuver Decision - Dodge Back Timer Max'),\n      {028}wbFloat('Maneuver Decision - Idle Timer min'),\n      {032}wbFloat('Maneuver Decision - Idle Timer max'),\n      {036}wbInteger('Melee Decision - Block % Chance', itU8),\n      {037}wbInteger('Melee Decision - Attack % Chance', itU8),\n      {038}wbByteArray('Unused', 2),\n      {040}wbFloat('Melee Decision - Recoil/Stagger Bonus to Attack'),\n      {044}wbFloat('Melee Decision - Unconscious Bonus to Attack'),\n      {048}wbFloat('Melee Decision - Hand-To-Hand Bonus to Attack'),\n      {052}wbInteger('Melee Decision - Power Attacks - Power Attack % Chance', itU8),\n      {053}wbByteArray('Unused', 3),\n      {056}wbFloat('Melee Decision - Power Attacks - Recoil/Stagger Bonus to Power'),\n      {060}wbFloat('Melee Decision - Power Attacks - Unconscious Bonus to Power Attack'),\n      {064}wbInteger('Melee Decision - Power Attacks - Normal', itU8),\n      {065}wbInteger('Melee Decision - Power Attacks - Forward', itU8),\n      {066}wbInteger('Melee Decision - Power Attacks - Back', itU8),\n      {067}wbInteger('Melee Decision - Power Attacks - Left', itU8),\n      {068}wbInteger('Melee Decision - Power Attacks - Right', itU8),\n      {069}wbByteArray('Unused', 3),\n      {072}wbFloat('Melee Decision - Hold Timer (min)'),\n      {076}wbFloat('Melee Decision - Hold Timer (max)'),\n      {080}wbInteger('Flags', itU16, wbFlags([\n             'Choose Attack using % Chance',\n             'Melee Alert OK',\n             'Flee Based on Personal Survival',\n             '',\n             'Ignore Threats',\n             'Ignore Damaging Self',\n             'Ignore Damaging Group',\n             'Ignore Damaging Spectators',\n             'Cannot Use Stealthboy'\n           ])),\n      {082}wbByteArray('Unused', 2),\n      {085}wbInteger('Maneuver Decision - Acrobatic Dodge % Chance', itU8),\n      {085}wbInteger('Melee Decision - Power Attacks - Rushing Attack % Chance', itU8),\n      {086}wbByteArray('Unused', 2),\n      {088}wbFloat('Melee Decision - Power Attacks - Rushing Attack Distance Mult')\n    ], cpNormal, True),\n    wbStruct(CSAD, 'Advanced - Advanced', [\n      wbFloat('Dodge Fatigue Mod Mult'),\n      wbFloat('Dodge Fatigue Mod Base'),\n      wbFloat('Encumb. Speed Mod Base'),\n      wbFloat('Encumb. Speed Mod Mult'),\n      wbFloat('Dodge While Under Attack Mult'),\n      wbFloat('Dodge Not Under Attack Mult'),\n      wbFloat('Dodge Back While Under Attack Mult'),\n      wbFloat('Dodge Back Not Under Attack Mult'),\n      wbFloat('Dodge Forward While Attacking Mult'),\n      wbFloat('Dodge Forward Not Attacking Mult'),\n      wbFloat('Block Skill Modifier Mult'),\n      wbFloat('Block Skill Modifier Base'),\n      wbFloat('Block While Under Attack Mult'),\n      wbFloat('Block Not Under Attack Mult'),\n      wbFloat('Attack Skill Modifier Mult'),\n      wbFloat('Attack Skill Modifier Base'),\n      wbFloat('Attack While Under Attack Mult'),\n      wbFloat('Attack Not Under Attack Mult'),\n      wbFloat('Attack During Block Mult'),\n      wbFloat('Power Att. Fatigue Mod Base'),\n      wbFloat('Power Att. Fatigue Mod Mult')\n    ], cpNormal, True),\n    wbStruct(CSSD, 'Simple', [\n      {00} wbFloat('Cover Search Radius'),\n      {04} wbFloat('Take Cover Chance'),\n      {08} wbFloat('Wait Timer (min)'),\n      {12} wbFloat('Wait Timer (max)'),\n      {16} wbFloat('Wait to Fire Timer (min)'),\n      {20} wbFloat('Wait to Fire Timer (max)'),\n      {24} wbFloat('Fire Timer (min)'),\n      {28} wbFloat('Fire Timer (max)'),\n      {32} wbFloat('Ranged Weapon Range Mult (min)'),\n      {36} wbByteArray('Unused', 4),\n      {40} wbInteger('Weapon Restrictions', itU32, wbEnum([\n        'None',\n        'Melee Only',\n        'Ranged Only'\n      ])),\n      {44} wbFloat('Ranged Weapon Range Mult (max)'),\n      {48} wbFloat('Max Targeting FOV'),\n      {52} wbFloat('Combat Radius'),\n      {56} wbFloat('Semi-Auto Firing Delay Mult (min)'),\n      {60} wbFloat('Semi-Auto Firing Delay Mult (max)')\n    ], cpNormal, True)\n  ]);\n\n  wbRecord(DIAL, 'Dialog Topic', [\n    wbEDIDReq,\n    wbRArrayS('Quests', wbFormIDCkNoReach(QSTI, 'Quest', [QUST], False, cpBenign)),\n    wbRArrayS('Quests?', wbFormIDCkNoReach(QSTR, 'Quest?', [QUST], False, cpBenign)),\n    wbFULL,\n    wbFloat(PNAM, 'Priority', cpNormal, True, 1, -1, nil, nil, 50.0),\n    wbStruct(DATA, '', [\n      wbInteger('Type', itU8, wbEnum([\n        {0} 'Topic',\n        {1} 'Conversation',\n        {2} 'Combat',\n        {3} 'Persuasion',\n        {4} 'Detection',\n        {5} 'Service',\n        {6} 'Miscellaneous',\n        {7} 'Radio'\n      ])),\n      wbInteger('Flags', itU8, wbFlags([\n        'Rumors',\n        'Top-level'\n      ]))\n    ], cpNormal, True, nil, 1)\n  ], True);\n\n  wbRecord(DOOR, 'Door', [\n    wbEDIDReq,\n    wbOBNDReq,\n    wbFULL,\n    wbMODLReq,\n    wbSCRI,\n    wbDEST,\n    wbFormIDCk(SNAM, 'Sound - Open', [SOUN]),\n    wbFormIDCk(ANAM, 'Sound - Close', [SOUN]),\n    wbFormIDCk(BNAM, 'Sound - Looping', [SOUN]),\n    wbInteger(FNAM, 'Flags', itU8, wbFlags([\n      '',\n      'Automatic Door',\n      'Hidden',\n      'Minimal Use',\n      'Sliding Door'\n    ]), cpNormal, True)\n  ]);\n\n  wbBlendModeEnum := wbEnum([\n    '',\n    'Zero',\n    'One',\n    'Source Color',\n    'Source Inverse Color',\n    'Source Alpha',\n    'Source Inverted Alpha',\n    'Dest Alpha',\n    'Dest Inverted Alpha',\n    'Dest Color',\n    'Dest Inverse Color',\n    'Source Alpha SAT'\n  ]);\n\n  wbBlendOpEnum := wbEnum([\n    '',\n    'Add',\n    'Subtract',\n    'Reverse Subtract',\n    'Minimum',\n    'Maximum'\n  ]);\n  wbZTestFuncEnum := wbEnum([\n    '',\n    '',\n    '',\n    'Equal To',\n    'Normal',\n    'Greater Than',\n    '',\n    'Greater Than or Equal Than',\n    'Always Show'\n  ]);\n\n  wbRecord(EFSH, 'Effect Shader', [\n    wbEDID,\n    wbString(ICON, 'Fill Texture'),\n    wbString(ICO2, 'Particle Shader Texture'),\n    wbString(NAM7, 'Holes Texture'),\n    wbStruct(DATA, '', [\n      wbInteger('Flags', itU8, wbFlags([\n        {0} 'No Membrane Shader',\n        {1} '',\n        {2} '',\n        {3} 'No Particle Shader',\n        {4} 'Edge Effect - Inverse',\n        {5} 'Membrane Shader - Affect Skin Only'\n      ])),\n      wbByteArray('Unused', 3),\n      wbInteger('Membrane Shader - Source Blend Mode', itU32, wbBlendModeEnum),\n      wbInteger('Membrane Shader - Blend Operation', itU32, wbBlendOpEnum),\n      wbInteger('Membrane Shader - Z Test Function', itU32, wbZTestFuncEnum),\n      wbStruct('Fill/Texture Effect - Color', [\n        wbInteger('Red', itU8),\n        wbInteger('Green', itU8),\n        wbInteger('Blue', itU8),\n        wbByteArray('Unused', 1)\n      ]),\n      wbFloat('Fill/Texture Effect - Alpha Fade In Time'),\n      wbFloat('Fill/Texture Effect - Full Alpha Time'),\n      wbFloat('Fill/Texture Effect - Alpha Fade Out Time'),\n      wbFloat('Fill/Texture Effect - Presistent Alpha Ratio'),\n      wbFloat('Fill/Texture Effect - Alpha Pulse Amplitude'),\n      wbFloat('Fill/Texture Effect - Alpha Pulse Frequency'),\n      wbFloat('Fill/Texture Effect - Texture Animation Speed (U)'),\n      wbFloat('Fill/Texture Effect - Texture Animation Speed (V)'),\n      wbFloat('Edge Effect - Fall Off'),\n      wbStruct('Edge Effect - Color', [\n        wbInteger('Red', itU8),\n        wbInteger('Green', itU8),\n        wbInteger('Blue', itU8),\n        wbByteArray('Unused', 1)\n      ]),\n      wbFloat('Edge Effect - Alpha Fade In Time'),\n      wbFloat('Edge Effect - Full Alpha Time'),\n      wbFloat('Edge Effect - Alpha Fade Out Time'),\n      wbFloat('Edge Effect - Persistent Alpha Ratio'),\n      wbFloat('Edge Effect - Alpha Pulse Amplitude'),\n      wbFloat('Edge Effect - Alpha Pusle Frequence'),\n      wbFloat('Fill/Texture Effect - Full Alpha Ratio'),\n      wbFloat('Edge Effect - Full Alpha Ratio'),\n      wbInteger('Membrane Shader - Dest Blend Mode', itU32, wbBlendModeEnum),\n      wbInteger('Particle Shader - Source Blend Mode', itU32, wbBlendModeEnum),\n      wbInteger('Particle Shader - Blend Operation', itU32, wbBlendOpEnum),\n      wbInteger('Particle Shader - Z Test Function', itU32, wbZTestFuncEnum),\n      wbInteger('Particle Shader - Dest Blend Mode', itU32, wbBlendModeEnum),\n      wbFloat('Particle Shader - Particle Birth Ramp Up Time'),\n      wbFloat('Particle Shader - Full Particle Birth Time'),\n      wbFloat('Particle Shader - Particle Birth Ramp Down Time'),\n      wbFloat('Particle Shader - Full Particle Birth Ratio'),\n      wbFloat('Particle Shader - Persistant Particle Birth Ratio'),\n      wbFloat('Particle Shader - Particle Lifetime'),\n      wbFloat('Particle Shader - Particle Lifetime +/-'),\n      wbFloat('Particle Shader - Initial Speed Along Normal'),\n      wbFloat('Particle Shader - Acceleration Along Normal'),\n      wbFloat('Particle Shader - Initial Velocity #1'),\n      wbFloat('Particle Shader - Initial Velocity #2'),\n      wbFloat('Particle Shader - Initial Velocity #3'),\n      wbFloat('Particle Shader - Acceleration #1'),\n      wbFloat('Particle Shader - Acceleration #2'),\n      wbFloat('Particle Shader - Acceleration #3'),\n      wbFloat('Particle Shader - Scale Key 1'),\n      wbFloat('Particle Shader - Scale Key 2'),\n      wbFloat('Particle Shader - Scale Key 1 Time'),\n      wbFloat('Particle Shader - Scale Key 2 Time'),\n      wbStruct('Color Key 1 - Color', [\n        wbInteger('Red', itU8),\n        wbInteger('Green', itU8),\n        wbInteger('Blue', itU8),\n        wbByteArray('Unused', 1)\n      ]),\n      wbStruct('Color Key 2 - Color', [\n        wbInteger('Red', itU8),\n        wbInteger('Green', itU8),\n        wbInteger('Blue', itU8),\n        wbByteArray('Unused', 1)\n      ]),\n      wbStruct('Color Key 3 - Color', [\n        wbInteger('Red', itU8),\n        wbInteger('Green', itU8),\n        wbInteger('Blue', itU8),\n        wbByteArray('Unused', 1)\n      ]),\n      wbFloat('Color Key 1 - Color Alpha'),\n      wbFloat('Color Key 2 - Color Alpha'),\n      wbFloat('Color Key 3 - Color Alpha'),\n      wbFloat('Color Key 1 - Color Key Time'),\n      wbFloat('Color Key 2 - Color Key Time'),\n      wbFloat('Color Key 3 - Color Key Time'),\n      wbFloat('Particle Shader - Initial Speed Along Normal +/-'),\n      wbFloat('Particle Shader - Initial Rotation (deg)'),\n      wbFloat('Particle Shader - Initial Rotation (deg) +/-'),\n      wbFloat('Particle Shader - Rotation Speed (deg/sec)'),\n      wbFloat('Particle Shader - Rotation Speed (deg/sec) +/-'),\n      wbFormIDCk('Addon Models', [DEBR, NULL]),\n      wbFloat('Holes - Start Time'),\n      wbFloat('Holes - End Time'),\n      wbFloat('Holes - Start Val'),\n      wbFloat('Holes - End Val'),\n      wbFloat('Edge Width (alpha units)'),\n      wbStruct('Edge Color', [\n        wbInteger('Red', itU8),\n        wbInteger('Green', itU8),\n        wbInteger('Blue', itU8),\n        wbByteArray('Unused', 1)\n      ]),\n      wbFloat('Explosion Wind Speed'),\n      wbInteger('Texture Count U', itU32),\n      wbInteger('Texture Count V', itU32),\n      wbFloat('Addon Models - Fade In Time'),\n      wbFloat('Addon Models - Fade Out Time'),\n      wbFloat('Addon Models - Scale Start'),\n      wbFloat('Addon Models - Scale End'),\n      wbFloat('Addon Models - Scale In Time'),\n      wbFloat('Addon Models - Scale Out Time')\n    ], cpNormal, True, nil, 57)\n  ], False, nil, cpNormal, False, wbEFSHAfterLoad);\n\n  wbRecord(ENCH, 'Object Effect', [\n    wbEDIDReq,\n    wbFULL,\n    wbStruct(ENIT, 'Effect Data', [\n      wbInteger('Type', itU32, wbEnum([\n        {0} '',\n        {1} '',\n        {2} 'Weapon',\n        {3} 'Apparel'\n      ])),\n      wbByteArray('Unused', 4),\n      wbByteArray('Unused', 4),\n      wbInteger('Flags', itU8, wbFlags([\n        'No Auto-Calc',\n        '',\n        'Hide Effect'\n      ])),\n      wbByteArray('Unused', 3)\n    ], cpNormal, True),\n    wbEffectsReq\n  ]);\n\n  wbRecord(EYES, 'Eyes', [\n    wbEDIDReq,\n    wbFULLReq,\n    wbString(ICON, 'Texture', 0{, cpNormal, True??}),\n    wbInteger(DATA, 'Flags', itU8, wbFlags([\n      'Playable',\n      'Not Male',\n      'Not Female'\n    ]), cpNormal, True)\n  ]);\n\n  wbXNAM :=\n    wbStructSK(XNAM, [0], 'Relation', [\n      wbFormIDCkNoReach('Faction', [FACT, RACE]),\n      wbInteger('Modifier', itS32),\n      wbInteger('Group Combat Reaction', itU32, wbEnum([\n        'Neutral',\n        'Enemy',\n        'Ally',\n        'Friend'\n      ]))\n    ]);\n\n  wbXNAMs := wbRArrayS('Relations', wbXNAM);\n\n  wbRecord(FACT, 'Faction', [\n    wbEDIDReq,\n    wbFULL,\n    wbXNAMs,\n    wbStruct(DATA, '', [\n      wbInteger('Flags 1', itU8, wbFlags([\n        'Hidden from PC',\n        'Evil',\n        'Special Combat'\n      ])),\n      wbInteger('Flags 2', itU8, wbFlags([\n        'Track Crime',\n        'Allow Sell'\n      ])),\n      wbByteArray('Unused', 2)\n    ], cpNormal, True, nil, 1),\n    wbFloat(CNAM, 'Unused'),\n    wbRStructsSK('Ranks', 'Rank', [0], [\n      wbInteger(RNAM, 'Rank#', itS32),\n      wbString(MNAM, 'Male', 0, cpTranslate),\n      wbString(FNAM, 'Female', 0, cpTranslate),\n      wbString(INAM, 'Insignia (Unused)')\n    ], [])\n  ], False, nil, cpNormal, False, wbFACTAfterLoad);\n\n  wbRecord(FURN, 'Furniture', [\n    wbEDIDReq,\n    wbOBNDReq,\n    wbFULL,\n    wbMODLReq,\n    wbSCRI,\n    wbDEST,\n    wbByteArray(MNAM, 'Marker Flags', 0, cpNormal, True)\n  ]);\n\n  wbRecord(GLOB, 'Global', [\n    wbEDIDReq,\n    wbInteger(FNAM, 'Type', itU8, wbGLOBFNAM, nil, cpNormal, True),\n    wbFloat(FLTV, 'Value', cpNormal, True)\n  ]);\n\n\n  wbRecord(GMST, 'Game Setting', [\n    wbString(EDID, 'Editor ID', 0, cpCritical, True, nil, wbGMSTEDIDAfterSet),\n    wbUnion(DATA, 'Value', wbGMSTUnionDecider, [\n      wbString('', 0, cpTranslate),\n      wbInteger('', itS32),\n      wbFloat('')\n    ], cpNormal, True)\n  ]);\n\n  wbDODT := wbStruct(DODT, 'Decal Data', [\n              wbFloat('Min Width'),\n              wbFloat('Max Width'),\n              wbFloat('Min Height'),\n              wbFloat('Max Height'),\n              wbFloat('Depth'),\n              wbFloat('Shininess'),\n              wbStruct('Parallax', [\n                wbFloat('Scale'),\n                wbInteger('Passes', itU8)\n              ]),\n              wbInteger('Flags', itU8, wbFlags([\n                'Parallax',\n                'Alpha - Blending',\n                'Alpha - Testing'\n              ], True)),\n              wbByteArray('Unused', 2),\n              wbStruct('Color', [\n                wbInteger('Red', itU8),\n                wbInteger('Green', itU8),\n                wbInteger('Blue', itU8),\n                wbByteArray('Unused', 1)\n              ])\n            ]);\n\n  wbRecord(TXST, 'Texture Set', [\n    wbEDIDReq,\n    wbOBNDReq,\n    wbRStruct('Textures (RGB/A)', [\n      wbString(TX00,'Base Image / Transparency'),\n      wbString(TX01,'Normal Map / Specular'),\n      wbString(TX02,'Environment Map Mask / ?'),\n      wbString(TX03,'Glow Map / Unused'),\n      wbString(TX04,'Parallax Map / Unused'),\n      wbString(TX05,'Environment Map / Unused')\n    ], []),\n    wbDODT,\n    wbInteger(DNAM, 'Flags', itU16, wbFlags([\n      'No Specular Map'\n    ]), cpNormal, True)\n  ]);\n\n  wbRecord(MICN, 'Menu Icon', [\n    wbEDIDReq,\n    wbICONReq\n  ]);\n\n  wbRecord(HDPT, 'Head Part', [\n    wbEDIDReq,\n    wbFULLReq,\n    wbMODL,\n    wbInteger(DATA, 'Flags', itU8, wbFlags([\n      'Playable'\n    ]), cpNormal, True),\n    wbRArrayS('Extra Parts',\n      wbFormIDCk(HNAM, 'Part', [HDPT])\n    )\n  ]);\n\n  wbRecord(ASPC, 'Acoustic Space', [\n    wbEDIDReq,\n    wbOBNDReq,\n    wbFormIDCk(SNAM, 'Sound - Looping', [SOUN]),\n    wbFormIDCk(RDAT, 'Use Sound from Region (Interiors Only)', [REGN]),\n    wbInteger(ANAM, 'Environment Type', itU32, wbEnum([\n      'None',\n      'Default',\n      'Generic',\n      'Padded Cell',\n      'Room',\n      'Bathroom',\n      'Livingroom',\n      'Stone Room',\n      'Auditorium',\n      'Concerthall',\n      'Cave',\n      'Arena',\n      'Hangar',\n      'Carpeted Hallway',\n      'Hallway',\n      'Stone Corridor',\n      'Alley',\n      'Forest',\n      'City',\n      'Mountains',\n      'Quarry',\n      'Plain',\n      'Parkinglot',\n      'Sewerpipe',\n      'Underwater',\n      'Small Room',\n      'Medium Room',\n      'Large Room',\n      'Medium Hall',\n      'Large Hall',\n      'Plate'\n    ]), cpNormal, True)\n  ]);\n\n  wbRecord(TACT, 'Talking Activator', [\n    wbEDIDReq,\n    wbOBNDReq,\n    wbFULL,\n    wbMODLReq,\n    wbSCRI,\n    wbDEST,\n    wbFormIDCk(SNAM, 'Sound', [SOUN]),\n    wbFormIDCk(VNAM, 'Voice Type', [VTYP])\n  ]);\n\n  wbRecord(SCPT, 'Script', [\n    wbEDIDReq,\n    wbSCHRReq,\n    wbByteArray(SCDA, 'Compiled Script'),\n    wbStringScript(SCTX, 'Script Source', 0, cpNormal{, True}),\n    wbRArrayS('Local Variables', wbRStructSK([0], 'Local Variable', [\n      wbSLSD,\n      wbString(SCVR, 'Name', 0, cpCritical, True)\n    ], [])),\n    wbSCROs\n  ]);\n\n  wbRecord(TERM, 'Terminal', [\n    wbEDIDReq,\n    wbOBNDReq,\n    wbFULL,\n    wbMODL,\n    wbSCRI,\n    wbDEST,\n    wbDESCReq,\n    wbFormIDCk(SNAM, 'Sound - Looping', [SOUN]),\n    wbFormIDCk(PNAM, 'Password Note', [NOTE]),\n    wbStruct(DNAM, '', [\n      wbInteger('Base Hacking Difficulty', itU8, wbEnum([\n        'Very Easy',\n        'Easy',\n        'Average',\n        'Hard',\n        'Very Hard',\n        'Requires Key'\n      ])),\n      wbInteger('Flags', itU8, wbFlags([\n        'Leveled',\n        'Unlocked',\n        'Alternate Colors',\n        'Hide Welcome Text when displaying Image'\n      ])),\n      wbInteger('ServerType', itU8, wbEnum([\n        '-Server 1-',\n        '-Server 2-',\n        '-Server 3-',\n        '-Server 4-',\n        '-Server 5-',\n        '-Server 6-',\n        '-Server 7-',\n        '-Server 8-',\n        '-Server 9-',\n        '-Server 10-'\n      ])),\n      wbByteArray('Unused', 1)\n    ], cpNormal, True),\n    wbRArray('Menu Items',\n      wbRStruct('Menu Item', [\n        wbString(ITXT, 'Item Text'),\n        wbString(RNAM, 'Result Text', 0, cpNormal, True),\n        wbInteger(ANAM, 'Flags', itU8, wbFlags([\n          'Add Note',\n          'Force Redraw'\n        ]), cpNormal, True),\n        wbFormIDCk(INAM, 'Display Note', [NOTE]),\n        wbFormIDCk(TNAM, 'Sub Menu', [TERM]),\n        wbEmbeddedScriptReq,\n        wbCTDAs\n      ], [])\n    )\n  ]);\n\n  wbRecord(SCOL, 'Static Collection', [\n    wbEDIDReq,\n    wbOBNDReq,\n    wbMODLReq,\n    wbRStructsSK('Parts', 'Part', [0], [\n      wbFormIDCk(ONAM, 'Static', [STAT]),\n      wbArrayS(DATA, 'Placements', wbStruct('Placement', [\n        wbStruct('Position', [\n          wbFloat('X'),\n          wbFloat('Y'),\n          wbFloat('Z')\n        ]),\n        wbStruct('Rotation', [\n          wbFloat('X', cpNormal, True, wbRotationFactor, wbRotationScale, nil, RadiansNormalize),\n          wbFloat('Y', cpNormal, True, wbRotationFactor, wbRotationScale, nil, RadiansNormalize),\n          wbFloat('Z', cpNormal, True, wbRotationFactor, wbRotationScale, nil, RadiansNormalize)\n        ]),\n        wbFloat('Scale')\n      ]), 0, cpNormal, True)\n    ], [], cpNormal, True)\n  ]);\n\n  wbRecord(MSTT, 'Moveable Static', [\n    wbEDIDReq,\n    wbOBNDReq,\n    wbFULL,\n    wbMODLReq,\n    wbDEST,\n    wbByteArray(DATA, 'Unknown', 1, cpNormal, True),\n    wbFormIDCk(SNAM, 'Sound', [SOUN])\n  ]);\n\n  wbRecord(PWAT, 'Placeable Water', [\n    wbEDIDReq,\n    wbOBNDReq,\n    wbMODLReq,\n    wbStruct(DNAM, '', [\n      wbInteger('Flags', itU32, wbFlags([\n        {0x00000001}'Reflects',\n        {0x00000002}'Reflects - Actors',\n        {0x00000004}'Reflects - Land',\n        {0x00000008}'Reflects - LOD Land',\n        {0x00000010}'Reflects - LOD Buildings',\n        {0x00000020}'Reflects - Trees',\n        {0x00000040}'Reflects - Sky',\n        {0x00000080}'Reflects - Dynamic Objects',\n        {0x00000100}'Reflects - Dead Bodies',\n        {0x00000200}'Refracts',\n        {0x00000400}'Refracts - Actors',\n        {0x00000800}'Refracts - Land',\n        {0x00001000}'',\n        {0x00002000}'',\n        {0x00004000}'',\n        {0x00008000}'',\n        {0x00010000}'Refracts - Dynamic Objects',\n        {0x00020000}'Refracts - Dead Bodies',\n        {0x00040000}'Silhouette Reflections',\n        {0x00080000}'',\n        {0x00100000}'',\n        {0x00200000}'',\n        {0x00400000}'',\n        {0x00800000}'',\n        {0x01000000}'',\n        {0x02000000}'',\n        {0x03000000}'',\n        {0x08000000}'',\n        {0x10000000}'Depth',\n        {0x20000000}'Object Texture Coordinates',\n        {0x40000000}'',\n        {0x80000000}'No Underwater Fog'\n      ])),\n      wbFormIDCk('Water', [WATR])\n    ], cpNormal, True)\n  ]);\n\n  wbRecord(IDLM, 'Idle Marker', [\n    wbEDIDReq,\n    wbOBNDReq,\n    wbInteger(IDLF, 'Flags', itU8, wbFlags([\n      'Run in Sequence',\n      '',\n      'Do Once'\n    ]), cpNormal, True),\n    wbStruct(IDLC, '', [\n      wbInteger('Animation Count', itU8),\n      wbByteArray('Unused', 3)\n    ], cpNormal, True, nil, 1),\n    wbFloat(IDLT, 'Idle Timer Setting', cpNormal, True),\n    wbArray(IDLA, 'Animations', wbFormIDCk('Animation', [IDLE, NULL]), 0, nil, wbIDLAsAfterSet, cpNormal, True)  // NULL looks valid if IDLS\\Animation Count is 0\n  ], False, nil, cpNormal, False, nil, wbAnimationsAfterSet);\n\n  wbRecord(NOTE, 'Note', [\n    wbEDIDReq,\n    wbOBNDReq,\n    wbFULL,\n    wbMODL,\n    wbICON,\n    wbYNAM,\n    wbZNAM,\n    wbInteger(DATA, 'Type', itU8, wbEnum([\n      'Sound',\n      'Text',\n      'Image',\n      'Voice'\n    ]), cpNormal, True),\n    wbRArrayS('Quests',\n      wbFormIDCkNoReach(ONAM, 'Quest', [QUST])\n    ),\n    wbString(XNAM, 'Texture'),\n    wbUnion(TNAM, 'Text / Topic', wbNOTETNAMDecide, [\n      wbString('Text'),\n      wbFormIDCk('Topic', [DIAL])\n    ]),\n    wbUnion(SNAM, 'Sound / NPC', wbNOTESNAMDecide, [\n      wbFormIDCk('Sound', [SOUN]),\n      wbFormIDCk('NPC', [NPC_])\n    ])\n  ]);\n\nend;\n\nprocedure DefineFO3e;\nbegin\n  wbRecord(PROJ, 'Projectile', [\n    wbEDIDReq,\n    wbOBNDReq,\n    wbFULL,\n    wbMODLReq,\n    wbDEST,\n    wbStruct(DATA, 'Data', [\n      {00} wbInteger('Flags', itU16, wbFlags([\n        'Hitscan',\n        'Explosion',\n        'Alt. Trigger',\n        'Muzzle Flash',\n        '',\n        'Can Be Disabled',\n        'Can Be Picked Up',\n        'Supersonic',\n        'Pins Limbs',\n        'Pass Through Small Transparent'\n      ])),\n      {00} wbInteger('Type', itU16, wbEnum([\n        {00} '',\n        {01} 'Missile',\n        {02} 'Lobber',\n        {03} '',\n        {04} 'Beam',\n        {05} '',\n        {06} '',\n        {07} '',\n        {08} 'Flame'\n      ])),\n      {04} wbFloat('Gravity'),\n      {08} wbFloat('Speed'),\n      {12} wbFloat('Range'),\n      {16} wbFormIDCk('Light', [LIGH, NULL]),\n      {20} wbFormIDCk('Muzzle Flash - Light', [LIGH, NULL]),\n      {24} wbFloat('Tracer Chance'),\n      {28} wbFloat('Explosion - Alt. Trigger - Proximity'),\n      {32} wbFloat('Explosion - Alt. Trigger - Timer'),\n      {36} wbFormIDCk('Explosion', [EXPL, NULL]),\n      {40} wbFormIDCk('Sound', [SOUN, NULL]),\n      {44} wbFloat('Muzzle Flash - Duration'),\n      {48} wbFloat('Fade Duration'),\n      {52} wbFloat('Impact Force'),\n      {56} wbFormIDCk('Sound - Countdown', [SOUN, NULL]),\n      {60} wbFormIDCk('Sound - Disable', [SOUN, NULL]),\n      {64} wbFormIDCk('Default Weapon Source', [WEAP, NULL])\n    ], cpNormal, True),\n    wbRStructSK([0], 'Muzzle Flash Model', [\n      wbString(NAM1, 'Model Filename'),\n      wbByteArray(NAM2, 'Texture Files Hashes', 0, cpIgnore)\n    ], [], cpNormal, True),\n    wbInteger(VNAM, 'Sound Level', itU32, wbSoundLevelEnum, cpNormal, True)\n  ]);\n\n  wbRecord(NAVI, 'Navigation Mesh Info Map', [\n    wbEDID,\n    wbInteger(NVER, 'Version', itU32),\n    wbRArray('Navigation Map Infos',\n      wbStruct(NVMI, 'Navigation Map Info', [\n        wbByteArray('Unknown', 4),\n        wbFormIDCk('Navigation Mesh', [NAVM]),\n        wbFormIDCk('Location', [CELL, WRLD]),\n        wbStruct('Grid', [\n          wbInteger('X', itS16),\n          wbInteger('Y', itS16)\n        ]),\n        wbUnknown\n{        wbUnion('Data', wbNAVINVMIDecider, [\n          wbStruct('Data', [\n            wbUnknown\n          ]),\n          wbStruct('Data', [\n            wbArray('Unknown', wbFloat('Unknown'), 3),\n            wbByteArray('Unknown', 4)\n          ]),\n          wbStruct('Data', [\n            wbArray('Unknown', wbArray('Unknown', wbFloat('Unknown'), 3), 3),\n            wbInteger('Count 1', itU16),\n            wbInteger('Count 2', itU16),\n            wbArray('Unknown', wbArray('Unknown', wbFloat('Unknown'), 3), [], wbNAVINAVMGetCount1),\n            wbUnknown\n          ]),\n          wbStruct('Data', [\n            wbUnknown\n          ])\n        ])}\n      ])\n    ),\n    wbRArray('Unknown',\n      wbStruct(NVCI, 'Unknown', [\n        wbFormIDCk('Unknown', [NAVM]),\n        wbArray('Unknown', wbFormIDCk('Unknown', [NAVM]), -1),\n        wbArray('Unknown', wbFormIDCk('Unknown', [NAVM]), -1),\n        wbArray('Doors', wbFormIDCk('Door', [REFR]), -1)\n      ])\n    )\n  ]);\n\n  if wbSimpleRecords then begin\n\n    wbRecord(NAVM, 'Navigation Mesh', [\n      wbEDID,\n      wbInteger(NVER, 'Version', itU32),\n      wbStruct(DATA, '', [\n        wbFormIDCk('Cell', [CELL]),\n        wbInteger('Vertex Count', itU32),\n        wbInteger('Triangle Count', itU32),\n        wbInteger('External Connections Count', itU32),\n        wbInteger('NVCA Count', itU32),\n        wbInteger('Doors Count', itU32)\n      ]),\n      wbByteArray(NVVX, 'Vertices'),\n      wbByteArray(NVTR, 'Triangles'),\n      wbByteArray(NVCA, 'Unknown'),\n      wbArray(NVDP, 'Doors', wbStruct('Door', [\n        wbFormIDCk('Reference', [REFR]),\n        wbInteger('Triangle', itU16),\n        wbByteArray('Unused', 2)\n      ])),\n      wbByteArray(NVGD, 'Unknown'),\n      wbArray(NVEX, 'External Connections', wbStruct('Connection', [\n        wbByteArray('Unknown', 4),\n        wbFormIDCk('Navigation Mesh', [NAVM], False, cpNormal),\n        wbInteger('Triangle', itU16, nil, cpNormal)\n      ]))\n    ], False, wbNAVMAddInfo);\n\n  end else begin\n\n    wbRecord(NAVM, 'Navigation Mesh', [\n      wbEDID,\n      wbInteger(NVER, 'Version', itU32),\n      wbStruct(DATA, '', [\n        wbFormIDCk('Cell', [CELL]),\n        wbInteger('Vertex Count', itU32),\n        wbInteger('Triangle Count', itU32),\n        wbInteger('External Connections Count', itU32),\n        wbInteger('NVCA Count', itU32),\n        wbInteger('Doors Count', itU32) // as of version = 5 (earliest NavMesh version I saw (Fallout3 1.7) is already 11)\n      ]),\n      wbArray(NVVX, 'Vertices', wbStruct('Vertex', [\n        wbFloat('X'),\n        wbFloat('Y'),\n        wbFloat('Z')\n      ])),\n      wbArray(NVTR, 'Triangles', wbStruct('Triangle', [\n        wbArray('Vertices', wbInteger('Vertex', itS16), 3),\n        wbArray('Edges', wbInteger('Triangle', itS16, wbNVTREdgeToStr, wbNVTREdgeToInt), [\n          '0 <-> 1',\n          '1 <-> 2',\n          '2 <-> 0'\n        ]),\n        wbInteger('Flags', itU32, wbFlags([\n          'Triangle #0 Is External',\n          'Triangle #1 Is External',\n          'Triangle #2 Is External',\n          'Unknown 4',\n          'Unknown 5',\n          'Unknown 6',\n          'Unknown 7',\n          'Unknown 8',\n          'Unknown 9',\n          'Unknown 10',\n          'Unknown 11',\n          'Unknown 12',\n          'Unknown 13',\n          'Unknown 14',\n          'Unknown 15',\n          'Unknown 16',\n          'Unknown 17',\n          'Unknown 18',\n          'Unknown 19',\n          'Unknown 20',\n          'Unknown 21',\n          'Unknown 22',\n          'Unknown 23',\n          'Unknown 24',\n          'Unknown 25',\n          'Unknown 26',\n          'Unknown 27',\n          'Unknown 28',\n          'Unknown 29',\n          'Unknown 30',\n          'Unknown 31',\n          'Unknown 32'\n        ]))\n      ])),\n      wbArray(NVCA, 'Unknown', wbInteger('Unknown', itS16)),\n      wbArray(NVDP, 'Doors', wbStruct('Door', [\n        wbFormIDCk('Reference', [REFR]),\n        wbInteger('Triangle', itU16),\n        wbByteArray('Unused', 2)\n      ])),\n      wbStruct(NVGD, 'Unknown', [\n        wbByteArray('Unknown', 4),\n        wbFloat('Unknown'),\n        wbFloat('Unknown'),\n        wbFloat('Unknown'),\n        wbFloat('Unknown'),\n        wbFloat('Unknown'),\n        wbFloat('Unknown'),\n        wbFloat('Unknown'),\n        wbFloat('Unknown'),\n        wbArray('Unknown', wbArray('Unknown', wbInteger('Unknown', itU16), -2))\n      ]),\n      wbArray(NVEX, 'External Connections', wbStruct('Connection', [\n        wbByteArray('Unknown', 4),\n        wbFormIDCk('Navigation Mesh', [NAVM], False, cpNormal),\n        wbInteger('Triangle', itU16, nil, cpNormal)\n      ]))\n    ], False, wbNAVMAddInfo);\n\n  end;\n\n  wbRecord(PGRE, 'Placed Grenade', [\n    wbEDID,\n    wbFormIDCk(NAME, 'Base', [PROJ], False, cpNormal, True),\n    wbFormIDCk(XEZN, 'Encounter Zone', [ECZN]),\n\n    wbXRGD,\n    wbXRGB,\n\n    {--- Patrol Data ---}\n    wbRStruct('Patrol Data', [\n      wbFloat(XPRD, 'Idle Time', cpNormal, True),\n      wbEmpty(XPPA, 'Patrol Script Marker', cpNormal, True),\n      wbFormIDCk(INAM, 'Idle', [IDLE, NULL], False, cpNormal, True),\n      wbEmbeddedScriptReq,\n      wbFormIDCk(TNAM, 'Topic', [DIAL, NULL], False, cpNormal, True)\n    ], []),\n\n    {--- Ownership ---}\n    wbRStruct('Ownership', [\n      wbXOWN,\n      wbInteger(XRNK, 'Faction rank', itS32)\n    ], [XCMT, XCMO]),\n\n    {--- Extra ---}\n    wbInteger(XCNT, 'Count', itS32),\n    wbFloat(XRDS, 'Radius'),\n    wbFloat(XHLP, 'Health'),\n\n    {--- Reflected By / Refracted By ---}\n    wbRArrayS('Reflected/Refracted By',\n      wbStructSK(XPWR, [0], 'Water', [\n        wbFormIDCk('Reference', [REFR]),\n        wbInteger('Type', itU32, wbFlags([\n          'Reflection',\n          'Refraction'\n        ]))\n      ])\n    ),\n\n    {--- Decals ---}\n    wbRArrayS('Linked Decals',\n      wbStructSK(XDCR, [0], 'Decal', [\n        wbFormIDCk('Reference', [REFR]),\n        wbUnknown\n      ])\n    ),\n\n    {--- Linked Ref ---}\n    wbFormIDCk(XLKR, 'Linked Reference', [REFR, ACRE, ACHR, PGRE, PMIS, PBEA, PLYR]),\n    wbStruct(XCLP, 'Linked Reference Color', [\n      wbStruct('Link Start Color', [\n        wbInteger('Red', itU8),\n        wbInteger('Green', itU8),\n        wbInteger('Blue', itU8),\n        wbByteArray('Unused', 1)\n      ]),\n      wbStruct('Link End Color', [\n        wbInteger('Red', itU8),\n        wbInteger('Green', itU8),\n        wbInteger('Blue', itU8),\n        wbByteArray('Unused', 1)\n      ])\n    ]),\n\n    {--- Activate Parents ---}\n    wbRStruct('Activate Parents', [\n      wbInteger(XAPD, 'Flags', itU8, wbFlags([\n        'Parent Activate Only'\n      ], True)),\n      wbRArrayS('Activate Parent Refs',\n        wbStructSK(XAPR, [0], 'Activate Parent Ref', [\n          wbFormIDCk('Reference', [REFR, ACRE, ACHR, PGRE, PMIS, PBEA, PLYR]),\n          wbFloat('Delay')\n        ])\n      )\n    ], []),\n\n    {--- Enable Parent ---}\n    wbXESP,\n\n    {--- Emittance ---}\n    wbFormIDCk(XEMI, 'Emittance', [LIGH, REGN]),\n\n    {--- MultiBound ---}\n    wbFormIDCk(XMBR, 'MultiBound Reference', [REFR]),\n\n    {--- Flags ---}\n    wbEmpty(XIBS, 'Ignored By Sandbox'),\n\n    {--- 3D Data ---}\n    wbXSCL,\n    wbDATAPosRot\n  ], True, wbPlacedAddInfo);\n\n  wbRecord(PMIS, 'Placed Missile', [\n    wbEDID,\n    wbFormIDCk(NAME, 'Base', [PROJ], False, cpNormal, True),\n    wbFormIDCk(XEZN, 'Encounter Zone', [ECZN]),\n\n    wbXRGD,\n    wbXRGB,\n\n    {--- Patrol Data ---}\n    wbRStruct('Patrol Data', [\n      wbFloat(XPRD, 'Idle Time', cpNormal, True),\n      wbEmpty(XPPA, 'Patrol Script Marker', cpNormal, True),\n      wbFormIDCk(INAM, 'Idle', [IDLE, NULL], False, cpNormal, True),\n      wbEmbeddedScriptReq,\n      wbFormIDCk(TNAM, 'Topic', [DIAL, NULL], False, cpNormal, True)\n    ], []),\n\n    {--- Ownership ---}\n    wbRStruct('Ownership', [\n      wbXOWN,\n      wbInteger(XRNK, 'Faction rank', itS32)\n    ], [XCMT, XCMO]),\n\n    {--- Extra ---}\n    wbInteger(XCNT, 'Count', itS32),\n    wbFloat(XRDS, 'Radius'),\n    wbFloat(XHLP, 'Health'),\n\n    {--- Reflected By / Refracted By ---}\n    wbRArrayS('Reflected/Refracted By',\n      wbStructSK(XPWR, [0], 'Water', [\n        wbFormIDCk('Reference', [REFR]),\n        wbInteger('Type', itU32, wbFlags([\n          'Reflection',\n          'Refraction'\n        ]))\n      ])\n    ),\n\n    {--- Decals ---}\n    wbRArrayS('Linked Decals',\n      wbStructSK(XDCR, [0], 'Decal', [\n        wbFormIDCk('Reference', [REFR]),\n        wbUnknown\n      ])\n    ),\n\n    {--- Linked Ref ---}\n    wbFormIDCk(XLKR, 'Linked Reference', [REFR, ACRE, ACHR, PGRE, PMIS, PBEA, PLYR]),\n    wbStruct(XCLP, 'Linked Reference Color', [\n      wbStruct('Link Start Color', [\n        wbInteger('Red', itU8),\n        wbInteger('Green', itU8),\n        wbInteger('Blue', itU8),\n        wbByteArray('Unused', 1)\n      ]),\n      wbStruct('Link End Color', [\n        wbInteger('Red', itU8),\n        wbInteger('Green', itU8),\n        wbInteger('Blue', itU8),\n        wbByteArray('Unused', 1)\n      ])\n    ]),\n\n    {--- Activate Parents ---}\n    wbRStruct('Activate Parents', [\n      wbInteger(XAPD, 'Flags', itU8, wbFlags([\n        'Parent Activate Only'\n      ], True)),\n      wbRArrayS('Activate Parent Refs',\n        wbStructSK(XAPR, [0], 'Activate Parent Ref', [\n          wbFormIDCk('Reference', [REFR, ACRE, ACHR, PGRE, PMIS, PBEA, PLYR]),\n          wbFloat('Delay')\n        ])\n      )\n    ], []),\n\n    {--- Enable Parent ---}\n    wbXESP,\n\n    {--- Emittance ---}\n    wbFormIDCk(XEMI, 'Emittance', [LIGH, REGN]),\n\n    {--- MultiBound ---}\n    wbFormIDCk(XMBR, 'MultiBound Reference', [REFR]),\n\n    {--- Flags ---}\n    wbEmpty(XIBS, 'Ignored By Sandbox'),\n\n    {--- 3D Data ---}\n    wbXSCL,\n    wbDATAPosRot\n  ], True, wbPlacedAddInfo);\n\n  wbRecord(PBEA, 'Placed Beam', [\n    wbEDID,\n    wbFormIDCk(NAME, 'Base', [PROJ], False, cpNormal, True),\n    wbFormIDCk(XEZN, 'Encounter Zone', [ECZN]),\n\n    wbXRGD,\n    wbXRGB,\n\n    {--- Patrol Data ---}\n    wbRStruct('Patrol Data', [\n      wbFloat(XPRD, 'Idle Time', cpNormal, True),\n      wbEmpty(XPPA, 'Patrol Script Marker', cpNormal, True),\n      wbFormIDCk(INAM, 'Idle', [IDLE, NULL], False, cpNormal, True),\n      wbEmbeddedScriptReq,\n      wbFormIDCk(TNAM, 'Topic', [DIAL, NULL], False, cpNormal, True)\n    ], []),\n\n    {--- Ownership ---}\n    wbRStruct('Ownership', [\n      wbXOWN,\n      wbInteger(XRNK, 'Faction rank', itS32)\n    ], [XCMT, XCMO]),\n\n    {--- Extra ---}\n    wbInteger(XCNT, 'Count', itS32),\n    wbFloat(XRDS, 'Radius'),\n    wbFloat(XHLP, 'Health'),\n\n    {--- Reflected By / Refracted By ---}\n    wbRArrayS('Reflected/Refracted By',\n      wbStructSK(XPWR, [0], 'Water', [\n        wbFormIDCk('Reference', [REFR]),\n        wbInteger('Type', itU32, wbFlags([\n          'Reflection',\n          'Refraction'\n        ]))\n      ])\n    ),\n\n    {--- Decals ---}\n    wbRArrayS('Linked Decals',\n      wbStructSK(XDCR, [0], 'Decal', [\n        wbFormIDCk('Reference', [REFR]),\n        wbUnknown\n      ])\n    ),\n\n    {--- Linked Ref ---}\n    wbFormIDCk(XLKR, 'Linked Reference', [REFR, ACRE, ACHR, PGRE, PMIS, PBEA, PLYR]),\n    wbStruct(XCLP, 'Linked Reference Color', [\n      wbStruct('Link Start Color', [\n        wbInteger('Red', itU8),\n        wbInteger('Green', itU8),\n        wbInteger('Blue', itU8),\n        wbByteArray('Unused', 1)\n      ]),\n      wbStruct('Link End Color', [\n        wbInteger('Red', itU8),\n        wbInteger('Green', itU8),\n        wbInteger('Blue', itU8),\n        wbByteArray('Unused', 1)\n      ])\n    ]),\n\n    {--- Activate Parents ---}\n    wbRStruct('Activate Parents', [\n      wbInteger(XAPD, 'Flags', itU8, wbFlags([\n        'Parent Activate Only'\n      ], True)),\n      wbRArrayS('Activate Parent Refs',\n        wbStructSK(XAPR, [0], 'Activate Parent Ref', [\n          wbFormIDCk('Reference', [REFR, ACRE, ACHR, PGRE, PMIS, PBEA, PLYR]),\n          wbFloat('Delay')\n        ])\n      )\n    ], []),\n\n    {--- Enable Parent ---}\n    wbXESP,\n\n    {--- Emittance ---}\n    wbFormIDCk(XEMI, 'Emittance', [LIGH, REGN]),\n\n    {--- MultiBound ---}\n    wbFormIDCk(XMBR, 'MultiBound Reference', [REFR]),\n\n    {--- Flags ---}\n    wbEmpty(XIBS, 'Ignored By Sandbox'),\n\n    {--- 3D Data ---}\n    wbXSCL,\n    wbDATAPosRot\n  ], True, wbPlacedAddInfo);\n\n   wbRecord(EXPL, 'Explosion', [\n    wbEDIDReq,\n    wbOBNDReq,\n    wbFULL,\n    wbMODL,\n    wbEITM,\n    wbFormIDCk(MNAM, 'Image Space Modifier', [IMAD]),\n    wbStruct(DATA, 'Data', [\n      {00} wbFloat('Force'),\n      {04} wbFloat('Damage'),\n      {08} wbFloat('Radius'),\n      {12} wbFormIDCk('Light', [LIGH, NULL]),\n      {16} wbFormIDCk('Sound 1', [SOUN, NULL]),\n      {20} wbInteger('Flags', itU32, wbFlags([\n             {0x00000001}'Unknown 1',\n             {0x00000002}'Always Uses World Orientation',\n             {0x00000004}'Knock Down - Always',\n             {0x00000008}'Knock Down - By Formula',\n             {0x00000010}'Ignore LOS Check',\n             {0x00000020}'Push Explosion Source Ref Only',\n             {0x00000040}'Ignore Image Space Swap'\n           ])),\n      {24} wbFloat('IS Radius'),\n      {28} wbFormIDCk('Impact DataSet', [IPDS, NULL]),\n      {32} wbFormIDCk('Sound 2', [SOUN, NULL]),\n           wbStruct('Radiation', [\n             {36} wbFloat('Level'),\n             {40} wbFloat('Dissipation Time'),\n             {44} wbFloat('Radius')\n           ]),\n      {48} wbInteger('Sound Level', itU32, wbSoundLevelEnum, cpNormal, True)\n    ], cpNormal, True),\n    wbFormIDCk(INAM, 'Placed Impact Object', [TREE, SOUN, ACTI, DOOR, STAT, FURN,\n          CONT, ARMO, AMMO, LVLN, LVLC, MISC, WEAP, BOOK, KEYM, ALCH, LIGH, GRAS,\n          ASPC, IDLM, ARMA, MSTT, NOTE, PWAT, SCOL, TACT, TERM, TXST])\n  ]);\n\n  wbRecord(DEBR, 'Debris', [\n    wbEDIDReq,\n    wbRStructs('Models', 'Model', [\n      wbStruct(DATA, 'Data', [\n        wbInteger('Percentage', itU8),\n        wbString('Model Filename'),\n        wbInteger('Flags', itU8, wbFlags([\n          'Has Collission Data'\n        ]))\n      ], cpNormal, True),\n      wbByteArray(MODT, 'Texture Files Hashes', 0, cpIgnore)\n    ], [], cpNormal, True)\n  ]);\n\n  wbRecord(IMGS, 'Image Space', [\n    wbEDIDReq,\n    wbStruct(DNAM, '', [\n      wbStruct('HDR', [\n        {00} wbFloat('Eye Adapt Speed'),\n        {04} wbFloat('Blur Radius'),\n        {08} wbFloat('Blur Passes'),\n        {12} wbFloat('Emissive Mult'),\n        {16} wbFloat('Target LUM'),\n        {20} wbFloat('Upper LUM Clamp'),\n        {24} wbFloat('Bright Scale'),\n        {28} wbFloat('Bright Clamp'),\n        {32} wbFloat('LUM Ramp No Tex'),\n        {36} wbFloat('LUM Ramp Min'),\n        {40} wbFloat('LUM Ramp Max'),\n        {44} wbFloat('Sunlight Dimmer'),\n        {48} wbFloat('Grass Dimmer'),\n        {52} wbFloat('Tree Dimmer'),\n        {56} wbUnion('Skin Dimmer', wbIMGSSkinDimmerDecider, [\n               wbFloat('Skin Dimmer'),\n               wbEmpty('Skin Dimmer', cpIgnore)\n             ])\n      ], cpNormal, False, nil, 14),\n      wbStruct('Bloom', [\n        {60} wbFloat('Blur Radius'),\n        {64} wbFloat('Alpha Mult Interior'),\n        {68} wbFloat('Alpha Mult Exterior')\n      ]),\n      wbStruct('Get Hit', [\n        {72} wbFloat('Blur Radius'),\n        {76} wbFloat('Blur Damping Constant'),\n        {80} wbFloat('Damping Constant')\n      ]),\n      wbStruct('Night Eye', [\n        wbStruct('Tint Color', [\n          {84} wbFloat('Red', cpNormal, False, 255, 0),\n          {88} wbFloat('Green', cpNormal, False, 255, 0),\n          {92} wbFloat('Blue', cpNormal, False, 255, 0)\n        ]),\n      {96} wbFloat('Brightness')\n      ]),\n      wbStruct('Cinematic', [\n        {100} wbFloat('Saturation'),\n        wbStruct('Contrast', [\n          {104} wbFloat('Avg Lum Value'),\n          {108} wbFloat('Value')\n        ]),\n        {112} wbFloat('Cinematic - Brightness - Value'),\n        wbStruct('Tint', [\n          wbStruct('Color', [\n            {116} wbFloat('Red', cpNormal, False, 255, 0),\n            {120} wbFloat('Green', cpNormal, False, 255, 0),\n            {124} wbFloat('Blue', cpNormal, False, 255, 0)\n          ]),\n        {128} wbFloat('Value')\n        ])\n      ]),\n      wbByteArray('Unused', 4),\n      wbByteArray('Unused', 4),\n      wbByteArray('Unused', 4),\n      wbByteArray('Unused', 4),\n      wbInteger('Flags', itU8, wbFlags([\n        'Saturation',\n        'Contrast',\n        'Tint',\n        'Brightness'\n      ], True)),\n      wbByteArray('Unused', 3)\n    ], cpNormal, True, nil, 5)\n  ]);\n\n  wbTimeInterpolator := wbStruct('Data', [\n    wbFloat('Time'),\n    wbFloat('Value')\n  ]);\n\n  wbColorInterpolator := wbStruct('Data', [\n    wbFloat('Time'),\n    wbFloat('Red', cpNormal, False, 255, 0),\n    wbFloat('Green', cpNormal, False, 255, 0),\n    wbFloat('Blue', cpNormal, False, 255, 0),\n    wbFloat('Alpha', cpNormal, False, 255, 0)\n  ]);\n\n  wbRecord(IMAD, 'Image Space Adapter', [\n    wbEDID,\n    wbStruct(DNAM, 'Data Count', [\n      wbInteger('Flags', itU32, wbFlags(['Animatable'])),\n      wbFloat('Duration'),\n      wbStruct('HDR', [\n        wbInteger('Eye Adapt Speed Mult', itU32),\n        wbInteger('Eye Adapt Speed Add', itU32),\n        wbInteger('Bloom Blur Radius Mult', itU32),\n        wbInteger('Bloom Blur Radius Add', itU32),\n        wbInteger('Bloom Threshold Mult', itU32),\n        wbInteger('Bloom Threshold Add', itU32),\n        wbInteger('Bloom Scale Mult', itU32),\n        wbInteger('Bloom Scale Add', itU32),\n        wbInteger('Target Lum Min Mult', itU32),\n        wbInteger('Target Lum Min Add', itU32),\n        wbInteger('Target Lum Max Mult', itU32),\n        wbInteger('Target Lum Max Add', itU32),\n        wbInteger('Sunlight Scale Mult', itU32),\n        wbInteger('Sunlight Scale Add', itU32),\n        wbInteger('Sky Scale Mult', itU32),\n        wbInteger('Sky Scale Add', itU32)\n      ]),\n      wbInteger('Unknown08 Mult', itU32),\n      wbInteger('Unknown48 Add', itU32),\n      wbInteger('Unknown09 Mult', itU32),\n      wbInteger('Unknown49 Add', itU32),\n      wbInteger('Unknown0A Mult', itU32),\n      wbInteger('Unknown4A Add', itU32),\n      wbInteger('Unknown0B Mult', itU32),\n      wbInteger('Unknown4B Add', itU32),\n      wbInteger('Unknown0C Mult', itU32),\n      wbInteger('Unknown4C Add', itU32),\n      wbInteger('Unknown0D Mult', itU32),\n      wbInteger('Unknown4D Add', itU32),\n      wbInteger('Unknown0E Mult', itU32),\n      wbInteger('Unknown4E Add', itU32),\n      wbInteger('Unknown0F Mult', itU32),\n      wbInteger('Unknown4F Add', itU32),\n      wbInteger('Unknown10 Mult', itU32),\n      wbInteger('Unknown50 Add', itU32),\n      wbStruct('Cinematic', [\n        wbInteger('Saturation Mult', itU32),\n        wbInteger('Saturation Add', itU32),\n        wbInteger('Brightness Mult', itU32),\n        wbInteger('Brightness Add', itU32),\n        wbInteger('Contrast Mult', itU32),\n        wbInteger('Contrast Add', itU32)\n      ]),\n      wbInteger('Unknown14 Mult', itU32),\n      wbInteger('Unknown54 Add', itU32),\n      wbInteger('Tint Color', itU32),\n      wbInteger('Blur Radius', itU32),\n      wbInteger('Double Vision Strength', itU32),\n      wbInteger('Radial Blur Strength', itU32),\n      wbInteger('Radial Blur Ramp Up', itU32),\n      wbInteger('Radial Blur Start', itU32),\n      wbInteger('Radial Blur Flags', itU32, wbFlags(['Use Target'])),\n      wbFloat('Radial Blur Center X'),\n      wbFloat('Radial Blur Center Y'),\n      wbInteger('DoF Strength', itU32),\n      wbInteger('DoF Distance', itU32),\n      wbInteger('DoF Range', itU32),\n      wbInteger('DoF Flags', itU32, wbFlags(['Use Target'])),\n      wbInteger('Radial Blur Ramp Down', itU32),\n      wbInteger('Radial Blur Down Start', itU32),\n      wbInteger('Fade Color', itU32),\n      wbInteger('Motion Blur Strength', itU32)\n    ], cpNormal, True, nil, 26),\n    wbArray(BNAM, 'Blur Radius', wbTimeInterpolator),\n    wbArray(VNAM, 'Double Vision Strength', wbTimeInterpolator),\n    wbArray(TNAM, 'Tint Color', wbColorInterpolator),\n    wbArray(NAM3, 'Fade Color', wbColorInterpolator),\n    wbArray(RNAM, 'Radial Blur Strength', wbTimeInterpolator),\n    wbArray(SNAM, 'Radial Blur Ramp Up', wbTimeInterpolator),\n    wbArray(UNAM, 'Radial Blur Start', wbTimeInterpolator),\n    wbArray(NAM1, 'Radial Blur Ramp Down', wbTimeInterpolator),\n    wbArray(NAM2, 'Radial Blur Down Start', wbTimeInterpolator),\n    wbArray(WNAM, 'DoF Strength', wbTimeInterpolator),\n    wbArray(XNAM, 'DoF Distance', wbTimeInterpolator),\n    wbArray(YNAM, 'DoF Range', wbTimeInterpolator),\n    wbArray(NAM4, 'Motion Blur Strength', wbTimeInterpolator),\n    wbRStruct('HDR', [\n      wbArray(_00_IAD, 'Eye Adapt Speed Mult', wbTimeInterpolator),\n      wbArray(_40_IAD, 'Eye Adapt Speed Add', wbTimeInterpolator),\n      wbArray(_01_IAD, 'Bloom Blur Radius Mult', wbTimeInterpolator),\n      wbArray(_41_IAD, 'Bloom Blur Radius Add', wbTimeInterpolator),\n      wbArray(_02_IAD, 'Bloom Threshold Mult', wbTimeInterpolator),\n      wbArray(_42_IAD, 'Bloom Threshold Add', wbTimeInterpolator),\n      wbArray(_03_IAD, 'Bloom Scale Mult', wbTimeInterpolator),\n      wbArray(_43_IAD, 'Bloom Scale Add', wbTimeInterpolator),\n      wbArray(_04_IAD, 'Target Lum Min Mult', wbTimeInterpolator),\n      wbArray(_44_IAD, 'Target Lum Min Add', wbTimeInterpolator),\n      wbArray(_05_IAD, 'Target Lum Max Mult', wbTimeInterpolator),\n      wbArray(_45_IAD, 'Target Lum Max Add', wbTimeInterpolator),\n      wbArray(_06_IAD, 'Sunlight Scale Mult', wbTimeInterpolator),\n      wbArray(_46_IAD, 'Sunlight Scale Add', wbTimeInterpolator),\n      wbArray(_07_IAD, 'Sky Scale Mult', wbTimeInterpolator),\n      wbArray(_47_IAD, 'Sky Scale Add', wbTimeInterpolator)\n    ], []),\n    wbUnknown(_08_IAD),\n    wbUnknown(_48_IAD),\n    wbUnknown(_09_IAD),\n    wbUnknown(_49_IAD),\n    wbUnknown(_0A_IAD),\n    wbUnknown(_4A_IAD),\n    wbUnknown(_0B_IAD),\n    wbUnknown(_4B_IAD),\n    wbUnknown(_0C_IAD),\n    wbUnknown(_4C_IAD),\n    wbUnknown(_0D_IAD),\n    wbUnknown(_4D_IAD),\n    wbUnknown(_0E_IAD),\n    wbUnknown(_4E_IAD),\n    wbUnknown(_0F_IAD),\n    wbUnknown(_4F_IAD),\n    wbUnknown(_10_IAD),\n    wbUnknown(_50_IAD),\n    wbRStruct('Cinematic', [\n      wbArray(_11_IAD, 'Saturation Mult', wbTimeInterpolator),\n      wbArray(_51_IAD, 'Saturation Add', wbTimeInterpolator),\n      wbArray(_12_IAD, 'Brightness Mult', wbTimeInterpolator),\n      wbArray(_52_IAD, 'Brightness Add', wbTimeInterpolator),\n      wbArray(_13_IAD, 'Contrast Mult', wbTimeInterpolator),\n      wbArray(_53_IAD, 'Contrast Add', wbTimeInterpolator)\n    ], []),\n    wbUnknown(_14_IAD),\n    wbUnknown(_54_IAD)\n  ]);\n\n  wbRecord(FLST, 'FormID List', [\n    wbString(EDID, 'Editor ID', 0, cpBenign, True, nil, wbFLSTEDIDAfterSet),\n    wbRArrayS('FormIDs', wbFormID(LNAM, 'FormID'), cpNormal, False, nil, nil, nil, wbFLSTLNAMIsSorted)\n  ]);\n\n  wbRecord(PERK, 'Perk', [\n    wbEDIDReq,\n    wbFULL,\n    wbDESCReq,\n    wbICON,\n    wbCTDAs,\n    wbStruct(DATA, 'Data', [\n      wbInteger('Trait', itU8, wbEnum(['No', 'Yes'])),\n      wbInteger('Min Level', itU8),\n      wbInteger('Ranks', itU8),\n      wbInteger('Playable', itU8, wbEnum(['No', 'Yes'])),\n      wbInteger('Hidden', itU8, wbEnum(['No', 'Yes']))\n    ], cpNormal, True, nil, 4),\n    wbRStructsSK('Effects', 'Effect', [0, 1], [\n      wbStructSK(PRKE, [1, 2, 0], 'Header', [\n        wbInteger('Type', itU8, wbEnum([\n          'Quest + Stage',\n          'Ability',\n          'Entry Point'\n        ]), cpNormal, False, nil, wbPERKPRKETypeAfterSet),\n        wbInteger('Rank', itU8),\n        wbInteger('Priority', itU8)\n      ]),\n      wbUnion(DATA, 'Effect Data', wbPerkDATADecider, [\n        wbStructSK([0, 1], 'Quest + Stage', [\n          wbFormIDCk('Quest', [QUST]),\n          wbInteger('Quest Stage', itU8, wbPerkDATAQuestStageToStr, wbCTDAParam2QuestStageToInt),\n          wbByteArray('Unused', 3)\n        ]),\n        wbFormIDCk('Ability', [SPEL]),\n        wbStructSK([0, 1], 'Entry Point', [\n          wbInteger('Entry Point', itU8, wbEnum([\n           {00} 'Calculate Weapon Damage',\n           {01} 'Calculate My Critical Hit Chance',\n           {02} 'Calculate My Critical Hit Damage',\n           {03} 'Calculate Weapon Attack AP Cost',\n           {04} 'Calculate Mine Explode Chance',\n           {05} 'Adjust Range Penalty',\n           {06} 'Adjust Limb Damage',\n           {07} 'Calculate Weapon Range',\n           {08} 'Calculate To Hit Chance',\n           {09} 'Adjust Experience Points',\n           {10} 'Adjust Gained Skill Points',\n           {11} 'Adjust Book Skill Points',\n           {12} 'Modify Recovered Health',\n           {13} 'Calculate Inventory AP Cost',\n           {14} 'Get Disposition',\n           {15} 'Get Should Attack',\n           {16} 'Get Should Assist',\n           {17} 'Calculate Buy Price',\n           {18} 'Get Bad Karma',\n           {19} 'Get Good Karma',\n           {20} 'Ignore Locked Terminal',\n           {21} 'Add Leveled List On Death',\n           {22} 'Get Max Carry Weight',\n           {23} 'Modify Addiction Chance',\n           {24} 'Modify Addiction Duration',\n           {25} 'Modify Positive Chem Duration',\n           {26} 'Adjust Drinking Radiation',\n           {27} 'Activate',\n           {28} 'Mysterious Stranger',\n           {29} 'Has Paralyzing Palm',\n           {30} 'Hacking Science Bonus',\n           {31} 'Ignore Running During Detection',\n           {32} 'Ignore Broken Lock',\n           {33} 'Has Concentrated Fire',\n           {34} 'Calculate Gun Spread',\n           {35} 'Player Kill AP Reward',\n           {36} 'Modify Enemy Critical Hit Chance'\n          ]), cpNormal, True, nil, wbPERKEntryPointAfterSet),\n          wbInteger('Function', itU8, wbPerkDATAFunctionToStr, wbPerkDATAFunctionToInt, cpNormal, False, nil, wbPerkDATAFunctionAfterSet),\n          wbInteger('Perk Condition Tab Count', itU8, nil, cpIgnore)\n        ])\n      ], cpNormal, True),\n      wbRStructsSK('Perk Conditions', 'Perk Condition', [0], [\n        wbInteger(PRKC, 'Run On', itS8, wbPRKCToStr, wbPRKCToInt),\n        wbCTDAsReq\n      ], [], cpNormal, False, nil, nil, wbPERKPRKCDontShow),\n      wbRStruct('Entry Point Function Parameters', [\n        wbInteger(EPFT, 'Type', itU8, wbPerkEPFTToStr, wbPerkEPFTToInt, cpIgnore, False, nil, wbPerkEPFTAfterSet),\n        wbUnion(EPFD, 'Data', wbEPFDDecider, [\n          wbByteArray('Unknown'),\n          wbFloat('Float'),\n          wbStruct('Float, Float', [\n            wbFloat('Float 1'),\n            wbFloat('Float 2')\n          ]),\n          wbFormIDCk('Leveled Item', [LVLI]),\n          wbEmpty('None (Script)'),\n          wbStruct('Actor Value, Float', [\n            wbInteger('Actor Value', itU32, wbEPFDActorValueToStr, wbEPFDActorValueToInt),\n            wbFloat('Float')\n          ])\n        ], cpNormal, False, wbEPFDDontShow),\n        wbString(EPF2, 'Button Label', 0, cpNormal, False, wbEPF2DontShow),\n        wbInteger(EPF3, 'Script Flags', itU16, wbFlags([\n          'Run Immediately'\n        ]), cpNormal, False, False, wbEPF2DontShow),\n        wbEmbeddedScriptPerk\n      ], [], cpNormal, False, wbPERKPRKCDontShow),\n      wbEmpty(PRKF, 'End Marker', cpIgnore, True)\n    ], [])\n  ]);\n\n  wbBPNDStruct := wbStruct(BPND, '', [\n    {00} wbFloat('Damage Mult'),\n    {04} wbInteger('Flags', itU8, wbFlags([\n      'Severable',\n      'IK Data',\n      'IK Data - Biped Data',\n      'Explodable',\n      'IK Data - Is Head',\n      'IK Data - Headtracking',\n      'To Hit Chance - Absolute'\n    ])),\n    {05} wbInteger('Part Type', itU8, wbEnum([\n           'Torso',\n           'Head 1',\n           'Head 2',\n           'Left Arm 1',\n           'Left Arm 2',\n           'Right Arm 1',\n           'Right Arm 2',\n           'Left Leg 1',\n           'Left Leg 2',\n           'Left Leg 3',\n           'Right Leg 1',\n           'Right Leg 2',\n           'Right Leg 3',\n           'Brain',\n           'Weapon'\n         ])),\n    {06} wbInteger('Health Percent', itU8),\n    {07} wbInteger('Actor Value', itS8, wbActorValueEnum),\n    {08} wbInteger('To Hit Chance', itU8),\n    {09} wbInteger('Explodable - Explosion Chance %', itU8),\n    {10} wbInteger('Explodable - Debris Count', itU16),\n    {12} wbFormIDCk('Explodable - Debris', [DEBR, NULL]),\n    {16} wbFormIDCk('Explodable - Explosion', [EXPL, NULL]),\n    {20} wbFloat('Tracking Max Angle'),\n    {24} wbFloat('Explodable - Debris Scale'),\n    {28} wbInteger('Severable - Debris Count', itS32),\n    {32} wbFormIDCk('Severable - Debris', [DEBR, NULL]),\n    {36} wbFormIDCk('Severable - Explosion', [EXPL, NULL]),\n    {40} wbFloat('Severable - Debris Scale'),\n    wbStruct('Gore Effects Positioning', [\n      wbStruct('Translate', [\n        {44} wbFloat('X'),\n        {48} wbFloat('Y'),\n        {52} wbFloat('Z')\n      ]),\n      wbStruct('Rotation', [\n        {56} wbFloat('X', cpNormal, True, wbRotationFactor, wbRotationScale, nil, RadiansNormalize),\n        {60} wbFloat('Y', cpNormal, True, wbRotationFactor, wbRotationScale, nil, RadiansNormalize),\n        {64} wbFloat('Z', cpNormal, True, wbRotationFactor, wbRotationScale, nil, RadiansNormalize)\n      ])\n    ]),\n    {68} wbFormIDCk('Severable - Impact DataSet', [IPDS, NULL]),\n    {72} wbFormIDCk('Explodable - Impact DataSet', [IPDS, NULL]),\n    {28} wbInteger('Severable - Decal Count', itU8),\n    {28} wbInteger('Explodable - Decal Count', itU8),\n    {76} wbByteArray('Unused', 2),\n    {80} wbFloat('Limb Replacement Scale')\n  ], cpNormal, True);\n\n  wbRecord(BPTD, 'Body Part Data', [\n    wbEDIDReq,\n    wbMODLReq,\n    wbRStructS('Body Parts', 'Body Part', [\n      wbString(BPTN, 'Part Name', 0, cpNormal, True),\n      wbString(BPNN, 'Part Node', 0, cpNormal, True),\n      wbString(BPNT, 'VATS Target', 0, cpNormal, True),\n      wbString(BPNI, 'IK Data - Start Node', 0, cpNormal, True),\n      wbBPNDStruct,\n      wbString(NAM1, 'Limb Replacement Model', 0, cpNormal, True),\n      wbString(NAM4, 'Gore Effects - Target Bone', 0, cpNormal, True),\n      wbByteArray(NAM5, 'Texture Files Hashes', 0, cpIgnore)\n    ], [], cpNormal, True),\n    wbFormIDCk(RAGA, 'Ragdoll', [RGDL])\n  ]);\n\n  wbRecord(ADDN, 'Addon Node', [\n    wbEDIDReq,\n    wbOBNDReq,\n    wbMODLReq,\n    wbInteger(DATA, 'Node Index', itS32, nil, cpNormal, True),\n    wbFormIDCk(SNAM, 'Sound', [SOUN]),\n    wbStruct(DNAM, 'Data', [\n      wbInteger('Master Particle System Cap', itU16),\n      wbByteArray('Unknown', 2)\n    ], cpNormal, True)\n  ]);\n\n  wbRecord(AVIF, 'ActorValue Information', [\n    wbEDIDReq,\n    wbFULL,\n    wbDESCReq,\n    wbICON,\n    wbString(ANAM, 'Short Name')\n  ]);\n\n  wbRecord(RADS, 'Radiation Stage', [\n    wbEDIDReq,\n    wbStruct(DATA, '', [\n      wbInteger('Trigger Threshold', itU32),\n      wbFormIDCk('Actor Effect', [SPEL])\n    ], cpNormal, True)\n  ]);\n\n  wbRecord(CAMS, 'Camera Shot', [\n    wbEDIDReq,\n    wbMODL,\n    wbStruct(DATA, 'Data', [\n      {00} wbInteger('Action', itU32, wbEnum([\n        'Shoot',\n        'Fly',\n        'Hit',\n        'Zoom'\n      ])),\n      {04} wbInteger('Location', itU32, wbEnum([\n        'Attacker',\n        'Projectile',\n        'Target'\n      ])),\n      {08} wbInteger('Target', itU32, wbEnum([\n        'Attacker',\n        'Projectile',\n        'Target'\n      ])),\n      {12} wbInteger('Flags', itU32, wbFlags([\n        'Position Follows Location',\n        'Rotation Follows Target',\n        'Don''t Follow Bone',\n        'First Person Camera',\n        'No Tracer',\n        'Start At Time Zero'\n      ])),\n      wbStruct('Time Multipliers', [\n        {16} wbFloat('Player'),\n        {20} wbFloat('Target'),\n        {24} wbFloat('Global')\n      ]),\n      {28} wbFloat('Max Time'),\n      {32} wbFloat('Min Time'),\n      {36} wbFloat('Target % Between Actors')\n    ], cpNormal, True, nil, 7),\n    wbFormIDCk(MNAM, 'Image Space Modifier', [IMAD])\n  ]);\n\n  wbRecord(CPTH, 'Camera Path', [\n    wbEDIDReq,\n    wbCTDAs,\n    wbArray(ANAM, 'Related Camera Paths', wbFormIDCk('Related Camera Path', [CPTH, NULL]), ['Parent', 'Previous Sibling'], cpNormal, True),\n    wbInteger(DATA, 'Camera Zoom', itU8, wbEnum([\n      'Default',\n      'Disable',\n      'Shot List'\n    ]), cpNormal, True),\n    wbRArray('Camera Shots', wbFormIDCk(SNAM, 'Camera Shot', [CAMS]))\n  ]);\n\n  wbRecord(VTYP, 'Voice Type', [\n    wbEDIDReq,\n    wbInteger(DNAM, 'Flags', itU8, wbFlags([\n      'Allow Default Dialog',\n      'Female'\n    ]), cpNormal, True)\n  ]);\n\n  wbRecord(IPCT, 'Impact', [\n    wbEDIDReq,\n    wbMODL,\n    wbStruct(DATA, '', [\n      wbFloat('Effect - Duration'),\n      wbInteger('Effect - Orientation', itU32, wbEnum([\n        'Surface Normal',\n        'Projectile Vector',\n        'Projectile Reflection'\n      ])),\n      wbFloat('Angle Threshold'),\n      wbFloat('Placement Radius'),\n      wbInteger('Sound Level', itU32, wbSoundLevelEnum),\n      wbInteger('Flags', itU32, wbFlags([\n        'No Decal Data'\n      ]))\n    ], cpNormal, True),\n    wbDODT,\n    wbFormIDCk(DNAM, 'Texture Set', [TXST]),\n    wbFormIDCk(SNAM, 'Sound 1', [SOUN]),\n    wbFormIDCk(NAM1, 'Sound 2', [SOUN])\n  ]);\n\n  wbRecord(IPDS, 'Impact DataSet', [\n    wbEDIDReq,\n    wbStruct(DATA, 'Impacts', [\n      wbFormIDCk('Stone', [IPCT, NULL]),\n      wbFormIDCk('Dirt', [IPCT, NULL]),\n      wbFormIDCk('Grass', [IPCT, NULL]),\n      wbFormIDCk('Glass', [IPCT, NULL]),\n      wbFormIDCk('Metal', [IPCT, NULL]),\n      wbFormIDCk('Wood', [IPCT, NULL]),\n      wbFormIDCk('Organic', [IPCT, NULL]),\n      wbFormIDCk('Cloth', [IPCT, NULL]),\n      wbFormIDCk('Water', [IPCT, NULL]),\n      wbFormIDCk('Hollow Metal', [IPCT, NULL]),\n      wbFormIDCk('Organic Bug', [IPCT, NULL]),\n      wbFormIDCk('Organic Glow', [IPCT, NULL])\n    ], cpNormal, True, nil, 9)\n  ]);\n\n  wbRecord(ECZN, 'Encounter Zone', [\n    wbEDIDReq,\n    wbStruct(DATA, '', [\n      wbFormIDCkNoReach('Owner', [NPC_, FACT, NULL]),\n      wbInteger('Rank', itS8),\n      wbInteger('Minimum Level', itS8),\n      wbInteger('Flags', itU8, wbFlags([\n        'Never Resets',\n        'Match PC Below Minimum Level'\n      ])),\n      wbByteArray('Unused', 1)\n    ], cpNormal, True)\n  ]);\n\n  wbRecord(MESG, 'Message', [\n    wbEDIDReq,\n    wbDESCReq,\n    wbFULL,\n    wbFormIDCk(INAM, 'Icon', [MICN, NULL], False, cpNormal, True),\n    wbByteArray(NAM0, 'Unused', 0, cpIgnore),\n    wbByteArray(NAM1, 'Unused', 0, cpIgnore),\n    wbByteArray(NAM2, 'Unused', 0, cpIgnore),\n    wbByteArray(NAM3, 'Unused', 0, cpIgnore),\n    wbByteArray(NAM4, 'Unused', 0, cpIgnore),\n    wbByteArray(NAM5, 'Unused', 0, cpIgnore),\n    wbByteArray(NAM6, 'Unused', 0, cpIgnore),\n    wbByteArray(NAM7, 'Unused', 0, cpIgnore),\n    wbByteArray(NAM8, 'Unused', 0, cpIgnore),\n    wbByteArray(NAM9, 'Unused', 0, cpIgnore),\n    wbInteger(DNAM, 'Flags', itU32, wbFlags([\n      'Message Box',\n      'Auto Display'\n    ]), cpNormal, True, False, nil, wbMESGDNAMAfterSet),\n    wbInteger(TNAM, 'Display Time', itU32, nil, cpNormal, False, False, wbMESGTNAMDontShow),\n    wbRStructs('Menu Buttons', 'Menu Button', [\n      wbString(ITXT, 'Button Text'),\n      wbCTDAs\n    ], [])\n  ], False, nil, cpNormal, False, wbMESGAfterLoad);\n\n  wbRecord(RGDL, 'Ragdoll', [\n    wbEDIDReq,\n    wbInteger(NVER, 'Version', itU32, nil, cpNormal, True),\n    wbStruct(DATA, 'General Data', [\n      wbInteger('Dynamic Bone Count', itU32),\n      wbByteArray('Unused', 4),\n      wbStruct('Enabled', [\n        wbInteger('Feedback', itU8, wbEnum(['No', 'Yes'])),\n        wbInteger('Foot IK (broken, don''t use)', itU8, wbEnum(['No', 'Yes'])),\n        wbInteger('Look IK (broken, don''t use)', itU8, wbEnum(['No', 'Yes'])),\n        wbInteger('Grab IK (broken, don''t use)', itU8, wbEnum(['No', 'Yes'])),\n        wbInteger('Pose Matching', itU8, wbEnum(['No', 'Yes']))\n      ]),\n      wbByteArray('Unused', 1)\n    ], cpNormal, True),\n    wbFormIDCk(XNAM, 'Actor Base', [CREA, NPC_], False, cpNormal, True),\n    wbFormIDCk(TNAM, 'Body Part Data', [BPTD], False, cpNormal, True),\n    wbStruct(RAFD, 'Feedback Data', [\n    {00} wbFloat('Dynamic/Keyframe Blend Amount'),\n    {04} wbFloat('Hierarchy Gain'),\n    {08} wbFloat('Position Gain'),\n    {12} wbFloat('Velocity Gain'),\n    {16} wbFloat('Acceleration Gain'),\n    {20} wbFloat('Snap Gain'),\n    {24} wbFloat('Velocity Damping'),\n         wbStruct('Snap Max Settings', [\n           {28} wbFloat('Linear Velocity'),\n           {32} wbFloat('Angular Velocity'),\n           {36} wbFloat('Linear Distance'),\n           {40} wbFloat('Angular Distance')\n         ]),\n         wbStruct('Position Max Velocity', [\n           {44} wbFloat('Linear'),\n           {48} wbFloat('Angular')\n         ]),\n         wbStruct('Position Max Velocity', [\n           {52} wbInteger('Projectile', itS32, wbDiv(1000)),\n           {56} wbInteger('Melee', itS32, wbDiv(1000))\n         ])\n    ], cpNormal, False),\n    wbArray(RAFB, 'Feedback Dynamic Bones', wbInteger('Bone', itU16), 0, nil, nil, cpNormal, False),\n    wbStruct(RAPS, 'Pose Matching Data', [\n    {00} wbArray('Match Bones', wbInteger('Bone', itU16, wbHideFFFF), 3),\n    {06} wbInteger('Flags', itU8, wbFlags([\n           'Disable On Move'\n         ])),\n    {07} wbByteArray('Unused', 1),\n    {08} wbFloat('Motors Strength'),\n    {12} wbFloat('Pose Activation Delay Time'),\n    {16} wbFloat('Match Error Allowance'),\n    {20} wbFloat('Displacement To Disable')\n    ], cpNormal, True),\n    wbString(ANAM, 'Death Pose')\n  ]);\n\n  wbRecord(DOBJ, 'Default Object Manager', [\n    wbEDIDReq,\n    wbArray(DATA, 'Default Objects', wbFormID('Default Object'), [\n      'Stimpack',\n      'SuperStimpack',\n      'RadX',\n      'RadAway',\n      'Morphine',\n      'Perk Paralysis',\n      'Player Faction',\n      'Mysterious Stranger NPC',\n      'Mysterious Stranger Faction',\n      'Default Music',\n      'Battle Music',\n      'Death Music',\n      'Success Music',\n      'Level Up Music',\n      'Player Voice (Male)',\n      'Player Voice (Male Child)',\n      'Player Voice (Female)',\n      'Player Voice (Female Child)',\n      'Eat Package Default Food',\n      'Every Actor Ability',\n      'Drug Wears Off Image Space'\n    ], cpNormal, True)\n  ]);\n\n  wbRecord(LGTM, 'Lighting Template', [\n    wbEDIDReq,\n    wbStruct(DATA, 'Lighting', [\n      wbStruct('Ambient Color', [\n        wbInteger('Red', itU8),\n        wbInteger('Green', itU8),\n        wbInteger('Blue', itU8),\n        wbByteArray('Unused', 1)\n      ]),\n      wbStruct('Directional Color', [\n        wbInteger('Red', itU8),\n        wbInteger('Green', itU8),\n        wbInteger('Blue', itU8),\n        wbByteArray('Unused', 1)\n      ]),\n      wbStruct('Fog Color', [\n        wbInteger('Red', itU8),\n        wbInteger('Green', itU8),\n        wbInteger('Blue', itU8),\n        wbByteArray('Unused', 1)\n      ]),\n      wbFloat('Fog Near'),\n      wbFloat('Fog Far'),\n      wbInteger('Directional Rotation XY', itS32),\n      wbInteger('Directional Rotation Z', itS32),\n      wbFloat('Directional Fade'),\n      wbFloat('Fog Clip Dist'),\n      wbFloat('Fog Power')\n    ], cpNormal, True)\n  ]);\n\n  wbRecord(MUSC, 'Music Type', [\n    wbEDIDReq,\n    wbString(FNAM, 'Filename')\n  ]);\n\n  wbRecord(GRAS, 'Grass', [\n    wbEDIDReq,\n    wbOBNDReq,\n    wbMODLReq,\n    wbStruct(DATA, '', [\n      wbInteger('Density', itU8),\n      wbInteger('Min Slope', itU8),\n      wbInteger('Max Slope', itU8),\n      wbByteArray('Unused', 1),\n      wbInteger('Unit from water amount', itU16),\n      wbByteArray('Unused', 2),\n      wbInteger('Unit from water type', itU32, wbEnum([\n        'Above - At Least',\n        'Above - At Most',\n        'Below - At Least',\n        'Below - At Most',\n        'Either - At Least',\n        'Either - At Most',\n        'Either - At Most Above',\n        'Either - At Most Below'\n      ])),\n      wbFloat('Position Range'),\n      wbFloat('Height Range'),\n      wbFloat('Color Range'),\n      wbFloat('Wave Period'),\n      wbInteger('Flags', itU8, wbFlags([\n        'Vertex Lighting',\n        'Uniform Scaling',\n        'Fit to Slope'\n      ])),\n      wbByteArray('Unused', 3)\n    ], cpNormal, True)\n  ]);\n\n  wbRecord(HAIR, 'Hair', [\n    wbEDIDReq,\n    wbFULLReq,\n    wbMODLReq,\n    wbString(ICON, 'Texture', 0, cpNormal, True),\n    wbInteger(DATA, 'Flags', itU8, wbFlags([\n      'Playable',\n      'Not Male',\n      'Not Female',\n      'Fixed'\n    ]), cpNormal, True)\n  ]);\n\n  wbRecord(IDLE, 'Idle Animation', [\n    wbEDID,\n    wbMODLReq,\n    wbCTDAs,\n    wbArray(ANAM, 'Related Idle Animations', wbFormIDCk('Related Idle Animation', [IDLE, NULL]), ['Parent', 'Previous Sibling'], cpNormal, True),\n    wbStruct(DATA, '', [\n      wbInteger('Animation Group Section', itU8, wbIdleAnam),\n      wbStruct('Looping', [\n        wbInteger('Min', itU8),\n        wbInteger('Max', itU8)\n      ]),\n      wbByteArray('Unused', 1),\n      wbInteger('Replay Delay', itS16),\n      wbInteger('Flags', itU8, wbFlags([\n        'No attacking'\n      ])),\n      wbByteArray('Unused', 1)\n    ], cpNormal, True, nil, 4)\n  ]);\n\n  wbRecord(INFO, 'Dialog response', [\n    wbStruct(DATA, '', [\n      wbInteger('Type', itU8, wbEnum([\n        {0} 'Topic',\n        {1} 'Conversation',\n        {2} 'Combat',\n        {3} 'Persuasion',\n        {4} 'Detection',\n        {5} 'Service',\n        {6} 'Miscellaneous',\n        {7} 'Radio'\n      ])),\n      wbInteger('Next Speaker', itU8, wbEnum([\n        {0} 'Target',\n        {1} 'Self',\n        {2} 'Either'\n      ])),\n      wbInteger('Flags 1', itU8, wbFlags([\n        {0x01} 'Goodbye',\n        {0x02} 'Random',\n        {0x04} 'Say Once',\n        {0x08} 'Run Immediately',\n        {0x10} 'Info Refusal',\n        {0x20} 'Random End',\n        {0x40} 'Run for Rumors',\n        {0x80} 'Speech Challenge'\n      ])),\n      wbInteger('Flags 2', itU8, wbFlags([\n        {0x01} 'Say Once a Day',\n        {0x02} 'Always Darken'\n      ]))\n    ], cpNormal, True, nil, 3),\n    wbFormIDCkNoReach(QSTI, 'Quest', [QUST], False, cpNormal, True),\n    wbFormIDCk(TPIC, 'Topic', [DIAL]),\n    wbFormIDCkNoReach(PNAM, 'Previous INFO', [INFO, NULL]),\n    wbRArray('Add Topics', wbFormIDCk(NAME, 'Topic', [DIAL])),\n    wbRArray('Responses',\n      wbRStruct('Response', [\n        wbStruct(TRDT, 'Response Data', [\n          wbInteger('Emotion Type', itU32, wbEnum([\n            {0} 'Neutral',\n            {1} 'Anger',\n            {2} 'Disgust',\n            {3} 'Fear',\n            {4} 'Sad',\n            {5} 'Happy',\n            {6} 'Surprise',\n            {7} 'Pained'\n          ])),\n          wbInteger('Emotion Value', itS32),\n          wbByteArray('Unused', 4),\n          wbInteger('Response number', itU8),\n          wbByteArray('Unused', 3),\n          wbFormIDCk('Sound', [SOUN, NULL]),\n          wbInteger('Flags', itU8, wbFlags([\n            'Use Emotion Animation'\n          ])),\n          wbByteArray('Unused', 3)\n        ], cpNormal, False, nil, 5),\n        wbStringKC(NAM1, 'Response Text', 0, cpTranslate, True),\n        wbString(NAM2, 'Script Notes', 0, cpTranslate, True),\n        wbString(NAM3, 'Edits'),\n        wbFormIDCk(SNAM, 'Speaker Animation', [IDLE]),\n        wbFormIDCk(LNAM, 'Listener Animation', [IDLE])\n      ], [])\n    ),\n    wbCTDAs,\n    wbRArray('Choices', wbFormIDCk(TCLT, 'Choice', [DIAL])),\n    wbRArray('Link From', wbFormIDCk(TCLF, 'Topic', [DIAL])),\n    wbRStruct('Script (Begin)', [\n      wbEmbeddedScriptReq\n    ], [], cpNormal, True),\n    wbRStruct('Script (End)', [\n      wbEmpty(NEXT, 'Marker'),\n      wbEmbeddedScriptReq\n    ], [], cpNormal, True),\n    wbFormIDCk(SNDD, 'Unused', [SOUN]),\n    wbString(RNAM, 'Prompt'),\n    wbFormIDCk(ANAM, 'Speaker', [CREA, NPC_]),\n    wbFormIDCk(KNAM, 'ActorValue/Perk', [AVIF, PERK]),\n    wbInteger(DNAM, 'Speech Challenge', itU32, wbEnum([\n      '---',\n      'Very Easy',\n      'Easy',\n      'Average',\n      'Hard',\n      'Very Hard'\n    ]))\n  ], False, wbINFOAddInfo, cpNormal, False, wbINFOAfterLoad);\n\n  wbRecord(INGR, 'Ingredient', [\n    wbEDIDReq,\n    wbOBNDReq,\n    wbFULL,\n    wbMODL,\n    wbICON,\n    wbSCRI,\n    wbETYPReq,\n    wbFloat(DATA, 'Weight', cpNormal, True),\n    wbStruct(ENIT, 'Effect Data', [\n      wbInteger('Value', itS32),\n      wbInteger('Flags', itU8, wbFlags(['No auto-calculation', 'Food item'])),\n      wbByteArray('Unused', 3)\n    ], cpNormal, True),\n    wbEffectsReq\n  ]);\n\n  wbRecord(KEYM, 'Key', [\n    wbEDIDReq,\n    wbOBNDReq,\n    wbFULLReq,\n    wbMODL,\n    wbICONReq,\n    wbSCRI,\n    wbDEST,\n    wbYNAM,\n    wbZNAM,\n    wbStruct(DATA, '', [\n      wbInteger('Value', itS32),\n      wbFloat('Weight')\n    ], cpNormal, True)\n  ]);\n\n  wbQuadrantEnum := wbEnum([\n    {0} 'Bottom Left',\n    {1} 'Bottom Right',\n    {2} 'Top Left',\n    {3} 'Top Right'\n  ]);\n\n  if wbSimpleRecords then begin\n\n    wbRecord(LAND, 'Landscape', [\n      wbByteArray(DATA, 'Unknown'),\n      wbByteArray(VNML, 'Vertex Normals'),\n      wbByteArray(VHGT, 'Vertext Height Map'),\n      wbByteArray(VCLR, 'Vertex Colours'),\n\n      wbRArrayS('Layers', wbRUnion('Layer', [\n        wbRStructSK([0],'Base Layer', [\n          wbStructSK(BTXT, [1, 3], 'Base Layer Header', [\n            wbFormIDCk('Texture', [LTEX, NULL]),\n            wbInteger('Quadrant', itU8, wbQuadrantEnum),\n            wbByteArray('Unused', 1),\n            wbInteger('Layer', itS16)\n          ])\n        ], []),\n        wbRStructSK([0],'Alpha Layer', [\n          wbStructSK(ATXT, [1, 3], 'Alpha Layer Header', [\n            wbFormIDCk('Texture', [LTEX, NULL]),\n            wbInteger('Quadrant', itU8, wbQuadrantEnum),\n            wbByteArray('Unused', 1),\n            wbInteger('Layer', itS16)\n          ]),\n          wbByteArray(VTXT, 'Alpha Layer Data')\n        ], [])\n      ], [])),\n\n      wbArray(VTEX, 'Textures', wbFormIDCk('Texture', [LTEX, NULL]))\n    ]);\n\n  end else begin\n\n    wbRecord(LAND, 'Landscape', [\n      wbByteArray(DATA, 'Unknown'),\n      wbArray(VNML, 'Vertex Normals', wbStruct('Row', [\n        wbArray('Columns', wbStruct('Column', [\n          wbInteger('X', itU8),\n          wbInteger('Y', itU8),\n          wbInteger('Z', itU8)\n        ]), 33)\n      ]), 33),\n      wbStruct(VHGT, 'Vertext Height Map', [\n        wbFloat('Offset'),\n        wbArray('Rows', wbStruct('Row', [\n          wbArray('Columns', wbInteger('Column', itU8), 33)\n        ]), 33),\n        wbByteArray('Unused', 3)\n      ]),\n      wbArray(VCLR, 'Vertex Colours', wbStruct('Row', [\n        wbArray('Columns', wbStruct('Column', [\n          wbInteger('X', itU8),\n          wbInteger('Y', itU8),\n          wbInteger('Z', itU8)\n        ]), 33)\n      ]), 33),\n\n      wbRArrayS('Layers', wbRUnion('Layer', [\n        wbRStructSK([0],'Base Layer', [\n          wbStructSK(BTXT, [1, 3], 'Base Layer Header', [\n            wbFormIDCk('Texture', [LTEX, NULL]),\n            wbInteger('Quadrant', itU8, wbQuadrantEnum),\n            wbByteArray('Unused', 1),\n            wbInteger('Layer', itS16)\n          ])\n        ], []),\n        wbRStructSK([0],'Alpha Layer', [\n          wbStructSK(ATXT, [1, 3], 'Alpha Layer Header', [\n            wbFormIDCk('Texture', [LTEX, NULL]),\n            wbInteger('Quadrant', itU8, wbQuadrantEnum),\n            wbByteArray('Unused', 1),\n            wbInteger('Layer', itS16)\n          ]),\n          wbArrayS(VTXT, 'Alpha Layer Data', wbStructSK([0], 'Cell', [\n            wbInteger('Position', itU16, wbAtxtPosition),\n            wbByteArray('Unused', 2),\n            wbFloat('Opacity')\n          ]))\n        ], [])\n      ], [])),\n\n      wbArray(VTEX, 'Textures', wbFormIDCk('Texture', [LTEX, NULL]))\n    ]);\n\n  end;\n\n  wbRecord(LIGH, 'Light', [\n    wbEDIDReq,\n    wbOBNDReq,\n    wbMODL,\n    wbSCRI,\n    wbDEST,\n    wbFULL,\n    wbICON,\n    wbStruct(DATA, '', [\n      wbInteger('Time', itS32),\n      wbInteger('Radius', itU32),\n      wbStruct('Color', [\n        wbInteger('Red', itU8),\n        wbInteger('Green', itU8),\n        wbInteger('Blue', itU8),\n        wbInteger('Unused', itU8)\n      ]),\n      wbInteger('Flags', itU32, wbFlags([\n        {0x00000001} 'Dynamic',\n        {0x00000002} 'Can be Carried',\n        {0x00000004} 'Negative',\n        {0x00000008} 'Flicker',\n        {0x00000010} 'Unused',\n        {0x00000020} 'Off By Default',\n        {0x00000040} 'Flicker Slow',\n        {0x00000080} 'Pulse',\n        {0x00000100} 'Pulse Slow',\n        {0x00000200} 'Spot Light',\n        {0x00000400} 'Spot Shadow'\n      ])),\n      wbFloat('Falloff Exponent'),\n      wbFloat('FOV'),\n      wbInteger('Value', itU32),\n      wbFloat('Weight')\n    ], cpNormal, True),\n    wbFloat(FNAM, 'Fade value', cpNormal, True),\n    wbFormIDCk(SNAM, 'Sound', [SOUN])\n  ], False, nil, cpNormal, False, wbLIGHAfterLoad);\n\n  wbRecord(LSCR, 'Load Screen', [\n    wbEDIDReq,\n    wbICONReq,\n    wbDESCReq,\n    wbRArrayS('Locations', wbStructSK(LNAM, [0, 1], 'Location', [\n      wbFormIDCkNoReach('Cell', [CELL, WRLD]),\n      wbByteArray('Unused', 8)\n    ]))\n  ]);\n\n  wbRecord(LTEX, 'Landscape Texture', [\n    wbEDIDReq,\n    wbICON,\n    wbFormIDCk(TNAM, 'Texture', [TXST], False, cpNormal, True),\n    wbStruct(HNAM, 'Havok Data', [\n      wbInteger('Material Type', itU8, wbEnum([\n        {00} 'STONE',\n        {01} 'CLOTH',\n        {02} 'DIRT',\n        {03} 'GLASS',\n        {04} 'GRASS',\n        {05} 'METAL',\n        {06} 'ORGANIC',\n        {07} 'SKIN',\n        {08} 'WATER',\n        {09} 'WOOD',\n        {10} 'HEAVY STONE',\n        {11} 'HEAVY METAL',\n        {12} 'HEAVY WOOD',\n        {13} 'CHAIN',\n        {14} 'SNOW',\n        {15} 'ELEVATOR',\n        {16} 'HOLLOW METAL',\n        {17} 'SHEET METAL',\n        {18} 'SAND',\n        {19} 'BRIKEN CONCRETE',\n        {20} 'VEHILCE BODY',\n        {21} 'VEHILCE PART SOLID',\n        {22} 'VEHILCE PART HOLLOW',\n        {23} 'BARREL',\n        {24} 'BOTTLE',\n        {25} 'SODA CAN',\n        {26} 'PISTOL',\n        {27} 'RIFLE',\n        {28} 'SHOPPING CART',\n        {29} 'LUNCHBOX',\n        {30} 'BABY RATTLE',\n        {31} 'RUBER BALL'\n      ])),\n      wbInteger('Friction', itU8),\n      wbInteger('Restitution', itU8)\n    ], cpNormal, True),\n    wbInteger(SNAM, 'Texture Specular Exponent', itU8, nil, cpNormal, True),\n    wbRArrayS('Grasses', wbFormIDCk(GNAM, 'Grass', [GRAS]))\n  ]);\n\n  wbRecord(LVLC, 'Leveled Creature', [\n    wbEDIDReq,\n    wbOBNDReq,\n    wbInteger(LVLD, 'Chance none', itU8, nil, cpNormal, True),\n    wbInteger(LVLF, 'Flags', itU8, wbFlags([\n      {0x01} 'Calculate from all levels <= player''s level',\n      {0x02} 'Calculate for each item in count'\n    ]), cpNormal, True),\n    wbRArrayS('Leveled List Entries',\n      wbRStructExSK([0], [1], 'Leveled List Entry', [\n        wbStructExSK(LVLO , [0, 2], [3], 'Base Data', [\n          wbInteger('Level', itS16),\n          wbByteArray('Unused', 2),\n          wbFormIDCk('Reference', [CREA, LVLC]),\n          wbInteger('Count', itS16),\n          wbByteArray('Unused', 2)\n        ]),\n        wbCOED\n      ], []),\n    cpNormal, True),\n    wbMODL\n  ]);\n\n  wbRecord(LVLN, 'Leveled NPC', [\n    wbEDIDReq,\n    wbOBNDReq,\n    wbInteger(LVLD, 'Chance none', itU8, nil, cpNormal, True),\n    wbInteger(LVLF, 'Flags', itU8, wbFlags([\n      {0x01} 'Calculate from all levels <= player''s level',\n      {0x02} 'Calculate for each item in count'\n    ]), cpNormal, True),\n    wbRArrayS('Leveled List Entries',\n      wbRStructExSK([0], [1], 'Leveled List Entry', [\n        wbStructExSK(LVLO , [0, 2], [3], 'Base Data', [\n          wbInteger('Level', itS16),\n          wbByteArray('Unused', 2),\n          wbFormIDCk('Reference', [NPC_, LVLN]),\n          wbInteger('Count', itS16),\n          wbByteArray('Unused', 2)\n        ]),\n        wbCOED\n      ], []),\n    cpNormal, True),\n    wbMODL\n  ]);\n\n   wbRecord(LVLI, 'Leveled Item', [\n    wbEDIDReq,\n    wbOBNDReq,\n    wbInteger(LVLD, 'Chance none', itU8, nil, cpNormal, True),\n    wbInteger(LVLF, 'Flags', itU8, wbFlags([\n      {0x01} 'Calculate from all levels <= player''s level',\n      {0x02} 'Calculate for each item in count',\n      {0x04} 'Use All'\n    ]), cpNormal, True),\n    wbFormIDCk(LVLG, 'Global', [GLOB]),\n    wbRArrayS('Leveled List Entries',\n      wbRStructExSK([0], [1], 'Leveled List Entry', [\n        wbStructExSK(LVLO , [0, 2], [3], 'Base Data', [\n          wbInteger('Level', itS16),\n          wbByteArray('Unused', 2),\n          wbFormIDCk('Reference', [ARMO, AMMO, MISC, WEAP, BOOK, LVLI, KEYM, ALCH, NOTE]),\n          wbInteger('Count', itS16),\n          wbByteArray('Unused', 2)\n        ]),\n        wbCOED\n      ], [])\n    )\n  ]);\n\n  wbArchtypeEnum := wbEnum([\n    {00} 'Value Modifier',\n    {01} 'Script',\n    {02} 'Dispel',\n    {03} 'Cure Disease',\n    {04} '',\n    {05} '',\n    {06} '',\n    {07} '',\n    {08} '',\n    {09} '',\n    {10} '',\n    {11} 'Invisibility',\n    {12} 'Chameleon',\n    {13} 'Light',\n    {14} '',\n    {15} '',\n    {16} 'Lock',\n    {17} 'Open',\n    {18} 'Bound Item',\n    {19} 'Summon Creature',\n    {20} '',\n    {21} '',\n    {22} '',\n    {23} '',\n    {24} 'Paralysis',\n    {25} '',\n    {26} '',\n    {27} '',\n    {28} '',\n    {29} '',\n    {30} 'Cure Paralysis',\n    {31} 'Cure Addiction',\n    {32} 'Cure Poison',\n    {33} 'Concussion',\n    {34} 'Value And Parts'\n  ]);\n\n  wbRecord(MGEF, 'Base Effect', [\n    wbEDIDReq,\n    wbFULL,\n    wbDESCReq,\n    wbICON,\n    wbMODL,\n    wbStruct(DATA, 'Data', [\n      wbInteger('Flags', itU32, wbFlags([\n        {0x00000001} 'Hostile',\n        {0x00000002} 'Recover',\n        {0x00000004} 'Detrimental',\n        {0x00000008} '',\n        {0x00000010} 'Self',\n        {0x00000020} 'Touch',\n        {0x00000040} 'Target',\n        {0x00000080} 'No Duration',\n        {0x00000100} 'No Magnitude',\n        {0x00000200} 'No Area',\n        {0x00000400} 'FX Persist',\n        {0x00000800} '',\n        {0x00001000} 'Gory Visuals',\n        {0x00002000} 'Display Name Only',\n        {0x00004000} '',\n        {0x00008000} 'Radio Broadcast ??',\n        {0x00010000} '',\n        {0x00020000} '',\n        {0x00040000} '',\n        {0x00080000} 'Use skill',\n        {0x00100000} 'Use attribute',\n        {0x00200000} '',\n        {0x00400000} '',\n        {0x00800000} '',\n        {0x01000000} 'Painless',\n        {0x02000000} 'Spray projectile type (or Fog if Bolt is specified as well)',\n        {0x04000000} 'Bolt projectile type (or Fog if Spray is specified as well)',\n        {0x08000000} 'No Hit Effect',\n        {0x10000000} 'No Death Dispel',\n        {0x20000000} '????'\n      ])),\n      {04} wbFloat('Base cost (Unused)'),\n      {08} wbUnion('Assoc. Item', wbMGEFFAssocItemDecider, [\n             wbFormID('Unused', cpIgnore),\n             wbFormID('Assoc. Item'),\n             wbFormIDCk('Assoc. Script', [SCPT, NULL]), //Script\n             wbFormIDCk('Assoc. Item', [WEAP, ARMO, NULL]), //Bound Item\n             wbFormIDCk('Assoc. Creature', [CREA]) //Summon Creature\n           ], cpNormal, false, nil, wbMGEFFAssocItemAfterSet),\n      {12} wbInteger('Magic School (Unused)', itS32, wbEnum([\n      ], [\n        -1, 'None'\n      ])),\n      {16} wbInteger('Resistance Type', itS32, wbActorValueEnum),\n      {20} wbInteger('Counter effect count', itU16),\n      {22} wbByteArray('Unused', 2),\n      {24} wbFormIDCk('Light', [LIGH, NULL]),\n      {28} wbFloat('Projectile speed'),\n      {32} wbFormIDCk('Effect Shader', [EFSH, NULL]),\n      {36} wbFormIDCk('Object Display Shader', [EFSH, NULL]),\n      {40} wbFormIDCk('Effect sound', [NULL, SOUN]),\n      {44} wbFormIDCk('Bolt sound', [NULL, SOUN]),\n      {48} wbFormIDCk('Hit sound', [NULL, SOUN]),\n      {52} wbFormIDCk('Area sound', [NULL, SOUN]),\n      {56} wbFloat('Constant Effect enchantment factor  (Unused)'),\n      {60} wbFloat('Constant Effect barter factor (Unused)'),\n      {64} wbInteger('Archtype', itU32, wbArchtypeEnum, cpNormal, False, nil, wbMGEFArchtypeAfterSet),\n      {68} wbActorValue\n    ], cpNormal, True),\n    wbRArrayS('Counter Effects', wbFormIDCk(ESCE, 'Effect', [MGEF]), cpNormal, False, nil, wbCounterEffectsAfterSet)\n  ], False, nil, cpNormal, False, wbMGEFAfterLoad, wbMGEFAfterSet);\n\n  wbRecord(MISC, 'Misc. Item', [\n    wbEDIDReq,\n    wbOBNDReq,\n    wbFULL,\n    wbMODL,\n    wbICON,\n    wbSCRI,\n    wbDEST,\n    wbYNAM,\n    wbZNAM,\n    wbStruct(DATA, '', [\n      wbInteger('Value', itS32),\n      wbFloat('Weight')\n    ], cpNormal, True)\n  ]);\n\n  wbRecord(COBJ, 'Constructible Object', [\n    wbEDID,\n    wbOBND,\n    wbFULL,\n    wbMODL,\n    wbICON,\n    wbSCRI,\n    wbYNAM,\n    wbZNAM,\n    wbStruct(DATA, '', [\n      wbInteger('Value', itS32),\n      wbFloat('Weight')\n    ], cpNormal, True)\n  ]);\n\n  wbFaceGen := wbRStruct('FaceGen Data', [\n    wbByteArray(FGGS, 'FaceGen Geometry-Symmetric', 0, cpNormal, True),\n    wbByteArray(FGGA, 'FaceGen Geometry-Asymmetric', 0, cpNormal, True),\n    wbByteArray(FGTS, 'FaceGen Texture-Symmetric', 0, cpNormal, True)\n  ], [], cpNormal, True);\n\n  wbFaceGenNPC := wbRStruct('FaceGen Data', [\n    wbByteArray(FGGS, 'FaceGen Geometry-Symmetric', 0, cpNormal, True),\n    wbByteArray(FGGA, 'FaceGen Geometry-Asymmetric', 0, cpNormal, True),\n    wbByteArray(FGTS, 'FaceGen Texture-Symmetric', 0, cpNormal, True)\n  ], [], cpNormal, True, wbActorTemplateUseModelAnimation);\n\n\n  wbRecord(NPC_, 'Non-Player Character', [\n    wbEDIDReq,\n    wbOBNDReq,\n    wbFULLActor,\n    wbMODLActor,\n    wbStruct(ACBS, 'Configuration', [\n      {00} wbInteger('Flags', itU32, wbFlags([\n             {0x000001} 'Female',\n             {0x000002} 'Essential',\n             {0x000004} 'Is CharGen Face Preset',\n             {0x000008} 'Respawn',\n             {0x000010} 'Auto-calc stats',\n             {0x000020} '',\n             {0x000040} '',\n             {0x000080} 'PC Level Mult',\n             {0x000100} 'Use Template',\n             {0x000200} 'No Low Level Processing',\n             {0x000400} '',\n             {0x000800} 'No Blood Spray',\n             {0x001000} 'No Blood Decal',\n             {0x002000} '',\n             {0x004000} '',\n             {0x008000} '',\n             {0x010000} '',\n             {0x020000} '',\n             {0x040000} '',\n             {0x080000} '',\n             {0x100000} 'No VATS Melee',\n           {0x00200000} '',\n           {0x00400000} 'Can be all races',\n           {0x00800000} '',\n           {0x01000000} '',\n           {0x02000000} '',\n           {0x03000000} 'No Knockdowns',\n           {0x08000000} 'Not Pushable',\n           {0x10000000} '', {28}\n           {0x20000000} '',\n           {0x40000000} 'No Rotating To Head-track',\n           {0x80000000} ''\n           ], [\n             {0x000001 Female} wbActorTemplateUseTraits,\n             {0x000002 Essential} wbActorTemplateUseBaseData,\n             {0x000004 Is CharGen Face Preset} nil,\n             {0x000008 Respawn} wbActorTemplateUseBaseData,\n             {0x000010 Auto-calc stats} wbActorTemplateUseStats,\n             {0x000020 } nil,\n             {0x000040 } nil,\n             {0x000080 PC Level Mult} wbActorTemplateUseStats,\n             {0x000100 Use Template} nil,\n             {0x000200 No Low Level Processing} wbActorTemplateUseBaseData,\n             {0x000400 } nil,\n             {0x000800 No Blood Spray} wbActorTemplateUseModelAnimation,\n             {0x001000 No Blood Decal} wbActorTemplateUseModelAnimation,\n             {0x002000 } nil,\n             {0x004000 } nil,\n             {0x008000 } nil,\n             {0x010000 } nil,\n             {0x020000 } nil,\n             {0x040000 } nil,\n             {0x080000 } nil,\n             {0x100000 No VATS Melee} nil,\n           {0x00200000 } nil,\n           {0x00400000 Can be all races} nil,\n           {0x00800000 } nil,\n           {0x01000000 } nil,\n           {0x02000000 } nil,\n           {0x03000000 No Knockdowns} nil,\n           {0x08000000 Not Pushable} wbActorTemplateUseModelAnimation,\n           {0x10000000 } nil,\n           {0x20000000 } nil,\n           {0x40000000 No Rotating To Head-track} wbActorTemplateUseModelAnimation,\n           {0x80000000 } nil\n           ])),\n      {04} wbInteger('Fatigue', itU16, nil, cpNormal, True, wbActorTemplateUseStats),\n      {06} wbInteger('Barter gold', itU16, nil, cpNormal, False, wbActorTemplateUseAIData),\n      {08} wbUnion('Level', wbCreaLevelDecider, [\n             wbInteger('Level', itS16, nil, cpNormal, True, wbActorTemplateUseStats),\n             wbInteger('Level Mult', itS16, wbDiv(1000), cpNormal, True, wbActorTemplateUseStats)\n           ], cpNormal, True, wbActorTemplateUseStats),\n      {10} wbInteger('Calc min', itU16, nil, cpNormal, True, wbActorTemplateUseStats),\n      {12} wbInteger('Calc max', itU16, nil, cpNormal, True, wbActorTemplateUseStats),\n      {14} wbInteger('Speed Multiplier', itU16, nil, cpNormal, True, wbActorTemplateUseStats),\n      {16} wbFloat('Karma (Alignment)', cpNormal, False, 1, -1, wbActorTemplateUseTraits),\n      {20} wbInteger('Disposition Base', itS16, nil, cpNormal, False, wbActorTemplateUseTraits),\n      {22} wbInteger('Template Flags', itU16, wbTemplateFlags)\n    ], cpNormal, True),\n    wbRArrayS('Factions',\n      wbStructSK(SNAM, [0], 'Faction', [\n        wbFormIDCk('Faction', [FACT]),\n        wbInteger('Rank', itU8),\n        wbByteArray('Unused', 3)\n      ]),\n    cpNormal, False, nil, nil, wbActorTemplateUseFactions),\n    wbFormIDCk(INAM, 'Death item', [LVLI], False, cpNormal, False, wbActorTemplateUseTraits),\n    wbFormIDCk(VTCK, 'Voice', [VTYP], False, cpNormal, True, wbActorTemplateUseTraits),\n    wbFormIDCk(TPLT, 'Template', [LVLN, NPC_]),\n    wbFormIDCk(RNAM, 'Race', [RACE], False, cpNormal, True, wbActorTemplateUseTraits),\n    wbSPLOs,\n    wbFormIDCk(EITM, 'Unarmed Attack Effect', [ENCH, SPEL], False, cpNormal, False, wbActorTemplateUseActorEffectList),\n    wbInteger(EAMT, 'Unarmed Attack Animation', itU16, wbAttackAnimationEnum, cpNormal, True, False, wbActorTemplateUseActorEffectList),\n    wbDESTActor,\n    wbSCRIActor,\n    wbRArrayS('Items', wbCNTO, cpNormal, False, nil, nil, wbActorTemplateUseInventory),\n    wbAIDT,\n    wbRArray('Packages', wbFormIDCk(PKID, 'Package', [PACK]), cpNormal, False, nil, nil, wbActorTemplateUseAIPackages),\n    wbArrayS(KFFZ, 'Animations', wbStringLC('Animation'), 0, cpNormal, False, nil, nil, wbActorTemplateUseModelAnimation),\n    wbFormIDCk(CNAM, 'Class', [CLAS], False, cpNormal, True, wbActorTemplateUseTraits),\n    wbStruct(DATA, '', [\n      {00} wbInteger('Base Health', itS32),\n      {04} wbArray('Attributes', wbInteger('Attribute', itU8), [\n            'Strength',\n            'Perception',\n            'Endurance',\n            'Charisma',\n            'Intelligence',\n            'Agility',\n            'Luck'\n          ], cpNormal, False, wbActorAutoCalcDontShow),\n          wbByteArray('Unused'{, 14 - only present in old record versions})\n    ], cpNormal, True, wbActorTemplateUseStats),\n    wbStruct(DNAM, '', [\n      {00} wbArray('Skill Values', wbInteger('Skill', itU8), [\n             'Barter',\n             'Big Guns',\n             'Energy Weapons',\n             'Explosives',\n             'Lockpick',\n             'Medicine',\n             'Melee Weapons',\n             'Repair',\n             'Science',\n             'Small Guns',\n             'Sneak',\n             'Speech',\n             'Throwing (unused)',\n             'Unarmed'\n           ]),\n      {14} wbArray('Skill Offsets', wbInteger('Skill', itU8), [\n             'Barter',\n             'Big Guns',\n             'Energy Weapons',\n             'Explosives',\n             'Lockpick',\n             'Medicine',\n             'Melee Weapons',\n             'Repair',\n             'Science',\n             'Small Guns',\n             'Sneak',\n             'Speech',\n             'Throwing (unused)',\n             'Unarmed'\n           ])\n    ], cpNormal, False, wbActorTemplateUseStatsAutoCalc),\n    wbRArrayS('Head Parts',\n      wbFormIDCk(PNAM, 'Head Part', [HDPT]),\n    cpNormal, False, nil, nil, wbActorTemplateUseModelAnimation),\n    wbFormIDCk(HNAM, 'Hair', [HAIR], False, cpNormal, False, wbActorTemplateUseModelAnimation),\n    wbFloat(LNAM, 'Hair length', cpNormal, False, 1, -1, wbActorTemplateUseModelAnimation),\n    wbFormIDCk(ENAM, 'Eyes', [EYES], False, cpNormal, False, wbActorTemplateUseModelAnimation),\n    wbStruct(HCLR, 'Hair color', [\n      wbInteger('Red', itU8),\n      wbInteger('Green', itU8),\n      wbInteger('Blue', itU8),\n      wbByteArray('Unused', 1)\n    ], cpNormal, True, wbActorTemplateUseModelAnimation),\n    wbFormIDCk(ZNAM, 'Combat Style', [CSTY], False, cpNormal, False, wbActorTemplateUseTraits),\n    wbInteger(NAM4, 'Impact Material Type', itU32, wbImpactMaterialTypeEnum, cpNormal, True, False, wbActorTemplateUseModelAnimation),\n    wbFaceGenNPC,\n    wbInteger(NAM5, 'Unknown', itU16, nil, cpNormal, True, False, nil, nil, 255),\n    wbFloat(NAM6, 'Height', cpNormal, True, 1, -1, wbActorTemplateUseTraits),\n    wbFloat(NAM7, 'Weight', cpNormal, True, 1, -1, wbActorTemplateUseTraits)\n  ], True, nil, cpNormal, False, wbNPCAfterLoad);\n\n  wbPKDTFlags := wbFlags([\n          {0x00000001} 'Offers Services',\n          {0x00000002} 'Must reach location',\n          {0x00000004} 'Must complete',\n          {0x00000008} 'Lock doors at package start',\n          {0x00000010} 'Lock doors at package end',\n          {0x00000020} 'Lock doors at location',\n          {0x00000040} 'Unlock doors at package start',\n          {0x00000080} 'Unlock doors at package end',\n          {0x00000100} 'Unlock doors at location',\n          {0x00000200} 'Continue if PC near',\n          {0x00000400} 'Once per day',\n          {0x00000800} '',\n          {0x00001000} 'Skip fallout behavior',\n          {0x00002000} 'Always run',\n          {0x00004000} '',\n          {0x00008000} '',\n          {0x00010000} '',\n          {0x00020000} 'Always sneak',\n          {0x00040000} 'Allow swimming',\n          {0x00080000} 'Allow falls',\n          {0x00100000} 'Head-Tracking off',\n          {0x00200000} 'Weapons unequipped',\n          {0x00400000} 'Defensive combat',\n          {0x00800000} 'Weapon Drawn',\n          {0x01000000} 'No idle anims',\n          {0x02000000} 'Pretend In Combat',\n          {0x04000000} 'Continue During Combat',\n          {0x08000000} 'No Combat Alert',\n          {0x10000000} 'No Warn/Attack Behaviour',\n          {0x20000000} '',\n          {0x40000000} '',\n          {0x80000000} ''\n        ]);\n\n  wbPKDTType := wbEnum([\n           {0} 'Find',\n           {1} 'Follow',\n           {2} 'Escort',\n           {3} 'Eat',\n           {4} 'Sleep',\n           {5} 'Wander',\n           {6} 'Travel',\n           {7} 'Accompany',\n           {8} 'Use Item At',\n           {9} 'Ambush',\n          {10} 'Flee Not Combat',\n          {11} '',\n          {12} 'Sandbox',\n          {13} 'Patrol',\n          {14} 'Guard',\n          {15} 'Dialogue',\n          {16} 'Use Weapon'\n        ]);\n\n  wbObjectTypeEnum := wbEnum([\n          ' NONE',\n          'Activators',\n          'Armor',\n          'Books',\n          'Clothing',\n          'Containers',\n          'Doors',\n          'Ingredients',\n          'Lights',\n          'Misc',\n          'Flora',\n          'Furniture',\n          'Weapons: Any',\n          'Ammo',\n          'NPCs',\n          'Creatures',\n          'Keys',\n          'Alchemy',\n          'Food',\n          ' All: Combat Wearable',\n          ' All: Wearable',\n          'Weapons: Ranged',\n          'Weapons: Melee',\n          'Weapons: NONE',\n          'Actor Effects: Any',\n          'Actor Effects: Range Target',\n          'Actor Effects: Range Touch',\n          'Actor Effects: Range Self',\n          '',\n          'Actors: Any'\n        ]);\n\n\n  wbPKDTSpecificFlagsUnused := True;\n\n  wbRecord(PACK, 'Package', [\n    wbEDIDReq,\n    wbStruct(PKDT, 'General', [\n      wbInteger('General Flags', itU32, wbPKDTFlags),\n      wbInteger('Type', itU8, wbPKDTType),\n      wbByteArray('Unused', 1),\n      wbInteger('Fallout Behavior Flags', itU16, wbFlags([\n        {0x00000001}'Hellos To Player',\n        {0x00000002}'Random Conversations',\n        {0x00000004}'Observe Combat Behavior',\n        {0x00000008}'Unknown 4',\n        {0x00000010}'Reaction To Player Actions',\n        {0x00000020}'Friendly Fire Comments',\n        {0x00000040}'Aggro Radius Behavior',\n        {0x00000080}'Allow Idle Chatter',\n        {0x00000100}'Avoid Radiation'\n      ], True)),\n      wbUnion('Type Specific Flags', wbPKDTSpecificFlagsDecider, [\n        wbEmpty('Type Specific Flags (missing)', cpIgnore, False, nil, True),\n        wbInteger('Type Specific Flags - Find', itU16, wbFlags([\n          {0x00000001}'',\n          {0x00000002}'',\n          {0x00000004}'',\n          {0x00000008}'',\n          {0x00000010}'',\n          {0x00000020}'',\n          {0x00000040}'',\n          {0x00000080}'',\n          {0x00000100}'Find - Allow Buying',\n          {0x00000200}'Find - Allow Killing',\n          {0x00000400}'Find - Allow Stealing'\n        ], wbPKDTSpecificFlagsUnused)),\n        wbInteger('Type Specific Flags - Follow', itU16, wbFlags([], wbPKDTSpecificFlagsUnused)),\n        wbInteger('Type Specific Flags - Escort', itU16, wbFlags([\n          {0x00000001}'',\n          {0x00000002}'',\n          {0x00000004}'',\n          {0x00000008}'',\n          {0x00000010}'',\n          {0x00000020}'',\n          {0x00000040}'',\n          {0x00000080}'',\n          {0x00000100}'Escort - Allow Buying',\n          {0x00000200}'Escort - Allow Killing',\n          {0x00000400}'Escort - Allow Stealing'\n        ], wbPKDTSpecificFlagsUnused)),\n        wbInteger('Type Specific Flags - Eat', itU16, wbFlags([\n          {0x00000001}'',\n          {0x00000002}'',\n          {0x00000004}'',\n          {0x00000008}'',\n          {0x00000010}'',\n          {0x00000020}'',\n          {0x00000040}'',\n          {0x00000080}'',\n          {0x00000100}'Eat - Allow Buying',\n          {0x00000200}'Eat - Allow Killing',\n          {0x00000400}'Eat - Allow Stealing'\n        ], wbPKDTSpecificFlagsUnused)),\n        wbInteger('Type Specific Flags - Sleep', itU16, wbFlags([], wbPKDTSpecificFlagsUnused)),\n        wbInteger('Type Specific Flags - Wander', itU16, wbFlags([\n          {0x00000001}'Wander - No Eating',\n          {0x00000002}'Wander - No Sleeping',\n          {0x00000004}'Wander - No Conversation',\n          {0x00000008}'Wander - No Idle Markers',\n          {0x00000010}'Wander - No Furniture',\n          {0x00000020}'Wander - No Wandering'\n        ], wbPKDTSpecificFlagsUnused)),\n        wbInteger('Type Specific Flags - Travel', itU16, wbFlags([], wbPKDTSpecificFlagsUnused)),\n        wbInteger('Type Specific Flags - Accompany', itU16, wbFlags([], wbPKDTSpecificFlagsUnused)),\n        wbInteger('Type Specific Flags - Use Item At', itU16, wbFlags([\n          {0x00000001}'',\n          {0x00000002}'Use Item At - Sit Down',\n          {0x00000004}'',\n          {0x00000008}'',\n          {0x00000010}'',\n          {0x00000020}'',\n          {0x00000040}'',\n          {0x00000080}'',\n          {0x00000100}'Use Item At - Allow Buying',\n          {0x00000200}'Use Item At - Allow Killing',\n          {0x00000400}'Use Item At - Allow Stealing'\n        ], wbPKDTSpecificFlagsUnused)),\n        wbInteger('Type Specific Flags - Ambush', itU16, wbFlags([\n          {0x00000001}'Ambush - Hide While Ambushing'\n        ], wbPKDTSpecificFlagsUnused)),\n        wbInteger('Type Specific Flags - Flee Not Combat', itU16, wbFlags([], wbPKDTSpecificFlagsUnused)),\n        wbInteger('Type Specific Flags - ?', itU16, wbFlags([], wbPKDTSpecificFlagsUnused)),\n        wbInteger('Type Specific Flags - Sandbox', itU16, wbFlags([\n          {0x00000001}'Sandbox - No Eating',\n          {0x00000002}'Sandbox - No Sleeping',\n          {0x00000004}'Sandbox - No Conversation',\n          {0x00000008}'Sandbox - No Idle Markers',\n          {0x00000010}'Sandbox - No Furniture',\n          {0x00000020}'Sandbox - No Wandering'\n        ], wbPKDTSpecificFlagsUnused)),\n        wbInteger('Type Specific Flags - Patrol', itU16, wbFlags([], wbPKDTSpecificFlagsUnused)),\n        wbInteger('Type Specific Flags - Guard', itU16, wbFlags([\n          {0x00000001}'',\n          {0x00000002}'',\n          {0x00000004}'Guard - Remain Near Reference to Guard'\n        ], wbPKDTSpecificFlagsUnused)),\n        wbInteger('Type Specific Flags - Dialogue', itU16, wbFlags([], wbPKDTSpecificFlagsUnused)),\n        wbInteger('Type Specific Flags - Use Weapon', itU16, wbFlags([], wbPKDTSpecificFlagsUnused))\n      ]),\n      wbByteArray('Unused', 2)\n    ], cpNormal, True, nil, 2),\n    wbRStruct('Locations', [\n      wbStruct(PLDT, 'Location 1', [\n        wbInteger('Type', itS32, wbEnum([     // Byte + filler\n          {0} 'Near reference',\n          {1} 'In cell',\n          {2} 'Near current location',\n          {3} 'Near editor location',\n          {4} 'Object ID',\n          {5} 'Object Type',\n          {6} 'Near linked reference',\n          {7} 'At package location'\n        ])),\n        wbUnion('Location', wbPxDTLocationDecider, [\n          wbFormIDCkNoReach('Reference', [REFR, PGRE, PMIS, PBEA, ACHR, ACRE, PLYR], True),\n          wbFormIDCkNoReach('Cell', [CELL]),\n          wbByteArray('Unused', 4, cpIgnore),\n          wbByteArray('Unused', 4, cpIgnore),\n          wbFormIDCkNoReach('Object ID', [ACTI, DOOR, STAT, FURN, CREA, SPEL, NPC_, CONT, ARMO, AMMO, MISC, WEAP, BOOK, KEYM, ALCH, LIGH]),\n          wbInteger('Object Type', itU32, wbObjectTypeEnum),\n          wbByteArray('Unused', 4, cpIgnore),\n          wbByteArray('Unused', 4, cpIgnore)\n        ]),\n        wbInteger('Radius', itS32)\n      ]),\n      wbStruct(PLD2, 'Location 2', [\n        wbInteger('Type', itS32, wbEnum([\n          {0} 'Near reference',\n          {1} 'In cell',\n          {2} 'Near current location',\n          {3} 'Near editor location',\n          {4} 'Object ID',\n          {5} 'Object Type',\n          {6} 'Near linked reference',\n          {7} 'At package location'\n        ])),\n        wbUnion('Location', wbPxDTLocationDecider, [\n          wbFormIDCkNoReach('Reference', [REFR, PGRE, PMIS, PBEA, ACHR, ACRE, PLYR], True),\n          wbFormIDCkNoReach('Cell', [CELL]),\n          wbByteArray('Unused', 4, cpIgnore),\n          wbByteArray('Unused', 4, cpIgnore),\n          wbFormIDCkNoReach('Object ID', [ACTI, DOOR, STAT, FURN, CREA, SPEL, NPC_, CONT, ARMO, AMMO, MISC, WEAP, BOOK, KEYM, ALCH, LIGH]),\n          wbInteger('Object Type', itU32, wbObjectTypeEnum),\n          wbByteArray('Unused', 4, cpIgnore),\n          wbByteArray('Unused', 4, cpIgnore)\n        ]),\n        wbInteger('Radius', itS32)\n      ])\n    ], []),\n    wbStruct(PSDT, 'Schedule', [\n      wbInteger('Month', itS8),\n      wbInteger('Day of week', itS8, wbEnum([\n        'Sunday',\n        'Monday',\n        'Tuesday',\n        'Wednesday',\n        'Thursday',\n        'Friday',\n        'Saturday',\n        'Weekdays',\n        'Weekends',\n        'Monday, Wednesday, Friday',\n        'Tuesday, Thursday'\n      ], [\n        -1, 'Any'\n      ])),\n      wbInteger('Date', itU8),\n      wbInteger('Time', itS8),\n      wbInteger('Duration', itS32)\n    ], cpNormal, True),\n    wbStruct(PTDT, 'Target 1', [\n      wbInteger('Type', itS32, wbEnum([\n        {0} 'Specific Reference',\n        {1} 'Object ID',\n        {2} 'Object Type',\n        {3} 'Linked Reference'\n      ]), cpNormal, False, nil, nil, 2),\n      wbUnion('Target', wbPxDTLocationDecider, [\n        wbFormIDCkNoReach('Reference', [ACHR, ACRE, REFR, PGRE, PMIS, PBEA, PLYR], True),\n        wbFormIDCkNoReach('Object ID', [ACTI, DOOR, STAT, FURN, CREA, SPEL, NPC_, LVLN, LVLC, CONT, ARMO, AMMO, MISC, WEAP, BOOK, KEYM, ALCH, LIGH, FACT, FLST]),\n        wbInteger('Object Type', itU32, wbObjectTypeEnum),\n        wbByteArray('Unused', 4, cpIgnore)\n      ]),\n      wbInteger('Count / Distance', itS32),\n      wbFloat('Unknown')\n    ], cpNormal, False, nil, 3),\n    wbCTDAs,\n    wbRStruct('Idle Animations', [\n      wbInteger(IDLF, 'Flags', itU8, wbFlags([\n        'Run in Sequence',\n        '',\n        'Do Once'\n      ]), cpNormal, True),\n      wbStruct(IDLC, '', [\n        wbInteger( 'Animation Count', itU8),\n        wbByteArray('Unused', 3)\n      ], cpNormal, True, nil, 1),\n      wbFloat(IDLT, 'Idle Timer Setting', cpNormal, True),\n      wbArray(IDLA, 'Animations', wbFormIDCk('Animation', [IDLE]), 0, nil, wbIDLAsAfterSet, cpNormal, True),\n      wbByteArray(IDLB, 'Unused', 4, cpIgnore)\n    ], [], cpNormal, False, nil, False, nil {cannot be totally removed , wbAnimationsAfterSet}),\n    wbFormIDCk(CNAM, 'Combat Style', [CSTY]),\n    wbEmpty(PKED, 'Eat Marker'),\n    wbInteger(PKE2, 'Escort Distance', itU32),\n    wbFloat(PKFD, 'Follow - Start Location - Trigger Radius'),\n    wbStruct(PKPT, 'Patrol Flags', [\n      wbInteger('Repeatable', itU8, wbEnum(['No', 'Yes']), cpNormal, False, nil, nil, 1),\n      wbByteArray('Unused', 1)\n    ], cpNormal, False, nil, 1),\n    wbStruct(PKW3, 'Use Weapon Data', [\n      wbInteger('Flags', itU32, wbFlags([\n        'Always Hit',\n        '',\n        '',\n        '',\n        '',\n        '',\n        '',\n        '',\n        'Do No Damage',\n        '',\n        '',\n        '',\n        '',\n        '',\n        '',\n        '',\n        'Crouch To Reload',\n        '',\n        '',\n        '',\n        '',\n        '',\n        '',\n        '',\n        'Hold Fire When Blocked'\n      ])),\n      wbInteger('Fire Rate', itU8, wbEnum([\n        'Auto Fire',\n        'Volley Fire'\n      ])),\n      wbInteger('Fire Count', itU8, wbEnum([\n        'Number of Bursts',\n        'Repeat Fire'\n      ])),\n      wbInteger('Number of Bursts', itU16),\n      wbStruct('Shoots Per Volleys', [\n        wbInteger('Min', itU16),\n        wbInteger('Max', itU16)\n      ]),\n      wbStruct('Pause Between Volleys', [\n        wbFloat('Min'),\n        wbFloat('Max')\n      ]),\n      wbByteArray('Unused', 4)\n    ]),\n    wbStruct(PTD2, 'Target 2', [\n      wbInteger('Type', itS32, wbEnum([\n        {0} 'Specific reference',\n        {1} 'Object ID',\n        {2} 'Object Type',\n        {3} 'Linked Reference'\n      ])),\n      wbUnion('Target', wbPxDTLocationDecider, [\n        wbFormIDCkNoReach('Reference', [ACHR, ACRE, REFR, PGRE, PMIS, PBEA, PLYR], True),\n        wbFormIDCkNoReach('Object ID', [ACTI, DOOR, STAT, FURN, CREA, SPEL, NPC_, LVLN, LVLC, CONT, ARMO, AMMO, MISC, WEAP, BOOK, KEYM, ALCH, LIGH, FACT, FLST]),\n        wbInteger('Object Type', itU32, wbObjectTypeEnum),\n        wbByteArray('Unused', 4, cpIgnore)\n      ]),\n      wbInteger('Count / Distance', itS32),\n      wbFloat('Unknown')\n    ], cpNormal, False, nil, 3),\n    wbEmpty(PUID, 'Use Item Marker'),\n    wbEmpty(PKAM, 'Ambush Marker'),\n    wbStruct(PKDD, 'Dialogue Data', [\n      wbFloat('FOV'),\n      wbFormIDCk('Topic', [DIAL, NULL]),\n      wbInteger('Flags', itU32, wbFlags([\n        'No Headtracking',\n        '',\n        '',\n        '',\n        '',\n        '',\n        '',\n        '',\n        'Don''t Control Target Movement'\n      ])),\n      wbByteArray('Unused', 4),\n      wbInteger('Dialogue Type', itU32, wbEnum([\n        'Conversation',\n        'Say To'\n      ])),\n      wbByteArray('Unknown', 4)\n    ], cpNormal, False, nil, 3),\n    wbStruct(PLD2, 'Location 2 (again??)', [\n      wbInteger('Type', itS32, wbEnum([\n        {0} 'Near reference',\n        {1} 'In cell',\n        {2} 'Near current location',\n        {3} 'Near editor location',\n        {4} 'Object ID',\n        {5} 'Object Type',\n        {6} 'Near linked reference',\n        {7} 'At package location'\n      ])),\n      wbUnion('Location', wbPxDTLocationDecider, [\n        wbFormIDCkNoReach('Reference', [REFR, PGRE, PMIS, PBEA, ACHR, ACRE, PLYR], True),\n        wbFormIDCkNoReach('Cell', [CELL]),\n        wbByteArray('Unused', 4, cpIgnore),\n        wbByteArray('Unused', 4, cpIgnore),\n        wbFormIDCkNoReach('Object ID', [ACTI, DOOR, STAT, FURN, CREA, SPEL, NPC_, CONT, ARMO, AMMO, MISC, WEAP, BOOK, KEYM, ALCH, LIGH]),\n        wbInteger('Object Type', itU32, wbObjectTypeEnum),\n        wbByteArray('Unused', 4, cpIgnore),\n        wbByteArray('Unused', 4, cpIgnore)\n      ]),\n      wbInteger('Radius', itS32)\n    ]),\n    wbRStruct('OnBegin', [\n      wbEmpty(POBA, 'OnBegin Marker', cpNormal, True),\n      wbFormIDCk(INAM, 'Idle', [IDLE, NULL], False, cpNormal, True),\n      wbEmbeddedScriptReq,\n      wbFormIDCk(TNAM, 'Topic', [DIAL, NULL], False, cpNormal, True)\n    ], [], cpNormal, True),\n    wbRStruct('OnEnd', [\n      wbEmpty(POEA, 'OnEnd Marker', cpNormal, True),\n      wbFormIDCk(INAM, 'Idle', [IDLE, NULL], False, cpNormal, True),\n      wbEmbeddedScriptReq,\n      wbFormIDCk(TNAM, 'Topic', [DIAL, NULL], False, cpNormal, True)\n    ], [], cpNormal, True),\n    wbRStruct('OnChange', [\n      wbEmpty(POCA, 'OnChange Marker', cpNormal, True),\n      wbFormIDCk(INAM, 'Idle', [IDLE, NULL], False, cpNormal, True),\n      wbEmbeddedScriptReq,\n      wbFormIDCk(TNAM, 'Topic', [DIAL, NULL], False, cpNormal, True)\n    ], [], cpNormal, True)\n  ], False, nil, cpNormal, False, wbPACKAfterLoad);\n\n  wbRecord(QUST, 'Quest', [\n    wbEDIDReq,\n    wbSCRI,\n    wbFULL,\n    wbICON,\n    wbStruct(DATA, 'General', [\n      wbInteger('Flags', itU8, wbFlags([\n        {0x01} 'Start game enabled',\n        {0x02} '',\n        {0x04} 'Allow repeated conversation topics',\n        {0x08} 'Allow repeated stages',\n        {0x10} 'Unknown 4'\n      ])),\n      wbInteger('Priority', itU8),\n      wbByteArray('Unused', 2),\n      wbFloat('Quest Delay')\n    ], cpNormal, True, nil, 3),\n    wbCTDAs,\n    wbRArrayS('Stages', wbRStructSK([0], 'Stage', [\n      wbInteger(INDX, 'Stage Index', itS16),\n      wbRArray('Log Entries', wbRStruct('Log Entry', [\n        wbInteger(QSDT, 'Stage Flags', itU8, wbFlags([\n          {0x01} 'Complete Quest',\n          {0x02} 'Fail Quest'\n        ])),\n        wbCTDAs,\n        wbString(CNAM, 'Log Entry', 0, cpTranslate),\n        wbEmbeddedScriptReq,\n        wbFormIDCk(NAM0, 'Next Quest', [QUST])\n      ], []))\n    ], [])),\n    wbRArray('Objectives', wbRStruct('Objective', [\n      wbInteger(QOBJ, 'Objective Index', itS32),\n      wbString(NNAM, 'Description', 0, cpNormal, True),\n      wbRArray('Targets', wbRStruct('Target', [\n        wbStruct(QSTA, 'Target', [\n          wbFormIDCkNoReach('Target', [REFR, PGRE, PMIS, PBEA, ACRE, ACHR], True),\n          wbInteger('Flags', itU8, wbFlags([\n            {0x01} 'Compass Marker Ignores Locks'\n          ])),\n          wbByteArray('Unused', 3)\n        ]),\n        wbCTDAs\n      ], []))\n    ], []))\n  ]);\n\n  wbHeadPartIndexEnum := wbEnum([\n    'Head',\n    'Ears',\n    'Mouth',\n    'Teeth Lower',\n    'Teeth Upper',\n    'Tongue',\n    'Left Eye',\n    'Right Eye'\n  ]);\n\n  wbBodyPartIndexEnum := wbEnum([\n    'Upper Body',\n    'Left Hand',\n    'Right Hand',\n    'Upper Body Texture'\n  ]);\n\n  wbRecord(RACE, 'Race', [\n    wbEDIDReq,\n    wbFULLReq,\n    wbDESCReq,\n    wbXNAMs,\n    wbStruct(DATA, '', [\n      wbArrayS('Skill Boosts', wbStructSK([0], 'Skill Boost', [\n        wbInteger('Skill', itS8, wbActorValueEnum),\n        wbInteger('Boost', itS8)\n      ]), 7),\n      wbByteArray('Unused', 2),\n      wbFloat('Male Height'),\n      wbFloat('Female Height'),\n      wbFloat('Male Weight'),\n      wbFloat('Female Weight'),\n      wbInteger('Flags', itU32, wbFlags([\n        'Playable',\n        '',\n        'Child'\n      ]))\n    ], cpNormal, True),\n    wbFormIDCk(ONAM, 'Older', [RACE]),\n    wbFormIDCk(YNAM, 'Younger', [RACE]),\n    wbEmpty(NAM2, 'Unknown Marker', cpNormal, True),\n    wbArray(VTCK, 'Voices', wbFormIDCk('Voice', [VTYP]), ['Male', 'Female'], cpNormal, True),\n    wbArray(DNAM, 'Default Hair Styles', wbFormIDCk('Default Hair Style', [HAIR, NULL]), ['Male', 'Female'], cpNormal, True),\n    wbArray(CNAM, 'Default Hair Colors', wbInteger('Default Hair Color', itU8, wbEnum([\n      'Bleached',\n      'Brown',\n      'Chocolate',\n      'Platinum',\n      'Cornsilk',\n      'Suede',\n      'Pecan',\n      'Auburn',\n      'Ginger',\n      'Honey',\n      'Gold',\n      'Rosewood',\n      'Black',\n      'Chestnut',\n      'Steel',\n      'Champagne'\n    ])), ['Male', 'Female'], cpNormal, True),\n    wbFloat(PNAM, 'FaceGen - Main clamp', cpNormal, True),\n    wbFloat(UNAM, 'FaceGen - Face clamp', cpNormal, True),\n    wbByteArray(ATTR, 'Unused', 0, cpNormal, True),\n    wbRStruct('Head Data', [\n      wbEmpty(NAM0, 'Head Data Marker', cpNormal, True),\n      wbRStruct('Male Head Data', [\n        wbEmpty(MNAM, 'Male Data Marker', cpNormal, True),\n        wbRArrayS('Parts', wbRStructSK([0], 'Part', [\n          wbInteger(INDX, 'Index', itU32, wbHeadPartIndexEnum),\n          wbMODLReq,\n          wbICON\n        ], [], cpNormal, False, nil, False, nil, wbHeadPartsAfterSet), cpNormal, True)\n      ], [], cpNormal, True),\n      wbRStruct('Female Head Data', [\n        wbEmpty(FNAM, 'Female Data Marker', cpNormal, True),\n        wbRArrayS('Parts', wbRStructSK([0], 'Part', [\n          wbInteger(INDX, 'Index', itU32, wbHeadPartIndexEnum),\n          wbMODLReq,\n          wbICON\n        ], [], cpNormal, False, nil, False, nil, wbHeadPartsAfterSet), cpNormal, True)\n      ], [], cpNormal, True)\n    ], [], cpNormal, True),\n    wbRStruct('Body Data', [\n      wbEmpty(NAM1, 'Body Data Marker', cpNormal, True),\n      wbRStruct('Male Body Data', [\n        wbEmpty(MNAM, 'Male Data Marker'),\n        wbRArrayS('Parts', wbRStructSK([0], 'Part', [\n          wbInteger(INDX, 'Index', itU32, wbBodyPartIndexEnum),\n          wbICON,\n          wbMODLReq\n        ], []), cpNormal, True)\n      ], [], cpNormal, True),\n      wbRStruct('Female Body Data', [\n        wbEmpty(FNAM, 'Female Data Marker', cpNormal, True),\n        wbRArrayS('Parts', wbRStructSK([0], 'Part', [\n          wbInteger(INDX, 'Index', itU32, wbBodyPartIndexEnum),\n          wbICON,\n          wbMODLReq\n        ], []), cpNormal, True)\n      ], [], cpNormal, True)\n    ], [], cpNormal, True),\n    wbArrayS(HNAM, 'Hairs', wbFormIDCk('Hair', [HAIR]), 0, cpNormal, True),\n    wbArrayS(ENAM, 'Eyes', wbFormIDCk('Eye', [EYES]),  0,  cpNormal, True),\n    wbRStruct('FaceGen Data', [\n      wbRStruct('Male FaceGen Data', [\n        wbEmpty(MNAM, 'Male Data Marker', cpNormal, True),\n        wbFaceGen,\n        wbUnknown(SNAM, cpNormal, True)\n      ], [], cpNormal, True),\n      wbRStruct('Female FaceGen Data', [\n        wbEmpty(FNAM, 'Female Data Marker', cpNormal, True),\n        wbFaceGen,\n        wbUnknown(SNAM, cpNormal, True)\n      ], [], cpNormal, True)\n    ], [], cpNormal, True)\n  ]);\n\n  wbRecord(REFR, 'Placed Object', [\n    wbEDID,\n    {\n    wbStruct(RCLR, 'Linked Reference Color (Old Format?)', [\n      wbStruct('Link Start Color', [\n        wbInteger('Red', itU8),\n        wbInteger('Green', itU8),\n        wbInteger('Blue', itU8),\n        wbByteArray('Unused', 1)\n      ]),\n      wbStruct('Link End Color', [\n        wbInteger('Red', itU8),\n        wbInteger('Green', itU8),\n        wbInteger('Blue', itU8),\n        wbByteArray('Unused', 1)\n      ])\n    ], cpIgnore),}\n    wbByteArray(RCLR, 'Unused', 0, cpIgnore),\n    wbFormIDCk(NAME, 'Base', [TREE, SOUN, ACTI, DOOR, STAT, FURN, CONT, ARMO, AMMO, LVLN, LVLC,\n                              MISC, WEAP, BOOK, KEYM, ALCH, LIGH, GRAS, ASPC, IDLM, ARMA,\n                              MSTT, NOTE, PWAT, SCOL, TACT, TERM, TXST], False, cpNormal, True),\n    wbFormIDCk(XEZN, 'Encounter Zone', [ECZN]),\n\n    {--- ?? ---}\n    wbXRGD,\n    wbXRGB,\n\n    {--- Primitive ---}\n    wbStruct(XPRM, 'Primitive', [\n      wbStruct('Bounds', [\n        wbFloat('X', cpNormal, True, 2, 4),\n        wbFloat('Y', cpNormal, True, 2, 4),\n        wbFloat('Z', cpNormal, True, 2, 4)\n      ]),\n      wbStruct('Color', [\n        {84} wbFloat('Red', cpNormal, False, 255, 0),\n        {88} wbFloat('Green', cpNormal, False, 255, 0),\n        {92} wbFloat('Blue', cpNormal, False, 255, 0)\n      ]),\n      wbFloat('Unknown'),\n      wbInteger('Type', itU32, wbEnum([\n        'None',\n        'Box',\n        'Sphere',\n        'Portal Box'\n      ]))\n    ]),\n    wbInteger(XTRI, 'Collision Layer', itU32, wbEnum([\n      'Unidentified',\n      'Static',\n      'AnimStatic',\n      'Transparent',\n      'Clutter',\n      'Weapon',\n      'Projectile',\n      'Spell',\n      'Biped',\n      'Trees',\n      'Props',\n      'Water',\n      'Trigger',\n      'Terrain',\n      'Trap',\n      'Non Collidable',\n      'Cloud Trap',\n      'Ground',\n      'Portal',\n      'Debris Small',\n      'Debris Large',\n      'Acustic Space',\n      'Actor Zone',\n      'Projectile Zone',\n      'Gas Trap',\n      'Shell Casing',\n      'Transparent Small',\n      'Invisible Wall',\n      'Transparent Small Anim',\n      'Dead Bip',\n      'Char Controller',\n      'Avoid Box',\n      'Collision Box',\n      'Camera Sphere',\n      'Door Detection',\n      'Camera Pick',\n      'Item Pick',\n      'Line Of Sight',\n      'Path Pick',\n      'Custom Pick 1',\n      'Custom Pick 2',\n      'Spell Explosion',\n      'Dropping Pick'\n    ])),\n    wbEmpty(XMBP, 'MultiBound Primitive Marker'),\n\n    {--- Bound Contents ---}\n\n    {--- Bound Data ---}\n    wbStruct(XMBO, 'Bound Half Extents', [\n      wbFloat('X'),\n      wbFloat('Y'),\n      wbFloat('Z')\n    ]),\n\n    {--- Teleport ---}\n    wbStruct(XTEL, 'Teleport Destination', [\n      wbFormIDCk('Door', [REFR], True),\n      wbPosRot,\n      wbInteger('Flags', itU32, wbFlags([\n        'No Alarm'\n      ]))\n    ]),\n\n    {--- Map Data ---}\n    wbRStruct('Map Marker', [\n      wbEmpty(XMRK, 'Map Marker Data'),\n      wbInteger(FNAM, 'Flags', itU8, wbFlags([\n        {0x01} 'Visible',\n        {0x02} 'Can Travel To',\n        {0x04} '\"Show All\" Hidden'\n      ]), cpNormal, True),\n      wbFULLReq,\n      wbStruct(TNAM, '', [\n        wbInteger('Type', itU8, wbEnum([\n          'None',\n          'City',\n          'Settlement',\n          'Encampment',\n          'Natural Landmark',\n          'Cave',\n          'Factory',\n          'Monument',\n          'Military',\n          'Office',\n          'Town Ruins',\n          'Urban Ruins',\n          'Sewer Ruins',\n          'Metro',\n          'Vault'\n        ])),\n        wbByteArray('Unused', 1)\n      ], cpNormal, True)\n    ], []),\n\n    wbInteger(XSRF, 'Special Rendering Flags', itU32, wbFlags([\n      'Unknown 0',\n      'Imposter',\n      'Use Full Shader in LOD'\n    ])),\n    wbByteArray(XSRD, 'Special Rendering Data', 4),\n\n    {--- X Target Data ---}\n    wbFormIDCk(XTRG, 'Target', [REFR, ACRE, ACHR, PGRE, PMIS, PBEA], True),\n\n    {--- Leveled Actor ----}\n    wbXLCM,\n\n    {--- Patrol Data ---}\n    wbRStruct('Patrol Data', [\n      wbFloat(XPRD, 'Idle Time', cpNormal, True),\n      wbEmpty(XPPA, 'Patrol Script Marker', cpNormal, True),\n      wbFormIDCk(INAM, 'Idle', [IDLE, NULL], False, cpNormal, True),\n      wbEmbeddedScriptReq,\n      wbFormIDCk(TNAM, 'Topic', [DIAL, NULL], False, cpNormal, True)\n    ], []),\n\n    {--- Radio ---}\n    wbStruct(XRDO, 'Radio Data', [\n      wbFloat('Range Radius'),\n      wbInteger('Broadcast Range Type', itU32, wbEnum([\n        'Radius',\n        'Everywhere',\n        'Worldspace and Linked Interiors',\n        'Linked Interiors',\n        'Current Cell Only'\n      ])),\n      wbFloat('Static Percentage'),\n      wbFormIDCkNoReach('Position Reference', [REFR, ACRE, ACHR, PGRE, PMIS, PBEA, NULL])\n    ]),\n\n    {--- Ownership ---}\n    wbRStruct('Ownership', [\n      wbXOWN,\n      wbInteger(XRNK, 'Faction rank', itS32)\n    ], [XCMT, XCMO]),\n\n    {--- Lock ---}\n    wbStruct(XLOC, 'Lock Data', [\n      wbInteger('Level', itU8),\n      wbByteArray('Unused', 3),\n      wbFormIDCkNoReach('Key', [KEYM, NULL]),\n      wbInteger('Flags', itU8, wbFlags(['', '', 'Leveled Lock'])),\n      wbByteArray('Unused', 3),\n      wbByteArray('Unknown', 8)\n    ], cpNormal, False, nil, 5),\n\n    {--- Extra ---}\n    wbInteger(XCNT, 'Count', itS32),\n    wbFloat(XRDS, 'Radius'),\n    wbFloat(XHLP, 'Health'),\n    wbFloat(XRAD, 'Radiation'),\n    wbFloat(XCHG, 'Charge'),\n    wbRStruct('Ammo', [\n      wbFormIDCk(XAMT, 'Type', [AMMO], False, cpNormal, True),\n      wbInteger(XAMC, 'Count', itS32, nil, cpNormal, True)\n    ], []),\n\n    {--- Reflected By / Refracted By ---}\n    wbRArrayS('Reflected/Refracted By',\n      wbStructSK(XPWR, [0], 'Water', [\n        wbFormIDCk('Reference', [REFR]),\n        wbInteger('Type', itU32, wbFlags([\n          'Reflection',\n          'Refraction'\n        ]))\n      ])\n    ),\n\n    {--- Lit Water ---}\n    wbRArrayS('Lit Water',\n      wbFormIDCk(XLTW, 'Water', [REFR])\n    ),\n\n    {--- Decals ---}\n    wbRArrayS('Linked Decals',\n      wbStructSK(XDCR, [0], 'Decal', [\n        wbFormIDCk('Reference', [REFR]),\n        wbUnknown\n      ])\n    ),\n\n    {--- Linked Ref ---}\n    wbFormIDCk(XLKR, 'Linked Reference', [REFR, ACRE, ACHR, PGRE, PMIS, PBEA, PLYR]),\n    wbStruct(XCLP, 'Linked Reference Color', [\n      wbStruct('Link Start Color', [\n        wbInteger('Red', itU8),\n        wbInteger('Green', itU8),\n        wbInteger('Blue', itU8),\n        wbByteArray('Unused', 1)\n      ]),\n      wbStruct('Link End Color', [\n        wbInteger('Red', itU8),\n        wbInteger('Green', itU8),\n        wbInteger('Blue', itU8),\n        wbByteArray('Unused', 1)\n      ])\n    ]),\n\n    {--- Activate Parents ---}\n    wbRStruct('Activate Parents', [\n      wbInteger(XAPD, 'Flags', itU8, wbFlags([\n        'Parent Activate Only'\n      ], True)),\n      wbRArrayS('Activate Parent Refs',\n        wbStructSK(XAPR, [0], 'Activate Parent Ref', [\n          wbFormIDCk('Reference', [REFR, ACRE, ACHR, PGRE, PMIS, PBEA, PLYR]),\n          wbFloat('Delay')\n        ])\n      )\n    ], []),\n\n    {--- Enable Parent ---}\n    wbXESP,\n\n    {--- Emittance ---}\n    wbFormIDCk(XEMI, 'Emittance', [LIGH, REGN]),\n\n    {--- MultiBound ---}\n    wbFormIDCk(XMBR, 'MultiBound Reference', [REFR]),\n\n    {--- Flags ---}\n    wbInteger(XACT, 'Action Flag', itU32, wbFlags([\n      'Use Default',\n      'Activate',\n      'Open',\n      'Open by Default'\n    ])),\n    wbEmpty(ONAM, 'Open by Default'),\n    wbEmpty(XIBS, 'Ignored By Sandbox'),\n\n    {--- Generated Data ---}\n    wbStruct(XNDP, 'Navigation Door Link', [\n      wbFormIDCk('Navigation Mesh', [NAVM]),\n      wbInteger('Teleport Marker Triangle', itS16, wbREFRNavmeshTriangleToStr, wbStringToInt),\n      wbByteArray('Unused', 2)\n    ]),\n\n    wbArray(XPOD, 'Portal Data', wbFormIDCk('Room', [REFR, NULL]), 2),\n    wbStruct(XPTL, 'Portal Data', [\n      wbStruct('Size', [\n        wbFloat('Width', cpNormal, False, 2),\n        wbFloat('Height', cpNormal, False, 2)\n      ]),\n      wbStruct('Position', [\n        wbFloat('X'),\n        wbFloat('Y'),\n        wbFloat('Z')\n      ]),\n      wbStruct('Rotation (Quaternion?)', [\n        wbFloat('q1'),\n        wbFloat('q2'),\n        wbFloat('q3'),\n        wbFloat('q4')\n      ])\n    ]),\n\n    wbInteger(XSED, 'SpeedTree Seed', itU8),\n\n    wbRStruct('Room Data', [\n      wbStruct(XRMR, 'Header', [\n        wbInteger('Linked Rooms Count', itU16),\n        wbByteArray('Unknown', 2)\n      ]),\n      wbRArrayS('Linked Rooms',\n        wbFormIDCk(XLRM, 'Linked Room', [REFR])\n      )\n    ], []),\n\n    wbStruct(XOCP, 'Occlusion Plane Data', [\n      wbStruct('Size', [\n        wbFloat('Width', cpNormal, False, 2),\n        wbFloat('Height', cpNormal, False, 2)\n      ]),\n      wbStruct('Position', [\n        wbFloat('X'),\n        wbFloat('Y'),\n        wbFloat('Z')\n      ]),\n      wbStruct('Rotation (Quaternion?)', [\n        wbFloat('q1'),\n        wbFloat('q2'),\n        wbFloat('q3'),\n        wbFloat('q4')\n      ])\n    ]),\n    wbArray(XORD, 'Linked Occlusion Planes', wbFormIDCk('Plane', [REFR, NULL]), [\n      'Right',\n      'Left',\n      'Bottom',\n      'Top'\n    ]),\n\n    wbXLOD,\n\n    {--- 3D Data ---}\n    wbXSCL,\n    wbDATAPosRot\n  ], True, wbPlacedAddInfo, cpNormal, False, wbREFRAfterLoad);\n\n\n  wbRecord(REGN, 'Region', [\n    wbEDID,\n    wbICON,\n    wbStruct(RCLR, 'Map Color', [\n      wbInteger('Red', itU8),\n      wbInteger('Green', itU8),\n      wbInteger('Blue', itU8),\n      wbByteArray('Unused', 1)\n    ], cpNormal, True),\n    wbFormIDCkNoReach(WNAM, 'Worldspace', [WRLD]),\n\n    wbRArray('Region Areas', wbRStruct('Region Area', [\n      wbInteger(RPLI, 'Edge Fall-off', itU32),\n      wbArray(RPLD, 'Region Point List Data', wbStruct('Point', [\n        wbFloat('X'),\n        wbFloat('Y')\n      ]), 0, wbRPLDAfterLoad)\n    ], [])),\n\n    wbRArrayS('Region Data Entries', wbRStructSK([0], 'Region Data Entry', [\n      {always starts with an RDAT}\n      wbStructSK(RDAT, [0], 'Data Header', [\n        wbInteger('Type', itU32, wbEnum([\n          {0}'',\n          {1}'',\n          {2}'Objects',\n          {3}'Weather',\n          {4}'Map',\n          {5}'Land',\n          {6}'Grass',\n          {7}'Sound',\n          {8}'',\n          {9}''\n        ])),\n        wbInteger('Flags', itU8, wbFlags([\n          'Override'\n        ])),\n        wbInteger('Priority', itU8),\n        wbByteArray('Unused')\n      ], cpNormal, True),\n\n      {followed by one of these: }\n\n      {--- Objects ---}\n      wbArray(RDOT, 'Objects', wbStruct('Object', [\n        wbFormIDCk('Object', [TREE, STAT, LTEX]),\n        wbInteger('Parent Index', itU16, wbHideFFFF),\n        wbByteArray('Unused', 2),\n        wbFloat('Density'),\n        wbInteger('Clustering', itU8),\n        wbInteger('Min Slope', itU8),\n        wbInteger('Max Slope', itU8),\n        wbInteger('Flags', itU8, wbFlags([\n          {0}'Conform to slope',\n          {1}'Paint Vertices',\n          {2}'Size Variance +/-',\n          {3}'X +/-',\n          {4}'Y +/-',\n          {5}'Z +/-',\n          {6}'Tree',\n          {7}'Huge Rock'\n        ])),\n        wbInteger('Radius wrt Parent', itU16),\n        wbInteger('Radius', itU16),\n        wbFloat('Min Height'),\n        wbFloat('Max Height'),\n        wbFloat('Sink'),\n        wbFloat('Sink Variance'),\n        wbFloat('Size Variance'),\n        wbStruct('Angle Variance', [\n          wbInteger('X', itU16),\n          wbInteger('Y', itU16),\n          wbInteger('Z', itU16)\n        ]),\n        wbByteArray('Unused', 2),\n        wbByteArray('Unknown', 4)\n      ]), 0, nil, nil, cpNormal, False, wbREGNObjectsDontShow),\n\n      {--- Map ---}\n      wbString(RDMP, 'Map Name', 0, cpTranslate, False, wbREGNMapDontShow),\n\n      {--- Grass ---}\n      wbArrayS(RDGS, 'Grasses', wbStructSK([0], 'Grass', [\n        wbFormIDCk('Grass', [GRAS]),\n        wbByteArray('Unknown',4)\n      ]), 0, cpNormal, False, nil, nil, wbREGNGrassDontShow),\n\n      {--- Sound ---}\n      wbInteger(RDMD, 'Music Type', itU32, wbMusicEnum, cpIgnore, False, False, wbNeverShow),\n      wbFormIDCk(RDMO, 'Music', [MUSC], False, cpNormal, False, wbREGNSoundDontShow),\n      wbArrayS(RDSD, 'Sounds', wbStructSK([0], 'Sound', [\n        wbFormIDCk('Sound', [SOUN]),\n        wbInteger('Flags', itU32, wbFlags([\n          'Pleasant',\n          'Cloudy',\n          'Rainy',\n          'Snowy'\n        ])),\n        wbInteger('Chance', itU32, wbScaledInt4ToStr, wbScaledInt4ToInt)\n      ]), 0, cpNormal, False, nil, nil, wbREGNSoundDontShow),\n\n      {--- Weather ---}\n      wbArrayS(RDWT, 'Weather Types', wbStructSK([0], 'Weather Type', [\n        wbFormIDCk('Weather', [WTHR]),\n        wbInteger('Chance', itU32),\n        wbFormIDCk('Global', [GLOB, NULL])\n      ]), 0, cpNormal, False, nil, nil, wbREGNWeatherDontShow)\n    ], []))\n  ], True);\n\n  wbRecord(SOUN, 'Sound', [\n    wbEDIDReq,\n    wbOBNDReq,\n    wbString(FNAM, 'Sound Filename'),\n    wbRUnion('Sound Data', [\n      wbStruct(SNDD, 'Sound Data', [\n        wbInteger('Minimum Attentuation Distance', itU8, wbMul(5)),\n        wbInteger('Maximum Attentuation Distance', itU8, wbMul(100)),\n        wbInteger('Frequency Adjustment %', itS8),\n        wbByteArray('Unused', 1),\n        wbInteger('Flags', itU32, wbFlags([\n          {0x0001} 'Random Frequency Shift',\n          {0x0002} 'Play At Random',\n          {0x0004} 'Environment Ignored',\n          {0x0008} 'Random Location',\n          {0x0010} 'Loop',\n          {0x0020} 'Menu Sound',\n          {0x0040} '2D',\n          {0x0080} '360 LFE',\n          {0x0100} 'Dialogue Sound',\n          {0x0200} 'Envelope Fast',\n          {0x0400} 'Envelope Slow',\n          {0x0800} '2D Radius',\n          {0x1000} 'Mute When Submerged'\n        ])),\n        wbInteger('Static attentuation cdB', itS16),\n        wbInteger('Stop time ', itU8),\n        wbInteger('Start time ', itU8),\n        wbArray('Attenuation Curve', wbInteger('Point', itS16), 5),\n        wbInteger('Reverb Attenuation Control', itS16),\n        wbInteger('Priority', itS32),\n        wbByteArray('Unknown', 8)\n      ], cpNormal, True),\n      wbStruct(SNDX, 'Sound Data', [\n        wbInteger('Minimum attentuation distance', itU8, wbMul(5)),\n        wbInteger('Maximum attentuation distance', itU8, wbMul(100)),\n        wbInteger('Frequency adjustment %', itS8),\n        wbByteArray('Unused', 1),\n        wbInteger('Flags', itU32, wbFlags([\n          {0x0001} 'Random Frequency Shift',\n          {0x0002} 'Play At Random',\n          {0x0004} 'Environment Ignored',\n          {0x0008} 'Random Location',\n          {0x0010} 'Loop',\n          {0x0020} 'Menu Sound',\n          {0x0040} '2D',\n          {0x0080} '360 LFE',\n          {0x0100} 'Dialogue Sound',\n          {0x0200} 'Envelope Fast',\n          {0x0400} 'Envelope Slow',\n          {0x0800} '2D Radius',\n          {0x1000} 'Mute When Submerged'\n        ])),\n        wbInteger('Static attentuation cdB', itS16),\n        wbInteger('Stop time ', itU8),\n        wbInteger('Start time ', itU8)\n      ], cpNormal, True)\n    ], [], cpNormal, True),\n    wbArray(ANAM, 'Attenuation Curve', wbInteger('Point', itS16), 5, nil, nil, cpNormal, False, wbNeverShow),\n    wbInteger(GNAM, 'Reverb Attenuation Control', itS16, nil, cpNormal, False, False, wbNeverShow),\n    wbInteger(HNAM, 'Priority', itS32, nil, cpNormal, False, False, wbNeverShow)\n  ], False, nil, cpNormal, False, wbSOUNAfterLoad);\n\n  wbRecord(SPEL, 'Actor Effect', [\n    wbEDIDReq,\n    wbFULL,\n    wbStruct(SPIT, '', [\n      wbInteger('Type', itU32, wbEnum([\n        {0} 'Actor Effect',\n        {1} 'Disease',\n        {2} 'Power',\n        {3} 'Lesser Power',\n        {4} 'Ability',\n        {5} 'Poison',\n        {6} '',\n        {7} '',\n        {8} '',\n        {9} '',\n       {10} 'Addiction'\n      ])),\n      wbInteger('Cost (Unused)', itU32),\n      wbInteger('Level (Unused)', itU32, wbEnum([\n        {0} 'Unused'\n      ])),\n      wbInteger('Flags', itU8, wbFlags([\n        {0x00000001} 'No Auto-Calc',\n        {0x00000002} 'Immune to Silence 1?',\n        {0x00000004} 'PC Start Effect',\n        {0x00000008} 'Immune to Silence 2?',\n        {0x00000010} 'Area Effect Ignores LOS',\n        {0x00000020} 'Script Effect Always Applies',\n        {0x00000040} 'Disable Absorb/Reflect',\n        {0x00000080} 'Force Touch Explode'\n      ])),\n      wbByteArray('Unused', 3)\n    ], cpNormal, True),\n    wbEffectsReq\n  ]);\n\n  wbRecord(STAT, 'Static', [\n    wbEDIDReq,\n    wbOBNDReq,\n    wbMODL\n  ]);\n\n  wbRecord(TES4, 'Main File Header', [\n    wbStruct(HEDR, 'Header', [\n      wbFloat('Version'),\n      wbInteger('Number of Records', itU32),\n      wbInteger('Next Object ID', itU32)\n    ], cpNormal, True),\n    wbByteArray(OFST, 'Unknown', 0, cpIgnore),\n    wbByteArray(DELE, 'Unknown', 0, cpIgnore),\n    wbString(CNAM, 'Author', 0, cpTranslate, True),\n    wbString(SNAM, 'Description', 0, cpTranslate),\n    wbRArray('Master Files', wbRStruct('Master File', [\n      wbString(MAST, 'Filename', 0, cpNormal, True),\n      wbByteArray(DATA, 'Unused', 8, cpIgnore, True)\n    ], [ONAM])),\n    wbArray(ONAM, 'Overriden Forms', wbFormIDCk('Form', [REFR, ACHR, ACRE, PMIS, PBEA, PGRE, LAND, NAVM]), 0, nil, nil, cpNormal, False, wbTES4ONAMDontShow),\n    wbByteArray(SCRN, 'Screenshot')\n  ], True, nil, cpNormal, True, wbRemoveOFST);\n\n  wbRecord(TREE, 'Tree', [\n    wbEDIDReq,\n    wbOBNDReq,\n    wbMODLReq,\n    wbICONReq,\n    wbArrayS(SNAM, 'SpeedTree Seeds', wbInteger('SpeedTree Seed', itU32), 0, cpNormal, True),\n    wbStruct(CNAM, 'Tree Data', [\n      wbFloat('Leaf Curvature'),\n      wbFloat('Minimum Leaf Angle'),\n      wbFloat('Maximum Leaf Angle'),\n      wbFloat('Branch Dimming Value'),\n      wbFloat('Leaf Dimming Value'),\n      wbInteger('Shadow Radius', itS32),\n      wbFloat('Rock Speed'),\n      wbFloat('Rustle Speed')\n    ], cpNormal, True),\n    wbStruct(BNAM, 'Billboard Dimensions', [\n      wbFloat('Width'),\n      wbFloat('Height')\n    ], cpNormal, True)\n  ]);\nend;\n\nprocedure DefineFO3f;\nbegin\n  wbRecord(WATR, 'Water', [\n    wbEDIDReq,\n    wbFULL,\n    wbString(NNAM, 'Noise Map', 0, cpNormal, True),\n    wbInteger(ANAM, 'Opacity', itU8, nil, cpNormal, True),\n    wbInteger(FNAM, 'Flags', itU8, wbFlags([\n      {0}'Causes Damage',\n      {1}'Reflective'\n    ]), cpNormal, True),\n    wbString(MNAM, 'Material ID', 0, cpNormal, True),\n    wbFormIDCk(SNAM, 'Sound', [SOUN]),\n    wbFormIDCk(XNAM, 'Actor Effect', [SPEL]),\n    wbInteger(DATA, 'Damage', itU16, nil, cpNormal, True, True),\n    wbRUnion('Visual Data', [\n      wbStruct(DNAM, 'Visual Data', [\n        wbFloat('Unknown'),\n        wbFloat('Unknown'),\n        wbFloat('Unknown'),\n        wbFloat('Unknown'),\n        wbFloat('Water Properties - Sun Power'),\n        wbFloat('Water Properties - Reflectivity Amount'),\n        wbFloat('Water Properties - Fresnel Amount'),\n        wbByteArray('Unused', 4),\n        wbFloat('Fog Properties - Above Water - Fog Distance - Near Plane'),\n        wbFloat('Fog Properties - Above Water - Fog Distance - Far Plane'),\n        wbStruct('Shallow Color', [\n          wbInteger('Red', itU8),\n          wbInteger('Green', itU8),\n          wbInteger('Blue', itU8),\n          wbByteArray('Unused', 1)\n        ]),\n        wbStruct('Deep Color', [\n          wbInteger('Red', itU8),\n          wbInteger('Green', itU8),\n          wbInteger('Blue', itU8),\n          wbByteArray('Unused', 1)\n        ]),\n        wbStruct('Reflection Color', [\n          wbInteger('Red', itU8),\n          wbInteger('Green', itU8),\n          wbInteger('Blue', itU8),\n          wbByteArray('Unused', 1)\n        ]),\n        wbByteArray('Unused', 4),\n        wbFloat('Rain Simulator - Force'),\n        wbFloat('Rain Simulator - Velocity'),\n        wbFloat('Rain Simulator - Falloff'),\n        wbFloat('Rain Simulator - Dampner'),\n        wbFloat('Displacement Simulator - Starting Size'),\n        wbFloat('Displacement Simulator - Force'),\n        wbFloat('Displacement Simulator - Velocity'),\n        wbFloat('Displacement Simulator - Falloff'),\n        wbFloat('Displacement Simulator - Dampner'),\n        wbFloat('Rain Simulator - Starting Size'),\n        wbFloat('Noise Properties - Normals - Noise Scale'),\n        wbFloat('Noise Properties - Noise Layer One - Wind Direction'),\n        wbFloat('Noise Properties - Noise Layer Two - Wind Direction'),\n        wbFloat('Noise Properties - Noise Layer Three - Wind Direction'),\n        wbFloat('Noise Properties - Noise Layer One - Wind Speed'),\n        wbFloat('Noise Properties - Noise Layer Two - Wind Speed'),\n        wbFloat('Noise Properties - Noise Layer Three - Wind Speed'),\n        wbFloat('Noise Properties - Normals - Depth Falloff Start'),\n        wbFloat('Noise Properties - Normals - Depth Falloff End'),\n        wbFloat('Fog Properties - Above Water - Fog Amount'),\n        wbFloat('Noise Properties - Normals - UV Scale'),\n        wbFloat('Fog Properties - Under Water - Fog Amount'),\n        wbFloat('Fog Properties - Under Water - Fog Distance - Near Plane'),\n        wbFloat('Fog Properties - Under Water - Fog Distance - Far Plane'),\n        wbFloat('Water Properties - Distortion Amount'),\n        wbFloat('Water Properties - Shininess'),\n        wbFloat('Water Properties - Reflection HDR Multiplier'),\n        wbFloat('Water Properties - Light Radius'),\n        wbFloat('Water Properties - Light Brightness'),\n        wbFloat('Noise Properties - Noise Layer One - UV Scale'),\n        wbFloat('Noise Properties - Noise Layer Two - UV Scale'),\n        wbFloat('Noise Properties - Noise Layer Three - UV Scale'),\n        wbFloat('Noise Properties - Noise Layer One - Amplitude Scale'),\n        wbFloat('Noise Properties - Noise Layer Two - Amplitude Scale'),\n        wbFloat('Noise Properties - Noise Layer Three - Amplitude Scale')\n      ], cpNormal, True, nil, 46),\n      wbStruct(DATA, 'Visual Data', [\n        wbFloat('Unknown'),\n        wbFloat('Unknown'),\n        wbFloat('Unknown'),\n        wbFloat('Unknown'),\n        wbFloat('Water Properties - Sun Power'),\n        wbFloat('Water Properties - Reflectivity Amount'),\n        wbFloat('Water Properties - Fresnel Amount'),\n        wbByteArray('Unused', 4),\n        wbFloat('Fog Properties - Above Water - Fog Distance - Near Plane'),\n        wbFloat('Fog Properties - Above Water - Fog Distance - Far Plane'),\n        wbStruct('Shallow Color', [\n          wbInteger('Red', itU8),\n          wbInteger('Green', itU8),\n          wbInteger('Blue', itU8),\n          wbByteArray('Unused', 1)\n        ]),\n        wbStruct('Deep Color', [\n          wbInteger('Red', itU8),\n          wbInteger('Green', itU8),\n          wbInteger('Blue', itU8),\n          wbByteArray('Unused', 1)\n        ]),\n        wbStruct('Reflection Color', [\n          wbInteger('Red', itU8),\n          wbInteger('Green', itU8),\n          wbInteger('Blue', itU8),\n          wbByteArray('Unused', 1)\n        ]),\n        wbByteArray('Unused', 4),\n        wbFloat('Rain Simulator - Force'),\n        wbFloat('Rain Simulator - Velocity'),\n        wbFloat('Rain Simulator - Falloff'),\n        wbFloat('Rain Simulator - Dampner'),\n        wbFloat('Displacement Simulator - Starting Size'),\n        wbFloat('Displacement Simulator - Force'),\n        wbFloat('Displacement Simulator - Velocity'),\n        wbFloat('Displacement Simulator - Falloff'),\n        wbFloat('Displacement Simulator - Dampner'),\n        wbFloat('Rain Simulator - Starting Size'),\n        wbFloat('Noise Properties - Normals - Noise Scale'),\n        wbFloat('Noise Properties - Noise Layer One - Wind Direction'),\n        wbFloat('Noise Properties - Noise Layer Two - Wind Direction'),\n        wbFloat('Noise Properties - Noise Layer Three - Wind Direction'),\n        wbFloat('Noise Properties - Noise Layer One - Wind Speed'),\n        wbFloat('Noise Properties - Noise Layer Two - Wind Speed'),\n        wbFloat('Noise Properties - Noise Layer Three - Wind Speed'),\n        wbFloat('Noise Properties - Normals - Depth Falloff Start'),\n        wbFloat('Noise Properties - Normals - Depth Falloff End'),\n        wbFloat('Fog Properties - Above Water - Fog Amount'),\n        wbFloat('Noise Properties - Normals - UV Scale'),\n        wbFloat('Fog Properties - Under Water - Fog Amount'),\n        wbFloat('Fog Properties - Under Water - Fog Distance - Near Plane'),\n        wbFloat('Fog Properties - Under Water - Fog Distance - Far Plane'),\n        wbFloat('Water Properties - Distortion Amount'),\n        wbFloat('Water Properties - Shininess'),\n        wbFloat('Water Properties - Reflection HDR Multiplier'),\n        wbFloat('Water Properties - Light Radius'),\n        wbFloat('Water Properties - Light Brightness'),\n        wbFloat('Noise Properties - Noise Layer One - UV Scale'),\n        wbFloat('Noise Properties - Noise Layer Two - UV Scale'),\n        wbFloat('Noise Properties - Noise Layer Three - UV Scale'),\n        wbEmpty('Noise Properties - Noise Layer One - Amplitude Scale'),\n        wbEmpty('Noise Properties - Noise Layer Two - Amplitude Scale'),\n        wbEmpty('Noise Properties - Noise Layer Three - Amplitude Scale'),\n        wbInteger('Damage (Old Format)', itU16)\n      ], cpNormal, True)\n    ], [], cpNormal, True),\n    wbStruct(GNAM, 'Related Waters (Unused)', [\n      wbFormIDCk('Daytime', [WATR, NULL]),\n      wbFormIDCk('Nighttime', [WATR, NULL]),\n      wbFormIDCk('Underwater', [WATR, NULL])\n    ], cpNormal, True)\n  ], False, nil, cpNormal, False, wbWATRAfterLoad);\n\n  wbRecord(WEAP, 'Weapon', [\n    wbEDIDReq,\n    wbOBNDReq,\n    wbFULL,\n    wbMODL,\n    wbICON,\n    wbSCRI,\n    wbEITM,\n    wbInteger(EAMT, 'Enchantment Charge Amount', itS16),\n    wbFormIDCkNoReach(NAM0, 'Ammo', [AMMO, FLST]),\n    wbDEST,\n    wbREPL,\n    wbETYPReq,\n    wbBIPL,\n    wbYNAM,\n    wbZNAM,\n    wbRStruct('Shell Casing Model', [\n      wbString(MOD2, 'Model Filename'),\n      wbByteArray(MO2T, 'Texture Files Hashes', 0, cpIgnore),\n      wbMO2S\n    ], []),\n    wbRStruct('Scope Model', [\n      wbString(MOD3, 'Model Filename'),\n      wbByteArray(MO3T, 'Texture Files Hashes', 0, cpIgnore),\n      wbMO3S\n    ], []),\n    wbFormIDCK(EFSD, 'Scope Effect', [EFSH]),\n    wbRStruct('World Model', [\n      wbString(MOD4, 'Model Filename'),\n      wbByteArray(MO4T, 'Texture Files Hashes', 0, cpIgnore),\n      wbMO4S\n    ], []),\n    wbString(NNAM, 'Embedded Weapon Node'),\n    wbFormIDCk(INAM, 'Impact DataSet', [IPDS]),\n    wbFormIDCk(WNAM, '1st Person Model', [STAT]),\n    wbFormIDCk(SNAM, 'Sound - Gun - Shoot 3D', [SOUN]),\n    wbFormIDCk(XNAM, 'Sound - Gun - Shoot 2D', [SOUN]),\n    wbFormIDCk(NAM7, 'Sound - Gun - Shoot 3D Looping', [SOUN]),\n    wbFormIDCk(TNAM, 'Sound - Melee - Swing / Gun - No Ammo', [SOUN]),\n    wbFormIDCk(NAM6, 'Sound - Block', [SOUN]),\n    wbFormIDCk(UNAM, 'Sound - Idle', [SOUN]),\n    wbFormIDCk(NAM9, 'Sound - Equip', [SOUN]),\n    wbFormIDCk(NAM8, 'Sound - Unequip', [SOUN]),\n    wbStruct(DATA, '', [\n      wbInteger('Value', itS32),\n      wbInteger('Health', itS32),\n      wbFloat('Weight'),\n      wbInteger('Base Damage', itS16),\n      wbInteger('Clip Size', itU8)\n    ], cpNormal, True),\n    wbStruct(DNAM, '', [\n      {00} wbInteger('Animation Type', itU32, wbWeaponAnimTypeEnum),\n      {04} wbFloat('Animation Multiplier'),\n      {08} wbFloat('Reach'),\n      {12} wbInteger('Flags 1', itU8, wbFlags([\n        'Ignores Normal Weapon Resistance',\n        'Is Automatic',\n        'Has Scope',\n        'Can''t Drop',\n        'Hide Backpack',\n        'Embedded Weapon',\n        'Don''t Use 1st Person IS Animations',\n        'Non-Playable'\n      ])),\n      {13} wbInteger('Grip Animation', itU8, wbEnum([\n      ], [\n        171, 'HandGrip1',\n        172, 'HandGrip2',\n        173, 'HandGrip3',\n        255, 'DEFAULT'\n      ])),\n      {14} wbInteger('Ammo Use', itU8),\n      {15} wbInteger('Reload Animation', itU8, wbReloadAnimEnum),\n      {16} wbFloat('Min Spread'),\n      {20} wbFloat('Spread'),\n      {24} wbFloat('Unknown'),\n      {28} wbFloat('Sight FOV'),\n      {32} wbByteArray('Unused', 4),\n      {36} wbFormIDCk('Projectile', [PROJ, NULL]),\n      {40} wbInteger('Base VATS To-Hit Chance', itU8),\n      {41} wbInteger('Attack Animation', itU8, wbEnum([\n           ], [\n             26, 'AttackLeft',\n             32, 'AttackRight',\n             38, 'Attack3',\n             44, 'Attack4',\n             50, 'Attack5',\n             56, 'Attack6',\n             62, 'Attack7',\n             68, 'Attack8',\n             74, 'AttackLoop',\n             80, 'AttackSpin',\n             86, 'AttackSpin2',\n             97, 'PlaceMine',\n            103, 'PlaceMine2',\n            109, 'AttackThrow',\n            115, 'AttackThrow2',\n            121, 'AttackThrow3',\n            127, 'AttackThrow4',\n            133, 'AttackThrow5',\n            255, 'DEFAULT'\n           ])),\n      {42} wbInteger('Projectile Count', itU8),\n      {43} wbInteger('Embedded Weapon - Actor Value', itU8, wbEnum([\n        {00} 'Perception',\n        {01} 'Endurance',\n        {02} 'Left Attack',\n        {03} 'Right Attack',\n        {04} 'Left Mobility',\n        {05} 'Right Mobilty',\n        {06} 'Brain'\n      ])),\n      {44} wbFloat('Min Range'),\n      {48} wbFloat('Max Range'),\n      {52} wbInteger('On Hit', itU32, wbEnum([\n        'Normal formula behavior',\n        'Dismember Only',\n        'Explode Only',\n        'No Dismember/Explode'\n      ])),\n      {56} wbInteger('Flags 2', itU32, wbFlags([\n        {0x00000001}'Player Only',\n        {0x00000002}'NPCs Use Ammo',\n        {0x00000004}'No Jam After Reload',\n        {0x00000008}'Override - Action Points',\n        {0x00000010}'Minor Crime',\n        {0x00000020}'Range - Fixed',\n        {0x00000040}'Not Used In Normal Combat',\n        {0x00000080}'Override - Damage to Weapon Mult',\n        {0x00000100}'Don''t Use 3rd Person IS Animations',\n        {0x00000200}'Short Burst',\n        {0x00000400}'Rumble Alternate',\n        {0x00000800}'Long Burst'\n      ])),\n      {60} wbFloat('Animation Attack Multiplier'),\n      {64} wbFloat('Fire Rate'),\n      {68} wbFloat('Override - Action Points'),\n      {72} wbFloat('Rumble - Left Motor Strength'),\n      {76} wbFloat('Rumble - Right Motor Strength'),\n      {80} wbFloat('Rumble - Duration'),\n      {84} wbFloat('Override - Damage to Weapon Mult'),\n      {88} wbFloat('Attack Shots/Sec'),\n      {92} wbFloat('Reload Time'),\n      {96} wbFloat('Jam Time'),\n     {100} wbFloat('Aim Arc'),\n     {104} wbInteger('Skill', itS32, wbActorValueEnum),\n     {108} wbInteger('Rumble - Pattern', itU32, wbEnum([\n       'Constant',\n       'Square',\n       'Triangle',\n       'Sawtooth'\n     ])),\n     {112} wbFloat('Rumble - Wavelength'),\n     {116} wbFloat('Limb Dmg Mult'),\n     {120} wbInteger('Resist Type', itS32, wbActorValueEnum),\n     {124} wbFloat('Sight Usage'),\n     {128} wbFloat('Semi-Automatic Fire Delay Min'),\n     {132} wbFloat('Semi-Automatic Fire Delay Max')\n    ], cpNormal, True, nil, 36),\n\n   wbStruct(CRDT, 'Critical Data', [\n      {00} wbInteger('Critical Damage', itU16),\n      {09} wbByteArray('Unused', 2),\n      {04} wbFloat('Crit % Mult'),\n      {08} wbInteger('Flags', itU8, wbFlags([\n        'On Death'\n      ])),\n      {09} wbByteArray('Unused', 3),\n      {12} wbFormIDCk('Effect', [SPEL, NULL])\n    ], cpNormal, True),\n    wbInteger(VNAM, 'Sound Level', itU32, wbSoundLevelEnum, cpNormal, True)\n  ], False, nil, cpNormal, False, wbWEAPAfterLoad);\n\n  if wbSimpleRecords then\n    wbRecord(WRLD, 'Worldspace', [\n      wbEDIDReq,\n      wbFULL,\n      wbFormIDCk(XEZN, 'Encounter Zone', [ECZN]),\n      wbRStruct('Parent', [\n        wbFormIDCk(WNAM, 'Worldspace', [WRLD]),\n        wbStruct(PNAM, '', [\n          wbInteger('Flags', itU8, wbFlags([\n            {0x00000001}'Use Land Data',\n            {0x00000002}'Use LOD Data',\n            {0x00000004}'Use Map Data',\n            {0x00000008}'Use Water Data',\n            {0x00000010}'Use Climate Data',\n            {0x00000020}'Use Image Space Data',\n            {0x00000040}'',\n            {0x00000080}'Needs Water Adjustment'\n          ], True)),\n          wbByteArray('Unknown', 1)\n        ], cpNormal, True)\n      ], []),\n      wbFormIDCk(CNAM, 'Climate', [CLMT]),\n      wbFormIDCk(NAM2, 'Water', [WATR]),\n      wbFormIDCk(NAM3, 'LOD Water Type', [WATR]),\n      wbFloat(NAM4, 'LOD Water Height'),\n      wbStruct(DNAM, 'Land Data', [\n        wbFloat('Default Land Height'),\n        wbFloat('Default Water Height')\n      ]),\n      wbICON,\n      wbStruct(MNAM, 'Map Data', [\n        wbStruct('Usable Dimensions', [\n          wbInteger('X', itS32),\n          wbInteger('Y', itS32)\n        ]),\n        wbStruct('Cell Coordinates', [\n          wbStruct('NW Cell', [\n            wbInteger('X', itS16),\n            wbInteger('Y', itS16)\n          ]),\n          wbStruct('SE Cell', [\n            wbInteger('X', itS16),\n            wbInteger('Y', itS16)\n          ])\n        ])\n      ]),\n      wbStruct(ONAM, 'World Map Offset Data', [\n        wbFloat('World Map Scale'),\n        wbFloat('Cell X Offset'),\n        wbFloat('Cell Y Offset')\n      ], cpNormal, True),\n      wbFormIDCk(INAM, 'Image Space', [IMGS]),\n      wbInteger(DATA, 'Flags', itU8, wbFlags([\n        {0x01} 'Small World',\n        {0x02} 'Can''t Fast Travel',\n        {0x04} '',\n        {0x08} '',\n        {0x10} 'No LOD Water',\n        {0x20} 'No LOD Noise',\n        {0x40} 'Don''t Allow NPC Fall Damage',\n        {0x80} 'Needs Water Adjustment'\n      ]), cpNormal, True),\n      wbRStruct('Object Bounds', [\n        wbStruct(NAM0, 'Min', [\n          wbFloat('X', cpNormal, False, 1/4096),\n          wbFloat('Y', cpNormal, False, 1/4096)\n        ], cpIgnore, True),\n        wbStruct(NAM9, 'Max', [\n          wbFloat('X', cpNormal, False, 1/4096),\n          wbFloat('Y', cpNormal, False, 1/4096)\n        ], cpIgnore, True)\n      ], []),\n      wbFormIDCk(ZNAM, 'Music', [MUSC]),\n      wbString(NNAM, 'Canopy Shadow', 0, cpNormal, True),\n      wbString(XNAM, 'Water Noise Texture', 0, cpNormal, True),\n      wbRArrayS('Swapped Impacts', wbStructExSK(IMPS, [0, 1], [2], 'Swapped Impact', [\n        wbInteger('Material Type', itU32, wbImpactMaterialTypeEnum),\n        wbFormIDCkNoReach('Old', [IPCT]),\n        wbFormIDCk('New', [IPCT, NULL])\n      ])),\n      wbArray(IMPF, 'Footstep Materials', wbString('Unknown', 30), [\n        'ConcSolid',\n        'ConcBroken',\n        'MetalSolid',\n        'MetalHollow',\n        'MetalSheet',\n        'Wood',\n        'Sand',\n        'Dirt',\n        'Grass',\n        'Water'\n      ]),\n      wbByteArray(OFST, 'Offset Data')\n    ], False, nil, cpNormal, False, wbRemoveOFST)\n  else\n    wbRecord(WRLD, 'Worldspace', [\n      wbEDIDReq,\n      wbFULL,\n      wbFormIDCk(XEZN, 'Encounter Zone', [ECZN]),\n      wbRStruct('Parent', [\n        wbFormIDCk(WNAM, 'Worldspace', [WRLD]),\n        wbStruct(PNAM, '', [\n          wbInteger('Flags', itU8, wbFlags([\n            {0x00000001}'Use Land Data',\n            {0x00000002}'Use LOD Data',\n            {0x00000004}'Use Map Data',\n            {0x00000008}'Use Water Data',\n            {0x00000010}'Use Climate Data',\n            {0x00000020}'Use Image Space Data',\n            {0x00000040}'',\n            {0x00000080}'Needs Water Adjustment'\n          ], True)),\n          wbByteArray('Unknown', 1)\n        ], cpNormal, True)\n      ], []),\n      wbFormIDCk(CNAM, 'Climate', [CLMT]),\n      wbFormIDCk(NAM2, 'Water', [WATR]),\n      wbFormIDCk(NAM3, 'LOD Water Type', [WATR]),\n      wbFloat(NAM4, 'LOD Water Height'),\n      wbStruct(DNAM, 'Land Data', [\n        wbFloat('Default Land Height'),\n        wbFloat('Default Water Height')\n      ]),\n      wbICON,\n      wbStruct(MNAM, 'Map Data', [\n        wbStruct('Usable Dimensions', [\n          wbInteger('X', itS32),\n          wbInteger('Y', itS32)\n        ]),\n        wbStruct('Cell Coordinates', [\n          wbStruct('NW Cell', [\n            wbInteger('X', itS16),\n            wbInteger('Y', itS16)\n          ]),\n          wbStruct('SE Cell', [\n            wbInteger('X', itS16),\n            wbInteger('Y', itS16)\n          ])\n        ])\n      ]),\n      wbStruct(ONAM, 'World Map Offset Data', [\n        wbFloat('World Map Scale'),\n        wbFloat('Cell X Offset'),\n        wbFloat('Cell Y Offset')\n      ], cpNormal, True),\n      wbFormIDCk(INAM, 'Image Space', [IMGS]),\n      wbInteger(DATA, 'Flags', itU8, wbFlags([\n        {0x01} 'Small World',\n        {0x02} 'Can''t Fast Travel',\n        {0x04} '',\n        {0x08} '',\n        {0x10} 'No LOD Water',\n        {0x20} 'No LOD Noise',\n        {0x40} 'Don''t Allow NPC Fall Damage',\n        {0x80} 'Needs Water Adjustment'\n      ]), cpNormal, True),\n      wbRStruct('Object Bounds', [\n        wbStruct(NAM0, 'Min', [\n          wbFloat('X', cpNormal, False, 1/4096),\n          wbFloat('Y', cpNormal, False, 1/4096)\n        ], cpIgnore, True),\n        wbStruct(NAM9, 'Max', [\n          wbFloat('X', cpNormal, False, 1/4096),\n          wbFloat('Y', cpNormal, False, 1/4096)\n        ], cpIgnore, True)\n      ], []),\n      wbFormIDCk(ZNAM, 'Music', [MUSC]),\n      wbString(NNAM, 'Canopy Shadow', 0, cpNormal, True),\n      wbString(XNAM, 'Water Noise Texture', 0, cpNormal, True),\n      wbRArrayS('Swapped Impacts', wbStructExSK(IMPS, [0, 1], [2], 'Swapped Impact', [\n        wbInteger('Material Type', itU32, wbImpactMaterialTypeEnum),\n        wbFormIDCkNoReach('Old', [IPCT]),\n        wbFormIDCk('New', [IPCT, NULL])\n      ])),\n      wbArray(IMPF, 'Footstep Materials', wbString('Unknown', 30), [\n        'ConcSolid',\n        'ConcBroken',\n        'MetalSolid',\n        'MetalHollow',\n        'MetalSheet',\n        'Wood',\n        'Sand',\n        'Dirt',\n        'Grass',\n        'Water'\n      ]),\n      wbArray(OFST, 'Offset Data', wbArray('Rows', wbInteger('Offset', itU32), wbOffsetDataColsCounter), 0)\n    ], False, nil, cpNormal, False, wbRemoveOFST);\n\n  wbRecord(WTHR, 'Weather', [\n    wbEDIDReq,\n    wbFormIDCk(_0_IAD, 'Sunrise Image Space Modifier', [IMAD]),\n    wbFormIDCk(_1_IAD, 'Day Image Space Modifier', [IMAD]),\n    wbFormIDCk(_2_IAD, 'Sunset Image Space Modifier', [IMAD]),\n    wbFormIDCk(_3_IAD, 'Night Image Space Modifier', [IMAD]),\n    wbString(DNAM, 'Cloud Textures - Layer 0', 0, cpNormal, True),\n    wbString(CNAM, 'Cloud Textures - Layer 1', 0, cpNormal, True),\n    wbString(ANAM, 'Cloud Textures - Layer 2', 0, cpNormal, True),\n    wbString(BNAM, 'Cloud Textures - Layer 3', 0, cpNormal, True),\n    wbMODL,\n    wbByteArray(LNAM, 'Unknown', 4, cpNormal, True),\n    wbArray(ONAM, 'Cloud Speed', wbInteger('Layer', itU8{, wbDiv(2550)}), 4, nil, nil, cpNormal, True),\n    wbArray(PNAM, 'Cloud Layer Colors',\n      wbArray('Layer',\n        wbStruct('Color', [\n          wbInteger('Red', itU8),\n          wbInteger('Green', itU8),\n          wbInteger('Blue', itU8),\n          wbByteArray('Unused', 1)\n        ]),\n        ['Sunrise', 'Day', 'Sunset', 'Night']\n      ),\n    4),\n    wbArray(NAM0, 'Colors by Types/Times',\n      wbArray('Type',\n        wbStruct('Time', [\n          wbInteger('Red', itU8),\n          wbInteger('Green', itU8),\n          wbInteger('Blue', itU8),\n          wbByteArray('Unused', 1)\n        ]),\n        ['Sunrise', 'Day', 'Sunset', 'Night']\n      ),\n      ['Sky-Upper','Fog','Unused','Ambient','Sunlight','Sun','Stars','Sky-Lower','Horizon','Unused']\n    , cpNormal, True),\n    wbStruct(FNAM, 'Fog Distance', [\n      wbFloat('Day - Near'),\n      wbFloat('Day - Far'),\n      wbFloat('Night - Near'),\n      wbFloat('Night - Far'),\n      wbFloat('Day - Power'),\n      wbFloat('Night - Fower')\n    ], cpNormal, True),\n    wbByteArray(INAM, 'Unused', 304, cpIgnore, True),\n    wbStruct(DATA, '', [\n      wbInteger('Wind Speed', itU8),\n      wbInteger('Cloud Speed (Lower)', itU8),\n      wbInteger('Cloud Speed (Upper)', itU8),\n      wbInteger('Trans Delta', itU8),\n      wbInteger('Sun Glare', itU8),\n      wbInteger('Sun Damage', itU8),\n      wbInteger('Precipitation - Begin Fade In', itU8),\n      wbInteger('Precipitation - End Fade Out', itU8),\n      wbInteger('Thunder/Lightning - Begin Fade In', itU8),\n      wbInteger('Thunder/Lightning - End Fade Out', itU8),\n      wbInteger('Thunder/Lightning - Frequency', itU8),\n      wbInteger('Weather Classification', itU8, wbWthrDataClassification),\n      wbStruct('Lightning Color', [\n        wbInteger('Red', itU8),\n        wbInteger('Green', itU8),\n        wbInteger('Blue', itU8)\n      ])\n    ], cpNormal, True),\n    wbRArray('Sounds', wbStruct(SNAM, 'Sound', [\n      wbFormIDCk('Sound', [SOUN]),\n      wbInteger('Type', itU32, wbEnum([\n       {0}'Default',\n       {1}'Precip',\n       {2}'Wind',\n       {3}'Thunder'\n      ]))\n    ]))\n  ]);\n\n  wbAddGroupOrder(GMST);\n  wbAddGroupOrder(TXST);\n  wbAddGroupOrder(MICN);\n  wbAddGroupOrder(GLOB);\n  wbAddGroupOrder(CLAS);\n  wbAddGroupOrder(FACT);\n  wbAddGroupOrder(HDPT);\n  wbAddGroupOrder(HAIR);\n  wbAddGroupOrder(EYES);\n  wbAddGroupOrder(RACE);\n  wbAddGroupOrder(SOUN);\n  wbAddGroupOrder(ASPC);\n  wbAddGroupOrder(MGEF);\n  wbAddGroupOrder(SCPT);\n  wbAddGroupOrder(LTEX);\n  wbAddGroupOrder(ENCH);\n  wbAddGroupOrder(SPEL);\n  wbAddGroupOrder(ACTI);\n  wbAddGroupOrder(TACT);\n  wbAddGroupOrder(TERM);\n  wbAddGroupOrder(ARMO);\n  wbAddGroupOrder(BOOK);\n  wbAddGroupOrder(CONT);\n  wbAddGroupOrder(DOOR);\n  wbAddGroupOrder(INGR);\n  wbAddGroupOrder(LIGH);\n  wbAddGroupOrder(MISC);\n  wbAddGroupOrder(STAT);\n  wbAddGroupOrder(SCOL);\n  wbAddGroupOrder(MSTT);\n  wbAddGroupOrder(PWAT);\n  wbAddGroupOrder(GRAS);\n  wbAddGroupOrder(TREE);\n  wbAddGroupOrder(FURN);\n  wbAddGroupOrder(WEAP);\n  wbAddGroupOrder(AMMO);\n  wbAddGroupOrder(NPC_);\n  wbAddGroupOrder(CREA);\n  wbAddGroupOrder(LVLC);\n  wbAddGroupOrder(LVLN);\n  wbAddGroupOrder(KEYM);\n  wbAddGroupOrder(ALCH);\n  wbAddGroupOrder(IDLM);\n  wbAddGroupOrder(NOTE);\n  wbAddGroupOrder(PROJ);\n  wbAddGroupOrder(LVLI);\n  wbAddGroupOrder(WTHR);\n  wbAddGroupOrder(CLMT);\n  wbAddGroupOrder(COBJ);\n  wbAddGroupOrder(REGN);\n  wbAddGroupOrder(NAVI);\n  wbAddGroupOrder(CELL);\n  wbAddGroupOrder(WRLD);\n  wbAddGroupOrder(DIAL);\n  wbAddGroupOrder(QUST);\n  wbAddGroupOrder(IDLE);\n  wbAddGroupOrder(PACK);\n  wbAddGroupOrder(CSTY);\n  wbAddGroupOrder(LSCR);\n  wbAddGroupOrder(ANIO);\n  wbAddGroupOrder(WATR);\n  wbAddGroupOrder(EFSH);\n  wbAddGroupOrder(EXPL);\n  wbAddGroupOrder(DEBR);\n  wbAddGroupOrder(IMGS);\n  wbAddGroupOrder(IMAD);\n  wbAddGroupOrder(FLST);\n  wbAddGroupOrder(PERK);\n  wbAddGroupOrder(BPTD);\n  wbAddGroupOrder(ADDN);\n  wbAddGroupOrder(AVIF);\n  wbAddGroupOrder(RADS);\n  wbAddGroupOrder(CAMS);\n  wbAddGroupOrder(CPTH);\n  wbAddGroupOrder(VTYP);\n  wbAddGroupOrder(IPCT);\n  wbAddGroupOrder(IPDS);\n  wbAddGroupOrder(ARMA);\n  wbAddGroupOrder(ECZN);\n  wbAddGroupOrder(MESG);\n  wbAddGroupOrder(RGDL);\n  wbAddGroupOrder(DOBJ);\n  wbAddGroupOrder(LGTM);\n  wbAddGroupOrder(MUSC);\nend;\n\nprocedure DefineFO3;\nbegin\n  DefineFO3a;\n  DefineFO3b;\n  DefineFO3c;\n  DefineFO3d;\n  DefineFO3e;\n  DefineFO3f;\nend;\n\nend.\n"
  },
  {
    "path": "lib/xedit/wbDefinitionsFO4.pas",
    "content": "{*******************************************************************************\n\n     The contents of this file are subject to the Mozilla Public License\n     Version 1.1 (the \"License\"); you may not use this file except in\n     compliance with the License. You may obtain a copy of the License at\n     http://www.mozilla.org/MPL/\n\n     Software distributed under the License is distributed on an \"AS IS\"\n     basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the\n     License for the specific language governing rights and limitations\n     under the License.\n\n*******************************************************************************}\n\nunit wbDefinitionsFO4;\n\n{$I wbDefines.inc}\n\ninterface\n\nuses\n  wbInterface;\n\nvar\n\twbBipedObjectFlags: IwbFlagsDef;\n\twbEquipType: IwbFlagsDef;\n\twbFurnitureEntryTypeFlags: IwbFlagsDef;\n\twbPKDTFlags: IwbFlagsDef;\n\twbPKDTInterruptFlags: IwbFlagsDef;\n\twbSMNodeFlags: IwbFlagsDef;\n\n\twbActorPropertyEnum: IwbEnumDef;\n\twbAdvanceActionEnum: IwbEnumDef;\n\twbStaggerEnum: IwbEnumDef;\n\twbAlignmentEnum: IwbEnumDef;\n\twbArmorPropertyEnum: IwbEnumDef;\n\twbAxisEnum: IwbEnumDef;\n\twbBipedObjectEnum: IwbEnumDef;\n\twbBlendModeEnum: IwbEnumDef;\n\twbBlendOpEnum: IwbEnumDef;\n\twbBodyPartIndexEnum: IwbEnumDef;\n\twbCastEnum: IwbEnumDef;\n\twbCastingSourceEnum: IwbEnumDef;\n\twbCrimeTypeEnum: IwbEnumDef;\n\twbCriticalStageEnum: IwbEnumDef;\n\twbEmotionTypeEnum: IwbEnumDef;\n\twbEntryPointsEnum: IwbEnumDef;\n\twbEventFunctionEnum: IwbEnumDef;\n\twbEventMemberEnum: IwbEnumDef;\n\twbFormTypeEnum: IwbEnumDef;\n\twbFurnitureAnimTypeEnum: IwbEnumDef;\n\twbLocationEnum: IwbEnumDef;\n\twbMiscStatEnum: IwbEnumDef;\n\twbMusicEnum: IwbEnumDef;\n  wbObjectModProperties: IwbArrayDef;\n\twbObjectTypeEnum: IwbEnumDef;\n\twbPropTypeEnum: IwbEnumDef;\n\twbQuadrantEnum: IwbEnumDef;\n\twbSexEnum: IwbEnumDef;\n\twbSkillEnum: IwbEnumDef;\n\twbSoulGemEnum: IwbEnumDef;\n\twbSoundLevelEnum: IwbEnumDef;\n\twbTargetEnum: IwbEnumDef;\n\twbVatsValueFunctionEnum: IwbEnumDef;\n\twbWardStateEnum: IwbEnumDef;\n\twbWeaponAnimTypeEnum: IwbEnumDef;\n\twbWeaponPropertyEnum: IwbEnumDef;\n\twbZTestFuncEnum: IwbEnumDef;\n  wbKeywordTypeEnum: IwbEnumDef;\n  wbReverbClassEnum: IwbEnumDef;\n  wbHitBehaviourEnum: IwbEnumDef;\n  wbBoolEnum: IwbEnumDef;\n\nprocedure DefineFO4;\n\nimplementation\n\nuses\n  Types,\n  Classes,\n  SysUtils,\n  Math,\n  Variants,\n  wbHelpers;\n\nconst\n  _00_IAD: TwbSignature = #$00'IAD';\n  _01_IAD: TwbSignature = #$01'IAD';\n  _02_IAD: TwbSignature = #$02'IAD';\n  _03_IAD: TwbSignature = #$03'IAD';\n  _04_IAD: TwbSignature = #$04'IAD';\n  _05_IAD: TwbSignature = #$05'IAD';\n  _06_IAD: TwbSignature = #$06'IAD';\n  _07_IAD: TwbSignature = #$07'IAD';\n  _08_IAD: TwbSignature = #$08'IAD';\n  _09_IAD: TwbSignature = #$09'IAD';\n  _0A_IAD: TwbSignature = #$0A'IAD';\n  _0B_IAD: TwbSignature = #$0B'IAD';\n  _0C_IAD: TwbSignature = #$0C'IAD';\n  _0D_IAD: TwbSignature = #$0D'IAD';\n  _0E_IAD: TwbSignature = #$0E'IAD';\n  _0F_IAD: TwbSignature = #$0F'IAD';\n  _10_IAD: TwbSignature = #$10'IAD';\n  _11_IAD: TwbSignature = #$11'IAD';\n  _12_IAD: TwbSignature = #$12'IAD';\n  _13_IAD: TwbSignature = #$13'IAD';\n  _14_IAD: TwbSignature = #$14'IAD';\n  _40_IAD: TwbSignature = #$40'IAD';\n  _41_IAD: TwbSignature = #$41'IAD';\n  _42_IAD: TwbSignature = #$42'IAD';\n  _43_IAD: TwbSignature = #$43'IAD';\n  _44_IAD: TwbSignature = #$44'IAD';\n  _45_IAD: TwbSignature = #$45'IAD';\n  _46_IAD: TwbSignature = #$46'IAD';\n  _47_IAD: TwbSignature = #$47'IAD';\n  _48_IAD: TwbSignature = #$48'IAD';\n  _49_IAD: TwbSignature = #$49'IAD';\n  _4A_IAD: TwbSignature = #$4A'IAD';\n  _4B_IAD: TwbSignature = #$4B'IAD';\n  _4C_IAD: TwbSignature = #$4C'IAD';\n  _4D_IAD: TwbSignature = #$4D'IAD';\n  _4E_IAD: TwbSignature = #$4E'IAD';\n  _4F_IAD: TwbSignature = #$4F'IAD';\n  _50_IAD: TwbSignature = #$50'IAD';\n  _51_IAD: TwbSignature = #$51'IAD';\n  _52_IAD: TwbSignature = #$52'IAD';\n  _53_IAD: TwbSignature = #$53'IAD';\n  _54_IAD: TwbSignature = #$54'IAD';\n\n{00TX} _00_0TX: TwbSignature = #$30'0TX';\n{10TX} _10_0TX: TwbSignature = #$31'0TX';\n{20TX} _20_0TX: TwbSignature = #$32'0TX';\n{30TX} _30_0TX: TwbSignature = #$33'0TX';\n{40TX} _40_0TX: TwbSignature = #$34'0TX';\n{50TX} _50_0TX: TwbSignature = #$35'0TX';\n{60TX} _60_0TX: TwbSignature = #$36'0TX';\n{70TX} _70_0TX: TwbSignature = #$37'0TX';\n{80TX} _80_0TX: TwbSignature = #$38'0TX';\n{90TX} _90_0TX: TwbSignature = #$39'0TX';\n{:0TX} _3A_0TX: TwbSignature = #$3A'0TX';\n{;0TX} _3B_0TX: TwbSignature = #$3B'0TX';\n{<0TX} _3C_0TX: TwbSignature = #$3C'0TX';\n{=0TX} _3D_0TX: TwbSignature = #$3D'0TX';\n{>0TX} _3E_0TX: TwbSignature = #$3E'0TX';\n{?0TX} _3F_0TX: TwbSignature = #$3F'0TX';\n{@0TX} _40h_0TX: TwbSignature = #$40'0TX';\n{A0TX} A0TX: TwbSignature = 'A0TX';\n{B0TX} B0TX: TwbSignature = 'B0TX';\n{C0TX} C0TX: TwbSignature = 'C0TX';\n{D0TX} D0TX: TwbSignature = 'D0TX';\n{E0TX} E0TX: TwbSignature = 'E0TX';\n{F0TX} F0TX: TwbSignature = 'F0TX';\n{G0TX} G0TX: TwbSignature = 'G0TX';\n{H0TX} H0TX: TwbSignature = 'H0TX';\n{I0TX} I0TX: TwbSignature = 'I0TX';\n{J0TX} J0TX: TwbSignature = 'J0TX';\n{K0TX} K0TX: TwbSignature = 'K0TX';\n{L0TX} L0TX: TwbSignature = 'L0TX';\n\n  AACT : TwbSignature = 'AACT';\n  ACBS : TwbSignature = 'ACBS';\n  ACEC : TwbSignature = 'ACEC'; { New To Dawnguard }\n  ACEP : TwbSignature = 'ACEP'; { New To Dawnguard }\n  ACHR : TwbSignature = 'ACHR';\n  ACID : TwbSignature = 'ACID'; { New To Dawnguard }\n  ACPR : TwbSignature = 'ACPR'; { New To Skyrim }\n  ACSR : TwbSignature = 'ACSR'; { New To Dawnguard }\n  ACTI : TwbSignature = 'ACTI';\n  ACTV : TwbSignature = 'ACTV'; { New To Fallout 4 }\n  ACUN : TwbSignature = 'ACUN'; { New To Dawnguard }\n  ADDN : TwbSignature = 'ADDN';\n  AECH : TwbSignature = 'AECH'; { New To Fallout 4 }\n  AHCF : TwbSignature = 'AHCF'; { New To Skyrim }\n  AHCM : TwbSignature = 'AHCM'; { New To Skyrim }\n  AIDT : TwbSignature = 'AIDT';\n  ALCA : TwbSignature = 'ALCA'; { New To Skyrim }\n  ALCC : TwbSignature = 'ALCC'; { New To Fallout 4 }\n  ALCH : TwbSignature = 'ALCH';\n  ALCL : TwbSignature = 'ALCL'; { New To Skyrim }\n  ALCO : TwbSignature = 'ALCO'; { New To Skyrim }\n  ALCS : TwbSignature = 'ALCS'; { New To Fallout 4 }\n  ALDI : TwbSignature = 'ALDI'; { New To Fallout 4 }\n  ALDN : TwbSignature = 'ALDN'; { New To Skyrim }\n  ALEA : TwbSignature = 'ALEA'; { New To Skyrim }\n  ALED : TwbSignature = 'ALED'; { New To Skyrim }\n  ALEQ : TwbSignature = 'ALEQ'; { New To Skyrim }\n  ALFA : TwbSignature = 'ALFA'; { New To Skyrim }\n  ALFC : TwbSignature = 'ALFC'; { New To Skyrim }\n  ALFD : TwbSignature = 'ALFD'; { New To Skyrim }\n  ALFE : TwbSignature = 'ALFE'; { New To Skyrim }\n  ALFI : TwbSignature = 'ALFI'; { New To Skyrim }\n  ALFL : TwbSignature = 'ALFL'; { New To Skyrim }\n  ALFR : TwbSignature = 'ALFR'; { New To Skyrim }\n  ALFV : TwbSignature = 'ALFV'; { New To Fallout 4 }\n  ALID : TwbSignature = 'ALID'; { New To Skyrim }\n  ALLA : TwbSignature = 'ALLA'; { New To Fallout 4 }\n  ALLS : TwbSignature = 'ALLS'; { New To Skyrim }\n  ALMI : TwbSignature = 'ALMI'; { New To Fallout 4 }\n  ALNA : TwbSignature = 'ALNA'; { New To Skyrim }\n  ALNT : TwbSignature = 'ALNT'; { New To Skyrim }\n  ALPC : TwbSignature = 'ALPC'; { New To Skyrim }\n  ALRT : TwbSignature = 'ALRT'; { New To Skyrim }\n  ALSP : TwbSignature = 'ALSP'; { New To Skyrim }\n  ALST : TwbSignature = 'ALST'; { New To Skyrim }\n  ALUA : TwbSignature = 'ALUA'; { New To Skyrim }\n  AMDL : TwbSignature = 'AMDL'; { New To Fallout 4 }\n  AMMO : TwbSignature = 'AMMO';\n  ANAM : TwbSignature = 'ANAM';\n  ANIO : TwbSignature = 'ANIO';\n  AOR2 : TwbSignature = 'AOR2'; { New To Fallout 4 }\n  AORU : TwbSignature = 'AORU'; { New To Fallout 4 }\n  APPR : TwbSignature = 'APPR'; { New To Fallout 4 }\n  ARMA : TwbSignature = 'ARMA';\n  ARMO : TwbSignature = 'ARMO';\n  ARTO : TwbSignature = 'ARTO';\n  ASPC : TwbSignature = 'ASPC';\n  ASTP : TwbSignature = 'ASTP';\n  ATKD : TwbSignature = 'ATKD'; { New to Skyrim }\n  ATKE : TwbSignature = 'ATKE'; { New to Skyrim }\n  ATKR : TwbSignature = 'ATKR'; { New to Skyrim }\n  ATKT : TwbSignature = 'ATKT'; { New To Fallout 4 }\n  ATKS : TwbSignature = 'ATKS'; { New To Fallout 4 }\n  ATKW : TwbSignature = 'ATKW'; { New To Fallout 4 }\n  ATTN : TwbSignature = 'ATTN'; { New To Fallout 4 }\n  ATTX : TwbSignature = 'ATTX'; { New To Fallout 4 }\n  ATXT : TwbSignature = 'ATXT';\n  AVFL : TwbSignature = 'AVFL'; { New To Fallout 4 }\n  AVIF : TwbSignature = 'AVIF';\n  AVSK : TwbSignature = 'AVSK'; { New to Skyrim }\n  BAMT : TwbSignature = 'BAMT'; { New to Skyrim }\n  BCLF : TwbSignature = 'BCLF'; { New to Fallout 4 }\n  BIDS : TwbSignature = 'BIDS'; { New to Skyrim }\n  BIPL : TwbSignature = 'BIPL';\n  BMCT : TwbSignature = 'BMCT';\n  BMMP : TwbSignature = 'BMMP'; { New to Fallout 4 }\n  BNAM : TwbSignature = 'BNAM';\n  BNDS : TwbSignature = 'BNDS'; { New to Fallout 4 }\n  BOD2 : TwbSignature = 'BOD2'; { New to Skyrim 1.6.91 CK}\n  BODT : TwbSignature = 'BODT'; { New to Skyrim }\n  BOOK : TwbSignature = 'BOOK';\n  BPND : TwbSignature = 'BPND';\n  BPNI : TwbSignature = 'BPNI';\n  BPNN : TwbSignature = 'BPNN';\n  BPNT : TwbSignature = 'BPNT';\n  BPTD : TwbSignature = 'BPTD';\n  BPTN : TwbSignature = 'BPTN';\n  BSIZ : TwbSignature = 'BSIZ'; { New to Fallout 4 }\n  BSMB : TwbSignature = 'BSMB'; { New to Fallout 4 }\n  BSMP : TwbSignature = 'BSMP'; { New to Fallout 4 }\n  BSMS : TwbSignature = 'BSMS'; { New to Fallout 4 }\n  BTXT : TwbSignature = 'BTXT';\n  CAMS : TwbSignature = 'CAMS';\n  CDIX : TwbSignature = 'CDIX'; { New to Fallout 4 }\n  CELL : TwbSignature = 'CELL';\n  CIS1 : TwbSignature = 'CIS1'; { New to Skyrim }\n  CIS2 : TwbSignature = 'CIS2'; { New to Skyrim }\n  CITC : TwbSignature = 'CITC'; { New to Skyrim }\n  CLAS : TwbSignature = 'CLAS';\n  CLFM : TwbSignature = 'CLFM';\n  CLMT : TwbSignature = 'CLMT';\n  CLSZ : TwbSignature = 'CLSZ'; { New to Fallout 4 }\n  CMPO : TwbSignature = 'CMPO'; { New to Fallout 4 }\n  CNAM : TwbSignature = 'CNAM';\n  CNTO : TwbSignature = 'CNTO';\n  COBJ : TwbSignature = 'COBJ';\n  COCT : TwbSignature = 'COCT'; { New to Skyrim 'Count'}\n  COED : TwbSignature = 'COED';\n  COLL : TwbSignature = 'COLL';\n  CONT : TwbSignature = 'CONT';\n  CPTH : TwbSignature = 'CPTH';\n  CRDT : TwbSignature = 'CRDT';\n  CRGR : TwbSignature = 'CRGR'; { New to Skyrim }\n  CRIF : TwbSignature = 'CRIF'; { New to Skyrim }\n  CRIS : TwbSignature = 'CRIS'; { New to Fallout 4 }\n  CRVA : TwbSignature = 'CRVA'; { New to Skyrim }\n  CS2H : TwbSignature = 'CS2H'; { New To Fallout 4 }\n  CS2D : TwbSignature = 'CS2D'; { New To Fallout 4 }\n  CS2E : TwbSignature = 'CS2E'; { New To Fallout 4 }\n  CS2F : TwbSignature = 'CS2F'; { New To Fallout 4 }\n  CS2K : TwbSignature = 'CS2K'; { New To Fallout 4 }\n  CSCR : TwbSignature = 'CSCR';\n  CSCV : TwbSignature = 'CSCV'; { New To Fallout 4 }\n  CSDC : TwbSignature = 'CSDC';\n  CSDI : TwbSignature = 'CSDI';\n  CSDT : TwbSignature = 'CSDT';\n  CSFL : TwbSignature = 'CSFL'; { New to Skyrim }\n  CSGD : TwbSignature = 'CSGD'; { New to Skyrim }\n  CSLR : TwbSignature = 'CSLR'; { New to Skyrim }\n  CSMD : TwbSignature = 'CSMD'; { New to Skyrim }\n  CSME : TwbSignature = 'CSME'; { New to Skyrim }\n  CSRA : TwbSignature = 'CSRA'; { New To Fallout 4 }\n  CSTY : TwbSignature = 'CSTY';\n  CTDA : TwbSignature = 'CTDA';\n  CUSD : TwbSignature = 'CUSD'; { New to Fallout 4 }\n  CVPA : TwbSignature = 'CVPA'; { New to Fallout 4 }\n  DALC : TwbSignature = 'DALC'; { New to Skyrim }\n  DAMA : TwbSignature = 'DAMA'; { New to Fallout 4 }\n  DAMC : TwbSignature = 'DAMC'; { New to Fallout 4 }\n  DATA : TwbSignature = 'DATA';\n  DEBR : TwbSignature = 'DEBR';\n  DELE : TwbSignature = 'DELE';\n  DEMO : TwbSignature = 'DEMO'; { New to Skyrim }\n  DESC : TwbSignature = 'DESC';\n  DEST : TwbSignature = 'DEST';\n  DEVA : TwbSignature = 'DEVA'; { New to Skyrim }\n  DFOB : TwbSignature = 'DFOB'; { New to Fallout 4 }\n  DFTF : TwbSignature = 'DFTF'; { New To Skyrim }\n  DFTM : TwbSignature = 'DFTM'; { New To Skyrim }\n  DIAL : TwbSignature = 'DIAL';\n  DLBR : TwbSignature = 'DLBR';\n  DLVW : TwbSignature = 'DLVW';\n  DMAX : TwbSignature = 'DMAX'; { New to Skyrim }\n  DMDC : TwbSignature = 'DMDC'; { New to Fallout 4 }\n  DMDL : TwbSignature = 'DMDL';\n  DMDS : TwbSignature = 'DMDS'; { New to Skyrim }\n  DMDT : TwbSignature = 'DMDT';\n  DMGT : TwbSignature = 'DMGT'; { New to Fallout 4 }\n  DMIN : TwbSignature = 'DMIN'; { New to Skyrim }\n  DNAM : TwbSignature = 'DNAM';\n  DOBJ : TwbSignature = 'DOBJ';\n  DODT : TwbSignature = 'DODT';\n  DOFT : TwbSignature = 'DOFT'; { New to Skyrim }\n  DOOR : TwbSignature = 'DOOR';\n  DPLT : TwbSignature = 'DPLT'; { New to Skyrim }\n  DSTA : TwbSignature = 'DSTA'; { New To Fallout 4 }\n  DSTD : TwbSignature = 'DSTD';\n  DSTF : TwbSignature = 'DSTF';\n  DTGT : TwbSignature = 'DTGT'; { New To Fallout 4 }\n  DTID : TwbSignature = 'DTID'; { New To Fallout 4 }\n  DUAL : TwbSignature = 'DUAL';\n  EAMT : TwbSignature = 'EAMT';\n  ECOR : TwbSignature = 'ECOR'; { New to Skyrim }\n  ECZN : TwbSignature = 'ECZN';\n  EDID : TwbSignature = 'EDID';\n  EFID : TwbSignature = 'EFID';\n  EFIT : TwbSignature = 'EFIT';\n  EFSH : TwbSignature = 'EFSH';\n  EITM : TwbSignature = 'EITM';\n  ENAM : TwbSignature = 'ENAM';\n  ENCH : TwbSignature = 'ENCH';\n  ENIT : TwbSignature = 'ENIT';\n  EPF2 : TwbSignature = 'EPF2';\n  EPF3 : TwbSignature = 'EPF3';\n  EPFB : TwbSignature = 'EPFB'; { New To Fallout 4 }\n  EPFD : TwbSignature = 'EPFD';\n  EPFT : TwbSignature = 'EPFT';\n  EQUP : TwbSignature = 'EQUP';\n  ESCE : TwbSignature = 'ESCE';\n  ETYP : TwbSignature = 'ETYP';\n  EXPL : TwbSignature = 'EXPL';\n  EYES : TwbSignature = 'EYES';\n  FACT : TwbSignature = 'FACT';\n  FCHT : TwbSignature = 'FCHT'; { New to Skyrim }\n  FCPL : TwbSignature = 'FCPL'; { New To Fallout 4 }\n  FFFF : TwbSignature = 'FFFF';\n  FIMD : TwbSignature = 'FIMD'; { New To Fallout 4 }\n  FLMV : TwbSignature = 'FLMV'; { New to Skyrim }\n  FLOR : TwbSignature = 'FLOR';\n  FLST : TwbSignature = 'FLST';\n  FLTR : TwbSignature = 'FLTR'; { New to Skyrim }\n  FLTV : TwbSignature = 'FLTV';\n  FMIN : TwbSignature = 'FMIN'; { New To Fallout 4 }\n  FMRI : TwbSignature = 'FMRI'; { New To Fallout 4 }\n  FMRN : TwbSignature = 'FMRN'; { New To Fallout 4 }\n  FMRS : TwbSignature = 'FMRS'; { New To Fallout 4 }\n  FNAM : TwbSignature = 'FNAM';\n  FNMK : TwbSignature = 'FNMK'; { New to Skyrim }\n  FNPR : TwbSignature = 'FNPR'; { New to Skyrim }\n  FPRT : TwbSignature = 'FPRT'; { New to Skyrim }\n  FSTP : TwbSignature = 'FSTP';\n  FSTS : TwbSignature = 'FSTS';\n  FTSF : TwbSignature = 'FTSF'; { New to Skyrim }\n  FTSM : TwbSignature = 'FTSM'; { New to Skyrim }\n  FTST : TwbSignature = 'FTST'; { New to Skyrim }\n  FTYP : TwbSignature = 'FTYP'; { New To Fallout 4 }\n  FULL : TwbSignature = 'FULL';\n  FURN : TwbSignature = 'FURN';\n  FVPA : TwbSignature = 'FVPA'; { New To Fallout 4 }\n  GDRY : TwbSignature = 'GDRY'; { New to Fallout 4 }\n  GLOB : TwbSignature = 'GLOB';\n  GMST : TwbSignature = 'GMST';\n  GNAM : TwbSignature = 'GNAM';\n  GRAS : TwbSignature = 'GRAS';\n  GREE : TwbSignature = 'GREE'; { New to Fallout 4 }\n  GWOR : TwbSignature = 'GWOR'; { New to Skyrim }\n  HAZD : TwbSignature = 'HAZD';\n  HCLF : TwbSignature = 'HCLF'; { New to Skyrim }\n  HDPT : TwbSignature = 'HDPT';\n  HEAD : TwbSignature = 'HEAD'; { New to Skyrim }\n  HEDR : TwbSignature = 'HEDR';\n  HLTX : TwbSignature = 'HLTX'; { New to Fallout 4 }\n  HNAM : TwbSignature = 'HNAM';\n  HTID : TwbSignature = 'HTID'; { New to Skyrim }\n  ICO2 : TwbSignature = 'ICO2';\n  ICON : TwbSignature = 'ICON';\n  IDLA : TwbSignature = 'IDLA';\n  IDLB : TwbSignature = 'IDLB';\n  IDLC : TwbSignature = 'IDLC';\n  IDLE : TwbSignature = 'IDLE';\n  IDLF : TwbSignature = 'IDLF';\n  IDLM : TwbSignature = 'IDLM';\n  IDLT : TwbSignature = 'IDLT';\n  IMAD : TwbSignature = 'IMAD';\n  IMGS : TwbSignature = 'IMGS';\n  IMSP : TwbSignature = 'IMSP'; { New to Skyrim }\n  INAM : TwbSignature = 'INAM';\n  INCC : TwbSignature = 'INCC'; { New to Skyrim }\n  INDX : TwbSignature = 'INDX';\n  INFO : TwbSignature = 'INFO';\n  INGR : TwbSignature = 'INGR';\n  INNR : TwbSignature = 'INNR'; { New To Fallout 4 }\n  INRD : TwbSignature = 'INRD'; { New To Fallout 4 }\n  INTT : TwbSignature = 'INTT'; { New To Fallout 4 }\n  INTV : TwbSignature = 'INTV';\n  IOVR : TwbSignature = 'IOVR'; { New To Fallout 4 }\n  IPCT : TwbSignature = 'IPCT';\n  IPDS : TwbSignature = 'IPDS';\n  ISIZ : TwbSignature = 'ISIZ'; { New To Fallout 4 }\n  ITID : TwbSignature = 'ITID'; { New To Fallout 4 }\n  ITMC : TwbSignature = 'ITMC'; { New To Fallout 4 }\n  ITME : TwbSignature = 'ITME'; { New To Fallout 4 }\n  ITMS : TwbSignature = 'ITMS'; { New To Fallout 4 }\n  ITXT : TwbSignature = 'ITXT';\n  JAIL : TwbSignature = 'JAIL'; { New To Skyrim }\n  JNAM : TwbSignature = 'JNAM';\n  JOUT : TwbSignature = 'JOUT'; { New To Skyrim }\n  KEYM : TwbSignature = 'KEYM';\n  KNAM : TwbSignature = 'KNAM';\n  KSIZ : TwbSignature = 'KSIZ';\n  KSSM : TwbSignature = 'KSSM'; { New To Fallout 4 }\n  KWDA : TwbSignature = 'KWDA';\n  KYWD : TwbSignature = 'KYWD';\n  LAND : TwbSignature = 'LAND';\n  LAYR : TwbSignature = 'LAYR'; { New to Fallout 4 }\n  LCEC : TwbSignature = 'LCEC'; { New to Skyrim }\n  LCEP : TwbSignature = 'LCEP'; { New to Skyrim }\n  LCID : TwbSignature = 'LCID'; { New to Skyrim }\n  LCPR : TwbSignature = 'LCPR'; { New to Skyrim }\n  LCRT : TwbSignature = 'LCRT';\n  LCSR : TwbSignature = 'LCSR'; { New to Skyrim }\n  LCTN : TwbSignature = 'LCTN';\n  LCUN : TwbSignature = 'LCUN'; { New to Skyrim }\n  LENS : TwbSignature = 'LENS'; { New to Fallout 4 }\n  LFSD : TwbSignature = 'LFSD'; { New to Fallout 4 }\n  LFSP : TwbSignature = 'LFSP'; { New to Fallout 4 }\n  LGTM : TwbSignature = 'LGTM';\n  LIGH : TwbSignature = 'LIGH';\n  LLCT : TwbSignature = 'LLCT'; {New to Skyrim, part of LVLI 'Count'}\n  LLKC : TwbSignature = 'LLKC'; { New to Fallout 4 }\n  LNAM : TwbSignature = 'LNAM';\n  LSCR : TwbSignature = 'LSCR';\n  LSPR : TwbSignature = 'LSPR'; { New to Fallout 4 }\n  LTEX : TwbSignature = 'LTEX';\n  LTMP : TwbSignature = 'LTMP';\n  LTPT : TwbSignature = 'LTPT'; { New to Fallout 4 }\n  LTPC : TwbSignature = 'LTPC'; { New to Fallout 4 }\n  LVLC : TwbSignature = 'LVLC';\n  LVLD : TwbSignature = 'LVLD';\n  LVLF : TwbSignature = 'LVLF';\n  LVLG : TwbSignature = 'LVLG';\n  LVLI : TwbSignature = 'LVLI';\n  LVLM : TwbSignature = 'LVLM'; { New to Fallout 4 }\n  LVLN : TwbSignature = 'LVLN';\n  LVLO : TwbSignature = 'LVLO';\n  LVSG : TwbSignature = 'LVSG'; { New to Fallout 4 }\n  LVSP : TwbSignature = 'LVSP';\n  MASE : TwbSignature = 'MASE'; { New To Fallout 4 }\n  MAST : TwbSignature = 'MAST';\n  MATO : TwbSignature = 'MATO';\n  MATT : TwbSignature = 'MATT';\n  MCHT : TwbSignature = 'MCHT'; { New to Skyrim }\n  MDOB : TwbSignature = 'MDOB';\n  MESG : TwbSignature = 'MESG';\n  MGEF : TwbSignature = 'MGEF';\n  MHDT : TwbSignature = 'MHDT'; { New to Skyrim }\n  MIC2 : TwbSignature = 'MIC2';\n  MICN : TwbSignature = 'MICN'; { New to Fallout 4 }\n  MICO : TwbSignature = 'MICO';\n  MISC : TwbSignature = 'MISC';\n  MLSI : TwbSignature = 'MLSI'; { New to Fallout 4 }\n  MNAM : TwbSignature = 'MNAM';\n  MO2C : TwbSignature = 'MO2C'; { New to Fallout 4 }\n  MO2F : TwbSignature = 'MO2F'; { New to Fallout 4 }\n  MO2S : TwbSignature = 'MO2S';\n  MO2T : TwbSignature = 'MO2T';\n  MO3C : TwbSignature = 'MO3C'; { New to Fallout 4 }\n  MO3F : TwbSignature = 'MO3F'; { New to Fallout 4 }\n  MO3S : TwbSignature = 'MO3S';\n  MO3T : TwbSignature = 'MO3T';\n  MO4C : TwbSignature = 'MO4C'; { New to Fallout 4 }\n  MO4F : TwbSignature = 'MO4F'; { New to Fallout 4 }\n  MO4S : TwbSignature = 'MO4S';\n  MO4T : TwbSignature = 'MO4T';\n  MO5C : TwbSignature = 'MO5C'; { New to Fallout 4 }\n  MO5F : TwbSignature = 'MO5F'; { New to Fallout 4 }\n  MO5S : TwbSignature = 'MO5S'; { New to Skyrim }\n  MO5T : TwbSignature = 'MO5T'; { New to Skyrim }\n  MOD2 : TwbSignature = 'MOD2';\n  MOD3 : TwbSignature = 'MOD3';\n  MOD4 : TwbSignature = 'MOD4';\n  MOD5 : TwbSignature = 'MOD5'; { New to Skyrim }\n  MODC : TwbSignature = 'MODC'; { New to Fallout 4 }\n  MODF : TwbSignature = 'MODF'; { New to Fallout 4 }\n  MODL : TwbSignature = 'MODL';\n  MODS : TwbSignature = 'MODS';\n  MODT : TwbSignature = 'MODT';\n  MODQ : TwbSignature = 'MODQ'; { New to Fallout 4 }\n  MOVT : TwbSignature = 'MOVT';\n  MPAI : TwbSignature = 'MPAI'; { New To Skyrim }\n  MPAV : TwbSignature = 'MPAV'; { New To Skyrim }\n  MPCD : TwbSignature = 'MPCD'; { New to Fallout 4 }\n  MPGN : TwbSignature = 'MPGN'; { New to Fallout 4 }\n  MPGS : TwbSignature = 'MPGS'; { New to Fallout 4 }\n  MPPC : TwbSignature = 'MPPC'; { New to Fallout 4 }\n  MPPF : TwbSignature = 'MPPF'; { New to Fallout 4 }\n  MPPI : TwbSignature = 'MPPI'; { New to Fallout 4 }\n  MPPK : TwbSignature = 'MPPK'; { New to Fallout 4 }\n  MPPM : TwbSignature = 'MPPM'; { New to Fallout 4 }\n  MPPN : TwbSignature = 'MPPN'; { New to Fallout 4 }\n  MPPT : TwbSignature = 'MPPT'; { New to Fallout 4 }\n  MPRT : TwbSignature = 'MPRT'; { New to Skyrim }\n  MRSV : TwbSignature = 'MRSV'; { New to Fallout 4 }\n  MSDK : TwbSignature = 'MSDK'; { New to Fallout 4 }\n  MSDV : TwbSignature = 'MSDV'; { New to Fallout 4 }\n  MSID : TwbSignature = 'MSID'; { New to Fallout 4 }\n  MSM0 : TwbSignature = 'MSM0'; { New to Fallout 4 }\n  MSM1 : TwbSignature = 'MSM1'; { New to Fallout 4 }\n  MSTT : TwbSignature = 'MSTT';\n  MSWP : TwbSignature = 'MSWP'; { New to Fallout 4 }\n  MTNM : TwbSignature = 'MTNM'; { New to Skyrim }\n  MTYP : TwbSignature = 'MTYP'; { New To Skyrim }\n  MUSC : TwbSignature = 'MUSC';\n  MUST : TwbSignature = 'MUST';\n  MWGT : TwbSignature = 'MWGT'; { New to Fallout 4 }\n  NAM0 : TwbSignature = 'NAM0';\n  NAM1 : TwbSignature = 'NAM1';\n  NAM2 : TwbSignature = 'NAM2';\n  NAM3 : TwbSignature = 'NAM3';\n  NAM4 : TwbSignature = 'NAM4';\n  NAM5 : TwbSignature = 'NAM5';\n  NAM6 : TwbSignature = 'NAM6';\n  NAM7 : TwbSignature = 'NAM7';\n  NAM8 : TwbSignature = 'NAM8';\n  NAM9 : TwbSignature = 'NAM9';\n  NAMA : TwbSignature = 'NAMA'; { New to Skyrim }\n  NAME : TwbSignature = 'NAME';\n  NAVI : TwbSignature = 'NAVI';\n  NAVM : TwbSignature = 'NAVM';\n  NETO : TwbSignature = 'NETO'; { New to Fallout 4 }\n  NEXT : TwbSignature = 'NEXT';\n  NNAM : TwbSignature = 'NNAM';\n  NNGT : TwbSignature = 'NNGT'; { New to Fallout 4 }\n  NNGS : TwbSignature = 'NNGS'; { New to Fallout 4 }\n  NNUS : TwbSignature = 'NNUS'; { New to Fallout 4 }\n  NNUT : TwbSignature = 'NNUT'; { New to Fallout 4 }\n  NOCM : TwbSignature = 'NOCM'; { New to Fallout 4 }\n  NONE : TwbSignature = 'NONE'; { New to Fallout 4, used in OMOD Form Type }\n  NOTE : TwbSignature = 'NOTE'; { New to Fallout 4 }\n  NPC_ : TwbSignature = 'NPC_';\n  NPOS : TwbSignature = 'NPOS'; { New to Fallout 4 }\n  NPOT : TwbSignature = 'NPOT'; { New to Fallout 4 }\n  NQUS : TwbSignature = 'NQUS'; { New to Fallout 4 }\n  NQUT : TwbSignature = 'NQUT'; { New to Fallout 4 }\n  NTOP : TwbSignature = 'NTOP'; { New to Fallout 4 }\n  NTRM : TwbSignature = 'NTRM'; { New to Fallout 4 }\n  NULL : TwbSignature = 'NULL';\n  NVER : TwbSignature = 'NVER';\n  NVMI : TwbSignature = 'NVMI';\n  NVNM : TwbSignature = 'NVNM'; { New to Skyrim }\n  NVPP : TwbSignature = 'NVPP'; { New to Skyrim }\n  NVSI : TwbSignature = 'NVSI'; { New to Dawnguard }\n  OBND : TwbSignature = 'OBND';\n  OBTE : TwbSignature = 'OBTE'; { New to Fallout 4 }\n  OBTF : TwbSignature = 'OBTF'; { New to Fallout 4 }\n  OBTS : TwbSignature = 'OBTS'; { New to Fallout 4 }\n  OCOR : TwbSignature = 'OCOR'; { New to Skyrim }\n  OFST : TwbSignature = 'OFST';\n  OMOD : TwbSignature = 'OMOD'; { New to Fallout 4 }\n  ONAM : TwbSignature = 'ONAM';\n  OTFT : TwbSignature = 'OTFT';\n  OVIS : TwbSignature = 'OVIS'; { New to Fallout 4 }\n  PACK : TwbSignature = 'PACK';\n  PARW : TwbSignature = 'PARW'; { New to Skyrim }\n  PBAR : TwbSignature = 'PBAR'; { New to Skyrim }\n  PBEA : TwbSignature = 'PBEA'; { New to Skyrim }\n  PCMB : TwbSignature = 'PCMB'; { New to Fallout 4 }\n  PCON : TwbSignature = 'PCON'; { New to Skyrim }\n  PDTO : TwbSignature = 'PDTO'; { New to Skyrim }\n  PERK : TwbSignature = 'PERK';\n  PFIG : TwbSignature = 'PFIG';\n  PFLA : TwbSignature = 'PFLA'; { New to Skyrim }\n  PFO2 : TwbSignature = 'PFO2'; { New to Skyrim }\n  PFOR : TwbSignature = 'PFOR'; { New to Skyrim }\n  PFPC : TwbSignature = 'PFPC';\n  PFRN : TwbSignature = 'PFRN'; { New to Fallout 4 }\n  PGRE : TwbSignature = 'PGRE';\n  PHTN : TwbSignature = 'PHTN'; { New to Skyrim }\n  PHWT : TwbSignature = 'PHWT'; { New to Skyrim }\n  PHZD : TwbSignature = 'PHZD';\n  PKC2 : TwbSignature = 'PKC2'; { New to Skyrim }\n  PKCU : TwbSignature = 'PKCU'; { New to Skyrim }\n  PKDT : TwbSignature = 'PKDT';\n  PKID : TwbSignature = 'PKID';\n  PKIN : TwbSignature = 'PKIN'; { New to Fallout 4 }\n  PLCN : TwbSignature = 'PLCN'; { New to Skyrim }\n  PLDT : TwbSignature = 'PLDT';\n  PLVD : TwbSignature = 'PLVD'; { New to Skyrim }\n  PLYR : TwbSignature = 'PLYR';\n  PMIS : TwbSignature = 'PMIS';\n  PNAM : TwbSignature = 'PNAM';\n  POBA : TwbSignature = 'POBA';\n  POCA : TwbSignature = 'POCA';\n  POEA : TwbSignature = 'POEA';\n  PRCB : TwbSignature = 'PRCB'; { New to Skyrim }\n  PRKC : TwbSignature = 'PRKC';\n  PRKE : TwbSignature = 'PRKE';\n  PRKF : TwbSignature = 'PRKF';\n  PRKR : TwbSignature = 'PRKR'; { New to Skyrim }\n  PRKZ : TwbSignature = 'PRKZ'; { New to Skyrim }\n  PROJ : TwbSignature = 'PROJ';\n  PRPS : TwbSignature = 'PRPS'; { New to Fallout 4 }\n  PSDT : TwbSignature = 'PSDT';\n  PTDA : TwbSignature = 'PTDA'; { New to Skyrim }\n  PTOP : TwbSignature = 'PTOP'; { New to Fallout 4 }\n  PTRN : TwbSignature = 'PTRN'; { New to Fallout 4 }\n  QNAM : TwbSignature = 'QNAM';\n  QOBJ : TwbSignature = 'QOBJ';\n  QSDT : TwbSignature = 'QSDT';\n  QSTA : TwbSignature = 'QSTA';\n  QSTI : TwbSignature = 'QSTI'; { New to Fallout 4 }\n  QTGL : TwbSignature = 'QTGL'; { New To Skyrim }\n  QTOP : TwbSignature = 'QTOP'; { New to Fallout 4 }\n  QUAL : TwbSignature = 'QUAL'; { New To Skyrim }\n  QUST : TwbSignature = 'QUST';\n  RACE : TwbSignature = 'RACE';\n  RADR : TwbSignature = 'RADR'; { New To Fallout 4 }\n  RBPC : TwbSignature = 'RBPC'; { New To Fallout 4 }\n  RCEC : TwbSignature = 'RCEC'; { New To Skyrim }\n  RCLR : TwbSignature = 'RCLR';\n  RCPR : TwbSignature = 'RCPR'; { New to Dawnguard }\n  RCSR : TwbSignature = 'RCSR'; { New To Skyrim }\n  RCUN : TwbSignature = 'RCUN'; { New To Skyrim }\n  RDAT : TwbSignature = 'RDAT';\n  RDGS : TwbSignature = 'RDGS';\n  RDMO : TwbSignature = 'RDMO';\n  RDMP : TwbSignature = 'RDMP';\n  RDOT : TwbSignature = 'RDOT';\n  RDSA : TwbSignature = 'RDSA'; { New to Skyrim }\n  RDWT : TwbSignature = 'RDWT';\n  REFR : TwbSignature = 'REFR';\n  REGN : TwbSignature = 'REGN';\n  RELA : TwbSignature = 'RELA';\n  REPL : TwbSignature = 'REPL';\n  REPT : TwbSignature = 'REPT'; { New To Fallout 4 }\n  REVB : TwbSignature = 'REVB';\n  RFCT : TwbSignature = 'RFCT';\n  RFGP : TwbSignature = 'RFGP'; { New to Fallout 4 }\n  RGDL : TwbSignature = 'RGDL'; { Unused in Skyrim, but contained in Skyrim.esm }\n  RLDM : TwbSignature = 'RLDM'; { New to Fallout 4 }\n  RNAM : TwbSignature = 'RNAM';\n  RNMV : TwbSignature = 'RNMV'; { New to Skyrim }\n  RPLD : TwbSignature = 'RPLD';\n  RPLI : TwbSignature = 'RPLI';\n  RPRF : TwbSignature = 'RPRF'; { New To Skyrim }\n  RPRM : TwbSignature = 'RPRM'; { New To Skyrim }\n  RVIS : TwbSignature = 'RVIS'; { New to Fallout 4 }\n  SADD : TwbSignature = 'SADD'; { New To Fallout 4 }\n  SAKD : TwbSignature = 'SAKD'; { New To Fallout 4 }\n  SAPT : TwbSignature = 'SAPT'; { New To Fallout 4 }\n  SCCO : TwbSignature = 'SCCO'; { New To Fallout 4 }\n  SCDA : TwbSignature = 'SCDA';\n  SCEN : TwbSignature = 'SCEN';\n  SCHR : TwbSignature = 'SCHR';\n  SCOL : TwbSignature = 'SCOL'; { Unused in Skyrim, but contained in Skyrim.esm }\n  SCPT : TwbSignature = 'SCPT'; { Unused in Skyrim, but contained in Skyrim.esm }\n  SCQS : TwbSignature = 'SCQS'; { New To Fallout 4 }\n  SCRL : TwbSignature = 'SCRL';\n  SCRN : TwbSignature = 'SCRN';\n  SCRO : TwbSignature = 'SCRO';\n  SCSN : TwbSignature = 'SCSN'; { New To Fallout 4 }\n  SCTX : TwbSignature = 'SCTX';\n  SDSC : TwbSignature = 'SDSC'; { New to Skyrim }\n  SGNM : TwbSignature = 'SGNM'; { New to Fallout 4 }\n  SHOU : TwbSignature = 'SHOU';\n  SHRT : TwbSignature = 'SHRT'; { New to Skyrim }\n  SKIL : TwbSignature = 'SKIL'; { New to Fallout 4 }\n  SLCP : TwbSignature = 'SLCP';\n  SLGM : TwbSignature = 'SLGM';\n  SMBN : TwbSignature = 'SMBN';\n  SMEN : TwbSignature = 'SMEN';\n  SMQN : TwbSignature = 'SMQN';\n  SNAM : TwbSignature = 'SNAM';\n  SNCT : TwbSignature = 'SNCT';\n  SNDD : TwbSignature = 'SNDD';\n  SNDR : TwbSignature = 'SNDR';\n  SNMV : TwbSignature = 'SNMV'; { New to Skyrim }\n  SOFT : TwbSignature = 'SOFT'; { New to Skyrim }\n  SOPM : TwbSignature = 'SOPM';\n  SOUL : TwbSignature = 'SOUL';\n  SOUN : TwbSignature = 'SOUN';\n  SPCT : TwbSignature = 'SPCT'; { New to Skyrim }\n  SPED : TwbSignature = 'SPED'; { New To Skyrim }\n  SPEL : TwbSignature = 'SPEL';\n  SPGD : TwbSignature = 'SPGD';\n  SPIT : TwbSignature = 'SPIT';\n  SPLO : TwbSignature = 'SPLO';\n  SPMV : TwbSignature = 'SPMV'; { New To Skyrim }\n  SPOR : TwbSignature = 'SPOR'; { New to Skyrim }\n  SRAC : TwbSignature = 'SRAC'; { New to Fallout 4 }\n  SRAF : TwbSignature = 'SRAF'; { New to Fallout 4 }\n  SSPN : TwbSignature = 'SSPN'; { New to Fallout 4 }\n  STAG : TwbSignature = 'STAG'; { New to Fallout 4 }\n  STAT : TwbSignature = 'STAT';\n  STCP : TwbSignature = 'STCP'; { New to Fallout 4 }\n  STKD : TwbSignature = 'STKD'; { New to Fallout 4 }\n  STOL : TwbSignature = 'STOL'; { New to Skyrim }\n  STOP : TwbSignature = 'STOP'; { New to Fallout 4 }\n  STSC : TwbSignature = 'STSC'; { New to Fallout 4 }\n  SWMV : TwbSignature = 'SWMV'; { New to Skyrim }\n  TACT : TwbSignature = 'TACT';\n  TCLT : TwbSignature = 'TCLT';\n  TERM : TwbSignature = 'TERM'; { New to Fallout 4 }\n  TES4 : TwbSignature = 'TES4';\n  TETI : TwbSignature = 'TETI'; { New to Fallout 4 }\n  TEND : TwbSignature = 'TEND'; { New to Fallout 4 }\n  TIAS : TwbSignature = 'TIAS'; { New to Skyrim }\n  TIFC : TwbSignature = 'TIFC'; { New To Skyrim }\n  TINC : TwbSignature = 'TINC'; { New to Skyrim }\n  TIND : TwbSignature = 'TIND'; { New to Skyrim }\n  TINI : TwbSignature = 'TINI'; { New to Skyrim }\n  TINL : TwbSignature = 'TINL'; { New to Skyrim }\n  TINP : TwbSignature = 'TINP'; { New to Skyrim }\n  TINT : TwbSignature = 'TINT'; { New to Skyrim }\n  TINV : TwbSignature = 'TINV'; { New to Skyrim }\n  TIQS : TwbSignature = 'TIQS'; { New to Fallout 4 }\n  TIRS : TwbSignature = 'TIRS'; { New to Skyrim }\n  TLOD : TwbSignature = 'TLOD'; { New to Fallout 4 }\n  TNAM : TwbSignature = 'TNAM';\n  TOFT : TwbSignature = 'TOFT'; { New to Fallout 4 }\n  TPIC : TwbSignature = 'TPIC';\n  TPLT : TwbSignature = 'TPLT';\n  TPTA : TwbSignature = 'TPTA'; { New To Fallout 4 }\n  TRDA : TwbSignature = 'TRDA'; { New To Fallout 4 }\n  TRDT : TwbSignature = 'TRDT';\n  TREE : TwbSignature = 'TREE';\n  TRNS : TwbSignature = 'TRNS'; { New To Fallout 4 }\n  TSCE : TwbSignature = 'TSCE'; { New To Fallout 4 }\n  TTEB : TwbSignature = 'TTEB'; { New To Fallout 4 }\n  TTEC : TwbSignature = 'TTEC'; { New To Fallout 4 }\n  TTED : TwbSignature = 'TTED'; { New To Fallout 4 }\n  TTEF : TwbSignature = 'TTEF'; { New To Fallout 4 }\n  TTET : TwbSignature = 'TTET'; { New To Fallout 4 }\n  TTGE : TwbSignature = 'TTGE'; { New To Fallout 4 }\n  TTGP : TwbSignature = 'TTGP'; { New To Fallout 4 }\n  TVDT : TwbSignature = 'TVDT'; { New To Skyrim }\n  TWAT : TwbSignature = 'TWAT'; { New To Skyrim }\n  TX00 : TwbSignature = 'TX00';\n  TX01 : TwbSignature = 'TX01';\n  TX02 : TwbSignature = 'TX02';\n  TX03 : TwbSignature = 'TX03';\n  TX04 : TwbSignature = 'TX04';\n  TX05 : TwbSignature = 'TX05';\n  TX06 : TwbSignature = 'TX06'; { New To Skyrim }\n  TX07 : TwbSignature = 'TX07'; { New To Skyrim }\n  TXST : TwbSignature = 'TXST';\n  UNAM : TwbSignature = 'UNAM';\n  UNES : TwbSignature = 'UNES'; { New To Skyrim }\n  UNWP : TwbSignature = 'UNWP'; { New To Fallout 4 }\n  VATS : TwbSignature = 'VATS';\n  VCLR : TwbSignature = 'VCLR';\n  VENC : TwbSignature = 'VENC'; { New To Skyrim }\n  VEND : TwbSignature = 'VEND'; { New To Skyrim }\n  VENV : TwbSignature = 'VENV'; { New To Skyrim }\n  VHGT : TwbSignature = 'VHGT';\n  VISI : TwbSignature = 'VISI'; { New To Fallout 4 }\n  VMAD : TwbSignature = 'VMAD';\n  VNAM : TwbSignature = 'VNAM';\n  VNML : TwbSignature = 'VNML';\n  VTCK : TwbSignature = 'VTCK';\n  VTEX : TwbSignature = 'VTEX';\n  VTXT : TwbSignature = 'VTXT';\n  VTYP : TwbSignature = 'VTYP';\n  WAIT : TwbSignature = 'WAIT'; { New To Skyrim }\n  WAMD : TwbSignature = 'WAMD'; { New To Fallout 4 }\n  WATR : TwbSignature = 'WATR';\n  WBDT : TwbSignature = 'WBDT'; { New to Skyrim }\n  WCTR : TwbSignature = 'WCTR'; { New To Skyrim }\n  WEAP : TwbSignature = 'WEAP';\n  WGDR : TwbSignature = 'WGDR'; { New To Fallout 4 }\n  WKMV : TwbSignature = 'WKMV'; { New to Skyrim }\n  WLEV : TwbSignature = 'WLEV'; { New To Fallout 4 }\n  WLST : TwbSignature = 'WLST';\n  WMAP : TwbSignature = 'WMAP'; { New To Fallout 4 }\n  WNAM : TwbSignature = 'WNAM';\n  WOOP : TwbSignature = 'WOOP';\n  WRLD : TwbSignature = 'WRLD';\n  WTHR : TwbSignature = 'WTHR';\n  WZMD : TwbSignature = 'WZMD'; { New To Fallout 4 }\n  XACT : TwbSignature = 'XACT';\n  XALP : TwbSignature = 'XALP'; { New To Skyrim }\n  XAMC : TwbSignature = 'XAMC'; { New To Fallout 4 }\n  XAPD : TwbSignature = 'XAPD';\n  XAPR : TwbSignature = 'XAPR';\n  XASP : TwbSignature = 'XASP'; { New To Fallout 4 }\n  XATP : TwbSignature = 'XATP'; { New To Fallout 4 }\n  XATR : TwbSignature = 'XATR'; { New To Dawnguard }\n  XBSD : TwbSignature = 'XBSD'; { New To Fallout 4 }\n  XCAS : TwbSignature = 'XCAS';\n  XCCM : TwbSignature = 'XCCM';\n  XCHG : TwbSignature = 'XCHG';\n  XCIM : TwbSignature = 'XCIM';\n  XCLC : TwbSignature = 'XCLC';\n  XCLL : TwbSignature = 'XCLL';\n  XCLP : TwbSignature = 'XCLP';\n  XCLR : TwbSignature = 'XCLR';\n  XCLW : TwbSignature = 'XCLW';\n  XCMO : TwbSignature = 'XCMO';\n  XCNT : TwbSignature = 'XCNT';\n  XCRI : TwbSignature = 'XCRI'; { New To Fallout 4 }\n  XCVL : TwbSignature = 'XCVL'; { New To Skyrim }\n  XCVR : TwbSignature = 'XCVR'; { New To Fallout 4 }\n  XCWT : TwbSignature = 'XCWT';\n  XCZA : TwbSignature = 'XCZA'; { New To Skyrim }\n  XCZC : TwbSignature = 'XCZC'; { New To Skyrim }\n  XCZR : TwbSignature = 'XCZR'; { New To Skyrim }\n  XDCR : TwbSignature = 'XDCR';\n  XEMI : TwbSignature = 'XEMI';\n  XESP : TwbSignature = 'XESP';\n  XEZN : TwbSignature = 'XEZN';\n  XFVC : TwbSignature = 'XFVC'; { New To Skyrim }\n  XGDR : TwbSignature = 'XGDR'; { New To Fallout 4 }\n  XGLB : TwbSignature = 'XGLB';\n  XHLP : TwbSignature = 'XHLP';\n  XHLT : TwbSignature = 'XHLT'; { New To Fallout 4 }\n  XHOR : TwbSignature = 'XHOR'; { New To Skyrim }\n  XHTW : TwbSignature = 'XHTW'; { New To Skyrim }\n  XIBS : TwbSignature = 'XIBS';\n  XILL : TwbSignature = 'XILL'; { New To Skyrim }\n  XILW : TwbSignature = 'XILW'; { New To Fallout 4 }\n  XIS2 : TwbSignature = 'XIS2'; { New To Skyrim }\n  XLCM : TwbSignature = 'XLCM';\n  XLCN : TwbSignature = 'XLCN'; { New To Skyrim }\n  XLIB : TwbSignature = 'XLIB'; { New To Skyrim }\n  XLIG : TwbSignature = 'XLIG'; { New To Skyrim }\n  XLKR : TwbSignature = 'XLKR';\n  XLKT : TwbSignature = 'XLKT'; { New To Fallout 4 }\n  XLOC : TwbSignature = 'XLOC';\n  XLOD : TwbSignature = 'XLOD';\n  XLRL : TwbSignature = 'XLRL'; { New To Skyrim }\n  XLRM : TwbSignature = 'XLRM';\n  XLRT : TwbSignature = 'XLRT'; { New To Skyrim }\n  XLTW : TwbSignature = 'XLTW';\n  XLYR : TwbSignature = 'XLYR'; { New To Fallout 4 }\n  XMBO : TwbSignature = 'XMBO';\n  XMBP : TwbSignature = 'XMBP';\n  XMBR : TwbSignature = 'XMBR';\n  XMRC : TwbSignature = 'XMRC';\n  XMRK : TwbSignature = 'XMRK';\n  XMSP : TwbSignature = 'XMSP'; { New To Fallout 4 }\n  XNAM : TwbSignature = 'XNAM';\n  XNDP : TwbSignature = 'XNDP';\n  XOCP : TwbSignature = 'XOCP';\n  XORD : TwbSignature = 'XORD';\n  XOWN : TwbSignature = 'XOWN';\n  XPDD : TwbSignature = 'XPDD'; { New To Fallout 4 }\n  XPLK : TwbSignature = 'XPLK'; { New To Fallout 4 }\n  XPOD : TwbSignature = 'XPOD';\n  XPPA : TwbSignature = 'XPPA';\n  XPRD : TwbSignature = 'XPRD';\n  XPRI : TwbSignature = 'XPRI'; { New To Fallout 4 }\n  XPRM : TwbSignature = 'XPRM';\n  XPTL : TwbSignature = 'XPTL';\n  XPWR : TwbSignature = 'XPWR';\n  XRDO : TwbSignature = 'XRDO'; { New To Fallout 4 }\n  XRDS : TwbSignature = 'XRDS';\n  XRFG : TwbSignature = 'XRFG'; { New To Fallout 4 }\n  XRGB : TwbSignature = 'XRGB';\n  XRGD : TwbSignature = 'XRGD';\n  XRMR : TwbSignature = 'XRMR';\n  XRNK : TwbSignature = 'XRNK';\n  XSCL : TwbSignature = 'XSCL';\n  XSPC : TwbSignature = 'XSPC'; { New To Skyrim }\n  XTEL : TwbSignature = 'XTEL';\n  XTNM : TwbSignature = 'XTNM'; { New To Skyrim }\n  XTRI : TwbSignature = 'XTRI';\n  XWCN : TwbSignature = 'XWCN'; { New To Skyrim }\n  XWCS : TwbSignature = 'XWCS'; { New To Skyrim }\n  XWCU : TwbSignature = 'XWCU'; { New To Skyrim }\n  XWEM : TwbSignature = 'XWEM'; { New To Skyrim }\n  XWPG : TwbSignature = 'XWPG'; { New To Fallout 4 }\n  XWPN : TwbSignature = 'XWPN'; { New To Fallout 4 }\n  XXXX : TwbSignature = 'XXXX';\n  YNAM : TwbSignature = 'YNAM';\n  ZNAM : TwbSignature = 'ZNAM';\n  ZOOM : TwbSignature = 'ZOOM'; { New To Fallout 4 }\n\n  // signatures of reference records\n  sigReferences : array [0..11] of TwbSignature = (\n    'NULL', 'PLYR', 'ACHR', 'REFR', 'PGRE', 'PHZD',\n    'PMIS', 'PARW', 'PBAR', 'PBEA', 'PCON', 'PFLA'\n  );\n\n  // signatures of referenceable records (placed by references or constructable)\n  sigBaseObjects : array [0..43] of TwbSignature = (\n    'NULL', 'ACTI', 'ADDN', 'ALCH', 'AMMO', 'ARMO',\n    'ARTO', 'ASPC', 'BNDS', 'BOOK', 'CMPO', 'COBJ',\n    'CONT', 'DEBR', 'DOOR', 'EXPL', 'FLST', 'FLOR',\n    'FURN', 'HAZD', 'IDLM', 'INGR', 'KEYM', 'LIGH',\n    'LVLI', 'LVLN', 'LVSP', 'MISC', 'MSTT', 'NOTE',\n    'NPC_', 'OMOD', 'PROJ', 'SCOL', 'SCRL', 'SOUN',\n    'SPEL', 'STAT', 'TACT', 'TERM', 'TREE', 'TXST',\n    'WATR', 'WEAP'\n  );\n\nvar\n  wbPKDTSpecificFlagsUnused : Boolean;\n  wbEDID: IwbSubRecordDef;\n  wbCOED: IwbSubRecordDef;\n  wbXLCM: IwbSubRecordDef;\n  wbEITM: IwbSubRecordDef;\n  wbOBND: IwbSubRecordDef;\n  wbOBNDReq: IwbSubRecordDef;\n  wbDEST: IwbSubRecordStructDef;\n  wbDESTActor: IwbSubRecordStructDef;\n  wbDODT: IwbSubRecordDef;\n  wbXRGD: IwbSubRecordDef;\n  wbXRGB: IwbSubRecordDef;\n  wbSPLO: IwbSubRecordDef;\n  wbSPLOs: IwbSubRecordArrayDef;\n  wbCNTO: IwbSubRecordStructDef;\n  wbCNTOs: IwbSubRecordArrayDef;\n  wbAIDT: IwbSubRecordDef;\n  wbFULL: IwbSubRecordDef;\n  wbFULLActor: IwbSubRecordDef;\n  wbFULLReq: IwbSubRecordDef;\n  wbDESC: IwbSubRecordDef;\n  wbDESCReq: IwbSubRecordDef;\n  wbXSCL: IwbSubRecordDef;\n  wbDATAPosRot: IwbSubRecordDef;\n  wbPosRot: IwbStructDef;\n  wbMODC: IwbSubRecordDef;\n  wbMODF: IwbSubRecordDef;\n  wbMODL: IwbSubRecordStructDef;\n  wbMODS: IwbSubRecordDef;\n  wbMO2S: IwbSubRecordDef;\n  wbMO3S: IwbSubRecordDef;\n  wbMO4S: IwbSubRecordDef;\n  wbMO2F: IwbSubRecordDef;\n  wbMO3F: IwbSubRecordDef;\n  wbMO4F: IwbSubRecordDef;\n  wbMO5F: IwbSubRecordDef;\n  wbMO2C: IwbSubRecordDef;\n  wbMO3C: IwbSubRecordDef;\n  wbMO4C: IwbSubRecordDef;\n  wbMO5C: IwbSubRecordDef;\n  wbMODLActor: IwbSubRecordStructDef;\n  wbMODLReq: IwbSubRecordStructDef;\n  wbCTDA: IwbSubRecordStructDef;\n  wbCTDAs: IwbSubRecordArrayDef;\n  wbCTDAsReq: IwbSubRecordArrayDef;\n  wbCTDAsCount: IwbSubRecordArrayDef;\n  wbCTDAsReqCount: IwbSubRecordArrayDef;\n  wbXLOD: IwbSubRecordDef;\n  wbXESP: IwbSubRecordDef;\n  wbICON: IwbSubRecordDef;\n  wbMICO: IwbSubRecordDef;\n  wbActorValue: IwbIntegerDef;\n  wbETYP: IwbSubRecordDef;\n  wbETYPReq: IwbSubRecordDef;\n  wbEFID: IwbSubRecordDef;\n  wbEFIT: IwbSubRecordDef;\n  wbEffectsReq: IwbSubRecordArrayDef;\n  wbFirstPersonFlagsU32: IwbIntegerDef;\n  wbBOD2: IwbSubRecordDef;\n  wbScriptEntry: IwbStructDef;\n  wbScriptFlags: IwbIntegerDef;\n  wbScriptPropertyObject: IwbUnionDef;\n\twbScriptPropertyStruct: IwbArrayDef;\n\twbScriptProperties: IwbArrayDef;\n  wbScriptFragments: IwbStructDef;\n  wbScriptFragmentsQuest: IwbStructDef;\n  wbScriptFragmentsInfo: IwbStructDef;\n  wbScriptFragmentsPack: IwbStructDef;\n  wbScriptFragmentsScen: IwbStructDef;\n  wbPLDT: IwbSubRecordDef;\n  wbPLVD: IwbSubRecordDef;\n  wbTargetData: IwbStructDef;\n  wbAttackData: IwbSubRecordStructDef;\n  wbLLCT: IwbSubRecordDef;\n  wbLVLD: IwbSubRecordDef;\n  wbVMAD: IwbSubRecordDef;\n  wbVMADFragmentedPERK: IwbSubRecordDef;\n  wbVMADFragmentedPACK: IwbSubRecordDef;\n  wbVMADFragmentedQUST: IwbSubRecordDef;\n  wbVMADFragmentedSCEN: IwbSubRecordDef;\n  wbVMADFragmentedINFO: IwbSubRecordDef;\n  wbCOCT: IwbSubRecordDef;\n  wbKSIZ: IwbSubRecordDef;\n  wbKWDAs: IwbSubRecordDef;\n  wbReqKWDAs: IwbSubRecordDef;\n  wbKeywords: IwbSubRecordStructDef;\n  wbCNAM: IwbSubRecordDef;\n  wbCITC: IwbSubRecordDef;\n  wbMGEFData: IwbSubRecordStructDef;\n  wbMGEFType: IwbIntegerDef;\n  wbMDOB: IwbSubRecordDef;\n  wbSPIT: IwbSubRecordDef;\n  wbDMDC: IwbSubRecordDef;\n  wbDMDS: IwbSubRecordDef;\n  wbMO5S: IwbSubRecordDef;\n  wbSPCT: IwbSubRecordDef;\n  wbMODT: IwbSubRecordDef;\n  wbDMDT: IwbSubRecordDef;\n  wbXOWN: IwbSubRecordDef;\n  wbXRNK: IwbSubRecordDef;\n  wbPhonemeTargets: IwbSubRecordDef;\n  wbPHWT: IwbSubRecordStructDef;\n  wbHeadPart: IwbSubRecordStructDef;\n  wbQUSTAliasFlags: IwbSubRecordDef;\n  wbPDTO: IwbSubRecordDef;\n  wbPDTOs: IwbSubRecordArrayDef;\n  wbUNAMs: IwbSubRecordArrayDef;\n  wbNull: IwbValueDef;\n  wbTimeInterpolator: IwbStructDef;\n  wbColorInterpolator: IwbStructDef;\n  wbYNAM: IwbSubRecordDef;\n  wbZNAM: IwbSubRecordDef;\n  wbSPED: IwbSubRecordDef;\n  wbCUSD: IwbSubRecordDef;\n  wbINRD: IwbSubRecordDef;\n  wbPTRN: IwbSubRecordDef;\n  wbNTRM: IwbSubRecordDef;\n  wbPRPS: IwbSubRecordDef;\n  wbFLTR: IwbSubRecordDef;\n  wbAPPR: IwbSubRecordDef;\n  wbObjectTemplate: IwbSubRecordStructDef;\n  wbBSMPSequence: IwbSubRecordArrayDef;\n  wbFTYP: IwbSubRecordDef;\n  wbATTX: IwbSubRecordDef;\n  wbMNAMFurnitureMarker: IwbSubRecordDef;\n  wbSNAMMarkerParams: IwbSubRecordDef;\n  wbOBTSReq: IwbSubRecordDef;\n  //wbTintTemplateGroups: IwbSubrecordArrayDef;\n  //wbMorphGroups: IwbSubrecordArrayDef;\n  //wbRaceFRMI: IwbSubrecordArrayDef;\n  wbRaceRBPC: IwbSubRecordDef;\n  wbNVNM: IwbSubRecordDef;\n  wbMaxHeightDataCELL: IwbSubRecordDef;\n  wbMaxHeightDataWRLD: IwbSubRecordDef;\n  wbOFST: IwbSubRecordDef;\n\nfunction Sig2Int(aSignature: TwbSignature): Cardinal; inline;\nbegin\n  Result := PCardinal(@aSignature)^;\nend;\n\nfunction wbEPFDActorValueToStr(aInt: Int64; const aElement: IwbElement; aType: TwbCallbackType): string;\nvar\n  AsCardinal : Cardinal;\n  AsFloat    : Single;\nbegin\n  AsCardinal := aInt;\n  AsFloat := PSingle(@AsCardinal)^;\n  aInt := Round(AsFloat);\n  case aType of\n    ctToStr: Result := wbActorValueEnum.ToString(aInt, aElement);\n    ctToSortKey: Result := wbActorValueEnum.ToSortKey(aInt, aElement);\n    ctCheck: Result := wbActorValueEnum.Check(aInt, aElement);\n    ctToEditValue: Result := wbActorValueEnum.ToEditValue(aInt, aElement);\n    ctEditType: Result := 'ComboBox';\n    ctEditInfo: Result := wbActorValueEnum.EditInfo[aInt, aElement];\n  end;\nend;\n\nfunction wbEPFDActorValueToInt(const aString: string; const aElement: IwbElement): Int64;\nvar\n  AsCardinal : Cardinal;\n  AsFloat    : Single;\nbegin\n  AsFloat := wbActorValueEnum.FromEditValue(aString, aElement);\n  PSingle(@AsCardinal)^ := AsFloat;\n  Result := AsCardinal;\nend;\n\nfunction wbCTDAParam2QuestStageToStr(aInt: Int64; const aElement: IwbElement; aType: TwbCallbackType): string;\nvar\n  Container  : IwbContainerElementRef;\n  Param1     : IwbElement;\n  MainRecord : IwbMainRecord;\n  EditInfos  : TStringList;\n  Stages     : IwbContainerElementRef;\n  Stage      : IwbContainerElementRef;\n  i, j       : Integer;\n  s, t       : string;\nbegin\n  case aType of\n    ctToStr: Result := IntToStr(aInt) + ' <Warning: Could not resolve Parameter 1>';\n    ctToEditValue: Result := IntToStr(aInt);\n    ctToSortKey: begin\n      Result := IntToHex64(aInt, 8);\n      Exit;\n    end;\n    ctCheck: Result := '<Warning: Could not resolve Parameter 1>';\n    ctEditType: Result := '';\n    ctEditInfo: Result := '';\n  end;\n\n  if not Assigned(aElement) then Exit;\n  Container := GetContainerRefFromUnionOrValue(aElement);\n  if not Assigned(Container) then Exit;\n\n  Param1 := Container.ElementByName['Parameter #1'];\n\n  if not Assigned(Param1) then\n    Exit;\n\n  if not Supports(Param1.LinksTo, IwbMainRecord, MainRecord) then\n    Exit;\n\n  // get winning quest override except for partial forms\n  if MainRecord.WinningOverride.Flags._Flags and $00004000 = 0 then\n    MainRecord := MainRecord.WinningOverride\n  else if MainRecord.Flags._Flags and $00004000 <> 0 then\n    MainRecord := MainRecord.MasterOrSelf;\n\n  if MainRecord.Signature <> QUST then begin\n    case aType of\n      ctToStr: Result := IntToStr(aInt) + ' <Warning: \"'+MainRecord.ShortName+'\" is not a Quest record>';\n      ctCheck: Result := '<Warning: \"'+MainRecord.ShortName+'\" is not a Quest record>';\n    end;\n    Exit;\n  end;\n\n  case aType of\n    ctEditType: begin\n      Result := 'ComboBox';\n      Exit;\n    end;\n    ctEditInfo:\n      EditInfos := TStringList.Create;\n  else\n    EditInfos := nil;\n  end;\n  try\n    if Supports(MainRecord.ElementByName['Stages'], IwbContainerElementRef, Stages) then begin\n      for i := 0 to Pred(Stages.ElementCount) do\n        if Supports(Stages.Elements[i], IwbContainerElementRef, Stage) then begin\n          j := Stage.ElementNativeValues['INDX\\Stage Index'];\n          s := Trim(Stage.ElementValues['Log Entries\\Log Entry\\CNAM']);\n          t := IntToStr(j);\n          while Length(t) < 3 do\n            t := '0' + t;\n          if s <> '' then\n            t := t + ' ' + s;\n          if Assigned(EditInfos) then\n            EditInfos.AddObject(t, TObject(j))\n          else if j = aInt then begin\n            case aType of\n              ctToStr, ctToEditValue: Result := t;\n              ctCheck: Result := '';\n            end;\n            Exit;\n          end;\n        end;\n    end;\n\n    case aType of\n      ctToStr: Result := IntToStr(aInt) + ' <Warning: Quest Stage not found in \"' + MainRecord.Name + '\">';\n      ctCheck: Result := '<Warning: Quest Stage not found in \"' + MainRecord.Name + '\">';\n      ctEditInfo: begin\n        EditInfos.Sort;\n        Result := EditInfos.CommaText;\n      end;\n    end;\n  finally\n    FreeAndNil(EditInfos);\n  end;\nend;\n\nfunction wbPerkDATAQuestStageToStr(aInt: Int64; const aElement: IwbElement; aType: TwbCallbackType): string;\nvar\n  Container  : IwbContainerElementRef;\n  Param1     : IwbElement;\n  MainRecord : IwbMainRecord;\n  EditInfos  : TStringList;\n  Stages     : IwbContainerElementRef;\n  Stage      : IwbContainerElementRef;\n  i, j       : Integer;\n  s, t       : string;\nbegin\n  case aType of\n    ctToStr: Result := IntToStr(aInt) + ' <Warning: Could not resolve Quest>';\n    ctToEditValue: Result := IntToStr(aInt);\n    ctToSortKey: begin\n      Result := IntToHex64(aInt, 8);\n      Exit;\n    end;\n    ctCheck: Result := '<Warning: Could not resolve Quest>';\n    ctEditType: Result := '';\n    ctEditInfo: Result := '';\n  end;\n\n  if not Assigned(aElement) then Exit;\n  Container := GetContainerRefFromUnionOrValue(aElement);\n  if not Assigned(Container) then Exit;\n\n  Param1 := Container.ElementByName['Quest'];\n\n  if not Assigned(Param1) then\n    Exit;\n\n  if not Supports(Param1.LinksTo, IwbMainRecord, MainRecord) then\n    Exit;\n\n  // get winning quest override except for partial forms\n  if MainRecord.WinningOverride.Flags._Flags and $00004000 = 0 then\n    MainRecord := MainRecord.WinningOverride\n  else if MainRecord.Flags._Flags and $00004000 <> 0 then\n    MainRecord := MainRecord.MasterOrSelf;\n\n  if MainRecord.Signature <> QUST then begin\n    case aType of\n      ctToStr: Result := IntToStr(aInt) + ' <Warning: \"'+MainRecord.ShortName+'\" is not a Quest record>';\n      ctCheck: Result := '<Warning: \"'+MainRecord.ShortName+'\" is not a Quest record>';\n    end;\n    Exit;\n  end;\n\n  case aType of\n    ctEditType: begin\n      Result := 'ComboBox';\n      Exit;\n    end;\n    ctEditInfo:\n      EditInfos := TStringList.Create;\n  else\n    EditInfos := nil;\n  end;\n  try\n    if Supports(MainRecord.ElementByName['Stages'], IwbContainerElementRef, Stages) then begin\n      for i := 0 to Pred(Stages.ElementCount) do\n        if Supports(Stages.Elements[i], IwbContainerElementRef, Stage) then begin\n          j := Stage.ElementNativeValues['INDX\\Stage Index'];\n          s := Trim(Stage.ElementValues['Log Entries\\Log Entry\\CNAM']);\n          t := IntToStr(j);\n          while Length(t) < 3 do\n            t := '0' + t;\n          if s <> '' then\n            t := t + ' ' + s;\n          if Assigned(EditInfos) then\n            EditInfos.AddObject(t, TObject(j))\n          else if j = aInt then begin\n            case aType of\n              ctToStr, ctToEditValue: Result := t;\n              ctCheck: Result := '';\n            end;\n            Exit;\n          end;\n        end;\n    end;\n\n    case aType of\n      ctToStr: Result := IntToStr(aInt) + ' <Warning: Quest Stage not found in \"' + MainRecord.Name + '\">';\n      ctCheck: Result := '<Warning: Quest Stage not found in \"' + MainRecord.Name + '\">';\n      ctEditInfo: begin\n        EditInfos.Sort;\n        Result := EditInfos.CommaText;\n      end;\n    end;\n  finally\n    FreeAndNil(EditInfos);\n  end;\nend;\n\nfunction wbCTDAParam2QuestStageToInt(const aString: string; const aElement: IwbElement): Int64;\nvar\n  i    : Integer;\n  s    : string;\nbegin\n  i := 1;\n  s := Trim(aString);\n  while (i <= Length(s)) and (s[i] in ['0'..'9']) do\n    Inc(i);\n  s := Copy(s, 1, Pred(i));\n\n  Result := StrToInt(s);\nend;\n\nfunction wbREFRNavmeshTriangleToStr(aInt: Int64; const aElement: IwbElement; aType: TwbCallbackType): string;\nvar\n  Container  : IwbContainerElementRef;\n  Navmesh    : IwbElement;\n  MainRecord : IwbMainRecord;\n  Triangles  : IwbContainerElementRef;\nbegin\n  case aType of\n    ctToStr: Result := IntToStr(aInt);\n    ctToEditValue: Result := IntToStr(aInt);\n    ctToSortKey: begin\n      Result := IntToHex64(aInt, 8);\n      Exit;\n    end;\n    ctCheck: Result := '';\n    ctEditType: Result := '';\n    ctEditInfo: Result := '';\n  end;\n\n  if not Assigned(aElement) then Exit;\n  Container := GetContainerRefFromUnionOrValue(aElement);\n  if not Assigned(Container) then Exit;\n\n  Navmesh := Container.Elements[0];\n\n  if not Assigned(Navmesh) then\n    Exit;\n\n  if not Supports(Navmesh.LinksTo, IwbMainRecord, MainRecord) then\n    Exit;\n\n  MainRecord := MainRecord.WinningOverride;\n\n  if MainRecord.Signature <> NAVM then begin\n    case aType of\n      ctToStr: Result := IntToStr(aInt) + ' <Warning: \"'+MainRecord.ShortName+'\" is not a Navmesh record>';\n      ctCheck: Result := '<Warning: \"'+MainRecord.ShortName+'\" is not a Navmesh record>';\n    end;\n    Exit;\n  end;\n\n  if Supports(MainRecord.ElementByPath['NVNM\\Triangles'], IwbContainerElementRef, Triangles) and (aType = ctCheck) then\n    if aInt >= Triangles.ElementCount then\n      Result := '<Warning: Navmesh triangle not found in \"' + MainRecord.Name + '\">';\nend;\n\nfunction wbStringToInt(const aString: string; const aElement: IwbElement): Int64;\nbegin\n  Result := StrToIntDef(aString, 0);\nend;\n\n{ Alias to string conversion, requires quest reference or quest record specific to record that references alias }\nfunction wbAliasToStr(aInt: Int64; const aQuestRef: IwbElement; aType: TwbCallbackType): string;\nvar\n  MainRecord : IwbMainRecord;\n  EditInfos  : TStringList;\n  Aliases    : IwbContainerElementRef;\n  Alias      : IwbContainerElementRef;\n  i, j       : Integer;\n  s, t       : string;\nbegin\n  case aType of\n    ctToStr: if aInt = -1 then\n        Result := 'None'\n      else if aInt = -2 then\n        Result := 'Player'\n      else\n        Result := IntToStr(aInt) + ' <Warning: Could not resolve alias>';\n    ctToEditValue: if aInt = -1 then Result := 'None' else\n      Result := IntToStr(aInt);\n    ctToSortKey: begin\n      Result := IntToHex64(aInt, 8);\n      Exit;\n    end;\n    ctCheck: if (aInt = -1) or (aInt = -2) then Result := '' else\n      Result := '<Warning: Could not resolve alias>';\n    ctEditType: Result := '';\n    ctEditInfo: Result := '';\n  end;\n\n  if ((aInt = -1) or (aInt = -2)) and (aType <> ctEditType) and (aType <> ctEditInfo) then\n    Exit;\n\n  if not Assigned(aQuestRef) then\n    Exit;\n\n  // aQuestRef can be a QUST record or reference to QUST record\n  if not Supports(aQuestRef, IwbMainRecord, MainRecord) then\n    if not Supports(aQuestRef.LinksTo, IwbMainRecord, MainRecord) then\n      Exit;\n\n  // get winning quest override except for partial forms\n  if MainRecord.WinningOverride.Flags._Flags and $00004000 = 0 then\n    MainRecord := MainRecord.WinningOverride\n  else if MainRecord.Flags._Flags and $00004000 <> 0 then\n    MainRecord := MainRecord.MasterOrSelf;\n\n  if MainRecord.Signature <> QUST then begin\n    case aType of\n      ctToStr: Result := IntToStr(aInt) + ' <Warning: \"' + MainRecord.ShortName + '\" is not a Quest record>';\n      ctCheck: Result := '<Warning: \"' + MainRecord.ShortName + '\" is not a Quest record>';\n    end;\n    Exit;\n  end;\n\n  case aType of\n    ctEditType: begin\n      Result := 'ComboBox';\n      Exit;\n    end;\n    ctEditInfo: begin\n      EditInfos := TStringList.Create;\n    end;\n  else\n    EditInfos := nil;\n  end;\n\n  try\n    if Supports(MainRecord.ElementByName['Aliases'], IwbContainerElementRef, Aliases) then begin\n      for i := 0 to Pred(Aliases.ElementCount) do\n        if Supports(Aliases.Elements[i], IwbContainerElementRef, Alias) then begin\n          // skip alias collection\n          if Assigned(Alias.ElementBySignature['ALCS']) then\n            Continue;\n          j := Alias.Elements[0].NativeValue;\n          s := Alias.ElementEditValues['ALID'];\n          t := IntToStr(j);\n          while Length(t) < 3 do\n            t := '0' + t;\n          if s <> '' then\n            t := t + ' ' + s;\n          if Assigned(EditInfos) then\n            EditInfos.Add(t)\n          else if j = aInt then begin\n            case aType of\n              ctToStr, ctToEditValue: Result := t;\n              ctCheck: Result := '';\n            end;\n            Exit;\n          end;\n        end;\n    end;\n\n    case aType of\n      ctToStr: Result := IntToStr(aInt) + ' <Warning: Quest Alias not found in \"' + MainRecord.Name + '\">';\n      ctCheck: Result := '<Warning: Quest Alias not found in \"' + MainRecord.Name + '\">';\n      ctEditInfo: begin\n        EditInfos.Add('None');\n        EditInfos.Sort;\n        Result := EditInfos.CommaText;\n      end;\n    end;\n  finally\n    FreeAndNil(EditInfos);\n  end;\nend;\n\nfunction wbStrToAlias(const aString: string; const aElement: IwbElement): Int64;\nvar\n  i    : Integer;\n  s    : string;\nbegin\n  Result := -1;\n\n  if aString = 'None' then\n    Exit\n  else if aString = 'Player' then begin\n    Result := -2;\n    Exit;\n  end;\n\n  i := 1;\n  s := Trim(aString);\n  while (i <= Length(s)) and (s[i] in ['-', '0'..'9']) do\n    Inc(i);\n  s := Copy(s, 1, Pred(i));\n\n  Result := StrToIntDef(s, -1);\nend;\n\nfunction wbScriptObjectAliasToStr(aInt: Int64; const aElement: IwbElement; aType: TwbCallbackType): string;\nvar\n  Container  : IwbContainerElementRef;\nbegin\n  if not wbResolveAlias then begin\n    case aType of\n      ctToStr, ctToEditValue: Result := IntToStr(aInt);\n      ctToSortKey: Result := IntToHex64(aInt, 8);\n    else\n      Result := '';\n    end;\n    Exit;\n  end;\n\n  if not Assigned(aElement) then\n    Exit;\n\n  Container := GetContainerRefFromUnionOrValue(aElement);\n\n  if not Assigned(Container) then\n    Exit;\n\n  Result := wbAliasToStr(aInt, Container.ElementByName['FormID'], aType);\nend;\n\nfunction wbPackageLocationAliasToStr(aInt: Int64; const aElement: IwbElement; aType: TwbCallbackType): string;\nvar\n  Container  : IwbContainer;\nbegin\n  if not wbResolveAlias then begin\n    case aType of\n      ctToStr, ctToEditValue: Result := IntToStr(aInt);\n      ctToSortKey: Result := IntToHex64(aInt, 8);\n    else\n      Result := '';\n    end;\n    Exit;\n  end;\n\n  if not Assigned(aElement) then\n    Exit;\n\n  Container := GetContainerFromUnion(aElement);\n  if not Assigned(Container) then Exit;\n  while Assigned(Container) and (Container.ElementType <> etMainRecord) do\n    Container := Container.Container;\n\n  if not Assigned(Container) then\n    Exit;\n\n  Result := wbAliasToStr(aInt, Container.ElementBySignature['QNAM'], aType);\nend;\n\nfunction wbQuestAliasToStr(aInt: Int64; const aElement: IwbElement; aType: TwbCallbackType): string;\nvar\n  Container  : IwbContainer;\nbegin\n  if not wbResolveAlias then begin\n    case aType of\n      ctToStr, ctToEditValue: Result := IntToStr(aInt);\n      ctToSortKey: Result := IntToHex64(aInt, 8);\n    else\n      Result := '';\n    end;\n    Exit;\n  end;\n\n  if not Assigned(aElement) then\n    Exit;\n\n  Container := GetContainerFromUnion(aElement);\n  if not Assigned(Container) then Exit;\n  while Assigned(Container) and (Container.ElementType <> etMainRecord) do\n    Container := Container.Container;\n\n  if not Assigned(Container) then\n    Exit;\n\n  Result := wbAliasToStr(aInt, Container, aType);\nend;\n\nfunction wbQuestExternalAliasToStr(aInt: Int64; const aElement: IwbElement; aType: TwbCallbackType): string;\nvar\n  Container  : IwbContainer;\nbegin\n  if not wbResolveAlias then begin\n    case aType of\n      ctToStr, ctToEditValue: Result := IntToStr(aInt);\n      ctToSortKey: Result := IntToHex64(aInt, 8);\n    else\n      Result := '';\n    end;\n    Exit;\n  end;\n\n  if not Assigned(aElement) then\n    Exit;\n\n  Container := aElement.Container;\n\n  if not Assigned(Container) then\n    Exit;\n\n  Result := wbAliasToStr(aInt, Container.ElementBySignature['ALEQ'] , aType);\nend;\n\nfunction wbConditionAliasToStr(aInt: Int64; const aElement: IwbElement; aType: TwbCallbackType): string;\nvar\n  Container  : IwbContainer;\n  MainRecord : IwbMainRecord;\n  GroupRecord : IwbGroupRecord;\nbegin\n  if not wbResolveAlias then begin\n    case aType of\n      ctToStr, ctToEditValue: Result := IntToStr(aInt);\n      ctToSortKey: Result := IntToHex64(aInt, 8);\n    else\n      Result := '';\n    end;\n    Exit;\n  end;\n\n  if not Assigned(aElement) then\n    Exit;\n\n  Container := GetContainerFromUnion(aElement);\n  if not Assigned(Container) then Exit;\n  while Assigned(Container) and (Container.ElementType <> etMainRecord) do\n    Container := Container.Container;\n\n  if not Assigned(Container) then\n    Exit;\n\n  if not Supports(Container, IwbMainRecord, MainRecord) then\n    Exit;\n\n  if MainRecord.Signature = QUST then\n    Result := wbAliasToStr(aInt, Container, aType)\n  else if MainRecord.Signature = SCEN then\n    Result := wbAliasToStr(aInt, Container.ElementBySignature['PNAM'], aType)\n  else if MainRecord.Signature = PACK then\n    Result := wbAliasToStr(aInt, Container.ElementBySignature['QNAM'], aType)\n  else if MainRecord.Signature = INFO then begin\n    // get DIAL for INFO\n    if Supports(MainRecord.Container, IwbGroupRecord, GroupRecord) then\n      if Supports(GroupRecord.ChildrenOf, IwbMainRecord, MainRecord) then\n        Result := wbAliasToStr(aInt, MainRecord.ElementBySignature['QNAM'], aType);\n  end else\n  // this should never be called since aliases in conditions can be in the forms above only\n  // but just in case\n  case aType of\n    ctToStr, ctToEditValue: Result := IntToStr(aInt);\n    ctToSortKey: Result := IntToHex64(aInt, 8);\n  else\n    Result := '';\n  end;\nend;\n\nfunction wbClmtMoonsPhaseLength(aInt: Int64; const aElement: IwbElement; aType: TwbCallbackType): string;\nvar\n  PhaseLength : Byte;\n  Masser      : Boolean;\n  Secunda     : Boolean;\nbegin\n  Result := '';\n  if aType = ctToSortKey then begin\n    Result := IntToHex64(aInt, 2);\n  end else if aType = ctToStr then begin\n    PhaseLength := aInt mod 64;\n    Masser := (aInt and 64) <> 0;\n    Secunda := (aInt and 128) <> 0;\n    if Masser then\n      if Secunda then\n        Result := 'Masser, Secunda / '\n      else\n        Result := 'Masser / '\n    else\n      if Secunda then\n        Result := 'Secunda / '\n      else\n        Result := 'No Moon / ';\n    Result := Result + IntToStr(PhaseLength);\n  end;\nend;\n\nfunction wbClmtTime(aInt: Int64; const aElement: IwbElement; aType: TwbCallbackType): string;\nbegin\n  if aType = ctToSortKey then\n    Result := IntToHex64(aInt, 4)\n  else if aType = ctToStr then\n    Result := TimeToStr( EncodeTime(aInt div 6, (aInt mod 6) * 10, 0, 0) )\n  else\n    Result := '';\nend;\n\n\nvar\n  wbCtdaTypeFlags : IwbFlagsDef;\n\nfunction wbCtdaTypeToStr(aInt: Int64; const aElement: IwbElement; aType: TwbCallbackType): string;\nvar\n  s: string;\nbegin\n  Result := '';\n\n  if not Assigned(wbCtdaTypeFlags) then\n    wbCtdaTypeFlags := wbFlags([\n      {0x01} 'Or',\n      {0x02} 'Use aliases',\n      {0x04} 'Use global',\n      {0x08} 'Use packdata',\n      {0x10} 'Swap Subject and Target'\n    ]);\n{\n    Compare operator (upper 3 bits)\n    LGE\n    000    0=Equal to\n    001    1=Not equal to\n    010    2=Greater than\n    011    3=Greater than or equal to\n    100    4=Less than\n    101    5=Less than or equal to\n\n    Flags (lower 5 bits)\n        0x01=OR (default is to AND conditions together)\n        0x02=Parameters (use aliases) : Force function parameters to use quest alias data (exclusive with \"use pack data\")\n        0x04=Use global\n        0x08=Use Pack Data : Force function parameters to use pack data (exclusive with \"use aliases\")\n        0x10=Swap Subject and Target\n}\n  case aType of\n    ctEditType:\n      Result := 'CheckComboBox';\n    ctEditInfo:\n      Result := 'Equal,Greater,Lesser,Or,\"Use Aliases\",\"Use Global\",\"Use Packdata\",\"Swap Subject and Target\"';\n    ctToEditValue: begin\n      Result := '00000000';\n      case aInt and $E0 of\n        $00 : Result[1] := '1';\n        $40 : Result[2] := '1';\n        $60 : begin\n                Result[1] := '1';\n                Result[2] := '1';\n              end;\n        $80 : Result[3] := '1';\n        $A0 : begin\n                Result[1] := '1';\n                Result[3] := '1';\n              end;\n      end;\n      if (aInt and $01) <> 0 then // Or\n        Result[4] := '1';\n      if (aInt and $02) <> 0 then // Use aliases\n        Result[5] := '1';\n      if (aInt and $04) <> 0 then // Use global\n        Result[6] := '1';\n      if (aInt and $08) <> 0 then // Use packdata\n        Result[7] := '1';\n      if (aInt and $10) <> 0 then // Swap Subject and Target\n        Result[8] := '1';\n    end;\n    ctToStr: begin\n      case aInt and $E0 of\n        $00 : Result := 'Equal to';\n        $20 : Result := 'Not equal to';\n        $40 : Result := 'Greater than';\n        $60 : Result := 'Greater than or equal to';\n        $80 : Result := 'Less than';\n        $A0 : Result := 'Less than or equal to';\n      else\n        Result := '<Unknown Compare operator>'\n      end;\n      s := wbCtdaTypeFlags.ToString(aInt and $1F, aElement);\n      if s <> '' then\n        Result := Result + ' / ' + s;\n    end;\n    ctToSortKey: begin\n      Result := IntToHex64(aInt, 2);\n      Exit;\n    end;\n    ctCheck: begin\n      case aInt and $E0 of\n        $00, $20, $40, $60, $80, $A0 : Result := '';\n      else\n        Result := '<Unknown Compare operator>'\n      end;\n      s := wbCtdaTypeFlags.Check(aInt and $1F, aElement);\n      if s <> '' then\n        Result := Result + ' / ' + s;\n    end;\n  end;\nend;\n\nfunction wbCtdaTypeToInt(const aString: string; const aElement: IwbElement): Int64;\nvar\n  s: string;\nbegin\n  s := aString + '00000000';\n  if s[1] = '1' then begin\n    if s[2] = '1' then begin\n      if s[3] = '1' then begin\n        Result := $00;\n      end else begin\n        Result := $60;\n      end;\n    end else begin\n      if s[3] = '1' then begin\n        Result := $A0;\n      end else begin\n        Result := $00;\n      end;\n    end;\n  end else begin\n    if s[2] = '1' then begin\n      if s[3] = '1' then begin\n        Result := $20;\n      end else begin\n        Result := $40;\n      end;\n    end else begin\n      if s[3] = '1' then begin\n        Result := $80;\n      end else begin\n        Result := $20;\n      end;\n    end;\n  end;\n  // Or\n  if s[4] = '1' then\n    Result := Result or $01;\n  // Use aliases\n  if s[5] = '1' then\n    Result := Result or $02;\n  // Use global\n  if s[6] = '1' then\n    Result := Result or $04;\n  // Use packdata\n  if s[7] = '1' then\n    Result := Result or $08;\n  // Swap Subject and Target\n  if s[8] = '1' then\n    Result := Result or $10;\nend;\n\nvar\n  wbEventFunctionAndMemberEditInfo: string;\n\nfunction wbEventFunctionAndMemberToStr(aInt: Int64; const aElement: IwbElement; aType: TwbCallbackType): string;\nvar\n  EventFunction, EventMember: Integer;\n  i, j: Integer;\n  s1, s2: string;\n  slMember: TStringList;\nbegin\n  Result := '';\n  EventFunction := aInt and $FFFF;\n  EventMember := aInt shr 16;\n  case aType of\n    ctToStr, ctToEditValue: begin\n      Result := wbEventFunctionEnum.ToEditValue(EventFunction, nil);\n      Result := Result + ':' + wbEventMemberEnum.ToEditValue(EventMember, nil);\n    end;\n    ctToSortKey: Result := IntToHex(aInt, 8);\n    ctCheck: begin\n      s1 := wbEventFunctionEnum.Check(EventFunction, nil);\n      if s1 <> '' then\n        s1 := 'EventFunction' + s1;\n      s2 := wbEventMemberEnum.Check(EventMember, nil);\n      if s2 <> '' then\n        s2 := 'EventMember' + s2;\n      if (s1 <> '') or (s2 <> '') then\n        Result := s1 + ':' + s2;\n    end;\n    ctEditType:\n      Result := 'ComboBox';\n    ctEditInfo: begin\n      Result := wbEventFunctionAndMemberEditInfo;\n      if Result = '' then try\n        slMember := TStringList.Create;\n        slMember.CommaText := wbEventMemberEnum.EditInfo[0, nil];\n        with TStringList.Create do try\n          for i := 0 to Pred(wbEventFunctionEnum.NameCount) do\n            for j := 0 to Pred(slMember.Count) do\n              Add(wbEventFunctionEnum.Names[i] + ':' + slMember[j]);\n          Sort;\n          Result := CommaText;\n        finally\n          Free;\n        end;\n        wbEventFunctionAndMemberEditInfo := Result;\n      finally\n        FreeAndNil(slMember);\n      end\n    end;\n  end;\nend;\n\nfunction wbEventFunctionAndMemberToInt(const aString: string; const aElement: IwbElement): Int64;\nvar\n  EventFunction, EventMember, i: Integer;\nbegin\n  i := Pos(':', aString);\n  if i > 0 then begin\n    EventFunction := wbEventFunctionEnum.FromEditValue(Copy(aString, 1, i-1), nil);\n    EventMember := wbEventMemberEnum.FromEditValue(Copy(aString, i+1, Length(aString)), nil);\n  end\n  else begin\n    EventFunction := 0;\n    EventMember := 0;\n  end;\n  Result := EventMember shl 16 + EventFunction;\nend;\n\nprocedure wbMESGDNAMAfterSet(const aElement: IwbElement; const aOldValue, aNewValue: Variant);\nvar\n  OldValue, NewValue : Integer;\n  Container          : IwbContainerElementRef;\nbegin\n  if VarSameValue(aOldValue, aNewValue) then\n    Exit;\n  if Supports(aElement.Container, IwbContainerElementRef, Container) then begin\n    OldValue := Integer(aOldValue) and 1;\n    NewValue := Integer(aNewValue) and 1;\n    if NewValue = OldValue then\n      Exit;\n    if NewValue = 1 then\n      Container.RemoveElement('TNAM')\n    else\n      Container.Add('TNAM', True);\n  end;\nend;\n\nprocedure wbGMSTEDIDAfterSet(const aElement: IwbElement; const aOldValue, aNewValue: Variant);\nvar\n  OldValue, NewValue : string;\n  Container          : IwbContainerElementRef;\nbegin\n  if VarSameValue(aOldValue, aNewValue) then\n    Exit;\n  if Supports(aElement.Container, IwbContainerElementRef, Container) then begin\n    OldValue := aOldValue;\n    NewValue := aNewValue;\n    if (Length(OldValue) < 1) or (Length(OldValue) < 1) or (OldValue[1] <> NewValue[1]) then begin\n      Container.RemoveElement('DATA');\n      Container.Add('DATA', True);\n    end;\n  end;\nend;\n\nprocedure wbFLSTEDIDAfterSet(const aElement: IwbElement; const aOldValue, aNewValue: Variant);\nvar\n  OldValue, NewValue     : string;\n  OldOrdered, NewOrdered : Boolean;\n  Container              : IwbContainerElementRef;\nconst\n  OrderedList = 'OrderedList';\nbegin\n  if VarSameValue(aOldValue, aNewValue) then\n    Exit;\n  if Supports(aElement.Container, IwbContainerElementRef, Container) then begin\n    OldValue := aOldValue;\n    NewValue := aNewValue;\n\n    if Length(OldValue) > Length(OrderedList) then\n      Delete(OldValue, 1, Length(OldValue)-Length(OrderedList));\n    if Length(NewValue) > Length(OrderedList) then\n      Delete(NewValue, 1, Length(NewValue)-Length(OrderedList));\n\n    OldOrdered := SameText(OldValue, OrderedList);\n    NewOrdered := SameText(NewValue, OrderedList);\n\n    if OldOrdered <> NewOrdered then\n      Container.RemoveElement('FormIDs');\n  end;\nend;\n\nprocedure wbCtdaTypeAfterSet(const aElement: IwbElement; const aOldValue, aNewValue: Variant);\nvar\n  OldValue, NewValue: Integer;\n  Container: IwbContainerElementRef;\nbegin\n  if VarSameValue(aOldValue, aNewValue) then\n    Exit;\n  if not Supports(aElement, IwbContainerElementRef, Container) then\n    Exit;\n\n  // reset value if \"use global\" has changed\n  OldValue := aOldValue and $04;\n  NewValue := aNewValue and $04;\n  if OldValue <> NewValue then\n    Container.ElementNativeValues['..\\Comparison Value'] := 0;\n\n  {>>> \"run on target\", no such flag in Skyrim <<<}\n//  if aNewValue and $02 then begin\n//    Container.ElementNativeValues['..\\Run On'] := 1;\n//    if Integer(Container.ElementNativeValues['..\\Run On']) = 1 then\n//      aElement.NativeValue := Byte(aNewValue) and not $02;\n//  end;\nend;\n\nprocedure wbAfterSet(const aElement: IwbElement; const aOldValue, aNewValue: Variant);\nbegin\n  Exit;\nend;\n\nfunction wbMODTCallback(aInt: Int64; const aElement: IwbElement; aType: TwbCallbackType): string;\nvar\n  Strings: TDynStrings;\n  i: Integer;\nbegin\n  Result := '';\n  if wbLoaderDone and (aType in [ctToStr, ctToSortKey] ) then begin\n    Strings := wbContainerHandler.ResolveHash(aInt);\n    for i := Low(Strings) to High(Strings) do\n      Result := Result + Strings[i] + ', ';\n    SetLength(Result, Length(Result) -2 );\n  end;\nend;\n\n{>>> Needs revision for Skyrim <<<}\n//function wbIdleAnam(aInt: Int64; const aElement: IwbElement; aType: TwbCallbackType): string;\n//begin\n//  Result := '';\n//  case aType of\n//    ctToStr: begin\n//      case aInt and not $C0 of\n//        0: Result := 'Idle';\n//        1: Result := 'Movement';\n//        2: Result := 'Left Arm';\n//        3: Result := 'Left Hand';\n//        4: Result := 'Weapon';\n//        5: Result := 'Weapon Up';\n//        6: Result := 'Weapon Down';\n//        7: Result := 'Special Idle';\n//       20: Result := 'Whole Body';\n//       21: Result := 'Upper Body';\n//      else\n//        Result := '<Unknown: '+IntToStr(aInt and not $C0)+'>';\n//      end;\n//\n//      if (aInt and $80) = 0 then\n//        Result := Result + ', Must return a file';\n//      if (aInt and $40) = 1 then\n//        Result := Result + ', Unknown Flag';\n//    end;\n//    ctToSortKey: begin\n//      Result := IntToHex64(aInt, 2);\n//    end;\n//    ctCheck: begin\n//      case aInt and not $C0 of\n//        0..7, 20, 21: Result := '';\n//      else\n//        Result := '<Unknown: '+IntToStr(aInt and not $C0)+'>';\n//      end;\n//    end;\n//  end;\n//end;\n\nfunction wbScaledInt4ToStr(aInt: Int64; const aElement: IwbElement; aType: TwbCallbackType): string;\nconst\n  PlusMinus : array[Boolean] of string = ('+', '-');\nbegin\n  Result := '';\n  case aType of\n    ctToStr, ctToEditValue: Result := FloatToStrF(aInt / 10000, ffFixed, 99, 4);\n    ctToSortKey: begin\n      Result := FloatToStrF(aInt / 10000, ffFixed, 99, 4);\n      if Length(Result) < 22 then\n        Result := StringOfChar('0', 22 - Length(Result)) + Result;\n      Result := PlusMinus[aInt < 0] + Result;\n    end;\n    ctCheck: Result := '';\n  end;\nend;\n\nfunction wbScaledInt4ToInt(const aString: string; const aElement: IwbElement): Int64;\nvar\n  f: Extended;\nbegin\n  f := StrToFloat(aString);\n  f := f * 10000;\n  Result := Round(f);\nend;\n\nfunction wbCloudSpeedToStr(aInt: Int64; const aElement: IwbElement; aType: TwbCallbackType): string;\nbegin\n  Result := '';\n  case aType of\n    ctToStr, ctToEditValue: Result := FloatToStrF((aInt - 127)/127/10, ffFixed, 99, 4);\n    ctCheck: Result := '';\n  end;\nend;\n\nfunction wbCloudSpeedToInt(const aString: string; const aElement: IwbElement): Int64;\nvar\n  f: Extended;\nbegin\n  f := StrToFloat(aString);\n  f := f*10*127 + 127;\n  Result := Min(Round(f), 254);\nend;\n\nfunction wbShortXYtoStr(aInt: Int64; const aElement: IwbElement; aType: TwbCallbackType): string;\nvar\n  x, y: SmallInt;\nbegin\n  y := aInt and $FFFF;\n  x := aInt shr 16 and $FFFF;\n  Result := '';\n  case aType of\n    ctToStr, ctToEditValue: Result := Format('%d, %d', [x, y]);\n    ctCheck: Result := '';\n  end;\nend;\n\nfunction wbStrToShortXY(const aString: string; const aElement: IwbElement): Int64;\nvar\n  x, y: SmallInt;\n  Value: Cardinal;\nbegin\n  y := StrToIntDef(Copy(aString, 1, Pred(Pos(', ', aString))), 0);\n  x := StrToIntDef(Copy(aString, Pos(', ', aString) + 2, Length(aString)), 0);\n  PWord(@Value)^ := x;\n  PWord(Cardinal(@Value) + SizeOf(SmallInt))^ := y;\n  Result := Value;\nend;\n\nfunction wbHideFFFF(aInt: Int64; const aElement: IwbElement; aType: TwbCallbackType): string;\nbegin\n  Result := '';\n  if aType = ctToSortKey then\n    Result := IntToHex64(aInt, 4)\n  else if aType = ctToStr then\n    if aInt = $FFFF then\n      Result := 'None'\n    else\n      Result := IntToStr(aInt);\nend;\n\nfunction wbAtxtPosition(aInt: Int64; const aElement: IwbElement; aType: TwbCallbackType): string;\nbegin\n  Result := '';\n  if aType = ctToSortKey then\n    Result := IntToHex64(aInt div 17, 2) + IntToHex64(aInt mod 17, 2)\n  else if aType = ctCheck then begin\n    if (aInt < 0) or (aInt > 288) then\n      Result := '<Out of range: '+IntToStr(aInt)+'>'\n    else\n      Result := '';\n  end else if aType = ctToStr then\n    Result := IntToStr(aInt) + ' -> ' + IntToStr(aInt div 17) + ':' + IntToStr(aInt mod 17);\nend;\n\nfunction wbPlacedAddInfo(const aMainRecord: IwbMainRecord): string;\nvar\n  Rec: IwbRecord;\n  Container: IwbContainer;\n  s: string;\n  Cell: IwbMainRecord;\n  Position: TwbVector;\n  Grid: TwbGridCell;\nbegin\n  Result := '';\n\n  Rec := aMainRecord.RecordBySignature['NAME'];\n  if Assigned(Rec) then begin\n    s := Trim(Rec.Value);\n    if s <> '' then\n      Result := 'places ' + s;\n  end;\n\n  Container := aMainRecord.Container;\n  while Assigned(Container) and (Container.ElementType <> etGroupRecord) do\n    Container := Container.Container;\n\n  if Assigned(Container) then begin\n    s := Trim(Container.Name);\n    if s <> '' then begin\n      if Result <> '' then\n        Result := Result + ' ';\n      Result := Result + 'in ' + s;\n\n      // grid position of persistent reference in exterior persistent cell (interior cells are not persistent)\n      if Supports(aMainRecord.Container, IwbGroupRecord, Container) then\n        Cell := IwbGroupRecord(Container).ChildrenOf;\n      if Assigned(Cell) and Cell.IsPersistent and (Cell.Signature = 'CELL') then\n        if aMainRecord.GetPosition(Position) then begin\n          Grid := wbPositionToGridCell(Position);\n          Result := Result + ' at ' + IntToStr(Grid.x) + ',' + IntToStr(Grid.y);\n        end;\n\n      // in precombined mesh\n      if aMainRecord.HasPrecombinedMesh then\n        Result := Result + ' in ' + aMainRecord.PrecombinedMesh;\n    end;\n  end;\nend;\n\nfunction wbINFOAddInfo(const aMainRecord: IwbMainRecord): string;\nvar\n  Container: IwbContainer;\n  s: string;\nbegin\n  Result := Trim(aMainRecord.ElementValues['Responses\\Response\\NAM1']);\n  if Result <> '' then\n    Result := '''' + Result + '''';\n\n  Container := aMainRecord.Container;\n  while Assigned(Container) and (Container.ElementType <> etGroupRecord) do\n    Container := Container.Container;\n\n  if Assigned(Container) then begin\n    s := Trim(Container.Name);\n    if s <> '' then begin\n      if Result <> '' then\n        Result := Result + ' ';\n      Result := Result + 'in ' + s;\n    end;\n  end;\n\n  s := Trim(aMainRecord.ElementValues['QNAM']);\n  if s <> '' then begin\n    if Result <> '' then\n      Result := Result + ' ';\n    Result := Result + 'for ' + s;\n  end;\nend;\n\nfunction wbNAVMAddInfo(const aMainRecord: IwbMainRecord): string;\nvar\n  Container: IwbContainer;\n  s: string;\nbegin\n  Result := '';\n\n  Container := aMainRecord.Container;\n  while Assigned(Container) and (Container.ElementType <> etGroupRecord) do\n    Container := Container.Container;\n\n  if Assigned(Container) then begin\n    s := Trim(Container.Name);\n    if s <> '' then begin\n      if Result <> '' then\n        Result := Result + ' ';\n      Result := Result + 'in ' + s;\n    end;\n  end;\nend;\n\n//function wbNAVMAddInfo(const aMainRecord: IwbMainRecord): string;\n//var\n//  Rec        : IwbRecord;\n//  Element    : IwbElement;\n//  s          : string;\n//begin\n//  Result := '';\n//\n//  Rec := aMainRecord.RecordBySignature['DATA'];\n//  if Assigned(Rec) then begin\n//    Element := Rec.ElementByName['Cell'];\n//    if Assigned(Element) then\n//      Element := Element.LinksTo;\n//    if Assigned(Element) then\n//      s := Trim(Element.Name);\n//    if s <> '' then\n//      Result := 'for ' + s;\n//  end;\n//end;\n\nfunction wbCellAddInfo(const aMainRecord: IwbMainRecord): string;\nvar\n  Rec: IwbRecord;\n  Container: IwbContainer;\n  GroupRecord : IwbGroupRecord;\n  s: string;\nbegin\n  Result := '';\n\n  if not aMainRecord.IsPersistent then begin\n    Rec := aMainRecord.RecordBySignature['XCLC'];\n    if Assigned(Rec) then\n      Result := 'at ' + Rec.Elements[0].Value + ',' + Rec.Elements[1].Value;\n  end;\n\n  Container := aMainRecord.Container;\n  while Assigned(Container) and not\n    (Supports(Container, IwbGroupRecord, GroupRecord) and (GroupRecord.GroupType = 1))  do\n    Container := Container.Container;\n\n  if Assigned(Container) then begin\n    s := wbFormID.ToString(GroupRecord.GroupLabel, aMainRecord);\n    if s <> '' then begin\n      if Result <> '' then\n        s := s + ' ';\n      Result := 'in ' + s + Result;\n    end;\n  end;\nend;\n\nprocedure wbCTDARunOnAfterSet(const aElement: IwbElement; const aOldValue, aNewValue: Variant);\nbegin\n  if aOldValue <> aNewValue then\n    if aNewValue <> 2 then\n      aElement.Container.ElementNativeValues['Reference'] := 0;\nend;\n\n{>>> Needs revision for Skyrim <<<}\nprocedure wbPERKPRKETypeAfterSet(const aElement: IwbElement; const aOldValue, aNewValue: Variant);\nvar\n  Container : IwbContainerElementRef;\n//  rDATA     : IwbRecord;\nbegin\n  if aOldValue <> aNewValue then\n    if Supports(aElement.Container, IwbContainerElementRef, Container) then begin\n      if Supports(Container.Container, IwbContainerElementRef, Container) then begin\n        Container.RemoveElement('DATA');\n        Container.Add('DATA', True);\n        Container.RemoveElement('Perk Conditions');\n        Container.RemoveElement('Entry Point Function Parameters');\n        if aNewValue = 2 then begin\n          Container.Add('EPFT', True);\n          Container.ElementNativeValues['DATA\\Entry Point\\Function'] := 2;\n        end;\n      end;\n    end;\nend;\n\nfunction wbNPCLevelDecider(aBasePtr: Pointer; aEndPtr: Pointer; const aElement: IwbElement): Integer;\nvar\n  Container: IwbContainer;\n  i: Int64;\nbegin\n  Result := 0;\n  if not Assigned(aElement) then Exit;\n  Container := GetContainerFromUnion(aElement);\n  if not Assigned(Container) then Exit;\n\n  i := Container.ElementByName['Flags'].NativeValue;\n  if i and $00000080 <> 0 then\n    Result := 1;\nend;\n\nfunction wbMGEFAssocItemDecider(aBasePtr: Pointer; aEndPtr: Pointer; const aElement: IwbElement): Integer;\nvar\n  Container     : IwbContainer;\n  Archtype      : Variant;\n  DataContainer : IwbDataContainer;\n  Element       : IwbElement;\nconst\n  OffsetArchtype = 56;\n\nbegin\n  Result := 0;\n  if not Assigned(aElement) then Exit;\n  Container := GetContainerFromUnion(aElement);\n  if not Assigned(Container) then Exit;\n\n  VarClear(ArchType);\n  Element := Container.ElementByName['Archetype'];\n  if Assigned(Element) then\n    ArchType := Element.NativeValue\n  else if Supports(Container, IwbDataContainer, DataContainer) and\n          DataContainer.IsValidOffset(aBasePtr, aEndPtr, OffsetArchtype) then begin // we are part a proper structure\n      aBasePtr := Pointer(Cardinal(aBasePtr) + OffsetArchtype);\n      ArchType := PCardinal(aBasePtr)^;\n    end;\n\n  if not VarIsEmpty(ArchType) then\n    case Integer(ArchType) of\n      12: Result := 1; // Light\n      17: Result := 2; // Bound Item\n      18: Result := 3; // Summon Creature\n      25: Result := 4; // Guide\n      34: Result := 8; // Peak Mod\n      35: Result := 5; // Cloak\n      36: Result := 6; // Werewolf\n      39: Result := 7; // Enhance Weapon\n      40: Result := 4; // Spawn Hazard\n      46: Result := 6; // Vampire Lord\n    end;\nend;\n\nprocedure wbMGEFAssocItemAfterSet(const aElement: IwbElement; const aOldValue, aNewValue: Variant);\nvar\n  Container : IwbContainer;\n  Element   : IwbElement;\nbegin\n  if not Assigned(aElement) then Exit;\n  Container := GetContainerFromUnion(aElement);\n  if not Assigned(Container) then Exit;\n  if (aNewValue <> 0) then begin\n    Element := Container.ElementByName['Archetype'];\n    if Assigned(Element) and (Element.NativeValue = 0) then\n        Element.NativeValue := $FF; // Signals ArchType that it should not mess with us on the next change!\n          // I assume this will alo protect Second AV Weight (The two actor values are after ArchType)\n  end;\nend;\n\nprocedure wbMGEFAV2WeightAfterSet(const aElement: IwbElement; const aOldValue, aNewValue: Variant);\nvar\n  Container : IwbContainer;\n  Element   : IwbElement;\nbegin\n  if not Assigned(aElement) then Exit;\n  Container := GetContainerFromUnion(aElement);\n  if not Assigned(Container) then Exit;\n  if (aNewValue <> 0.0) then begin\n    Element := Container.ElementByName['Archetype'];\n    if Assigned(Element) and (Element.NativeValue = 0) then\n        Element.NativeValue := $FF; // Signals ArchType that it should not mess with us on the next change!\n  end;\nend;\n\nprocedure wbMGEFArchtypeAfterSet(const aElement: IwbElement; const aOldValue, aNewValue: Variant);\nvar\n  Container: IwbContainerElementRef;\nbegin\n  if VarSameValue(aOldValue, aNewValue) then\n    Exit;\n  if not Supports(aElement, IwbContainerElementRef, Container) then\n    Exit;\n  if (aNewValue < $FF) and (aOldValue < $FF) then begin\n    Container.ElementNativeValues['..\\Assoc. Item'] := 0;\n    case Integer(aNewValue) of\n      06: Container.ElementNativeValues['..\\Actor Value'] := 00;//Agression\n      07: Container.ElementNativeValues['..\\Actor Value'] := 01;//Confidence\n      08: Container.ElementNativeValues['..\\Actor Value'] := 00;//Agression\n      11: Container.ElementNativeValues['..\\Actor Value'] := 54;//Invisibility\n      21: Container.ElementNativeValues['..\\Actor Value'] := 53;//Paralysis\n      24: Container.ElementNativeValues['..\\Actor Value'] := 01;//Confidence\n      38: Container.ElementNativeValues['..\\Actor Value'] := 01;//Confidence\n      42: Container.ElementNativeValues['..\\Actor Value'] := 01;//Confidence\n    else\n      Container.ElementNativeValues['..\\Actor Value'] := -1;\n    end;\n    Container.ElementNativeValues['..\\Second Actor Value'] := -1;\n    Container.ElementNativeValues['..\\Second AV Weight'] := 0.0;\n  end;\nend;\n\nfunction wbCTDAReferenceDecider(aBasePtr: Pointer; aEndPtr: Pointer; const aElement: IwbElement): Integer;\nvar\n  Container     : IwbContainer;\nbegin\n  Result := 0;\n  if not Assigned(aElement) then Exit;\n  Container := GetContainerFromUnion(aElement);\n  if not Assigned(Container) then Exit;\n\n  if Integer(Container.ElementNativeValues['Run On']) = 2 then\n    Result := 1;\nend;\n\nfunction wbNAVIIslandDataDecider(aBasePtr: Pointer; aEndPtr: Pointer; const aElement: IwbElement): Integer;\nvar\n  Container   : IwbContainer;\n  SubRecord   : IwbMainRecord;\n  Element     : IwbElement;\nbegin\n  Result := 0;\n\n  Container := aElement.Container;\n  while Assigned(Container) and (Container.ElementType <> etSubRecord) do\n    Container := Container.Container;\n\n  if not Supports(Container, IwbSubRecord, SubRecord) then\n    Exit;\n\n  Element := SubRecord.ElementByName['Is Island'];\n  if not Assigned(Element) then\n    Exit;\n\n  Result := Element.NativeValue;\nend;\n\nfunction wbNAVIParentDecider(aBasePtr: Pointer; aEndPtr: Pointer; const aElement: IwbElement): Integer;\nvar\n  Container   : IwbContainer;\n  SubRecord   : IwbMainRecord;\n  Element     : IwbElement;\nbegin\n  Result := 0;\n\n  Container := aElement.Container;\n  while Assigned(Container) and (Container.ElementType <> etsubRecord) do\n    Container := Container.Container;\n\n  if not Supports(Container, IwbSubRecord, SubRecord) then\n    Exit;\n\n  Element := SubRecord.ElementByName['Parent Worldspace'];\n  if not Assigned(Element) then\n    Exit;\n\n  if (Element.NativeValue = 0) then\n    Result := 1;\nend;\n\nfunction wbNVNMParentDecider(aBasePtr: Pointer; aEndPtr: Pointer; const aElement: IwbElement): Integer;\nvar\n  Container   : IwbContainer;\n  Parent      : IwbElement;\n  i           : integer;\nbegin  // Could be simplified by checking if Parent Worldspace is NULL, that's what the runtime does :)\n  Result := 0;\n\n  Container := aElement.Container;\n\n  Parent := Container.ElementByName['Parent Worldspace'];\n\n  if not Assigned(Parent) then\n    Exit;\n\n  i := Parent.NativeValue;\n\n  // is interior cell?\n  if i = 0 then\n    Result := 1;\nend;\n\nfunction wbDoorTriangleDoorTriangleDecider(aBasePtr: Pointer; aEndPtr: Pointer; const aElement: IwbElement): Integer;\nvar\n  Container   : IwbContainer;\n  Parent      : IwbElement;\n  i           : int64;\nbegin\n  Result := 0;\n\n  Container := aElement.Container;\n\n  Parent := Container.ElementByName['DTUnknown'];\n\n  if not Assigned(Parent) then\n    Exit;\n\n  i := Parent.NativeValue;\n\n  // not sure if it would be an error in the file or if it really possible\n  if i <> 0 then\n    Result := 1;\nend;\n\nfunction wbSubrecordSizeDecider(aBasePtr: Pointer; aEndPtr: Pointer; const aElement: IwbElement): Integer;\nvar\n  SubRecord : IwbSubRecord;\nbegin\n  Result := 0;\n  if not Assigned(aElement) then Exit;\n\n  if Supports(aElement, IwbSubRecord, SubRecord) then\n    if SubRecord.DataSize > 0 then\n      Result := 1;\nend;\n\nfunction wbCOEDOwnerDecider(aBasePtr: Pointer; aEndPtr: Pointer; const aElement: IwbElement): Integer;\nvar\n  Container  : IwbContainer;\n  LinksTo    : IwbElement;\n  MainRecord : IwbMainRecord;\nbegin\n  Result := 0;\n  if not Assigned(aElement) then Exit;\n  Container := GetContainerFromUnion(aElement);\n  if not Assigned(Container) then Exit;\n\n  LinksTo := Container.ElementByName['Owner'].LinksTo;\n\n  if Supports(LinksTo, IwbMainRecord, MainRecord) then\n    if MainRecord.Signature = 'NPC_' then\n      Result := 1\n    else if MainRecord.Signature = 'FACT' then\n      Result := 2;\nend;\n\nfunction wbGMSTUnionDecider(aBasePtr: Pointer; aEndPtr: Pointer; const aElement: IwbElement): Integer;\nvar\n  rEDID: IwbRecord;\n  s: string;\nbegin\n  Result := 1;\n  rEDID := aElement.Container.RecordBySignature[EDID];\n  if Assigned(rEDID) then begin\n    s := rEDID.Value;\n    if Length(s) > 0 then\n      case s[1] of\n        's': Result := 0; {String} {>>> Localization Strings <<<}\n        'i': Result := 1; {intS32}\n        'f': Result := 2; {Float}\n        'b': Result := 3; {Boolean}\n      end;\n  end;\nend;\n\nfunction wbFLSTLNAMIsSorted(const aContainer: IwbContainer): Boolean;\nvar\n  rEDID      : IwbRecord;\n  s          : string;\nconst\n  OrderedList = 'OrderedList';\nbegin\n  Result := False; {>>> Should not be sorted according to Arthmoor and JustinOther <<<}\n  rEDID := aContainer.RecordBySignature[EDID];\n  if Assigned(rEDID) then begin\n    s := rEDID.Value;\n    if Length(s) > Length(OrderedList) then\n      Delete(s, 1, Length(s)-Length(OrderedList));\n    if SameText(s, OrderedList) then\n      Result := False;\n  end;\nend;\n\nfunction wbPerkDATADecider(aBasePtr: Pointer; aEndPtr: Pointer; const aElement: IwbElement): Integer;\nvar\n  rPRKE: IwbRecord;\n  eType: IwbElement;\nbegin\n  Result := 0;\n  rPRKE := aElement.Container.RecordBySignature[PRKE];\n  if Assigned(rPRKE) then begin\n    eType := rPRKE.ElementByName['Type'];\n    if Assigned(eType) then begin\n      Result := eType.NativeValue;\n    end;\n  end;\nend;\n\nfunction wbEPFDDecider(aBasePtr: Pointer; aEndPtr: Pointer; const aElement: IwbElement): Integer;\nvar\n  Container: IwbContainerElementRef;\nbegin\n  Result := 0;\n  if not Assigned(aElement) then\n    Exit;\n  if not Supports(aElement.Container, IwbContainerElementRef, Container) then\n    Exit;\n  Result := Container.ElementNativeValues['EPFT'];\n  if Result = 2 then\n    case Integer(Container.ElementNativeValues['..\\DATA\\Entry Point\\Function']) of\n      5, 12, 13, 14: Result := 8;\n    end;\nend;\n\nfunction wbSceneActionSoundDecider(aBasePtr: Pointer; aEndPtr: Pointer; const aElement: IwbElement): Integer;\nvar\n  Container: IwbContainerElementRef;\nbegin\n  Result := 0;\n  if not Assigned(aElement) then\n    Exit;\n  if not Supports(aElement.Container, IwbContainerElementRef, Container) then\n    Exit;\n  if Container.ElementNativeValues['ANAM'] <> 4 then\n    Result := 1;\nend;\n\nfunction wbEFSHFormatDecider(aBasePtr: Pointer; aEndPtr: Pointer; const aElement: IwbElement): Integer;\nvar\n  MainRecord: IwbMainRecord;\nbegin\n  Result := 0;\n  if not Assigned(aElement) then\n    Exit;\n  if not Supports(aElement.Container, IwbMainRecord, MainRecord) then\n    Exit;\n  if MainRecord.Version < 102 then\n    Result := 1;\nend;\n\nfunction wbDeciderFormVersion99(aBasePtr: Pointer; aEndPtr: Pointer; const aElement: IwbElement): Integer;\nbegin\n  Result := wbFormVerDecider(aBasePtr, aEndPtr, aElement, 99);\nend;\n\nfunction wbAECHDataDecider(aBasePtr: Pointer; aEndPtr: Pointer; const aElement: IwbElement): Integer;\nvar\n  Container  : IwbContainer;\n  rKNAM      : IwbElement;\n  s: string;\nbegin\n  Result := 0;\n  if not Assigned(aElement) then Exit;\n  Container := GetContainerFromUnion(aElement);\n  if not Assigned(Container) then Exit;\n\n  Container := Container.Container;\n  if not Assigned(Container) then Exit;\n\n  rKNAM := Container.ElementBySignature['KNAM'];\n  if not Assigned(rKNAM) then Exit;\n\n  s := rKNAM.EditValue;\n\n  if s = 'BSOverdrive' then\n    Result := 0\n  else if s = 'BSStateVariableFilter' then\n    Result := 1\n  else if s = 'BSDelayEffect' then\n    Result := 2;\nend;\n\nfunction wbCLFMColorDecider(aBasePtr: Pointer; aEndPtr: Pointer; const aElement: IwbElement): Integer;\nvar\n  Container  : IwbContainer;\n  rFNAM      : IwbElement;\n  i          : Integer;\nbegin\n  Result := 0;\n\n  // resolving to a float causes data loss when copying\n  // since deciding field FNAM comes after a value CNAM\n  Exit;\n\n  if not Assigned(aElement) then Exit;\n  Container := GetContainerFromUnion(aElement);\n  if not Assigned(Container) then Exit;\n\n  Container := Container.Container;\n  if not Assigned(Container) then Exit;\n\n  rFNAM := Container.ElementBySignature['FNAM'];\n  if not Assigned(rFNAM) then Exit;\n\n  i := rFNAM.NativeValue;\n\n  if i and 2 <> 0 then\n    Result := 1;\nend;\n\nfunction wbCLFMColorToStr(aInt: Int64; const aElement: IwbElement; aType: TwbCallbackType): string;\nvar\n  Container  : IwbContainer;\n  rFNAM      : IwbElement;\n  i          : Integer;\n  s          : string;\nbegin\n  i := 0;\n  Container := aElement.Container;\n  if Assigned(Container) then begin\n    rFNAM := Container.ElementBySignature['FNAM'];\n    if Assigned(rFNAM) then\n      i := rFNAM.NativeValue;\n  end;\n\n   if i and 2 <> 0 then\n    s := FloatToStrF(PSingle(@aInt)^, ffFixed, 99, wbFloatDigits)\n  else\n    s := 'rgba(' + IntToStr(aInt and $FF) + ', ' +\n                   IntToStr(aInt shr 8 and $FF) + ', ' +\n                   IntToStr(aInt shr 16 and $FF) + ', ' +\n                   IntToStr(aInt shr 24 and $FF) + ')';\n\n  case aType of\n    ctToStr: Result := s;\n    ctToSortKey: Result := IntToHex(aInt, 8);\n    ctToEditValue: Result := s;\n  end;\nend;\n\nfunction wbCLFMColorToInt(const aString: string; const aElement: IwbElement): Int64;\nvar\n  s: string;\n  value: Single;\nbegin\n  if SameText(Copy(aString, 1, 5), 'rgba(') then begin\n    s := Copy(aString, 6, Pos(')', aString) - 6);\n    with TStringList.Create do try\n      Delimiter := ',';\n      StrictDelimiter := True;\n      DelimitedText := s;\n      Result := 0;\n      if Count = 4 then begin\n        PByte(@Result)[0] := StrToIntDef(Strings[0], 0);\n        PByte(@Result)[1] := StrToIntDef(Strings[1], 0);\n        PByte(@Result)[2] := StrToIntDef(Strings[2], 0);\n        PByte(@Result)[3] := StrToIntDef(Strings[3], 0);\n      end;\n    finally\n      Free;\n    end;\n  end\n  else begin\n    try value := StrToFloat(aString) except value := 0.0 end;\n    Result := PInteger(@value)^;\n  end;\nend;\n\nfunction wbNOTEDataDecider(aBasePtr: Pointer; aEndPtr: Pointer; const aElement: IwbElement): Integer;\nvar\n  Container  : IwbContainer;\n  rDNAM      : IwbElement;\n  i          : Integer;\nbegin\n  Result := 0;\n\n  if not Assigned(aElement) then Exit;\n  Container := GetContainerFromUnion(aElement);\n  if not Assigned(Container) then Exit;\n\n  Container := Container.Container;\n  if not Assigned(Container) then Exit;\n\n  rDNAM := Container.ElementBySignature['DNAM'];\n  if not Assigned(rDNAM) then Exit;\n\n  i := rDNAM.NativeValue;\n\n  case i of\n    0: Result := 1;\n    1: Result := 2;\n    3: Result := 3;\n  end;\nend;\n\nfunction wbSNDRDataDecider(aBasePtr: Pointer; aEndPtr: Pointer; const aElement: IwbElement): Integer;\nvar\n  Container  : IwbContainer;\n  rCNAM      : IwbElement;\nbegin\n  Result := 0;\n\n  if not Assigned(aElement) then Exit;\n  Container := GetContainerFromUnion(aElement);\n  if not Assigned(Container) then Exit;\n\n  Container := Container.Container;\n  if not Assigned(Container) then Exit;\n\n  rCNAM := Container.ElementBySignature['CNAM'];\n  if not Assigned(rCNAM) then Exit;\n\n  if rCNAM.EditValue = 'AutoWeapon' then\n    Result := 1;\nend;\n\n\n{>>> For VMAD <<<}\nfunction wbScriptObjFormatDecider(aBasePtr: Pointer; aEndPtr: Pointer; const aElement: IwbElement): Integer;\nvar\n  ObjFormat: Integer;\n  Container: IwbContainer;\nbegin\n  Result := 0;\n\n  Container := aElement.Container;\n  while Assigned(Container) and (Container.ElementType <> etSubRecord) do\n    Container := Container.Container;\n\n  if not Assigned(Container) then Exit;\n\n  ObjFormat := Container.ElementNativeValues['Object Format'];\n\n  if ObjFormat = 1 then\n    Result := 1;\nend;\n\n{>>> For VMAD <<<}\nfunction wbScriptPropertyDecider(aBasePtr: Pointer; aEndPtr: Pointer; const aElement: IwbElement): Integer;\nvar\n  Container     : IwbContainer;\nbegin\n  Result := 0;\n  if not Assigned(aElement) then Exit;\n  Container := GetContainerFromUnion(aElement);\n  if not Assigned(Container) then Exit;\n\n  case Integer(Container.ElementNativeValues['Type']) of\n     1: Result := 1;\n     2: Result := 2;\n     3: Result := 3;\n     4: Result := 4;\n     5: Result := 5;\n     6: Result := 6;\n     7: Result := 7;\n    11: Result := 8;\n    12: Result := 9;\n    13: Result := 10;\n    14: Result := 11;\n    15: Result := 12;\n    17: Result := 13;\n  end;\nend;\n\nfunction wbScriptPropertyStructMemberDecider(aBasePtr: Pointer; aEndPtr: Pointer; const aElement: IwbElement): Integer;\nvar\n  Container     : IwbContainer;\nbegin\n  Result := 0;\n  if not Assigned(aElement) then Exit;\n  Container := GetContainerFromUnion(aElement);\n  if not Assigned(Container) then Exit;\n\n  case Integer(Container.ElementNativeValues['Type']) of\n     1: Result := 1;\n     2: Result := 2;\n     3: Result := 3;\n     4: Result := 4;\n     5: Result := 5;\n    11: Result := 6;\n    12: Result := 7;\n    13: Result := 8;\n    14: Result := 9;\n    15: Result := 10;\n  end;\nend;\n\nprocedure wbScriptPropertyTypeAfterSet(const aElement: IwbElement; const aOldValue, aNewValue: Variant);\nvar\n  Container : IwbContainerElementRef;\nbegin\n  if aOldValue <> aNewValue then\n    if Supports(aElement.Container, IwbContainerElementRef, Container) then\n      Container.ElementByName['Value'].SetToDefault;\nend;\n\n{>>> For VMAD <<<}\nfunction wbScriptFragmentsDecider(aBasePtr: Pointer; aEndPtr: Pointer; const aElement: IwbElement): Integer;\nvar\n  Container  : IwbContainer;\n  MainRecord : IwbMainRecord;\nbegin\n  Result := 0;\n  if not Assigned(aElement) then Exit;\n  Container := GetContainerFromUnion(aElement);\n  if not Assigned(Container) then Exit;\n  while Assigned(Container) and (Container.ElementType <> etMainRecord) do\n    Container := Container.Container;\n  if not Assigned(Container) then Exit;\n\n  Supports(Container, IwbMainRecord, MainRecord);\n  if MainRecord.Signature = PERK then\n    Result := 1\n  else if MainRecord.Signature = TERM then\n    Result := 1\n  else if MainRecord.Signature = INFO then\n    Result := 2\n  else if MainRecord.Signature = PACK then\n    Result := 3\n  else if MainRecord.Signature = QUST then\n    Result := 4\n  else if MainRecord.Signature = SCEN then\n    Result := 5;\nend;\n\n{>>> For VMAD <<<}\nfunction wbScriptFragmentsQuestCounter(aBasePtr: Pointer; aEndPtr: Pointer; const aElement: IwbElement): Cardinal;\nvar\n  Container     : IwbContainer;\nbegin\n  Result := 0;\n  if aElement.ElementType = etValue then\n    Container := aElement.Container\n  else\n    Container := aElement as IwbContainer;\n  if not Assigned(Container) then Exit;\n  while Assigned(Container) and (Container.Name <> 'Script Fragments') do\n    Container := Container.Container;\n  if not Assigned(Container) then Exit;\n\n  Result := Cardinal(Container.ElementNativeValues['fragmentCount']);\nend;\n\n{>>> For VMAD <<<}\nfunction wbScriptFragmentsInfoCounter(aBasePtr: Pointer; aEndPtr: Pointer; const aElement: IwbElement): Cardinal;\nvar\n  Container     : IwbContainer;\n  F             : Integer;\n  i             : Integer;\nbegin\n  Result := 0;\n  if aElement.ElementType = etValue then\n    Container := aElement.Container\n  else\n    Container := aElement as IwbContainer;\n  if not Assigned(Container) then Exit;\n  while Assigned(Container) and (Container.Name <> 'Script Fragments') do\n    Container := Container.Container;\n  if not Assigned(Container) then Exit;\n\n  F := Container.ElementByName['Flags'].NativeValue;\n  for i := 0 to 2 do begin\n    if (F and 1) = 1 then\n      Inc(Result);\n    F := F shr 1;\n  end;\n  for i := 3 to 7 do begin\n    if (F and 1) = 1 then begin\n      Inc(Result);\n    if Assigned(wbProgressCallback) then\n      wbProgressCallback('==='+aElement.Name+'       ['+Container.Name+':'+Container.Path+'] = unknown info VMAD flag bit '+IntToStr(i));\n  end;\n    F := F shr 1;\n  end;\nend;\n\n{>>> For VMAD <<<}\nfunction wbScriptFragmentsSceneCounter(aBasePtr: Pointer; aEndPtr: Pointer; const aElement: IwbElement): Cardinal;\nvar\n  Container     : IwbContainer;\n  F             : Integer;\n  i             : Integer;\nbegin\n  Result := 0;\n  if aElement.ElementType = etValue then\n    Container := aElement.Container\n  else\n    Container := aElement as IwbContainer;\n  if not Assigned(Container) then Exit;\n  while Assigned(Container) and (Container.Name <> 'Script Fragments') do\n    Container := Container.Container;\n  if not Assigned(Container) then Exit;\n\n  F := Container.ElementByName['Flags'].NativeValue;\n  for i := 0 to 2 do begin\n    if (F and 1) = 1 then\n      Inc(Result);\n    F := F shr 1;\n  end;\n  for i := 3 to 7 do begin\n    if (F and 1) = 1 then begin\n      Inc(Result);\n  if Assigned(wbProgressCallback) then\n      wbProgressCallback('==='+aElement.Name+'       ['+Container.Name+':'+Container.Path+'] = unknown scene VMAD flag bit '+IntToStr(i));\n  end;\n    F := F shr 1;\n  end;\nend;\n\n{>>> For VMAD <<<}\nfunction wbScriptFragmentsPackCounter(aBasePtr: Pointer; aEndPtr: Pointer; const aElement: IwbElement): Cardinal;\nvar\n  Container     : IwbContainer;\n  F             : Integer;\n  i             : Integer;\nbegin\n  Result := 0;\n  if aElement.ElementType = etValue then\n    Container := aElement.Container\n  else\n    Container := aElement as IwbContainer;\n  if not Assigned(Container) then Exit;\n  while Assigned(Container) and (Container.Name <> 'Script Fragments') do\n    Container := Container.Container;\n  if not Assigned(Container) then Exit;\n\n  F := Container.ElementByName['Flags'].NativeValue;\n  for i := 0 to 7 do begin\n    if (F and 1) = 1 then\n      Inc(Result);\n    F := F shr 1;\n  end;\nend;\n\n{>>> For VMAD <<<}\nfunction wbScriptFragmentsEmptyScriptDecider(aBasePtr: Pointer; aEndPtr: Pointer; const aElement: IwbElement): Integer;\nvar\n  Container  : IwbContainer;\nbegin\n  Result := 0;\n  if not Assigned(aElement) then Exit;\n  Container := GetContainerFromUnion(aElement);\n  if not Assigned(Container) then Exit;\n\n  if Container.ElementEditValues['scriptName'] = '' then\n    Result := 1;\nend;\n\nfunction wbBOOKTeachesDecider(aBasePtr: Pointer; aEndPtr: Pointer; const aElement: IwbElement): Integer;\nvar\n  Container: IwbContainer;\n  i: Int64;\nbegin\n  Result := 0;\n  if not Assigned(aElement) then Exit;\n  Container := GetContainerFromUnion(aElement);\n  if not Assigned(Container) then Exit;\n\n  i := Container.ElementByName['Flags'].NativeValue;\n  if i and $01 <> 0 then\n    Result := 1\n  else if i and $04 <> 0 then\n    Result := 2\n  else if i and $10 <> 0 then\n    Result := 3\n  else\n    Result := 0;\nend;\n\ntype\n  TCTDAFunctionParamType = (\n    { 0} ptNone,\n    { 1} ptInteger,\n    { 2} ptFloat,\n    { 3} ptActor,              // ACHR\n    { 4} ptActorBase,          // NPC_\n    { 5} ptActorValue,         // Enum: wbActorValue\n    { 6} ptAdvanceAction,      // ?? Enum\n    { 7} ptAlias,              // index into QUST quest aliases\n    { 8} ptAlignment,          // ?? Enum\n    { 9} ptAssociationType,    // ASTP\n    {10} ptAxis,               // ?? Char\n    {11} ptCastingSource,      // ?? Enum\n    {12} ptCell,               // CELL\n    {13} ptClass,              // CLAS\n    {14} ptCrimeType,          // ?? Enum\n    {15} ptCriticalStage,      // ?? Enum\n    {16} ptEncounterZone,      // ECZN\n    {17} ptEquipType,          // ?? Enum\n    {18} ptEvent,              // Struct\n    {19} ptEventData,          // LCTN, KYWD or FLST\n    {20} ptFaction,            // FACT\n    {21} ptFormList,           // FLST\n    {22} ptFormType,           // ?? Enum\n    {23} ptFurniture,          // FURN\n    {24} ptFurnitureAnim,      // enum\n    {25} ptFurnitureEntry,     // flags\n    {26} ptGlobal,             // GLOB\n    {27} ptIdleForm,           // IDLE\n    {28} ptInventoryObject,    // ARMO, BOOK, MISC, WEAP, AMMO, KEYM, ALCH, ARMA, LIGH, LVLI, COBJ\n    {29} ptKeyword,            // KYWD\n    {30} ptLocation,           // LCTN\n    {31} ptMagicEffect,        // MGEF\n    {32} ptMagicItem,          // SPEL\n    {33} ptMiscStat,           // ?? Enum\n    {34} ptObjectReference,    // REFR, ACHR\n    {35} ptOwner,              // FACT, NPC_\n    {36} ptPackage,            // PACK\n    {37} ptPackdata,           // index into PACK package data inputs\n    {38} ptPerk,               // PERK\n    {39} ptQuest,              // QUST\n    {40} ptQuestStage,         // ?? Integer\n    {41} ptRace,               // RACE\n    {42} ptReferencableObject,\n    {43} ptRefType,            // LCRT\n    {44} ptRegion,             // REGN\n    {45} ptScene,              // SCEN\n    {46} ptSex,                // Enum: Male, Female\n    {47} ptShout,              // SHOU\n    {48} ptVariableName,       // Integer\n    {49} ptVATSValueFunction,  //\n    {50} ptVATSValueParam,\n    {51} ptVoiceType,          // VTYP\n    {52} ptWardState,          // enum\n    {53} ptWeather,            // WTHR\n    {54} ptWorldspace,         // WRLD\n    {55} ptDamageType          // DMGT\n  );\n\n  PCTDAFunction = ^TCTDAFunction;\n  TCTDAFunction = record\n    Index: Integer;\n    Name: string;\n    ParamType1: TCTDAFunctionParamType;\n    ParamType2: TCTDAFunctionParamType;\n    ParamType3: TCTDAFunctionParamType;\n  end;\n\nconst\n  wbCTDAFunctions : array[0..514] of TCTDAFunction = (\n    (Index:   0; Name: 'GetWantBlocking'),\n    (Index:   1; Name: 'GetDistance'; ParamType1: ptObjectReference),\n    (Index:   5; Name: 'GetLocked'),\n    (Index:   6; Name: 'GetPos'; ParamType1: ptAxis),\n    (Index:   8; Name: 'GetAngle'; ParamType1: ptAxis),\n    (Index:  10; Name: 'GetStartingPos'; ParamType1: ptAxis),\n    (Index:  11; Name: 'GetStartingAngle'; ParamType1: ptAxis),\n    (Index:  12; Name: 'GetSecondsPassed'),\n    (Index:  14; Name: 'GetValue'; ParamType1: ptActorValue),\n    (Index:  18; Name: 'GetCurrentTime'),\n    (Index:  24; Name: 'GetScale'),\n    (Index:  25; Name: 'IsMoving'),\n    (Index:  26; Name: 'IsTurning'),\n    (Index:  27; Name: 'GetLineOfSight'; ParamType1: ptObjectReference),\n    (Index:  31; Name: 'GetButtonPressed'),\n    (Index:  32; Name: 'GetInSameCell'; ParamType1: ptObjectReference),\n    (Index:  35; Name: 'GetDisabled'),\n    (Index:  39; Name: 'GetDisease'),\n    (Index:  41; Name: 'GetClothingValue'),\n    (Index:  42; Name: 'SameFaction'; ParamType1: ptActor),\n    (Index:  43; Name: 'SameRace'; ParamType1: ptActor),\n    (Index:  44; Name: 'SameSex'; ParamType1: ptActor),\n    (Index:  45; Name: 'GetDetected'; ParamType1: ptActor),\n    (Index:  46; Name: 'GetDead'),\n    (Index:  47; Name: 'GetItemCount'; ParamType1: ptReferencableObject),\n    (Index:  48; Name: 'GetGold'),\n    (Index:  49; Name: 'GetSleeping'),\n    (Index:  50; Name: 'GetTalkedToPC'),\n    (Index:  56; Name: 'GetQuestRunning'; ParamType1: ptQuest),\n    (Index:  58; Name: 'GetStage'; ParamType1: ptQuest),\n    (Index:  59; Name: 'GetStageDone'; ParamType1: ptQuest; ParamType2: ptQuestStage),\n    (Index:  60; Name: 'GetFactionRankDifference'; ParamType1: ptFaction; ParamType2: ptActor),\n    (Index:  61; Name: 'GetAlarmed'),\n    (Index:  62; Name: 'IsRaining'),\n    (Index:  63; Name: 'GetAttacked'),\n    (Index:  64; Name: 'GetIsCreature'),\n    (Index:  65; Name: 'GetLockLevel'),\n    (Index:  66; Name: 'GetShouldAttack'; ParamType1: ptActor),\n    (Index:  67; Name: 'GetInCell'; ParamType1: ptCell),\n    (Index:  68; Name: 'GetIsClass'; ParamType1: ptClass),\n    (Index:  69; Name: 'GetIsRace'; ParamType1: ptRace),\n    (Index:  70; Name: 'GetIsSex'; ParamType1: ptSex),\n    (Index:  71; Name: 'GetInFaction'; ParamType1: ptFaction),\n    (Index:  72; Name: 'GetIsID'; ParamType1: ptReferencableObject),\n    (Index:  73; Name: 'GetFactionRank'; ParamType1: ptFaction),\n    (Index:  74; Name: 'GetGlobalValue'; ParamType1: ptGlobal),\n    (Index:  75; Name: 'IsSnowing'),\n    (Index:  77; Name: 'GetRandomPercent'),\n    (Index:  79; Name: 'WouldBeStealing'; ParamType1: ptObjectReference),\n    (Index:  80; Name: 'GetLevel'),\n    (Index:  81; Name: 'IsRotating'),\n    (Index:  83; Name: 'GetLeveledEncounterValue'; ParamType1: ptInteger),\n    (Index:  84; Name: 'GetDeadCount'; ParamType1: ptActorBase),\n    (Index:  91; Name: 'GetIsAlerted'),\n    (Index:  99; Name: 'GetHeadingAngle'; ParamType1: ptObjectReference),\n    (Index: 101; Name: 'IsWeaponMagicOut'),\n    (Index: 102; Name: 'IsTorchOut'),\n    (Index: 103; Name: 'IsShieldOut'),\n    (Index: 105; Name: 'IsActionRef'; ParamType1: ptObjectReference),\n    (Index: 106; Name: 'IsFacingUp'),\n    (Index: 107; Name: 'GetKnockedState'),\n    (Index: 108; Name: 'GetWeaponAnimType'),\n    (Index: 109; Name: 'IsWeaponSkillType'; ParamType1: ptActorValue),\n    (Index: 110; Name: 'GetCurrentAIPackage'),\n    (Index: 111; Name: 'IsWaiting'),\n    (Index: 112; Name: 'IsIdlePlaying'),\n    (Index: 116; Name: 'IsIntimidatedbyPlayer'),\n    (Index: 117; Name: 'IsPlayerInRegion'; ParamType1: ptRegion),\n    (Index: 118; Name: 'GetActorAggroRadiusViolated'),\n    (Index: 119; Name: 'GetCrimeKnown'; ParamType1: ptCrimeType; ParamType2: ptActor; ParamType3: ptActor),\n    (Index: 122; Name: 'GetCrime'; ParamType1: ptActor; ParamType2: ptCrimeType),\n    (Index: 123; Name: 'IsGreetingPlayer'),\n    (Index: 125; Name: 'IsGuard'),\n    (Index: 127; Name: 'HasBeenEaten'),\n    (Index: 128; Name: 'GetStaminaPercentage'),\n    (Index: 129; Name: 'HasBeenRead'),\n    (Index: 130; Name: 'GetDying'),\n    (Index: 131; Name: 'GetSceneActionPercent'; ParamType1: ptScene; ParamType2: ptInteger),\n    (Index: 132; Name: 'WouldRefuseCommand'; ParamType1: ptObjectReference),\n    (Index: 133; Name: 'SameFactionAsPC'),\n    (Index: 134; Name: 'SameRaceAsPC'),\n    (Index: 135; Name: 'SameSexAsPC'),\n    (Index: 136; Name: 'GetIsReference'; ParamType1: ptObjectReference),\n    (Index: 141; Name: 'IsTalking'),\n    (Index: 142; Name: 'GetComponentCount'; ParamType1: ptReferencableObject),\n    (Index: 143; Name: 'GetCurrentAIProcedure'),\n    (Index: 144; Name: 'GetTrespassWarningLevel'),\n    (Index: 145; Name: 'IsTrespassing'),\n    (Index: 146; Name: 'IsInMyOwnedCell'),\n    (Index: 147; Name: 'GetWindSpeed'),\n    (Index: 148; Name: 'GetCurrentWeatherPercent'),\n    (Index: 149; Name: 'GetIsCurrentWeather'; ParamType1: ptWeather),\n    (Index: 150; Name: 'IsContinuingPackagePCNear'),\n    (Index: 152; Name: 'GetIsCrimeFaction'; ParamType1: ptFaction),\n    (Index: 153; Name: 'CanHaveFlames'),\n    (Index: 154; Name: 'HasFlames'),\n    (Index: 157; Name: 'GetOpenState'),\n    (Index: 159; Name: 'GetSitting'),\n    (Index: 160; Name: 'GetFurnitureMarkerID'),\n    (Index: 161; Name: 'GetIsCurrentPackage'; ParamType1: ptPackage),\n    (Index: 162; Name: 'IsCurrentFurnitureRef'; ParamType1: ptObjectReference),\n    (Index: 163; Name: 'IsCurrentFurnitureObj'; ParamType1: ptFurniture),\n    (Index: 167; Name: 'GetFactionReaction'; ParamType1: ptFaction; ParamType2: ptFaction),\n    (Index: 170; Name: 'GetDayOfWeek'),\n    (Index: 172; Name: 'GetTalkedToPCParam'; ParamType1: ptActor),\n    (Index: 175; Name: 'IsPCSleeping'),\n    (Index: 176; Name: 'IsPCAMurderer'),\n    (Index: 180; Name: 'HasSameEditorLocationAsRef'; ParamType1: ptObjectReference; ParamType2: ptKeyword),\n    (Index: 181; Name: 'HasSameEditorLocationAsRefAlias'; ParamType1: ptAlias; ParamType2: ptKeyword),\n    (Index: 182; Name: 'GetEquipped'; ParamType1: ptReferencableObject),\n    (Index: 185; Name: 'IsSwimming'),\n    (Index: 186; Name: 'ScriptEffectElapsedSeconds'),\n    (Index: 188; Name: 'GetPCSleepHours'),\n    (Index: 190; Name: 'GetAmountSoldStolen'),\n    (Index: 192; Name: 'GetIgnoreCrime'),\n    (Index: 193; Name: 'GetPCExpelled'; ParamType1: ptFaction),\n    (Index: 195; Name: 'GetPCFactionMurder'; ParamType1: ptFaction),\n    (Index: 197; Name: 'GetPCEnemyofFaction'; ParamType1: ptFaction),\n    (Index: 199; Name: 'GetPCFactionAttack'; ParamType1: ptFaction),\n    (Index: 203; Name: 'GetDestroyed'),\n    (Index: 205; Name: 'GetActionRef'),\n    (Index: 206; Name: 'GetSelf'),\n    (Index: 207; Name: 'GetContainer'),\n    (Index: 208; Name: 'GetForceRun'),\n    (Index: 210; Name: 'GetForceSneak'),\n    (Index: 214; Name: 'HasMagicEffect'; ParamType1: ptMagicEffect),\n    (Index: 215; Name: 'GetDefaultOpen'),\n    (Index: 223; Name: 'IsSpellTarget'; ParamType1: ptMagicItem),\n    (Index: 224; Name: 'GetVATSMode'),\n    (Index: 225; Name: 'GetPersuasionNumber'),\n    (Index: 226; Name: 'GetVampireFeed'),\n    (Index: 227; Name: 'GetCannibal'),\n    (Index: 228; Name: 'GetIsClassDefault'; ParamType1: ptClass),\n    (Index: 229; Name: 'GetClassDefaultMatch'),\n    (Index: 230; Name: 'GetInCellParam'; ParamType1: ptCell; ParamType2: ptObjectReference),\n    (Index: 231; Name: 'GetPlayerDialogueInput'),\n    (Index: 232; Name: 'GetCombatTarget'),\n    (Index: 233; Name: 'GetPackageTarget'),\n    (Index: 235; Name: 'GetVatsTargetHeight'),\n    (Index: 237; Name: 'GetIsGhost'),\n    (Index: 242; Name: 'GetUnconscious'),\n    (Index: 244; Name: 'GetRestrained'),\n    (Index: 246; Name: 'GetIsUsedItem'; ParamType1: ptReferencableObject),\n    (Index: 247; Name: 'GetIsUsedItemType'; ParamType1: ptFormType),\n    (Index: 248; Name: 'IsScenePlaying'; ParamType1: ptScene),\n    (Index: 249; Name: 'IsInDialogueWithPlayer'),\n    (Index: 250; Name: 'GetLocationCleared'; ParamType1: ptLocation),\n    (Index: 254; Name: 'GetIsPlayableRace'),\n    (Index: 255; Name: 'GetOffersServicesNow'),\n    (Index: 256; Name: 'GetGameSetting'; ParamType1: ptNone),\n    (Index: 258; Name: 'HasAssociationType'; ParamType1: ptActor; ParamType2: ptAssociationType),\n    (Index: 259; Name: 'HasFamilyRelationship'; ParamType1: ptActor),\n    (Index: 261; Name: 'HasParentRelationship'; ParamType1: ptActor),\n    (Index: 262; Name: 'IsWarningAbout'; ParamType1: ptFormList),\n    (Index: 263; Name: 'IsWeaponOut'),\n    (Index: 264; Name: 'HasSpell'; ParamType1: ptMagicItem),\n    (Index: 265; Name: 'IsTimePassing'),\n    (Index: 266; Name: 'IsPleasant'),\n    (Index: 267; Name: 'IsCloudy'),\n    (Index: 274; Name: 'IsSmallBump'),\n    (Index: 275; Name: 'GetParentRef'),\n    (Index: 277; Name: 'GetBaseValue'; ParamType1: ptActorValue),\n    (Index: 278; Name: 'IsOwner'; ParamType1: ptOwner),\n    (Index: 280; Name: 'IsCellOwner'; ParamType1: ptCell; ParamType2: ptOwner),\n    (Index: 282; Name: 'IsHorseStolen'),\n    (Index: 285; Name: 'IsLeftUp'),\n    (Index: 286; Name: 'IsSneaking'),\n    (Index: 287; Name: 'IsRunning'),\n    (Index: 288; Name: 'GetFriendHit'),\n    (Index: 289; Name: 'IsInCombat'; ParamType1: ptInteger),\n    (Index: 296; Name: 'IsAnimPlaying'; ParamType1: ptReferencableObject),\n    (Index: 300; Name: 'IsInInterior'),\n    (Index: 303; Name: 'IsActorsAIOff'),\n    (Index: 304; Name: 'IsWaterObject'),\n    (Index: 305; Name: 'GetPlayerAction'),\n    (Index: 306; Name: 'IsActorUsingATorch'),\n    (Index: 309; Name: 'IsXBox'),\n    (Index: 310; Name: 'GetInWorldspace'; ParamType1: ptWorldspace),\n    (Index: 312; Name: 'GetPCMiscStat'; ParamType1: ptMiscStat),\n    (Index: 313; Name: 'GetPairedAnimation'),\n    (Index: 314; Name: 'IsActorAVictim'),\n    (Index: 315; Name: 'GetTotalPersuasionNumber'),\n    (Index: 318; Name: 'GetIdleDoneOnce'),\n    (Index: 320; Name: 'GetNoRumors'),\n    (Index: 323; Name: 'GetCombatState'),\n    (Index: 325; Name: 'GetWithinPackageLocation'; ParamType1: ptPackdata),\n    (Index: 327; Name: 'IsRidingMount'),\n    (Index: 329; Name: 'IsFleeing'),\n    (Index: 332; Name: 'IsInDangerousWater'),\n    (Index: 338; Name: 'GetIgnoreFriendlyHits'),\n    (Index: 339; Name: 'IsPlayersLastRiddenMount'),\n    (Index: 344; Name: 'ReleaseWeatherOverride'),\n    (Index: 348; Name: 'SendTrespassAlarm'; ParamType1: ptActor),\n    (Index: 353; Name: 'IsActor'),\n    (Index: 354; Name: 'IsEssential'),\n    (Index: 358; Name: 'IsPlayerMovingIntoNewSpace'),\n    (Index: 359; Name: 'GetInCurrentLocation'; ParamType1: ptLocation),\n    (Index: 360; Name: 'GetInCurrentLocationAlias'; ParamType1: ptAlias),\n    (Index: 361; Name: 'GetTimeDead'),\n    (Index: 362; Name: 'HasLinkedRef'; ParamType1: ptKeyword),\n    (Index: 363; Name: 'GetLinkedRef'; ParamType1: ptKeyword),\n    (Index: 365; Name: 'IsChild'),\n    (Index: 366; Name: 'GetStolenItemValueNoCrime'; ParamType1: ptFaction),\n    (Index: 367; Name: 'GetLastPlayerAction'),\n    (Index: 368; Name: 'IsPlayerActionActive'; ParamType1: ptInteger),\n    (Index: 370; Name: 'IsTalkingActivatorActor'; ParamType1: ptActor),\n    (Index: 372; Name: 'IsInList'; ParamType1: ptFormList),\n    (Index: 373; Name: 'GetStolenItemValue'; ParamType1: ptFaction),\n    (Index: 375; Name: 'GetCrimeGoldViolent'; ParamType1: ptFaction),\n    (Index: 376; Name: 'GetCrimeGoldNonviolent'; ParamType1: ptFaction),\n    (Index: 378; Name: 'IsOwnedBy'; ParamType1: ptActor),\n    (Index: 380; Name: 'GetCommandDistance'),\n    (Index: 381; Name: 'GetCommandLocationDistance'),\n    (Index: 387; Name: 'GetObjectiveFailed'; ParamType1: ptQuest; ParamType2: ptInteger),\n    (Index: 390; Name: 'GetHitLocation'),\n    (Index: 391; Name: 'IsPC1stPerson'),\n    (Index: 396; Name: 'GetCauseofDeath'),\n    (Index: 397; Name: 'IsLimbGone'; ParamType1: ptInteger),\n    (Index: 398; Name: 'IsWeaponInList'; ParamType1: ptFormList),\n    (Index: 402; Name: 'IsBribedbyPlayer'),\n    (Index: 403; Name: 'GetRelationshipRank'; ParamType1: ptActor),\n    (Index: 407; Name: 'GetVATSValue'; ParamType1: ptInteger; ParamType2: ptInteger),\n    (Index: 408; Name: 'IsKiller'; ParamType1: ptActor),\n    (Index: 409; Name: 'IsKillerObject'; ParamType1: ptFormList),\n    (Index: 410; Name: 'GetFactionCombatReaction'; ParamType1: ptFaction; ParamType2: ptFaction),\n    (Index: 414; Name: 'Exists'; ParamType1: ptObjectReference),\n    (Index: 415; Name: 'GetGroupMemberCount'),\n    (Index: 416; Name: 'GetGroupTargetCount'),\n    (Index: 419; Name: 'GetObjectiveCompleted'; ParamType1: ptQuest; ParamType2: ptInteger),\n    (Index: 420; Name: 'GetObjectiveDisplayed'; ParamType1: ptQuest; ParamType2: ptInteger),\n    (Index: 425; Name: 'GetIsFormType'),\n    (Index: 426; Name: 'GetIsVoiceType'; ParamType1: ptVoiceType),\n    (Index: 427; Name: 'GetPlantedExplosive'),\n    (Index: 429; Name: 'IsScenePackageRunning'),\n    (Index: 430; Name: 'GetHealthPercentage'),\n    (Index: 432; Name: 'GetIsObjectType'; ParamType1: ptFormType),\n    (Index: 437; Name: 'GetIsCreatureType'; ParamType1: ptInteger),\n    (Index: 438; Name: 'HasKey'; ParamType1: ptObjectReference),\n    (Index: 439; Name: 'IsFurnitureEntryType'; ParamType1: ptReferencableObject),\n    (Index: 444; Name: 'GetInCurrentLocationFormList'; ParamType1: ptFormList),\n    (Index: 445; Name: 'GetInZone'; ParamType1: ptEncounterZone),\n    (Index: 446; Name: 'GetVelocity'; ParamType1: ptAxis),\n    (Index: 447; Name: 'GetGraphVariableFloat'),\n    (Index: 448; Name: 'HasPerk'; ParamType1: ptPerk),\n    (Index: 449; Name: 'GetFactionRelation'; ParamType1: ptActor),\n    (Index: 450; Name: 'IsLastIdlePlayed'; ParamType1: ptIdleForm),\n    (Index: 453; Name: 'GetPlayerTeammate'),\n    (Index: 454; Name: 'GetPlayerTeammateCount'),\n    (Index: 458; Name: 'GetActorCrimePlayerEnemy'),\n    (Index: 459; Name: 'GetCrimeGold'; ParamType1: ptFaction),\n    (Index: 462; Name: 'GetPlayerGrabbedRef'),\n    (Index: 463; Name: 'IsPlayerGrabbedRef'; ParamType1: ptObjectReference),\n    (Index: 465; Name: 'GetKeywordItemCount'; ParamType1: ptKeyword),\n    (Index: 467; Name: 'GetBroadcastState'),\n    (Index: 470; Name: 'GetDestructionStage'),\n    (Index: 473; Name: 'GetIsAlignment'; ParamType1: ptAlignment),\n    (Index: 476; Name: 'IsProtected'),\n    (Index: 477; Name: 'GetThreatRatio'; ParamType1: ptActor),\n    (Index: 479; Name: 'GetIsUsedItemEquipType'; ParamType1: ptEquipType),\n    (Index: 480; Name: 'GetPlayerName'),\n    (Index: 483; Name: 'GetPlayerActivated'),\n    (Index: 485; Name: 'GetFullyEnabledActorsInHigh'),\n    (Index: 487; Name: 'IsCarryable'),\n    (Index: 488; Name: 'GetConcussed'),\n    (Index: 489; Name: 'SetZoneRespawns'; ParamType1: ptEncounterZone; ParamType2: ptInteger),\n    (Index: 490; Name: 'SetVATSTarget'; ParamType1: ptInteger),\n    (Index: 491; Name: 'GetMapMarkerVisible'),\n    (Index: 493; Name: 'PlayerKnows'; ParamType1: ptReferencableObject),\n    (Index: 494; Name: 'GetPermanentValue'; ParamType1: ptActorValue),\n    (Index: 495; Name: 'GetKillingBlowLimb'),\n    (Index: 497; Name: 'CanPayCrimeGold'; ParamType1: ptFaction),\n    (Index: 499; Name: 'GetDaysInJail'),\n    (Index: 500; Name: 'EPAlchemyGetMakingPoison'),\n    (Index: 501; Name: 'EPAlchemyEffectHasKeyword'; ParamType1: ptKeyword),\n    (Index: 503; Name: 'GetAllowWorldInteractions'),\n    (Index: 506; Name: 'DialogueGetAv'; ParamType1: ptActorValue),\n    (Index: 507; Name: 'DialogueHasPerk'; ParamType1: ptPerk),\n    (Index: 508; Name: 'GetLastHitCritical'),\n    (Index: 510; Name: 'DialogueGetItemCount'; ParamType1: ptReferencableObject),\n    (Index: 511; Name: 'LastCrippledCondition'; ParamType1: ptActorValue),\n    (Index: 512; Name: 'HasSharedPowerGrid'; ParamType1: ptObjectReference),\n    (Index: 513; Name: 'IsCombatTarget'; ParamType1: ptActor),\n    (Index: 515; Name: 'GetVATSRightAreaFree'; ParamType1: ptObjectReference),\n    (Index: 516; Name: 'GetVATSLeftAreaFree'; ParamType1: ptObjectReference),\n    (Index: 517; Name: 'GetVATSBackAreaFree'; ParamType1: ptObjectReference),\n    (Index: 518; Name: 'GetVATSFrontAreaFree'; ParamType1: ptObjectReference),\n    (Index: 519; Name: 'GetIsLockBroken'),\n    (Index: 520; Name: 'IsPS3'),\n    (Index: 521; Name: 'IsWindowsPC'),\n    (Index: 522; Name: 'GetVATSRightTargetVisible'; ParamType1: ptObjectReference),\n    (Index: 523; Name: 'GetVATSLeftTargetVisible'; ParamType1: ptObjectReference),\n    (Index: 524; Name: 'GetVATSBackTargetVisible'; ParamType1: ptObjectReference),\n    (Index: 525; Name: 'GetVATSFrontTargetVisible'; ParamType1: ptObjectReference),\n    (Index: 528; Name: 'IsInCriticalStage'; ParamType1: ptCriticalStage),\n    (Index: 530; Name: 'GetXPForNextLevel'),\n    (Index: 533; Name: 'GetInfamy'; ParamType1: ptFaction),\n    (Index: 534; Name: 'GetInfamyViolent'; ParamType1: ptFaction),\n    (Index: 535; Name: 'GetInfamyNonViolent'; ParamType1: ptFaction),\n    (Index: 536; Name: 'GetTypeCommandPerforming'),\n    (Index: 543; Name: 'GetQuestCompleted'; ParamType1: ptQuest),\n    (Index: 544; Name: 'GetSpeechChallengeSuccessLevel'),\n    (Index: 545; Name: 'PipBoyRadioOff'),\n    (Index: 547; Name: 'IsGoreDisabled'),\n    (Index: 550; Name: 'IsSceneActionComplete'; ParamType1: ptScene; ParamType2: ptInteger),\n    (Index: 552; Name: 'GetSpellUsageNum'; ParamType1: ptMagicItem),\n    (Index: 554; Name: 'GetActorsInHigh'),\n    (Index: 555; Name: 'HasLoaded3D'),\n    (Index: 559; Name: 'IsImageSpaceActive'; ParamType1: ptReferencableObject),\n    (Index: 560; Name: 'HasKeyword'; ParamType1: ptKeyword),\n    (Index: 561; Name: 'HasRefType'; ParamType1: ptRefType),\n    (Index: 562; Name: 'LocationHasKeyword'; ParamType1: ptKeyword),\n    (Index: 563; Name: 'LocationHasRefType'; ParamType1: ptRefType),\n    (Index: 565; Name: 'GetIsEditorLocation'; ParamType1: ptLocation),\n    (Index: 566; Name: 'GetIsAliasRef'; ParamType1: ptAlias),\n    (Index: 567; Name: 'GetIsEditorLocationAlias'; ParamType1: ptAlias),\n    (Index: 568; Name: 'IsSprinting'),\n    (Index: 569; Name: 'IsBlocking'),\n    (Index: 570; Name: 'HasEquippedSpell'; ParamType1: ptCastingSource),\n    (Index: 571; Name: 'GetCurrentCastingType'; ParamType1: ptCastingSource),\n    (Index: 572; Name: 'GetCurrentDeliveryType'; ParamType1: ptCastingSource),\n    (Index: 574; Name: 'GetAttackState'),\n    (Index: 575; Name: 'GetAliasedRef'; ParamType1: ptAlias),\n    (Index: 576; Name: 'GetEventData'; ParamType1: ptEvent; ParamType2: ptEventData; ParamType3: ptNone),  // fireundubh: Event Function, Event Member, Data (FO4)\n    (Index: 577; Name: 'IsCloserToAThanB'; ParamType1: ptObjectReference; ParamType2: ptObjectReference),\n    (Index: 578; Name: 'LevelMinusPCLevel'),\n    (Index: 580; Name: 'IsBleedingOut'),\n    (Index: 584; Name: 'GetRelativeAngle'; ParamType1: ptObjectReference; ParamType2: ptAxis),\n    (Index: 589; Name: 'GetMovementDirection'),\n    (Index: 590; Name: 'IsInScene'),\n    (Index: 591; Name: 'GetRefTypeDeadCount'; ParamType1: ptLocation; ParamType2: ptRefType),\n    (Index: 592; Name: 'GetRefTypeAliveCount'; ParamType1: ptLocation; ParamType2: ptRefType),\n    (Index: 594; Name: 'GetIsFlying'),\n    (Index: 595; Name: 'IsCurrentSpell'; ParamType1: ptMagicItem; ParamType2: ptCastingSource),\n    (Index: 596; Name: 'SpellHasKeyword'; ParamType1: ptCastingSource; ParamType2: ptKeyword),\n    (Index: 597; Name: 'GetEquippedItemType'; ParamType1: ptCastingSource),\n    (Index: 598; Name: 'GetLocationAliasCleared'; ParamType1: ptAlias),\n    (Index: 600; Name: 'GetLocationAliasRefTypeDeadCount'; ParamType1: ptAlias; ParamType2: ptRefType),\n    (Index: 601; Name: 'GetLocationAliasRefTypeAliveCount'; ParamType1: ptAlias; ParamType2: ptRefType),\n    (Index: 602; Name: 'IsWardState'; ParamType1: ptWardState),\n    (Index: 603; Name: 'IsInSameCurrentLocationAsRef'; ParamType1: ptObjectReference; ParamType2: ptKeyword),\n    (Index: 604; Name: 'IsInSameCurrentLocationAsRefAlias'; ParamType1: ptAlias; ParamType2: ptKeyword),\n    (Index: 605; Name: 'LocationAliasIsLocation'; ParamType1: ptAlias; ParamType2: ptLocation),\n    (Index: 606; Name: 'GetKeywordDataForLocation'; ParamType1: ptLocation; ParamType2: ptKeyword),\n    (Index: 608; Name: 'GetKeywordDataForAlias'; ParamType1: ptAlias; ParamType2: ptKeyword),\n    (Index: 610; Name: 'LocationAliasHasKeyword'; ParamType1: ptAlias; ParamType2: ptKeyword),\n    (Index: 611; Name: 'IsNullPackageData'; ParamType1: ptPackdata),\n    (Index: 612; Name: 'GetNumericPackageData'; ParamType1: ptPackdata),\n    (Index: 613; Name: 'IsPlayerRadioOn'),\n    (Index: 614; Name: 'GetPlayerRadioFrequency'),\n    (Index: 615; Name: 'GetHighestRelationshipRank'),\n    (Index: 616; Name: 'GetLowestRelationshipRank'),\n    (Index: 617; Name: 'HasAssociationTypeAny'; ParamType1: ptAssociationType),\n    (Index: 618; Name: 'HasFamilyRelationshipAny'),\n    (Index: 619; Name: 'GetPathingTargetOffset'; ParamType1: ptAxis),\n    (Index: 620; Name: 'GetPathingTargetAngleOffset'; ParamType1: ptAxis),\n    (Index: 621; Name: 'GetPathingTargetSpeed'),\n    (Index: 622; Name: 'GetPathingTargetSpeedAngle'; ParamType1: ptAxis),\n    (Index: 623; Name: 'GetMovementSpeed'),\n    (Index: 624; Name: 'GetInContainer'; ParamType1: ptObjectReference),\n    (Index: 625; Name: 'IsLocationLoaded'; ParamType1: ptLocation),\n    (Index: 626; Name: 'IsLocationAliasLoaded'; ParamType1: ptAlias),\n    (Index: 627; Name: 'IsDualCasting'),\n    (Index: 629; Name: 'GetVMQuestVariable'; ParamType1: ptQuest; ParamType2: ptNone),\n    (Index: 630; Name: 'GetCombatAudioDetection'),\n    (Index: 631; Name: 'GetCombatVisualDetection'),\n    (Index: 632; Name: 'IsCasting'),\n    (Index: 633; Name: 'GetFlyingState'),\n    (Index: 635; Name: 'IsInFavorState'),\n    (Index: 636; Name: 'HasTwoHandedWeaponEquipped'),\n    (Index: 637; Name: 'IsFurnitureExitType'; ParamType1: ptReferencableObject),\n    (Index: 638; Name: 'IsInFriendStatewithPlayer'),\n    (Index: 639; Name: 'GetWithinDistance'; ParamType1: ptObjectReference; ParamType2: ptFloat),\n    (Index: 640; Name: 'GetValuePercent'; ParamType1: ptActorValue),\n    (Index: 641; Name: 'IsUnique'),\n    (Index: 642; Name: 'GetLastBumpDirection'),\n    (Index: 644; Name: 'GetInfoChallangeSuccess'),\n    (Index: 645; Name: 'GetIsInjured'),\n    (Index: 646; Name: 'GetIsCrashLandRequest'),\n    (Index: 647; Name: 'GetIsHastyLandRequest'),\n    (Index: 650; Name: 'IsLinkedTo'; ParamType1: ptObjectReference; ParamType2: ptKeyword),\n    (Index: 651; Name: 'GetKeywordDataForCurrentLocation'; ParamType1: ptKeyword),\n    (Index: 652; Name: 'GetInSharedCrimeFaction'; ParamType1: ptObjectReference),\n    (Index: 653; Name: 'GetBribeAmount'),\n    (Index: 654; Name: 'GetBribeSuccess'),\n    (Index: 655; Name: 'GetIntimidateSuccess'),\n    (Index: 656; Name: 'GetArrestedState'),\n    (Index: 657; Name: 'GetArrestingActor'),\n    (Index: 659; Name: 'HasVMScript'; ParamType1: ptNone),\n    (Index: 660; Name: 'GetVMScriptVariable'; ParamType1: ptNone; ParamType2: ptNone),\n    (Index: 661; Name: 'GetWorkshopResourceDamage'; ParamType1: ptActorValue),\n    (Index: 664; Name: 'HasValidRumorTopic'; ParamType1: ptQuest),\n    (Index: 672; Name: 'IsAttacking'),\n    (Index: 673; Name: 'IsPowerAttacking'),\n    (Index: 674; Name: 'IsLastHostileActor'),\n    (Index: 675; Name: 'GetGraphVariableInt'; ParamType1: ptNone),\n    (Index: 678; Name: 'ShouldAttackKill'; ParamType1: ptActor),\n    (Index: 680; Name: 'GetActivationHeight'),\n    (Index: 682; Name: 'WornHasKeyword'; ParamType1: ptKeyword),\n    (Index: 683; Name: 'GetPathingCurrentSpeed'),\n    (Index: 684; Name: 'GetPathingCurrentSpeedAngle'; ParamType1: ptAxis),\n    (Index: 691; Name: 'GetWorkshopObjectCount'; ParamType1: ptReferencableObject),\n    (Index: 693; Name: 'EPMagic_SpellHasKeyword'; ParamType1: ptKeyword),\n    (Index: 694; Name: 'GetNoBleedoutRecovery'),\n    (Index: 696; Name: 'EPMagic_SpellHasSkill'; ParamType1: ptActorValue),\n    (Index: 697; Name: 'IsAttackType'; ParamType1: ptKeyword),\n    (Index: 698; Name: 'IsAllowedToFly'),\n    (Index: 699; Name: 'HasMagicEffectKeyword'; ParamType1: ptKeyword),\n    (Index: 700; Name: 'IsCommandedActor'),\n    (Index: 701; Name: 'IsStaggered'),\n    (Index: 702; Name: 'IsRecoiling'),\n    (Index: 703; Name: 'HasScopeWeaponEquipped'),\n    (Index: 704; Name: 'IsPathing'),\n    (Index: 705; Name: 'GetShouldHelp'; ParamType1: ptActor),\n    (Index: 706; Name: 'HasBoundWeaponEquipped'; ParamType1: ptCastingSource),\n    (Index: 707; Name: 'GetCombatTargetHasKeyword'; ParamType1: ptKeyword),\n    (Index: 709; Name: 'GetCombatGroupMemberCount'),\n    (Index: 710; Name: 'IsIgnoringCombat'),\n    (Index: 711; Name: 'GetLightLevel'),\n    (Index: 713; Name: 'SpellHasCastingPerk'; ParamType1: ptPerk),\n    (Index: 714; Name: 'IsBeingRidden'),\n    (Index: 715; Name: 'IsUndead'),\n    (Index: 716; Name: 'GetRealHoursPassed'),\n    (Index: 718; Name: 'IsUnlockedDoor'),\n    (Index: 719; Name: 'IsHostileToActor'; ParamType1: ptActor),\n    (Index: 720; Name: 'GetTargetHeight'; ParamType1: ptObjectReference),\n    (Index: 721; Name: 'IsPoison'),\n    (Index: 722; Name: 'WornApparelHasKeywordCount'; ParamType1: ptKeyword),\n    (Index: 723; Name: 'GetItemHealthPercent'),\n    (Index: 724; Name: 'EffectWasDualCast'),\n    (Index: 725; Name: 'GetKnockStateEnum'),\n    (Index: 726; Name: 'DoesNotExist'),\n    (Index: 728; Name: 'GetPlayerWalkAwayFromDialogueScene'),\n    (Index: 729; Name: 'GetActorStance'),\n    (Index: 734; Name: 'CanProduceForWorkshop'),\n    (Index: 735; Name: 'CanFlyHere'),\n    (Index: 736; Name: 'EPIsDamageType'; ParamType1: ptDamageType),\n    (Index: 738; Name: 'GetActorGunState'),\n    (Index: 739; Name: 'GetVoiceLineLength'),\n    (Index: 741; Name: 'ObjectTemplateItem_HasKeyword'; ParamType1: ptKeyword),\n    (Index: 742; Name: 'ObjectTemplateItem_HasUniqueKeyword'; ParamType1: ptKeyword),\n    (Index: 743; Name: 'ObjectTemplateItem_GetLevel'),\n    (Index: 744; Name: 'MovementIdleMatches'; ParamType1: ptInteger; ParamType2: ptInteger), // TODO: determine correct param types (2)\n    (Index: 745; Name: 'GetActionData'),\n    (Index: 746; Name: 'GetActionDataShort'; ParamType1: ptInteger),\n    (Index: 747; Name: 'GetActionDataByte'; ParamType1: ptInteger),\n    (Index: 748; Name: 'GetActionDataFlag'; ParamType1: ptInteger),\n    (Index: 749; Name: 'ModdedItemHasKeyword'; ParamType1: ptKeyword),\n    (Index: 750; Name: 'GetAngryWithPlayer'),\n    (Index: 751; Name: 'IsCameraUnderWater'),\n    (Index: 753; Name: 'IsActorRefOwner'; ParamType1: ptActor),\n    (Index: 754; Name: 'HasActorRefOwner'; ParamType1: ptActor),\n    (Index: 756; Name: 'GetLoadedAmmoCount'),\n    (Index: 757; Name: 'IsTimeSpanSunrise'),\n    (Index: 758; Name: 'IsTimeSpanMorning'),\n    (Index: 759; Name: 'IsTimeSpanAfternoon'),\n    (Index: 760; Name: 'IsTimeSpanEvening'),\n    (Index: 761; Name: 'IsTimeSpanSunset'),\n    (Index: 762; Name: 'IsTimeSpanNight'),\n    (Index: 763; Name: 'IsTimeSpanMidnight'),\n    (Index: 764; Name: 'IsTimeSpanAnyDay'),\n    (Index: 765; Name: 'IsTimeSpanAnyNight'),\n    (Index: 766; Name: 'CurrentFurnitureHasKeyword'; ParamType1: ptKeyword),\n    (Index: 767; Name: 'GetWeaponEquipIndex'),\n    (Index: 769; Name: 'IsOverEncumbered'),\n    (Index: 770; Name: 'IsPackageRequestingBlockedIdles'),\n    (Index: 771; Name: 'GetActionDataInt'),\n    (Index: 772; Name: 'GetVATSRightMinusLeftAreaFree'; ParamType1: ptObjectReference),\n    (Index: 773; Name: 'GetInIronSights'; ParamType1: ptObjectReference),\n    (Index: 774; Name: 'GetActorStaggerDirection'),\n    (Index: 775; Name: 'GetActorStaggerMagnitude'),\n    (Index: 776; Name: 'WornCoversBipedSlot'; ParamType1: ptInteger),\n    (Index: 777; Name: 'GetInventoryValue'),\n    (Index: 778; Name: 'IsPlayerInConversation'),\n    (Index: 779; Name: 'IsInDialogueCamera'),\n    (Index: 780; Name: 'IsMyDialogueTargetPlayer'),\n    (Index: 781; Name: 'IsMyDialogueTargetActor'),\n    (Index: 782; Name: 'GetMyDialogueTargetDistance'),\n    (Index: 783; Name: 'IsSeatOccupied'; ParamType1: ptKeyword),\n    (Index: 784; Name: 'IsPlayerRiding'),\n    (Index: 785; Name: 'IsTryingEventCamera'),\n    (Index: 786; Name: 'UseLeftSideCamera'),\n    (Index: 787; Name: 'GetNoteType'),\n    (Index: 788; Name: 'LocationHasPlayerOwnedWorkshop'),\n    (Index: 789; Name: 'IsStartingAction'),\n    (Index: 790; Name: 'IsMidAction'),\n    (Index: 791; Name: 'IsWeaponChargeAttack'),\n    (Index: 792; Name: 'IsInWorkshopMode'),\n    (Index: 793; Name: 'IsWeaponChargingHoldAttack'),\n    (Index: 794; Name: 'IsEncounterAbovePlayerLevel'),\n    (Index: 795; Name: 'IsMeleeAttacking'),\n    (Index: 796; Name: 'GetVATSQueuedTargetsUnique'),\n    (Index: 797; Name: 'GetCurrentLocationCleared'),\n    (Index: 798; Name: 'IsPowered'),\n    (Index: 799; Name: 'GetTransmitterDistance'),\n    (Index: 800; Name: 'GetCameraPlaybackTime'),\n    (Index: 801; Name: 'IsInWater'),\n    (Index: 802; Name: 'GetWithinActivateDistance'; ParamType1: ptObjectReference),\n    (Index: 803; Name: 'IsUnderWater'),\n    (Index: 804; Name: 'IsInSameSpace'; ParamType1: ptObjectReference),\n    (Index: 805; Name: 'LocationAllowsReset'),\n    (Index: 806; Name: 'GetVATSBackRightAreaFree'; ParamType1: ptObjectReference),\n    (Index: 807; Name: 'GetVATSBackLeftAreaFree'; ParamType1: ptObjectReference),\n    (Index: 808; Name: 'GetVATSBackRightTargetVisible'; ParamType1: ptObjectReference),\n    (Index: 809; Name: 'GetVATSBackLeftTargetVisible'; ParamType1: ptObjectReference),\n    (Index: 810; Name: 'GetVATSTargetLimbVisible'; ParamType1: ptObjectReference),\n    (Index: 811; Name: 'IsPlayerListening'; ParamType1: ptFloat),\n    (Index: 812; Name: 'GetPathingRequestedQuickTurn'),\n    (Index: 813; Name: 'EPIsCalculatingBaseDamage'),\n    (Index: 814; Name: 'GetReanimating'),\n    (Index: 817; Name: 'IsInRobotWorkbench'),\n\n    // F4SE\n    (Index: 1024; Name: 'GetSKSEVersion'; ),\n    (Index: 1025; Name: 'GetSKSEVersionMinor'; ),\n    (Index: 1026; Name: 'GetSKSEVersionBeta'; ),\n    (Index: 1027; Name: 'GetSKSERelease'; ),\n    (Index: 1028; Name: 'ClearInvalidRegistrations'; )\n  );\nvar\n  wbCTDAFunctionEditInfo: string;\n\nfunction wbCTDAParamDescFromIndex(aIndex: Integer): PCTDAFunction;\nvar\n  L, H, I, C: Integer;\nbegin\n  Result := nil;\n\n  L := Low(wbCTDAFunctions);\n  H := High(wbCTDAFunctions);\n  while L <= H do begin\n    I := (L + H) shr 1;\n    C := CmpW32(wbCTDAFunctions[I].Index, aIndex);\n    if C < 0 then\n      L := I + 1\n    else begin\n      H := I - 1;\n      if C = 0 then begin\n        L := I;\n        Result := @wbCTDAFunctions[L];\n      end;\n    end;\n  end;\nend;\n\nfunction wbCTDACompValueDecider(aBasePtr: Pointer; aEndPtr: Pointer; const aElement: IwbElement): Integer;\nvar\n  Container: IwbContainer;\nbegin\n  Result := 0;\n  if not Assigned(aElement) then Exit;\n  Container := GetContainerFromUnion(aElement);\n  if not Assigned(Container) then Exit;\n\n  // \"use global\" flag\n  if Integer(Container.ElementByName['Type'].NativeValue) and $04 <> 0 then\n    Result := 1;\nend;\n\nfunction wbCTDAParam1Decider(aBasePtr: Pointer; aEndPtr: Pointer; const aElement: IwbElement): Integer;\nvar\n  Desc: PCTDAFunction;\n  Container: IwbContainer;\n  ParamFlag: Byte;\n  ParamType: TCTDAFunctionParamType;\nbegin\n  Result := 0;\n  if not Assigned(aElement) then Exit;\n  Container := GetContainerFromUnion(aElement);\n  if not Assigned(Container) then Exit;\n\n  Desc := wbCTDAParamDescFromIndex(Container.ElementByName['Function'].NativeValue);\n\n  if Assigned(Desc) then begin\n    ParamType := Desc.ParamType1;\n    ParamFlag := Container.ElementByName['Type'].NativeValue;\n    if ParamType in [ptObjectReference, ptActor, ptPackage] then begin\n      if ParamFlag and $02 > 0 then begin\n        // except for this func when Run On = Quest Alias, then alias is param3 and package is param1\n        // [INFO:00020D3C]\n        if not ((Container.ElementByName['Run On'].NativeValue = 5) and (Desc.Name = 'GetIsCurrentPackage')) then\n          ParamType := ptAlias    {>>> 'use aliases' is set <<<}\n      end\n      else if ParamFlag and $08 > 0 then\n        ParamType := ptPackdata;  {>>> 'use packdata' is set <<<}\n    end;\n    Result := Succ(Integer(ParamType));\n  end;\nend;\n\nfunction wbCTDAParam2Decider(aBasePtr: Pointer; aEndPtr: Pointer; const aElement: IwbElement): Integer;\nvar\n  Desc: PCTDAFunction;\n  Container: IwbContainer;\n  ParamFlag: Byte;\n  ParamType: TCTDAFunctionParamType;\nbegin\n  Result := 0;\n  if not Assigned(aElement) then Exit;\n  Container := GetContainerFromUnion(aElement);\n  if not Assigned(Container) then Exit;\n\n  Desc := wbCTDAParamDescFromIndex(Container.ElementByName['Function'].NativeValue);\n\n  if Assigned(Desc) then begin\n    ParamType := Desc.ParamType2;\n    ParamFlag := Container.ElementByName['Type'].NativeValue;\n    if ParamType in [ptObjectReference, ptActor, ptPackage] then begin\n      if ParamFlag and $02 > 0 then ParamType := ptAlias else {>>> 'use aliases' is set <<<}\n      if ParamFlag and $08 > 0 then ParamType := ptPackdata;  {>>> 'use packdata' is set <<<}\n    end;\n    Result := Succ(Integer(ParamType));\n  end;\nend;\n\nfunction wbCTDAParam2VATSValueParamDecider(aBasePtr: Pointer; aEndPtr: Pointer; const aElement: IwbElement): Integer;\nvar\n  Container : IwbContainer;\nbegin\n  Result := 0;\n  if not Assigned(aElement) then Exit;\n  Container := GetContainerFromUnion(aElement);\n  if not Assigned(Container) then Exit;\n\n  Result := Container.ElementByName['Parameter #1'].NativeValue;\nend;\n\nfunction wbCTDAFunctionToStr(aInt: Int64; const aElement: IwbElement; aType: TwbCallbackType): string;\nvar\n  Desc : PCTDAFunction;\n  i    : Integer;\nbegin\n  Result := '';\n  case aType of\n    ctToStr, ctToEditValue: begin\n      Desc := wbCTDAParamDescFromIndex(aInt);\n      if Assigned(Desc) then\n        Result := Desc.Name\n      else if aType = ctToEditValue then\n        Result := IntToStr(aInt)\n      else\n        Result := '<Unknown: '+IntToStr(aInt)+'>';\n    end;\n    ctToSortKey: Result := IntToHex(aInt, 8);\n    ctCheck: begin\n      Desc := wbCTDAParamDescFromIndex(aInt);\n      if Assigned(Desc) then\n        Result := ''\n      else\n        Result := '<Unknown: '+IntToStr(aInt)+'>';\n    end;\n    ctEditType:\n      Result := 'ComboBox';\n    ctEditInfo: begin\n      Result := wbCTDAFunctionEditInfo;\n      if Result = '' then begin\n        with TStringList.Create do try\n          for i := Low(wbCTDAFunctions) to High(wbCTDAFunctions) do\n            Add(wbCTDAFunctions[i].Name);\n          Sort;\n          Result := CommaText;\n        finally\n          Free;\n        end;\n        wbCTDAFunctionEditInfo := Result;\n      end;\n    end;\n  end;\nend;\n\nfunction wbCTDAFunctionToInt(const aString: string; const aElement: IwbElement): Int64;\nvar\n  i: Integer;\nbegin\n  for i := Low(wbCTDAFunctions) to High(wbCTDAFunctions) do\n    with wbCTDAFunctions[i] do\n      if SameText(Name, aString) then begin\n        Result := Index;\n        Exit;\n      end;\n  Result := StrToInt64(aString);\nend;\n\nfunction wbNeverShow(const aElement: IwbElement): Boolean;\nbegin\n  Result := wbHideNeverShow;\nend;\n\nfunction GetREGNType(aElement: IwbElement): Integer;\nvar\n  Container: IwbContainerElementRef;\nbegin\n  Result := -1;\n  if not Assigned(aElement) then\n    Exit;\n  while aElement.Name <> 'Region Data Entry' do begin\n    aElement := aElement.Container;\n    if not Assigned(aElement) then\n      Exit;\n  end;\n  if not Supports(aElement, IwbContainerElementRef, Container) then\n    Exit;\n  Result := Container.ElementNativeValues['RDAT\\Type'];\nend;\n\nfunction wbREGNObjectsDontShow(const aElement: IwbElement): Boolean;\nbegin\n  Result := GetREGNType(aElement) <> 2;\nend;\n\nfunction wbREGNWeatherDontShow(const aElement: IwbElement): Boolean;\nbegin\n  Result := GetREGNType(aElement) <> 3;\nend;\n\nfunction wbREGNMapDontShow(const aElement: IwbElement): Boolean;\nbegin\n  Result := GetREGNType(aElement) <> 4;\nend;\n\nfunction wbREGNLandDontShow(const aElement: IwbElement): Boolean;\nbegin\n  Result := GetREGNType(aElement) <> 5;\nend;\n\nfunction wbREGNGrassDontShow(const aElement: IwbElement): Boolean;\nbegin\n  Result := GetREGNType(aElement) <> 6;\nend;\n\nfunction wbREGNSoundDontShow(const aElement: IwbElement): Boolean;\nbegin\n  Result := GetREGNType(aElement) <> 7;\nend;\n\nfunction wbREGNImposterDontShow(const aElement: IwbElement): Boolean;\nbegin\n  Result := GetREGNType(aElement) <> 8;\nend;\n\nfunction wbMESGTNAMDontShow(const aElement: IwbElement): Boolean;\nvar\n  Container  : IwbContainerElementRef;\n  MainRecord : IwbMainRecord;\nbegin\n  Result := False;\n  if not Supports(aElement, IwbMainRecord, MainRecord) then\n    Exit;\n  if not Supports(aElement, IwbContainerElementRef, Container) then\n    Exit;\n  if Integer(Container.ElementNativeValues['DNAM']) and 1 <> 0 then\n    Result := True;\nend;\n\nfunction wbEPFDDontShow(const aElement: IwbElement): Boolean;\nvar\n  Container: IwbContainerElementRef;\nbegin\n  Result := False;\n  if aElement.Name <> 'Entry Point Function Parameters' then\n    Exit;\n  if not Supports(aElement, IwbContainerElementRef, Container) then\n    Exit;\n  if not (Integer(Container.ElementNativeValues['EPFT']) in [1..3]) then\n    Result := True;\nend;\n\nfunction wbTES4ONAMDontShow(const aElement: IwbElement): Boolean;\nvar\n  MainRecord : IwbMainRecord;\nbegin\n  Result := False;\n  if not Assigned(aElement) then\n    Exit;\n  MainRecord := aElement.ContainingMainRecord;\n  if not Assigned(MainRecord) then\n    Exit;\n  if not MainRecord.IsESM then\n    Result := True;\nend;\n\nfunction wbEPF2DontShow(const aElement: IwbElement): Boolean;\nvar\n  Container: IwbContainerElementRef;\nbegin\n  Result := False;\n  if aElement.Name <> 'Entry Point Function Parameters' then\n    Exit;\n  if not Supports(aElement, IwbContainerElementRef, Container) then\n    Exit;\n  if not (Integer(Container.ElementNativeValues['EPFT']) in [4]) then\n    Result := True;\nend;\n\nprocedure wbRemoveOFST(const aElement: IwbElement);\nvar\n  Container: IwbContainer;\n  rOFST: IwbRecord;\nbegin\n  if not wbRemoveOffsetData then\n    Exit;\n\n  if Supports(aElement, IwbContainer, Container) then begin\n    if wbBeginInternalEdit then try\n      Container.RemoveElement(OFST);\n    finally\n      wbEndInternalEdit;\n    end else begin\n      rOFST := Container.RecordBySignature[OFST];\n      if Assigned(rOFST) then\n        Container.RemoveElement(rOFST);\n    end;\n  end;\nend;\n\nprocedure wbWRLDAfterLoad(const aElement: IwbElement);\n  function OutOfRange(aValue: Integer; aRange: Integer = 256): Boolean;\n  begin\n    Result := (aValue < -aRange) or (aValue > aRange);\n  end;\nvar\n  MainRecord: IwbMainRecord;\n  Container: IwbContainer;\nbegin\n  wbRemoveOFST(aElement);\n\n  if wbBeginInternalEdit then try\n\n    if not Supports(aElement, IwbMainRecord, MainRecord) then\n      Exit;\n\n    if MainRecord.ElementExists['Unused RNAM'] then\n      MainRecord.RemoveElement('Unused RNAM');\n\n    //if MainRecord.ElementExists['World Default Level Data'] then\n    //  MainRecord.RemoveElement('World Default Level Data');\n\n    //if MainRecord.ElementExists['MHDT'] then\n    //  MainRecord.RemoveElement('MHDT');\n\n    if MainRecord.ElementExists['CLSZ'] then\n      MainRecord.RemoveElement('CLSZ');\n\n    // large values in object bounds cause stutter and performance issues in game (reported by Arthmoor)\n    // CK can occasionally set them wrong, so make a warning\n    if Supports(MainRecord.ElementByName['Object Bounds'], IwbContainer, Container) then\n      if OutOfRange(StrToIntDef(Container.ElementEditValues['NAM0\\X'], 0)) or\n         OutOfRange(StrToIntDef(Container.ElementEditValues['NAM0\\Y'], 0)) or\n         OutOfRange(StrToIntDef(Container.ElementEditValues['NAM9\\X'], 0)) or\n         OutOfRange(StrToIntDef(Container.ElementEditValues['NAM9\\Y'], 0))\n      then\n        wbProgressCallback('<Warning: Object Bounds in ' + MainRecord.Name + ' are abnormally large and can cause performance issues in game>');\n\n  finally\n    wbEndInternalEdit;\n  end;\nend;\n\nprocedure wbDOBJObjectsAfterLoad(const aElement: IwbElement);\nvar\n  ObjectsContainer : IwbContainerElementRef;\n  i                : Integer;\n  ObjectContainer  : IwbContainerElementRef;\nbegin\n  wbRemoveOFST(aElement);\n\n  if wbBeginInternalEdit then try\n\n    if not Supports(aElement, IwbContainerElementRef, ObjectsContainer) then\n      Exit;\n\n    for i := Pred(ObjectsContainer.ElementCount) downto 0 do\n      if Supports(ObjectsContainer.Elements[i], IwbContainerElementRef, ObjectContainer) then\n        if ObjectContainer.ElementNativeValues['Use'] = 0 then\n          ObjectsContainer.RemoveElement(i, True);\n  finally\n    wbEndInternalEdit;\n  end;\nend;\n\nfunction wbActorTemplateUseTraits(const aElement: IwbElement): Boolean;\nvar\n  Element    : IwbElement;\n  MainRecord : IwbMainRecord;\n  i          : Int64;\nbegin\n  Result := False;\n  Element := aElement;\n  MainRecord := nil;\n  while Assigned(Element) and not Supports(Element, IwbMainRecord, MainRecord) do\n    Element := Element.Container;\n  if Assigned(MainRecord) then begin\n    i := MainRecord.ElementNativeValues['ACBS\\Template Flags'];\n    Result := (i and $00000001) <> 0;\n  end;\nend;\n\nfunction wbActorTemplateUseStats(const aElement: IwbElement): Boolean;\nvar\n  Element    : IwbElement;\n  MainRecord : IwbMainRecord;\n  i          : Int64;\nbegin\n  Result := False;\n  Element := aElement;\n  MainRecord := nil;\n  while Assigned(Element) and not Supports(Element, IwbMainRecord, MainRecord) do\n    Element := Element.Container;\n  if Assigned(MainRecord) then begin\n    i := MainRecord.ElementNativeValues['ACBS\\Template Flags'];\n    Result := (i and $00000002) <> 0;\n  end;\nend;\n\nfunction wbActorAutoCalcDontShow(const aElement: IwbElement): Boolean;\nvar\n  Element    : IwbElement;\n  MainRecord : IwbMainRecord;\n  i          : Int64;\nbegin\n  Result := False;\n  Element := aElement;\n  MainRecord := nil;\n  while Assigned(Element) and not Supports(Element, IwbMainRecord, MainRecord) do\n    Element := Element.Container;\n  if Assigned(MainRecord) then begin\n    i := MainRecord.ElementNativeValues['ACBS\\Flags'];\n    Result := (i and $00000010) <> 0;\n  end;\nend;\n\nfunction wbActorTemplateUseStatsAutoCalc(const aElement: IwbElement): Boolean;\nbegin\n  Result := wbActorTemplateUseStats(aElement) or wbActorAutoCalcDontShow(aElement);\nend;\n\nfunction wbActorTemplateUseFactions(const aElement: IwbElement): Boolean;\nvar\n  Element    : IwbElement;\n  MainRecord : IwbMainRecord;\n  i          : Int64;\nbegin\n  Result := False;\n  Element := aElement;\n  MainRecord := nil;\n  while Assigned(Element) and not Supports(Element, IwbMainRecord, MainRecord) do\n    Element := Element.Container;\n  if Assigned(MainRecord) then begin\n    i := MainRecord.ElementNativeValues['ACBS\\Template Flags'];\n    Result := (i and $00000004) <> 0;\n  end;\nend;\n\nfunction wbActorTemplateUseActorEffectList(const aElement: IwbElement): Boolean;\nvar\n  Element    : IwbElement;\n  MainRecord : IwbMainRecord;\n  i          : Int64;\nbegin\n  Result := False;\n  Element := aElement;\n  MainRecord := nil;\n  while Assigned(Element) and not Supports(Element, IwbMainRecord, MainRecord) do\n    Element := Element.Container;\n  if Assigned(MainRecord) then begin\n    i := MainRecord.ElementNativeValues['ACBS\\Template Flags'];\n    Result := (i and $00000008) <> 0;\n  end;\nend;\n\nfunction wbActorTemplateUseAIData(const aElement: IwbElement): Boolean;\nvar\n  Element    : IwbElement;\n  MainRecord : IwbMainRecord;\n  i          : Int64;\nbegin\n  Result := False;\n  Element := aElement;\n  MainRecord := nil;\n  while Assigned(Element) and not Supports(Element, IwbMainRecord, MainRecord) do\n    Element := Element.Container;\n  if Assigned(MainRecord) then begin\n    i := MainRecord.ElementNativeValues['ACBS\\Template Flags'];\n    Result := (i and $00000010) <> 0;\n  end;\nend;\n\nfunction wbActorTemplateUseAIPackages(const aElement: IwbElement): Boolean;\nvar\n  Element    : IwbElement;\n  MainRecord : IwbMainRecord;\n  i          : Int64;\nbegin\n  Result := False;\n  Element := aElement;\n  MainRecord := nil;\n  while Assigned(Element) and not Supports(Element, IwbMainRecord, MainRecord) do\n    Element := Element.Container;\n  if Assigned(MainRecord) then begin\n    i := MainRecord.ElementNativeValues['ACBS\\Template Flags'];\n    Result := (i and $00000020) <> 0;\n  end;\nend;\n\nfunction wbActorTemplateUseModelAnimation(const aElement: IwbElement): Boolean;\nvar\n  Element    : IwbElement;\n  MainRecord : IwbMainRecord;\n  i          : Int64;\nbegin\n  Result := False;\n  Element := aElement;\n  MainRecord := nil;\n  while Assigned(Element) and not Supports(Element, IwbMainRecord, MainRecord) do\n    Element := Element.Container;\n  if Assigned(MainRecord) then begin\n    i := MainRecord.ElementNativeValues['ACBS\\Template Flags'];\n    Result := (i and $00000040) <> 0;\n  end;\nend;\n\nfunction wbActorTemplateUseBaseData(const aElement: IwbElement): Boolean;\nvar\n  Element    : IwbElement;\n  MainRecord : IwbMainRecord;\n  i          : Int64;\nbegin\n  Result := False;\n  Element := aElement;\n  MainRecord := nil;\n  while Assigned(Element) and not Supports(Element, IwbMainRecord, MainRecord) do\n    Element := Element.Container;\n  if Assigned(MainRecord) then begin\n    i := MainRecord.ElementNativeValues['ACBS\\Template Flags'];\n    Result := (i and $00000080) <> 0;\n  end;\nend;\n\nfunction wbActorTemplateUseInventory(const aElement: IwbElement): Boolean;\nvar\n  Element    : IwbElement;\n  MainRecord : IwbMainRecord;\n  i          : Int64;\nbegin\n  Result := False;\n  Element := aElement;\n  MainRecord := nil;\n  while Assigned(Element) and not Supports(Element, IwbMainRecord, MainRecord) do\n    Element := Element.Container;\n  if Assigned(MainRecord) then begin\n    i := MainRecord.ElementNativeValues['ACBS\\Template Flags'];\n    Result := (i and $00000100) <> 0;\n  end;\nend;\n\nfunction wbActorTemplateUseScript(const aElement: IwbElement): Boolean;\nvar\n  Element    : IwbElement;\n  MainRecord : IwbMainRecord;\n  i          : Int64;\nbegin\n  Result := False;\n  Element := aElement;\n  MainRecord := nil;\n  while Assigned(Element) and not Supports(Element, IwbMainRecord, MainRecord) do\n    Element := Element.Container;\n  if Assigned(MainRecord) then begin\n    i := MainRecord.ElementNativeValues['ACBS\\Template Flags'];\n    Result := (i and $00000200) <> 0;\n  end;\nend;\n\nfunction wbActorTemplatesUseTemplate0(const aElement: IwbElement): Boolean;\nvar\n  MainRecord : IwbMainRecord;\nbegin\n  MainRecord := aElement.ContainingMainRecord;\n  if Assigned(MainRecord) then\n    Result := (Cardinal(MainRecord.ElementNativeValues['ACBS\\Use Template Actors']) shr 0 and 1) = 0\n  else\n    Result := False;\nend;\n\nfunction wbActorTemplatesUseTemplate1(const aElement: IwbElement): Boolean;\nvar\n  MainRecord : IwbMainRecord;\nbegin\n  MainRecord := aElement.ContainingMainRecord;\n  if Assigned(MainRecord) then\n    Result := (Cardinal(MainRecord.ElementNativeValues['ACBS\\Use Template Actors']) shr 1 and 1) = 0\n  else\n    Result := False;\nend;\n\nfunction wbActorTemplatesUseTemplate2(const aElement: IwbElement): Boolean;\nvar\n  MainRecord : IwbMainRecord;\nbegin\n  MainRecord := aElement.ContainingMainRecord;\n  if Assigned(MainRecord) then\n    Result := (Cardinal(MainRecord.ElementNativeValues['ACBS\\Use Template Actors']) shr 2 and 1) = 0\n  else\n    Result := False;\nend;\n\nfunction wbActorTemplatesUseTemplate3(const aElement: IwbElement): Boolean;\nvar\n  MainRecord : IwbMainRecord;\nbegin\n  MainRecord := aElement.ContainingMainRecord;\n  if Assigned(MainRecord) then\n    Result := (Cardinal(MainRecord.ElementNativeValues['ACBS\\Use Template Actors']) shr 3 and 1) = 0\n  else\n    Result := False;\nend;\n\nfunction wbActorTemplatesUseTemplate4(const aElement: IwbElement): Boolean;\nvar\n  MainRecord : IwbMainRecord;\nbegin\n  MainRecord := aElement.ContainingMainRecord;\n  if Assigned(MainRecord) then\n    Result := (Cardinal(MainRecord.ElementNativeValues['ACBS\\Use Template Actors']) shr 4 and 1) = 0\n  else\n    Result := False;\nend;\n\nfunction wbActorTemplatesUseTemplate5(const aElement: IwbElement): Boolean;\nvar\n  MainRecord : IwbMainRecord;\nbegin\n  MainRecord := aElement.ContainingMainRecord;\n  if Assigned(MainRecord) then\n    Result := (Cardinal(MainRecord.ElementNativeValues['ACBS\\Use Template Actors']) shr 5 and 1) = 0\n  else\n    Result := False;\nend;\n\nfunction wbActorTemplatesUseTemplate6(const aElement: IwbElement): Boolean;\nvar\n  MainRecord : IwbMainRecord;\nbegin\n  MainRecord := aElement.ContainingMainRecord;\n  if Assigned(MainRecord) then\n    Result := (Cardinal(MainRecord.ElementNativeValues['ACBS\\Use Template Actors']) shr 6 and 1) = 0\n  else\n    Result := False;\nend;\n\nfunction wbActorTemplatesUseTemplate7(const aElement: IwbElement): Boolean;\nvar\n  MainRecord : IwbMainRecord;\nbegin\n  MainRecord := aElement.ContainingMainRecord;\n  if Assigned(MainRecord) then\n    Result := (Cardinal(MainRecord.ElementNativeValues['ACBS\\Use Template Actors']) shr 7 and 1) = 0\n  else\n    Result := False;\nend;\n\nfunction wbActorTemplatesUseTemplate8(const aElement: IwbElement): Boolean;\nvar\n  MainRecord : IwbMainRecord;\nbegin\n  MainRecord := aElement.ContainingMainRecord;\n  if Assigned(MainRecord) then\n    Result := (Cardinal(MainRecord.ElementNativeValues['ACBS\\Use Template Actors']) shr 8 and 1) = 0\n  else\n    Result := False;\nend;\n\nfunction wbActorTemplatesUseTemplate9(const aElement: IwbElement): Boolean;\nvar\n  MainRecord : IwbMainRecord;\nbegin\n  MainRecord := aElement.ContainingMainRecord;\n  if Assigned(MainRecord) then\n    Result := (Cardinal(MainRecord.ElementNativeValues['ACBS\\Use Template Actors']) shr 9 and 1) = 0\n  else\n    Result := False;\nend;\n\nfunction wbActorTemplatesUseTemplate10(const aElement: IwbElement): Boolean;\nvar\n  MainRecord : IwbMainRecord;\nbegin\n  MainRecord := aElement.ContainingMainRecord;\n  if Assigned(MainRecord) then\n    Result := (Cardinal(MainRecord.ElementNativeValues['ACBS\\Use Template Actors']) shr 10 and 1) = 0\n  else\n    Result := False;\nend;\n\nfunction wbActorTemplatesUseTemplate11(const aElement: IwbElement): Boolean;\nvar\n  MainRecord : IwbMainRecord;\nbegin\n  MainRecord := aElement.ContainingMainRecord;\n  if Assigned(MainRecord) then\n    Result := (Cardinal(MainRecord.ElementNativeValues['ACBS\\Use Template Actors']) shr 11 and 1) = 0\n  else\n    Result := False;\nend;\n\nfunction wbActorTemplatesUseTemplate12(const aElement: IwbElement): Boolean;\nvar\n  MainRecord : IwbMainRecord;\nbegin\n  MainRecord := aElement.ContainingMainRecord;\n  if Assigned(MainRecord) then\n    Result := (Cardinal(MainRecord.ElementNativeValues['ACBS\\Use Template Actors']) shr 12 and 1) = 0\n  else\n    Result := False;\nend;\n\nprocedure wbRemoveEmptyKWDA(const aElement: IwbElement);\nvar\n  Container  : IwbContainerElementRef;\n  MainRecord : IwbMainRecord;\nbegin\n  if wbBeginInternalEdit then try\n    if not Supports(aElement, IwbContainerElementRef, Container) then\n      Exit;\n\n    if Container.ElementCount < 1 then\n      Exit;\n\n    if not Supports(aElement, IwbMainRecord, MainRecord) then\n      Exit;\n\n    if MainRecord.IsDeleted then\n      Exit;\n\n    if not Assigned(Container.ElementBySignature['KSIZ']) then\n      if Assigned(Container.ElementBySignature['KWDA']) then\n        Container.ElementBySignature['KWDA'].Remove;\n\n  finally\n    wbEndInternalEdit;\n  end;\nend;\n\nprocedure wbReplaceBODTwithBOD2(const aElement: IwbElement);\nvar\n  MainRecord    : IwbMainRecord;\n  ContainerBOD2 : IwbContainerElementRef;\n  ContainerBODT : IwbContainerElementRef;\nbegin\n  Exit; {>>> Looks like causes problems with Dawnguard.esm <<<}\n\n  if wbBeginInternalEdit then try\n    if not Supports(aElement, IwbMainRecord, MainRecord) then\n      Exit;\n\n    if not Supports(MainRecord.ElementBySignature[BODT], IwbContainerElementRef, ContainerBODT) then\n      Exit;\n\n    if Supports(MainRecord.Add('BOD2', True), IwbContainerElementRef, ContainerBOD2) then begin\n       ContainerBOD2.ElementNativeValues['First Person Flags'] := ContainerBODT.ElementNativeValues['First Person Flags'];\n       ContainerBOD2.ElementNativeValues['Armor Type'] := ContainerBODT.ElementNativeValues['Armor Type'];\n       MainRecord.RemoveElement(BODT);\n    end;\n\n  finally\n    wbEndInternalEdit;\n  end;\nend;\n\nprocedure wbARMOAfterLoad(const aElement: IwbElement);\nbegin\n  wbRemoveEmptyKWDA(aElement);\n  wbReplaceBODTwithBOD2(aElement);\nend;\n\nprocedure wbARMAAfterLoad(const aElement: IwbElement);\n{var\n  MainRecord    : IwbMainRecord;}\nbegin\n  wbReplaceBODTwithBOD2(aElement);\n  {if wbBeginInternalEdit then try\n    if not Supports(aElement, IwbMainRecord, MainRecord) then\n      Exit;\n    if MainRecord.ElementNativeValues['DNAM\\Weight slider - Male'] = 0 then\n      MainRecord.ElementNativeValues['DNAM\\Weight slider - Male'] := 2;\n    if MainRecord.ElementNativeValues['DNAM\\Weight slider - Female'] = 0 then\n      MainRecord.ElementNativeValues['DNAM\\Weight slider - Female'] := 2;\n  finally\n    wbEndInternalEdit;\n  end;}\nend;\n\nprocedure wbNPCAfterLoad(const aElement: IwbElement);\nbegin\n  wbRemoveEmptyKWDA(aElement);\nend;\n\nprocedure wbREFRAfterLoad(const aElement: IwbElement);\nvar\n  Container  : IwbContainerElementRef;\n  MainRecord : IwbMainRecord;\nbegin\n  if wbBeginInternalEdit then try\n    if not Supports(aElement, IwbContainerElementRef, Container) then\n      Exit;\n\n    if Container.ElementCount < 1 then\n      Exit;\n\n    if not Supports(aElement, IwbMainRecord, MainRecord) then\n      Exit;\n\n    if MainRecord.IsDeleted then\n      Exit;\n\n    if Container.ElementExists['XLOC'] then begin\n      if Container.ElementNativeValues['XLOC - Lock Data\\Level'] = 0 then\n        Container.ElementNativeValues['XLOC - Lock Data\\Level'] := 1;\n    end;\n\n    Container.RemoveElement('XPTL');\n  finally\n    wbEndInternalEdit;\n  end;\nend;\n\nprocedure wbWEAPAfterLoad(const aElement: IwbElement);\nvar\n  Container  : IwbContainerElementRef;\n  MainRecord : IwbMainRecord;\n  Flags      : Cardinal;\nbegin\n  wbRemoveEmptyKWDA(aElement);\n\n  if wbBeginInternalEdit then try\n    if not Supports(aElement, IwbContainerElementRef, Container) then\n      Exit;\n\n    if Container.ElementCount < 1 then\n      Exit;\n\n    if not Supports(aElement, IwbMainRecord, MainRecord) then\n      Exit;\n\n    if MainRecord.IsDeleted then\n      Exit;\n\n    // clear IronSights flags which are randomly assigned in CK\n    if Container.ElementExists['DNAM'] then begin\n      Flags := Container.ElementNativeValues['DNAM - Data\\Flags'];\n      Flags := Flags and ($FFFF xor $0040);\n      Container.ElementNativeValues['DNAM - Data\\Flags'] := Flags;\n      Flags := Container.ElementNativeValues['DNAM - Data\\Flags2'];\n      Flags := Flags and ($FFFFFFFF xor $0100);\n      Container.ElementNativeValues['DNAM - Data\\Flags2'] := Flags;\n    end;\n\n  finally\n    wbEndInternalEdit;\n  end;\nend;\n\nprocedure wbCELLXCLWGetConflictPriority(const aElement: IwbElement; var aCP: TwbConflictPriority);\nvar\n  Container  : IwbContainerElementRef;\n  MainRecord : IwbMainRecord;\n  DataRec    : IwbElement;\n  Flags      : Cardinal;\nbegin\n  if not Assigned(aElement) then\n    Exit;\n\n  if not Supports(aElement.Container, IwbContainerElementRef, Container) then\n    Exit;\n\n  if Container.ElementCount < 1 then\n    Exit;\n\n  if not Supports(Container, IwbMainRecord, MainRecord) then\n    Exit;\n\n  if MainRecord.IsDeleted then\n    Exit;\n\n  DataRec := MainRecord.ElementBySignature[DATA];\n\n  if not Assigned(DataRec) then\n    Exit;\n\n  Flags := DataRec.NativeValue;\n\n  {0x0001 Is Interior Cell}\n  if (Flags and 1) = 1 then\n    {Interior cells don't use water level in Skyrim at all}\n    aCP := cpIgnore;\nend;\n\nprocedure wbCELLDATAAfterSet(const aElement: IwbElement; const aOldValue, aNewValue: Variant);\nvar\n  Container : IwbContainer;\nbegin\n  if not Assigned(aElement) then\n    Exit;\n  Container := aElement.Container;\n  while Assigned(Container) and not (Container.Def.DefType = dtRecord) do\n    Container := Container.Container;\n  if Assigned(Container) then\n    Container.ResetConflict;\nend;\n\nprocedure wbCELLAfterLoad(const aElement: IwbElement);\nvar\n  Container    : IwbContainerElementRef;\n//  Container2   : IwbContainerElementRef;\n  MainRecord   : IwbMainRecord;\n  DataSubRec   : IwbSubrecord;\n  Flags        : Byte;\nbegin\n  if wbBeginInternalEdit then try\n    if not Supports(aElement, IwbContainerElementRef, Container) then\n      Exit;\n\n    if Container.ElementCount < 1 then\n      Exit;\n\n    if not Supports(aElement, IwbMainRecord, MainRecord) then\n      Exit;\n\n    if MainRecord.IsDeleted then\n      Exit;\n\n    if Supports(Container.ElementBySignature['DATA'] , IwbSubRecord, DataSubRec) then begin\n      // expand itU8 flags to itU16\n      if DataSubRec.SubRecordHeaderSize = 1 then begin\n        Flags := PByte(DataSubRec.DataBasePtr)^;\n        DataSubRec.SetToDefault;\n        DataSubRec.NativeValue := Flags;\n      end;\n      // 'Default' water height for exterior cells if not set (so water height will be taken from WRLD by game)\n      if (not Container.ElementExists['XCLW']) and ((Integer(DataSubRec.NativeValue) and $02) <> 0) then begin\n        Container.Add('XCLW', True);\n        Container.ElementEditValues['XCLW'] := 'Default';\n      end;\n    end;\n\n    // Min (-0 as in CK) water height is set to 0 when saving in CK\n    if Container.ElementEditValues['XCLW'] = 'Min' then\n      Container.ElementEditValues['XCLW'] := '0.0';\n\n//    if Supports(Container.ElementBySignature[XCLR], IwbContainerElementRef, Container2) then begin\n//      for i := Pred(Container2.ElementCount) downto 0 do\n//        if not Supports(Container2.Elements[i].LinksTo, IwbMainRecord, MainRecord) or (MainRecord.Signature <> 'REGN') then\n//          Container2.RemoveElement(i);\n//      if Container2.ElementCount < 1 then\n//        Container2.Remove;\n//    end;\n  finally\n    wbEndInternalEdit;\n  end;\nend;\n\nprocedure wbMESGAfterLoad(const aElement: IwbElement);\nvar\n  Container    : IwbContainerElementRef;\n  MainRecord   : IwbMainRecord;\n  IsMessageBox : Boolean;\n  HasTimeDelay : Boolean;\nbegin\n  if wbBeginInternalEdit then try\n    if not Supports(aElement, IwbContainerElementRef, Container) then\n      Exit;\n\n    if Container.ElementCount < 1 then\n      Exit;\n\n    if not Supports(aElement, IwbMainRecord, MainRecord) then\n      Exit;\n\n    if MainRecord.IsDeleted then\n      Exit;\n\n    IsMessageBox := (Integer(Container.ElementNativeValues['DNAM']) and 1) = 1;\n    HasTimeDelay := Container.ElementExists['TNAM'];\n\n    if IsMessageBox = HasTimeDelay then\n      if IsMessageBox then\n        Container.RemoveElement('TNAM')\n      else begin\n        if not Container.ElementExists['DNAM'] then\n          Container.Add('DNAM', True);\n        Container.ElementNativeValues['DNAM'] := Integer(Container.ElementNativeValues['DNAM']) or 1;\n      end;\n\n  finally\n    wbEndInternalEdit;\n  end;\nend;\n\nprocedure wbLIGHAfterLoad(const aElement: IwbElement);\nvar\n  Container: IwbContainerElementRef;\n  MainRecord   : IwbMainRecord;\nbegin\n  if wbBeginInternalEdit then try\n    if not Supports(aElement, IwbContainerElementRef, Container) then\n      Exit;\n\n    if Container.ElementCount < 1 then\n      Exit;\n\n    if not Supports(aElement, IwbMainRecord, MainRecord) then\n      Exit;\n\n    if MainRecord.IsDeleted then\n      Exit;\n\n    if not Container.ElementExists['FNAM'] then begin\n      Container.Add('FNAM', True);\n      Container.ElementNativeValues['FNAM'] := 1.0;\n    end;\n\n    if Container.ElementExists['DATA'] then begin\n      if SameValue(Container.ElementNativeValues['DATA\\Falloff Exponent'], 0.0) then\n        Container.ElementNativeValues['DATA\\Falloff Exponent'] := 1.0;\n      if SameValue(Container.ElementNativeValues['DATA\\FOV'], 0.0) then\n        Container.ElementNativeValues['DATA\\FOV'] := 90.0;\n    end;\n\n  finally\n    wbEndInternalEdit;\n  end;\nend;\n\nprocedure wbEFITAfterLoad(const aElement: IwbElement);\nvar\n  Container : IwbContainerElementRef;\n  Element   : IwbElement;\n  ActorValue: Variant;\n  MainRecord: IwbMainRecord;\nbegin\n  if wbBeginInternalEdit then try\n    if not Supports(aElement, IwbContainerElementRef, Container) then\n      Exit;\n\n    if Container.ElementCount < 1 then\n      Exit;\n\n    MainRecord := Container.ContainingMainRecord;\n    if not Assigned(MainRecord) or MainRecord.IsDeleted then\n      Exit;\n\n    Element := Container.ElementByPath['..\\EFID'];\n    if not Assigned(Element) then\n      Exit;\n    if not Supports(Element.LinksTo, IwbMainRecord, MainRecord) then\n      Exit;\n    if MainRecord.Signature <> 'MGEF' then\n      Exit;\n    ActorValue := MainRecord.ElementNativeValues['DATA - Data\\Actor Value'];\n    if VarIsNull(ActorValue) or VarIsClear(ActorValue) then\n      Exit;\n    if VarCompareValue(ActorValue, Container.ElementNativeValues['Actor Value']) <> vrEqual then\n      Container.ElementNativeValues['Actor Value'] := ActorValue;\n  finally\n    wbEndInternalEdit;\n  end;\nend;\n\nprocedure wbRPLDAfterLoad(const aElement: IwbElement);\nvar\n  Container: IwbContainer;\n  a, b: Single;\n  NeedsFlip: Boolean;\nbegin\n  if wbBeginInternalEdit then try\n    if Supports(aElement, IwbContainer, Container) then begin\n      NeedsFlip := False;\n      if Container.ElementCount > 1 then begin\n        a := StrToFloat((Container.Elements[0] as IwbContainer).Elements[0].Value);\n        b := StrToFloat((Container.Elements[Pred(Container.ElementCount)] as IwbContainer).Elements[0].Value);\n        case CompareValue(a, b) of\n          EqualsValue: begin\n            a := StrToFloat((Container.Elements[0] as IwbContainer).Elements[1].Value);\n            b := StrToFloat((Container.Elements[Pred(Container.ElementCount)] as IwbContainer).Elements[1].Value);\n            NeedsFlip := CompareValue(a, b) = GreaterThanValue;\n          end;\n          GreaterThanValue:\n            NeedsFlip := True;\n        end;\n      end;\n      if NeedsFlip then\n        Container.ReverseElements;\n    end;\n  finally\n    wbEndInternalEdit;\n  end;\nend;\n\nprocedure wbLLEAfterLoad(const aElement: IwbElement);\nvar\n  Container  : IwbContainerElementRef;\n  Entries    : IwbContainerElementRef;\n  MainRecord : IwbMainRecord;\n  i          : integer;\nbegin\n  if wbBeginInternalEdit then try\n    // zero entries' Chance None if Form Version < 69\n    if wbFormVerDecider(nil, nil, aElement, 69) = 1 then\n      Exit;\n\n    if not Supports(aElement, IwbContainerElementRef, Container) then\n      Exit;\n\n    if Container.ElementCount < 1 then\n      Exit;\n\n    if not Supports(aElement, IwbMainRecord, MainRecord) then\n      Exit;\n\n    if MainRecord.IsDeleted then\n      Exit;\n\n    if not Supports(MainRecord.ElementByName['Leveled List Entries'], IwbContainerElementRef, Entries) then\n      Exit;\n\n\n    for i := 0 to Pred(Entries.ElementCount) do begin\n      if not Supports(Entries.Elements[i], IwbContainerElementRef, Container) then\n        Exit;\n      Container.ElementNativeValues['LVLO\\Chance None'] := 0;\n    end;\n\n  finally\n    wbEndInternalEdit;\n  end;\nend;\n\nfunction wbPubPackCNAMDecider(aBasePtr: Pointer; aEndPtr: Pointer; const aElement: IwbElement): Integer;\nvar\n  rANAM: IwbRecord;\n  ctype: string;\nbegin\n  Result := 0;\n  rANAM := aElement.Container.RecordBySignature[ANAM];\n  if Assigned(rANAM) then begin\n    ctype := rANAM.NativeValue;\n    if ctype = 'Bool' then Result := 1 else\n    if ctype = 'Int' then Result := 2 else\n    if ctype = 'Float' then Result := 3 else\n    if ctype = 'ObjectList' then Result := 3;\n  end;\nend;\n\nfunction wbTypeDecider(aBasePtr: Pointer; aEndPtr: Pointer; const aElement: IwbElement): Integer;\nvar\n  Container : IwbContainer;\n  Element   : IwbElement;\nbegin\n  Result := 0;\n  if not Assigned(aElement) then Exit;\n  Container := GetContainerFromUnion(aElement);\n  if not Assigned(Container) then Exit;\n\n  Element := Container.ElementByName['Type'];\n  if Assigned(Element) then\n    Result := Element.NativeValue\n  else if wbMoreInfoForDecider then\n    wbProgressCallback('\"'+Container.Name+'\" does not contain an element named Type');\nend;\n\nprocedure wbCNTOsAfterSet(const aElement: IwbElement; const aOldValue, aNewValue: Variant);\nbegin\n  wbCounterAfterSet('COCT - Count', aElement);\nend;\n\nprocedure wbContainerAfterSet(const aElement: IwbElement; const aOldValue, aNewValue: Variant);\nbegin\n  wbCounterContainerAfterSet('COCT - Count', 'Items', aElement);\n  wbCounterContainerAfterSet('KSIZ - Keyword Count', 'KWDA - Keywords', aElement);\nend;\n\nprocedure wbSPLOsAfterSet(const aElement: IwbElement; const aOldValue, aNewValue: Variant);\nbegin\n  wbCounterAfterSet('SPCT - Count', aElement);\nend;\n\nprocedure wbKWDAsAfterSet(const aElement: IwbElement; const aOldValue, aNewValue: Variant);\nbegin\n  wbCounterAfterSet('KSIZ - Keyword Count', aElement);\nend;\n\nprocedure wbNPCAfterSet(const aElement: IwbElement; const aOldValue, aNewValue: Variant);\nbegin\n  wbCounterContainerAfterSet('COCT - Count', 'Items', aElement);\n  wbCounterContainerAfterSet('SPCT - Count', 'Actor Effects', aElement);\n  wbCounterContainerAfterSet('LLCT - Count', 'Leveled List Entries', aElement);\n  wbCounterContainerAfterSet('KSIZ - Keyword Count', 'KWDA - Keywords', aElement);\n  wbCounterContainerAfterSet('PRKZ - Perk Count', 'Perks', aElement);\nend;\n\nprocedure wbRaceAfterSet(const aElement: IwbElement; const aOldValue, aNewValue: Variant);\nbegin\n  wbCounterContainerAfterSet('SPCT - Count', 'Actor Effects', aElement);\n  wbCounterContainerAfterSet('KSIZ - Keyword Count', 'KWDA - Keywords', aElement);\nend;\n\nprocedure wbKeywordsAfterSet(const aElement: IwbElement; const aOldValue, aNewValue: Variant);\nbegin\n  wbCounterContainerAfterSet('KSIZ - Keyword Count', 'KWDA - Keywords', aElement);\nend;\n\nprocedure wbLVLOsAfterSet(const aElement: IwbElement; const aOldValue, aNewValue: Variant);\nbegin\n  wbCounterAfterSet('LLCT - Count', aElement);\nend;\n\nprocedure wbLLEAfterSet(const aElement: IwbElement; const aOldValue, aNewValue: Variant);\nbegin\n  wbCounterContainerAfterSet('LLCT - Count', 'Leveled List Entries', aElement);\nend;\n\nprocedure wbPRKRsAfterSet(const aElement: IwbElement; const aOldValue, aNewValue: Variant);\nbegin\n  wbCounterAfterSet('PRKZ - Perk Count', aElement);\nend;\n\nprocedure wbSMQNQuestsAfterSet(const aElement: IwbElement; const aOldValue, aNewValue: Variant);\nbegin\n  wbCounterAfterSet('QNAM - Quest Count', aElement);\nend;\n\nprocedure wbCTDAsAfterSet(const aElement: IwbElement; const aOldValue, aNewValue: Variant);\nbegin\n  wbCounterAfterSet('CITC - Condition Count', aElement);\nend;\n\nprocedure wbConditionsAfterSet(const aElement: IwbElement; const aOldValue, aNewValue: Variant);\nbegin\n  wbCounterContainerAfterSet('CITC - Condition Count', 'Conditions', aElement);\nend;\n\nprocedure wbCounterEffectsAfterSet(const aElement: IwbElement; const aOldValue, aNewValue: Variant);\nbegin\n  // if it is really possible to have both counter effects and multiple data, this is going to be tricky.\n  wbCounterByPathAfterSet('Magic Effect Data\\DATA - Data\\Counter effect count', aElement);\nend;\n\nprocedure wbMGEFAfterSet(const aElement: IwbElement; const aOldValue, aNewValue: Variant);\nbegin\n  wbKeywordsAfterSet(aElement, aOldValue, aNewValue);\n  wbCounterContainerByPathAfterSet('Magic Effect Data\\DATA - Data\\Counter effect count', 'Counter Effects', aElement);\nend;\n\nprocedure wbTERMDisplayItemsAfterSet(const aElement: IwbElement; const aOldValue, aNewValue: Variant);\nbegin\n  wbCounterAfterSet('BSIZ - Count', aElement);\nend;\n\nprocedure wbTERMMenuItemsAfterSet(const aElement: IwbElement; const aOldValue, aNewValue: Variant);\nbegin\n  wbCounterAfterSet('ISIZ - Count', aElement);\nend;\n\nprocedure wbSNDRRatesOfFireAfterSet(const aElement: IwbElement; const aOldValue, aNewValue: Variant);\nbegin\n  wbCounterAfterSet('ITMC - Count', aElement);\nend;\n\nprocedure wbNPCActorSoundsAfterSet(const aElement: IwbElement; const aOldValue, aNewValue: Variant);\nbegin\n  wbCounterAfterSet('CS2H - Count', aElement);\nend;\n\nprocedure wbMorphPresetsAfterSet(const aElement: IwbElement; const aOldValue, aNewValue: Variant);\nbegin\n  wbCounterAfterSet('MPPC - Count', aElement);\nend;\n\nprocedure wbLENSAfterSet(const aElement: IwbElement; const aOldValue, aNewValue: Variant);\nbegin\n  wbCounterAfterSet('LFSP - Count', aElement);\nend;\n\n\nprocedure wbIDLAsAfterSet(const aElement: IwbElement; const aOldValue, aNewValue: Variant);\nvar\n  Element         : IwbElement;\n  Container       : IwbContainer;\n  SelfAsContainer : IwbContainer;\nbegin\n  if wbBeginInternalEdit then try\n    if not wbCounterAfterSet('IDLC - Animation Count', aElement) then\n      if Supports(aElement.Container, IwbContainer, Container) then begin\n        Element := Container.ElementByPath['IDLC'];\n        if Assigned(Element) and Supports(aElement, IwbContainer, SelfAsContainer) and\n          (Element.GetNativeValue<>SelfAsContainer.GetElementCount) then\n          Element.SetNativeValue(SelfAsContainer.GetElementCount);\n      end;\n  finally\n    wbEndInternalEdit;\n  end;\nend;\n\nprocedure wbAnimationsAfterSet(const aElement: IwbElement; const aOldValue, aNewValue: Variant);\nvar\n  Element         : IwbElement;\n  Elems           : IwbElement;\n  Container       : IwbContainer;\nbegin\n  if wbBeginInternalEdit then try\n    if not wbCounterContainerAfterSet('IDLC - Animation Count', 'IDLA - Animations', aElement) then\n      if Supports(aElement, IwbContainer, Container) then begin\n        Element := Container.ElementByPath['IDLC\\Animation Count'];\n        Elems   := Container.ElementByName['IDLA - Animations'];\n        if Assigned(Element) and not Assigned(Elems) then\n          if Element.GetNativeValue<>0 then\n            Element.SetNativeValue(0);\n      end;\n  finally\n    wbEndInternalEdit;\n  end;\nend;\n\nfunction wbOffsetDataColsCounter(aBasePtr: Pointer; aEndPtr: Pointer; const aElement: IwbElement): Cardinal;\nvar\n  Container : IwbDataContainer;\n  Element   : IwbElement;\n  fResult   : Extended;\nbegin\n  Result := 0;\n\n  if Supports(aElement.Container, IwbDataContainer, Container) and (Container.Name = 'OFST - Offset Data') and\n     Supports(Container.Container, IwbDataContainer, Container) then begin\n    Element := Container.ElementByPath['Object Bounds\\NAM0 - Min\\X'];\n    if Assigned(Element) then begin\n      fResult :=  Element.NativeValue;\n      if fResult >= MaxInt then\n        Result := 0\n      else\n        Result := Trunc(fResult);\n      Element := Container.ElementByPath['Object Bounds\\NAM9 - Max\\X'];\n      if Assigned(Element) then begin\n        fResult :=  Element.NativeValue;\n        if fResult >= MaxInt then\n          Result := 1\n        else\n          Result := Trunc(fResult) - Result + 1;\n      end;\n    end;\n  end;\nend;\n\nprocedure wbOMODpropertyAfterSet(const aElement: IwbElement; const aOldValue, aNewValue: Variant);\nbegin\n  wbCounterAfterSet('Property Count', aElement);\nend;\n\nprocedure wbOMODincludeAfterSet(const aElement: IwbElement; const aOldValue, aNewValue: Variant);\nbegin\n  wbCounterAfterSet('Include Count', aElement);\nend;\n\nprocedure wbOMODdataAfterSet(const aElement: IwbElement; const aOldValue, aNewValue: Variant);\nbegin\n  wbCounterContainerAfterSet('Property Count', 'Properties', aElement);\n  wbCounterContainerAfterSet('Include Count', 'Includes', aElement);\nend;\n\nfunction wbOMODDataIncludeCounter(aBasePtr: Pointer; aEndPtr: Pointer; const aElement: IwbElement): Cardinal;\nvar\n  Container       : IwbContainer;\nbegin\n  if Supports(aElement.Container, IwbContainer, Container) then\n    Result := Container.ElementNativeValues['Include Count']\n  else\n    Result := 0;\nend;\n\nfunction wbOMODDataPropertyCounter(aBasePtr: Pointer; aEndPtr: Pointer; const aElement: IwbElement): Cardinal;\nvar\n  Container       : IwbContainer;\nbegin\n  if Supports(aElement.Container, IwbContainer, Container) then\n    Result := Container.ElementNativeValues['Property Count']\n  else\n    Result := 0;\nend;\n\nfunction GetObjectModPropertyEnum(const aElement: IwbElement): IwbEnumDef;\nvar\n  MainRecord: IwbMainRecord;\n  rDATA: IwbContainer;\n  Signature: TwbSignature;\n  FormType: Cardinal;\nbegin\n  Result := nil;\n\n  MainRecord := aElement.ContainingMainRecord;\n\n  if not Assigned(MainRecord) then\n    Exit;\n\n  Signature := MainRecord.Signature;\n\n  if Signature = OMOD then\n    if Supports(MainRecord.ElementBySignature['DATA'], IwbContainer, rDATA) then begin\n      FormType := rDATA.ElementNativeValues['Form Type'];\n      Signature := PwbSignature(@FormType)^;\n    end;\n\n  if Signature = ARMO then\n    Result := wbArmorPropertyEnum\n  else if Signature = WEAP then\n    Result := wbWeaponPropertyEnum\n  else if Signature = NPC_ then\n    Result := wbActorPropertyEnum;\nend;\n\nfunction wbObjectModPropertyToStr(aInt: Int64; const aElement: IwbElement; aType: TwbCallbackType): string;\nvar\n  PropEnum: IwbEnumDef;\nbegin\n  Result := '';\n\n  PropEnum := GetObjectModPropertyEnum(aElement);\n\n  if not Assigned(PropEnum) then\n    case aType of\n      ctToStr, ctToSortKey, ctToEditValue: Result := IntToStr(aInt);\n    end\n  else\n    case aType of\n      ctToStr: Result := PropEnum.ToString(aInt, aElement);\n      ctToSortKey: Result := PropEnum.ToSortKey(aInt, aElement);\n      ctCheck: Result := PropEnum.Check(aInt, aElement);\n      ctToEditValue: Result := PropEnum.ToEditValue(aInt, aElement);\n      ctEditType: Result := 'ComboBox';\n      ctEditInfo: Result := PropEnum.EditInfo[aInt, aElement];\n    end;\nend;\n\nfunction wbObjectModPropertyToInt(const aString: string; const aElement: IwbElement): Int64;\nvar\n  PropEnum: IwbEnumDef;\nbegin\n  PropEnum := GetObjectModPropertyEnum(aElement);\n\n  if not Assigned(PropEnum) then\n    Result := StrToIntDef(aString, 0)\n  else\n    Result := PropEnum.FromEditValue(aString, aElement);\nend;\n\nfunction wbOMODDataFunctionTypeDecider(aBasePtr: Pointer; aEndPtr: Pointer; const aElement: IwbElement): Integer;\nvar\n  Container     : IwbContainer;\n  ValueType      : Integer;\nbegin\n  Result := 0;\n  if not Assigned(aElement) then Exit;\n  Container := GetContainerFromUnion(aElement);\n  if not Assigned(Container) then Exit;\n\n  ValueType := Container.ElementNativeValues['Value Type'];\n\n  case ValueType of\n    0: Result := 0;\n    1: Result := 0;\n    2: Result := 1;\n    4: Result := 3;\n    5: Result := 2;\n    6: Result := 3;\n  end;\nend;\n\nfunction wbOMODDataPropertyValue1Decider(aBasePtr: Pointer; aEndPtr: Pointer; const aElement: IwbElement): Integer;\nvar\n  Container     : IwbContainer;\n  ValueType     : Integer;\n  PropName      : string;\nbegin\n  Result := 0;\n  if not Assigned(aElement) then Exit;\n  Container := GetContainerFromUnion(aElement);\n  if not Assigned(Container) then Exit;\n\n  ValueType := Container.ElementNativeValues['Value Type'];\n  PropName := Container.ElementEditValues['Property'];\n\n  case ValueType of\n    0: Result := 1;\n    1: Result := 2;\n    2: Result := 3;\n    4, 6: Result := 4;\n    5: begin\n      if PropName = 'SoundLevel'    then Result := 6 else\n      if PropName = 'StaggerValue'  then Result := 7 else\n      if PropName = 'HitBehaviour'  then Result := 8 else\n      Result := 5;\n    end;\n  end;\nend;\n\nfunction wbOMODDataPropertyValue2Decider(aBasePtr: Pointer; aEndPtr: Pointer; const aElement: IwbElement): Integer;\nvar\n  Container     : IwbContainer;\n  ValueType      : Integer;\nbegin\n  Result := 0;\n  if not Assigned(aElement) then Exit;\n  Container := GetContainerFromUnion(aElement);\n  if not Assigned(Container) then Exit;\n\n  ValueType := Container.ElementNativeValues['Value Type'];\n\n  case ValueType of\n    0: Result := 1;\n    1: Result := 2;\n    2: Result := 3;\n    4: Result := 1;\n    6: Result := 2;\n  end;\nend;\n\nprocedure wbOBTSCombinationsAfterSet(const aElement: IwbElement; const aOldValue, aNewValue: Variant);\nbegin\n  wbCounterAfterSet('OBTE - Count', aElement);\nend;\n\nprocedure wbINNRAfterSet(const aElement: IwbElement; const aOldValue, aNewValue: Variant);\nbegin\n  wbCounterAfterSet('VNAM - Count', aElement);\nend;\n\nfunction wbCELLCombinedMeshesCounter(aBasePtr: Pointer; aEndPtr: Pointer; const aElement: IwbElement): Cardinal;\nvar\n  Container       : IwbContainer;\nbegin\n  if Supports(aElement.Container, IwbContainer, Container) then\n    Result := Container.ElementNativeValues['Meshes Count']\n  else\n    Result := 0;\nend;\n\nprocedure wbCELLCombinedMeshesAfterSet(const aElement: IwbElement; const aOldValue, aNewValue: Variant);\nbegin\n  wbCounterAfterSet('Meshes Count', aElement);\nend;\n\nfunction wbCELLCombinedRefsCounter(aBasePtr: Pointer; aEndPtr: Pointer; const aElement: IwbElement): Cardinal;\nvar\n  Container       : IwbContainer;\nbegin\n  // the counter is double of entries (each member of struct is counted)\n  if Supports(aElement.Container, IwbContainer, Container) then\n    Result := Container.ElementNativeValues['References Count'] div 2\n  else\n    Result := 0;\nend;\n\nprocedure wbCELLCombinedRefsAfterSet(const aElement: IwbElement; const aOldValue, aNewValue: Variant);\nvar\n  Element         : IwbElement;\n  Container       : IwbContainer;\n  SelfAsContainer : IwbContainer;\nbegin\n  // the counter is double of entries (each member of struct is counted)\n  if wbBeginInternalEdit then try\n    if Supports(aElement.Container, IwbContainer, Container) and\n       Supports(aElement, IwbContainer, SelfAsContainer) then begin\n      Element := Container.ElementByName['References Count'];\n      if Assigned(Element) then try\n        if (Element.GetNativeValue <> (SelfAsContainer.GetElementCount * 2)) then\n          Element.SetNativeValue(SelfAsContainer.GetElementCount * 2);\n      except end;\n    end;\n  finally\n    wbEndInternalEdit;\n  end;\nend;\n\nfunction wbCombinedMeshIDToStr(aInt: Int64; const aElement: IwbElement; aType: TwbCallbackType): string;\nvar\n  Cell: IwbMainRecord;\nbegin\n  Result := IntToHex(aInt, 8);\n\n  Cell := aElement.ContainingMainRecord;\n  if not Assigned(Cell) then\n    Exit;\n\n  case aType of\n    ctToStr, ctToEditValue: begin\n      Result := 'Precombined\\' + IntToHex(Cell.FormID and $00FFFFFF, 8) + '_' + Result + '_OC.nif';\n    end;\n    ctCheck: Result := '';\n  end;\nend;\n\nfunction wbCombinedMeshIDToInt(const aString: string; const aElement: IwbElement): Int64;\nvar\n  s: string;\n  i: Integer;\nbegin\n  Result := 0;\n  // hex number between first and second underscope\n  i := Pos('_', aString);\n  if i <> 0 then begin\n    s := Copy(aString, i + 1, Length(aString) - i);\n    i := Pos('_', s);\n    if i <> 0 then begin\n      s := Copy(s, 1, i - 1);\n      if Length(s) = 8 then try\n        Result := StrToInt64('$' + s);\n      except end;\n    end;\n  end;\nend;\n\nfunction wbREFRRecordFlagsDecider(const aElement: IwbElement): Integer;\nvar\n  MainRecord : IwbMainRecord;\n  NameRec    : IwbElement;\nbegin\n  Result := 0;\n\n  if not Assigned(aElement) then\n    Exit;\n\n  MainRecord := aElement.ContainingMainRecord;\n\n  if not Assigned(MainRecord) then\n    Exit;\n\n  NameRec := MainRecord.ElementBySignature[NAME];\n  if not Assigned(NameRec) then\n    Exit;\n\n  if not Supports(NameRec.LinksTo, IwbMainRecord, MainRecord) then\n    Exit;\n\n  if (MainRecord.Signature = ACTI) or\n     (MainRecord.Signature = STAT) or\n     (MainRecord.Signature = SCOL) or\n     (MainRecord.Signature = TREE)\n  then\n    Result := 1\n  else if\n     (MainRecord.Signature = CONT) or\n     (MainRecord.Signature = TERM)\n  then\n    Result := 2\n  else if MainRecord.Signature = DOOR then\n    Result := 3\n  else if MainRecord.Signature = LIGH then\n    Result := 4\n  else if MainRecord.Signature = MSTT then\n    Result := 5\n  else if MainRecord.Signature = ADDN then\n    Result := 6\n  else if\n     (MainRecord.Signature = SCRL) or\n     (MainRecord.Signature = AMMO) or\n     (MainRecord.Signature = ARMO) or\n     (MainRecord.Signature = BOOK) or\n     (MainRecord.Signature = INGR) or\n     (MainRecord.Signature = KEYM) or\n     (MainRecord.Signature = MISC) or\n     (MainRecord.Signature = FURN) or\n     (MainRecord.Signature = WEAP) or\n     (MainRecord.Signature = ALCH)\n  then\n    Result := 7;\nend;\n\nfunction wbByteColors(const aName: string = 'Color'): IwbStructDef;\nbegin\n  Result := wbStruct(aName, [\n    wbInteger('Red', itU8),\n    wbInteger('Green', itU8),\n    wbInteger('Blue', itU8),\n    wbByteArray('Unused', 1)\n  ]);\nend;\n\nfunction wbFloatColors(const aName: string = 'Color'): IwbStructDef;\nbegin\n  Result := wbStruct(aName, [\n    wbFloat('Red', cpNormal, True, 255, 0),\n    wbFloat('Green', cpNormal, True, 255, 0),\n    wbFloat('Blue', cpNormal, True, 255, 0)\n  ]);\nend;\n\nfunction wbWeatherColors(const aName: string): IwbStructDef;\nbegin\n  Result := wbStruct(aName, [\n    wbByteColors('Sunrise'),\n    wbByteColors('Day'),\n    wbByteColors('Sunset'),\n    wbByteColors('Night'),\n    wbByteColors('EarlySunrise'),\n    wbByteColors('LateSunrise'),\n    wbByteColors('EarlySunset'),\n    wbByteColors('LateSunset')\n  ], cpNormal, True, nil, 4);\nend;\n\nfunction wbAmbientColors(const aSignature: TwbSignature; const aName: string = 'Directional Ambient Lighting Colors'): IwbSubRecordDef; overload;\nbegin\n  Result := wbStruct(aSignature, aName, [\n    wbStruct('Directional', [\n      wbByteColors('X+'),\n      wbByteColors('X-'),\n      wbByteColors('Y+'),\n      wbByteColors('Y-'),\n      wbByteColors('Z+'),\n      wbByteColors('Z-')\n    ]),\n    wbByteColors('Specular'),\n    wbFloat('Scale')\n  ])\nend;\n\nfunction wbAmbientColors(const aName: string = 'Directional Ambient Lighting Colors'): IwbStructDef; overload;\nbegin\n  Result := wbStruct(aName, [\n    wbStruct('Directional', [\n      wbByteColors('X+'),\n      wbByteColors('X-'),\n      wbByteColors('Y+'),\n      wbByteColors('Y-'),\n      wbByteColors('Z+'),\n      wbByteColors('Z-')\n    ]),\n    wbByteColors('Specular'),\n    wbFloat('Scale', cpIgnore)\n  ]);\nend;\n\nfunction wbIntToHexStr(aInt: Int64; const aElement: IwbElement; aType: TwbCallbackType): string;\nbegin\n  case aType of\n    ctToStr, ctToSortKey, ctToEditValue: Result := IntToHex(aInt, 8);\n  else\n    Result := '';\n  end;\nend;\n\nfunction wbStrToInt(const aString: string; const aElement: IwbElement): Int64;\nvar\n  s: string;\n  i: integer;\nbegin\n  // ignore anything after space or :\n  i := Pos(' ', aString);\n  if i = 0 then\n    i := Pos(':', aString);\n\n  if i <> 0 then\n    s := Copy(aString, 1, i - 1)\n  else\n    s := aString;\n\n  try\n    Result := StrToInt64(s)\n  except\n    Result := 0;\n  end;\nend;\n\nfunction wbHexStrToInt(const aString: string; const aElement: IwbElement): Int64;\nvar\n  s: string;\n  i: integer;\nbegin\n  // ignore anything after space or :\n  i := Pos(' ', aString);\n  if i = 0 then\n    i := Pos(':', aString);\n\n  if i <> 0 then\n    s := Copy(aString, 1, i - 1)\n  else\n    s := aString;\n\n  try\n    Result := StrToInt64('$' + s)\n  except\n    Result := 0;\n  end;\nend;\n\ntype\n  TFaceGenFeature = record\n    RaceID  : String;\n    Female  : Boolean;\n    Entries : array of record\n      Index: Cardinal;\n      Name : String;\n    end;\n  end;\n  PFaceGenFeature = ^TFaceGenFeature;\n\nvar\n  // cache of race specific face morphs\n  FaceMorphs: array of TFaceGenFeature;\n  // cache of race specific tint layers\n  TintLayers: array of TFaceGenFeature;\n  // cache of race specific morph groups/presets and values\n  MorphValues: array of TFaceGenFeature;\n\n\nfunction wbMorphValueToStr(aInt: Int64; const aElement: IwbElement; aType: TwbCallbackType): string;\n\n  function GetCached(const aRaceID: string; aFemale: boolean): PFaceGenFeature;\n  var\n    i: integer;\n  begin\n    Result := nil;\n    if Length(MorphValues) <> 0 then\n      for i := Low(MorphValues) to High(MorphValues) do\n        if (MorphValues[i].Female = aFemale) and (MorphValues[i].RaceID = aRaceID) then begin\n          Result := @MorphValues[i];\n          Break;\n        end;\n  end;\n\nvar\n  Actor, Race       : IwbMainRecord;\n  Element           : IwbElement;\n  Container, Entry  : IwbContainerElementRef;\n  Container2, Entry2: IwbContainerElementRef;\n  Female, Female2   : Boolean;\n  RaceID, EntryName : string;\n  Cache             : PFaceGenFeature;\n  Index             : Cardinal;\n  i, j, k           : integer;\n  slList            : TStringList;\nbegin\n  // defaults\n  case aType of\n    ctToStr, ctToEditValue: Result := IntToHex64(aInt, 8);\n    ctToSortKey: begin\n      Result := IntToHex64(aInt, 8);\n      Exit;\n    end;\n    ctCheck: Result := '<Warning: Could not resolve morph index ' + IntToHex64(aInt, 8) + '>';\n    ctEditType: Result := '';\n    ctEditInfo: Result := '';\n  end;\n\n  Actor := aElement.ContainingMainRecord;\n  if not Assigned(Actor) then\n    Exit;\n\n  Female := Actor.ElementEditValues['ACBS\\Flags\\Female'] = '1';\n\n  Element := Actor.ElementBySignature['RNAM'];\n  if not Assigned(Element) then\n    Exit;\n\n  Element := Element.LinksTo;\n  if not Supports(Element, IwbMainRecord, Race) then\n    Exit;\n\n  Race := Race.WinningOverride;\n  RaceID := Race.EditorID;\n\n  Cache := GetCached(RaceID, Female);\n\n  // cache not found, fill with data from RACE\n  if not Assigned(Cache) then begin\n\n    slList := TStringList.Create;\n\n    for i := 0 to 1 do begin\n\n      Female2 := i = 1;\n      SetLength(MorphValues, Succ(Length(MorphValues)));\n      Cache := @MorphValues[Pred(Length(MorphValues))];\n      Cache.RaceID := RaceID;\n      Cache.Female := Female2;\n\n      slList.Clear;\n\n      if not Female2 then\n        Element := Race.ElementByName['Male Morph Groups']\n      else\n        Element := Race.ElementByName['Female Morph Groups'];\n\n      // iterate over morph groups\n      if Supports(Element, IwbContainerElementRef, Container) then\n        for j := 0 to Pred(Container.ElementCount) do begin\n          if not Supports(Container.Elements[j], IwbContainerElementRef, Entry) then\n            Break;\n\n          // group name\n          EntryName := Entry.ElementEditValues['MPGN'];\n\n          // iterate over morph group presets\n          if not Supports(Entry.ElementByName['Morph Presets'], IwbContainerElementRef, Container2) then\n            Continue;\n\n          for k := 0 to Pred(Container2.ElementCount) do\n            if Supports(Container2.Elements[k], IwbContainerElementRef, Entry2) then\n              slList.AddObject(\n                EntryName + ' - ' + Entry2.ElementEditValues['MPPN'],\n                TObject(Cardinal(Entry2.ElementNativeValues['MPPI']))\n              );\n        end;\n\n      // append morph values, same for both sexes\n      if Supports(Race.ElementByName['Morph Values'], IwbContainerElementRef, Container) then\n        for j := 0 to Pred(Container.ElementCount) do\n          if Supports(Container.Elements[j], IwbContainerElementRef, Entry) then\n            slList.AddObject(\n              Entry.ElementEditValues['MSM0'] + '/' + Entry.ElementEditValues['MSM1'],\n              TObject(Cardinal(Entry.ElementNativeValues['MSID']))\n            );\n\n      SetLength(Cache.Entries, slList.Count);\n\n      for j := 0 to Pred(slList.Count) do begin\n        Cache.Entries[j].Index := Cardinal(slList.Objects[j]);\n        Cache.Entries[j].Name := slList[j];\n      end;\n\n    end;\n\n    slList.Free;\n\n    Cache := GetCached(RaceID, Female);\n  end;\n\n  if not Assigned(Cache) then\n    Exit;\n\n  EntryName := '';\n  Index := Cardinal(aInt);\n  if Length(Cache.Entries) <> 0 then\n    for i := Low(Cache.Entries) to High(Cache.Entries) do\n      if Cache.Entries[i].Index = Index then begin\n        EntryName := Cache.Entries[i].Name;\n        Break;\n      end;\n\n  case aType of\n    ctToStr: begin\n      if EntryName <> '' then\n        Result := IntToHex64(aInt, 8) + ' ' + EntryName\n      else\n        Result := IntToHex64(aInt, 8) + ' <Morph index not found in ' + Race.Name + '>';\n    end;\n    ctCheck: begin\n      if EntryName = '' then\n        Result := '<Morph index ' + IntToHex(aInt, 8) + ' not found in ' + Race.Name + '>'\n      else\n        Result := '';\n    end;\n    ctEditType: Result := 'ComboBox';\n    ctEditInfo: begin\n      Result := '';\n      if Length(Cache.Entries) <> 0 then\n        for i := Low(Cache.Entries) to High(Cache.Entries) do begin\n          if Result <> '' then Result := Result + ',';\n          Result := Result +  '\"' + IntToHex(Cache.Entries[i].Index, 8) + ' ' + Cache.Entries[i].Name + '\"';\n        end;\n    end;\n  end;\nend;\n\n\n\nfunction wbFaceMorphToStr(aInt: Int64; const aElement: IwbElement; aType: TwbCallbackType): string;\n\n  function GetCached(const aRaceID: string; aFemale: boolean): PFaceGenFeature;\n  var\n    i: integer;\n  begin\n    Result := nil;\n    if Length(FaceMorphs) <> 0 then\n      for i := Low(FaceMorphs) to High(FaceMorphs) do\n        if (FaceMorphs[i].Female = aFemale) and (FaceMorphs[i].RaceID = aRaceID) then begin\n          Result := @FaceMorphs[i];\n          Break;\n        end;\n  end;\n\nvar\n  Actor, Race       : IwbMainRecord;\n  Element           : IwbElement;\n  Container, Entry  : IwbContainerElementRef;\n  Female, Female2   : Boolean;\n  RaceID, EntryName : string;\n  Cache             : PFaceGenFeature;\n  Index             : Cardinal;\n  i, j              : integer;\nbegin\n  // defaults\n  case aType of\n    ctToStr, ctToEditValue: Result := IntToHex64(aInt, 8);\n    ctToSortKey: begin\n      Result := IntToHex64(aInt, 8);\n      Exit;\n    end;\n    ctCheck: Result := '<Warning: Could not resolve face morph index ' + IntToHex64(aInt, 8) + '>';\n    ctEditType: Result := '';\n    ctEditInfo: Result := '';\n  end;\n\n  Actor := aElement.ContainingMainRecord;\n  if not Assigned(Actor) then\n    Exit;\n\n  Female := Actor.ElementEditValues['ACBS\\Flags\\Female'] = '1';\n\n  Element := Actor.ElementBySignature['RNAM'];\n  if not Assigned(Element) then\n    Exit;\n\n  Element := Element.LinksTo;\n  if not Supports(Element, IwbMainRecord, Race) then\n    Exit;\n\n  Race := Race.WinningOverride;\n  RaceID := Race.EditorID;\n\n  Cache := GetCached(RaceID, Female);\n\n  // cache not found, fill with data from RACE\n  if not Assigned(Cache) then begin\n\n    for i := 0 to 1 do begin\n\n      Female2 := i = 1;\n      SetLength(FaceMorphs, Succ(Length(FaceMorphs)));\n      Cache := @FaceMorphs[Pred(Length(FaceMorphs))];\n      Cache.RaceID := RaceID;\n      Cache.Female := Female2;\n\n      if not Female2 then\n        Element := Race.ElementByName['Male Face Morphs']\n      else\n        Element := Race.ElementByName['Female Face Morphs'];\n\n      if not Supports(Element, IwbContainerElementRef, Container) then\n        Continue;\n\n      SetLength(Cache.Entries, Container.ElementCount);\n\n      for j := 0 to Pred(Container.ElementCount) do begin\n        if not Supports(Container.Elements[j], IwbContainerElementRef, Entry) then\n          Break;\n        Cache.Entries[j].Index := Entry.ElementNativeValues['FMRI'];\n        Cache.Entries[j].Name := Entry.ElementEditValues['FMRN'];\n      end;\n    end;\n\n    Cache := GetCached(RaceID, Female);\n  end;\n\n  if not Assigned(Cache) then\n    Exit;\n\n  EntryName := '';\n  Index := Cardinal(aInt);\n  if Length(Cache.Entries) <> 0 then\n    for i := Low(Cache.Entries) to High(Cache.Entries) do\n      if Cache.Entries[i].Index = Index then begin\n        EntryName := Cache.Entries[i].Name;\n        Break;\n      end;\n\n  case aType of\n    ctToStr: begin\n      if EntryName <> '' then\n        Result := IntToHex64(aInt, 8) + ' ' + EntryName\n      else\n        Result := IntToHex64(aInt, 8) + ' <Face morph index not found in ' + Race.Name + '>';\n    end;\n    ctCheck: begin\n      if EntryName = '' then\n        Result := '<Face morph index ' + IntToHex(aInt, 8) + ' not found in ' + Race.Name + '>'\n      else\n        Result := '';\n    end;\n    ctEditType: Result := 'ComboBox';\n    ctEditInfo: begin\n      Result := '';\n      if Length(Cache.Entries) <> 0 then\n        for i := Low(Cache.Entries) to High(Cache.Entries) do begin\n          if Result <> '' then Result := Result + ',';\n          Result := Result +  '\"' + IntToHex(Cache.Entries[i].Index, 8) + ' ' + Cache.Entries[i].Name + '\"';\n        end;\n    end;\n  end;\nend;\n\nfunction wbTintLayerToStr(aInt: Int64; const aElement: IwbElement; aType: TwbCallbackType): string;\n\n  function GetCached(const aRaceID: string; aFemale: boolean): PFaceGenFeature;\n  var\n    i: integer;\n  begin\n    Result := nil;\n    if Length(TintLayers) <> 0 then\n      for i := Low(TintLayers) to High(TintLayers) do\n        if (TintLayers[i].Female = aFemale) and (TintLayers[i].RaceID = aRaceID) then begin\n          Result := @TintLayers[i];\n          Break;\n        end;\n  end;\n\nvar\n  Actor, Race       : IwbMainRecord;\n  Element           : IwbElement;\n  Container, Entry  : IwbContainerElementRef;\n  Container2, Entry2: IwbContainerElementRef;\n  Female, Female2   : Boolean;\n  RaceID, EntryName : string;\n  Cache             : PFaceGenFeature;\n  Index             : Cardinal;\n  i, j, k           : integer;\n  slList            : TStringList;\nbegin\n  // defaults\n  case aType of\n    ctToStr, ctToEditValue: Result := IntToStr(aInt);\n    ctToSortKey: begin\n      Result := IntToHex64(aInt, 8);\n      Exit;\n    end;\n    ctCheck: Result := '<Warning: Could not resolve tint layer index ' + IntToStr(aInt) + '>';\n    ctEditType: Result := '';\n    ctEditInfo: Result := '';\n  end;\n\n  Actor := aElement.ContainingMainRecord;\n  if not Assigned(Actor) then\n    Exit;\n\n  Female := Actor.ElementEditValues['ACBS\\Flags\\Female'] = '1';\n\n  Element := Actor.ElementBySignature['RNAM'];\n  if not Assigned(Element) then\n    Exit;\n\n  Element := Element.LinksTo;\n  if not Supports(Element, IwbMainRecord, Race) then\n    Exit;\n\n  Race := Race.WinningOverride;\n  RaceID := Race.EditorID;\n\n  Cache := GetCached(RaceID, Female);\n\n  // cache not found, fill with data from RACE\n  if not Assigned(Cache) then begin\n\n    slList := TStringList.Create;\n\n    for i := 0 to 1 do begin\n\n      Female2 := i = 1;\n      SetLength(TintLayers, Succ(Length(TintLayers)));\n      Cache := @TintLayers[Pred(Length(TintLayers))];\n      Cache.RaceID := RaceID;\n      Cache.Female := Female2;\n\n      if not Female2 then\n        Element := Race.ElementByName['Male Tint Layers']\n      else\n        Element := Race.ElementByName['Female Tint Layers'];\n\n      if not Supports(Element, IwbContainerElementRef, Container) then\n        Continue;\n\n      slList.Clear;\n\n      // iterate over tint groups\n      for j := 0 to Pred(Container.ElementCount) do\n        if Supports(Container.Elements[j], IwbContainerElementRef, Entry) then\n          // iterate over tint group options\n          if Supports(Entry.ElementByName['Options'], IwbContainerElementRef, Container2) then\n            for k := 0 to Pred(Container2.ElementCount) do\n              if Supports(Container2.Elements[k], IwbContainerElementRef, Entry2) then\n                slList.AddObject(\n                  Entry.ElementEditValues['TTGP'] + ' - ' + Entry2.ElementEditValues['TTGP'],\n                  TObject(Cardinal(Entry2.ElementNativeValues['TETI\\Index']))\n                );\n\n      SetLength(Cache.Entries, slList.Count);\n\n      for j := 0 to Pred(slList.Count) do begin\n        Cache.Entries[j].Index := Cardinal(slList.Objects[j]);\n        Cache.Entries[j].Name := slList[j];\n      end;\n    end;\n\n    slList.Free;\n\n    Cache := GetCached(RaceID, Female);\n  end;\n\n  if not Assigned(Cache) then\n    Exit;\n\n  EntryName := '';\n  Index := Cardinal(aInt);\n  if Length(Cache.Entries) <> 0 then\n    for i := Low(Cache.Entries) to High(Cache.Entries) do\n      if Cache.Entries[i].Index = Index then begin\n        EntryName := Cache.Entries[i].Name;\n        Break;\n      end;\n\n  case aType of\n    ctToStr: begin\n      if EntryName <> '' then\n        Result := IntToStr(aInt) + ' ' + EntryName\n      else\n        Result := IntToStr(aInt) + ' <Tint layer index not found in ' + Race.Name + '>';\n    end;\n    ctCheck: begin\n      if EntryName = '' then\n        Result := '<Tint layer index ' + IntToStr(aInt) + ' not found in ' + Race.Name + '>'\n      else\n        Result := '';\n    end;\n    ctEditType: Result := 'ComboBox';\n    ctEditInfo: begin\n      Result := '';\n      if Length(Cache.Entries) <> 0 then\n        for i := Low(Cache.Entries) to High(Cache.Entries) do begin\n          if Result <> '' then Result := Result + ',';\n          Result := Result + '\"' + IntToStr(Cache.Entries[i].Index) + ' ' + Cache.Entries[i].Name + '\"';\n        end;\n    end;\n  end;\nend;\n\n\nvar\n  wbRecordFlagsFlags : IwbFlagsDef;\n\nprocedure DefineFO4a;\n\nbegin\n  wbNull := wbByteArray('Unused', -255);\n  wbBoolEnum := wbEnum(['False', 'True']);\n  wbLLCT := wbInteger(LLCT, 'Count', itU8, nil, cpBenign);\n  wbCITC := wbInteger(CITC, 'Condition Count', itU32, nil, cpBenign);\n  wbLVLD := wbInteger(LVLD, 'Chance None', itU8, nil, cpNormal, True);\n\n  wbSPCT := wbInteger(SPCT, 'Count', itU32, nil, cpBenign);\n  wbSPLO := wbFormIDCk(SPLO, 'Actor Effect', [SPEL, LVSP]);\n  wbSPLOs := wbRArrayS('Actor Effects', wbSPLO, cpNormal, False, nil, wbSPLOsAfterSet, nil{wbActorTemplateUseActorEffectList});\n\n  wbKSIZ := wbInteger(KSIZ, 'Keyword Count', itU32, nil, cpBenign);\n  wbKWDAs := wbArrayS(KWDA, 'Keywords', wbFormIDCk('Keyword', [KYWD, NULL]), 0, cpNormal, False, nil, wbKWDAsAfterSet);\n  wbReqKWDAs := wbArrayS(KWDA, 'Keywords', wbFormIDCk('Keyword', [KYWD, NULL]), 0, cpNormal, True, nil, wbKWDAsAfterSet);\n\n  wbKeywords := wbRStruct('Keywords', [\n    wbKSIZ,\n    wbReqKWDAs\n  ], []);\n\n  //wbActorValue := wbInteger('Actor Value', itS32, wbActorValueEnum);\n  wbActorValue := wbFormIDCkNoReach('Actor Value', [AVIF, NULL]);\n\n  wbCOED := wbStructExSK(COED, [2], [0, 1], 'Extra Data', [\n    {00} wbFormIDCkNoReach('Owner', [NPC_, FACT, NULL]),\n    {04} wbUnion('Global Variable / Required Rank', wbCOEDOwnerDecider, [\n           wbByteArray('Unused', 4, cpIgnore),\n           wbFormIDCk('Global Variable', [GLOB, NULL]),\n           wbInteger('Required Rank', itS32)\n         ]),\n    {08} wbFloat('Item Condition')\n  ]);\n\n  wbCNTO :=\n    wbRStructExSK([0], [1], 'Item', [\n      wbStructExSK(CNTO, [0], [1], 'Item', [\n        wbFormIDCk('Item', sigBaseObjects),\n        wbInteger('Count', itS32)\n      ]),\n      wbCOED\n    ], []);\n  wbCOCT := wbInteger(COCT, 'Count', itU32, nil, cpBenign);\n  wbCNTOs := wbRArrayS('Items', wbCNTO, cpNormal, False, nil, wbCNTOsAfterSet);\n\n  {>>> When NAME is user defined these will be incorrect <<<}\n  wbBipedObjectEnum := wbEnum([\n    '30 - Hair Top',\n    '31 - Hair Long',\n    '32 - FaceGen Head',\n    '33 - BODY',\n    '34 - L Hand',\n    '35 - R Hand',\n    '36 - [U] Torso',\n    '37 - [U] L Arm',\n    '38 - [U] R Arm',\n    '39 - [U] L Leg',\n    '40 - [U] R Leg',\n    '41 - [A] Torso',\n    '42 - [A] L Arm',\n    '43 - [A] R Arm',\n    '44 - [A] L Leg',\n    '45 - [A] R Leg',\n    '46 - Headband',\n    '47 - Eyes',\n    '48 - Beard',\n    '49 - Mouth',\n    '50 - Neck',\n    '51 - Ring',\n    '52 - Scalp',\n    '53 - Decapitation',\n    '54 - Unnamed',\n    '55 - Unnamed',\n    '56 - Unnamed',\n    '57 - Unnamed',\n    '58 - Unnamed',\n    '59 - Shield',\n    '60 - Pipboy',\n    '61 - FX'\n  ], [\n    -1, 'None'\n  ]);\n\n  wbBipedObjectFlags := wbFlags([\n    {0x00000001} '30 - Hair Top',\n    {0x00000002} '31 - Hair Long',\n    {0x00000004} '32 - FaceGen Head',\n    {0x00000008} '33 - BODY',\n    {0x00000010} '34 - L Hand',\n    {0x00000020} '35 - R Hand',\n    {0x00000040} '36 - [U] Torso',\n    {0x00000080} '37 - [U] L Arm',\n    {0x00000100} '38 - [U] R Arm',\n    {0x00000200} '39 - [U] L Leg',\n    {0x00000400} '40 - [U] R Leg',\n    {0x00000800} '41 - [A] Torso',\n    {0x00001000} '42 - [A] L Arm',\n    {0x00002000} '43 - [A] R Arm',\n    {0x00004000} '44 - [A] L Leg',\n    {0x00008000} '45 - [A] R Leg',\n    {0x00010000} '46 - Headband',\n    {0x00020000} '47 - Eyes',\n    {0x00040000} '48 - Beard',\n    {0x00080000} '49 - Mouth',\n    {0x00100000} '50 - Neck',\n    {0x00200000} '51 - Ring',\n    {0x00400000} '52 - Scalp',\n    {0x00800000} '53 - Decapitation',\n    {0x01000000} '54 - Unnamed',\n    {0x02000000} '55 - Unnamed',\n    {0x04000000} '56 - Unnamed',\n    {0x08000000} '57 - Unnamed',\n    {0x10000000} '58 - Unnamed',\n    {0x20000000} '59 - Shield',\n    {0x40000000} '60 - Pipboy',\n    {0x80000000} '61 - FX'\n  ], True);\n\n  wbFirstPersonFlagsU32 := wbInteger('First Person Flags', itU32, wbBipedObjectFlags);\n\n  wbBOD2 := wbStruct(BOD2, 'Biped Body Template', [\n    wbFirstPersonFlagsU32\n  ], cpNormal, False);\n\n  wbMDOB := wbFormID(MDOB, 'Menu Display Object', cpNormal, False);\n  wbCNAM := wbStruct(CNAM, 'Color', [\n    wbInteger('Red', itU8),\n    wbInteger('Green', itU8),\n    wbInteger('Blue', itU8),\n    wbByteArray('Unknown', 1)\n  ]);\n\n  wbDODT := wbStruct(DODT, 'Decal Data', [\n    wbFloat('Min Width'),\n    wbFloat('Max Width'),\n    wbFloat('Min Height'),\n    wbFloat('Max Height'),\n    wbFloat('Depth'),\n    wbFloat('Shininess'),\n    wbStruct('Parallax', [\n      wbFloat('Scale'),\n      wbInteger('Passes', itU8) {>>> This can't be higher than 30 <<<}\n    ]),\n    wbInteger('Flags', itU8, wbFlags([\n      {0x01} 'POM Shadows',\n      {0x02} 'Alpha - Blending',\n      {0x04} 'Alpha - Testing',\n      {0x08} 'No Subtextures'\n    ], True)),\n    wbInteger('Alpha Threshold?', itU16),\n    wbByteColors('Color')\n  ]);\n\n//  wbRecordFlagsFlags := wbFlags([\n//    {>>> 0x00000000 ACTI: Collision Geometry (default) <<<}\n//    {0x00000001}'ESM',\n//    {0x00000002}'Unknown 2',\n//    {>>> 0x00000004 ARMO: Not playable <<<}\n//    {0x00000004}'NotPlayable',\n//    {0x00000008}'Unknown 4',\n//    {0x00000010}'Unknown 5',\n//    {0x00000020}'Deleted',\n//    {>>> 0x00000040 ACTI: Has Tree LOD <<<}\n//    {>>> 0x00000040 REGN: Border Region <<<}\n//    {>>> 0x00000040 STAT: Has Tree LOD <<<}\n//    {>>> 0x00000040 REFR: Hidden From Local Map <<<}\n//    {0x00000040}'Constant HiddenFromLocalMap BorderRegion HasTreeLOD',\n//    {>>> 0x00000080 TES4: Localized <<<}\n//    {>>> 0x00000080 PHZD: Turn Off Fire <<<}\n//    {>>> 0x00000080 SHOU: Treat Spells as Powers <<<}\n//    {>>> 0x00000080 STAT: Add-on LOD Object <<<}\n//    {0x00000080}'Localized IsPerch AddOnLODObject TurnOffFire TreatSpellsAsPowers',\n//    {>>> 0x00000100 ACTI: Must Update Anims <<<}\n//    {>>> 0x00000100 REFR: Inaccessible <<<}\n//    {>>> 0x00000100 REFR for LIGH: Doesn't light water <<<}\n//    {0x00000100}'MustUpdateAnims Inaccessible DoesntLightWater',\n//    {>>> 0x00000200 ACTI: Local Map - Turns Flag Off, therefore it is Hidden <<<}\n//    {>>> 0x00000200 REFR: MotionBlurCastsShadows <<<}\n//    {0x00000200}'HiddenFromLocalMap StartsDead MotionBlurCastsShadows',\n//    {>>> 0x00000400 LSCR: Displays in Main Menu <<<}\n//    {0x00000400}'PersistentReference QuestItem DisplaysInMainMenu',\n//    {0x00000800}'InitiallyDisabled',\n//    {0x00001000}'Ignored',\n//    {0x00002000}'ActorChanged',\n//    {0x00004000}'Unknown 15',\n//    {>>> 0x00008000 STAT: Has Distant LOD <<<}\n//    {0x00008000}'VWD',\n//    {>>> 0x00010000 ACTI: Random Animation Start <<<}\n//    {>>> 0x00010000 REFR light: Never fades <<<}\n//    {0x00010000}'RandomAnimationStart NeverFades',\n//    {>>> 0x00020000 ACTI: Dangerous <<<}\n//    {>>> 0x00020000 REFR light: Doesn't light landscape <<<}\n//    {>>> 0x00020000 SLGM: Can hold NPC's soul <<<}\n//    {>>> 0x00020000 STAT: Use High-Detail LOD Texture <<<}\n//    {0x00020000}'Dangerous OffLimits DoesntLightLandscape HighDetailLOD CanHoldNPC',\n//    {0x00040000}'Compressed',\n//    {>>> 0x00080000 STAT: Has Currents <<<}\n//    {0x00080000}'CantWait HasCurrents',\n//    {>>> 0x00100000 ACTI: Ignore Object Interaction <<<}\n//    {0x00100000}'IgnoreObjectInteraction',\n//    {0x00200000}'(Used in Memory Changed Form)',\n//    {0x00400000}'Unknown 23',\n//    {>>> 0x00800000 ACTI: Is Marker <<<}\n//    {0x00800000}'IsMarker',\n//    {0x01000000}'Unknown 25',\n//    {>>> 0x02000000 ACTI: Obstacle <<<}\n//    {>>> 0x02000000 REFR: No AI Acquire <<<}\n//    {0x02000000}'Obstacle NoAIAcquire',\n//    {>>> 0x04000000 ACTI: Filter <<<}\n//    {0x04000000}'NavMeshFilter',\n//    {>>> 0x08000000 ACTI: Bounding Box <<<}\n//    {0x08000000}'NavMeshBoundingBox',\n//    {>>> 0x10000000 STAT: Show in World Map <<<}\n//    {0x10000000}'MustExitToTalk ShowInWorldMap',\n//    {>>> 0x20000000 ACTI: Child Can Use <<<}\n//    {>>> 0x20000000 REFR: Don't Havok Settle <<<}\n//    {0x20000000}'ChildCanUse DontHavokSettle',\n//    {>>> 0x40000000 ACTI: GROUND <<<}\n//    {>>> 0x40000000 REFR: NoRespawn <<<}\n//    {0x40000000}'NavMeshGround NoRespawn',\n//    {>>> 0x80000000 REFR: MultiBound <<<}\n//    {0x80000000}'MultiBound'\n//  ], [18]);\n\n  wbRecordFlagsFlags := wbFlags(wbRecordFlagsFlags, [\n    {0x00000001} { 0} 'Unknown 0',\n    {0x00000002} { 1} 'Unknown 1',\n    {0x00000004} { 2} 'Unknown 2',\n    {0x00000008} { 3} 'Unknown 3',\n    {0x00000010} { 4} 'Unknown 4',\n    {0x00000020} { 4} 'Unknown 5',\n    {0x00000040} { 6} 'Unknown 6',\n    {0x00000080} { 7} 'Unknown 7',\n    {0x00000100} { 8} 'Unknown 8',\n    {0x00000200} { 9} 'Unknown 9',\n    {0x00000400} {10} 'Unknown 10',\n    {0x00000800} {11} 'Unknown 11',\n    {0x00001000} {12} 'Unknown 12',\n    {0x00002000} {13} 'Unknown 13',\n    {0x00004000} {14} 'Unknown 14',\n    {0x00008000} {15} 'Unknown 15',\n    {0x00010000} {16} 'Unknown 16',\n    {0x00020000} {17} 'Unknown 17',\n    {0x00040000} {18} 'Unknown 18',\n    {0x00080000} {19} 'Unknown 19',\n    {0x00100000} {20} 'Unknown 20',\n    {0x00200000} {21} 'Unknown 21',\n    {0x00400000} {22} 'Unknown 22',\n    {0x00800000} {23} 'Unknown 23',\n    {0x01000000} {24} 'Unknown 24',\n    {0x02000000} {25} 'Unknown 25',\n    {0x04000000} {26} 'Unknown 26',\n    {0x08000000} {27} 'Unknown 27',\n    {0x10000000} {28} 'Unknown 28',\n    {0x20000000} {29} 'Unknown 29',\n    {0x40000000} {30} 'Unknown 30',\n    {0x80000000} {31} 'Unknown 31'\n  ]);\n\n  wbRecordFlags := wbInteger('Record Flags', itU32, wbFlags(wbRecordFlagsFlags, wbFlagsList([])));\n\n  wbMainRecordHeader := wbStruct('Record Header', [\n    wbString('Signature', 4, cpCritical),\n    wbInteger('Data Size', itU32, nil, cpIgnore),\n    wbRecordFlags,\n    wbFormID('FormID', cpFormID),\n    wbByteArray('Version Control Info 1', 4, cpIgnore),\n    wbInteger('Form Version', itU16, nil, cpIgnore),\n    wbByteArray('Version Control Info 2', 2, cpIgnore)\n  ]);\n\n  wbSizeOfMainRecordStruct := 24;\n\n  wbIgnoreRecords.Add(XXXX);\n\n  wbXRGD := wbByteArray(XRGD, 'Ragdoll Data');\n  wbXRGB := wbByteArray(XRGB, 'Ragdoll Biped Data');\n\n  wbMusicEnum := wbEnum(['Default', 'Public', 'Dungeon']);\n  wbSoundLevelEnum := wbEnum([\n     'Loud',\n     'Normal',\n     'Silent',\n     'Very Loud',\n     'Quiet'\n    ]);\n\n  wbEntryPointsEnum := wbEnum([\n    { 0} 'Mod Breath Timer',\n    { 1} 'Mod My Critical Hit Chance',\n    { 2} 'Mod My Critical Hit Damage Mult',\n    { 3} 'Mod Mine Explode Chance',\n    { 4} 'Mod Incoming Limb Damage',\n    { 5} 'Mod Book Actor Value Bonus',\n    { 6} 'Mod Recovered Health',\n    { 7} 'Set Should Attack',\n    { 8} 'Mod Buy Prices',\n    { 9} 'Add Leveled List On Death',\n    {10} 'Set Max Carry Weight',\n    {11} 'Mod Addiction Chance',\n    {12} 'Mod Addiction Duration',\n    {13} 'Mod Positive Chem Duration',\n    {14} 'Activate',\n    {15} 'Ignore Running During Detection',\n    {16} 'Ignore Broken Lock',\n    {17} 'Mod Enemy Critical Hit Chance',\n    {18} 'Mod Sneak Attack Mult',\n    {19} 'Mod Max Placeable Mines',\n    {20} 'Mod Bow Zoom',\n    {21} 'Mod Recover Arrow Chance',\n    {22} 'Mod Exp',\n    {23} 'Mod Telekinesis Distance',\n    {24} 'Mod Telekinesis Damage Mult',\n    {25} 'Mod Telekinesis Damage',\n    {26} 'Mod Bashing Damage',\n    {27} 'Mod Power Attack Action Points',\n    {28} 'Mod Power Attack Damage',\n    {29} 'Mod Spell Magnitude',\n    {30} 'Mod Spell Duration',\n    {31} 'Mod Secondary Value Weight',\n    {32} 'Mod Armor Weight',\n    {33} 'Mod Incoming Stagger',\n    {34} 'Mod Target Stagger',\n    {35} 'Mod Weapon Attack Damage',\n    {36} 'Mod Incoming Weapon Damage',\n    {37} 'Mod Target Damage Resistance',\n    {38} 'Mod Spell Cost',\n    {39} 'Mod Percent Blocked',\n    {40} 'Mod Shield Deflect Arrow Chance',\n    {41} 'Mod Incoming Spell Magnitude',\n    {42} 'Mod Incoming Spell Duration',\n    {43} 'Mod Player Intimidation',\n    {44} 'Mod Ricochet Chance',\n    {45} 'Mod Ricochet Damage',\n    {46} 'Mod Bribe Amount',\n    {47} 'Mod Detection Light',\n    {48} 'Mod Detection Movement',\n    {49} 'Mod Scrap Reward Mult',\n    {50} 'Set Sweep Attack',\n    {51} 'Apply Combat Hit Spell',\n    {52} 'Apply Bashing Spell',\n    {53} 'Apply Reanimate Spell',\n    {54} 'Set Boolean Graph Variable',\n    {55} 'Mod Spell Casting Sound Event',\n    {56} 'Mod Pickpocket Chance',\n    {57} 'Mod Detection Sneak Skill',\n    {58} 'Mod Falling Damage',\n    {59} 'Mod Lockpick Sweet Spot',\n    {60} 'Mod Sell Prices',\n    {61} 'Set Pickpocket Equipped Item',\n    {62} 'Set Player Gate Lockpick',\n    {63} 'Set Lockpick Starting Arc',\n    {64} 'Set Progression Picking',\n    {65} 'Set Lockpicks Unbreakable',\n    {66} 'Mod Alchemy Effectiveness',\n    {67} 'Apply Weapon Swing Spell',\n    {68} 'Mod Commanded Actor Limit',\n    {69} 'Apply Sneaking Spell',\n    {70} 'Mod Player Magic Slowdown',\n    {71} 'Mod Ward Magicka Absorption Pct',\n    {72} 'Mod Initial Ingredient Effects Learned',\n    {73} 'Purify Alchemy Ingredients',\n    {74} 'Set Filter Activation',\n    {75} 'Set Dual Cast',\n    {76} 'Mod Outgoing Explosion Limb Damage',\n    {77} 'Mod Enchantment Power',\n    {78} 'Mod Soul Pct Captured to Weapon',\n    {79} 'Mod VATS Attack Action Points',\n    {80} 'Mod Reflect Damage Chance',\n    {81} 'Set Activate Label',\n    {82} 'Mod Kill Experience',\n    {83} 'Mod Poison Dose Count',\n    {84} 'Set Apply Placed Item',\n    {85} 'Mod Armor Rating',\n    {86} 'Mod lockpicking crime chance',\n    {87} 'Mod ingredients harvested',\n    {88} 'Mod Spell Range (Target Loc.)',\n    {89} 'Mod Critical Charge Mult on Ricochet',\n    {90} 'Mod lockpicking key reward chance',\n    {91} 'Mod Auto Lockpicking Chance',\n    {92} 'Mod Auto Hacking Chance',\n    {93} 'Mod Typed Weapon Attack Damage',\n    {94} 'Mod Typed Incoming Weapon Damage',\n    {95} 'Mod Charisma Challenge Chance',\n    {96} 'Mod Sprint AP Drain Rate',\n    {97} 'Mod Drawn Weapon Weight Speed Effect',\n    {98} 'Set Player Gate Hacking',\n    {99} 'Mod Player Explosion Damage',\n   {100} 'Mod Player Explosion Scale',\n   {101} 'Set Rads To Health Mult',\n   {102} 'Mod Actor Scope Stability',\n   {103} 'Mod Actor Grenade Speed Mult',\n   {104} 'Mod Explosion Force',\n   {105} 'Mod VATS Penetration Min Visibility',\n   {106} 'Mod Rads for Rad Health Max',\n   {107} 'Mod VATS Player AP On Kill Chance',\n   {108} 'Set VATS Fill Critical Bar On Hit',\n   {109} 'Mod VATS Concentrated Fire Chance Bonus',\n   {110} 'Mod VATS Critical Count',\n   {111} 'Mod VATS Hold Em Steady Bonus',\n   {112} 'Mod Typed Spell Magnitude',\n   {113} 'Mod Typed Incoming Spell Magnitude',\n   {114} 'Set VATS Gun-Fu Num Targets For Crits',\n   {115} 'Mod Outgoing Limb Damage',\n   {116} 'Mod Restore Action Cost Value',\n   {117} 'Mod VATS Reload Action Points',\n   {118} 'Mod Incoming Battery Damage',\n   {119} 'Mod VATS Critical Charge',\n   {120} 'Mod Exp Location',\n   {121} 'Mod Exp Speech',\n   {122} 'Mod VATS Head Shot Chance',\n   {123} 'Mod VATS Hit Chance',\n   {124} 'Mod Incoming Explosion Damage',\n   {125} 'Mod Ammo Health Mult',\n   {126} 'Mod Hacking Guesses',\n   {127} 'Mod Terminal Lockout Time',\n   {128} 'Set Undetectable',\n   {129} 'Invest In Vendor',\n   {130} 'Mod Outgoing Limb Bash Damage',\n   {131} 'Set Run While Over Encumbered',\n   {132} 'Get Component Radar Distance',\n   {133} 'Show Grenade Trajectory',\n   {134} 'Mod Cone-of-fire Mult',\n   {135} 'Mod VATS Concentrated Fire Damage Mult',\n   {136} 'Apply Bloody Mess Spell',\n   {137} 'Mod VATS Critical Fill Chance On Bank',\n   {138} 'Mod VATS Critical Fill Chance On Use',\n   {139} 'Set VATS Critical Fill On AP Reward',\n   {140} 'Set VATS Critical Fill On Stranger',\n   {141} 'Mod Gun Range Mult',\n   {142} 'Mod Scope Hold Breath AP Drain Mult',\n   {143} 'Set Force Decapitate',\n   {144} 'Mod VATS Shoot Explosive Damage Mult',\n   {145} 'Mod Scrounger Fill Ammo Chance',\n   {146} 'Set Can Explode Pants',\n   {147} 'Set VATS Penetration Full Damage',\n   {148} 'Mod VATS Gun-Fu 2nd Target Dmg Mult',\n   {149} 'Mod VATS Gun-Fu 3rd Target Dmg Mult',\n   {150} 'Mod VATS Gun-Fu 4th+ Target Dmg Mult',\n   {151} 'Mod VATS Blitz Max Distance',\n   {152} 'Set VATS Blitz Max Dmg Mult',\n   {153} 'Mod VATS Blitz Dmg Bonus Dist',\n   {154} 'Mod Bash Critical Chance',\n   {155} 'VATS Apply Paralyzing Palm Spell',\n   {156} 'Null Function'\n  ]);\n\n  wbEquipType := wbFlags([\n    {0x00000001} 'Hand To Hand Melee',\n    {0x00000002} 'One Hand Sword',\n    {0x00000004} 'One Hand Dagger',\n    {0x00000008} 'One Hand Axe',\n    {0x00000010} 'One Hand Mace',\n    {0x00000020} 'Two Hand Sword',\n    {0x00000040} 'Two Hand Axe',\n    {0x00000080} 'Bow',\n    {0x00000100} 'Staff',\n    {0x00000200} 'Gun',\n    {0x00000400} 'Grenade',\n    {0x00000800} 'Mine',\n    {0x00001000} 'Spell',\n    {0x00002000} 'Shield',\n    {0x00004000} 'Torch'\n  ], True);\n\n  wbEmotionTypeEnum := wbEnum([\n    {0} 'Neutral',\n    {1} 'Anger',\n    {2} 'Disgust',\n    {3} 'Fear',\n    {4} 'Sad',\n    {5} 'Happy',\n    {6} 'Surprise',\n    {7} 'Puzzled'\n  ]);\n\n  wbFurnitureAnimTypeEnum := wbEnum([\n    {0} '',\n    {1} 'Sit',\n    {2} 'Lay',\n    {3} '',\n    {4} 'Lean'\n  ]);\n\n  wbFurnitureEntryTypeFlags := wbFlags([\n    {0x01} 'Front',\n    {0x02} 'Behind',\n    {0x04} 'Right',\n    {0x08} 'Left',\n    {0x10} 'Up'\n  ]);\n\n  wbWardStateEnum := wbEnum([\n    'None',\n    'Absorb',\n    'Break'\n  ]);\n\n  wbEventFunctionEnum := wbEnum([\n    'GetIsID',\n    'IsInList',\n    'GetValue',\n    'HasKeyword',\n    'GetItemValue'\n  ]);\n\n  // Event member names and availability are different depending on event type\n  // Using generic names for the last 3 of them: Form, Value1, Value2\n  wbEventMemberEnum := wbEnum([], [\n    $0000, 'None',\n    $314F, 'CreatedObject',\n    $314C, '(Old)Location',\n    $324C, '(New)Location',\n    $314B, 'Keyword',\n    $3146, 'Form',\n    $3156, 'Value1',\n    $3256, 'Value2'\n  ]);\n\n  wbWeaponAnimTypeEnum := wbEnum([\n    {0} 'HandToHandMelee',\n    {1} 'OneHandSword',\n    {2} 'OneHandDagger',\n    {3} 'OneHandAxe',\n    {4} 'OneHandMace',\n    {5} 'TwoHandSword',\n    {6} 'TwoHandAxe',\n    {7} 'Bow',\n    {8} 'Staff',\n    {9} 'Crossbow'\n  ]);\n\n  wbReverbClassEnum := wbEnum([\n    'Default',\n    'Class A',\n    'Class B',\n    'Class C',\n    'Class D',\n    'Class E'\n  ]);\n\n  wbHitBehaviourEnum := wbEnum([\n    'Normal formula behaviour',\n    'Dismember only',\n    'Explode only',\n    'No dismember/explode'\n  ]);\n\n  wbEDID := wbString(EDID, 'Editor ID', 0, cpNormal); // not cpBenign according to Arthmoor\n  wbFULL := wbLStringKC(FULL, 'Name', 0, cpTranslate);\n  wbFULLActor := wbLStringKC(FULL, 'Name', 0, cpTranslate, False, nil{wbActorTemplateUseBaseData});\n  wbFULLReq := wbLStringKC(FULL, 'Name', 0, cpTranslate, True);\n  wbDESC := wbLStringKC(DESC, 'Description', 0, cpTranslate);\n  wbDESCReq := wbLStringKC(DESC, 'Description', 0, cpTranslate, True);\n  wbXSCL := wbFloat(XSCL, 'Scale');\n\n  wbOBND := wbStruct(OBND, 'Object Bounds', [\n    wbInteger('X1', itS16),\n    wbInteger('Y1', itS16),\n    wbInteger('Z1', itS16),\n    wbInteger('X2', itS16),\n    wbInteger('Y2', itS16),\n    wbInteger('Z2', itS16)\n  ]);\n\n  wbOBNDReq := wbStruct(OBND, 'Object Bounds', [\n    wbInteger('X1', itS16),\n    wbInteger('Y1', itS16),\n    wbInteger('Z1', itS16),\n    wbInteger('X2', itS16),\n    wbInteger('Y2', itS16),\n    wbInteger('Z2', itS16)\n  ], cpNormal, True);\n\n  wbPropTypeEnum := wbEnum([\n    {00} 'None',\n    {01} 'Object',\n    {02} 'String',\n    {03} 'Int32',\n    {04} 'Float',\n    {05} 'Bool',\n    {06} 'Variable',\n    {07} 'Struct',\n    {08} '',\n    {09} '',\n    {10} '',\n    {11} 'Array of Object',\n    {12} 'Array of String',\n    {13} 'Array of Int32',\n    {14} 'Array of Float',\n    {15} 'Array of Bool',\n    {16} 'Array of Variable',\n    {17} 'Array of Struct'\n  ]);\n\n  wbScriptFlags := wbInteger('Flags', itU8, wbEnum([\n    {0x00} 'Local',\n    {0x01} 'Inherited',\n    {0x02} 'Removed',\n    {0x03} 'Inherited and Removed'\n  ]));\n\n  wbScriptPropertyObject := wbUnion('Object Union', wbScriptObjFormatDecider, [\n    wbStructSK([1], 'Object v2', [\n      wbInteger('Unused', itU16, nil, cpIgnore),\n      wbInteger('Alias', itS16, wbScriptObjectAliasToStr, wbStrToAlias),\n      wbFormID('FormID')\n    ], [2, 1, 0]),\n    wbStructSK([1], 'Object v1', [\n      wbFormID('FormID'),\n      wbInteger('Alias', itS16, wbScriptObjectAliasToStr, wbStrToAlias),\n      wbInteger('Unused', itU16, nil, cpIgnore)\n    ])\n  ]);\n\n  wbScriptPropertyStruct :=\n    wbArrayS('Struct', wbStructSK([0], 'Member', [\n      wbLenString('memberName', 2),\n      wbInteger('Type', itU8, wbPropTypeEnum, cpNormal, False, nil, wbScriptPropertyTypeAfterSet),\n      wbInteger('Flags', itU8, wbEnum([\n        {0x00} '',\n        {0x01} 'Edited',\n        {0x02} '',\n        {0x03} 'Removed'\n      ])),\n      wbUnion('Value', wbScriptPropertyStructMemberDecider, [\n        {00} wbNull,\n        {01} wbScriptPropertyObject,\n        {02} wbLenString('String', 2),\n        {03} wbInteger('Int32', itS32),\n        {04} wbFloat('Float'),\n        {05} wbInteger('Bool', itU8, wbBoolEnum),\n        {11} wbArray('Array of Object', wbScriptPropertyObject, -1),\n        {12} wbArray('Array of String', wbLenString('Element', 2), -1),\n        {13} wbArray('Array of Int32', wbInteger('Element', itS32), -1),\n        {14} wbArray('Array of Float', wbFloat('Element'), -1),\n        {15} wbArray('Array of Bool', wbInteger('Element', itU8, wbBoolEnum), -1)\n      ])\n    ]), -1, cpNormal, False);\n\n  wbScriptProperties :=\n    wbArrayS('Properties', wbStructSK([0], 'Property', [\n      wbLenString('propertyName', 2),\n      wbInteger('Type', itU8, wbPropTypeEnum, cpNormal, False, nil, wbScriptPropertyTypeAfterSet),\n      wbInteger('Flags', itU8, wbEnum([\n        {0x00} '',\n        {0x01} 'Edited',\n        {0x02} '',\n        {0x03} 'Removed'\n      ])),\n      wbUnion('Value', wbScriptPropertyDecider, [\n       {00} wbNull,\n       {01} wbScriptPropertyObject,\n       {02} wbLenString('String', 2),\n       {03} wbInteger('Int32', itS32),\n       {04} wbFloat('Float'),\n       {05} wbInteger('Bool', itU8, wbBoolEnum),\n       {06} wbScriptPropertyStruct, // Variable. No idea if possible or how to decode, leaving like that for the moment\n       {07} wbScriptPropertyStruct,\n       {11} wbArray('Array of Object', wbScriptPropertyObject, -1),\n       {12} wbArray('Array of String', wbLenString('Element', 2), -1),\n       {13} wbArray('Array of Int32', wbInteger('Element', itS32), -1),\n       {14} wbArray('Array of Float', wbFloat('Element'), -1),\n       {15} wbArray('Array of Bool', wbInteger('Element', itU8, wbBoolEnum), -1),\n       {17} wbArray('Array of Struct', wbScriptPropertyStruct, -1)\n      ])\n    ]), -2, cpNormal, False, nil, nil, nil, False);\n\n  wbScriptEntry := wbStructSK([0], 'Script', [\n    wbLenString('scriptName', 2),\n    wbScriptFlags,\n    wbScriptProperties\n  ]);\n\n  wbScriptFragmentsInfo := wbStruct('Script Fragments', [\n    wbInteger('Unknown', itS8),\n    wbInteger('Flags', itU8, wbFlags([\n      {1} 'OnBegin',\n      {2} 'OnEnd'\n    ])),\n    wbScriptEntry,\n    wbArray('Fragments',  // Do NOT sort, ordered OnBegin, OnEnd\n      wbStruct('Fragment', [\n        wbInteger('Unknown', itS8),\n        wbLenString('scriptName', 2),\n        wbLenString('fragmentName', 2)\n      ]), [], wbScriptFragmentsInfoCounter)\n  ]);\n\n  wbScriptFragmentsPack := wbStruct('Script Fragments', [\n    wbInteger('Unknown', itS8),\n    wbInteger('Flags', itU8, wbFlags([\n      {1} 'OnBegin',\n      {2} 'OnEnd',\n      {4} 'OnChange'\n    ])),\n    wbScriptEntry,\n    wbArray('Fragments',  // Do NOT sort, ordered OnBegin, OnEnd, OnChange\n      wbStruct('Fragment', [\n        wbInteger('Unknown', itS8),\n        wbLenString('scriptName', 2),\n        wbLenString('fragmentName', 2)\n      ]), [], wbScriptFragmentsPackCounter)\n  ]);\n\n  wbScriptFragmentsQuest := wbStruct('Script Fragments', [\n    wbInteger('Unknown', itS8),\n    wbInteger('fragmentCount', itU16),\n    wbLenString('scriptName', 2),\n    // if scriptName = \"\" then no Flags and Properties\n    wbUnion('Script', wbScriptFragmentsEmptyScriptDecider, [\n      wbStruct('Script Data', [\n        wbScriptFlags,\n        wbScriptProperties\n      ]),\n//       Quest [000179EF] <DialogueGenericPlayer>\n//       Quest [000792CA] <DialogueGenericMerchants> \"Merchant Dialogue System\"\n//       Quest [00091FE1] <DialogueDiamondCityChapel>\n//       MQ101KelloggSequence \"Kellogg Sequence in Vault 111\" [QUST:000D3997]\n//       DialogueGlowingSeaAtom \"Children of the Atom Dialogue\" [QUST:0012DB31]\n//       BoSIdleHandlerQuest [QUST:00157460]\n      wbNull\n    ]),\n    wbArrayS('Fragments',\n      wbStructSK([0, 2], 'Fragment', [\n        wbInteger('Quest Stage', itU16),\n        wbInteger('Unknown', itS16),\n        wbInteger('Quest Stage Index', itS32),\n        wbInteger('Unknown', itS8),\n        wbLenString('scriptName', 2),\n        wbLenString('fragmentName', 2)\n      ]),\n      wbScriptFragmentsQuestCounter)\n  ]);\n\n  wbScriptFragmentsScen := wbStruct('Script Fragments', [\n    wbInteger('Unknown', itS8),\n    wbInteger('Flags', itU8, wbFlags([\n      {1} 'OnBegin',\n      {2} 'OnEnd'\n    ])),\n    wbScriptEntry,\n    wbArray('Fragments',  // Do NOT sort, ordered OnBegin, OnEnd\n      wbStruct('Fragment', [\n        wbInteger('Unknown', itS8),\n        wbLenString('scriptName', 2),\n        wbLenString('fragmentName', 2)\n      ]), [], wbScriptFragmentsSceneCounter),\n    wbArray('Phase Fragments',\n      wbStructSK([0, 1], 'Phase Fragment', [\n        wbInteger('Phase Flag', itU8, wbFlags([\n          {1} 'OnStart',\n          {2} 'OnCompletion'\n        ])),\n        wbInteger('Phase Index', itU8),\n        wbInteger('Unknown', itS16),\n        wbInteger('Unknown', itS8),\n        wbInteger('Unknown', itS8),\n        wbLenString('scriptName', 2),\n        wbLenString('fragmentName', 2)\n      ]), -2)\n  ]);\n\n  wbScriptFragments := wbStruct('Script Fragments', [\n    wbInteger('Unknown', itS8),\n    wbScriptEntry,\n    wbArrayS('Fragments',\n      wbStructSK([0], 'Fragment', [\n        wbInteger('Fragment Index', itU16),\n        wbInteger('Unknown', itS16),\n        wbInteger('Unknown', itS8),\n        wbLenString('scriptName', 2),\n        wbLenString('fragmentName', 2)\n      ]), -2)\n  ]);\n\n  {>>> http://www.uesp.net/wiki/Tes5Mod:Mod_File_Format/VMAD_Field <<<}\n\n  wbVMAD := wbStruct(VMAD, 'Virtual Machine Adapter', [\n    wbInteger('Version', itS16, nil, cpIgnore),\n    wbInteger('Object Format', itS16, nil, cpIgnore),\n    wbArrayS('Scripts', wbScriptEntry, -2, cpNormal, False, nil, nil, nil, False)\n  ]);\n\n  wbVMADFragmentedPERK := wbStruct(VMAD, 'Virtual Machine Adapter', [\n    wbInteger('Version', itS16, nil, cpIgnore),\n    wbInteger('Object Format', itS16, nil, cpIgnore),\n    wbArrayS('Scripts', wbScriptEntry, -2, cpNormal, False, nil, nil, nil, False),\n    wbScriptFragments\n  ], cpNormal, False, nil, 3);\n\n  wbVMADFragmentedPACK := wbStruct(VMAD, 'Virtual Machine Adapter', [\n    wbInteger('Version', itS16, nil, cpIgnore),\n    wbInteger('Object Format', itS16, nil, cpIgnore),\n    wbArrayS('Scripts', wbScriptEntry, -2, cpNormal, False, nil, nil, nil, False),\n    wbScriptFragmentsPack\n  ], cpNormal, False, nil, 3);\n\n  wbVMADFragmentedQUST := wbStruct(VMAD, 'Virtual Machine Adapter', [\n    wbInteger('Version', itS16, nil, cpIgnore),\n    wbInteger('Object Format', itS16, nil, cpIgnore),\n    wbArrayS('Scripts', wbScriptEntry, -2, cpNormal, False, nil, nil, nil, False),\n    wbScriptFragmentsQuest,\n    wbArrayS('Aliases', wbStructSK([0], 'Alias', [\n      wbScriptPropertyObject,\n      wbInteger('Version', itS16, nil, cpIgnore),\n      wbInteger('Object Format', itS16, nil, cpIgnore),\n      wbArrayS('Alias Scripts', wbScriptEntry, -2)\n    ]), -2)\n  ], cpNormal, False, nil, 3);\n\n  wbVMADFragmentedSCEN := wbStruct(VMAD, 'Virtual Machine Adapter', [\n    wbInteger('Version', itS16, nil, cpIgnore),\n    wbInteger('Object Format', itS16, nil, cpIgnore),\n    wbArrayS('Scripts', wbScriptEntry, -2, cpNormal, False, nil, nil, nil, False),\n    wbScriptFragmentsScen\n  ], cpNormal, False, nil, 3);\n\n  wbVMADFragmentedINFO := wbStruct(VMAD, 'Virtual Machine Adapter', [\n    wbInteger('Version', itS16, nil, cpIgnore),\n    wbInteger('Object Format', itS16, nil, cpIgnore),\n    wbArrayS('Scripts', wbScriptEntry, -2, cpNormal, False, nil, nil, nil, False),\n    wbScriptFragmentsInfo\n  ], cpNormal, False, nil, 3);\n\n  wbAttackData := wbRStructSK([1], 'Attack', [\n    wbStruct(ATKD, 'Attack Data', [\n      wbFloat('Damage Mult'),\n      wbFloat('Attack Chance'),\n      wbFormIDCk('Attack Spell', [SPEL, NULL]),\n      wbInteger('Attack Flags', itU32, wbFlags([\n        {0x00000001} 'Ignore Weapon',\n        {0x00000002} 'Bash Attack',\n        {0x00000004} 'Power Attack',\n        {0x00000008} 'Charge Attack',\n        {0x00000010} 'Rotating Attack',\n        {0x00000020} 'Continuous Attack',\n        {0x00000040} 'Unknown 6',\n        {0x00000080} 'Unknown 7',\n        {0x00000100} 'Unknown 8',\n        {0x00000200} 'Unknown 9',\n        {0x00000400} 'Unknown 10',\n        {0x00000800} 'Unknown 11',\n        {0x00001000} 'Unknown 12',\n        {0x00002000} 'Unknown 13',\n        {0x00004000} 'Unknown 14',\n        {0x00008000} 'Unknown 15',\n        {0x00010000} 'Unknown 16',\n        {0x00020000} 'Unknown 17',\n        {0x00040000} 'Unknown 18',\n        {0x00080000} 'Unknown 19',\n        {0x00100000} 'Unknown 20',\n        {0x00200000} 'Unknown 21',\n        {0x00400000} 'Unknown 22',\n        {0x00800000} 'Unknown 23',\n        {0x01000000} 'Unknown 24',\n        {0x02000000} 'Unknown 25',\n        {0x04000000} 'Unknown 26',\n        {0x08000000} 'Unknown 27',\n        {0x10000000} 'Unknown 28',\n        {0x20000000} 'Unknown 29',\n        {0x40000000} 'Unknown 30',\n        {0x80000000} 'Override Data'\n      ])),\n      wbFloat('Attack Angle'),\n      wbFloat('Strike Angle'),\n      wbFloat('Stagger'),\n      wbFloat('Knockdown'),\n      wbFloat('Recovery Time'),\n      wbFloat('Action Points Mult'),\n      wbInteger('Stagger Offset', itS32)\n    ]),\n    wbString(ATKE, 'Attack Event'),\n    wbFormIDCk(ATKW, 'Weapon Slot', [EQUP]),\n    wbFormIDCk(ATKS, 'Required Slot', [EQUP]),\n    wbString(ATKT, 'Description')\n  ], []);\n\n  wbLocationEnum := wbEnum([\n    {0} 'Near reference', // string dump: '%s' in '%s' radius %u\n    {1} 'In cell', // string dump: In cell '%s'\n    {2} 'Near package start location', // string dump: Near package start location, radius %u\n    {3} 'Near editor location', // string dump: Near editor location, radius %u\n    {4} 'Object ID',\n    {5} 'Object Type',\n    {6} 'Near linked reference', // string dump: Near linked reference, radius %u%s%s\n    {7} 'At package location', // string dump: At package location, radius %u\n    {8} 'Alias (reference)', // string dump: Alias: %s [item #%u], radius %u\n    {9} 'Alias (location)', // string dump: Alias: %s, radius %u\n   {10} 'Target', // string dump: <Target>\n   {11} 'Target (location)', // string dump: Target: %s, radius %u\n   {12} 'Near self', // Near Self, radius %u\n   {13} 'Near Editor Location Cell',\n   {14} 'Alias (ref collection)'\n  ]);\n\n  wbObjectTypeEnum := wbEnum([\n    { 0} ' NONE',\n    { 1} 'Activators',\n    { 2} 'Armor',\n    { 3} 'Books',\n    { 4} 'Containers',\n    { 5} 'Doors',\n    { 6} 'Ingredients',\n    { 7} 'Lights',\n    { 8} 'Miscellaneous',\n    { 9} 'Flora',\n    {10} 'Furniture',\n    {11} 'Weapons: Any',\n    {12} 'Ammo',\n    {13} 'Keys',\n    {14} 'Alchemy',\n    {15} 'Food',\n    {16} 'Clothing',\n    {17} 'All: Wearable',\n    {18} 'Weapons: NONE',\n    {19} 'Weapons: Melee',\n    {20} 'Weapons: Ranged',\n    {21} 'Spells: Any',\n    {22} 'Spells: Range Target',\n    {23} 'Spells: Range Touch',\n    {24} 'Spells: Range Self',\n    {25} 'Actors: Any',\n    {26} 'Furniture: Beds',\n    {27} 'Furniture: Chairs',\n    {28} 'Shouts',\n    {29} 'Headtrack Markers'\n  ]);\n\n  wbPLDT := wbStruct(PLDT, 'Location', [\n    wbInteger('Type', itS32, wbLocationEnum),\n    wbUnion('Location Value', wbTypeDecider, [\n      {0} wbFormIDCkNoReach('Reference', sigReferences),\n      {1} wbFormIDCkNoReach('Cell', [NULL, CELL]),\n      {2} wbByteArray('Near Package Start Location', 4, cpIgnore),\n      {3} wbByteArray('Near Editor Location', 4, cpIgnore),\n      {4} wbFormIDCkNoReach('Object ID', [NULL, ACTI, DOOR, STAT, MSTT, FURN, SPEL, NPC_, CONT, ARMO, AMMO, MISC, WEAP, OMOD, BOOK, NOTE, KEYM, ALCH, INGR, LIGH, FACT, FLST, IDLM, TXST, PROJ]),\n      {5} wbInteger('Object Type', itU32, wbObjectTypeEnum),\n      {6} wbFormIDCk('Keyword', [NULL, KYWD]),\n      {7} wbByteArray('Unused', 4, cpIgnore),\n      {8} wbInteger('Ref Alias', itS32, wbPackageLocationAliasToStr, wbStrToAlias),\n      {9} wbInteger('Loc Alias', itS32, wbPackageLocationAliasToStr, wbStrToAlias),\n     {10} wbInteger('Interrupt Data', itU32),\n     {11} wbInteger('Packdata Target', itU32),\n     {12} wbByteArray('Unknown', 4, cpIgnore),\n     {13} wbByteArray('Unknown', 4),\n     {14} wbInteger('Ref Collection Alias', itS32, wbPackageLocationAliasToStr, wbStrToAlias)\n    ]),\n    wbInteger('Radius', itS32),\n    wbInteger('Collection Index', itU32)\n  ], cpNormal, False, nil, 3);\n\n  wbPLVD := wbStruct(PLVD, 'Location', [\n    wbInteger('Type', itS32, wbLocationEnum),\n    wbUnion('Location Value', wbTypeDecider, [\n      {0} wbFormIDCkNoReach('Reference', sigReferences),\n      {1} wbFormIDCkNoReach('Cell', [NULL, CELL]),\n      {2} wbByteArray('Near Package Start Location', 4, cpIgnore),\n      {3} wbByteArray('Near Editor Location', 4, cpIgnore),\n      {4} wbFormIDCkNoReach('Object ID', [NULL, ACTI, DOOR, STAT, MSTT, FURN, SPEL, NPC_, CONT, ARMO, AMMO, MISC, WEAP, OMOD, BOOK, NOTE, KEYM, ALCH, INGR, LIGH, FACT, FLST, IDLM, TXST, PROJ]),\n      {5} wbInteger('Object Type', itU32, wbObjectTypeEnum),\n      {6} wbFormIDCk('Keyword', [NULL, KYWD]),\n      {7} wbByteArray('Unused', 4, cpIgnore),\n      {8} wbInteger('Ref Alias', itS32, wbPackageLocationAliasToStr, wbStrToAlias),\n      {9} wbInteger('Loc Alias', itS32, wbPackageLocationAliasToStr, wbStrToAlias),\n     {10} wbInteger('Interrupt Data', itU32),\n     {11} wbInteger('Packdata Target', itU32),\n     {12} wbByteArray('Unknown', 4, cpIgnore),\n     {13} wbByteArray('Unknown', 4),\n     {14} wbInteger('Ref Collection Alias', itS32, wbPackageLocationAliasToStr, wbStrToAlias)\n    ]),\n    wbInteger('Radius', itS32),\n    wbInteger('Collection Index', itU32)\n  ], cpNormal, False, nil, 3);\n\n  wbTargetData := wbStruct('Target Data', [\n    wbInteger('Type', itS32, wbEnum([\n      {0} 'Specific Reference',\n      {1} 'Object ID',\n      {2} 'Object Type',\n      {3} 'Linked Reference',\n      {4} 'Ref Alias',\n      {5} 'Interrupt Data',\n      {6} 'Self',\n      {7} 'Keyword',\n      {8} 'Unknown 8'\n    ]), cpNormal, False, nil, nil, 2),\n    wbUnion('Target', wbTypeDecider, [\n      {0} wbFormIDCkNoReach('Reference', sigReferences, True),\n      {1} wbFormIDCkNoReach('Object ID', [NULL, ACTI, DOOR, STAT, MSTT, FURN, SPEL, NPC_, CONT, ARMO, AMMO, MISC, WEAP, OMOD, BOOK, NOTE, KEYM, ALCH, INGR, LIGH, FACT, FLST, IDLM, TXST, PROJ]),\n      {2} wbInteger('Object Type', itU32, wbObjectTypeEnum),\n      {3} wbFormIDCk('Keyword', [KYWD, NULL]),\n      {4} wbInteger('Alias', itS32, wbPackageLocationAliasToStr, wbStrToAlias),\n      {5} wbInteger('Interrupt Data', itU32),\n      {6} wbByteArray('Unknown', 4, cpIgnore),\n      {7} wbFormIDCk('Keyword', [KYWD, NULL]),\n      {8} wbByteArray('Unknown', 4, cpIgnore)\n    ]),\n    wbInteger('Count / Distance', itS32)\n  ]);\n\n  wbEITM := wbFormIDCk(EITM, 'Object Effect', [ENCH, SPEL]);\n\n  wbPosRot :=\n    wbStruct('Position/Rotation', [\n      wbStruct('Position', [\n        wbFloat('X'),\n        wbFloat('Y'),\n        wbFloat('Z')\n      ]),\n      wbStruct('Rotation', [\n        wbFloat('X', cpNormal, True, wbRotationFactor, wbRotationScale, nil, RadiansNormalize),\n        wbFloat('Y', cpNormal, True, wbRotationFactor, wbRotationScale, nil, RadiansNormalize),\n        wbFloat('Z', cpNormal, True, wbRotationFactor, wbRotationScale, nil, RadiansNormalize)\n      ])\n    ]);\n\n  wbDATAPosRot :=\n    wbStruct(DATA, 'Position/Rotation', [\n      wbStruct('Position', [\n        wbFloat('X'),\n        wbFloat('Y'),\n        wbFloat('Z')\n      ]),\n      wbStruct('Rotation', [\n        wbFloat('X', cpNormal, True, wbRotationFactor, wbRotationScale, nil, RadiansNormalize),\n        wbFloat('Y', cpNormal, True, wbRotationFactor, wbRotationScale, nil, RadiansNormalize),\n        wbFloat('Z', cpNormal, True, wbRotationFactor, wbRotationScale, nil, RadiansNormalize)\n      ])\n    ], cpNormal, True);\n\n  wbMODS := wbFormIDCk(MODS, 'Material Swap', [MSWP]);\n  wbMO2S := wbFormIDCk(MO2S, 'Material Swap', [MSWP]);\n  wbMO3S := wbFormIDCk(MO3S, 'Material Swap', [MSWP]);\n  wbMO4S := wbFormIDCk(MO4S, 'Material Swap', [MSWP]);\n  wbMO5S := wbFormIDCk(MO5S, 'Material Swap', [MSWP]);\n\n  wbMODF := wbUnknown(MODF);\n  wbMO2F := wbUnknown(MO2F);\n  wbMO3F := wbUnknown(MO3F);\n  wbMO4F := wbUnknown(MO4F);\n  wbMO5F := wbUnknown(MO5F);\n\n  wbMODC := wbFloat(MODC, 'Color Remapping Index');\n  wbMO2C := wbFloat(MO2C, 'Color Remapping Index');\n  wbMO3C := wbFloat(MO3C, 'Color Remapping Index');\n  wbMO4C := wbFloat(MO4C, 'Color Remapping Index');\n  wbMO5C := wbFloat(MO5C, 'Color Remapping Index');\n\n\twbMODT := wbByteArray(MODT, 'Texture Files Hashes', 0, cpIgnore, false, false, wbNeverShow);\n\twbDMDT := wbByteArray(DMDT, 'Texture Files Hashes', 0, cpIgnore, false, false, wbNeverShow);\n  {wbMODT := wbStruct(MODT, 'Texture Files Hashes', [\n    wbInteger('Number of headers', itU32),\n    wbInteger('Textures count', itU32),\n    wbByteArray('Unused', 4),\n    wbInteger('Unique textures count', itU32),\n    wbInteger('Materials count', itU32),\n    wbArray('Hashes', wbStruct('Hash', [\n      wbByteArray('Flags', 4),\n      wbString('Type', 4),\n      wbByteArray('Texture hash', 4)\n    ]))\n  ]);}\n\n  wbMODL :=\n    wbRStructSK([0], 'Model', [\n      wbString(MODL, 'Model Filename', 0, cpNormal, True),\n      wbMODT,\n      wbMODS,\n      wbMODC,\n      wbMODF\n    ], [], cpNormal, False, nil, True);\n\n  wbMODLActor :=\n    wbRStructSK([0], 'Model', [\n      wbString(MODL, 'Model Filename', 0, cpNormal, True),\n      wbMODT,\n      wbMODS\n    ], [], cpNormal, False, nil{wbActorTemplateUseModelAnimation}, True);\n\n  wbMODLReq :=\n    wbRStructSK([0], 'Model', [\n      wbString(MODL, 'Model Filename', 0, cpNormal, True),\n      wbMODT,\n      wbMODS,\n      wbMODC,\n      wbMODF\n    ], [], cpNormal, True, nil, True);\n\n  wbDMDS := wbFormIDCk(DMDS, 'Material Swap', [MSWP]);\n  wbDMDC := wbFloat(DMDC, 'Color Remapping Index');\n\n  wbDEST := wbRStruct('Destructible', [\n    wbStruct(DEST, 'Header', [\n      wbInteger('Health', itS32),\n      wbInteger('DEST Count', itU8),\n      wbInteger('Flags', itU8, wbFlags([\n        'VATS Targetable',\n        'Large Actor Destroys'\n      ])),\n      wbByteArray('Unknown', 2)\n    ]),\n    wbArrayS(DAMC, 'Resistances', wbStructSK([0], 'Resistance', [\n      wbFormIDCk('Damage Type', [DMGT]),\n      wbInteger('Value', itU32)\n    ])),\n    wbRArray('Stages',\n      wbRStruct('Stage', [\n        wbStruct(DSTD, 'Destruction Stage Data', [\n          wbInteger('Health %', itU8),\n          wbInteger('Index', itU8),\n          wbInteger('Model Damage Stage', itU8),\n          wbInteger('Flags', itU8, wbFlags([\n            'Cap Damage',\n            'Disable',\n            'Destroy',\n            'Ignore External Dmg',\n            'Becomes Dynamic'\n          ])),\n          wbInteger('Self Damage per Second', itS32),\n          wbFormIDCk('Explosion', [EXPL, NULL]),\n          wbFormIDCk('Debris', [DEBR, NULL]),\n          wbInteger('Debris Count', itS32)\n        ], cpNormal, True),\n        wbString(DSTA, 'Sequence Name'),\n        wbRStructSK([0], 'Model', [\n          wbString(DMDL, 'Model Filename', 0, cpNormal, True),\n          wbDMDT,\n          wbDMDC,\n          wbDMDS\n        ], [], cpNormal, False, nil, True),\n        wbEmpty(DSTF, 'End Marker', cpNormal, True)\n      ], [], cpNormal, False, nil)\n    )\n  ], [], cpNormal, False, nil);\n\n  wbDESTActor := wbRStruct('Destructible', [\n    wbStruct(DEST, 'Header', [\n      wbInteger('Health', itS32),\n      wbInteger('Count', itU8),\n      wbInteger('VATS Targetable', itU8, wbBoolEnum),\n      wbByteArray('Unknown', 2)\n    ]),\n    wbRArray('Stages',  // Begin Stage Array\n      wbRStruct('Stage', [ // Begin Stage RStruct\n        wbStruct(DSTD, 'Destruction Stage Data', [ // Begin DSTD\n          wbInteger('Health %', itU8),\n          wbInteger('Index', itU8),\n          wbInteger('Damage Stage', itU8),\n          wbInteger('Flags', itU8, wbFlags([\n            'Cap Damage',\n            'Disable',\n            'Destroy'\n          ])),\n          wbInteger('Self Damage per Second', itS32),\n          wbFormIDCk('Explosion', [EXPL, NULL]),\n          wbFormIDCk('Debris', [DEBR, NULL]),\n          wbInteger('Debris Count', itS32)\n        ], cpNormal, True), // End DSTD\n        wbRStructSK([0], 'Model', [ // Begin DMDL\n          wbString(DMDL, 'Model Filename')\n        ], []), // End DMDL\n        wbDMDT,\n        wbDMDC,\n        wbDMDS,\n        wbEmpty(DSTF, 'End Marker', cpNormal, True)\n      ], []) // Begin Stage RStruct\n    ) // End Stage Array\n  ], [], cpNormal, False, nil{wbActorTemplateUseModelAnimation});\n\n  wbXLOD := wbArray(XLOD, 'Distant LOD Data', wbFloat('Unknown'), 3);\n\n  wbXESP := wbStruct(XESP, 'Enable Parent', [\n    wbFormIDCk('Reference', sigReferences),\n    wbInteger('Flags', itU8, wbFlags([\n      'Set Enable State to Opposite of Parent',\n      'Pop In'\n    ])),\n    wbByteArray('Unused', 3, cpIgnore)\n  ]);\n\n  wbPDTO :=\n    wbStruct(PDTO, 'Topic Data', [\n      wbInteger('Type', itU32, wbEnum([\n        'Topic Ref',\n        'Topic Subtype'\n      ])),\n      wbUnion('Data', wbTypeDecider, [\n        wbFormIDCk('Topic', [DIAL, NULL]),\n        wbString('Subtype', 4)\n      ])\n    ]);\n\n  wbPDTOs := wbRArray('Topic', wbPDTO, cpNormal, False, nil);\n\n  wbXLCM := wbInteger(XLCM, 'Level Modifier', itS32, wbEnum([\n    'Easy',\n    'Medium',\n    'Hard',\n    'Very Hard'\n  ]));\n\n  if wbSimpleRecords then begin\n    wbMaxHeightDataCELL := wbByteArray(MHDT, 'Max Height Data', 0, cpNormal);\n    wbMaxHeightDataWRLD := wbByteArray(MHDT, 'Max Height Data', 0, cpNormal);\n  end\n  else begin\n    wbMaxHeightDataCELL := wbStruct(MHDT, 'Max Height Data', [\n      wbFloat('Offset'),\n      wbArray('Rows',\n        wbByteArray('Columns', 32)\n        // way too verbose for no practical use\n        //wbStruct('Row', [ wbArray('Columns', wbInteger('Column', itU8), 32) ])\n      , 32)\n    ]);\n    wbMaxHeightDataWRLD := wbStruct(MHDT, 'Max Height Data', [\n      wbStruct('Min', [\n        wbInteger('X', itS16),\n        wbInteger('Y', itS16)\n      ]),\n      wbStruct('Max', [\n        wbInteger('X', itS16),\n        wbInteger('Y', itS16)\n      ]),\n      wbByteArray('Cell Data', 0)\n      // way too verbose for no practical use\n      {wbArray('Cell Data', wbStruct('Quad Height', [\n        wbInteger('Bottom Left', itU8),\n        wbInteger('Bottom Right', itU8),\n        wbInteger('Top Left', itU8),\n        wbInteger('Top Right', itU8)\n      ]))}\n    ]);\n  end;\n\n  if wbSimpleRecords then\n    wbOFST := wbByteArray(OFST, 'Offset Data')\n  else\n    wbOFST := wbArray(OFST, 'Offset Data', wbArray('Rows', wbInteger('Offset', itU32), wbOffsetDataColsCounter), 0);\n\n  wbXOWN := wbStruct(XOWN, 'Owner', [\n    wbFormIDCkNoReach('Owner', [FACT, ACHR, NPC_]),\n    wbByteArray('Unknown', 4),\n    wbInteger('Flags', itU8, wbFlags(['No Crime'])),\n    wbByteArray('Unknown', 3)\n  ]);\n  wbXRNK := wbInteger(XRNK, 'Owner Faction Rank', itS32);\n\n  if wbSimpleRecords then\n    wbNVNM := wbStruct(NVNM, 'Navmesh Geometry', [\n      wbInteger('Version', itU32),\n      wbByteArray('Magic', 4),\n      wbFormIDCk('Parent Worldspace', [WRLD, NULL]),\n      wbUnion('Parent', wbNVNMParentDecider, [\n        wbStruct('Coordinates', [\n          wbInteger('Grid Y', itS16),\n          wbInteger('Grid X', itS16)\n        ]),\n        wbFormIDCk('Parent Cell', [CELL])\n      ]),\n      wbByteArray('Vertices and Triangles')\n    ])\n  else\n    wbNVNM := wbStruct(NVNM, 'Navmesh Geometry', [\n      wbInteger('Version', itU32),  // Changes how the struct is loaded, should be 15 in FO4\n      wbStruct('Pathing Cell', [\n        wbInteger('Magic', itU32),  // This looks like a magic number (always $A5E9A03C), loaded with the parents\n        wbFormIDCk('Parent Worldspace', [WRLD, NULL]),\n        wbUnion('Parent', wbNVNMParentDecider, [  // same as TES5 cell if worldspace is null or Grid X Y\n          wbStruct('Coordinates', [\n            wbInteger('Grid Y', itS16),\n            wbInteger('Grid X', itS16)\n          ]),\n          wbFormIDCk('Parent Cell', [CELL])\n        ])\n      ]),\n      wbArray('Vertices', wbStruct('Vertex', [\n        wbFloat('X'),\n        wbFloat('Y'),\n        wbFloat('Z')\n      ]), -1),\n      wbArray('Triangles',\n        wbStruct('Triangle', [\n          wbInteger('Vertex 0', itS16),\n          wbInteger('Vertex 1', itS16),\n          wbInteger('Vertex 2', itS16),\n          wbInteger('Edge 0-1', itS16),\n          wbInteger('Edge 1-2', itS16),\n          wbInteger('Edge 2-0', itS16),\n          wbFloat('Height'), // this and next if form ver > 57\n          wbInteger('Unknown', itU8, wbFlags([])), // flags\n          wbInteger('Unknown', itU32) // encoding or flags\n        ])\n      , -1),\n      wbArray('Edge Links',\n        wbStruct('Edge Link', [\n          wbInteger('Unknown', itU32),\n          wbFormIDCk('Mesh', [NAVM]), // those last three are a structure\n          wbInteger('Triangle', itS16),\n          wbInteger('Unknown', itU8) // if form ver > 127\n        ])\n      , -1),\n      wbArray('Door Triangles',\n        wbStruct('Door Triangle', [\n          wbInteger('Triangle before door', itU16), // I would say itU16\n          wbInteger('DTUnknown', itU32),  // used as a key to lookup in a map of PathingDoor\n          wbUnion('Door', wbDoorTriangleDoorTriangleDecider, [wbNull, wbFormIDCk('Door', [REFR])])\n        ])\n      , -1),\n      wbArray('Unknown 5',  // if navmesh version gt 12\n        wbStruct('Unknown', [\n          wbInteger('Unknown', itU16),\n          wbInteger('Unknown', itU16),\n          wbInteger('Unknown', itU32 {, wbFlags([]) ? })\n        ])\n      , -1),\n      wbArray('Unknown 6',\n        wbStruct('Uknown', [\n          wbInteger('Unknown', itU16),\n          wbInteger('Unknown', itU16)\n        ])\n      , -1),\n      wbArray('Unknown 7',  // if navmesh version gt 11\n        wbStruct('Unknown', [\n          wbFloat('Unknown'),\n          wbFloat('Unknown'),\n          wbFloat('Unknown'),\n          wbInteger('Unknown', itU16),\n          wbInteger('Unknown', itU32)\n        ])\n      , -1),\n      wbStruct('Navmesh Grid', [\n        wbInteger('Navmesh Grid Size', itU32),  // max 12\n        wbFloat('Max X Distance'),\n        wbFloat('Max Y Distance'),\n        wbFloat('Min X'),\n        wbFloat('Min Y'),\n        wbFloat('Min Z'),\n        wbFloat('Max X'),\n        wbFloat('Max Y'),\n        wbFloat('Max Z'),\n        wbArray('NavMesh Grid Arrays', wbArray('NavMeshGridCell', wbInteger('Triangle', itS16), -1)) // There are NavMeshGridSize^2 arrays to load\n      ])\n    ]);\n\nend;\n\nprocedure DefineFO4b;\nbegin\n\n  wbRecord(ACHR, 'Placed NPC',\n    wbFlags(wbRecordFlagsFlags, wbFlagsList([\n      {0x00000200}  9, 'Starts Dead',\n      {0x00000400} 10, 'Persistent',\n      {0x00000800} 11, 'Initially Disabled',\n      {0x02000000} 25, 'No AI Acquire',\n      {0x20000000} 29, 'Don''t Havok Settle'\n    ], True, True)), [\n    wbEDID,\n    wbVMAD,\n    wbFormIDCk(NAME, 'Base', [NPC_], False, cpNormal, True),\n    wbFormIDCk(XEZN, 'Encounter Zone', [ECZN]),\n\n    {--- Ragdoll ---}\n    wbXRGD,\n    wbXRGB,\n\n    {--- Patrol Data ---}\n    wbRStruct('Patrol Data', [\n      wbFloat(XPRD, 'Idle Time', cpNormal, True),\n      wbEmpty(XPPA, 'Patrol Script Marker', cpNormal, True),\n      wbFormIDCk(INAM, 'Idle', [IDLE, NULL], False, cpNormal, True),\n      wbPDTOs,\n      wbFormIDCk(TNAM, 'Topic', [DIAL, NULL], False, cpNormal)\n    ], []),\n\n    {--- Leveled Actor ----}\n    wbXLCM,\n\n    {--- Extra ---}\n    wbInteger(XCNT, 'Count', itS32),\n    wbFloat(XRDS, 'Radius'),\n    wbInteger(XHLT, 'Health %', itU32),\n\n    wbRArrayS('Linked References', wbStructSK(XLKR, [0], 'Linked Reference', [\n      wbFormIDCk('Keyword/Ref', [KYWD, PLYR, ACHR, REFR, PGRE, PHZD, PMIS, PARW, PBAR, PBEA, PCON, PFLA, NULL]),\n      wbFormIDCk('Ref', sigReferences)\n    ], cpNormal, False, nil, 1)),\n\n    {--- Activate Parents ---}\n    wbRStruct('Activate Parents', [\n      wbInteger(XAPD, 'Flags', itU8, wbFlags([\n        'Parent Activate Only'\n      ], True)),\n      wbRArrayS('Activate Parent Refs',\n        wbStructSK(XAPR, [0], 'Activate Parent Ref', [\n          wbFormIDCk('Reference', sigReferences),\n          wbFloat('Delay')\n        ])\n      )\n    ], []),\n\n    wbEmpty(XLKT, 'Linked Ref Transient'),\n    wbFormIDCk(XRFG, 'Reference Group', [RFGP]),\n    wbFormIDCk(XLYR, 'Layer', [LAYR]),\n    wbFormIDCk(XMSP, 'Material Swap', [MSWP]),\n\n    wbFormIDCk(XLCN, 'Persistent Location', [LCTN]),\n    wbFormIDCk(XLRL, 'Location Reference', [LCRT, LCTN, NULL], False, cpBenignIfAdded),\n    wbArray(XLRT, 'Location Ref Type', wbFormIDCk('Ref', [LCRT, NULL])),\n\n    wbEmpty(XIS2, 'Ignored by Sandbox'),\n    wbRArray('Spline Connection', wbStruct(XPLK, 'Link', [\n      wbFormIDCk('Ref', [REFR, ACHR]),\n      wbUnknown  // always 00 00 00 00 so far in DLCWorkshop03.esm\n    ])),\n    wbFloat(XHTW, 'Head-Tracking Weight'),\n    wbFloat(XFVC, 'Favor Cost'),\n\n    {--- Enable Parent ---}\n    wbXESP,\n\n    {--- Ownership ---}\n    wbXOWN,\n    wbXRNK,\n\n    {--- Emittance ---}\n    wbFormIDCk(XEMI, 'Emittance', [LIGH, REGN]),\n\n    {--- MultiBound ---}\n    wbFormIDCk(XMBR, 'MultiBound Reference', sigReferences),\n\n    {--- Flags ---}\n    wbEmpty(XIBS, 'Ignored By Sandbox'),\n\n    {--- 3D Data ---}\n    wbXSCL,\n    wbDATAPosRot,\n    wbString(MNAM, 'Comments')\n  ], True, wbPlacedAddInfo);\n\n  wbVatsValueFunctionEnum :=\n    wbEnum([\n      { 0} 'Weapon Is',\n      { 1} 'Weapon In List',\n      { 2} 'Target Is',\n      { 3} 'Target In List',\n      { 4} 'Target Distance',\n      { 5} 'Target Part',\n      { 6} 'VATS Action',\n      { 7} 'Is Success',\n      { 8} 'Is Critical',\n      { 9} 'Critical Effect Is',\n      {10} 'Critical Effect In List',\n      {11} 'Is Fatal',\n      {12} 'Explode Part',\n      {13} 'Dismember Part',\n      {14} 'Cripple Part',\n      {15} 'Weapon Type Is',\n      {16} 'Is Stranger',\n      {17} 'Is Paralyzing Palm',\n      {18} 'Projectile Type Is',\n      {19} 'Delivery Type Is',\n      {20} 'Casting Type Is'\n    ]);\n\n  wbActorValueEnum :=\n    wbEnum([\n    {00} 'Aggression',\n    {01} 'Confidence',\n    {02} 'Energy',\n    {03} 'Morality',\n    {04} 'Mood',\n    {05} 'Assistance',\n    {06} 'One-Handed',\n    {07} 'Two-Handed',\n    {08} 'Archery',\n    {09} 'Block',\n    {10} 'Smithing',\n    {11} 'Heavy Armor',\n    {12} 'Light Armor',\n    {13} 'Pickpocket',\n    {14} 'Lockpicking',\n    {15} 'Sneak',\n    {16} 'Alchemy',\n    {17} 'Speech',\n    {18} 'Alteration',\n    {19} 'Conjuration',\n    {20} 'Destruction',\n    {21} 'Illusion',\n    {22} 'Restoration',\n    {23} 'Enchanting',\n    {24} 'Health',\n    {25} 'Magicka',\n    {26} 'Stamina',\n    {27} 'Heal Rate',\n    {28} 'Magicka Rate',\n    {29} 'Stamina Rate',\n    {30} 'Speed Mult',\n    {31} 'Inventory Weight',\n    {32} 'Carry Weight',\n    {33} 'Critical Chance',\n    {34} 'Melee Damage',\n    {35} 'Unarmed Damage',\n    {36} 'Mass',\n    {37} 'Voice Points',\n    {38} 'Voice Rate',\n    {39} 'Damage Resist',\n    {40} 'Poison Resist',\n    {41} 'Resist Fire',\n    {42} 'Resist Shock',\n    {43} 'Resist Frost',\n    {44} 'Resist Magic',\n    {45} 'Resist Disease',\n    {46} 'Unknown 46',\n    {47} 'Unknown 47',\n    {48} 'Unknown 48',\n    {49} 'Unknown 49',\n    {50} 'Unknown 50',\n    {51} 'Unknown 51',\n    {52} 'Unknown 52',\n    {53} 'Paralysis',\n    {54} 'Invisibility',\n    {55} 'Night Eye',\n    {56} 'Detect Life Range',\n    {57} 'Water Breathing',\n    {58} 'Water Walking',\n    {59} 'Unknown 59',\n    {60} 'Fame',\n    {61} 'Infamy',\n    {62} 'Jumping Bonus',\n    {63} 'Ward Power',\n    {64} 'Right Item Charge',\n    {65} 'Armor Perks',\n    {66} 'Shield Perks',\n    {67} 'Ward Deflection',\n    {68} 'Variable01',\n    {69} 'Variable02',\n    {70} 'Variable03',\n    {71} 'Variable04',\n    {72} 'Variable05',\n    {73} 'Variable06',\n    {74} 'Variable07',\n    {75} 'Variable08',\n    {76} 'Variable09',\n    {77} 'Variable10',\n    {78} 'Bow Speed Bonus',\n    {79} 'Favor Active',\n    {80} 'Favors Per Day',\n    {81} 'Favors Per Day Timer',\n    {82} 'Left Item Charge',\n    {83} 'Absorb Chance',\n    {84} 'Blindness',\n    {85} 'Weapon Speed Mult',\n    {86} 'Shout Recovery Mult',\n    {87} 'Bow Stagger Bonus',\n    {88} 'Telekinesis',\n    {89} 'Favor Points Bonus',\n    {90} 'Last Bribed Intimidated',\n    {91} 'Last Flattered',\n    {92} 'Movement Noise Mult',\n    {93} 'Bypass Vendor Stolen Check',\n    {94} 'Bypass Vendor Keyword Check',\n    {95} 'Waiting For Player',\n    {96} 'One-Handed Modifier',\n    {97} 'Two-Handed Modifier',\n    {98} 'Marksman Modifier',\n    {99} 'Block Modifier',\n   {100} 'Smithing Modifier',\n   {101} 'Heavy Armor Modifier',\n   {102} 'Light Armor Modifier',\n   {103} 'Pickpocket Modifier',\n   {104} 'Lockpicking Modifier',\n   {105} 'Sneaking Modifier',\n   {106} 'Alchemy Modifier',\n   {107} 'Speechcraft Modifier',\n   {108} 'Alteration Modifier',\n   {109} 'Conjuration Modifier',\n   {110} 'Destruction Modifier',\n   {111} 'Illusion Modifier',\n   {112} 'Restoration Modifier',\n   {113} 'Enchanting Modifier',\n   {114} 'One-Handed Skill Advance',\n   {115} 'Two-Handed Skill Advance',\n   {116} 'Marksman Skill Advance',\n   {117} 'Block Skill Advance',\n   {118} 'Smithing Skill Advance',\n   {119} 'Heavy Armor Skill Advance',\n   {120} 'Light Armor Skill Advance',\n   {121} 'Pickpocket Skill Advance',\n   {122} 'Lockpicking Skill Advance',\n   {123} 'Sneaking Skill Advance',\n   {124} 'Alchemy Skill Advance',\n   {125} 'Speechcraft Skill Advance',\n   {126} 'Alteration Skill Advance',\n   {127} 'Conjuration Skill Advance',\n   {128} 'Destruction Skill Advance',\n   {129} 'Illusion Skill Advance',\n   {130} 'Restoration Skill Advance',\n   {131} 'Enchanting Skill Advance',\n   {132} 'Left Weapon Speed Multiply',\n   {133} 'Dragon Souls',\n   {134} 'Combat Health Regen Multiply',\n   {135} 'One-Handed Power Modifier',\n   {136} 'Two-Handed Power Modifier',\n   {137} 'Marksman Power Modifier',\n   {138} 'Block Power Modifier',\n   {139} 'Smithing Power Modifier',\n   {140} 'Heavy Armor Power Modifier',\n   {141} 'Light Armor Power Modifier',\n   {142} 'Pickpocket Power Modifier',\n   {143} 'Lockpicking Power Modifier',\n   {144} 'Sneaking Power Modifier',\n   {145} 'Alchemy Power Modifier',\n   {146} 'Speechcraft Power Modifier',\n   {147} 'Alteration Power Modifier',\n   {148} 'Conjuration Power Modifier',\n   {149} 'Destruction Power Modifier',\n   {150} 'Illusion Power Modifier',\n   {151} 'Restoration Power Modifier',\n   {152} 'Enchanting Power Modifier',\n   {153} 'Dragon Rend',\n   {154} 'Attack Damage Mult',\n   {155} 'Heal Rate Mult',\n   {156} 'Magicka Rate Mult',\n   {157} 'Stamina Rate Mult',\n   {158} 'Werewolf Perks',\n   {159} 'Vampire Perks',\n   {160} 'Grab Actor Offset',\n   {161} 'Grabbed',\n   {162} 'Unknown 162',\n   {163} 'Reflect Damage'\n      ], [\n        -1, 'None'\n      ]);\n\n  wbSkillEnum :=\n    wbEnum([\n      'Unknown 1',\n      'Unknown 2',\n      'Unknown 3',\n      'Unknown 4',\n      'Unknown 5',\n      'Unknown 6',\n      'One Handed',\n      'Two Handed',\n      'Archery',\n      'Block',\n      'Smithing',\n      'Heavy Armor',\n      'Light Armor',\n      'Pickpocket',\n      'Lockpicking',\n      'Sneak',\n      'Alchemy',\n      'Speech',\n      'Alteration',\n      'Conjuration',\n      'Destruction',\n      'Illusion',\n      'Restoration',\n      'Enchanting'\n    ], [\n    -1, 'None'\n    ]);\n\n  wbCastEnum := wbEnum([\n    {0} 'Constant Effect',\n    {1} 'Fire and Forget',\n    {2} 'Concentration',\n    {3} 'Scroll'\n  ]);\n\n  wbTargetEnum := wbEnum([\n    {0} 'Self',\n    {1} 'Touch',\n    {2} 'Aimed',\n    {3} 'Target Actor',\n    {4} 'Target Location'\n  ]);\n\n  wbCastingSourceEnum := wbEnum([\n    'Left',\n    'Right',\n    'Voice',\n    'Instant'\n  ]);\n\n  wbCrimeTypeEnum :=\n    wbEnum([\n      'Steal',\n      'Pickpocket',\n      'Trespass',\n      'Attack',\n      'Murder',\n      'Escape Jail',\n      'Werewolf Transformation'\n    ], [\n      -1, 'None'\n    ]);\n\n  wbKeywordTypeEnum :=\n    wbEnum([\n      {00} 'None',\n      {01} 'Component Tech Level',\n      {02} 'Attach Point',\n      {03} 'Component Property',\n      {04} 'Instantiation Filter',\n      {05} 'Mod Association',\n      {06} 'Sound',\n      {07} 'Anim Archetype',\n      {08} 'Function Call',\n      {09} 'Recipe Filter',\n      {10} 'Attraction Type',\n      {11} 'Dialogue Subtype',\n      {12} 'Quest Target',\n      {13} 'Anim Flavor',\n      {14} 'Anim Gender',\n      {15} 'Anim Face',\n      {16} 'Quest Group',\n      {17} 'Anim Injured',\n      {18} 'Dispel Effect'\n    ]);\n\n  wbETYP := wbFormIDCk(ETYP, 'Equipment Type', [EQUP, NULL]);\n  wbETYPReq := wbFormIDCk(ETYP, 'Equipment Type', [EQUP, NULL], False, cpNormal, True);\n\n  wbFormTypeEnum := wbEnum([], [\n     0, 'Activator',\n     1, 'Armor',\n     2, 'Book',\n     3, 'Container',\n     4, 'Door',\n     5, 'Ingredient',\n     6, 'Light',\n     7, 'MiscItem',\n     8, 'Static',\n     9, 'Grass',\n    10, 'Tree',\n    12, 'Weapon',\n    13, 'Actor',\n    14, 'LeveledCharacter',\n    15, 'Spell',\n    16, 'Enchantment',\n    17, 'Potion',\n    18, 'LeveledItem',\n    19, 'Key',\n    20, 'Ammo',\n    21, 'Flora',\n    22, 'Furniture',\n    23, 'Sound Marker',\n    24, 'LandTexture',\n    25, 'CombatStyle',\n    26, 'LoadScreen',\n    27, 'LeveledSpell',\n    28, 'AnimObject',\n    29, 'WaterType',\n    30, 'IdleMarker',\n    31, 'EffectShader',\n    32, 'Projectile',\n    33, 'TalkingActivator',\n    34, 'Explosion',\n    35, 'TextureSet',\n    36, 'Debris',\n    37, 'MenuIcon',\n    38, 'FormList',\n    39, 'Perk',\n    40, 'BodyPartData',\n    41, 'AddOnNode',\n    42, 'MovableStatic',\n    43, 'CameraShot',\n    44, 'ImpactData',\n    45, 'ImpactDataSet',\n    46, 'Quest',\n    47, 'Package',\n    48, 'VoiceType',\n    49, 'Class',\n    50, 'Race',\n    51, 'Eyes',\n    52, 'HeadPart',\n    53, 'Faction',\n    54, 'Note',\n    55, 'Weather',\n    56, 'Climate',\n    57, 'ArmorAddon',\n    58, 'Global',\n    59, 'Imagespace',\n    60, 'Imagespace Modifier',\n    61, 'Encounter Zone',\n    62, 'Message',\n    63, 'Constructible Object',\n    64, 'Acoustic Space',\n    65, 'Ragdoll',\n    66, 'Script',\n    67, 'Magic Effect',\n    68, 'Music Type',\n    69, 'Static Collection',\n    70, 'Keyword',\n    71, 'Location',\n    72, 'Location Ref Type',\n    73, 'Footstep',\n    74, 'Footstep Set',\n    75, 'Material Type',\n    76, 'Actor Action',\n    77, 'Music Track',\n    78, 'Word of Power',\n    79, 'Shout',\n    80, 'Relationship',\n    81, 'Equip Slot',\n    82, 'Association Type',\n    83, 'Outfit',\n    84, 'Art Object',\n    85, 'Material Object',\n    87, 'Lighting Template',\n    88, 'Shader Particle Geometry',\n    89, 'Visual Effect',\n    90, 'Apparatus',\n    91, 'Movement Type',\n    92, 'Hazard',\n    93, 'SM Event Node',\n    94, 'Sound Descriptor',\n    95, 'Dual Cast Data',\n    96, 'Sound Category',\n    97, 'Soul Gem',\n    98, 'Sound Output Model',\n    99, 'Collision Layer',\n   100, 'Scroll',\n   101, 'ColorForm',\n   102, 'Reverb Parameters',\n   116, 'Terminal'\n  ]);\n\n  wbMiscStatEnum := wbEnum([], [\n    Int64($1EE71DBC), 'Animals Friended',\n    Int64($FCDD5011), 'Animals Killed',\n    Int64($366D84CF), 'Armor Improved',\n    Int64($8E20D7C9), 'Assaults',\n    Int64($B9B50725), 'Backstabs',\n    Int64($EA01A954), 'Bobbleheads Collected',\n    Int64($6932624D), 'Bright Ideas',\n    Int64($7FF0CC3B), 'Brotherhood of Steel Quests Completed',\n    Int64($FEA920AA), 'Buildings',\n    Int64($1F84743B), 'Caps Found',\n    Int64($9360004C), 'Chems Crafted',\n    Int64($B2A78B7A), 'Chems Taken',\n    Int64($53D9E9B5), 'Chests Looted',\n    Int64($1E258BEE), 'Computers Hacked',\n    Int64($3DE99B41), 'Cores Ejected',\n    Int64($737EAA97), 'Corpses Eaten',\n    Int64($40B11EFE), 'Creatures Killed',\n    Int64($4C4B8DF3), 'Creatures Killed DLC03',\n    Int64($22D5BA38), 'Critical Strikes',\n    Int64($3C626A90), 'Days Passed',\n    Int64($C5A52FD0), 'Days Survived',\n    Int64($45FDBB1C), 'DLC01 Quests Completed',\n    Int64($FA7CC7F9), 'DLC03 Locations Discovered',\n    Int64($AA444695), 'Dungeons Cleared',\n    Int64($F4E8FFD6), 'Fatman Deaths',\n    Int64($66DAF3CF), 'Fits of Rage',\n    Int64($554E59D5), 'Food',\n    Int64($E1EB3490), 'Food Cooked',\n    Int64($9311B22B), 'Food Eaten',\n    Int64($F947D866), 'Four Leaf Clovers',\n    Int64($7C586E7A), 'Fusion Cores Consumed',\n    Int64($2826309E), 'Game Difficulty',\n    Int64($A5EA7ABC), 'Grand Slams',\n    Int64($F5A36770), 'Grim Reaper Sprints',\n    Int64($52984AA4), 'Happiness',\n    Int64($FA024018), 'Hours Slept',\n    Int64($CAD2ECA1), 'Hours Waiting',\n    Int64($8CC5DAB6), 'HSAtomicCommand',\n    Int64($A2E4C1F2), 'HSAutomatron',\n    Int64($20F9993D), 'HSGrognak',\n    Int64($8D882844), 'HSJangles',\n    Int64($910B02C0), 'HSPipfall',\n    Int64($860E0723), 'HSRedMenace',\n    Int64($3FFA8658), 'HSZetaInvaders',\n    Int64($40CA9C83), 'Institute Quests Completed',\n    Int64($7D2E57C0), 'Intimidations',\n    Int64($FFE8010B), 'Investments Made',\n    Int64($9AF17D9D), 'Items Crafted DLC03',\n    Int64($CF48C0B9), 'Items Scrapped',\n    Int64($82F190C2), 'Items Stolen',\n    Int64($6D8671DD), 'Junk Collected',\n    Int64($110B8D2F), 'Legendary Enemies Killed',\n    Int64($8A24FDE2), 'Locations Discovered',\n    Int64($5829CC2E), 'Locks Picked',\n    Int64($7EA26C2D), 'Main Quests Completed',\n    Int64($493B803C), 'Mines Disarmed',\n    Int64($B1511B82), 'Minuteman Quests Completed',\n    Int64($98EE55DC), 'Misc Objectives Completed',\n    Int64($0F3315AC), 'Money Shots',\n    Int64($5E457DAC), 'Most Caps Carried',\n    Int64($D37C6909), 'Murders',\n    Int64($B91253A4), 'Mysterious Strabger Visits',\n    Int64($1DEEA18A), 'Nuka Cola Flavors Created',\n    Int64($9CE72536), 'Nuka World Creatures Killed',\n    Int64($EB0D60AC), 'Objects Built',\n    Int64($73AD915B), 'Pants Exploded',\n    Int64($53706A04), 'Paralyzing Punches',\n    Int64($9E78CEB3), 'People',\n    Int64($F22A8133), 'People Killed',\n    Int64($D3F632FF), 'Plants Harvested',\n    Int64($856FA4C1), 'PlayedFutureRetroHolotape',\n    Int64($F2BAC234), 'Pockets Picked',\n    Int64($AC69D9B9), 'Power',\n    Int64($0D7B8B16), 'Quests Completed',\n    Int64($0580BB9F), 'RadAway Taken',\n    Int64($D2960073), 'Rad-X Taken',\n    Int64($FDE20426), 'Railroad Quests Completed',\n    Int64($3CBF7E59), 'Ricochets',\n    Int64($01E1BC85), 'Robots Disabled',\n    Int64($2CA4ECC0), 'Robots Improved',\n    Int64($C8BC93BE), 'Robots Killed',\n    Int64($98D5710C), 'Sandman Kills',\n    Int64($B1AE4792), 'Side Quests Completed',\n    Int64($ACE470D7), 'Skill Books Read',\n    Int64($B556CC52), 'Sneak Attacks',\n    Int64($32D1B38F), 'Speach Successes',\n    Int64($5D6B18F1), 'Stimpacks Taken',\n    Int64($C5321BC5), 'Supply Lines Created',\n    Int64($3869002E), 'Survival Denied',\n    Int64($F9DEC209), 'Survival Level-Ups',\n    Int64($69AF5B9A), 'Synths Killed',\n    Int64($0A872FA3), 'Times Addicted',\n    Int64($7AEA9C2B), 'Trespasses',\n    Int64($13752285), 'Turrets Killed',\n    Int64($0B479511), 'Wasteland Whispers',\n    Int64($FCD0CCC3), 'Water',\n    Int64($61A5C5A9), 'Weapons Disarmed',\n    Int64($1D3BA844), 'Weapons Improved',\n    Int64($60A11697), 'Workshops Unlocked'\n  ]);\n\n  wbAdvanceActionEnum := wbEnum([\n    'Normal Usage',\n    'Power Attack',\n    'Bash',\n    'Lockpick Success',\n    'Lockpick Broken'\n  ]);\n\n  wbAlignmentEnum :=\n    wbEnum([\n      'Good',\n      'Neutral',\n      'Evil',\n      'Very Good',\n      'Very Evil'\n    ]);\n\n  wbAxisEnum :=\n    wbEnum([], [\n      88, 'X',\n      89, 'Y',\n      90, 'Z'\n    ]);\n\n  wbCriticalStageEnum :=\n    wbEnum([\n      'None',\n      'Goo Start',\n      'Goo End',\n      'Disintegrate Start',\n      'Disintegrate End'\n    ]);\n\n  wbStaggerEnum := wbEnum([\n    'None',\n    'Small',\n    'Medium',\n    'Large',\n    'Extra Large'\n  ]);\n\n  wbSexEnum := wbEnum(['Male','Female']);\n\n  wbEFID := wbFormIDCk(EFID, 'Base Effect', [MGEF]);\n\n  wbEFIT :=\n    wbStructSK(EFIT, [3, 4], '', [\n      wbFloat('Magnitude', cpNormal, True),\n      wbInteger('Area', itU32),\n      wbInteger('Duration', itU32)\n    ], cpNormal, True, nil, -1, wbEFITAfterLoad);\n\n  wbCTDA := wbRStruct('Condition', [\n    wbStruct(CTDA, '', [\n      wbInteger('Type', itU8, wbCtdaTypeToStr, wbCtdaTypeToInt, cpNormal, False, nil, wbCtdaTypeAfterSet),\n      wbByteArray('Unused', 3, cpIgnore, False, wbNeverShow),\n      wbUnion('Comparison Value', wbCTDACompValueDecider, [\n        wbFloat('Comparison Value - Float'),\n        wbFormIDCk('Comparison Value - Global', [GLOB])\n      ]),\n      wbInteger('Function', itU16, wbCTDAFunctionToStr, wbCTDAFunctionToInt),\n      wbByteArray('Unused', 2, cpIgnore, False, wbNeverShow),\n      wbUnion('Parameter #1', wbCTDAParam1Decider, [\n        { unknown }\n        wbByteArray('Unknown', 4),\n        { 0 ptNone}\n        wbByteArray('None', 4, cpIgnore),\n        { 1 ptInteger}\n        wbInteger('Integer', itS32),\n        { 2 ptFloat}\n        wbFloat('Float'),\n        { 3 ptActor}\n        wbFormIDCkNoReach('Actor', [NULL, PLYR, ACHR, REFR]),\n        { 4 ptActorBase}\n        wbFormIDCkNoReach('Actor Base', [NPC_]),\n        { 5 ptActorValue}\n        wbActorValue,\n        { 6 ptAdvanceAction}\n        wbInteger('Player Action', itU32, wbAdvanceActionEnum),\n        { 7 ptAlias}\n        wbInteger('Alias', itS32, wbConditionAliasToStr, wbStrToAlias),\n        { 8 ptAlignment}\n        wbInteger('Alignment', itU32, wbAlignmentEnum),\n        { 9 ptAssociationType}\n        wbFormIDCk('Association Type', [ASTP]),\n        {10 ptAxis}\n        wbInteger('Axis', itU32, wbAxisEnum),\n        {11 ptCastingSource}\n        wbInteger('Casting Type', itU32, wbCastingSourceEnum),\n        {12 ptCell}\n        wbFormIDCkNoReach('Cell', [CELL]),\n        {13 ptClass}\n        wbFormIDCkNoReach('Class', [CLAS]),\n        {14 ptCrimeType}\n        wbInteger('Crime Type', itU32, wbCrimeTypeEnum),\n        {15 ptCriticalStage}\n        wbInteger('Critical Stage', itU32, wbCriticalStageEnum),\n        {16 ptEncounterZone}\n        wbFormIDCkNoReach('Encounter Zone', [ECZN]),\n        {17 ptEquipType}\n        wbFormIDCkNoReach('Equip Type', [EQUP]),\n        {18 ptEvent}\n        wbInteger('Event', itU32, wbEventFunctionAndMemberToStr, wbEventFunctionAndMemberToInt),\n        {19 ptEventData}\n        wbFormID('Event Data'),\n        {20 ptFaction}\n        wbFormIDCkNoReach('Faction', [FACT]),\n        {21 ptFormList}\n        wbFormIDCkNoReach('Form List', [FLST]),\n        {22 ptFormType}\n        wbInteger('Form Type', itU32, wbFormTypeEnum),\n        {23 ptFurniture}\n        wbFormIDCkNoReach('Furniture', [FURN, FLST]),\n        {24 ptFurnitureAnim}\n        wbInteger('Furniture Anim', itU32, wbFurnitureAnimTypeEnum),\n        {25 ptFurnitureEntry}\n        wbInteger('Furniture Entry', itU32, wbEnum([], [$010000, 'Front', $020000, 'Behind', $040000, 'Right', $80000, 'Left', $100000, 'Up'])),\n        {26 ptGlobal}\n        wbFormIDCkNoReach('Global', [GLOB]),\n        {27 ptIdleForm}\n        wbFormIDCkNoReach('Idle', [IDLE]),\n        {28 ptInventoryObject}\n        wbFormIDCkNoReach('Inventory Object', sigBaseObjects),\n        {29 ptKeyword}\n        wbFormIDCkNoReach('Keyword', [KYWD, FLST, NULL]),\n        {30 ptLocation}\n        wbFormIDCkNoReach('Location', [LCTN]),\n        {31 ptMagicEffect}\n        wbFormIDCkNoReach('Base Effect', [MGEF]),\n        {32 ptMagicItem}\n        wbFormIDCkNoReach('Effect Item', [SPEL, ENCH, ALCH, INGR, SCRL]),\n        {33 ptMiscStat}\n        wbInteger('Misc Stat', itU32, wbMiscStatEnum),\n        {34 ptObjectReference}\n        wbFormIDCkNoReach('Object Reference', sigReferences),\n        {35 ptOwner}\n        wbFormIDCkNoReach('Owner', [NULL, FACT, NPC_]),\n        {36 ptPackage}\n        wbFormIDCkNoReach('Package', [PACK]),\n        {37 ptPackdata}\n        wbInteger('Packdata ID', itU32),\n        {38 ptPerk}\n        wbFormIDCkNoReach('Perk', [PERK]),\n        {39 ptQuest}\n        wbFormIDCkNoReach('Quest', [QUST]),\n        {40 ptQuestStage}\n        wbInteger('Quest Stage', itU32, wbCTDAParam2QuestStageToStr, wbCTDAParam2QuestStageToInt),\n        {41 ptRace}\n        wbFormIDCkNoReach('Race', [RACE]),\n        {42 ptReferencableObject}\n        wbFormIDCkNoReach('Referenceable Object', sigBaseObjects),\n        {43 ptRefType}\n        wbFormIDCkNoReach('Location Ref Type', [LCRT]),\n        {44 ptRegion}\n        wbFormIDCkNoReach('Region', [REGN]),\n        {45 ptScene}\n        wbFormIDCk('Scene', [NULL, SCEN]),\n        {46 ptSex}\n        wbInteger('Sex', itU32, wbSexEnum),\n        {47 ptShout}\n        wbFormIDCkNoReach('Shout', [SHOU]),\n        {48 ptVariableName}\n        wbByteArray('Variable Name (unused)', 4, cpIgnore),\n        {49 ptVATSValueFunction}\n        wbInteger('VATS Value Function', itU32, wbVATSValueFunctionEnum),\n        {50 ptVATSValueParam}\n        wbInteger('VATS Value Param (unused)', itU32),\n        {51 ptVoiceType}\n        wbFormIDCkNoReach('Voice Type', [VTYP, FLST]),\n        {52 ptWardState}\n        wbInteger('Ward State', itU32, wbWardStateEnum),\n        {53 ptWeather}\n        wbFormIDCkNoReach('Weather', [WTHR]),\n        {54 ptWorldspace}\n        wbFormIDCkNoReach('Worldspace', [WRLD, FLST]),\n        {55 ptDamageType}\n        wbFormIDCkNoReach('Damage Type', [DMGT, FLST])\n      ]),\n\n      wbUnion('Parameter #2', wbCTDAParam2Decider, [\n        { unknown }\n        wbByteArray('Unknown', 4),\n        { 0 ptNone}\n        wbByteArray('None', 4, cpIgnore),\n        { 1 ptInteger}\n        wbInteger('Integer', itS32),\n        { 2 ptFloat}\n        wbFloat('Float'),\n        { 3 ptActor}\n        wbFormIDCkNoReach('Actor', [NULL, PLYR, ACHR, REFR]),\n        { 4 ptActorBase}\n        wbFormIDCkNoReach('Actor Base', [NPC_]),\n        { 5 ptActorValue}\n        wbActorValue,\n        { 6 ptAdvanceAction}\n        wbInteger('Player Action', itU32, wbAdvanceActionEnum),\n        { 7 ptAlias}\n        wbInteger('Alias', itS32, wbConditionAliasToStr, wbStrToAlias),\n        { 8 ptAlignment}\n        wbInteger('Alignment', itU32, wbAlignmentEnum),\n        { 9 ptAssociationType}\n        wbFormIDCk('Association Type', [ASTP]),\n        {10 ptAxis}\n        wbInteger('Axis', itU32, wbAxisEnum),\n        {11 ptCastingSource}\n        wbInteger('Casting Type', itU32, wbCastingSourceEnum),\n        {12 ptCell}\n        wbFormIDCkNoReach('Cell', [CELL]),\n        {13 ptClass}\n        wbFormIDCkNoReach('Class', [CLAS]),\n        {14 ptCrimeType}\n        wbInteger('Crime Type', itU32, wbCrimeTypeEnum),\n        {15 ptCriticalStage}\n        wbInteger('Critical Stage', itU32, wbCriticalStageEnum),\n        {16 ptEncounterZone}\n        wbFormIDCkNoReach('Encounter Zone', [ECZN]),\n        {17 ptEquipType}\n        wbFormIDCkNoReach('Equip Type', [EQUP]),\n        {18 ptEvent}\n        wbInteger('Event', itU32, wbEventFunctionAndMemberToStr, wbEventFunctionAndMemberToInt),\n        {19 ptEventData}\n        wbFormID('Event Data'),\n        {20 ptFaction}\n        wbFormIDCkNoReach('Faction', [FACT]),\n        {21 ptFormList}\n        wbFormIDCkNoReach('Form List', [FLST]),\n        {22 ptFormType}\n        wbInteger('Form Type', itU32, wbFormTypeEnum),\n        {23 ptFurniture}\n        wbFormIDCkNoReach('Furniture', [FURN, FLST]),\n        {24 ptFurnitureAnim}\n        wbInteger('Furniture Anim', itU32, wbFurnitureAnimTypeEnum),\n        {25 ptFurnitureEntry}\n        wbInteger('Furniture Entry', itU32, wbEnum([], [$010000, 'Front', $020000, 'Behind', $040000, 'Right', $80000, 'Left', $100000, 'Up'])),\n        {26 ptGlobal}\n        wbFormIDCkNoReach('Global', [GLOB]),\n        {27 ptIdleForm}\n        wbFormIDCkNoReach('Idle', [IDLE]),\n        {28 ptInventoryObject}\n        wbFormIDCkNoReach('Inventory Object', sigBaseObjects),\n        {29 ptKeyword}\n        wbFormIDCkNoReach('Keyword', [KYWD, FLST, NULL]),\n        {30 ptLocation}\n        wbFormIDCkNoReach('Location', [LCTN]),\n        {31 ptMagicEffect}\n        wbFormIDCkNoReach('Base Effect', [MGEF]),\n        {32 ptMagicItem}\n        wbFormIDCkNoReach('Effect Item', [SPEL, ENCH, ALCH, INGR, SCRL]),\n        {33 ptMiscStat}\n        wbInteger('Misc Stat', itU32, wbMiscStatEnum),\n        {34 ptObjectReference}\n        wbFormIDCkNoReach('Object Reference', sigReferences),\n        {35 ptOwner}\n        wbFormIDCkNoReach('Owner', [NULL, FACT, NPC_]),\n        {36 ptPackage}\n        wbFormIDCkNoReach('Package', [PACK]),\n        {37 ptPackdata}\n        wbInteger('Packdata ID', itU32),\n        {38 ptPerk}\n        wbFormIDCkNoReach('Perk', [PERK]),\n        {39 ptQuest}\n        wbFormIDCkNoReach('Quest', [QUST]),\n        {40 ptQuestStage}\n        wbInteger('Quest Stage', itU32, wbCTDAParam2QuestStageToStr, wbCTDAParam2QuestStageToInt),\n        {41 ptRace}\n        wbFormIDCkNoReach('Race', [RACE]),\n        {42 ptReferencableObject}\n        wbFormIDCkNoReach('Referenceable Object', sigBaseObjects),\n        {43 ptRefType}\n        wbFormIDCkNoReach('Location Ref Type', [LCRT]),\n        {44 ptRegion}\n        wbFormIDCkNoReach('Region', [REGN]),\n        {45 ptScene}\n        wbFormIDCk('Scene', [NULL, SCEN]),\n        {46 ptSex}\n        wbInteger('Sex', itU32, wbSexEnum),\n        {47 ptShout}\n        wbFormIDCkNoReach('Shout', [SHOU]),\n        {48 ptVariableName}\n        wbByteArray('Variable Name (unused)', 4, cpIgnore),\n        {49 ptVATSValueFunction}\n        wbInteger('VATS Value Function', itU32, wbVATSValueFunctionEnum),\n        {50 ptVATSValueParam}\n        wbUnion('VATS Value Param', wbCTDAParam2VATSValueParamDecider, [\n         { 0} wbFormIDCkNoReach('Weapon', [WEAP]),\n         { 1} wbFormIDCkNoReach('Weapon List', [FLST], [WEAP]),\n         { 2} wbFormIDCkNoReach('Target', [NPC_]),\n         { 3} wbFormIDCkNoReach('Target List', [FLST], [NPC_]),\n         { 4} wbByteArray('Unknown', 4, cpIgnore),\n         { 5} wbInteger('Target Part', itS32, wbActorValueEnum),\n         { 6} wbInteger('VATS Action', itU32, wbEnum([\n                'Unarmed Attack',\n                'One Hand Melee Attack',\n                'Two Hand Melee Attack',\n                'Magic Attack',\n                'Ranged Attack',\n                'Reload',\n                'Crouch',\n                'Stand',\n                'Switch Weapon',\n                'Toggle Weapon Drawn',\n                'Heal',\n                'Player Death'\n          ])),\n         { 7} wbByteArray('Unknown', 4, cpIgnore),\n         { 8} wbByteArray('Unknown', 4, cpIgnore),\n         { 9} wbFormIDCkNoReach('Critical Effect', [SPEL]),\n         {10} wbFormIDCkNoReach('Critical Effect List', [FLST], [SPEL]),\n         {11} wbByteArray('Unknown', 4, cpIgnore),\n         {12} wbByteArray('Unknown', 4, cpIgnore),\n         {13} wbByteArray('Unknown', 4, cpIgnore),\n         {14} wbByteArray('Unknown', 4, cpIgnore),\n         {15} wbInteger('Weapon Type', itU32, wbWeaponAnimTypeEnum),\n         {16} wbByteArray('Unknown', 4, cpIgnore),\n         {17} wbByteArray('Unknown', 4, cpIgnore),\n         {18} wbInteger('Projectile Type', itU32, wbEnum([\n                'Missile',\n                'Lobber',\n                'Beam',\n                'Flame',\n                'Cone',\n                'Barrier',\n                'Arrow'\n              ])),\n         {19} wbInteger('Delivery Type', itU32, wbTargetEnum),\n         {20} wbInteger('Casting Type', itU32, wbCastEnum)\n        ]),\n        {51 ptVoiceType}\n        wbFormIDCkNoReach('Voice Type', [VTYP, FLST]),\n        {52 ptWardState}\n        wbInteger('Ward State', itU32, wbWardStateEnum),\n        {53 ptWeather}\n        wbFormIDCkNoReach('Weather', [WTHR]),\n        {54 ptWorldspace}\n        wbFormIDCkNoReach('Worldspace', [WRLD, FLST]),\n        {55 ptDamageType}\n        wbFormIDCkNoReach('Damage Type', [DMGT, FLST])\n      ]),\n      wbInteger('Run On', itU32, wbEnum([\n        { 0} 'Subject',\n        { 1} 'Target',\n        { 2} 'Reference',\n        { 3} 'Combat Target',\n        { 4} 'Linked Reference',\n        { 5} 'Quest Alias',\n        { 6} 'Package Data',\n        { 7} 'Event Data',\n        { 9} 'Command Target',\n        {10} 'Event Camera Ref',\n        {11} 'My Killer'\n      ]), cpNormal, False, nil, wbCTDARunOnAfterSet),\n      wbUnion('Reference', wbCTDAReferenceDecider, [\n        wbInteger('Unused', itU32, nil, cpIgnore),\n        wbFormIDCkNoReach('Reference', sigReferences, False)\n      ]),\n      wbInteger('Parameter #3', itS32, nil, cpNormal, False, nil, nil, -1)\n    ], cpNormal, False{, nil, 0, wbCTDAAfterLoad}),\n    wbString(CIS1, 'Parameter #1'),\n    wbString(CIS2, 'Parameter #2')\n  ], [], cpNormal);\n\n  wbCTDAs := wbRArray('Conditions', wbCTDA, cpNormal, False);\n  wbCTDAsCount := wbRArray('Conditions', wbCTDA, cpNormal, False, nil, wbCTDAsAfterSet);\n  wbCTDAsReq := wbRArray('Conditions', wbCTDA, cpNormal, True);\n  wbCTDAsReqCount := wbRArray('Conditions', wbCTDA, cpNormal, True, nil, wbCTDAsAfterSet);\n\n  wbICON := wbString(ICON, 'Inventory Image');\n  wbMICO := wbString(MICO, 'Message Icon');\n  wbPTRN := wbFormIDCk(PTRN, 'Preview Transform', [TRNS]);\n  wbNTRM := wbFormIDCk(NTRM, 'Native Terminal', [TERM]);\n  wbYNAM := wbFormIDCk(YNAM, 'Sound - Pick Up', [SNDR]);\n  wbZNAM := wbFormIDCk(ZNAM, 'Sound - Put Down', [SNDR]);\n  wbCUSD := wbFormIDCk(CUSD, 'Sound - Crafting', [SNDR]);\n  wbINRD := wbFormIDCk(INRD, 'Instance Naming', [INNR]);\n  wbPRPS := wbArrayS(PRPS, 'Properties', wbStructSK([0], 'Property', [\n    wbActorValue,\n    wbFloat('Value')\n  ]));\n  wbFLTR := wbString(FLTR, 'Filter');\n  wbAPPR := wbArray(APPR, 'Attach Parent Slots', wbFormIDCk('Keyword', [KYWD]));\n  wbFTYP := wbFormIDCk(FTYP, 'Forced Loc Ref Type', [LCRT]);\n  wbATTX := wbLString(ATTX, 'Activate Text Override', 0, cpTranslate);\n\n  wbMNAMFurnitureMarker := wbInteger(MNAM, 'Active Markers / Flags', itU32, wbFlags([\n    {0x00000001} 'Interaction Point 0',\n    {0x00000002} 'Interaction Point 1',\n    {0x00000004} 'Interaction Point 2',\n    {0x00000008} 'Interaction Point 3',\n    {0x00000010} 'Interaction Point 4',\n    {0x00000020} 'Interaction Point 5',\n    {0x00000040} 'Interaction Point 6',\n    {0x00000080} 'Interaction Point 7',\n    {0x00000100} 'Interaction Point 8',\n    {0x00000200} 'Interaction Point 9',\n    {0x00000400} 'Interaction Point 10',\n    {0x00000800} 'Interaction Point 11',\n    {0x00001000} 'Interaction Point 12',\n    {0x00002000} 'Interaction Point 13',\n    {0x00004000} 'Interaction Point 14',\n    {0x00008000} 'Interaction Point 15',\n    {0x00010000} 'Interaction Point 16',\n    {0x00020000} 'Interaction Point 17',\n    {0x00040000} 'Interaction Point 18',\n    {0x00080000} 'Interaction Point 19',\n    {0x00100000} 'Interaction Point 20',\n    {0x00200000} 'Interaction Point 21',\n    {0x00400000} 'Allow Awake Sound',\n    {0x00800000} 'Enter With Weapon Drawn',\n    {0x01000000} 'Play Anim When Full',\n    {0x02000000} 'Disables Activation',\n    {0x04000000} 'Is Perch',\n    {0x08000000} 'Must Exit to Talk',\n    {0x10000000} 'Use Static Avoid Node',\n    {0x20000000} 'Unknown 29',\n    {0x40000000} 'Has Model?',\n    {0x80000000} 'Unknown 31'\n  ]));\n\n  wbSNAMMarkerParams :=\n    wbArray(SNAM, 'Marker Paramaters', wbStruct('Marker', [\n      wbFloat('Offset X'),\n      wbFloat('Offset Y'),\n      wbFloat('Offset Z'),\n      wbFloat('Rotation Z', cpNormal, True, wbRotationFactor, wbRotationScale, nil, RadiansNormalize),\n      wbFormIDCk('Keyword', [KYWD, NULL]),\n      wbInteger('Entry Types', itU8, wbFlags([\n        'Front',\n        'Rear',\n        'Right',\n        'Left',\n        'Other',\n        'Unused 5',\n        'Unused 6',\n        'Unused 7'\n      ])),\n      wbByteArray('Unknown', 3)\n    ], cpNormal, False, nil, 4));\n\n  wbArmorPropertyEnum := wbEnum([\n    { 0} 'Enchantments',\n    { 1} 'BashImpactDataSet',\n    { 2} 'BlockMaterial',\n    { 3} 'Keywords',\n    { 4} 'Weight',\n    { 5} 'Value',\n    { 6} 'Rating',\n    { 7} 'AddonIndex',\n    { 8} 'BodyPart',\n    { 9} 'DamageTypeValue',\n    {10} 'ActorValues',\n    {11} 'Health',\n    {12} 'ColorRemappingIndex',\n    {13} 'MaterialSwaps'\n  ]);\n\n  wbActorPropertyEnum := wbEnum([\n    { 0} 'Keywords',\n    { 1} 'ForcedInventory',\n    { 2} 'XPOffset',\n    { 3} 'Enchantments',\n    { 4} 'ColorRemappingIndex',\n    { 5} 'MaterialSwaps'\n  ]);\n\n  wbWeaponPropertyEnum := wbEnum([\n    { 0} 'Speed',\n    { 1} 'Reach',\n    { 2} 'MinRange',\n    { 3} 'MaxRange',\n    { 4} 'AttackDelaySec',\n    { 5} 'Unknown 5',\n    { 6} 'OutOfRangeDamageMult',\n    { 7} 'SecondaryDamage',\n    { 8} 'CriticalChargeBonus',\n    { 9} 'HitBehaviour',\n    {10} 'Rank',\n    {11} 'Unknown 11',\n    {12} 'AmmoCapacity',\n    {13} 'Unknown 13',\n    {14} 'Unknown 14',\n    {15} 'Type',\n    {16} 'IsPlayerOnly',\n    {17} 'NPCsUseAmmo',\n    {18} 'HasChargingReload',\n    {19} 'IsMinorCrime',\n    {20} 'IsFixedRange',\n    {21} 'HasEffectOnDeath',\n    {22} 'HasAlternateRumble',\n    {23} 'IsNonHostile',\n    {24} 'IgnoreResist',\n    {25} 'IsAutomatic',\n    {26} 'CantDrop',\n    {27} 'IsNonPlayable',\n    {28} 'AttackDamage',\n    {29} 'Value',\n    {30} 'Weight',\n    {31} 'Keywords',\n    {32} 'AimModel',\n    {33} 'AimModelMinConeDegrees',\n    {34} 'AimModelMaxConeDegrees',\n    {35} 'AimModelConeIncreasePerShot',\n    {36} 'AimModelConeDecreasePerSec',\n    {37} 'AimModelConeDecreaseDelayMs',\n    {38} 'AimModelConeSneakMultiplier',\n    {39} 'AimModelRecoilDiminishSpringForce',\n    {40} 'AimModelRecoilDiminishSightsMult',\n    {41} 'AimModelRecoilMaxDegPerShot',\n    {42} 'AimModelRecoilMinDegPerShot',\n    {43} 'AimModelRecoilHipMult',\n    {44} 'AimModelRecoilShotsForRunaway',\n    {45} 'AimModelRecoilArcDeg',\n    {46} 'AimModelRecoilArcRotateDeg',\n    {47} 'AimModelConeIronSightsMultiplier',\n    {48} 'HasScope',\n    {49} 'ZoomDataFOVMult',\n    {50} 'FireSeconds',\n    {51} 'NumProjectiles',\n    {52} 'AttackSound',\n    {53} 'AttackSound2D',\n    {54} 'AttackLoop',\n    {55} 'AttackFailSound',\n    {56} 'IdleSound',\n    {57} 'EquipSound',\n    {58} 'UnEquipSound',\n    {59} 'SoundLevel',\n    {50} 'ImpactDataSet',\n    {61} 'Ammo',\n    {62} 'CritEffect',\n    {63} 'BashImpactDataSet',\n    {64} 'BlockMaterial',\n    {65} 'Enchantments',\n    {66} 'AimModelBaseStability',\n    {67} 'ZoomData',\n    {68} 'ZoomDataOverlay',\n    {69} 'ZoomDataImageSpace',\n    {70} 'ZoomDataCameraOffsetX',\n    {71} 'ZoomDataCameraOffsetY',\n    {72} 'ZoomDataCameraOffsetZ',\n    {73} 'EquipSlot',\n    {74} 'SoundLevelMult',\n    {75} 'NPCAmmoList',\n    {76} 'ReloadSpeed',\n    {77} 'DamageTypeValues',\n    {78} 'AccuracyBonus',\n    {79} 'AttackActionPointCost',\n    {80} 'OverrideProjectile',\n    {81} 'HasBoltAction',\n    {82} 'StaggerValue',\n    {83} 'SightedTransitionSeconds',\n    {84} 'FullPowerSeconds',\n    {85} 'HoldInputToPower',\n    {86} 'HasRepeatableSingleFire',\n    {87} 'MinPowerPerShot',\n    {88} 'ColorRemappingIndex',\n    {89} 'MaterialSwaps',\n    {90} 'CriticalDamageMult',\n    {91} 'FastEquipSound',\n    {92} 'DisableShells',\n    {93} 'HasChargingAttack',\n    {94} 'ActorValues'\n  ]);\n\n  wbObjectModProperties :=\n    wbArrayS('Properties', wbStructSK([4], 'Property', [\n      wbInteger('Value Type', itU8, wbEnum([\n        {0} 'Int',\n        {1} 'Float',\n        {2} 'Bool',\n        {3} 'Unknown 3',\n        {4} 'FormID,Int',\n        {5} 'Enum',\n        {6} 'FormID,Float'\n      ])),\n      wbByteArray('Unused', 3, cpIgnore),\n      wbUnion('Function Type', wbOMODDataFunctionTypeDecider, [\n        { Float }  wbInteger('Function Type', itU8, wbEnum(['SET', 'MUL+ADD', 'ADD'])),\n        { Bool }   wbInteger('Function Type', itU8, wbEnum(['SET', 'AND', 'OR'])),\n        { Enum }   wbInteger('Function Type', itU8, wbEnum(['SET'])),\n        { FormID } wbInteger('Function Type', itU8, wbEnum(['SET', 'REM', 'ADD']))\n      ]),\n      wbByteArray('Unused', 3, cpIgnore),\n      wbInteger('Property', itU16, wbObjectModPropertyToStr, wbObjectModPropertyToInt),\n      wbByteArray('Unused', 2, cpIgnore),\n      wbUnion('Value 1', wbOMODDataPropertyValue1Decider, [\n        { 0} wbByteArray('Value 1 - Unknown', 4),\n        { 1} wbInteger('Value 1 - Int', itU32),\n        { 2} wbFloat('Value 1 - Float'),\n        { 3} wbInteger('Value 1 - Bool', itU32, wbBoolEnum),\n        { 4} wbFormID('Value 1 - FormID'),\n        { 5} wbInteger('Value 1 - Enum', itU32),\n        { 6} wbInteger('Sound Level', itU32, wbSoundLevelEnum),\n        { 7} wbInteger('Stagger Value', itU32, wbStaggerEnum),\n        { 8} wbInteger('Hit Behaviour', itU32, wbHitBehaviourEnum)\n      ]),\n      wbUnion('Value 2', wbOMODDataPropertyValue2Decider, [\n        wbByteArray('Unused', 4, cpIgnore),\n        wbInteger('Value 2 - Int', itU32),\n        wbFloat('Value 2 - Float'),\n        wbInteger('Value 2 - Bool', itU32, wbBoolEnum)\n      ]),\n      wbFloat('Step')\n    ]), wbOMODDataPropertyCounter, cpNormal, False, nil, wbOMODpropertyAfterSet);\n\n  wbOBTSReq := wbStruct(OBTS, 'Object Mod Template Item', [\n    wbInteger('Include Count', itU32),  // fixed name for wbOMOD* handlers\n    wbInteger('Property Count', itU32), // fixed name for wbOMOD* handlers\n    wbInteger('Level Min', itU8),\n    wbByteArray('Unused', 1),\n    wbInteger('Level Max', itU8),\n    wbByteArray('Unused', 1),\n    wbInteger('ID', itS16),\n    wbInteger('Default', itU8, wbBoolEnum),\n    wbArray('Keywords', wbFormIDCk('Keyword', [KYWD, NULL]), -4),\n    wbInteger('Min Level For Ranks', itU8),\n    wbInteger('Alt Levels Per Tier', itU8),\n    wbArray('Includes', wbStruct('Include', [\n      wbFormIDCk('Mod', [OMOD]),\n      wbInteger('Attach Point Index', itU8),\n      wbInteger('Optional', itU8, wbBoolEnum),\n      wbInteger('Don''t Use All', itU8, wbBoolEnum)\n    ]), wbOMODDataIncludeCounter, cpNormal, False, nil, wbOMODincludeAfterSet),\n    wbObjectModProperties\n  ], cpNormal, True);\n\n  wbObjectTemplate := wbRStruct('Object Template', [\n    wbInteger(OBTE, 'Count', itU32, nil, cpBenign),\n    wbRArray('Combinations',\n      wbRStruct('Combination', [\n        wbEmpty(OBTF, 'Editor Only'),\n        wbFULL,\n        wbOBTSReq\n      ], [], cpNormal, False, nil, True),\n      cpNormal, False, nil, wbOBTSCombinationsAfterSet),\n    wbEmpty(STOP, 'Marker', cpNormal, True)\n  ], []);\n\n  wbBSMPSequence := wbRStructs('Bone Data', 'Data', [\n    wbInteger(BSMP, 'Gender', itU32, wbEnum(['Male', 'Female'])),\n    // should not be sorted!!!\n    wbRArray('Bones',\n      wbRStruct('Bone', [\n        wbString(BSMB, 'Name'),\n        wbArray(BSMS, 'Values', wbFloat('Value')),\n        wbUnknown(BMMP)\n      ], [])\n    )\n  ], []);\n\n  wbEffectsReq :=\n    wbRStructs('Effects', 'Effect', [\n      wbEFID,\n      wbEFIT,\n      wbCTDAs\n    ], [], cpNormal, True);\n\n  wbRecord(ACTI, 'Activator',\n    wbFlags(wbRecordFlagsFlags, wbFlagsList([\n      {0x00000002}  2, 'Never Fades',\n      {0x00000004}  4, 'Non Occluder',\n      {0x00000040}  6, 'Unknown 6',\n      {0x00000080}  7, 'Heading Marker',\n      {0x00000100}  8, 'Must Update Anims',\n      {0x00000200}  9, 'Hidden From Local Map',\n      {0x00000400} 10, 'Headtrack Marker',\n      {0x00000800} 11, 'Used as Platform',\n      {0x00001000} 13, 'Pack-In Use Only',\n      {0x00008000} 15, 'Has Distant LOD',\n      {0x00010000} 16, 'Random Anim Start',\n      {0x00020000} 17, 'Dangerous',\n      {0x00100000} 20, 'Ignore Object Interaction',\n      {0x00800000} 23, 'Is Marker',\n      {0x02000000} 25, 'Obstacle',\n      {0x04000000} 26, 'NavMesh Generation - Filter',\n      {0x08000000} 27, 'NavMesh Generation - Bounding Box',\n      {0x20000000} 29, 'Child Can Use',\n      {0x40000000} 30, 'NavMesh Generation - Ground'\n    ])), [\n    wbEDID,\n    wbVMAD,\n    wbOBNDReq,\n    wbPTRN,\n    wbFormIDCk(STCP, 'Sound', [STAG]),\n    wbFULL,\n    wbMODL,\n    wbDEST,\n    wbKSIZ,\n    wbKWDAs,\n    wbPRPS,\n    wbNTRM,\n    wbFTYP,\n    wbStruct(PNAM, 'Marker Color', [\n      wbInteger('Red', itU8),\n      wbInteger('Green', itU8),\n      wbInteger('Blue', itU8),\n      wbInteger('Unused', itU8)\n    ]),\n    wbFormIDCk(SNAM, 'Sound - Looping', [SNDR]),\n    wbFormIDCk(VNAM, 'Sound - Activation', [SNDR]),\n    wbFormIDCk(WNAM, 'Water Type', [WATR]),\n    wbATTX,\n    wbInteger(FNAM, 'Flags', itU16, wbFlags([\n      'No Displacement',\n      'Ignored by Sandbox',\n      'Unknown 2',\n      'Unknown 3',\n      'Is a Radio'\n    ])),\n    wbFormIDCk(KNAM, 'Interaction Keyword', [KYWD]),\n    wbStruct(RADR, 'Radio Receiver', [\n      wbFormIDCk('Sound Model', [SOPM, NULL]),\n      wbFloat('Frequency'),\n      wbFloat('Volume'),\n      wbInteger('Starts Active', itU8, wbBoolEnum),\n      wbInteger('No Signal Static', itU8, wbBoolEnum)\n    ], cpNormal, False, nil, 4),\n    wbCITC,\n    wbCTDAs,\n    wbNVNM\n  ], False, nil, cpNormal, False, nil, wbKeywordsAfterSet);\n\n  wbRecord(TACT, 'Talking Activator',\n    wbFlags(wbRecordFlagsFlags, wbFlagsList([\n      {0x00000200}  9, 'Hidden From Local Map',\n      {0x00010000} 16, 'Random Anim Start',\n      {0x00020000} 17, 'Radio Station'\n    ]), [17]), [\n    wbEDID,\n    wbVMAD,\n    wbOBNDReq,\n    wbFULL,\n    wbMODL,\n    wbDEST,\n    wbKSIZ,\n    wbKWDAs,\n    wbUnknown(PNAM, cpIgnore, True),\n    wbFormIDCk(SNAM, 'Looping Sound', [SNDR]),\n    wbUnknown(FNAM, cpIgnore, True),\n    wbFormIDCk(VNAM, 'Voice Type', [VTYP])\n  ], False, nil, cpNormal, False, nil, wbKeywordsAfterSet);\n\n  wbRecord(ALCH, 'Ingestible',\n    wbFlags(wbRecordFlagsFlags, wbFlagsList([\n      {0x20000000} 29, 'Medicine'\n    ])), [\n    wbEDID,\n    wbOBNDReq,\n    wbPTRN,\n    wbFULL,\n    wbKSIZ,\n    wbKWDAs,\n    wbMODL,\n    wbICON,\n    wbMICO,\n    wbYNAM,\n    wbZNAM,\n    wbETYP,\n    wbCUSD,\n    wbDEST,\n    wbDESC,\n    wbFloat(DATA, 'Weight', cpNormal, True),\n    wbStruct(ENIT, 'Effect Data', [\n      wbInteger('Value', itS32),\n      wbInteger('Flags', itU32, wbFlags([\n        {0x00000001} 'No Auto-Calc',\n        {0x00000002} 'Food Item',\n        {0x00000004} 'Unknown 3',\n        {0x00000008} 'Unknown 4',\n        {0x00000010} 'Unknown 5',\n\t\t\t\t{0x00000020} 'Unknown 6',\n\t\t\t\t{0x00000040} 'Unknown 7',\n\t\t\t\t{0x00000080} 'Unknown 8',\n\t\t\t\t{0x00000100} 'Unknown 9',\n\t\t\t\t{0x00000200} 'Unknown 10',\n\t\t\t\t{0x00000400} 'Unknown 11',\n\t\t\t\t{0x00000800} 'Unknown 12',\n\t\t\t\t{0x00001000} 'Unknown 13',\n\t\t\t\t{0x00002000} 'Unknown 14',\n\t\t\t\t{0x00004000} 'Unknown 15',\n\t\t\t\t{0x00008000} 'Unknown 16',\n\t\t\t\t{0x00010000} 'Medicine',\n\t\t\t\t{0x00020000} 'Poison'\n      ])),\n      wbFormID('Addiction'),\n      wbFloat('Addiction Chance'),\n      wbFormIDCk('Sound - Consume', [SNDR, NULL])\n    ], cpNormal, True),\n    wbLString(DNAM, 'Addiction Name', 0, cpTranslate),\n    wbEffectsReq\n  ], False, nil, cpNormal, False, wbRemoveEmptyKWDA, wbKeywordsAfterSet);\n\n  wbRecord(AMMO, 'Ammunition',\n    wbFlags(wbRecordFlagsFlags, wbFlagsList([\n      {0x00000004}  2, 'Non-Playable'\n    ])), [\n    wbEDID,\n    wbOBNDReq,\n    wbPTRN,\n    wbFULL,\n    wbMODL,\n    wbDEST,\n    wbYNAM,\n    wbZNAM,\n    wbDESC,\n    wbKSIZ,\n    wbKWDAs,\n    wbStruct(DATA, 'Data', [\n      wbInteger('Value', itU32),\n      wbFloat('Weight')\n    ], cpNormal, True, nil, 1),\n    wbStruct(DNAM, '', [\n      wbFormIDCk('Projectile', [PROJ, NULL]),\n      wbInteger('Flags', itU8, wbFlags([\n        {0x01} 'Ignores Normal Weapon Resistance',\n        {0x02} 'Non-Playable',\n        {0x04} 'Has Count Based 3D'\n      ])),\n      wbByteArray('Unused', 3),\n      wbFloat('Damage'),\n      wbInteger('Health', itU32)\n    ], cpNormal, True),\n    wbLStringKC(ONAM, 'Short Name', 0, cpTranslate),\n    wbString(NAM1, 'Casing Model'),\n    wbByteArray(NAM2, 'Texture Files Hashes', 0, cpIgnore, false, false, wbNeverShow)\n  ], False, nil, cpNormal, False, wbRemoveEmptyKWDA, wbKeywordsAfterSet);\n\n  wbRecord(ANIO, 'Animated Object',\n    wbFlags(wbRecordFlagsFlags, wbFlagsList([\n      {0x00000200}  9, 'Unknown 9'\n    ]), [9]), [\n    wbEDID,\n    wbMODL,\n    wbString(BNAM, 'Unload Event')\n  ]);\n\n  wbRecord(ARMO, 'Armor',\n    wbFlags(wbRecordFlagsFlags, wbFlagsList([\n      {0x00000004}  2, 'Non-Playable',\n      {0x00000040}  6, 'Shield',\n      {0x00000400} 10, 'Unknown 10',\n      {0x00008000} 15, 'Unknown 15'\n    ])), [\n    wbEDID,\n    wbVMAD,\n    wbOBNDReq,\n    wbPTRN,\n    wbFULL,\n    wbEITM,\n    wbRStruct('Male world model', [\n      wbString(MOD2, 'Model Filename'),\n      wbByteArray(MO2T, 'Texture Files Hashes', 0, cpIgnore, false, false, wbNeverShow),\n      wbMO2S\n    ], []),\n    wbString(ICON, 'Male Inventory Image'),\n    wbString(MICO, 'Male Message Icon'),\n    wbRStruct('Female world model', [\n      wbString(MOD4, 'Model Filename'),\n      wbByteArray(MO4T, 'Texture Files Hashes', 0, cpIgnore, false, false, wbNeverShow),\n      wbMO4S\n    ], []),\n    wbString(ICO2, 'Female Inventory Image'),\n    wbString(MIC2, 'Female Message Icon'),\n    wbBOD2,\n    wbDEST,\n    wbYNAM,\n    wbZNAM,\n    wbETYP,\n    wbFormIDCk(BIDS, 'Block Bash Impact Data Set', [IPDS, NULL]),\n    wbFormIDCk(BAMT, 'Alternate Block Material', [MATT, NULL]),\n    wbFormIDCk(RNAM, 'Race', [RACE]),\n    wbKSIZ,\n    wbKWDAs,\n    wbDESC,\n    wbINRD,\n    wbRArray('Models',\n      wbRStruct('Model', [\n        wbInteger(INDX, 'Addon Index', itU16),\n        wbFormIDCk(MODL, 'Armor Addon', [ARMA])\n      ], [])\n    ),\n    wbStruct(DATA, '', [\n      wbInteger('Value', itS32),\n      wbFloat('Weight'),\n      wbInteger('Health', itU32)\n    ], cpNormal, True),\n    wbStruct(FNAM, '', [\n      wbInteger('Armor Rating', itU16),\n      wbInteger('Base Addon Index', itU16),\n      wbInteger('Stagger Rating', itU8, wbStaggerEnum),\n      wbUnknown\n    ]),\n    wbArrayS(DAMA, 'Resistances', wbStructSK([0], 'Resistance', [\n      wbFormIDCk('Damage Type', [DMGT]),\n      wbInteger('Value', itU32)\n    ])),\n    wbFormIDCk(TNAM, 'Template Armor', [ARMO]),\n    wbAPPR,\n    wbObjectTemplate\n  ], False, nil, cpNormal, False, wbARMOAfterLoad, wbKeywordsAfterSet);\n\n  wbRecord(ARMA, 'Armor Addon',\n    wbFlags(wbRecordFlagsFlags, wbFlagsList([\n      {0x00000040}  6, 'No Underarmor Scaling',\n      {0x00000200}  9, 'Unknown 9',\n      {0x40000000} 30, 'Hi-Res 1st Person Only'\n    ])), [\n    wbEDID,\n    wbBOD2,\n    wbFormIDCk(RNAM, 'Race', [RACE]),\n    wbStruct(DNAM, 'Data', [\n      wbInteger('Male Priority', itU8),\n      wbInteger('Female Priority', itU8),\n      // essentialy a number of world models for different weights (Enabled = 2 models _0.nif and _1.nif)\n      wbInteger('Weight slider - Male', itU8, wbFlags([\n        {0x01} 'Unknown 0',\n        {0x02} 'Enabled'\n      ])),\n      wbInteger('Weight slider - Female', itU8, wbFlags([\n        {0x01} 'Unknown 0',\n        {0x02} 'Enabled'\n      ])),\n      wbByteArray('Unknown', 2),\n      wbInteger('Detection Sound Value', itU8),\n      wbByteArray('Unknown', 1),\n      wbFloat('Weapon Adjust')\n    ], cpNormal, True),\n    wbRStruct('Male world model', [\n      wbString(MOD2, 'Model Filename'),\n      wbByteArray(MO2T, 'Texture Files Hashes', 0, cpIgnore, false, false, wbNeverShow),\n      wbMO2S,\n      wbMO2C,\n      wbMO2F\n    ], [], cpNormal, False),\n    wbRStruct('Female world model', [\n      wbString(MOD3, 'Model Filename'),\n      wbByteArray(MO3T, 'Texture Files Hashes', 0, cpIgnore, false, false, wbNeverShow),\n      wbMO3S,\n      wbMO3C,\n      wbMO3F\n    ], []),\n    wbRStruct('Male 1st Person', [\n      wbString(MOD4, 'Model Filename'),\n      wbByteArray(MO4T, 'Texture Files Hashes', 0, cpIgnore, false, false, wbNeverShow),\n      wbMO4S,\n      wbMO4C,\n      wbMO4F\n    ], []),\n    wbRStruct('Female 1st Person', [\n      wbString(MOD5, 'Model Filename'),\n      wbByteArray(MO5T, 'Texture Files Hashes', 0, cpIgnore, false, false, wbNeverShow),\n      wbMO5S,\n      wbMO5C,\n      wbMO5F\n    ], []),\n    wbFormIDCK(NAM0, 'Male Skin Texture', [TXST, NULL]),\n    wbFormIDCK(NAM1, 'Female Skin Texture', [TXST, NULL]),\n    wbFormIDCK(NAM2, 'Male Skin Texture Swap List', [FLST, NULL]),\n    wbFormIDCK(NAM3, 'Female Skin Texture Swap List', [FLST, NULL]),\n    wbRArrayS('Additional Races', wbFormIDCK(MODL, 'Race', [RACE, NULL])),\n    wbFormIDCk(SNDD, 'Footstep Sound', [FSTS, NULL]),\n    wbFormIDCk(ONAM, 'Art Object', [ARTO]),\n    wbBSMPSequence\n  ], False, nil, cpNormal, False, wbARMAAfterLoad);\n\n  wbRecord(BOOK, 'Book', [\n    wbEDID,\n    wbVMAD,\n    wbOBNDReq,\n    wbPTRN,\n    wbFULL,\n    wbMODL,\n    wbICON,\n    wbMICO,\n    wbDESCreq,\n    wbDEST,\n    wbYNAM,\n    wbZNAM,\n    wbKSIZ,\n    wbKWDAs,\n    wbFormIDCk(FIMD, 'Featured Item Message', [MESG]),\n    wbStruct(DATA, 'Data', [\n      wbInteger('Value', itU32),\n      wbFloat('Weight')\n    ], cpNormal, True),\n    wbStruct(DNAM, '', [\n      wbInteger('Flags', itU8, wbFlags([\n        {0x01} 'Advance Actor Value',\n        {0x02} 'Can''t be Taken',\n        {0x04} 'Add Spell',\n        {0x08} 'Unknown 3',\n        {0x10} 'Add Perk'\n      ])),\n      wbUnion('Teaches', wbBOOKTeachesDecider, [\n        wbByteArray('Unused', 4),\n        wbFormIDCk('Actor Value', [AVIF, NULL]),\n        wbFormIDCk('Spell', [SPEL, NULL]),\n        wbFormIDCk('Perk', [PERK, NULL])\n      ]),\n      wbStruct('Text Offset' , [\n        wbInteger('X', itU32),\n        wbInteger('Y', itU32)\n      ])\n    ], cpNormal, True),\n    wbLString(CNAM, 'Description', 0, cpTranslate),\n    wbFormIDCk(INAM, 'Inventory Art', [STAT])\n  ], False, nil, cpNormal, False, nil, wbKeywordsAfterSet);\nend;\n\nprocedure DefineFO4c;\n\n  procedure ReferenceRecord(aSignature: TwbSignature; const aName: string);\n  begin\n    wbRecord(aSignature, aName,\n      wbFlags(wbRecordFlagsFlags, wbFlagsList([\n        {0x00000080}  7, 'Turn Off Fire',\n        {0x00000400} 10, 'Persistent',\n        {0x00000800} 11, 'Initially Disabled',\n        {0x10000000} 28, 'Reflected By Auto Water',\n        {0x20000000} 29, 'Don''t Havok Settle',\n        {0x40000000} 30, 'No Respawn'\n      ], True, True)), [\n      wbEDID,\n      wbVMAD,\n      wbFormIDCk(NAME, 'Projectile', [PROJ, HAZD]),\n      wbFormIDCk(XEZN, 'Encounter Zone', [ECZN]),\n      wbFloat(XHTW, 'Head-Tracking Weight'),\n      wbFloat(XFVC, 'Favor Cost'),\n      wbRArrayS('Reflected/Refracted By',\n        wbStructSK(XPWR, [0], 'Water', [\n          wbFormIDCk('Reference', [REFR]),\n          wbInteger('Type', itU32, wbFlags([\n            'Reflection',\n            'Refraction'\n          ]))\n        ], cpNormal, False, nil, 1)\n      ),\n      wbRArrayS('Linked References', wbStructSK(XLKR, [0], 'Linked Reference', [\n        wbFormIDCk('Keyword/Ref', [KYWD, PLYR, ACHR, REFR, PGRE, PHZD, PMIS, PARW, PBAR, PBEA, PCON, PFLA, NULL]),\n        wbFormIDCk('Ref', sigReferences)\n      ], cpNormal, False, nil, 1)),\n      wbRStruct('Activate Parents', [\n        wbInteger(XAPD, 'Flags', itU8, wbFlags([\n          'Parent Activate Only'\n        ], True)),\n        wbRArrayS('Activate Parent Refs',\n          wbStructSK(XAPR, [0], 'Activate Parent Ref', [\n            wbFormIDCk('Reference', sigReferences),\n            wbFloat('Delay')\n          ])\n        )\n      ], []),\n\n      wbFormIDCk(XASP, 'Unknown', [REFR]),\n      wbUnknown(XATP),\n      wbInteger(XAMC, 'Ammo Count', itU32),\n      wbEmpty(XLKT, 'Linked Ref Transient'),\n      wbFormIDCk(XLYR, 'Layer', [LAYR]),\n      wbFormIDCk(XMSP, 'Material Swap', [MSWP]),\n      wbFormIDCk(XRFG, 'Reference Group', [RFGP]),\n      wbUnknown(XCVR),\n      wbXESP,\n      wbXOWN,\n      wbXRNK,\n      wbFormIDCk(XEMI, 'Emittance', [LIGH, REGN]),\n      wbFormIDCk(XMBR, 'MultiBound Reference', [REFR]),\n      wbEmpty(XIS2, 'Ignored by Sandbox'),\n      wbArray(XLRT, 'Location Ref Type', wbFormIDCk('Ref', [LCRT, NULL])),\n      wbFormIDCk(XLRL, 'Location Reference', [LCRT, LCTN, NULL], False, cpBenignIfAdded),\n      wbXSCL,\n      wbXLOD,\n      wbDataPosRot,\n      wbString(MNAM, 'Comments')\n    ], True, wbPlacedAddInfo);\n  end;\n\nbegin\n{>>>\n  Skrim has its own ref record for every projectile type\n  PARW 'Arrow'\n  PBEA 'Beam'\n  PFLA 'Flame'\n  PCON 'Cone' (voice)\n  PBAR 'Barrier'\n  PGRE 'Traps'\n  PHZD 'Hazards'\n  I guess all of them have the same structure\n<<<}\n  ReferenceRecord(PARW, 'Placed Arrow');\n  ReferenceRecord(PBAR, 'Placed Barrier');\n  ReferenceRecord(PBEA, 'Placed Beam');\n  ReferenceRecord(PCON, 'Placed Cone/Voice');\n  ReferenceRecord(PFLA, 'Placed Flame');\n  ReferenceRecord(PGRE, 'Placed Projectile');\n  ReferenceRecord(PHZD, 'Placed Hazard');\n  ReferenceRecord(PMIS, 'Placed Missile');\n\n  wbRecord(CELL, 'Cell',\n    wbFlags(wbRecordFlagsFlags, wbFlagsList([\n      {0x00000400}  7, 'No Pre Vis',\n      {0x00000400} 10, 'Persistent',\n      {0x00020000} 17, 'Off Limits',\n      {0x00040000} 18, 'Compressed',\n      {0x00080000} 19, 'Can''t Wait'\n    ]), [18]), [\n    wbEDID,\n    wbFULL,\n    wbInteger(DATA, 'Flags', itU16, wbFlags([\n      {0x0001} 'Is Interior Cell',\n      {0x0002} 'Has Water',\n      {0x0004} 'Can''t Travel From Here',\n      {0x0008} 'No LOD Water',\n      {0x0010} 'Unknown 5',\n      {0x0020} 'Public Area',\n      {0x0040} 'Hand Changed',\n      {0x0080} 'Show Sky',\n      {0x0100} 'Use Sky Lighting',\n      {0x0200} 'Unknown 10',\n      {0x0400} 'Unknown 11',\n      {0x0800} 'Sunlight Shadows',\n      {0x1000} 'Distant LOD only',\n      {0x2000} 'Player Followers Can''t Travel Here',\n      {0x4000} 'Unknown 15',\n      {0x8000} 'Unknown 16'\n    ]), cpNormal, True, False, nil, wbCELLDATAAfterSet),\n    wbStruct(XCLC, 'Grid', [\n      wbInteger('X', itS32),\n      wbInteger('Y', itS32),\n      wbInteger('Force Hide Land', itU32, wbFlags([\n        'Quad 1',\n        'Quad 2',\n        'Quad 3',\n        'Quad 4'\n      ], True))\n    ], cpNormal, False, nil, 2),\n\n    wbByteArray(VISI, 'PreVis Files Timestamp', 2),\n    wbFormIDCk(RVIS, 'In PreVis File Of', [CELL]),\n    wbByteArray(PCMB, 'PreCombined Files Timestamp', 2),\n\n    wbStruct(XCLL, 'Lighting', [\n      wbByteColors('Ambient Color'),\n      wbByteColors('Directional Color'),\n      wbByteColors('Fog Color Near'),\n      wbFloat('Fog Near'),\n      wbFloat('Fog Far'),\n      wbInteger('Directional Rotation XY', itS32),\n      wbInteger('Directional Rotation Z', itS32),\n      wbFloat('Directional Fade'),\n      wbFloat('Fog Clip Distance'),\n      wbFloat('Fog Power'),\n      wbAmbientColors,\n      wbByteColors('Fog Color Far'),\n      wbFloat('Fog Max'),\n      wbFloat('Light Fade Begin'),\n      wbFloat('Light Fade End'),\n      wbInteger('Inherits', itU32, wbFlags([\n        {0x00000001} 'Ambient Color',\n        {0x00000002} 'Directional Color',\n        {0x00000004} 'Fog Color',\n        {0x00000008} 'Fog Near',\n        {0x00000010} 'Fog Far',\n        {0x00000020} 'Directional Rotation',\n        {0x00000040} 'Directional Fade',\n        {0x00000080} 'Clip Distance',\n        {0x00000100} 'Fog Power',\n        {0x00000200} 'Fog Max',\n        {0x00000400} 'Light Fade Distances'\n      ])),\n      wbFloat('Near Height Mid'),\n      wbFloat('Near Height Range'),\n      wbByteColors('Fog Color High Near'),\n      wbByteColors('Fog Color High Far'),\n      wbFloat('High Density Scale'),\n      wbFloat('Fog Near Scale'),\n      wbFloat('Fog Far Scale'),\n      wbFloat('Fog High Near Scale'),\n      wbFloat('Fog High Far Scale'),\n      wbFloat('Far Height Mid'),\n      wbFloat('Far Height Range')\n    ], cpNormal, False, nil, 11),\n\n    wbInteger(CNAM, 'Precombined Object Level XY', itU8),\n    wbInteger(ZNAM, 'Precombined Object Level Z', itU8),\n    wbByteArray(TVDT, 'Unknown', 0, cpNormal),\n    wbMaxHeightDataCELL,\n    wbFormIDCk(LTMP, 'Lighting Template', [LGTM, NULL], False, cpNormal, True),\n\n    {>>> XCLW sometimes has $FF7FFFFF and causes invalid floation point <<<}\n    wbFloat(XCLW, 'Water Height', cpNormal, False, 1, -1, nil, nil, 0, wbCELLXCLWGetConflictPriority),\n    wbArrayS(XCLR, 'Regions', wbFormIDCk('Region', [REGN])),\n    wbFormIDCk(XLCN, 'Location', [LCTN]),\n    wbByteArray(XWCN, 'Unknown', 0, cpIgnore), // leftover\n    wbStruct(XWCU, 'Water Velocity', [\n      wbFloat('X Offset'),\n      wbFloat('Y Offset'),\n      wbFloat('Z Offset'),\n      wbByteArray('Unknown', 4),\n      wbFloat('X Angle'),\n      wbFloat('Y Angle'),\n      wbFloat('Z Angle'),\n      wbByteArray('Unknown', 0)\n    ]),\n    wbFormIDCk(XCWT, 'Water', [WATR]),\n\n    {--- Ownership ---}\n    wbXOWN,\n    wbXRNK,\n\n    wbFormIDCk(XILL, 'Lock List', [FLST, NPC_]),\n\n    wbStruct(XILW, 'Exterior LOD', [\n      wbFormIDCk('Worldspace', [WRLD]),\n      wbFloat('Offset X'),\n      wbFloat('Offset Y'),\n      wbFloat('Offset Z')\n    ]),\n    wbString(XWEM, 'Water Environment Map'),\n    wbFormIDCk(XCCM, 'Sky/Weather from Region', [REGN]),\n    wbFormIDCk(XCAS, 'Acoustic Space', [ASPC]),\n    wbFormIDCk(XEZN, 'Encounter Zone', [ECZN]),\n    wbFormIDCk(XCMO, 'Music Type', [MUSC]),\n    wbFormIDCk(XCIM, 'Image Space', [IMGS]),\n    wbFormIDCk(XGDR, 'God Rays', [GDRY]),\n\n    // those can be sorted I think, but makes copying records very slow since some cells have over 22000+ entries\n    // DLC01Lair01 \"The Mechanist's Lair\" [CELL:010008A3]\n    wbArrayS(XPRI, 'Physics References', wbFormIDCk('Reference', [REFR, PGRE, PHZD, PMIS, PARW, PBAR, PBEA, PCON, PFLA])),\n    wbStruct(XCRI, 'Combined References', [\n      wbInteger('Meshes Count', itU32),\n      wbInteger('References Count', itU32),\n      wbArrayS('Meshes', wbInteger('Combined Mesh', itU32, wbCombinedMeshIDToStr, wbCombinedMeshIDToInt), wbCELLCombinedMeshesCounter, cpNormal, False, nil, wbCELLCombinedMeshesAfterSet),\n      wbArrayS('References',  wbStructSK([1, 0], 'Reference', [\n        wbFormIDCk('Reference', [REFR, PGRE, PHZD, PMIS, PARW, PBAR, PBEA, PCON, PFLA]),\n        wbInteger('Combined Mesh', itU32, wbCombinedMeshIDToStr, wbCombinedMeshIDToInt)\n      ]), wbCELLCombinedRefsCounter, cpNormal, False, nil, wbCELLCombinedRefsAfterSet)\n    ])\n  ], True, wbCellAddInfo, cpNormal, False{, wbCELLAfterLoad});\n\n  wbRecord(CLAS, 'Class', [\n    wbEDID,\n    wbFULLReq,\n    wbDESCReq,\n    wbICON,\n    wbPRPS,\n    wbStruct(DATA, 'Data', [\n      wbByteArray('Unknown', 4),\n      wbFloat('Bleedout Default')\n    ])\n  ]);\n\n  wbRecord(CLMT, 'Climate', [\n    wbEDID,\n    wbArrayS(WLST, 'Weather Types', wbStructSK([0], 'Weather Type', [\n      wbFormIDCk('Weather', [WTHR, NULL]),\n      wbInteger('Chance', itS32),\n      wbFormIDCk('Global', [GLOB, NULL])\n    ])),\n    wbString(FNAM, 'Sun Texture'),\n    wbString(GNAM, 'Sun Glare Texture'),\n    wbMODL,\n    wbStruct(TNAM, 'Timing', [\n      wbStruct('Sunrise', [\n        wbInteger('Begin', itU8, wbClmtTime),\n        wbInteger('End', itU8, wbClmtTime)\n      ]),\n      wbStruct('Sunset', [\n        wbInteger('Begin', itU8, wbClmtTime),\n        wbInteger('End', itU8, wbClmtTime)\n      ]),\n      wbInteger('Volatility', itU8),\n      wbInteger('Moons / Phase Length', itU8, wbClmtMoonsPhaseLength)\n    ], cpNormal, True)\n  ]);\n\n  wbRecord(SPGD, 'Shader Particle Geometry', [\n    wbEDID,\n    wbStruct(DATA, 'Data', [\n      wbFloat('Gravity Velocity'),\n      wbByteArray('Unknown', 4),\n      wbFloat('Rotation Velocity'),\n      wbByteArray('Unknown', 4),\n      wbFloat('Particle Size X'),\n      wbFloat('Center Offset Min'),\n      wbFloat('Particle Size Y'),\n      wbByteArray('Unknown', 4),\n      wbFloat('Center Offset Min'),\n      wbByteArray('Unknown', 4),\n      wbFloat('Center Offset Max'),\n      wbByteArray('Unknown', 4),\n      wbFloat('Initial Rotation'),\n      wbByteArray('Unknown', 4),\n      wbInteger('# of Subtextures X', itU32),\n      wbByteArray('Unknown', 4),\n      wbInteger('# of Subtextures Y', itU32),\n      wbByteArray('Unknown', 4),\n      wbInteger('Type', itU32, wbEnum([\n        'Rain',\n        'Snow'\n      ])),\n      wbByteArray('Unknown', 4),\n      wbInteger('Box Size', itU32),\n      wbByteArray('Unknown', 4),\n      wbFloat('Particle Density'),\n      wbUnknown\n    ], cpNormal, True, nil, 10),\n    wbString(MNAM, 'Particle Texture')\n  ]);\n\n  wbRecord(RFCT, 'Visual Effect', [\n    wbEDID,\n    wbStruct(DATA, 'Effect Data', [\n\t\t\twbFormIDCK('Effect Art', [ARTO, NULL]),\n      wbFormIDCK('Shader', [EFSH, NULL]),\n      wbInteger('Flags', itU32, wbFlags([\n        {0x00000001} 'Rotate to Face Target',\n        {0x00000002} 'Attach to Camera',\n        {0x00000004} 'Inherit Rotation'\n      ]))\n    ], cpNormal, True)\n  ]);\n\n  wbRecord(CONT, 'Container',\n    wbFlags(wbRecordFlagsFlags, wbFlagsList([\n      {0x00008000} 15, 'Has Distant LOD',\n      {0x00010000} 16, 'Random Anim Start',\n      {0x02000000} 25, 'Obstacle',\n      {0x04000000} 26, 'NavMesh Generation - Filter',\n      {0x08000000} 27, 'NavMesh Generation - Bounding Box',\n      {0x40000000} 30, 'NavMesh Generation - Ground'\n    ])), [\n    wbEDID,\n    wbVMAD,\n    wbOBNDReq,\n    wbPTRN,\n    wbFULL,\n    wbMODL,\n    wbCOCT,\n    wbCNTOs,\n    wbDEST,\n    wbStruct(DATA, '', [\n      wbInteger('Flags', itU8, wbFlags([\n        {0x01} 'Allow Sounds When Animation',\n        {0x02} 'Respawns',\n        {0x04} 'Show Owner'\n      ])),\n      wbFloat('Weight')\n    ], cpNormal, True),\n    wbKSIZ,\n    wbKWDAs,\n    wbFTYP,\n    wbPRPS,\n    wbNTRM,\n    wbFormIDCk(SNAM, 'Sound - Open', [SNDR]),\n    wbFormIDCk(QNAM, 'Sound - Close', [SNDR]),\n    wbFormIDCk(TNAM, 'Sound - Take All', [SNDR]),\n    wbFormIDCk(ONAM, 'Filter List', [FLST])\n  ], True, nil, cpNormal, False, nil, wbContainerAfterSet);\n\n  wbAIDT :=\n    wbStruct(AIDT, 'AI Data', [\n     {00} wbInteger('Aggression', itU8, wbEnum([\n            'Unaggressive',\n            'Aggressive',\n            'Very Aggressive',\n            'Frenzied'\n          ])),\n     {01} wbInteger('Confidence', itU8, wbEnum([\n            'Cowardly',\n            'Cautious',\n            'Average',\n            'Brave',\n            'Foolhardy'\n          ])),\n     {02} wbInteger('Energy Level', itU8),\n     {03} wbInteger('Responsibility', itU8, wbEnum([\n            'Any crime',\n            'Violence against enemies',\n            'Property crime only',\n            'No crime'\n          ])),\n     {04} wbInteger('Mood', itU8, wbEnum([\n            'Neutral',\n            'Angry',\n            'Fear',\n            'Happy',\n            'Sad',\n            'Surprised',\n            'Puzzled',\n            'Disgusted'\n          ])),\n          wbInteger('Assistance', itU8, wbEnum([\n            'Helps Nobody',\n            'Helps Allies',\n            'Helps Friends and Allies'\n          ])),\n          wbStruct('Aggro', [\n            wbInteger('Aggro Radius Behavior', itU8, wbBoolEnum),\n            wbInteger('Unknown', itU8),\n            wbInteger('Warn', itU32),\n            wbInteger('Warn/Attack', itU32),\n            wbInteger('Attack', itU32)\n          ]),\n          wbByteArray('Unknown', 4)\n    ], cpNormal, True, nil{wbActorTemplateUseAIData});\n\n  wbRecord(CSTY, 'Combat Style',\n    wbFlags(wbRecordFlagsFlags, wbFlagsList([\n      {0x00080000} 19, 'Allow Dual Wielding'\n    ])), [\n    wbEDID,\n    wbStruct(CSGD, 'General', [\n      wbFloat('Offensive Mult'),\n      wbFloat('Defensive Mult'),\n      wbFloat('Group Offensive Mult'),\n      wbFloat('Equipment Score Mult - Melee'),\n      wbFloat('Equipment Score Mult - Magic'),\n      wbFloat('Equipment Score Mult - Ranged'),\n      wbFloat('Equipment Score Mult - Shout'),\n      wbFloat('Equipment Score Mult - Unarmed'),\n      wbFloat('Equipment Score Mult - Staff'),\n      wbFloat('Avoid Threat Chance'),\n      wbFloat('Dodge Threat Chance'),\n      wbFloat('Evade Threat Chance')\n    ], cpNormal, True),\n    wbUnknown(CSMD, cpIgnore),\n    wbStruct(CSME, 'Melee', [\n      wbFloat('Attack Staggered Mult'),\n      wbFloat('Power Attack Staggered Mult'),\n      wbFloat('Power Attack Blocking Mult'),\n      wbFloat('Bash Mult'),\n      wbFloat('Bash Recoil Mult'),\n      wbFloat('Bash Attack Mult'),\n      wbFloat('Bash Power Attack Mult'),\n      wbFloat('Special Attack Mult'),\n      wbFloat('Block When Staggered Mult'),\n      wbFloat('Attack When Staggered Mult')\n    ], cpNormal, True, nil, 9),\n    wbFloat(CSRA, 'Ranged Accuracy Mult', cpNormal, True),\n    wbStruct(CSCR, 'Close Range', [\n      wbFloat('Dueling - Circle Mult'),\n      wbFloat('Dueling - Fallback Mult'),\n      wbFloat('Flanking - Flank Distance'),\n      wbFloat('Flanking - Stalk Time'),\n      wbFloat('Charging - Charge Distance'),\n      wbFloat('Charging - Throw Probability'),\n      wbFloat('Charging - Sprint Fast Probability'),\n      wbFloat('Charging - Sideswipe Probability'),\n      wbFloat('Charging - Disengane Probability'),\n      wbInteger('Charging - Throw Max Targets', itU32),\n      wbFloat('Flanking - Flank Variance')\n    ], cpNormal, True),\n    wbStruct(CSLR, 'Long Range', [\n      wbFloat('Strafe Mult'),\n      wbFloat('Adjust Range Mult'),\n      wbFloat('Crouch Mult'),\n      wbFloat('Wait Mult'),\n      wbFloat('Range Mult')\n    ], cpNormal, True, nil, 3),\n    wbFloat(CSCV, 'Cover Search Distance Mult', cpNormal, True),\n    wbStruct(CSFL, 'Flight', [\n      wbFloat('Hover Chance'),\n      wbFloat('Dive Bomb Chance'),\n      wbFloat('Ground Attack Chance'),\n      wbFloat('Hover Time'),\n      wbFloat('Ground Attack Time'),\n      wbFloat('Perch Attack Chance'),\n      wbFloat('Perch Attack Time'),\n      wbFloat('Flying Attack Chance')\n    ], cpNormal, True),\n    wbInteger(DATA, 'Flags', itU32, wbFlags([\n      {0x01} 'Dueling',\n      {0x02} 'Flanking',\n      {0x04} 'Allow Dual Wielding',\n      {0x08} 'Charging',\n      {0x10} 'Retarget Any Nearby Melee Target',\n      {0x20} 'Unknown 5'\n    ]), cpNormal, True)\n  ]);\nend;\n\nprocedure DefineFO4d;\nbegin\n  wbRecord(DIAL, 'Dialog Topic', [\n    wbEDID,\n    wbFULL,\n    wbFloat(PNAM, 'Priority', cpNormal, True, 1, -1, nil, nil, 50.0),\n    wbFormIDCk(BNAM, 'Branch', [DLBR]),\n    wbFormIDCk(QNAM, 'Quest', [QUST], False, cpNormal, False),\n    wbFormIDCk(KNAM, 'Keyword', [KYWD]),\n    wbStruct(DATA, 'Data', [\n      // this should not be named Flags since TwbFile.BuildReachable\n      // expects Top-Level flag here from FNV\n      wbInteger('Topic Flags', itU8, wbFlags([\n        'Do All Before Repeating',\n        'Unknown 1',\n        'Unknown 2'\n      ]), cpNormal, True),\n      wbInteger('Category', itU8, wbEnum([\n        {0} 'Player',\n        {1} 'Command',\n        {2} 'Scene',\n        {3} 'Combat',\n        {4} 'Favor',\n        {5} 'Detection',\n        {6} 'Service',\n        {7} 'Miscellaneous'\n      ])),\n      wbInteger('Subtype', itU16, wbEnum([\n        { 0} 'Custom',\n        { 1} 'ForceGreet',\n        { 2} 'Rumors',\n        { 3} 'Custom',\n        { 4} 'Call',\n        { 5} 'Follow',\n        { 6} 'Move',\n        { 7} 'Attack',\n        { 8} 'Inspect',\n        { 9} 'Retrieve',\n        {10} 'Stay',\n        {11} 'Release',\n        {12} 'ShowRelationships',\n        {13} 'Reject',\n        {14} 'Heal',\n        {15} 'Assign',\n        {16} 'Enter',\n        {17} 'Custom',\n        {18} 'Show',\n        {19} 'Agree',\n        {20} 'Refuse',\n        {21} 'ExitFavorState',\n        {22} 'MoralRefusal',\n        {23} 'Trade',\n        {24} 'PathingRefusal',\n        {25} 'Attack',\n        {26} 'PowerAttack',\n        {27} 'Bash',\n        {28} 'Hit',\n        {29} 'Flee',\n        {30} 'BleedOut',\n        {31} 'AvoidThreat',\n        {32} 'Death',\n        {33} 'Block',\n        {34} 'Taunt',\n        {35} 'ThrowGrenade',\n        {36} 'AllyKilled',\n        {37} 'OrderFallback',\n        {38} 'OrderMoveUp',\n        {39} 'OrderFlank',\n        {40} 'OrderTakeCover',\n        {41} 'Retreat',\n        {42} 'CoverMe',\n        {43} 'SuppressiveFire',\n        {44} 'CrippledLimb',\n        {45} 'PairedAttack',\n        {46} 'Steal',\n        {47} 'Yield',\n        {48} 'AcceptYield',\n        {49} 'PickpocketCombat',\n        {50} 'Assault',\n        {51} 'Murder',\n        {52} 'AssaultNC',\n        {53} 'MurderNC',\n        {54} 'PickpocketNC',\n        {55} 'StealFromNC',\n        {56} 'TrespassAgainstNC',\n        {57} 'Trespass',\n        {58} 'UNUSED01',\n        {59} 'VoicePowerStartShort',\n        {60} 'VoicePowerStartLong',\n        {61} 'VoicePowerEndShort',\n        {62} 'VoicePowerEndLong',\n        {63} 'AlertIdle',\n        {64} 'LostIdle',\n        {65} 'NormalToAlert',\n        {66} 'NormalToCombat',\n        {67} 'NormalToLost',\n        {68} 'AlertToNormal',\n        {69} 'AlertToCombat',\n        {70} 'CombatToNormal',\n        {71} 'CombatToLost',\n        {72} 'LostToNormal',\n        {73} 'LostToCombat',\n        {74} 'DetectFriendDie',\n        {75} 'ServiceRefusal',\n        {76} 'Repair',\n        {77} 'Travel',\n        {78} 'Training',\n        {79} 'BarterExit',\n        {80} 'RepairExit',\n        {81} 'Recharge',\n        {82} 'RechargeExit',\n        {83} 'TrainingExit',\n        {84} 'ObserveCombat',\n        {85} 'NoticeCorpse',\n        {86} 'TimeToGo',\n        {87} 'Goodbye',\n        {88} 'Hello',\n        {89} 'SwingMeleeWeapon',\n        {90} 'ShootBow',\n        {91} 'ZKeyObject',\n        {92} 'Jump',\n        {93} 'KnockOverObject',\n        {94} 'DestroyObject',\n        {95} 'StandonFurniture',\n        {96} 'LockedObject',\n        {97} 'PickpocketTopic',\n        {98} 'PursueIdleTopic',\n        {99} 'SharedInfo',\n       {100} 'SceneChoice',\n       {101} 'PlayerCastProjectileSpell',\n       {102} 'PlayerCastSelfSpell',\n       {103} 'PlayerShout',\n       {104} 'Idle',\n       {105} 'EnterSprintBreath',\n       {106} 'EnterBowZoomBreath',\n       {107} 'ExitBowZoomBreath',\n       {108} 'ActorCollidewithActor',\n       {109} 'PlayerinIronSights',\n       {110} 'OutofBreath',\n       {111} 'CombatGrunt',\n       {112} 'LeaveWaterBreath',\n       {113} 'ImpatientPostitive',\n       {114} 'ImpatientNegative',\n       {115} 'ImpatientNeutral',\n       {116} 'ImpatientQuestion',\n       {117} 'WaitingForPlayerInput',\n       {118} 'Greeting',\n       {119} 'PlayerActivateDoor',\n       {120} 'PlayerActivateTerminals',\n       {121} 'PlayerActivateFurniture',\n       {122} 'PlayerActivateActivators',\n       {123} 'PlayerActivateContainer',\n       {124} 'PlayerAquireFeaturedItem'\n      ]))\n    ]),\n    wbString(SNAM, 'Subtype Name', 4),\n    wbInteger(TIFC, 'Info Count', itU32, nil, cpBenign)\n  ]);\n\n  wbRecord(DOOR, 'Door',\n    wbFlags(wbRecordFlagsFlags, wbFlagsList([\n      {0x00000010}  4, 'Non Occluder',\n      {0x00008000} 15, 'Has Distant LOD',\n      {0x00010000} 16, 'Random Anim Start',\n      {0x00800000} 23, 'Is Marker'\n    ])), [\n    wbEDID,\n    wbVMAD,\n    wbOBNDReq,\n    wbPTRN,\n    wbFULL,\n    wbMODL,\n    wbDEST,\n    wbKSIZ,\n    wbKWDAs,\n    wbNTRM,\n    wbFormIDCk(SNAM, 'Sound - Open', [SNDR]),\n    wbFormIDCk(ANAM, 'Sound - Close', [SNDR]),\n    wbFormIDCk(BNAM, 'Sound - Loop', [SNDR]),\n    wbInteger(FNAM, 'Flags', itU8, wbFlags([\n      '',\n      'Automatic',\n      'Hidden',\n      'Minimal Use',\n      'Sliding',\n      'Do Not Open in Combat Search',\n      'No \"To\" Text'\n    ]), cpNormal, True),\n    wbLStringKC(ONAM, 'Alternate Text - Open', 0, cpTranslate),\n    wbLStringKC(CNAM, 'Alternate Text - Close', 0, cpTranslate)\n  ]);\n\n  wbBlendModeEnum := wbEnum([\n    '',\n    'Zero',\n    'One',\n    'Source Color',\n    'Source Inverse Color',\n    'Source Alpha',\n    'Source Inverted Alpha',\n    'Dest Alpha',\n    'Dest Inverted Alpha',\n    'Dest Color',\n    'Dest Inverse Color',\n    'Source Alpha SAT'\n  ]);\n\n  wbBlendOpEnum := wbEnum([\n    '',\n    'Add',\n    'Subtract',\n    'Reverse Subtract',\n    'Minimum',\n    'Maximum'\n  ]);\n\n  wbZTestFuncEnum := wbEnum([\n    '',\n    '',\n    '',\n    'Equal To',\n    '',\n    'Greater Than',\n    '',\n    'Greater Than or Equal To'\n  ]);\n\n  wbRecord(EFSH, 'Effect Shader', [\n    wbEDID,\n    wbString(ICON, 'Fill Texture'),\n    wbString(ICO2, 'Particle Shader Texture'),\n    wbString(NAM7, 'Holes Texture'),\n    wbString(NAM8, 'Membrane Palette Texture'),\n    wbString(NAM9, 'Particle Palette Texture'),\n    wbUnknown(DATA),  // if form version < 62, ignored otherwise\n    // format depends on Form Version (appear with form version 62, changed in form version 106), different for older records starting from the first field\n    wbUnion(DNAM, '', wbEFSHFormatDecider, [\n      wbStruct('Data', [\n        wbInteger('Membrane Shader - Source Blend Mode', itU32, wbBlendModeEnum),\n        wbInteger('Membrane Shader - Blend Operation', itU32, wbBlendOpEnum),\n        wbInteger('Membrane Shader - Z Test Function', itU32, wbZTestFuncEnum),\n        wbByteColors('Fill/Texture Effect - Color Key 1'),\n        wbFloat('Fill/Texture Effect - Alpha Fade In Time'),\n        wbFloat('Fill/Texture Effect - Full Alpha Time'),\n        wbFloat('Fill/Texture Effect - Alpha Fade Out Time'),\n        wbFloat('Fill/Texture Effect - Presistent Alpha Ratio'),\n        wbFloat('Fill/Texture Effect - Alpha Pulse Amplitude'),\n        wbFloat('Fill/Texture Effect - Alpha Pulse Frequency'),\n        wbFloat('Fill/Texture Effect - Texture Animation Speed (U)'),\n        wbFloat('Fill/Texture Effect - Texture Animation Speed (V)'),\n        wbFloat('Edge Effect - Fall Off'),\n        wbByteColors('Edge Effect - Color'),\n        wbFloat('Edge Effect - Alpha Fade In Time'),\n        wbFloat('Edge Effect - Full Alpha Time'),\n        wbFloat('Edge Effect - Alpha Fade Out Time'),\n        wbFloat('Edge Effect - Persistent Alpha Ratio'),\n        wbFloat('Edge Effect - Alpha Pulse Amplitude'),\n        wbFloat('Edge Effect - Alpha Pulse Frequency'),\n        wbFloat('Fill/Texture Effect - Full Alpha Ratio'),\n        wbFloat('Edge Effect - Full Alpha Ratio'),\n        wbInteger('Membrane Shader - Dest Blend Mode', itU32, wbBlendModeEnum),\n        wbFloat('Holes Animation - Start Time'),\n        wbFloat('Holes Animation - End Time'),\n        wbFloat('Holes Animation - Start Value'),\n        wbFloat('Holes Animation - End Value'),\n        wbFormIDCk('Ambient Sound', [SNDR, NULL]),\n        wbByteColors('Fill/Texture Effect - Color Key 2'),\n        wbByteColors('Fill/Texture Effect - Color Key 3'),\n        wbInteger('Unknown', itU8),\n        wbStruct('Fill/Texture Effect - Color Key Scale/Time', [\n          wbFloat('Color Key 1 - Scale'),\n          wbFloat('Color Key 2 - Scale'),\n          wbFloat('Color Key 3 - Scale'),\n          wbFloat('Color Key 1 - Time'),\n          wbFloat('Color Key 2 - Time'),\n          wbFloat('Color Key 3 - Time')\n        ]),\n        wbInteger('Flags', itU32, wbFlags([\n          'No Membrane Shader',\n          'Membrane Grayscale Color',\n          'Membrane Grayscale Alpha',\n          'No Particle Shader',\n          'Edge Effect - Inverse',\n          'Affect Skin Only',\n          'Texture Effect - Ignore Alpha',\n          'Texture Effect - Project UVs',\n          'Ignore Base Geometry Alpha',\n          'Texture Effect - Lighting',\n          'Texture Effect - No Weapons',\n          'Use Alpha Sorting',\n          'Prefer Dismembered Limbs',\n          'Unknown 13',\n          'Unknown 14',\n          'Particle Animated',\n          'Particle Grayscale Color',\n          'Particle Grayscale Alpha',\n          'Unknown 18',\n          'Unknown 19',\n          'Unknown 20',\n          'Unknown 21',\n          'Unknown 22',\n          'Unknown 23',\n          'Use Blood Geometry (Weapons Only)'\n        ])),\n        wbFloat('Fill/Texture Effect - Texture Scale (U)'),\n        wbFloat('Fill/Texture Effect - Texture Scale (V)')\n      ]),\n      wbStruct('Data (old format)', [\n        wbByteArray('Unknown', 1),\n        wbInteger('Membrane Shader - Source Blend Mode', itU32, wbBlendModeEnum),\n        wbInteger('Membrane Shader - Blend Operation', itU32, wbBlendOpEnum),\n        wbInteger('Membrane Shader - Z Test Function', itU32, wbZTestFuncEnum),\n        wbByteColors('Fill/Texture Effect - Color Key 1'),\n        wbFloat('Fill/Texture Effect - Alpha Fade In Time'),\n        wbFloat('Fill/Texture Effect - Full Alpha Time'),\n        wbFloat('Fill/Texture Effect - Alpha Fade Out Time'),\n        wbFloat('Fill/Texture Effect - Presistent Alpha Ratio'),\n        wbFloat('Fill/Texture Effect - Alpha Pulse Amplitude'),\n        wbFloat('Fill/Texture Effect - Alpha Pulse Frequency'),\n        wbFloat('Fill/Texture Effect - Texture Animation Speed (U)'),\n        wbFloat('Fill/Texture Effect - Texture Animation Speed (V)'),\n        wbFloat('Edge Effect - Fall Off'),\n        wbByteColors('Edge Effect - Color'),\n        wbFloat('Edge Effect - Alpha Fade In Time'),\n        wbFloat('Edge Effect - Full Alpha Time'),\n        wbFloat('Edge Effect - Alpha Fade Out Time'),\n        wbFloat('Edge Effect - Persistent Alpha Ratio'),\n        wbFloat('Edge Effect - Alpha Pulse Amplitude'),\n        wbFloat('Edge Effect - Alpha Pulse Frequency'),\n        wbFloat('Fill/Texture Effect - Full Alpha Ratio'),\n        wbFloat('Edge Effect - Full Alpha Ratio'),\n        wbInteger('Membrane Shader - Dest Blend Mode', itU32, wbBlendModeEnum),\n        wbInteger('Particle Shader - Source Blend Mode', itU32, wbBlendModeEnum),\n        wbInteger('Particle Shader - Blend Operation', itU32, wbBlendOpEnum),\n        wbInteger('Particle Shader - Z Test Function', itU32, wbZTestFuncEnum),\n        wbInteger('Particle Shader - Dest Blend Mode', itU32, wbBlendModeEnum),\n        wbFloat('Particle Shader - Particle Birth Ramp Up Time'),\n        wbFloat('Particle Shader - Full Particle Birth Time'),\n        wbFloat('Particle Shader - Particle Birth Ramp Down Time'),\n        wbFloat('Particle Shader - Full Particle Birth Ratio'),\n        wbFloat('Particle Shader - Persistant Particle Count'),\n        wbFloat('Particle Shader - Particle Lifetime'),\n        wbFloat('Particle Shader - Particle Lifetime +/-'),\n        wbFloat('Particle Shader - Initial Speed Along Normal'),\n        wbFloat('Particle Shader - Acceleration Along Normal'),\n        wbFloat('Particle Shader - Initial Velocity #1'),\n        wbFloat('Particle Shader - Initial Velocity #2'),\n        wbFloat('Particle Shader - Initial Velocity #3'),\n        wbFloat('Particle Shader - Acceleration #1'),\n        wbFloat('Particle Shader - Acceleration #2'),\n        wbFloat('Particle Shader - Acceleration #3'),\n        wbFloat('Particle Shader - Scale Key 1'),\n        wbFloat('Particle Shader - Scale Key 2'),\n        wbFloat('Particle Shader - Scale Key 1 Time'),\n        wbFloat('Particle Shader - Scale Key 2 Time'),\n        wbByteColors('Color Key 1 - Color'),\n        wbByteColors('Color Key 2 - Color'),\n        wbByteColors('Color Key 3 - Color'),\n        wbFloat('Color Key 1 - Color Alpha'),\n        wbFloat('Color Key 2 - Color Alpha'),\n        wbFloat('Color Key 3 - Color Alpha'),\n        wbFloat('Color Key 1 - Color Key Time'),\n        wbFloat('Color Key 2 - Color Key Time'),\n        wbFloat('Color Key 3 - Color Key Time'),\n        wbFloat('Particle Shader - Initial Speed Along Normal +/-'),\n        wbFloat('Particle Shader - Initial Rotation (deg)'),\n        wbFloat('Particle Shader - Initial Rotation (deg) +/-'),\n        wbFloat('Particle Shader - Rotation Speed (deg/sec)'),\n        wbFloat('Particle Shader - Rotation Speed (deg/sec) +/-'),\n        wbFormIDCk('Addon Models', [DEBR, NULL]),\n        wbFloat('Holes - Start Time'),\n        wbFloat('Holes - End Time'),\n        wbFloat('Holes - Start Val'),\n        wbFloat('Holes - End Val'),\n        wbFloat('Edge Width (alpha units)'),\n        wbByteColors('Edge Color'),\n        wbFloat('Explosion Wind Speed'),\n        wbInteger('Texture Count U', itU32),\n        wbInteger('Texture Count V', itU32),\n        wbFloat('Addon Models - Fade In Time'),\n        wbFloat('Addon Models - Fade Out Time'),\n        wbFloat('Addon Models - Scale Start'),\n        wbFloat('Addon Models - Scale End'),\n        wbFloat('Addon Models - Scale In Time'),\n        wbFloat('Addon Models - Scale Out Time'),\n        wbFormIDCk('Ambient Sound', [SNDR, NULL]),\n        wbByteColors('Fill/Texture Effect - Color Key 2'),\n        wbByteColors('Fill/Texture Effect - Color Key 3'),\n        wbStruct('Fill/Texture Effect - Color Key Scale/Time', [\n          wbFloat('Color Key 1 - Scale'),\n          wbFloat('Color Key 2 - Scale'),\n          wbFloat('Color Key 3 - Scale'),\n          wbFloat('Color Key 1 - Time'),\n          wbFloat('Color Key 2 - Time'),\n          wbFloat('Color Key 3 - Time')\n        ]),\n        wbFloat('Color Scale'),\n        wbFloat('Birth Position Offset'),\n        wbFloat('Birth Position Offset Range +/-'),\n        wbStruct('Particle Shader Animated', [\n          wbInteger('Start Frame', itU32),\n          wbInteger('Start Frame Variation', itU32),\n          wbInteger('End Frame', itU32),\n          wbInteger('Loop Start Frame', itU32),\n          wbInteger('Loop Start Variation', itU32),\n          wbInteger('Frame Count', itU32),\n          wbInteger('Frame Count Variation', itU32)\n        ]),\n        wbInteger('Flags', itU32, wbFlags([\n          'No Membrane Shader',\n          'Membrane Grayscale Color',\n          'Membrane Grayscale Alpha',\n          'No Particle Shader',\n          'Edge Effect Inverse',\n          'Affect Skin Only',\n          'Ignore Alpha',\n          'Project UVs',\n          'Ignore Base Geometry Alpha',\n          'Lighting',\n          'No Weapons',\n          'Unknown 11',\n          'Unknown 12',\n          'Unknown 13',\n          'Unknown 14',\n          'Particle Animated',\n          'Particle Grayscale Color',\n          'Particle Grayscale Alpha',\n          'Unknown 18',\n          'Unknown 19',\n          'Unknown 20',\n          'Unknown 21',\n          'Unknown 22',\n          'Unknown 23',\n          'Use Blood Geometry'\n        ])),\n        wbFloat('Fill/Texture Effect - Texture Scale (U)'),\n        wbFloat('Fill/Texture Effect - Texture Scale (V)'),\n        wbInteger('Scene Graph Emit Depth Limit (unused)', itU16)\n      ])\n    ], cpNormal, True),\n    wbMODL\n  ]);\n\n  wbRecord(ENCH, 'Object Effect', [\n    wbEDID,\n    wbOBNDReq,\n    wbFULL,\n    wbStruct(ENIT, 'Effect Data', [\n      wbInteger('Enchantment Cost', itS32),\n      wbInteger('Flags', itU32, wbFlags([\n        'No Auto-Calc',\n        '',\n        'Extend Duration On Recast'\n      ])),\n      wbInteger('Cast Type', itU32, wbCastEnum),\n      wbInteger('Enchantment Amount', itS32),\n      wbInteger('Target Type', itU32, wbTargetEnum),\n      wbInteger('Enchant Type', itU32, wbEnum([], [\n        $06, 'Enchantment',\n        $0C, 'Staff Enchantment'\n      ])),\n      wbFloat('Charge Time'),\n      wbFormIDCk('Base Enchantment', [ENCH, NULL]),\n      wbFormIDCk('Worn Restrictions', [FLST, NULL])\n    ], cpNormal, True, nil, 8),\n    wbEffectsReq\n  ]);\n\n  {wbRecord(EYES, 'Eyes', [\n    wbEDID\n  ]);}\n\n  wbRecord(FACT, 'Faction', [\n    wbEDID,\n    wbFULL,\n    wbRArrayS('Relations',\n      wbStructSK(XNAM, [0], 'Relation', [\n        wbFormIDCkNoReach('Faction', [FACT, RACE]),\n        wbInteger('Modifier', itS32),\n        wbInteger('Group Combat Reaction', itU32, wbEnum([\n        {0x00000001} 'Neutral',\n        {0x00000002} 'Enemy',\n        {0x00000004} 'Ally',\n        {0x00000008} 'Friend'\n      ]))\n    ])),\n    wbStruct(DATA, 'Flags', [\n      wbInteger('Flags', itU32, wbFlags([\n        {0x00000001} 'Hidden From NPC',\n        {0x00000002} 'Special Combat',\n        {0x00000004} 'Unknown 3',\n        {0x00000008} 'Unknown 4',\n        {0x00000010} 'Unknown 5',\n        {0x00000020} 'Unknown 6',\n        {0x00000040} 'Track Crime',\n        {0x00000080} 'Ignore Crimes: Murder',\n        {0x00000100} 'Ignore Crimes: Assault',\n        {0x00000200} 'Ignore Crimes: Stealing',\n        {0x00000400} 'Ignore Crimes: Trespass',\n        {0x00000800} 'Do Not Report Crimes Against Members',\n        {0x00001000} 'Crime Gold - Use Defaults',\n        {0x00002000} 'Ignore Crimes: Pickpocket',\n        {0x00004000} 'Vendor',\n        {0x00008000} 'Can Be Owner',\n        {0x00010000} 'Ignore Crimes: Werewolf (unused)'\n      ]))\n    ], cpNormal, True, nil, 1),\n    wbFormIDCk(JAIL, 'Exterior Jail Marker', [REFR]),\n    wbFormIDCk(WAIT, 'Follower Wait Marker', [REFR]),\n    wbFormIDCk(STOL, 'Stolen Goods Container', [REFR]),\n    wbFormIDCk(PLCN, 'Player Inventory Container', [REFR]),\n    wbFormIDCk(CRGR, 'Shared Crime Faction List', [FLST]),\n    wbFormIDCk(JOUT, 'Jail Outfit', [OTFT]),\n    wbStruct(CRVA, 'Crime Values', [\n      wbInteger('Arrest', itU8, wbBoolEnum),\n      wbInteger('Attack On Sight', itU8, wbBoolEnum),\n      wbInteger('Murder', itU16),\n      wbInteger('Assault', itU16),\n      wbInteger('Trespass', itU16),\n      wbInteger('Pickpocket', itU16),\n      wbInteger('Unknown', itU16),\n      wbFloat('Steal Multiplier'),\n      wbInteger('Escape', itU16),\n      wbInteger('Werewolf (unused)', itU16)\n    ], cpNormal, False, nil, 7),\n    wbRStructsSK('Ranks', 'Rank', [0], [\n      wbInteger(RNAM, 'Rank#', itU32),\n      wbLString(MNAM, 'Male Title', 0, cpTranslate),\n      wbLString(FNAM, 'Female Title', 0, cpTranslate),\n      wbString(INAM, 'Insignia (unused)')\n    ], []),\n    wbFormIDCk(VEND, 'Vendor Buy/Sell List', [FLST]),\n    wbFormIDCk(VENC, 'Merchant Container', [REFR]),\n    wbStruct(VENV, 'Vendor Values', [\n      wbInteger('Start Hour', itU16),\n      wbInteger('End Hour', itU16),\n      wbInteger('Radius', itU16),\n      wbByteArray('Unknown 1', 2),\n      wbInteger('Buys Stolen Items', itU8, wbBoolEnum),\n      wbInteger('Buy/Sell Everything Not In List?', itU8, wbBoolEnum),\n      wbInteger('Buys NonStolen Items', itU8, wbBoolEnum),\n      wbInteger('Unknown', itU8)\n    ]),\n    wbPLVD,\n    wbCITC,\n    wbCTDAsCount\n  ], False, nil, cpNormal, False, nil {wbFACTAfterLoad}, wbConditionsAfterSet);\n\n  wbRecord(FURN, 'Furniture',\n    wbFlags(wbRecordFlagsFlags, wbFlagsList([\n      {0x00000004}  2, 'Unknown 2',\n      {0x00000010}  4, 'Unknown 4',\n      {0x00000080}  7, 'Is Perch',\n      {0x00002000} 13, 'Unknown 13',\n      {0x00008000} 15, 'Has Distant LOD',\n      {0x00010000} 16, 'Random Anim Start',\n      {0x00800000} 23, 'Is Marker',\n      {0x02000000} 25, 'Power Armor',\n      {0x10000000} 28, 'Must Exit To Talk',\n      {0x20000000} 29, 'Child Can Use'\n    ])), [\n    wbEDID,\n    wbVMAD,\n    wbOBNDReq,\n    wbPTRN,\n    wbFULL,\n    wbMODL,\n    wbDEST,\n    wbKSIZ,\n    wbKWDAs,\n    wbPRPS,\n    wbNTRM,\n    wbFTYP,\n    wbUnknown(PNAM),\n    wbFormIDCk(WNAM, 'Drinking Water Type', [WATR]),\n    wbATTX,\n    wbInteger(FNAM, 'Flags', itU16, wbFlags([\n      {0x0001} 'Unknown 0',\n      {0x0002} 'Ignored By Sandbox'\n    ])),\n    wbCITC,\n    wbCTDAsCount,\n    wbCOCT,\n    wbCNTOs,\n    wbMNAMFurnitureMarker,\n    wbStruct(WBDT, 'Workbench Data', [\n      wbInteger('Bench Type', itU8, wbEnum([\n        {0} 'None',\n        {1} 'Create Object', // used only for MS11Workbench [FURN:00091FD5]\n        {2} 'Weapons', // used for the Weapons (plural) workbench\n        {3} 'Enchanting (unused)', // not used\n        {4} 'Enchanting Experiment (unused)', // not used\n        {5} 'Alchemy', // used for Chemistry and Cooking, so Alchemy is probably okay\n        {6} 'Alchemy Experiment (unused)', // not used\n        {7} 'Armor', // FO4 calls this the Armor workbench, no mention of Smithing\n        {8} 'Power Armor', // used for Power Armor stations\n        {9} 'Robot Mod' // used for Robot stations\n      ])),\n      wbInteger('Uses Skill', itS8, wbSkillEnum)\n    ], cpNormal, True, nil, 1),\n    wbFormIDCk(NAM1, 'Associated Form', [ARMO, WEAP, PERK, SPEL, HAZD]),\n    wbRArray('Markers', wbRStruct('Marker', [\n      wbInteger(ENAM, 'Marker Index', itS32),\n      wbStruct(NAM0, 'Disabled Entry Points', [\n        wbByteArray('Unknown', 2),\n        wbInteger('Disabled Points', itU16, wbFurnitureEntryTypeFlags)\n      ])\n      //wbFormIDCk(FNMK, 'Marker Keyword', [KYWD, NULL])\n    ], [])),\n    wbRArray('Marker Entry Points', wbStruct(FNPR, 'Marker', [\n      wbInteger('Type', itU16, wbFurnitureAnimTypeEnum),\n      wbInteger('Entry Points', itU16, wbFurnitureEntryTypeFlags)\n    ])),\n    wbString(XMRK, 'Marker Model'),\n    wbSNAMMarkerParams,\n    wbNVNM,\n    wbAPPR,\n    wbObjectTemplate\n  ], False, nil, cpNormal, False, nil, wbKeywordsAfterSet);\n\n  wbRecord(GLOB, 'Global',\n    wbFlags(wbRecordFlagsFlags, wbFlagsList([\n      {0x00000040}  6, 'Constant'\n    ])), [\n    wbEDID,\n    wbInteger(FNAM, 'Type', itU8, wbEnum([], [\n             0, 'Unknown 0',\n      Ord('s'), 'Short',\n      Ord('l'), 'Long',\n      Ord('f'), 'Float',\n      Ord('b'), 'Boolean'\n    ]), cpNormal, True),\n    wbFloat(FLTV, 'Value', cpNormal, True)\n  ]);\n\n  wbRecord(GMST, 'Game Setting', [\n    wbString(EDID, 'Editor ID', 0, cpCritical, True, nil, wbGMSTEDIDAfterSet),\n    wbUnion(DATA, 'Value', wbGMSTUnionDecider, [\n      wbLString('Name', 0, cpTranslate),\n      wbInteger('Int', itS32),\n      wbFloat('Float'),\n      wbInteger('Bool', itU32, wbBoolEnum)\n    ], cpNormal, True)\n  ]);\n\n  wbRecord(KYWD, 'Keyword',\n    wbFlags(wbRecordFlagsFlags, wbFlagsList([\n      {0x00080000} {15} 15, 'Restricted'\n    ])), [\n    wbEDID,\n    wbCNAM,\n    wbString(DNAM, 'Notes'),\n    wbInteger(TNAM, 'Type', itU32, wbKeywordTypeEnum),\n    wbFormIDCk(DATA, 'Attraction Rule', [AORU]),\n    wbFULL,\n    wbString(NNAM, 'Display Name') {Legacy record replaced with FULL}\n  ]);\nend;\n\nprocedure DefineFO4e;\nbegin\n  wbRecord(LCRT, 'Location Reference Type', [\n    wbEDID,\n    wbCNAM,\n    wbUnknown(TNAM)\n  ]);\n\n  wbRecord(AACT, 'Action',\n    wbFlags(wbRecordFlagsFlags, wbFlagsList([\n      {0x00080000} {15} 15, 'Restricted'\n    ])), [\n    wbEDID,\n    wbCNAM,\n    wbString(DNAM, 'Notes'),\n    wbInteger(TNAM, 'Type', itU32, wbKeywordTypeEnum),\n    wbFormIDCk(DATA, 'Attraction Rule', [AORU]),\n    wbFULL\n  ]);\n\n  wbRecord(TXST, 'Texture Set', [\n    wbEDID,\n    wbOBNDReq,\n    wbRStruct('Textures (RGB/A)', [\n      wbString(TX00, 'Difuse'),\n      wbString(TX01, 'Normal/Gloss'),\n      wbString(TX03, 'Glow'),\n      wbString(TX04, 'Height'),\n      wbString(TX05, 'Environment'),\n      wbString(TX02, 'Wrinkles'), {TX05 TX02 TX06 Yes this has to go here}\n      wbString(TX06, 'Multilayer'),\n      wbString(TX07, 'Smooth Spec')\n    ], []),\n    wbDODT,\n    wbInteger(DNAM, 'Flags', itU16, wbFlags([\n      {0x0001} 'No Specular Map',\n      {0x0002} 'Facegen Textures',\n      {0x0004} 'Has Model Space Normal Map'\n    ]), cpNormal, True),\n    wbString(MNAM, 'Material')\n  ]);\n\n  wbRecord(HDPT, 'Head Part',\n    wbFlags(wbRecordFlagsFlags, wbFlagsList([\n      {0x00000004}  2, 'Non-Playable'\n    ])), [\n    wbEDID,\n    wbFULL,\n    wbMODL,\n    wbInteger(DATA, 'Flags', itU8, wbFlags([\n      {0x01} 'Playable',\n      {0x02} 'Male',\n      {0x04} 'Female',\n      {0x10} 'Is Extra Part',\n      {0x20} 'Use Solid Tint',\n      {0x40} 'Uses Body Texture'\n    ]), cpNormal, True),\n    wbInteger(PNAM, 'Type', itU32, wbEnum([\n      'Misc',\n      'Face',\n      'Eyes',\n      'Hair',\n      'Facial Hair',\n      'Scar',\n      'Eyebrows',\n      'Meatcaps',\n      'Teeth',\n      'Head Rear'\n    ])),\n    wbRArrayS('Extra Parts',\n      wbFormIDCk(HNAM, 'Part', [HDPT])\n    ),\n    wbRStructs('Parts', 'Part', [\n      wbInteger(NAM0, 'Part Type', itU32, wbEnum([\n        'Race Morph',\n        'Tri',\n        'Chargen Morph'\n      ])),\n      wbString(NAM1, 'Filename', 0, cpTranslate, True)\n    ], []),\n    wbFormIDCk(TNAM, 'Texture Set', [TXST]),\n    wbFormIDCk(CNAM, 'Color', [CLFM]),\n    wbFormIDCk(RNAM, 'Valid Races', [FLST]),\n    wbCTDAs\n  ]);\n\n  wbRecord(ASPC, 'Acoustic Space', [\n    wbEDID,\n    wbOBNDReq,\n    wbFormIDCk(SNAM, 'Looping Sound', [SNDR]),\n    wbFormIDCk(RDAT, 'Use Sound from Region (Interiors Only)', [REGN]),\n    wbFormIDCk(BNAM, 'Environment Type', [REVB]),\n    wbInteger(XTRI, 'Is Interior', itU8, wbBoolEnum, cpNormal, True),\n    wbInteger(WNAM, 'Weather Attenuation (dB)', itU16, wbDiv(100))\n  ]);\n\n  wbRecord(MSTT, 'Moveable Static',\n    wbFlags(wbRecordFlagsFlags, wbFlagsList([\n      {0x00000100}  8, 'Must Update Anims',\n      {0x00000200}  9, 'Hidden From Local Map',\n      {0x00000800} 11, 'Used As Platform',\n      {0x00002000} 13, 'Pack-In Use Only',\n      {0x00008000} 15, 'Has Distant LOD',\n      {0x00010000} 16, 'Random Anim Start',\n      {0x00080000} 19, 'Has Currents',\n      {0x02000000} 25, 'Obstacle',\n      {0x04000000} 26, 'NavMesh Generation - Filter',\n      {0x08000000} 27, 'NavMesh Generation - Bounding Box',\n      {0x40000000} 30, 'NavMesh Generation - Ground'\n    ])), [\n    wbEDID,\n    wbVMAD,\n    wbOBNDReq,\n    wbPTRN,\n    wbFULL,\n    wbMODL,\n    wbDEST,\n    wbKSIZ,\n    wbKWDAs,\n    wbPRPS,\n    wbInteger(DATA, 'On Local Map', itU8, wbBoolEnum, cpNormal, True),\n    wbFormIDCk(SNAM, 'Looping Sound', [SNDR])\n  ]);\nend;\n\nprocedure DefineFO4f;\nbegin\n  wbRecord(IDLM, 'Idle Marker',\n    wbFlags(wbRecordFlagsFlags, wbFlagsList([\n      {0x20000000} 29, 'Child Can Use'\n    ])), [\n    wbEDID,\n    wbOBNDReq,\n    wbKSIZ,\n    wbKWDAs,\n    wbInteger(IDLF, 'Flags', itU8, wbFlags([\n      'Run in Sequence',\n      'Unknown 1',\n      'Do Once',\n      'Unknown 3',\n      'Ignored by Sandbox'\n    ]), cpNormal, False),\n    wbInteger(IDLC, 'Animation Count', itU8, nil, cpBenign),\n    wbFloat(IDLT, 'Idle Timer Setting', cpNormal, False),\n    wbArray(IDLA, 'Animations', wbFormIDCk('Animation', [IDLE]), 0, nil, wbIDLAsAfterSet, cpNormal, False),\n    wbFormIDCk(QNAM, 'Unknown', [KYWD]),\n    wbMODL\n  ], False, nil, cpNormal, False, nil, wbAnimationsAfterSet);\n\n  wbRecord(PROJ, 'Projectile', [\n    wbEDID,\n    wbOBNDReq,\n    wbFULL,\n    wbMODL,\n    wbDEST,\n    wbByteArray(DATA, 'Unused', 0, cpIgnore),\n    wbStruct(DNAM, 'Data', [\n      wbInteger('Flags', itU16, wbFlags([\n        {0x00001} 'Hitscan',\n        {0x00002} 'Explosion',\n        {0x00004} 'Alt. Trigger',\n        {0x00008} 'Muzzle Flash',\n        {0x00010} 'Unknown 4',\n        {0x00020} 'Can Be Disabled',\n        {0x00040} 'Can Be Picked Up',\n        {0x00080} 'Supersonic',\n        {0x00100} 'Pins Limbs',\n        {0x00200} 'Pass Through Small Transparent',\n        {0x00400} 'Disable Combat Aim Correction',\n        {0x00800} 'Penetrates Geometry',\n        {0x01000} 'Continuous Update',\n        {0x02000} 'Seeks Target'\n      ])),\n      wbInteger('Type', itU16, wbEnum([], [\n        $01, 'Missile',\n        $02, 'Lobber',\n        $04, 'Beam',\n        $08, 'Flame',\n        $10, 'Cone',\n        $20, 'Barrier',\n        $40, 'Arrow'\n      ])),\n      wbFloat('Gravity'),\n      wbFloat('Speed'),\n      wbFloat('Range'),\n      wbFormIDCk('Light', [LIGH, NULL]),\n      wbFormIDCk('Muzzle Flash - Light', [LIGH, NULL]),\n      wbFloat('Explosion - Alt. Trigger - Proximity'),\n      wbFloat('Explosion - Alt. Trigger - Timer'),\n      wbFormIDCk('Explosion', [EXPL, NULL]),\n      wbFormIDCk('Sound', [SNDR, NULL]),\n      wbFloat('Muzzle Flash - Duration'),\n      wbFloat('Fade Duration'),\n      wbFloat('Impact Force'),\n      wbFormIDCk('Sound - Countdown', [SNDR, NULL]),\n      wbFormIDCk('Sound - Disable', [SNDR, NULL]),\n      wbFormIDCk('Default Weapon Source', [WEAP, NULL]),\n      wbFloat('Cone Spread'),\n      wbFloat('Collision Radius'),\n      wbFloat('Lifetime'),\n      wbFloat('Relaunch Interval'),\n      wbFormIDCk('Decal Data', [TXST, NULL]),\n      wbFormIDCk('Collision Layer', [COLL, NULL]),\n      wbInteger('Tracer Frequency', itU8),\n      wbFormIDCk('VATS Projectile', [PROJ, NULL])\n    ]),\n    wbRStructSK([0], 'Muzzle Flash Model', [\n      wbString(NAM1, 'Model Filename'),\n      wbByteArray(NAM2, 'Texture Files Hashes', 0, cpIgnore, false, false, wbNeverShow)\n    ], [], cpNormal, True),\n    wbInteger(VNAM, 'Sound Level', itU32, wbSoundLevelEnum, cpNormal, True)\n  ]);\n\n  wbRecord(HAZD, 'Hazard', [\n    wbEDID,\n    wbOBNDReq,\n    wbFULL,\n    wbMODL,\n    wbFormIDCk(MNAM, 'Image Space Modifier', [IMAD, NULL]),\n    wbStruct(DNAM, 'Data', [\n      wbInteger('Limit', itU32),\n      wbFloat('Radius'),\n      wbFloat('Lifetime'),\n      wbFloat('Image Space Radius'),\n      wbFloat('Target Interval'),\n      wbInteger('Flags', itU32, wbFlags([\n        {0x01} 'Affects Player Only',\n        {0x02} 'Inherit Duration from Spawn Spell',\n        {0x04} 'Align to Impact Normal',\n        {0x08} 'Inherit Radius from Spawn Spell',\n        {0x10} 'Drop to Ground',\n        {0x20} 'Taper Effectiveness by Proximity'\n      ])),\n      wbFormIDCk('Effect', [SPEL, ENCH, NULL]),\n      wbFormIDCk('Light', [LIGH, NULL]),\n      wbFormIDCk('Impact Data Set', [IPDS, NULL]),\n      wbFormIDCk('Sound', [SNDR, NULL]),\n      wbStruct('Taper Effectiveness', [\n        wbFloat('Full Effect Radius'),\n        wbFloat('Taper Weight'),\n        wbFloat('Taper Curse')\n      ])\n    ])\n  ]);\n\n  wbSoulGemEnum := wbEnum([\n    {0} 'None',\n    {1} 'Petty',\n    {2} 'Lesser',\n    {3} 'Common',\n    {4} 'Greater',\n    {5} 'Grand'\n  ]);\n\n  {wbRecord(SLGM, 'Soul Gem', [\n    wbEDID\n  ]);}\n\n  if wbSimpleRecords then begin\n\n    wbRecord(NAVI, 'Navigation Mesh Info Map', [\n      wbEDID,\n      wbInteger(NVER, 'Version', itU32),\n      wbRArray('Navigation Map Infos',\n        wbStruct(NVMI, 'Navigation Map Info', [\n          wbFormIDCk('Navigation Mesh', [NAVM]),\n          wbByteArray('Data', 20),\n          wbArray('Merged To', wbFormIDCk('Mesh', [NAVM]), -1),\n          wbArray('Preferred Merges', wbFormIDCk('Mesh', [NAVM]), -1),\n          wbArray('Linked Doors', wbStruct('Door', [\n            wbByteArray('Unknown', 4),\n            wbFormIDCk('Door Ref', [REFR])\n          ]), -1),\n          wbInteger('Is Island', itU8, wbBoolEnum),\n          wbUnion('Island', wbNAVIIslandDataDecider, [\n            wbNull,\n            wbStruct('Island Data', [\n              wbByteArray('Unknown', 24),\n              wbArray('Triangles', wbByteArray('Triangle', 6), -1),\n              wbArray('Vertices', wbByteArray('Vertex', 12), -1)\n            ])\n          ]),\n          wbByteArray('Unknown', 4),\n          wbFormIDCk('Parent Worldspace', [WRLD, NULL]),\n          wbUnion('Parent', wbNAVIParentDecider, [\n            wbStruct('Coordinates', [\n              wbInteger('Grid Y', itS16),\n              wbInteger('Grid X', itS16)\n            ]),\n            wbFormIDCk('Parent Cell', [CELL])\n          ])\n        ])\n      ),\n      wbStruct(NVPP, 'Preferred Pathing', [\n        wbArray('NavMeshes', wbArray('Set', wbFormIDCk('', [NAVM]), -1), -1),\n        wbArray('NavMesh Tree?', wbStruct('', [\n          wbFormIDCk('NavMesh', [NAVM]),\n          wbInteger('Index/Node', itU32)\n        ]), -1)\n      ]),\n      //wbArray(NVSI, 'Unknown', wbFormIDCk('Navigation Mesh', [NAVM]))\n      wbUnknown(NVSI)\n    ]);\n\n    wbRecord(NAVM, 'Navigation Mesh',\n      wbFlags(wbRecordFlagsFlags, wbFlagsList([\n        {0x00040000} 18, 'Compressed',\n        {0x04000000} 26, 'AutoGen',\n        {0x80000000} 31, 'Unknown 31'\n      ]), [18]), [\n      wbEDID,\n      wbNVNM,\n//      wbStruct(NVNM, 'Geometry', [\n//        wbByteArray('Unknown', 8),\n//        wbFormIDCk('Parent Worldspace', [WRLD, NULL]),\n//        wbUnion('Parent', wbNVNMParentDecider, [\n//          wbStruct('Coordinates', [\n//            wbInteger('Grid Y', itS16),\n//            wbInteger('Grid X', itS16)\n//          ]),\n//          wbFormIDCk('Parent Cell', [CELL])\n//        ]),\n//        wbArray('Vertices', wbByteArray('Vertex', 12), -1),\n//        wbArray('Triangles', wbByteArray('Triangle', 21), -1),\n//        wbArray('Edge Links',\n//          wbStruct('Edge Link', [\n//            wbByteArray('Unknown', 4),\n//            wbFormIDCk('Mesh', [NAVM]),\n//            wbInteger('Triangle', itS16),\n//            wbInteger('Unknown', itU8)\n//          ])\n//        , -1),\n//        wbArray('Door Triangles',\n//          wbStruct('Door Triangle', [\n//            wbInteger('Triangle before door', itS16),\n//            wbByteArray('Unknown', 4),\n//            wbFormIDCk('Door', [REFR])\n//          ])\n//        , -1),\n//        wbUnknown\n//      ]),\n      wbUnknown(ONAM),\n      wbUnknown(NNAM),\n      wbUnknown(MNAM)\n    ], False, wbNAVMAddInfo);\n\n  end else begin\n\n    wbRecord(NAVI, 'Navigation Mesh Info Map', [\n      wbEDID,\n      wbInteger(NVER, 'Version', itU32),\n      wbRArray('Navigation Map Infos',\n        wbStruct(NVMI, 'Navigation Map Info', [\n          wbFormIDCk('Navigation Mesh', [NAVM]),\n          wbByteArray('Unknown', 4),\n          wbFloat('X'),\n          wbFloat('Y'),\n          wbFloat('Z'),\n          wbInteger('Preferred Merges Flag', itU32),\n          wbArray('Merged To', wbFormIDCk('Mesh', [NAVM]), -1),\n          wbArray('Preferred Merges', wbFormIDCk('Mesh', [NAVM]), -1),\n          wbArray('Linked Doors', wbStruct('Door', [\n            wbByteArray('Unknown', 4),\n            wbFormIDCk('Door Ref', [REFR])\n          ]), -1),\n          wbInteger('Is Island', itU8, wbBoolEnum),\n          wbUnion('Island', wbNAVIIslandDataDecider, [\n            wbNull,\n            wbStruct('Island Data', [\n              wbFloat('Min X'),\n              wbFloat('Min Y'),\n              wbFloat('Min Z'),\n              wbFloat('Max X'),\n              wbFloat('Max Y'),\n              wbFloat('Max Z'),\n              wbArray('Triangles',\n                wbStruct('Triangle', [\n                  wbArray('Vertices', wbInteger('Vertex', itS16), 3)\n                ])\n              , -1),\n              wbArray('Vertices', wbStruct('Vertex', [\n                wbFloat('X'),\n                wbFloat('Y'),\n                wbFloat('Z')\n              ]), -1)\n            ])\n          ]),\n          wbByteArray('Unknown', 4),\n          wbFormIDCk('Parent Worldspace', [WRLD, NULL]),\n          wbUnion('Parent', wbNAVIParentDecider, [\n            wbStruct('Coordinates', [\n              wbInteger('Grid Y', itS16),\n              wbInteger('Grid X', itS16)\n            ]),\n            wbFormIDCk('Parent Cell', [CELL])\n          ])\n        ])\n      ),\n      wbStruct(NVPP, 'Preferred Pathing', [\n        wbArray('NavMeshes', wbArray('Set', wbFormIDCk('', [NAVM]), -1), -1),\n        wbArray('NavMesh Tree?', wbStruct('', [\n          wbFormIDCk('NavMesh', [NAVM]),\n          wbInteger('Index/Node', itU32)\n        ]), -1)\n      ]),\n      wbArray(NVSI, 'Unknown', wbFormIDCk('Navigation Mesh', [NAVM]))\n    ]);\n\n    wbRecord(NAVM, 'Navigation Mesh',\n      wbFlags(wbRecordFlagsFlags, wbFlagsList([\n        {0x00040000} 18, 'Compressed',\n        {0x04000000} 26, 'AutoGen'\n      ]), [18]), [\n      wbEDID,\n      wbNVNM,\n//      wbStruct(NVNM, 'Geometry', [\n//        wbInteger('Unknown', itU32),\n//        wbByteArray('Unknown', 4),\n//        wbFormIDCk('Parent Worldspace', [WRLD, NULL]),\n//        wbUnion('Parent', wbNVNMParentDecider, [\n//          wbStruct('Coordinates', [\n//            wbInteger('Grid Y', itS16),\n//            wbInteger('Grid X', itS16)\n//          ]),\n//          wbFormIDCk('Parent Cell', [CELL])\n//        ]),\n//        wbArray('Vertices', wbStruct('Vertex', [\n//          wbFloat('X'),\n//          wbFloat('Y'),\n//          wbFloat('Z')\n//        ]), -1),\n//        wbArray('Triangles',\n//          wbStruct('Triangle', [\n//            wbInteger('Vertex 0', itS16),\n//            wbInteger('Vertex 1', itS16),\n//            wbInteger('Vertex 2', itS16),\n//            wbInteger('Edge 0-1', itS16),\n//            wbInteger('Edge 1-2', itS16),\n//            wbInteger('Edge 2-0', itS16),\n//            wbFloat('Height'),\n//            wbByteArray('Unknown', 5)\n//          ])\n//        , -1),\n//        wbArray('Edge Links',\n//          wbStruct('Edge Link', [\n//            wbByteArray('Unknown', 4),\n//            wbFormIDCk('Mesh', [NAVM]),\n//            wbInteger('Triangle', itS16),\n//            wbInteger('Unknown', itU8)\n//          ])\n//        , -1),\n//        wbArray('Door Triangles',\n//          wbStruct('Door Triangle', [\n//            wbInteger('Triangle before door', itS16),\n//            wbByteArray('Unknown', 4),\n//            wbFormIDCk('Door', [REFR])\n//          ])\n//        , -1),\n//        wbUnknown\n//      ]),\n      wbFormID(ONAM),\n      wbArray(NNAM, 'Unknown', wbInteger('Unknown', itU16)),\n      wbUnion(MNAM, 'Unknown', wbSubrecordSizeDecider, [wbNull,\n        wbStruct('Unknown', [\n          wbFormID('Unknown'),\n          wbInteger('Unknown', itU16),\n          wbInteger('Unused', itU16),\n          wbUnknown\n        ])\n      ])\n    ], False, wbNAVMAddInfo);\n\n  end;\n\nend;\n\nprocedure DefineFO4g;\nbegin\n\n   wbRecord(EXPL, 'Explosion', [\n    wbEDID,\n    wbOBNDReq,\n    wbFULL,\n    wbMODL,\n    wbEITM,\n    wbFormIDCk(MNAM, 'Image Space Modifier', [IMAD]),\n    wbStruct(DATA, 'Data', [\n      wbFormIDCk('Light', [LIGH, NULL]),\n      wbFormIDCk('Sound 1', [SNDR, NULL]),\n      wbFormIDCk('Sound 2', [SNDR, NULL]),\n      wbFormIDCk('Impact Data Set', [IPDS, NULL]),\n      wbFormID('Placed Object'),\n      wbFormIDCk('Spawn Projectile', [PROJ, NULL]),\n      wbFloat('Force'),\n      wbFloat('Damage'),\n      wbFloat('Inner Radius'),\n      wbFloat('Outer Radius'),\n      wbFloat('IS Radius'),\n      wbUnion('Vertical Offset Mult', wbDeciderFormVersion99, [\n        wbByteArray('Unknown', 4),\n        wbFloat('Vertical Offset Mult')\n      ]),\n      wbInteger('Flags', itU32, wbFlags([\n        {0x00000001} 'Unknown 0',\n        {0x00000002} 'Always Uses World Orientation',\n        {0x00000004} 'Knock Down - Always',\n        {0x00000008} 'Knock Down - By Formula',\n        {0x00000010} 'Ignore LOS Check',\n        {0x00000020} 'Push Explosion Source Ref Only',\n        {0x00000040} 'Ignore Image Space Swap',\n        {0x00000080} 'Chain',\n        {0x00000100} 'No Controller Vibration',\n        {0x00000200} 'Placed Object Persists',\n        {0x00000400} 'Skip Underwater Tests'\n      ])),\n      wbInteger('Sound Level', itU32, wbSoundLevelEnum),\n      wbFloat('Placed Object AutoFade Delay'),\n      wbInteger('Stagger', itU32, wbEnum([\n        'None',\n        'Small',\n        'Medium',\n        'Large',\n        'Extra Large'\n      ])),\n      wbStruct('Spawn', [\n        wbFloat('X'),\n        wbFloat('Y'),\n        wbFloat('Z'),\n        wbFloat('Spread Degrees'),\n        wbInteger('Count', itU32)\n      ])\n    ], cpNormal, True, nil, 13)\n  ]);\n\n  wbRecord(DEBR, 'Debris', [\n    wbEDID,\n    wbRStructs('Models', 'Model', [\n      wbStruct(DATA, 'Data', [\n        wbInteger('Percentage', itU8),\n        wbString('Model Filename'),\n        wbInteger('Flags', itU8, wbFlags([\n          'Has Collision Data'\n        ]))\n      ], cpNormal, True),\n      wbMODT\n    ], [], cpNormal, True)\n  ]);\n\n  wbRecord(IMGS, 'Image Space', [\n    wbEDID,\n    wbByteArray(ENAM, 'Unused', 0, cpIgnore),\n    wbStruct(HNAM, 'HDR', [\n      wbFloat('Eye Adapt Speed'),\n      wbFloat('Tonemap E'),\n      wbFloat('Bloom Threshold'),\n      wbFloat('Bloom Scale'),\n      wbFloat('Auto Exposure Max'),\n      wbFloat('Auto Exposure Min'),\n      wbFloat('Sunlight Scale'),\n      wbFloat('Sky Scale'),\n      wbFloat('Middle Gray')\n    ], cpNormal, True),\n    wbStruct(CNAM, 'Cinematic', [\n      wbFloat('Saturation'),\n      wbFloat('Brightness'),\n      wbFloat('Contrast')\n    ], cpNormal, True),\n    wbStruct(TNAM, 'Tint', [\n      wbFloat('Amount'),\n      wbFloatColors('Color')\n    ], cpNormal, True),\n    wbStruct(DNAM, 'Depth of Field', [\n      wbFloat('Strength'),\n      wbFloat('Distance'),\n      wbFloat('Range'),\n      wbByteArray('Unused', 2, cpIgnore),\n      wbInteger('Sky / Blur Radius', itU16, wbEnum([], [\n        16384, 'Radius 0',\n        16672, 'Radius 1',\n        16784, 'Radius 2',\n        16848, 'Radius 3',\n        16904, 'Radius 4',\n        16936, 'Radius 5',\n        16968, 'Radius 6',\n        17000, 'Radius 7',\n        16576, 'No Sky, Radius 0',\n        16736, 'No Sky, Radius 1',\n        16816, 'No Sky, Radius 2',\n        16880, 'No Sky, Radius 3',\n        16920, 'No Sky, Radius 4',\n        16952, 'No Sky, Radius 5',\n        16984, 'No Sky, Radius 6',\n        17016, 'No Sky, Radius 7'\n      ])),\n      wbFloat('Vignette Radius'),\n      wbFloat('Vignette Strength')\n    ], cpNormal, True, nil, 5),\n    wbString(TX00, 'LUT')\n  ]);\n\n  wbTimeInterpolator := wbStruct('Data', [\n    wbFloat('Time'),\n    wbFloat('Value')\n  ]);\n\n  wbColorInterpolator := wbStruct('Data', [\n    wbFloat('Time'),\n    wbFloat('Red', cpNormal, False, 255, 0),\n    wbFloat('Green', cpNormal, False, 255, 0),\n    wbFloat('Blue', cpNormal, False, 255, 0),\n    wbFloat('Alpha', cpNormal, False, 255, 0)\n  ]);\n\n  wbRecord(IMAD, 'Image Space Adapter', [\n    wbEDID,\n    wbStruct(DNAM, 'Data Count', [\n      wbInteger('Flags', itU32, wbFlags(['Animatable'])),\n      wbFloat('Duration'),\n      wbStruct('HDR', [\n        wbInteger('Eye Adapt Speed Mult', itU32),\n        wbInteger('Eye Adapt Speed Add', itU32),\n        wbInteger('Bloom Blur Radius Mult', itU32),\n        wbInteger('Bloom Blur Radius Add', itU32),\n        wbInteger('Bloom Threshold Mult', itU32),\n        wbInteger('Bloom Threshold Add', itU32),\n        wbInteger('Bloom Scale Mult', itU32),\n        wbInteger('Bloom Scale Add', itU32),\n        wbInteger('Target Lum Min Mult', itU32),\n        wbInteger('Target Lum Min Add', itU32),\n        wbInteger('Target Lum Max Mult', itU32),\n        wbInteger('Target Lum Max Add', itU32),\n        wbInteger('Sunlight Scale Mult', itU32),\n        wbInteger('Sunlight Scale Add', itU32),\n        wbInteger('Sky Scale Mult', itU32),\n        wbInteger('Sky Scale Add', itU32)\n      ]),\n      wbInteger('Unknown08 Mult', itU32),\n      wbInteger('Unknown48 Add', itU32),\n      wbInteger('Unknown09 Mult', itU32),\n      wbInteger('Unknown49 Add', itU32),\n      wbInteger('Unknown0A Mult', itU32),\n      wbInteger('Unknown4A Add', itU32),\n      wbInteger('Unknown0B Mult', itU32),\n      wbInteger('Unknown4B Add', itU32),\n      wbInteger('Unknown0C Mult', itU32),\n      wbInteger('Unknown4C Add', itU32),\n      wbInteger('Unknown0D Mult', itU32),\n      wbInteger('Unknown4D Add', itU32),\n      wbInteger('Unknown0E Mult', itU32),\n      wbInteger('Unknown4E Add', itU32),\n      wbInteger('Unknown0F Mult', itU32),\n      wbInteger('Unknown4F Add', itU32),\n      wbInteger('Unknown10 Mult', itU32),\n      wbInteger('Unknown50 Add', itU32),\n      wbStruct('Cinematic', [\n        wbInteger('Saturation Mult', itU32),\n        wbInteger('Saturation Add', itU32),\n        wbInteger('Brightness Mult', itU32),\n        wbInteger('Brightness Add', itU32),\n        wbInteger('Contrast Mult', itU32),\n        wbInteger('Contrast Add', itU32)\n      ]),\n      wbInteger('Unknown14 Mult', itU32),\n      wbInteger('Unknown54 Add', itU32),\n      wbInteger('Tint Color', itU32),\n      wbInteger('Blur Radius', itU32),\n      wbInteger('Double Vision Strength', itU32),\n      wbInteger('Radial Blur Strength', itU32),\n      wbInteger('Radial Blur Ramp Up', itU32),\n      wbInteger('Radial Blur Start', itU32),\n      wbInteger('Radial Blur Flags', itU32, wbFlags(['Use Target'])),\n      wbFloat('Radial Blur Center X'),\n      wbFloat('Radial Blur Center Y'),\n      wbInteger('DoF Strength', itU32),\n      wbInteger('DoF Distance', itU32),\n      wbInteger('DoF Range', itU32),\n      wbInteger('DoF Flags', itU32, wbFlags([\n        {0x00000001} 'Use Target',\n        {0x00000002} 'Unknown 2',\n        {0x00000004} 'Unknown 3',\n        {0x00000008} 'Unknown 4',\n        {0x00000010} 'Unknown 5',\n        {0x00000020} 'Unknown 6',\n        {0x00000040} 'Unknown 7',\n        {0x00000080} 'Unknown 8',\n        {0x00000100} 'Mode - Front',\n        {0x00000200} 'Mode - Back',\n        {0x00000400} 'No Sky',\n        {0x00000800} 'Blur Radius Bit 2',\n        {0x00001000} 'Blur Radius Bit 1',\n        {0x00002000} 'Blur Radius Bit 0'\n      ])),\n      wbInteger('Radial Blur Ramp Down', itU32),\n      wbInteger('Radial Blur Down Start', itU32),\n      wbInteger('Fade Color', itU32),\n      wbInteger('Motion Blur Strength', itU32),\n      wbUnknown\n    ]),\n    wbArray(BNAM, 'Blur Radius', wbTimeInterpolator),\n    wbArray(VNAM, 'Double Vision Strength', wbTimeInterpolator),\n    wbArray(TNAM, 'Tint Color', wbColorInterpolator),\n    wbArray(NAM3, 'Fade Color', wbColorInterpolator),\n    wbRStruct('Radial Blur', [\n      wbArray(RNAM, 'Strength', wbTimeInterpolator),\n      wbArray(SNAM, 'RampUp', wbTimeInterpolator),\n      wbArray(UNAM, 'Start', wbTimeInterpolator),\n      wbArray(NAM1, 'RampDown', wbTimeInterpolator),\n      wbArray(NAM2, 'DownStart', wbTimeInterpolator)\n    ], []),\n    wbRStruct('Depth of Field', [\n      wbArray(WNAM, 'Strength', wbTimeInterpolator),\n      wbArray(XNAM, 'Distance', wbTimeInterpolator),\n      wbArray(YNAM, 'Range', wbTimeInterpolator),\n      wbArray(NAM5, 'Vignette Radius', wbTimeInterpolator),\n      wbArray(NAM6, 'Vignette Strength', wbTimeInterpolator)\n    ], []),\n    wbArray(NAM4, 'Motion Blur Strength', wbTimeInterpolator),\n    wbRStruct('HDR', [\n      wbArray(_00_IAD, 'Eye Adapt Speed Mult', wbTimeInterpolator),\n      wbArray(_40_IAD, 'Eye Adapt Speed Add', wbTimeInterpolator),\n      wbArray(_01_IAD, 'Bloom Blur Radius Mult', wbTimeInterpolator),\n      wbArray(_41_IAD, 'Bloom Blur Radius Add', wbTimeInterpolator),\n      wbArray(_02_IAD, 'Bloom Threshold Mult', wbTimeInterpolator),\n      wbArray(_42_IAD, 'Bloom Threshold Add', wbTimeInterpolator),\n      wbArray(_03_IAD, 'Bloom Scale Mult', wbTimeInterpolator),\n      wbArray(_43_IAD, 'Bloom Scale Add', wbTimeInterpolator),\n      wbArray(_04_IAD, 'Target Lum Min Mult', wbTimeInterpolator),\n      wbArray(_44_IAD, 'Target Lum Min Add', wbTimeInterpolator),\n      wbArray(_05_IAD, 'Target Lum Max Mult', wbTimeInterpolator),\n      wbArray(_45_IAD, 'Target Lum Max Add', wbTimeInterpolator),\n      wbArray(_06_IAD, 'Sunlight Scale Mult', wbTimeInterpolator),\n      wbArray(_46_IAD, 'Sunlight Scale Add', wbTimeInterpolator),\n      wbArray(_07_IAD, 'Sky Scale Mult', wbTimeInterpolator),\n      wbArray(_47_IAD, 'Sky Scale Add', wbTimeInterpolator)\n    ], []),\n    wbUnknown(_08_IAD),\n    wbUnknown(_48_IAD),\n    wbUnknown(_09_IAD),\n    wbUnknown(_49_IAD),\n    wbUnknown(_0A_IAD),\n    wbUnknown(_4A_IAD),\n    wbUnknown(_0B_IAD),\n    wbUnknown(_4B_IAD),\n    wbUnknown(_0C_IAD),\n    wbUnknown(_4C_IAD),\n    wbUnknown(_0D_IAD),\n    wbUnknown(_4D_IAD),\n    wbUnknown(_0E_IAD),\n    wbUnknown(_4E_IAD),\n    wbUnknown(_0F_IAD),\n    wbUnknown(_4F_IAD),\n    wbUnknown(_10_IAD),\n    wbUnknown(_50_IAD),\n    wbRStruct('Cinematic', [\n      wbArray(_11_IAD, 'Saturation Mult', wbTimeInterpolator),\n      wbArray(_51_IAD, 'Saturation Add', wbTimeInterpolator),\n      wbArray(_12_IAD, 'Brightness Mult', wbTimeInterpolator),\n      wbArray(_52_IAD, 'Brightness Add', wbTimeInterpolator),\n      wbArray(_13_IAD, 'Contrast Mult', wbTimeInterpolator),\n      wbArray(_53_IAD, 'Contrast Add', wbTimeInterpolator)\n    ], []),\n    wbUnknown(_14_IAD),\n    wbUnknown(_54_IAD)\n  ]);\n\n  wbRecord(FLST, 'FormID List', [\n    wbString(EDID, 'Editor ID', 0, cpBenign, True, nil, wbFLSTEDIDAfterSet),\n    wbFULL,\n    wbRArrayS('FormIDs', wbFormID(LNAM, 'FormID'), cpNormal, False, nil, nil, nil, wbFLSTLNAMIsSorted)\n  ]);\n\n  wbRecord(PERK, 'Perk',\n    wbFlags(wbRecordFlagsFlags, wbFlagsList([\n      {0x00000004}  2, 'Non-Playable'\n    ])), [\n    wbEDID,\n    wbVMADFragmentedPERK,\n    wbFULL,\n    wbDESCReq,\n    wbString(ICON, 'Image'),\n    wbCTDAs,\n    wbStruct(DATA, 'Data', [\n      wbInteger('Trait', itU8, wbBoolEnum),\n      wbInteger('Level', itU8),\n      wbInteger('Num Ranks', itU8),\n      wbInteger('Playable', itU8, wbBoolEnum),\n      wbInteger('Hidden', itU8, wbBoolEnum)\n    ], cpNormal, True),\n    wbFormIDCk(SNAM, 'Sound', [SNDR]),\n    wbFormIDCK(NNAM, 'Next Perk', [PERK, NULL]),\n    wbString(FNAM, 'SWF'),\n\n    wbRStructsSK('Effects', 'Effect', [0, 1], [\n      wbStructSK(PRKE, [1, 2, 0], 'Header', [\n        wbInteger('Type', itU8, wbEnum([\n          'Quest + Stage',\n          'Ability',\n          'Entry Point'\n        ]), cpNormal, False, nil, wbPERKPRKETypeAfterSet),\n        wbInteger('Rank', itU8),\n        wbInteger('Priority', itU8)\n      ]),\n      wbUnion(DATA, 'Effect Data', wbPerkDATADecider, [\n        wbStructSK([0, 1], 'Quest + Stage', [\n          wbFormIDCk('Quest', [QUST]),\n          wbInteger('Quest Stage', itU16, wbPerkDATAQuestStageToStr, wbCTDAParam2QuestStageToInt),\n          wbByteArray('Unused', 2)\n        ]),\n        wbFormIDCk('Ability', [SPEL]),\n        wbStructSK([0, 1], 'Entry Point', [\n          wbInteger('Entry Point', itU8, wbEntryPointsEnum, cpNormal, True, nil{, wbPERKEntryPointAfterSet}),\n          wbInteger('Function', itU8, wbEnum([\n            {0} 'Unknown 0',\n            {1} 'Set Value', // EPFT=1\n            {2} 'Add Value', // EPFT=1\n            {3} 'Multiply Value', // EPFT=1\n            {4} 'Add Range To Value', // EPFT=2\n            {5} 'Add Actor Value Mult', // EPFT=2\n            {6} 'Absolute Value', // no params\n            {7} 'Negative Absolute Value', // no params\n            {8} 'Add Leveled List', // EPFT=3\n            {9} 'Add Activate Choice', // EPFT=4\n           {10} 'Select Spell', // EPFT=5\n           {11} 'Select Text', // EPFT=6\n           {12} 'Set to Actor Value Mult', // EPFT=2\n           {13} 'Multiply Actor Value Mult', // EPFT=2\n           {14} 'Multiply 1 + Actor Value Mult', // EPFT=2\n           {15} 'Set Text' // EPFT=7\n          ])),\n          wbInteger('Perk Condition Tab Count', itU8, nil, cpIgnore)\n        ])\n      ], cpNormal, True),\n\n      wbRStructsSK('Perk Conditions', 'Perk Condition', [0], [\n        wbInteger(PRKC, 'Run On (Tab Index)', itS8{, wbPRKCToStr, wbPRKCToInt}),\n        wbCTDAsReq\n      ], [], cpNormal, False{, nil, nil, wbPERKPRKCDontShow}),\n\n      wbRStruct('Function Parameters', [\n        wbInteger(EPFT, 'Type', itU8, wbEnum([\n          {0} 'None',\n          {1} 'Float',\n          {2} 'Float/AV,Float',\n          {3} 'LVLI',\n          {4} 'SPEL,lstring,flags',\n          {5} 'SPEL',\n          {6} 'string',\n          {7} 'lstring',\n          {8} 'AVIF'\n        ])),\n        // case(EPFT) of\n        // 1: EPFD=float\n        // 2: EPFD=float,float\n        // 3: EPFD=LVLI\n        // 4: EPFD=SPEL, EPF2=lstring, EPF3=int32 flags\n        // 5: EPFD=SPEL\n        // 6: EPFD=string\n        // 7: EPFD=lstring\n\n        wbInteger(EPFB, 'Perk Entry ID (unique)', itU16),\n        wbLString(EPF2, 'Button Label', 0, cpTranslate),\n        wbStruct(EPF3, 'Script Flags', [\n          wbInteger('Script Flags', itU8, wbFlags([\n            'Run Immediately',\n            'Replace Default'\n          ])),\n          wbByteArray('Unknown', 1)\n        ]),\n        wbUnion(EPFD, 'Data', wbEPFDDecider, [\n          {0} wbByteArray('Unknown'),\n          {1} wbFloat('Float'),\n          {2} wbStruct('Float, Float', [\n                wbFloat('Float 1'),\n                wbFloat('Float 2')\n              ]),\n          {3} wbFormIDCk('Leveled Item', [LVLI]),\n          {4} wbFormIDCk('Spell', [SPEL]),\n          {5} wbFormIDCk('Spell', [SPEL]),\n          {6} wbString('Text', 0, cpTranslate),\n          {7} wbLString('Text', 0, cpTranslate),\n          {8} wbStruct('Actor Value, Float', [\n                wbActorValue, // wbInteger('Actor Value', itU32, wbEPFDActorValueToStr, wbEPFDActorValueToInt),\n                wbFloat('Float')\n              ])\n        ], cpNormal, False{, wbEPFDDontShow})\n      ], [], cpNormal, False{, wbPERKPRKCDontShow}),\n      wbEmpty(PRKF, 'End Marker', cpIgnore, True)\n    ], [])\n  ]);\n\n  wbRecord(BPTD, 'Body Part Data', [\n    wbEDID,\n    wbMODL,\n    wbRArrayS('Body Parts',\n      wbRStructSK([1], 'Body Part', [\n        wbLString(BPTN, 'Part Name', 0, cpTranslate), // optional\n        wbString(BPNN, 'Part Node', 0, cpNormal, True),\n        wbString(BPNT, 'VATS Target', 0, cpNormal, True),\n        wbStruct(BPND, '', [\n          wbFloat('Damage Mult'),\n          wbFormIDCk('Explodable - Debris', [DEBR, NULL]),\n          wbFormIDCk('Explodable - Explosion', [EXPL, NULL]),\n          wbFloat('Explodable - Debris Scale'),\n          wbFormIDCk('Severable - Debris', [DEBR, NULL]),\n          wbFormIDCk('Severable - Explosion', [EXPL, NULL]),\n          wbFloat('Severable - Debris Scale'),\n          wbFloat('Cut - Min'),\n          wbFloat('Cut - Max'),\n          wbFloat('Cut - Radius'),\n          wbFloat('Gore Effects - Local Rotate X', cpNormal, True, wbRotationFactor, wbRotationScale, nil, RadiansNormalize),\n          wbFloat('Gore Effects - Local Rotate Y', cpNormal, True, wbRotationFactor, wbRotationScale, nil, RadiansNormalize),\n          wbFloat('Cut - Tesselation'),\n          wbFormIDCk('Severable - Impact DataSet', [IPDS, NULL]),\n          wbFormIDCk('Explodable - Impact DataSet', [IPDS, NULL]),\n          wbFloat('Explodable - Limb Replacement Scale'),\n          wbInteger('Flags', itU8, wbFlags([\n            {0x01} 'Severable',\n            {0x02} 'Hit Reaction',\n            {0x04} 'Hit Reaction - Default',\n            {0x08} 'Explodable',\n            {0x10} 'Cut - Meat Cap Sever',\n            {0x20} 'On Cripple',\n            {0x40} 'Explodable - Absolute Chance',\n            {0x80} 'Show Cripple Geometry'\n          ])),\n          wbInteger('Part Type', itU8, wbEnum([\n            { 0} 'Torso',\n            { 1} 'Head1',\n            { 2} 'Eye',\n            { 3} 'LookAt',\n            { 4} 'Fly Grab',\n            { 5} 'Head2',\n            { 6} 'LeftArm1',\n            { 7} 'LeftArm2',\n            { 8} 'RightArm1',\n            { 9} 'RightArm2',\n            {10} 'LeftLeg1',\n            {11} 'LeftLeg2',\n            {12} 'LeftLeg3',\n            {13} 'RightLeg1',\n            {14} 'RightLeg2',\n            {15} 'RightLeg3',\n            {16} 'Brain',\n            {17} 'Weapon',\n            {18} 'Root',\n            {19} 'COM',\n            {20} 'Pelvis',\n            {21} 'Camera',\n            {22} 'Offset Root',\n            {23} 'Left Foot',\n            {24} 'Right Foot',\n            {25} 'Face Target Source'\n          ])),\n          wbInteger('Health Percent', itU8),\n          wbFormIDCk('Actor Value', [AVIF, NULL]),\n          wbInteger('To Hit Chance', itU8),\n          wbInteger('Explodable - Explosion Chance %', itU8),\n          wbInteger('Non-Lethal Dismemberment Chance', itU8),\n          wbInteger('Severable - Debris Count', itU8),\n          wbInteger('Explodable - Debris Count', itU8),\n          wbInteger('Severable - Decal Count', itU8),\n          wbInteger('Explodable - Decal Count', itU8),\n          wbInteger('Geometry Segment Index', itU8),\n          wbFormIDCk('On Cripple - Art Object', [ARTO, NULL]),\n          wbFormIDCk('On Cripple - Debris', [DEBR, NULL]),\n          wbFormIDCk('On Cripple - Explosion', [EXPL, NULL]),\n          wbFormIDCk('On Cripple - Impact DataSet', [IPDS, NULL]),\n          wbFloat('On Cripple - Debris Scale'),\n          wbInteger('On Cripple - Debris Count', itU8),\n          wbInteger('On Cripple - Decal Count', itU8)\n        ], cpNormal, True),\n        wbString(NAM1, 'Limb Replacement Model', 0, cpNormal, True),\n        wbString(NAM4, 'Gore Effects - Target Bone', 0, cpNormal, True),\n        wbByteArray(NAM5, 'Texture Files Hashes', 0, cpNormal),\n        wbString(ENAM, 'Hit Reaction - Start'),\n        wbString(FNAM, 'Hit Reaction - End'),\n        wbFormIDCk(BNAM, 'Gore Effects - Dismember Blood Art', [ARTO]),\n        wbFormIDCk(INAM, 'Gore Effects - Blood Impact Material Type', [MATT]),\n        wbFormIDCk(JNAM, 'On Cripple - Blood Impact Material Type', [MATT]),\n        wbFormIDCk(CNAM, 'Meat Cap TextureSet', [TXST]),\n        wbFormIDCk(NAM2, 'Collar TextureSet', [TXST]),\n        wbString(DNAM, 'Twist Variable Prefix')\n      ], [], cpNormal, False, nil, True)\n    )\n  ]);\n\n  wbRecord(ADDN, 'Addon Node', [\n    wbEDID,\n    wbOBNDReq,\n    wbMODL,\n    wbInteger(DATA, 'Node Index', itS32, nil, cpNormal, True),\n    wbFormIDCk(SNAM, 'Sound', [SNDR]),\n    wbFormIDCk(LNAM, 'Light', [LIGH]),\n    wbStruct(DNAM, 'Data', [\n      wbInteger('Master Particle System Cap', itU16),\n      wbInteger('Flags', itU16, wbEnum([\n        'No Master Particle System',\n        'Master Particle System',\n        'Always Loaded',\n        'Master Particle System and Always Loaded'\n      ]))\n    ], cpNormal, True)\n  ]);\nend;\n\nprocedure DefineFO4h;\nbegin\n  wbRecord(AVIF, 'Actor Value Information', [\n    wbEDID,\n    wbFULL,\n    wbDESCReq,\n    wbLString(ANAM, 'Abbreviation', 0, cpTranslate),\n    wbFloat(NAM0, 'Default Value'), // Prior to form version 81, it was either 0.0, 1.0 or 100.0, so scale or multiplier ?\n    wbInteger(AVFL, 'Flags', itU32, wbFlags([ // 32 bits Flags, it used to impact NAM0 loading (bits 10, 11, 12) (even though it loads later :) )\n      'Unknown 1',\n      'Unknown 2',\n      'Unknown 3',\n      'Unknown 4',\n      'Unknown 5',\n      'Unknown 6',\n      'Unknown 7',\n      'Unknown 8',\n      'Unknown 9',\n      'Unknown 10',\n      'Unknown 11',\n      'Unknown 12',\n      'Unknown 13',\n      'Unknown 14',\n      'Unknown 15',\n      'Unknown 16',\n      'Unknown 17',\n      'Unknown 18',\n      'Unknown 19',\n      'Unknown 20',\n      'Minimum 1',\n      'Maximum 10',\n      'Maximum 100',\n      'Multiply By 100',\n      'Percentage',\n      'Unknown 26',\n      'Damage Is Positive',\n      'God Mode Immune',\n      'Unknown 29',\n      'Unknown 30',\n      'Unknown 31',\n      'Hardcoded'\n    ])),\n    wbInteger(NAM1, 'Type', itU32, wbEnum([\n      'Derived Attribute',\n      'Special (Attribute)',\n      'Skill',\n      'AI Attribute',\n      'Resistance',\n      'Condition',\n      'Charge',\n      'Int Value',\n      'Variable',\n      'Resource'\n    ]))\n  ]); // S.P.E.C.I.A.L start at index 5, so FormID 0x2bc+5 to 0x2bc+11, RadResistIngestion at index 0x29\n\n  wbRecord(CAMS, 'Camera Shot', [\n    wbEDID,\n    wbMODL,\n    wbCTDAs,\n    wbStruct(DATA, 'Data', [\n      wbInteger('Action', itU32, wbEnum([\n        {0} 'Shoot',\n        {1} 'Fly',\n        {2} 'Hit',\n        {3} 'Zoom'\n      ])),\n      wbInteger('Location', itU32, wbEnum([\n        {0} 'Attacker',\n        {1} 'Projectile',\n        {2} 'Target',\n        {3} 'Lead Actor'\n      ])),\n      wbInteger('Target', itU32, wbEnum([\n        {0} 'Attacker',\n        {1} 'Projectile',\n        {2} 'Target',\n        {3} 'Lead Actor'\n      ])),\n      wbInteger('Flags', itU32, wbFlags([\n        {0x00000001} 'Position Follows Location',\n        {0x00000002} 'Rotation Follows Target',\n        {0x00000004} 'Don''t Follow Bone',\n        {0x00000008} 'First Person Camera',\n        {0x00000010} 'No Tracer',\n        {0x00000020} 'Start At Time Zero',\n        {0x00000040} 'Don''t Reset Location Spring',\n        {0x00000080} 'Don''t Reset Target Spring'\n      ])),\n      wbStruct('Time Multipliers', [\n        wbFloat('Player'),\n        wbFloat('Target'),\n        wbFloat('Global')\n      ]),\n      wbFloat('Max Time'),\n      wbFloat('Min Time'),\n      wbFloat('Target % Between Actors'),\n      wbFloat('Near Target Distance'),\n      wbFloat('Location Spring'),\n      wbFloat('Target Spring'),\n      wbStruct('Rotation Offset', [\n        wbFloat('X'),\n        wbFloat('Y'),\n        wbFloat('Z')\n      ])\n    ], cpNormal, True, nil, 9),\n    wbFormIDCk(MNAM, 'Image Space Modifier', [IMAD])\n  ]);\n\n  wbRecord(CPTH, 'Camera Path', [\n    wbEDID,\n    wbCTDAs,\n    wbArray(ANAM, 'Related Camera Paths', wbFormIDCk('Related Camera Path', [CPTH, NULL]), ['Parent', 'Previous Sibling'], cpNormal, True),\n    wbInteger(DATA, 'Camera Zoom / Flags', itU8, wbFlags([\n      {0x01} 'Disable',\n      {0x02} 'Shot List',\n      {0x04} 'Dynamic Camera Times',\n      {0x08} 'Unknown 3',\n      {0x10} 'Unknown 4',\n      {0x20} 'Unknown 5',\n      {0x40} 'Randomize Paths',\n      {0x80} 'Not Must Have Camera Shots'\n    ]), cpNormal, True),\n    wbRArray('Camera Shots', wbFormIDCk(SNAM, 'Camera Shot', [CAMS]))\n  ]);\n\n  wbRecord(VTYP, 'Voice Type', [\n    wbEDID,\n    wbInteger(DNAM, 'Flags', itU8, wbFlags([\n      'Allow Default Dialog',\n      'Female'\n    ]), cpNormal, True)\n  ]);\n\n  wbRecord(MATT, 'Material Type', [\n    wbEDID,\n    wbFormIDCk(PNAM, 'Material Parent', [MATT, NULL]),\n    wbString(MNAM, 'Material Name'),\n    wbStruct(CNAM, 'Havok Display Color', [\n      wbFloat('Red', cpNormal, True, 255, 0),\n      wbFloat('Green', cpNormal, True, 255, 0),\n      wbFloat('Blue', cpNormal, True, 255, 0)\n    ]),\n    wbFloat(BNAM, 'Buoyancy'),\n    wbInteger(FNAM, 'Flags', itU32, wbFlags([\n      'Stair Material',\n      'Arrows Stick',\n      'Can Tunnel'\n    ], False)),\n    wbFormIDCk(HNAM, 'Havok Impact Data Set', [IPDS]),\n    wbString(ANAM, 'Breakable FX'),\n    wbMODT\n  ]);\n\n  wbRecord(IPCT, 'Impact', [\n    wbEDID,\n    wbMODL,\n    wbStruct(DATA, '', [\n      wbFloat('Effect - Duration'),\n      wbInteger('Effect - Orientation', itU32, wbEnum([\n        'Surface Normal',\n        'Projectile Vector',\n        'Projectile Reflection'\n      ])),\n      wbFloat('Angle Threshold'),\n      wbFloat('Placement Radius'),\n      wbInteger('Sound Level', itU32, wbSoundLevelEnum),\n      wbInteger('Flags', itU8, wbFlags([\n        {0x01} 'No Decal Data'\n      ])),\n      wbInteger('Impact Result', itU8, wbEnum([\n         {0} 'Default',\n         {1} 'Destroy',\n         {2} 'Bounce',\n         {3} 'Impale',\n         {4} 'Stick'\n      ])),\n      wbByteArray('Unknown', 2)\n    ], cpNormal, True),\n    wbDODT,\n    wbFormIDCk(DNAM, 'Texture Set', [TXST]),\n    wbFormIDCk(ENAM, 'Secondary Texture Set', [TXST]),\n    wbFormIDCk(SNAM, 'Sound 1', [SNDR]),\n    wbFormIDCk(NAM1, 'Sound 2', [SNDR]),\n    wbFormIDCk(NAM3, 'Footstep Explosion', [EXPL]),\n    wbFormIDCk(NAM2, 'Hazard', [HAZD]),\n    wbFloat(FNAM, 'Footstep Particle Max Dist')\n  ]);\n\n  wbRecord(IPDS, 'Impact Data Set', [\n    wbEDID,\n    wbRArrayS('Data', wbStructSK(PNAM, [0], '', [\n      wbFormIDCk('Material', [MATT]),\n      wbFormIDCk('Impact', [IPCT])\n    ]))\n  ]);\n\n  wbRecord(ECZN, 'Encounter Zone', [\n    wbEDID,\n    wbStruct(DATA, '', [\n      wbFormIDCkNoReach('Owner', [NPC_, FACT, NULL]),\n      wbFormIDCk('Location', [LCTN, NULL]),\n      wbInteger('Rank', itS8),\n      wbInteger('Min Level', itS8),\n      wbInteger('Flags', itU8, wbFlags([\n        'Never Resets',\n        'Match PC Below Minimum Level',\n        'Disable Combat Boundary',\n        'Workshop'\n      ])),\n      wbInteger('Max Level', itS8)\n    ], cpNormal, True)\n  ]);\n\n  wbRecord(LCTN, 'Location', [\n    wbEDID,\n\n    wbArray(ACPR, 'Actor Cell Persistent Reference', wbStruct('', [\n      wbFormIDCk('Actor', sigReferences, False, cpBenign),\n      wbFormIDCk('Location', [WRLD, CELL], False, cpBenign),\n      wbInteger('Grid Y', itS16, nil, cpBenign),\n      wbInteger('Grid X', itS16, nil, cpBenign)\n    ])),\n    wbArray(LCPR, 'Location Cell Persistent Reference', wbStruct('', [\n      wbFormIDCk('Actor', sigReferences, False, cpBenign),\n      wbFormIDCk('Location', [WRLD, CELL], False, cpBenign),\n      wbInteger('Grid Y', itS16, nil, cpBenign),\n      wbInteger('Grid X', itS16, nil, cpBenign)\n    ])),\n    wbArray(RCPR, 'Reference Cell Persistent Reference', wbFormIDCk('Ref', [ACHR, REFR], False, cpBenign)),\n\n    wbArray(ACUN, 'Actor Cell Unique', wbStruct('', [\n      wbFormIDCk('Actor', [NPC_], False, cpBenign),\n      wbFormIDCk('Ref', [ACHR], False, cpBenign),\n      wbFormIDCk('Location', [LCTN, NULL], False, cpBenign)\n    ])),\n    wbArray(LCUN, 'Location Cell Unique', wbStruct('', [\n      wbFormIDCk('Actor', [NPC_], False, cpBenign),\n      wbFormIDCk('Ref', [ACHR], False, cpBenign),\n      wbFormIDCk('Location', [LCTN, NULL], False, cpBenign)\n    ])),\n    wbArray(RCUN, 'Reference Cell Unique', wbFormIDCk('Actor', [NPC_], False, cpBenign)),\n\n    wbArray(ACSR, 'Actor Cell Static Reference', wbStruct('', [\n      wbFormIDCk('Loc Ref Type', [LCRT], False, cpBenign),\n      wbFormIDCk('Marker', sigReferences, False, cpBenign),\n      wbFormIDCk('Location', [WRLD, CELL], False, cpBenign),\n      wbInteger('Grid Y', itS16, nil, cpBenign),\n      wbInteger('Grid X', itS16, nil, cpBenign)\n    ])),\n    wbArray(LCSR, 'Location Cell Static Reference', wbStruct('', [\n      wbFormIDCk('Loc Ref Type', [LCRT], False, cpBenign),\n      wbFormIDCk('Marker', sigReferences, False, cpBenign),\n      wbFormIDCk('Location', [WRLD, CELL], False, cpBenign),\n      wbInteger('Grid Y', itS16, nil, cpBenign),\n      wbInteger('Grid X', itS16, nil, cpBenign)\n    ])),\n    wbArray(RCSR, 'Reference Cell Static Reference', wbFormIDCk('Ref', [ACHR, REFR], False, cpBenign)),\n\n    wbRArray('Actor Cell Encounter Cell',\n      wbStruct(ACEC, 'Unknown', [\n        wbFormIDCk('Location', [WRLD, CELL], False, cpBenign),\n        wbArray('Coordinates', wbStruct('', [\n          wbInteger('Grid Y', itS16, nil, cpBenign),\n          wbInteger('Grid X', itS16, nil, cpBenign)\n        ]))\n      ])\n    ),\n    wbRArray('Location Cell Encounter Cell',\n      wbStruct(LCEC, 'Unknown', [\n        wbFormIDCk('Location', [WRLD, CELL], False, cpBenign),\n        wbArray('Coordinates', wbStruct('', [\n          wbInteger('Grid Y', itS16, nil, cpBenign),\n          wbInteger('Grid X', itS16, nil, cpBenign)\n        ]))\n      ])\n    ),\n    wbRArray('Reference Cell Encounter Cell',\n      wbStruct(RCEC, 'Unknown', [\n        wbFormIDCk('Location', [WRLD, CELL], False, cpBenign),\n        wbArray('Coordinates', wbStruct('', [\n          wbInteger('Grid Y', itS16, nil, cpBenign),\n          wbInteger('Grid X', itS16, nil, cpBenign)\n        ]))\n      ])\n    ),\n\n    wbArray(ACID, 'Actor Cell Marker Reference', wbFormIDCk('Ref', sigReferences, False, cpBenign)),\n    wbArray(LCID, 'Location Cell Marker Reference', wbFormIDCk('Ref', sigReferences, False, cpBenign)),\n\n    wbArray(ACEP, 'Actor Cell Enable Point', wbStruct('', [\n      wbFormIDCk('Actor', sigReferences, False, cpBenign),\n      wbFormIDCk('Ref', sigReferences, False, cpBenign),\n      wbInteger('Grid Y', itS16, nil, cpBenign),\n      wbInteger('Grid X', itS16, nil, cpBenign)\n    ])),\n    wbArray(LCEP, 'Location Cell Enable Point', wbStruct('', [\n      wbFormIDCk('Actor', sigReferences, False, cpBenign),\n      wbFormIDCk('Ref', sigReferences, False, cpBenign),\n      wbInteger('Grid Y', itS16, nil, cpBenign),\n      wbInteger('Grid X', itS16, nil, cpBenign)\n    ])),\n\n    wbFULL,\n    wbKSIZ,\n    wbKWDAs,\n    wbFormIDCk(PNAM, 'Parent Location', [LCTN, NULL]),\n    wbFormIDCk(NAM1, 'Music', [MUSC, NULL]),\n    wbFormIDCk(FNAM, 'Unreported Crime Faction', [FACT]),\n    wbFormIDCk(MNAM, 'World Location Marker Ref', [REFR, ACHR]),\n    wbFloat(RNAM, 'World Location Radius'),\n    //wbFormIDCk(NAM0, 'Horse Marker Ref', [REFR]),\n    wbFloat(ANAM, 'Unknown'),\n    wbCNAM\n  ], False, nil, cpNormal, False, nil, wbKeywordsAfterSet);\n\nend;\n\n{this is required to prevent XE6 compiler error}\ntype\n  TVarRecs = array of TVarRec;\n\nfunction CombineVarRecs(const a, b : array of const)\n                                   : TVarRecs;\nbegin\n  SetLength(Result, Length(a) + Length(b));\n  if Length(a) > 0 then\n    Move(a[0], Result[0], SizeOf(TVarRec) * Length(a));\n  if Length(b) > 0 then\n    Move(b[0], Result[Length(a)], SizeOf(TVarRec) * Length(b));\nend;\n\nfunction MakeVarRecs(const a : array of const)\n                             : TVarRecs;\nbegin\n  SetLength(Result, Length(a));\n  if Length(a) > 0 then\n    Move(a[0], Result[0], SizeOf(TVarRec) * Length(a));\nend;\n\n\nprocedure DefineFO4i;\nvar\n  a, b, c : TVarRecs;\nbegin\n  wbRecord(MESG, 'Message', [\n    wbEDID,\n    wbDESCReq,\n    wbFULL,\n    wbFormIDCk(INAM, 'Icon (unused)', [NULL], False, cpIgnore, True), // leftover\n    wbFormIDCk(QNAM, 'Owner Quest', [QUST]),\n    wbInteger(DNAM, 'Flags', itU32, wbFlags([\n      'Message Box',\n      'Delay Initial Display'\n    ]), cpNormal, True, False, nil, wbMESGDNAMAfterSet),\n    wbInteger(TNAM, 'Display Time', itU32, nil, cpNormal, False, False, wbMESGTNAMDontShow),\n    wbString(SNAM, 'SWF'),\n    wbLString(NNAM, 'Short Title', 0, cpTranslate),\n    wbRStructs('Menu Buttons', 'Menu Button', [\n      wbLString(ITXT, 'Button Text', 0, cpTranslate),\n      wbCTDAs\n    ], [])\n  ], False, nil, cpNormal, False, wbMESGAfterLoad);\n\n  a := MakeVarRecs([\n                        0, 'None',\n          Sig2Int('AAAC'), 'Action Activate',\n          Sig2Int('AAB1'), 'Action Bleedout Start',\n          Sig2Int('AAB2'), 'Action Bleedout Stop',\n          Sig2Int('AABA'), 'Action Block Anticipate',\n          Sig2Int('AABH'), 'Action Block Hit',\n          Sig2Int('AABI'), 'Action Bumped Into',\n          Sig2Int('AADA'), 'Action Dual Attack',\n          Sig2Int('AADE'), 'Action Death',\n          Sig2Int('AADL'), 'Action Dual Release',\n          Sig2Int('AADR'), 'Action Draw',\n          Sig2Int('AADW'), 'Action Death Wait',\n          Sig2Int('AAF1'), 'Action Fly Start',\n          Sig2Int('AAF2'), 'Action Fly Stop',\n          Sig2Int('AAFA'), 'Action Fall',\n          Sig2Int('AAFQ'), 'Action Force Equip',\n          Sig2Int('AAGU'), 'Action Get Up',\n          Sig2Int('AAH1'), 'Action Hover Start',\n          Sig2Int('AAH2'), 'Action Hover Stop',\n          Sig2Int('AAID'), 'Action Idle',\n          Sig2Int('AAIS'), 'Action Idle Stop',\n          Sig2Int('AAJP'), 'Action Jump',\n          Sig2Int('AALA'), 'Action Left Attack',\n          Sig2Int('AALD'), 'Action Left Ready',\n          Sig2Int('AALI'), 'Action Left Interrupt',\n          Sig2Int('AALK'), 'Action Look',\n          Sig2Int('AALM'), 'Action Large Movement Delta',\n          Sig2Int('AALN'), 'Action Land',\n          Sig2Int('AALR'), 'Action Left Release',\n          Sig2Int('AALS'), 'Action Left Sync Attack',\n          Sig2Int('AAMT'), 'Action Mantle',\n          Sig2Int('AAOE'), 'Action AoE Attack',\n          Sig2Int('AAPA'), 'Action Right Power Attack',\n          Sig2Int('AAPE'), 'Action Path End',\n          Sig2Int('AAPS'), 'Action Path Start',\n          Sig2Int('AAR2'), 'Action Large Recoil',\n          Sig2Int('AARA'), 'Action Right Attack',\n          Sig2Int('AARC'), 'Action Recoil',\n          Sig2Int('AARD'), 'Action Right Ready',\n          Sig2Int('AARI'), 'Action Right Interrupt',\n          Sig2Int('AARR'), 'Action Right Release',\n          Sig2Int('AARS'), 'Action Right Sync Attack',\n          Sig2Int('AAS1'), 'Action Stagger Start',\n          Sig2Int('AASC'), 'Action Shield Change',\n          Sig2Int('AASH'), 'Action Sheath',\n          Sig2Int('AASN'), 'Action Sneak',\n          Sig2Int('AASP'), 'Action Sprint Stop',\n          Sig2Int('AASS'), 'Action Summoned Start',\n          Sig2Int('AAST'), 'Action Sprint Start',\n          Sig2Int('AASW'), 'Action Swim State Change',\n          Sig2Int('AAVC'), 'Action Voice',\n          Sig2Int('AAVD'), 'Action Voice Ready',\n          Sig2Int('AAVI'), 'Action Voice Interrupt',\n          Sig2Int('AAVR'), 'Action Voice Release',\n          Sig2Int('AAWH'), 'Action Ward Hit',\n          Sig2Int('ABLA'), 'Action Begin Looping Activate',\n          Sig2Int('ABOL'), 'Action Bolt Charge',\n          Sig2Int('ABSE'), 'Art Object Absorb Effect',\n          Sig2Int('ACHI'), 'Action Hide',\n          Sig2Int('ACSS'), 'Action Cover Sprint Start',\n          Sig2Int('ACTN'), 'Action Tunnel',\n          Sig2Int('ACWR'), 'Action Cower',\n          Sig2Int('ADGE'), 'Action Dodge',\n          Sig2Int('ADPA'), 'Action Dual Power Attack',\n          Sig2Int('AECL'), 'Action Enter Cover',\n          Sig2Int('AELA'), 'Action End Looping Activate',\n          Sig2Int('AENC'), 'Action Enter Combat',\n          Sig2Int('AENI'), 'Action Dialogue Enter',\n          Sig2Int('AEVD'), 'Action Evade',\n          Sig2Int('AEXC'), 'Action Exit Cover',\n          Sig2Int('AEXI'), 'Action Dialogue Exit',\n          Sig2Int('AEXT'), 'Action Exit Combat',\n          Sig2Int('AFCH'), 'Action Fire Charge',\n          Sig2Int('AFCO'), 'Action Fire Charge Hold',\n          Sig2Int('AFEM'), 'Action Fire Empty',\n          Sig2Int('AFIA'), 'Action Fire Auto',\n          Sig2Int('AFIS'), 'Action Fire Single',\n          Sig2Int('AFLT'), 'Action Flip-Throw',\n          Sig2Int('AFNP'), 'Keyword Activator Furniture No Player',\n          Sig2Int('AGAL'), 'Action Gun Alert',\n          Sig2Int('AGCS'), 'Action Gun Charge Start',\n          Sig2Int('AGDN'), 'Action Gun Down',\n          Sig2Int('AGRX'), 'Action Gun Relaxed',\n          Sig2Int('AGRY'), 'Action Gun Ready',\n          Sig2Int('AIDW'), 'Action Idle Warn',\n          Sig2Int('AIEN'), 'Action Interaction Enter',\n          Sig2Int('AIEQ'), 'Action Interaction Exit Quick',\n          Sig2Int('AIEX'), 'Action Interaction Exit',\n          Sig2Int('AILN'), 'Action Dialogue Listen Negative',\n          Sig2Int('AILp'), 'Action Dialogue Listen Positive',\n          Sig2Int('AILQ'), 'Action Dialogue Listen Question',\n          Sig2Int('AINT'), 'Action Intimidate',\n          Sig2Int('AIVC'), 'Verlet Cape',\n          Sig2Int('AIXA'), 'Action Interaction Exit Alternate',\n          Sig2Int('AKDN'), 'Action Knockdown',\n          Sig2Int('ALIC'), 'Action Limb Critical',\n          Sig2Int('ALIK'), 'Alcohol Item keyword',\n          Sig2Int('ALPA'), 'Action Left Power Attack',\n          Sig2Int('ALTI'), 'Action Dialogue Listen',\n          Sig2Int('AMBK'), 'Action Move Backward',\n          Sig2Int('AMEL'), 'Action Melee',\n          Sig2Int('AMFD'), 'Action Move Forward',\n          Sig2Int('AMLT'), 'Action Move Left',\n          Sig2Int('AMRT'), 'Action Move Right',\n          Sig2Int('AMSP'), 'Action Move Stop',\n          Sig2Int('AMST'), 'Action Move Start',\n          Sig2Int('ANML'), 'Keyword Animal',\n          Sig2Int('ANSC'), 'Action NonSupport Contact',\n          Sig2Int('AODA'), 'Keyword Armor Material Daedric',\n          Sig2Int('AODB'), 'Keyword Armor Material Dragonbone',\n          Sig2Int('AODP'), 'Keyword Armor Material Dragonplate',\n          Sig2Int('AODS'), 'Keyword Armor Material Dragonscale',\n          Sig2Int('AODW'), 'Keyword Armor Material Dwarven',\n          Sig2Int('AOEB'), 'Keyword Armor Material Ebony',\n          Sig2Int('AOEL'), 'Keyword Armor Material Elven',\n          Sig2Int('AOES'), 'Keyword Armor Material ElvenSplinted',\n          Sig2Int('AOFE'), 'Keyword Armor Material Iron',\n          Sig2Int('AOFL'), 'Keyword Armor Material FullLeather',\n          Sig2Int('AOGL'), 'Keyword Armor Material Glass',\n          Sig2Int('AOHI'), 'Keyword Armor Material Hide',\n          Sig2Int('AOIB'), 'Keyword Armor Material IronBanded',\n          Sig2Int('AOIH'), 'Keyword Armor Material ImperialHeavy',\n          Sig2Int('AOIM'), 'Keyword Armor Material Imperial',\n          Sig2Int('AOIR'), 'Keyword Armor Material ImperialReinforced',\n          Sig2Int('AOOR'), 'Keyword Armor Material Orcish',\n          Sig2Int('AOSC'), 'Keyword Armor Material Scaled',\n          Sig2Int('AOSD'), 'Keyword Armor Material Studded',\n          Sig2Int('AOSK'), 'Keyword Armor Material Stormcloak',\n          Sig2Int('AOSP'), 'Keyword Armor Material SteelPlate',\n          Sig2Int('AOST'), 'Keyword Armor Material Steel',\n          Sig2Int('APIC'), 'Action Pipboy Close',\n          Sig2Int('APID'), 'Action Pipboy Data',\n          Sig2Int('APII'), 'Action Pipboy Inventory',\n          Sig2Int('APIM'), 'Action Pipboy Map',\n          Sig2Int('APIN'), 'Action Pipboy Inspect',\n          Sig2Int('APIP'), 'Action Pipboy',\n          Sig2Int('APIS'), 'Action Pipboy Stats',\n          Sig2Int('APIT'), 'Action Pipboy Tab',\n          Sig2Int('APIZ'), 'Action Pipboy Zoom',\n          Sig2Int('APLH'), 'Action Pipboy Load Holotape',\n          Sig2Int('APLN'), 'Action Dialogue Listen Neutral',\n          Sig2Int('APNC'), 'Action Panic',\n          Sig2Int('APPS'), 'Action Pipboy Select',\n          Sig2Int('APR0'), 'Action Pipboy Radio Off',\n          Sig2Int('APR1'), 'Action Pipboy Radio On',\n          Sig2Int('APSH'), 'Allow Player Shout',\n          Sig2Int('APTP'), 'Action Pipboy Tab Previous',\n          Sig2Int('AREL'), 'Action Reload',\n          Sig2Int('ARGI'), 'Action Ragdoll Instant',\n          Sig2Int('ARTL'), 'Armor Material List',\n          Sig2Int('ASFL'), 'Action Shuffle',\n          Sig2Int('ASID'), 'Action Idle Stop Instant',\n          Sig2Int('ASIR'), 'Action Sighted Release',\n          Sig2Int('ASIT'), 'Action Sighted',\n          Sig2Int('ATHR'), 'Action Throw',\n          Sig2Int('ATKI'), 'Action Dialogue Talking',\n          Sig2Int('ATLE'), 'Action Turn Left',\n          Sig2Int('ATRI'), 'Action Turn Right',\n          Sig2Int('ATSP'), 'Action Turn Stop',\n          Sig2Int('AVVP'), 'Vampire Available Perks',\n          Sig2Int('AVWP'), 'Unused',\n          Sig2Int('AWWS'), 'Action Waterwalk Start',\n          Sig2Int('AWWW'), 'Bunny Faction',\n          Sig2Int('BAPO'), 'Base Potion',\n          Sig2Int('BAPS'), 'Base Poison',\n          Sig2Int('BEEP'), 'Keyword Robot',\n          Sig2Int('BENA'), 'Base Armor Enchantment',\n          Sig2Int('BENW'), 'Base Weapon Enchantment',\n          Sig2Int('BTMS'), 'Battle Music',\n          Sig2Int('CACA'), 'Commanded Actor Ability',\n          Sig2Int('CHIK'), 'Chem Item keyword',\n          Sig2Int('CLIK'), 'Clothes Item keyword',\n          Sig2Int('CMPX'), 'Complex Scene Object',\n          Sig2Int('CNMK'), 'Keyword nullptr Mod',\n          Sig2Int('COEX'), 'Keyword Conditional Explosion',\n          Sig2Int('COOK'), 'Keyword Cooking Pot',\n          Sig2Int('CSTY'), 'Combat Style',\n          Sig2Int('CWNE'), 'Keyword Civil War Neutral',\n          Sig2Int('CWOK'), 'Keyword Civil War Owner',\n          Sig2Int('DAED'), 'Keyword Daedra',\n          Sig2Int('DBHF'), 'Dark Brotherhood Faction',\n          Sig2Int('DCMS'), 'Dungeon Cleared Music',\n          Sig2Int('DCZM'), 'Dragon Crash Zone Marker',\n          Sig2Int('DDSC'), 'Dialogue Voice Category',\n          Sig2Int('DEIS'), 'Drug Wears Off Image Space',\n          Sig2Int('DFTS'), 'Footstep Set',\n          Sig2Int('DGFL'), 'DialogueFollower Quest',\n          Sig2Int('DIEN'), 'Keyword Disallow Enchanting',\n          Sig2Int('DLMT'), 'Landscape Material',\n          Sig2Int('DLZM'), 'Dragon Land Zone Marker',\n          Sig2Int('DMFL'), 'Default Movement Type: Fly',\n          Sig2Int('DMSN'), 'Default Movement Type: Sneak',\n          Sig2Int('DMSW'), 'Default Movement Type: Swim',\n          Sig2Int('DMWL'), 'Default Movement Type: Default',\n          Sig2Int('DOP2'), 'Dialogue Output Model 3D',\n          Sig2Int('DOP3'), 'Dialogue Output Model 2D',\n          Sig2Int('DRAK'), 'Keyword Dragon',\n          Sig2Int('DTMS'), 'Death Music',\n          Sig2Int('EACA'), 'Every Actor Ability',\n          Sig2Int('EPDF'), 'Eat Package Default Food',\n          Sig2Int('FFFP'), 'Keyword Furniture Forces 1st Person',\n          Sig2Int('FFTP'), 'Keyword Furniture Forces 3rd Person',\n          Sig2Int('FOIK'), 'Food Item Keyword',\n          Sig2Int('FORG'), 'Keyword Forge',\n          Sig2Int('FTEL'), 'Male Face Texture Set: Eyes',\n          Sig2Int('FTGF'), 'Fighters'' Guild Faction',\n          Sig2Int('FTHD'), 'Male Face Texture Set: Head',\n          Sig2Int('FTHF'), 'Female Face Texture Set: Head',\n          Sig2Int('FTMF'), 'Female Face Texture Set: Mouth',\n          Sig2Int('FTML'), 'Favor travel marker location',\n          Sig2Int('FTMO'), 'Male Face Texture Set: Mouth',\n          Sig2Int('FTNP'), 'Furniture Test NPC',\n          Sig2Int('FTRF'), 'Female Face Texture Set: Eyes'\n        ]);\n\n  b := MakeVarRecs([\n          Sig2Int('GCK1'), 'Keyword Generic Craftable Keyword 01',\n          Sig2Int('GCK2'), 'Keyword Generic Craftable Keyword 02',\n          Sig2Int('GCK3'), 'Keyword Generic Craftable Keyword 03',\n          Sig2Int('GCK4'), 'Keyword Generic Craftable Keyword 04',\n          Sig2Int('GCK5'), 'Keyword Generic Craftable Keyword 05',\n          Sig2Int('GCK6'), 'Keyword Generic Craftable Keyword 06',\n          Sig2Int('GCK7'), 'Keyword Generic Craftable Keyword 07',\n          Sig2Int('GCK8'), 'Keyword Generic Craftable Keyword 08',\n          Sig2Int('GCK9'), 'Keyword Generic Craftable Keyword 09',\n          Sig2Int('GCKX'), 'Keyword Generic Craftable Keyword 10',\n          Sig2Int('GFAC'), 'Guard Faction',\n          Sig2Int('GLIK'), 'Gloves Item Keyword',\n          Sig2Int('GOLD'), 'Gold',\n          Sig2Int('GRIK'), 'Grenade Item Keyword',\n          Sig2Int('HBAL'), 'Help Basic Alchemy',\n          Sig2Int('HBBR'), 'Help Barter',\n          Sig2Int('HBCO'), 'Help Basic Cooking',\n          Sig2Int('HBEC'), 'Help Basic Enchanting',\n          Sig2Int('HBFG'), 'Help Basic Forging',\n          Sig2Int('HBFS'), 'Help Favorites',\n          Sig2Int('HBFT'), 'Help Teamate Favor',\n          Sig2Int('HBHJ'), 'Help Jail',\n          Sig2Int('HBJL'), 'Help Journal',\n          Sig2Int('HBLH'), 'Help Low Health',\n          Sig2Int('HBLK'), 'Help Basic Lockpicking PC',\n          Sig2Int('HBLM'), 'Help Low Magicka',\n          Sig2Int('HBLS'), 'Help Low Stamina',\n          Sig2Int('HBLU'), 'Help Leveling up',\n          Sig2Int('HBLX'), 'Help Basic Lockpicking Console',\n          Sig2Int('HBML'), 'Help Basic Smelting',\n          Sig2Int('HBMM'), 'Help Map Menu',\n          Sig2Int('HBOC'), 'Help Basic Object Creation',\n          Sig2Int('HBSA'), 'Help Basic Smithing Armor',\n          Sig2Int('HBSK'), 'Help Skills Menu',\n          Sig2Int('HBSM'), 'Help Basic Smithing Weapon',\n          Sig2Int('HBTA'), 'Help Basic Tanning',\n          Sig2Int('HBWC'), 'Help Weapon Charge',\n          Sig2Int('HCLL'), 'FormList Hair Color List',\n          Sig2Int('HEIK'), 'Helmet Item Keyword',\n          Sig2Int('HFSD'), 'Heartbeat Sound Fast',\n          Sig2Int('HMPC'), 'Help Manual PC',\n          Sig2Int('HMXB'), 'Help Manual XBox',\n          Sig2Int('HRSK'), 'Keyword Horse',\n          Sig2Int('HSSD'), 'Heartbeat Sound Slow',\n          Sig2Int('HVFS'), 'Harvest Failed Sound',\n          Sig2Int('HVSS'), 'Harvest Sound',\n          Sig2Int('HWIK'), 'Heavy Weapon Item keyword',\n          Sig2Int('IMDI'), 'Dialogue Imagespace',\n          Sig2Int('IMID'), 'ImageSpaceModifier for inventory menu.',\n          Sig2Int('IMLH'), 'Imagespace: Low Health',\n          Sig2Int('IMPP'), 'ImageSpaceModifier for Pipboy menu in Power armor.',\n          Sig2Int('IOPM'), 'Interface Output Model',\n          Sig2Int('JRLF'), 'Jarl Faction',\n          Sig2Int('JWLR'), 'Keyword Jewelry',\n          Sig2Int('KHFL'), 'Kinect Help FormList',\n          Sig2Int('KTRW'), 'Teammate Ready Weapon',\n          Sig2Int('KWBR'), 'Color Form',\n          Sig2Int('KWCU'), 'Keyword Cuirass',\n          Sig2Int('KWDM'), 'Keyword DummyObject',\n          Sig2Int('KWDO'), 'Keyword ClearableLocation',\n          Sig2Int('KWGE'), 'Keyword UseGeometryEmitter',\n          Sig2Int('KWMS'), 'Keyword MustStop',\n          Sig2Int('LGH1'), 'Default Light 1',\n          Sig2Int('LGH2'), 'Default Light 2',\n          Sig2Int('LGH3'), 'Default Light 3',\n          Sig2Int('LGH4'), 'Default Light 4',\n          Sig2Int('LGHP'), 'Pipboy Light',\n          Sig2Int('LKHO'), 'Keyword Hold Location',\n          Sig2Int('LKPK'), 'Lockpick',\n          Sig2Int('LMHP'), 'Local Map Hide Plane',\n          Sig2Int('LRRD'), 'LocRefType Resource Destructible',\n          Sig2Int('LRSO'), 'LocRefType Civil War Soldier',\n          Sig2Int('LSIS'), 'Imagespace: Load screen',\n          Sig2Int('MBIK'), 'Med Bag Item Keyword',\n          Sig2Int('MDSC'), 'Music Sound Category',\n          Sig2Int('MFSN'), 'Magic Fail Sound',\n          Sig2Int('MGGF'), 'Mages'' Guild Faction',\n          Sig2Int('MIIK'), 'Mine Item Keyword',\n          Sig2Int('MMCL'), 'Main Menu Cell',\n          Sig2Int('MMSD'), 'Map Menu Looping Sound',\n          Sig2Int('MNTK'), 'Keyword Mount',\n          Sig2Int('MTSC'), 'Master Sound Category',\n          Sig2Int('MVBL'), 'Keyword Movable',\n          Sig2Int('NASD'), 'No-Activation Sound',\n          Sig2Int('NDSC'), 'Non-Dialogue Voice Category',\n          Sig2Int('NMRD'), 'Road Marker',\n          Sig2Int('NPCK'), 'Keyword NPC',\n          Sig2Int('NRNT'), 'Keyword Nirnroot',\n          Sig2Int('P3OM'), 'Player''s Output Model 3rd Person',\n          Sig2Int('PDLC'), 'Pause During Loading Menu Category',\n          Sig2Int('PDMC'), 'Pause During Menu Category Fade',\n          Sig2Int('PDSA'), 'Putdown Sound Armor',\n          Sig2Int('PDSB'), 'Putdown Sound Book',\n          Sig2Int('PDSG'), 'Putdown Sound Generic',\n          Sig2Int('PDSI'), 'Putdown Sound Ingredient',\n          Sig2Int('PDSW'), 'Putdown Sound Weapon',\n          Sig2Int('PFAC'), 'Player Faction',\n          Sig2Int('PIMC'), 'Pause During Menu Category Immediate',\n          Sig2Int('PIVV'), 'Player Is Vampire Variable',\n          Sig2Int('PIWV'), 'UNUSED01',\n          Sig2Int('PLOC'), 'PersistAll Location',\n          Sig2Int('PLST'), 'Default Pack List',\n          Sig2Int('POEQ'), 'Potion Equip',\n          Sig2Int('POPM'), 'Player''s Output Model 1st Person',\n          Sig2Int('PTEM'), 'Package Template',\n          Sig2Int('PTFR'), 'PotentialFollower Faction',\n          Sig2Int('PTNP'), 'Pathing Test NPC',\n          Sig2Int('PUSA'), 'Pickup Sound Armor',\n          Sig2Int('PUSB'), 'Pickup Sound Book',\n          Sig2Int('PUSG'), 'Pickup Sound Generic',\n          Sig2Int('PUSI'), 'Pickup Sound Ingredient',\n          Sig2Int('PUSW'), 'Pickup Sound Weapon',\n          Sig2Int('PVFA'), 'Player Voice Female',\n          Sig2Int('PVFC'), 'Player Voice Female Child',\n          Sig2Int('PVMA'), 'Player Voice Male',\n          Sig2Int('PVMC'), 'Player Voice Male Child',\n          Sig2Int('PWFD'), 'Wait-For-Dialogue Package',\n          Sig2Int('QMEA'), 'Quest Marker Enemy Above',\n          Sig2Int('QMEB'), 'Quest Marker Enemy Below',\n          Sig2Int('QMEN'), 'Quest Marker Enemy',\n          Sig2Int('QMFO'), 'Quest Marker Follower',\n          Sig2Int('QMLO'), 'Quest Marker Location',\n          Sig2Int('RIVR'), 'Vampire Race',\n          Sig2Int('RIVS'), 'Vampire Spells',\n          Sig2Int('RIWR'), 'UNUSED02',\n          Sig2Int('RKIK'), 'Repair Kit Item Keyword',\n          Sig2Int('RUSG'), 'Keyword Reusable SoulGem',\n          Sig2Int('RVBT'), 'Reverb Type',\n          Sig2Int('SALT'), 'Sitting Angle Limit',\n          Sig2Int('SAT1'), 'Keyword Scale Actor To 1.0',\n          Sig2Int('SCSD'), 'Soul Captured Sound',\n          Sig2Int('SFDC'), 'SFX To Fade In Dialogue Category',\n          Sig2Int('SFSN'), 'Shout Fail Sound',\n          Sig2Int('SKLK'), 'Skeleton Key',\n          Sig2Int('SLDM'), 'Snow LOD Material',\n          Sig2Int('SLHD'), 'Snow LOD Material HD',\n          Sig2Int('SMLT'), 'Keyword Smelter',\n          Sig2Int('SMSC'), 'Stats Mute Category',\n          Sig2Int('SPFK'), 'Keyword Special Furniture',\n          Sig2Int('SSSC'), 'Stats Music',\n          Sig2Int('TANN'), 'Keyword Tanning Rack',\n          Sig2Int('TKAM'), 'Keyword Type Ammo',\n          Sig2Int('TKAR'), 'Keyword Type Armor',\n          Sig2Int('TKBK'), 'Keyword Type Book',\n          Sig2Int('TKGS'), 'Telekinesis Grab Sound',\n          Sig2Int('TKIG'), 'Keyword Type Ingredient',\n          Sig2Int('TKKY'), 'Keyword Type Key',\n          Sig2Int('TKMS'), 'Keyword Type Misc',\n          Sig2Int('TKPT'), 'Keyword Type Potion',\n          Sig2Int('TKSG'), 'Keyword Type SoulGem',\n          Sig2Int('TKTS'), 'Telekinesis Throw Sound',\n          Sig2Int('TKWP'), 'Keyword Type Weapon',\n          Sig2Int('TVGF'), 'Thieves'' Guild Faction',\n          Sig2Int('UNDK'), 'Keyword Undead',\n          Sig2Int('URVT'), 'Underwater Reverb Type',\n          Sig2Int('UWLS'), 'Underwater Loop Sound',\n          Sig2Int('VAMP'), 'Keyword Vampire',\n          Sig2Int('VLOC'), 'Virtual Location',\n          Sig2Int('VOEQ'), 'Voice Equip',\n          Sig2Int('WASN'), 'Ward Absorb Sound',\n          Sig2Int('WBSN'), 'Ward Break Sound',\n          Sig2Int('WDSN'), 'Ward Deflect Sound',\n          Sig2Int('WEML'), 'Weapon Material List',\n          Sig2Int('WMDA'), 'Keyword Weapon Material Daedric',\n          Sig2Int('WMDH'), 'Keyword Weapon Material DraugrHoned',\n          Sig2Int('WMDR'), 'Keyword Weapon Material Draugr',\n          Sig2Int('WMDW'), 'Keyword Weapon Material Dwarven',\n          Sig2Int('WMEB'), 'Keyword Weapon Material Ebony',\n          Sig2Int('WMEL'), 'Keyword Weapon Material Elven',\n          Sig2Int('WMFA'), 'Keyword Weapon Material Falmer',\n          Sig2Int('WMFH'), 'Keyword Weapon Material FalmerHoned',\n          Sig2Int('WMGL'), 'Keyword Weapon Material Glass',\n          Sig2Int('WMIK'), 'Workshop Misc Item Keyword',\n          Sig2Int('WMIM'), 'Keyword Weapon Material Imperial',\n          Sig2Int('WMIR'), 'Keyword Weapon Material Iron',\n          Sig2Int('WMOR'), 'Keyword Weapon Material Orcish',\n          Sig2Int('WMST'), 'Keyword Weapon Material Steel',\n          Sig2Int('WMWE'), 'World Map Weather',\n          Sig2Int('WMWO'), 'Keyword Weapon Material Wood',\n          Sig2Int('WPOK'), 'Workshop Player Ownership',\n          Sig2Int('WTBA'), 'Keyword WeaponTypeBoundArrow',\n          Sig2Int('WWSP'), 'UNUSED03'\n        ]);\n\n  c := CombineVarRecs(a, b);\n\n  wbRecord(DOBJ, 'Default Object Manager', [\n    wbEDID,\n    wbArrayS(DNAM, 'Objects',\n      wbStructSK([0], 'Object', [\n        wbInteger('Use', itU32, wbEnum([], c), cpNormalIgnoreEmpty),\n        wbFormID('Object ID', cpNormalIgnoreEmpty)\n      ]), 0, cpNormalIgnoreEmpty, True, wbDOBJObjectsAfterLoad\n    )\n  ]);\n\n  wbRecord(LGTM, 'Lighting Template', [\n    wbEDID,\n    wbStruct(DATA, 'Lighting', [\n      wbByteColors('Ambient Color'),\n      wbByteColors('Directional Color'),\n      wbByteColors('Fog Color Near'),\n      wbFloat('Fog Near'),\n      wbFloat('Fog Far'),\n      wbInteger('Directional Rotation XY', itS32),\n      wbInteger('Directional Rotation Z', itS32),\n      wbFloat('Directional Fade'),\n      wbFloat('Fog Clip Distance'),\n      wbFloat('Fog Power'),\n      wbByteArray('Unused', 32, cpIgnore),\n      wbByteColors('Fog Color Far'),\n      wbFloat('Fog Max'),\n      wbFloat('Light Fade Begin'),\n      wbFloat('Light Fade End'),\n      wbByteArray('Unused', 4, cpIgnore),\n      wbFloat('Near Height Mid'),\n      wbFloat('Near Height Range'),\n      wbByteColors('Fog Color High Near'),\n      wbByteColors('Fog Color High Far'),\n      wbFloat('High Density Scale'),\n      wbFloat('Fog Near Scale'),\n      wbFloat('Fog Far Scale'),\n      wbFloat('Fog High Near Scale'),\n      wbFloat('Fog High Far Scale'),\n      wbFloat('Far Height Mid'),\n      wbFloat('Far Height Range')\n    ], cpNormal, True, nil, 15),\n    wbAmbientColors(DALC),\n    wbFormIDCk(WGDR, 'God Rays', [GDRY])\n  ]);\n\n  wbRecord(MUSC, 'Music Type', [\n    wbEDID,\n    wbInteger(FNAM, 'Flags', itU32, wbFlags([\n      {0x01} 'Plays One Selection',\n      {0x02} 'Abrupt Transition',\n      {0x04} 'Cycle Tracks',\n      {0x08} 'Maintain Track Order',\n      {0x10} 'Unknown 5',\n      {0x20} 'Ducks Current Track',\n      {0x40} 'Doesn''t Queue'\n    ]), cpNormal, True),\n    wbStruct(PNAM, 'Data', [\n      wbInteger('Priority', itU16),\n      wbInteger('Ducking (dB)', itU16, wbDiv(100))\n    ]),\n    wbFloat(WNAM, 'Fade Duration'),\n    wbArray(TNAM, 'Music Tracks', wbFormIDCk('Track', [MUST, NULL]))\n  ]);\n\n  wbRecord(FSTP, 'Footstep', [\n    wbEDID,\n    wbFormIDCk(DATA, 'Impact Data Set', [IPDS, NULL], False, cpNormal, True),\n    wbString(ANAM, 'Tag', 0, cpNormal, True)\n  ]);\n\n  wbRecord(FSTS, 'Footstep Set', [\n    wbEDID,\n    wbStruct(XCNT, 'Count', [\n      wbInteger('Walking', itU32),\n      wbInteger('Running', itU32),\n      wbInteger('Sprinting', itU32),\n      wbInteger('Sneaking', itU32),\n      wbInteger('Swimming', itU32)\n    ], cpNormal, True),\n    wbArray(DATA, 'Footstep Sets', wbFormIDCk('Footstep', [FSTP]), 0, nil, nil, cpNormal, True)\n  ]);\n\n  wbSMNodeFlags := wbFlags([\n    'Random',\n    'Warn if no child quest started'\n  ]);\n\n  wbRecord(SMBN, 'Story Manager Branch Node', [\n    wbEDID,\n    wbFormIDCk(PNAM, 'Parent ', [SMQN, SMBN, SMEN, NULL]),\n    wbFormIDCk(SNAM, 'Child ', [SMQN, SMBN, SMEN, NULL], False, cpBenign),\n    wbCITC,\n    wbCTDAsCount,\n    wbInteger(DNAM, 'Flags', itU32, wbSMNodeFlags),\n    wbUnknown(XNAM)\n  ], False, nil, cpNormal, False, nil, wbConditionsAfterSet);\n\n  wbRecord(SMQN, 'Story Manager Quest Node', [\n    wbEDID,\n    wbFormIDCk(PNAM, 'Parent ', [SMQN, SMBN, SMEN, NULL]),\n    wbFormIDCk(SNAM, 'Child ', [SMQN, SMBN, SMEN, NULL], False, cpBenign),\n    wbCITC,\n    wbCTDAsCount,\n    wbStruct(DNAM, 'Flags', [\n      wbInteger('Node Flags', itU16, wbSMNodeFlags),\n      wbInteger('Quest Flags', itU16, wbFlags([\n        'Do all before repeating',\n        'Shares event',\n        'Num quests to run'\n      ]))\n    ]),\n    wbInteger(XNAM, 'Max concurrent quests', itU32),\n    wbInteger(MNAM, 'Num quests to run', itU32),\n    wbFloat(HNAM, 'Hours until reset'),\n    wbInteger(QNAM, 'Quest Count', itU32, nil, cpBenign),\n    wbRArray('Quests', wbRStructSK([0], 'Quest', [\n      wbFormIDCk(NNAM, 'Quest', [QUST]),\n      wbUnknown(FNAM),\n      wbFloat(RNAM, 'Hours until reset', cpNormal, False, 1/24)\n    ], []), cpNormal, False, nil, wbSMQNQuestsAfterSet)\n  ], False, nil, cpNormal, False, nil, wbConditionsAfterSet);\n\n  wbRecord(SMEN, 'Story Manager Event Node', [\n    wbEDID,\n    wbFormIDCk(PNAM, 'Parent ', [SMQN, SMBN, SMEN, NULL]),\n    wbFormIDCk(SNAM, 'Child ', [SMQN, SMBN, SMEN, NULL]),\n    wbCITC,\n    wbCTDAsCount,\n    wbInteger(DNAM, 'Flags', itU32, wbSMNodeFlags),\n    wbUnknown(XNAM),\n    wbString(ENAM, 'Type', 4)\n  ], False, nil, cpNormal, False, nil, wbConditionsAfterSet);\nend;\n\nprocedure DefineFO4j;\nbegin\n  wbRecord(DLBR, 'Dialog Branch', [\n    wbEDID,\n    wbFormIDCk(QNAM, 'Quest', [QUST], False, cpNormal, True),\n    wbInteger(TNAM, 'Unknown', itU32),\n    wbInteger(DNAM, 'Flags', itU32, wbFlags([\n      {0x01} 'Top-Level',\n      {0x02} 'Blocking',\n      {0x04} 'Exclusive'\n    ])),\n    wbFormIDCk(SNAM, 'Starting Topic', [DIAL], False, cpNormal, True)\n  ]);\n\n  wbRecord(MUST, 'Music Track', [\n    wbEDID,\n    wbInteger(CNAM, 'Track Type', itU32, wbEnum([], [\n      Int64($23F678C3), 'Palette',\n      Int64($6ED7E048), 'Single Track',\n      Int64($A1A9C4D5), 'Silent Track'\n    ]), cpNormal, True),\n    wbFloat(FLTV, 'Duration'),\n    wbFloat(DNAM, 'Fade-Out'),\n    wbString(ANAM, 'Track Filename'),\n    wbString(BNAM, 'Finale Filename'),\n    wbStruct(LNAM, 'Loop Data', [\n      wbFloat('Loop Begins'),\n      wbFloat('Loop Ends'),\n      wbInteger('Loop Count', itU32)\n    ]),\n    wbArray(FNAM, 'Cue Points', wbFloat('Point')),\n    wbCITC,\n    wbCTDAsCount,\n    wbArray(SNAM, 'Tracks', wbFormIDCk('Track', [MUST, NULL]))\n  ], False, nil, cpNormal, False, nil, wbConditionsAfterSet);\n\n  wbRecord(DLVW, 'Dialog View', [\n    wbEDID,\n    wbFormIDCk(QNAM, 'Quest', [QUST], False, cpNormal, True),\n    wbRArray('Branches', wbFormIDCk(BNAM, 'Branch', [DLBR])),\n    wbRArray('Unknown TNAM', wbRStruct('Unknown', [\n      wbUnknown(TNAM)\n    ], [])),\n    wbUnknown(ENAM),\n    wbUnknown(DNAM)\n  ]);\n\n  {wbRecord(WOOP, 'Word of Power', [\n    wbEDID\n  ]);}\n\n  {wbRecord(SHOU, 'Shout', [\n    wbEDID\n  ]);}\n\n  wbRecord(EQUP, 'Equip Type', [\n    wbEDID,\n    wbArray(PNAM, 'Slot Parents', wbFormIDCk('Parent', [EQUP])),\n    wbInteger(DATA, 'Flags', itU32, wbFlags([\n      'Use All Parents',\n      'Parents Optional',\n      'Item Slot'\n    ])),\n    wbFormIDCk(ANAM, 'Condition Actor Value', [AVIF, NULL, FFFF])\n  ]);\n\n  wbRecord(RELA, 'Relationship', [\n    wbEDID,\n    wbStruct(DATA, 'Data', [\n      wbFormIDCk('Parent', [NPC_, NULL]),\n      wbFormIDCk('Child', [NPC_, NULL]),\n      wbInteger('Rank', itU8, wbEnum([\n        'Lover',\n        'Ally',\n        'Confidant',\n        'Friend',\n        'Acquaitance',\n        'Rival',\n        'Foe',\n        'Enemy',\n        'Archnemesis'\n      ])),\n      wbByteArray('Unknown', 2),\n      wbInteger('Flags', itU8, wbFlags([\n        {0x01} 'Unknown 1',\n        {0x02} 'Unknown 2',\n        {0x04} 'Unknown 3',\n        {0x08} 'Unknown 4',\n        {0x10} 'Unknown 5',\n        {0x20} 'Unknown 6',\n        {0x40} 'Unknown 7',\n        {0x80} 'Secret'\n      ])),\n      wbFormIDCk('Association Type', [ASTP, NULL])\n    ])\n  ]);\n\n  wbRecord(SCEN, 'Scene', [\n    wbEDID,\n    wbVMADFragmentedSCEN,\n    wbInteger(FNAM, 'Flags', itU32, wbFlags([\n      {0x00000001} 'Begin on Quest Start',\n      {0x00000002} 'Stop on Quest End',\n      {0x00000004} 'Unknown 2',\n      {0x00000008} 'Repeat Conditions While True',\n      {0x00000010} 'Interruptible',\n      {0x00000020} 'Unknown 5',\n      {0x00000040} 'Prevent Player Exit Dialogue',\n      {0x00000080} 'Unknown 7',\n      {0x00000100} 'Unknown 8',\n      {0x00000200} 'Unknown 9',\n      {0x00000400} 'Unknown 10',\n      {0x00000800} 'Disable Dialogue Camera',\n      {0x00001000} 'No Follower Idle Chatter'\n    ])),\n    wbRArray('Phases',\n      wbRStruct('Phase', [\n        wbEmpty(HNAM, 'Marker Phase Start'),\n        wbString(NAM0, 'Name'),\n        wbRStruct('Start Conditions', [wbCTDAs], []),\n        wbEmpty(NEXT, 'Marker Start Conditions'),\n        wbRStruct('Completion Conditions', [wbCTDAs], []),\n        wbEmpty(NEXT, 'Marker Completion Conditions'),\n        wbInteger(WNAM, 'Editor Width', itU32),\n        wbInteger(FNAM, 'Flags', itU16, wbFlags([\n          {0x0001} 'Start - WalkAway Phase',\n          {0x0002} 'Don''t Run End Scripts on Scene Jump',\n          {0x0004} 'Start - Inherit In Templated Scenes'\n        ])),\n        wbStruct(SCQS, 'Set Parent Quest Stage', [\n          wbInteger('On Start', itS16),\n          wbInteger('On Completion', itS16)\n        ]),\n        wbEmpty(HNAM, 'Marker Phase End')\n      ], [])\n    ),\n    wbRArray('Actors', wbRStruct('Actor', [\n      wbInteger(ALID, 'Alias ID', itS32),\n      wbInteger(LNAM, 'Flags', itU32, wbFlags([\n        'No Player Activation',\n        'Optional',\n        'Run Only Scene Packages',\n        'No Command State'\n      ])),\n      wbInteger(DNAM, 'Behaviour Flags', itU32, wbFlags([\n        'Death Pause',\n        'Death End',\n        'Combat Pause',\n        'Combat End',\n        'Dialogue Pause',\n        'Dialogue End',\n        'OBS_COM Pause',\n        'OBS_COM End'\n      ]))\n    ], [])),\n    wbRArray('Actions', wbRStruct('Action', [\n      wbInteger(ANAM, 'Type', itU16, wbEnum([\n        {0} 'Dialogue',\n        {1} 'Package',\n        {2} 'Timer',\n        {3} 'Player Dialogue',\n        {4} 'Start Scene',\n        {5} 'NPC Response Dialogue',\n        {6} 'Radio'\n      ])),\n      wbString(NAM0, 'Name'),\n      wbInteger(ALID, 'Alias ID', itS32),\n      wbInteger(INAM, 'Index', itU32),\n      wbInteger(FNAM, 'Flags', itU32, wbFlags([\n        {0x00000001} 'Unknown 0',\n        {0x00000002} 'Unknown 1',\n        {0x00000004} 'Unknown 2',\n        {0x00000008} 'Unknown 3',\n        {0x00000010} 'Unknown 4',\n        {0x00000020} 'Unknown 5',\n        {0x00000040} 'Unknown 6',\n        {0x00000080} 'Player Positive Use Dialogue Subtype / Hold Into Next Scene',\n        {0x00000100} 'Player Negative Use Dialogue Subtype',\n        {0x00000200} 'Player Neutral Use Dialogue Subtype',\n        {0x00000400} 'Use Dialogue Subtype',\n        {0x00000800} 'Player Question Use Dialogue Subtype',\n        {0x00001000} 'Keep/Clear Target on Action End',\n        {0x00002000} 'Unknown 13',\n        {0x00004000} 'Unknown 14',\n        {0x00008000} 'Face Target',\n        {0x00010000} 'Looping',\n        {0x00020000} 'Headtrack Player',\n        {0x00040000} 'Unknown 18',\n        {0x00080000} 'Ignore For Completion',\n        {0x00100000} 'Unknown 20',\n        {0x00200000} 'Camera Speaker Target',\n        {0x00400000} 'Complete Face Target',\n        {0x00800000} 'Unknown 23',\n        {0x01000000} 'Unknown 24',\n        {0x02000000} 'Unknown 25',\n        {0x04000000} 'Unknown 26',\n        {0x08000000} 'NPC Positive Use Dialogue Subtype',\n        {0x10000000} 'NPC Negative Use Dialogue Subtype',\n        {0x20000000} 'NPC Neutral Use Dialogue Subtype',\n        {0x40000000} 'NPC Question Use Dialogue Subtype'\n      ])),\n      wbInteger(SNAM, 'Start Phase', itU32),\n      wbInteger(ENAM, 'End Phase', itU32),\n      wbFloat(SNAM, 'Timer - Max Seconds'),\n      wbInteger(SCQS, 'Set Parent Quest Stage', itS16),\n      wbFloat(TNAM, 'Timer - Min Seconds'),\n      wbUnknown(STSC),\n      wbRStructs('Start Scenes', 'Start Scene', [\n        wbFormIDCk(LCEP, 'Scene', [SCEN]),\n        wbInteger(INTT, 'Phase Index', itU16),\n        wbString(SSPN, 'Start Phase for Scene'),\n        wbCITC,\n        wbCTDAs\n      ], []),\n      wbFormIDCk(PTOP, 'Player Positive Response', [DIAL]),\n      wbFormIDCk(NTOP, 'Player Negative Response', [DIAL]),\n      wbFormIDCk(NETO, 'Player Neutral Response', [DIAL]),\n      wbFormIDCk(QTOP, 'Player Question Response', [DIAL]),\n      wbFormIDCk(VENC, 'Player Positive Dialogue Subtype', [KYWD]),\n      wbFormIDCk(PLVD, 'Player Negative Dialogue Subtype', [KYWD]),\n      wbFormIDCk(JOUT, 'Player Neutral Dialogue Subtype', [KYWD]),\n      wbFormIDCk(DALC, 'Player Question Dialogue Subtype', [KYWD]),\n      wbArray(DTID, 'NPC Headtracking', wbInteger('Actor ID', itS32)),\n      wbFormIDCk(NPOT, 'NPC Positive Response', [DIAL]),\n      wbFormIDCk(NNGT, 'NPC Negative Response', [DIAL]),\n      wbFormIDCk(NNUT, 'NPC Neutral Response', [DIAL]),\n      wbFormIDCk(NQUT, 'NPC Question Response', [DIAL]),\n      wbFormIDCk(NPOS, 'NPC Positive Dialogue Subtype', [KYWD]),\n      wbFormIDCk(NNGS, 'NPC Negative Dialogue Subtype', [KYWD]),\n      wbFormIDCk(NNUS, 'NPC Neutral Dialogue Subtype', [KYWD]),\n      wbFormIDCk(NQUS, 'NPC Question Dialogue Subtype', [KYWD]),\n      wbInteger(DTGT, 'Dialogue Target Actor', itS32),\n      wbRArray('Packages', wbFormIDCk(PNAM, 'Package', [PACK])),\n      wbFormIDCk(DATA, 'Topic', [DIAL, NULL]),\n      wbUnion(HTID, '', wbSceneActionSoundDecider, [\n        wbEmpty('End Scene Say Greeting'),\n        wbFormIDCk('Play Sound', [SNDR, NULL])\n      ]),\n      wbFloat(DMAX, 'Looping - Max'),\n      wbFloat(DMIN, 'Looping - Min'),\n      wbStruct(CRIS, 'Camera', [\n        wbFloat('FOV On Player Camera'),\n        wbFloat('Rate Of Camera Change')\n      ]),\n      wbInteger(DEMO, 'Emotion Type', itU32, wbEmotionTypeEnum),\n      wbInteger(DEVA, 'Emotion Value', itU32),\n      wbArray(HTID, 'Player Headtracking', wbInteger('Actor ID', itS32)),\n      wbFormIDCk(VENC, 'Dialogue Subtype', [KYWD]),\n      wbFormIDCk(PNAM, 'AnimArchType', [KYWD]),\n      wbFormIDCk(ONAM, 'Audio Output Override', [SOPM]),\n      wbEmpty(ANAM, 'End Marker')\n    ], [])),\n    wbFormIDCk(PNAM, 'Quest', [QUST]),\n    wbInteger(INAM, 'Last Action Index', itU32),\n    wbUnknown(VNAM),\n    wbFloat(CNAM, 'Camera Distance Override'),\n    wbFloat(ACTV, 'Dialogue Distance Override'),\n    wbFloat(CRIS, 'FOV Override'),\n    wbKSIZ,\n    wbKWDAs,\n    wbCTDAs,\n    wbStruct(SCQS, 'Set Parent Quest Stage', [\n      wbInteger('On Begin', itS16),\n      wbInteger('On End', itS16)\n    ]),\n    wbString(NNAM, 'Notes'),\n    wbFormIDCk(TNAM, 'Template Scene', [SCEN]),\n    wbInteger(XNAM, 'Index', itU32)\n  ]);\n\n  wbRecord(ASTP, 'Association Type', [\n    wbEDID,\n    wbString(MPRT, 'Male Parent Title'),\n    wbString(FPRT, 'Female Parent Title'),\n    wbString(MCHT, 'Male Child Title'),\n    wbString(FCHT, 'Female Child Title'),\n    wbInteger(DATA, 'Flags', itU32, wbFlags([\n      'Family Association'\n    ]))\n  ]);\nend;\n\nprocedure DefineFO4k;\nbegin\n\n  wbSPED := wbStruct(SPED, 'Movement Data', [\n    wbFloat('Unknown'),\n    wbFloat('Walk - Left'),\n    wbFloat('Run - Left'),\n    wbFloat('Unknown'),\n    wbFloat('Unknown'),\n    wbFloat('Walk - Right'),\n    wbFloat('Run - Right'),\n    wbFloat('Unknown'),\n    wbFloat('Unknown'),\n    wbFloat('Walk - Forward'),\n    wbFloat('Run - Forward'),\n    wbFloat('Sprint - Forward'),\n    wbFloat('Unknown'),\n    wbFloat('Walk - Back'),\n    wbFloat('Run - Back'),\n    wbFloat('Unknown'),\n    wbFloat('Standing - Pitch', cpNormal, True, wbRotationFactor, wbRotationScale, nil, RadiansNormalize),\n    wbFloat('Walk - Pitch', cpNormal, True, wbRotationFactor, wbRotationScale, nil, RadiansNormalize),\n    wbFloat('Run - Pitch', cpNormal, True, wbRotationFactor, wbRotationScale, nil, RadiansNormalize),\n    wbFloat('Sprint - Pitch', cpNormal, True, wbRotationFactor, wbRotationScale, nil, RadiansNormalize),\n    wbFloat('Unknown'{, cpNormal, True, wbRotationFactor, wbRotationScale, nil, RadiansNormalize}),\n    wbFloat('Unknown'{, cpNormal, True, wbRotationFactor, wbRotationScale, nil, RadiansNormalize}),\n    wbFloat('Unknown'{, cpNormal, True, wbRotationFactor, wbRotationScale, nil, RadiansNormalize}),\n    wbFloat('Unknown'{, cpNormal, True, wbRotationFactor, wbRotationScale, nil, RadiansNormalize}),\n    wbFloat('Standing - Yaw', cpNormal, True, wbRotationFactor, wbRotationScale, nil, RadiansNormalize),\n    wbFloat('Walk - Yaw', cpNormal, True, wbRotationFactor, wbRotationScale, nil, RadiansNormalize),\n    wbFloat('Run - Yaw', cpNormal, True, wbRotationFactor, wbRotationScale, nil, RadiansNormalize),\n    wbFloat('Sprint - Yaw', cpNormal, True, wbRotationFactor, wbRotationScale, nil, RadiansNormalize)\n  ], cpNormal, True, nil, 10);\n\n  wbRecord(OTFT, 'Outfit', [\n    wbEDID,\n    wbArrayS(INAM, 'Items', wbFormIDCk('Item', [ARMO, LVLI]))\n  ]);\n\n  wbRecord(ARTO, 'Art Object', [\n    wbEDID,\n    wbOBNDReq,\n    wbPTRN,\n    wbKSIZ,\n    wbKWDAs,\n    wbMODL,\n    wbInteger(DNAM, 'Art Type', itU32, wbEnum([\n      'Magic Casting',\n      'Magic Hit Effect',\n      'Enchantment Effect'\n    ]))\n  ]);\n\n  wbRecord(MATO, 'Material Object', [\n    wbEDID,\n    wbMODL,\n    wbRArray('Property Data',\n      wbByteArray(DNAM, 'Data', 0, cpIgnore, False, False, wbNeverShow)\n    ),\n    wbStruct(DATA, 'Directional Material Data', [\n      wbFloat('Falloff Scale'),\n      wbFloat('Falloff Bias'),\n      wbFloat('Noise UV Scale'),\n      wbFloat('Material UV Scale'),\n      wbStruct('Projection Vector', [\n        wbFloat('X'),\n        wbFloat('Y'),\n        wbFloat('Z')\n      ]),\n      wbFloat('Normal Dampener'),\n      wbFloatColors('Single Pass Color'),\n      wbInteger('Flags', itU32, wbFlags(['Single Pass']))\n    ], cpNormal, True, nil, 5)\n  ]);\n\n  wbRecord(MOVT, 'Movement Type', [\n    wbEDID,\n    wbString(MNAM, 'Name'),\n    wbSPED,\n    wbStruct(INAM, 'Anim Change Thresholds (unused)', [\n      wbFloat('Directional', cpNormal, True, 180/Pi),\n      wbFloat('Movement Speed'),\n      wbFloat('Rotation Speed', cpNormal, True, 180/Pi)\n    ]),\n    wbFloat(JNAM, 'Float Height'),\n    wbFloat(LNAM, 'Flight - Angle Gain')\n  ]);\n\n  wbRecord(SNDR, 'Sound Descriptor', [\n    wbEDID,\n    wbString(NNAM, 'Notes'),\n    wbInteger(CNAM, 'Descriptor Type', itU32, wbEnum([], [\n      Int64($1EEF540A), 'Standard',\n      Int64($54651A43), 'Compound',\n      Int64($ED157AE3), 'AutoWeapon'\n    ])),\n    wbFormIDCk(GNAM, 'Category', [SNCT]),\n    wbFormIDCk(SNAM, 'Alternate Sound For', [SNDR]),\n    wbRArray('Sounds',\n      wbRStruct('Sound Files', [\n        wbString(ANAM, 'File Name')\n      ], [])\n    ),\n    wbFormIDCk(ONAM, 'Output Model', [SOPM]),\n    wbCTDAs,\n    wbStruct(LNAM, 'Values', [\n      wbByteArray('Unknown', 1),\n      wbInteger('Looping', itU8, wbEnum([], [\n        $00, 'None',\n        $08, 'Loop',\n        $10, 'Envelope Fast',\n        $20, 'Envelope Slow'\n      ])),\n      wbInteger('Sidechain', itU8),\n      wbInteger('Rumble Send Value = (Small / 7) + ((Big / 7) * 16)', itU8)\n    ]),\n    wbUnion(BNAM, 'Data', wbSNDRDataDecider, [\n      wbStruct('Values', [\n        wbInteger('% Frequency Shift', itS8),\n        wbInteger('% Frequency Variance', itS8),\n        wbInteger('Priority', itU8),\n        wbInteger('db Variance', itU8),\n        wbInteger('Static Attenuation (db)', itU16, wbDiv(100))\n      ]),\n      wbFormIDCk('Base Descriptor', [SNDR])\n    ]),\n    wbRArray('Descriptors', wbFormIDCk(DNAM, 'Descriptor', [SNDR])),\n    wbInteger(ITMC, 'Count', itU32, nil, cpBenign),\n    wbRArrayS('Rates of Fire',\n      wbRStructSK([1], 'Sound', [\n        wbEmpty(ITMS, 'Marker Start'),\n        wbInteger(INTV, 'RoF (RPM)', itU32),\n        wbString(FNAM, 'File'),\n        wbEmpty(ITME, 'Marker End')\n      ], []),\n      cpNormal, False, nil, wbSNDRRatesOfFireAfterSet\n    )\n  ]);\n\n  wbRecord(DUAL, 'Dual Cast Data', [\n    wbEDID\n  ]);\n\n  wbRecord(SNCT, 'Sound Category', [\n    wbEDID,\n    wbFULL,\n    wbInteger(FNAM, 'Flags', itU32, wbFlags([\n      {0x0000001} 'Mute When Submerged',\n      {0x0000002} 'Should Appear on Menu',\n      {0x0000004} 'Immune to Time Speedup',\n      {0x0000008} 'Pause During Menus (Immed)',\n      {0x0000010} 'Pause During Menus (Fade)',\n      {0x0000020} 'Exclude from Player OPM Override',\n      {0x0000040} 'Pause During Start Menu'\n    ]), cpNormal, True),\n    wbFormIDCk(PNAM, 'Parent Category', [SNCT]),\n    wbFormIDCk(ONAM, 'Menu Slider Category', [SNCT]),\n    wbInteger(VNAM, 'Static Volume Multiplier', itU16, wbDiv(65535)),\n    wbInteger(UNAM, 'Default Menu Value', itU16, wbDiv(65535)),\n    wbFloat(MNAM, 'Min Frequency Multiplier'),\n    wbFloat(CNAM, 'Sidechain Target Multiplier')\n  ]);\n\n  wbRecord(SOPM, 'Sound Output Model', [\n    wbEDID,\n    wbStruct(NAM1, 'Data', [\n      wbInteger('Flags', itU8, wbFlags([\n        {0x01} 'Attenuates With Distance',\n        {0x02} 'Allows Rumble',\n        {0x04} 'Applies Doppler',\n        {0x08} 'Applies Distance Delay',\n        {0x10} 'Player Output Model',\n        {0x20} 'Try Play on Controller',\n        {0x40} 'Causes Ducking',\n        {0x80} 'Avoids Ducking'\n      ])),\n      wbByteArray('Unknown', 2),\n      wbInteger('Reverb Send %', itU8)\n    ]),\n    wbInteger(MNAM, 'Type', itU32, wbEnum([\n      'Uses HRTF',\n      'Defined Speaker Output'\n    ])),\n    wbInteger(VNAM, 'Static Attenuation', itS16, wbDiv(100)),\n    wbStruct(ONAM, 'Output Values', [\n      wbArray('Channels', wbStruct('', [\n        wbInteger('FL', itU8),\n        wbInteger('FR', itU8),\n        wbInteger('C', itU8),\n        wbInteger('LFE', itU8),\n        wbInteger('RL', itU8),\n        wbInteger('RR', itU8),\n        wbInteger('SL', itU8),\n        wbInteger('SR', itU8)\n      ]), [\n        'Channel 0',\n        'Channel 1',\n        'Channel 2? (unused)'\n      ])\n    ]),\n    wbStruct(ATTN, 'Attenuation Values', [\n      wbFloat('Fade In Distance - Start'),\n      wbFloat('Fade In Distance - End'),\n      wbFloat('Fade Out Distance - Start'),\n      wbFloat('Fade Out Distance - End'),\n      wbStruct('Fade In Curve', [\n        wbInteger('Value 1', itU8),\n        wbInteger('Value 2', itU8),\n        wbInteger('Value 3', itU8),\n        wbInteger('Value 4', itU8)\n      ]),\n      wbStruct('Fade Out Curve', [\n        wbInteger('Value 1', itU8),\n        wbInteger('Value 2', itU8),\n        wbInteger('Value 3', itU8),\n        wbInteger('Value 4', itU8)\n      ])\n    ]),\n    wbFormIDCk(ENAM, 'Effect Chain', [AECH])\n  ]);\n\n  wbRecord(COLL, 'Collision Layer', [\n    wbEDID,\n    wbDESCReq,\n    wbInteger(BNAM, 'Index', itU32, nil, cpNormal, True),\n    wbStruct(FNAM, 'Debug Color', [\n      wbInteger('Red', itU8),\n      wbInteger('Green', itU8),\n      wbInteger('Blue', itU8),\n      wbInteger('Unused', itU8)\n    ], cpNormal, True),\n    wbInteger(GNAM, 'Flags', itU32, wbFlags([\n      {0x00000001} 'Trigger Volume',\n      {0x00000002} 'Sensor',\n      {0x00000004} 'Navmesh Obstacle'\n    ]), cpNormal, True),\n    wbString(MNAM, 'Name', 0, cpNormal, True),\n    wbInteger(INTV, 'Interactables Count', itU32, nil, cpNormal, True),\n    wbArrayS(CNAM, 'Collides With', wbFormIDCk('Forms', [COLL]), 0, cpNormal, False)\n  ]);\n\n  wbRecord(CLFM, 'Color',\n    wbFlags(wbRecordFlagsFlags, wbFlagsList([\n      {0x00000004}  2, 'Non-Playable'\n    ])), [\n    wbEDID,\n    wbFULL,\n    // union decider doesn't work during copying since decision data FNAM is located after it\n    // workaround using integer formatters\n    wbInteger(CNAM, 'Color/Index', itU32, wbCLFMColorToStr, wbCLFMColorToInt),\n    {wbUnion(CNAM, 'Value', wbCLFMColorDecider, [\n      wbByteColors('Color'),\n      wbFloat('Remapping Index')\n    ]),}\n    wbInteger(FNAM, 'Flags', itU32, wbFlags([\n      'Playable',\n      'Remapping Index',\n      'Extended LUT'\n    ]), cpNormal, True),\n    wbCTDAs\n  ]);\nend;\n\nprocedure DefineFO4l;\nbegin\n  wbRecord(REVB, 'Reverb Parameters', [\n    wbEDID,\n    wbStruct(DATA, 'Data', [\n      wbInteger('Decay Time (ms)', itU16),\n      wbInteger('HF Reference (Hz)', itU16),\n      wbInteger('Room Filter', itS8),\n      wbInteger('Room HF Filter', itS8),\n      wbInteger('Reflections', itS8),\n      wbInteger('Reverb Amp', itS8),\n      wbInteger('Decay HF Ratio', itU8, wbDiv(100)),\n      wbInteger('Reflect Delay (ms), scaled', itU8),\n      wbInteger('Reverb Delay (ms)', itU8),\n      wbInteger('Diffusion %', itU8),\n      wbInteger('Density %', itU8),\n      wbInteger('Unknown', itU8)\n    ], cpNormal, True),\n    wbInteger(ANAM, 'Reverb Class', itU32, wbReverbClassEnum, cpNormal, True)\n  ]);\n\n  wbRecord(GRAS, 'Grass', [\n    wbEDID,\n    wbOBNDReq,\n    wbMODL,\n    wbStruct(DATA, '', [\n      wbInteger('Density', itU8),\n      wbInteger('Min Slope', itU8),\n      wbInteger('Max Slope', itU8),\n      wbByteArray('Unknown', 1),\n      wbInteger('Units From Water', itU16),\n      wbByteArray('Unknown', 2),\n      wbInteger('Units From Water Type', itU32, wbEnum([\n        'Above - At Least',\n        'Above - At Most',\n        'Below - At Least',\n        'Below - At Most',\n        'Either - At Least',\n        'Either - At Most',\n        'Either - At Most Above',\n        'Either - At Most Below'\n      ])),\n      wbFloat('Position Range'),\n      wbFloat('Height Range'),\n      wbFloat('Color Range'),\n      wbFloat('Wave Period'),\n      wbInteger('Flags', itU8, wbFlags([\n        'Vertex Lighting',\n        'Uniform Scaling',\n        'Fit to Slope'\n      ])),\n      wbByteArray('Unknown', 3)\n    ], cpNormal, True)\n  ]);\n\n  wbRecord(IDLE, 'Idle Animation', [\n    wbEDID,\n    wbCTDAs,\n    wbString(DNAM, 'Behavior Graph'),\n    wbString(ENAM, 'Animation Event'),\n    wbArray(ANAM, 'Related Idle Animations', wbFormIDCk('Related Idle Animation', [AACT, IDLE, NULL]),\n      ['Parent', 'Previous Sibling'], cpNormal, True),\n    wbStruct(DATA, '', [\n      wbStruct('Looping seconds (both 255 forever)', [\n        wbInteger('Min', itU8),\n        wbInteger('Max', itU8)\n      ]),\n      wbInteger('Flags', itU8, wbFlags([\n        {0x01} 'Parent',\n        {0x02} 'Sequence',\n        {0x04} 'No Attacking',\n        {0x04} 'Blocking'\n      ], True)),\n      wbInteger('Animation Group Section', itU8{, wbIdleAnam}),\n      wbInteger('Replay Delay', itU16)\n    ], cpNormal, True),\n    wbString(GNAM, 'Animation File')\n  ]);\n\n  wbRecord(INFO, 'Dialog response',\n    wbFlags(wbRecordFlagsFlags, wbFlagsList([\n      {0x00000040}  6, 'Unknown 6',\n      {0x00000080}  7, 'Exclude From Export',\n      {0x00002000} 13, 'Actor Changed'\n    ])), [\n    wbEDID,\n    wbVMADFragmentedINFO,\n    wbStruct(ENAM, 'Response flags', [\n      wbInteger('Flags', itU16, wbFlags([\n        {0x0001} 'Start Scene on End',\n        {0x0002} 'Random',\n        {0x0004} 'Say Once',\n        {0x0008} 'Requires Player Activation',\n        {0x0010} 'Unknown 4',\n        {0x0020} 'Random End',\n        {0x0040} 'End Running Scene',\n        {0x0080} 'ForceGreet Hello',\n        {0x0100} 'Player Address',\n        {0x0200} 'Unknown 9',\n        {0x0400} 'Can Move While Greeting',\n        {0x0800} 'No LIP File',\n        {0x1000} 'Requires post-processing',\n        {0x2000} 'Audio Output Override',\n        {0x4000} 'Has Capture',\n        {0x8000} 'Unknown 16'\n      ])),\n      wbInteger('Reset Hours', itU16, wbDiv(2730))\n    ]),\n    wbFormIDCk(TPIC, 'Topic', [DIAL]),\n    wbFormIDCkNoReach(PNAM, 'Previous INFO', [INFO, NULL], False, cpBenign),\n    wbFormIDCk(DNAM, 'Shared INFO', [INFO]),\n    wbFormIDCk(GNAM, 'Unknown', [INFO]),\n    wbString(IOVR, 'Override Filename'),\n\n    wbRArray('Responses', wbRStruct('Response', [\n      wbStruct(TRDA, 'Response Data', [\n        wbFormIDCk('Emotion', [KYWD, FFFF]),\n        wbInteger('Response number', itU8),\n        wbByteArray('Unused', 3),\n        wbByteArray('Unknown', 2),\n        wbInteger('Interrupt Percentage', itU16),\n        wbInteger('Camera Target Alias', itS32),\n        wbInteger('Camera Location Alias', itS32)\n      ]),\n      wbLStringKC(NAM1, 'Response Text', 0, cpTranslate, True),\n      wbString(NAM2, 'Script Notes', 0, cpNormal, True),\n      wbString(NAM3, 'Edits', 0, cpNormal, True),\n      wbString(NAM4, 'Alternate LIP Text', 0, cpNormal, True),\n      wbFormIDCk(SNAM, 'Idle Animations: Speaker', [IDLE]),\n      wbFormIDCk(LNAM, 'Idle Animations: Listener', [IDLE]),\n      wbInteger(TNAM, 'Interrupt Percentage', itU16),\n      wbByteArray(NAM9, 'Text Hash'),\n      wbFormIDCk(SRAF, 'Camera Path', [CPTH]),\n      wbEmpty(WZMD, 'Stop on Scene End')\n    ], [])),\n\n    wbCTDAs,\n    wbLString(RNAM, 'Prompt', 0, cpTranslate),\n    wbFormIDCk(ANAM, 'Speaker', [NPC_]),\n    wbFormIDCk(TSCE, 'Start Scene', [SCEN]),\n    wbInteger(ALFA, 'Forced Alias', itS32),\n    wbUnknown(INTV),\n    wbFormIDCk(ONAM, 'Audio Output Override', [SOPM]),\n    wbInteger(GREE, 'Greet Distance', itU32),\n    wbStruct(TIQS, 'Set Parent Quest Stage', [\n      wbInteger('On Begin', itS16),\n      wbInteger('On End', itS16)\n    ]),\n    wbString(NAM0, 'Start Scene Phase'),\n    wbInteger(INCC, 'Challenge', itU32, wbEnum([\n      {0} 'None',\n      {1} 'Easy',\n      {2} 'Medium',\n      {3} 'Hard',\n      {4} 'Always Succeeds',\n      {5} 'Easy Repeatable',\n      {6} 'Medium Repeatable',\n      {7} 'Hard Repeatable'\n    ])),\n    wbFormIDCk(MODQ, 'Reset Global', [GLOB]),\n    wbInteger(INAM, 'Subtitle Priority', itU32, wbEnum([\n      'Low',\n      'Normal',\n      'Unknown 2',\n      'Force'\n    ]))\n  ], False, wbINFOAddInfo, cpNormal, False, nil{wbINFOAfterLoad});\n\n  wbRecord(INGR, 'Ingredient', [\n    wbEDID,\n    wbVMAD,\n    wbOBNDReq,\n    wbFULL,\n    wbKSIZ,\n    wbKWDAs,\n    wbMODL,\n    wbICON,\n    wbMICO,\n    wbDEST,\n    wbETYP,\n    wbYNAM,\n    wbZNAM,\n    wbStruct(DATA, '', [\n      wbInteger('Value', itS32),\n      wbFloat('Weight')\n    ], cpNormal, True),\n    wbStruct(ENIT, 'Effect Data', [\n      wbInteger('Ingredient Value', itS32),\n      wbInteger('Flags', itU32, wbFlags([\n        {0x00000001} 'No auto-calculation',\n        {0x00000002} 'Food item',\n        {0x00000004} 'Unknown 3',\n        {0x00000008} 'Unknown 4',\n        {0x00000010} 'Unknown 5',\n        {0x00000020} 'Unknown 6',\n        {0x00000040} 'Unknown 7',\n        {0x00000080} 'Unknown 8',\n        {0x00000100} 'References Persist'\n      ]))\n    ], cpNormal, True),\n    wbEffectsReq\n  ], False, nil, cpNormal, False, nil, wbKeywordsAfterSet);\n\n  wbRecord(KEYM, 'Key',\n    wbFlags(wbRecordFlagsFlags, wbFlagsList([\n      {0x00000800} 11, 'Calc Value From Components',\n      {0x00002000} 13, 'Pack-In Use Only'\n    ])), [\n    wbEDID,\n    wbVMAD,\n    wbOBNDReq,\n    wbPTRN,\n    wbFULLReq,\n    wbMODL,\n    wbICON,\n    wbMICO,\n    wbDEST,\n    wbYNAM,\n    wbZNAM,\n    wbKSIZ,\n    wbKWDAs,\n    wbStruct(DATA, '', [\n      wbInteger('Value', itS32),\n      wbFloat('Weight')\n    ], cpNormal, True)\n  ], False, nil, cpNormal, False, nil, wbKeywordsAfterSet);\n\n  wbQuadrantEnum := wbEnum([\n    {0} 'Bottom Left',\n    {1} 'Bottom Right',\n    {2} 'Top Left',\n    {3} 'Top Right'\n  ]);\n\n  if wbSimpleRecords then begin\n\n    wbRecord(LAND, 'Landscape',\n      wbFlags(wbRecordFlagsFlags, wbFlagsList([\n        {0x00040000} 18, 'Compressed'\n      ]), [18]), [\n      wbByteArray(DATA, 'Unknown'),\n      wbByteArray(VNML, 'Vertex Normals'),\n      wbByteArray(VHGT, 'Vertext Height Map'),\n      wbByteArray(VCLR, 'Vertex Colours'),\n\n      wbRArrayS('Layers', wbRUnion('Layer', [\n        wbRStructSK([0],'Base Layer', [\n          wbStructSK(BTXT, [1, 3], 'Base Layer Header', [\n            wbFormIDCk('Texture', [LTEX, NULL]),\n            wbInteger('Quadrant', itU8, wbQuadrantEnum),\n            wbByteArray('Unknown', 1),\n            wbInteger('Layer', itS16)\n          ])\n        ], []),\n        wbRStructSK([0],'Alpha Layer', [\n          wbStructSK(ATXT, [1, 3], 'Alpha Layer Header', [\n            wbFormIDCk('Texture', [LTEX, NULL]),\n            wbInteger('Quadrant', itU8, wbQuadrantEnum),\n            wbByteArray('Unknown', 1),\n            wbInteger('Layer', itS16)\n          ]),\n          wbByteArray(VTXT, 'Alpha Layer Data')\n        ], [])\n      ], [])),\n      wbArray(VTEX, 'Textures', wbFormIDCk('Texture', [LTEX, NULL])),\n      wbRArray('Unknown', wbUnknown(MPCD))\n    ]);\n\n  end else begin\n\n    wbRecord(LAND, 'Landscape',\n      wbFlags(wbRecordFlagsFlags, wbFlagsList([\n        {0x00040000} 18, 'Compressed'\n      ]), [18]), [\n      wbByteArray(DATA, 'Unknown'),\n      wbArray(VNML, 'Vertex Normals', wbStruct('Row', [\n        wbArray('Columns', wbStruct('Column', [\n          wbInteger('X', itU8),\n          wbInteger('Y', itU8),\n          wbInteger('Z', itU8)\n        ]), 33)\n      ]), 33),\n      wbStruct(VHGT, 'Vertext Height Map', [\n        wbFloat('Offset'),\n        wbArray('Rows', wbStruct('Row', [\n          wbArray('Columns', wbInteger('Column', itU8), 33)\n        ]), 33),\n        wbByteArray('Unknown', 3)\n      ]),\n      wbArray(VCLR, 'Vertex Colours', wbStruct('Row', [\n        wbArray('Columns', wbStruct('Column', [\n          wbInteger('X', itU8),\n          wbInteger('Y', itU8),\n          wbInteger('Z', itU8)\n        ]), 33)\n      ]), 33),\n\n      wbRArrayS('Layers', wbRUnion('Layer', [\n        wbRStructSK([0],'Base Layer', [\n          wbStructSK(BTXT, [1, 3], 'Base Layer Header', [\n            wbFormIDCk('Texture', [LTEX, NULL]),\n            wbInteger('Quadrant', itU8, wbQuadrantEnum),\n            wbByteArray('Unknown', 1),\n            wbInteger('Layer', itS16)\n          ])\n        ], []),\n        wbRStructSK([0],'Alpha Layer', [\n          wbStructSK(ATXT, [1, 3], 'Alpha Layer Header', [\n            wbFormIDCk('Texture', [LTEX, NULL]),\n            wbInteger('Quadrant', itU8, wbQuadrantEnum),\n            wbByteArray('Unknown', 1),\n            wbInteger('Layer', itS16)\n          ]),\n          wbArrayS(VTXT, 'Alpha Layer Data', wbStructSK([0], 'Cell', [\n            wbInteger('Position', itU16, wbAtxtPosition),\n            wbByteArray('Unknown', 2),\n            wbFloat('Opacity')\n          ]))\n        ], [])\n      ], [])),\n      wbArray(VTEX, 'Textures', wbFormIDCk('Texture', [LTEX, NULL])),\n      wbRArray('Unknown', wbUnknown(MPCD))\n    ]);\n\n  end;\n\n  wbRecord(LIGH, 'Light',\n    wbFlags(wbRecordFlagsFlags, wbFlagsList([\n      {0x00010000} 16, 'Random Anim Start',\n      {0x00020000} 17, 'Unknown 17',\n      {0x00020000} 25, 'Obstacle',\n      {0x00020000} 28, 'Portal-strict'\n    ])), [\n    wbEDID,\n    wbVMAD,\n    wbOBNDReq,\n    wbPTRN,\n    wbMODL,\n    wbKSIZ,\n    wbKWDAs,\n    wbDEST,\n    wbPRPS,\n    wbFULL,\n    wbICON,\n    wbMICO,\n    wbStruct(DATA, '', [\n      wbInteger('Time', itS32),\n      wbInteger('Radius', itU32),\n      wbByteColors('Color'),\n      // Omnidirectional is the default type\n      wbInteger('Flags', itU32, wbFlags([\n        {0x00000001} 'Unknown 0',\n        {0x00000002} 'Can be Carried',\n        {0x00000004} 'Unknown 2',\n        {0x00000008} 'Flicker',\n        {0x00000010} 'Unknown 4',\n        {0x00000020} 'Off By Default',\n        {0x00000040} 'Unknown 6',\n        {0x00000080} 'Pulse',\n        {0x00000100} 'Unknown 8',\n        {0x00000200} 'Unknown 9',\n        {0x00000400} 'Shadow Spotlight',\n        {0x00000800} 'Shadow Hemisphere',\n        {0x00001000} 'Shadow OmniDirectional',\n        {0x00002000} 'Unknown 13',\n        {0x00004000} 'NonShadow Spotlight',\n        {0x00008000} 'Non Specular',\n        {0x00010000} 'Attenuation Only',\n        {0x00020000} 'NonShadow Box',\n        {0x00040000} 'Ignore Roughness',\n        {0x00080000} 'No Rim Lighting',\n        {0x00100000} 'Ambient Only',\n        {0x00200000} 'Unknown 21' // only in [001C7F0C] <RandomSpot01GR>\n      ])),\n      wbFloat('Falloff Exponent'),\n      wbFloat('FOV'),\n      wbFloat('Near Clip'),\n      wbStruct('Flicker Effect', [\n        wbFloat('Period'),\n        wbFloat('Intensity Amplitude'),\n        wbFloat('Movement Amplitude')\n      ]),\n      wbFloat('Constant'),\n      wbFloat('Scalar'),\n      wbFloat('Exponent'),\n      wbFloat('God Rays - Near Clip'),\n      wbInteger('Value', itU32),\n      wbFloat('Weight')\n    ], cpNormal, True, nil, 10),\n    wbFloat(FNAM, 'Fade value', cpNormal, True),\n    wbString(NAM0, 'Gobo'),\n    wbFormIDCk(LNAM, 'Lens', [LENS]),\n    wbFormIDCk(WGDR, 'God Rays', [GDRY]),\n    wbFormIDCk(SNAM, 'Sound', [SNDR])\n  ], False, nil, cpNormal, False, wbLIGHAfterLoad);\nend;\n\nprocedure DefineFO4m;\nbegin\n\n  wbRecord(LSCR, 'Load Screen',\n    wbFlags(wbRecordFlagsFlags, wbFlagsList([\n      {0x00000400} 10, 'Displays In Main Menu',\n      {0x00008000} 15, 'No Rotation'\n    ])), [\n    wbEDID,\n    wbDESCReq,\n    wbCTDAs,\n    wbFormIDCk(NNAM, 'Loading Screen NIF', [STAT, SCOL, NULL], False, cpNormal, True),\n    wbFormIDCk(TNAM, 'Transform', [TRNS]),\n    wbStruct(ONAM, 'Rotation', [\n      wbInteger('Min', itS16),\n      wbInteger('Max', itS16)\n    ]),\n    wbStruct(ZNAM, 'Zoom', [\n      wbFloat('Min'),\n      wbFloat('Max')\n    ]),\n    wbString(MOD2, 'Camera Path', 0, cpNormal, False)\n  ]);\n\n  wbRecord(LTEX, 'Landscape Texture', [\n    wbEDID,\n    wbFormIDCk(TNAM, 'Texture Set', [TXST], False, cpNormal, False),\n    wbFormIDCk(MNAM, 'Material Type', [MATT, NULL], False, cpNormal, True),\n    wbStruct(HNAM, 'Havok Data', [\n      wbInteger('Friction', itU8),\n      wbInteger('Restitution', itU8)\n    ], cpNormal, True),\n    wbInteger(SNAM, 'Texture Specular Exponent', itU8, nil, cpNormal, True),\n    wbRArray('Grasses', wbFormIDCk(GNAM, 'Grass', [GRAS]))\n  ]);\n\n  wbRecord(LVLN, 'Leveled NPC', [\n    wbEDID,\n    wbOBNDReq,\n    wbLVLD,\n    wbInteger(LVLM, 'Max Count', itU8), { Always 00 } {Unavailable}\n    wbInteger(LVLF, 'Flags', itU8, wbFlags([\n      {0x01} 'Calculate from all levels <= player''s level',\n      {0x02} 'Calculate for each item in count',\n      {0x04} 'Calculate All' {Still picks just one}\n    ]), cpNormal, True),\n    wbFormIDCk(LVLG, 'Use Global', [GLOB]),\n    wbLLCT,\n    wbRArrayS('Leveled List Entries',\n      wbRStructExSK([0], [1], 'Leveled List Entry', [\n        wbStructExSK(LVLO , [0, 2], [3], 'Base Data', [\n          wbInteger('Level', itU16),\n          wbByteArray('Unused', 2, cpIgnore, false, wbNeverShow),\n          wbFormIDCk('Reference', [NPC_, LVLN]),\n          wbInteger('Count', itS16),\n          wbInteger('Chance None', itU8),\n          wbByteArray('Unused', 1, cpIgnore, false, wbNeverShow)\n        ]),\n\t\t\t\twbCOED\n      ], []), cpNormal, False, nil, wbLVLOsAfterSet),\n    wbArrayS(LLKC, 'Filter Keyword Chances',\n      wbStructSK([0], 'Filter', [\n        wbFormIDCk('Keyword', [KYWD]),\n        wbInteger('Chance', itU32)\n      ])\n    ),\n    wbMODL\n  ], False, nil, cpNormal, False, wbLLEAfterLoad, wbLLEAfterSet);\n\n  wbRecord(LVLI, 'Leveled Item', [\n    wbEDID,\n    wbOBNDReq,\n    wbLVLD,\n    wbInteger(LVLM, 'Max Count', itU8), { Always 00 }\n    wbInteger(LVLF, 'Flags', itU8, wbFlags([\n      {0x01} 'Calculate from all levels <= player''s level',\n      {0x02} 'Calculate for each item in count',\n      {0x04} 'Use All'\n    ]), cpNormal, True),\n    wbFormIDCk(LVLG, 'Use Global', [GLOB]),\n    wbLLCT,\n    wbRArrayS('Leveled List Entries',\n      wbRStructExSK([0], [1], 'Leveled List Entry', [\n        wbStructExSK(LVLO , [0, 2], [3], 'Base Data', [\n          wbInteger('Level', itU16),\n          wbByteArray('Unused', 2, cpIgnore, false, wbNeverShow),\n          wbFormIDCk('Reference', sigBaseObjects),\n          wbInteger('Count', itU16),\n          wbInteger('Chance None', itU8),\n          wbByteArray('Unused', 1, cpIgnore, false, wbNeverShow)\n        ]),\n        wbCOED\n      ], []), cpNormal, False, nil, wbLVLOsAfterSet\n    ),\n    wbArrayS(LLKC, 'Filter Keyword Chances',\n      wbStructSK([0], 'Filter', [\n        wbFormIDCk('Keyword', [KYWD]),\n        wbInteger('Chance', itU32)\n      ])\n    ),\n    wbFormIDCk(LVSG, 'Epic Loot Chance', [GLOB]),\n    wbLStringKC(ONAM, 'Override Name', 0, cpTranslate)\n  ], False, nil, cpNormal, False, wbLLEAfterLoad, wbLLEAfterSet);\n\n  wbRecord(LVSP, 'Leveled Spell', [\n    wbEDID\n  ]);\n\n  wbMGEFType := wbInteger('Archetype', itU32, wbEnum([\n    {00} 'Value Modifier',\n    {01} 'Script',\n    {02} 'Dispel',\n    {03} 'Cure Disease',\n    {04} 'Absorb',\n    {05} 'Dual Value Modifier',\n    {06} 'Calm',\n    {07} 'Demoralize',\n    {08} 'Frenzy',\n    {09} 'Disarm',\n    {10} 'Command Summoned',\n    {11} 'Invisibility',\n    {12} 'Light',\n    {13} 'Darkness',\n    {14} 'Nighteye',\n    {15} 'Lock',\n    {16} 'Open',\n    {17} 'Bound Weapon',\n    {18} 'Summon Creature',\n    {19} 'Detect Life',\n    {20} 'Telekinesis',\n    {21} 'Paralysis',\n    {22} 'Reanimate',\n    {23} 'Soul Trap',\n    {24} 'Turn Undead',\n    {25} 'Guide',\n    {26} 'Unknown 26',\n    {27} 'Cure Paralysis',\n    {28} 'Cure Addiction',\n    {29} 'Cure Poison',\n    {30} 'Concussion',\n    {31} 'Stimpack',\n    {32} 'Accumulate Magnitude',\n    {33} 'Stagger',\n    {34} 'Peak Value Modifier',\n    {35} 'Cloak',\n    {36} 'Unknown 36',\n    {37} 'Slow Time',\n    {38} 'Rally',\n    {39} 'Enhance Weapon',\n    {40} 'Spawn Hazard',\n    {41} 'Etherealize',\n    {42} 'Banish',\n    {43} 'Spawn Scripted Ref',\n    {44} 'Disguise',\n    {45} 'Damage',\n    {46} 'Immunity',\n    {47} 'Permanent Reanimate',\n    {48} 'Jetpack',\n    {49} 'Chameleon'\n  ]), cpNormal, False, nil, wbMGEFArchtypeAfterSet);\n\n  wbMGEFData := wbRStruct('Magic Effect Data', [\n    wbStruct(DATA, 'Data', [\n      wbInteger('Flags', itU32, wbFlags([\n        {0x00000001}  'Hostile',\n        {0x00000002}  'Recover',\n        {0x00000004}  'Detrimental',\n        {0x00000008}  'Snap to Navmesh',\n        {0x00000010}  'No Hit Event',\n\t\t\t\t{0x00000020}  'Unknown 6',\n\t\t\t\t{0x00000040}  'Unknown 7',\n\t\t\t\t{0x00000080}  'Unknown 8',\n\t\t\t\t{0x00000100}  'Dispel with Keywords',\n\t\t\t\t{0x00000200}  'No Duration',\n\t\t\t\t{0x00000400}  'No Magnitude',\n\t\t\t\t{0x00000800}  'No Area',\n\t\t\t\t{0x00001000}  'FX Persist',\n\t\t\t\t{0x00002000}  'Unknown 14',\n\t\t\t\t{0x00004000}  'Gory Visuals',\n\t\t\t\t{0x00008000}  'Hide in UI',\n\t\t\t\t{0x00010000}  'Unknown 17',\n\t\t\t\t{0x00020000}  'No Recast',\n\t\t\t\t{0x00040000}  'Unknown 19',\n\t\t\t\t{0x00080000}  'Unknown 20',\n\t\t\t\t{0x00100000}  'Unknown 21',\n\t\t\t\t{0x00200000}  'Power Affects Magnitude',\n\t\t\t\t{0x00400000}  'Power Affects Duration',\n\t\t\t\t{0x00800000}  'Unknown 24',\n\t\t\t\t{0x01000000}  'Unknown 25',\n\t\t\t\t{0x02000000}  'Unknown 26',\n\t\t\t\t{0x04000000}  'Painless',\n\t\t\t\t{0x08000000}  'No Hit Effect',\n\t\t\t\t{0x10000000}  'No Death Dispel',\n\t\t\t\t{0x20000000}  'Unknown 30',\n\t\t\t\t{0x40000000}  'Unknown 31',\n\t\t\t\t{0x80000000}  'Unknown 32'\n\t\t\t])),\n      wbFloat('Base Cost'),\n      wbUnion('Assoc. Item', wbMGEFAssocItemDecider, [\n        wbFormID('Unused', cpIgnore),\n        wbFormIDCk('Assoc. Item', [LIGH, NULL]),\n        wbFormIDCk('Assoc. Item', [WEAP, ARMO, NULL]),\n        wbFormIDCk('Assoc. Item', [NPC_, NULL]),\n        wbFormIDCk('Assoc. Item', [HAZD, NULL]),\n        wbFormIDCk('Assoc. Item', [SPEL, NULL]),\n        wbFormIDCk('Assoc. Item', [RACE, NULL]),\n        wbFormIDCk('Assoc. Item', [ENCH, NULL]),\n        wbFormIDCk('Assoc. Item', [KYWD, NULL])\n      ], cpNormal, False, nil, wbMGEFAssocItemAfterSet),\n      wbByteArray('Magic Skill (unused)', 4),\n      wbFormIDCk('Resist Value', [AVIF, NULL]),\n      wbInteger('Counter Effect count', itU16),\n      wbByteArray('Unused', 2),\n      wbFormIDCk('Casting Light', [LIGH, NULL]),\n      wbFloat('Taper Weight'),\n      wbFormIDCk('Hit Shader', [EFSH, NULL]),\n      wbFormIDCk('Enchant Shader', [EFSH, NULL]),\n      wbInteger('Minimum Skill Level', itU32),\n      wbStruct('Spellmaking', [\n        wbInteger('Area', itU32),\n        wbFloat('Casting Time')\n      ]),\n      wbFloat('Taper Curve'),\n      wbFloat('Taper Duration'),\n      wbFloat('Second AV Weight', cpNormal, False, nil, wbMGEFAV2WeightAfterSet),\n      wbMGEFType,\n      wbActorValue,\n      wbFormIDCk('Projectile', [PROJ, NULL]),\n      wbFormIDCk('Explosion', [EXPL, NULL]),\n      wbInteger('Casting Type', itU32, wbCastEnum),\n      wbInteger('Delivery', itU32, wbTargetEnum),\n      wbActorValue, //wbInteger('Second Actor Value', itS32, wbActorValueEnum),\n      wbFormIDCk('Casting Art', [ARTO, NULL]),\n      wbFormIDCk('Hit Effect Art', [ARTO, NULL]),\n      wbFormIDCk('Impact Data', [IPDS, NULL]),\n      wbFloat('Skill Usage Multiplier'),\n      wbStruct('Dual Casting', [\n        wbFormIDCk('Art', [DUAL, NULL]),\n        wbFloat('Scale')\n      ]),\n      wbFormIDCk('Enchant Art', [ARTO, NULL]),\n      wbByteArray('Unknown', 4),\n      wbByteArray('Unknown', 4),\n      wbFormIDCk('Equip Ability', [SPEL, NULL]),\n      wbFormIDCk('Image Space Modifier', [IMAD, NULL]),\n      wbFormIDCk('Perk to Apply', [PERK, NULL]),\n      wbInteger('Casting Sound Level', itU32, wbSoundLevelEnum),\n      wbStruct('Script Effect AI', [\n        wbFloat('Score'),\n        wbFloat('Delay Time')\n      ])\n    ], cpNormal, True)\n  ], []);\n\n  wbRecord(MGEF, 'Magic Effect', [\n    wbEDID,\n    wbVMAD,\n    wbFULL,\n    wbMDOB,\n    wbKSIZ,\n    wbKWDAs,\n    wbMGEFData,\n    wbRArrayS('Counter Effects', wbFormIDCk(ESCE, 'Effect', [MGEF]), cpNormal, False, nil, wbCounterEffectsAfterSet),\n    wbArray(SNDD, 'Sounds', wbStruct('', [\n      wbInteger('Type', itU32, wbEnum([\n        'Sheathe/Draw',\n        'Charge',\n        'Ready',\n        'Release',\n        'Concentration Cast Loop',\n        'On Hit'\n      ])),\n      wbFormIDCk('Sound', [SNDR])\n    ])),\n    wbLStringKC(DNAM, 'Magic Item Description', 0, cpTranslate),\n    wbCTDAs\n  ], False, nil, cpNormal, False, nil {wbMGEFAfterLoad}, wbMGEFAfterSet);\n\n  wbRecord(MISC, 'Misc. Item',\n    wbFlags(wbRecordFlagsFlags, wbFlagsList([\n      {0x00000004}  11, 'Calc From Components',\n      {0x00000004}  13, 'Pack-In Use Only'\n    ])), [\n    wbEDID,\n    wbVMAD,\n    wbOBNDReq,\n    wbPTRN,\n    wbFULL,\n    wbMODL,\n    wbICON,\n    wbMICO,\n    wbDEST,\n    wbYNAM,\n    wbZNAM,\n    wbKSIZ,\n    wbKWDAs,\n    wbFormID(FIMD, 'Featured Item Message'),\n    wbStruct(DATA, 'Data', [\n      wbInteger('Value', itS32),\n      wbFloat('Weight')\n    ], cpNormal, True),\n    // the amount of components is the same as size of CDIX, so should not be sorted probably\n    wbStructs(CVPA, 'Components', 'Component', [\n      wbFormIDCk('Component', sigBaseObjects), // CK allows only CMPO\n      wbInteger('Count', itU32)\n    ]),\n    wbArray(CDIX, 'Component Display Indices', wbInteger('Display Index', itU8))\n  ], False, nil, cpNormal, False, wbRemoveEmptyKWDA, wbKeywordsAfterSet);\n\n  wbRecord(COBJ, 'Constructible Object', [\n    wbEDID,\n    wbYNAM,\n    wbZNAM,\n    wbArrayS(FVPA, 'Components',\n      wbStructSK([0], 'Component', [\n        wbFormIDCk('Component', sigBaseObjects),\n        wbInteger('Count', itU32)\n      ])\n    ),\n    wbDESC,\n    wbCTDAs,\n    wbFormIDCk(CNAM, 'Created Object', sigBaseObjects),\n    wbFormIDCk(BNAM, 'Workbench Keyword', [KYWD]),\n    wbByteArray(NAM1, 'Unused', 0, cpIgnore, False, False, wbNeverShow), // co_PA_FusionCore01\n    wbByteArray(NAM2, 'Unused', 0, cpIgnore, False, False, wbNeverShow), // co_PA_FusionCore01\n    wbByteArray(NAM3, 'Unused', 0, cpIgnore, False, False, wbNeverShow), // co_PA_FusionCore01\n    wbFormIDCk(ANAM, 'Menu Art Object', [ARTO]),\n    wbArrayS(FNAM, 'Category', wbFormIDCk('Keyword', [KYWD])),\n    wbStruct(INTV, 'Data', [\n      wbInteger('Created Object Count', itU16),\n      wbInteger('Priority', itU16)\n    ], cpNormal, False, nil, 1)\n  ]);\n\n  wbRecord(NPC_, 'Non-Player Character (Actor)',\n    wbFlags(wbRecordFlagsFlags, wbFlagsList([\n      {0x00000400} 10, 'Unknown 10',\n      {0x00040000} 18, 'Compressed',\n      {0x00080000} 19, 'Unknown 19',\n      {0x20000000} 29, 'Bleedout Override'\n    ]), [18]), [\n    wbEDID,\n    wbVMAD,\n    wbOBNDReq,\n    wbPTRN,\n    wbFormIDCk(STCP, 'Unknown', [STAG]),\n    wbStruct(ACBS, 'Configuration', [\n      wbInteger('Flags', itU32, wbFlags([\n        {0x00000001} 'Female',\n        {0x00000002} 'Essential',\n        {0x00000004} 'Is CharGen Face Preset',\n        {0x00000008} 'Respawn',\n        {0x00000010} 'Auto-calc stats',\n        {0x00000020} 'Unique',\n        {0x00000040} 'Doesn''t affect stealth meter',\n        {0x00000080} 'PC Level Mult',\n        {0x00000100} 'Unknown 8',\n        {0x00000200} 'Calc For Each Template',\n        {0x00000400} 'Unknown 10',\n        {0x00000800} 'Protected',\n        {0x00001000} 'Unknown 12',\n        {0x00002000} 'Unknown 13',\n        {0x00004000} 'Summonable',\n        {0x00008000} 'Unknown 15',\n        {0x00010000} 'Doesn''t bleed',\n        {0x00020000} 'Unknown 17',\n        {0x00040000} 'Bleedout Override',\n        {0x00080000} 'Opposite Gender Anims',\n        {0x00100000} 'Simple Actor',\n        {0x00200000} 'Unknown 21',\n        {0x00400000} 'Unknown 22',\n        {0x00800000} 'No Activation/Hellos',\n        {0x01000000} 'Diffuse Alpha Test',\n        {0x02000000} 'Unknown 25',\n        {0x04000000} 'Unknown 26',\n        {0x08000000} 'Unknown 27',\n        {0x10000000} 'Unknown 28',\n        {0x20000000} 'Is Ghost',\n        {0x40000000} 'Unknown 30',\n        {0x80000000} 'Invulnerable'\n      ])),\n      wbInteger('XP Value Offset', itS16, nil, cpNormal, True, nil{wbActorTemplateUseStats}),\n      wbUnion('Level', wbNPCLevelDecider, [\n        wbInteger('Level', itS16, nil, cpNormal, True, nil{wbActorTemplateUseStats}),\n        wbInteger('Level Mult', itS16, wbDiv(1000), cpNormal, True, nil{wbActorTemplateUseStats})\n      ], cpNormal, True, nil{wbActorTemplateUseStats}),\n      wbInteger('Calc min level', itU16, nil, cpNormal, True, nil{wbActorTemplateUseStats}),\n      wbInteger('Calc max level', itU16, nil, cpNormal, True, nil{wbActorTemplateUseStats}),\n      wbInteger('Disposition Base', itS16),\n      wbInteger('Use Template Actors', itU16, wbFlags([\n        {0x0001} 'Traits',\n        {0x0002} 'Stats',\n        {0x0004} 'Factions',\n        {0x0008} 'Spell List',\n        {0x0010} 'AI Data',\n        {0x0020} 'AI Packages',\n        {0x0040} 'Model/Animation',\n        {0x0080} 'Base Data',\n        {0x0100} 'Inventory',\n        {0x0200} 'Script',\n        {0x0400} 'Def Pack List',\n        {0x0800} 'Attack Data',\n        {0x1000} 'Keywords'\n      ])),\n      wbInteger('Bleedout Override', itU16),\n      wbByteArray('Unknown', 2)\n    ], cpNormal, True),\n    wbRArrayS('Factions',\n      wbStructSK(SNAM, [0], 'Faction', [\n        wbFormIDCk('Faction', [FACT]),\n        wbInteger('Rank', itS8)\n      ]), cpNormal, False, nil, nil, nil{wbActorTemplateUseFactions}\n    ),\n    wbFormIDCk(INAM, 'Death item', [LVLI], False, cpNormal, False, nil{wbActorTemplateUseTraits}),\n    wbFormIDCk(VTCK, 'Voice', [VTYP], False, cpNormal, False, nil{wbActorTemplateUseTraits}),\n    wbFormIDCk(TPLT, 'Default Template', [LVLN, NPC_]),\n    wbFormIDCk(LTPT, 'Legendary Template', [LVLN, NPC_]),\n    wbFormIDCk(LTPC, 'Legendary Chance', [GLOB]),\n    wbStruct(TPTA, 'Template Actors', [\n      wbFormIDCk('Traits', [LVLN, NPC_, NULL], False, cpNormal, False, wbActorTemplatesUseTemplate0),\n      wbFormIDCk('Stats', [LVLN, NPC_, NULL], False, cpNormal, False, wbActorTemplatesUseTemplate1),\n      wbFormIDCk('Factions', [LVLN, NPC_, NULL], False, cpNormal, False, wbActorTemplatesUseTemplate2),\n      wbFormIDCk('Spell List', [LVLN, NPC_, NULL], False, cpNormal, False, wbActorTemplatesUseTemplate3),\n      wbFormIDCk('AI Data', [LVLN, NPC_, NULL], False, cpNormal, False, wbActorTemplatesUseTemplate4),\n      wbFormIDCk('AI Packages', [LVLN, NPC_, NULL], False, cpNormal, False, wbActorTemplatesUseTemplate5),\n      wbFormIDCk('Model/Animation', [LVLN, NPC_, NULL], False, cpNormal, False, wbActorTemplatesUseTemplate6),\n      wbFormIDCk('Base Data', [LVLN, NPC_, NULL], False, cpNormal, False, wbActorTemplatesUseTemplate7),\n      wbFormIDCk('Inventory', [LVLN, NPC_, NULL], False, cpNormal, False, wbActorTemplatesUseTemplate8),\n      wbFormIDCk('Script', [LVLN, NPC_, NULL], False, cpNormal, False, wbActorTemplatesUseTemplate9),\n      wbFormIDCk('Def Pack List', [LVLN, NPC_, NULL], False, cpNormal, False, wbActorTemplatesUseTemplate10),\n      wbFormIDCk('Attack Data', [LVLN, NPC_, NULL], False, cpNormal, False, wbActorTemplatesUseTemplate11),\n      wbFormIDCk('Keywords', [LVLN, NPC_, NULL], False, cpNormal, False, wbActorTemplatesUseTemplate12)\n    ]),\n    wbFormIDCk(RNAM, 'Race', [RACE], False, cpNormal, True, nil{wbActorTemplateUseTraits}),\n    wbSPCT,\n    wbSPLOs,\n    wbDEST,\n    wbFormIDCk(WNAM, 'Skin', [ARMO], False, cpNormal, False),\n    wbFormIDCk(ANAM, 'Far away model', [ARMO], False, cpNormal, False, nil{wbActorTemplateUseTraits}),\n    wbFormIDCk(ATKR, 'Attack Race', [RACE], False, cpNormal, False),\n    wbRArrayS('Attacks', wbAttackData),\n    wbFormIDCk(SPOR, 'Spectator Override Package List', [FLST]),\n    wbFormIDCk(OCOR, 'Observe Dead Body Override Package List', [FLST]),\n    wbFormIDCk(GWOR, 'Guard Warn Override Package List', [FLST]),\n    wbFormIDCk(ECOR, 'Combat Override Package List', [FLST]),\n    wbFormIDCk(FCPL, 'Follower Command Package List', [FLST]),\n    wbFormIDCk(RCLR, 'Follower Elevator Package List', [FLST]),\n    wbInteger(PRKZ, 'Perk Count', itU32, nil, cpBenign),\n    wbRArrayS('Perks',\n      wbStructSK(PRKR, [0], 'Perk', [\n        wbFormIDCk('Perk', [PERK]),\n        wbInteger('Rank', itU8)\n      ]), cpNormal, False, nil, wbPRKRsAfterSet\n    ),\n    wbPRPS,\n    wbFTYP,\n    wbNTRM,\n    wbCOCT,\n    wbCNTOs,\n    wbAIDT,\n    wbRArray('Packages', wbFormIDCk(PKID, 'Package', [PACK]), cpNormal, False, nil{wbActorTemplateUseAIPackages}),\n    wbKSIZ,\n    wbKWDAs,\n    wbAPPR,\n    wbObjectTemplate,\n    wbFormIDCk(CNAM, 'Class', [CLAS], False, cpNormal, True),\n    wbFULL,\n    wbLString(SHRT, 'Short Name', 0, cpTranslate),\n    wbByteArray(DATA, 'Marker'),\n    wbStruct(DNAM, '', [\n      wbInteger('Unknown', itU16),\n      wbInteger('Unknown', itU16),\n      wbInteger('Far Away Model Distance', itU16),\n      wbInteger('Geared Up Weapons', itU16)\n    ]),\n    wbRArrayS('Head Parts', wbFormIDCk(PNAM, 'Head Part', [HDPT]), cpNormal, False, nil, nil, nil{wbActorTemplateUseModelAnimation}),\n    wbFormIDCk(HCLF, 'Hair Color', [CLFM], False, cpNormal, False),\n    wbFormIDCk(BCLF, 'Facial Hair Color', [CLFM], False, cpNormal, False),\n    wbFormIDCk(ZNAM, 'Combat Style', [CSTY], False, cpNormal, False),\n    wbFormIDCk(GNAM, 'Gift Filter', [FLST], False, cpNormal, False),\n    wbUnknown(NAM5, cpNormal, True),\n    wbFloat(NAM6, 'Height Min', cpNormal, True),\n    wbFloat(NAM7, 'Unused', cpNormal, True),\n    wbFloat(NAM4, 'Height Max'),\n    wbStruct(MWGT, 'Weight', [\n       wbFloat('Thin'),\n       wbFloat('Muscular'),\n       wbFloat('Fat')\n    ]),\n    wbInteger(NAM8, 'Sound Level', itU32, wbSoundLevelEnum, cpNormal, True),\n    wbRStruct('Actor Sounds', [\n      wbInteger(CS2H, 'Count', itU32, nil, cpBenign, True),\n      wbRArrayS('Sounds',\n        wbRStructSK([0], 'Sound', [\n          wbFormIDCk(CS2K, 'Keyword', [KYWD]),\n          wbFormIDCk(CS2D, 'Sound', [SNDR], False, cpNormal, True)\n        ], [], cpNormal, False, nil, True),\n        cpNormal, False, nil, wbNPCActorSoundsAfterSet\n      ),\n      wbEmpty(CS2E, 'End Marker', cpNormal, True),\n      wbByteArray(CS2F, 'Finalize', 1, cpNormal, True)\n    ], []),\n    wbFormIDCk(CSCR, 'Inherits Sounds From', [NPC_], False, cpNormal, False),\n    wbFormIDCk(PFRN, 'Power Armor Stand', [FURN]),\n    wbFormIDCk(DOFT, 'Default Outfit', [OTFT], False, cpNormal, False),\n    wbFormIDCk(SOFT, 'Sleeping Outfit', [OTFT], False, cpNormal, False),\n    wbFormIDCk(DPLT, 'Default Package List', [FLST], False, cpNormal, False),\n    wbFormIDCk(CRIF, 'Crime Faction', [FACT], False, cpNormal, False),\n    wbFormIDCk(FTST, 'Head Texture', [TXST], False, cpNormal, False),\n    wbStruct(QNAM, 'Texture lighting', [\n      wbFloat('Red', cpNormal, True, 255, 0),\n      wbFloat('Green', cpNormal, True, 255, 0),\n      wbFloat('Blue', cpNormal, True, 255, 0),\n      wbFloat('Alpha')\n    ]),\n    wbArray(MSDK, 'Morph Keys', wbInteger('Key', itU32, wbMorphValueToStr, wbHexStrToInt)),\n    wbArray(MSDV, 'Morph Values', wbFloat('Value')),\n    wbRArrayS('Face Tinting Layers',\n      wbRStructSK([0], 'Layer', [\n        wbStructSK(TETI, [1], 'Index', [\n          wbInteger('Data Type', itU16, wbEnum(['', 'Value/Color', 'Value'])),\n          wbInteger('Index', itU16, wbTintLayerToStr, wbStrToInt)\n        ]),\n        //wbByteArray(TEND, 'Data')\n        wbStruct(TEND, 'Data', [\n          wbInteger('Value', itU8, wbDiv(100)),\n          wbByteColors('Color'),\n          wbInteger('Template Color Index', itS16)\n        ], cpNormal, True, nil, 1)\n      ], [])\n    ),\n    wbStruct(MRSV, 'Body Morph Region Values', [\n      wbFloat('Head'),\n      wbFloat('Upper Torso'),\n      wbFloat('Arms'),\n      wbFloat('Lower Torso'),\n      wbFloat('Legs')\n    ]),\n    // reported to cause issues when sorted\n    wbRArrayS('Face Morphs',\n      wbRStructSK([0], 'Face Morph', [\n        wbInteger(FMRI, 'Index', itU32, wbFaceMorphToStr, wbHexStrToInt),\n        //wbArray(FMRS, 'Unknown', wbFloat('Unknown'))\n        wbStruct(FMRS, 'Values', [\n          wbFloat('Position - X'),\n          wbFloat('Position - Y'),\n          wbFloat('Position - Z'),\n          wbFloat('Rotation - X'),\n          wbFloat('Rotation - Y'),\n          wbFloat('Rotation - Z'),\n          wbFloat('Scale'),\n          wbByteArray('Unknown')\n        ])\n      ], [])\n    ),\n    wbFloat(FMIN, 'Facial Morph Intensity'),\n    wbATTX\n  ], False, nil, cpNormal, False, wbNPCAfterLoad, wbNPCAfterSet);\n\n  wbPKDTSpecificFlagsUnused := False;\n\n  wbPKDTFlags := wbFlags([\n    {0x00000001} 'Offers Services',\n    {0x00000002} 'Unknown 2',\n    {0x00000004} 'Must complete',\n    {0x00000008} 'Maintain Speed at Goal',\n    {0x00000010} 'Treat As Player Follower',\n    {0x00000020} 'Unknown 6',\n    {0x00000040} 'Unlock doors at package start',\n    {0x00000080} 'Unlock doors at package end',\n    {0x00000100} 'Request Block Idles',\n    {0x00000200} 'Continue if PC Near',\n    {0x00000400} 'Once per day',\n    {0x00000800} 'Unknown 12',\n    {0x00001000} 'Skip Load Into Furniture',\n    {0x00002000} 'Preferred Speed',\n    {0x00004000} 'Unknown 15',\n    {0x00008000} 'Unknown 16',\n    {0x00010000} 'Unknown 17',\n    {0x00020000} 'Always Sneak',\n    {0x00040000} 'Allow Swimming',\n    {0x00080000} 'Unknown 20',\n    {0x00100000} 'Ignore Combat',\n    {0x00200000} 'Weapons Unequipped',\n    {0x00400000} 'Unknown 23',\n    {0x00800000} 'Weapon Drawn',\n    {0x01000000} 'Unknown 25',\n    {0x02000000} 'Unknown 26',\n    {0x04000000} 'Unknown 27',\n    {0x08000000} 'No Combat Alert',\n    {0x10000000} 'Unknown 29',\n    {0x20000000} 'Wear Sleep Outfit',\n    {0x40000000} 'Unknown 31',\n    {0x80000000} 'Unknown 32'\n  ], [29]);\n\n  wbPKDTInterruptFlags := wbFlags([\n    {0x0001} 'Hellos to player',\n    {0x0002} 'Random conversations',\n    {0x0004} 'Observe combat behavior',\n    {0x0008} 'Greet corpse behavior',\n    {0x0010} 'Reaction to player actions',\n    {0x0020} 'Friendly fire comments',\n    {0x0040} 'Aggro Radius Behavior',\n    {0x0080} 'Allow Idle Chatter',\n    {0x0100} 'Unknown 9',\n    {0x0200} 'World Interactions',\n    {0x0400} 'Off For Important Scene',\n    {0x0800} 'Unknown 12',\n    {0x1000} 'Unknown 13',\n    {0x2000} 'Unknown 14',\n    {0x4000} 'Unknown 15',\n    {0x8000} 'Unknown 16'\n  ]);\nend;\n\n\nprocedure DefineFO4n;\n\n  function wbTintTemplateGroups(const aName: string): IwbSubRecordArrayDef;\n  begin\n    Result :=\n      wbRStructs(aName, 'Group', [\n        wbLString(TTGP, 'Group Name', 0, cpTranslate),\n        wbRStructs('Options', 'Option', [\n          wbStruct(TETI, 'Index', [\n            wbByteArray('Unknown', 2),\n            wbInteger('Index', itU16)\n          ]),\n          wbLString(TTGP, 'Name', 0, cpTranslate),\n          wbUnknown(TTEF),\n          wbCTDAs,\n          wbRArray('Textures', wbString(TTET, 'Texture')),\n          wbUnknown(TTEB),\n          wbArray(TTEC, 'Template Colors', wbStruct('Template Color', [\n            wbFormIDCk('Color', [CLFM]),\n            wbFloat('Alpha'),\n            wbInteger('Template Index', itU16),\n            wbByteArray('Unknown', 4)\n          ])),\n          wbFloat(TTED, 'Unknown')\n        ], []),\n        wbByteArray(TTGE, 'Group End', 4)\n      ], []);\n  end;\n\n  function wbMorphGroups(const aName: string): IwbSubRecordArrayDef;\n  begin\n    Result :=\n      wbRArray(aName,\n        wbRStruct('Morph Group', [\n          wbString(MPGN, 'Name'),\n          wbInteger(MPPC, 'Count', itU32, nil, cpBenign),\n          wbRArray('Morph Presets',\n            wbRStruct('Morph Preset', [\n              wbInteger(MPPI, 'Index', itU32, wbIntToHexStr, wbHexStrToInt),\n              wbLString(MPPN, 'Name', 0, cpTranslate),\n              wbString(MPPM, 'Unknown'),\n              wbFormIDCk(MPPT, 'Texture', [TXST]),\n              wbUnknown(MPPF)\n            ], []),\n            cpNormal, False, nil, wbMorphPresetsAfterSet\n          ),\n          wbUnknown(MPPK),\n          wbUnknown(MPGS)\n        ], [])\n      );\n  end;\n\n  function wbFaceMorphs(const aName: string): IwbSubRecordArrayDef;\n  begin\n    Result :=\n      wbRArray(aName,\n        wbRStruct('Face Morph', [\n          wbInteger(FMRI, 'Index', itU32, wbIntToHexStr, wbHexStrToInt),\n          wbLString(FMRN, 'Name')\n        ], [])\n      );\n  end;\n\nbegin\n  wbUNAMs := wbRArray('Data Inputs', wbRStruct('Data Input', [\n    wbInteger(UNAM, 'Index', itS8),\n    wbString(BNAM, 'Name'),\n    wbInteger(PNAM, 'Flags', itU32, wbFlags([\n      'Public'\n    ]))\n  ], []));\n\n  wbRecord(PACK, 'Package', [\n    wbEDID,\n    wbVMADFragmentedPACK,\n\n    wbStruct(PKDT, 'Pack Data', [\n      wbInteger('General Flags', itU32, wbPKDTFlags),\n      wbInteger('Type', itU8, wbEnum ([], [\n        18, 'Package',\n        19, 'Package Template'\n      ])),\n      wbInteger('Interrupt Override', itU8, wbEnum([\n        {0} 'None',\n        {1} 'Spectator',\n        {2} 'ObserveDead',\n        {3} 'GuardWarn',\n        {4} 'Combat',\n        {5} 'Command Travel',\n        {6} 'Command Activate',\n        {7} 'Leave Workstation'\n      ])),\n      wbInteger('Preferred Speed', itU8, wbEnum([\n        'Walk',\n        'Jog',\n        'Run',\n        'Fast Walk'\n      ])),\n      wbByteArray('Unknown', 1),\n      wbInteger('Interrupt Flags', itU16, wbPKDTInterruptFlags),\n      wbByteArray('Unknown', 2)\n    ], cpNormal, True),\n\n    wbStruct(PSDT, 'Schedule', [\n      wbInteger('Month', itS8),\n      wbInteger('Day of week', itS8, wbEnum([\n        'Sunday',\n        'Monday',\n        'Tuesday',\n        'Wednesday',\n        'Thursday',\n        'Friday',\n        'Saturday',\n        'Weekdays',\n        'Weekends',\n        'Monday, Wednesday, Friday',\n        'Tuesday, Thursday'\n      ], [\n        -1, 'Any'\n      ])),\n      wbInteger('Date', itU8),\n      wbInteger('Hour', itS8),\n      wbInteger('Minute', itS8),\n      wbByteArray('Unused', 3, cpIgnore),\n      wbInteger('Duration (minutes)', itS32)\n    ], cpNormal, True),\n\n    wbCTDAs,\n\n    wbRStruct('Idle Animations', [\n      wbInteger(IDLF, 'Flags', itU8, wbEnum([], [\n         0, 'Unknown',\n         8, 'Random',\n         9, 'Run in Sequence',\n        12, 'Random, Do Once',\n        13, 'Run in Sequence, Do Once'\n      ]), cpNormal, True),\n      wbInteger(IDLC, 'Animation Count', itU8, nil, cpBenign),\n      wbFloat(IDLT, 'Idle Timer Setting', cpNormal, True),\n      wbArray(IDLA, 'Animations', wbFormIDCk('Animation', [IDLE]), 0, nil, wbIDLAsAfterSet, cpNormal, True),\n      wbByteArray(IDLB, 'Unknown', 4, cpIgnore)\n    ], [], cpNormal, False, nil, False, nil {cannot be totally removed , wbAnimationsAfterSet}),\n\n    wbFormIDCk(CNAM, 'Combat Style', [CSTY]),\n    wbFormIDCk(QNAM, 'Owner Quest', [QUST]),\n    wbStruct(PKCU, 'Counter', [\n      wbInteger('Data Input Count', itU32),\n      wbFormIDCk('Package Template', [PACK, NULL]),\n      wbInteger('Version Counter (autoincremented)', itU32)\n    ], cpNormal, True),\n\n    wbRStruct('Package Data', [\n      wbRArray('Data Input Values', wbRStruct('Value', [\n        wbString(ANAM, 'Type'),\n        wbUnion(CNAM, 'Value', wbPubPackCNAMDecider, [\n          {0} wbByteArray('Unknown'),\n          {1} wbInteger('Bool', itU8, wbBoolEnum),\n          {2} wbInteger('Integer', itU32),\n          {3} wbFloat('Float')\n        ]),\n        wbUnknown(BNAM),\n        wbPDTOs,\n        wbPLDT,\n        wbStruct(PTDA, 'Target', [wbTargetData]),\n        wbUnknown(TPIC)\n      ], [], cpNormal, False)),\n      wbUNAMs\n    ], []),\n    wbByteArray(XNAM, 'Marker'),\n\n    wbRStruct('Procedure Tree', [\n      wbRArray('Branches', wbRStruct('Branch', [\n        wbString(ANAM, 'Branch Type'),\n        wbCITC,\n        wbCTDAsCount,\n        wbStruct(PRCB, 'Root', [\n          wbInteger('Branch Count', itU32),\n          wbInteger('Flags', itU32, wbFlags([\n            'Repeat when Complete',\n            'Unknown 1'\n          ]))\n        ]),\n        wbString(PNAM, 'Procedure Type'),\n        wbInteger(FNAM, 'Flags', itU32, wbFlags(['Success Completes Package'])),\n        wbRArray('Data Input Indexes', wbInteger(PKC2, 'Index', itU8)),\n        {>>> PFO2 should be single, there is only 1 PACK [00095F46] <PatrolAndHunt> in Skyrim.esm with 2xPFO2 <<<}\n        wbRArray('Flags Override',\n          wbStruct(PFO2, 'Data', [\n            wbInteger('Set General Flags', itU32, wbPKDTFlags),\n            wbInteger('Clear General Flags', itU32, wbPKDTFlags),\n            wbInteger('Set Interrupt Flags', itU16, wbPKDTInterruptFlags),\n            wbInteger('Clear Interrupt Flags', itU16, wbPKDTInterruptFlags),\n            wbInteger('Preferred Speed Override', itU8, wbEnum([\n              'Walk',\n              'Jog',\n              'Run',\n              'Fast Walk'\n            ])),\n            wbByteArray('Unknown', 3)\n          ])\n        ),\n        wbRArray('Unknown', wbUnknown(PFOR), cpIgnore)\n      ], [], cpNormal, False, nil, False, nil, wbConditionsAfterSet))\n    ], []),\n    wbUNAMs,\n    wbRStruct('OnBegin', [\n      wbEmpty(POBA, 'OnBegin Marker', cpNormal, True),\n      wbFormIDCk(INAM, 'Idle', [IDLE, NULL], False, cpNormal, True),\n      wbPDTOs\n    ], []),\n    wbRStruct('OnEnd', [\n      wbEmpty(POEA, 'OnEnd Marker', cpNormal, True),\n      wbFormIDCk(INAM, 'Idle', [IDLE, NULL], False, cpNormal, True),\n      wbPDTOs\n    ], []),\n    wbRStruct('OnChange', [\n      wbEmpty(POCA, 'OnChange Marker', cpNormal, True),\n      wbFormIDCk(INAM, 'Idle', [IDLE, NULL], False, cpNormal, True),\n      wbPDTOs\n    ], [])\n  ], False, nil, cpNormal, False, nil {wbPACKAfterLoad});\n\n  wbQUSTAliasFlags :=\n    wbInteger(FNAM, 'Flags', itU32, wbFlags([\n      {0x00000001} 'Reserves Location/Reference',\n      {0x00000002} 'Optional',\n      {0x00000004} 'Quest Object',\n      {0x00000008} 'Allow Reuse in Quest',\n      {0x00000010} 'Allow Dead',\n      {0x00000020} 'Matching Ref - In Loaded Area',\n      {0x00000040} 'Essential',\n      {0x00000080} 'Allow Disabled',\n      {0x00000100} 'Stores Text',\n      {0x00000200} 'Allow Reserved',\n      {0x00000400} 'Protected',\n      {0x00000800} 'Forced by Aliases',\n      {0x00001000} 'Allow Destroyed',\n      {0x00002000} 'Matching Ref - Closest',\n      {0x00004000} 'Uses Stored Text',\n      {0x00008000} 'Initially Disabled',\n      {0x00010000} 'Allow Cleared',\n      {0x00020000} 'Clear Names When Removed',\n      {0x00040000} 'Matching Ref - Actors Only',\n      {0x00080000} 'Create Ref - Temp',\n      {0x00100000} 'External Alias - Linked',\n      {0x00200000} 'No Pickpocket',\n      {0x00400000} 'Can Apply Data To Non-Aliased Refs',\n      {0x00800000} 'Is Companion',\n      {0x01000000} 'Optional All Scenes'\n    ]));\n\n  wbRecord(QUST, 'Quest',\n    wbFlags(wbRecordFlagsFlags, wbFlagsList([\n      {0x00004000} 14, 'Partial Form'\t// Allows the Record to inherit some subrecords from its master\n    ])), [\n    wbEDID,\n    wbVMADFragmentedQUST,\n    wbFULL,\n    wbStruct(DNAM, 'General', [\n      wbInteger('Flags', itU16, wbFlags([\n        {0x0001} 'Start Game Enabled',\n        {0x0002} 'Unknown 2',\n        {0x0004} 'Add Idle Topic To Hello',\n        {0x0008} 'Allow repeated stages',\n        {0x0010} 'Unknown 5',\n        {0x0020} 'Unknown 6',\n        {0x0040} 'Unknown 7',\n        {0x0080} 'Unknown 8',\n        {0x0100} 'Run Once',\n        {0x0200} 'Exclude from dialogue export',\n        {0x0400} 'Warn on alias fill failure',\n        {0x0800} 'Unknown 12',\n        {0x1000} 'Unknown 13'\n      ])),\n      wbInteger('Priority', itU8),\n      wbInteger('Form Version', itU8, nil, cpIgnore),\n      wbByteArray('Unknown', 4),\n      wbInteger('Type', itU32, wbEnum([\n        {0} 'None',\n        {1} 'Main Quest',\n        {2} 'Brotherhood of Steel',\n        {3} 'Institute',\n        {4} 'Minutemen',\n        {5} 'Railroad',\n        {6} 'Miscellaneous',\n        {7} 'Side Quests',\n        {8} 'DLC01',\n        {9} 'DLC02',\n       {10} 'DLC03',\n       {11} 'DLC04',\n       {12} 'DLC05',\n       {13} 'DLC06',\n       {14} 'DLC07'\n      ]))\n    ]),\n    wbString(ENAM, 'Event', 4),\n    wbFormIDCk(LNAM, 'Location', [LCTN]),\n    wbFormIDCk(XNAM, 'Quest Completion XP', [GLOB]),\n    wbRArray('Text Display Globals', wbFormIDCk(QTGL, 'Global', [GLOB])),\n    wbFLTR,\n    wbRStruct('Quest Dialogue Conditions', [wbCTDAs], [], cpNormal, False),\n    wbEmpty(NEXT, 'Marker'),\n    wbCTDAs, {>>> Unknown, doesn't show up in CK <<<}\n    wbRArrayS('Stages', wbRStructSK([0], 'Stage', [\n      wbStructSK(INDX, [0], 'Stage Index', [\n        wbInteger('Stage Index', itU16),\n        wbInteger('Flags', itU8, wbFlags([\n          {0x01} 'Unknown 1',\n          {0x02} 'Run On Start',\n          {0x04} 'Run On Stop',\n          {0x08} 'Keep Instance Data From Here On'\n        ])),\n        wbInteger('Unknown', itU8)\n      ]),\n      wbRArray('Log Entries', wbRStruct('Log Entry', [\n        wbInteger(QSDT, 'Stage Flags', itU8, wbFlags([\n          {0x01} 'Complete Quest',\n          {0x02} 'Fail Quest'\n        ])),\n        wbCTDAs,\n        wbString(NAM2, 'Note'),\n        wbLString(CNAM, 'Log Entry', 0, cpTranslate),\n        wbFormIDCk(NAM0, 'Next Quest', [QUST])\n      ], []))\n    ], [])),\n    wbRArray('Objectives', wbRStruct('Objective', [\n      wbInteger(QOBJ, 'Objective Index', itU16),\n      wbInteger(FNAM, 'Flags', itU32, wbFlags([\n        {0x01} 'ORed With Previous',\n        {0x02} 'No Stats Tracking'\n      ])),\n      wbLString(NNAM, 'Display Text', 0, cpTranslate, True),\n      wbRArray('Targets', wbRStruct('Target', [\n        wbStruct(QSTA, 'Target', [\n          wbInteger('Alias', itS32, wbQuestAliasToStr, wbStrToAlias),\n          wbInteger('Flags', itU32, wbFlags([\n            {0x01} 'Compass Marker Ignores Locks',\n            {0x02} 'Hostile',\n            {0x04} 'Use Straight Line Pathing'\n          ])),\n          wbFormIDCk('Keyword', [KYWD, NULL])\n        ]),\n        wbCTDAs\n      ], []))\n    ], [])),\n\n    wbByteArray(ANAM, 'Aliases Marker', 4),\n\n    wbRArray('Aliases',\n      wbRUnion('Alias', [\n\n        // Reference Alias\n        wbRStruct('Alias', [\n          wbInteger(ALST, 'Reference Alias ID', itU32),\n          wbString(ALID, 'Alias Name'),\n          wbQUSTAliasFlags,\n          wbInteger(ALFI, 'Force Into Alias When Filled', itS32, wbQuestAliasToStr, wbStrToAlias),\n          //wbFormIDCk(ALFL, 'Specific Location', [LCTN]),\n          wbFormID(ALFR, 'Forced Reference'),\n          wbFormIDCk(ALUA, 'Unique Actor', [NPC_]),\n          wbRStruct('Location Alias Reference', [\n            wbInteger(ALFA, 'Alias', itS32, wbQuestAliasToStr, wbStrToAlias),\n            wbFormIDCk(KNAM, 'Keyword', [KYWD]),\n            wbFormIDCk(ALRT, 'Ref Type', [LCRT])\n          ], []),\n          wbRStruct('External Alias Reference', [\n            wbFormIDCk(ALEQ, 'Quest', [QUST]),\n            wbInteger(ALEA, 'Alias', itS32, wbQuestExternalAliasToStr, wbStrToAlias)\n          ], []),\n          wbRStruct('Create Reference to Object', [\n            wbFormID(ALCO, 'Object'),\n            wbStruct(ALCA, 'Alias', [\n              wbInteger('Alias', itS16, wbQuestAliasToStr, wbStrToAlias),\n              wbInteger('Create', itU16, wbEnum([] ,[\n                $0000, 'At',\n                $8000, 'In'\n              ]))\n            ]),\n            wbInteger(ALCL, 'Level', itU32, wbEnum([\n              'Easy',\n              'Medium',\n              'Hard',\n              'Very Hard',\n              'None'\n            ]))\n          ], []),\n          wbRStruct('Find Matching Reference Near Alias', [\n            wbInteger(ALNA, 'Alias', itS32, wbQuestAliasToStr, wbStrToAlias),\n            wbInteger(ALNT, 'Type', itU32, wbEnum([\n              'Linked From',\n              'Linked Ref'\n            ]))\n          ], []),\n          wbRStruct('Find Matching Reference From Event', [\n            wbString(ALFE, 'From Event', 4),\n            wbByteArray(ALFD, 'Event Data')\n          ], []),\n          wbInteger(ALCC, 'Closest To Alias', itS32, wbQuestAliasToStr, wbStrToAlias),\n          wbCTDAs,\n          wbKSIZ,\n          wbKWDAs,\n          wbCOCT,\n          wbCNTOs,\n          wbFormIDCk(SPOR, 'Spectator override package list', [FLST], False, cpNormal, False),\n          wbFormIDCk(OCOR, 'Observe dead body override package list', [FLST], False, cpNormal, False),\n          wbFormIDCk(GWOR, 'Guard warn override package list', [FLST], False, cpNormal, False),\n          wbFormIDCk(ECOR, 'Combat override package list', [FLST], False, cpNormal, False),\n          wbArray(ALLA, 'Linked Aliases', wbStruct('Linked Alias', [\n            wbFormIDCk('Keyword', [KYWD, NULL]),\n            wbInteger('Alias', itS32, wbQuestAliasToStr, wbStrToAlias)\n          ])),\n          wbFormIDCk(ALDN, 'Display Name', [MESG]),\n          wbFormIDCk(ALFV, 'Forced Voice', [VTYP]),\n          wbFormIDCk(ALDI, 'Death Item', [LVLI]),\n          wbRArrayS('Alias Spells', wbFormIDCk(ALSP, 'Spell', [SPEL])),\n          wbRArrayS('Alias Factions', wbFormIDCk(ALFC, 'Faction', [FACT])),\n          wbRArray('Alias Package Data', wbFormIDCk(ALPC, 'Package', [PACK])),\n          wbFormIDCk(VTCK, 'Voice Types', [NPC_, FACT, FLST, VTYP, NULL]),\n          wbEmpty(ALED, 'Alias End', cpNormal, True)\n        ], [], cpNormal, False, nil, False, nil, wbContainerAfterSet),\n\n        // Location Alias\n        wbRStruct('Alias', [\n          wbInteger(ALLS, 'Location Alias ID', itU32),\n          wbString(ALID, 'Alias Name'),\n          wbQUSTAliasFlags,\n          wbInteger(ALFI, 'Force Into Alias When Filled', itS32, wbQuestAliasToStr, wbStrToAlias),\n          wbFormIDCk(ALFL, 'Specific Location', [LCTN]),\n          wbRStruct('Reference Alias Location', [\n            wbInteger(ALFA, 'Alias', itS32, wbQuestAliasToStr, wbStrToAlias),\n            wbFormIDCk(KNAM, 'Keyword', [KYWD])\n          ], []),\n          wbRStruct('External Alias Location', [\n            wbFormIDCk(ALEQ, 'Quest', [QUST]),\n            wbInteger(ALEA, 'Alias', itS32, wbQuestExternalAliasToStr, wbStrToAlias)\n          ], []),\n          wbRStruct('Find Matching Location From Event', [\n            wbString(ALFE, 'From Event', 4),\n            wbByteArray(ALFD, 'Event Data')\n          ], []),\n          wbCTDAs,\n          wbInteger(ALCC, 'Closest To Alias', itS32, wbQuestAliasToStr, wbStrToAlias),\n          wbEmpty(ALED, 'Alias End', cpNormal, True)\n        ], []),\n\n        // Ref Collection Alias\n        wbRStruct('Alias', [\n          wbInteger(ALCS, 'Collection Alias ID', itU32),\n          wbInteger(ALMI, 'Max Initial Fill Count', itU8)\n        ], [])\n\n      ], [])\n    ),\n\n    wbString(NNAM, 'Description', 0, cpTranslate, False),\n    wbFormIDCk(GNAM, 'Quest Group', [KYWD]),\n    wbString(SNAM, 'SWF File')\n  ]);\n\n  wbBodyPartIndexEnum := wbEnum([\n    'Body Texture'\n  ]);\n\n  wbPhonemeTargets := wbStruct(PHWT, 'Phoneme Target Weight', [\n    wbFloat('Aah / LipBigAah'),\n    wbFloat('BigAah / LipDST'),\n    wbFloat('BMP / LipEee'),\n    wbFloat('ChJsh / LipFV'),\n    wbFloat('DST / LipK'),\n    wbFloat('Eee / LipL'),\n    wbFloat('Eh / LipR'),\n    wbFloat('FV / LipTh'),\n    wbFloat('I'),\n    wbFloat('K'),\n    wbFloat('N'),\n    wbFloat('Oh'),\n    wbFloat('OohQ'),\n    wbFloat('R'),\n    wbFloat('TH'),\n    wbFloat('W'),\n    wbUnknown\n  ], cpNormal, False, nil, 1); // only a single value in HandyRace\n\n  wbPHWT := wbRStruct('FaceFX Phonemes', [\n    wbRStruct('IY', [wbPhonemeTargets], []),\n    wbRStruct('IH', [wbPhonemeTargets], []),\n    wbRStruct('EH', [wbPhonemeTargets], []),\n    wbRStruct('EY', [wbPhonemeTargets], []),\n    wbRStruct('AE', [wbPhonemeTargets], []),\n    wbRStruct('AA', [wbPhonemeTargets], []),\n    wbRStruct('AW', [wbPhonemeTargets], []),\n    wbRStruct('AY', [wbPhonemeTargets], []),\n    wbRStruct('AH', [wbPhonemeTargets], []),\n    wbRStruct('AO', [wbPhonemeTargets], []),\n    wbRStruct('OY', [wbPhonemeTargets], []),\n    wbRStruct('OW', [wbPhonemeTargets], []),\n    wbRStruct('UH', [wbPhonemeTargets], []),\n    wbRStruct('UW', [wbPhonemeTargets], []),\n    wbRStruct('ER', [wbPhonemeTargets], []),\n    wbRStruct('AX', [wbPhonemeTargets], []),\n    wbRStruct('S',  [wbPhonemeTargets], []),\n    wbRStruct('SH', [wbPhonemeTargets], []),\n    wbRStruct('Z',  [wbPhonemeTargets], []),\n    wbRStruct('ZH', [wbPhonemeTargets], []),\n    wbRStruct('F',  [wbPhonemeTargets], []),\n    wbRStruct('TH', [wbPhonemeTargets], []),\n    wbRStruct('V',  [wbPhonemeTargets], []),\n    wbRStruct('DH', [wbPhonemeTargets], []),\n    wbRStruct('M',  [wbPhonemeTargets], []),\n    wbRStruct('N',  [wbPhonemeTargets], []),\n    wbRStruct('NG', [wbPhonemeTargets], []),\n    wbRStruct('L',  [wbPhonemeTargets], []),\n    wbRStruct('R',  [wbPhonemeTargets], []),\n    wbRStruct('W',  [wbPhonemeTargets], []),\n    wbRStruct('Y',  [wbPhonemeTargets], []),\n    wbRStruct('HH', [wbPhonemeTargets], []),\n    wbRStruct('B',  [wbPhonemeTargets], []),\n    wbRStruct('D',  [wbPhonemeTargets], []),\n    wbRStruct('JH', [wbPhonemeTargets], []),\n    wbRStruct('G',  [wbPhonemeTargets], []),\n    wbRStruct('P',  [wbPhonemeTargets], []),\n    wbRStruct('T',  [wbPhonemeTargets], []),\n    wbRStruct('K',  [wbPhonemeTargets], []),\n    wbRStruct('CH', [wbPhonemeTargets], []),\n    wbRStruct('SIL', [wbPhonemeTargets], []),\n    wbRStruct('SHOTSIL', [wbPhonemeTargets], []),\n    wbRStruct('FLAP', [wbPhonemeTargets], [])\n  ], []);\n\n  wbHeadPart := wbRStructSK([0], 'Head Part', [\n    wbInteger(INDX, 'Head Part Number', itU32),\n    wbFormIDCk(HEAD, 'Head', [HDPT, NULL])\n  ], []);\n\n  wbRaceRBPC :=\n    wbArray(RBPC, 'Biped Object Conditions',\n      wbUnion('Slot 30+', wbFormVer78Decider, [\n        wbInteger('Slot 30+', itU32),\n        wbFormIDCk('Slot 30+', [AVIF, NULL])\n      ])\n    );\n    // since version 78: array of pair of AVIF FormID, before array of AVIF index. Similar to DamageType (and MGEF also somehow).\n    {wbUnion(RBPC, 'Biped Object Conditions', wbFormVer78Decider, [\n      wbArray('Biped Object Conditions', wbInteger('Condition AV', itU32)),\n      wbArray('Biped Object Conditions', wbStruct('Condition AV', [\n        wbFormIDck('AVIF 1', [AVIF, NULL]),\n        wbFormIDck('AVIF 2', [AVIF, NULL])\n      ]))\n    ]);}\n\n  wbRecord(RACE, 'Race',\n    wbFlags(wbRecordFlagsFlags, wbFlagsList([\n      {0x00080000} 19, 'Unknown 19'\n    ])), [\n    wbEDID,\n    wbFormIDCk(STCP, 'Sound', [STAG]),\n    wbFULL,\n    wbDESCReq,\n    wbSPCT,\n    wbSPLOs,\n    wbFormIDCk(WNAM, 'Skin', [ARMO, NULL]),\n    wbBOD2,\n    wbKSIZ,\n    wbKWDAs,\n    wbPRPS,\n    wbAPPR,\n    wbStruct(DATA, 'Data', [\n      wbFloat('Male Height'),\n      wbFloat('Female Height'),\n      wbStruct('Male Default Weight', [\n        wbFloat('Thin'),\n        wbFloat('Muscular'),\n        wbFloat('Fat')\n      ]),\n      wbStruct('Female Default Weight', [\n        wbFloat('Thin'),\n        wbFloat('Muscular'),\n        wbFloat('Fat')\n      ]),\n      wbInteger('Flags', itU32, wbFlags([\n        {0x00000001} 'Playable',\n        {0x00000002} 'FaceGen Head',\n        {0x00000004} 'Child',\n        {0x00000008} 'Tilt Front/Back',\n        {0x00000010} 'Tilt Left/Right',\n        {0x00000020} 'No Shadow',\n        {0x00000040} 'Swims',\n        {0x00000080} 'Flies',\n        {0x00000100} 'Walks',\n        {0x00000200} 'Immobile',\n        {0x00000400} 'Not Pushable',\n        {0x00000800} 'No Combat In Water',\n        {0x00001000} 'No Rotating to Head-Track',\n        {0x00002000} 'Don''t Show Blood Spray',\n        {0x00004000} 'Don''t Show Blood Decal',\n        {0x00008000} 'Uses Head Track Anims',\n        {0x00010000} 'Spells Align w/Magic Node',\n        {0x00020000} 'Use World Raycasts For FootIK',\n        {0x00040000} 'Allow Ragdoll Collision',\n        {0x00080000} 'Regen HP In Combat',\n        {0x00100000} 'Can''t Open Doors',\n        {0x00200000} 'Allow PC Dialogue',\n        {0x00400000} 'No Knockdowns',\n        {0x00800000} 'Allow Pickpocket',\n        {0x01000000} 'Always Use Proxy Controller',\n        {0x02000000} 'Don''t Show Weapon Blood',\n        {0x04000000} 'Overlay Head Part List', {>>>Only one can be active<<<}\n        {0x08000000} 'Override Head Part List', {>>>Only one can be active<<<}\n        {0x10000000} 'Can Pickup Items',\n        {0x20000000} 'Allow Multiple Membrane Shaders',\n        {0x40000000} 'Can Dual Wield',\n        {0x80000000} 'Avoids Roads'\n      ])),\n      wbFloat('Acceleration Rate'),\n      wbFloat('Deceleration Rate'),\n      wbInteger('Size', itU32, wbEnum([\n        'Small',\n        'Medium',\n        'Large',\n        'Extra Large'\n      ])),\n      wbByteArray('Unknown', 8),\n      wbFloat('Injured Health Pct'),\n      wbInteger('Shield Biped Object', itS32, wbBipedObjectEnum),\n      wbInteger('Beard Biped Object', itS32, wbBipedObjectEnum),\n      wbInteger('Body Biped Object', itS32, wbBipedObjectEnum),\n      wbFloat('Aim Angle Tolerance'),\n      wbFloat('Flight Radius'),\n      wbFloat('Angular Acceleration Rate'),\n      wbFloat('Angular Tolerance'),\n      wbInteger('Flags 2', itU32, wbFlags([\n        {0x00000001} 'Use Advanced Avoidance',\n        {0x00000002} 'Non-Hostile',\n        {0x00000004} 'Floats',\n        {0x00000008} 'Unknown 3',\n        {0x00000010} 'Unknown 4',\n        {0x00000020} 'Head Axis Bit 0',\n        {0x00000040} 'Head Axis Bit 1',\n        {0x00000080} 'Can Melee When Knocked Down',\n        {0x00000100} 'Use Idle Chatter During Combat',\n        {0x00000200} 'Ungendered',\n        {0x00000400} 'Can Move When Knocked Down',\n        {0x00000800} 'Use Large Actor Pathing',\n        {0x00001000} 'Use Subsegmented Damage',\n        {0x00002000} 'Flight - Defer Kill',\n        {0x00004000} 'Unknown 14',\n        {0x00008000} 'Flight - Allow Procedural Crash Land',\n        {0x00010000} 'Disable Weapon Culling',\n        {0x00020000} 'Use Optimal Speeds',\n        {0x00040000} 'Has Facial Rig',\n        {0x00080000} 'Can Use Crippled Limbs',\n        {0x00100000} 'Use Quadruped Controller',\n        {0x00200000} 'Low Priority Pushable',\n        {0x00400000} 'Cannot Use Playable Items'\n      ])),\n      wbByteArray('Unknown', 36),\n      wbInteger('Pipboy Biped Object', itS32, wbBipedObjectEnum),\n      wbInteger('XP Value', itS16),\n      wbFloat('Severable - Debris Scale'),\n      wbInteger('Severable - Debris Count', itU8),\n      wbInteger('Severable - Decal Count', itU8),\n      wbFloat('Explodable - Debris Scale'),\n      wbInteger('Explodable - Debris Count', itU8),\n      wbInteger('Explodable - Decal Count', itU8),\n      wbFormIDCk('Severable - Explosion', [EXPL, NULL]),\n      wbFormIDCk('Severable - Debris', [DEBR, NULL]),\n      wbFormIDCk('Severable - Impact DataSet', [IPDS, NULL]),\n      wbFormIDCk('Explodable - Explosion', [EXPL, NULL]),\n      wbFormIDCk('Explodable - Debris', [DEBR, NULL]),\n      wbFormIDCk('Explodable - Impact DataSet', [IPDS, NULL]),\n      wbFloat('OnCripple - Debris Scale'),\n      wbInteger('OnCripple - Debris Count', itU8),\n      wbInteger('OnCripple - Decal Count', itU8),\n      wbFormIDCk('OnCripple - Explosion', [EXPL, NULL]),\n      wbFormIDCk('OnCripple - Debris', [DEBR, NULL]),\n      wbFormIDCk('OnCripple - Impact DataSet', [IPDS, NULL]),\n      wbFormIDCk('Explodable - Subsegment Explosion', [EXPL, NULL]),\n      wbFloat('Orientation Limits - Pitch'),\n      wbFloat('Orientation Limits - Roll')\n    ], cpNormal, True),\n\n    wbEmpty(MNAM, 'Male Marker'),\n    wbString(ANAM, 'Male Skeletal Model'),\n    wbMODT,\n    wbEmpty(FNAM, 'Female Marker'),\n    wbString(ANAM, 'Female Skeletal Model'),\n    wbMODT,\n    wbEmpty(NAM2, 'Marker NAM2 #1'),\n    wbRArrayS('Movement Type Names', wbString(MTNM, 'Name')),\n    wbArray(VTCK, 'Voices', wbFormIDCk('Voice', [VTYP]), ['Male', 'Female'], cpNormal, True),\n    //wbArray(DNAM, 'Decapitate Armors', wbFormIDCk('Decapitate Armor', [NULL, ARMO]), ['Male', 'Female'], cpNormal, False),\n    wbArray(HCLF, 'Default Hair Colors', wbFormIDCk('Default Hair Color', [NULL, CLFM]), ['Male', 'Female'], cpNormal, False),\n    wbInteger(TINL, 'Total Number of Tints in List', itU16, nil, nil, cpNormal, False), {>>> Needs Count Updated <<<}\n    wbFloat(PNAM, 'FaceGen - Main clamp', cpNormal, True),\n    wbFloat(UNAM, 'FaceGen - Face clamp', cpNormal, True),\n\n    wbFormIDCk(ATKR, 'Attack Race', [RACE], False, cpNormal, False),\n    wbRArrayS('Attacks', wbAttackData),\n\n    wbRStruct('Body Data', [\n      wbEmpty(NAM1, 'Body Data Marker', cpNormal, True),\n      wbRStruct('Male Body Data', [\n        wbEmpty(MNAM, 'Male Data Marker'),\n        wbRArrayS('Parts', wbRStructSK([0], 'Part', [\n          wbInteger(INDX, 'Index', itU32, wbBodyPartIndexEnum),\n          wbMODL\n        ], []), cpNormal, True)\n      ], [], cpNormal, True),\n      wbRStruct('Female Body Data', [\n        wbEmpty(FNAM, 'Female Data Marker', cpNormal, True),\n        wbRArrayS('Parts', wbRStructSK([0], 'Part', [\n          wbInteger(INDX, 'Index', itU32, wbBodyPartIndexEnum),\n          wbMODL\n        ], []), cpNormal, True)\n      ], [], cpNormal, True)\n    ], [], cpNormal, True),\n    wbFormIDCk(GNAM, 'Body Part Data', [BPTD]),\n\n\t  wbEmpty(NAM2, 'Marker NAM2 #2', cpNormal),\n\t  wbEmpty(NAM3, 'Marker NAM3 #3', cpNormal, True),\n    wbRStruct('Male Behavior Graph', [\n      wbEmpty(MNAM, 'Male Data Marker'),\n      wbMODL\n    ], [], cpNormal, True),\n    wbRStruct('Female Behavior Graph', [\n      wbEmpty(FNAM, 'Female Data Marker', cpNormal, True),\n      wbMODL\n    ], [], cpNormal, True),\n\n    wbFormIDCk(NAM4, 'Impact Material Type', [MATT]),\n    wbFormIDCk(NAM5, 'Impact Data Set', [IPDS]),\n\t\twbFormIDCk(NAM7, 'Dismember Blood Art', [ARTO]),\n\t\twbFormIDCk(CNAM, 'Meat Cap TextureSet', [TXST]),\n\t\twbFormIDCk(NAM2, 'Collar TextureSet', [TXST]),\n    wbFormIDCk(ONAM, 'Sound - Open Corpse', [SNDR]),\n    wbFormIDCk(LNAM, 'Sound - Close Corpse', [SNDR]),\n    wbRArray('Biped Object Names', wbString(NAME, 'Name')),\n    wbRaceRBPC,\n    wbRArrayS('Movement Data Overrides', wbRStructSK([0], 'Override', [\n      wbFormIDCk(MTYP, 'Movement Type', [MOVT]),\n      wbSPED\n    ], [])),\n    wbInteger(VNAM, 'Equipment Flags', itU32, wbEquipType),\n    wbRArray('Equip Slots',\n      wbRStruct('Equip Slot', [\n        wbFormIDCk(QNAM, 'Equip Slot', [EQUP]),\n        wbString(ZNAM, 'Node')\n      ], [])\n    ),\n    wbFormIDCk(UNWP, 'Unarmed Weapon', [WEAP]),\n\n    wbRArray('Phoneme Target Names', wbString(PHTN, 'Name')),\n    wbPHWT,\n\n    wbFormIDCk(WKMV, 'Base Movement Defaults - Default', [MOVT]),\n    wbFormIDCk(SWMV, 'Base Movement Defaults - Swim', [MOVT]),\n    wbFormIDCk(FLMV, 'Base Movement Defaults - Fly', [MOVT]),\n    wbFormIDCk(SNMV, 'Base Movement Defaults - Sneak', [MOVT]),\n\n    // Male head\n    wbEmpty(NAM0, 'Head Data Marker'),\n    wbEmpty(MNAM, 'Male Data Marker'),\n    wbStruct(NNAM, 'Male Neck Fat Adjustments Scale', [\n      wbByteArray('Unknown', 4),\n      wbFloat('X'),\n      wbFloat('Y')\n    ]),\n    wbRArrayS('Male Head Parts', wbHeadPart),\n    wbRArray('Male Race Presets', wbFormIDCk(RPRM, 'Preset NPC', [NPC_, NULL])),\n    wbRArray('Male Hair Colors', wbFormIDCk(AHCM, 'Hair Color', [CLFM, NULL])),\n    wbRArrayS('Male Face Details', wbFormIDCk(FTSM, 'Texture Set', [TXST, NULL])),\n    wbFormIDCk(DFTM, 'Male Default Face Texture', [TXST]),\n    wbTintTemplateGroups('Male Tint Layers'),\n    wbMorphGroups('Male Morph Groups'),\n    wbFaceMorphs('Male Face Morphs'),\n    wbString(WMAP, 'Male Wrinkle Map Path'),\n\n    // Female head\n    wbEmpty(NAM0, 'Head Data Marker'),\n    wbEmpty(FNAM, 'Female Data Marker'),\n    wbStruct(NNAM, 'Female Neck Fat Adjustments Scale', [\n      wbByteArray('Unknown', 4),\n      wbFloat('X'),\n      wbFloat('Y')\n    ]),\n    wbRArrayS('Female Head Parts', wbHeadPart),\n    wbRArray('Female Race Presets', wbFormIDCk(RPRF, 'Preset NPC', [NPC_, NULL])),\n    wbRArray('Female Hair Colors', wbFormIDCk(AHCF, 'Hair Color', [CLFM, NULL])),\n    wbRArrayS('Female Face Details', wbFormIDCk(FTSF, 'Texture Set', [TXST, NULL])),\n    wbFormIDCk(DFTF, 'Female Default Face Texture', [TXST]),\n    wbTintTemplateGroups('Female Tint Layers'),\n    wbMorphGroups('Female Morph Groups'),\n    wbFaceMorphs('Female Face Morphs'),\n    wbString(WMAP, 'Female Wrinkle Map Path'),\n\n\t\twbFormIDCk(NAM8, 'Morph Race', [RACE]),\n    wbFormIDCk(RNAM, 'Armor Race', [RACE]),\n    wbFormIDCk(SRAC, 'Subgraph Template Race', [RACE]),\n    wbFormIDCk(SADD, 'Subgraph Additive Race', [RACE]),\n    wbRArray('Subgraph Data',\n      wbRStruct('Data', [\n        wbString(SGNM, 'Behaviour Graph'),\n        wbRArray('Actor Keywords', wbFormIDCk(SAKD, 'Keyword', [KYWD])),\n        wbRArray('Target Keywords', wbFormIDCk(STKD, 'Keyword', [KYWD])),\n        wbRArray('Animation Paths', wbString(SAPT, 'Path'), cpNormal, True),\n        // Values greater than $10000 sets a bool. Reading this \"closes\" the current record.\n        wbStruct(SRAF, 'Flags', [\n          wbInteger('Role', itU16, wbEnum([\n            {0} 'MT',\n            {1} 'Weapon',\n            {2} 'Furniture',\n            {3} 'Idle',\n            {4} 'Pipboy'\n          ])),\n          wbInteger('Perspective', itU16, wbEnum([\n            '3rd',\n            '1st'\n          ]))\n        ], cpNormal, True)\n      ], [], cpNormal, False, nil, True)\n    ),\n    wbFloat(PTOP, 'Idle Chatter Time Min'),\n    wbFloat(NTOP, 'Idle Chatter Time Max'),\n    wbRArray('Morph Values',\n      wbRStruct('Value', [\n        wbInteger(MSID, 'Index', itU32, wbIntToHexStr, wbHexStrToInt),\n        wbString(MSM0, 'Min Name'),\n        wbString(MSM1, 'Max Name')\n      ], [])\n    ),\n    wbUnknown(MLSI),\n    wbString(HNAM, 'Hair Color Lookup Texture'),\n    wbString(HLTX, 'Hair Color Extended Lookup Texture'),\n    wbFormIDCk(QSTI, 'Dialogue Quest', [QUST]),\n    wbBSMPSequence\n  ], False, nil, cpNormal, False, nil, wbRACEAfterSet);\n\n\n  wbRecord(REFR, 'Placed Object', wbFormaterUnion(wbREFRRecordFlagsDecider, [\n    wbFlags(wbRecordFlagsFlags, wbFlagsList([\n      {0x00000010}  4, 'Ground Piece',\n      {0x00000100}  8, 'LOD Respects Enable State',\n      {0x00000400} 10, 'Persistent',\n      {0x00000800} 11, 'Initially Disabled',\n      {0x00010000} 16, 'Is Full LOD',\n      {0x04000000} 26, 'Filter (Collision Geometry)',\n      {0x08000000} 27, 'Bounding Box (Collision Geometry)',\n      {0x10000000} 28, 'Reflected By Auto Water',\n      {0x40000000} 30, 'Ground',\n      {0x80000000} 31, 'Multibound'\n    ], True, True)),\n    {ACTI STAT SCOL TREE} wbFlags(wbRecordFlagsFlags, wbFlagsList([\n      {0x00000010}  4, 'Ground Piece',\n      {0x00000100}  8, 'LOD Respects Enable State',\n      {0x00000200}  9, 'Hidden From Local Map',\n      {0x00000400} 10, 'Persistent',\n      {0x00000800} 11, 'Initially Disabled',\n      {0x00008000} 15, 'Visible when distant',\n      {0x00010000} 16, 'Is Full LOD',\n      {0x04000000} 26, 'Filter (Collision Geometry)',\n      {0x08000000} 27, 'Bounding Box (Collision Geometry)',\n      {0x10000000} 28, 'Reflected By Auto Water',\n      {0x20000000} 29, 'Don''t Havok Settle',\n      {0x40000000} 30, 'No Respawn',\n      {0x80000000} 31, 'Multibound'\n    ], True, True)),\n    {CONT TERM} wbFlags(wbRecordFlagsFlags, wbFlagsList([\n      {0x00000010}  4, 'Ground Piece',\n      {0x00000400} 10, 'Persistent',\n      {0x00000800} 11, 'Initially Disabled',\n      {0x00010000} 16, 'Is Full LOD',\n      {0x02000000} 25, 'No AI Acquire',\n      {0x04000000} 26, 'Filter (Collision Geometry)',\n      {0x08000000} 27, 'Bounding Box (Collision Geometry)',\n      {0x20000000} 29, 'Don''t Havok Settle',\n      {0x40000000} 30, 'Ground',\n      {0x80000000} 31, 'Multibound'\n    ], True, True)),\n    {DOOR} wbFlags(wbRecordFlagsFlags, wbFlagsList([\n      {0x00000004}  2, 'Minimal Use Door',\n      {0x00000040}  6, 'Hidden From Local Map',\n      {0x00000100}  8, 'Inaccessible',\n      {0x00000400} 10, 'Persistent',\n      {0x00000800} 11, 'Initially Disabled',\n      {0x00010000} 16, 'Is Full LOD',\n      {0x04000000} 26, 'Filter (Collision Geometry)',\n      {0x08000000} 27, 'Bounding Box (Collision Geometry)',\n      {0x20000000} 29, 'Don''t Havok Settle',\n      {0x40000000} 30, 'No Respawn',\n      {0x80000000} 31, 'Multibound'\n    ], True, True)),\n    {LIGH} wbFlags(wbRecordFlagsFlags, wbFlagsList([\n      {0x00000100}  8, 'Doesn''t Light Water',\n      {0x00000200}  9, 'Casts Shadows',\n      {0x00000400} 10, 'Persistent',\n      {0x00000800} 11, 'Initially Disabled',\n      {0x00010000} 16, 'Never Fades',\n      {0x00020000} 17, 'Doesn''t Light Landscape',\n      {0x02000000} 25, 'No AI Acquire',\n      {0x10000000} 28, 'Reflected By Auto Water',\n      {0x20000000} 29, 'Don''t Havok Settle',\n      {0x40000000} 30, 'No Respawn',\n      {0x80000000} 31, 'Multibound'\n    ], True, True)),\n    {MSTT} wbFlags(wbRecordFlagsFlags, wbFlagsList([\n      {0x00000010}  4, 'Ground Piece',\n      {0x00000200}  9, 'Motion Blur',\n      {0x00000400} 10, 'Persistent',\n      {0x00000800} 11, 'Initially Disabled',\n      {0x00010000} 16, 'Is Full LOD',\n      {0x04000000} 26, 'Filter (Collision Geometry)',\n      {0x08000000} 27, 'Bounding Box (Collision Geometry)',\n      {0x10000000} 28, 'Reflected By Auto Water',\n      {0x20000000} 29, 'Don''t Havok Settle',\n      {0x40000000} 30, 'No Respawn',\n      {0x80000000} 31, 'Multibound'\n    ], True, True)),\n    {ADDN} wbFlags(wbRecordFlagsFlags, wbFlagsList([\n      {0x00000400} 10, 'Persistent',\n      {0x00000800} 11, 'Initially Disabled',\n      {0x00010000} 16, 'Is Full LOD',\n      {0x10000000} 28, 'Reflected By Auto Water',\n      {0x20000000} 29, 'Don''t Havok Settle',\n      {0x40000000} 30, 'No Respawn',\n      {0x80000000} 31, 'Multibound'\n    ], True, True)),\n    {ALCH BOOK SCRL AMMO ARMO INGR KEYM MISC FURN WEAP}\n    wbFlags(wbRecordFlagsFlags, wbFlagsList([\n      {0x00000010}  4, 'Ground Piece',\n      {0x00000400} 10, 'Persistent',\n      {0x00000800} 11, 'Initially Disabled',\n      {0x00010000} 16, 'Is Full LOD',\n      {0x02000000} 25, 'No AI Acquire',\n      {0x10000000} 28, 'Reflected By Auto Water',\n      {0x20000000} 29, 'Don''t Havok Settle',\n      {0x40000000} 30, 'No Respawn',\n      {0x80000000} 31, 'Multibound'\n    ], True, True))\n  ]), [\n    wbEDID,\n    wbVMAD,\n    wbFormIDCk(NAME, 'Base', sigBaseObjects, False, cpNormal, True),\n\n    {--- Bound Contents ---}\n    {--- Bound Data ---}\n    wbStruct(XMBO, 'Bound Half Extents', [\n      wbFloat('X'),\n      wbFloat('Y'),\n      wbFloat('Z')\n    ]),\n\n    {--- Primitive ---}\n    wbStruct(XPRM, 'Primitive', [\n      wbStruct('Bounds', [\n        wbFloat('X', cpNormal, True, 2, 4),\n        wbFloat('Y', cpNormal, True, 2, 4),\n        wbFloat('Z', cpNormal, True, 2, 4)\n      ]),\n      wbFloatColors('Color'),\n      wbFloat('Unknown'),\n      wbInteger('Type', itU32, wbEnum([\n        'None',\n        'Box',\n        'Sphere',\n        'Plane',\n        'Line',\n        'Ellipsoid'\n      ]))\n    ]),\n\n    wbArray(XPOD, 'Portal Data', wbStruct('References', [\n      wbFormIDCk('Origin', [REFR, NULL]),\n      wbFormIDCk('Destination', [REFR, NULL])\n    ])),\n\n    wbUnknown(XORD),\n\n    wbStruct(XOCP, 'Occlusion Plane Data', [\n      wbStruct('Size', [\n        wbFloat('Width', cpNormal, False, 2),\n        wbFloat('Height', cpNormal, False, 2)\n      ]),\n      wbStruct('Position', [\n        wbFloat('X'),\n        wbFloat('Y'),\n        wbFloat('Z')\n      ]),\n      wbStruct('Rotation (Quaternion?)', [\n        wbFloat('q1'),\n        wbFloat('q2'),\n        wbFloat('q3'),\n        wbFloat('q4')\n      ])\n    ]),\n\n    wbRStruct('Bound Data', [\n      wbStruct(XRMR, 'Header', [\n        wbInteger('Linked Rooms Count', itU8),\n        wbInteger('Flags', itU8, wbFlags([\n          'Unknown 1',\n          'Unknown 2',\n          'Unknown 3',\n          'Unknown 4',\n          'Unknown 5',\n          'Unknown 6',\n          'Has Image Space',\n          'Has Lighting Template'\n        ])),\n        wbByteArray('Unknown', 2)\n      ]),\n      wbFormIDCk(LNAM, 'Lighting Template', [LGTM]),\n      wbFormIDCk(INAM, 'Image Space', [IMGS]),\n      wbRArrayS('Linked Rooms',\n        wbFormIDCk(XLRM, 'Linked Room', [REFR])\n      )\n    ], []),\n    wbEmpty(XMBP, 'MultiBound Primitive Marker', cpIgnore),\n\n    {--- Ragdoll ---}\n    wbXRGD,\n    wbXRGB,\n\n    wbFloat(XRDS, 'Radius'),\n    wbXSCL,\n\n    {--- Emittance ---}\n    wbFormIDCk(XEMI, 'Emittance', [LIGH, REGN]),\n\t\twbStruct(XLIG, 'Light Data', [\n      wbFloat('FOV 90+/-'),\n      wbFloat('Fade 1.0+/-'),\n      wbFloat('End Distance Cap'),\n      wbFloat('Shadow Depth Bias'),\n      wbFloat('Near Clip'),\n      wbFloat('Volumetric Intensity')\n    ], cpNormal, False, nil, 4),\n\t\twbStruct(XALP, 'Alpha', [\n      wbInteger('Cutoff', itU8),\n      wbInteger('Base', itU8)\n    ]),\n\n    {--- Teleport ---}\n    wbStruct(XTEL, 'Teleport Destination', [\n      wbFormIDCk('Door', [REFR], True),\n      wbPosRot,\n      wbInteger('Flags', itU32, wbFlags([\n        'No Alarm',\n        'No Load Screen',\n        'Relative Position'\n      ])),\n      wbFormIDCk('Transition Interior', [CELL, NULL])\n    ]),\n    wbFormIDCk(XTNM, 'Teleport Loc Name', [MESG]),\n\n    {--- MultiBound ---}\n    wbFormIDCk(XMBR, 'MultiBound Reference', [REFR]),\n\n    {--- Placed Water ---}\n    wbUnknown(XWCN),\n    wbStruct(XWCU, 'Water Velocity', [\n      wbFloat('X Offset'),\n      wbFloat('Y Offset'),\n      wbFloat('Z Offset'),\n      wbByteArray('Unknown', 4),\n      wbFloat('X Angle'),\n      wbFloat('Y Angle'),\n      wbFloat('Z Angle'),\n      wbByteArray('Unknown', 0)\n    ]),\n\n    wbFormIDCk(XASP, 'Acoustic Restriction', [REFR]),\n    wbEmpty(XATP, 'Activation Point'),\n    wbInteger(XAMC, 'Ammo Count', itU32),\n    wbEmpty(XLKT, 'Linked Ref Transient'),\n    wbFormIDCk(XLYR, 'Layer', [LAYR]),\n    wbFormIDCk(XMSP, 'Material Swap', [MSWP]),\n    wbFormIDCk(XRFG, 'Reference Group', [RFGP]),\n    wbStruct(XRDO, 'Radio', [\n      wbFloat('Frequency'),\n      wbFloat('Min Weak Distance'),\n      wbFloat('Max Weak Distance'),\n      wbInteger('Flags', itU32, wbFlags(['Ignores Distance Checks']))\n    ]),\n    wbStruct(XBSD, 'Spline', [\n      wbFloat('Slack'),\n      wbFloat('Thickness'),\n      wbFloat('Unknown'), // not shown in editor\n      wbFloat('Unknown'), // not shown in editor\n      wbFloat('Unknown'), // not shown in editor\n      wbInteger('Wind - Detached End', itU8, wbBoolEnum),\n      wbByteArray('Unused', 0) // junk data?\n    ], cpNormal, False, nil, 5),\n    wbStruct(XPDD, 'Projected Decal', [\n      wbFloat('Width Scale'),\n      wbFloat('Height Scale')\n      // \"Uses Box Primitive\" checkbox does the following:\n      // 1. \"Rounds\" above floats (probably due to floating point precision)  [DIRTY EDITS?]\n      // 2. \"Rounds\" DATA\\Position floats (probably due to floating point precision)  [DIRTY EDITS?]\n      // 3. Creates an XPRM subrecord (this is the \"Primitive\" tab in the editor)\n      // 4. Fills out Primitive data:\n      //    4a. Primitive type: Box\n      //    4b. Collision layer: XTRI subrecord = 15\n      //    4c. Bounds (XYZ): 256.0, 215.0, 256.0\n      //    4d. Color (RGB): 0, 128, 128\n      //    4e. Unknown: 0.4\n    ]),\n    wbFormIDCk(XSPC, 'Spawn Container', [REFR]),\n\n    {--- Activate Parents ---}\n    wbRStruct('Activate Parents', [\n      wbInteger(XAPD, 'Flags', itU8, wbFlags([\n        'Parent Activate Only'\n      ], True)),\n      wbRArrayS('Activate Parent Refs',\n        wbStructSK(XAPR, [0], 'Activate Parent Ref', [\n          wbFormIDCk('Reference', sigReferences),\n          wbFloat('Delay')\n        ])\n      )\n    ], []),\n\n    wbFormIDCk(XLIB, 'Leveled Item Base Object', [LVLI]),\n    wbXLCM,\n    wbFormIDCk(XLCN, 'Persistent Location', [LCTN]),\n\n    {>>> COLL form Index value <<<}\n    wbInteger(XTRI, 'Collision Layer', itU32),\n\n    {--- Lock ---}\n    wbStruct(XLOC, 'Lock Data', [\n      wbInteger('Level', itU8, wbEnum([], [\n         0, 'None',\n         1, 'Novice 1',\n        25, 'Novice 25',\n        50, 'Advanced',\n        75, 'Expert',\n       100, 'Master',\n       253, 'Requires Terminal',\n       251, 'Barred',\n       252, 'Chained',\n       254, 'Inaccessible',\n       255, 'Requires Key'\n      ])),\n      wbByteArray('Unused', 3, cpIgnore),\n      wbFormIDCkNoReach('Key', [KEYM, NULL]),\n      wbInteger('Flags', itU8, wbFlags(['', '', 'Leveled Lock'])),\n      wbByteArray('Unused', 3, cpIgnore),\n      wbUnknown\n    ], cpNormal, False, nil, 4),\n\n    wbFormIDCk(XEZN, 'Encounter Zone', [ECZN]),\n\n    {--- Generated Data ---}\n    wbStruct(XNDP, 'Navigation Door Link', [\n      wbFormIDCk('Navigation Mesh', [NAVM]),\n      wbInteger('Teleport Marker Triangle', itS16, wbREFRNavmeshTriangleToStr, wbStringToInt),\n      wbByteArray('Unused', 2, cpIgnore)\n    ]),\n\n    wbFormIDCk(XLRL, 'Location Reference', [LCRT, LCTN, NULL], False, cpBenignIfAdded),\n    wbArray(XLRT, 'Location Ref Type', wbFormIDCk('Ref', [LCRT, NULL])),\n    wbEmpty(XIS2, 'Ignored by Sandbox'),\n\n    {--- Ownership ---}\n    wbXOWN,\n    wbXRNK,\n\n    wbInteger(XCNT, 'Item Count', itS32),\n    wbInteger(XHLT, 'Health %', itU32),\n\n    wbXESP,\n    wbRArray('Linked References', wbStruct(XLKR, 'Linked Reference', [\n      wbFormIDCk('Keyword/Ref', [KYWD, PLYR, ACHR, REFR, PGRE, PHZD, PMIS, PARW, PBAR, PBEA, PCON, PFLA, NULL]),\n      wbFormIDCk('Ref', sigReferences)\n    ], cpNormal, False, nil, 1)),\n\n    wbRArray('Patrol', wbRStruct('Data', [\n      wbFloat(XPRD, 'Idle Time', cpNormal, True),\n      wbEmpty(XPPA, 'Patrol Script Marker', cpNormal, True),\n      wbFormIDCk(INAM, 'Idle', [IDLE, NULL], False, cpNormal, True),\n      wbPDTOs\n    ], [])),\n\n    {--- Flags ---}\n    wbInteger(XACT, 'Action Flag', itU32, wbFlags([\n      'Use Default',\n      'Activate',\n      'Open',\n      'Open by Default'\n    ])),\n\n    wbFloat(XHTW, 'Head-Tracking Weight'),\n    wbFloat(XFVC, 'Favor Cost'),\n\n    wbEmpty(ONAM, 'Open by Default'),\n\n    {--- Map Data ---}\n    wbRStruct('Map Marker', [\n      wbEmpty(XMRK, 'Map Marker Data'),\n      wbInteger(FNAM, 'Map Flags', itU8, wbFlags([\n        {0x01} 'Visible',\n        {0x02} 'Can Travel To',\n        {0x04} '\"Show All\" Hidden',\n        {0x08} 'Use Location Name'\n      ]), cpNormal, True),\n      wbFULLReq,\n      wbStruct(TNAM, '', [\n        wbInteger('Type', itU8, wbEnum([], [\n          {Vv = Verified Vanilla}\n          {No new map markers for Automatron or Workshop}\n          0, 'Cave', {Vv}\n          1, 'City', {Vv}\n          2, 'Diamond City', {Vv}\n          3, 'Encampment', {Vv}\n          4, 'Factory / Industrial Site', {Vv}\n          5, 'Gov''t Building / Monument', {Vv}\n          6, 'Metro Station', {Vv}\n          7, 'Military Base', {Vv}\n          8, 'Natural Landmark', {Vv}\n          9, 'Office / Civic Building', {Vv}\n          10, 'Ruins - Town', {Vv}\n          11, 'Ruins - Urban', {Vv}\n          12, 'Sanctuary', {Vv}\n          13, 'Settlement', {Vv}\n          14, 'Sewer / Utility Tunnels', {Vv}\n          15, 'Vault', {Vv}\n          16, 'Airfield', {Vv}\n          17, 'Bunker Hill', {Vv}\n          18, 'Camper', {Vv}\n          19, 'Car', {Vv}\n          20, 'Church', {Vv}\n          21, 'Country Club', {Vv}\n          22, 'Custom House', {Vv}\n          23, 'Drive-In', {Vv}\n          24, 'Elevated Highway', {Vv}\n          25, 'Faneuil Hall', {Vv}\n          26, 'Farm', {Vv}\n          27, 'Filling Station', {Vv}\n          28, 'Forested', {Vv}\n          29, 'Goodneighbor', {Vv}\n          30, 'Graveyard', {Vv}\n          31, 'Hospital', {Vv}\n          32, 'Industrial Dome', {Vv}\n          33, 'Industrial Stacks', {Vv}\n          34, 'Institute', {Vv}\n          35, 'Irish Pride', {Vv}\n          36, 'Junkyard', {Vv}\n          37, 'Observatory', {Vv}\n          38, 'Pier', {Vv}\n          39, 'Pond / Lake', {Vv}\n          40, 'Quarry', {Vv}\n          41, 'Radioactive Area', {Vv}\n          42, 'Radio Tower', {Vv}\n          43, 'Salem', {Vv}\n          44, 'School', {Vv}\n          45, 'Shipwreck', {Vv}\n          46, 'Submarine', {Vv}\n          47, 'Swan Pond', {Vv}\n          48, 'Synth Head', {Vv}\n          49, 'Town', {Vv}\n          50, 'Brotherhood of Steel', {Vv}\n          51, 'Brownstone Townhouse', {Vv}\n          52, 'Bunker', {Vv}\n          53, 'Castle', {Vv}\n          54, 'Skyscraper', {Vv}\n          55, 'Libertalia', {Vv}\n          56, 'Low-Rise Building', {Vv}\n          57, 'Minutemen', {Vv}\n          58, 'Police Station', {Vv}\n          59, 'Prydwen', {Vv}\n          60, 'Railroad - Faction', {Vv}\n          61, 'Railroad', {Vv}\n          62, 'Satellite', {Vv}\n          63, 'Sentinel', {Vv}\n          64, 'USS Constitution', {Vv}\n          65, 'Mechanist LairRaider settlementVassal settlementPotential Vassal settlement', {Vv}\n          66, 'Custom 66',\n          67, 'Custom 67',\n          68, 'Custom 68',\n          69, 'Custom 69',\n          70, 'Custom 70',\n          71, 'Custom 71',\n          72, 'Custom 72',\n          73, 'Custom 73',\n          74, 'Custom 74',\n          75, 'Custom 75',\n          76, 'Custom 76',\n          77, 'Custom 77',\n          78, 'Custom 78',\n          79, 'Custom 79',\n          80, 'Custom 80',\n          81, 'Custom 81',\n          82, 'Custom 82',\n          83, 'Custom 83',\n          84, 'Custom 84',\n          85, 'Custom 85',\n          86, 'Custom 86',\n          87, 'Custom 87',\n          88, 'Custom 88',\n          89, 'Custom 89',\n          90, 'Custom 90',\n          91, 'Custom 91',\n          92, 'Custom 92',\n          93, 'Custom 93',\n          94, 'Custom 94',\n          95, 'Custom 95',\n          96, 'Custom 96',\n          97, 'Custom 97',\n          98, 'Custom 98',\n          99, 'Custom 99'\n        ])),\n        wbByteArray('Unused', 1)\n      ], cpNormal, True)\n    ], []),\n\n    {--- Attach reference ---}\n    wbFormIDCk(XATR, 'Attach Ref', [REFR, PGRE, PHZD, PMIS, PARW, PBAR, PBEA, PCON, PFLA]),\n\n    wbRArray('Spline Connection', wbStruct(XPLK, 'Link', [\n      wbFormIDCk('Ref', [REFR, ACHR]),\n      wbUnknown  // always 00 00 00 00 so far in DLCWorkshop03.esm\n    ])),\n\n    wbRStruct('Power Grid', [\n      wbInteger(XWPG, 'Count', itU32),\n      wbRArray('Connections', wbStruct(XWPN, 'Connection', [\n        wbFormIDCk('Node 1', [REFR, ACHR, NULL]),\n        wbFormIDCk('Node 2', [REFR, ACHR, NULL]),\n        wbFormIDCk('Line', [REFR, NULL]) // BNDS ref\n      ]))\n    ], []),\n\n    wbUnknown(XCVR),\n    wbUnknown(XCVL),\n    wbFormIDCk(XCZR, 'Unknown', sigReferences),\n    wbUnknown(XCZA),\n    wbFormIDCk(XCZC, 'Unknown', [CELL, NULL]),\n\n    wbXLOD, // not seen in FO4 vanilla files\n\n    wbDataPosRot,\n    wbString(MNAM, 'Comments')\n  ], True, wbPlacedAddInfo, cpNormal, False, wbREFRAfterLoad);\n\n  wbRecord(REGN, 'Region',\n    wbFlags(wbRecordFlagsFlags, wbFlagsList([\n      {0x00000040} 6, 'Border Region'\n    ])), [\n    wbEDID,\n    wbStruct(RCLR, 'Map Color', [\n      wbInteger('Red', itU8),\n      wbInteger('Green', itU8),\n      wbInteger('Blue', itU8),\n      wbByteArray('Unknown', 1)\n    ], cpNormal, True),\n    wbFormIDCkNoReach(WNAM, 'Worldspace', [WRLD]),\n    wbRArray('Region Areas', wbRStruct('Region Area', [\n      wbInteger(RPLI, 'Edge Fall-off', itU32),\n      wbArray(RPLD, 'Region Point List Data', wbStruct('Point', [\n        wbFloat('X'),\n        wbFloat('Y')\n      ]), 0, wbRPLDAfterLoad),\n      wbUnknown(ANAM)\n    ], [])),\n    wbRArrayS('Region Data Entries', wbRStructSK([0], 'Region Data Entry', [\n      {always starts with an RDAT}\n      wbStructSK(RDAT, [0], 'Data Header', [\n        wbInteger('Type', itU32, wbEnum([\n          {0} 'Unknown 0',\n          {1} 'Unknown 1',\n          {2} 'Objects',\n          {3} 'Weather',\n          {4} 'Map',\n          {5} 'Land',\n          {6} 'Grass',\n          {7} 'Sound',\n          {8} 'Imposter',\n          {9} 'Unknown 10',\n          {10}'Unknown 11',\n          {11}'Unknown 12',\n          {12}'Unknown 13',\n          {13}'Unknown 14',\n          {14}'Unknown 15',\n          {15}'Unknown 16'\n        ])),\n        wbInteger('Flags', itU8, wbFlags([\n          'Override'\n        ])),\n        wbInteger('Priority', itU8),\n        wbByteArray('Unknown')\n      ], cpNormal, True),\n\n      {--- Icon ---}\n      wbICON,\n\n      {--- Sound ---}\n      wbFormIDCk(RDMO, 'Music', [MUSC], False, cpNormal, False, wbREGNSoundDontShow),\n      wbArrayS(RDSA, 'Sounds', wbStructSK([0], 'Sound', [\n        wbFormIDCk('Sound', [SNDR, NULL]),\n        wbInteger('Flags', itU32, wbFlags([\n          {0x00000001} 'Pleasant',\n          {0x00000002} 'Cloudy',\n          {0x00000004} 'Rainy',\n          {0x00000008} 'Snowy'\n        ])),\n        wbFloat('Chance')\n      ]), 0, cpNormal, False, nil, nil, wbREGNSoundDontShow),\n\n\t\t\t{--- Map ---}\n      wbLString(RDMP, 'Map Name', 0, cpTranslate, False, wbREGNMapDontShow),\n\n      {followed by one of these: }\n\n      {--- Objects ---}\n      wbArray(RDOT, 'Objects', wbStruct('Object', [\n        wbFormIDCk('Object', [TREE, FLOR, STAT, LTEX, MSTT]),\n        wbInteger('Parent Index', itU16, wbHideFFFF),\n        wbByteArray('Unknown', 2),\n        wbFloat('Density'),\n        wbInteger('Clustering', itU8),\n        wbInteger('Min Slope', itU8),\n        wbInteger('Max Slope', itU8),\n        wbInteger('Flags', itU8, wbFlags([\n          {0}'Conform to slope',\n          {1}'Paint Vertices',\n          {2}'Size Variance +/-',\n          {3}'X +/-',\n          {4}'Y +/-',\n          {5}'Z +/-',\n          {6}'Tree',\n          {7}'Huge Rock'\n        ])),\n        wbInteger('Radius wrt Parent', itU16),\n        wbInteger('Radius', itU16),\n        wbFloat('Min Height'),\n        wbFloat('Max Height'),\n        wbFloat('Sink'),\n        wbFloat('Sink Variance'),\n        wbFloat('Size Variance'),\n        wbStruct('Angle Variance', [\n          wbInteger('X', itU16),\n          wbInteger('Y', itU16),\n          wbInteger('Z', itU16)\n        ]),\n        wbByteArray('Unknown', 2),\n        wbByteArray('Unknown', 4)\n      ]), 0, nil, nil, cpNormal, False, wbREGNObjectsDontShow),\n\n      {--- Grass ---}\n      wbArrayS(RDGS, 'Grasses', wbStructSK([0], 'Grass', [\n        wbFormIDCk('Grass', [GRAS]),\n        wbByteArray('Unknown',4)\n      ]), 0, cpNormal, False, nil, nil, wbREGNGrassDontShow),\n\n      {--- Weather ---}\n      wbArrayS(RDWT, 'Weather Types', wbStructSK([0], 'Weather Type', [\n        wbFormIDCk('Weather', [WTHR]),\n        wbInteger('Chance', itU32),\n        wbFormIDCk('Global', [GLOB, NULL])\n      ]), 0, cpNormal, False, nil, nil, wbREGNWeatherDontShow),\n\n      wbFloat(RLDM, 'LOD Display Distance Multiplier'),\n      wbFloat(ANAM, 'Occlusion Accuracy Dist')\n\n    ], []))\n  ], True);\n\n  wbRecord(SOUN, 'Sound Marker', [\n    wbEDID,\n    wbOBNDReq,\n    wbFormIDCk(SDSC, 'Sound Descriptor', [SNDR, NULL]),\n    wbStruct(REPT, 'Repeat', [\n      wbFloat('Min Time'),\n      wbFloat('Max Time'),\n      wbInteger('Stackable', itU8, wbBoolEnum)\n    ], cpNormal, False, nil, 2)\n  ]);\n\n  wbSPIT := wbStruct(SPIT, 'Data', [\n    wbInteger('Base Cost', itU32),\n    wbInteger('Flags', itU32, wbFlags([\n      {0x00000001} 'Manual Cost Calc',\n      {0x00000002} 'Unknown 2',\n      {0x00000004} 'Unknown 3',\n      {0x00000008} 'Unknown 4',\n      {0x00000010} 'Unknown 5',\n      {0x00000020} 'Unknown 6',\n      {0x00000040} 'Unknown 7',\n      {0x00000080} 'Unknown 8',\n      {0x00000100} 'Unknown 9',\n      {0x00000200} 'Unknown 10',\n      {0x00000400} 'Unknown 11',\n      {0x00000800} 'Unknown 12',\n      {0x00001000} 'Unknown 13',\n      {0x00002000} 'Unknown 14',\n      {0x00004000} 'Unknown 15',\n      {0x00008000} 'Unknown 16',\n      {0x00010000} 'Unknown 17',\n      {0x00020000} 'PC Start Spell',\n      {0x00040000} 'Instant Cast',\n      {0x00080000} 'Area Effect Ignores LOS',\n      {0x00100000} 'Ignore Resistance',\n      {0x00200000} 'No Absorb/Reflect',\n      {0x00400000} 'Unknown 23',\n      {0x00800000} 'No Dual Cast Modification',\n      {0x01000000} 'Unknown 25',\n      {0x02000000} 'Unknown 26',\n      {0x04000000} 'Unknown 27',\n      {0x08000000} 'Unknown 28',\n      {0x10000000} 'Unknown 29',\n      {0x20000000} 'Unknown 30',\n      {0x40000000} 'Unknown 31',\n      {0x80000000} 'Unknown 32'\n    ])),\n    wbInteger('Type', itU32, wbEnum([\n      {0} 'Spell',\n      {1} 'Disease',\n      {2} 'Power',\n      {3} 'Lesser Power',\n      {4} 'Ability',\n      {5} 'Poison',\n      {6} 'Unknown 6',\n      {7} 'Unknown 7',\n      {8} 'Unknown 8',\n      {9} 'Unknown 9',\n     {10} 'Addiction',\n     {11} 'Voice'\n    ])),\n    wbFloat('Charge Time'),\n    wbInteger('Cast Type', itU32, wbCastEnum),\n    wbInteger('Target Type', itU32, wbTargetEnum),\n    wbFloat('Cast Duration'),\n    wbFloat('Range'),\n    wbFormIDCk('Casting Perk', [NULL, PERK])\n  ], cpNormal, True);\n\n  wbRecord(SPEL, 'Spell', [\n    wbEDID,\n    wbOBNDReq,\n    wbFULL,\n    wbKSIZ,\n    wbKWDAs,\n    wbETYP,\n    wbDESCReq,\n    wbSPIT,\n    wbEffectsReq\n  ], False, nil, cpNormal, False, nil, wbKeywordsAfterSet);\n\n  {wbRecord(SCRL, 'Scroll', [\n    wbEDID\n  ]);}\n\n  wbRecord(STAT, 'Static',\n    wbFlags(wbRecordFlagsFlags, [\n      {0x00000001} { 0} '',\n      {0x00000002} { 1} '',\n      {0x00000004} { 2} 'Heading Marker',\n      {0x00000008} { 3} '',\n      {0x00000010} { 4} 'Non Occluder',\n      {0x00000020} { 5} 'Deleted',\n      {0x00000040} { 6} 'Has Tree LOD', // Used in Fallout 4 ?\n      {0x00000080} { 7} 'Add-On LOD Object',\n      {0x00000100} { 8} '',\n      {0x00000200} { 9} 'Hidden From Local Map',\n      {0x00000400} {10} 'Headtrack Marker',\n      {0x00000800} {11} 'Used as Platform',\n      {0x00001000} {12} '',\n      {0x00002000} {13} 'Pack-In Use Only',\n      {0x00004000} {14} '',\n      {0x00008000} {15} 'Has Distant LOD',\n      {0x00010000} {16} '',\n      {0x00020000} {17} 'Uses HD LOD Texture',\n      {0x00040000} {18} '',\n      {0x00080000} {19} 'Has Currents',\n      {0x00100000} {20} '',\n      {0x00200000} {21} '',\n      {0x00400000} {22} '',\n      {0x00800000} {23} 'Is Marker',\n      {0x01000000} {24} '',\n      {0x02000000} {25} 'Obstacle',\n      {0x04000000} {26} 'NavMesh Generation - Filter',\n      {0x08000000} {27} 'NavMesh Generation - Bounding Box',\n      {0x10000000} {28} 'Show In World Map (Sky Cell Only)',\n      {0x20000000} {29} '',\n      {0x40000000} {30} 'NavMesh Generation - Ground',\n      {0x80000000} {31} ''\n    ]), [\n    wbEDID,\n    wbVMAD,\n    wbOBNDReq,\n    wbPTRN,\n    wbFTYP,\n    wbMODL,\n    wbPRPS,\n    wbFULL,\n    wbStruct(DNAM, 'Direction Material', [\n      wbFloat('Max Angle (30-120)'),\n      wbFormIDCk('Material', [MATO, NULL]),\n      wbFloat('Leaf Amplitude'),\n      wbFloat('Leaf Frequency')\n    ], cpNormal, True, nil, 2),\n    wbNVNM,\n    wbArray(MNAM, 'Distant LOD',\n      wbStruct('LOD', [\n        {>>> Contains null-terminated mesh filename followed by random data up to 260 bytes <<<}\n        wbString(True, 'Mesh', 260)\n        //wbByteArray('Mesh', 260, cpIgnore)\n      ]), [\n        'Level 0',\n        'Level 1',\n        'Level 2',\n        'Level 3'\n      ],\n      cpNormal, False\n    )\n  ], True);  // unordered, NVNM can be before or after MNAM\n\n  wbRecord(TES4, 'Main File Header',\n    wbFlags(wbRecordFlagsFlags, wbFlagsList([\n      {0x00000001}  0, 'ESM',\n      {0x00000080}  7, 'Localized'\n    ], False), True), [\n    wbStruct(HEDR, 'Header', [\n      wbFloat('Version'),\n      wbInteger('Number of Records', itU32),\n      wbInteger('Next Object ID', itU32)\n    ], cpNormal, True),\n    wbByteArray(OFST, 'Unknown', 0, cpIgnore),            // If possible then ignored by the runtime. Neither from the CK\n    wbByteArray(DELE, 'Unknown', 0, cpIgnore),            // If possible then ignored by the runtime. Neither from the CK\n    wbString(CNAM, 'Author', 0, cpTranslate, True),\n    wbString(SNAM, 'Description', 0, cpTranslate),\n    wbRArray('Master Files', wbRStruct('Master File', [\n      wbString(MAST, 'Filename', 0, cpNormal, True),\n      // wbInteger(DATA, 'Filesize', itU64, nil, nil, cpIgnore, True)  // Should be set by CK but usually null\n      wbByteArray(DATA, 'Unknown', 8, cpIgnore, True)\n    ], [ONAM])),\n    wbArray(ONAM, 'Overridden Forms',                     // Valid in CK\n      wbFormIDCk('Form', [ACHR, LAND, NAVM, REFR, PGRE, PHZD, PMIS, PARW, PBAR, PBEA, PCON, PFLA, DLBR, DIAL, INFO, SCEN]),\n      0, nil, nil, cpNormal, False{, wbTES4ONAMDontShow}),\n    wbByteArray(SCRN, 'Screenshot'),                      // If possible then ignored by the runtime. Neither from the CK\n    wbRArray('Transient Types (CK only)', wbStruct(TNAM, 'Transient Type', [\n      wbInteger('FormType', itU32), // seen TESTopic 78 (array of DIAL) and BGSScene 126 (array of SCEN)\n      wbArray('Unknown', wbFormID('Unknown'))\n    ])),          // Ignored by the runtime\n    wbInteger(INTV, 'Unknown', itU32),                    // Ignored by the runtime, 4 bytes loaded in CK\n    wbInteger(INCC, 'Unknown', itU32)                     // Size of some array of 12 bytes elements\n  ], True, nil, cpNormal, True, wbRemoveOFST);\nend;\n\nprocedure DefineFO4o;\nbegin\n\n  wbRecord(TREE, 'Tree',\n    wbFlags(wbRecordFlagsFlags, wbFlagsList([\n      {0x00008000} 15, 'Has Distant LOD'\n    ])), [\n    wbEDID,\n    wbVMAD,\n    wbOBNDReq,\n    wbMODL,\n    wbFormIDCK(PFIG, 'Ingredient', sigBaseObjects),\n    wbFormIDCK(SNAM, 'Harvest Sound', [SNDR, NULL]),\n    wbStruct(PFPC, 'Ingredient Production', [\n      wbInteger('Spring', itU8),\n      wbInteger('Summer', itU8),\n      wbInteger('Fall', itU8),\n      wbInteger('Winter', itU8)\n    ]),\n    wbFULL,\n    wbStruct(CNAM, 'Tree Data', [\n      wbFloat('Trunk Flexibility'),\n      wbFloat('Branch Flexibility'),\n      //wbByteArray('Unknown', 32),\n      wbFloat('Unknown'),\n      wbFloat('Unknown'),\n      wbFloat('Unknown'),\n      wbFloat('Unknown'),\n      wbFloat('Unknown'),\n      wbFloat('Unknown'),\n      wbFloat('Unknown'),\n      wbFloat('Unknown'),\n      wbFloat('Leaf Amplitude'),\n      wbFloat('Leaf Frequency')\n    ], cpNormal, True)\n  ]);\n\n  wbRecord(FLOR, 'Flora', [\n    wbEDID,\n    wbVMAD,\n    wbOBNDReq,\n    wbPTRN,\n    wbFULLReq,\n    wbMODL,\n    wbDEST,\n    wbKSIZ,\n    wbKWDAs,\n    wbPRPS,\n    wbUnknown(PNAM),\n    wbATTX,\n    wbLString(RNAM, 'Activate Text Override', 0, cpTranslate),\n    wbUnknown(FNAM),\n    wbFormIDCk(PFIG, 'Ingredient', sigBaseObjects),\n    wbFormIDCK(SNAM, 'Harvest Sound', [SNDR]),\n    wbStruct(PFPC, 'Ingredient Production', [\n      wbInteger('Spring', itU8),\n      wbInteger('Summer ', itU8),\n      wbInteger('Fall', itU8),\n      wbInteger('Winter', itU8)\n    ], cpNormal, True)\n  ], False, nil, cpNormal, False, nil, wbKeywordsAfterSet);\n\n  wbRecord(WATR, 'Water', [\n    wbEDID,\n    wbFULL,\n    wbInteger(ANAM, 'Opacity (unused)', itU8),\n    wbInteger(FNAM, 'Flags', itU8, wbFlags([\n      {0x01} 'Dangerous',\n      {0x02} 'Unknown 1',\n      {0x04} 'Directional Sound'\n    ]), cpNormal, True),\n    wbFormIDCk(TNAM, 'Material (unused)', [MATT]),\n    wbFormIDCk(SNAM, 'Open Sound', [SNDR, NULL]),\n    wbFormIDCk(XNAM, 'Consume Spell', [SPEL]),\n    wbFormIDCk(YNAM, 'Contact Spell', [SPEL]),\n    wbFormIDCk(INAM, 'Image Space', [IMGS]),\n    wbByteArray(DATA, 'Unused', 0),\n    wbStruct(DNAM, 'Visual Data', [\n      wbStruct('Fog Properties', [\n        wbFloat('Depth Amount'),\n        wbByteColors('Shallow Color'),\n        wbByteColors('Deep Color'),\n        wbFloat('Color Shallow Range'),\n        wbFloat('Color Deep Range'),\n        wbFloat('Shallow Alpha'),\n        wbFloat('Deep Alpha'),\n        wbFloat('Alpha Shallow Range'),\n        wbFloat('Alpha Deep Range'),\n        wbByteColors('Underwater Color'),\n        wbFloat('Underwater Fog Amount'),\n        wbFloat('Underwater Near Fog'),\n        wbFloat('Underwater Far Fog')\n      ]),\n      wbStruct('Physical Properties', [\n        wbFloat('Normal Magnitude'),\n        wbFloat('Shallow Normal Falloff'),\n        wbFloat('Deep Normal Falloff'),\n        wbFloat('Reflectivity Amount'),\n        wbFloat('Fresnel Amount'),\n        wbFloat('Surface Effect Falloff'),\n        wbStruct('Displacement Simulator', [\n          wbFloat('Force'),\n          wbFloat('Velocity'),\n          wbFloat('Falloff'),\n          wbFloat('Dampener'),\n          wbFloat('Starting Size')\n        ]),\n        wbByteColors('Reflection Color')\n      ]),\n      wbStruct('Specular Properties', [\n        wbFloat('Sun Specular Power'),\n        wbFloat('Sun Specular Magnitude'),\n        wbFloat('Sun Sparkle Power'),\n        wbFloat('Sun Sparkle Magnitude'),\n        wbFloat('Interior Specular Radius'),\n        wbFloat('Interior Specular Brightness'),\n        wbFloat('Interior Specular Power')\n      ]),\n      wbStruct('Noise Properties', [\n        wbFloat('Layer 1 - Wind Direction'),\n        wbFloat('Layer 2 - Wind Direction'),\n        wbFloat('Layer 3 - Wind Direction'),\n        wbFloat('Layer 1 - Wind Speed'),\n        wbFloat('Layer 2 - Wind Speed'),\n        wbFloat('Layer 3 - Wind Speed'),\n        wbFloat('Layer 1 - Amplitude Scale'),\n        wbFloat('Layer 2 - Amplitude Scale'),\n        wbFloat('Layer 3 - Amplitude Scale'),\n        wbFloat('Layer 1 - UV Scale'),\n        wbFloat('Layer 2 - UV Scale'),\n        wbFloat('Layer 3 - UV Scale'),\n        wbFloat('Layer 1 - Noise Falloff'),\n        wbFloat('Layer 2 - Noise Falloff'),\n        wbFloat('Layer 3 - Noise Falloff')\n      ]),\n      wbStruct('Silt Properties', [\n        wbFloat('Silt Amount'),\n        wbByteColors('Light Color'),\n        wbByteColors('Dark Color')\n      ]),\n      wbInteger('Screen Space Reflections', itU8, wbBoolEnum)\n    ], cpNormal, True, nil, 4),\n    wbByteArray(GNAM, 'Unused', 0),\n    wbStruct(NAM0, 'Linear Velocity', [\n      wbFloat('X'),\n      wbFloat('Y'),\n      wbFloat('Z')\n    ], cpNormal, False),\n    wbStruct(NAM1, 'Angular Velocity', [\n      wbFloat('X'),\n      wbFloat('Y'),\n      wbFloat('Z')\n    ], cpNormal, False),\n    wbString(NAM2, 'Layer 1 Noise Texture'),\n    wbString(NAM3, 'Layer 2 Noise Texture'),\n    wbString(NAM4, 'Layer 3 Noise Texture')\n  ]);\n\n  wbRecord(WEAP, 'Weapon',\n    wbFlags(wbRecordFlagsFlags, wbFlagsList([\n      {0x00000004}  2, 'Non-Playable',\n      {0x20000000} 30, 'High-Res 1st Person Only'\n    ])), [\n    wbEDID,\n    wbVMAD,\n    wbOBNDReq,\n    wbPTRN,\n    wbFULL,\n    wbMODL,\n    wbICON,\n    wbMICO,\n    wbEITM,\n    wbInteger(EAMT, 'Enchantment Amount', itU16),\n    wbDEST,\n    wbETYP,\n    wbFormIDCk(BIDS, 'Block Bash Impact Data Set', [IPDS, NULL]),\n    wbFormIDCk(BAMT, 'Alternate Block Material', [MATT, NULL]),\n    wbYNAM,\n    wbZNAM,\n    wbKSIZ,\n    wbKWDAs,\n    wbDESC,\n    wbFormIDCk(INRD, 'Instance Naming', [INNR]),\n    wbAPPR,\n    wbObjectTemplate,\n    wbFormIDCk(NNAM, 'Embedded Weapon Mod', [OMOD]),\n    wbRStruct('1st Person Model', [\n      wbString(MOD4, 'Model Filename'),\n      wbByteArray(MO4T, 'Texture Files Hashes', 0, cpIgnore, false, false, wbNeverShow),\n      wbMO4S,\n      wbMO4C,\n      wbMO4F\n    ], []),\n    wbStruct(DNAM, 'Data', [\n      wbFormIDCk('Ammo', [AMMO, NULL]),\n      wbFloat('Speed'),\n      wbFloat('Reload Speed'),\n      wbFloat('Reach'),\n      wbFloat('Min Range'),\n      wbFloat('Max Range'),\n      wbFloat('Attack Delay'),\n      wbByteArray('Unknown', 4),\n      wbFloat('Damage - OutOfRange Mult'),\n      wbInteger('On Hit', itU32, wbHitBehaviourEnum),\n      wbFormIDCk('Skill', [AVIF, NULL]),\n      wbFormIDCk('Resist', [AVIF, NULL]),\n      wbInteger('Flags', itU32, wbFlags([\n        {0x00000001} 'Player Only',\n        {0x00000002} 'NPCs Use Ammo',\n        {0x00000004} 'No Jam After Reload',\n        {0x00000008} 'Charging Reload',\n        {0x00000010} 'Minor Crime',\n        {0x00000020} 'Fixed Range',\n        {0x00000040} 'Not Used In Normal Combat',\n        {0x00000080} 'Unknown 8',\n        {0x00000100} 'Crit Effect - on Death',\n        {0x00000200} 'Charging Attack',\n        {0x00000400} 'Unknown 11',\n        {0x00000800} 'Hold Input To Power',\n        {0x00001000} 'Non Hostile',\n        {0x00002000} 'Bound Weapon',\n        {0x00004000} 'Ignores Normal Weapon Resistance',\n        {0x00008000} 'Automatic',\n        {0x00010000} 'Repeatable Single Fire',\n        {0x00020000} 'Can''t Drop',\n        {0x00040000} 'Hide Backpack',\n        {0x00080000} 'Embedded Weapon',\n        {0x00100000} 'Not Playable',\n        {0x00200000} 'Has Scope',\n        {0x00400000} 'Bolt Action',\n        {0x00800000} 'Secondary Weapon',\n        {0x01000000} 'Disable Shells',\n        {0x02000000} 'Unknown 26',\n        {0x04000000} 'Unknown 27',\n        {0x08000000} 'Unknown 28',\n        {0x10000000} 'Unknown 29',\n        {0x20000000} 'Unknown 30',\n        {0x40000000} 'Unknown 31',\n        {0x80000000} 'Unknown 32'\n      ])),\n      wbInteger('Capacity', itU16),\n      wbInteger('Animation Type', itU8, wbEnum([\n        'HandToHandMelee',\n        'OneHandSword',\n        'OneHandDagger',\n        'OneHandAxe',\n        'OneHandMace',\n        'TwoHandSword',\n        'TwoHandAxe',\n        'Bow',\n        'Staff',\n        'Gun',\n        'Grenade',\n        'Mine'\n      ])),\n      wbFloat('Damage - Secondary'),\n      wbFloat('Weight'),\n      wbInteger('Value', itU32),\n      wbInteger('Damage - Base', itU16),\n      wbInteger('Sound Level', itU32, wbSoundLevelEnum),\n      wbFormIDCk('Sound - Attack', [SNDR, NULL]),\n      wbFormIDCk('Sound - Attack 2D', [SNDR, NULL]),\n      wbFormIDCk('Sound - Attack Loop', [SNDR, NULL]),\n      wbFormIDCk('Sound - Attack Fail', [SNDR, NULL]),\n      wbFormIDCk('Sound - Idle', [SNDR, NULL]),\n      wbFormIDCk('Sound - Equip Sound', [SNDR, NULL]),\n      wbFormIDCk('Sound - UnEquip Sound', [SNDR, NULL]),\n      wbFormIDCk('Sound - Fast Equip Sound', [SNDR, NULL]),\n      wbInteger('Accuracy Bonus', itU8),\n      wbFloat('Animation Attack Seconds'),\n      wbByteArray('Unknown', 2),\n      wbFloat('Action Point Cost'),\n      wbFloat('Full Power Seconds'),\n      wbFloat('Min Power Per Shot'),\n      wbInteger('Stagger', itU32, wbStaggerEnum),\n      wbByteArray('Unknown', 4)\n    ]),\n    wbStruct(FNAM, '', [\n      wbFloat('Animation Fire Seconds'),\n      wbFloat('Rumble - Left Motor Strength'),\n      wbFloat('Rumble - Right Motor Strength'),\n      wbFloat('Rumble - Duration'),\n      wbFloat('Animation Reload Seconds'),\n      wbByteArray('Unknown', 4),\n      wbFloat('Sighted Transition Seconds'),\n      wbInteger('# Projectiles', itU8),\n      wbFormIDCk('Override Projectile', [PROJ, NULL]),\n      wbInteger('Pattern', itU32, wbEnum([\n        'Constant',\n        'Square',\n        'Triangle',\n        'Sawtooth'\n      ])),\n      wbInteger('Rumble - Peroid (ms)', itU32)\n    ]),\n    wbStruct(CRDT, 'Critical Data', [\n      wbFloat('Crit Damage Mult'),\n      wbFloat('Crit Charge Bonus'),\n      wbFormIDCk('Crit Effect', [SPEL, NULL])\n    ]),\n    wbFormIDCk(INAM, 'Impact Data Set', [IPDS]),\n    wbFormIDCk(LNAM, 'NPC Add Ammo List', [LVLI]),\n    wbFormIDCk(WAMD, 'Aim Model', [AMDL]),\n    wbFormIDCk(WZMD, 'Zoom', [ZOOM]),\n    wbFormIDCk(CNAM, 'Template', [WEAP]),\n    wbStructs(DAMA, 'Damage Types', 'Damage Type', [\n      wbFormIDCk('Type', [DMGT]),\n      wbInteger('Amount', itU32)\n    ]),\n    wbFLTR,\n    wbInteger(MASE, 'Melee Speed', itU32, wbEnum([\n      'Very Slow',\n      'Slow',\n      'Medium',\n      'Fast',\n      'Very Fast'\n    ]))\n  ], False, nil, cpNormal, False, nil{wbWEAPAfterLoad}, wbKeywordsAfterSet);\n\n  wbRecord(WRLD, 'Worldspace',\n    wbFlags(wbRecordFlagsFlags, wbFlagsList([\n      {0x00080000} 19, 'Can''t Wait'\n    ])), [\n    wbEDID,\n    wbRArray('Unused RNAM', wbUnknown(RNAM), cpIgnore, False{, wbNeverShow}),\n    wbMaxHeightDataWRLD,\n    wbFULL,\n    wbStruct(WCTR, 'Fixed Dimensions Center Cell', [\n      wbInteger('X', itS16),\n      wbInteger('Y', itS16)\n    ]),\n    wbFormIDCk(LTMP, 'Interior Lighting', [LGTM]),\n    wbFormIDCk(XEZN, 'Encounter Zone', [ECZN, NULL]),\n    wbFormIDCk(XLCN, 'Location', [LCTN, NULL]),\n    wbRStruct('Parent', [\n      wbFormIDCk(WNAM, 'Worldspace', [WRLD]),\n      wbStruct(PNAM, '', [\n        wbInteger('Flags', itU8, wbFlags([\n          {0x0001} 'Use Land Data',\n          {0x0002} 'Use LOD Data',\n          {0x0004} 'Don''t Use Map Data',\n          {0x0008} 'Use Water Data',\n          {0x0010} 'Use Climate Data',\n          {0x0020} 'Use Image Space Data (unused)',\n          {0x0040} 'Use Sky Cell'\n        ], [5])),\n        wbByteArray('Unknown', 1)\n      ], cpNormal, True)\n    ], []),\n    wbFormIDCk(CNAM, 'Climate', [CLMT]),\n    wbFormIDCk(NAM2, 'Water', [WATR]),\n    wbFormIDCk(NAM3, 'LOD Water Type', [WATR]),\n    wbFloat(NAM4, 'LOD Water Height'),\n    wbStruct(DNAM, 'Land Data', [\n      wbFloat('Default Land Height'),\n      wbFloat('Default Water Height')\n    ]),\n    wbString(ICON, 'Map Image'),\n    wbRStruct('Cloud Model', [wbMODL], []),\n    wbStruct(MNAM, 'Map Data', [\n      wbStruct('Usable Dimensions', [\n        wbInteger('X', itS32),\n        wbInteger('Y', itS32)\n      ]),\n      wbStruct('Cell Coordinates', [\n        wbStruct('NW Cell', [\n          wbInteger('X', itS16),\n          wbInteger('Y', itS16)\n        ]),\n        wbStruct('SE Cell', [\n          wbInteger('X', itS16),\n          wbInteger('Y', itS16)\n        ])\n      ])\n    ]),\n    wbStruct(ONAM, 'World Map Offset Data', [\n      wbFloat('World Map Scale'),\n      wbFloat('Cell X Offset'),\n      wbFloat('Cell Y Offset'),\n      wbFloat('Cell Z Offset')\n    ], cpNormal, True),\n    wbFloat(NAMA, 'Distant LOD Multiplier'),\n    wbInteger(DATA, 'Flags', itU8, wbFlags([\n      {0x01} 'Small World',\n      {0x02} 'Can''t Fast Travel',\n      {0x04} 'Unknown 3',\n      {0x08} 'No LOD Water',\n      {0x10} 'No Landscape',\n      {0x20} 'No Sky',\n      {0x40} 'Fixed Dimensions',\n      {0x80} 'No Grass'\n    ]), cpNormal, True),\n    {>>> Object Bounds doesn't show up in CK <<<}\n    wbRStruct('Object Bounds', [\n      wbStruct(NAM0, 'Min', [\n        wbFloat('X', cpNormal, False, 1/4096),\n        wbFloat('Y', cpNormal, False, 1/4096)\n      ], cpIgnore, True),\n      wbStruct(NAM9, 'Max', [\n        wbFloat('X', cpNormal, False, 1/4096),\n        wbFloat('Y', cpNormal, False, 1/4096)\n      ], cpIgnore, True)\n    ], []),\n    wbFormIDCk(ZNAM, 'Music', [MUSC]),\n    wbString(NNAM, 'Canopy Shadow (unused)', 0, cpIgnore),\n    wbString(XWEM, 'Water Environment Map'),\n    wbString(TNAM, 'HD LOD Diffuse Texture'),\n    wbString(UNAM, 'HD LOD Normal Texture'),\n    wbRStruct('World Default Level Data', [\n      wbStruct(WLEV, 'Dimension', [\n        wbStruct('NW Cell', [\n          wbInteger('X', itS8),\n          wbInteger('Y', itS8)\n        ]),\n        wbStruct('Size', [\n          wbInteger('Width', itU8),\n          wbInteger('Height', itU8)\n        ])\n      ]),\n      wbByteArray(WLEV, 'Data')\n    ], []),\n    wbOFST,\n    wbUnknown(CLSZ)\n  ], False, nil, cpNormal, False, wbWRLDAfterLoad);\n\n\n  wbRecord(WTHR, 'Weather',\n    wbFlags(wbRecordFlagsFlags, wbFlagsList([\n      {0x00000200}  9, 'Unknown 9'\n    ])), [\n    wbEDID,\n    wbString(_00_0TX, 'Cloud Texture Layer #0'),\n    wbString(_10_0TX, 'Cloud Texture Layer #1'),\n    wbString(_20_0TX, 'Cloud Texture Layer #2'),\n    wbString(_30_0TX, 'Cloud Texture Layer #3'),\n    wbString(_40_0TX, 'Cloud Texture Layer #4'),\n    wbString(_50_0TX, 'Cloud Texture Layer #5'),\n    wbString(_60_0TX, 'Cloud Texture Layer #6'),\n    wbString(_70_0TX, 'Cloud Texture Layer #7'),\n    wbString(_80_0TX, 'Cloud Texture Layer #8'),\n    wbString(_90_0TX, 'Cloud Texture Layer #9'),\n    wbString(_3A_0TX, 'Cloud Texture Layer #10'),\n    wbString(_3B_0TX, 'Cloud Texture Layer #11'),\n    wbString(_3C_0TX, 'Cloud Texture Layer #12'),\n    wbString(_3D_0TX, 'Cloud Texture Layer #13'),\n    wbString(_3E_0TX, 'Cloud Texture Layer #14'),\n    wbString(_3F_0TX, 'Cloud Texture Layer #15'),\n    wbString(_40h_0TX, 'Cloud Texture Layer #16'),\n    wbString(A0TX, 'Cloud Texture Layer #17'),\n    wbString(B0TX, 'Cloud Texture Layer #18'),\n    wbString(C0TX, 'Cloud Texture Layer #19'),\n    wbString(D0TX, 'Cloud Texture Layer #20'),\n    wbString(E0TX, 'Cloud Texture Layer #21'),\n    wbString(F0TX, 'Cloud Texture Layer #22'),\n    wbString(G0TX, 'Cloud Texture Layer #23'),\n    wbString(H0TX, 'Cloud Texture Layer #24'),\n    wbString(I0TX, 'Cloud Texture Layer #25'),\n    wbString(J0TX, 'Cloud Texture Layer #26'),\n    wbString(K0TX, 'Cloud Texture Layer #27'),\n    wbString(L0TX, 'Cloud Texture Layer #28'),\n    wbUnknown(LNAM),\n    wbFormIDCK(MNAM, 'Precipitation Type', [SPGD, NULL]),\n    wbFormIDCK(NNAM, 'Visual Effect', [RFCT, NULL], False, cpNormal, True),\n    wbByteArray(ONAM, 'Unused', 0, cpIgnore),\n    wbRStruct('Cloud Speed', [\n      wbArray(RNAM, 'Y Speed', wbInteger('Layer', itU8, wbCloudSpeedToStr, wbCloudSpeedToInt)),\n      wbArray(QNAM, 'X Speed', wbInteger('Layer', itU8, wbCloudSpeedToStr, wbCloudSpeedToInt))\n    ], []),\n    wbArray(PNAM, 'Cloud Colors', wbWeatherColors('Layer')),\n    wbArray(JNAM, 'Cloud Alphas', wbStruct('Layer', [\n      wbFloat('Sunrise'),\n      wbFloat('Day'),\n      wbFloat('Sunset'),\n      wbFloat('Night'),\n      wbFloat('EarlySunrise'),\n      wbFloat('LateSunrise'),\n      wbFloat('EarlySunset'),\n      wbFloat('LateSunset')\n    ])),\n    wbStruct(NAM0, 'Weather Colors', [\n      wbWeatherColors('Sky-Upper'),\n      wbWeatherColors('Fog Near'),\n      wbWeatherColors('Unknown'),\n      wbWeatherColors('Ambient'),\n      wbWeatherColors('Sunlight'),\n      wbWeatherColors('Sun'),\n      wbWeatherColors('Stars'),\n      wbWeatherColors('Sky-Lower'),\n      wbWeatherColors('Horizon'),\n      wbWeatherColors('Effect Lighting'),\n      wbWeatherColors('Cloud LOD Diffuse'),\n      wbWeatherColors('Cloud LOD Ambient'),\n      wbWeatherColors('Fog Far'),\n      wbWeatherColors('Sky Statics'),\n      wbWeatherColors('Water Multiplier'),\n      wbWeatherColors('Sun Glare'),\n      wbWeatherColors('Moon Glare'),\n      wbWeatherColors('Fog Near High'),\n      wbWeatherColors('Fog Far High')\n    ], cpNormal, True, nil, 8),\n    wbArray(NAM4, 'Unknown', wbFloat('Unknown')),\n    wbStruct(FNAM, 'Fog Distance', [\n      wbFloat('Day - Near'),\n      wbFloat('Day - Far'),\n      wbFloat('Night - Near'),\n      wbFloat('Night - Far'),\n      wbFloat('Day - Power'),\n      wbFloat('Night - Power'),\n      wbFloat('Day - Max'),\n      wbFloat('Night - Max'),\n      wbFloat('Day - Near Height Mid'),\n      wbFloat('Day - Near Height Range'),\n      wbFloat('Night - Near Height Mid'),\n      wbFloat('Night - Near Height Range'),\n      wbFloat('Day - High Density Scale'),\n      wbFloat('Night - High Density Scale'),\n      wbFloat('Day - Far Height Mid'),\n      wbFloat('Day - Far Height Range'),\n      wbFloat('Night - Far Height Mid'),\n      wbFloat('Night - Far Height Range')\n    ], cpNormal, True, nil, 8),\n    wbStruct(DATA, 'Data', [\n      wbInteger('Wind Speed', itU8), // scaled 0..1\n      wbByteArray('Unknown', 2),\n      wbInteger('Trans Delta', itU8), // scaled 0..0,25\n      wbInteger('Sun Glare', itU8), // scaled 0..1\n      wbInteger('Sun Damage', itU8), // scaled 0..1\n      wbInteger('Precipitation - Begin Fade In', itU8), // scaled 0..1\n      wbInteger('Precipitation - End Fade Out', itU8), // scaled 0..1\n      wbInteger('Thunder/Lightning - Begin Fade In', itU8),\n      wbInteger('Thunder/Lightning - End Fade Out', itU8),\n      wbInteger('Thunder/Lightning - Frequency', itU8),\n      wbInteger('Flags', itU8, wbFlags([\n        {0x01} 'Weather - Pleasant',\n        {0x02} 'Weather - Cloudy',\n        {0x04} 'Weather - Rainy',\n        {0x08} 'Weather - Snow',\n        {0x10} 'Sky Statics - Always Visible',\n        {0x20} 'Sky Statics - Follows Sun Position',\n        {0x40} 'Rain Occlusion',\n        {0x80} 'HUD Rain Effects'\n      ])),\n      wbStruct('Lightning Color', [\n        wbInteger('Red', itU8),\n        wbInteger('Green', itU8),\n        wbInteger('Blue', itU8)\n      ]),\n      wbInteger('Visual Effect - Begin', itU8), // scaled 0..1\n      wbInteger('Visual Effect - End', itU8), // scaled 0..1\n      wbInteger('Wind Direction', itU8), // scaled 0..360\n      wbInteger('Wind Direction Range', itU8), // scaled 0..180\n      wbInteger('Unknown', itU8)\n    ], cpNormal, True, nil, 16),\n    wbInteger(NAM1, 'Disabled Cloud Layers', itU32, wbFlags(['0','1','2','3','4','5','6','7','8','9','10','11','12','13','14','15','16','17','18','19','20','21','22','23','24','25','26','27','28','29','30','31'])),\n    wbRArray('Sounds',\n      wbStruct(SNAM, 'Sound', [\n        wbFormIDCK('Sound', [SNDR, NULL]),\n        wbInteger('Type', itU32, wbEnum([\n          {0x01} 'Default',\n          {0x02} 'Precipitation',\n          {0x04} 'Wind',\n          {0x08} 'Thunder'\n        ]))\n      ])\n    ),\n    wbRArrayS('Sky Statics', wbFormIDCk(TNAM, 'Static', [STAT, NULL])),\n    wbStruct(IMSP, 'Image Spaces', [\n      wbFormIDCK('Sunrise', [IMGS, NULL]),\n      wbFormIDCK('Day', [IMGS, NULL]),\n      wbFormIDCK('Sunset', [IMGS, NULL]),\n      wbFormIDCK('Night', [IMGS, NULL]),\n      wbFormIDCK('EarlySunrise', [IMGS, NULL]),\n      wbFormIDCK('LateSunrise', [IMGS, NULL]),\n      wbFormIDCK('EarlySunset', [IMGS, NULL]),\n      wbFormIDCK('LateSunset', [IMGS, NULL])\n    ], cpNormal, True, nil, 4),\n    wbStruct(WGDR, 'God Rays', [\n      wbFormIDCK('Sunrise', [GDRY, NULL]),\n      wbFormIDCK('Day', [GDRY, NULL]),\n      wbFormIDCK('Sunset', [GDRY, NULL]),\n      wbFormIDCK('Night', [GDRY, NULL]),\n      wbFormIDCK('EarlySunrise', [GDRY, NULL]),\n      wbFormIDCK('LateSunrise', [GDRY, NULL]),\n      wbFormIDCK('EarlySunset', [GDRY, NULL]),\n      wbFormIDCK('LateSunset', [GDRY, NULL])\n    ]),\n    wbRStruct('Directional Ambient Lighting Colors', [\n      wbAmbientColors(DALC, 'Sunrise'),\n      wbAmbientColors(DALC, 'Day'),\n      wbAmbientColors(DALC, 'Sunset'),\n      wbAmbientColors(DALC, 'Night'),\n      wbAmbientColors(DALC, 'EarlySunrise'),\n      wbAmbientColors(DALC, 'LateSunrise'),\n      wbAmbientColors(DALC, 'EarlySunset'),\n      wbAmbientColors(DALC, 'LateSunset')\n    ], [], cpNormal, True),\n    wbRStruct('Aurora', [wbMODL], []),\n    wbFormIDCk(GNAM, 'Sun Glare Lens Flare', [LENS]),\n    wbStruct(UNAM, 'Magic', [\n      wbFormIDCk('On Lightning Strike - Spell', [SPEL, NULL]),\n      wbFloat('On Lightning Strike - Threshold'),\n      wbFormIDCk('On Weather Activate - Spell', [SPEL, NULL]),\n      wbFloat('On Weather Activate - Threshold'),\n      wbByteArray('Unknown', 4), // SPEL FormID for another context but unresolved in Fallout4.esm, legacy data\n      wbFloat('Unknown')\n    ], cpNormal, False, nil, 3),\n    wbFloat(VNAM, 'Volatility Mult'),\n    wbFloat(WNAM, 'Visibility Mult')\n  ]);\nend;\n\nprocedure DefineFO4p;\nbegin\n  {wbRecord(SCPT, 'SCPT', [\n    wbEDID\n  ]);}\nend;\n\n{>>> Start of new Fallout 4 Records <<<}\n\nprocedure DefineFO4q;\nbegin\n  wbRecord(AECH, 'Audio Effect Chain', [\n    wbEDID,\n    wbRArray('Effects',\n      wbRStruct('Effect', [\n        wbInteger(KNAM, 'Type', itU32, wbEnum([], [\n          Int64($864804BE), 'BSOverdrive',\n          Int64($EF575F7F), 'BSStateVariableFilter',\n          Int64($18837B4F), 'BSDelayEffect'\n        ]), cpNormal, False, False, nil, nil, Int64($864804BE)),\n        wbStruct(DNAM, 'Data', [\n          wbInteger('Enabled', itU32, wbBoolEnum),\n          wbUnion('Value 1', wbAECHDataDecider, [\n            wbFloat('Input Gain'), // exponentially(?) normalized from 0..10 to -80..20\n            wbFloat('Center Freq'),\n            wbFloat('Feedback %')\n          ]),\n          wbUnion('Value 2', wbAECHDataDecider, [\n            wbFloat('Output Gain'), // exponentially(?) normalized from 0..10 to -80..20\n            wbFloat('Q Value'),\n            wbFloat('Wet Mix %')\n          ]),\n          wbUnion('Value 3', wbAECHDataDecider, [\n            wbFloat('Upper Threshold'), // exponentially(?) normalized from 0..1 to -74..0\n            wbInteger('Filter Mode', itU32, wbEnum([\n              'High Pass',\n              'Low Pass',\n              'Band Pass',\n              'Notch'\n            ])),\n            wbInteger('Delay MS', itU32)\n          ]),\n          wbUnion('Value 4', wbAECHDataDecider, [\n            wbFloat('Lower Threshold'), // exponentially(?) normalized from 0..1 to -80..0\n            wbByteArray('Unused', 0),\n            wbByteArray('Unused', 0)\n          ])\n        ])\n      ], [])\n    )\n  ]);\n\n  wbRecord(AMDL, 'Aim Model', [\n    wbEDID,\n    wbStruct(DNAM, 'Data', [\n      wbFloat('Cone of Fire - Min Angle'),\n      wbFloat('Cone of Fire - Max Angle'),\n      wbFloat('Cone of Fire - Increase Per Shot'),\n      wbFloat('Cone of Fire - Decrease Per Sec'),\n      wbInteger('Cone of Fire - Decrease Delay MS', itU32),\n      wbFloat('Cone of Fire - Sneak Mult'),\n      wbFloat('Recoil - Diminish Spring Force'),\n      wbFloat('Recoil - Diminish Sights Mult'),\n      wbFloat('Recoil - Max Per Shot'),\n      wbFloat('Recoil - Min Per Shot'),\n      wbFloat('Recoil - Hip Mult'),\n      wbInteger('Runaway - Recoil Shots', itU32),\n      wbFloat('Recoil - Arc'),\n      wbFloat('Recoil - Arc Rotate'),\n      wbFloat('Cone of Fire - Iron Sights Mult'),\n      wbFloat('Stability - Base Stability')\n    ])\n  ]);\n\n  wbRecord(AORU, 'Attraction Rule', [\n    wbEDID,\n    wbStruct(AOR2, 'Data', [\n      wbFloat('Radius'),\n      wbFloat('Min Delay'),\n      wbFloat('Max Delay'),\n      wbInteger('Requires Line of Sight', itU8, wbBoolEnum),\n      wbInteger('Combat Target', itU8, wbBoolEnum),\n      wbByteArray('Unused', 2)\n    ], cpNormal, True)\n  ]);\n\n  wbRecord(BNDS, 'Bendable Spline', [\n    wbEDID,\n    wbOBND,\n    wbStruct(DNAM, 'Data', [\n      wbFloat('Default Number of Tiles'),\n      wbInteger('Default Number of Slices', itU16),\n      wbInteger('Default Number of Tiles - Relative to Length', itU16, wbBoolEnum),\n      wbFloatColors('Default Color'),\n      wbFloat('Wind Settings - Sensibility'),\n      wbFloat('Wind Settings - Flexibility')\n    ]),\n    wbFormIDCk(TNAM, 'Texture', [TXST])\n  ]);\n\n  wbRecord(CMPO, 'Component', [\n    wbEDID,\n    wbOBND,\n    wbFULL,\n    wbCUSD,\n    wbInteger(DATA, 'Auto Calc Value', itU32),\n    wbFormIDCk(MNAM, 'Scrap Item', [MISC]),\n    wbFormIDCk(GNAM, 'Mod Scrap Scalar', [GLOB])\n  ]);\n\n  wbRecord(DFOB, 'Default Object', [\n    wbEDID,\n    wbFormID(DATA, 'Object')\n  ]);\n\n  wbRecord(DMGT, 'Damage Type', [\n    wbEDID,\n    // Before form version 78, it was an array of AVIF index, since then array of AVIF formID, coupled with a SPEL formID\n    wbUnion(DNAM, 'Data', wbFormVer78Decider, [\n      wbArray('Damage Types', wbInteger('Actor Value Index', itU32)),\n      wbArray('Damage Types', wbStruct('Damage Type', [\n        wbFormIDck('Actor Value', [AVIF, NULL]),\n        wbFormIDck('Spell', [SPEL, NULL])\n      ]))\n    ])\n  ]);\n\n  wbRecord(GDRY, 'God Rays', [\n    wbEDID,\n    wbStruct(DATA, 'Data', [\n      wbFloatColors('Back Color'),\n      wbFloatColors('Fwd Color'),\n      wbFloat('Intensity'),\n      wbFloat('Air Color - Scale'),\n      wbFloat('Back Color - Scale'),\n      wbFloat('Fwd Color - Scale'),\n      wbFloat('Back Phase'),\n      wbFloatColors('Air Color'),\n      wbFloat('Fwd Phase')\n    ])\n  ]);\n\nend;\n\nprocedure DefineFO4r;\nbegin\n  wbRecord(INNR, 'Instance Naming Rules', [\n    wbEDID,\n    wbInteger(UNAM, 'Target', itU32, wbEnum([], [\n        0, 'None',\n      $1D, 'Armor',\n      $2D, 'Actor',\n      $2A, 'Furniture',\n      $2B, 'Weapon'\n    ])),\n    wbRArray('Naming Rules',\n      wbRStruct('Ruleset', [\n        wbInteger(VNAM, 'Count', itU32),\n        // should not be sorted\n        wbRArray('Names',\n          wbRStruct('Name', [\n            wbLString(WNAM, 'Text', 0, cpTranslate),\n            wbKSIZ,\n            wbKWDAs,\n            wbStruct(XNAM, 'Property', [\n              wbFloat('Value'),\n              wbInteger('Target', itU8, wbEnum([\n                { 0} 'Enchantments',\n                { 1} 'BashImpactDataSet',\n                { 2} 'BlockMaterial',\n                { 3} 'Keywords',\n                { 4} 'Weight',\n                { 5} 'Value',\n                { 6} 'Rating',\n                { 7} 'AddonIndex',\n                { 8} 'BodyPart',\n                { 9} 'DamageTypeValues',\n                {10} 'ActorValues',\n                {11} 'Health',\n                {12} 'ColorRemappingIndex',\n                {13} 'MaterialSwaps'\n              ])),\n              wbInteger('Op', itU8, wbEnum([\n                {0} '>=',\n                {1} '>',\n                {2} '<=',\n                {3} '<',\n                {4} '='\n              ]))\n            ]),\n            wbInteger(YNAM, 'Index', itU16)\n          ], []),\n          cpNormal, False, nil, wbINNRAfterSet\n        )\n      ], [])\n    )\n  ]);\n\n  wbRecord(KSSM, 'Sound Keyword Mapping', [\n    wbEDID,\n    wbFormIDCk(DNAM, 'Primary Descriptor', [SNDR]),\n    wbFormIDCk(ENAM, 'Exterior Tail', [SNDR]),\n    wbFormIDCk(VNAM, 'VATS Descriptor', [SNDR]),\n    wbFloat(TNAM, 'VATS Threshold'),\n    wbRArray('Keywords', wbFormIDCk(KNAM, 'Keyword', [KYWD])),\n    wbRArrayS('Sounds', wbStructSK(RNAM, [0], 'Sound', [\n      wbInteger('Reverb Class', itU32, wbReverbClassEnum),\n      wbFormIDCk('Descriptor', [SNDR])\n    ]))\n  ]);\n\n  wbRecord(LAYR, 'Layer', [\n    wbEDID,\n    wbFormIDCk(PNAM, 'Parent', [LAYR])\n  ]);\n\n  wbRecord(LENS, 'Lens Flare', [\n    wbEDID,\n    wbFloat(CNAM, 'Color Influence'),\n    wbFloat(DNAM, 'Fade Distance Radius Scale'),\n    wbInteger(LFSP, 'Count', itU32, nil, cpBenign),\n    wbRArrayS('Lens Flare Sprites',\n      wbRStructSK([0], 'Flare', [\n        wbString(DNAM, 'Lens Flare Sprite ID'),\n        wbString(FNAM, 'Texture'),\n        wbStruct(LFSD, 'Lens Flare Data', [\n          wbFloatColors('Tint'),\n          wbFloat('Width'),\n          wbFloat('Height'),\n          wbFloat('Position'),\n          wbFloat('Angular Fade'),\n          wbFloat('Opacity'),\n          wbInteger('Flags', itU32, wbFlags([\n            {0x01} 'Rotates',\n            {0x02} 'Shrinks When Occluded'\n          ]))\n        ])\n      ], []),\n      cpNormal, False, nil, wbLENSAfterSet\n    )\n  ]);\n\n  {wbRecord(LSPR, 'LSPR', [\n    wbEDID\n  ]);\n\n  wbRecord(MICN, 'MICN', [\n    wbEDID\n  ]);}\n\n  wbRecord(MSWP, 'Material Swap',\n    wbFlags(wbRecordFlagsFlags, wbFlagsList([\n      {0x00010000} 16, 'Custom Swap'\n    ])), [\n    wbEDID,\n    wbString(FNAM, 'Tree Folder'), {First FNAM}\n    wbRArrayS('Material Substitutions',\n      wbRStructSK([0], 'Substitution', [\n        wbString(BNAM, 'Original Material'),\n        wbString(SNAM, 'Replacement Material'),\n        wbString(FNAM, 'Tree Folder (obsolete)'), {Unused, will be moved up to First FNAM}\n        wbFloat(CNAM, 'Color Remapping Index')\n      ], [])\n    )\n  ]);\n\n  wbRecord(NOCM, 'Navigation Mesh Obstacle Manager', [\n    wbRArray('Unknown',\n      wbRStruct('Unknown', [\n        wbInteger(INDX, 'Index', itU32),\n        wbRArray('Unknown', wbUnknown(DATA)),\n        wbUnknown(INTV),\n        wbString(NAM1, 'Model')\n      ], [])\n    )\n  ]);\n\nend;\n\nprocedure DefineFO4s;\nbegin\n  wbRecord(NOTE, 'Note', [\n    wbEDID,\n    wbVMAD,\n    wbOBND,\n    wbPTRN,\n    wbFULL,\n    wbMODL,\n    wbICON,\n    wbYNAM,\n    wbZNAM,\n    wbInteger(DNAM, 'Type', itU8, wbEnum([\n      'Sound',\n      'Voice',\n      'Program',\n      'Terminal'\n    ]), cpNormal, True),\n    wbStruct(DATA, '', [      // was DNAM before form version 65. Now holds value and weight\n      wbInteger('Value', itU32),\n      wbFloat('Weight')\n    ]),\n    wbUnion(SNAM, 'Data', wbNOTEDataDecider, [\n      wbByteArray('Unused', 4),\n      wbFormIDCk('Sound', [SNDR]),\n      wbFormIDCk('Scene', [SCEN]),\n      wbFormIDCk('Terminal', [TERM])\n    ]),\n    wbString(PNAM, 'Program File')\n  ]);\n\n  wbRecord(OMOD, 'Object Modification',\n    wbFlags(wbRecordFlagsFlags, wbFlagsList([\n      {0x00000008} 4, 'Legendary Mod',\n      {0x00000040} 7, 'Mod Collection'\n    ])), [\n    wbEDID,\n    wbFULL,\n    wbDESC,\n    wbMODL,\n    wbStruct(DATA, 'Data', [\n      wbInteger('Include Count', itU32),\n      wbInteger('Property Count', itU32),\n      wbByteArray('Unused', 2, cpIgnore),\n      wbInteger('Form Type', itU32, wbEnum([], [\n        Sig2Int(ARMO), 'Armor',\n        Sig2Int(NPC_), 'Non-player character',\n        Sig2Int(WEAP), 'Weapon',\n        Sig2Int(NONE), 'None'\n      ])),\n      wbByteArray('Unused', 2, cpIgnore),\n      wbFormIDCk('Attach Point', [KYWD, NULL]),\n      wbArray('Attach Parent Slots', wbFormIDCk('Keyword', [KYWD, NULL]), -1),\n      // no way to change these in CK, legacy data leftover?\n      wbArray('Items', wbStruct('Item', [\n        wbByteArray('Value 1', 4),\n        wbByteArray('Value 2', 4)\n      ]), -1),\n      // should not be sorted\n      wbArray('Includes', wbStruct('Include', [\n        wbFormIDCk('Mod', [OMOD]),\n        wbInteger('Minimum Level', itU8),\n        wbInteger('Optional', itU8, wbBoolEnum),\n        wbInteger('Don''t Use All', itU8, wbBoolEnum)\n      ]), wbOMODDataIncludeCounter, cpNormal, False, nil, wbOMODincludeAfterSet),\n      wbObjectModProperties\n    ], cpNormal, False, nil, -1, nil, wbOMODdataAfterSet),\n    wbArray(MNAM, 'Target OMOD Keywords', wbFormIDCk('Keyword', [KYWD])),\n    wbArray(FNAM, 'Filter Keywords', wbFormIDCk('Keyword', [KYWD])),\n    wbFormIDCk(LNAM, 'Loose Mod', sigBaseObjects),\n    wbInteger(NAM1, 'Priority', itU8),\n    wbFLTR\n  ]);\n\n  wbRecord(OVIS, 'Object Visibility Manager', [\n    wbRArray('Unknown',\n      wbRStruct('Unknown', [\n        wbFormIDCk(INDX, 'Object', [STAT]),\n        wbStruct(DATA, 'Object Bounds', [\n          wbFloat('X1'),\n          wbFloat('Y1'),\n          wbFloat('Z1'),\n          wbFloat('X2'),\n          wbFloat('Y2'),\n          wbFloat('Z2')\n        ])\n      ], [])\n    )\n  ]);\n\n  wbRecord(PKIN, 'Pack-In',\n    wbFlags(wbRecordFlagsFlags, wbFlagsList([\n      {0x00000200}  9, 'Prefab'\n    ])), [\n    wbEDID,\n    wbOBND,\n    wbFLTR,\n    wbFormIDCk(CNAM, 'Cell', [CELL]),\n    wbInteger(VNAM, 'Version', itU32)\n  ]);\n\n  wbRecord(RFGP, 'Reference Group', [\n    wbEDID,\n    wbString(NNAM, 'Name'),\n    wbFormIDCk(RNAM, 'Reference', sigReferences),\n    wbUnknown(PNAM)\n  ]);\n\n  {wbRecord(RGDL, 'RGDL', [\n    wbEDID\n  ]);}\n\n  wbRecord(SCCO, 'Scene Collection', [\n    wbEDID,\n    wbFormIDCk(QNAM, 'Quest', [QUST]),\n    wbRArray('Scenes',\n      wbRStruct('Scene', [\n        wbFormIDCk(SNAM, 'Scene', [SCEN]),\n        wbStruct(XNAM, 'Unknown', [\n          wbInteger('Unknown', itS32),\n          wbInteger('Unknown', itS32)\n        ])\n      ], [])\n    ),\n    wbUnknown(VNAM, cpNormal, True),\n    wbRArray('Unknown', wbStruct(XNAM, 'Unknown', [\n      wbInteger('Unknown', itS32),\n      wbInteger('Unknown', itS32)\n    ])),\n    wbUnknown(VNAM, cpNormal, True)\n  ]);\n\n  wbRecord(SCOL, 'Static Collection',\n    wbFlags(wbRecordFlagsFlags, wbFlagsList([\n      {0x00000004}  4, 'Non Occluder',\n      {0x00000200}  9, 'Hidden From Local Map',\n      {0x00000400} 10, 'Unknown 10',\n      {0x00000800} 11, 'Used as Platform',\n      {0x00008000} 15, 'Has Distant LOD',\n      {0x02000000} 25, 'Obstacle',\n      {0x04000000} 26, 'NavMesh Generation - Filter',\n      {0x08000000} 27, 'NavMesh Generation - Bounding Box',\n      {0x40000000} 30, 'NavMesh Generation - Ground'\n    ])), [\n    wbEDID,\n    wbOBNDReq,\n    wbPTRN,\n    wbMODL,\n    wbFULL,\n    wbFLTR,\n    wbRStructsSK('Parts', 'Part', [0], [\n      wbFormIDCk(ONAM, 'Static', [ACTI, ALCH, AMMO, BOOK, CONT, DOOR, FURN, MISC, MSTT, STAT, TERM, WEAP]),\n      wbArrayS(DATA, 'Placements', wbStruct('Placement', [\n        wbStruct('Position', [\n          wbFloat('X'),\n          wbFloat('Y'),\n          wbFloat('Z')\n        ]),\n        wbStruct('Rotation', [\n          wbFloat('X', cpNormal, True, wbRotationFactor, wbRotationScale, nil, RadiansNormalize),\n          wbFloat('Y', cpNormal, True, wbRotationFactor, wbRotationScale, nil, RadiansNormalize),\n          wbFloat('Z', cpNormal, True, wbRotationFactor, wbRotationScale, nil, RadiansNormalize)\n        ]),\n        wbFloat('Scale')\n      ]), 0, cpNormal, True)\n    ], [], cpNormal, True)\n  ]);\n\n  wbRecord(SCSN, 'Audio Category Snapshot', [\n    wbEDID,\n    wbInteger(PNAM, 'Priority', itU16),\n    wbRArray('Category Multipliers', wbStruct(CNAM, 'Category Multiplier', [\n      wbFormIDCk('Categoty', [SNCT]),\n      wbFloat('Multiplier')\n    ]))\n  ]);\n\nend;\n\nprocedure DefineFO4t;\nbegin\n  {wbRecord(SKIL, 'SKIL', [\n    wbEDID\n  ]);}\n\n  wbRecord(STAG, 'Animation Sound Tag Set', [\n    wbEDID,\n    wbRArray('Sounds', wbStruct(TNAM, 'Sound', [\n      wbFormIDCk('Sound', [SNDR, NULL]),\n      wbString('Action')\n    ]))\n  ]);\n\n  wbRecord(TERM, 'Terminal',\n    wbFlags(wbRecordFlagsFlags, wbFlagsList([\n      {0x00000004}  4, 'Unknown 4',\n      {0x00002000} 13, 'Unknown 13',\n      {0x00008000} 15, 'Has Distant LOD',\n      {0x00010000} 16, 'Random Anim Start'\n    ])), [\n    wbEDID,\n    wbVMADFragmentedPERK, // same fragments format as in PERK\n    wbOBNDReq,\n    wbPTRN,\n    wbLString(NAM0, 'Header Text'),\n    wbLString(WNAM, 'Welcome Text'),\n    wbFULL,\n    wbMODL,\n    wbKSIZ,\n    wbKWDAs,\n    wbPRPS,\n    wbUnknown(PNAM),\n    wbFormIDCk(SNAM, 'Looping Sound', [SNDR]),\n    wbUnknown(FNAM),\n    wbCOCT,\n    wbCNTOs,\n    wbMNAMFurnitureMarker,\n    wbByteArray(WBDT, 'Workbench Data (unused)', 0),\n    wbString(XMRK, 'Marker Model'),\n    wbSNAMMarkerParams,\n    wbInteger(BSIZ, 'Count', itU32, nil, cpBenign),\n    wbRArray('Body Text',\n      wbRStruct('Item', [\n        wbLString(BTXT, 'Text', 0, cpTranslate),\n        wbCTDAs\n      ], []),\n      cpNormal, False, nil, wbTERMDisplayItemsAfterSet\n    ),\n    wbInteger(ISIZ, 'Count', itU32, nil, cpBenign),\n    wbRArray('Menu Items',\n      wbRStruct('Menu Item', [\n        wbLString(ITXT, 'Item Text', 0, cpTranslate),\n        wbLString(RNAM, 'Response Text', 0, cpTranslate),\n        wbInteger(ANAM, 'Type', itU8, wbEnum([\n          {0} 'Unknown 0',\n          {1} 'Unknown 1',\n          {2} 'Unknown 2',\n          {3} 'Unknown 3',\n          {4} 'Submenu - Terminal',\n          {5} 'Submenu - Return to Top Level',\n          {6} 'Submenu - Force Redraw',\n          {7} 'Unknown 7',\n          {8} 'Display Text'\n        ]), cpNormal, True),\n        wbInteger(ITID, 'Item ID', itU16),\n        wbLString(UNAM, 'Display Text', 0, cpTranslate),\n        wbString(VNAM, 'Show Image'),\n        wbFormIDCk(TNAM, 'Submenu', [TERM]),\n        wbCTDAs\n      ], []),\n      cpNormal, False, nil, wbTERMMenuItemsAfterSet\n    )\n  ]);\n\n  {wbRecord(TLOD, 'TLOD', [\n    wbEDID\n  ]);\n\n  wbRecord(TOFT, 'TOFT', [\n    wbEDID\n  ]);}\n\n  wbRecord(TRNS, 'Transform',\n    wbFlags(wbRecordFlagsFlags, wbFlagsList([\n      {0x00008000} 16, 'Around Origin'\n    ])), [\n    wbEDID,\n    wbStruct(DATA, 'Data', [\n      wbPosRot,\n      wbFloat('Scale'),\n      wbFloat('Zoom Min'),\n      wbFloat('Zoom Max')\n    ], cpNormal, True, nil, 2)\n  ]);\n\n  wbRecord(ZOOM, 'Zoom', [\n    wbEDID,\n    wbStruct(GNAM, 'Data', [\n      wbFloat('FOV Mult'),\n      wbInteger('Overlay', itU32, wbEnum([\n        { 0} 'Default',\n        { 1} 'Fine',\n        { 2} 'Duplex',\n        { 3} 'German',\n        { 4} 'Dot',\n        { 5} 'Mil-Dot',\n        { 6} 'Circle',\n        { 7} 'Old Rangefind',\n        { 8} 'Modern Rangefind',\n        { 9} 'SVD',\n        {10} 'Hand Painted',\n        {11} 'Binoculars',\n        {12} 'Cross',\n        {13} 'Double Zero',\n        {14} 'Rangefinder 1',\n        {15} 'Rangefinder 2',\n        {16} 'Rectangle'\n      ])),\n      wbFormIDCk('Imagespace Modifier', [IMAD, NULL]),\n      wbStruct('Camera Offset', [\n        wbFloat('X'),\n        wbFloat('Y'),\n        wbFloat('Z')\n      ])\n    ])\n  ]);\n\nend;\n\nprocedure DefineFO4u;\nbegin\n   wbAddGroupOrder(GMST);\n   wbAddGroupOrder(KYWD);\n   wbAddGroupOrder(LCRT);\n   wbAddGroupOrder(AACT);\n   wbAddGroupOrder(TRNS);\n   wbAddGroupOrder(CMPO);\n   wbAddGroupOrder(TXST);\n   //wbAddGroupOrder(MICN);\n   wbAddGroupOrder(GLOB);\n   wbAddGroupOrder(DMGT);\n   wbAddGroupOrder(CLAS);\n   wbAddGroupOrder(FACT);\n   wbAddGroupOrder(HDPT);\n   //wbAddGroupOrder(EYES);\n   wbAddGroupOrder(RACE);\n   wbAddGroupOrder(SOUN);\n   wbAddGroupOrder(ASPC);\n   //wbAddGroupOrder(SKIL);\n   wbAddGroupOrder(MGEF);\n   //wbAddGroupOrder(SCPT);{>>> Unused in Skyrim, but contained in Skyrim.esm <<<}\n   wbAddGroupOrder(LTEX);\n   wbAddGroupOrder(ENCH);\n   wbAddGroupOrder(SPEL);\n   //wbAddGroupOrder(SCRL);\n   wbAddGroupOrder(ACTI);\n   wbAddGroupOrder(TACT);\n   wbAddGroupOrder(ARMO);\n   wbAddGroupOrder(BOOK);\n   wbAddGroupOrder(CONT);\n   wbAddGroupOrder(DOOR);\n   wbAddGroupOrder(INGR);\n   wbAddGroupOrder(LIGH);\n   wbAddGroupOrder(MISC);\n   wbAddGroupOrder(STAT);\n   wbAddGroupOrder(SCOL);\n   wbAddGroupOrder(MSTT);\n   wbAddGroupOrder(GRAS);\n   wbAddGroupOrder(TREE);\n   wbAddGroupOrder(FLOR);\n   wbAddGroupOrder(FURN);\n   wbAddGroupOrder(WEAP);\n   wbAddGroupOrder(AMMO);\n   wbAddGroupOrder(NPC_);\n   wbAddGroupOrder(LVLN);\n   wbAddGroupOrder(KEYM);\n   wbAddGroupOrder(ALCH);\n   wbAddGroupOrder(IDLM);\n   wbAddGroupOrder(NOTE);\n   wbAddGroupOrder(PROJ);\n   wbAddGroupOrder(HAZD);\n   wbAddGroupOrder(BNDS);\n   //wbAddGroupOrder(SLGM);\n   wbAddGroupOrder(TERM);\n   wbAddGroupOrder(LVLI);\n   wbAddGroupOrder(WTHR);\n   wbAddGroupOrder(CLMT);\n   wbAddGroupOrder(SPGD);\n   wbAddGroupOrder(RFCT);\n   wbAddGroupOrder(REGN);\n   wbAddGroupOrder(NAVI);\n   wbAddGroupOrder(CELL);\n   //wbAddGroupOrder(REFR);\n   //wbAddGroupOrder(ACHR);\n   //wbAddGroupOrder(PMIS);\n   //wbAddGroupOrder(PARW);\n   //wbAddGroupOrder(PGRE);\n   //wbAddGroupOrder(PBEA);\n   //wbAddGroupOrder(PFLA);\n   //wbAddGroupOrder(PCON);\n   //wbAddGroupOrder(PBAR);\n   //wbAddGroupOrder(PHZD);\n   wbAddGroupOrder(WRLD);\n   //wbAddGroupOrder(LAND);\n   //wbAddGroupOrder(NAVM);\n   //wbAddGroupOrder(TLOD);\n   //wbAddGroupOrder(DIAL);\n   //wbAddGroupOrder(INFO);\n   wbAddGroupOrder(QUST);\n   wbAddGroupOrder(IDLE);\n   wbAddGroupOrder(PACK);\n   wbAddGroupOrder(CSTY);\n   wbAddGroupOrder(LSCR);\n   wbAddGroupOrder(LVSP);\n   wbAddGroupOrder(ANIO);\n   wbAddGroupOrder(WATR);\n   wbAddGroupOrder(EFSH);\n   //wbAddGroupOrder(TOFT);\n   wbAddGroupOrder(EXPL);\n   wbAddGroupOrder(DEBR);\n   wbAddGroupOrder(IMGS);\n   wbAddGroupOrder(IMAD);\n   wbAddGroupOrder(FLST);\n   wbAddGroupOrder(PERK);\n   wbAddGroupOrder(BPTD);\n   wbAddGroupOrder(ADDN);\n   wbAddGroupOrder(AVIF);\n   wbAddGroupOrder(CAMS);\n   wbAddGroupOrder(CPTH);\n   wbAddGroupOrder(VTYP);\n   wbAddGroupOrder(MATT);\n   wbAddGroupOrder(IPCT);\n   wbAddGroupOrder(IPDS);\n   wbAddGroupOrder(ARMA);\n   wbAddGroupOrder(ECZN);\n   wbAddGroupOrder(LCTN);\n   wbAddGroupOrder(MESG);\n   //wbAddGroupOrder(RGDL);{>>> Unused in Skyrim, but contained in Skyrim.esm <<<}\n   wbAddGroupOrder(DOBJ);\n   wbAddGroupOrder(DFOB);\n   wbAddGroupOrder(LGTM);\n   wbAddGroupOrder(MUSC);\n   wbAddGroupOrder(FSTP);\n   wbAddGroupOrder(FSTS);\n   wbAddGroupOrder(SMBN);\n   wbAddGroupOrder(SMQN);\n   wbAddGroupOrder(SMEN);\n   wbAddGroupOrder(DLBR);\n   wbAddGroupOrder(MUST);\n   wbAddGroupOrder(DLVW);\n   //wbAddGroupOrder(WOOP);\n   //wbAddGroupOrder(SHOU);\n   wbAddGroupOrder(EQUP);\n   wbAddGroupOrder(RELA);\n   wbAddGroupOrder(SCEN);\n   wbAddGroupOrder(ASTP);\n   wbAddGroupOrder(OTFT);\n   wbAddGroupOrder(ARTO);\n   wbAddGroupOrder(MATO);\n   wbAddGroupOrder(MOVT);\n   wbAddGroupOrder(SNDR);\n   wbAddGroupOrder(DUAL); // doesn't exist but can be created in CK\n   wbAddGroupOrder(SNCT);\n   wbAddGroupOrder(SOPM);\n   wbAddGroupOrder(COLL);\n   wbAddGroupOrder(CLFM);\n   wbAddGroupOrder(REVB);\n   wbAddGroupOrder(PKIN);\n   wbAddGroupOrder(RFGP);\n   wbAddGroupOrder(AMDL);\n   wbAddGroupOrder(LAYR);\n   wbAddGroupOrder(COBJ);\n   wbAddGroupOrder(OMOD);\n   wbAddGroupOrder(MSWP);\n   wbAddGroupOrder(ZOOM);\n   wbAddGroupOrder(INNR);\n   wbAddGroupOrder(KSSM);\n   wbAddGroupOrder(AECH);\n   wbAddGroupOrder(SCCO);\n   wbAddGroupOrder(AORU);\n   wbAddGroupOrder(SCSN);\n   wbAddGroupOrder(STAG);\n   wbAddGroupOrder(NOCM);\n   wbAddGroupOrder(LENS);\n   //wbAddGroupOrder(LSPR);\n   wbAddGroupOrder(GDRY);\n   wbAddGroupOrder(OVIS);\nend;\n\nprocedure DefineFO4;\nbegin\n  DefineFO4a;\n  DefineFO4b;\n  DefineFO4c;\n  DefineFO4d;\n  DefineFO4e;\n  DefineFO4f;\n  DefineFO4g;\n  DefineFO4h;\n  DefineFO4i;\n  DefineFO4j;\n  DefineFO4k;\n  DefineFO4l;\n  DefineFO4m;\n  DefineFO4n;\n  DefineFO4o;\n  DefineFO4p;\n  DefineFO4q;\n  DefineFO4r;\n  DefineFO4s;\n  DefineFO4t;\n  DefineFO4u;\n\n  SetLength(wbOfficialDLC, 6);\n  wbOfficialDLC[0] := 'DLCRobot.esm';\n  wbOfficialDLC[1] := 'DLCWorkshop01.esm';\n  wbOfficialDLC[2] := 'DLCCoast.esm';\n  wbOfficialDLC[3] := 'DLCWorkshop02.esm';\n  wbOfficialDLC[4] := 'DLCWorkshop03.esm';\n  wbOfficialDLC[5] := 'DLCNukaWorld.esm';\nend;\n\ninitialization\nend.\n"
  },
  {
    "path": "lib/xedit/wbDefinitionsTES3.pas",
    "content": "{*******************************************************************************\n\n     The contents of this file are subject to the Mozilla Public License\n     Version 1.1 (the \"License\"); you may not use this file except in\n     compliance with the License. You may obtain a copy of the License at\n     http://www.mozilla.org/MPL/\n\n     Software distributed under the License is distributed on an \"AS IS\"\n     basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the\n     License for the specific language governing rights and limitations\n     under the License.\n\n*******************************************************************************}\n//------------------------------------------------------------------------------\n// Placeholder for future expansion\n//------------------------------------------------------------------------------\nunit wbDefinitionsTES3;\n\ninterface\n\nuses\n  wbInterface;\n\nvar\n\twbPKDTFlags: IwbFlagsDef;\n\twbServiceFlags: IwbFlagsDef;\n\n\twbAxisEnum: IwbEnumDef;\n\twbBlendModeEnum: IwbEnumDef;\n\twbBlendOpEnum: IwbEnumDef;\n\twbCrimeTypeEnum: IwbEnumDef;\n\twbFormTypeEnum: IwbEnumDef;\n\twbFunctionsEnum: IwbEnumDef;\n\twbMagicSchoolEnum: IwbEnumDef;\n\twbMusicEnum: IwbEnumDef;\n\twbOBMEResolutionInfo: IwbEnumDef;\n\twbPKDTType: IwbEnumDef;\n\twbQuadrantEnum: IwbEnumDef;\n\twbSexEnum: IwbEnumDef;\n\twbSkillEnum: IwbEnumDef;\n\twbSoulGemEnum: IwbEnumDef;\n\twbSpecializationEnum: IwbEnumDef;\n\twbZTestFuncEnum: IwbEnumDef;\n\nprocedure DefineTES3;\n\nimplementation\n\nuses\n  Types,\n  Classes,\n  SysUtils,\n  Math,\n  Variants;\n\nconst\n  ACBS : TwbSignature = 'ACBS';\n  ACHR : TwbSignature = 'ACHR';\n  ACRE : TwbSignature = 'ACRE';\n  TRGT : TwbSignature = 'TRGT';\n  ACTI : TwbSignature = 'ACTI';\n  AIDT : TwbSignature = 'AIDT';\n  ALCH : TwbSignature = 'ALCH';\n  AMMO : TwbSignature = 'AMMO';\n  ANAM : TwbSignature = 'ANAM';\n  ANIO : TwbSignature = 'ANIO';\n  APPA : TwbSignature = 'APPA';\n  ARMO : TwbSignature = 'ARMO';\n  ATTR : TwbSignature = 'ATTR';\n  ATXT : TwbSignature = 'ATXT';\n  BMDT : TwbSignature = 'BMDT';\n  BNAM : TwbSignature = 'BNAM';\n  BOOK : TwbSignature = 'BOOK';\n  BSGN : TwbSignature = 'BSGN';\n  BTXT : TwbSignature = 'BTXT';\n  CELL : TwbSignature = 'CELL';\n  CLAS : TwbSignature = 'CLAS';\n  CLMT : TwbSignature = 'CLMT';\n  CLOT : TwbSignature = 'CLOT';\n  CNAM : TwbSignature = 'CNAM';\n  CNTO : TwbSignature = 'CNTO';\n  CONT : TwbSignature = 'CONT';\n  CREA : TwbSignature = 'CREA';\n  CSAD : TwbSignature = 'CSAD';\n  CSCR : TwbSignature = 'CSCR';\n  CSDC : TwbSignature = 'CSDC';\n  CSDI : TwbSignature = 'CSDI';\n  CSDT : TwbSignature = 'CSDT';\n  CSTD : TwbSignature = 'CSTD';\n  CSTY : TwbSignature = 'CSTY';\n  CTDA : TwbSignature = 'CTDA';\n  CTDT : TwbSignature = 'CTDT';\n  DATA : TwbSignature = 'DATA';\n  DATX : TwbSignature = 'DATX';\n  DELE : TwbSignature = 'DELE';\n  DESC : TwbSignature = 'DESC';\n  DIAL : TwbSignature = 'DIAL';\n  DNAM : TwbSignature = 'DNAM';\n  DOOR : TwbSignature = 'DOOR';\n  EDID : TwbSignature = 'EDID';\n  EDDX : TwbSignature = 'EDDX';\n  EFID : TwbSignature = 'EFID';\n  EFIT : TwbSignature = 'EFIT';\n  ACVA : TwbSignature = 'ACVA';\n  EFII : TwbSignature = 'EFII';\n  EFXX : TwbSignature = 'EFXX';\n  EFIX : TwbSignature = 'EFIX';\n  EFME : TwbSignature = 'EFME';\n  EFSH : TwbSignature = 'EFSH';\n  ENAM : TwbSignature = 'ENAM';\n  ENCH : TwbSignature = 'ENCH';\n  ENIT : TwbSignature = 'ENIT';\n  ESCE : TwbSignature = 'ESCE';\n  EYES : TwbSignature = 'EYES';\n  FACT : TwbSignature = 'FACT';\n  FGGA : TwbSignature = 'FGGA';\n  FGGS : TwbSignature = 'FGGS';\n  FGTS : TwbSignature = 'FGTS';\n  FLOR : TwbSignature = 'FLOR';\n  FLTV : TwbSignature = 'FLTV';\n  FNAM : TwbSignature = 'FNAM';\n  FULL : TwbSignature = 'FULL';\n  FURN : TwbSignature = 'FURN';\n  GLOB : TwbSignature = 'GLOB';\n  GMST : TwbSignature = 'GMST';\n  GNAM : TwbSignature = 'GNAM';\n  GRAS : TwbSignature = 'GRAS';\n  HAIR : TwbSignature = 'HAIR';\n  HCLR : TwbSignature = 'HCLR';\n  HEDR : TwbSignature = 'HEDR';\n  HNAM : TwbSignature = 'HNAM';\n  ICO2 : TwbSignature = 'ICO2';\n  ICON : TwbSignature = 'ICON';\n  IDLE : TwbSignature = 'IDLE';\n  NULL : TwbSignature = 'NULL';\n  INAM : TwbSignature = 'INAM';\n  INDX : TwbSignature = 'INDX';\n  INFO : TwbSignature = 'INFO';\n  INGR : TwbSignature = 'INGR';\n  JNAM : TwbSignature = 'JNAM';\n  KEYM : TwbSignature = 'KEYM';\n  KFFZ : TwbSignature = 'KFFZ';\n  LAND : TwbSignature = 'LAND';\n  LIGH : TwbSignature = 'LIGH';\n  LNAM : TwbSignature = 'LNAM';\n  LSCR : TwbSignature = 'LSCR';\n  LTEX : TwbSignature = 'LTEX';\n  LVLC : TwbSignature = 'LVLC';\n  LVLD : TwbSignature = 'LVLD';\n  LVLF : TwbSignature = 'LVLF';\n  LVLI : TwbSignature = 'LVLI';\n  LVLO : TwbSignature = 'LVLO';\n  LVSP : TwbSignature = 'LVSP';\n  MAST : TwbSignature = 'MAST';\n  MGEF : TwbSignature = 'MGEF';\n  MISC : TwbSignature = 'MISC';\n  MNAM : TwbSignature = 'MNAM';\n  MO2B : TwbSignature = 'MO2B';\n  MO2T : TwbSignature = 'MO2T';\n  MO3B : TwbSignature = 'MO3B';\n  MO3T : TwbSignature = 'MO3T';\n  MO4B : TwbSignature = 'MO4B';\n  MO4T : TwbSignature = 'MO4T';\n  MOD2 : TwbSignature = 'MOD2';\n  MOD3 : TwbSignature = 'MOD3';\n  MOD4 : TwbSignature = 'MOD4';\n  MODB : TwbSignature = 'MODB';\n  MODL : TwbSignature = 'MODL';\n  MODT : TwbSignature = 'MODT';\n  NAM0 : TwbSignature = 'NAM0';\n  NAM1 : TwbSignature = 'NAM1';\n  NAM2 : TwbSignature = 'NAM2';\n  NAM9 : TwbSignature = 'NAM9';\n  NAME : TwbSignature = 'NAME';\n  NIFT : TwbSignature = 'NIFT';\n  NIFZ : TwbSignature = 'NIFZ';\n  NPC_ : TwbSignature = 'NPC_';\n  OFST : TwbSignature = 'OFST';\n  OBME : TwbSignature = 'OBME';\n  ONAM : TwbSignature = 'ONAM';\n  PACK : TwbSignature = 'PACK';\n  PFIG : TwbSignature = 'PFIG';\n  PFPC : TwbSignature = 'PFPC';\n  PGAG : TwbSignature = 'PGAG';\n  PGRD : TwbSignature = 'PGRD';\n  PGRI : TwbSignature = 'PGRI';\n  PGRL : TwbSignature = 'PGRL';\n  PGRP : TwbSignature = 'PGRP';\n  PGRR : TwbSignature = 'PGRR';\n  PKDT : TwbSignature = 'PKDT';\n  PKID : TwbSignature = 'PKID';\n  PLDT : TwbSignature = 'PLDT';\n  PNAM : TwbSignature = 'PNAM';\n  PSDT : TwbSignature = 'PSDT';\n  PTDT : TwbSignature = 'PTDT';\n  QNAM : TwbSignature = 'QNAM';\n  QSDT : TwbSignature = 'QSDT';\n  QSTA : TwbSignature = 'QSTA';\n  QSTI : TwbSignature = 'QSTI';\n  QSTR : TwbSignature = 'QSTR';\n  TPIC : TwbSignature = 'TPIC';\n  QUST : TwbSignature = 'QUST';\n  RACE : TwbSignature = 'RACE';\n  RCLR : TwbSignature = 'RCLR';\n  RDAT : TwbSignature = 'RDAT';\n  RDGS : TwbSignature = 'RDGS';\n  RDMD : TwbSignature = 'RDMD';\n  RDMP : TwbSignature = 'RDMP';\n  RDOT : TwbSignature = 'RDOT';\n  RDSD : TwbSignature = 'RDSD';\n  RDWT : TwbSignature = 'RDWT';\n  REFR : TwbSignature = 'REFR';\n  PLYR : TwbSignature = 'PLYR';\n  REGN : TwbSignature = 'REGN';\n  RNAM : TwbSignature = 'RNAM';\n  ROAD : TwbSignature = 'ROAD';\n  RPLD : TwbSignature = 'RPLD';\n  RPLI : TwbSignature = 'RPLI';\n  SBSP : TwbSignature = 'SBSP';\n  SCDA : TwbSignature = 'SCDA';\n  SCHD : TwbSignature = 'SCHD';\n  SCHR : TwbSignature = 'SCHR';\n  SCIT : TwbSignature = 'SCIT';\n  SCPT : TwbSignature = 'SCPT';\n  SCRI : TwbSignature = 'SCRI';\n  SCRO : TwbSignature = 'SCRO';\n  SCRV : TwbSignature = 'SCRV';\n  SCTX : TwbSignature = 'SCTX';\n  SCVR : TwbSignature = 'SCVR';\n  SGST : TwbSignature = 'SGST';\n  SKIL : TwbSignature = 'SKIL';\n  SLCP : TwbSignature = 'SLCP';\n  SLGM : TwbSignature = 'SLGM';\n  SLSD : TwbSignature = 'SLSD';\n  SNAM : TwbSignature = 'SNAM';\n  SNDD : TwbSignature = 'SNDD';\n  SNDX : TwbSignature = 'SNDX';\n  SOUL : TwbSignature = 'SOUL';\n  SOUN : TwbSignature = 'SOUN';\n  SPEL : TwbSignature = 'SPEL';\n  SPIT : TwbSignature = 'SPIT';\n  SPLO : TwbSignature = 'SPLO';\n  STAT : TwbSignature = 'STAT';\n  TCLF : TwbSignature = 'TCLF';\n  TCLT : TwbSignature = 'TCLT';\n  TES3 : TwbSignature = 'TES3';\n  TNAM : TwbSignature = 'TNAM';\n  TRDT : TwbSignature = 'TRDT';\n  TREE : TwbSignature = 'TREE';\n  UNAM : TwbSignature = 'UNAM';\n  VCLR : TwbSignature = 'VCLR';\n  VHGT : TwbSignature = 'VHGT';\n  VNAM : TwbSignature = 'VNAM';\n  VNML : TwbSignature = 'VNML';\n  VTEX : TwbSignature = 'VTEX';\n  VTXT : TwbSignature = 'VTXT';\n  WATR : TwbSignature = 'WATR';\n  WEAP : TwbSignature = 'WEAP';\n  WLST : TwbSignature = 'WLST';\n  WNAM : TwbSignature = 'WNAM';\n  WRLD : TwbSignature = 'WRLD';\n  WTHR : TwbSignature = 'WTHR';\n  XACT : TwbSignature = 'XACT';\n  XCCM : TwbSignature = 'XCCM';\n  XCHG : TwbSignature = 'XCHG';\n  XCLC : TwbSignature = 'XCLC';\n  XCLL : TwbSignature = 'XCLL';\n  XCLR : TwbSignature = 'XCLR';\n  XCLW : TwbSignature = 'XCLW';\n  XCMT : TwbSignature = 'XCMT';\n  XCNT : TwbSignature = 'XCNT';\n  XCWT : TwbSignature = 'XCWT';\n  XESP : TwbSignature = 'XESP';\n  XGLB : TwbSignature = 'XGLB';\n  XHLT : TwbSignature = 'XHLT';\n  XHRS : TwbSignature = 'XHRS';\n  XLCM : TwbSignature = 'XLCM';\n  XLOC : TwbSignature = 'XLOC';\n  XLOD : TwbSignature = 'XLOD';\n  XMRC : TwbSignature = 'XMRC';\n  XMRK : TwbSignature = 'XMRK';\n  XNAM : TwbSignature = 'XNAM';\n  XOWN : TwbSignature = 'XOWN';\n  XPCI : TwbSignature = 'XPCI';\n  XRGD : TwbSignature = 'XRGD';\n  XRNK : TwbSignature = 'XRNK';\n  XRTM : TwbSignature = 'XRTM';\n  XSCL : TwbSignature = 'XSCL';\n  XSED : TwbSignature = 'XSED';\n  XSOL : TwbSignature = 'XSOL';\n  XTEL : TwbSignature = 'XTEL';\n  XTRG : TwbSignature = 'XTRG';\n  XXXX : TwbSignature = 'XXXX';\n  ZNAM : TwbSignature = 'ZNAM';\n\nvar\n  wbEDID: IwbSubRecordDef;\n  wbXOWN: IwbSubRecordDef;\n  wbXGLB: IwbSubRecordDef;\n  wbXRGD: IwbSubRecordDef;\n  wbSLSD: IwbSubRecordDef;\n  wbBodyDataIndex: IwbSubRecordDef;\n  wbSPLO: IwbSubRecordDef;\n  wbSPLOs: IwbSubRecordArrayDef;\n  wbCNTO: IwbSubRecordDef;\n  wbCNTOs: IwbSubRecordArrayDef;\n  wbCSDT: IwbSubRecordStructDef;\n  wbCSDTs: IwbSubRecordArrayDef;\n  wbFULL: IwbSubRecordDef;\n  wbFULLReq: IwbSubRecordDef;\n  wbXNAM: IwbSubRecordDef;\n  wbXNAMs: IwbSubRecordArrayDef;\n  wbDESC: IwbSubRecordDef;\n  wbXSCL: IwbSubRecordDef;\n  wbDATAPosRot : IwbSubRecordDef;\n  wbPosRot : IwbStructDef;\n  wbMODL: IwbSubRecordStructDef;\n  wbCTDA: IwbSubRecordUnionDef;\n  wbSCHR: IwbSubRecordUnionDef;\n  wbCTDAs: IwbSubRecordArrayDef;\n  wbSCROs: IwbSubRecordArrayDef;\n  wbPGRP: IwbSubRecordDef;\n  wbResultScript: IwbSubRecordStructDef;\n//  wbResultScriptOld: IwbSubRecordStructDef;\n  wbSCRI: IwbSubRecordDef;\n  wbFaceGen: IwbSubRecordStructDef;\n  wbENAM: IwbSubRecordDef;\n  wbFGGS: IwbSubRecordDef;\n  wbXLOD: IwbSubRecordDef;\n  wbXESP: IwbSubRecordDef;\n  wbICON: IwbSubRecordDef;\n  wbEFID: IwbSubRecordDef;\n  wbEFIDOBME: IwbSubRecordDef;\n  wbEFIT: IwbSubRecordDef;\n  wbEFITOBME: IwbSubRecordDef;\n  wbEFIX: IwbSubRecordDef;\n  wbSCIT: IwbSubRecordStructDef;\n  wbSCITOBME: IwbSubRecordStructDef;\n  wbEffects: IwbSubRecordUnionDef;\n\nfunction wbClmtMoonsPhaseLength(aInt: Int64; const aElement: IwbElement; aType: TwbCallbackType): string;\nvar\n  PhaseLength : Byte;\n  Masser      : Boolean;\n  Secunda     : Boolean;\nbegin\n  Result := '';\n  if aType = ctToSortKey then begin\n    Result := IntToHex64(aInt, 2);\n  end else if aType = ctToStr then begin\n    PhaseLength := aInt mod 64;\n    Masser := (aInt and 64) <> 0;\n    Secunda := (aInt and 128) <> 0;\n    if Masser then\n      if Secunda then\n        Result := 'Masser, Secunda / '\n      else\n        Result := 'Masser / '\n    else\n      if Secunda then\n        Result := 'Secunda / '\n      else\n        Result := 'No Moon / ';\n    Result := Result + IntToStr(PhaseLength);\n  end;\nend;\n\nfunction wbClmtTime(aInt: Int64; const aElement: IwbElement; aType: TwbCallbackType): string;\nbegin\n  Result := '';\n  if aType = ctToSortKey then\n    Result := IntToHex64(aInt, 4)\n  else if aType = ctToStr then\n    Result := TimeToStr( EncodeTime(aInt div 6, (aInt mod 6) * 10, 0, 0) );\nend;\n\nvar\n  wbCtdaTypeFlags : IwbFlagsDef;\n\nfunction wbCtdaType(aInt: Int64; const aElement: IwbElement; aType: TwbCallbackType): string;\nvar\n  s: string;\nbegin\n  Result := '';\n  case aType of\n    ctToStr: begin\n      case aInt and $F0 of\n        $00 : Result := 'Equal to';\n        $20 : Result := 'Not equal to';\n        $40 : Result := 'Greater than';\n        $60 : Result := 'Greater than or equal to';\n        $80 : Result := 'Less than';\n        $A0 : Result := 'Less than or equal to';\n      else\n        Result := '<Unknown Compare operator>'\n      end;\n\n      if not Assigned(wbCtdaTypeFlags) then\n        wbCtdaTypeFlags := wbFlags([\n          {0x01} 'Or',\n          {0x02} 'Run on target',\n          {0x04} 'Use global'\n        ]);\n\n      s := wbCtdaTypeFlags.ToString(aInt and $0F, aElement);\n\n      if s <> '' then\n        Result := Result + ' / ' + s;\n    end;\n    ctToSortKey: begin\n      Result := IntToHex64(aInt, 2);\n      Exit;\n    end;\n    ctCheck: begin\n      case aInt and $F0 of\n        $00, $20, $40, $60, $80, $A0 : Result := '';\n      else\n        Result := '<Unknown Compare operator>'\n      end;\n\n      if not Assigned(wbCtdaTypeFlags) then\n        wbCtdaTypeFlags := wbFlags([\n          {0x01} 'Or',\n          {0x02} 'Run on target',\n          {0x04} 'Use global'\n        ]);\n\n      s := wbCtdaTypeFlags.Check(aInt and $0F, aElement);\n\n      if s <> '' then\n        Result := Result + ' / ' + s;\n    end;\n  end;\nend;\n\nfunction wbIdleAnam(aInt: Int64; const aElement: IwbElement; aType: TwbCallbackType): string;\nbegin\n  Result := '';\n  case aType of\n    ctToStr: begin\n      case aInt and not $80 of\n        0: Result := 'Lower Body';\n        1: Result := 'Left Arm';\n        2: Result := 'Left Hand';\n        3: Result := 'Right Arm';\n        4: Result := 'Special Idle';\n        5: Result := 'Whole Body';\n        6: Result := 'Upper Body';\n      else\n        Result := '<Unknown: '+IntToStr(aInt and not $80)+'>';\n      end;\n\n      if (aInt and $80) = 0 then\n        Result := Result + ', Must return a file';\n    end;\n    ctToSortKey: begin\n      Result := IntToHex64(aInt, 2);\n    end;\n    ctCheck: begin\n      case aInt and not $80 of\n        0..6: Result := '';\n      else\n        Result := '<Unknown: '+IntToStr(aInt and not $80)+'>';\n      end;\n    end;\n  end;\nend;\n\nfunction wbScaledInt4ToStr(aInt: Int64; const aElement: IwbElement; aType: TwbCallbackType): string;\nconst\n  PlusMinus : array[Boolean] of string = ('+', '-');\nbegin\n  Result := '';\n  case aType of\n    ctToStr, ctToEditValue: Result := FloatToStrF(aInt / 10000, ffFixed, 99, 4);\n    ctToSortKey: begin\n      Result := FloatToStrF(aInt / 10000, ffFixed, 99, 4);\n      if Length(Result) < 22 then\n        Result := StringOfChar('0', 22 - Length(Result)) + Result;\n      Result := PlusMinus[aInt < 0] + Result;\n    end;\n    ctCheck: Result := '';\n  end;\nend;\n\nfunction wbScaledInt4ToInt(const aString: string; const aElement: IwbElement): Int64;\nvar\n  f: Extended;\nbegin\n  f := StrToFloat(aString);\n  f := f * 10000;\n  Result := Round(f);\nend;\n\nfunction wbHideFFFF(aInt: Int64; const aElement: IwbElement; aType: TwbCallbackType): string;\nbegin\n  Result := '';\n  if aType = ctToSortKey then\n    Result := IntToHex64(aInt, 4)\n  else if aType = ctToStr then\n    if aInt = $FFFF then\n      Result := 'None'\n    else\n      Result := IntToStr(aInt);\nend;\n\nfunction wbAtxtPosition(aInt: Int64; const aElement: IwbElement; aType: TwbCallbackType): string;\nbegin\n  Result := '';\n  if aType = ctToSortKey then\n    Result := IntToHex64(aInt div 17, 2) + IntToHex64(aInt mod 17, 2)\n  else if aType = ctCheck then begin\n    if (aInt < 0) or (aInt > 288) then\n      Result := '<Out of range: '+IntToStr(aInt)+'>'\n    else\n      Result := '';\n  end else if aType = ctToStr then\n    Result := IntToStr(aInt) + ' -> ' + IntToStr(aInt div 17) + ':' + IntToStr(aInt mod 17);\nend;\n\nfunction wbWthrDataClassification(aInt: Int64; const aElement: IwbElement; aType: TwbCallbackType): string;\nbegin\n  Result := '';\n  case aType of\n    ctToStr: begin\n      case aInt and not 192 of\n        0: Result := 'None';\n        1: Result := 'Pleasant';\n        2: Result := 'Cloudy';\n        3: Result := 'Rainy';\n        4: Result := 'Snow';\n      else\n        Result := '<Unknown: '+IntToStr(aInt and not 192)+'>';\n      end;\n    end;\n    ctToSortKey: begin\n      Result := IntToHex64(aInt, 2)\n    end;\n    ctCheck: begin\n      case aInt and not 192 of\n        0..4: Result := '';\n      else\n        Result := '<Unknown: '+IntToStr(aInt and not 192)+'>';\n      end;\n    end;\n  end;\nend;\n\nfunction wbGLOBFNAM(aInt: Int64; const aElement: IwbElement; aType: TwbCallbackType): string;\nbegin\n  Result := '';\n  case aType of\n    ctToStr: begin\n      case aInt of\n        Ord('s'): Result := 'Short';\n        Ord('l'): Result := 'Long';\n        Ord('f'): Result := 'Float';\n      else\n        Result := '<Unknown: '+IntToStr(aInt)+'>';\n      end;\n    end;\n    ctToSortKey: Result := Chr(aInt);\n    ctCheck: begin\n      case aInt of\n        Ord('s'), Ord('l'), Ord('f'): Result := '';\n      else\n        Result := '<Unknown: '+IntToStr(aInt)+'>';\n      end;\n    end;\n  end;\nend;\n\nfunction wbPlacedAddInfo(const aMainRecord: IwbMainRecord): string;\nvar\n  Rec: IwbRecord;\n  Container: IwbContainer;\n  s: string;\nbegin\n  Result := '';\n\n  Rec := aMainRecord.RecordBySignature['NAME'];\n  if Assigned(Rec) then begin\n    s := Trim(Rec.Value);\n    if s <> '' then\n      Result := 'places ' + s;\n  end;\n\n  Container := aMainRecord.Container;\n  while Assigned(Container) and (Container.ElementType <> etGroupRecord) do\n    Container := Container.Container;\n\n  if Assigned(Container) then begin\n    s := Trim(Container.Name);\n    if s <> '' then begin\n      if Result <> '' then\n        Result := Result + ' ';\n      Result := Result + 'in ' + s;\n    end;\n  end;\nend;\n\nfunction wbCellAddInfo(const aMainRecord: IwbMainRecord): string;\nvar\n  Rec: IwbRecord;\n  Container: IwbContainer;\n  GroupRecord : IwbGroupRecord;\n  s: string;\nbegin\n  Result := '';\n\n  Rec := aMainRecord.RecordBySignature['XCLC'];\n  if Assigned(Rec) then\n      Result := 'at ' + Rec.Elements[0].Value + ',' + Rec.Elements[1].Value;\n\n  Container := aMainRecord.Container;\n  while Assigned(Container) and not\n    (Supports(Container, IwbGroupRecord, GroupRecord) and (GroupRecord.GroupType = 1))  do\n    Container := Container.Container;\n\n  if Assigned(Container) then begin\n    s := wbFormID.ToString(GroupRecord.GroupLabel, aMainRecord);\n    if s <> '' then begin\n      if Result <> '' then\n        s := s + ' ';\n      Result := 'in ' + s + Result;\n    end;\n  end;\nend;\n\nfunction wbGMSTUnionDecider(aBasePtr: Pointer; aEndPtr: Pointer; const aElement: IwbElement): Integer;\nvar\n  rEDID: IwbRecord;\n  s: string;\nbegin\n  Result := 1;\n  rEDID := aElement.Container.RecordBySignature[EDID];\n  if Assigned(rEDID) then begin\n    s := rEDID.Value;\n    if Length(s) > 0 then\n      case s[1] of\n        's': Result := 0;\n        'f': Result := 2;\n      end;\n  end;\nend;\n\nfunction wbMISCActorValueDecider(aBasePtr: Pointer; aEndPtr: Pointer; const aElement: IwbElement): Integer;\nvar\n  MainRecord : IwbMainRecord;\nbegin\n  Result := 0;\n\n  if not Assigned(aElement) then\n    Exit;\n\n  MainRecord := aElement.ContainingMainRecord;\n  if not Assigned(MainRecord) then\n    Exit;\n\n  if (MainRecord.Flags._Flags and $000000C0) = $000000C0 then\n    Result := 1;\nend;\n\nfunction wbXLOCFillerDecider(aBasePtr: Pointer; aEndPtr: Pointer; const aElement: IwbElement): Integer;\nvar\n  Container: IwbContainer;\nbegin\n  Result := 0;\n  if not Assigned(aElement) then Exit;\n  Container := GetContainerFromUnion(aElement);\n  if not Assigned(Container) then Exit;\n\n  if Container.DataSize = 16 then\n    Result := 1;\nend;\n\nfunction wbPACKPKDTDecider(aBasePtr: Pointer; aEndPtr: Pointer; const aElement: IwbElement): Integer;\nvar\n  Container: IwbContainer;\nbegin\n  Result := 1;\n  if not Assigned(aElement) then Exit;\n  Container := GetContainerFromUnion(aElement);\n  if not Assigned(Container) then Exit;\n\n  if Container.DataSize = 4 then\n    Result := 0;\nend;\n\nfunction wbREFRXSEDDecider(aBasePtr: Pointer; aEndPtr: Pointer; const aElement: IwbElement): Integer;\nvar\n  Container: IwbContainer;\nbegin\n  Result := 0;\n  if not Assigned(aElement) then Exit;\n  Container := GetContainerFromUnion(aElement);\n  if not Assigned(Container) then Exit;\n\n  if Container.DataSize = 4 then\n    Result := 1;\nend;\n\n\ntype\n  TCTDAFunctionParamType = (\n    ptNone,\n    ptInteger,\n    ptVariableName,  //Integer\n    ptSex,           //Enum: Male, Female\n    ptActorValue,    //Enum: wbActorValue\n    ptCrimeType,     //?? Enum\n    ptAxis,          //?? Char\n    ptFormType,      //?? Enum\n    ptQuestStage,\n\n    ptObjectReference,    //REFR, ACHR, ACRE, PGRE\n    ptInventoryObject,    //ARMO, BOOK, MISC, WEAP, AMMO, KEYM, ALCH, NOTE, ARMA\n    ptActor,              //ACHR, ACRE\n    ptQuest,              //QUST\n    ptFaction,            //FACT\n    ptCell,               //CELL\n    ptClass,              //CLAS\n    ptRace,               //RACE\n    ptActorBase,          //NPC_, CREA\n    ptGlobal,             //GLOB\n    ptWeather,            //WTHR\n    ptPackage,            //PACK\n    ptOwnerOpt,           //FACT, NPC_\n    ptBirthsign,          //BSGN\n    ptFurniture,          //FURN\n    ptMagicItem,          //SPEL\n    ptMagicEffect,        //MGEF\n    ptWorldspace,         //WRLD\n    ptReferencableObject\n  );\n\n  PCTDAFunction = ^TCTDAFunction;\n  TCTDAFunction = record\n    Index: Integer;\n    Name: string;\n    ParamType1: TCTDAFunctionParamType;\n    ParamType2: TCTDAFunctionParamType;\n  end;\n\nconst\n  wbCTDAFunctions : array[0..168] of TCTDAFunction = (\n    (Index:   1; Name: 'GetDistance'; ParamType1: ptObjectReference),\n    (Index:   5; Name: 'GetLocked'),\n    (Index:   6; Name: 'GetPos'; ParamType1: ptAxis),\n    (Index:   8; Name: 'GetAngle'; ParamType1: ptAxis),\n    (Index:  10; Name: 'GetStartingPos'; ParamType1: ptAxis),\n    (Index:  11; Name: 'GetStartingAngle'; ParamType1: ptAxis),\n    (Index:  12; Name: 'GetSecondsPassed'),\n    (Index:  14; Name: 'GetActorValue'; ParamType1: ptActorValue),\n    (Index:  18; Name: 'GetCurrentTime'),\n    (Index:  24; Name: 'GetScale'),\n    (Index:  27; Name: 'GetLineOfSight'; ParamType1: ptObjectReference),\n    (Index:  32; Name: 'GetInSameCell'; ParamType1: ptObjectReference),\n    (Index:  35; Name: 'GetDisabled'),\n    (Index:  36; Name: 'MenuMode'; ParamType1: ptInteger),\n    (Index:  39; Name: 'GetDisease'),\n    (Index:  40; Name: 'GetVampire'),\n    (Index:  41; Name: 'GetClothingValue'),\n    (Index:  42; Name: 'SameFaction'; ParamType1: ptActor),\n    (Index:  43; Name: 'SameRace'; ParamType1: ptActor),\n    (Index:  44; Name: 'SameSex'; ParamType1: ptActor),\n    (Index:  45; Name: 'GetDetected'; ParamType1: ptActor),\n    (Index:  46; Name: 'GetDead'),\n    (Index:  47; Name: 'GetItemCount'; ParamType1: ptInventoryObject),\n    (Index:  48; Name: 'GetGold'),\n    (Index:  49; Name: 'GetSleeping'),\n    (Index:  50; Name: 'GetTalkedToPC'),\n    (Index:  53; Name: 'GetScriptVariable'; ParamType1: ptObjectReference; ParamType2: ptVariableName),\n    (Index:  56; Name: 'GetQuestRunning'; ParamType1: ptQuest),\n    (Index:  58; Name: 'GetStage'; ParamType1: ptQuest),\n    (Index:  59; Name: 'GetStageDone'; ParamType1: ptQuest; ParamType2: ptQuestStage),\n    (Index:  60; Name: 'GetFactionRankDifference'; ParamType1: ptFaction; ParamType2: ptActor),\n    (Index:  61; Name: 'GetAlarmed'),\n    (Index:  62; Name: 'IsRaining'),\n    (Index:  63; Name: 'GetAttacked'),\n    (Index:  64; Name: 'GetIsCreature'),\n    (Index:  65; Name: 'GetLockLevel'),\n    (Index:  66; Name: 'GetShouldAttack'; ParamType1: ptActor),\n    (Index:  67; Name: 'GetInCell'; ParamType1: ptCell),\n    (Index:  68; Name: 'GetIsClass'; ParamType1: ptClass),\n    (Index:  69; Name: 'GetIsRace'; ParamType1: ptRace),\n    (Index:  70; Name: 'GetIsSex'; ParamType1: ptSex),\n    (Index:  71; Name: 'GetInFaction'; ParamType1: ptFaction),\n    (Index:  72; Name: 'GetIsID'; ParamType1: ptReferencableObject),\n    (Index:  73; Name: 'GetFactionRank'; ParamType1: ptFaction),\n    (Index:  74; Name: 'GetGlobalValue'; ParamType1: ptGlobal),\n    (Index:  75; Name: 'IsSnowing'),\n    (Index:  76; Name: 'GetDisposition'; ParamType1: ptActor),\n    (Index:  77; Name: 'GetRandomPercent'),\n    (Index:  79; Name: 'GetQuestVariable'; ParamType1: ptQuest; ParamType2: ptVariableName),\n    (Index:  80; Name: 'GetLevel'),\n    (Index:  81; Name: 'GetArmorRating'),\n    (Index:  84; Name: 'GetDeadCount'; ParamType1: ptActorBase),\n    (Index:  91; Name: 'GetIsAlerted'),\n    (Index:  98; Name: 'GetPlayerControlsDisabled'),\n    (Index:  99; Name: 'GetHeadingAngle'; ParamType1: ptObjectReference),\n    (Index: 101; Name: 'IsWeaponOut'),\n    (Index: 102; Name: 'IsTorchOut'),\n    (Index: 103; Name: 'IsShieldOut'),\n    (Index: 104; Name: 'IsYielding'),\n    (Index: 106; Name: 'IsFacingUp'),\n    (Index: 107; Name: 'GetKnockedState'),\n    (Index: 108; Name: 'GetWeaponAnimType'),\n    (Index: 109; Name: 'GetWeaponSkillType'),\n    (Index: 110; Name: 'GetCurrentAIPackage'),\n    (Index: 111; Name: 'IsWaiting'),\n    (Index: 112; Name: 'IsIdlePlaying'),\n    (Index: 116; Name: 'GetCrimeGold'),\n    (Index: 122; Name: 'GetCrime'; ParamType1: ptActor; ParamType2: ptCrimeType),\n    (Index: 125; Name: 'IsGuard'),\n    (Index: 127; Name: 'CanPayCrimeGold'),\n    (Index: 128; Name: 'GetFatiguePercentage'),\n    (Index: 129; Name: 'GetPCIsClass'; ParamType1: ptClass),\n    (Index: 130; Name: 'GetPCIsRace'; ParamType1: ptRace),\n    (Index: 131; Name: 'GetPCIsSex'; ParamType1: ptSex),\n    (Index: 132; Name: 'GetPCInFaction'; ParamType1: ptFaction),\n    (Index: 133; Name: 'SameFactionAsPC'),\n    (Index: 134; Name: 'SameRaceAsPC'),\n    (Index: 135; Name: 'SameSexAsPC'),\n    (Index: 136; Name: 'GetIsReference'; ParamType1: ptObjectReference),\n    (Index: 141; Name: 'IsTalking'),\n    (Index: 142; Name: 'GetWalkSpeed'),\n    (Index: 143; Name: 'GetCurrentAIProcedure'),\n    (Index: 144; Name: 'GetTrespassWarningLevel'),\n    (Index: 145; Name: 'IsTrespassing'),\n    (Index: 146; Name: 'IsInMyOwnedCell'),\n    (Index: 147; Name: 'GetWindSpeed'),\n    (Index: 148; Name: 'GetCurrentWeatherPercent'),\n    (Index: 149; Name: 'GetIsCurrentWeather'; ParamType1: ptWeather),\n    (Index: 150; Name: 'IsContinuingPackagePCNear'),\n    (Index: 153; Name: 'CanHaveFlames'),\n    (Index: 154; Name: 'HasFlames'),\n    (Index: 157; Name: 'GetOpenState'),\n    (Index: 159; Name: 'GetSitting'),\n    (Index: 160; Name: 'GetFurnitureMarkerID'),\n    (Index: 161; Name: 'GetIsCurrentPackage'; ParamType1: ptPackage),\n    (Index: 162; Name: 'IsCurrentFurnitureRef'; ParamType1: ptObjectReference),\n    (Index: 163; Name: 'IsCurrentFurnitureObj'; ParamType1: ptFurniture),\n    (Index: 170; Name: 'GetDayOfWeek'),\n    (Index: 171; Name: 'IsPlayerInJail'),\n    (Index: 172; Name: 'GetTalkedToPCParam'; ParamType1: ptActor),\n    (Index: 175; Name: 'IsPCSleeping'),\n    (Index: 176; Name: 'IsPCAMurderer'),\n    (Index: 180; Name: 'GetDetectionLevel'; ParamType1: ptActor),\n    (Index: 182; Name: 'GetEquipped'; ParamType1: ptInventoryObject),\n    (Index: 185; Name: 'IsSwimming'),\n    (Index: 190; Name: 'GetAmountSoldStolen'),\n    (Index: 193; Name: 'GetPCExpelled'; ParamType1: ptFaction),\n    (Index: 195; Name: 'GetPCFactionMurder'; ParamType1: ptFaction),\n    (Index: 197; Name: 'GetPCFactionSteal'; ParamType1: ptFaction),\n    (Index: 199; Name: 'GetPCFactionAttack'; ParamType1: ptFaction),\n    (Index: 201; Name: 'GetPCFactionSubmitAuthority'; ParamType1: ptFaction),\n    (Index: 203; Name: 'GetDestroyed'),\n    (Index: 214; Name: 'HasMagicEffect'; ParamType1: ptMagicEffect),\n    (Index: 215; Name: 'GetDoorDefaultOpen'),\n    (Index: 223; Name: 'IsSpellTarget'; ParamType1: ptMagicItem),\n    (Index: 224; Name: 'GetIsPlayerBirthsign'; ParamType1: ptBirthsign),\n    (Index: 225; Name: 'GetPersuasionNumber'),\n    (Index: 227; Name: 'HasVampireFed'),\n    (Index: 228; Name: 'GetIsClassDefault'; ParamType1: ptClass),\n    (Index: 229; Name: 'GetClassDefaultMatch'),\n    (Index: 230; Name: 'GetInCellParam'; ParamType1: ptCell; ParamType2: ptObjectReference),\n    (Index: 237; Name: 'GetIsGhost'),\n    (Index: 242; Name: 'GetUnconscious'),\n    (Index: 244; Name: 'GetRestrained'),\n    (Index: 246; Name: 'GetIsUsedItem'; ParamType1: ptReferencableObject),\n    (Index: 247; Name: 'GetIsUsedItemType'; ParamType1: ptFormType),\n    (Index: 249; Name: 'GetPCFame'),\n    (Index: 251; Name: 'GetPCInfamy'),\n    (Index: 254; Name: 'GetIsPlayableRace'),\n    (Index: 255; Name: 'GetOffersServicesNow'),\n    (Index: 258; Name: 'GetUsedItemLevel'),\n    (Index: 259; Name: 'GetUsedItemActivate'),\n    (Index: 264; Name: 'GetBarterGold'),\n    (Index: 265; Name: 'IsTimePassing'),\n    (Index: 266; Name: 'IsPleasant'),\n    (Index: 267; Name: 'IsCloudy'),\n    (Index: 274; Name: 'GetArmorRatingUpperBody'),\n    (Index: 277; Name: 'GetBaseActorValue'; ParamType1: ptActorValue),\n    (Index: 278; Name: 'IsOwner'; ParamType1: ptOwnerOpt),\n    (Index: 280; Name: 'IsCellOwner'; ParamType1: ptCell; ParamType2: ptOwnerOpt),\n    (Index: 282; Name: 'IsHorseStolen'),\n    (Index: 285; Name: 'IsLeftUp'),\n    (Index: 286; Name: 'IsSneaking'),\n    (Index: 287; Name: 'IsRunning'),\n    (Index: 288; Name: 'GetFriendHit'; ParamType1: ptActor),\n    (Index: 289; Name: 'IsInCombat'),\n    (Index: 300; Name: 'IsInInterior'),\n    (Index: 305; Name: 'GetInvestmentGold'),\n    (Index: 306; Name: 'IsActorUsingATorch'),\n    (Index: 309; Name: 'IsXBox'),\n    (Index: 310; Name: 'GetInWorldspace'; ParamType1: ptWorldSpace),\n    (Index: 312; Name: 'GetPCMiscStat'; ParamType1: ptInteger),\n    (Index: 313; Name: 'IsActorEvil'),\n    (Index: 314; Name: 'IsActorAVictim'),\n    (Index: 315; Name: 'GetTotalPersuasionNumber'),\n    (Index: 318; Name: 'GetIdleDoneOnce'),\n    (Index: 320; Name: 'GetNoRumors'),\n    (Index: 323; Name: 'WhichServiceMenu'),\n    (Index: 327; Name: 'IsRidingHorse'),\n    (Index: 329; Name: 'IsTurnArrest'),\n    (Index: 332; Name: 'IsInDangerousWater'),\n    (Index: 338; Name: 'GetIgnoreFriendlyHits'),\n    (Index: 339; Name: 'IsPlayersLastRiddenHorse'),\n    (Index: 353; Name: 'IsActor'),\n    (Index: 354; Name: 'IsEssential'),\n    (Index: 358; Name: 'IsPlayerMovingIntoNewSpace'),\n    (Index: 361; Name: 'GetTimeDead'),\n    (Index: 362; Name: 'GetPlayerHasLastRiddenHorse'),\n    (Index: 365; Name: 'GetPlayerInSEWorld')\n  );\n\nvar\n  wbCTDAFunctionEditInfo : string;\n\nfunction wbCTDAParamDescFromIndex(aIndex: Integer): PCTDAFunction;\nvar\n  L, H, I, C: Integer;\nbegin\n  Result := nil;\n\n  L := Low(wbCTDAFunctions);\n  H := High(wbCTDAFunctions);\n  while L <= H do begin\n    I := (L + H) shr 1;\n    C := CmpW32(wbCTDAFunctions[I].Index, aIndex);\n    if C < 0 then\n      L := I + 1\n    else begin\n      H := I - 1;\n      if C = 0 then begin\n        L := I;\n        Result := @wbCTDAFunctions[L];\n      end;\n    end;\n  end;\nend;\n\nfunction wbCTDACompValueDecider(aBasePtr: Pointer; aEndPtr: Pointer; const aElement: IwbElement): Integer;\nvar\n  Container: IwbContainer;\nbegin\n  Result := 0;\n  if not Assigned(aElement) then Exit;\n  Container := GetContainerFromUnion(aElement);\n  if not Assigned(Container) then Exit;\n\n  if Integer(Container.ElementByName['Type'].NativeValue) and $04 <> 0 then\n    Result := 1;\nend;\n\nfunction wbEFITOBMEParamDecider(aBasePtr: Pointer; aEndPtr: Pointer; const aElement: IwbElement): Integer;\nvar\n  ParamInfo: Variant;\n  Container: IwbContainer;\nbegin\n  Result := 0;\n  if not Assigned(aElement) then Exit;\n  Container := GetContainerFromUnion(aElement);\n  if not Assigned(Container) then Exit;\n\n  ParamInfo := Container.ElementNativeValues['..\\EFME\\EFIT Param Info'];\n  if VarIsNull(ParamInfo) or VarIsEmpty(ParamInfo) then\n  else\n    Result := ParamInfo;\nend;\n\nfunction wbEFIXParamDecider(aBasePtr: Pointer; aEndPtr: Pointer; const aElement: IwbElement): Integer;\nvar\n  ParamInfo: Variant;\n  Container: IwbContainer;\nbegin\n  Result := 0;\n  if not Assigned(aElement) then Exit;\n  Container := GetContainerFromUnion(aElement);\n  if not Assigned(Container) then Exit;\n\n  ParamInfo := Container.ElementNativeValues['..\\EFME\\EFIX Param Info'];\n  if VarIsNull(ParamInfo) or VarIsEmpty(ParamInfo) then\n  else\n    Result := ParamInfo;\nend;\n\nfunction wbCTDAParam1Decider(aBasePtr: Pointer; aEndPtr: Pointer; const aElement: IwbElement): Integer;\nvar\n  Desc: PCTDAFunction;\n  Container: IwbContainer;\nbegin\n  Result := 0;\n  if not Assigned(aElement) then Exit;\n  Container := GetContainerFromUnion(aElement);\n  if not Assigned(Container) then Exit;\n\n  Desc := wbCTDAParamDescFromIndex(Container.ElementByName['Function'].NativeValue);\n  if Assigned(Desc) then\n    Result := Succ(Integer(Desc.ParamType1));\nend;\n\nfunction wbCTDAParam2Decider(aBasePtr: Pointer; aEndPtr: Pointer; const aElement: IwbElement): Integer;\nvar\n  Desc: PCTDAFunction;\n  Container: IwbContainer;\nbegin\n  Result := 0;\n  if not Assigned(aElement) then Exit;\n  Container := GetContainerFromUnion(aElement);\n  if not Assigned(Container) then Exit;\n\n  Desc := wbCTDAParamDescFromIndex(Container.ElementByName['Function'].NativeValue);\n  if Assigned(Desc) then\n    Result := Succ(Integer(Desc.ParamType2));\nend;\n{\nfunction wbCTDAFunction(aInt: Int64; const aElement: IwbElement; aType: TwbCallbackType): string;\nvar\n  Desc: PCTDAFunction;\nbegin\n  Result := '';\n  case aType of\n    ctToStr: begin\n      Desc := wbCTDAParamDescFromIndex(aInt);\n      if Assigned(Desc) then\n        Result := Desc.Name\n      else\n        Result := '<Unknown: '+IntToStr(aInt)+'>';\n    end;\n    ctToSortKey: Result := IntToHex(aInt, 8);\n    ctCheck: begin\n      Desc := wbCTDAParamDescFromIndex(aInt);\n      if Assigned(Desc) then\n        Result := ''\n      else\n        Result := '<Unknown: '+IntToStr(aInt)+'>';\n    end;\n  end;\nend;\n}\nfunction wbCTDAFunctionToStr(aInt: Int64; const aElement: IwbElement; aType: TwbCallbackType): string;\nvar\n  Desc : PCTDAFunction;\n  i    : Integer;\nbegin\n  Result := '';\n  case aType of\n    ctToStr, ctToEditValue: begin\n      Desc := wbCTDAParamDescFromIndex(aInt);\n      if Assigned(Desc) then\n        Result := Desc.Name\n      else if aType = ctToEditValue then\n        Result := IntToStr(aInt)\n      else\n        Result := '<Unknown: '+IntToStr(aInt)+'>';\n    end;\n    ctToSortKey: Result := IntToHex(aInt, 8);\n    ctCheck: begin\n      Desc := wbCTDAParamDescFromIndex(aInt);\n      if Assigned(Desc) then\n        Result := ''\n      else\n        Result := '<Unknown: '+IntToStr(aInt)+'>';\n    end;\n    ctEditType:\n      Result := 'ComboBox';\n    ctEditInfo: begin\n      Result := wbCTDAFunctionEditInfo;\n      if Result = '' then begin\n        with TStringList.Create do try\n          for i := Low(wbCTDAFunctions) to High(wbCTDAFunctions) do\n            Add(wbCTDAFunctions[i].Name);\n          Sort;\n          Result := CommaText;\n        finally\n          Free;\n        end;\n        wbCTDAFunctionEditInfo := Result;\n      end;\n    end;\n  end;\nend;\n\nfunction wbCTDAFunctionToInt(const aString: string; const aElement: IwbElement): Int64;\nvar\n  i: Integer;\nbegin\n  for i := Low(wbCTDAFunctions) to High(wbCTDAFunctions) do\n    with wbCTDAFunctions[i] do\n      if SameText(Name, aString) then begin\n        Result := Index;\n        Exit;\n      end;\n  Result := StrToInt64(aString);\nend;\n\nfunction wbCTDAParam2VariableNameToStr(aInt: Int64; const aElement: IwbElement; aType: TwbCallbackType): string;\nvar\n  Container  : IwbContainerElementRef;\n  Param1     : IwbElement;\n  MainRecord : IwbMainRecord;\n  BaseRecord : IwbMainRecord;\n  ScriptRef  : IwbElement;\n  Script     : IwbMainRecord;\n  Variables  : TStringList;\n  LocalVars  : IwbContainerElementRef;\n  LocalVar   : IwbContainerElementRef;\n  i, j       : Integer;\n  s          : string;\nbegin\n  case aType of\n    ctToStr: Result := IntToStr(aInt) + ' <Warning: Could not resolve Parameter 1>';\n    ctToEditValue: Result := IntToStr(aInt);\n    ctToSortKey: begin\n      Result := IntToHex64(aInt, 8);\n      Exit;\n    end;\n    ctCheck: Result := '<Warning: Could not resolve Parameter 1>';\n    ctEditType: Result := '';\n    ctEditInfo: Result := '';\n  end;\n\n  if not Assigned(aElement) then Exit;\n  Container := GetContainerRefFromUnionOrValue(aElement);\n  if not Assigned(Container) then Exit;\n\n  Param1 := Container.ElementByName['Parameter #1'];\n\n  if not Assigned(Param1) then\n    Exit;\n\n  MainRecord := nil;\n  if not Supports(Param1.LinksTo, IwbMainRecord, MainRecord) then\n    Exit;\n{    if Param1.NativeValue = 0 then\n      if Supports(Container.Container, IwbContainerElementRef, Container) then\n        for i := 0 to Pred(Container.ElementCount) do\n          if Supports(Container.Elements[i], IwbContainerElementRef, Container2) then\n            if SameText(Container2.ElementValues['Function'], 'GetIsID') then begin\n              Param1 := Container2.ElementByName['Parameter #1'];\n              if Supports(Param1.LinksTo, IwbMainRecord, MainRecord) then\n                Break;\n            end;}\n\n  if not Assigned(MainRecord) then\n    Exit;\n\n  BaseRecord := MainRecord.BaseRecord;\n  if Assigned(BaseRecord) then\n    MainRecord := BaseRecord;\n\n  ScriptRef := MainRecord.RecordBySignature['SCRI'];\n\n  if not Assigned(ScriptRef) then begin\n    case aType of\n      ctToStr: Result := IntToStr(aInt) + ' <Warning: \"'+MainRecord.ShortName+'\" does not contain a SCRI subrecord>';\n      ctCheck: Result := '<Warning: \"'+MainRecord.ShortName+'\" does not contain a SCRI subrecord>';\n    end;\n    Exit;\n  end;\n\n  if not Supports(ScriptRef.LinksTo, IwbMainRecord, Script) then begin\n    case aType of\n      ctToStr: Result := IntToStr(aInt) + ' <Warning: \"'+MainRecord.ShortName+'\" does not have a valid script>';\n      ctCheck: Result := '<Warning: \"'+MainRecord.ShortName+'\" does not have a valid script>';\n    end;\n    Exit;\n  end;\n\n  case aType of\n    ctEditType: begin\n      Result := 'ComboBox';\n      Exit;\n    end;\n    ctEditInfo:\n      Variables := TStringList.Create;\n  else\n    Variables := nil;\n  end;\n  try\n    if Supports(Script.ElementByName['Local Variables'], IwbContainerElementRef, LocalVars) then begin\n      for i := 0 to Pred(LocalVars.ElementCount) do\n        if Supports(LocalVars.Elements[i], IwbContainerElementRef, LocalVar) then begin\n          j := LocalVar.ElementNativeValues['SLSD\\Index'];\n          s := LocalVar.ElementNativeValues['SCVR'];\n          if Assigned(Variables) then\n            Variables.AddObject(s, TObject(j))\n          else if j = aInt then begin\n            case aType of\n              ctToStr, ctToEditValue: Result := s;\n              ctCheck: Result := '';\n            end;\n            Exit;\n          end;\n        end;\n    end;\n\n    case aType of\n      ctToStr: Result := IntToStr(aInt) + ' <Warning: Variable Index not found in \"' + Script.Name + '\">';\n      ctCheck: Result := '<Warning: Variable Index not found in \"' + Script.Name + '\">';\n      ctEditInfo: begin\n        Variables.Sort;\n        Result := Variables.CommaText;\n      end;\n    end;\n  finally\n    FreeAndNil(Variables);\n  end;\nend;\n\nfunction wbCTDAParam2VariableNameToInt(const aString: string; const aElement: IwbElement): Int64;\nvar\n  Container  : IwbContainerElementRef;\n  Param1     : IwbElement;\n  MainRecord : IwbMainRecord;\n  BaseRecord : IwbMainRecord;\n  ScriptRef  : IwbElement;\n  Script     : IwbMainRecord;\n  LocalVars  : IwbContainerElementRef;\n  LocalVar   : IwbContainerElementRef;\n  i, j       : Integer;\n  s          : string;\nbegin\n  Result := StrToInt64Def(aString, Low(Cardinal));\n  if Result <> Low(Cardinal) then\n    Exit;\n\n  if not Assigned(aElement) then\n    raise Exception.Create('aElement not specified');\n\n  Container := GetContainerRefFromUnionOrValue(aElement);\n\n  if not Assigned(Container) then\n    raise Exception.Create('Container not assigned');\n\n  Param1 := Container.ElementByName['Parameter #1'];\n\n  if not Assigned(Param1) then\n    raise Exception.Create('Could not find \"Parameter #1\"');\n\n  if not Supports(Param1.LinksTo, IwbMainRecord, MainRecord) then\n    raise Exception.Create('\"Parameter #1\" does not reference a valid main record');\n\n  BaseRecord := MainRecord.BaseRecord;\n  if Assigned(BaseRecord) then\n    MainRecord := BaseRecord;\n\n  ScriptRef := MainRecord.RecordBySignature['SCRI'];\n\n  if not Assigned(ScriptRef) then\n    raise Exception.Create('\"'+MainRecord.ShortName+'\" does not contain a SCRI subrecord');\n\n  if not Supports(ScriptRef.LinksTo, IwbMainRecord, Script) then\n    raise Exception.Create('\"'+MainRecord.ShortName+'\" does not have a valid script');\n\n  if Supports(Script.ElementByName['Local Variables'], IwbContainerElementRef, LocalVars) then begin\n    for i := 0 to Pred(LocalVars.ElementCount) do\n      if Supports(LocalVars.Elements[i], IwbContainerElementRef, LocalVar) then begin\n        j := LocalVar.ElementNativeValues['SLSD\\Index'];\n        s := LocalVar.ElementNativeValues['SCVR'];\n        if SameText(s, Trim(aString)) then begin\n          Result := j;\n          Exit;\n        end;\n      end;\n  end;\n\n  raise Exception.Create('Variable \"'+aString+'\" was not found in \"'+MainRecord.ShortName+'\"');\nend;\n\nfunction wbCTDAParam2QuestStageToStr(aInt: Int64; const aElement: IwbElement; aType: TwbCallbackType): string;\nvar\n  Container  : IwbContainerElementRef;\n  Param1     : IwbElement;\n  MainRecord : IwbMainRecord;\n  EditInfos  : TStringList;\n  Stages     : IwbContainerElementRef;\n  Stage      : IwbContainerElementRef;\n  i, j       : Integer;\n  s, t       : string;\nbegin\n  case aType of\n    ctToStr: Result := IntToStr(aInt) + ' <Warning: Could not resolve Parameter 1>';\n    ctToEditValue: Result := IntToStr(aInt);\n    ctToSortKey: begin\n      Result := IntToHex64(aInt, 8);\n      Exit;\n    end;\n    ctCheck: Result := '<Warning: Could not resolve Parameter 1>';\n    ctEditType: Result := '';\n    ctEditInfo: Result := '';\n  end;\n\n  if not Assigned(aElement) then Exit;\n  Container := GetContainerRefFromUnionOrValue(aElement);\n  if not Assigned(Container) then Exit;\n\n  Param1 := Container.ElementByName['Parameter #1'];\n\n  if not Assigned(Param1) then\n    Exit;\n\n  if not Supports(Param1.LinksTo, IwbMainRecord, MainRecord) then\n    Exit;\n\n  if MainRecord.Signature <> QUST then begin\n    case aType of\n      ctToStr: Result := IntToStr(aInt) + ' <Warning: \"'+MainRecord.ShortName+'\" is not a Quest record>';\n      ctCheck: Result := '<Warning: \"'+MainRecord.ShortName+'\" is not a Quest record>';\n    end;\n    Exit;\n  end;\n\n  case aType of\n    ctEditType: begin\n      Result := 'ComboBox';\n      Exit;\n    end;\n    ctEditInfo:\n      EditInfos := TStringList.Create;\n  else\n    EditInfos := nil;\n  end;\n  try\n    if Supports(MainRecord.ElementByName['Stages'], IwbContainerElementRef, Stages) then begin\n      for i := 0 to Pred(Stages.ElementCount) do\n        if Supports(Stages.Elements[i], IwbContainerElementRef, Stage) then begin\n          j := Stage.ElementNativeValues['INDX'];\n          s := Trim(Stage.ElementValues['Log Entries\\Log Entry\\CNAM']);\n          t := IntToStr(j);\n          while Length(t) < 3 do\n            t := '0' + t;\n          if s <> '' then\n            t := t + ' ' + s;\n          if Assigned(EditInfos) then\n            EditInfos.AddObject(t, TObject(j))\n          else if j = aInt then begin\n            case aType of\n              ctToStr, ctToEditValue: Result := t;\n              ctCheck: Result := '';\n            end;\n            Exit;\n          end;\n        end;\n    end;\n\n    case aType of\n      ctToStr: Result := IntToStr(aInt) + ' <Warning: Quest Stage not found in \"' + MainRecord.Name + '\">';\n      ctCheck: Result := '<Warning: Quest Stage not found in \"' + MainRecord.Name + '\">';\n      ctEditInfo: begin\n        EditInfos.Sort;\n        Result := EditInfos.CommaText;\n      end;\n    end;\n  finally\n    FreeAndNil(EditInfos);\n  end;\nend;\n\nfunction wbCTDAParam2QuestStageToInt(const aString: string; const aElement: IwbElement): Int64;\nvar\n  i    : Integer;\n  s    : string;\nbegin\n  i := 1;\n  s := Trim(aString);\n  while (i <= Length(s)) and (s[i] in ['0'..'9']) do\n    Inc(i);\n  s := Copy(s, 1, Pred(i));\n\n  Result := StrToInt(s);\nend;\n\nprocedure wbRemoveOFST(const aElement: IwbElement);\nvar\n  Container: IwbContainer;\n  rOFST: IwbRecord;\nbegin\n  if Supports(aElement, IwbContainer, Container) then begin\n    rOFST := Container.RecordBySignature[OFST];\n    if Assigned(rOFST) then\n      Container.RemoveElement(rOFST);\n  end;\nend;\n\nprocedure wbCELLAfterLoad(const aElement: IwbElement);\nvar\n  Container    : IwbContainerElementRef;\n  Container2   : IwbContainerElementRef;\n  MainRecord   : IwbMainRecord;\n  i            : Integer;\n  IsInterior   : Boolean;\n  GroupRecord  : IwbGroupRecord;\n  Removed      : Boolean;\nbegin\n  if wbBeginInternalEdit then try\n    if not Supports(aElement, IwbContainerElementRef, Container) then\n      Exit;\n\n    if Container.ElementCount < 1 then\n      Exit;\n\n    if not Supports(aElement, IwbMainRecord, MainRecord) then\n      Exit;\n\n    if MainRecord.IsDeleted then\n      Exit;\n\n    if not Container.ElementExists['DATA'] then\n      Exit;\n\n    IsInterior := (Container.ElementNativeValues['DATA'] and 1) <> 0;\n\n    if IsInterior then\n      Container.Add('XCLL')\n    else begin\n      Container.Add('XCLC');\n      if (Container.ElementNativeValues['DATA'] and 2) = 0 then\n        if Supports(MainRecord.Container, IwbGroupRecord, GroupRecord) then\n          if GroupRecord.GroupType = 1 then\n            Container.ElementNativeValues['DATA'] :=\n              Container.ElementNativeValues['DATA'] or 2;\n    end;\n\n    Removed := False;\n    if Supports(Container.ElementBySignature[XCLR], IwbContainerElementRef, Container2) then begin\n      for i:= Pred(Container2.ElementCount) downto 0 do\n        if not Supports(Container2.Elements[i].LinksTo, IwbMainRecord, MainRecord) or (MainRecord.Signature <> 'REGN') then begin\n          if not Removed then begin\n            Removed := True;\n            Container2.MarkModifiedRecursive;\n          end;\n          Container2.RemoveElement(i);\n        end;\n      if Container2.ElementCount < 1 then\n        Container2.Remove;\n    end;\n  finally\n    wbEndInternalEdit;\n  end;\nend;\n\nprocedure wbMGEFAfterLoad(const aElement: IwbElement);\nvar\n  Container    : IwbContainerElementRef;\n  MainRecord   : IwbMainRecord;\n  _File        : IwbFile;\nbegin\n  if wbBeginInternalEdit then try\n    if not Supports(aElement, IwbContainerElementRef, Container) then\n      Exit;\n\n    if Container.ElementCount < 1 then\n      Exit;\n\n    if not Supports(aElement, IwbMainRecord, MainRecord) then\n      Exit;\n\n    if MainRecord.IsDeleted then\n      Exit;\n\n    _File := MainRecord._File;\n\n    if not Assigned(_File) then\n      Exit;\n\n    if not SameText(_File.FileName, 'Oblivion.esm') then\n      Exit;\n\n    if SameText(MainRecord.EditorID, 'RSFI') or\n       SameText(MainRecord.EditorID, 'RSFR') or\n       SameText(MainRecord.EditorID, 'RSPA') or\n       SameText(MainRecord.EditorID, 'RSSH') then begin\n\n         Container.ElementNativeValues['DATA - Data\\Flags'] :=\n           Cardinal(Container.ElementNativeValues['DATA - Data\\Flags']) or $8;\n\n       end;\n\n    if SameText(MainRecord.EditorID, 'REAN') then begin\n\n         Container.ElementNativeValues['DATA - Data\\Flags'] :=\n           Cardinal(Container.ElementNativeValues['DATA - Data\\Flags']) and not $20000;\n\n       end;\n\n  finally\n    wbEndInternalEdit;\n  end;\nend;\n\n\nprocedure wbEFITAfterLoad(const aElement: IwbElement);\nvar\n  Container : IwbContainerElementRef;\n  Element   : IwbElement;\n  ActorValue: Variant;\n  MainRecord: IwbMainRecord;\nbegin\n  if wbBeginInternalEdit then try\n    if not Supports(aElement, IwbContainerElementRef, Container) then\n      Exit;\n    if Container.ElementCount < 1 then\n      Exit;\n\n    Element := Container.ElementByName['Magic effect name'];\n    if not Assigned(Element) then\n      Exit;\n    if not Supports(Element.LinksTo, IwbMainRecord, MainRecord) then\n      Exit;\n    if MainRecord.Signature <> 'MGEF' then\n      Exit;\n\n    if (MainRecord.ElementNativeValues['DATA - Data\\Flags'] and $01000000) = 0 then\n      Exit;\n\n    ActorValue := MainRecord.ElementNativeValues['DATA - Data\\Assoc. Item'];\n    if VarIsNull(ActorValue) or VarIsClear(ActorValue) then\n      Exit;\n    if VarCompareValue(ActorValue, Container.ElementNativeValues['Actor Value']) <> vrEqual then\n      Container.ElementNativeValues['Actor Value'] := ActorValue;\n  finally\n    wbEndInternalEdit;\n  end;\nend;\n\nprocedure wbREFRAfterLoad(const aElement: IwbElement);\nvar\n  Container: IwbContainerElementRef;\nbegin\n  if wbBeginInternalEdit then try\n    if not Supports(aElement, IwbContainerElementRef, Container) then\n      Exit;\n    if Container.ElementCount < 1 then\n      Exit;\n\n    Container.RemoveElement('XPCI');\n  finally\n    wbEndInternalEdit;\n  end;\nend;\n\nprocedure wbLIGHAfterLoad(const aElement: IwbElement);\nvar\n  Container  : IwbContainerElementRef;\n  MainRecord : IwbMainRecord;\nbegin\n  if wbBeginInternalEdit then try\n    if not Supports(aElement, IwbContainerElementRef, Container) then\n      Exit;\n\n    if Container.ElementCount < 1 then\n      Exit;\n\n    if not Supports(aElement, IwbMainRecord, MainRecord) then\n      Exit;\n\n    if MainRecord.IsDeleted then\n      Exit;\n\n    if Container.ElementExists['DATA'] then begin\n      if SameValue(Container.ElementNativeValues['DATA\\Falloff Exponent'], 0.0) then\n        Container.ElementNativeValues['DATA\\Falloff Exponent'] := 1.0;\n      if SameValue(Container.ElementNativeValues['DATA\\FOV'], 0.0) then\n        Container.ElementNativeValues['DATA\\FOV'] := 90.0;\n    end;\n  finally\n    wbEndInternalEdit;\n  end;\nend;\n\nprocedure wbLVLAfterLoad(const aElement: IwbElement);\nvar\n  Container  : IwbContainerElementRef;\n  MainRecord : IwbMainRecord;\n  Chance     : Integer;\nbegin\n  if wbBeginInternalEdit then try\n    if not Supports(aElement, IwbContainerElementRef, Container) then\n      Exit;\n\n    if Container.ElementCount < 1 then\n      Exit;\n\n    if not Supports(aElement, IwbMainRecord, MainRecord) then\n      Exit;\n\n    if MainRecord.IsDeleted then\n      Exit;\n\n    Container.RemoveElement('DATA');\n\n    Chance := Container.ElementNativeValues['LVLD'];\n    if (Chance and $80) <> 0 then begin\n      Chance := Chance and not $80;\n      Container.ElementNativeValues['LVLD'] := Chance;\n      Container.ElementNativeValues['LVLF'] := Container.ElementNativeValues['LVLF'] or $01;\n    end;\n  finally\n    wbEndInternalEdit;\n  end;\nend;\n\nprocedure wbRPLDAfterLoad(const aElement: IwbElement);\nvar\n  Container : IwbContainer;\n  a, b      : Single;\n  NeedsFlip : Boolean;\nbegin\n  if wbBeginInternalEdit then try\n    if not Supports(aElement, IwbContainer, Container) then\n      Exit;\n\n    NeedsFlip := False;\n    if Container.ElementCount > 1 then begin\n      a := (Container.Elements[0] as IwbContainer).Elements[0].NativeValue;\n      b := (Container.Elements[Pred(Container.ElementCount)] as IwbContainer).Elements[0].NativeValue;\n      case CompareValue(a, b) of\n        EqualsValue: begin\n          a := (Container.Elements[0] as IwbContainer).Elements[1].NativeValue;\n          b := (Container.Elements[Pred(Container.ElementCount)] as IwbContainer).Elements[1].NativeValue;\n          NeedsFlip := CompareValue(a, b) = GreaterThanValue;\n        end;\n        GreaterThanValue:\n          NeedsFlip := True;\n      end;\n    end;\n    if NeedsFlip then\n      Container.ReverseElements;\n  finally\n    wbEndInternalEdit;\n  end;\nend;\n\nprocedure wbPGRDAfterLoad(const aElement: IwbElement);\nvar\n  Container   : IwbContainerElementRef;\n  MainRecord  : IwbMainRecord;\n  Points      : IwbContainerElementRef;\n  Connections : IwbContainerElementRef;\n  i, j        : Integer;\n  Point       : IwbContainerElementRef;\n  Connection  : IwbContainerElementRef;\n  Removed     : Boolean;\n  FirstRemoved: Boolean;\nbegin\n  if wbBeginInternalEdit then try\n    if not Supports(aElement, IwbContainerElementRef, Container) then\n      Exit;\n\n    if Container.ElementCount < 1 then\n      Exit;\n\n    if not Supports(aElement, IwbMainRecord, MainRecord) then\n      Exit;\n\n    if MainRecord.IsDeleted then\n      Exit;\n\n    if not Supports(Container.ElementBySignature['PGRP'], IwbContainerElementRef, Points) then\n      Exit;\n\n    if not Container.ElementExists['PGAG'] then\n      Container.Add('PGAG').DataSize := (Points.ElementCount + 7) div 8;\n\n    MainRecord.IsCompressed := True;\n\n    if not Supports(Container.ElementBySignature['PGRR'], IwbContainerElementRef, Connections) then\n      Exit;\n\n    if Points.ElementCount < Connections.ElementCount then\n      Exit;\n\n    FirstRemoved := False;\n    for i := Pred(Connections.ElementCount) downto 0 do begin\n      Connection := Connections.Elements[i] as IwbContainerElementRef;\n\n      Removed := False;\n      j := Connection.ElementCount;\n      while j > 0 do begin\n        Dec(j);\n        if Connection.Elements[j].NativeValue = 65535 then begin\n          if not FirstRemoved then begin\n            FirstRemoved := True;\n            Connections.MarkModifiedRecursive;\n          end;\n          Connection.Elements[j].Remove;\n          Removed := True;\n        end else\n          Break;\n      end;\n\n      if Removed then begin\n        Point := Points.Elements[i] as IwbContainerElementRef;\n        Point.ElementNativeValues['Connections'] := Connection.ElementCount;\n      end;\n\n    end;\n\n  finally\n    wbEndInternalEdit;\n  end;\nend;\n\nprocedure wbPGRRPointAfterLoad(const aElement: IwbElement);\nvar\n  Connections : IwbContainerElementRef;\n  i           : Integer;\n//  Index       : Integer;\nbegin\n  if wbBeginInternalEdit then try\n    if not Supports(aElement, IwbContainerElementRef, Connections) then\n      Exit;\n    for i := Pred(Connections.ElementCount) downto 0 do\n      if Connections.Elements[i].NativeValue = 65535 then begin\n        Connections.RemoveElement(i);\n      end;\n{    if Removed then begin\n      Index := aElement.Container.ElementCount;\n      (aElement.ContainingMainRecord.RecordBySignature['PGRP'].Elements[Index] as IwbContainer).Elements[3].NativeValue := Connections.ElementCount;\n    end;}\n  finally\n    wbEndInternalEdit;\n  end;\nend;\n\nprocedure wbPGRIPointerAfterLoad(const aElement: IwbElement);\nvar\n  Connections : IwbContainerElementRef;\n  i, j        : Integer;\n  s           : string;\n  Keys        : TStringList;\nbegin\n  if wbBeginInternalEdit then try\n    if not Supports(aElement, IwbContainerElementRef, Connections) then\n      Exit;\n\n    Keys := TStringList.Create;\n    try\n      Keys.Sorted := True;\n      Keys.Duplicates := dupError;\n      for i := Pred(Connections.ElementCount) downto 0 do begin\n        s := Connections.Elements[i].SortKey[True];\n        if Keys.Find(s, j) then\n          Connections.RemoveElement(i, True)\n        else\n          Keys.Add(s);\n      end;\n    finally\n      Keys.Free;\n    end;\n  finally\n    wbEndInternalEdit;\n  end;\nend;\n\n{\nfunction wbPGRPConnectionsCallback(aInt: Int64; const aElement: IwbElement; aType: TwbCallbackType): string;\nvar\n  Point : IwbContainerElementRef;\n  s     : string;\n  i     : Integer;\n  PGRP  : IwbContainerElementRef;\n  PGRD  : IwbMainRecord;\n  PGRR  : IwbContainerElementRef;\n  Cons  : IwbContainerElementRef;\nbegin\n  Result := '';\n  if aType = ctCheck then\n    Exit;\n\n  if wbFixupPGRD and (aInt > 0) and Assigned(aElement) and (aElement.ElementStates * [esModified] = []) then begin\n    Point := aElement.Container as IwbContainerElementRef;\n    if Assigned(Point) then begin\n      s := Trim(Point.Name);\n      i := Pos('#', s);\n      if i > 0 then begin\n        i := StrToIntDef(Copy(s, i+1, High(Integer)), -1);\n        if i >= 0 then begin\n          PGRP := Point.Container as IwbContainerElementRef;\n          if Assigned(PGRP) then begin\n            if Supports(PGRP.Container, IwbMainRecord, PGRD) then begin\n              if (csInitDone in PGRD.ContainerStates) and (PGRD.Signature = 'PGRD') then begin\n                PGRR := PGRD.RecordBySignature['PGRR'] as IwbContainerElementRef;\n                if Assigned(PGRR) and (PGRR.ElementCount > 0) and (csInitDone in PGRR.ContainerStates) then begin\n                  if (i < PGRR.ElementCount) then begin\n                    if Supports(PGRR.Elements[i], IwbContainer, Cons) then begin\n                      aInt := Cons.ElementCount;\n                    end;\n                  end;\n                end;\n                PGRR := nil;\n              end;\n            end;\n          end;\n        end;\n      end;\n    end;\n  end;\n\n  if aType = ctToSortKey then\n    Result := IntToHex64(aInt, 2)\n  else if aType = ctToStr then\n    Result := IntToStr(aInt);\nend;\n}\n\nfunction wbPxDTLocationDecider(aBasePtr: Pointer; aEndPtr: Pointer; const aElement: IwbElement): Integer;\nvar\n  Container: IwbContainer;\nbegin\n  Result := 0;\n  if not Assigned(aElement) then Exit;\n  Container := GetContainerFromUnion(aElement);\n  if not Assigned(Container) then Exit;\n\n  Result := Container.ElementByName['Type'].NativeValue;\nend;\n\nfunction wbCalcPGRRSize(aBasePtr: Pointer; aEndPtr: Pointer; const aElement: IwbElement): Cardinal;\nvar\n  Index: Integer;\nbegin\n  Index := aElement.Container.ElementCount;\n  Result := ((aElement.Container.Container as IwbMainRecord).RecordBySignature['PGRP'].Elements[Pred(Index)] as IwbContainer).Elements[3].NativeValue;\nend;\n\nfunction wbMGEFFAssocItemDecider(aBasePtr: Pointer; aEndPtr: Pointer; const aElement: IwbElement): Integer;\nvar\n  s: string;\n  Container: IwbContainer;\nbegin\n  Result := 0;\n  if not Assigned(aElement) then Exit;\n  Container := GetContainerFromUnion(aElement);\n  if not Assigned(Container) then Exit;\n\n  s := Container.ElementByName['Flags'].SortKey[False];\n  if s[17] = '1' then\n    Result := 1\n  else if s[18] = '1' then\n    Result := 2\n  else if s[19] = '1' then\n    Result := 3\n  else if s[25] = '1' then\n    Result := 4;\nend;\n\nfunction wbEDDXDontShow(const aElement: IwbElement): Boolean;\nvar\n  MainRecord : IwbMainRecord;\nbegin\n  Result := True;\n\n  if Supports(aElement.Container, IwbMainRecord, MainRecord) then\n    Result := not Assigned(MainRecord.ElementBySignature[OBME]);\nend;\n\nfunction wbOBMEDontShow(const aElement: IwbElement): Boolean;\nvar\n  _File: IwbFile;\nbegin\n  if not Assigned(aElement) then begin\n    Result := True;\n    Exit;\n  end;\n\n  Result := False;\n\n  _File := aElement._File;\n  if Assigned(_File) and SameText(_File.FileName, 'Oblivion.esm') then\n    Result := True;\nend;\n\nprocedure DefineTES3;\nbegin\n  wbHeaderSignature := 'TES3';\n  \n  wbRecordFlags := wbInteger('Record Flags', itU32, wbFlags([\n    {0x00000001}'ESM',\n    {0x00000002}'',\n    {0x00000004}'',\n    {0x00000008}'',\n    {0x00000010}'',\n    {0x00000020}'Deleted',\n    {0x00000040}'Border Region / Actor Value',\n    {0x00000080}'Turn Off Fire / Actor Value',\n    {0x00000100}'',\n    {0x00000200}'Casts shadows',\n    {0x00000400}'Quest item / Persistent reference / Show in Menu',\n    {0x00000800}'Initially disabled',\n    {0x00001000}'Ignored',\n    {0x00002000}'',\n    {0x00004000}'',\n    {0x00008000}'Visible when distant',\n    {0x00010000}'',\n    {0x00020000}'Dangerous / Off limits (Interior cell)',\n    {0x00040000}'Compressed ',\n    {0x00080000}'Can''t wait'\n  ]));\n\n  wbMainRecordHeader := wbStruct('Record Header', [\n    wbString('Signature', 4, cpCritical),\n    wbInteger('Data Size', itU32, nil, cpIgnore),\n    wbRecordFlags,\n    wbFormID('FormID', cpFormID),\n    wbByteArray('Unknown', 4, cpIgnore)\n  ]);\n\n  wbSizeOfMainRecordStruct := 20;\n\n  wbIgnoreRecords.Add(XXXX);\n\n  wbXRGD := wbByteArray(XRGD, 'Ragdoll Data');\n\n  wbMusicEnum := wbEnum(['Default', 'Public', 'Dungeon']);\n\n  wbEDID := wbString(EDID, 'Editor ID', 0, cpBenign);\n  wbFULL := wbString(FULL, 'Name', 0, cpTranslate);\n  wbFULLReq := wbString(FULL, 'Name', 0, cpNormal, True);\n  wbDESC := wbString(DESC, 'Description', 0, cpTranslate);\n  wbXSCL := wbFloat(XSCL, 'Scale');\n\n  wbPosRot :=\n    wbStruct('Position/Rotation', [\n      wbStruct('Position', [\n        wbFloat('X'),\n        wbFloat('Y'),\n        wbFloat('Z')\n      ]),\n      wbStruct('Rotation', [\n        wbFloat('X', cpNormal, True, wbRotationFactor, wbRotationScale, nil, RadiansNormalize),\n        wbFloat('Y', cpNormal, True, wbRotationFactor, wbRotationScale, nil, RadiansNormalize),\n        wbFloat('Z', cpNormal, True, wbRotationFactor, wbRotationScale, nil, RadiansNormalize)\n      ])\n    ]);\n\n  wbDATAPosRot :=\n    wbStruct(DATA, 'Position/Rotation', [\n      wbStruct('Position', [\n        wbFloat('X'),\n        wbFloat('Y'),\n        wbFloat('Z')\n      ]),\n      wbStruct('Rotation', [\n        wbFloat('X', cpNormal, True, wbRotationFactor, wbRotationScale, nil, RadiansNormalize),\n        wbFloat('Y', cpNormal, True, wbRotationFactor, wbRotationScale, nil, RadiansNormalize),\n        wbFloat('Z', cpNormal, True, wbRotationFactor, wbRotationScale, nil, RadiansNormalize)\n      ])\n    ], cpNormal, True);\n\n  wbMODL :=\n    wbRStructSK([0], 'Model', [\n      wbString(MODL, 'Model Filename'),\n      wbFloat(MODB, 'Bound Radius', cpBenign),\n      wbByteArray(MODT, 'Texture Files Hashes', 0, cpIgnore)\n//      wbArray(MODT, 'Unknown',\n//        wbByteArray('Unknown', 24, cpBenign),\n//      0, nil, cpBenign)\n    ], []);\n\n  wbSCRI := wbFormIDCk(SCRI, 'Script', [SCPT]);\n  wbENAM := wbFormIDCk(ENAM, 'Enchantment', [ENCH]);\n\n  wbXLOD := wbArray(XLOD, 'Distant LOD Data', wbFloat('Unknown'), 3);\n  wbXESP := wbStruct(XESP, 'Enable Parent', [\n    wbFormIDCk('Reference', [PLYR, REFR, ACRE, ACHR]),\n    wbInteger('Flags', itU8, wbFlags([\n      'Set Enable State to Opposite of Parent'\n    ])),\n    wbByteArray('Unused', 3)\n  ]);\n\n  wbRecord(ACHR, 'Placed NPC', [\n    wbEDID,\n    wbFormIDCk(NAME, 'Base', [NPC_], False, cpNormal, True),\n    wbRStruct('Unused', [\n      wbFormIDCk(XPCI, 'Unused', [CELL]),\n      wbString(FULL, 'Unused')\n    ], []),\n    wbXLOD,\n    wbXESP,\n    wbFormIDCk(XMRC, 'Merchant container', [REFR], True),\n    wbFormIDCk(XHRS, 'Horse', [ACRE], True),\n    wbXRGD,\n    wbXSCL,\n    wbDATAPosRot\n  ], True, wbPlacedAddInfo, cpNormal, False, wbREFRAfterLoad);\n\n  wbXOWN := wbFormIDCk(XOWN, 'Owner', [FACT, NPC_]);\n  wbXGLB := wbFormIDCk(XGLB, 'Global variable', [GLOB]);\n\n  wbRecord(ACRE, 'Placed Creature', [\n    wbEDID,\n    wbFormIDCk(NAME, 'Base', [CREA], False, cpNormal, True),\n    wbRStruct('Ownership', [\n      wbXOWN,\n      wbInteger(XRNK, 'Faction rank', itS32),\n      wbXGLB\n    ], []),\n    wbXESP,\n    wbXRGD,\n    wbXSCL,\n    wbDATAPosRot\n  ], True, wbPlacedAddInfo);\n\n  wbRecord(ACTI, 'Activator', [\n    wbEDID,\n    wbFULL,\n    wbMODL,\n    wbSCRI,\n    wbFormIDCk(SNAM, 'Sound', [SOUN])\n  ]);\n\n  wbICON := wbString(ICON, 'Icon filename');\n\n  wbActorValueEnum :=\n    wbEnum([\n      'Strength',\n      'Intelligence',\n      'Willpower',\n      'Agility',\n      'Speed',\n      'Endurance',\n      'Personality',\n      'Luck',\n      'Health',\n      'Magicka',\n      'Fatigue',\n      'Encumbrance',\n      'Armorer',\n      'Athletics',\n      'Blade',\n      'Block',\n      'Blunt',\n      'Hand To Hand',\n      'Heavy Armor',\n      'Alchemy',\n      'Alteration',\n      'Conjuration',\n      'Destruction',\n      'Illusion',\n      'Mysticism',\n      'Restoration',\n      'Acrobatics',\n      'Light Armor',\n      'Marksman',\n      'Mercantile',\n      'Security',\n      'Sneak',\n      'Speechcraft',\n {33} 'Aggression',\n {34} 'Confidence',\n {35} 'Energy',\n {36} 'Responsibility',\n {37} 'Bounty',\n {38} 'Fame',\n {39} 'Infamy',\n {40} 'Magicka Multiplier',\n {41} 'Night Eye Bonus',\n {42} 'Attack Bonus',\n {43} 'Defend Bonus',\n {44} 'Casting Penalty',\n {45} 'Blindness',\n {46} 'Chameleon',\n {47} 'Invisibility',\n {48} 'Paralysis',\n {49} 'Silence',\n {50} 'Confusion',\n {51} 'Detect Item Range',\n {52} 'Spell Absorb Chance',\n {53} 'Spell Reflect Chance',\n {54} 'Swim Speed Multiplier',\n {55} 'Water Breathing',\n {56} 'Water Walking',\n {57} 'Stunted Magicka',\n {58} 'Detect Life Range',\n {59} 'Reflect Damage',\n {60} 'Telekinesis',\n {61} 'Resist Fire',\n {62} 'Resist Frost',\n {63} 'Resist Disease',\n {64} 'Resist Magic',\n {65} 'Resist Normal Weapons',\n {66} 'Resist Paralysis',\n {67} 'Resist Poison',\n {68} 'Resist Shock',\n {69} 'Vampirism',\n {70} 'Darkness',\n {71} 'Resist Water Damage'\n    ], [\n      -1, 'None'\n    ]);\n\n  wbSkillEnum :=\n    wbEnum([\n      'Armorer',\n      'Athletics',\n      'Blade',\n      'Block',\n      'Blunt',\n      'Hand To Hand',\n      'Heavy Armor',\n      'Alchemy',\n      'Alteration',\n      'Conjuration',\n      'Destruction',\n      'Illusion',\n      'Mysticism',\n      'Restoration',\n      'Acrobatics',\n      'Light Armor',\n      'Marksman',\n      'Mercantile',\n      'Security',\n      'Sneak',\n      'Speechcraft'\n    ], [\n      -1, 'None'\n    ]);\n\n\n  wbEFID := wbInteger(EFID, 'Magic effect name', itU32, wbChar4, cpNormal, True);\n\n  wbEFIDOBME := wbStringMgefCode(EFID, 'Magic Effect Code', 4, cpNormal, True);\n\n  wbEFIT :=\n    wbStructSK(EFIT, [4, 5], '', [\n      wbInteger('Magic effect name', itU32, wbChar4),\n      wbInteger('Magnitude', itU32),\n      wbInteger('Area', itU32),\n      wbInteger('Duration', itU32),\n      wbInteger('Type', itU32, wbEnum(['Self', 'Touch', 'Target'])),\n      wbInteger('Actor Value', itS32, wbActorValueEnum)\n    ], cpNormal, True, nil, -1, wbEFITAfterLoad);\n\n  wbEFITOBME :=\n    wbStructSK(EFIT, [4, 5], '', [\n      wbStringMgefCode('Magic Effect Code', 4),\n      wbInteger('Magnitude', itU32),\n      wbInteger('Area', itU32),\n      wbInteger('Duration', itU32),\n      wbInteger('Type', itU32, wbEnum(['Self', 'Touch', 'Target'])),\n      wbUnion('Param #1', wbEFITOBMEParamDecider, [\n        wbByteArray('Param #1 - Unknown Type', 4),\n        wbFormID('Param #1 - FormID'),\n        wbStringMgefCode('Param #1 - Magic Effect Code', 4),\n        wbFormIDCk('Param #1 - Actor Value', [ACVA])\n      ])\n    ], cpNormal, True, nil, -1{, wbEFITAfterLoad});\n\n  wbEFIX :=\n    wbStructSK(EFIX, [3], '', [\n      wbInteger('Override Mask', itU32, wbFlags([])),\n      wbInteger('Flags', itU32, wbFlags([])),\n      wbFloat('Base Cost'),\n      wbUnion('Param #2', wbEFIXParamDecider, [\n        wbByteArray('Param #2 - Unknown Type', 4),\n        wbFormID('Param #2 - FormID'),\n        wbStringMgefCode('Param #2 - Magic Effect Code', 4),\n        wbFormIDCk('Param #2 - Actor Value', [ACVA])\n      ])\n    ], cpNormal, True, nil, -1, wbEFITAfterLoad);\n\n  wbMagicSchoolEnum :=\n    wbEnum([\n      'Alteration',\n      'Conjuration',\n      'Destruction',\n      'Illusion',\n      'Mysticism',\n      'Restoration'\n    ]);\n\n  wbSCIT :=\n    wbRStructSK([0], 'Script effect', [\n      wbStructSK(SCIT, [0], 'Script effect data', [\n        wbFormIDCk('Script effect', [NULL, SCPT]),\n        wbInteger('Magic school', itU32, wbMagicSchoolEnum),\n        wbInteger('Visual effect name', itU32, wbChar4),\n        wbInteger('Flags', itU8, wbFlags(['Hostile'])),\n        wbByteArray('Unused', 3)\n      ], cpNormal, True, nil, 1),\n      wbFULLReq\n    ], []);\n\n  wbSCITOBME :=\n    wbRStructSK([0], 'Script effect', [\n      wbStructSK(SCIT, [0], 'Script effect data', [\n        wbFormIDCk('Script effect', [NULL, SCPT]),\n        wbInteger('Magic school', itU32, wbMagicSchoolEnum),\n        wbStringMgefCode('Visual Effect Code', 4),\n        wbInteger('Flags', itU8, wbFlags(['Hostile'])),\n        wbByteArray('Unused', 3)\n      ], cpNormal, True, nil, 1),\n      wbFULLReq\n    ], []);\n\n\n  wbOBMEResolutionInfo := wbEnum(['None', 'FormID', 'Magic Effect Code', 'Actor Value']);\n\n  wbEffects :=\n    wbRUnion('Effects', [\n      wbRStruct('Effects', [\n        wbRStructs('Effects','Effect', [\n          wbEFID,\n          wbEFIT,\n          wbSCIT\n        ], [])\n      ], []),\n      wbRStruct('Effects', [\n        wbRStructs('Effects','Effect', [\n          wbStruct(EFME, 'Oblivion Magic Extender', [\n            wbInteger('Record Version', itU8),\n            wbStruct('OBME Version', [\n              wbInteger('Beta', itU8),\n              wbInteger('Minor', itU8),\n              wbInteger('Major', itU8)\n            ]),\n            wbInteger('EFIT Param Info', itU8, wbOBMEResolutionInfo),\n            wbInteger('EFIX Param Info', itU8, wbOBMEResolutionInfo),\n            wbByteArray('Unused', $0A)\n          ]),\n          wbEFIDOBME,\n          wbEFITOBME,\n          wbSCITOBME,\n          wbString(EFII, 'Icon'),\n          wbEFIX\n        ], []),\n        wbEmpty(EFXX, 'Effects End Marker', cpNormal, True),\n        wbFULLReq\n      ], [])\n    ], []);\n\n  wbRecord(ALCH, 'Potion', [\n    wbEDID,\n    wbStruct(OBME, 'Oblivion Magic Extender', [\n      wbInteger('Record Version', itU8),\n      wbStruct('OBME Version', [\n        wbInteger('Beta', itU8),\n        wbInteger('Minor', itU8),\n        wbInteger('Major', itU8)\n      ]),\n      wbByteArray('Unused', $1C)\n    ], cpNormal, False, wbOBMEDontShow),\n    wbFULL,\n    wbMODL,\n    wbICON,\n    wbSCRI,\n    wbFloat(DATA, 'Weight', cpNormal, True),\n    wbStruct(ENIT, '', [\n      wbInteger('Value', itS32),\n      wbInteger('Flags', itU8, wbFlags(['No auto-calculation', 'Food item'])),\n      wbByteArray('Unused', 3)\n    ], cpNormal, True),\n    wbEffects\n  ]);\n\n  wbRecord(AMMO, 'Ammunition', [\n    wbEDID,\n    wbFULL,\n    wbMODL,\n    wbICON,\n    wbFormIDCk(ENAM, 'Enchantment', [ENCH]),\n    wbInteger(ANAM, 'Enchantment Points', itU16),\n    wbStruct(DATA, '', [\n      wbFloat('Speed'),\n      wbInteger('Flags', itU8, wbFlags(['Ignores Normal Weapon Resistance'])),\n      wbByteArray('Unused', 3),\n      wbInteger('Value', itU32),\n      wbFloat('Weight'),\n      wbInteger('Damage', itU16)\n    ], cpNormal, True)\n  ]);\n\n  wbRecord(ANIO, 'Animated Object', [\n    wbEDID,\n    wbMODL,\n    wbFormIDCk(DATA, 'IDLE animation', [IDLE], False, cpNormal, True)\n  ]);\n\n  wbRecord(APPA, 'Alchemical Apparatus', [\n    wbEDID,\n    wbFULL,\n    wbMODL,\n    wbICON,\n    wbSCRI,\n    wbStruct(DATA, '', [\n      wbInteger('Type', itU8, wbEnum(['Mortar and Pestle', 'Alembic', 'Calcinator', 'Retort'])),\n      wbInteger('Value', itU32),\n      wbFloat('Weight'),\n      wbFloat('Quality')\n    ], cpNormal, True)\n  ]);\n\n  wbRecord(ARMO, 'Armor', [\n    wbEDID,\n    wbFULL,\n    wbSCRI,\n    wbENAM,\n    wbInteger(ANAM, 'Enchantment Points', itU16),\n    wbStruct(BMDT, '', [\n      wbInteger('Biped Flags', itU16, wbFlags([\n        {0x00000001} 'Head',\n        {0x00000002} 'Hair',\n        {0x00000004} 'Upper Body',\n        {0x00000008} 'Lower Body',\n        {0x00000010} 'Hand',\n        {0x00000020} 'Foot',\n        {0x00000040} 'Right Ring',\n        {0x00000080} 'Left Ring',\n        {0x00000100} 'Amulet',\n        {0x00000200} 'Weapon',\n        {0x00000400} 'Back Weapon',\n        {0x00000800} 'Side Weapon',\n        {0x00001000} 'Quiver',\n        {0x00002000} 'Shield',\n        {0x00004000} 'Torch',\n        {0x00008000} 'Tail'\n      ])),\n      wbInteger('General Flags', itU8, wbFlags([\n        {0x0001} 'Hide Rings',\n        {0x0002} 'Hide Amulets',\n        {0x0004} '',\n        {0x0008} '',\n        {0x0010} '',\n        {0x0020} '',\n        {0x0040} 'Non-Playable',\n        {0x0080} 'Heavy armor'\n      ])),\n      wbByteArray('Unused', 1)\n    ], cpNormal, True),\n    wbRStruct('Male biped model', [\n      wbString(MODL, 'Model Filename'),\n      wbFloat(MODB, 'Bound Radius', cpBenign),\n      wbByteArray(MODT, 'Texture Files Hashes', 0, cpIgnore)\n    ], []),\n    wbRStruct('Male world model', [\n      wbString(MOD2, 'Model Filename'),\n      wbFloat(MO2B, 'Bound Radius', cpBenign),\n      wbByteArray(MO2T, 'Texture Files Hashes', 0, cpIgnore)\n    ], []),\n    wbString(ICON, 'Male icon filename'),\n    wbRStruct('Female biped model', [\n      wbString(MOD3, 'Model Filename'),\n      wbFloat(MO3B, 'Bound Radius', cpBenign),\n      wbByteArray(MO3T, 'Texture Files Hashes', 0, cpIgnore)\n    ], []),\n    wbRStruct('Female world model', [\n      wbString(MOD4, 'Model Filename'),\n      wbFloat(MO4B, 'Bound Radius', cpBenign),\n      wbByteArray(MO4T, 'Texture Files Hashes', 0, cpIgnore)\n    ], []),\n    wbString(ICO2, 'Female icon filename'),\n    wbStruct(DATA, '', [\n      wbInteger('Armor', itU16, wbDiv(100)),\n      wbInteger('Value', itU32),\n      wbInteger('Health', itU32),\n      wbFloat('Weight')\n    ], cpNormal, True)\n  ]);\n\n  wbRecord(BOOK, 'Book', [\n    wbEDID,\n    wbFULL,\n    wbMODL,\n    wbICON,\n    wbSCRI,\n    wbENAM,\n    wbInteger(ANAM, 'Enchantment Points', itU16),\n    wbDESC,\n    wbStruct(DATA, '', [\n      wbInteger('Flags', itU8, wbFlags(['Scroll', 'Can''t be taken'])),\n      wbInteger('Teaches', itS8, wbSkillEnum),\n      wbInteger('Value', itU32),\n      wbFloat('Weight')\n    ], cpNormal, True)\n  ], True);\n\n  wbSPLO := wbFormIDCk(SPLO, 'Spell', [SPEL, LVSP]);\n  wbSPLOs := wbRArrayS('Spells', wbSPLO);\n\n  wbRecord(BSGN, 'Birthsign', [\n    wbEDID,\n    wbFULL,\n    wbICON,\n    wbDESC,\n    wbSPLOs\n  ]);\n\n  wbRecord(CELL, 'Cell', [\n    wbEDID,\n    wbFULL,\n    wbInteger(DATA, 'Flags', itU8, wbFlags([\n      {0x01} 'Is Interior Cell',\n      {0x02} 'Has water',\n      {0x04} 'Invert Fast Travel behavior',\n      {0x08} 'Force hide land (exterior cell) / Oblivion interior (interior cell)',\n      {0x10} '',\n      {0x20} 'Public place',\n      {0x40} 'Hand changed',\n      {0x80} 'Behave like exterior'\n    ]), cpNormal, True),\n    wbStruct(XCLC, 'Grid', [\n      wbInteger('X', itS32),\n      wbInteger('Y', itS32)\n    ]),\n    wbStruct(XCLL, 'Lighting', [\n      wbStruct('Ambient Color', [\n        wbInteger('Red', itU8),\n        wbInteger('Green', itU8),\n        wbInteger('Blue', itU8),\n        wbByteArray('Unused', 1)\n      ]),\n      wbStruct('Directional Color', [\n        wbInteger('Red', itU8),\n        wbInteger('Green', itU8),\n        wbInteger('Blue', itU8),\n        wbByteArray('Unused', 1)\n      ]),\n      wbStruct('Fog Color', [\n        wbInteger('Red', itU8),\n        wbInteger('Green', itU8),\n        wbInteger('Blue', itU8),\n        wbByteArray('Unused', 1)\n      ]),\n      wbFloat('Fog Near'),\n      wbFloat('Fog Far'),\n      wbInteger('Directional Rotation XY', itS32),\n      wbInteger('Directional Rotation Z', itS32),\n      wbFloat('Directional Fade', cpNormal, False, 1, -1, nil, nil, 1.0),\n      wbFloat('Fog Clip Dist')\n    ]),\n    wbArrayS(XCLR, 'Regions', wbFormIDCk('Region', [REGN])),\n    wbInteger(XCMT, 'Music', itU8, wbMusicEnum),\n    wbFloat(XCLW, 'Water Height', cpBenign),\n    wbFormIDCk(XCCM, 'Climate', [CLMT]),\n    wbFormIDCk(XCWT, 'Water', [WATR]),\n    wbRStruct('Ownership', [\n      wbXOWN,\n      wbInteger(XRNK, 'Faction rank', itS32),\n      wbXGLB\n    ], [XCLW, XCMT])\n  ], True, wbCellAddInfo, cpNormal, False, wbCELLAfterLoad);\n\n  wbServiceFlags :=\n    wbFlags([\n      {0x00000001} 'Weapons',\n      {0x00000002} 'Armor',\n      {0x00000004} 'Clothing',\n      {0x00000008} 'Books',\n      {0x00000010} 'Ingredients',\n      {0x00000020} '',\n      {0x00000040} '',\n      {0x00000080} 'Lights',\n      {0x00000100} 'Apparatus',\n      {0x00000200} '',\n      {0x00000400} 'Miscellaneous',\n      {0x00000800} 'Spells',\n      {0x00001000} 'Magic Items',\n      {0x00002000} 'Potions',\n      {0x00004000} 'Training',\n      {0x00008000} '',\n      {0x00010000} 'Recharge',\n      {0x00020000} 'Repair'\n    ]);\n\n  wbSpecializationEnum := wbEnum(['Combat', 'Magic', 'Stealth']);\n\n  wbRecord(CLAS, 'Class', [\n    wbEDID,\n    wbFULL,\n    wbDESC,\n    wbICON,\n    wbStruct(DATA, '', [\n      wbArrayS('Primary Attributes', wbInteger('Primary Attribute', itS32, wbActorValueEnum), 2),\n      wbInteger('Specialization', itU32, wbSpecializationEnum),\n      wbArrayS('Major Skills', wbInteger('Major Skill', itS32, wbActorValueEnum), 7),\n      wbInteger('Flags', itU32, wbFlags(['Playable', 'Guard'])),\n      wbInteger('Buys/Sells and Services', itU32, wbServiceFlags),\n      wbInteger('Teaches', itS8, wbSkillEnum),\n      wbInteger('Maximum training level', itU8),\n      wbInteger('Unused', itU16)\n    ], cpNormal, True, nil, 5)\n  ]);\n\n  wbRecord(CLMT, 'Climate', [\n    wbEDID,\n    wbArrayS(WLST, 'Weather Types', wbStructSK([0], 'Weather Type', [\n      wbFormIDCk('Weather', [WTHR]),\n      wbInteger('Chance', itS32)\n    ])),\n    wbString(FNAM, 'Sun Texture'),\n    wbString(GNAM, 'Sun Glare Texture'),\n    wbMODL,\n    wbStruct(TNAM, 'Timing', [\n      wbStruct('Sunrise', [\n        wbInteger('Begin', itU8, wbClmtTime),\n        wbInteger('End', itU8, wbClmtTime)\n      ]),\n      wbStruct('Sunset', [\n        wbInteger('Begin', itU8, wbClmtTime),\n        wbInteger('End', itU8, wbClmtTime)\n      ]),\n      wbInteger('Volatility', itU8),\n      wbInteger('Moons / Phase Length', itU8, wbClmtMoonsPhaseLength)\n    ], cpNormal, True)\n  ]);\n\n  wbRecord(CLOT, 'Clothing', [\n    wbEDID,\n    wbFULL,\n    wbSCRI,\n    wbENAM,\n    wbInteger(ANAM, 'Enchantment Points', itU16),\n    wbStruct(BMDT, '', [\n      wbInteger('Biped Flags', itU16, wbFlags([\n        {0x00000001} 'Head',\n        {0x00000002} 'Hair',\n        {0x00000004} 'Upper Body',\n        {0x00000008} 'Lower Body',\n        {0x00000010} 'Hand',\n        {0x00000020} 'Foot',\n        {0x00000040} 'Right Ring',\n        {0x00000080} 'Left Ring',\n        {0x00000100} 'Amulet',\n        {0x00000200} 'Weapon',\n        {0x00000400} 'Back Weapon',\n        {0x00000800} 'Side Weapon',\n        {0x00001000} 'Quiver',\n        {0x00002000} 'Shield',\n        {0x00004000} 'Torch',\n        {0x00008000} 'Tail'\n      ])),\n      wbInteger('General Flags', itU8, wbFlags([\n        {0x0001} 'Hide Rings',\n        {0x0002} 'Hide Amulets',\n        {0x0004} '',\n        {0x0008} '',\n        {0x0010} '',\n        {0x0020} '',\n        {0x0040} 'Non-Playable',\n        {0x0080} '' {Heavy armor}\n      ])),\n      wbByteArray('Unused', 1)\n    ], cpNormal, True),\n    wbRStruct('Male biped model', [\n      wbString(MODL, 'Model Filename'),\n      wbFloat(MODB, 'Bound Radius', cpBenign),\n      wbByteArray(MODT, 'Texture Files Hashes', 0, cpIgnore)\n    ], []),\n    wbRStruct('Male world model', [\n      wbString(MOD2, 'Model Filename'),\n      wbFloat(MO2B, 'Bound Radius', cpBenign),\n      wbByteArray(MO2T, 'Texture Files Hashes', 0, cpIgnore)\n    ], []),\n    wbString(ICON, 'Male icon filename'),\n    wbRStruct('Female biped model', [\n      wbString(MOD3, 'Model Filename'),\n      wbFloat(MO3B, 'Bound Radius', cpBenign),\n      wbByteArray(MO3T, 'Texture Files Hashes', 0, cpIgnore)\n    ], []),\n    wbRStruct('Female world model', [\n      wbString(MOD4, 'Model Filename'),\n      wbFloat(MO4B, 'Bound Radius', cpBenign),\n      wbByteArray(MO4T, 'Texture Files Hashes', 0, cpIgnore)\n    ], []),\n    wbString(ICO2, 'Female icon filename'),\n    wbStruct(DATA, '', [\n      wbInteger('Value', itU32),\n      wbFloat('Weight')\n    ], cpNormal, True)\n  ]);\n\n  wbCNTO :=\n    wbStructSK(CNTO, [0], 'Item', [\n      wbFormIDCk('Item', [ARMO, AMMO, MISC, WEAP, INGR, SLGM, SGST, BOOK, LVLI, KEYM, CLOT, ALCH, APPA, LIGH]),\n      wbInteger('Count', itS32)\n    ]);\n\n  wbCNTOs := wbRArrayS('Items', wbCNTO);\n\n  wbRecord(CONT, 'Container', [\n    wbEDID,\n    wbFULL,\n    wbMODL,\n    wbSCRI,\n    wbCNTOs,\n    wbStruct(DATA, '', [\n      wbInteger('Flags', itU8, wbFlags(['', 'Respawns'])),\n      wbFloat('Weight')\n    ], cpNormal, True),\n    wbFormIDCk(SNAM, 'Open sound', [SOUN]),\n    wbFormIDCk(QNAM, 'Close sound', [SOUN])\n  ]);\n\n  wbCSDT := wbRStructSK([0], 'Sound Type', [\n    wbInteger(CSDT, 'Type', itU32,wbEnum([\n      {0x00} 'Left Foot',\n      {0x01} 'Right Foot',\n      {0x02} 'Left Back Foot',\n      {0x03} 'Right Back Foot',\n      {0x04} 'Idle',\n      {0x05} 'Aware',\n      {0x06} 'Attack',\n      {0x07} 'Hit',\n      {0x08} 'Death',\n      {0x09} 'Weapon'\n    ])),\n    wbRArrayS('Sounds', wbRStructSK([0], 'Sound', [\n      wbFormIDCk(CSDI, 'Sound', [SOUN], False, cpNormal, True),\n      wbInteger(CSDC, 'Sound Chance', itU8, nil, cpNormal, True)\n    ], []), cpNormal, True)\n  ], []);\n\n  wbCSDTs := wbRArrayS('Sound Types', wbCSDT);\n\n  wbSoulGemEnum := wbEnum([\n    {0} 'None',\n    {1} 'Petty',\n    {2} 'Lesser',\n    {3} 'Common',\n    {4} 'Greater',\n    {5} 'Grand'\n  ]);\n\n  wbRecord(CREA, 'Creature', [\n    wbEDID,\n    wbFULL,\n    wbMODL,\n    wbCNTOs,\n    wbSPLOs,\n    wbArrayS(NIFZ, 'Models', wbStringLC('Model')),\n    wbByteArray(NIFT, 'Texture Files Hashes', 0, cpIgnore),\n    wbStruct(ACBS, 'Configuration', [\n      wbInteger('Flags', itU32, wbFlags([\n        {0x000001} 'Biped',\n        {0x000002} 'Essential',\n        {0x000004} 'Weapon & Shield',\n        {0x000008} 'Respawn',\n        {0x000010} 'Swims',\n        {0x000020} 'Flies',\n        {0x000040} 'Walks',\n        {0x000080} 'PC Level Offset',\n        {0x000100} 'Unused', //??\n        {0x000200} 'No Low Level Processing',\n        {0x000400} 'Unused', //??\n        {0x000800} 'No Blood Spray',\n        {0x001000} 'No Blood Decal',\n        {0x002000} '',\n        {0x004000} '',\n        {0x008000} 'No Head',\n        {0x010000} 'No Right Arm',\n        {0x020000} 'No Left Arm',\n        {0x040000} 'No Combat in Water',\n        {0x080000} 'No Shadow',\n        {0x100000} 'No Corpse Check'\n      ])),\n      wbInteger('Base spell points', itU16),\n      wbInteger('Fatigue', itU16),\n      wbInteger('Barter gold', itU16),\n      wbInteger('Level (offset)', itS16),\n      wbInteger('Calc min', itU16),\n      wbInteger('Calc max', itU16)\n    ], cpNormal, True),\n    wbRArrayS('Factions',\n      wbStructSK(SNAM, [0], 'Faction', [\n        wbFormIDCk('Faction', [FACT]),\n        wbInteger('Rank', itU8),\n        wbByteArray('Unused', 3)\n      ])\n    ),\n    wbFormIDCk(INAM, 'Death item', [LVLI]),\n    wbSCRI,\n    wbStruct(AIDT, 'AI Data', [\n      wbInteger('Aggression', itU8),\n      wbInteger('Confidence', itU8),\n      wbInteger('Energy Level', itU8),\n      wbInteger('Responsibility', itU8),\n      wbInteger('Buys/Sells and Services', itU32, wbServiceFlags),\n      wbInteger('Teaches', itS8, wbSkillEnum),\n      wbInteger('Maximum training level', itU8),\n      wbByteArray('Unused', 2)\n    ], cpNormal, True),\n    wbRArray('AI Packages', wbFormIDCk(PKID, 'AI Package', [PACK])),\n    wbArrayS(KFFZ, 'Animations', wbStringLC('Animation')),\n    wbStruct(DATA, 'Creature Data', [\n      wbInteger('Type', itU8, wbEnum([\n        'Creature',\n        'Daedra',\n        'Undead',\n        'Humanoid',\n        'Horse',\n        'Giant'\n      ])),\n      wbInteger('Combat Skill', itU8),\n      wbInteger('Magic Skill', itU8),\n      wbInteger('Stealth Skill', itU8),\n      wbInteger('Soul', itU8, wbSoulGemEnum),\n      wbByteArray('Unused', 1),\n      wbInteger('Health', itU16),\n      wbByteArray('Unused', 2),\n      wbInteger('Attack Damage', itU16),\n      wbInteger('Strength', itU8),\n      wbInteger('Intelligence', itU8),\n      wbInteger('Willpower', itU8),\n      wbInteger('Agility', itU8),\n      wbInteger('Speed', itU8),\n      wbInteger('Endurance', itU8),\n      wbInteger('Personality', itU8),\n      wbInteger('Luck', itU8)\n    ], cpNormal, True),\n    wbInteger(RNAM, 'Attack reach', itU8, nil, cpNormal, True),\n    wbFormIDCk(ZNAM, 'Combat Style', [CSTY]),\n    wbFloat(TNAM, 'Turning Speed', cpNormal, True),\n    wbFloat(BNAM, 'Base Scale', cpNormal, True),\n    wbFloat(WNAM, 'Foot Weight', cpNormal, True),\n    wbString(NAM0, 'Blood Spray'),\n    wbString(NAM1, 'Blood Decal'),\n    wbFormIDCk(CSCR, 'Inherits Sounds from', [CREA]),\n    wbCSDTs\n  ], True);\n\n  wbRecord(CSTY, 'Combat Style', [\n    wbEDID,\n    wbStruct(CSTD, 'Standard', [\n      {000}wbInteger('Dodge % Chance', itU8),\n      {001}wbInteger('Left/Right % Chance', itU8),\n      {002}wbByteArray('Unused', 2),\n      {004}wbFloat('Dodge L/R Timer (min)'),\n      {008}wbFloat('Dodge L/R Timer (max)'),\n      {012}wbFloat('Dodge Forward Timer (min)'),\n      {016}wbFloat('Dodge Forward Timer (max)'),\n      {020}wbFloat('Dodge Back Timer Min'),\n      {024}wbFloat('Dodge Back Timer Max'),\n      {028}wbFloat('Idle Timer min'),\n      {032}wbFloat('Idle Timer max'),\n      {036}wbInteger('Block % Chance', itU8),\n      {037}wbInteger('Attack % Chance', itU8),\n      {038}wbByteArray('Unused', 2),\n      {040}wbFloat('Recoil/Stagger Bonus to Attack'),\n      {044}wbFloat('Unconscious Bonus to Attack'),\n      {048}wbFloat('Hand-To-Hand Bonus to Attack'),\n      {052}wbInteger('Power Attack % Chance', itU8),\n      {053}wbByteArray('Unused', 3),\n      {056}wbFloat('Recoil/Stagger Bonus to Power'),\n      {060}wbFloat('Unconscious Bonus to Power Attack'),\n      {064}wbInteger('Power Attack - Normal', itU8),\n      {065}wbInteger('Power Attack - Forward', itU8),\n      {066}wbInteger('Power Attack - Back', itU8),\n      {067}wbInteger('Power Attack - Left', itU8),\n      {068}wbInteger('Power Attack - Right', itU8),\n      {069}wbByteArray('Unused', 3),\n      {072}wbFloat('Hold Timer (min)'),\n      {076}wbFloat('Hold Timer (max)'),\n      {080}wbInteger('Flags 1', itU8, wbFlags([\n             'Advanced',\n             'Choose Attack using % Chance',\n             'Ignore Allies in Area',\n             'Will Yield',\n             'Rejects Yields',\n             'Fleeing Disabled',\n             'Prefers Ranged',\n             'Melee Alert OK'\n           ])),\n      {081}wbInteger('Acrobatic Dodge % Chance', itU8),\n      {082}wbByteArray('Unused', 2),\n      {084}wbFloat('Range Mult (Optimal)'),\n      {088}wbFloat('Range Mult (Max)'),\n      {092}wbFloat('Switch Distance (Melee)'),\n      {096}wbFloat('Switch Distance (Ranged)'),\n      {100}wbFloat('Buff standoff Distance'),\n      {104}wbFloat('Ranged standoff Distance'),\n      {108}wbFloat('Group standoff Distance'),\n      {112}wbInteger('Rushing Attack % Chance', itU8),\n      {113}wbByteArray('Unused', 3),\n      {116}wbFloat('Rushing Attack Distance Mult'),\n      {120}wbInteger('Flags 2', itU32, wbFlags([\n             'Do Not Acquire'\n           ]))\n    ], cpNormal, True, nil, 31),\n    wbStruct(CSAD, 'Advanced', [\n      wbFloat('Dodge Fatigue Mod Mult'),\n      wbFloat('Dodge Fatigue Mod Base'),\n      wbFloat('Encumb. Speed Mod Base'),\n      wbFloat('Encumb. Speed Mod Mult'),\n      wbFloat('Dodge While Under Attack Mult'),\n      wbFloat('Dodge Not Under Attack Mult'),\n      wbFloat('Dodge Back While Under Attack Mult'),\n      wbFloat('Dodge Back Not Under Attack Mult'),\n      wbFloat('Dodge Forward While Attacking Mult'),\n      wbFloat('Dodge Forward Not Attacking Mult'),\n      wbFloat('Block Skill Modifier Mult'),\n      wbFloat('Block Skill Modifier Base'),\n      wbFloat('Block While Under Attack Mult'),\n      wbFloat('Block Not Under Attack Mult'),\n      wbFloat('Attack Skill Modifier Mult'),\n      wbFloat('Attack Skill Modifier Base'),\n      wbFloat('Attack While Under Attack Mult'),\n      wbFloat('Attack Not Under Attack Mult'),\n      wbFloat('Attack During Block Mult'),\n      wbFloat('Power Att. Fatigue Mod Base'),\n      wbFloat('Power Att. Fatigue Mod Mult')\n    ])\n  ]);\n\n  wbRecord(DIAL, 'Dialog Topic', [\n    wbEDID,\n    wbRArrayS('Quests', wbFormIDCk(QSTI, 'Quest', [QUST], False, cpBenign)),\n    wbRArrayS('Quests?', wbFormIDCk(QSTR, 'Quest?', [QUST], False, cpBenign)),\n    wbFULL,\n    wbInteger(DATA, 'Type', itU8, wbEnum([\n      {0} 'Topic',\n      {1} 'Conversation',\n      {2} 'Combat',\n      {3} 'Persuasion',\n      {4} 'Detection',\n      {5} 'Service',\n      {6} 'Miscellaneous'\n    ]), cpNormal, True)\n  ], True);\n\n  wbRecord(DOOR, 'Door', [\n    wbEDID,\n    wbFULL,\n    wbMODL,\n    wbSCRI,\n    wbFormIDCk(SNAM, 'Open sound', [SOUN]),\n    wbFormIDCk(ANAM, 'Close sound', [SOUN]),\n    wbFormIDCk(BNAM, 'Loop sound', [SOUN]),\n    wbInteger(FNAM, 'Flags', itU8, wbFlags([\n      {0x01} 'Oblivion gate',\n      {0x02} 'Automatic door',\n      {0x04} 'Hidden',\n      {0x08} 'Minimal use'\n    ]), cpNormal, True),\n    wbRArrayS('Random teleport destinations', wbFormIDCk(TNAM, 'Destination', [CELL, WRLD]))\n  ]);\n\n  wbBlendModeEnum := wbEnum([\n    '',\n    'Zero',\n    'One',\n    'Source Color',\n    'Source Inverse Color',\n    'Source Alpha',\n    'Source Inverted Alpha',\n    'Dest Alpha',\n    'Dest Inverted Alpha',\n    'Dest Color',\n    'Dest Inverse Color',\n    'Source Alpha SAT'\n  ]);\n\n  wbBlendOpEnum := wbEnum([\n    '',\n    'Add',\n    'Subtract',\n    'Reverse Subtract',\n    'Minimum',\n    'Maximum'\n  ]);\n  wbZTestFuncEnum := wbEnum([\n    '',\n    '',\n    '',\n    'Equal To',\n    'Normal',\n    'Greater Than',\n    '',\n    'Greater Than or Equal Than',\n    'Always Show'\n  ]);\n\n  wbRecord(EFSH, 'Effect Shader', [\n    wbEDID,\n    wbString(ICON, 'Fill Texture'),\n    wbString(ICO2, 'Particle Shader Texture'),\n    wbStruct(DATA, '', [\n      wbInteger('Flags', itU8, wbFlags([\n        {0} 'No Membrane Shader',\n        {1} '',\n        {2} '',\n        {3} 'No Particle Shader',\n        {4} 'Edge Effect - Inverse',\n        {5} 'Membrane Shader - Affect Skin Only'\n      ])),\n      wbByteArray('Unused', 3),\n      wbInteger('Membrane Shader - Source Blend Mode', itU32, wbBlendModeEnum),\n      wbInteger('Membrane Shader - Blend Operation', itU32, wbBlendOpEnum),\n      wbInteger('Membrane Shader - Z Test Function', itU32, wbZTestFuncEnum),\n      wbStruct('Fill/Texture Effect - Color', [\n        wbInteger('Red', itU8),\n        wbInteger('Green', itU8),\n        wbInteger('Blue', itU8),\n        wbByteArray('Unused', 1)\n      ]),\n      wbFloat('Fill/Texture Effect - Alpha Fade In Time'),\n      wbFloat('Fill/Texture Effect - Full Alpha Time'),\n      wbFloat('Fill/Texture Effect - Alpha Fade Out Time'),\n      wbFloat('Fill/Texture Effect - Presistent Alpha Ratio'),\n      wbFloat('Fill/Texture Effect - Alpha Pulse Amplitude'),\n      wbFloat('Fill/Texture Effect - Alpha Pulse Frequency'),\n      wbFloat('Fill/Texture Effect - Texture Animation Speed (U)'),\n      wbFloat('Fill/Texture Effect - Texture Animation Speed (V)'),\n      wbFloat('Edge Effect - Fall Off'),\n      wbStruct('Edge Effect - Color', [\n        wbInteger('Red', itU8),\n        wbInteger('Green', itU8),\n        wbInteger('Blue', itU8),\n        wbByteArray('Unused', 1)\n      ]),\n      wbFloat('Edge Effect - Alpha Fade In Time'),\n      wbFloat('Edge Effect - Full Alpha Time'),\n      wbFloat('Edge Effect - Alpha Fade Out Time'),\n      wbFloat('Edge Effect - Persistent Alpha Ratio'),\n      wbFloat('Edge Effect - Alpha Pulse Amplitude'),\n      wbFloat('Edge Effect - Alpha Pusle Frequence'),\n      wbFloat('Fill/Texture Effect - Full Alpha Ratio'),\n      wbFloat('Edge Effect - Full Alpha Ratio'),\n      wbInteger('Membrane Shader - Dest Blend Mode', itU32, wbBlendModeEnum),\n      wbInteger('Particle Shader - Source Blend Mode', itU32, wbBlendModeEnum),\n      wbInteger('Particle Shader - Blend Operation', itU32, wbBlendOpEnum),\n      wbInteger('Particle Shader - Z Test Function', itU32, wbZTestFuncEnum),\n      wbInteger('Particle Shader - Dest Blend Mode', itU32, wbBlendModeEnum),\n      wbFloat('Particle Shader - Particle Birth Ramp Up Time'),\n      wbFloat('Particle Shader - Full Particle Birth Time'),\n      wbFloat('Particle Shader - Particle Birth Ramp Down Time'),\n      wbFloat('Particle Shader - Full Particle Birth Ratio'),\n      wbFloat('Particle Shader - Persistant Particle Birth Ratio'),\n      wbFloat('Particle Shader - Particle Lifetime'),\n      wbFloat('Particle Shader - Particle Lifetime +/-'),\n      wbFloat('Particle Shader - Initial Speed Along Normal'),\n      wbFloat('Particle Shader - Acceleration Along Normal'),\n      wbFloat('Particle Shader - Initial Velocity #1'),\n      wbFloat('Particle Shader - Initial Velocity #2'),\n      wbFloat('Particle Shader - Initial Velocity #3'),\n      wbFloat('Particle Shader - Acceleration #1'),\n      wbFloat('Particle Shader - Acceleration #2'),\n      wbFloat('Particle Shader - Acceleration #3'),\n      wbFloat('Particle Shader - Scale Key 1'),\n      wbFloat('Particle Shader - Scale Key 2'),\n      wbFloat('Particle Shader - Scale Key 1 Time'),\n      wbFloat('Particle Shader - Scale Key 2 Time'),\n      wbStruct('Color Key 1 - Color', [\n        wbInteger('Red', itU8),\n        wbInteger('Green', itU8),\n        wbInteger('Blue', itU8),\n        wbByteArray('Unused', 1)\n      ]),\n      wbStruct('Color Key 2 - Color', [\n        wbInteger('Red', itU8),\n        wbInteger('Green', itU8),\n        wbInteger('Blue', itU8),\n        wbByteArray('Unused', 1)\n      ]),\n      wbStruct('Color Key 3 - Color', [\n        wbInteger('Red', itU8),\n        wbInteger('Green', itU8),\n        wbInteger('Blue', itU8),\n        wbByteArray('Unused', 1)\n      ]),\n      wbFloat('Color Key 1 - Color Alpha'),\n      wbFloat('Color Key 2 - Color Alpha'),\n      wbFloat('Color Key 3 - Color Alpha'),\n      wbFloat('Color Key 1 - Color Key Time'),\n      wbFloat('Color Key 2 - Color Key Time'),\n      wbFloat('Color Key 3 - Color Key Time')\n    ], cpNormal, True, nil, 25)\n  ]);\n\n  wbRecord(ENCH, 'Enchantment', [\n    wbEDID,\n    wbStruct(OBME, 'Oblivion Magic Extender', [\n      wbInteger('Record Version', itU8),\n      wbStruct('OBME Version', [\n        wbInteger('Beta', itU8),\n        wbInteger('Minor', itU8),\n        wbInteger('Major', itU8)\n      ]),\n      wbByteArray('Unused', $1C)\n    ], cpNormal, False, wbOBMEDontShow),\n    wbFULL,\n    wbStruct(ENIT, '', [\n      wbInteger('Type', itU32, wbEnum([\n        {0} 'Scroll',\n        {1} 'Staff',\n        {2} 'Weapon',\n        {3} 'Apparel'\n      ])),\n      wbInteger('Charge Amount', itU32),\n      wbInteger('Enchant Cost', itU32),\n      wbInteger('Flags', itU8, wbFlags(['Manual Enchant Cost (Autocalc Off)'])),\n      wbByteArray('Unused', 3)\n    ], cpNormal, True),\n    wbEffects\n  ]);\n\n  wbRecord(EYES, 'Eyes', [\n    wbEDID,\n    wbFULL,\n    wbString(ICON, 'Texture', 0, cpNormal, True),\n    wbInteger(DATA, 'Flags', itU8, wbFlags(['Playable']), cpNormal, True)\n  ]);\n\n  wbXNAM :=\n    wbStructSK(XNAM, [0], 'Relation', [\n      wbFormIDCk('Faction', [FACT, RACE]),\n      wbInteger('Modifier', itS32)\n    ]);\n\n  wbXNAMs := wbRArrayS('Relations', wbXNAM);\n\n  wbRecord(FACT, 'Faction', [\n    wbEDID,\n    wbFULL,\n    wbXNAMs,\n    wbInteger(DATA, 'Flags', itU8, wbFlags(['Hidden from Player', 'Evil', 'Special Combat']), cpNormal, True),\n    wbFloat(CNAM, 'Crime Gold Multiplier', cpNormal, True, 1, -1, nil, nil, 1.0),\n    wbRStructsSK('Ranks', 'Rank', [0], [\n      wbInteger(RNAM, 'Rank#', itS32),\n      wbString(MNAM, 'Male', 0, cpTranslate),\n      wbString(FNAM, 'Female', 0, cpTranslate),\n      wbString(INAM, 'Insignia')\n    ], [])\n  ]);\n\n  wbRecord(FLOR, 'Flora', [\n    wbEDID,\n    wbFULL,\n    wbMODL,\n    wbSCRI,\n    wbFormIDCk(PFIG, 'Ingredient', [INGR]),\n    wbStruct(PFPC, 'Seasonal ingredient production', [\n      wbInteger('Spring', itU8),\n      wbInteger('Summer ', itU8),\n      wbInteger('Fall', itU8),\n      wbInteger('Winter', itU8)\n    ], cpNormal, True)\n  ]);\n\n  wbRecord(FURN, 'Furniture', [\n    wbEDID,\n    wbFULL,\n    wbMODL,\n    wbSCRI,\n    wbByteArray(MNAM, 'Marker Flags', 0, cpNormal, True)\n  ]);\n\n  wbRecord(GLOB, 'Global', [\n    wbEDID,\n    wbInteger(FNAM, 'Type', itU8, wbGLOBFNAM, nil, cpNormal, True),\n    wbFloat(FLTV, 'Value', cpNormal, True)\n  ]);\n\n  wbRecord(GMST, 'Game Setting', [\n    wbEDID,\n    wbUnion(DATA, 'Value', wbGMSTUnionDecider, [\n      wbString('', 0, cpTranslate),\n      wbInteger('', itS32),\n      wbFloat('')\n    ], cpNormal, True)\n  ]);\n\n  wbRecord(GRAS, 'Grass', [\n    wbEDID,\n    wbMODL,\n    wbStruct(DATA, '', [\n      wbInteger('Density', itU8),\n      wbInteger('Min Slope', itU8),\n      wbInteger('Max Slope', itU8),\n      wbByteArray('Unused', 1),\n      wbInteger('Unit from water amount', itU16),\n      wbByteArray('Unused', 2),\n      wbInteger('Unit from water type', itU32, wbEnum([\n        'Above - At Least',\n        'Above - At Most',\n        'Below - At Least',\n        'Below - At Most',\n        'Either - At Least',\n        'Either - At Most',\n        'Either - At Most Above',\n        'Either - At Most Below'\n      ])),\n      wbFloat('Position Range'),\n      wbFloat('Height Range'),\n      wbFloat('Color Range'),\n      wbFloat('Wave Period'),\n      wbInteger('Flags', itU8, wbFlags([\n        'Vertex Lighting',\n        'Uniform Scaling',\n        'Fit to Slope'\n      ])),\n      wbByteArray('Unused', 3)\n    ], cpNormal, True)\n  ]);\n\n  wbRecord(HAIR, 'Hair', [\n    wbEDID,\n    wbFULL,\n    wbMODL,\n    wbString(ICON, 'Texture', 0, cpNormal, True),\n    wbInteger(DATA, 'Flags', itU8, wbFlags([\n      'Playable',\n      'Not Male',\n      'Not Female',\n      'Fixed'\n    ]), cpNormal, True)\n  ]);\n\n  wbCrimeTypeEnum :=\n    wbEnum([\n      'Steal',\n      'Pickpocket',\n      'Trespass',\n      'Attack',\n      'Murder',\n      'Steal Horse'\n    ], [\n      -1, 'None'\n    ]);\n\n  wbFormTypeEnum :=\n    wbEnum([], [\n      $03, 'Game Setting',\n      $04, 'Global',\n      $05, 'Class',\n      $06, 'Faction',\n      $07, 'Hair',\n      $08, 'Eyes',\n      $09, 'Race',\n      $0A, 'Sound',\n      $0B, 'Skill',\n      $0C, 'Magic Effect',\n      $0D, 'Script',\n      $0E, 'Land Texture',\n      $0F, 'Enchantment',\n      $10, 'Spell',\n      $11, 'BirthSign',\n      $12, 'Activator',\n      $13, 'Apparatus',\n      $14, 'Armor',\n      $15, 'Book',\n      $16, 'Clothing',\n      $17, 'Container',\n      $18, 'Door',\n      $19, 'Ingredient',\n      $1A, 'Light',\n      $1B, 'Misc',\n      $1C, 'Static',\n      $1D, 'Grass',\n      $1E, 'Tree',\n      $1F, 'Flora',\n      $20, 'Furniture',\n      $21, 'Weapon',\n      $22, 'Ammi',\n      $23, 'NPC',\n      $24, 'Creature',\n      $25, 'Leveled Creature',\n      $26, 'Soul Gem',\n      $27, 'Key',\n      $28, 'Alchemy',\n      $29, 'SubSpace',\n      $2A, 'Sigil Stone',\n      $2B, 'Leveled Item',\n      $2D, 'Weather',\n      $2E, 'Climate',\n      $2F, 'Region',\n      $30, 'Cell',\n      $31, 'Placed Object',\n      $32, 'Placed NPC',\n      $33, 'Placed Creature',\n      $34, 'Path Grid',\n      $35, 'Worldspace',\n      $36, 'Landscape',\n      $38, 'Road',\n      $39, 'Dialog Topic',\n      $3A, 'Dialog Response',\n      $3B, 'Quest',\n      $3C, 'Idle Animation',\n      $3D, 'Package',\n      $3E, 'Combat Style',\n      $3F, 'Load Screen',\n      $40, 'Leveled Spell',\n      $41, 'Animated Object',\n      $42, 'Water',\n      $43, 'Effect Shader'\n  ]);\n\n  wbSexEnum :=\n    wbEnum(['Male','Female']);\n\n  wbAxisEnum :=\n    wbEnum([], [\n      88, 'X',\n      89, 'Y',\n      90, 'Z'\n    ]);\n\n  wbCTDA :=\n    wbRUnion('Condition', [\n      wbStruct(CTDA, 'Condition', [\n        wbInteger('Type', itU8, wbCtdaType),\n        wbByteArray('Unused', 3),\n        wbUnion('Comparison Value', wbCTDACompValueDecider, [\n          wbFloat('Comparison Value - Float'),\n          wbFormIDCk('Comparison Value - Global', [GLOB])\n        ]),\n        wbInteger('Function', itU32, wbCTDAFunctionToStr, wbCTDAFunctionToInt),\n        wbUnion('Parameter #1', wbCTDAParam1Decider, [\n          {00} wbByteArray('Unknown', 4),\n          {01} wbByteArray('None', 4, cpIgnore),\n          {02} wbInteger('Integer', itS32),\n          {03} wbInteger('Variable Name (INVALID)', itS32),\n          {04} wbInteger('Sex', itU32, wbSexEnum),\n          {05} wbFormIDCk('Actor Value', [ACVA]),\n//          {05} wbInteger('Actor Value', itS32, wbActorValueEnum),\n          {06} wbInteger('Crime Type', itU32, wbCrimeTypeEnum),\n          {07} wbInteger('Axis', itU32, wbAxisEnum),\n          {08} wbInteger('Form Type', itU32, wbFormTypeEnum),\n          {09} wbInteger('Quest Stage (INVALID)', itS32),\n          {10} wbFormIDCk('Object Reference', [PLYR, REFR, ACHR, ACRE, TRGT]),\n          {12} wbFormIDCk('Inventory Object', [ARMO, AMMO, MISC, WEAP, INGR, SLGM, SGST, BOOK, KEYM, CLOT, ALCH, APPA, LIGH]),\n          {13} wbFormIDCk('Actor', [PLYR, ACHR, ACRE, TRGT]),\n          {14} wbFormIDCk('Quest', [QUST]),\n          {15} wbFormIDCk('Faction', [FACT]),\n          {16} wbFormIDCk('Cell', [CELL]),\n          {17} wbFormIDCk('Class', [CLAS]),\n          {18} wbFormIDCk('Race', [RACE]),\n          {19} wbFormIDCk('Actor Base', [NPC_, CREA, ACTI]),\n          {20} wbFormIDCk('Global', [GLOB]),\n          {21} wbFormIDCk('Weather', [WTHR]),\n          {22} wbFormIDCk('Package', [PACK]),\n          {23} wbFormIDCk('Owner', [FACT, NPC_]),\n          {24} wbFormIDCk('Birthsign', [BSGN]),\n          {25} wbFormIDCk('Furniture', [FURN]),\n          {26} wbFormIDCk('Magic Item', [SPEL]),\n          {27} wbFormIDCk('Magic Effect', [MGEF]),\n          {28} wbFormIDCk('Worldspace', [WRLD]),\n          {29} wbFormIDCk('Referenceable Object', [CREA, NPC_, TREE, SBSP, LVLC, SOUN, ACTI, DOOR, FLOR, STAT, FURN, CONT, ARMO, AMMO, MISC, WEAP, INGR, SLGM, SGST, BOOK, KEYM, CLOT, ALCH, APPA, LIGH, GRAS])\n        ]),\n        wbUnion('Parameter #2', wbCTDAParam2Decider, [\n          {00} wbByteArray('Unknown', 4),\n          {01} wbByteArray('None', 4, cpIgnore),\n          {02} wbInteger('Integer', itS32),\n          {03} wbInteger('Variable Name', itS32, wbCTDAParam2VariableNameToStr, wbCTDAParam2VariableNameToInt),\n          {04} wbInteger('Sex', itU32, wbSexEnum),\n          {05} wbFormIDCk('Actor Value', [ACVA]),\n//          {05} wbInteger('Actor Value', itS32, wbActorValueEnum),\n          {06} wbInteger('Crime Type', itU32, wbCrimeTypeEnum),\n          {07} wbInteger('Axis', itU32, wbAxisEnum),\n          {08} wbInteger('Form Type', itU32, wbFormTypeEnum),\n          {09} wbInteger('Quest Stage', itS32, wbCTDAParam2QuestStageToStr, wbCTDAParam2QuestStageToInt),\n          {10} wbFormIDCk('Object Reference', [PLYR, REFR, ACHR, ACRE, TRGT]),\n          {12} wbFormIDCk('Inventory Object', [ARMO, AMMO, MISC, WEAP, INGR, SLGM, SGST, BOOK, KEYM, CLOT, ALCH, APPA, LIGH]),\n          {13} wbFormIDCk('Actor', [PLYR, ACHR, ACRE, TRGT]),\n          {14} wbFormIDCk('Quest', [QUST]),\n          {15} wbFormIDCk('Faction', [FACT]),\n          {16} wbFormIDCk('Cell', [CELL]),\n          {17} wbFormIDCk('Class', [CLAS]),\n          {18} wbFormIDCk('Race', [RACE]),\n          {19} wbFormIDCk('Actor Base', [NPC_, CREA, ACTI]),\n          {20} wbFormIDCk('Global', [GLOB]),\n          {21} wbFormIDCk('Weather', [WTHR]),\n          {22} wbFormIDCk('Package', [PACK]),\n          {23} wbFormIDCk('Owner', [FACT, NPC_]),\n          {24} wbFormIDCk('Birthsign', [BSGN]),\n          {25} wbFormIDCk('Furniture', [FURN]),\n          {26} wbFormIDCk('Magic Item', [SPEL]),\n          {27} wbFormIDCk('Magic Effect', [MGEF]),\n          {28} wbFormIDCk('Worldspace', [WRLD]),\n          {29} wbFormIDCk('Referenceable Object', [CREA, NPC_, TREE, SBSP, LVLC, SOUN, ACTI, DOOR, FLOR, STAT, FURN, CONT, ARMO, AMMO, MISC, WEAP, INGR, SLGM, SGST, BOOK, KEYM, CLOT, ALCH, APPA, LIGH, GRAS])\n        ]),\n        wbInteger('Unused', itU32, nil, cpIgnore)\n      ], cpNormal, False, nil, 6),\n      wbStruct(CTDT, 'Condition (old format)', [\n        wbInteger('Type', itU8, wbCtdaType),\n        wbByteArray('Unused', 3),\n        wbUnion('Comparison Value', wbCTDACompValueDecider, [\n          wbFloat('Comparison Value - Float'),\n          wbFormIDCk('Comparison Value - Global', [GLOB])\n        ]),\n        wbInteger('Function', itU32, wbCTDAFunctionToStr, wbCTDAFunctionToInt),\n        wbUnion('Parameter #1', wbCTDAParam1Decider, [\n          {00} wbByteArray('Unknown', 4),\n          {01} wbByteArray('None', 4, cpIgnore),\n          {02} wbInteger('Integer', itS32),\n          {03} wbInteger('Variable Name (INVALID)', itS32),\n          {04} wbInteger('Sex', itU32, wbSexEnum),\n          {05} wbFormIDCk('Actor Value', [ACVA]),\n//          {05} wbInteger('Actor Value', itS32, wbActorValueEnum),\n          {06} wbInteger('Crime Type', itU32, wbCrimeTypeEnum),\n          {07} wbInteger('Axis', itU32, wbAxisEnum),\n          {08} wbInteger('Form Type', itU32, wbFormTypeEnum),\n          {09} wbInteger('Quest Stage (INVALID)', itS32),\n          {10} wbFormIDCk('Object Reference', [PLYR, REFR, ACHR, ACRE, TRGT]),\n          {12} wbFormIDCk('Inventory Object', [ARMO, AMMO, MISC, WEAP, INGR, SLGM, SGST, BOOK, KEYM, CLOT, ALCH, APPA, LIGH]),\n          {13} wbFormIDCk('Actor', [PLYR, ACHR, ACRE, TRGT]),\n          {14} wbFormIDCk('Quest', [QUST]),\n          {15} wbFormIDCk('Faction', [FACT]),\n          {16} wbFormIDCk('Cell', [CELL]),\n          {17} wbFormIDCk('Class', [CLAS]),\n          {18} wbFormIDCk('Race', [RACE]),\n          {19} wbFormIDCk('Actor Base', [NPC_, CREA, ACTI]),\n          {20} wbFormIDCk('Global', [GLOB]),\n          {21} wbFormIDCk('Weather', [WTHR]),\n          {22} wbFormIDCk('Package', [PACK]),\n          {23} wbFormIDCk('Owner', [FACT, NPC_]),\n          {24} wbFormIDCk('Birthsign', [BSGN]),\n          {25} wbFormIDCk('Furniture', [FURN]),\n          {26} wbFormIDCk('Magic Item', [SPEL]),\n          {27} wbFormIDCk('Magic Effect', [MGEF]),\n          {28} wbFormIDCk('Worldspace', [WRLD]),\n          {29} wbFormIDCk('Referenceable Object', [CREA, NPC_, TREE, SBSP, LVLC, SOUN, ACTI, DOOR, FLOR, STAT, FURN, CONT, ARMO, AMMO, MISC, WEAP, INGR, SLGM, SGST, BOOK, KEYM, CLOT, ALCH, APPA, LIGH, GRAS])\n        ]),\n        wbUnion('Parameter #2', wbCTDAParam2Decider, [\n          {00} wbByteArray('Unknown', 4),\n          {01} wbByteArray('None', 4, cpIgnore),\n          {02} wbInteger('Integer', itS32),\n          {03} wbInteger('Variable Name', itS32, wbCTDAParam2VariableNameToStr, wbCTDAParam2VariableNameToInt),\n          {04} wbInteger('Sex', itU32, wbSexEnum),\n          {05} wbFormIDCk('Actor Value', [ACVA]),\n//          {05} wbInteger('Actor Value', itS32, wbActorValueEnum),\n          {06} wbInteger('Crime Type', itU32, wbCrimeTypeEnum),\n          {07} wbInteger('Axis', itU32, wbAxisEnum),\n          {08} wbInteger('Form Type', itU32, wbFormTypeEnum),\n          {09} wbInteger('Quest Stage', itS32, wbCTDAParam2QuestStageToStr, wbCTDAParam2QuestStageToInt),\n          {10} wbFormIDCk('Object Reference', [PLYR, REFR, ACHR, ACRE, TRGT]),\n          {12} wbFormIDCk('Inventory Object', [ARMO, AMMO, MISC, WEAP, INGR, SLGM, SGST, BOOK, KEYM, CLOT, ALCH, APPA, LIGH]),\n          {13} wbFormIDCk('Actor', [PLYR, ACHR, ACRE, TRGT]),\n          {14} wbFormIDCk('Quest', [QUST]),\n          {15} wbFormIDCk('Faction', [FACT]),\n          {16} wbFormIDCk('Cell', [CELL]),\n          {17} wbFormIDCk('Class', [CLAS]),\n          {18} wbFormIDCk('Race', [RACE]),\n          {19} wbFormIDCk('Actor Base', [NPC_, CREA, ACTI]),\n          {20} wbFormIDCk('Global', [GLOB]),\n          {21} wbFormIDCk('Weather', [WTHR]),\n          {22} wbFormIDCk('Package', [PACK]),\n          {23} wbFormIDCk('Owner', [FACT, NPC_]),\n          {24} wbFormIDCk('Birthsign', [BSGN]),\n          {25} wbFormIDCk('Furniture', [FURN]),\n          {26} wbFormIDCk('Magic Item', [SPEL]),\n          {27} wbFormIDCk('Magic Effect', [MGEF]),\n          {28} wbFormIDCk('Worldspace', [WRLD]),\n          {29} wbFormIDCk('Referenceable Object', [CREA, NPC_, TREE, SBSP, LVLC, SOUN, ACTI, DOOR, FLOR, STAT, FURN, CONT, ARMO, AMMO, MISC, WEAP, INGR, SLGM, SGST, BOOK, KEYM, CLOT, ALCH, APPA, LIGH, GRAS])\n        ]),\n        wbEmpty('Unused', cpIgnore)\n      ])\n    ], []);\n\n  wbCTDAs := wbRArray('Conditions', wbCTDA);\n\n  wbSCHR :=\n    wbRUnion('Basic Script Data', [\n      wbStruct(SCHR, 'Basic Script Data', [\n        wbByteArray('Unused', 4),\n        wbInteger('RefCount', itU32),\n        wbInteger('CompiledSize', itU32),\n        wbInteger('VariableCount', itU32),\n        wbInteger('Type', itU32, wbEnum([\n          'Object',\n          'Quest'\n        ], [\n          $100, 'Magic Effect'\n        ]))\n      ]),\n      wbStruct(SCHD, 'Basic Script Data', [\n        wbByteArray('Unused', 4),\n        wbInteger('RefCount', itU32),\n        wbInteger('CompiledSize', itU32),\n        wbInteger('VariableCount', itU32),\n        wbInteger('Type', itU32, wbEnum([\n          'Object',\n          'Quest'\n        ], [\n          $100, 'Magic Effect'\n        ]))\n      ])\n    ], []);\n\n  wbSCROs :=\n    wbRArray('References',\n      wbRUnion('', [\n        wbFormIDCk(SCRO, 'Global Reference',\n          [ACTI, DOOR, FLOR, STAT, FURN, CREA, SPEL, NPC_, CONT, ARMO, AMMO, MISC, WEAP,\n           INGR, SLGM, SGST, BOOK, KEYM, CLOT, ALCH, APPA, LIGH, QUST, PLYR, PACK, LVLI,\n           FACT, ACHR, REFR, ACRE, GLOB, DIAL, CELL, SOUN, MGEF, WTHR, CLAS, EFSH, RACE,\n           LVLC, CSTY, WRLD, SCPT, BSGN, TREE, NULL]),\n        wbInteger(SCRV, 'Local Variable', itU32)\n      ], [])\n    );\n\n  wbResultScript := wbRStruct('Result Script', [\n    wbSCHR,\n    wbByteArray(SCDA, 'Compiled result script'),\n    wbStringScript(SCTX, 'Result script source'),\n    wbSCROs\n  ], []);\n{\n  wbResultScriptOld := wbRStruct('Result Script (Old Format?)', [\n    wbByteArray(SCHD, 'Unknown (Script Header?)'),\n    wbByteArray(SCDA, 'Compiled result script'),\n    wbStringScript(SCTX, 'Result script source'),\n    wbSCROs\n  ], []);\n}\n  wbRecord(IDLE, 'Idle Animation', [\n    wbEDID,\n    wbMODL,\n    wbCTDAs,\n    wbInteger(ANAM, 'Animation Group Section', itU8, wbIdleAnam, nil, cpNormal, True),\n    wbArray(DATA, 'Related Idle Animations', wbFormIDCk('Related Idle Animation', [IDLE, NULL]), ['Parent', 'Previous Sibling'], cpNormal, True)\n  ]);\n\n  wbRecord(INFO, 'Dialog response', [\n    wbStruct(DATA, '', [\n      wbInteger('Type', itU8, wbEnum([\n        {0} 'Topic',\n        {1} 'Conversation',\n        {2} 'Combat',\n        {3} 'Persuasion',\n        {4} 'Detection',\n        {5} 'Service',\n        {6} 'Miscellaneous'\n      ])),\n      wbInteger('Flags', itU8, wbFlags([\n        {0x0001} 'Goodbye',\n        {0x0002} 'Random',\n        {0x0004} 'Say Once',\n        {0x0008} '',\n        {0x0010} 'Info Refusal',\n        {0x0020} 'Random End',\n        {0x0040} 'Run for Rumors'\n      ])),\n      wbByteArray('Unused', 1)\n    ], cpNormal, True),\n    wbFormIDCk(QSTI, 'Quest', [QUST], False, cpNormal, True),\n    wbFormIDCk(TPIC, 'Topic', [DIAL]),\n    wbFormIDCk(PNAM, 'Previous INFO', [INFO, NULL]),\n    wbRArray('Add topics', wbFormIDCk(NAME, 'Topic', [DIAL])),\n    wbRArray('Responses',\n      wbRStruct('Response', [\n        wbStruct(TRDT, 'Response Data', [\n          wbInteger('Emotion Type', itU32, wbEnum([\n            {0} 'Neutral',\n            {1} 'Anger',\n            {2} 'Disgust',\n            {3} 'Fear',\n            {4} 'Sad',\n            {5} 'Happy',\n            {6} 'Surprise'\n          ])),\n          wbInteger('Emotion Value', itS32),\n          wbByteArray('Unused', 4),\n          wbInteger('Response number', itU8),\n          wbByteArray('Unused', 3)\n        ]),\n        wbString(NAM1, 'Response Text', 0, cpTranslate),\n        wbString(NAM2, 'Actor notes', 0, cpTranslate)\n      ], [])\n    ),\n    wbCTDAs,\n    wbRArray('Choices', wbFormIDCk(TCLT, 'Choice', [DIAL])),\n    wbRArray('Link From', wbFormIDCk(TCLF, 'Topic', [DIAL])),\n    wbResultScript\n  ]);\n\n  wbRecord(INGR, 'Ingredient', [\n    wbEDID,\n    wbStruct(OBME, 'Oblivion Magic Extender', [\n      wbInteger('Record Version', itU8),\n      wbStruct('OBME Version', [\n        wbInteger('Beta', itU8),\n        wbInteger('Minor', itU8),\n        wbInteger('Major', itU8)\n      ]),\n      wbByteArray('Unused', $1C)\n    ], cpNormal, False, wbOBMEDontShow),\n    wbFULL,\n    wbMODL,\n    wbICON,\n    wbSCRI,\n    wbFloat(DATA, 'Weight', cpNormal, True),\n    wbStruct(ENIT, '', [\n      wbInteger('Value', itS32),\n      wbInteger('Flags', itU8, wbFlags(['No auto-calculation', 'Food item'])),\n      wbByteArray('Unused', 3)\n    ], cpNormal, True),\n    wbEffects\n  ]);\n\n  wbRecord(KEYM, 'Key', [\n    wbEDID,\n    wbFULL,\n    wbMODL,\n    wbICON,\n    wbSCRI,\n    wbStruct(DATA, '', [\n      wbInteger('Value', itS32),\n      wbFloat('Weight')\n    ], cpNormal, True)\n  ]);\n\n  wbQuadrantEnum := wbEnum([\n    {0} 'Bottom Left',\n    {1} 'Bottom Right',\n    {2} 'Top Left',\n    {3} 'Top Right'\n  ]);\n\n  if wbSimpleRecords then begin\n\n    wbRecord(LAND, 'Landscape', [\n      wbByteArray(DATA, 'Unknown'),\n      wbByteArray(VNML, 'Vertex Normals'),\n      wbByteArray(VHGT, 'Vertext Height Map'),\n      wbByteArray(VCLR, 'Vertex Colours'),\n\n      wbRArrayS('Layers', wbRUnion('Layer', [\n        wbRStructSK([0],'Base Layer', [\n          wbStructSK(BTXT, [1, 3], 'Base Layer Header', [\n            wbFormIDCk('Texture', [LTEX, NULL]),\n            wbInteger('Quadrant', itU8, wbQuadrantEnum),\n            wbByteArray('Unused', 1),\n            wbInteger('Layer', itS16)\n          ])\n        ], []),\n        wbRStructSK([0],'Alpha Layer', [\n          wbStructSK(ATXT, [1, 3], 'Alpha Layer Header', [\n            wbFormIDCk('Texture', [LTEX, NULL]),\n            wbInteger('Quadrant', itU8, wbQuadrantEnum),\n            wbByteArray('Unused', 1),\n            wbInteger('Layer', itS16)\n          ]),\n          wbByteArray(VTXT, 'Alpha Layer Data')\n        ], [])\n      ], [])),\n\n      wbArray(VTEX, 'Textures', wbFormIDCk('Texture', [LTEX, NULL]))\n    ]);\n\n  end else begin\n\n    wbRecord(LAND, 'Landscape', [\n      wbByteArray(DATA, 'Unknown'),\n//      wbStruct(DATA, '', [\n//        wbInteger('Flags', itU8, wbFlags([])),\n//        wbByteArray('Unknown')\n//      ]),\n      wbArray(VNML, 'Vertex Normals', wbStruct('Row', [\n        wbArray('Columns', wbStruct('Column', [\n          wbInteger('X', itU8),\n          wbInteger('Y', itU8),\n          wbInteger('Z', itU8)\n        ]), 33)\n      ]), 33),\n      wbStruct(VHGT, 'Vertext Height Map', [\n        wbFloat('Offset'),\n        wbArray('Rows', wbStruct('Row', [\n          wbArray('Columns', wbInteger('Column', itU8), 33)\n        ]), 33),\n        wbByteArray('Unused', 3)\n      ]),\n      wbArray(VCLR, 'Vertex Colours', wbStruct('Row', [\n        wbArray('Columns', wbStruct('Column', [\n          wbInteger('X', itU8),\n          wbInteger('Y', itU8),\n          wbInteger('Z', itU8)\n        ]), 33)\n      ]), 33),\n\n      wbRArrayS('Layers', wbRUnion('Layer', [\n        wbRStructSK([0],'Base Layer', [\n          wbStructSK(BTXT, [1, 3], 'Base Layer Header', [\n            wbFormIDCk('Texture', [LTEX, NULL]),\n            wbInteger('Quadrant', itU8, wbQuadrantEnum),\n            wbByteArray('Unused', 1),\n            wbInteger('Layer', itS16)\n          ])\n        ], []),\n        wbRStructSK([0],'Alpha Layer', [\n          wbStructSK(ATXT, [1, 3], 'Alpha Layer Header', [\n            wbFormIDCk('Texture', [LTEX, NULL]),\n            wbInteger('Quadrant', itU8, wbQuadrantEnum),\n            wbByteArray('Unused', 1),\n            wbInteger('Layer', itS16)\n          ]),\n          wbArrayS(VTXT, 'Alpha Layer Data', wbStructSK([0], 'Cell', [\n            wbInteger('Position', itU16, wbAtxtPosition),\n            wbByteArray('Unused', 2),\n            wbFloat('Opacity')\n          ]))\n        ], [])\n      ], [])),\n\n      wbArray(VTEX, 'Textures', wbFormIDCk('Texture', [LTEX, NULL]))\n    ]);\n\n  end;\n\n  wbRecord(LIGH, 'Light', [\n    wbEDID,\n    wbMODL,\n    wbSCRI,\n    wbFULL,\n    wbICON,\n    wbStruct(DATA, '', [\n      wbInteger('Time', itS32),\n      wbInteger('Radius', itU32),\n      wbStruct('Color', [\n        wbInteger('Red', itU8),\n        wbInteger('Green', itU8),\n        wbInteger('Blue', itU8),\n        wbInteger('Unused', itU8)\n      ]),\n      wbInteger('Flags', itU32, wbFlags([\n        {0x00000001} 'Dynamic',\n        {0x00000002} 'Can be Carried',\n        {0x00000004} 'Negative',\n        {0x00000008} 'Flicker',\n        {0x00000010} 'Unused',\n        {0x00000020} 'Off By Default',\n        {0x00000040} 'Flicker Slow',\n        {0x00000080} 'Pulse',\n        {0x00000100} 'Pulse Slow',\n        {0x00000200} 'Spot Light',\n        {0x00000400} 'Spot Shadow'\n      ])),\n      wbFloat('Falloff Exponent'),\n      wbFloat('FOV'),\n      wbInteger('Value', itU32),\n      wbFloat('Weight')\n    ], cpNormal, True, nil, 6),\n    wbFloat(FNAM, 'Fade value', cpNormal, True, 1, -1, nil, nil, 1.0),\n    wbFormIDCk(SNAM, 'Sound', [SOUN])\n  ], False, nil, cpNormal, False, wbLIGHAfterLoad);\n\n  wbRecord(LSCR, 'Load Screen', [\n    wbEDID,\n    wbICON,\n    wbDESC,\n    wbRArrayS('Locations', wbStructSK(LNAM, [0, 1], 'Location', [\n      wbFormIDCk('Direct', [CELL, WRLD, NULL]),\n      wbStructSK([0, 1], 'Indirect', [\n        wbFormIDCk('World', [NULL, WRLD]),\n        wbStructSK([0,1], 'Grid', [\n          wbInteger('Y', itS16),\n          wbInteger('X', itS16)\n        ])\n      ])\n    ]))\n  ]);\n\n  wbRecord(LTEX, 'Landscape Texture', [\n    wbEDID,\n    wbICON,\n    wbStruct(HNAM, 'Havok Data', [\n      wbInteger('Material Type', itU8, wbEnum([\n        {00} 'STONE',\n        {01} 'CLOTH',\n        {02} 'DIRT',\n        {03} 'GLASS',\n        {04} 'GRASS',\n        {05} 'METAL',\n        {06} 'ORGANIC',\n        {07} 'SKIN',\n        {08} 'WATER',\n        {09} 'WOOD',\n        {10} 'HEAVY STONE',\n        {11} 'HEAVY METAL',\n        {12} 'HEAVY WOOD',\n        {13} 'CHAIN',\n        {14} 'SNOW'\n      ]), cpNormal, True, nil, nil, 2),\n      wbInteger('Friction', itU8, nil, cpNormal, True, nil, nil, 30),\n      wbInteger('Restitution', itU8, nil, cpNormal, True, nil, nil, 30)\n    ], cpNormal, True),\n    wbInteger(SNAM, 'Texture Specular Exponent', itU8, nil, cpNormal, True, False, nil, nil, 30),\n    wbRArrayS('Grasses', wbFormIDCk(GNAM, 'Grass', [GRAS]))\n  ]);\n\n  wbRecord(LVLC, 'Leveled Creature', [\n    wbEDID,\n    wbInteger(LVLD, 'Chance none', itU8, nil, cpNormal, True),\n    wbInteger(LVLF, 'Flags', itU8, wbFlags([\n      {0x01} 'Calculate from all levels <= player''s level',\n      {0x02} 'Calculate for each item in count'\n    ]), cpNormal, True),\n    wbRArrayS('Leveled List Entries',\n      wbStructExSK(LVLO , [0, 2], [3], 'Leveled List Entry', [\n        wbInteger('Level', itS16),\n        wbByteArray('Unused', 2),\n        wbFormIDCk('Reference', [NPC_, CREA, LVLC]),\n        wbInteger('Count', itS16),\n        wbByteArray('Unused', 2)\n      ], cpNormal, False, nil, 3),\n    cpNormal, True),\n    wbSCRI,\n    wbFormIDCk(TNAM, 'Creature template', [NPC_, CREA])\n  ], True, nil, cpNormal, False, wbLVLAfterLoad);\n\n  wbRecord(LVLI, 'Leveled Item', [\n    wbEDID,\n    wbInteger(LVLD, 'Chance none', itU8, nil, cpNormal, True),\n    wbInteger(LVLF, 'Flags', itU8, wbFlags([\n      {0x01} 'Calculate from all levels <= player''s level',\n      {0x02} 'Calculate for each item in count'\n    ]), cpNormal, True),\n    wbRArrayS('Leveled List Entries',\n      wbStructExSK(LVLO , [0, 2], [3], 'Leveled List Entry', [\n        wbInteger('Level', itS16),\n        wbByteArray('Unused', 2),\n        wbFormIDCk('Reference', [ARMO, AMMO, MISC, WEAP, INGR, SLGM, SGST, BOOK, LVLI, KEYM, CLOT, ALCH, APPA, LIGH]),\n        wbInteger('Count', itS16),\n        wbByteArray('Unused', 2)\n      ], cpNormal, False, nil, 3),\n    cpNormal, True),\n    wbByteArray(DATA, 'Unused', 1)\n  ], False, nil, cpNormal, False, wbLVLAfterLoad);\n\n  wbRecord(LVSP, 'Leveled Spell', [\n    wbEDID,\n    wbInteger(LVLD, 'Chance none', itU8, nil, cpNormal, True),\n    wbInteger(LVLF, 'Flags', itU8, wbFlags([\n      {0x01} 'Calculate from all levels <= player''s level',\n      {0x02} 'Calculate for each item in count',\n      {0x04} 'Use all spells'\n    ]), cpNormal, True),\n    wbRArrayS('Leveled List Entries',\n      wbStructExSK(LVLO , [0, 2], [3], 'Leveled List Entry', [\n        wbInteger('Level', itS16),\n        wbByteArray('Unused', 2),\n        wbFormIDCk('Reference', [SPEL, LVSP]),\n        wbInteger('Count', itS16),\n        wbByteArray('Unused', 2)\n      ], cpNormal, False, nil, 3),\n    cpNormal, True)\n  ], False, nil, cpNormal, False, wbLVLAfterLoad);\n\n  wbRecord(MGEF, 'Magic Effect', [\n    wbStringMgefCode(EDID, 'Magic Effect Code'),\n    wbStruct(OBME, 'Oblivion Magic Extender', [\n      wbInteger('Record Version', itU8),\n      wbStruct('OBME Version', [\n        wbInteger('Beta', itU8),\n        wbInteger('Minor', itU8),\n        wbInteger('Major', itU8)\n      ]),\n      wbInteger('Param A Info', itU8, wbOBMEResolutionInfo),\n      wbInteger('Param B Info', itU8, wbOBMEResolutionInfo),\n      wbByteArray('Unused', 2),\n      wbString('Handler', 4),\n      wbInteger('Flag Overrides', itU32, wbFlags([\n        { 0} '',\n        { 1} '',\n        { 2} 'ParamFlagA',\n        { 3} 'Beneficial',\n        { 4} '',\n        { 5} '',\n        { 6} '',\n        { 7} '',\n        { 8} '',\n        { 9} '',\n        {10} '',\n        {11} '',\n        {12} '',\n        {13} '',\n        {14} '',\n        {15} '',\n        {16} 'ParamFlagB',\n        {17} 'Magnitude Is Range',\n        {18} 'Atomic Resistance',\n        {19} 'ParamFlagC',\n        {20} 'ParamFlagD',\n        {21} '',\n        {22} '',\n        {23} '',\n        {24} '',\n        {25} '',\n        {26} '',\n        {27} '',\n        {28} '',\n        {29} '',\n        {30} 'Hidden'\n      ])),\n      wbByteArray('ParamB', 4),\n      wbByteArray('Unused', $1C)\n    ], cpNormal, False, wbOBMEDontShow),\n    wbString(EDDX, 'EditorID', 0, cpNormal, False, wbEDDXDontShow),\n    wbFULL,\n    wbDESC,\n    wbICON,\n    wbMODL,\n    wbStruct(DATA, 'Data', [\n      wbInteger('Flags', itU32, wbFlags([\n        {0x00000001} 'Hostile',\n        {0x00000002} 'Recover',\n        {0x00000004} 'Detrimental',\n        {0x00000008} 'Magnitude %',\n        {0x00000010} 'Self',\n        {0x00000020} 'Touch',\n        {0x00000040} 'Target',\n        {0x00000080} 'No duration',\n        {0x00000100} 'No magnitude',\n        {0x00000200} 'No area',\n        {0x00000400} 'FX persist',\n        {0x00000800} 'Spellmaking',\n        {0x00001000} 'Enchanting',\n        {0x00002000} 'No Ingredient',\n        {0x00004000} '',\n        {0x00008000} '',\n        {0x00010000} 'Use weapon',\n        {0x00020000} 'Use armor',\n        {0x00040000} 'Use creature',\n        {0x00080000} 'Use skill',\n        {0x00100000} 'Use attribute',\n        {0x00200000} '',\n        {0x00400000} '',\n        {0x00800000} '',\n        {0x01000000} 'Use actor value',\n        {0x02000000} 'Spray projectile type (or Fog if Bolt is specified as well)',\n        {0x04000000} 'Bolt projectile type',\n        {0x08000000} 'No hit effect'\n      ])),\n      wbFloat('Base cost'),\n      wbUnion('Assoc. Item', wbMGEFFAssocItemDecider, [\n        wbFormIDCk('Unused', [NULL]),\n        wbFormIDCk('Assoc. Weapon', [WEAP]),\n        wbFormIDCk('Assoc. Armor', [ARMO, NULL{?}]),\n        wbFormIDCk('Assoc. Creature', [CREA, LVLC, NPC_]),\n        wbInteger('Assoc. Actor Value', itS32, wbActorValueEnum)\n      ]),\n      wbInteger('Magic School', itS32, wbMagicSchoolEnum),\n      wbInteger('Resist value', itS32, wbActorValueEnum),\n      wbInteger('Counter Effect Count', itU16), //!!! must be updated automatically when ESCE length changes!\n      wbByteArray('Unused', 2),\n      wbFormIDCk('Light', [LIGH, NULL]),\n      wbFloat('Projectile speed'),\n      wbFormIDCk('Effect Shader', [EFSH, NULL]),\n      wbFormIDCk('Enchant effect', [EFSH, NULL]),\n      wbFormIDCk('Casting sound', [NULL, SOUN]),\n      wbFormIDCk('Bolt sound', [NULL, SOUN]),\n      wbFormIDCk('Hit sound', [NULL, SOUN]),\n      wbFormIDCk('Area sound', [NULL, SOUN]),\n      wbFloat('Constant Effect enchantment factor'),\n      wbFloat('Constant Effect barter factor')\n    ], cpNormal, True, nil, 10),\n    wbArrayS(ESCE, 'Counter Effects', wbStringMgefCode('Counter Effect Code', 4){wbInteger('Counter Effect', itU32, wbChar4)})\n  ], False, nil, cpNormal, False, wbMGEFAfterLoad);\n\n  wbRecord(MISC, 'Misc. Item', [\n    wbEDID,\n    wbFULL,\n    wbMODL,\n    wbICON,\n    wbSCRI,\n    wbStruct(DATA, '', [\n      wbUnion('', wbMISCActorValueDecider, [\n        wbInteger('Value', itS32),\n        wbFormIDCk('Actor Value', [ACVA])\n      ]),\n      wbUnion('', wbMISCActorValueDecider, [\n        wbFloat('Weight'),\n        wbInteger('Group', itU32, wbEnum([], [\n          $40E00000, ' [NONE]',\n          $40400000, 'AI',\n          $00000000, 'Attribute',\n          $40C00000, 'Combat',\n          $40A00000, 'Misc',\n          $40000000, 'Skill',\n          $40800000, 'Social',\n          $3F800000, 'Stat'\n        ]))\n      ])\n    ], cpNormal, True)\n  ]);\n\n  wbFaceGen := wbRStruct('FaceGen Data', [\n    wbByteArray(FGGS, 'FaceGen Geometry-Symmetric', 0, cpNormal, True),\n    wbByteArray(FGGA, 'FaceGen Geometry-Asymmetric', 0, cpNormal, True),\n    wbByteArray(FGTS, 'FaceGen Texture-Symmetric', 0, cpNormal, True)\n  ], [], cpNormal, True);\n\n  wbRecord(NPC_, 'Non-Player Character', [\n    wbEDID,\n    wbFULL,\n    wbMODL,\n    wbStruct(ACBS, 'Configuration', [\n      wbInteger('Flags', itU32, wbFlags([\n        {0x000001} 'Female',\n        {0x000002} 'Essential',\n        {0x000004} '',\n        {0x000008} 'Respawn',\n        {0x000010} 'Auto-calc stats',\n        {0x000020} '',\n        {0x000040} '',\n        {0x000080} 'PC Level Offset',\n        {0x000100} '',\n        {0x000200} 'No Low Level Processing',\n        {0x000400} '',\n        {0x000800} '',\n        {0x001000} '',\n        {0x002000} 'No Rumors',\n        {0x004000} 'Summonable',\n        {0x008000} 'No Persuasion',\n        {0x010000} '',\n        {0x020000} '',\n        {0x040000} '',\n        {0x080000} '',\n        {0x100000} 'Can Corpse Check'\n      ])),\n      wbInteger('Base spell points', itU16),\n      wbInteger('Fatigue', itU16),\n      wbInteger('Barter gold', itU16),\n      wbInteger('Level (offset)', itS16),\n      wbInteger('Calc min', itU16),\n      wbInteger('Calc max', itU16)\n    ], cpNormal, True),\n    wbRArrayS('Factions',\n      wbStructSK(SNAM, [0], 'Faction', [\n        wbFormIDCk('Faction', [FACT]),\n        wbInteger('Rank', itU8),\n        wbByteArray('Unused', 3)\n      ])\n    ),\n    wbFormIDCk(INAM, 'Death item', [LVLI]),\n    wbFormIDCk(RNAM, 'Race', [RACE], False, cpNormal, True),\n    wbCNTOs,\n    wbSPLOs,\n    wbSCRI,\n    wbStruct(AIDT, 'AI Data', [\n      wbInteger('Aggression', itU8),\n      wbInteger('Confidence', itU8),\n      wbInteger('Energy Level', itU8),\n      wbInteger('Responsibility', itU8),\n      wbInteger('Buys/Sells and Services', itU32, wbServiceFlags),\n      wbInteger('Teaches', itS8, wbSkillEnum),\n      wbInteger('Maximum training level', itU8),\n      wbByteArray('Unused', 2)\n    ], cpNormal, True),\n    wbRArray('AI Packages', wbFormIDCk(PKID, 'AI Package', [PACK])),\n    wbArrayS(KFFZ, 'Animations', wbString('Animation')),\n    wbFormIDCk(CNAM, 'Class', [CLAS], False, cpNormal, True),\n    wbStruct(DATA, 'Stats', [\n      wbInteger('Armorer', itU8),\n      wbInteger('Athletics', itU8),\n      wbInteger('Blade', itU8),\n      wbInteger('Block', itU8),\n      wbInteger('Blunt', itU8),\n      wbInteger('Hand to Hand', itU8),\n      wbInteger('Heavy Armor', itU8),\n      wbInteger('Alchemy', itU8),\n      wbInteger('Alteration', itU8),\n      wbInteger('Conjuration', itU8),\n      wbInteger('Destruction', itU8),\n      wbInteger('Illusion', itU8),\n      wbInteger('Mysticism', itU8),\n      wbInteger('Restoration', itU8),\n      wbInteger('Acrobatics', itU8),\n      wbInteger('Light Armor', itU8),\n      wbInteger('Marksman', itU8),\n      wbInteger('Mercantile', itU8),\n      wbInteger('Security', itU8),\n      wbInteger('Sneak', itU8),\n      wbInteger('Speechcraft', itU8),\n      wbInteger('Health', itU16),\n      wbByteArray('Unused', 2),\n      wbInteger('Strength', itU8),\n      wbInteger('Intelligence', itU8),\n      wbInteger('Willpower', itU8),\n      wbInteger('Agility', itU8),\n      wbInteger('Speed', itU8),\n      wbInteger('Endurance', itU8),\n      wbInteger('Personality', itU8),\n      wbInteger('Luck', itU8)\n    ], cpNormal, True),\n    wbFormIDCk(HNAM, 'Hair', [HAIR]),\n    wbFloat(LNAM, 'Hair length'),\n    wbArray(ENAM, 'Eyes', wbFormIDCk('Eyes', [EYES])),\n    wbStruct(HCLR, 'Hair color', [\n      wbInteger('Red', itU8),\n      wbInteger('Green', itU8),\n      wbInteger('Blue', itU8),\n      wbByteArray('Unused', 1)\n    ], cpNormal, True),\n    wbFormIDCk(ZNAM, 'Combat Style', [CSTY]),\n    wbFaceGen,\n    wbByteArray(FNAM, 'Unknown', 0, cpBenign)\n  ], True);\n\n  wbPKDTFlags := wbFlags([\n          {0x00000001} 'Offers services',\n          {0x00000002} 'Must reach location',\n          {0x00000004} 'Must complete',\n          {0x00000008} 'Lock doors at package start',\n          {0x00000010} 'Lock doors at package end',\n          {0x00000020} 'Lock doors at location',\n          {0x00000040} 'Unlock doors at package start',\n          {0x00000080} 'Unlock doors at package end',\n          {0x00000100} 'Unlock doors at location',\n          {0x00000200} 'Continue if PC near',\n          {0x00000400} 'Once per day',\n          {0x00000800} 'Unused',\n          {0x00001000} 'Skip fallout behavior',\n          {0x00002000} 'Always run',\n          {0x00004000} '',\n          {0x00008000} '',\n          {0x00010000} '',\n          {0x00020000} 'Always sneak',\n          {0x00040000} 'Allow swimming',\n          {0x00080000} 'Allow falls',\n          {0x00100000} 'Armor unequipped',\n          {0x00200000} 'Weapons unequipped',\n          {0x00400000} 'Defensive combat',\n          {0x00800000} 'Use horse',\n          {0x01000000} 'No idle anims',\n          {0x02000000} '',\n          {0x04000000} '',\n          {0x08000000} '',\n          {0x10000000} '',\n          {0x20000000} '',\n          {0x40000000} '',\n          {0x80000000} ''\n        ]);\n\n  wbPKDTType := wbEnum([\n           {0} 'Find',\n           {1} 'Follow',\n           {2} 'Escort',\n           {3} 'Eat',\n           {4} 'Sleep',\n           {5} 'Wander',\n           {6} 'Travel',\n           {7} 'Accompany',\n           {8} 'Use item at',\n           {9} 'Ambush',\n          {10} 'Flee not combat',\n          {11} 'Cast magic'\n        ]);\n\n  wbRecord(PACK, 'AI Package', [\n    wbEDID,\n    wbUnion(PKDT, 'General', wbPACKPKDTDecider, [\n      wbStruct('General', [\n        wbInteger('Flags', itU16, wbPKDTFlags),\n        wbInteger('Type', itU8, wbPKDTType),\n        wbByteArray('Unused', 1)\n      ]),\n      wbStruct('General', [\n        wbInteger('Flags', itU32, wbPKDTFlags),\n        wbInteger('Type', itU8, wbPKDTType),\n        wbByteArray('Unused', 3)\n      ])\n    ]),\n    wbStruct(PLDT, 'Location', [\n      wbInteger('Type', itS32, wbEnum([\n        {0} 'Near reference',\n        {1} 'In cell',\n        {2} 'Near current location',\n        {3} 'Near editor location',\n        {4} 'Object ID',\n        {5} 'Object type'\n      ])),\n      wbUnion('Location', wbPxDTLocationDecider, [\n        wbFormIDCk('Reference', [REFR, ACHR, ACRE, PLYR], True),\n        wbFormIDCk('Cell', [CELL]),\n        wbFormIDCk('Unused', [NULL]),\n        wbFormIDCk('Unused', [NULL]),\n        wbFormIDCk('Object ID', [ACTI, DOOR, FLOR, STAT, FURN, CREA, SPEL, NPC_, CONT, ARMO, AMMO, MISC, WEAP, INGR, SLGM, SGST, BOOK, KEYM, CLOT, ALCH, APPA, LIGH]),\n        wbInteger('Object type', itU32)\n      ]),\n      wbInteger('Radius', itS32)\n    ]),\n    wbStruct(PSDT, 'Schedule', [\n      wbInteger('Month', itS8),\n      wbInteger('Day of week', itS8, wbEnum([\n        'Sundas',\n        'Morndas',\n        'Tirdas',\n        'Middas',\n        'Turdas',\n        'Fredas',\n        'Loredas',\n        'Morndas to Fredas',\n        'Loredas, Sundas',\n        'Morndas, Middas, Fredas',\n        'Tirdas, Turdas'\n      ], [\n        -1, 'Any'\n      ])),\n      wbInteger('Date', itU8),\n      wbInteger('Time', itS8),\n      wbInteger('Duration', itS32)\n    ]),\n    wbStruct(PTDT, 'Target', [\n      wbInteger('Type', itS32, wbEnum([\n        {0} 'Specific reference',\n        {1} 'Object ID',\n        {2} 'Object type'\n      ])),\n      wbUnion('Target', wbPxDTLocationDecider, [\n        wbFormIDCk('Reference', [ACHR, ACRE, REFR, PLYR], True),\n        wbFormIDCk('Object ID', [ACTI, DOOR, FLOR, STAT, FURN, CREA, SPEL, NPC_, CONT, ARMO, AMMO, MISC, WEAP, INGR, SLGM, SGST, BOOK, KEYM, CLOT, ALCH, APPA, LIGH]),\n        wbInteger('Object type', itU32)\n      ]),\n      wbInteger('Count', itS32)\n    ]),\n    wbCTDAs\n  ]);\n\n  wbPGRP :=\n    wbArray(PGRP, 'Points', wbStruct('Point', [\n      wbFloat('X'),\n      wbFloat('Y'),\n      wbFloat('Z (Even = Red/Orange, Odd = Blue)'),\n      wbInteger('Connections', itU8{, wbPGRPConnectionsCallback}),\n      wbByteArray('Unused', 3)\n    ]), 0, nil, nil, cpNormal, True);\n\n      {The Connection Count in the PGRP record specifies how many entries in this\n       array belong to each point. If the first 4 points in the PGRP array have\n       Connection Counts 2, 5, 2, 4 then the first 2 entries are the connections\n       of point 0, then next 5 are the connections of point 1, the next 2 of point 2,\n       the next 4 of point 3 and so on..., this can currently not be represented\n       declaratively }\n\n  wbRecord(PGRD, 'Path Grid', [\n    wbInteger(DATA, 'Point Count', itU16, nil, cpNormal, True),\n    wbPGRP,\n    wbByteArray(PGAG, 'Unknown'),\n    wbArray(PGRR, 'Point-to-Point Connections',\n      wbArrayS('Point', wbInteger('Point', itU16), wbCalcPGRRSize{, cpNormal, False, wbPGRRPointAfterLoad})\n    ),\n    wbArrayS(PGRI, 'Inter-Cell Connections', wbStructSK([0,2,3,4], 'Inter-Cell Connection', [\n      wbInteger('Point', itU16),\n      wbByteArray('Unused', 2),\n      wbFloat('X'),\n      wbFloat('Y'),\n      wbFloat('Z')\n    ]), 0, cpNormal, False, wbPGRIPointerAfterLoad),\n    wbRArrayS('Point-to-Reference Mappings',\n      wbStructSK(PGRL, [0], 'Point-to-Reference Mapping', [\n        wbFormIDCk('Reference', [REFR]),\n        wbArrayS('Points', wbInteger('Point', itU32))\n      ])\n    )\n  ], False, nil, cpNormal, False, wbPGRDAfterLoad);\n\n  wbRecord(QUST, 'Quest', [\n    wbEDID,\n    wbSCRI,\n    wbFULL,\n    wbICON,\n    wbStruct(DATA, 'General', [\n      wbInteger('Flags', itU8, wbFlags([\n        {0x01} 'Start game enabled',\n        {0x02} '',\n        {0x04} 'Allow repeated conversation topics',\n        {0x08} 'Allow repeated stages'\n      ])),\n      wbInteger('Priority', itU8)\n    ], cpNormal, True),\n    wbCTDAs,\n    wbRArrayS('Stages', wbRStructSK([0], 'Stage', [\n      wbInteger(INDX, 'Stage index', itS16),\n      wbRArray('Log Entries', wbRStruct('Log Entry', [\n        wbInteger(QSDT, 'Stage Flags', itU8, wbFlags([\n          {0x01} 'Complete quest'\n        ])),\n        wbCTDAs,\n        wbString(CNAM, 'Log Entry', 0, cpTranslate),\n        wbResultScript\n      ], []))\n    ], [])),\n    wbRArray('Targets', wbRStruct('Target', [\n      wbStruct(QSTA, 'Target', [\n        wbFormIDCk('Target', [REFR, ACRE, ACHR], True),\n        wbInteger('Flags', itU8, wbFlags([\n          {0x01} 'Compass marker ignores locks'\n        ])),\n        wbByteArray('Unused', 3)\n      ]),\n      wbCTDAs\n    ], []))\n  ]);\n\n  wbBodyDataIndex :=\n    wbInteger(INDX, 'Index', itU32, wbEnum([\n      'Upper Body',\n      'Lower Body',\n      'Hand',\n      'Foot',\n      'Tail'\n    ]));\n\n  wbRecord(RACE, 'Race', [\n    wbEDID,\n    wbFULL,\n    wbDESC,\n    wbSPLOs,\n    wbXNAMs,\n    wbStruct(DATA, '', [\n      wbArrayS('Skill Boosts', wbStructSK([0], 'Skill Boost', [\n        wbInteger('Skill', itS8, wbActorValueEnum),\n        wbInteger('Boost', itS8)\n      ]), 7),\n      wbByteArray('Unused', 2),\n      wbFloat('Male Height'),\n      wbFloat('Female Height'),\n      wbFloat('Male Weight'),\n      wbFloat('Female Weight'),\n      wbInteger('Flags', itU32, wbFlags([\n        'Playable'\n      ]))\n    ], cpNormal, True),\n    wbStruct(VNAM, 'Voice', [\n      wbFormIDCk('Male', [RACE, NULL]),\n      wbFormIDCk('Female', [RACE, NULL])\n    ]),\n    wbStruct(DNAM, 'Default Hair', [\n      wbFormIDCk('Male', [HAIR]),\n      wbFormIDCk('Female', [HAIR])\n    ]),\n    wbInteger(CNAM, 'Default Hair Color', itU8, nil, cpNormal, True),\n    wbFloat(PNAM, 'FaceGen - Main clamp', cpNormal, True),\n    wbFloat(UNAM, 'FaceGen - Face clamp', cpNormal, True),\n    wbStruct(ATTR, 'Base Attributes', [\n      wbStruct('Male', [\n        wbInteger('Strength', itU8),\n        wbInteger('Intelligence', itU8),\n        wbInteger('Willpower', itU8),\n        wbInteger('Agility', itU8),\n        wbInteger('Speed', itU8),\n        wbInteger('Endurance', itU8),\n        wbInteger('Personality', itU8),\n        wbInteger('Luck', itU8)\n      ]),\n      wbStruct('Female', [\n        wbInteger('Strength', itU8),\n        wbInteger('Intelligence', itU8),\n        wbInteger('Willpower', itU8),\n        wbInteger('Agility', itU8),\n        wbInteger('Speed', itU8),\n        wbInteger('Endurance', itU8),\n        wbInteger('Personality', itU8),\n        wbInteger('Luck', itU8)\n      ])\n    ]),\n    wbRStruct('Face Data', [\n      wbEmpty(NAM0, 'Face Data Marker'),\n      wbRArrayS('Parts', wbRStructSK([0], 'Part', [\n        wbInteger(INDX, 'Index', itU32, wbEnum([\n          'Head',\n          'Ear (Male)',\n          'Ear (Female)',\n          'Mouth',\n          'Teeth (Lower)',\n          'Teeth (Upper)',\n          'Tongue',\n          'Eye (Left)',\n          'Eye (Right)'\n        ])),\n        wbMODL,\n        wbICON\n      ], []))\n    ], [], cpNormal, True),\n    wbEmpty(NAM1, 'Body Data Marker', cpNormal, True),\n    wbRStruct('Male Body Data', [\n      wbEmpty(MNAM, 'Male Body Data Marker'),\n      wbMODL,\n      wbRArrayS('Parts', wbRStructSK([0], 'Part', [\n        wbBodyDataIndex,\n        wbICON\n      ], []))\n    ], [], cpNormal, True),\n    wbRStruct('Female Body Data', [\n      wbEmpty(FNAM, 'Female Body Data Marker'),\n      wbMODL,\n      wbRArrayS('Parts', wbRStructSK([0], 'Part', [\n        wbBodyDataIndex,\n        wbICON\n      ], []))\n    ], [], cpNormal, True),\n    wbArrayS(HNAM, 'Hairs', wbFormIDCk('Hair', [HAIR]), 0, cpNormal, True),\n    wbArrayS(ENAM, 'Eyes', wbFormIDCk('Eye', [EYES]),  0,  cpNormal, True),\n    wbFaceGen,\n    wbByteArray(SNAM, 'Unknown', 2, cpNormal, True)\n  ], True);\n\n  wbRecord(REFR, 'Placed Object', [\n    wbEDID,\n    wbFormIDCk(NAME, 'Base', [TREE, SBSP, LVLC, SOUN, ACTI, DOOR, FLOR, STAT, FURN, CONT, ARMO, AMMO, MISC, WEAP, INGR, SLGM, SGST, BOOK, KEYM, CLOT, ALCH, APPA, LIGH, GRAS], False, cpNormal, True),\n    wbStruct(XTEL, 'Teleport Destination', [\n      wbFormIDCk('Door', [REFR], True),\n      wbPosRot\n    ]),\n    wbStruct(XLOC, 'Lock information', [\n      wbInteger('Lock Level', itU8),\n      wbByteArray('Unused', 3),\n      wbFormIDCk('Key', [KEYM, NULL]),\n      wbUnion('Unused', wbXLOCFillerDecider, [\n        wbEmpty('Unused'),\n        wbByteArray('Unused', 4)\n      ]),\n      wbInteger('Flags', itU8, wbFlags(['', '', 'Leveled Lock'])),\n      wbByteArray('Unused', 3)\n    ]),\n    wbRStruct('Ownership', [\n      wbXOWN,\n      wbInteger(XRNK, 'Faction rank', itS32),\n      wbXGLB\n    ], [XLOC]),\n    wbXESP,\n    wbFormIDCk(XTRG, 'Target', [REFR, ACHR, ACRE], True),\n    wbUnion(XSED, '', wbREFRXSEDDecider, [\n      wbInteger('SpeedTree Seed', itU8),\n      wbInteger('SpeedTree Seed (old format)', itU8{itU32 CS just cuts it off...})\n    ]),\n    wbXLOD,\n    wbFloat(XCHG, 'Charge'),\n    wbInteger(XHLT, 'Health', itS32),\n    wbRStruct('Unused', [\n      wbFormIDCk(XPCI, 'Unused', [CELL]),\n      wbString(FULL, 'Unused')\n    ], []),\n    wbInteger(XLCM, 'Level Modifier', itS32),\n    wbFormIDCk(XRTM, 'Unknown', [REFR]),\n    wbInteger(XACT, 'Action Flag', itU32, wbFlags([\n      'Use Default',\n      'Activate',\n      'Open',\n      'Open by Default'\n    ])),\n    wbInteger(XCNT, 'Count', itS32),\n    wbRStruct('Map Marker', [\n      wbEmpty(XMRK, 'Map Marker Start Marker'),\n      wbInteger(FNAM, 'Map Flags', itU8, wbFlags([\n        {0x01} 'Visible',\n        {0x02} 'Can Travel To'\n      ]), cpNormal, True),\n      wbFULLReq,\n      wbStruct(TNAM, '', [\n        wbInteger('Type', itU8, wbEnum([\n          {0x00} 'None?',\n          {0x01} 'Camp',\n          {0x02} 'Cave',\n          {0x03} 'City',\n          {0x04} 'Elven Ruin',\n          {0x05} 'Fort Ruin',\n          {0x06} 'Mine',\n          {0x07} 'Landmark',\n          {0x08} 'Tavern',\n          {0x09} 'Settlement',\n          {0x0A} 'Daedric Shrine',\n          {0x0B} 'Oblivion Gate',\n          {0x0C} 'Unknown? (door icon)'\n        ])),\n        wbByteArray('Unused', 1)\n      ], cpNormal, True)\n    ], []),\n    wbEmpty(ONAM, 'Open by Default'),\n    wbXSCL,\n    wbInteger(XSOL, 'Contained Soul', itU8, wbSoulGemEnum),\n    wbDATAPosRot\n  ], True, wbPlacedAddInfo, cpNormal, False, wbREFRAfterLoad);\n\n  wbRecord(REGN, 'Region', [\n    wbEDID,\n    wbICON,\n    wbStruct(RCLR, 'Map Color', [\n      wbInteger('Red', itU8),\n      wbInteger('Green', itU8),\n      wbInteger('Blue', itU8),\n      wbByteArray('Unused', 1)\n    ], cpNormal, True),\n    wbFormIDCk(WNAM, 'Worldspace', [WRLD]),\n\n    wbRArray('Region Areas', wbRStruct('Region Area', [\n      wbInteger(RPLI, 'Edge Fall-off', itU32),\n      wbArray(RPLD, 'Region Point List Data', wbStruct('Point', [\n        wbFloat('X'),\n        wbFloat('Y')\n      ]), 0, wbRPLDAfterLoad)\n    ], []), cpNormal, True),\n\n    wbRArrayS('Region Data Entries', wbRStructSK([0], 'Region Data Entry', [\n      {always starts with an RDAT}\n      wbStructSK(RDAT, [0], 'Data Header', [\n        wbInteger('Type', itU32, wbEnum([\n          {0}'',\n          {1}'',\n          {2}'Objects',\n          {3}'Weather',\n          {4}'Map',\n          {5}'',\n          {6}'Grass',\n          {7}'Sound',\n          {8}'',\n          {9}''\n        ])),\n        wbInteger('Flags', itU8, wbFlags([\n          'Override'\n        ])),\n        wbInteger('Priority', itU8),\n        wbByteArray('Unused', 2)\n      ], cpNormal, True, nil, 3),\n\n      {followed by one of these: }\n\n      {--- Objects ---}\n      wbArray(RDOT, 'Objects', wbStruct('Object', [\n        wbFormIDCk('Object', [TREE, FLOR, STAT, LTEX]),\n        wbInteger('Parent Index', itU16, wbHideFFFF),\n        wbByteArray('Unused', 2),\n        wbFloat('Density'),\n        wbInteger('Clustering', itU8),\n        wbInteger('Min Slope', itU8),\n        wbInteger('Max Slope', itU8),\n        wbInteger('Flags', itU8, wbFlags([\n          {0}'Conform to slope',\n          {1}'Paint Vertices',\n          {2}'Size Variance +/-',\n          {3}'X +/-',\n          {4}'Y +/-',\n          {5}'Z +/-',\n          {6}'Tree',\n          {7}'Huge Rock'\n        ])),\n        wbInteger('Radius wrt Parent', itU16),\n        wbInteger('Radius', itU16),\n        wbByteArray('Unknown', 4),\n        wbFloat('Max Height'),\n        wbFloat('Sink'),\n        wbFloat('Sink Variance'),\n        wbFloat('Size Variance'),\n        wbStruct('Angle Variance', [\n          wbInteger('X', itU16),\n          wbInteger('Y', itU16),\n          wbInteger('Z', itU16)\n        ]),\n        wbByteArray('Unused', 2),\n        wbByteArray('Unknown', 4)\n      ])),\n\n      {--- Map ---}\n      wbString(RDMP, 'Map Name', 0, cpTranslate),\n\n      {--- Grass ---}\n      wbArrayS(RDGS, 'Grasses', wbStructSK([0], 'Grass', [\n        wbFormIDCk('Grass', [GRAS]),\n        wbByteArray('Unused', 4)\n      ])),\n\n      {--- Sound ---}\n      wbInteger(RDMD, 'Music Type', itU32, wbMusicEnum),\n      wbArrayS(RDSD, 'Sounds', wbStructSK([0], 'Sound', [\n        wbFormIDCk('Sound', [SOUN]),\n        wbInteger('Flags', itU32, wbFlags([\n          'Pleasant',\n          'Cloudy',\n          'Rainy',\n          'Snowy'\n        ])),\n        wbInteger('Chance', itU32, wbScaledInt4ToStr, wbScaledInt4ToInt)\n      ])),\n\n      {--- Weather ---}\n      wbArrayS(RDWT, 'Weather Types', wbStructSK([0], 'Weather Type', [\n        wbFormIDCk('Weather', [WTHR]),\n        wbInteger('Chance', itU32)\n      ]))\n    ], []))\n  ], True);\n\n  wbRecord(ROAD, 'Road', [\n    wbPGRP,\n    wbArray(PGRR, 'Point-to-Point Connections (complex structure can''t be represented, see source)',\n      {The Connection Count in the PGRP record specifies how many entries in this\n       array belong to each point. If the first 4 points in the PGRP array have\n       Connection Counts 2, 5, 2, 4 then the first 2 entries are the connections\n       of point 0, then next 5 are the connections of point 1, the next 2 of point 2,\n       the next 4 of point 3 and so on..., this can currently not be represented\n       declaratively }\n      wbStruct('Point', [\n        wbFloat('X'),\n        wbFloat('Y'),\n        wbFloat('Z')\n      ]), 0, nil, nil, cpNormal, True)\n  ]);\n\n  wbRecord(SBSP, 'Subspace', [\n    wbEDID,\n    wbStruct(DNAM, '', [\n      wbFloat('X'),\n      wbFloat('Y'),\n      wbFloat('Z')\n    ], cpNormal, True)\n  ]);\n\n  wbSLSD := wbStructSK(SLSD, [0], 'Local Variable Data', [\n    wbInteger('Index', itU32),\n    wbByteArray('Unused', 12),\n    wbInteger('Flags', itU8, wbFlags(['IsLongOrShort']), cpCritical),\n    wbByteArray('Unused')\n  ]);\n\n  wbRecord(SCPT, 'Script', [\n    wbEDID,\n    wbByteArray(SCHD, 'Unknown (Script Header?)'),\n    wbSCHR,\n    wbByteArray(SCDA, 'Compiled Script'),\n    wbStringScript(SCTX, 'Script Source', 0, cpNormal, True),\n    wbRArrayS('Local Variables', wbRStructSK([0], 'Local Variable', [\n      wbSLSD,\n      wbString(SCVR, 'Name', 0, cpCritical)\n    ], [])),\n    wbSCROs\n  ]);\n\n  wbRecord(SGST, 'Sigil Stone', [\n    wbEDID,\n    wbStruct(OBME, 'Oblivion Magic Extender', [\n      wbInteger('Record Version', itU8),\n      wbStruct('OBME Version', [\n        wbInteger('Beta', itU8),\n        wbInteger('Minor', itU8),\n        wbInteger('Major', itU8)\n      ]),\n      wbByteArray('Unused', $1C)\n    ], cpNormal, False, wbOBMEDontShow),\n    wbFULL,\n    wbMODL,\n    wbICON,\n    wbSCRI,\n    wbEffects,\n    wbStruct(DATA, '', [\n      wbInteger('Uses ', itU8),\n      wbInteger('Value', itU32),\n      wbFloat('Weight')\n    ], cpNormal, True)\n  ]);\n\n  wbRecord(SKIL, 'Skill', [\n    wbEDID,\n    wbInteger(INDX, 'Skill', itS32, wbActorValueEnum, cpNormal, True),\n    wbDESC,\n    wbICON,\n    wbStruct(DATA, 'Skill Data', [\n      wbInteger('Action', itS32, wbActorValueEnum),\n      wbInteger('Attribute', itS32, wbActorValueEnum),\n      wbInteger('Specialization', itU32, wbSpecializationEnum),\n      wbArray('Use Values', wbFloat('Use Value'), 2)\n    ], cpNormal, True),\n    wbString(ANAM, 'Apprentice Text', 0, cpTranslate, True),\n    wbString(JNAM, 'Journeyman Text', 0, cpTranslate, True),\n    wbString(ENAM, 'Expert Text', 0, cpTranslate, True),\n    wbString(MNAM, 'Master Text', 0, cpTranslate, True)\n  ]);\n\n  wbRecord(SLGM, 'Soul Gem', [\n    wbEDID,\n    wbFULL,\n    wbMODL,\n    wbICON,\n    wbSCRI,\n    wbStruct(DATA, '', [\n      wbInteger('Value', itU32),\n      wbFloat('Weight')\n    ], cpNormal, True),\n    wbInteger(SOUL, 'Contained Soul', itU8, wbSoulGemEnum, cpNormal, True),\n    wbInteger(SLCP, 'Maximum Capacity', itU8, wbSoulGemEnum, cpNormal, True)\n  ]);\n\n  wbRecord(SOUN, 'Sound', [\n    wbEDID,\n    wbString(FNAM, 'Sound Filename'),\n    wbRUnion('Sound Data', [\n      wbStruct(SNDX, 'Sound Data', [\n        wbInteger('Minimum attentuation distance', itU8, wbMul(5)),\n        wbInteger('Maximum attentuation distance', itU8, wbMul(100)),\n        wbInteger('Frequency adjustment %', itS8),\n        wbByteArray('Unused', 1),\n        wbInteger('Flags', itU16, wbFlags([\n          {0x0001} 'Random Frequency Shift',\n          {0x0002} 'Play At Random',\n          {0x0004} 'Environment Ignored',\n          {0x0008} 'Random Location',\n          {0x0010} 'Loop',\n          {0x0020} 'Menu Sound',\n          {0x0040} '2D',\n          {0x0080} '360 LFE'\n        ])),\n        wbByteArray('Unused', 2),\n        wbInteger('Static attentuation cdB', itS16),\n        wbInteger('Stop time ', itU8),\n        wbInteger('Start time ', itU8)\n      ], cpNormal, True),\n      wbStruct(SNDD, 'Sound Data', [\n        wbInteger('Minimum attentuation distance', itU8, wbMul(5)),\n        wbInteger('Maximum attentuation distance', itU8, wbMul(100)),\n        wbInteger('Frequency adjustment %', itS8),\n        wbByteArray('Unused', 1),\n        wbInteger('Flags', itU16, wbFlags([\n          {0x0001} 'Random Frequency Shift',\n          {0x0002} 'Play At Random',\n          {0x0004} 'Environment Ignored',\n          {0x0008} 'Random Location',\n          {0x0010} 'Loop',\n          {0x0020} 'Menu Sound',\n          {0x0040} '2D',\n          {0x0080} '360 LFE'\n        ])),\n        wbByteArray('Unused', 2),\n        wbEmpty('Unused'),\n        wbEmpty('Unused'),\n        wbEmpty('Unused')\n      ], cpNormal, True)\n    ], [], cpNormal, True)\n  ]);\n\n  wbRecord(SPEL, 'Spell', [\n    wbEDID,\n    wbStruct(OBME, 'Oblivion Magic Extender', [\n      wbInteger('Record Version', itU8),\n      wbStruct('OBME Version', [\n        wbInteger('Beta', itU8),\n        wbInteger('Minor', itU8),\n        wbInteger('Major', itU8)\n      ]),\n      wbByteArray('Unused', $1C)\n    ], cpNormal, False, wbOBMEDontShow),\n    wbFULL,\n    wbStruct(SPIT, '', [\n      wbInteger('Type', itU32, wbEnum([\n        {0} 'Spell',\n        {1} 'Disease',\n        {2} 'Power',\n        {3} 'Lesser Power',\n        {4} 'Ability',\n        {5} 'Poison'\n      ])),\n      wbInteger('Cost', itU32),\n      wbInteger('Level', itU32, wbEnum([\n        {0} 'Novice',\n        {1} 'Apprentice',\n        {2} 'Journeyman',\n        {3} 'Expert',\n        {4} 'Master'\n      ])),\n      wbInteger('Flags', itU8, wbFlags([\n        {0x00000001} 'Manual Spell Cost',\n        {0x00000002} 'Immune to Silence 1',\n        {0x00000004} 'Player Start Spell',\n        {0x00000008} 'Immune to Silence 2',\n        {0x00000010} 'Area Effect Ignores LOS',\n        {0x00000020} 'Script Effect Always Applies',\n        {0x00000040} 'Disallow Spell Absorb/Reflect',\n        {0x00000080} 'Touch Spell Explodes w/ no Target'\n      ])),\n      wbByteArray('Unused', 3)\n    ], cpNormal, True),\n    wbEffects\n  ]);\n\n  wbRecord(STAT, 'Static', [\n    wbEDID,\n    wbMODL\n  ]);\n\n  wbRecord(TES3, 'Main File Header', [\n    wbStruct(HEDR, 'Header', [\n      wbFloat('Version'),\n      wbInteger('Number of Records', itU32),\n      wbInteger('Next Object ID', itU32)\n    ], cpNormal, True),\n    wbByteArray(OFST, 'Unknown', 0, cpIgnore),\n    wbByteArray(DELE, 'Unknown', 0, cpIgnore),\n    wbString(CNAM, 'Author', 0, cpTranslate, True),\n    wbString(SNAM, 'Description', 0, cpTranslate),\n    wbRArray('Master Files', wbRStruct('Master File', [\n      wbString(MAST, 'Filename', 0, cpNormal, True),\n      wbByteArray(DATA, 'Unused', 8, cpIgnore, True)\n    ], []))\n  ], False, nil, cpNormal, True, wbRemoveOFST);\n\n  wbRecord(TREE, 'Tree', [\n    wbEDID,\n    wbMODL,\n    wbICON,\n    wbArrayS(SNAM, 'SpeedTree Seeds', wbInteger('SpeedTree Seed', itU32)),\n    wbStruct(CNAM, 'Tree Data', [\n      wbFloat('Leaf Curvature'),\n      wbFloat('Minimum Leaf Angle'),\n      wbFloat('Maximum Leaf Angle'),\n      wbFloat('Branch Dimming Value'),\n      wbFloat('Leaf Dimming Value'),\n      wbInteger('Shadow Radius', itS32),\n      wbFloat('Rock Speed'),\n      wbFloat('Rustle Speed')\n    ], cpNormal, True),\n    wbStruct(BNAM, 'Billboard Dimensions', [\n      wbFloat('Width'),\n      wbFloat('Height')\n    ], cpNormal, True)\n  ]);\n\n  wbRecord(WATR, 'Water', [\n    wbEDID,\n    wbString(TNAM, 'Texture', 0, cpNormal, True),\n    wbInteger(ANAM, 'Opacity', itU8, nil, cpNormal, True),\n    wbInteger(FNAM, 'Flags', itU8, wbFlags([\n      {0}'Causes Damage',\n      {1}'Reflective'\n    ]), cpNormal, True),\n    wbString(MNAM, 'Material ID'),\n    wbFormIDCk(SNAM, 'Sound', [SOUN]),\n    wbStruct(DATA, '', [\n      wbFloat('Wind Velocity'),\n      wbFloat('Wind Direction'),\n      wbFloat('Wave Amplitude'),\n      wbFloat('Wave Frequency'),\n      wbFloat('Sun Power'),\n      wbFloat('Reflectivity Amount'),\n      wbFloat('Fresnel Amount'),\n      wbFloat('Scroll X Speed'),\n      wbFloat('Scroll Y Speed'),\n      wbFloat('Fog Distance - Near Plane'),\n      wbFloat('Fog Distance - Far Plane'),\n      wbStruct('Shallow Color', [\n        wbInteger('Red', itU8),\n        wbInteger('Green', itU8),\n        wbInteger('Blue', itU8),\n        wbByteArray('Unused', 1)\n      ]),\n      wbStruct('Deep Color', [\n        wbInteger('Red', itU8),\n        wbInteger('Green', itU8),\n        wbInteger('Blue', itU8),\n        wbByteArray('Unused', 1)\n      ]),\n      wbStruct('Reflection Color', [\n        wbInteger('Red', itU8),\n        wbInteger('Green', itU8),\n        wbInteger('Blue', itU8),\n        wbByteArray('Unused', 1)\n      ]),\n      wbInteger('Texture Blend', itU8),\n      wbByteArray('Unused', 3),\n      wbFloat('Rain Simulator - Force'),\n      wbFloat('Rain Simulator - Velocity'),\n      wbFloat('Rain Simulator - Falloff'),\n      wbFloat('Rain Simulator - Dampner'),\n      wbFloat('Rain Simulator - Starting Size'),\n      wbFloat('Displacement Simulator - Force'),\n      wbFloat('Displacement Simulator - Velocity'),\n      wbFloat('Displacement Simulator - Falloff'),\n      wbFloat('Displacement Simulator - Dampner'),\n      wbFloat('Displacement Simulator - Starting Size'),\n      wbInteger('Damage', itU16)\n    ], cpNormal, True, nil, 0),\n    wbStruct(GNAM, 'Related Waters', [\n      wbFormIDCk('Daytime', [WATR, NULL]),\n      wbFormIDCk('Nighttime', [WATR, NULL]),\n      wbFormIDCk('Underwater', [WATR, NULL])\n    ], cpNormal, True)\n  ]);\n\n  wbRecord(WEAP, 'Weapon', [\n    wbEDID,\n    wbFULL,\n    wbMODL,\n    wbICON,\n    wbSCRI,\n    wbENAM,\n    wbInteger(ANAM, 'Enchantment Points', itU16),\n    wbStruct(DATA, '', [\n      wbInteger('Type', itU32, wbEnum([\n        {0} 'Blade One Hand',\n        {1} 'Blade Two Hand',\n        {2} 'Blunt One Hand',\n        {3} 'Blunt Two Hand',\n        {4} 'Staff',\n        {5} 'Bow'\n      ])),\n      wbFloat('Speed'),\n      wbFloat('Reach'),\n      wbInteger('Flags', itU32, wbFlags(['Ignores Normal Weapon Resistance'])),\n      wbInteger('Value', itU32),\n      wbInteger('Health', itU32),\n      wbFloat('Weight'),\n      wbInteger('Damage', itU16)\n    ], cpNormal, True)\n  ]);\n\n  wbRecord(WRLD, 'Worldspace', [\n    wbEDID,\n    wbFULL,\n    wbFormIDCk(WNAM, 'Parent Worldspace', [WRLD]),\n    wbFormIDCk(CNAM, 'Climate', [CLMT]),\n    wbFormIDCk(NAM2, 'Water', [WATR]),\n    wbICON,\n    wbStruct(MNAM, 'Map Data', [\n      wbStruct('Uable Dimensions', [\n        wbInteger('X', itS32),\n        wbInteger('Y', itS32)\n      ]),\n      wbStruct('Cell Coordinates', [\n        wbStruct('NW Cell', [\n          wbInteger('X', itS16),\n          wbInteger('Y', itS16)\n        ]),\n        wbStruct('SE Cell', [\n          wbInteger('X', itS16),\n          wbInteger('Y', itS16)\n        ])\n      ])\n    ]),\n    wbInteger(DATA, 'Flags', itU8, wbFlags([\n      {0x01} 'Small world',\n      {0x02} 'Can''t fast travel',\n      {0x04} 'Oblivion worldspace',\n      {0x08} '',\n      {0x10} 'No LOD water'\n    ]), cpNormal, True),\n    wbArray(NAM0, 'Unknown', wbFloat(''), 0, nil, nil, cpNormal, True),\n    wbArray(NAM9, 'Unknown', wbFloat(''), 0, nil, nil, cpNormal, True),\n    wbInteger(SNAM, 'Music', itU32, wbMusicEnum),\n    wbByteArray(OFST, 'Unknown')\n  ], False, nil, cpNormal, False, wbRemoveOFST);\n\n  wbRecord(WTHR, 'Weather', [\n    wbEDID,\n    wbString(CNAM, 'Texture Lower Layer'),\n    wbString(DNAM, 'Texture Upper Layer'),\n    wbMODL,\n    wbArray(NAM0, 'Colors by Types/Times',\n      wbArray('Type',\n        wbStruct('Time', [\n          wbInteger('Red', itU8),\n          wbInteger('Green', itU8),\n          wbInteger('Blue', itU8),\n          wbByteArray('Unused', 1)\n        ]),\n        ['Sunrise', 'Day', 'Sunset', 'Night']\n      ),\n      ['Sky-Upper','Fog','Clouds-Lower','Ambient','Sunlight','Sun','Stars','Sky-Lower','Horizon','Clouds-Upper']\n    , cpNormal, True),\n    wbStruct(FNAM, 'Fog Distance', [\n      wbFloat('Day Near'),\n      wbFloat('Day Far'),\n      wbFloat('Night Near'),\n      wbFloat('Night Far')\n    ], cpNormal, True),\n    wbStruct(HNAM, 'HDR Data', [\n      wbFloat('Eye Adapt Speed'),\n      wbFloat('Blur Radius'),\n      wbFloat('Blur Passes'),\n      wbFloat('Emissive Mult'),\n      wbFloat('Target LUM'),\n      wbFloat('Upper LUM Clamp'),\n      wbFloat('Bright Scale'),\n      wbFloat('Bright Clamp'),\n      wbFloat('LUM Ramp No Tex'),\n      wbFloat('LUM Ramp Min'),\n      wbFloat('LUM Ramp Max'),\n      wbFloat('Sunlight Dimmer'),\n      wbFloat('Grass Dimmer'),\n      wbFloat('Tree Dimmer')\n    ], cpNormal, True),\n    wbStruct(DATA, '', [\n      wbInteger('Wind Speed', itU8),\n      wbInteger('Cloud Speed (Lower)', itU8),\n      wbInteger('Cloud Speed (Upper)', itU8),\n      wbInteger('Trans Delta', itU8),\n      wbInteger('Sun Glare', itU8),\n      wbInteger('Sun Damage', itU8),\n      wbInteger('Precipitation - Begin Fade In', itU8),\n      wbInteger('Precipitation - End Fade Out', itU8),\n      wbInteger('Thunder/Lightning - Begin Fade In', itU8),\n      wbInteger('Thunder/Lightning - End Fade Out', itU8),\n      wbInteger('Thunder/Lightning - Frequency', itU8),\n      wbInteger('Weather Classification', itU8, wbWthrDataClassification),\n      wbStruct('Lightning Color', [\n        wbInteger('Red', itU8),\n        wbInteger('Green', itU8),\n        wbInteger('Blue', itU8)\n      ])\n    ], cpNormal, True),\n    wbRArray('Sounds', wbStruct(SNAM, 'Sound', [\n      wbFormIDCk('Sound', [SOUN]),\n      wbInteger('Type', itU32, wbEnum([\n       {0}'Default',\n       {1}'Precip',\n       {2}'Wind',\n       {3}'Thunder'\n      ]))\n    ]))\n  ]);\n\n  wbAddGroupOrder(GMST);\n  wbAddGroupOrder(GLOB);\n  wbAddGroupOrder(CLAS);\n  wbAddGroupOrder(FACT);\n  wbAddGroupOrder(HAIR);\n  wbAddGroupOrder(EYES);\n  wbAddGroupOrder(RACE);\n  wbAddGroupOrder(SOUN);\n  wbAddGroupOrder(SKIL);\n  wbAddGroupOrder(MGEF);\n  wbAddGroupOrder(SCPT);\n  wbAddGroupOrder(LTEX);\n  wbAddGroupOrder(ENCH);\n  wbAddGroupOrder(SPEL);\n  wbAddGroupOrder(BSGN);\n  wbAddGroupOrder(ACTI);\n  wbAddGroupOrder(APPA);\n  wbAddGroupOrder(ARMO);\n  wbAddGroupOrder(BOOK);\n  wbAddGroupOrder(CLOT);\n  wbAddGroupOrder(CONT);\n  wbAddGroupOrder(DOOR);\n  wbAddGroupOrder(INGR);\n  wbAddGroupOrder(LIGH);\n  wbAddGroupOrder(MISC);\n  wbAddGroupOrder(STAT);\n  wbAddGroupOrder(GRAS);\n  wbAddGroupOrder(TREE);\n  wbAddGroupOrder(FLOR);\n  wbAddGroupOrder(FURN);\n  wbAddGroupOrder(WEAP);\n  wbAddGroupOrder(AMMO);\n  wbAddGroupOrder(NPC_);\n  wbAddGroupOrder(CREA);\n  wbAddGroupOrder(LVLC);\n  wbAddGroupOrder(SLGM);\n  wbAddGroupOrder(KEYM);\n  wbAddGroupOrder(ALCH);\n  wbAddGroupOrder(SBSP);\n  wbAddGroupOrder(SGST);\n  wbAddGroupOrder(LVLI);\n  wbAddGroupOrder(WTHR);\n  wbAddGroupOrder(CLMT);\n  wbAddGroupOrder(REGN);\n  wbAddGroupOrder(CELL);\n  wbAddGroupOrder(WRLD);\n  wbAddGroupOrder(DIAL);\n  wbAddGroupOrder(QUST);\n  wbAddGroupOrder(IDLE);\n  wbAddGroupOrder(PACK);\n  wbAddGroupOrder(CSTY);\n  wbAddGroupOrder(LSCR);\n  wbAddGroupOrder(LVSP);\n  wbAddGroupOrder(ANIO);\n  wbAddGroupOrder(WATR);\n  wbAddGroupOrder(EFSH);\nend;\n\ninitialization\nend.\n"
  },
  {
    "path": "lib/xedit/wbDefinitionsTES4.pas",
    "content": "{*******************************************************************************\n\n     The contents of this file are subject to the Mozilla Public License\n     Version 1.1 (the \"License\"); you may not use this file except in\n     compliance with the License. You may obtain a copy of the License at\n     http://www.mozilla.org/MPL/\n\n     Software distributed under the License is distributed on an \"AS IS\"\n     basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the\n     License for the specific language governing rights and limitations\n     under the License.\n\n*******************************************************************************}\n\nunit wbDefinitionsTES4;\n\n{$I wbDefines.inc}\n\ninterface\n\nuses\n  wbInterface;\n\nvar\n\twbPKDTFlags: IwbFlagsDef;\n\twbServiceFlags: IwbFlagsDef;\n\n\twbAxisEnum: IwbEnumDef;\n\twbBlendModeEnum: IwbEnumDef;\n\twbBlendOpEnum: IwbEnumDef;\n\twbCrimeTypeEnum: IwbEnumDef;\n\twbFormTypeEnum: IwbEnumDef;\n\twbFunctionsEnum: IwbEnumDef;\n\twbMagicSchoolEnum: IwbEnumDef;\n\twbMusicEnum: IwbEnumDef;\n\twbOBMEResolutionInfo: IwbEnumDef;\n\twbPKDTType: IwbEnumDef;\n\twbQuadrantEnum: IwbEnumDef;\n\twbSexEnum: IwbEnumDef;\n\twbSkillEnum: IwbEnumDef;\n\twbSoulGemEnum: IwbEnumDef;\n\twbSpecializationEnum: IwbEnumDef;\n\twbZTestFuncEnum: IwbEnumDef;\n\nprocedure DefineTES4;\n\nimplementation\n\nuses\n  Types,\n  Classes,\n  SysUtils,\n  Math,\n  Variants,\n  wbHelpers;\n\nconst\n  ACBS : TwbSignature = 'ACBS';\n  ACHR : TwbSignature = 'ACHR';\n  ACRE : TwbSignature = 'ACRE';\n  TRGT : TwbSignature = 'TRGT';\n  ACTI : TwbSignature = 'ACTI';\n  AIDT : TwbSignature = 'AIDT';\n  ALCH : TwbSignature = 'ALCH';\n  AMMO : TwbSignature = 'AMMO';\n  ANAM : TwbSignature = 'ANAM';\n  ANIO : TwbSignature = 'ANIO';\n  APPA : TwbSignature = 'APPA';\n  ARMO : TwbSignature = 'ARMO';\n  ATTR : TwbSignature = 'ATTR';\n  ATXT : TwbSignature = 'ATXT';\n  BMDT : TwbSignature = 'BMDT';\n  BNAM : TwbSignature = 'BNAM';\n  BOOK : TwbSignature = 'BOOK';\n  BSGN : TwbSignature = 'BSGN';\n  BTXT : TwbSignature = 'BTXT';\n  CELL : TwbSignature = 'CELL';\n  CLAS : TwbSignature = 'CLAS';\n  CLMT : TwbSignature = 'CLMT';\n  CLOT : TwbSignature = 'CLOT';\n  CNAM : TwbSignature = 'CNAM';\n  CNTO : TwbSignature = 'CNTO';\n  CONT : TwbSignature = 'CONT';\n  CREA : TwbSignature = 'CREA';\n  CSAD : TwbSignature = 'CSAD';\n  CSCR : TwbSignature = 'CSCR';\n  CSDC : TwbSignature = 'CSDC';\n  CSDI : TwbSignature = 'CSDI';\n  CSDT : TwbSignature = 'CSDT';\n  CSTD : TwbSignature = 'CSTD';\n  CSTY : TwbSignature = 'CSTY';\n  CTDA : TwbSignature = 'CTDA';\n  CTDT : TwbSignature = 'CTDT';\n  DATA : TwbSignature = 'DATA';\n  DATX : TwbSignature = 'DATX';\n  DELE : TwbSignature = 'DELE';\n  DESC : TwbSignature = 'DESC';\n  DIAL : TwbSignature = 'DIAL';\n  DNAM : TwbSignature = 'DNAM';\n  DOOR : TwbSignature = 'DOOR';\n  EDID : TwbSignature = 'EDID';\n  EDDX : TwbSignature = 'EDDX';\n  EFID : TwbSignature = 'EFID';\n  EFIT : TwbSignature = 'EFIT';\n  ACVA : TwbSignature = 'ACVA';\n  EFII : TwbSignature = 'EFII';\n  EFXX : TwbSignature = 'EFXX';\n  EFIX : TwbSignature = 'EFIX';\n  EFME : TwbSignature = 'EFME';\n  EFSH : TwbSignature = 'EFSH';\n  ENAM : TwbSignature = 'ENAM';\n  ENCH : TwbSignature = 'ENCH';\n  ENIT : TwbSignature = 'ENIT';\n  ESCE : TwbSignature = 'ESCE';\n  EYES : TwbSignature = 'EYES';\n  FACT : TwbSignature = 'FACT';\n  FGGA : TwbSignature = 'FGGA';\n  FGGS : TwbSignature = 'FGGS';\n  FGTS : TwbSignature = 'FGTS';\n  FLOR : TwbSignature = 'FLOR';\n  FLTV : TwbSignature = 'FLTV';\n  FNAM : TwbSignature = 'FNAM';\n  FULL : TwbSignature = 'FULL';\n  FURN : TwbSignature = 'FURN';\n  GLOB : TwbSignature = 'GLOB';\n  GMST : TwbSignature = 'GMST';\n  GNAM : TwbSignature = 'GNAM';\n  GRAS : TwbSignature = 'GRAS';\n  HAIR : TwbSignature = 'HAIR';\n  HCLR : TwbSignature = 'HCLR';\n  HEDR : TwbSignature = 'HEDR';\n  HNAM : TwbSignature = 'HNAM';\n  ICO2 : TwbSignature = 'ICO2';\n  ICON : TwbSignature = 'ICON';\n  IDLE : TwbSignature = 'IDLE';\n  NULL : TwbSignature = 'NULL';\n  INAM : TwbSignature = 'INAM';\n  INDX : TwbSignature = 'INDX';\n  INFO : TwbSignature = 'INFO';\n  INGR : TwbSignature = 'INGR';\n  JNAM : TwbSignature = 'JNAM';\n  KEYM : TwbSignature = 'KEYM';\n  KFFZ : TwbSignature = 'KFFZ';\n  LAND : TwbSignature = 'LAND';\n  LIGH : TwbSignature = 'LIGH';\n  LNAM : TwbSignature = 'LNAM';\n  LSCR : TwbSignature = 'LSCR';\n  LTEX : TwbSignature = 'LTEX';\n  LVLC : TwbSignature = 'LVLC';\n  LVLD : TwbSignature = 'LVLD';\n  LVLF : TwbSignature = 'LVLF';\n  LVLI : TwbSignature = 'LVLI';\n  LVLO : TwbSignature = 'LVLO';\n  LVSP : TwbSignature = 'LVSP';\n  MAST : TwbSignature = 'MAST';\n  MGEF : TwbSignature = 'MGEF';\n  MISC : TwbSignature = 'MISC';\n  MNAM : TwbSignature = 'MNAM';\n  MO2B : TwbSignature = 'MO2B';\n  MO2T : TwbSignature = 'MO2T';\n  MO3B : TwbSignature = 'MO3B';\n  MO3T : TwbSignature = 'MO3T';\n  MO4B : TwbSignature = 'MO4B';\n  MO4T : TwbSignature = 'MO4T';\n  MOD2 : TwbSignature = 'MOD2';\n  MOD3 : TwbSignature = 'MOD3';\n  MOD4 : TwbSignature = 'MOD4';\n  MODB : TwbSignature = 'MODB';\n  MODL : TwbSignature = 'MODL';\n  MODT : TwbSignature = 'MODT';\n  NAM0 : TwbSignature = 'NAM0';\n  NAM1 : TwbSignature = 'NAM1';\n  NAM2 : TwbSignature = 'NAM2';\n  NAM9 : TwbSignature = 'NAM9';\n  NAME : TwbSignature = 'NAME';\n  NIFT : TwbSignature = 'NIFT';\n  NIFZ : TwbSignature = 'NIFZ';\n  NPC_ : TwbSignature = 'NPC_';\n  OFST : TwbSignature = 'OFST';\n  OBME : TwbSignature = 'OBME';\n  ONAM : TwbSignature = 'ONAM';\n  PACK : TwbSignature = 'PACK';\n  PFIG : TwbSignature = 'PFIG';\n  PFPC : TwbSignature = 'PFPC';\n  PGAG : TwbSignature = 'PGAG';\n  PGRD : TwbSignature = 'PGRD';\n  PGRI : TwbSignature = 'PGRI';\n  PGRL : TwbSignature = 'PGRL';\n  PGRP : TwbSignature = 'PGRP';\n  PGRR : TwbSignature = 'PGRR';\n  PKDT : TwbSignature = 'PKDT';\n  PKID : TwbSignature = 'PKID';\n  PLDT : TwbSignature = 'PLDT';\n  PNAM : TwbSignature = 'PNAM';\n  PSDT : TwbSignature = 'PSDT';\n  PTDT : TwbSignature = 'PTDT';\n  QNAM : TwbSignature = 'QNAM';\n  QSDT : TwbSignature = 'QSDT';\n  QSTA : TwbSignature = 'QSTA';\n  QSTI : TwbSignature = 'QSTI';\n  QSTR : TwbSignature = 'QSTR';\n  TPIC : TwbSignature = 'TPIC';\n  QUST : TwbSignature = 'QUST';\n  RACE : TwbSignature = 'RACE';\n  RCLR : TwbSignature = 'RCLR';\n  RDAT : TwbSignature = 'RDAT';\n  RDGS : TwbSignature = 'RDGS';\n  RDMD : TwbSignature = 'RDMD';\n  RDMP : TwbSignature = 'RDMP';\n  RDOT : TwbSignature = 'RDOT';\n  RDSD : TwbSignature = 'RDSD';\n  RDWT : TwbSignature = 'RDWT';\n  REFR : TwbSignature = 'REFR';\n  PLYR : TwbSignature = 'PLYR';\n  REGN : TwbSignature = 'REGN';\n  RNAM : TwbSignature = 'RNAM';\n  ROAD : TwbSignature = 'ROAD';\n  RPLD : TwbSignature = 'RPLD';\n  RPLI : TwbSignature = 'RPLI';\n  SBSP : TwbSignature = 'SBSP';\n  SCDA : TwbSignature = 'SCDA';\n  SCHD : TwbSignature = 'SCHD';\n  SCHR : TwbSignature = 'SCHR';\n  SCIT : TwbSignature = 'SCIT';\n  SCPT : TwbSignature = 'SCPT';\n  SCRI : TwbSignature = 'SCRI';\n  SCRO : TwbSignature = 'SCRO';\n  SCRV : TwbSignature = 'SCRV';\n  SCTX : TwbSignature = 'SCTX';\n  SCVR : TwbSignature = 'SCVR';\n  SGST : TwbSignature = 'SGST';\n  SKIL : TwbSignature = 'SKIL';\n  SLCP : TwbSignature = 'SLCP';\n  SLGM : TwbSignature = 'SLGM';\n  SLSD : TwbSignature = 'SLSD';\n  SNAM : TwbSignature = 'SNAM';\n  SNDD : TwbSignature = 'SNDD';\n  SNDX : TwbSignature = 'SNDX';\n  SOUL : TwbSignature = 'SOUL';\n  SOUN : TwbSignature = 'SOUN';\n  SPEL : TwbSignature = 'SPEL';\n  SPIT : TwbSignature = 'SPIT';\n  SPLO : TwbSignature = 'SPLO';\n  STAT : TwbSignature = 'STAT';\n  TCLF : TwbSignature = 'TCLF';\n  TCLT : TwbSignature = 'TCLT';\n  TES4 : TwbSignature = 'TES4';\n  TNAM : TwbSignature = 'TNAM';\n  TRDT : TwbSignature = 'TRDT';\n  TREE : TwbSignature = 'TREE';\n  UNAM : TwbSignature = 'UNAM';\n  VCLR : TwbSignature = 'VCLR';\n  VHGT : TwbSignature = 'VHGT';\n  VNAM : TwbSignature = 'VNAM';\n  VNML : TwbSignature = 'VNML';\n  VTEX : TwbSignature = 'VTEX';\n  VTXT : TwbSignature = 'VTXT';\n  WATR : TwbSignature = 'WATR';\n  WEAP : TwbSignature = 'WEAP';\n  WLST : TwbSignature = 'WLST';\n  WNAM : TwbSignature = 'WNAM';\n  WRLD : TwbSignature = 'WRLD';\n  WTHR : TwbSignature = 'WTHR';\n  XACT : TwbSignature = 'XACT';\n  XCCM : TwbSignature = 'XCCM';\n  XCHG : TwbSignature = 'XCHG';\n  XCLC : TwbSignature = 'XCLC';\n  XCLL : TwbSignature = 'XCLL';\n  XCLR : TwbSignature = 'XCLR';\n  XCLW : TwbSignature = 'XCLW';\n  XCMT : TwbSignature = 'XCMT';\n  XCNT : TwbSignature = 'XCNT';\n  XCWT : TwbSignature = 'XCWT';\n  XESP : TwbSignature = 'XESP';\n  XGLB : TwbSignature = 'XGLB';\n  XHLT : TwbSignature = 'XHLT';\n  XHRS : TwbSignature = 'XHRS';\n  XLCM : TwbSignature = 'XLCM';\n  XLOC : TwbSignature = 'XLOC';\n  XLOD : TwbSignature = 'XLOD';\n  XMRC : TwbSignature = 'XMRC';\n  XMRK : TwbSignature = 'XMRK';\n  XNAM : TwbSignature = 'XNAM';\n  XOWN : TwbSignature = 'XOWN';\n  XPCI : TwbSignature = 'XPCI';\n  XRGD : TwbSignature = 'XRGD';\n  XRNK : TwbSignature = 'XRNK';\n  XRTM : TwbSignature = 'XRTM';\n  XSCL : TwbSignature = 'XSCL';\n  XSED : TwbSignature = 'XSED';\n  XSOL : TwbSignature = 'XSOL';\n  XTEL : TwbSignature = 'XTEL';\n  XTRG : TwbSignature = 'XTRG';\n  XXXX : TwbSignature = 'XXXX';\n  ZNAM : TwbSignature = 'ZNAM';\n\nvar\n  wbEDID: IwbSubRecordDef;\n  wbXOWN: IwbSubRecordDef;\n  wbXGLB: IwbSubRecordDef;\n  wbXRGD: IwbSubRecordDef;\n  wbSLSD: IwbSubRecordDef;\n  wbBodyDataIndex: IwbSubRecordDef;\n  wbSPLO: IwbSubRecordDef;\n  wbSPLOs: IwbSubRecordArrayDef;\n  wbCNTO: IwbSubRecordDef;\n  wbCNTOs: IwbSubRecordArrayDef;\n  wbCSDT: IwbSubRecordStructDef;\n  wbCSDTs: IwbSubRecordArrayDef;\n  wbFULL: IwbSubRecordDef;\n  wbFULLReq: IwbSubRecordDef;\n  wbXNAM: IwbSubRecordDef;\n  wbXNAMs: IwbSubRecordArrayDef;\n  wbDESC: IwbSubRecordDef;\n  wbXSCL: IwbSubRecordDef;\n  wbDATAPosRot : IwbSubRecordDef;\n  wbPosRot : IwbStructDef;\n  wbMODL: IwbSubRecordStructDef;\n  wbCTDA: IwbSubRecordUnionDef;\n  wbSCHR: IwbSubRecordUnionDef;\n  wbCTDAs: IwbSubRecordArrayDef;\n  wbSCROs: IwbSubRecordArrayDef;\n  wbPGRP: IwbSubRecordDef;\n  wbResultScript: IwbSubRecordStructDef;\n//  wbResultScriptOld: IwbSubRecordStructDef;\n  wbSCRI: IwbSubRecordDef;\n  wbFaceGen: IwbSubRecordStructDef;\n  wbENAM: IwbSubRecordDef;\n  wbFGGS: IwbSubRecordDef;\n  wbXLOD: IwbSubRecordDef;\n  wbXESP: IwbSubRecordDef;\n  wbICON: IwbSubRecordDef;\n  wbEFID: IwbSubRecordDef;\n  wbEFIDOBME: IwbSubRecordDef;\n  wbEFIT: IwbSubRecordDef;\n  wbEFITOBME: IwbSubRecordDef;\n  wbEFIX: IwbSubRecordDef;\n  wbSCIT: IwbSubRecordStructDef;\n  wbSCITOBME: IwbSubRecordStructDef;\n//  wbEffects: IwbSubRecordUnionDef;\n  wbEffects: IwbSubRecordArrayDef;\n\nfunction wbClmtMoonsPhaseLength(aInt: Int64; const aElement: IwbElement; aType: TwbCallbackType): string;\nvar\n  PhaseLength : Byte;\n  Masser      : Boolean;\n  Secunda     : Boolean;\nbegin\n  Result := '';\n  if aType = ctToSortKey then begin\n    Result := IntToHex64(aInt, 2);\n  end else if aType = ctToStr then begin\n    PhaseLength := aInt mod 64;\n    Masser := (aInt and 64) <> 0;\n    Secunda := (aInt and 128) <> 0;\n    if Masser then\n      if Secunda then\n        Result := 'Masser, Secunda / '\n      else\n        Result := 'Masser / '\n    else\n      if Secunda then\n        Result := 'Secunda / '\n      else\n        Result := 'No Moon / ';\n    Result := Result + IntToStr(PhaseLength);\n  end;\nend;\n\nfunction wbClmtTime(aInt: Int64; const aElement: IwbElement; aType: TwbCallbackType): string;\nbegin\n  Result := '';\n  if aType = ctToSortKey then\n    Result := IntToHex64(aInt, 4)\n  else if aType = ctToStr then\n    Result := TimeToStr( EncodeTime(aInt div 6, (aInt mod 6) * 10, 0, 0) );\nend;\n\nvar\n  wbCtdaTypeFlags : IwbFlagsDef;\n\nfunction wbCtdaType(aInt: Int64; const aElement: IwbElement; aType: TwbCallbackType): string;\nvar\n  s: string;\nbegin\n  Result := '';\n  case aType of\n    ctToStr: begin\n      case aInt and $F0 of\n        $00 : Result := 'Equal to';\n        $20 : Result := 'Not equal to';\n        $40 : Result := 'Greater than';\n        $60 : Result := 'Greater than or equal to';\n        $80 : Result := 'Less than';\n        $A0 : Result := 'Less than or equal to';\n      else\n        Result := '<Unknown Compare operator>'\n      end;\n\n      if not Assigned(wbCtdaTypeFlags) then\n        wbCtdaTypeFlags := wbFlags([\n          {0x01} 'Or',\n          {0x02} 'Run on target',\n          {0x04} 'Use global'\n        ]);\n\n      s := wbCtdaTypeFlags.ToString(aInt and $0F, aElement);\n\n      if s <> '' then\n        Result := Result + ' / ' + s;\n    end;\n    ctToSortKey: begin\n      Result := IntToHex64(aInt, 2);\n      Exit;\n    end;\n    ctCheck: begin\n      case aInt and $F0 of\n        $00, $20, $40, $60, $80, $A0 : Result := '';\n      else\n        Result := '<Unknown Compare operator>'\n      end;\n\n      if not Assigned(wbCtdaTypeFlags) then\n        wbCtdaTypeFlags := wbFlags([\n          {0x01} 'Or',\n          {0x02} 'Run on target',\n          {0x04} 'Use global'\n        ]);\n\n      s := wbCtdaTypeFlags.Check(aInt and $0F, aElement);\n\n      if s <> '' then\n        Result := Result + ' / ' + s;\n    end;\n  end;\nend;\n\nfunction wbIdleAnam(aInt: Int64; const aElement: IwbElement; aType: TwbCallbackType): string;\nbegin\n  Result := '';\n  case aType of\n    ctToStr: begin\n      case aInt and not $80 of\n        0: Result := 'Lower Body';\n        1: Result := 'Left Arm';\n        2: Result := 'Left Hand';\n        3: Result := 'Right Arm';\n        4: Result := 'Special Idle';\n        5: Result := 'Whole Body';\n        6: Result := 'Upper Body';\n      else\n        Result := '<Unknown: '+IntToStr(aInt and not $80)+'>';\n      end;\n\n      if (aInt and $80) = 0 then\n        Result := Result + ', Must return a file';\n    end;\n    ctToSortKey: begin\n      Result := IntToHex64(aInt, 2);\n    end;\n    ctCheck: begin\n      case aInt and not $80 of\n        0..6: Result := '';\n      else\n        Result := '<Unknown: '+IntToStr(aInt and not $80)+'>';\n      end;\n    end;\n  end;\nend;\n\nfunction wbScaledInt4ToStr(aInt: Int64; const aElement: IwbElement; aType: TwbCallbackType): string;\nconst\n  PlusMinus : array[Boolean] of string = ('+', '-');\nbegin\n  Result := '';\n  case aType of\n    ctToStr, ctToEditValue: Result := FloatToStrF(aInt / 10000, ffFixed, 99, 4);\n    ctToSortKey: begin\n      Result := FloatToStrF(aInt / 10000, ffFixed, 99, 4);\n      if Length(Result) < 22 then\n        Result := StringOfChar('0', 22 - Length(Result)) + Result;\n      Result := PlusMinus[aInt < 0] + Result;\n    end;\n    ctCheck: Result := '';\n  end;\nend;\n\nfunction wbScaledInt4ToInt(const aString: string; const aElement: IwbElement): Int64;\nvar\n  f: Extended;\nbegin\n  f := StrToFloat(aString);\n  f := f * 10000;\n  Result := Round(f);\nend;\n\nfunction wbHideFFFF(aInt: Int64; const aElement: IwbElement; aType: TwbCallbackType): string;\nbegin\n  Result := '';\n  if aType = ctToSortKey then\n    Result := IntToHex64(aInt, 4)\n  else if aType = ctToStr then\n    if aInt = $FFFF then\n      Result := 'None'\n    else\n      Result := IntToStr(aInt);\nend;\n\nfunction wbAtxtPosition(aInt: Int64; const aElement: IwbElement; aType: TwbCallbackType): string;\nbegin\n  Result := '';\n  if aType = ctToSortKey then\n    Result := IntToHex64(aInt div 17, 2) + IntToHex64(aInt mod 17, 2)\n  else if aType = ctCheck then begin\n    if (aInt < 0) or (aInt > 288) then\n      Result := '<Out of range: '+IntToStr(aInt)+'>'\n    else\n      Result := '';\n  end else if aType = ctToStr then\n    Result := IntToStr(aInt) + ' -> ' + IntToStr(aInt div 17) + ':' + IntToStr(aInt mod 17);\nend;\n\nfunction wbWthrDataClassification(aInt: Int64; const aElement: IwbElement; aType: TwbCallbackType): string;\nbegin\n  Result := '';\n  case aType of\n    ctToStr: begin\n      case aInt and not 192 of\n        0: Result := 'None';\n        1: Result := 'Pleasant';\n        2: Result := 'Cloudy';\n        3: Result := 'Unknown 3';\n        4: Result := 'Rainy';\n        8: Result := 'Snow';\n      else\n        Result := '<Unknown: '+IntToStr(aInt and not 192)+'>';\n      end;\n    end;\n    ctToSortKey: begin\n      Result := IntToHex64(aInt, 2)\n    end;\n    ctCheck: begin\n      case aInt and not 192 of\n        0..4, 8: Result := '';\n      else\n        Result := '<Unknown: '+IntToStr(aInt and not 192)+'>';\n      end;\n    end;\n  end;\nend;\n\nfunction wbGLOBFNAM(aInt: Int64; const aElement: IwbElement; aType: TwbCallbackType): string;\nbegin\n  Result := '';\n  case aType of\n    ctToStr: begin\n      case aInt of\n        Ord('s'): Result := 'Short';\n        Ord('l'): Result := 'Long';\n        Ord('f'): Result := 'Float';\n      else\n        Result := '<Unknown: '+IntToStr(aInt)+'>';\n      end;\n    end;\n    ctToSortKey: Result := Chr(aInt);\n    ctCheck: begin\n      case aInt of\n        Ord('s'), Ord('l'), Ord('f'): Result := '';\n      else\n        Result := '<Unknown: '+IntToStr(aInt)+'>';\n      end;\n    end;\n  end;\nend;\n\nfunction wbPlacedAddInfo(const aMainRecord: IwbMainRecord): string;\nvar\n  Rec: IwbRecord;\n  Container: IwbContainer;\n  s: string;\n  Cell: IwbMainRecord;\n  Position: TwbVector;\n  Grid: TwbGridCell;\nbegin\n  Result := '';\n\n  Rec := aMainRecord.RecordBySignature['NAME'];\n  if Assigned(Rec) then begin\n    s := Trim(Rec.Value);\n    if s <> '' then\n      Result := 'places ' + s;\n  end;\n\n  Container := aMainRecord.Container;\n  while Assigned(Container) and (Container.ElementType <> etGroupRecord) do\n    Container := Container.Container;\n\n  if Assigned(Container) then begin\n    s := Trim(Container.Name);\n    if s <> '' then begin\n      if Result <> '' then\n        Result := Result + ' ';\n      Result := Result + 'in ' + s;\n\n      // grid position of persistent reference in exterior persistent cell (interior cells are not persistent)\n      if Supports(aMainRecord.Container, IwbGroupRecord, Container) then\n        Cell := IwbGroupRecord(Container).ChildrenOf;\n      if Assigned(Cell) and Cell.IsPersistent and (Cell.Signature = 'CELL') then\n        if aMainRecord.GetPosition(Position) then begin\n          Grid := wbPositionToGridCell(Position);\n          Result := Result + ' at ' + IntToStr(Grid.x) + ',' + IntToStr(Grid.y);\n        end;\n    end;\n  end;\nend;\n\nfunction wbCellAddInfo(const aMainRecord: IwbMainRecord): string;\nvar\n  Rec: IwbRecord;\n  Container: IwbContainer;\n  GroupRecord : IwbGroupRecord;\n  s: string;\nbegin\n  Result := '';\n\n  if not aMainRecord.IsPersistent then begin\n    Rec := aMainRecord.RecordBySignature['XCLC'];\n    if Assigned(Rec) then\n      Result := 'at ' + Rec.Elements[0].Value + ',' + Rec.Elements[1].Value;\n  end;\n\n  Container := aMainRecord.Container;\n  while Assigned(Container) and not\n    (Supports(Container, IwbGroupRecord, GroupRecord) and (GroupRecord.GroupType = 1))  do\n    Container := Container.Container;\n\n  if Assigned(Container) then begin\n    s := wbFormID.ToString(GroupRecord.GroupLabel, aMainRecord);\n    if s <> '' then begin\n      if Result <> '' then\n        s := s + ' ';\n      Result := 'in ' + s + Result;\n    end;\n  end;\nend;\n\nfunction wbGMSTUnionDecider(aBasePtr: Pointer; aEndPtr: Pointer; const aElement: IwbElement): Integer;\nvar\n  rEDID: IwbRecord;\n  s: string;\nbegin\n  Result := 1;\n  rEDID := aElement.Container.RecordBySignature[EDID];\n  if Assigned(rEDID) then begin\n    s := rEDID.Value;\n    if Length(s) > 0 then\n      case s[1] of\n        's': Result := 0;\n        'f': Result := 2;\n      end;\n  end;\nend;\n\nfunction wbMISCActorValueDecider(aBasePtr: Pointer; aEndPtr: Pointer; const aElement: IwbElement): Integer;\nvar\n  MainRecord : IwbMainRecord;\nbegin\n  Result := 0;\n\n  if not Assigned(aElement) then\n    Exit;\n\n  MainRecord := aElement.ContainingMainRecord;\n  if not Assigned(MainRecord) then\n    Exit;\n\n  if (MainRecord.Flags._Flags and $000000C0) = $000000C0 then\n    Result := 1;\nend;\n\nfunction wbXLOCFillerDecider(aBasePtr: Pointer; aEndPtr: Pointer; const aElement: IwbElement): Integer;\nvar\n  Container : IwbContainer;\n  SubRecord : IwbSubRecord;\nbegin\n  Result := 0;\n  if not Assigned(aElement) then Exit;\n  Container := GetContainerFromUnion(aElement);\n  if not Assigned(Container) then Exit;\n\n  if Supports(Container, IwbSubRecord, SubRecord) then\n    if SubRecord.SubRecordHeaderSize = 16 then\n      Result := 1;\nend;\n\nfunction wbPACKPKDTDecider(aBasePtr: Pointer; aEndPtr: Pointer; const aElement: IwbElement): Integer;\nvar\n  Container : IwbContainer;\n  SubRecord : IwbSubRecord;\nbegin\n  Result := 1;\n  if not Assigned(aElement) then Exit;\n  Container := GetContainerFromUnion(aElement);\n  if not Assigned(Container) then Exit;\n  if Supports(Container, IwbSubRecord, SubRecord) then\n    if SubRecord.SubRecordHeaderSize = 4 then\n      Result := 0;\nend;\n\nfunction wbREFRXSEDDecider(aBasePtr: Pointer; aEndPtr: Pointer; const aElement: IwbElement): Integer;\nvar\n  Container : IwbContainer;\n  SubRecord : IwbSubRecord;\nbegin\n  Result := 0;\n  if not Assigned(aElement) then Exit;\n  Container := GetContainerFromUnion(aElement);\n  if not Assigned(Container) then Exit;\n\n  if Supports(Container, IwbSubRecord, SubRecord) then\n    if SubRecord.SubRecordHeaderSize = 4 then\n      Result := 1;\nend;\n\n\ntype\n  TCTDAFunctionParamType = (\n    ptNone,\n    ptInteger,\n    ptVariableName,  //Integer\n    ptSex,           //Enum: Male, Female\n    ptActorValue,    //Enum: wbActorValue\n    ptCrimeType,     //?? Enum\n    ptAxis,          //?? Char\n    ptFormType,      //?? Enum\n    ptQuestStage,\n\n    ptObjectReference,    //REFR, ACHR, ACRE, PGRE\n    ptInventoryObject,    //ARMO, BOOK, MISC, WEAP, AMMO, KEYM, ALCH, NOTE, ARMA\n    ptActor,              //ACHR, ACRE\n    ptQuest,              //QUST\n    ptFaction,            //FACT\n    ptCell,               //CELL\n    ptClass,              //CLAS\n    ptRace,               //RACE\n    ptActorBase,          //NPC_, CREA\n    ptGlobal,             //GLOB\n    ptWeather,            //WTHR\n    ptPackage,            //PACK\n    ptOwnerOpt,           //FACT, NPC_\n    ptBirthsign,          //BSGN\n    ptFurniture,          //FURN\n    ptMagicItem,          //SPEL\n    ptMagicEffect,        //MGEF\n    ptWorldspace,         //WRLD\n    ptReferencableObject\n  );\n\n  PCTDAFunction = ^TCTDAFunction;\n  TCTDAFunction = record\n    Index: Integer;\n    Name: string;\n    ParamType1: TCTDAFunctionParamType;\n    ParamType2: TCTDAFunctionParamType;\n  end;\n\nconst\n  wbCTDAFunctions : array[0..191] of TCTDAFunction = (\n    (Index:   1; Name: 'GetDistance'; ParamType1: ptObjectReference),\n    (Index:   5; Name: 'GetLocked'),\n    (Index:   6; Name: 'GetPos'; ParamType1: ptAxis),\n    (Index:   8; Name: 'GetAngle'; ParamType1: ptAxis),\n    (Index:  10; Name: 'GetStartingPos'; ParamType1: ptAxis),\n    (Index:  11; Name: 'GetStartingAngle'; ParamType1: ptAxis),\n    (Index:  12; Name: 'GetSecondsPassed'),\n    (Index:  14; Name: 'GetActorValue'; ParamType1: ptActorValue),\n    (Index:  18; Name: 'GetCurrentTime'),\n    (Index:  24; Name: 'GetScale'),\n    (Index:  27; Name: 'GetLineOfSight'; ParamType1: ptObjectReference),\n    (Index:  32; Name: 'GetInSameCell'; ParamType1: ptObjectReference),\n    (Index:  35; Name: 'GetDisabled'),\n    (Index:  36; Name: 'MenuMode'; ParamType1: ptInteger),\n    (Index:  39; Name: 'GetDisease'),\n    (Index:  40; Name: 'GetVampire'),\n    (Index:  41; Name: 'GetClothingValue'),\n    (Index:  42; Name: 'SameFaction'; ParamType1: ptActor),\n    (Index:  43; Name: 'SameRace'; ParamType1: ptActor),\n    (Index:  44; Name: 'SameSex'; ParamType1: ptActor),\n    (Index:  45; Name: 'GetDetected'; ParamType1: ptActor),\n    (Index:  46; Name: 'GetDead'),\n    (Index:  47; Name: 'GetItemCount'; ParamType1: ptInventoryObject),\n    (Index:  48; Name: 'GetGold'),\n    (Index:  49; Name: 'GetSleeping'),\n    (Index:  50; Name: 'GetTalkedToPC'),\n    (Index:  53; Name: 'GetScriptVariable'; ParamType1: ptObjectReference; ParamType2: ptVariableName),\n    (Index:  56; Name: 'GetQuestRunning'; ParamType1: ptQuest),\n    (Index:  58; Name: 'GetStage'; ParamType1: ptQuest),\n    (Index:  59; Name: 'GetStageDone'; ParamType1: ptQuest; ParamType2: ptQuestStage),\n    (Index:  60; Name: 'GetFactionRankDifference'; ParamType1: ptFaction; ParamType2: ptActor),\n    (Index:  61; Name: 'GetAlarmed'),\n    (Index:  62; Name: 'IsRaining'),\n    (Index:  63; Name: 'GetAttacked'),\n    (Index:  64; Name: 'GetIsCreature'),\n    (Index:  65; Name: 'GetLockLevel'),\n    (Index:  66; Name: 'GetShouldAttack'; ParamType1: ptActor),\n    (Index:  67; Name: 'GetInCell'; ParamType1: ptCell),\n    (Index:  68; Name: 'GetIsClass'; ParamType1: ptClass),\n    (Index:  69; Name: 'GetIsRace'; ParamType1: ptRace),\n    (Index:  70; Name: 'GetIsSex'; ParamType1: ptSex),\n    (Index:  71; Name: 'GetInFaction'; ParamType1: ptFaction),\n    (Index:  72; Name: 'GetIsID'; ParamType1: ptReferencableObject),\n    (Index:  73; Name: 'GetFactionRank'; ParamType1: ptFaction),\n    (Index:  74; Name: 'GetGlobalValue'; ParamType1: ptGlobal),\n    (Index:  75; Name: 'IsSnowing'),\n    (Index:  76; Name: 'GetDisposition'; ParamType1: ptActor),\n    (Index:  77; Name: 'GetRandomPercent'),\n    (Index:  79; Name: 'GetQuestVariable'; ParamType1: ptQuest; ParamType2: ptVariableName),\n    (Index:  80; Name: 'GetLevel'),\n    (Index:  81; Name: 'GetArmorRating'),\n    (Index:  84; Name: 'GetDeadCount'; ParamType1: ptActorBase),\n    (Index:  91; Name: 'GetIsAlerted'),\n    (Index:  98; Name: 'GetPlayerControlsDisabled'),\n    (Index:  99; Name: 'GetHeadingAngle'; ParamType1: ptObjectReference),\n    (Index: 101; Name: 'IsWeaponOut'),\n    (Index: 102; Name: 'IsTorchOut'),\n    (Index: 103; Name: 'IsShieldOut'),\n    (Index: 104; Name: 'IsYielding'),\n    (Index: 106; Name: 'IsFacingUp'),\n    (Index: 107; Name: 'GetKnockedState'),\n    (Index: 108; Name: 'GetWeaponAnimType'),\n    (Index: 109; Name: 'GetWeaponSkillType'),\n    (Index: 110; Name: 'GetCurrentAIPackage'),\n    (Index: 111; Name: 'IsWaiting'),\n    (Index: 112; Name: 'IsIdlePlaying'),\n    (Index: 116; Name: 'GetCrimeGold'),\n    (Index: 122; Name: 'GetCrime'; ParamType1: ptActor; ParamType2: ptCrimeType),\n    (Index: 125; Name: 'IsGuard'),\n    (Index: 127; Name: 'CanPayCrimeGold'),\n    (Index: 128; Name: 'GetFatiguePercentage'),\n    (Index: 129; Name: 'GetPCIsClass'; ParamType1: ptClass),\n    (Index: 130; Name: 'GetPCIsRace'; ParamType1: ptRace),\n    (Index: 131; Name: 'GetPCIsSex'; ParamType1: ptSex),\n    (Index: 132; Name: 'GetPCInFaction'; ParamType1: ptFaction),\n    (Index: 133; Name: 'SameFactionAsPC'),\n    (Index: 134; Name: 'SameRaceAsPC'),\n    (Index: 135; Name: 'SameSexAsPC'),\n    (Index: 136; Name: 'GetIsReference'; ParamType1: ptObjectReference),\n    (Index: 141; Name: 'IsTalking'),\n    (Index: 142; Name: 'GetWalkSpeed'),\n    (Index: 143; Name: 'GetCurrentAIProcedure'),\n    (Index: 144; Name: 'GetTrespassWarningLevel'),\n    (Index: 145; Name: 'IsTrespassing'),\n    (Index: 146; Name: 'IsInMyOwnedCell'),\n    (Index: 147; Name: 'GetWindSpeed'),\n    (Index: 148; Name: 'GetCurrentWeatherPercent'),\n    (Index: 149; Name: 'GetIsCurrentWeather'; ParamType1: ptWeather),\n    (Index: 150; Name: 'IsContinuingPackagePCNear'),\n    (Index: 153; Name: 'CanHaveFlames'),\n    (Index: 154; Name: 'HasFlames'),\n    (Index: 157; Name: 'GetOpenState'),\n    (Index: 159; Name: 'GetSitting'),\n    (Index: 160; Name: 'GetFurnitureMarkerID'),\n    (Index: 161; Name: 'GetIsCurrentPackage'; ParamType1: ptPackage),\n    (Index: 162; Name: 'IsCurrentFurnitureRef'; ParamType1: ptObjectReference),\n    (Index: 163; Name: 'IsCurrentFurnitureObj'; ParamType1: ptFurniture),\n    (Index: 170; Name: 'GetDayOfWeek'),\n    (Index: 171; Name: 'IsPlayerInJail'),\n    (Index: 172; Name: 'GetTalkedToPCParam'; ParamType1: ptActor),\n    (Index: 175; Name: 'IsPCSleeping'),\n    (Index: 176; Name: 'IsPCAMurderer'),\n    (Index: 180; Name: 'GetDetectionLevel'; ParamType1: ptActor),\n    (Index: 182; Name: 'GetEquipped'; ParamType1: ptInventoryObject),\n    (Index: 185; Name: 'IsSwimming'),\n    (Index: 190; Name: 'GetAmountSoldStolen'),\n    (Index: 193; Name: 'GetPCExpelled'; ParamType1: ptFaction),\n    (Index: 195; Name: 'GetPCFactionMurder'; ParamType1: ptFaction),\n    (Index: 197; Name: 'GetPCFactionSteal'; ParamType1: ptFaction),\n    (Index: 199; Name: 'GetPCFactionAttack'; ParamType1: ptFaction),\n    (Index: 201; Name: 'GetPCFactionSubmitAuthority'; ParamType1: ptFaction),\n    (Index: 203; Name: 'GetDestroyed'),\n    (Index: 214; Name: 'HasMagicEffect'; ParamType1: ptMagicEffect),\n    (Index: 215; Name: 'GetDoorDefaultOpen'),\n    (Index: 223; Name: 'IsSpellTarget'; ParamType1: ptMagicItem),\n    (Index: 224; Name: 'GetIsPlayerBirthsign'; ParamType1: ptBirthsign),\n    (Index: 225; Name: 'GetPersuasionNumber'),\n    (Index: 227; Name: 'HasVampireFed'),\n    (Index: 228; Name: 'GetIsClassDefault'; ParamType1: ptClass),\n    (Index: 229; Name: 'GetClassDefaultMatch'),\n    (Index: 230; Name: 'GetInCellParam'; ParamType1: ptCell; ParamType2: ptObjectReference),\n    (Index: 237; Name: 'GetIsGhost'),\n    (Index: 242; Name: 'GetUnconscious'),\n    (Index: 244; Name: 'GetRestrained'),\n    (Index: 246; Name: 'GetIsUsedItem'; ParamType1: ptReferencableObject),\n    (Index: 247; Name: 'GetIsUsedItemType'; ParamType1: ptFormType),\n    (Index: 249; Name: 'GetPCFame'),\n    (Index: 251; Name: 'GetPCInfamy'),\n    (Index: 254; Name: 'GetIsPlayableRace'),\n    (Index: 255; Name: 'GetOffersServicesNow'),\n    (Index: 258; Name: 'GetUsedItemLevel'),\n    (Index: 259; Name: 'GetUsedItemActivate'),\n    (Index: 264; Name: 'GetBarterGold'),\n    (Index: 265; Name: 'IsTimePassing'),\n    (Index: 266; Name: 'IsPleasant'),\n    (Index: 267; Name: 'IsCloudy'),\n    (Index: 274; Name: 'GetArmorRatingUpperBody'),\n    (Index: 277; Name: 'GetBaseActorValue'; ParamType1: ptActorValue),\n    (Index: 278; Name: 'IsOwner'; ParamType1: ptOwnerOpt),\n    (Index: 280; Name: 'IsCellOwner'; ParamType1: ptCell; ParamType2: ptOwnerOpt),\n    (Index: 282; Name: 'IsHorseStolen'),\n    (Index: 285; Name: 'IsLeftUp'),\n    (Index: 286; Name: 'IsSneaking'),\n    (Index: 287; Name: 'IsRunning'),\n    (Index: 288; Name: 'GetFriendHit'; ParamType1: ptActor),\n    (Index: 289; Name: 'IsInCombat'),\n    (Index: 300; Name: 'IsInInterior'),\n    (Index: 305; Name: 'GetInvestmentGold'),\n    (Index: 306; Name: 'IsActorUsingATorch'),\n    (Index: 309; Name: 'IsXBox'),\n    (Index: 310; Name: 'GetInWorldspace'; ParamType1: ptWorldSpace),\n    (Index: 312; Name: 'GetPCMiscStat'; ParamType1: ptInteger),\n    (Index: 313; Name: 'IsActorEvil'),\n    (Index: 314; Name: 'IsActorAVictim'),\n    (Index: 315; Name: 'GetTotalPersuasionNumber'),\n    (Index: 318; Name: 'GetIdleDoneOnce'),\n    (Index: 320; Name: 'GetNoRumors'),\n    (Index: 323; Name: 'WhichServiceMenu'),\n    (Index: 327; Name: 'IsRidingHorse'),\n    (Index: 329; Name: 'IsTurnArrest'),\n    (Index: 332; Name: 'IsInDangerousWater'),\n    (Index: 338; Name: 'GetIgnoreFriendlyHits'),\n    (Index: 339; Name: 'IsPlayersLastRiddenHorse'),\n    (Index: 353; Name: 'IsActor'),\n    (Index: 354; Name: 'IsEssential'),\n    (Index: 358; Name: 'IsPlayerMovingIntoNewSpace'),\n    (Index: 361; Name: 'GetTimeDead'),\n    (Index: 362; Name: 'GetPlayerHasLastRiddenHorse'),\n    (Index: 365; Name: 'GetPlayerInSEWorld'),\n\n    // Added by OBSE:\n    (Index: 1107; Name: 'IsAmmo,'; ParamType1: ptInteger),\n    (Index: 1884; Name: 'GetPCTrainingSessionsUsed'; ParamType1: ptPackage),\n    (Index: 2213; Name: 'GetPackageOffersServices'; ParamType1: ptPackage),\n    (Index: 2214; Name: 'GetPackageMustReachLocation'; ParamType1: ptPackage),\n    (Index: 2215; Name: 'GetPackageMustComplete'; ParamType1: ptPackage),\n    (Index: 2216; Name: 'GetPackageLockDoorsAtStart'; ParamType1: ptPackage),\n    (Index: 2217; Name: 'GetPackageLockDoorsAtEnd'; ParamType1: ptPackage),\n    (Index: 2218; Name: 'GetPackageLockDoorsAtLocation'; ParamType1: ptPackage),\n    (Index: 2219; Name: 'GetPackageUnlockDoorsAtStart'; ParamType1: ptPackage),\n    (Index: 2220; Name: 'GetPackageUnlockDoorsAtEnd'; ParamType1: ptPackage),\n    (Index: 2221; Name: 'GetPackageUnlockDoorsAtLocation'; ParamType1: ptPackage),\n    (Index: 2222; Name: 'GetPackageContinueIfPCNear'; ParamType1: ptPackage),\n    (Index: 2223; Name: 'GetPackageOncePerDay'; ParamType1: ptPackage),\n    (Index: 2224; Name: 'GetPackageSkipFalloutBehavior'; ParamType1: ptPackage),\n    (Index: 2225; Name: 'GetPackageAlwaysRun'; ParamType1: ptPackage),\n    (Index: 2226; Name: 'GetPackageAlwaysSneak'; ParamType1: ptPackage),\n    (Index: 2227; Name: 'GetPackageAllowSwimming'; ParamType1: ptPackage),\n    (Index: 2228; Name: 'GetPackageAllowFalls'; ParamType1: ptPackage),\n    (Index: 2229; Name: 'GetPackageArmorUnequipped'; ParamType1: ptPackage),\n    (Index: 2230; Name: 'GetPackageWeaponsUnequipped'; ParamType1: ptPackage),\n    (Index: 2231; Name: 'GetPackageDefensiveCombat'; ParamType1: ptPackage),\n    (Index: 2232; Name: 'GetPackageUseHorse'; ParamType1: ptPackage),\n    (Index: 2233; Name: 'GetPackageNoIdleAnims'; ParamType1: ptPackage)\n  );\n\nvar\n  wbCTDAFunctionEditInfo : string;\n\nfunction wbCTDAParamDescFromIndex(aIndex: Integer): PCTDAFunction;\nvar\n  L, H, I, C: Integer;\nbegin\n  Result := nil;\n\n  L := Low(wbCTDAFunctions);\n  H := High(wbCTDAFunctions);\n  while L <= H do begin\n    I := (L + H) shr 1;\n    C := CmpW32(wbCTDAFunctions[I].Index, aIndex);\n    if C < 0 then\n      L := I + 1\n    else begin\n      H := I - 1;\n      if C = 0 then begin\n        L := I;\n        Result := @wbCTDAFunctions[L];\n      end;\n    end;\n  end;\nend;\n\nfunction wbCTDACompValueDecider(aBasePtr: Pointer; aEndPtr: Pointer; const aElement: IwbElement): Integer;\nvar\n  Container: IwbContainer;\nbegin\n  Result := 0;\n  if not Assigned(aElement) then Exit;\n  Container := GetContainerFromUnion(aElement);\n  if not Assigned(Container) then Exit;\n\n  if Integer(Container.ElementByName['Type'].NativeValue) and $04 <> 0 then\n    Result := 1;\nend;\n\nfunction wbEFITOBMEParamDecider(aBasePtr: Pointer; aEndPtr: Pointer; const aElement: IwbElement): Integer;\nvar\n  ParamInfo: Variant;\n  Container: IwbContainer;\nbegin\n  Result := 0;\n  if not Assigned(aElement) then Exit;\n  Container := GetContainerFromUnion(aElement);\n  if not Assigned(Container) then Exit;\n\n  ParamInfo := Container.ElementNativeValues['..\\EFME\\EFIT Param Info'];\n  if VarIsNull(ParamInfo) or VarIsEmpty(ParamInfo) then\n  else\n    Result := ParamInfo;\nend;\n\nfunction wbEFIXParamDecider(aBasePtr: Pointer; aEndPtr: Pointer; const aElement: IwbElement): Integer;\nvar\n  ParamInfo: Variant;\n  Container: IwbContainer;\nbegin\n  Result := 0;\n  if not Assigned(aElement) then Exit;\n  Container := GetContainerFromUnion(aElement);\n  if not Assigned(Container) then Exit;\n\n  ParamInfo := Container.ElementNativeValues['..\\EFME\\EFIX Param Info'];\n  if VarIsNull(ParamInfo) or VarIsEmpty(ParamInfo) then\n  else\n    Result := ParamInfo;\nend;\n\nfunction wbCTDAParam1Decider(aBasePtr: Pointer; aEndPtr: Pointer; const aElement: IwbElement): Integer;\nvar\n  Desc: PCTDAFunction;\n  Container: IwbContainer;\nbegin\n  Result := 0;\n  if not Assigned(aElement) then Exit;\n  Container := GetContainerFromUnion(aElement);\n  if not Assigned(Container) then Exit;\n\n  Desc := wbCTDAParamDescFromIndex(Container.ElementByName['Function'].NativeValue);\n  if Assigned(Desc) then\n    Result := Succ(Integer(Desc.ParamType1));\nend;\n\nfunction wbCTDAParam2Decider(aBasePtr: Pointer; aEndPtr: Pointer; const aElement: IwbElement): Integer;\nvar\n  Desc: PCTDAFunction;\n  Container: IwbContainer;\nbegin\n  Result := 0;\n  if not Assigned(aElement) then Exit;\n  Container := GetContainerFromUnion(aElement);\n  if not Assigned(Container) then Exit;\n\n  Desc := wbCTDAParamDescFromIndex(Container.ElementByName['Function'].NativeValue);\n  if Assigned(Desc) then\n    Result := Succ(Integer(Desc.ParamType2));\nend;\n{\nfunction wbCTDAFunction(aInt: Int64; const aElement: IwbElement; aType: TwbCallbackType): string;\nvar\n  Desc: PCTDAFunction;\nbegin\n  Result := '';\n  case aType of\n    ctToStr: begin\n      Desc := wbCTDAParamDescFromIndex(aInt);\n      if Assigned(Desc) then\n        Result := Desc.Name\n      else\n        Result := '<Unknown: '+IntToStr(aInt)+'>';\n    end;\n    ctToSortKey: Result := IntToHex(aInt, 8);\n    ctCheck: begin\n      Desc := wbCTDAParamDescFromIndex(aInt);\n      if Assigned(Desc) then\n        Result := ''\n      else\n        Result := '<Unknown: '+IntToStr(aInt)+'>';\n    end;\n  end;\nend;\n}\nfunction wbCTDAFunctionToStr(aInt: Int64; const aElement: IwbElement; aType: TwbCallbackType): string;\nvar\n  Desc : PCTDAFunction;\n  i    : Integer;\nbegin\n  Result := '';\n  case aType of\n    ctToStr, ctToEditValue: begin\n      Desc := wbCTDAParamDescFromIndex(aInt);\n      if Assigned(Desc) then\n        Result := Desc.Name\n      else if aType = ctToEditValue then\n        Result := IntToStr(aInt)\n      else\n        Result := '<Unknown: '+IntToStr(aInt)+'>';\n    end;\n    ctToSortKey: Result := IntToHex(aInt, 8);\n    ctCheck: begin\n      Desc := wbCTDAParamDescFromIndex(aInt);\n      if Assigned(Desc) then\n        Result := ''\n      else\n        Result := '<Unknown: '+IntToStr(aInt)+'>';\n    end;\n    ctEditType:\n      Result := 'ComboBox';\n    ctEditInfo: begin\n      Result := wbCTDAFunctionEditInfo;\n      if Result = '' then begin\n        with TStringList.Create do try\n          for i := Low(wbCTDAFunctions) to High(wbCTDAFunctions) do\n            Add(wbCTDAFunctions[i].Name);\n          Sort;\n          Result := CommaText;\n        finally\n          Free;\n        end;\n        wbCTDAFunctionEditInfo := Result;\n      end;\n    end;\n  end;\nend;\n\nfunction wbCTDAFunctionToInt(const aString: string; const aElement: IwbElement): Int64;\nvar\n  i: Integer;\nbegin\n  for i := Low(wbCTDAFunctions) to High(wbCTDAFunctions) do\n    with wbCTDAFunctions[i] do\n      if SameText(Name, aString) then begin\n        Result := Index;\n        Exit;\n      end;\n  Result := StrToInt64(aString);\nend;\n\nfunction wbCTDAParam2VariableNameToStr(aInt: Int64; const aElement: IwbElement; aType: TwbCallbackType): string;\nvar\n  Container  : IwbContainerElementRef;\n  Param1     : IwbElement;\n  MainRecord : IwbMainRecord;\n  BaseRecord : IwbMainRecord;\n  ScriptRef  : IwbElement;\n  Script     : IwbMainRecord;\n  Variables  : TStringList;\n  LocalVars  : IwbContainerElementRef;\n  LocalVar   : IwbContainerElementRef;\n  i, j       : Integer;\n  s          : string;\nbegin\n  case aType of\n    ctToStr: Result := IntToStr(aInt) + ' <Warning: Could not resolve Parameter 1>';\n    ctToEditValue: Result := IntToStr(aInt);\n    ctToSortKey: begin\n      Result := IntToHex64(aInt, 8);\n      Exit;\n    end;\n    ctCheck: Result := '<Warning: Could not resolve Parameter 1>';\n    ctEditType: Result := '';\n    ctEditInfo: Result := '';\n  end;\n\n  if not Assigned(aElement) then Exit;\n  Container := GetContainerRefFromUnionOrValue(aElement);\n  if not Assigned(Container) then Exit;\n\n  Param1 := Container.ElementByName['Parameter #1'];\n\n  if not Assigned(Param1) then\n    Exit;\n\n  MainRecord := nil;\n  if not Supports(Param1.LinksTo, IwbMainRecord, MainRecord) then\n    Exit;\n{    if Param1.NativeValue = 0 then\n      if Supports(Container.Container, IwbContainerElementRef, Container) then\n        for i := 0 to Pred(Container.ElementCount) do\n          if Supports(Container.Elements[i], IwbContainerElementRef, Container2) then\n            if SameText(Container2.ElementValues['Function'], 'GetIsID') then begin\n              Param1 := Container2.ElementByName['Parameter #1'];\n              if Supports(Param1.LinksTo, IwbMainRecord, MainRecord) then\n                Break;\n            end;}\n\n  if not Assigned(MainRecord) then\n    Exit;\n\n  BaseRecord := MainRecord.BaseRecord;\n  if Assigned(BaseRecord) then\n    MainRecord := BaseRecord;\n\n  ScriptRef := MainRecord.RecordBySignature['SCRI'];\n\n  if not Assigned(ScriptRef) then begin\n    case aType of\n      ctToStr: Result := IntToStr(aInt) + ' <Warning: \"'+MainRecord.ShortName+'\" does not contain a SCRI subrecord>';\n      ctCheck: Result := '<Warning: \"'+MainRecord.ShortName+'\" does not contain a SCRI subrecord>';\n    end;\n    Exit;\n  end;\n\n  if not Supports(ScriptRef.LinksTo, IwbMainRecord, Script) then begin\n    case aType of\n      ctToStr: Result := IntToStr(aInt) + ' <Warning: \"'+MainRecord.ShortName+'\" does not have a valid script>';\n      ctCheck: Result := '<Warning: \"'+MainRecord.ShortName+'\" does not have a valid script>';\n    end;\n    Exit;\n  end;\n\n  case aType of\n    ctEditType: begin\n      Result := 'ComboBox';\n      Exit;\n    end;\n    ctEditInfo:\n      Variables := TStringList.Create;\n  else\n    Variables := nil;\n  end;\n  try\n    if Supports(Script.ElementByName['Local Variables'], IwbContainerElementRef, LocalVars) then begin\n      for i := 0 to Pred(LocalVars.ElementCount) do\n        if Supports(LocalVars.Elements[i], IwbContainerElementRef, LocalVar) then begin\n          j := LocalVar.ElementNativeValues['SLSD\\Index'];\n          s := LocalVar.ElementNativeValues['SCVR'];\n          if Assigned(Variables) then\n            Variables.AddObject(s, TObject(j))\n          else if j = aInt then begin\n            case aType of\n              ctToStr, ctToEditValue: Result := s;\n              ctCheck: Result := '';\n            end;\n            Exit;\n          end;\n        end;\n    end;\n\n    case aType of\n      ctToStr: Result := IntToStr(aInt) + ' <Warning: Variable Index not found in \"' + Script.Name + '\">';\n      ctCheck: Result := '<Warning: Variable Index not found in \"' + Script.Name + '\">';\n      ctEditInfo: begin\n        Variables.Sort;\n        Result := Variables.CommaText;\n      end;\n    end;\n  finally\n    FreeAndNil(Variables);\n  end;\nend;\n\nfunction wbCTDAParam2VariableNameToInt(const aString: string; const aElement: IwbElement): Int64;\nvar\n  Container  : IwbContainerElementRef;\n  Param1     : IwbElement;\n  MainRecord : IwbMainRecord;\n  BaseRecord : IwbMainRecord;\n  ScriptRef  : IwbElement;\n  Script     : IwbMainRecord;\n  LocalVars  : IwbContainerElementRef;\n  LocalVar   : IwbContainerElementRef;\n  i, j       : Integer;\n  s          : string;\nbegin\n  Result := StrToInt64Def(aString, Low(Cardinal));\n  if Result <> Low(Cardinal) then\n    Exit;\n\n  if not Assigned(aElement) then\n    raise Exception.Create('aElement not specified');\n\n  Container := GetContainerRefFromUnionOrValue(aElement);\n\n  if not Assigned(Container) then\n    raise Exception.Create('Container not assigned');\n\n  Param1 := Container.ElementByName['Parameter #1'];\n\n  if not Assigned(Param1) then\n    raise Exception.Create('Could not find \"Parameter #1\"');\n\n  if not Supports(Param1.LinksTo, IwbMainRecord, MainRecord) then\n    raise Exception.Create('\"Parameter #1\" does not reference a valid main record');\n\n  BaseRecord := MainRecord.BaseRecord;\n  if Assigned(BaseRecord) then\n    MainRecord := BaseRecord;\n\n  ScriptRef := MainRecord.RecordBySignature['SCRI'];\n\n  if not Assigned(ScriptRef) then\n    raise Exception.Create('\"'+MainRecord.ShortName+'\" does not contain a SCRI subrecord');\n\n  if not Supports(ScriptRef.LinksTo, IwbMainRecord, Script) then\n    raise Exception.Create('\"'+MainRecord.ShortName+'\" does not have a valid script');\n\n  if Supports(Script.ElementByName['Local Variables'], IwbContainerElementRef, LocalVars) then begin\n    for i := 0 to Pred(LocalVars.ElementCount) do\n      if Supports(LocalVars.Elements[i], IwbContainerElementRef, LocalVar) then begin\n        j := LocalVar.ElementNativeValues['SLSD\\Index'];\n        s := LocalVar.ElementNativeValues['SCVR'];\n        if SameText(s, Trim(aString)) then begin\n          Result := j;\n          Exit;\n        end;\n      end;\n  end;\n\n  raise Exception.Create('Variable \"'+aString+'\" was not found in \"'+MainRecord.ShortName+'\"');\nend;\n\nfunction wbCTDAParam2QuestStageToStr(aInt: Int64; const aElement: IwbElement; aType: TwbCallbackType): string;\nvar\n  Container  : IwbContainerElementRef;\n  Param1     : IwbElement;\n  MainRecord : IwbMainRecord;\n  EditInfos  : TStringList;\n  Stages     : IwbContainerElementRef;\n  Stage      : IwbContainerElementRef;\n  i, j       : Integer;\n  s, t       : string;\nbegin\n  case aType of\n    ctToStr: Result := IntToStr(aInt) + ' <Warning: Could not resolve Parameter 1>';\n    ctToEditValue: Result := IntToStr(aInt);\n    ctToSortKey: begin\n      Result := IntToHex64(aInt, 8);\n      Exit;\n    end;\n    ctCheck: Result := '<Warning: Could not resolve Parameter 1>';\n    ctEditType: Result := '';\n    ctEditInfo: Result := '';\n  end;\n\n  if not Assigned(aElement) then Exit;\n  Container := GetContainerRefFromUnionOrValue(aElement);\n  if not Assigned(Container) then Exit;\n\n  Param1 := Container.ElementByName['Parameter #1'];\n\n  if not Assigned(Param1) then\n    Exit;\n\n  if not Supports(Param1.LinksTo, IwbMainRecord, MainRecord) then\n    Exit;\n\n  MainRecord := MainRecord.WinningOverride;\n\n  if MainRecord.Signature <> QUST then begin\n    case aType of\n      ctToStr: Result := IntToStr(aInt) + ' <Warning: \"'+MainRecord.ShortName+'\" is not a Quest record>';\n      ctCheck: Result := '<Warning: \"'+MainRecord.ShortName+'\" is not a Quest record>';\n    end;\n    Exit;\n  end;\n\n  case aType of\n    ctEditType: begin\n      Result := 'ComboBox';\n      Exit;\n    end;\n    ctEditInfo:\n      EditInfos := TStringList.Create;\n  else\n    EditInfos := nil;\n  end;\n  try\n    if Supports(MainRecord.ElementByName['Stages'], IwbContainerElementRef, Stages) then begin\n      for i := 0 to Pred(Stages.ElementCount) do\n        if Supports(Stages.Elements[i], IwbContainerElementRef, Stage) then begin\n          j := Stage.ElementNativeValues['INDX'];\n          s := Trim(Stage.ElementValues['Log Entries\\Log Entry\\CNAM']);\n          t := IntToStr(j);\n          while Length(t) < 3 do\n            t := '0' + t;\n          if s <> '' then\n            t := t + ' ' + s;\n          if Assigned(EditInfos) then\n            EditInfos.AddObject(t, TObject(j))\n          else if j = aInt then begin\n            case aType of\n              ctToStr, ctToEditValue: Result := t;\n              ctCheck: Result := '';\n            end;\n            Exit;\n          end;\n        end;\n    end;\n\n    case aType of\n      ctToStr: Result := IntToStr(aInt) + ' <Warning: Quest Stage not found in \"' + MainRecord.Name + '\">';\n      ctCheck: Result := '<Warning: Quest Stage not found in \"' + MainRecord.Name + '\">';\n      ctEditInfo: begin\n        EditInfos.Sort;\n        Result := EditInfos.CommaText;\n      end;\n    end;\n  finally\n    FreeAndNil(EditInfos);\n  end;\nend;\n\nfunction wbCTDAParam2QuestStageToInt(const aString: string; const aElement: IwbElement): Int64;\nvar\n  i    : Integer;\n  s    : string;\nbegin\n  i := 1;\n  s := Trim(aString);\n  while (i <= Length(s)) and (s[i] in ['0'..'9']) do\n    Inc(i);\n  s := Copy(s, 1, Pred(i));\n\n  Result := StrToInt(s);\nend;\n\nprocedure wbRemoveOFST(const aElement: IwbElement);\nvar\n  Container: IwbContainer;\n  rOFST: IwbRecord;\nbegin\n  if not wbRemoveOffsetData then\n    Exit;\n\n  if Supports(aElement, IwbContainer, Container) then begin\n    rOFST := Container.RecordBySignature[OFST];\n    if Assigned(rOFST) then\n      Container.RemoveElement(rOFST);\n  end;\nend;\n\nprocedure wbCELLAfterLoad(const aElement: IwbElement);\nvar\n  Container    : IwbContainerElementRef;\n//  Container2   : IwbContainerElementRef;\n  MainRecord   : IwbMainRecord;\n//  i            : Integer;\n  IsInterior   : Boolean;\n  GroupRecord  : IwbGroupRecord;\n//  Removed      : Boolean;\nbegin\n  if wbBeginInternalEdit then try\n    if not Supports(aElement, IwbContainerElementRef, Container) then\n      Exit;\n\n    if Container.ElementCount < 1 then\n      Exit;\n\n    if not Supports(aElement, IwbMainRecord, MainRecord) then\n      Exit;\n\n    if MainRecord.IsDeleted then\n      Exit;\n\n    if not Container.ElementExists['DATA'] then\n      Exit;\n\n    IsInterior := (Container.ElementNativeValues['DATA'] and 1) <> 0;\n\n    if IsInterior then\n      Container.Add('XCLL')\n    else begin\n      Container.Add('XCLC');\n      if (Container.ElementNativeValues['DATA'] and 2) = 0 then\n        if Supports(MainRecord.Container, IwbGroupRecord, GroupRecord) then\n          if GroupRecord.GroupType = 1 then\n            Container.ElementNativeValues['DATA'] :=\n              Container.ElementNativeValues['DATA'] or 2;\n    end;\n\n//    Removed := False;\n//    if Supports(Container.ElementBySignature[XCLR], IwbContainerElementRef, Container2) then begin\n//      for i:= Pred(Container2.ElementCount) downto 0 do\n//        if not Supports(Container2.Elements[i].LinksTo, IwbMainRecord, MainRecord) or (MainRecord.Signature <> 'REGN') then begin\n//          if not Removed then begin\n//            Removed := True;\n//            Container2.MarkModifiedRecursive;\n//          end;\n//          Container2.RemoveElement(i);\n//        end;\n//      if Container2.ElementCount < 1 then\n//        Container2.Remove;\n//    end;\n  finally\n    wbEndInternalEdit;\n  end;\nend;\n\nprocedure wbMGEFAfterLoad(const aElement: IwbElement);\nvar\n  Container    : IwbContainerElementRef;\n  MainRecord   : IwbMainRecord;\n  _File        : IwbFile;\nbegin\n  if wbBeginInternalEdit then try\n    if not Supports(aElement, IwbContainerElementRef, Container) then\n      Exit;\n\n    if Container.ElementCount < 1 then\n      Exit;\n\n    if not Supports(aElement, IwbMainRecord, MainRecord) then\n      Exit;\n\n    if MainRecord.IsDeleted then\n      Exit;\n\n    _File := MainRecord._File;\n\n    if not Assigned(_File) then\n      Exit;\n\n    if not SameText(_File.FileName, 'Oblivion.esm') then\n      Exit;\n\n    if SameText(MainRecord.EditorID, 'RSFI') or\n       SameText(MainRecord.EditorID, 'RSFR') or\n       SameText(MainRecord.EditorID, 'RSPA') or\n       SameText(MainRecord.EditorID, 'RSSH') then begin\n\n         Container.ElementNativeValues['DATA - Data\\Flags'] :=\n           Cardinal(Container.ElementNativeValues['DATA - Data\\Flags']) or $8;\n\n       end;\n\n    if SameText(MainRecord.EditorID, 'REAN') then begin\n\n         Container.ElementNativeValues['DATA - Data\\Flags'] :=\n           Cardinal(Container.ElementNativeValues['DATA - Data\\Flags']) and not $20000;\n\n       end;\n\n  finally\n    wbEndInternalEdit;\n  end;\nend;\n\nprocedure wbCounterEffectsAfterSet(const aElement: IwbElement; const aOldValue, aNewValue: Variant);\nbegin\n  wbCounterByPathAfterSet('DATA - Data\\Counter effect count', aElement);\nend;\n\nprocedure wbMGEFAfterSet(const aElement: IwbElement; const aOldValue, aNewValue: Variant);\nbegin\n  wbCounterContainerByPathAfterSet('DATA - Data\\Counter effect count', 'ESCE - Counter Effects', aElement);\nend;\n\nprocedure wbEFITAfterLoad(const aElement: IwbElement);\nvar\n  Container : IwbContainerElementRef;\n  Element   : IwbElement;\n  ActorValue: Variant;\n  MainRecord: IwbMainRecord;\nbegin\n  if wbBeginInternalEdit then try\n    if not Supports(aElement, IwbContainerElementRef, Container) then\n      Exit;\n    if Container.ElementCount < 1 then\n      Exit;\n\n    Element := Container.ElementByName['Magic effect name'];\n    if not Assigned(Element) then\n      Exit;\n    if not Supports(Element.LinksTo, IwbMainRecord, MainRecord) then\n      Exit;\n    if MainRecord.Signature <> 'MGEF' then\n      Exit;\n\n    if (MainRecord.ElementNativeValues['DATA - Data\\Flags'] and $01000000) = 0 then\n      Exit;\n\n    ActorValue := MainRecord.ElementNativeValues['DATA - Data\\Assoc. Item'];\n    if VarIsNull(ActorValue) or VarIsClear(ActorValue) then\n      Exit;\n    if VarCompareValue(ActorValue, Container.ElementNativeValues['Actor Value']) <> vrEqual then\n      Container.ElementNativeValues['Actor Value'] := ActorValue;\n  finally\n    wbEndInternalEdit;\n  end;\nend;\n\nprocedure wbREFRAfterLoad(const aElement: IwbElement);\nvar\n  Container: IwbContainerElementRef;\nbegin\n  if wbBeginInternalEdit then try\n    if not Supports(aElement, IwbContainerElementRef, Container) then\n      Exit;\n    if Container.ElementCount < 1 then\n      Exit;\n\n    Container.RemoveElement('XPCI');\n  finally\n    wbEndInternalEdit;\n  end;\nend;\n\nprocedure wbLIGHAfterLoad(const aElement: IwbElement);\nvar\n  Container  : IwbContainerElementRef;\n  MainRecord : IwbMainRecord;\nbegin\n  if wbBeginInternalEdit then try\n    if not Supports(aElement, IwbContainerElementRef, Container) then\n      Exit;\n\n    if Container.ElementCount < 1 then\n      Exit;\n\n    if not Supports(aElement, IwbMainRecord, MainRecord) then\n      Exit;\n\n    if MainRecord.IsDeleted then\n      Exit;\n\n    if Container.ElementExists['DATA'] then begin\n      if SameValue(Container.ElementNativeValues['DATA\\Falloff Exponent'], 0.0) then\n        Container.ElementNativeValues['DATA\\Falloff Exponent'] := 1.0;\n      if SameValue(Container.ElementNativeValues['DATA\\FOV'], 0.0) then\n        Container.ElementNativeValues['DATA\\FOV'] := 90.0;\n    end;\n  finally\n    wbEndInternalEdit;\n  end;\nend;\n\nprocedure wbLVLAfterLoad(const aElement: IwbElement);\nvar\n  Container  : IwbContainerElementRef;\n  MainRecord : IwbMainRecord;\n  Chance     : Integer;\nbegin\n  if wbBeginInternalEdit then try\n    if not Supports(aElement, IwbContainerElementRef, Container) then\n      Exit;\n\n    if Container.ElementCount < 1 then\n      Exit;\n\n    if not Supports(aElement, IwbMainRecord, MainRecord) then\n      Exit;\n\n    if MainRecord.IsDeleted then\n      Exit;\n\n    Container.RemoveElement('DATA');\n\n    Chance := Container.ElementNativeValues['LVLD'];\n    if (Chance and $80) <> 0 then begin\n      Chance := Chance and not $80;\n      Container.ElementNativeValues['LVLD'] := Chance;\n      Container.ElementNativeValues['LVLF'] := Container.ElementNativeValues['LVLF'] or $01;\n    end;\n  finally\n    wbEndInternalEdit;\n  end;\nend;\n\nprocedure wbRPLDAfterLoad(const aElement: IwbElement);\nvar\n  Container : IwbContainer;\n  a, b      : Single;\n  NeedsFlip : Boolean;\nbegin\n  if wbBeginInternalEdit then try\n    if not Supports(aElement, IwbContainer, Container) then\n      Exit;\n\n    NeedsFlip := False;\n    if Container.ElementCount > 1 then begin\n      a := (Container.Elements[0] as IwbContainer).Elements[0].NativeValue;\n      b := (Container.Elements[Pred(Container.ElementCount)] as IwbContainer).Elements[0].NativeValue;\n      case CompareValue(a, b) of\n        EqualsValue: begin\n          a := (Container.Elements[0] as IwbContainer).Elements[1].NativeValue;\n          b := (Container.Elements[Pred(Container.ElementCount)] as IwbContainer).Elements[1].NativeValue;\n          NeedsFlip := CompareValue(a, b) = GreaterThanValue;\n        end;\n        GreaterThanValue:\n          NeedsFlip := True;\n      end;\n    end;\n    if NeedsFlip then\n      Container.ReverseElements;\n  finally\n    wbEndInternalEdit;\n  end;\nend;\n\nprocedure wbPGRDAfterLoad(const aElement: IwbElement);\nvar\n  Container   : IwbContainerElementRef;\n  MainRecord  : IwbMainRecord;\n  Points      : IwbContainerElementRef;\n  Connections : IwbContainerElementRef;\n  i, j        : Integer;\n  Point       : IwbContainerElementRef;\n  Connection  : IwbContainerElementRef;\n  Removed     : Boolean;\n  FirstRemoved: Boolean;\nbegin\n  if wbBeginInternalEdit then try\n    if not Supports(aElement, IwbContainerElementRef, Container) then\n      Exit;\n\n    if Container.ElementCount < 1 then\n      Exit;\n\n    if not Supports(aElement, IwbMainRecord, MainRecord) then\n      Exit;\n\n    if MainRecord.IsDeleted then\n      Exit;\n\n    if not Supports(Container.ElementBySignature['PGRP'], IwbContainerElementRef, Points) then\n      Exit;\n\n    if not Container.ElementExists['PGAG'] then\n      Container.Add('PGAG').DataSize := (Points.ElementCount + 7) div 8;\n\n    MainRecord.IsCompressed := True;\n\n    if not Supports(Container.ElementBySignature['PGRR'], IwbContainerElementRef, Connections) then\n      Exit;\n\n    if Points.ElementCount < Connections.ElementCount then\n      Exit;\n\n    FirstRemoved := False;\n    for i := Pred(Connections.ElementCount) downto 0 do begin\n      Connection := Connections.Elements[i] as IwbContainerElementRef;\n\n      Removed := False;\n      j := Connection.ElementCount;\n      while j > 0 do begin\n        Dec(j);\n        if Connection.Elements[j].NativeValue = 65535 then begin\n          if not FirstRemoved then begin\n            FirstRemoved := True;\n            Connections.MarkModifiedRecursive;\n          end;\n          Connection.Elements[j].Remove;\n          Removed := True;\n        end else\n          Break;\n      end;\n\n      if Removed then begin\n        Point := Points.Elements[i] as IwbContainerElementRef;\n        Point.ElementNativeValues['Connections'] := Connection.ElementCount;\n      end;\n\n    end;\n\n  finally\n    wbEndInternalEdit;\n  end;\nend;\n\nprocedure wbPGRRPointAfterLoad(const aElement: IwbElement);\nvar\n  Connections : IwbContainerElementRef;\n  i           : Integer;\n//  Index       : Integer;\nbegin\n  if wbBeginInternalEdit then try\n    if not Supports(aElement, IwbContainerElementRef, Connections) then\n      Exit;\n    for i := Pred(Connections.ElementCount) downto 0 do\n      if Connections.Elements[i].NativeValue = 65535 then begin\n        Connections.RemoveElement(i);\n      end;\n{    if Removed then begin\n      Index := aElement.Container.ElementCount;\n      (aElement.ContainingMainRecord.RecordBySignature['PGRP'].Elements[Index] as IwbContainer).Elements[3].NativeValue := Connections.ElementCount;\n    end;}\n  finally\n    wbEndInternalEdit;\n  end;\nend;\n\nprocedure wbPGRIPointerAfterLoad(const aElement: IwbElement);\nvar\n  Connections : IwbContainerElementRef;\n  i, j        : Integer;\n  s           : string;\n  Keys        : TStringList;\nbegin\n  if wbBeginInternalEdit then try\n    if not Supports(aElement, IwbContainerElementRef, Connections) then\n      Exit;\n\n    Keys := TStringList.Create;\n    try\n      Keys.Sorted := True;\n      Keys.Duplicates := dupError;\n      for i := Pred(Connections.ElementCount) downto 0 do begin\n        s := Connections.Elements[i].SortKey[True];\n        if Keys.Find(s, j) then\n          Connections.RemoveElement(i, True)\n        else\n          Keys.Add(s);\n      end;\n    finally\n      Keys.Free;\n    end;\n  finally\n    wbEndInternalEdit;\n  end;\nend;\n\n{\nfunction wbPGRPConnectionsCallback(aInt: Int64; const aElement: IwbElement; aType: TwbCallbackType): string;\nvar\n  Point : IwbContainerElementRef;\n  s     : string;\n  i     : Integer;\n  PGRP  : IwbContainerElementRef;\n  PGRD  : IwbMainRecord;\n  PGRR  : IwbContainerElementRef;\n  Cons  : IwbContainerElementRef;\nbegin\n  Result := '';\n  if aType = ctCheck then\n    Exit;\n\n  if wbFixupPGRD and (aInt > 0) and Assigned(aElement) and (aElement.ElementStates * [esModified] = []) then begin\n    Point := aElement.Container as IwbContainerElementRef;\n    if Assigned(Point) then begin\n      s := Trim(Point.Name);\n      i := Pos('#', s);\n      if i > 0 then begin\n        i := StrToIntDef(Copy(s, i+1, High(Integer)), -1);\n        if i >= 0 then begin\n          PGRP := Point.Container as IwbContainerElementRef;\n          if Assigned(PGRP) then begin\n            if Supports(PGRP.Container, IwbMainRecord, PGRD) then begin\n              if (csInitDone in PGRD.ContainerStates) and (PGRD.Signature = 'PGRD') then begin\n                PGRR := PGRD.RecordBySignature['PGRR'] as IwbContainerElementRef;\n                if Assigned(PGRR) and (PGRR.ElementCount > 0) and (csInitDone in PGRR.ContainerStates) then begin\n                  if (i < PGRR.ElementCount) then begin\n                    if Supports(PGRR.Elements[i], IwbContainer, Cons) then begin\n                      aInt := Cons.ElementCount;\n                    end;\n                  end;\n                end;\n                PGRR := nil;\n              end;\n            end;\n          end;\n        end;\n      end;\n    end;\n  end;\n\n  if aType = ctToSortKey then\n    Result := IntToHex64(aInt, 2)\n  else if aType = ctToStr then\n    Result := IntToStr(aInt);\nend;\n}\n\nfunction wbPxDTLocationDecider(aBasePtr: Pointer; aEndPtr: Pointer; const aElement: IwbElement): Integer;\nvar\n  Container: IwbContainer;\nbegin\n  Result := 0;\n  if not Assigned(aElement) then Exit;\n  Container := GetContainerFromUnion(aElement);\n  if not Assigned(Container) then Exit;\n\n  Result := Container.ElementByName['Type'].NativeValue;\nend;\n\nfunction wbCalcPGRRSize(aBasePtr: Pointer; aEndPtr: Pointer; const aElement: IwbElement): Cardinal;\nvar\n  Index: Integer;\n\n  function ExtractCountFromLabel(const aElement: IwbElement; aCount: Integer): Integer;\n  var\n    i: Integer;\n  begin\n    i := Pos('#', aElement.Name);\n    if i = 0 then\n      Result := aCount\n    else try\n      Result := StrToInt(Trim(Copy(aElement.Name, i+1, Length(aElement.Name))))+1;\n    except\n      Result := aCount;\n    end;\n\n  end;\n\nbegin\n  Index := ExtractCountFromLabel(aElement, aElement.Container.ElementCount);\n  Result := ((aElement.Container.Container as IwbMainRecord).RecordBySignature['PGRP'].Elements[Pred(Index)] as IwbContainer).Elements[3].NativeValue;\nend;\n\nfunction wbMGEFFAssocItemDecider(aBasePtr: Pointer; aEndPtr: Pointer; const aElement: IwbElement): Integer;\nvar\n  s: string;\n  Container: IwbContainer;\nbegin\n  Result := 0;\n  if not Assigned(aElement) then Exit;\n  Container := GetContainerFromUnion(aElement);\n  if not Assigned(Container) then Exit;\n\n  s := Container.ElementByName['Flags'].SortKey[False];\n  if s[17] = '1' then\n    Result := 1\n  else if s[18] = '1' then\n    Result := 2\n  else if s[19] = '1' then\n    Result := 3\n  else if s[25] = '1' then\n    Result := 4;\nend;\n\nfunction wbEDDXDontShow(const aElement: IwbElement): Boolean;\nvar\n  MainRecord : IwbMainRecord;\nbegin\n  Result := True;\n\n  if Supports(aElement.Container, IwbMainRecord, MainRecord) then\n    Result := not Assigned(MainRecord.ElementBySignature[OBME]);\nend;\n\nfunction wbOBMEDontShow(const aElement: IwbElement): Boolean;\nvar\n  _File: IwbFile;\nbegin\n  if not Assigned(aElement) then begin\n    Result := True;\n    Exit;\n  end;\n\n  Result := False;\n\n  _File := aElement._File;\n  if Assigned(_File) and SameText(_File.FileName, 'Oblivion.esm') then\n    Result := True;\nend;\n\nfunction wbOffsetDataColsCounter(aBasePtr: Pointer; aEndPtr: Pointer; const aElement: IwbElement): Cardinal;\nvar\n  Container : IwbDataContainer;\n  Element   : IwbElement;\n  fResult   : Extended;\nbegin\n  Result := 0;\n\n  if Supports(aElement.Container, IwbDataContainer, Container) and (Container.Name = 'OFST - Offset Data') and\n     Supports(Container.Container, IwbDataContainer, Container) then begin\n    Element := Container.ElementByPath['Object Bounds\\NAM0 - Min\\X'];\n    if Assigned(Element) then begin\n      fResult :=  Element.NativeValue;\n      if fResult >= MaxInt then\n        Result := 0\n      else\n        Result := Trunc(fResult);\n      Element := Container.ElementByPath['Object Bounds\\NAM9 - Max\\X'];\n      if Assigned(Element) then begin\n        fResult :=  Element.NativeValue;\n        if fResult >= MaxInt then\n          Result := 1\n        else\n          Result := Trunc(fResult) - Result + 1;\n      end;\n    end;\n  end;\nend;\n\nprocedure DefineTES4;\nbegin\n  wbRecordFlags := wbInteger('Record Flags', itU32, wbFlags([\n    {0x00000001}'ESM',\n    {0x00000002}'',\n    {0x00000004}'',\n    {0x00000008}'',\n    {0x00000010}'',\n    {0x00000020}'Deleted',\n    {0x00000040}'Border Region / Actor Value',\n    {0x00000080}'Turn Off Fire / Actor Value',\n    {0x00000100}'',\n    {0x00000200}'Casts shadows',\n    {0x00000400}'Quest item / Persistent reference / Show in Menu',\n    {0x00000800}'Initially disabled',\n    {0x00001000}'Ignored',\n    {0x00002000}'',\n    {0x00004000}'',\n    {0x00008000}'Visible when distant',\n    {0x00010000}'',\n    {0x00020000}'Dangerous / Off limits (Interior cell)',\n    {0x00040000}'Compressed ',\n    {0x00080000}'Can''t wait'\n  ]));\n\n  wbMainRecordHeader := wbStruct('Record Header', [\n    wbString('Signature', 4, cpCritical),\n    wbInteger('Data Size', itU32, nil, cpIgnore),\n    wbRecordFlags,\n    wbFormID('FormID', cpFormID),\n    wbByteArray('Unknown', 4, cpIgnore)\n  ]);\n\n  wbSizeOfMainRecordStruct := 20;\n\n  wbIgnoreRecords.Add(XXXX);\n\n  wbXRGD := wbByteArray(XRGD, 'Ragdoll Data');\n\n  wbMusicEnum := wbEnum(['Default', 'Public', 'Dungeon']);\n\n  wbEDID := wbString(EDID, 'Editor ID', 0, cpNormal); // not cpBenign according to Arthmoor\n  wbFULL := wbStringKC(FULL, 'Name', 0, cpTranslate);\n  wbFULLReq := wbStringKC(FULL, 'Name', 0, cpNormal, True);\n  wbDESC := wbStringKC(DESC, 'Description', 0, cpTranslate);\n  wbXSCL := wbFloat(XSCL, 'Scale');\n\n  wbPosRot :=\n    wbStruct('Position/Rotation', [\n      wbStruct('Position', [\n        wbFloat('X'),\n        wbFloat('Y'),\n        wbFloat('Z')\n      ]),\n      wbStruct('Rotation', [\n        wbFloat('X', cpNormal, True, wbRotationFactor, wbRotationScale, nil, RadiansNormalize),\n        wbFloat('Y', cpNormal, True, wbRotationFactor, wbRotationScale, nil, RadiansNormalize),\n        wbFloat('Z', cpNormal, True, wbRotationFactor, wbRotationScale, nil, RadiansNormalize)\n      ])\n    ]);\n\n  wbDATAPosRot :=\n    wbStruct(DATA, 'Position/Rotation', [\n      wbStruct('Position', [\n        wbFloat('X'),\n        wbFloat('Y'),\n        wbFloat('Z')\n      ]),\n      wbStruct('Rotation', [\n        wbFloat('X', cpNormal, True, wbRotationFactor, wbRotationScale, nil, RadiansNormalize),\n        wbFloat('Y', cpNormal, True, wbRotationFactor, wbRotationScale, nil, RadiansNormalize),\n        wbFloat('Z', cpNormal, True, wbRotationFactor, wbRotationScale, nil, RadiansNormalize)\n      ])\n    ], cpNormal, True);\n\n  wbMODL :=\n    wbRStructSK([0], 'Model', [\n      wbString(MODL, 'Model Filename'),\n      wbFloat(MODB, 'Bound Radius', cpBenign),\n      wbByteArray(MODT, 'Texture Files Hashes', 0, cpIgnore)\n//      wbArray(MODT, 'Unknown',\n//        wbByteArray('Unknown', 24, cpBenign),\n//      0, nil, cpBenign)\n    ], []);\n\n  wbSCRI := wbFormIDCk(SCRI, 'Script', [SCPT]);\n  wbENAM := wbFormIDCk(ENAM, 'Enchantment', [ENCH]);\n\n  wbXLOD := wbArray(XLOD, 'Distant LOD Data', wbFloat('Unknown'), 3);\n  wbXESP := wbStruct(XESP, 'Enable Parent', [\n    wbFormIDCk('Reference', [PLYR, REFR, ACRE, ACHR]),\n    wbInteger('Flags', itU8, wbFlags([\n      'Set Enable State to Opposite of Parent'\n    ])),\n    wbByteArray('Unused', 3)\n  ]);\n\n  wbRecord(ACHR, 'Placed NPC', [\n    wbEDID,\n    wbFormIDCk(NAME, 'Base', [NPC_], False, cpNormal, True),\n    wbRStruct('Unused', [\n      wbFormIDCk(XPCI, 'Unused', [CELL]),\n      wbString(FULL, 'Unused')\n    ], []),\n    wbXLOD,\n    wbXESP,\n    wbFormIDCk(XMRC, 'Merchant container', [REFR], True),\n    wbFormIDCk(XHRS, 'Horse', [ACRE], True),\n    wbXRGD,\n    wbXSCL,\n    wbDATAPosRot\n  ], True, wbPlacedAddInfo, cpNormal, False, wbREFRAfterLoad);\n\n  wbXOWN := wbFormIDCk(XOWN, 'Owner', [FACT, NPC_]);\n  wbXGLB := wbFormIDCk(XGLB, 'Global variable', [GLOB]);\n\n  wbRecord(ACRE, 'Placed Creature', [\n    wbEDID,\n    wbFormIDCk(NAME, 'Base', [CREA], False, cpNormal, True),\n    wbRStruct('Ownership', [\n      wbXOWN,\n      wbInteger(XRNK, 'Faction rank', itS32),\n      wbXGLB\n    ], []),\n    wbXESP,\n    wbXRGD,\n    wbXSCL,\n    wbDATAPosRot\n  ], True, wbPlacedAddInfo);\n\n  wbRecord(ACTI, 'Activator', [\n    wbEDID,\n    wbFULL,\n    wbMODL,\n    wbSCRI,\n    wbFormIDCk(SNAM, 'Sound', [SOUN])\n  ]);\n\n  wbICON := wbString(ICON, 'Icon filename');\n\n  wbActorValueEnum :=\n    wbEnum([\n      'Strength',\n      'Intelligence',\n      'Willpower',\n      'Agility',\n      'Speed',\n      'Endurance',\n      'Personality',\n      'Luck',\n      'Health',\n      'Magicka',\n      'Fatigue',\n      'Encumbrance',\n      'Armorer',\n      'Athletics',\n      'Blade',\n      'Block',\n      'Blunt',\n      'Hand To Hand',\n      'Heavy Armor',\n      'Alchemy',\n      'Alteration',\n      'Conjuration',\n      'Destruction',\n      'Illusion',\n      'Mysticism',\n      'Restoration',\n      'Acrobatics',\n      'Light Armor',\n      'Marksman',\n      'Mercantile',\n      'Security',\n      'Sneak',\n      'Speechcraft',\n {33} 'Aggression',\n {34} 'Confidence',\n {35} 'Energy',\n {36} 'Responsibility',\n {37} 'Bounty',\n {38} 'Fame',\n {39} 'Infamy',\n {40} 'Magicka Multiplier',\n {41} 'Night Eye Bonus',\n {42} 'Attack Bonus',\n {43} 'Defend Bonus',\n {44} 'Casting Penalty',\n {45} 'Blindness',\n {46} 'Chameleon',\n {47} 'Invisibility',\n {48} 'Paralysis',\n {49} 'Silence',\n {50} 'Confusion',\n {51} 'Detect Item Range',\n {52} 'Spell Absorb Chance',\n {53} 'Spell Reflect Chance',\n {54} 'Swim Speed Multiplier',\n {55} 'Water Breathing',\n {56} 'Water Walking',\n {57} 'Stunted Magicka',\n {58} 'Detect Life Range',\n {59} 'Reflect Damage',\n {60} 'Telekinesis',\n {61} 'Resist Fire',\n {62} 'Resist Frost',\n {63} 'Resist Disease',\n {64} 'Resist Magic',\n {65} 'Resist Normal Weapons',\n {66} 'Resist Paralysis',\n {67} 'Resist Poison',\n {68} 'Resist Shock',\n {69} 'Vampirism',\n {70} 'Darkness',\n {71} 'Resist Water Damage'\n    ], [\n      -1, 'None'\n    ]);\n\n  wbSkillEnum :=\n    wbEnum([\n      'Armorer',\n      'Athletics',\n      'Blade',\n      'Block',\n      'Blunt',\n      'Hand To Hand',\n      'Heavy Armor',\n      'Alchemy',\n      'Alteration',\n      'Conjuration',\n      'Destruction',\n      'Illusion',\n      'Mysticism',\n      'Restoration',\n      'Acrobatics',\n      'Light Armor',\n      'Marksman',\n      'Mercantile',\n      'Security',\n      'Sneak',\n      'Speechcraft'\n    ], [\n      -1, 'None'\n    ]);\n\n\n  wbEFID := wbInteger(EFID, 'Magic effect name', itU32, wbChar4, cpNormal, True);\n\n  wbEFIDOBME := wbStringMgefCode(EFID, 'Magic Effect Code', 4, cpNormal, True);\n\n  wbEFIT :=\n    wbStructSK(EFIT, [4, 5], '', [\n      wbInteger('Magic effect name', itU32, wbChar4),\n      wbInteger('Magnitude', itU32),\n      wbInteger('Area', itU32),\n      wbInteger('Duration', itU32),\n      wbInteger('Type', itU32, wbEnum(['Self', 'Touch', 'Target'])),\n      wbInteger('Actor Value', itS32, wbActorValueEnum)\n    ], cpNormal, True, nil, -1, wbEFITAfterLoad);\n\n  wbEFITOBME :=\n    wbStructSK(EFIT, [4, 5], '', [\n      wbStringMgefCode('Magic Effect Code', 4),\n      wbInteger('Magnitude', itU32),\n      wbInteger('Area', itU32),\n      wbInteger('Duration', itU32),\n      wbInteger('Type', itU32, wbEnum(['Self', 'Touch', 'Target'])),\n      wbUnion('Param #1', wbEFITOBMEParamDecider, [\n        wbByteArray('Param #1 - Unknown Type', 4),\n        wbFormID('Param #1 - FormID'),\n        wbStringMgefCode('Param #1 - Magic Effect Code', 4),\n        wbFormIDCk('Param #1 - Actor Value', [ACVA])\n      ])\n    ], cpNormal, True, nil, -1{, wbEFITAfterLoad});\n\n  wbEFIX :=\n    wbStructSK(EFIX, [3], '', [\n      wbInteger('Override Mask', itU32, wbFlags([])),\n      wbInteger('Flags', itU32, wbFlags([])),\n      wbFloat('Base Cost'),\n      wbUnion('Param #2', wbEFIXParamDecider, [\n        wbByteArray('Param #2 - Unknown Type', 4),\n        wbFormID('Param #2 - FormID'),\n        wbStringMgefCode('Param #2 - Magic Effect Code', 4),\n        wbFormIDCk('Param #2 - Actor Value', [ACVA])\n      ])\n    ], cpNormal, True, nil, -1, wbEFITAfterLoad);\n\n  wbMagicSchoolEnum :=\n    wbEnum([\n      'Alteration',\n      'Conjuration',\n      'Destruction',\n      'Illusion',\n      'Mysticism',\n      'Restoration'\n    ]);\n\n  wbSCIT :=\n    wbRStructSK([0], 'Script effect', [\n      wbStructSK(SCIT, [0], 'Script effect data', [\n        wbFormIDCk('Script effect', [NULL, SCPT]),\n        wbInteger('Magic school', itU32, wbMagicSchoolEnum),\n        wbInteger('Visual effect name', itU32, wbChar4),\n        wbInteger('Flags', itU8, wbFlags(['Hostile'])),\n        wbByteArray('Unused', 3)\n      ], cpNormal, True, nil, 1),\n      wbFULLReq\n    ], []);\n\n  wbSCITOBME :=\n    wbRStructSK([0], 'Script effect', [\n      wbStructSK(SCIT, [0], 'Script effect data', [\n        wbFormIDCk('Script effect', [NULL, SCPT]),\n        wbInteger('Magic school', itU32, wbMagicSchoolEnum),\n        wbStringMgefCode('Visual Effect Code', 4),\n        wbInteger('Flags', itU8, wbFlags(['Hostile'])),\n        wbByteArray('Unused', 3)\n      ], cpNormal, True, nil, 1),\n      wbFULLReq\n    ], []);\n\n\n  wbOBMEResolutionInfo := wbEnum(['None', 'FormID', 'Magic Effect Code', 'Actor Value']);\n\n  wbEffects := wbRArray('Effects',\n    wbRUnion('Effects', [\n      wbRStruct('Effect', [\n        wbEFID,\n        wbEFIT,\n        wbSCIT\n      ], []),\n      wbRStruct('Effects', [\n        wbRStructs('Effects','Effect', [\n          wbStruct(EFME, 'Oblivion Magic Extender', [\n            wbInteger('Record Version', itU8),\n            wbStruct('OBME Version', [\n              wbInteger('Beta', itU8),\n              wbInteger('Minor', itU8),\n              wbInteger('Major', itU8)\n            ]),\n            wbInteger('EFIT Param Info', itU8, wbOBMEResolutionInfo),\n            wbInteger('EFIX Param Info', itU8, wbOBMEResolutionInfo),\n            wbByteArray('Unused', $0A)\n          ]),\n          wbEFIDOBME,\n          wbEFITOBME,\n          wbSCITOBME,\n          wbString(EFII, 'Icon'),\n          wbEFIX\n        ], []),\n        wbEmpty(EFXX, 'Effects End Marker', cpNormal, True),\n        wbFULLReq\n      ], [])\n    ], [])\n  );\n\n//  wbEffects :=\n//    wbRUnion('Effects', [\n//      wbRStruct('Effects', [\n//        wbRStructs('Effects','Effect', [\n//          wbEFID,\n//          wbEFIT,\n//          wbSCIT\n//        ], [])\n//      ], []),\n//      wbRStruct('Effects', [\n//        wbRStructs('Effects','Effect', [\n//          wbStruct(EFME, 'Oblivion Magic Extender', [\n//            wbInteger('Record Version', itU8),\n//            wbStruct('OBME Version', [\n//              wbInteger('Beta', itU8),\n//              wbInteger('Minor', itU8),\n//              wbInteger('Major', itU8)\n//            ]),\n//            wbInteger('EFIT Param Info', itU8, wbOBMEResolutionInfo),\n//            wbInteger('EFIX Param Info', itU8, wbOBMEResolutionInfo),\n//            wbByteArray('Unused', $0A)\n//          ]),\n//          wbEFIDOBME,\n//          wbEFITOBME,\n//          wbSCITOBME,\n//          wbString(EFII, 'Icon'),\n//          wbEFIX\n//        ], []),\n//        wbEmpty(EFXX, 'Effects End Marker', cpNormal, True),\n//        wbFULLReq\n//      ], [])\n//    ], []);\n\n  wbRecord(ALCH, 'Potion', [\n    wbEDID,\n    wbStruct(OBME, 'Oblivion Magic Extender', [\n      wbInteger('Record Version', itU8),\n      wbStruct('OBME Version', [\n        wbInteger('Beta', itU8),\n        wbInteger('Minor', itU8),\n        wbInteger('Major', itU8)\n      ]),\n      wbByteArray('Unused', $1C)\n    ], cpNormal, False, wbOBMEDontShow),\n    wbFULL,\n    wbMODL,\n    wbICON,\n    wbSCRI,\n    wbFloat(DATA, 'Weight', cpNormal, True),\n    wbStruct(ENIT, '', [\n      wbInteger('Value', itS32),\n      wbInteger('Flags', itU8, wbFlags(['No auto-calculation', 'Food item'])),\n      wbByteArray('Unused', 3)\n    ], cpNormal, True),\n    wbEffects\n  ]);\n\n  wbRecord(AMMO, 'Ammunition', [\n    wbEDID,\n    wbFULL,\n    wbMODL,\n    wbICON,\n    wbFormIDCk(ENAM, 'Enchantment', [ENCH]),\n    wbInteger(ANAM, 'Enchantment Points', itU16),\n    wbStruct(DATA, '', [\n      wbFloat('Speed'),\n      wbInteger('Flags', itU8, wbFlags(['Ignores Normal Weapon Resistance'])),\n      wbByteArray('Unused', 3),\n      wbInteger('Value', itU32),\n      wbFloat('Weight'),\n      wbInteger('Damage', itU16)\n    ], cpNormal, True)\n  ]);\n\n  wbRecord(ANIO, 'Animated Object', [\n    wbEDID,\n    wbMODL,\n    wbFormIDCk(DATA, 'IDLE animation', [IDLE], False, cpNormal, True)\n  ]);\n\n  wbRecord(APPA, 'Alchemical Apparatus', [\n    wbEDID,\n    wbFULL,\n    wbMODL,\n    wbICON,\n    wbSCRI,\n    wbStruct(DATA, '', [\n      wbInteger('Type', itU8, wbEnum(['Mortar and Pestle', 'Alembic', 'Calcinator', 'Retort'])),\n      wbInteger('Value', itU32),\n      wbFloat('Weight'),\n      wbFloat('Quality')\n    ], cpNormal, True)\n  ]);\n\n  wbRecord(ARMO, 'Armor', [\n    wbEDID,\n    wbFULL,\n    wbSCRI,\n    wbENAM,\n    wbInteger(ANAM, 'Enchantment Points', itU16),\n    wbStruct(BMDT, '', [\n      wbInteger('Biped Flags', itU16, wbFlags([\n        {0x00000001} 'Head',\n        {0x00000002} 'Hair',\n        {0x00000004} 'Upper Body',\n        {0x00000008} 'Lower Body',\n        {0x00000010} 'Hand',\n        {0x00000020} 'Foot',\n        {0x00000040} 'Right Ring',\n        {0x00000080} 'Left Ring',\n        {0x00000100} 'Amulet',\n        {0x00000200} 'Weapon',\n        {0x00000400} 'Back Weapon',\n        {0x00000800} 'Side Weapon',\n        {0x00001000} 'Quiver',\n        {0x00002000} 'Shield',\n        {0x00004000} 'Torch',\n        {0x00008000} 'Tail'\n      ])),\n      wbInteger('General Flags', itU8, wbFlags([\n        {0x0001} 'Hide Rings',\n        {0x0002} 'Hide Amulets',\n        {0x0004} '',\n        {0x0008} '',\n        {0x0010} '',\n        {0x0020} '',\n        {0x0040} 'Non-Playable',\n        {0x0080} 'Heavy armor'\n      ])),\n      wbByteArray('Unused', 1)\n    ], cpNormal, True),\n    wbRStruct('Male biped model', [\n      wbString(MODL, 'Model Filename'),\n      wbFloat(MODB, 'Bound Radius', cpBenign),\n      wbByteArray(MODT, 'Texture Files Hashes', 0, cpIgnore)\n    ], []),\n    wbRStruct('Male world model', [\n      wbString(MOD2, 'Model Filename'),\n      wbFloat(MO2B, 'Bound Radius', cpBenign),\n      wbByteArray(MO2T, 'Texture Files Hashes', 0, cpIgnore)\n    ], []),\n    wbString(ICON, 'Male icon filename'),\n    wbRStruct('Female biped model', [\n      wbString(MOD3, 'Model Filename'),\n      wbFloat(MO3B, 'Bound Radius', cpBenign),\n      wbByteArray(MO3T, 'Texture Files Hashes', 0, cpIgnore)\n    ], []),\n    wbRStruct('Female world model', [\n      wbString(MOD4, 'Model Filename'),\n      wbFloat(MO4B, 'Bound Radius', cpBenign),\n      wbByteArray(MO4T, 'Texture Files Hashes', 0, cpIgnore)\n    ], []),\n    wbString(ICO2, 'Female icon filename'),\n    wbStruct(DATA, '', [\n      wbInteger('Armor', itU16, wbDiv(100)),\n      wbInteger('Value', itU32),\n      wbInteger('Health', itU32),\n      wbFloat('Weight')\n    ], cpNormal, True)\n  ]);\n\n  wbRecord(BOOK, 'Book', [\n    wbEDID,\n    wbFULL,\n    wbMODL,\n    wbICON,\n    wbSCRI,\n    wbENAM,\n    wbInteger(ANAM, 'Enchantment Points', itU16),\n    wbDESC,\n    wbStruct(DATA, '', [\n      wbInteger('Flags', itU8, wbFlags(['Scroll', 'Can''t be taken'])),\n      wbInteger('Teaches', itS8, wbSkillEnum),\n      wbInteger('Value', itU32),\n      wbFloat('Weight')\n    ], cpNormal, True)\n  ], True);\n\n  wbSPLO := wbFormIDCk(SPLO, 'Spell', [SPEL, LVSP]);\n  wbSPLOs := wbRArrayS('Spells', wbSPLO);\n\n  wbRecord(BSGN, 'Birthsign', [\n    wbEDID,\n    wbFULL,\n    wbICON,\n    wbDESC,\n    wbSPLOs\n  ]);\n\n  wbRecord(CELL, 'Cell', [\n    wbEDID,\n    wbFULL,\n    wbInteger(DATA, 'Flags', itU8, wbFlags([\n      {0x01} 'Is Interior Cell',\n      {0x02} 'Has water',\n      {0x04} 'Invert Fast Travel behavior',\n      {0x08} 'Force hide land (exterior cell) / Oblivion interior (interior cell)',\n      {0x10} '',\n      {0x20} 'Public place',\n      {0x40} 'Hand changed',\n      {0x80} 'Behave like exterior'\n    ]), cpNormal, True),\n    wbStruct(XCLC, 'Grid', [\n      wbInteger('X', itS32),\n      wbInteger('Y', itS32)\n    ]),\n    wbStruct(XCLL, 'Lighting', [\n      wbStruct('Ambient Color', [\n        wbInteger('Red', itU8),\n        wbInteger('Green', itU8),\n        wbInteger('Blue', itU8),\n        wbByteArray('Unused', 1)\n      ]),\n      wbStruct('Directional Color', [\n        wbInteger('Red', itU8),\n        wbInteger('Green', itU8),\n        wbInteger('Blue', itU8),\n        wbByteArray('Unused', 1)\n      ]),\n      wbStruct('Fog Color', [\n        wbInteger('Red', itU8),\n        wbInteger('Green', itU8),\n        wbInteger('Blue', itU8),\n        wbByteArray('Unused', 1)\n      ]),\n      wbFloat('Fog Near'),\n      wbFloat('Fog Far'),\n      wbInteger('Directional Rotation XY', itS32),\n      wbInteger('Directional Rotation Z', itS32),\n      wbFloat('Directional Fade', cpNormal, False, 1, -1, nil, nil, 1.0),\n      wbFloat('Fog Clip Dist')\n    ]),\n    wbArrayS(XCLR, 'Regions', wbFormIDCk('Region', [REGN])),\n    wbInteger(XCMT, 'Music', itU8, wbMusicEnum),\n    wbFloat(XCLW, 'Water Height', cpBenign),\n    wbFormIDCk(XCCM, 'Climate', [CLMT]),\n    wbFormIDCk(XCWT, 'Water', [WATR]),\n    wbRStruct('Ownership', [\n      wbXOWN,\n      wbInteger(XRNK, 'Faction rank', itS32),\n      wbXGLB\n    ], [XCLW, XCMT, XCCM])\n  ], True, wbCellAddInfo, cpNormal, False, wbCELLAfterLoad);\n\n  wbServiceFlags :=\n    wbFlags([\n      {0x00000001} 'Weapons',\n      {0x00000002} 'Armor',\n      {0x00000004} 'Clothing',\n      {0x00000008} 'Books',\n      {0x00000010} 'Ingredients',\n      {0x00000020} '',\n      {0x00000040} '',\n      {0x00000080} 'Lights',\n      {0x00000100} 'Apparatus',\n      {0x00000200} '',\n      {0x00000400} 'Miscellaneous',\n      {0x00000800} 'Spells',\n      {0x00001000} 'Magic Items',\n      {0x00002000} 'Potions',\n      {0x00004000} 'Training',\n      {0x00008000} '',\n      {0x00010000} 'Recharge',\n      {0x00020000} 'Repair'\n    ]);\n\n  wbSpecializationEnum := wbEnum(['Combat', 'Magic', 'Stealth']);\n\n  wbRecord(CLAS, 'Class', [\n    wbEDID,\n    wbFULL,\n    wbDESC,\n    wbICON,\n    wbStruct(DATA, '', [\n      wbArrayS('Primary Attributes', wbInteger('Primary Attribute', itS32, wbActorValueEnum), 2),\n      wbInteger('Specialization', itU32, wbSpecializationEnum),\n      wbArrayS('Major Skills', wbInteger('Major Skill', itS32, wbActorValueEnum), 7),\n      wbInteger('Flags', itU32, wbFlags(['Playable', 'Guard'])),\n      wbInteger('Buys/Sells and Services', itU32, wbServiceFlags),\n      wbInteger('Teaches', itS8, wbSkillEnum),\n      wbInteger('Maximum training level', itU8),\n      wbInteger('Unused', itU16)\n    ], cpNormal, True, nil, 5)\n  ]);\n\n  wbRecord(CLMT, 'Climate', [\n    wbEDID,\n    wbArrayS(WLST, 'Weather Types', wbStructSK([0], 'Weather Type', [\n      wbFormIDCk('Weather', [WTHR]),\n      wbInteger('Chance', itS32)\n    ])),\n    wbString(FNAM, 'Sun Texture'),\n    wbString(GNAM, 'Sun Glare Texture'),\n    wbMODL,\n    wbStruct(TNAM, 'Timing', [\n      wbStruct('Sunrise', [\n        wbInteger('Begin', itU8, wbClmtTime),\n        wbInteger('End', itU8, wbClmtTime)\n      ]),\n      wbStruct('Sunset', [\n        wbInteger('Begin', itU8, wbClmtTime),\n        wbInteger('End', itU8, wbClmtTime)\n      ]),\n      wbInteger('Volatility', itU8),\n      wbInteger('Moons / Phase Length', itU8, wbClmtMoonsPhaseLength)\n    ], cpNormal, True)\n  ]);\n\n  wbRecord(CLOT, 'Clothing', [\n    wbEDID,\n    wbFULL,\n    wbSCRI,\n    wbENAM,\n    wbInteger(ANAM, 'Enchantment Points', itU16),\n    wbStruct(BMDT, '', [\n      wbInteger('Biped Flags', itU16, wbFlags([\n        {0x00000001} 'Head',\n        {0x00000002} 'Hair',\n        {0x00000004} 'Upper Body',\n        {0x00000008} 'Lower Body',\n        {0x00000010} 'Hand',\n        {0x00000020} 'Foot',\n        {0x00000040} 'Right Ring',\n        {0x00000080} 'Left Ring',\n        {0x00000100} 'Amulet',\n        {0x00000200} 'Weapon',\n        {0x00000400} 'Back Weapon',\n        {0x00000800} 'Side Weapon',\n        {0x00001000} 'Quiver',\n        {0x00002000} 'Shield',\n        {0x00004000} 'Torch',\n        {0x00008000} 'Tail'\n      ])),\n      wbInteger('General Flags', itU8, wbFlags([\n        {0x0001} 'Hide Rings',\n        {0x0002} 'Hide Amulets',\n        {0x0004} '',\n        {0x0008} '',\n        {0x0010} '',\n        {0x0020} '',\n        {0x0040} 'Non-Playable',\n        {0x0080} '' {Heavy armor}\n      ])),\n      wbByteArray('Unused', 1)\n    ], cpNormal, True),\n    wbRStruct('Male biped model', [\n      wbString(MODL, 'Model Filename'),\n      wbFloat(MODB, 'Bound Radius', cpBenign),\n      wbByteArray(MODT, 'Texture Files Hashes', 0, cpIgnore)\n    ], []),\n    wbRStruct('Male world model', [\n      wbString(MOD2, 'Model Filename'),\n      wbFloat(MO2B, 'Bound Radius', cpBenign),\n      wbByteArray(MO2T, 'Texture Files Hashes', 0, cpIgnore)\n    ], []),\n    wbString(ICON, 'Male icon filename'),\n    wbRStruct('Female biped model', [\n      wbString(MOD3, 'Model Filename'),\n      wbFloat(MO3B, 'Bound Radius', cpBenign),\n      wbByteArray(MO3T, 'Texture Files Hashes', 0, cpIgnore)\n    ], []),\n    wbRStruct('Female world model', [\n      wbString(MOD4, 'Model Filename'),\n      wbFloat(MO4B, 'Bound Radius', cpBenign),\n      wbByteArray(MO4T, 'Texture Files Hashes', 0, cpIgnore)\n    ], []),\n    wbString(ICO2, 'Female icon filename'),\n    wbStruct(DATA, '', [\n      wbInteger('Value', itU32),\n      wbFloat('Weight')\n    ], cpNormal, True)\n  ]);\n\n  wbCNTO :=\n    wbStructSK(CNTO, [0], 'Item', [\n      wbFormIDCk('Item', [ARMO, AMMO, MISC, WEAP, INGR, SLGM, SGST, BOOK, LVLI, KEYM, CLOT, ALCH, APPA, LIGH]),\n      wbInteger('Count', itS32)\n    ]);\n\n  wbCNTOs := wbRArrayS('Items', wbCNTO);\n\n  wbRecord(CONT, 'Container', [\n    wbEDID,\n    wbFULL,\n    wbMODL,\n    wbSCRI,\n    wbCNTOs,\n    wbStruct(DATA, '', [\n      wbInteger('Flags', itU8, wbFlags(['', 'Respawns'])),\n      wbFloat('Weight')\n    ], cpNormal, True),\n    wbFormIDCk(SNAM, 'Open sound', [SOUN]),\n    wbFormIDCk(QNAM, 'Close sound', [SOUN])\n  ]);\n\n  wbCSDT := wbRStructSK([0], 'Sound Type', [\n    wbInteger(CSDT, 'Type', itU32,wbEnum([\n      {0x00} 'Left Foot',\n      {0x01} 'Right Foot',\n      {0x02} 'Left Back Foot',\n      {0x03} 'Right Back Foot',\n      {0x04} 'Idle',\n      {0x05} 'Aware',\n      {0x06} 'Attack',\n      {0x07} 'Hit',\n      {0x08} 'Death',\n      {0x09} 'Weapon'\n    ])),\n    wbRArrayS('Sounds', wbRStructSK([0], 'Sound', [\n      wbFormIDCk(CSDI, 'Sound', [SOUN, NULL], False, cpNormal, True),\n      wbInteger(CSDC, 'Sound Chance', itU8, nil, cpNormal, True)\n    ], []), cpNormal, True)\n  ], []);\n\n  wbCSDTs := wbRArrayS('Sound Types', wbCSDT);\n\n  wbSoulGemEnum := wbEnum([\n    {0} 'None',\n    {1} 'Petty',\n    {2} 'Lesser',\n    {3} 'Common',\n    {4} 'Greater',\n    {5} 'Grand'\n  ]);\n\n  wbRecord(CREA, 'Creature', [\n    wbEDID,\n    wbFULL,\n    wbMODL,\n    wbCNTOs,\n    wbSPLOs,\n    wbArrayS(NIFZ, 'Models', wbStringLC('Model')),\n    wbByteArray(NIFT, 'Texture Files Hashes', 0, cpIgnore),\n    wbStruct(ACBS, 'Configuration', [\n      wbInteger('Flags', itU32, wbFlags([\n        {0x000001} 'Biped',\n        {0x000002} 'Essential',\n        {0x000004} 'Weapon & Shield',\n        {0x000008} 'Respawn',\n        {0x000010} 'Swims',\n        {0x000020} 'Flies',\n        {0x000040} 'Walks',\n        {0x000080} 'PC Level Offset',\n        {0x000100} 'Unused', //??\n        {0x000200} 'No Low Level Processing',\n        {0x000400} 'Unused', //??\n        {0x000800} 'No Blood Spray',\n        {0x001000} 'No Blood Decal',\n        {0x002000} '',\n        {0x004000} '',\n        {0x008000} 'No Head',\n        {0x010000} 'No Right Arm',\n        {0x020000} 'No Left Arm',\n        {0x040000} 'No Combat in Water',\n        {0x080000} 'No Shadow',\n        {0x100000} 'No Corpse Check'\n      ])),\n      wbInteger('Base spell points', itU16),\n      wbInteger('Fatigue', itU16),\n      wbInteger('Barter gold', itU16),\n      wbInteger('Level (offset)', itS16),\n      wbInteger('Calc min', itU16),\n      wbInteger('Calc max', itU16)\n    ], cpNormal, True),\n    wbRArrayS('Factions',\n      wbStructSK(SNAM, [0], 'Faction', [\n        wbFormIDCk('Faction', [FACT]),\n        wbInteger('Rank', itU8),\n        wbByteArray('Unused', 3)\n      ])\n    ),\n    wbFormIDCk(INAM, 'Death item', [LVLI]),\n    wbSCRI,\n    wbStruct(AIDT, 'AI Data', [\n      wbInteger('Aggression', itU8),\n      wbInteger('Confidence', itU8),\n      wbInteger('Energy Level', itU8),\n      wbInteger('Responsibility', itU8),\n      wbInteger('Buys/Sells and Services', itU32, wbServiceFlags),\n      wbInteger('Teaches', itS8, wbSkillEnum),\n      wbInteger('Maximum training level', itU8),\n      wbByteArray('Unused', 2)\n    ], cpNormal, True),\n    wbRArray('AI Packages', wbFormIDCk(PKID, 'AI Package', [PACK])),\n    wbArrayS(KFFZ, 'Animations', wbStringLC('Animation')),\n    wbStruct(DATA, 'Creature Data', [\n      wbInteger('Type', itU8, wbEnum([\n        'Creature',\n        'Daedra',\n        'Undead',\n        'Humanoid',\n        'Horse',\n        'Giant'\n      ])),\n      wbInteger('Combat Skill', itU8),\n      wbInteger('Magic Skill', itU8),\n      wbInteger('Stealth Skill', itU8),\n      wbInteger('Soul', itU8, wbSoulGemEnum),\n      wbByteArray('Unused', 1),\n      wbInteger('Health', itU16),\n      wbByteArray('Unused', 2),\n      wbInteger('Attack Damage', itU16),\n      wbInteger('Strength', itU8),\n      wbInteger('Intelligence', itU8),\n      wbInteger('Willpower', itU8),\n      wbInteger('Agility', itU8),\n      wbInteger('Speed', itU8),\n      wbInteger('Endurance', itU8),\n      wbInteger('Personality', itU8),\n      wbInteger('Luck', itU8)\n    ], cpNormal, True),\n    wbInteger(RNAM, 'Attack reach', itU8, nil, cpNormal, True),\n    wbFormIDCk(ZNAM, 'Combat Style', [CSTY]),\n    wbFloat(TNAM, 'Turning Speed', cpNormal, True),\n    wbFloat(BNAM, 'Base Scale', cpNormal, True),\n    wbFloat(WNAM, 'Foot Weight', cpNormal, True),\n    wbString(NAM0, 'Blood Spray'),\n    wbString(NAM1, 'Blood Decal'),\n    wbFormIDCk(CSCR, 'Inherits Sounds from', [CREA]),\n    wbCSDTs\n  ], True);\n\n  wbRecord(CSTY, 'Combat Style', [\n    wbEDID,\n    wbStruct(CSTD, 'Standard', [\n      {000}wbInteger('Dodge % Chance', itU8),\n      {001}wbInteger('Left/Right % Chance', itU8),\n      {002}wbByteArray('Unused', 2),\n      {004}wbFloat('Dodge L/R Timer (min)'),\n      {008}wbFloat('Dodge L/R Timer (max)'),\n      {012}wbFloat('Dodge Forward Timer (min)'),\n      {016}wbFloat('Dodge Forward Timer (max)'),\n      {020}wbFloat('Dodge Back Timer Min'),\n      {024}wbFloat('Dodge Back Timer Max'),\n      {028}wbFloat('Idle Timer min'),\n      {032}wbFloat('Idle Timer max'),\n      {036}wbInteger('Block % Chance', itU8),\n      {037}wbInteger('Attack % Chance', itU8),\n      {038}wbByteArray('Unused', 2),\n      {040}wbFloat('Recoil/Stagger Bonus to Attack'),\n      {044}wbFloat('Unconscious Bonus to Attack'),\n      {048}wbFloat('Hand-To-Hand Bonus to Attack'),\n      {052}wbInteger('Power Attack % Chance', itU8),\n      {053}wbByteArray('Unused', 3),\n      {056}wbFloat('Recoil/Stagger Bonus to Power'),\n      {060}wbFloat('Unconscious Bonus to Power Attack'),\n      {064}wbInteger('Power Attack - Normal', itU8),\n      {065}wbInteger('Power Attack - Forward', itU8),\n      {066}wbInteger('Power Attack - Back', itU8),\n      {067}wbInteger('Power Attack - Left', itU8),\n      {068}wbInteger('Power Attack - Right', itU8),\n      {069}wbByteArray('Unused', 3),\n      {072}wbFloat('Hold Timer (min)'),\n      {076}wbFloat('Hold Timer (max)'),\n      {080}wbInteger('Flags 1', itU8, wbFlags([\n             'Advanced',\n             'Choose Attack using % Chance',\n             'Ignore Allies in Area',\n             'Will Yield',\n             'Rejects Yields',\n             'Fleeing Disabled',\n             'Prefers Ranged',\n             'Melee Alert OK'\n           ])),\n      {081}wbInteger('Acrobatic Dodge % Chance', itU8),\n      {082}wbByteArray('Unused', 2),\n      {084}wbFloat('Range Mult (Optimal)'),\n      {088}wbFloat('Range Mult (Max)'),\n      {092}wbFloat('Switch Distance (Melee)'),\n      {096}wbFloat('Switch Distance (Ranged)'),\n      {100}wbFloat('Buff standoff Distance'),\n      {104}wbFloat('Ranged standoff Distance'),\n      {108}wbFloat('Group standoff Distance'),\n      {112}wbInteger('Rushing Attack % Chance', itU8),\n      {113}wbByteArray('Unused', 3),\n      {116}wbFloat('Rushing Attack Distance Mult'),\n      {120}wbInteger('Flags 2', itU32, wbFlags([\n             'Do Not Acquire'\n           ]))\n    ], cpNormal, True, nil, 31),\n    wbStruct(CSAD, 'Advanced', [\n      wbFloat('Dodge Fatigue Mod Mult'),\n      wbFloat('Dodge Fatigue Mod Base'),\n      wbFloat('Encumb. Speed Mod Base'),\n      wbFloat('Encumb. Speed Mod Mult'),\n      wbFloat('Dodge While Under Attack Mult'),\n      wbFloat('Dodge Not Under Attack Mult'),\n      wbFloat('Dodge Back While Under Attack Mult'),\n      wbFloat('Dodge Back Not Under Attack Mult'),\n      wbFloat('Dodge Forward While Attacking Mult'),\n      wbFloat('Dodge Forward Not Attacking Mult'),\n      wbFloat('Block Skill Modifier Mult'),\n      wbFloat('Block Skill Modifier Base'),\n      wbFloat('Block While Under Attack Mult'),\n      wbFloat('Block Not Under Attack Mult'),\n      wbFloat('Attack Skill Modifier Mult'),\n      wbFloat('Attack Skill Modifier Base'),\n      wbFloat('Attack While Under Attack Mult'),\n      wbFloat('Attack Not Under Attack Mult'),\n      wbFloat('Attack During Block Mult'),\n      wbFloat('Power Att. Fatigue Mod Base'),\n      wbFloat('Power Att. Fatigue Mod Mult')\n    ])\n  ]);\n\n  wbRecord(DIAL, 'Dialog Topic', [\n    wbEDID,\n    wbRArrayS('Quests', wbFormIDCk(QSTI, 'Quest', [QUST], False, cpBenign)),\n    wbRArrayS('Quests?', wbFormIDCk(QSTR, 'Quest?', [QUST], False, cpBenign)),\n    wbFULL,\n    wbInteger(DATA, 'Type', itU8, wbEnum([\n      {0} 'Topic',\n      {1} 'Conversation',\n      {2} 'Combat',\n      {3} 'Persuasion',\n      {4} 'Detection',\n      {5} 'Service',\n      {6} 'Miscellaneous'\n    ]), cpNormal, True)\n  ], True);\n\n  wbRecord(DOOR, 'Door', [\n    wbEDID,\n    wbFULL,\n    wbMODL,\n    wbSCRI,\n    wbFormIDCk(SNAM, 'Open sound', [SOUN]),\n    wbFormIDCk(ANAM, 'Close sound', [SOUN]),\n    wbFormIDCk(BNAM, 'Loop sound', [SOUN]),\n    wbInteger(FNAM, 'Flags', itU8, wbFlags([\n      {0x01} 'Oblivion gate',\n      {0x02} 'Automatic door',\n      {0x04} 'Hidden',\n      {0x08} 'Minimal use'\n    ]), cpNormal, True),\n    wbRArrayS('Random teleport destinations', wbFormIDCk(TNAM, 'Destination', [CELL, WRLD]))\n  ]);\n\n  wbBlendModeEnum := wbEnum([\n    '',\n    'Zero',\n    'One',\n    'Source Color',\n    'Source Inverse Color',\n    'Source Alpha',\n    'Source Inverted Alpha',\n    'Dest Alpha',\n    'Dest Inverted Alpha',\n    'Dest Color',\n    'Dest Inverse Color',\n    'Source Alpha SAT'\n  ]);\n\n  wbBlendOpEnum := wbEnum([\n    '',\n    'Add',\n    'Subtract',\n    'Reverse Subtract',\n    'Minimum',\n    'Maximum'\n  ]);\n  wbZTestFuncEnum := wbEnum([\n    '',\n    '',\n    '',\n    'Equal To',\n    'Normal',\n    'Greater Than',\n    '',\n    'Greater Than or Equal Than',\n    'Always Show'\n  ]);\n\n  wbRecord(EFSH, 'Effect Shader', [\n    wbEDID,\n    wbString(ICON, 'Fill Texture'),\n    wbString(ICO2, 'Particle Shader Texture'),\n    wbStruct(DATA, '', [\n      wbInteger('Flags', itU8, wbFlags([\n        {0} 'No Membrane Shader',\n        {1} '',\n        {2} '',\n        {3} 'No Particle Shader',\n        {4} 'Edge Effect - Inverse',\n        {5} 'Membrane Shader - Affect Skin Only'\n      ])),\n      wbByteArray('Unused', 3),\n      wbInteger('Membrane Shader - Source Blend Mode', itU32, wbBlendModeEnum),\n      wbInteger('Membrane Shader - Blend Operation', itU32, wbBlendOpEnum),\n      wbInteger('Membrane Shader - Z Test Function', itU32, wbZTestFuncEnum),\n      wbStruct('Fill/Texture Effect - Color', [\n        wbInteger('Red', itU8),\n        wbInteger('Green', itU8),\n        wbInteger('Blue', itU8),\n        wbByteArray('Unused', 1)\n      ]),\n      wbFloat('Fill/Texture Effect - Alpha Fade In Time'),\n      wbFloat('Fill/Texture Effect - Full Alpha Time'),\n      wbFloat('Fill/Texture Effect - Alpha Fade Out Time'),\n      wbFloat('Fill/Texture Effect - Presistent Alpha Ratio'),\n      wbFloat('Fill/Texture Effect - Alpha Pulse Amplitude'),\n      wbFloat('Fill/Texture Effect - Alpha Pulse Frequency'),\n      wbFloat('Fill/Texture Effect - Texture Animation Speed (U)'),\n      wbFloat('Fill/Texture Effect - Texture Animation Speed (V)'),\n      wbFloat('Edge Effect - Fall Off'),\n      wbStruct('Edge Effect - Color', [\n        wbInteger('Red', itU8),\n        wbInteger('Green', itU8),\n        wbInteger('Blue', itU8),\n        wbByteArray('Unused', 1)\n      ]),\n      wbFloat('Edge Effect - Alpha Fade In Time'),\n      wbFloat('Edge Effect - Full Alpha Time'),\n      wbFloat('Edge Effect - Alpha Fade Out Time'),\n      wbFloat('Edge Effect - Persistent Alpha Ratio'),\n      wbFloat('Edge Effect - Alpha Pulse Amplitude'),\n      wbFloat('Edge Effect - Alpha Pusle Frequence'),\n      wbFloat('Fill/Texture Effect - Full Alpha Ratio'),\n      wbFloat('Edge Effect - Full Alpha Ratio'),\n      wbInteger('Membrane Shader - Dest Blend Mode', itU32, wbBlendModeEnum),\n      wbInteger('Particle Shader - Source Blend Mode', itU32, wbBlendModeEnum),\n      wbInteger('Particle Shader - Blend Operation', itU32, wbBlendOpEnum),\n      wbInteger('Particle Shader - Z Test Function', itU32, wbZTestFuncEnum),\n      wbInteger('Particle Shader - Dest Blend Mode', itU32, wbBlendModeEnum),\n      wbFloat('Particle Shader - Particle Birth Ramp Up Time'),\n      wbFloat('Particle Shader - Full Particle Birth Time'),\n      wbFloat('Particle Shader - Particle Birth Ramp Down Time'),\n      wbFloat('Particle Shader - Full Particle Birth Ratio'),\n      wbFloat('Particle Shader - Persistant Particle Birth Ratio'),\n      wbFloat('Particle Shader - Particle Lifetime'),\n      wbFloat('Particle Shader - Particle Lifetime +/-'),\n      wbFloat('Particle Shader - Initial Speed Along Normal'),\n      wbFloat('Particle Shader - Acceleration Along Normal'),\n      wbFloat('Particle Shader - Initial Velocity #1'),\n      wbFloat('Particle Shader - Initial Velocity #2'),\n      wbFloat('Particle Shader - Initial Velocity #3'),\n      wbFloat('Particle Shader - Acceleration #1'),\n      wbFloat('Particle Shader - Acceleration #2'),\n      wbFloat('Particle Shader - Acceleration #3'),\n      wbFloat('Particle Shader - Scale Key 1'),\n      wbFloat('Particle Shader - Scale Key 2'),\n      wbFloat('Particle Shader - Scale Key 1 Time'),\n      wbFloat('Particle Shader - Scale Key 2 Time'),\n      wbStruct('Color Key 1 - Color', [\n        wbInteger('Red', itU8),\n        wbInteger('Green', itU8),\n        wbInteger('Blue', itU8),\n        wbByteArray('Unused', 1)\n      ]),\n      wbStruct('Color Key 2 - Color', [\n        wbInteger('Red', itU8),\n        wbInteger('Green', itU8),\n        wbInteger('Blue', itU8),\n        wbByteArray('Unused', 1)\n      ]),\n      wbStruct('Color Key 3 - Color', [\n        wbInteger('Red', itU8),\n        wbInteger('Green', itU8),\n        wbInteger('Blue', itU8),\n        wbByteArray('Unused', 1)\n      ]),\n      wbFloat('Color Key 1 - Color Alpha'),\n      wbFloat('Color Key 2 - Color Alpha'),\n      wbFloat('Color Key 3 - Color Alpha'),\n      wbFloat('Color Key 1 - Color Key Time'),\n      wbFloat('Color Key 2 - Color Key Time'),\n      wbFloat('Color Key 3 - Color Key Time')\n    ], cpNormal, True, nil, 25)\n  ]);\n\n  wbRecord(ENCH, 'Enchantment', [\n    wbEDID,\n    wbStruct(OBME, 'Oblivion Magic Extender', [\n      wbInteger('Record Version', itU8),\n      wbStruct('OBME Version', [\n        wbInteger('Beta', itU8),\n        wbInteger('Minor', itU8),\n        wbInteger('Major', itU8)\n      ]),\n      wbByteArray('Unused', $1C)\n    ], cpNormal, False, wbOBMEDontShow),\n    wbFULL,\n    wbStruct(ENIT, '', [\n      wbInteger('Type', itU32, wbEnum([\n        {0} 'Scroll',\n        {1} 'Staff',\n        {2} 'Weapon',\n        {3} 'Apparel'\n      ])),\n      wbInteger('Charge Amount', itU32),\n      wbInteger('Enchant Cost', itU32),\n      wbInteger('Flags', itU8, wbFlags(['Manual Enchant Cost (Autocalc Off)'])),\n      wbByteArray('Unused', 3)\n    ], cpNormal, True),\n    wbEffects\n  ]);\n\n  wbRecord(EYES, 'Eyes', [\n    wbEDID,\n    wbFULL,\n    wbString(ICON, 'Texture', 0, cpNormal, True),\n    wbInteger(DATA, 'Flags', itU8, wbFlags(['Playable']), cpNormal, True)\n  ]);\n\n  wbXNAM :=\n    wbStructSK(XNAM, [0], 'Relation', [\n      wbFormIDCk('Faction', [FACT, RACE]),\n      wbInteger('Modifier', itS32)\n    ]);\n\n  wbXNAMs := wbRArrayS('Relations', wbXNAM);\n\n  wbRecord(FACT, 'Faction', [\n    wbEDID,\n    wbFULL,\n    wbXNAMs,\n    wbInteger(DATA, 'Flags', itU8, wbFlags(['Hidden from Player', 'Evil', 'Special Combat']), cpNormal, True),\n    wbFloat(CNAM, 'Crime Gold Multiplier', cpNormal, True, 1, -1, nil, nil, 1.0),\n    wbRStructsSK('Ranks', 'Rank', [0], [\n      wbInteger(RNAM, 'Rank#', itS32),\n      wbString(MNAM, 'Male', 0, cpTranslate),\n      wbString(FNAM, 'Female', 0, cpTranslate),\n      wbString(INAM, 'Insignia')\n    ], [])\n  ]);\n\n  wbRecord(FLOR, 'Flora', [\n    wbEDID,\n    wbFULL,\n    wbMODL,\n    wbSCRI,\n    wbFormIDCk(PFIG, 'Ingredient', [INGR]),\n    wbStruct(PFPC, 'Seasonal ingredient production', [\n      wbInteger('Spring', itU8),\n      wbInteger('Summer ', itU8),\n      wbInteger('Fall', itU8),\n      wbInteger('Winter', itU8)\n    ], cpNormal, True)\n  ]);\n\n  wbRecord(FURN, 'Furniture', [\n    wbEDID,\n    wbFULL,\n    wbMODL,\n    wbSCRI,\n    wbByteArray(MNAM, 'Marker Flags', 0, cpNormal, True)\n  ]);\n\n  wbRecord(GLOB, 'Global', [\n    wbEDID,\n    wbInteger(FNAM, 'Type', itU8, wbGLOBFNAM, nil, cpNormal, True),\n    wbFloat(FLTV, 'Value', cpNormal, True)\n  ]);\n\n  wbRecord(GMST, 'Game Setting', [\n    wbEDID,\n    wbUnion(DATA, 'Value', wbGMSTUnionDecider, [\n      wbString('', 0, cpTranslate),\n      wbInteger('', itS32),\n      wbFloat('')\n    ], cpNormal, True)\n  ]);\n\n  wbRecord(GRAS, 'Grass', [\n    wbEDID,\n    wbMODL,\n    wbStruct(DATA, '', [\n      wbInteger('Density', itU8),\n      wbInteger('Min Slope', itU8),\n      wbInteger('Max Slope', itU8),\n      wbByteArray('Unused', 1),\n      wbInteger('Unit from water amount', itU16),\n      wbByteArray('Unused', 2),\n      wbInteger('Unit from water type', itU32, wbEnum([\n        'Above - At Least',\n        'Above - At Most',\n        'Below - At Least',\n        'Below - At Most',\n        'Either - At Least',\n        'Either - At Most',\n        'Either - At Most Above',\n        'Either - At Most Below'\n      ])),\n      wbFloat('Position Range'),\n      wbFloat('Height Range'),\n      wbFloat('Color Range'),\n      wbFloat('Wave Period'),\n      wbInteger('Flags', itU8, wbFlags([\n        'Vertex Lighting',\n        'Uniform Scaling',\n        'Fit to Slope'\n      ])),\n      wbByteArray('Unused', 3)\n    ], cpNormal, True)\n  ]);\n\n  wbRecord(HAIR, 'Hair', [\n    wbEDID,\n    wbFULL,\n    wbMODL,\n    wbString(ICON, 'Texture', 0, cpNormal, True),\n    wbInteger(DATA, 'Flags', itU8, wbFlags([\n      'Playable',\n      'Not Male',\n      'Not Female',\n      'Fixed'\n    ]), cpNormal, True)\n  ]);\n\n  wbCrimeTypeEnum :=\n    wbEnum([\n      'Steal',\n      'Pickpocket',\n      'Trespass',\n      'Attack',\n      'Murder',\n      'Steal Horse'\n    ], [\n      -1, 'None'\n    ]);\n\n  wbFormTypeEnum :=\n    wbEnum([], [\n      $03, 'Game Setting',\n      $04, 'Global',\n      $05, 'Class',\n      $06, 'Faction',\n      $07, 'Hair',\n      $08, 'Eyes',\n      $09, 'Race',\n      $0A, 'Sound',\n      $0B, 'Skill',\n      $0C, 'Magic Effect',\n      $0D, 'Script',\n      $0E, 'Land Texture',\n      $0F, 'Enchantment',\n      $10, 'Spell',\n      $11, 'BirthSign',\n      $12, 'Activator',\n      $13, 'Apparatus',\n      $14, 'Armor',\n      $15, 'Book',\n      $16, 'Clothing',\n      $17, 'Container',\n      $18, 'Door',\n      $19, 'Ingredient',\n      $1A, 'Light',\n      $1B, 'Misc',\n      $1C, 'Static',\n      $1D, 'Grass',\n      $1E, 'Tree',\n      $1F, 'Flora',\n      $20, 'Furniture',\n      $21, 'Weapon',\n      $22, 'Ammi',\n      $23, 'NPC',\n      $24, 'Creature',\n      $25, 'Leveled Creature',\n      $26, 'Soul Gem',\n      $27, 'Key',\n      $28, 'Alchemy',\n      $29, 'SubSpace',\n      $2A, 'Sigil Stone',\n      $2B, 'Leveled Item',\n      $2D, 'Weather',\n      $2E, 'Climate',\n      $2F, 'Region',\n      $30, 'Cell',\n      $31, 'Placed Object',\n      $32, 'Placed NPC',\n      $33, 'Placed Creature',\n      $34, 'Path Grid',\n      $35, 'Worldspace',\n      $36, 'Landscape',\n      $38, 'Road',\n      $39, 'Dialog Topic',\n      $3A, 'Dialog Response',\n      $3B, 'Quest',\n      $3C, 'Idle Animation',\n      $3D, 'Package',\n      $3E, 'Combat Style',\n      $3F, 'Load Screen',\n      $40, 'Leveled Spell',\n      $41, 'Animated Object',\n      $42, 'Water',\n      $43, 'Effect Shader'\n  ]);\n\n  wbSexEnum :=\n    wbEnum(['Male','Female']);\n\n  wbAxisEnum :=\n    wbEnum([], [\n      88, 'X',\n      89, 'Y',\n      90, 'Z'\n    ]);\n\n  wbCTDA :=\n    wbRUnion('Condition', [\n      wbStruct(CTDA, 'Condition', [\n        wbInteger('Type', itU8, wbCtdaType),\n        wbByteArray('Unused', 3),\n        wbUnion('Comparison Value', wbCTDACompValueDecider, [\n          wbFloat('Comparison Value - Float'),\n          wbFormIDCk('Comparison Value - Global', [GLOB])\n        ]),\n        wbInteger('Function', itU32, wbCTDAFunctionToStr, wbCTDAFunctionToInt),\n        wbUnion('Parameter #1', wbCTDAParam1Decider, [\n          {00} wbByteArray('Unknown', 4),\n          {01} wbByteArray('None', 4, cpIgnore),\n          {02} wbInteger('Integer', itS32),\n          {03} wbInteger('Variable Name (INVALID)', itS32),\n          {04} wbInteger('Sex', itU32, wbSexEnum),\n          {05} wbFormIDCk('Actor Value', [ACVA]),\n//          {05} wbInteger('Actor Value', itS32, wbActorValueEnum),\n          {06} wbInteger('Crime Type', itU32, wbCrimeTypeEnum),\n          {07} wbInteger('Axis', itU32, wbAxisEnum),\n          {08} wbInteger('Form Type', itU32, wbFormTypeEnum),\n          {09} wbInteger('Quest Stage (INVALID)', itS32),\n          {10} wbFormIDCk('Object Reference', [PLYR, REFR, ACHR, ACRE, TRGT]),\n          {12} wbFormIDCk('Inventory Object', [ARMO, AMMO, MISC, WEAP, INGR, SLGM, SGST, BOOK, KEYM, CLOT, ALCH, APPA, LIGH]),\n          {13} wbFormIDCk('Actor', [PLYR, ACHR, ACRE, TRGT]),\n          {14} wbFormIDCk('Quest', [QUST]),\n          {15} wbFormIDCk('Faction', [FACT]),\n          {16} wbFormIDCk('Cell', [CELL]),\n          {17} wbFormIDCk('Class', [CLAS]),\n          {18} wbFormIDCk('Race', [RACE]),\n          {19} wbFormIDCk('Actor Base', [NPC_, CREA, ACTI]),\n          {20} wbFormIDCk('Global', [GLOB]),\n          {21} wbFormIDCk('Weather', [WTHR]),\n          {22} wbFormIDCk('Package', [PACK]),\n          {23} wbFormIDCk('Owner', [FACT, NPC_]),\n          {24} wbFormIDCk('Birthsign', [BSGN]),\n          {25} wbFormIDCk('Furniture', [FURN]),\n          {26} wbFormIDCk('Magic Item', [SPEL]),\n          {27} wbFormIDCk('Magic Effect', [MGEF]),\n          {28} wbFormIDCk('Worldspace', [WRLD]),\n          {29} wbFormIDCk('Referenceable Object', [CREA, NPC_, TREE, SBSP, LVLC, SOUN, ACTI, DOOR, FLOR, STAT, FURN, CONT, ARMO, AMMO, MISC, WEAP, INGR, SLGM, SGST, BOOK, KEYM, CLOT, ALCH, APPA, LIGH, GRAS])\n        ]),\n        wbUnion('Parameter #2', wbCTDAParam2Decider, [\n          {00} wbByteArray('Unknown', 4),\n          {01} wbByteArray('None', 4, cpIgnore),\n          {02} wbInteger('Integer', itS32),\n          {03} wbInteger('Variable Name', itS32, wbCTDAParam2VariableNameToStr, wbCTDAParam2VariableNameToInt),\n          {04} wbInteger('Sex', itU32, wbSexEnum),\n          {05} wbFormIDCk('Actor Value', [ACVA]),\n//          {05} wbInteger('Actor Value', itS32, wbActorValueEnum),\n          {06} wbInteger('Crime Type', itU32, wbCrimeTypeEnum),\n          {07} wbInteger('Axis', itU32, wbAxisEnum),\n          {08} wbInteger('Form Type', itU32, wbFormTypeEnum),\n          {09} wbInteger('Quest Stage', itS32, wbCTDAParam2QuestStageToStr, wbCTDAParam2QuestStageToInt),\n          {10} wbFormIDCk('Object Reference', [PLYR, REFR, ACHR, ACRE, TRGT]),\n          {12} wbFormIDCk('Inventory Object', [ARMO, AMMO, MISC, WEAP, INGR, SLGM, SGST, BOOK, KEYM, CLOT, ALCH, APPA, LIGH]),\n          {13} wbFormIDCk('Actor', [PLYR, ACHR, ACRE, TRGT]),\n          {14} wbFormIDCk('Quest', [QUST]),\n          {15} wbFormIDCk('Faction', [FACT]),\n          {16} wbFormIDCk('Cell', [CELL]),\n          {17} wbFormIDCk('Class', [CLAS]),\n          {18} wbFormIDCk('Race', [RACE]),\n          {19} wbFormIDCk('Actor Base', [NPC_, CREA, ACTI]),\n          {20} wbFormIDCk('Global', [GLOB]),\n          {21} wbFormIDCk('Weather', [WTHR]),\n          {22} wbFormIDCk('Package', [PACK]),\n          {23} wbFormIDCk('Owner', [FACT, NPC_]),\n          {24} wbFormIDCk('Birthsign', [BSGN]),\n          {25} wbFormIDCk('Furniture', [FURN]),\n          {26} wbFormIDCk('Magic Item', [SPEL]),\n          {27} wbFormIDCk('Magic Effect', [MGEF]),\n          {28} wbFormIDCk('Worldspace', [WRLD]),\n          {29} wbFormIDCk('Referenceable Object', [CREA, NPC_, TREE, SBSP, LVLC, SOUN, ACTI, DOOR, FLOR, STAT, FURN, CONT, ARMO, AMMO, MISC, WEAP, INGR, SLGM, SGST, BOOK, KEYM, CLOT, ALCH, APPA, LIGH, GRAS])\n        ]),\n        wbInteger('Unused', itU32, nil, cpIgnore)\n      ], cpNormal, False, nil, 6),\n      wbStruct(CTDT, 'Condition (old format)', [\n        wbInteger('Type', itU8, wbCtdaType),\n        wbByteArray('Unused', 3),\n        wbUnion('Comparison Value', wbCTDACompValueDecider, [\n          wbFloat('Comparison Value - Float'),\n          wbFormIDCk('Comparison Value - Global', [GLOB])\n        ]),\n        wbInteger('Function', itU32, wbCTDAFunctionToStr, wbCTDAFunctionToInt),\n        wbUnion('Parameter #1', wbCTDAParam1Decider, [\n          {00} wbByteArray('Unknown', 4),\n          {01} wbByteArray('None', 4, cpIgnore),\n          {02} wbInteger('Integer', itS32),\n          {03} wbInteger('Variable Name (INVALID)', itS32),\n          {04} wbInteger('Sex', itU32, wbSexEnum),\n          {05} wbFormIDCk('Actor Value', [ACVA]),\n//          {05} wbInteger('Actor Value', itS32, wbActorValueEnum),\n          {06} wbInteger('Crime Type', itU32, wbCrimeTypeEnum),\n          {07} wbInteger('Axis', itU32, wbAxisEnum),\n          {08} wbInteger('Form Type', itU32, wbFormTypeEnum),\n          {09} wbInteger('Quest Stage (INVALID)', itS32),\n          {10} wbFormIDCk('Object Reference', [PLYR, REFR, ACHR, ACRE, TRGT]),\n          {12} wbFormIDCk('Inventory Object', [ARMO, AMMO, MISC, WEAP, INGR, SLGM, SGST, BOOK, KEYM, CLOT, ALCH, APPA, LIGH]),\n          {13} wbFormIDCk('Actor', [PLYR, ACHR, ACRE, TRGT]),\n          {14} wbFormIDCk('Quest', [QUST]),\n          {15} wbFormIDCk('Faction', [FACT]),\n          {16} wbFormIDCk('Cell', [CELL]),\n          {17} wbFormIDCk('Class', [CLAS]),\n          {18} wbFormIDCk('Race', [RACE]),\n          {19} wbFormIDCk('Actor Base', [NPC_, CREA, ACTI]),\n          {20} wbFormIDCk('Global', [GLOB]),\n          {21} wbFormIDCk('Weather', [WTHR]),\n          {22} wbFormIDCk('Package', [PACK]),\n          {23} wbFormIDCk('Owner', [FACT, NPC_]),\n          {24} wbFormIDCk('Birthsign', [BSGN]),\n          {25} wbFormIDCk('Furniture', [FURN]),\n          {26} wbFormIDCk('Magic Item', [SPEL]),\n          {27} wbFormIDCk('Magic Effect', [MGEF]),\n          {28} wbFormIDCk('Worldspace', [WRLD]),\n          {29} wbFormIDCk('Referenceable Object', [CREA, NPC_, TREE, SBSP, LVLC, SOUN, ACTI, DOOR, FLOR, STAT, FURN, CONT, ARMO, AMMO, MISC, WEAP, INGR, SLGM, SGST, BOOK, KEYM, CLOT, ALCH, APPA, LIGH, GRAS])\n        ]),\n        wbUnion('Parameter #2', wbCTDAParam2Decider, [\n          {00} wbByteArray('Unknown', 4),\n          {01} wbByteArray('None', 4, cpIgnore),\n          {02} wbInteger('Integer', itS32),\n          {03} wbInteger('Variable Name', itS32, wbCTDAParam2VariableNameToStr, wbCTDAParam2VariableNameToInt),\n          {04} wbInteger('Sex', itU32, wbSexEnum),\n          {05} wbFormIDCk('Actor Value', [ACVA]),\n//          {05} wbInteger('Actor Value', itS32, wbActorValueEnum),\n          {06} wbInteger('Crime Type', itU32, wbCrimeTypeEnum),\n          {07} wbInteger('Axis', itU32, wbAxisEnum),\n          {08} wbInteger('Form Type', itU32, wbFormTypeEnum),\n          {09} wbInteger('Quest Stage', itS32, wbCTDAParam2QuestStageToStr, wbCTDAParam2QuestStageToInt),\n          {10} wbFormIDCk('Object Reference', [PLYR, REFR, ACHR, ACRE, TRGT]),\n          {12} wbFormIDCk('Inventory Object', [ARMO, AMMO, MISC, WEAP, INGR, SLGM, SGST, BOOK, KEYM, CLOT, ALCH, APPA, LIGH]),\n          {13} wbFormIDCk('Actor', [PLYR, ACHR, ACRE, TRGT]),\n          {14} wbFormIDCk('Quest', [QUST]),\n          {15} wbFormIDCk('Faction', [FACT]),\n          {16} wbFormIDCk('Cell', [CELL]),\n          {17} wbFormIDCk('Class', [CLAS]),\n          {18} wbFormIDCk('Race', [RACE]),\n          {19} wbFormIDCk('Actor Base', [NPC_, CREA, ACTI]),\n          {20} wbFormIDCk('Global', [GLOB]),\n          {21} wbFormIDCk('Weather', [WTHR]),\n          {22} wbFormIDCk('Package', [PACK]),\n          {23} wbFormIDCk('Owner', [FACT, NPC_]),\n          {24} wbFormIDCk('Birthsign', [BSGN]),\n          {25} wbFormIDCk('Furniture', [FURN]),\n          {26} wbFormIDCk('Magic Item', [SPEL]),\n          {27} wbFormIDCk('Magic Effect', [MGEF]),\n          {28} wbFormIDCk('Worldspace', [WRLD]),\n          {29} wbFormIDCk('Referenceable Object', [CREA, NPC_, TREE, SBSP, LVLC, SOUN, ACTI, DOOR, FLOR, STAT, FURN, CONT, ARMO, AMMO, MISC, WEAP, INGR, SLGM, SGST, BOOK, KEYM, CLOT, ALCH, APPA, LIGH, GRAS])\n        ]),\n        wbEmpty('Unused', cpIgnore)\n      ])\n    ], []);\n\n  wbCTDAs := wbRArray('Conditions', wbCTDA);\n\n  wbSCHR :=\n    wbRUnion('Basic Script Data', [\n      wbStruct(SCHR, 'Basic Script Data', [\n        wbByteArray('Unused', 4),\n        wbInteger('RefCount', itU32),\n        wbInteger('CompiledSize', itU32),\n        wbInteger('VariableCount', itU32),\n        wbInteger('Type', itU32, wbEnum([\n          'Object',\n          'Quest'\n        ], [\n          $100, 'Magic Effect'\n        ]))\n      ]),\n      wbStruct(SCHD, 'Basic Script Data', [\n        wbByteArray('Unused', 4),\n        wbInteger('RefCount', itU32),\n        wbInteger('CompiledSize', itU32),\n        wbInteger('VariableCount', itU32),\n        wbInteger('Type', itU32, wbEnum([\n          'Object',\n          'Quest'\n        ], [\n          $100, 'Magic Effect'\n        ])),\n        wbByteArray('Unknown')\n      ])\n    ], []);\n\n  wbSCROs :=\n    wbRArray('References',\n      wbRUnion('', [\n        wbFormID(SCRO, 'Global Reference'),\n//        wbFormIDCk(SCRO, 'Global Reference',\n//          [ACTI, DOOR, FLOR, STAT, FURN, CREA, SPEL, NPC_, CONT, ARMO, AMMO, MISC, WEAP,\n//           INGR, SLGM, SGST, BOOK, KEYM, CLOT, ALCH, APPA, LIGH, QUST, PLYR, PACK, LVLI,\n//           FACT, ACHR, REFR, ACRE, GLOB, DIAL, CELL, SOUN, MGEF, WTHR, CLAS, EFSH, RACE,\n//           LVLC, CSTY, WATR, WRLD, SCPT, BSGN, TREE, ENCH, NULL]),\n        wbInteger(SCRV, 'Local Variable', itU32)\n      ], [])\n    );\n\n  wbResultScript := wbRStruct('Result Script', [\n    wbSCHR,\n    wbByteArray(SCDA, 'Compiled result script'),\n    wbStringScript(SCTX, 'Result script source'),\n    wbSCROs\n  ], []);\n{\n  wbResultScriptOld := wbRStruct('Result Script (Old Format?)', [\n    wbByteArray(SCHD, 'Unknown (Script Header?)'),\n    wbByteArray(SCDA, 'Compiled result script'),\n    wbStringScript(SCTX, 'Result script source'),\n    wbSCROs\n  ], []);\n}\n  wbRecord(IDLE, 'Idle Animation', [\n    wbEDID,\n    wbMODL,\n    wbCTDAs,\n    wbInteger(ANAM, 'Animation Group Section', itU8, wbIdleAnam, nil, cpNormal, True),\n    wbArray(DATA, 'Related Idle Animations', wbFormIDCk('Related Idle Animation', [IDLE, NULL]), ['Parent', 'Previous Sibling'], cpNormal, True)\n  ]);\n\n  wbRecord(INFO, 'Dialog response', [\n    wbStruct(DATA, '', [\n      wbInteger('Type', itU8, wbEnum([], [\n        0, 'Topic',\n        1, 'Conversation',\n        2, 'Combat',\n        3, 'Persuasion',\n        4, 'Detection',\n        5, 'Service',\n        6, 'Miscellaneous'\n      ])),\n      wbInteger('Next Speaker', itU8, wbEnum([\n        {0} 'Target',\n        {1} 'Self',\n        {2} 'Either'\n      ])),\n      wbInteger('Flags', itU8, wbFlags([\n        {0x0001} 'Goodbye',\n        {0x0002} 'Random',\n        {0x0004} 'Say Once',\n        {0x0008} 'Run Immediately',\n        {0x0010} 'Info Refusal',\n        {0x0020} 'Random End',\n        {0x0040} 'Run for Rumors'\n      ]))\n    ], cpNormal, True),\n    wbFormIDCk(QSTI, 'Quest', [QUST], False, cpNormal, True),\n    wbFormIDCk(TPIC, 'Topic', [DIAL]),\n    wbFormIDCk(PNAM, 'Previous INFO', [INFO, NULL]),\n    wbRArray('Add topics', wbFormIDCk(NAME, 'Topic', [DIAL])),\n    wbRArray('Responses',\n      wbRStruct('Response', [\n        wbStruct(TRDT, 'Response Data', [\n          wbInteger('Emotion Type', itU32, wbEnum([\n            {0} 'Neutral',\n            {1} 'Anger',\n            {2} 'Disgust',\n            {3} 'Fear',\n            {4} 'Sad',\n            {5} 'Happy',\n            {6} 'Surprise'\n          ])),\n          wbInteger('Emotion Value', itS32),\n          wbByteArray('Unused', 4),\n          wbInteger('Response number', itU8),\n          wbByteArray('Unused', 3)\n        ]),\n        wbStringKC(NAM1, 'Response Text', 0, cpTranslate),\n        wbString(NAM2, 'Actor notes', 0, cpTranslate)\n      ], [])\n    ),\n    wbCTDAs,\n    wbRArray('Choices', wbFormIDCk(TCLT, 'Choice', [DIAL])),\n    wbRArray('Link From', wbFormIDCk(TCLF, 'Topic', [DIAL])),\n    wbResultScript\n  ]);\n\n  wbRecord(INGR, 'Ingredient', [\n    wbEDID,\n    wbStruct(OBME, 'Oblivion Magic Extender', [\n      wbInteger('Record Version', itU8),\n      wbStruct('OBME Version', [\n        wbInteger('Beta', itU8),\n        wbInteger('Minor', itU8),\n        wbInteger('Major', itU8)\n      ]),\n      wbByteArray('Unused', $1C)\n    ], cpNormal, False, wbOBMEDontShow),\n    wbFULL,\n    wbMODL,\n    wbICON,\n    wbSCRI,\n    wbFloat(DATA, 'Weight', cpNormal, True),\n    wbStruct(ENIT, '', [\n      wbInteger('Value', itS32),\n      wbInteger('Flags', itU8, wbFlags(['No auto-calculation', 'Food item'])),\n      wbByteArray('Unused', 3)\n    ], cpNormal, True),\n    wbEffects\n  ]);\n\n  wbRecord(KEYM, 'Key', [\n    wbEDID,\n    wbFULL,\n    wbMODL,\n    wbICON,\n    wbSCRI,\n    wbStruct(DATA, '', [\n      wbInteger('Value', itS32),\n      wbFloat('Weight')\n    ], cpNormal, True)\n  ]);\n\n  wbQuadrantEnum := wbEnum([\n    {0} 'Bottom Left',\n    {1} 'Bottom Right',\n    {2} 'Top Left',\n    {3} 'Top Right'\n  ]);\n\n  if wbSimpleRecords then begin\n\n    wbRecord(LAND, 'Landscape', [\n      wbByteArray(DATA, 'Unknown'),\n      wbByteArray(VNML, 'Vertex Normals'),\n      wbByteArray(VHGT, 'Vertext Height Map'),\n      wbByteArray(VCLR, 'Vertex Colours'),\n\n      wbRArrayS('Layers', wbRUnion('Layer', [\n        wbRStructSK([0],'Base Layer', [\n          wbStructSK(BTXT, [1, 3], 'Base Layer Header', [\n            wbFormIDCk('Texture', [LTEX, NULL]),\n            wbInteger('Quadrant', itU8, wbQuadrantEnum),\n            wbByteArray('Unused', 1),\n            wbInteger('Layer', itS16)\n          ])\n        ], []),\n        wbRStructSK([0],'Alpha Layer', [\n          wbStructSK(ATXT, [1, 3], 'Alpha Layer Header', [\n            wbFormIDCk('Texture', [LTEX, NULL]),\n            wbInteger('Quadrant', itU8, wbQuadrantEnum),\n            wbByteArray('Unused', 1),\n            wbInteger('Layer', itS16)\n          ]),\n          wbByteArray(VTXT, 'Alpha Layer Data')\n        ], [])\n      ], [])),\n\n      wbArray(VTEX, 'Textures', wbFormIDCk('Texture', [LTEX, NULL]))\n    ]);\n\n  end else begin\n\n    wbRecord(LAND, 'Landscape', [\n      wbByteArray(DATA, 'Unknown'),\n//      wbStruct(DATA, '', [\n//        wbInteger('Flags', itU8, wbFlags([])),\n//        wbByteArray('Unknown')\n//      ]),\n      wbArray(VNML, 'Vertex Normals', wbStruct('Row', [\n        wbArray('Columns', wbStruct('Column', [\n          wbInteger('X', itU8),\n          wbInteger('Y', itU8),\n          wbInteger('Z', itU8)\n        ]), 33)\n      ]), 33),\n      wbStruct(VHGT, 'Vertext Height Map', [\n        wbFloat('Offset'),\n        wbArray('Rows', wbStruct('Row', [\n          wbArray('Columns', wbInteger('Column', itU8), 33)\n        ]), 33),\n        wbByteArray('Unused', 3)\n      ]),\n      wbArray(VCLR, 'Vertex Colours', wbStruct('Row', [\n        wbArray('Columns', wbStruct('Column', [\n          wbInteger('X', itU8),\n          wbInteger('Y', itU8),\n          wbInteger('Z', itU8)\n        ]), 33)\n      ]), 33),\n\n      wbRArrayS('Layers', wbRUnion('Layer', [\n        wbRStructSK([0],'Base Layer', [\n          wbStructSK(BTXT, [1, 3], 'Base Layer Header', [\n            wbFormIDCk('Texture', [LTEX, NULL]),\n            wbInteger('Quadrant', itU8, wbQuadrantEnum),\n            wbByteArray('Unused', 1),\n            wbInteger('Layer', itS16)\n          ])\n        ], []),\n        wbRStructSK([0],'Alpha Layer', [\n          wbStructSK(ATXT, [1, 3], 'Alpha Layer Header', [\n            wbFormIDCk('Texture', [LTEX, NULL]),\n            wbInteger('Quadrant', itU8, wbQuadrantEnum),\n            wbByteArray('Unused', 1),\n            wbInteger('Layer', itS16)\n          ]),\n          wbArrayS(VTXT, 'Alpha Layer Data', wbStructSK([0], 'Cell', [\n            wbInteger('Position', itU16, wbAtxtPosition),\n            wbByteArray('Unused', 2),\n            wbFloat('Opacity')\n          ]))\n        ], [])\n      ], [])),\n\n      wbArray(VTEX, 'Textures', wbFormIDCk('Texture', [LTEX, NULL]))\n    ]);\n\n  end;\n\n  wbRecord(LIGH, 'Light', [\n    wbEDID,\n    wbMODL,\n    wbSCRI,\n    wbFULL,\n    wbICON,\n    wbStruct(DATA, '', [\n      wbInteger('Time', itS32),\n      wbInteger('Radius', itU32),\n      wbStruct('Color', [\n        wbInteger('Red', itU8),\n        wbInteger('Green', itU8),\n        wbInteger('Blue', itU8),\n        wbInteger('Unused', itU8)\n      ]),\n      wbInteger('Flags', itU32, wbFlags([\n        {0x00000001} 'Dynamic',\n        {0x00000002} 'Can be Carried',\n        {0x00000004} 'Negative',\n        {0x00000008} 'Flicker',\n        {0x00000010} 'Unused',\n        {0x00000020} 'Off By Default',\n        {0x00000040} 'Flicker Slow',\n        {0x00000080} 'Pulse',\n        {0x00000100} 'Pulse Slow',\n        {0x00000200} 'Spot Light',\n        {0x00000400} 'Spot Shadow'\n      ])),\n      wbFloat('Falloff Exponent'),\n      wbFloat('FOV'),\n      wbInteger('Value', itU32),\n      wbFloat('Weight')\n    ], cpNormal, True, nil, 6),\n    wbFloat(FNAM, 'Fade value', cpNormal, True, 1, -1, nil, nil, 1.0),\n    wbFormIDCk(SNAM, 'Sound', [SOUN])\n  ], False, nil, cpNormal, False, wbLIGHAfterLoad);\n\n  wbRecord(LSCR, 'Load Screen', [\n    wbEDID,\n    wbICON,\n    wbDESC,\n    wbRArrayS('Locations', wbStructSK(LNAM, [0, 1], 'Location', [\n      wbFormIDCk('Direct', [CELL, WRLD, NULL]),\n      wbStructSK([0, 1], 'Indirect', [\n        wbFormIDCk('World', [NULL, WRLD]),\n        wbStructSK([0,1], 'Grid', [\n          wbInteger('Y', itS16),\n          wbInteger('X', itS16)\n        ])\n      ])\n    ]))\n  ]);\n\n  wbRecord(LTEX, 'Landscape Texture', [\n    wbEDID,\n    wbICON,\n    wbStruct(HNAM, 'Havok Data', [\n      wbInteger('Material Type', itU8, wbEnum([\n        {00} 'STONE',\n        {01} 'CLOTH',\n        {02} 'DIRT',\n        {03} 'GLASS',\n        {04} 'GRASS',\n        {05} 'METAL',\n        {06} 'ORGANIC',\n        {07} 'SKIN',\n        {08} 'WATER',\n        {09} 'WOOD',\n        {10} 'HEAVY STONE',\n        {11} 'HEAVY METAL',\n        {12} 'HEAVY WOOD',\n        {13} 'CHAIN',\n        {14} 'SNOW'\n      ]), cpNormal, True, nil, nil, 2),\n      wbInteger('Friction', itU8, nil, cpNormal, True, nil, nil, 30),\n      wbInteger('Restitution', itU8, nil, cpNormal, True, nil, nil, 30)\n    ], cpNormal, True),\n    wbInteger(SNAM, 'Texture Specular Exponent', itU8, nil, cpNormal, True, False, nil, nil, 30),\n    wbRArrayS('Grasses', wbFormIDCk(GNAM, 'Grass', [GRAS]))\n  ]);\n\n  wbRecord(LVLC, 'Leveled Creature', [\n    wbEDID,\n    wbInteger(LVLD, 'Chance none', itU8, nil, cpNormal, True),\n    wbInteger(LVLF, 'Flags', itU8, wbFlags([\n      {0x01} 'Calculate from all levels <= player''s level',\n      {0x02} 'Calculate for each item in count'\n    ]), cpNormal, True),\n    wbRArrayS('Leveled List Entries',\n      wbStructExSK(LVLO , [0, 2], [3], 'Leveled List Entry', [\n        wbInteger('Level', itS16),\n        wbByteArray('Unused', 2),\n        wbFormIDCk('Reference', [NPC_, CREA, LVLC]),\n        wbInteger('Count', itS16),\n        wbByteArray('Unused', 2)\n      ], cpNormal, False, nil, 3),\n    cpNormal, True),\n    wbSCRI,\n    wbFormIDCk(TNAM, 'Creature template', [NPC_, CREA])\n  ], True, nil, cpNormal, False, wbLVLAfterLoad);\n\n  wbRecord(LVLI, 'Leveled Item', [\n    wbEDID,\n    wbInteger(LVLD, 'Chance none', itU8, nil, cpNormal, True),\n    wbInteger(LVLF, 'Flags', itU8, wbFlags([\n      {0x01} 'Calculate from all levels <= player''s level',\n      {0x02} 'Calculate for each item in count'\n    ]), cpNormal, True),\n    wbRArrayS('Leveled List Entries',\n      wbStructExSK(LVLO , [0, 2], [3], 'Leveled List Entry', [\n        wbInteger('Level', itS16),\n        wbByteArray('Unused', 2),\n        wbFormIDCk('Reference', [ARMO, AMMO, MISC, WEAP, INGR, SLGM, SGST, BOOK, LVLI, KEYM, CLOT, ALCH, APPA, LIGH]),\n        wbInteger('Count', itS16),\n        wbByteArray('Unused', 2)\n      ], cpNormal, False, nil, 3),\n    cpNormal, True),\n    wbByteArray(DATA, 'Unused', 1)\n  ], False, nil, cpNormal, False, wbLVLAfterLoad);\n\n  wbRecord(LVSP, 'Leveled Spell', [\n    wbEDID,\n    wbInteger(LVLD, 'Chance none', itU8, nil, cpNormal, True),\n    wbInteger(LVLF, 'Flags', itU8, wbFlags([\n      {0x01} 'Calculate from all levels <= player''s level',\n      {0x02} 'Calculate for each item in count',\n      {0x04} 'Use all spells'\n    ]), cpNormal, True),\n    wbRArrayS('Leveled List Entries',\n      wbStructExSK(LVLO , [0, 2], [3], 'Leveled List Entry', [\n        wbInteger('Level', itS16),\n        wbByteArray('Unused', 2),\n        wbFormIDCk('Reference', [SPEL, LVSP]),\n        wbInteger('Count', itS16),\n        wbByteArray('Unused', 2)\n      ], cpNormal, False, nil, 3),\n    cpNormal, True)\n  ], False, nil, cpNormal, False, wbLVLAfterLoad);\n\n  wbRecord(MGEF, 'Magic Effect', [\n    wbStringMgefCode(EDID, 'Magic Effect Code'),\n    wbStruct(OBME, 'Oblivion Magic Extender', [\n      wbInteger('Record Version', itU8),\n      wbStruct('OBME Version', [\n        wbInteger('Beta', itU8),\n        wbInteger('Minor', itU8),\n        wbInteger('Major', itU8)\n      ]),\n      wbInteger('Param A Info', itU8, wbOBMEResolutionInfo),\n      wbInteger('Param B Info', itU8, wbOBMEResolutionInfo),\n      wbByteArray('Unused', 2),\n      wbString('Handler', 4),\n      wbInteger('Flag Overrides', itU32, wbFlags([\n        { 0} '',\n        { 1} '',\n        { 2} 'ParamFlagA',\n        { 3} 'Beneficial',\n        { 4} '',\n        { 5} '',\n        { 6} '',\n        { 7} '',\n        { 8} '',\n        { 9} '',\n        {10} '',\n        {11} '',\n        {12} '',\n        {13} '',\n        {14} '',\n        {15} '',\n        {16} 'ParamFlagB',\n        {17} 'Magnitude Is Range',\n        {18} 'Atomic Resistance',\n        {19} 'ParamFlagC',\n        {20} 'ParamFlagD',\n        {21} '',\n        {22} '',\n        {23} '',\n        {24} '',\n        {25} '',\n        {26} '',\n        {27} '',\n        {28} '',\n        {29} '',\n        {30} 'Hidden'\n      ])),\n      wbByteArray('ParamB', 4),\n      wbByteArray('Unused', $1C)\n    ], cpNormal, False, wbOBMEDontShow),\n    wbString(EDDX, 'EditorID', 0, cpNormal, False, wbEDDXDontShow),\n    wbFULL,\n    wbDESC,\n    wbICON,\n    wbMODL,\n    wbStruct(DATA, 'Data', [\n      wbInteger('Flags', itU32, wbFlags([\n        {0x00000001} 'Hostile',\n        {0x00000002} 'Recover',\n        {0x00000004} 'Detrimental',\n        {0x00000008} 'Magnitude %',\n        {0x00000010} 'Self',\n        {0x00000020} 'Touch',\n        {0x00000040} 'Target',\n        {0x00000080} 'No duration',\n        {0x00000100} 'No magnitude',\n        {0x00000200} 'No area',\n        {0x00000400} 'FX persist',\n        {0x00000800} 'Spellmaking',\n        {0x00001000} 'Enchanting',\n        {0x00002000} 'No Ingredient',\n        {0x00004000} 'Unknown 14',\n        {0x00008000} 'Unknown 15',\n        {0x00010000} 'Use weapon',\n        {0x00020000} 'Use armor',\n        {0x00040000} 'Use creature',\n        {0x00080000} 'Use skill',\n        {0x00100000} 'Use attribute',\n        {0x00200000} 'Unknown 21',\n        {0x00400000} 'Unknown 22',\n        {0x00800000} 'Unknown 23',\n        {0x01000000} 'Use actor value',\n        {0x02000000} 'Spray projectile type (or Fog if Bolt is specified as well)',\n        {0x04000000} 'Bolt projectile type',\n        {0x08000000} 'No hit effect',\n        {0x10000000} 'Unknown 28',\n        {0x20000000} 'Unknown 29',\n        {0x40000000} 'Unknown 30',\n        {0x80000000} 'Unknown 31'\n      ])),\n      wbFloat('Base cost'),\n      wbUnion('Assoc. Item', wbMGEFFAssocItemDecider, [\n        wbFormIDCk('Unused', [NULL]),\n        wbFormIDCk('Assoc. Weapon', [WEAP]),\n        wbFormIDCk('Assoc. Armor', [ARMO, NULL{?}]),\n        wbFormIDCk('Assoc. Creature', [CREA, LVLC, NPC_]),\n        wbInteger('Assoc. Actor Value', itS32, wbActorValueEnum)\n      ]),\n      wbInteger('Magic School', itS32, wbMagicSchoolEnum),\n      wbInteger('Resist value', itS32, wbActorValueEnum),\n      wbInteger('Counter Effect Count', itU16), //!!! must be updated automatically when ESCE length changes!\n      wbByteArray('Unused', 2),\n      wbFormIDCk('Light', [LIGH, NULL]),\n      wbFloat('Projectile speed'),\n      wbFormIDCk('Effect Shader', [EFSH, NULL]),\n      wbFormIDCk('Enchant effect', [EFSH, NULL]),\n      wbFormIDCk('Casting sound', [NULL, SOUN]),\n      wbFormIDCk('Bolt sound', [NULL, SOUN]),\n      wbFormIDCk('Hit sound', [NULL, SOUN]),\n      wbFormIDCk('Area sound', [NULL, SOUN]),\n      wbFloat('Constant Effect enchantment factor'),\n      wbFloat('Constant Effect barter factor')\n    ], cpNormal, True, nil, 10),\n    wbArrayS(ESCE, 'Counter Effects', wbStringMgefCode('Counter Effect Code', 4),\n      0, cpNormal, False, nil, wbCounterEffectsAfterSet)\n  ], False, nil, cpNormal, False, wbMGEFAfterLoad, wbMGEFAfterSet);\n\n  wbRecord(MISC, 'Misc. Item', [\n    wbEDID,\n    wbFULL,\n    wbMODL,\n    wbICON,\n    wbSCRI,\n    wbStruct(DATA, '', [\n      wbUnion('', wbMISCActorValueDecider, [\n        wbInteger('Value', itS32),\n        wbFormIDCk('Actor Value', [ACVA])\n      ]),\n      wbUnion('', wbMISCActorValueDecider, [\n        wbFloat('Weight'),\n        wbInteger('Group', itU32, wbEnum([], [\n          $40E00000, ' [NONE]',\n          $40400000, 'AI',\n          $00000000, 'Attribute',\n          $40C00000, 'Combat',\n          $40A00000, 'Misc',\n          $40000000, 'Skill',\n          $40800000, 'Social',\n          $3F800000, 'Stat'\n        ]))\n      ])\n    ], cpNormal, True)\n  ]);\n\n  wbFaceGen := wbRStruct('FaceGen Data', [\n    wbByteArray(FGGS, 'FaceGen Geometry-Symmetric', 0, cpNormal, True),\n    wbByteArray(FGGA, 'FaceGen Geometry-Asymmetric', 0, cpNormal, True),\n    wbByteArray(FGTS, 'FaceGen Texture-Symmetric', 0, cpNormal, True)\n  ], [], cpNormal, True);\n\n  wbRecord(NPC_, 'Non-Player Character', [\n    wbEDID,\n    wbFULL,\n    wbMODL,\n    wbStruct(ACBS, 'Configuration', [\n      wbInteger('Flags', itU32, wbFlags([\n        {0x000001} 'Female',\n        {0x000002} 'Essential',\n        {0x000004} '',\n        {0x000008} 'Respawn',\n        {0x000010} 'Auto-calc stats',\n        {0x000020} '',\n        {0x000040} '',\n        {0x000080} 'PC Level Offset',\n        {0x000100} '',\n        {0x000200} 'No Low Level Processing',\n        {0x000400} '',\n        {0x000800} '',\n        {0x001000} '',\n        {0x002000} 'No Rumors',\n        {0x004000} 'Summonable',\n        {0x008000} 'No Persuasion',\n        {0x010000} '',\n        {0x020000} '',\n        {0x040000} '',\n        {0x080000} '',\n        {0x100000} 'Can Corpse Check'\n      ])),\n      wbInteger('Base spell points', itU16),\n      wbInteger('Fatigue', itU16),\n      wbInteger('Barter gold', itU16),\n      wbInteger('Level (offset)', itS16),\n      wbInteger('Calc min', itU16),\n      wbInteger('Calc max', itU16)\n    ], cpNormal, True),\n    wbRArrayS('Factions',\n      wbStructSK(SNAM, [0], 'Faction', [\n        wbFormIDCk('Faction', [FACT]),\n        wbInteger('Rank', itU8),\n        wbByteArray('Unused', 3)\n      ])\n    ),\n    wbFormIDCk(INAM, 'Death item', [LVLI]),\n    wbFormIDCk(RNAM, 'Race', [RACE], False, cpNormal, True),\n    wbCNTOs,\n    wbSPLOs,\n    wbSCRI,\n    wbStruct(AIDT, 'AI Data', [\n      wbInteger('Aggression', itU8),\n      wbInteger('Confidence', itU8),\n      wbInteger('Energy Level', itU8),\n      wbInteger('Responsibility', itU8),\n      wbInteger('Buys/Sells and Services', itU32, wbServiceFlags),\n      wbInteger('Teaches', itS8, wbSkillEnum),\n      wbInteger('Maximum training level', itU8),\n      wbByteArray('Unused', 2)\n    ], cpNormal, True),\n    wbRArray('AI Packages', wbFormIDCk(PKID, 'AI Package', [PACK])),\n    wbArrayS(KFFZ, 'Animations', wbString('Animation')),\n    wbFormIDCk(CNAM, 'Class', [CLAS], False, cpNormal, True),\n    wbStruct(DATA, 'Stats', [\n      wbInteger('Armorer', itU8),\n      wbInteger('Athletics', itU8),\n      wbInteger('Blade', itU8),\n      wbInteger('Block', itU8),\n      wbInteger('Blunt', itU8),\n      wbInteger('Hand to Hand', itU8),\n      wbInteger('Heavy Armor', itU8),\n      wbInteger('Alchemy', itU8),\n      wbInteger('Alteration', itU8),\n      wbInteger('Conjuration', itU8),\n      wbInteger('Destruction', itU8),\n      wbInteger('Illusion', itU8),\n      wbInteger('Mysticism', itU8),\n      wbInteger('Restoration', itU8),\n      wbInteger('Acrobatics', itU8),\n      wbInteger('Light Armor', itU8),\n      wbInteger('Marksman', itU8),\n      wbInteger('Mercantile', itU8),\n      wbInteger('Security', itU8),\n      wbInteger('Sneak', itU8),\n      wbInteger('Speechcraft', itU8),\n      wbInteger('Health', itU16),\n      wbByteArray('Unused', 2),\n      wbInteger('Strength', itU8),\n      wbInteger('Intelligence', itU8),\n      wbInteger('Willpower', itU8),\n      wbInteger('Agility', itU8),\n      wbInteger('Speed', itU8),\n      wbInteger('Endurance', itU8),\n      wbInteger('Personality', itU8),\n      wbInteger('Luck', itU8)\n    ], cpNormal, True),\n    wbFormIDCk(HNAM, 'Hair', [HAIR]),\n    wbFloat(LNAM, 'Hair length'),\n    wbArray(ENAM, 'Eyes', wbFormIDCk('Eyes', [EYES])),\n    wbStruct(HCLR, 'Hair color', [\n      wbInteger('Red', itU8),\n      wbInteger('Green', itU8),\n      wbInteger('Blue', itU8),\n      wbByteArray('Unused', 1)\n    ], cpNormal, True),\n    wbFormIDCk(ZNAM, 'Combat Style', [CSTY]),\n    wbFaceGen,\n    wbByteArray(FNAM, 'Unknown', 0, cpBenign)\n  ], True);\n\n  wbPKDTFlags := wbFlags([\n          {0x00000001} 'Offers services',\n          {0x00000002} 'Must reach location',\n          {0x00000004} 'Must complete',\n          {0x00000008} 'Lock doors at package start',\n          {0x00000010} 'Lock doors at package end',\n          {0x00000020} 'Lock doors at location',\n          {0x00000040} 'Unlock doors at package start',\n          {0x00000080} 'Unlock doors at package end',\n          {0x00000100} 'Unlock doors at location',\n          {0x00000200} 'Continue if PC near',\n          {0x00000400} 'Once per day',\n          {0x00000800} 'Unused',\n          {0x00001000} 'Skip fallout behavior',\n          {0x00002000} 'Always run',\n          {0x00004000} '',\n          {0x00008000} '',\n          {0x00010000} '',\n          {0x00020000} 'Always sneak',\n          {0x00040000} 'Allow swimming',\n          {0x00080000} 'Allow falls',\n          {0x00100000} 'Armor unequipped',\n          {0x00200000} 'Weapons unequipped',\n          {0x00400000} 'Defensive combat',\n          {0x00800000} 'Use horse',\n          {0x01000000} 'No idle anims',\n          {0x02000000} '',\n          {0x04000000} '',\n          {0x08000000} '',\n          {0x10000000} '',\n          {0x20000000} '',\n          {0x40000000} '',\n          {0x80000000} ''\n        ]);\n\n  wbPKDTType := wbEnum([\n           {0} 'Find',\n           {1} 'Follow',\n           {2} 'Escort',\n           {3} 'Eat',\n           {4} 'Sleep',\n           {5} 'Wander',\n           {6} 'Travel',\n           {7} 'Accompany',\n           {8} 'Use item at',\n           {9} 'Ambush',\n          {10} 'Flee not combat',\n          {11} 'Cast magic'\n        ]);\n\n  wbRecord(PACK, 'AI Package', [\n    wbEDID,\n    wbUnion(PKDT, 'General', wbPACKPKDTDecider, [\n      wbStruct('General', [\n        wbInteger('Flags', itU16, wbPKDTFlags),\n        wbInteger('Type', itU8, wbPKDTType),\n        wbByteArray('Unused', 1)\n      ]),\n      wbStruct('General', [\n        wbInteger('Flags', itU32, wbPKDTFlags),\n        wbInteger('Type', itU8, wbPKDTType),\n        wbByteArray('Unused', 3)\n      ])\n    ]),\n    wbStruct(PLDT, 'Location', [\n      wbInteger('Type', itS32, wbEnum([\n        {0} 'Near reference',\n        {1} 'In cell',\n        {2} 'Near current location',\n        {3} 'Near editor location',\n        {4} 'Object ID',\n        {5} 'Object type'\n      ])),\n      wbUnion('Location', wbPxDTLocationDecider, [\n        wbFormIDCk('Reference', [REFR, ACHR, ACRE, PLYR], True),\n        wbFormIDCk('Cell', [CELL]),\n        wbFormIDCk('Unused', [NULL]),\n        wbFormIDCk('Unused', [NULL]),\n        wbFormIDCk('Object ID', [ACTI, DOOR, FLOR, STAT, FURN, CREA, SPEL, NPC_, CONT, ARMO, AMMO, MISC, WEAP, INGR, SLGM, SGST, BOOK, KEYM, CLOT, ALCH, APPA, LIGH]),\n        wbInteger('Object type', itU32)\n      ]),\n      wbInteger('Radius', itS32)\n    ]),\n    wbStruct(PSDT, 'Schedule', [\n      wbInteger('Month', itS8),\n      wbInteger('Day of week', itS8, wbEnum([\n        'Sundas',\n        'Morndas',\n        'Tirdas',\n        'Middas',\n        'Turdas',\n        'Fredas',\n        'Loredas',\n        'Morndas to Fredas',\n        'Loredas, Sundas',\n        'Morndas, Middas, Fredas',\n        'Tirdas, Turdas'\n      ], [\n        -1, 'Any'\n      ])),\n      wbInteger('Date', itU8),\n      wbInteger('Time', itS8),\n      wbInteger('Duration', itS32)\n    ]),\n    wbStruct(PTDT, 'Target', [\n      wbInteger('Type', itS32, wbEnum([\n        {0} 'Specific reference',\n        {1} 'Object ID',\n        {2} 'Object type'\n      ])),\n      wbUnion('Target', wbPxDTLocationDecider, [\n        wbFormIDCk('Reference', [ACHR, ACRE, REFR, PLYR], True),\n        wbFormIDCk('Object ID', [ACTI, DOOR, FLOR, STAT, FURN, CREA, SPEL, NPC_, CONT, ARMO, AMMO, MISC, WEAP, INGR, SLGM, SGST, BOOK, KEYM, CLOT, ALCH, APPA, LIGH]),\n        wbInteger('Object type', itU32)\n      ]),\n      wbInteger('Count', itS32)\n    ]),\n    wbCTDAs\n  ]);\n\n  wbPGRP :=\n    wbArray(PGRP, 'Points', wbStruct('Point', [\n      wbFloat('X'),\n      wbFloat('Y'),\n      wbFloat('Z (Even = Red/Orange, Odd = Blue)'),\n      wbInteger('Connections', itU8{, wbPGRPConnectionsCallback}),\n      wbByteArray('Unused', 3)\n    ]), 0, nil, nil, cpNormal, True);\n\n      {The Connection Count in the PGRP record specifies how many entries in this\n       array belong to each point. If the first 4 points in the PGRP array have\n       Connection Counts 2, 5, 2, 4 then the first 2 entries are the connections\n       of point 0, then next 5 are the connections of point 1, the next 2 of point 2,\n       the next 4 of point 3 and so on..., this can currently not be represented\n       declaratively }\n\n  wbRecord(PGRD, 'Path Grid', [\n    wbInteger(DATA, 'Point Count', itU16, nil, cpNormal, True),\n    wbPGRP,\n    wbByteArray(PGAG, 'Unknown'),\n    wbArray(PGRR, 'Point-to-Point Connections',\n      wbArrayS('Point', wbInteger('Point', itS16), wbCalcPGRRSize{, cpNormal, False, wbPGRRPointAfterLoad})\n    ),\n    wbArrayS(PGRI, 'Inter-Cell Connections', wbStructSK([0,2,3,4], 'Inter-Cell Connection', [\n      wbInteger('Point', itU16),\n      wbByteArray('Unused', 2),\n      wbFloat('X'),\n      wbFloat('Y'),\n      wbFloat('Z')\n    ]), 0, cpNormal, False, wbPGRIPointerAfterLoad),\n    wbRArrayS('Point-to-Reference Mappings',\n      wbStructSK(PGRL, [0], 'Point-to-Reference Mapping', [\n        wbFormIDCk('Reference', [REFR]),\n        wbArrayS('Points', wbInteger('Point', itU32))\n      ])\n    )\n  ], False, nil, cpNormal, False, wbPGRDAfterLoad);\n\n  wbRecord(QUST, 'Quest', [\n    wbEDID,\n    wbSCRI,\n    wbFULL,\n    wbICON,\n    wbStruct(DATA, 'General', [\n      wbInteger('Flags', itU8, wbFlags([\n        {0x01} 'Start game enabled',\n        {0x02} '',\n        {0x04} 'Allow repeated conversation topics',\n        {0x08} 'Allow repeated stages'\n      ])),\n      wbInteger('Priority', itU8)\n    ], cpNormal, True),\n    wbCTDAs,\n    wbRArrayS('Stages', wbRStructSK([0], 'Stage', [\n      wbInteger(INDX, 'Stage index', itS16),\n      wbRArray('Log Entries', wbRStruct('Log Entry', [\n        wbInteger(QSDT, 'Stage Flags', itU8, wbFlags([\n          {0x01} 'Complete quest'\n        ])),\n        wbCTDAs,\n        wbString(CNAM, 'Log Entry', 0, cpTranslate),\n        wbResultScript\n      ], []))\n    ], [])),\n    wbRArray('Targets', wbRStruct('Target', [\n      wbStruct(QSTA, 'Target', [\n        wbFormIDCk('Target', [REFR, ACRE, ACHR], True),\n        wbInteger('Flags', itU8, wbFlags([\n          {0x01} 'Compass marker ignores locks'\n        ])),\n        wbByteArray('Unused', 3)\n      ]),\n      wbCTDAs\n    ], []))\n  ]);\n\n  wbBodyDataIndex :=\n    wbInteger(INDX, 'Index', itU32, wbEnum([\n      'Upper Body',\n      'Lower Body',\n      'Hand',\n      'Foot',\n      'Tail'\n    ]));\n\n  wbRecord(RACE, 'Race', [\n    wbEDID,\n    wbFULL,\n    wbDESC,\n    wbSPLOs,\n    wbXNAMs,\n    wbStruct(DATA, '', [\n      wbArrayS('Skill Boosts', wbStructSK([0], 'Skill Boost', [\n        wbInteger('Skill', itS8, wbActorValueEnum),\n        wbInteger('Boost', itS8)\n      ]), 7),\n      wbByteArray('Unused', 2),\n      wbFloat('Male Height'),\n      wbFloat('Female Height'),\n      wbFloat('Male Weight'),\n      wbFloat('Female Weight'),\n      wbInteger('Flags', itU32, wbFlags([\n        'Playable'\n      ]))\n    ], cpNormal, True),\n    wbStruct(VNAM, 'Voice', [\n      wbFormIDCk('Male', [RACE, NULL]),\n      wbFormIDCk('Female', [RACE, NULL])\n    ]),\n    wbStruct(DNAM, 'Default Hair', [\n      wbFormIDCk('Male', [HAIR]),\n      wbFormIDCk('Female', [HAIR])\n    ]),\n    wbInteger(CNAM, 'Default Hair Color', itU8, nil, cpNormal, True),\n    wbFloat(PNAM, 'FaceGen - Main clamp', cpNormal, True),\n    wbFloat(UNAM, 'FaceGen - Face clamp', cpNormal, True),\n    wbStruct(ATTR, 'Base Attributes', [\n      wbStruct('Male', [\n        wbInteger('Strength', itU8),\n        wbInteger('Intelligence', itU8),\n        wbInteger('Willpower', itU8),\n        wbInteger('Agility', itU8),\n        wbInteger('Speed', itU8),\n        wbInteger('Endurance', itU8),\n        wbInteger('Personality', itU8),\n        wbInteger('Luck', itU8)\n      ]),\n      wbStruct('Female', [\n        wbInteger('Strength', itU8),\n        wbInteger('Intelligence', itU8),\n        wbInteger('Willpower', itU8),\n        wbInteger('Agility', itU8),\n        wbInteger('Speed', itU8),\n        wbInteger('Endurance', itU8),\n        wbInteger('Personality', itU8),\n        wbInteger('Luck', itU8)\n      ])\n    ]),\n    wbRStruct('Face Data', [\n      wbEmpty(NAM0, 'Face Data Marker'),\n      wbRArrayS('Parts', wbRStructSK([0], 'Part', [\n        wbInteger(INDX, 'Index', itU32, wbEnum([\n          'Head',\n          'Ear (Male)',\n          'Ear (Female)',\n          'Mouth',\n          'Teeth (Lower)',\n          'Teeth (Upper)',\n          'Tongue',\n          'Eye (Left)',\n          'Eye (Right)'\n        ])),\n        wbMODL,\n        wbICON\n      ], []))\n    ], [], cpNormal, True),\n    wbEmpty(NAM1, 'Body Data Marker', cpNormal, True),\n    wbRStruct('Male Body Data', [\n      wbEmpty(MNAM, 'Male Body Data Marker'),\n      wbMODL,\n      wbRArrayS('Parts', wbRStructSK([0], 'Part', [\n        wbBodyDataIndex,\n        wbICON\n      ], []))\n    ], [], cpNormal, True),\n    wbRStruct('Female Body Data', [\n      wbEmpty(FNAM, 'Female Body Data Marker'),\n      wbMODL,\n      wbRArrayS('Parts', wbRStructSK([0], 'Part', [\n        wbBodyDataIndex,\n        wbICON\n      ], []))\n    ], [], cpNormal, True),\n    wbArrayS(HNAM, 'Hairs', wbFormIDCk('Hair', [HAIR]), 0, cpNormal, True),\n    wbArrayS(ENAM, 'Eyes', wbFormIDCk('Eye', [EYES]),  0,  cpNormal, True),\n    wbFaceGen,\n    wbByteArray(SNAM, 'Unknown', 2, cpNormal, True)\n  ], True);\n\n  wbRecord(REFR, 'Placed Object', [\n    wbEDID,\n    wbFormIDCk(NAME, 'Base', [TREE, SBSP, LVLC, SOUN, ACTI, DOOR, FLOR, STAT, FURN, CONT, ARMO, AMMO, MISC, WEAP, INGR, SLGM, SGST, BOOK, KEYM, CLOT, ALCH, APPA, LIGH, GRAS], False, cpNormal, True),\n    wbStruct(XTEL, 'Teleport Destination', [\n      wbFormIDCk('Door', [REFR], True),\n      wbPosRot\n    ]),\n    wbStruct(XLOC, 'Lock information', [\n      wbInteger('Lock Level', itU8),\n      wbByteArray('Unused', 3),\n      wbFormIDCk('Key', [KEYM, NULL]),\n      wbUnion('Unused', wbXLOCFillerDecider, [\n        wbEmpty('Unused'),\n        wbByteArray('Unused', 4)\n      ]),\n      wbInteger('Flags', itU8, wbFlags(['', '', 'Leveled Lock'])),\n      wbByteArray('Unused', 3)\n    ]),\n    wbRStruct('Ownership', [\n      wbXOWN,\n      wbInteger(XRNK, 'Faction rank', itS32),\n      wbXGLB\n    ], [XLOC]),\n    wbXESP,\n    wbFormIDCk(XTRG, 'Target', [REFR, ACHR, ACRE], True),\n    wbStruct(XSED, 'SpeedTree', [\n      wbInteger('Seed', itU8),\n      wbUnion('Unused', wbREFRXSEDDecider, [\n        wbEmpty('Unused', cpIgnore),\n        wbByteArray('Unused', 3, cpIgnore)\n      ])\n    ]),\n    wbXLOD,\n    wbFloat(XCHG, 'Charge'),\n    wbInteger(XHLT, 'Health', itS32),\n    wbRStruct('Unused', [\n      wbFormIDCk(XPCI, 'Unused', [CELL]),\n      wbString(FULL, 'Unused')\n    ], []),\n    wbInteger(XLCM, 'Level Modifier', itS32),\n    wbFormIDCk(XRTM, 'Unknown', [REFR]),\n    wbInteger(XACT, 'Action Flag', itU32, wbFlags([\n      'Use Default',\n      'Activate',\n      'Open',\n      'Open by Default'\n    ])),\n    wbInteger(XCNT, 'Count', itS32),\n    wbRStruct('Map Marker', [\n      wbEmpty(XMRK, 'Map Marker Data'),\n      wbInteger(FNAM, 'Map Flags', itU8, wbFlags([\n        {0x01} 'Visible',\n        {0x02} 'Can Travel To'\n      ]), cpNormal, True),\n      wbFULLReq,\n      wbStruct(TNAM, '', [\n        wbInteger('Type', itU8, wbEnum([\n          {0x00} 'None',\n          {0x01} 'Camp',\n          {0x02} 'Cave',\n          {0x03} 'City',\n          {0x04} 'Elven Ruin',\n          {0x05} 'Fort Ruin',\n          {0x06} 'Mine',\n          {0x07} 'Landmark',\n          {0x08} 'Tavern',\n          {0x09} 'Settlement',\n          {0x0A} 'Daedric Shrine',\n          {0x0B} 'Oblivion Gate',\n          {0x0C} 'Unknown? (door icon)'\n        ])),\n        wbByteArray('Unused', 1)\n      ], cpNormal, True)\n    ], []),\n    wbEmpty(ONAM, 'Open by Default'),\n    wbXRGD,\n    wbXSCL,\n    wbInteger(XSOL, 'Contained Soul', itU8, wbSoulGemEnum),\n    wbDATAPosRot\n  ], True, wbPlacedAddInfo, cpNormal, False, wbREFRAfterLoad);\n\n  wbRecord(REGN, 'Region', [\n    wbEDID,\n    wbICON,\n    wbStruct(RCLR, 'Map Color', [\n      wbInteger('Red', itU8),\n      wbInteger('Green', itU8),\n      wbInteger('Blue', itU8),\n      wbByteArray('Unused', 1)\n    ], cpNormal, True),\n    wbFormIDCk(WNAM, 'Worldspace', [WRLD]),\n\n    wbRArray('Region Areas', wbRStruct('Region Area', [\n      wbInteger(RPLI, 'Edge Fall-off', itU32),\n      wbArray(RPLD, 'Region Point List Data', wbStruct('Point', [\n        wbFloat('X'),\n        wbFloat('Y')\n      ]), 0, wbRPLDAfterLoad)\n    ], []), cpNormal, True),\n\n    wbRArrayS('Region Data Entries', wbRStructSK([0], 'Region Data Entry', [\n      {always starts with an RDAT}\n      wbStructSK(RDAT, [0], 'Data Header', [\n        wbInteger('Type', itU32, wbEnum([\n          {0}'',\n          {1}'',\n          {2}'Objects',\n          {3}'Weather',\n          {4}'Map',\n          {5}'Unknown 5',\n          {6}'Grass',\n          {7}'Sound',\n          {8}'',\n          {9}''\n        ])),\n        wbInteger('Flags', itU8, wbFlags([\n          'Override'\n        ])),\n        wbInteger('Priority', itU8),\n        wbByteArray('Unused', 2)\n      ], cpNormal, True, nil, 3),\n\n      {followed by one of these: }\n\n      {--- Objects ---}\n      wbArray(RDOT, 'Objects', wbStruct('Object', [\n        wbFormIDCk('Object', [TREE, FLOR, STAT, LTEX]),\n        wbInteger('Parent Index', itU16, wbHideFFFF),\n        wbByteArray('Unused', 2),\n        wbFloat('Density'),\n        wbInteger('Clustering', itU8),\n        wbInteger('Min Slope', itU8),\n        wbInteger('Max Slope', itU8),\n        wbInteger('Flags', itU8, wbFlags([\n          {0}'Conform to slope',\n          {1}'Paint Vertices',\n          {2}'Size Variance +/-',\n          {3}'X +/-',\n          {4}'Y +/-',\n          {5}'Z +/-',\n          {6}'Tree',\n          {7}'Huge Rock'\n        ])),\n        wbInteger('Radius wrt Parent', itU16),\n        wbInteger('Radius', itU16),\n        wbFloat('Min Height'),\n        wbFloat('Max Height'),\n        wbFloat('Sink'),\n        wbFloat('Sink Variance'),\n        wbFloat('Size Variance'),\n        wbStruct('Angle Variance', [\n          wbInteger('X', itU16),\n          wbInteger('Y', itU16),\n          wbInteger('Z', itU16)\n        ]),\n        wbByteArray('Unused', 2),\n        wbByteArray('Unknown', 4)\n      ])),\n\n      {--- Map ---}\n      wbString(RDMP, 'Map Name', 0, cpTranslate),\n\n      {--- Grass ---}\n      wbArrayS(RDGS, 'Grasses', wbStructSK([0], 'Grass', [\n        wbFormIDCk('Grass', [GRAS]),\n        wbByteArray('Unused', 4)\n      ])),\n\n      {--- Sound ---}\n      wbInteger(RDMD, 'Music Type', itU32, wbMusicEnum),\n      wbArrayS(RDSD, 'Sounds', wbStructSK([0], 'Sound', [\n        wbFormIDCk('Sound', [SOUN]),\n        wbInteger('Flags', itU32, wbFlags([\n          'Pleasant',\n          'Cloudy',\n          'Rainy',\n          'Snowy'\n        ])),\n        wbInteger('Chance', itU32, wbScaledInt4ToStr, wbScaledInt4ToInt)\n      ])),\n\n      {--- Weather ---}\n      wbArrayS(RDWT, 'Weather Types', wbStructSK([0], 'Weather Type', [\n        wbFormIDCk('Weather', [WTHR]),\n        wbInteger('Chance', itU32)\n      ]))\n    ], []))\n  ], True);\n\n  wbRecord(ROAD, 'Road', [\n    wbPGRP,\n    wbArray(PGRR, 'Point-to-Point Connections (complex structure can''t be represented, see source)',\n      {The Connection Count in the PGRP record specifies how many entries in this\n       array belong to each point. If the first 4 points in the PGRP array have\n       Connection Counts 2, 5, 2, 4 then the first 2 entries are the connections\n       of point 0, then next 5 are the connections of point 1, the next 2 of point 2,\n       the next 4 of point 3 and so on..., this can currently not be represented\n       declaratively }\n      wbStruct('Point', [\n        wbFloat('X'),\n        wbFloat('Y'),\n        wbFloat('Z')\n      ]), 0, nil, nil, cpNormal, True)\n  ]);\n\n  wbRecord(SBSP, 'Subspace', [\n    wbEDID,\n    wbStruct(DNAM, '', [\n      wbFloat('X'),\n      wbFloat('Y'),\n      wbFloat('Z')\n    ], cpNormal, True)\n  ]);\n\n  wbSLSD := wbStructSK(SLSD, [0], 'Local Variable Data', [\n    wbInteger('Index', itU32),\n    wbByteArray('Unused', 12),\n    wbInteger('Flags', itU8, wbFlags(['IsLongOrShort']), cpCritical),\n    wbByteArray('Unused')\n  ]);\n\n  wbRecord(SCPT, 'Script', [\n    wbEDID,\n    wbByteArray(SCHD, 'Unknown (Script Header?)'),\n    wbSCHR,\n    wbByteArray(SCDA, 'Compiled Script'),\n    wbStringScript(SCTX, 'Script Source', 0, cpNormal, True),\n    wbRArrayS('Local Variables', wbRStructSK([0], 'Local Variable', [\n      wbSLSD,\n      wbString(SCVR, 'Name', 0, cpCritical)\n    ], [])),\n    wbSCROs\n  ]);\n\n  wbRecord(SGST, 'Sigil Stone', [\n    wbEDID,\n    wbStruct(OBME, 'Oblivion Magic Extender', [\n      wbInteger('Record Version', itU8),\n      wbStruct('OBME Version', [\n        wbInteger('Beta', itU8),\n        wbInteger('Minor', itU8),\n        wbInteger('Major', itU8)\n      ]),\n      wbByteArray('Unused', $1C)\n    ], cpNormal, False, wbOBMEDontShow),\n    wbFULL,\n    wbMODL,\n    wbICON,\n    wbSCRI,\n    wbEffects,\n    wbStruct(DATA, '', [\n      wbInteger('Uses ', itU8),\n      wbInteger('Value', itU32),\n      wbFloat('Weight')\n    ], cpNormal, True)\n  ]);\n\n  wbRecord(SKIL, 'Skill', [\n    wbEDID,\n    wbInteger(INDX, 'Skill', itS32, wbActorValueEnum, cpNormal, True),\n    wbDESC,\n    wbICON,\n    wbStruct(DATA, 'Skill Data', [\n      wbInteger('Action', itS32, wbActorValueEnum),\n      wbInteger('Attribute', itS32, wbActorValueEnum),\n      wbInteger('Specialization', itU32, wbSpecializationEnum),\n      wbArray('Use Values', wbFloat('Use Value'), 2)\n    ], cpNormal, True),\n    wbString(ANAM, 'Apprentice Text', 0, cpTranslate, True),\n    wbString(JNAM, 'Journeyman Text', 0, cpTranslate, True),\n    wbString(ENAM, 'Expert Text', 0, cpTranslate, True),\n    wbString(MNAM, 'Master Text', 0, cpTranslate, True)\n  ]);\n\n  wbRecord(SLGM, 'Soul Gem', [\n    wbEDID,\n    wbFULL,\n    wbMODL,\n    wbICON,\n    wbSCRI,\n    wbStruct(DATA, '', [\n      wbInteger('Value', itU32),\n      wbFloat('Weight')\n    ], cpNormal, True),\n    wbInteger(SOUL, 'Contained Soul', itU8, wbSoulGemEnum, cpNormal, True),\n    wbInteger(SLCP, 'Maximum Capacity', itU8, wbSoulGemEnum, cpNormal, True)\n  ]);\n\n  wbRecord(SOUN, 'Sound', [\n    wbEDID,\n    wbString(FNAM, 'Sound Filename'),\n    wbRUnion('Sound Data', [\n      wbStruct(SNDX, 'Sound Data', [\n        wbInteger('Minimum attenuation distance', itU8, wbMul(5)),\n        wbInteger('Maximum attenuation distance', itU8, wbMul(100)),\n        wbInteger('Frequency adjustment %', itS8),\n        wbByteArray('Unused', 1),\n        wbInteger('Flags', itU16, wbFlags([\n          {0x0001} 'Random Frequency Shift',\n          {0x0002} 'Play At Random',\n          {0x0004} 'Environment Ignored',\n          {0x0008} 'Random Location',\n          {0x0010} 'Loop',\n          {0x0020} 'Menu Sound',\n          {0x0040} '2D',\n          {0x0080} '360 LFE'\n        ])),\n        wbByteArray('Unused', 2),\n        wbInteger('Static Attenuation (db)', itU16, wbDiv(100)),\n        wbInteger('Stop time', itU8),\n        wbInteger('Start time', itU8)\n      ], cpNormal, True),\n      wbStruct(SNDD, 'Sound Data', [\n        wbInteger('Minimum attenuation distance', itU8, wbMul(5)),\n        wbInteger('Maximum attenuation distance', itU8, wbMul(100)),\n        wbInteger('Frequency adjustment %', itS8),\n        wbByteArray('Unused', 1),\n        wbInteger('Flags', itU16, wbFlags([\n          {0x0001} 'Random Frequency Shift',\n          {0x0002} 'Play At Random',\n          {0x0004} 'Environment Ignored',\n          {0x0008} 'Random Location',\n          {0x0010} 'Loop',\n          {0x0020} 'Menu Sound',\n          {0x0040} '2D',\n          {0x0080} '360 LFE'\n        ])),\n        wbByteArray('Unused', 2),\n        wbEmpty('Unused'),\n        wbEmpty('Unused'),\n        wbEmpty('Unused')\n      ], cpNormal, True)\n    ], [], cpNormal, True)\n  ]);\n\n  wbRecord(SPEL, 'Spell', [\n    wbEDID,\n    wbStruct(OBME, 'Oblivion Magic Extender', [\n      wbInteger('Record Version', itU8),\n      wbStruct('OBME Version', [\n        wbInteger('Beta', itU8),\n        wbInteger('Minor', itU8),\n        wbInteger('Major', itU8)\n      ]),\n      wbByteArray('Unused', $1C)\n    ], cpNormal, False, wbOBMEDontShow),\n    wbFULL,\n    wbStruct(SPIT, '', [\n      wbInteger('Type', itU32, wbEnum([\n        {0} 'Spell',\n        {1} 'Disease',\n        {2} 'Power',\n        {3} 'Lesser Power',\n        {4} 'Ability',\n        {5} 'Poison'\n      ])),\n      wbInteger('Cost', itU32),\n      wbInteger('Level', itU32, wbEnum([\n        {0} 'Novice',\n        {1} 'Apprentice',\n        {2} 'Journeyman',\n        {3} 'Expert',\n        {4} 'Master'\n      ])),\n      wbInteger('Flags', itU8, wbFlags([\n        {0x00000001} 'Manual Spell Cost',\n        {0x00000002} 'Immune to Silence 1',\n        {0x00000004} 'Player Start Spell',\n        {0x00000008} 'Immune to Silence 2',\n        {0x00000010} 'Area Effect Ignores LOS',\n        {0x00000020} 'Script Effect Always Applies',\n        {0x00000040} 'Disallow Spell Absorb/Reflect',\n        {0x00000080} 'Touch Spell Explodes w/ no Target'\n      ])),\n      wbByteArray('Unused', 3)\n    ], cpNormal, True),\n    wbEffects\n  ]);\n\n  wbRecord(STAT, 'Static', [\n    wbEDID,\n    wbMODL\n  ]);\n\n  wbRecord(TES4, 'Main File Header', [\n    wbStruct(HEDR, 'Header', [\n      wbFloat('Version'),\n      wbInteger('Number of Records', itU32),\n      wbInteger('Next Object ID', itU32)\n    ], cpNormal, True),\n    wbByteArray(OFST, 'Unknown', 0, cpIgnore),\n    wbByteArray(DELE, 'Unknown', 0, cpIgnore),\n    wbString(CNAM, 'Author', 0, cpTranslate, True),\n    wbString(SNAM, 'Description', 0, cpTranslate),\n    wbRArray('Master Files', wbRStruct('Master File', [\n      wbString(MAST, 'Filename', 0, cpNormal, True),\n      wbByteArray(DATA, 'Unused', 8, cpIgnore, True)\n    ], []))\n  ], False, nil, cpNormal, True, wbRemoveOFST);\n\n  wbRecord(TREE, 'Tree', [\n    wbEDID,\n    wbMODL,\n    wbICON,\n    wbArrayS(SNAM, 'SpeedTree Seeds', wbInteger('SpeedTree Seed', itU32)),\n    wbStruct(CNAM, 'Tree Data', [\n      wbFloat('Leaf Curvature'),\n      wbFloat('Minimum Leaf Angle'),\n      wbFloat('Maximum Leaf Angle'),\n      wbFloat('Branch Dimming Value'),\n      wbFloat('Leaf Dimming Value'),\n      wbInteger('Shadow Radius', itS32),\n      wbFloat('Rock Speed'),\n      wbFloat('Rustle Speed')\n    ], cpNormal, True),\n    wbStruct(BNAM, 'Billboard Dimensions', [\n      wbFloat('Width'),\n      wbFloat('Height')\n    ], cpNormal, True)\n  ]);\n\n  wbRecord(WATR, 'Water', [\n    wbEDID,\n    wbString(TNAM, 'Texture', 0, cpNormal, True),\n    wbInteger(ANAM, 'Opacity', itU8, nil, cpNormal, True),\n    wbInteger(FNAM, 'Flags', itU8, wbFlags([\n      {0}'Causes Damage',\n      {1}'Reflective'\n    ]), cpNormal, True),\n    wbString(MNAM, 'Material ID'{>>>}, 0, cpNormal, True{<<<}),\n    wbFormIDCk(SNAM, 'Sound', [SOUN]),\n    wbStruct(DATA, '', [\n      wbFloat('Wind Velocity'),\n      wbFloat('Wind Direction'),\n      wbFloat('Wave Amplitude'),\n      wbFloat('Wave Frequency'),\n      wbFloat('Sun Power'),\n      wbFloat('Reflectivity Amount'),\n      wbFloat('Fresnel Amount'),\n      wbFloat('Scroll X Speed'),\n      wbFloat('Scroll Y Speed'),\n      wbFloat('Fog Distance - Near Plane'),\n      wbFloat('Fog Distance - Far Plane'),\n      wbStruct('Shallow Color', [\n        wbInteger('Red', itU8),\n        wbInteger('Green', itU8),\n        wbInteger('Blue', itU8),\n        wbByteArray('Unused', 1)\n      ]),\n      wbStruct('Deep Color', [\n        wbInteger('Red', itU8),\n        wbInteger('Green', itU8),\n        wbInteger('Blue', itU8),\n        wbByteArray('Unused', 1)\n      ]),\n      wbStruct('Reflection Color', [\n        wbInteger('Red', itU8),\n        wbInteger('Green', itU8),\n        wbInteger('Blue', itU8),\n        wbByteArray('Unused', 1)\n      ]),\n      wbInteger('Texture Blend', itU8),\n      wbByteArray('Unused', 3),\n      wbFloat('Rain Simulator - Force'),\n      wbFloat('Rain Simulator - Velocity'),\n      wbFloat('Rain Simulator - Falloff'),\n      wbFloat('Rain Simulator - Dampner'),\n      wbFloat('Rain Simulator - Starting Size'),\n      wbFloat('Displacement Simulator - Force'),\n      wbFloat('Displacement Simulator - Velocity'),\n      wbFloat('Displacement Simulator - Falloff'),\n      wbFloat('Displacement Simulator - Dampner'),\n      wbFloat('Displacement Simulator - Starting Size'),\n      wbInteger('Damage', itU16)\n    ], cpNormal, True, nil, 0),\n    wbStruct(GNAM, 'Related Waters', [\n      wbFormIDCk('Daytime', [WATR, NULL]),\n      wbFormIDCk('Nighttime', [WATR, NULL]),\n      wbFormIDCk('Underwater', [WATR, NULL])\n    ], cpNormal{>>>, True<<<})\n  ]);\n\n  wbRecord(WEAP, 'Weapon', [\n    wbEDID,\n    wbFULL,\n    wbMODL,\n    wbICON,\n    wbSCRI,\n    wbENAM,\n    wbInteger(ANAM, 'Enchantment Points', itU16),\n    wbStruct(DATA, '', [\n      wbInteger('Type', itU32, wbEnum([\n        {0} 'Blade One Hand',\n        {1} 'Blade Two Hand',\n        {2} 'Blunt One Hand',\n        {3} 'Blunt Two Hand',\n        {4} 'Staff',\n        {5} 'Bow'\n      ])),\n      wbFloat('Speed'),\n      wbFloat('Reach'),\n      wbInteger('Flags', itU32, wbFlags(['Ignores Normal Weapon Resistance'])),\n      wbInteger('Value', itU32),\n      wbInteger('Health', itU32),\n      wbFloat('Weight'),\n      wbInteger('Damage', itU16)\n    ], cpNormal, True)\n  ]);\n\n  if wbSimpleRecords then\n    wbRecord(WRLD, 'Worldspace', [\n      wbEDID,\n      wbFULL,\n      wbRStruct('Parent', [\n        wbFormIDCk(WNAM, 'Worldspace', [WRLD])\n      ], []),\n      wbFormIDCk(CNAM, 'Climate', [CLMT]),\n      wbFormIDCk(NAM2, 'Water', [WATR]),\n      wbICON,\n      wbStruct(MNAM, 'Map Data', [\n        wbStruct('Usable Dimensions', [\n          wbInteger('X', itS32),\n          wbInteger('Y', itS32)\n        ]),\n        wbStruct('Cell Coordinates', [\n          wbStruct('NW Cell', [\n            wbInteger('X', itS16),\n            wbInteger('Y', itS16)\n          ]),\n          wbStruct('SE Cell', [\n            wbInteger('X', itS16),\n            wbInteger('Y', itS16)\n          ])\n        ])\n      ]),\n      wbInteger(DATA, 'Flags', itU8, wbFlags([\n        {0x01} 'Small world',\n        {0x02} 'Can''t fast travel',\n        {0x04} 'Oblivion worldspace',\n        {0x08} '',\n        {0x10} 'No LOD water'\n      ]), cpNormal, True),\n      //wbArray(NAM0, 'Unknown', wbFloat(''), 0, nil, nil, cpNormal, True),\n      //wbArray(NAM9, 'Unknown', wbFloat(''), 0, nil, nil, cpNormal, True),\n      wbRStruct('Object Bounds', [\n        wbStruct(NAM0, 'Min', [\n          wbFloat('X', cpNormal, False, 1/4096),\n          wbFloat('Y', cpNormal, False, 1/4096)\n        ], cpIgnore, True),\n        wbStruct(NAM9, 'Max', [\n          wbFloat('X', cpNormal, False, 1/4096),\n          wbFloat('Y', cpNormal, False, 1/4096)\n        ], cpIgnore, True)\n      ], []),\n      wbInteger(SNAM, 'Music', itU32, wbMusicEnum),\n      wbByteArray(OFST, 'Offset Data')\n    ], False, nil, cpNormal, False, wbRemoveOFST)\n  else\n\twbRecord(WRLD, 'Worldspace', [\n      wbEDID,\n      wbFULL,\n      wbRStruct('Parent', [\n        wbFormIDCk(WNAM, 'Worldspace', [WRLD])\n      ], []),\n      wbFormIDCk(CNAM, 'Climate', [CLMT]),\n      wbFormIDCk(NAM2, 'Water', [WATR]),\n      wbICON,\n      wbStruct(MNAM, 'Map Data', [\n        wbStruct('Usable Dimensions', [\n          wbInteger('X', itS32),\n          wbInteger('Y', itS32)\n        ]),\n        wbStruct('Cell Coordinates', [\n          wbStruct('NW Cell', [\n            wbInteger('X', itS16),\n            wbInteger('Y', itS16)\n          ]),\n          wbStruct('SE Cell', [\n            wbInteger('X', itS16),\n            wbInteger('Y', itS16)\n          ])\n        ])\n      ]),\n      wbInteger(DATA, 'Flags', itU8, wbFlags([\n        {0x01} 'Small world',\n        {0x02} 'Can''t fast travel',\n        {0x04} 'Oblivion worldspace',\n        {0x08} '',\n        {0x10} 'No LOD water'\n      ]), cpNormal, True),\n      //wbArray(NAM0, 'Unknown', wbFloat(''), 0, nil, nil, cpNormal, True),\n      //wbArray(NAM9, 'Unknown', wbFloat(''), 0, nil, nil, cpNormal, True),\n      wbRStruct('Object Bounds', [\n        wbStruct(NAM0, 'Min', [\n          wbFloat('X', cpNormal, False, 1/4096),\n          wbFloat('Y', cpNormal, False, 1/4096)\n        ], cpIgnore, True),\n        wbStruct(NAM9, 'Max', [\n          wbFloat('X', cpNormal, False, 1/4096),\n          wbFloat('Y', cpNormal, False, 1/4096)\n        ], cpIgnore, True)\n      ], []),\n      wbInteger(SNAM, 'Music', itU32, wbMusicEnum),\n      wbArray(OFST, 'Offset Data', wbArray('Rows', wbInteger('Offset', itU32), wbOffsetDataColsCounter), 0)\n    ], False, nil, cpNormal, False, wbRemoveOFST);\n\n  wbRecord(WTHR, 'Weather', [\n    wbEDID,\n    wbString(CNAM, 'Texture Lower Layer'),\n    wbString(DNAM, 'Texture Upper Layer'),\n    wbMODL,\n    wbArray(NAM0, 'Colors by Types/Times',\n      wbArray('Type',\n        wbStruct('Time', [\n          wbInteger('Red', itU8),\n          wbInteger('Green', itU8),\n          wbInteger('Blue', itU8),\n          wbByteArray('Unused', 1)\n        ]),\n        ['Sunrise', 'Day', 'Sunset', 'Night']\n      ),\n      ['Sky-Upper','Fog','Clouds-Lower','Ambient','Sunlight','Sun','Stars','Sky-Lower','Horizon','Clouds-Upper']\n    , cpNormal, True),\n    wbStruct(FNAM, 'Fog Distance', [\n      wbFloat('Day Near'),\n      wbFloat('Day Far'),\n      wbFloat('Night Near'),\n      wbFloat('Night Far')\n    ], cpNormal, True),\n    wbStruct(HNAM, 'HDR Data', [\n      wbFloat('Eye Adapt Speed'),\n      wbFloat('Blur Radius'),\n      wbFloat('Blur Passes'),\n      wbFloat('Emissive Mult'),\n      wbFloat('Target LUM'),\n      wbFloat('Upper LUM Clamp'),\n      wbFloat('Bright Scale'),\n      wbFloat('Bright Clamp'),\n      wbFloat('LUM Ramp No Tex'),\n      wbFloat('LUM Ramp Min'),\n      wbFloat('LUM Ramp Max'),\n      wbFloat('Sunlight Dimmer'),\n      wbFloat('Grass Dimmer'),\n      wbFloat('Tree Dimmer')\n    ], cpNormal, True),\n    wbStruct(DATA, '', [\n      wbInteger('Wind Speed', itU8),\n      wbInteger('Cloud Speed (Lower)', itU8),\n      wbInteger('Cloud Speed (Upper)', itU8),\n      wbInteger('Trans Delta', itU8),\n      wbInteger('Sun Glare', itU8),\n      wbInteger('Sun Damage', itU8),\n      wbInteger('Precipitation - Begin Fade In', itU8),\n      wbInteger('Precipitation - End Fade Out', itU8),\n      wbInteger('Thunder/Lightning - Begin Fade In', itU8),\n      wbInteger('Thunder/Lightning - End Fade Out', itU8),\n      wbInteger('Thunder/Lightning - Frequency', itU8),\n      wbInteger('Weather Classification', itU8, wbWthrDataClassification),\n      wbStruct('Lightning Color', [\n        wbInteger('Red', itU8),\n        wbInteger('Green', itU8),\n        wbInteger('Blue', itU8)\n      ])\n    ], cpNormal, True),\n    wbRArray('Sounds', wbStruct(SNAM, 'Sound', [\n      wbFormIDCk('Sound', [SOUN]),\n      wbInteger('Type', itU32, wbEnum([\n       {0}'Default',\n       {1}'Precip',\n       {2}'Wind',\n       {3}'Thunder'\n      ]))\n    ]))\n  ]);\n\n  wbAddGroupOrder(GMST);\n  wbAddGroupOrder(GLOB);\n  wbAddGroupOrder(CLAS);\n  wbAddGroupOrder(FACT);\n  wbAddGroupOrder(HAIR);\n  wbAddGroupOrder(EYES);\n  wbAddGroupOrder(RACE);\n  wbAddGroupOrder(SOUN);\n  wbAddGroupOrder(SKIL);\n  wbAddGroupOrder(MGEF);\n  wbAddGroupOrder(SCPT);\n  wbAddGroupOrder(LTEX);\n  wbAddGroupOrder(ENCH);\n  wbAddGroupOrder(SPEL);\n  wbAddGroupOrder(BSGN);\n  wbAddGroupOrder(ACTI);\n  wbAddGroupOrder(APPA);\n  wbAddGroupOrder(ARMO);\n  wbAddGroupOrder(BOOK);\n  wbAddGroupOrder(CLOT);\n  wbAddGroupOrder(CONT);\n  wbAddGroupOrder(DOOR);\n  wbAddGroupOrder(INGR);\n  wbAddGroupOrder(LIGH);\n  wbAddGroupOrder(MISC);\n  wbAddGroupOrder(STAT);\n  wbAddGroupOrder(GRAS);\n  wbAddGroupOrder(TREE);\n  wbAddGroupOrder(FLOR);\n  wbAddGroupOrder(FURN);\n  wbAddGroupOrder(WEAP);\n  wbAddGroupOrder(AMMO);\n  wbAddGroupOrder(NPC_);\n  wbAddGroupOrder(CREA);\n  wbAddGroupOrder(LVLC);\n  wbAddGroupOrder(SLGM);\n  wbAddGroupOrder(KEYM);\n  wbAddGroupOrder(ALCH);\n  wbAddGroupOrder(SBSP);\n  wbAddGroupOrder(SGST);\n  wbAddGroupOrder(LVLI);\n  wbAddGroupOrder(WTHR);\n  wbAddGroupOrder(CLMT);\n  wbAddGroupOrder(REGN);\n  wbAddGroupOrder(CELL);\n  wbAddGroupOrder(WRLD);\n  wbAddGroupOrder(DIAL);\n  wbAddGroupOrder(QUST);\n  wbAddGroupOrder(IDLE);\n  wbAddGroupOrder(PACK);\n  wbAddGroupOrder(CSTY);\n  wbAddGroupOrder(LSCR);\n  wbAddGroupOrder(LVSP);\n  wbAddGroupOrder(ANIO);\n  wbAddGroupOrder(WATR);\n  wbAddGroupOrder(EFSH);\nend;\n\ninitialization\nend.\n"
  },
  {
    "path": "lib/xedit/wbDefinitionsTES5.pas",
    "content": "{*******************************************************************************\n\n     The contents of this file are subject to the Mozilla Public License\n     Version 1.1 (the \"License\"); you may not use this file except in\n     compliance with the License. You may obtain a copy of the License at\n     http://www.mozilla.org/MPL/\n\n     Software distributed under the License is distributed on an \"AS IS\"\n     basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the\n     License for the specific language governing rights and limitations\n     under the License.\n\n*******************************************************************************}\n\nunit wbDefinitionsTES5;\n\n{$I wbDefines.inc}\n\ninterface\n\nuses\n  wbInterface;\n\nvar\n\twbBipedObjectFlags: IwbFlagsDef;\n\twbEquipType: IwbFlagsDef;\n\twbFurnitureEntryTypeFlags: IwbFlagsDef;\n\twbPKDTFlags: IwbFlagsDef;\n\twbPKDTInterruptFlags: IwbFlagsDef;\n\twbSMNodeFlags: IwbFlagsDef;\n\n\twbAdvanceActionEnum: IwbEnumDef;\n\twbAlignmentEnum: IwbEnumDef;\n\twbArmorTypeEnum: IwbEnumDef;\n\twbAttackAnimationEnum: IwbEnumDef;\n\twbAxisEnum: IwbEnumDef;\n\twbBipedObjectEnum: IwbEnumDef;\n\twbBlendModeEnum: IwbEnumDef;\n\twbBlendOpEnum: IwbEnumDef;\n\twbBodyPartIndexEnum: IwbEnumDef;\n\twbCastEnum: IwbEnumDef;\n\twbCastingSourceEnum: IwbEnumDef;\n\twbCrimeTypeEnum: IwbEnumDef;\n\twbCriticalStageEnum: IwbEnumDef;\n\twbEmotionTypeEnum: IwbEnumDef;\n\twbEntryPointsEnum: IwbEnumDef;\n\twbEventFunctionEnum: IwbEnumDef;\n\twbEventMemberEnum: IwbEnumDef;\n\twbFormTypeEnum: IwbEnumDef;\n\twbFunctionsEnum: IwbEnumDef;\n\twbFurnitureAnimTypeEnum: IwbEnumDef;\n\twbLocationEnum: IwbEnumDef;\n\twbMiscStatEnum: IwbEnumDef;\n\twbMusicEnum: IwbEnumDef;\n\twbObjectTypeEnum: IwbEnumDef;\n\twbPropTypeEnum: IwbEnumDef;\n\twbQuadrantEnum: IwbEnumDef;\n\twbSexEnum: IwbEnumDef;\n\twbSkillEnum: IwbEnumDef;\n\twbSoulGemEnum: IwbEnumDef;\n\twbSoundLevelEnum: IwbEnumDef;\n\twbTargetEnum: IwbEnumDef;\n\twbTintMaskTypeEnum: IwbEnumDef;\n\twbVatsValueFunctionEnum: IwbEnumDef;\n\twbWardStateEnum: IwbEnumDef;\n\twbWeaponAnimTypeEnum: IwbEnumDef;\n\twbZTestFuncEnum: IwbEnumDef;\n\nprocedure DefineTES5;\n\nimplementation\n\nuses\n  Types,\n  Classes,\n  SysUtils,\n  Math,\n  Variants,\n  wbHelpers;\n\nconst\n  _00_IAD: TwbSignature = #$00'IAD';\n  _01_IAD: TwbSignature = #$01'IAD';\n  _02_IAD: TwbSignature = #$02'IAD';\n  _03_IAD: TwbSignature = #$03'IAD';\n  _04_IAD: TwbSignature = #$04'IAD';\n  _05_IAD: TwbSignature = #$05'IAD';\n  _06_IAD: TwbSignature = #$06'IAD';\n  _07_IAD: TwbSignature = #$07'IAD';\n  _08_IAD: TwbSignature = #$08'IAD';\n  _09_IAD: TwbSignature = #$09'IAD';\n  _0A_IAD: TwbSignature = #$0A'IAD';\n  _0B_IAD: TwbSignature = #$0B'IAD';\n  _0C_IAD: TwbSignature = #$0C'IAD';\n  _0D_IAD: TwbSignature = #$0D'IAD';\n  _0E_IAD: TwbSignature = #$0E'IAD';\n  _0F_IAD: TwbSignature = #$0F'IAD';\n  _10_IAD: TwbSignature = #$10'IAD';\n  _11_IAD: TwbSignature = #$11'IAD';\n  _12_IAD: TwbSignature = #$12'IAD';\n  _13_IAD: TwbSignature = #$13'IAD';\n  _14_IAD: TwbSignature = #$14'IAD';\n  _40_IAD: TwbSignature = #$40'IAD';\n  _41_IAD: TwbSignature = #$41'IAD';\n  _42_IAD: TwbSignature = #$42'IAD';\n  _43_IAD: TwbSignature = #$43'IAD';\n  _44_IAD: TwbSignature = #$44'IAD';\n  _45_IAD: TwbSignature = #$45'IAD';\n  _46_IAD: TwbSignature = #$46'IAD';\n  _47_IAD: TwbSignature = #$47'IAD';\n  _48_IAD: TwbSignature = #$48'IAD';\n  _49_IAD: TwbSignature = #$49'IAD';\n  _4A_IAD: TwbSignature = #$4A'IAD';\n  _4B_IAD: TwbSignature = #$4B'IAD';\n  _4C_IAD: TwbSignature = #$4C'IAD';\n  _4D_IAD: TwbSignature = #$4D'IAD';\n  _4E_IAD: TwbSignature = #$4E'IAD';\n  _4F_IAD: TwbSignature = #$4F'IAD';\n  _50_IAD: TwbSignature = #$50'IAD';\n  _51_IAD: TwbSignature = #$51'IAD';\n  _52_IAD: TwbSignature = #$52'IAD';\n  _53_IAD: TwbSignature = #$53'IAD';\n  _54_IAD: TwbSignature = #$54'IAD';\n\n{00TX} _00_0TX: TwbSignature = #$30'0TX';\n{10TX} _10_0TX: TwbSignature = #$31'0TX';\n{20TX} _20_0TX: TwbSignature = #$32'0TX';\n{30TX} _30_0TX: TwbSignature = #$33'0TX';\n{40TX} _40_0TX: TwbSignature = #$34'0TX';\n{50TX} _50_0TX: TwbSignature = #$35'0TX';\n{60TX} _60_0TX: TwbSignature = #$36'0TX';\n{70TX} _70_0TX: TwbSignature = #$37'0TX';\n{80TX} _80_0TX: TwbSignature = #$38'0TX';\n{90TX} _90_0TX: TwbSignature = #$39'0TX';\n{:0TX} _3A_0TX: TwbSignature = #$3A'0TX';\n{;0TX} _3B_0TX: TwbSignature = #$3B'0TX';\n{<0TX} _3C_0TX: TwbSignature = #$3C'0TX';\n{=0TX} _3D_0TX: TwbSignature = #$3D'0TX';\n{>0TX} _3E_0TX: TwbSignature = #$3E'0TX';\n{?0TX} _3F_0TX: TwbSignature = #$3F'0TX';\n{@0TX} _40h_0TX: TwbSignature = #$40'0TX';\n{A0TX} A0TX: TwbSignature = 'A0TX';\n{B0TX} B0TX: TwbSignature = 'B0TX';\n{C0TX} C0TX: TwbSignature = 'C0TX';\n{D0TX} D0TX: TwbSignature = 'D0TX';\n{E0TX} E0TX: TwbSignature = 'E0TX';\n{F0TX} F0TX: TwbSignature = 'F0TX';\n{G0TX} G0TX: TwbSignature = 'G0TX';\n{H0TX} H0TX: TwbSignature = 'H0TX';\n{I0TX} I0TX: TwbSignature = 'I0TX';\n{J0TX} J0TX: TwbSignature = 'J0TX';\n{K0TX} K0TX: TwbSignature = 'K0TX';\n{L0TX} L0TX: TwbSignature = 'L0TX';\n\n  AACT : TwbSignature = 'AACT';\n  ACBS : TwbSignature = 'ACBS';\n  ACEC : TwbSignature = 'ACEC'; { New To Dawnguard }\n  ACEP : TwbSignature = 'ACEP'; { New To Dawnguard }\n  ACHR : TwbSignature = 'ACHR';\n  ACID : TwbSignature = 'ACID'; { New To Dawnguard }\n  ACPR : TwbSignature = 'ACPR'; { New To Skyrim }\n  ACSR : TwbSignature = 'ACSR'; { New To Dawnguard }\n  ACTI : TwbSignature = 'ACTI';\n  ACUN : TwbSignature = 'ACUN'; { New To Dawnguard }\n  ADDN : TwbSignature = 'ADDN';\n  AHCF : TwbSignature = 'AHCF'; { New To Skyrim }\n  AHCM : TwbSignature = 'AHCM'; { New To Skyrim }\n  AIDT : TwbSignature = 'AIDT';\n  ALCA : TwbSignature = 'ALCA'; { New To Skyrim }\n  ALCH : TwbSignature = 'ALCH';\n  ALCL : TwbSignature = 'ALCL'; { New To Skyrim }\n  ALCO : TwbSignature = 'ALCO'; { New To Skyrim }\n  ALDN : TwbSignature = 'ALDN'; { New To Skyrim }\n  ALEA : TwbSignature = 'ALEA'; { New To Skyrim }\n  ALED : TwbSignature = 'ALED'; { New To Skyrim }\n  ALEQ : TwbSignature = 'ALEQ'; { New To Skyrim }\n  ALFA : TwbSignature = 'ALFA'; { New To Skyrim }\n  ALFC : TwbSignature = 'ALFC'; { New To Skyrim }\n  ALFD : TwbSignature = 'ALFD'; { New To Skyrim }\n  ALFE : TwbSignature = 'ALFE'; { New To Skyrim }\n  ALFI : TwbSignature = 'ALFI'; { New To Skyrim }\n  ALFL : TwbSignature = 'ALFL'; { New To Skyrim }\n  ALFR : TwbSignature = 'ALFR'; { New To Skyrim }\n  ALID : TwbSignature = 'ALID'; { New To Skyrim }\n  ALLS : TwbSignature = 'ALLS'; { New To Skyrim }\n  ALNA : TwbSignature = 'ALNA'; { New To Skyrim }\n  ALNT : TwbSignature = 'ALNT'; { New To Skyrim }\n  ALPC : TwbSignature = 'ALPC'; { New To Skyrim }\n  ALRT : TwbSignature = 'ALRT'; { New To Skyrim }\n  ALSP : TwbSignature = 'ALSP'; { New To Skyrim }\n  ALST : TwbSignature = 'ALST'; { New To Skyrim }\n  ALUA : TwbSignature = 'ALUA'; { New To Skyrim }\n  AMMO : TwbSignature = 'AMMO';\n  ANAM : TwbSignature = 'ANAM';\n  ANIO : TwbSignature = 'ANIO';\n  APPA : TwbSignature = 'APPA';\n  ARMA : TwbSignature = 'ARMA';\n  ARMO : TwbSignature = 'ARMO';\n  ARTO : TwbSignature = 'ARTO';\n  ASPC : TwbSignature = 'ASPC';\n  ASTP : TwbSignature = 'ASTP';\n  ATKD : TwbSignature = 'ATKD'; { New to Skyrim }\n  ATKE : TwbSignature = 'ATKE'; { New to Skyrim }\n  ATKR : TwbSignature = 'ATKR'; { New to Skyrim }\n  ATXT : TwbSignature = 'ATXT';\n  AVIF : TwbSignature = 'AVIF';\n  AVSK : TwbSignature = 'AVSK'; { New to Skyrim }\n  BAMT : TwbSignature = 'BAMT'; { New to Skyrim }\n  BIDS : TwbSignature = 'BIDS'; { New to Skyrim }\n  BIPL : TwbSignature = 'BIPL';\n  BMCT : TwbSignature = 'BMCT';\n  BNAM : TwbSignature = 'BNAM';\n  BOD2 : TwbSignature = 'BOD2'; { New to Skyrim 1.6.91 CK}\n  BODT : TwbSignature = 'BODT'; { New to Skyrim }\n  BOOK : TwbSignature = 'BOOK';\n  BPND : TwbSignature = 'BPND';\n  BPNI : TwbSignature = 'BPNI';\n  BPNN : TwbSignature = 'BPNN';\n  BPNT : TwbSignature = 'BPNT';\n  BPTD : TwbSignature = 'BPTD';\n  BPTN : TwbSignature = 'BPTN';\n  BTXT : TwbSignature = 'BTXT';\n  CAMS : TwbSignature = 'CAMS';\n  CELL : TwbSignature = 'CELL';\n  CIS1 : TwbSignature = 'CIS1'; { New to Skyrim }\n  CIS2 : TwbSignature = 'CIS2'; { New to Skyrim }\n  CITC : TwbSignature = 'CITC'; { New to Skyrim }\n  CLAS : TwbSignature = 'CLAS';\n  CLDC : TwbSignature = 'CLDC'; { New to Skyrim, but unused }\n  CLFM : TwbSignature = 'CLFM';\n  CLMT : TwbSignature = 'CLMT';\n  CNAM : TwbSignature = 'CNAM';\n  CNTO : TwbSignature = 'CNTO';\n  COBJ : TwbSignature = 'COBJ';\n  COCT : TwbSignature = 'COCT'; { New to Skyrim 'Count'}\n  COED : TwbSignature = 'COED';\n  COLL : TwbSignature = 'COLL';\n  CONT : TwbSignature = 'CONT';\n  CPTH : TwbSignature = 'CPTH';\n  CRDT : TwbSignature = 'CRDT';\n  CRGR : TwbSignature = 'CRGR'; { New to Skyrim }\n  CRIF : TwbSignature = 'CRIF'; { New to Skyrim }\n  CRVA : TwbSignature = 'CRVA'; { New to Skyrim }\n  CSCR : TwbSignature = 'CSCR';\n  CSDC : TwbSignature = 'CSDC';\n  CSDI : TwbSignature = 'CSDI';\n  CSDT : TwbSignature = 'CSDT';\n  CSFL : TwbSignature = 'CSFL'; { New to Skyrim }\n  CSGD : TwbSignature = 'CSGD'; { New to Skyrim }\n  CSLR : TwbSignature = 'CSLR'; { New to Skyrim }\n  CSMD : TwbSignature = 'CSMD'; { New to Skyrim }\n  CSME : TwbSignature = 'CSME'; { New to Skyrim }\n  CSTY : TwbSignature = 'CSTY';\n  CTDA : TwbSignature = 'CTDA';\n  DALC : TwbSignature = 'DALC'; { New to Skyrim }\n  DATA : TwbSignature = 'DATA';\n  DEBR : TwbSignature = 'DEBR';\n  DELE : TwbSignature = 'DELE';\n  DEMO : TwbSignature = 'DEMO'; { New to Skyrim }\n  DESC : TwbSignature = 'DESC';\n  DEST : TwbSignature = 'DEST';\n  DEVA : TwbSignature = 'DEVA'; { New to Skyrim }\n  DFTF : TwbSignature = 'DFTF'; { New To Skyrim }\n  DFTM : TwbSignature = 'DFTM'; { New To Skyrim }\n  DIAL : TwbSignature = 'DIAL';\n  DLBR : TwbSignature = 'DLBR';\n  DLVW : TwbSignature = 'DLVW';\n  DMAX : TwbSignature = 'DMAX'; { New to Skyrim }\n  DMDL : TwbSignature = 'DMDL';\n  DMDS : TwbSignature = 'DMDS'; { New to Skyrim }\n  DMDT : TwbSignature = 'DMDT';\n  DMIN : TwbSignature = 'DMIN'; { New to Skyrim }\n  DNAM : TwbSignature = 'DNAM';\n  DOBJ : TwbSignature = 'DOBJ';\n  DODT : TwbSignature = 'DODT';\n  DOFT : TwbSignature = 'DOFT'; { New to Skyrim }\n  DOOR : TwbSignature = 'DOOR';\n  DPLT : TwbSignature = 'DPLT'; { New to Skyrim }\n  DSTD : TwbSignature = 'DSTD';\n  DSTF : TwbSignature = 'DSTF';\n  DUAL : TwbSignature = 'DUAL';\n  EAMT : TwbSignature = 'EAMT';\n  ECOR : TwbSignature = 'ECOR'; { New to Skyrim }\n  ECZN : TwbSignature = 'ECZN';\n  EDID : TwbSignature = 'EDID';\n  EFID : TwbSignature = 'EFID';\n  EFIT : TwbSignature = 'EFIT';\n  EFSH : TwbSignature = 'EFSH';\n  EITM : TwbSignature = 'EITM';\n  ENAM : TwbSignature = 'ENAM';\n  ENCH : TwbSignature = 'ENCH';\n  ENIT : TwbSignature = 'ENIT';\n  EPF2 : TwbSignature = 'EPF2';\n  EPF3 : TwbSignature = 'EPF3';\n  EPFD : TwbSignature = 'EPFD';\n  EPFT : TwbSignature = 'EPFT';\n  EQUP : TwbSignature = 'EQUP';\n  ESCE : TwbSignature = 'ESCE';\n  ETYP : TwbSignature = 'ETYP';\n  EXPL : TwbSignature = 'EXPL';\n  EYES : TwbSignature = 'EYES';\n  FACT : TwbSignature = 'FACT';\n  FCHT : TwbSignature = 'FCHT'; { New to Skyrim }\n  FLMV : TwbSignature = 'FLMV'; { New to Skyrim }\n  FLOR : TwbSignature = 'FLOR';\n  FLST : TwbSignature = 'FLST';\n  FLTR : TwbSignature = 'FLTR'; { New to Skyrim }\n  FLTV : TwbSignature = 'FLTV';\n  FNAM : TwbSignature = 'FNAM';\n  FNMK : TwbSignature = 'FNMK'; { New to Skyrim }\n  FNPR : TwbSignature = 'FNPR'; { New to Skyrim }\n  FPRT : TwbSignature = 'FPRT'; { New to Skyrim }\n  FSTP : TwbSignature = 'FSTP';\n  FSTS : TwbSignature = 'FSTS';\n  FTSF : TwbSignature = 'FTSF'; { New to Skyrim }\n  FTSM : TwbSignature = 'FTSM'; { New to Skyrim }\n  FTST : TwbSignature = 'FTST'; { New to Skyrim }\n  FULL : TwbSignature = 'FULL';\n  FURN : TwbSignature = 'FURN';\n  GLOB : TwbSignature = 'GLOB';\n  GMST : TwbSignature = 'GMST';\n  GNAM : TwbSignature = 'GNAM';\n  GRAS : TwbSignature = 'GRAS';\n  GWOR : TwbSignature = 'GWOR'; { New to Skyrim }\n  HAIR : TwbSignature = 'HAIR'; { Unused in Skyrim, but contained in Skyrim.esm }\n  HAZD : TwbSignature = 'HAZD';\n  HCLF : TwbSignature = 'HCLF'; { New to Skyrim }\n  HDPT : TwbSignature = 'HDPT';\n  HEAD : TwbSignature = 'HEAD'; { New to Skyrim }\n  HEDR : TwbSignature = 'HEDR';\n  HNAM : TwbSignature = 'HNAM';\n  HTID : TwbSignature = 'HTID'; { New to Skyrim }\n  ICO2 : TwbSignature = 'ICO2';\n  ICON : TwbSignature = 'ICON';\n  IDLA : TwbSignature = 'IDLA';\n  IDLB : TwbSignature = 'IDLB';\n  IDLC : TwbSignature = 'IDLC';\n  IDLE : TwbSignature = 'IDLE';\n  IDLF : TwbSignature = 'IDLF';\n  IDLM : TwbSignature = 'IDLM';\n  IDLT : TwbSignature = 'IDLT';\n  IMAD : TwbSignature = 'IMAD';\n  IMGS : TwbSignature = 'IMGS';\n  IMSP : TwbSignature = 'IMSP'; { New to Skyrim }\n  INAM : TwbSignature = 'INAM';\n  INCC : TwbSignature = 'INCC'; { New to Skyrim }\n  INDX : TwbSignature = 'INDX';\n  INFO : TwbSignature = 'INFO';\n  INGR : TwbSignature = 'INGR';\n  INTV : TwbSignature = 'INTV';\n  IPCT : TwbSignature = 'IPCT';\n  IPDS : TwbSignature = 'IPDS';\n  ITXT : TwbSignature = 'ITXT';\n  JAIL : TwbSignature = 'JAIL'; { New To Skyrim }\n  JNAM : TwbSignature = 'JNAM';\n  JOUT : TwbSignature = 'JOUT'; { New To Skyrim }\n  KEYM : TwbSignature = 'KEYM';\n  KNAM : TwbSignature = 'KNAM';\n  KSIZ : TwbSignature = 'KSIZ';\n  KWDA : TwbSignature = 'KWDA';\n  KYWD : TwbSignature = 'KYWD';\n  LAND : TwbSignature = 'LAND';\n  LCEC : TwbSignature = 'LCEC'; { New to Skyrim }\n  LCEP : TwbSignature = 'LCEP'; { New to Skyrim }\n  LCID : TwbSignature = 'LCID'; { New to Skyrim }\n  LCPR : TwbSignature = 'LCPR'; { New to Skyrim }\n  LCRT : TwbSignature = 'LCRT';\n  LCSR : TwbSignature = 'LCSR'; { New to Skyrim }\n  LCTN : TwbSignature = 'LCTN';\n  LCUN : TwbSignature = 'LCUN'; { New to Skyrim }\n  LENS : TwbSignature = 'LENS'; { New to SSE }\n  LFSD : TwbSignature = 'LFSD'; { New to SSE }\n  LFSP : TwbSignature = 'LFSP'; { New to SSE }\n  LGTM : TwbSignature = 'LGTM';\n  LIGH : TwbSignature = 'LIGH';\n  LLCT : TwbSignature = 'LLCT'; {New to Skyrim, part of LVLI 'Count'}\n  LNAM : TwbSignature = 'LNAM';\n  LSCR : TwbSignature = 'LSCR';\n  LTEX : TwbSignature = 'LTEX';\n  LTMP : TwbSignature = 'LTMP';\n  LVLC : TwbSignature = 'LVLC';\n  LVLD : TwbSignature = 'LVLD';\n  LVLF : TwbSignature = 'LVLF';\n  LVLG : TwbSignature = 'LVLG';\n  LVLI : TwbSignature = 'LVLI';\n  LVLN : TwbSignature = 'LVLN';\n  LVLO : TwbSignature = 'LVLO';\n  LVSP : TwbSignature = 'LVSP';\n  MAST : TwbSignature = 'MAST';\n  MATO : TwbSignature = 'MATO';\n  MATT : TwbSignature = 'MATT';\n  MCHT : TwbSignature = 'MCHT'; { New to Skyrim }\n  MDOB : TwbSignature = 'MDOB';\n  MESG : TwbSignature = 'MESG';\n  MGEF : TwbSignature = 'MGEF';\n  MHDT : TwbSignature = 'MHDT'; { New to Skyrim }\n  MIC2 : TwbSignature = 'MIC2';\n  MICO : TwbSignature = 'MICO';\n  MISC : TwbSignature = 'MISC';\n  MNAM : TwbSignature = 'MNAM';\n  MO2S : TwbSignature = 'MO2S';\n  MO2T : TwbSignature = 'MO2T';\n  MO3S : TwbSignature = 'MO3S';\n  MO3T : TwbSignature = 'MO3T';\n  MO4S : TwbSignature = 'MO4S';\n  MO4T : TwbSignature = 'MO4T';\n  MO5S : TwbSignature = 'MO5S'; { New to Skyrim }\n  MO5T : TwbSignature = 'MO5T'; { New to Skyrim }\n  MOD2 : TwbSignature = 'MOD2';\n  MOD3 : TwbSignature = 'MOD3';\n  MOD4 : TwbSignature = 'MOD4';\n  MOD5 : TwbSignature = 'MOD5'; { New to Skyrim }\n  MODD : TwbSignature = 'MODD';\n  MODL : TwbSignature = 'MODL';\n  MODS : TwbSignature = 'MODS';\n  MODT : TwbSignature = 'MODT';\n  MOVT : TwbSignature = 'MOVT';\n  MPAI : TwbSignature = 'MPAI'; { New To Skyrim }\n  MPAV : TwbSignature = 'MPAV'; { New To Skyrim }\n  MPRT : TwbSignature = 'MPRT'; { New to Skyrim }\n  MSTT : TwbSignature = 'MSTT';\n  MTNM : TwbSignature = 'MTNM'; { New to Skyrim }\n  MTYP : TwbSignature = 'MTYP'; { New To Skyrim }\n  MUSC : TwbSignature = 'MUSC';\n  MUST : TwbSignature = 'MUST';\n  NAM0 : TwbSignature = 'NAM0';\n  NAM1 : TwbSignature = 'NAM1';\n  NAM2 : TwbSignature = 'NAM2';\n  NAM3 : TwbSignature = 'NAM3';\n  NAM4 : TwbSignature = 'NAM4';\n  NAM5 : TwbSignature = 'NAM5';\n  NAM6 : TwbSignature = 'NAM6';\n  NAM7 : TwbSignature = 'NAM7';\n  NAM8 : TwbSignature = 'NAM8';\n  NAM9 : TwbSignature = 'NAM9';\n  NAMA : TwbSignature = 'NAMA'; { New to Skyrim }\n  NAME : TwbSignature = 'NAME';\n  NAVI : TwbSignature = 'NAVI';\n  NAVM : TwbSignature = 'NAVM';\n  NEXT : TwbSignature = 'NEXT';\n  NNAM : TwbSignature = 'NNAM';\n  NPC_ : TwbSignature = 'NPC_';\n  NULL : TwbSignature = 'NULL';\n  NVER : TwbSignature = 'NVER';\n  NVMI : TwbSignature = 'NVMI';\n  NVNM : TwbSignature = 'NVNM'; { New to Skyrim }\n  NVPP : TwbSignature = 'NVPP'; { New to Skyrim }\n  NVSI : TwbSignature = 'NVSI'; { New to Dawnguard }\n  OBND : TwbSignature = 'OBND';\n  OCOR : TwbSignature = 'OCOR'; { New to Skyrim }\n  OFST : TwbSignature = 'OFST';\n  ONAM : TwbSignature = 'ONAM';\n  OTFT : TwbSignature = 'OTFT';\n  PACK : TwbSignature = 'PACK';\n  PARW : TwbSignature = 'PARW'; { New to Skyrim }\n  PBAR : TwbSignature = 'PBAR'; { New to Skyrim }\n  PBEA : TwbSignature = 'PBEA'; { New to Skyrim }\n  PCON : TwbSignature = 'PCON'; { New to Skyrim }\n  PDTO : TwbSignature = 'PDTO'; { New to Skyrim }\n  PERK : TwbSignature = 'PERK';\n  PFIG : TwbSignature = 'PFIG';\n  PFLA : TwbSignature = 'PFLA'; { New to Skyrim }\n  PFO2 : TwbSignature = 'PFO2'; { New to Skyrim }\n  PFOR : TwbSignature = 'PFOR'; { New to Skyrim }\n  PFPC : TwbSignature = 'PFPC';\n  PGRE : TwbSignature = 'PGRE';\n  PHTN : TwbSignature = 'PHTN'; { New to Skyrim }\n  PHWT : TwbSignature = 'PHWT'; { New to Skyrim }\n  PHZD : TwbSignature = 'PHZD';\n  PKC2 : TwbSignature = 'PKC2'; { New to Skyrim }\n  PKCU : TwbSignature = 'PKCU'; { New to Skyrim }\n  PKDT : TwbSignature = 'PKDT';\n  PKID : TwbSignature = 'PKID';\n  PLCN : TwbSignature = 'PLCN'; { New to Skyrim }\n  PLDT : TwbSignature = 'PLDT';\n  PLVD : TwbSignature = 'PLVD'; { New to Skyrim }\n  PLYR : TwbSignature = 'PLYR';\n  PMIS : TwbSignature = 'PMIS';\n  PNAM : TwbSignature = 'PNAM';\n  POBA : TwbSignature = 'POBA';\n  POCA : TwbSignature = 'POCA';\n  POEA : TwbSignature = 'POEA';\n  PRCB : TwbSignature = 'PRCB'; { New to Skyrim }\n  PRKC : TwbSignature = 'PRKC';\n  PRKE : TwbSignature = 'PRKE';\n  PRKF : TwbSignature = 'PRKF';\n  PRKR : TwbSignature = 'PRKR'; { New to Skyrim }\n  PRKZ : TwbSignature = 'PRKZ'; { New to Skyrim }\n  PROJ : TwbSignature = 'PROJ';\n  PSDT : TwbSignature = 'PSDT';\n  PTDA : TwbSignature = 'PTDA'; { New to Skyrim }\n  PWAT : TwbSignature = 'PWAT'; { Unused in Skyrim, but contained in Skyrim.esm }\n  QNAM : TwbSignature = 'QNAM';\n  QOBJ : TwbSignature = 'QOBJ';\n  QSDT : TwbSignature = 'QSDT';\n  QSTA : TwbSignature = 'QSTA';\n  QTGL : TwbSignature = 'QTGL'; { New To Skyrim }\n  QUAL : TwbSignature = 'QUAL'; { New To Skyrim }\n  QUST : TwbSignature = 'QUST';\n  RACE : TwbSignature = 'RACE';\n  RCEC : TwbSignature = 'RCEC'; { New To Skyrim }\n  RCLR : TwbSignature = 'RCLR';\n  RCPR : TwbSignature = 'RCPR'; { New to Dawnguard }\n  RCSR : TwbSignature = 'RCSR'; { New To Skyrim }\n  RCUN : TwbSignature = 'RCUN'; { New To Skyrim }\n  RDAT : TwbSignature = 'RDAT';\n  RDGS : TwbSignature = 'RDGS';\n  RDMO : TwbSignature = 'RDMO';\n  RDMP : TwbSignature = 'RDMP';\n  RDOT : TwbSignature = 'RDOT';\n  RDSA : TwbSignature = 'RDSA'; { New to Skyrim }\n  RDWT : TwbSignature = 'RDWT';\n  REFR : TwbSignature = 'REFR';\n  REGN : TwbSignature = 'REGN';\n  RELA : TwbSignature = 'RELA';\n  REPL : TwbSignature = 'REPL';\n  RGDL : TwbSignature = 'RGDL';{ Unused in Skyrim, but contained in Skyrim.esm }\n  REVB : TwbSignature = 'REVB';\n  RFCT : TwbSignature = 'RFCT';\n  RNAM : TwbSignature = 'RNAM';\n  RNMV : TwbSignature = 'RNMV'; { New to Skyrim }\n  RPLD : TwbSignature = 'RPLD';\n  RPLI : TwbSignature = 'RPLI';\n  RPRF : TwbSignature = 'RPRF'; { New To Skyrim }\n  RPRM : TwbSignature = 'RPRM'; { New To Skyrim }\n  SCDA : TwbSignature = 'SCDA';\n  SCEN : TwbSignature = 'SCEN';\n  SCHR : TwbSignature = 'SCHR';\n  SCOL : TwbSignature = 'SCOL'; { Unused in Skyrim, but contained in Skyrim.esm }\n  SCPT : TwbSignature = 'SCPT'; { Unused in Skyrim, but contained in Skyrim.esm }\n  SCRL : TwbSignature = 'SCRL';\n  SCRN : TwbSignature = 'SCRN';\n  SCRO : TwbSignature = 'SCRO';\n  SCTX : TwbSignature = 'SCTX';\n  SDSC : TwbSignature = 'SDSC'; { New to Skyrim }\n  SHOU : TwbSignature = 'SHOU';\n  SHRT : TwbSignature = 'SHRT'; { New to Skyrim }\n  SLCP : TwbSignature = 'SLCP';\n  SLGM : TwbSignature = 'SLGM';\n  SMBN : TwbSignature = 'SMBN';\n  SMEN : TwbSignature = 'SMEN';\n  SMQN : TwbSignature = 'SMQN';\n  SNAM : TwbSignature = 'SNAM';\n  SNCT : TwbSignature = 'SNCT';\n  SNDD : TwbSignature = 'SNDD';\n  SNDR : TwbSignature = 'SNDR';\n  SNMV : TwbSignature = 'SNMV'; { New to Skyrim }\n  SOFT : TwbSignature = 'SOFT'; { New to Skyrim }\n  SOPM : TwbSignature = 'SOPM';\n  SOUL : TwbSignature = 'SOUL';\n  SOUN : TwbSignature = 'SOUN';\n  SPCT : TwbSignature = 'SPCT'; { New to Skyrim }\n  SPED : TwbSignature = 'SPED'; { New To Skyrim }\n  SPEL : TwbSignature = 'SPEL';\n  SPGD : TwbSignature = 'SPGD';\n  SPIT : TwbSignature = 'SPIT';\n  SPLO : TwbSignature = 'SPLO';\n  SPMV : TwbSignature = 'SPMV'; { New To Skyrim }\n  SPOR : TwbSignature = 'SPOR'; { New to Skyrim }\n  STAT : TwbSignature = 'STAT';\n  STOL : TwbSignature = 'STOL'; { New to Skyrim }\n  SWMV : TwbSignature = 'SWMV'; { New to Skyrim }\n  TACT : TwbSignature = 'TACT';\n  TCLT : TwbSignature = 'TCLT';\n  TES4 : TwbSignature = 'TES4';\n  TIAS : TwbSignature = 'TIAS'; { New to Skyrim }\n  TIFC : TwbSignature = 'TIFC'; { New To Skyrim }\n  TINC : TwbSignature = 'TINC'; { New to Skyrim }\n  TIND : TwbSignature = 'TIND'; { New to Skyrim }\n  TINI : TwbSignature = 'TINI'; { New to Skyrim }\n  TINL : TwbSignature = 'TINL'; { New to Skyrim }\n  TINP : TwbSignature = 'TINP'; { New to Skyrim }\n  TINT : TwbSignature = 'TINT'; { New to Skyrim }\n  TINV : TwbSignature = 'TINV'; { New to Skyrim }\n  TIRS : TwbSignature = 'TIRS'; { New to Skyrim }\n  TNAM : TwbSignature = 'TNAM';\n  TPIC : TwbSignature = 'TPIC';\n  TPLT : TwbSignature = 'TPLT';\n  TRDT : TwbSignature = 'TRDT';\n  TREE : TwbSignature = 'TREE';\n  TVDT : TwbSignature = 'TVDT'; { New To Skyrim }\n  TWAT : TwbSignature = 'TWAT'; { New To Skyrim }\n  TX00 : TwbSignature = 'TX00';\n  TX01 : TwbSignature = 'TX01';\n  TX02 : TwbSignature = 'TX02';\n  TX03 : TwbSignature = 'TX03';\n  TX04 : TwbSignature = 'TX04';\n  TX05 : TwbSignature = 'TX05';\n  TX06 : TwbSignature = 'TX06'; { New To Skyrim }\n  TX07 : TwbSignature = 'TX07'; { New To Skyrim }\n  TXST : TwbSignature = 'TXST';\n  UNAM : TwbSignature = 'UNAM';\n  UNES : TwbSignature = 'UNES'; { New To Skyrim }\n  VATS : TwbSignature = 'VATS';\n  VCLR : TwbSignature = 'VCLR';\n  VENC : TwbSignature = 'VENC'; { New To Skyrim }\n  VEND : TwbSignature = 'VEND'; { New To Skyrim }\n  VENV : TwbSignature = 'VENV'; { New To Skyrim }\n  VHGT : TwbSignature = 'VHGT';\n  VMAD : TwbSignature = 'VMAD';\n  VNAM : TwbSignature = 'VNAM';\n  VNML : TwbSignature = 'VNML';\n  VOLI : TwbSignature = 'VOLI'; { New To SSE }\n  VTCK : TwbSignature = 'VTCK';\n  VTEX : TwbSignature = 'VTEX';\n  VTXT : TwbSignature = 'VTXT';\n  VTYP : TwbSignature = 'VTYP';\n  WAIT : TwbSignature = 'WAIT'; { New To Skyrim }\n  WATR : TwbSignature = 'WATR';\n  WBDT : TwbSignature = 'WBDT'; { New to Skyrim }\n  WCTR : TwbSignature = 'WCTR'; { New To Skyrim }\n  WEAP : TwbSignature = 'WEAP';\n  WKMV : TwbSignature = 'WKMV'; { New to Skyrim }\n  WLST : TwbSignature = 'WLST';\n  WNAM : TwbSignature = 'WNAM';\n  WOOP : TwbSignature = 'WOOP';\n  WRLD : TwbSignature = 'WRLD';\n  WTHR : TwbSignature = 'WTHR';\n  XACT : TwbSignature = 'XACT';\n  XALP : TwbSignature = 'XALP'; { New To Skyrim }\n  XAPD : TwbSignature = 'XAPD';\n  XAPR : TwbSignature = 'XAPR';\n  XATR : TwbSignature = 'XATR'; { New To Dawnguard }\n  XCAS : TwbSignature = 'XCAS';\n  XCCM : TwbSignature = 'XCCM';\n  XCHG : TwbSignature = 'XCHG';\n  XCIM : TwbSignature = 'XCIM';\n  XCLC : TwbSignature = 'XCLC';\n  XCLL : TwbSignature = 'XCLL';\n  XCLP : TwbSignature = 'XCLP';\n  XCLR : TwbSignature = 'XCLR';\n  XCLW : TwbSignature = 'XCLW';\n  XCMO : TwbSignature = 'XCMO';\n  XCNT : TwbSignature = 'XCNT';\n  XCVL : TwbSignature = 'XCVL'; { New To Skyrim }\n  XCWT : TwbSignature = 'XCWT';\n  XCZA : TwbSignature = 'XCZA'; { New To Skyrim }\n  XCZC : TwbSignature = 'XCZC'; { New To Skyrim }\n  XCZR : TwbSignature = 'XCZR'; { New To Skyrim }\n  XDCR : TwbSignature = 'XDCR';\n  XEMI : TwbSignature = 'XEMI';\n  XESP : TwbSignature = 'XESP';\n  XEZN : TwbSignature = 'XEZN';\n  XFVC : TwbSignature = 'XFVC'; { New To Skyrim }\n  XGLB : TwbSignature = 'XGLB';\n  XHLP : TwbSignature = 'XHLP';\n  XHOR : TwbSignature = 'XHOR'; { New To Skyrim }\n  XHTW : TwbSignature = 'XHTW'; { New To Skyrim }\n  XIBS : TwbSignature = 'XIBS';\n  XILL : TwbSignature = 'XILL'; { New To Skyrim }\n  XIS2 : TwbSignature = 'XIS2'; { New To Skyrim }\n  XLCM : TwbSignature = 'XLCM';\n  XLCN : TwbSignature = 'XLCN'; { New To Skyrim }\n  XLIB : TwbSignature = 'XLIB'; { New To Skyrim }\n  XLIG : TwbSignature = 'XLIG'; { New To Skyrim }\n  XLKR : TwbSignature = 'XLKR';\n  XLOC : TwbSignature = 'XLOC';\n  XLOD : TwbSignature = 'XLOD';\n  XLRL : TwbSignature = 'XLRL'; { New To Skyrim }\n  XLRM : TwbSignature = 'XLRM';\n  XLRT : TwbSignature = 'XLRT'; { New To Skyrim }\n  XLTW : TwbSignature = 'XLTW';\n  XMBO : TwbSignature = 'XMBO';\n  XMBP : TwbSignature = 'XMBP';\n  XMBR : TwbSignature = 'XMBR';\n  XMRC : TwbSignature = 'XMRC';\n  XMRK : TwbSignature = 'XMRK';\n  XNAM : TwbSignature = 'XNAM';\n  XNDP : TwbSignature = 'XNDP';\n  XOCP : TwbSignature = 'XOCP';\n  XORD : TwbSignature = 'XORD';\n  XOWN : TwbSignature = 'XOWN';\n  XPOD : TwbSignature = 'XPOD';\n  XPPA : TwbSignature = 'XPPA';\n  XPRD : TwbSignature = 'XPRD';\n  XPRM : TwbSignature = 'XPRM';\n  XPTL : TwbSignature = 'XPTL';\n  XPWR : TwbSignature = 'XPWR';\n  XRDS : TwbSignature = 'XRDS';\n  XRGB : TwbSignature = 'XRGB';\n  XRGD : TwbSignature = 'XRGD';\n  XRMR : TwbSignature = 'XRMR';\n  XRNK : TwbSignature = 'XRNK';\n  XSCL : TwbSignature = 'XSCL';\n  XSPC : TwbSignature = 'XSPC'; { New To Skyrim }\n  XTEL : TwbSignature = 'XTEL';\n  XTNM : TwbSignature = 'XTNM'; { New To Skyrim }\n  XTRI : TwbSignature = 'XTRI';\n  XWEM : TwbSignature = 'XWEM'; { New To Skyrim }\n  XWCN : TwbSignature = 'XWCN'; { New To Skyrim }\n  XWCS : TwbSignature = 'XWCS'; { New To Skyrim }\n  XWCU : TwbSignature = 'XWCU'; { New To Skyrim }\n  XXXX : TwbSignature = 'XXXX';\n  YNAM : TwbSignature = 'YNAM';\n  ZNAM : TwbSignature = 'ZNAM';\n\nvar\n  wbPKDTSpecificFlagsUnused : Boolean;\n  wbEDID: IwbSubRecordDef;\n  wbCOED: IwbSubRecordDef;\n  wbXLCM: IwbSubRecordDef;\n  wbEITM: IwbSubRecordDef;\n  wbOBND: IwbSubRecordDef;\n  wbOBNDReq: IwbSubRecordDef;\n  wbDEST: IwbSubRecordStructDef;\n  wbDESTActor: IwbSubRecordStructDef;\n  wbDODT: IwbSubRecordDef;\n  wbXGLB: IwbSubRecordDef;\n  wbXRGD: IwbSubRecordDef;\n  wbXRGB: IwbSubRecordDef;\n  wbSPLO: IwbSubRecordDef;\n  wbSPLOs: IwbSubRecordArrayDef;\n  wbCNTO: IwbSubRecordStructDef;\n  wbCNTOs: IwbSubRecordArrayDef;\n  wbAIDT: IwbSubRecordDef;\n  wbCSDT: IwbSubRecordStructDef;\n  wbCSDTs: IwbSubRecordArrayDef;\n  wbFULL: IwbSubRecordDef;\n  wbFULLActor: IwbSubRecordDef;\n  wbFULLReq: IwbSubRecordDef;\n  wbDESC: IwbSubRecordDef;\n  wbDESCReq: IwbSubRecordDef;\n  wbXSCL: IwbSubRecordDef;\n  wbDATAPosRot: IwbSubRecordDef;\n  wbPosRot: IwbStructDef;\n  wbMODD: IwbSubRecordDef;\n  wbMODL: IwbSubRecordStructDef;\n  wbMODS: IwbSubRecordDef;\n  wbMO2S: IwbSubRecordDef;\n  wbMO3S: IwbSubRecordDef;\n  wbMO4S: IwbSubRecordDef;\n  wbMODLActor: IwbSubRecordStructDef;\n  wbMODLReq: IwbSubRecordStructDef;\n  wbCTDA: IwbSubRecordStructDef;\n  wbCTDAs: IwbSubRecordArrayDef;\n  wbCTDAsReq: IwbSubRecordArrayDef;\n  wbCTDAsCount: IwbSubRecordArrayDef;\n  wbCTDAsReqCount: IwbSubRecordArrayDef;\n  wbXLOD: IwbSubRecordDef;\n  wbXESP: IwbSubRecordDef;\n  wbICON: IwbSubRecordStructDef;\n  wbICONReq: IwbSubRecordStructDef;\n  wbICO2: IwbSubRecordStructDef;\n  wbActorValue: IwbIntegerDef;\n  wbETYP: IwbSubRecordDef;\n  wbETYPReq: IwbSubRecordDef;\n  wbEFID: IwbSubRecordDef;\n  wbEFIT: IwbSubRecordDef;\n  wbEffectsReq: IwbSubRecordArrayDef;\n  wbFirstPersonFlagsU32: IwbIntegerDef;\n  wbBODT: IwbSubRecordDef;\n  wbBOD2: IwbSubRecordDef;\n  wbBODTBOD2: IwbSubRecordUnionDef;\n  wbScriptEntry: IwbStructDef;\n  wbScriptFlags: IwbIntegerDef;\n  wbScriptPropertyObject: IwbUnionDef;\n\twbScriptProperties: IwbArrayDef;\n  wbScriptFragments: IwbStructDef;\n  wbScriptFragmentsQuest: IwbStructDef;\n  wbScriptFragmentsInfo: IwbStructDef;\n  wbScriptFragmentsPack: IwbStructDef;\n  wbScriptFragmentsScen: IwbStructDef;\n  wbPLDT: IwbSubRecordDef;\n  wbPLVD: IwbSubRecordDef;\n  wbTargetData: IwbStructDef;\n  wbAttackData: IwbSubRecordStructDef;\n  wbLLCT: IwbSubRecordDef;\n  wbLVLD: IwbSubRecordDef;\n  wbVMAD: IwbSubRecordDef;\n  wbVMADFragmentedPERK: IwbSubRecordDef;\n  wbVMADFragmentedPACK: IwbSubRecordDef;\n  wbVMADFragmentedQUST: IwbSubRecordDef;\n  wbVMADFragmentedSCEN: IwbSubRecordDef;\n  wbVMADFragmentedINFO: IwbSubRecordDef;\n  wbCOCT: IwbSubRecordDef;\n  wbKSIZ: IwbSubRecordDef;\n  wbKWDAs: IwbSubRecordDef;\n  wbReqKWDAs: IwbSubRecordDef;\n  wbKeywords: IwbSubRecordStructDef;\n  wbCNAM: IwbSubRecordDef;\n  wbCNAMReq: IwbSubRecordDef;\n  wbCITC: IwbSubRecordDef;\n  wbMGEFData: IwbSubRecordStructDef;\n  wbMGEFType: IwbIntegerDef;\n  wbMDOB: IwbSubRecordDef;\n  wbSPIT: IwbSubRecordDef;\n  wbDMDSs: IwbSubRecordDef;\n  wbMO5S: IwbSubRecordDef;\n  wbSPCT: IwbSubRecordDef;\n  wbTints: IwbSubRecordArrayDef;\n  wbMODT: IwbSubRecordDef;\n  wbDMDT: IwbSubRecordDef;\n  wbOwnership: IwbSubRecordStructDef;\n  wbRACE_DATAFlags01: IwbIntegerDef;\n  wbPhonemeTargets: IwbSubRecordDef;\n  wbNoseMorphFlags: IwbIntegerDef;\n  wbBrowMorphFlags: IwbIntegerDef;\n  wbEyesMorphFlags01: IwbIntegerDef;\n  wbEyesMorphFlags02: IwbIntegerDef;\n  wbLipMorphFlags: IwbIntegerDef;\n  wbPHWT: IwbSubRecordStructDef;\n  wbMorphs: IwbSubRecordStructDef;\n  wbHeadPart: IwbSubRecordStructDef;\n  wbQUSTAliasFlags: IwbSubRecordDef;\n  wbPDTO: IwbSubRecordDef;\n  wbPDTOs: IwbSubRecordArrayDef;\n  wbUNAMs: IwbSubRecordArrayDef;\n  wbNull: IwbValueDef;\n  wbTimeInterpolator: IwbStructDef;\n  wbColorInterpolator: IwbStructDef;\n  wbYNAM: IwbSubRecordDef;\n  wbZNAM: IwbSubRecordDef;\n  wbMaxHeightDataCELL: IwbSubRecordDef;\n  wbMaxHeightDataWRLD: IwbSubRecordDef;\n  wbTVDT: IwbSubRecordDef;\n  wbOFST: IwbSubRecordDef;\n  wbNVNM: IwbSubRecordDef;\n  wbNAVIslandData: IwbStructDef;\n\n\nfunction IsSSE: Boolean; inline; overload;\nbegin\n  Result := wbGameMode = gmSSE;\nend;\n\nfunction IsSSE(const aDef1, aDef2: String): String; inline; overload;\nbegin\n  if IsSSE then\n    Result := aDef1\n  else\n    Result := aDef2;\nend;\n\nfunction IsSSE(const aDef1, aDef2: IwbSubRecordDef): IwbSubRecordDef; inline; overload;\nbegin\n  if IsSSE then\n    Result := aDef1\n  else\n    Result := aDef2;\nend;\n\n\nfunction Sig2Int(aSignature: TwbSignature): Cardinal; inline;\nbegin\n  Result := PCardinal(@aSignature)^;\nend;\n\nfunction wbEPFDActorValueToStr(aInt: Int64; const aElement: IwbElement; aType: TwbCallbackType): string;\nvar\n  AsCardinal : Cardinal;\n  AsFloat    : Single;\nbegin\n  AsCardinal := aInt;\n  AsFloat := PSingle(@AsCardinal)^;\n  aInt := Round(AsFloat);\n  case aType of\n    ctToStr: Result := wbActorValueEnum.ToString(aInt, aElement);\n    ctToSortKey: Result := wbActorValueEnum.ToSortKey(aInt, aElement);\n    ctCheck: Result := wbActorValueEnum.Check(aInt, aElement);\n    ctToEditValue: Result := wbActorValueEnum.ToEditValue(aInt, aElement);\n    ctEditType: Result := 'ComboBox';\n    ctEditInfo: Result := wbActorValueEnum.EditInfo[aInt, aElement];\n  end;\nend;\n\nfunction wbEPFDActorValueToInt(const aString: string; const aElement: IwbElement): Int64;\nvar\n  AsCardinal : Cardinal;\n  AsFloat    : Single;\nbegin\n  AsFloat := wbActorValueEnum.FromEditValue(aString, aElement);\n  PSingle(@AsCardinal)^ := AsFloat;\n  Result := AsCardinal;\nend;\n\nfunction wbCTDAParam2QuestStageToStr(aInt: Int64; const aElement: IwbElement; aType: TwbCallbackType): string;\nvar\n  Container  : IwbContainerElementRef;\n  Param1     : IwbElement;\n  MainRecord : IwbMainRecord;\n  EditInfos  : TStringList;\n  Stages     : IwbContainerElementRef;\n  Stage      : IwbContainerElementRef;\n  i, j       : Integer;\n  s, t       : string;\nbegin\n  case aType of\n    ctToStr: Result := IntToStr(aInt) + ' <Warning: Could not resolve Parameter 1>';\n    ctToEditValue: Result := IntToStr(aInt);\n    ctToSortKey: begin\n      Result := IntToHex64(aInt, 8);\n      Exit;\n    end;\n    ctCheck: Result := '<Warning: Could not resolve Parameter 1>';\n    ctEditType: Result := '';\n    ctEditInfo: Result := '';\n  end;\n\n  if not Assigned(aElement) then Exit;\n  Container := GetContainerRefFromUnionOrValue(aElement);\n  if not Assigned(Container) then Exit;\n\n  Param1 := Container.ElementByName['Parameter #1'];\n\n  if not Assigned(Param1) then\n    Exit;\n\n  if not Supports(Param1.LinksTo, IwbMainRecord, MainRecord) then\n    Exit;\n\n  MainRecord := MainRecord.WinningOverride;\n\n  if MainRecord.Signature <> QUST then begin\n    case aType of\n      ctToStr: Result := IntToStr(aInt) + ' <Warning: \"'+MainRecord.ShortName+'\" is not a Quest record>';\n      ctCheck: Result := '<Warning: \"'+MainRecord.ShortName+'\" is not a Quest record>';\n    end;\n    Exit;\n  end;\n\n  case aType of\n    ctEditType: begin\n      Result := 'ComboBox';\n      Exit;\n    end;\n    ctEditInfo:\n      EditInfos := TStringList.Create;\n  else\n    EditInfos := nil;\n  end;\n  try\n    if Supports(MainRecord.ElementByName['Stages'], IwbContainerElementRef, Stages) then begin\n      for i := 0 to Pred(Stages.ElementCount) do\n        if Supports(Stages.Elements[i], IwbContainerElementRef, Stage) then begin\n          j := Stage.ElementNativeValues['INDX\\Stage Index'];\n          s := Trim(Stage.ElementValues['Log Entries\\Log Entry\\CNAM']);\n          t := IntToStr(j);\n          while Length(t) < 3 do\n            t := '0' + t;\n          if s <> '' then\n            t := t + ' ' + s;\n          if Assigned(EditInfos) then\n            EditInfos.AddObject(t, TObject(j))\n          else if j = aInt then begin\n            case aType of\n              ctToStr, ctToEditValue: Result := t;\n              ctCheck: Result := '';\n            end;\n            Exit;\n          end;\n        end;\n    end;\n\n    case aType of\n      ctToStr: Result := IntToStr(aInt) + ' <Warning: Quest Stage not found in \"' + MainRecord.Name + '\">';\n      ctCheck: Result := '<Warning: Quest Stage not found in \"' + MainRecord.Name + '\">';\n      ctEditInfo: begin\n        EditInfos.Sort;\n        Result := EditInfos.CommaText;\n      end;\n    end;\n  finally\n    FreeAndNil(EditInfos);\n  end;\nend;\n\nfunction wbPerkDATAQuestStageToStr(aInt: Int64; const aElement: IwbElement; aType: TwbCallbackType): string;\nvar\n  Container  : IwbContainerElementRef;\n  Param1     : IwbElement;\n  MainRecord : IwbMainRecord;\n  EditInfos  : TStringList;\n  Stages     : IwbContainerElementRef;\n  Stage      : IwbContainerElementRef;\n  i, j       : Integer;\n  s, t       : string;\nbegin\n  case aType of\n    ctToStr: Result := IntToStr(aInt) + ' <Warning: Could not resolve Quest>';\n    ctToEditValue: Result := IntToStr(aInt);\n    ctToSortKey: begin\n      Result := IntToHex64(aInt, 8);\n      Exit;\n    end;\n    ctCheck: Result := '<Warning: Could not resolve Quest>';\n    ctEditType: Result := '';\n    ctEditInfo: Result := '';\n  end;\n\n  if not Assigned(aElement) then Exit;\n  Container := GetContainerRefFromUnionOrValue(aElement);\n  if not Assigned(Container) then Exit;\n\n  Param1 := Container.ElementByName['Quest'];\n\n  if not Assigned(Param1) then\n    Exit;\n\n  if not Supports(Param1.LinksTo, IwbMainRecord, MainRecord) then\n    Exit;\n\n  MainRecord := MainRecord.WinningOverride;\n\n  if MainRecord.Signature <> QUST then begin\n    case aType of\n      ctToStr: Result := IntToStr(aInt) + ' <Warning: \"'+MainRecord.ShortName+'\" is not a Quest record>';\n      ctCheck: Result := '<Warning: \"'+MainRecord.ShortName+'\" is not a Quest record>';\n    end;\n    Exit;\n  end;\n\n  case aType of\n    ctEditType: begin\n      Result := 'ComboBox';\n      Exit;\n    end;\n    ctEditInfo:\n      EditInfos := TStringList.Create;\n  else\n    EditInfos := nil;\n  end;\n  try\n    if Supports(MainRecord.ElementByName['Stages'], IwbContainerElementRef, Stages) then begin\n      for i := 0 to Pred(Stages.ElementCount) do\n        if Supports(Stages.Elements[i], IwbContainerElementRef, Stage) then begin\n          j := Stage.ElementNativeValues['INDX\\Stage Index'];\n          s := Trim(Stage.ElementValues['Log Entries\\Log Entry\\CNAM']);\n          t := IntToStr(j);\n          while Length(t) < 3 do\n            t := '0' + t;\n          if s <> '' then\n            t := t + ' ' + s;\n          if Assigned(EditInfos) then\n            EditInfos.AddObject(t, TObject(j))\n          else if j = aInt then begin\n            case aType of\n              ctToStr, ctToEditValue: Result := t;\n              ctCheck: Result := '';\n            end;\n            Exit;\n          end;\n        end;\n    end;\n\n    case aType of\n      ctToStr: Result := IntToStr(aInt) + ' <Warning: Quest Stage not found in \"' + MainRecord.Name + '\">';\n      ctCheck: Result := '<Warning: Quest Stage not found in \"' + MainRecord.Name + '\">';\n      ctEditInfo: begin\n        EditInfos.Sort;\n        Result := EditInfos.CommaText;\n      end;\n    end;\n  finally\n    FreeAndNil(EditInfos);\n  end;\nend;\n\nfunction wbCTDAParam2QuestStageToInt(const aString: string; const aElement: IwbElement): Int64;\nvar\n  i    : Integer;\n  s    : string;\nbegin\n  i := 1;\n  s := Trim(aString);\n  while (i <= Length(s)) and (s[i] in ['0'..'9']) do\n    Inc(i);\n  s := Copy(s, 1, Pred(i));\n\n  Result := StrToInt(s);\nend;\n\nfunction wbREFRNavmeshTriangleToStr(aInt: Int64; const aElement: IwbElement; aType: TwbCallbackType): string;\nvar\n  Container  : IwbContainerElementRef;\n  Navmesh    : IwbElement;\n  MainRecord : IwbMainRecord;\n  Triangles  : IwbContainerElementRef;\nbegin\n  case aType of\n    ctToStr: Result := IntToStr(aInt);\n    ctToEditValue: Result := IntToStr(aInt);\n    ctToSortKey: begin\n      Result := IntToHex64(aInt, 8);\n      Exit;\n    end;\n    ctCheck: Result := '';\n    ctEditType: Result := '';\n    ctEditInfo: Result := '';\n  end;\n\n  if not Assigned(aElement) then Exit;\n  Container := GetContainerRefFromUnionOrValue(aElement);\n  if not Assigned(Container) then Exit;\n\n  Navmesh := Container.Elements[0];\n\n  if not Assigned(Navmesh) then\n    Exit;\n\n  if not Supports(Navmesh.LinksTo, IwbMainRecord, MainRecord) then\n    Exit;\n\n  MainRecord := MainRecord.WinningOverride;\n\n  if MainRecord.Signature <> NAVM then begin\n    case aType of\n      ctToStr: Result := IntToStr(aInt) + ' <Warning: \"'+MainRecord.ShortName+'\" is not a Navmesh record>';\n      ctCheck: Result := '<Warning: \"'+MainRecord.ShortName+'\" is not a Navmesh record>';\n    end;\n    Exit;\n  end;\n\n  if Supports(MainRecord.ElementByPath['NVNM\\Triangles'], IwbContainerElementRef, Triangles) and (aType = ctCheck) then\n    if aInt >= Triangles.ElementCount then\n      Result := '<Warning: Navmesh triangle not found in \"' + MainRecord.Name + '\">';\nend;\n\nfunction wbStringToInt(const aString: string; const aElement: IwbElement): Int64;\nbegin\n  Result := StrToIntDef(aString, 0);\nend;\n\n\n{ Alias to string conversion, requires quest reference or quest record specific to record that references alias }\nfunction wbAliasToStr(aInt: Int64; const aQuestRef: IwbElement; aType: TwbCallbackType): string;\nvar\n  MainRecord : IwbMainRecord;\n  EditInfos  : TStringList;\n  Aliases    : IwbContainerElementRef;\n  Alias      : IwbContainerElementRef;\n  i, j       : Integer;\n  s, t       : string;\nbegin\n  case aType of\n    ctToStr: if aInt = -1 then Result := 'None' else\n      Result := IntToStr(aInt) + ' <Warning: Could not resolve alias>';\n    ctToEditValue: if aInt = -1 then Result := 'None' else\n      Result := IntToStr(aInt);\n    ctToSortKey: begin\n      Result := IntToHex64(aInt, 8);\n      Exit;\n    end;\n    ctCheck: if aInt = -1 then Result := '' else\n      Result := '<Warning: Could not resolve alias>';\n    ctEditType: Result := '';\n    ctEditInfo: Result := '';\n  end;\n\n  if (aInt = -1) and (aType <> ctEditType) and (aType <> ctEditInfo) then\n    Exit;\n\n  if not Assigned(aQuestRef) then\n    Exit;\n\n  // aQuestRef can be a QUST record or reference to QUST record\n  if not Supports(aQuestRef, IwbMainRecord, MainRecord) then\n    if not Supports(aQuestRef.LinksTo, IwbMainRecord, MainRecord) then\n      Exit;\n\n  MainRecord := MainRecord.WinningOverride;\n\n  if MainRecord.Signature <> QUST then begin\n    case aType of\n      ctToStr: Result := IntToStr(aInt) + ' <Warning: \"' + MainRecord.ShortName + '\" is not a Quest record>';\n      ctCheck: Result := '<Warning: \"' + MainRecord.ShortName + '\" is not a Quest record>';\n    end;\n    Exit;\n  end;\n\n  case aType of\n    ctEditType: begin\n      Result := 'ComboBox';\n      Exit;\n    end;\n    ctEditInfo:\n      EditInfos := TStringList.Create;\n  else\n    EditInfos := nil;\n  end;\n\n  try\n    if Supports(MainRecord.ElementByName['Aliases'], IwbContainerElementRef, Aliases) then begin\n      for i := 0 to Pred(Aliases.ElementCount) do\n        if Supports(Aliases.Elements[i], IwbContainerElementRef, Alias) then begin\n          j := Alias.Elements[0].NativeValue;\n          s := Alias.ElementEditValues['ALID'];\n          t := IntToStr(j);\n          while Length(t) < 3 do\n            t := '0' + t;\n          if s <> '' then\n            t := t + ' ' + s;\n          if Assigned(EditInfos) then\n            EditInfos.Add(t)\n          else if j = aInt then begin\n            case aType of\n              ctToStr, ctToEditValue: Result := t;\n              ctCheck: Result := '';\n            end;\n            Exit;\n          end;\n        end;\n    end;\n\n    case aType of\n      ctToStr: Result := IntToStr(aInt) + ' <Warning: Quest Alias not found in \"' + MainRecord.Name + '\">';\n      ctCheck: Result := '<Warning: Quest Alias not found in \"' + MainRecord.Name + '\">';\n      ctEditInfo: begin\n        EditInfos.Add('None');\n        EditInfos.Sort;\n        Result := EditInfos.CommaText;\n      end;\n    end;\n  finally\n    FreeAndNil(EditInfos);\n  end;\nend;\n\nfunction wbStrToAlias(const aString: string; const aElement: IwbElement): Int64;\nvar\n  i    : Integer;\n  s    : string;\nbegin\n  Result := -1;\n\n  if aString = 'None' then\n    Exit;\n\n  i := 1;\n  s := Trim(aString);\n  while (i <= Length(s)) and (s[i] in ['-', '0'..'9']) do\n    Inc(i);\n  s := Copy(s, 1, Pred(i));\n\n  Result := StrToIntDef(s, -1);\nend;\n\nfunction wbScriptObjectAliasToStr(aInt: Int64; const aElement: IwbElement; aType: TwbCallbackType): string;\nvar\n  Container  : IwbContainerElementRef;\nbegin\n  if not wbResolveAlias then begin\n    case aType of\n      ctToStr, ctToEditValue: Result := IntToStr(aInt);\n      ctToSortKey: Result := IntToHex64(aInt, 8);\n    else\n      Result := '';\n    end;\n    Exit;\n  end;\n\n  if not Assigned(aElement) then\n    Exit;\n\n  Container := GetContainerRefFromUnionOrValue(aElement);\n\n  if not Assigned(Container) then\n    Exit;\n\n  Result := wbAliasToStr(aInt, Container.ElementByName['FormID'], aType);\nend;\n\nfunction wbPackageLocationAliasToStr(aInt: Int64; const aElement: IwbElement; aType: TwbCallbackType): string;\nvar\n  Container  : IwbContainer;\nbegin\n  if not wbResolveAlias then begin\n    case aType of\n      ctToStr, ctToEditValue: Result := IntToStr(aInt);\n      ctToSortKey: Result := IntToHex64(aInt, 8);\n    else\n      Result := '';\n    end;\n    Exit;\n  end;\n\n  if not Assigned(aElement) then\n    Exit;\n\n  Container := GetContainerFromUnion(aElement);\n  if not Assigned(Container) then Exit;\n  while Assigned(Container) and (Container.ElementType <> etMainRecord) do\n    Container := Container.Container;\n\n  if not Assigned(Container) then\n    Exit;\n\n  Result := wbAliasToStr(aInt, Container.ElementBySignature['QNAM'], aType);\nend;\n\nfunction wbQuestAliasToStr(aInt: Int64; const aElement: IwbElement; aType: TwbCallbackType): string;\nvar\n  Container  : IwbContainer;\nbegin\n  if not wbResolveAlias then begin\n    case aType of\n      ctToStr, ctToEditValue: Result := IntToStr(aInt);\n      ctToSortKey: Result := IntToHex64(aInt, 8);\n    else\n      Result := '';\n    end;\n    Exit;\n  end;\n\n  if not Assigned(aElement) then\n    Exit;\n\n  Container := GetContainerFromUnion(aElement);\n  if not Assigned(Container) then Exit;\n  while Assigned(Container) and (Container.ElementType <> etMainRecord) do\n    Container := Container.Container;\n\n  if not Assigned(Container) then\n    Exit;\n\n  Result := wbAliasToStr(aInt, Container, aType);\nend;\n\nfunction wbQuestExternalAliasToStr(aInt: Int64; const aElement: IwbElement; aType: TwbCallbackType): string;\nvar\n  Container  : IwbContainer;\nbegin\n  if not wbResolveAlias then begin\n    case aType of\n      ctToStr, ctToEditValue: Result := IntToStr(aInt);\n      ctToSortKey: Result := IntToHex64(aInt, 8);\n    else\n      Result := '';\n    end;\n    Exit;\n  end;\n\n  if not Assigned(aElement) then\n    Exit;\n\n  Container := aElement.Container;\n\n  if not Assigned(Container) then\n    Exit;\n\n  Result := wbAliasToStr(aInt, Container.ElementBySignature['ALEQ'] , aType);\nend;\n\nfunction wbConditionAliasToStr(aInt: Int64; const aElement: IwbElement; aType: TwbCallbackType): string;\nvar\n  Container  : IwbContainer;\n  MainRecord : IwbMainRecord;\n  GroupRecord : IwbGroupRecord;\nbegin\n  if not wbResolveAlias then begin\n    case aType of\n      ctToStr, ctToEditValue: Result := IntToStr(aInt);\n      ctToSortKey: Result := IntToHex64(aInt, 8);\n    else\n      Result := '';\n    end;\n    Exit;\n  end;\n\n  if not Assigned(aElement) then\n    Exit;\n\n  Container := GetContainerFromUnion(aElement);\n  if not Assigned(Container) then Exit;\n  while Assigned(Container) and (Container.ElementType <> etMainRecord) do\n    Container := Container.Container;\n\n  if not Assigned(Container) then\n    Exit;\n\n  if not Supports(Container, IwbMainRecord, MainRecord) then\n    Exit;\n\n  if MainRecord.Signature = QUST then\n    Result := wbAliasToStr(aInt, Container, aType)\n  else if MainRecord.Signature = SCEN then\n    Result := wbAliasToStr(aInt, Container.ElementBySignature['PNAM'], aType)\n  else if MainRecord.Signature = PACK then\n    Result := wbAliasToStr(aInt, Container.ElementBySignature['QNAM'], aType)\n  else if MainRecord.Signature = INFO then begin\n    // get DIAL for INFO\n    if Supports(MainRecord.Container, IwbGroupRecord, GroupRecord) then\n      if Supports(GroupRecord.ChildrenOf, IwbMainRecord, MainRecord) then\n        Result := wbAliasToStr(aInt, MainRecord.ElementBySignature['QNAM'], aType);\n  end else\n  // this should never be called since aliases in conditions can be in the forms above only\n  // but just in case\n  case aType of\n    ctToStr, ctToEditValue: Result := IntToStr(aInt);\n    ctToSortKey: Result := IntToHex64(aInt, 8);\n  else\n    Result := '';\n  end;\nend;\n\nfunction wbClmtMoonsPhaseLength(aInt: Int64; const aElement: IwbElement; aType: TwbCallbackType): string;\nvar\n  PhaseLength : Byte;\n  Masser      : Boolean;\n  Secunda     : Boolean;\nbegin\n  Result := '';\n  if aType = ctToSortKey then begin\n    Result := IntToHex64(aInt, 2);\n  end else if aType = ctToStr then begin\n    PhaseLength := aInt mod 64;\n    Masser := (aInt and 64) <> 0;\n    Secunda := (aInt and 128) <> 0;\n    if Masser then\n      if Secunda then\n        Result := 'Masser, Secunda / '\n      else\n        Result := 'Masser / '\n    else\n      if Secunda then\n        Result := 'Secunda / '\n      else\n        Result := 'No Moon / ';\n    Result := Result + IntToStr(PhaseLength);\n  end;\nend;\n\nfunction wbClmtTime(aInt: Int64; const aElement: IwbElement; aType: TwbCallbackType): string;\nbegin\n  if aType = ctToSortKey then\n    Result := IntToHex64(aInt, 4)\n  else if aType = ctToStr then\n    try\n      Result := TimeToStr( EncodeTime(aInt div 6, (aInt mod 6) * 10, 0, 0) )\n    except\n      Result := IntToStr(aInt)\n    end\n  else\n    Result := '';\nend;\n\n\nvar\n  wbCtdaTypeFlags : IwbFlagsDef;\n\nfunction wbCtdaTypeToStr(aInt: Int64; const aElement: IwbElement; aType: TwbCallbackType): string;\nvar\n  s: string;\nbegin\n  Result := '';\n\n  if not Assigned(wbCtdaTypeFlags) then\n    wbCtdaTypeFlags := wbFlags([\n      {0x01} 'Or',\n      {0x02} 'Use aliases',\n      {0x04} 'Use global',\n      {0x08} 'Use packdata',\n      {0x10} 'Swap Subject and Target'\n    ]);\n{\n    Compare operator (upper 3 bits)\n    LGE\n    000    0=Equal to\n    001    1=Not equal to\n    010    2=Greater than\n    011    3=Greater than or equal to\n    100    4=Less than\n    101    5=Less than or equal to\n\n    Flags (lower 5 bits)\n        0x01=OR (default is to AND conditions together)\n        0x02=Parameters (use aliases) : Force function parameters to use quest alias data (exclusive with \"use pack data\")\n        0x04=Use global\n        0x08=Use Pack Data : Force function parameters to use pack data (exclusive with \"use aliases\")\n        0x10=Swap Subject and Target\n}\n  case aType of\n    ctEditType:\n      Result := 'CheckComboBox';\n    ctEditInfo:\n      Result := 'Equal,Greater,Lesser,Or,\"Use Aliases\",\"Use Global\",\"Use Packdata\",\"Swap Subject and Target\"';\n    ctToEditValue: begin\n      Result := '00000000';\n      case aInt and $E0 of\n        $00 : Result[1] := '1';\n        $40 : Result[2] := '1';\n        $60 : begin\n                Result[1] := '1';\n                Result[2] := '1';\n              end;\n        $80 : Result[3] := '1';\n        $A0 : begin\n                Result[1] := '1';\n                Result[3] := '1';\n              end;\n      end;\n      if (aInt and $01) <> 0 then // Or\n        Result[4] := '1';\n      if (aInt and $02) <> 0 then // Use aliases\n        Result[5] := '1';\n      if (aInt and $04) <> 0 then // Use global\n        Result[6] := '1';\n      if (aInt and $08) <> 0 then // Use packdata\n        Result[7] := '1';\n      if (aInt and $10) <> 0 then // Swap Subject and Target\n        Result[8] := '1';\n    end;\n    ctToStr: begin\n      case aInt and $E0 of\n        $00 : Result := 'Equal to';\n        $20 : Result := 'Not equal to';\n        $40 : Result := 'Greater than';\n        $60 : Result := 'Greater than or equal to';\n        $80 : Result := 'Less than';\n        $A0 : Result := 'Less than or equal to';\n      else\n        Result := '<Unknown Compare operator>'\n      end;\n      s := wbCtdaTypeFlags.ToString(aInt and $1F, aElement);\n      if s <> '' then\n        Result := Result + ' / ' + s;\n    end;\n    ctToSortKey: begin\n      Result := IntToHex64(aInt, 2);\n      Exit;\n    end;\n    ctCheck: begin\n      case aInt and $E0 of\n        $00, $20, $40, $60, $80, $A0 : Result := '';\n      else\n        Result := '<Unknown Compare operator>'\n      end;\n      s := wbCtdaTypeFlags.Check(aInt and $1F, aElement);\n      if s <> '' then\n        Result := Result + ' / ' + s;\n    end;\n  end;\nend;\n\nfunction wbCtdaTypeToInt(const aString: string; const aElement: IwbElement): Int64;\nvar\n  s: string;\nbegin\n  s := aString + '00000000';\n  if s[1] = '1' then begin\n    if s[2] = '1' then begin\n      if s[3] = '1' then begin\n        Result := $00;\n      end else begin\n        Result := $60;\n      end;\n    end else begin\n      if s[3] = '1' then begin\n        Result := $A0;\n      end else begin\n        Result := $00;\n      end;\n    end;\n  end else begin\n    if s[2] = '1' then begin\n      if s[3] = '1' then begin\n        Result := $20;\n      end else begin\n        Result := $40;\n      end;\n    end else begin\n      if s[3] = '1' then begin\n        Result := $80;\n      end else begin\n        Result := $20;\n      end;\n    end;\n  end;\n  // Or\n  if s[4] = '1' then\n    Result := Result or $01;\n  // Use aliases\n  if s[5] = '1' then\n    Result := Result or $02;\n  // Use global\n  if s[6] = '1' then\n    Result := Result or $04;\n  // Use packdata\n  if s[7] = '1' then\n    Result := Result or $08;\n  // Swap Subject and Target\n  if s[8] = '1' then\n    Result := Result or $10;\nend;\n\nvar\n  wbEventFunctionAndMemberEditInfo: string;\n\nfunction wbEventFunctionAndMemberToStr(aInt: Int64; const aElement: IwbElement; aType: TwbCallbackType): string;\nvar\n  EventFunction, EventMember: Integer;\n  i, j: Integer;\n  s1, s2: string;\n  slMember: TStringList;\nbegin\n  Result := '';\n  EventFunction := aInt and $FFFF;\n  EventMember := aInt shr 16;\n  case aType of\n    ctToStr, ctToEditValue: begin\n      Result := wbEventFunctionEnum.ToEditValue(EventFunction, nil);\n      Result := Result + ':' + wbEventMemberEnum.ToEditValue(EventMember, nil);\n    end;\n    ctToSortKey: Result := IntToHex(aInt, 8);\n    ctCheck: begin\n      s1 := wbEventFunctionEnum.Check(EventFunction, nil);\n      if s1 <> '' then\n        s1 := 'EventFunction' + s1;\n      s2 := wbEventMemberEnum.Check(EventMember, nil);\n      if s2 <> '' then\n        s2 := 'EventMember' + s2;\n      if (s1 <> '') or (s2 <> '') then\n        Result := s1 + ':' + s2;\n    end;\n    ctEditType:\n      Result := 'ComboBox';\n    ctEditInfo: begin\n      Result := wbEventFunctionAndMemberEditInfo;\n      if Result = '' then try\n        slMember := TStringList.Create;\n        slMember.CommaText := wbEventMemberEnum.EditInfo[0, nil];\n        with TStringList.Create do try\n          for i := 0 to Pred(wbEventFunctionEnum.NameCount) do\n            for j := 0 to Pred(slMember.Count) do\n              Add(wbEventFunctionEnum.Names[i] + ':' + slMember[j]);\n          Sort;\n          Result := CommaText;\n        finally\n          Free;\n        end;\n        wbEventFunctionAndMemberEditInfo := Result;\n      finally\n        FreeAndNil(slMember);\n      end\n    end;\n  end;\nend;\n\nfunction wbEventFunctionAndMemberToInt(const aString: string; const aElement: IwbElement): Int64;\nvar\n  EventFunction, EventMember, i: Integer;\nbegin\n  i := Pos(':', aString);\n  if i > 0 then begin\n    EventFunction := wbEventFunctionEnum.FromEditValue(Copy(aString, 1, i-1), nil);\n    EventMember := wbEventMemberEnum.FromEditValue(Copy(aString, i+1, Length(aString)), nil);\n  end\n  else begin\n    EventFunction := 0;\n    EventMember := 0;\n  end;\n  Result := EventMember shl 16 + EventFunction;\nend;\n\nprocedure wbMESGDNAMAfterSet(const aElement: IwbElement; const aOldValue, aNewValue: Variant);\nvar\n  OldValue, NewValue : Integer;\n  Container          : IwbContainerElementRef;\nbegin\n  if VarSameValue(aOldValue, aNewValue) then\n    Exit;\n  if Supports(aElement.Container, IwbContainerElementRef, Container) then begin\n    OldValue := Integer(aOldValue) and 1;\n    NewValue := Integer(aNewValue) and 1;\n    if NewValue = OldValue then\n      Exit;\n    if NewValue = 1 then\n      Container.RemoveElement('TNAM')\n    else\n      Container.Add('TNAM', True);\n  end;\nend;\n\nprocedure wbGMSTEDIDAfterSet(const aElement: IwbElement; const aOldValue, aNewValue: Variant);\nvar\n  OldValue, NewValue : string;\n  Container          : IwbContainerElementRef;\nbegin\n  if VarSameValue(aOldValue, aNewValue) then\n    Exit;\n  if Supports(aElement.Container, IwbContainerElementRef, Container) then begin\n    OldValue := aOldValue;\n    NewValue := aNewValue;\n    if (Length(OldValue) < 1) or (Length(OldValue) < 1) or (OldValue[1] <> NewValue[1]) then begin\n      Container.RemoveElement('DATA');\n      Container.Add('DATA', True);\n    end;\n  end;\nend;\n\nprocedure wbFLSTEDIDAfterSet(const aElement: IwbElement; const aOldValue, aNewValue: Variant);\nvar\n  OldValue, NewValue     : string;\n  OldOrdered, NewOrdered : Boolean;\n  Container              : IwbContainerElementRef;\nconst\n  OrderedList = 'OrderedList';\nbegin\n  if VarSameValue(aOldValue, aNewValue) then\n    Exit;\n  if Supports(aElement.Container, IwbContainerElementRef, Container) then begin\n    OldValue := aOldValue;\n    NewValue := aNewValue;\n\n    if Length(OldValue) > Length(OrderedList) then\n      Delete(OldValue, 1, Length(OldValue)-Length(OrderedList));\n    if Length(NewValue) > Length(OrderedList) then\n      Delete(NewValue, 1, Length(NewValue)-Length(OrderedList));\n\n    OldOrdered := SameText(OldValue, OrderedList);\n    NewOrdered := SameText(NewValue, OrderedList);\n\n    if OldOrdered <> NewOrdered then\n      Container.RemoveElement('FormIDs');\n  end;\nend;\n\nprocedure wbCtdaTypeAfterSet(const aElement: IwbElement; const aOldValue, aNewValue: Variant);\nvar\n  OldValue, NewValue: Integer;\n  Container: IwbContainerElementRef;\nbegin\n  if VarSameValue(aOldValue, aNewValue) then\n    Exit;\n  if not Supports(aElement, IwbContainerElementRef, Container) then\n    Exit;\n\n  // reset value if \"use global\" has changed\n  OldValue := aOldValue and $04;\n  NewValue := aNewValue and $04;\n  if OldValue <> NewValue then\n    Container.ElementNativeValues['..\\Comparison Value'] := 0;\n\n  {>>> \"run on target\", no such flag in Skyrim <<<}\n//  if aNewValue and $02 then begin\n//    Container.ElementNativeValues['..\\Run On'] := 1;\n//    if Integer(Container.ElementNativeValues['..\\Run On']) = 1 then\n//      aElement.NativeValue := Byte(aNewValue) and not $02;\n//  end;\nend;\n\nprocedure wbAfterSet(const aElement: IwbElement; const aOldValue, aNewValue: Variant);\nbegin\n  Exit;\nend;\n\nfunction wbMODTCallback(aInt: Int64; const aElement: IwbElement; aType: TwbCallbackType): string;\nvar\n  Strings: TDynStrings;\n  i: Integer;\nbegin\n  Result := '';\n  if wbLoaderDone and (aType in [ctToStr, ctToSortKey] ) then begin\n    Strings := wbContainerHandler.ResolveHash(aInt);\n    for i := Low(Strings) to High(Strings) do\n      Result := Result + Strings[i] + ', ';\n    SetLength(Result, Length(Result) -2 );\n  end;\nend;\n\n{>>> Needs revision for Skyrim <<<}\n//function wbIdleAnam(aInt: Int64; const aElement: IwbElement; aType: TwbCallbackType): string;\n//begin\n//  Result := '';\n//  case aType of\n//    ctToStr: begin\n//      case aInt and not $C0 of\n//        0: Result := 'Idle';\n//        1: Result := 'Movement';\n//        2: Result := 'Left Arm';\n//        3: Result := 'Left Hand';\n//        4: Result := 'Weapon';\n//        5: Result := 'Weapon Up';\n//        6: Result := 'Weapon Down';\n//        7: Result := 'Special Idle';\n//       20: Result := 'Whole Body';\n//       21: Result := 'Upper Body';\n//      else\n//        Result := '<Unknown: '+IntToStr(aInt and not $C0)+'>';\n//      end;\n//\n//      if (aInt and $80) = 0 then\n//        Result := Result + ', Must return a file';\n//      if (aInt and $40) = 1 then\n//        Result := Result + ', Unknown Flag';\n//    end;\n//    ctToSortKey: begin\n//      Result := IntToHex64(aInt, 2);\n//    end;\n//    ctCheck: begin\n//      case aInt and not $C0 of\n//        0..7, 20, 21: Result := '';\n//      else\n//        Result := '<Unknown: '+IntToStr(aInt and not $C0)+'>';\n//      end;\n//    end;\n//  end;\n//end;\n\nfunction wbScaledInt4ToStr(aInt: Int64; const aElement: IwbElement; aType: TwbCallbackType): string;\nconst\n  PlusMinus : array[Boolean] of string = ('+', '-');\nbegin\n  Result := '';\n  case aType of\n    ctToStr, ctToEditValue: Result := FloatToStrF(aInt / 10000, ffFixed, 99, 4);\n    ctToSortKey: begin\n      Result := FloatToStrF(aInt / 10000, ffFixed, 99, 4);\n      if Length(Result) < 22 then\n        Result := StringOfChar('0', 22 - Length(Result)) + Result;\n      Result := PlusMinus[aInt < 0] + Result;\n    end;\n    ctCheck: Result := '';\n  end;\nend;\n\nfunction wbScaledInt4ToInt(const aString: string; const aElement: IwbElement): Int64;\nvar\n  f: Extended;\nbegin\n  f := StrToFloat(aString);\n  f := f * 10000;\n  Result := Round(f);\nend;\n\nfunction wbCloudSpeedToStr(aInt: Int64; const aElement: IwbElement; aType: TwbCallbackType): string;\nbegin\n  Result := '';\n  case aType of\n    ctToStr, ctToEditValue: Result := FloatToStrF((aInt - 127)/127/10, ffFixed, 99, 4);\n    ctCheck: Result := '';\n  end;\nend;\n\nfunction wbCloudSpeedToInt(const aString: string; const aElement: IwbElement): Int64;\nvar\n  f: Extended;\nbegin\n  f := StrToFloat(aString);\n  f := f*10*127 + 127;\n  Result := Min(Round(f), 254);\nend;\n\nfunction wbShortXYtoStr(aInt: Int64; const aElement: IwbElement; aType: TwbCallbackType): string;\nvar\n  x, y: SmallInt;\nbegin\n  y := aInt and $FFFF;\n  x := aInt shr 16 and $FFFF;\n  Result := '';\n  case aType of\n    ctToStr, ctToEditValue: Result := Format('%d, %d', [x, y]);\n    ctCheck: Result := '';\n  end;\nend;\n\nfunction wbStrToShortXY(const aString: string; const aElement: IwbElement): Int64;\nvar\n  x, y: SmallInt;\n  Value: Cardinal;\nbegin\n  y := StrToIntDef(Copy(aString, 1, Pred(Pos(', ', aString))), 0);\n  x := StrToIntDef(Copy(aString, Pos(', ', aString) + 2, Length(aString)), 0);\n  PWord(@Value)^ := x;\n  PWord(Cardinal(@Value) + SizeOf(SmallInt))^ := y;\n  Result := Value;\nend;\n\nfunction wbHideFFFF(aInt: Int64; const aElement: IwbElement; aType: TwbCallbackType): string;\nbegin\n  Result := '';\n  if aType = ctToSortKey then\n    Result := IntToHex64(aInt, 4)\n  else if aType = ctToStr then\n    if aInt = $FFFF then\n      Result := 'None'\n    else\n      Result := IntToStr(aInt);\nend;\n\nfunction wbAtxtPosition(aInt: Int64; const aElement: IwbElement; aType: TwbCallbackType): string;\nbegin\n  Result := '';\n  if aType = ctToSortKey then\n    Result := IntToHex64(aInt div 17, 2) + IntToHex64(aInt mod 17, 2)\n  else if aType = ctCheck then begin\n    if (aInt < 0) or (aInt > 288) then\n      Result := '<Out of range: '+IntToStr(aInt)+'>'\n    else\n      Result := '';\n  end else if aType = ctToStr then\n    Result := IntToStr(aInt) + ' -> ' + IntToStr(aInt div 17) + ':' + IntToStr(aInt mod 17);\nend;\n\nfunction wbGLOBFNAM(aInt: Int64; const aElement: IwbElement; aType: TwbCallbackType): string;\nbegin\n  Result := '';\n  case aType of\n    ctToStr: begin\n      case aInt of\n        Ord('s'): Result := 'Short';\n        Ord('l'): Result := 'Long';\n        Ord('f'): Result := 'Float';\n        Ord('b'): Result := 'Boolean';\n      else\n        Result := '<Unknown: '+IntToStr(aInt)+'>';\n      end;\n    end;\n    ctToSortKey: Result := Chr(aInt);\n    ctCheck: begin\n      case aInt of\n        Ord('s'), Ord('l'), Ord('f'), Ord('b'): Result := '';\n      else\n        Result := '<Unknown: '+IntToStr(aInt)+'>';\n      end;\n    end;\n  end;\nend;\n\nfunction wbPlacedAddInfo(const aMainRecord: IwbMainRecord): string;\nvar\n  Rec: IwbRecord;\n  Container: IwbContainer;\n  s: string;\n  Cell: IwbMainRecord;\n  Position: TwbVector;\n  Grid: TwbGridCell;\nbegin\n  Result := '';\n\n  Rec := aMainRecord.RecordBySignature['NAME'];\n  if Assigned(Rec) then begin\n    s := Trim(Rec.Value);\n    if s <> '' then\n      Result := 'places ' + s;\n  end;\n\n  Container := aMainRecord.Container;\n  while Assigned(Container) and (Container.ElementType <> etGroupRecord) do\n    Container := Container.Container;\n\n  if Assigned(Container) then begin\n    s := Trim(Container.Name);\n    if s <> '' then begin\n      if Result <> '' then\n        Result := Result + ' ';\n      Result := Result + 'in ' + s;\n\n      // grid position of persistent reference in exterior persistent cell (interior cells are not persistent)\n      if Supports(aMainRecord.Container, IwbGroupRecord, Container) then\n        Cell := IwbGroupRecord(Container).ChildrenOf;\n      if Assigned(Cell) and Cell.IsPersistent and (Cell.Signature = 'CELL') then\n        if aMainRecord.GetPosition(Position) then begin\n          Grid := wbPositionToGridCell(Position);\n          Result := Result + ' at ' + IntToStr(Grid.x) + ',' + IntToStr(Grid.y);\n        end;\n    end;\n  end;\nend;\n\nfunction wbINFOAddInfo(const aMainRecord: IwbMainRecord): string;\nvar\n  Container: IwbContainer;\n  s: string;\nbegin\n  Result := Trim(aMainRecord.ElementValues['Responses\\Response\\NAM1']);\n  if Result <> '' then\n    Result := '''' + Result + '''';\n\n  Container := aMainRecord.Container;\n  while Assigned(Container) and (Container.ElementType <> etGroupRecord) do\n    Container := Container.Container;\n\n  if Assigned(Container) then begin\n    s := Trim(Container.Name);\n    if s <> '' then begin\n      if Result <> '' then\n        Result := Result + ' ';\n      Result := Result + 'in ' + s;\n    end;\n  end;\n\n  s := Trim(aMainRecord.ElementValues['QNAM']);\n  if s <> '' then begin\n    if Result <> '' then\n      Result := Result + ' ';\n    Result := Result + 'for ' + s;\n  end;\nend;\n\nfunction wbNAVMAddInfo(const aMainRecord: IwbMainRecord): string;\nvar\n  Container: IwbContainer;\n  s: string;\nbegin\n  Result := '';\n\n  Container := aMainRecord.Container;\n  while Assigned(Container) and (Container.ElementType <> etGroupRecord) do\n    Container := Container.Container;\n\n  if Assigned(Container) then begin\n    s := Trim(Container.Name);\n    if s <> '' then begin\n      if Result <> '' then\n        Result := Result + ' ';\n      Result := Result + 'in ' + s;\n    end;\n  end;\nend;\n\nfunction wbCellAddInfo(const aMainRecord: IwbMainRecord): string;\nvar\n  Rec: IwbRecord;\n  Container: IwbContainer;\n  GroupRecord : IwbGroupRecord;\n  s: string;\nbegin\n  Result := '';\n\n  if not aMainRecord.IsPersistent then begin\n    Rec := aMainRecord.RecordBySignature['XCLC'];\n    if Assigned(Rec) then\n      Result := 'at ' + Rec.Elements[0].Value + ',' + Rec.Elements[1].Value;\n  end;\n\n  Container := aMainRecord.Container;\n  while Assigned(Container) and not\n    (Supports(Container, IwbGroupRecord, GroupRecord) and (GroupRecord.GroupType = 1))  do\n    Container := Container.Container;\n\n  if Assigned(Container) then begin\n    s := wbFormID.ToString(GroupRecord.GroupLabel, aMainRecord);\n    if s <> '' then begin\n      if Result <> '' then\n        s := s + ' ';\n      Result := 'in ' + s + Result;\n    end;\n  end;\nend;\n\nprocedure wbCTDARunOnAfterSet(const aElement: IwbElement; const aOldValue, aNewValue: Variant);\nbegin\n  if aOldValue <> aNewValue then\n    if aNewValue <> 2 then\n      aElement.Container.ElementNativeValues['Reference'] := 0;\nend;\n\n{>>> Needs revision for Skyrim <<<}\nprocedure wbPERKPRKETypeAfterSet(const aElement: IwbElement; const aOldValue, aNewValue: Variant);\nvar\n  Container : IwbContainerElementRef;\n//  rDATA     : IwbRecord;\nbegin\n  if aOldValue <> aNewValue then\n    if Supports(aElement.Container, IwbContainerElementRef, Container) then begin\n      if Supports(Container.Container, IwbContainerElementRef, Container) then begin\n        Container.RemoveElement('DATA');\n        Container.Add('DATA', True);\n        Container.RemoveElement('Perk Conditions');\n        Container.RemoveElement('Entry Point Function Parameters');\n        if aNewValue = 2 then begin\n          Container.Add('EPFT', True);\n          Container.ElementNativeValues['DATA\\Entry Point\\Function'] := 2;\n        end;\n      end;\n    end;\nend;\n\nfunction wbNPCLevelDecider(aBasePtr: Pointer; aEndPtr: Pointer; const aElement: IwbElement): Integer;\nvar\n  Container: IwbContainer;\n  i: Int64;\nbegin\n  Result := 0;\n  if not Assigned(aElement) then Exit;\n  Container := GetContainerFromUnion(aElement);\n  if not Assigned(Container) then Exit;\n\n  i := Container.ElementByName['Flags'].NativeValue;\n  if i and $00000080 <> 0 then\n    Result := 1;\nend;\n\nfunction wbMGEFAssocItemDecider(aBasePtr: Pointer; aEndPtr: Pointer; const aElement: IwbElement): Integer;\nvar\n  Container     : IwbContainer;\n  Archtype      : Variant;\n  DataContainer : IwbDataContainer;\n  Element       : IwbElement;\nconst\n  OffsetArchtype = 56;\n\nbegin\n  Result := 0;\n  if not Assigned(aElement) then Exit;\n  Container := GetContainerFromUnion(aElement);\n  if not Assigned(Container) then Exit;\n\n  VarClear(ArchType);\n  Element := Container.ElementByName['Archtype'];\n  if Assigned(Element) then\n    ArchType := Element.NativeValue\n  else if Supports(Container, IwbDataContainer, DataContainer) and\n          DataContainer.IsValidOffset(aBasePtr, aEndPtr, OffsetArchtype) then begin // we are part a proper structure\n      aBasePtr := Pointer(Cardinal(aBasePtr) + OffsetArchtype);\n      ArchType := PCardinal(aBasePtr)^;\n    end;\n\n  if not VarIsEmpty(ArchType) then\n    case Integer(ArchType) of\n      12: Result := 1; // Light\n      17: Result := 2; // Bound Item\n      18: Result := 3; // Summon Creature\n      25: Result := 4; // Guide\n      34: Result := 8; // Peak Mod\n      35: Result := 5; // Cloak\n      36: Result := 6; // Werewolf\n      39: Result := 7; // Enhance Weapon\n      40: Result := 4; // Spawn Hazard\n      46: Result := 6; // Vampire Lord\n    end;\nend;\n\nprocedure wbMGEFAssocItemAfterSet(const aElement: IwbElement; const aOldValue, aNewValue: Variant);\nvar\n  Container : IwbContainer;\n  Element   : IwbElement;\nbegin\n  if not Assigned(aElement) then Exit;\n  Container := GetContainerFromUnion(aElement);\n  if not Assigned(Container) then Exit;\n  if (aNewValue <> 0) then begin\n    Element := Container.ElementByName['Archtype'];\n    if Assigned(Element) and (Element.NativeValue = 0) then\n        Element.NativeValue := $FF; // Signals ArchType that it should not mess with us on the next change!\n          // I assume this will alo protect Second AV Weight (The two actor values are after ArchType)\n  end;\nend;\n\nprocedure wbMGEFAV2WeightAfterSet(const aElement: IwbElement; const aOldValue, aNewValue: Variant);\nvar\n  Container : IwbContainer;\n  Element   : IwbElement;\nbegin\n  if not Assigned(aElement) then Exit;\n  Container := GetContainerFromUnion(aElement);\n  if not Assigned(Container) then Exit;\n  if (aNewValue <> 0.0) then begin\n    Element := Container.ElementByName['Archtype'];\n    if Assigned(Element) and (Element.NativeValue = 0) then\n        Element.NativeValue := $FF; // Signals ArchType that it should not mess with us on the next change!\n  end;\nend;\n\nprocedure wbMGEFArchtypeAfterSet(const aElement: IwbElement; const aOldValue, aNewValue: Variant);\nvar\n  Container: IwbContainerElementRef;\nbegin\n  if VarSameValue(aOldValue, aNewValue) then\n    Exit;\n  if not Supports(aElement, IwbContainerElementRef, Container) then\n    Exit;\n  if (aNewValue < $FF) and (aOldValue < $FF) then begin\n    Container.ElementNativeValues['..\\Assoc. Item'] := 0;\n    case Integer(aNewValue) of\n      06: Container.ElementNativeValues['..\\Actor Value'] := 00;//Agression\n      07: Container.ElementNativeValues['..\\Actor Value'] := 01;//Confidence\n      08: Container.ElementNativeValues['..\\Actor Value'] := 00;//Agression\n      11: Container.ElementNativeValues['..\\Actor Value'] := 54;//Invisibility\n      21: Container.ElementNativeValues['..\\Actor Value'] := 53;//Paralysis\n      24: Container.ElementNativeValues['..\\Actor Value'] := 01;//Confidence\n      38: Container.ElementNativeValues['..\\Actor Value'] := 01;//Confidence\n      42: Container.ElementNativeValues['..\\Actor Value'] := 01;//Confidence\n    else\n      Container.ElementNativeValues['..\\Actor Value'] := -1;\n    end;\n    Container.ElementNativeValues['..\\Second Actor Value'] := -1;\n    Container.ElementNativeValues['..\\Second AV Weight'] := 0.0;\n  end;\nend;\n\nfunction wbCTDAReferenceDecider(aBasePtr: Pointer; aEndPtr: Pointer; const aElement: IwbElement): Integer;\nvar\n  Container     : IwbContainer;\nbegin\n  Result := 0;\n  if not Assigned(aElement) then Exit;\n  Container := GetContainerFromUnion(aElement);\n  if not Assigned(Container) then Exit;\n\n  if Integer(Container.ElementNativeValues['Run On']) = 2 then\n    Result := 1;\nend;\n\nfunction wbNAVIIslandDataDecider(aBasePtr: Pointer; aEndPtr: Pointer; const aElement: IwbElement): Integer;\nvar\n  Container   : IwbContainer;\n  SubRecord   : IwbMainRecord;\n  Element     : IwbElement;\nbegin\n  Result := 0;\n\n  Container := aElement.Container;\n  while Assigned(Container) and (Container.ElementType <> etsubRecord) do\n    Container := Container.Container;\n\n  if not Supports(Container, IwbSubRecord, SubRecord) then\n    Exit;\n\n  Element := SubRecord.ElementByName['Is Island'];\n  if not Assigned(Element) then\n    Exit;\n\n  Result := Element.NativeValue;\nend;\n\nfunction wbNAVIParentDecider(aBasePtr: Pointer; aEndPtr: Pointer; const aElement: IwbElement): Integer;\nvar\n  Container   : IwbContainer;\n  SubRecord   : IwbMainRecord;\n  Element     : IwbElement;\nbegin\n  Result := 0;\n\n  Container := aElement.Container;\n  while Assigned(Container) and (Container.ElementType <> etsubRecord) do\n    Container := Container.Container;\n\n  if not Supports(Container, IwbSubRecord, SubRecord) then\n    Exit;\n\n  Element := SubRecord.ElementByName['Parent Worldspace'];\n  if not Assigned(Element) then\n    Exit;\n\n  if (Element.NativeValue = 0) then\n    Result := 1;\nend;\n\nfunction wbNVNMParentDecider(aBasePtr: Pointer; aEndPtr: Pointer; const aElement: IwbElement): Integer;\nvar\n  Container   : IwbContainer;\n  Current     : IwbContainer;\n  Parent      : IwbContainer;\n  GroupRecord : IwbGroupRecord;\n  MainRecord  : IwbMainRecord;\n  rData       : IwbRecord;\n  i           : integer;\nbegin\n  Result := 0;\n\n  Container := aElement.Container;\n  while Assigned(Container) and (Container.ElementType <> etGroupRecord) do\n    Container := Container.Container;\n\n  if not Supports(Container, IwbGroupRecord, GroupRecord) then\n    Exit;\n\n  MainRecord := GroupRecord.ChildrenOf;     // This does NOT work while adding master!\n\n  if not Assigned(MainRecord) then begin // we expect:\n     //   plugin \\ CELL group \\ Block \\ Sub Block \\ CELL\n     //                                           \\ CELL Children group \\ Permanent children group\n     //                                                                 \\ Temporary children group = GroupRecord = Container\n    if Assigned(Container) and (Container.ElementType = etGroupRecord) then\n      Container := Container.Container;\n    if Assigned(Container) and (Container.ElementType = etGroupRecord) then\n      Parent := Container.Container;\n    i := 0;\n    while (i < Parent.ElementCount) and Supports(Parent.Elements[i], IwbContainer, Current) and (Current <> Container) do\n      Inc(i);\n    if (i = 0) or (i = Parent.ElementCount) or not Supports(Parent.Elements[i-1], IwbMainRecord,MainRecord) then begin\n      wbProgressCallback('Parent of a NVNM is not a MainRecord');\n//      Assert(Assigned(MainRecord)); // Better an exception than to destroy the plugin.\n      Exit;\n    end;\n  end;\n  if (MainRecord.Signature<>CELL) then begin\n    wbProgressCallback('Parent of a NVNM is not identified as a CELL');\n    Assert(MainRecord.Signature=CELL); // Better an exception than to destroy the plugin.\n    Exit;\n  end;\n\n  rDATA := MainRecord.RecordBySignature['DATA'];\n\n  if not Assigned(rData) then\n    Exit;\n\n  i := rData.NativeValue;\n\n  // is interior cell?\n  if i and 1 <> 0 then\n    Result := 1;\nend;\n\nfunction wbCOEDOwnerDecider(aBasePtr: Pointer; aEndPtr: Pointer; const aElement: IwbElement): Integer;\nvar\n  Container  : IwbContainer;\n  LinksTo    : IwbElement;\n  MainRecord : IwbMainRecord;\nbegin\n  Result := 0;\n  if not Assigned(aElement) then Exit;\n  Container := GetContainerFromUnion(aElement);\n  if not Assigned(Container) then Exit;\n\n  LinksTo := Container.ElementByName['Owner'].LinksTo;\n\n  if Supports(LinksTo, IwbMainRecord, MainRecord) then\n    if MainRecord.Signature = 'NPC_' then\n      Result := 1\n    else if MainRecord.Signature = 'FACT' then\n      Result := 2;\nend;\n\nfunction wbGMSTUnionDecider(aBasePtr: Pointer; aEndPtr: Pointer; const aElement: IwbElement): Integer;\nvar\n  rEDID: IwbRecord;\n  s: string;\nbegin\n  Result := 1;\n  rEDID := aElement.Container.RecordBySignature[EDID];\n  if Assigned(rEDID) then begin\n    s := rEDID.Value;\n    if Length(s) > 0 then\n      case s[1] of\n        's': Result := 0; {String} {>>> Localization Strings <<<}\n        'i': Result := 1; {intS32}\n        'f': Result := 2; {Float}\n        'b': Result := 3; {Boolean}\n      end;\n  end;\nend;\n\nfunction wbFLSTLNAMIsSorted(const aContainer: IwbContainer): Boolean;\nvar\n  rEDID      : IwbRecord;\n  s          : string;\nconst\n  OrderedList = 'OrderedList';\nbegin\n  Result := False; {>>> Should not be sorted according to Arthmoor and JustinOther <<<}\n  rEDID := aContainer.RecordBySignature[EDID];\n  if Assigned(rEDID) then begin\n    s := rEDID.Value;\n    if Length(s) > Length(OrderedList) then\n      Delete(s, 1, Length(s)-Length(OrderedList));\n    if SameText(s, OrderedList) then\n      Result := False;\n  end;\nend;\n\nfunction wbPerkDATADecider(aBasePtr: Pointer; aEndPtr: Pointer; const aElement: IwbElement): Integer;\nvar\n  rPRKE: IwbRecord;\n  eType: IwbElement;\nbegin\n  Result := 0;\n  rPRKE := aElement.Container.RecordBySignature[PRKE];\n  if Assigned(rPRKE) then begin\n    eType := rPRKE.ElementByName['Type'];\n    if Assigned(eType) then begin\n      Result := eType.NativeValue;\n    end;\n  end;\nend;\n\nfunction wbEPFDDecider(aBasePtr: Pointer; aEndPtr: Pointer; const aElement: IwbElement): Integer;\nvar\n  Container: IwbContainerElementRef;\nbegin\n  Result := 0;\n  if not Assigned(aElement) then\n    Exit;\n  if not Supports(aElement.Container, IwbContainerElementRef, Container) then\n    Exit;\n  Result := Container.ElementNativeValues['EPFT'];\n  if Result = 2 then\n    case Integer(Container.ElementNativeValues['..\\DATA\\Entry Point\\Function']) of\n      5, 12, 13, 14: Result := 8;\n    end;\nend;\n\nfunction wbSPGDFormatDecider(aBasePtr: Pointer; aEndPtr: Pointer; const aElement: IwbElement): Integer;\nvar\n  MainRecord: IwbMainRecord;\nbegin\n  Result := 0;\n  if not Assigned(aElement) then\n    Exit;\n  if not Supports(aElement.Container, IwbMainRecord, MainRecord) then\n    Exit;\n  if MainRecord.Version < 44 then\n    Result := 1;\nend;\n\n\n{>>> For VMAD <<<}\nfunction wbScriptObjFormatDecider(aBasePtr: Pointer; aEndPtr: Pointer; const aElement: IwbElement): Integer;\nvar\n  ObjFormat: Integer;\n  Container: IwbContainer;\nbegin\n  Result := 0;\n\n  Container := aElement.Container;\n  while Assigned(Container) and (Container.ElementType <> etSubRecord) do\n    Container := Container.Container;\n\n  if not Assigned(Container) then Exit;\n\n  ObjFormat := Container.ElementNativeValues['Object Format'];\n\n  if ObjFormat = 1 then\n    Result := 1;\nend;\n\n{>>> For VMAD <<<}\nfunction wbScriptPropertyDecider(aBasePtr: Pointer; aEndPtr: Pointer; const aElement: IwbElement): Integer;\nvar\n  Container     : IwbContainer;\nbegin\n  Result := 0;\n  if not Assigned(aElement) then Exit;\n  Container := GetContainerFromUnion(aElement);\n  if not Assigned(Container) then Exit;\n\n  case Integer(Container.ElementNativeValues['Type']) of\n     1: Result := 1;\n     2: Result := 2;\n     3: Result := 3;\n     4: Result := 4;\n     5: Result := 5;\n    11: Result := 6;\n    12: Result := 7;\n    13: Result := 8;\n    14: Result := 9;\n    15: Result := 10;\n  end;\nend;\n\nprocedure wbScriptPropertyTypeAfterSet(const aElement: IwbElement; const aOldValue, aNewValue: Variant);\nvar\n  Container : IwbContainerElementRef;\nbegin\n  if aOldValue <> aNewValue then\n    if Supports(aElement.Container, IwbContainerElementRef, Container) then\n      Container.ElementByName['Value'].SetToDefault;\nend;\n\n{>>> For VMAD <<<}\nfunction wbScriptFragmentExistsDecider(aBasePtr: Pointer; aEndPtr: Pointer; const aElement: IwbElement): Integer;\nvar\n  Container  : IwbContainer;\n  MainRecord : IwbMainRecord;\nbegin\n  Result := 0;\n  if not Assigned(aElement) then Exit;\n  Container := GetContainerFromUnion(aElement);\n  if not Assigned(Container) then Exit;\n  while Assigned(Container) and (Container.ElementType <> etMainRecord) do\n    Container := Container.Container;\n  if not Assigned(Container) then Exit;\n\n  Supports(Container, IwbMainRecord, MainRecord);\n  if MainRecord.Signature = INFO then\n    Result := 1\n  else if MainRecord.Signature = PACK then\n    Result := 2\n  else if MainRecord.Signature = PERK then\n    Result := 3\n  else if MainRecord.Signature = QUST then\n    Result := 4\n  else if MainRecord.Signature = SCEN then\n    Result := 5;\nend;\n\n{>>> For VMAD <<<}\nfunction wbScriptFragmentsQuestCounter(aBasePtr: Pointer; aEndPtr: Pointer; const aElement: IwbElement): Cardinal;\nvar\n  Container     : IwbContainer;\n\nbegin\n  Result := 0;\n  if aElement.ElementType = etValue then\n    Container := aElement.Container\n  else\n    Container := aElement as IwbContainer;\n  if not Assigned(Container) then Exit;\n  while Assigned(Container) and (Container.Name <> 'Script Fragments') do\n    Container := Container.Container;\n  if not Assigned(Container) then Exit;\n\n  Result := Integer(Container.ElementNativeValues['fragmentCount']);\nend;\n\n{>>> For VMAD <<<}\nfunction wbScriptFragmentsInfoCounter(aBasePtr: Pointer; aEndPtr: Pointer; const aElement: IwbElement): Cardinal;\nvar\n  Container     : IwbContainer;\n  F             : Integer;\n  i             : Integer;\nbegin\n  Result := 0;\n  if aElement.ElementType = etValue then\n    Container := aElement.Container\n  else\n    Container := aElement as IwbContainer;\n  if not Assigned(Container) then Exit;\n  while Assigned(Container) and (Container.Name <> 'Script Fragments') do\n    Container := Container.Container;\n  if not Assigned(Container) then Exit;\n\n  F := Container.ElementByName['Flags'].NativeValue;\n  for i := 0 to 2 do begin\n    if (F and 1) = 1 then\n      Inc(Result);\n    F := F shr 1;\n  end;\n  for i := 3 to 7 do begin\n    if (F and 1) = 1 then begin\n      Inc(Result);\n    if Assigned(wbProgressCallback) then\n      wbProgressCallback('==='+aElement.Name+'       ['+Container.Name+':'+Container.Path+'] = unknown info VMAD flag bit '+IntToStr(i));\n  end;\n    F := F shr 1;\n  end;\nend;\n\n{>>> For VMAD <<<}\nfunction wbScriptFragmentsSceneCounter(aBasePtr: Pointer; aEndPtr: Pointer; const aElement: IwbElement): Cardinal;\nvar\n  Container     : IwbContainer;\n  F             : Integer;\n  i             : Integer;\nbegin\n  Result := 0;\n  if aElement.ElementType = etValue then\n    Container := aElement.Container\n  else\n    Container := aElement as IwbContainer;\n  if not Assigned(Container) then Exit;\n  while Assigned(Container) and (Container.Name <> 'Script Fragments') do\n    Container := Container.Container;\n  if not Assigned(Container) then Exit;\n\n  F := Container.ElementByName['Flags'].NativeValue;\n  for i := 0 to 2 do begin\n    if (F and 1) = 1 then\n      Inc(Result);\n    F := F shr 1;\n  end;\n  for i := 3 to 7 do begin\n    if (F and 1) = 1 then begin\n      Inc(Result);\n  if Assigned(wbProgressCallback) then\n      wbProgressCallback('==='+aElement.Name+'       ['+Container.Name+':'+Container.Path+'] = unknown scene VMAD flag bit '+IntToStr(i));\n  end;\n    F := F shr 1;\n  end;\nend;\n\n{>>> For VMAD <<<}\nfunction wbScriptFragmentsPackCounter(aBasePtr: Pointer; aEndPtr: Pointer; const aElement: IwbElement): Cardinal;\nvar\n  Container     : IwbContainer;\n  F             : Integer;\n  i             : Integer;\nbegin\n  Result := 0;\n  if aElement.ElementType = etValue then\n    Container := aElement.Container\n  else\n    Container := aElement as IwbContainer;\n  if not Assigned(Container) then Exit;\n  while Assigned(Container) and (Container.Name <> 'Script Fragments') do\n    Container := Container.Container;\n  if not Assigned(Container) then Exit;\n\n  F := Container.ElementByName['Flags'].NativeValue;\n  for i := 0 to 7 do begin\n    if (F and 1) = 1 then\n      Inc(Result);\n    F := F shr 1;\n  end;\nend;\n\nfunction wbBOOKTeachesDecider(aBasePtr: Pointer; aEndPtr: Pointer; const aElement: IwbElement): Integer;\nvar\n  Container: IwbContainer;\n  i: Int64;\nbegin\n  Result := 0;\n  if not Assigned(aElement) then Exit;\n  Container := GetContainerFromUnion(aElement);\n  if not Assigned(Container) then Exit;\n\n  i := Container.ElementByName['Flags'].NativeValue;\n  if i and $00000004 <> 0 then Result := 1;\nend;\n\n\ntype\n  TCTDAFunctionParamType = (\n    ptNone,\n    ptInteger,\n    ptFloat,\n    ptVariableName,  //Integer\n    ptSex,           //Enum: Male, Female\n    ptActorValue,    //Enum: wbActorValue\n    ptCrimeType,     //?? Enum\n    ptAxis,          //?? Char\n    ptQuestStage,    //?? Integer\n    ptMiscStat,      //?? Enum\n    ptAlignment,     //?? Enum\n    ptEquipType,     //?? Enum\n    ptFormType,      //?? Enum\n    ptCriticalStage, //?? Enum\n    ptObjectReference,    //REFR, ACHR\n    ptInventoryObject,    //ARMO, BOOK, MISC, WEAP, AMMO, KEYM, ALCH, ARMA, LIGH, LVLI, COBJ\n    ptActor,              //ACHR\n    ptVoiceType,          //VTYP\n    ptIdleForm,           //IDLE\n    ptFormList,           //FLST\n    ptQuest,              //QUST\n    ptFaction,            //FACT\n    ptCell,               //CELL\n    ptClass,              //CLAS\n    ptRace,               //RACE\n    ptActorBase,          //NPC_\n    ptGlobal,             //GLOB\n    ptWeather,            //WTHR\n    ptPackage,            //PACK\n    ptEncounterZone,      //ECZN\n    ptPerk,               //PERK\n    ptOwner,              //FACT, NPC_\n    ptFurniture,          //FURN\n    ptMagicItem,          //SPEL\n    ptMagicEffect,        //MGEF\n    ptWorldspace,         //WRLD\n    ptVATSValueFunction,\n    ptVATSValueParam,\n    ptReferencableObject,\n    ptRegion,             //REGN\n    ptKeyword,            //KYWD\n    ptAdvanceAction,      // ?? Enum\n    ptCastingSource,      // ?? Enum\n    ptShout,              //SHOU\n    ptLocation,           //LCTN\n    ptRefType,            //LCRT\n    ptAlias,              // index into QUST quest aliases\n    ptPackdata,           // index into PACK package data inputs\n    ptAssociationType,    // ASTP\n    ptFurnitureAnim,      // enum\n    ptFurnitureEntry,     // flags\n    ptScene,              // SCEN\n    ptWardState,          // enum\n    ptEvent,              // Struct\n    ptEventData           // LCTN, KYWD or FLST\n  );\n\n  PCTDAFunction = ^TCTDAFunction;\n  TCTDAFunction = record\n    Index: Integer;\n    Name: string;\n    ParamType1: TCTDAFunctionParamType;\n    ParamType2: TCTDAFunctionParamType;\n    ParamType3: TCTDAFunctionParamType;\n  end;\n\nconst\n  {>> N means New, V means verified that the name has not changed <<<}\n  wbCTDAFunctions : array[0..399] of TCTDAFunction = (\n{N} (Index:   0; Name: 'GetWantBlocking'),\n{V} (Index:   1; Name: 'GetDistance'; ParamType1: ptObjectReference),\n{V} (Index:   5; Name: 'GetLocked'),\n{V} (Index:   6; Name: 'GetPos'; ParamType1: ptAxis),\n{V} (Index:   8; Name: 'GetAngle'; ParamType1: ptAxis),\n{V} (Index:  10; Name: 'GetStartingPos'; ParamType1: ptAxis),\n{V} (Index:  11; Name: 'GetStartingAngle'; ParamType1: ptAxis),\n{V} (Index:  12; Name: 'GetSecondsPassed'),\n{V} (Index:  14; Name: 'GetActorValue'; ParamType1: ptActorValue),\n{V} (Index:  18; Name: 'GetCurrentTime'),\n{V} (Index:  24; Name: 'GetScale'),\n{V} (Index:  25; Name: 'IsMoving'),\n{V} (Index:  26; Name: 'IsTurning'),\n{V} (Index:  27; Name: 'GetLineOfSight'; ParamType1: ptObjectReference),\n{V} (Index:  32; Name: 'GetInSameCell'; ParamType1: ptObjectReference),\n{V} (Index:  35; Name: 'GetDisabled'),\n{V} (Index:  36; Name: 'MenuMode'; ParamType1: ptInteger), // was ptMenuMode\n{V} (Index:  39; Name: 'GetDisease'),\n{V} (Index:  41; Name: 'GetClothingValue'),\n{V} (Index:  42; Name: 'SameFaction'; ParamType1: ptActor),\n{V} (Index:  43; Name: 'SameRace'; ParamType1: ptActor),\n{V} (Index:  44; Name: 'SameSex'; ParamType1: ptActor),\n{V} (Index:  45; Name: 'GetDetected'; ParamType1: ptActor),\n{V} (Index:  46; Name: 'GetDead'),\n{V} (Index:  47; Name: 'GetItemCount'; ParamType1: ptInventoryObject),\n{V} (Index:  48; Name: 'GetGold'),\n{V} (Index:  49; Name: 'GetSleeping'),\n{V} (Index:  50; Name: 'GetTalkedToPC'),\n{V} (Index:  53; Name: 'GetScriptVariable'; ParamType1: ptObjectReference; ParamType2: ptVariableName),\n{V} (Index:  56; Name: 'GetQuestRunning'; ParamType1: ptQuest),\n{V} (Index:  58; Name: 'GetStage'; ParamType1: ptQuest),\n{V} (Index:  59; Name: 'GetStageDone'; ParamType1: ptQuest; ParamType2: ptQuestStage),\n{V} (Index:  60; Name: 'GetFactionRankDifference'; ParamType1: ptFaction; ParamType2: ptActor),\n{V} (Index:  61; Name: 'GetAlarmed'),\n{V} (Index:  62; Name: 'IsRaining'),\n{V} (Index:  63; Name: 'GetAttacked'),\n{V} (Index:  64; Name: 'GetIsCreature'),\n{V} (Index:  65; Name: 'GetLockLevel'),\n{V} (Index:  66; Name: 'GetShouldAttack'; ParamType1: ptActor),\n{V} (Index:  67; Name: 'GetInCell'; ParamType1: ptCell),\n{V} (Index:  68; Name: 'GetIsClass'; ParamType1: ptClass),\n{V} (Index:  69; Name: 'GetIsRace'; ParamType1: ptRace),\n{V} (Index:  70; Name: 'GetIsSex'; ParamType1: ptSex),\n{V} (Index:  71; Name: 'GetInFaction'; ParamType1: ptFaction),\n{V} (Index:  72; Name: 'GetIsID'; ParamType1: ptReferencableObject),\n{V} (Index:  73; Name: 'GetFactionRank'; ParamType1: ptFaction),\n{V} (Index:  74; Name: 'GetGlobalValue'; ParamType1: ptGlobal),\n{V} (Index:  75; Name: 'IsSnowing'),\n{V} (Index:  77; Name: 'GetRandomPercent'),\n{V} (Index:  79; Name: 'GetQuestVariable'; ParamType1: ptQuest; ParamType2: ptVariableName),\n{V} (Index:  80; Name: 'GetLevel'),\n{N} (Index:  81; Name: 'IsRotating'),\n{V} (Index:  84; Name: 'GetDeadCount'; ParamType1: ptActorBase),\n{V} (Index:  91; Name: 'GetIsAlerted'),\n{V} (Index:  98; Name: 'GetPlayerControlsDisabled'; ParamType1: ptInteger; ParamType2: ptInteger),\n{V} (Index:  99; Name: 'GetHeadingAngle'; ParamType1: ptObjectReference),\n{N} (Index: 101; Name: 'IsWeaponMagicOut'),\n{V} (Index: 102; Name: 'IsTorchOut'),\n{V} (Index: 103; Name: 'IsShieldOut'),\n{V} (Index: 106; Name: 'IsFacingUp'),\n{V} (Index: 107; Name: 'GetKnockedState'),\n{V} (Index: 108; Name: 'GetWeaponAnimType'),\n{V} (Index: 109; Name: 'IsWeaponSkillType'; ParamType1: ptActorValue),\n{V} (Index: 110; Name: 'GetCurrentAIPackage'),\n{V} (Index: 111; Name: 'IsWaiting'),\n{V} (Index: 112; Name: 'IsIdlePlaying'),\n{N} (Index: 116; Name: 'IsIntimidatebyPlayer'),\n{N} (Index: 117; Name: 'IsPlayerInRegion'; ParamType1: ptRegion),\n{V} (Index: 118; Name: 'GetActorAggroRadiusViolated'),\n{V} (Index: 122; Name: 'GetCrime'; ParamType1: ptActor; ParamType2: ptCrimeType),\n{V} (Index: 123; Name: 'IsGreetingPlayer'),\n{V} (Index: 125; Name: 'IsGuard'),\n{V} (Index: 127; Name: 'HasBeenEaten'),\n{V} (Index: 128; Name: 'GetStaminaPercentage'),\n{V} (Index: 129; Name: 'GetPCIsClass'; ParamType1: ptClass),\n{V} (Index: 130; Name: 'GetPCIsRace'; ParamType1: ptRace),\n{V} (Index: 131; Name: 'GetPCIsSex'; ParamType1: ptSex),\n{V} (Index: 132; Name: 'GetPCInFaction'; ParamType1: ptFaction),\n{V} (Index: 133; Name: 'SameFactionAsPC'),\n{V} (Index: 134; Name: 'SameRaceAsPC'),\n{V} (Index: 135; Name: 'SameSexAsPC'),\n{V} (Index: 136; Name: 'GetIsReference'; ParamType1: ptObjectReference),\n{V} (Index: 141; Name: 'IsTalking'),\n{V} (Index: 142; Name: 'GetWalkSpeed'),\n{V} (Index: 143; Name: 'GetCurrentAIProcedure'),\n{V} (Index: 144; Name: 'GetTrespassWarningLevel'),\n{V} (Index: 145; Name: 'IsTrespassing'),\n{V} (Index: 146; Name: 'IsInMyOwnedCell'),\n{V} (Index: 147; Name: 'GetWindSpeed'),\n{V} (Index: 148; Name: 'GetCurrentWeatherPercent'),\n{V} (Index: 149; Name: 'GetIsCurrentWeather'; ParamType1: ptWeather),\n{V} (Index: 150; Name: 'IsContinuingPackagePCNear'),\n{N} (Index: 152; Name: 'GetIsCrimeFaction'; ParamType1: ptFaction),\n{V} (Index: 153; Name: 'CanHaveFlames'),\n{V} (Index: 154; Name: 'HasFlames'),\n{V} (Index: 157; Name: 'GetOpenState'),\n{V} (Index: 159; Name: 'GetSitting'),\n{V} (Index: 161; Name: 'GetIsCurrentPackage'; ParamType1: ptPackage),\n{V} (Index: 162; Name: 'IsCurrentFurnitureRef'; ParamType1: ptObjectReference),\n{V} (Index: 163; Name: 'IsCurrentFurnitureObj'; ParamType1: ptFurniture),\n{V} (Index: 170; Name: 'GetDayOfWeek'),\n{V} (Index: 172; Name: 'GetTalkedToPCParam'; ParamType1: ptActor),\n{V} (Index: 175; Name: 'IsPCSleeping'),\n{V} (Index: 176; Name: 'IsPCAMurderer'),\n{N} (Index: 180; Name: 'HasSameEditorLocAsRef'; ParamType1: ptObjectReference; ParamType2: ptKeyword),\n{N} (Index: 181; Name: 'HasSameEditorLocAsRefAlias'; ParamType1: ptAlias; ParamType2: ptKeyword),\n{V} (Index: 182; Name: 'GetEquipped'; ParamType1: ptInventoryObject),\n{V} (Index: 185; Name: 'IsSwimming'),\n{V} (Index: 190; Name: 'GetAmountSoldStolen'),\n{V} (Index: 192; Name: 'GetIgnoreCrime'),\n{V} (Index: 193; Name: 'GetPCExpelled'; ParamType1: ptFaction),\n{V} (Index: 195; Name: 'GetPCFactionMurder'; ParamType1: ptFaction),\n{V} (Index: 197; Name: 'GetPCEnemyofFaction'; ParamType1: ptFaction),\n{V} (Index: 199; Name: 'GetPCFactionAttack'; ParamType1: ptFaction),\n{V} (Index: 203; Name: 'GetDestroyed'),\n{V} (Index: 214; Name: 'HasMagicEffect'; ParamType1: ptMagicEffect),\n{V} (Index: 215; Name: 'GetDefaultOpen'),\n{V} (Index: 219; Name: 'GetAnimAction'),\n{V} (Index: 223; Name: 'IsSpellTarget'; ParamType1: ptMagicItem),\n{V} (Index: 224; Name: 'GetVATSMode'),\n{V} (Index: 225; Name: 'GetPersuasionNumber'),\n{V} (Index: 226; Name: 'GetVampireFeed'),\n{V} (Index: 227; Name: 'GetCannibal'),\n{V} (Index: 228; Name: 'GetIsClassDefault'; ParamType1: ptClass),\n{V} (Index: 229; Name: 'GetClassDefaultMatch'),\n{V} (Index: 230; Name: 'GetInCellParam'; ParamType1: ptCell; ParamType2: ptObjectReference),\n{V} (Index: 235; Name: 'GetVatsTargetHeight'),\n{V} (Index: 237; Name: 'GetIsGhost'),\n{V} (Index: 242; Name: 'GetUnconscious'),\n{V} (Index: 244; Name: 'GetRestrained'),\n{V} (Index: 246; Name: 'GetIsUsedItem'; ParamType1: ptReferencableObject),\n{V} (Index: 247; Name: 'GetIsUsedItemType'; ParamType1: ptFormType),\n{N} (Index: 248; Name: 'IsScenePlaying'; ParamType1: ptScene),\n{N} (Index: 249; Name: 'IsInDialogueWithPlayer'),\n{N} (Index: 250; Name: 'GetLocationCleared'; ParamType1: ptLocation),\n{V} (Index: 254; Name: 'GetIsPlayableRace'),\n{V} (Index: 255; Name: 'GetOffersServicesNow'),\n{N} (Index: 258; Name: 'HasAssociationType'; ParamType1: ptActor; ParamType2: ptAssociationType),\n{N} (Index: 259; Name: 'HasFamilyRelationship'; ParamType1: ptActor),\n{N} (Index: 261; Name: 'HasParentRelationship'; ParamType1: ptActor),\n{N} (Index: 262; Name: 'IsWarningAbout'; ParamType1: ptFormList),\n{V} (Index: 263; Name: 'IsWeaponOut'),\n{N} (Index: 264; Name: 'HasSpell'; ParamType1: ptMagicItem),\n{V} (Index: 265; Name: 'IsTimePassing'),\n{V} (Index: 266; Name: 'IsPleasant'),\n{V} (Index: 267; Name: 'IsCloudy'),\n{N} (Index: 274; Name: 'IsSmallBump'),\n{V} (Index: 277; Name: 'GetBaseActorValue'; ParamType1: ptActorValue),\n{V} (Index: 278; Name: 'IsOwner'; ParamType1: ptOwner),\n{V} (Index: 280; Name: 'IsCellOwner'; ParamType1: ptCell; ParamType2: ptOwner),\n{V} (Index: 282; Name: 'IsHorseStolen'),\n{V} (Index: 285; Name: 'IsLeftUp'),\n{V} (Index: 286; Name: 'IsSneaking'),\n{V} (Index: 287; Name: 'IsRunning'),\n{V} (Index: 288; Name: 'GetFriendHit'),\n{V} (Index: 289; Name: 'IsInCombat'; ParamType1: ptInteger),\n{V} (Index: 300; Name: 'IsInInterior'),\n{V} (Index: 304; Name: 'IsWaterObject'),\n{N} (Index: 305; Name: 'GetPlayerAction'),\n{V} (Index: 306; Name: 'IsActorUsingATorch'),\n{V} (Index: 309; Name: 'IsXBox'),\n{V} (Index: 310; Name: 'GetInWorldspace'; ParamType1: ptWorldSpace),\n{V} (Index: 312; Name: 'GetPCMiscStat'; ParamType1: ptMiscStat),\n{N} (Index: 313; Name: 'GetPairedAnimation'),\n{V} (Index: 314; Name: 'IsActorAVictim'),\n{V} (Index: 315; Name: 'GetTotalPersuasionNumber'),\n{V} (Index: 318; Name: 'GetIdleDoneOnce'),\n{V} (Index: 320; Name: 'GetNoRumors'),\n{N} (Index: 323; Name: 'GetCombatState'),\n{N} (Index: 325; Name: 'GetWithinPackageLocation'; ParamType1: ptPackdata),\n{V} (Index: 327; Name: 'IsRidingMount'),\n{N} (Index: 329; Name: 'IsFleeing'),\n{V} (Index: 332; Name: 'IsInDangerousWater'),\n{V} (Index: 338; Name: 'GetIgnoreFriendlyHits'),\n{V} (Index: 339; Name: 'IsPlayersLastRiddenMount'),\n{V} (Index: 353; Name: 'IsActor'),\n{V} (Index: 354; Name: 'IsEssential'),\n{V} (Index: 358; Name: 'IsPlayerMovingIntoNewSpace'),\n{N} (Index: 359; Name: 'GetInCurrentLoc'; ParamType1: ptLocation),\n{N} (Index: 360; Name: 'GetInCurrentLocAlias'; ParamType1: ptAlias),\n{V} (Index: 361; Name: 'GetTimeDead'),\n{N} (Index: 362; Name: 'HasLinkedRef'; ParamType1: ptKeyword),\n{V} (Index: 365; Name: 'IsChild'),\n{N} (Index: 366; Name: 'GetStolenItemValueNoCrime'; ParamType1: ptFaction),\n{V} (Index: 367; Name: 'GetLastPlayerAction'),\n{V} (Index: 368; Name: 'IsPlayerActionActive'; ParamType1: ptInteger), // was ptPlayerAction\n{V} (Index: 370; Name: 'IsTalkingActivatorActor'; ParamType1: ptActor),\n{V} (Index: 372; Name: 'IsInList'; ParamType1: ptFormList),\n{N} (Index: 373; Name: 'GetStolenItemValue'; ParamType1: ptFaction),\n{N} (Index: 375; Name: 'GetCrimeGoldViolent'),\n{N} (Index: 376; Name: 'GetCrimeGoldNonviolent'),\n{N} (Index: 378; Name: 'HasShout'; ParamType1: ptShout),\n{V} (Index: 381; Name: 'GetHasNote'; ParamType1: ptInteger), // was ptNote\n{V} (Index: 390; Name: 'GetHitLocation'),\n{V} (Index: 391; Name: 'IsPC1stPerson'),\n{V} (Index: 396; Name: 'GetCauseofDeath'),\n{V} (Index: 397; Name: 'IsLimbGone'; ParamType1: ptInteger), // was ptBodyLocation\n{V} (Index: 398; Name: 'IsWeaponInList'; ParamType1: ptFormList),\n{N} (Index: 402; Name: 'IsBribedbyPlayer'),\n{V} (Index: 403; Name: 'GetRelationshipRank'; ParamType1: ptObjectReference),\n{V} (Index: 407; Name: 'GetVATSValue'; ParamType1: ptVATSValueFunction; ParamType2: ptVATSValueParam),\n{V} (Index: 408; Name: 'IsKiller'; ParamType1: ptActor),\n{V} (Index: 409; Name: 'IsKillerObject'; ParamType1: ptFormList),\n{V} (Index: 410; Name: 'GetFactionCombatReaction'; ParamType1: ptFaction; ParamType2: ptFaction),\n{V} (Index: 414; Name: 'Exists'; ParamType1: ptObjectReference),\n{V} (Index: 415; Name: 'GetGroupMemberCount'),\n{V} (Index: 416; Name: 'GetGroupTargetCount'),\n{V} (Index: 426; Name: 'GetIsVoiceType'; ParamType1: ptVoiceType),\n{V} (Index: 427; Name: 'GetPlantedExplosive'),\n{N} (Index: 429; Name: 'IsScenePackageRunning'),\n{V} (Index: 430; Name: 'GetHealthPercentage'),\n{V} (Index: 432; Name: 'GetIsObjectType'; ParamType1: ptFormType),\n{V} (Index: 434; Name: 'GetDialogueEmotion'),\n{V} (Index: 435; Name: 'GetDialogueEmotionValue'),\n{V} (Index: 437; Name: 'GetIsCreatureType'; ParamType1: ptInteger),\n{N} (Index: 444; Name: 'GetInCurrentLocFormList'; ParamType1: ptFormList),\n{V} (Index: 445; Name: 'GetInZone'; ParamType1: ptEncounterZone),\n{N} (Index: 446; Name: 'GetVelocity'; ParamType1: ptAxis),\n{N} (Index: 447; Name: 'GetGraphVariableFloat'; ParamType1: ptVariableName),\n{V} (Index: 448; Name: 'HasPerk'; ParamType1: ptPerk; ParamType2: ptInteger{Alt?}),\n{V} (Index: 449; Name: 'GetFactionRelation'; ParamType1: ptActor),\n{V} (Index: 450; Name: 'IsLastIdlePlayed'; ParamType1: ptIdleForm),\n{V} (Index: 453; Name: 'GetPlayerTeammate'),\n{V} (Index: 454; Name: 'GetPlayerTeammateCount'),\n{V} (Index: 458; Name: 'GetActorCrimePlayerEnemy'),\n{V} (Index: 459; Name: 'GetCrimeGold'),\n{V} (Index: 463; Name: 'IsPlayerGrabbedRef'; ParamType1: ptObjectReference),\n{N} (Index: 465; Name: 'GetKeywordItemCount'; ParamType1: ptKeyword),\n{V} (Index: 470; Name: 'GetDestructionStage'),\n{V} (Index: 473; Name: 'GetIsAlignment'; ParamType1: ptAlignment),\n{N} (Index: 476; Name: 'IsProtected'),\n{V} (Index: 477; Name: 'GetThreatRatio'; ParamType1: ptActor),\n{V} (Index: 479; Name: 'GetIsUsedItemEquipType'; ParamType1: ptEquipType),\n{N} (Index: 487; Name: 'IsCarryable'),\n{V} (Index: 488; Name: 'GetConcussed'),\n{V} (Index: 491; Name: 'GetMapMarkerVisible'),\n{N} (Index: 493; Name: 'PlayerKnows'; ParamType1: ptMagicEffect),\n{V} (Index: 494; Name: 'GetPermanentActorValue'; ParamType1: ptActorValue),\n{V} (Index: 495; Name: 'GetKillingBlowLimb'),\n{N} (Index: 497; Name: 'CanPayCrimeGold'),\n{N} (Index: 499; Name: 'GetDaysInJail'),\n{N} (Index: 500; Name: 'EPAlchemyGetMakingPoison'),\n{N} (Index: 501; Name: 'EPAlchemyEffectHasKeyword'; ParamType1: ptKeyword),\n{N} (Index: 503; Name: 'GetAllowWorldInteractions'),\n{V} (Index: 508; Name: 'GetLastHitCritical'),\n{N} (Index: 513; Name: 'IsCombatTarget'; ParamType1: ptActor),\n{V} (Index: 515; Name: 'GetVATSRightAreaFree'; ParamType1: ptObjectReference),\n{V} (Index: 516; Name: 'GetVATSLeftAreaFree'; ParamType1: ptObjectReference),\n{V} (Index: 517; Name: 'GetVATSBackAreaFree'; ParamType1: ptObjectReference),\n{V} (Index: 518; Name: 'GetVATSFrontAreaFree'; ParamType1: ptObjectReference),\n{N} (Index: 519; Name: 'GetLockIsBroken'),\n{N} (Index: 520; Name: 'IsPS3'),\n{N} (Index: 521; Name: 'IsWin32'),\n{V} (Index: 522; Name: 'GetVATSRightTargetVisible'; ParamType1: ptObjectReference),\n{V} (Index: 523; Name: 'GetVATSLeftTargetVisible'; ParamType1: ptObjectReference),\n{V} (Index: 524; Name: 'GetVATSBackTargetVisible'; ParamType1: ptObjectReference),\n{V} (Index: 525; Name: 'GetVATSFrontTargetVisible'; ParamType1: ptObjectReference),\n{V} (Index: 528; Name: 'IsInCriticalStage'; ParamType1: ptCriticalStage),\n{N} (Index: 530; Name: 'GetXPForNextLevel'),\n{N} (Index: 533; Name: 'GetInfamy'),\n{N} (Index: 534; Name: 'GetInfamyViolent'),\n{N} (Index: 535; Name: 'GetInfamyNonViolent'),\n{V} (Index: 543; Name: 'GetQuestCompleted'; ParamType1: ptQuest),\n{V} (Index: 547; Name: 'IsGoreDisabled'),\n{N} (Index: 550; Name: 'IsSceneActionComplete'; ParamType1: ptScene; ParamType2: ptInteger),\n{V} (Index: 552; Name: 'GetSpellUsageNum'; ParamType1: ptMagicItem),\n{N} (Index: 554; Name: 'GetActorsInHigh'),\n{V} (Index: 555; Name: 'HasLoaded3D'),\n{N} (Index: 560; Name: 'HasKeyword'; ParamType1: ptKeyword),\n{N} (Index: 561; Name: 'HasRefType'; ParamType1: ptRefType),\n{N} (Index: 562; Name: 'LocationHasKeyword'; ParamType1: ptKeyword),\n{N} (Index: 563; Name: 'LocationHasRefType'; ParamType1: ptRefType),\n{N} (Index: 565; Name: 'GetIsEditorLocation'; ParamType1: ptLocation),\n{N} (Index: 566; Name: 'GetIsAliasRef'; ParamType1: ptAlias),\n{N} (Index: 567; Name: 'GetIsEditorLocAlias'; ParamType1: ptAlias),\n{N} (Index: 568; Name: 'IsSprinting'),\n{N} (Index: 569; Name: 'IsBlocking'),\n{N} (Index: 570; Name: 'HasEquippedSpell'; ParamType1: ptCastingSource),\n{N} (Index: 571; Name: 'GetCurrentCastingType'; ParamType1: ptCastingSource),\n{N} (Index: 572; Name: 'GetCurrentDeliveryType'; ParamType1: ptCastingSource),\n{N} (Index: 574; Name: 'GetAttackState'),\n{N} (Index: 576; Name: 'GetEventData'; ParamType1: ptEvent; ParamType2: ptEventData; ParamType3: ptNone),\n{N} (Index: 577; Name: 'IsCloserToAThanB'; ParamType1: ptObjectReference; ParamType2: ptObjectReference),\n{N} (Index: 579; Name: 'GetEquippedShout'; ParamType1: ptShout),\n{N} (Index: 580; Name: 'IsBleedingOut'),\n{N} (Index: 584; Name: 'GetRelativeAngle'; ParamType1: ptObjectReference; ParamType2: ptAxis),\n{N} (Index: 589; Name: 'GetMovementDirection'),\n{N} (Index: 590; Name: 'IsInScene'),\n{N} (Index: 591; Name: 'GetRefTypeDeadCount'; ParamType1: ptLocation; ParamType2: ptRefType),\n{N} (Index: 592; Name: 'GetRefTypeAliveCount'; ParamType1: ptLocation; ParamType2: ptRefType),\n{N} (Index: 594; Name: 'GetIsFlying'),\n{N} (Index: 595; Name: 'IsCurrentSpell'; ParamType1: ptMagicItem; ParamType2: ptCastingSource),\n{N} (Index: 596; Name: 'SpellHasKeyword'; ParamType1: ptCastingSource; ParamType2: ptKeyword),\n{N} (Index: 597; Name: 'GetEquippedItemType'; ParamType1: ptCastingSource),\n{N} (Index: 598; Name: 'GetLocationAliasCleared'; ParamType1: ptAlias),\n{N} (Index: 600; Name: 'GetLocAliasRefTypeDeadCount'; ParamType1: ptAlias; ParamType2: ptRefType),\n{N} (Index: 601; Name: 'GetLocAliasRefTypeAliveCount'; ParamType1: ptAlias; ParamType2: ptRefType),\n{N} (Index: 602; Name: 'IsWardState'; ParamType1: ptWardState),\n{N} (Index: 603; Name: 'IsInSameCurrentLocAsRef'; ParamType1: ptObjectReference; ParamType2: ptKeyword),\n{N} (Index: 604; Name: 'IsInSameCurrentLocAsRefAlias'; ParamType1: ptAlias; ParamType2: ptKeyword),\n{N} (Index: 605; Name: 'LocAliasIsLocation'; ParamType1: ptAlias; ParamType2: ptLocation),\n{N} (Index: 606; Name: 'GetKeywordDataForLocation'; ParamType1: ptLocation; ParamType2: ptKeyword),\n{N} (Index: 608; Name: 'GetKeywordDataForAlias'; ParamType1: ptAlias; ParamType2: ptKeyword),\n{N} (Index: 610; Name: 'LocAliasHasKeyword'; ParamType1: ptAlias; ParamType2: ptKeyword),\n{N} (Index: 611; Name: 'IsNullPackageData'; ParamType1: ptPackdata),\n{N} (Index: 612; Name: 'GetNumericPackageData'; ParamType1: ptInteger),\n{N} (Index: 613; Name: 'IsFurnitureAnimType'; ParamType1: ptFurnitureAnim),\n{N} (Index: 614; Name: 'IsFurnitureEntryType'; ParamType1: ptFurnitureEntry),\n{N} (Index: 615; Name: 'GetHighestRelationshipRank'),\n{N} (Index: 616; Name: 'GetLowestRelationshipRank'),\n{N} (Index: 617; Name: 'HasAssociationTypeAny'; ParamType1: ptAssociationType),\n{N} (Index: 618; Name: 'HasFamilyRelationshipAny'),\n{N} (Index: 619; Name: 'GetPathingTargetOffset'; ParamType1: ptAxis),\n{N} (Index: 620; Name: 'GetPathingTargetAngleOffset'; ParamType1: ptAxis),\n{N} (Index: 621; Name: 'GetPathingTargetSpeed'),\n{N} (Index: 622; Name: 'GetPathingTargetSpeedAngle'; ParamType1: ptAxis),\n{N} (Index: 623; Name: 'GetMovementSpeed'),\n{N} (Index: 624; Name: 'GetInContainer'; ParamType1: ptObjectReference),\n{N} (Index: 625; Name: 'IsLocationLoaded'; ParamType1: ptLocation),\n{N} (Index: 626; Name: 'IsLocAliasLoaded'; ParamType1: ptAlias),\n{N} (Index: 627; Name: 'IsDualCasting'),\n{N} (Index: 629; Name: 'GetVMQuestVariable'; ParamType1: ptQuest; ParamType2: ptVariableName),\n{N} (Index: 630; Name: 'GetVMScriptVariable'; ParamType1: ptObjectReference; ParamType2: ptVariableName),\n{N} (Index: 631; Name: 'IsEnteringInteractionQuick'),\n{N} (Index: 632; Name: 'IsCasting'),\n{N} (Index: 633; Name: 'GetFlyingState'),\n{N} (Index: 635; Name: 'IsInFavorState'),\n{N} (Index: 636; Name: 'HasTwoHandedWeaponEquipped'),\n{N} (Index: 637; Name: 'IsExitingInstant'),\n{N} (Index: 638; Name: 'IsInFriendStateWithPlayer'),\n{N} (Index: 639; Name: 'GetWithinDistance'; ParamType1: ptObjectReference; ParamType2: ptFloat),\n{N} (Index: 640; Name: 'GetActorValuePercent'; ParamType1: ptActorValue),\n{N} (Index: 641; Name: 'IsUnique'),\n{N} (Index: 642; Name: 'GetLastBumpDirection'),\n{N} (Index: 644; Name: 'IsInFurnitureState'; ParamType1: ptFurnitureAnim),\n{N} (Index: 645; Name: 'GetIsInjured'),\n{N} (Index: 646; Name: 'GetIsCrashLandRequest'),\n{N} (Index: 647; Name: 'GetIsHastyLandRequest'),\n{N} (Index: 650; Name: 'IsLinkedTo'; ParamType1: ptObjectReference; ParamType2: ptKeyword),\n{N} (Index: 651; Name: 'GetKeywordDataForCurrentLocation'; ParamType1: ptKeyword),\n{N} (Index: 652; Name: 'GetInSharedCrimeFaction'; ParamType1: ptObjectReference),\n{N} (Index: 654; Name: 'GetBribeSuccess'),\n{N} (Index: 655; Name: 'GetIntimidateSuccess'),\n{N} (Index: 656; Name: 'GetArrestedState'),\n{N} (Index: 657; Name: 'GetArrestingActor'),\n{N} (Index: 659; Name: 'EPTemperingItemIsEnchanted'),\n{N} (Index: 660; Name: 'EPTemperingItemHasKeyword'; ParamType1: ptKeyword),\n{N} (Index: 664; Name: 'GetReplacedItemType'; ParamType1: ptCastingSource),\n{N} (Index: 672; Name: 'IsAttacking'),\n{N} (Index: 673; Name: 'IsPowerAttacking'),\n{N} (Index: 674; Name: 'IsLastHostileActor'),\n{N} (Index: 675; Name: 'GetGraphVariableInt'; ParamType1: ptVariableName),\n{N} (Index: 676; Name: 'GetCurrentShoutVariation'),\n{N} (Index: 678; Name: 'ShouldAttackKill'; ParamType1: ptActor),\n{N} (Index: 680; Name: 'GetActivatorHeight'),\n{N} (Index: 681; Name: 'EPMagic_IsAdvanceSkill'; ParamType1: ptActorValue),\n{N} (Index: 682; Name: 'WornHasKeyword'; ParamType1: ptKeyword),\n{N} (Index: 683; Name: 'GetPathingCurrentSpeed'),\n{N} (Index: 684; Name: 'GetPathingCurrentSpeedAngle'; ParamType1: ptAxis),\n{N} (Index: 691; Name: 'EPModSkillUsage_AdvanceObjectHasKeyword'; ParamType1: ptKeyword),\n{N} (Index: 692; Name: 'EPModSkillUsage_IsAdvanceAction'; ParamType1: ptAdvanceAction),\n{N} (Index: 693; Name: 'EPMagic_SpellHasKeyword'; ParamType1: ptKeyword),\n{N} (Index: 694; Name: 'GetNoBleedoutRecovery'),\n{N} (Index: 696; Name: 'EPMagic_SpellHasSkill'; ParamType1: ptActorValue),\n{N} (Index: 697; Name: 'IsAttackType'; ParamType1: ptKeyword),\n{N} (Index: 698; Name: 'IsAllowedToFly'),\n{N} (Index: 699; Name: 'HasMagicEffectKeyword'; ParamType1: ptKeyword),\n{N} (Index: 700; Name: 'IsCommandedActor'),\n{N} (Index: 701; Name: 'IsStaggered'),\n{N} (Index: 702; Name: 'IsRecoiling'),\n{N} (Index: 703; Name: 'IsExitingInteractionQuick'),\n{N} (Index: 704; Name: 'IsPathing'),\n{N} (Index: 705; Name: 'GetShouldHelp'; ParamType1: ptActor),\n{N} (Index: 706; Name: 'HasBoundWeaponEquipped'; ParamType1: ptCastingSource),\n{N} (Index: 707; Name: 'GetCombatTargetHasKeyword'; ParamType1: ptKeyword),\n{N} (Index: 709; Name: 'GetCombatGroupMemberCount'),\n{N} (Index: 710; Name: 'IsIgnoringCombat'),\n{N} (Index: 711; Name: 'GetLightLevel'),\n{N} (Index: 713; Name: 'SpellHasCastingPerk'; ParamType1: ptPerk),\n{N} (Index: 714; Name: 'IsBeingRidden'),\n{N} (Index: 715; Name: 'IsUndead'),\n{N} (Index: 716; Name: 'GetRealHoursPassed'),\n{N} (Index: 718; Name: 'IsUnlockedDoor'),\n{N} (Index: 719; Name: 'IsHostileToActor'; ParamType1: ptActor),\n{N} (Index: 720; Name: 'GetTargetHeight'; ParamType1: ptObjectReference),\n{N} (Index: 721; Name: 'IsPoison'),\n{N} (Index: 722; Name: 'WornApparelHasKeywordCount'; ParamType1: ptKeyword),\n{N} (Index: 723; Name: 'GetItemHealthPercent'),\n{N} (Index: 724; Name: 'EffectWasDualCast'),\n{N} (Index: 725; Name: 'GetKnockedStateEnum'),\n{N} (Index: 726; Name: 'DoesNotExist'),\n{N} (Index: 730; Name: 'IsOnFlyingMount'),\n{N} (Index: 731; Name: 'CanFlyHere'),\n{N} (Index: 732; Name: 'IsFlyingMountPatrolQueud'),\n{N} (Index: 733; Name: 'IsFlyingMountFastTravelling'),\n\n    // Added by SKSE\n    (Index: 1024; Name: 'GetSKSEVersion'; ),\n    (Index: 1025; Name: 'GetSKSEVersionMinor'; ),\n    (Index: 1026; Name: 'GetSKSEVersionBeta'; ),\n    (Index: 1027; Name: 'GetSKSERelease'; ),\n    (Index: 1028; Name: 'ClearInvalidRegistrations'; )\n  );\n\nvar\n  wbCTDAFunctionEditInfo: string;\n\nfunction wbCTDAParamDescFromIndex(aIndex: Integer): PCTDAFunction;\nvar\n  L, H, I, C: Integer;\nbegin\n  Result := nil;\n\n  L := Low(wbCTDAFunctions);\n  H := High(wbCTDAFunctions);\n  while L <= H do begin\n    I := (L + H) shr 1;\n    C := CmpW32(wbCTDAFunctions[I].Index, aIndex);\n    if C < 0 then\n      L := I + 1\n    else begin\n      H := I - 1;\n      if C = 0 then begin\n        L := I;\n        Result := @wbCTDAFunctions[L];\n      end;\n    end;\n  end;\nend;\n\nfunction wbCTDACompValueDecider(aBasePtr: Pointer; aEndPtr: Pointer; const aElement: IwbElement): Integer;\nvar\n  Container: IwbContainer;\nbegin\n  Result := 0;\n  if not Assigned(aElement) then Exit;\n  Container := GetContainerFromUnion(aElement);\n  if not Assigned(Container) then Exit;\n\n  // \"use global\" flag\n  if Integer(Container.ElementByName['Type'].NativeValue) and $04 <> 0 then\n    Result := 1;\nend;\n\nfunction wbCTDAParam1Decider(aBasePtr: Pointer; aEndPtr: Pointer; const aElement: IwbElement): Integer;\nvar\n  Desc: PCTDAFunction;\n  Container: IwbContainer;\n  ParamFlag: Byte;\n  ParamType: TCTDAFunctionParamType;\nbegin\n  Result := 0;\n  if not Assigned(aElement) then Exit;\n  Container := GetContainerFromUnion(aElement);\n  if not Assigned(Container) then Exit;\n\n  Desc := wbCTDAParamDescFromIndex(Container.ElementByName['Function'].NativeValue);\n\n  if Assigned(Desc) then begin\n    ParamType := Desc.ParamType1;\n    ParamFlag := Container.ElementByName['Type'].NativeValue;\n    if ParamType in [ptObjectReference, ptActor, ptPackage] then begin\n      if ParamFlag and $02 > 0 then ParamType := ptAlias else {>>> 'use aliases' is set <<<}\n      if ParamFlag and $08 > 0 then ParamType := ptPackdata;  {>>> 'use packdata' is set <<<}\n    end;\n    Result := Succ(Integer(ParamType));\n  end;\nend;\n\nfunction wbCTDAParam2Decider(aBasePtr: Pointer; aEndPtr: Pointer; const aElement: IwbElement): Integer;\nvar\n  Desc: PCTDAFunction;\n  Container: IwbContainer;\n  ParamFlag: Byte;\n  ParamType: TCTDAFunctionParamType;\nbegin\n  Result := 0;\n  if not Assigned(aElement) then Exit;\n  Container := GetContainerFromUnion(aElement);\n  if not Assigned(Container) then Exit;\n\n  Desc := wbCTDAParamDescFromIndex(Container.ElementByName['Function'].NativeValue);\n\n  if Assigned(Desc) then begin\n    ParamType := Desc.ParamType2;\n    ParamFlag := Container.ElementByName['Type'].NativeValue;\n    if ParamType in [ptObjectReference, ptActor, ptPackage] then begin\n      if ParamFlag and $02 > 0 then ParamType := ptAlias else {>>> 'use aliases' is set <<<}\n      if ParamFlag and $08 > 0 then ParamType := ptPackdata;  {>>> 'use packdata' is set <<<}\n    end;\n    Result := Succ(Integer(ParamType));\n  end;\nend;\n\nfunction wbCTDAParam2VATSValueParamDecider(aBasePtr: Pointer; aEndPtr: Pointer; const aElement: IwbElement): Integer;\nvar\n  Container : IwbContainer;\nbegin\n  Result := 0;\n  if not Assigned(aElement) then Exit;\n  Container := GetContainerFromUnion(aElement);\n  if not Assigned(Container) then Exit;\n\n  Result := Container.ElementByName['Parameter #1'].NativeValue;\nend;\n\nfunction wbCTDAFunctionToStr(aInt: Int64; const aElement: IwbElement; aType: TwbCallbackType): string;\nvar\n  Desc : PCTDAFunction;\n  i    : Integer;\nbegin\n  Result := '';\n  case aType of\n    ctToStr, ctToEditValue: begin\n      Desc := wbCTDAParamDescFromIndex(aInt);\n      if Assigned(Desc) then\n        Result := Desc.Name\n      else if aType = ctToEditValue then\n        Result := IntToStr(aInt)\n      else\n        Result := '<Unknown: '+IntToStr(aInt)+'>';\n    end;\n    ctToSortKey: Result := IntToHex(aInt, 8);\n    ctCheck: begin\n      Desc := wbCTDAParamDescFromIndex(aInt);\n      if Assigned(Desc) then\n        Result := ''\n      else\n        Result := '<Unknown: '+IntToStr(aInt)+'>';\n    end;\n    ctEditType:\n      Result := 'ComboBox';\n    ctEditInfo: begin\n      Result := wbCTDAFunctionEditInfo;\n      if Result = '' then begin\n        with TStringList.Create do try\n          for i := Low(wbCTDAFunctions) to High(wbCTDAFunctions) do\n            Add(wbCTDAFunctions[i].Name);\n          Sort;\n          Result := CommaText;\n        finally\n          Free;\n        end;\n        wbCTDAFunctionEditInfo := Result;\n      end;\n    end;\n  end;\nend;\n\nfunction wbCTDAFunctionToInt(const aString: string; const aElement: IwbElement): Int64;\nvar\n  i: Integer;\nbegin\n  for i := Low(wbCTDAFunctions) to High(wbCTDAFunctions) do\n    with wbCTDAFunctions[i] do\n      if SameText(Name, aString) then begin\n        Result := Index;\n        Exit;\n      end;\n  Result := StrToInt64(aString);\nend;\n\nfunction wbNeverShow(const aElement: IwbElement): Boolean;\nbegin\n  Result := wbHideNeverShow;\nend;\n\nfunction GetREGNType(aElement: IwbElement): Integer;\nvar\n  Container: IwbContainerElementRef;\nbegin\n  Result := -1;\n  if not Assigned(aElement) then\n    Exit;\n  while aElement.Name <> 'Region Data Entry' do begin\n    aElement := aElement.Container;\n    if not Assigned(aElement) then\n      Exit;\n  end;\n  if not Supports(aElement, IwbContainerElementRef, Container) then\n    Exit;\n  Result := Container.ElementNativeValues['RDAT\\Type'];\nend;\n\nfunction wbREGNObjectsDontShow(const aElement: IwbElement): Boolean;\nbegin\n  Result := GetREGNType(aElement) <> 2;\nend;\n\nfunction wbREGNWeatherDontShow(const aElement: IwbElement): Boolean;\nbegin\n  Result := GetREGNType(aElement) <> 3;\nend;\n\nfunction wbREGNMapDontShow(const aElement: IwbElement): Boolean;\nbegin\n  Result := GetREGNType(aElement) <> 4;\nend;\n\nfunction wbREGNLandDontShow(const aElement: IwbElement): Boolean;\nbegin\n  Result := GetREGNType(aElement) <> 5;\nend;\n\nfunction wbREGNGrassDontShow(const aElement: IwbElement): Boolean;\nbegin\n  Result := GetREGNType(aElement) <> 6;\nend;\n\nfunction wbREGNSoundDontShow(const aElement: IwbElement): Boolean;\nbegin\n  Result := GetREGNType(aElement) <> 7;\nend;\n\nfunction wbREGNImposterDontShow(const aElement: IwbElement): Boolean;\nbegin\n  Result := GetREGNType(aElement) <> 8;\nend;\n\nfunction wbMESGTNAMDontShow(const aElement: IwbElement): Boolean;\nvar\n  Container  : IwbContainerElementRef;\n  MainRecord : IwbMainRecord;\nbegin\n  Result := False;\n  if not Supports(aElement, IwbMainRecord, MainRecord) then\n    Exit;\n  if not Supports(aElement, IwbContainerElementRef, Container) then\n    Exit;\n  if Integer(Container.ElementNativeValues['DNAM']) and 1 <> 0 then\n    Result := True;\nend;\n\nfunction wbEPFDDontShow(const aElement: IwbElement): Boolean;\nvar\n  Container: IwbContainerElementRef;\nbegin\n  Result := False;\n  if aElement.Name <> 'Entry Point Function Parameters' then\n    Exit;\n  if not Supports(aElement, IwbContainerElementRef, Container) then\n    Exit;\n  if not (Integer(Container.ElementNativeValues['EPFT']) in [1..3]) then\n    Result := True;\nend;\n\nfunction wbTES4ONAMDontShow(const aElement: IwbElement): Boolean;\nvar\n  MainRecord : IwbMainRecord;\nbegin\n  Result := False;\n  if not Assigned(aElement) then\n    Exit;\n  MainRecord := aElement.ContainingMainRecord;\n  if not Assigned(MainRecord) then\n    Exit;\n  if not MainRecord.IsESM then\n    Result := True;\nend;\n\nfunction wbEPF2DontShow(const aElement: IwbElement): Boolean;\nvar\n  Container: IwbContainerElementRef;\nbegin\n  Result := False;\n  if aElement.Name <> 'Entry Point Function Parameters' then\n    Exit;\n  if not Supports(aElement, IwbContainerElementRef, Container) then\n    Exit;\n  if not (Integer(Container.ElementNativeValues['EPFT']) in [4]) then\n    Result := True;\nend;\n\nprocedure wbRemoveOFST(const aElement: IwbElement);\nvar\n  Container: IwbContainer;\n  rOFST: IwbRecord;\nbegin\n  if not wbRemoveOffsetData then\n    Exit;\n\n  if Supports(aElement, IwbContainer, Container) then begin\n    if wbBeginInternalEdit then try\n      Container.RemoveElement(OFST);\n    finally\n      wbEndInternalEdit;\n    end else begin\n      rOFST := Container.RecordBySignature[OFST];\n      if Assigned(rOFST) then\n        Container.RemoveElement(rOFST);\n    end;\n  end;\nend;\n\nprocedure wbWRLDAfterLoad(const aElement: IwbElement);\n  function OutOfRange(aValue: Integer; aRange: Integer = 256): Boolean;\n  begin\n    Result := (aValue < -aRange) or (aValue > aRange);\n  end;\nvar\n  MainRecord: IwbMainRecord;\n  Container: IwbContainer;\nbegin\n  wbRemoveOFST(aElement);\n\n  if wbBeginInternalEdit then try\n\n    if not Supports(aElement, IwbMainRecord, MainRecord) then\n      Exit;\n\n    // not used in Skyrim\n    if MainRecord.ElementExists['Unused RNAM'] then\n      MainRecord.RemoveElement('Unused RNAM');\n\n    // used in SSE but remove from the game master to speed up worldspace browsing since it is huge\n    // and the game master is never saved anyway\n    if IsSSE and (MainRecord._File.LoadOrder = 0) then\n      MainRecord.RemoveElement('Large References');\n\n    // large values in object bounds cause stutter and performance issues in game (reported by Arthmoor)\n    // CK can occasionally set them wrong, so make a warning\n    if Supports(MainRecord.ElementByName['Object Bounds'], IwbContainer, Container) then\n      if OutOfRange(StrToIntDef(Container.ElementEditValues['NAM0\\X'], 0)) or\n         OutOfRange(StrToIntDef(Container.ElementEditValues['NAM0\\Y'], 0)) or\n         OutOfRange(StrToIntDef(Container.ElementEditValues['NAM9\\X'], 0)) or\n         OutOfRange(StrToIntDef(Container.ElementEditValues['NAM9\\Y'], 0))\n      then\n        wbProgressCallback('<Warning: Object Bounds in ' + MainRecord.Name + ' are abnormally large and can cause performance issues in game>');\n\n  finally\n    wbEndInternalEdit;\n  end;\nend;\n\nprocedure wbDOBJObjectsAfterLoad(const aElement: IwbElement);\nvar\n  ObjectsContainer : IwbContainerElementRef;\n  i                : Integer;\n  ObjectContainer  : IwbContainerElementRef;\nbegin\n  wbRemoveOFST(aElement);\n\n  if wbBeginInternalEdit then try\n\n    if not Supports(aElement, IwbContainerElementRef, ObjectsContainer) then\n      Exit;\n\n    for i := Pred(ObjectsContainer.ElementCount) downto 0 do\n      if Supports(ObjectsContainer.Elements[i], IwbContainerElementRef, ObjectContainer) then\n        if ObjectContainer.ElementNativeValues['Use'] = 0 then\n          ObjectsContainer.RemoveElement(i, True);\n  finally\n    wbEndInternalEdit;\n  end;\nend;\n\nfunction wbActorTemplateUseTraits(const aElement: IwbElement): Boolean;\nvar\n  Element    : IwbElement;\n  MainRecord : IwbMainRecord;\n  i          : Int64;\nbegin\n  Result := False;\n  Element := aElement;\n  MainRecord := nil;\n  while Assigned(Element) and not Supports(Element, IwbMainRecord, MainRecord) do\n    Element := Element.Container;\n  if Assigned(MainRecord) then begin\n    i := MainRecord.ElementNativeValues['ACBS\\Template Flags'];\n    Result := (i and $00000001) <> 0;\n  end;\nend;\n\nfunction wbActorTemplateUseStats(const aElement: IwbElement): Boolean;\nvar\n  Element    : IwbElement;\n  MainRecord : IwbMainRecord;\n  i          : Int64;\nbegin\n  Result := False;\n  Element := aElement;\n  MainRecord := nil;\n  while Assigned(Element) and not Supports(Element, IwbMainRecord, MainRecord) do\n    Element := Element.Container;\n  if Assigned(MainRecord) then begin\n    i := MainRecord.ElementNativeValues['ACBS\\Template Flags'];\n    Result := (i and $00000002) <> 0;\n  end;\nend;\n\nfunction wbActorAutoCalcDontShow(const aElement: IwbElement): Boolean;\nvar\n  Element    : IwbElement;\n  MainRecord : IwbMainRecord;\n  i          : Int64;\nbegin\n  Result := False;\n  Element := aElement;\n  MainRecord := nil;\n  while Assigned(Element) and not Supports(Element, IwbMainRecord, MainRecord) do\n    Element := Element.Container;\n  if Assigned(MainRecord) then begin\n    i := MainRecord.ElementNativeValues['ACBS\\Flags'];\n    Result := (i and $00000010) <> 0;\n  end;\nend;\n\nfunction wbActorTemplateUseStatsAutoCalc(const aElement: IwbElement): Boolean;\nbegin\n  Result := wbActorTemplateUseStats(aElement) or wbActorAutoCalcDontShow(aElement);\nend;\n\nfunction wbActorTemplateUseFactions(const aElement: IwbElement): Boolean;\nvar\n  Element    : IwbElement;\n  MainRecord : IwbMainRecord;\n  i          : Int64;\nbegin\n  Result := False;\n  Element := aElement;\n  MainRecord := nil;\n  while Assigned(Element) and not Supports(Element, IwbMainRecord, MainRecord) do\n    Element := Element.Container;\n  if Assigned(MainRecord) then begin\n    i := MainRecord.ElementNativeValues['ACBS\\Template Flags'];\n    Result := (i and $00000004) <> 0;\n  end;\nend;\n\nfunction wbActorTemplateUseActorEffectList(const aElement: IwbElement): Boolean;\nvar\n  Element    : IwbElement;\n  MainRecord : IwbMainRecord;\n  i          : Int64;\nbegin\n  Result := False;\n  Element := aElement;\n  MainRecord := nil;\n  while Assigned(Element) and not Supports(Element, IwbMainRecord, MainRecord) do\n    Element := Element.Container;\n  if Assigned(MainRecord) then begin\n    i := MainRecord.ElementNativeValues['ACBS\\Template Flags'];\n    Result := (i and $00000008) <> 0;\n  end;\nend;\n\nfunction wbActorTemplateUseAIData(const aElement: IwbElement): Boolean;\nvar\n  Element    : IwbElement;\n  MainRecord : IwbMainRecord;\n  i          : Int64;\nbegin\n  Result := False;\n  Element := aElement;\n  MainRecord := nil;\n  while Assigned(Element) and not Supports(Element, IwbMainRecord, MainRecord) do\n    Element := Element.Container;\n  if Assigned(MainRecord) then begin\n    i := MainRecord.ElementNativeValues['ACBS\\Template Flags'];\n    Result := (i and $00000010) <> 0;\n  end;\nend;\n\nfunction wbActorTemplateUseAIPackages(const aElement: IwbElement): Boolean;\nvar\n  Element    : IwbElement;\n  MainRecord : IwbMainRecord;\n  i          : Int64;\nbegin\n  Result := False;\n  Element := aElement;\n  MainRecord := nil;\n  while Assigned(Element) and not Supports(Element, IwbMainRecord, MainRecord) do\n    Element := Element.Container;\n  if Assigned(MainRecord) then begin\n    i := MainRecord.ElementNativeValues['ACBS\\Template Flags'];\n    Result := (i and $00000020) <> 0;\n  end;\nend;\n\nfunction wbActorTemplateUseModelAnimation(const aElement: IwbElement): Boolean;\nvar\n  Element    : IwbElement;\n  MainRecord : IwbMainRecord;\n  i          : Int64;\nbegin\n  Result := False;\n  Element := aElement;\n  MainRecord := nil;\n  while Assigned(Element) and not Supports(Element, IwbMainRecord, MainRecord) do\n    Element := Element.Container;\n  if Assigned(MainRecord) then begin\n    i := MainRecord.ElementNativeValues['ACBS\\Template Flags'];\n    Result := (i and $00000040) <> 0;\n  end;\nend;\n\nfunction wbActorTemplateUseBaseData(const aElement: IwbElement): Boolean;\nvar\n  Element    : IwbElement;\n  MainRecord : IwbMainRecord;\n  i          : Int64;\nbegin\n  Result := False;\n  Element := aElement;\n  MainRecord := nil;\n  while Assigned(Element) and not Supports(Element, IwbMainRecord, MainRecord) do\n    Element := Element.Container;\n  if Assigned(MainRecord) then begin\n    i := MainRecord.ElementNativeValues['ACBS\\Template Flags'];\n    Result := (i and $00000080) <> 0;\n  end;\nend;\n\nfunction wbActorTemplateUseInventory(const aElement: IwbElement): Boolean;\nvar\n  Element    : IwbElement;\n  MainRecord : IwbMainRecord;\n  i          : Int64;\nbegin\n  Result := False;\n  Element := aElement;\n  MainRecord := nil;\n  while Assigned(Element) and not Supports(Element, IwbMainRecord, MainRecord) do\n    Element := Element.Container;\n  if Assigned(MainRecord) then begin\n    i := MainRecord.ElementNativeValues['ACBS\\Template Flags'];\n    Result := (i and $00000100) <> 0;\n  end;\nend;\n\nfunction wbActorTemplateUseScript(const aElement: IwbElement): Boolean;\nvar\n  Element    : IwbElement;\n  MainRecord : IwbMainRecord;\n  i          : Int64;\nbegin\n  Result := False;\n  Element := aElement;\n  MainRecord := nil;\n  while Assigned(Element) and not Supports(Element, IwbMainRecord, MainRecord) do\n    Element := Element.Container;\n  if Assigned(MainRecord) then begin\n    i := MainRecord.ElementNativeValues['ACBS\\Template Flags'];\n    Result := (i and $00000200) <> 0;\n  end;\nend;\n\nprocedure wbRemoveEmptyKWDA(const aElement: IwbElement);\nvar\n  Container  : IwbContainerElementRef;\n  MainRecord : IwbMainRecord;\nbegin\n  if wbBeginInternalEdit then try\n    if not Supports(aElement, IwbContainerElementRef, Container) then\n      Exit;\n\n    if Container.ElementCount < 1 then\n      Exit;\n\n    if not Supports(aElement, IwbMainRecord, MainRecord) then\n      Exit;\n\n    if MainRecord.IsDeleted then\n      Exit;\n\n    if not Assigned(Container.ElementBySignature['KSIZ']) then\n      if Assigned(Container.ElementBySignature['KWDA']) then\n        Container.ElementBySignature['KWDA'].Remove;\n\n  finally\n    wbEndInternalEdit;\n  end;\nend;\n\nprocedure wbReplaceBODTwithBOD2(const aElement: IwbElement);\nvar\n  MainRecord    : IwbMainRecord;\n  ContainerBOD2 : IwbContainerElementRef;\n  ContainerBODT : IwbContainerElementRef;\nbegin\n  Exit; {>>> Looks like causes problems with Dawnguard.esm <<<}\n\n  if wbBeginInternalEdit then try\n    if not Supports(aElement, IwbMainRecord, MainRecord) then\n      Exit;\n\n    if not Supports(MainRecord.ElementBySignature[BODT], IwbContainerElementRef, ContainerBODT) then\n      Exit;\n\n    if Supports(MainRecord.Add('BOD2', True), IwbContainerElementRef, ContainerBOD2) then begin\n       ContainerBOD2.ElementNativeValues['First Person Flags'] := ContainerBODT.ElementNativeValues['First Person Flags'];\n       ContainerBOD2.ElementNativeValues['Armor Type'] := ContainerBODT.ElementNativeValues['Armor Type'];\n       MainRecord.RemoveElement(BODT);\n    end;\n\n  finally\n    wbEndInternalEdit;\n  end;\nend;\n\nprocedure wbARMOAfterLoad(const aElement: IwbElement);\nbegin\n  wbRemoveEmptyKWDA(aElement);\n  wbReplaceBODTwithBOD2(aElement);\nend;\n\nprocedure wbARMAAfterLoad(const aElement: IwbElement);\n{var\n  MainRecord    : IwbMainRecord;}\nbegin\n  wbReplaceBODTwithBOD2(aElement);\n  {if wbBeginInternalEdit then try\n    if not Supports(aElement, IwbMainRecord, MainRecord) then\n      Exit;\n    if MainRecord.ElementNativeValues['DNAM\\Weight slider - Male'] = 0 then\n      MainRecord.ElementNativeValues['DNAM\\Weight slider - Male'] := 2;\n    if MainRecord.ElementNativeValues['DNAM\\Weight slider - Female'] = 0 then\n      MainRecord.ElementNativeValues['DNAM\\Weight slider - Female'] := 2;\n  finally\n    wbEndInternalEdit;\n  end;}\nend;\n\nprocedure wbNPCAfterLoad(const aElement: IwbElement);\nbegin\n  wbRemoveEmptyKWDA(aElement);\nend;\n\nprocedure wbREFRAfterLoad(const aElement: IwbElement);\nvar\n  Container  : IwbContainerElementRef;\n  MainRecord : IwbMainRecord;\nbegin\n  if wbBeginInternalEdit then try\n    if not Supports(aElement, IwbContainerElementRef, Container) then\n      Exit;\n\n    if Container.ElementCount < 1 then\n      Exit;\n\n    if not Supports(aElement, IwbMainRecord, MainRecord) then\n      Exit;\n\n    if MainRecord.IsDeleted then\n      Exit;\n\n    if Container.ElementExists['XLOC'] then begin\n      if Container.ElementNativeValues['XLOC - Lock Data\\Level'] = 0 then\n        Container.ElementNativeValues['XLOC - Lock Data\\Level'] := 1;\n    end;\n\n    Container.RemoveElement('XPTL');\n  finally\n    wbEndInternalEdit;\n  end;\nend;\n\nprocedure wbRACEAfterLoad(const aElement: IwbElement);\nbegin\n  wbReplaceBODTwithBOD2(aElement);\nend;\n\nprocedure wbWEAPAfterLoad(const aElement: IwbElement);\nvar\n  Container  : IwbContainerElementRef;\n  MainRecord : IwbMainRecord;\n  Flags      : Cardinal;\nbegin\n  wbRemoveEmptyKWDA(aElement);\n\n  if wbBeginInternalEdit then try\n    if not Supports(aElement, IwbContainerElementRef, Container) then\n      Exit;\n\n    if Container.ElementCount < 1 then\n      Exit;\n\n    if not Supports(aElement, IwbMainRecord, MainRecord) then\n      Exit;\n\n    if MainRecord.IsDeleted then\n      Exit;\n\n    // clear IronSights flags which are randomly assigned in CK\n    if Container.ElementExists['DNAM'] then begin\n      Flags := Container.ElementNativeValues['DNAM - Data\\Flags'];\n      Flags := Flags and ($FFFF xor $0040);\n      Container.ElementNativeValues['DNAM - Data\\Flags'] := Flags;\n      Flags := Container.ElementNativeValues['DNAM - Data\\Flags2'];\n      Flags := Flags and ($FFFFFFFF xor $0100);\n      Container.ElementNativeValues['DNAM - Data\\Flags2'] := Flags;\n    end;\n\n  finally\n    wbEndInternalEdit;\n  end;\nend;\n\nprocedure wbCELLXCLWGetConflictPriority(const aElement: IwbElement; var aCP: TwbConflictPriority);\nvar\n  Container  : IwbContainerElementRef;\n  MainRecord : IwbMainRecord;\n  DataRec    : IwbElement;\n  Flags      : Cardinal;\nbegin\n  if not Assigned(aElement) then\n    Exit;\n\n  if not Supports(aElement.Container, IwbContainerElementRef, Container) then\n    Exit;\n\n  if Container.ElementCount < 1 then\n    Exit;\n\n  if not Supports(Container, IwbMainRecord, MainRecord) then\n    Exit;\n\n  if MainRecord.IsDeleted then\n    Exit;\n\n  DataRec := MainRecord.ElementBySignature[DATA];\n\n  if not Assigned(DataRec) then\n    Exit;\n\n  Flags := DataRec.NativeValue;\n\n  {0x0001 Is Interior Cell}\n  if (Flags and 1) = 1 then\n    {Interior cells don't use water level in Skyrim at all}\n    aCP := cpIgnore;\nend;\n\nprocedure wbCELLDATAAfterSet(const aElement: IwbElement; const aOldValue, aNewValue: Variant);\nvar\n  Container : IwbContainer;\nbegin\n  if not Assigned(aElement) then\n    Exit;\n  Container := aElement.Container;\n  while Assigned(Container) and not (Container.Def.DefType = dtRecord) do\n    Container := Container.Container;\n  if Assigned(Container) then\n    Container.ResetConflict;\nend;\n\nprocedure wbCELLAfterLoad(const aElement: IwbElement);\nvar\n  Container    : IwbContainerElementRef;\n//  Container2   : IwbContainerElementRef;\n  MainRecord   : IwbMainRecord;\n  DataSubRec   : IwbSubrecord;\n  Flags8       : Byte;\nbegin\n  if wbBeginInternalEdit then try\n    if not Supports(aElement, IwbContainerElementRef, Container) then\n      Exit;\n\n    if Container.ElementCount < 1 then\n      Exit;\n\n    if not Supports(aElement, IwbMainRecord, MainRecord) then\n      Exit;\n\n    if MainRecord.IsDeleted then\n      Exit;\n\n    if Supports(Container.ElementBySignature['DATA'] , IwbSubRecord, DataSubRec) then begin\n      // expand legacy itU8 flags to itU16\n      if DataSubRec.SubRecordHeaderSize = 1 then begin\n        Flags8 := PByte(DataSubRec.DataBasePtr)^;\n        DataSubRec.SetToDefault;\n        DataSubRec.NativeValue := Flags8;\n      end;\n      // 'Default' water height for exterior cells if not set (so water height will be taken from WRLD by game)\n      if (not Container.ElementExists['XCLW']) and ((Integer(DataSubRec.NativeValue) and $02) <> 0) then begin\n        Container.Add('XCLW', True);\n        Container.ElementEditValues['XCLW'] := 'Default';\n      end;\n    end;\n\n    // Min (-0 as in CK) water height is set to 0 when saving in CK\n    if Container.ElementEditValues['XCLW'] = 'Min' then\n      Container.ElementEditValues['XCLW'] := '0.0';\n\n//    if Supports(Container.ElementBySignature[XCLR], IwbContainerElementRef, Container2) then begin\n//      for i := Pred(Container2.ElementCount) downto 0 do\n//        if not Supports(Container2.Elements[i].LinksTo, IwbMainRecord, MainRecord) or (MainRecord.Signature <> 'REGN') then\n//          Container2.RemoveElement(i);\n//      if Container2.ElementCount < 1 then\n//        Container2.Remove;\n//    end;\n  finally\n    wbEndInternalEdit;\n  end;\nend;\n\nprocedure wbMESGAfterLoad(const aElement: IwbElement);\nvar\n  Container    : IwbContainerElementRef;\n  MainRecord   : IwbMainRecord;\n  IsMessageBox : Boolean;\n  HasTimeDelay : Boolean;\nbegin\n  if wbBeginInternalEdit then try\n    if not Supports(aElement, IwbContainerElementRef, Container) then\n      Exit;\n\n    if Container.ElementCount < 1 then\n      Exit;\n\n    if not Supports(aElement, IwbMainRecord, MainRecord) then\n      Exit;\n\n    if MainRecord.IsDeleted then\n      Exit;\n\n    IsMessageBox := (Integer(Container.ElementNativeValues['DNAM']) and 1) = 1;\n    HasTimeDelay := Container.ElementExists['TNAM'];\n\n    if IsMessageBox = HasTimeDelay then\n      if IsMessageBox then\n        Container.RemoveElement('TNAM')\n      else begin\n        if not Container.ElementExists['DNAM'] then\n          Container.Add('DNAM', True);\n        Container.ElementNativeValues['DNAM'] := Integer(Container.ElementNativeValues['DNAM']) or 1;\n      end;\n\n  finally\n    wbEndInternalEdit;\n  end;\nend;\n\n\n{>>>\n  Updated, but not called for Skyrim\n  Why is it required to fix particle counts? Because 1 pass = 79 particles?\n>>>}\n//procedure wbEFSHAfterLoad(const aElement: IwbElement);\n//var\n//  Container: IwbContainerElementRef;\n//  MainRecord   : IwbMainRecord;\n//  FullParticleBirthRatio : Extended;\n//  PersistantParticleCount : Extended;\n//begin\n//  if wbBeginInternalEdit then try\n//    if not Supports(aElement, IwbContainerElementRef, Container) then\n//      Exit;\n//\n//    if Container.ElementCount < 1 then\n//      Exit;\n//\n//    if not Supports(aElement, IwbMainRecord, MainRecord) then\n//      Exit;\n//\n//    if MainRecord.IsDeleted then\n//      Exit;\n//\n//    if not Container.ElementExists['DATA'] then\n//      Exit;\n//\n//    FullParticleBirthRatio := Container.ElementNativeValues['DATA\\Particle Shader - Full Particle Birth Ratio'];\n//    PersistantParticleCount := Container.ElementNativeValues['DATA\\Particle Shader - Persistant Particle Count'];\n//\n//    if ((FullParticleBirthRatio <> 0) and (FullParticleBirthRatio <= 1)) then begin\n//      FullParticleBirthRatio := FullParticleBirthRatio * 78.0;\n//      Container.ElementNativeValues['DATA\\Particle Shader - Full Particle Birth Ratio'] := FullParticleBirthRatio;\n//    end;\n//\n//    if ((PersistantParticleCount <> 0) and (PersistantParticleCount <= 1)) then begin\n//      PersistantParticleCount := PersistantParticleCount * 78.0;\n//      Container.ElementNativeValues['DATA\\Particle Shader - Persistant Particle Count'] := PersistantParticleCount;\n//    end;\n//\n//  finally\n//    wbEndInternalEdit;\n//  end;\n//end;\n\nprocedure wbLIGHAfterLoad(const aElement: IwbElement);\nvar\n  Container: IwbContainerElementRef;\n  MainRecord   : IwbMainRecord;\nbegin\n  if wbBeginInternalEdit then try\n    if not Supports(aElement, IwbContainerElementRef, Container) then\n      Exit;\n\n    if Container.ElementCount < 1 then\n      Exit;\n\n    if not Supports(aElement, IwbMainRecord, MainRecord) then\n      Exit;\n\n    if MainRecord.IsDeleted then\n      Exit;\n\n    if not Container.ElementExists['FNAM'] then begin\n      Container.Add('FNAM', True);\n      Container.ElementNativeValues['FNAM'] := 1.0;\n    end;\n\n    if Container.ElementExists['DATA'] then begin\n      if SameValue(Container.ElementNativeValues['DATA\\Falloff Exponent'], 0.0) then\n        Container.ElementNativeValues['DATA\\Falloff Exponent'] := 1.0;\n      if SameValue(Container.ElementNativeValues['DATA\\FOV'], 0.0) then\n        Container.ElementNativeValues['DATA\\FOV'] := 90.0;\n    end;\n\n  finally\n    wbEndInternalEdit;\n  end;\nend;\n\nprocedure wbEFITAfterLoad(const aElement: IwbElement);\nvar\n  Container : IwbContainerElementRef;\n  Element   : IwbElement;\n  ActorValue: Variant;\n  MainRecord: IwbMainRecord;\nbegin\n  if wbBeginInternalEdit then try\n    if not Supports(aElement, IwbContainerElementRef, Container) then\n      Exit;\n\n    if Container.ElementCount < 1 then\n      Exit;\n\n    MainRecord := Container.ContainingMainRecord;\n    if not Assigned(MainRecord) or MainRecord.IsDeleted then\n      Exit;\n\n    Element := Container.ElementByPath['..\\EFID'];\n    if not Assigned(Element) then\n      Exit;\n    if not Supports(Element.LinksTo, IwbMainRecord, MainRecord) then\n      Exit;\n    if MainRecord.Signature <> 'MGEF' then\n      Exit;\n    ActorValue := MainRecord.ElementNativeValues['DATA - Data\\Actor Value'];\n    if VarIsNull(ActorValue) or VarIsClear(ActorValue) then\n      Exit;\n    if VarCompareValue(ActorValue, Container.ElementNativeValues['Actor Value']) <> vrEqual then\n      Container.ElementNativeValues['Actor Value'] := ActorValue;\n  finally\n    wbEndInternalEdit;\n  end;\nend;\n\nprocedure wbRPLDAfterLoad(const aElement: IwbElement);\nvar\n  Container: IwbContainer;\n  a, b: Single;\n  NeedsFlip: Boolean;\nbegin\n  if wbBeginInternalEdit then try\n    if Supports(aElement, IwbContainer, Container) then begin\n      NeedsFlip := False;\n      if Container.ElementCount > 1 then begin\n        a := StrToFloat((Container.Elements[0] as IwbContainer).Elements[0].Value);\n        b := StrToFloat((Container.Elements[Pred(Container.ElementCount)] as IwbContainer).Elements[0].Value);\n        case CompareValue(a, b) of\n          EqualsValue: begin\n            a := StrToFloat((Container.Elements[0] as IwbContainer).Elements[1].Value);\n            b := StrToFloat((Container.Elements[Pred(Container.ElementCount)] as IwbContainer).Elements[1].Value);\n            NeedsFlip := CompareValue(a, b) = GreaterThanValue;\n          end;\n          GreaterThanValue:\n            NeedsFlip := True;\n        end;\n      end;\n      if NeedsFlip then\n        Container.ReverseElements;\n    end;\n  finally\n    wbEndInternalEdit;\n  end;\nend;\n\nfunction wbPubPackCNAMDecider(aBasePtr: Pointer; aEndPtr: Pointer; const aElement: IwbElement): Integer;\nvar\n  rANAM: IwbRecord;\n  ctype: string;\nbegin\n  Result := 0;\n  rANAM := aElement.Container.RecordBySignature[ANAM];\n  if Assigned(rANAM) then begin\n    ctype := rANAM.NativeValue;\n    if ctype = 'Bool' then Result := 1 else\n    if ctype = 'Int' then Result := 2 else\n    if ctype = 'Float' then Result := 3 else\n    if ctype = 'ObjectList' then Result := 3;\n  end;\nend;\n\nfunction wbTypeDecider(aBasePtr: Pointer; aEndPtr: Pointer; const aElement: IwbElement): Integer;\nvar\n  Container : IwbContainer;\n  Element   : IwbElement;\nbegin\n  Result := 0;\n  if not Assigned(aElement) then Exit;\n  Container := GetContainerFromUnion(aElement);\n  if not Assigned(Container) then Exit;\n\n  Element := Container.ElementByName['Type'];\n  if Assigned(Element) then\n    Result := Element.NativeValue\n  else if wbMoreInfoForDecider then\n    wbProgressCallback('\"'+Container.Name+'\" does not contain an element named Type');\nend;\n\nprocedure wbCNTOsAfterSet(const aElement: IwbElement; const aOldValue, aNewValue: Variant);\nbegin\n  wbCounterAfterSet('COCT - Count', aElement);\nend;\n\nprocedure wbContainerAfterSet(const aElement: IwbElement; const aOldValue, aNewValue: Variant);\nbegin\n  wbCounterContainerAfterSet('COCT - Count', 'Items', aElement);\n  wbCounterContainerAfterSet('KSIZ - Keyword Count', 'KWDA - Keywords', aElement);\nend;\n\nprocedure wbSPLOsAfterSet(const aElement: IwbElement; const aOldValue, aNewValue: Variant);\nbegin\n  wbCounterAfterSet('SPCT - Count', aElement);\nend;\n\nprocedure wbKWDAsAfterSet(const aElement: IwbElement; const aOldValue, aNewValue: Variant);\nbegin\n  wbCounterAfterSet('KSIZ - Keyword Count', aElement);\nend;\n\nprocedure wbNPCAfterSet(const aElement: IwbElement; const aOldValue, aNewValue: Variant);\nbegin\n  wbCounterContainerAfterSet('COCT - Count', 'Items', aElement);\n  wbCounterContainerAfterSet('SPCT - Count', 'Actor Effects', aElement);\n  wbCounterContainerAfterSet('LLCT - Count', 'Leveled List Entries', aElement);\n  wbCounterContainerAfterSet('KSIZ - Keyword Count', 'KWDA - Keywords', aElement);\n  wbCounterContainerAfterSet('PRKZ - Perk Count', 'Perks', aElement);\nend;\n\nprocedure wbRaceAfterSet(const aElement: IwbElement; const aOldValue, aNewValue: Variant);\nbegin\n  wbCounterContainerAfterSet('SPCT - Count', 'Actor Effects', aElement);\n  wbCounterContainerAfterSet('KSIZ - Keyword Count', 'KWDA - Keywords', aElement);\nend;\n\nprocedure wbKeywordsAfterSet(const aElement: IwbElement; const aOldValue, aNewValue: Variant);\nbegin\n  wbCounterContainerAfterSet('KSIZ - Keyword Count', 'KWDA - Keywords', aElement);\nend;\n\nprocedure wbLVLOsAfterSet(const aElement: IwbElement; const aOldValue, aNewValue: Variant);\nbegin\n  wbCounterAfterSet('LLCT - Count', aElement);\nend;\n\nprocedure wbLLEAfterSet(const aElement: IwbElement; const aOldValue, aNewValue: Variant);\nbegin\n  wbCounterContainerAfterSet('LLCT - Count', 'Leveled List Entries', aElement);\nend;\n\nprocedure wbPRKRsAfterSet(const aElement: IwbElement; const aOldValue, aNewValue: Variant);\nbegin\n  wbCounterAfterSet('PRKZ - Perk Count', aElement);\nend;\n\nprocedure wbSMQNQuestsAfterSet(const aElement: IwbElement; const aOldValue, aNewValue: Variant);\nbegin\n  wbCounterAfterSet('QNAM - Quest Count', aElement);\nend;\n\nprocedure wbCTDAsAfterSet(const aElement: IwbElement; const aOldValue, aNewValue: Variant);\nbegin\n  wbCounterAfterSet('CITC - Condition Count', aElement);\nend;\n\nprocedure wbConditionsAfterSet(const aElement: IwbElement; const aOldValue, aNewValue: Variant);\nbegin\n  wbCounterContainerAfterSet('CITC - Condition Count', 'Conditions', aElement);\nend;\n\nprocedure wbCounterEffectsAfterSet(const aElement: IwbElement; const aOldValue, aNewValue: Variant);\nbegin\n  // if it is really possible to have both counter effects and multiple data, this is going to be tricky.\n  wbCounterByPathAfterSet('Magic Effect Data\\DATA - Data\\Counter effect count', aElement);\nend;\n\nprocedure wbMGEFAfterSet(const aElement: IwbElement; const aOldValue, aNewValue: Variant);\nbegin\n  wbKeywordsAfterSet(aElement, aOldValue, aNewValue);\n  wbCounterContainerByPathAfterSet('Magic Effect Data\\DATA - Data\\Counter effect count', 'Counter Effects', aElement);\nend;\n\nprocedure wbLENSAfterSet(const aElement: IwbElement; const aOldValue, aNewValue: Variant);\nbegin\n  wbCounterAfterSet('LFSP - Count', aElement);\nend;\n\nprocedure wbIDLAsAfterSet(const aElement: IwbElement; const aOldValue, aNewValue: Variant);\nvar\n  Element         : IwbElement;\n  Container       : IwbContainer;\n  SelfAsContainer : IwbContainer;\nbegin\n  if wbBeginInternalEdit then try\n    if not wbCounterAfterSet('IDLC - Animation Count', aElement) then\n      if Supports(aElement.Container, IwbContainer, Container) then begin\n        Element := Container.ElementByPath['IDLC\\Animation Count'];\n        if Assigned(Element) and Supports(aElement, IwbContainer, SelfAsContainer) and\n          (Element.GetNativeValue<>SelfAsContainer.GetElementCount) then\n          Element.SetNativeValue(SelfAsContainer.GetElementCount);\n      end;\n  finally\n    wbEndInternalEdit;\n  end;\nend;\n\nprocedure wbAnimationsAfterSet(const aElement: IwbElement; const aOldValue, aNewValue: Variant);\nvar\n  Element         : IwbElement;\n  Elems           : IwbElement;\n  Container       : IwbContainer;\nbegin\n  if wbBeginInternalEdit then try\n    if not wbCounterContainerAfterSet('IDLC - Animation Count', 'IDLA - Animations', aElement) then\n      if Supports(aElement, IwbContainer, Container) then begin\n        Element := Container.ElementByPath['IDLC\\Animation Count'];\n        Elems   := Container.ElementByName['IDLA - Animations'];\n        if Assigned(Element) and not Assigned(Elems) then\n          if Element.GetNativeValue<>0 then\n            Element.SetNativeValue(0);\n      end;\n  finally\n    wbEndInternalEdit;\n  end;\nend;\n\nfunction wbOffsetDataColsCounter(aBasePtr: Pointer; aEndPtr: Pointer; const aElement: IwbElement): Cardinal;\nvar\n  Container : IwbDataContainer;\n  Element   : IwbElement;\n  fResult   : Extended;\nbegin\n  Result := 0;\n\n  if Supports(aElement.Container, IwbDataContainer, Container) and (Container.Name = 'OFST - Offset Data') and\n     Supports(Container.Container, IwbDataContainer, Container) then begin\n    Element := Container.ElementByPath['Object Bounds\\NAM0 - Min\\X'];\n    if Assigned(Element) then begin\n      fResult :=  Element.NativeValue;\n      if fResult >= MaxInt then\n        Result := 0\n      else\n        Result := Trunc(fResult);\n      Element := Container.ElementByPath['Object Bounds\\NAM9 - Max\\X'];\n      if Assigned(Element) then begin\n        fResult :=  Element.NativeValue;\n        if fResult >= MaxInt then\n          Result := 1\n        else\n          Result := Trunc(fResult) - Result + 1;\n      end;\n    end;\n  end;\nend;\n\nfunction wbREFRRecordFlagsDecider(const aElement: IwbElement): Integer;\nvar\n  MainRecord : IwbMainRecord;\n  NameRec    : IwbElement;\nbegin\n  Result := 0;\n\n  if not Assigned(aElement) then\n    Exit;\n\n  MainRecord := aElement.ContainingMainRecord;\n\n  if not Assigned(MainRecord) then\n    Exit;\n\n  NameRec := MainRecord.ElementBySignature[NAME];\n  if not Assigned(NameRec) then\n    Exit;\n\n  if not Supports(NameRec.LinksTo, IwbMainRecord, MainRecord) then\n    Exit;\n\n  if (MainRecord.Signature = ACTI) or\n     (MainRecord.Signature = STAT) or\n     (MainRecord.Signature = TREE)\n  then\n    Result := 1\n  else if MainRecord.Signature = CONT then\n    Result := 2\n  else if MainRecord.Signature = DOOR then\n    Result := 3\n  else if MainRecord.Signature = LIGH then\n    Result := 4\n  else if MainRecord.Signature = MSTT then\n    Result := 5\n  else if MainRecord.Signature = ADDN then\n    Result := 6\n  else if\n     (MainRecord.Signature = SCRL) or\n     (MainRecord.Signature = AMMO) or\n     (MainRecord.Signature = ARMO) or\n     (MainRecord.Signature = BOOK) or\n     (MainRecord.Signature = INGR) or\n     (MainRecord.Signature = KEYM) or\n     (MainRecord.Signature = MISC) or\n     (MainRecord.Signature = SLGM) or\n     (MainRecord.Signature = WEAP) or\n     (MainRecord.Signature = ALCH)\n  then\n    Result := 7;\nend;\n\nfunction wbByteColors(const aName: string = 'Color'): IwbStructDef;\nbegin\n  Result := wbStruct(aName, [\n    wbInteger('Red', itU8),\n    wbInteger('Green', itU8),\n    wbInteger('Blue', itU8),\n    wbByteArray('Unused', 1)\n  ]);\nend;\n\nfunction wbFloatColors(const aName: string = 'Color'): IwbStructDef;\nbegin\n  Result := wbStruct(aName, [\n    wbFloat('Red', cpNormal, True, 255, 0),\n    wbFloat('Green', cpNormal, True, 255, 0),\n    wbFloat('Blue', cpNormal, True, 255, 0)\n  ]);\nend;\n\nfunction wbWeatherColors(const aName: string): IwbStructDef;\nbegin\n  Result := wbStruct(aName, [\n    wbByteColors('Sunrise'),\n    wbByteColors('Day'),\n    wbByteColors('Sunset'),\n    wbByteColors('Night')\n  ], cpNormal, True);\nend;\n\nfunction wbAmbientColors(const aSignature: TwbSignature; const aName: string = 'Directional Ambient Lighting Colors'): IwbSubRecordDef; overload;\nbegin\n  Result := wbStruct(aSignature, aName, [\n    wbStruct('Directional', [\n      wbByteColors('X+'),\n      wbByteColors('X-'),\n      wbByteColors('Y+'),\n      wbByteColors('Y-'),\n      wbByteColors('Z+'),\n      wbByteColors('Z-')\n    ]),\n    wbByteColors('Specular'),\n    wbFloat('Scale')\n  ], cpNormal, False, nil, 1)\nend;\n\nfunction wbAmbientColors(const aName: string = 'Directional Ambient Lighting Colors'): IwbStructDef; overload;\nbegin\n  Result := wbStruct(aName, [\n    wbStruct('Directional', [\n      wbByteColors('X+'),\n      wbByteColors('X-'),\n      wbByteColors('Y+'),\n      wbByteColors('Y-'),\n      wbByteColors('Z+'),\n      wbByteColors('Z-')\n    ]),\n    wbByteColors('Specular'),\n    wbFloat('Scale', cpIgnore)\n  ], cpNormal, False, nil, 1);\nend;\n\nfunction wbStrToInt(const aString: string; const aElement: IwbElement): Int64;\nvar\n  s: string;\n  i: integer;\nbegin\n  // ignore anything after space or :\n  i := Pos(' ', aString);\n  if i = 0 then\n    i := Pos(':', aString);\n\n  if i <> 0 then\n    s := Copy(aString, 1, i - 1)\n  else\n    s := aString;\n\n  try\n    Result := StrToInt64(s)\n  except\n    Result := 0;\n  end;\nend;\n\ntype\n  TFaceGenFeature = record\n    RaceID  : String;\n    Female  : Boolean;\n    Entries : array of record\n      Index: Cardinal;\n      Name : String;\n    end;\n  end;\n  PFaceGenFeature = ^TFaceGenFeature;\n\nvar\n  // cache of race specific tint layers\n  TintLayers: array of TFaceGenFeature;\n\nfunction wbTintLayerToStr(aInt: Int64; const aElement: IwbElement; aType: TwbCallbackType): string;\n\n  function GetCached(const aRaceID: string; aFemale: boolean): PFaceGenFeature;\n  var\n    i: integer;\n  begin\n    Result := nil;\n    if Length(TintLayers) <> 0 then\n      for i := Low(TintLayers) to High(TintLayers) do\n        if (TintLayers[i].Female = aFemale) and (TintLayers[i].RaceID = aRaceID) then begin\n          Result := @TintLayers[i];\n          Break;\n        end;\n  end;\n\nvar\n  Actor, Race       : IwbMainRecord;\n  Element           : IwbElement;\n  Container, Entry  : IwbContainerElementRef;\n  Female, Female2   : Boolean;\n  RaceID, EntryName : string;\n  s                 : string;\n  Cache             : PFaceGenFeature;\n  Index             : Cardinal;\n  i, j              : integer;\nbegin\n  // defaults\n  case aType of\n    ctToStr, ctToEditValue: Result := IntToStr(aInt);\n    ctToSortKey: begin\n      Result := IntToHex64(aInt, 8);\n      Exit;\n    end;\n    ctCheck: Result := '<Warning: Could not resolve tint layer index ' + IntToStr(aInt) + '>';\n    ctEditType: Result := '';\n    ctEditInfo: Result := '';\n  end;\n\n  Actor := aElement.ContainingMainRecord;\n  if not Assigned(Actor) then\n    Exit;\n\n  Female := Actor.ElementEditValues['ACBS\\Flags\\Female'] = '1';\n\n  Element := Actor.ElementBySignature['RNAM'];\n  if not Assigned(Element) then\n    Exit;\n\n  Element := Element.LinksTo;\n  if not Supports(Element, IwbMainRecord, Race) then\n    Exit;\n\n  Race := Race.WinningOverride;\n  RaceID := Race.EditorID;\n\n  Cache := GetCached(RaceID, Female);\n\n  // cache not found, fill with data from RACE\n  if not Assigned(Cache) then begin\n\n    for i := 0 to 1 do begin\n\n      Female2 := i = 1;\n      SetLength(TintLayers, Succ(Length(TintLayers)));\n      Cache := @TintLayers[Pred(Length(TintLayers))];\n      Cache.RaceID := RaceID;\n      Cache.Female := Female2;\n\n      if not Female2 then\n        Element := Race.ElementByPath['Head Data\\Male Head Data\\Tint Masks']\n      else\n        Element := Race.ElementByPath['Head Data\\Female Head Data\\Tint Masks'];\n\n      if not Supports(Element, IwbContainerElementRef, Container) then\n        Continue;\n\n      SetLength(Cache.Entries, Container.ElementCount);\n\n      for j := 0 to Pred(Container.ElementCount) do begin\n        if not Supports(Container.Elements[j], IwbContainerElementRef, Entry) then\n          Break;\n        Cache.Entries[j].Index := Entry.ElementNativeValues['Tint Layer\\Texture\\TINI'];\n        s := Entry.ElementEditValues['Tint Layer\\Texture\\TINP'];\n        // add texture name\n        if s <> '' then\n          s := '[' + s + '] ';\n        s := s + ChangeFileExt(ExtractFileName(Entry.ElementEditValues['Tint Layer\\Texture\\TINT']), '');\n        Cache.Entries[j].Name := s;\n      end;\n    end;\n\n    Cache := GetCached(RaceID, Female);\n  end;\n\n  if not Assigned(Cache) then\n    Exit;\n\n  EntryName := '';\n  Index := Cardinal(aInt);\n  if Length(Cache.Entries) <> 0 then\n    for i := Low(Cache.Entries) to High(Cache.Entries) do\n      if Cache.Entries[i].Index = Index then begin\n        EntryName := Cache.Entries[i].Name;\n        Break;\n      end;\n\n  case aType of\n    ctToStr: begin\n      if EntryName <> '' then\n        Result := IntToStr(aInt) + ' ' + EntryName\n      else\n        Result := IntToStr(aInt) + ' <Tint layer index not found in ' + Race.Name + '>';\n    end;\n    ctCheck: begin\n      if EntryName = '' then\n        Result := '<Tint layer index ' + IntToStr(aInt) + ' not found in ' + Race.Name + '>'\n      else\n        Result := '';\n    end;\n    ctEditType: Result := 'ComboBox';\n    ctEditInfo: begin\n      Result := '';\n      if Length(Cache.Entries) <> 0 then\n        for i := Low(Cache.Entries) to High(Cache.Entries) do begin\n          if Result <> '' then Result := Result + ',';\n          Result := Result + '\"' + IntToStr(Cache.Entries[i].Index) + ' ' + Cache.Entries[i].Name + '\"';\n        end;\n    end;\n  end;\nend;\n\n\nvar\n  wbRecordFlagsFlags : IwbFlagsDef;\n\nprocedure DefineTES5a;\n\nbegin\n  wbNull := wbByteArray('Unused', -255);\n  wbLLCT := wbInteger(LLCT, 'Count', itU8, nil, cpBenign);\n  wbCITC := wbInteger(CITC, 'Condition Count', itU32, nil, cpBenign);\n  wbLVLD := wbInteger(LVLD, 'Chance None', itU8, nil, cpNormal, True);\n\n  wbSPCT := wbInteger(SPCT, 'Count', itU32, nil, cpBenign);\n  wbSPLO := wbFormIDCk(SPLO, 'Actor Effect', [SPEL, SHOU, LVSP]);\n  wbSPLOs := wbRArrayS('Actor Effects', wbSPLO, cpNormal, False, nil, wbSPLOsAfterSet, nil{wbActorTemplateUseActorEffectList});\n\n  wbKSIZ := wbInteger(KSIZ, 'Keyword Count', itU32, nil, cpBenign);\n  wbKWDAs := wbArrayS(KWDA, 'Keywords', wbFormIDCk('Keyword', [KYWD, NULL]), 0, cpNormal, False, nil, wbKWDAsAfterSet);\n  wbReqKWDAs := wbArrayS(KWDA, 'Keywords', wbFormIDCk('Keyword', [KYWD, NULL]), 0, cpNormal, True, nil, wbKWDAsAfterSet);\n\n  wbKeywords := wbRStruct('Keywords', [\n    wbKSIZ,\n    wbReqKWDAs\n  ], []);\n\n  wbCOED := wbStructExSK(COED, [2], [0, 1], 'Extra Data', [\n    {00} wbFormIDCkNoReach('Owner', [NPC_, FACT, NULL]),\n    {04} wbUnion('Global Variable / Required Rank', wbCOEDOwnerDecider, [\n           wbByteArray('Unused', 4, cpIgnore),\n           wbFormIDCk('Global Variable', [GLOB, NULL]),\n           wbInteger('Required Rank', itS32)\n         ]),\n    {08} wbFloat('Item Condition')\n  ]);\n\n  wbCNTO :=\n    wbRStructExSK([0], [1], 'Item', [\n      wbStructExSK(CNTO, [0], [1], 'Item', [\n        wbFormIDCk('Item', [ARMO, AMMO, APPA, MISC, WEAP, BOOK, LVLI, KEYM, ALCH, INGR, LIGH, SLGM, SCRL]),\n        wbInteger('Count', itS32)\n      ]),\n      wbCOED\n    ], []);\n  wbCOCT := wbInteger(COCT, 'Count', itU32, nil, cpBenign);\n  wbCNTOs := wbRArrayS('Items', wbCNTO, cpNormal, False, nil, wbCNTOsAfterSet);\n\n  wbArmorTypeEnum := wbEnum([\n    'Light Armor',\n    'Heavy Armor',\n    'Clothing'\n  ]);\n\n  {>>> When NAME is user defined these will be incorrect <<<}\n  wbBipedObjectEnum := wbEnum([\n    '30 - Head',\n    '31 - Hair',\n    '32 - Body',\n    '33 - Hands',\n    '34 - Forearms',\n    '35 - Amulet',\n    '36 - Ring',\n    '37 - Feet',\n    '38 - Calves',\n    '39 - Shield',\n    '40 - Tail',\n    '41 - LongHair',\n    '42 - Circlet',\n    '43 - Ears',\n    '44 - Unnamed',\n    '45 - Unnamed',\n    '46 - Unnamed',\n    '47 - Unnamed',\n    '48 - Unnamed',\n    '49 - Unnamed',\n    '50 - DecapitateHead',\n    '51 - Decapitate',\n    '52 - Unnamed',\n    '53 - Unnamed',\n    '54 - Unnamed',\n    '55 - Unnamed',\n    '56 - Unnamed',\n    '57 - Unnamed',\n    '58 - Unnamed',\n    '59 - Unnamed',\n    '60 - Unnamed',\n    '61 - FX01'\n  ], [\n    -1, 'None'\n  ]);\n\n  wbBipedObjectFlags := wbFlags([\n    {0x00000001} '30 - Head',\n    {0x00000002} '31 - Hair',\n    {0x00000004} '32 - Body',\n    {0x00000008} '33 - Hands',\n    {0x00000010} '34 - Forearms',\n    {0x00000020} '35 - Amulet',\n    {0x00000040} '36 - Ring',\n    {0x00000080} '37 - Feet',\n    {0x00000100} '38 - Calves',\n    {0x00000200} '39 - Shield',\n    {0x00000400} '40 - Tail',\n    {0x00000800} '41 - LongHair',\n    {0x00001000} '42 - Circlet',\n    {0x00002000} '43 - Ears',\n    {0x00004000} '44 - Unnamed',\n    {0x00008000} '45 - Unnamed',\n    {0x00010000} '46 - Unnamed',\n    {0x00020000} '47 - Unnamed',\n    {0x00040000} '48 - Unnamed',\n    {0x00080000} '49 - Unnamed',\n    {0x00100000} '50 - DecapitateHead',\n    {0x00200000} '51 - Decapitate',\n    {0x00400000} '52 - Unnamed',\n    {0x00800000} '53 - Unnamed',\n    {0x01000000} '54 - Unnamed',\n    {0x02000000} '55 - Unnamed',\n    {0x04000000} '56 - Unnamed',\n    {0x08000000} '57 - Unnamed',\n    {0x10000000} '58 - Unnamed',\n    {0x20000000} '59 - Unnamed',\n    {0x40000000} '60 - Unnamed',\n    {0x80000000} '61 - FX01'\n  ], True);\n\n  wbFirstPersonFlagsU32 := wbInteger('First Person Flags', itU32, wbBipedObjectFlags);\n\n  wbBODT := wbStruct(BODT, 'Body Template', [\n    wbFirstPersonFlagsU32,\n    wbInteger('General Flags', itU8, wbFlags([\n      {0x00000001}'(ARMA)Modulates Voice', {>>> From ARMA <<<}\n      {0x00000002}'Unknown 2',\n      {0x00000004}'Unknown 3',\n      {0x00000008}'Unknown 4',\n      {0x00000010}'(ARMO)Non-Playable', {>>> From ARMO <<<}\n      {0x00000020}'Unknown 6',\n      {0x00000040}'Unknown 7',\n      {0x00000080}'Unknown 8'\n    ], True)),\n    wbByteArray('Unused', 3, cpIgnore),\n    wbInteger('Armor Type', itU32, wbArmorTypeEnum)\n  ], cpNormal, False, nil, 3);\n\n  wbBOD2 := wbStruct(BOD2, 'Biped Body Template', [\n    wbFirstPersonFlagsU32,\n    wbInteger('Armor Type', itU32, wbArmorTypeEnum)\n  ], cpNormal, False);\n\n  wbBODTBOD2 :=\n    wbRUnion('Biped Body Template', [\n      wbStruct(BOD2, 'Biped Body Template', [\n        wbFirstPersonFlagsU32,\n        wbInteger('General Flags', it0, wbFlags([\n          {0x00000001}'(ARMA)Modulates Voice', {>>> From ARMA <<<}\n          {0x00000002}'Unknown 2',\n          {0x00000004}'Unknown 3',\n          {0x00000008}'Unknown 4',\n          {0x00000010}'(ARMO)Non-Playable', {>>> From ARMO <<<}\n          {0x00000020}'Unknown 6',\n          {0x00000040}'Unknown 7',\n          {0x00000080}'Unknown 8'\n        ], True)),\n        wbEmpty('Unused'),\n        wbInteger('Armor Type', itU32, wbArmorTypeEnum)\n      ], cpNormal, False),\n      wbStruct(BODT, 'Body Template', [\n        wbFirstPersonFlagsU32,\n        wbInteger('General Flags', itU8, wbFlags([\n          {0x00000001}'(ARMA)Modulates Voice', {>>> From ARMA <<<}\n          {0x00000002}'Unknown 2',\n          {0x00000004}'Unknown 3',\n          {0x00000008}'Unknown 4',\n          {0x00000010}'(ARMO)Non-Playable', {>>> From ARMO <<<}\n          {0x00000020}'Unknown 6',\n          {0x00000040}'Unknown 7',\n          {0x00000080}'Unknown 8'\n        ], True)),\n        wbByteArray('Unused', 3, cpIgnore),\n        wbInteger('Armor Type', itU32, wbArmorTypeEnum)\n      ], cpNormal, False, nil, 3)\n    ], []);\n\n  wbMDOB := wbFormID(MDOB, 'Menu Display Object', cpNormal, False);\n  wbCNAM := wbStruct(CNAM, 'Color', [\n    wbInteger('Red', itU8),\n    wbInteger('Green', itU8),\n    wbInteger('Blue', itU8),\n    wbByteArray('Unknown', 1)\n  ]);\n  wbCNAMReq := wbStruct(CNAM, 'Color', [\n    wbInteger('Red', itU8),\n    wbInteger('Green', itU8),\n    wbInteger('Blue', itU8),\n    wbByteArray('Unknown', 1)\n  ], cpNormal, True);\n\n  wbDODT := wbStruct(DODT, 'Decal Data', [\n    wbFloat('Min Width'),\n    wbFloat('Max Width'),\n    wbFloat('Min Height'),\n    wbFloat('Max Height'),\n    wbFloat('Depth'),\n    wbFloat('Shininess'),\n    wbStruct('Parallax', [\n      wbFloat('Scale'),\n      wbInteger('Passes', itU8) {>>> This can't be higher than 30 <<<}\n    ]),\n    wbInteger('Flags', itU8, wbFlags([\n      {0x01}'Parallax',\n      {0x02}'Alpha - Blending',\n      {0x04}'Alpha - Testing',\n      {0x08}'No Subtextures'\n    ], True)),\n    wbByteArray('Unknown', 2),\n    wbByteColors('Color')\n  ]);\n\n//  wbRecordFlagsFlags := wbFlags([\n//    {>>> 0x00000000 ACTI: Collision Geometry (default) <<<}\n//    {0x00000001}'ESM',\n//    {0x00000002}'Unknown 2',\n//    {>>> 0x00000004 ARMO: Not playable <<<}\n//    {0x00000004}'NotPlayable',\n//    {0x00000008}'Unknown 4',\n//    {0x00000010}'Unknown 5',\n//    {0x00000020}'Deleted',\n//    {>>> 0x00000040 ACTI: Has Tree LOD <<<}\n//    {>>> 0x00000040 REGN: Border Region <<<}\n//    {>>> 0x00000040 STAT: Has Tree LOD <<<}\n//    {>>> 0x00000040 REFR: Hidden From Local Map <<<}\n//    {0x00000040}'Constant HiddenFromLocalMap BorderRegion HasTreeLOD',\n//    {>>> 0x00000080 TES4: Localized <<<}\n//    {>>> 0x00000080 PHZD: Turn Off Fire <<<}\n//    {>>> 0x00000080 SHOU: Treat Spells as Powers <<<}\n//    {>>> 0x00000080 STAT: Add-on LOD Object <<<}\n//    {0x00000080}'Localized IsPerch AddOnLODObject TurnOffFire TreatSpellsAsPowers',\n//    {>>> 0x00000100 ACTI: Must Update Anims <<<}\n//    {>>> 0x00000100 REFR: Inaccessible <<<}\n//    {>>> 0x00000100 REFR for LIGH: Doesn't light water <<<}\n//    {0x00000100}'MustUpdateAnims Inaccessible DoesntLightWater',\n//    {>>> 0x00000200 ACTI: Local Map - Turns Flag Off, therefore it is Hidden <<<}\n//    {>>> 0x00000200 REFR: MotionBlurCastsShadows <<<}\n//    {0x00000200}'HiddenFromLocalMap StartsDead MotionBlurCastsShadows',\n//    {>>> 0x00000400 LSCR: Displays in Main Menu <<<}\n//    {0x00000400}'PersistentReference QuestItem DisplaysInMainMenu',\n//    {0x00000800}'InitiallyDisabled',\n//    {0x00001000}'Ignored',\n//    {0x00002000}'ActorChanged',\n//    {0x00004000}'Unknown 15',\n//    {>>> 0x00008000 STAT: Has Distant LOD <<<}\n//    {0x00008000}'VWD',\n//    {>>> 0x00010000 ACTI: Random Animation Start <<<}\n//    {>>> 0x00010000 REFR light: Never fades <<<}\n//    {0x00010000}'RandomAnimationStart NeverFades',\n//    {>>> 0x00020000 ACTI: Dangerous <<<}\n//    {>>> 0x00020000 REFR light: Doesn't light landscape <<<}\n//    {>>> 0x00020000 SLGM: Can hold NPC's soul <<<}\n//    {>>> 0x00020000 STAT: Use High-Detail LOD Texture <<<}\n//    {0x00020000}'Dangerous OffLimits DoesntLightLandscape HighDetailLOD CanHoldNPC',\n//    {0x00040000}'Compressed',\n//    {>>> 0x00080000 STAT: Has Currents <<<}\n//    {0x00080000}'CantWait HasCurrents',\n//    {>>> 0x00100000 ACTI: Ignore Object Interaction <<<}\n//    {0x00100000}'IgnoreObjectInteraction',\n//    {0x00200000}'(Used in Memory Changed Form)',\n//    {0x00400000}'Unknown 23',\n//    {>>> 0x00800000 ACTI: Is Marker <<<}\n//    {0x00800000}'IsMarker',\n//    {0x01000000}'Unknown 25',\n//    {>>> 0x02000000 ACTI: Obstacle <<<}\n//    {>>> 0x02000000 REFR: No AI Acquire <<<}\n//    {0x02000000}'Obstacle NoAIAcquire',\n//    {>>> 0x04000000 ACTI: Filter <<<}\n//    {0x04000000}'NavMeshFilter',\n//    {>>> 0x08000000 ACTI: Bounding Box <<<}\n//    {0x08000000}'NavMeshBoundingBox',\n//    {>>> 0x10000000 STAT: Show in World Map <<<}\n//    {0x10000000}'MustExitToTalk ShowInWorldMap',\n//    {>>> 0x20000000 ACTI: Child Can Use <<<}\n//    {>>> 0x20000000 REFR: Don't Havok Settle <<<}\n//    {0x20000000}'ChildCanUse DontHavokSettle',\n//    {>>> 0x40000000 ACTI: GROUND <<<}\n//    {>>> 0x40000000 REFR: NoRespawn <<<}\n//    {0x40000000}'NavMeshGround NoRespawn',\n//    {>>> 0x80000000 REFR: MultiBound <<<}\n//    {0x80000000}'MultiBound'\n//  ], [18]);\n\n  wbRecordFlagsFlags := wbFlags(wbRecordFlagsFlags, [\n    {0x00000001} { 0} 'Unknown 0',\n    {0x00000002} { 1} 'Unknown 1',\n    {0x00000004} { 2} 'Unknown 2',\n    {0x00000008} { 3} 'Unknown 3',\n    {0x00000010} { 4} 'Unknown 4',\n    {0x00000020} { 4} 'Unknown 5',\n    {0x00000040} { 6} 'Unknown 6',\n    {0x00000080} { 7} 'Unknown 7',\n    {0x00000100} { 8} 'Unknown 8',\n    {0x00000200} { 9} 'Unknown 9',\n    {0x00000400} {10} 'Unknown 10',\n    {0x00000800} {11} 'Unknown 11',\n    {0x00001000} {12} 'Unknown 12',\n    {0x00002000} {13} 'Unknown 13',\n    {0x00004000} {14} 'Unknown 14',\n    {0x00008000} {15} 'Unknown 15',\n    {0x00010000} {16} 'Unknown 16',\n    {0x00020000} {17} 'Unknown 17',\n    {0x00040000} {18} 'Unknown 18',\n    {0x00080000} {19} 'Unknown 19',\n    {0x00100000} {20} 'Unknown 20',\n    {0x00200000} {21} 'Unknown 21',\n    {0x00400000} {22} 'Unknown 22',\n    {0x00800000} {23} 'Unknown 23',\n    {0x01000000} {24} 'Unknown 24',\n    {0x02000000} {25} 'Unknown 25',\n    {0x04000000} {26} 'Unknown 26',\n    {0x08000000} {27} 'Unknown 27',\n    {0x10000000} {28} 'Unknown 28',\n    {0x20000000} {29} 'Unknown 29',\n    {0x40000000} {30} 'Unknown 30',\n    {0x80000000} {31} 'Unknown 31'\n  ]);\n\n  wbRecordFlags := wbInteger('Record Flags', itU32, wbFlags(wbRecordFlagsFlags, wbFlagsList([])));\n\n  wbMainRecordHeader := wbStruct('Record Header', [\n    wbString('Signature', 4, cpCritical),\n    wbInteger('Data Size', itU32, nil, cpIgnore),\n    wbRecordFlags,\n    wbFormID('FormID', cpFormID),\n    wbByteArray('Version Control Info 1', 4, cpIgnore),\n    wbInteger('Form Version', itU16, nil, cpIgnore),\n    wbByteArray('Version Control Info 2', 2, cpIgnore)\n  ]);\n\n  wbSizeOfMainRecordStruct := 24;\n\n  wbIgnoreRecords.Add(XXXX);\n\n  wbXRGD := wbByteArray(XRGD, 'Ragdoll Data');\n  wbXRGB := wbByteArray(XRGB, 'Ragdoll Biped Data');\n\n  wbMusicEnum := wbEnum(['Default', 'Public', 'Dungeon']);\n  wbSoundLevelEnum := wbEnum([\n     'Loud',\n     'Normal',\n     'Silent',\n     'Very Loud'\n    ]);\n\n  wbEntryPointsEnum := wbEnum([\n    { 0} 'Calculate Weapon Damage',\n    { 1} 'Calculate My Critical Hit Chance',\n    { 2} 'Calculate My Critical Hit Damage',\n    { 3} 'Calculate Mine Explode Chance',\n    { 4} 'Adjust Limb Damage',\n    { 5} 'Adjust Book Skill Points',\n    { 6} 'Mod Recovered Health',\n    { 7} 'Get Should Attack',\n    { 8} 'Mod Buy Prices',\n    { 9} 'Add Leveled List On Death',\n    {10} 'Get Max Carry Weight',\n    {11} 'Mod Addiction Chance',\n    {12} 'Mod Addiction Duration',\n    {13} 'Mod Positive Chem Duration',\n    {14} 'Activate',\n    {15} 'Ignore Running During Detection',\n    {16} 'Ignore Broken Lock',\n    {17} 'Mod Enemy Critical Hit Chance',\n    {18} 'Mod Sneak Attack Mult',\n    {19} 'Mod Max Placeable Mines',\n    {20} 'Mod Bow Zoom',\n    {21} 'Mod Recover Arrow Chance',\n    {22} 'Mod Skill Use',\n    {23} 'Mod Telekinesis Distance',\n    {24} 'Mod Telekinesis Damage Mult',\n    {25} 'Mod Telekinesis Damage',\n    {26} 'Mod Bashing Damage',\n    {27} 'Mod Power Attack Stamina',\n    {28} 'Mod Power Attack Damage',\n    {29} 'Mod Spell Magnitude',\n    {30} 'Mod Spell Duration',\n    {31} 'Mod Secondary Value Weight',\n    {32} 'Mod Armor Weight',\n    {33} 'Mod Incoming Stagger',\n    {34} 'Mod Target Stagger',\n    {35} 'Mod Attack Damage',\n    {36} 'Mod Incoming Damage',\n    {37} 'Mod Target Damage Resistance',\n    {38} 'Mod Spell Cost',\n    {39} 'Mod Percent Blocked',\n    {40} 'Mod Shield Deflect Arrow Chance',\n    {41} 'Mod Incoming Spell Magnitude',\n    {42} 'Mod Incoming Spell Duration',\n    {43} 'Mod Player Intimidation',\n    {44} 'Mod Player Reputation',\n    {45} 'Mod Favor Points',\n    {46} 'Mod Bribe Amount',\n    {47} 'Mod Detection Light',\n    {48} 'Mod Detection Movement',\n    {49} 'Mod Soul Gem Recharge',\n    {50} 'Set Sweep Attack',\n    {51} 'Apply Combat Hit Spell',\n    {52} 'Apply Bashing Spell',\n    {53} 'Apply Reanimate Spell',\n    {54} 'Set Boolean Graph Variable',\n    {55} 'Mod Spell Casting Sound Event',\n    {56} 'Mod Pickpocket Chance',\n    {57} 'Mod Detection Sneak Skill',\n    {58} 'Mod Falling Damage',\n    {59} 'Mod Lockpick Sweet Spot',\n    {60} 'Mod Sell Prices',\n    {61} 'Can Pickpocket Equipped Item',\n    {62} 'Mod Lockpick Level Allowed',\n    {63} 'Set Lockpick Starting Arc',\n    {64} 'Set Progression Picking',\n    {65} 'Make Lockpicks Unbreakable',\n    {66} 'Mod Alchemy Effectiveness',\n    {67} 'Apply Weapon Swing Spell',\n    {68} 'Mod Commanded Actor Limit',\n    {69} 'Apply Sneaking Spell',\n    {70} 'Mod Player Magic Slowdown',\n    {71} 'Mod Ward Magicka Absorption Pct',\n    {72} 'Mod Initial Ingredient Effects Learned',\n    {73} 'Purify Alchemy Ingredients',\n    {74} 'Filter Activation',\n    {75} 'Can Dual Cast Spell',\n    {76} 'Mod Tempering Health',\n    {77} 'Mod Enchantment Power',\n    {78} 'Mod Soul Pct Captured to Weapon',\n    {79} 'Mod Soul Gem Enchanting',\n    {80} 'Mod # Applied Enchantments Allowed',\n    {81} 'Set Activate Label',\n    {82} 'Mod Shout OK',\n    {83} 'Mod Poison Dose Count',\n    {84} 'Should Apply Placed Item',\n    {85} 'Mod Armor Rating',\n    {86} 'Mod Lockpicking Crime Chance',\n    {87} 'Mod Ingredients Harvested',\n    {88} 'Mod Spell Range (Target Loc.)',\n    {89} 'Mod Potions Created',\n    {90} 'Mod Lockpicking Key Reward Chance',\n    {91} 'Allow Mount Actor'\n  ]);\n\n  wbLocationEnum := wbEnum([\n    {0} 'Near reference',\n    {1} 'In cell',\n    {2} 'Near package start location',\n    {3} 'Near editor location',\n    {4} 'Object ID',\n    {5} 'Object Type',\n    {6} 'Near linked reference',\n    {7} 'At package location',\n    {8} 'Alias (reference)',\n    {9} 'Alias (location)',\n   {10} 'Unknown 10',\n   {11} 'Unknown 11',\n   {12} 'Near self'\n  ]);\n\n  wbEquipType := wbFlags([\n    {0x00000001}'Hand To Hand Melee',\n    {0x00000002}'One Hand Sword',\n    {0x00000004}'One Hand Dagger',\n    {0x00000008}'One Hand Axe',\n    {0x00000010}'One Hand Mace',\n    {0x00000020}'Two Hand Sword',\n    {0x00000040}'Two Hand Axe',\n    {0x00000080}'Bow',\n    {0x00000100}'Staff',\n    {0x00000200}'Spell',\n    {0x00000400}'Shield',\n    {0x00000800}'Torch',\n    {0x00001000}'Crossbow'\n  ], True);\n\n  wbEmotionTypeEnum := wbEnum([\n    {0} 'Neutral',\n    {1} 'Anger',\n    {2} 'Disgust',\n    {3} 'Fear',\n    {4} 'Sad',\n    {5} 'Happy',\n    {6} 'Surprise',\n    {7} 'Puzzled'\n  ]);\n\n  wbFurnitureAnimTypeEnum := wbEnum([\n    {0} '',\n    {1} 'Sit',\n    {2} 'Lay',\n    {3} '',\n    {4} 'Lean'\n  ]);\n\n  wbFurnitureEntryTypeFlags := wbFlags([\n    {0x01} 'Front',\n    {0x02} 'Behind',\n    {0x04} 'Right',\n    {0x08} 'Left',\n    {0x10} 'Up'\n  ]);\n\n  wbWardStateEnum := wbEnum([\n    'None',\n    'Absorb',\n    'Break'\n  ]);\n\n  wbEventFunctionEnum := wbEnum([\n    'GetIsID',\n    'IsInList',\n    'GetValue',\n    'HasKeyword',\n    'GetItemValue'\n  ]);\n\n  // Event member names and availability are different depending on event type\n  // Using generic names for the last 3 of them: Form, Value1, Value2\n  wbEventMemberEnum := wbEnum([], [\n    $0000, 'None',\n    $314F, 'CreatedObject',\n    $314C, '(Old)Location',\n    $324C, '(New)Location',\n    $314B, 'Keyword',\n    $3146, 'Form',\n    $3156, 'Value1',\n    $3256, 'Value2'\n  ]);\n\n  wbWeaponAnimTypeEnum := wbEnum([\n    {0} 'HandToHandMelee',\n    {1} 'OneHandSword',\n    {2} 'OneHandDagger',\n    {3} 'OneHandAxe',\n    {4} 'OneHandMace',\n    {5} 'TwoHandSword',\n    {6} 'TwoHandAxe',\n    {7} 'Bow',\n    {8} 'Staff',\n    {9} 'Crossbow'\n  ]);\n\n  wbEDID := wbString(EDID, 'Editor ID', 0, cpNormal); // not cpBenign according to Arthmoor\n  wbFULL := wbLStringKC(FULL, 'Name', 0, cpTranslate);\n  wbFULLActor := wbLStringKC(FULL, 'Name', 0, cpTranslate, False, nil{wbActorTemplateUseBaseData});\n  wbFULLReq := wbLStringKC(FULL, 'Name', 0, cpTranslate, True);\n  wbDESC := wbLStringKC(DESC, 'Description', 0, cpTranslate);\n  wbDESCReq := wbLStringKC(DESC, 'Description', 0, cpTranslate, True);\n  wbXSCL := wbFloat(XSCL, 'Scale');\n\n  wbOBND := wbStruct(OBND, 'Object Bounds', [\n    wbInteger('X1', itS16),\n    wbInteger('Y1', itS16),\n    wbInteger('Z1', itS16),\n    wbInteger('X2', itS16),\n    wbInteger('Y2', itS16),\n    wbInteger('Z2', itS16)\n  ]);\n\n  wbOBNDReq := wbStruct(OBND, 'Object Bounds', [\n    wbInteger('X1', itS16),\n    wbInteger('Y1', itS16),\n    wbInteger('Z1', itS16),\n    wbInteger('X2', itS16),\n    wbInteger('Y2', itS16),\n    wbInteger('Z2', itS16)\n  ], cpNormal, True);\n\n  wbPropTypeEnum := wbEnum([\n    {00} 'None',\n    {01} 'Object',\n    {02} 'String',\n    {03} 'Int32',\n    {04} 'Float',\n    {05} 'Bool',\n    {06} '',\n    {07} '',\n    {08} '',\n    {09} '',\n    {10} '',\n    {11} 'Array of Object',\n    {12} 'Array of String',\n    {13} 'Array of Int32',\n    {14} 'Array of Float',\n    {15} 'Array of Bool'\n  ]);\n\n  wbScriptFlags := wbInteger('Flags', itU8, wbEnum([\n    {0x00} 'Local',\n    {0x01} 'Inherited',\n    {0x02} 'Removed',\n    {0x03} 'Inherited and Removed'\n  ]));\n\n  wbScriptPropertyObject := wbUnion('Object Union', wbScriptObjFormatDecider, [\n    wbStructSK([1], 'Object v2', [\n      wbInteger('Unused', itU16, nil, cpIgnore),\n      wbInteger('Alias', itS16, wbScriptObjectAliasToStr, wbStrToAlias),\n      wbFormID('FormID')\n    ], [2, 1, 0]),\n    wbStructSK([1], 'Object v1', [\n      wbFormID('FormID'),\n      wbInteger('Alias', itS16, wbScriptObjectAliasToStr, wbStrToAlias),\n      wbInteger('Unused', itU16, nil, cpIgnore)\n    ])\n  ]);\n\n  wbScriptProperties :=\n    wbArrayS('Properties', wbStructSK([0], 'Property', [\n      wbLenString('propertyName', 2),\n      wbInteger('Type', itU8, wbPropTypeEnum, cpNormal, False, nil, wbScriptPropertyTypeAfterSet),\n      wbInteger('Flags', itU8, wbEnum([\n        {0x00} '',\n        {0x01} 'Edited',\n        {0x02} '',\n        {0x03} 'Removed'\n      ])),\n      wbUnion('Value', wbScriptPropertyDecider, [\n       {00} wbNull,\n       {01} wbScriptPropertyObject,\n       {02} wbLenString('String', 2),\n       {03} wbInteger('Int32', itS32),\n       {04} wbFloat('Float'),\n       {05} wbInteger('Bool', itU8, wbEnum(['False', 'True'])),\n       {11} wbArray('Array of Object', wbScriptPropertyObject, -1),\n       {12} wbArray('Array of String', wbLenString('Element', 2), -1),\n       {13} wbArray('Array of Int32', wbInteger('Element', itS32), -1),\n       {14} wbArray('Array of Float', wbFloat('Element'), -1),\n       {15} wbArray('Array of Bool', wbInteger('Element', itU8, wbEnum(['False', 'True'])), -1)\n      ])\n    ]), -2, cpNormal, False, nil, nil, nil, False);\n\n  wbScriptEntry := wbStructSK([0], 'Script', [\n    wbLenString('scriptName', 2),\n    wbScriptFlags,\n    wbScriptProperties\n  ]);\n\n  wbScriptFragmentsInfo := wbStruct('Script Fragments', [\n    wbInteger('Unknown', itS8),\n    wbInteger('Flags', itU8, wbFlags([\n      {1} 'OnBegin',\n      {2} 'OnEnd'\n    ])),\n    wbLenString('fileName', 2),\n    wbArray('Fragments',  // Do NOT sort, ordered OnBegin, OnEnd\n      wbStruct('Fragment', [\n        wbInteger('Unknown', itS8),\n        wbLenString('scriptName', 2),\n        wbLenString('fragmentName', 2)\n      ]), [], wbScriptFragmentsInfoCounter)\n  ]);\n\n  wbScriptFragmentsPack := wbStruct('Script Fragments', [\n    wbInteger('Unknown', itS8),\n    wbInteger('Flags', itU8, wbFlags([\n      {1} 'OnBegin',\n      {2} 'OnEnd',\n      {4} 'OnChange'\n    ])),\n    wbLenString('fileName', 2),\n    wbArray('Fragments',  // Do NOT sort, ordered OnBegin, OnEnd, OnChange\n      wbStruct('Fragment', [\n        wbInteger('Unknown', itS8),\n        wbLenString('scriptName', 2),\n        wbLenString('fragmentName', 2)\n      ]), [], wbScriptFragmentsPackCounter)\n  ]);\n\n  wbScriptFragmentsQuest := wbStruct('Script Fragments', [\n    wbInteger('Unknown', itS8),\n    wbInteger('fragmentCount', itU16),\n    wbLenString('fileName', 2),\n    wbArrayS('Fragments',\n      wbStructSK([0, 2], 'Fragment', [\n        wbInteger('Quest Stage', itU16),\n        wbInteger('Unknown', itS16),\n        wbInteger('Quest Stage Index', itS32),\n        wbInteger('Unknown', itS8),\n        wbLenString('scriptName', 2),\n        wbLenString('fragmentName', 2)\n      ]), wbScriptFragmentsQuestCounter)\n  ]);\n\n  wbScriptFragmentsScen := wbStruct('Script Fragments', [\n    wbInteger('Unknown', itS8),\n    wbInteger('Flags', itU8, wbFlags([\n      {1} 'OnBegin',\n      {2} 'OnEnd'\n    ])),\n    wbLenString('fileName', 2),\n    wbArray('Fragments',  // Do NOT sort, ordered OnBegin, OnEnd\n      wbStruct('Fragment', [\n        wbInteger('Unknown', itS8),\n        wbLenString('scriptName', 2),\n        wbLenString('fragmentName', 2)\n      ]), [], wbScriptFragmentsSceneCounter),\n    wbArray('Phase Fragments',\n      wbStructSK([0, 1], 'Phase Fragment', [\n        wbInteger('Phase Flag', itU8, wbFlags([\n          {1} 'OnStart',\n          {2} 'OnCompletion'\n        ])),\n        wbInteger('Phase Index', itU8),\n        wbInteger('Unknown', itS16),\n        wbInteger('Unknown', itS8),\n        wbInteger('Unknown', itS8),\n        wbLenString('scriptName', 2),\n        wbLenString('fragmentName', 2)\n      ]), -2)\n  ]);\n\n  wbScriptFragments := wbStruct('Script Fragments', [\n    wbInteger('Unknown', itS8),\n    wbLenString('fileName', 2),\n    wbArrayS('Fragments',\n      wbStructSK([0], 'Fragment', [\n        wbInteger('Fragment Index', itU16),\n        wbInteger('Unknown', itS16),\n        wbInteger('Unknown', itS8),\n        wbLenString('scriptName', 2),\n        wbLenString('fragmentName', 2)\n      ]), -2)\n  ]);\n\n  {>>> http://www.uesp.net/wiki/Tes5Mod:Mod_File_Format/VMAD_Field <<<}\n\n  wbVMAD := wbStruct(VMAD, 'Virtual Machine Adapter', [\n    wbInteger('Version', itS16, nil, cpIgnore),\n    wbInteger('Object Format', itS16, nil, cpIgnore),\n    wbArrayS('Scripts', wbScriptEntry, -2, cpNormal, False, nil, nil, nil, False)\n  ]);\n\n  wbVMADFragmentedPERK := wbStruct(VMAD, 'Virtual Machine Adapter', [\n    wbInteger('Version', itS16, nil, cpIgnore),\n    wbInteger('Object Format', itS16, nil, cpIgnore),\n    wbArrayS('Scripts', wbScriptEntry, -2, cpNormal, False, nil, nil, nil, False),\n    wbScriptFragments\n  ], cpNormal, False, nil, 3);\n\n  wbVMADFragmentedPACK := wbStruct(VMAD, 'Virtual Machine Adapter', [\n    wbInteger('Version', itS16, nil, cpIgnore),\n    wbInteger('Object Format', itS16, nil, cpIgnore),\n    wbArrayS('Scripts', wbScriptEntry, -2, cpNormal, False, nil, nil, nil, False),\n    wbScriptFragmentsPack\n  ], cpNormal, False, nil, 3);\n\n  wbVMADFragmentedQUST := wbStruct(VMAD, 'Virtual Machine Adapter', [\n    wbInteger('Version', itS16, nil, cpIgnore),\n    wbInteger('Object Format', itS16, nil, cpIgnore),\n    wbArrayS('Scripts', wbScriptEntry, -2, cpNormal, False, nil, nil, nil, False),\n    wbScriptFragmentsQuest,\n    wbArrayS('Aliases', wbStructSK([0], 'Alias', [\n      wbScriptPropertyObject,\n      wbInteger('Version', itS16, nil, cpIgnore),\n      wbInteger('Object Format', itS16, nil, cpIgnore),\n\t    wbArrayS('Alias Scripts', wbScriptEntry, -2)\n\t  ]), -2)\n  ], cpNormal, False, nil, 3);\n\n  wbVMADFragmentedSCEN := wbStruct(VMAD, 'Virtual Machine Adapter', [\n    wbInteger('Version', itS16, nil, cpIgnore),\n    wbInteger('Object Format', itS16, nil, cpIgnore),\n    wbArrayS('Scripts', wbScriptEntry, -2, cpNormal, False, nil, nil, nil, False),\n    wbScriptFragmentsScen\n  ], cpNormal, False, nil, 3);\n\n  wbVMADFragmentedINFO := wbStruct(VMAD, 'Virtual Machine Adapter', [\n    wbInteger('Version', itS16, nil, cpIgnore),\n    wbInteger('Object Format', itS16, nil, cpIgnore),\n    wbArrayS('Scripts', wbScriptEntry, -2, cpNormal, False, nil, nil, nil, False),\n    wbScriptFragmentsInfo\n  ], cpNormal, False, nil, 3);\n\n\n  wbAttackData := wbRStructSK([1], 'Attack', [\n    wbStruct(ATKD, 'Attack Data', [\n      wbFloat('Damage Mult'),\n      wbFloat('Attack Chance'),\n      wbFormIDCk('Attack Spell', [SPEL, SHOU, NULL]),\n      wbInteger('Attack Flags', itU32, wbFlags([\n        {0x00000001} 'Ignore Weapon',\n        {0x00000002} 'Bash Attack',\n        {0x00000004} 'Power Attack',\n        {0x00000008} 'Left Attack',\n        {0x00000010} 'Rotating Attack',\n        {0x00000020} 'Unknown 5',\n        {0x00000040} 'Unknown 6',\n        {0x00000080} 'Unknown 7',\n        {0x00000100} 'Unknown 8',\n        {0x00000200} 'Unknown 9',\n        {0x00000400} 'Unknown 10',\n        {0x00000800} 'Unknown 11',\n        {0x00001000} 'Unknown 12',\n        {0x00002000} 'Unknown 13',\n        {0x00004000} 'Unknown 14',\n        {0x00008000} 'Unknown 15',\n        {0x00010000} 'Unknown 16',\n        {0x00020000} 'Unknown 17',\n        {0x00040000} 'Unknown 18',\n        {0x00080000} 'Unknown 19',\n        {0x00100000} 'Unknown 20',\n        {0x00200000} 'Unknown 21',\n        {0x00400000} 'Unknown 22',\n        {0x00800000} 'Unknown 23',\n        {0x01000000} 'Unknown 24',\n        {0x02000000} 'Unknown 25',\n        {0x04000000} 'Unknown 26',\n        {0x08000000} 'Unknown 27',\n        {0x10000000} 'Unknown 28',\n        {0x20000000} 'Unknown 29',\n        {0x40000000} 'Unknown 30',\n        {0x80000000} 'Override Data'\n      ])),\n      wbFloat('Attack Angle'),\n      wbFloat('Strike Angle'),\n      wbFloat('Stagger'),\n      wbFormIDCk('Attack Type', [KYWD, NULL]),\n      wbFloat('Knockdown'),\n      wbFloat('Recovery Time'),\n      wbFloat('Stamina Mult')\n    ]),\n    wbString(ATKE, 'Attack Event')\n  ], []);\n\n  wbPLDT := wbStruct(PLDT, 'Location', [\n    wbInteger('Type', itS32, wbLocationEnum),\n    wbUnion('Location Value', wbTypeDecider, [\n      {0} wbFormIDCkNoReach('Reference', [NULL, DOOR, PLYR, ACHR, REFR, PGRE, PHZD, PMIS, PARW, PBAR, PBEA, PCON, PFLA]),\n      {1} wbFormIDCkNoReach('Cell', [NULL, CELL]),\n      {2} wbByteArray('Near Package Start Location', 4, cpIgnore),\n      {3} wbByteArray('Near Editor Location', 4, cpIgnore),\n      {4} wbFormIDCkNoReach('Object ID', [NULL, ACTI, DOOR, STAT, MSTT, FURN, SPEL, SCRL, NPC_, CONT, ARMO, AMMO, MISC, WEAP, BOOK, KEYM, ALCH, LIGH, FACT, FLST, IDLM, SHOU]),\n      {5} wbInteger('Object Type', itU32, wbObjectTypeEnum),\n      {6} wbFormIDCk('Keyword', [NULL, KYWD]),\n      {7} wbByteArray('Unused', 4, cpIgnore),\n      {8} wbInteger('Alias', itS32, wbPackageLocationAliasToStr, wbStrToAlias),\n      {9} wbInteger('Reference', itS32, wbPackageLocationAliasToStr, wbStrToAlias),\n     {10} wbByteArray('Unknown', 4, cpIgnore),\n     {11} wbByteArray('Unknown', 4, cpIgnore),\n     {12} wbByteArray('Unknown', 4, cpIgnore)\n    ]),\n    wbInteger('Radius', itS32)\n  ]);\n\n  wbPLVD := wbStruct(PLVD, 'Location', [\n    wbInteger('Type', itS32, wbLocationEnum),\n    wbUnion('Location Value', wbTypeDecider, [\n      {0} wbFormIDCkNoReach('Reference', [NULL, DOOR, PLYR, ACHR, REFR, PGRE, PHZD, PMIS, PARW, PBAR, PBEA, PCON, PFLA]),\n      {1} wbFormIDCkNoReach('Cell', [NULL, CELL]),\n      {2} wbByteArray('Near Package Start Location', 4, cpIgnore),\n      {3} wbByteArray('Near Editor Location', 4, cpIgnore),\n      {4} wbFormIDCkNoReach('Object ID', [NULL, ACTI, DOOR, STAT, MSTT, FURN, SPEL, SCRL, NPC_, CONT, ARMO, AMMO, MISC, WEAP, BOOK, KEYM, ALCH, INGR, LIGH, FACT, FLST, IDLM, SHOU]),\n      {5} wbInteger('Object Type', itU32, wbObjectTypeEnum),\n      {6} wbFormIDCk('Keyword', [NULL, KYWD]),\n      {7} wbByteArray('Unused', 4, cpIgnore),\n      {8} wbInteger('Alias', itS32, wbPackageLocationAliasToStr, wbStrToAlias),\n      {9} wbInteger('Reference', itS32, wbPackageLocationAliasToStr, wbStrToAlias),\n     {10} wbByteArray('Unknown', 4, cpIgnore),\n     {11} wbByteArray('Unknown', 4, cpIgnore),\n     {12} wbByteArray('Unknown', 4, cpIgnore)\n    ]),\n    wbInteger('Radius', itS32)\n  ]);\n\n  wbTargetData := wbStruct('Target Data', [\n    wbInteger('Type', itS32, wbEnum([\n      {0} 'Specific Reference',\n      {1} 'Object ID',\n      {2} 'Object Type',\n      {3} 'Linked Reference',\n      {4} 'Ref Alias',\n      {5} 'Unknown 5',\n      {6} 'Self'\n    ]), cpNormal, False, nil, nil, 2),\n    wbUnion('Target', wbTypeDecider, [\n      {0} wbFormIDCkNoReach('Reference', [NULL, PLYR, ACHR, REFR, PGRE, PHZD, PMIS, PARW, PBAR, PBEA, PCON, PFLA], True),\n      {1} wbFormIDCkNoReach('Object ID', [NULL, ACTI, DOOR, STAT, MSTT, FURN, SPEL, SCRL, NPC_, CONT, ARMO, AMMO, MISC, WEAP, BOOK, KEYM, ALCH, INGR, LIGH, FACT, FLST, IDLM, SHOU, SOUN, TXST, PROJ]),\n      {2} wbInteger('Object Type', itU32, wbObjectTypeEnum),\n      {3} wbFormID('Reference'),\n      {4} wbInteger('Alias', itS32, wbPackageLocationAliasToStr, wbStrToAlias),\n      {5} wbByteArray('Unknown', 4, cpIgnore),\n      {6} wbByteArray('Unknown', 4, cpIgnore)\n    ]),\n    wbInteger('Count / Distance', itS32)\n  ]);\n\n  wbEITM := wbFormIDCk(EITM, 'Object Effect', [ENCH, SPEL]);\n\n  wbPosRot :=\n    wbStruct('Position/Rotation', [\n      wbStruct('Position', [\n        wbFloat('X'),\n        wbFloat('Y'),\n        wbFloat('Z')\n      ]),\n      wbStruct('Rotation', [\n        wbFloat('X', cpNormal, True, wbRotationFactor, wbRotationScale, nil, RadiansNormalize),\n        wbFloat('Y', cpNormal, True, wbRotationFactor, wbRotationScale, nil, RadiansNormalize),\n        wbFloat('Z', cpNormal, True, wbRotationFactor, wbRotationScale, nil, RadiansNormalize)\n      ])\n    ]);\n\n  wbDATAPosRot :=\n    wbStruct(DATA, 'Position/Rotation', [\n      wbStruct('Position', [\n        wbFloat('X'),\n        wbFloat('Y'),\n        wbFloat('Z')\n      ]),\n      wbStruct('Rotation', [\n        wbFloat('X', cpNormal, True, wbRotationFactor, wbRotationScale, nil, RadiansNormalize),\n        wbFloat('Y', cpNormal, True, wbRotationFactor, wbRotationScale, nil, RadiansNormalize),\n        wbFloat('Z', cpNormal, True, wbRotationFactor, wbRotationScale, nil, RadiansNormalize)\n      ])\n    ], cpNormal, True);\n\n  wbMO2S :=\n    wbArrayS(MO2S, 'Alternate Textures',\n      wbStructSK([0, 2], 'Alternate Texture', [\n        wbLenString('3D Name'),\n        wbFormIDCk('New Texture', [TXST]),\n        wbInteger('3D Index', itS32)\n      ]),\n    -1);\n  wbMO3S :=\n    wbArrayS(MO3S, 'Alternate Textures',\n      wbStructSK([0, 2], 'Alternate Texture', [\n        wbLenString('3D Name'),\n        wbFormIDCk('New Texture', [TXST]),\n        wbInteger('3D Index', itS32)\n      ]),\n    -1);\n  wbMO4S :=\n    wbArrayS(MO4S, 'Alternate Textures',\n      wbStructSK([0, 2], 'Alternate Texture', [\n        wbLenString('3D Name'),\n        wbFormIDCk('New Texture', [TXST]),\n        wbInteger('3D Index', itS32)\n      ]),\n    -1);\n  wbMO5S :=\n    wbArrayS(MO5S, 'Alternate Textures',\n      wbStructSK([0, 2], 'Alternate Texture', [\n        wbLenString('3D Name'),\n        wbFormIDCk('New Texture', [TXST]),\n        wbInteger('3D Index', itS32)\n      ]),\n    -1);\n\n  wbMODS :=\n    wbArrayS(MODS, 'Alternate Textures',\n      wbStructSK([0, 2], 'Alternate Texture', [\n        wbLenString('3D Name'),\n        wbFormIDCk('New Texture', [TXST]),\n        wbInteger('3D Index', itS32)\n      ]),\n    -1);\n\n  wbMODD :=\n    wbInteger(MODD, 'FaceGen Model Flags', itU8, wbFlags([\n      'Head',\n      'Torso',\n      'Right Hand',\n      'Left Hand'\n    ]));\n\n\twbMODT := wbByteArray(MODT, 'Texture Files Hashes', 0, cpIgnore, false, false, wbNeverShow);\n\twbDMDT := wbByteArray(DMDT, 'Texture Files Hashes', 0, cpIgnore, false, false, wbNeverShow);\n\n  wbMODL :=\n    wbRStructSK([0], 'Model', [\n      wbString(MODL, 'Model Filename', 0, cpNormal, True),\n      wbMODT,\n      wbMODS\n    ], [], cpNormal, False, nil, True);\n\n  wbMODLActor :=\n    wbRStructSK([0], 'Model', [\n      wbString(MODL, 'Model Filename', 0, cpNormal, True),\n      wbMODT,\n      wbMODS\n    ], [], cpNormal, False, nil{wbActorTemplateUseModelAnimation}, True);\n\n  wbMODLReq :=\n    wbRStructSK([0], 'Model', [\n      wbString(MODL, 'Model Filename', 0, cpNormal, True),\n      wbMODT,\n      wbMODS\n    ], [], cpNormal, True, nil, True);\n\n  wbDMDSs := wbArrayS(DMDS, 'Alternate Textures',\n    wbStructSK([0, 2], 'Alternate Texture', [\n      wbLenString('3D Name'),\n      wbFormIDCk('New Texture', [TXST]),\n      wbInteger('3D Index', itS32)\n    ]),\n  -1);\n\n  wbDEST := wbRStruct('Destructable', [\n    wbStruct(DEST, 'Header', [\n      wbInteger('Health', itS32),\n      wbInteger('DEST Count', itU8),\n      wbInteger('VATS Targetable', itU8, wbEnum(['False', 'True'])),\n      wbByteArray('Unknown', 2)\n    ]),\n    wbRArray('Stages',\n      wbRStruct('Stage', [\n        wbStruct(DSTD, 'Destruction Stage Data', [\n          wbInteger('Health %', itU8),\n          wbInteger('Index', itU8),\n          wbInteger('Model Damage Stage', itU8),\n          wbInteger('Flags', itU8, wbFlags([\n            'Cap Damage',\n            'Disable',\n            'Destroy',\n            'Ignore External Dmg'\n          ])),\n          wbInteger('Self Damage per Second', itS32),\n          wbFormIDCk('Explosion', [EXPL, NULL]),\n          wbFormIDCk('Debris', [DEBR, NULL]),\n          wbInteger('Debris Count', itS32)\n        ], cpNormal, True),\n        wbRStructSK([0], 'Model', [\n          wbString(DMDL, 'Model Filename'),\n          wbDMDT,\n          wbDMDSs\n        ], [], cpNormal, False, nil),\n        wbEmpty(DSTF, 'End Marker', cpNormal, True)\n      ], [], cpNormal, False, nil)\n    )\n  ], [], cpNormal, False, nil);\n\n  wbDESTActor := wbRStruct('Destructable', [\n    wbStruct(DEST, 'Header', [\n      wbInteger('Health', itS32),\n      wbInteger('Count', itU8),\n      wbInteger('VATS Targetable', itU8, wbEnum(['False', 'True'])),\n      wbByteArray('Unknown', 2)\n    ]),\n    wbRArray('Stages',  // Begin Stage Array\n      wbRStruct('Stage', [ // Begin Stage RStruct\n        wbStruct(DSTD, 'Destruction Stage Data', [ // Begin DSTD\n          wbInteger('Health %', itU8),\n          wbInteger('Index', itU8),\n          wbInteger('Damage Stage', itU8),\n          wbInteger('Flags', itU8, wbFlags([\n            'Cap Damage',\n            'Disable',\n            'Destroy'\n          ])),\n          wbInteger('Self Damage per Second', itS32),\n          wbFormIDCk('Explosion', [EXPL, NULL]),\n          wbFormIDCk('Debris', [DEBR, NULL]),\n          wbInteger('Debris Count', itS32)\n        ], cpNormal, True), // End DSTD\n        wbRStructSK([0], 'Model', [ // Begin DMDL\n          wbString(DMDL, 'Model Filename')\n        ], []), // End DMDL\n        wbDMDT,\n        wbDMDSs,\n        wbEmpty(DSTF, 'End Marker', cpNormal, True)\n      ], []) // Begin Stage RStruct\n    ) // End Stage Array\n  ], [], cpNormal, False, nil{wbActorTemplateUseModelAnimation});\n\n  wbXLOD := wbArray(XLOD, 'Distant LOD Data', wbFloat('Unknown'), 3);\n\n  wbXESP := wbStruct(XESP, 'Enable Parent', [\n    wbFormIDCk('Reference', [PLYR, ACHR, REFR, PGRE, PHZD, PMIS, PARW, PBAR, PBEA, PCON, PFLA]),\n    wbInteger('Flags', itU8, wbFlags([\n      'Set Enable State to Opposite of Parent',\n      'Pop In'\n    ])),\n    wbByteArray('Unused', 3, cpIgnore)\n  ]);\n\n  wbPDTO :=\n    wbStruct(PDTO, 'Topic Data', [\n      wbInteger('Type', itU32, wbEnum([\n        'Topic Ref',\n        'Topic Subtype'\n      ])),\n      wbUnion('Data', wbTypeDecider, [\n        wbFormIDCk('Topic', [DIAL, NULL]),\n        wbString('Subtype', 4)\n      ])\n    ]);\n\n  wbPDTOs := wbRArray('Topic', wbPDTO, cpNormal, False, nil);\n\n  wbXLCM := wbInteger(XLCM, 'Level Modifier', itS32, wbEnum([\n    'Easy',\n    'Medium',\n    'Hard',\n    'Very Hard'\n  ]));\n\n  wbTVDT := wbByteArray(TVDT, 'Occlusion Data', 0, cpNormal);\n//  wbTVDT := wbArray(TVDT, 'Occlusion Data', wbInteger('Unknown', itS32)),\n\n  if wbSimpleRecords then begin\n    wbMaxHeightDataCELL := wbByteArray(MHDT, 'Max Height Data', 0, cpNormal);\n    wbMaxHeightDataWRLD := wbByteArray(MHDT, 'Max Height Data', 0, cpNormal);\n  end\n  else begin\n    wbMaxHeightDataCELL := wbStruct(MHDT, 'Max Height Data', [\n      wbFloat('Offset'),\n      wbArray('Rows',\n        wbByteArray('Columns', 32)\n        // way too verbose for no practical use\n        //wbStruct('Row', [ wbArray('Columns', wbInteger('Column', itU8), 32) ])\n      , 32)\n    ]);\n    wbMaxHeightDataWRLD := wbStruct(MHDT, 'Max Height Data', [\n      wbStruct('Min', [\n        wbInteger('X', itS16),\n        wbInteger('Y', itS16)\n      ]),\n      wbStruct('Max', [\n        wbInteger('X', itS16),\n        wbInteger('Y', itS16)\n      ]),\n      wbByteArray('Cell Data', 0)\n      // way too verbose for no practical use\n      {wbArray('Cell Data', wbStruct('Quad Height', [\n        wbInteger('Bottom Left', itU8),\n        wbInteger('Bottom Right', itU8),\n        wbInteger('Top Left', itU8),\n        wbInteger('Top Right', itU8)\n      ]))}\n    ]);\n  end;\n\n  if wbSimpleRecords then\n    wbOFST := wbByteArray(OFST, 'Offset Data')\n  else\n    wbOFST := wbArray(OFST, 'Offset Data', wbArray('Rows', wbInteger('Offset', itU32), wbOffsetDataColsCounter), 0);\n\n  wbOwnership := wbRStruct('Ownership', [\n    wbFormIDCkNoReach(XOWN, 'Owner', [FACT, ACHR, NPC_]),\n    wbInteger(XRNK, 'Faction rank', itS32)\n  ], [XRGD]);\n\n  wbXGLB := wbFormIDCk(XGLB, 'Global variable', [GLOB]);\nend;\n\nprocedure DefineTES5b;\nbegin\n\n  wbRecord(ACHR, 'Placed NPC',\n    wbFlags(wbRecordFlagsFlags, wbFlagsList([\n      {0x00000200}  9, 'Starts Dead',\n      {0x00000400} 10, 'Persistent',\n      {0x00000800} 11, 'Initially Disabled',\n      {0x02000000} 25, 'No AI Acquire',\n      {0x20000000} 29, 'Don''t Havok Settle'\n    ], True, True)), [\n    wbEDID,\n    wbVMAD,\n    wbFormIDCk(NAME, 'Base', [NPC_], False, cpNormal, True),\n    wbFormIDCk(XEZN, 'Encounter Zone', [ECZN]),\n\n    {--- Ragdoll ---}\n    wbXRGD,\n    wbXRGB,\n\n    {--- Patrol Data ---}\n    wbRStruct('Patrol Data', [\n      wbFloat(XPRD, 'Idle Time', cpNormal, True),\n      wbEmpty(XPPA, 'Patrol Script Marker', cpNormal, True),\n      wbFormIDCk(INAM, 'Idle', [IDLE, NULL], False, cpNormal, True),\n      {>>> BEGIN leftover from earlier CK versions <<<}\n      wbRStruct('Unused', [\n        wbUnknown(SCHR),\n        wbUnknown(SCDA),\n        wbUnknown(SCTX),\n        wbUnknown(QNAM),\n        wbUnknown(SCRO)\n      ], [], cpIgnore, false, wbNeverShow),\n      {>>> END leftover from earlier CK versions <<<}\n      wbPDTOs,\n      wbFormIDCk(TNAM, 'Topic', [DIAL, NULL], False, cpNormal)\n    ], []),\n\n    {--- Leveled Actor ----}\n    wbXLCM,\n\n    {--- Merchant Container ----}\n    wbFormIDCk(XMRC, 'Merchant Container', [REFR], True),\n\n    {--- Extra ---}\n    wbInteger(XCNT, 'Count', itS32),\n    wbFloat(XRDS, 'Radius'),\n    wbFloat(XHLP, 'Health'),\n\n    wbRArrayS('Linked References', wbStructSK(XLKR, [0], 'Linked Reference', [\n      wbFormIDCk('Keyword/Ref', [KYWD, PLYR, ACHR, REFR, PGRE, PHZD, PMIS, PARW, PBAR, PBEA, PCON, PFLA, NULL]),\n      wbFormIDCk('Ref', [PLYR, ACHR, REFR, PGRE, PHZD, PMIS, PARW, PBAR, PBEA, PCON, PFLA])\n    ], cpNormal, False, nil, 1)),\n\n    {--- Activate Parents ---}\n    wbRStruct('Activate Parents', [\n      wbInteger(XAPD, 'Flags', itU8, wbFlags([\n        'Parent Activate Only'\n      ], True)),\n      wbRArrayS('Activate Parent Refs',\n        wbStructSK(XAPR, [0], 'Activate Parent Ref', [\n          wbFormIDCk('Reference', [PLYR, ACHR, REFR, PGRE, PHZD, PMIS, PARW, PBAR, PBEA, PCON, PFLA]),\n          wbFloat('Delay')\n        ])\n      )\n    ], []),\n\n    {--- Linked Ref ---}\n    wbStruct(XCLP, 'Linked Reference Color', [\n      wbByteColors('Link Start Color'),\n      wbByteColors('Link End Color')\n    ]),\n\n    wbFormIDCk(XLCN, 'Persistent Location', [LCTN]),\n    wbFormIDCk(XLRL, 'Location Reference', [LCRT, LCTN, NULL], False, cpBenignIfAdded),\n    wbEmpty(XIS2, 'Ignored by Sandbox'),\n    wbArray(XLRT, 'Location Ref Type', wbFormIDCk('Ref', [LCRT, NULL])),\n\t\twbFormIDCk(XHOR, 'Horse', [ACHR]),\n    wbFloat(XHTW, 'Head-Tracking Weight'),\n    wbFloat(XFVC, 'Favor Cost'),\n\n    {--- Enable Parent ---}\n    wbXESP,\n\n    {--- Ownership ---}\n    wbOwnership,\n\n    {--- Emittance ---}\n    wbFormIDCk(XEMI, 'Emittance', [LIGH, REGN]),\n\n    {--- MultiBound ---}\n    wbFormIDCk(XMBR, 'MultiBound Reference', [REFR, PGRE, PHZD, PMIS, PARW, PBAR, PBEA, PCON, PFLA]),\n\n    {--- Flags ---}\n    wbEmpty(XIBS, 'Ignored By Sandbox'),\n\n    {--- 3D Data ---}\n    wbXSCL,\n    wbDATAPosRot\n  ], True, wbPlacedAddInfo);\n\n  wbRecord(ACTI, 'Activator',\n    wbFlags(wbRecordFlagsFlags, wbFlagsList([\n      {0x00000040}  6, 'Has Tree LOD',\n      {0x00000100}  8, 'Must Update Anims',\n      {0x00000200}  9, 'Hidden From Local Map',\n      {0x00008000} 15, 'Has Distant LOD',\n      {0x00010000} 16, 'Random Anim Start',\n      {0x00020000} 17, 'Dangerous',\n      {0x00100000} 20, 'Ignore Object Interaction',\n      {0x00800000} 23, 'Is Marker',\n      {0x02000000} 25, 'Obstacle',\n      {0x04000000} 26, 'NavMesh Generation - Filter',\n      {0x08000000} 27, 'NavMesh Generation - Bounding Box',\n      {0x20000000} 29, 'Child Can Use',\n      {0x40000000} 30, 'NavMesh Generation - Ground'\n    ])), [\n    wbEDID,\n    wbVMAD,\n    wbOBNDReq,\n    wbFULL,\n    wbMODL,\n    wbDEST,\n    wbKSIZ,\n    wbKWDAs,\n    wbStruct(PNAM, 'Marker Color', [\n      wbInteger('Red', itU8),\n      wbInteger('Green', itU8),\n      wbInteger('Blue', itU8),\n      wbInteger('Unused', itU8)\n    ]),\n    wbFormIDCk(SNAM, 'Sound - Looping', [SNDR]),\n    wbFormIDCk(VNAM, 'Sound - Activation', [SNDR]),\n    wbFormIDCk(WNAM, 'Water Type', [WATR]),\n    wbLString(RNAM, 'Activate Text Override', 0, cpTranslate),\n    wbInteger(FNAM, 'Flags', itU16, wbFlags([\n      'No Displacement',\n      'Ignored by Sandbox'\n    ])),\n    wbFormIDCk(KNAM, 'Interaction Keyword', [KYWD])\n  ], False, nil, cpNormal, False, nil, wbKeywordsAfterSet);\n\n  wbRecord(TACT, 'Talking Activator',\n    wbFlags(wbRecordFlagsFlags, wbFlagsList([\n      {0x00000200}  9, 'Hidden From Local Map',\n      {0x00010000} 16, 'Random Anim Start',\n      {0x00020000} 17, 'Radio Station'\n    ]), [17]), [\n    wbEDID,\n    wbVMAD,\n    wbOBNDReq,\n    wbFULL,\n    wbMODL,\n    wbDEST,\n    wbKSIZ,\n    wbKWDAs,\n    wbUnknown(PNAM, cpIgnore, True),\n    wbFormIDCk(SNAM, 'Looping Sound', [SNDR]),\n    wbUnknown(FNAM, cpIgnore, True),\n    wbFormIDCk(VNAM, 'Voice Type', [VTYP])\n  ], False, nil, cpNormal, False, nil, wbKeywordsAfterSet);\n\n  wbICON := wbRStruct('Icon', [\n    wbString(ICON, 'Large Icon filename', 0, cpNormal, True),\n    wbString(MICO, 'Small Icon filename')\n  ], [], cpNormal, False, nil, True);\n\n  wbICONReq := wbRStruct('Icon', [\n    wbString(ICON, 'Large Icon filename', 0, cpNormal, True),\n    wbString(MICO, 'Small Icon filename')\n  ], [], cpNormal, True, nil, True);\n\n  wbICO2 := wbRStruct('Icon 2 (female)', [\n    wbString(ICO2, 'Large Icon filename', 0, cpNormal, True),\n    wbString(MIC2, 'Small Icon filename')\n  ], [], cpNormal, False, nil, True);\n\n  wbVatsValueFunctionEnum :=\n    wbEnum([\n      { 0} 'Weapon Is',\n      { 1} 'Weapon In List',\n      { 2} 'Target Is',\n      { 3} 'Target In List',\n      { 4} 'Target Distance',\n      { 5} 'Target Part',\n      { 6} 'VATS Action',\n      { 7} 'Is Success',\n      { 8} 'Is Critical',\n      { 9} 'Critical Effect Is',\n      {10} 'Critical Effect In List',\n      {11} 'Is Fatal',\n      {12} 'Explode Part',\n      {13} 'Dismember Part',\n      {14} 'Cripple Part',\n      {15} 'Weapon Type Is',\n      {16} 'Is Stranger',\n      {17} 'Is Paralyzing Palm',\n      {18} 'Projectile Type Is',\n      {19} 'Delivery Type Is',\n      {20} 'Casting Type Is'\n    ]);\n\n  wbActorValueEnum :=\n    wbEnum([\n    {00} 'Aggresion',\n    {01} 'Confidence',\n    {02} 'Energy',\n    {03} 'Morality',\n    {04} 'Mood',\n    {05} 'Assistance',\n    {06} 'One-Handed',\n    {07} 'Two-Handed',\n    {08} 'Archery',\n    {09} 'Block',\n    {10} 'Smithing',\n    {11} 'Heavy Armor',\n    {12} 'Light Armor',\n    {13} 'Pickpocket',\n    {14} 'Lockpicking',\n    {15} 'Sneak',\n    {16} 'Alchemy',\n    {17} 'Speech',\n    {18} 'Alteration',\n    {19} 'Conjuration',\n    {20} 'Destruction',\n    {21} 'Illusion',\n    {22} 'Restoration',\n    {23} 'Enchanting',\n    {24} 'Health',\n    {25} 'Magicka',\n    {26} 'Stamina',\n    {27} 'Heal Rate',\n    {28} 'Magicka Rate',\n    {29} 'Stamina Rate',\n    {30} 'Speed Mult',\n    {31} 'Inventory Weight',\n    {32} 'Carry Weight',\n    {33} 'Critical Chance',\n    {34} 'Melee Damage',\n    {35} 'Unarmed Damage',\n    {36} 'Mass',\n    {37} 'Voice Points',\n    {38} 'Voice Rate',\n    {39} 'Damage Resist',\n    {40} 'Poison Resist',\n    {41} 'Resist Fire',\n    {42} 'Resist Shock',\n    {43} 'Resist Frost',\n    {44} 'Resist Magic',\n    {45} 'Resist Disease',\n    {46} 'Unknown 46',\n    {47} 'Unknown 47',\n    {48} 'Unknown 48',\n    {49} 'Unknown 49',\n    {50} 'Unknown 50',\n    {51} 'Unknown 51',\n    {52} 'Unknown 52',\n    {53} 'Paralysis',\n    {54} 'Invisibility',\n    {55} 'Night Eye',\n    {56} 'Detect Life Range',\n    {57} 'Water Breathing',\n    {58} 'Water Walking',\n    {59} 'Unknown 59',\n    {60} 'Fame',\n    {61} 'Infamy',\n    {62} 'Jumping Bonus',\n    {63} 'Ward Power',\n    {64} 'Right Item Charge',\n    {65} 'Armor Perks',\n    {66} 'Shield Perks',\n    {67} 'Ward Deflection',\n    {68} 'Variable01',\n    {69} 'Variable02',\n    {70} 'Variable03',\n    {71} 'Variable04',\n    {72} 'Variable05',\n    {73} 'Variable06',\n    {74} 'Variable07',\n    {75} 'Variable08',\n    {76} 'Variable09',\n    {77} 'Variable10',\n    {78} 'Bow Speed Bonus',\n    {79} 'Favor Active',\n    {80} 'Favors Per Day',\n    {81} 'Favors Per Day Timer',\n    {82} 'Left Item Charge',\n    {83} 'Absorb Chance',\n    {84} 'Blindness',\n    {85} 'Weapon Speed Mult',\n    {86} 'Shout Recovery Mult',\n    {87} 'Bow Stagger Bonus',\n    {88} 'Telekinesis',\n    {89} 'Favor Points Bonus',\n    {90} 'Last Bribed Intimidated',\n    {91} 'Last Flattered',\n    {92} 'Movement Noise Mult',\n    {93} 'Bypass Vendor Stolen Check',\n    {94} 'Bypass Vendor Keyword Check',\n    {95} 'Waiting For Player',\n    {96} 'One-Handed Modifier',\n    {97} 'Two-Handed Modifier',\n    {98} 'Marksman Modifier',\n    {99} 'Block Modifier',\n   {100} 'Smithing Modifier',\n   {101} 'Heavy Armor Modifier',\n   {102} 'Light Armor Modifier',\n   {103} 'Pickpocket Modifier',\n   {104} 'Lockpicking Modifier',\n   {105} 'Sneaking Modifier',\n   {106} 'Alchemy Modifier',\n   {107} 'Speechcraft Modifier',\n   {108} 'Alteration Modifier',\n   {109} 'Conjuration Modifier',\n   {110} 'Destruction Modifier',\n   {111} 'Illusion Modifier',\n   {112} 'Restoration Modifier',\n   {113} 'Enchanting Modifier',\n   {114} 'One-Handed Skill Advance',\n   {115} 'Two-Handed Skill Advance',\n   {116} 'Marksman Skill Advance',\n   {117} 'Block Skill Advance',\n   {118} 'Smithing Skill Advance',\n   {119} 'Heavy Armor Skill Advance',\n   {120} 'Light Armor Skill Advance',\n   {121} 'Pickpocket Skill Advance',\n   {122} 'Lockpicking Skill Advance',\n   {123} 'Sneaking Skill Advance',\n   {124} 'Alchemy Skill Advance',\n   {125} 'Speechcraft Skill Advance',\n   {126} 'Alteration Skill Advance',\n   {127} 'Conjuration Skill Advance',\n   {128} 'Destruction Skill Advance',\n   {129} 'Illusion Skill Advance',\n   {130} 'Restoration Skill Advance',\n   {131} 'Enchanting Skill Advance',\n   {132} 'Left Weapon Speed Multiply',\n   {133} 'Dragon Souls',\n   {134} 'Combat Health Regen Multiply',\n   {135} 'One-Handed Power Modifier',\n   {136} 'Two-Handed Power Modifier',\n   {137} 'Marksman Power Modifier',\n   {138} 'Block Power Modifier',\n   {139} 'Smithing Power Modifier',\n   {140} 'Heavy Armor Power Modifier',\n   {141} 'Light Armor Power Modifier',\n   {142} 'Pickpocket Power Modifier',\n   {143} 'Lockpicking Power Modifier',\n   {144} 'Sneaking Power Modifier',\n   {145} 'Alchemy Power Modifier',\n   {146} 'Speechcraft Power Modifier',\n   {147} 'Alteration Power Modifier',\n   {148} 'Conjuration Power Modifier',\n   {149} 'Destruction Power Modifier',\n   {150} 'Illusion Power Modifier',\n   {151} 'Restoration Power Modifier',\n   {152} 'Enchanting Power Modifier',\n   {153} 'Dragon Rend',\n   {154} 'Attack Damage Mult',\n   {155} 'Heal Rate Mult',\n   {156} 'Magicka Rate Mult',\n   {157} 'Stamina Rate Mult',\n   {158} 'Werewolf Perks',\n   {159} 'Vampire Perks',\n   {160} 'Grab Actor Offset',\n   {161} 'Grabbed',\n   {162} 'Unknown 162',\n   {163} 'Reflect Damage'\n      ], [\n        -1, 'None'\n      ]);\n\n  wbSkillEnum :=\n    wbEnum([\n      'Unknown 1',\n      'Unknown 2',\n      'Unknown 3',\n      'Unknown 4',\n      'Unknown 5',\n      'Unknown 6',\n      'One Handed',\n      'Two Handed',\n      'Archery',\n      'Block',\n      'Smithing',\n      'Heavy Armor',\n      'Light Armor',\n      'Pickpocket',\n      'Lockpicking',\n      'Sneak',\n      'Alchemy',\n      'Speech',\n      'Alteration',\n      'Conjuration',\n      'Destruction',\n      'Illusion',\n      'Restoration',\n      'Enchanting'\n    ], [\n    -1, 'None'\n    ]);\n\n  wbCastEnum := wbEnum([\n    {0} 'Constant Effect',\n    {1} 'Fire and Forget',\n    {2} 'Concentration',\n    {3} 'Scroll'\n  ]);\n\n  wbTargetEnum := wbEnum([\n    {0} 'Self',\n    {1} 'Touch',\n    {2} 'Aimed',\n    {3} 'Target Actor',\n    {4} 'Target Location'\n  ]);\n\n  wbCastingSourceEnum := wbEnum([\n    'Left',\n    'Right',\n    'Voice',\n    'Instant'\n  ]);\n\n  wbCrimeTypeEnum :=\n    wbEnum([\n      'Steal',\n      'Pickpocket',\n      'Trespass',\n      'Attack',\n      'Murder',\n      'Escape Jail',\n      'Werewolf Transformation'\n    ], [\n      -1, 'None'\n    ]);\n\n  wbActorValue := wbInteger('Actor Value', itS32, wbActorValueEnum);\n\n  wbETYP := wbFormIDCk(ETYP, 'Equipment Type', [EQUP, NULL]);\n  wbETYPReq := wbFormIDCk(ETYP, 'Equipment Type', [EQUP, NULL], False, cpNormal, True);\n\n  wbFormTypeEnum := wbEnum([], [\n     0, 'Activator',\n     1, 'Armor',\n     2, 'Book',\n     3, 'Container',\n     4, 'Door',\n     5, 'Ingredient',\n     6, 'Light',\n     7, 'MiscItem',\n     8, 'Static',\n     9, 'Grass',\n    10, 'Tree',\n    12, 'Weapon',\n    13, 'Actor',\n    14, 'LeveledCharacter',\n    15, 'Spell',\n    16, 'Enchantment',\n    17, 'Potion',\n    18, 'LeveledItem',\n    19, 'Key',\n    20, 'Ammo',\n    21, 'Flora',\n    22, 'Furniture',\n    23, 'Sound Marker',\n    24, 'LandTexture',\n    25, 'CombatStyle',\n    26, 'LoadScreen',\n    27, 'LeveledSpell',\n    28, 'AnimObject',\n    29, 'WaterType',\n    30, 'IdleMarker',\n    31, 'EffectShader',\n    32, 'Projectile',\n    33, 'TalkingActivator',\n    34, 'Explosion',\n    35, 'TextureSet',\n    36, 'Debris',\n    37, 'MenuIcon',\n    38, 'FormList',\n    39, 'Perk',\n    40, 'BodyPartData',\n    41, 'AddOnNode',\n    42, 'MovableStatic',\n    43, 'CameraShot',\n    44, 'ImpactData',\n    45, 'ImpactDataSet',\n    46, 'Quest',\n    47, 'Package',\n    48, 'VoiceType',\n    49, 'Class',\n    50, 'Race',\n    51, 'Eyes',\n    52, 'HeadPart',\n    53, 'Faction',\n    54, 'Note',\n    55, 'Weather',\n    56, 'Climate',\n    57, 'ArmorAddon',\n    58, 'Global',\n    59, 'Imagespace',\n    60, 'Imagespace Modifier',\n    61, 'Encounter Zone',\n    62, 'Message',\n    63, 'Constructible Object',\n    64, 'Acoustic Space',\n    65, 'Ragdoll',\n    66, 'Script',\n    67, 'Magic Effect',\n    68, 'Music Type',\n    69, 'Static Collection',\n    70, 'Keyword',\n    71, 'Location',\n    72, 'Location Ref Type',\n    73, 'Footstep',\n    74, 'Footstep Set',\n    75, 'Material Type',\n    76, 'Actor Action',\n    77, 'Music Track',\n    78, 'Word of Power',\n    79, 'Shout',\n    80, 'Relationship',\n    81, 'Equip Slot',\n    82, 'Association Type',\n    83, 'Outfit',\n    84, 'Art Object',\n    85, 'Material Object',\n    87, 'Lighting Template',\n    88, 'Shader Particle Geometry',\n    89, 'Visual Effect',\n    90, 'Apparatus',\n    91, 'Movement Type',\n    92, 'Hazard',\n    93, 'SM Event Node',\n    94, 'Sound Descriptor',\n    95, 'Dual Cast Data',\n    96, 'Sound Category',\n    97, 'Soul Gem',\n    98, 'Sound Output Model',\n    99, 'Collision Layer',\n   100, 'Scroll',\n   101, 'ColorForm',\n   102, 'Reverb Parameters'\n  ]);\n\n  wbMiscStatEnum := wbEnum([], [\n    Int64($FCDD5011), 'Animals Killed',\n    Int64($366D84CF), 'Armor Improved',\n    Int64($023497E6), 'Armor Made',\n    Int64($8E20D7C9), 'Assaults',\n    Int64($579FFA75), 'Automations Killed',\n    Int64($B9B50725), 'Backstabs',\n    Int64($ED6A0EF2), 'Barters',\n    Int64($CCB952CE), 'Books Read',\n    Int64($317E8B4C), 'Brawls Won',\n    Int64($1D79006B), 'Bribes',\n    Int64($3602DE8F), 'Bunnies Slaughtered',\n    Int64($53D9E9B5), 'Chests Looted',\n    Int64($683C1980), 'Civil War Quests Completed',\n    Int64($66CCC50A), 'College of Winterhold Quests Completed',\n    Int64($40B11EFE), 'Creatures Killed',\n    Int64($22D5BA38), 'Critical Strikes',\n    Int64($A930980F), 'Daedra Killed',\n    Int64($3558374B), 'Daedric Quests Completed',\n    Int64($37A76425), 'Dawnguard Quests Completed',\n    Int64($2BDAC36F), 'Days as a Vampire',\n    Int64($6E684590), 'Days as a Werewolf',\n    Int64($B6F118DB), 'Days Jailed',\n    Int64($3C626A90), 'Days Passed',\n    Int64($8556AD88), 'Diseases Contracted',\n    Int64($46D6FBBC), 'Dragon Souls Collected',\n    Int64($AA444695), 'Dungeons Cleared',\n    Int64($1A37F336), 'Eastmarch Bounty',\n    Int64($5AC3A8ED), 'Falkreath Bounty',\n    Int64($87B12ECC), 'Favorite School',\n    Int64($518BBC4E), 'Favorite Shout',\n    Int64($41DD77A6), 'Favorite Spell',\n    Int64($171C5391), 'Favorite Weapon',\n    Int64($4F041AA2), 'Fines Paid',\n    Int64($9311B22B), 'Food Eaten',\n    Int64($57C089F7), 'Gold Found',\n    Int64($D20EDA4F), 'Haafingar Bounty',\n    Int64($516C486D), 'Hjaalmarch Bounty',\n    Int64($B0A1E32E), 'Horses Owned',\n    Int64($EBAE35E8), 'Horses Stolen',\n    Int64($FA024018), 'Hours Slept',\n    Int64($CAD2ECA1), 'Hours Waiting',\n    Int64($527DF857), 'Houses Owned',\n    Int64($47B4A015), 'Ingredients Eaten',\n    Int64($CE842356), 'Ingredients Harvested',\n    Int64($7D2E57C0), 'Intimidations',\n    Int64($C21702B5), 'Items Pickpocketed',\n    Int64($82F190C2), 'Items Stolen',\n    Int64($6627464B), 'Jail Escapes',\n    Int64($3520E710), 'Largest Bounty',\n    Int64($8A24FDE2), 'Locations Discovered',\n    Int64($5829CC2E), 'Locks Picked',\n    Int64($88089979), 'Magic Items Made',\n    Int64($7EA26C2D), 'Main Quests Completed',\n    Int64($7187A208), 'Mauls',\n    Int64($98EE55DC), 'Misc Objectives Completed',\n    Int64($FA06230B), 'Most Gold Carried',\n    Int64($D37C6909), 'Murders',\n    Int64($22C2CBD0), 'Necks Bitten',\n    Int64($BEEBCC87), 'Nirnroots Found',\n    Int64($56CCFC54), 'NumVampirePerks',\n    Int64($76A1A5C0), 'NumWerewolfPerks',\n    Int64($F22A8133), 'People Killed',\n    Int64($47A78467), 'Persuasions',\n    Int64($F2BAC234), 'Pockets Picked',\n    Int64($17C64668), 'Poisons Mixed',\n    Int64($7D8F2EA6), 'Poisons Used',\n    Int64($4228DE85), 'Potions Mixed',\n    Int64($9631EC11), 'Potions Used',\n    Int64($DE6C73FE), 'Questlines Completed',\n    Int64($0D7B8B16), 'Quests Completed',\n    Int64($BB39399E), 'Shouts Learned',\n    Int64($731B5333), 'Shouts Mastered',\n    Int64($F921D8BA), 'Shouts Unlocked',\n    Int64($B1AE4792), 'Side Quests Completed',\n    Int64($ACE470D7), 'Skill Books Read',\n    Int64($F33130CE), 'Skill Increases',\n    Int64($B556CC52), 'Sneak Attacks',\n    Int64($A74CBE83), 'Soul Gems Used',\n    Int64($C2C9E233), 'Souls Trapped',\n    Int64($5EC89F1A), 'Spells Learned',\n    Int64($B251A346), 'Standing Stones Found',\n    Int64($05D45702), 'Stores Invested In',\n    Int64($D0FE7031), 'The Companions Quests Completed',\n    Int64($52BA68CB), 'The Dark Brotherhood Quests Completed',\n    Int64($3E267D77), 'The Pale Bounty',\n    Int64($69B48177), 'The Reach Bounty',\n    Int64($50A23F69), 'The Rift Bounty',\n    Int64($62B2E95D), 'Thieves'' Guild Quests Completed',\n    Int64($944CEA93), 'Times Jailed',\n    Int64($50AAB633), 'Times Shouted',\n    Int64($99BB86D8), 'Total Lifetime Bounty',\n    Int64($4C252391), 'Training Sessions',\n    Int64($7AEA9C2B), 'Trespasses',\n    Int64($A67626F4), 'Tribal Orcs Bounty',\n    Int64($41D4BC0F), 'Undead Killed',\n    Int64($F39260A1), 'Vampirism Cures',\n    Int64($61A5C5A9), 'Weapons Disarmed',\n    Int64($1D3BA844), 'Weapons Improved',\n    Int64($25F1EA25), 'Weapons Made',\n    Int64($38A2DD66), 'Werewolf Transformations',\n    Int64($4231FA4F), 'Whiterun Bounty',\n    Int64($92565767), 'Wings Plucked',\n    Int64($C7FC518D), 'Winterhold Bounty',\n    Int64($949FA7BC), 'Words of Power Learned',\n    Int64($2C6E3FC0), 'Words of Power Unlocked'\n  ]);\n\n  wbAdvanceActionEnum := wbEnum([\n    'Normal Usage',\n    'Power Attack',\n    'Bash',\n    'Lockpick Success',\n    'Lockpick Broken'\n  ]);\n\n  wbAlignmentEnum :=\n    wbEnum([\n      'Good',\n      'Neutral',\n      'Evil',\n      'Very Good',\n      'Very Evil'\n    ]);\n\n  wbAxisEnum :=\n    wbEnum([], [\n      88, 'X',\n      89, 'Y',\n      90, 'Z'\n    ]);\n\n  wbCriticalStageEnum :=\n    wbEnum([\n      'None',\n      'Goo Start',\n      'Goo End',\n      'Disintegrate Start',\n      'Disintegrate End'\n    ]);\n\n  wbSexEnum := wbEnum(['Male','Female']);\n\n  wbEFID := wbFormIDCk(EFID, 'Base Effect', [MGEF]);\n\n  wbEFIT :=\n    wbStructSK(EFIT, [3, 4], '', [\n      wbFloat('Magnitude', cpNormal, True),\n      wbInteger('Area', itU32),\n      wbInteger('Duration', itU32)\n    ], cpNormal, True, nil, -1, wbEFITAfterLoad);\n\n  wbCTDA := wbRStruct('Condition', [\n    wbStruct(CTDA, '', [\n      wbInteger('Type', itU8, wbCtdaTypeToStr, wbCtdaTypeToInt, cpNormal, False, nil, wbCtdaTypeAfterSet),\n      wbByteArray('Unused', 3, cpIgnore, False, wbNeverShow),\n      wbUnion('Comparison Value', wbCTDACompValueDecider, [\n        wbFloat('Comparison Value - Float'),\n        wbFormIDCk('Comparison Value - Global', [GLOB])\n      ]),\n      wbInteger('Function', itU16, wbCTDAFunctionToStr, wbCTDAFunctionToInt),\n      wbByteArray('Unused', 2, cpIgnore, False, wbNeverShow),\n      wbUnion('Parameter #1', wbCTDAParam1Decider, [\n        wbByteArray('Unknown', 4),\n        wbByteArray('None', 4, cpIgnore),\n        wbInteger('Integer', itS32),\n        wbFloat('Float'),\n        wbByteArray('Variable Name (unused)', 4, cpIgnore),\n        wbInteger('Sex', itU32, wbSexEnum),\n        wbInteger('Actor Value', itS32, wbActorValueEnum),\n        wbInteger('Crime Type', itU32, wbCrimeTypeEnum),\n        wbInteger('Axis', itU32, wbAxisEnum),\n        wbInteger('Quest Stage (unused)', itS32),\n        wbInteger('Misc Stat', itU32, wbMiscStatEnum),\n        wbInteger('Alignment', itU32, wbAlignmentEnum),\n        wbFormIDCkNoReach('Equip Type', [EQUP]),\n        wbInteger('Form Type', itU32, wbFormTypeEnum),\n        wbInteger('Critical Stage', itU32, wbCriticalStageEnum),\n        wbFormIDCkNoReach('Object Reference', [NULL, PLYR, ACHR, REFR, PGRE, PHZD, PMIS, PARW, PBAR, PBEA, PCON, PFLA]),\n        wbFormIDCkNoReach('Inventory Object', [ARMO, BOOK, MISC, WEAP, AMMO, KEYM, ALCH, SCRL, SLGM, INGR, FLST, LIGH, LVLI, COBJ]),\n        wbFormIDCkNoReach('Actor', [NULL, PLYR, ACHR, REFR]),\n        wbFormIDCkNoReach('Voice Type', [VTYP, FLST]),\n        wbFormIDCkNoReach('Idle', [IDLE]),\n        wbFormIDCkNoReach('Form List', [FLST]),\n        wbFormIDCkNoReach('Quest', [QUST]),\n        wbFormIDCkNoReach('Faction', [FACT]),\n        wbFormIDCkNoReach('Cell', [CELL]),\n        wbFormIDCkNoReach('Class', [CLAS]),\n        wbFormIDCkNoReach('Race', [RACE]),\n        wbFormIDCkNoReach('Actor Base', [NPC_]),\n        wbFormIDCkNoReach('Global', [GLOB]),\n        wbFormIDCkNoReach('Weather', [WTHR]),\n        wbFormIDCkNoReach('Package', [PACK]),\n        wbFormIDCkNoReach('Encounter Zone', [ECZN]),\n        wbFormIDCkNoReach('Perk', [PERK]),\n        wbFormIDCkNoReach('Owner', [NULL, FACT, NPC_]),\n        wbFormIDCkNoReach('Furniture', [FURN, FLST]),\n        wbFormIDCkNoReach('Effect Item', [SPEL, ENCH, ALCH, INGR, SCRL]),\n        wbFormIDCkNoReach('Base Effect', [MGEF]),\n        wbFormIDCkNoReach('Worldspace', [WRLD, FLST]),\n        wbInteger('VATS Value Function', itU32, wbVATSValueFunctionEnum),\n        wbInteger('VATS Value Param (INVALID)', itU32),\n        wbFormIDCkNoReach('Referenceable Object', [NULL, NPC_, PROJ, TREE, SOUN, ACTI, DOOR, STAT, FURN, CONT, ARMO, AMMO, MISC, WEAP, BOOK, KEYM, ALCH, LIGH, GRAS, ASPC, IDLM, ARMA, MSTT, TACT, FLST, LVLI, LVSP, SPEL, SCRL, SHOU, SLGM, ENCH], [NPC_, PROJ, TREE, SOUN, ACTI, DOOR, STAT, FURN, CONT, ARMO, AMMO, MISC, WEAP, BOOK, KEYM, ALCH, LIGH, GRAS, ASPC, IDLM, ARMA, MSTT, TACT, LVLI, LVSP, SPEL, SCRL, SHOU, SLGM, ENCH]),\n        wbFormIDCkNoReach('Region', [REGN]),\n        wbFormIDCkNoReach('Keyword', [KYWD, NULL]),\n        wbInteger('Player Action', itU32, wbAdvanceActionEnum),\n        wbInteger('Casting Type', itU32, wbCastingSourceEnum),\n        wbFormIDCkNoReach('Shout', [SHOU]),\n        wbFormIDCkNoReach('Location', [LCTN]),\n        wbFormIDCkNoReach('Location Ref Type', [LCRT]),\n        wbInteger('Alias', itS32, wbConditionAliasToStr, wbStrToAlias),\n        wbInteger('Packdata ID', itU32),\n        wbFormIDCk('Association Type', [ASTP]),\n        wbInteger('Furniture Anim', itU32, wbFurnitureAnimTypeEnum),\n        wbInteger('Furniture Entry', itU32, wbEnum([], [$010000, 'Front', $020000, 'Behind', $040000, 'Right', $80000, 'Left', $100000, 'Up'])),\n        wbFormIDCk('Scene', [NULL, SCEN]),\n        wbInteger('Ward State', itU32, wbWardStateEnum),\n        wbInteger('Event', itU32, wbEventFunctionAndMemberToStr, wbEventFunctionAndMemberToInt),\n        wbFormID('Event Data')\n      ]),\n      wbUnion('Parameter #2', wbCTDAParam2Decider, [\n        wbByteArray('Unknown', 4),\n        wbByteArray('None', 4, cpIgnore),\n        wbInteger('Integer', itS32),\n        wbFloat('Float'),\n        wbByteArray('Variable Name (unused)', 4, cpIgnore),\n        wbInteger('Sex', itU32, wbSexEnum),\n        wbInteger('Actor Value', itS32, wbActorValueEnum),\n        wbInteger('Crime Type', itU32, wbCrimeTypeEnum),\n        wbInteger('Axis', itU32, wbAxisEnum),\n        wbInteger('Quest Stage', itS32, wbCTDAParam2QuestStageToStr, wbCTDAParam2QuestStageToInt),\n        wbInteger('Misc Stat', itU32, wbMiscStatEnum),\n        wbInteger('Alignment', itU32, wbAlignmentEnum),\n        wbFormIDCkNoReach('Equip Type', [EQUP]),\n        wbInteger('Form Type', itU32, wbFormTypeEnum),\n        wbInteger('Critical Stage', itU32, wbCriticalStageEnum),\n        wbFormIDCkNoReach('Object Reference', [NULL, PLYR, ACHR, REFR, PGRE, PHZD, PMIS, PARW, PBAR, PBEA, PCON, PFLA]),\n        wbFormIDCkNoReach('Inventory Object', [ARMO, BOOK, MISC, WEAP, AMMO, KEYM, ALCH, SCRL, SLGM, INGR, FLST, LIGH, LVLI, COBJ]),\n        wbFormIDCkNoReach('Actor', [NULL, PLYR, ACHR, REFR]),\n        wbFormIDCkNoReach('Voice Type', [VTYP, FLST]),\n        wbFormIDCkNoReach('Idle', [IDLE]),\n        wbFormIDCkNoReach('Form List', [FLST]),\n        wbFormIDCkNoReach('Quest', [QUST]),\n        wbFormIDCkNoReach('Faction', [FACT]),\n        wbFormIDCkNoReach('Cell', [CELL]),\n        wbFormIDCkNoReach('Class', [CLAS]),\n        wbFormIDCkNoReach('Race', [RACE]),\n        wbFormIDCkNoReach('Actor Base', [NPC_]),\n        wbFormIDCkNoReach('Global', [GLOB]),\n        wbFormIDCkNoReach('Weather', [WTHR]),\n        wbFormIDCkNoReach('Package', [PACK]),\n        wbFormIDCkNoReach('Encounter Zone', [ECZN]),\n        wbFormIDCkNoReach('Perk', [PERK]),\n        wbFormIDCkNoReach('Owner', [NULL, FACT, NPC_]),\n        wbFormIDCkNoReach('Furniture', [FURN, FLST]),\n        wbFormIDCkNoReach('Effect Item', [SPEL, ENCH, ALCH, INGR, SCRL]),\n        wbFormIDCkNoReach('Base Effect', [MGEF]),\n        wbFormIDCkNoReach('Worldspace', [WRLD, FLST]),\n        wbInteger('VATS Value Function', itU32, wbVATSValueFunctionEnum),\n        wbUnion('VATS Value Param', wbCTDAParam2VATSValueParamDecider, [\n         { 0} wbFormIDCkNoReach('Weapon', [WEAP]),\n         { 1} wbFormIDCkNoReach('Weapon List', [FLST], [WEAP]),\n         { 2} wbFormIDCkNoReach('Target', [NPC_]),\n         { 3} wbFormIDCkNoReach('Target List', [FLST], [NPC_]),\n         { 4} wbByteArray('Unknown', 4, cpIgnore),\n         { 5} wbInteger('Target Part', itS32, wbActorValueEnum),\n         { 6} wbInteger('VATS Action', itU32, wbEnum([\n                'Unarmed Attack',\n                'One Hand Melee Attack',\n                'Two Hand Melee Attack',\n                'Magic Attack',\n                'Ranged Attack',\n                'Reload',\n                'Crouch',\n                'Stand',\n                'Switch Weapon',\n                'Toggle Weapon Drawn',\n                'Heal',\n                'Player Death'\n          ])),\n         { 7} wbByteArray('Unknown', 4, cpIgnore),\n         { 8} wbByteArray('Unknown', 4, cpIgnore),\n         { 9} wbFormIDCkNoReach('Critical Effect', [SPEL]),\n         {10} wbFormIDCkNoReach('Critical Effect List', [FLST], [SPEL]),\n         {11} wbByteArray('Unknown', 4, cpIgnore),\n         {12} wbByteArray('Unknown', 4, cpIgnore),\n         {13} wbByteArray('Unknown', 4, cpIgnore),\n         {14} wbByteArray('Unknown', 4, cpIgnore),\n         {15} wbInteger('Weapon Type', itU32, wbWeaponAnimTypeEnum),\n         {16} wbByteArray('Unknown', 4, cpIgnore),\n         {17} wbByteArray('Unknown', 4, cpIgnore),\n         {18} wbInteger('Projectile Type', itU32, wbEnum([\n                'Missile',\n                'Lobber',\n                'Beam',\n                'Flame',\n                'Cone',\n                'Barrier',\n                'Arrow'\n              ])),\n         {19} wbInteger('Delivery Type', itU32, wbTargetEnum),\n         {20} wbInteger('Casting Type', itU32, wbCastEnum)\n        ]),\n        wbFormIDCkNoReach('Referenceable Object', [NULL, NPC_, PROJ, TREE, SOUN, ACTI, DOOR, STAT, FURN, CONT, ARMO, AMMO, MISC, WEAP, BOOK, KEYM, ALCH, LIGH, GRAS, ASPC, IDLM, ARMA, MSTT, TACT, FLST, LVLI, LVSP, SPEL, SCRL, SHOU, SLGM, ENCH], [NPC_, PROJ, TREE, SOUN, ACTI, DOOR, STAT, FURN, CONT, ARMO, AMMO, MISC, WEAP, BOOK, KEYM, ALCH, LIGH, GRAS, ASPC, IDLM, ARMA, MSTT, TACT, LVLI, LVSP, SPEL, SCRL, SHOU, SLGM, ENCH]),\n        wbFormIDCkNoReach('Region', [REGN]),\n        wbFormIDCkNoReach('Keyword', [KYWD, NULL]),\n        wbInteger('Player Action', itU32, wbAdvanceActionEnum),\n        wbInteger('Casting Type', itU32, wbCastingSourceEnum),\n        wbFormIDCkNoReach('Shout', [SHOU]),\n        wbFormIDCkNoReach('Location', [LCTN]),\n        wbFormIDCkNoReach('Location Ref Type', [LCRT]),\n        wbInteger('Alias', itS32, wbConditionAliasToStr, wbStrToAlias),\n        wbInteger('Packdata ID', itU32),\n        wbFormIDCk('Association Type', [ASTP]),\n        wbInteger('Furniture Anim', itU32, wbFurnitureAnimTypeEnum),\n        wbInteger('Furniture Entry', itU32, wbEnum([], [$010000, 'Front', $020000, 'Behind', $040000, 'Right', $80000, 'Left', $100000, 'Up'])),\n        wbFormIDCk('Scene', [NULL, SCEN]),\n        wbInteger('Ward State', itU32, wbWardStateEnum),\n        wbInteger('Event', itU32, wbEventFunctionAndMemberToStr, wbEventFunctionAndMemberToInt),\n        wbFormID('Event Data')\n      ]),\n      wbInteger('Run On', itU32, wbEnum([\n        {0} 'Subject',\n        {1} 'Target',\n        {2} 'Reference',\n        {3} 'Combat Target',\n        {4} 'Linked Reference',\n        {5} 'Quest Alias',\n        {6} 'Package Data',\n        {7} 'Event Data'\n      ]), cpNormal, False, nil, wbCTDARunOnAfterSet),\n      wbUnion('Reference', wbCTDAReferenceDecider, [\n        wbInteger('Unused', itU32, nil, cpIgnore),\n        wbFormIDCkNoReach('Reference', [NULL, PLYR, ACHR, REFR, PGRE, PHZD, PMIS, PARW, PBAR, PBEA, PCON, PFLA], False)\n      ]),\n      wbInteger('Parameter #3', itS32, nil, cpNormal, False, nil, nil, -1)\n    ], cpNormal, False{, nil, 0, wbCTDAAfterLoad}),\n    wbString(CIS1, 'Parameter #1'),\n    wbString(CIS2, 'Parameter #2')\n  ], [], cpNormal);\n\n  wbCTDAs := wbRArray('Conditions', wbCTDA, cpNormal, False);\n  wbCTDAsCount := wbRArray('Conditions', wbCTDA, cpNormal, False, nil, wbCTDAsAfterSet);\n  wbCTDAsReq := wbRArray('Conditions', wbCTDA, cpNormal, True);\n  wbCTDAsReqCount := wbRArray('Conditions', wbCTDA, cpNormal, True, nil, wbCTDAsAfterSet);\n  wbYNAM := wbFormIDCk(YNAM, 'Sound - Pick Up', [SNDR]);\n  wbZNAM := wbFormIDCk(ZNAM, 'Sound - Put Down', [SNDR]);\n\n  wbEffectsReq :=\n    wbRStructs('Effects', 'Effect', [\n      wbEFID,\n      wbEFIT,\n      wbCTDAs\n    ], [], cpNormal, True);\n\n  wbRecord(ALCH, 'Ingestible',\n    wbFlags(wbRecordFlagsFlags, wbFlagsList([\n      {0x20000000} 29, 'Medicine'\n    ])), [\n    wbEDID,\n    wbOBNDReq,\n    wbFULL,\n    wbKSIZ,\n    wbKWDAs,\n    wbDESC,\n    wbMODL,\n    wbDEST,\n    wbICON,\n    wbYNAM,\n    wbZNAM,\n    wbETYP,\n    wbFloat(DATA, 'Weight', cpNormal, True),\n    wbStruct(ENIT, 'Effect Data', [\n      wbInteger('Value', itS32),\n      wbInteger('Flags', itU32, wbFlags([\n        {0x00000001} 'No Auto-Calc',\n        {0x00000002} 'Food Item',\n        {0x00000004} 'Unknown 3',\n        {0x00000008} 'Unknown 4',\n        {0x00000010} 'Unknown 5',\n\t\t\t\t{0x00000020} 'Unknown 6',\n\t\t\t\t{0x00000040} 'Unknown 7',\n\t\t\t\t{0x00000080} 'Unknown 8',\n\t\t\t\t{0x00000100} 'Unknown 9',\n\t\t\t\t{0x00000200} 'Unknown 10',\n\t\t\t\t{0x00000400} 'Unknown 11',\n\t\t\t\t{0x00000800} 'Unknown 12',\n\t\t\t\t{0x00001000} 'Unknown 13',\n\t\t\t\t{0x00002000} 'Unknown 14',\n\t\t\t\t{0x00004000} 'Unknown 15',\n\t\t\t\t{0x00008000} 'Unknown 16',\n\t\t\t\t{0x00010000} 'Medicine',\n\t\t\t\t{0x00020000} 'Poison'\n      ])),\n      wbFormID('Addiction'),\n      wbFloat('Addiction Chance'),\n      wbFormIDCk('Sound - Consume', [SNDR, NULL])\n    ], cpNormal, True),\n    wbEffectsReq\n  ], False, nil, cpNormal, False, wbRemoveEmptyKWDA, wbKeywordsAfterSet);\n\n  wbRecord(AMMO, 'Ammunition',\n    wbFlags(wbRecordFlagsFlags, wbFlagsList([\n      {0x00000004}  2, 'Non-Playable'\n    ])), [\n    wbEDID,\n    wbOBNDReq,\n    wbFULL,\n    wbMODL,\n    wbICON,\n    wbDEST,\n    wbYNAM,\n    wbZNAM,\n    wbDESC,\n    wbKSIZ,\n    wbKWDAs,\n    wbStruct(DATA, 'Data', [\n      wbFormIDCk('Projectile', [PROJ, NULL]),\n        wbInteger('Flags', itU32, wbFlags([\n          'Ignores Normal Weapon Resistance',\n          'Non-Playable',\n          'Non-Bolt'\n        ])),\n      wbFloat('Damage'),\n      wbInteger('Value', itU32)\n    ], cpNormal, True),\n    wbString(ONAM, 'Short Name')\n  ], False, nil, cpNormal, False, wbRemoveEmptyKWDA, wbKeywordsAfterSet);\n\n  wbRecord(ANIO, 'Animated Object',\n    wbFlags(wbRecordFlagsFlags, wbFlagsList([\n      {0x00000200}  9, 'Unknown 9' // always present in updated records, not in Skyrim.esm\n    ]), [9]), [\n    wbEDID,\n    wbMODL,\n    wbString(BNAM, 'Unload Event')\n  ]);\n\n  wbRecord(ARMO, 'Armor',\n    wbFlags(wbRecordFlagsFlags, wbFlagsList([\n      {0x00000004}  2, 'Non-Playable',\n      {0x00000040}  6, 'Shield',\n      {0x00000400} 10, 'Unknown 10',\n      {0x00008000} 15, 'Unknown 15'\n    ])), [\n    wbEDID,\n    wbVMAD,\n    wbOBNDReq,\n    wbFULL,\n    wbEITM,\n    wbInteger(EAMT, 'Enchantment Amount', itU16),\n    wbRStruct('Male world model', [\n      wbString(MOD2, 'Model Filename'),\n      wbByteArray(MO2T, 'Texture Files Hashes', 0, cpIgnore, false, false, wbNeverShow),\n      wbMO2S\n    ], []),\n    wbICON,\n    wbRStruct('Female world model', [\n      wbString(MOD4, 'Model Filename'),\n      wbByteArray(MO4T, 'Texture Files Hashes', 0, cpIgnore, false, false, wbNeverShow),\n      wbMO4S\n    ], []),\n    wbICO2,\n    wbBODTBOD2,\n    wbDEST,\n    wbYNAM,\n    wbZNAM,\n    wbString(BMCT, 'Ragdoll Constraint Template'),\n    wbETYP,\n    wbFormIDCk(BIDS, 'Bash Impact Data Set', [IPDS]),\n    wbFormIDCk(BAMT, 'Alternate Block Material', [MATT]),\n    wbFormIDCk(RNAM, 'Race', [RACE]),\n    wbKSIZ,\n    wbKWDAs,\n    wbDESC,\n    wbRArray('Armature', wbFormIDCK(MODL, 'Model Filename', [ARMA, NULL])),\n    wbStruct(DATA, 'Data', [\n      wbInteger('Value', itS32),\n      wbFloat('Weight')\n    ], cpNormal, True),\n    wbInteger(DNAM, 'Armor Rating', itS32, wbDiv(100), cpNormal, True),\n    wbFormIDCk(TNAM, 'Template Armor', [ARMO])\n  ], False, nil, cpNormal, False, wbARMOAfterLoad, wbKeywordsAfterSet);\n\n  wbRecord(ARMA, 'Armor Addon', [\n    wbEDID,\n    wbBODTBOD2,\n    wbFormIDCk(RNAM, 'Race', [RACE]),\n    wbStruct(DNAM, 'Data', [\n      wbInteger('Male Priority', itU8),\n      wbInteger('Female Priority', itU8),\n      // essentialy a number of world models for different weights (Enabled = 2 models _0.nif and _1.nif)\n      wbInteger('Weight slider - Male', itU8, wbFlags([\n        {0x01} 'Unknown 0',\n        {0x02} 'Enabled'\n      ])),\n      wbInteger('Weight slider - Female', itU8, wbFlags([\n        {0x01} 'Unknown 0',\n        {0x02} 'Enabled'\n      ])),\n      wbByteArray('Unknown', 2),\n      wbInteger('Detection Sound Value', itU8),\n      wbByteArray('Unknown', 1),\n      wbFloat('Weapon Adjust')\n    ], cpNormal, True),\n    wbRStruct('Male world model', [\n      wbString(MOD2, 'Model Filename'),\n      wbByteArray(MO2T, 'Texture Files Hashes', 0, cpIgnore, false, false, wbNeverShow),\n      wbMO2S\n    ], [], cpNormal, False),\n    wbRStruct('Female world model', [\n      wbString(MOD3, 'Model Filename'),\n      wbByteArray(MO3T, 'Texture Files Hashes', 0, cpIgnore, false, false, wbNeverShow),\n      wbMO3S\n    ], []),\n    wbRStruct('Male 1st Person', [\n      wbString(MOD4, 'Model Filename'),\n      wbByteArray(MO4T, 'Texture Files Hashes', 0, cpIgnore, false, false, wbNeverShow),\n      wbMO4S\n    ], []),\n    wbRStruct('Female 1st Person', [\n      wbString(MOD5, 'Model Filename'),\n      wbByteArray(MO5T, 'Texture Files Hashes', 0, cpIgnore, false, false, wbNeverShow),\n      wbMO5S\n    ], []),\n    wbFormIDCK(NAM0, 'Male Skin Texture', [TXST, NULL]),\n    wbFormIDCK(NAM1, 'Female Skin texture', [TXST, NULL]),\n    wbFormIDCK(NAM2, 'Male Skin Texture Swap List', [FLST, NULL]),\n    wbFormIDCK(NAM3, 'Female Skin Texture Swap List', [FLST, NULL]),\n    wbRArrayS('Additional Races', wbFormIDCK(MODL, 'Race', [RACE, NULL])),\n    wbFormIDCk(SNDD, 'Footstep Sound', [FSTS, NULL]),\n    wbFormIDCk(ONAM, 'Art Object', [ARTO])\n  ], False, nil, cpNormal, False, wbARMAAfterLoad);\n\n  wbRecord(BOOK, 'Book', [\n    wbEDID,\n    wbVMAD,\n    wbOBNDReq,\n    wbFULL,\n    wbMODL,\n    wbICON,\n    wbLStringKC(DESC, 'Book Text', 0, cpTranslate, True),\n    wbDEST,\n    wbYNAM,\n    wbZNAM,\n    wbKSIZ,\n    wbKWDAs,\n    wbStruct(DATA, 'Data', [\n      wbInteger('Flags', itU8, wbFlags([\n       {0x01} 'Teaches Skill',\n       {0x02} 'Can''t be Taken',\n       {0x04} 'Teaches Spell',\n       {0x08} 'Unknown 4',\n       {0x10} 'Unknown 5',\n       {0x20} 'Unknown 6',\n       {0x40} 'Unknown 7',\n       {0x80} 'Unknown 8'\n      ])),\n      wbInteger('Type', itU8, wbEnum([], [\n        0, 'Book/Tome', 255, 'Note/Scroll'\n      ])),\n      wbByteArray('Unused', 2),\n      wbUnion('Teaches', wbBOOKTeachesDecider, [\n        wbInteger('Skill', itS32, wbSkillEnum),\n        wbFormIDCk('Spell', [SPEL, NULL])\n      ]),\n      wbInteger('Value', itU32),\n      wbFloat('Weight')\n    ], cpNormal, True),\n    wbFormIDCk(INAM, 'Inventory Art', [STAT]),\n    wbLString(CNAM, 'Description', 0, cpTranslate)\n  ], False, nil, cpNormal, False, nil, wbKeywordsAfterSet);\nend;\n\nprocedure DefineTES5c;\n\n  procedure ReferenceRecord(aSignature: TwbSignature; const aName: string);\n  begin\n    wbRecord(aSignature, aName,\n      wbFlags(wbRecordFlagsFlags, wbFlagsList([\n        {0x00000080}  7, 'Turn Off Fire',\n        {0x00000400} 10, 'Persistent',\n        {0x00000800} 11, 'Initially Disabled',\n        {0x10000000} 28, 'Reflected By Auto Water',\n        {0x20000000} 29, 'Don''t Havok Settle',\n        {0x40000000} 30, 'No Respawn'\n      ], True, True)), [\n      wbEDID,\n      wbVMAD,\n      wbFormIDCk(NAME, 'Projectile', [PROJ, HAZD]),\n      wbFormIDCk(XEZN, 'Encounter Zone', [ECZN]),\n      wbOwnership,\n      wbFloat(XHTW, 'Head-Tracking Weight'),\n      wbFloat(XFVC, 'Favor Cost'),\n      wbRArrayS('Reflected/Refracted By',\n        wbStructSK(XPWR, [0], 'Water', [\n          wbFormIDCk('Reference', [REFR]),\n          wbInteger('Type', itU32, wbFlags([\n            'Reflection',\n            'Refraction'\n          ]))\n        ], cpNormal, False, nil, 1)\n      ),\n      wbRArrayS('Linked References', wbStructSK(XLKR, [0], 'Linked Reference', [\n        wbFormIDCk('Keyword/Ref', [KYWD, PLYR, ACHR, REFR, PGRE, PHZD, PMIS, PARW, PBAR, PBEA, PCON, PFLA, NULL]),\n        wbFormIDCk('Ref', [PLYR, ACHR, REFR, PGRE, PHZD, PMIS, PARW, PBAR, PBEA, PCON, PFLA])\n      ], cpNormal, False, nil, 1)),\n      wbRStruct('Activate Parents', [\n        wbInteger(XAPD, 'Flags', itU8, wbFlags([\n          'Parent Activate Only'\n        ], True)),\n        wbRArrayS('Activate Parent Refs',\n          wbStructSK(XAPR, [0], 'Activate Parent Ref', [\n            wbFormIDCk('Reference', [PLYR, ACHR, REFR, PGRE, PHZD, PMIS, PARW, PBAR, PBEA, PCON, PFLA]),\n            wbFloat('Delay')\n          ])\n        )\n      ], []),\n      wbXESP,\n      wbFormIDCk(XEMI, 'Emittance', [LIGH, REGN]),\n      wbFormIDCk(XMBR, 'MultiBound Reference', [REFR]),\n      wbEmpty(XIS2, 'Ignored by Sandbox'),\n      wbArray(XLRT, 'Location Ref Type', wbFormIDCk('Ref', [LCRT, NULL])),\n      wbFormIDCk(XLRL, 'Location Reference', [LCRT, LCTN, NULL], False, cpBenignIfAdded),\n      wbXLOD,\n      wbXSCL,\n      wbDataPosRot\n    ], True, wbPlacedAddInfo);\n  end;\n\nbegin\n{>>>\n  Skrim has its own ref record for every projectile type\n  PARW 'Arrow'\n  PBEA 'Beam'\n  PFLA 'Flame'\n  PCON 'Cone' (voice)\n  PBAR 'Barrier'\n  PGRE 'Traps'\n  PHZD 'Hazards'\n  I guess all of them have the same structure\n<<<}\n  ReferenceRecord(PARW, 'Placed Arrow');\n  ReferenceRecord(PBAR, 'Placed Barrier');\n  ReferenceRecord(PBEA, 'Placed Beam');\n  ReferenceRecord(PCON, 'Placed Cone/Voice');\n  ReferenceRecord(PFLA, 'Placed Flame');\n  ReferenceRecord(PGRE, 'Placed Projectile');\n  ReferenceRecord(PHZD, 'Placed Hazard');\n  ReferenceRecord(PMIS, 'Placed Missile');\n\n  wbRecord(CELL, 'Cell',\n    wbFlags(wbRecordFlagsFlags, wbFlagsList([\n      {0x00000400} 10, 'Persistent',\n      {0x00020000} 17, 'Off Limits',\n      {0x00040000} 18, 'Compressed',\n      {0x00080000} 19, 'Can''t Wait'\n    ]), [18]), [\n    wbEDID,\n    wbFULL,\n    {>>>\n    Flags can be itU8, but CELL\\DATA has a critical role in various wbImplementation.pas routines\n    and replacing it with wbUnion generates error when setting for example persistent flag in REFR.\n    So let it always be an integer\n    <<<}\n    wbInteger(DATA, 'Flags', itU16, wbFlags([\n      {0x0001} 'Is Interior Cell',\n      {0x0002} 'Has Water',\n      {0x0004} 'Can''t Travel From Here',\n      {0x0008} 'No LOD Water',\n      {0x0010} 'Unknown 5',\n      {0x0020} 'Public Area',\n      {0x0040} 'Hand Changed',\n      {0x0080} 'Show Sky',\n      {0x0100} 'Use Sky Lighting'\n    ]), cpNormal, True, False, nil, wbCELLDATAAfterSet),\n    wbStruct(XCLC, 'Grid', [\n      wbInteger('X', itS32),\n      wbInteger('Y', itS32),\n      wbInteger('Force Hide Land', itU32, wbFlags([\n        'Quad 1',\n        'Quad 2',\n        'Quad 3',\n        'Quad 4'\n      ], True))\n    ], cpNormal, False, nil, 2),\n    wbStruct(XCLL, 'Lighting', [\n      wbByteColors('Ambient Color'),\n      wbByteColors('Directional Color'),\n      wbByteColors('Fog Color Near'),\n      wbFloat('Fog Near'),\n      wbFloat('Fog Far'),\n      wbInteger('Directional Rotation XY', itS32),\n      wbInteger('Directional Rotation Z', itS32),\n      wbFloat('Directional Fade'),\n      wbFloat('Fog Clip Distance'),\n      wbFloat('Fog Power'),\n      wbAmbientColors('Ambient Colors'),\n      wbByteColors('Fog Color Far'),\n      wbFloat('Fog Max'),\n      wbFloat('Light Fade Begin'),\n      wbFloat('Light Fade End'),\n      wbInteger('Inherits', itU32, wbFlags([\n        {0x00000001}'Ambient Color',\n        {0x00000002}'Directional Color',\n        {0x00000004}'Fog Color',\n        {0x00000008}'Fog Near',\n        {0x00000010}'Fog Far',\n        {0x00000020}'Directional Rotation',\n        {0x00000040}'Directional Fade',\n        {0x00000080}'Clip Distance',\n        {0x00000100}'Fog Power',\n        {0x00000200}'Fog Max',\n        {0x00000400}'Light Fade Distances'\n      ]))\n    ], cpNormal, False, nil, 11),\n\n    wbTVDT,\n    wbMaxHeightDataCELL,\n    wbFormIDCk(LTMP, 'Lighting Template', [LGTM, NULL], False, cpNormal, True),\n    wbByteArray(LNAM, 'Unknown', 0, cpIgnore), // leftover flags, they are now in XCLC\n\n    {>>> XCLW sometimes has $FF7FFFFF and causes invalid floation point <<<}\n    wbFloat(XCLW, 'Water Height', cpNormal, False, 1, -1, nil, nil, 0, wbCELLXCLWGetConflictPriority),\n    //wbByteArray(XCLW, 'Water Height', 4),\n    wbString(XNAM, 'Water Noise Texture'),\n    wbArrayS(XCLR, 'Regions', wbFormIDCk('Region', [REGN])),\n    wbFormIDCk(XLCN, 'Location', [LCTN]),\n    wbByteArray(XWCN, 'Unknown', 0, cpIgnore), // leftover\n    wbByteArray(XWCS, 'Unknown', 0, cpIgnore), // leftover\n    wbStruct(XWCU, 'Water Velocity', [\n      wbFloat('X Offset'),\n      wbFloat('Y Offset'),\n      wbFloat('Z Offset'),\n      wbByteArray('Unknown', 4),\n      wbFloat('X Angle'),\n      wbFloat('Y Angle'),\n      wbFloat('Z Angle'),\n      wbByteArray('Unknown', 0)\n    ]),\n    wbFormIDCk(XCWT, 'Water', [WATR]),\n    wbOwnership,\n    wbFormIDCk(XILL, 'Lock List', [FLST, NPC_]),\n    wbString(XWEM, 'Water Environment Map'),\n    wbFormIDCk(XCCM, 'Sky/Weather from Region', [REGN]),\n    wbFormIDCk(XCAS, 'Acoustic Space', [ASPC]),\n    wbFormIDCk(XEZN, 'Encounter Zone', [ECZN]),\n    wbFormIDCk(XCMO, 'Music Type', [MUSC]),\n    wbFormIDCk(XCIM, 'Image Space', [IMGS])\n  ], True, wbCellAddInfo, cpNormal, False, wbCELLAfterLoad);\n\n\n  wbRecord(CLAS, 'Class', [\n    wbEDID,\n    wbFULLReq,\n    wbDESCReq,\n    wbICON,\n    wbStruct(DATA, '', [\n      wbByteArray('Unknown', 4),\n      wbInteger('Teaches', itS8, wbEnum([\n        'One Handed',\n        'Two Handed',\n        'Archery',\n        'Block',\n        'Smithing',\n        'Heavy Armor',\n        'Light Armor',\n        'Pickpocket',\n        'Lockpicking',\n        'Sneak',\n        'Alchemy',\n        'Speech',\n        'Alteration',\n        'Conjuration',\n        'Destruction',\n        'Illusion',\n        'Restoration',\n        'Enchanting'\n      ])),\n      wbInteger('Maximum training level', itU8),\n      wbArray('Skill Weights', wbInteger('Weight', itU8), [\n        'One Handed',\n        'Two Handed',\n        'Archery',\n        'Block',\n        'Smithing',\n        'Heavy Armor',\n        'Light Armor',\n        'Pickpocket',\n        'Lockpicking',\n        'Sneak',\n        'Alchemy',\n        'Speech',\n        'Alteration',\n        'Conjuration',\n        'Destruction',\n        'Illusion',\n        'Restoration',\n        'Enchanting'\n      ]),\n      wbFloat('Bleedout Default'),\n      wbInteger('Voice Points', itU32),\n      wbArray('Attribute Weights', wbInteger('Weight', itU8), [\n        'Health',\n        'Magicka',\n        'Stamina',\n        'Unknown'\n      ])\n    ], cpNormal, True)\n  ]);\n\n  wbRecord(CLMT, 'Climate', [\n    wbEDID,\n    wbArrayS(WLST, 'Weather Types', wbStructSK([0], 'Weather Type', [\n      wbFormIDCk('Weather', [WTHR, NULL]),\n      wbInteger('Chance', itS32),\n      wbFormIDCk('Global', [GLOB, NULL])\n    ])),\n    wbString(FNAM, 'Sun Texture'),\n    wbString(GNAM, 'Sun Glare Texture'),\n    wbMODL,\n    wbStruct(TNAM, 'Timing', [\n      wbStruct('Sunrise', [\n        wbInteger('Begin', itU8, wbClmtTime),\n        wbInteger('End', itU8, wbClmtTime)\n      ]),\n      wbStruct('Sunset', [\n        wbInteger('Begin', itU8, wbClmtTime),\n        wbInteger('End', itU8, wbClmtTime)\n      ]),\n      wbInteger('Volatility', itU8),\n      wbInteger('Moons / Phase Length', itU8, wbClmtMoonsPhaseLength)\n    ], cpNormal, True)\n  ]);\n\n  wbRecord(SPGD, 'Shader Particle Geometry', [\n    wbEDID,\n    // FO4 SPGD format for Form Version 44\n    wbUnion(DATA, '', wbSPGDFormatDecider, [\n      wbStruct('Data', [\n        wbFloat('Gravity Velocity'),\n        wbByteArray('Unknown', 4),\n        wbFloat('Rotation Velocity'),\n        wbByteArray('Unknown', 4),\n        wbFloat('Particle Size X'),\n        wbFloat('Center Offset Min'),\n        wbFloat('Particle Size Y'),\n        wbByteArray('Unknown', 4),\n        wbFloat('Center Offset Min'),\n        wbByteArray('Unknown', 4),\n        wbFloat('Center Offset Max'),\n        wbByteArray('Unknown', 4),\n        wbFloat('Initial Rotation'),\n        wbByteArray('Unknown', 4),\n        wbInteger('# of Subtextures X', itU32),\n        wbByteArray('Unknown', 4),\n        wbInteger('# of Subtextures Y', itU32),\n        wbByteArray('Unknown', 4),\n        wbInteger('Type', itU32, wbEnum([\n          'Rain',\n          'Snow'\n        ])),\n        wbByteArray('Unknown', 4),\n        wbInteger('Box Size', itU32),\n        wbByteArray('Unknown', 4),\n        wbFloat('Particle Density'),\n        wbByteArray('Unknown', 4)\n      ], cpNormal, True),\n      wbStruct('Data', [\n        wbFloat('Gravity Velocity'),\n        wbFloat('Rotation Velocity'),\n        wbFloat('Particle Size X'),\n        wbFloat('Particle Size Y'),\n        wbFloat('Center Offset Min'),\n        wbFloat('Center Offset Max'),\n        wbFloat('Initial Rotation Range'),\n        wbInteger('# of Subtextures X', itU32),\n        wbInteger('# of Subtextures Y', itU32),\n        wbInteger('Type', itU32, wbEnum([\n          'Rain',\n          'Snow'\n        ])),\n        wbInteger('Box Size', itU32),\n        wbFloat('Particle Density')\n      ], cpNormal, True, nil, 10)\n    ]),\n    wbString(ICON, 'Particle Texture')\n  ]);\n\n  wbRecord(RFCT, 'Visual Effect', [\n    wbEDID,\n    wbStruct(DATA, 'Effect Data', [\n\t\t\twbFormIDCK('Effect Art', [ARTO, NULL]),\n      wbFormIDCK('Shader', [EFSH, NULL]),\n      wbInteger('Flags', itU32, wbFlags([\n        {0x00000001}'Rotate to Face Target',\n        {0x00000002}'Attach to Camera',\n        {0x00000004}'Inherit Rotation'\n      ]))\n    ], cpNormal, True)\n  ]);\n\n  wbRecord(CONT, 'Container',\n    wbFlags(wbRecordFlagsFlags, wbFlagsList([\n      {0x00008000} 15, 'Has Distant LOD',\n      {0x00010000} 16, 'Random Anim Start',\n      {0x02000000} 25, 'Obstacle',\n      {0x04000000} 26, 'NavMesh Generation - Filter',\n      {0x08000000} 27, 'NavMesh Generation - Bounding Box',\n      {0x40000000} 30, 'NavMesh Generation - Ground'\n    ])), [\n    wbEDID,\n    wbVMAD,\n    wbOBNDReq,\n    wbFULL,\n    wbMODL,\n    wbCOCT,\n    wbCNTOs,\n    wbDEST,\n    wbStruct(DATA, '', [\n      wbInteger('Flags', itU8, wbFlags([\n        {0x01} 'Allow Sounds When Animation',\n        {0x02} 'Respawns',\n        {0x04} 'Show Owner'\n      ])),\n      wbFloat('Weight')\n    ], cpNormal, True),\n    wbFormIDCk(SNAM, 'Sound - Open', [SNDR]),\n    wbFormIDCk(QNAM, 'Sound - Close', [SNDR])\n  ], True, nil, cpNormal, False, nil, wbContainerAfterSet);\n\n  wbCSDT := wbRStructSK([0], 'Sound Type', [\n    wbInteger(CSDT, 'Type', itU32,wbEnum([\n      {00} 'Left Foot',\n      {01} 'Right Foot',\n      {02} 'Left Back Foot',\n      {03} 'Right Back Foot',\n      {04} 'Idle',\n      {05} 'Aware',\n      {06} 'Attack',\n      {07} 'Hit',\n      {08} 'Death',\n      {09} 'Weapon',\n      {10} 'Movement Loop',\n      {11} 'Conscious Loop',\n      {12} 'Auxiliary 1',\n      {13} 'Auxiliary 2',\n      {14} 'Auxiliary 3',\n      {15} 'Auxiliary 4',\n      {16} 'Auxiliary 5',\n      {17} 'Auxiliary 6',\n      {18} 'Auxiliary 7',\n      {19} 'Auxiliary 8',\n      {19} 'Auxiliary 8',\n      {20} 'Jump',\n      {21} 'PlayRandom/Loop'\n    ])),\n    wbRArrayS('Sounds', wbRStructSK([0], 'Sound', [\n      wbFormIDCk(CSDI, 'Sound', [SNDR, NULL], False, cpNormal, True),\n      wbInteger(CSDC, 'Sound Chance', itU8, nil, cpNormal, True)\n    ], []), cpNormal, True)\n  ], []);\n\n  wbCSDTs := wbRArrayS('Sound Types', wbCSDT, cpNormal, False, nil, nil, nil{wbActorTemplateUseModelAnimation});\n\n  wbAIDT :=\n    wbStruct(AIDT, 'AI Data', [\n     {00} wbInteger('Aggression', itU8, wbEnum([\n            'Unaggressive',\n            'Aggressive',\n            'Very Aggressive',\n            'Frenzied'\n          ])),\n     {01} wbInteger('Confidence', itU8, wbEnum([\n            'Cowardly',\n            'Cautious',\n            'Average',\n            'Brave',\n            'Foolhardy'\n          ])),\n     {02} wbInteger('Energy Level', itU8),\n     {03} wbInteger('Responsibility', itU8, wbEnum([\n            'Any crime',\n            'Violence against enemies',\n            'Property crime only',\n            'No crime'\n          ])),\n     {04} wbInteger('Mood', itU8, wbEnum([\n            'Neutral',\n            'Angry',\n            'Fear',\n            'Happy',\n            'Sad',\n            'Surprised',\n            'Puzzled',\n            'Disgusted'\n          ])),\n          wbInteger('Assistance', itU8, wbEnum([\n            'Helps Nobody',\n            'Helps Allies',\n            'Helps Friends and Allies'\n          ])),\n          wbStruct('Aggro', [\n            wbInteger('Aggro Radius Behavior', itU8, wbEnum(['False', 'True'])),\n            wbInteger('Unknown', itU8),\n            wbInteger('Warn', itU32),\n            wbInteger('Warn/Attack', itU32),\n            wbInteger('Attack', itU32)\n          ])\n    ], cpNormal, True, nil{wbActorTemplateUseAIData});\n\n  wbAttackAnimationEnum := wbEnum([], [\n     26, 'AttackLeft',\n     32, 'AttackRight',\n     38, 'Attack3',\n     44, 'Attack4',\n     50, 'Attack5',\n     56, 'Attack6',\n     62, 'Attack7',\n     68, 'Attack8',\n     74, 'AttackLoop',\n     80, 'AttackSpin',\n     86, 'AttackSpin2',\n     97, 'PlaceMine',\n    103, 'PlaceMine2',\n    109, 'AttackThrow',\n    115, 'AttackThrow2',\n    121, 'AttackThrow3',\n    127, 'AttackThrow4',\n    133, 'AttackThrow5',\n    255, ' DEFAULT'\n  ]);\n\n  wbRecord(CSTY, 'Combat Style',\n    wbFlags(wbRecordFlagsFlags, wbFlagsList([\n      {0x00080000} 19, 'Allow Dual Wielding'\n    ])), [\n    wbEDID,\n    wbStruct(CSGD, 'General', [\n      wbFloat('Offensive Mult'),\n      wbFloat('Defensive Mult'),\n      wbFloat('Group Offensive Mult'),\n      // keep as separate floats, some elements can be omitted\n      wbFloat('Equipment Score Mult - Melee'),\n      wbFloat('Equipment Score Mult - Magic'),\n      wbFloat('Equipment Score Mult - Ranged'),\n      wbFloat('Equipment Score Mult - Shout'),\n      wbFloat('Equipment Score Mult - Unarmed'),\n      wbFloat('Equipment Score Mult - Staff'),\n      wbFloat('Avoid Threat Chance')\n    ], cpNormal, True, nil, 0),\n    wbUnknown(CSMD, cpIgnore),\n    wbStruct(CSME, 'Melee', [\n      wbFloat('Attack Staggered Mult'),\n      wbFloat('Power Attack Staggered Mult'),\n      wbFloat('Power Attack Blocking Mult'),\n      wbFloat('Bash Mult'),\n      wbFloat('Bash Recoil Mult'),\n      wbFloat('Bash Attack Mult'),\n      wbFloat('Bash Power Attack Mult'),\n      wbFloat('Special Attack Mult')\n    ], cpNormal, False, nil, 0),\n    wbStruct(CSCR, 'Close Range', [\n      wbFloat('Circle Mult'),\n      wbFloat('Fallback Mult'),\n      wbFloat('Flank Distance'),\n      wbFloat('Stalk Time')\n    ], cpNormal, False, nil, 0),\n    wbStruct(CSLR, 'Long Range', [\n      wbFloat('Strafe Mult')\n    ], cpNormal, False),\n    wbStruct(CSFL, 'Flight', [\n      wbFloat('Hover Chance'),\n      wbFloat('Dive Bomb Chance'),\n      wbFloat('Ground Attack Chance'),\n      wbFloat('Hover Time'),\n      wbFloat('Ground Attack Time'),\n      wbFloat('Perch Attack Chance'),\n      wbFloat('Perch Attack Time'),\n      wbFloat('Flying Attack Chance')\n    ], cpNormal, False, nil, 0),\n    wbInteger(DATA, 'Flags', itU32, wbFlags([\n      {0x01} 'Dueling',\n      {0x02} 'Flanking',\n      {0x04} 'Allow Dual Wielding'\n    ]), cpNormal, False)\n  ]);\nend;\n\nprocedure DefineTES5d;\nbegin\n  wbRecord(DIAL, 'Dialog Topic', [\n    wbEDID,\n    wbFULL,\n    wbFloat(PNAM, 'Priority', cpNormal, True, 1, -1, nil, nil, 50.0),\n    wbFormIDCk(BNAM, 'Branch', [DLBR, NULL]),\n    wbFormIDCk(QNAM, 'Quest', [QUST, NULL], False, cpNormal, False),\n    wbStruct(DATA, 'Data', [\n      // this should not be named Flags since TwbFile.BuildReachable\n      // expects Top-Level flag here from FNV\n      wbInteger('Topic Flags', itU8, wbFlags([\n        'Do All Before Repeating'\n      ]), cpNormal, True),\n      wbInteger('Category', itU8, wbEnum([\n        {0} 'Topic',\n        {1} 'Favor', // only in DA14 quest topics\n        {2} 'Scene',\n        {3} 'Combat',\n        {4} 'Favors',\n        {5} 'Detection',\n        {6} 'Service',\n        {7} 'Miscellaneous'\n      ])),\n      wbInteger('Subtype', itU16, wbEnum([], [\n         0, 'Custom',\n         1, 'ForceGreet',\n         2, 'Rumors',\n         3, 'Custom?',\n         4, 'Intimidate',\n         5, 'Flatter',\n         6, 'Bribe',\n         7, 'Ask Gift',\n         8, 'Gift',\n         9, 'Ask Favor',\n        10, 'Favor',\n        11, 'Show Relationships',\n        12, 'Folow',\n        13, 'Reject',\n        14, 'Scene',\n        15, 'Show',\n        16, 'Agree',\n        17, 'Refuse',\n        18, 'ExitFavorState',\n        19, 'MoralRefusal',\n        20, 'FlyingMountLand',\n        21, 'FlyingMountCancelLand',\n        22, 'FlyingMountAcceptTarget',\n        23, 'FlyingMountRejectTarget',\n        24, 'FlyingMountNoTarget',\n        25, 'FlyingMountDestinationReached',\n        26, 'Attack',\n        27, 'PowerAttack',\n        28, 'Bash',\n        29, 'Hit',\n        30, 'Flee',\n        31, 'Bleedout',\n        32, 'AvoidThreat',\n        33, 'Death',\n        34, 'GroupStrategy',\n        35, 'Block',\n        36, 'Taunt',\n        37, 'AllyKilled',\n        38, 'Steal',\n        39, 'Yield',\n        40, 'AcceptYield',\n        41, 'PickpocketCombat',\n        42, 'Assault',\n        43, 'Murder',\n        44, 'AssaultNC',\n        45, 'MurderNC',\n        46, 'PickpocketNC',\n        47, 'StealFromNC',\n        48, 'TrespassAgainstNC',\n        49, 'Trespass',\n        50, 'WereTransformCrime',\n        51, 'VoicePowerStartShort',\n        52, 'VoicePowerStartLong',\n        53, 'VoicePowerEndShort',\n        54, 'VoicePowerEndLong',\n        55, 'AlertIdle',\n        56, 'LostIdle',\n        57, 'NormalToAlert',\n        58, 'AlertToCombat',\n        59, 'NormalToCombat',\n        60, 'AlertToNormal',\n        61, 'CombatToNormal',\n        62, 'CombatToLost',\n        63, 'LostToNormal',\n        64, 'LostToCombat',\n        65, 'DetectFriendDie',\n        66, 'ServiceRefusal',\n        67, 'Repair',\n        68, 'Travel',\n        69, 'Training',\n        70, 'BarterExit',\n        71, 'RepairExit',\n        72, 'Recharge',\n        73, 'RechargeExit',\n        74, 'TrainingExit',\n        75, 'ObserveCombat',\n        76, 'NoticeCorpse',\n        77, 'TimeToGo',\n        78, 'GoodBye',\n        79, 'Hello',\n        80, 'SwingMeleeWeapon',\n        81, 'ShootBow',\n        82, 'ZKeyObject',\n        83, 'Jump',\n        84, 'KnockOverObject',\n        85, 'DestroyObject',\n        86, 'StandonFurniture',\n        87, 'LockedObject',\n        88, 'PickpocketTopic',\n        89, 'PursueIdleTopic',\n        90, 'SharedInfo',\n        91, 'PlayerCastProjectileSpell',\n        92, 'PlayerCastSelfSpell',\n        93, 'PlayerShout',\n        94, 'Idle',\n        95, 'EnterSprintBreath',\n        96, 'EnterBowZoomBreath',\n        97, 'ExitBowZoomBreath',\n        98, 'ActorCollidewithActor',\n        99, 'PlayerinIronSights',\n       100, 'OutofBreath',\n       101, 'CombatGrunt',\n       102, 'LeaveWaterBreath'\n      ]))\n    ]),\n    wbString(SNAM, 'Subtype Name', 4),\n    wbInteger(TIFC, 'Info Count', itU32, nil, cpBenign)\n  ]);\n\n  wbRecord(DOOR, 'Door',\n    wbFlags(wbRecordFlagsFlags, wbFlagsList([\n      {0x00008000} 15, 'Has Distant LOD',\n      {0x00010000} 16, 'Random Anim Start',\n      {0x00800000} 23, 'Is Marker'\n    ])), [\n    wbEDID,\n    wbVMAD,\n    wbOBNDReq,\n    wbFULL,\n    wbMODL,\n    wbDEST,\n    wbFormIDCk(SNAM, 'Sound - Open', [SNDR]),\n    wbFormIDCk(ANAM, 'Sound - Close', [SNDR]),\n    wbFormIDCk(BNAM, 'Sound - Loop', [SNDR]),\n    wbInteger(FNAM, 'Flags', itU8, wbFlags([\n      '',\n      'Automatic',\n      'Hidden',\n      'Minimal Use',\n      'Sliding',\n      'Do Not Open in Combat Search'\n    ]), cpNormal, True)\n  ]);\n\n  wbBlendModeEnum := wbEnum([\n    '',\n    'Zero',\n    'One',\n    'Source Color',\n    'Source Inverse Color',\n    'Source Alpha',\n    'Source Inverted Alpha',\n    'Dest Alpha',\n    'Dest Inverted Alpha',\n    'Dest Color',\n    'Dest Inverse Color',\n    'Source Alpha SAT'\n  ]);\n\n  wbBlendOpEnum := wbEnum([\n    '',\n    'Add',\n    'Subtract',\n    'Reverse Subtract',\n    'Minimum',\n    'Maximum'\n  ]);\n\n  wbZTestFuncEnum := wbEnum([\n    '',\n    '',\n    '',\n    'Equal To',\n    'Normal',\n    'Greater Than',\n    '',\n    'Greater Than or Equal To',\n    'Always Show'\n  ]);\n\n  wbRecord(EFSH, 'Effect Shader', [\n    wbEDID,\n    wbString(ICON, 'Fill Texture'),\n    wbString(ICO2, 'Particle Shader Texture'),\n    wbString(NAM7, 'Holes Texture'),\n    wbString(NAM8, 'Membrane Palette Texture'),\n    wbString(NAM9, 'Particle Palette Texture'),\n    wbStruct(DATA, '', [\n      wbByteArray('Unknown', 4),\n      wbInteger('Membrane Shader - Source Blend Mode', itU32, wbBlendModeEnum),\n      wbInteger('Membrane Shader - Blend Operation', itU32, wbBlendOpEnum),\n      wbInteger('Membrane Shader - Z Test Function', itU32, wbZTestFuncEnum),\n      wbByteColors('Fill/Texture Effect - Color Key 1'),\n      wbFloat('Fill/Texture Effect - Alpha Fade In Time'),\n      wbFloat('Fill/Texture Effect - Full Alpha Time'),\n      wbFloat('Fill/Texture Effect - Alpha Fade Out Time'),\n      wbFloat('Fill/Texture Effect - Presistent Alpha Ratio'),\n      wbFloat('Fill/Texture Effect - Alpha Pulse Amplitude'),\n      wbFloat('Fill/Texture Effect - Alpha Pulse Frequency'),\n      wbFloat('Fill/Texture Effect - Texture Animation Speed (U)'),\n      wbFloat('Fill/Texture Effect - Texture Animation Speed (V)'),\n      wbFloat('Edge Effect - Fall Off'),\n      wbByteColors('Edge Effect - Color'),\n      wbFloat('Edge Effect - Alpha Fade In Time'),\n      wbFloat('Edge Effect - Full Alpha Time'),\n      wbFloat('Edge Effect - Alpha Fade Out Time'),\n      wbFloat('Edge Effect - Persistent Alpha Ratio'),\n      wbFloat('Edge Effect - Alpha Pulse Amplitude'),\n      wbFloat('Edge Effect - Alpha Pulse Frequency'),\n      wbFloat('Fill/Texture Effect - Full Alpha Ratio'),\n      wbFloat('Edge Effect - Full Alpha Ratio'),\n      wbInteger('Membrane Shader - Dest Blend Mode', itU32, wbBlendModeEnum),\n      wbInteger('Particle Shader - Source Blend Mode', itU32, wbBlendModeEnum),\n      wbInteger('Particle Shader - Blend Operation', itU32, wbBlendOpEnum),\n      wbInteger('Particle Shader - Z Test Function', itU32, wbZTestFuncEnum),\n      wbInteger('Particle Shader - Dest Blend Mode', itU32, wbBlendModeEnum),\n      wbFloat('Particle Shader - Particle Birth Ramp Up Time'),\n      wbFloat('Particle Shader - Full Particle Birth Time'),\n      wbFloat('Particle Shader - Particle Birth Ramp Down Time'),\n      wbFloat('Particle Shader - Full Particle Birth Ratio'),\n      wbFloat('Particle Shader - Persistant Particle Count'),\n      wbFloat('Particle Shader - Particle Lifetime'),\n      wbFloat('Particle Shader - Particle Lifetime +/-'),\n      wbFloat('Particle Shader - Initial Speed Along Normal'),\n      wbFloat('Particle Shader - Acceleration Along Normal'),\n      wbFloat('Particle Shader - Initial Velocity #1'),\n      wbFloat('Particle Shader - Initial Velocity #2'),\n      wbFloat('Particle Shader - Initial Velocity #3'),\n      wbFloat('Particle Shader - Acceleration #1'),\n      wbFloat('Particle Shader - Acceleration #2'),\n      wbFloat('Particle Shader - Acceleration #3'),\n      wbFloat('Particle Shader - Scale Key 1'),\n      wbFloat('Particle Shader - Scale Key 2'),\n      wbFloat('Particle Shader - Scale Key 1 Time'),\n      wbFloat('Particle Shader - Scale Key 2 Time'),\n      wbByteColors('Color Key 1 - Color'),\n      wbByteColors('Color Key 2 - Color'),\n      wbByteColors('Color Key 3 - Color'),\n      wbFloat('Color Key 1 - Color Alpha'),\n      wbFloat('Color Key 2 - Color Alpha'),\n      wbFloat('Color Key 3 - Color Alpha'),\n      wbFloat('Color Key 1 - Color Key Time'),\n      wbFloat('Color Key 2 - Color Key Time'),\n      wbFloat('Color Key 3 - Color Key Time'),\n      wbFloat('Particle Shader - Initial Speed Along Normal +/-'),\n      wbFloat('Particle Shader - Initial Rotation (deg)'),\n      wbFloat('Particle Shader - Initial Rotation (deg) +/-'),\n      wbFloat('Particle Shader - Rotation Speed (deg/sec)'),\n      wbFloat('Particle Shader - Rotation Speed (deg/sec) +/-'),\n      wbFormIDCk('Addon Models', [DEBR, NULL]),\n      wbFloat('Holes - Start Time'),\n      wbFloat('Holes - End Time'),\n      wbFloat('Holes - Start Val'),\n      wbFloat('Holes - End Val'),\n      wbFloat('Edge Width (alpha units)'),\n      wbByteColors('Edge Color'),\n      wbFloat('Explosion Wind Speed'),\n      wbInteger('Texture Count U', itU32),\n      wbInteger('Texture Count V', itU32),\n      wbFloat('Addon Models - Fade In Time'),\n      wbFloat('Addon Models - Fade Out Time'),\n      wbFloat('Addon Models - Scale Start'),\n      wbFloat('Addon Models - Scale End'),\n      wbFloat('Addon Models - Scale In Time'),\n      wbFloat('Addon Models - Scale Out Time'),\n      wbFormIDCk('Ambient Sound', [SNDR, SOUN, NULL]),\n      wbByteColors('Fill/Texture Effect - Color Key 2'),\n      wbByteColors('Fill/Texture Effect - Color Key 3'),\n      wbStruct('Fill/Texture Effect - Color Key Scale/Time', [\n        wbFloat('Color Key 1 - Scale'),\n        wbFloat('Color Key 2 - Scale'),\n        wbFloat('Color Key 3 - Scale'),\n        wbFloat('Color Key 1 - Time'),\n        wbFloat('Color Key 2 - Time'),\n        wbFloat('Color Key 3 - Time')\n      ]),\n      wbFloat('Color Scale'),\n      wbFloat('Birth Position Offset'),\n      wbFloat('Birth Position Offset Range +/-'),\n      wbStruct('Particle Shader Animated', [\n        wbInteger('Start Frame', itU32),\n        wbInteger('Start Frame Variation', itU32),\n        wbInteger('End Frame', itU32),\n        wbInteger('Loop Start Frame', itU32),\n        wbInteger('Loop Start Variation', itU32),\n        wbInteger('Frame Count', itU32),\n        wbInteger('Frame Count Variation', itU32)\n      ]),\n      wbInteger('Flags', itU32, wbFlags([\n        'No Membrane Shader',\n        'Membrane Grayscale Color',\n        'Membrane Grayscale Alpha',\n        'No Particle Shader',\n        'Edge Effect Inverse',\n        'Affect Skin Only',\n        'Ignore Alpha',\n        'Project UVs',\n        'Ignore Base Geometry Alpha',\n        'Lighting',\n        'No Weapons',\n        'Unknown 11',\n        'Unknown 12',\n        'Unknown 13',\n        'Unknown 14',\n        'Particle Animated',\n        'Particle Grayscale Color',\n        'Particle Grayscale Alpha',\n        'Unknown 18',\n        'Unknown 19',\n        'Unknown 20',\n        'Unknown 21',\n        'Unknown 22',\n        'Unknown 23',\n        'Use Blood Geometry'\n      ])),\n      wbFloat('Fill/Texture Effect - Texture Scale (U)'),\n      wbFloat('Fill/Texture Effect - Texture Scale (V)'),\n      wbInteger('Scene Graph Emit Depth Limit (unused)', itU32)\n    ], cpNormal, True, nil, 0)\n  ], False, nil, cpNormal, False, nil {wbEFSHAfterLoad});\n\n  wbRecord(ENCH, 'Object Effect', [\n    wbEDID,\n    wbOBNDReq,\n    wbFULL,\n    wbStruct(ENIT, 'Effect Data', [\n      wbInteger('Enchantment Cost', itS32),\n      wbInteger('Flags', itU32, wbFlags([\n        'No Auto-Calc',\n        '',\n        'Extend Duration On Recast'\n      ])),\n      wbInteger('Cast Type', itU32, wbCastEnum),\n      wbInteger('Enchantment Amount', itS32),\n      wbInteger('Target Type', itU32, wbTargetEnum),\n      wbInteger('Enchant Type', itU32, wbEnum([], [\n        $06, 'Enchantment',\n        $0C, 'Staff Enchantment'\n      ])),\n      wbFloat('Charge Time'),\n      wbFormIDCk('Base Enchantment', [ENCH, NULL]),\n      wbFormIDCk('Worn Restrictions', [FLST, NULL])\n    ], cpNormal, True, nil, 8),\n    wbEffectsReq\n  ]);\n\n  wbRecord(EYES, 'Eyes',\n    wbFlags(wbRecordFlagsFlags, wbFlagsList([\n      {0x00000004}  2, 'Non-Playable'\n    ])), [\n    wbEDID,\n    wbFULLReq,\n    wbString(ICON, 'Texture', 0, cpNormal, True),\n    wbInteger(DATA, 'Flags', itU8, wbFlags([\n      {0x01}'Playable',\n      {0x02}'Not Male',\n      {0x04}'Not Female',\n      {0x08}'Unknown 4',\n      {0x10}'Unknown 5',\n      {0x20}'Unknown 6',\n      {0x40}'Unknown 7',\n      {0x80}'Unknown 8'\n    ]), cpNormal, True)\n  ]);\n\n  wbRecord(FACT, 'Faction', [\n    wbEDID,\n    wbFULL,\n    wbRArrayS('Relations',\n      wbStructSK(XNAM, [0], 'Relation', [\n        wbFormIDCkNoReach('Faction', [FACT, RACE]),\n        wbInteger('Modifier', itS32),\n        wbInteger('Group Combat Reaction', itU32, wbEnum([\n        {0x00000001}'Neutral',\n        {0x00000002}'Enemy',\n        {0x00000004}'Ally',\n        {0x00000008}'Friend'\n      ]))\n    ])),\n    wbStruct(DATA, 'Flags', [\n      wbInteger('Flags', itU32, wbFlags([\n        {0x00000001}'Hidden From NPC',\n        {0x00000002}'Special Combat',\n        {0x00000004}'Unknown 3',\n        {0x00000008}'Unknown 4',\n        {0x00000010}'Unknown 5',\n        {0x00000020}'Unknown 6',\n        {0x00000040}'Track Crime',\n        {0x00000080}'Ignore Crimes: Murder',\n        {0x00000100}'Ignore Crimes: Assault',\n        {0x00000200}'Ignore Crimes: Stealing',\n        {0x00000400}'Ignore Crimes: Trespass',\n        {0x00000800}'Do Not Report Crimes Against Members',\n        {0x00001000}'Crime Gold - Use Defaults',\n        {0x00002000}'Ignore Crimes: Pickpocket',\n        {0x00004000}'Vendor',\n        {0x00008000}'Can Be Owner',\n        {0x00010000}'Ignore Crimes: Werewolf',\n        {0x00020000}'Unknown 18',\n        {0x00040000}'Unknown 19',\n        {0x00080000}'Unknown 20',\n        {0x00100000}'Unknown 21',\n        {0x00200000}'Unknown 22',\n        {0x00400000}'Unknown 23',\n        {0x00800000}'Unknown 24',\n        {0x01000000}'Unknown 25',\n        {0x02000000}'Unknown 26',\n        {0x04000000}'Unknown 27',\n        {0x08000000}'Unknown 28',\n        {0x10000000}'Unknown 29',\n        {0x20000000}'Unknown 30',\n        {0x40000000}'Unknown 31',\n        {0x80000000}'Unknown 32'\n      ]))\n    ], cpNormal, True, nil, 1),\n    wbFormIDCk(JAIL, 'Exterior Jail Marker', [REFR]),\n    wbFormIDCk(WAIT, 'Follower Wait Marker', [REFR]),\n    wbFormIDCk(STOL, 'Stolen Goods Container', [REFR]),\n    wbFormIDCk(PLCN, 'Player Inventory Container', [REFR]),\n    wbFormIDCk(CRGR, 'Shared Crime Faction List', [FLST]),\n    wbFormIDCk(JOUT, 'Jail Outfit', [OTFT]),\n    wbStruct(CRVA, 'Crime Values', [\n      {01} wbInteger('Arrest', itU8, wbEnum(['False', 'True'])),\n      {02} wbInteger('Attack On Sight', itU8, wbEnum(['False', 'True'])),\n      {02} wbInteger('Murder', itU16),\n      {02} wbInteger('Assault', itU16),\n      {02} wbInteger('Trespass', itU16),\n      {02} wbInteger('Pickpocket', itU16),\n      {02} wbInteger('Unknown', itU16),\n      {02} wbFloat('Steal Multiplier'),\n      {02} wbInteger('Escape', itU16),\n      {02} wbInteger('Werewolf', itU16)\n      ], cpNormal, False, nil, 7),\n    wbRStructsSK('Ranks', 'Rank', [0], [\n      wbInteger(RNAM, 'Rank#', itU32),\n      wbLString(MNAM, 'Male Title', 0, cpTranslate),\n      wbLString(FNAM, 'Female Title', 0, cpTranslate),\n      wbString(INAM, 'Insignia Unused')\n    ], []),\n    wbFormIDCk(VEND, 'Vendor Buy/Sell List', [FLST]),\n    wbFormIDCk(VENC, 'Merchant Container', [REFR]),\n    wbStruct(VENV, 'Vendor Values', [\n      {01} wbInteger('Start Hour', itU16),\n      {02} wbInteger('End Hour', itU16),\n      {02} wbInteger('Radius', itU16),\n      {02} wbByteArray('Unknown 1', 2),\n           wbInteger('Only Buys Stolen Items', itU8, wbEnum(['False', 'True'])),\n           wbInteger('Not/Sell Buy', itU8, wbEnum(['False', 'True'])),\n      {02} wbByteArray('Unknown 2', 2)\n      ]),\n    wbPLVD,\n    wbCITC,\n    wbCTDAsCount\n  ], False, nil, cpNormal, False, nil {wbFACTAfterLoad}, wbConditionsAfterSet);\n\n  wbRecord(FURN, 'Furniture',\n    wbFlags(wbRecordFlagsFlags, wbFlagsList([\n      {0x00000080}  7, 'Is Perch',\n      {0x00008000} 15, 'Has Distant LOD',\n      {0x00010000} 16, 'Random Anim Start',\n      {0x00800000} 23, 'Is Marker',\n      {0x10000000} 28, 'Must Exit To Talk',\n      {0x20000000} 29, 'Child Can Use'\n    ])), [\n    wbEDID,\n    wbVMAD,\n    wbOBNDReq,\n    wbFULL,\n    wbMODL,\n    wbDEST,\n    wbKSIZ,\n    wbKWDAs,\n    wbUnknown(PNAM),\n    wbInteger(FNAM, 'Flags', itU16, wbFlags([\n      {0x0001} 'Unknown 0',\n      {0x0002} 'Ignored By Sandbox'\n    ])),\n    wbFormIDCk(KNAM, 'Interaction Keyword', [KYWD, NULL]),\n    wbInteger(MNAM, 'Active Markers / Flags', itU32, wbFlags([\n      {0x00000001} 'Sit 0',\n      {0x00000002} 'Sit 1',\n      {0x00000004} 'Sit 2',\n      {0x00000008} 'Sit 3',\n      {0x00000010} 'Sit 4',\n      {0x00000020} 'Sit 5',\n      {0x00000040} 'Sit 6',\n      {0x00000080} 'Sit 7',\n      {0x00000100} 'Sit 8',\n      {0x00000200} 'Sit 9',\n      {0x00000400} 'Sit 10',\n      {0x00000800} 'Sit 11',\n      {0x00001000} 'Sit 12',\n      {0x00002000} 'Sit 13',\n      {0x00004000} 'Sit 14',\n      {0x00008000} 'Sit 15',\n      {0x00010000} 'Sit 16',\n      {0x00020000} 'Sit 17',\n      {0x00040000} 'Sit 18',\n      {0x00080000} 'Sit 19',\n      {0x00100000} 'Sit 20',\n      {0x00200000} 'Sit 21',\n      {0x00400000} 'Sit 22',\n      {0x00800000} 'Sit 23',\n      {0x01000000} 'Unknown 25',\n      {0x02000000} 'Disables Activation',\n      {0x04000000} 'Is Perch',\n      {0x08000000} 'Must Exit to Talk',\n      {0x10000000} 'Unknown 29',\n      {0x20000000} 'Unknown 30',\n      {0x40000000} 'Unknown 31',\n      {0x80000000} 'Unknown 32'\n    ])),\n    wbStruct(WBDT, 'Workbench Data', [\n      wbInteger('Bench Type', itU8, wbEnum([\n        {0} 'None',\n        {1} 'Create object',\n        {2} 'Smithing Weapon',\n        {3} 'Enchanting',\n        {4} 'Enchanting Experiment',\n        {5} 'Alchemy',\n        {6} 'Alchemy Experiment',\n        {7} 'Smithing Armor'\n      ])),\n      wbInteger('Uses Skill', itS8, wbSkillEnum)\n    ]),\n    wbFormIDCk(NAM1, 'Associated Spell', [SPEL]),\n    wbRArray('Markers', wbRStruct('Marker', [\n      wbInteger(ENAM, 'Marker Index', itU32),\n      wbStruct(NAM0, 'Disabled Entry Points', [\n        wbByteArray('Unknown', 2),\n        wbInteger('Disabled Points', itU16, wbFurnitureEntryTypeFlags)\n      ]),\n      wbFormIDCk(FNMK, 'Marker Keyword', [KYWD, NULL])\n    ], [])),\n    wbRArray('Marker Entry Points', wbStruct(FNPR, 'Marker', [\n      wbInteger('Type', itU16, wbFurnitureAnimTypeEnum),\n      wbInteger('Entry Points', itU16, wbFurnitureEntryTypeFlags)\n    ])),\n    wbString(XMRK, 'Model Filename')\n  ], False, nil, cpNormal, False, nil, wbKeywordsAfterSet);\n\n//----------------------------------------------------------------------------\n// For expansion to use wbGLOBUnionDecider to display Short, Long, Float\n// correctly without making a signed float by default\n//----------------------------------------------------------------------------\n  wbRecord(GLOB, 'Global',\n    wbFlags(wbRecordFlagsFlags, wbFlagsList([\n      {0x00000040}  6, 'Constant'\n    ])), [\n    wbEDID,\n    wbInteger(FNAM, 'Type', itU8, wbGLOBFNAM, nil, cpNormal, True),\n    wbFloat(FLTV, 'Value', cpNormal, True)\n  ]);\n\n  wbRecord(GMST, 'Game Setting', [\n    wbString(EDID, 'Editor ID', 0, cpCritical, True, nil, wbGMSTEDIDAfterSet),\n    wbUnion(DATA, 'Value', wbGMSTUnionDecider, [\n      wbLString('Name', 0, cpTranslate),\n      wbInteger('Int', itS32),\n      wbFloat('Float'),\n      wbInteger('Bool', itU32, wbEnum(['False', 'True']))\n    ], cpNormal, True)\n  ]);\n\n  wbRecord(KYWD, 'Keyword', [\n    wbEDID,\n    wbCNAM\n  ]);\nend;\n\nprocedure DefineTES5e;\nbegin\n  wbRecord(LCRT, 'Location Reference Type', [\n    wbEDID,\n    wbCNAM\n  ]);\n\n  wbRecord(AACT, 'Action', [\n    wbEDID,\n    wbCNAM\n  ]);\n\n  wbRecord(TXST, 'Texture Set', [\n    wbEDID,\n    wbOBNDReq,\n    wbRStruct('Textures (RGB/A)', [\n      wbString(TX00,'Difuse'),\n      wbString(TX01,'Normal/Gloss'),\n      wbString(TX02,'Environment Mask/Subsurface Tint'),\n      wbString(TX03,'Glow/Detail Map'),\n      wbString(TX04,'Height'),\n      wbString(TX05,'Environment'),\n      wbString(TX06,'Multilayer'),\n      wbString(TX07,'Backlight Mask/Specular')\n    ], []),\n    wbDODT,\n    wbInteger(DNAM, 'Flags', itU16, wbFlags([\n      {0x0001}'No Specular Map',\n      {0x0002}'Facegen Textures',\n      {0x0004}'Has Model Space Normal Map'\n    ]), cpNormal, False)\n  ]);\n\n  wbRecord(HDPT, 'Head Part',\n    wbFlags(wbRecordFlagsFlags, wbFlagsList([\n      {0x00000004}  2, 'Non-Playable'\n    ])), [\n    wbEDID,\n    wbFULL,\n    wbMODL,\n    wbInteger(DATA, 'Flags', itU8, wbFlags([\n      {0x01} 'Playable',\n      {0x02} 'Male',\n      {0x04} 'Female',\n      {0x10} 'Is Extra Part',\n      {0x20} 'Use Solid Tint'\n    ]), cpNormal, True),\n    wbInteger(PNAM, 'Type', itU32, wbEnum([\n      'Misc',\n      'Face',\n      'Eyes',\n      'Hair',\n      'Facial Hair',\n      'Scar',\n      'Eyebrows'\n    ])),\n    wbRArrayS('Extra Parts',\n      wbFormIDCk(HNAM, 'Part', [HDPT])\n    ),\n    wbRStructs('Parts', 'Part', [\n      wbInteger(NAM0, 'Part Type', itU32, wbEnum([\n        'Race Morph',\n        'Tri',\n        'Chargen Morph'\n      ])),\n      wbString(NAM1, 'Filename', 0, cpTranslate, True)\n    ], []),\n    wbFormIDCk(TNAM, 'Texture Set', [TXST, NULL]),\n    wbFormIDCk(CNAM, 'Color', [CLFM, NULL]),\n    wbFormIDCk(RNAM, 'Valid Races', [FLST, NULL])\n  ]);\n\n  wbRecord(ASPC, 'Acoustic Space', [\n    wbEDID,\n    wbOBNDReq,\n    wbFormIDCk(SNAM, 'Ambient Sound', [SNDR]),\n    wbFormIDCk(RDAT, 'Use Sound from Region (Interiors Only)', [REGN]),\n    wbFormIDCk(BNAM, 'Environment Type (reverb)', [REVB])\n  ]);\n\n  wbRecord(MSTT, 'Moveable Static',\n    wbFlags(wbRecordFlagsFlags, wbFlagsList([\n      {0x00000100}  8, 'Must Update Anims',\n      {0x00000200}  9, 'Hidden From Local Map',\n      {0x00008000} 15, 'Has Distant LOD',\n      {0x00010000} 16, 'Random Anim Start',\n      {0x00080000} 19, 'Has Currents',\n      {0x02000000} 25, 'Obstacle',\n      {0x04000000} 26, 'NavMesh Generation - Filter',\n      {0x08000000} 27, 'NavMesh Generation - Bounding Box',\n      {0x40000000} 30, 'NavMesh Generation - Ground'\n    ])), [\n    wbEDID,\n    wbOBNDReq,\n    wbFULL,\n    wbMODL,\n    wbDEST,\n    wbInteger(DATA, 'Flags', itU8, wbFlags([\n      'On Local Map',\n      'Unknown 1',\n      'Unknown 2'\n    ]), cpNormal, True),\n    wbFormIDCk(SNAM, 'Looping Sound', [SNDR])\n  ]);\nend;\n\nprocedure DefineTES5f;\nbegin\n  wbRecord(IDLM, 'Idle Marker',\n    wbFlags(wbRecordFlagsFlags, wbFlagsList([\n      {0x20000000} 29, 'Child Can Use'\n    ])), [\n    wbEDID,\n    wbOBNDReq,\n    wbInteger(IDLF, 'Flags', itU8, wbFlags([\n      'Run in Sequence',\n      'Unknown 1',\n      'Do Once',\n      'Unknown 3',\n      'Ignored by Sandbox'\n    ]), cpNormal, False),\n    wbInteger(IDLC, 'Animation Count', itU8, nil, cpBenign),\n    wbFloat(IDLT, 'Idle Timer Setting', cpNormal, False),\n    wbArray(IDLA, 'Animations', wbFormIDCk('Animation', [IDLE]), 0, nil, wbIDLAsAfterSet, cpNormal, False),\n    wbMODL\n  ], False, nil, cpNormal, False, nil, wbAnimationsAfterSet);\n\n  wbRecord(PROJ, 'Projectile', [\n    wbEDID,\n    wbOBNDReq,\n    wbFULL,\n    wbMODL,\n    wbDEST,\n    wbStruct(DATA, 'Data', [\n      {00} wbInteger('Flags', itU16, wbFlags([\n        'Hitscan',\n        'Explosion',\n        'Alt. Trigger',\n        'Muzzle Flash',\n        '',\n        'Can Be Disabled',\n        'Can Be Picked Up',\n        'Supersonic',\n        'Pins Limbs',\n        'Pass Through Small Transparent',\n        'Disable Combat Aim Correction',\n        'Rotation'\n      ])),\n      {02} wbInteger('Type', itU16, wbEnum([], [\n        $01, 'Missile',\n        $02, 'Lobber',\n        $04, 'Beam',\n        $08, 'Flame',\n        $10, 'Cone',\n        $20, 'Barrier',\n        $40, 'Arrow'\n      ])),\n      {04} wbFloat('Gravity'),\n      {08} wbFloat('Speed'),\n      {12} wbFloat('Range'),\n      {16} wbFormIDCk('Light', [LIGH, NULL]),\n      {20} wbFormIDCk('Muzzle Flash - Light', [LIGH, NULL]),\n      {24} wbFloat('Tracer Chance'),\n      {28} wbFloat('Explosion - Alt. Trigger - Proximity'),\n      {32} wbFloat('Explosion - Alt. Trigger - Timer'),\n      {36} wbFormIDCk('Explosion', [EXPL, NULL]),\n      {40} wbFormIDCk('Sound', [SNDR, NULL]),\n      {44} wbFloat('Muzzle Flash - Duration'),\n      {48} wbFloat('Fade Duration'),\n      {52} wbFloat('Impact Force'),\n      {56} wbFormIDCk('Sound - Countdown', [SNDR, NULL]),\n      {60} wbFormIDCk('Sound - Disable', [SNDR, NULL]),\n      {64} wbFormIDCk('Default Weapon Source', [WEAP, NULL]),\n      {68} wbFloat('Cone Spread'),\n      {72} wbFloat('Collision Radius'),\n      {76} wbFloat('Lifetime'),\n      {80} wbFloat('Relaunch Interval'),\n           wbFormIDCk('Decal Data', [TXST, NULL]),\n           wbFormIDCk('Collision Layer', [COLL, NULL])\n    ], cpNormal, True, nil, 22),\n    wbRStructSK([0], 'Muzzle Flash Model', [\n      wbString(NAM1, 'Model Filename'),\n      wbByteArray(NAM2, 'Texture Files Hashes', 0, cpIgnore, false, false, wbNeverShow)\n    ], [], cpNormal, True),\n    wbInteger(VNAM, 'Sound Level', itU32, wbSoundLevelEnum, cpNormal, True)\n  ]);\n\n  wbRecord(HAZD, 'Hazard', [\n    wbEDID,\n    wbOBNDReq,\n    wbFULL,\n    wbMODL,\n    wbFormIDCk(MNAM, 'Image Space Modifier', [IMAD, NULL]),\n    wbStruct(DATA, 'Data', [\n      wbInteger('Limit', itU32),\n      wbFloat('Radius'),\n      wbFloat('Lifetime'),\n      wbFloat('Image Space Radius'),\n      wbFloat('Target Interval'),\n      wbInteger('Flags', itU32, wbFlags([\n        {0x01} 'Affects Player Only',\n        {0x02} 'Inherit Duration from Spawn Spell',\n        {0x04} 'Align to Impact Normal',\n        {0x08} 'Inherit Radius from Spawn Spell',\n        {0x10} 'Drop to Ground'\n      ])),\n      wbFormIDCk('Spell', [SPEL, NULL]),\n      wbFormIDCk('Light', [LIGH, NULL]),\n      wbFormIDCk('Impact Data Set', [IPDS, NULL]),\n      wbFormIDCk('Sound', [SNDR, NULL])\n    ])\n  ]);\n\n  wbSoulGemEnum := wbEnum([\n    {0} 'None',\n    {1} 'Petty',\n    {2} 'Lesser',\n    {3} 'Common',\n    {4} 'Greater',\n    {5} 'Grand'\n  ]);\n\n  wbRecord(SLGM, 'Soul Gem',\n    wbFlags(wbRecordFlagsFlags, wbFlagsList([\n      {0x00020000} 17, 'Can Hold NPC Soul'\n    ])), [\n    wbEDID,\n    wbOBND,\n    wbFULL,\n    wbMODL,\n    wbICON,\n    wbDEST,\n    wbYNAM,\n    wbZNAM,\n    wbKSIZ,\n    wbKWDAs,\n    wbStruct(DATA, '', [\n      wbInteger('Value', itU32),\n      wbFloat('Weight')\n    ], cpNormal, True),\n    wbInteger(SOUL, 'Contained Soul', itU8, wbSoulGemEnum, cpNormal, True),\n    wbInteger(SLCP, 'Maximum Capacity', itU8, wbSoulGemEnum, cpNormal, True),\n    wbFormIDCk(NAM0, 'Linked To', [SLGM])\n  ], False, nil, cpNormal, False, nil, wbKeywordsAfterSet);\n\n\n  if wbSimpleRecords then\n    wbNVNM :=\n      wbStruct(NVNM, 'Geometry', [\n        wbByteArray('Unknown', 8),\n        wbFormIDCk('Parent Worldspace', [WRLD, NULL]),\n        wbUnion('Parent', wbNVNMParentDecider, [\n          wbStruct('Coordinates', [\n            wbInteger('Grid Y', itS16),\n            wbInteger('Grid X', itS16)\n          ]),\n          wbFormIDCk('Parent Cell', [CELL])\n        ]),\n        wbArray('Vertices', wbByteArray('Vertex', 12), -1),\n        wbArray('Triangles', wbByteArray('Triangle', 16), -1),\n        wbArray('External Connections',\n          wbStruct('Connection', [\n            wbByteArray('Unknown', 4),\n            wbFormIDCk('Mesh', [NAVM]),\n            wbInteger('Triangle', itS16)\n          ])\n        , -1),\n        wbArray('Door Triangles',\n          wbStruct('Door Triangle', [\n            wbInteger('Triangle before door', itS16),\n            wbByteArray('Unknown', 4),\n            wbFormIDCk('Door', [REFR])\n          ])\n        , -1),\n        wbUnknown\n      ])\n  else\n    wbNVNM :=\n      wbStruct(NVNM, 'Geometry', [\n        wbInteger('Unknown', itU32),\n        wbByteArray('Unknown', 4),\n        wbFormIDCk('Parent Worldspace', [WRLD, NULL]),\n        wbUnion('Parent', wbNVNMParentDecider, [\n          wbStruct('Coordinates', [\n            wbInteger('Grid Y', itS16),\n            wbInteger('Grid X', itS16)\n          ]),\n          wbFormIDCk('Parent Cell', [CELL])\n        ]),\n        wbArray('Vertices', wbStruct('Vertex', [\n          wbFloat('X'),\n          wbFloat('Y'),\n          wbFloat('Z')\n        ]), -1),\n        wbArray('Triangles',\n          wbStruct('Triangle', [\n            wbInteger('Vertex 0', itS16),\n            wbInteger('Vertex 1', itS16),\n            wbInteger('Vertex 2', itS16),\n            wbInteger('Edge 0-1', itS16),\n            wbInteger('Edge 1-2', itS16),\n            wbInteger('Edge 2-0', itS16),\n            wbInteger('Flags', itU16, wbFlags([\n              'Edge 0-1 link',\n              'Edge 1-2 link',\n              'Edge 2-0 link',\n              'Unknown 4',\n              'Unknown 5',\n              'Unknown 6',\n              'Preferred',\n              'Unknown 8',\n              'Unknown 9',\n              'Water',\n              'Door',\n              'Found',\n              'Unknown 13',\n              'Unknown 14',\n              'Unknown 15',\n              'Unknown 16'\n            ])),\n            wbInteger('Cover Flags', itU16, wbFlags([\n              'Edge 0-1 wall',\n              'Edge 0-1 ledge cover',\n              'Unknown 3',\n              'Unknown 4',\n              'Edge 0-1 left',\n              'Edge 0-1 right',\n              'Edge 1-2 wall',\n              'Edge 1-2 ledge cover',\n              'Unknown 9',\n              'Unknown 10',\n              'Edge 1-2 left',\n              'Edge 1-2 right',\n              'Unknown 13',\n              'Unknown 14',\n              'Unknown 15',\n              'Unknown 16'\n            ]))\n            //wbInteger('Cover Edge #1 Flags', itU8),\n            //wbInteger('Cover Edge #2 Flags', itU8)\n          ])\n        , -1),\n        wbArray('Edge Links',\n          wbStruct('Edge Link', [\n            wbByteArray('Unknown', 4),\n            wbFormIDCk('Mesh', [NAVM]),\n            wbInteger('Triangle', itS16)\n          ])\n        , -1),\n        wbArray('Door Triangles',\n          wbStruct('Door Triangle', [\n            wbInteger('Triangle before door', itS16),\n            wbByteArray('Unknown', 4),\n            wbFormIDCk('Door', [REFR])\n          ])\n        , -1),\n        wbArray('Cover Triangles', wbInteger('Triangle', itS16), -1),\n        wbInteger('NavMeshGrid Divisor', itU32),\n        wbFloat('Max X Distance'),\n        wbFloat('Max Y Distance'),\n        wbFloat('Min X'),\n        wbFloat('Min Y'),\n        wbFloat('Min Z'),\n        wbFloat('Max X'),\n        wbFloat('Max Y'),\n        wbFloat('Max Z'),\n        wbArray('NavMeshGrid', wbArray('NavMeshGridCell', wbInteger('Triangle', itS16), -1))\n      ]);\n\n  wbRecord(NAVM, 'Navigation Mesh',\n    wbFlags(wbRecordFlagsFlags, wbFlagsList([\n      {0x00040000} 18, 'Compressed',\n      {0x04000000} 26, 'AutoGen',\n      {0x80000000} 31, 'NavmeshGenCell'\n    ]), [18]), [\n    wbEDID,\n    wbNVNM,\n    wbUnknown(ONAM),\n    wbUnknown(PNAM),\n    wbUnknown(NNAM)\n  ], False, wbNAVMAddInfo);\n\n\n  if wbSimpleRecords then\n    wbNAVIslandData :=\n      wbStruct('Island Data', [\n        wbByteArray('Unknown', 24),\n        wbArray('Triangles', wbByteArray('Triangle', 6), -1),\n        wbArray('Vertices', wbByteArray('Vertex', 12), -1)\n      ])\n  else\n    wbNAVIslandData :=\n      wbStruct('Island Data', [\n        wbFloat('Min X'),\n        wbFloat('Min Y'),\n        wbFloat('Min Z'),\n        wbFloat('Max X'),\n        wbFloat('Max Y'),\n        wbFloat('Max Z'),\n        wbArray('Triangles',\n          wbStruct('Triangle', [\n            wbArray('Vertices', wbInteger('Vertex', itS16), 3)\n          ])\n        , -1),\n        wbArray('Vertices', wbStruct('Vertex', [\n          wbFloat('X'),\n          wbFloat('Y'),\n          wbFloat('Z')\n        ]), -1)\n      ]);\n\n  wbRecord(NAVI, 'Navigation Mesh Info Map', [\n    wbEDID,\n    wbInteger(NVER, 'Version', itU32),\n    wbRArray('Navigation Map Infos',\n      wbStruct(NVMI, 'Navigation Map Info', [\n        wbFormIDCk('Navigation Mesh', [NAVM]),\n        wbByteArray('Unknown', 4),\n        wbFloat('X'),\n        wbFloat('Y'),\n        wbFloat('Z'),\n        wbInteger('Preferred Merges Flag', itU32),\n        wbArray('Merged To', wbFormIDCk('Mesh', [NAVM]), -1),\n        wbArray('Preferred Merges', wbFormIDCk('Mesh', [NAVM]), -1),\n        wbArray('Linked Doors', wbStruct('Door', [\n          wbByteArray('Unknown', 4),\n          wbFormIDCk('Door Ref', [REFR])\n        ]), -1),\n        wbInteger('Is Island', itU8, wbEnum(['False', 'True'])),\n        wbUnion('Island', wbNAVIIslandDataDecider, [\n          wbNull,\n          wbNAVIslandData\n        ]),\n        wbByteArray('Unknown', 4),\n        wbFormIDCk('Parent Worldspace', [WRLD, NULL]),\n        wbUnion('Parent', wbNAVIParentDecider, [\n          wbStruct('Coordinates', [\n            wbInteger('Grid Y', itS16),\n            wbInteger('Grid X', itS16)\n          ]),\n          wbFormIDCk('Parent Cell', [CELL])\n        ])\n      ])\n    ),\n    wbStruct(NVPP, 'Preferred Pathing', [\n      wbArray('NavMeshes', wbArray('Set', wbFormIDCk('', [NAVM]), -1), -1),\n      wbArray('NavMesh Tree?', wbStruct('', [\n        wbFormIDCk('NavMesh', [NAVM]),\n        wbInteger('Index/Node', itU32)\n      ]), -1)\n    ]),\n    wbArray(NVSI, 'Unknown', wbFormIDCk('Navigation Mesh', [NAVM]))\n  ]);\n\nend;\n\nprocedure DefineTES5g;\nbegin\n\n   wbRecord(EXPL, 'Explosion', [\n    wbEDID,\n    wbVMAD,\n    wbOBNDReq,\n    wbFULL,\n    wbMODL,\n    wbEITM,\n    wbFormIDCk(MNAM, 'Image Space Modifier', [IMAD]),\n    wbStruct(DATA, 'Data', [  // Contradicted by FireStormExplosion02 [EXPL:000877F9]\n      wbFormIDCk('Light', [LIGH, NULL]),\n      wbFormIDCk('Sound 1', [SNDR, NULL]),\n      wbFormIDCk('Sound 2', [SNDR, NULL]),\n      wbFormIDCk('Impact Data Set', [IPDS, NULL]),\n      wbFormID('Placed Object'),\n      wbFormIDCk('Spawn Projectile', [PROJ, NULL]),\n      wbFloat('Force'),\n      wbFloat('Damage'),\n      wbFloat('Radius'),\n      wbFloat('IS Radius'),\n      wbFloat('Vertical Offset Mult'),\n      wbInteger('Flags', itU32, wbFlags([\n        'Unknown 0',\n        'Always Uses World Orientation',\n        'Knock Down - Always',\n        'Knock Down - By Formula',\n        'Ignore LOS Check',\n        'Push Explosion Source Ref Only',\n        'Ignore Image Space Swap',\n        'Chain',\n        'No Controller Vibration'\n      ])),\n      wbInteger('Sound Level', itU32, wbSoundLevelEnum, cpNormal, True)\n    ], cpNormal, True, nil, 10)\n  ]);\n\n  wbRecord(DEBR, 'Debris', [\n    wbEDID,\n    wbRStructs('Models', 'Model', [\n      wbStruct(DATA, 'Data', [\n        wbInteger('Percentage', itU8),\n        wbString('Model Filename'),\n        wbInteger('Flags', itU8, wbFlags([\n          'Has Collision Data'\n        ]))\n      ], cpNormal, True),\n      wbMODT\n    ], [], cpNormal, True)\n  ]);\n\n  wbRecord(IMGS, 'Image Space', [\n    wbEDID,\n    wbUnknown(ENAM, cpIgnore),\n    wbStruct(HNAM, 'HDR', [\n      wbFloat('Eye Adapt Speed'),\n      wbFloat('Bloom Blur Radius'),\n      wbFloat('Bloom Threshold'),\n      wbFloat('Bloom Scale'),\n      wbFloat('Receive Bloom Threshold'),\n      wbFloat('White'),\n      wbFloat('Sunlight Scale'),\n      wbFloat('Sky Scale'),\n      wbFloat('Eye Adapt Strength')\n    ]),\n    wbStruct(CNAM, 'Cinematic', [\n      wbFloat('Saturation'),\n      wbFloat('Brightness'),\n      wbFloat('Contrast')\n    ]),\n    wbStruct(TNAM, 'Tint', [\n      wbFloat('Amount'),\n      wbFloatColors('Color')\n    ]),\n    wbStruct(DNAM, 'Depth of Field', [\n      wbFloat('Strength'),\n      wbFloat('Distance'),\n      wbFloat('Range'),\n      wbByteArray('Unknown', 2),\n      wbInteger('Sky / Blur Radius', itU16, wbEnum([], [\n        16384, 'Radius 0',\n        16672, 'Radius 1',\n        16784, 'Radius 2',\n        16848, 'Radius 3',\n        16904, 'Radius 4',\n        16936, 'Radius 5',\n        16968, 'Radius 6',\n        17000, 'Radius 7',\n        16576, 'No Sky, Radius 0',\n        16736, 'No Sky, Radius 1',\n        16816, 'No Sky, Radius 2',\n        16880, 'No Sky, Radius 3',\n        16920, 'No Sky, Radius 4',\n        16952, 'No Sky, Radius 5',\n        16984, 'No Sky, Radius 6',\n        17016, 'No Sky, Radius 7'\n      ]))\n    ], cpNormal, False, nil, 3)\n  ]);\n\n  wbTimeInterpolator := wbStruct('Data', [\n    wbFloat('Time'),\n    wbFloat('Value')\n  ]);\n\n  wbColorInterpolator := wbStruct('Data', [\n    wbFloat('Time'),\n    wbFloat('Red', cpNormal, False, 255, 0),\n    wbFloat('Green', cpNormal, False, 255, 0),\n    wbFloat('Blue', cpNormal, False, 255, 0),\n    wbFloat('Alpha', cpNormal, False, 255, 0)\n  ]);\n\n  wbRecord(IMAD, 'Image Space Adapter', [\n    wbEDID,\n    wbStruct(DNAM, 'Data Count', [\n      wbInteger('Flags', itU32, wbFlags(['Animatable'])),\n      wbFloat('Duration'),\n      wbStruct('HDR', [\n        wbInteger('Eye Adapt Speed Mult', itU32),\n        wbInteger('Eye Adapt Speed Add', itU32),\n        wbInteger('Bloom Blur Radius Mult', itU32),\n        wbInteger('Bloom Blur Radius Add', itU32),\n        wbInteger('Bloom Threshold Mult', itU32),\n        wbInteger('Bloom Threshold Add', itU32),\n        wbInteger('Bloom Scale Mult', itU32),\n        wbInteger('Bloom Scale Add', itU32),\n        wbInteger('Target Lum Min Mult', itU32),\n        wbInteger('Target Lum Min Add', itU32),\n        wbInteger('Target Lum Max Mult', itU32),\n        wbInteger('Target Lum Max Add', itU32),\n        wbInteger('Sunlight Scale Mult', itU32),\n        wbInteger('Sunlight Scale Add', itU32),\n        wbInteger('Sky Scale Mult', itU32),\n        wbInteger('Sky Scale Add', itU32)\n      ]),\n      wbInteger('Unknown08 Mult', itU32),\n      wbInteger('Unknown48 Add', itU32),\n      wbInteger('Unknown09 Mult', itU32),\n      wbInteger('Unknown49 Add', itU32),\n      wbInteger('Unknown0A Mult', itU32),\n      wbInteger('Unknown4A Add', itU32),\n      wbInteger('Unknown0B Mult', itU32),\n      wbInteger('Unknown4B Add', itU32),\n      wbInteger('Unknown0C Mult', itU32),\n      wbInteger('Unknown4C Add', itU32),\n      wbInteger('Unknown0D Mult', itU32),\n      wbInteger('Unknown4D Add', itU32),\n      wbInteger('Unknown0E Mult', itU32),\n      wbInteger('Unknown4E Add', itU32),\n      wbInteger('Unknown0F Mult', itU32),\n      wbInteger('Unknown4F Add', itU32),\n      wbInteger('Unknown10 Mult', itU32),\n      wbInteger('Unknown50 Add', itU32),\n      wbStruct('Cinematic', [\n        wbInteger('Saturation Mult', itU32),\n        wbInteger('Saturation Add', itU32),\n        wbInteger('Brightness Mult', itU32),\n        wbInteger('Brightness Add', itU32),\n        wbInteger('Contrast Mult', itU32),\n        wbInteger('Contrast Add', itU32)\n      ]),\n      wbInteger('Unknown14 Mult', itU32),\n      wbInteger('Unknown54 Add', itU32),\n      wbInteger('Tint Color', itU32),\n      wbInteger('Blur Radius', itU32),\n      wbInteger('Double Vision Strength', itU32),\n      wbInteger('Radial Blur Strength', itU32),\n      wbInteger('Radial Blur Ramp Up', itU32),\n      wbInteger('Radial Blur Start', itU32),\n      wbInteger('Radial Blur Flags', itU32, wbFlags(['Use Target'])),\n      wbFloat('Radial Blur Center X'),\n      wbFloat('Radial Blur Center Y'),\n      wbInteger('DoF Strength', itU32),\n      wbInteger('DoF Distance', itU32),\n      wbInteger('DoF Range', itU32),\n      wbInteger('DoF Flags', itU32, wbFlags([\n        {0x00000001} 'Use Target',\n        {0x00000002} 'Unknown 2',\n        {0x00000004} 'Unknown 3',\n        {0x00000008} 'Unknown 4',\n        {0x00000010} 'Unknown 5',\n        {0x00000020} 'Unknown 6',\n        {0x00000040} 'Unknown 7',\n        {0x00000080} 'Unknown 8',\n        {0x00000100} 'Mode - Front',\n        {0x00000200} 'Mode - Back',\n        {0x00000400} 'No Sky',\n        {0x00000800} 'Blur Radius Bit 2',\n        {0x00001000} 'Blur Radius Bit 1',\n        {0x00002000} 'Blur Radius Bit 0'\n      ])),\n      wbInteger('Radial Blur Ramp Down', itU32),\n      wbInteger('Radial Blur Down Start', itU32),\n      wbInteger('Fade Color', itU32),\n      wbInteger('Motion Blur Strength', itU32)\n    ]),\n    wbArray(BNAM, 'Blur Radius', wbTimeInterpolator),\n    wbArray(VNAM, 'Double Vision Strength', wbTimeInterpolator),\n    wbArray(TNAM, 'Tint Color', wbColorInterpolator),\n    wbArray(NAM3, 'Fade Color', wbColorInterpolator),\n    wbArray(RNAM, 'Radial Blur Strength', wbTimeInterpolator),\n    wbArray(SNAM, 'Radial Blur Ramp Up', wbTimeInterpolator),\n    wbArray(UNAM, 'Radial Blur Start', wbTimeInterpolator),\n    wbArray(NAM1, 'Radial Blur Ramp Down', wbTimeInterpolator),\n    wbArray(NAM2, 'Radial Blur Down Start', wbTimeInterpolator),\n    wbArray(WNAM, 'DoF Strength', wbTimeInterpolator),\n    wbArray(XNAM, 'DoF Distance', wbTimeInterpolator),\n    wbArray(YNAM, 'DoF Range', wbTimeInterpolator),\n    wbArray(NAM4, 'Motion Blur Strength', wbTimeInterpolator),\n    wbRStruct('HDR', [\n      wbArray(_00_IAD, 'Eye Adapt Speed Mult', wbTimeInterpolator),\n      wbArray(_40_IAD, 'Eye Adapt Speed Add', wbTimeInterpolator),\n      wbArray(_01_IAD, 'Bloom Blur Radius Mult', wbTimeInterpolator),\n      wbArray(_41_IAD, 'Bloom Blur Radius Add', wbTimeInterpolator),\n      wbArray(_02_IAD, 'Bloom Threshold Mult', wbTimeInterpolator),\n      wbArray(_42_IAD, 'Bloom Threshold Add', wbTimeInterpolator),\n      wbArray(_03_IAD, 'Bloom Scale Mult', wbTimeInterpolator),\n      wbArray(_43_IAD, 'Bloom Scale Add', wbTimeInterpolator),\n      wbArray(_04_IAD, 'Target Lum Min Mult', wbTimeInterpolator),\n      wbArray(_44_IAD, 'Target Lum Min Add', wbTimeInterpolator),\n      wbArray(_05_IAD, 'Target Lum Max Mult', wbTimeInterpolator),\n      wbArray(_45_IAD, 'Target Lum Max Add', wbTimeInterpolator),\n      wbArray(_06_IAD, 'Sunlight Scale Mult', wbTimeInterpolator),\n      wbArray(_46_IAD, 'Sunlight Scale Add', wbTimeInterpolator),\n      wbArray(_07_IAD, 'Sky Scale Mult', wbTimeInterpolator),\n      wbArray(_47_IAD, 'Sky Scale Add', wbTimeInterpolator)\n    ], []),\n    wbUnknown(_08_IAD),\n    wbUnknown(_48_IAD),\n    wbUnknown(_09_IAD),\n    wbUnknown(_49_IAD),\n    wbUnknown(_0A_IAD),\n    wbUnknown(_4A_IAD),\n    wbUnknown(_0B_IAD),\n    wbUnknown(_4B_IAD),\n    wbUnknown(_0C_IAD),\n    wbUnknown(_4C_IAD),\n    wbUnknown(_0D_IAD),\n    wbUnknown(_4D_IAD),\n    wbUnknown(_0E_IAD),\n    wbUnknown(_4E_IAD),\n    wbUnknown(_0F_IAD),\n    wbUnknown(_4F_IAD),\n    wbUnknown(_10_IAD),\n    wbUnknown(_50_IAD),\n    wbRStruct('Cinematic', [\n      wbArray(_11_IAD, 'Saturation Mult', wbTimeInterpolator),\n      wbArray(_51_IAD, 'Saturation Add', wbTimeInterpolator),\n      wbArray(_12_IAD, 'Brightness Mult', wbTimeInterpolator),\n      wbArray(_52_IAD, 'Brightness Add', wbTimeInterpolator),\n      wbArray(_13_IAD, 'Contrast Mult', wbTimeInterpolator),\n      wbArray(_53_IAD, 'Contrast Add', wbTimeInterpolator)\n    ], []),\n    wbUnknown(_14_IAD),\n    wbUnknown(_54_IAD)\n  ]);\n\n  wbRecord(FLST, 'FormID List', [\n    wbString(EDID, 'Editor ID', 0, cpBenign, True, nil, wbFLSTEDIDAfterSet),\n    wbRArrayS('FormIDs', wbFormID(LNAM, 'FormID'), cpNormal, False, nil, nil, nil, wbFLSTLNAMIsSorted)\n  ]);\n\n  wbRecord(PERK, 'Perk',\n    wbFlags(wbRecordFlagsFlags, wbFlagsList([\n      {0x00000004}  2, 'Non-Playable'\n    ])), [\n    wbEDID,\n    wbVMADFragmentedPERK,\n    wbFULL,\n    wbDESCReq,\n    wbICON,\n    wbCTDAs,\n    wbStruct(DATA, 'Data', [\n      wbInteger('Trait', itU8, wbEnum(['False', 'True'])),\n      wbInteger('Level', itU8),\n      wbInteger('Num Ranks', itU8),\n      wbInteger('Playable', itU8, wbEnum(['False', 'True'])),\n      wbInteger('Hidden', itU8, wbEnum(['False', 'True']))\n    ], cpNormal, True),\n    wbFormIDCK(NNAM, 'Next Perk', [PERK, NULL]),\n\n    wbRStructsSK('Effects', 'Effect', [0, 1], [\n      wbStructSK(PRKE, [1, 2, 0], 'Header', [\n        wbInteger('Type', itU8, wbEnum([\n          'Quest + Stage',\n          'Ability',\n          'Entry Point'\n        ]), cpNormal, False, nil, wbPERKPRKETypeAfterSet),\n        wbInteger('Rank', itU8),\n        wbInteger('Priority', itU8)\n      ]),\n      wbUnion(DATA, 'Effect Data', wbPerkDATADecider, [\n        wbStructSK([0, 1], 'Quest + Stage', [\n          wbFormIDCk('Quest', [QUST]),\n          wbInteger('Quest Stage', itU8, wbPerkDATAQuestStageToStr, wbCTDAParam2QuestStageToInt),\n          wbByteArray('Unused', 3)\n        ]),\n        wbFormIDCk('Ability', [SPEL]),\n        wbStructSK([0, 1], 'Entry Point', [\n          wbInteger('Entry Point', itU8, wbEntryPointsEnum, cpNormal, True, nil{, wbPERKEntryPointAfterSet}),\n          wbInteger('Function', itU8, wbEnum([\n            {0} 'Unknown 0',\n            {1} 'Set Value', // EPFT=1\n            {2} 'Add Value', // EPFT=1\n            {3} 'Multiply Value', // EPFT=1\n            {4} 'Add Range To Value', // EPFT=2\n            {5} 'Add Actor Value Mult', // EPFT=2\n            {6} 'Absolute Value', // no params\n            {7} 'Negative Absolute Value', // no params\n            {8} 'Add Leveled List', // EPFT=3\n            {9} 'Add Activate Choice', // EPFT=4\n           {10} 'Select Spell', // EPFT=5\n           {11} 'Select Text', // EPFT=6\n           {12} 'Set to Actor Value Mult', // EPFT=2\n           {13} 'Multiply Actor Value Mult', // EPFT=2\n           {14} 'Multiply 1 + Actor Value Mult', // EPFT=2\n           {15} 'Set Text' // EPFT=7\n          ])),\n          wbInteger('Perk Condition Tab Count', itU8, nil, cpIgnore)\n        ])\n      ], cpNormal, True),\n\n      wbRStructsSK('Perk Conditions', 'Perk Condition', [0], [\n        wbInteger(PRKC, 'Run On (Tab Index)', itS8{, wbPRKCToStr, wbPRKCToInt}),\n        wbCTDAsReq\n      ], [], cpNormal, False{, nil, nil, wbPERKPRKCDontShow}),\n\n      wbRStruct('Function Parameters', [\n        wbInteger(EPFT, 'Type', itU8, wbEnum([\n          {0} 'None',\n          {1} 'Float',\n          {2} 'Float/AV,Float',\n          {3} 'LVLI',\n          {4} 'SPEL,lstring,flags',\n          {5} 'SPEL',\n          {6} 'string',\n          {7} 'lstring'\n        ])),\n        // case(EPFT) of\n        // 1: EPFD=float\n        // 2: EPFD=float,float\n        // 3: EPFD=LVLI\n        // 4: EPFD=SPEL, EPF2=lstring, EPF3=int32 flags\n        // 5: EPFD=SPEL\n        // 6: EPFD=string\n        // 7: EPFD=lstring\n        wbLString(EPF2, 'Button Label', 0, cpTranslate),\n        wbStruct(EPF3, 'Script Flags', [\n          wbInteger('Script Flags', itU8, wbFlags([\n            'Run Immediately',\n            'Replace Default'\n          ])),\n          wbByteArray('Unknown', 3)\n        ]),\n        wbUnion(EPFD, 'Data', wbEPFDDecider, [\n          {0} wbByteArray('Unknown'),\n          {1} wbFloat('Float'),\n          {2} wbStruct('Float, Float', [\n                wbFloat('Float 1'),\n                wbFloat('Float 2')\n              ]),\n          {3} wbFormIDCk('Leveled Item', [LVLI]),\n          {4} wbFormIDCk('Spell', [SPEL]),\n          {5} wbFormIDCk('Spell', [SPEL]),\n          {6} wbString('Text', 0, cpTranslate),\n          {7} wbLString('Text', 0, cpTranslate),\n          {8} wbStruct('Actor Value, Float', [\n                wbInteger('Actor Value', itU32, wbEPFDActorValueToStr, wbEPFDActorValueToInt),\n                wbFloat('Float')\n              ])\n        ], cpNormal, False{, wbEPFDDontShow})\n      ], [], cpNormal, False{, wbPERKPRKCDontShow}),\n      wbEmpty(PRKF, 'End Marker', cpIgnore, True)\n    ], [])\n  ]);\n\n  wbRecord(BPTD, 'Body Part Data', [\n    wbEDID,\n    wbMODL,\n    wbRStructsSK('Body Parts', 'Body Part', [2], [\n      wbLString(BPTN, 'Part Name', 0, cpTranslate, True),\n      wbString(PNAM, 'Pose Matching', 0, cpNormal, False),\n      wbString(BPNN, 'Part Node', 0, cpNormal, True),\n      wbString(BPNT, 'VATS Target', 0, cpNormal, True),\n      wbString(BPNI, 'IK Data - Start Node', 0, cpNormal, True),\n      wbStruct(BPND, '', [\n        {00} wbFloat('Damage Mult'),\n        {04} wbInteger('Flags', itU8, wbFlags([\n          'Severable',\n          'IK Data',\n          'IK Data - Biped Data',\n          'Explodable',\n          'IK Data - Is Head',\n          'IK Data - Headtracking',\n          'To Hit Chance - Absolute'\n        ])),\n        {05} wbInteger('Part Type', itU8, wbEnum([\n               'Torso',\n               'Head',\n               'Eye',\n               'LookAt',\n               'Fly Grab',\n               'Saddle'\n             ])),\n        {06} wbInteger('Health Percent', itU8),\n        {07} wbInteger('Actor Value', itS8, wbActorValueEnum),\n        {08} wbInteger('To Hit Chance', itU8),\n        {09} wbInteger('Explodable - Explosion Chance %', itU8),\n        {10} wbInteger('Explodable - Debris Count', itU16),\n        {12} wbFormIDCk('Explodable - Debris', [DEBR, NULL]),\n        {16} wbFormIDCk('Explodable - Explosion', [EXPL, NULL]),\n        {20} wbFloat('Tracking Max Angle'),\n        {24} wbFloat('Explodable - Debris Scale'),\n        {28} wbInteger('Severable - Debris Count', itS32),\n        {32} wbFormIDCk('Severable - Debris', [DEBR, NULL]),\n        {36} wbFormIDCk('Severable - Explosion', [EXPL, NULL]),\n        {40} wbFloat('Severable - Debris Scale'),\n        wbStruct('Gore Effects Positioning', [\n          wbStruct('Translate', [\n            {44} wbFloat('X'),\n            {48} wbFloat('Y'),\n            {52} wbFloat('Z')\n          ]),\n          wbStruct('Rotation', [\n            {56} wbFloat('X', cpNormal, True, wbRotationFactor, wbRotationScale, nil, RadiansNormalize),\n            {60} wbFloat('Y', cpNormal, True, wbRotationFactor, wbRotationScale, nil, RadiansNormalize),\n            {64} wbFloat('Z', cpNormal, True, wbRotationFactor, wbRotationScale, nil, RadiansNormalize)\n          ])\n        ]),\n        {68} wbFormIDCk('Severable - Impact DataSet', [IPDS, NULL]),\n        {72} wbFormIDCk('Explodable - Impact DataSet', [IPDS, NULL]),\n        {28} wbInteger('Severable - Decal Count', itU8),\n        {28} wbInteger('Explodable - Decal Count', itU8),\n        {76} wbByteArray('Unknown', 2),\n        {80} wbFloat('Limb Replacement Scale')\n      ], cpNormal, True),\n      wbString(NAM1, 'Limb Replacement Model', 0, cpNormal, True),\n      wbString(NAM4, 'Gore Effects - Target Bone', 0, cpNormal, True),\n      wbByteArray(NAM5, 'Texture Files Hashes', 0, cpNormal)\n    ], [], cpNormal, True)\n  ]);\n\n  wbRecord(ADDN, 'Addon Node', [\n    wbEDID,\n    wbOBNDReq,\n    wbMODL,\n    wbInteger(DATA, 'Node Index', itS32, nil, cpNormal, True),\n    wbFormIDCk(SNAM, 'Sound', [SNDR, NULL]),\n    wbStruct(DNAM, 'Data', [\n      wbInteger('Master Particle System Cap', itU16),\n      wbInteger('Flags', itU16, wbEnum([], [\n        {>>> Value Must be 1 or 3 <<<}\n        1, 'Unknown 1',    // {0x0001}'Unknown 0', : The Check-Box is Unchecked in the CK\n        3, 'Always Loaded' // {0x0002}'Always Loaded' : The Check-Box is Unchecked in the CK\n      ]))\n    ], cpNormal, True)\n  ]);\nend;\n\nprocedure DefineTES5h;\nbegin\n  wbRecord(AVIF, 'Actor Value Information', [\n    wbEDID,\n    wbFULL,\n    wbDESCReq,\n    wbString(ANAM, 'Abbreviation'),\n    wbUnknown(CNAM),\n    wbStruct(AVSK, 'Skill', [\n      wbFloat('Skill Use Mult'),\n      wbFloat('Skill Offset Mult'),\n      wbFloat('Skill Improve Mult'),\n      wbFloat('Skill Improve Offset')\n    ]),\n    wbRArray('Perk Tree',\n      wbRStruct('Node', [\n        wbFormIDCk(PNAM, 'Perk', [PERK, NULL]),\n        wbUnknown(FNAM),\n        wbInteger(XNAM, 'Perk-Grid X', itU32),\n        wbInteger(YNAM, 'Perk-Grid Y', itU32),\n        wbFloat(HNAM, 'Horizontal Position'),\n        wbFloat(VNAM, 'Vertical Position'),\n        wbFormIDCk(SNAM, 'Associated Skill', [AVIF, NULL]),\n        wbRArray('Connections', wbInteger(CNAM, 'Line to Index', itU32)),\n        wbInteger(INAM, 'Index', itU32)\n      ], [])\n    )\n  ]);\n\n  wbRecord(CAMS, 'Camera Shot', [\n    wbEDID,\n    wbMODL,\n    wbStruct(DATA, 'Data', [\n      {00} wbInteger('Action', itU32, wbEnum([\n        'Shoot',\n        'Fly',\n        'Hit',\n        'Zoom'\n      ])),\n      {04} wbInteger('Location', itU32, wbEnum([\n        'Attacker',\n        'Projectile',\n        'Target',\n        'Lead Actor'\n      ])),\n      {08} wbInteger('Target', itU32, wbEnum([\n        'Attacker',\n        'Projectile',\n        'Target',\n        'Lead Actor'\n      ])),\n      {12} wbInteger('Flags', itU32, wbFlags([\n        'Position Follows Location',\n        'Rotation Follows Target',\n        'Don''t Follow Bone',\n        'First Person Camera',\n        'No Tracer',\n        'Start At Time Zero'\n      ])),\n      wbStruct('Time Multipliers', [\n        {16} wbFloat('Player'),\n        {20} wbFloat('Target'),\n        {24} wbFloat('Global')\n      ]),\n      {28} wbFloat('Max Time'),\n      {32} wbFloat('Min Time'),\n      {36} wbFloat('Target % Between Actors'),\n      {40} wbFloat('Near Target Distance')\n    ], cpNormal, True, nil, 8),\n    wbFormIDCk(MNAM, 'Image Space Modifier', [IMAD])\n  ]);\n\n  wbRecord(CPTH, 'Camera Path', [\n    wbEDID,\n    wbCTDAs,\n    wbArray(ANAM, 'Related Camera Paths', wbFormIDCk('Related Camera Path', [CPTH, NULL]), ['Parent', 'Previous Sibling'], cpNormal, True),\n    wbInteger(DATA, 'Camera Zoom', itU8, wbEnum([], [\n      0, 'Default, Must Have Camera Shots',\n      1, 'Disable, Must Have Camera Shots',\n      2, 'Shot List, Must Have Camera Shots',\n      128, 'Default',\n      129, 'Disable',\n      130, 'Shot List'\n    ]), cpNormal, True),\n    wbRArray('Camera Shots', wbFormIDCk(SNAM, 'Camera Shot', [CAMS]))\n  ]);\n\n  wbRecord(VTYP, 'Voice Type', [\n    wbEDID,\n    wbInteger(DNAM, 'Flags', itU8, wbFlags([\n      'Allow Default Dialog',\n      'Female'\n    ]), cpNormal, True)\n  ]);\n\n  wbRecord(MATT, 'Material Type', [\n    wbEDID,\n    wbFormIDCk(PNAM, 'Material Parent', [MATT, NULL]),\n    wbString(MNAM, 'Material Name'),\n    wbStruct(CNAM, 'Havok Display Color', [\n      wbFloat('Red', cpNormal, True, 255, 0),\n      wbFloat('Green', cpNormal, True, 255, 0),\n      wbFloat('Blue', cpNormal, True, 255, 0)\n    ]),\n    wbFloat(BNAM, 'Buoyancy'),\n    wbInteger(FNAM, 'Flags', itU32, wbFlags([\n      'Stair Material',\n      'Arrows Stick'\n    ], False)),\n    wbFormIDCk(HNAM, 'Havok Impact Data Set', [IPDS, NULL])\n  ]);\n\n  wbRecord(IPCT, 'Impact', [\n    wbEDID,\n    wbMODL,\n    wbStruct(DATA, '', [\n      wbFloat('Effect - Duration'),\n      wbInteger('Effect - Orientation', itU32, wbEnum([\n        'Surface Normal',\n        'Projectile Vector',\n        'Projectile Reflection'\n      ])),\n      wbFloat('Angle Threshold'),\n      wbFloat('Placement Radius'),\n      wbInteger('Sound Level', itU32, wbSoundLevelEnum),\n      wbInteger('Flags', itU8, wbFlags([\n        {0x01} 'No Decal Data'\n      ])),\n      wbInteger('Impact Result', itU8, wbEnum([\n         {0} 'Default',\n         {1} 'Destroy',\n         {2} 'Bounce',\n         {3} 'Impale',\n         {4} 'Stick'\n      ])),\n      wbByteArray('Unknown', 2)\n    ], cpNormal, True, nil, 4),\n    wbDODT,\n    wbFormIDCk(DNAM, 'Texture Set', [TXST]),\n    wbFormIDCk(ENAM, 'Secondary Texture Set', [TXST]),\n    wbFormIDCk(SNAM, 'Sound 1', [SNDR, SOUN, NULL]),\n    wbFormIDCk(NAM1, 'Sound 2', [SNDR, SOUN, NULL]),\n    wbFormIDCk(NAM2, 'Hazard', [HAZD, NULL])\n  ]);\n\n  wbRecord(IPDS, 'Impact Data Set', [\n    wbEDID,\n    wbRArrayS('Data', wbStructSK(PNAM, [0], '', [\n      wbFormIDCk('Material', [MATT]),\n      wbFormIDCk('Impact', [IPCT])\n    ]))\n  ]);\n\n  wbRecord(ECZN, 'Encounter Zone', [\n    wbEDID,\n    wbStruct(DATA, '', [\n      wbFormIDCkNoReach('Owner', [NPC_, FACT, NULL]),\n      wbFormIDCk('Location', [LCTN, NULL]),\n      wbInteger('Rank', itS8),\n      wbInteger('Min Level', itS8),\n      wbInteger('Flags', itU8, wbFlags([\n        'Never Resets',\n        'Match PC Below Minimum Level',\n        'Disable Combat Boundary'\n      ])),\n      wbInteger('Max Level', itS8)\n    ], cpNormal, True, nil, 2)\n  ]);\n\n  wbRecord(LCTN, 'Location', [\n    wbEDID,\n\n    wbArray(ACPR, 'Actor Cell Persistent Reference', wbStruct('', [\n      wbFormIDCk('Actor', [PLYR, ACHR, REFR, PGRE, PHZD, PMIS, PARW, PBAR, PBEA, PCON, PFLA], False, cpBenign),\n      wbFormIDCk('Location', [WRLD, CELL], False, cpBenign),\n      wbInteger('Grid Y', itS16, nil, cpBenign),\n      wbInteger('Grid X', itS16, nil, cpBenign)\n    ])),\n    wbArray(LCPR, 'Location Cell Persistent Reference', wbStruct('', [\n      wbFormIDCk('Actor', [PLYR, ACHR, REFR, PGRE, PHZD, PMIS, PARW, PBAR, PBEA, PCON, PFLA], False, cpBenign),\n      wbFormIDCk('Location', [WRLD, CELL], False, cpBenign),\n      wbInteger('Grid Y', itS16, nil, cpBenign),\n      wbInteger('Grid X', itS16, nil, cpBenign)\n    ])),\n    {>>> From Danwguard.esm, Does not follow similar previous patterns <<<}\n    wbArray(RCPR, 'Reference Cell Persistent Reference', wbFormIDCk('Ref', [ACHR, REFR], False, cpBenign)),\n\n    wbArray(ACUN, 'Actor Cell Unique', wbStruct('', [\n      wbFormIDCk('Actor', [NPC_], False, cpBenign),\n      wbFormIDCk('Ref', [ACHR], False, cpBenign),\n      wbFormIDCk('Location', [LCTN, NULL], False, cpBenign)\n    ])),\n    wbArray(LCUN, 'Location Cell Unique', wbStruct('', [\n      wbFormIDCk('Actor', [NPC_], False, cpBenign),\n      wbFormIDCk('Ref', [ACHR], False, cpBenign),\n      wbFormIDCk('Location', [LCTN, NULL], False, cpBenign)\n    ])),\n    {>>> in Unofficial Skyrim patch <<<}\n    wbArray(RCUN, 'Reference Cell Unique', wbFormIDCk('Actor', [NPC_], False, cpBenign)),\n\n    wbArray(ACSR, 'Actor Cell Static Reference', wbStruct('', [\n      wbFormIDCk('Loc Ref Type', [LCRT], False, cpBenign),\n      wbFormIDCk('Marker', [PLYR, ACHR, REFR, PGRE, PHZD, PMIS, PARW, PBAR, PBEA, PCON, PFLA], False, cpBenign),\n      wbFormIDCk('Location', [WRLD, CELL], False, cpBenign),\n      wbInteger('Grid Y', itS16, nil, cpBenign),\n      wbInteger('Grid X', itS16, nil, cpBenign)\n    ])),\n    wbArray(LCSR, 'Location Cell Static Reference', wbStruct('', [\n      wbFormIDCk('Loc Ref Type', [LCRT], False, cpBenign),\n      wbFormIDCk('Marker', [PLYR, ACHR, REFR, PGRE, PHZD, PMIS, PARW, PBAR, PBEA, PCON, PFLA], False, cpBenign),\n      wbFormIDCk('Location', [WRLD, CELL], False, cpBenign),\n      wbInteger('Grid Y', itS16, nil, cpBenign),\n      wbInteger('Grid X', itS16, nil, cpBenign)\n    ])),\n    {>>> Seen in Open Cities <<<}\n    wbArray(RCSR, 'Reference Cell Static Reference', wbFormIDCk('Ref', [ACHR, REFR], False, cpBenign)),\n\n    wbRArray('Actor Cell Encounter Cell',\n      wbStruct(ACEC, 'Unknown', [\n        wbFormIDCk('Location', [WRLD, CELL], False, cpBenign),\n        wbArray('Coordinates', wbStruct('', [\n          wbInteger('Grid Y', itS16, nil, cpBenign),\n          wbInteger('Grid X', itS16, nil, cpBenign)\n        ]))\n      ])\n    ),\n    wbRArray('Location Cell Encounter Cell',\n      wbStruct(LCEC, 'Unknown', [\n        wbFormIDCk('Location', [WRLD, CELL], False, cpBenign),\n        wbArray('Coordinates', wbStruct('', [\n          wbInteger('Grid Y', itS16, nil, cpBenign),\n          wbInteger('Grid X', itS16, nil, cpBenign)\n        ]))\n      ])\n    ),\n    {>>> Seen in Open Cities <<<}\n    wbRArray('Reference Cell Encounter Cell',\n      wbStruct(RCEC, 'Unknown', [\n        wbFormIDCk('Location', [WRLD, CELL], False, cpBenign),\n        wbArray('Coordinates', wbStruct('', [\n          wbInteger('Grid Y', itS16, nil, cpBenign),\n          wbInteger('Grid X', itS16, nil, cpBenign)\n        ]))\n      ])\n    ),\n\n    wbArray(ACID, 'Actor Cell Marker Reference', wbFormIDCk('Ref', [PLYR, ACHR, REFR, PGRE, PHZD, PMIS, PARW, PBAR, PBEA, PCON, PFLA], False, cpBenign)),\n    wbArray(LCID, 'Location Cell Marker Reference', wbFormIDCk('Ref', [PLYR, ACHR, REFR, PGRE, PHZD, PMIS, PARW, PBAR, PBEA, PCON, PFLA], False, cpBenign)),\n\n    wbArray(ACEP, 'Actor Cell Enable Point', wbStruct('', [\n      wbFormIDCk('Actor', [PLYR, ACHR, REFR, PGRE, PHZD, PMIS, PARW, PBAR, PBEA, PCON, PFLA], False, cpBenign),\n      wbFormIDCk('Ref', [PLYR, ACHR, REFR, PGRE, PHZD, PMIS, PARW, PBAR, PBEA, PCON, PFLA], False, cpBenign),\n      wbInteger('Grid Y', itS16, nil, cpBenign),\n      wbInteger('Grid X', itS16, nil, cpBenign)\n    ])),\n    wbArray(LCEP, 'Location Cell Enable Point', wbStruct('', [\n      wbFormIDCk('Actor', [PLYR, ACHR, REFR, PGRE, PHZD, PMIS, PARW, PBAR, PBEA, PCON, PFLA], False, cpBenign),\n      wbFormIDCk('Ref', [PLYR, ACHR, REFR, PGRE, PHZD, PMIS, PARW, PBAR, PBEA, PCON, PFLA], False, cpBenign),\n      wbInteger('Grid Y', itS16, nil, cpBenign),\n      wbInteger('Grid X', itS16, nil, cpBenign)\n    ])),\n\n    wbFULL,\n    wbKSIZ,\n    wbKWDAs,\n    wbFormIDCk(PNAM, 'Parent Location', [LCTN, NULL]),\n    wbFormIDCk(NAM1, 'Music', [MUSC, NULL]),\n    wbFormIDCk(FNAM, 'Unreported Crime Faction', [FACT]),\n    wbFormIDCk(MNAM, 'World Location Marker Ref', [REFR, ACHR]),\n    wbFloat(RNAM, 'World Location Radius'),\n    wbFormIDCk(NAM0, 'Horse Marker Ref', [REFR]),\n    wbCNAM\n  ], False, nil, cpNormal, False, nil, wbKeywordsAfterSet);\n\nend;\n\n{this is required to prevent XE6 compiler error}\ntype\n  TVarRecs = array of TVarRec;\n\nfunction CombineVarRecs(const a, b : array of const)\n                                   : TVarRecs;\nbegin\n  SetLength(Result, Length(a) + Length(b));\n  if Length(a) > 0 then\n    Move(a[0], Result[0], SizeOf(TVarRec) * Length(a));\n  if Length(b) > 0 then\n    Move(b[0], Result[Length(a)], SizeOf(TVarRec) * Length(b));\nend;\n\nfunction MakeVarRecs(const a : array of const)\n                             : TVarRecs;\nbegin\n  SetLength(Result, Length(a));\n  if Length(a) > 0 then\n    Move(a[0], Result[0], SizeOf(TVarRec) * Length(a));\nend;\n\n\nprocedure DefineTES5i;\nvar\n  a, b, c : TVarRecs;\nbegin\n  wbRecord(MESG, 'Message', [\n    wbEDID,\n    wbDESCReq,\n    wbFULL,\n    wbFormIDCk(INAM, 'Icon (unused)', [NULL], False, cpIgnore, True), // leftover\n    wbFormIDCk(QNAM, 'Owner Quest', [QUST]),\n    wbInteger(DNAM, 'Flags', itU32, wbFlags([\n      'Message Box',\n      'Auto Display'\n    ]), cpNormal, True, False, nil, wbMESGDNAMAfterSet),\n    wbInteger(TNAM, 'Display Time', itU32, nil, cpNormal, False, False, wbMESGTNAMDontShow),\n    wbRStructs('Menu Buttons', 'Menu Button', [\n      wbLString(ITXT, 'Button Text', 0, cpTranslate),\n      wbCTDAs\n    ], [])\n  ], False, nil, cpNormal, False, wbMESGAfterLoad);\n\n  a := MakeVarRecs([\n                        0, 'None',\n          Sig2Int('RADA'), 'RADA (Unused)',\n          Sig2Int('MORP'), 'MORP (Unused)',\n          Sig2Int('PPAR'), 'PPAR (Unused)',\n          Sig2Int('MYSN'), 'MYSN (Unused)',\n          Sig2Int('MYSF'), 'MYSF (Unused)',\n          Sig2Int('WWSP'), 'Werewolf Spell',\n          Sig2Int('SALT'), 'Sitting Angle Limit',\n          Sig2Int('APSH'), 'Allow Player Shout',\n          Sig2Int('GOLD'), 'Gold',\n          Sig2Int('LKPK'), 'Lockpick',\n          Sig2Int('SKLK'), 'SkeletonKey',\n          Sig2Int('PFAC'), 'Player Faction',\n          Sig2Int('GFAC'), 'Guard Faction',\n          Sig2Int('DFMS'), 'Default Music',\n          Sig2Int('BTMS'), 'Battle Music',\n          Sig2Int('DTMS'), 'Death Music',\n          Sig2Int('SCMS'), 'Success Music',\n          Sig2Int('LUMS'), 'Level Up Music',\n          Sig2Int('DCMS'), 'Dungeon Cleared Music',\n          Sig2Int('PVMA'), 'Player Voice (Male)',\n          Sig2Int('PVMC'), 'Player Voice (Male Child)',\n          Sig2Int('PVFA'), 'Player Voice (Female)',\n          Sig2Int('PVFC'), 'Player Voice (Female Child)',\n          Sig2Int('EPDF'), 'Eat Package Default Food',\n          Sig2Int('LHEQ'), 'LeftHand Equip',\n          Sig2Int('RHEQ'), 'RightHand Equip',\n          Sig2Int('EHEQ'), 'EitherHand Equip',\n          Sig2Int('VOEQ'), 'Voice Equip',\n          Sig2Int('POEQ'), 'Potion Equip',\n          Sig2Int('EACA'), 'Every Actor Ability',\n          Sig2Int('CACA'), 'Commanded Actor Ability',\n          Sig2Int('DEIS'), 'Drug Wears Off Image Space',\n          Sig2Int('DFTS'), 'Footstep Set',\n          Sig2Int('DLMT'), 'Landscape Material',\n          Sig2Int('DLZM'), 'Dragon Land Zone Marker',\n          Sig2Int('DCZM'), 'Dragon Crash Zone Marker',\n          Sig2Int('CSTY'), 'Combat Style',\n          Sig2Int('PLST'), 'Default Pack List',\n          Sig2Int('PWFD'), 'Wait-For-Dialogue Package',\n          Sig2Int('LRTB'), 'LocRefType Boss',\n          Sig2Int('VLOC'), 'Virtual Location',\n          Sig2Int('PLOC'), 'PersistAll Location',\n          Sig2Int('INVP'), 'Inventory Player',\n          Sig2Int('PTNP'), 'Pathing Test NPC',\n          Sig2Int('FPCS'), 'Favor Cost Small',\n          Sig2Int('FPCM'), 'Favor Cost Medium',\n          Sig2Int('FPCL'), 'Favor Cost Large',\n          Sig2Int('FGPD'), 'Favor Gifts Per Day',\n          Sig2Int('AASW'), 'Action Swim State Change',\n          Sig2Int('AALK'), 'Action Look',\n          Sig2Int('AALA'), 'Action LeftAttack',\n          Sig2Int('AALD'), 'Action LeftReady',\n          Sig2Int('AALR'), 'Action LeftRelease',\n          Sig2Int('AALI'), 'Action LeftInterrupt',\n          Sig2Int('AARA'), 'Action RightAttack',\n          Sig2Int('AARD'), 'Action RightReady',\n          Sig2Int('AARR'), 'Action RightRelease',\n          Sig2Int('AARI'), 'Action RightInterrupt',\n          Sig2Int('AADA'), 'Action DualAttack',\n          Sig2Int('AADL'), 'Action DualRelease',\n          Sig2Int('AAAC'), 'Action Activate',\n          Sig2Int('AAJP'), 'Action Jump',\n          Sig2Int('AAFA'), 'Action Fall',\n          Sig2Int('AALN'), 'Action Land',\n          Sig2Int('AASN'), 'Action Sneak',\n          Sig2Int('AAVC'), 'Action Voice',\n          Sig2Int('AAVD'), 'Action VoiceReady',\n          Sig2Int('AAVR'), 'Action VoiceRelease',\n          Sig2Int('AAVI'), 'Action VoiceInterrupt',\n          Sig2Int('AAID'), 'Action Idle',\n          Sig2Int('AAST'), 'Action Sprint Start',\n          Sig2Int('AASP'), 'Action Sprint Stop',\n          Sig2Int('AADR'), 'Action Draw',\n          Sig2Int('AASH'), 'Action Sheath',\n          Sig2Int('ALPA'), 'Action Left Power Attack',\n          Sig2Int('AAPA'), 'Action Right Power Attack',\n          Sig2Int('ADPA'), 'Action Dual Power Attack',\n          Sig2Int('AAS1'), 'Action Stagger Start',\n          Sig2Int('AABH'), 'Action Block Hit',\n          Sig2Int('AABA'), 'Action Block Anticipate',\n          Sig2Int('AARC'), 'Action Recoil',\n          Sig2Int('AAR2'), 'Action Large Recoil',\n          Sig2Int('AAB1'), 'Action Bleedout Start',\n          Sig2Int('AAB2'), 'Action Bleedout Stop',\n          Sig2Int('AAIS'), 'Action Idle Stop',\n          Sig2Int('AAWH'), 'Action Ward Hit',\n          Sig2Int('AAFQ'), 'Action Force Equip',\n          Sig2Int('AASC'), 'Action Shield Change',\n          Sig2Int('AAPS'), 'Action Path Start',\n          Sig2Int('AAPE'), 'Action Path End',\n          Sig2Int('AALM'), 'Action Large Movement Delta',\n          Sig2Int('AAF1'), 'Action Fly Start',\n          Sig2Int('AAF2'), 'Action Fly Stop',\n          Sig2Int('AAH1'), 'Action Hover Start',\n          Sig2Int('AAH2'), 'Action Hover Stop',\n          Sig2Int('AABI'), 'Action Bumped Into',\n          Sig2Int('AASS'), 'Action Summoned Start',\n          Sig2Int('ATKI'), 'Action Talking Idle',\n          Sig2Int('ALTI'), 'Action Listen Idle',\n          Sig2Int('AADE'), 'Action Death',\n          Sig2Int('AADW'), 'Action Death Wait',\n          Sig2Int('AIDW'), 'Action Idle Warn',\n          Sig2Int('AMST'), 'Action Move Start',\n          Sig2Int('AMSP'), 'Action Move Stop',\n          Sig2Int('ATRI'), 'Action Turn Right',\n          Sig2Int('ATLE'), 'Action Turn Left',\n          Sig2Int('ATSP'), 'Action Turn Stop',\n          Sig2Int('AMFD'), 'Action Move Forward',\n          Sig2Int('AMBK'), 'Action Move Backward',\n          Sig2Int('AMLT'), 'Action Move Left',\n          Sig2Int('AMRT'), 'Action Move Right',\n          Sig2Int('ARAG'), 'Action Reset Animation Graph',\n          Sig2Int('AKDN'), 'Action Knockdown',\n          Sig2Int('AAGU'), 'Action Get Up',\n          Sig2Int('ASID'), 'Action Idle Stop Instant',\n          Sig2Int('ARGI'), 'Action Ragdoll Instant',\n          Sig2Int('AWWS'), 'Action Waterwalk Start',\n          Sig2Int('AREL'), 'Action Reload',\n          Sig2Int('PUSG'), 'Pickup Sound Generic',\n          Sig2Int('PDSG'), 'Putdown Sound Generic',\n          Sig2Int('PUSW'), 'Pickup Sound Weapon',\n          Sig2Int('PDSW'), 'Putdown Sound Weapon',\n          Sig2Int('PUSA'), 'Pickup Sound Armor',\n          Sig2Int('PDSA'), 'Putdown Sound Armor',\n          Sig2Int('PUSB'), 'Pickup Sound Book',\n          Sig2Int('PDSB'), 'Putdown Sound Book',\n          Sig2Int('PUSI'), 'Pickup Sound Ingredient',\n          Sig2Int('PDSI'), 'Putdown Sound Ingredient',\n          Sig2Int('HVSS'), 'Harvest Sound',\n          Sig2Int('HVFS'), 'Harvest Failed Sound',\n          Sig2Int('WBSN'), 'Ward Break Sound',\n          Sig2Int('WASN'), 'Ward Absorb Sound',\n          Sig2Int('WDSN'), 'Ward Deflect Sound',\n          Sig2Int('MFSN'), 'Magic Fail Sound',\n          Sig2Int('SFSN'), 'Shout Fail Sound',\n          Sig2Int('HFSD'), 'Heartbeat Sound Fast',\n          Sig2Int('HSSD'), 'Heartbeat Sound Slow',\n          Sig2Int('IMLH'), 'Imagespace: Low Health',\n          Sig2Int('SCSD'), 'Soul Captured Sound',\n          Sig2Int('NASD'), 'No-Activation Sound',\n          Sig2Int('MMSD'), 'Map Menu Looping Sound',\n          Sig2Int('DDSC'), 'Dialogue Voice Category',\n          Sig2Int('NDSC'), 'Non-Dialogue Voice Category',\n          Sig2Int('SFDC'), 'SFX To Fade In Dialogue Category',\n          Sig2Int('PDMC'), 'Pause During Menu Category (Fade)',\n          Sig2Int('PIMC'), 'Pause During Menu Category (Immediate)',\n          Sig2Int('PDLC'), 'Pause During Loading Menu Category',\n          Sig2Int('MDSC'), 'Music Sound Category',\n          Sig2Int('SMSC'), 'Stats Mute Category',\n          Sig2Int('SSSC'), 'Stats Music',\n          Sig2Int('MTSC'), 'Master Sound Category',\n          Sig2Int('TSSC'), 'Time Sensitive Sound Category',\n          Sig2Int('DOP2'), 'Dialogue Output Model (3D)',\n          Sig2Int('DOP3'), 'Dialogue Output Model (2D)',\n          Sig2Int('POPM'), 'Player''s Output Model (1st Person)',\n          Sig2Int('P3OM'), 'Player''s Output Model (3rd Person)',\n          Sig2Int('IOPM'), 'Interface Output Model',\n          Sig2Int('RVBT'), 'Reverb Type',\n          Sig2Int('UWLS'), 'Underwater Loop Sound',\n          Sig2Int('URVT'), 'Underwater Reverb Type',\n          Sig2Int('HRSK'), 'Keyword - Horse',\n          Sig2Int('UNDK'), 'Keyword - Undead',\n          Sig2Int('NPCK'), 'Keyword - NPC',\n          Sig2Int('KWBR'), 'Keyword - BeastRace',\n          Sig2Int('KWDM'), 'Keyword - DummyObject',\n          Sig2Int('KWGE'), 'Keyword - UseGeometryEmitter',\n          Sig2Int('KWMS'), 'Keyword - MustStop',\n          Sig2Int('KWUA'), 'Keyword - UpdateDuringArchery',\n          Sig2Int('KWOT'), 'Keyword - Skip Outfit Items',\n          Sig2Int('FTHD'), 'Male Face Texture Set: Head',\n          Sig2Int('FTMO'), 'Male Face Texture Set: Mouth',\n          Sig2Int('FTEL'), 'Male Face Texture Set: Eyes',\n          Sig2Int('FTHF'), 'Female Face Texture Set: Head',\n          Sig2Int('FTMF'), 'Female Face Texture Set: Mouth',\n          Sig2Int('FTRF'), 'Female Face Texture Set: Eyes',\n          Sig2Int('IMID'), 'ImageSpaceModifier for inventory menu.',\n          Sig2Int('PTEM'), 'Package template',\n          Sig2Int('MMCL'), 'Main Menu Cell',\n          Sig2Int('DMWL'), 'Default MovementType: Walk',\n          Sig2Int('DMRN'), 'Default MovementType: Run',\n          Sig2Int('DMSW'), 'Default MovementType: Swim',\n          Sig2Int('DMFL'), 'Default MovementType: Fly',\n          Sig2Int('DMSN'), 'Default MovementType: Sneak',\n          Sig2Int('DMSP'), 'Default MovementType: Sprint',\n          Sig2Int('SPFK'), 'Keyword - Special Furniture',\n          Sig2Int('FFFP'), 'Keyword - Furniture Forces 1st Person',\n          Sig2Int('FFTP'), 'Keyword - Furniture Forces 3rd Person',\n          Sig2Int('AFNP'), 'Keyword - Activator Furniture No Player',\n          Sig2Int('TKGS'), 'Telekinesis Grab Sound',\n          Sig2Int('TKTS'), 'Telekinesis Throw Sound',\n          Sig2Int('WMWE'), 'World Map Weather',\n          Sig2Int('HMPC'), 'Help Manual PC',\n          Sig2Int('HMXB'), 'Help Manual XBox',\n          Sig2Int('TKAM'), 'Keyword - Type Ammo',\n          Sig2Int('TKAR'), 'Keyword - Type Armor',\n          Sig2Int('TKBK'), 'Keyword - Type Book',\n          Sig2Int('TKIG'), 'Keyword - Type Ingredient',\n          Sig2Int('TKKY'), 'Keyword - Type Key',\n          Sig2Int('TKMS'), 'Keyword - Type Misc',\n          Sig2Int('TKSG'), 'Keyword - Type SoulGem',\n          Sig2Int('TKWP'), 'Keyword - Type Weapon',\n          Sig2Int('TKPT'), 'Keyword - Type Potion',\n          Sig2Int('BENW'), 'Base Weapon Enchantment',\n          Sig2Int('BENA'), 'Base Armor Enchantment',\n          Sig2Int('BAPO'), 'Base Potion',\n          Sig2Int('BAPS'), 'Base Poison',\n          Sig2Int('DRAK'), 'Keyword - Dragon',\n          Sig2Int('MVBL'), 'Keyword - Movable',\n          Sig2Int('ABSE'), 'Art Object - Absorb Effect',\n          Sig2Int('WEML'), 'Weapon Material List',\n          Sig2Int('ARTL'), 'Armor Material List',\n          Sig2Int('DIEN'), 'Keyword - Disallow Enchanting',\n          Sig2Int('FTML'), 'Favor travel marker location',\n          Sig2Int('LKHO'), 'Keyword - Hold Location',\n          Sig2Int('CWOK'), 'Keyword - Civil War Owner',\n          Sig2Int('CWNE'), 'Keyword - Civil War Neutral',\n          Sig2Int('LRSO'), 'LocRefType - Civil War Soldier',\n          Sig2Int('KWDO'), 'Keyword - ClearableLocation',\n          Sig2Int('LRRD'), 'LocRefType - Resource Destructible',\n          Sig2Int('HCLL'), 'FormList - Hair Color List',\n          Sig2Int('CMPX'), 'Complex Scene Object',\n          Sig2Int('RUSG'), 'Keyword - Reusable SoulGem',\n          Sig2Int('ANML'), 'Keyword - Animal',\n          Sig2Int('DAED'), 'Keyword - Daedra'\n        ]);\n\n  b := MakeVarRecs([\n          Sig2Int('BEEP'), 'Keyword - Robot',\n          Sig2Int('NRNT'), 'Keyword - Nirnroot',\n          Sig2Int('FTGF'), 'Fighters'' Guild Faction',\n          Sig2Int('MGGF'), 'Mages'' Guild Faction',\n          Sig2Int('TVGF'), 'Thieves'' Guild Faction',\n          Sig2Int('DBHF'), 'Dark Brotherhood Faction',\n          Sig2Int('JRLF'), 'Jarl Faction',\n          Sig2Int('AWWW'), 'Bunny Faction',\n          Sig2Int('PIVV'), 'Player Is Vampire Variable',\n          Sig2Int('PIWV'), 'Player Is Werewolf Variable',\n          Sig2Int('NMRD'), 'Road Marker',\n          Sig2Int('SAT1'), 'Keyword: Scale Actor To 1.0',\n          Sig2Int('VAMP'), 'Keyword: Vampire',\n          Sig2Int('FORG'), 'Keyword: Forge',\n          Sig2Int('COOK'), 'Keyword: Cooking Pot',\n          Sig2Int('SMLT'), 'Keyword: Smelter',\n          Sig2Int('TANN'), 'Keyword: Tanning Rack',\n          Sig2Int('HBLK'), 'Help - Basic Lockpicking (PC)',\n          Sig2Int('HBLX'), 'Help - Basic Lockpicking (Console)',\n          Sig2Int('HBFG'), 'Help - Basic Forging',\n          Sig2Int('HBCO'), 'Help - Basic Cooking',\n          Sig2Int('HBML'), 'Help - Basic Smelting',\n          Sig2Int('HBTA'), 'Help - Basic Tanning',\n          Sig2Int('HBOC'), 'Help - Basic Object Creation',\n          Sig2Int('HBEC'), 'Help - Basic Enchanting',\n          Sig2Int('HBSM'), 'Help - Basic Smithing Weapon',\n          Sig2Int('HBSA'), 'Help - Basic Smithing Armor',\n          Sig2Int('HBAL'), 'Help - Basic Alchemy',\n          Sig2Int('HBBR'), 'Help - Barter',\n          Sig2Int('HBLU'), 'Help - Leveling up',\n          Sig2Int('HBSK'), 'Help - Skills Menu',\n          Sig2Int('HBMM'), 'Help - Map Menu',\n          Sig2Int('HBJL'), 'Help - Journal',\n          Sig2Int('HBLH'), 'Help - Low Health',\n          Sig2Int('HBLM'), 'Help - Low Magicka',\n          Sig2Int('HBLS'), 'Help - Low Stamina',\n          Sig2Int('HBHJ'), 'Help - Jail',\n          Sig2Int('HBFT'), 'Help - Teamate Favor',\n          Sig2Int('HBWC'), 'Help - Weapon Charge',\n          Sig2Int('HBFS'), 'Help - Favorites',\n          Sig2Int('KHFL'), 'Kinect Help FormList',\n          Sig2Int('HBFM'), 'Help - Flying Mount',\n          Sig2Int('HBTL'), 'Help - Target Lock',\n          Sig2Int('HBAT'), 'Help - Attack Target',\n          Sig2Int('MHFL'), 'Help - Mods',\n          Sig2Int('LSIS'), 'Imagespace: Load screen',\n          Sig2Int('WMDA'), 'Keyword - Weapon Material Daedric',\n          Sig2Int('WMDR'), 'Keyword - Weapon Material Draugr',\n          Sig2Int('WMDH'), 'Keyword - Weapon Material DraugrHoned',\n          Sig2Int('WMDW'), 'Keyword - Weapon Material Dwarven',\n          Sig2Int('WMEB'), 'Keyword - Weapon Material Ebony',\n          Sig2Int('WMEL'), 'Keyword - Weapon Material Elven',\n          Sig2Int('WMFA'), 'Keyword - Weapon Material Falmer',\n          Sig2Int('WMFH'), 'Keyword - Weapon Material FalmerHoned',\n          Sig2Int('WMGL'), 'Keyword - Weapon Material Glass',\n          Sig2Int('WMIM'), 'Keyword - Weapon Material Imperial',\n          Sig2Int('WMIR'), 'Keyword - Weapon Material Iron',\n          Sig2Int('WMOR'), 'Keyword - Weapon Material Orcish',\n          Sig2Int('WMST'), 'Keyword - Weapon Material Steel',\n          Sig2Int('WMWO'), 'Keyword - Weapon Material Wood',\n          Sig2Int('WTBA'), 'Keyword - WeaponTypeBoundArrow',\n          Sig2Int('AODA'), 'Keyword - Armor Material Daedric',\n          Sig2Int('AODP'), 'Keyword - Armor Material Dragonplate',\n          Sig2Int('AODS'), 'Keyword - Armor Material Dragonscale',\n          Sig2Int('AODB'), 'Keyword - Armor Material Dragonbone',\n          Sig2Int('AODW'), 'Keyword - Armor Material Dwarven',\n          Sig2Int('AOEB'), 'Keyword - Armor Material Ebony',\n          Sig2Int('AOEL'), 'Keyword - Armor Material Elven',\n          Sig2Int('AOES'), 'Keyword - Armor Material ElvenSplinted',\n          Sig2Int('AOFL'), 'Keyword - Armor Material FullLeather',\n          Sig2Int('AOGL'), 'Keyword - Armor Material Glass',\n          Sig2Int('AOHI'), 'Keyword - Armor Material Hide',\n          Sig2Int('AOIM'), 'Keyword - Armor Material Imperial',\n          Sig2Int('AOIH'), 'Keyword - Armor Material ImperialHeavy',\n          Sig2Int('AOIR'), 'Keyword - Armor Material ImperialReinforced',\n          Sig2Int('AOFE'), 'Keyword - Armor Material Iron',\n          Sig2Int('AOIB'), 'Keyword - Armor Material IronBanded',\n          Sig2Int('AOOR'), 'Keyword - Armor Material Orcish',\n          Sig2Int('AOSC'), 'Keyword - Armor Material Scaled',\n          Sig2Int('AOST'), 'Keyword - Armor Material Steel',\n          Sig2Int('AOSP'), 'Keyword - Armor Material SteelPlate',\n          Sig2Int('AOSK'), 'Keyword - Armor Material Stormcloak',\n          Sig2Int('AOSD'), 'Keyword - Armor Material Studded',\n          Sig2Int('GCK1'), 'Keyword - Generic Craftable Keyword 01',\n          Sig2Int('GCK2'), 'Keyword - Generic Craftable Keyword 02',\n          Sig2Int('GCK3'), 'Keyword - Generic Craftable Keyword 03',\n          Sig2Int('GCK4'), 'Keyword - Generic Craftable Keyword 04',\n          Sig2Int('GCK5'), 'Keyword - Generic Craftable Keyword 05',\n          Sig2Int('GCK6'), 'Keyword - Generic Craftable Keyword 06',\n          Sig2Int('GCK7'), 'Keyword - Generic Craftable Keyword 07',\n          Sig2Int('GCK8'), 'Keyword - Generic Craftable Keyword 08',\n          Sig2Int('GCK9'), 'Keyword - Generic Craftable Keyword 09',\n          Sig2Int('GCKX'), 'Keyword - Generic Craftable Keyword 10',\n          Sig2Int('JWLR'), 'Keyword - Jewelry',\n          Sig2Int('KWCU'), 'Keyword - Cuirass',\n          Sig2Int('MNTK'), 'Keyword - Mount',\n          Sig2Int('LMHP'), 'Local Map Hide Plane',\n          Sig2Int('SLDM'), 'Snow LOD Material',\n          Sig2Int('SLHD'), 'Snow LOD Material (HD)',\n          Sig2Int('ALDM'), 'Ash LOD Material',\n          Sig2Int('ALHD'), 'Ash LOD Material (HD)',\n          Sig2Int('DGFL'), 'DialogueFollower Quest',\n          Sig2Int('PTFR'), 'PotentialFollower Faction',\n          Sig2Int('AVWP'), 'Werewolf Available Perks',\n          Sig2Int('AVVP'), 'Vampire Available Perks',\n          Sig2Int('RIWR'), 'Werewolf Race',\n          Sig2Int('RIVR'), 'Vampire Race',\n          Sig2Int('RIVS'), 'Vampire Spells',\n          Sig2Int('DMXL'), 'Dragon Mount No Land List',\n          Sig2Int('PCMD'), 'Player Can Mount Dragon Here List',\n          Sig2Int('FMYS'), 'Flying Mount - Allowed Spells',\n          Sig2Int('FMNS'), 'Flying Mount - Disallowed Spells',\n          Sig2Int('MNT2'), 'Keyword - Mount',\n          Sig2Int('AIVC'), 'Verlet Cape',\n          Sig2Int('FTNP'), 'Furniture Test NPC',\n          Sig2Int('COEX'), 'Keyword - Conditional Explosion',\n          Sig2Int('VFNC'), 'Vampire Feed No Crime Faction',\n          Sig2Int('KWSP'), 'Skyrim - Worldspace',\n          Sig2Int('ALBM'), 'Keyword - Armor Material Light Bonemold',\n          Sig2Int('ALCH'), 'Keyword - Armor Material Light Chitin',\n          Sig2Int('ALNC'), 'Keyword - Armor Material Light Nordic',\n          Sig2Int('ALSM'), 'Keyword - Armor Material Light Stalhrim',\n          Sig2Int('FMFF'), 'Flying Mount - Fly Fast Worldspaces',\n          Sig2Int('AHBM'), 'Keyword - Armor Material Heavy Bonemold',\n          Sig2Int('AHCH'), 'Keyword - Armor Material Heavy Chitin',\n          Sig2Int('AHNC'), 'Keyword - Armor Material Heavy Nordic',\n          Sig2Int('AHSM'), 'Keyword - Armor Material Heavy Stalhrim',\n          Sig2Int('WPNC'), 'Keyword - Weapon Material Nordic',\n          Sig2Int('WPSM'), 'Keyword - Weapon Material Stalhrim'\n        ]);\n\n  c := CombineVarRecs(a, b);\n\n  wbRecord(DOBJ, 'Default Object Manager', [\n    wbEDID,\n    wbArrayS(DNAM, 'Objects',\n      wbStructSK([0], 'Object', [\n        wbInteger('Use', itU32, wbEnum([], c), cpNormalIgnoreEmpty),\n        wbFormID('Object ID', cpNormalIgnoreEmpty)\n      ]), 0, cpNormalIgnoreEmpty, True, wbDOBJObjectsAfterLoad\n    )\n  ]);\n\n  wbRecord(LGTM, 'Lighting Template', [\n    wbEDID,\n    wbStruct(DATA, 'Lighting', [\n      wbByteColors('Ambient Color'),\n      wbByteColors('Directional Color'),\n      wbByteColors('Fog Color Near'),\n      wbFloat('Fog Near'),\n      wbFloat('Fog Far'),\n      wbInteger('Directional Rotation XY', itS32),\n      wbInteger('Directional Rotation Z', itS32),\n      wbFloat('Directional Fade'),\n      wbFloat('Fog Clip Dist'),\n      wbFloat('Fog Power'),\n      wbAmbientColors('Ambient Colors'), // WindhelmLightingTemplate [LGTM:0007BA87] only find 24 !\n      wbByteColors('Fog Color Far'),\n      wbFloat('Fog Max'),\n      wbStruct('Light Fade Distances', [\n        wbFloat('Start'),\n        wbFloat('End')\n      ]),\n      wbByteArray('Unknown', 4)\n    ], cpNormal, True, nil, 11),\n    wbAmbientColors(DALC)\n  ]);\n\n  wbRecord(MUSC, 'Music Type', [\n    wbEDID,\n    wbInteger(FNAM, 'Flags', itU32, wbFlags([\n      {0x01} 'Plays One Selection',\n      {0x02} 'Abrupt Transition',\n      {0x04} 'Cycle Tracks',\n      {0x08} 'Maintain Track Order',\n      {0x10} 'Unknown 4',\n      {0x20} 'Ducks Current Track',\n      {0x40} IsSSE('Doesn''t Queue', 'Unknown 6')\n    ]), cpNormal, True),\n    wbStruct(PNAM, 'Data', [\n      wbInteger('Priority', itU16),\n      wbInteger('Ducking (dB)', itU16, wbDiv(100))\n    ]),\n    wbFloat(WNAM, 'Fade Duration'),\n    wbArray(TNAM, 'Music Tracks', wbFormIDCk('Track', [MUST, NULL]))\n  ]);\n\n  wbRecord(FSTP, 'Footstep', [\n    wbEDID,\n    wbFormIDCk(DATA, 'Impact Data Set', [IPDS, NULL], False, cpNormal, True),\n    wbString(ANAM, 'Tag', 0, cpNormal, True)\n  ]);\n\n  wbRecord(FSTS, 'Footstep Set', [\n    wbEDID,\n    wbStruct(XCNT, 'Count', [\n      wbInteger('Walk Forward Sets', itU32),\n      wbInteger('Run Forward Sets', itU32),\n      wbInteger('Walk Forward Alternate Sets', itU32),\n      wbInteger('Run Forward Alternate Sets', itU32),\n      wbInteger('Walk Forward Alternate 2 Sets', itU32)\n    ], cpNormal, True),\n    wbArray(DATA, 'Footstep Sets', wbFormIDCk('Footstep', [FSTP]), 0, nil, nil, cpNormal, True)\n  ]);\n\n  wbSMNodeFlags := wbFlags([\n    'Random',\n    'Warn if no child quest started'\n  ]);\n\n  wbRecord(SMBN, 'Story Manager Branch Node', [\n    wbEDID,\n    wbFormIDCk(PNAM, 'Parent ', [SMQN, SMBN, SMEN, NULL]),\n    wbFormIDCk(SNAM, 'Child ', [SMQN, SMBN, SMEN, NULL]),\n    wbCITC,\n    wbCTDAsCount,\n    wbInteger(DNAM, 'Flags', itU32, wbSMNodeFlags),\n    wbUnknown(XNAM)\n  ], False, nil, cpNormal, False, nil, wbConditionsAfterSet);\n\n  wbRecord(SMQN, 'Story Manager Quest Node', [\n    wbEDID,\n    wbFormIDCk(PNAM, 'Parent ', [SMQN, SMBN, SMEN, NULL]),\n    wbFormIDCk(SNAM, 'Child ', [SMQN, SMBN, SMEN, NULL]),\n    wbCITC,\n    wbCTDAsCount,\n    wbStruct(DNAM, 'Flags', [\n      wbInteger('Node Flags', itU16, wbSMNodeFlags),\n      wbInteger('Quest Flags', itU16, wbFlags([\n        'Do all before repeating',\n        'Shares event',\n        'Num quests to run'\n      ]))\n    ]),\n    wbInteger(XNAM, 'Max concurrent quests', itU32),\n    wbInteger(MNAM, 'Num quests to run', itU32),\n    wbInteger(QNAM, 'Quest Count', itU32, nil, cpBenign),\n    wbRArray('Quests', wbRStructSK([0], 'Quest', [\n      wbFormIDCk(NNAM, 'Quest', [QUST]),\n      wbUnknown(FNAM),\n      wbFloat(RNAM, 'Hours until reset', cpNormal, False, 1/24)\n    ], []), cpNormal, False, nil, wbSMQNQuestsAfterSet)\n  ], False, nil, cpNormal, False, nil, wbConditionsAfterSet);\n\n  wbRecord(SMEN, 'Story Manager Event Node', [\n    wbEDID,\n    wbFormIDCk(PNAM, 'Parent ', [SMQN, SMBN, SMEN, NULL]),\n    wbFormIDCk(SNAM, 'Child ', [SMQN, SMBN, SMEN, NULL]),\n    wbCITC,\n    wbCTDAsCount,\n    wbInteger(DNAM, 'Flags', itU32, wbSMNodeFlags),\n    wbUnknown(XNAM),\n    wbString(ENAM, 'Type', 4)\n  ], False, nil, cpNormal, False, nil, wbConditionsAfterSet);\nend;\n\nprocedure DefineTES5j;\nbegin\n  wbRecord(DLBR, 'Dialog Branch', [\n    wbEDID,\n    wbFormIDCk(QNAM, 'Quest', [QUST], False, cpNormal, True),\n    wbInteger(TNAM, 'Unknown', itU32),\n    wbInteger(DNAM, 'Flags', itU32, wbFlags([\n      {0x01} 'Top-Level',\n      {0x02} 'Blocking',\n      {0x04} 'Exclusive'\n    ])),\n    wbFormIDCk(SNAM, 'Starting Topic', [DIAL], False, cpNormal, True)\n  ]);\n\n  wbRecord(MUST, 'Music Track', [\n    wbEDID,\n    wbInteger(CNAM, 'Track Type', itU32, wbEnum([], [\n      Int64($23F678C3), 'Palette',\n      Int64($6ED7E048), 'Single Track',\n      Int64($A1A9C4D5), 'Silent Track'\n    ]), cpNormal, True),\n    wbFloat(FLTV, 'Duration'),\n    wbFloat(DNAM, 'Fade-Out'),\n    wbString(ANAM, 'Track Filename'),\n    wbString(BNAM, 'Finale Filename'),\n    wbArray(FNAM, 'Cue Points', wbFloat('Point')),\n    wbStruct(LNAM, 'Loop Data', [\n      wbFloat('Loop Begins'),\n      wbFloat('Loop Ends'),\n      wbInteger('Loop Count', itU32)\n    ]),\n    wbCITC,\n    wbCTDAsCount,\n    wbArray(SNAM, 'Tracks', wbFormIDCk('Track', [MUST, NULL]))\n  ], False, nil, cpNormal, False, nil, wbConditionsAfterSet);\n\n  wbRecord(DLVW, 'Dialog View', [\n    wbEDID,\n    wbFormIDCk(QNAM, 'Quest', [QUST], False, cpNormal, True),\n    wbRArray('Branches', wbFormIDCk(BNAM, 'Branch', [DLBR])),\n    wbRArray('Unknown TNAM', wbRStruct('Unknown', [\n      wbUnknown(TNAM)\n    ], [])),\n    wbUnknown(ENAM),\n    wbUnknown(DNAM)\n  ]);\n\n  wbRecord(WOOP, 'Word of Power', [\n    wbEDID,\n    wbFULL,\n    wbLString(TNAM, 'Translation', 0, cpTranslate, True)\n  ]);\n\n  wbRecord(SHOU, 'Shout',\n    wbFlags(wbRecordFlagsFlags, wbFlagsList([\n      {0x00000080}  7, 'Treat spells as powers'\n    ])), [\n    wbEDID,\n    wbFULL,\n    wbMDOB,\n    wbDESC,\n    {>>> Don't sort <<<}\n    wbRArray('Words of Power',\n      wbStruct(SNAM, '', [\n        wbFormIDCk('Word', [WOOP, NULL]),\n        wbFormIDCk('Spell', [SPEL, NULL]),\n        wbFloat('Recovery Time')\n      ])\n    )\n  ]);\n\n  wbRecord(EQUP, 'Equip Type', [\n    wbEDID,\n    wbArray(PNAM, 'Slot Parents', wbFormID('Can Be Equipped'), 0, nil, nil, cpNormal, False),\n    wbInteger(DATA, 'Use All Parents', itU32, wbEnum(['False', 'True']))\n  ]);\n\n  wbRecord(RELA, 'Relationship',\n    wbFlags(wbRecordFlagsFlags, wbFlagsList([\n      {0x00000040}  6, 'Secret'\n    ])), [\n    wbEDID,\n    wbStruct(DATA, 'Data', [\n      wbFormIDCk('Parent', [NPC_, NULL]),\n      wbFormIDCk('Child', [NPC_, NULL]),\n      wbInteger('Rank', itU16, wbEnum([\n        'Lover',\n        'Ally',\n        'Confidant',\n        'Friend',\n        'Acquaitance',\n        'Rival',\n        'Foe',\n        'Enemy',\n        'Archnemesis'\n      ])),\n      wbByteArray('Unknown', 1),\n      wbInteger('Flags', itU8, wbFlags([\n        {0x01} 'Unknown 1',\n        {0x02} 'Unknown 2',\n        {0x04} 'Unknown 3',\n        {0x08} 'Unknown 4',\n        {0x10} 'Unknown 5',\n        {0x20} 'Unknown 6',\n        {0x40} 'Unknown 7',\n        {0x80} 'Secret'\n      ])),\n      wbFormIDCk('Association Type', [ASTP, NULL])\n    ])\n  ]);\n\n  wbRecord(SCEN, 'Scene', [\n    wbEDID,\n    wbVMADFragmentedSCEN,\n    wbInteger(FNAM, 'Flags', itU32, wbFlags([\n      'Begin on Quest Start',\n      'Stop on Quest End',\n      'Unknown 3',\n      'Repeat Conditions While True',\n      'Interruptible'\n    ])),\n    wbRArray('Phases',\n      wbRStruct('Phase', [\n        wbEmpty(HNAM, 'Marker Phase Start'),\n        wbString(NAM0, 'Name'),\n        // CTDA before or after next\n        //wbEmpty(NEXT, 'Marker'),\n        wbRStruct('Start Conditions', [wbCTDAs], []),\n        wbEmpty(NEXT, 'Marker'),\n        wbRStruct('Completion Conditions', [wbCTDAs], []),\n        {>>> BEGIN leftover from earlier CK versions <<<}\n        wbRStruct('Unused', [\n          wbUnknown(SCHR),\n          wbUnknown(SCDA),\n          wbUnknown(SCTX),\n          wbUnknown(QNAM),\n          wbUnknown(SCRO)\n        ], [], cpIgnore, false, wbNeverShow),\n        wbEmpty(NEXT, 'Marker'),\n        wbRStruct('Unused', [\n          wbUnknown(SCHR),\n          wbUnknown(SCDA),\n          wbUnknown(SCTX),\n          wbUnknown(QNAM),\n          wbUnknown(SCRO)\n        ], [], cpIgnore, false, wbNeverShow),\n        {>>> END leftover from earlier CK versions begin <<<}\n        wbInteger(WNAM, 'Editor Width', itU32),\n        wbEmpty(HNAM, 'Marker Phase End')\n      ], [])\n    ),\n    wbRArray('Actors', wbRStruct('Actor', [\n      wbInteger(ALID, 'Actor ID', itU32),\n      wbInteger(LNAM, 'Flags', itU32, wbFlags([\n        'No Player Activation',\n        'Optional'\n      ])),\n      wbInteger(DNAM, 'Behaviour Flags', itU32, wbFlags([\n        'Death Pause (unsused)',\n        'Death End',\n        'Combat Pause',\n        'Combat End',\n        'Dialogue Pause',\n        'Dialogue End',\n        'OBS_COM Pause',\n        'OBS_COM End'\n      ]))\n    ], [])),\n    wbRArray('Actions', wbRStruct('Action', [\n      wbInteger(ANAM, 'Type', itU16, wbEnum([\n        'Dialogue',\n        'Package',\n        'Timer'\n      ])),\n      wbString(NAM0, 'Name'),\n      wbInteger(ALID, 'Actor ID', itS32),\n      wbUnknown(LNAM),\n      wbInteger(INAM, 'Index', itU32),\n      wbInteger(FNAM, 'Flags', itU32, wbFlags([\n        {0x00000001} 'Unknown 1',\n        {0x00000002} 'Unknown 2',\n        {0x00000004} 'Unknown 3',\n        {0x00000008} 'Unknown 4',\n        {0x00000010} 'Unknown 5',\n        {0x00000020} 'Unknown 6',\n        {0x00000040} 'Unknown 7',\n        {0x00000080} 'Unknown 8',\n        {0x00000100} 'Unknown 9',\n        {0x00000200} 'Unknown 10',\n        {0x00000400} 'Unknown 11',\n        {0x00000800} 'Unknown 12',\n        {0x00001000} 'Unknown 13',\n        {0x00002000} 'Unknown 14',\n        {0x00004000} 'Unknown 15',\n        {0x00008000} 'Face Target',\n        {0x00010000} 'Looping',\n        {0x00020000} 'Headtrack Player'\n      ])),\n      wbInteger(SNAM, 'Start Phase', itU32),\n      wbInteger(ENAM, 'End Phase', itU32),\n      wbFloat(SNAM, 'Timer Seconds'),\n      wbRArray('Packages', wbFormIDCk(PNAM, 'Package', [PACK])),\n      wbFormIDCk(DATA, 'Topic', [DIAL, NULL]),\n      wbInteger(HTID, 'Headtrack Actor ID', itS32),\n      wbFloat(DMAX, 'Looping - Max'),\n      wbFloat(DMIN, 'Looping - Min'),\n      wbInteger(DEMO, 'Emotion Type', itU32, wbEmotionTypeEnum),\n      wbInteger(DEVA, 'Emotion Value', itU32),\n      {>>> BEGIN leftover from earlier CK versions <<<}\n      wbRStruct('Unused', [\n        wbUnknown(SCHR),\n        wbUnknown(SCDA),\n        wbUnknown(SCTX),\n        wbUnknown(QNAM),\n        wbUnknown(SCRO)\n      ], [], cpIgnore, false, wbNeverShow),\n      {>>> END leftover from earlier CK versions <<<}\n      wbEmpty(ANAM, 'End Marker')\n    ], [])),\n    {>>> BEGIN leftover from earlier CK versions <<<}\n    wbRStruct('Unused', [\n      wbUnknown(SCHR),\n      wbUnknown(SCDA),\n      wbUnknown(SCTX),\n      wbUnknown(QNAM),\n      wbUnknown(SCRO)\n    ], [], cpIgnore, false, wbNeverShow),\n    wbEmpty(NEXT, 'Marker'),\n    wbRStruct('Unused', [\n      wbUnknown(SCHR),\n      wbUnknown(SCDA),\n      wbUnknown(SCTX),\n      wbUnknown(QNAM),\n      wbUnknown(SCRO)\n    ], [], cpIgnore, false, wbNeverShow),\n    {>>> END leftover from earlier CK versions <<<}\n    wbFormIDCk(PNAM, 'Quest', [QUST]),\n    wbInteger(INAM, 'Last Action Index', itU32),\n    wbUnknown(VNAM),\n    wbCTDAs\n  ]);\n\n  wbRecord(ASTP, 'Association Type', [\n    wbEDID,\n    wbString(MPRT, 'Male Parent Title'),\n    wbString(FPRT, 'Female Parent Title'),\n    wbString(MCHT, 'Male Child Title'),\n    wbString(FCHT, 'Female Child Title'),\n    wbInteger(DATA, 'Flags', itU32, wbFlags([\n      'Family Association'\n    ]))\n  ]);\nend;\n\nprocedure DefineTES5k;\nbegin\n\n  wbRecord(OTFT, 'Outfit', [\n    wbEDID,\n    wbArrayS(INAM, 'Items', wbFormIDCk('Item', [ARMO, LVLI]))\n  ]);\n\n  wbRecord(ARTO, 'Art Object', [\n    wbEDID,\n    wbOBNDReq,\n    wbMODL,\n    wbInteger(DNAM, 'Art Type', itU32, wbEnum([\n      'Magic Casting',\n      'Magic Hit Effect',\n      'Enchantment Effect'\n    ]))\n  ]);\n\n  wbRecord(MATO, 'Material Object', [\n    wbEDID,\n    wbMODL,\n    wbRArray('Property Data',\n      wbByteArray(DNAM, 'Data', 0, cpIgnore, False, False, wbNeverShow)\n    ),\n    IsSSE(\n      wbStruct(DATA, 'Directional Material Data', [\n        wbFloat('Falloff Scale'),\n        wbFloat('Falloff Bias'),\n        wbFloat('Noise UV Scale'),\n        wbFloat('Material UV Scale'),\n        wbStruct('Projection Vector', [\n          wbFloat('X'),\n          wbFloat('Y'),\n          wbFloat('Z')\n        ]),\n        wbFloat('Normal Dampener'),\n        wbFloatColors('Single Pass Color'),\n        wbInteger('Flags', itU32, wbFlags(['Single Pass'])),\n        // SSE\n        wbInteger('Flags', itU8, wbFlags([\n          {0x01} 'Snow'\n        ])),\n        wbByteArray('Unused', 3, cpIgnore)\n      ], cpNormal, True, nil, 5),\n      wbStruct(DATA, 'Directional Material Data', [\n        wbFloat('Falloff Scale'),\n        wbFloat('Falloff Bias'),\n        wbFloat('Noise UV Scale'),\n        wbFloat('Material UV Scale'),\n        wbStruct('Projection Vector', [\n          wbFloat('X'),\n          wbFloat('Y'),\n          wbFloat('Z')\n        ]),\n        wbFloat('Normal Dampener'),\n        wbFloatColors('Single Pass Color'),\n        wbInteger('Flags', itU32, wbFlags(['Single Pass']))\n      ], cpNormal, True, nil, 5)\n    )\n  ]);\n\n  wbRecord(MOVT, 'Movement Type', [\n    wbEDID,\n    wbString(MNAM, 'Name'),\n    wbStruct(SPED, 'Default Data', [\n      wbFloat('Left Walk'),\n      wbFloat('Left Run'),\n      wbFloat('Right Walk'),\n      wbFloat('Right Run'),\n      wbFloat('Forward Walk'),\n      wbFloat('Forward Run'),\n      wbFloat('Back Walk'),\n      wbFloat('Back Run'),\n      wbFloat('Rotate in Place Walk', cpNormal, True, wbRotationFactor, wbRotationScale, nil, RadiansNormalize),\n      wbFloat('Rotate in Place Run', cpNormal, True, wbRotationFactor, wbRotationScale, nil, RadiansNormalize),\n      wbFloat('Rotate while Moving Run', cpNormal, True, wbRotationFactor, wbRotationScale, nil, RadiansNormalize)\n    ], cpNormal, True, nil, 10),\n    wbStruct(INAM, 'Anim Change Thresholds', [\n      wbFloat('Directional', cpNormal, True, 180/Pi),\n      wbFloat('Movement Speed'),\n      wbFloat('Rotation Speed', cpNormal, True, 180/Pi)\n    ])\n  ]);\n\n  wbRecord(SNDR, 'Sound Descriptor', [\n    wbEDID,\n    wbUnknown(CNAM),\n    wbFormID(GNAM, 'Category'),\n    wbFormIDCk(SNAM, 'Alternate Sound For', [SNDR, NULL]),\n    wbRArray('Sounds',\n      wbRStruct('Sound Files', [\n        wbString(ANAM, 'File Name')\n      ],[])\n    ),\n    wbFormIDCk(ONAM, 'Output Model', [SOPM, NULL]),\n    wbLString(FNAM, 'String', 0, cpIgnore),\n    wbCTDAs,\n    wbStruct(LNAM, 'Values', [\n      wbByteArray('Unknown', 1),\n      wbInteger('Looping', itU8, wbEnum([], [\n        $00 , 'None',\n        $08 , 'Loop',\n        $10 , 'Envelope Fast',\n        $20 , 'Envelope Slow'\n      ])),\n      wbByteArray('Unknown', 1),\n      wbInteger('Rumble Send Value = (Small / 7) + ((Big / 7) * 16)', itU8)\n    ]),\n    wbStruct(BNAM, 'Values', [\n      wbInteger('% Frequency Shift', itS8),\n      wbInteger('% Frequency Variance', itS8),\n      wbInteger('Priority', itU8),\n      wbInteger('db Variance', itU8),\n      wbInteger('Static Attenuation (db)', itU16, wbDiv(100))\n    ])\n  ]);\n\n  wbRecord(DUAL, 'Dual Cast Data', [\n    wbEDID,\n    wbOBNDReq,\n    wbStruct(DATA, 'Data', [\n      wbFormIDCk('Projectile', [PROJ, NULL]),\n      wbFormIDCk('Explosion', [EXPL, NULL]),\n      wbFormIDCk('Effect Shader', [EFSH, NULL]),\n      wbFormIDCk('Hit Effect Art', [ARTO, NULL]),\n      wbFormIDCk('Impact Data Set', [IPDS, NULL]),\n      wbInteger('Inherit Scale', itU32, wbFlags([\n        'Hit Effect Art',\n        'Projectile',\n        'Explosion'\n      ]))\n    ], cpNormal, True)\n  ]);\n\n  wbRecord(SNCT, 'Sound Category', [\n    wbEDID,\n    wbFULL,\n    wbInteger(FNAM, 'Flags', itU32, wbFlags([\n      'Mute When Submerged',\n      'Should Appear on Menu'\n    ]), cpNormal, True),\n    wbFormIDCk(PNAM, 'Parent', [SNCT]),\n    wbInteger(VNAM, 'Static Volume Multiplier', itU16, wbDiv(65535)),\n    wbInteger(UNAM, 'Default Menu Value', itU16, wbDiv(65535))\n  ]);\n\n  wbRecord(SOPM, 'Sound Output Model', [\n    wbEDID,\n    wbStruct(NAM1, 'Data', [\n      wbInteger('Flags', itU8, wbFlags([\n        'Attenuates With Distance',\n        'Allows Rumble'\n      ])),\n      wbByteArray('Unknown', 2),\n      wbInteger('Reverb Send %', itU8)\n    ]),\n    wbUnknown(FNAM), // leftover, unused\n    wbInteger(MNAM, 'Type', itU32, wbEnum([\n      'Uses HRTF',\n      'Defined Speaker Output'\n    ])),\n    wbUnknown(CNAM), // leftover, unused\n    wbUnknown(SNAM), // leftover, unused\n    wbStruct(ONAM, 'Output Values', [\n      wbArray('Channels', wbStruct('', [\n        wbInteger('L', itU8),\n        wbInteger('R', itU8),\n        wbInteger('C', itU8),\n        wbInteger('LFE', itU8),\n        wbInteger('RL', itU8),\n        wbInteger('RR', itU8),\n        wbInteger('BL', itU8),\n        wbInteger('BR', itU8)\n      ]), [\n        'Channel 0',\n        'Channel 1',\n        'Channel 2? (unused)'\n      ])\n    ]),\n    wbStruct(ANAM, 'Attenuation Values', [\n      wbByteArray('Unknown', 4),\n      wbFloat('Min Distance'),\n      wbFloat('Max Distance'),\n      wbArray('Curve', wbInteger('Value', itU8), 5),\n      wbByteArray('Unknown')\n    ])\n  ]);\n\n  wbRecord(COLL, 'Collision Layer', [\n    wbEDID,\n    wbDESCReq,\n    wbInteger(BNAM, 'Index', itU32, nil, cpNormal, True),\n    wbStruct(FNAM, 'Debug Color', [\n      wbInteger('Red', itU8),\n      wbInteger('Green', itU8),\n      wbInteger('Blue', itU8),\n      wbInteger('Unused', itU8)\n    ], cpNormal, True),\n    wbInteger(GNAM, 'Flags', itU32, wbFlags([\n      {0x00000001} 'Trigger Volume',\n      {0x00000002} 'Sensor',\n      {0x00000004} 'Navmesh Obstacle'\n    ]), cpNormal, True),\n    wbString(MNAM, 'Name', 0, cpNormal, True),\n    wbInteger(INTV, 'Interactables Count', itU32, nil, cpNormal, True),\n    wbArrayS(CNAM, 'Collides With', wbFormIDCk('Forms', [COLL]), 0, cpNormal, False)\n  ]);\n\n  wbRecord(CLFM, 'Color',\n    wbFlags(wbRecordFlagsFlags, wbFlagsList([\n      {0x00000004}  2, 'Non-Playable'\n    ])), [\n    wbEDID,\n    wbFULL,\n    wbCNAMReq,\n    wbInteger(FNAM, 'Playable', itU32, wbEnum(['False', 'True']), cpNormal, True)\n  ]);\nend;\n\nprocedure DefineTES5l;\nbegin\n  wbRecord(REVB, 'Reverb Parameters', [\n    wbEDID,\n    wbStruct(DATA, 'Data', [\n      wbInteger('Decay Time (ms)', itU16),\n      wbInteger('HF Reference (Hz)', itU16),\n      wbInteger('Room Filter', itS8),\n      wbInteger('Room HF Filter', itS8),\n      wbInteger('Reflections', itS8),\n      wbInteger('Reverb Amp', itS8),\n      wbInteger('Decay HF Ratio', itU8, wbDiv(100)),\n      wbInteger('Reflect Delay (ms), scaled', itU8),\n      wbInteger('Reverb Delay (ms)', itU8),\n      wbInteger('Diffusion %', itU8),\n      wbInteger('Density %', itU8),\n      wbInteger('Unknown', itU8)\n    ], cpNormal, True)\n  ]);\n\n  wbRecord(GRAS, 'Grass', [\n    wbEDID,\n    wbOBNDReq,\n    wbMODL,\n    wbStruct(DATA, '', [\n      wbInteger('Density', itU8),\n      wbInteger('Min Slope', itU8),\n      wbInteger('Max Slope', itU8),\n      wbByteArray('Unknown', 1),\n      wbInteger('Units From Water', itU16),\n      wbByteArray('Unknown', 2),\n      wbInteger('Units From Water Type', itU32, wbEnum([\n        'Above - At Least',\n        'Above - At Most',\n        'Below - At Least',\n        'Below - At Most',\n        'Either - At Least',\n        'Either - At Most',\n        'Either - At Most Above',\n        'Either - At Most Below'\n      ])),\n      wbFloat('Position Range'),\n      wbFloat('Height Range'),\n      wbFloat('Color Range'),\n      wbFloat('Wave Period'),\n      wbInteger('Flags', itU8, wbFlags([\n        'Vertex Lighting',\n        'Uniform Scaling',\n        'Fit to Slope'\n      ])),\n      wbByteArray('Unknown', 3)\n    ], cpNormal, True)\n  ]);\n\n  wbRecord(IDLE, 'Idle Animation', [\n    wbEDID,\n    wbCTDAs,\n    wbString(DNAM, 'Filename'),\n    wbString(ENAM, 'Animation Event'),\n    wbArray(ANAM, 'Related Idle Animations', wbFormIDCk('Related Idle Animation', [AACT, IDLE, NULL]),\n      ['Parent', 'Previous Sibling'], cpNormal, True),\n    wbStruct(DATA, 'Data (unused)', [\n      wbStruct('Looping seconds (both 255 forever)', [\n        wbInteger('Min', itU8),\n        wbInteger('Max', itU8)\n      ]),\n      wbInteger('Flags', itU8, wbFlags([\n        {0x01} 'Parent',\n        {0x02} 'Sequence',\n        {0x04} 'No Attacking',\n        {0x04} 'Blocking'\n      ], True)),\n      wbInteger('Animation Group Section', itU8{, wbIdleAnam}),\n      wbInteger('Replay Delay', itU16)\n    ], cpIgnore, True)\n  ]);\n\n  wbRecord(INFO, 'Dialog response',\n    wbFlags(wbRecordFlagsFlags, wbFlagsList([\n      {0x00002000} 13, 'Actor Changed'\n    ])), [\n    wbEDID,\n    wbVMADFragmentedINFO,\n    wbUnknown(DATA),\n    wbStruct(ENAM, 'Response flags', [\n      wbInteger('Flags', itU16, wbFlags([\n        {0x0001} 'Goodbye',\n        {0x0002} 'Random',\n        {0x0004} 'Say once',\n        {0x0008} 'Unknown 4',\n        {0x0010} 'Unknown 5',\n        {0x0020} 'Random end',\n        {0x0040} 'Invisible continue',\n        {0x0080} 'Walk Away',\n        {0x0100} 'Walk Away Invisible in Menu',\n        {0x0200} 'Force subtitle',\n        {0x0400} 'Can move while greeting',\n        {0x0800} 'No LIP File',\n        {0x1000} 'Requires post-processing',\n        {0x2000} 'Audio Output Override',\n        {0x4000} 'Spends favor points',\n        {0x8000} 'Unknown 16'\n      ])),\n      wbInteger('Reset Hours', itU16, wbDiv(2730))\n    ]),\n    wbFormIDCk(TPIC, 'Topic', [DIAL]),\n    wbFormIDCkNoReach(PNAM, 'Previous INFO', [INFO, NULL], False, cpBenign),\n    wbInteger(CNAM, 'Favor Level', itU8, wbEnum([\n      'None',\n      'Small',\n      'Medium',\n      'Large'\n    ])),\n\n    wbRArray('Link To', wbFormIDCk(TCLT, 'Response', [DIAL, INFO, NULL])),\n    wbFormID(DNAM, 'Response Data'),\n\n    wbRArray('Responses', wbRStruct('Response', [\n      wbStruct(TRDT, 'Response Data', [\n        wbInteger('Emotion Type', itU32, wbEmotionTypeEnum),\n        wbInteger('Emotion Value', itU32),\n        wbByteArray('Unused', 4),\n        wbInteger('Response number', itU8),\n        wbByteArray('Unused', 3),\n        wbFormIDCk('Sound', [SNDR, NULL]),\n        wbInteger('Flags', itU8, wbFlags([\n          'Use Emotion Animation'\n        ])),\n        wbByteArray('Unused', 3)\n      ]),\n      wbLStringKC(NAM1, 'Response Text', 0, cpTranslate),\n      wbString(NAM2, 'Script Notes'),\n      wbString(NAM3, 'Edits'),\n      wbFormIDCk(SNAM, 'Idle Animations: Speaker', [IDLE]),\n      wbFormIDCk(LNAM, 'Idle Animations: Listener', [IDLE])\n    ], [])),\n\n    wbCTDAs,\n\n    {>>> BEGIN leftover from earlier CK versions <<<}\n    wbRArray('Unknown',\n      wbRStruct('Unknown', [\n        wbUnknown(SCHR),\n        wbFormID(QNAM, 'Unknown'),\n        wbEmpty(NEXT, 'Marker')\n      ], []), cpIgnore, false, nil, nil, wbNeverShow\n    ),\n    {>>> END leftover from earlier CK versions <<<}\n\n    wbLString(RNAM, 'Prompt', 0, cpTranslate),\n    wbFormIDCk(ANAM, 'Speaker', [NPC_]),\n    wbFormIDCk(TWAT, 'Walk Away Topic', [DIAL]),\n    wbFormIDCk(ONAM, 'Audio Output Override', [SOPM])\n  ], False, wbINFOAddInfo, cpNormal, False, nil{wbINFOAfterLoad});\n\n  wbRecord(INGR, 'Ingredient', [\n    wbEDID,\n    wbVMAD,\n    wbOBNDReq,\n    wbFULL,\n    wbKSIZ,\n    wbKWDAs,\n    wbMODL,\n    wbICON,\n    wbDEST,\n    wbETYP,\n    wbYNAM,\n    wbZNAM,\n    wbStruct(DATA, '', [\n      wbInteger('Value', itS32),\n      wbFloat('Weight')\n    ], cpNormal, True),\n    wbStruct(ENIT, 'Effect Data', [\n      wbInteger('Ingredient Value', itS32),\n      wbInteger('Flags', itU32, wbFlags([\n        {0x00000001} 'No auto-calculation',\n        {0x00000002} 'Food item',\n        {0x00000004} 'Unknown 3',\n        {0x00000008} 'Unknown 4',\n        {0x00000010} 'Unknown 5',\n        {0x00000020} 'Unknown 6',\n        {0x00000040} 'Unknown 7',\n        {0x00000080} 'Unknown 8',\n        {0x00000100} 'References Persist'\n      ]))\n    ], cpNormal, True),\n    wbEffectsReq\n  ], False, nil, cpNormal, False, nil, wbKeywordsAfterSet);\n\n  wbRecord(KEYM, 'Key',\n    wbFlags(wbRecordFlagsFlags, wbFlagsList([\n      {0x00000004}  2, 'Non-Playable'\n    ])), [\n    wbEDID,\n    wbVMAD,\n    wbOBNDReq,\n    wbFULLReq,\n    wbMODL,\n    wbICON,\n    wbDEST,\n    wbYNAM,\n    wbZNAM,\n    wbKSIZ,\n    wbKWDAs,\n    wbStruct(DATA, '', [\n      wbInteger('Value', itS32),\n      wbFloat('Weight')\n    ], cpNormal, True)\n  ], False, nil, cpNormal, False, nil, wbKeywordsAfterSet);\n\n  wbQuadrantEnum := wbEnum([\n    {0} 'Bottom Left',\n    {1} 'Bottom Right',\n    {2} 'Top Left',\n    {3} 'Top Right'\n  ]);\n\n  if wbSimpleRecords then begin\n\n    wbRecord(LAND, 'Landscape',\n      wbFlags(wbRecordFlagsFlags, wbFlagsList([\n        {0x00040000} 18, 'Compressed'\n      ]), [18]), [\n      wbByteArray(DATA, 'Unknown'),\n      wbByteArray(VNML, 'Vertex Normals'),\n      wbByteArray(VHGT, 'Vertext Height Map'),\n      wbByteArray(VCLR, 'Vertex Colours'),\n\n      wbRArrayS('Layers', wbRUnion('Layer', [\n        wbRStructSK([0],'Base Layer', [\n          wbStructSK(BTXT, [1, 3], 'Base Layer Header', [\n            wbFormIDCk('Texture', [LTEX, NULL]),\n            wbInteger('Quadrant', itU8, wbQuadrantEnum),\n            wbByteArray('Unknown', 1),\n            wbInteger('Layer', itS16)\n          ])\n        ], []),\n        wbRStructSK([0],'Alpha Layer', [\n          wbStructSK(ATXT, [1, 3], 'Alpha Layer Header', [\n            wbFormIDCk('Texture', [LTEX, NULL]),\n            wbInteger('Quadrant', itU8, wbQuadrantEnum),\n            wbByteArray('Unknown', 1),\n            wbInteger('Layer', itS16)\n          ]),\n          wbByteArray(VTXT, 'Alpha Layer Data')\n        ], [])\n      ], [])),\n\n      wbArray(VTEX, 'Textures', wbFormIDCk('Texture', [LTEX, NULL]))\n    ]);\n\n  end else begin\n\n    wbRecord(LAND, 'Landscape',\n      wbFlags(wbRecordFlagsFlags, wbFlagsList([\n        {0x00040000} 18, 'Compressed'\n      ]), [18]), [\n      wbByteArray(DATA, 'Unknown'),\n      wbArray(VNML, 'Vertex Normals', wbStruct('Row', [\n        wbArray('Columns', wbStruct('Column', [\n          wbInteger('X', itU8),\n          wbInteger('Y', itU8),\n          wbInteger('Z', itU8)\n        ]), 33)\n      ]), 33),\n      wbStruct(VHGT, 'Vertext Height Map', [\n        wbFloat('Offset'),\n        wbArray('Rows', wbStruct('Row', [\n          wbArray('Columns', wbInteger('Column', itU8), 33)\n        ]), 33),\n        wbByteArray('Unknown', 3)\n      ]),\n      wbArray(VCLR, 'Vertex Colours', wbStruct('Row', [\n        wbArray('Columns', wbStruct('Column', [\n          wbInteger('X', itU8),\n          wbInteger('Y', itU8),\n          wbInteger('Z', itU8)\n        ]), 33)\n      ]), 33),\n\n      wbRArrayS('Layers', wbRUnion('Layer', [\n        wbRStructSK([0],'Base Layer', [\n          wbStructSK(BTXT, [1, 3], 'Base Layer Header', [\n            wbFormIDCk('Texture', [LTEX, NULL]),\n            wbInteger('Quadrant', itU8, wbQuadrantEnum),\n            wbByteArray('Unknown', 1),\n            wbInteger('Layer', itS16)\n          ])\n        ], []),\n        wbRStructSK([0],'Alpha Layer', [\n          wbStructSK(ATXT, [1, 3], 'Alpha Layer Header', [\n            wbFormIDCk('Texture', [LTEX, NULL]),\n            wbInteger('Quadrant', itU8, wbQuadrantEnum),\n            wbByteArray('Unknown', 1),\n            wbInteger('Layer', itS16)\n          ]),\n          wbArrayS(VTXT, 'Alpha Layer Data', wbStructSK([0], 'Cell', [\n            wbInteger('Position', itU16, wbAtxtPosition),\n            wbByteArray('Unknown', 2),\n            wbFloat('Opacity')\n          ]))\n        ], [])\n      ], [])),\n\n      wbArray(VTEX, 'Textures', wbFormIDCk('Texture', [LTEX, NULL]))\n    ]);\n\n  end;\n\n  wbRecord(LIGH, 'Light',\n    wbFlags(wbRecordFlagsFlags, wbFlagsList([\n      {0x00010000} 16, 'Random Anim Start',\n      {0x00020000} 17, 'Portal-strict',\n      {0x02000000} 25, 'Obstacle'\n    ])), [\n    wbEDID,\n    wbVMAD,\n    wbOBNDReq,\n    wbMODL,\n    wbDEST,\n    wbFULL,\n    wbICON,\n    wbStruct(DATA, '', [\n      wbInteger('Time', itS32),\n      wbInteger('Radius', itU32),\n      wbByteColors,\n      wbInteger('Flags', itU32, wbFlags([\n        {0x00000001} 'Dynamic',\n        {0x00000002} 'Can be Carried',\n        {0x00000004} 'Negative',\n        {0x00000008} 'Flicker',\n        {0x00000010} 'Unknown',\n        {0x00000020} 'Off By Default',\n        {0x00000040} 'Flicker Slow',\n        {0x00000080} 'Pulse',\n        {0x00000100} 'Pulse Slow',\n        {0x00000200} 'Spot Light',\n        {0x00000400} 'Shadow Spotlight',\n        {0x00000800} 'Shadow Hemisphere',\n        {0x00001000} 'Shadow Omnidirectional',\n        {0x00002000} 'Portal-strict'\n      ])),\n      wbFloat('Falloff Exponent'),\n      wbFloat('FOV'),\n      wbFloat('Near Clip'),\n      wbStruct('Flicker Effect', [\n        wbFloat('Period', cpNormal, False, 0.01),\n        wbFloat('Intensity Amplitude'),\n        wbFloat('Movement Amplitude')\n      ]),\n      wbInteger('Value', itU32),\n      wbFloat('Weight')\n    ], cpNormal, True),\n    wbFloat(FNAM, 'Fade value', cpNormal, True),\n    wbFormIDCk(SNAM, 'Sound', [SNDR])\n  ], False, nil, cpNormal, False, wbLIGHAfterLoad);\nend;\n\nprocedure DefineTES5m;\nbegin\n\n  wbRecord(LSCR, 'Load Screen',\n    wbFlags(wbRecordFlagsFlags, wbFlagsList([\n      {0x00000400} 10, 'Displays In Main Menu'\n    ])), [\n    wbEDID,\n    wbICON,\n    wbDESCReq,\n    wbCTDAs,\n    wbFormIDCk(NNAM, 'Loading Screen NIF', [STAT, NULL], False, cpNormal, True),\n    wbFloat(SNAM, 'Initial Scale'),\n    wbStruct(RNAM, 'Initial Rotation', [\n      wbInteger('X', itS16),\n      wbInteger('Y', itS16),\n      wbInteger('Z', itS16)\n    ]),\n    wbStruct(ONAM, 'Rotation Offset Constraints', [\n      wbInteger('Min', itS16),\n      wbInteger('Max', itS16)\n    ]),\n    wbStruct(XNAM, 'Initial Translation Offset', [\n      wbFloat('X'),\n      wbFloat('Y'),\n      wbFloat('Z')\n    ]),\n    wbString(MOD2, 'Camera Path', 0, cpNormal, False)\n  ]);\n\n  wbRecord(LTEX, 'Landscape Texture', [\n    wbEDID,\n    wbFormIDCk(TNAM, 'Texture Set', [TXST], False, cpNormal, False),\n    wbFormIDCk(MNAM, 'Material Type', [MATT, NULL], False, cpNormal, True),\n    wbStruct(HNAM, 'Havok Data', [\n      wbInteger('Friction', itU8),\n      wbInteger('Restitution', itU8)\n    ], cpNormal, True),\n    wbInteger(SNAM, 'Texture Specular Exponent', itU8, nil, cpNormal, True),\n    wbRArrayS('Grasses', wbFormIDCk(GNAM, 'Grass', [GRAS])),\n    // SSE\n    wbInteger(INAM, IsSSE('Flags', 'Unused'), itU32, wbFlags([\n      {0x01} 'Is Snow'\n    ]))\n  ]);\n\n  wbRecord(LVLN, 'Leveled NPC', [\n    wbEDID,\n    wbOBNDReq,\n    wbLVLD,\n    wbInteger(LVLF, 'Flags', itU8, wbFlags([\n      {0x01} 'Calculate from all levels <= player''s level',\n      {0x02} 'Calculate for each item in count'\n    ]), cpNormal, True),\n    wbFormIDCk(LVLG, 'Global', [GLOB]),\n    wbLLCT,\n    wbRArrayS('Leveled List Entries',\n      wbRStructExSK([0], [1], 'Leveled List Entry', [\n        wbStructExSK(LVLO , [0, 2], [3], 'Base Data', [\n          wbInteger('Level', itS16),\n          wbByteArray('Unknown', 2, cpIgnore, false, wbNeverShow),\n          wbFormIDCk('Reference', [NPC_, LVLN]),\n          wbInteger('Count', itS16),\n          wbByteArray('Unknown', 2, cpIgnore, false, wbNeverShow)\n        ]),\n\t\t\t\twbCOED\n      ], []), cpNormal, False, nil, wbLVLOsAfterSet),\n    wbMODL\n  ], False, nil, cpNormal, False, nil, wbLLEAfterSet);\n\n  wbRecord(LVLI, 'Leveled Item', [\n    wbEDID,\n    wbOBNDReq,\n    wbLVLD,\n    wbInteger(LVLF, 'Flags', itU8, wbFlags([\n      {0x01} 'Calculate from all levels <= player''s level',\n      {0x02} 'Calculate for each item in count',\n      {0x04} 'Use All',\n      {0x08} 'Special Loot'\n    ]), cpNormal, True),\n    wbFormIDCk(LVLG, 'Global', [GLOB]),\n    wbLLCT,\n    wbRArrayS('Leveled List Entries',\n      wbRStructExSK([0], [1], 'Leveled List Entry', [\n        wbStructExSK(LVLO , [0, 2], [3], 'Base Data', [\n          wbInteger('Level', itU16),\n          wbByteArray('Unknown', 2, cpIgnore, false, wbNeverShow),\n          wbFormIDCk('Reference', [ARMO, AMMO, APPA, MISC, WEAP, BOOK, LVLI, KEYM, ALCH, LIGH, INGR, SLGM, SCRL]),\n          wbInteger('Count', itU16),\n          wbByteArray('Unknown', 2, cpIgnore, false, wbNeverShow)\n        ]),\n        wbCOED\n      ], []), cpNormal, False, nil, wbLVLOsAfterSet\n    )\n  ], False, nil, cpNormal, False, nil, wbLLEAfterSet);\n\n   wbRecord(LVSP, 'Leveled Spell', [\n    wbEDID,\n    wbOBNDReq,\n    wbLVLD,\n    wbInteger(LVLF, 'Flags', itU8, wbFlags([\n      {0x01} 'Calculate from all levels <= player''s level',\n      {0x02} 'Calculate for each item in count',\n      {0x04} 'Use All Spells'\n    ]), cpNormal, True),\n    wbLLCT,\n    wbRArrayS('Leveled List Entries',\n      wbRStructSK([0], 'Leveled List Entry', [\n        wbStructExSK(LVLO , [0, 2], [3], 'Base Data', [\n        wbInteger('Level', itU16),\n        wbByteArray('Unknown', 2, cpIgnore, false, wbNeverShow),\n        wbFormIDCk('Reference', [SPEL, LVSP]),\n        wbInteger('Count', itU16),\n        wbByteArray('Unknown', 2, cpIgnore, false, wbNeverShow)\n      ])\n      ], []), cpNormal, False, nil, wbLVLOsAfterSet\n    )\n  ], False, nil, cpNormal, False, nil, wbLLEAfterSet);\n\n  wbMGEFType := wbInteger('Archtype', itU32, wbEnum([\n    {00} 'Value Modifier',\n    {01} 'Script',\n    {02} 'Dispel',\n    {03} 'Cure Disease',\n    {04} 'Absorb',\n    {05} 'Dual Value Modifier',\n    {06} 'Calm',\n    {07} 'Demoralize',\n    {08} 'Frenzy',\n    {09} 'Disarm',\n    {10} 'Command Summoned',\n    {11} 'Invisibility',\n    {12} 'Light',\n    {13} 'Unknown 13',\n    {14} 'Unknown 14',\n    {15} 'Lock',\n    {16} 'Open',\n    {17} 'Bound Weapon',\n    {18} 'Summon Creature',\n    {19} 'Detect Life',\n    {20} 'Telekinesis',\n    {21} 'Paralysis',\n    {22} 'Reanimate',\n    {23} 'Soul Trap',\n    {24} 'Turn Undead',\n    {25} 'Guide',\n    {26} 'Werewolf Feed',\n    {27} 'Cure Paralysis',\n    {28} 'Cure Addiction',\n    {29} 'Cure Poison',\n    {30} 'Concussion',\n    {31} 'Value and Parts',\n    {32} 'Accumulate Magnitude',\n    {33} 'Stagger',\n    {34} 'Peak Value Modifier',\n    {35} 'Cloak',\n    {36} 'Werewolf',\n    {37} 'Slow Time',\n    {38} 'Rally',\n    {39} 'Enhance Weapon',\n    {40} 'Spawn Hazard',\n    {41} 'Etherealize',\n    {42} 'Banish',\n    {43} 'Spawn Scripted Ref',\n    {44} 'Disguise',\n    {45} 'Grab Actor',\n    {46} 'Vampire Lord'\n  ]), cpNormal, False, nil, wbMGEFArchtypeAfterSet);\n\n  wbMGEFData := wbRStruct('Magic Effect Data', [\n    wbStruct(DATA, 'Data', [\n      wbInteger('Flags', itU32, wbFlags([\n        {0x00000001}  'Hostile',\n        {0x00000002}  'Recover',\n        {0x00000004}  'Detrimental',\n        {0x00000008}  'Snap to Navmesh',\n        {0x00000010}  'No Hit Event',\n\t\t\t\t{0x00000020}  'Unknown 6',\n\t\t\t\t{0x00000040}  'Unknown 7',\n\t\t\t\t{0x00000080}  'Unknown 8',\n\t\t\t\t{0x00000100}  'Dispel with Keywords',\n\t\t\t\t{0x00000200}  'No Duration',\n\t\t\t\t{0x00000400}  'No Magnitude',\n\t\t\t\t{0x00000800}  'No Area',\n\t\t\t\t{0x00001000}  'FX Persist',\n\t\t\t\t{0x00002000}  'Unknown 14',\n\t\t\t\t{0x00004000}  'Gory Visuals',\n\t\t\t\t{0x00008000}  'Hide in UI',\n\t\t\t\t{0x00010000}  'Unknown 17',\n\t\t\t\t{0x00020000}  'No Recast',\n\t\t\t\t{0x00040000}  'Unknown 19',\n\t\t\t\t{0x00080000}  'Unknown 20',\n\t\t\t\t{0x00100000}  'Unknown 21',\n\t\t\t\t{0x00200000}  'Power Affects Magnitude',\n\t\t\t\t{0x00400000}  'Power Affects Duration',\n\t\t\t\t{0x00800000}  'Unknown 24',\n\t\t\t\t{0x01000000}  'Unknown 25',\n\t\t\t\t{0x02000000}  'Unknown 26',\n\t\t\t\t{0x04000000}  'Painless',\n\t\t\t\t{0x08000000}  'No Hit Effect',\n\t\t\t\t{0x10000000}  'No Death Dispel',\n\t\t\t\t{0x20000000}  'Unknown 30',\n\t\t\t\t{0x40000000}  'Unknown 31',\n\t\t\t\t{0x80000000}  'Unknown 32'\n\t\t\t])),\n      wbFloat('Base Cost'),\n      wbUnion('Assoc. Item', wbMGEFAssocItemDecider, [\n        wbFormID('Unused', cpIgnore),\n        wbFormIDCk('Assoc. Item', [LIGH, NULL]),\n        wbFormIDCk('Assoc. Item', [WEAP, ARMO, NULL]),\n        wbFormIDCk('Assoc. Item', [NPC_, NULL]),\n        wbFormIDCk('Assoc. Item', [HAZD, NULL]),\n        wbFormIDCk('Assoc. Item', [SPEL, NULL]),\n        wbFormIDCk('Assoc. Item', [RACE, NULL]),\n        wbFormIDCk('Assoc. Item', [ENCH, NULL]),\n        wbFormIDCk('Assoc. Item', [KYWD, NULL])\n      ], cpNormal, False, nil, wbMGEFAssocItemAfterSet),\n      wbInteger('Magic Skill', itS32, wbActorValueEnum),\n      wbInteger('Resist Value', itS32, wbActorValueEnum),\n      wbInteger('Counter Effect count', itU16),\n      wbByteArray('Unused', 2),\n      wbFormIDCk('Casting Light', [LIGH, NULL]),\n      wbFloat('Taper Weight'),\n      wbFormIDCk('Hit Shader', [EFSH, NULL]),\n      wbFormIDCk('Enchant Shader', [EFSH, NULL]),\n      wbInteger('Minimum Skill Level', itU32),\n      wbStruct('Spellmaking', [\n        wbInteger('Area', itU32),\n        wbFloat('Casting Time')\n      ]),\n      wbFloat('Taper Curve'),\n      wbFloat('Taper Duration'),\n      wbFloat('Second AV Weight', cpNormal, False, nil, wbMGEFAV2WeightAfterSet),\n      wbMGEFType,\n      wbActorValue,\n      wbFormIDCk('Projectile', [PROJ, NULL]),\n      wbFormIDCk('Explosion', [EXPL, NULL]),\n      wbInteger('Casting Type', itU32, wbCastEnum),\n      wbInteger('Delivery', itU32, wbTargetEnum),\n      wbInteger('Second Actor Value', itS32, wbActorValueEnum),\n      wbFormIDCk('Casting Art', [ARTO, NULL]),\n      wbFormIDCk('Hit Effect Art', [ARTO, NULL]),\n      wbFormIDCk('Impact Data', [IPDS, NULL]),\n      wbFloat('Skill Usage Multiplier'),\n      wbStruct('Dual Casting', [\n        wbFormIDCk('Art', [DUAL, NULL]),\n        wbFloat('Scale')\n      ]),\n      wbFormIDCk('Enchant Art', [ARTO, NULL]),\n      wbByteArray('Unknown', 4),\n      wbByteArray('Unknown', 4),\n      wbFormIDCk('Equip Ability', [SPEL, NULL]),\n      wbFormIDCk('Image Space Modifier', [IMAD, NULL]),\n      wbFormIDCk('Perk to Apply', [PERK, NULL]),\n      wbInteger('Casting Sound Level', itU32, wbSoundLevelEnum),\n      wbStruct('Script Effect AI', [\n        wbFloat('Score'),\n        wbFloat('Delay Time')\n      ])\n    ], cpNormal, True)\n  ], []);\n\n  wbRecord(MGEF, 'Magic Effect', [\n    wbEDID,\n    wbVMAD,\n    wbFULL,\n    wbMDOB,\n    wbKSIZ,\n    wbKWDAs,\n    wbMGEFData,\n    wbRArrayS('Counter Effects', wbFormIDCk(ESCE, 'Effect', [MGEF]), cpNormal, False, nil, wbCounterEffectsAfterSet),\n    wbArray(SNDD, 'Sounds', wbStruct('', [\n      wbInteger('Type', itU32, wbEnum([\n        'Sheathe/Draw',\n        'Charge',\n        'Ready',\n        'Release',\n        'Concentration Cast Loop',\n        'On Hit'\n      ])),\n      wbFormIDCk('Sound', [SNDR])\n    ])),\n    wbLStringKC(DNAM, 'Magic Item Description', 0, cpTranslate),\n    wbCTDAs\n  ], False, nil, cpNormal, False, nil {wbMGEFAfterLoad}, wbMGEFAfterSet);\n\n  wbRecord(MISC, 'Misc. Item',\n    wbFlags(wbRecordFlagsFlags, wbFlagsList([\n      {0x00000004}  2, 'Non-Playable'\n    ])), [\n    wbEDID,\n    wbVMAD,\n    wbOBNDReq,\n    wbFULL,\n    wbMODL,\n    wbICON,\n    wbDEST,\n    wbYNAM,\n    wbZNAM,\n    wbKSIZ,\n    wbKWDAs,\n    wbStruct(DATA, 'Data', [\n      wbInteger('Value', itS32),\n      wbFloat('Weight')\n    ], cpNormal, True)\n  ], False, nil, cpNormal, False, wbRemoveEmptyKWDA, wbKeywordsAfterSet);\n\n  wbRecord(APPA, 'Alchemical Apparatus', [\n    wbEDID,\n    wbVMAD,\n    wbOBNDReq,\n    wbFULL,\n    wbMODL,\n    wbICON,\n    wbDEST,\n    wbYNAM,\n    wbZNAM,\n    wbInteger(QUAL, 'Quality', itS32, wbEnum([], [\n      0, 'Novice',\n      1, 'Apprentice',\n      2, 'Journeyman',\n      3, 'Expert',\n      4, 'Master'\n    ])),\n    wbDESC,\n    wbStruct(DATA, 'Data', [\n      wbInteger('Value', itU32),\n      wbFloat('Weight')\n    ])\n  ]);\n\n  wbRecord(COBJ, 'Constructible Object', [\n    wbEDID,\n    wbCOCT,\n    wbCNTOs,\n    wbCTDAs,\n    wbFormID(CNAM, 'Created Object'),\n    wbFormIDCk(BNAM, 'Workbench Keyword', [KYWD]),\n    wbInteger(NAM1, 'Created Object Count', itU16)\n  ], False, nil, cpNormal, False, nil, wbContainerAfterSet);\n\n  wbRecord(NPC_, 'Non-Player Character (Actor)',\n    wbFlags(wbRecordFlagsFlags, wbFlagsList([\n      {0x00000400} 10, 'Unknown 10',\n      {0x00040000} 18, 'Compressed',\n      {0x00080000} 19, 'Unknown 19',\n      {0x20000000} 29, 'Bleedout Override'\n    ]), [18]), [\n    wbEDID,\n    wbVMAD,\n    wbOBNDReq,\n    wbStruct(ACBS, 'Configuration', [\n      wbInteger('Flags', itU32, wbFlags([\n        {0x00000001} 'Female',\n        {0x00000002} 'Essential',\n        {0x00000004} 'Is CharGen Face Preset',\n        {0x00000008} 'Respawn',\n        {0x00000010} 'Auto-calc stats',\n        {0x00000020} 'Unique',\n        {0x00000040} 'Doesn''t affect stealth meter',\n        {0x00000080} 'PC Level Mult',\n        {0x00000100} 'Use Template?',\n        {0x00000200} 'Unknown 9',\n        {0x00000400} 'Unknown 10',\n        {0x00000800} 'Protected',\n        {0x00001000} 'Unknown 12',\n        {0x00002000} 'Unknown 13',\n        {0x00004000} 'Summonable',\n        {0x00008000} 'Unknown 15',\n        {0x00010000} 'Doesn''t bleed',\n        {0x00020000} 'Unknown 17',\n        {0x00040000} 'Bleedout Override',\n        {0x00080000} 'Opposite Gender Anims',\n        {0x00100000} 'Simple Actor',\n        {0x00200000} 'looped script?',\n        {0x00400000} 'Unknown 22',\n        {0x00800000} 'Unknown 23',\n        {0x01000000} 'Unknown 24',\n        {0x02000000} 'Unknown 25',\n        {0x04000000} 'Unknown 26',\n        {0x08000000} 'Unknown 27',\n        {0x10000000} 'looped audio?',\n        {0x20000000} 'Is Ghost',\n        {0x40000000} 'Unknown 30',\n        {0x80000000} 'Invulnerable'\n      ])),\n      wbInteger('Magicka Offset', itS16, nil, cpNormal, True, nil{wbActorTemplateUseStats}),\n      wbInteger('Stamina Offset', itS16, nil, cpNormal, False, nil{wbActorTemplateUseAIData}),\n      wbUnion('Level', wbNPCLevelDecider, [\n        wbInteger('Level', itS16, nil, cpNormal, True, nil{wbActorTemplateUseStats}),\n        wbInteger('Level Mult', itS16, wbDiv(1000), cpNormal, True, nil{wbActorTemplateUseStats})\n      ], cpNormal, True, nil{wbActorTemplateUseStats}),\n      wbInteger('Calc min level', itU16, nil, cpNormal, True, nil{wbActorTemplateUseStats}),\n      wbInteger('Calc max level', itU16, nil, cpNormal, True, nil{wbActorTemplateUseStats}),\n      wbInteger('Speed Multiplier', itU16, nil, cpNormal, True, nil{wbActorTemplateUseStats}),\n      wbInteger('Disposition Base (unused)', itS16, nil, cpIgnore, True, nil{wbActorTemplateUseTraits}),\n      wbInteger('Template Flags', itU16, wbFlags([\n        {0x0001} 'Use Traits',\n        {0x0002} 'Use Stats',\n        {0x0004} 'Use Factions',\n        {0x0008} 'Use Spell List',\n        {0x0010} 'Use AI Data',\n        {0x0020} 'Use AI Packages',\n        {0x0040} 'Use Model/Animation?',\n        {0x0080} 'Use Base Data',\n        {0x0100} 'Use Inventory',\n        {0x0200} 'Use Script',\n        {0x0400} 'Use Def Pack List',\n        {0x0800} 'Use Attack Data',\n        {0x1000} 'Use Keywords'\n      ])),\n      wbInteger('Health Offset', itS16, nil, cpNormal, True, nil{wbActorTemplateUseStats}),\n      wbInteger('Bleedout Override', itU16, nil, cpNormal, True, nil{wbActorTemplateUseStats})\n    ], cpNormal, True),\n    wbRArrayS('Factions',\n      wbStructSK(SNAM, [0], 'Faction', [\n        wbFormIDCk('Faction', [FACT]),\n        wbInteger('Rank', itS8),\n        wbByteArray('Unused', 3, cpIgnore)\n      ]), cpNormal, False, nil, nil, nil{wbActorTemplateUseFactions}\n    ),\n    wbFormIDCk(INAM, 'Death item', [LVLI], False, cpNormal, False, nil{wbActorTemplateUseTraits}),\n    wbFormIDCk(VTCK, 'Voice', [VTYP], False, cpNormal, False, nil{wbActorTemplateUseTraits}),\n    wbFormIDCk(TPLT, 'Template', [LVLN, NPC_]),\n    wbFormIDCk(RNAM, 'Race', [RACE], False, cpNormal, True, nil{wbActorTemplateUseTraits}),\n    wbSPCT,\n    wbSPLOs,\n    wbDEST,\n    wbFormIDCk(WNAM, 'Worn Armor', [ARMO], False, cpNormal, False),\n    wbFormIDCk(ANAM, 'Far away model', [ARMO], False, cpNormal, False, nil{wbActorTemplateUseTraits}),\n    wbFormIDCk(ATKR, 'Attack Race', [RACE], False, cpNormal, False),\n    wbRArrayS('Attacks', wbAttackData),\n    wbFormIDCk(SPOR, 'Spectator override package list', [FLST], False, cpNormal, False),\n    wbFormIDCk(OCOR, 'Observe dead body override package list', [FLST], False, cpNormal, False),\n    wbFormIDCk(GWOR, 'Guard warn override package list', [FLST], False, cpNormal, False),\n    wbFormIDCk(ECOR, 'Combat override package list', [FLST], False, cpNormal, False),\n    wbInteger(PRKZ, 'Perk Count', itU32, nil, cpBenign),\n    wbRArrayS('Perks',\n      wbStructSK(PRKR, [0], 'Perk', [\n        wbFormIDCk('Perk', [PERK]),\n        wbInteger('Rank', itU8),\n        wbByteArray('Unused', 3, cpIgnore)\n      ]), cpNormal, False, nil, wbPRKRsAfterSet\n    ),\n    wbCOCT,\n    wbCNTOs,\n    wbAIDT,\n    wbRArray('Packages', wbFormIDCk(PKID, 'Package', [PACK]), cpNormal, False, nil{wbActorTemplateUseAIPackages}),\n    wbKSIZ,\n    wbKWDAs,\n    wbFormIDCk(CNAM, 'Class', [CLAS], False, cpNormal, True),\n    wbFULL,\n    wbLString(SHRT, 'Short Name', 0, cpTranslate),\n    wbByteArray(DATA, 'Marker'),\n    wbStruct(DNAM, 'Player Skills', [\n      wbArray('Skill Values', wbInteger('Skill', itU8), [\n        'OneHanded',\n        'TwoHanded',\n        'Marksman',\n        'Block',\n        'Smithing',\n        'HeavyArmor',\n        'LightArmor',\n        'Pickpocket',\n        'Lockpicking',\n        'Sneak',\n        'Alchemy',\n        'Speechcraft',\n        'Alteration',\n        'Conjuration',\n        'Destruction',\n        'Illusion',\n        'Restoration',\n        'Enchanting'\n      ]),\n      wbArray('Skill Offsets', wbInteger('Skill', itU8), [\n        'OneHanded',\n        'TwoHanded',\n        'Marksman',\n        'Block',\n        'Smithing',\n        'HeavyArmor',\n        'LightArmor',\n        'Pickpocket',\n        'Lockpicking',\n        'Sneak',\n        'Alchemy',\n        'Speechcraft',\n        'Alteration',\n        'Conjuration',\n        'Destruction',\n        'Illusion',\n        'Restoration',\n        'Enchanting'\n      ]),\n      //wbByteArray('Unknown', 4),\n      wbInteger('Health', itU16),\n      wbInteger('Magicka', itU16),\n      wbInteger('Stamina', itU16),\n      wbByteArray('Unused', 2, cpIgnore),\n      wbFloat('Far away model distance'),\n      wbInteger('Geared up weapons', itU8),\n      wbByteArray('Unused', 3, cpIgnore)\n    ], cpNormal, False, nil{wbActorTemplateUseStatsAutoCalc}),\n    wbRArrayS('Head Parts', wbFormIDCk(PNAM, 'Head Part', [HDPT]), cpNormal, False, nil, nil, nil{wbActorTemplateUseModelAnimation}),\n    wbFormIDCk(HCLF, 'Hair Color', [CLFM], False, cpNormal, False),\n    wbFormIDCk(ZNAM, 'Combat Style', [CSTY], False, cpNormal, False),\n    wbFormIDCk(GNAM, 'Gift Filter', [FLST], False, cpNormal, False),\n    wbUnknown(NAM5, cpNormal, True),\n    wbFloat(NAM6, 'Height', cpNormal, True),\n    wbFloat(NAM7, 'Weight', cpNormal, True),\n    wbInteger(NAM8, 'Sound Level', itU32, wbSoundLevelEnum, cpNormal, True),\n    wbCSDTs,\n    // When CSCR exists CSDT, CSDI, CSDC are not present\n    wbFormIDCk(CSCR, 'Inherits Sounds From', [NPC_], False, cpNormal, False),\n    wbFormIDCk(DOFT, 'Default outfit', [OTFT], False, cpNormal, False),\n    wbFormIDCk(SOFT, 'Sleeping outfit', [OTFT], False, cpNormal, False),\n    wbFormIDCk(DPLT, 'Default Package List', [FLST], False, cpNormal, False),\n    wbFormIDCk(CRIF, 'Crime faction', [FACT], False, cpNormal, False),\n    wbFormIDCk(FTST, 'Head texture', [TXST], False, cpNormal, False),\n    wbStruct(QNAM, 'Texture lighting', [\n      wbFloat('Red', cpNormal, True, 255, 0),\n      wbFloat('Green', cpNormal, True, 255, 0),\n      wbFloat('Blue', cpNormal, True, 255, 0)\n    ]),\n    wbStruct(NAM9, 'Face morph', [\n      wbFloat('Nose Long/Short'),\n      wbFloat('Nose Up/Down'),\n      wbFloat('Jaw Up/Down'),\n      wbFloat('Jaw Narrow/Wide'),\n      wbFloat('Jaw Farward/Back'),\n      wbFloat('Cheeks Up/Down'),\n      wbFloat('Cheeks Farward/Back'),\n      wbFloat('Eyes Up/Down'),\n      wbFloat('Eyes In/Out'),\n      wbFloat('Brows Up/Down'),\n      wbFloat('Brows In/Out'),\n      wbFloat('Brows Farward/Back'),\n      wbFloat('Lips Up/Down'),\n      wbFloat('Lips In/Out'),\n      wbFloat('Chin Narrow/Wide'),\n      wbFloat('Chin Up/Down'),\n      wbFloat('Chin Underbite/Overbite'),\n      wbFloat('Eyes Farward/Back'),\n      wbFloat('Unknown')\n    ], cpNormal, False),\n    wbStruct(NAMA, 'Face parts', [\n      wbInteger('Nose', itU32),\n      wbInteger('Unknown', itS32),\n      wbInteger('Eyes', itU32),\n      wbInteger('Mouth', itU32)\n    ]),\n    wbRArrayS('Tint Layers',\n      wbRStructSK([0], 'Layer', [\n        wbInteger(TINI, 'Tint Index', itU16, wbTintLayerToStr, wbStrToInt),\n        wbStruct(TINC, 'Tint Color', [\n          wbInteger('Red', itU8),\n          wbInteger('Green', itU8),\n          wbInteger('Blue', itU8),\n          wbInteger('Alpha', itU8)\n        ]),\n        wbInteger(TINV, 'Interpolation Value', itU32, wbDiv(100)),\n        wbInteger(TIAS, 'Preset', itS16)\n      ], []))\n  ], False, nil, cpNormal, False, wbNPCAfterLoad, wbNPCAfterSet);\n\n  wbObjectTypeEnum := wbEnum([\n    ' NONE',\n    'Activators',\n    'Armor',\n    'Books',\n    'Clothing',\n    'Containers',\n    'Doors',\n    'Ingredients',\n    'Lights',\n    'Misc',\n    'Flora',\n    'Furniture',\n    'Weapons: Any',\n    'Ammo',\n    'NPCs',\n    'Creatures',\n    'Keys',\n    'Alchemy',\n    'Food',\n    ' All: Combat Wearable',\n    ' All: Wearable',\n    'Weapons: Ranged',\n    'Weapons: Melee',\n    'Weapons: NONE',\n    'Actor Effects: Any',\n    'Actor Effects: Range Target',\n    'Actor Effects: Range Touch',\n    'Actor Effects: Range Self',\n    'Actors: Any'\n  ]);\n\n  wbPKDTSpecificFlagsUnused := False;\n\n  wbPKDTFlags := wbFlags([\n    {0x00000001} 'Offers Services',\n    {0x00000002} 'Unknown 2',\n    {0x00000004} 'Must complete',\n    {0x00000008} 'Maintain Speed at Goal',\n    {0x00000010} 'Unknown 5',\n    {0x00000020} 'Unknown 6',\n    {0x00000040} 'Unlock doors at package start',\n    {0x00000080} 'Unlock doors at package end',\n    {0x00000100} 'Unknown 9',\n    {0x00000200} 'Continue if PC Near',\n    {0x00000400} 'Once per day',\n    {0x00000800} 'Unknown 12',\n    {0x00001000} 'Unknown 13',\n    {0x00002000} 'Preferred Speed',\n    {0x00004000} 'Unknown 15',\n    {0x00008000} 'Unknown 16',\n    {0x00010000} 'Unknown 17',\n    {0x00020000} 'Always Sneak',\n    {0x00040000} 'Allow Swimming',\n    {0x00080000} 'Unknown 20',\n    {0x00100000} 'Ignore Combat',\n    {0x00200000} 'Weapons Unequipped',\n    {0x00400000} 'Unknown 23',\n    {0x00800000} 'Weapon Drawn',\n    {0x01000000} 'Unknown 25',\n    {0x02000000} 'Unknown 26',\n    {0x04000000} 'Unknown 27',\n    {0x08000000} 'No Combat Alert',\n    {0x10000000} 'Unknown 29',\n    {0x20000000} 'Wear Sleep Outfit (unused)',\n    {0x40000000} 'Unknown 31',\n    {0x80000000} 'Unknown 32'\n  ], [29]);\n\n  wbPKDTInterruptFlags := wbFlags([\n    {0x0001}'Hellos to player',\n    {0x0002}'Random conversations',\n    {0x0004}'Observe combat behavior',\n    {0x0008}'Greet corpse behavior',\n    {0x0010}'Reaction to player actions',\n    {0x0020}'Friendly fire comments',\n    {0x0040}'Aggro Radius Behavior',\n    {0x0080}'Allow Idle Chatter',\n    {0x0100}'Unknown 9',\n    {0x0200}'World Interactions',\n    {0x0400}'Unknown 11',\n    {0x0800}'Unknown 12',\n    {0x1000}'Unknown 13',\n    {0x2000}'Unknown 14',\n    {0x4000}'Unknown 15',\n    {0x8000}'Unknown 16'\n  ]);\nend;\n\nprocedure DefineTES5n;\nbegin\n\n  wbUNAMs:= wbRArray('Data Inputs', wbRStruct('Data Input', [\n    wbInteger(UNAM, 'Index', itS8),\n    wbString(BNAM, 'Name'),\n    wbInteger(PNAM, 'Flags', itU32, wbFlags([\n      'Public'\n    ]))\n  ], []));\n\n  wbRecord(PACK, 'Package', [\n    wbEDID,\n    wbVMADFragmentedPACK,\n\n    wbStruct(PKDT, 'Pack Data', [\n      wbInteger('General Flags', itU32, wbPKDTFlags),\n      wbInteger('Type', itU8, wbEnum ([], [\n        18, 'Package',\n        19, 'Package Template'\n      ])),\n      wbInteger('Interrupt Override', itU8, wbEnum([\n        'None',\n        'Spectator',\n        'ObserveDead',\n        'GuardWarn',\n        'Combat'\n      ])),\n      wbInteger('Preferred Speed', itU8, wbEnum([\n        'Walk',\n        'Jog',\n        'Run',\n        'Fast Walk'\n      ])),\n      wbByteArray('Unknown', 1),\n      wbInteger('Interrupt Flags', itU16, wbPKDTInterruptFlags),\n      wbByteArray('Unknown', 2)\n    ], cpNormal, True),\n\n    wbStruct(PSDT, 'Schedule', [\n      wbInteger('Month', itS8),\n      wbInteger('Day of week', itS8, wbEnum([\n        'Sunday',\n        'Monday',\n        'Tuesday',\n        'Wednesday',\n        'Thursday',\n        'Friday',\n        'Saturday',\n        'Weekdays',\n        'Weekends',\n        'Monday, Wednesday, Friday',\n        'Tuesday, Thursday'\n      ], [\n        -1, 'Any'\n      ])),\n      wbInteger('Date', itU8),\n      wbInteger('Hour', itS8),\n      wbInteger('Minute', itS8),\n      wbByteArray('Unused', 3, cpIgnore),\n      wbInteger('Duration (minutes)', itS32)\n    ], cpNormal, True),\n    wbCTDAs,\n\n    wbRStruct('Idle Animations', [\n      wbInteger(IDLF, 'Flags', itU8, wbEnum([], [\n         0, 'Unknown',\n         8, 'Random',\n         9, 'Run in Sequence',\n        12, 'Random, Do Once',\n        13, 'Run in Sequence, Do Once'\n      ]), cpNormal, True),\n      wbStruct(IDLC, '', [\n        wbInteger('Animation Count', itU8, nil, cpBenign),\n        wbByteArray('Unknown', 3)\n      ], cpNormal, True, nil, 1),\n      wbFloat(IDLT, 'Idle Timer Setting', cpNormal, True),\n      wbArray(IDLA, 'Animations', wbFormIDCk('Animation', [IDLE]), 0, nil, wbIDLAsAfterSet, cpNormal, True),\n      wbByteArray(IDLB, 'Unknown', 4, cpIgnore)\n    ], [], cpNormal, False, nil, False, nil {cannot be totally removed , wbAnimationsAfterSet}),\n\n    wbFormIDCk(CNAM, 'Combat Style', [CSTY]),\n    wbFormIDCk(QNAM, 'Owner Quest', [QUST]),\n    wbStruct(PKCU, 'Counter', [\n      wbInteger('Data Input Count', itU32),\n      wbFormIDCk('Package Template', [PACK, NULL]),\n      wbInteger('Version Counter (autoincremented)', itU32)\n    ], cpNormal, True),\n\n    wbRStruct('Package Data', [\n      wbRArray('Data Input Values', wbRStruct('Value', [\n        wbString(ANAM, 'Type'),\n        wbUnion(CNAM, 'Value', wbPubPackCNAMDecider, [\n          {0} wbByteArray('Unknown'),\n          {1} wbInteger('Bool', itU8, wbEnum(['False', 'True'])),\n          {2} wbInteger('Integer', itU32),\n          {3} wbFloat('Float')\n        ]),\n        wbUnknown(BNAM),\n        wbPDTOs,\n        wbPLDT,\n        wbStruct(PTDA, 'Target', [wbTargetData]),\n        wbUnknown(TPIC)\n      ], [], cpNormal, False)),\n      wbUNAMs\n    ], []),\n    wbByteArray(XNAM, 'Marker'),\n\n    wbRStruct('Procedure Tree', [\n      wbRArray('Branches', wbRStruct('Branch', [\n        wbString(ANAM, 'Branch Type'),\n        wbCITC,\n        wbCTDAsCount,\n        wbStruct(PRCB, 'Root', [\n          wbInteger('Branch Count', itU32),\n          wbInteger('Flags', itU32, wbFlags([\n            'Repeat when Complete',\n            'Unknown 1'\n          ]))\n        ]),\n        wbString(PNAM, 'Procedure Type'),\n        wbInteger(FNAM, 'Flags', itU32, wbFlags(['Success Completes Package'])),\n        wbRArray('Data Input Indexes', wbInteger(PKC2, 'Index', itU8)),\n        {>>> PFO2 should be single, there is only 1 PACK [00095F46] <PatrolAndHunt> in Skyrim.esm with 2xPFO2 <<<}\n        wbRArray('Flags Override',\n          wbStruct(PFO2, 'Data', [\n            wbInteger('Set General Flags', itU32, wbPKDTFlags),\n            wbInteger('Clear General Flags', itU32, wbPKDTFlags),\n            wbInteger('Set Interrupt Flags', itU16, wbPKDTInterruptFlags),\n            wbInteger('Clear Interrupt Flags', itU16, wbPKDTInterruptFlags),\n            wbInteger('Preferred Speed Override', itU8, wbEnum([\n              'Walk',\n              'Jog',\n              'Run',\n              'Fast Walk'\n            ])),\n            wbByteArray('Unknown', 3)\n          ])\n        ),\n        wbRArray('Unknown', wbUnknown(PFOR), cpIgnore)\n      ], [], cpNormal, False, nil, False, nil, wbConditionsAfterSet))\n    ], []),\n    wbUNAMs,\n    wbRStruct('OnBegin', [\n      wbEmpty(POBA, 'OnBegin Marker', cpNormal, True),\n      wbFormIDCk(INAM, 'Idle', [IDLE, NULL], False, cpNormal, True),\n      {>>> BEGIN leftover from earlier CK versions <<<}\n      wbByteArray(SCHR, 'Unused', 0, cpIgnore, false, false, wbNeverShow),\n      wbByteArray(SCTX, 'Unused', 0, cpIgnore, false, false, wbNeverShow),\n      wbByteArray(QNAM, 'Unused', 0, cpIgnore, false, false, wbNeverShow),\n      wbByteArray(TNAM, 'Unused', 0, cpIgnore, false, false, wbNeverShow),\n      {>>> END leftover from earlier CK versions <<<}\n      wbPDTOs\n    ], []),\n    wbRStruct('OnEnd', [\n      wbEmpty(POEA, 'OnEnd Marker', cpNormal, True),\n      wbFormIDCk(INAM, 'Idle', [IDLE, NULL], False, cpNormal, True),\n      {>>> BEGIN leftover from earlier CK versions <<<}\n      wbByteArray(SCHR, 'Unused', 0, cpIgnore, false, false, wbNeverShow),\n      wbByteArray(SCTX, 'Unused', 0, cpIgnore, false, false, wbNeverShow),\n      wbByteArray(QNAM, 'Unused', 0, cpIgnore, false, false, wbNeverShow),\n      wbByteArray(TNAM, 'Unused', 0, cpIgnore, false, false, wbNeverShow),\n      {>>> END leftover from earlier CK versions <<<}\n      wbPDTOs\n    ], []),\n    wbRStruct('OnChange', [\n      wbEmpty(POCA, 'OnChange Marker', cpNormal, True),\n      wbFormIDCk(INAM, 'Idle', [IDLE, NULL], False, cpNormal, True),\n      {>>> BEGIN leftover from earlier CK versions <<<}\n      wbByteArray(SCHR, 'Unused', 0, cpIgnore, false, false, wbNeverShow),\n      wbByteArray(SCDA, 'Unused', 0, cpIgnore, false, false, wbNeverShow),\n      wbByteArray(SCTX, 'Unused', 0, cpIgnore, false, false, wbNeverShow),\n      wbByteArray(QNAM, 'Unused', 0, cpIgnore, false, false, wbNeverShow),\n      wbByteArray(TNAM, 'Unused', 0, cpIgnore, false, false, wbNeverShow),\n      {>>> END leftover from earlier CK versions <<<}\n      wbPDTOs\n    ], [])\n  ], False, nil, cpNormal, False, nil {wbPACKAfterLoad});\n\n  wbQUSTAliasFlags :=\n    wbStruct(FNAM, 'Alias Flags', [\n      wbInteger('Flags', itU16, wbFlags([\n        {0x0001}'Reserves Location/Reference',\n        {0x0002}'Optional',\n        {0x0004}'Quest Object',\n        {0x0008}'Allow Reuse in Quest',\n        {0x0010}'Allow Dead',\n        {0x0020}'Matching Ref - In Loaded Area',\n        {0x0040}'Essential',\n        {0x0080}'Allow Disabled',\n        {0x0100}'Stores Text',\n        {0x0200}'Allow Reserved',\n        {0x0400}'Protected',\n        {0x0800}'Forced by Aliases?',\n        {0x1000}'Allow Destroyed',\n        {0x2000}'Matching Ref - Closest',\n        {0x4000}'Uses Stored Text',\n        {0x8000}'Initially Disabled'\n      ])),\n      wbInteger('Additional Flags', itU16, wbFlags([\n        {0x0001}'Allow Cleared',\n        {0x0002}'Clear Names When Removed'\n      ]))\n    ], cpNormal, False, nil, 1);\n\n  wbRecord(QUST, 'Quest', [\n    wbEDID,\n    wbVMADFragmentedQUST,\n    wbFULL,\n    wbStruct(DNAM, 'General', [\n      wbInteger('Flags', itU16, wbFlags([\n        {0x0001} 'Start Game Enabled',\n        {0x0002} 'Unknown 2',\n        {0x0004} 'Unknown 3',\n        {0x0008} 'Allow repeated stages',\n        {0x0010} 'Unknown 5',\n        {0x0020} 'Unknown 6',\n        {0x0040} 'Unknown 7',\n        {0x0080} 'Unknown 8',\n        {0x0100} 'Run Once',\n        {0x0200} 'Exclude from dialogue export',\n        {0x0400} 'Warn on alias fill failure',\n        {0x0800} 'Unknown 12',\n        {0x1000} 'Unknown 13'\n      ])),\n      wbInteger('Priority', itU8),\n      wbInteger('Form Version', itU8, nil, cpIgnore),\n      wbByteArray('Unknown', 4),\n      wbInteger('Type', itU32, wbEnum([\n        {0} 'None',\n        {1} 'Main Quest',\n        {2} 'Mages'' Guild',\n        {3} 'Thieves'' Guild',\n        {4} 'Dark Brotherhood',\n        {5} 'Companion Quests',\n        {6} 'Miscellaneous',\n        {7} 'Daedric',\n        {8} 'Side Quest',\n        {9} 'Civil War',\n       {10} 'DLC01 - Vampire',\n       {11} 'DLC02 - Dragonborn'\n      ]))\n    ]),\n    wbString(ENAM, 'Event', 4),\n    wbRArray('Text Display Globals', wbFormIDCk(QTGL, 'Global', [GLOB])),\n    wbString(FLTR, 'Object Window Filter', 0, cpTranslate),\n    wbRStruct('Quest Dialogue Conditions', [wbCTDAs], [], cpNormal, False),\n    wbEmpty(NEXT, 'Marker'),\n    wbCTDAs, {>>> Unknown, doesn't show up in CK <<<}\n    wbRArrayS('Stages', wbRStructSK([0], 'Stage', [\n      wbStructSK(INDX, [0], 'Stage Index', [\n        wbInteger('Stage Index', itU16),\n        wbInteger('Flags', itU8, wbFlags([\n          {0x01} 'Unknown 1',\n          {0x02} 'Start Up Stage',\n          {0x04} 'Shut Down Stage',\n          {0x08} 'Keep Instance Data From Here On'\n        ])),\n        wbInteger('Unknown', itU8)\n      ]),\n      wbRArray('Log Entries', wbRStruct('Log Entry', [\n        wbInteger(QSDT, 'Stage Flags', itU8, wbFlags([\n          {0x01} 'Complete Quest',\n          {0x02} 'Fail Quest'\n        ])),\n        wbCTDAs,\n        wbLString(CNAM, 'Log Entry', 0, cpTranslate),\n        wbFormIDCk(NAM0, 'Next Quest', [QUST]),\n        {>>> BEGIN leftover from earlier CK versions <<<}\n        wbByteArray(SCHR, 'Unused', 0, cpIgnore, false, false, wbNeverShow),\n        wbByteArray(SCTX, 'Unused', 0, cpIgnore, false, false, wbNeverShow),\n        wbByteArray(QNAM, 'Unused', 0, cpIgnore, false, false, wbNeverShow)\n        {>>> END leftover from earlier CK versions <<<}\n      ], []))\n    ], [])),\n    wbRArray('Objectives', wbRStruct('Objective', [\n      wbInteger(QOBJ, 'Objective Index', itU16),\n      wbInteger(FNAM, 'Flags', itU32, wbFlags(['ORed With Previous'])),\n      wbLString(NNAM, 'Display Text', 0, cpTranslate, True),\n      wbRArray('Targets', wbRStruct('Target', [\n        wbStruct(QSTA, 'Target', [\n          wbInteger('Alias', itS32, wbQuestAliasToStr, wbStrToAlias),\n          wbInteger('Flags', itU8, wbFlags([\n            {0x01} 'Compass Marker Ignores Locks'\n          ])),\n          wbByteArray('Unused', 3)\n        ]),\n        wbCTDAs\n      ], []))\n    ], [])),\n    wbByteArray(ANAM, 'Aliases Marker', 4),\n    wbRArray('Aliases',\n      wbRUnion('Alias', [\n\n        // Reference Alias\n        wbRStruct('Alias', [\n          wbInteger(ALST, 'Reference Alias ID', itU32),\n          wbString(ALID, 'Alias Name'),\n          wbQUSTAliasFlags,\n          wbInteger(ALFI, 'Force Into Alias When Filled', itS32, wbQuestAliasToStr, wbStrToAlias),\n          wbFormIDCk(ALFL, 'Specific Location', [LCTN]),\n          wbFormID(ALFR, 'Forced Reference'),\n          wbFormIDCk(ALUA, 'Unique Actor', [NPC_]),\n          wbRStruct('Location Alias Reference', [\n            wbInteger(ALFA, 'Alias', itS32, wbQuestAliasToStr, wbStrToAlias),\n            wbFormIDCk(KNAM, 'Keyword', [KYWD]),\n            wbFormIDCk(ALRT, 'Ref Type', [LCRT])\n          ], []),\n          wbRStruct('External Alias Reference', [\n            wbFormIDCk(ALEQ, 'Quest', [QUST]),\n            wbInteger(ALEA, 'Alias', itS32, wbQuestExternalAliasToStr, wbStrToAlias)\n          ], []),\n          wbRStruct('Create Reference to Object', [\n            wbFormID(ALCO, 'Object'),\n            wbStruct(ALCA, 'Alias', [\n              wbInteger('Alias', itS16, wbQuestAliasToStr, wbStrToAlias),\n              wbInteger('Create', itU16, wbEnum([] ,[\n                $0000, 'At',\n                $8000, 'In'\n              ]))\n            ]),\n            wbInteger(ALCL, 'Level', itU32, wbEnum([\n              'Easy',\n              'Medium',\n              'Hard',\n              'Very Hard',\n              'None'\n            ]))\n          ], []),\n          wbRStruct('Find Matching Reference Near Alias', [\n            wbInteger(ALNA, 'Alias', itS32, wbQuestAliasToStr, wbStrToAlias),\n            wbInteger(ALNT, 'Type', itU32, wbEnum([\n              'Linked Ref Child'\n            ]))\n          ], []),\n          wbRStruct('Find Matching Reference From Event', [\n            wbString(ALFE, 'From Event', 4),\n            wbByteArray(ALFD, 'Event Data')\n          ], []),\n          wbCTDAs,\n          wbKSIZ,\n          wbKWDAs,\n          wbCOCT,\n          wbCNTOs,\n          wbFormIDCk(SPOR, 'Spectator override package list', [FLST], False, cpNormal, False),\n          wbFormIDCk(OCOR, 'Observe dead body override package list', [FLST], False, cpNormal, False),\n          wbFormIDCk(GWOR, 'Guard warn override package list', [FLST], False, cpNormal, False),\n          wbFormIDCk(ECOR, 'Combat override package list', [FLST], False, cpNormal, False),\n          wbFormIDCk(ALDN, 'Display Name', [MESG]),\n          wbRArray('Alias Spells', wbFormIDCk(ALSP, 'Spell', [SPEL])),\n          wbRArray('Alias Factions', wbFormIDCk(ALFC, 'Faction', [FACT])),\n          wbRArray('Alias Package Data', wbFormIDCk(ALPC, 'Package', [PACK])),\n          wbFormIDCk(VTCK, 'Voice Types', [NPC_, FLST, NULL]),\n          wbEmpty(ALED, 'Alias End', cpNormal, True)\n        ], [], cpNormal, False, nil, False, nil, wbContainerAfterSet),\n\n        // Location Alias\n        wbRStruct('Alias', [\n          wbInteger(ALLS, 'Location Alias ID', itU32),\n          wbString(ALID, 'Alias Name'),\n          wbQUSTAliasFlags,\n          wbInteger(ALFI, 'Force Into Alias When Filled', itS32, wbQuestAliasToStr, wbStrToAlias),\n          wbFormIDCk(ALFL, 'Specific Location', [LCTN]),\n          wbFormID(ALFR, 'Forced Reference'),\n          wbFormIDCk(ALUA, 'Unique Actor', [NPC_]),\n          wbRStruct('Location Alias Reference', [\n            wbInteger(ALFA, 'Alias', itS32, wbQuestAliasToStr, wbStrToAlias),\n            wbFormIDCk(KNAM, 'Keyword', [KYWD]),\n            wbFormIDCk(ALRT, 'Ref Type', [LCRT])\n          ], []),\n          wbRStruct('External Alias Reference', [\n            wbFormIDCk(ALEQ, 'Quest', [QUST]),\n            wbInteger(ALEA, 'Alias', itS32, wbQuestExternalAliasToStr, wbStrToAlias)\n          ], []),\n          wbRStruct('Create Reference to Object', [\n            wbFormID(ALCO, 'Object'),\n            wbStruct(ALCA, 'Alias', [\n              wbInteger('Alias', itS16, wbQuestAliasToStr, wbStrToAlias),\n              wbInteger('Create', itU16, wbEnum([] ,[\n                $0000, 'At',\n                $8000, 'In'\n              ]))\n            ]),\n            wbInteger(ALCL, 'Level', itU32, wbEnum([\n              'Easy',\n              'Medium',\n              'Hard',\n              'Very Hard',\n              'None'\n            ]))\n          ], []),\n          wbRStruct('Find Matching Reference Near Alias', [\n            wbInteger(ALNA, 'Alias', itS32, wbQuestAliasToStr, wbStrToAlias),\n            wbInteger(ALNT, 'Type', itU32, wbEnum([\n              'Linked Ref Child'\n            ]))\n          ], []),\n          wbRStruct('Find Matching Reference From Event', [\n            wbString(ALFE, 'From Event', 4),\n            wbByteArray(ALFD, 'Event Data')\n          ], []),\n          wbCTDAs,\n          wbKSIZ,\n          wbKWDAs,\n          wbCOCT,\n          wbCNTOs,\n          wbFormIDCk(SPOR, 'Spectator override package list', [FLST], False, cpNormal, False),\n          wbFormIDCk(OCOR, 'Observe dead body override package list', [FLST], False, cpNormal, False),\n          wbFormIDCk(GWOR, 'Guard warn override package list', [FLST], False, cpNormal, False),\n          wbFormIDCk(ECOR, 'Combat override package list', [FLST], False, cpNormal, False),\n          wbFormIDCk(ALDN, 'Display Name', [MESG]),\n          wbRArray('Alias Spells', wbFormIDCk(ALSP, 'Spell', [SPEL])),\n          wbRArray('Alias Factions', wbFormIDCk(ALFC, 'Faction', [FACT])),\n          wbRArray('Alias Package Data', wbFormIDCk(ALPC, 'Package', [PACK])),\n          wbFormIDCk(VTCK, 'Voice Types', [NPC_, FLST, NULL]),\n          wbEmpty(ALED, 'Alias End', cpNormal, True)\n        ], [], cpNormal, False, nil, False, nil, wbContainerAfterSet)\n      ], [])\n    ),\n    wbString(NNAM, 'Description', 0, cpNormal, False),\n    wbRArray('Targets', wbRStruct('Target', [\n      wbStruct(QSTA, 'Target', [\n        wbFormIDCkNoReach('Target', [ACHR, REFR, PGRE, PHZD, PMIS, PARW, PBAR, PBEA, PCON, PFLA], True),\n        wbInteger('Flags', itU8, wbFlags([\n          {0x01} 'Compass Marker Ignores Locks'\n        ])),\n        wbByteArray('Unknown', 3)\n      ]),\n      wbCTDAs\n    ], []))\n  ]);\n\n  wbBodyPartIndexEnum := wbEnum([\n    'Body Texture'\n  ]);\n\n  wbNoseMorphFlags := wbInteger('Nose Morph Flags', itU32, wbFlags([\n    {0x00000001}'NoseType0',\n    {0x00000002}'NoseType1',\n    {0x00000004}'NoseType2',\n    {0x00000008}'NoseType3',\n    {0x00000010}'NoseType4',\n    {0x00000020}'NoseType5',\n    {0x00000040}'NoseType6',\n    {0x00000080}'NoseType7',\n    {0x00000100}'NoseType8',\n    {0x00000200}'NoseType9',\n    {0x00000400}'NoseType10',\n    {0x00000800}'NoseType11',\n    {0x00001000}'NoseType12',\n    {0x00002000}'NoseType13',\n    {0x00004000}'NoseType14',\n    {0x00008000}'NoseType15',\n    {0x00010000}'NoseType16',\n    {0x00020000}'NoseType17',\n    {0x00040000}'NoseType18',\n    {0x00080000}'NoseType19',\n    {0x00100000}'NoseType20',\n    {0x00200000}'NoseType21',\n    {0x00400000}'NoseType22',\n    {0x00800000}'NoseType23',\n    {0x01000000}'NoseType24',\n    {0x02000000}'NoseType25',\n    {0x04000000}'NoseType26',\n    {0x08000000}'NoseType27',\n    {0x10000000}'NoseType28',\n    {0x20000000}'NoseType29',\n    {0x40000000}'NoseType30',\n    {0x80000000}'NoseType31'\n  ]));\n\n  wbBrowMorphFlags := wbInteger('Brow Morph Flags', itU32, wbFlags([\n    {0x00000001}'BrowType0',\n    {0x00000002}'BrowType1',\n    {0x00000004}'BrowType2',\n    {0x00000008}'BrowType3',\n    {0x00000010}'BrowType4',\n    {0x00000020}'BrowType5',\n    {0x00000040}'BrowType6',\n    {0x00000080}'BrowType7',\n    {0x00000100}'BrowType8',\n    {0x00000200}'BrowType9',\n    {0x00000400}'BrowType10',\n    {0x00000800}'BrowType11',\n    {0x00001000}'BrowType12',\n    {0x00002000}'BrowType13',\n    {0x00004000}'BrowType14',\n    {0x00008000}'BrowType15',\n    {0x00010000}'BrowType16',\n    {0x00020000}'BrowType17',\n    {0x00040000}'BrowType18',\n    {0x00080000}'BrowType19',\n    {0x00100000}'BrowType20'\n  ], True));\n\n  wbEyesMorphFlags01 := wbInteger('Eye Morph Flags 1', itU32, wbFlags([\n    {0x00000001}'EyesType0',\n    {0x00000002}'EyesType1',\n    {0x00000004}'EyesType2',\n    {0x00000008}'EyesType3',\n    {0x00000010}'EyesType4',\n    {0x00000020}'EyesType5',\n    {0x00000040}'EyesType6',\n    {0x00000080}'EyesType7',\n    {0x00000100}'EyesType8',\n    {0x00000200}'EyesType9',\n    {0x00000400}'EyesType10',\n    {0x00000800}'EyesType11',\n    {0x00001000}'EyesType12',\n    {0x00002000}'EyesType13',\n    {0x00004000}'EyesType14',\n    {0x00008000}'EyesType15',\n    {0x00010000}'EyesType16',\n    {0x00020000}'EyesType17',\n    {0x00040000}'EyesType18',\n    {0x00080000}'EyesType19',\n    {0x00100000}'EyesType20',\n    {0x00200000}'EyesType21',\n    {0x00400000}'EyesType22',\n    {0x00800000}'EyesType23',\n    {0x01000000}'EyesType24',\n    {0x02000000}'EyesType25',\n    {0x04000000}'EyesType26',\n    {0x08000000}'EyesType27',\n    {0x10000000}'EyesType28',\n    {0x20000000}'EyesType29',\n    {0x40000000}'EyesType30',\n    {0x80000000}'EyesType31'\n  ]));\n\n  wbEyesMorphFlags02 := wbInteger('Eye Morph Flags 2', itU8, wbFlags([\n    {0x00000001}'EyesType32',\n    {0x00000002}'EyesType33',\n    {0x00000004}'EyesType34',\n    {0x00000008}'EyesType35',\n    {0x00000010}'EyesType36',\n    {0x00000020}'EyesType37',\n    {0x00000040}'EyesType38'\n  ], True));\n\n  wbLipMorphFlags := wbInteger('Lip Morph Flags', itU32, wbFlags([\n    {0x00000001}'LipType0',\n    {0x00000002}'LipType1',\n    {0x00000004}'LipType2',\n    {0x00000008}'LipType3',\n    {0x00000010}'LipType4',\n    {0x00000020}'LipType5',\n    {0x00000040}'LipType6',\n    {0x00000080}'LipType7',\n    {0x00000100}'LipType8',\n    {0x00000200}'LipType9',\n    {0x00000400}'LipType10',\n    {0x00000800}'LipType11',\n    {0x00001000}'LipType12',\n    {0x00002000}'LipType13',\n    {0x00004000}'LipType14',\n    {0x00008000}'LipType15',\n    {0x00010000}'LipType16',\n    {0x00020000}'LipType17',\n    {0x00040000}'LipType18',\n    {0x00080000}'LipType19',\n    {0x00100000}'LipType20',\n    {0x00200000}'LipType21',\n    {0x00400000}'LipType22',\n    {0x00800000}'LipType23',\n    {0x01000000}'LipType24',\n    {0x02000000}'LipType25',\n    {0x04000000}'LipType26',\n    {0x08000000}'LipType27',\n    {0x10000000}'LipType28',\n    {0x20000000}'LipType29',\n    {0x40000000}'LipType30',\n    {0x80000000}'LipType31'\n  ]));\n\n  wbTintMaskTypeEnum := wbEnum([\n    'None',\n    'Lip Color',\n    'Cheek Color',\n    'Eyeliner',\n    'EyeSocket Upper',\n    'EyeSocket Lower',\n    'Skin Tone',\n    'Paint',\n    'Laugh Lines',\n    'Cheek Color Lower',\n    'Nose',\n    'Chin',\n    'Neck',\n    'Forehead',\n    'Dirt',\n    'Unknown 16'\n  ]);\n\n  wbTints := wbRArray('Tint Masks', wbRStruct('Tint Assets', [\n    wbRArray('Tint Layer', wbRStruct('Texture', [\n      wbInteger(TINI, 'Index', itU16),\n      wbString(TINT, 'File Name'),\n      {>>> When set to None TINP does not exist Needs routine to add when\n      changing the Mask Type <<<}\n      wbInteger(TINP, 'Mask Type', itU16, wbTintMaskTypeEnum),\n      wbFormIDCk(TIND, 'Preset Default', [CLFM, NULL])\n    ], [])),\n    wbRArray('Presets', wbRStruct('Preset', [\n      wbFormIDCk(TINC, 'Color', [CLFM, NULL]),\n\t\t\twbFloat(TINV, 'Default Value'),\n      wbInteger(TIRS, 'Index', itU16)\n    ], []))\n  ], []));\n\n  wbRACE_DATAFlags01 := wbInteger('Flags', itU32, wbFlags([\n    {0x00000001}'Playable',\n    {0x00000002}'FaceGen Head',\n    {0x00000004}'Child',\n    {0x00000008}'Tilt Front/Back',\n    {0x00000010}'Tilt Left/Right',\n    {0x00000020}'No Shadow',\n    {0x00000040}'Swims',\n    {0x00000080}'Flies',\n    {0x00000100}'Walks',\n    {0x00000200}'Immobile',\n    {0x00000400}'Not Pushable',\n    {0x00000800}'No Combat In Water',\n    {0x00001000}'No Rotating to Head-Track',\n    {0x00002000}'Don''t Show Blood Spray',\n    {0x00004000}'Don''t Show Blood Decal',\n    {0x00008000}'Uses Head Track Anims',\n    {0x00010000}'Spells Align w/Magic Node',\n    {0x00020000}'Use World Raycasts For FootIK',\n    {0x00040000}'Allow Ragdoll Collision',\n    {0x00080000}'Regen HP In Combat',\n    {0x00100000}'Can''t Open Doors',\n    {0x00200000}'Allow PC Dialogue',\n    {0x00400000}'No Knockdowns',\n    {0x00800000}'Allow Pickpocket',\n    {0x01000000}'Always Use Proxy Controller',\n    {0x02000000}'Don''t Show Weapon Blood',\n    {0x04000000}'Overlay Head Part List', {>>>Only one can be active<<<}\n    {0x08000000}'Override Head Part List', {>>>Only one can be active<<<}\n    {0x10000000}'Can Pickup Items',\n    {0x20000000}'Allow Multiple Membrane Shaders',\n    {0x40000000}'Can Dual Wield',\n    {0x80000000}'Avoids Roads'\n  ]));\n\n  wbPhonemeTargets := wbStruct(PHWT, 'Phoneme Target Weight', [\n    wbFloat('Aah / LipBigAah'),\n    wbFloat('BigAah / LipDST'),\n    wbFloat('BMP / LipEee'),\n    wbFloat('ChJsh / LipFV'),\n    wbFloat('DST / LipK'),\n    wbFloat('Eee / LipL'),\n    wbFloat('Eh / LipR'),\n    wbFloat('FV / LipTh'),\n    wbFloat('I'),\n    wbFloat('K'),\n    wbFloat('N'),\n    wbFloat('Oh'),\n    wbFloat('OohQ'),\n    wbFloat('R'),\n    wbFloat('TH'),\n    wbFloat('W')\n  ], cpNormal, False, nil, 8);\n\n  wbPHWT := wbRStruct('FaceFX Phonemes', [\n    wbRStruct('IY', [wbPhonemeTargets], []),\n    wbRStruct('IH', [wbPhonemeTargets], []),\n    wbRStruct('EH', [wbPhonemeTargets], []),\n    wbRStruct('EY', [wbPhonemeTargets], []),\n    wbRStruct('AE', [wbPhonemeTargets], []),\n    wbRStruct('AA', [wbPhonemeTargets], []),\n    wbRStruct('AW', [wbPhonemeTargets], []),\n    wbRStruct('AY', [wbPhonemeTargets], []),\n    wbRStruct('AH', [wbPhonemeTargets], []),\n    wbRStruct('AO', [wbPhonemeTargets], []),\n    wbRStruct('OY', [wbPhonemeTargets], []),\n    wbRStruct('OW', [wbPhonemeTargets], []),\n    wbRStruct('UH', [wbPhonemeTargets], []),\n    wbRStruct('UW', [wbPhonemeTargets], []),\n    wbRStruct('ER', [wbPhonemeTargets], []),\n    wbRStruct('AX', [wbPhonemeTargets], []),\n    wbRStruct('S',  [wbPhonemeTargets], []),\n    wbRStruct('SH', [wbPhonemeTargets], []),\n    wbRStruct('Z',  [wbPhonemeTargets], []),\n    wbRStruct('ZH', [wbPhonemeTargets], []),\n    wbRStruct('F',  [wbPhonemeTargets], []),\n    wbRStruct('TH', [wbPhonemeTargets], []),\n    wbRStruct('V',  [wbPhonemeTargets], []),\n    wbRStruct('DH', [wbPhonemeTargets], []),\n    wbRStruct('M',  [wbPhonemeTargets], []),\n    wbRStruct('N',  [wbPhonemeTargets], []),\n    wbRStruct('NG', [wbPhonemeTargets], []),\n    wbRStruct('L',  [wbPhonemeTargets], []),\n    wbRStruct('R',  [wbPhonemeTargets], []),\n    wbRStruct('W',  [wbPhonemeTargets], []),\n    wbRStruct('Y',  [wbPhonemeTargets], []),\n    wbRStruct('HH', [wbPhonemeTargets], []),\n    wbRStruct('B',  [wbPhonemeTargets], []),\n    wbRStruct('D',  [wbPhonemeTargets], []),\n    wbRStruct('JH', [wbPhonemeTargets], []),\n    wbRStruct('G',  [wbPhonemeTargets], []),\n    wbRStruct('P',  [wbPhonemeTargets], []),\n    wbRStruct('T',  [wbPhonemeTargets], []),\n    wbRStruct('K',  [wbPhonemeTargets], []),\n    wbRStruct('CH', [wbPhonemeTargets], []),\n    wbRStruct('SIL', [wbPhonemeTargets], []),\n    wbRStruct('SHOTSIL', [wbPhonemeTargets], []),\n    wbRStruct('FLAP', [wbPhonemeTargets], [])\n  ], []);\n\n  wbMorphs := wbRStruct('Available Morphs', [\n    wbByteArray(MPAI, 'Unknown', 0),\n    wbStruct(MPAV, 'Nose Variants', [\n      wbNoseMorphFlags,\n      wbByteArray('Unknown', 4),\n      wbByteArray('Unknown', 4),\n      wbByteArray('Unknown', 4),\n      wbByteArray('Unknown', 4),\n      wbByteArray('Unknown', 4),\n      wbByteArray('Unknown', 4),\n      wbByteArray('Unknown', 4)\n    ]),\n    wbByteArray(MPAI, 'Unknown', 0),\n    wbStruct(MPAV, 'Brow Variants', [\n      wbBrowMorphFlags,\n      wbByteArray('Unknown', 4),\n      wbByteArray('Unknown', 4),\n      wbByteArray('Unknown', 4),\n      wbByteArray('Unknown', 4),\n      wbByteArray('Unknown', 4),\n      wbByteArray('Unknown', 4),\n      wbByteArray('Unknown', 4)\n    ]),\n    wbByteArray(MPAI, 'Unknown', 0),\n    wbStruct(MPAV, 'Eye Variants', [\n      wbEyesMorphFlags01,\n      wbEyesMorphFlags02,\n      wbByteArray('Unknown', 3),\n      wbByteArray('Unknown', 4),\n      wbByteArray('Unknown', 4),\n      wbByteArray('Unknown', 4),\n      wbByteArray('Unknown', 4),\n      wbByteArray('Unknown', 4),\n      wbByteArray('Unknown', 4)\n    ]),\n    wbByteArray(MPAI, 'Unknown', 0),\n    wbStruct(MPAV, 'Lip Variants', [\n      wbLipMorphFlags,\n      wbByteArray('Unknown', 4),\n      wbByteArray('Unknown', 4),\n      wbByteArray('Unknown', 4),\n      wbByteArray('Unknown', 4),\n      wbByteArray('Unknown', 4),\n      wbByteArray('Unknown', 4),\n      wbByteArray('Unknown', 4)\n    ])\n  ], []);\n\n  wbHeadPart := wbRStructSK([0],'Head Part', [\n    wbInteger(INDX, 'Head Part Number', itU32),\n    wbFormIDCk(HEAD, 'Head', [HDPT, NULL])\n  ], []);\n\n  wbRecord(RACE, 'Race',\n    wbFlags(wbRecordFlagsFlags, wbFlagsList([\n      {0x00080000} 19, 'Critter?'\n    ])), [\n    wbEDID,\n    wbFULL,\n    wbDESCReq,\n    wbSPCT,\n    wbSPLOs,\n    wbFormIDCk(WNAM, 'Skin', [ARMO, NULL]),\n//    wbBODT,\n//    wbBOD2,\n    wbBODTBOD2,\n    wbKSIZ,\n    wbKWDAs,\n    wbStruct(DATA, '', [\n      wbArrayS('Skill Boosts', wbStructSK([0], 'Skill Boost', [\n        wbInteger('Skill', itS8, wbActorValueEnum),\n        wbInteger('Boost', itS8)\n      ]), 7),\n      wbByteArray('Unknown', 2),\n      wbFloat('Male Height'),\n      wbFloat('Female Height'),\n      wbFloat('Male Weight'),\n      wbFloat('Female Weight'),\n      wbRACE_DATAFlags01,\n      wbFloat('Starting Health'),\n      wbFloat('Starting Magicka'),\n      wbFloat('Starting Stamina'),\n      wbFloat('Base Carry Weight'),\n      wbFloat('Base Mass'),\n      wbFloat('Acceleration rate'),\n      wbFloat('Deceleration rate'),\n      wbInteger('Size', itU32, wbEnum([\n        'Small',\n        'Medium',\n        'Large',\n        'Extra Large'\n      ])),\n      wbInteger('Head Biped Object', itS32, wbBipedObjectEnum),\n      wbInteger('Hair Biped Object', itS32, wbBipedObjectEnum),\n      wbFloat('Injured Health Pct'),\n      wbInteger('Shield Biped Object', itS32, wbBipedObjectEnum),\n      wbFloat('Health Regen'),\n      wbFloat('Magicka Regen'),\n      wbFloat('Stamina Regen'),\n      wbFloat('Unarmed Damage'),\n      wbFloat('Unarmed Reach'),\n      wbInteger('Body Biped Object', itS32, wbBipedObjectEnum),\n      wbFloat('Aim Angle Tolerance'),\n      wbFloat('Flight Radius'),\n      wbFloat('Angular Acceleration Rate'),\n      wbFloat('Angular Tolerance'),\n      wbInteger('Flags 2', itU32, wbFlags([\n        {0x00000001} 'Use Advanced Avoidance',\n        {0x00000002} 'Non-Hostile',\n        {0x00000004} 'Unknown 2',\n        {0x00000008} 'Unknown 3',\n        {0x00000010} 'Allow Mounted Combat'\n      ])),\n      wbStruct('Mount Data', [\n        wbFloat('Offset X', cpNormal, False, 1, -1, nil, nil, -63.479000),\n        wbFloat('Offset Y'),\n        wbFloat('Unknown'),\n        wbFloat('Unknown', cpNormal, False, 1, -1, nil, nil, -50.0),\n        wbFloat('Unknown'),\n        wbFloat('Unknown', cpNormal, False, 1, -1, nil, nil, 65.0),\n        wbFloat('Unknown'),\n        wbFloat('Unknown', cpNormal, False, 1, -1, nil, nil, -300.0),\n        wbFloat('Unknown')\n      ])\n      //wbByteArray('Unknown', 4*7)\n    ], cpNormal, True, nil, 29),\n    wbEmpty(MNAM, 'Male Marker'),\n    wbString(ANAM, 'Male Skeletal Model'),\n    wbMODT,\n    wbEmpty(FNAM, 'Female Marker'),\n    wbString(ANAM, 'Female Skeletal Model'),\n    wbMODT,\n    wbEmpty(NAM2, 'Marker NAM2 #1'),\n    wbRArrayS('Movement Type Names', wbString(MTNM, 'Name')),\n    wbArray(VTCK, 'Voices', wbFormIDCk('Voice', [VTYP]), ['Male', 'Female'], cpNormal, True),\n    wbArray(DNAM, 'Decapitate Armors', wbFormIDCk('Decapitate Armor', [NULL, ARMO]), ['Male', 'Female'], cpNormal, False),\n    wbArray(HCLF, 'Default Hair Colors', wbFormIDCk('Default Hair Color', [NULL, CLFM]), ['Male', 'Female'], cpNormal, False),\n    wbInteger(TINL, 'Total Number of Tints in List', itU16, nil, nil, cpNormal, False), {>>> Needs Count Updated <<<}\n    wbFloat(PNAM, 'FaceGen - Main clamp', cpNormal, True),\n    wbFloat(UNAM, 'FaceGen - Face clamp', cpNormal, True),\n    wbFormIDCk(ATKR, 'Attack Race', [RACE], False, cpNormal, False),\n    wbRArrayS('Attacks', wbAttackData),\n    wbRStruct('Body Data', [\n      wbEmpty(NAM1, 'Body Data Marker', cpNormal, True),\n      wbRStruct('Male Body Data', [\n        wbEmpty(MNAM, 'Male Data Marker'),\n        wbRArrayS('Parts', wbRStructSK([0], 'Part', [\n          wbInteger(INDX, 'Index', itU32, wbBodyPartIndexEnum),\n          wbMODL\n        ], []), cpNormal, True)\n      ], [], cpNormal, True),\n      wbRStruct('Female Body Data', [\n        wbEmpty(FNAM, 'Female Data Marker', cpNormal, True),\n        wbRArrayS('Parts', wbRStructSK([0], 'Part', [\n          wbInteger(INDX, 'Index', itU32, wbBodyPartIndexEnum),\n          wbMODL\n        ], []), cpNormal, True)\n      ], [], cpNormal, True)\n    ], [], cpNormal, True),\n    wbArrayS(HNAM, 'Hairs', wbFormIDCk('Hair', [HDPT, NULL]), 0, cpNormal),\n    wbArrayS(ENAM, 'Eyes', wbFormIDCk('Eye', [EYES, NULL]),  0,  cpNormal),\n    wbFormIDCk(GNAM, 'Body Part Data', [BPTD, NULL]),\n\t  wbEmpty(NAM2, 'Marker NAM2 #2', cpNormal),\n\t  wbEmpty(NAM3, 'Marker NAM3 #3', cpNormal, True),\n    wbRStruct('Male Behavior Graph', [\n      wbEmpty(MNAM, 'Male Data Marker'),\n      wbMODL\n    ], [], cpNormal, True),\n    wbRStruct('Female Behavior Graph', [\n      wbEmpty(FNAM, 'Female Data Marker', cpNormal, True),\n      wbMODL\n    ], [], cpNormal, True),\n    wbFormIDCk(NAM4, 'Material Type', [MATT, NULL]),\n    wbFormIDCk(NAM5, 'Impact Data Set', [IPDS, NULL]),\n\t\twbFormIDCk(NAM7, 'Decapitation FX', [ARTO, NULL]),\n    wbFormIDCk(ONAM, 'Open Loot Sound', [SNDR, NULL]),\n    wbFormIDCk(LNAM, 'Close Loot Sound', [SNDR, NULL]),\n    {>>> When NAME is user defined wbBipedObjectEnum will be incorrect <<<}\n    wbRArray('Biped Object Names', wbString(NAME, 'Name')),\n    wbRArrayS('Movement Types', wbRStructSK([0], 'Movement Types', [\n      wbFormIDCk(MTYP, 'Movement Type', [MOVT, NULL]),\n      wbStruct(SPED, 'Override Values', [\n        wbFloat('Left - Walk'),\n        wbFloat('Left - Run'),\n        wbFloat('Right - Walk'),\n        wbFloat('Right - Run'),\n        wbFloat('Forward - Walk'),\n        wbFloat('Forward - Run'),\n        wbFloat('Back - Walk'),\n        wbFloat('Back - Run'),\n        wbFloat('Rotate - Walk'),\n        wbFloat('Rotate - Walk'),\n        wbFloat('Unknown')\n      ])\n    ], [])),\n    wbInteger(VNAM, 'Equipment Flags', itU32, wbEquipType),\n    wbRArrayS('Equip Slots', wbFormIDCk(QNAM, 'Equip Slot', [EQUP, NULL])),\n    wbFormIDCk(UNES, 'Unarmed Equip Slot', [EQUP, NULL]),\n    wbRArray('Phoneme Target Names', wbString(PHTN, 'Name')),\n    wbPHWT,\n    wbFormIDCk(WKMV, 'Base Movement Default - Walk', [MOVT, NULL]),\n    wbFormIDCk(RNMV, 'Base Movement Default - Run', [MOVT, NULL]),\n    wbFormIDCk(SWMV, 'Base Movement Default - Swim', [MOVT, NULL]),\n    wbFormIDCk(FLMV, 'Base Movement Default - Fly', [MOVT, NULL]),\n    wbFormIDCk(SNMV, 'Base Movement Default - Sneak', [MOVT, NULL]),\n    wbFormIDCk(SPMV, 'Base Movement Default - Sprint', [MOVT, NULL]),\n    // Start Head Data\n    wbRStruct('Head Data', [\n      wbEmpty(NAM0, 'Head Data Marker', cpNormal, True),\n      wbRStruct('Male Head Data', [\n        wbEmpty(MNAM, 'Male Data Marker', cpNormal, True),\n          wbRArrayS('Head Parts', wbHeadPart),\n          wbMorphs,\n          wbRArrayS('Race Presets Male', wbFormIDCk(RPRM, 'Preset NPC', [NPC_, NULL])),\n          wbRArrayS('Available Hair Colors Male', wbFormIDCk(AHCM, 'Hair Color', [CLFM, NULL])),\n          wbRArrayS('Face Details Texture Set List Male', wbFormIDCk(FTSM, 'Texture Set', [TXST, NULL])),\n          wbFormIDCk(DFTM, 'Default Face Texture Male', [TXST, NULL]),\n          wbTints,\n          wbMODL\n      ], [], cpNormal, True),\n      wbRStruct('Female Head Data', [\n        wbEmpty(NAM0, 'Head Data Marker', cpNormal, True),\n        wbEmpty(FNAM, 'Female Data Marker', cpNormal, True),\n          wbRArrayS('Head Parts', wbHeadPart),\n          wbMorphs,\n          wbRArrayS('Race Presets Female', wbFormIDCk(RPRF, 'Preset NPC', [NPC_, NULL])),\n          wbRArrayS('Available Hair Colors Female', wbFormIDCk(AHCF, 'Hair Color', [CLFM, NULL])),\n          wbRArrayS('Face Details Texture Set List Female', wbFormIDCk(FTSF, 'Texture Set', [TXST, NULL])),\n          wbFormIDCk(DFTF, 'Default Face Texture Female', [TXST, NULL]),\n          wbTints,\n          wbMODL\n      ], [], cpNormal, True)\n    ], [], cpNormal, False),\n    // End Head Data\n    wbFormIDCk(NAM8, 'Morph race', [RACE, NULL]),\n    wbFormIDCk(RNAM, 'Armor race', [RACE, NULL])\n  ], False, nil, cpNormal, False, wbRACEAfterLoad, wbRACEAfterSet);\n\n\n  wbRecord(REFR, 'Placed Object', wbFormaterUnion(wbREFRRecordFlagsDecider, [\n    wbFlags(wbRecordFlagsFlags, wbFlagsList([\n      {0x00000400} 10, 'Persistent',\n      {0x00000800} 11, 'Initially Disabled',\n      {0x00010000} 16, 'Is Full LOD',\n      {0x04000000} 26, 'Filter (Collision Geometry)',\n      {0x08000000} 27, 'Bounding Box (Collision Geometry)',\n      {0x10000000} 28, 'Reflected By Auto Water',\n      {0x40000000} 30, 'Ground',\n      {0x80000000} 31, 'Multibound'\n    ], True, True)),\n    {ACTI STAT TREE} wbFlags(wbRecordFlagsFlags, wbFlagsList([\n      {0x00000200}  9, 'Hidden From Local Map',\n      {0x00000400} 10, 'Persistent',\n      {0x00000800} 11, 'Initially Disabled',\n      {0x00008000} 15, 'Visible when distant',\n      {0x00010000} 16, 'Is Full LOD',\n      {0x04000000} 26, 'Filter (Collision Geometry)',\n      {0x08000000} 27, 'Bounding Box (Collision Geometry)',\n      {0x10000000} 28, 'Reflected By Auto Water',\n      {0x20000000} 29, 'Don''t Havok Settle',\n      {0x40000000} 30, 'No Respawn',\n      {0x80000000} 31, 'Multibound'\n    ], True, True)),\n    {CONT} wbFlags(wbRecordFlagsFlags, wbFlagsList([\n      {0x00000400} 10, 'Persistent',\n      {0x00000800} 11, 'Initially Disabled',\n      {0x00010000} 16, 'Is Full LOD',\n      {0x02000000} 25, 'No AI Acquire',\n      {0x04000000} 26, 'Filter (Collision Geometry)',\n      {0x08000000} 27, 'Bounding Box (Collision Geometry)',\n      {0x10000000} 28, 'Reflected By Auto Water',\n      {0x20000000} 29, 'Don''t Havok Settle',\n      {0x40000000} 30, 'Ground',\n      {0x80000000} 31, 'Multibound'\n    ], True, True)),\n    {DOOR} wbFlags(wbRecordFlagsFlags, wbFlagsList([\n      {0x00000040}  6, 'Hidden From Local Map',\n      {0x00000100}  8, 'Inaccessible',\n      {0x00000400} 10, 'Persistent',\n      {0x00000800} 11, 'Initially Disabled',\n      {0x00010000} 16, 'Is Full LOD',\n      {0x04000000} 26, 'Filter (Collision Geometry)',\n      {0x08000000} 27, 'Bounding Box (Collision Geometry)',\n      {0x10000000} 28, 'Reflected By Auto Water',\n      {0x20000000} 29, 'Don''t Havok Settle',\n      {0x40000000} 30, 'No Respawn',\n      {0x80000000} 31, 'Multibound'\n    ], True, True)),\n    {LIGH} wbFlags(wbRecordFlagsFlags, wbFlagsList([\n      {0x00000100}  8, 'Doesn''t Light Water',\n      {0x00000200}  9, 'Casts Shadows',\n      {0x00000400} 10, 'Persistent',\n      {0x00000800} 11, 'Initially Disabled',\n      {0x00010000} 16, 'Never Fades',\n      {0x00020000} 17, 'Doesn''t Light Landscape',\n      {0x02000000} 25, 'No AI Acquire',\n      {0x10000000} 28, 'Reflected By Auto Water',\n      {0x20000000} 29, 'Don''t Havok Settle',\n      {0x40000000} 30, 'No Respawn',\n      {0x80000000} 31, 'Multibound'\n    ], True, True)),\n    {MSTT} wbFlags(wbRecordFlagsFlags, wbFlagsList([\n      {0x00000200}  9, 'Motion Blur',\n      {0x00000400} 10, 'Persistent',\n      {0x00000800} 11, 'Initially Disabled',\n      {0x00010000} 16, 'Is Full LOD',\n      {0x04000000} 26, 'Filter (Collision Geometry)',\n      {0x08000000} 27, 'Bounding Box (Collision Geometry)',\n      {0x10000000} 28, 'Reflected By Auto Water',\n      {0x20000000} 29, 'Don''t Havok Settle',\n      {0x40000000} 30, 'No Respawn',\n      {0x80000000} 31, 'Multibound'\n    ], True, True)),\n    {ADDN} wbFlags(wbRecordFlagsFlags, wbFlagsList([\n      {0x00000400} 10, 'Persistent',\n      {0x00000800} 11, 'Initially Disabled',\n      {0x00010000} 16, 'Is Full LOD',\n      {0x10000000} 28, 'Reflected By Auto Water',\n      {0x20000000} 29, 'Don''t Havok Settle',\n      {0x40000000} 30, 'No Respawn',\n      {0x80000000} 31, 'Multibound'\n    ], True, True)),\n    {ALCH SCRL AMMO ARMO INGR KEYM MISC SLGM WEAP}\n    wbFlags(wbRecordFlagsFlags, wbFlagsList([\n      {0x00000400} 10, 'Persistent',\n      {0x00000800} 11, 'Initially Disabled',\n      {0x00010000} 16, 'Is Full LOD',\n      {0x02000000} 25, 'No AI Acquire',\n      {0x10000000} 28, 'Reflected By Auto Water',\n      {0x20000000} 29, 'Don''t Havok Settle',\n      {0x40000000} 30, 'No Respawn',\n      {0x80000000} 31, 'Multibound'\n    ], True, True))\n  ]), [\n    wbEDID,\n    wbVMAD,\n    wbFormIDCk(NAME, 'Base', [\n      TREE, SNDR, ACTI, DOOR, STAT, FURN, CONT, ARMO, AMMO, LVLN, LVLC,\n      MISC, WEAP, BOOK, KEYM, ALCH, LIGH, GRAS, ASPC, IDLM, ARMA, INGR,\n      MSTT, TACT, TXST, FLOR, SLGM, SCRL, SOUN, APPA, SPEL, ARTO, ADDN\n    ], False, cpNormal, True),\n\n    {--- Bound Contents ---}\n    {--- Bound Data ---}\n    wbStruct(XMBO, 'Bound Half Extents', [\n      wbFloat('X'),\n      wbFloat('Y'),\n      wbFloat('Z')\n    ]),\n\n    {--- Primitive ---}\n    wbStruct(XPRM, 'Primitive', [\n      wbStruct('Bounds', [\n        wbFloat('X', cpNormal, True, 2, 4),\n        wbFloat('Y', cpNormal, True, 2, 4),\n        wbFloat('Z', cpNormal, True, 2, 4)\n      ]),\n      wbStruct('Color', [\n        {84} wbFloat('Red', cpNormal, False, 255, 0),\n        {88} wbFloat('Green', cpNormal, False, 255, 0),\n        {92} wbFloat('Blue', cpNormal, False, 255, 0)\n      ]),\n      wbFloat('Unknown'),\n      wbInteger('Type', itU32, wbEnum([\n        'None',\n        'Box',\n        'Sphere',\n        'Portal Box',\n        'Unknown 4'\n      ]))\n    ]),\n    wbUnknown(XORD),\n    wbStruct(XOCP, 'Occlusion Plane Data', [\n      wbStruct('Size', [\n        wbFloat('Width', cpNormal, False, 2),\n        wbFloat('Height', cpNormal, False, 2)\n      ]),\n      wbStruct('Position', [\n        wbFloat('X'),\n        wbFloat('Y'),\n        wbFloat('Z')\n      ]),\n      wbStruct('Rotation (Quaternion?)', [\n        wbFloat('q1'),\n        wbFloat('q2'),\n        wbFloat('q3'),\n        wbFloat('q4')\n      ])\n    ]),\n\n    wbArray(XPOD, 'Portal Data', wbStruct('References', [\n      wbFormIDCk('Origin', [REFR, NULL]),\n      wbFormIDCk('Destination', [REFR, NULL])\n    ])),\n    wbStruct(XPTL, 'Room Portal (unused)', [\n      wbStruct('Size', [\n        wbFloat('Width', cpNormal, False, 2),\n        wbFloat('Height', cpNormal, False, 2)\n      ]),\n      wbStruct('Position', [\n        wbFloat('X'),\n        wbFloat('Y'),\n        wbFloat('Z')\n      ]),\n      wbStruct('Rotation (Quaternion?)', [\n        wbFloat('q1'),\n        wbFloat('q2'),\n        wbFloat('q3'),\n        wbFloat('q4')\n      ])\n    ], cpIgnore), // removed by CK\n\n    wbRStruct('Bound Data', [\n      wbStruct(XRMR, 'Header', [\n        wbInteger('Linked Rooms Count', itU8),\n        wbInteger('Flags', itU8, wbFlags([\n          'Unknown 1',\n          'Unknown 2',\n          'Unknown 3',\n          'Unknown 4',\n          'Unknown 5',\n          'Unknown 6',\n          'Has Image Space',\n          'Has Lighting Template'\n        ])),\n        wbByteArray('Unknown', 2)\n      ]),\n      wbFormIDCk(LNAM, 'Lighting Template', [LGTM]),\n      wbFormIDCk(INAM, 'Image Space', [IMGS]),\n      wbRArrayS('Linked Rooms',\n        wbFormIDCk(XLRM, 'Linked Room', [REFR])\n      )\n    ], []),\n    wbEmpty(XMBP, 'MultiBound Primitive Marker', cpIgnore),\n\n    wbXRGD,\n    wbXRGB,\n    wbFloat(XRDS, 'Radius'),\n\n    {--- Reflected By / Refracted By ---}\n    wbRArrayS('Reflected/Refracted By',\n      wbStructSK(XPWR, [0], 'Water', [\n        wbFormIDCk('Reference', [REFR]),\n        wbInteger('Type', itU32, wbFlags([\n          'Reflection',\n          'Refraction'\n        ]))\n      ], cpNormal, False, nil, 1)\n    ),\n\n    {--- Lit Water ---}\n    wbRArrayS('Lit Water',\n      wbFormIDCk(XLTW, 'Water', [REFR])\n    ),\n\n    {--- Emittance ---}\n    wbFormIDCk(XEMI, 'Emittance', [LIGH, REGN]),\n\t\twbStruct(XLIG, 'Light Data', [\n      wbFloat('FOV 90+/-'),\n      wbFloat('Fade 1.35+/-'),\n      wbByteArray('Unknown', 4),\n      wbFloat('Shadow Depth Bias'),\n      wbByteArray('Unknown', 4) // optional\n    ], cpNormal, False, nil, 4),\n\t\twbStruct(XALP, 'Alpha', [\n      wbInteger('Cutoff', itU8),\n      wbInteger('Base', itU8)\n    ]),\n\n    {--- Teleport ---}\n    wbStruct(XTEL, 'Teleport Destination', [\n      wbFormIDCk('Door', [REFR], True),\n      wbPosRot,\n      wbInteger('Flags', itU32, wbFlags([\n        'No Alarm'\n      ]))\n    ]),\n    wbFormIDCk(XTNM, 'Teleport Message Box', [MESG]),\n\n    {--- MultiBound ---}\n    wbFormIDCk(XMBR, 'MultiBound Reference', [REFR]),\n\n    wbByteArray(XWCN, 'Unknown', 0, cpIgnore), // leftover\n    wbByteArray(XWCS, 'Unknown', 0, cpIgnore), // leftover\n    wbStruct(XWCU, 'Water Velocity', [\n      wbFloat('X Offset'),\n      wbFloat('Y Offset'),\n      wbFloat('Z Offset'),\n      wbByteArray('Unknown', 4),\n      wbFloat('X Angle'),\n      wbFloat('Y Angle'),\n      wbFloat('Z Angle'),\n      wbByteArray('Unknown', 0)\n    ]),\n\n    wbStruct(XCVL, 'Unknown', [\n\t\t\twbByteArray('Unknown', 4),\n\t\t\twbFloat('X Angle'),\n\t\t\twbByteArray('Unknown', 4)\n    ]),\n    wbFormIDCk(XCZR, 'Unknown', [PLYR, ACHR, REFR, PGRE, PHZD, PMIS, PARW, PBAR, PBEA, PCON, PFLA, NULL]),\n    wbUnknown(XCZA),\n    wbFormIDCk(XCZC, 'Unknown', [CELL, NULL]),\n    wbXSCL,\n    wbFormIDCk(XSPC, 'Spawn Container', [REFR]),\n\n    {--- Activate Parents ---}\n    wbRStruct('Activate Parents', [\n      wbInteger(XAPD, 'Flags', itU8, wbFlags([\n        'Parent Activate Only'\n      ], True)),\n      wbRArrayS('Activate Parent Refs',\n        wbStructSK(XAPR, [0], 'Activate Parent Ref', [\n          wbFormIDCk('Reference', [PLYR, ACHR, REFR, PGRE, PHZD, PMIS, PARW, PBAR, PBEA, PCON, PFLA]),\n          wbFloat('Delay')\n        ])\n      )\n    ], []),\n\n    wbFormIDCk(XLIB, 'Leveled Item Base Object', [LVLI]),\n    wbXLCM,\n    wbFormIDCk(XLCN, 'Persistent Location', [LCTN]),\n\n    {>>> COLL form Index value <<<}\n    wbInteger(XTRI, 'Collision Layer', itU32),\n\n    {--- Lock ---}\n    {>>Lock Tab for REFR when 'Locked' is Unchecked this record is not present <<<}\n    wbStruct(XLOC, 'Lock Data', [\n      wbInteger('Level', itU8, wbEnum([], [\n         1, 'Novice',\n        25, 'Apprentice',\n        50, 'Adept',\n        75, 'Expert',\n       100, 'Master',\n       255, 'Requires Key'\n      ])),\n      wbByteArray('Unused', 3, cpIgnore),\n      wbFormIDCkNoReach('Key', [KEYM, NULL]),\n      wbInteger('Flags', itU8, wbFlags(['', '', 'Leveled Lock'])),\n      wbByteArray('Unused', 3, cpIgnore),\n      wbByteArray('Unused', 8, cpIgnore)\n    ], cpNormal, False, nil, 4),\n\n    wbFormIDCk(XEZN, 'Encounter Zone', [ECZN]),\n\n    {--- Generated Data ---}\n    wbStruct(XNDP, 'Navigation Door Link', [\n      wbFormIDCk('Navigation Mesh', [NAVM]),\n      wbInteger('Teleport Marker Triangle', itS16, wbREFRNavmeshTriangleToStr, wbStringToInt),\n      wbByteArray('Unused', 2, cpIgnore)\n    ]),\n\n    wbArray(XLRT, 'Location Ref Type', wbFormIDCk('Ref', [LCRT, NULL])),\n    wbEmpty(XIS2, 'Ignored by Sandbox'),\n\n    {--- Ownership ---}\n    wbOwnership,\n\n    wbInteger(XCNT, 'Item Count', itS32),\n    wbFloat(XCHG, 'Charge'),\n    wbFormIDCk(XLRL, 'Location Reference', [LCRT, LCTN, NULL], False, cpBenignIfAdded),\n\n    wbXESP,\n    wbRArray('Linked References', wbStruct(XLKR, 'Linked Reference', [\n      wbFormIDCk('Keyword/Ref', [KYWD, PLYR, ACHR, REFR, PGRE, PHZD, PMIS, PARW, PBAR, PBEA, PCON, PFLA, NULL]),\n      wbFormIDCk('Ref', [PLYR, ACHR, REFR, PGRE, PHZD, PMIS, PARW, PBAR, PBEA, PCON, PFLA])\n    ], cpNormal, False, nil, 1)),\n\n    wbRArray('Patrol', wbRStruct('Data', [\n      wbFloat(XPRD, 'Idle Time', cpNormal, True),\n      wbEmpty(XPPA, 'Patrol Script Marker', cpNormal, True),\n      wbFormIDCk(INAM, 'Idle', [IDLE, NULL], False, cpNormal, True),\n      wbByteArray(SCHR, 'Unused', 0, cpIgnore, false, false, wbNeverShow),\n      wbByteArray(SCTX, 'Unused', 0, cpIgnore, false, false, wbNeverShow),\n      wbPDTOs\n    ], [])),\n\n    {--- Flags ---}\n    wbInteger(XACT, 'Action Flag', itU32, wbFlags([\n      'Use Default',\n      'Activate',\n      'Open',\n      'Open by Default'\n    ])),\n\n    wbFloat(XHTW, 'Head-Tracking Weight'),\n    wbFloat(XFVC, 'Favor Cost'),\n\n    wbEmpty(ONAM, 'Open by Default'),\n\n    {--- Map Data ---}\n    wbRStruct('Map Marker', [\n      wbEmpty(XMRK, 'Map Marker Data'),\n      wbInteger(FNAM, 'Map Flags', itU8, wbFlags([\n        {0x01} 'Visible',\n        {0x02} 'Can Travel To',\n        {0x04} '\"Show All\" Hidden'\n      ]), cpNormal, True),\n      wbFULLReq,\n      wbStruct(TNAM, '', [\n        wbInteger('Type', itU8, wbEnum([], [\n          0, 'None',\n          1, 'City',\n          2, 'Town',\n          3, 'Settlement',\n          4, 'Cave',\n          5, 'Camp',\n          6, 'Fort',\n          7, 'Nordic Ruins',\n          8, 'Dwemer Ruin',\n          9, 'Shipwreck',\n          10, 'Grove',\n          11, 'Landmark',\n          12, 'Dragon Lair',\n          13, 'Farm',\n          14, 'Wood Mill',\n          15, 'Mine',\n          16, 'Imperial Camp',\n          17, 'Stormcloak Camp',\n          18, 'Doomstone',\n          19, 'Wheat Mill',\n          20, 'Smelter',\n          21, 'Stable',\n          22, 'Imperial Tower',\n          23, 'Clearing',\n          24, 'Pass',\n          25, 'Altar',\n          26, 'Rock',\n          27, 'Lighthouse',\n          28, 'Orc Stronghold',\n          29, 'Giant Camp',\n          30, 'Shack',\n          31, 'Nordic Tower',\n          32, 'Nordic Dwelling',\n          33, 'Docks',\n          34, 'Shrine',\n          35, 'Riften Castle',\n          36, 'Riften Capitol',\n          37, 'Windhelm Castle',\n          38, 'Windhelm Capitol',\n          39, 'Whiterun Castle',\n          40, 'Whiterun Capitol',\n          41, 'Solitude Castle',\n          42, 'Solitude Capitol',\n          43, 'Markarth Castle',\n          44, 'Markarth Capitol',\n          45, 'Winterhold Castle',\n          46, 'Winterhold Capitol',\n          47, 'Morthal Castle',\n          48, 'Morthal Capitol',\n          49, 'Falkreath Castle',\n          50, 'Falkreath Capitol',\n          51, 'Dawnstar Castle',\n          52, 'Dawnstar Capitol',\n          53, 'DLC02 - Temple of Miraak',\n          54, 'DLC02 - Raven Rock',\n          55, 'DLC02 - Beast Stone',\n          56, 'DLC02 - Tel Mithryn',\n          57, 'DLC02 - To Skyrim',\n          58, 'DLC02 - To Solstheim',\n          59, 'Custom 59',\n          60, 'Custom 60',\n          61, 'Custom 61',\n          62, 'Custom 62',\n          63, 'Custom 63',\n          64, 'Custom 64',\n          65, 'Custom 65',\n          66, 'Custom 66',\n          67, 'Custom 67',\n          68, 'Custom 68',\n          69, 'Custom 69',\n          70, 'Custom 70',\n          71, 'Custom 71',\n          72, 'Custom 72',\n          73, 'Custom 73',\n          74, 'Custom 74',\n          75, 'Custom 75',\n          76, 'Custom 76',\n          77, 'Custom 77',\n          78, 'Custom 78',\n          79, 'Custom 79',\n          80, 'Custom 80',\n          81, 'Custom 81',\n          82, 'Custom 82',\n          83, 'Custom 83',\n          84, 'Custom 84',\n          85, 'Custom 85',\n          86, 'Custom 86',\n          87, 'Custom 87',\n          88, 'Custom 88',\n          89, 'Custom 89',\n          90, 'Custom 90',\n          91, 'Custom 91',\n          92, 'Custom 92',\n          93, 'Custom 93',\n          94, 'Custom 94',\n          95, 'Custom 95',\n          96, 'Custom 96',\n          97, 'Custom 97',\n          98, 'Custom 98',\n          99, 'Custom 99'\n        ])),\n        wbByteArray('Unused', 1)\n      ], cpNormal, True)\n    ], []),\n    {--- Attach reference ---}\n    wbFormIDCk(XATR, 'Attach Ref', [REFR, PGRE, PHZD, PMIS, PARW, PBAR, PBEA, PCON, PFLA]),\n    wbXLOD,\n    wbDataPosRot\n  ], True, wbPlacedAddInfo, cpNormal, False, wbREFRAfterLoad);\n\n  wbRecord(REGN, 'Region',\n    wbFlags(wbRecordFlagsFlags, wbFlagsList([\n      {0x00000040} 6, 'Border Region'\n    ])), [\n    wbEDID,\n    wbStruct(RCLR, 'Map Color', [\n      wbInteger('Red', itU8),\n      wbInteger('Green', itU8),\n      wbInteger('Blue', itU8),\n      wbByteArray('Unknown', 1)\n    ], cpNormal, True),\n    {>>> Skyrim.esm has some incorrect FormIDs here, probably leftover <<<}\n    wbFormIDCkNoReach(WNAM, 'Worldspace', [WRLD]),\n    wbRArray('Region Areas', wbRStruct('Region Area', [\n      wbInteger(RPLI, 'Edge Fall-off', itU32),\n      wbArray(RPLD, 'Region Point List Data', wbStruct('Point', [\n        wbFloat('X'),\n        wbFloat('Y')\n      ]), 0, wbRPLDAfterLoad)\n    ], [])),\n    wbRArrayS('Region Data Entries', wbRStructSK([0], 'Region Data Entry', [\n      {always starts with an RDAT}\n      wbStructSK(RDAT, [0], 'Data Header', [\n        wbInteger('Type', itU32, wbEnum([\n          {0} 'Unknown 0',\n          {1} 'Unknown 1',\n          {2} 'Objects',\n          {3} 'Weather',\n          {4} 'Map',\n          {5} 'Land',\n          {6} 'Grass',\n          {7} 'Sound',\n          {8} 'Imposter',\n          {9} 'Unknown 10',\n          {10}'Unknown 11',\n          {11}'Unknown 12',\n          {12}'Unknown 13',\n          {13}'Unknown 14',\n          {14}'Unknown 15',\n          {15}'Unknown 16'\n        ])),\n        wbInteger('Flags', itU8, wbFlags([\n          'Override'\n        ])),\n        wbInteger('Priority', itU8),\n        wbByteArray('Unknown')\n      ], cpNormal, True),\n\n      {--- Icon ---}\n      wbICON,\n\n      {--- Sound ---}\n      wbFormIDCk(RDMO, 'Music', [MUSC], False, cpNormal, False, wbREGNSoundDontShow),\n      wbArrayS(RDSA, 'Sounds', wbStructSK([0], 'Sound', [\n        wbFormIDCk('Sound', [SNDR, NULL]),\n        wbInteger('Flags', itU32, wbFlags([\n          {0x00000001}'Pleasant',\n          {0x00000002}'Cloudy',\n          {0x00000004}'Rainy',\n          {0x00000008}'Snowy'\n        ])),\n        wbFloat('Chance')\n      ]), 0, cpNormal, False, nil, nil, wbREGNSoundDontShow),\n\n\t\t\t{--- Map ---}\n      wbLString(RDMP, 'Map Name', 0, cpTranslate, False, wbREGNMapDontShow),\n\n      {followed by one of these: }\n\n      {--- Objects ---}\n      wbArray(RDOT, 'Objects', wbStruct('Object', [\n        wbFormIDCk('Object', [TREE, FLOR, STAT, LTEX, MSTT]),\n        wbInteger('Parent Index', itU16, wbHideFFFF),\n        wbByteArray('Unknown', 2),\n        wbFloat('Density'),\n        wbInteger('Clustering', itU8),\n        wbInteger('Min Slope', itU8),\n        wbInteger('Max Slope', itU8),\n        wbInteger('Flags', itU8, wbFlags([\n          {0}'Conform to slope',\n          {1}'Paint Vertices',\n          {2}'Size Variance +/-',\n          {3}'X +/-',\n          {4}'Y +/-',\n          {5}'Z +/-',\n          {6}'Tree',\n          {7}'Huge Rock'\n        ])),\n        wbInteger('Radius wrt Parent', itU16),\n        wbInteger('Radius', itU16),\n        wbFloat('Min Height'),\n        wbFloat('Max Height'),\n        wbFloat('Sink'),\n        wbFloat('Sink Variance'),\n        wbFloat('Size Variance'),\n        wbStruct('Angle Variance', [\n          wbInteger('X', itU16),\n          wbInteger('Y', itU16),\n          wbInteger('Z', itU16)\n        ]),\n        wbByteArray('Unknown', 2),\n        wbByteArray('Unknown', 4)\n      ]), 0, nil, nil, cpNormal, False, wbREGNObjectsDontShow),\n\n      {--- Grass ---}\n      wbArrayS(RDGS, 'Grasses', wbStructSK([0], 'Grass', [\n        wbFormIDCk('Grass', [GRAS]),\n        wbByteArray('Unknown',4)\n      ]), 0, cpNormal, False, nil, nil, wbREGNGrassDontShow),\n\n      {--- Weather ---}\n      wbArrayS(RDWT, 'Weather Types', wbStructSK([0], 'Weather Type', [\n        wbFormIDCk('Weather', [WTHR]),\n        wbInteger('Chance', itU32),\n        wbFormIDCk('Global', [GLOB, NULL])\n      ]), 0, cpNormal, False, nil, nil, wbREGNWeatherDontShow)\n\n    ], []))\n  ], True);\n\n  wbRecord(SOUN, 'Sound Marker', [\n    wbEDID,\n    wbOBNDReq,\n    wbUnknown(FNAM, cpIgnore), // leftover, unused\n    wbUnknown(SNDD, cpIgnore), // leftover, unused\n    wbFormIDCk(SDSC, 'Sound Descriptor', [SNDR, NULL])\n  ]);\n\n  wbSPIT := wbStruct(SPIT, 'Data', [\n    wbInteger('Base Cost', itU32),\n    wbInteger('Flags', itU32, wbFlags([\n      {0x00000001} 'Manual Cost Calc',\n      {0x00000002} 'Unknown 2',\n      {0x00000004} 'Unknown 3',\n      {0x00000008} 'Unknown 4',\n      {0x00000010} 'Unknown 5',\n      {0x00000020} 'Unknown 6',\n      {0x00000040} 'Unknown 7',\n      {0x00000080} 'Unknown 8',\n      {0x00000100} 'Unknown 9',\n      {0x00000200} 'Unknown 10',\n      {0x00000400} 'Unknown 11',\n      {0x00000800} 'Unknown 12',\n      {0x00001000} 'Unknown 13',\n      {0x00002000} 'Unknown 14',\n      {0x00004000} 'Unknown 15',\n      {0x00008000} 'Unknown 16',\n      {0x00010000} 'Unknown 17',\n      {0x00020000} 'PC Start Spell',\n      {0x00040000} 'Unknown 19',\n      {0x00080000} 'Area Effect Ignores LOS',\n      {0x00100000} 'Ignore Resistance',\n      {0x00200000} 'No Absorb/Reflect',\n      {0x00400000} 'Unknown 23',\n      {0x00800000} 'No Dual Cast Modification',\n      {0x01000000} 'Unknown 25',\n      {0x02000000} 'Unknown 26',\n      {0x04000000} 'Unknown 27',\n      {0x08000000} 'Unknown 28',\n      {0x10000000} 'Unknown 29',\n      {0x20000000} 'Unknown 30',\n      {0x40000000} 'Unknown 31',\n      {0x80000000} 'Unknown 32'\n    ])),\n    wbInteger('Type', itU32, wbEnum([\n      {0} 'Spell',\n      {1} 'Disease',\n      {2} 'Power',\n      {3} 'Lesser Power',\n      {4} 'Ability',\n      {5} 'Poison',\n      {6} 'Unknown 6',\n      {7} 'Unknown 7',\n      {8} 'Unknown 8',\n      {9} 'Unknown 9',\n     {10} 'Addiction',\n     {11} 'Voice'\n    ])),\n    wbFloat('Charge Time'),\n    wbInteger('Cast Type', itU32, wbCastEnum),\n    wbInteger('Target Type', itU32, wbTargetEnum),\n    wbFloat('Cast Duration'),\n    wbFloat('Range'),\n    wbFormIDCk('Half-cost Perk', [NULL, PERK])\n  ], cpNormal, True);\n\n  wbRecord(SPEL, 'Spell', [\n    wbEDID,\n    wbOBNDReq,\n    wbFULL,\n    wbKSIZ,\n    wbKWDAs,\n    wbMDOB,\n    wbETYP,\n    wbDESCReq,\n    wbSPIT,\n    wbEffectsReq\n  ], False, nil, cpNormal, False, nil, wbKeywordsAfterSet);\n\n  wbRecord(SCRL, 'Scroll', [\n    wbEDID,\n    wbOBNDReq,\n    wbFULL,\n    wbKSIZ,\n    wbKWDAs,\n    wbMDOB,\n    wbETYP,\n    wbDESC,\n    wbMODL,\n    wbDEST,\n    wbYNAM,\n    wbZNAM,\n    wbStruct(DATA, 'Item', [\n      wbInteger('Value', itU32),\n      wbFloat('Weight')\n    ], cpNormal, True),\n    wbSPIT,\n    wbEffectsReq\n  ], False, nil, cpNormal, False, nil, wbKeywordsAfterSet);\n\n  wbRecord(STAT, 'Static',\n    wbFlags(wbRecordFlagsFlags, [\n      {0x00000001} { 0} '',\n      {0x00000002} { 1} '',\n      {0x00000004} { 2} 'Never Fades',\n      {0x00000008} { 3} '',\n      {0x00000010} { 4} '',\n      {0x00000020} { 5} 'Deleted',\n      {0x00000040} { 6} 'Has Tree LOD',\n      {0x00000080} { 7} 'Add-On LOD Object',\n      {0x00000100} { 8} '',\n      {0x00000200} { 9} 'Hidden From Local Map',\n      {0x00000400} {10} '',\n      {0x00000800} {11} 'Unknown 11', // present in Skyrim.esm but can't be set\n      {0x00001000} {12} '',\n      {0x00002000} {13} '',\n      {0x00004000} {14} '',\n      {0x00008000} {15} 'Has Distant LOD',\n      {0x00010000} {16} 'Unknown 16', // present in Skyrim.esm but can't be set\n      {0x00020000} {17} 'Uses HD LOD Texture',\n      {0x00040000} {18} '',\n      {0x00080000} {19} 'Has Currents',\n      {0x00100000} {20} '',\n      {0x00200000} {21} '',\n      {0x00400000} {22} '',\n      {0x00800000} {23} 'Is Marker',\n      {0x01000000} {24} '',\n      {0x02000000} {25} 'Obstacle',\n      {0x04000000} {26} 'NavMesh Generation - Filter',\n      {0x08000000} {27} 'NavMesh Generation - Bounding Box',\n      {0x10000000} {28} 'Show In World Map',\n      {0x20000000} {29} '',\n      {0x40000000} {30} 'NavMesh Generation - Ground',\n      {0x80000000} {31} ''\n    ], [11, 16]), [\n    wbEDID,\n    wbOBNDReq,\n    wbMODL,\n    IsSSE(\n      wbStruct(DNAM, 'Direction Material', [\n        wbFloat('Max Angle (30-120)'),\n        wbFormIDCk('Material', [MATO, NULL]),\n        // SSE\n        wbInteger('Flags', itU8, wbFlags([\n          {0x01} 'Considered Snow'\n        ])),\n        wbByteArray('Unused', 3, cpIgnore)\n      ], cpNormal, True, nil, 2),\n      wbStruct(DNAM, 'Direction Material', [\n        wbFloat('Max Angle (30-120)'),\n        wbFormIDCk('Material', [MATO, NULL])\n      ], cpNormal, True)\n    ),\n    wbArray(MNAM, 'Distant LOD',\n      wbStruct('LOD', [\n        {>>> Contains null-terminated mesh filename followed by random data up to 260 bytes <<<}\n        wbString(True, 'Mesh', 260)\n        //wbByteArray('Mesh', 260, cpIgnore)\n      ]), [\n        'Level 0',\n        'Level 1',\n        'Level 2',\n        'Level 3'\n      ],\n      cpNormal, False\n    )\n  ]);\n\n  wbRecord(TES4, 'Main File Header',\n    wbFlags(wbRecordFlagsFlags, wbFlagsList([\n      {0x00000001}  0, 'ESM',\n      {0x00000080}  7, 'Localized'\n    ], False), True), [\n    wbStruct(HEDR, 'Header', [\n      wbFloat('Version'),\n      wbInteger('Number of Records', itU32),\n      wbInteger('Next Object ID', itU32)\n    ], cpNormal, True),\n    wbByteArray(OFST, 'Unknown', 0, cpIgnore),\n    wbByteArray(DELE, 'Unknown', 0, cpIgnore),\n    wbString(CNAM, 'Author', 0, cpTranslate, True),\n    wbString(SNAM, 'Description', 0, cpTranslate),\n    wbRArray('Master Files', wbRStruct('Master File', [\n      wbString(MAST, 'Filename', 0, cpNormal, True),\n      wbByteArray(DATA, 'Unknown', 8, cpIgnore, True)\n    ], [ONAM])),\n    wbArray(ONAM, 'Overridden Forms',\n      wbFormIDCk('Form', [ACHR, LAND, NAVM, REFR, PGRE, PHZD, PMIS, PARW, PBAR, PBEA, PCON, PFLA]),\n      0, nil, nil, cpNormal, False{, wbTES4ONAMDontShow}),\n    wbByteArray(SCRN, 'Screenshot'),\n    wbUnknown(INTV),\n    wbUnknown(INCC)\n  ], True, nil, cpNormal, True, wbRemoveOFST);\nend;\n\nprocedure DefineTES5o;\nbegin\n\n  wbRecord(TREE, 'Tree',\n    wbFlags(wbRecordFlagsFlags, wbFlagsList([\n      {0x00008000} 15, 'Has Distant LOD'\n    ])), [\n    wbEDID,\n    wbVMAD,\n    wbOBNDReq,\n    wbMODL,\n    wbFormIDCK(PFIG, 'Ingredient', [INGR, ALCH, MISC, LVLI, NULL]),\n    wbFormIDCK(SNAM, 'Harvest Sound', [SNDR, NULL]),\n    wbStruct(PFPC, 'Ingredient Production', [\n      wbInteger('Spring', itU8),\n      wbInteger('Summer', itU8),\n      wbInteger('Fall', itU8),\n      wbInteger('Winter', itU8)\n    ]),\n    wbFULL,\n    wbStruct(CNAM, 'Tree Data', [\n      wbFloat('Trunk Flexibility'),\n      wbFloat('Branch Flexibility'),\n      //wbByteArray('Unknown', 32),\n      wbFloat('Unknown'),\n      wbFloat('Unknown'),\n      wbFloat('Unknown'),\n      wbFloat('Unknown'),\n      wbFloat('Unknown'),\n      wbFloat('Unknown'),\n      wbFloat('Unknown'),\n      wbFloat('Unknown'),\n      wbFloat('Leaf Amplitude'),\n      wbFloat('Leaf Frequency')\n    ], cpNormal, True)\n  ]);\n\n  wbRecord(FLOR, 'Flora', [\n    wbEDID,\n    wbVMAD,\n    wbOBNDReq,\n    wbFULLReq,\n    wbMODL,\n    wbDEST,\n    wbKSIZ,\n    wbKWDAs,\n    wbUnknown(PNAM),\n    wbLString(RNAM, 'Activate Text Override', 0, cpTranslate),\n    wbUnknown(FNAM),\n    wbFormIDCk(PFIG, 'Ingredient', [INGR, ALCH, LVLI, MISC, NULL]),\n    wbFormIDCK(SNAM, 'Sound', [SNDR, NULL]),\n    wbStruct(PFPC, 'Seasonal ingredient production', [\n      wbInteger('Spring', itU8),\n      wbInteger('Summer ', itU8),\n      wbInteger('Fall', itU8),\n      wbInteger('Winter', itU8)\n    ], cpNormal, True)\n  ], False, nil, cpNormal, False, nil, wbKeywordsAfterSet);\n\n  wbRecord(WATR, 'Water', [\n    wbEDID,\n    wbFULL,\n    wbRArray('Unused', wbString(NNAM, 'Noise Map', 0, cpIgnore, False)), // leftover\n    wbInteger(ANAM, 'Opacity', itU8, nil, cpNormal, True),\n    wbInteger(FNAM, 'Flags', itU8, wbFlags([\n      {0x01} 'Causes Damage',\n      {0x02} 'Unknown 1',\n      {0x04} 'Unknown 2',\n      {0x08} IsSSE('Enable Flowmap', 'Unknown 3'),\n      {0x10} IsSSE('Blend Normals', 'Unknown 4'),\n      {0x20} 'Unknown 5',\n      {0x40} 'Unknown 6',\n      {0x80} 'Unknown 7'\n    ]), cpNormal, True),\n    wbByteArray(MNAM, 'Unused', 0, cpIgnore, False),  // leftover\n    wbFormIDCk(TNAM, 'Material', [MATT]),\n    wbFormIDCk(SNAM, 'Open Sound', [SNDR, NULL]),\n    wbFormIDCk(XNAM, 'Spell', [SPEL]),\n    wbFormIDCk(INAM, 'Image Space', [IMGS]),\n    wbInteger(DATA, 'Damage Per Second', itU16, nil, cpNormal, True, True),\n    IsSSE(\n      wbStruct(DNAM, 'Visual Data', [\n        wbFloat('Unknown'),\n        wbFloat('Unknown'),\n        wbFloat('Unknown'),\n        wbFloat('Unknown'),\n        wbFloat('Specular Properties - Sun Specular Power'),\n        wbFloat('Water Properties - Reflectivity Amount'),\n        wbFloat('Water Properties - Fresnel Amount'),\n        wbByteArray('Unknown', 4),\n        wbFloat('Fog Properties - Above Water - Fog Distance - Near Plane'),\n        wbFloat('Fog Properties - Above Water - Fog Distance - Far Plane'),\n        wbByteColors('Shallow Color'),\n        wbByteColors('Deep Color'),\n        wbByteColors('Reflection Color'),\n        wbByteArray('Unknown', 4),\n        wbFloat('Unknown'),\n        wbFloat('Unknown'),\n        wbFloat('Unknown'),\n        wbFloat('Unknown'),\n        wbFloat('Displacement Simulator - Starting Size'),\n        wbFloat('Displacement Simulator - Force'),\n        wbFloat('Displacement Simulator - Velocity'),\n        wbFloat('Displacement Simulator - Falloff'),\n        wbFloat('Displacement Simulator - Dampner'),\n        wbFloat('Unknown'),\n        wbFloat('Noise Properties - Noise Falloff'),\n        wbFloat('Noise Properties - Layer One - Wind Direction'),\n        wbFloat('Noise Properties - Layer Two - Wind Direction'),\n        wbFloat('Noise Properties - Layer Three - Wind Direction'),\n        wbFloat('Noise Properties - Layer One - Wind Speed'),\n        wbFloat('Noise Properties - Layer Two - Wind Speed'),\n        wbFloat('Noise Properties - Layer Three - Wind Speed'),\n        wbFloat('Unknown'),\n        wbFloat('Unknown'),\n        wbFloat('Fog Properties - Above Water - Fog Amount'),\n        wbFloat('Unknown'),\n        wbFloat('Fog Properties - Under Water - Fog Amount'),\n        wbFloat('Fog Properties - Under Water - Fog Distance - Near Plane'),\n        wbFloat('Fog Properties - Under Water - Fog Distance - Far Plane'),\n        wbFloat('Water Properties - Refraction Magnitude'),\n        wbFloat('Specular Properties - Specular Power'),\n        wbFloat('Unknown'),\n        wbFloat('Specular Properties - Specular Radius'),\n        wbFloat('Specular Properties - Specular Brightness'),\n        wbFloat('Noise Properties - Layer One - UV Scale'),\n        wbFloat('Noise Properties - Layer Two - UV Scale'),\n        wbFloat('Noise Properties - Layer Three - UV Scale'),\n        wbFloat('Noise Properties - Layer One - Amplitude Scale'),\n        wbFloat('Noise Properties - Layer Two - Amplitude Scale'),\n        wbFloat('Noise Properties - Layer Three - Amplitude Scale'),\n        wbFloat('Water Properties - Reflection Magnitude'),\n        wbFloat('Specular Properties - Sun Sparkle Magnitude'),\n        wbFloat('Specular Properties - Sun Specular Magnitude'),\n        wbFloat('Depth Properties - Reflections'),\n        wbFloat('Depth Properties - Refraction'),\n        wbFloat('Depth Properties - Normals'),\n        wbFloat('Depth Properties - Specular Lighting'),\n        wbFloat('Specular Properties - Sun Sparkle Power'),\n        // SSE\n        wbFloat('Noise Properties - Flowmap Scale')\n      ], cpNormal, True, nil, 57),\n      wbStruct(DNAM, 'Visual Data', [\n        wbFloat('Unknown'),\n        wbFloat('Unknown'),\n        wbFloat('Unknown'),\n        wbFloat('Unknown'),\n        wbFloat('Specular Properties - Sun Specular Power'),\n        wbFloat('Water Properties - Reflectivity Amount'),\n        wbFloat('Water Properties - Fresnel Amount'),\n        wbByteArray('Unknown', 4),\n        wbFloat('Fog Properties - Above Water - Fog Distance - Near Plane'),\n        wbFloat('Fog Properties - Above Water - Fog Distance - Far Plane'),\n        wbByteColors('Shallow Color'),\n        wbByteColors('Deep Color'),\n        wbByteColors('Reflection Color'),\n        wbByteArray('Unknown', 4),\n        wbFloat('Unknown'),\n        wbFloat('Unknown'),\n        wbFloat('Unknown'),\n        wbFloat('Unknown'),\n        wbFloat('Displacement Simulator - Starting Size'),\n        wbFloat('Displacement Simulator - Force'),\n        wbFloat('Displacement Simulator - Velocity'),\n        wbFloat('Displacement Simulator - Falloff'),\n        wbFloat('Displacement Simulator - Dampner'),\n        wbFloat('Unknown'),\n        wbFloat('Noise Properties - Noise Falloff'),\n        wbFloat('Noise Properties - Layer One - Wind Direction'),\n        wbFloat('Noise Properties - Layer Two - Wind Direction'),\n        wbFloat('Noise Properties - Layer Three - Wind Direction'),\n        wbFloat('Noise Properties - Layer One - Wind Speed'),\n        wbFloat('Noise Properties - Layer Two - Wind Speed'),\n        wbFloat('Noise Properties - Layer Three - Wind Speed'),\n        wbFloat('Unknown'),\n        wbFloat('Unknown'),\n        wbFloat('Fog Properties - Above Water - Fog Amount'),\n        wbFloat('Unknown'),\n        wbFloat('Fog Properties - Under Water - Fog Amount'),\n        wbFloat('Fog Properties - Under Water - Fog Distance - Near Plane'),\n        wbFloat('Fog Properties - Under Water - Fog Distance - Far Plane'),\n        wbFloat('Water Properties - Refraction Magnitude'),\n        wbFloat('Specular Properties - Specular Power'),\n        wbFloat('Unknown'),\n        wbFloat('Specular Properties - Specular Radius'),\n        wbFloat('Specular Properties - Specular Brightness'),\n        wbFloat('Noise Properties - Layer One - UV Scale'),\n        wbFloat('Noise Properties - Layer Two - UV Scale'),\n        wbFloat('Noise Properties - Layer Three - UV Scale'),\n        wbFloat('Noise Properties - Layer One - Amplitude Scale'),\n        wbFloat('Noise Properties - Layer Two - Amplitude Scale'),\n        wbFloat('Noise Properties - Layer Three - Amplitude Scale'),\n        wbFloat('Water Properties - Reflection Magnitude'),\n        wbFloat('Specular Properties - Sun Sparkle Magnitude'),\n        wbFloat('Specular Properties - Sun Specular Magnitude'),\n        wbFloat('Depth Properties - Reflections'),\n        wbFloat('Depth Properties - Refraction'),\n        wbFloat('Depth Properties - Normals'),\n        wbFloat('Depth Properties - Specular Lighting'),\n        wbFloat('Specular Properties - Sun Sparkle Power')\n      ])\n    ),\n    wbByteArray(GNAM, 'Unused', 0, cpNormal, True),  // leftover\n    wbStruct(NAM0, 'Linear Velocity', [\n      wbFloat('X'),\n      wbFloat('Y'),\n      wbFloat('Z')\n    ], cpNormal, False),\n    wbStruct(NAM1, 'Angular Velocity', [\n      wbFloat('X'),\n      wbFloat('Y'),\n      wbFloat('Z')\n    ], cpNormal, False),\n    wbString(NAM2, 'Noise Layer One - Noise Texture', 0, cpNormal, False),\n    wbString(NAM3, 'Noise Layer Two - Noise Texture', 0, cpNormal, False),\n    wbString(NAM4, 'Noise Layer Three - Noise Texture', 0, cpNormal, False),\n    // SSE\n    wbString(NAM5, 'Flow Normals - Noise Texture', 0, cpNormal, False)\n  ], False, nil, cpNormal, False);\n\n  wbRecord(WEAP, 'Weapon',\n    wbFlags(wbRecordFlagsFlags, wbFlagsList([\n      {0x00000004}  2, 'Non-Playable'\n    ])), [\n    wbEDID,\n    wbVMAD,\n    wbOBNDReq,\n    wbFULL,\n    wbMODL,\n    wbICON,\n    wbEITM,\n    wbInteger(EAMT, 'Enchantment Amount', itU16),\n    wbDEST,\n    wbETYP,\n    wbFormIDCk(BIDS, 'Block Bash Impact Data Set', [IPDS, NULL]),\n    wbFormIDCk(BAMT, 'Alternate Block Material', [MATT, NULL]),\n    wbYNAM,\n    wbZNAM,\n    wbKSIZ,\n    wbKWDAs,\n    wbDESC,\n    wbRStruct('Has Scope', [\n      wbString(MOD3, 'Model Filename'),\n      wbByteArray(MO3T, 'Texture Files Hashes', 0, cpIgnore, false, false, wbNeverShow),\n      wbMO3S\n    ], []),\n    wbByteArray(NNAM, 'Unused', 0, cpIgnore, False), // leftover\n    wbFormIDCk(INAM, 'Impact Data Set', [IPDS, NULL]),\n    wbFormIDCk(WNAM, '1st Person Model Object', [STAT, NULL]),\n    wbFormIDCk(SNAM, 'Attack Sound', [SNDR]),\n    wbFormIDCk(XNAM, 'Attack Sound 2D', [SNDR]),\n    wbFormIDCk(NAM7, 'Attack Loop Sound', [SNDR]),\n    wbFormIDCk(TNAM, 'Attack Fail Sound', [SNDR]),\n    wbFormIDCk(UNAM, 'Idle Sound', [SNDR]),\n    wbFormIDCk(NAM9, 'Equip Sound', [SNDR]),\n    wbFormIDCk(NAM8, 'Unequip Sound', [SNDR]),\n    wbStruct(DATA, 'Game Data', [\n      wbInteger('Value', itU32),\n      wbFloat('Weight'),\n      wbInteger('Damage', itU16)\n    ]),\n    wbStruct(DNAM, 'Data', [\n      wbInteger('Animation Type', itU8, wbWeaponAnimTypeEnum),\n      wbByteArray('Unused', 3, cpIgnore),\n      wbFloat('Speed'),\n      wbFloat('Reach'),\n      wbInteger('Flags', itU16, wbFlags([\n        {0x0001}'Ignores Normal Weapon Resistance',\n        {0x0002}'Automatic (unused)',\n        {0x0004}'Has Scope (unused)',\n        {0x0008}'Can''t Drop',\n        {0x0010}'Hide Backpack (unused)',\n        {0x0020}'Embedded Weapon (unused)',\n        {0x0040}'Don''t Use 1st Person IS Anim (unused)',\n        {0x0080}'Non-playable'\n      ], [1, 2, 4, 5, 6])),\n      wbByteArray('Unused', 2, cpIgnore),\n      wbFloat('Sight FOV'),\n      wbByteArray('Unknown', 4),\n      wbInteger('Base VATS To-Hit Chance', itU8),\n      wbInteger('Attack Animation', itU8, wbAttackAnimationEnum),\n      wbInteger('# Projectiles', itU8),\n      wbInteger('Embedded Weapon AV (unused)', itU8),\n      wbFloat('Range Min'),\n      wbFloat('Range Max'),\n      wbInteger('On Hit', itU32, wbEnum([\n        'No formula behaviour',\n        'Dismember only',\n        'Explode only',\n        'No dismember/explode'\n      ])),\n      wbInteger('Flags2', itU32, wbFlags([\n        {0x00000001} 'Player Only',\n        {0x00000002} 'NPCs Use Ammo',\n        {0x00000004} 'No Jam After Reload (unused)',\n        {0x00000008} 'Unknown 4',\n        {0x00000010} 'Minor Crime',\n        {0x00000020} 'Range Fixed',\n        {0x00000040} 'Not Used in Normal Combat',\n        {0x00000080} 'Unknown 8',\n        {0x00000100} 'Don''t Use 3rd Person IS Anim (unused)',\n        {0x00000200} 'Burst Shot',\n        {0x00000400} 'Rumble - Alternate',\n        {0x00000800} 'Long Bursts',\n        {0x00001000} 'Non-hostile',\n        {0x00002000} 'Bound Weapon'\n      ], [2, 8])),\n      wbFloat('Animation Attack Mult'),\n      wbFloat('Unknown'),\n      wbFloat('Rumble - Left Motor Strength'),\n      wbFloat('Rumble - Right Motor Strength'),\n      wbFloat('Rumble - Duration'),\n      wbByteArray('Unknown', 12),\n      wbInteger('Skill', itS32, wbSkillEnum),\n      wbByteArray('Unknown', 8),\n      wbInteger('Resist', itS32, wbActorValueEnum),\n      wbByteArray('Unknown', 4),\n      wbFloat('Stagger')\n    ]),\n    IsSSE(\n      wbStruct(CRDT, 'Critical Data', [\n        wbInteger('Damage', itU16),\n        wbByteArray('Unknown', 2),\n        wbFloat('% Mult'),\n        wbInteger('Flags', itU8, wbFlags([\n          'On Death'\n        ])),\n\t\t// SSE\n        wbByteArray('Unused', 3, cpIgnore),\n        wbByteArray('Unknown', 4),\n        wbFormIDCk('Effect', [SPEL, NULL]),\n        wbByteArray('Unknown', 4)\n      ]),\n      wbStruct(CRDT, 'Critical Data', [\n        wbInteger('Damage', itU16),\n        wbByteArray('Unknown', 2),\n        wbFloat('% Mult'),\n        wbInteger('Flags', itU8, wbFlags([\n          'On Death'\n        ])),\n        wbByteArray('Unused', 3, cpIgnore),\n        wbFormIDCk('Effect', [SPEL, NULL])\n      ])\n    ),\n    wbInteger(VNAM, 'Detection Sound Level', itU32, wbSoundlevelEnum),\n    wbFormIDCk(CNAM, 'Template', [WEAP])\n  ], False, nil, cpNormal, False, wbWEAPAfterLoad, wbKeywordsAfterSet);\n\n  wbRecord(WRLD, 'Worldspace',\n    wbFlags(wbRecordFlagsFlags, wbFlagsList([\n      {0x00080000} 19, 'Can''t Wait'\n    ])), [\n    wbEDID,\n    wbRArray(IsSSE('Large References', 'Unused RNAM'),\n      wbStruct(RNAM, 'Grid', [\n        wbInteger('Y', itS16, nil, cpIgnore),\n        wbInteger('X', itS16, nil, cpIgnore),\n        wbArray('References', wbStruct('Reference', [\n          wbFormIDCk('Ref', [REFR], False, cpIgnore),\n          wbInteger('Y', itS16, nil, cpIgnore),\n          wbInteger('X', itS16, nil, cpIgnore)\n        ]), -1)\n      ]),\n      cpIgnore, False, nil, nil, wbNeverShow\n    ),\n    wbMaxHeightDataWRLD,\n    wbFULL,\n    wbStruct(WCTR, 'Fixed Dimensions Center Cell', [\n      wbInteger('X', itS16),\n      wbInteger('Y', itS16)\n    ]),\n    wbFormIDCk(LTMP, 'Interior Lighting', [LGTM]),\n    wbFormIDCk(XEZN, 'Encounter Zone', [ECZN, NULL]),\n    wbFormIDCk(XLCN, 'Location', [LCTN, NULL]),\n    wbRStruct('Parent', [\n      wbFormIDCk(WNAM, 'Worldspace', [WRLD]),\n      wbStruct(PNAM, '', [\n        wbInteger('Flags', itU8, wbFlags([\n          {0x0001}'Use Land Data',\n          {0x0002}'Use LOD Data',\n          {0x0004}'Don''t Use Map Data',\n          {0x0008}'Use Water Data',\n          {0x0010}'Use Climate Data',\n          {0x0020}'Use Image Space Data (unused)',\n          {0x0040}'Use Sky Cell'\n        ], [5])),\n        wbByteArray('Unknown', 1)\n      ], cpNormal, True)\n    ], []),\n    wbFormIDCk(CNAM, 'Climate', [CLMT]),\n    wbFormIDCk(NAM2, 'Water', [WATR]),\n    wbFormIDCk(NAM3, 'LOD Water Type', [WATR]),\n    wbFloat(NAM4, 'LOD Water Height'),\n    wbStruct(DNAM, 'Land Data', [\n      wbFloat('Default Land Height'),\n      wbFloat('Default Water Height')\n    ]),\n    wbString(ICON, 'Map Image'),\n    wbRStruct('Cloud Model', [wbMODL], []),\n    wbStruct(MNAM, 'Map Data', [\n      wbStruct('Usable Dimensions', [\n        wbInteger('X', itS32),\n        wbInteger('Y', itS32)\n      ]),\n      wbStruct('Cell Coordinates', [\n        wbStruct('NW Cell', [\n          wbInteger('X', itS16),\n          wbInteger('Y', itS16)\n        ]),\n        wbStruct('SE Cell', [\n          wbInteger('X', itS16),\n          wbInteger('Y', itS16)\n        ])\n      ]),\n      wbStruct('Camera Data', [\n        wbFloat('Min Height'),\n        wbFloat('Max Height'),\n        wbFloat('Initial Pitch')\n      ])\n    ], cpNormal, False, nil, 2),\n    wbStruct(ONAM, 'World Map Offset Data', [\n      wbFloat('World Map Scale'),\n      wbFloat('Cell X Offset'),\n      wbFloat('Cell Y Offset'),\n      wbFloat('Cell Z Offset')\n    ], cpNormal, True),\n    wbFloat(NAMA, 'Distant LOD Multiplier'),\n    wbInteger(DATA, 'Flags', itU8, wbFlags([\n      {0x01} 'Small World',\n      {0x02} 'Can''t Fast Travel',\n      {0x04} 'Unknown 3',\n      {0x08} 'No LOD Water',\n      {0x10} 'No Landscape',\n      {0x20} 'No Sky',\n      {0x40} 'Fixed Dimensions',\n      {0x80} 'No Grass'\n    ]), cpNormal, True),\n    {>>> Object Bounds doesn't show up in CK <<<}\n    wbRStruct('Object Bounds', [\n      wbStruct(NAM0, 'Min', [\n        wbFloat('X', cpNormal, False, 1/4096),\n        wbFloat('Y', cpNormal, False, 1/4096)\n      ], cpIgnore, True),\n      wbStruct(NAM9, 'Max', [\n        wbFloat('X', cpNormal, False, 1/4096),\n        wbFloat('Y', cpNormal, False, 1/4096)\n      ], cpIgnore, True)\n    ], []),\n    wbFormIDCk(ZNAM, 'Music', [MUSC]),\n    wbString(NNAM, 'Canopy Shadow (unused)', 0, cpIgnore),\n    wbString(XNAM, 'Water Noise Texture'),\n    wbString(TNAM, 'HD LOD Diffuse Texture'),\n    wbString(UNAM, 'HD LOD Normal Texture'),\n    wbString(XWEM, 'Water Environment Map (unused)', 0, cpIgnore),\n    wbOFST\n  ], False, nil, cpNormal, False, wbWRLDAfterLoad);\n\n\n  wbRecord(WTHR, 'Weather', [\n    wbEDID,\n    wbString(_00_0TX, 'Cloud Texture Layer #0'),\n    wbString(_10_0TX, 'Cloud Texture Layer #1'),\n    wbString(_20_0TX, 'Cloud Texture Layer #2'),\n    wbString(_30_0TX, 'Cloud Texture Layer #3'),\n    wbString(_40_0TX, 'Cloud Texture Layer #4'),\n    wbString(_50_0TX, 'Cloud Texture Layer #5'),\n    wbString(_60_0TX, 'Cloud Texture Layer #6'),\n    wbString(_70_0TX, 'Cloud Texture Layer #7'),\n    wbString(_80_0TX, 'Cloud Texture Layer #8'),\n    wbString(_90_0TX, 'Cloud Texture Layer #9'),\n    wbString(_3A_0TX, 'Cloud Texture Layer #10'),\n    wbString(_3B_0TX, 'Cloud Texture Layer #11'),\n    wbString(_3C_0TX, 'Cloud Texture Layer #12'),\n    wbString(_3D_0TX, 'Cloud Texture Layer #13'),\n    wbString(_3E_0TX, 'Cloud Texture Layer #14'),\n    wbString(_3F_0TX, 'Cloud Texture Layer #15'),\n    wbString(_40h_0TX, 'Cloud Texture Layer #16'),\n    wbString(A0TX, 'Cloud Texture Layer #17'),\n    wbString(B0TX, 'Cloud Texture Layer #18'),\n    wbString(C0TX, 'Cloud Texture Layer #19'),\n    wbString(D0TX, 'Cloud Texture Layer #20'),\n    wbString(E0TX, 'Cloud Texture Layer #21'),\n    wbString(F0TX, 'Cloud Texture Layer #22'),\n    wbString(G0TX, 'Cloud Texture Layer #23'),\n    wbString(H0TX, 'Cloud Texture Layer #24'),\n    wbString(I0TX, 'Cloud Texture Layer #25'),\n    wbString(J0TX, 'Cloud Texture Layer #26'),\n    wbString(K0TX, 'Cloud Texture Layer #27'),\n    wbString(L0TX, 'Cloud Texture Layer #28'),\n    wbByteArray(DNAM, 'Unused', 0, cpIgnore),\n    wbByteArray(CNAM, 'Unused', 0, cpIgnore),\n    wbByteArray(ANAM, 'Unused', 0, cpIgnore),\n    wbByteArray(BNAM, 'Unused', 0, cpIgnore),\n    wbUnknown(LNAM),\n    wbFormIDCK(MNAM, 'Precipitation Type', [SPGD, NULL]),\n    wbFormIDCK(NNAM, 'Visual Effect', [RFCT, NULL], False, cpNormal, True),\n    wbByteArray(ONAM, 'Unused', 0, cpIgnore),\n    wbRStruct('Cloud Speed', [\n      wbArray(RNAM, 'Y Speed', wbInteger('Layer', itU8, wbCloudSpeedToStr, wbCloudSpeedToInt)),\n      wbArray(QNAM, 'X Speed', wbInteger('Layer', itU8, wbCloudSpeedToStr, wbCloudSpeedToInt))\n    ], []),\n    wbArray(PNAM, 'Cloud Colors', wbWeatherColors('Layer')),\n    wbArray(JNAM, 'Cloud Alphas', wbStruct('Layer', [\n      wbFloat('Sunrise'),\n      wbFloat('Day'),\n      wbFloat('Sunset'),\n      wbFloat('Night')\n    ])),\n    {>>> not as an array since last entries are omitted in skyrim.esm <<<}\n    wbStruct(NAM0, 'Weather Colors', [\n      wbWeatherColors('Sky-Upper'),\n      wbWeatherColors('Fog Near'),\n      wbWeatherColors('Unknown'),\n      wbWeatherColors('Ambient'),\n      wbWeatherColors('Sunlight'),\n      wbWeatherColors('Sun'),\n      wbWeatherColors('Stars'),\n      wbWeatherColors('Sky-Lower'),\n      wbWeatherColors('Horizon'),\n      wbWeatherColors('Effect Lighting'),\n      wbWeatherColors('Cloud LOD Diffuse'),\n      wbWeatherColors('Cloud LOD Ambient'),\n      wbWeatherColors('Fog Far'),\n      wbWeatherColors('Sky Statics'),\n      wbWeatherColors('Water Multiplier'),\n      wbWeatherColors('Sun Glare'),\n      wbWeatherColors('Moon Glare')\n    ], cpNormal, True, nil, 13),\n    wbStruct(FNAM, 'Fog Distance', [\n      wbFloat('Day - Near'),\n      wbFloat('Day - Far'),\n      wbFloat('Night - Near'),\n      wbFloat('Night - Far'),\n      wbFloat('Day - Power'),\n      wbFloat('Night - Power'),\n      wbFloat('Day - Max'),\n      wbFloat('Night - Max')\n    ], cpNormal, True),\n    wbStruct(DATA, 'Data', [\n      wbInteger('Wind Speed', itU8), // scaled 0..1\n      wbByteArray('Unknown', 2),\n      wbInteger('Trans Delta', itU8), // scaled 0..0,25\n      wbInteger('Sun Glare', itU8), // scaled 0..1\n      wbInteger('Sun Damage', itU8), // scaled 0..1\n      wbInteger('Precipitation - Begin Fade In', itU8), // scaled 0..1\n      wbInteger('Precipitation - End Fade Out', itU8), // scaled 0..1\n      wbInteger('Thunder/Lightning - Begin Fade In', itU8),\n      wbInteger('Thunder/Lightning - End Fade Out', itU8),\n      wbInteger('Thunder/Lightning - Frequency', itU8),\n      wbInteger('Flags', itU8, wbFlags([\n        {0x01} 'Weather - Pleasant',\n        {0x02} 'Weather - Cloudy',\n        {0x04} 'Weather - Rainy',\n        {0x08} 'Weather - Snow',\n        {0x10} 'Sky Statics - Always Visible',\n        {0x20} 'Sky Statics - Follows Sun Position'\n      ])),\n      wbStruct('Lightning Color', [\n        wbInteger('Red', itU8),\n        wbInteger('Green', itU8),\n        wbInteger('Blue', itU8)\n      ]),\n      wbInteger('Visual Effect - Begin', itU8), // scaled 0..1\n      wbInteger('Visual Effect - End', itU8), // scaled 0..1\n      wbInteger('Wind Direction', itU8), // scaled 0..360\n      wbInteger('Wind Direction Range', itU8) // scaled 0..180\n    ], cpNormal, True),\n    wbInteger(NAM1, 'Disabled Cloud Layers', itU32, wbFlags(['0','1','2','3','4','5','6','7','8','9','10','11','12','13','14','15','16','17','18','19','20','21','22','23','24','25','26','27','28','29','30','31'])),\n    wbRArray('Sounds',\n      wbStruct(SNAM, 'Sound', [\n        wbFormIDCK('Sound', [SNDR, SOUN, NULL]),\n        wbInteger('Type', itU32, wbEnum([\n          {0x01} 'Default',\n          {0x02} 'Precipitation',\n          {0x04} 'Wind',\n          {0x08} 'Thunder'\n        ]))\n      ])\n    ),\n    wbRArrayS('Sky Statics', wbFormIDCk(TNAM, 'Static', [STAT, NULL])),\n    wbStruct(IMSP, 'Image Spaces', [\n      wbFormIDCK('Sunrise', [IMGS, NULL]),\n      wbFormIDCK('Day', [IMGS, NULL]),\n      wbFormIDCK('Sunset', [IMGS, NULL]),\n      wbFormIDCK('Night', [IMGS, NULL])\n    ]),\n    // SSE\n    wbStruct(HNAM, 'Volumetric Lighting', [\n      wbFormIDCK('Sunrise', [VOLI, NULL]),\n      wbFormIDCK('Day', [VOLI, NULL]),\n      wbFormIDCK('Sunset', [VOLI, NULL]),\n      wbFormIDCK('Night', [VOLI, NULL])\n    ]),\n    wbRStruct('Directional Ambient Lighting Colors', [\n      wbAmbientColors(DALC, 'Sunrise'),\n      wbAmbientColors(DALC, 'Day'),\n      wbAmbientColors(DALC, 'Sunset'),\n      wbAmbientColors(DALC, 'Night')\n    ], [], cpNormal, True),\n    wbByteArray(NAM2, 'Unused', 0, cpIgnore),\n    wbByteArray(NAM3, 'Unused', 0, cpIgnore),\n    wbRStruct('Aurora', [wbMODL], []),\n    wbFormIDCk(GNAM, 'Sun Glare Lens Flare', [LENS])\n  ]);\n\n  if IsSSE then begin\n    wbRecord(VOLI, 'Volumetric Lighting', [\n      wbEDID,\n      wbFloat(CNAM, 'Intensity'),\n      wbFloat(DNAM, 'Custom Color - Contribution'),\n      wbFloat(ENAM, 'Red', cpNormal, False, 255, 0),\n      wbFloat(FNAM, 'Green', cpNormal, False, 255, 0),\n      wbFloat(GNAM, 'Blue', cpNormal, False, 255, 0),\n      wbFloat(HNAM, 'Density - Contribution'),\n      wbFloat(INAM, 'Density - Size'),\n      wbFloat(JNAM, 'Density - Wind Speed'),\n      wbFloat(KNAM, 'Density - Falling Speed'),\n      wbFloat(LNAM, 'Phase Function - Contribution'),\n      wbFloat(MNAM, 'Phase Function - Scattering'),\n      wbFloat(NNAM, 'Sampling Repartition - Range Factor') { max 1.0 }\n    ]);\n\n    wbRecord(LENS, 'Lens Flare', [\n      wbEDID,\n      wbFloat(CNAM, 'Color Influence'),\n      wbFloat(DNAM, 'Fade Distance Radius Scale'),\n      wbInteger(LFSP, 'Count', itU32, nil, cpBenign),\n      wbRArray('Lens Flare Sprites',\n        wbRStruct('Flare', [\n          wbString(DNAM, 'Lens Flare Sprite ID'),\n          wbString(FNAM, 'Texture'),\n          wbStruct(LFSD, 'Lens Flare Data', [\n            wbFloatColors('Tint'),\n            wbFloat('Width'),\n            wbFloat('Height'),\n            wbFloat('Position'),\n            wbFloat('Angular Fade'),\n            wbFloat('Opacity'),\n            wbInteger('Flags', itU32, wbFlags([\n              {0x01} 'Rotates',\n              {0x02} 'Shrinks When Occluded'\n            ]))\n          ])\n        ], []),\n        cpNormal, False, nil, wbLENSAfterSet\n      )\n    ]);\n\n  end;\nend;\n\n{>>> Unused records, they have empty GRUP in skyrim.esm <<<}\nprocedure DefineTES5p;\nbegin\n  wbRecord(CLDC, 'CLDC', [\n    wbEDID\n  ]);\n  wbRecord(HAIR, 'HAIR', [\n    wbEDID\n  ]);\n  wbRecord(PWAT, 'PWAT', [\n    wbEDID\n  ]);\n  wbRecord(RGDL, 'RGDL', [\n    wbEDID\n  ]);\n  wbRecord(SCOL, 'SCOL', [\n    wbEDID\n  ]);\n  wbRecord(SCPT, 'SCPT', [\n    wbEDID\n  ]);\nend;\n\nprocedure DefineTES5q;\nbegin\n   wbAddGroupOrder(GMST);\n   wbAddGroupOrder(KYWD);\n   wbAddGroupOrder(LCRT);\n   wbAddGroupOrder(AACT);\n   wbAddGroupOrder(TXST);\n   wbAddGroupOrder(GLOB);\n   wbAddGroupOrder(CLAS);\n   wbAddGroupOrder(FACT);\n   wbAddGroupOrder(HDPT);\n   wbAddGroupOrder(HAIR);{>>> Unused in Skyrim, but contained in Skyrim.esm <<<}\n   wbAddGroupOrder(EYES);\n   wbAddGroupOrder(RACE);\n   wbAddGroupOrder(SOUN);\n   wbAddGroupOrder(ASPC);\n   wbAddGroupOrder(MGEF);\n   wbAddGroupOrder(SCPT);{>>> Unused in Skyrim, but contained in Skyrim.esm <<<}\n   wbAddGroupOrder(LTEX);\n   wbAddGroupOrder(ENCH);\n   wbAddGroupOrder(SPEL);\n   wbAddGroupOrder(SCRL);\n   wbAddGroupOrder(ACTI);\n   wbAddGroupOrder(TACT);\n   wbAddGroupOrder(ARMO);\n   wbAddGroupOrder(BOOK);\n   wbAddGroupOrder(CONT);\n   wbAddGroupOrder(DOOR);\n   wbAddGroupOrder(INGR);\n   wbAddGroupOrder(LIGH);\n   wbAddGroupOrder(MISC);\n   wbAddGroupOrder(APPA);\n   wbAddGroupOrder(STAT);\n   wbAddGroupOrder(SCOL);{>>> Unused in Skyrim, but contained in Skyrim.esm <<<}\n   wbAddGroupOrder(MSTT);\n   wbAddGroupOrder(PWAT);{>>> Unused in Skyrim, but contained in Skyrim.esm <<<}\n   wbAddGroupOrder(GRAS);\n   wbAddGroupOrder(TREE);\n   wbAddGroupOrder(CLDC);{>>> Unused in Skyrim, but contained in Skyrim.esm <<<}\n   wbAddGroupOrder(FLOR);\n   wbAddGroupOrder(FURN);\n   wbAddGroupOrder(WEAP);\n   wbAddGroupOrder(AMMO);\n   wbAddGroupOrder(NPC_);\n   wbAddGroupOrder(LVLN);\n   wbAddGroupOrder(KEYM);\n   wbAddGroupOrder(ALCH);\n   wbAddGroupOrder(IDLM);\n   wbAddGroupOrder(COBJ);\n   wbAddGroupOrder(PROJ);\n   wbAddGroupOrder(HAZD);\n   wbAddGroupOrder(SLGM);\n   wbAddGroupOrder(LVLI);\n   wbAddGroupOrder(WTHR);\n   wbAddGroupOrder(CLMT);\n   wbAddGroupOrder(SPGD);\n   wbAddGroupOrder(RFCT);\n   wbAddGroupOrder(REGN);\n   wbAddGroupOrder(NAVI);\n   wbAddGroupOrder(CELL);\n   wbAddGroupOrder(WRLD);\n   wbAddGroupOrder(DIAL);\n   wbAddGroupOrder(QUST);\n   wbAddGroupOrder(IDLE);\n   wbAddGroupOrder(PACK);\n   wbAddGroupOrder(CSTY);\n   wbAddGroupOrder(LSCR);\n   wbAddGroupOrder(LVSP);\n   wbAddGroupOrder(ANIO);\n   wbAddGroupOrder(WATR);\n   wbAddGroupOrder(EFSH);\n   wbAddGroupOrder(EXPL);\n   wbAddGroupOrder(DEBR);\n   wbAddGroupOrder(IMGS);\n   wbAddGroupOrder(IMAD);\n   wbAddGroupOrder(FLST);\n   wbAddGroupOrder(PERK);\n   wbAddGroupOrder(BPTD);\n   wbAddGroupOrder(ADDN);\n   wbAddGroupOrder(AVIF);\n   wbAddGroupOrder(CAMS);\n   wbAddGroupOrder(CPTH);\n   wbAddGroupOrder(VTYP);\n   wbAddGroupOrder(MATT);\n   wbAddGroupOrder(IPCT);\n   wbAddGroupOrder(IPDS);\n   wbAddGroupOrder(ARMA);\n   wbAddGroupOrder(ECZN);\n   wbAddGroupOrder(LCTN);\n   wbAddGroupOrder(MESG);\n   wbAddGroupOrder(RGDL);{>>> Unused in Skyrim, but contained in Skyrim.esm <<<}\n   wbAddGroupOrder(DOBJ);\n   wbAddGroupOrder(LGTM);\n   wbAddGroupOrder(MUSC);\n   wbAddGroupOrder(FSTP);\n   wbAddGroupOrder(FSTS);\n   wbAddGroupOrder(SMBN);\n   wbAddGroupOrder(SMQN);\n   wbAddGroupOrder(SMEN);\n   wbAddGroupOrder(DLBR);\n   wbAddGroupOrder(MUST);\n   wbAddGroupOrder(DLVW);\n   wbAddGroupOrder(WOOP);\n   wbAddGroupOrder(SHOU);\n   wbAddGroupOrder(EQUP);\n   wbAddGroupOrder(RELA);\n   wbAddGroupOrder(SCEN);\n   wbAddGroupOrder(ASTP);\n   wbAddGroupOrder(OTFT);\n   wbAddGroupOrder(ARTO);\n   wbAddGroupOrder(MATO);\n   if IsSSE then wbAddGroupOrder(VOLI); {New to SSE}\n   wbAddGroupOrder(MOVT);\n   wbAddGroupOrder(SNDR);\n   wbAddGroupOrder(DUAL);\n   wbAddGroupOrder(SNCT);\n   wbAddGroupOrder(SOPM);\n   wbAddGroupOrder(COLL);\n   wbAddGroupOrder(CLFM);\n   wbAddGroupOrder(REVB);\n   if IsSSE then wbAddGroupOrder(LENS); {New to SSE}\nend;\n\nprocedure DefineTES5;\nbegin\n  DefineTES5a;\n  DefineTES5b;\n  DefineTES5c;\n  DefineTES5d;\n  DefineTES5e;\n  DefineTES5f;\n  DefineTES5g;\n  DefineTES5h;\n  DefineTES5i;\n  DefineTES5j;\n  DefineTES5k;\n  DefineTES5l;\n  DefineTES5m;\n  DefineTES5n;\n  DefineTES5o;\n  DefineTES5p;\n  DefineTES5q;\n\n  if IsSSE then begin\n    SetLength(wbOfficialDLC, 3);\n    wbOfficialDLC[0] := 'Dawnguard.esm';\n    wbOfficialDLC[1] := 'HearthFires.esm';\n    wbOfficialDLC[2] := 'Dragonborn.esm';\n  end;\n\nend;\n\ninitialization\nend.\n"
  },
  {
    "path": "lib/xedit/wbHelpers.pas",
    "content": "{*******************************************************************************\n\n     The contents of this file are subject to the Mozilla Public License\n     Version 1.1 (the \"License\"); you may not use this file except in\n     compliance with the License. You may obtain a copy of the License at\n     http://www.mozilla.org/MPL/\n\n     Software distributed under the License is distributed on an \"AS IS\"\n     basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the\n     License for the specific language governing rights and limitations\n     under the License.\n\n*******************************************************************************}\n\nunit wbHelpers;\n\n{$I wbDefines.inc}\n\ninterface\n\nuses\n  Classes,\n  Windows,\n  SysUtils,\n  Graphics,\n  ShellAPI,\n  ShlObj,\n  IniFiles,\n  Registry,\n  wbInterface,\n  Imaging,\n  ImagingTypes;\n\nConst\n  CRCSeed = $ffffffff;\n{$IFDEF WIN64}\n  CRC32tab : Array[0..255] of DWord = (\n      $00000000, $77073096, $ee0e612c, $990951ba, $076dc419, $706af48f,\n      $e963a535, $9e6495a3, $0edb8832, $79dcb8a4, $e0d5e91e, $97d2d988,\n      $09b64c2b, $7eb17cbd, $e7b82d07, $90bf1d91, $1db71064, $6ab020f2,\n      $f3b97148, $84be41de, $1adad47d, $6ddde4eb, $f4d4b551, $83d385c7,\n      $136c9856, $646ba8c0, $fd62f97a, $8a65c9ec, $14015c4f, $63066cd9,\n      $fa0f3d63, $8d080df5, $3b6e20c8, $4c69105e, $d56041e4, $a2677172,\n      $3c03e4d1, $4b04d447, $d20d85fd, $a50ab56b, $35b5a8fa, $42b2986c,\n      $dbbbc9d6, $acbcf940, $32d86ce3, $45df5c75, $dcd60dcf, $abd13d59,\n      $26d930ac, $51de003a, $c8d75180, $bfd06116, $21b4f4b5, $56b3c423,\n      $cfba9599, $b8bda50f, $2802b89e, $5f058808, $c60cd9b2, $b10be924,\n      $2f6f7c87, $58684c11, $c1611dab, $b6662d3d, $76dc4190, $01db7106,\n      $98d220bc, $efd5102a, $71b18589, $06b6b51f, $9fbfe4a5, $e8b8d433,\n      $7807c9a2, $0f00f934, $9609a88e, $e10e9818, $7f6a0dbb, $086d3d2d,\n      $91646c97, $e6635c01, $6b6b51f4, $1c6c6162, $856530d8, $f262004e,\n      $6c0695ed, $1b01a57b, $8208f4c1, $f50fc457, $65b0d9c6, $12b7e950,\n      $8bbeb8ea, $fcb9887c, $62dd1ddf, $15da2d49, $8cd37cf3, $fbd44c65,\n      $4db26158, $3ab551ce, $a3bc0074, $d4bb30e2, $4adfa541, $3dd895d7,\n      $a4d1c46d, $d3d6f4fb, $4369e96a, $346ed9fc, $ad678846, $da60b8d0,\n      $44042d73, $33031de5, $aa0a4c5f, $dd0d7cc9, $5005713c, $270241aa,\n      $be0b1010, $c90c2086, $5768b525, $206f85b3, $b966d409, $ce61e49f,\n      $5edef90e, $29d9c998, $b0d09822, $c7d7a8b4, $59b33d17, $2eb40d81,\n      $b7bd5c3b, $c0ba6cad, $edb88320, $9abfb3b6, $03b6e20c, $74b1d29a,\n      $ead54739, $9dd277af, $04db2615, $73dc1683, $e3630b12, $94643b84,\n      $0d6d6a3e, $7a6a5aa8, $e40ecf0b, $9309ff9d, $0a00ae27, $7d079eb1,\n      $f00f9344, $8708a3d2, $1e01f268, $6906c2fe, $f762575d, $806567cb,\n      $196c3671, $6e6b06e7, $fed41b76, $89d32be0, $10da7a5a, $67dd4acc,\n      $f9b9df6f, $8ebeeff9, $17b7be43, $60b08ed5, $d6d6a3e8, $a1d1937e,\n      $38d8c2c4, $4fdff252, $d1bb67f1, $a6bc5767, $3fb506dd, $48b2364b,\n      $d80d2bda, $af0a1b4c, $36034af6, $41047a60, $df60efc3, $a867df55,\n      $316e8eef, $4669be79, $cb61b38c, $bc66831a, $256fd2a0, $5268e236,\n      $cc0c7795, $bb0b4703, $220216b9, $5505262f, $c5ba3bbe, $b2bd0b28,\n      $2bb45a92, $5cb36a04, $c2d7ffa7, $b5d0cf31, $2cd99e8b, $5bdeae1d,\n      $9b64c2b0, $ec63f226, $756aa39c, $026d930a, $9c0906a9, $eb0e363f,\n      $72076785, $05005713, $95bf4a82, $e2b87a14, $7bb12bae, $0cb61b38,\n      $92d28e9b, $e5d5be0d, $7cdcefb7, $0bdbdf21, $86d3d2d4, $f1d4e242,\n      $68ddb3f8, $1fda836e, $81be16cd, $f6b9265b, $6fb077e1, $18b74777,\n      $88085ae6, $ff0f6a70, $66063bca, $11010b5c, $8f659eff, $f862ae69,\n      $616bffd3, $166ccf45, $a00ae278, $d70dd2ee, $4e048354, $3903b3c2,\n      $a7672661, $d06016f7, $4969474d, $3e6e77db, $aed16a4a, $d9d65adc,\n      $40df0b66, $37d83bf0, $a9bcae53, $debb9ec5, $47b2cf7f, $30b5ffe9,\n      $bdbdf21c, $cabac28a, $53b39330, $24b4a3a6, $bad03605, $cdd70693,\n      $54de5729, $23d967bf, $b3667a2e, $c4614ab8, $5d681b02, $2a6f2b94,\n      $b40bbe37, $c30c8ea1, $5a05df1b, $2d02ef8d  );\n{$ENDIF}\n\nfunction wbDistance(const a, b: TwbVector): Single; overload\nfunction wbDistance(const a, b: IwbMainRecord): Single; overload;\nfunction wbStringToSignatures(aSignatures: string): TwbSignatures;\nfunction wbGetSiblingREFRsWithin(const aMainRecord: IwbMainRecord; aDistance: Single): TDynMainRecords;\nfunction wbGetSiblingRecords(const aElement: IwbElement; aSignatures: TwbSignatures; aOverrides: Boolean): TDynMainRecords;\nfunction FindMatchText(Strings: TStrings; const Str: string): Integer;\nfunction IsFileESM(const aFileName: string): Boolean;\nfunction IsFileESP(const aFileName: string): Boolean;\nfunction IsFileESL(const aFileName: string): Boolean;\nprocedure DeleteDirectory(const DirName: string);\nfunction FullPathToFilename(aString: string): string;\nprocedure wbFlipBitmap(aBitmap: TBitmap; MirrorType: Integer); // MirrorType: 1 - horizontal, 2 - vertical, 0 - both\nfunction wbAlphaBlend(DestDC, X, Y, Width, Height,\n  SrcDC, SrcX, SrcY, SrcWidth, SrcHeight, Alpha: integer): Boolean;\nprocedure SaveFont(aIni: TMemIniFile; aSection, aName: string; aFont: TFont);\nprocedure LoadFont(aIni: TMemIniFile; aSection, aName: string; aFont: TFont);\nfunction wbDDSDataToBitmap(aData: TBytes; Bitmap: TBitmap): Boolean;\nfunction wbDDSStreamToBitmap(aStream: TStream; Bitmap: TBitmap): Boolean;\nfunction wbCRC32Data(aData: TBytes): Cardinal;\nfunction wbCRC32File(aFileName: string): Cardinal;\nfunction wbDecodeCRCList(const aList: string): TDynCardinalArray;\nfunction wbSHA1Data(aData: TBytes): string;\nfunction wbSHA1File(aFileName: string): string;\nfunction wbMD5Data(aData: TBytes): string;\nfunction wbMD5File(aFileName: string): string;\nfunction wbIsAssociatedWithExtension(aExt: string): Boolean;\nfunction wbAssociateWithExtension(aExt, aName, aDescr: string): Boolean;\n\ntype\n  PnxLeveledListCheckCircularStack = ^TnxLeveledListCheckCircularStack;\n  TnxLeveledListCheckCircularStack = record\n    rllcLast       : PnxLeveledListCheckCircularStack;\n    rllcMainRecord : IwbMainRecord;\n  end;\n\nprocedure wbLeveledListCheckCircular(const aMainRecord: IwbMainRecord; aStack: PnxLeveledListCheckCircularStack);\n\ntype\n  TnxFastStringList = class(TStringList)\n  protected\n    function CompareStrings(const S1, S2: string): Integer; override;\n  public\n    constructor CreateSorted(aDups : TDuplicates = dupError);\n\n    procedure Clear(aFreeObjects: Boolean = False); reintroduce;\n  end;\n\n  TnxFastStringListCS = class(TnxFastStringList)\n  public\n    procedure AfterConstruction; override;\n  end;\n\n  TnxFastStringListIC = class(TnxFastStringList)\n  end;\n\nfunction wbExtractNameFromPath(aPathName: String): String;\n\nfunction wbCounterAfterSet(aCounterName: String; const aElement: IwbElement): Boolean;\nfunction wbCounterByPathAfterSet(aCounterName: String; const aElement: IwbElement): Boolean;\nfunction wbCounterContainerAfterSet(aCounterName: String; anArrayName: String; const aElement: IwbElement; DeleteOnEmpty: Boolean = True): Boolean;\nfunction wbCounterContainerByPathAfterSet(aCounterName: String; anArrayName: String; const aElement: IwbElement): Boolean;\nfunction wbFormVerDecider(aBasePtr: Pointer; aEndPtr: Pointer; const aElement: IwbElement; aMinimum: Integer): Integer;\nfunction wbFormVer78Decider(aBasePtr: Pointer; aEndPtr: Pointer; const aElement: IwbElement): Integer;\n\n// BSA helper\n\nfunction MakeDataFileName(FileName, DataPath: String): String;\nfunction FindBSAs(IniName, DataPath: String; var bsaNames: TStringList; var bsaMissing: TStringList): Integer;\nfunction HasBSAs(ModName, DataPath: String; Exact, modini: Boolean; var bsaNames: TStringList; var bsaMissing: TStringList): Integer;\n\nimplementation\n\nuses\n  wbSort;\n\nprocedure wbLeveledListCheckCircular(const aMainRecord: IwbMainRecord; aStack: PnxLeveledListCheckCircularStack);\nvar\n  Stack    : TnxLeveledListCheckCircularStack;\n  s          : string;\n  CER        : IwbContainerElementRef;\n  LLE        : IwbContainerElementRef;\n  i          : Integer;\n  LVLO       : IwbContainerElementRef;\n  Reference  : IwbContainerElementRef;\n  MainRecord : IwbMainRecord;\nbegin\n  Stack.rllcLast := aStack;\n  Stack.rllcMainRecord := aMainRecord;\n\n  while Assigned(aStack) do begin\n    if aStack.rllcMainRecord.LoadOrderFormID = aMainRecord.LoadOrderFormID then begin\n      s := aMainRecord.Name;\n      aStack := Stack.rllcLast;\n      while Assigned(aStack) do begin\n        s := ' -> ' + s;\n        s := aStack.rllcMainRecord.Name + s;\n        if aStack.rllcMainRecord.LoadOrderFormID = aMainRecord.LoadOrderFormID then\n          Break;\n        aStack := aStack.rllcLast;\n      end;\n      s := 'Circular Leveled List found: ' + s;\n      raise Exception.Create(s);\n    end;\n    aStack := aStack.rllcLast;\n  end;\n\n  if aMainRecord.IsTagged then\n    Exit;\n  aMainRecord.Tag;\n\n  if Supports(aMainRecord, IwbContainerElementRef, CER) then begin\n    if Supports(CER.ElementByName['Leveled List Entries'], IwbContainerElementRef, LLE) then begin\n      for i := 0 to Pred(LLE.ElementCount) do\n        if Supports(LLE.Elements[i], IwbContainerElementRef, LVLO) then begin\n          if Supports(LVLO.ElementByName['Reference'], IwbContainerElementRef, Reference) then begin\n            if Supports(Reference.LinksTo, IwbMainRecord, MainRecord) then begin\n              if (MainRecord.Signature = aMainRecord.Signature) then begin\n                MainRecord := MainRecord.WinningOverride;\n                wbLeveledListCheckCircular(MainRecord, @Stack);\n              end;\n            end;\n          end;\n        end;\n    end;\n  end;\nend;\n\nfunction Vec3Subtract(out vOut: TwbVector; const v1, v2: TwbVector): TwbVector;\nbegin\n  with vOut do\n  begin\n    x:= v1.x - v2.x;\n    y:= v1.y - v2.y;\n    z:= v1.z - v2.z;\n  end;\n  Result := vOut;\nend;\n\nfunction Vec3Length(const v: TwbVector): Single;\nbegin\n  with v do Result:= Sqrt(x*x + y*y + z*z);\nend;\n\nfunction wbDistance(const a, b: TwbVector): Single;\nvar\n  t: TwbVector;\nbegin\n  Result := Vec3Length(Vec3Subtract(t,a,b));\nend;\n\nfunction wbDistance(const a, b: IwbMainRecord): Single; overload;\nvar\n  PosA, PosB: TwbVector;\nbegin\n  if not a.GetPosition(PosA) then\n    raise Exception.Create('GetPosition failed');\n  if not b.GetPosition(PosB) then\n    raise Exception.Create('GetPosition failed');\n  Result := wbDistance(PosA, PosB);\nend;\n\nfunction wbStringToSignatures(aSignatures: string): TwbSignatures;\nvar\n  i: integer;\n  s: AnsiString;\nbegin\n  with TStringList.Create do try\n    if Pos(',', aSignatures) <> 0 then Delimiter := ',' else Delimiter := ' ';\n    StrictDelimiter := True;\n    DelimitedText := aSignatures;\n    for i := 0 to Pred(Count) do begin\n      s := AnsiString(Strings[i]);\n      if Length(s) >= SizeOf(TwbSignature) then begin\n        SetLength(Result, Succ(Length(Result)));\n        System.Move(s[1], Result[Pred(Length(Result))][0], SizeOf(TwbSignature));\n      end;\n    end;\n  finally\n    Free;\n  end;\nend;\n\nfunction wbGetSiblingREFRsWithin(const aMainRecord: IwbMainRecord; aDistance: Single): TDynMainRecords;\nvar\n  Count       : Integer;\n  Position    : TwbVector;\n  MaxLoadOrder: Integer;\n\n  procedure FindREFRs(const aElement: IwbElement);\n  var\n    MainRecord : IwbMainRecord;\n    Container  : IwbContainerElementRef;\n    i          : Integer;\n    Temp       : TwbVector;\n  begin\n    if Supports(aElement, IwbMainRecord, MainRecord) then begin\n      if not (aMainRecord.LoadOrderFormID = MainRecord.LoadOrderFormID) and\n        MainRecord.GetPosition(Temp) and\n        (wbDistance(Temp,Position) <= aDistance) then begin\n\n        if High(Result) < Count then\n          SetLength(Result, Length(Result) * 2);\n        Result[Count] := MainRecord.HighestOverrideOrSelf[MaxLoadOrder];\n        Inc(Count);\n\n      end;\n    end else\n      if Supports(aElement, IwbContainerElementRef, Container) then\n        for i := 0 to Pred(Container.ElementCount) do\n          FindREFRs(Container.Elements[i]);\n  end;\n\nvar\n  GroupRecord : IwbGroupRecord;\n  CellMaster  : IwbMainRecord;\n  i, j        : Integer;\nbegin\n  Result := nil;\n  if not aMainRecord.GetPosition(Position) then\n    Exit;\n  if not Supports(aMainRecord.Container, IwbGroupRecord, GroupRecord) then\n    Exit;\n  if not (GroupRecord.GroupType in [8..10]) then\n    Exit;\n  CellMaster := GroupRecord.ChildrenOf;\n  if not Assigned(CellMaster) then\n    Exit;\n  CellMaster := CellMaster.MasterOrSelf;\n  MaxLoadOrder := aMainRecord._File.LoadOrder;\n\n  Count := 0;\n  SetLength(Result, 1024);\n  FindREFRs(CellMaster.ChildGroup);\n  for i := 0 to Pred(CellMaster.OverrideCount) do\n    if CellMaster.Overrides[i]._File.LoadOrder <= aMainRecord._File.LoadOrder then\n      FindREFRs(CellMaster.Overrides[i])\n    else\n      Break;\n  SetLength(Result, Count);\n\n\n  if Length(Result) > 1 then begin\n    wbMergeSort(@Result[0], Length(Result), CompareElementsFormIDAndLoadOrder);\n\n    j := 0;\n    for i := Succ(Low(Result)) to High(Result) do begin\n      if (Result[j].LoadOrderFormID <> Result[i].LoadOrderFormID) and not (Result[j].IsDeleted) then\n        Inc(j);\n      if j <> i then\n        Result[j] := Result[i];\n    end;\n    SetLength(Result, Succ(j));\n  end;\nend;\n\nfunction wbGetSiblingRecords(const aElement: IwbElement; aSignatures: TwbSignatures; aOverrides: Boolean): TDynMainRecords;\n\n  procedure FindRecords(const aElement: IwbElement; var aSignatures: TwbSignatures; var Records: TDynMainRecords; var Count: Integer);\n  var\n    MainRecord : IwbMainRecord;\n    Container  : IwbContainerElementRef;\n    i          : Integer;\n  begin\n    if Supports(aElement, IwbMainRecord, MainRecord) then begin\n      for i := Low(aSignatures) to High(aSignatures) do\n        if MainRecord.Signature = aSignatures[i] then begin\n          if High(Records) < Count then\n            SetLength(Records, Length(Records) * 2);\n          Records[Count] := MainRecord;\n          Inc(Count);\n          Break;\n        end;\n    end else if Supports(aElement, IwbContainerElementRef, Container) then\n      for i := 0 to Pred(Container.ElementCount) do\n        FindRecords(Container.Elements[i], aSignatures, Records, Count);\n  end;\n\nvar\n  MainRecord, Master  : IwbMainRecord;\n  i, j, Count         : Integer;\nbegin\n  Count := 0;\n  SetLength(Result, 4096);\n  if Supports(aElement, IwbMainRecord, MainRecord) then begin\n    FindRecords(MainRecord.ChildGroup, aSignatures, Result, Count);\n    // include overrides from plugins loaded later for that record\n    if aOverrides then begin\n      Master := MainRecord.MasterOrSelf;\n      for i := 0 to Pred(Master.OverrideCount) do\n        if Master.Overrides[i]._File.LoadOrder > MainRecord._File.LoadOrder then\n          FindRecords(Master.Overrides[i].ChildGroup, aSignatures, Result, Count);\n    end;\n  end else\n    // if Group or File object is passed, no overrides\n    FindRecords(aElement, aSignatures, Result, Count);\n\n  SetLength(Result, Count);\n  // removing duplicates (overridden records)\n  if aOverrides and (Length(Result) > 1) then begin\n    wbMergeSort(@Result[0], Length(Result), CompareElementsFormIDAndLoadOrder);\n    j := 0;\n    for i := Succ(Low(Result)) to High(Result) do begin\n      if Result[j].LoadOrderFormID <> Result[i].LoadOrderFormID then\n        Inc(j);\n      if j <> i then\n        Result[j] := Result[i];\n    end;\n    SetLength(Result, Succ(j));\n  end;\nend;\n\nfunction FindMatchText(Strings: TStrings; const Str: string): Integer;\nbegin\n  for Result := 0 to Strings.Count-1 do\n    if SameText(Strings[Result], Str) then\n      Exit;\n  Result := -1;\nend;\n\nfunction IsFileESM(const aFileName: string): Boolean;\nconst\n  ghostesm = '.esm.ghost';\nbegin\n  Result := SameText(ExtractFileExt(aFileName), '.esm') or\n    SameText(Copy(aFileName, Length(aFileName) - Length(ghostesm) + 1, Length(ghostesm)), ghostesm)\nend;\n\nfunction IsFileESP(const aFileName: string): Boolean;\nconst\n  ghostesp = '.esp.ghost';\nbegin\n  Result := SameText(ExtractFileExt(aFileName), '.esp') or\n    SameText(Copy(aFileName, Length(aFileName) - Length(ghostesp) + 1, Length(ghostesp)), ghostesp)\nend;\n\nfunction IsFileESL(const aFileName: string): Boolean;\nconst\n  ghostesp = '.esl.ghost';\nbegin\n  Result := SameText(ExtractFileExt(aFileName), '.esl') or\n    SameText(Copy(aFileName, Length(aFileName) - Length(ghostesp) + 1, Length(ghostesp)), ghostesp)\nend;\n\nprocedure DeleteDirectory(const DirName: string);\nvar\n  FileOp: TSHFileOpStruct;\nbegin\n  FillChar(FileOp, SizeOf(FileOp), 0);\n  FileOp.wFunc := FO_DELETE;\n  FileOp.pFrom := PChar(DirName+#0);//double zero-terminated\n  FileOp.fFlags := FOF_SILENT or FOF_NOERRORUI or FOF_NOCONFIRMATION;\n  SHFileOperation(FileOp);\nend;\n\nfunction FullPathToFilename(aString: string): string;\nvar\n  i: Integer;\n  s: string;\nbegin\n  s := aString;\n  for i := Length(s) downto 1 do\n    if Copy(s, i, 3) = ' \\ ' then begin\n      Delete(s, i, 1);\n      Delete(s, i+1, 1);\n    end else if Copy(s, i, 2) = ' \\' then begin\n      Delete(s, i, 1);\n  \tend else if s[i] = '\"' then\n      s[i] := ''''\n  \telse if s[i] = ':' then\n      s[i] := '-'\n  \telse if s[i] = '/' then\n      s[i] := ' ';\n  while (Length(s)>0) and (s[Length(s)]=' ') do\n    Delete(s, Length(s), 1);\n  Result := s;\nend;\n\nprocedure wbFlipBitmap(aBitmap: TBitmap; MirrorType: Integer);\nvar\n  MemBmp: TBitmap;\n  Dest: TRect;\nbegin\n  if not Assigned(aBitmap) then\n    Exit;\n\n  MemBmp := TBitmap.Create;\n  try\n    MemBmp.Assign(aBitmap);\n    case MirrorType of\n      1:\n        begin\n          Dest.Left := MemBmp.Width;\n          Dest.Top := 0;\n          Dest.Right := -MemBmp.Width;\n          Dest.Bottom := MemBmp.Height\n        end;\n      2:\n        begin\n          Dest.Left := 0;\n          Dest.Top := MemBmp.Height;\n          Dest.Right := MemBmp.Width;\n          Dest.Bottom := -MemBmp.Height\n        end;\n      0:\n        begin\n          Dest.Left := MemBmp.Width;\n          Dest.Top := MemBmp.Height;\n          Dest.Right := -MemBmp.Width;\n          Dest.Bottom := -MemBmp.Height\n        end;\n    end;\n    StretchBlt(MemBmp.Canvas.Handle, Dest.Left, Dest.Top, Dest.Right, Dest.Bottom,\n               MemBmp.Canvas.Handle, 0, 0, MemBmp.Width, MemBmp.Height,\n               SRCCOPY);\n    aBitmap.Assign(MemBmp);\n  finally\n    FreeAndNil(MemBmp);\n  end;\nend;\n\nfunction wbAlphaBlend(DestDC, X, Y, Width, Height,\n  SrcDC, SrcX, SrcY, SrcWidth, SrcHeight, Alpha: integer): Boolean;\nvar\n  BlendFunc: TBlendFunction;\nbegin\n  BlendFunc.BlendOp := AC_SRC_OVER;\n  BlendFunc.BlendFlags := 0;\n  BlendFunc.SourceConstantAlpha := Alpha;\n  if Alpha = 255 then\n    BlendFunc.AlphaFormat := AC_SRC_ALPHA\n  else\n    BlendFunc.AlphaFormat := 0;\n  Result := Windows.AlphaBlend(DestDC, X, Y, Width, Height, SrcDC, SrcX, SrcY, SrcWidth, SrcHeight, BlendFunc);\nend;\n\nprocedure SaveFont(aIni: TMemIniFile; aSection, aName: string; aFont: TFont);\nbegin\n  aIni.WriteString(aSection, aName + 'Name', aFont.Name);\n  aIni.WriteInteger(aSection, aName + 'CharSet', aFont.CharSet);\n  aIni.WriteInteger(aSection, aName + 'Color', aFont.Color);\n  aIni.WriteInteger(aSection, aName + 'Size', aFont.Size);\n  aIni.WriteInteger(aSection, aName + 'Style', Byte(aFont.Style));\nend;\n\nprocedure LoadFont(aIni: TMemIniFile; aSection, aName: string; aFont: TFont);\nbegin\n  aFont.Name    := aIni.ReadString(aSection, aName + 'Name', aFont.Name);\n  aFont.CharSet := TFontCharSet(aIni.ReadInteger(aSection, aName + 'CharSet', aFont.CharSet));\n  aFont.Color   := TColor(aIni.ReadInteger(aSection, aName + 'Color', aFont.Color));\n  aFont.Size    := aIni.ReadInteger(aSection, aName + 'Size', aFont.Size);\n  aFont.Style   := TFontStyles(Byte(aIni.ReadInteger(aSection, aName + 'Style', Byte(aFont.Style))));\nend;\n\nvar\n  crctbl: array[0..7] of array[0..255] of cardinal;\n\nprocedure CRCInit;\nvar\n  c: cardinal;\n  i, j: integer;\nbegin;\n  for i:=0 to 255 do begin;\n    c:=i;\n    for j:=1 to 8 do if odd(c)\n                     then c:=(c shr 1) xor $EDB88320\n                     else c:=(c shr 1);\n    crctbl[0][i]:=c;\n    end;\n\n  for i:=0 to 255 do begin;\n    c:=crctbl[0][i];\n    for j:=1 to 7 do begin;\n      c:=(c shr 8) xor crctbl[0][byte(c)];\n      crctbl[j][i]:=c;\n      end;\n    end;\nend;\n\n{$IFDEF WIN64}\nfunction crc32_update(inbuffer: pointer; buffersize, crc: DWord): DWord;\n// crc-32.  Processes 4 bytes at a time.\ntype\n  PDWord = ^DWord;\n  PByte = ^Byte;\nvar\n  currptr: pointer;\n  i: byte;\nbegin\n  currptr := inbuffer;\n  Result := crc;\n  while buffersize > 4 do\n    begin\n      Result := Result xor PDWord(currptr)^;\n      inc(PByte(currptr), 4);\n      Result := (Result shr 8) xor Crc32Tab[Byte(Result)];\n      Result := (Result shr 8) xor Crc32Tab[Byte(Result)];\n      Result := (Result shr 8) xor CRC32Tab[Byte(Result)];\n      Result := (Result shr 8) xor crc32Tab[Byte(Result)];\n      dec(buffersize, 4);\n    end;\n  for i := 1 to buffersize do\n    begin\n      Result := CRC32tab[Byte(Result xor DWord(PByte(currptr)^))] xor (Result shr 8);\n      inc(PByte(currptr), 1);\n    end;\nend;\n{$ENDIF}\n\nFunction CRCend( crc : DWord ): DWord;\nbegin\n  CRCend := (crc xor CRCSeed);\nend;\n\nfunction ShaCrcRefresh(OldCRC: cardinal; BufPtr: pointer; BufLen: integer): cardinal;\n// Fast CRC32 calculator\n// (c) Aleksandr Sharahov 2009\n// Free for any use\n{$IFDEF WIN64}\nbegin\n  Result := crc32_update(BufPtr, BufLen, OldCRC);\n{$ENDIF WIN64}\n{$IFDEF WIN32}\nasm\n  test edx, edx\n  jz   @ret\n  neg  ecx\n  jz   @ret\n  push ebx\n@head:\n  test dl, 3\n  jz   @bodyinit\n  movzx ebx, byte [edx]\n  inc  edx\n  xor  bl, al\n  shr  eax, 8\n  xor  eax, [ebx*4 + crctbl]\n  inc  ecx\n  jnz  @head\n  pop  ebx\n@ret:\n  ret\n@bodyinit:\n  sub  edx, ecx\n  add  ecx, 8\n  jg   @bodydone\n  push esi\n  push edi\n  mov  edi, edx\n  mov  edx, eax\n@bodyloop:\n  mov ebx, [edi + ecx - 4]\n  xor edx, [edi + ecx - 8]\n  movzx esi, bl\n  mov eax, [esi*4 + crctbl + 1024*3]\n  movzx esi, bh\n  xor eax, [esi*4 + crctbl + 1024*2]\n  shr ebx, 16\n  movzx esi, bl\n  xor eax, [esi*4 + crctbl + 1024*1]\n  movzx esi, bh\n  xor eax, [esi*4 + crctbl + 1024*0]\n\n  movzx esi, dl\n  xor eax, [esi*4 + crctbl + 1024*7]\n  movzx esi, dh\n  xor eax, [esi*4 + crctbl + 1024*6]\n  shr edx, 16\n  movzx esi, dl\n  xor eax, [esi*4 + crctbl + 1024*5]\n  movzx esi, dh\n  xor eax, [esi*4 + crctbl + 1024*4]\n\n  add ecx, 8\n  jg  @done\n\n  mov ebx, [edi + ecx - 4]\n  xor eax, [edi + ecx - 8]\n  movzx esi, bl\n  mov edx, [esi*4 + crctbl + 1024*3]\n  movzx esi, bh\n  xor edx, [esi*4 + crctbl + 1024*2]\n  shr ebx, 16\n  movzx esi, bl\n  xor edx, [esi*4 + crctbl + 1024*1]\n  movzx esi, bh\n  xor edx, [esi*4 + crctbl + 1024*0]\n\n  movzx esi, al\n  xor edx, [esi*4 + crctbl + 1024*7]\n  movzx esi, ah\n  xor edx, [esi*4 + crctbl + 1024*6]\n  shr eax, 16\n  movzx esi, al\n  xor edx, [esi*4 + crctbl + 1024*5]\n  movzx esi, ah\n  xor edx, [esi*4 + crctbl + 1024*4]\n\n  add ecx, 8\n  jle @bodyloop\n  mov eax, edx\n@done:\n  mov edx, edi\n  pop edi\n  pop esi\n@bodydone:\n  sub ecx, 8\n  jl @tail\n  pop ebx\n  ret\n@tail:\n  movzx ebx, byte [edx + ecx];\n  xor bl,al;\n  shr eax,8;\n  xor eax, [ebx*4 + crctbl];\n  inc ecx;\n  jnz @tail;\n  pop ebx\n  ret\n{$ENDIF WIN32}\nend;\n\nfunction wbCRC32Data(aData: TBytes): Cardinal;\nbegin\n  Result := not ShaCrcRefresh($FFFFFFFF, @aData[0], Length(aData));\nend;\n\nfunction wbCRC32File(aFileName: string): Cardinal;\nvar\n  Data: TBytes;\nbegin\n  Result := 0;\n  if FileExists(aFileName) then\n    with TFileStream.Create(aFileName, fmOpenRead + fmShareDenyNone) do try\n      SetLength(Data, Size);\n      ReadBuffer(Data[0], Length(Data));\n      Result := wbCRC32Data(Data);\n    finally\n      Free;\n    end;\nend;\n\nfunction wbDecodeCRCList(const aList: string): TDynCardinalArray;\nvar\n  i: Integer;\n  s: string;\n  j: Int64;\nbegin\n  Result := nil;\n  try\n    with TStringList.Create do try\n      CommaText := aList;\n      for i := 0 to Pred(Count) do begin\n        s := Trim(Strings[i]);\n        if Length(s) <> 8 then\n          Abort;\n        j := StrToInt64('$'+s);\n        if (j < Low(Cardinal)) or (j > High(Cardinal)) then\n          Abort;\n        SetLength(Result, Succ(Length(Result)));\n        Result[High(Result)] := j;\n      end;\n    finally\n      Free;\n    end;\n  except\n    SetLength(Result, 1);\n    Result[0] := $FFFFFFFF;\n  end;\nend;\n\nfunction CryptAcquireContext(var phProv: DWORD;\n  pszContainer, pszProvider: LPCSTR; dwProvType, dwFlags: DWORD): BOOL;\n  stdcall; external advapi32 name 'CryptAcquireContextA';\nfunction CryptCreateHash(hProv,Algid,hKey,dwFlags: DWORD;\n  var phHash: DWORD): BOOL; stdcall; external advapi32;\nfunction CryptHashData(hHash: DWORD; pbData: PBYTE; dwDataLen,\n  dwFlags: DWORD): BOOL; stdcall; external advapi32;\nfunction CryptGetHashParam(hHash, dwParam: DWORD; pbData: PBYTE;\n  var pdwDataLen: DWORD; dwFlags: DWORD): BOOL; stdcall; external advapi32;\nfunction CryptDestroyHash(hHash: DWORD): BOOL; stdcall; external advapi32;\nfunction CryptReleaseContext(hProv: DWORD; dwFlags: DWORD): BOOL; stdcall; external advapi32;\n\nfunction CryptoAPIGetHash(Data: Pointer; nSize: Cardinal; HashType: Cardinal): TBytes;\nconst\n  HP_HASHVAL           = $0002; {hash value}\n  PROV_RSA_FULL        = 1;\n  CRYPT_VERIFYCONTEXT  = $F0000000;\nvar\n  hProv, hHash: Cardinal;\nbegin\n  if CryptAcquireContext(hProv, nil, nil, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT) then try\n    if CryptCreateHash(hProv, HashType, 0, 0, hHash) then try\n      if CryptHashData(hHash, Data, nSize, 0) then begin\n        if CryptGetHashParam(hHash, HP_HASHVAL, nil, nSize, 0) then begin\n          SetLength(Result, nSize);\n          if not CryptGetHashParam(hHash, HP_HASHVAL, @Result[0], nSize, 0) then\n            SetLength(Result, 0);\n        end;\n      end;\n    finally\n      CryptDestroyHash(hHash);\n    end;\n  finally\n    CryptReleaseContext(hProv, 0);\n  end;\nend;\n\nconst\n  ALG_CRC32 = $0001;\n  ALG_MD2 = $8001;\n  ALG_MD4 = $8002;\n  ALG_MD5 = $8003;\n  ALG_SHA = $8004;\n\nfunction wbCryptoApiHashData(aData: TBytes; aALG: Cardinal): string;\n  function BytesToHexStr(aBytes: TBytes): string;\n  var\n    i: Cardinal;\n    bt: Byte;\n  const\n    Hex = '0123456789abcdef';\n  begin\n    Result:= '';\n    for i:= Low(aBytes) to High(aBytes) do begin\n      bt := aBytes[i];\n      Result:= Result + Hex[bt shr $4 + 1] + Hex[bt and $0f + 1]\n    end;\n  end;\nbegin\n  Result := BytesToHexStr(CryptoAPIGetHash(@aData[0], Length(aData), aALG));\nend;\n\nfunction wbSHA1Data(aData: TBytes): string;\nbegin\n  Result := wbCryptoApiHashData(aData, ALG_SHA);\nend;\n\nfunction wbSHA1File(aFileName: string): string;\nvar\n  Data: TBytes;\nbegin\n  Result := '';\n  if FileExists(aFileName) then\n    with TFileStream.Create(aFileName, fmOpenRead + fmShareDenyNone) do try\n      SetLength(Data, Size);\n      ReadBuffer(Data[0], Length(Data));\n      Result := wbSHA1Data(Data);\n    finally\n      Free;\n    end;\nend;\n\nfunction wbMD5Data(aData: TBytes): string;\nbegin\n  Result := wbCryptoApiHashData(aData, ALG_MD5);\nend;\n\nfunction wbMD5File(aFileName: string): string;\nvar\n  Data: TBytes;\nbegin\n  Result := '';\n  if FileExists(aFileName) then\n    with TFileStream.Create(aFileName, fmOpenRead + fmShareDenyNone) do try\n      SetLength(Data, Size);\n      ReadBuffer(Data[0], Length(Data));\n      Result := wbMD5Data(Data);\n    finally\n      Free;\n    end;\nend;\n\n\n{ TnxFastStringList }\n\nprocedure TnxFastStringList.Clear(aFreeObjects: Boolean);\nvar\n  i: Integer;\nbegin\n  if aFreeObjects then\n    for i := 0 to Pred(Count) do\n      Objects[i].Free;\n  inherited Clear;\nend;\n\nfunction TnxFastStringList.CompareStrings(const S1, S2: string): Integer;\nbegin\n  {x$IFDEF DCC6OrLater}\n  if CaseSensitive then\n    Result := CompareStr(S1, S2)\n  else\n  {x$ENDIF}\n    Result := CompareText(S1, S2);\nend;\n\nconstructor TnxFastStringList.CreateSorted(aDups: TDuplicates);\nbegin\n  Create;\n  Duplicates := aDups;\n  Sorted := True;\nend;\n\n{ TnxFastStringListCS }\n\nprocedure TnxFastStringListCS.AfterConstruction;\nbegin\n  inherited;\n  {x$IFDEF DCC6OrLater}\n  CaseSensitive := True;\n  {x$ENDIF}\nend;\n\nfunction wbExtractNameFromPath(aPathName: String): String;\nbegin\n  Result := aPathName;\n  while Pos('\\', Result)>0 do\n    Delete(Result, 1, Pos('\\', Result))\nend;\n\nfunction wbCounterAfterSet(aCounterName: String; const aElement: IwbElement): Boolean;\nvar\n  Element         : IwbElement;\n  Container       : IwbContainer;\n  SelfAsContainer : IwbContainer;\nbegin\n  Result := False;\n  if wbBeginInternalEdit then try\n    if (Length(aCounterName)>=4) and Supports(aElement.Container, IwbContainer, Container) and\n       Supports(aElement, IwbContainer, SelfAsContainer) then begin\n      Element := Container.ElementByName[aCounterName];\n      if not Assigned(Element) then  // Signatures not listed in mrDef cannot be added\n        Element := Container.Add(Copy(aCounterName, 1, 4));\n      if Assigned(Element) and (SameText(Element.Name, aCounterName)) then try\n        if (Element.GetNativeValue<>SelfAsContainer.GetElementCount) then\n          Element.SetNativeValue(SelfAsContainer.GetElementCount);\n        Result := True;\n      except\n        // No exception if the value cannot be set, expected non value\n      end;\n    end;\n  finally\n    wbEndInternalEdit;\n  end;\nend;\n\nfunction wbCounterByPathAfterSet(aCounterName: String; const aElement: IwbElement): Boolean;\nvar\n  Element         : IwbElement;\n  Container       : IwbContainer;\n  SelfAsContainer : IwbContainer;\nbegin\n  Result := False;\n  if wbBeginInternalEdit then try\n    if (Length(aCounterName)>=4) and Supports(aElement.Container, IwbContainer, Container) and\n       Supports(aElement, IwbContainer, SelfAsContainer) then begin\n      Element := Container.ElementByPath[aCounterName];\n//      if not Assigned(Element) then  // Signatures not listed in mrDef cannot be added\n//        Element := Container.Add(Copy(aCounterName, 1, 4));\n      if Assigned(Element) and (SameText(Element.Name, wbExtractNameFromPath(aCounterName))) then try\n        if (Element.GetNativeValue<>SelfAsContainer.GetElementCount) then\n          Element.SetNativeValue(SelfAsContainer.GetElementCount);\n        Result := True;\n      except\n        // No exception if the value cannot be set, expected non value\n      end;\n    end;\n  finally\n    wbEndInternalEdit;\n  end;\nend;\n\nfunction wbCounterContainerAfterSet(aCounterName: String; anArrayName: String; const aElement: IwbElement; DeleteOnEmpty: Boolean = True): Boolean;\nvar\n  Element         : IwbElement;\n  Elems           : IwbElement;\n  Container       : IwbContainer;\nbegin\n  Result := False;  // You may need to check alterative counter name\n  if wbBeginInternalEdit then try\n    if Supports(aElement, IwbContainer, Container) then begin\n      Element := Container.ElementByName[aCounterName];\n      Elems   := Container.ElementByName[anArrayName];\n      if Assigned(Element) then begin\n        if not Assigned(Elems) then\n           if DeleteOnEmpty then\n            Container.RemoveElement(aCounterName)\n          else if Element.GetNativeValue <> 0 then\n            Element.SetNativeValue(0);\n        Result := True; // Counter member exists\n      end;\n    end;\n  finally\n    wbEndInternalEdit;\n  end;\nend;\n\nfunction wbCounterContainerByPathAfterSet(aCounterName: String; anArrayName: String; const aElement: IwbElement): Boolean;\nvar\n  Element         : IwbElement;\n  Elems           : IwbElement;\n  Container       : IwbContainer;\nbegin\n  Result := False;  // You may need to check alterative counter name\n  if wbBeginInternalEdit then try\n    if Supports(aElement, IwbContainer, Container) then begin\n      Element := Container.ElementByPath[aCounterName];\n      Elems   := Container.ElementByName[anArrayName];\n      if Assigned(Element) then begin\n        if not Assigned(Elems) then\n          if Element.GetNativeValue <> 0 then\n            Element.SetNativeValue(0);\n        Result := True; // Counter member exists\n      end;\n    end;\n  finally\n    wbEndInternalEdit;\n  end;\nend;\n\n// BSA helper\n\nfunction MakeDataFileName(FileName, DataPath: String): String;\nbegin\n  // MO uses 3 chars aliases\n  if Length(FileName) < 3 then\n    Result := ''\n  else if not ((FileName[1] = '\\') or (FileName[2] = ':')) then\n    Result := DataPath + FileName\n  else\n    Result := FileName;\nend;\n\nfunction FindBSAs(IniName, DataPath: String; var bsaNames: TStringList; var bsaMissing: TStringList): Integer;\nvar\n  i: Integer;\n  j: Integer;\n  s: String;\n  t: String;\nbegin\n  Result := 0;\n  j := 0;\n  if Assigned(bsaNames) then\n    j := bsaNames.Count;\n  if Assigned(bsaMissing) then\n    j := j + bsaMissing.Count;\n\n  if Assigned(bsaNames) then\n    // TIniFile uses GetPrivateProfileString() to read data, it is virtualized by MO\n    // TMemIniFile reads from string list directly, not supported by MO\n    with TIniFile.Create(iniName) do try\n      with TStringList.Create do try\n        if wbGameMode in [gmTES4, gmFO3, gmFNV] then\n          Text := StringReplace(ReadString('Archive', 'sArchiveList', ''), ',' ,#10, [rfReplaceAll])\n        else if wbGameMode in [ gmTES5, gmSSE ] then\n          Text := StringReplace(\n            ReadString('Archive', 'sResourceArchiveList', '') + ',' +\n            ReadString('Archive', 'sResourceArchiveList2', ''),\n            ',', #10, [rfReplaceAll]\n          )\n        else if wbGameMode = gmFO4 then\n          Text := StringReplace(\n            ReadString('Archive', 'sResourceIndexFileList', '') + ',' +\n            ReadString('Archive', 'sResourceStartUpArchiveList', '') + ',' +\n            ReadString('Archive', 'sResourceArchiveList', '') + ',' +\n            ReadString('Archive', 'sResourceArchiveList2', ''),\n            ',', #10, [rfReplaceAll]\n          );\n        for i := 0 to Pred(Count) do begin\n          s := Trim(Strings[i]);\n          t := MakeDataFileName(s, DataPath);\n          if (Length(t)>0) then\n            if FileExists(t) then begin\n              if wbContainerHandler.ContainerExists(t) then\n                Continue;\n              bsaNames.Add(s);\n            end else\n              if Assigned(bsaMissing) then\n                bsaMissing.Add(s);\n        end;\n        Result := bsaNames.Count  + bsaMissing.Count - j; // How many were added\n      finally\n        Free;\n      end;\n    finally\n      Free;\n    end;\nend;\n\nfunction HasBSAs(ModName, DataPath: String; Exact, modini: Boolean; var bsaNames: TStringList; var bsaMissing: TStringList): Integer;\nvar\n  j: Integer;\n  t: String;\n  F: TSearchRec;\nbegin\n  Result := 0;\n  j := 0;\n  if Assigned(bsaNames) then\n    j := bsaNames.Count;\n  if Assigned(bsaMissing) then\n    j := j + bsaMissing.Count;\n  // All games prior to Skyrim load BSA files with partial matching, Skyrim requires exact name match and\n  //   can use a private ini to specify the bsa to use.\n  if not exact then\n    ModName := ModName + '*';\n  if FindFirst(DataPath + ModName + wbArchiveExtension, faAnyFile, F) = 0 then try\n    repeat\n      if wbContainerHandler.ContainerExists(DataPath + F.Name) then\n        Continue;\n      t := MakeDataFileName(F.Name, DataPath);\n      if (Length(t)>0) and FileExists(t) then begin\n        if not wbContainerHandler.ContainerExists(t) then\n          if Assigned(bsaNames) then\n            bsaNames.Add(F.Name);\n      end else\n        if Assigned(bsaMissing) then\n          bsaMissing.Add(F.Name);\n    until FindNext(F) <> 0;\n    Result := bsaNames.Count  + bsaMissing.Count - j;\n  finally\n    FindClose(F);\n  end;\n\n  if modIni then\n    Result := Result + FindBSAs(DataPath+ChangeFileExt(ModName, '.ini'), DataPath, bsaNames, bsaMissing);\nend;\n\nfunction wbDDSDataToBitmap(aData: TBytes; Bitmap: TBitmap): Boolean;\nvar\n  img: TImageData;\n  ms: TMemoryStream;\nbegin\n  Result := False;\n  if not LoadImageFromMemory(@aData[0], Length(aData), img) then\n    Exit;\n  ms := TMemoryStream.Create;\n  try\n    if SaveImageToStream('BMP', ms, img) then begin\n      ms.Position := 0;\n      Bitmap.LoadFromStream(ms);\n      Result := True;\n    end;\n  finally\n    FreeImage(img);\n    ms.Free;\n  end;\nend;\n\nfunction wbDDSStreamToBitmap(aStream: TStream; Bitmap: TBitmap): Boolean;\nvar\n  img: TImageData;\n  ms: TMemoryStream;\nbegin\n  Result := False;\n  if not LoadImageFromStream(aStream, img) then\n    Exit;\n  ms := TMemoryStream.Create;\n  try\n    if SaveImageToStream('BMP', ms, img) then begin\n      ms.Position := 0;\n      Bitmap.LoadFromStream(ms);\n      Result := True;\n    end;\n  finally\n    FreeImage(img);\n    ms.Free;\n  end;\nend;\n\nfunction wbIsAssociatedWithExtension(aExt: string): Boolean;\nvar\n  Name: string;\nbegin\n  Result := False;\n  with TRegistry.Create do try\n    RootKey := HKEY_CURRENT_USER;\n    if OpenKey('\\Software\\Classes\\' + LowerCase(aExt), False) then begin\n      Name := ReadString('');\n      if OpenKey('\\Software\\Classes\\' + Name + '\\DefaultIcon', False) then\n        if SameText(ReadString(''), ParamStr(0)) then\n          Result := True;\n    end;\n  finally\n    Free;\n  end;\nend;\n\nfunction wbAssociateWithExtension(aExt, aName, aDescr: string): Boolean;\nbegin\n  Result := False;\n\n  if aExt = '' then\n    Exit\n  else\n    aExt := LowerCase(aExt);\n\n  if aExt[1] <> '.' then\n    aExt := '.' + aExt;\n\n  with TRegistry.Create do try\n    RootKey := HKEY_CURRENT_USER;\n\n    if OpenKey('\\Software\\Classes\\' + aExt, True) then\n      WriteString('', aName)\n    else\n      raise Exception.Create('Not enough rights to modify the registry');\n\n    if OpenKey('\\Software\\Classes\\' + aName, True) then\n      WriteString('', aDescr);\n\n    if OpenKey('\\Software\\Classes\\' + aName + '\\DefaultIcon', True) then\n      WriteString('', ParamStr(0));\n\n    if OpenKey('\\Software\\Classes\\' + aName + '\\shell\\open\\command', True) then\n      WriteString('', ParamStr(0) + ' \"%1\"');\n\n    Result := True;\n  finally\n    Free;\n  end;\n\n  SHChangeNotify(SHCNE_ASSOCCHANGED, SHCNF_IDLIST, nil, nil);\nend;\n\nfunction wbFormVerDecider(aBasePtr: Pointer; aEndPtr: Pointer; const aElement: IwbElement; aMinimum: Integer): Integer;\nvar\n  FormVer    : Integer;\n  MainRecord : IwbMainRecord;\n  Element    : IwbElement;\nbegin\n  Result := 1;\n  if not Assigned(aElement) then Exit;\n  MainRecord := aElement.GetContainingMainRecord;\n  if not Assigned(MainRecord) then Exit;\n\n  Element := MainRecord.ElementByPath['Record Header\\Form Version'];\n  if Assigned(Element) then begin\n    FormVer := Element.NativeValue;\n    if FormVer<aMinimum then\n      Result := 0;\n  end;\nend;\n\nfunction wbFormVer78Decider(aBasePtr: Pointer; aEndPtr: Pointer; const aElement: IwbElement): Integer;\nbegin\n  Result := wbFormVerDecider(aBasePtr, aEndPtr, aElement, 78);\nend;\n\ninitialization\n  CRCInit;\n\nend.\n"
  },
  {
    "path": "lib/xedit/wbImplementation.pas",
    "content": "{*******************************************************************************\n\n     The contents of this file are subject to the Mozilla Public License\n     Version 1.1 (the \"License\"); you may not use this file except in\n     compliance with the License. You may obtain a copy of the License at\n     http://www.mozilla.org/MPL/\n\n     Software distributed under the License is distributed on an \"AS IS\"\n     basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the\n     License for the specific language governing rights and limitations\n     under the License.\n\n*******************************************************************************}\n\nunit wbImplementation;\n\n{$I wbDefines.inc}\n\n{$DEFINE DBGSUBREC}\n\ninterface\n\nuses\n  Variants,\n  Windows,\n  Classes,\n  SysUtils,\n  Contnrs,\n  Math,\n  wbInterface,\n  {$IFDEF USE_CODESITE}\n  CodeSiteLogging,\n  {$ENDIF}\n  Zlibex,\n  lz4;\n\nconst\n  DefaultVCS1 = 0;\n  DefaultVCS2 = 0;\n\nvar\n  RecordToSkip       : TStringList;\n  GroupToSkip        : TStringList;\n  ChaptersToSkip     : TStringList;\n  SubRecordOrderList : TStringList;\n\nprocedure wbMastersForFile(const aFileName: string; aMasters: TStrings);\nfunction wbFile(const aFileName: string; aLoadOrder: Integer = -1; aCompareTo: string = '';\n  IsTemporary: Boolean = False; aOnlyHeader: Boolean = False): IwbFile;\nfunction wbNewFile(const aFileName: string; aLoadOrder: Integer): IwbFile;\nprocedure wbFileForceClosed;\n\nfunction StartsWith(const s, t: string): Boolean;\n\nfunction wbCopyElementToFile(const aSource: IwbElement; aFile: IwbFile; aAsNew, aDeepCopy: Boolean; const aPrefixRemove, aPrefix, aSuffix: string): IwbElement;\nfunction wbCopyElementToRecord(const aSource: IwbElement; aMainRecord: IwbMainRecord; aAsNew, aDeepCopy: Boolean): IwbElement;\n\nfunction wbFindWinningMainRecordByEditorID(const aSignature: TwbSignature; const aEditorID: string): IwbMainRecord;\nfunction wbFormListToArray(const aFormList: IwbMainRecord; const aSignatures: string): TDynMainRecords;\n\nfunction wbCreateKeepAliveRoot: IwbKeepAliveRoot;\n\nfunction wbBeginKeepAlive: Integer;\nfunction wbEndKeepAlive: Integer;\n\nimplementation\n\nuses\n  wbSort;\n\nconst\n  EmptyPtr: AnsiChar = #0;\n\ntype\n  PwbKeepAliveContext = ^TwbKeepAliveContext;\n  TwbKeepAliveContext = record\n    kacHead     : IwbContainerElementRef;\n    kacPrev     : PwbKeepAliveContext;\n    kacFinished : Boolean;\n  end;\n\n  TwbKeepAliveRoot = class(TInterfacedObject, IwbKeepAliveRoot)\n  protected {private}\n    karKAC: PwbKeepAliveContext;\n\n    procedure Setup;\n    procedure Teardown;\n\n    constructor Create;\n    destructor Destroy; override;\n\n    {---IwbKeepAliveRoot---}\n    procedure Done;\n  end;\n\nfunction wbCreateKeepAliveRoot: IwbKeepAliveRoot;\nbegin\n  Result := TwbKeepAliveRoot.Create;\nend;\n\nthreadvar\n  wbKeepAliveContext : PwbKeepAliveContext;\n\n  wbKeepAliveCount   : Integer;\n  wbKeepAliveRoot    : IwbKeepAliveRoot;\n\nfunction wbBeginKeepAlive: Integer;\nbegin\n  Result := Succ(wbKeepAliveCount);\n  wbKeepAliveCount := Result;\n  if (Result > 0) and not Assigned(wbKeepAliveRoot) then\n    wbKeepAliveRoot := wbCreateKeepAliveRoot;\nend;\n\nfunction wbEndKeepAlive: Integer;\nbegin\n  Result := Pred(wbKeepAliveCount);\n  wbKeepAliveCount := Result;\n  if Result = 0 then\n    wbKeepAliveRoot := nil;\nend;\n\nconst\n  TheEmptyPlugin = 'SavesEmptyPlugin.esp';\n\ntype\n  TwbMainRecordEntryHeader = record\n    mrehGeneration : Cardinal;\n    mrehHead       : Pointer;\n    mrehTail       : Pointer;\n    mrehCount      : Cardinal;\n    mrehInUse      : Boolean;\n\n    procedure BeginUse;\n    procedure EndUse;\n  end;\n\nvar\n  mreHeader: TwbMainRecordEntryHeader;\n\nfunction wbCopyElementToFile(const aSource: IwbElement; aFile: IwbFile; aAsNew, aDeepCopy: Boolean; const aPrefixRemove, aPrefix, aSuffix: string): IwbElement;\nvar\n  MainRecord  : IwbMainRecord;\n  Container   : IwbContainer;\n  Target      : IwbElement;\nbegin\n  Inc(wbCopyIsRunning);\n  try\n    if (wbCurrentTick>0) and (wbCurrentTick+500<GetTickCount) then begin\n      wbProgressCallback('');\n      wbCurrentTick := GetTickCount;\n    end;\n    Container := aSource.Container;\n    if Assigned(Container) then begin\n      if Supports(Container, IwbMainRecord, MainRecord) then\n        Container := MainRecord.HighestOverrideOrSelf[aFile.LoadOrder];\n      Target := wbCopyElementToFile(Container, aFile, False, False, aPrefixRemove, aPrefix, aSuffix)\n    end else begin\n      Result := aFile;\n      Exit;\n    end;\n\n    if Assigned(Target) then\n      Result := Target.AddIfMissing(aSource, aAsNew, aDeepCopy, aPrefixRemove, aPrefix, aSuffix)\n    else\n      Result := nil;\n  finally\n    Dec(wbCopyIsRunning);\n  end;\nend;\n\nfunction wbCopyElementToRecord(const aSource: IwbElement; aMainRecord: IwbMainRecord; aAsNew, aDeepCopy: Boolean): IwbElement;\nvar\n  Container                   : IwbContainer;\n  Target                      : IwbElement;\n  CER                         : IwbContainerElementRef;\nbegin\n  CER := aMainRecord as IwbContainerElementRef;\n\n  if Assigned(aSource) and (aSource.ElementType = etMainRecord) then begin\n    if aSource.Equals(aMainRecord) then\n      Result := nil\n    else\n      Result := aMainRecord;\n    Exit;\n  end;\n\n  Container := aSource.Container;\n  Assert(Assigned(Container));\n  Target := wbCopyElementToRecord(Container, aMainRecord, False, False);\n\n  if Assigned(Target) then\n    Result := Target.AddIfMissing(aSource, aAsNew, aDeepCopy, '', '', '')\n  else\n    Result := nil;\nend;\n\nfunction StartsWith(const s, t: string): Boolean;\nvar\n  i                           : Integer;\nbegin\n  Result := False;\n  if Length(s) < Length(t) then\n    Exit;\n\n  for i := 1 to Length(t) do\n    if UpCase(s[i]) <> UpCase(t[i]) then\n      Exit;\n  Result := True;\nend;\n\ntype\n  IwbElementInternal = interface(IwbElement)\n    ['{556DF03C-2723-46FC-99C6-F50BB5E66F86}']\n    procedure SetContainer(const aContainer: IwbContainer);\n    procedure SetSortOrder(aIndex: Integer);\n    procedure SetMemoryOrder(aIndex: Integer);\n    function GetMemoryOrder: Integer;\n    procedure SetModified(aValue: Boolean);\n    procedure SetInternalModified(aValue: Boolean);\n    function GetCountedRecordCount: Cardinal;\n    procedure PrepareSave;\n    procedure MasterCountUpdated(aOld, aNew: Byte);\n    procedure MasterIndicesUpdated(const aOld, aNew: TBytes);\n    procedure FindUsedMasters(aMasters: PwbUsedMasters);\n    procedure InvalidateStorage;\n    function Reached: Boolean;\n\n    function BeginDecide: Boolean;\n    procedure EndDecide;\n\n    property Modified: Boolean\n      read GetModified\n      write SetModified;\n\n    property MemoryOrder: Integer\n      read GetMemoryOrder\n      write SetMemoryOrder;\n\n    property InternalModified: Boolean\n      write SetInternalModified;\n  end;\n\n  TwbElement = class(TInterfacedObject, IInterface, IwbElement, IwbElementInternal)\n  protected\n    eContainer       : Pointer{IwbContainer}; //weak reference\n    eSortOrder       : Integer;\n    eMemoryOrder     : Integer;\n    eStates          : TwbElementStates;\n    eSortKey         : string;\n    eExtendedSortKey : string;\n\n    eExternalRefs    : Integer;\n    eContainerRef    : IwbContainerElementRef;\n\n    eUpdateCount     : Integer;\n\n    {---IInterface---}\n    function _AddRef: Integer; virtual; stdcall;\n    function _Release: Integer; virtual; stdcall;\n\n    {---IwbElementInternal---}\n    function InternalAddRef: Integer; stdcall;\n    function InternalRelease: Integer; stdcall;\n    function IwbElementInternal._AddRef = InternalAddRef;\n    function IwbElementInternal._Release = InternalRelease;\n    function GetCountedRecordCount: Cardinal; virtual;\n    procedure PrepareSave; virtual;\n    procedure MasterCountUpdated(aOld, aNew: Byte); virtual;\n    procedure MasterIndicesUpdated(const aOld, aNew: TBytes); virtual;\n    procedure FindUsedMasters(aMasters: PwbUsedMasters); virtual;\n    procedure InvalidateStorage; virtual;\n    procedure InvalidateParentStorage; virtual;\n    function Reached: Boolean; virtual;\n    function LinksToParent: Boolean; virtual;\n    procedure SetMemoryOrder(aIndex: Integer);\n    function GetMemoryOrder: Integer;\n\n    function BeginDecide: Boolean;\n    procedure EndDecide;\n\n    procedure NotifyChanged(aContainer: Pointer);\n    procedure NotifyChangedInternal(aContainer: Pointer); virtual;\n\n    procedure ReportRequiredMasters(aStrings: TStrings; aAsNew: Boolean; Recursive: Boolean = True; Initial: Boolean = false); virtual;\n\n    function GetElementID: Cardinal;\n    function GetElementStates: TwbElementStates;\n    procedure SetElementState(aState: TwbElementState; Clear: Boolean = false);\n    function Equals(const aElement: IwbElement): Boolean; reintroduce;\n\n    procedure Hide;\n    procedure Show;\n    function GetIsHidden: Boolean;\n\n    function HasErrors: Boolean; virtual;\n\n    function GetValue: string; virtual;\n    function GetCheck: string; virtual;\n    function GetSortKey(aExtended: Boolean): string; virtual;\n    function GetSortKeyInternal(aExtended: Boolean): string; virtual;\n    function GetSortPriority: Integer; virtual;\n    function GetName: string; virtual;\n    function GetBaseName: string; virtual;\n    function GetDisplayName: string; virtual;\n    function GetShortName: string; virtual;\n    function GetPath: string; virtual;\n    function GetFullPath: string; virtual;\n    function GetPathName: string; virtual;\n    function GetSkipped: Boolean; virtual;\n    function GetDef: IwbNamedDef; virtual;\n    function GetValueDef: IwbValueDef; virtual;\n    function GetResolvedValueDef: IwbValueDef; virtual;\n    function GetElementType: TwbElementType; virtual;\n    procedure DoReset(aForce: Boolean); virtual;\n    function GetContainer: IwbContainer;\n    function GetContainingMainRecord: IwbMainRecord; virtual;\n    function GetFile: IwbFile; virtual;\n    function GetReferenceFile: IwbFile; virtual;\n    function GetSortOrder: Integer;\n    procedure BuildRef; virtual;\n    procedure AddReferencedFromID(aFormID: Cardinal); virtual;\n    function CompareExchangeFormID(aOldFormID: Cardinal; aNewFormID: Cardinal): Boolean; virtual;\n    function GetIsEditable: Boolean; virtual;\n    function GetIsRemoveable: Boolean; virtual;\n    function GetEditValue: string; virtual;\n    procedure SetEditValue(const aValue: string); virtual;\n    function GetNativeValue: Variant; virtual;\n    procedure SetNativeValue(const aValue: Variant); virtual;\n    procedure RequestStorageChange(var aBasePtr, aEndPtr: Pointer; aNewSize: Cardinal); virtual;\n    function GetConflictPriority: TwbConflictPriority; virtual;\n    function GetConflictPriorityCanChange: Boolean; virtual;\n    function GetModified: Boolean;\n    procedure MarkModifiedRecursive; virtual;\n    function GetIsInjected: Boolean; virtual;\n    function GetReferencesInjected: Boolean; virtual;\n    function GetInjectionSourceFiles: TDynFiles; virtual;\n    function GetIsNotReachable: Boolean; virtual;\n    procedure SetModified(aValue: Boolean); virtual;\n    procedure SetInternalModified(aValue: Boolean); virtual;\n    function GetDataSize: Integer; virtual;\n    procedure SetDataSize(aSize: Integer); virtual;\n    procedure MergeStorage(var aBasePtr: Pointer; aEndPtr: Pointer);\n    procedure MergeStorageInternal(var aBasePtr: Pointer; aEndPtr: Pointer); virtual;\n    procedure InformStorage(var aBasePtr: Pointer; aEndPtr: Pointer); virtual;\n    procedure Remove; virtual;\n    function CanContainFormIDs: Boolean; virtual;\n    function AddIfMissing(const aElement: IwbElement; aAsNew, aDeepCopy : Boolean; const aPrefixRemove, aPrefix, aSuffix: string): IwbElement;\n    function AddIfMissingInternal(const aElement: IwbElement; aAsNew, aDeepCopy : Boolean; const aPrefixRemove, aPrefix, aSuffix: string): IwbElement; virtual;\n    procedure ResetConflict; virtual;\n    procedure ResetReachable; virtual;\n    function RemoveInjected(aCanRemove: Boolean): Boolean; virtual;\n    function GetEditType: TwbEditType; virtual;\n    function GetEditInfo: string; virtual;\n    function GetDontShow: Boolean; virtual;\n    procedure SetToDefault;\n    procedure SetToDefaultInternal; virtual;\n\n    function CanAssign(aIndex: Integer; const aElement: IwbElement; aCheckDontShow: Boolean): Boolean;\n    function CanAssignInternal(aIndex: Integer; const aElement: IwbElement; aCheckDontShow: Boolean): Boolean; virtual;\n    function Assign(aIndex: Integer; const aElement: IwbElement; aOnlySK: Boolean): IwbElement;\n    function AssignInternal(aIndex: Integer; const aElement: IwbElement; aOnlySK: Boolean): IwbElement; virtual;\n\n    procedure WriteToStream(aStream: TStream; aResetModified: Boolean);\n    procedure WriteToStreamInternal(aStream: TStream; aResetModified: Boolean); virtual;\n    function GetLinksTo: IwbElement; virtual;\n    function GetNoReach: Boolean;\n\n    procedure SetContainer(const aContainer: IwbContainer); virtual;\n    procedure SetSortOrder(aIndex: Integer);\n\n    procedure DoAfterSet(const aOldValue, aNewValue: Variant); virtual;\n\n    procedure MoveUp;\n    procedure MoveDown;\n    function CanMoveUp: Boolean;\n    function CanMoveDown: Boolean;\n\n    procedure NextMember;\n    procedure PreviousMember;\n    function CanChangeMember: Boolean;\n\n    procedure Tag;\n    procedure ResetTags; virtual;\n    function IsTagged: Boolean;\n\n    function CopyInto(const aFile: IwbFile; aAsNew, aDeepCopy: Boolean; const aPrefixRemove, aPrefix, aSuffix: string): IwbElement;\n\n    function BeginUpdate: Integer;\n    function EndUpdate: Integer;\n    procedure UpdatedEnded; virtual;\n\n    constructor Create(const aContainer: IwbContainer);\n    procedure BeforeDestruction; override;\n    procedure AfterConstruction; override;\n    class function NewInstance: TObject; override;\n    procedure FreeInstance; override;\n\n    function GetTreeHead: Boolean;              // Is the element expected to be a \"header record\" in the tree navigator\n    function GetTreeBranch: Boolean;            // Is the element expected to show in the tree navigator\n  end;\n\n  TDynElementInternals = array of IwbElementInternal;\n\n  IwbContainerInternal = interface(IwbContainer)\n    ['{8D9AC0D3-3961-4320-A036-EB4771B081CD}']\n\n    function ReleaseElements: TDynElementInternals;\n    procedure ElementChanged(const aElement: IwbElement; aContainer: Pointer);\n    procedure SortBySortOrder;\n    procedure CreatedEmpty;\n\n    procedure MoveElementUp(const aElement: IwbElement);\n    procedure MoveElementDown(const aElement: IwbElement);\n    function CanMoveElementUp(const aElement: IwbElement): Boolean;\n    function CanMoveElementDown(const aElement: IwbElement): Boolean;\n\n    procedure NextElementMember(const aElement: IwbElement);\n    procedure PreviousElementMember(const aElement: IwbElement);\n    function CanChangeElementMember(const aElement: IwbElement): Boolean;\n  end;\n\n  TwbContainer = class(TwbElement, IwbContainerElementRef, IwbContainer, IwbContainerInternal)\n  protected\n    cntElements      : TDynElementInternals;\n    cntElementsMap   : TDynCardinalArray;\n    cntElementRefs   : Integer;\n    cntStates        : TwbContainerStates;\n    cntKeepAliveNext : IwbContainerElementRef;\n\n    function _AddRef: Integer; override; stdcall;\n    function _Release: Integer; override; stdcall;\n\n    {---IwbContainerElementRef---}\n    function ElementAddRef: Integer; stdcall;\n    function ElementRelease: Integer; stdcall;\n    function IwbContainerElementRef._AddRef = ElementAddRef;\n    function IwbContainerElementRef._Release = ElementRelease;\n    function GetCountedRecordCount: Cardinal; override;\n    procedure PrepareSave; override;\n    procedure MasterCountUpdated(aOld, aNew: Byte); override;\n    procedure MasterIndicesUpdated(const aOld, aNew: TBytes); override;\n    procedure FindUsedMasters(aMasters: PwbUsedMasters); override;\n\n    procedure SortBySortOrder; virtual;\n    procedure CreatedEmpty;\n\n    function Reached: Boolean; override;\n    function RemoveInjected(aCanRemove: Boolean): Boolean; override;\n\n    procedure ReportRequiredMasters(aStrings: TStrings; aAsNew: Boolean; Recursive: Boolean = True; Initial: Boolean = false); override;\n    procedure ResetConflict; override;\n    procedure ResetReachable; override;\n\n    procedure DoReset(aForce: Boolean); override;\n    procedure DoInit; virtual;\n\n    function HasErrors: Boolean; override;\n\n    function GetSortKeyInternal(aExtended: Boolean): string; override;\n    function GetDataSize: Integer; override;\n    procedure MergeStorageInternal(var aBasePtr: Pointer; aEndPtr: Pointer); override;\n    procedure InformStorage(var aBasePtr: Pointer; aEndPtr: Pointer); override;\n    procedure BuildRef; override;\n    procedure MarkModifiedRecursive; override;\n\n    function CanAssignInternal(aIndex: Integer; const aElement: IwbElement; aCheckDontShow: Boolean): Boolean; override;\n    function AssignInternal(aIndex: Integer; const aElement: IwbElement; aOnlySK: Boolean): IwbElement; override;\n    function GetIsInSK(aIndex: Integer): Boolean; virtual;\n\n    procedure SetToDefaultInternal; override;\n\n    procedure WriteToStreamInternal(aStream: TStream; aResetModified: Boolean); override;\n\n    function GetElement(aIndex: Integer): IwbElement;\n    function GetElementCount: Integer;\n    function GetElementByName(const aName: string): IwbElement;\n    function GetRecordBySignature(const aSignature: TwbSignature): IwbRecord;\n    function GetElementByMemoryOrder(aSortOrder: Integer): IwbElement;\n    function GetElementBySignature(const aSignature: TwbSignature): IwbElement;\n    function GetElementBySortOrder(aSortOrder: Integer): IwbElement;\n    function GetAdditionalElementCount: Integer; virtual;\n    procedure ReverseElements;\n    function GetContainerStates: TwbContainerStates;\n    function GetElementByPath(const aPath: string): IwbElement;\n    function GetElementValue(const aName: string): string;\n    function GetElementExists(const aName: string): Boolean;\n    function GetElementEditValue(const aName: string): string;\n    procedure SetElementEditValue(const aName, aValue: string);\n    function GetElementNativeValue(const aName: string): Variant;\n    procedure SetElementNativeValue(const aName: string; const aValue: Variant);\n    function GetElementLinksTo(const aName: string): IwbElement;\n    function GetElementSortKey(const aName: string; aExtended: Boolean): string;\n\n    function ResolveElementName(aName: string; out aRemainingName: string; aCanCreate: Boolean = False): IwbElement; virtual;\n\n    procedure AddElement(const aElement: IwbElement); virtual;\n    procedure InsertElement(aPosition: Integer; const aElement: IwbElement);\n    function RemoveElement(aPos: Integer; aMarkModified: Boolean = False): IwbElement; overload; virtual;\n    function RemoveElement(const aElement: IwbElement; aMarkModified: Boolean = False): IwbElement; overload; virtual;\n    function RemoveElement(const aName: string): IwbElement; overload;\n    function LastElement: IwbElement;\n\n    function CanElementReset: Boolean; virtual;\n\n    function GetAddList: TDynStrings; virtual;\n    function Add(const aName: string; aSilent: Boolean): IwbElement; virtual;\n\n    function IsElementRemoveable(const aElement: IwbElement): Boolean; virtual;\n    function IsElementEditable(const aElement: IwbElement): Boolean; virtual;\n\n    function IndexOf(const aElement: IwbElement): Integer; virtual;\n\n    function ReleaseElements: TDynElementInternals;\n    procedure ElementChanged(const aElement: IwbElement; aContainer: Pointer); virtual;\n    procedure NotifyChangedInternal(aContainer: Pointer); override;\n\n    function CompareExchangeFormID(aOldFormID: Cardinal; aNewFormID: Cardinal): Boolean; override;\n\n    procedure Init; virtual;\n    procedure Reset; virtual;\n    procedure Bar;\n    function ReleaseKeepAlive: IwbContainerElementRef;\n\n    procedure MoveElementUp(const aElement: IwbElement);\n    procedure MoveElementDown(const aElement: IwbElement);\n    function CanMoveElementUp(const aElement: IwbElement): Boolean;\n    function CanMoveElementDown(const aElement: IwbElement): Boolean;\n    function CanMoveElement: Boolean; virtual;\n\n    procedure NextElementMember(const aElement: IwbElement);\n    procedure PreviousElementMember(const aElement: IwbElement);\n    function CanChangeElementMember(const aElement: IwbElement): Boolean;\n\n    function FindBySortKey(const aSortKey: string; aExtended: Boolean; out aIndex: Integer): Boolean;\n\n    procedure AfterConstruction; override;\n    procedure BeforeDestruction; override;\n    class function NewInstance: TObject; override;\n    destructor Destroy; override;\n    procedure FreeInstance; override;\n\n    procedure ResetTags; override;\n  end;\n\n  IwbFileInternal = interface(IwbFile)\n    ['{E1334034-06D0-4299-BFE0-E0DE97C128E2}']\n    procedure AddMainRecord(const aRecord: IwbMainRecord);\n    procedure RemoveMainRecord(const aRecord: IwbMainRecord);\n    procedure InjectMainRecord(const aRecord: IwbMainRecord);\n    procedure RemoveInjectedMainRecord(const aRecord: IwbMainRecord);\n    procedure ForceClosed;\n    procedure GetMasters(aMasters: TStrings);\n  end;\n\n  TwbFile = class(TwbContainer, IwbFile, IwbFileInternal)\n  protected\n    flFileName               : string;\n    flLoadOrder              : Integer;\n    flCompareTo              : string;\n    flStates                 : TwbFileStates;\n    flUnsavedSince           : TDateTime;\n\n    flFileHandle             : THandle;\n    flMapHandle              : THandle;\n\n    flView                   : Pointer;\n    flEndPtr                 : Pointer;\n\n    flMasters                : array of IwbFile;\n\n    flRecords                : array of IwbMainRecord;\n    flRecordsCount           : Integer; {only used during loading}\n\n    flRecordsByEditorID      : array of IwbMainRecord;\n    flRecordsByEditorIDCount : Integer; {only used during loading}\n\n    flLoadFinished           : Boolean;\n    flFormIDsSorted          : Boolean;\n\n    flInjectedRecords        : array of IwbMainRecord;\n\n    procedure flOpenFile; virtual;\n    procedure flCloseFile; virtual;\n    procedure flProgress(const aStatus: string);\n\n    function Reached: Boolean; override;\n\n    function GetElementType: TwbElementType; override;\n    function GetFile: IwbFile; override;\n    function GetReferenceFile: IwbFile; override;\n    function GetName: string; override;\n    function GetBaseName: string; override;\n    procedure PrepareSave; override;\n    procedure SetModified(aValue: Boolean); override;\n\n    procedure BuildRef; override;\n\n    function FindFormID(aFormID: Cardinal; var Index: Integer): Boolean;\n    function FindInjectedID(aFormID: Cardinal; var Index: Integer): Boolean;\n    function FindEditorID(const aEditorID: string; var Index: Integer): Boolean;\n    function GetMasterRecordByFormID(aFormID: Cardinal; aAllowInjected: Boolean): IwbMainRecord;\n\n    function GetAddList: TDynStrings; override;\n    function Add(const aName: string; aSilent: Boolean): IwbElement; override;\n\n    function IsElementRemoveable(const aElement: IwbElement): Boolean; override;\n    function IsElementEditable(const aElement: IwbElement): Boolean; override;\n    function GetIsEditable: Boolean; override;\n    function GetIsRemoveable: Boolean; override;\n\n    procedure WriteToStreamInternal(aStream: TStream; aResetModified: Boolean); override;\n\n    function AddIfMissingInternal(const aElement: IwbElement; aAsNew, aDeepCopy : Boolean; const aPrefixRemove, aPrefix, aSuffix: string): IwbElement; override;\n\n    function NewFormID: Cardinal;\n\n    {---IwbFile---}\n    function GetFileName: string;\n    function GetUnsavedSince: TDateTime;\n    function HasMaster(const aFileName: string): Boolean;\n    function GetMaster(aIndex: Integer): IwbFile;\n    function GetMasterCount: Integer;\n    function GetRecordByFormID(aFormID: Cardinal; aAllowInjected: Boolean): IwbMainRecord;\n    function GetRecordByEditorID(const aEditorID: string): IwbMainRecord;\n    function GetGroupBySignature(const aSignature: TwbSignature): IwbGroupRecord;\n    function HasGroup(const aSignature: TwbSignature): Boolean;\n    function GetFileStates: TwbFileStates;\n    function GetRecord(aIndex: Integer): IwbMainRecord;\n    function GetRecordCount: Integer;\n    function GetHeader: IwbMainRecord;\n\n    function GetLoadOrder: Integer;\n    procedure ForceLoadOrder(aValue: Integer);\n    procedure SetLoadOrder(aValue: Integer);\n\n    function LoadOrderFormIDtoFileFormID(aFormID: Cardinal): Cardinal;\n    function FileFormIDtoLoadOrderFormID(aFormID: Cardinal): Cardinal;\n\n    function LoadOrderFileIDtoFileFileID(aFileID: Byte): Byte;\n    function FileFileIDtoLoadOrderFileID(aFileID: Byte): Byte;\n\n    procedure AddMasters(aMasters: TStrings);\n    procedure AddMasterIfMissing(const aMaster: string);\n    procedure SortMasters;\n    procedure CleanMasters;\n\n    procedure BuildReachable;\n\n    function GetIsESM: Boolean;\n    procedure SetIsESM(Value: Boolean);\n\n    function GetIsLocalized: Boolean;\n    procedure SetIsLocalized(Value: Boolean);\n\n    function GetNextObjectID: Cardinal;\n    procedure SetNextObjectID(aObjectID: Cardinal);\n\n    function GetIsNotPlugin: Boolean;\n    function GetHasNoFormID: Boolean;\n    procedure SetHasNoFormID(Value: Boolean);\n\n    {---IwbFileInternal---}\n    procedure AddMainRecord(const aRecord: IwbMainRecord);\n    procedure RemoveMainRecord(const aRecord: IwbMainRecord);\n    procedure InjectMainRecord(const aRecord: IwbMainRecord);\n    procedure RemoveInjectedMainRecord(const aRecord: IwbMainRecord);\n    procedure ForceClosed;\n    procedure GetMasters(aMasters: TStrings); virtual;\n\n    procedure Scan; virtual;\n    procedure SortRecords;\n    procedure SortRecordsByEditorID;\n\n    procedure AddMaster(const aFileName: string; isTemporary: Boolean = False); overload;\n    procedure AddMaster(const aFile: IwbFile); overload;\n\n    constructor Create(const aFileName: string; aLoadOrder: Integer; aCompareTo: string; aOnlyHeader: Boolean; IsTemporary: Boolean = False);\n    constructor CreateNew(const aFileName: string; aLoadOrder: Integer);\n  public\n    destructor Destroy; override;\n  end;\n\n  TwbFileSource = class(TwbFile)\n  protected\n    procedure Scan; override;\n    constructor CreateNew(const aFileName: string; aLoadOrder: Integer);\n    procedure GetMasters(aMasters: TStrings); override;\n  end;\n\n  TwbDataContainerFlag = (\n    dcfDontCompare,\n    dcfDontMerge,\n    dcfDontSave,\n    dcfStorageInvalid\n  );\n\n  TwbDataContainerFlags = set of TwbDataContainerFlag;\n\n  IwbDataContainerInternal = interface(IwbDataContainer)\n    ['{E13AE2AD-20CB-4429-86C2-0DEC3ECEE38B}']\n    procedure UpdateStorageFromElements;\n  end;\n\n  TwbDataContainer = class(TwbContainer, IwbDataContainer, IwbDataContainerInternal)\n  protected\n    dcBasePtr       : Pointer;\n    dcEndPtr        : Pointer;\n    dcDataBasePtr   : Pointer;\n    dcDataEndPtr    : Pointer;\n    dcDataStorage   : TBytes;\n    dcFlags         : TwbDataContainerFlags;\n\n    constructor Create(const aContainer      : IwbContainer;\n                         var aBasePtr        : Pointer;\n                             aEndPtr         : Pointer;\n                       const aPrevMainRecord : IwbMainRecord); virtual;\n    procedure InitDataPtr; virtual; abstract;\n    function GetDataPrefixSize: Integer; virtual;\n\n    function GetResolvedValueDef: IwbValueDef; override;\n\n    procedure InvalidateStorage; override;\n    procedure SetContainer(const aContainer: IwbContainer); override;\n\n    procedure SetModified(aValue: Boolean); override;\n    procedure RequestStorageChange(var aBasePtr, aEndPtr: Pointer; aNewSize: Cardinal); override;\n\n    procedure WriteToStreamInternal(aStream: TStream; aResetModified: Boolean); override;\n    procedure MergeStorageInternal(var aBasePtr: Pointer; aEndPtr: Pointer); override;\n    procedure InformStorage(var aBasePtr: Pointer; aEndPtr: Pointer); override;\n    function DoCheckSizeAfterWrite: Boolean; virtual;\n    procedure SetToDefaultInternal; override;\n    function IsFlags: Boolean; virtual;\n\n    function GetEditType: TwbEditType; override;\n    function GetEditInfo: string; override;\n\n    function GetConflictPriority: TwbConflictPriority; override;\n\n    {---IwbDataContainer---}\n    function GetDataBasePtr: Pointer;\n    function GetDataEndPtr: Pointer;\n    function GetDataSize: Integer; override;\n    procedure SetDataSize(aSize: Integer); override;\n    function GetDontCompare: Boolean;\n    function GetDontSave: Boolean;\n    function IsValidOffset(aBasePtr, aEndPtr: Pointer; anOffset: Integer): Boolean;\n    function IsLocalOffset(anOffset: Integer): Boolean;\n\n    {--- IwbDataContainerInternal ---}\n    procedure UpdateStorageFromElements; virtual;\n  end;\n\n  TwbRecordClass = class of TwbRecord;\n  TwbRecord = class(TwbDataContainer, IwbRecord, IwbHasSignature)\n  protected\n    recSkipped          : Boolean;\n  protected\n    constructor Create(const aContainer      : IwbContainer;\n                         var aBasePtr        : Pointer;\n                             aEndPtr         : Pointer;\n                       const aPrevMainRecord : IwbMainRecord); overload; override;\n\n    function GetSignature: TwbSignature;\n    procedure ScanData; virtual; abstract;\n    procedure InformPrevMainRecord(const aPrevMainRecord : IwbMainRecord); virtual;\n    procedure SortBySortOrder; override;\n  public\n    class function CreateForPtr(var aPtr            : Pointer;\n                                    aEndPtr         : Pointer;\n                              const aContainer      : IwbContainer;\n                              const aPrevMainRecord : IwbMainRecord)\n                                                    : IwbRecord;\n\n    function GetName: string; override;\n    function GetSkipped: Boolean; override;\n  end;\n\n  PwbMainRecordStruct = ^TwbMainRecordStruct;\n  TwbMainRecordStruct = packed record\n    mrsSignature : TwbSignature;\n    mrsDataSize  : Cardinal;\n    mrsFlags     : TwbMainRecordStructFlags;\n    mrsFormID    : Cardinal;\n    mrsVCS1      : Cardinal;\n    mrsVersion   : Word;\n    mrsVCS2      : Word;\n  end;\n\n  IwbMainRecordInternal = interface(IwbMainRecord)\n    ['{405C85E0-2261-4078-B99C-199007D31544}']\n    procedure AddOverride(const aMainRecord: IwbMainRecord);\n    procedure RemoveOverride(const aMainRecord: IwbMainRecord);\n    procedure SetMaster(const aMaster: IwbMainRecord);\n    procedure YouAreTheMaster(const aOverrides, aReferencedBy: TDynMainRecords); overload;\n    procedure YouAreTheMaster(const aOldMaster: IwbMainRecord; const aOverrides, aReferencedBy: TDynMainRecords); overload;\n    procedure YouGotAMaster(const aMaster: IwbMainRecord);\n    procedure SetChildGroup(const aGroup: IwbGroupRecord);\n    procedure RemoveChildGroup(const aGroup: IwbGroupRecord);\n    procedure SetReferencesInjected(aValue: Boolean);\n    procedure ClearForRelease;\n\n    procedure MakeHeaderWriteable;\n    function mrStruct: PwbMainRecordStruct;\n  end;\n\n  IwbMainRecordEntry = interface(IwbMainRecordInternal)\n    ['{0C89F580-C95A-4A6C-85EA-BD5E411788A4}']\n    procedure RemoveEntry;\n    procedure RemoveEntryInternal;\n\n    procedure InsertEntryAfter(const aEntry: IwbMainRecordEntry);\n    procedure InsertEntryHead;\n    procedure InsertEntryTail;\n\n    function GetPrevEntry: IwbMainRecordEntry;\n    procedure SetPrevEntry(const aEntry: IwbMainRecordEntry);\n\n    function GetNextEntry: IwbMainRecordEntry;\n    procedure SetNextEntry(const aEntry: IwbMainRecordEntry);\n\n    function GetIsInList: Boolean;\n\n    property PrevEntry: IwbMainRecordEntry\n      read GetPrevEntry\n      write SetPrevEntry;\n\n    property NextEntry: IwbMainRecordEntry\n      read GetNextEntry\n      write SetNextEntry;\n\n    property IsInList: Boolean\n      read GetIsInList;\n  end;\n\n  TwbMainRecordState = (\n    mrsBuildingRef,\n    mrsReferencedByUnsorted,\n    mrsIsInjected,\n    mrsIsInjectedChecked,\n    mrsReferencesInjected,\n    mrsReferencesInjectedChecked,\n    mrsSearchedChildGroup,\n    mrsHasVWDMeshChecked,\n    mrsHasVWDMesh,\n    mrsHasPrecombinedMeshChecked,\n    mrsHasPrecombinedMesh,\n    mrsBaseRecordChecked,\n    mrsQuickInit,\n    mrsQuickInitDone,\n    mrsHasMeshChecked,\n    mrsHasMesh,\n    mrsNoUpdateRefs,\n    mrBasePtrAllocated\n  );\n\n  TwbMainRecordStates = set of TwbMainRecordState;\n\n  IwbContainedIn = interface\n    ['{002F064A-81B8-40EB-AA09-E5F7AE061D9E}']\n    procedure ContainerChanged;\n  end;\n\n  TwbMainRecord = class(TwbRecord, IwbMainRecord, IwbMainRecordInternal, IwbMainRecordEntry, IwbContainedIn)\n  protected\n    mrDef              : IwbRecordDef;\n    mrLoadOrderFormID  : Cardinal;\n    mrFixedFormID      : Cardinal;\n    mrMaster           : Pointer{IwbMainRecord};\n    mrOverrides        : TDynMainRecords;\n    mrOverridesSorted  : Boolean;\n    mrEditorID         : string;\n    mrFullName         : string;\n    mrStates           : TwbMainRecordStates;\n    mrBaseRecordID     : Cardinal;\n    mrPrecombinedCellID: Cardinal;\n    mrPrecombinedID    : Cardinal;\n    mrConflictAll      : TConflictAll;\n    mrConflictThis     : TConflictThis;\n    mrDataStorage      : TBytes;\n    mrGroup            : IwbGroupRecord;\n\n    mrReferencedBy     : TDynMainRecords;\n    mrReferences       : TDynCardinalArray;\n    mrTmpRefFormIDs    : TDynCardinalArray;\n    mrTmpRefFormIDHigh : Integer;\n\n    mreGeneration      : Integer;\n    mrePrev            : Pointer;\n    mreNext            : Pointer;\n\n    function mrStruct: PwbMainRecordStruct; inline;\n\n    procedure ElementChanged(const aElement: IwbElement; aContainer: Pointer); override;\n    function RemoveElement(aPos: Integer; aMarkModified: Boolean = False): IwbElement; overload; override;\n    function ResolveElementName(aName: string; out aRemainingName: string; aCanCreate: Boolean = False): IwbElement; override;\n\n    function GetIsInjected: Boolean; override;\n    function GetReferencesInjected: Boolean; override;\n    function GetInjectionSourceFiles: TDynFiles; override;\n    function RemoveInjected(aCanRemove: Boolean): Boolean; override;\n    function GetIsNotReachable: Boolean; override;\n    function GetCountedRecordCount: Cardinal; override;\n    procedure InitDataPtr; override;\n    procedure DecompressIfNeeded;\n    procedure ScanData; override;\n    procedure WriteToStreamInternal(aStream: TStream; aResetModified: Boolean); override;\n    procedure MergeStorageInternal(var aBasePtr: Pointer; aEndPtr: Pointer); override;\n    procedure InformStorage(var aBasePtr: Pointer; aEndPtr: Pointer); override;\n    function CanContainFormIDs: Boolean; override;\n    function CompareExchangeFormID(aOldFormID: Cardinal; aNewFormID: Cardinal): Boolean; override;\n    function CanElementReset: Boolean; override;\n    procedure Remove; override;\n    procedure PrepareSave; override;\n    procedure MasterCountUpdated(aOld, aNew: Byte); override;\n    procedure MasterIndicesUpdated(const aOld, aNew: TBytes); override;\n    procedure FindUsedMasters(aMasters: PwbUsedMasters); override;\n    function GetReferenceFile: IwbFile; override;\n    procedure ReportRequiredMasters(aStrings: TStrings; aAsNew: Boolean; Recursive: Boolean = True; Initial: Boolean = false); override;\n    function LinksToParent: Boolean; override;\n    function Reached: Boolean; override;\n    function GetContainingMainRecord: IwbMainRecord; override;\n\n    procedure DoBuildRef(aRemove: Boolean);\n    procedure BuildRef; override;\n    procedure AddReferencedFromID(aFormID: Cardinal); override;\n    procedure ResetConflict; override;\n    procedure ResetReachable; override;\n\n    procedure Init; override;\n    procedure Reset; override;\n\n    function GetPath: string; override;\n    function GetValue: string; override;\n    function GetSortKeyInternal(aExtended: Boolean): string; override;\n    function GetSortPriority: Integer; override;\n    function GetAdditionalElementCount: Integer; override;\n    function GetIsEditable: Boolean; override;\n    function GetEditValue: string; override;\n    procedure SetEditValue(const aValue: string); override;\n    function GetNativeValue: Variant; override;\n    procedure SetNativeValue(const aValue: Variant); override;\n    function IsElementRemoveable(const aElement: IwbElement): Boolean; override;\n    procedure SetContainer(const aContainer: IwbContainer); override;\n\n    function FindReferencedBy(const aMainRecord: IwbMainRecord; var Index: Integer): Boolean;\n\n    function CanAssignInternal(aIndex: Integer; const aElement: IwbElement; aCheckDontShow: Boolean): Boolean; override;\n    function AssignInternal(aIndex: Integer; const aElement: IwbElement; aOnlySK: Boolean): IwbElement; override;\n    function AddIfMissingInternal(const aElement: IwbElement; aAsNew, aDeepCopy : Boolean; const aPrefixRemove, aPrefix, aSuffix: string): IwbElement; override;\n\n    procedure CollapseStorage;\n\n    function GetAddList: TDynStrings; override;\n    function Add(const aName: string; aSilent: Boolean): IwbElement; override;\n\n    function CheckChildOfCell: Boolean;\n    procedure UpdateCellChildGroup;\n    procedure UpdateInteriorCellGroup;\n\n    procedure MarkModifiedRecursive; override;\n\n    {---IwbMainRecord---}\n    function GetDef: IwbNamedDef; override;\n    function GetElementType: TwbElementType; override;\n    function GetFormID: Cardinal;\n    function GetFixedFormID: Cardinal;\n    function GetLoadOrderFormID: Cardinal;\n    procedure SetLoadOrderFormID(aFormID: Cardinal);\n    function GetEditorID: string;\n    function GetCanHaveEditorID: Boolean;\n    procedure SetEditorID(const aValue: string);\n    function GetFullName: string;\n    function GetDisplayNameKey: string;\n    function GetMaster: IwbMainRecord;\n    function GetIsMaster: Boolean;\n    function GetMasterOrSelf: IwbMainRecord;\n    function GetOverride(aIndex: Integer): IwbMainRecord;\n    function GetOverrideCount: Integer;\n    procedure AddReferencedBy(aMainRecord: IwbMainRecord);\n    procedure RemoveReferencedBy(aMainRecord: IwbMainRecord);\n    procedure SortReferencedBy;\n    function GetReferencedBy(aIndex: Integer): IwbMainRecord;\n    function GetReferencedByCount: Integer;\n    function GetCheck: string; override;\n    function GetIsWinningOverride: Boolean;\n    function GetWinningOverride: IwbMainRecord;\n    function GetHighestOverrideOrSelf(aMaxLoadOrder: Integer): IwbMainRecord;\n    function GetFlags: TwbMainRecordStructFlags;\n    function GetFlagsPtr: PwbMainRecordStructFlags;\n    function GetChildGroup: IwbGroupRecord;\n    function EnsureChildGroup: IwbGroupRecord;\n    function GetBaseRecord: IwbMainRecord;\n    function GetBaseRecordID: Cardinal;\n\n    procedure MakeHeaderWriteable;\n\n    function GetConflictAll: TConflictAll;\n    procedure SetConflictAll(aValue: TConflictAll);\n    function GetConflictThis: TConflictThis;\n    procedure SetConflictThis(aValue: TConflictThis);\n\n    function GetIsESM: Boolean;\n    procedure SetIsESM(aValue: Boolean);\n    function GetIsLocalized: Boolean;\n    procedure SetIsLocalized(aValue: Boolean);\n    function GetIsPersistent: Boolean;\n    procedure SetIsPersistent(aValue: Boolean);\n    function GetIsDeleted: Boolean;\n    procedure SetIsDeleted(aValue: Boolean);\n    function GetIsCompressed: Boolean;\n    procedure SetIsCompressed(aValue: Boolean);\n    function GetIsVisibleWhenDistant: Boolean;\n    procedure SetIsVisibleWhenDistant(aValue: Boolean);\n    function GetHasVisibleWhenDistantMesh: Boolean;\n    function GetHasMesh: Boolean;\n    function GetHasPrecombinedMesh: Boolean;\n    function GetPrecombinedMesh: string;\n    function GetIsInitiallyDisabled: Boolean;\n    procedure SetIsInitiallyDisabled(aValue: Boolean);\n\n    procedure UpdateRefs;\n\n    function GetPosition(out aPosition: TwbVector): Boolean;\n    function SetPosition(const aPosition: TwbVector): Boolean;\n    function GetRotation(out aRotation: TwbVector): Boolean;\n    function GetScale(out aScale: Single): Boolean;\n    function GetGridCell(out aGridCell: TwbGridCell): Boolean;\n    function GetFormVersion: Cardinal; {>>> Form Version access <<<}\n    procedure SetFormVersion(aFormVersion: Cardinal); {>>> Form Version access <<<}\n    procedure ChangeFormSignature(aSignature: TwbSignature);\n    procedure ClampFormID(aIndex: Cardinal);\n\n    procedure Delete;\n    procedure DeleteInto(const aFile: IwbFile);\n\n    function MasterRecordsFromMasterFilesAndSelf: TDynMainRecords;\n\n    {---IwbMainRecordInternal---}\n    procedure AddOverride(const aMainRecord: IwbMainRecord);\n    procedure RemoveOverride(const aMainRecord: IwbMainRecord);\n    procedure SetMaster(const aMaster: IwbMainRecord);\n    procedure YouAreTheMaster(const aOverrides, aReferencedBy: TDynMainRecords); overload;\n    procedure YouAreTheMaster(const aOldMaster: IwbMainRecord; const aOverrides, aReferencedBy: TDynMainRecords); overload;\n    procedure YouGotAMaster(const aMaster: IwbMainRecord);\n    procedure SetChildGroup(const aGroup: IwbGroupRecord);\n    procedure RemoveChildGroup(const aGroup: IwbGroupRecord);\n    procedure SetReferencesInjected(aValue: Boolean);\n    procedure ClearForRelease;\n\n    {---IwbMainRecordEntry---}\n    procedure RemoveEntry;\n    procedure RemoveEntryInternal;\n\n    procedure InsertEntryAfter(const aEntry: IwbMainRecordEntry);\n    procedure InsertEntryHead;\n    procedure InsertEntryTail;\n\n    function GetPrevEntry: IwbMainRecordEntry;\n    procedure SetPrevEntry(const aEntry: IwbMainRecordEntry);\n\n    function GetNextEntry: IwbMainRecordEntry;\n    procedure SetNextEntry(const aEntry: IwbMainRecordEntry);\n\n    function GetIsInList: Boolean;\n\n    {--- IwbContainedIn ---}\n    procedure ContainerChanged;\n  public\n    constructor Create(const aContainer      : IwbContainer;\n                         var aBasePtr        : Pointer;\n                             aEndPtr         : Pointer;\n                       const aPrevMainRecord : IwbMainRecord); override;\n    constructor Create(const aContainer : IwbContainer;\n                       const aSignature : TwbSignature;\n                             aFormID    : Cardinal); overload;\n    destructor Destroy; override;\n\n    function GetName: string; override;\n    function GetShortName: string; override;\n    function GetDisplayName: string; override;\n  end;\n\n  PwbSubRecordHeaderStruct = ^TwbSubRecordHeaderStruct;\n  TwbSubRecordHeaderStruct = packed record\n    srsSignature : TwbSignature;\n    srsDataSize  : Word;\n  end;\n\n  IwbSubRecordInternal = interface(IwbSubRecord)\n    ['{AB66BAE8-2618-4B85-80CE-A108C3B80808}']\n    procedure SetDef(const aDef: IwbSubRecordDef);\n  end;\n\n  TwbSubRecordState = (\n    srsIsArray,\n    srsIsFlags,\n    srsIsUnion,\n    srsSorted,\n    srsSortInvalid\n  );\n\n  TwbSubRecordStates = set of TwbSubRecordState;\n\n  TwbSubRecord = class(TwbRecord, IwbSubRecord, IwbSubRecordInternal, IwbSortableContainer)\n  protected {private}\n    srDef                : IwbSubRecordDef;\n    srValueDef           : IwbValueDef;\n    srStates             : TwbSubRecordStates;\n    srArraySizePrefix    : Integer;\n  protected\n    constructor Create(const aContainer : IwbContainer;\n                       const aSubRecordDef: IwbSubRecordDef); overload;\n    destructor Destroy; override;\n\n    procedure SetDef(const aDef: IwbSubRecordDef);\n    function srStruct: PwbSubRecordHeaderStruct; inline;\n\n    procedure InitDataPtr; override;\n    procedure ScanData; override;\n\n    procedure DoInit; override;\n    procedure Init; override;\n    procedure Reset; override;\n\n    function GetDataPrefixSize: Integer; override;\n    procedure CheckCount;\n\n    function GetName: string; override;\n    function GetDisplayName: string; override;\n\n    function IsFlags: Boolean; override;\n\n    function GetValue: string; override;\n    function GetCheck: string; override;\n    function GetSortKeyInternal(aExtended: Boolean): string; override;\n    function GetIsEditable: Boolean; override;\n    function GetValueDef: IwbValueDef; override;\n    function GetEditValue: string; override;\n    procedure SetEditValue(const aValue: string); override;\n    function GetNativeValue: Variant; override;\n    procedure SetNativeValue(const aValue: Variant); override;\n    procedure BuildRef; override;\n    function CompareExchangeFormID(aOldFormID: Cardinal; aNewFormID: Cardinal): Boolean; override;\n    procedure MasterCountUpdated(aOld, aNew: Byte); override;\n    procedure MasterIndicesUpdated(const aOld, aNew: TBytes); override;\n    procedure FindUsedMasters(aMasters: PwbUsedMasters); override;\n    procedure MergeStorageInternal(var aBasePtr: Pointer; aEndPtr: Pointer); override;\n    procedure InformStorage(var aBasePtr: Pointer; aEndPtr: Pointer); override;\n    function IsElementRemoveable(const aElement: IwbElement): Boolean; override;\n    procedure SetModified(aValue: Boolean); override;\n    function CanContainFormIDs: Boolean; override;\n    function CanElementReset: Boolean; override;\n    function GetLinksTo: IwbElement; override;\n    procedure ElementChanged(const aElement: IwbElement; aContainer: Pointer); override;\n    procedure PrepareSave; override;\n    function RemoveInjected(aCanRemove: Boolean): Boolean; override;\n\n    procedure SetToDefaultInternal; override;\n\n    procedure WriteToStreamInternal(aStream: TStream; aResetModified: Boolean); override;\n\n    function CanAssignInternal(aIndex: Integer; const aElement: IwbElement; aCheckDontShow: Boolean): Boolean; override;\n    function AssignInternal(aIndex: Integer; const aElement: IwbElement; aOnlySK: Boolean): IwbElement; override;\n    function AddIfMissingInternal(const aElement: IwbElement; aAsNew, aDeepCopy : Boolean; const aPrefixRemove, aPrefix, aSuffix: string): IwbElement; override;\n    function GetIsInSK(aIndex: Integer): Boolean; override;\n    function DoCheckSizeAfterWrite: Boolean; override;\n\n    function GetDef: IwbNamedDef; override;\n    function GetElementType: TwbElementType; override;\n\n    function GetDataSize: Integer; override;\n\n    function CanMoveElement: Boolean; override;\n\n    procedure CheckTerminator;\n\n    {--- IwbSubRecord ---}\n    function GetSubRecordHeaderSize: Integer;\n\n    {--- IwbSortableContainer ---}\n    function GetSorted: Boolean;\n  end;\n\n  TwbValueBase = class(TwbDataContainer)\n  protected\n    vbValueDef   : IwbValueDef;\n    vbNameSuffix : string;\n  protected\n    procedure InitDataPtr; override;\n\n    function GetDef: IwbNamedDef; override;\n    function GetValueDef: IwbValueDef; override;\n\n    function GetName: string; override;\n    function GetBaseName: string; override;\n    function GetDisplayName: string; override;\n\n    function GetCheck: string; override;\n    function GetValue: string; override;\n    function GetSortKeyInternal(aExtended: Boolean): string; override;\n\n    function GetIsEditable: Boolean; override;\n    function CanElementReset: Boolean; override;\n\n    function GetEditValue: string; override;\n    procedure SetEditValue(const aValue: string); override;\n\n    function GetNativeValue: Variant; override;\n    procedure SetNativeValue(const aValue: Variant); override;\n\n    procedure BuildRef; override;\n    function CanContainFormIDs: Boolean; override;\n    function GetLinksTo: IwbElement; override;\n    function GetDataSize: Integer; override;\n    function DoCheckSizeAfterWrite: Boolean; override;\n\n    procedure SetToDefaultInternal; override;\n\n    function GetIsInSK(aIndex: Integer): Boolean; override;\n  public\n    constructor Create(const aContainer  : IwbContainer;\n                         var aBasePtr    : Pointer;\n                             aEndPtr     : Pointer;\n                       const aValueDef   : IwbValueDef;\n                       const aNameSuffix : string;\n                             aDontCompare: Boolean = False); reintroduce; overload;\n    constructor Create(const aContainer  : IwbContainer;\n                       const aValueDef   : IwbValueDef;\n                       const aSource     : IwbElement;\n                       const aOnlySK     : Boolean;\n                       const aNameSuffix : string); reintroduce; overload;\n  end;\n\n  TwbArray = class(TwbValueBase, IwbSortableContainer)\n  protected {private}\n    arrSorted        : Boolean;\n    arrSortInvalid   : Boolean;\n    arrSizePrefix    : Integer;\n  protected\n    procedure DoInit; override;\n    procedure Init; override;\n    procedure Reset; override;\n\n    function GetElementType: TwbElementType; override;\n    function IsElementRemoveable(const aElement: IwbElement): Boolean; override;\n    procedure SetModified(aValue: Boolean); override;\n    procedure ElementChanged(const aElement: IwbElement; aContainer: Pointer); override;\n\n    function CanAssignInternal(aIndex: Integer; const aElement: IwbElement; aCheckDontShow: Boolean): Boolean; override;\n    function AssignInternal(aIndex: Integer; const aElement: IwbElement; aOnlySK: Boolean): IwbElement; override;\n    function AddIfMissingInternal(const aElement: IwbElement; aAsNew, aDeepCopy : Boolean; const aPrefixRemove, aPrefix, aSuffix: string): IwbElement; override;\n\n    procedure PrepareSave; override;\n    procedure CheckTerminator;\n\n    function GetDataPrefixSize: Integer; override;\n    procedure CheckCount;\n\n    function CanMoveElement: Boolean; override;\n\n    {--- IwbSortableContainer ---}\n    function GetSorted: Boolean;\n  end;\n\n  TwbStruct = class(TwbValueBase)\n  protected\n    szCompressedSize   : Integer;\n    szUncompressedSize : Cardinal;\n    szCompressedType   : TwbStructCompression;\n    procedure Init; override;\n    procedure Reset; override;\n\n    function GetElementType: TwbElementType; override;\n    procedure DecompressIfNeeded;\n    function GetIsCompressed: TwbStructCompression;\n    property IsCompressed: TwbStructCompression read GetIsCompressed;\n  end;\n\n  TwbFileHeader = class(TwbStruct, IwbFileHeader)\n  protected\n    function GetFileMagic: TwbFileMagic;\n  end;\n\n  TwbChapter = class(TwbStruct, IwbChapter)\n  protected\n    cChapterSkipped : Boolean;\n  protected\n    function GetSkipped: Boolean; override;\n    function GetElementType: TwbElementType; override;\n    function GetChapterType: Integer;\n    function GetChapterTypeName: String;\n    function GetChapterName: String;\n  public\n    constructor Create(const aContainer  : IwbContainer;\n                       const aValueDef   : IwbValueDef;\n                       const aSource     : IwbElement;\n                       const aOnlySK     : Boolean;\n                       const aNameSuffix : string);  reintroduce; overload;\n  end;\n\n  TwbUnion = class(TwbValueBase)\n  protected\n    function CompareExchangeFormID(aOldFormID: Cardinal; aNewFormID: Cardinal): Boolean; override;\n    procedure Init; override;\n    procedure Reset; override;\n\n    function GetElementType: TwbElementType; override;\n    procedure MasterCountUpdated(aOld, aNew: Byte); override;\n    procedure MasterIndicesUpdated(const aOld, aNew: TBytes); override;\n    procedure FindUsedMasters(aMasters: PwbUsedMasters); override;\n  end;\n\n  TwbRecordHeaderStruct = class(TwbStruct)\n  protected\n    function CanContainFormIDs: Boolean; override;\n    procedure BuildRef; override;\n    function CompareExchangeFormID(aOldFormID: Cardinal; aNewFormID: Cardinal): Boolean; override;\n    function IsElementEditable(const aElement: IwbElement): Boolean; override;\n    function GetIsEditable: Boolean; override;\n    procedure ElementChanged(const aElement: IwbElement; aContainer: Pointer); override;\n    function AddIfMissingInternal(const aElement: IwbElement; aAsNew, aDeepCopy : Boolean; const aPrefixRemove, aPrefix, aSuffix: string): IwbElement; override;\n  end;\n\n  TwbValue = class(TwbValueBase, IwbSortableContainer)\n  protected {private}\n    vIsFlags    : Boolean;\n  protected\n    function GetValue: string; override;\n    function CompareExchangeFormID(aOldFormID: Cardinal; aNewFormID: Cardinal): Boolean; override;\n    procedure MasterCountUpdated(aOld, aNew: Byte); override;\n    procedure MasterIndicesUpdated(const aOld, aNew: TBytes); override;\n    procedure FindUsedMasters(aMasters: PwbUsedMasters); override;\n    function AddIfMissingInternal(const aElement: IwbElement; aAsNew, aDeepCopy : Boolean; const aPrefixRemove, aPrefix, aSuffix: string): IwbElement; override;\n\n    function IsFlags: Boolean; override;\n\n    procedure Init; override;\n    procedure Reset; override;\n\n    function GetElementType: TwbElementType; override;\n    procedure SetEditValue(const aValue: string); override;\n    procedure SetNativeValue(const aValue: Variant); override;\n\n    {--- IwbSortableContainer ---}\n    function GetSorted: Boolean;\n  end;\n\n  TwbContainedInElement = class(TwbValue, IwbContainedIn)\n  protected {private}\n    cieLockCount: Integer;\n  protected\n    procedure InvalidateParentStorage; override;\n    function CanContainFormIDs: Boolean; override;\n    procedure BuildRef; override;\n    function CompareExchangeFormID(aOldFormID: Cardinal; aNewFormID: Cardinal): Boolean; override;\n    function IsElementEditable(const aElement: IwbElement): Boolean; override;\n    procedure ElementChanged(const aElement: IwbElement; aContainer: Pointer); override;\n    procedure SetModified(aValue: Boolean); override;\n    procedure DoAfterSet(const aOldValue, aNewValue: Variant); override;\n\n    {--- IwbContainedIn ---}\n    procedure ContainerChanged;\n  public\n    constructor Create(const aMainRecord: IwbMainRecord);\n  end;\n\n  IwbStringListTerminator = interface\n    ['{0D8ED4AA-1AFE-4283-87D7-2B66C5496227}']\n  end;\n\n  TwbStringListTerminator = class(TwbElement, IwbStringListTerminator)\n    function GetName: string; override;\n    function GetElementType: TwbElementType; override;\n    function GetConflictPriority: TwbConflictPriority; override;\n    function GetSortKeyInternal(aExtended: Boolean): string; override;\n    procedure SetEditValue(const aValue: string); override;\n    procedure SetNativeValue(const aValue: Variant); override;\n    function GetDataSize: Integer; override;\n    procedure WriteToStreamInternal(aStream: TStream; aResetModified: Boolean); override;\n    procedure MergeStorageInternal(var aBasePtr: Pointer; aEndPtr: Pointer); override;\n    procedure InformStorage(var aBasePtr: Pointer; aEndPtr: Pointer); override;\n    function CanAssignInternal(aIndex: Integer; const aElement: IwbElement; aCheckDontShow: Boolean): Boolean; override;\n    function AssignInternal(aIndex: Integer; const aElement: IwbElement; aOnlySK: Boolean): IwbElement; override;\n  end;\n\n  IwbFlag = interface(IwbElement)\n  ['{EED55516-C6D5-4ADD-B147-36B115E7449D}']\n    function GetFlagsDef: IwbFlagsDef;\n    function GetFlagIndex: Integer;\n\n    property FlagsDef: IwbFlagsDef\n      read GetFlagsDef;\n    property FlagIndex: Integer\n      read GetFlagIndex;\n  end;\n\n  TwbFlag = class(TwbElement, IwbFlag)\n  protected {private}\n    fBasePtr    : Pointer;\n    fEndPtr     : Pointer;\n    fIntegerDef : IwbIntegerDef;\n    fFlagsDef   : IwbFlagsDef;\n    fLastDefID  : Cardinal;\n    fIndex      : Integer;\n  protected\n    constructor Create(const aContainer  : IwbContainer;\n                             aBasePtr    : Pointer;\n                             aEndPtr     : Pointer;\n                       const aIntegerDef : IwbIntegerDef;\n                       const aFlagsDef   : IwbFlagsDef;\n                             aIndex      : Integer);\n\n    function GetName: string; override;\n    function GetDef: IwbNamedDef; override;\n    function GetValueDef: IwbValueDef; override;\n\n    function GetValue: string; override;\n    function GetSortKey(aExtended: Boolean): string; override;\n    function GetSortKeyInternal(aExtended: Boolean): string; override;\n    function GetConflictPriority: TwbConflictPriority; override;\n    function GetDontShow: Boolean; override;\n    procedure InformStorage(var aBasePtr: Pointer; aEndPtr: Pointer); override;\n    function GetDataSize: Integer; override;\n    procedure InvalidateParentStorage; override;\n\n    function GetIsEditable: Boolean; override;\n    function GetIsRemoveable: Boolean; override;\n\n    procedure Remove; override;\n\n    function GetEditValue: string; override;\n    procedure SetEditValue(const aValue: string); override;\n\n    function GetNativeValue: Variant; override;\n    procedure SetNativeValue(const aValue: Variant); override;\n\n    function GetElementType: TwbElementType; override;\n\n    {--- IwbFlag ---}\n    function GetFlagsDef: IwbFlagsDef;\n    function GetFlagIndex: Integer;\n  end;\n\n  PwbGroupRecordStruct = ^TwbGroupRecordStruct;\n  TwbGroupRecordStruct = packed record\n    grsSignature : TwbSignature;\n    grsGroupSize : Cardinal;\n    grsLabel     : Cardinal;\n    grsGroupType : Integer;\n    grsStamp     : Cardinal;\n    grsUnknown   : Cardinal;\n  end;\n\n  IwbGroupRecordInternal = interface(IwbGroupRecord)\n    ['{0BDDCF46-DFF6-4771-8FBB-0BC78828999B}']\n    procedure Sort;\n    procedure SetModified(aValue: Boolean);\n  end;\n\n  TwbGroupState = (\n    gsSorted,\n    gsSorting,\n    gsSortPostponed\n  );\n\n  TwbGroupStates = set of TwbGroupState;\n\n  TwbGroupRecord = class(TwbRecord, IwbGroupRecord, IwbGroupRecordInternal)\n  protected {private}\n    grStates: TwbGroupStates;\n  protected\n    constructor Create(const aContainer  : IwbContainer;\n                       const aSignature  : TwbSignature); overload;\n    constructor Create(const aContainer  : IwbContainer;\n                             aType       : Integer;\n                       const aMainRecord : IwbMainRecord); overload;\n    constructor Create(const aContainer  : IwbContainer;\n                             aType       : Integer;\n                             aLabel      : Cardinal); overload;\n    destructor Destroy; override;\n\n    function grStruct: PwbGroupRecordStruct; inline;\n\n    function GetCountedRecordCount: Cardinal; override;\n    procedure InitDataPtr; override;\n    procedure ScanData; override;\n    procedure InformPrevMainRecord(const aPrevMainRecord : IwbMainRecord); override;\n\n    function GetName: string; override;\n    function GetShortName: string; override;\n    function GetElementType: TwbElementType; override;\n    function GetSortKeyInternal(aExtended: Boolean): string; override;\n    function IsElementRemoveable(const aElement: IwbElement): Boolean; override;\n    procedure Remove; override;\n    procedure NotifyChangedInternal(aContainer: Pointer); override;\n\n    function GetAddList: TDynStrings; override;\n    function Add(const aName: string; aSilent: Boolean): IwbElement; override;\n    procedure Sort;\n\n    procedure UpdatedEnded; override;\n\n    procedure SetModified(aValue: Boolean); override;\n\n    procedure PrepareSave; override;\n    procedure WriteToStreamInternal(aStream: TStream; aResetModified: Boolean); override;\n    procedure MasterCountUpdated(aOld, aNew: Byte); override;\n    procedure MasterIndicesUpdated(const aOld, aNew: TBytes); override;\n    procedure FindUsedMasters(aMasters: PwbUsedMasters); override;\n\n    function AddIfMissingInternal(const aElement: IwbElement; aAsNew, aDeepCopy : Boolean; const aPrefixRemove, aPrefix, aSuffix: string): IwbElement; override;\n\n    procedure MakeHeaderWriteable;\n\n    procedure BuildRef; override;\n    function LinksToParent: Boolean; override;\n    function Reached: Boolean; override;\n\n    function FindChildGroup(aType: Integer; aMainRecord: IwbMainRecord): IwbGroupRecord;\n\n    function GetMainRecordByEditorID(const aEditorID: string): IwbMainRecord;\n    function GetMainRecordByFormID(const aFormID: Cardinal): IwbMainRecord;\n\n    function GetGroupType: Integer;\n    function GetGroupLabel: Cardinal;\n    procedure SetGroupLabel(aLabel: Cardinal);\n    function GetChildrenOf: IwbMainRecord;\n\n    procedure AddElement(const aElement: IwbElement); override;\n  end;\n\n  IwbSubRecordArrayInternal = interface(IwbSubRecordArray)\n    ['{4400F93F-9D13-43CA-B43D-727725EC73C8}']\n\n    procedure DoProcess(const aContainer : IwbContainer;\n                              aPos       : Integer);\n  end;\n\n  TwbSubRecordArray = class(TwbContainer, IwbSubRecordArray, IwbSubRecordArrayInternal, IwbSortableContainer, IwbHasSignature)\n  protected {private}\n    arcDef         : IwbSubRecordArrayDef;\n    arcSorted      : Boolean;\n    arcSortInvalid : Boolean;\n  protected\n    constructor Create(const aOwner     : IwbContainer;\n                       const aContainer : IwbContainer;\n                             aPos       : Integer;\n                       const aDef       : IwbSubRecordArrayDef);\n\n    procedure DoProcess(const aContainer : IwbContainer;\n                              aPos       : Integer);\n\n    procedure DoInit; override;\n\n    function GetName: string; override;\n    function GetDef: IwbNamedDef; override;\n    function GetElementType: TwbElementType; override;\n    function IsElementRemoveable(const aElement: IwbElement): Boolean; override;\n    procedure SetModified(aValue: Boolean); override;\n    function CanContainFormIDs: Boolean; override;\n    function CanElementReset: Boolean; override;\n    procedure ElementChanged(const aElement: IwbElement; aContainer: Pointer); override;\n\n    function CanAssignInternal(aIndex: Integer; const aElement: IwbElement; aCheckDontShow: Boolean): Boolean; override;\n    function AssignInternal(aIndex: Integer; const aElement: IwbElement; aOnlySK: Boolean): IwbElement; override;\n    function AddIfMissingInternal(const aElement: IwbElement; aAsNew, aDeepCopy : Boolean; const aPrefixRemove, aPrefix, aSuffix: string): IwbElement; override;\n\n    function CanMoveElement: Boolean; override;\n\n    {---IwbSortableContainer---}\n    function GetSorted: Boolean;\n\n    {--- IwbHasSignature ---}\n    function GetSignature: TwbSignature;\n  end;\n\n  TwbSubRecordStruct = class(TwbContainer, IwbHasSignature)\n  protected {private}\n    srcDef: IwbRecordDef;\n  protected\n    constructor Create(const aOwner     : IwbContainer;\n                       const aContainer : IwbContainer;\n                             aPos       : Integer;\n                       const aDef       : IwbSubRecordStructDef);\n\n    procedure AddRequiredElements;\n    function Add(const aName: string; aSilent: Boolean): IwbElement; override;\n\n    function GetSortKeyInternal(aExtended: Boolean): string; override;\n    function GetName: string; override;\n    function GetDef: IwbNamedDef; override;\n    function GetElementType: TwbElementType; override;\n    function IsElementRemoveable(const aElement: IwbElement): Boolean; override;\n    function CanContainFormIDs: Boolean; override;\n    function CanElementReset: Boolean; override;\n    function RemoveInjected(aCanRemove: Boolean): Boolean; override;\n\n    function CanAssignInternal(aIndex: Integer; const aElement: IwbElement; aCheckDontShow: Boolean): Boolean; override;\n    function AssignInternal(aIndex: Integer; const aElement: IwbElement; aOnlySK: Boolean): IwbElement; override;\n    function AddIfMissingInternal(const aElement: IwbElement; aAsNew, aDeepCopy : Boolean; const aPrefixRemove, aPrefix, aSuffix: string): IwbElement; override;\n    function GetIsInSK(aIndex: Integer): Boolean; override;\n\n    {--- IwbHasSignature ---}\n    function GetSignature: TwbSignature;\n  end;\n\nconst\n  NONE : TwbSignature = #0#0#0#0;\n\nfunction CompareFormIDs(Item1, Item2: Pointer): Integer;\nasm\n{$IFDEF WIN32}\n  xor ecx, ecx\n  cmp eax, edx\n  ja @@GT\n  je @@EQ\n@@LT:\n  dec ecx\n  dec ecx\n@@GT:\n  inc ecx\n@@EQ:\n  mov eax, ecx\n{$ENDIF WIN32}\n{$IFDEF WIN64}\n  xor rax, rax\n  cmp rcx, rdx\n  ja @@GT\n  je @@EQ\n@@LT:\n  dec rax\n  dec rax\n@@GT:\n  inc rax\n@@EQ:\n{$ENDIF WIN64}\nend;\n\nfunction CompareSubRecords(Item1, Item2: Pointer): Integer;\nvar\n  SortOrder1: Integer;\n  SortOrder2: Integer;\nbegin\n  if Item1 = Item2 then begin\n    Result := 0;\n    Exit;\n  end;\n\n  SortOrder1 := IwbElement(Item1).SortOrder;\n  SortOrder2 := IwbElement(Item2).SortOrder;\n\n  Result := CmpI32(SortOrder1, SortOrder2);\n\n  if Result = 0 then begin\n    Result := CmpW32(Ord(IwbElement(Item1).ElementType), Ord(IwbElement(Item2).ElementType));\n    if Result = 0 then begin\n      if IwbElement(Item1).ElementType = etSubRecord then\n        Result := CmpW32(\n          Cardinal((IwbElement(Item1) as IwbSubRecord).DataBasePtr),\n          Cardinal((IwbElement(Item2) as IwbSubRecord).DataBasePtr)\n        );\n    end;\n  end;\nend;\n\nfunction CompareSortKeys(Item1, Item2: Pointer): Integer;\nvar\n  SortKey1   : string;\n  SortKey2   : string;\n//  Container1 : IwbContainer;\n//  Container2 : IwbContainer;\nbegin\n  if Item1 = Item2 then begin\n    Result := 0;\n    Exit;\n  end;\n\n  SortKey1 := IwbElement(Item1).SortKey[True];\n  SortKey2 := IwbElement(Item2).SortKey[True];\n\n  Result := CompareStr(SortKey1, SortKey2);\n\n  if Result = 0 then begin\n    SortKey1 := IwbElement(Item1).Value;\n    SortKey2 := IwbElement(Item1).Value;\n\n    Result := CompareStr(SortKey1, SortKey2);\n\n    if Result = 0 then begin\n      Result := CmpW32(Ord(IwbElement(Item1).ElementType), Ord(IwbElement(Item2).ElementType));\n      if Result = 0 then begin\n        if IwbElement(Item1).ElementType = etSubRecord then\n          Result := CmpW32(\n            Cardinal((IwbElement(Item1) as IwbSubRecord).DataBasePtr),\n            Cardinal((IwbElement(Item2) as IwbSubRecord).DataBasePtr)\n          ){\n        else try\n          if Supports(IwbElement(Item1), IwbContainer, Container1) and Supports(IwbElement(Item2), IwbContainer, Container2) then\n            Result := CmpW32(\n              Cardinal((Container1 as TwbContainer).cntElements),  // Arbitrary value that should not change during the sort\n              Cardinal((Container2 as TwbContainer).cntElements)\n            );\n        except\n          // If an Element supporting IwbContainer could NOT be a TwbContainer\n        end};\n      end;\n    end;\n  end;\nend;\n\n\nfunction CompareSortOrder(Item1, Item2: Pointer): Integer;\nvar\n  SortOrder1: Integer;\n  SortOrder2: Integer;\nbegin\n  if Item1 = Item2 then begin\n    Result := 0;\n    Exit;\n  end;\n\n  SortOrder1 := IwbElement(Item1).SortOrder;\n  SortOrder2 := IwbElement(Item2).SortOrder;\n\n  Result := CmpI32(SortOrder1, SortOrder2);\nend;\n\nfunction CompareLoadOrder(Item1, Item2: Pointer): Integer;\nvar\n  LoadOrder1: Integer;\n  LoadOrder2: Integer;\nbegin\n  if Item1 = Item2 then begin\n    Result := 0;\n    Exit;\n  end;\n\n  LoadOrder1 := IwbFile(Item1).LoadOrder;\n  LoadOrder2 := IwbFile(Item2).LoadOrder;\n\n  Result := CmpI32(LoadOrder1, LoadOrder2);\n  if Result = 0 then\n    Result := CmpW32(IwbFile(Item1).ElementID, IwbFile(Item2).ElementID);\nend;\n\n{ TwbFile }\n\nprocedure TwbFile.AddMaster(const aFileName: string; IsTemporary: Boolean);\nvar\n  _File : IwbFile;\n  s     : string;\n  t     : string;\n  i     : Integer;\nbegin\n  if not wbRequireLoadorder and IsTemporary then begin\n    for i := 0 to Pred(GetMasterCount) do\n      if SameText(ExtractFileName(aFileName), GetMaster(i).FileName) then\n        Exit;\n  end;\n\n  s := ExtractFilePath(aFileName);\n  t := ExtractFileName(aFileName);\n  if s = '' then\n    s := ExtractFilePath(flFileName);\n  if s <> '' then\n    s := IncludeTrailingPathDelimiter(s);\n\n  flProgress('Adding master \"' + t + '\"');\n  _File := wbFile(s + t, -1, '', IsTemporary, False);\n  if not (wbToolMode in [tmDump, tmExport]) and (wbRequireLoadOrder and (_File.LoadOrder < 0)) then\n    raise Exception.Create('\"' + GetFileName + '\" requires master \"' + aFileName + '\" to be loaded before it.')\n  else\n    AddMaster(_File);\nend;\n\nfunction TwbFile.Add(const aName: string; aSilent: Boolean): IwbElement;\nvar\n  Signature : TwbSignature;\n  Dummy     : Integer;\nbegin\n  if not IsElementEditable(nil) then\n    raise Exception.Create('File \"'+GetFileName+'\" is not editable');\n\n  Result := nil;\n\n  if Length(aName) < 4 then\n    Exit;\n\n  Signature := StrToSignature(aName);\n\n  Result := GetGroupBySignature(Signature);\n\n  if Assigned(Result) then\n    Exit;\n\n  if not wbGroupOrder.Find(Signature, Dummy) then\n    Exit;\n  if GroupToSkip.Find(Signature, Dummy) then\n    Exit;\n  if RecordToSkip.Find(Signature, Dummy) then\n    Exit;\n\n  Result := TwbGroupRecord.Create(Self, Signature);\n\n  if Length(cntElements) > 1 then\n    wbMergeSort(@cntElements[1], High(cntElements), CompareSortOrder);\nend;\n\nfunction TwbFile.AddIfMissingInternal(const aElement: IwbElement; aAsNew, aDeepCopy : Boolean; const aPrefixRemove, aPrefix, aSuffix: string): IwbElement;\nvar\n  GroupRecord : IwbGroupRecord;\n  Dummy       : Integer;\n  Signature   : TwbSignature;\n  SelfRef     : IwbContainerElementRef;\n  i           : Integer;\nbegin\n  if not IsElementEditable(nil) then\n    raise Exception.Create('File \"'+GetFileName+'\" is not editable');\n\n  SelfRef := Self as IwbContainerElementRef;\n  if not Supports(aElement, IwbGroupRecord, GroupRecord) then\n    raise Exception.Create('Only group records can be added to files');\n  if GroupRecord.GroupType <> 0 then\n    raise Exception.Create('Only top level group records can be added to files');\n  Signature := TwbSignature(GroupRecord.GroupLabel);\n  if not wbGroupOrder.Find(Signature, Dummy) then\n    raise Exception.Create(Signature + 'is not a valid group label');\n  Result := GetGroupBySignature(Signature);\n  if not Assigned(Result) then begin\n    Result := TwbGroupRecord.Create(Self, Signature);\n    if Length(cntElements) > 1 then\n      wbMergeSort(@cntElements[1],  High(cntElements), CompareSortOrder);\n  end;\n\n  if aDeepCopy then\n    for i := 0 to Pred(GroupRecord.ElementCount) do\n      Result.AddIfMissing(GroupRecord.Elements[i], aAsNew, True, aPrefixRemove, aPrefix, aSuffix);\nend;\n\nprocedure TwbFile.AddMainRecord(const aRecord: IwbMainRecord);\nconst\n  MGEF      : TwbSignature = 'MGEF';\n  GMST      : TwbSignature = 'GMST';\nvar\n  FormID    : Cardinal;\n  s         : string;\n  i         : Integer;\n  Master    : IwbMainRecord;\n  FileID    : Byte;\n  Signature : TwbSignature;\nbegin\n  if not Assigned(aRecord) then\n    Exit;\n  FormID := aRecord.FormID;\n  if FormID <> 0 then begin\n\n    if flFormIDsSorted then begin\n\n      if Length(flRecords) > 0 then begin\n        if FindFormID(FormID, i) then\n          raise Exception.Create('Duplicate FormID ['+IntToHex64(FormID, 8)+'] in file ' + GetName);\n      end else\n        i := 0;\n\n      SetLength(flRecords, Succ(Length(flRecords)));\n      if i < High(flRecords) then begin\n        Move(flRecords[i], flRecords[Succ(i)], SizeOf(Pointer) * (High(flRecords) - i));\n        Pointer(flRecords[i]) := nil;\n      end;\n      flRecords[i] := aRecord;\n\n    end else begin\n\n      if flRecordsCount >= Length(flRecords) then\n        SetLength(flRecords, Succ(flRecordsCount));\n\n      flRecords[flRecordsCount] := aRecord;\n      Inc(flRecordsCount);\n\n    end;\n\n    FileID := FormID shr 24;\n    if FileID >= Cardinal(GetMasterCount) then begin\n      {new record...}\n    end else try\n      Master := GetMasterRecordByFormID(FormID, True);\n      if Assigned(Master) then\n        (Master as IwbMainRecordInternal).AddOverride(aRecord)\n      else\n        (GetMaster(FileID) as IwbFileInternal).InjectMainRecord(aRecord);\n    except\n      on E: Exception do\n        if Assigned(wbProgressCallback) then\n          wbProgressCallback('Error: <'+e.Message+'> while trying to determine master record for ' + aRecord.Name);\n    end;\n  end;\n\n  if flFormIDsSorted then\n    Exit;\n\n  Signature := aRecord.Signature;\n\n  if (Cardinal(Signature) = Cardinal(MGEF)) or (Cardinal(Signature) = Cardinal(GMST)) or wbTrackAllEditorID then begin\n    s := aRecord.EditorID;\n    if s <> '' then begin\n      if flRecordsByEditorIDCount >= Length(flRecordsByEditorID) then\n        SetLength(flRecordsByEditorID, Succ(flRecordsByEditorIDCount));\n\n      flRecordsByEditorID[flRecordsByEditorIDCount] := aRecord;\n      Inc(flRecordsByEditorIDCount);\n    end;\n  end;\nend;\n\nprocedure TwbFile.AddMaster(const aFile: IwbFile);\nbegin\n  SetLength(flMasters, Succ(Length(flMasters)));\n  flMasters[High(flMasters)] := aFile;\nend;\n\nprocedure TwbFile.AddMasterIfMissing(const aMaster: string);\nvar\n  i       : Integer;\n  Masters : TStringList;\nbegin\n  for i := 0 to Pred(GetMasterCount) do\n    if SameText(aMaster, GetMaster(i).FileName) then\n      Exit;\n  Masters := TStringList.Create;\n  try\n    Masters.Add(aMaster);\n    AddMasters(Masters);\n    SortMasters;\n  finally\n    Masters.Free;\n  end;\nend;\n\nprocedure TwbFile.AddMasters(aMasters: TStrings);\nvar\n  OldMasterCount : Integer;\n  Header         : IwbContainerElementRef;\n  MasterFiles    : IwbContainerElementRef;\n  IsNew          : Boolean;\n  rec            : IwbRecord;\n  i, j           : Integer;\nbegin\n  OldMasterCount := GetMasterCount;\n\n  if not IsElementEditable(nil) then\n    raise Exception.Create('File \"'+GetFileName+'\" is not editable');\n\n  if GetIsNotPlugin then\n    Exit;\n\n  if (GetElementCount < 1) or not Supports(GetElement(0), IwbContainerElementRef, Header) then\n    raise Exception.CreateFmt('Unexpected error reading file \"%s\"', [flFileName]);\n\n  IsNew := False;\n  MasterFiles := Header.ElementByName['Master Files'] as IwbContainerElementRef;\n  if not Assigned(MasterFiles) then begin\n    Header.Assign(5, nil, False);\n    MasterFiles := Header.ElementByName['Master Files'] as IwbContainerElementRef;\n    Assert(Assigned(MasterFiles));\n    IsNew := True;\n  end;\n\n  for i := 0 to Pred(aMasters.Count) do begin\n    if IsNew then begin\n      Assert(MasterFiles.ElementCount = 1);\n      Rec := (MasterFiles[0] as IwbContainer).RecordBySignature['MAST'];\n      IsNew := False;\n    end else begin\n      j := MasterFiles.ElementCount;\n      MasterFiles.Assign(High(Integer), nil, False);\n      Assert(MasterFiles.ElementCount = Succ(j));\n      Rec := (MasterFiles[j] as IwbContainer).RecordBySignature['MAST'];\n    end;\n\n    Assert(Assigned(Rec));\n    Assert(Rec.EditValue = '');\n\n    Rec.EditValue := aMasters[i];\n    AddMaster(aMasters[i]);\n  end;\n\n  MasterCountUpdated(OldMasterCount, GetMasterCount);\n  SortRecords;\nend;\n\nprocedure TwbFile.BuildReachable;\nvar\n  Group : IwbGroupRecord;\n  i     : Integer;\n  Rec   : IwbMainRecord;\n  Cnt   : IwbContainerElementRef;\n  Cnt2  : IwbContainerElementRef;\n  Flg   : IwbElement;\n  s     : string;\nbegin\n  Assert(Length(cntElements) > 0);\n  cntElements[0].Reached;\n\n  for i := Low(flRecords) to High(flRecords) do\n    if flRecords[i].LoadOrderFormID > $800 then\n      break\n    else\n      if flRecords[i].IsWinningOverride then\n        (flRecords[i] as IwbElementInternal).Reached;\n\n  Group := GetGroupBySignature('GMST');\n  if Assigned(Group) then\n    for i := 0 to Pred(Group.ElementCount) do\n      (Group.Elements[i] as IwbElementInternal).Reached;\n  Group := GetGroupBySignature('ANIO');\n  if Assigned(Group) then\n    for i := 0 to Pred(Group.ElementCount) do\n      (Group.Elements[i] as IwbElementInternal).Reached;\n  Group := GetGroupBySignature('IDLE');\n  if Assigned(Group) then\n    for i := 0 to Pred(Group.ElementCount) do\n      (Group.Elements[i] as IwbElementInternal).Reached;\n  Group := GetGroupBySignature('LSCR');\n  if Assigned(Group) then\n    for i := 0 to Pred(Group.ElementCount) do\n      (Group.Elements[i] as IwbElementInternal).Reached;\n\n  if wbGameMode = gmTES4 then begin\n    Group := GetGroupBySignature('SKIL');\n    if Assigned(Group) then\n      for i := 0 to Pred(Group.ElementCount) do\n        (Group.Elements[i] as IwbElementInternal).Reached;\n    Group := GetGroupBySignature('BSGN');\n    if Assigned(Group) then\n      for i := 0 to Pred(Group.ElementCount) do\n        (Group.Elements[i] as IwbElementInternal).Reached;\n\n    Group := GetGroupBySignature('CLAS');\n    if Assigned(Group) then\n      for i := 0 to Pred(Group.ElementCount) do\n        if Supports(Group.Elements[i], IwbMainRecord, Rec) then begin\n          if Rec.IsWinningOverride then begin\n            Cnt := Rec as IwbContainerElementRef;\n            if Supports(Cnt.RecordBySignature['DATA'], IwbContainerElementRef, Cnt) then begin\n              Flg := Cnt.ElementByName['Flags'];\n              if Assigned(Flg) then begin\n                s := Flg.EditValue;\n                if (Length(s) > 0) and (s[1]='1') then\n                  (Rec as IwbElementInternal).Reached;\n              end;\n            end;\n          end;\n        end;\n  end else begin\n    Group := GetGroupBySignature('AVIF');\n    if Assigned(Group) then\n      for i := 0 to Pred(Group.ElementCount) do\n        (Group.Elements[i] as IwbElementInternal).Reached;\n    Group := GetGroupBySignature('ADDN');\n    if Assigned(Group) then\n      for i := 0 to Pred(Group.ElementCount) do\n        (Group.Elements[i] as IwbElementInternal).Reached;\n    Group := GetGroupBySignature('CAMS');\n    if Assigned(Group) then\n      for i := 0 to Pred(Group.ElementCount) do\n        (Group.Elements[i] as IwbElementInternal).Reached;\n    Group := GetGroupBySignature('CPTH');\n    if Assigned(Group) then\n      for i := 0 to Pred(Group.ElementCount) do\n        (Group.Elements[i] as IwbElementInternal).Reached;\n    Group := GetGroupBySignature('NAVI');\n    if Assigned(Group) then\n      for i := 0 to Pred(Group.ElementCount) do\n        (Group.Elements[i] as IwbElementInternal).Reached;\n    Group := GetGroupBySignature('RADS');\n    if Assigned(Group) then\n      for i := 0 to Pred(Group.ElementCount) do\n        (Group.Elements[i] as IwbElementInternal).Reached;\n\n    Group := GetGroupBySignature('PERK');\n    if Assigned(Group) then\n      for i := 0 to Pred(Group.ElementCount) do\n        if Supports(Group.Elements[i], IwbMainRecord, Rec) then begin\n          if Rec.IsWinningOverride then begin\n            Cnt := Rec as IwbContainerElementRef;\n            if Supports(Cnt.RecordBySignature['DATA'], IwbContainerElementRef, Cnt) then begin\n              Flg := Cnt.ElementByName['Playable'];\n              if Assigned(Flg) then begin\n                if Flg.NativeValue <> 0 then\n                  (Rec as IwbElementInternal).Reached;\n              end;\n            end;\n          end;\n        end;\n\n    Group := GetGroupBySignature('HDPT');\n    if Assigned(Group) then\n      for i := 0 to Pred(Group.ElementCount) do\n        if Supports(Group.Elements[i], IwbMainRecord, Rec) then begin\n          if Rec.IsWinningOverride then begin\n            Cnt := Rec as IwbContainerElementRef;\n            if Supports(Cnt.RecordBySignature['DATA'], IwbContainerElementRef, Cnt) then begin\n              if (Integer(Cnt.NativeValue) and 1) <> 0 then\n                (Rec as IwbElementInternal).Reached;\n            end;\n          end;\n        end;\n\n    Group := GetGroupBySignature('DIAL');\n    if Assigned(Group) then\n      for i := 0 to Pred(Group.ElementCount) do\n        if Supports(Group.Elements[i], IwbMainRecord, Rec) then begin\n          if Rec.IsWinningOverride then begin\n            Cnt := Rec as IwbContainerElementRef;\n            if Supports(Cnt.RecordBySignature['DATA'], IwbContainerElementRef, Cnt2) then begin\n              Flg := Cnt2.ElementByName['Flags'];\n              if Assigned(Flg) then begin\n                s := Flg.SortKey[False];\n                if (Length(s)>1) and (s[2] = '1') then\n                  (Rec as IwbElementInternal).Reached;\n              end;\n            end;\n          end;\n        end;\n\n    Group := GetGroupBySignature('NPC_');\n    if Assigned(Group) then\n      for i := 0 to Pred(Group.ElementCount) do\n        if Supports(Group.Elements[i], IwbMainRecord, Rec) then begin\n          if Rec.IsWinningOverride then begin\n            Cnt := Rec as IwbContainerElementRef;\n            if Supports(Cnt.RecordBySignature['ACBS'], IwbContainerElementRef, Cnt) then begin\n              Flg := Cnt.ElementByName['Flags'];\n              if Assigned(Flg) then begin\n                s := Flg.EditValue;\n                if (Length(s) > 2) and (s[3]='1') then\n                  (Rec as IwbElementInternal).Reached;\n              end;\n            end;\n          end;\n        end;\n  end;\n\n  Group := GetGroupBySignature('RACE');\n  if Assigned(Group) then\n    for i := 0 to Pred(Group.ElementCount) do\n      if Supports(Group.Elements[i], IwbMainRecord, Rec) then begin\n        if Rec.IsWinningOverride then begin\n          Cnt := Rec as IwbContainerElementRef;\n          if Supports(Cnt.RecordBySignature['DATA'], IwbContainerElementRef, Cnt) then begin\n            Flg := Cnt.ElementByName['Flags'];\n            if Assigned(Flg) then begin\n              s := Flg.EditValue;\n              if (Length(s) > 0) and (s[1]='1') then\n                (Rec as IwbElementInternal).Reached;\n            end;\n          end;\n        end;\n      end;\n\n  Group := GetGroupBySignature('QUST');\n  if Assigned(Group) then\n    for i := 0 to Pred(Group.ElementCount) do\n      if Supports(Group.Elements[i], IwbMainRecord, Rec) then begin\n        if Rec.IsWinningOverride then begin\n          Cnt := Rec as IwbContainerElementRef;\n          if Supports(Cnt.RecordBySignature['DATA'], IwbContainerElementRef, Cnt) then begin\n            Flg := Cnt.Elements[0];\n            if Assigned(Flg) then begin\n              s := Flg.EditValue;\n              if (Length(s) > 0) and (s[1]='1') then\n                (Rec as IwbElementInternal).Reached;\n            end;\n          end;\n        end;\n      end;\nend;\n\nprocedure TwbFile.BuildRef;\nbegin\n  inherited;\nend;\n\nprocedure TwbFile.CleanMasters;\nvar\n  i, j, k     : Integer;\n  Old,New     : TBytes;\n  Header      : IwbContainerElementRef;\n  MasterFiles : IwbContainerElementRef;\n  Rec         : IwbRecord;\n  UsedMasters : TwbUsedMasters;\nbegin\n  if not IsElementEditable(nil) then\n    raise Exception.Create('File \"'+GetFileName+'\" is not editable');\n  if (GetElementCount < 1) or not Supports(GetElement(0), IwbContainerElementRef, Header) then\n    raise Exception.CreateFmt('Unexpected error reading file \"%s\"', [flFileName]);\n\n  if Length(flMasters) >= 1 then begin\n    MasterFiles := Header.ElementByName['Master Files'] as IwbContainerElementRef;\n    Assert(Assigned(MasterFiles));\n    Assert(MasterFiles.ElementCount = Length(flMasters));\n\n    for i := Low(flMasters) to High(flMasters) do begin\n      Rec := (MasterFiles[i] as IwbContainer).RecordBySignature['MAST'];\n      Assert(Assigned(Rec));\n      Assert(SameText(Rec.Value, flMasters[i].FileName));\n      MasterFiles[i].SortOrder := i;\n    end;\n\n    FillChar(UsedMasters, SizeOf(UsedMasters), 0);\n    FindUsedMasters(@UsedMasters);\n\n    Old := nil;\n    New := nil;\n    j := 0;\n    for i := Low(flMasters) to High(flMasters) do\n      if UsedMasters[i] then begin\n        if i <> j then begin\n          flMasters[j] := flMasters[i];\n\n          MasterFiles[i].SortOrder := j;\n          SetLength(Old, Succ(Length(Old)));\n          Old[High(Old)] := i;\n          SetLength(New, Succ(Length(New)));\n          New[High(New)] := j;\n        end;\n        Inc(j);\n      end else\n        MasterFiles[i].SortOrder := $100;\n\n    k := Length(flMasters);\n    if j <> k then begin\n      SetLength(flMasters, j);\n\n      (MasterFiles as IwbContainerInternal).SortBySortOrder;\n      for i := Pred(MasterFiles.ElementCount) downto 0 do\n        if MasterFiles[i].SortOrder = $100 then\n          MasterFiles.RemoveElement(i);\n\n      Assert(Length(flMasters) = MasterFiles.ElementCount);\n\n      for i := Low(flMasters) to High(flMasters) do begin\n        Rec := (MasterFiles[i] as IwbContainer).RecordBySignature['MAST'];\n        Assert(Assigned(Rec));\n        Assert(SameText(Rec.Value, flMasters[i].FileName));\n      end;\n\n      if Length(Old) > 0 then\n        MasterIndicesUpdated(Old, New);\n      MasterCountUpdated(k, j);\n      SortRecords;\n    end;\n  end;\nend;\n\nconstructor TwbFile.Create(const aFileName: string; aLoadOrder: Integer; aCompareTo: string; aOnlyHeader: Boolean; IsTemporary: Boolean = False);\nbegin\n  if IsTemporary then\n    Include(flStates, fsIsTemporary);\n  if aCompareTo <> '' then begin\n    Include(flStates, fsIsCompareLoad);\n    if SameText(ExtractFileName(aFileName), wbGameName + wbHardcodedDat) then\n      Include(flStates, fsIsHardcoded);\n  end else if SameText(ExtractFileName(aFileName), wbGameName + '.esm') then\n    Include(flStates, fsIsGameMaster);\n  if aOnlyHeader then\n    Include(flStates, fsOnlyHeader);\n  flCompareTo := aCompareTo;\n  flLoadOrder := aLoadOrder;\n  flFileName := aFileName;\n  flOpenFile;\n  Scan;\nend;\n\nconstructor TwbFile.CreateNew(const aFileName: string; aLoadOrder: Integer);\nvar\n  Header : IwbMainRecord;\nbegin\n  Include(flStates, fsIsNew);\n  flLoadOrder := aLoadOrder;\n  flFileName := aFileName;\n  Header := TwbMainRecord.Create(Self, wbHeaderSignature, 0);\n  if wbGameMode = gmFNV then\n    Header.RecordBySignature['HEDR'].Elements[0].EditValue := '1.34'\n  else if wbGameMode = gmFO3 then\n    Header.RecordBySignature['HEDR'].Elements[0].EditValue := '0.94'\n  else if wbGameMode = gmTES3 then\n    Header.RecordBySignature['HEDR'].Elements[0].EditValue := '1.30'\n  else if wbGameMode = gmTES4 then\n    Header.RecordBySignature['HEDR'].Elements[0].EditValue := '1.0'\n  else if wbGameMode = gmTES5 then\n    Header.RecordBySignature['HEDR'].Elements[0].EditValue := '1.7'\n  else if wbGameMode = gmSSE then\n    Header.RecordBySignature['HEDR'].Elements[0].EditValue := '1.7'\n  else if wbGameMode = gmFO4 then\n    Header.RecordBySignature['HEDR'].Elements[0].EditValue := '0.95';\n  Header.RecordBySignature['HEDR'].Elements[2].EditValue := '2048';\n  flLoadFinished := True;\nend;\n\ndestructor TwbFile.Destroy;\nbegin\n  flCloseFile;\n  inherited;\nend;\n\nfunction TwbFile.FileFileIDtoLoadOrderFileID(aFileID: Byte): Byte;\nvar\n  NewFileID : Integer;\nbegin\n  if aFileID >= GetMasterCount then\n    NewFileID := GetLoadOrder\n  else\n    NewFileID := flMasters[aFileID].LoadOrder;\n\n  if NewFileID < 0 then\n    raise Exception.Create('File FormID ['+IntToHex64(aFileID, 2)+'] can not be mapped to load order FormID for file \"'+GetFileName+'\"');\n\n  Result := NewFileID;\nend;\n\nfunction TwbFile.FileFormIDtoLoadOrderFormID(aFormID: Cardinal): Cardinal;\nvar\n  FileID    : Integer;\n  NewFileID : Integer;\nbegin\n  if aFormID = 0 then begin\n    Result := 0;\n    Exit;\n  end;\n\n  FileID := aFormID shr 24;\n  if FileID >= GetMasterCount then\n    NewFileID := GetLoadOrder\n  else\n    NewFileID := flMasters[FileID].LoadOrder;\n\n  if NewFileID < 0 then\n    raise Exception.Create('File FormID ['+IntToHex64(aFormID, 8)+'] can not be mapped to load order FormID for file \"'+GetFileName+'\"');\n\n  Result := (aFormID and $00FFFFFF) or (Cardinal(NewFileID) shl 24);\nend;\n\nfunction TwbFile.FindEditorID(const aEditorID: string; var Index: Integer): Boolean;\nvar\n  L, H, I, C: Integer;\nbegin\n  Result := False;\n  if not flLoadFinished then\n    Exit;\n\n  L := Low(flRecordsByEditorID);\n  H := High(flRecordsByEditorID);\n  while L <= H do begin\n    I := (L + H) shr 1;\n    C := CompareText(flRecordsByEditorID[I].EditorID, aEditorID);\n    if C < 0 then\n      L := I + 1\n    else begin\n      H := I - 1;\n      if C = 0 then begin\n        Result := True;\n        L := I;\n      end;\n    end;\n  end;\n  Index := L;\nend;\n\nfunction TwbFile.FindFormID(aFormID: Cardinal; var Index: Integer): Boolean;\nvar\n  L, H, I, C: Integer;\nbegin\n  Result := False;\n  if not flFormIDsSorted then begin\n    Exit;\n\n    for i := 0 to Pred(flRecordsCount) do\n      if flRecords[I].FixedFormID = aFormID then begin\n        Index := i;\n        Result := True;\n        Exit;\n      end;\n    Exit;\n  end;\n\n  if (aFormID shr 24) > Cardinal(GetMasterCount) then\n    aFormID := (aFormID and $00FFFFFF) or (Cardinal(GetMasterCount) shl 24);\n\n  L := Low(flRecords);\n  H := High(flRecords);\n  while L <= H do begin\n    I := (L + H) shr 1;\n    C := CmpW32(flRecords[I].FixedFormID, aFormID);\n    if C < 0 then\n      L := I + 1\n    else begin\n      H := I - 1;\n      if C = 0 then begin\n        Result := True;\n        L := I;\n      end;\n    end;\n  end;\n  Index := L;\nend;\n\nfunction TwbFile.FindInjectedID(aFormID: Cardinal; var Index: Integer): Boolean;\nvar\n  L, H, I, C: Integer;\nbegin\n  Result := False;\n  aFormID := aFormID and $00FFFFFF;\n\n  L := Low(flInjectedRecords);\n  H := High(flInjectedRecords);\n  while L <= H do begin\n    I := (L + H) shr 1;\n    C := CmpW32(flInjectedRecords[I].FormID and $00FFFFFF, aFormID);\n    if C < 0 then\n      L := I + 1\n    else begin\n      H := I - 1;\n      if C = 0 then begin\n        Result := True;\n        L := I;\n      end;\n    end;\n  end;\n  Index := L;\nend;\n\nprocedure TwbFile.flCloseFile;\nbegin\n  if Assigned(flView) then begin\n    UnmapViewOfFile(flView);\n    flView := nil;\n  end;\n\n  if (flMapHandle <> INVALID_HANDLE_VALUE) and (flMapHandle <> 0) then begin\n    CloseHandle(flMapHandle);\n    flMapHandle := INVALID_HANDLE_VALUE;\n  end;\n\n  if (flFileHandle <> INVALID_HANDLE_VALUE) and (flFileHandle <> 0) then begin\n    CloseHandle(flFileHandle);\n    flFileHandle := INVALID_HANDLE_VALUE;\n  end;\n  if fsIsTemporary in flStates then\n    try\n      DeleteFile(Self.flFileName);\n    except\n      wbProgressCallback('Could not delete temporary file '+flFileName);\n    end;\nend;\n\nprocedure TwbFile.flOpenFile;\nconst\n  FileAccessMode: array[Boolean] of Cardinal = (GENERIC_READ, GENERIC_READ or GENERIC_WRITE);\n  FileShareMode: array[Boolean] of Cardinal = (FILE_SHARE_READ, 0);\n  PageProtection: array[Boolean] of Cardinal = (PAGE_READONLY, PAGE_READWRITE);\n  ViewAccessMode: array[Boolean] of Cardinal = (FILE_MAP_READ, FILE_MAP_READ or FILE_MAP_WRITE);\nbegin\n  flProgress('Loading file');\n\n  flFileHandle := CreateFile(\n    PChar(flFileName),\n    FileAccessMode[False],\n    FileShareMode[False],\n    nil,\n    OPEN_EXISTING,\n    FILE_FLAG_RANDOM_ACCESS,\n    0\n  );\n  if (flFileHandle = INVALID_HANDLE_VALUE) or (flFileHandle = 0) then\n    RaiseLastOSError;\n\n  flMapHandle := CreateFileMapping(\n    flFileHandle,\n    nil,\n    PageProtection[False],\n    0,\n    0,\n    nil\n  );\n  if (flMapHandle = INVALID_HANDLE_VALUE) or (flMapHandle = 0) then\n    RaiseLastOSError;\n\n  flView := MapViewOfFileEx(\n    flMapHandle,\n    ViewAccessMode[False],\n    0,\n    0,\n    0,\n    nil\n  );\n\n  if not Assigned(flView) then\n    RaiseLastOSError;\n\n  flEndPtr := Pointer( Cardinal(flView) + GetFileSize(flFileHandle, nil) );\n\n  flProgress('File loaded');\nend;\n\nprocedure TwbFile.flProgress(const aStatus: string);\nbegin\n  if Assigned(wbProgressCallback) then\n    wbProgressCallback('['+GetFileName+'] ' + aStatus);\nend;\n\nprocedure TwbFile.ForceClosed;\nvar\n  i: Integer;\nbegin\n  for i := High(flRecords) downto Low(flRecords) do\n    (flRecords[i] as IwbMainRecordInternal).ClearForRelease;\n  for i := High(flInjectedRecords) downto Low(flInjectedRecords) do\n    (flInjectedRecords[i] as IwbMainRecordInternal).ClearForRelease;\n  flMasters                := nil;\n  flRecords                := nil;\n  flRecordsByEditorID      := nil;\n  flInjectedRecords        := nil;\n  ReleaseElements;\n  flCloseFile;\nend;\n\nprocedure TwbFile.ForceLoadOrder(aValue: Integer);\nbegin\n  flLoadOrder := aValue;\nend;\n\nfunction TwbFile.GetAddList: TDynStrings;\nvar\n  i, j        : Integer;\n  GroupRecord : IwbGroupRecord;\n  RecordDef   : PwbRecordDef;\nbegin\n  Result := nil;\n\n  if not IsElementEditable(nil) then\n    Exit;\n\n  with TStringList.Create do try\n    Sorted := True;\n    Duplicates := dupIgnore;\n\n    AddStrings(wbGroupOrder);\n\n    for i := 0 to Pred(GroupToSkip.Count) do\n      if Find(GroupToSkip[i], j) then\n        Delete(j);\n    for i := 0 to Pred(RecordToSkip.Count) do\n      if Find(RecordToSkip[i], j) then\n        Delete(j);\n    for i := Succ(Low(cntElements)) to High(cntElements) do\n      if Supports(cntElements[i], IwbGroupRecord, GroupRecord) then\n        if GroupRecord.GroupType = 0 then\n          if Find(TwbSignature(GroupRecord.GroupLabel), j) then\n            Delete(j);\n\n    Sorted := False;\n\n    for i := Pred(Count) downto 0 do\n      if wbFindRecordDef(AnsiString(Strings[i]), RecordDef) then\n        Strings[i] := Strings[i] + ' - ' + RecordDef.Name\n      else\n        Delete(i);\n\n    SetLength(Result, Count);\n    for i := 0 to Pred(Count) do\n      Result[i] := Strings[i];\n  finally\n    Free;\n  end;\nend;\n\nfunction TwbFile.GetBaseName: string;\nbegin\n  Result := GetFileName;\n  if fsIsHardcoded in flStates then\n    Result := wbGameName + '.exe';\nend;\n\nfunction TwbFile.GetElementType: TwbElementType;\nbegin\n  Result := etFile;\nend;\n\nfunction TwbFile.GetFile: IwbFile;\nbegin\n  Result := Self;\nend;\n\nfunction TwbFile.GetFileName: string;\nbegin\n  Result := ExtractFileName(flFileName);\nend;\n\nfunction TwbFile.GetFileStates: TwbFileStates;\nbegin\n  Result := flStates;\nend;\n\nfunction TwbFile.GetGroupBySignature(const aSignature: TwbSignature): IwbGroupRecord;\nvar\n  SelfRef: IwbContainerElementRef;\n  i: Integer;\nbegin\n  SelfRef := Self;\n  DoInit;\n\n  for i := Low(cntElements) to High(cntElements) do\n    if Supports(cntElements[i], IwbGroupRecord, Result) and\n      (Result.GroupType = 0) and\n      (TwbSignature(Result.GroupLabel) = aSignature) then\n      Exit;\n\n  Result := nil;\nend;\n\nfunction TwbFile.GetHasNoFormID: Boolean;\nbegin\n  Result := GetIsNotPlugin or (fsHasNoFormID in flStates);\nend;\n\nfunction TwbFile.GetHeader: IwbMainRecord;\nvar\n  SelfRef : IwbContainerElementRef;\nbegin\n  SelfRef := Self;\n  DoInit;\n\n  if (Length(cntElements) > 0) and\n     (Supports(cntElements[0], IwbMainRecord, Result)) and\n     (Result.Signature = wbHeaderSignature) then begin\n    {Result already set}\n  end else\n    Result := nil;\nend;\n\nfunction TwbFile.GetIsEditable: Boolean;\nbegin\n  Result := wbIsInternalEdit or (\n        wbEditAllowed and\n    not (fsIsGameMaster in flStates) and\n    not (fsIsHardcoded in flStates) and\n    not (fsIsCompareLoad in flStates)\n  );\nend;\n\nfunction TwbFile.GetIsESM: Boolean;\nvar\n  Header         : IwbMainRecord;\nbegin\n  if GetIsNotPlugin then begin\n    Result := False;\n    Exit;\n  end;\n\n  if (GetElementCount < 1) or not Supports(GetElement(0), IwbMainRecord, Header) then\n    raise Exception.CreateFmt('Unexpected error reading file \"%s\"', [flFileName]);\n\n  Result := Header.IsESM;\nend;\n\nfunction TwbFile.GetIsLocalized: Boolean;\nvar\n  Header         : IwbMainRecord;\nbegin\n  if GetIsNotPlugin then begin\n    Result := False;\n    Exit;\n  end;\n\n  if (GetElementCount < 1) or not Supports(GetElement(0), IwbMainRecord, Header) then\n    raise Exception.CreateFmt('Unexpected error reading file \"%s\"', [flFileName]);\n\n  Result := Header.IsLocalized;\nend;\n\nfunction TwbFile.GetNextObjectID: Cardinal;\nvar\n  Header         : IwbContainerElementRef;\nbegin\n  if (GetElementCount > 0) and Supports(GetElement(0), IwbContainerElementRef, Header) then\n    Result := Cardinal(Header.ElementNativeValues['HEDR\\Next Object ID'])\n  else\n    Result := 0;\nend;\n\nprocedure TwbFile.SetNextObjectID(aObjectID: Cardinal);\nvar\n  Header         : IwbMainRecord;\nbegin\n  if (GetElementCount > 0) and Supports(GetElement(0), IwbContainerElementRef, Header) then\n    Header.ElementNativeValues['HEDR\\Next Object ID'] := aObjectID;\nend;\n\nfunction TwbFile.GetIsNotPlugin: Boolean;\nbegin\n  Result := not wbIsPlugin(flFileName);\nend;\n\nfunction TwbFile.GetIsRemoveable: Boolean;\nbegin\n  Result := False;\nend;\n\nfunction TwbFile.GetLoadOrder: Integer;\nbegin\n  Result := flLoadOrder;\nend;\n\nfunction TwbFile.GetMaster(aIndex: Integer): IwbFile;\nbegin\n  Result := flMasters[aIndex];\nend;\n\nfunction TwbFile.GetMasterCount: Integer;\nbegin\n  Result := Length(flMasters);\nend;\n\nfunction TwbFile.GetMasterRecordByFormID(aFormID: Cardinal; aAllowInjected: Boolean): IwbMainRecord;\nvar\n  FileID : Byte;\n  Master : IwbFile;\nbegin\n  FileID := aFormID shr 24;\n\n  if FileID >= Cardinal(GetMasterCount) then begin\n    Result := nil;\n  end else begin\n    Master := flMasters[FileID];\n    Result := Master.RecordByFormID[(aFormID and $00FFFFFF) or (Cardinal(Master.MasterCount) shl 24), aAllowInjected];\n  end;\nend;\n\nprocedure TwbFile.GetMasters(aMasters: TStrings);\nvar\n  Header      : IwbMainRecord;\n  MasterFiles : IwbContainerElementRef;\n  Rec         : IwbRecord;\n  i           : Integer;\nbegin\n  if (GetElementCount <> 1) or not Supports(GetElement(0), IwbMainRecord, Header) then\n    raise Exception.CreateFmt('Unexpected error reading file \"%s\"', [flFileName]);\n\n  if Header.Signature <> wbHeaderSignature then\n    raise Exception.CreateFmt('Expected header signature '+wbHeaderSignature+', found %s in file \"%s\"', [String(Header.Signature), flFileName]);\n\n  MasterFiles := Header.ElementByName['Master Files'] as IwbContainerElementRef;\n  if Assigned(MasterFiles) then\n    for i := 0 to Pred(MasterFiles.ElementCount) do begin\n      Rec := (MasterFiles[i] as IwbContainer).RecordBySignature['MAST'];\n      if not Assigned(Rec) then\n        raise Exception.CreateFmt('Unexpected error reading master list for file \"%s\"', [flFileName]);\n      aMasters.Add(Rec.Value);\n    end;\nend;\n\nfunction TwbFile.GetName: string;\nbegin\n  Result := GetFileName;\n  if fsIsHardcoded in flStates then\n    Result := wbGameName + '.exe';\n  if flLoadOrder >= 0 then\n    Result := '['+IntToHex64(flLoadOrder, 2)+'] ' + Result;\nend;\n\nfunction TwbFile.GetRecord(aIndex: Integer): IwbMainRecord;\nbegin\n  Result := flRecords[aIndex];\nend;\n\nfunction TwbFile.GetRecordByEditorID(const aEditorID: string): IwbMainRecord;\nvar\n  i: Integer;\nbegin\n  Result := nil;\n  if FindEditorID(aEditorID, i) then\n    Result := flRecordsByEditorID[i]\n  else\n    for i := Pred(GetMasterCount) downto 0 do begin\n      Result := GetMaster(i).RecordByEditorID[aEditorID];\n      if Assigned(Result) then\n        Exit;\n    end;\nend;\n\nfunction TwbFile.GetRecordByFormID(aFormID: Cardinal; aAllowInjected: Boolean): IwbMainRecord;\nvar\n  i: Integer;\nbegin\n  if FindFormID(aFormID, i) then begin\n    Result := flRecords[i];\n    Exit;\n  end else if aAllowInjected and ((aFormID shr 24) >= Cardinal(GetMasterCount)) and FindInjectedID(aFormID, i) then begin\n    Result := flInjectedRecords[i];\n    Exit;\n  end;\n\n  Result := GetMasterRecordByFormID(aFormID, aAllowInjected);\nend;\n\nfunction TwbFile.GetRecordCount: Integer;\nbegin\n  Result := Length(flRecords);\nend;\n\nfunction TwbFile.GetReferenceFile: IwbFile;\nbegin\n  Result := Self;\nend;\n\nfunction TwbFile.GetUnsavedSince: TDateTime;\nbegin\n  Result := flUnsavedSince;\nend;\n\nfunction TwbFile.HasGroup(const aSignature: TwbSignature): Boolean;\nbegin\n  Result := GetGroupBySignature(aSignature) <> nil;\nend;\n\nfunction TwbFile.HasMaster(const aFileName: string): Boolean;\nvar\n  i: Integer;\nbegin\n  Result := False;\n  for i := 0 to Pred(GetMasterCount) do begin\n    Result := SameText(GetMaster(i).FileName, aFileName);\n    if Result then\n      Exit;\n  end;\n\nend;\n\nprocedure TwbFile.InjectMainRecord(const aRecord: IwbMainRecord);\nvar\n  i: Integer;\nbegin\n  if Length(flInjectedRecords) > 0 then begin\n    if FindInjectedID(aRecord.FormID, i) then begin\n      if [fsIsHardcoded, fsIsCompareLoad] * flInjectedRecords[i]._File.FileStates = [] then begin\n        if Assigned(wbProgressCallback) then\n          wbProgressCallback('<Warning: ' + aRecord.Name + ' was injected into ' + GetFileName + ' which already has been injected with '+flInjectedRecords[i].Name+' from '+flInjectedRecords[i]._File.FileName+' >');\n      end;\n      (flInjectedRecords[i] as IwbMainRecordInternal).AddOverride(aRecord);\n      Exit;\n    end\n  end else\n    i := 0;\n\n  if [fsIsHardcoded, fsIsCompareLoad] * aRecord._File.FileStates = [] then begin\n    if Assigned(wbProgressCallback) then\n      wbProgressCallback('<Note: ' + aRecord.Name + ' was injected into ' + GetFileName + '>');\n  end;\n\n  SetLength(flInjectedRecords, Succ(Length(flInjectedRecords)));\n  if i < High(flInjectedRecords) then begin\n    Move(flInjectedRecords[i], flInjectedRecords[Succ(i)], SizeOf(Pointer) * (High(flInjectedRecords) - i));\n    Pointer(flInjectedRecords[i]) := nil;\n  end;\n  flInjectedRecords[i] := aRecord;\nend;\n\nfunction TwbFile.IsElementEditable(const aElement: IwbElement): Boolean;\nbegin\n  Result := wbIsInternalEdit or GetIsEditable;\nend;\n\nfunction TwbFile.IsElementRemoveable(const aElement: IwbElement): Boolean;\nbegin\n  Result := False;\n\n  if not IsElementEditable(aElement) then\n    Exit;\n\n  if Assigned(aElement) then\n    case aElement.ElementType of\n      etMainRecord: Result := (aElement as IwbMainRecord).Signature <> wbHeaderSignature; {can't remove the file header}\n      etGroupRecord: Result := True;\n    else\n      Assert(False);\n    end;\nend;\n\nfunction TwbFile.LoadOrderFileIDtoFileFileID(aFileID: Byte): Byte;\nvar\n  NewFileID : Integer;\n  i         : Integer;\nbegin\n  NewFileID := -1;\n  if aFileID = GetLoadOrder then\n    NewFileID := GetMasterCount\n  else\n    for i := 0 to Pred(GetMasterCount) do\n      if flMasters[i].LoadOrder = aFileID then begin\n        NewFileID := i;\n        Break;\n      end;\n  if NewFileID < 0 then\n    raise Exception.Create('Load order FileID ['+IntToHex64(aFileID, 2)+'] can not be mapped to file FileID for file \"'+GetFileName+'\"');\n  Result := NewFileID;\nend;\n\nfunction TwbFile.LoadOrderFormIDtoFileFormID(aFormID: Cardinal): Cardinal;\nvar\n  FileID    : Integer;\n  NewFileID : Integer;\n  i         : Integer;\nbegin\n  if aFormID = 0 then begin\n    Result := 0;\n    Exit;\n  end;\n\n  FileID := aFormID shr 24;\n  NewFileID := -1;\n  if FileID = GetLoadOrder then\n    NewFileID := GetMasterCount\n  else\n    for i := 0 to Pred(GetMasterCount) do\n      if flMasters[i].LoadOrder = FileID then begin\n        NewFileID := i;\n        Break;\n      end;\n  if NewFileID < 0 then\n    raise Exception.Create('Load order FormID ['+IntToHex64(aFormID, 8)+'] can not be mapped to file FormID for file \"'+GetFileName+'\"');\n  Result := (aFormID and $00FFFFFF) or (Cardinal(NewFileID) shl 24);\nend;\n\nfunction TwbFile.NewFormID: Cardinal;\nvar\n  SelfRef    : IwbContainerElementRef;\n  FileHeader : IwbMainRecord;\n  HEDR       : IwbRecord;\n\nbegin\n  SelfRef := Self as IwbContainerElementRef;\n  DoInit;\n\n  if Length(cntElements) < 1 then\n    raise Exception.Create('File '+GetFileName+' has no file header');\n\n  if cntElements[0].ElementType <> etMainRecord then\n    raise Exception.Create('File '+GetFileName+' has invalid record '+cntElements[0].Name+' as file header.');\n\n  FileHeader := cntElements[0] as IwbMainRecord;\n  if FileHeader.Signature <> wbHeaderSignature then\n    raise Exception.Create('File '+GetFileName+' has invalid record '+cntElements[0].Name+' with invalid signature as file header.');\n\n  HEDR := FileHeader.RecordBySignature['HEDR'];\n  if not Assigned(HEDR) then\n    raise Exception.Create('File '+GetFileName+' has a file header with missing HEDR subrecord');\n\n  Result := StrToInt64Def(HEDR.Elements[2].EditValue, 2048);\n  Result := Result and $00FFFFFF;\n\n  if (Result = 0) or (Result = $00FFFFFF) then\n    Result := StrToInt64Def(HEDR.Elements[1].EditValue, 2048);\n\n  if Result < 2048 then\n    Result := 2048;\n\n  Result := (Result and $00FFFFFF) or (Cardinal(GetMasterCount) shl 24);\n  while GetRecordByFormID(Result, True) <> nil do begin\n    Inc(Result);\n    if Cardinal(Result shr 24) <> Cardinal(Length(flMasters)) then\n      Result := Cardinal(2048) or (Cardinal(GetMasterCount) shl 24);\n  end;\n  HEDR.Elements[2].EditValue := IntToStr(Succ(Result) and $00FFFFFF);\nend;\n\nprocedure TwbFile.PrepareSave;\nvar\n  SelfRef     : IwbContainerElementRef;\n  i, j, k     : Integer;\n  GroupRecord : IwbGroupRecord;\n  Groups      : array of Boolean;\n  RecordCount : Cardinal;\n\n  FileHeader: IwbMainRecord;\n  HEDR: IwbRecord;\n  MasterFiles : IwbContainerElementRef;\n  MasterFile : IwbContainerElementRef;\n  ONAMs: IwbContainerElementRef;\n  NewONAM: IwbElement;\n  Current: IwbMainRecord;\n  FormID: Cardinal;\n  FileID: Cardinal;\n  Signature : TwbSignature;\n  Master : IwbMainRecord;\nbegin\n  SelfRef := Self as IwbContainerElementRef;\n  DoInit;\n\n  if Length(cntElements) < 1 then\n    raise Exception.Create('File '+GetFileName+' has no file header');\n\n  if not GetIsNotPlugin then begin\n    if cntElements[0].ElementType <> etMainRecord then\n      raise Exception.Create('File '+GetFileName+' has invalid record '+cntElements[0].Name+' as file header.');\n\n    FileHeader := cntElements[0] as IwbMainRecord;\n    if FileHeader.Signature <> wbHeaderSignature then\n      raise Exception.Create('File '+GetFileName+' has invalid record '+cntElements[0].Name+' with invalid signature as file header.');\n\n    HEDR := FileHeader.RecordBySignature['HEDR'];\n    if not Assigned(HEDR) then\n      raise Exception.Create('File '+GetFileName+' has a file header with missing HEDR subrecord');\n\n    inherited;\n\n    SetLength(Groups, wbGroupOrder.Count);\n    for i := Succ(Low(cntElements)) to High(cntElements) do begin\n      if not Supports(cntElements[i], IwbGroupRecord, GroupRecord) then\n        raise Exception.Create('File '+GetFileName+' contains invalid top level record: '+ cntElements[i].Name);\n      if GroupRecord.GroupType <> 0 then\n        raise Exception.Create('File '+GetFileName+' contains invalid top level group type '+IntToStr(GroupRecord.GroupType)+' for group: '+ cntElements[i].Name);\n      if GroupRecord.SortOrder < 0 then\n        raise Exception.Create('File '+GetFileName+' contains top level group without known sort order: '+ cntElements[i].Name);\n      if GroupRecord.SortOrder > High(Groups) then\n        raise Exception.Create('File '+GetFileName+' contains top level group with invalid sort order: '+ cntElements[i].Name);\n      if Groups[GroupRecord.SortOrder] then\n        raise Exception.Create('File '+GetFileName+' contains duplicated top level group: '+ cntElements[i].Name);\n      Groups[GroupRecord.SortOrder] := True;\n    end;\n\n    if Length(cntElements) > 1 then\n      wbMergeSort(@cntElements[1],  High(cntElements), CompareSortOrder);\n\n    RecordCount := GetCountedRecordCount;\n    if RecordCount < 1 then\n      raise Exception.Create('File '+GetFileName+' has an invalid record count');\n\n    HEDR.Elements[1].EditValue := IntToStr(Pred(RecordCount));\n\n    j := 0;\n    ONAMs := nil;\n    if wbGameMode in [gmFO3, gmFNV, gmTES5, gmSSE, gmFO4] then begin\n      Include(TwbMainRecord(FileHeader).mrStates, mrsNoUpdateRefs);\n      while FileHeader.RemoveElement('ONAM') <> nil do\n        ;\n      if Supports(FileHeader.ElementByName['Master Files'], IwbContainerElementRef, MasterFiles) then\n        for i := 0 to Pred(MasterFiles.ElementCount) do begin\n          if Supports(MasterFiles.Elements[i], IwbContainerElementRef, MasterFile) then begin\n            // Fallout 4 CK creates ONAMs in ESP too\n            if FileHeader.IsESM or (wbGameMode = gmFO4) then\n              while j <= High(flRecords) do begin\n                Current := flRecords[j];\n                FormID := Current.FixedFormID;\n                FileID := FormID shr 24;\n                if FileID > i then\n                  Break;\n                Assert(FileID = i);\n                Inc(j);\n\n                Signature := Current.Signature;\n\n                if (Signature = 'NAVM') or\n                   (Signature = 'LAND') or\n                   (Signature = 'REFR') or\n                   (Signature = 'PGRE') or\n                   (Signature = 'PMIS') or\n                   (Signature = 'ACHR') or\n                   (Signature = 'ACRE') or\n                   (Signature = 'PARW') or {>>> Skyrim <<<}\n                   (Signature = 'PBEA') or {>>> Skyrim <<<}\n                   (Signature = 'PFLA') or {>>> Skyrim <<<}\n                   (Signature = 'PCON') or {>>> Skyrim <<<}\n                   (Signature = 'PBAR') or {>>> Skyrim <<<}\n                   (Signature = 'PHZD') or {>>> Skyrim <<<}\n                   // Fallout 4 (and later games?)\n                   ((wbGameMode >= gmFO4) and (\n                     (Signature = 'SCEN') or\n                     (Signature = 'DLBR') or\n                     (Signature = 'DIAL') or\n                     (Signature = 'INFO')\n                   ))\n                then begin\n\n                  if (not wbMasterUpdateFilterONAM) or Current.IsWinningOverride then begin\n                    // ONAMs are for overridden temporary refs only\n                    if Current.IsPersistent then\n                      Continue;\n\n                    if not Assigned(ONAMs) then begin\n                      if not Supports(FileHeader.Add('ONAM', True), IwbContainerElementRef, ONAMs) then\n                        Assert(False);\n                      Assert(ONAMs.ElementCount = 1);\n                      NewONAM := ONAMs.Elements[0];\n                    end else\n                      NewONAM := ONAMs.Assign(High(Integer), nil, True);\n\n                    NewONAM.NativeValue := FormID;\n\n                    if wbMasterUpdateFixPersistence and not Current.IsPersistent and not Current.IsMaster then begin\n                      Master := Current.Master;\n                      if Assigned(Master) then begin\n                        if Master.IsPersistent then begin\n                          flProgress('Setting Persistent: ' + Current.Name);\n                          Current.IsPersistent := True;\n                        end else\n                          for k := 0 to Pred(Master.OverrideCount) do\n                            if Current.Equals(Master.Overrides[k]) then\n                              Break\n                            else\n                              if Master.Overrides[k].IsPersistent then begin\n                                flProgress('Setting Persistent: ' + Current.Name);\n                                Current.IsPersistent := True;\n                                Break;\n                              end;\n                      end;\n                    end;\n\n                  end;\n\n                end;\n\n              end;\n          end;\n          if j > High(flRecords) then\n            Break;\n        end;\n      Exclude(TwbMainRecord(FileHeader).mrStates, mrsNoUpdateRefs);\n      FileHeader.UpdateRefs;\n    end;\n\n    if wbClampFormID then begin\n      if Supports(FileHeader.ElementByName['Master Files'], IwbContainerElementRef, MasterFiles) then\n        k := MasterFiles.ElementCount\n      else\n        k := 0;\n      for i := Low(flRecords) to High(flRecords) do\n        flRecords[i].ClampFormID(k);\n    end;\n  end else\n    inherited;\nend;\n\nfunction TwbFile.Reached: Boolean;\nbegin\n  Result := False;\nend;\n\nprocedure TwbFile.RemoveInjectedMainRecord(const aRecord: IwbMainRecord);\nvar\n  i: Integer;\nbegin\n  if (Length(flInjectedRecords) > 0) and FindInjectedID(aRecord.FormID, i) then begin\n\n    Assert( (aRecord as IwbElement) = (flInjectedRecords[i] as IwbElement) );\n\n    flInjectedRecords[i] := nil;\n    if i < High(flInjectedRecords) then begin\n      Move(flInjectedRecords[Succ(i)], flInjectedRecords[i], SizeOf(Pointer) * (High(flInjectedRecords) - i));\n      Pointer(flInjectedRecords[High(flInjectedRecords)]) := nil;\n    end;\n    SetLength(flInjectedRecords, Pred(Length(flInjectedRecords)));\n\n  end;\nend;\n\nprocedure TwbFile.RemoveMainRecord(const aRecord: IwbMainRecord);\nvar\n  i      : Integer;\n  Master : IwbMainRecord;\n  FileID : Byte;\nbegin\n  if not Assigned(aRecord) then\n    Exit;\n  if aRecord.FormID <> 0 then begin\n    Assert(flLoadFinished);\n\n    if (Length(flRecords) < 1) or not FindFormID(aRecord.FormID, i) then\n      raise Exception.Create('Can''t remove FormID ['+IntToHex64(aRecord.FormID, 8)+'] from file '+GetName+': FormID not registered');\n\n    flRecords[i] := nil;\n    if i < High(flRecords) then begin\n      Move(flRecords[Succ(i)], flRecords[i], SizeOf(Pointer) * (High(flRecords) - i));\n      Pointer(flRecords[High(flRecords)]) := nil;\n    end;\n    SetLength(flRecords, Pred(Length(flRecords)));\n\n    FileID := aRecord.FormID shr 24;\n    if FileID >= Cardinal(GetMasterCount) then begin\n      {record for this file}\n    end else try\n      Master := GetMasterRecordByFormID(aRecord.FormID, True);\n      if Assigned(Master) and ((Master as IwbElement) <> (aRecord as IwbElement)) then\n        (Master as IwbMainRecordInternal).RemoveOverride(aRecord)\n      else\n        (GetMaster(FileID) as IwbFileInternal).RemoveInjectedMainRecord(aRecord);\n    except\n      on E: Exception do\n        if Assigned(wbProgressCallback) then\n          wbProgressCallback('Error: <'+e.Message+'> while trying to determine master record for ' + aRecord.Name);\n    end;\n  end;\nend;\n\nprocedure TwbFile.Scan;\nvar\n  CurrentPtr  : Pointer;\n  Header      : IwbMainRecord;\n  HEDR        : IwbRecord;\n  MasterFiles : IwbContainerElementRef;\n  Rec         : IwbRecord;\n  i, j        : Integer;\n  SelfRef     : IwbContainerElementRef;\n\n  Groups      : array of IwbGroupRecord;\n  GroupRecord : IwbGroupRecord;\n\n  IsInternal  : Boolean;\nbegin\n  SelfRef := Self as IwbContainerElementRef;\n  flProgress('Start processing');\n\n  CurrentPtr := flView;\n  TwbRecord.CreateForPtr(CurrentPtr, flEndPtr, Self, nil);\n\n  if (GetElementCount <> 1) or not Supports(GetElement(0), IwbMainRecord, Header) then\n    raise Exception.CreateFmt('Unexpected error reading file \"%s\"', [flFileName]);\n\n  if Header.Signature <> wbHeaderSignature then\n    raise Exception.CreateFmt('Expected header signature TES4, found %s in file \"%s\"', [String(Header.Signature), flFileName]);\n\n  if fsOnlyHeader in flStates then\n    Exit;\n\n  MasterFiles := Header.ElementByName['Master Files'] as IwbContainerElementRef;\n  if Assigned(MasterFiles) then\n    for i := 0 to Pred(MasterFiles.ElementCount) do begin\n      Rec := (MasterFiles[i] as IwbContainer).RecordBySignature['MAST'];\n      if not Assigned(Rec) then\n        raise Exception.CreateFmt('Unexpected error reading master list for file \"%s\"', [flFileName]);\n      AddMaster(Rec.Value);\n    end;\n\n  if flCompareTo <> '' then\n    AddMaster(flCompareTo);\n\n  flRecordsCount := 0;\n  HEDR := Header.RecordBySignature['HEDR'];\n  if Assigned(HEDR) then begin\n    SetLength(flRecords, StrToInt(HEDR.Elements[1].Value));\n  end;\n\n  flProgress('Header processed. Expecting ' + IntToStr(Length(flRecords)) + ' records');\n\n  while Cardinal(CurrentPtr) < Cardinal(flEndPtr) do begin\n    Rec := TwbRecord.CreateForPtr(CurrentPtr, flEndPtr, Self, nil);\n    flProgress(Rec.Name + ' processed');\n  end;\n\n  if flRecordsCount < Length(flRecords) then\n    SetLength(flRecords, flRecordsCount);\n\n  flProgress('Building FormID index');\n  if flRecordsCount < Length(flRecords) then\n    SetLength(flRecords, flRecordsCount);\n  SortRecords;\n  flProgress('FormID index built');\n\n  flProgress('Building EditorID index');\n  if flRecordsByEditorIDCount < Length(flRecordsByEditorID) then\n    SetLength(flRecordsByEditorID, flRecordsByEditorIDCount);\n  SortRecordsByEditorID;\n  flProgress('EditorID index built');\n\n  if wbGameMode in [gmFNV, gmTES5, gmSSE, gmFO4] then begin\n    IsInternal := not GetIsEditable and wbBeginInternalEdit(True);\n    try\n      SetLength(Groups, wbGroupOrder.Count);\n      for i := High(cntElements) downto Succ(Low(cntElements)) do begin\n        if not Supports(cntElements[i], IwbGroupRecord, GroupRecord) then begin\n          flProgress('Error: File contains invalid top level record: '+ cntElements[i].Name);\n          Continue;\n        end;\n        if GroupRecord.GroupType <> 0 then begin\n          flProgress('Error: File contains invalid top level group type '+IntToStr(GroupRecord.GroupType)+' for group: '+ cntElements[i].Name);\n          Continue;\n        end;\n        if GroupRecord.SortOrder < 0 then begin\n          flProgress('Error: File contains top level group without known sort order: '+ cntElements[i].Name);\n          Continue;\n        end;\n        if GroupRecord.SortOrder > High(Groups) then begin\n          flProgress('Error: File contains top level group with invalid sort order: '+ cntElements[i].Name);\n          Continue;\n        end;\n        if Assigned(Groups[GroupRecord.SortOrder]) then begin\n          flProgress('Warning: File contains duplicated top level group: ' + cntElements[i].Name);\n          if wbBeginInternalEdit(True) then try\n            if Groups[GroupRecord.SortOrder].ElementCount = 0 then begin\n              Groups[GroupRecord.SortOrder].Remove;\n              Groups[GroupRecord.SortOrder] := nil;\n              Groups[GroupRecord.SortOrder] := GroupRecord;\n            end else begin\n              j := 0;\n              while GroupRecord.ElementCount > 0 do begin\n                Groups[GroupRecord.SortOrder].AddElement(GroupRecord.RemoveElement(0, True));\n                Inc(j);\n              end;\n              (Groups[GroupRecord.SortOrder] as IwbGroupRecordInternal).Sort;\n              (Groups[GroupRecord.SortOrder] as IwbGroupRecordInternal).SetModified(True);\n              flProgress('Merged ' + IntToStr(j) + ' record from duplicated group: ' + cntElements[i].Name);\n              GroupRecord.Remove;\n            end;\n          finally\n            wbEndInternalEdit;\n          end;\n          Continue;\n        end;\n        Groups[GroupRecord.SortOrder] := GroupRecord;\n      end;\n    finally\n      if IsInternal then\n        wbEndInternalEdit;\n    end;\n  end;\n\n  flProgress('Processing completed');\n  flLoadFinished := True;\nend;\n\nprocedure TwbFile.SetHasNoFormID(Value: Boolean);\nbegin\n  if Value or GetIsNotPlugin then\n    Include(flStates, fsHasNoFormID)\n  else\n    Exclude(flStates, fsHasNoFormID);\nend;\n\nprocedure TwbFile.SetIsESM(Value: Boolean);\nvar\n  Header         : IwbMainRecord;\nbegin\n  if GetIsNotPlugin then begin\n    Exit;\n  end;\n\n  if (GetElementCount < 1) or not Supports(GetElement(0), IwbMainRecord, Header) then\n    raise Exception.CreateFmt('Unexpected error reading file \"%s\"', [flFileName]);\n\n  if Value <> Header.IsESM then begin\n    if not IsElementEditable(nil) then\n      raise Exception.Create('File \"'+GetFileName+'\" is not editable');\n\n    Header.IsESM := Value;\n  end;\nend;\n\nprocedure TwbFile.SetIsLocalized(Value: Boolean);\nvar\n  Header         : IwbMainRecord;\nbegin\n  if GetIsNotPlugin then begin\n    Exit;\n  end;\n\n  if (GetElementCount < 1) or not Supports(GetElement(0), IwbMainRecord, Header) then\n    raise Exception.CreateFmt('Unexpected error reading file \"%s\"', [flFileName]);\n\n  if Value <> Header.IsLocalized then begin\n    if not IsElementEditable(nil) then\n      raise Exception.Create('File \"'+GetFileName+'\" is not editable');\n\n    Header.IsLocalized := Value;\n  end;\nend;\n\nprocedure TwbFile.SetLoadOrder(aValue: Integer);\nbegin\n  flLoadOrder := aValue;\nend;\n\nprocedure TwbFile.SetModified(aValue: Boolean);\nbegin\n  if not (esUnsaved in eStates) and not wbIsInternalEdit then\n    flUnsavedSince := Now;\n\n  inherited;\nend;\n\nfunction CompareRecords(Item1, Item2: Pointer): Integer;\nvar\n  FormID1 : Cardinal;\n  FormID2 : Cardinal;\nbegin\n  FormID1 := IwbMainRecord(Item1).FixedFormID;\n  FormID2 := IwbMainRecord(Item2).FixedFormID;\n\n  if FormID1 < FormID2 then\n    Result := -1\n  else if FormID1 = FormID2 then\n    Result := 0\n  else\n    Result := 1;\nend;\n\nfunction CompareOverrides(Item1, Item2: Pointer): Integer;\nvar\n  LoadOrder1 : Cardinal;\n  LoadOrder2 : Cardinal;\nbegin\n  LoadOrder1 := IwbMainRecord(Item1)._File.LoadOrder;\n  LoadOrder2 := IwbMainRecord(Item2)._File.LoadOrder;\n\n  if LoadOrder1 < LoadOrder2 then\n    Result := -1\n  else if LoadOrder1 = LoadOrder2 then\n    Result := 0\n  else\n    Result := 1;\nend;\n\nfunction CompareRecordsByEditorID(Item1, Item2: Pointer): Integer;\nbegin\n  Result := CompareText(IwbMainRecord(Item1).EditorID, IwbMainRecord(Item2).EditorID);\nend;\n\nprocedure TwbFile.SortMasters;\nvar\n  OldList     : TStringList;\n  i, j        : Integer;\n  Old,New     : TBytes;\n  Header      : IwbContainerElementRef;\n  MasterFiles : IwbContainerElementRef;\n  Rec            : IwbRecord;\nbegin\n  if not IsElementEditable(nil) then\n    raise Exception.Create('File \"'+GetFileName+'\" is not editable');\n  if GetIsNotPlugin then\n    Exit;\n\n  if (GetElementCount < 1) or not Supports(GetElement(0), IwbContainerElementRef, Header) then\n    raise Exception.CreateFmt('Unexpected error reading file \"%s\"', [flFileName]);\n\n  if Length(flMasters) > 1 then begin\n    MasterFiles := Header.ElementByName['Master Files'] as IwbContainerElementRef;\n    Assert(Assigned(MasterFiles));\n    Assert(MasterFiles.ElementCount = Length(flMasters));\n    OldList := TStringList.Create;\n    OldList.Sorted := True;\n    OldList.Duplicates := dupError;\n    try\n      for i := Low(flMasters) to High(flMasters) do begin\n        Rec := (MasterFiles[i] as IwbContainer).RecordBySignature['MAST'];\n        Assert(Assigned(Rec));\n        Assert(SameText(Rec.Value, flMasters[i].FileName));\n        OldList.AddObject(flMasters[i].FileName, Pointer(i));\n        MasterFiles[i].SortOrder := i;\n      end;\n\n      wbMergeSort(@flMasters[0], Length(flMasters), CompareLoadOrder);\n\n      Old := nil;\n      New := nil;\n      for i := Low(flMasters) to High(flMasters) do begin\n        j := Integer(OldList.Objects[OldList.IndexOf(flMasters[i].FileName)]);\n        if i <> j then begin\n          MasterFiles[j].SortOrder := i;\n          SetLength(Old, Succ(Length(Old)));\n          Old[High(Old)] := j;\n          SetLength(New, Succ(Length(New)));\n          New[High(New)] := i;\n        end;\n      end;\n      if Length(Old) > 0 then begin\n        (MasterFiles as IwbContainerInternal).SortBySortOrder;\n        MasterIndicesUpdated(Old, New);\n      end;\n    finally\n      OldList.Free;\n    end;\n    SortRecords;\n  end;\nend;\n\ntype\n  TwbRecordSortEntry = record\n    rseFormID     : Cardinal;\n    rseMainRecord : Pointer;\n  end;\n  TwbRecordSortEntries = array of TwbRecordSortEntry;\n\n  PwbRecordSortEntry = ^TwbRecordSortEntry;\n  TwbRecordSortEntryPtrs = array of PwbRecordSortEntry;\n\nfunction CompareSortEntryPtrs(Item1{eax}, Item2{edx}: Pointer): Integer;\nasm\n  {$IFDEF WIN32}\n  mov ecx, [eax + TwbRecordSortEntry.rseFormID]\n  mov edx, [edx + TwbRecordSortEntry.rseFormID]\n  xor eax, eax\n  cmp ecx, edx\n  mov ecx, -1\n  cmovb eax, ecx\n  seta al\n  {$ENDIF WIN32}\n  {$IFDEF WIN64}\n  mov rcx, [rcx + TwbRecordSortEntry.rseFormID]\n  mov rdx, [rdx + TwbRecordSortEntry.rseFormID]\n  xor rax, rax\n  cmp rcx, rdx\n  mov rcx, -1\n  cmovb rax, rcx\n  seta al\n  {$ENDIF WIN64}\nend;\n\nprocedure TwbFile.SortRecords;\nvar\n  SortEntries   : TwbRecordSortEntries;\n  SortEntryPtrs : TwbRecordSortEntryPtrs;\n  i             : Integer;\nbegin\n  i := Length(flRecords);\n  if i > 0 then begin\n    SetLength(SortEntries, i);\n    SetLength(SortEntryPtrs, i);\n    for i := Low(flRecords) to High(flRecords) do begin\n      SortEntries[i].rseFormID := flRecords[i].FixedFormID;\n      SortEntries[i].rseMainRecord := Pointer(flRecords[i]);\n      SortEntryPtrs[i] := @SortEntries[i];\n    end;\n    wbMergeSort(@SortEntryPtrs[0], Length(SortEntryPtrs), CompareSortEntryPtrs);\n    for i := Low(flRecords) to High(flRecords) do\n      Pointer(flRecords[i]) := SortEntryPtrs[i].rseMainRecord;\n  end;\n  flFormIDsSorted := True;\nend;\n\nprocedure TwbFile.SortRecordsByEditorID;\nbegin\n  if Length(flRecordsByEditorID) > 0 then\n    wbMergeSort(@flRecordsByEditorID[0], Length(flRecordsByEditorID), CompareRecordsByEditorID);\nend;\n\nprocedure TwbFile.WriteToStreamInternal(aStream: TStream; aResetModified: Boolean);\nvar\n  SelfRef : IwbContainerElementRef;\nbegin\n  SelfRef := Self as IwbContainerElementRef;\n  PrepareSave;\n  inherited WriteToStreamInternal(aStream, aResetModified);\n\n  Exclude(eStates, esUnsaved);\n  if aResetModified then begin\n    Exclude(eStates, esModified);\n    Exclude(eStates, esInternalModified);\n  end;\nend;\n\ntype\n  TwbUnionFlags = (\n    ufNone,\n    ufArray,\n    ufSortedArray,\n    ufFlags\n  );\n\nfunction ArrayDoInit(const aValueDef: IwbValueDef; const aContainer: IwbContainer; var aBasePtr: Pointer; aEndPtr: Pointer; out SizePrefix: Integer): Boolean; forward;\nprocedure StructDoInit(const aValueDef: IwbValueDef; const aContainer: IwbContainer; var aBasePtr: Pointer; aEndPtr: Pointer); forward;\nfunction UnionDoInit(const aValueDef: IwbValueDef; const aContainer: IwbContainer; var aBasePtr: Pointer; aEndPtr: Pointer): TwbUnionFlags; forward;\nfunction ValueDoInit(const aValueDef: IwbValueDef; const aContainer: IwbContainer; var aBasePtr: Pointer; aEndPtr: Pointer; const aElement: IwbElement): Boolean; forward;\n\n{ TwbContainer }\n\nfunction TwbContainer.Add(const aName: string; aSilent: Boolean): IwbElement;\nbegin\n  Result := nil;\nend;\n\nprocedure TwbContainer.AddElement(const aElement: IwbElement);\nbegin\n  if not Assigned(aElement) then\n    Exit;\n\n  SetLength(cntElements, Succ(Length(cntElements)));\n  cntElements[High(cntElements)] := aElement as IwbElementInternal;\n  cntElements[High(cntElements)].SetContainer(Self);\n  NotifyChanged(eContainer);\nend;\n\nfunction TwbContainer.IndexOf(const aElement: IwbElement): Integer;\nvar\n  i: Integer;\nbegin\n  Result := -1;\n  if Assigned(aElement) then\n    for i := Low(cntElements) to High(cntElements) do\n      if aElement.Equals(cntElements[i]) then begin\n        Result := i;\n        Exit;\n      end;\nend;\n\nprocedure TwbContainer.InformStorage(var aBasePtr: Pointer; aEndPtr: Pointer);\nvar\n  i: Integer;\n  j: Integer;\n  k: Integer;\n  l: Integer;\n  m: Integer;\n  n: Integer;\n  SelfRef : IwbContainerElementRef;\nbegin\n  SelfRef := Self as IwbContainerElementRef;\n\n  DoInit;\n  m := Low(Integer);\n  for l := Low(cntElements) to High(cntElements) do\n    if cntElements[l].MemoryOrder > m then\n      m := cntElements[l].MemoryOrder;\n  for l := Low(cntElements) to High(cntElements) do\n    if cntElements[l].MemoryOrder = Low(Integer) then begin\n      cntElements[l].MemoryOrder := m + 1;\n      Inc(m);\n    end;\n  m := Low(Integer);\n  k := Low(Integer);\n  for i := Low(cntElements) to High(cntElements) do begin\n    n := k;\n    j := High(Integer);\n    for l := Low(cntElements) to High(cntElements) do begin\n      if (m<cntElements[l].MemoryOrder) and (cntElements[l].MemoryOrder < j) then begin\n        k := l;\n        j := cntElements[l].MemoryOrder;\n      end;\n    end;\n    Assert(k <= High(cntElements));\n    Assert(k >= Low(cntElements));\n    Assert(k <> n);\n    m := cntElements[k].MemoryOrder;\n    cntElements[k].InformStorage(aBasePtr, aEndPtr);\n  end;\nend;\n\nprocedure TwbContainer.InsertElement(aPosition: Integer; const aElement: IwbElement);\nbegin\n  if not Assigned(aElement) then\n    Exit;\n\n  SetLength(cntElements, Succ(Length(cntElements)));\n\n  if aPosition < Low(cntElements) then\n    aPosition := Low(cntElements)\n  else if aPosition > High(cntElements) then\n    aPosition := High(cntElements);\n\n  if aPosition < High(cntElements) then begin\n    Move(cntElements[aPosition], cntElements[Succ(aPosition)], (High(cntElements) - aPosition) * SizeOf(Pointer));\n    Pointer(cntElements[aPosition]) := nil;\n  end;\n\n  cntElements[aPosition] := aElement as IwbElementInternal;\n  cntElements[aPosition].SetContainer(Self);\n  NotifyChanged(eContainer);\nend;\n\nfunction TwbContainer.IsElementEditable(const aElement: IwbElement): Boolean;\nbegin\n  if Assigned(eContainer) then\n    Result := IwbContainer(eContainer).IsElementEditable(Self)\n  else\n    Result := True;\nend;\n\nfunction TwbContainer.IsElementRemoveable(const aElement: IwbElement): Boolean;\nbegin\n  Result := False;\nend;\n\nfunction LockedInc(var Target: Integer): Integer; register;\nasm\n  {$IFDEF WIN32}\n        mov     ecx, eax\n        mov     eax, 1\n   lock xadd    [ecx], eax\n        inc     eax\n  {$ENDIF WIN32}\n  {$IFDEF WIN64}\n        mov     rax, 1\n   lock xadd    [rcx], rax\n        inc     rax\n  {$ENDIF WIN64}\nend;\n\nfunction LockedDec(var Target: Integer): Integer; register;\nasm\n  {$IFDEF WIN32}\n        mov     ecx, eax\n        mov     eax, -1\n   lock xadd    [ecx], eax\n        dec     eax\n  {$ENDIF WIN32}\n  {$IFDEF WIN64}\n        mov     rax, -1\n   lock xadd    [rcx], rax\n        dec     rax\n  {$ENDIF WIN64}\nend;\n\nprocedure TwbContainer.AfterConstruction;\nbegin\n  inherited;\n  {$IFDEF WIN64}\n  LockedDec(cntElementRefs);\n  {$ENDIF WIN64}\n  {$IFDEF WIN32}\n  asm\n         mov eax, [Self]\n    lock dec dword ptr [eax + cntElementRefs]\n  end;\n  {$ENDIF WIN32}\nend;\n\nfunction TwbContainer.AssignInternal(aIndex: Integer; const aElement: IwbElement; aOnlySK: Boolean): IwbElement;\nvar\n  Container  : IwbContainer;\n  uContainer : IwbContainerElementRef;\n  sElement   : IwbElement;\n  BasePtr    : Pointer;\n  i, j       : Integer;\n  SelfRef    : IwbContainerElementRef;\n  ValueDef   : IwbValueDef;\n  UnionDef   : IwbUnionDef;\n  HasMap     : Boolean;\n  StructDef  : IwbStructDef;\n  OurSize    : Integer;\nbegin\n  Result := nil;\n\n  if not wbEditAllowed then\n    raise Exception.Create(GetName + ' can not be assigned.');\n\n  SelfRef := Self as IwbContainerElementRef;\n\n  if Assigned(eContainer) then\n    if not IwbContainer(eContainer).IsElementEditable(Self) then\n      Exit;\n\n  DoInit;\n\n  if inherited CanAssignInternal(aIndex, aElement, False) then\n    Result := inherited AssignInternal(aIndex, aElement, aOnlySK);\n\n  if (aIndex = Low(Integer)) and (Length(cntElements) > 0) then begin\n\n    if Supports(aElement, IwbContainer, Container) and (Container.ElementCount = GetElementCount) then begin\n\n      ValueDef := GetValueDef;\n      if (ValueDef = aElement.ValueDef) or\n        ( Assigned(ValueDef) and\n          (\n            ValueDef.Equals(aElement.ValueDef) or\n            ValueDef.CanAssign(Self, aIndex, aElement.ValueDef)\n          )\n        ) then begin\n            HasMap := Length(cntElementsMap) > 0;\n            if HasMap then begin\n              Assert(Length(cntElements) = Length(cntElementsMap));\n              //if the elements haven't got their space allocated yet, we need\n              //to make sure they are first written to in the \"on disk\" order\n              //before copying in the mapped order below\n              SetToDefault;\n            end;\n            for i := Low(cntElements) to High(cntElements) do begin\n              if HasMap then\n                j := cntElementsMap[i]\n              else\n                j := i;\n\n              // if we have a union, we cannot progress until the union has been resolved and its cntElements is populated\n              sElement := Container.Elements[i];\n              if (sElement.ElementType = etUnion) and\n                 Supports(cntElements[j], IwbContainerElementRef, uContainer) and\n                 Supports(uContainer.GetValueDef, IwbUnionDef, UnionDef) then begin\n                if (uContainer.ElementCount = 1) then begin // At this point it is usually the default choice set by default\n                  uContainer.RemoveElement(0);\n                end;\n                if (uContainer.ElementCount = 0) then begin\n                  BasePtr := nil;\n                  UnionDoInit(UnionDef, uContainer as IwbContainer, BasePtr, nil);\n                end;\n              end;\n              if (not aOnlySK or GetIsInSK(cntElements[j].SortOrder)) then begin\n                if cntElements[j].CanAssign(Low(Integer), sElement, False) then\n                  cntElements[j].Assign(Low(Integer), sElement, aOnlySK)\n                else if Supports(sElement.ValueDef, IwbEmptyDef) then begin\n                  // this might be a case the source begin a struct\n                  // with \"OptionalFromElement\" empty elements at the end\n                  If Supports(Container.ResolvedValueDef, IwbStructDef, StructDef) then\n                    if StructDef.OptionalFromElement >= 0 then\n                      if StructDef.OptionalFromElement <= j then begin\n                        //yes it is\n                        Assert(not HasMap); //this would be really tricky to handle with mapped elements...\n                        Assert(Self is TwbDataContainer); //if the source is a struct and is assignable to us, this should be guaranteed\n                        OurSize := 0;\n                        for j := Low(cntElements) to Pred(i) do\n                          Inc(OurSize, cntElements[j].DataSize);\n                        if GetDataSize > OurSize then\n                          with TwbDataContainer(Self) do begin\n                            UpdateStorageFromElements;\n                            Assert(Length(dcDataStorage) >= OurSize);\n                            Assert(not (dcfStorageInvalid in dcFlags));\n                            Reset;\n                            SetLength(dcDataStorage, OurSize);\n                            if OurSize > 0 then begin\n                              dcDataBasePtr := @dcDataStorage[Low(dcDataStorage)];\n                              dcDataEndPtr := Pointer( Cardinal(dcDataBasePtr) + OurSize );\n                            end else begin\n                              dcDataBasePtr := @EmptyPtr;\n                              dcDataEndPtr := @EmptyPtr;\n                            end;\n                            Init;\n                          end;\n                        Exit;\n                      end;\n                end;\n              end;\n            end;\n        end;\n    end;\n\n  end;\nend;\n\nprocedure TwbContainer.Bar;\nbegin\n\nend;\n\nprocedure TwbContainer.BeforeDestruction;\nbegin\n  Assert(cntElementRefs = 0);\n  inherited BeforeDestruction;\n  {$IFDEF WIN64}\n  LockedInc(cntElementRefs);\n  {$ENDIF WIN64}\n  {$IFDEF WIN32}\n  asm\n         mov eax, [Self]\n    lock inc dword ptr [eax + cntElementRefs]\n  end;\n  {$ENDIF WIN32}\nend;\n\nprocedure TwbContainer.BuildRef;\nvar\n  i: Integer;\n  SelfRef : IwbContainerElementRef;\nbegin\n  SelfRef := Self as IwbContainerElementRef;\n  DoInit;\n  Include(cntStates, csRefsBuild);\n  for i := Low(cntElements) to High(cntElements) do\n    if cntElements[i].CanContainFormIDs then\n      cntElements[i].BuildRef;\nend;\n\nfunction TwbContainer.CanAssignInternal(aIndex: Integer; const aElement: IwbElement; aCheckDontShow: Boolean): Boolean;\nvar\n  Container : IwbContainer;\n  i         : Integer;\n  SelfRef   : IwbContainerElementRef;\n  ValueDef  : IwbValueDef;\nbegin\n  Result := False;\n  if not wbEditAllowed then\n    Exit;\n\n  if not Assigned(aElement) then\n    Exit;\n\n  if Assigned(eContainer) then\n    if not IwbContainer(eContainer).IsElementEditable(Self) then\n      Exit;\n\n  SelfRef := Self as IwbContainerElementRef;\n\n  Result := inherited CanAssignInternal(aIndex, aElement, aCheckDontShow);\n\n  DoInit;\n\n  if not Result and (aIndex = Low(Integer)) and (Length(cntElements) > 0) then begin\n\n    if Supports(aElement, IwbContainer, Container) and (Container.ElementCount = GetElementCount) then begin\n      ValueDef := GetValueDef;\n      Result := (ValueDef = aElement.ValueDef) or\n        ( Assigned(ValueDef) and\n          (\n            ValueDef.Equals(aElement.ValueDef) or\n            ValueDef.CanAssign(Self, aIndex, aElement.ValueDef)\n          )\n        );\n    end;\n\n    if Result then\n      for i := Low(cntElements) to High(cntElements) do begin\n        Result :=\n          (cntElements[i].ConflictPriority = cpIgnore) or\n          (Container.Elements[i].ConflictPriority = cpIgnore) or\n          cntElements[i].CanAssign(Low(Integer), Container.Elements[i], aCheckDontShow);\n        if not Result then\n          Exit;\n      end;\n  end;\nend;\n\nfunction TwbContainer.CanChangeElementMember(const aElement: IwbElement): Boolean;\nvar\n  SubRecordArrayDef : IwbSubRecordArrayDef;\nbegin\n  Result := Supports(GetDef, IwbSubRecordArrayDef, SubRecordArrayDef) and\n    Supports(SubRecordArrayDef.Element, IwbSubRecordUnionDef) and\n    IsElementEditable(Self);\nend;\n\nfunction TwbContainer.CanMoveElement: Boolean;\nbegin\n  Result := False;\nend;\n\nfunction TwbContainer.CanMoveElementDown(const aElement: IwbElement): Boolean;\nvar\n  i: Integer;\nbegin\n  Result := False;\n  if Assigned(eContainer) and not IwbContainer(eContainer).IsElementEditable(Self) then\n    Exit;\n  if not CanMoveElement then\n    Exit;\n  if Length(cntElements) < 2 then\n    Exit;\n  if cntElements[High(cntElements)].Equals(aElement) then\n    Exit;\n  Result := True;\n  for i := 0 to Pred(High(cntElements)) do\n    if cntElements[i].Equals(aElement) then\n      Exit;\n  Result := False;\nend;\n\nfunction TwbContainer.CanMoveElementUp(const aElement: IwbElement): Boolean;\nvar\n  i: Integer;\nbegin\n  Result := False;\n  if Assigned(eContainer) and not IwbContainer(eContainer).IsElementEditable(Self) then\n    Exit;\n  if not CanMoveElement then\n    Exit;\n  if Length(cntElements) < 2 then\n    Exit;\n  if cntElements[0].Equals(aElement) then\n    Exit;\n  Result := True;\n  for i := 1 to High(cntElements) do\n    if cntElements[i].Equals(aElement) then\n      Exit;\n  Result := False;\nend;\n\nfunction TwbContainer.CanElementReset: Boolean;\nbegin\n  if Assigned(eContainer) then\n    Result := IwbContainer(eContainer).CanElementReset\n  else\n    Result := True;\nend;\n\nfunction TwbContainer.CompareExchangeFormID(aOldFormID, aNewFormID: Cardinal): Boolean;\nvar\n  i: Integer;\n  SelfRef : IwbContainerElementRef;\nbegin\n  SelfRef := Self as IwbContainerElementRef;\n  DoInit;\n  Result := False;\n  for i := Low(cntElements) to High(cntElements) do\n    if cntElements[i].CanContainFormIDs then\n      Result := cntElements[i].CompareExchangeFormID(aOldFormID, aNewFormID) or Result;\nend;\n\nprocedure TwbContainer.CreatedEmpty;\nbegin\n  Include(cntStates, csAsCreatedEmpty);\nend;\n\nprocedure TwbContainer.Init;\nbegin\n  { can be overriden }\nend;\n\ndestructor TwbContainer.Destroy;\nbegin\n  ReleaseElements;\n  inherited;\nend;\n\nprocedure TwbContainer.DoInit;\nvar\n  i        : Integer;\n  ValueDef : IwbValueDef;\n  KAC      : PwbKeepAliveContext;\nbegin\n  if esDestroying in eStates then\n    Exit;\n  if csInit in cntStates then\n    Exit;\n  if [csInitializing, csReseting] * cntStates <> [] then\n    Exit;\n  Include(cntStates, csInitializing);\n  try\n    cntElementsMap := nil;\n    Include(cntStates, csInit);\n    Include(cntStates, csInitOnce);\n    Init;\n    Include(cntStates, csInitDone);\n    for i := Low(cntElements) to High(cntElements) do\n      cntElements[i].MemoryOrder := i;\n    ValueDef := GetValueDef;\n    if Assigned(ValueDef) then\n      cntElementsMap := ValueDef.GetElementMap;\n    if not wbSpeedOverMemory then\n      if not (GetElementType in [etMainRecord, etGroupRecord]) then\n        if not Assigned(cntKeepAliveNext) and (Length(cntElements) > 0) then begin\n          KAC := wbKeepAliveContext;\n          if Assigned(KAC) then begin\n            cntKeepAliveNext := KAC.kacHead;\n            KAC.kacHead := Self as IwbContainerElementRef;\n          end;\n        end;\n  finally\n    Exclude(cntStates, csInitializing);\n  end;\nend;\n\nprocedure TwbContainer.DoReset(aForce: Boolean);\nbegin\n  if not aForce then begin\n    if Length(cntElements) = 0 then\n      Exit;\n    if not (csInit in cntStates) then\n      Exit;\n    if esModified in eStates then\n      Exit;\n    if cntElementRefs > 0 then\n      Exit;\n    if not CanElementReset then\n      Exit;\n  end;\n\n  if [csInitializing, csReseting] * cntStates <> [] then\n    Exit;\n\n  {$IFDEF WIN64}\n  LockedInc(cntElementRefs);\n  {$ENDIF WIN64}\n  {$IFDEF WIN32}\n  asm\n         mov eax, [Self]\n    lock inc dword ptr [eax + cntElementRefs]\n  end;\n  {$ENDIF WIN32}\n  try\n    Include(cntStates, csReseting);\n    Exclude(cntStates, csInitDone);\n    Reset;\n    cntElementsMap := nil;\n  finally\n    Exclude(cntStates, csReseting);\n    {$IFDEF WIN64}\n    LockedDec(cntElementRefs);\n    {$ENDIF WIN64}\n    {$IFDEF WIN32}\n    asm\n           mov eax, [Self]\n      lock dec dword ptr [eax + cntElementRefs]\n    end;\n    {$ENDIF WIN32}\n    Exclude(cntStates, csInit);\n  end;\nend;\n\n{$D-}\nfunction TwbContainer.ElementAddRef: Integer;\nbegin\n  {$IFDEF WIN64}\n  LockedInc(cntElementRefs);\n  {$ENDIF WIN64}\n  {$IFDEF WIN32}\n  asm\n         mov eax, [Self]\n    lock inc dword ptr [eax + cntElementRefs]\n  end;\n  {$ENDIF WIN32}\n  Result := inherited _AddRef;\nend;\n{$D+}\n\nprocedure TwbContainer.ElementChanged(const aElement: IwbElement; aContainer: Pointer);\nbegin\n  NotifyChanged(aContainer);\nend;\n\n{$D-}\nfunction TwbContainer.ElementRelease: Integer;\nlabel\n  Skip;\nbegin\n  {$IFDEF WIN64}\n  if LockedDec(cntElementRefs) = 0 then\n  {$ENDIF WIN64}\n  {$IFDEF WIN32}\n  asm\n         mov  eax, -1\n         mov  ecx, [Self]\n    lock xadd dword ptr [ecx + cntElementRefs], eax\n         cmp  eax, 1\n         jne  Skip\n  end;\n  {$ENDIF WIN32}\n  DoReset(False);\nSkip:\n\n  Result := inherited _Release;\nend;\n{$D+}\n\nfunction TwbContainer.FindBySortKey(const aSortKey: string; aExtended: Boolean; out aIndex: Integer): Boolean;\nvar\n  L, H, I, C: Integer;\nbegin\n  Result := False;\n\n  L := Low(cntElements);\n  H := High(cntElements);\n  while L <= H do begin\n    I := (L + H) shr 1;\n    C := CompareStr(cntElements[I].SortKey[aExtended], aSortKey);\n    if C < 0 then\n      L := I + 1\n    else begin\n      H := I - 1;\n      if C = 0 then begin\n        Result := True;\n        L := I;\n      end;\n    end;\n  end;\n  aIndex := L;\nend;\n\nprocedure TwbContainer.FindUsedMasters(aMasters: PwbUsedMasters);\nvar\n  i       : Integer;\n  SelfRef : IwbContainerElementRef;\nbegin\n  inherited;\n  SelfRef := Self as IwbContainerElementRef;\n  DoInit;\n  for i := Low(cntElements) to High(cntElements) do\n    if cntElements[i].CanContainFormIDs then\n      cntElements[i].FindUsedMasters(aMasters);\nend;\n\nprocedure TwbContainer.FreeInstance;\nbegin\n  Assert(cntElementRefs = 1);\n  inherited;\nend;\n\nfunction TwbContainer.GetAdditionalElementCount: Integer;\nbegin\n  Result := 0;\nend;\n\nfunction TwbContainer.GetAddList: TDynStrings;\nbegin\n  Result := nil;\nend;\n\nfunction TwbContainer.GetContainerStates: TwbContainerStates;\nbegin\n  Result := cntStates;\nend;\n\nfunction TwbContainer.GetDataSize: Integer;\nvar\n  i             : Integer;\n  SelfRef       : IwbContainerElementRef;\n  DataContainer : IwbDataContainer;\nbegin\n  SelfRef := Self as IwbContainerElementRef;\n  Result := 0;\n  DoInit;\n  for i := Low(cntElements) to High(cntElements) do begin\n    if Supports(cntElements[i], IwbDataContainer, DataContainer) and DataContainer.DontSave then\n      Continue;\n\n    Inc(Result, cntElements[i].DataSize);\n  end;\nend;\n\nfunction TwbContainer.GetElement(aIndex: Integer): IwbElement;\nvar\n  SelfRef : IwbContainerElementRef;\nbegin\n  SelfRef := Self as IwbContainerElementRef;\n\n  DoInit;\n  if not Assigned(cntElements) or (aIndex>=Length(cntElements)) then begin // Using the wrong contained array at the time\n    if wbMoreInfoForIndex and (DebugHook <> 0) and Assigned(wbProgressCallback) then\n      wbProgressCallback('Debugger: ['+ IwbElement(Self).Path +'] Index ' + IntToStr(aIndex) + ' greater than max '+\n        IntToStr(Length(cntElements)-1));\n    Result := nil\n  end else begin\n    if Length(cntElementsMap) = Length(cntElements) then\n      aIndex := cntElementsMap[aIndex];\n    Result := IInterface(cntElements[aIndex]) as IwbElement;\n  end;\nend;\n\nfunction TwbContainer.GetElementByName(const aName: string): IwbElement;\nvar\n  i: integer;\n  SelfRef : IwbContainerElementRef;\nbegin\n  SelfRef := Self as IwbContainerElementRef;\n  DoInit;\n  Result := nil;\n  for i := Low(cntElements) to High(cntElements) do\n    if SameText(cntElements[i].Name, aName) then begin\n      Result := IInterface(cntElements[i]) as IwbElement;\n      Exit;\n    end;\n  for i := Low(cntElements) to High(cntElements) do\n    if SameText(cntElements[i].DisplayName, aName) then begin\n      Result := IInterface(cntElements[i]) as IwbElement;\n      Exit;\n    end;\nend;\n\nfunction TwbContainer.GetElementByPath(const aPath: string): IwbElement;\nvar\n  SelfRef   : IwbContainerElementRef;\n  Element   : IwbElement;\n  Path      : string;\n  Container : IwbContainerElementRef;\nbegin\n  Result := nil;\n\n  SelfRef := Self as IwbContainerElementRef;\n  DoInit;\n\n  Element := ResolveElementName(aPath, Path);\n  if not Assigned(Element) then\n    Exit;\n\n  if Path = '' then\n    Result := Element\n  else if Supports(Element, IwbContainerElementRef, Container) then\n    Result := Container.ElementByPath[Path];\nend;\n\nfunction TwbContainer.GetElementByMemoryOrder(aSortOrder: Integer): IwbElement;\nvar\n  i: integer;\n  SelfRef : IwbContainerElementRef;\nbegin\n  SelfRef := Self as IwbContainerElementRef;\n  DoInit;\n  Dec(aSortOrder, GetAdditionalElementCount);\n  Result := nil;\n  for i := Low(cntElements) to High(cntElements) do\n    if cntElements[i].MemoryOrder = aSortOrder then begin\n      Result := IInterface(cntElements[i]) as IwbElement;\n      Exit;\n    end;\nend;\n\nfunction TwbContainer.GetElementBySignature(const aSignature: TwbSignature): IwbElement;\nvar\n  i: integer;\n  HasSignature: IwbHasSignature;\n  SelfRef : IwbContainerElementRef;\nbegin\n  SelfRef := Self as IwbContainerElementRef;\n  DoInit;\n  Result := nil;\n  for i := Low(cntElements) to High(cntElements) do\n    if Supports(cntElements[i], IwbHasSignature, HasSignature) then\n      if HasSignature.Signature = aSignature then begin\n        Result := HasSignature;\n        Exit;\n      end;\nend;\n\nfunction TwbContainer.GetElementBySortOrder(aSortOrder: Integer): IwbElement;\nvar\n  i: integer;\n  SelfRef : IwbContainerElementRef;\nbegin\n  SelfRef := Self as IwbContainerElementRef;\n  DoInit;\n  Dec(aSortOrder, GetAdditionalElementCount);\n  Result := nil;\n  for i := Low(cntElements) to High(cntElements) do\n    if cntElements[i].SortOrder = aSortOrder then begin\n      Result := IInterface(cntElements[i]) as IwbElement;\n      Exit;\n    end;\nend;\n\nfunction TwbContainer.GetElementCount: Integer;\nvar\n  SelfRef : IwbContainerElementRef;\nbegin\n  SelfRef := Self as IwbContainerElementRef;\n  DoInit;\n  Result := Length(cntElements);\nend;\n\nfunction TwbContainer.GetElementEditValue(const aName: string): string;\nvar\n  SelfRef   : IwbContainerElementRef;\n  Element   : IwbElement;\n  Name      : string;\n  Container : IwbContainerElementRef;\nbegin\n  Result := '';\n\n  SelfRef := Self as IwbContainerElementRef;\n  DoInit;\n\n  Element := ResolveElementName(aName, Name);\n  if not Assigned(Element) then\n    Exit;\n\n  if Name = '' then\n    Result := Element.EditValue\n  else if Supports(Element, IwbContainerElementRef, Container) then\n    Result := Container.ElementEditValues[Name];\nend;\n\nfunction TwbContainer.GetElementExists(const aName: string): Boolean;\nvar\n  SelfRef   : IwbContainerElementRef;\n  Element   : IwbElement;\n  Name      : string;\n  Container : IwbContainerElementRef;\nbegin\n  Result := False;\n\n  SelfRef := Self as IwbContainerElementRef;\n  DoInit;\n\n  Element := ResolveElementName(aName, Name);\n  if not Assigned(Element) then\n    Exit;\n\n  if Name = '' then\n    Result := True\n  else if Supports(Element, IwbContainerElementRef, Container) then\n    Result := Container.ElementExists[Name];\nend;\n\nfunction TwbContainer.GetElementLinksTo(const aName: string): IwbElement;\nvar\n  SelfRef   : IwbContainerElementRef;\n  Element   : IwbElement;\n  Name      : string;\n  Container : IwbContainerElementRef;\nbegin\n  Result := nil;\n\n  SelfRef := Self as IwbContainerElementRef;\n  DoInit;\n\n  Element := ResolveElementName(aName, Name);\n  if not Assigned(Element) then\n    Exit;\n\n  if Name = '' then\n    Result := Element.LinksTo\n  else if Supports(Element, IwbContainerElementRef, Container) then\n    Result := Container.ElementLinksTo[Name];\nend;\n\nfunction TwbContainer.GetElementNativeValue(const aName: string): Variant;\nvar\n  SelfRef   : IwbContainerElementRef;\n  Element   : IwbElement;\n  Name      : string;\n  Container : IwbContainerElementRef;\nbegin\n  VarClear(Result);\n\n  SelfRef := Self as IwbContainerElementRef;\n  DoInit;\n\n  Element := ResolveElementName(aName, Name);\n  if not Assigned(Element) then\n    Exit;\n\n  if Name = '' then\n    Result := Element.NativeValue\n  else if Supports(Element, IwbContainerElementRef, Container) then\n    Result := Container.ElementNativeValues[Name];\nend;\n\nfunction TwbContainer.GetElementSortKey(const aName: string;\n  aExtended: Boolean): string;\nvar\n  SelfRef   : IwbContainerElementRef;\n  Element   : IwbElement;\n  Name      : string;\n  Container : IwbContainerElementRef;\nbegin\n  Result := '';\n\n  SelfRef := Self as IwbContainerElementRef;\n  DoInit;\n\n  Element := ResolveElementName(aName, Name);\n  if not Assigned(Element) then\n    Exit;\n\n  if Name = '' then\n    Result := Element.SortKey[aExtended]\n  else if Supports(Element, IwbContainerElementRef, Container) then\n    Result := Container.ElementSortKeys[Name, aExtended];\nend;\n\nfunction TwbContainer.GetElementValue(const aName: string): string;\nvar\n  SelfRef   : IwbContainerElementRef;\n  Element   : IwbElement;\n  Name      : string;\n  Container : IwbContainerElementRef;\nbegin\n  Result := '';\n\n  SelfRef := Self as IwbContainerElementRef;\n  DoInit;\n\n  Element := ResolveElementName(aName, Name);\n  if not Assigned(Element) then\n    Exit;\n\n  if Name = '' then\n    Result := Element.Value\n  else if Supports(Element, IwbContainerElementRef, Container) then\n    Result := Container.ElementValues[Name];\nend;\n\nfunction TwbContainer.GetIsInSK(aIndex: Integer): Boolean;\nbegin\n  Result := False;\nend;\n\nfunction TwbContainer.GetRecordBySignature(const aSignature: TwbSignature): IwbRecord;\nvar\n  i: integer;\n  lRecord: IwbRecord;\n  SelfRef : IwbContainerElementRef;\nbegin\n  SelfRef := Self as IwbContainerElementRef;\n  DoInit;\n  Result := nil;\n  for i := Low(cntElements) to High(cntElements) do\n    if Supports(cntElements[i], IwbRecord, lRecord) then\n      if lRecord.Signature = aSignature then begin\n        Result := lRecord;\n        Exit;\n      end;\nend;\n\nfunction TwbContainer.GetCountedRecordCount: Cardinal;\nvar\n  i: Integer;\n  SelfRef : IwbContainerElementRef;\nbegin\n  SelfRef := Self as IwbContainerElementRef;\n  Result := 0;\n  DoInit;\n  for i := Low(cntElements) to High(cntElements) do\n    Inc(Result, cntElements[i].GetCountedRecordCount);\nend;\n\nfunction TwbContainer.GetSortKeyInternal(aExtended: Boolean): string;\nvar\n  i: Integer;\n  SelfRef : IwbContainerElementRef;\nbegin\n  SelfRef := Self as IwbContainerElementRef;\n  DoInit;\n  Result := '';\n  for i := Low(cntElements) to High(cntElements) do begin\n    Result := Result + cntElements[i].SortKey[aExtended];\n    if i < High(cntElements) then\n      Result := Result + '|';\n  end;\nend;\n\nfunction TwbContainer.HasErrors: Boolean;\nvar\n  SelfRef : IwbContainerElementRef;\n  i       : Integer;\nbegin\n  SelfRef := Self as IwbContainerElementRef;\n  DoInit;\n\n  Result := inherited HasErrors;\n  if Result then\n    Exit;\n\n  for i := Low(cntElements) to High(cntElements) do begin\n    Result := cntElements[i].HasErrors;\n    if Result then\n      Exit;\n  end;\nend;\n\nfunction TwbContainer.LastElement: IwbElement;\nvar\n  SelfRef : IwbContainerElementRef;\nbegin\n  SelfRef := Self as IwbContainerElementRef;\n  DoInit;\n  if Length(cntElements) > 0 then\n    Result := IInterface(cntElements[High(cntElements)]) as IwbElement\n  else\n    Result := nil;\nend;\n\nprocedure TwbContainer.MarkModifiedRecursive;\nvar\n  i: Integer;\n  SelfRef : IwbContainerElementRef;\nbegin\n  SelfRef := Self as IwbContainerElementRef;\n  DoInit;\n  for i := Low(cntElements) to High(cntElements) do\n    cntElements[i].MarkModifiedRecursive;\n  inherited;\nend;\n\nprocedure TwbContainer.MasterCountUpdated(aOld, aNew: Byte);\nvar\n  i: Integer;\n  SelfRef : IwbContainerElementRef;\nbegin\n  SelfRef := Self as IwbContainerElementRef;\n  DoInit;\n  for i := Low(cntElements) to High(cntElements) do\n    if cntElements[i].CanContainFormIDs then\n      cntElements[i].MasterCountUpdated(aOld, aNew);\nend;\n\nprocedure TwbContainer.MasterIndicesUpdated(const aOld, aNew: TBytes);\nvar\n  i       : Integer;\n  SelfRef : IwbContainerElementRef;\nbegin\n  inherited;\n  SelfRef := Self as IwbContainerElementRef;\n  DoInit;\n  for i := Low(cntElements) to High(cntElements) do\n    if cntElements[i].CanContainFormIDs then\n      cntElements[i].MasterIndicesUpdated(aOld, aNew);\nend;\n\nprocedure TwbContainer.MergeStorageInternal(var aBasePtr: Pointer; aEndPtr: Pointer);\nvar\n  i: Integer;\n  j: Integer;\n  k: Integer;\n  l: Integer;\n  m: Integer;\n  n: Integer;\n  SelfRef : IwbContainerElementRef;\nbegin\n  SelfRef := Self as IwbContainerElementRef;\n\n  DoInit;\n  If GetElementType in SortedElementTypes then\n    begin\n      m := Low(Integer);\n      for l := Low(cntElements) to High(cntElements) do\n        if (cntElements[l].MemoryOrder > m) and not Supports(cntElements[l], IwbStringListTerminator) then\n          m := cntElements[l].MemoryOrder;\n      for l := Low(cntElements) to High(cntElements) do\n        if cntElements[l].MemoryOrder = Low(Integer) then begin\n          cntElements[l].MemoryOrder := m + 1;\n          Inc(m);\n        end;\n      for l := Low(cntElements) to High(cntElements) do\n        if Supports(cntElements[l], IwbStringListTerminator) then\n          cntElements[l].MemoryOrder := m+1;\n      m := Low(Integer);\n      k := Low(Integer);\n      for i := Low(cntElements) to High(cntElements) do begin\n        n := k;\n        j := High(Integer);\n        for l := Low(cntElements) to High(cntElements) do begin\n          if (m<cntElements[l].MemoryOrder) and (cntElements[l].MemoryOrder < j) then begin\n            k := l;\n            j := cntElements[l].MemoryOrder;\n          end;\n        end;\n        Assert(k <= High(cntElements));\n        Assert(k >= Low(cntElements));\n        if k = n then\n          Assert(k <> n);\n        m := cntElements[k].MemoryOrder;\n        cntElements[k].MergeStorage(aBasePtr, aEndPtr);\n      end;\n    end\n  else\n    for l := Low(cntElements) to High(cntElements) do\n      cntElements[l].MergeStorage(aBasePtr, aEndPtr);\nend;\n\nprocedure TwbContainer.MoveElementDown(const aElement: IwbElement);\nvar\n  i: Integer;\nbegin\n  if Assigned(eContainer) and not IwbContainer(eContainer).IsElementEditable(Self) then\n    Exit;\n  if not CanMoveElement then\n    Exit;\n  if Length(cntElements) < 2 then\n    Exit;\n  if cntElements[High(cntElements)].Equals(aElement) then\n    Exit;\n  for i := 0 to Pred(High(cntElements)) do\n    if cntElements[i].Equals(aElement) then begin\n      SetModified(True);\n      InvalidateStorage;\n      cntElements[i] := cntElements[Succ(i)];\n      cntElements[Succ(i)] := aElement as IwbElementInternal;\n      Exit;\n    end;\nend;\n\nprocedure TwbContainer.MoveElementUp(const aElement: IwbElement);\nvar\n  i: Integer;\nbegin\n  if Assigned(eContainer) and not IwbContainer(eContainer).IsElementEditable(Self) then\n    Exit;\n  if not CanMoveElement then\n    Exit;\n  if Length(cntElements) < 2 then\n    Exit;\n  if cntElements[0].Equals(aElement) then\n    Exit;\n  for i := 1 to High(cntElements) do\n    if cntElements[i].Equals(aElement) then begin\n      SetModified(True);\n      InvalidateStorage;\n      cntElements[i] := cntElements[Pred(i)];\n      cntElements[Pred(i)] := aElement as IwbElementInternal;\n      Exit;\n    end;\nend;\n\nclass function TwbContainer.NewInstance: TObject;\nbegin\n  Result := inherited NewInstance;\n  TwbContainer(Result).cntElementRefs := 1;\nend;\n\nprocedure TwbContainer.NextElementMember(const aElement: IwbElement);\nvar\n  ElementIndex      : Integer;\n  ElementDef        : IwbRecordMemberDef;\n  Element           : IwbElement;\n  Container         : IwbContainer;\n  SubRecordArrayDef : IwbSubRecordArrayDef;\n  SubRecordUnionDef : IwbSubRecordUnionDef;\n  RecordDef         : IwbRecordDef;\n  i                 : Integer;\nbegin\n  if Assigned(eContainer) and not IwbContainer(eContainer).IsElementEditable(Self) then\n    Exit;\n  if not CanChangeElementMember(aElement) then\n    Exit;\n  if not Supports(GetDef, IwbSubRecordArrayDef, SubRecordArrayDef) or\n     not Supports(SubRecordArrayDef.Element, IwbSubRecordUnionDef, SubRecordUnionDef) then\n    Exit;\n  if not Supports(SubRecordArrayDef.Element, IwbRecordDef, RecordDef) then\n    Exit;\n  if Supports(aElement.Container, IwbContainer, Container) then begin\n    for i := 0 to Pred(RecordDef.MemberCount) do\n      if RecordDef.Members[i].Equals(aElement.Def) then\n        break;\n    if i < RecordDef.MemberCount then begin\n      RemoveElement(aElement);\n      ElementIndex := (i + 1) mod RecordDef.MemberCount;\n      ElementDef := RecordDef.Members[ElementIndex];\n\n      case ElementDef.DefType of\n        dtSubRecord:\n          Element := TwbSubRecord.Create(Self, ElementDef as IwbSubRecordDef);\n        dtSubRecordArray:\n          Element := TwbSubRecordArray.Create(Self, nil, Low(Integer), ElementDef as IwbSubRecordArrayDef);\n        dtSubRecordStruct:\n          Element := TwbSubRecordStruct.Create(Self, nil, Low(Integer), ElementDef as IwbSubRecordStructDef);\n      else\n        Assert(False);\n      end;\n\n      if Assigned(Element) and Assigned(aElement) then try\n        Element.Assign(Low(Integer), nil, False);\n        if csAsCreatedEmpty in cntStates then\n          Exclude(cntStates, csAsCreatedEmpty);\n      except\n        Element.Container.RemoveElement(Element);\n        raise;\n      end;\n    end;\n  end;\nend;\n\nprocedure TwbContainer.NotifyChangedInternal(aContainer: Pointer);\nbegin\n  if [csInitializing, csReseting] * cntStates <> [] then\n    Exit;\n  if csAsCreatedEmpty in cntStates then\n    Exclude(cntStates, csAsCreatedEmpty);\n\n  inherited;\n\n  if esModified in eStates then\n    DoAfterSet(varEmpty, varEmpty);\nend;\n\nprocedure TwbContainer.PrepareSave;\nvar\n  i: Integer;\n  SelfRef : IwbContainerElementRef;\nbegin\n  if wbDelayLoadRecords then\n    if not (esModified in eStates) then\n      Exit;\n\n  SelfRef := Self as IwbContainerElementRef;\n  DoInit;\n  for i := High(cntElements) downto Low(cntElements) do\n    cntElements[i].PrepareSave;\nend;\n\nprocedure TwbContainer.PreviousElementMember(const aElement: IwbElement);\nvar\n  ElementIndex      : Integer;\n  ElementDef        : IwbRecordMemberDef;\n  Element           : IwbElement;\n  Container         : IwbContainer;\n  SubRecordArrayDef : IwbSubRecordArrayDef;\n  SubRecordUnionDef : IwbSubRecordUnionDef;\n  RecordDef         : IwbRecordDef;\n  i                 : Integer;\nbegin\n  if Assigned(eContainer) and not IwbContainer(eContainer).IsElementEditable(Self) then\n    Exit;\n  if not CanChangeElementMember(aElement) then\n    Exit;\n  if not Supports(GetDef, IwbSubRecordArrayDef, SubRecordArrayDef) or\n     not Supports(SubRecordArrayDef.Element, IwbSubRecordUnionDef, SubRecordUnionDef) then\n    Exit;\n  if not Supports(SubRecordArrayDef.Element, IwbRecordDef, RecordDef) then\n    Exit;\n  if Supports(aElement.Container, IwbContainer, Container) then begin\n    for i := 0 to Pred(RecordDef.MemberCount) do\n      if RecordDef.Members[i].Equals(aElement.Def) then\n        break;\n    if i < RecordDef.MemberCount then begin\n      RemoveElement(aElement);\n      ElementIndex := (i - 1) mod RecordDef.MemberCount;\n      ElementDef := RecordDef.Members[ElementIndex];\n\n      case ElementDef.DefType of\n        dtSubRecord:\n          Element := TwbSubRecord.Create(Self, ElementDef as IwbSubRecordDef);\n        dtSubRecordArray:\n          Element := TwbSubRecordArray.Create(Self, nil, Low(Integer), ElementDef as IwbSubRecordArrayDef);\n        dtSubRecordStruct:\n          Element := TwbSubRecordStruct.Create(Self, nil, Low(Integer), ElementDef as IwbSubRecordStructDef);\n      else\n        Assert(False);\n      end;\n\n      if Assigned(Element) and Assigned(aElement) then try\n        Element.Assign(Low(Integer), nil, False);\n        if csAsCreatedEmpty in cntStates then\n          Exclude(cntStates, csAsCreatedEmpty);\n      except\n        Element.Container.RemoveElement(Element);\n        raise;\n      end;\n    end;\n  end;\nend;\n\nfunction TwbContainer.Reached: Boolean;\nvar\n  i       : Integer;\n  SelfRef : IwbContainerElementRef;\nbegin\n  Result := False;\n\n  if GetDontShow then\n    Exit;\n\n  SelfRef := Self as IwbContainerElementRef;\n  DoInit;\n\n  Result := inherited Reached;\n  if not Result then\n    Exit;\n\n  for i := Low(cntElements) to High(cntElements) do\n    if cntElements[i].CanContainFormIDs then\n      cntElements[i].Reached;\nend;\n\nfunction TwbContainer.ReleaseElements: TDynElementInternals;\nvar\n  i: Integer;\n  SelfRef : IwbContainerElementRef;\nbegin\n  if not (esDestroying in eStates) then\n    SelfRef := Self as IwbContainerElementRef;\n\n  Result := cntElements;\n  cntElements := nil;\n  for i := Low(Result) to High(Result) do\n    Result[i].SetContainer(nil);\n  Exclude(cntStates, csAsCreatedEmpty);\nend;\n\nfunction TwbContainer.ReleaseKeepAlive: IwbContainerElementRef;\nbegin\n  Result := cntKeepAliveNext;\n  cntKeepAliveNext := nil;\nend;\n\nfunction TwbContainer.RemoveElement(const aElement: IwbElement; aMarkModified: Boolean = False): IwbElement;\nvar\n  i: Integer;\n  SelfRef : IwbContainerElementRef;\nbegin\n  SelfRef := Self as IwbContainerElementRef;\n  Result := aElement;\n  if not Assigned(aElement) then\n    Exit;\n\n  if Length(cntElements) > 0 then begin\n    if cntElements[High(cntElements)].Equals(aElement) then begin\n      Result := RemoveElement(High(cntElements), aMarkModified);\n      Exit;\n    end;\n\n    for i := Low(cntElements) to Pred(High(cntElements)) do\n      if cntElements[i].Equals(aElement) then begin\n        Result := RemoveElement(i, aMarkModified);\n        Exit;\n      end;\n  end;\n\n  Result := nil;\n  Exit;\nend;\n\nfunction TwbContainer.RemoveElement(const aName: string): IwbElement;\nvar\n  SelfRef   : IwbContainerElementRef;\n  Name      : string;\n  Container : IwbContainerElementRef;\nbegin\n  SelfRef := Self as IwbContainerElementRef;\n  DoInit;\n\n  Result := ResolveElementName(aName, Name);\n  if not Assigned(Result) then\n    Exit;\n\n  if Name = '' then\n    Result.Remove\n  else if Supports(Result, IwbContainerElementRef, Container) then\n    Result := Container.RemoveElement(Name)\n  else\n    Result := nil;\nend;\n\nfunction TwbContainer.RemoveInjected(aCanRemove: Boolean): Boolean;\nvar\n  i       : Integer;\n  SelfRef : IwbContainerElementRef;\nbegin\n  SelfRef := Self as IwbContainerElementRef;\n  DoInit;\n\n  Result := GetReferencesInjected;\n  if not Result then\n    for i := High(cntElements) downto Low(cntElements) do\n      if cntElements[i].CanContainFormIDs then begin\n        Result := cntElements[i].RemoveInjected(True) or Result;\n        if Result and aCanRemove then\n          Break;\n      end;\n  if Result and aCanRemove and GetIsRemoveable then begin\n    Result := False;\n    Remove;\n  end;\nend;\n\nprocedure TwbContainer.ReportRequiredMasters(aStrings: TStrings; aAsNew: Boolean; Recursive: Boolean = True; Initial: Boolean = false);\nvar\n  i: Integer;\n  SelfRef : IwbContainerElementRef;\nbegin\n  SelfRef := Self as IwbContainerElementRef;\n  DoInit;\n  inherited;\n  if Recursive or (Initial and not Supports(Self, IwbGroupRecord)) then\n    for i := Low(cntElements) to High(cntElements) do\n      if cntElements[i].CanContainFormIDs then\n        cntElements[i].ReportRequiredMasters(aStrings, aAsNew, Recursive);\nend;\n\nfunction TwbContainer.RemoveElement(aPos: Integer; aMarkModified: Boolean = False): IwbElement;\nvar\n  SelfRef : IwbContainerElementRef;\nbegin\n  SelfRef := Self as IwbContainerElementRef;\n\n  Result := nil;\n\n  if aPos < Low(cntElements) then\n    Exit\n  else if aPos > High(cntElements) then\n    Exit;\n\n  if aMarkModified then begin\n    SetModified(True);\n    InvalidateStorage;\n  end;\n\n  Result := IInterface(cntElements[aPos]) as IwbElement;\n  cntElements[aPos].SetContainer(nil);\n  cntElements[aPos] := nil;\n\n  if aPos < High(cntElements) then begin\n    Move(cntElements[Succ(aPos)], cntElements[aPos], (High(cntElements) - aPos) * SizeOf(Pointer));\n    Pointer(cntElements[High(cntElements)]) := nil;\n  end;\n\n  SetLength(cntElements, Pred(Length(cntElements)));\n  NotifyChanged(eContainer);\nend;\n\nprocedure TwbContainer.Reset;\nbegin\n  { can be overriden }\nend;\n\nprocedure TwbContainer.ResetConflict;\nvar\n  i       : Integer;\n  SelfRef : IwbContainerElementRef;\nbegin\n  SelfRef := Self as IwbContainerElementRef;\n//  DoInit; elements that don't exist yet don't have anything to reset...\n  inherited;\n  for i := Low(cntElements) to High(cntElements) do\n    cntElements[i].ResetConflict;\nend;\n\nprocedure TwbContainer.ResetReachable;\nvar\n  i       : Integer;\n  SelfRef : IwbContainerElementRef;\nbegin\n  SelfRef := Self as IwbContainerElementRef;\n//  DoInit; elements that don't exist yet don't have anything to reset...\n  inherited;\n  for i := Low(cntElements) to High(cntElements) do\n    cntElements[i].ResetReachable;\nend;\n\nprocedure TwbContainer.ResetTags;\nvar\n  i: Integer;\nbegin\n  inherited;\n  for i := Low(cntElements) to High(cntElements) do\n    cntElements[i].ResetTags;\nend;\n\nfunction TwbContainer.ResolveElementName(aName: string; out aRemainingName: string; aCanCreate: Boolean = False): IwbElement;\nvar\n  i : Integer;\nbegin\n  aRemainingName := '';\n  i := Pos('\\', aName);\n  if i > 0 then begin\n    aRemainingName := Copy(aName, Succ(i), High(Integer));\n    Delete(aName, i, High(Integer));\n  end;\n  if aName = '..' then\n    Result := GetContainer\n  else if (Length(aName) > 0) and (aName[1] = '[') and (aName[Length(aName)] = ']') then begin\n    i := StrToIntDef(Copy(aName, 2, Length(aName) - 2), 0);\n    Result := GetElement(i);\n  end\n  else\n    Result := GetElementByName(aName);\n  if not Assigned(Result) and (Length(aName) = 4) then\n    Result := GetElementBySignature(StrToSignature(aName));\nend;\n\nprocedure TwbContainer.ReverseElements;\nvar\n  Temp: TDynElementInternals;\n  i: Integer;\n  SelfRef : IwbContainerElementRef;\nbegin\n  SelfRef := Self as IwbContainerElementRef;\n  SetLength(Temp, Length(cntElements));\n  for i := Low(cntElements) to High(cntElements) do\n    Temp[High(cntElements)-i] := cntElements[i];\n  cntElements := Temp;\nend;\n\nprocedure TwbContainer.SetElementEditValue(const aName, aValue: string);\nvar\n  SelfRef   : IwbContainerElementRef;\n  Element   : IwbElement;\n  Name      : string;\n  Container : IwbContainerElementRef;\nbegin\n  SelfRef := Self as IwbContainerElementRef;\n  DoInit;\n\n  Element := ResolveElementName(aName, Name, True);\n  if not Assigned(Element) then\n    Exit;\n\n  if Name = '' then\n    Element.EditValue := aValue\n  else if Supports(Element, IwbContainerElementRef, Container) then\n    Container.ElementEditValues[Name] := aValue;\nend;\n\nprocedure TwbContainer.SetElementNativeValue(const aName: string; const aValue: Variant);\nvar\n  SelfRef   : IwbContainerElementRef;\n  Element   : IwbElement;\n  Name      : string;\n  Container : IwbContainerElementRef;\nbegin\n  SelfRef := Self as IwbContainerElementRef;\n  DoInit;\n\n  Element := ResolveElementName(aName, Name, True);\n  if not Assigned(Element) then\n    Exit;\n\n  if Name = '' then\n    Element.NativeValue := aValue\n  else if Supports(Element, IwbContainerElementRef, Container) then\n    Container.ElementNativeValues[Name] := aValue;\nend;\n\nprocedure TwbContainer.SetToDefaultInternal;\nvar\n  i         : Integer;\n  SelfRef   : IwbContainerElementRef;\nbegin\n  SelfRef := Self as IwbContainerElementRef;\n  DoInit;\n\n  inherited;\n\n  for i := Low(cntElements) to High(cntElements) do\n    cntElements[i].SetToDefault;\nend;\n\nprocedure TwbContainer.SortBySortOrder;\nvar\n  i, j: Integer;\nbegin\n  SetModified(True);\n  i := GetAdditionalElementCount;\n  j := Length(cntElements) - i;\n  if j > 1 then begin\n    wbMergeSort(@cntElements[i], j, CompareSortOrder);\n    InvalidateStorage;\n  end;\nend;\n\nprocedure TwbContainer.WriteToStreamInternal(aStream: TStream; aResetModified: Boolean);\nvar\n  i: Integer;\n  SelfRef : IwbContainerElementRef;\nbegin\n  SelfRef := Self as IwbContainerElementRef;\n\n  DoInit;\n  inherited;\n  for i := Low(cntElements) to High(cntElements) do\n    cntElements[i].WriteToStream(aStream, aResetModified);\n\n  Exclude(eStates, esUnsaved);\n  if aResetModified then begin\n    Exclude(eStates, esModified);\n    Exclude(eStates, esInternalModified);\n  end;\nend;\n\n{$D-}\nfunction TwbContainer._AddRef: Integer;\nbegin\n  if wbSpeedOverMemory then\n    Result := ElementAddRef\n  else\n    Result := inherited _AddRef;\nend;\n\nfunction TwbContainer._Release: Integer;\nbegin\n  if wbSpeedOverMemory then\n    Result := ElementRelease\n  else begin\n    Result := inherited _Release;\n    if (Result > 0) and (cntElementRefs = 0) and (csInit in cntStates) then\n      DoReset(False);\n  end;\nend;\n{$D+}\n\n//------------------------------------------------------------------------------\n// TwbRecord\n//------------------------------------------------------------------------------\n\nconstructor TwbRecord.Create(const aContainer      : IwbContainer;\n                               var aBasePtr        : Pointer;\n                                   aEndPtr         : Pointer;\n                             const aPrevMainRecord : IwbMainRecord);\nvar\n  Dummy: Integer;\nbegin\n  inherited Create(aContainer, aBasePtr, aEndPtr, aPrevMainRecord);\n  recSkipped := recSkipped or RecordToSkip.Find(GetSignature, Dummy);\n  InformPrevMainRecord(aPrevMainRecord);\n  ScanData;\nend;\n\nclass function TwbRecord.CreateForPtr(var aPtr            : Pointer;\n                                          aEndPtr         : Pointer;\n                                    const aContainer      : IwbContainer;\n                                    const aPrevMainRecord : IwbMainRecord)\n                                                          : IwbRecord;\nbegin\n  if aContainer.ElementType = etMainRecord then\n    Result := TwbSubRecord.Create(aContainer, aPtr, aEndPtr, aPrevMainRecord)\n  else\n    if PwbSignature(aPtr)^ = 'GRUP' then\n      Result := TwbGroupRecord.Create(aContainer, aPtr, aEndPtr, aPrevMainRecord)\n    else\n      Result := TwbMainRecord.Create(aContainer, aPtr, aEndPtr, aPrevMainRecord);\nend;\n\nfunction TwbRecord.GetName: string;\nvar\n  Sig : TwbSignature;\n  i   : Integer;\nbegin\n  Sig := GetSignature;\n  for i := Low(Sig) to High(Sig) do\n    if Ord(Sig[i]) < 32 then\n      Sig[i] := AnsiChar( Ord('a') + Ord(Sig[i]) );\n\n  Result := Sig;\nend;\n\nfunction TwbRecord.GetSkipped: Boolean;\nbegin\n  Result := recSkipped;\nend;\n\nprocedure TwbRecord.InformPrevMainRecord(const aPrevMainRecord: IwbMainRecord);\nbegin\n  {can be overriden}\nend;\n\nprocedure TwbRecord.SortBySortOrder;\nbegin\n  SetModified(True);\n  if Length(cntElements) > 1 then begin\n    wbMergeSort(@cntElements[1],  High(cntElements), CompareSortOrder);\n    InvalidateStorage;\n  end;\nend;\n\nfunction TwbRecord.GetSignature: TwbSignature;\nbegin\n  if Assigned(dcBasePtr) then\n    Result := PwbSignature(dcBasePtr)^\n  else\n    Result := NONE;\nend;\n\n{ TwbMainRecord }\n\nfunction TwbMainRecord.Add(const aName: string; aSilent: Boolean): IwbElement;\nvar\n  s         : string;\n  SelfRef   : IwbContainerElementRef;\n  i         : Integer;\n  Group     : IwbGroupRecord;\nbegin\n  Result := nil;\n\n  if not wbIsInternalEdit then\n    if not wbEditAllowed or not GetIsEditable then\n      raise Exception.Create(GetName + ' can not be edited');\n\n  if GetIsDeleted then\n    Exit;\n\n  s := Copy(aName, 1, 4);\n\n  if (GetSignature = 'CELL') and\n     (\n        SameText(s, 'NAVM') or\n        SameText(s, 'PGRD') or\n        SameText(s, 'LAND') or\n        SameText(s, 'REFR') or\n        SameText(s, 'PGRE') or\n        SameText(s, 'PMIS') or\n        SameText(s, 'ACRE') or\n        SameText(s, 'ACHR') or\n        SameText(s, 'PARW') or {>>> Skyrim <<<}\n        SameText(s, 'PBEA') or {>>> Skyrim <<<}\n        SameText(s, 'PFLA') or {>>> Skyrim <<<}\n        SameText(s, 'PCON') or {>>> Skyrim <<<}\n        SameText(s, 'PBAR') or {>>> Skyrim <<<}\n        SameText(s, 'PHZD')    {>>> Skyrim <<<}\n     ) then begin\n\n    Group := GetChildGroup;\n    if not Assigned(Group) then begin\n      Group := TwbGroupRecord.Create(GetContainer, 6, Self);\n      mrGroup := Group;\n    end;\n\n    SelfRef := Group as IwbContainerElementRef;\n    Group := nil;\n    for i := 0 to Pred(SelfRef.ElementCount) do\n      if Supports(SelfRef.Elements[i], IwbGroupRecord, Group) then\n        if (Group.GroupType = 9) and (Group.GroupLabel = Self.GetFormID) then\n          Break\n        else\n          Group := nil;\n    if not Assigned(Group) then\n      Group := TwbGroupRecord.Create(SelfRef as IwbContainer, 9, Self);\n\n    Result := Group.Add(aName, aSilent);\n\n    Exit;\n  end else if (GetSignature = 'DIAL') and\n     (\n        SameText(s, 'INFO')\n     ) then begin\n\n    Group := GetChildGroup;\n    if not Assigned(Group) then begin\n      Group := TwbGroupRecord.Create(GetContainer, 7, Self);\n      mrGroup := Group;\n    end;\n\n    Result := Group.Add(aName, aSilent);\n\n    Exit;\n  end else if (GetSignature = 'WRLD') and\n     (\n        SameText(s, 'ROAD') or\n        SameText(s, 'CELL')\n     ) then begin\n\n    Group := GetChildGroup;\n    if not Assigned(Group) then begin\n      Group := TwbGroupRecord.Create(GetContainer, 1, Self);\n      mrGroup := Group;\n    end;\n\n    Result := Group.Add(aName, aSilent);\n\n    Exit;\n  end else if wbVWDAsQuestChildren and (GetSignature = 'QUST') and\n     (\n        SameText(s, 'DLBR') or\n        SameText(s, 'DIAL') or\n        SameText(s, 'SCEN')\n     ) then begin\n\n    Group := GetChildGroup;\n    if not Assigned(Group) then begin\n      Group := TwbGroupRecord.Create(GetContainer, 10, Self);\n      mrGroup := Group;\n    end;\n\n    Result := Group.Add(aName, aSilent);\n\n    Exit;\n  end;\n\n  if Assigned(mrDef) then begin\n\n    SelfRef := Self as IwbContainerElementRef;\n    DoInit;\n\n    for i := 0 to Pred(mrDef.MemberCount) do\n      if SameText(mrDef.Members[i].Name, aName) or SameText(mrDef.Members[i].DefaultSignature, aName) then begin\n        Result := GetElementBySortOrder(i + GetAdditionalElementCount);\n        if not Assigned(Result) then begin\n          Assign(i, nil, False);\n          Result := GetElementBySortOrder(i + GetAdditionalElementCount);\n          Assert(Assigned(Result));\n\n          if wbSortSubRecords and (Length(cntElements) > 1) then\n            wbMergeSort(@cntElements[0], Length(cntElements), CompareSubRecords);\n        end;\n\n        Exit;\n      end;\n  end;\nend;\n\nfunction TwbMainRecord.AddIfMissingInternal(const aElement: IwbElement; aAsNew, aDeepCopy: Boolean; const aPrefixRemove, aPrefix, aSuffix: string): IwbElement;\nvar\n  SelfRef   : IwbContainerElementRef;\nbegin\n  if not wbEditAllowed then\n    raise Exception.Create(GetName + ' can not be assigned.');\n\n  if GetIsDeleted then\n    Exit;\n\n  if Assigned(mrDef) then begin\n\n    SelfRef := Self as IwbContainerElementRef;\n    DoInit;\n\n    Assert(Assigned(aElement.Def));\n    if aElement.SortOrder < 0 then begin\n      Result := GetElementBySortOrder(aElement.SortOrder + GetAdditionalElementCount);\n      Assert(Assigned(Result));\n      Assert(Assigned(Result.Def));\n      Assert(aElement.Def.Equals(Result.Def));\n    end else begin\n      Assert(aElement.SortOrder >= 0);\n      Assert(aElement.SortOrder < mrDef.MemberCount);\n      if not aElement.Def.Equals(mrDef.Members[aElement.SortOrder]) then\n        Assert(Self.CanAssign(aElement.SortOrder, aElement, True));\n      Result := GetElementBySortOrder(aElement.SortOrder + GetAdditionalElementCount);\n    end;\n\n    if not Assigned(Result) then begin\n      Assign(aElement.SortOrder, aElement, not aDeepCopy);\n      Result := GetElementBySortOrder(aElement.SortOrder + GetAdditionalElementCount);\n      Assert(Assigned(Result));\n\n      if wbSortSubRecords and (Length(cntElements) > 1) then\n        wbMergeSort(@cntElements[0], Length(cntElements), CompareSubRecords);\n    end else\n      Result.Assign(Low(Integer), aElement, not aDeepCopy);\n  end;\nend;\n\nprocedure TwbMainRecord.AddOverride(const aMainRecord: IwbMainRecord);\nbegin\n  if aMainRecord.Signature <> GetSignature then\n    if Assigned(wbProgressCallback) then\n      wbProgressCallback(Format('Warning: Record %s in file %s is being overridden by record %s in file %s.', [\n        '['+ GetSignature + ':' + IntToHex64(GetFormID, 8)+ ']',\n        GetFile.FileName,\n        '['+ aMainRecord.Signature + ':' + IntToHex64(aMainRecord.FormID, 8)+ ']',\n        aMainRecord._File.FileName\n      ]));\n\n  SetLength(mrOverrides, Succ(Length(mrOverrides)));\n  mrOverrides[High(mrOverrides)] := aMainRecord;\n  (aMainRecord as IwbMainRecordInternal).SetMaster(Self);\n  mrOverridesSorted := False;\nend;\n\nprocedure TwbMainRecord.AddReferencedBy(aMainRecord : IwbMainRecord);\nbegin\n  SetLength(mrReferencedBy, Succ(Length(mrReferencedBy)));\n  mrReferencedBy[High(mrReferencedBy)] := aMainRecord;\n  Include(mrStates, mrsReferencedByUnsorted);\nend;\n\nprocedure TwbMainRecord.AddReferencedFromID(aFormID: Cardinal);\nbegin\n  Assert(mrsBuildingRef in mrStates);\n\n  if aFormID = 0 then\n    Exit;\n\n  Inc(mrTmpRefFormIDHigh);\n  if High(mrTmpRefFormIDs) < mrTmpRefFormIDHigh then\n    if mrTmpRefFormIDHigh = 0 then\n      SetLength(mrTmpRefFormIDs, 64)\n    else\n      SetLength(mrTmpRefFormIDs, mrTmpRefFormIDHigh * 2);\n\n  mrTmpRefFormIDs[mrTmpRefFormIDHigh] := aFormID;\nend;\n\nfunction TwbMainRecord.AssignInternal(aIndex: Integer; const aElement: IwbElement; aOnlySK: Boolean): IwbElement;\nvar\n  MainRecord    : IwbMainRecord;\n  Member        : IwbRecordMemberDef;\n  Container     : IwbContainerElementRef;\n  Element       : IwbElement;\n  i             : Integer;\n  SelfRef       : IwbContainerElementRef;\n  BasePtr       : Pointer;\n  IsAdd         : Boolean;\n  IsAddChild    : Boolean;\n  GroupRecord   : IwbGroupRecord;\n  DataContainer : IwbDataContainer;\n  NeedUpdate    : Boolean;\nbegin\n  Result := nil;\n\n  if not wbEditAllowed then\n    raise Exception.Create(GetName + ' can not be assigned.');\n\n  if GetIsDeleted then\n    Exit;\n\n  if Assigned(mrDef) then begin\n\n    wbBeginKeepAlive;\n    try\n      SelfRef := Self as IwbContainerElementRef;\n      DoInit;\n\n      if aIndex = Low(Integer) then begin\n\n        NeedUpdate := CheckChildOfCell;\n\n        SetModified(True);\n        InvalidateStorage;\n        ReleaseElements;\n\n        if Assigned(aElement) then begin\n          Container := aElement as IwbContainerElementRef;\n\n          if Supports(aElement, IwbMainRecord, MainRecord) then begin\n            MakeHeaderWriteable;\n            with TwbMainRecord(MainRecord.ElementID) do begin\n              Self.mrStruct.mrsFlags := mrStruct.mrsFlags;\n              Self.mrStruct.mrsVCS1 := DefaultVCS1;\n              if wbGameMode in [gmFO3, gmFNV, gmTES5, gmSSE, gmFO4] then begin\n                Self.mrStruct.mrsVersion := mrStruct.mrsVersion;\n                Self.mrStruct.mrsVCS2 := DefaultVCS2; //mrStruct.mrsVCS2;\n              end;\n            end;\n          end;\n        end;\n\n        if Supports(Self.GetContainer, IwbGroupRecord, GroupRecord) then\n          if wbCreateContainedIn and (GroupRecord.GroupType in [1, 4..10]) then\n            with TwbContainedInElement.Create(Self) do begin\n              _AddRef; _Release;\n            end;\n        GroupRecord := nil;\n\n        BasePtr := dcBasePtr;\n        with TwbRecordHeaderStruct.Create(Self, BasePtr, Pointer( Cardinal(BasePtr) + wbSizeOfMainRecordStruct), mrDef.RecordHeaderStruct, '') do begin\n          Include(dcFlags, dcfDontSave);\n          SetSortOrder(-1);\n          SetMemoryOrder(Low(Integer));\n          _AddRef; _Release;\n        end;\n\n        if Assigned(aElement) then begin\n          for i := 0 to Pred(Container.ElementCount) do begin\n            Element := Container.Elements[i];\n            Assign(Element.SortOrder, Element, aOnlySK);\n          end;\n        end else begin\n          for i := 0 to Pred(mrDef.MemberCount) do\n            if mrDef.Members[i].Required then\n              Assign(i, nil, False);\n        end;\n\n        if NeedUpdate then\n          UpdateCellChildGroup;\n\n        CollapseStorage;\n\n      end else begin\n        if (aIndex >= 0) and (aIndex < mrDef.MemberCount) then begin\n          Member := mrDef.Members[aIndex];\n          IsAdd := not Assigned(aElement) or Member.CanAssign(Self, Low(Integer), aElement.Def);\n          IsAddChild := not IsAdd and Assigned(aElement) and Member.CanAssign(Self, High(Integer), aElement.Def);\n          if IsAdd or IsAddChild then begin\n            Element := GetElementBySortOrder(aIndex + GetAdditionalElementCount);\n            if Assigned(Element) then begin\n              if IsAdd and Assigned(aElement) then\n                Element.Assign(Low(Integer), aElement, aOnlySK)\n              else if IsAddChild then\n                Element.Assign(High(Integer), aElement, aOnlySK);\n            end else begin\n\n              if Member.DefType = dtSubRecordUnion then begin\n                if Assigned(aElement) then begin\n                  Supports(aElement, IwbDataContainer, DataContainer);\n                  Member := (Member as IwbRecordDef).GetMemberFor((aElement as IwbHasSignature).Signature, DataContainer);\n                end else\n                  Member := (Member as IwbRecordDef).Members[0];\n                Assert(Assigned(Member));\n              end;\n\n              case Member.DefType of\n                dtSubRecord:\n                  Element := TwbSubRecord.Create(Self, Member as IwbSubRecordDef);\n                dtSubRecordArray:\n                  Element := TwbSubRecordArray.Create(Self, nil, Low(Integer), Member as IwbSubRecordArrayDef);\n                dtSubRecordStruct:\n                  Element := TwbSubRecordStruct.Create(Self, nil, Low(Integer), Member as IwbSubRecordStructDef);\n              else\n                Assert(False);\n              end;\n\n              if Assigned(Element) then try\n                Element.SortOrder := aIndex;\n                Element.MemoryOrder := aIndex;\n                if IsAdd and Assigned(aElement) then\n                  Element.Assign(Low(Integer), aElement, aOnlySK)\n                else if IsAddChild then\n                  Element.Assign(High(Integer), aElement, aOnlySK);\n              except\n                Element.Container.RemoveElement(Element);\n                raise;\n              end;\n\n            end;\n            Result := Element;\n          end;\n        end else if (aIndex = -2) then begin\n          Element := GetElementBySortOrder(aIndex + GetAdditionalElementCount);\n          if Assigned(Element) then\n            Element.Assign(Low(Integer), aElement, False);\n          Result := Element;\n        end;\n      end;\n    finally\n      wbEndKeepAlive;\n    end;\n\n    if wbSortSubRecords and (Length(cntElements) > 1) then\n      wbMergeSort(@cntElements[0], Length(cntElements), CompareSubRecords);\n\n  end else\n    Result := inherited AssignInternal(aIndex, aElement, aOnlySK);\nend;\n\nprocedure TwbMainRecord.BuildRef;\n\n  procedure UseKAC;\n  var\n    KAR: IwbKeepAliveRoot;\n  begin\n    KAR := wbCreateKeepAliveRoot;\n    DoBuildRef(False);\n  end;\n\nbegin\n  if wbSpeedOverMemory then\n    DoBuildRef(False)\n  else\n    UseKAC;\n  if Assigned(wbProgressCallback) then\n    wbProgressCallback('');\nend;\n\nprocedure TwbMainRecord.DoBuildRef(aRemove: Boolean);\nvar\n  _File         : IwbFile;\n  Files         : array of IwbFile;\n  FilesCount    : Integer;\n  SelfIntf      : IwbMainRecord;\n\n  procedure ProcessRef(aFormID: Cardinal; aAdd: Boolean);\n  var\n    FileID     : Integer;\n    MainRecord : IwbMainRecord;\n  begin\n    if not Assigned(_File) then begin\n      _File := GetFile;\n      FilesCount := _File.MasterCount;\n      SetLength(Files, Succ(FilesCount));\n      Files[FilesCount] := _File;\n      SelfIntf := Self as IwbMainRecord;\n    end;\n\n    FileID := aFormID shr 24;\n    if FileID > FilesCount then\n      FileID := FilesCount;\n\n    if not Assigned(Files[FileID]) then\n      Files[FileID] := _File.Masters[FileID];\n\n    aFormID := (aFormID and $00FFFFFF) or (Cardinal(Files[FileID].MasterCount) shl 24);\n\n    MainRecord := Files[FileID].RecordByFormID[aFormID, True];\n    if Assigned(MainRecord) then\n      if aAdd then\n        MainRecord.AddReferencedBy(SelfIntf)\n      else\n        MainRecord.RemoveReferencedBy(SelfIntf);\n  end;\n\nvar\n  NewReferences : TDynCardinalArray;\n  LastFormID    : Cardinal;\n  i, j          : Integer;\n  NewCount      : integer;\n  Cmp           : Integer;\n  SelfRef : IwbContainerElementRef;\nbegin\n  if mrsBuildingRef in mrStates then\n    Exit;\n\n  SelfRef := Self as IwbContainerElementRef;\n\n  Assert(not (mrsBuildingRef in mrStates));\n  Include(mrStates, mrsBuildingRef);\n  try\n    mrTmpRefFormIDHigh := -1;\n    mrTmpRefFormIDs := nil;\n\n    if not aRemove then\n      inherited BuildRef;\n\n    NewCount := 0;\n    SetLength(NewReferences, Succ(mrTmpRefFormIDHigh));\n    if mrTmpRefFormIDHigh >= 0 then begin\n      wbMergeSort(@mrTmpRefFormIDs[0], Succ(mrTmpRefFormIDHigh), CompareFormIDs);\n      LastFormID := 0;\n      for i := 0 to mrTmpRefFormIDHigh do\n        if mrTmpRefFormIDs[i] <> LastFormID then begin\n          LastFormID := mrTmpRefFormIDs[i];\n          NewReferences[NewCount] := LastFormID;\n          Inc(NewCount);\n        end;\n    end;\n    SetLength(NewReferences, NewCount);\n\n    i := 0;\n    j := 0;\n    while (i < NewCount) and (j < Length(mrReferences)) do begin\n      Cmp := CmpW32(NewReferences[i], mrReferences[j]);\n      if Cmp = 0 then begin\n        Inc(i);\n        Inc(j);\n      end else if Cmp < 0 then begin\n        ProcessRef(NewReferences[i], True);\n        Inc(i);\n      end else begin\n        ProcessRef(mrReferences[j], False);\n        Inc(j);\n      end;\n    end;\n    while i < NewCount do begin\n      ProcessRef(NewReferences[i], True);\n      Inc(i);\n    end;\n    while j < Length(mrReferences) do begin\n      ProcessRef(mrReferences[j], False);\n      Inc(j);\n    end;\n\n    mrReferences := NewReferences;\n  finally\n    Exclude(mrStates, mrsBuildingRef);\n    mrTmpRefFormIDs := nil;\n  end;\nend;\n\nprocedure TwbMainRecord.ElementChanged(const aElement: IwbElement; aContainer: Pointer);\nconst\n  EDID = $44494445;\n  FULL = $4C4C5546;\n  NAME = $454D414E;\nvar\n  SubRecord: IwbSubRecord;\nbegin\n  if Supports(aElement, IwbSubRecord, SubRecord) then\n    case Cardinal(SubRecord.Signature) of\n      EDID: mrEditorID := SubRecord.Value;\n      FULL: mrFullName := SubRecord.Value;\n      NAME: Exclude(mrStates, mrsBaseRecordChecked);\n    end;\n  inherited;\n  if not (mrsNoUpdateRefs in mrStates) then\n    UpdateRefs;\nend;\n\nfunction TwbMainRecord.EnsureChildGroup: IwbGroupRecord;\nconst\n  WRLD = $444C5257;\n  CELL = $4C4C4543;\n  DIAL = $4C414944;\nvar\n  SearchForGroup  : Integer;\n  ContainingGroup : IwbGroupRecord;\nbegin\n  Result := GetChildGroup;\n  if not Assigned(Result) then begin\n    case Cardinal(GetSignature) of\n      WRLD: SearchForGroup := 1;\n      CELL: SearchForGroup := 6;\n      DIAL: SearchForGroup := 7;\n    else\n      if wbVWDAsQuestChildren and (GetSignature = 'QUST') then\n        SearchForGroup := 10\n      else\n        SearchForGroup := 0;\n    end;\n    if (SearchForGroup > 0) and Supports(GetContainer, IwbGroupRecord, ContainingGroup) then begin\n      mrGroup := ContainingGroup.FindChildGroup(SearchForGroup, Self);\n      if not Assigned(mrGroup) and ContainingGroup.IsElementEditable(nil) then begin\n        mrGroup := TwbGroupRecord.Create(ContainingGroup, SearchForGroup, Self);\n        Result := mrGroup;\n      end;\n    end;\n  end;\n  Assert(Assigned(Result));\nend;\n\nfunction TwbMainRecord.CanAssignInternal(aIndex: Integer; const aElement: IwbElement; aCheckDontShow: Boolean): Boolean;\nbegin\n  Result := False;\n  if not wbEditAllowed then\n    Exit;\n\n  if GetIsDeleted then\n    Exit;\n\n  if Assigned(eContainer) then\n    if not IwbContainer(eContainer).IsElementEditable(Self) then\n      Exit;\n\n  if aCheckDontShow then\n    if GetDontShow then\n      Exit;\n\n  if not Assigned(aElement) then begin\n    Result := (aIndex >= 0) and (aIndex < mrDef.MemberCount) and (GetElementBySortOrder(aIndex + GetAdditionalElementCount) = nil);\n    if Result and aCheckDontShow then\n      Result := not mrDef.Members[aIndex].DontShow[Self];\n    Exit;\n  end;\n\n  if Assigned(mrDef) then begin\n    if aIndex = Low(Integer) then\n      Result := mrDef.Equals(aElement.Def)\n    else begin\n      Result := (aIndex >= 0) and (aIndex < mrDef.MemberCount) and\n        (\n          mrDef.Members[aIndex].CanAssign(Self, Low(Integer), aElement.Def) or\n          mrDef.Members[aIndex].CanAssign(Self, High(Integer), aElement.Def)\n        );\n      if Result and aCheckDontShow then\n        Result := not mrDef.Members[aIndex].DontShow[Self];\n    end;\n  end else\n    Result := False;\nend;\n\nfunction TwbMainRecord.CanContainFormIDs: Boolean;\nbegin\n  Result := True; {There is a FormID in the header}\nend;\n\nfunction TwbMainRecord.CanElementReset: Boolean;\nbegin\n  Result := cntElementRefs < 1;\nend;\n\nfunction TwbMainRecord.CheckChildOfCell: Boolean;\nvar\n  Sig    : TwbSignature;\n  Group1 : IwbGroupRecord;\n  Group2 : IwbGroupRecord;\nbegin\n  Sig := GetSignature;\n  Result :=\n    (Sig = 'REFR') or\n    (Sig = 'PMIS') or\n    (Sig = 'PGRE') or\n    (Sig = 'ACRE') or\n    (Sig = 'ACHR') or\n    (Sig = 'PARW') or {>>> Skyrim <<<}\n    (Sig = 'PBEA') or {>>> Skyrim <<<}\n    (Sig = 'PFLA') or {>>> Skyrim <<<}\n    (Sig = 'PCON') or {>>> Skyrim <<<}\n    (Sig = 'PBAR') or {>>> Skyrim <<<}\n    (Sig = 'PHZD');   {>>> Skyrim <<<}\n  if not Result then\n    Exit;\n  if not Supports(GetContainer, IwbGroupRecord, Group1) then\n    raise Exception.Create(GetName + ' is not contained in a group.');\n  if not (Group1.GroupType in [8, 9, 10]) then\n    raise Exception.Create(GetName + ' is not contained in a group of type \"Cell Persistent Childen\", \"Cell Temporary Children\" or \"Cell Visible Distant Children\"');\n  if not Supports(Group1.Container, IwbGroupRecord, Group2) then\n    raise Exception.Create(Group1.GetName + ' is not contained in a group.');\n  if not (Group2.GroupType in [6]) then\n    raise Exception.Create(Group1.GetName + ' is not contained in a group of type \"Cell Children\"');\nend;\n\nprocedure TwbMainRecord.ClearForRelease;\nbegin\n  mrMaster := nil;\n  mrOverrides := nil;\n  mrReferencedBy := nil;\n  mrGroup := nil;\n  ReleaseElements;\nend;\n\nprocedure TwbMainRecord.CollapseStorage;\nvar\n  Stream  : TMemoryStream;\n\nbegin\n  if (esModified in eStates) then begin\n    PrepareSave;\n    Stream := TMemoryStream.Create;\n    try\n      WriteToStream(Stream, True);\n      DoReset(True);\n      ReleaseElements;\n\n      if mrBasePtrAllocated in mrStates then\n        FreeMem(dcBasePtr);\n      GetMem(dcBasePtr, Stream.Size);\n      Include(mrStates, mrBasePtrAllocated);\n\n      Move(Stream.Memory^, dcBasePtr^, Stream.Size);\n\n      dcEndPtr := Pointer( Cardinal(dcBasePtr) + Stream.Size);\n\n      Exclude(dcFlags, dcfStorageInvalid);\n      mrDataStorage := nil;\n      dcDataStorage := nil;\n      dcDataBasePtr := nil;\n      dcDataEndPtr := nil;\n\n      InitDataPtr;\n\n      SetModified(True);\n      InvalidateParentStorage;\n    finally\n      Stream.Free;\n    end;\n  end;\nend;\n\nfunction TwbMainRecord.CompareExchangeFormID(aOldFormID, aNewFormID: Cardinal): Boolean;\nvar\n  SelfRef : IwbContainerElementRef;\nbegin\n  SelfRef := Self as IwbContainerElementRef;\n\n  mrBaseRecordID := 0;\n  Exclude(mrStates, mrsBaseRecordChecked);\n\n  Result := inherited CompareExchangeFormID(aOldFormID, aNewFormID);\n  if {Result and} (csRefsBuild in cntStates) then // if you changed to an already existing FormID\n    BuildRef;\nend;\n\nprocedure TwbMainRecord.ContainerChanged;\nvar\n  ContainedIn: IwbContainedIn;\nbegin\n  if csInit in cntStates then\n    if Supports(GetElementBySortOrder(-2 + GetAdditionalElementCount), IwbContainedIn, ContainedIn) then\n      ContainedIn.ContainerChanged;\nend;\n\nconstructor TwbMainRecord.Create(const aContainer: IwbContainer; const aSignature: TwbSignature; aFormID: Cardinal);\nvar\n  BasePtr      : PwbMainRecordStruct;\n  i            : Integer;\n  SelfRef      : IwbContainerElementRef;\n  Group        : IwbGroupRecordInternal;\n  Group2       : IwbGroupRecordInternal;\n  ContainerRef : IwbContainerElementRef;\n  s            : string;\n  Block        : Cardinal;\n  SubBlock     : Cardinal;\n  lContainer   : IwbContainer;\n  IsInterior   : Boolean;\nbegin\n  IsInterior := False;\n  lContainer := aContainer;\n  New(BasePtr);\n  Include(mrStates, mrBasePtrAllocated);\n  BasePtr.mrsSignature := aSignature;\n  BasePtr.mrsDataSize := 0;\n  BasePtr.mrsFlags._Flags := 0;\n  BasePtr.mrsFormID := aFormID;\n  BasePtr.mrsVCS1 := DefaultVCS1;\n  case wbGameMode of\n    gmFO4 : BasePtr.mrsVersion := 131;\n    gmTES5: BasePtr.mrsVersion := 43;\n    gmSSE : BasePtr.mrsVersion := 44;\n    gmFNV : BasePtr.mrsVersion := 15;\n    gmFO3 : BasePtr.mrsVersion := 15;\n    else    BasePtr.mrsVersion := 15;\n  end;\n  BasePtr.mrsVCS2 := DefaultVCS2;\n\n  Group := nil;\n  if Supports(lContainer, IwbGroupRecordInternal, Group) then\n    if Group.GroupType = 8 then\n      BasePtr.mrsFlags.SetPersistent(True)\n    else if (Group.GroupType = 10) and not (wbVWDAsQuestChildren\n               and Supports(Group.Container, IwbGroupRecord, Group2) and (TwbSignature(Group2.GroupLabel) = 'QUST')) then\n      BasePtr.mrsFlags.SetVisibleWhenDistant(True);\n\n  if Assigned(Group) then\n    if aSignature = 'CELL' then begin\n      if Group.GroupType = 3 then\n        Supports(Group.Container, IwbGroupRecordInternal, Group);\n      if Assigned(Group) then begin\n        if Group.GroupType = 2 then\n          Supports(Group.Container, IwbGroupRecordInternal, Group);\n        if Assigned(Group) then begin\n          if (Group.GroupType = 0) and (TwbSignature(Group.GroupLabel) = 'CELL') then begin\n            s := '00' + IntToStr(aFormID and $00FFFFFF);\n            Block := StrToInt(s[Length(s)]);\n            SubBlock := StrToInt(s[Pred(Length(s))]);\n\n            ContainerRef := Group as IwbContainerElementRef;\n            Group := nil;\n            for i := 0 to Pred(ContainerRef.ElementCount) do\n              if Supports(ContainerRef.Elements[i], IwbGroupRecord, Group) then\n                if (Group.GroupType = 2) and (Group.GroupLabel = Block) then\n                  Break\n                else\n                  Group := nil;\n            if not Assigned(Group) then\n              Group := TwbGroupRecord.Create(ContainerRef as IwbContainer, 2, Block);\n\n            ContainerRef := Group as IwbContainerElementRef;\n            Group := nil;\n            for i := 0 to Pred(ContainerRef.ElementCount) do\n              if Supports(ContainerRef.Elements[i], IwbGroupRecord, Group) then\n                if (Group.GroupType = 3) and (Group.GroupLabel = SubBlock) then\n                  Break\n                else\n                  Group := nil;\n            if not Assigned(Group) then\n              Group := TwbGroupRecord.Create(ContainerRef as IwbContainer, 3, SubBlock);\n\n            lContainer := Group as IwbContainer;\n            IsInterior := True;\n          end;\n        end;\n      end;\n    end;\n\n  Create(lContainer, Pointer(BasePtr), nil, nil);\n  Assert(Assigned(mrDef));\n  SelfRef := Self as IwbContainerElementRef;\n  DoInit;\n  SetModified(True);\n  InvalidateStorage;\n  for i := 0 to Pred(mrDef.MemberCount) do\n    if mrDef.Members[i].Required then\n      Assign(i, nil, False);\n  if Supports(lContainer, IwbGroupRecordInternal, Group) then\n    Group.Sort;\n\n  if IsInterior then\n    if Supports(GetRecordBySignature('DATA'), IwbContainerElementRef, ContainerRef) then\n      ContainerRef.EditValue := '1';\nend;\n\nconstructor TwbMainRecord.Create(const aContainer: IwbContainer; var aBasePtr: Pointer; aEndPtr: Pointer; const aPrevMainRecord : IwbMainRecord);\nvar\n  _File: IwbFileInternal;\nbegin\n  inherited;\n  try\n    _File := GetFile as IwbFileInternal;\n    if Assigned(_File) then\n      _File.AddMainRecord(Self);\n  except\n    if Assigned(aContainer) then\n      aContainer.RemoveElement(Self);\n    raise;\n  end;\nend;\n\nprocedure TwbMainRecord.DecompressIfNeeded;\nvar\n  UncompressedLength: Cardinal;\nbegin\n  InitDataPtr; // reset...\n\n  if mrStruct.mrsFlags.IsCompressed then try\n    UncompressedLength := PCardinal(dcDataBasePtr)^;\n    if UncompressedLength > 0 then begin\n      SetLength(mrDataStorage, UncompressedLength );\n\n      DecompressToUserBuf(\n        Pointer( Cardinal(dcDataBasePtr) + SizeOf(Cardinal) ),\n        mrStruct.mrsDataSize - SizeOf(Cardinal),\n        @mrDataStorage[0],\n        UncompressedLength\n      );\n\n      dcDataBasePtr := @mrDataStorage[0];\n      dcDataEndPtr := Pointer( Cardinal(dcDataBasePtr) + UncompressedLength );\n    end else begin\n      mrDataStorage := nil;\n      dcDataBasePtr := @EmptyPtr;\n      dcDataEndPtr := @EmptyPtr;\n    end;\n  except\n    dcDataBasePtr := nil;\n    dcDataEndPtr := nil;\n  end;\nend;\n\nprocedure TwbMainRecord.Delete;\nvar\n  SelfRef     : IwbContainerElementRef;\n  BasePtr     : Pointer;\n  GroupRecord : IwbGroupRecord;\nbegin\n  SelfRef := Self;\n  DoInit;\n\n  SetModified(True);\n  InvalidateStorage;\n  ReleaseElements;\n\n  MakeHeaderWriteable;\n  GetFlagsPtr.SetDeleted(True);\n\n  if Supports(Self.GetContainer, IwbGroupRecord, GroupRecord) then\n    if wbCreateContainedIn and (GroupRecord.GroupType in [1, 4..10]) then\n      with TwbContainedInElement.Create(Self) do begin\n        _AddRef; _Release;\n      end;\n  GroupRecord := nil;\n\n  BasePtr := dcBasePtr;\n  with TwbRecordHeaderStruct.Create(Self, BasePtr, Pointer( Cardinal(BasePtr) + wbSizeOfMainRecordStruct), mrDef.RecordHeaderStruct, '') do begin\n    Include(dcFlags, dcfDontSave);\n    SetSortOrder(-1);\n    SetMemoryOrder(Low(Integer));\n    _AddRef; _Release;\n  end;\nend;\n\nprocedure TwbMainRecord.DeleteInto(const aFile: IwbFile);\nvar\n  MainRecord: IwbMainRecord;\nbegin\n  if Supports(CopyInto(aFile, False, False, '', '', ''), IwbMainRecord, MainRecord) then\n    MainRecord.Delete;\nend;\n\ndestructor TwbMainRecord.Destroy;\nbegin\n  if mrBasePtrAllocated in mrStates then\n    FreeMem(dcBasePtr);\n  inherited;\nend;\n\nprocedure TwbMainRecord.Init;\nvar\n  FoundError           : Boolean;\n  CurrentPtr           : Pointer;\n  CurrentDefPos        : Integer;\n  CurrentRecPos        : Integer;\n  Element              : IwbElement;\n  CurrentRec           : IwbSubRecord;\n  CurrentDef           : IwbRecordMemberDef;\n  SubRecordArray       : IwbSubRecordArrayInternal;\n  Dummy                : Integer;\n  LastElementForMember : array of IwbElement;\n  GroupRecord          : IwbGroupRecord;\n  GroupRecordInternal  : IwbGroupRecordInternal;\n{$IFDEF DBGSUBREC}\n//  MainRecord             : IwbMainRecord;\n  s: string;\n{$ENDIF}\n  RequiredRecords      : set of byte;\n  PresentRecords       : set of byte;\n  i                    : Integer;\nbegin\n  RequiredRecords := [];\n  PresentRecords := [];\n\n  inherited;\n\n  if recSkipped then\n    Exit;\n\n  if Length(cntElements) > 0 then\n    Exit;\n\n  DecompressIfNeeded;\n\n  FoundError := False;\n\n  if not (mrsQuickInit in mrStates) then begin\n    if Supports(Self.GetContainer, IwbGroupRecord, GroupRecord) then\n      if wbCreateContainedIn and (GroupRecord.GroupType in [1, 4..10]) then\n        with TwbContainedInElement.Create(Self) do begin\n          _AddRef; _Release;\n        end;\n    GroupRecord := nil;\n\n    CurrentPtr := dcBasePtr;\n    with TwbRecordHeaderStruct.Create(Self, CurrentPtr, Pointer( Cardinal(CurrentPtr) + wbSizeOfMainRecordStruct), mrDef.RecordHeaderStruct, '') do begin\n      Include(dcFlags, dcfDontSave);\n      SetSortOrder(-1);\n      SetMemoryOrder(Low(Integer));\n      _AddRef; _Release;\n    end;\n  end;\n\n{$IFDEF DBGSUBREC}\n  s := '';\n{$ENDIF}\n  CurrentPtr := GetDataBasePtr;\n  while Cardinal(CurrentPtr) < Cardinal(dcDataEndPtr) do begin\n    Element := TwbRecord.CreateForPtr(CurrentPtr, dcDataEndPtr, Self, nil);\n{$IFDEF DBGSUBREC}\n    if Supports(Element, IwbSubRecord, CurrentRec) then\n      s := s + CurrentRec.Signature + ' ';\n{$ENDIF}\n  end;\n  Element := nil;\n\n  if not Assigned(mrDef) then\n    Exit;\n\n  SetLength(LastElementForMember, mrDef.MemberCount);\n\n  if not Assigned(cntElements) then\n    Exit;\n\n  CurrentDefPos := 0;\n  CurrentRecPos := 0;\n\n  while (CurrentRecPos < Length(cntElements)) do begin\n    if cntElements[CurrentRecPos].ElementType <> etSubRecord then begin\n      Inc(CurrentRecPos);\n      Continue;\n    end;\n    CurrentRec := cntElements[CurrentRecPos] as IwbSubRecord;\n    if wbIgnoreRecords.Find(CurrentRec.Signature, Dummy) then begin\n      Inc(CurrentRecPos);\n      Continue;\n    end;\n\n    if mrDef.AllowUnordered then begin\n      CurrentDefPos := mrDef.GetMemberIndexFor(CurrentRec.Signature, CurrentRec);\n      if CurrentDefPos < 0 then begin\n        if Assigned(wbProgressCallback) then\n          wbProgressCallback('Error: record '+ String(GetSignature) + ' contains unexpected (or out of order) subrecord ' + String(CurrentRec.Signature) + ' ' + IntToHex(Int64(Cardinal(CurrentRec.Signature)), 8) );\n        FoundError := True;\n        Inc(CurrentRecPos);\n        Continue;\n      end;\n      CurrentDef := mrDef.Members[CurrentDefPos];\n    end else begin\n      if not mrDef.ContainsMemberFor(CurrentRec.Signature, CurrentRec) then begin\n        if Assigned(wbProgressCallback) then\n          wbProgressCallback('Error: record '+ String(GetSignature) + ' contains unexpected (or out of order) subrecord ' + String(CurrentRec.Signature) + ' ' + IntToHex(Int64(Cardinal(CurrentRec.Signature)), 8) );\n        FoundError := True;\n        Inc(CurrentRecPos);\n        Continue;\n      end;\n\n      if (CurrentDefPos < mrDef.MemberCount) and not FoundError then begin\n        CurrentDef := mrDef.Members[CurrentDefPos];\n        if not CurrentDef.CanHandle(CurrentRec.Signature, CurrentRec) then begin\n          Inc(CurrentDefPos);\n          Continue;\n        end;\n      end else begin\n        if Assigned(wbProgressCallback) then\n          wbProgressCallback('Error: record '+ String(GetSignature) + ' contains unexpected (or out of order) subrecord ' + String(CurrentRec.Signature) );\n        FoundError := True;\n        CurrentDefPos := mrDef.GetMemberIndexFor(CurrentRec.Signature, CurrentRec);\n        if CurrentDefPos < 0 then begin\n          Inc(CurrentRecPos);\n          Continue;\n        end;\n        CurrentDef := mrDef.Members[CurrentDefPos];\n      end;\n    end;\n\n    if CurrentDefPos > mrDef.QuickInitLimit then begin\n      Include(mrStates, mrsQuickInitDone);\n      if mrsQuickInit in mrStates then\n        Exit;\n    end;\n\n    if CurrentDef.DefType = dtSubRecordUnion then begin\n      CurrentDef := (CurrentDef as IwbRecordDef).GetMemberFor(CurrentRec.Signature, CurrentRec);\n      Assert(Assigned(CurrentDef));\n    end;\n\n    case CurrentDef.DefType of\n      dtSubRecord       : begin\n        (CurrentRec as IwbSubRecordInternal).SetDef(CurrentDef as IwbSubRecordDef);\n        if CurrentRec.Signature = 'EDID' then\n          mrEditorID := CurrentRec.Value\n        else if CurrentRec.Signature = 'FULL' then\n          mrFullName := CurrentRec.Value\n        else if (CurrentRec.Signature = 'NAME') and\n                (\n                  (mrDef.DefaultSignature = 'REFR') or\n                  (mrDef.DefaultSignature = 'PGRE') or\n                  (mrDef.DefaultSignature = 'PMIS') or\n                  (mrDef.DefaultSignature = 'ACHR') or\n                  (mrDef.DefaultSignature = 'ACRE') or\n                  (mrDef.DefaultSignature = 'PARW') or {>>> Skyrim <<<}\n                  (mrDef.DefaultSignature = 'PBEA') or {>>> Skyrim <<<}\n                  (mrDef.DefaultSignature = 'PFLA') or {>>> Skyrim <<<}\n                  (mrDef.DefaultSignature = 'PCON') or {>>> Skyrim <<<}\n                  (mrDef.DefaultSignature = 'PBAR') or {>>> Skyrim <<<}\n                  (mrDef.DefaultSignature = 'PHZD')    {>>> Skyrim <<<}\n                ) then begin\n\n          mrBaseRecordID := CurrentRec.NativeValue;\n          Include(mrStates, mrsBaseRecordChecked);\n        end;\n      end;\n      dtSubRecordArray  : begin\n        if Supports(LastElementForMember[CurrentDefPos], IwbSubRecordArrayInternal, SubRecordArray) then begin\n          SubRecordArray.DoProcess(Self, CurrentRecPos);\n          Continue;\n        end else\n          InsertElement(CurrentRecPos, TwbSubRecordArray.Create(nil, Self, CurrentRecPos, CurrentDef as IwbSubRecordArrayDef));\n      end;\n      dtSubRecordStruct :\n        InsertElement(CurrentRecPos, TwbSubRecordStruct.Create(nil, Self, CurrentRecPos, CurrentDef as IwbSubRecordStructDef));\n    else\n      raise Exception.CreateFmt('Unexpected def type for SubRecord %s in %s', [String(CurrentRec.Signature), String(GetSignature)]);\n    end;\n\n    (cntElements[CurrentRecPos] as IwbElementInternal).SetSortOrder(CurrentDefPos);\n    (cntElements[CurrentRecPos] as IwbElementInternal).SetMemoryOrder(CurrentDefPos);\n    Include(PresentRecords, CurrentDefPos);\n    LastElementForMember[CurrentDefPos] := cntElements[CurrentRecPos];\n\n    Inc(CurrentRecPos);\n    Inc(CurrentDefPos);\n  end;\n\n  while CurrentRecPos < Length(cntElements) do begin\n    if cntElements[CurrentRecPos].ElementType <> etSubRecord then begin\n      Inc(CurrentRecPos);\n      Continue;\n    end;\n    CurrentRec := cntElements[CurrentRecPos] as IwbSubRecord;\n    if wbIgnoreRecords.Find(CurrentRec.Signature, Dummy) then begin\n      Inc(CurrentRecPos);\n      Continue;\n    end;\n\n    if Assigned(wbProgressCallback) then\n      wbProgressCallback('Error: record '+ String(GetSignature) + ' contains unexpected (or out of order) subrecord ' + String(CurrentRec.Signature) );\n    FoundError := True;\n\n    Inc(CurrentRecPos);\n  end;\n\n//  if GetSignature = 'DIAL' then\n//    FoundError := True;\n\n  if FoundError then\n    if Assigned(wbProgressCallback) then begin\n      wbProgressCallback('Errors were found in: ' + GetName);\n{$IFDEF DBGSUBREC}\n      wbProgressCallback('Contained subrecords: ' + s);\n{$ENDIF}\n    end;\n\n  if wbSortSubRecords and (mrDef.AllowUnordered or (esModified in eStates)) and (Length(cntElements) > 1) then\n    wbMergeSort(@cntElements[0], Length(cntElements), CompareSubRecords);\n\n  mrDef.AfterLoad(Self);\n\n  if not mrStruct.mrsFlags.IsDeleted then begin\n    for i := 0 to Pred(mrDef.MemberCount) do\n      if mrDef.Members[i].Required then\n        Include(RequiredRecords, i);\n\n    RequiredRecords := RequiredRecords - PresentRecords;\n    if RequiredRecords <> [] then begin\n      if wbBeginInternalEdit then try\n        for i := 0 to Pred(mrDef.MemberCount) do\n          if i in RequiredRecords then begin\n            if wbMoreInfoForRequired  then\n              wbProgressCallback(' ['+IntToHex64(mrFixedFormID, 8)+'] Adding missing record: ' + mrDef.Members[i].GetName);\n            Assign(i, nil, False);\n          end;\n      finally\n        wbEndInternalEdit;\n      end;\n    end;\n  end;\n\n  if wbReportMode {and mrDef.AllowUnordered} then begin\n    s := GetSignature + ' -> ' + s;\n    CurrentRecPos := SubRecordOrderList.Add(s);\n    SubRecordOrderList.Objects[CurrentRecPos] := Pointer(Succ(Integer(SubRecordOrderList.Objects[CurrentRecPos])));\n  end;\n\n{\n  if GetSignature = 'SCPT' then begin\n//    s :=  (GetRecordBySignature('DATA') as IwbContainer).Elements[0].EditValue + s;\n    CurrentRecPos := SubRecordOrderList.Add(s);\n    SubRecordOrderList.Objects[CurrentRecPos] := Pointer(Succ(Integer(SubRecordOrderList.Objects[CurrentRecPos])));\n  end;\n}\n\n  Include(cntStates, csInitOnce);\n\n  if not GetIsDeleted and (GetSignature = 'INFO') and not Assigned(GetRecordBySignature('PNAM')) and wbAllowInternalEdit then\n    if Supports(IwbContainer(eContainer), IwbGroupRecordInternal, GroupRecordInternal) then\n      GroupRecordInternal.Sort;\nend;\n\nfunction TwbMainRecord.FindReferencedBy(const aMainRecord: IwbMainRecord; var Index: Integer): Boolean;\nvar\n  L, H, I, C: Integer;\nbegin\n  Result := False;\n\n  L := Low(mrReferencedBy);\n  H := High(mrReferencedBy);\n  while L <= H do begin\n    I := (L + H) shr 1;\n\n    C := CmpW32(mrReferencedBy[I].LoadOrderFormID , aMainRecord.LoadOrderFormID);\n    if C = 0 then\n      C := CmpW32(mrReferencedBy[I]._File.LoadOrder, aMainRecord._File.LoadOrder);\n\n    if C < 0 then\n      L := I + 1\n    else begin\n      H := I - 1;\n      if C = 0 then begin\n        Result := True;\n        L := I;\n      end;\n    end;\n  end;\n  Index := L;\nend;\n\nprocedure TwbMainRecord.FindUsedMasters(aMasters: PwbUsedMasters);\nvar\n  FileID   : Integer;\n  i        : Integer;\n\n  SelfRef : IwbContainerElementRef;\nbegin\n  SelfRef := Self as IwbContainerElementRef;\n  DoInit;\n\n  if mrStruct.mrsFormID <> 0 then begin\n    FileID := mrStruct.mrsFormID shr 24;\n    aMasters[FileID] := True;\n  end;\n\n  if csRefsBuild in cntStates then begin\n\n    for i := High(mrReferences) downto Low(mrReferences) do begin\n      FileID := mrReferences[i] shr 24;\n      aMasters[FileID] := True;\n    end;\n\n  end else\n    inherited;\nend;\n\nfunction TwbMainRecord.GetAdditionalElementCount: Integer;\nvar\n  GroupRecord: IwbGroupRecord;\nbegin\n  Result := 1;\n  if wbCreateContainedIn and Supports(Self.GetContainer, IwbGroupRecord, GroupRecord) then\n    if GroupRecord.GroupType in [1, 4..10] then\n      Inc(Result);\nend;\n\nfunction TwbMainRecord.GetAddList: TDynStrings;\nvar\n  i, j      : Integer;\n  RecordDef : PwbRecordDef;\nbegin\n  Result := nil;\n\n  if GetIsDeleted then\n    Exit;\n\n  if GetSignature = 'DIAL' then begin\n    SetLength(Result, 1);\n    Result[0] := 'INFO';\n  end else if GetSignature = 'CELL' then begin\n    SetLength(Result, 11);\n    Result[0] := 'ACHR';\n    Result[1] := 'ACRE';\n    Result[2] := 'REFR';\n    Result[3] := 'PGRE';\n    Result[4] := 'PMIS';\n    Result[5] := 'PARW'; {>>> Skyrim <<<}\n    Result[6] := 'PBEA'; {>>> Skyrim <<<}\n    Result[7] := 'PFLA'; {>>> Skyrim <<<}\n    Result[8] := 'PCON'; {>>> Skyrim <<<}\n    Result[9] := 'PBAR'; {>>> Skyrim <<<}\n    Result[10] := 'PHZD'; {>>> Skyrim <<<}\n  end else if GetSignature = 'WRLD' then begin\n  end else if wbVWDAsQuestChildren and (GetSignature = 'QUST') then begin\n    SetLength(Result, 3);\n    Result[0] := 'DIAL';\n    Result[1] := 'DLBR';\n    Result[2] := 'SCEN';\n  end;\n\n  j := 0;\n  for i := Low(Result) to High(Result) do\n    if wbFindRecordDef(AnsiString(Result[i]), RecordDef) then begin\n      Result[j] := Result[i] + ' - ' + RecordDef.Name;\n      Inc(j);\n    end;\n  SetLength(Result, j);\nend;\n\nfunction TwbMainRecord.GetBaseRecord: IwbMainRecord;\nvar\n  SelfRef: IwbContainerElementRef;\n  NameRec: IwbContainerElementRef;\nbegin\n  Result := nil;\n\n  if not ((mrsQuickInitDone in mrStates) or (csInitOnce in cntStates)) then begin\n    SelfRef := Self as IwbContainerElementRef;\n    Assert(not (csInit in cntStates));\n    Include(mrStates, mrsQuickInit);\n    Include(cntStates, csInit);\n    try\n      try\n        Init;\n      finally\n        DoReset(True);\n      end;\n    finally\n      Exclude(cntStates, csInit);\n      Exclude(mrStates, mrsQuickInit);\n    end;\n  end;\n\n  if not (mrsBaseRecordChecked in mrStates) then begin\n    SelfRef := Self as IwbContainerElementRef;\n    mrBaseRecordID := 0;\n    Include(mrStates, mrsBaseRecordChecked);\n    if Supports(GetRecordBySignature('NAME'), IwbContainerElementRef, NameRec) then\n      if Supports(NameRec.LinksTo, IwbMainRecord, Result) then begin\n        mrBaseRecordID := NameRec.NativeValue;\n      end;\n    Exit;\n  end;\n  if mrBaseRecordID <> 0 then\n    with GetFile do\n      Result := RecordByFormID[mrBaseRecordID, True];\nend;\n\nfunction TwbMainRecord.GetBaseRecordID: Cardinal;\nbegin\n  if not (mrsBaseRecordChecked in mrStates) then\n    GetBaseRecord;\n  Result := GetFile.FileFormIDtoLoadOrderFormID(mrBaseRecordID);\nend;\n\nfunction TwbMainRecord.GetCanHaveEditorID: Boolean;\nbegin\n  Result := Assigned(mrDef) and mrDef.ContainsEditorID;\nend;\n\nfunction TwbMainRecord.GetCheck: string;\nvar\n  i, j: Integer;\n  RequiredCount: Integer;\n  Element: IwbElement;\n  Def: IwbNamedDef;\n  FoundIt: Boolean;\n  SelfRef : IwbContainerElementRef;\nbegin\n  SelfRef := Self as IwbContainerElementRef;\n  Result := '';\n\n  if not Assigned(mrDef) then\n    Exit;\n  if recSkipped then\n    Exit;\n\n  if mrStruct.mrsFlags.IsDeleted then begin\n    Result := '';\n\n    for i := GetAdditionalElementCount to Pred(GetElementCount) do begin\n      Element := cntElements[i];\n      Def := Element.Def;\n      if Assigned(Def) then\n        Result := Result + Def.Name + ', ';\n    end;\n    SetLength(Result, Length(Result) - 2);\n\n    if Result <> '' then\n      Result := 'Record marked as deleted but contains: ' + Result;\n\n    Exit;\n  end;\n\n  RequiredCount := 0;\n  for i := 0 to Pred(mrDef.MemberCount) do\n    if mrDef.Members[i].Required then\n      Inc(RequiredCount);\n\n  for i := 0 to Pred(GetElementCount) do begin\n    Element := cntElements[i];\n    Def := Element.Def;\n    if Assigned(Def) then begin\n      if Def.Required then\n        Dec(RequiredCount);\n    end;\n  end;\n\n  if RequiredCount > 0 then begin\n    Result := 'Missing required members: ';\n\n    for i := 0 to Pred(mrDef.MemberCount) do\n      if mrDef.Members[i].Required then begin\n        Def := mrDef.Members[i];\n        FoundIt := False;\n        for j := 0 to High(cntElements) do begin\n          Element := cntElements[j];\n          if Def.Equals(Element.Def) then begin\n            FoundIt := True;\n            Break;\n          end;\n        end;\n        if not FoundIt then\n          Result := Result + Def.Name + ', ';\n      end;\n    SetLength(Result, Length(Result) - 2);\n  end;\nend;\n\nfunction TwbMainRecord.GetChildGroup: IwbGroupRecord;\nvar\n  SearchForGroup: Integer;\n  ContainingGroup: IwbGroupRecord;\nbegin\n  Result := mrGroup;\n  if not Assigned(Result) and not (mrsSearchedChildGroup in mrStates) then begin\n    try\n      Include(mrStates, mrsSearchedChildGroup);\n      SearchForGroup := 0;\n      if GetSignature = 'WRLD' then\n        SearchForGroup := 1\n      else if GetSignature = 'CELL' then\n        SearchForGroup := 6\n      else if GetSignature = 'DIAL' then\n        SearchForGroup := 7\n      else if wbVWDAsQuestChildren and (GetSignature = 'QUST') then\n        SearchForGroup := 10;\n\n      if (SearchForGroup > 0) and Supports(GetContainer, IwbGroupRecord, ContainingGroup) then\n        mrGroup := ContainingGroup.FindChildGroup(SearchForGroup, Self);\n      Result := mrGroup;\n    finally\n      Exclude(mrStates, mrsSearchedChildGroup);\n    end;\n  end;\nend;\n\nfunction TwbMainRecord.GetConflictAll: TConflictAll;\nbegin\n  Result := mrConflictAll;\nend;\n\nfunction TwbMainRecord.GetConflictThis: TConflictThis;\nbegin\n  Result := mrConflictThis;\nend;\n\nfunction TwbMainRecord.GetContainingMainRecord: IwbMainRecord;\nbegin\n  Result := Self;\nend;\n\nfunction TwbMainRecord.GetDef: IwbNamedDef;\nbegin\n  Result := mrDef;\nend;\n\nfunction StrRight(const s: String; Len: Integer): string;\nbegin\n  Result := s;\n  while Length(Result)<Len do\n    Result := ' ' + Result;\nend;\n\nfunction TwbMainRecord.GetDisplayName: string;\nvar\n  Rec         : IwbRecord;\n  GridCoords  : IwbContainerElementRef;\n  GroupRecord : IwbGroupRecord;\n  MapMarker   : IwbContainerElementRef;\nbegin\n  Result := GetFullName;\n  if Result = '' then\n    if\n      (GetSignature = 'REFR') or\n      (GetSignature = 'PGRE') or\n      (GetSignature = 'PMIS') or\n      (GetSignature = 'ACHR') or\n      (GetSignature = 'ACRE') or\n      (GetSignature = 'PARW') or {>>> Skyrim <<<}\n      (GetSignature = 'PBEA') or {>>> Skyrim <<<}\n      (GetSignature = 'PFLA') or {>>> Skyrim <<<}\n      (GetSignature = 'PCON') or {>>> Skyrim <<<}\n      (GetSignature = 'PBAR') or {>>> Skyrim <<<}\n      (GetSignature = 'PHZD')    {>>> Skyrim <<<}\n    then begin\n        if Supports(GetElementByName('Map Marker'), IwbContainerElementRef, MapMarker) then\n          Rec := MapMarker.RecordBySignature['FULL']\n        else\n          Rec := GetRecordBySignature('NAME');\n        if Assigned(Rec) then\n          Result := Trim(Rec.Value)\n    end else if (GetSignature = 'CELL') then begin\n        if Supports(GetContainer, IwbGroupRecord, GroupRecord) and (GroupRecord.GroupType = 1) then\n          Result := '<Persistent Worldspace Cell>'\n        else\n          if Supports(GetRecordBySignature('XCLC'), IwbContainerElementRef, GridCoords) and\n            (GridCoords.ElementCount >= 2) then\n              Result := '<' + StrRight(GridCoords.Elements[0].Value,3) + ', ' + StrRight(GridCoords.Elements[1].Value,3) + '>';\n    end else if (GetSignature = 'INFO') then begin\n        Result := GetElementValue('Responses\\Response\\NAM1');\n    end;\nend;\n\nfunction TwbMainRecord.GetDisplayNameKey: string;\nvar\n  Rec         : IwbRecord;\n  GridCoords  : IwbContainerElementRef;\n  GroupRecord : IwbGroupRecord;\n  MapMarker   : IwbContainerElementRef;\nbegin\n  Result := GetFullName;\n  if Result = '' then\n    if\n      (GetSignature = 'REFR') or\n      (GetSignature = 'PGRE') or\n      (GetSignature = 'PMIS') or\n      (GetSignature = 'ACHR') or\n      (GetSignature = 'ACRE') or\n      (GetSignature = 'PARW') or {>>> Skyrim <<<}\n      (GetSignature = 'PBEA') or {>>> Skyrim <<<}\n      (GetSignature = 'PFLA') or {>>> Skyrim <<<}\n      (GetSignature = 'PCON') or {>>> Skyrim <<<}\n      (GetSignature = 'PBAR') or {>>> Skyrim <<<}\n      (GetSignature = 'PHZD')    {>>> Skyrim <<<}\n      then begin\n        if Supports(GetElementByName('Map Marker'), IwbContainerElementRef, MapMarker) then\n          Rec := MapMarker.RecordBySignature['FULL']\n        else\n          Rec := GetRecordBySignature('NAME');\n        if Assigned(Rec) then\n          Result := Trim(Rec.Value)\n    end else if\n      (GetSignature = 'CELL') then begin\n        if Supports(GetContainer, IwbGroupRecord, GroupRecord) and (GroupRecord.GroupType = 1) then\n          Result := ' '\n        else\n          if Supports(GetRecordBySignature('XCLC'), IwbContainerElementRef, GridCoords) and\n            (GridCoords.ElementCount >= 2) then\n              Result := GridCoords.Elements[0].SortKey[True] + '|' + GridCoords.Elements[1].SortKey[True];\n    end;\nend;\n\nfunction TwbMainRecord.GetEditorID: string;\nvar\n  SelfRef: IwbContainerElementRef;\nbegin\n  SelfRef := Self as IwbContainerElementRef;\n\n  if not ((mrsQuickInitDone in mrStates) or (csInitOnce in cntStates)) then begin\n    if csInit in cntStates then begin\n      Result := '<EditorID not yet available: init still running>';\n      Exit;\n    end;\n    Include(mrStates, mrsQuickInit);\n    Include(cntStates, csInit);\n    try\n      try\n        Init;\n      finally\n        DoReset(True);\n      end;\n    finally\n      Exclude(cntStates, csInit);\n      Exclude(mrStates, mrsQuickInit);\n    end;\n  end;\n\n  Result := mrEditorID;\nend;\n\nfunction TwbMainRecord.GetEditValue: string;\nbegin\n  if wbDisplayLoadOrderFormID then\n    Result := IntToHex64(GetLoadOrderFormID, 8)\n  else\n    Result := IntToHex64(GetFormID, 8);\nend;\n\nfunction TwbMainRecord.GetElementType: TwbElementType;\nbegin\n  Result := etMainRecord;\nend;\n\nfunction TwbMainRecord.GetFixedFormID: Cardinal;\n\n  function MovedHereForSpeed: Cardinal;\n  var\n    MasterCount: Cardinal;\n    _File: IwbFile;\n  begin\n    Result := PwbMainRecordStruct(dcBasePtr).mrsFormID;\n    _File := GetFile;\n    if Assigned(_File) then begin\n      MasterCount := _File.MasterCount;\n      if Result shr 24 > MasterCount then begin\n        Result := (Result and $00FFFFFF) or (MasterCount shl 24);\n      end;\n    end;\n    mrFixedFormID := Result;\n  end;\n\nbegin\n  Result := mrFixedFormID;\n  if Result = 0 then\n    Result := MovedHereForSpeed;\nend;\n\nfunction TwbMainRecord.GetFlags: TwbMainRecordStructFlags;\nbegin\n  Result := mrStruct.mrsFlags;\nend;\n\nfunction TwbMainRecord.GetFlagsPtr: PwbMainRecordStructFlags;\nbegin\n  Result := @mrStruct.mrsFlags;\nend;\n\n\nfunction TwbMainRecord.GetFormID: Cardinal;\nbegin\n  Result := mrStruct.mrsFormID;\nend;\n\nfunction TwbMainRecord.GetFullName: string;\nvar\n  SelfRef: IwbContainerElementRef;\nbegin\n  SelfRef := Self as IwbContainerElementRef;\n\n  if not ((mrsQuickInitDone in mrStates) or (csInitOnce in cntStates)) then begin\n    Include(mrStates, mrsQuickInit);\n    if csInit in cntStates then begin\n      Result := '<FullName not yet available: init still running>';\n      Exit;\n    end;\n    Include(cntStates, csInit);\n    try\n      try\n        Init;\n      finally\n        DoReset(True);\n      end;\n    finally\n      Exclude(cntStates, csInit);\n      Exclude(mrStates, mrsQuickInit);\n    end;\n  end;\n\n  Result := mrFullName;\nend;\n\nfunction TwbMainRecord.GetFormVersion: Cardinal;\nbegin\n  Result := mrStruct.mrsVersion;\nend;\n\nprocedure TwbMainRecord.SetFormVersion(aFormVersion: Cardinal);\nbegin\n  MakeHeaderWriteable;\n  mrStruct.mrsVersion := aFormVersion;\nend;\n\nprocedure TwbMainRecord.ChangeFormSignature(aSignature: TwbSignature);\nbegin\n  MakeHeaderWriteable;\n  mrStruct.mrsSignature := aSignature;\nend;\n\nprocedure TwbMainRecord.ClampFormID(aIndex: Cardinal);\nbegin\n  if mrStruct.mrsFormID shr 24 > aIndex then begin\n    MakeHeaderWriteable;\n    mrStruct.mrsFormID := (mrStruct.mrsFormID and $00FFFFFF) or (aIndex shl 24);\n    if Assigned(mrGroup) then\n      mrGroup.GroupLabel := mrStruct.mrsFormID;\n  end;\nend;\n\nfunction TwbMainRecord.GetGridCell(out aGridCell: TwbGridCell): Boolean;\nvar\n  Signature : TwbSignature;\n  SelfRef   : IwbContainerElementRef;\n  XCLCRec   : IwbContainerElementRef;\nbegin\n  Result := False;\n\n  Signature := GetSignature;\n  if (Signature <> 'CELL') then\n    Exit;\n\n  SelfRef := Self;\n  DoInit;\n\n  if not Supports(GetRecordBySignature('XCLC'), IwbContainerElementRef, XCLCRec) then\n    Exit;\n\n  if XCLCRec.ElementCount < 2 then\n    Exit;\n\n  with aGridCell, XCLCRec do begin\n    X := StrToIntDef(Elements[0].Value, -10000);\n    Y := StrToIntDef(Elements[1].Value, -10000);\n    Result := (x <> -10000) and (y <> -10000);\n  end;\nend;\n\nfunction TwbMainRecord.GetHasMesh: Boolean;\nvar\n  SelfRef  : IwbContainerElementRef;\n  ModelCnt : IwbContainerElementRef;\n  MODL     : IwbContainerElementRef;\n  s        : String;\nbegin\n  if not (mrsHasMeshChecked in mrStates) and Assigned(wbContainerHandler) then begin\n    Include(mrStates, mrsHasMeshChecked);\n    if GetSignature = 'TREE' then begin\n      Include(mrStates, mrsHasMesh);\n    end else begin\n      SelfRef := Self as IwbContainerElementRef;\n      if Supports(GetElementByName('Model'), IwbContainerElementRef, ModelCnt) then\n        if Supports(ModelCnt.RecordBySignature['MODL'], IwbContainerElementRef, MODL) then begin\n          s := Trim(StringReplace(MODL.Value, '/', '\\', [rfReplaceAll]));\n          if s <> '' then begin\n            s := 'meshes\\'+ s;//\n            if Length(wbContainerHandler.OpenResource(s)) > 0 then\n              Include(mrStates, mrsHasMesh);\n          end;\n        end;\n    end;\n  end;\n  Result := mrsHasMesh in mrStates;\nend;\n\nfunction TwbMainRecord.GetHasPrecombinedMesh: Boolean;\nbegin\n  if not (mrsHasPrecombinedMeshChecked in mrStates) then\n    Self.GetPrecombinedMesh;\n\n  Result := mrsHasPrecombinedMesh in mrStates;\nend;\n\ntype\n  TwbPrecombinedInfo = record\n    Ref, ID: Cardinal;\n  end;\n\nvar\n  PrecombinedCacheFileName: string;\n  PrecombinedCacheCellFormID: Cardinal;\n  PrecombinedCache: array of TwbPrecombinedInfo;\n\nfunction TwbMainRecord.GetPrecombinedMesh: string;\nvar\n  Signature   : TwbSignature;\n  SelfRef     : IwbContainerElementRef;\n  Group       : IwbGroupRecord;\n  Cell        : IwbMainRecord;\n  CombinedRefs, CombinedRef: IwbContainerElementRef;\n  cnt, i      : Cardinal;\n  s: string;\nbegin\n  Result := '';\n\n  if not (mrsHasPrecombinedMeshChecked in mrStates) then begin\n\n    // we need file for cache checking\n    if not Assigned(IwbElement(Self)._File) then\n      Exit;\n\n    Include(mrStates, mrsHasPrecombinedMeshChecked);\n    Self.mrPrecombinedCellID := 0;\n    Self.mrPrecombinedID := 0;\n\n    if wbGameMode <> gmFO4 then\n      Exit;\n\n    Signature := Self.GetSignature;\n\n    if (Signature <> 'REFR') and\n       (Signature <> 'PGRE') and\n       (Signature <> 'PMIS') and\n       (Signature <> 'PARW') and\n       (Signature <> 'PBEA') and\n       (Signature <> 'PFLA') and\n       (Signature <> 'PCON') and\n       (Signature <> 'PBAR') and\n       (Signature <> 'PHZD')\n    then\n      Exit;\n\n    SelfRef := Self as IwbContainerElementRef;\n\n    // markers can't be precombined\n    if Cardinal(SelfRef.ElementNativeValues['NAME']) < $800 then\n      Exit;\n\n    if Supports(SelfRef.Container, IwbGroupRecord, Group) then\n      Cell := Group.ChildrenOf;\n\n    if not Assigned(Cell) then\n      Exit;\n\n    s := IwbElement(Self)._File.Name;\n    i := Cell.FormID;\n\n    // store cell's precombined index in cache\n    if (i <> PrecombinedCacheCellFormID) or (s <> PrecombinedCacheFileName) then begin\n      PrecombinedCacheCellFormID := i;\n      PrecombinedCacheFileName := s;\n      SetLength(PrecombinedCache, 0);\n\n      if Supports(Cell.ElementByPath['XCRI\\References'], IwbContainerElementRef, CombinedRefs) then begin\n        cnt := CombinedRefs.ElementCount;\n        SetLength(PrecombinedCache, cnt);\n        for i := 0 to Pred(cnt) do\n          if Supports(CombinedRefs[i], IwbContainerElementRef, CombinedRef) and (CombinedRef.ElementCount = 2) then begin\n            PrecombinedCache[i].Ref := CombinedRef.Elements[0].NativeValue;\n            PrecombinedCache[i].ID := CombinedRef.Elements[1].NativeValue;\n          end;\n      end;\n    end;\n\n    // search for ref in precombined index cache\n    if Length(PrecombinedCache) > 0 then\n      for i := Low(PrecombinedCache) to High(PrecombinedCache) do\n        if PrecombinedCache[i].Ref = Self.GetFormID then begin\n          Self.mrPrecombinedCellID := Cell.FormID and $00FFFFFF;\n          Self.mrPrecombinedID := PrecombinedCache[i].ID;\n          Include(mrStates, mrsHasPrecombinedMesh);\n          Break;\n        end;\n  end;\n\n  if mrsHasPrecombinedMesh in mrStates then\n    Result := 'Precombined\\' + IntToHex(Self.mrPrecombinedCellID, 8) + '_' + IntToHex(Self.mrPrecombinedID, 8) + '_OC.nif';\nend;\n\nfunction TwbMainRecord.GetHasVisibleWhenDistantMesh: Boolean;\nvar\n  SelfRef  : IwbContainerElementRef;\n  ModelCnt : IwbContainerElementRef;\n  MODL     : IwbContainerElementRef;\n  s        : String;\nbegin\n  if not (mrsHasVWDMeshChecked in mrStates) and Assigned(wbContainerHandler) then begin\n    Include(mrStates, mrsHasVWDMeshChecked);\n    if GetSignature = 'TREE' then begin\n      SelfRef := Self as IwbContainerElementRef;\n      if Supports(GetElementByName('Model'), IwbContainerElementRef, ModelCnt) then\n        if Supports(ModelCnt.RecordBySignature['MODL'], IwbContainerElementRef, MODL) then begin\n          s := Trim(StringReplace(MODL.Value, '/', '\\', [rfReplaceAll]));\n          if s <> '' then begin\n            s := 'textures\\trees\\billboards'+ChangeFileExt(s, '.dds');\n            if Length(wbContainerHandler.OpenResource(s)) > 0 then\n              Include(mrStates, mrsHasVWDMesh);\n          end;\n        end;\n    end else begin\n      SelfRef := Self as IwbContainerElementRef;\n      if Supports(GetElementByName('Model'), IwbContainerElementRef, ModelCnt) then\n        if Supports(ModelCnt.RecordBySignature['MODL'], IwbContainerElementRef, MODL) then begin\n          s := Trim(StringReplace(MODL.Value, '/', '\\', [rfReplaceAll]));\n          if s <> '' then begin\n            s := 'meshes\\'+ChangeFileExt(s, '_far.nif');\n            if Length(wbContainerHandler.OpenResource(s)) > 0 then\n              Include(mrStates, mrsHasVWDMesh);\n          end;\n        end;\n    end;\n  end;\n  Result := mrsHasVWDMesh in mrStates;\nend;\n\nfunction TwbMainRecord.GetHighestOverrideOrSelf(aMaxLoadOrder: Integer): IwbMainRecord;\nvar\n  Master : IwbMainRecord;\n  i      : Integer;\nbegin\n  Result := Self;\n  Master := GetMasterOrSelf;\n  for i := Pred(Master.OverrideCount) downto 0 do\n    if Master.Overrides[i]._File.LoadOrder <= aMaxLoadOrder then begin\n      Result := Master.Overrides[i];\n      Exit;\n    end;\nend;\n\nfunction TwbMainRecord.GetInjectionSourceFiles: TDynFiles;\nvar\n  i, j, k : Integer;\n  Rec     : IwbMainRecord;\n  _File : IwbFile;\n  LastID  : Cardinal;\nbegin\n  SetLength(Result, Length(mrReferences));\n  if Length(Result) > 0 then begin\n    _File := GetFile;\n    j := 0;\n    for i := Low(mrReferences) to High(mrReferences) do begin\n      Rec := _File.RecordByFormID[mrReferences[i], True];\n      if Assigned(Rec) then\n        if not _File.Equals(Rec._File) then begin\n          Rec := Rec.MasterOrSelf;\n          if Rec.IsInjected then begin\n            Result[j] := Rec._File;\n            Inc(j);\n          end;\n        end;\n    end;\n    if j > 1 then begin\n      wbMergeSort(@Result[0], j, CompareLoadOrder);\n      k := 1;\n      LastID := Result[0].ElementID;\n      for i := 1 to Pred(j) do\n        if Result[i].ElementID <> LastID then begin\n          LastID := Result[i].ElementID;\n          if k <> i then\n            Result[k] := Result[i];\n          Inc(k);\n        end;\n      SetLength(Result, k);\n    end else\n      SetLength(Result, j);\n  end;\nend;\n\nfunction TwbMainRecord.GetIsCompressed: Boolean;\nbegin\n  Result := GetFlags.IsCompressed;\nend;\n\nfunction TwbMainRecord.GetIsDeleted: Boolean;\nbegin\n  Result := GetFlags.IsDeleted;\nend;\n\nfunction TwbMainRecord.GetIsEditable: Boolean;\nbegin\n  Result := wbIsInternalEdit;\n  if Result then\n    Exit;\n\n  if Assigned(eContainer) and not IwbContainer(eContainer).IsElementEditable(Self) then\n    Exit;\n\n  Result := True;\nend;\n\nfunction TwbMainRecord.GetIsESM: Boolean;\nbegin\n  Result := GetFlags.IsESM;\nend;\n\nfunction TwbMainRecord.GetIsLocalized: Boolean;\nbegin\n  Result := GetFlags.IsLocalized;\nend;\n\nfunction TwbMainRecord.GetIsInitiallyDisabled: Boolean;\nbegin\n  Result := GetFlags.IsInitiallyDisabled;\nend;\n\nfunction TwbMainRecord.GetIsInjected: Boolean;\nbegin\n  if not (mrsIsInjectedChecked in mrStates) then begin\n    if not Assigned(mrMaster) and (mrStruct.mrsFormID <> 0) and( (mrStruct.mrsFormID shr 24) < Cardinal(GetFile.MasterCount) ) and not (fsIsHardcoded in GetFile.FileStates) then\n      Include(mrStates, mrsIsInjected)\n    else\n      Exclude(mrStates, mrsIsInjected);\n    Include(mrStates, mrsIsInjectedChecked);\n  end;\n  Result := mrsIsInjected in mrStates;\nend;\n\nfunction TwbMainRecord.GetIsInList: Boolean;\nbegin\n  with mreHeader do\n    Result := mrehInUse and (mrehGeneration = mreGeneration);\nend;\n\nfunction TwbMainRecord.GetIsMaster: Boolean;\nbegin\n  Result := not Assigned(mrMaster);\nend;\n\nfunction TwbMainRecord.GetIsNotReachable: Boolean;\nvar\n  i: Integer;\nbegin\n  if Assigned(mrMaster) then\n    Result := IwbMainRecord(mrMaster).IsNotReachable\n  else begin\n    Result := inherited GetIsNotReachable;\n    if Result then\n      for i := Low(mrOverrides) to High(mrOverrides) do\n        if not (esNotReachable in mrOverrides[i].ElementStates) then begin\n          Result := False;\n          Exit;\n        end;\n  end;\nend;\n\nfunction TwbMainRecord.GetIsPersistent: Boolean;\nbegin\n  Result := GetFlags.IsPersistent;\nend;\n\nfunction TwbMainRecord.GetIsVisibleWhenDistant: Boolean;\nbegin\n  Result := GetFlags.IsVisibleWhenDistant;\nend;\n\nfunction TwbMainRecord.GetIsWinningOverride: Boolean;\nvar\n  Master: IwbMainRecord;\nbegin\n  if Assigned(mrMaster) then begin\n    Master := IwbMainRecord(mrMaster);\n    Assert(Master.OverrideCount > 0);\n    Result := Equals(Master.Overrides[Pred(Master.OverrideCount)]);\n  end else\n    Result := Length(mrOverrides) < 1;\nend;\n\nfunction TwbMainRecord.GetLoadOrderFormID: Cardinal;\nvar\n  _File   : IwbFile;\n  _Master : IwbFile;\n  FileID  : Cardinal;\nbegin\n  Result := mrLoadOrderFormID;\n  if Result = 0 then begin\n    Result := mrStruct.mrsFormID;\n    if Result = 0 then\n      Exit;\n\n    _File := GetFile;\n    Assert(Assigned(_File));\n\n    FileID := Result shr 24;\n\n    if FileID >= Cardinal(_File.MasterCount) then\n      _Master := _File\n    else\n      _Master := _File.Masters[FileID];\n\n    if _Master.LoadOrder < 0 then\n      raise Exception.CreateFmt('FormID [%s] in file %s refers to master file %s which has not been assigned a global load order', [\n        IntToHex64(Result, 8),\n        _File.FileName,\n        _Master.FileName\n      ]);\n\n    FileID := _Master.LoadOrder;\n\n    Result := (Result and $00FFFFFF) or (FileID shl 24);\n\n    mrLoadOrderFormID := Result;\n  end;\nend;\n\nfunction TwbMainRecord.GetMaster: IwbMainRecord;\nbegin\n  Result := IwbMainRecord(mrMaster);\nend;\n\nfunction TwbMainRecord.GetMasterOrSelf: IwbMainRecord;\nbegin\n  Result := GetMaster;\n  if not Assigned(Result) then\n    Result := Self;\nend;\n\nfunction TwbMainRecord.GetShortName: string;\nvar\n//  Rec: IwbRecord;\n  s : string;\nbegin\n  if wbDisplayShorterNames then begin\n    Result := '';\n\n    s := GetEditorID;\n    if s <> '' then\n      Result := Result + {'<' +} s {+'>'};\n\n    s := GetFullName;\n    if s <> '' then begin\n      if Result <> '' then\n        Result := Result + ' ';\n      Result := Result + '\"' + s +'\"';\n    end;\n\n    if Result <> '' then\n      Result := Result + ' ';\n\n    if wbDisplayLoadOrderFormID then\n      Result := Result + '[' + GetSignature + ':' + IntToHex64(GetLoadOrderFormID, 8) + ']'\n    else\n      Result := Result + '[' + GetSignature + ':' + IntToHex64(mrStruct.mrsFormID, 8) + ']';\n\n  end else begin\n    Result := inherited GetName;\n\n    if Assigned(mrDef) then\n      Result := Result + ' - ' + mrDef.GetName;\n\n    if wbDisplayLoadOrderFormID then\n      Result := Result + ' [' + IntToHex64(GetLoadOrderFormID, 8) + ']'\n    else\n      Result := Result + ' [' + IntToHex64(mrStruct.mrsFormID, 8) + ']';\n\n    s := GetEditorID;\n    if s <> '' then\n      Result := Result + ' <' + s +'>';\n\n    s := GetFullName;\n    if s <> '' then\n      Result := Result + ' \"' + s +'\"';\n\n  end;\nend;\n\nfunction TwbMainRecord.GetName: string;\nvar\n  s : string;\nbegin\n  Result := GetShortName;\n  if Assigned(mrDef) then begin\n    s := Trim(mrDef.AdditionalInfoFor(Self));\n    if s <> '' then\n      Result := Result + ' (' + s + ')';\n  end;\nend;\n\nfunction TwbMainRecord.GetNativeValue: Variant;\nbegin\n  if wbDisplayLoadOrderFormID then\n    Result := GetLoadOrderFormID\n  else\n    Result := GetFormID;\nend;\n\nfunction TwbMainRecord.GetNextEntry: IwbMainRecordEntry;\nbegin\n  Assert(mreHeader.mrehInUse);\n  if mreGeneration = mreHeader.mrehGeneration then\n    Result := IwbMainRecordEntry(mreNext)\n  else\n    Result := nil;\nend;\n\nfunction TwbMainRecord.GetOverride(aIndex: Integer): IwbMainRecord;\nbegin\n  if not mrOverridesSorted then begin\n    wbMergeSort(@mrOverrides[0], Length(mrOverrides), CompareOverrides);\n    mrOverridesSorted := True;\n  end;\n\n  Result := mrOverrides[aIndex];\nend;\n\nfunction TwbMainRecord.GetOverrideCount: Integer;\nbegin\n  Result := Length(mrOverrides);\nend;\n\nfunction TwbMainRecord.GetPosition(out aPosition: TwbVector): Boolean;\nvar\n  Signature : TwbSignature;\n  SelfRef   : IwbContainerElementRef;\n  DataRec   : IwbContainerElementRef;\nbegin\n  Result := False;\n  try\n    Signature := GetSignature;\n    if (Signature <> 'REFR') and\n       (Signature <> 'ACRE') and\n       (Signature <> 'ACHR') and\n       (Signature <> 'PGRE') and\n       (Signature <> 'PMIS') and\n       (Signature <> 'PARW') and {>>> Skyrim <<<}\n       (Signature <> 'PBEA') and {>>> Skyrim <<<}\n       (Signature <> 'PFLA') and {>>> Skyrim <<<}\n       (Signature <> 'PCON') and {>>> Skyrim <<<}\n       (Signature <> 'PBAR') and {>>> Skyrim <<<}\n       (Signature <> 'PHZD')     {>>> Skyrim <<<}\n    then\n      Exit;\n\n    SelfRef := Self;\n    DoInit;\n\n    if not Supports(GetRecordBySignature('DATA'), IwbContainerElementRef, DataRec) then\n      Exit;\n\n    if DataRec.ElementCount <> 2 then\n      Exit;\n\n    with aPosition, (DataRec.Elements[0] as IwbContainerElementRef) do begin\n      if ElementCount <> 3 then\n        Exit;\n\n      X := Elements[0].NativeValue;\n      Y := Elements[1].NativeValue;\n      Z := Elements[2].NativeValue;\n    end;\n  except\n    on E: Exception do begin\n      if Assigned(wbProgressCallback) then\n        wbProgressCallback('Error getting position for \"' + GetName + '\": ' + E.Message);\n      Result := False;\n      Exit;\n    end;\n  end;\n  Result := True;\nend;\n\nfunction TwbMainRecord.GetPrevEntry: IwbMainRecordEntry;\nbegin\n  Assert(mreHeader.mrehInUse);\n  if mreGeneration = mreHeader.mrehGeneration then\n    Result := IwbMainRecordEntry(mrePrev)\n  else\n    Result := nil;\nend;\n\nfunction TwbMainRecord.GetPath: string;\nbegin\n  Result := mrStruct.mrsSignature;\nend;\n\nfunction TwbMainRecord.GetCountedRecordCount: Cardinal;\nbegin\n  Result := 1;\nend;\n\nfunction TwbMainRecord.GetReferencedBy(aIndex: Integer): IwbMainRecord;\nbegin\n  if mrsReferencedByUnsorted in mrStates then\n    SortReferencedBy;\n  Result := mrReferencedBy[aIndex];\nend;\n\nfunction TwbMainRecord.GetReferencedByCount: Integer;\nbegin\n  Result := Length(mrReferencedBy);\nend;\n\nfunction TwbMainRecord.GetReferenceFile: IwbFile;\nvar\n  FileID: Integer;\nbegin\n  Result := GetFile;\n  FileID := mrStruct.mrsFormID shr 24;\n  if FileID < Result.MasterCount then\n    Result := Result.Masters[FileID];\nend;\n\nfunction TwbMainRecord.GetReferencesInjected: Boolean;\nvar\n  i, j    : Integer;\n  _File   : IwbFile;\n  RecFile : IwbFile;\n  Rec     : IwbMainRecord;\n  Found   : Boolean;\nbegin\n  if not (mrsReferencesInjectedChecked in mrStates) and (csRefsBuild in cntStates) then begin\n    Include(mrStates, mrsReferencesInjectedChecked);\n    Exclude(mrStates, mrsReferencesInjected);\n    if Length(mrReferences) > 0 then begin\n      _File := GetFile;\n      for i := Low(mrReferences) to High(mrReferences) do begin\n        Rec := _File.RecordByFormID[mrReferences[i], True];\n        if Assigned(Rec) then begin\n          RecFile := Rec._File;\n          if not _File.Equals(RecFile) then begin\n            Rec := Rec.MasterOrSelf;\n            if Rec.IsInjected then begin\n              Found := False;\n              for j := 0 to Pred(_File.MasterCount) do\n                if _File.Masters[j].Equals(RecFile) then begin\n                  Found := True;\n                  Break;\n                end;\n              if not Found then begin\n                Include(mrStates, mrsReferencesInjected);\n                Break;\n              end;\n            end;\n          end;\n        end;\n      end;\n    end;\n  end;\n  Result := mrsReferencesInjected in mrStates;\nend;\n\nfunction TwbMainRecord.GetRotation(out aRotation: TwbVector): Boolean;\nvar\n  Signature : TwbSignature;\n  SelfRef   : IwbContainerElementRef;\n  DataRec   : IwbContainerElementRef;\nbegin\n  Result := False;\n\n  Signature := GetSignature;\n  if (Signature <> 'REFR') and\n     (Signature <> 'ACRE') and\n     (Signature <> 'ACHR') and\n     (Signature <> 'PGRE') and\n     (Signature <> 'PMIS') and\n     (Signature <> 'PARW') and {>>> Skyrim <<<}\n     (Signature <> 'PBEA') and {>>> Skyrim <<<}\n     (Signature <> 'PFLA') and {>>> Skyrim <<<}\n     (Signature <> 'PCON') and {>>> Skyrim <<<}\n     (Signature <> 'PBAR') and {>>> Skyrim <<<}\n     (Signature <> 'PHZD')     {>>> Skyrim <<<}\n  then\n    Exit;\n\n  SelfRef := Self;\n  DoInit;\n\n  if not Supports(GetRecordBySignature('DATA'), IwbContainerElementRef, DataRec) then\n    Exit;\n\n  if DataRec.ElementCount <> 2 then\n    Exit;\n\n  with aRotation, (DataRec.Elements[1] as IwbContainerElementRef) do begin\n    if ElementCount <> 3 then\n      Exit;\n\n    X := StrToFloatDef(Elements[0].Value, 0);\n    Y := StrToFloatDef(Elements[1].Value, 0);\n    Z := StrToFloatDef(Elements[2].Value, 0);\n  end;\n  Result := True;\nend;\n\nfunction TwbMainRecord.GetScale(out aScale: Single): Boolean;\nvar\n  Signature : TwbSignature;\n  SelfRef   : IwbContainerElementRef;\n  XSclRec   : IwbContainerElementRef;\nbegin\n  Result := False;\n  aScale := 1;\n\n  Signature := GetSignature;\n  if (Signature <> 'REFR') and\n     (Signature <> 'ACRE') and\n     (Signature <> 'ACHR') and\n     (Signature <> 'PGRE') and\n     (Signature <> 'PMIS') and\n     (Signature <> 'PARW') and {>>> Skyrim <<<}\n     (Signature <> 'PBEA') and {>>> Skyrim <<<}\n     (Signature <> 'PFLA') and {>>> Skyrim <<<}\n     (Signature <> 'PCON') and {>>> Skyrim <<<}\n     (Signature <> 'PBAR') and {>>> Skyrim <<<}\n     (Signature <> 'PHZD')     {>>> Skyrim <<<}\n  then\n    Exit;\n\n  SelfRef := Self;\n  DoInit;\n\n  if not Supports(GetRecordBySignature('XSCL'), IwbContainerElementRef, XSclRec) then\n    Exit;\n\n  aScale := StrToFloatDef(XSclRec.Value, 0);\n  Result := True;\nend;\n\nfunction TwbMainRecord.GetSortKeyInternal(aExtended: Boolean): string;\nbegin\n  Result := IntToHex64(mrStruct.mrsFormID, 8);\nend;\n\nfunction TwbMainRecord.GetSortPriority: Integer;\nbegin\n  if (GetSignature = 'ROAD') or (GetSignature = 'LAND') then\n    Result := -2\n  else if (GetSignature = 'CELL') or (GetSignature = 'PGRD') or (GetSignature = 'NAVM') then\n    Result := -1\n  else\n    Result := 0;\nend;\n\nfunction TwbMainRecord.GetValue: string;\nvar\n  Def: IwbDef;\nbegin\n  if wbReportMode then begin\n    Def := GetValueDef;\n    if Assigned(Def) then\n      Def.Used;\n    Def := GetDef;\n    if Assigned(Def) then\n      Def.Used;\n  end;\n  Result := '';\nend;\n\nfunction TwbMainRecord.GetWinningOverride: IwbMainRecord;\nbegin\n  if Assigned(mrMaster) then\n    Result := IwbMainRecord(mrMaster).WinningOverride\n  else\n    if Length(mrOverrides) > 0 then\n      Result := mrOverrides[High(mrOverrides)]\n    else\n      Result := Self;\nend;\n\nprocedure TwbMainRecord.InformStorage(var aBasePtr: Pointer; aEndPtr: Pointer);\nbegin\n  Assert(False);\nend;\n\nprocedure TwbMainRecord.InitDataPtr;\nvar\n  RecordDef : PwbRecordDef;\nbegin\n  if Assigned(dcEndPtr) then begin\n    dcDataBasePtr := Pointer( Cardinal( dcBasePtr ) + wbSizeOfMainRecordStruct );\n    dcDataEndPtr := Pointer( Cardinal( dcDataBasePtr ) + mrStruct.mrsDataSize );\n    dcEndPtr := dcDataEndPtr;\n  end;\n\n  if not Assigned(mrDef) then begin\n    if wbFindRecordDef(PwbSignature(dcBasePtr)^, RecordDef) then\n      mrDef := RecordDef^\n    else begin\n      if Assigned(wbProgressCallback) then\n        wbProgressCallback('Error: unknown record type '+ String(PwbSignature(dcBasePtr)^));\n    end;\n  end;\nend;\n\nprocedure TwbMainRecord.InsertEntryAfter(const aEntry: IwbMainRecordEntry);\nvar\n  Entry: IwbMainRecordEntry;\nbegin\n  Assert(Assigned(aEntry));\n  RemoveEntry;\n  Assert(mreGeneration = -1);\n  with mreHeader do begin\n    Assert(mrehInUse);\n    mreGeneration := mrehGeneration;\n    Entry := Self;\n    mrePrev := Pointer(aEntry);\n    mreNext := Pointer(aEntry.NextEntry);\n    aEntry.NextEntry := Entry;\n    if Assigned(mreNext) then begin\n      Assert( aEntry.Equals(IwbMainRecordEntry(mreNext).PrevEntry) );\n      IwbMainRecordEntry(mreNext).PrevEntry := Entry;\n    end else begin\n      Assert( aEntry.Equals(IwbMainRecordEntry(mrehTail)) );\n      mrehTail := Pointer(Entry);\n    end;\n    Inc(mrehCount);\n  end;\nend;\n\nprocedure TwbMainRecord.InsertEntryHead;\nvar\n  Entry: IwbMainRecordEntry;\nbegin\n  RemoveEntry;\n  Assert(mreGeneration = -1);\n  with mreHeader do begin\n    Assert(mrehInUse);\n    mreGeneration := mrehGeneration;\n    mrePrev := nil;\n    mreNext := mrehHead;\n    Entry := Self;\n    mrehHead := Pointer(Entry);\n    if Assigned(mreNext) then begin\n      Assert(not Assigned(IwbMainRecordEntry(mreNext).PrevEntry));\n      IwbMainRecordEntry(mreNext).PrevEntry := Entry\n    end else begin\n      Assert(not Assigned(mrehTail));\n      mrehTail := Pointer(Entry);\n    end;\n    Inc(mrehCount);\n  end;\nend;\n\nprocedure TwbMainRecord.InsertEntryTail;\nvar\n  Entry: IwbMainRecordEntry;\nbegin\n  RemoveEntry;\n  Assert(mreGeneration = -1);\n  with mreHeader do begin\n    Assert(mrehInUse);\n    mreGeneration := mrehGeneration;\n    mreNext := nil;\n    mrePrev := mrehTail;\n    Entry := Self;\n    mrehTail := Pointer(Entry);\n    if Assigned(mrePrev) then begin\n      Assert(not Assigned(IwbMainRecordEntry(mrePrev).NextEntry));\n      IwbMainRecordEntry(mrePrev).NextEntry := Entry\n    end else begin\n      Assert(not Assigned(mrehHead));\n      mrehHead := Pointer(Entry);\n    end;\n    Inc(mrehCount);\n  end;\nend;\n\nfunction TwbMainRecord.IsElementRemoveable(const aElement: IwbElement): Boolean;\nbegin\n  Result := IsElementEditable(aElement) and not aElement.Def.Required;\nend;\n\nfunction TwbMainRecord.LinksToParent: Boolean;\nvar\n  Signature : TwbSignature;\n  DATA      : IwbRecord;\n  SelfPtr   : IwbContainerElementRef;\n  s         : string;\nbegin\n  Signature := GetSignature;\n\n  if (Signature = 'CELL') then begin\n    Result := True;\n    SelfPtr := Self as IwbContainerElementRef;\n    DATA := GetRecordBySignature('DATA');\n    if Assigned(DATA) then begin\n      s := DATA.EditValue;\n      if (Length(s)>0) and (s[1]='1') then\n        Result := False;\n    end;\n  end else\n    Result :=\n      (Signature = 'INFO') or\n      (Signature = 'REFR') or\n      (Signature = 'PGRE') or\n      (Signature = 'PMIS') or\n      (Signature = 'ACHR') or\n      (Signature = 'ACRE') or\n      (Signature = 'PGRD') or\n      (Signature = 'PARW') or {>>> Skyrim <<<}\n      (Signature = 'PBEA') or {>>> Skyrim <<<}\n      (Signature = 'PFLA') or {>>> Skyrim <<<}\n      (Signature = 'PCON') or {>>> Skyrim <<<}\n      (Signature = 'PBAR') or {>>> Skyrim <<<}\n      (Signature = 'PHZD') or {>>> Skyrim <<<}\n      (Signature = 'NAVM') or\n      (Signature = 'ROAD') or\n      (Signature = 'LAND') or\n      (wbVWDAsQuestChildren and ((Signature = 'DLBR') or (Signature = 'DIAL') or (Signature = 'SCEN')));\nend;\n\nprocedure TwbMainRecord.MakeHeaderWriteable;\nvar\n  p            : PwbMainRecordStruct;\n  BasePtr      : Pointer;\n  SelfPtr      : IwbContainerElementRef;\n  RecordHeader : IwbElement;\nbegin\n  SelfPtr := Self as IwbContainerElementRef;\n\n  DoInit;\n\n  SetModified(True);\n  InvalidateParentStorage;\n\n  if Assigned(dcEndPtr) then begin\n    New(p);\n    Include(mrStates, mrBasePtrAllocated);\n    p^ := mrStruct^;\n    dcBasePtr := p;\n    dcEndPtr := nil;\n\n    RecordHeader := GetElementBySortOrder( (-1) + GetAdditionalElementCount );\n    if Assigned(RecordHeader) then begin\n      BasePtr := p;\n      RecordHeader.InformStorage(BasePtr, Pointer( Cardinal(BasePtr) + wbSizeOfMainRecordStruct ) );\n    end;\n  end;\n\nend;\n\nprocedure TwbMainRecord.MarkModifiedRecursive;\nvar\n  SelfRef : IwbContainerElementRef;\n  Group   : IwbGroupRecord;\nbegin\n  SelfRef := Self as IwbContainerElementRef;\n  DoInit;\n  inherited;\n  Group := GetChildGroup;\n  if Assigned(Group) then\n    Group.MarkModifiedRecursive;\nend;\n\nprocedure TwbMainRecord.MasterCountUpdated(aOld, aNew: Byte);\nvar\n  FileID   : Integer;\n  i        : Integer;\n  FoundOne : Boolean;\n\n  SelfRef  : IwbContainerElementRef;\n//  EditorID : IwbElement;\nbegin\n  mrBaseRecordID := 0;\n  Exclude(mrStates, mrsBaseRecordChecked);\n\n  SelfRef := Self as IwbContainerElementRef;\n  DoInit;\n\n  if mrStruct.mrsFormID <> 0 then begin\n    //Assert(aNew > aOld);\n    FileID := mrStruct.mrsFormID shr 24;\n    if FileID >= aOld then begin\n      FileID := aNew;\n      MakeHeaderWriteable;\n      mrStruct.mrsFormID := (mrStruct.mrsFormID and $00FFFFFF) or (Cardinal(FileID) shl 24);\n      mrFixedFormID := 0;\n      mrLoadOrderFormID := 0;\n      Exclude(mrStates, mrsIsInjectedChecked);\n    end;\n  end;\n\n  if csRefsBuild in cntStates then begin\n\n    FoundOne := False;\n    for i := High(mrReferences) downto Low(mrReferences) do begin\n      FileID := mrReferences[i] shr 24;\n      if FileID < aOld then\n        Break;\n      FoundOne := True;\n\n      FileID := aNew;\n      mrReferences[i] := (mrReferences[i] and $00FFFFFF) or (Cardinal(FileID) shl 24);\n    end;\n\n    if FoundOne then\n      inherited;\n\n  end else\n    inherited;\nend;\n\nprocedure TwbMainRecord.MasterIndicesUpdated(const aOld, aNew: TBytes);\nvar\n  OldFormID: Cardinal;\n  NewFormID: Cardinal;\n  i        : Integer;\n  FoundOne : Boolean;\n\n  SelfRef : IwbContainerElementRef;\nbegin\n  mrBaseRecordID := 0;\n  Exclude(mrStates, mrsBaseRecordChecked);\n\n  SelfRef := Self as IwbContainerElementRef;\n  DoInit;\n\n  if mrStruct.mrsFormID <> 0 then begin\n    OldFormID := mrStruct.mrsFormID;\n    NewFormID := FixupFormID(OldFormID, aOld, aNew);\n    if OldFormID <> NewFormID then begin\n      MakeHeaderWriteable;\n      mrStruct.mrsFormID := NewFormID;\n      mrFixedFormID := 0;\n      mrLoadOrderFormID := 0;\n      Exclude(mrStates, mrsIsInjectedChecked);\n    end;\n  end;\n\n  if csRefsBuild in cntStates then begin\n\n    FoundOne := False;\n    for i := Low(mrReferences) to High(mrReferences) do begin\n      OldFormID := mrReferences[i];\n      NewFormID := FixupFormID(OldFormID, aOld, aNew);\n      if OldFormID <> NewFormID then begin\n        FoundOne := True;\n        mrReferences[i] := NewFormID;\n      end;\n    end;\n\n    if FoundOne then begin\n      wbMergeSort(@mrReferences[0], Length(mrReferences), CompareFormIDs );\n      inherited;\n    end;\n\n  end else\n    inherited;\nend;\n\nfunction TwbMainRecord.MasterRecordsFromMasterFilesAndSelf: TDynMainRecords;\nvar\n  Res     : TDynMainRecords;\n  _File   : IwbFile;\n  Master  : IwbMainRecord;\n  i, j    : Integer;\n\n  function AddRecord(const aRecord: IwbMainRecord): Boolean;\n  var\n    k       : Integer;\n    RecFile : IwbFile;\n  begin\n    Result := Equals(aRecord);\n    if not Result then begin\n      RecFile := aRecord._File;\n\n      Result := _File.Equals(RecFile);\n      if not Result then\n        for k := 0 to Pred(_File.MasterCount) do begin\n          Result := _File.Masters[k].Equals(RecFile);\n          if Result then\n            Break;\n        end;\n      if Result then\n        Result := False\n      else\n        Exit;\n    end;\n\n    Res[i] := aRecord;\n    Inc(i);\n  end;\n\nbegin\n  Result := nil;\n  Res := nil;\n  if Assigned(mrMaster) then begin\n    _File := GetFile;\n    if Assigned(_File) then begin\n      Master := IwbMainRecord(mrMaster);\n      SetLength(Res, Succ(Master.OverrideCount));\n      i := 0;\n      if not AddRecord(Master) then\n        for j := 0 to Pred(Master.OverrideCount) do\n          if AddRecord(Master.Overrides[j]) then\n            break;\n      SetLength(Res, i);\n      if i> 0 then begin\n        Result := Res;\n        Exit;\n      end;\n    end;\n  end;\n  SetLength(Res, 1);\n  Res[0] := Self;\n  Result := Res;\nend;\n\nprocedure TwbMainRecord.MergeStorageInternal(var aBasePtr: Pointer; aEndPtr: Pointer);\nbegin\n  Assert(False);\nend;\n\nfunction TwbMainRecord.mrStruct: PwbMainRecordStruct;\nbegin\n  Result := PwbMainRecordStruct(dcBasePtr);\nend;\n\nprocedure TwbMainRecord.PrepareSave;\nvar\n  _File       : IwbFile;\n  GroupRecord : IwbGroupRecord;\nbegin\n  if GetSignature = wbHeaderSignature then begin\n    if not Supports(GetContainer, IwbFile, _File) then\n      raise Exception.Create('File Header record '+GetName+' must be contained directly in the file.');\n    if GetFormID <> 0 then\n      raise Exception.Create('File Header record '+GetName+' can not have a FormID.');\n  end else begin\n    if GetFormID = 0 then\n      raise Exception.Create('Record '+GetName+' must have a FormID.');\n    if not Supports(GetContainer, IwbGroupRecord, GroupRecord) then\n      raise Exception.Create('Record '+GetName+' is not contained in a group.');\n    case GroupRecord.GroupType of\n      0: begin {top level}\n        if TwbSignature(GroupRecord.GroupLabel) <> GetSignature then\n          raise Exception.Create('Record ' + GetName + ' can not be contained in ' + GroupRecord.Name);\n      end;\n      1: begin {World Children}\n        if (GetSignature <> 'CELL') and (GetSignature <> 'ROAD') then\n          raise Exception.Create('Record ' + GetName + ' can not be contained in ' + GroupRecord.Name);\n      end;\n      2, 4, 6: begin {interior and exterior block and cell children}\n        raise Exception.Create('Record ' + GetName + ' can not be contained in ' + GroupRecord.Name);\n      end;\n      3, 5: begin {interior and exterior sub-block}\n        if (GetSignature <> 'CELL') then\n          raise Exception.Create('Record ' + GetName + ' can not be contained in ' + GroupRecord.Name);\n      end;\n      7: begin {topic children}\n        if (GetSignature <> 'INFO') then\n          raise Exception.Create('Record ' + GetName + ' can not be contained in ' + GroupRecord.Name);\n      end;\n      8, 10: begin {Persistent and Visible when Distant/Quest Children}\n        if (GetSignature <> 'REFR') and\n           (GetSignature <> 'ACHR') and\n           (GetSignature <> 'ACRE') and\n           (GetSignature <> 'PGRE') and\n           (GetSignature <> 'PMIS') and\n           (GetSignature <> 'PARW') and {>>> Skyrim <<<}\n           (GetSignature <> 'PBEA') and {>>> Skyrim <<<}\n           (GetSignature <> 'PFLA') and {>>> Skyrim <<<}\n           (GetSignature <> 'PCON') and {>>> Skyrim <<<}\n           (GetSignature <> 'PBAR') and {>>> Skyrim <<<}\n           (GetSignature <> 'PHZD')     {>>> Skyrim <<<}\n        then\n          if not (wbVWDAsQuestChildren and ((GetSignature = 'DLBR') or (GetSignature = 'DIAL') or (GetSignature = 'SCEN'))) then\n            raise Exception.Create('Record ' + GetName + ' can not be contained in ' + GroupRecord.Name);\n\n        case GroupRecord.GroupType of\n          8:begin\n            if not mrStruct.mrsFlags.IsPersistent then\n              raise Exception.Create('Record ' + GetName + ' needs to have it''s Persistent flag set to be contained in ' + GroupRecord.Name);\n          end;\n          10: if not wbVWDAsQuestChildren then begin\n            if not mrStruct.mrsFlags.IsVisibleWhenDistant then\n              raise Exception.Create('Record ' + GetName + ' needs to have it''s Visible when Distant flag set to be contained in ' + GroupRecord.Name);\n            if mrStruct.mrsFlags.IsPersistent then\n              raise Exception.Create('Record ' + GetName + ' can not have it''s Persistent flag set to be contained in ' + GroupRecord.Name);\n          end;\n        end;\n      end;\n      9: begin {Temporary}\n        if (GetSignature <> 'REFR') and\n           (GetSignature <> 'ACHR') and\n           (GetSignature <> 'ACRE') and\n           (GetSignature <> 'LAND') and\n           (GetSignature <> 'PGRD') and\n           (GetSignature <> 'NAVM') and\n           (GetSignature <> 'PGRE') and\n           (GetSignature <> 'PMIS') and\n           (GetSignature <> 'PARW') and {>>> Skyrim <<<}\n           (GetSignature <> 'PBEA') and {>>> Skyrim <<<}\n           (GetSignature <> 'PFLA') and {>>> Skyrim <<<}\n           (GetSignature <> 'PCON') and {>>> Skyrim <<<}\n           (GetSignature <> 'PBAR') and {>>> Skyrim <<<}\n           (GetSignature <> 'PHZD')     {>>> Skyrim <<<}\n        then\n          raise Exception.Create('Record ' + GetName + ' can not be contained in ' + GroupRecord.Name);\n        if mrStruct.mrsFlags.IsPersistent then\n          raise Exception.Create('Record ' + GetName + ' can not have it''s Persistent flag set to be contained in ' + GroupRecord.Name);\n        if mrStruct.mrsFlags.IsVisibleWhenDistant and not wbVWDInTemporary then\n          raise Exception.Create('Record ' + GetName + ' can not have it''s Visible when Distant flag set to be contained in ' + GroupRecord.Name);\n      end;\n    end;\n  end;\n\n  if GetIsDeleted and (GetDataSize > 0) then begin\n    GetDataSize;\n    Delete;\n  end;\n\n  //not needed for now\n  inherited;\nend;\n\nfunction TwbMainRecord.Reached: Boolean;\nvar\n  Signature : TwbSignature;\n  i         : Integer;\n  IsComplex : Boolean;\n{\n  _File     : IwbFile;\n  Rec       : IwbMainRecord;\n}\n\n  SelfRef   : IwbContainerElementRef;\nbegin\n  if esReachable in eStates then\n    Exit(False);\n\n  SelfRef := Self as IwbContainerElementRef;\n  DoInit;\n\n  Signature := GetSignature;\n  IsComplex := (Signature = 'DIAL') or (Signature = 'WRLD') or (Signature = 'CELL');\n  if GetIsWinningOverride or IsComplex then begin\n    {if csRefsBuild in cntStates then begin\n      Result := esNotReachable in eStates;\n      Exclude(eStates, esNotReachable);\n      if Result and (Length(mrReferences) > 0) then begin\n        _File := GetFile;\n        for i := Low(mrReferences) to High(mrReferences) do begin\n          Rec := _File.RecordByFormID[mrReferences[i], True];\n          if Assigned(Rec) then\n            (Rec as IwbElementInternal).Reached;\n        end;\n      end;\n      if LinksToParent then begin\n        if Assigned(eContainer) then\n          (IwbContainer(eContainer) as IwbElementInternal).Reached;\n        Exit;\n      end;\n    end else}\n    Result := inherited Reached;\n\n    if Result then begin\n      if not Assigned(eContainer) then\n        Exit;\n      if LinksToParent then\n        Exit;\n      if not IsComplex then\n        Exit;\n\n      if Assigned(mrMaster) then\n        (IwbMainRecord(mrMaster) as IwbElementInternal).Reached\n      else\n        for i := 0 to Pred(GetOverrideCount) do\n          (GetOverride(i) as IwbElementInternal).Reached;\n\n      if Assigned(mrGroup) then\n        (mrGroup as IwbElementInternal).Reached;\n    end;\n  end else\n    Result := (GetWinningOverride as IwbElementInternal).Reached;\nend;\n\nprocedure TwbMainRecord.Remove;\nvar\n  _File: IwbFileInternal;\nbegin\n  DoBuildRef(True);\n\n  _File := GetFile as IwbFileInternal;\n  if Assigned(_File) then\n    _File.RemoveMainRecord(Self);\n\n  if Assigned(mrMaster) then\n    (IwbMainRecord(mrMaster) as IwbMainRecordInternal).RemoveOverride(Self)\n  else\n    if Length(mrOverrides) > 0 then\n      (mrOverrides[0] as IwbMainRecordInternal).YouAreTheMaster(mrOverrides, mrReferencedBy);\n\n  mrMaster := nil;\n  mrOverrides := nil;\n  mrReferencedBy := nil;\n  mrFixedFormID := 0;\n  mrLoadOrderFormID := 0;\n  Exclude(mrStates, mrsIsInjectedChecked);\n  mrConflictAll := caUnknown;\n  mrConflictThis := ctUnknown;\n\n  inherited;\nend;\n\nprocedure TwbMainRecord.RemoveChildGroup(const aGroup: IwbGroupRecord);\nbegin\n  if Assigned(mrGroup) and mrGroup.Equals(aGroup) then begin\n    mrGroup := nil;\n    Exclude(mrStates, mrsSearchedChildGroup);\n  end;\nend;\n\nfunction TwbMainRecord.RemoveElement(aPos: Integer; aMarkModified: Boolean = False): IwbElement;\nbegin\n  Result := inherited RemoveElement(aPos, aMarkModified);\n  if Assigned(Result) and (Result.ElementType = etSubRecord) then\n    with (Result as IwbSubRecord) do begin\n      if Signature = 'EDID' then\n        mrEditorID := ''\n      else if Signature = 'FULL' then begin\n        if (mrFullName <> '') and (Value = mrFullName) then\n          mrFullName := '';\n      end else if Signature = 'NAME' then\n        Exclude(mrStates, mrsBaseRecordChecked);\n    end;\nend;\n\nprocedure TwbMainRecord.RemoveEntry;\nvar\n  Entry : IwbMainRecordEntry;\n  i     : Integer;\nbegin\n  if Supports(IInterface(mrMaster), IwbMainRecordEntry, Entry) then\n    Entry.RemoveEntry\n  else begin\n    RemoveEntryInternal;\n    for i := Low(mrOverrides) to High(mrOverrides) do\n    if Supports(mrOverrides[i], IwbMainRecordEntry, Entry) then\n      Entry.RemoveEntryInternal;\n  end;\nend;\n\nprocedure TwbMainRecord.RemoveEntryInternal;\nbegin\n  with mreHeader do begin\n    Assert(mrehInUse);\n    if mreGeneration = mrehGeneration then begin\n      if Assigned(mrePrev) then\n        IwbMainRecordEntry(mrePrev).NextEntry := IwbMainRecordEntry(mreNext)\n      else begin\n        Assert(Equals(IwbMainRecordEntry(mrehHead)));\n        mrehHead := mreNext;\n      end;\n\n      if Assigned(mreNext) then\n        IwbMainRecordEntry(mreNext).PrevEntry := IwbMainRecordEntry(mrePrev)\n      else begin\n        Assert(Equals(IwbMainRecordEntry(mrehTail)));\n        mrehTail := mrePrev;\n      end;\n      Dec(mrehCount);\n    end;\n    mrePrev := nil;\n    mreNext := nil;\n    mreGeneration := -1;\n  end;\nend;\n\nfunction TwbMainRecord.RemoveInjected(aCanRemove: Boolean): Boolean;\nvar\n  i         : Integer;\n  SelfRef   : IwbContainerElementRef;\n  Element   : IwbElement;\nbegin\n  SelfRef := Self as IwbContainerElementRef;\n  DoInit;\n\n  Result := False;\n  if GetReferencesInjected then begin\n    if GetSignature = 'SCPT' then begin\n      Element := GetElementByName('References');\n      if Assigned(Element) then\n        Element.Remove;\n      Element := GetRecordBySignature('SCDA');\n      if Assigned(Element) then\n        Element.EditValue := '1D 00 00 00';\n      Element := GetRecordBySignature('SCHR');\n      if Assigned(Element) then with (Element as IwbContainerElementRef) do begin\n        ElementByName['RefCount'].EditValue := '0';\n        ElementByName['CompiledSize'].EditValue := '4';\n      end;\n      Element := GetRecordBySignature('SCTX');\n      if Assigned(Element) then\n        with TStringList.Create do try\n          Text := Element.EditValue;\n          for i := 0 to Pred(Count) do\n            if StartsWith(Trim(Strings[i]), 'begin') then begin\n              while i <= Count do\n                Delete(Pred(Count));\n              Break;\n            end;\n          Element.EditValue := Text;\n        finally\n          Free;\n        end;\n    end else begin\n      for i := High(cntElements) downto Low(cntElements) do\n        if cntElements[i].CanContainFormIDs then begin\n          Result := cntElements[i].RemoveInjected(True) or Result;\n          if Result and aCanRemove then\n            Break;\n        end;\n    end;\n  end;\n  Exclude(mrStates, mrsReferencesInjectedChecked);\n  if Result and aCanRemove and GetIsRemoveable then begin\n    Result := False;\n    Remove;\n  end;\nend;\n\nprocedure TwbMainRecord.RemoveOverride(const aMainRecord: IwbMainRecord);\nvar\n  i,j: Integer;\nbegin\n  j := 0;\n  for i := Low(mrOverrides) to High(mrOverrides) do begin\n    if (mrOverrides[i] as IwbElement) <> (aMainRecord as IwbElement) then begin\n      if i <> j then\n        mrOverrides[j] := mrOverrides[i];\n      Inc(j);\n    end;\n  end;\n  SetLength(mrOverrides, j);\nend;\n\nprocedure TwbMainRecord.RemoveReferencedBy(aMainRecord: IwbMainRecord);\nvar\n  i: Integer;\nbegin\n  if mrsReferencedByUnsorted in mrStates then\n    SortReferencedBy;\n\n  if FindReferencedBy(aMainRecord, i) then begin\n    mrReferencedBy[i] := nil;\n    if i < High(mrReferencedBy) then begin\n      Move(mrReferencedBy[Succ(i)], mrReferencedBy[i], SizeOf(Pointer) * (High(mrReferencedBy) - i));\n      Pointer(mrReferencedBy[High(mrReferencedBy)]) := nil;\n    end;\n    SetLength(mrReferencedBy, Pred(Length(mrReferencedBy)));\n  end;\nend;\n\nprocedure TwbMainRecord.ReportRequiredMasters(aStrings: TStrings; aAsNew: Boolean; Recursive: Boolean = True; Initial: Boolean = false);\nvar\n  _File: IwbFile;\nbegin\n  if not aAsNew then begin\n    _File := GetReferenceFile;\n    aStrings.AddObject(_File.FileName, Pointer(_File));\n  end;\n  inherited;\nend;\n\nprocedure TwbMainRecord.Reset;\nbegin\n  ReleaseElements;\n  mrDataStorage := nil;\n  InitDataPtr;\n  inherited;\nend;\n\nprocedure TwbMainRecord.ResetConflict;\nvar\n  i: Integer;\nbegin\n  inherited;\n  if Assigned(mrMaster) then\n    IwbElement(mrMaster).ResetConflict\n  else begin\n    mrConflictAll := caUnknown;\n    mrConflictThis := ctUnknown;\n    for i := Low(mrOverrides) to High(mrOverrides) do\n      with mrOverrides[i] do begin\n        ConflictAll := caUnknown;\n        ConflictThis := ctUnknown;\n      end;\n  end;\nend;\n\nprocedure TwbMainRecord.ResetReachable;\nbegin\n  Include(eStates, esNotReachable);\n  Exclude(eStates, esReachable);\nend;\n\nfunction TwbMainRecord.ResolveElementName(aName: string; out aRemainingName: string; aCanCreate: Boolean): IwbElement;\nvar\n  i: Integer;\nbegin\n  Result := inherited ResolveElementName(aName, aRemainingName, aCanCreate);\n  if not Assigned(Result) and aCanCreate and Assigned(mrDef) and (Length(aName) = 4) then begin\n    i := mrDef.GetMemberIndexFor(StrToSignature(aName), nil);\n    if i < 0 then\n      Exit;\n    Assign(i, nil, False);\n    Result := GetElementBySignature(StrToSignature(aName));\n  end;\nend;\n\nprocedure TwbMainRecord.ScanData;\nvar\n  SelfRef : IwbContainerElementRef;\nbegin\n  if not wbDelayLoadRecords then begin\n    SelfRef := Self as IwbContainerElementRef;\n    DoInit;\n  end;\nend;\n\nprocedure TwbMainRecord.SetChildGroup(const aGroup: IwbGroupRecord);\nbegin\n  if Pointer(mrGroup) = Pointer(aGroup) then\n    Exit;\n\n  if Assigned(aGroup) then begin\n    if not (not Assigned(mrGroup) or (mrGroup.Equals(aGroup))) then begin\n      if not (not Assigned(mrGroup) or (mrGroup.Equals(aGroup))) then\n        Assert(not Assigned(mrGroup) or (mrGroup.Equals(aGroup)), 'Found additional ' + mrGroup.Name + ' for ' + Self.GetName);\n    end;\n    if Assigned(eContainer) then\n      IwbContainer(eContainer).Equals(aGroup.Container);\n  end else\n    Assert(Assigned(mrGroup));\n  mrGroup := aGroup;\nend;\n\nprocedure TwbMainRecord.SetConflictAll(aValue: TConflictAll);\nbegin\n  mrConflictAll := aValue;\nend;\n\nprocedure TwbMainRecord.SetConflictThis(aValue: TConflictThis);\nbegin\n  mrConflictThis := aValue;\nend;\n\nprocedure TwbMainRecord.SetContainer(const aContainer: IwbContainer);\nvar\n  ContainedIn: IwbContainedIn;\nbegin\n  inherited;\n  if csInit in cntStates then\n    if Supports(GetElementBySortOrder(-2 + GetAdditionalElementCount), IwbContainedIn, ContainedIn) then\n      ContainedIn.ContainerChanged;\nend;\n\nprocedure TwbMainRecord.SetEditorID(const aValue: string);\nvar\n  SelfRef : IwbContainerElementRef;\n  Rec     : IwbRecord;\n  i       : Integer;\nbegin\n  if not Assigned(mrDef) then\n    Exit;\n\n  if aValue = GetEditorID then\n    Exit;\n\n  SelfRef := Self as IwbContainerElementRef;\n  DoInit;\n\n  Rec := GetRecordBySignature('EDID');\n  if not Assigned(Rec) then begin\n    i := mrDef.GetMemberIndexFor('EDID', nil);\n    if i < 0 then\n      Exit;\n    Assign(i, nil, False);\n    Rec := GetRecordBySignature('EDID');\n    Assert(Assigned(Rec));\n  end;\n\n  if aValue = '' then\n    Rec.Remove\n  else\n    Rec.EditValue := aValue;\n\n  Assert(mrEditorID = aValue);\nend;\n\nprocedure TwbMainRecord.SetEditValue(const aValue: string);\nbegin\n  if not wbEditAllowed then\n    raise Exception.Create(GetName + ' can not be edited.');\n\n  if wbDisplayLoadOrderFormID then begin\n    SetLoadOrderFormID(StrToInt64('$'+aValue));\n    NotifyChanged(eContainer);\n  end else\n    raise Exception.Create('FormID can only be edited if wbDisplayLoadOrderFormID is active');\nend;\n\nprocedure TwbMainRecord.SetIsCompressed(aValue: Boolean);\nbegin\n  if aValue <> GetIsCompressed then begin\n    MakeHeaderWriteable;\n    GetFlagsPtr.SetCompressed(aValue);\n  end;\nend;\n\nprocedure TwbMainRecord.SetIsDeleted(aValue: Boolean);\nvar\n  SelfRef     : IwbContainerElementRef;\n  i, j        : Integer;\n  BasePtr     : Pointer;\n  GroupRecord : IwbGroupRecord;\n  Master      : IwbMainRecord;\n  MainRecord  : IwbMainRecord;\n  SelfIndex   : Integer;\n  _File       : IwbFile;\nbegin\n  if aValue <> GetIsDeleted then begin\n    if aValue then\n      Delete\n    else begin\n      SelfRef := Self;\n      DoInit;\n\n      SetModified(True);\n      InvalidateStorage;\n      ReleaseElements;\n\n      MakeHeaderWriteable;\n      GetFlagsPtr.SetDeleted(False);\n\n      if Supports(Self.GetContainer, IwbGroupRecord, GroupRecord) then\n        if wbCreateContainedIn and (GroupRecord.GroupType in [1, 4..10]) then\n          with TwbContainedInElement.Create(Self) do begin\n            _AddRef; _Release;\n          end;\n      GroupRecord := nil;\n\n      BasePtr := dcBasePtr;\n      with TwbRecordHeaderStruct.Create(Self, BasePtr, Pointer( Cardinal(BasePtr) + wbSizeOfMainRecordStruct), mrDef.RecordHeaderStruct, '') do begin\n        Include(dcFlags, dcfDontSave);\n        SetSortOrder(-1);\n        SetMemoryOrder(Low(Integer));\n        _AddRef; _Release;\n      end;\n\n      for i := 0 to Pred(mrDef.MemberCount) do\n        if mrDef.Members[i].Required then\n          Assign(i, nil, False);\n\n      Master := GetMaster;\n\n      if not Assigned(Master) then\n        Exit;\n\n      _File := GetFile;\n\n      SelfIndex := -1;\n      for i := 0 to Pred(Master.OverrideCount) do\n        if Equals(Master.Overrides[i]) then begin\n          SelfIndex := i;\n          Break;\n        end;\n\n      for i := Pred(SelfIndex) downto 0 do begin\n        MainRecord := Master.Overrides[i];\n        if not MainRecord.IsDeleted then begin\n          for j := Pred(_File.MasterCount) downto 0 do\n            if MainRecord._File.Equals(_File.Masters[j]) then begin\n              Self.Assign(Low(Integer), MainRecord, False);\n              Exit;\n            end;\n        end;\n      end;\n\n      if not Master.IsDeleted then\n        Self.Assign(Low(Integer), Master, False);\n\n    end;\n  end;\nend;\n\nprocedure TwbMainRecord.SetIsESM(aValue: Boolean);\nbegin\n  if aValue <> GetIsESM then begin\n    MakeHeaderWriteable;\n    GetFlagsPtr.SetESM(aValue);\n  end;\nend;\n\nprocedure TwbMainRecord.SetIsLocalized(aValue: Boolean);\nbegin\n  if aValue <> GetIsLocalized then begin\n    MakeHeaderWriteable;\n    GetFlagsPtr.SetLocalized(aValue);\n  end;\nend;\n\nprocedure TwbMainRecord.SetIsInitiallyDisabled(aValue: Boolean);\nbegin\n  if aValue <> GetIsInitiallyDisabled then begin\n    MakeHeaderWriteable;\n    GetFlagsPtr.SetInitiallyDisabled(aValue);\n  end;\nend;\n\nprocedure TwbMainRecord.SetIsPersistent(aValue: Boolean);\nvar\n  NeedUpdate: Boolean;\nbegin\n  if aValue <> GetIsPersistent then begin\n    NeedUpdate := CheckChildOfCell;\n    MakeHeaderWriteable;\n    GetFlagsPtr.SetPersistent(aValue);\n    if NeedUpdate then\n      UpdateCellChildGroup;\n  end;\nend;\n\nprocedure TwbMainRecord.SetIsVisibleWhenDistant(aValue: Boolean);\nvar\n  NeedUpdate: Boolean;\nbegin\n  if aValue <> GetIsVisibleWhenDistant then begin\n    NeedUpdate := CheckChildOfCell;\n    MakeHeaderWriteable;\n    GetFlagsPtr.SetVisibleWhenDistant(aValue);\n    if NeedUpdate then\n      UpdateCellChildGroup;\n  end;\nend;\n\nprocedure TwbMainRecord.SetLoadOrderFormID(aFormID: Cardinal);\nvar\n  _File: IwbFileInternal;\n  FileID: Integer;\n  NewFileID: Integer;\n  i : Integer;\n  Master: IwbMainRecord;\nbegin\n  if GetLoadOrderFormID = aFormID then\n    Exit;\n\n  _File := GetFile as IwbFileInternal;\n\n  FileID := aFormID shr 24;\n  NewFileID := -1;\n\n  if FileID = _File.LoadOrder then\n    NewFileID := _File.MasterCount\n  else begin\n    for i := 0 to Pred(_File.MasterCount) do\n      if _File.Masters[i].LoadOrder = FileID then begin\n        NewFileID := i;\n        Break;\n      end;\n  end;\n\n  if NewFileID < 0 then\n    raise Exception.Create('FormID ['+IntToHex64(aFormID, 8)+'] belongs to a file that is not available as master to records in ' + _File.Name);\n\n  aFormID := (aFormID and $00FFFFFF) or (Cardinal(NewFileID) shl 24);\n\n  if (GetFormID and $00FFFFFF) = (aFormID and $00FFFFFF) then\n    if ((GetFormID shr 24) >= Cardinal(_File.MasterCount)) and ((aFormID shr 24) >= Cardinal(_File.MasterCount)) then begin\n      // we can do this relatively quietly and quickly...\n\n      if Assigned(mrGroup) then\n        Assert(mrGroup.GroupLabel = mrStruct.mrsFormID);\n      MakeHeaderWriteable;\n      mrStruct.mrsFormID := aFormID;\n      if Assigned(mrGroup) then\n        mrGroup.GroupLabel := aFormID;\n      UpdateInteriorCellGroup;\n      Exit;\n    end;\n\n  Master := _File.RecordByFormID[aFormID, False];\n  if Assigned(Master) and ((Master._File as IwbFileInternal) = _File) then\n    raise Exception.Create('FormID ['+IntToHex64(aFormID, 8)+'] is already present in file ' + _File.Name);\n\n  _File.RemoveMainRecord(Self);\n\n  if Assigned(mrMaster) then\n    (IwbMainRecord(mrMaster) as IwbMainRecordInternal).RemoveOverride(Self)\n  else\n    if Length(mrOverrides) > 0 then\n      (mrOverrides[0] as IwbMainRecordInternal).YouAreTheMaster(mrOverrides, mrReferencedBy);\n\n  mrMaster := nil;\n  mrOverrides := nil;\n  mrReferencedBy := nil;\n  mrFixedFormID := 0;\n  mrLoadOrderFormID := 0;\n  Exclude(mrStates, mrsIsInjectedChecked);\n  mrConflictAll := caUnknown;\n  mrConflictThis := ctUnknown;\n\n  if Assigned(mrGroup) then\n    Assert(mrGroup.GroupLabel = mrStruct.mrsFormID);\n  MakeHeaderWriteable;\n  mrStruct.mrsFormID := aFormID;\n  if Assigned(mrGroup) then\n    mrGroup.GroupLabel := aFormID;\n  UpdateInteriorCellGroup;\n\n  _File.AddMainRecord(Self);\nend;\n\nprocedure TwbMainRecord.SetMaster(const aMaster: IwbMainRecord);\nbegin\n  mrMaster := Pointer(aMaster);\n  if Assigned(mrMaster) then begin\n    Include(mrStates, mrsIsInjectedChecked);\n    Exclude(mrStates, mrsIsInjected);\n  end else\n    Exclude(mrStates, mrsIsInjectedChecked);\nend;\n\nprocedure TwbMainRecord.SetNativeValue(const aValue: Variant);\nbegin\n  if not wbEditAllowed then\n    raise Exception.Create(GetName + ' can not be edited.');\n\n  if wbDisplayLoadOrderFormID then begin\n    SetLoadOrderFormID(aValue);\n    NotifyChanged(eContainer);\n  end else\n    raise Exception.Create('FormID can only be edited if wbDisplayLoadOrderFormID is active');\nend;\n\nprocedure TwbMainRecord.SetNextEntry(const aEntry: IwbMainRecordEntry);\nbegin\n  Assert(mreHeader.mrehInUse);\n  Assert(mreGeneration = mreHeader.mrehGeneration);\n  mreNext := Pointer(aEntry);\nend;\n\nfunction TwbMainRecord.SetPosition(const aPosition: TwbVector): Boolean;\nvar\n  Signature : TwbSignature;\n  SelfRef   : IwbContainerElementRef;\n  DataRec   : IwbContainerElementRef;\nbegin\n  Result := False;\n\n  Signature := GetSignature;\n  if (Signature <> 'REFR') and\n     (Signature <> 'ACRE') and\n     (Signature <> 'ACHR') and\n     (Signature <> 'PGRE') and\n     (Signature <> 'PMIS') and\n     (Signature <> 'PARW') and {>>> Skyrim <<<}\n     (Signature <> 'PBEA') and {>>> Skyrim <<<}\n     (Signature <> 'PFLA') and {>>> Skyrim <<<}\n     (Signature <> 'PCON') and {>>> Skyrim <<<}\n     (Signature <> 'PBAR') and {>>> Skyrim <<<}\n     (Signature <> 'PHZD')     {>>> Skyrim <<<}\n  then\n    Exit;\n\n  SelfRef := Self;\n  DoInit;\n\n  if not Supports(GetRecordBySignature('DATA'), IwbContainerElementRef, DataRec) then\n    Exit;\n\n  if DataRec.ElementCount <> 2 then\n    Exit;\n\n  with aPosition, (DataRec.Elements[0] as IwbContainerElementRef) do begin\n    if ElementCount <> 3 then\n      Exit;\n\n    Elements[0].NativeValue := X;\n    Elements[1].NativeValue := Y;\n    Elements[2].NativeValue := Z;\n  end;\n  Result := True;\nend;\n\nprocedure TwbMainRecord.SetPrevEntry(const aEntry: IwbMainRecordEntry);\nbegin\n  Assert(mreHeader.mrehInUse);\n  Assert(mreGeneration = mreHeader.mrehGeneration);\n  mrePrev := Pointer(aEntry);\nend;\n\nprocedure TwbMainRecord.SetReferencesInjected(aValue: Boolean);\nbegin\n  if aValue then begin\n    Include(mrStates, mrsReferencesInjectedChecked);\n    Include(mrStates, mrsReferencesInjected);\n  end else begin\n    Exclude(mrStates, mrsReferencesInjectedChecked);\n    Exclude(mrStates, mrsReferencesInjected);\n  end;\nend;\n\nfunction CompareReferencedByFile(Item1, Item2: Pointer): Integer;\nbegin\n  Result := CmpW32(IwbMainRecord(Item1)._File.LoadOrder, IwbMainRecord(Item2)._File.LoadOrder);\nend;\n\nfunction CompareReferencedBy(Item1, Item2: Pointer): Integer;\nbegin\n  Result := CmpW32(IwbMainRecord(Item1).LoadOrderFormID , IwbMainRecord(Item2).LoadOrderFormID);\n  if Result = 0 then\n    Result := CompareReferencedByFile(Item1, Item2);\nend;\n\nprocedure TwbMainRecord.SortReferencedBy;\nbegin\n  Exclude(mrStates, mrsReferencedByUnsorted);\n  if Length(mrReferencedBy) > 1  then\n    wbMergeSort(@mrReferencedBy[0], Length(mrReferencedBy), CompareReferencedBy);\nend;\n\nprocedure TwbMainRecord.UpdateCellChildGroup;\nvar\n  OldTypeGroup      : IwbGroupRecord;\n  OldChildGroup     : IwbGroupRecord;\n  OldCellOwnerGroup : IwbGroupRecord;\n  NewTypeGroup      : IwbGroupRecord;\n  TempGroup         : IwbGroupRecord;\n  TempGroup2        : IwbGroupRecord;\n  NewChildGroup     : IwbGroupRecord;\n  NewCellOwnerGroup : IwbGroupRecord;\n  CorrectGroupType  : Integer;\n  i                 : Integer;\n  OldCell           : IwbMainRecord;\n  NewCell           : IwbMainRecord;\n  Worldspace        : IwbMainRecord;\n  IsExterior        : Boolean;\n  SelfRef           : IwbElement;\n  Position          : TwbVector;\n  GridCell          : TwbGridCell;\n  SubBlock          : TwbGridCell;\n  Block             : TwbGridCell;\n  TempGridCell      : TwbGridCell;\n  SubBlockLabel     : Cardinal;\n  BlockLabel        : Cardinal;\nbegin\n  SelfRef := Self as IwbElement;\n\n  if not Supports(GetContainer, IwbGroupRecord, OldTypeGroup) then\n    raise Exception.Create(GetName + ' is not contained in a group.');\n  if not (OldTypeGroup.GroupType in [8, 9, 10]) then\n    raise Exception.Create(GetName + ' is not contained in a group of type \"Cell Persistent Childen\", \"Cell Temporary Children\" or \"Cell Visible Distant Children\"');\n  if not Supports(OldTypeGroup.Container, IwbGroupRecord, OldChildGroup) then\n    raise Exception.Create(OldTypeGroup.GetName + ' is not contained in a group');\n  if not (OldChildGroup.GroupType in [6]) then\n    raise Exception.Create(OldTypeGroup.GetName + ' is not contained in a group of type \"Cell Children\"');\n\n  if GetIsPersistent then\n    CorrectGroupType := 8\n  else if GetIsVisibleWhenDistant and not wbVWDInTemporary then\n    CorrectGroupType := 10\n  else\n    CorrectGroupType := 9;\n\n  if OldTypeGroup.GroupType = CorrectGroupType then\n    Exit;\n\n  OldCell := OldChildGroup.ChildrenOf;\n  if not Assigned(OldCell) then\n    raise Exception.Create(OldChildGroup.GetName + ' can not find its CELL record');\n  if not OldCell.ElementExists['DATA'] then\n    raise Exception.Create(OldCell.GetName + ' is missing its DATA subrecord');\n\n  i := OldCell.GetElementNativeValue('DATA');\n  IsExterior := (i and 1) = 0;\n  if IsExterior then begin\n    if not Supports(OldCell.Container, IwbGroupRecord, OldCellOwnerGroup) then\n      raise Exception.Create(OldCell.GetName + ' is not contained in a group');\n    if not (OldCellOwnerGroup.GroupType in [1, 5]) then\n      raise Exception.Create(OldCell.GetName + ' is not contained in a group of type \"World Childen\" or \"Exterior Cell Sub-Block\"');\n    if (CorrectGroupType = 8) then begin\n      if OldCellOwnerGroup.GroupType <> 1 then begin\n\n        if not Supports(OldCellOwnerGroup.Container, IwbGroupRecord, TempGroup) then\n          raise Exception.Create(OldCellOwnerGroup.GetName + ' is not contained in a group');\n        if not (TempGroup.GroupType in [4]) then\n          raise Exception.Create(OldCellOwnerGroup.GetName + ' is not contained in a group of type \"Exterior Cell Block\"');\n\n        if not Supports(TempGroup.Container, IwbGroupRecord, NewCellOwnerGroup) then\n          raise Exception.Create(TempGroup.GetName + ' is not contained in a group');\n        if not (NewCellOwnerGroup.GroupType in [1]) then\n          raise Exception.Create(TempGroup.GetName + ' is not contained in a group of type \"World Childen\"');\n\n        NewCell := nil;\n        for i := 0 to Pred(NewCellOwnerGroup.ElementCount) do\n          if Supports(NewCellOwnerGroup.Elements[i], IwbMainRecord, NewCell) then\n            if NewCell.Signature <> 'CELL' then\n              NewCell := nil\n            else\n              Break;\n\n        if not Assigned(NewCell) then begin\n          Worldspace := NewCellOwnerGroup.ChildrenOf;\n          if not Assigned(Worldspace) then\n            raise Exception.Create(NewCellOwnerGroup.GetName + ' can not find its WRLD record');\n          Worldspace := Worldspace.MasterOrSelf;\n          TempGroup := Worldspace.ChildGroup;\n          if not Assigned(TempGroup) then\n            raise Exception.Create(Worldspace.GetName + ' can not find its child group');\n\n          for i := 0 to Pred(TempGroup.ElementCount) do\n            if Supports(TempGroup.Elements[i], IwbMainRecord, NewCell) then\n              if NewCell.Signature <> 'CELL' then\n                NewCell := nil\n              else\n                Break;\n\n          if Assigned(NewCell) then\n            NewCell := wbCopyElementToFile(NewCell, GetFile, False, True, '', '', '') as IwbMainRecord;\n        end;\n\n        if not Assigned(NewCell) then\n          raise Exception.Create('Could not determine CELL for persistent exterior references');\n\n        NewChildGroup := NewCell.EnsureChildGroup;\n      end else\n        NewChildGroup := OldChildGroup;\n    end else begin\n      if OldCellOwnerGroup.GroupType <> 5 then begin\n\n        if not GetPosition(Position) then\n          raise Exception.Create('Could not determine position of ' + GetName);\n\n        GridCell := wbPositionToGridCell(Position);\n        SubBlock := wbSubBlockFromGridCell(GridCell);\n        Block := wbBlockFromSubBlock(SubBlock);\n\n        SubBlockLabel := wbGridCellToGroupLabel(SubBlock);\n        BlockLabel := wbGridCellToGroupLabel(Block);\n\n        NewCell := nil;\n        TempGroup := nil;\n        for i := 0 to Pred(OldCellOwnerGroup.ElementCount) do\n          if Supports(OldCellOwnerGroup.Elements[i], IwbGroupRecord, TempGroup) then\n            if (TempGroup.GroupType = 4) and (TempGroup.GroupLabel = BlockLabel) then\n              Break\n            else\n              TempGroup := nil;\n\n        if Assigned(TempGroup) then begin\n          NewCellOwnerGroup := nil;\n          for i := 0 to Pred(TempGroup.ElementCount) do\n            if Supports(TempGroup.Elements[i], IwbGroupRecord, NewCellOwnerGroup) then\n              if (NewCellOwnerGroup.GroupType = 5) and (NewCellOwnerGroup.GroupLabel = SubBlockLabel) then\n                Break\n              else\n                NewCellOwnerGroup := nil;\n          if Assigned(NewCellOwnerGroup) then\n            for i := 0 to Pred(NewCellOwnerGroup.ElementCount) do\n              if Supports(NewCellOwnerGroup.Elements[i], IwbMainRecord, NewCell) then\n                if NewCell.GetGridCell(TempGridCell) and (GridCell.x = TempGridCell.x) and (GridCell.y = TempGridCell.y) then\n                  Break\n                else\n                  NewCell := nil;\n        end;\n\n        if not Assigned(NewCell) then begin\n          Worldspace := OldCellOwnerGroup.ChildrenOf;\n          if not Assigned(Worldspace) then\n            raise Exception.Create(OldCellOwnerGroup.GetName + ' can not find its WRLD record');\n          Worldspace := Worldspace.MasterOrSelf;\n          TempGroup2 := Worldspace.ChildGroup;\n          if not Assigned(TempGroup2) then\n            raise Exception.Create(Worldspace.GetName + ' can not find its child group');\n\n          TempGroup := nil;\n          for i := 0 to Pred(TempGroup2.ElementCount) do\n            if Supports(TempGroup2.Elements[i], IwbGroupRecord, TempGroup) then\n              if (TempGroup.GroupType = 4) and (TempGroup.GroupLabel = BlockLabel) then\n                Break\n              else\n                TempGroup := nil;\n\n          if Assigned(TempGroup) then begin\n            NewCellOwnerGroup := nil;\n            for i := 0 to Pred(TempGroup.ElementCount) do\n              if Supports(TempGroup.Elements[i], IwbGroupRecord, NewCellOwnerGroup) then\n                if (NewCellOwnerGroup.GroupType = 5) and (NewCellOwnerGroup.GroupLabel = SubBlockLabel) then\n                  Break\n                else\n                  NewCellOwnerGroup := nil;\n            if Assigned(NewCellOwnerGroup) then\n              for i := 0 to Pred(NewCellOwnerGroup.ElementCount) do\n                if Supports(NewCellOwnerGroup.Elements[i], IwbMainRecord, NewCell) then\n                  if NewCell.GetGridCell(TempGridCell) and (GridCell.x = TempGridCell.x) and (GridCell.y = TempGridCell.y) then\n                    Break\n                  else\n                    NewCell := nil;\n          end;\n\n          if Assigned(NewCell) then\n            NewCell := wbCopyElementToFile(NewCell, GetFile, False, True, '', '', '') as IwbMainRecord;\n        end;\n\n        if not Assigned(NewCell) then\n          raise Exception.Create('Could not determine CELL for persistent exterior references');\n\n        NewChildGroup := NewCell.EnsureChildGroup;\n      end else\n        NewChildGroup := OldChildGroup;\n    end;\n  end else\n    NewChildGroup := OldChildGroup;\n\n  if not Assigned(NewChildGroup) then\n    raise Exception.Create('Could not determine new CELL child group');\n\n  NewTypeGroup := nil;\n  for i := 0 to Pred(NewChildGroup.ElementCount) do\n    if Supports(NewChildGroup.Elements[i], IwbGroupRecord, NewTypeGroup) then\n      if NewTypeGroup.GroupType = CorrectGroupType then\n        Break\n      else\n        NewTypeGroup := nil;\n\n  if not Assigned(NewTypeGroup) then\n    NewTypeGroup := TwbGroupRecord.Create(NewChildGroup, CorrectGroupType, NewChildGroup.ChildrenOf);\n\n  OldTypeGroup.RemoveElement(SelfRef);\n  if OldTypeGroup.ElementCount = 0 then\n    OldTypeGroup.Remove\n  else\n    (OldTypeGroup as IwbGroupRecordInternal).SetModified(True);\n  NewTypeGroup.AddElement(SelfRef);\n  (NewTypeGroup as IwbGroupRecordInternal).SetModified(True);\n  (NewTypeGroup as IwbGroupRecordInternal).Sort;\n  if OldChildGroup.ElementCount = 0 then\n    OldChildGroup.Remove\n  else\n    (OldChildGroup as IwbGroupRecordInternal).SetModified(True);\nend;\n\nprocedure TwbMainRecord.UpdateInteriorCellGroup;\nvar\n  Container        : IwbContainer;\n\n  SubBlockGroup    : IwbGroupRecord;\n  BlockGroup       : IwbGroupRecord;\n  TopGroup         : IwbGroupRecord;\n\n  NewSubBlockGroup : IwbGroupRecord;\n  NewBlockGroup    : IwbGroupRecord;\n\n  ChildGroup       : IwbGroupRecord;\n\n  i: Integer;\n  s            : string;\n\n  Block        : Integer;\n  SubBlock     : Integer;\n\n  SelfRef      : IwbElement;\nbegin\n  SelfRef := Self as IwbElement;\n\n  if GetSignature <> 'CELL' then\n    Exit;\n  if not GetElementExists('DATA') then\n    Exit;\n  i := GetElementNativeValue('DATA');\n  if (i and 1) <> 1 then\n    Exit;\n\n  Container := GetContainer;\n\n  if not Supports(Container, IwbGroupRecord, SubBlockGroup) then\n    raise Exception.Create(GetName + ' is not contained in a group.');\n  if not (SubBlockGroup.GroupType in [3]) then begin\n    if (SubBlockGroup.GroupType in [0]) and (TwbSignature(SubBlockGroup.GroupLabel) = 'CELL') then begin\n      TopGroup := SubBlockGroup;\n      SubBlockGroup := nil;\n    end else\n      raise Exception.Create(GetName + ' is not contained in a group of type \"Interior Cell Sub-Block\"');\n  end else begin\n    if not Supports(SubBlockGroup.Container, IwbGroupRecord, BlockGroup) then\n      raise Exception.Create(SubBlockGroup.GetName + ' is not contained in a group.');\n    if not (BlockGroup.GroupType in [2]) then\n      raise Exception.Create(GetName + ' is not contained in a group of type \"Interior Cell Block\"');\n\n    if not Supports(BlockGroup.Container, IwbGroupRecord, TopGroup) then\n      raise Exception.Create(TopGroup.GetName + ' is not contained in a group.');\n    if not (TopGroup.GroupType in [0]) or (TwbSignature(TopGroup.GroupLabel) <> 'CELL') then\n      raise Exception.Create(GetName + ' is not contained in a group of type \"Top CELL\"');\n  end;\n\n  s := '00' + IntToStr(mrStruct.mrsFormID and Cardinal($00FFFFFF));\n  i := Length(s);\n  if i > 2 then\n    System.Delete(s, 1, i - 2);\n\n  Block := StrToInt(s[2]);\n  SubBlock := StrToInt(s[1]);\n\n  NewBlockGroup := BlockGroup;\n  NewSubBlockGroup := SubBlockGroup;\n\n  if not Assigned(NewBlockGroup) or (NewBlockGroup.GroupLabel <> Block) then begin\n    NewBlockGroup := nil;\n    NewSubBlockGroup := nil;\n\n    for i := 0 to Pred(TopGroup.ElementCount) do\n      if Supports(TopGroup.Elements[i], IwbGroupRecord, NewBlockGroup) then\n        if NewBlockGroup.GroupLabel = Block then\n          Break\n        else\n          NewBlockGroup := nil;\n\n    if not Assigned(NewBlockGroup) then begin\n      NewBlockGroup := TwbGroupRecord.Create(TopGroup, 2, Block);\n      (TopGroup as IwbGroupRecordInternal).SetModified(True);\n      (TopGroup as IwbGroupRecordInternal).Sort;\n    end;\n  end;\n\n  if not Assigned(NewSubBlockGroup) or (NewSubBlockGroup.GroupLabel <> SubBlock) then begin\n    NewSubBlockGroup := nil;\n\n    for i := 0 to Pred(NewBlockGroup.ElementCount) do\n      if Supports(NewBlockGroup.Elements[i], IwbGroupRecord, NewSubBlockGroup) then\n        if NewSubBlockGroup.GroupLabel = SubBlock then\n          Break\n        else\n          NewSubBlockGroup := nil;\n\n    if not Assigned(NewSubBlockGroup) then begin\n      NewSubBlockGroup := TwbGroupRecord.Create(NewBlockGroup, 3, SubBlock);\n      (NewBlockGroup as IwbGroupRecordInternal).SetModified(True);\n      (NewBlockGroup as IwbGroupRecordInternal).Sort;\n    end;\n  end;\n\n  if not Container.Equals(NewSubBlockGroup) then begin\n\n    ChildGroup := mrGroup;\n\n    Container.RemoveElement(SelfRef);\n    if Assigned(ChildGroup) then\n      Container.RemoveElement(ChildGroup);\n\n    NewSubBlockGroup.AddElement(SelfRef);\n    if Assigned(ChildGroup) then\n      NewSubBlockGroup.AddElement(ChildGroup);\n    (NewSubBlockGroup as IwbGroupRecordInternal).SetModified(True);\n    (NewSubBlockGroup as IwbGroupRecordInternal).Sort;\n\n    if Assigned(SubBlockGroup) then begin\n      if SubBlockGroup.ElementCount = 0 then begin\n        SubBlockGroup.Remove;\n        if Assigned(BlockGroup) then begin\n          if BlockGroup.ElementCount = 0 then begin\n            BlockGroup.Remove;\n            (TopGroup as IwbGroupRecordInternal).SetModified(True);\n          end else\n            (BlockGroup as IwbGroupRecordInternal).SetModified(True);\n        end;\n      end else\n        (SubBlockGroup as IwbGroupRecordInternal).SetModified(True);\n    end;\n  end;\nend;\n\nprocedure TwbMainRecord.UpdateRefs;\nbegin\n  if (csRefsBuild in cntStates) then\n    BuildRef;\nend;\n\nprocedure TwbMainRecord.WriteToStreamInternal(aStream: TStream; aResetModified: Boolean);\nvar\n  CurrentPosition   : Int64;\n  NewPosition       : Int64;\n  DataSize          : Cardinal;\n  MemoryStream      : TMemoryStream;\n  mrs               : TwbMainRecordStruct;\nvar\n  SelfRef : IwbContainerElementRef;\nbegin\n  if (esModified in eStates) or wbTestWrite then begin\n    SelfRef := Self as IwbContainerElementRef;\n    DoInit;\n\n    CurrentPosition := aStream.Position;\n\n    mrs := mrStruct^;\n//    mrs.mrsFlags2 := 0;\n\n    aStream.WriteBuffer(mrs, wbSizeOfMainRecordStruct );\n\n    if wbForceNewHeader then\n      aStream.WriteBuffer(wbNewHeaderAddon, SizeOf(wbNewHeaderAddon) );\n\n    if mrStruct.mrsFlags.IsCompressed then begin\n\n      MemoryStream := TMemoryStream.Create;\n      try\n        inherited WriteToStreamInternal(MemoryStream, aResetModified);\n        DataSize := MemoryStream.Size;\n        aStream.WriteBuffer(DataSize, SizeOf(DataSize));\n        MemoryStream.Position := 0;\n        ZCompressStream(MemoryStream, aStream);\n      finally\n        FreeAndNil(MemoryStream);\n      end;\n\n    end else\n      inherited;\n\n    NewPosition := aStream.Position;\n    if wbForceNewHeader then\n      DataSize := (NewPosition - CurrentPosition) - wbSizeOfMainRecordStruct - SizeOf(wbNewHeaderAddon)\n    else\n      DataSize := (NewPosition - CurrentPosition) - wbSizeOfMainRecordStruct;\n    aStream.Position := CurrentPosition + 4;\n    aStream.WriteBuffer(DataSize, SizeOf(DataSize));\n    aStream.Position := NewPosition;\n\n  end else begin\n    CurrentPosition := aStream.Position;\n    aStream.WriteBuffer(dcBasePtr^, Cardinal(dcEndPtr) - Cardinal(dcBasePtr) );\n    if CurrentPosition + wbSizeOfMainRecordStruct + mrStruct.mrsDataSize <> aStream.Position then\n      Assert(CurrentPosition + wbSizeOfMainRecordStruct + mrStruct.mrsDataSize <> aStream.Position);\n  end;\n\n  Exclude(eStates, esUnsaved);\n  if aResetModified then begin\n    Exclude(eStates, esModified);\n    Exclude(eStates, esInternalModified);\n  end;\nend;\n\nprocedure TwbMainRecord.YouAreTheMaster(const aOverrides, aReferencedBy: TDynMainRecords);\nvar\n  i: Integer;\n  FileID: Integer;\n  _File: IwbFile;\nbegin\n  Assert(Length(aOverrides) > 0);\n  Assert(Equals(aOverrides[0]));\n  Assert(Assigned(mrMaster));\n  Assert(Length(mrOverrides) = 0);\n  Assert(Length(mrReferencedBy) = 0);\n\n  mrMaster := nil;\n  mrOverrides := Copy(aOverrides, 1, High(Integer));\n  for i := Low(mrOverrides) to High(mrOverrides) do\n    (mrOverrides[i] as IwbMainRecordInternal).SetMaster(Self);\n  mrOverridesSorted := False;\n\n  mrReferencedBy := aReferencedBy;\n\n  for i := Low(mrReferencedBy) to High(mrReferencedBy) do\n    (mrReferencedBy[i] as IwbMainRecordInternal).SetReferencesInjected(True);\n\n  FileID := GetFormID shr 24;\n  _File := GetFile;\n  Assert(FileID < _File.MasterCount);\n\n  (_File.Masters[FileID] as IwbFileInternal).InjectMainRecord(Self);\n  Include(mrStates, mrsIsInjectedChecked);\n  Include(mrStates, mrsIsInjected);\nend;\n\nprocedure TwbMainRecord.YouAreTheMaster(const aOldMaster: IwbMainRecord; const aOverrides, aReferencedBy: TDynMainRecords);\nvar\n  i      : Integer;\nbegin\n  Assert(not Assigned(mrMaster));\n  Assert(Length(mrOverrides) = 0);\n  Assert(Length(mrReferencedBy) = 0);\n\n  SetLength(mrOverrides, Succ(Length(aOverrides)));\n  mrOverrides[0] := aOldMaster;\n  for i := Low(aOverrides) to High(aOverrides) do\n    mrOverrides[Succ(i)] := aOverrides[i];\n\n  for i := Low(mrOverrides) to High(mrOverrides) do\n    (mrOverrides[i] as IwbMainRecordInternal).SetMaster(Self);\n  mrOverridesSorted := False;\n\n  mrReferencedBy := aReferencedBy;\n\n  for i := Low(mrReferencedBy) to High(mrReferencedBy) do\n    (mrReferencedBy[i] as IwbMainRecordInternal).SetReferencesInjected(False);\n  Exclude(mrStates, mrsIsInjectedChecked);\nend;\n\nprocedure TwbMainRecord.YouGotAMaster(const aMaster: IwbMainRecord);\nbegin\n  Assert(Assigned(aMaster));\n  Assert(not Assigned(mrMaster));\n  (aMaster as IwbMainRecordInternal).YouAreTheMaster(Self as IwbMainRecord, mrOverrides, mrReferencedBy);\n  Assert(aMaster.Equals(IwbElement(mrMaster)));\n  mrOverrides := nil;\n  mrReferencedBy := nil;\n  (aMaster._File as IwbFileInternal).RemoveInjectedMainRecord(Self);\n  Include(mrStates, mrsIsInjectedChecked);\n  Exclude(mrStates, mrsIsInjected);\nend;\n\n{ TwbSubRecord }\n\nfunction TwbSubRecord.AddIfMissingInternal(const aElement: IwbElement; aAsNew, aDeepCopy: Boolean; const aPrefixRemove, aPrefix, aSuffix: string): IwbElement;\nvar\n  SelfRef    : IwbContainerElementRef;\n  i          : Integer;\n  s          : string;\n  ArrayDef   : IwbArrayDef;\n  StructDef  : IwbStructDef;\n  IntegerDef : IwbIntegerDef;\n  FlagsDef   : IwbFlagsDef;\nbegin\n  if not wbEditAllowed then\n    raise Exception.Create(GetName + ' can not be modified.');\n\n  SelfRef := Self as IwbContainerElementRef;\n\n  DoInit;\n\n  if Assigned(srValueDef) then begin\n\n    case srValueDef.DefType of\n      dtRecord, dtSubRecord, dtSubRecordArray, dtSubRecordStruct: Assert(False);\n      dtArray: begin\n\n        ArrayDef := srValueDef as IwbArrayDef;\n\n        if srsSorted in srStates  then begin\n          Assert(not (srsSortInvalid in srStates));\n          if FindBySortKey(aElement.SortKey[False], False, i) then begin\n            Result := cntElements[i];\n            if aDeepCopy then\n              Result.Assign(Low(Integer), aElement, False);\n            Exit;\n          end;\n        end;\n\n        if srsSorted in srStates then\n          s := ''\n        else\n          s := '#' + IntToStr(Length(cntElements));\n\n        if not Supports(aElement, IwbStringListTerminator) then\n          if (csAsCreatedEmpty in cntStates) then begin\n            SetModified(True);\n            Assert(Length(cntElements)=1);\n            Result := cntElements[0];\n            Exclude(cntStates, csAsCreatedEmpty);\n            try\n              Result.Assign(Low(Integer), aElement, not aDeepCopy);\n            except\n              Result := nil;\n              raise;\n            end;\n          end else case ArrayDef.Element.DefType of\n            dtArray: Result := TwbArray.Create(Self, ArrayDef.Element, aElement, not aDeepCopy, s);\n            dtStruct: Result := TwbStruct.Create(Self, ArrayDef.Element, aElement, not aDeepCopy, s);\n            dtStructChapter: Result := TwbChapter.Create(Self, ArrayDef.Element, aElement, not aDeepCopy, s);\n            dtUnion: Result := TwbUnion.Create(Self, ArrayDef.Element, aElement, not aDeepCopy, s);\n          else\n            Result := TwbValue.Create(Self, ArrayDef.Element, aElement, not aDeepCopy, s);\n          end;\n\n        CheckCount;\n        CheckTerminator;\n      end;\n      dtStruct, dtStructChapter: begin\n        StructDef := srValueDef as IwbStructDef;\n\n        Assert(aElement.SortOrder >= 0);\n        Assert(aElement.SortOrder < StructDef.MemberCount );\n        Assert(Assigned(aElement.ValueDef));\n\n        Result := GetElementBySortOrder(aElement.SortOrder);\n        Assert(Assigned(Result));\n\n        Assert(StructDef.Members[aElement.SortOrder].CanAssign(Result, Low(Integer), aElement.ValueDef));\n\n        if not aDeepCopy then\n          if Supports(Result.ValueDef, IwbIntegerDef, IntegerDef) then\n            if Supports(IntegerDef.Formater[Result], IwbFlagsDef, FlagsDef) then\n              Exit(Result);\n\n        Result.Assign(Low(Integer), aElement, not aDeepCopy);\n      end;\n      dtUnion: begin\n        inherited AddIfMissingInternal(aElement, aAsNew, aDeepCopy, aPrefixRemove, aPrefix, aSuffix);\n      end;\n    else\n      inherited AddIfMissingInternal(aElement, aAsNew, aDeepCopy, aPrefixRemove, aPrefix, aSuffix);\n    end;\n\n  end else\n    inherited AddIfMissingInternal(aElement, aAsNew, aDeepCopy, aPrefixRemove, aPrefix, aSuffix);\nend;\n\nfunction TwbSubRecord.AssignInternal(aIndex: Integer; const aElement: IwbElement; aOnlySK: Boolean): IwbElement;\nvar\n  Element   : IwbElement;\n  ArrayDef  : IwbArrayDef;\n  Container : IwbContainer;\n  s         : string;\n  i         : Integer;\n  SelfRef   : IwbContainerElementRef;\n  p, q      : Pointer;\nbegin\n  Result := nil;\n\n  if not wbEditAllowed then\n    raise Exception.Create(GetName + ' can not be assigned.');\n\n  SelfRef := Self as IwbContainerElementRef;\n  DoInit;\n\n  if Assigned(srValueDef) then begin\n\n    case srValueDef.DefType of\n      dtRecord, dtSubRecord, dtSubRecordArray, dtSubRecordStruct: Assert(False);\n      dtArray: begin\n\n        ArrayDef := srValueDef as IwbArrayDef;\n\n        if (aIndex = Low(Integer)) and ArrayDef.CanAssign(Self, aIndex, aElement.ValueDef) then begin\n\n          if aOnlySK then\n            Exit;\n\n          Container := aElement as IwbContainer;\n\n          if ArrayDef.IsVariableSize then begin\n            Assert(ArrayDef.ElementCount <= 0);\n            SetModified(True);\n            InvalidateStorage;\n            ReleaseElements;\n            dcDataStorage := nil;\n            dcDataBasePtr := @EmptyPtr;\n            dcDataEndPtr := @EmptyPtr;\n            Exclude(dcFlags, dcfStorageInvalid);\n            if ArrayDef.ElementCount < 0 then\n              RequestStorageChange(p, q, 4);\n\n            for i := 0 to Pred(Container.ElementCount) do\n              Assign(i, Container.Elements[i], aOnlySK);\n          end else begin\n            Assert(Container.ElementCount = ArrayDef.ElementCount);\n            Assert(GetElementCount = ArrayDef.ElementCount);\n\n            for i := 0 to Pred(Container.ElementCount) do\n              cntElements[i].Assign(Low(Integer), Container.Elements[i], aOnlySK);\n          end;\n\n        end else begin\n          if (aIndex >= 0) and (ArrayDef.ElementCount <= 0) and ((aIndex = High(Integer)) or ArrayDef.Element.CanAssign(Self, Low(Integer), aElement.ValueDef)) then begin\n            {add one entry}\n\n            if srsSorted in srStates then\n              s := ''\n            else\n              s := '#' + IntToStr(Length(cntElements));\n\n            if (csAsCreatedEmpty in cntStates) then begin\n              SetModified(True);\n              Assert(Length(cntElements)=1);\n              Result := cntElements[0];\n              Exclude(cntStates, csAsCreatedEmpty);\n              try\n                Result.Assign(Low(Integer), aElement, aOnlySK);\n              except\n                Result := nil;\n                raise;\n              end;\n            end else begin\n              Element := nil;\n              if not Supports(aElement, IwbStringListTerminator) then\n                case ArrayDef.Element.DefType of\n                  dtArray: Element := TwbArray.Create(Self, ArrayDef.Element, aElement, aOnlySK, s);\n                  dtStruct: Element := TwbStruct.Create(Self, ArrayDef.Element, aElement, aOnlySK, s);\n                  dtStructChapter: Element := TwbChapter.Create(Self, ArrayDef.Element, aElement, aOnlySK, s);\n                  dtUnion: Element := TwbUnion.Create(Self, ArrayDef.Element, aElement, aOnlySK, s);\n                else\n                  Element := TwbValue.Create(Self, ArrayDef.Element, aElement, aOnlySK, s);\n                end;\n              Result := Element;\n            end;\n          end;\n        end;\n\n        CheckCount;\n        CheckTerminator;\n      end;\n    else\n      Result := inherited AssignInternal(aIndex, aElement, aOnlySK);\n    end;\n\n  end else\n    if inherited CanAssignInternal(aIndex, aElement, False) then\n      Result := inherited AssignInternal(aIndex, aElement, aOnlySK);\nend;\n\nprocedure TwbSubRecord.BuildRef;\nvar\n  SelfRef: IwbElement;\nbegin\n  SelfRef := Self as IwbContainerElementRef;\n\n  if Assigned(srDef) then begin\n    DoInit;\n\n    if Assigned(srValueDef) then\n      srValueDef.BuildRef(GetDataBasePtr, dcDataEndPtr, Self);\n  end;\n\n  inherited;\nend;\n\nfunction TwbSubRecord.CanAssignInternal(aIndex: Integer; const aElement: IwbElement; aCheckDontShow: Boolean): Boolean;\nvar\n  ArrayDef: IwbArrayDef;\nbegin\n  Result := False;\n  if not wbEditAllowed then\n    Exit;\n\n  if Assigned(eContainer) then\n    if not IwbContainer(eContainer).IsElementEditable(Self) then\n      Exit;\n\n  if aCheckDontShow and GetDontShow then\n    Exit;\n\n  if srsIsArray in srStates then begin\n    ArrayDef := srValueDef as IwbArrayDef;\n    if not Assigned(aElement) then begin\n      if aIndex = High(Integer) then\n        Result := ArrayDef.ElementCount <= 0;\n      Exit;\n    end;\n    Result :=\n       ArrayDef.CanAssign(Self, aIndex, aElement.ValueDef) or\n       ( (ArrayDef.ElementCount <= 0) and ArrayDef.Element.CanAssign(Self, Low(Integer), aElement.ValueDef) );\n  end else begin\n    if not Assigned(aElement) then\n      Exit;\n\n    Result := inherited CanAssignInternal(aIndex, aElement, aCheckDontShow);\n    if not Result and Assigned(srDef) then\n      Result := srDef.CanAssign(Self, aIndex, aElement.Def);\n  end;\nend;\n\nfunction TwbSubRecord.CanContainFormIDs: Boolean;\nbegin\n  Result := Assigned(srDef) and srDef.CanContainFormIDs;\nend;\n\nfunction TwbSubRecord.CanMoveElement: Boolean;\nbegin\n  Result := srStates * [srsIsArray, srsSorted] = [srsIsArray];\nend;\n\nfunction TwbSubRecord.CanElementReset: Boolean;\nbegin\n//  Result := inherited CanElementReset;\n  Result := cntElementRefs < 1;\nend;\n\nprocedure TwbSubRecord.CheckCount;\nvar\n  Count       : Cardinal;\n  i           : Integer;\n  UpdateCount : Integer;\nbegin\n  if not (srArraySizePrefix in [1, 2, 4]) then\n    Exit;\n\n  if Assigned(dcDataBasePtr) then\n    case srArraySizePrefix of\n      1: Count := PByte(dcDataBasePtr)^;\n      2: Count := PWord(dcDataBasePtr)^;\n      4: Count := PCardinal(dcDataBasePtr)^;\n    else\n      Count := 0;\n    end\n  else\n    Count := 0;\n\n  if Count <> Length(cntElements) then begin\n    UpdateCount := eUpdateCount;\n    for i := 1 to UpdateCount do EndUpdate;\n    case srArraySizePrefix of\n      1: PByte(GetDataBasePtr)^ := Length(cntElements);\n      2: PWord(GetDataBasePtr)^ := Length(cntElements);\n      4: PCardinal(GetDataBasePtr)^ := Length(cntElements);\n    end;\n    for i := 1 to UpdateCount do BeginUpdate;\n  end;\nend;\n\nprocedure TwbSubRecord.CheckTerminator;\nvar\n  i         : Integer;\n  ArrayDef  : IwbArrayDef;\n  StringDef : IwbStringDef;\nbegin\n  if not Supports(srValueDef, IwbArrayDef, ArrayDef) then\n    Exit;\n  if not ArrayDef.IsVariableSize then\n    Exit;\n  if ArrayDef.Element.DefType <> dtString then\n    Exit;\n  if (not Supports(ArrayDef.Element, IwbStringDef, StringDef)) or (StringDef.GetStringSize>0) then\n    Exit;\n\n  for i := Low(cntElements) to High(cntElements) do\n    if Supports(cntElements[i], IwbStringListTerminator) then\n      Exit;\n\n  SetModified(True);\n  InvalidateStorage;\n  TwbStringListTerminator.Create(Self);\n  if srsSorted in srStates then\n    Include(srStates, srsSortInvalid);\nend;\n\nfunction Resolve(const aValueDef: IwbValueDef; aBasePtr: Pointer; aEndPtr: Pointer; const aElement: IwbElement): IwbValueDef;\nvar\n  Internal  : IwbElementInternal;\n  UnionDef  : IwbUnionDef;\n  CanDecide : Boolean;\nbegin\n  Result := aValueDef;\n\n  Supports(aElement, IwbElementInternal, Internal);\n  CanDecide := False;\n  try\n    while Supports(Result, IwbUnionDef, UnionDef) do begin\n      CanDecide := CanDecide or (Assigned(Internal) and Internal.BeginDecide);\n      if CanDecide then\n        Result := UnionDef.Decide(aBasePtr,aEndPtr,aElement)\n      else\n        break;\n    end;\n  finally\n    if CanDecide then\n      Internal.EndDecide;\n  end;\nend;\n\nfunction TwbSubRecord.CompareExchangeFormID(aOldFormID, aNewFormID: Cardinal): Boolean;\nvar\n  SelfRef     : IwbContainerElementRef;\n  ResolvedDef : IwbValueDef;\nbegin\n  SelfRef := Self as IwbContainerElementRef;\n  Result := False;\n  if not Assigned(srDef) then\n    Exit;\n\n  DoInit;\n\n  Result := inherited CompareExchangeFormID(aOldFormID, aNewFormID);\n\n  ResolvedDef := Resolve(srValueDef, GetDataBasePtr, dcDataEndPtr, Self);\n  if Assigned(ResolvedDef) then\n    Result := ResolvedDef.CompareExchangeFormID(GetDataBasePtr, dcDataEndPtr, Self, aOldFormID, aNewFormID) or Result;\nend;\n\nconstructor TwbSubRecord.Create(const aContainer: IwbContainer; const aSubRecordDef: IwbSubRecordDef);\nvar\n  BasePtr            : Pointer;\n  EndPtr             : Pointer;\n  SaveAsCreatedEmpty : Boolean;\n\nbegin\n  cntStates := [];\n  srDef := aSubRecordDef;\n  BasePtr := nil;\n  Create(aContainer, BasePtr, nil, nil);\n\n  DoInit;\n\n  SaveAsCreatedEmpty := (csAsCreatedEmpty in cntStates);\n  BasePtr := nil;\n  EndPtr := nil;\n  RequestStorageChange(BasePtr, EndPtr, GetDataSize);\n  SetToDefault;\n\n  if SaveAsCreatedEmpty then\n    Include(cntStates, csAsCreatedEmpty);\nend;\n\ndestructor TwbSubRecord.Destroy;\nbegin\n  if not Assigned(dcEndPtr) and Assigned(dcBasePtr) then\n    FreeMem(dcBasePtr, SizeOf(TwbSubRecordHeaderStruct) );\n  inherited;\nend;\n\nfunction TwbSubRecord.DoCheckSizeAfterWrite: Boolean;\nbegin\n  Result := True;\nend;\n\nprocedure TwbSubRecord.DoInit;\nbegin\n  inherited;\n  if srStates * [srsSorted, srsSortInvalid] = [srsSorted, srsSortInvalid] then begin\n    if Length(cntElements) > 1 then\n      wbMergeSort(@cntElements[0], Length(cntElements), CompareSortKeys);\n    Exclude(srStates, srsSortInvalid);\n  end;\nend;\n\nprocedure TwbSubRecord.ElementChanged(const aElement: IwbElement; aContainer: Pointer);\nbegin\n  if srsSorted in srStates then\n    Include(srStates, srsSortInvalid);\n  inherited;\nend;\n\nprocedure TwbSubRecord.FindUsedMasters(aMasters: PwbUsedMasters);\nvar\n  SelfRef     : IwbContainerElementRef;\n  ResolvedDef : IwbValueDef;\nbegin\n  SelfRef := Self as IwbContainerElementRef;\n\n  if not Assigned(srDef) then\n    Exit;\n\n  DoInit;\n\n  inherited FindUsedMasters(aMasters);\n\n  ResolvedDef := Resolve(srValueDef, GetDataBasePtr, dcDataEndPtr, Self);\n  if Assigned(ResolvedDef) then\n    ResolvedDef.FindUsedMasters(GetDataBasePtr, dcDataEndPtr, Self, aMasters);\nend;\n\n//var\n//  y: Integer;\n\nprocedure TwbSubRecord.Init;\nvar\n  ValueDef          : IwbValueDef;\n  BasePtr           : Pointer;\n  Element           : IwbElement;\n  HasUnusedData     : Boolean;\nbegin\n  inherited;\n\n  if GetSkipped then\n    Exit;\n\n  if not Assigned(srDef) then\n    Exit;\n\n  BasePtr := GetDataBasePtr;\n  ValueDef := Resolve(srDef.Value, BasePtr, dcDataEndPtr, Self);\n  srArraySizePrefix := 0;\n\n  if Assigned(ValueDef) then\n    if ValueDef.Name = '' then begin\n      srValueDef := ValueDef;\n      case ValueDef.DefType of\n        dtArray: begin\n          Include(srStates, srsIsArray);\n          if ArrayDoInit(ValueDef, Self, BasePtr, dcDataEndPtr, srArraySizePrefix) then\n            Include(srStates, srsSorted);\n        end;\n        dtStruct, dtStructChapter: StructDoInit(ValueDef, Self, BasePtr, dcDataEndPtr);\n        dtUnion:  begin\n          Include(srStates, srsIsUnion);\n          case UnionDoInit(ValueDef, Self, BasePtr, dcDataEndPtr) of\n            ufArray: Include(srStates, srsIsArray);\n            ufSortedArray: begin\n              Include(srStates, srsIsArray);\n              Include(srStates, srsSorted);\n            end;\n            ufFlags: begin\n              Include(srStates, srsIsFlags);\n              Include(srStates, srsSorted);\n            end;\n          end;\n        end;\n      else\n        if ValueDoInit(ValueDef, Self, BasePtr, dcDataEndPtr, Self) then begin\n          Include(srStates, srsIsFlags);\n          Include(srStates, srsSorted);\n        end;\n      end;\n      // flags are already created in the right sort order\n      if srStates * [srsSorted, srsIsFlags] = [srsSorted] then\n        Include(srStates, srsSortInvalid);\n    end else\n      case ValueDef.DefType of\n        dtArray: Element := TwbArray.Create(Self, BasePtr, dcDataEndPtr, ValueDef, '');\n        dtStruct: Element := TwbStruct.Create(Self, BasePtr, dcDataEndPtr, ValueDef, '');\n        dtStructChapter: Element := TwbChapter.Create(Self, BasePtr, dcDataEndPtr, ValueDef, '');\n        dtUnion: Element := TwbUnion.Create(Self, BasePtr, dcDataEndPtr, ValueDef, '');\n      else\n        Element := TwbValue.Create(Self, BasePtr, dcDataEndPtr, ValueDef, '');\n      end;\n\n  if Assigned(dcDataEndPtr) and Assigned(BasePtr) and (BasePtr <> dcDataEndPtr) then begin\n    HasUnusedData := not SameText(ValueDef.Name, 'Unused');\n    if HasUnusedData and (ValueDef.DefType = dtString) then begin\n      HasUnusedData := False;\n      while Cardinal(BasePtr) < Cardinal(dcDataEndPtr) do begin\n        if PAnsiChar(BasePtr)^ <> #0 then begin\n          HasUnusedData := True;\n          Break;\n        end;\n        Inc(PByte(BasePtr));\n      end;\n    end;\n    if HasUnusedData then begin\n      if wbReportMode then\n        srDef.HasUnusedData;\n      {$IFDEF DBGSUBREC}\n      if Assigned(wbProgressCallback) then\n        wbProgressCallback('<Warning: Unused data in: ' + GetFullPath + '>');\n      {$ENDIF}\n    end;\n  end;\n\n  srDef.AfterLoad(Self);\nend;\n\nfunction TwbSubRecord.GetCheck: string;\nvar\n  SelfRef : IwbContainerElementRef;\nbegin\n  SelfRef := Self as IwbContainerElementRef;\n\n  Result := '';\n\n  if not Assigned(srDef) then\n    Exit;\n  DoInit;\n\n  if Assigned(srValueDef) then\n    Result := srValueDef.Check(GetDataBasePtr, dcDataEndPtr, Self);\nend;\n\nfunction TwbSubRecord.GetDataPrefixSize: Integer;\nbegin\n  Result := srArraySizePrefix;\nend;\n\nfunction TwbSubRecord.GetDataSize: Integer;\nvar\n  SelfRef : IwbContainerElementRef;\nbegin\n  SelfRef := Self as IwbContainerElementRef;\n\n  DoInit;\n\n  if not Assigned(dcDataBasePtr) and Assigned(srValueDef) and not (dcfStorageInvalid in dcFlags) then begin\n    Result := srValueDef.DefaultSize[nil, nil, Self];\n    Assert(Result <> Cardinal(High(Integer)));\n  end else\n    Result := inherited GetDataSize;\nend;\n\nfunction TwbSubRecord.GetDef: IwbNamedDef;\nbegin\n  Result := srDef;\nend;\n\nfunction TwbSubRecord.GetDisplayName: string;\nvar\n  s        : string;\n  SelfRef  : IwbContainerElementRef;\n  ValueDef : IwbValueDef;\nbegin\n  SelfRef := Self as IwbContainerElementRef;\n\n  Result := inherited GetName;\n\n  ValueDef := Resolve(srValueDef, GetDataBasePtr, GetDataEndPtr, Self);\n\n  if Assigned(ValueDef) then begin\n    s := ValueDef.Name;\n    if s <> '' then begin\n      Result := Result + ' - ' + s;\n      Exit;\n    end;\n  end;\n\n  if not Assigned(srDef) then\n    Exit;\n\n  Result := Result + ' - ' + srDef.GetName;\nend;\n\nfunction TwbSubRecord.GetEditValue: string;\nvar\n  SelfRef : IwbContainerElementRef;\nbegin\n  SelfRef := Self as IwbContainerElementRef;\n\n  Result := '';\n\n  if not Assigned(srDef) then\n    Exit;\n  DoInit;\n\n  if Assigned(srValueDef) then\n    Result := srValueDef.EditValue[GetDataBasePtr, dcDataEndPtr, Self]\n  else\n    Result := '';\nend;\n\nfunction TwbSubRecord.GetElementType: TwbElementType;\nbegin\n  Result := etSubRecord;\nend;\n\nfunction TwbSubRecord.GetIsEditable: Boolean;\nvar\n  SelfRef : IwbContainerElementRef;\nbegin\n  SelfRef := Self as IwbContainerElementRef;\n\n  Result := wbIsInternalEdit;\n  if Result then\n    Exit;\n\n  if Assigned(eContainer) and not IwbContainer(eContainer).IsElementEditable(SelfRef) then\n    Exit;\n\n  if not Assigned(srDef) then\n    Exit;\n  DoInit;\n\n  Result := Assigned(srValueDef) and\n    srValueDef.IsEditable[GetDataBasePtr, dcDataEndPtr, Self];\nend;\n\nfunction TwbSubRecord.GetIsInSK(aIndex: Integer): Boolean;\nvar\n  SelfRef    : IwbContainerElementRef;\n  HasSortKey : IwbHasSortKeyDef;\nbegin\n  Result := False;\n\n  SelfRef := Self as IwbContainerElementRef;\n  DoInit;\n\n  if not Supports(srValueDef, IwbHasSortKeyDef, HasSortKey) then\n    Exit;\n\n  Result := HasSortKey.IsInSK(aIndex);\nend;\n\nfunction TwbSubRecord.GetLinksTo: IwbElement;\nvar\n  SelfRef: IwbContainerElementRef;\nbegin\n  Result := nil;\n  SelfRef := Self as IwbContainerElementRef;\n  DoInit;\n  if not Assigned(srValueDef) then\n    Exit;\n  Result := srValueDef.LinksTo[dcDataBasePtr, dcDataEndPtr, Self];\nend;\n\nfunction TwbSubRecord.GetName: string;\nbegin\n  Result := inherited GetName;\n\n  if not Assigned(srDef) then\n    Exit;\n\n  Result := Result + ' - ' + srDef.GetName;\nend;\n\nfunction TwbSubRecord.GetNativeValue: Variant;\nvar\n  SelfRef : IwbContainerElementRef;\nbegin\n  SelfRef := Self as IwbContainerElementRef;\n\n  Result := '';\n\n  if not Assigned(srDef) then\n    Exit;\n  DoInit;\n\n  if Assigned(srValueDef) then\n    Result := srValueDef.NativeValue[GetDataBasePtr, dcDataEndPtr, Self]\n  else\n    Result := Null;\nend;\n\nfunction TwbSubRecord.GetSorted: Boolean;\nvar\n  EmptyDef : IwbEmptyDef;\n  SelfRef  : IwbContainerElementRef;\nbegin\n  SelfRef := Self as IwbContainerElementRef;\n\n  if not Assigned(srValueDef) then\n    DoInit;\n\n  Result := (srsSorted in srStates) or\n    (Supports(Resolve(srValueDef, GetDataBasePtr, GetDataEndPtr, Self), IwbEmptyDef, EmptyDef) and EmptyDef.Sorted);\nend;\n\nfunction TwbSubRecord.GetSortKeyInternal(aExtended: Boolean): string;\nvar\n  SelfRef : IwbContainerElementRef;\nbegin\n  SelfRef := Self as IwbContainerElementRef;\n\n  Result := GetSignature;\n\n  if not Assigned(srDef) then\n    Exit;\n  DoInit;\n\n  if Assigned(srValueDef) then\n    Result := srValueDef.ToSortKey(GetDataBasePtr, dcDataEndPtr, Self, aExtended)\n  else\n    Result := inherited GetSortKeyInternal(aExtended);\nend;\n\nfunction TwbSubRecord.GetSubRecordHeaderSize: Integer;\nbegin\n  if Assigned(dcBasePtr) then\n    Result := srStruct.srsDataSize\n  else\n    Result := 0;\nend;\n\nfunction TwbSubRecord.GetValue: string;\nvar\n//  i : Integer;\n//  j : Int64;\n  SelfRef : IwbContainerElementRef;\nvar\n  Def: IwbDef;\nbegin\n  if wbReportMode then begin\n    Def := GetValueDef;\n    if Assigned(Def) then\n      Def.Used;\n    Def := GetDef;\n    if Assigned(Def) then\n      Def.Used;\n  end;\n\n  SelfRef := Self as IwbContainerElementRef;\n  Result := '';\n\n  if not Assigned(srDef) then\n    Exit;\n  DoInit;\n\n  if Assigned(srValueDef) then\n    Result := srValueDef.ToString(GetDataBasePtr, dcDataEndPtr, Self);\nend;\n\nfunction TwbSubRecord.GetValueDef: IwbValueDef;\nvar\n  SelfRef : IwbContainerElementRef;\nbegin\n  if not Assigned(srValueDef) or ((srsIsUnion in srStates) and not (csInit in cntStates)) then begin\n    SelfRef := Self as IwbContainerElementRef;\n    DoInit;\n  end;\n  Result := srValueDef;\nend;\n\nprocedure TwbSubRecord.InformStorage(var aBasePtr: Pointer; aEndPtr: Pointer);\nvar\n  SizeNeeded    : Cardinal;\n  SizeAvailable : Cardinal;\n  BasePtr       : Pointer;\nbegin\n  Assert(Assigned(dcBasePtr));\n  Assert(Assigned(dcEndPtr));\n\n  SizeNeeded := SizeOf(TwbSubRecordHeaderStruct);\n  SizeAvailable := Cardinal( aEndPtr ) - Cardinal( aBasePtr );\n  Assert( SizeAvailable >= SizeNeeded );\n\n  BasePtr := aBasePtr;\n  Inc(PByte(aBasePtr), SizeNeeded );\n  inherited;\n\n  Assert(srStruct.srsDataSize = Cardinal( dcDataEndPtr ) - Cardinal( dcDataBasePtr ));\n\n  dcBasePtr := BasePtr;\n  dcEndPtr := dcDataEndPtr;\nend;\n\nprocedure TwbSubRecord.InitDataPtr;\nvar\n  lDataSize  : Cardinal;\n  LastRecord : IwbElement;\n  Container  : IwbContainer;\nbegin\n  if Assigned(dcBasePtr) then begin\n    dcDataBasePtr := Pointer( Cardinal( dcBasePtr ) + SizeOf(TwbSubRecordHeaderStruct) );\n\n    lDataSize := srStruct.srsDataSize;\n\n    if lDataSize = 0 then begin\n      Container := GetContainer;\n      if Assigned(Container) and (Container.ElementCount >= 2) then begin\n        LastRecord := Container.Elements[Container.ElementCount - 2];\n        if Assigned(LastRecord) and (LastRecord.ElementType = etSubRecord) then\n          with LastRecord as IwbSubRecord do\n            if Signature = 'XXXX' then begin\n              lDataSize := PCardinal(DataBasePtr)^;\n              Container.RemoveElement(Container.ElementCount - 2);\n            end;\n      end;\n    end;\n\n    dcDataEndPtr := Pointer( Cardinal( dcDataBasePtr ) + lDataSize );\n    dcEndPtr := dcDataEndPtr;\n  end else begin\n    GetMem(dcBasePtr, SizeOf(TwbSubRecordHeaderStruct) );\n    if Assigned(srDef) then\n      srStruct.srsSignature := srDef.DefaultSignature\n    else\n      srStruct.srsSignature := NONE;\n  end;\nend;\n\nfunction TwbSubRecord.IsElementRemoveable(const aElement: IwbElement): Boolean;\nbegin\n  Result := IsElementEditable(aElement)\n    and (srsIsArray in srStates)\n    and Assigned(srValueDef)\n    and ((srValueDef as IwbArrayDef).ElementCount <= 0) and (Length(cntElements)>1);\nend;\n\nfunction TwbSubRecord.IsFlags: Boolean;\nbegin\n  Result := srsIsFlags in srStates;\nend;\n\nprocedure TwbSubRecord.MasterCountUpdated(aOld, aNew: Byte);\nvar\n  SelfRef     : IwbContainerElementRef;\n  ResolvedDef : IwbValueDef;\nbegin\n  SelfRef := Self as IwbContainerElementRef;\n\n  if not Assigned(srDef) then\n    Exit;\n\n  DoInit;\n\n  inherited MasterCountUpdated(aOld, aNew);\n\n  ResolvedDef := Resolve(srValueDef, GetDataBasePtr, dcDataEndPtr, Self);\n  if Assigned(ResolvedDef) then\n    ResolvedDef.MasterCountUpdated(GetDataBasePtr, dcDataEndPtr, Self, aOld, aNew);\nend;\n\nprocedure TwbSubRecord.MasterIndicesUpdated(const aOld, aNew: TBytes);\nvar\n  SelfRef     : IwbContainerElementRef;\n  ResolvedDef : IwbValueDef;\nbegin\n  SelfRef := Self as IwbContainerElementRef;\n\n  if not Assigned(srDef) then\n    Exit;\n\n  DoInit;\n\n  inherited MasterIndicesUpdated(aOld, aNew);\n\n  ResolvedDef := Resolve(srValueDef, GetDataBasePtr, dcDataEndPtr, Self);\n  if Assigned(ResolvedDef) then\n    ResolvedDef.MasterIndicesUpdated(GetDataBasePtr, dcDataEndPtr, Self, aOld, aNew);\nend;\n\nprocedure TwbSubRecord.MergeStorageInternal(var aBasePtr: Pointer; aEndPtr: Pointer);\nvar\n  SizeNeeded    : Cardinal;\n  SizeAvailable : Cardinal;\n  BasePtr       : Pointer;\nbegin\n  Assert(Assigned(dcBasePtr));\n  SizeNeeded := SizeOf(TwbSubRecordHeaderStruct);\n  SizeAvailable := Cardinal( aEndPtr ) - Cardinal( aBasePtr );\n  Assert( SizeAvailable >= SizeNeeded );\n\n  BasePtr := aBasePtr;\n  Move(dcBasePtr^, aBasePtr^, SizeNeeded);\n  Inc(PByte(aBasePtr), SizeNeeded );\n  inherited;\n\n  if not Assigned(dcEndPtr) then\n    FreeMem(dcBasePtr, SizeNeeded);\n\n  dcBasePtr := BasePtr;\n  dcEndPtr := dcDataEndPtr;\n  srStruct.srsDataSize := Cardinal( dcDataEndPtr ) - Cardinal( dcDataBasePtr );\nend;\n\nprocedure TwbSubRecord.PrepareSave;\nbegin\n  if wbDelayLoadRecords then\n    if not (esModified in eStates) then\n      Exit;\n\n  CheckCount;\n  CheckTerminator;\n  inherited;\n  UpdateStorageFromElements;\nend;\n\nfunction TwbSubRecord.RemoveInjected(aCanRemove: Boolean): Boolean;\nvar\n  i       : Integer;\n  SelfRef : IwbContainerElementRef;\nbegin\n  SelfRef := Self as IwbContainerElementRef;\n  DoInit;\n\n  Result := False;\n  if {(GetSignature = 'PTDT') or} (GetSignature = 'PLDT') then begin\n    Assert(GetElementCount = 3);\n    Result := GetElement(1).ReferencesInjected;\n    if Result then begin\n      GetElement(0).EditValue := '2';\n      GetElement(1).EditValue := '00000000';\n      Result := False;\n    end;\n  end else begin\n    for i := High(cntElements) downto Low(cntElements) do\n      if cntElements[i].CanContainFormIDs then begin\n        Result := cntElements[i].RemoveInjected(True) or Result;\n        if Result and aCanRemove then\n          Break;\n      end;\n  end;\n  if Result and aCanRemove and GetIsRemoveable then begin\n    Result := False;\n    Remove;\n  end;\nend;\n\nprocedure TwbSubRecord.Reset;\nbegin\n  ReleaseElements;\n  srValueDef := nil;\n  srStates := srStates - [srsIsArray, srsIsFlags, srsSorted, srsSortInvalid];\n  inherited;\nend;\n\nprocedure TwbSubRecord.ScanData;\nbegin\n  { nothing }\nend;\n\nprocedure TwbSubRecord.SetDef(const aDef: IwbSubRecordDef);\nbegin\n  srDef := aDef;\n  DoReset(True);\nend;\n\nprocedure TwbSubRecord.SetEditValue(const aValue: string);\nvar\n  SelfRef : IwbContainerElementRef;\n  OldValue, NewValue: Variant;\nbegin\n  if not wbEditAllowed then\n    raise Exception.Create(GetName + ' can not be edited.');\n\n  SelfRef := Self as IwbContainerElementRef;\n  if not Assigned(srDef) then\n    if aValue <> '' then\n      raise Exception.Create(GetName + ' can not be edited')\n    else\n      Exit;\n\n  DoInit;\n\n  if GetEditValue <> aValue then begin\n    if Assigned(srValueDef) then begin\n      OldValue := GetNativeValue;\n      srValueDef.EditValue[GetDataBasePtr, dcDataEndPtr, Self] := aValue;\n      NewValue := GetNativeValue;\n      DoAfterSet(OldValue, NewValue);\n    end else\n      raise Exception.Create(GetName + ' can not be edited');\n    if (srsIsFlags in srStates) and (csInit in cntStates) then begin\n      Reset;\n      Init;\n    end;\n    NotifyChanged(eContainer);\n  end;\nend;\n\nprocedure TwbSubRecord.SetModified(aValue: Boolean);\nbegin\n  inherited;\n  if aValue and (srsSorted in srStates) then\n    Include(srStates, srsSortInvalid);\nend;\n\nprocedure TwbSubRecord.SetNativeValue(const aValue: Variant);\nvar\n  OldValue, NewValue: Variant;\n  SelfRef : IwbContainerElementRef;\nbegin\n  if not wbEditAllowed then\n    raise Exception.Create(GetName + ' can not be edited.');\n\n  SelfRef := Self as IwbContainerElementRef;\n  if not Assigned(srDef) then\n    raise Exception.Create(GetName + ' can not be edited');\n\n  DoInit;\n\n  if Assigned(srValueDef) then begin\n    OldValue := GetNativeValue;\n    srValueDef.NativeValue[GetDataBasePtr, dcDataEndPtr, Self] := aValue;\n    NewValue := GetNativeValue;\n    DoAfterSet(OldValue, NewValue);\n  end else\n    raise Exception.Create(GetName + ' can not be edited');\n  if (srsIsFlags in srStates) and (csInit in cntStates) then begin\n    Reset;\n    Init;\n  end;\n  NotifyChanged(eContainer);\nend;\n\nprocedure TwbSubRecord.SetToDefaultInternal;\nvar\n  SelfRef: IwbContainerElementRef;\n  BasePtr, EndPtr: Pointer;\nbegin\n  SelfRef := Self as IwbContainerElementRef;\n\n  if csInit in cntStates then\n    DoReset(True);\n  BasePtr := nil;\n  EndPtr := nil;\n  dcDataBasePtr := nil;\n  dcDataEndPtr := nil;\n  dcDataStorage := nil;\n  DoInit;\n  if Assigned(srValueDef) then\n    RequestStorageChange(BasePtr, EndPtr, srValueDef.DefaultSize[nil, nil, Self]);\n  inherited;\nend;\n\nfunction TwbSubRecord.srStruct: PwbSubRecordHeaderStruct;\nbegin\n  Result := PwbSubRecordHeaderStruct(dcBasePtr);\nend;\n\nprocedure TwbSubRecord.WriteToStreamInternal(aStream: TStream; aResetModified: Boolean);\nvar\n  CurrentPosition   : Int64;\n  NewPosition       : Int64;\n  BigDataSize       : Cardinal;\n  SubHeader         : TwbSubRecordHeaderStruct;\n  SelfRef           : IwbContainerElementRef;\nbegin\n  if (esModified in eStates) or wbTestWrite or (srStruct.srsDataSize = 0) then begin\n    SelfRef := Self as IwbContainerElementRef;\n    DoInit;\n\n    BigDataSize := GetDataSize;\n    if BigDataSize > High(Word) then begin\n      SubHeader.srsSignature := 'XXXX';\n      SubHeader.srsDataSize := SizeOf(Cardinal);\n      aStream.WriteBuffer(SubHeader, SizeOf(TwbSubRecordHeaderStruct) );\n      aStream.WriteBuffer(BigDataSize, SizeOf(BigDataSize) );\n      SubHeader.srsSignature := srStruct.srsSignature;\n      SubHeader.srsDataSize := 0;\n    end else begin\n      SubHeader.srsSignature := srStruct.srsSignature;\n      SubHeader.srsDataSize := BigDataSize;\n    end;\n\n    aStream.WriteBuffer(SubHeader, SizeOf(TwbSubRecordHeaderStruct) );\n    CurrentPosition := aStream.Position;\n    inherited;\n    NewPosition := aStream.Position;\n    if BigDataSize <> NewPosition - CurrentPosition then\n      Assert(BigDataSize = NewPosition - CurrentPosition );\n\n  end else begin\n    aStream.WriteBuffer(dcBasePtr^, SizeOf(TwbSubRecordHeaderStruct) );\n    CurrentPosition := aStream.Position;\n    inherited;\n    if CurrentPosition + srStruct.srsDataSize <> aStream.Position then\n      Assert(CurrentPosition + srStruct.srsDataSize = aStream.Position);\n  end;\n\n  Exclude(eStates, esUnsaved);\n  if aResetModified then begin\n    Exclude(eStates, esModified);\n    Exclude(eStates, esInternalModified);\n  end;\nend;\n\n{ TwbGroupRecord }\n\nfunction TwbGroupRecord.Add(const aName: string; aSilent: Boolean): IwbElement;\nvar\n  Signature : TwbSignature;\n  FormID    : Cardinal;\n  _File     : IwbFile;\n  MainRecord: IwbMainRecord;\n  IsInjected: Boolean;\n  Group     : IwbGroupRecord;\n  i         : Integer;\n\n  SelfRef   : IwbContainerElementRef;\nbegin\n  SelfRef := Self as IwbContainerElementRef;\n\n  Result := nil;\n  if Length(aName) < 4 then\n    Exit;\n  Signature := StrToSignature(aName);\n\n  case grStruct.grsGroupType of\n    0: if Signature <> TwbSignature(grStruct.grsLabel) then\n         Exit;\n    1: if (Signature <> 'ROAD') and\n          (Signature <> 'CELL') then\n         Exit;\n    7: if (Signature <> 'INFO') then\n         Exit;\n    6: begin\n      Group := nil;\n      for i := 0 to GetElementCount do\n        if Supports(GetElement(i), IwbGroupRecord, Group) then\n          if (Group.GroupType = 9) and (Group.GroupLabel = GetGroupLabel) then\n            Break\n          else\n            Group := nil;\n      if not Assigned(Group) then\n        Group := TwbGroupRecord.Create(Self, 9, GetGroupLabel);\n\n      Result := Group.Add(aName, aSilent);\n      Exit;\n    end;\n    8: if (Signature <> 'REFR') and\n          (Signature <> 'ACRE') and\n          (Signature <> 'PGRE') and\n          (Signature <> 'PMIS') and\n          (Signature <> 'PARW') and {>>> Skyrim <<<}\n          (Signature <> 'PBEA') and {>>> Skyrim <<<}\n          (Signature <> 'PFLA') and {>>> Skyrim <<<}\n          (Signature <> 'PCON') and {>>> Skyrim <<<}\n          (Signature <> 'PBAR') and {>>> Skyrim <<<}\n          (Signature <> 'PHZD') and {>>> Skyrim <<<}\n          (Signature <> 'ACHR') then\n         Exit;\n    9: if (Signature <> 'LAND') and\n          (Signature <> 'PGRD') and\n          (Signature <> 'NAVM') and\n          (Signature <> 'REFR') and\n          (Signature <> 'PGRE') and\n          (Signature <> 'PMIS') and\n          (Signature <> 'PARW') and {>>> Skyrim <<<}\n          (Signature <> 'PBEA') and {>>> Skyrim <<<}\n          (Signature <> 'PFLA') and {>>> Skyrim <<<}\n          (Signature <> 'PCON') and {>>> Skyrim <<<}\n          (Signature <> 'PBAR') and {>>> Skyrim <<<}\n          (Signature <> 'PHZD') and {>>> Skyrim <<<}\n          (Signature <> 'ACRE') and\n          (Signature <> 'ACHR') then\n         Exit;\n   10: if (not wbVWDAsQuestChildren and (Signature <> 'REFR')) or\n          (wbVWDAsQuestChildren and\n             not ((Signature = 'REFR') or (Signature = 'DLBR') or (Signature = 'DIAL') or (Signature = 'SCEN')))\n       then\n         Exit;\n  else\n    Exit;\n  end;\n\n  _File := GetFile;\n  if not Assigned(_File) then\n    Exit;\n\n  if aSilent then\n    FormID := _File.NewFormID\n  else\n    FormID := _File.LoadOrderFormIDtoFileFormID(wbGetFormID(Self));\n  if FormID = 0 then\n    Exit;\n\n  IsInjected := False;\n  MainRecord := _File.RecordByFormID[FormID, True];\n  if Assigned(MainRecord) then begin\n    if _File.Equals(MainRecord._File) then\n      raise Exception.Create('FormID ['+IntToHex64(FormID, 8)+'] is already defined in file \"'+_File.Name+'\"');\n\n    IsInjected := (FormID shr 24) = Cardinal(_File.MasterCount);\n\n    if MainRecord.Signature <> Signature then\n      raise Exception.Create('Existing record '+MainRecord.Name+' has different signature');\n  end;\n\n  Result := TwbMainRecord.Create(Self, Signature, FormID);\n  if IsInjected then\n    (MainRecord as IwbMainRecordInternal).YouGotAMaster(Result as IwbMainRecord);\n  if csRefsBuild in _File.ContainerStates then\n    Result.BuildRef;\nend;\n\nfunction RemovePrefix(const s, aPrefix: string): string;\nbegin\n  if SameText(Copy(s, 1, Length(aPrefix)), aPrefix) then\n    Result := Copy(s, Succ(Length(aPrefix)), High(Integer))\n  else\n    Result := s;\nend;\n\nprocedure TwbGroupRecord.AddElement(const aElement: IwbElement);\nvar\n  DialGroup : IwbGroupRecord;\n  Container : IwbContainer;\n  DialRec   : IwbMainRecord;\n  i         : Integer;\nbegin\n  if esUnsaved in aElement.ElementStates then  // Let's not penalised too much loading time.\n    if ((TwbSignature(grStruct.grsLabel) = 'DIAL') or wbVWDAsQuestChildren) then  // Issue 86: https://code.google.com/p/skyrim-plugin-decoding-project/issues/detail?id=86\n      if Supports(aElement, IwbGroupRecord, DialGroup) then // The DIAL GRUP must immediatly follow corresponding DIAL MainRecord.\n        if DialGroup.GroupType = 7 then // Let's hope nobody messes up the groupType\n          if Supports(Self, IwbContainer, Container) then\n            if Container.ElementCount > 0 then\n              for i := 0 to Pred(Container.ElementCount) - 1 do  // If we are reading the plugins and at the end don't bother moving data around.\n                if Supports(Container.Elements[i], IwbMainRecord, DialRec) then\n                  if DialRec.Signature = 'DIAL' then\n                    if DialRec.FormID = DialGroup.GroupLabel then begin\n                      InsertElement(i+1, aElement);\n                      Exit;\n                    end;\n    inherited;\nend;\n\nfunction TwbGroupRecord.AddIfMissingInternal(const aElement: IwbElement; aAsNew, aDeepCopy : Boolean; const aPrefixRemove, aPrefix, aSuffix: string): IwbElement;\nvar\n  MainRecord   : IwbMainRecord;\n  MainRecord2  : IwbMainRecord;\n  FormID       : Cardinal;\n  i            : Integer;\n  SelfRef      : IwbContainerElementRef;\n  s            : string;\n  GroupRecord  : IwbGroupRecord;\n  GroupRecord2 : IwbGroupRecord;\nbegin\n  Result := nil;\n  SelfRef := Self as IwbContainerElementRef;\n  case grStruct.grsGroupType of\n    0: begin\n      if TwbSignature(grStruct.grsLabel) = 'DIAL' then begin\n        if Supports(aElement, IwbGroupRecord, GroupRecord) then begin\n          if GroupRecord.GroupType <> 7 then\n            raise Exception.Create('Can''t add '+GroupRecord.Name+' to top level group with signature ' + TwbSignature(grStruct.grsLabel));\n          MainRecord := GroupRecord.ChildrenOf;\n          if not Assigned(MainRecord) then\n            raise Exception.Create('Can''t find record for '+ GroupRecord.Name);\n          MainRecord := MainRecord.HighestOverrideOrSelf[GetFile.LoadOrder];\n          MainRecord := AddIfMissingInternal(MainRecord, aAsNew, True, aPrefixRemove, aPrefix, aSuffix) as IwbMainRecord;\n          Assert(Assigned(MainRecord));\n          Result := MainRecord.ChildGroup;\n          if not Assigned(Result) then\n            Result := TwbGroupRecord.Create(Self, 7, MainRecord);\n\n          GroupRecord2 := Result as IwbGroupRecord;\n          if aDeepCopy then\n            for i := 0 to Pred(GroupRecord.ElementCount) do\n              GroupRecord2.AddIfMissing(GroupRecord.Elements[i], aAsNew, aDeepCopy, aPrefixRemove, aPrefix, aSuffix);\n\n          Exit;\n        end;\n      end else if TwbSignature(grStruct.grsLabel) = 'CELL' then begin\n        if Supports(aElement, IwbGroupRecord, GroupRecord) then begin\n          if GroupRecord.GroupType <> 2 then\n            raise Exception.Create('Can''t add '+GroupRecord.Name+' to top level group with signature ' + TwbSignature(grStruct.grsLabel));\n          if GroupRecord.GroupLabel > 9 then\n            raise Exception.Create('Can''t add '+GroupRecord.Name+' to top level group with signature ' + TwbSignature(grStruct.grsLabel));\n          for i := 0 to Pred(GetElementCount) do\n            if Supports(GetElement(i), IwbGroupRecord, GroupRecord2) then begin\n              if (GroupRecord2.GroupType = 2) and (GroupRecord2.GroupLabel = GroupRecord.GroupLabel) then begin\n                Result := GroupRecord2;\n                break;\n              end;\n            end;\n          if not Assigned(Result) then\n            Result := TwbGroupRecord.Create(Self, 2, GroupRecord.GroupLabel);\n\n          GroupRecord2 := Result as IwbGroupRecord;\n          if aDeepCopy then\n            for i := 0 to Pred(GroupRecord.ElementCount) do\n              GroupRecord2.AddIfMissing(GroupRecord.Elements[i], aAsNew, aDeepCopy, aPrefixRemove, aPrefix, aSuffix);\n\n          Exit;\n        end;\n      end else if TwbSignature(grStruct.grsLabel) = 'WRLD' then begin\n        if Supports(aElement, IwbGroupRecord, GroupRecord) then begin\n          if GroupRecord.GroupType <> 1 then\n            raise Exception.Create('Can''t add '+GroupRecord.Name+' to top level group with signature ' + TwbSignature(grStruct.grsLabel));\n          MainRecord := GroupRecord.ChildrenOf;\n          if not Assigned(MainRecord) then\n            raise Exception.Create('Can''t find record for '+ GroupRecord.Name);\n          MainRecord := MainRecord.HighestOverrideOrSelf[GetFile.LoadOrder];\n          MainRecord := AddIfMissingInternal(MainRecord, aAsNew, True, aPrefixRemove, aPrefix, aSuffix) as IwbMainRecord;\n          Assert(Assigned(MainRecord));\n          Result := MainRecord.ChildGroup;\n          if not Assigned(Result) then\n            Result := TwbGroupRecord.Create(Self, 1, MainRecord);\n\n          GroupRecord2 := Result as IwbGroupRecord;\n          if aDeepCopy then\n            for i := 0 to Pred(GroupRecord.ElementCount) do\n              GroupRecord2.AddIfMissing(GroupRecord.Elements[i], aAsNew, aDeepCopy, aPrefixRemove, aPrefix, aSuffix);\n\n          Exit;\n        end;\n      end else if wbVWDAsQuestChildren and (TwbSignature(grStruct.grsLabel) = 'QUST') then begin\n        if Supports(aElement, IwbGroupRecord, GroupRecord) then begin\n          if GroupRecord.GroupType <> 10 then\n            raise Exception.Create('Can''t add '+GroupRecord.Name+' to top level group with signature ' + TwbSignature(grStruct.grsLabel));\n          MainRecord := GroupRecord.ChildrenOf;\n          if not Assigned(MainRecord) then\n            raise Exception.Create('Can''t find record for '+ GroupRecord.Name);\n          MainRecord := MainRecord.HighestOverrideOrSelf[GetFile.LoadOrder];\n          MainRecord := AddIfMissingInternal(MainRecord, aAsNew, True, aPrefixRemove, aPrefix, aSuffix) as IwbMainRecord;\n          Assert(Assigned(MainRecord));\n          Result := MainRecord.ChildGroup;\n          if not Assigned(Result) then\n            Result := TwbGroupRecord.Create(Self, 10, MainRecord);\n\n          GroupRecord2 := Result as IwbGroupRecord;\n          if aDeepCopy then\n            for i := 0 to Pred(GroupRecord.ElementCount) do\n              GroupRecord2.AddIfMissing(GroupRecord.Elements[i], aAsNew, aDeepCopy, aPrefixRemove, aPrefix, aSuffix);\n\n          Exit;\n        end;\n      end;\n      if not Supports(aElement, IwbMainRecord, MainRecord) then\n        raise Exception.Create('Only main records can be added to top level groups');\n      if MainRecord.Signature <> TwbSignature(grStruct.grsLabel) then\n        raise Exception.Create('Can''t add main record with signature '+MainRecord.Signature+' to top level group with signature ' + TwbSignature(grStruct.grsLabel));\n\n      if aAsNew then\n        FormID := GetFile.NewFormID\n      else begin\n        FormID := GetFile.LoadOrderFormIDtoFileFormID(MainRecord.LoadOrderFormID);\n        for i := Low(cntElements) to High(cntElements) do\n          if Supports(cntElements[i], IwbMainRecord, MainRecord2) then\n            if MainRecord2.FixedFormID = FormID then begin\n              Result := MainRecord2;\n              exit;\n            end;\n      end;\n\n      Result := TwbMainRecord.Create(Self, MainRecord.Signature, FormID);\n      if aDeepCopy then begin\n        Result.Assign(Low(Integer), aElement, False);\n        if (aPrefix <> '') or (aSuffix <> '') then\n          with Result as IwbMainRecord do begin\n            s := EditorID;\n            s := RemovePrefix(s, aPrefixRemove);\n            if s <> '' then\n              EditorID := aPrefix + s + aSuffix;\n          end;\n      end;\n\n      if not aAsNew and MainRecord.IsMaster and (Result._File.LoadOrder <= MainRecord._File.LoadOrder) then\n        if Supports(Result, IwbMainRecord, MainRecord2) then\n          (MainRecord as IwbMainRecordInternal).YouGotAMaster(MainRecord2);\n      if Assigned(Result) and (csRefsBuild in Result._File.ContainerStates) then\n        Result.BuildRef;\n    end;\n    1: begin\n        if Supports(aElement, IwbGroupRecord, GroupRecord) then begin\n          if GroupRecord.GroupType = 4 then begin\n            for i := 0 to Pred(GetElementCount) do\n              if Supports(GetElement(i), IwbGroupRecord, GroupRecord2) then begin\n                if (GroupRecord2.GroupType = GroupRecord.GroupType) and (GroupRecord2.GroupLabel = GroupRecord.GroupLabel) then begin\n                  Result := GroupRecord2;\n                  break;\n                end;\n              end;\n            if not Assigned(Result) then\n              Result := TwbGroupRecord.Create(Self, 4, GroupRecord.GroupLabel);\n\n            GroupRecord2 := Result as IwbGroupRecord;\n            if aDeepCopy then\n              for i := 0 to Pred(GroupRecord.ElementCount) do\n                GroupRecord2.AddIfMissing(GroupRecord.Elements[i], aAsNew, aDeepCopy, aPrefixRemove, aPrefix, aSuffix);\n\n            Exit;\n          end;\n          if GroupRecord.GroupType <> 6 then\n            raise Exception.Create('Can''t add '+GroupRecord.Name+' to top level group with signature ' + TwbSignature(grStruct.grsLabel));\n          MainRecord := GroupRecord.ChildrenOf;\n          if not Assigned(MainRecord) then\n            raise Exception.Create('Can''t find record for '+ GroupRecord.Name);\n          MainRecord := MainRecord.HighestOverrideOrSelf[GetFile.LoadOrder];\n          MainRecord := AddIfMissingInternal(MainRecord, aAsNew, True, aPrefixRemove, aPrefix, aSuffix) as IwbMainRecord;\n          Assert(Assigned(MainRecord));\n          Result := MainRecord.ChildGroup;\n          if not Assigned(Result) then\n            Result := TwbGroupRecord.Create(Self, 6, MainRecord);\n\n          GroupRecord2 := Result as IwbGroupRecord;\n          if aDeepCopy then\n            for i := 0 to Pred(GroupRecord.ElementCount) do\n              GroupRecord2.AddIfMissing(GroupRecord.Elements[i], aAsNew, aDeepCopy, aPrefixRemove, aPrefix, aSuffix);\n\n          Exit;\n        end;\n      if not Supports(aElement, IwbMainRecord, MainRecord) then\n        raise Exception.Create('Only main records can be added to ' + GetName);\n      if (MainRecord.Signature <> 'CELL') and (MainRecord.Signature <> 'ROAD') then\n        raise Exception.Create('Can''t add main record with signature '+MainRecord.Signature+' to ' + GetName);\n\n      if aAsNew then\n        raise Exception.Create('Can''t copy record '+MainRecord.Name+' as new record.')\n      else begin\n        FormID := GetFile.LoadOrderFormIDtoFileFormID(MainRecord.LoadOrderFormID);\n        for i := Low(cntElements) to High(cntElements) do\n          if Supports(cntElements[i], IwbMainRecord, MainRecord2) then\n            if MainRecord2.FixedFormID = FormID then begin\n              Result := MainRecord2;\n              exit;\n            end;\n      end;\n      Result := TwbMainRecord.Create(Self, MainRecord.Signature, FormID);\n      if aDeepCopy then begin\n        Result.Assign(Low(Integer), aElement, False);\n        if (aPrefix <> '') or (aSuffix <> '') then\n          with Result as IwbMainRecord do begin\n            s := EditorID;\n            s := RemovePrefix(s, aPrefixRemove);\n            if s <> '' then\n              EditorID := aPrefix + s + aSuffix;\n          end;\n      end;\n      if not aAsNew and MainRecord.IsMaster and (Result._File.LoadOrder <= MainRecord._File.LoadOrder) then\n        if Supports(Result, IwbMainRecord, MainRecord2) then\n          (MainRecord as IwbMainRecordInternal).YouGotAMaster(MainRecord2);\n      if Assigned(Result) and (csRefsBuild in Result._File.ContainerStates) then\n        Result.BuildRef;\n    end;\n    2, 4: begin\n      if Supports(aElement, IwbGroupRecord, GroupRecord) then begin\n        if GroupRecord.GroupType <> grStruct.grsGroupType + 1 then\n          raise Exception.Create('Can''t add '+GroupRecord.Name+' to ' + GetName);\n        for i := 0 to Pred(GetElementCount) do\n          if Supports(GetElement(i), IwbGroupRecord, GroupRecord2) then begin\n            if (GroupRecord2.GroupType = GroupRecord.GroupType) and (GroupRecord2.GroupLabel = GroupRecord.GroupLabel) then begin\n              Result := GroupRecord2;\n              break;\n            end;\n          end;\n        if not Assigned(Result) then\n          Result := TwbGroupRecord.Create(Self, GroupRecord.GroupType, GroupRecord.GroupLabel);\n\n        GroupRecord2 := Result as IwbGroupRecord;\n        if aDeepCopy then\n          for i := 0 to Pred(GroupRecord.ElementCount) do\n            GroupRecord2.AddIfMissing(GroupRecord.Elements[i], aAsNew, aDeepCopy, aPrefixRemove, aPrefix, aSuffix);\n\n        Exit;\n      end;\n      raise Exception.Create('Can''t add ' + aElement.Name + ' to ' + GetName);\n    end;\n    3, 5: begin\n        if Supports(aElement, IwbGroupRecord, GroupRecord) then begin\n          if GroupRecord.GroupType <> 6 then\n            raise Exception.Create('Can''t add '+GroupRecord.Name+' to top level group with signature ' + TwbSignature(grStruct.grsLabel));\n          MainRecord := GroupRecord.ChildrenOf;\n          if not Assigned(MainRecord) then\n            raise Exception.Create('Can''t find record for '+ GroupRecord.Name);\n          MainRecord := MainRecord.HighestOverrideOrSelf[GetFile.LoadOrder];\n          MainRecord := AddIfMissingInternal(MainRecord, aAsNew, True, aPrefixRemove, aPrefix, aSuffix) as IwbMainRecord;\n          Assert(Assigned(MainRecord));\n          Result := MainRecord.ChildGroup;\n          if not Assigned(Result) then\n            Result := TwbGroupRecord.Create(Self, 6, MainRecord);\n\n          GroupRecord2 := Result as IwbGroupRecord;\n          if aDeepCopy then\n            for i := 0 to Pred(GroupRecord.ElementCount) do\n              GroupRecord2.AddIfMissing(GroupRecord.Elements[i], aAsNew, aDeepCopy, aPrefixRemove, aPrefix, aSuffix);\n\n          Exit;\n        end;\n      if not Supports(aElement, IwbMainRecord, MainRecord) then\n        raise Exception.Create('Only main records can be added to ' + GetName);\n      if MainRecord.Signature <> 'CELL' then\n        raise Exception.Create('Can''t add main record with signature '+MainRecord.Signature+' to ' + GetName);\n\n      if aAsNew then\n        raise Exception.Create('Can''t copy record '+MainRecord.Name+' as new record.')\n      else begin\n        FormID := GetFile.LoadOrderFormIDtoFileFormID(MainRecord.LoadOrderFormID);\n        for i := Low(cntElements) to High(cntElements) do\n          if Supports(cntElements[i], IwbMainRecord, MainRecord2) then\n            if MainRecord2.FixedFormID = FormID then begin\n              Result := MainRecord2;\n              exit;\n            end;\n      end;\n      Result := TwbMainRecord.Create(Self, MainRecord.Signature, FormID);\n      if aDeepCopy then begin\n        Result.Assign(Low(Integer), aElement, False);\n        if (aPrefix <> '') or (aSuffix <> '') then\n          with Result as IwbMainRecord do begin\n            s := EditorID;\n            s := RemovePrefix(s, aPrefixRemove);\n            if s <> '' then\n              EditorID := aPrefix + s + aSuffix;\n          end;\n      end;\n      if not aAsNew and MainRecord.IsMaster and (Result._File.LoadOrder <= MainRecord._File.LoadOrder) then\n        if Supports(Result, IwbMainRecord, MainRecord2) then\n          (MainRecord as IwbMainRecordInternal).YouGotAMaster(MainRecord2);\n      if Assigned(Result) and (csRefsBuild in Result._File.ContainerStates) then\n        Result.BuildRef;\n    end;\n    6: begin\n      if Supports(aElement, IwbGroupRecord, GroupRecord) then begin\n        if not (GroupRecord.GroupType in [8, 9, 10]) then\n          raise Exception.Create('Can''t add '+GroupRecord.Name+' to ' + GetName);\n        for i := 0 to Pred(GetElementCount) do\n          if Supports(GetElement(i), IwbGroupRecord, GroupRecord2) then begin\n            if GroupRecord2.GroupType = GroupRecord.GroupType then begin\n              Result := GroupRecord2;\n              break;\n            end;\n          end;\n        if not Assigned(Result) then\n          Result := TwbGroupRecord.Create(Self, GroupRecord.GroupType, Self.GetChildrenOf);\n\n        GroupRecord2 := Result as IwbGroupRecord;\n        if aDeepCopy then\n          for i := 0 to Pred(GroupRecord.ElementCount) do\n            GroupRecord2.AddIfMissing(GroupRecord.Elements[i], aAsNew, aDeepCopy, aPrefixRemove, aPrefix, aSuffix);\n\n        Exit;\n      end;\n      raise Exception.Create('Can''t add ' + aElement.Name + ' to ' + GetName);\n    end;\n    7: begin\n      if not Supports(aElement, IwbMainRecord, MainRecord) then\n        raise Exception.Create('Only main records can be added to ' + GetName);\n      if MainRecord.Signature <> 'INFO' then\n        raise Exception.Create('Can''t add main record with signature '+MainRecord.Signature+' to ' + GetName);\n\n      if aAsNew then\n        FormID := GetFile.NewFormID\n      else begin\n        FormID := GetFile.LoadOrderFormIDtoFileFormID(MainRecord.LoadOrderFormID);\n        for i := Low(cntElements) to High(cntElements) do\n          if Supports(cntElements[i], IwbMainRecord, MainRecord2) then\n            if MainRecord2.FixedFormID = FormID then begin\n              Result := MainRecord2;\n              exit;\n            end;\n      end;\n\n      Result := TwbMainRecord.Create(Self, MainRecord.Signature, FormID);\n      if aDeepCopy then begin\n        Result.Assign(Low(Integer), aElement, False);\n        if (aPrefix <> '') or (aSuffix <> '') then\n          with Result as IwbMainRecord do begin\n            s := EditorID;\n            s := RemovePrefix(s, aPrefixRemove);\n            if s <> '' then\n              EditorID := aPrefix + s + aSuffix;\n          end;\n      end;\n      if not aAsNew and MainRecord.IsMaster and (Result._File.LoadOrder <= MainRecord._File.LoadOrder) then\n        if Supports(Result, IwbMainRecord, MainRecord2) then\n          (MainRecord as IwbMainRecordInternal).YouGotAMaster(MainRecord2);\n      if Assigned(Result) and (csRefsBuild in Result._File.ContainerStates) then\n        Result.BuildRef;\n    end;\n    8, 9, 10: begin\n      if wbVWDAsQuestChildren and Supports(aElement, IwbGroupRecord, GroupRecord) then begin\n        if GroupRecord.GroupType <> 7 then\n          raise Exception.Create('Can''t add '+GroupRecord.Name+' to top level group with signature ' + TwbSignature(grStruct.grsLabel));\n        MainRecord := GroupRecord.ChildrenOf;\n        if not Assigned(MainRecord) then\n          raise Exception.Create('Can''t find record for '+ GroupRecord.Name);\n        MainRecord := MainRecord.HighestOverrideOrSelf[GetFile.LoadOrder];\n        MainRecord := AddIfMissingInternal(MainRecord, aAsNew, True, aPrefixRemove, aPrefix, aSuffix) as IwbMainRecord;\n        Assert(Assigned(MainRecord));\n        Result := MainRecord.ChildGroup;\n        if not Assigned(Result) then\n          Result := TwbGroupRecord.Create(Self, 7, MainRecord);\n\n        GroupRecord2 := Result as IwbGroupRecord;\n        if aDeepCopy then\n          for i := 0 to Pred(GroupRecord.ElementCount) do\n            GroupRecord2.AddIfMissing(GroupRecord.Elements[i], aAsNew, aDeepCopy, aPrefixRemove, aPrefix, aSuffix);\n\n        Exit;\n      end;\n      if not Supports(aElement, IwbMainRecord, MainRecord) then\n        raise Exception.Create('Only main records can be added to ' + GetName);\n      if (MainRecord.Signature <> 'REFR') and\n         (MainRecord.Signature <> 'ACHR') and\n         (MainRecord.Signature <> 'ACRE') and\n         (MainRecord.Signature <> 'PGRE') and\n         (MainRecord.Signature <> 'PMIS') and\n         (MainRecord.Signature <> 'PARW') and {>>> Skyrim <<<}\n         (MainRecord.Signature <> 'PBEA') and {>>> Skyrim <<<}\n         (MainRecord.Signature <> 'PFLA') and {>>> Skyrim <<<}\n         (MainRecord.Signature <> 'PCON') and {>>> Skyrim <<<}\n         (MainRecord.Signature <> 'PBAR') and {>>> Skyrim <<<}\n         (MainRecord.Signature <> 'PHZD')     {>>> Skyrim <<<}\n      then\n        // check any non reference record\n        if not (\n          // DIAL, DLBR and SCEN can be added to child group 10 (quest children)\n          (wbVWDAsQuestChildren and (grStruct.grsGroupType = 10) and ((MainRecord.Signature = 'DLBR') or (MainRecord.Signature = 'DIAL') or (MainRecord.Signature = 'SCEN')))\n          or\n          // PGRD, LAND and NAVM can be added to child group 9 (temporary)\n          (grStruct.grsGroupType = 9) and ((MainRecord.Signature = 'PGRD') or (MainRecord.Signature = 'LAND') or (MainRecord.Signature = 'NAVM'))\n        ) then\n          raise Exception.Create('Can''t add main record with signature '+MainRecord.Signature+' to ' + GetName);\n\n      if aAsNew then\n        FormID := GetFile.NewFormID\n      else begin\n        FormID := GetFile.LoadOrderFormIDtoFileFormID(MainRecord.LoadOrderFormID);\n        for i := Low(cntElements) to High(cntElements) do\n          if Supports(cntElements[i], IwbMainRecord, MainRecord2) then\n            if MainRecord2.FixedFormID = FormID then begin\n              Result := MainRecord2;\n              exit;\n            end;\n      end;\n\n      Result := TwbMainRecord.Create(Self, MainRecord.Signature, FormID);\n      if aDeepCopy then begin\n        Result.Assign(Low(Integer), aElement, False);\n        if (aPrefix <> '') or (aSuffix <> '') then\n          with Result as IwbMainRecord do begin\n            s := EditorID;\n            s := RemovePrefix(s, aPrefixRemove);\n            if s <> '' then\n              EditorID := aPrefix + s + aSuffix;\n          end;\n      end;\n      if not aAsNew and MainRecord.IsMaster and (Result._File.LoadOrder <= MainRecord._File.LoadOrder) then\n        if Supports(Result, IwbMainRecord, MainRecord2) then\n          (MainRecord as IwbMainRecordInternal).YouGotAMaster(MainRecord2);\n      if Assigned(Result) and (csRefsBuild in Result._File.ContainerStates) then\n        Result.BuildRef;\n    end;\n  else\n    raise Exception.Create(ClassName + '.AddIfMissingInternal is not implemented for GroupType ' + IntToStr(grStruct.grsGroupType));\n  end;\nend;\n\nprocedure TwbGroupRecord.BuildRef;\nvar\n  Rec: IwbMainRecord;\nbegin\n  inherited;\n  if GetGroupType in [1, 6, 7] then begin\n    Rec := (GetFile as IwbFileInternal).RecordByFormID[GetGroupLabel, False];\n    if Assigned(Rec) then begin\n      if Rec._File.Equals(GetFile) then\n        (Rec as IwbMainRecordInternal).SetChildGroup(Self)\n      else begin\n        if Assigned(wbProgressCallback) then\n          wbProgressCallback('<Warning: File ' + GetFile.Name + ' with Group ' + GetName + ' is missing an overriden record for ' + Rec.Name);\n      end;\n    end;\n  end;\nend;\n\nconstructor TwbGroupRecord.Create(const aContainer: IwbContainer; aType: Integer; const aMainRecord: IwbMainRecord);\nvar\n  BasePtr : PwbGroupRecordStruct;\nbegin\n  Assert(Assigned(aContainer));\n  Assert(Assigned(aMainRecord));\n  Assert(aContainer._File.Equals(aMainRecord._File));\n  Assert(aType in [1, 6, 7, 8, 9, 10]);\n\n  if aType in [1, 6, 7] then\n    Assert(aContainer.Equals(aMainRecord.Container));\n\n  case aType of\n    1: Assert(aMainRecord.Signature = 'WRLD');\n    6, 8, 9: Assert(aMainRecord.Signature = 'CELL');\n    10: Assert(\n      (aMainRecord.Signature = 'CELL') or\n      (wbVWDAsQuestChildren and (aMainRecord.Signature = 'QUST'))\n    );\n    7: Assert(aMainRecord.Signature = 'DIAL');\n  end;\n\n  Assert(aContainer.ElementType = etGroupRecord);\n\n  New(BasePtr);\n  BasePtr.grsSignature := 'GRUP';\n  BasePtr.grsGroupSize := wbSizeOfMainRecordStruct;\n  BasePtr.grsLabel := aMainRecord.FormID;\n  BasePtr.grsGroupType := aType;\n  BasePtr.grsStamp := 0;\n  BasePtr.grsUnknown := 0;\n  Include(eStates, esUnsaved);\n  Create(aContainer, Pointer(BasePtr), nil, nil);\n  SetModified(True);\n  InvalidateStorage;\n  BuildRef;\n  (aContainer as IwbGroupRecordInternal).Sort;\nend;\n\nconstructor TwbGroupRecord.Create(const aContainer: IwbContainer; aType: Integer; aLabel: Cardinal);\nvar\n  BasePtr : PwbGroupRecordStruct;\nbegin\n  Assert(Assigned(aContainer));\n  Assert(aType in [2, 3, 4, 5]);\n  Assert(aContainer.ElementType = etGroupRecord);\n\n  New(BasePtr);\n  BasePtr.grsSignature := 'GRUP';\n  BasePtr.grsGroupSize := wbSizeOfMainRecordStruct;\n  BasePtr.grsLabel := aLabel;\n  BasePtr.grsGroupType := aType;\n  BasePtr.grsStamp := 0;\n  BasePtr.grsUnknown := 0;\n  Create(aContainer, Pointer(BasePtr), nil, nil);\n  SetModified(True);\n  InvalidateStorage;\n  (aContainer as IwbGroupRecordInternal).Sort;\nend;\n\nconstructor TwbGroupRecord.Create(const aContainer: IwbContainer; const aSignature: TwbSignature);\nvar\n  BasePtr : PwbGroupRecordStruct;\nbegin\n  New(BasePtr);\n  BasePtr.grsSignature := 'GRUP';\n  BasePtr.grsGroupSize := wbSizeOfMainRecordStruct;\n  BasePtr.grsLabel := Cardinal(aSignature);\n  BasePtr.grsGroupType := 0;\n  BasePtr.grsStamp := 0;\n  BasePtr.grsUnknown := 0;\n  Create(aContainer, Pointer(BasePtr), nil, nil);\n  SetModified(True);\n  InvalidateStorage;\nend;\n\ndestructor TwbGroupRecord.Destroy;\nbegin\n  if Assigned(dcBasePtr) and not Assigned(dcEndPtr) then begin\n    FreeMem(dcBasePtr, SizeOf(TwbGroupRecordStruct));\n    dcBasePtr := nil;\n  end;\n  inherited;\nend;\n\nfunction TwbGroupRecord.FindChildGroup(aType: Integer; aMainRecord: IwbMainRecord): IwbGroupRecord;\nvar\n  SelfRef : IwbContainerElementRef;\n  i       : Integer;\nbegin\n  Result := nil;\n\n  SelfRef := Self;\n  DoInit;\n  for i := Low(cntElements) to High(cntElements) do\n    if Supports(cntElements[i], IwbGroupRecord, Result) then\n      if Result.GroupType = aType then\n        if Result.GroupLabel = aMainRecord.FormID then\n          Exit;\n  Result := nil;\nend;\n\nprocedure TwbGroupRecord.FindUsedMasters(aMasters: PwbUsedMasters);\nvar\n  FileID: Integer;\nbegin\n  inherited;\n\n  if grStruct.grsGroupType in [1, 6..10] then begin\n    if grStruct.grsLabel <> 0 then begin\n      FileID := grStruct.grsLabel shr 24;\n      aMasters[FileID] := True;\n    end;\n  end;\nend;\n\nfunction TwbGroupRecord.GetAddList: TDynStrings;\nvar\n  i, j      : Integer;\n  RecordDef : PwbRecordDef;\nbegin\n  Result := nil;\n  case grStruct.grsGroupType of\n    0: begin\n         SetLength(Result, 1);\n         Result[0] := TwbSignature(grStruct.grsLabel);\n       end;\n    7: begin\n         SetLength(Result, 1);\n         Result[0] := 'INFO';\n       end;\n    8: begin\n         SetLength(Result, 11);\n         Result[0] := 'ACHR';\n         Result[1] := 'ACRE';\n         Result[2] := 'REFR';\n         Result[3] := 'PGRE';\n         Result[4] := 'PMIS';\n         Result[5] := 'PARW'; {>>> Skyrim <<<}\n         Result[6] := 'PBEA'; {>>> Skyrim <<<}\n         Result[7] := 'PFLA'; {>>> Skyrim <<<}\n         Result[8] := 'PCON'; {>>> Skyrim <<<}\n         Result[9] := 'PBAR'; {>>> Skyrim <<<}\n         Result[10] := 'PHZD'; {>>> Skyrim <<<}\n       end;\n    6, 9: begin\n         SetLength(Result, 11);\n         Result[0] := 'ACHR';\n         Result[1] := 'ACRE';\n         Result[2] := 'REFR';\n         Result[3] := 'PGRE';\n         Result[4] := 'PMIS';\n         Result[5] := 'PARW'; {>>> Skyrim <<<}\n         Result[6] := 'PBEA'; {>>> Skyrim <<<}\n         Result[7] := 'PFLA'; {>>> Skyrim <<<}\n         Result[8] := 'PCON'; {>>> Skyrim <<<}\n         Result[9] := 'PBAR'; {>>> Skyrim <<<}\n         Result[10] := 'PHZD'; {>>> Skyrim <<<}\n       end;\n    10: if wbVWDAsQuestChildren then begin\n         SetLength(Result, 3);\n         Result[0] := 'DIAL';\n         Result[1] := 'DLBR';\n         Result[2] := 'SCEN';\n      end\n      else begin\n         SetLength(Result, 1);\n         Result[0] := 'REFR';\n       end;\n  end;\n  j := 0;\n  for i := Low(Result) to High(Result) do\n    if wbFindRecordDef(AnsiString(Result[i]), RecordDef) then begin\n      Result[j] := Result[i] + ' - ' + RecordDef.Name;\n      Inc(j);\n    end;\n  SetLength(Result, j);\nend;\n\nfunction TwbGroupRecord.GetChildrenOf: IwbMainRecord;\nbegin\n  Result := nil;\n  if grStruct.grsGroupType in [1, 6..10] then\n    Result := GetFile.RecordByFormID[grStruct.grsLabel, True];\nend;\n\nfunction TwbGroupRecord.GetElementType: TwbElementType;\nbegin\n  Result := etGroupRecord;\nend;\n\nfunction TwbGroupRecord.GetGroupLabel: Cardinal;\nbegin\n  Result := grStruct.grsLabel;\nend;\n\nfunction TwbGroupRecord.GetGroupType: Integer;\nbegin\n  Result := grStruct.grsGroupType;\nend;\n\nfunction TwbGroupRecord.GetMainRecordByEditorID(const aEditorID: string): IwbMainRecord;\nvar\n  SelfRef : IwbContainerElementRef;\n  i       : Integer;\nbegin\n  Result := nil;\n\n  SelfRef := Self;\n  DoInit;\n  for i := Low(cntElements) to High(cntElements) do\n    if Supports(cntElements[i], IwbMainRecord, Result) then\n      if SameText(Result.EditorID, aEditorID) then\n        Exit;\n  Result := nil;\nend;\n\nfunction TwbGroupRecord.GetMainRecordByFormID(const aFormID: Cardinal): IwbMainRecord;\nvar\n  SelfRef : IwbContainerElementRef;\n  i       : Integer;\nbegin\n  Result := nil;\n\n  SelfRef := Self;\n  DoInit;\n  for i := Low(cntElements) to High(cntElements) do\n    if Supports(cntElements[i], IwbMainRecord, Result) then\n      if Result.FormID = aFormID then\n        Exit;\n  Result := nil;\nend;\n\nfunction TwbGroupRecord.GetName: string;\nbegin\n  Result := inherited GetName;\n\n  case grStruct.grsGroupType of\n    0: begin\n      Result := Result + ' Top \"' + PwbSignature(@grStruct.grsLabel)^ + '\"';\n      Exit;\n    end;\n    1: Result := Result + ' World Children of ';\n    2: begin\n      Result := Result + ' Interior Cell Block ' + IntToStr(grStruct.grsLabel);\n      Exit;\n    end;\n    3: begin\n      Result := Result + ' Interior Cell Sub-Block ' + IntToStr(grStruct.grsLabel);\n      Exit;\n    end;\n    4: begin\n      Result := Result + ' Exterior Cell Block ' + IntToStr(LongRecSmall(grStruct.grsLabel).Lo) + ', ' + IntToStr(LongRecSmall(grStruct.grsLabel).Hi);\n      Exit;\n    end;\n    5: begin\n      Result := Result + ' Exterior Cell Sub-Block ' + IntToStr(LongRecSmall(grStruct.grsLabel).Lo) + ', ' + IntToStr(LongRecSmall(grStruct.grsLabel).Hi);\n      Exit;\n    end;\n    6: Result := Result + ' Cell Children of ';\n    7: Result := Result + ' Topic Children of ';\n    8: Result := Result + ' Cell Persistent Children of ';\n    9: Result := Result + ' Cell Temporary Children of ';\n    10: if wbVWDAsQuestChildren then\n      Result := Result + ' Quest Children of '\n    else\n      Result := Result + ' Cell Visible Distant Children of ';\n  else\n    Result := Result + ' Unknown type: ' + IntToStr(grStruct.grsGroupType);\n    Exit;\n  end;\n\n//  if wbDisplayLoadOrderFormID then\n//    Result := Result + wbFormID.ToString(GetChildrenOf.FixedFormID, Self)\n//  else\n    Result := Result + wbFormID.ToString(grStruct.grsLabel, Self);\nend;\n\nfunction TwbGroupRecord.GetCountedRecordCount: Cardinal;\nbegin\n  Result := Succ(inherited GetCountedRecordCount);\nend;\n\nfunction TwbGroupRecord.GetShortName: string;\nvar\n  RecordDef : PwbRecordDef;\nbegin\n  case grStruct.grsGroupType of\n    0: begin\n      Result := PwbSignature(@grStruct.grsLabel)^;\n      if wbFindRecordDef(AnsiString(Result), RecordDef) then\n        Result := RecordDef.GetName;\n    end;\n    1: Result := 'World Children';\n    2: Result := 'Block ' + IntToStr(grStruct.grsLabel);\n    3: Result := 'Sub-Block ' + IntToStr(grStruct.grsLabel);\n    4: Result := 'Block ' + IntToStr(LongRecSmall(grStruct.grsLabel).Hi) + ', ' + IntToStr(LongRecSmall(grStruct.grsLabel).Lo);\n    5: Result := 'Sub-Block ' + IntToStr(LongRecSmall(grStruct.grsLabel).Hi) + ', ' + IntToStr(LongRecSmall(grStruct.grsLabel).Lo);\n    6: Result := 'Children of ' + IntToHex(grStruct.grsLabel, 8);\n    7: Result := 'Children of ' + IntToHex(grStruct.grsLabel, 8);\n    8: Result := 'Persistent';\n    9: Result := 'Temporary';\n    10: if wbVWDAsQuestChildren then\n      Result := 'Children of ' + IntToHex(grStruct.grsLabel, 8)\n    else\n      Result := 'Visible when Distant';\n  else\n    Result := Result + ' Unknown type: ' + IntToStr(grStruct.grsGroupType);\n  end;\nend;\n\nfunction TwbGroupRecord.GetSortKeyInternal(aExtended: Boolean): string;\nbegin\n  Result := IntToHex64(GetGroupType, 2);\n\n  case grStruct.grsGroupType of\n    0: Result := Result + PwbSignature(@grStruct.grsLabel)^;\n    4: Result := Result +\n      IntToHex64(LongRecSmall(grStruct.grsLabel).Hi + Low(SmallInt), 5) +\n      IntToHex64(LongRecSmall(grStruct.grsLabel).Lo + Low(SmallInt), 5);\n    5: Result := Result +\n      IntToHex64(LongRecSmall(grStruct.grsLabel).Hi + Low(SmallInt), 5) +\n      IntToHex64(LongRecSmall(grStruct.grsLabel).Lo + Low(SmallInt), 5);\n  else\n    Result := Result + IntToHex64(grStruct.grsLabel, 8);\n  end;\nend;\n\nfunction TwbGroupRecord.grStruct: PwbGroupRecordStruct;\nbegin\n  Result := PwbGroupRecordStruct(dcBasePtr);\nend;\n\nprocedure TwbGroupRecord.InformPrevMainRecord(const aPrevMainRecord: IwbMainRecord);\nbegin\n  inherited;\n  if (grStruct.grsGroupType in [1, 6, 7]) and Assigned(aPrevMainRecord) and (aPrevMainRecord.FormID = grStruct.grsLabel) then\n    (aPrevMainRecord as IwbMainRecordInternal).SetChildGroup(Self);\nend;\n\nprocedure TwbGroupRecord.InitDataPtr;\nvar\n  Dummy: Integer;\nbegin\n  if Assigned(dcEndPtr) then begin\n    dcDataBasePtr := Pointer( Cardinal( dcBasePtr ) + wbSizeOfMainRecordStruct );\n    dcDataEndPtr := Pointer( Cardinal( dcBasePtr ) + grStruct.grsGroupSize );\n    dcEndPtr := dcDataEndPtr;\n    if not recSkipped then\n      if grStruct.grsGroupType = 0 then\n        recSkipped := GroupToSkip.Find(PwbSignature(@grStruct.grsLabel)^, Dummy);\n  end;\nend;\n\nfunction TwbGroupRecord.IsElementRemoveable(const aElement: IwbElement): Boolean;\nbegin\n  Result := IsElementEditable(aElement);\nend;\n\nfunction TwbGroupRecord.LinksToParent: Boolean;\nbegin\n  Result := GetGroupType in [4, 5, 8..10];\nend;\n\nprocedure TwbGroupRecord.MakeHeaderWriteable;\nvar\n  p       : PwbGroupRecordStruct;\n  SelfPtr : IwbContainerElementRef;\nbegin\n  SelfPtr := Self as IwbContainerElementRef;\n\n  DoInit;\n\n  SetModified(True);\n  InvalidateParentStorage;\n\n  if Assigned(dcEndPtr) then begin\n    New(p);\n    p^ := grStruct^;\n    dcBasePtr := p;\n    dcEndPtr := nil;\n  end;\nend;\n\nprocedure TwbGroupRecord.MasterCountUpdated(aOld, aNew: Byte);\nvar\n  FileID: Integer;\nbegin\n  if grStruct.grsGroupType in [1, 6..10] then begin\n    if grStruct.grsLabel <> 0 then begin\n      FileID := grStruct.grsLabel shr 24;\n      if FileID >= aOld then begin\n        FileID := aNew;\n        MakeHeaderWriteable;\n        grStruct.grsLabel := (grStruct.grsLabel and $00FFFFFF) or (Cardinal(FileID) shl 24);\n      end;\n    end;\n  end;\n\n  inherited;\nend;\n\nprocedure TwbGroupRecord.MasterIndicesUpdated(const aOld, aNew: TBytes);\nvar\n  OldFormID: Cardinal;\n  NewFormID: Cardinal;\nbegin\n  inherited;\n\n  if grStruct.grsGroupType in [1, 6..10] then begin\n    if grStruct.grsLabel <> 0 then begin\n      OldFormID := grStruct.grsLabel;\n      NewFormID := FixupFormID(OldFormID, aOld, aNew);\n      if OldFormID <> NewFormID then begin\n        MakeHeaderWriteable;\n        grStruct.grsLabel := NewFormID;\n      end;\n    end;\n  end;\nend;\n\nprocedure TwbGroupRecord.NotifyChangedInternal(aContainer: Pointer);\nbegin\n  if gsSorting in grStates then\n    Exit;\n  inherited;\n  // Let's try to sort only when the group membership change and not when one of its member change.\n  if Assigned(aContainer) and (IwbContainerInternal(aContainer).ElementID = GetElementID) then\n    Exclude(grStates, gsSorted);\nend;\n\nprocedure TwbGroupRecord.PrepareSave;\nbegin\n  if esModified in eStates then\n    Sort;\n  inherited;\n  if Length(cntElements) = 0 then\n    Remove\n  else if esModified in eStates then begin\n    Exclude(grStates, gsSorted);\n    Sort;\n  end;\nend;\n\nfunction TwbGroupRecord.Reached: Boolean;\nvar\n  Rec     : IwbMainRecord;\n  SelfRef : IwbContainerElementRef;\nbegin\n  if esReachable in eStates then\n    Exit(False);\n\n  SelfRef := Self as IwbContainerElementRef;\n  DoInit;\n\n  if GetGroupType in [0, 2, 3] then begin\n    Result := False;\n    Exit;\n  end;\n  Result := inherited Reached;\n  if Result and (GetGroupType in [1, 6..10]) then begin\n    Rec := (GetFile as IwbFileInternal).RecordByFormID[GetGroupLabel, False];\n    if Assigned(Rec) then\n      (Rec as IwbElementInternal).Reached;\n  end;\nend;\n\nprocedure TwbGroupRecord.Remove;\nvar\n  i          : Integer;\n  SelfRef    : IwbContainerElementRef;\n  MainRecord : IwbMainRecord;\nbegin\n  SelfRef := Self as IwbContainerElementRef;\n  for i := High(cntElements) downto Low(cntElements) do\n    cntElements[i].Remove;\n  MainRecord := GetChildrenOf;\n  if Assigned(MainRecord) and MainRecord._File.Equals(GetFile) then\n    (MainRecord as IwbMainRecordInternal).RemoveChildGroup(Self);\n  inherited Remove;\nend;\n\nprocedure TwbGroupRecord.ScanData;\nvar\n  CurrentPtr     : Pointer;\n  Rec            : IwbRecord;\n  MainRecord     : IwbMainRecord;\n  PrevMainRecord : IwbMainRecord;\nbegin\n  case grStruct.grsGroupType of\n    0: begin\n      SetSortOrder(wbGetGroupOrder(PwbSignature(@grStruct.grsLabel)^));\n      SetMemoryOrder(wbGetGroupOrder(PwbSignature(@grStruct.grsLabel)^));\n    end;\n  end;\n\n  if recSkipped then\n    Exit;\n\n  CurrentPtr := GetDataBasePtr;\n  PrevMainRecord := nil;\n  while Cardinal(CurrentPtr) < Cardinal(dcDataEndPtr) do begin\n    Rec := TwbRecord.CreateForPtr(CurrentPtr, dcDataEndPtr, Self, PrevMainRecord);\n    if Supports(Rec, IwbMainRecord, MainRecord) then\n      PrevMainRecord := MainRecord;\n    Rec := nil;\n    MainRecord := nil;\n  end;\n  PrevMainRecord := nil;\nend;\n\nprocedure TwbGroupRecord.SetGroupLabel(aLabel: Cardinal);\nvar\n  OldLabel    : Cardinal;\n  i           : Integer;\n  GroupRecord : IwbGroupRecord;\n\n  SelfPtr     : IwbContainerElementRef;\n  ContainedIn : IwbContainedIn;\nbegin\n  SelfPtr := Self as IwbContainerElementRef;\n\n  OldLabel := grStruct.grsLabel;\n  if aLabel = OldLabel then\n    Exit;\n\n  case grStruct.grsGroupType of\n    1: ;//Result := Result + ' World Children of ';\n    6: ;//Result := Result + ' Cell Children of ';\n    7: ;//Result := Result + ' Topic Children of ';\n    8: ;//Result := Result + ' Cell Persistent Children of ';\n    9: ;//Result := Result + ' Cell Temporary Children of ';\n    10: ;//Result := Result + ' Cell Visible Distant Children of ';\n  else\n    raise Exception.Create('Can not set Label of ' + GetName);\n  end;\n\n  MakeHeaderWriteable;\n  grStruct.grsLabel := aLabel;\n\n//  if grStruct.grsGroupType <> 6 then\n//    Exit;\n\n  for i := 0 to Pred(GetElementCount) do\n    if Supports(GetElement(i), IwbGroupRecord, GroupRecord) then begin\n      if GroupRecord.GroupType in [8..10] then\n        if GroupRecord.GroupLabel = OldLabel then\n          GroupRecord.GroupLabel := aLabel;\n    end else if Supports(GetElement(i), IwbContainedIn, ContainedIn) then\n      ContainedIn.ContainerChanged;\nend;\n\nprocedure TwbGroupRecord.SetModified(aValue: Boolean);\nbegin\n  inherited;\n  InvalidateStorage;\nend;\n\nfunction FindSortElement(const aElement: IwbElement): IwbElement;\nvar\n  GroupRecord                 : IwbGroupRecord;\nbegin\n  if Supports(aElement, IwbGroupRecord, GroupRecord) then begin\n    Result := GroupRecord.ChildrenOf;\n    if Assigned(Result) then\n      Exit;\n  end;\n  Result := aElement;\nend;\n\nfunction CompareGroupContents(Item1, Item2: Pointer): Integer;\nvar\n  Element1                    : IwbElement;\n  Element2                    : IwbElement;\n  SortElement1                : IwbElement;\n  SortElement2                : IwbElement;\n  GroupRecord1                : IwbGroupRecord;\n  GroupRecord2                : IwbGroupRecord;\n  MainRecord1                 : IwbMainRecord;\n  MainRecord2                 : IwbMainRecord;\nbegin\n  Element1 := IwbElement(Item1);\n  Element2 := IwbElement(Item2);\n\n  if Element1 = Element2 then begin\n    Result := 0;\n    Exit;\n  end;\n\n  if Assigned(Element1) <> Assigned(Element2) then begin\n    if Assigned(Element1) then\n      Result := -1\n    else\n      Result := 1;\n    Exit;\n  end\n  else if not Assigned(Element1) then begin\n    Result := 0;\n    Exit;\n  end;\n\n  {\"ChildrenOf\" groups always sort like their owner}\n  SortElement1 := FindSortElement(Element1);\n  SortElement2 := FindSortElement(Element2);\n\n  if Assigned(SortElement1) <> Assigned(SortElement2) then begin\n    if Assigned(SortElement1) then\n      Result := -1\n    else\n      Result := 1;\n    Exit;\n  end\n  else if not Assigned(SortElement1) then begin\n    Result := 0;\n    Exit;\n  end;\n\n  Result := CmpI32(Ord(SortElement1.ElementType), Ord(SortElement2.ElementType));\n  if Result = 0 then\n    case SortElement1.ElementType of\n      etFile: begin\n          Assert(False);\n          Exit;\n        end;\n      etGroupRecord: begin\n          Assert(SortElement2.ElementType = etGroupRecord);\n          GroupRecord1 := SortElement1 as IwbGroupRecord;\n          GroupRecord2 := SortElement2 as IwbGroupRecord;\n          Assert(GroupRecord1.GroupType = GroupRecord2.GroupType);\n          case GroupRecord1.GroupType of\n            0: Result := CompareText(\n                TwbSignature(GroupRecord1.GroupLabel),\n                TwbSignature(GroupRecord2.GroupLabel));\n            2, 3: Result := CmpI32(\n                Integer(GroupRecord1.GroupLabel),\n                Integer(GroupRecord2.GroupLabel));\n            4, 5: begin\n                Result := CmpI32(\n                  LongRecSmall(GroupRecord1.GroupLabel).Hi,\n                  LongRecSmall(GroupRecord2.GroupLabel).Hi);\n                if Result = 0 then\n                  Result := CmpI32(\n                    LongRecSmall(GroupRecord1.GroupLabel).Lo,\n                    LongRecSmall(GroupRecord2.GroupLabel).Lo);\n              end;\n          else\n            Assert(False);\n          end;\n        end;\n      etMainRecord: begin\n          Assert(SortElement2.ElementType = etMainRecord);\n          MainRecord1 := SortElement1 as IwbMainRecord;\n          MainRecord2 := SortElement2 as IwbMainRecord;\n          Result := 0;\n          if Result = 0 then begin\n            Result := CmpI32(MainRecord1.SortPriority, MainRecord2.SortPriority);\n            if Result = 0 then begin\n              if wbDisplayLoadOrderFormID then\n                Result := CmpW32(MainRecord1.LoadOrderFormID, MainRecord2.LoadOrderFormID)\n              else\n                Result := CmpW32(MainRecord1.FixedFormID, MainRecord2.FixedFormID);\n              if Result = 0 then\n                Result := CmpW32(MainRecord1.ElementID, MainRecord2.ElementID);\n            end;\n          end;\n        end\n    else\n      Assert(False);\n    end;\n\n  if Result = 0 then\n    if Element1 <> SortElement1 then begin\n      if Element2 <> SortElement2 then begin\n        {both are groups of the same element }\n        GroupRecord1 := Element1 as IwbGroupRecord;\n        GroupRecord2 := Element2 as IwbGroupRecord;\n        Result := CmpI32(GroupRecord1.GroupType, GroupRecord2.GroupType);\n        if Result = 0 then\n          Result := CmpW32(GroupRecord1.GroupLabel, GroupRecord2.GroupLabel);\n      end\n      else begin\n        {element1 is a group of element2}\n        Result := 1;\n      end;\n    end\n    else begin\n      if Element2 <> SortElement2 then begin\n        {element2 is a group of element1}\n        Result := -1;\n      end\n      else begin\n        {really seems to be the same}\n      end;\n    end;\nend;\n\nvar\n  ElementRefs      : array of IwbContainerElementRef;\n  ElementRefsCount : Integer;\n\nprocedure TwbGroupRecord.Sort;\n\n  procedure DoInserRecord(const InsertRecord: IwbMainRecordEntry);\n  var\n    TargetRecord: IwbMainRecordEntry;\n  begin\n    SetLength(ElementRefs, Succ(Length(ElementRefs)));\n    if not Supports(InsertRecord, IwbContainerElementRef, ElementRefs[High(ElementRefs)]) then\n      Assert(False);\n\n    if Supports(InsertRecord.ElementLinksTo['PNAM'], IwbMainRecordEntry, TargetRecord) then begin\n\n      SetLength(ElementRefs, Succ(Length(ElementRefs)));\n      if not Supports(TargetRecord, IwbContainerElementRef, ElementRefs[High(ElementRefs)]) then\n        Assert(False);\n\n      if not TargetRecord.IsInList then\n        DoInserRecord(TargetRecord);\n\n      InsertRecord.InsertEntryAfter(TargetRecord);\n\n    end else if InsertRecord.ElementExists['PNAM'] then\n      InsertRecord.InsertEntryHead\n    else\n      InsertRecord.InsertEntryTail;\n  end;\n\nvar\n  ChildrenOf  : IwbMainRecord;\n  MainRecords : TDynMainRecords;\n  Groups      : TDynGroupRecords;\n  Group       : IwbContainerElementRef;\n  g           : IwbGroupRecord;\n  i, j, k     : Integer;\n  InsertRecord: IwbMainRecordEntry;\n  TargetRecord: IwbMainRecordEntry;\n  PrevRecord  : IwbMainRecordEntry;\n  InfoQuest   : Int64;\n  InfoQuest2  : Int64;\n  Inserted    : Boolean;\n  NewElements : TDynElementInternals;\n\nbegin\n  if grStates * [gsSorted, gsSorting] <> [] then\n    Exit;\n\n  if eUpdateCount > 0 then begin\n    Include(grStates, gsSortPostponed);\n    Exit;\n  end;\n\n  Include(grStates, gsSorting);\n  try\n    ChildrenOf := GetChildrenOf;\n    // there is no PNAM in Fallout 4, looks like INFOs are no longer linked lists\n    if (wbGameMode <> gmFO4) and Assigned(ChildrenOf) and (ChildrenOf.Signature = 'DIAL') then begin\n      {>>> Sorting DIAL group doesn't always work, and Skyrim.esm has a plenty of unsorted DIALs <<<}\n      {>>> Also disabled for FNV, https://code.google.com/p/skyrim-plugin-decoding-project/issues/detail?id=59 <<<}\n      if not wbSortGroupRecord then\n        Exit;\n\n      if not wbDisplayLoadOrderFormID then\n        Exit;\n\n      Inc(ElementRefsCount);\n      try\n        MainRecords := ChildrenOf.MasterRecordsFromMasterFilesAndSelf;\n        SetLength(Groups, Length(MainRecords));\n        i := 0;\n        for j := Low(MainRecords) to High(MainRecords) do begin\n          Groups[i] := MainRecords[j].ChildGroup;\n          if Assigned(Groups[i]) and (Groups[i].ElementCount > 0) then\n            Inc(i);\n        end;\n        SetLength(Groups, i);\n\n        for i := Low(Groups) to High(Groups) do\n          if not Equals(Groups[i]) then\n            (Groups[i] as IwbGroupRecordInternal).Sort;\n\n        mreHeader.BeginUse;\n        try\n          for i := Low(Groups) to High(Groups) do\n            if Supports(Groups[i], IwbContainerElementRef, Group) then\n              for j := 0 to Pred(Group.ElementCount) do\n                if Supports(Group.Elements[j], IwbMainRecordEntry, InsertRecord) then\n                   DoInserRecord(InsertRecord);\n          TargetRecord := IwbMainRecordEntry(mreHeader.mrehTail);\n          while Assigned(TargetRecord) do begin\n            PrevRecord := TargetRecord.PrevEntry;\n            if not Equals(TargetRecord.Container) then\n              TargetRecord.RemoveEntry\n            else if not TargetRecord.IsDeleted then if wbBeginInternalEdit then try\n              if not TargetRecord.ElementExists['PNAM'] then begin\n                {>>> No QSTI in Skyrim, using DIAL\\QNAM <<<}\n                if wbGameMode in [ gmTES5, gmSSE ] then begin\n                  Supports(TargetRecord.Container, IwbGroupRecord, g);\n                  InfoQuest := g.ChildrenOf.ElementNativeValues['QNAM'];\n                end else\n                  InfoQuest := TargetRecord.ElementNativeValues['QSTI'];\n                InsertRecord := PrevRecord;\n                Inserted := False;\n                while Assigned(InsertRecord) do begin\n                  if wbGameMode in [ gmTES5, gmSSE ] then begin\n                    Supports(InsertRecord.Container, IwbGroupRecord, g);\n                    InfoQuest2 := g.ChildrenOf.ElementNativeValues['QNAM'];\n                  end else\n                    InfoQuest2 := InsertRecord.ElementNativeValues['QSTI'];\n                  if (not InsertRecord.IsDeleted) and (InfoQuest = InfoQuest2) then begin\n                    try\n                      Inserted := True;\n                      TargetRecord.Add('PNAM').NativeValue := InsertRecord.LoadOrderFormID;\n                    except\n                      TargetRecord.RemoveElement('PNAM');\n                    end;\n                    Break;\n                  end;\n                  InsertRecord := InsertRecord.PrevEntry;\n                end;\n                if not Inserted then\n                  TargetRecord.Add('PNAM');\n              end;\n            finally\n              wbEndInternalEdit;\n            end;\n            TargetRecord := PrevRecord;\n          end;\n\n          Assert(mreHeader.mrehCount = Length(cntElements));\n\n          SetLength(NewElements, Length(cntElements));\n          k := High(NewElements);\n          TargetRecord := IwbMainRecordEntry(mreHeader.mrehTail);\n          while Assigned(TargetRecord) do begin\n            Assert(k >= Low(NewElements));\n            if not Supports(TargetRecord, IwbElementInternal, NewElements[k]) then\n              Assert(False);\n            TargetRecord := TargetRecord.PrevEntry;\n            Dec(k);\n          end;\n          Assert(k = -1);\n\n          cntElements := NewElements;\n          Include(grStates, gsSorted);\n        finally\n          mreHeader.EndUse;\n        end;\n      finally\n        Dec(ElementRefsCount);\n        if ElementRefsCount = 0 then\n          ElementRefs := nil;\n      end;\n      Exit;\n    end;\n\n    if Length(cntElements) > 1 then\n      wbMergeSort(@cntElements[0], Length(cntElements), CompareGroupContents);\n    Include(grStates, gsSorted);\n  finally\n    Exclude(grStates, gsSorting);\n  end;\nend;\n\nprocedure TwbGroupRecord.UpdatedEnded;\nbegin\n  if gsSortPostponed in grStates then begin\n    Exclude(grStates, gsSortPostponed);\n    Sort;\n  end;\n  inherited;\nend;\n\nprocedure TwbGroupRecord.WriteToStreamInternal(aStream: TStream; aResetModified: Boolean);\nvar\n  CurrentPosition   : Int64;\n  NewPosition       : Int64;\n  DataSize          : Cardinal;\n  grs               : TwbGroupRecordStruct;\nbegin\n  CurrentPosition := aStream.Position;\n  grs := grStruct^;\n  aStream.WriteBuffer(grs, wbSizeOfMainRecordStruct );\n  if wbForceNewHeader then\n    aStream.WriteBuffer(wbNewHeaderAddon, SizeOf(wbNewHeaderAddon) );\n  inherited;\n  if (esModified in eStates) or wbTestWrite then begin\n\n    NewPosition := aStream.Position;\n    DataSize := (NewPosition - CurrentPosition);\n    aStream.Position := CurrentPosition + 4;\n    aStream.WriteBuffer(DataSize, SizeOf(DataSize));\n    aStream.Position := NewPosition;\n\n  end else\n    if wbForceNewHeader then\n      Assert(CurrentPosition + grStruct.grsGroupSize + SizeOf(wbNewHeaderAddon) = aStream.Position)\n    else\n      Assert(CurrentPosition + grStruct.grsGroupSize = aStream.Position);\n\n  Exclude(eStates, esUnsaved);\n  if aResetModified then begin\n    Exclude(eStates, esModified);\n    Exclude(eStates, esInternalModified);\n  end;\nend;\n\n{ TwbElement }\n\nfunction TwbElement.AddIfMissing(const aElement: IwbElement; aAsNew, aDeepCopy : Boolean; const aPrefixRemove, aPrefix, aSuffix: string): IwbElement;\n{$IFDEF USE_CODESITE}\nvar\n  Log: Boolean;\n  Group : IwbGroupRecord;\n{$ENDIF}\nbegin\n  if (wbCurrentTick>0) and (wbCurrentTick+500<GetTickCount) then begin\n    wbProgressCallback('');\n    wbCurrentTick := GetTickCount;\n  end;\n\n  {$IFDEF USE_CODESITE}\n  Log := (laAddIfMissing in wbLoggingAreas) and wbCodeSiteLoggingEnabled;\n  if Log then begin\n    CodeSite.EnterMethod(Self, 'AddIfMissing');\n    CodeSite.Send('Self.Name', Self.GetName);\n    CodeSite.Send('Self.Path', Self.GetPath);\n    CodeSite.Send('Self.Value', Self.GetValue);\n    if Assigned(aElement) then begin\n      CodeSite.Send('aElement.Name', aElement.Name);\n      CodeSite.Send('aElement.Path', aElement.Path);\n      CodeSite.Send('aElement.Value', aElement.Value);\n      if Supports(aElement, IwbGrouprecord, Group) then\n        CodeSite.Send('aGroup.Type', Group.GroupType);\n    end else\n        CodeSite.Send('aElement', 'nil');\n  end;\n  {$ENDIF}\n  BeginUpdate;\n  try\n    Result := AddIfMissingInternal(aElement, aAsNew, aDeepCopy, aPrefixRemove, aPrefix, aSuffix);\n  finally\n    EndUpdate;\n  {$IFDEF USE_CODESITE}\n    if Log then begin\n      CodeSite.Send('Self.Value', Self.GetValue);\n      if Assigned(Result) then begin\n        CodeSite.Send('Result.Name', Result.Name);\n        CodeSite.Send('Result.Path', Result.Path);\n        CodeSite.Send('Result.Value', Result.Value);\n      end else\n        CodeSite.Send('Result', 'nil');\n      CodeSite.ExitMethod(Self, 'AddIfMissing');\n    end;\n  {$ENDIF}\n  end;\nend;\n\nfunction TwbElement.AddIfMissingInternal(const aElement: IwbElement; aAsNew, aDeepCopy : Boolean; const aPrefixRemove, aPrefix, aSuffix: string): IwbElement;\nbegin\n  raise Exception.Create(ClassName + '.AddIfMissingInternal is not implemented');\nend;\n\nprocedure TwbElement.AddReferencedFromID(aFormID: Cardinal);\nbegin\n  if Assigned(eContainer) then\n    IwbElement(eContainer).AddReferencedFromID(aFormID);\nend;\n\nprocedure TwbElement.AfterConstruction;\nlabel\n  Skip;\nbegin\n  inherited;\n  {$IFDEF WIN64}\n  if LockedDec(eExternalRefs) = 0 then\n  {$ENDIF WIN64}\n  {$IFDEF WIN32}\n  asm\n         mov  eax, -1\n         mov  ecx, [Self]\n    lock xadd dword ptr [ecx + eExternalRefs], eax\n         cmp  eax, 1\n         jne  Skip\n  end;\n  {$ENDIF WIN32}\n  eContainerRef := nil;\nSkip:\n  Include(eStates, esConstructionComplete);\nend;\n\nfunction TwbElement.Assign(aIndex: Integer; const aElement: IwbElement; aOnlySK: Boolean): IwbElement;\n{$IFDEF USE_CODESITE}\nvar\n  Log: Boolean;\n{$ENDIF}\nbegin\n  if (wbCurrentTick>0) and (wbCurrentTick+500<GetTickCount) then begin\n    wbProgressCallback('');\n    wbCurrentTick := GetTickCount;\n  end;\n\n  {$IFDEF USE_CODESITE}\n  Log := (laElementAssign in wbLoggingAreas) and wbCodeSiteLoggingEnabled;\n  if Log then begin\n    CodeSite.EnterMethod(Self, 'Assign');\n    CodeSite.Send('Self.Name', Self.GetName);\n    CodeSite.Send('Self.Path', Self.GetPath);\n    CodeSite.Send('Self.DataSize', Self.GetDataSize);\n    CodeSite.Send('Self.Value', Self.GetValue);\n    CodeSite.Send('aIndex', aIndex);\n    if Assigned(aElement) then begin\n      CodeSite.Send('aElement.Name', aElement.Name);\n      CodeSite.Send('aElement.Path', aElement.Path);\n      CodeSite.Send('aElement.DataSize', aElement.GetDataSize);\n      CodeSite.Send('aElement.Value', aElement.Value);\n    end else\n      CodeSite.Send('aElement', 'nil');\n    CodeSite.Send('aOnlySK', aOnlySK);\n  end;\n  {$ENDIF}\n  BeginUpdate;\n  try\n    Result := AssignInternal(aIndex, aElement, aOnlySK);\n  finally\n    EndUpdate;\n  {$IFDEF USE_CODESITE}\n    if Log then begin\n      CodeSite.Send('Self.Value', Self.GetValue);\n      CodeSite.Send('Self.DataSize', Self.GetDataSize);\n      if Assigned(Result) then begin\n        CodeSite.Send('Result.Name', Result.Name);\n        CodeSite.Send('Result.Path', Result.Path);\n        CodeSite.Send('Result.DataSize', Result.GetDataSize);\n        CodeSite.Send('Result.Value', Result.Value);\n      end else\n        CodeSite.Send('Result', 'nil');\n      CodeSite.ExitMethod(Self, 'Assign');\n    end;\n  {$ENDIF}\n  end;\nend;\n\nfunction TwbElement.AssignInternal(aIndex: Integer; const aElement: IwbElement; aOnlySK: Boolean): IwbElement;\nbegin\n  if not wbEditAllowed then\n    raise Exception.Create(GetName + ' can not be assigned.');\n\n  Result := GetDef.Assign(Self, aIndex, aElement, aOnlySK);\nend;\n\nprocedure TwbElement.BeforeDestruction;\nbegin\n  Assert(eExternalRefs = 0);\n  if (FRefCount and $7FFFFFFF) <> 0 then\n    Assert(FRefCount = 0);\n  Include(eStates, esDestroying);\n  inherited BeforeDestruction;\n  {$IFDEF WIN64}\n  LockedInc(eExternalRefs);\n  LockedInc(FRefCount);\n  {$ENDIF WIN64}\n  {$IFDEF WIN32}\n  asm\n         mov eax, [Self]\n    lock inc dword ptr [eax + eExternalRefs]\n    lock inc dword ptr [eax + FRefCount]\n  end;\n  {$ENDIF WIN64}\nend;\n\nfunction TwbElement.BeginDecide: Boolean;\nbegin\n  Result := not (esDeciding in eStates);\n  if Result then\n    Include(eStates, esDeciding);\nend;\n\nfunction TwbElement.BeginUpdate: Integer;\nbegin\n  Result := Succ(eUpdateCount);\n  eUpdateCount := Result;\nend;\n\nprocedure TwbElement.BuildRef;\nbegin\n  {nothing}\nend;\n\nfunction TwbElement.CanAssign(aIndex: Integer; const aElement: IwbElement; aCheckDontShow: Boolean): Boolean;\n{$IFDEF USE_CODESITE}\nvar\n  Log: Boolean;\n{$ENDIF}\nbegin\n  {$IFDEF USE_CODESITE}\n  Log := (laElementCanAssign in wbLoggingAreas) and wbCodeSiteLoggingEnabled;\n  if Log then begin\n    CodeSite.EnterMethod(Self, 'CanAssign');\n    CodeSite.Send('Self.Name', Self.GetName);\n    CodeSite.Send('Self.Path', Self.GetPath);\n    CodeSite.Send('Self.Value', Self.GetValue);\n    CodeSite.Send('aIndex', aIndex);\n    if Assigned(aElement) then begin\n      CodeSite.Send('aElement.Name', aElement.Name);\n      CodeSite.Send('aElement.Path', aElement.Path);\n      CodeSite.Send('aElement.Value', aElement.Value);\n    end else\n      CodeSite.Send('aElement', 'nil');\n    CodeSite.Send('aCheckDontShow', aCheckDontShow);\n  end;\n  Result := False;\n  try\n  {$ENDIF}\n    Result := CanAssignInternal(aIndex, aElement, aCheckDontShow);\n  {$IFDEF USE_CODESITE}\n  finally\n    if Log then begin\n      CodeSite.Send('Result', Result);\n      CodeSite.ExitMethod(Self, 'CanAssign');\n    end;\n  end;\n  {$ENDIF}\nend;\n\nfunction TwbElement.CanAssignInternal(aIndex: Integer; const aElement: IwbElement; aCheckDontShow: Boolean): Boolean;\nvar\n  TargetValueDef: IwbValueDef;\n  SourceValueDef: IwbValueDef;\nbegin\n  Result := wbIsInternalEdit;\n  if Result then\n    Exit;\n\n  if not wbEditAllowed then\n    Exit;\n\n  if not GetIsEditable then\n    Exit;\n\n  if not Assigned(aElement) then\n    Exit;\n\n  TargetValueDef := GetValueDef;\n  if TargetValueDef = nil then\n    Exit;\n\n  SourceValueDef := aElement.ValueDef;\n  if SourceValueDef = nil then\n    Exit;\n\n  Result := TargetValueDef.CanAssign(Self, aIndex, SourceValueDef);\n\n  if Result and aCheckDontShow and GetDontShow then\n    Result := False;\nend;\n\nfunction TwbElement.CanChangeMember: Boolean;\nbegin\n  Result := Assigned(eContainer) and\n    IwbContainerInternal(eContainer).CanChangeElementMember(Self);\nend;\n\nfunction TwbElement.CanContainFormIDs: Boolean;\nbegin\n  Result := True;\nend;\n\nfunction TwbElement.CanMoveDown: Boolean;\nbegin\n  Result := Assigned(eContainer) and\n    IwbContainerInternal(eContainer).CanMoveElementDown(Self);\nend;\n\nfunction TwbElement.CanMoveUp: Boolean;\nbegin\n  Result := Assigned(eContainer) and\n    IwbContainerInternal(eContainer).CanMoveElementUp(Self);\nend;\n\nfunction TwbElement.CompareExchangeFormID(aOldFormID, aNewFormID: Cardinal): Boolean;\nbegin\n  Result := False;\nend;\n\nfunction CompareLoadOrderSL(List: TStringList; Index1, Index2: Integer): Integer;\nbegin\n  if Index1 = Index2 then begin\n    Result := 0;\n    Exit;\n  end;\n\n  Result := CmpI32(\n    IwbFile(Pointer(List.Objects[Index1])).LoadOrder,\n    IwbFile(Pointer(List.Objects[Index2])).LoadOrder);\nend;\n\nprocedure AddRequiredMasters(aMasters: TStrings; const aTargetFile: IwbFile);\nvar\n  sl                          : TStringList;\n  i, j                        : Integer;\nbegin\n  sl := TStringList.Create;\n  try\n    sl.Sorted := True;\n    sl.Duplicates := dupIgnore;\n    sl.AddStrings(aMasters);\n\n    for i := 0 to Pred(aTargetFile.MasterCount) do\n      if sl.Find(aTargetFile.Masters[i].FileName, j) then\n        sl.Delete(j);\n    if sl.Find(aTargetFile.FileName, j) then\n      sl.Delete(j);\n\n    if sl.Count > 0 then begin\n\n      for i := 0 to Pred(sl.Count) do\n        if IwbFile(Pointer(sl.Objects[i])).LoadOrder >= aTargetFile.LoadOrder then\n          raise Exception.Create('The required master \"' + sl[i] + '\" can not be added to \"' + aTargetFile.FileName + '\" as it has a higher load order');\n\n      sl.Sorted := False;\n      sl.CustomSort(CompareLoadOrderSL);\n\n      aTargetFile.AddMasters(sl);\n    end;\n  finally\n    sl.Free;\n  end;\nend;\n\nfunction TwbElement.CopyInto(const aFile: IwbFile; aAsNew, aDeepCopy: Boolean; const aPrefixRemove, aPrefix, aSuffix: string): IwbElement;\nvar\n  sl          : TStringList;\n  MainRecord  : IwbMainRecord;\n  GroupRecord : IwbGroupRecord;\nbegin\n  sl := TStringList.Create;\n  try\n    sl.Sorted := True;\n    sl.Duplicates := dupIgnore;\n    ReportRequiredMasters(sl, aAsNew);\n    AddRequiredMasters(sl, aFile);\n\n    if aDeepCopy and Supports(Self, IwbMainRecord, MainRecord) and Assigned(MainRecord.ChildGroup) then begin\n      Result := wbCopyElementToFile(MainRecord.ChildGroup, aFile, aAsNew, True, aPrefixRemove, aPrefix, aSuffix);\n      if Supports(Result, IwbGroupRecord, GroupRecord) then\n        Result := GroupRecord.ChildrenOf\n      else\n        Result := nil;\n    end else\n      Result := wbCopyElementToFile(Self, aFile, aAsNew, True, aPrefixRemove, aPrefix, aSuffix);\n  finally\n    sl.Free;\n  end;\nend;\n\nconstructor TwbElement.Create(const aContainer: IwbContainer);\nbegin\n  eSortOrder := High(Integer);\n  eMemoryOrder := Low(Integer);\n  inherited Create;\n  if Assigned(aContainer) then\n    aContainer.AddElement(Self);\nend;\n\nprocedure TwbElement.DoAfterSet(const aOldValue, aNewValue: Variant);\nvar\n  NamedDef: IwbNamedDef;\nbegin\n  NamedDef := GetValueDef;\n  if Assigned(NamedDef) then\n    NamedDef.AfterSet(Self, aOldValue, aNewValue);\n  if Supports(GetDef, IwbNamedDef, NamedDef) then\n    NamedDef.AfterSet(Self, aOldValue, aNewValue);\nend;\n\nprocedure TwbElement.DoReset(aForce: Boolean);\nbegin\n  {nothing}\nend;\n\nprocedure TwbElement.EndDecide;\nbegin\n  Exclude(eStates, esDeciding);\nend;\n\nfunction TwbElement.EndUpdate: Integer;\n\nbegin\n  Result := Pred(eUpdateCount);\n  eUpdateCount := Result;\n  if Result = 0 then\n    UpdatedEnded;\nend;\n\nfunction TwbElement.Equals(const aElement: IwbElement): Boolean;\nbegin\n  Result := Assigned(aElement) and (aElement.ElementID = GetElementID);\nend;\n\nprocedure TwbElement.FindUsedMasters(aMasters: PwbUsedMasters);\nbegin\n  {can be overriden}\nend;\n\nprocedure TwbElement.FreeInstance;\nbegin\n  if (FRefCount and $7FFFFFFF) <> 1 then\n    Assert(FRefCount = 1);\n  Assert(eExternalRefs = 1);\n  inherited;\nend;\n\nfunction TwbElement.GetBaseName: string;\nbegin\n  Result := GetName;\nend;\n\nfunction TwbElement.GetCheck: string;\nbegin\n  Result := '';\nend;\n\nfunction TwbElement.GetConflictPriority: TwbConflictPriority;\nvar\n  Def        : IwbDef;\n  MainRecord : IwbMainRecord;\nbegin\n  Result := cpNormal;\n\n  Def := GetValueDef;\n\n  if not Assigned(Def) then\n    Def := GetDef;\n\n  if Assigned(Def) then\n    Result := Def.ConflictPriority[Self];\n\n  if wbTranslationMode then begin\n    if Result <> cpTranslate then\n      Result := cpIgnore\n    else\n      Result := cpNormal;\n  end else begin\n    if Result = cpTranslate then\n      Result := cpNormal;\n  end;\n\n  if Result = cpFormID then begin\n    Result := cpCritical;\n    MainRecord := GetContainingMainRecord;\n    if Assigned(MainRecord) and (MainRecord.Signature = 'GMST') then\n      Result := cpBenign;\n  end;\nend;\n\nfunction TwbElement.GetConflictPriorityCanChange: Boolean;\nvar\n  Def        : IwbDef;\nbegin\n  Result := False;\n\n  Def := GetValueDef;\n\n  if not Assigned(Def) then\n    Def := GetDef;\n\n  if Assigned(Def) then\n    Result := Def.ConflictPriorityCanChange;\nend;\n\nfunction TwbElement.GetContainer: IwbContainer;\nbegin\n  Result := IwbContainer(eContainer);\nend;\n\nfunction TwbElement.GetContainingMainRecord: IwbMainRecord;\nbegin\n  if Assigned(eContainer) then\n    Result := IwbContainer(eContainer).ContainingMainRecord\n  else\n    Result := nil;\nend;\n\nfunction TwbElement.GetDataSize: Integer;\nbegin\n  Result := 0;\nend;\n\nfunction TwbElement.GetDef: IwbNamedDef;\nbegin\n  Result := nil;\nend;\n\nfunction TwbElement.GetDisplayName: string;\nbegin\n  Result := GetName;\nend;\n\nfunction TwbElement.GetDontShow: Boolean;\nvar\n  Def: IwbDef;\nbegin\n  Result := False;\n  Def := GetValueDef;\n  if Assigned(Def) then\n    Result := Def.DontShow[Self];\n  if not Result then begin\n    Def := GetDef;\n    if Assigned(Def) then\n      Result := Def.DontShow[Self];\n  end;\nend;\n\nfunction TwbElement.GetEditInfo: string;\nbegin\n  Result := '';\nend;\n\nfunction TwbElement.GetEditType: TwbEditType;\nbegin\n  Result := etDefault;\nend;\n\nfunction TwbElement.GetEditValue: string;\nbegin\n  Result := '';\nend;\n\nfunction TwbElement.GetElementID: Cardinal;\nbegin\n  Result := Cardinal(Self);\nend;\n\nfunction TwbElement.GetElementStates: TwbElementStates;\nbegin\n  Result := eStates;\nend;\n\nfunction TwbElement.GetElementType: TwbElementType;\nbegin\n  Assert(False, 'This method is abstract');\n  Result := TwbElementType(-1);\nend;\n\nfunction TwbElement.GetFile: IwbFile;\nbegin\n  if Assigned(eContainer) then\n    Result := IwbContainerInternal(eContainer)._File\n  else\n    Result := nil;\nend;\n\nfunction TwbElement.GetFullPath: string;\nbegin\n  if Assigned(eContainer) then\n    Result := IwbElement(eContainer).FullPath\n  else\n    Result := '';\n  Result := Result + ' \\ ';\n  if Assigned(eContainer) then\n    Result := Result + '['+IntToStr(IwbContainer(eContainer).IndexOf(Self))+'] ';\n  Result := Result + GetName;\nend;\n\nfunction TwbElement.GetPathName: string;\nbegin\n  if Assigned(eContainer) then\n    Result := IwbElement(eContainer).PathName\n  else\n    Result := '';\n  Result := Result + '\\';\n  if Assigned(eContainer) then\n    Result := Result + '['+IntToStr(IwbContainer(eContainer).IndexOf(Self))+'] ';\n  Result := Result + GetShortName;\nend;\n\nfunction TwbElement.GetInjectionSourceFiles: TDynFiles;\nvar\n  Element : IwbElement;\n  MainRecord : IwbMainRecord;\nbegin\n  Result := nil;\n  Element := GetLinksTo;\n  if Supports(Element, IwbMainRecord, MainRecord) and not GetFile.Equals(MainRecord._File) and MainRecord.MasterOrSelf.IsInjected then begin\n    SetLength(Result, 1);\n    Result[0] := MainRecord.MasterOrSelf._File;\n  end;\nend;\n\nfunction TwbElement.GetIsEditable: Boolean;\nbegin\n  Result := wbIsInternalEdit;\nend;\n\nfunction TwbElement.GetIsHidden: Boolean;\nbegin\n  if [esHidden, esParentHiddenChecked] * eStates = [] then begin\n    Include(eStates, esParentHiddenChecked);\n    if Assigned(eContainer) and IwbContainer(eContainer).IsHidden then\n      Include(eStates, esParentHidden)\n    else\n      Exclude(eStates, esParentHidden);\n  end;\n  Result := eStates * [esHidden, esParentHidden] <> [];\nend;\n\nfunction TwbElement.GetIsInjected: Boolean;\nbegin\n  Result := False;\nend;\n\nfunction TwbElement.GetIsNotReachable: Boolean;\nbegin\n  Result := esNotReachable in eStates;\nend;\n\nfunction TwbElement.GetIsRemoveable: Boolean;\nbegin\n  Result := not Assigned(eContainer) or IwbContainer(eContainer).IsElementRemoveable(Self);\nend;\n\nfunction TwbElement.GetLinksTo: IwbElement;\nbegin\n  Result := nil;\nend;\n\nfunction TwbElement.GetMemoryOrder: Integer;\nbegin\n  Result := eMemoryOrder;\nend;\n\nfunction TwbElement.GetModified: Boolean;\nbegin\n  if wbShowInternalEdit then\n    Result := [esModified] * eStates = [esModified]\n  else\n    Result := [esModified, esInternalModified] * eStates = [esModified];\nend;\n\nfunction TwbElement.GetName: string;\nvar\n  Def: IwbDef;\nbegin\n  if wbReportMode then begin\n    Def := GetValueDef;\n    if Assigned(Def) then\n      Def.Used;\n    Def := GetDef;\n    if Assigned(Def) then\n      Def.Used;\n  end;\n  Result := '';\nend;\n\nfunction TwbElement.GetNativeValue: Variant;\nbegin\n  Result := Null;\nend;\n\nfunction TwbElement.GetNoReach: Boolean;\nvar\n  Def : IwbDef;\nbegin\n  Def := GetValueDef;\n  if not Assigned(Def) then\n    Def := GetDef;\n  if Assigned(Def) then\n    Result := Def.NoReach\n  else\n    Result := False;\nend;\n\nfunction TwbElement.GetPath: string;\nbegin\n  if Assigned(eContainer) then\n    Result := IwbElement(eContainer).Path\n  else\n    Result := '';\n  Result := Result + ' \\ ' + GetName;\nend;\n\nfunction TwbElement.GetCountedRecordCount: Cardinal;\nbegin\n  Result := 0;\nend;\n\nfunction TwbElement.GetReferenceFile: IwbFile;\nvar\n  Container: IwbContainer;\nbegin\n  Container := GetContainer;\n  if Assigned(Container) then\n    Result := Container.ReferenceFile\n  else\n    Result := nil;\nend;\n\nfunction TwbElement.GetReferencesInjected: Boolean;\nvar\n  Element     : IwbElement;\n  _File       : IwbFile;\n  ElementFile : IwbFile;\n  i           : Integer;\nbegin\n  Element := GetLinksTo;\n  Result := Assigned(Element) and Element.IsInjected;\n\n  if Result then begin\n    _File := GetFile;\n    ElementFile := Element._File;\n    Result := not _File.Equals(ElementFile);\n    if Result then begin\n      for i := 0 to Pred(_File.MasterCount) do\n        if _File.Masters[i].Equals(ElementFile) then begin\n          Result := False;\n          Exit;\n        end;\n    end;\n  end;\nend;\n\nfunction TwbElement.GetResolvedValueDef: IwbValueDef;\nbegin\n  Result := GetValueDef;\nend;\n\nfunction TwbElement.GetShortName: string;\nvar\n  Def: IwbDef;\nbegin\n  if wbReportMode then begin\n    Def := GetDef;\n    if Assigned(Def) then\n      Def.Used;\n  end;\n  Result := GetName;\nend;\n\nfunction TwbElement.GetSkipped: Boolean;\nbegin\n  Result := False;\nend;\n\nfunction TwbElement.GetSortKey(aExtended: Boolean): string;\nbegin\n  if aExtended then begin\n    if not (esExtendedSortKeyValid in eStates) then begin\n      if not (esSorting in eStates) then begin\n        Include(eStates, esSorting);\n        eExtendedSortKey := GetSortKeyInternal(aExtended);\n        Exclude(eStates, esSorting);\n      end\n      else\n        eExtendedSortKey := GetSortKeyInternal(aExtended);\n      Include(eStates, esExtendedSortKeyValid);\n    end;\n    Result := eExtendedSortKey;\n  end else begin\n    if not (esSortKeyValid in eStates) then begin\n      if not (esSorting in eStates) then begin\n        Include(eStates, esSorting);\n        eSortKey := GetSortKeyInternal(aExtended);\n        Exclude(eStates, esSorting);\n      end else\n        eSortKey := GetSortKeyInternal(aExtended);\n      Include(eStates, esSortKeyValid);\n    end;\n    Result := eSortKey;\n  end;\nend;\n\nfunction TwbElement.GetSortKeyInternal(aExtended: Boolean): string;\nbegin\n  Result := '';\nend;\n\nfunction TwbElement.GetSortOrder: Integer;\nbegin\n  Result := eSortOrder;\nend;\n\nfunction TwbElement.GetSortPriority: Integer;\nbegin\n  Result := 0;\nend;\n\nfunction TwbElement.GetTreeBranch: Boolean;\nvar\n  NamedDef: IwbNamedDef;\nbegin\n  if Supports(GetDef, IwbNamedDef, NamedDef) then\n    Result := NamedDef.TreeBranch\n  else\n    Result := False;\nend;\n\nfunction TwbElement.GetTreeHead: Boolean;\nvar\n  NamedDef: IwbNamedDef;\nbegin\n  if Supports(GetDef, IwbNamedDef, NamedDef) then\n    Result := NamedDef.TreeHead\n  else\n    Result := False;\nend;\n\nfunction TwbElement.GetValue: string;\nvar\n  Def: IwbDef;\nbegin\n  if wbReportMode then begin\n    Def := GetValueDef;\n    if Assigned(Def) then\n      Def.Used;\n    Def := GetDef;\n    if Assigned(Def) then\n      Def.Used;\n  end;\n  Result := '';\nend;\n\nfunction TwbElement.GetValueDef: IwbValueDef;\nbegin\n  Result := nil;\nend;\n\nfunction TwbElement.HasErrors: Boolean;\nbegin\n  Result := Trim(GetCheck) <> '';\nend;\n\nprocedure TwbElement.Hide;\nbegin\n  if not (esHidden in eStates) then begin\n    Include(eStates, esHidden);\n    ResetConflict;\n  end;\nend;\n\nprocedure TwbElement.InformStorage(var aBasePtr: Pointer; aEndPtr: Pointer);\nbegin\n  {can be overriden}\nend;\n\n{$D-}\nfunction TwbElement.InternalAddRef: Integer;\nbegin\n  Result := inherited _AddRef;\nend;\n\nfunction TwbElement.InternalRelease: Integer;\nbegin\n  Result := inherited _Release;\nend;\n{$D+}\n\nprocedure TwbElement.InvalidateParentStorage;\nbegin\n  if Assigned(eContainer) then\n    (IwbContainer(eContainer) as IwbElementInternal).InvalidateStorage;\nend;\n\nprocedure TwbElement.InvalidateStorage;\nbegin\n  InvalidateParentStorage;\nend;\n\nfunction TwbElement.IsTagged: Boolean;\nbegin\n  Result := esTagged in eStates;\nend;\n\nfunction TwbElement.LinksToParent: Boolean;\nbegin\n  Result := False;\nend;\n\nprocedure TwbElement.MarkModifiedRecursive;\nbegin\n  if not Assigned(eContainer) or IwbContainer(eContainer).IsElementEditable(Self) then begin\n    SetModified(True);\n    InvalidateParentStorage;\n  end;\nend;\n\nprocedure TwbElement.MasterCountUpdated(aOld, aNew: Byte);\nbegin\n  {can be overriden}\nend;\n\nprocedure TwbElement.MasterIndicesUpdated(const aOld, aNew: TBytes);\nbegin\n  Assert( Length(aOld) = Length(aNew) );\nend;\n\nprocedure TwbElement.MergeStorage(var aBasePtr: Pointer; aEndPtr: Pointer);\n{$IFDEF USE_CODESITE}\nvar\n  Log: Boolean;\n{$ENDIF}\nbegin\n  {$IFDEF USE_CODESITE}\n  Log := (laElementMergeStorage in wbLoggingAreas) and wbCodeSiteLoggingEnabled;\n  if Log then begin\n    CodeSite.EnterMethod(Self, 'MergeStorage');\n    CodeSite.Send('Self.Name', Self.GetName);\n    CodeSite.Send('Self.Path', Self.GetPath);\n    CodeSite.Send('Self.Value', Self.GetValue);\n    if StartsWith(Self.GetValue, '<Error') then\n      asm nop end;\n    CodeSite.Send('Self.SortOrder', Self.eSortOrder);\n    CodeSite.Send('Self.MemoryOrder', Self.eMemoryOrder);\n    CodeSite.Send('aBasePtr', Cardinal(aBasePtr), True);\n    CodeSite.Send('aEndPtr', Cardinal(aEndPtr), True);\n  end;\n  try\n  {$ENDIF}\n    MergeStorageInternal(aBasePtr, aEndPtr);\n  {$IFDEF USE_CODESITE}\n  finally\n    if Log then begin\n      CodeSite.Send('Self.Value', Self.GetValue);\n      CodeSite.Send('aBasePtr', Cardinal(aBasePtr), True);\n      CodeSite.Send('aEndPtr', Cardinal(aEndPtr), True);\n      CodeSite.ExitMethod(Self, 'MergeStorage');\n    end;\n  end;\n  {$ENDIF}\nend;\n\nprocedure TwbElement.MergeStorageInternal(var aBasePtr: Pointer; aEndPtr: Pointer);\nbegin\n  {can be overriden}\nend;\n\nprocedure TwbElement.MoveDown;\nbegin\n  if not CanMoveDown then\n    Exit;\n  IwbContainerInternal(eContainer).MoveElementDown(Self);\nend;\n\nprocedure TwbElement.MoveUp;\nbegin\n  if not CanMoveUp then\n    Exit;\n  IwbContainerInternal(eContainer).MoveElementUp(Self);\nend;\n\nclass function TwbElement.NewInstance: TObject;\nbegin\n  Result := inherited NewInstance;\n  TwbElement(Result).eExternalRefs := 1;\nend;\n\nprocedure TwbElement.NextMember;\nbegin\n  if not CanChangeMember then\n    Exit;\n  IwbContainerInternal(eContainer).NextElementMember(Self);\nend;\n\nprocedure TwbElement.NotifyChanged(aContainer: Pointer);\nbegin\n  if eUpdateCount > 0 then\n    Include(eStates, esChangeNotified)\n  else\n    NotifyChangedInternal(aContainer);\nend;\n\nprocedure TwbElement.NotifyChangedInternal(aContainer: Pointer);\nbegin\n  if Assigned(eContainer) then\n    IwbContainerInternal(eContainer).ElementChanged(Self, aContainer);\nend;\n\nprocedure TwbElement.PrepareSave;\nbegin\n  {can be overriden}\nend;\n\nprocedure TwbElement.PreviousMember;\nbegin\n  if not CanChangeMember then\n    Exit;\n  IwbContainerInternal(eContainer).PreviousElementMember(Self);\nend;\n\nfunction TwbElement.Reached: Boolean;\nvar\n  MainRecord : IwbMainRecord;\nbegin\n  Result := not (esReachable in eStates);\n\n  if GetDontShow then\n    Exit;\n\n  Exclude(eStates, esNotReachable);\n  Include(eStates, esReachable);\n  If Result then begin\n    if not GetNoReach then\n      if Supports(GetLinksTo, IwbMainRecord, MainRecord) then begin\n        MainRecord := MainRecord.WinningOverride;\n        (MainRecord as IwbElementInternal).Reached;\n      end;\n    if LinksToParent and Assigned(eContainer) then\n      (IwbContainer(eContainer) as IwbElementInternal).Reached;\n  end;\nend;\n\nprocedure TwbElement.Remove;\nbegin\n  if Assigned(eContainer) then begin\n    SetModified(True);\n    InvalidateParentStorage;\n    IwbContainer(eContainer).RemoveElement(Self as IwbElement);\n  end;\nend;\n\nfunction TwbElement.RemoveInjected(aCanRemove: Boolean): Boolean;\nbegin\n  Result := GetReferencesInjected;\n  if Result and GetIsRemoveable then begin\n    Result := False;\n    Remove;\n  end;\nend;\n\nprocedure TwbElement.ReportRequiredMasters(aStrings: TStrings; aAsNew: Boolean; Recursive: Boolean = True; Initial: Boolean = false);\nvar\n  Element       : IwbElement;\n  ReferenceFile : IwbFile;\nbegin\n  Element := GetLinksTo;\n  if Assigned(Element) then begin\n    ReferenceFile := Element.ReferenceFile;\n    if Assigned(ReferenceFile) then begin\n      aStrings.AddObject(ReferenceFile.FileName, Pointer(ReferenceFile));\n    end;\n  end;\nend;\n\nprocedure TwbElement.RequestStorageChange(var aBasePtr, aEndPtr: Pointer; aNewSize: Cardinal);\nbegin\n  raise Exception.Create(GetName + ' is not editable');\nend;\n\nprocedure TwbElement.ResetConflict;\nbegin\n  Exclude(eStates, esParentHiddenChecked);\n  Exclude(eStates, esParentHidden);\nend;\n\nprocedure TwbElement.ResetReachable;\nbegin\n  Include(eStates, esNotReachable);\n  Exclude(eStates, esReachable);\nend;\n\nprocedure TwbElement.ResetTags;\nbegin\n  Exclude(eStates, esTagged);\nend;\n\nprocedure TwbElement.SetContainer(const aContainer: IwbContainer);\nbegin\n  if Assigned(aContainer) then begin\n    Assert(not Assigned(eContainer));\n    if esNotReachable in aContainer.ElementStates then\n      Include(eStates, esNotReachable);\n  end else\n    Assert(Assigned(eContainer));\n\n  if Assigned(aContainer) then\n    eContainer := Pointer(aContainer as IwbContainerInternal)\n  else\n    eContainer := nil;\n\n  if not Assigned(eContainer) then\n    eContainerRef := nil\n  else\n    if eExternalRefs > 0 then\n      eContainerRef := aContainer as IwbContainerElementRef;\nend;\n\nprocedure TwbElement.SetDataSize(aSize: Integer);\nbegin\n  Assert(False, 'Can''t SetDataSize on ' + ClassName);\nend;\n\nprocedure TwbElement.SetEditValue(const aValue: string);\nbegin\n  raise Exception.Create(GetName + ' can not be edited.');\nend;\n\nprocedure TwbElement.SetElementState(aState: TwbElementState; Clear: Boolean);\nbegin\n  if Clear then\n    Exclude(eStates, aState)\n  else\n    Include(eStates, aState);\nend;\n\nprocedure TwbElement.SetInternalModified(aValue: Boolean);\nbegin\n  wbBeginInternalEdit(True);\n  try\n    SetModified(aValue);\n  finally\n    wbEndInternalEdit;\n  end;\nend;\n\nprocedure TwbElement.SetMemoryOrder(aIndex: Integer);\nbegin\n  eMemoryOrder := aIndex;\nend;\n\nprocedure TwbElement.SetModified(aValue: Boolean);\nbegin\n  if aValue then begin\n\n    if wbIsInternalEdit then begin\n      if not (esModified in eStates) then\n        Include(eStates, esInternalModified);\n    end else begin\n      Exclude(eStates, esInternalModified);\n      Include(eStates, esUnsaved);\n    end;\n\n    Include(eStates, esModified);\n    Exclude(eStates, esSortKeyValid);\n    Exclude(eStates, esExtendedSortKeyValid);\n    eSortKey := '';\n    eExtendedSortKey := '';\n\n//    if wbIsInternalEdit and (Self is TwbMainRecord) then\n//      Exit;\n\n    if eUpdateCount > 0 then\n      Include(eStates, esModifiedUpdated)\n    else\n      if Assigned(eContainer) then\n        (IwbContainer(eContainer) as IwbElementInternal).Modified := True;\n  end;\nend;\n\nprocedure TwbElement.SetNativeValue(const aValue: Variant);\nbegin\n  raise Exception.Create(GetName + ' can not be edited.');\nend;\n\nprocedure TwbElement.SetSortOrder(aIndex: Integer);\nbegin\n  eSortOrder := aIndex;\nend;\n\nprocedure TwbElement.SetToDefault;\n{$IFDEF USE_CODESITE}\nvar\n  Log: Boolean;\n{$ENDIF}\nbegin\n  {$IFDEF USE_CODESITE}\n  Log := (laElementSetToDefault in wbLoggingAreas) and wbCodeSiteLoggingEnabled;\n  if Log then begin\n    CodeSite.EnterMethod(Self, 'SetToDefault');\n    CodeSite.Send('Self.Name', Self.GetName);\n    CodeSite.Send('Self.Path', Self.GetPath);\n    CodeSite.Send('Self.DataSize', Self.GetDataSize);\n    CodeSite.Send('Self.Value', Self.GetValue);\n  end;\n  {$ENDIF}\n  BeginUpdate;\n  try\n    SetToDefaultInternal;\n  finally\n    EndUpdate;\n  {$IFDEF USE_CODESITE}\n    if Log then begin\n      CodeSite.Send('Self.Value', Self.GetValue);\n      CodeSite.Send('Self.DataSize', Self.GetDataSize);\n      CodeSite.ExitMethod(Self, 'SetToDefault');\n    end;\n  {$ENDIF}\n  end;\nend;\n\nprocedure TwbElement.SetToDefaultInternal;\nbegin\n  { can be overriden }\nend;\n\nprocedure TwbElement.Show;\nbegin\n  if esHidden in eStates then begin\n    Exclude(eStates, esHidden);\n    ResetConflict;\n  end;\nend;\n\nprocedure TwbElement.Tag;\nbegin\n  Include(eStates, esTagged);\nend;\n\nprocedure TwbElement.UpdatedEnded;\nbegin\n  if esChangeNotified in eStates then begin\n    Exclude(eStates, esChangeNotified);\n    NotifyChanged(eContainer);\n  end;\n  if esModifiedUpdated in eStates then begin\n    Exclude(eStates, esModifiedUpdated);\n    if Assigned(eContainer) and (esModified in eStates) then\n      (IwbContainer(eContainer) as IwbElementInternal).Modified := True;\n  end;\nend;\n\nprocedure TwbElement.WriteToStream(aStream: TStream; aResetModified: Boolean);\n{$IFDEF USE_CODESITE}\nvar\n  Log: Boolean;\n{$ENDIF}\nbegin\n  {$IFDEF USE_CODESITE}\n  Log := (laElementWriteToStream in wbLoggingAreas) and wbCodeSiteLoggingEnabled;\n  if Log then begin\n    CodeSite.EnterMethod(Self, 'WriteToStream');\n    CodeSite.Send('Self.Name', Self.GetName);\n    CodeSite.Send('Self.Path', Self.GetPath);\n    CodeSite.Send('Self.Value', Self.GetValue);\n    CodeSite.Send('aStream.Position', aStream.Position);\n    CodeSite.Send('aResetModified', aResetModified);\n  end;\n  try\n  {$ENDIF}\n    WriteToStreamInternal(aStream, aResetModified);\n  {$IFDEF USE_CODESITE}\n  finally\n    if Log then begin\n      CodeSite.Send('aStream.Position', aStream.Position);\n      CodeSite.Send('Self.Value', Self.GetValue);\n      CodeSite.ExitMethod(Self, 'WriteToStream');\n    end;\n  end;\n  {$ENDIF}\nend;\n\nprocedure TwbElement.WriteToStreamInternal(aStream: TStream; aResetModified: Boolean);\nbegin\n  Exclude(eStates, esUnsaved);\n  if aResetModified then begin\n    Exclude(eStates, esModified);\n    Exclude(eStates, esInternalModified);\n  end;\nend;\n\n{$D-}\nfunction TwbElement._AddRef: Integer;\nlabel\n  Skip;\nbegin\n  Assert(not (esDestroying in eStates));\n  {$IFDEF WIN64}\n  if LockedInc(eExternalRefs) = 1 then\n  {$ENDIF WIN64}\n  {$IFDEF WIN32}\n  asm\n         mov  eax, 1\n         mov  ecx, [Self]\n    lock xadd dword ptr [ecx + eExternalRefs], eax\n         cmp  eax, 0\n         jne  Skip\n  end;\n  {$ENDIF WIN32}\n  eContainerRef := IInterface(eContainer) as IwbContainerElementRef;\nSkip:\n\n  Result := inherited _AddRef;\nend;\n\nfunction TwbElement._Release: Integer;\nlabel\n  Skip;\nbegin\n  {$IFDEF WIN64}\n  if LockedDec(eExternalRefs) = 0 then\n  {$ENDIF WIN64}\n  {$IFDEF WIN32}\n  asm\n         mov  eax, -1\n         mov  ecx, [Self]\n    lock xadd dword ptr [ecx + eExternalRefs], eax\n         cmp  eax, 1\n         jne  Skip\n  end;\n  {$ENDIF WIN32}\n  eContainerRef := nil;\nSkip:\n  Result := inherited _Release;\nend;\n{$D+}\n\n{ TwbSubRecordArray }\n\nfunction TwbSubRecordArray.AddIfMissingInternal(const aElement: IwbElement; aAsNew, aDeepCopy: Boolean; const aPrefixRemove, aPrefix, aSuffix: string): IwbElement;\nvar\n  SelfRef   : IwbContainerElementRef;\n  i         : Integer;\nbegin\n  if not wbEditAllowed then\n    raise Exception.Create(GetName + ' can not be assigned.');\n\n  SelfRef := Self as IwbContainerElementRef;\n  DoInit;\n\n  Assert(Assigned(aElement.Def));\n  Assert(arcDef.Element.Equals(aElement.Def));\n\n  if arcSorted and not aAsNew then begin\n    Assert(not arcSortInvalid);\n    if FindBySortKey(aElement.SortKey[False], False,i) then begin\n      Result := cntElements[i];\n      if aDeepCopy then\n        Result.Assign(Low(Integer), aElement, False);\n      Exit;\n    end;\n  end;\n\n  if (csAsCreatedEmpty in cntStates) then begin\n    SetModified(True);\n    Assert(Length(cntElements)=1);\n    Result := cntElements[0];\n    Exclude(cntStates, csAsCreatedEmpty);\n  end else\n    case arcDef.Element.DefType of\n      dtSubRecord:\n        Result := TwbSubRecord.Create(Self, arcDef.Element as IwbSubRecordDef);\n      dtSubRecordArray:\n        Result := TwbSubRecordArray.Create(Self, nil, Low(Integer), arcDef.Element as IwbSubRecordArrayDef);\n      dtSubRecordStruct:\n        Result := TwbSubRecordStruct.Create(Self, nil, Low(Integer), arcDef.Element as IwbSubRecordStructDef);\n    else\n      Assert(False);\n    end;\n\n  try\n    Result.Assign(Low(Integer), aElement, not aDeepCopy);\n  except\n    Result.Container.RemoveElement(Result);\n    Result := nil;\n    raise;\n  end;\nend;\n\nfunction TwbSubRecordArray.AssignInternal(aIndex: Integer; const aElement: IwbElement; aOnlySK: Boolean): IwbElement;\nvar\n  Element       : IwbElement;\n  Container     : IwbContainer;\n  i             : Integer;\n  SelfRef       : IwbContainerElementRef;\n  ElementDef    : IwbRecordMemberDef;\n  DataContainer : IwbDataContainer;\nbegin\n  Result := nil;\n\n  if not wbEditAllowed then\n    raise Exception.Create(GetName + ' can not be assigned.');\n\n  SelfRef := Self as IwbContainerElementRef;\n  DoInit;\n\n  if (aIndex = Low(Integer)) and arcDef.CanAssign(Self, aIndex, aElement.Def) then begin\n\n    if aOnlySK then\n      Exit;\n\n    Container := aElement as IwbContainer;\n\n    SetModified(True);\n    InvalidateStorage;\n    ReleaseElements;\n\n    for i := 0 to Pred(Container.ElementCount) do\n      Assign(i, Container.Elements[i], aOnlySK);\n\n  end else if (aIndex >= 0) and (not Assigned(aElement) or arcDef.Element.CanAssign(Self, Low(Integer), aElement.Def))  or\n    ((aIndex = Low(Integer)) and arcDef.Element.CanAssign(Self, aIndex, aElement.Def)) then begin\n\n    Element := nil;\n\n    if (csAsCreatedEmpty in cntStates) and Assigned(aElement) then begin\n      SetModified(True);\n      Assert(Length(cntElements)=1);\n      Element := cntElements[0];\n      Exclude(cntStates, csAsCreatedEmpty);\n    end else begin\n\n      ElementDef := arcDef.Element;\n      if ElementDef.DefType = dtSubRecordUnion then begin\n        if Assigned(aElement) then begin\n          Supports(aElement, IwbDataContainer, DataContainer);\n          ElementDef := (ElementDef as IwbRecordDef).GetMemberFor((aElement as IwbHasSignature).Signature, DataContainer)\n        end else\n          ElementDef := (ElementDef as IwbRecordDef).Members[0];\n        Assert(Assigned(ElementDef));\n      end;\n\n      case ElementDef.DefType of\n        dtSubRecord:\n          Element := TwbSubRecord.Create(Self, ElementDef as IwbSubRecordDef);\n        dtSubRecordArray:\n          Element := TwbSubRecordArray.Create(Self, nil, Low(Integer), ElementDef as IwbSubRecordArrayDef);\n        dtSubRecordStruct:\n          Element := TwbSubRecordStruct.Create(Self, nil, Low(Integer), ElementDef as IwbSubRecordStructDef);\n      else\n        Assert(False);\n      end;\n    end;\n\n    if Assigned(Element) and Assigned(aElement) then try\n      Element.Assign(Low(Integer), aElement, aOnlySK);\n      if csAsCreatedEmpty in cntStates then\n        Exclude(cntStates, csAsCreatedEmpty);\n    except\n      Element.Container.RemoveElement(Element);\n      raise;\n    end;\n\n    Result := Element;\n  end;\n\n  arcSorted := False;\n  if wbSortSubRecords and arcDef.Sorted[IwbContainer(eContainer)] then begin\n    if Length(cntElements) > 1 then\n      wbMergeSort(@cntElements[0], Length(cntElements), CompareSortKeys);\n    arcSorted := True;\n  end;\nend;\n\nfunction TwbSubRecordArray.CanAssignInternal(aIndex: Integer; const aElement: IwbElement; aCheckDontShow: Boolean): Boolean;\nbegin\n  Result := False;\n  if not wbEditAllowed then\n    Exit;\n\n  if Assigned(eContainer) then\n    if not IwbContainer(eContainer).IsElementEditable(Self) then\n      Exit;\n\n  if aCheckDontShow and GetDontShow then\n    Exit;\n\n  if not Assigned(aElement) then begin\n    Result := aIndex >= 0;\n    Exit;\n  end;\n\n  Result := arcDef.CanAssign(Self, aIndex, aElement.Def);\n  if not Result then begin\n    Result := arcDef.Element.CanAssign(Self, Low(Integer), aElement.Def);\n    if Result then\n      if aCheckDontShow and arcDef.Element.DontShow[aElement] then\n        Result := False;\n  end;\nend;\n\nfunction TwbSubRecordArray.CanContainFormIDs: Boolean;\nbegin\n  Result := arcDef.CanContainFormIDs;\nend;\n\nfunction TwbSubRecordArray.CanMoveElement: Boolean;\nbegin\n  Result := not arcSorted;\nend;\n\nfunction TwbSubRecordArray.CanElementReset: Boolean;\nbegin\n//  Result := inherited CanElementReset;\n  Result := cntElementRefs < 1;\nend;\n\nconstructor TwbSubRecordArray.Create(const aOwner     : IwbContainer;\n                                     const aContainer : IwbContainer;\n                                           aPos       : Integer;\n                                     const aDef       : IwbSubRecordArrayDef);\nbegin\n  arcDef := aDef;\n  eContainer := Pointer(aOwner);\n  try\n    if aPos <> Low(Integer) then begin\n      DoProcess(aContainer, aPos)\n    end else begin\n      Assign(High(Integer), nil, False);\n      Include(cntStates, csAsCreatedEmpty);\n    end;\n  finally\n    eContainer := nil;\n  end;\n  inherited Create(aOwner);\n  if aPos = Low(Integer) then begin\n    SetModified(True);\n    InvalidateStorage;\n  end;\nend;\n\nprocedure TwbSubRecordArray.DoInit;\nbegin\n  inherited;\n  if arcSorted and arcSortInvalid then begin\n    if Length(cntElements) > 1 then\n      wbMergeSort(@cntElements[0], Length(cntElements), CompareSortKeys);\n    arcSortInvalid := False;\n  end;\nend;\n\nprocedure TwbSubRecordArray.DoProcess(const aContainer : IwbContainer;\n                                                  aPos : Integer);\nvar\n  SubRecord  : IwbSubRecordInternal;\n  ElementDef : IwbRecordMemberDef;\n  Element    : IwbElement;\n  SelfRef    : IwbContainerElementRef;\nbegin\n  SelfRef := Self;\n\n  while (aPos < aContainer.ElementCount) and\n    (aContainer[aPos].ElementType = etSubRecord) do begin\n\n    SubRecord := aContainer[aPos] as IwbSubRecordInternal;\n    ElementDef := arcDef.Element;\n    if ElementDef.DefType = dtSubRecordUnion then begin\n      ElementDef := (ElementDef as IwbRecordDef).GetMemberFor(SubRecord.Signature, SubRecord);\n      if not Assigned(ElementDef) then\n        Break;\n    end;\n\n    if not ElementDef.CanHandle(SubRecord.Signature, SubRecord) then\n      Break;\n\n    case ElementDef.DefType of\n      dtSubRecord: begin\n        aContainer.RemoveElement(aPos);\n        SubRecord.SetDef(ElementDef as IwbSubRecordDef);\n        AddElement(SubRecord);\n      end;\n      dtSubRecordArray: begin\n        Element := TwbSubRecordArray.Create(Self, aContainer, aPos, ElementDef as IwbSubRecordArrayDef);\n      end;\n      dtSubRecordStruct:\n        Element := TwbSubRecordStruct.Create(Self, aContainer, aPos, ElementDef as IwbSubRecordStructDef);\n    else\n      raise Exception.CreateFmt('Unexpected def type for SubRecord %s in array', [String(SubRecord.Signature)]);\n    end;\n\n  end;\n\n  arcSorted := False;\n  if wbSortSubRecords and arcDef.Sorted[aContainer] then begin\n    arcSorted := True;\n    arcSortInvalid := True;\n  end;\nend;\n\nprocedure TwbSubRecordArray.ElementChanged(const aElement: IwbElement; aContainer: Pointer);\nbegin\n  inherited;\n  if arcSorted then\n    arcSortInvalid := True;\nend;\n\nfunction TwbSubRecordArray.GetDef: IwbNamedDef;\nbegin\n  Result := arcDef;\nend;\n\nfunction TwbSubRecordArray.GetElementType: TwbElementType;\nbegin\n  Result := etSubRecordArray;\nend;\n\nfunction TwbSubRecordArray.GetName: string;\nbegin\n  Result := arcDef.GetName;\nend;\n\nfunction TwbSubRecordArray.GetSignature: TwbSignature;\nvar\n  i       : Integer;\n  lRecord : IwbRecord;\n\n  SelfRef : IwbContainerElementRef;\nbegin\n  SelfRef := Self as IwbContainerElementRef;\n\n  if GetElementCount > 0 then begin\n    Assert(not arcSortInvalid);\n    Result := NONE;\n    for i := 0 to Pred(GetElementCount) do\n      if Supports(GetElement(i), IwbRecord, lRecord) then begin\n        Result := lRecord.Signature;\n        Exit;\n      end;\n  end;\nend;\n\nfunction TwbSubRecordArray.GetSorted: Boolean;\nbegin\n  Result := arcSorted;\nend;\n\nfunction TwbSubRecordArray.IsElementRemoveable(const aElement: IwbElement): Boolean;\nbegin\n  Result := IsElementEditable(aElement) and (Length(cntElements) > 1);\nend;\n\nprocedure TwbSubRecordArray.SetModified(aValue: Boolean);\nbegin\n  inherited;\n  if aValue and arcSorted then\n    arcSortInvalid := True;\nend;\n\n{ TwbSubRecordStruct }\n\nfunction TwbSubRecordStruct.Add(const aName: string; aSilent: Boolean): IwbElement;\nvar\n  Signature : TwbSignature;\n  Index     : Integer;\nbegin\n  Result := nil;\n\n  if not IsElementEditable(nil) then\n    raise Exception.Create('\"' + GetName + '\" is not editable');\n\n  Result := nil;\n\n  if Length(aName) < 4 then\n    Exit;\n\n  Signature := StrToSignature(aName);\n\n  Result := GetElementBySignature(Signature);\n  if Assigned(Result) then\n    Exit;\n\n  Index := srcDef.GetMemberIndexFor(Signature, nil);\n  if Index >= 0 then\n    Assign(Index, nil, False);\n\n  Result := GetElementBySignature(Signature);\n  Assert(Assigned(Result));\nend;\n\nfunction TwbSubRecordStruct.AddIfMissingInternal(const aElement: IwbElement; aAsNew, aDeepCopy: Boolean; const aPrefixRemove, aPrefix, aSuffix: string): IwbElement;\nvar\n  SelfRef   : IwbContainerElementRef;\nbegin\n  if not wbEditAllowed then\n    raise Exception.Create(GetName + ' can not be assigned.');\n\n  SelfRef := Self as IwbContainerElementRef;\n  DoInit;\n\n  Assert(aElement.SortOrder >= 0);\n  Assert(aElement.SortOrder < srcDef.MemberCount);\n  Assert(Assigned(aElement.Def));\n  Assert(aElement.Def.Equals(srcDef.Members[aElement.SortOrder]));\n\n  Result := GetElementBySortOrder(aElement.SortOrder + GetAdditionalElementCount);\n  if not Assigned(Result) then begin\n    Assign(aElement.SortOrder, aElement, not aDeepCopy);\n    Result := GetElementBySortOrder(aElement.SortOrder + GetAdditionalElementCount);\n    Assert(Assigned(Result));\n\n    if wbSortSubRecords and (Length(cntElements) > 1) then\n      wbMergeSort(@cntElements[0], Length(cntElements), CompareSubRecords);\n  end else\n    Result.Assign(Low(Integer), aElement, not aDeepCopy);\nend;\n\nprocedure TwbSubRecordStruct.AddRequiredElements;\nvar\n  CurrentDefPos : Integer;\n  CurrentDef    : IwbRecordMemberDef;\n  Element       : IwbElementInternal;\nbegin\n  for CurrentDefPos := 0 to Pred(srcDef.MemberCount) do begin\n    CurrentDef := srcDef.Members[CurrentDefPos];\n    if ((CurrentDefPos = 0) and not srcDef.AllowUnordered) or CurrentDef.Required then begin\n\n      if CurrentDef.DefType = dtSubRecordUnion then begin\n        CurrentDef := (CurrentDef as IwbRecordDef).Members[0];\n        Assert(Assigned(CurrentDef));\n      end;\n\n      case CurrentDef.DefType of\n        dtSubRecord :       Element := TwbSubRecord.Create(Self, CurrentDef as IwbSubRecordDef);\n        dtSubRecordArray  : Element := TwbSubRecordArray.Create(Self, nil, Low(Integer), CurrentDef as IwbSubRecordArrayDef);\n        dtSubRecordStruct : Element := TwbSubRecordStruct.Create(Self, nil, Low(Integer), CurrentDef as IwbSubRecordStructDef);\n      else\n        Assert(False);\n      end;\n\n      Element.SetSortOrder(CurrentDefPos);\n      Element.SetMemoryOrder(CurrentDefPos);\n\n    end;\n  end;\nend;\n\nfunction TwbSubRecordStruct.AssignInternal(aIndex: Integer; const aElement: IwbElement; aOnlySK: Boolean): IwbElement;\nvar\n  Member    : IwbRecordMemberDef;\n  Container : IwbContainer;\n  Element   : IwbElement;\n  i         : Integer;\nbegin\n  Result := nil;\n\n  if not wbEditAllowed then\n    raise Exception.Create(GetName + ' can not be assigned.');\n\n  if aIndex = Low(Integer) then begin\n\n    Container := aElement as IwbContainer;\n\n    SetModified(True);\n    InvalidateStorage;\n    ReleaseElements;\n    AddRequiredElements;\n\n    if Assigned(Container) then\n      for i := 0 to Pred(Container.ElementCount) do begin\n        Element := Container.Elements[i];\n        if not aOnlySK or GetIsInSK(Element.SortOrder) then\n          Assign(Element.SortOrder, Element, aOnlySK);\n      end;\n\n  end else begin\n\n    if (aIndex >= 0) and (aIndex < srcDef.MemberCount) then begin\n      Member := srcDef.Members[aIndex];\n      if not Assigned(aElement) or Member.CanAssign(Self, Low(Integer), aElement.Def) then begin\n        Element := GetElementBySortOrder(aIndex + GetAdditionalElementCount);\n        if Assigned(Element) then begin\n          if Assigned(aElement) then\n            Element.Assign(Low(Integer), aElement, aOnlySK)\n        end else begin\n\n          case Member.DefType of\n            dtSubRecord:\n              Element := TwbSubRecord.Create(Self, Member as IwbSubRecordDef);\n            dtSubRecordArray:\n              Element := TwbSubRecordArray.Create(Self, nil, Low(Integer), Member as IwbSubRecordArrayDef);\n            dtSubRecordStruct:\n              Element := TwbSubRecordStruct.Create(Self, nil, Low(Integer), Member as IwbSubRecordStructDef);\n          else\n            Assert(False);\n          end;\n\n          if Assigned(Element) then try\n            Element.SortOrder := aIndex;\n            if Assigned(aElement) then\n              Element.Assign(Low(Integer), aElement, aOnlySK);\n          except\n            Element.Container.RemoveElement(Element);\n            raise;\n          end;\n\n        end;\n        Result := Element;\n      end;\n    end;\n  end;\n\n  if wbSortSubRecords and (Length(cntElements) > 1) then\n    wbMergeSort(@cntElements[0], Length(cntElements), CompareSubRecords);\nend;\n\nfunction TwbSubRecordStruct.CanAssignInternal(aIndex: Integer; const aElement: IwbElement; aCheckDontShow: Boolean): Boolean;\nbegin\n  Result := False;\n  if not wbEditAllowed then\n    Exit;\n\n  if Assigned(eContainer) then\n    if not IwbContainer(eContainer).IsElementEditable(Self) then\n      Exit;\n\n  if aCheckDontShow and GetDontShow then\n    Exit;\n\n  if not Assigned(aElement) then begin\n    Result := (aIndex >= 0) and (aIndex < srcDef.MemberCount) and (GetElementBySortOrder(aIndex + GetAdditionalElementCount) = nil);\n    if Result and aCheckDontShow then\n      if srcDef.Members[aIndex].DontShow[Self] then\n        Result := False;\n    Exit;\n  end;\n\n  if Assigned(srcDef) then begin\n    if aIndex = Low(Integer) then\n      Result := srcDef.Equals(aElement.Def)\n    else begin\n      Result := (aIndex >= 0) and (aIndex < srcDef.MemberCount) and\n        srcDef.Members[aIndex].CanAssign(Self, Low(Integer), aElement.Def);\n      if Result and aCheckDontShow then\n        if srcDef.Members[aIndex].DontShow[Self] then\n          Result := False;\n    end;\n  end else\n    Result := False;\nend;\n\nfunction TwbSubRecordStruct.CanContainFormIDs: Boolean;\nbegin\n Result := srcDef.CanContainFormIDs;\nend;\n\nfunction TwbSubRecordStruct.CanElementReset: Boolean;\nbegin\n//  Result := inherited CanElementReset;\n  Result := cntElementRefs < 1;\nend;\n\nconstructor TwbSubRecordStruct.Create(const aOwner     : IwbContainer;\n                                      const aContainer : IwbContainer;\n                                            aPos       : Integer;\n                                      const aDef       : IwbSubRecordStructDef);\nvar\n  CurrentDefPos : Integer;\n  CurrentRec    : IwbSubRecordInternal;\n  CurrentDef    : IwbRecordMemberDef;\n  Element       : IwbElementInternal;\nbegin\n  srcDef := aDef as IwbRecordDef;\n\n  if aPos = Low(Integer) then begin\n    AddRequiredElements;\n  end else begin\n    CurrentDefPos := 0;\n    while (aPos < aContainer.ElementCount) and (CurrentDefPos < srcDef.MemberCount) do begin\n\n      if aContainer[aPos].ElementType <> etSubRecord then\n        Break;\n\n      CurrentRec := aContainer[aPos] as IwbSubRecordInternal;\n\n      if not srcDef.ContainsMemberFor(CurrentRec.Signature, CurrentRec) then begin\n        if srcDef.SkipSignature[CurrentRec.Signature] then begin\n          Inc(aPos);\n          Continue;\n        end;\n        Break;\n      end;\n\n      if srcDef.AllowUnordered then begin\n\n        CurrentDefPos := srcDef.GetMemberIndexFor(CurrentRec.Signature, CurrentRec);\n        if CurrentDefPos < 0 then begin\n          if Assigned(wbProgressCallback) then\n            wbProgressCallback('Error: record '+ String(GetSignature) + ' contains unexpected (or out of order) subrecord ' + String(CurrentRec.Signature) + ' ' + IntToHex(Int64(Cardinal(CurrentRec.Signature)), 8) );\n          //FoundError := True;\n          Inc(aPos);\n          Continue;\n        end;\n        CurrentDef := srcDef.Members[CurrentDefPos];\n\n      end;\n\n      CurrentDef := srcDef.Members[CurrentDefPos];\n      if not CurrentDef.CanHandle(CurrentRec.Signature, CurrentRec) then begin\n        Inc(CurrentDefPos);\n        Continue;\n      end;\n\n      if CurrentDef.DefType = dtSubRecordUnion then begin\n        CurrentDef := (CurrentDef as IwbRecordDef).GetMemberFor(CurrentRec.Signature, CurrentRec);\n        Assert(Assigned(CurrentDef));\n      end;\n\n      case CurrentDef.DefType of\n        dtSubRecord : begin\n          aContainer.RemoveElement(aPos);\n          CurrentRec.SetDef(CurrentDef as IwbSubRecordDef);\n          AddElement(CurrentRec);\n          Element := CurrentRec as IwbElementInternal;\n        end;\n        dtSubRecordArray  : Element := TwbSubRecordArray.Create(Self, aContainer, aPos, CurrentDef as IwbSubRecordArrayDef);\n        dtSubRecordStruct : Element := TwbSubRecordStruct.Create(Self, aContainer, aPos, CurrentDef as IwbSubRecordStructDef);\n      else\n        raise Exception.CreateFmt('Unexpected def type for SubRecord %s', [String(CurrentRec.Signature)]);\n      end;\n\n      Element.SetSortOrder(CurrentDefPos);\n      Element.SetMemoryOrder(CurrentDefPos);\n\n      Inc(CurrentDefPos);\n    end;\n  end;\n\n  srcDef.AfterLoad(Self);\n\n  inherited Create(aOwner);\n  if aPos = Low(Integer) then begin\n    SetModified(True);\n    InvalidateStorage;\n  end;\nend;\n\nfunction TwbSubRecordStruct.GetDef: IwbNamedDef;\nbegin\n  Result := srcDef;\nend;\n\nfunction TwbSubRecordStruct.GetElementType: TwbElementType;\nbegin\n  Result := etSubRecordStruct;\nend;\n\nfunction TwbSubRecordStruct.GetIsInSK(aIndex: Integer): Boolean;\nvar\n  SelfRef    : IwbContainerElementRef;\n  HasSortKey : IwbHasSortKeyDef;\nbegin\n  Result := False;\n\n  SelfRef := Self as IwbContainerElementRef;\n  DoInit;\n\n  if not Supports(srcDef, IwbHasSortKeyDef, HasSortKey) then\n    Exit;\n\n  Result := HasSortKey.IsInSK(aIndex);\nend;\n\nfunction TwbSubRecordStruct.GetName: string;\nbegin\n  Result := srcDef.GetName;\nend;\n\nfunction TwbSubRecordStruct.GetSignature: TwbSignature;\nvar\n  i       : Integer;\n  lRecord : IwbRecord;\n\n  SelfRef : IwbContainerElementRef;\nbegin\n  SelfRef := Self as IwbContainerElementRef;\n\n  Result := NONE;\n  for i := 0 to Pred(GetElementCount) do\n    if Supports(GetElement(i), IwbRecord, lRecord) then begin\n      Result := lRecord.Signature;\n      Exit;\n    end;\nend;\n\nfunction TwbSubRecordStruct.GetSortKeyInternal(aExtended: Boolean): string;\nvar\n  HasSortKey : IwbHasSortKeyDef;\n  SortMember : Integer;\n  Element    : IwbElement;\n  i          : Integer;\n  SelfRef : IwbContainerElementRef;\nbegin\n  SelfRef := Self as IwbContainerElementRef;\n  Result := '';\n  if Supports(srcDef, IwbHasSortKeyDef, HasSortKey) then begin\n    DoInit;\n    if HasSortKey.SortKeyCount[False] > 0 then\n      for i := 0 to Pred(HasSortKey.SortKeyCount[aExtended]) do begin\n        SortMember := HasSortKey.SortKeys[i, aExtended];\n        Element := GetElementBySortOrder(SortMember + GetAdditionalElementCount);\n        if Assigned(Element) then\n          Result := Result + Element.SortKey[aExtended];\n\n        if i < Pred(HasSortKey.SortKeyCount[aExtended]) then\n          Result := Result + '|';\n      end;\n  end;\nend;\n\nfunction TwbSubRecordStruct.IsElementRemoveable(const aElement: IwbElement): Boolean;\nbegin\n  Result := IsElementEditable(aElement) and (Length(cntElements) > 1) and (srcDef.AllowUnordered or not cntElements[0].Equals(aElement));\n  if Result and Assigned(aElement.Def) then\n    Result := not aElement.Def.Required;\nend;\n\nfunction TwbSubRecordStruct.RemoveInjected(aCanRemove: Boolean): Boolean;\nvar\n  Element   : IwbElement;\n  Container : IwbContainerElementRef;\n  SelfRef   : IwbContainerElementRef;\n  i         : Integer;\nbegin\n  if SameText(GetName, 'Result Script') then begin\n    Result := False;\n\n    SelfRef := Self as IwbContainerElementRef;\n    DoInit;\n\n    if Supports(GetElementByName('References'), IwbContainerElementRef, Container) then\n      for i := 0 to Pred(Container.ElementCount) do begin\n        Result := Container.Elements[i].ReferencesInjected;\n        if Result then\n          Break;\n      end;\n\n    if Result then begin\n      Result := False;\n      Container.Remove;\n      Element := GetRecordBySignature('SCHD');\n      if Assigned(Element) then\n        Element.Remove;\n      Element := GetRecordBySignature('SCDA');\n      if Assigned(Element) then\n        Element.Remove;\n      Element := GetRecordBySignature('SCTX');\n      if Assigned(Element) then\n        Element.Remove;\n      if Supports(GetRecordBySignature('SCHR'), IwbContainerElementRef, Container) then begin\n        Container.ElementByName['RefCount'].EditValue := '0';\n        Container.ElementByName['CompiledSize'].EditValue := '0';\n        Container.ElementByName['VariableCount'].EditValue := '0';\n      end;\n    end;\n  end else\n    Result := inherited RemoveInjected(aCanRemove);\nend;\n\nfunction ArrayDoInit(const aValueDef: IwbValueDef; const aContainer: IwbContainer; var aBasePtr: Pointer; aEndPtr: Pointer; out SizePrefix: Integer): Boolean;\nvar\n  Element  : IwbElement;\n  ArrayDef : IwbArrayDef;\n  ValueDef : IwbValueDef;\n  i        : Integer;\n  t        : string;\n  VarSize  : Boolean;\n  ArrSize  : Integer;\nbegin\n  ArrayDef := aValueDef as IwbArrayDef;\n  Result := wbSortSubRecords and ArrayDef.Sorted;\n  if not ArrayDef.CanAddTo then\n    aContainer.SetElementState(esNotSuitableToAddTo);\n\n  SizePrefix := ArrayDef.PrefixSize[aBasePtr];\n\n  i := 0;\n\n  ValueDef := ArrayDef.Element;\n  VarSize := ArrayDef.IsVariableSize;\n  ArrSize := ArrayDef.ElementCount;\n  if ArrSize < 0 then begin\n    ArrSize := ArrayDef.PrefixCount[aBasePtr];\n  end else\n    if (ArrSize < 1) and Assigned(ArrayDef.CountCallback) then\n      ArrSize := ArrayDef.CountCallback(aBasePtr, aEndPtr, aContainer)\n    else if VarSize then\n      ArrSize := High(Integer);\n\n  if Assigned(aBasePtr) then\n    Inc(PByte(aBasePtr), SizePrefix);\n\n  if ArrSize > 0 then\n    while not VarSize or ((Cardinal(aBasePtr) < Cardinal(aEndPtr)) or (not Assigned(aBasePtr))) do begin\n      if Result then\n        t := ''\n      else begin\n        t := ArrayDef.ElementLabel[i];\n        if t <> '' then\n          t := ' (' + t + ')';\n        t := '#' + IntToStr(i) + t;\n      end;\n\n      case ValueDef.DefType of\n        dtArray: Element := TwbArray.Create(aContainer, aBasePtr, aEndPtr, ValueDef, t);\n        dtStruct: Element := TwbStruct.Create(aContainer, aBasePtr, aEndPtr, ValueDef, t);\n        dtStructChapter: Element := TwbChapter.Create(aContainer, aBasePtr, aEndPtr, ValueDef, t);\n        dtUnion: Element := TwbUnion.Create(aContainer, aBasePtr, aEndPtr, ValueDef, t);\n        dtString: begin\n          if Assigned(aBasePtr) and (PAnsiChar(aBasePtr)^ = #0) and (ValueDef.IsVariableSize) then begin\n            Inc(PByte(aBasePtr));\n            Break;\n          end;\n          Element := TwbValue.Create(aContainer, aBasePtr, aEndPtr, ValueDef, t);\n        end;\n      else\n        Element := TwbValue.Create(aContainer, aBasePtr, aEndPtr, ValueDef, t);\n      end;\n\n      Inc(i);\n      if VarSize and not Assigned(aBasePtr) then begin\n        (aContainer as IwbContainerInternal).CreatedEmpty;\n        Break;\n      end;\n\n      Dec(ArrSize);\n      if ArrSize = 0 then\n        Break\n      { else if not (not VarSize or ((Cardinal(aBasePtr) < Cardinal(aEndPtr)) or (not Assigned(aBasePtr)))) then\n        wbProgressCallback('Error: not enough data for array. Elements remaining are '+IntToStr(ArrSize)) Silently fails = called at an invalid time };\n    end;\n\n  if (ValueDef.DefType = dtString) and (ValueDef.IsVariableSize) then\n    Element := TwbStringListTerminator.Create(aContainer);\n\n  ArrayDef.AfterLoad(aContainer);\nend;\n\n{ TwbArray }\n\nprocedure TwbArray.Init;\nvar\n  BasePtr: Pointer;\nbegin\n  inherited;\n\n  if GetSkipped then\n    Exit;\n\n  BasePtr := GetDataBasePtr;\n  arrSorted := ArrayDoInit(vbValueDef, Self, BasePtr, dcDataEndPtr, arrSizePrefix);\n\n  arrSortInvalid := arrSorted;\nend;\n\nfunction TwbArray.AddIfMissingInternal(const aElement: IwbElement; aAsNew, aDeepCopy: Boolean; const aPrefixRemove, aPrefix, aSuffix: string): IwbElement;\nvar\n  SelfRef   : IwbContainerElementRef;\n  i         : Integer;\n  s         : string;\n  ArrayDef  : IwbArrayDef;\nbegin\n  if not wbEditAllowed then\n    raise Exception.Create(GetName + ' can not be modified.');\n\n  SelfRef := Self as IwbContainerElementRef;\n\n  DoInit;\n\n  ArrayDef := vbValueDef as IwbArrayDef;\n\n  if arrSorted then begin\n    Assert(not arrSortInvalid);\n    if FindBySortKey(aElement.SortKey[False], False, i) then begin\n      Result := cntElements[i];\n      if aDeepCopy then\n        Result.Assign(Low(Integer), aElement, False);\n      Exit;\n    end;\n  end;\n\n  if arrSorted then\n    s := ''\n  else\n    s := '#' + IntToStr(Length(cntElements));\n\n  if not Supports(aElement, IwbStringListTerminator) then\n    case ArrayDef.Element.DefType of\n      dtArray: Result := TwbArray.Create(Self, ArrayDef.Element, aElement, not aDeepCopy, s);\n      dtStruct: Result := TwbStruct.Create(Self, ArrayDef.Element, aElement, not aDeepCopy, s);\n      dtStructChapter: Result := TwbChapter.Create(Self, ArrayDef.Element, aElement, not aDeepCopy, s);\n      dtUnion: Result := TwbUnion.Create(Self, ArrayDef.Element, aElement, not aDeepCopy, s);\n    else\n      Result := TwbValue.Create(Self, ArrayDef.Element, aElement, not aDeepCopy, s);\n    end;\n\n  CheckCount;\n  CheckTerminator;\nend;\n\nfunction TwbArray.AssignInternal(aIndex: Integer; const aElement: IwbElement; aOnlySK: Boolean): IwbElement;\nvar\n  Element       : IwbElement;\n  sElement      : IwbElement;\n  dElement      : IwbElement;\n  ArrayDef      : IwbArrayDef;\n  Container     : IwbContainer;\n  DataContainer : IwbDataContainer;\n  s             : string;\n  i             : Integer;\n  SelfRef       : IwbContainerElementRef;\n  p, q          : Pointer;\nbegin\n  Result := nil;\n\n  if not wbEditAllowed then\n    raise Exception.Create(GetName + ' can not be assigned.');\n\n  SelfRef := Self as IwbContainerElementRef;\n  DoInit;\n\n  ArrayDef := vbValueDef as IwbArrayDef;\n\n  if (aIndex = Low(Integer)) and ArrayDef.CanAssign(Self, aIndex, aElement.ValueDef) then begin\n\n    if aOnlySK then\n      Exit;\n\n    Container := aElement as IwbContainer;\n\n    if ArrayDef.IsVariableSize then begin\n      Assert(ArrayDef.ElementCount <= 0);\n      SetModified(True);\n      InvalidateStorage;\n      ReleaseElements;\n      dcDataStorage := nil;\n      dcDataBasePtr := @EmptyPtr;\n      dcDataEndPtr := @EmptyPtr;\n      Exclude(dcFlags, dcfStorageInvalid);\n      if ArrayDef.ElementCount < 0 then\n        if aElement.DataSize > 0 then begin\n          RequestStorageChange(p, q, aElement.DataSize);\n          if Supports(aElement, IwbDataContainer, DataContainer) then begin\n            q := DataContainer.DataBasePtr;\n            Move(q^, p^, aElement.DataSize);\n          end;\n        end else\n          RequestStorageChange(p, q, ArrayDef.PrefixSize[nil]);\n      NotifyChanged(eContainer);\n\n      for i := 0 to Pred(Container.ElementCount) do\n        Assign(i, Container.Elements[i], aOnlySK);\n    end else begin\n      Assert(Container.ElementCount = ArrayDef.ElementCount);\n      Assert(GetElementCount = ArrayDef.ElementCount);\n\n      for i := 0 to Pred(Container.ElementCount) do begin\n        sElement := Container.Elements[i];\n        dElement := GetElementByMemoryOrder(i);\n        dElement.Assign(Low(Integer), sElement, aOnlySK);\n      end;\n    end;\n\n  end else begin\n    if (aIndex >= 0) and (ArrayDef.ElementCount <= 0) and ((aIndex = High(Integer)) or ArrayDef.Element.CanAssign(Self, Low(Integer), aElement.ValueDef)) then begin\n      {add one entry}\n\n      if arrSorted then\n        s := ''\n      else\n        s := '#' + IntToStr(Length(cntElements));\n\n      Element := nil;\n\n      if not Supports(aElement, IwbStringListTerminator) then\n        case ArrayDef.Element.DefType of\n          dtArray: Element := TwbArray.Create(Self, ArrayDef.Element, aElement, aOnlySK, s);\n          dtStruct: Element := TwbStruct.Create(Self, ArrayDef.Element, aElement, aOnlySK, s);\n          dtStructChapter: Element := TwbChapter.Create(Self, ArrayDef.Element, aElement, aOnlySK, s);\n          dtUnion: Element := TwbUnion.Create(Self, ArrayDef.Element, aElement, aOnlySK, s);\n        else\n          Element := TwbValue.Create(Self, ArrayDef.Element, aElement, aOnlySK, s);\n        end;\n\n      Result := Element;\n\n    end;\n  end;\n\n  CheckCount;\n  CheckTerminator;\nend;\n\nfunction TwbArray.CanAssignInternal(aIndex: Integer; const aElement: IwbElement; aCheckDontShow: Boolean): Boolean;\nvar\n  ArrayDef: IwbArrayDef;\nbegin\n  Result := False;\n  if not wbEditAllowed then\n    Exit;\n\n  if Assigned(eContainer) then\n    if not IwbContainer(eContainer).IsElementEditable(Self) then\n      Exit;\n\n  if aCheckDontShow and GetDontShow then\n    Exit;\n\n  ArrayDef := vbValueDef as IwbArrayDef;\n  if not Assigned(aElement) then begin\n    if aIndex = High(Integer) then\n      Result := ArrayDef.ElementCount <= 0;\n    Exit;\n  end;\n  Result :=\n     ArrayDef.CanAssign(Self, aIndex, aElement.ValueDef) or\n     ( (ArrayDef.ElementCount <= 0) and ArrayDef.Element.CanAssign(Self, Low(Integer), aElement.ValueDef) );\nend;\n\nfunction TwbArray.CanMoveElement: Boolean;\nbegin\n  Result := not arrSorted;\nend;\n\nprocedure TwbArray.CheckCount;\nvar\n  Count       : Cardinal;\n  i           : Integer;\n  UpdateCount : Integer;\n  ArrayDef    : IwbArrayDef;\nbegin\n  if arrSizePrefix = 0 then\n    Exit;\n\n  ArrayDef := vbValueDef as IwbArrayDef;\n  Count := arrayDef.PrefixCount[dcDataBasePtr];\n\n  DoInit;\n\n  if Count <> Length(cntElements) then begin\n    UpdateCount := eUpdateCount;\n    for i := 1 to UpdateCount do EndUpdate;  // Stops optimisation\n    ArrayDef.SetPrefixCount(dcDataBasePtr, Length(cntElements));\n    for i := 1 to UpdateCount do BeginUpdate; // Restore optimisation\n  end;\nend;\n\nprocedure TwbArray.CheckTerminator;\nvar\n  i        : Integer;\n  ArrayDef : IwbArrayDef;\nbegin\n  ArrayDef := vbValueDef as IwbArrayDef;\n  if not ArrayDef.IsVariableSize then\n    Exit;\n  if ArrayDef.Element.DefType <> dtString then\n    Exit;\n\n  for i := Low(cntElements) to High(cntElements) do\n    if Supports(cntElements[i], IwbStringListTerminator) then\n      Exit;\n\n  SetModified(True);\n  InvalidateStorage;\n  TwbStringListTerminator.Create(Self);\n  if arrSorted then\n    arrSortInvalid := True;\nend;\n\nprocedure TwbArray.DoInit;\nvar\n  i       : Integer;\n  Sorting : Boolean;\nbegin\n  inherited;\n  if arrSorted and arrSortInvalid then\n    if (Length(cntElements) > 1) then begin\n      Sorting := False;\n      for i := 0 to Length(cntElements)-1 do\n        if (esSorting in (cntElements[i] as IwbElementInternal).ElementStates) then begin\n          Sorting := TRue;\n          Break;\n        end;\n        if not Sorting then begin\n          wbMergeSort(@cntElements[0], Length(cntElements), CompareSortKeys);\n          arrSortInvalid := False;\n        end;\n    end;\nend;\n\nprocedure TwbArray.ElementChanged(const aElement: IwbElement; aContainer: Pointer);\nbegin\n  inherited;\n  if arrSorted then\n    arrSortInvalid := True;\nend;\n\nfunction TwbArray.GetDataPrefixSize: Integer;\nbegin\n  Result := arrSizePrefix;\nend;\n\nfunction TwbArray.GetElementType: TwbElementType;\nbegin\n  Result := etArray;\nend;\n\nfunction TwbArray.GetSorted: Boolean;\nbegin\n  Result := arrSorted;\nend;\n\nfunction TwbArray.IsElementRemoveable(const aElement: IwbElement): Boolean;\nbegin\n  Result := IsElementEditable(aElement) and ((vbValueDef as IwbArrayDef).ElementCount <= 0) { and (Length(cntElements)>1)};\nend;\n\nprocedure TwbArray.PrepareSave;\nbegin\n  CheckCount;\n  CheckTerminator;\n  inherited;\nend;\n\nprocedure TwbArray.Reset;\nbegin\n  ReleaseElements;\n  arrSorted := False;\n  arrSortInvalid := False;\n  inherited;\nend;\n\nprocedure TwbArray.SetModified(aValue: Boolean);\nbegin\n  inherited;\n  if aValue and arrSorted then\n    arrSortInvalid := True;\nend;\n\n{ TwbStruct }\n\nprocedure StructDoInit(const aValueDef: IwbValueDef; const aContainer: IwbContainer; var aBasePtr: Pointer; aEndPtr: Pointer);\nvar\n  StructDef           : IwbStructDef;\n  i                   : Integer;\n  ValueDef            : IwbValueDef;\n  Element             : IwbElementInternal;\n  IntegerDef          : IwbIntegerDef;\n  OptionalFromElement : Integer;\n  Size                : Integer;\n  over                : Boolean;\nbegin\n  StructDef := aValueDef as IwbStructDef;\n\n  OptionalFromElement := StructDef.OptionalFromElement;\n  if OptionalFromElement < 0 then\n    OptionalFromElement := High(Integer);\n\n  for i := 0 to Pred(StructDef.MemberCount) do begin\n    ValueDef := StructDef.Members[i];\n    if Assigned(aBasePtr) and (i >= OptionalFromElement) then begin\n      over := (Cardinal(aBasePtr) >= Cardinal(aEndPtr));\n      if not over then begin\n        Size := ValueDef.Size[aBasePtr, aEndPtr, aContainer];\n        over := (Size<High(Integer)) and  //Intercept multiple calls to Size[ during initialisation\n                ((Cardinal(aBasePtr) + Size) > Cardinal(aEndPtr));\n      end;\n      if over then begin\n        aEndPtr := aBasePtr;\n        ValueDef := Resolve(ValueDef, aBasePtr, aEndPtr, aContainer);\n        if Supports(ValueDef, IwbIntegerDef, IntegerDef) and Supports(IntegerDef.Formater[aContainer], IwbFlagsDef) then\n          ValueDef := wbEmpty(ValueDef.Name, cpIgnore, False, nil, True)\n        else\n          ValueDef := wbEmpty(ValueDef.Name, cpIgnore);\n      end;\n    end;\n\n    case ValueDef.DefType of\n      dtArray: Element := TwbArray.Create(aContainer, aBasePtr, aEndPtr, ValueDef, '');\n      dtStruct: Element := TwbStruct.Create(aContainer, aBasePtr, aEndPtr, ValueDef, '');\n      dtStructChapter: Element := TwbChapter.Create(aContainer, aBasePtr, aEndPtr, ValueDef, '');\n      dtUnion: Element := TwbUnion.Create(aContainer, aBasePtr, aEndPtr, ValueDef, '');\n    else\n      Element := TwbValue.Create(aContainer, aBasePtr, aEndPtr, ValueDef, '');\n    end;\n\n    {if wbHideUnused and not wbEditAllowed and (Element.GetName = 'Unused') then begin\n      with aContainer do begin\n        Assert((LastElement as IwbElementInternal) = Element);\n        RemoveElement(Pred(ElementCount));\n      end;\n    end else} begin\n      Element.SetSortOrder(i);\n      Element.SetMemoryOrder(i);\n    end;\n  end;\n\n  StructDef.AfterLoad(aContainer);\nend;\n\nprocedure TwbStruct.Init;\nvar\n  BasePtr: Pointer;\nbegin\n  inherited;\n\n  if GetSkipped then\n    Exit;\n\n  DecompressIfNeeded;\n\n  BasePtr := GetDataBasePtr;\n  StructDoInit(vbValueDef, Self, BasePtr, dcDataEndPtr);\nend;\n\nfunction TwbStruct.GetElementType: TwbElementType;\nbegin\n  Result := etStruct;\nend;\n\nprocedure TwbStruct.Reset;\nbegin\n  ReleaseElements;\n  inherited;\nend;\n\nprocedure TwbStruct.DecompressIfNeeded;\nvar\n  sc : TwbStructCompression;\nbegin\n  sc := IsCompressed;\n  if sc <> scNone then try\n    InitDataPtr; // reset...\n\n    SetLength(dcDataStorage, szUncompressedSize );\n\n    case sc of\n      scNone: Assert(False);  // Getting there would be very funny :)\n      scZComp:\n        DecompressToUserBuf(\n          Pointer(Cardinal(dcDataBasePtr)),\n          GetDataSize,\n          @dcDataStorage[0],\n          PCardinal(dcDataBasePtr)^\n        );\n      scLZComp:\n        LZ4_decompress_safe(Pointer(Cardinal(dcDataBasePtr)), @dcDataStorage[0], GetDataSize, szUncompressedSize);\n      else\n        Assert(False);  // Something hasn't been updated yet.\n    end;\n\n    dcDataEndPtr := Pointer( Cardinal(@dcDataStorage[0]) + szUncompressedSize );\n    dcDataBasePtr := @dcDataStorage[0];\n  except\n    dcDataBasePtr := nil;\n    dcDataEndPtr := nil;\n  end;\nend;\n\nfunction TwbStruct.GetIsCompressed: TwbStructCompression;\nvar\n  szDef : IwbStructZDef;\n  lzDef : IwbStructLZDef;\nbegin\n  if (szCompressedSize = 0) then\n    if Supports(vbValueDef, IwbStructZDef, szDef)  then begin\n      szUncompressedSize := szDef.GetSizing(GetDataBasePtr, GetDataEndPtr, Self, szCompressedSize);\n      if szUncompressedSize <> 0 then szCompressedType := scZComp;\n    end else if Supports(vbValueDef, IwbStructLZDef, lzDef)  then begin\n      szUncompressedSize := lzDef.GetSizing(GetDataBasePtr, GetDataEndPtr, Self, szCompressedSize);\n      if szUncompressedSize <> 0 then szCompressedType := scLZComp;\n    end else\n      szCompressedSize := -1;\n  Result := szCompressedType;\nend;\n\n{ TwbUnion }\n\nfunction UnionDoInit(const aValueDef: IwbValueDef; const aContainer: IwbContainer; var aBasePtr: Pointer; aEndPtr: Pointer): TwbUnionFlags;\nvar\n  UnionDef : IwbUnionDef;\n  ValueDef : IwbValueDef;\n  ArrayDef : IwbArrayDef;\n  Element  : IwbElementInternal;\n\nbegin\n  Result := ufNone;\n  UnionDef := aValueDef as IwbUnionDef;\n\n  ValueDef := UnionDef.Decide(aBasePtr, aEndPtr, aContainer);\n\n  if Assigned(ValueDef) then // I had one case. Most likely due to an error in wbXXXXDefinitions\n    case ValueDef.DefType of\n      dtArray: begin\n        if wbSortSubRecords and Supports(ValueDef, IwbArrayDef, ArrayDef) and ArrayDef.Sorted then\n          Result := ufSortedArray\n        else\n          Result := ufArray;\n        Element := TwbArray.Create(aContainer, aBasePtr, aEndPtr, ValueDef, '');\n      end;\n      dtStruct: Element := TwbStruct.Create(aContainer, aBasePtr, aEndPtr, ValueDef, '');\n      dtStructChapter: Element := TwbChapter.Create(aContainer, aBasePtr, aEndPtr, ValueDef, '');\n      dtUnion: Element := TwbUnion.Create(aContainer, aBasePtr, aEndPtr, ValueDef, '');\n    else\n      Element := nil; // >>> so that simple union behave as they did <<< TwbValue.Create(aContainer, aBasePtr, aEndPtr, ValueDef, '');\n      if ValueDoInit(aValueDef, aContainer, aBasePtr, aEndPtr, aContainer) then Result := ufFlags;\n    end;\n\n  if Assigned(Element) then begin\n    Element.SetSortOrder(0);\n    Element.SetMemoryOrder(0);\n  end;\n\n  UnionDef.AfterLoad(aContainer);\nend;\n\nfunction TwbUnion.CompareExchangeFormID(aOldFormID, aNewFormID: Cardinal): Boolean;\nvar\n  SelfRef     : IwbContainerElementRef;\n  ResolvedDef : IwbValueDef;\nbegin\n  SelfRef := Self as IwbContainerElementRef;\n\n  DoInit;\n\n  Result := inherited CompareExchangeFormID(aOldFormID, aNewFormID);\n\n  ResolvedDef := Resolve(vbValueDef, GetDataBasePtr, dcDataEndPtr, Self);\n  if Assigned(ResolvedDef) then\n    Result := ResolvedDef.CompareExchangeFormID(GetDataBasePtr, dcDataEndPtr, Self, aOldFormID, aNewFormID) or Result;\nend;\n\nfunction TwbUnion.GetElementType: TwbElementType;\nbegin\n  Result := etUnion;\nend;\n\nprocedure TwbUnion.Init;\nvar\n  BasePtr: Pointer;\nbegin\n  inherited;\n\n  if GetSkipped then\n    Exit;\n\n  BasePtr := GetDataBasePtr;\n  UnionDoInit(vbValueDef, Self, BasePtr, dcDataEndPtr);\nend;\n\nprocedure TwbUnion.MasterCountUpdated(aOld, aNew: Byte);\nvar\n  SelfRef     : IwbContainerElementRef;\n  ResolvedDef : IwbValueDef;\nbegin\n  SelfRef := Self as IwbContainerElementRef;\n\n  DoInit;\n\n  inherited MasterCountUpdated(aOld, aNew);\n\n  ResolvedDef := Resolve(vbValueDef, GetDataBasePtr, dcDataEndPtr, Self);\n  if Assigned(ResolvedDef) then\n    ResolvedDef.MasterCountUpdated(GetDataBasePtr, dcDataEndPtr, Self, aOld, aNew);\nend;\n\nprocedure TwbUnion.MasterIndicesUpdated(const aOld, aNew: TBytes);\nvar\n  SelfRef    : IwbContainerElementRef;\n  ResolvedDef : IwbValueDef;\nbegin\n  SelfRef := Self as IwbContainerElementRef;\n\n  DoInit;\n\n  inherited MasterIndicesUpdated(aOld, aNew);\n\n  ResolvedDef := Resolve(vbValueDef, GetDataBasePtr, dcDataEndPtr, Self);\n  if Assigned(ResolvedDef) then\n    ResolvedDef.MasterIndicesUpdated(GetDataBasePtr, dcDataEndPtr, Self, aOld, aNew);\nend;\n\nprocedure TwbUnion.FindUsedMasters(aMasters: PwbUsedMasters);\nvar\n  SelfRef    : IwbContainerElementRef;\n  ResolvedDef : IwbValueDef;\nbegin\n  SelfRef := Self as IwbContainerElementRef;\n\n  DoInit;\n\n  inherited FindUsedMasters(aMasters);\n\n  ResolvedDef := Resolve(vbValueDef, GetDataBasePtr, dcDataEndPtr, Self);\n  if Assigned(ResolvedDef) then\n    ResolvedDef.FindUsedMasters(GetDataBasePtr, dcDataEndPtr, Self, aMasters);\nend;\n\nprocedure TwbUnion.Reset;\nbegin\n  ReleaseElements;\n  inherited;\nend;\n\n{ TwbValue }\n\nfunction TwbValue.AddIfMissingInternal(const aElement      :  IwbElement;\n                                     aAsNew        :  Boolean;\n                                     aDeepCopy     :  Boolean;\n                               const aPrefixRemove : string;\n                               const aPrefix       : string;\n                               const aSuffix       : string)\n                                                   : IwbElement;\nvar\n  Flag       : IwbFlag;\n  IntegerDef : IwbIntegerDef;\n  FlagsDef   : IwbFlagsDef;\n  s          : string;\nbegin\n  if vIsFlags and Supports(aElement, IwbFlag, Flag) then\n    if Supports(vbValueDef, IwbIntegerDef, IntegerDef) then\n      if Supports(IntegerDef.Formater[Self], IwbFlagsDef, FlagsDef) then\n        if FlagsDef.CanAssign(Self, Low(Integer), Flag.FlagsDef) then begin\n          s := GetEditValue;\n          s := s + StringOfChar('0', 64 - Length(s));\n          if (Flag.FlagIndex >= 0) and (Flag.FlagIndex < Length(s)) then begin\n            s[Succ(Flag.FlagIndex)] := '1';\n            SetEditValue(s);\n            Exit(GetElementBySortOrder(Flag.FlagIndex));\n          end;\n        end;\n\n  Result := inherited AddIfMissingInternal(aElement, aAsNew, aDeepCopy, aPrefixRemove, aPrefix, aSuffix)\nend;\n\nfunction TwbValue.CompareExchangeFormID(aOldFormID, aNewFormID: Cardinal): Boolean;\nvar\n  SelfRef     : IwbContainerElementRef;\n  ResolvedDef : IwbValueDef;\nbegin\n  SelfRef := Self as IwbContainerElementRef;\n\n  DoInit;\n\n  Result := inherited CompareExchangeFormID(aOldFormID, aNewFormID);\n\n  ResolvedDef := Resolve(vbValueDef, GetDataBasePtr, dcDataEndPtr, Self);\n  if Assigned(ResolvedDef) then\n    Result := ResolvedDef.CompareExchangeFormID(GetDataBasePtr, dcDataEndPtr, Self, aOldFormID, aNewFormID) or Result;\nend;\n\nfunction ValueDoInit(const aValueDef: IwbValueDef; const aContainer: IwbContainer; var aBasePtr: Pointer; aEndPtr: Pointer; const aElement: IwbElement): Boolean;\nvar\n  IntegerDef : IwbIntegerDef;\n  FlagsDef   : IwbFlagsDef;\n  i          : Cardinal;\n  j          : Cardinal;\n  t          : string;\n  BasePtr    : Pointer;\n  Element    : IwbElement;\n  ValueDef   : IwbValueDef;\nbegin\n  Result := False;\n\n  ValueDef := Resolve(aValueDef, aBasePtr, aEndPtr, aElement);\n\n  if Assigned(ValueDef) then\n  begin\n    if wbFlagsAsArray then\n      if Supports(ValueDef, IwbIntegerDef, IntegerDef) then\n        if Supports(IntegerDef.Formater[aElement], IwbFlagsDef, FlagsDef) then begin\n          if Assigned(aBasePtr) and (FlagsDef.FlagCount > 0) then begin\n            j := IntegerDef.ToInt(aBasePtr, aEndPtr, aContainer);\n            if j <> 0 then\n              for i := 0 to Pred(FlagsDef.FlagCount) do\n                if (j and (Cardinal(1) shl i)) <> 0 then begin\n                  t := FlagsDef.Flags[i];\n                  if (t <> '') and (not wbHideUnused or not SameText(t,'Unused')) then\n                    Element := TwbFlag.Create(aContainer, aBasePtr, aEndPtr, IntegerDef, FlagsDef, i);\n                  j := j and not (Cardinal(1) shl i);\n                  if j = 0 then\n                    Break;\n                end;\n          end;\n\n          Result := True;\n\n        end;\n\n    ValueDef.AfterLoad(aContainer);\n  end;\n\n  if wbMoreInfoForUnknown then begin\n    if Assigned(ValueDef) then\n      t := ValueDef.Name\n    else\n      t := '';\n    if t = '' then\n      t := aContainer.Def.Name;\n    if SameText(t, 'Unknown') and (not Assigned(aBasePtr) or (aBasePtr <> aEndPtr)) then\n      for i := 0 to 3 do begin\n        BasePtr := Pointer( Cardinal(aBasePtr) + i );\n        Element := TwbArray.Create(aContainer, BasePtr, aEndPtr, wbArray('Offset '+IntToStr(i)+' AsU8', wbInteger('AsU8', itU8)), '', True);\n        BasePtr := Pointer( Cardinal(aBasePtr) + i );\n        Element := TwbArray.Create(aContainer, BasePtr, aEndPtr, wbArray('Offset '+IntToStr(i)+' AsS8', wbInteger('AsS8', itS8)), '', True);\n        BasePtr := Pointer( Cardinal(aBasePtr) + i );\n        Element := TwbArray.Create(aContainer, BasePtr, aEndPtr, wbArray('Offset '+IntToStr(i)+' AsU16', wbInteger('AsU16', itU16)), '', True);\n        BasePtr := Pointer( Cardinal(aBasePtr) + i );\n        Element := TwbArray.Create(aContainer, BasePtr, aEndPtr, wbArray('Offset '+IntToStr(i)+' AsS16', wbInteger('AsS16', itS16)), '', True);\n        BasePtr := Pointer( Cardinal(aBasePtr) + i );\n        Element := TwbArray.Create(aContainer, BasePtr, aEndPtr, wbArray('Offset '+IntToStr(i)+' AsU32', wbInteger('AsU32', itU32)), '', True);\n        BasePtr := Pointer( Cardinal(aBasePtr) + i );\n        Element := TwbArray.Create(aContainer, BasePtr, aEndPtr, wbArray('Offset '+IntToStr(i)+' AsS32', wbInteger('AsS32', itS32)), '', True);\n        BasePtr := Pointer( Cardinal(aBasePtr) + i );\n        Element := TwbArray.Create(aContainer, BasePtr, aEndPtr, wbArray('Offset '+IntToStr(i)+' AsS64', wbInteger('AsS64', itS64)), '', True);\n        BasePtr := Pointer( Cardinal(aBasePtr) + i );\n        Element := TwbArray.Create(aContainer, BasePtr, aEndPtr, wbArray('Offset '+IntToStr(i)+' AsFormID', wbInteger('AsFormID', itU32, wbFormID)), '', True);\n        BasePtr := Pointer( Cardinal(aBasePtr) + i );\n        Element := TwbArray.Create(aContainer, BasePtr, aEndPtr, wbArray('Offset '+IntToStr(i)+' AsChar4', wbInteger('AsChar4', itU32, wbChar4)), '', True);\n        BasePtr := Pointer( Cardinal(aBasePtr) + i );\n        Element := TwbArray.Create(aContainer, BasePtr, aEndPtr, wbArray('Offset '+IntToStr(i)+' AsFloat', wbFloat('AsFloat')), '', True);\n        BasePtr := Pointer( Cardinal(aBasePtr) + i );\n        Element := TwbArray.Create(aContainer, BasePtr, aEndPtr, wbArray('Offset '+IntToStr(i)+' AsString', wbString('AsString')), '', True);\n        if wbToolSource in [tsSaves] then begin\n          BasePtr := Pointer( Cardinal(aBasePtr) + i );\n          Element := TwbArray.Create(aContainer, BasePtr, aEndPtr, wbArray('Offset '+IntToStr(i)+' AsRefID', wbRefID('RefID')), '', True);\n          BasePtr := Pointer( Cardinal(aBasePtr) + i );\n          Element := TwbArray.Create(aContainer, BasePtr, aEndPtr, wbArray('Offset '+IntToStr(i)+' AsU6to30', wbInteger('AsU6to30', itU6to30)), '', True);\n        end;\n      end;\n  end;\n\n  if assigned(ValueDef) then\n    i := ValueDef.Size[aBasePtr, aEndPtr, aContainer]\n  else\n    i := High(Integer);\n  if i = Cardinal(High(Integer)) then\n    aBasePtr := aEndPtr\n  else if Assigned(aBasePtr) then\n    Inc(PByte(aBasePtr), i);\nend;\n\n\nprocedure TwbValue.Init;\nvar\n  BasePtr: Pointer;\nbegin\n  inherited;\n  BasePtr := GetDataBasePtr;\n  vIsFlags := ValueDoInit(vbValueDef, Self, BasePtr, dcDataEndPtr, Self);\n// flags should already have been created in the right order, no need to sort them\n//  if vIsFlags then\n//    if Length(cntElements) > 1 then\n//      wbMergeSort(@cntElements[0], Length(cntElements), CompareSortKeys);\nend;\n\nfunction TwbValue.IsFlags: Boolean;\nbegin\n  Result := vIsFlags;\nend;\n\nprocedure TwbValue.MasterCountUpdated(aOld, aNew: Byte);\nvar\n  SelfRef     : IwbContainerElementRef;\n  ResolvedDef : IwbValueDef;\nbegin\n  SelfRef := Self as IwbContainerElementRef;\n\n  DoInit;\n\n  inherited MasterCountUpdated(aOld, aNew);\n\n  ResolvedDef := Resolve(vbValueDef, GetDataBasePtr, dcDataEndPtr, Self);\n  if Assigned(ResolvedDef) then\n    ResolvedDef.MasterCountUpdated(GetDataBasePtr, dcDataEndPtr, Self, aOld, aNew);\nend;\n\nprocedure TwbValue.MasterIndicesUpdated(const aOld, aNew: TBytes);\nvar\n  SelfRef    : IwbContainerElementRef;\n  ResolvedDef : IwbValueDef;\nbegin\n  SelfRef := Self as IwbContainerElementRef;\n\n  DoInit;\n\n  inherited MasterIndicesUpdated(aOld, aNew);\n\n  ResolvedDef := Resolve(vbValueDef, GetDataBasePtr, dcDataEndPtr, Self);\n  if Assigned(ResolvedDef) then\n    ResolvedDef.MasterIndicesUpdated(GetDataBasePtr, dcDataEndPtr, Self, aOld, aNew);\nend;\n\nprocedure TwbValue.FindUsedMasters(aMasters: PwbUsedMasters);\nvar\n  SelfRef    : IwbContainerElementRef;\n  ResolvedDef : IwbValueDef;\nbegin\n  SelfRef := Self as IwbContainerElementRef;\n\n  DoInit;\n\n  inherited FindUsedMasters(aMasters);\n\n  ResolvedDef := Resolve(vbValueDef, GetDataBasePtr, dcDataEndPtr, Self);\n  if Assigned(ResolvedDef) then\n    ResolvedDef.FindUsedMasters(GetDataBasePtr, dcDataEndPtr, Self, aMasters);\nend;\n\nfunction TwbValue.GetElementType: TwbElementType;\nbegin\n  Result := etValue;\nend;\n\nfunction TwbValue.GetSorted: Boolean;\nvar\n  EmptyDef: IwbEmptyDef;\nbegin\n  Result := vIsFlags or (Supports(Resolve(vbValueDef, GetDataBasePtr, GetDataEndPtr, Self), IwbEmptyDef, EmptyDef) and EmptyDef.Sorted);\nend;\n\nfunction TwbValue.GetValue: string;\n//var\n//  i : Integer;\n//  j : Int64;\nvar\n  Def: IwbDef;\nbegin\n  if wbReportMode then begin\n    Def := GetValueDef;\n    if Assigned(Def) then\n      Def.Used;\n    Def := GetDef;\n    if Assigned(Def) then\n      Def.Used;\n  end;\n {\n if vIsFlags then begin\n   Result := '';\n   with (vbValueDef as IwbIntegerDef), (Formater as IwbFlagsDef) do begin\n     j := ToInt(GetDataBasePtr, dcDataEndPtr, Self);\n     for i := 0 to 63 do\n       if (j and (Int64(1) shl i)) <> 0 then\n         if (i >= FlagCount) or (Flags[i] = '') then\n           Result := Result + '<Unknown: '+IntToStr(i)+'>, ';\n   end;\n   SetLength(Result, Length(Result) - 2);\n end else}\n   Result := inherited GetValue;\nend;\n\nprocedure TwbValue.Reset;\nbegin\n  vIsFlags := False;\n  ReleaseElements;\n  inherited;\nend;\n\nprocedure TwbValue.SetEditValue(const aValue: string);\nvar\n  OldValue, NewValue: Variant;\nbegin\n  if not wbEditAllowed then\n    raise Exception.Create(GetName + ' can not be edited.');\n\n  if (not Assigned(dcDataBasePtr) or not Assigned(dcDataEndPtr)) or (aValue <> GetEditValue) then begin\n    OldValue := GetNativeValue;\n    vbValueDef.EditValue[GetDataBasePtr, dcDataEndPtr, Self] := aValue;\n    if vIsFlags and (csInit in cntStates) then begin\n      Reset;\n      Init;\n    end;\n    NewValue := GetNativeValue;\n    DoAfterSet(OldValue, NewValue);\n    NotifyChanged(eContainer);\n    if vIsFlags and (csInit in cntStates) then begin\n      if vbValueDef.EditValue[GetDataBasePtr, dcDataEndPtr, Self] <> aValue then begin\n        Reset;\n        Init;\n      end;\n    end;\n  end;\nend;\n\nprocedure TwbValue.SetNativeValue(const aValue: Variant);\nvar\n  OldValue, NewValue: Variant;\nbegin\n  if not wbEditAllowed then\n    raise Exception.Create(GetName + ' can not be edited.');\n\n  OldValue := GetNativeValue;\n  vbValueDef.NativeValue[GetDataBasePtr, dcDataEndPtr, Self] := aValue;\n  if vIsFlags and (csInit in cntStates) then begin\n    Reset;\n    Init;\n  end;\n  NewValue := GetNativeValue;\n  DoAfterSet(OldValue, NewValue);\n  NotifyChanged(eContainer);\n  if vIsFlags and (csInit in cntStates) then begin\n    Reset;\n    Init;\n  end;\nend;\n\nvar\n  Files : array of IwbFile;\n  FilesMap: TStringList;\n\nprocedure wbFileForceClosed;\nvar\n  i: Integer;\nbegin\n  for i := Low(Files) to High(Files) do\n    (Files[i] as IwbFileInternal).ForceClosed;\n  Files := nil;\n  FilesMap.Clear;\nend;\n\nfunction wbExpandFileName(const aFileName: string): string;\nbegin\n  if ExtractFilePath(aFileName) = '' then\n    Result := wbDataPath + ExtractFileName(aFileName)\n  else\n    Result := aFileName;\nend;\n\nfunction wbFile(const aFileName: string; aLoadOrder: Integer = -1; aCompareTo: string = '';\n  IsTemporary: Boolean = False; aOnlyHeader: Boolean = False): IwbFile;\nvar\n  FileName: string;\n  i: Integer;\nbegin\n  FileName := wbExpandFileName(aFileName);\n  {if ExtractFilePath(aFileName) = '' then\n    FileName := ExpandFileName('.\\'+aFileName)\n  else\n    FileName := ExpandFileName(aFileName);}\n\n  if FilesMap.Find(FileName, i) then\n    Result := IwbFile(Pointer(FilesMap.Objects[i]))\n  else begin\n    if not wbIsPlugin(FileName) then\n      Result := TwbFileSource.Create(FileName, aLoadOrder, aCompareTo, aOnlyHeader, IsTemporary)\n    else\n      Result := TwbFile.Create(FileName, aLoadOrder, aCompareTo, aOnlyHeader, IsTemporary);\n    SetLength(Files, Succ(Length(Files)));\n    Files[High(Files)] := Result;\n    FilesMap.AddObject(FileName, Pointer(Result));\n  end;\nend;\n\nprocedure wbMastersForFile(const aFileName: string; aMasters: TStrings);\nvar\n  FileName : string;\n  i        : Integer;\n  _File    : IwbFileInternal;\nbegin\n  FileName := wbExpandFileName(aFileName);\n  {if ExtractFilePath(aFileName) = '' then\n    FileName := ExpandFileName('.\\'+aFileName)\n  else\n    FileName := ExpandFileName(aFileName);}\n\n  try\n    if FilesMap.Find(FileName, i) then\n      _File := IwbFile(Pointer(FilesMap.Objects[i])) as IwbFileInternal\n    else if not wbIsPlugin(FileName) then\n      _File := TwbFileSource.Create(FileName, -1, '', True)\n    else\n      _File := TwbFile.Create(FileName, -1, '', True);\n\n    _File.GetMasters(aMasters);\n  except\n    // File neither found nor replaced, ignore if in xDump\n    if not (wbToolMode in [tmDump, tmExport]) then Raise;\n  end;\nend;\n\nfunction wbNewFile(const aFileName: string; aLoadOrder: Integer): IwbFile;\nvar\n  FileName: string;\n  i: Integer;\nbegin\n  FileName := wbExpandFileName(aFileName);\n  {if ExtractFilePath(aFileName) = '' then\n    FileName := ExpandFileName('.\\'+aFileName)\n  else\n    FileName := ExpandFileName(aFileName);}\n\n  if FilesMap.Find(FileName, i) then\n    raise Exception.Create(FileName + ' exists already')\n  else begin\n    Result := TwbFile.CreateNew(FileName, aLoadOrder);\n    SetLength(Files, Succ(Length(Files)));\n    Files[High(Files)] := Result;\n    FilesMap.AddObject(FileName, Pointer(Result));\n  end;\nend;\n\nfunction wbFindWinningMainRecordByEditorID(const aSignature: TwbSignature; const aEditorID: string): IwbMainRecord;\nvar\n  i     : Integer;\n  Group : IwbGroupRecord;\nbegin\n  Result := nil;\n  for i := High(Files) downto Low(Files) do\n    if Supports(Files[i].GroupBySignature[aSignature], IwbGroupRecord, Group) then begin\n      Result := Group.MainRecordByEditorID[aEditorID];\n      if Assigned(Result) then begin\n        Result := Result.WinningOverride;\n        Exit;\n      end;\n    end;\nend;\n\nfunction wbFormListToArray(const aFormList: IwbMainRecord; const aSignatures: string): TDynMainRecords;\nvar\n  Container  : IwbContainerElementRef;\n  Signatures : TStringList;\n  i, j       : Integer;\n  MainRecord : IwbMainRecord;\nbegin\n  Result := nil;\n  if not Assigned(aFormList) or (aFormList.Signature <> 'FLST') then\n    Exit;\n  if not Supports(aFormList.ElementByName['wbFormListToArray FormIDs'], IwbContainerElementRef, Container) then\n    Exit;\n  if Container.ElementCount < 1 then\n    Exit;\n  Signatures := TStringList.Create;\n  try\n    Signatures.CommaText := aSignatures;\n    Signatures.Sorted := True;\n    for i := 0 to Pred(Container.ElementCount) do begin\n      if Supports(Container.Elements[i].LinksTo, IwbMainRecord, MainRecord) then\n        if Signatures.Find(MainRecord.Signature, j) then begin\n          SetLength(Result, Succ(Length(Result)));\n          Result[High(Result)] := MainRecord;\n        end;\n    end;\n  finally\n    Signatures.Free;\n  end;\nend;\n\n{ TwbFlag }\n\nconstructor TwbFlag.Create(const aContainer  : IwbContainer;\n                                 aBasePtr    : Pointer;\n                                 aEndPtr     : Pointer;\n                           const aIntegerDef : IwbIntegerDef;\n                           const aFlagsDef   : IwbFlagsDef;\n                                 aIndex      : Integer);\nbegin\n  fBasePtr    := aBasePtr;\n  fEndPtr     := aEndPtr;\n  fIntegerDef := aIntegerDef;\n  if not fIntegerDef.FormaterCanChange then\n    fFlagsDef := aFlagsDef;\n  fIndex      := aIndex;\n  inherited Create(aContainer);\n  SetSortOrder(aIndex);\n  SetMemoryOrder(aIndex);\nend;\n\nfunction TwbFlag.GetConflictPriority: TwbConflictPriority;\nvar\n  MainRecord: IwbMainRecord;\nbegin\n  if wbTranslationMode then\n    Result := cpIgnore\n  else if GetFlagsDef.FlagIgnoreConflict[fIndex] then\n    Result := cpIgnore\n  else if Assigned(fIntegerDef) then\n    Result := fIntegerDef.ConflictPriority[Self]\n  else\n    Result := cpNormal;\n\n  if Result = cpFormID then begin\n    Result := cpCritical;\n    MainRecord := GetContainingMainRecord;\n    if Assigned(MainRecord) and (MainRecord.Signature = 'GMST') then\n      Result := cpBenign;\n  end;\nend;\n\nfunction TwbFlag.GetDataSize: Integer;\nbegin\n  Result := 0;\nend;\n\nfunction TwbFlag.GetDef: IwbNamedDef;\nbegin\n  Result := GetFlagsDef.FlagDef[fIndex];\nend;\n\nfunction TwbFlag.GetDontShow: Boolean;\nbegin\n  Result := GetFlagsDef.FlagDontShow[Self, fIndex];\nend;\n\nfunction TwbFlag.GetEditValue: string;\nvar\n  s: string;\nbegin\n  s := GetContainer.EditValue;\n  if Length(s) >= Succ(fIndex) then\n    Result := s[Succ(fIndex)]\n  else\n    Result := '0';\nend;\n\nfunction TwbFlag.GetElementType: TwbElementType;\nbegin\n  Result := etFlag;\nend;\n\nfunction TwbFlag.GetFlagIndex: Integer;\nbegin\n  Result := fIndex;\nend;\n\nfunction TwbFlag.GetFlagsDef: IwbFlagsDef;\nbegin\n  if Assigned(fFlagsDef) then\n    Result := fFlagsDef\n  else\n    Result := fIntegerDef.Formater[IwbContainer(eContainer)] as IwbFlagsDef;\nend;\n\nfunction TwbFlag.GetIsEditable: Boolean;\nbegin\n  Result := wbIsInternalEdit or GetContainer.IsEditable;\nend;\n\nfunction TwbFlag.GetIsRemoveable: Boolean;\nbegin\n  Result := wbIsInternalEdit or GetContainer.IsEditable;\nend;\n\nfunction TwbFlag.GetName: string;\nbegin\n  Result := GetFlagsDef.Flags[fIndex];\nend;\n\nfunction TwbFlag.GetNativeValue: Variant;\nvar\n  s: string;\nbegin\n  s := GetContainer.EditValue;\n  if Length(s) >= Succ(fIndex) then\n    Result := s[Succ(fIndex)] = '1'\n  else\n    Result := False;\nend;\n\nfunction TwbFlag.GetSortKey(aExtended: Boolean): string;\n\n  procedure CheckFlagsChanged;\n  var\n    FlagsDef     : IwbFlagsDef;\n  begin\n    FlagsDef := GetFlagsDef.Root as IwbFlagsDef;\n    if FlagsDef.DefID <> fLastDefID then begin\n      Exclude(eStates, esExtendedSortKeyValid);\n      Exclude(eStates, esSortKeyValid);\n    end;\n  end;\n\nbegin\n  if not Assigned(fFlagsDef) then\n    CheckFlagsChanged;\n  Result := inherited GetSortKey(aExtended);\nend;\n\nfunction TwbFlag.GetSortKeyInternal(aExtended: Boolean): string;\nvar\n  s            : string;\n  FlagsDef     : IwbFlagsDef;\n  BaseFlagsDef : IwbFlagsDef;\nbegin\n  FlagsDef := GetFlagsDef.Root as IwbFlagsDef;\n  BaseFlagsDef := FlagsDef.BaseFlagsDef;\n\n  s := IntToHex64(BaseFlagsDef.DefID, 8);\n  Result := s + IntToHex64(fIndex, 2);\n  if not FlagsDef.Equals(BaseFlagsDef) then begin\n    s := FlagsDef.Flags[fIndex];\n    if not SameText(s, BaseFlagsDef.Flags[fIndex]) then\n      Result := Result + s;\n  end;\n  fLastDefID := FlagsDef.DefID;\nend;\n\nfunction TwbFlag.GetValue: string;\n//var\n//  i: Int64;\nvar\n  Def: IwbDef;\nbegin\n  if wbReportMode then begin\n    Def := GetValueDef;\n    if Assigned(Def) then\n      Def.Used;\n    Def := GetDef;\n    if Assigned(Def) then\n      Def.Used;\n  end;\n  Result := GetFlagsDef.Flags[fIndex];\n{\n  i := fIntegerDef.ToInt(fBasePtr, fEndPtr, Self);\n  if (i and (Int64(1) shl fIndex)) <> 0 then\n    Result := GetName\n  else\n    Result := '';\n}\nend;\n\nfunction TwbFlag.GetValueDef: IwbValueDef;\nbegin\n  Result := GetFlagsDef.FlagDef[fIndex];\nend;\n\nprocedure TwbFlag.InformStorage(var aBasePtr: Pointer; aEndPtr: Pointer);\nvar\n  Size: Cardinal;\nbegin\n  fBasePtr := aBasePtr;\n  Size := fIntegerDef.Size[aBasePtr, aEndPtr, GetContainer];\n  fEndPtr := Pointer( Cardinal(fBasePtr) + Size );\n  if Cardinal(fEndPtr) > Cardinal(aEndPtr) then\n    fEndPtr := aEndPtr;\nend;\n\nprocedure TwbFlag.InvalidateParentStorage;\nbegin\n  {not inherited}\nend;\n\nprocedure TwbFlag.Remove;\nbegin\n  SetEditValue('0');\nend;\n\nprocedure TwbFlag.SetEditValue(const aValue: string);\nvar\n  s: string;\n  c: Char;\nbegin\n  if not wbEditAllowed then\n    raise Exception.Create(GetName + ' can not be edited.');\n\n  if aValue = '1' then\n    c := '1'\n  else\n    c := '0';\n\n  s := GetContainer.EditValue;\n  if Length(s) >= Succ(fIndex) then\n    s[Succ(fIndex)] := c\n  else\n    s := s + StringOfChar('0', fIndex - Length(s) ) + c;\n  GetContainer.EditValue := s;\nend;\n\nprocedure TwbFlag.SetNativeValue(const aValue: Variant);\nvar\n  s: string;\n  c: Char;\nbegin\n  if not wbEditAllowed then\n    raise Exception.Create(GetName + ' can not be edited.');\n\n  if aValue = True then\n    c := '1'\n  else\n    c := '0';\n\n  s := GetContainer.EditValue;\n  if Length(s) >= Succ(fIndex) then\n    s[Succ(fIndex)] := c\n  else\n    s := s + StringOfChar('0', fIndex - Length(s) ) + c;\n  GetContainer.EditValue := s;\nend;\n\n{ TwbDataContainer }\n\nconstructor TwbDataContainer.Create(const aContainer: IwbContainer; var aBasePtr: Pointer; aEndPtr: Pointer; const aPrevMainRecord : IwbMainRecord);\nbegin\n  dcBasePtr := aBasePtr;\n  dcEndPtr := aEndPtr;\n  dcDataBasePtr := aBasePtr;\n  dcDataEndPtr := aEndPtr;\n  inherited Create(aContainer);\n  try\n    InitDataPtr;\n    aBasePtr := dcEndPtr;\n  except\n    if Assigned(aContainer) then\n      aContainer.RemoveElement(Self);\n    raise;\n  end;\nend;\n\nfunction TwbDataContainer.DoCheckSizeAfterWrite: Boolean;\nbegin\n  Result := False;\nend;\n\nfunction TwbDataContainer.GetConflictPriority: TwbConflictPriority;\nvar\n  Def        : IwbDef;\n  ValueDef   : IwbValueDef;\n  MainRecord : IwbMainRecord;\nbegin\n  Result := cpNormal;\n\n  Def := GetValueDef;\n\n  if not Assigned(Def) then\n    Def := GetDef;\n\n  if Supports(Def, IwbValueDef, ValueDef) then\n    Def := Resolve(ValueDef, GetDataBasePtr, GetDataEndPtr, Self);\n\n  if Assigned(Def) then\n    Result := Def.ConflictPriority[Self];\n\n  if wbTranslationMode then begin\n    if Result <> cpTranslate then\n      Result := cpIgnore\n    else\n      Result := cpNormal;\n  end else begin\n    if Result = cpTranslate then\n      Result := cpNormal;\n  end;\n\n  if Result = cpFormID then begin\n    Result := cpCritical;\n    MainRecord := GetContainingMainRecord;\n    if Assigned(MainRecord) and (MainRecord.Signature = 'GMST') then\n      Result := cpBenign;\n  end;\nend;\n\nfunction TwbDataContainer.GetDataBasePtr: Pointer;\nbegin\n  if (dcfStorageInvalid in dcFlags) then\n    UpdateStorageFromElements;\n  Result := dcDataBasePtr;\nend;\n\nfunction TwbDataContainer.GetDataEndPtr: Pointer;\nbegin\n  if (dcfStorageInvalid in dcFlags) then\n    UpdateStorageFromElements;\n  Result := dcDataEndPtr;\nend;\n\nfunction TwbDataContainer.GetDataSize: Integer;\nbegin\n  if (dcfStorageInvalid in dcFlags) or not Assigned(dcDataBasePtr) or not Assigned(dcDataEndPtr) then\n    Result := inherited GetDataSize + GetDataPrefixSize\n  else\n    Result := Cardinal( dcDataEndPtr ) - Cardinal( dcDataBasePtr );\nend;\n\nfunction TwbDataContainer.GetDontCompare: Boolean;\nbegin\n  Result := (dcfDontCompare in dcFlags);\nend;\n\nfunction TwbDataContainer.GetDontSave: Boolean;\nbegin\n  Result := (dcfDontSave in dcFlags);\nend;\n\nfunction TwbDataContainer.GetEditInfo: string;\nvar\n  ValueDef: IwbValueDef;\nbegin\n  Result := '';\n  if Supports(GetValueDef, IwbValueDef, ValueDef) then\n    Result := ValueDef.EditInfo[GetDataBasePtr, dcDataEndPtr, Self];\nend;\n\nfunction TwbDataContainer.GetEditType: TwbEditType;\nvar\n  ValueDef: IwbValueDef;\nbegin\n  Result := etDefault;\n  if Supports(GetValueDef, IwbValueDef, ValueDef) then\n    Result := ValueDef.EditType[GetDataBasePtr, dcDataEndPtr, Self];\nend;\n\nfunction TwbDataContainer.GetResolvedValueDef: IwbValueDef;\nbegin\n  Result := Resolve(GetValueDef, GetDataBasePtr, dcDataEndPtr, Self);\nend;\n\nfunction TwbDataContainer.GetDataPrefixSize: Integer;\nbegin\n  Result := 0;\nend;\n\nprocedure TwbDataContainer.InformStorage(var aBasePtr: Pointer; aEndPtr: Pointer);\nvar\n  SizeNeeded    : Cardinal;\n  SizeAvailable : Cardinal;\n  BasePtr       : Pointer;\nbegin\n  if [dcfDontMerge, dcfDontCompare] * dcFlags <> [] then\n    Exit;\n\n  if Length(dcDataStorage) <> 0 then\n    Assert(Length(dcDataStorage) = 0);\n  SizeNeeded := GetDataSize;\n  if SizeNeeded > 0 then begin\n    SizeAvailable := Cardinal( aEndPtr ) - Cardinal( aBasePtr );\n    if (SizeAvailable < SizeNeeded) then\n      Assert( SizeAvailable >= SizeNeeded );\n\n    BasePtr := aBasePtr;\n    Inc(PByte(aBasePtr), GetDataPrefixSize);\n    inherited;\n\n    if BasePtr = aBasePtr then begin\n      if not (dcfDontMerge in dcFlags) then\n        Inc(PByte(aBasePtr), SizeNeeded);\n    end else\n      if Cardinal(aBasePtr) - Cardinal(BasePtr) > SizeNeeded then // we overwrote something\n        Assert( Cardinal(aBasePtr) - Cardinal(BasePtr) = SizeNeeded)\n      else // Adjust size of data not initialized yet\n        aBasePtr := PByte(BasePtr) + SizeNeeded;\n\n    dcDataBasePtr := BasePtr;\n    dcDataEndPtr := aBasePtr;\n  end;\nend;\n\nprocedure TwbDataContainer.InvalidateStorage;\nbegin\n  Include(dcFlags, dcfStorageInvalid);\n  inherited;\nend;\n\nfunction TwbDataContainer.IsFlags: Boolean;\nbegin\n  Result := False;\nend;\n\nfunction TwbDataContainer.IsValidOffset(aBasePtr, aEndPtr: Pointer; anOffset: Integer): Boolean;\nbegin\n  Result := False;\n  if Cardinal(aBasePtr) >= Cardinal(dcBasePtr) then\n    if Cardinal(aBasePtr) < Cardinal(dcEndPtr) then\n      if Cardinal(aEndPtr) > Cardinal(dcBasePtr) then\n        if Cardinal(aEndPtr) <= Cardinal(dcEndPtr) then\n          if Cardinal(aBasePtr)+anOffset < Cardinal(dcEndPtr) then\n            Result := True;\nend;\n\nfunction TwbDataContainer.IsLocalOffset(anOffset: Integer): Boolean;\nbegin\n  if Cardinal(dcDataBasePtr)+anOffset < Cardinal(dcDataEndPtr) then\n    Result := True\n  else\n    Result := False;\nend;\n\nprocedure TwbDataContainer.MergeStorageInternal(var aBasePtr: Pointer; aEndPtr: Pointer);\nvar\n  SizeNeeded    : Cardinal;\n  SizeAvailable : Cardinal;\n  BasePtr       : Pointer;\n  PrefixSize   : Integer;\nbegin\n  if [dcfDontMerge, dcfDontCompare] * dcFlags <> [] then\n    Exit;\n\n  if (dcfStorageInvalid in dcFlags) then begin\n    BasePtr := aBasePtr;\n    PrefixSize := GetDataPrefixSize;\n    if (PrefixSize > 0) then begin\n      Move(dcDataBasePtr^, aBasePtr^, PrefixSize);\n      Inc(PByte(aBasePtr), PrefixSize);\n    end;\n    inherited;\n    dcDataBasePtr := BasePtr;\n    dcDataEndPtr := aBasePtr;\n  end else begin\n    SizeNeeded := Cardinal( dcDataEndPtr ) - Cardinal( dcDataBasePtr );\n    if SizeNeeded > 0 then begin\n      SizeAvailable := Cardinal( aEndPtr ) - Cardinal( aBasePtr );\n      if SizeAvailable < SizeNeeded then\n        Assert( SizeAvailable >= SizeNeeded );\n\n      Move(dcDataBasePtr^, aBasePtr^, SizeNeeded);\n\n      dcDataBasePtr := aBasePtr;\n      Inc(PByte(aBasePtr), SizeNeeded);\n      dcDataEndPtr := aBasePtr;\n\n      BasePtr := dcDataBasePtr;\n      Inc(PByte(BasePtr), GetDataPrefixSize);\n      inherited InformStorage(BasePtr, dcDataEndPtr);\n    end else begin\n      dcDataBasePtr := nil;\n      dcDataEndPtr := nil;\n    end;\n    dcDataStorage := nil;\n  end;\nend;\n\nprocedure TwbDataContainer.RequestStorageChange(var aBasePtr, aEndPtr: Pointer; aNewSize: Cardinal);\nvar\n  BasePtr   : Pointer;\n  OldSize   : Cardinal;\n  NeedsCopy : Boolean;\nbegin\n  if (dcfStorageInvalid in dcFlags) then\n    UpdateStorageFromElements;\n\n  SetModified(True);\n  InvalidateParentStorage;\n  if aNewSize = 0 then begin\n    dcDataStorage := nil;\n    dcDataBasePtr := @EmptyPtr;\n    dcDataEndPtr := @EmptyPtr;\n  end else if Cardinal(Length(dcDataStorage)) <> aNewSize then begin\n    OldSize := Cardinal( dcDataEndPtr ) - Cardinal( dcDataBasePtr );\n    NeedsCopy := (Length(dcDataStorage) = 0) and (OldSize > 0);\n    SetLength(dcDataStorage, aNewSize);\n    if NeedsCopy then\n      Move(dcDataBasePtr^, dcDataStorage[0], Min(OldSize, aNewSize));\n    dcDataBasePtr := @dcDataStorage[0];\n    dcDataEndPtr := Pointer( Cardinal(dcDataBasePtr) + aNewSize );\n\n    BasePtr := dcDataBasePtr;\n    Inc(PByte(BasePtr), GetDataPrefixSize);\n    inherited InformStorage(BasePtr, dcDataEndPtr);\n  end;\n  Exclude(dcFlags, dcfStorageInvalid);\n  aBasePtr := dcDataBasePtr;\n  aEndPtr := dcDataEndPtr;\nend;\n\nprocedure TwbDataContainer.SetContainer(const aContainer: IwbContainer);\nvar\n  DataContainer: IwbDataContainer;\nbegin\n  if not (dcfDontCompare in dcFlags) then\n    if Supports(aContainer, IwbDataContainer, DataContainer) and DataContainer.DontCompare then\n      Include(dcFlags, dcfDontCompare);\n  inherited;\nend;\n\nprocedure TwbDataContainer.SetDataSize(aSize: Integer);\nvar\n  BasePtr, EndPtr: Pointer;\nbegin\n  if aSize = GetDataSize then\n    Exit;\n\n  BasePtr := nil;\n  EndPtr := nil;\n  RequestStorageChange(BasePtr, EndPtr, aSize);\n  if csInit in cntStates then begin\n    Reset;\n    Init;\n  end;\nend;\n\nprocedure TwbDataContainer.SetModified(aValue: Boolean);\nbegin\n  inherited SetModified(aValue);\nend;\n\nprocedure TwbDataContainer.SetToDefaultInternal;\nvar\n  SelfRef            : IwbContainerElementRef;\n  ValueDef           : IwbValueDef;\n  OldValue, NewValue : Variant;\nbegin\n  SelfRef := Self as IwbContainerElementRef;\n  DoInit;\n\n  ValueDef := GetValueDef;\n  if Assigned(ValueDef) then begin\n    OldValue := GetNativeValue;\n    if ValueDef.SetToDefault(GetDataBasePtr, GetDataEndPtr, Self) then begin\n      NewValue := GetNativeValue;\n      DoAfterSet(OldValue, NewValue);\n      NotifyChanged(eContainer);\n\n      if IsFlags and (csInit in cntStates) then begin\n        Reset;\n        Init;\n      end;\n    end;\n  end;\n\n  inherited;\nend;\n\nprocedure TwbDataContainer.UpdateStorageFromElements;\nvar\n  PrefixSize            : Integer;\n  NewStorage            : TBytes;\n  BasePtr               : Pointer;\n  EndPtr                : Pointer;\n  SelfRef               : IwbContainerElementRef;\n  i                     : Integer;\n  DataContainerInternal : IwbDataContainerInternal;\nbegin\n  if not (dcfStorageInvalid in dcFlags) then\n    Exit;\n\n  SelfRef := Self as IwbContainerElementRef;\n\n  for i := Low(cntElements) to High(cntElements) do\n    if Supports(cntElements[i], IwbDataContainerInternal, DataContainerInternal) then\n      DataContainerInternal.UpdateStorageFromElements;\n\n  SetLength(NewStorage, inherited GetDataSize + GetDataPrefixSize);\n  if Length(NewStorage) > 0 then begin\n    BasePtr := @NewStorage[0];\n    EndPtr := Pointer( Cardinal(BasePtr) + Cardinal(Length(NewStorage)) );\n    PrefixSize := GetDataPrefixSize;\n    if (PrefixSize > 0) then\n      Move(dcDataBasePtr^, BasePtr^, PrefixSize);\n    Inc(PByte(BasePtr), PrefixSize);\n    inherited MergeStorageInternal(BasePtr, EndPtr);\n\n    dcDataStorage := NewStorage;\n    dcDataBasePtr := @NewStorage[0];\n    dcDataEndPtr := Pointer( Cardinal(dcDataBasePtr) + Cardinal(Length(dcDataStorage)) );\n    Assert(dcDataEndPtr = EndPtr);\n  end else begin\n    dcDataStorage := nil;\n    dcDataBasePtr := nil;\n    dcDataEndPtr := nil;\n  end;\n\n  Exclude(dcFlags, dcfStorageInvalid);\nend;\n\nprocedure TwbDataContainer.WriteToStreamInternal(aStream: TStream; aResetModified: Boolean);\nvar\n  OldPosition  : Int64;\n  Size         : Cardinal;\n  ExpectedSize : Cardinal;\nbegin\n  if [dcfDontSave, dcfDontCompare] * dcFlags <> [] then\n    Exit;\n\n  OldPosition := aStream.Position;\n  ExpectedSize := GetDataSize;\n\n  if (esModified in eStates) or wbTestWrite then begin\n    if not (dcfStorageInvalid in dcFlags) and Assigned(dcDataEndPtr) and Assigned(dcDataBasePtr) then\n      Size := Cardinal( dcDataEndPtr ) - Cardinal( dcDataBasePtr )\n    else\n      Size := 0;\n    if Size > 0 then begin\n      if Size <> ExpectedSize then\n        Assert(Size = ExpectedSize);\n      aStream.WriteBuffer(dcDataBasePtr^, Size);\n    end else begin\n      inherited WriteToStreamInternal(aStream, aResetModified);\n      if aStream.Position = OldPosition then begin\n        Size := GetDataSize;\n        if Size > 0 then\n          aStream.WriteBuffer(GetDataBasePtr^, Size);\n      end;\n    end;\n  end else begin\n    Size := ExpectedSize;\n    if Size > 0 then\n      aStream.WriteBuffer(GetDataBasePtr^, Size);\n  end;\n\n  if (aStream.Position - OldPosition) <> ExpectedSize then\n    if DoCheckSizeAfterWrite then\n      Assert(not DoCheckSizeAfterWrite);\n\n  Exclude(eStates, esUnsaved);\n  if aResetModified then begin\n    Exclude(eStates, esModified);\n    Exclude(eStates, esInternalModified);\n  end;\nend;\n\n{ TwbValueBase }\n\nprocedure TwbValueBase.BuildRef;\nvar\n  SelfRef: IwbElement;\nbegin\n  SelfRef := Self as IwbContainerElementRef;\n\n  inherited;\n  vbValueDef.BuildRef(GetDataBasePtr, dcDataEndPtr, Self);\nend;\n\nconstructor TwbValueBase.Create(const aContainer  : IwbContainer;\n                                  var aBasePtr    : Pointer;\n                                      aEndPtr     : Pointer;\n                                const aValueDef   : IwbValueDef;\n                                const aNameSuffix : string;\n                                      aDontCompare: Boolean);\nbegin\n  if aDontCompare then\n    Include(dcFlags, dcfDontCompare);\n  vbValueDef := aValueDef;\n  vbNameSuffix := aNameSuffix;\n  inherited Create(aContainer, aBasePtr, aEndPtr, nil);\nend;\n\nfunction TwbValueBase.CanContainFormIDs: Boolean;\nbegin\n  Result := vbValueDef.CanContainFormIDs;\nend;\n\nfunction TwbValueBase.CanElementReset: Boolean;\nbegin\n//  Result := inherited CanElementReset;\n  Result := eExternalRefs < 1;\nend;\n\nconstructor TwbValueBase.Create(const aContainer  : IwbContainer;\n                                const aValueDef   : IwbValueDef;\n                                const aSource     : IwbElement;\n                                const aOnlySK     : Boolean;\n                                const aNameSuffix : string);\nvar\n  BasePtr : Pointer;\n  EndPtr  : Pointer;\nbegin\n  BasePtr := nil;\n  Create(aContainer, BasePtr, nil, aValueDef, aNameSuffix);\n  if Assigned(aSource) then try\n    RequestStorageChange(BasePtr, EndPtr, GetDataSize);\n    SetToDefault;\n    Assign(Low(Integer), aSource, aOnlySK);\n    SetModified(True);\n  except\n    if Assigned(aContainer) then\n      aContainer.RemoveElement(Self);\n    raise;\n  end else begin\n    BasePtr := nil;\n    EndPtr := nil;\n    SetModified(True);\n    RequestStorageChange(BasePtr, EndPtr, GetDataSize);\n    SetToDefault;\n  end;\nend;\n\nfunction TwbValueBase.DoCheckSizeAfterWrite: Boolean;\nbegin\n  Result := True;\nend;\n\nfunction TwbValueBase.GetBaseName: string;\nbegin\n  Result := vbValueDef.Name;\nend;\n\nfunction TwbValueBase.GetCheck: string;\nvar\n  SelfRef : IwbContainerElementRef;\nbegin\n  SelfRef := Self as IwbContainerElementRef;\n  DoInit;\n  Result := vbValueDef.Check(GetDataBasePtr, dcDataEndPtr, Self);\nend;\n\nfunction TwbValueBase.GetDataSize: Integer;\nbegin\n  if not Assigned(dcDataBasePtr) and not (dcfStorageInvalid in dcFlags) then\n    Result := vbValueDef.DefaultSize[nil, nil, Self]\n  else\n    Result := inherited GetDataSize;\nend;\n\nfunction TwbValueBase.GetDef: IwbNamedDef;\nbegin\n  Result := vbValueDef;\nend;\n\nfunction TwbValueBase.GetDisplayName: string;\nvar\n  Resolved: IwbValueDef;\n  Container: IwbDataContainer;\nbegin\n  Resolved := Resolve(vbValueDef, GetDataBasePtr, GetDataEndPtr, Self);\n  if (not Assigned(Resolved)) or (Resolved <> vbValueDef) and (Resolved.DefType in dtNonValues) then\n    Result := vbValueDef.Name\n  else\n    Result := Resolved.Name;\n  if Assigned(Resolved) then\n  begin\n    if (Resolved.DefType in dtNonValues) and (wbDumpOffset=1) then // simply display starting offset.\n      Result := Result + ' {' + IntToHex64(Cardinal(GetDataBasePtr)-wbBaseOffset, 8) + '}';\n    // something for Dump: Displaying the size in {} and the array count in []\n    //  Triggers a lot of pre calculations\n    if (Resolved.DefType in dtNonValues) and (wbDumpOffset>2) then\n      Result := Result + ' {' + IntToHex64(Cardinal(GetDataEndPtr)-wbBaseOffset, 8) + '-' + IntToHex64(Cardinal(GetDataBasePtr)-wbBaseOffset, 8) +\n        ' = ' +IntToStr(Resolved.Size[GetDataBasePtr, GetDataEndPtr, Self]) + '}';\n    if (Resolved.DefType = dtArray) and (wbDumpOffset>1) and Supports(Self, IwbDataContainer, Container) then\n      Result := Result + ' [' + IntToStr(Container.GetElementCount) + ']';\n  end;\n  if vbNameSuffix <> '' then\n    Result := Result + ' ' + vbNameSuffix;\nend;\n\nfunction TwbValueBase.GetEditValue: string;\nvar\n  SelfRef : IwbContainerElementRef;\nbegin\n  SelfRef := Self as IwbContainerElementRef;\n  DoInit;\n  Result := vbValueDef.EditValue[GetDataBasePtr, dcDataEndPtr, Self]\nend;\n\nfunction TwbValueBase.GetIsEditable: Boolean;\nvar\n  SelfRef : IwbContainerElementRef;\nbegin\n  Result := wbIsInternalEdit;\n  if Result then\n    Exit;\n\n  SelfRef := Self as IwbContainerElementRef;\n\n  if Assigned(eContainer) and not IwbContainer(eContainer).IsElementEditable(SelfRef) then\n    Exit;\n\n  DoInit;\n  Result := vbValueDef.IsEditable[GetDataBasePtr, dcDataEndPtr, Self];\nend;\n\nfunction TwbValueBase.GetIsInSK(aIndex: Integer): Boolean;\nvar\n  SelfRef    : IwbContainerElementRef;\n  HasSortKey : IwbHasSortKeyDef;\nbegin\n  Result := False;\n\n  SelfRef := Self as IwbContainerElementRef;\n  DoInit;\n\n  if not Supports(vbValueDef, IwbHasSortKeyDef, HasSortKey) then\n    Exit;\n\n  Result := HasSortKey.IsInSK(aIndex);\nend;\n\nfunction TwbValueBase.GetLinksTo: IwbElement;\nvar\n  SelfRef: IwbContainerElementRef;\nbegin\n  Result := nil;\n  SelfRef := Self as IwbContainerElementRef;\n  DoInit;\n  if not Assigned(vbValueDef) then\n    Exit;\n  Result := vbValueDef.LinksTo[dcDataBasePtr, dcDataEndPtr, Self];\nend;\n\nfunction TwbValueBase.GetName: string;\nbegin\n  Result := vbValueDef.Name;\n  if vbNameSuffix <> '' then\n    Result := Result + ' ' + vbNameSuffix;\nend;\n\nfunction TwbValueBase.GetNativeValue: Variant;\nvar\n  SelfRef : IwbContainerElementRef;\nbegin\n  SelfRef := Self as IwbContainerElementRef;\n  DoInit;\n  Result := vbValueDef.NativeValue[GetDataBasePtr, dcDataEndPtr, Self]\nend;\n\nfunction TwbValueBase.GetSortKeyInternal(aExtended: Boolean): string;\nvar\n  SelfRef : IwbContainerElementRef;\nbegin\n  SelfRef := Self as IwbContainerElementRef;\n  if (dcfDontCompare in dcFlags) then\n    Result := ''\n  else begin\n    DoInit;\n    Result := vbValueDef.ToSortKey(GetDataBasePtr, dcDataEndPtr, Self, aExtended);\n  end;\nend;\n\nfunction TwbValueBase.GetValue: string;\nvar\n  SelfRef : IwbContainerElementRef;\nvar\n  Def: IwbDef;\nbegin\n  if wbReportMode then begin\n    Def := GetValueDef;\n    if Assigned(Def) then\n      Def.Used;\n    Def := GetDef;\n    if Assigned(Def) then\n      Def.Used;\n  end;\n\n  SelfRef := Self as IwbContainerElementRef;\n  DoInit;\n  Result := vbValueDef.ToString(GetDataBasePtr, dcDataEndPtr, Self);\nend;\n\nfunction TwbValueBase.GetValueDef: IwbValueDef;\n//var\n//  SelfRef: IwbContainerElementRef;\nbegin\n//  SelfRef := Self as IwbContainerElementRef;\n//  DoInit;\n\n  Result := vbValueDef;\nend;\n\nprocedure TwbValueBase.InitDataPtr;\nvar\n  Size : Integer;\nbegin\n  if (GetDataBasePtr <> nil) and (Cardinal(dcDataEndPtr)>=Cardinal(dcDataBasePtr)) then begin\n    Size := vbValueDef.Size[dcDataBasePtr, dcDataEndPtr, Self];\n    if Size < High(Integer) then begin\n      dcDataEndPtr := Pointer( Cardinal(dcDataBasePtr) + Cardinal(Size) );\n      if Cardinal(dcDataEndPtr) > Cardinal(dcEndPtr) then\n        dcDataEndPtr := dcEndPtr\n      else\n        dcEndPtr := dcDataEndPtr;\n    end;\n  end;\nend;\n\nprocedure TwbValueBase.SetEditValue(const aValue: string);\nvar\n  OldValue, NewValue: Variant;\nbegin\n  if not wbEditAllowed then\n    raise Exception.Create(GetName + ' can not be edited.');\n\n  if aValue <> GetEditValue then begin\n    OldValue := GetNativeValue;\n    vbValueDef.EditValue[GetDataBasePtr, dcDataEndPtr, Self] := aValue;\n    NewValue := GetNativeValue;\n    DoAfterSet(OldValue, NewValue);\n    NotifyChanged(eContainer);\n  end;\nend;\n\n\nprocedure TwbValueBase.SetNativeValue(const aValue: Variant);\nvar\n  OldValue, NewValue: Variant;\nbegin\n  if not wbEditAllowed then\n    raise Exception.Create(GetName + ' can not be edited.');\n\n  OldValue := GetNativeValue;\n  vbValueDef.NativeValue[GetDataBasePtr, dcDataEndPtr, Self] := aValue;\n  NewValue := GetNativeValue;\n  DoAfterSet(OldValue, NewValue);\n  NotifyChanged(eContainer);\nend;\n\nprocedure TwbValueBase.SetToDefaultInternal;\nvar\n  SelfRef: IwbContainerElementRef;\n  BasePtr, EndPtr: Pointer;\nbegin\n  SelfRef := Self as IwbContainerElementRef;\n\n  if csInit in cntStates then\n    DoReset(True);\n  BasePtr := nil;\n  EndPtr := nil;\n  dcDataBasePtr := nil;\n  dcDataEndPtr := nil;\n  dcDataStorage := nil;\n  DoInit;\n  RequestStorageChange(BasePtr, EndPtr, vbValueDef.DefaultSize[nil, nil, Self]);\n  inherited;\nend;\n\n{ TwbRecordHeaderStruct }\n\nfunction TwbRecordHeaderStruct.AddIfMissingInternal(const aElement      : IwbElement;\n                                                  aAsNew        : Boolean;\n                                                  aDeepCopy     : Boolean;\n                                            const aPrefixRemove : string;\n                                            const aPrefix       : string;\n                                            const aSuffix       : string)\n                                                                : IwbElement;\nvar\n  StructDef : IwbStructDef;\n  SelfRef   : IwbContainerElementRef;\nbegin\n  Result := nil;\n\n  if not wbEditAllowed then\n    raise Exception.Create(GetName + ' can not be assigned.');\n\n  SelfRef := Self as IwbContainerElementRef;\n  DoInit;\n\n  if not Supports(GetDef, IwbStructDef, StructDef) then\n    Exit;\n\n  Assert(aElement.SortOrder >= 0);\n  Assert(aElement.SortOrder < StructDef.MemberCount);\n  Assert(Assigned(aElement.Def));\n  Assert(aElement.Def.Equals(StructDef.Members[aElement.SortOrder]));\n\n  Result := GetElementBySortOrder(aElement.SortOrder + GetAdditionalElementCount);\n  Assert(Assigned(Result));\n  Result.Assign(Low(Integer), aElement, not aDeepCopy);\nend;\n\nprocedure TwbRecordHeaderStruct.BuildRef;\nbegin\nend;\n\nfunction TwbRecordHeaderStruct.CanContainFormIDs: Boolean;\nbegin\n  Result := False;\nend;\n\nfunction TwbRecordHeaderStruct.CompareExchangeFormID(aOldFormID, aNewFormID: Cardinal): Boolean;\nbegin\n  Result := False;\nend;\n\nprocedure TwbRecordHeaderStruct.ElementChanged(const aElement: IwbElement; aContainer: Pointer);\nvar\n  MainRecordInternal       : IwbMainRecordInternal;\n  DataContainer            : IwbDataContainer;\n  Flags                    : TwbMainRecordStructFlags;\n  p                        : Pointer;\n\n  ToggleDeleted            : Boolean;\n  TogglePersistent         : Boolean;\n  ToggleVisibleWhenDistant : Boolean;\nbegin\n\n  ToggleDeleted := False;\n  TogglePersistent := False;\n  ToggleVisibleWhenDistant := False;\n\n  if Supports(IInterface(eContainer) , IwbMainRecordInternal, MainRecordInternal) then begin\n    if SameText(aElement.Def.Name, 'Record Flags') then begin\n      if Supports(aElement, IwbDataContainer, DataContainer) then begin\n        Flags._Flags := PCardinal(DataContainer.DataBasePtr)^;\n        UpdateStorageFromElements;\n        dcDataStorage := nil;\n        Exclude(dcFlags, dcfStorageInvalid);\n        MainRecordInternal.MakeHeaderWriteable;\n\n        if Flags.IsESM then\n          if MainRecordInternal.Signature <> wbHeaderSignature then\n            Flags.SetESM(False);\n\n        if Flags.IsDeleted <> MainRecordInternal.mrStruct.mrsFlags.IsDeleted then begin\n          Flags.SetDeleted(MainRecordInternal.mrStruct.mrsFlags.IsDeleted);\n          ToggleDeleted := True;\n        end;\n\n        if Flags.IsPersistent <> MainRecordInternal.mrStruct.mrsFlags.IsPersistent then begin\n          Flags.SetPersistent(MainRecordInternal.mrStruct.mrsFlags.IsPersistent);\n          TogglePersistent := True;\n        end;\n\n        if Flags.IsVisibleWhenDistant <> MainRecordInternal.mrStruct.mrsFlags.IsVisibleWhenDistant then begin\n          Flags.SetVisibleWhenDistant(MainRecordInternal.mrStruct.mrsFlags.IsVisibleWhenDistant);\n          ToggleVisibleWhenDistant := True;\n        end;\n\n        MainRecordInternal.mrStruct.mrsFlags := Flags;\n      end;\n    end;\n    p := MainRecordInternal.mrStruct;\n    InformStorage(p, Pointer(Cardinal(p) + wbSizeOfMainRecordStruct ));\n\n    with MainRecordInternal do begin\n      if ToggleDeleted then\n        IsDeleted := not IsDeleted;\n\n      if not IsDeleted then begin\n        if TogglePersistent then\n          IsPersistent := not IsPersistent;\n        if ToggleVisibleWhenDistant then\n          IsVisibleWhenDistant := not IsVisibleWhenDistant;\n      end;\n    end;\n  end;\n\n  inherited;\nend;\n\nfunction TwbRecordHeaderStruct.GetIsEditable: Boolean;\nbegin\n  Result := wbIsInternalEdit;\nend;\n\nfunction TwbRecordHeaderStruct.IsElementEditable(const aElement: IwbElement): Boolean;\nbegin\n  Result := Assigned(aElement) and Assigned(aElement.ValueDef) and\n    SameText(aElement.ValueDef.Name, 'Record Flags');\n  if Result and Assigned(eContainer) then\n    Result := IwbContainer(eContainer).IsElementEditable(Self);\nend;\n\n{ TwbStringListTerminator }\n\nfunction TwbStringListTerminator.AssignInternal(aIndex: Integer; const aElement: IwbElement; aOnlySK: Boolean): IwbElement;\nbegin\n  Result := nil;\nend;\n\nfunction TwbStringListTerminator.CanAssignInternal(aIndex: Integer; const aElement: IwbElement; aCheckDontShow: Boolean): Boolean;\nbegin\n  Result := False;\n  if Assigned(eContainer) then\n    if not IwbContainer(eContainer).IsElementEditable(Self) then\n      Exit;\n\n  Result := Supports(aElement, IwbStringListTerminator);\nend;\n\nfunction TwbStringListTerminator.GetConflictPriority: TwbConflictPriority;\nbegin\n  Result := cpIgnore;\nend;\n\nfunction TwbStringListTerminator.GetDataSize: Integer;\nbegin\n  Result := 1;\nend;\n\nfunction TwbStringListTerminator.GetElementType: TwbElementType;\nbegin\n  Result := etStringListTerminator;\nend;\n\nfunction TwbStringListTerminator.GetName: string;\nbegin\n  Result := 'Terminator';\nend;\n\nfunction TwbStringListTerminator.GetSortKeyInternal(aExtended: Boolean): string;\nbegin\n  Result := #255;\nend;\n\nprocedure TwbStringListTerminator.InformStorage(var aBasePtr: Pointer; aEndPtr: Pointer);\nbegin\n  Assert( Cardinal(aBasePtr) < Cardinal(aEndPtr));\n  Inc(PByte(aBasePtr));\nend;\n\nprocedure TwbStringListTerminator.MergeStorageInternal(var aBasePtr: Pointer; aEndPtr: Pointer);\nbegin\n  Assert( Cardinal(aBasePtr) < Cardinal(aEndPtr));\n  PAnsiChar(aBasePtr)^ := #0;\n  Inc(PByte(aBasePtr));\nend;\n\nprocedure TwbStringListTerminator.SetEditValue(const aValue: string);\nbegin\nend;\n\nprocedure TwbStringListTerminator.SetNativeValue(const aValue: Variant);\nbegin\nend;\n\nprocedure TwbStringListTerminator.WriteToStreamInternal(aStream: TStream; aResetModified: Boolean);\nconst\n  NullChar : AnsiChar = #0;\nbegin\n  aStream.Write(NullChar, 1);\n  Exclude(eStates, esUnsaved);\n  if aResetModified then begin\n    Exclude(eStates, esModified);\n    Exclude(eStates, esInternalModified);\n  end;\nend;\n\nprocedure WriteSubRecordOrderList;\nvar\n  i: Integer;\nbegin\n  if not wbReportMode then\n    Exit;\n\n  SubRecordOrderList.Sorted := False;\n\n  for i := 0 to Pred(SubRecordOrderList.Count) do\n    SubRecordOrderList[i] := SubRecordOrderList[i] + ' (' + IntToStr(Integer(SubRecordOrderList.Objects[i]) )+ ')';\n\n  SubRecordOrderList.SaveToFile('SubRecordOrderList.txt');\nend;\n\nvar\n  wbContainedInDef : array[0..10] of IwbIntegerDef;\n\n{ TwbContainedInElement }\n\nprocedure TwbContainedInElement.BuildRef;\nbegin\nend;\n\nfunction TwbContainedInElement.CanContainFormIDs: Boolean;\nbegin\n  Result := False;\nend;\n\nfunction TwbContainedInElement.CompareExchangeFormID(aOldFormID, aNewFormID: Cardinal): Boolean;\nbegin\n  Result := False;\nend;\n\nprocedure TwbContainedInElement.ContainerChanged;\nvar\n  MainRecord     : IwbMainRecord;\n  GroupRecord    : IwbGroupRecord;\n  Grp            : TwbGroupTypes;\nbegin\n  if cieLockCount > 0 then\n    Exit;\n\n  if not Supports(GetContainer, IwbMainRecord, MainRecord) then\n    Exit;\n  if not Supports(MainRecord.Container, IwbGroupRecord, GroupRecord) then\n    Exit;\n  if GroupRecord.GroupType = 5 then\n    if not Supports(GroupRecord.Container, IwbGroupRecord, GroupRecord) then\n      Exit;\n  if GroupRecord.GroupType = 4 then\n    if not Supports(GroupRecord.Container, IwbGroupRecord, GroupRecord) then\n      Exit;\n\n  if wbVWDAsQuestChildren then Grp := [8..9] else Grp := [8..10];\n  if GroupRecord.GroupType in Grp then\n    if not Supports(GroupRecord.Container, IwbGroupRecord, GroupRecord) then\n      Exit;\n\n  if wbVWDAsQuestChildren then Grp := [1, 6, 7, 10] else Grp := [1, 6, 7];\n  if not (GroupRecord.GroupType in Grp) then\n    Exit;\n\n  PCardinal(GetDataBasePtr)^ := GroupRecord.GroupLabel;\n  Exclude(eStates, esSortKeyValid);\n  Exclude(eStates, esExtendedSortKeyValid);\n  eSortKey := '';\n  eExtendedSortKey := '';\nend;\n\nconstructor TwbContainedInElement.Create(const aMainRecord: IwbMainRecord);\nvar\n  BasePtr        : Pointer;\n  EndPtr         : Pointer;\n  GroupRecord    : IwbGroupRecord;\n  Grp            : TwbGroupTypes;\nbegin\n  // MainRecord must be in a group\n  if not Supports(aMainRecord.Container, IwbGroupRecord, GroupRecord) then\n    Assert(False);\n  // if that group is Exterior Sub-Block, then it must be in a group too, get it\n  if GroupRecord.GroupType = 5 then\n    if not Supports(GroupRecord.Container, IwbGroupRecord, GroupRecord) then\n      Assert(False);\n  // if that group is Exterior Block, then it must be in a group too, get it\n  if GroupRecord.GroupType = 4 then\n    if not Supports(GroupRecord.Container, IwbGroupRecord, GroupRecord) then\n      Assert(False);\n  // if group is persistent, temporary or vwd cell children, it should be in a group too\n  // if vwd is treated as quest children, then exclude it from check\n  if wbVWDAsQuestChildren then Grp := [8..9] else Grp := [8..10];\n  if GroupRecord.GroupType in Grp then\n    if not Supports(GroupRecord.Container, IwbGroupRecord, GroupRecord) then\n      Assert(False);\n\n  // the final list of parent groups, mainrecords in those will have ContainedIn element\n  if wbVWDAsQuestChildren then Grp := [1, 6, 7, 10] else Grp := [1, 6, 7];\n  Assert(GroupRecord.GroupType in Grp);\n\n  Include(dcFlags, dcfDontMerge);\n  Include(dcFlags, dcfDontSave);\n\n  BasePtr := nil;\n  EndPtr := nil;\n  inherited Create(aMainRecord, BasePtr, EndPtr, wbContainedInDef[GroupRecord.GroupType], '', False);\n\n  SetSortOrder(-2);\n\n  BasePtr := nil;\n  EndPtr := nil;\n\n  RequestStorageChange(BasePtr, EndPtr, GetDataSize);\n  Assert(Assigned(BasePtr));\n\n  PCardinal(BasePtr)^ := GroupRecord.GroupLabel;\nend;\n\nprocedure TwbContainedInElement.DoAfterSet(const aOldValue, aNewValue: Variant);\nvar\n  OldFormID   : Cardinal;\n  NewFormID   : Cardinal;\n  _File       : IwbFile;\n  MainRecord  : IwbMainRecord;\n  NewOwner    : IwbMainRecord;\n  GroupRecord : IwbGroupRecord;\n  OldGroup    : IwbGroupRecord;\n\n  Group1       : IwbGroupRecord;\n  Group2       : IwbGroupRecord;\n  Group3       : IwbGroupRecord;\n  CorrectGroup : Integer;\n  i            : Integer;\nbegin\n  Inc(cieLockCount);\n  try\n    inherited;\n    if aOldValue <> aNewValue then begin\n      OldFormID := aOldValue;\n      NewFormID := aNewValue;\n      _File := GetFile;\n      MainRecord := GetContainer as IwbMainRecord;\n      OldGroup := MainRecord.Container as IwbGroupRecord;\n      NewOwner := _File.RecordByFormID[NewFormID, False];\n      if not Assigned(NewOwner) then begin\n        if Assigned(dcDataBasePtr) then\n          PCardinal(dcDataBasePtr)^ := OldFormID;\n        Exit;\n      end;\n      if not _File.Equals(NewOwner._File) then\n        NewOwner := wbCopyElementToFile(NewOwner, _File, False, True, '', '', '') as IwbMainRecord;\n      GroupRecord := NewOwner.EnsureChildGroup;\n\n      case GroupRecord.GroupType of\n        1: begin\n          Assert(OldGroup.GroupType in [1, 5]);\n          Group1 := OldGroup;\n          Group2 := nil;\n          Group3 := nil;\n          if OldGroup.GroupType = 5 then begin\n            if not Supports(Group1.Container, IwbGroupRecord, Group2) then\n              Assert(False);\n            Assert(Group2.GroupType = 4);\n\n            Group3 := nil;\n            for i := 0 to Pred(GroupRecord.ElementCount) do\n              if Supports(GroupRecord.Elements[i], IwbGroupRecord, Group3) then\n                if (Group3.GroupType = 4) and (Group3.GroupLabel = Group2.GroupLabel) then\n                  Break\n                else\n                  Group3 := nil;\n            if not Assigned(Group3) then\n              Group3 := TwbGroupRecord.Create(GroupRecord, 4, Group2.GroupLabel);\n            GroupRecord := Group3;\n\n            Group3 := nil;\n            for i := 0 to Pred(GroupRecord.ElementCount) do\n              if Supports(GroupRecord.Elements[i], IwbGroupRecord, Group3) then\n                if (Group3.GroupType = 5) and (Group3.GroupLabel = Group1.GroupLabel) then\n                  Break\n                else\n                  Group3 := nil;\n            if not Assigned(Group3) then\n              Group3 := TwbGroupRecord.Create(GroupRecord, 5, Group1.GroupLabel);\n            GroupRecord := Group3;\n\n            if not Supports(Group2.Container, IwbGroupRecord, Group3) then\n              Assert(False);\n            Assert(Group3.GroupType = 1);\n          end;\n\n          Group1.RemoveElement(MainRecord);\n          if Group1.ElementCount = 0 then begin\n            (Group1 as IwbGroupRecordInternal).SetModified(True);\n            Group1.Remove;\n            if Assigned(Group2) then\n              if Group2.ElementCount = 0 then begin\n               (Group2 as IwbGroupRecordInternal).SetModified(True);\n                Group2.Remove;\n                if Assigned(Group3) then\n                  if Group3.ElementCount = 0 then begin\n                    (Group3 as IwbGroupRecordInternal).SetModified(True);\n                    Group3.Remove;\n                  end else\n                    (Group3 as IwbGroupRecordInternal).SetModified(True);\n              end else\n                (Group2 as IwbGroupRecordInternal).SetModified(True);\n          end else\n            (Group1 as IwbGroupRecordInternal).SetModified(True);\n\n          GroupRecord.AddElement(MainRecord);\n          (GroupRecord as IwbGroupRecordInternal).SetModified(True);\n          (GroupRecord as IwbGroupRecordInternal).Sort;\n        end;\n        6: begin\n             if MainRecord.IsPersistent then\n               CorrectGroup := 8\n             else if MainRecord.IsVisibleWhenDistant and not wbVWDInTemporary then\n               CorrectGroup := 10\n             else\n               CorrectGroup := 9;\n\n             Group3 := nil;\n             for i := 0 to Pred(GroupRecord.ElementCount) do\n               if Supports(GroupRecord.Elements[i], IwbGroupRecord, Group3) then\n                 if Group3.GroupType = CorrectGroup then\n                   Break\n                 else\n                   Group3 := nil;\n\n             if not Assigned(Group3) then\n               Group3 := TwbGroupRecord.Create(GroupRecord, CorrectGroup, GroupRecord.ChildrenOf);\n\n             OldGroup.RemoveElement(MainRecord);\n             if OldGroup.ElementCount = 0 then\n               OldGroup.Remove\n             else\n               (OldGroup as IwbGroupRecordInternal).SetModified(True);\n             Group3.AddElement(MainRecord);\n             (Group3 as IwbGroupRecordInternal).SetModified(True);\n             (Group3 as IwbGroupRecordInternal).Sort;\n        end;\n        7: begin\n             OldGroup.RemoveElement(MainRecord);\n             if OldGroup.ElementCount = 0 then\n               OldGroup.Remove\n             else\n               (OldGroup as IwbGroupRecordInternal).SetModified(True);\n             GroupRecord.AddElement(MainRecord);\n             (GroupRecord as IwbGroupRecordInternal).SetModified(True);\n             (GroupRecord as IwbGroupRecordInternal).Sort;\n          end;\n      else\n        Assert(False);\n      end;\n\n    end;\n  finally\n    Dec(cieLockCount);\n  end;\n  ContainerChanged;\nend;\n\nprocedure TwbContainedInElement.ElementChanged(const aElement: IwbElement; aContainer: Pointer);\nbegin\nend;\n\nprocedure TwbContainedInElement.InvalidateParentStorage;\nbegin\nend;\n\nfunction TwbContainedInElement.IsElementEditable(const aElement: IwbElement): Boolean;\nbegin\n  Result := False;\nend;\n\nprocedure TwbContainedInElement.SetModified(aValue: Boolean);\nbegin\n  if not aValue then\n    inherited\n  else begin\n    Exclude(eStates, esSortKeyValid);\n    Exclude(eStates, esExtendedSortKeyValid);\n    eSortKey := '';\n  end;\nend;\n\n{ TwbMainRecordEntryHeader }\n\nprocedure TwbMainRecordEntryHeader.BeginUse;\nbegin\n  Assert(not mrehInUse);\n  mrehInUse := True;\n\n  Inc(mrehGeneration);\n  mrehHead := nil;\n  mrehTail := nil;\n  mrehCount := 0;\nend;\n\nprocedure TwbMainRecordEntryHeader.EndUse;\nbegin\n  Assert(mrehInUse);\n  mrehInUse := False;\n\n  Inc(mrehGeneration);\n  mrehHead := nil;\n  mrehTail := nil;\n  mrehCount := 0;\nend;\n\nconst\n  WRLD : TwbSignature = 'WRLD';\n  CELL : TwbSignature = 'CELL';\n  DIAL : TwbSignature = 'DIAL';\n  QUST : TwbSignature = 'QUST';\n\n{ TwbFileSource }\n\nconstructor TwbFileSource.CreateNew(const aFileName: string; aLoadOrder: Integer);\nbegin\n  Include(flStates, fsIsNew);\n  flLoadOrder := aLoadOrder;\n  flFileName := aFileName;\nend;\n\nprocedure TwbFileSource.GetMasters(aMasters: TStrings);\nvar\n  Header      : IwbFileHeader;\n  MasterFiles : IwbContainerElementRef;\n  fPath       : String;\n  i           : Integer;\n  modOffset   : Cardinal;\n  modPtr      : Pointer;\n  mods        : TwbArray;\nbegin\n  if (GetElementCount <> 1) or not Supports(GetElement(0), IwbFileHeader, Header) then\n    raise Exception.CreateFmt('Unexpected error reading file \"%s\"', [flFileName]);\n\n  if Header.FileMagic <> wbFileMagic then\n    raise Exception.CreateFmt('Expected File Magic %s, found %s in file \"%s\"',\n      [wbFileMagic, String(Header.FileMagic), flFileName]);\n\n  if Pos('Absolute:', wbFilePlugins)=1 then begin\n    modOffset := Cardinal(flView)+StrToInt(Copy(wbFilePlugins, 10, Length(wbFilePlugins)));\n    modPtr := Pointer(modOffset);\n    mods := TwbArray.Create(nil, modPtr, flEndPtr, wbArray('Modules', wbLenString('PluginName', 2), -4), '', False);\n    Supports(mods, IwbContainerElementRef, MasterFiles);\n  end else\n    MasterFiles := Header.ElementByName[wbFilePlugins] as IwbContainerElementRef;\n\n  if Assigned(MasterFiles) then\n    for i := 0 to Pred(MasterFiles.ElementCount) do begin\n      fPath := wbDataPath + MasterFiles[i].Value;\n      if FileExists(fPath) then\n        aMasters.Add(MasterFiles[i].Value)\n    end;\n\nend;\n\nfunction CreateTemporaryCopy(FileName, CompareFile: String): String;\nvar\n  s : String;\n  i : Integer;\n\nbegin\n  if not SameText(ExtractFilePath(CompareFile), wbDataPath) then begin\n    s := wbDataPath + ExtractFileName(CompareFile);\n    if FileExists(s) then // Finds a unique name\n      for i := 0 to 255 do begin\n        s := wbDataPath + ExtractFileName(CompareFile) + IntToHex(i, 3);\n        if not FileExists(s) then Break;\n      end;\n    if FileExists(s) then begin\n      wbProgressCallback('Could not copy '+FileName+' into '+wbDataPath);\n      Exit;\n    end;\n    CompareFile := s;\n    CopyFile(PChar(FileName), PChar(CompareFile), false);\n  end;\n  Result := CompareFile;\nend;\n\nfunction SelectTemporaryCopy(FileName, CompareFile: String): String;\nvar\n  s : String;\n  i : Integer;\n\nbegin\n  if not SameText(ExtractFilePath(CompareFile), wbDataPath) then begin\n    for i := 0 to 255 do begin\n      s := wbDataPath + ExtractFileName(CompareFile) + IntToHex(i, 3);\n      if FileExists(s) then Break;\n    end;\n    if not FileExists(s) then\n      s := wbDataPath + CompareFile + IntToHex(0, 3);\n    CompareFile := s;\n    if not FileExists(CompareFile) then\n      CopyFile(PChar(FileName), PChar(CompareFile), false);\n  end;\n  Result := CompareFile;\nend;\n\nprocedure TwbFileSource.Scan;\nvar\n  CurrentPtr  : Pointer;\n  Header      : IwbFileHeader;\n  MasterFiles : IwbContainerElementRef;\n  i           : Integer;\n  ExtractInfo : TByteSet;\n  Element     : IwbElement;\n  Container   : IwbContainer;\n  SelfRef     : IwbContainerElementRef;\n  fPath       : String;\n  modOffset   : Cardinal;\n  modPtr      : Pointer;\n  mods        : TwbArray;\n\nbegin\n  SelfRef := Self as IwbContainerElementRef;\n  flProgress('Start processing');\n\n  wbBaseOffset := Cardinal(flView);\n\n  CurrentPtr := flView;\n  TwbFileHeader.Create(Self, CurrentPtr, flEndPtr, wbFileHeader, '', False);\n\n  if (GetElementCount <> 1) or not Supports(GetElement(0), IwbFileHeader, Header) then\n    raise Exception.CreateFmt('Unexpected error reading file \"%s\"', [flFileName]);\n\n  if Header.FileMagic <> wbFileMagic then\n    raise Exception.CreateFmt('Expected header Magic %s, found %s in file \"%s\"',\n      [wbFileMagic, String(Header.FileMagic), flFileName]);\n\n  if fsOnlyHeader in flStates then\n    Exit;\n\n  if Pos('Absolute:', wbFilePlugins)=1 then begin\n    modOffset := Cardinal(flView)+StrToInt(Copy(wbFilePlugins, 10, Length(wbFilePlugins)));\n    modPtr := Pointer(modOffset);\n    mods := TwbArray.Create(nil, modPtr, flEndPtr, wbArray('Modules', wbLenString('PluginName', 2), -4), '', False);\n    Supports(mods, IwbContainerElementRef, MasterFiles);\n  end else\n    MasterFiles := Header.ElementByName[wbFilePlugins] as IwbContainerElementRef;\n\n  if Assigned(MasterFiles) then\n    for i := 0 to Pred(MasterFiles.ElementCount) do begin\n      fPath := wbDataPath + MasterFiles[i].Value;\n      if FileExists(fPath) then\n        AddMaster(fPath)\n      else if wbUseFalsePlugins then begin\n        fPath := wbDataPath + wbAppName + TheEmptyPlugin; // place holder to keep save indexes\n        if not FileExists(fPath) then\n          fPath := ExtractFilePath(wbProgramPath) + wbAppName + TheEmptyPlugin; // place holder to keep save indexes\n        if FileExists(fPath) then\n          AddMaster(SelectTemporaryCopy(fPath, MasterFiles[i].Value), True);\n      end;\n    end;\n\n  if flCompareTo <> '' then\n    AddMaster(flCompareTo);\n\n  if Assigned(wbExtractInfo) then\n    ExtractInfo := wbExtractInfo^\n  else\n    ExtractInfo := [];\n\n  for i := 0 to Pred(wbFileChapters.MemberCount) do begin\n    case wbFileChapters.Members[i].DefType of\n      dtArray: Element := TwbArray.Create(Self, currentPtr, flEndPtr, wbFileChapters.Members[i], '');\n      dtStruct: Element := TwbStruct.Create(Self, currentPtr, flEndPtr, wbFileChapters.Members[i], '');\n      dtStructChapter: Element := TwbChapter.Create(Self, currentPtr, flEndPtr, wbFileChapters.Members[i], '');\n      dtUnion: Element := TwbUnion.Create(Self, currentPtr, flEndPtr, wbFileChapters.Members[i], '');\n    else\n      Element := TwbValue.Create(Self, currentPtr, flEndPtr, wbFileChapters.Members[i], '');\n    end;\n    if (i in ExtractInfo) and Supports(Element, IwbContainer, Container) then\n      with Element as TwbContainer do DoInit;\n  end;\n\n  for i := 0 to Pred(GetElementCount) do\n    GetElement(i).SortOrder := i;\n\n  flProgress('Processing completed');\n  flLoadFinished := True;\nend;\n\n{ TwbFileHeader }\n\nfunction TwbFileHeader.GetFileMagic: TwbFileMagic;\nvar\n  Element : IwbElement;\n  Container : IwbContainer;\nbegin\n  Result := '';\n  if not Supports(Self, IwbContainer, Container) or (Container.ElementCount < 1) then Exit;\n  Element := Container.Elements[0];\n  if Assigned(Element) then\n    Result := Element.NativeValue;\nend;\n\n{ TwbChapter }\n\nconstructor TwbChapter.Create(const aContainer  : IwbContainer;\n                              const aValueDef   : IwbValueDef;\n                              const aSource     : IwbElement;\n                              const aOnlySK     : Boolean;\n                              const aNameSuffix : string);\nvar\n  Dummy : Integer;\nbegin\n  if Assigned(aValueDef) then\n    Assert(Supports(aValueDef, IwbStructCDef));\n  inherited;\n  cChapterSkipped := cChapterSkipped or ChaptersToSkip.Find(aValueDef.Name, Dummy);\nend;\n\nfunction TwbChapter.GetChapterName: String;\nvar\n  Struct : IwbStructCDef;\nbegin\n  if Assigned(vbValueDef) and Supports(vbValueDef, IwbStructCDef, Struct) then\n    Result := Struct.GetChapterName(dcBasePtr, dcEndPtr, Self)\n  else\n    Result := Struct.GetChapterTypeName(dcBasePtr, dcEndPtr, Self);\nend;\n\nfunction TwbChapter.GetChapterType: Integer;\nvar\n  Struct : IwbStructCDef;\nbegin\n  Result := -1;\n  if Assigned(vbValueDef) and Supports(vbValueDef, IwbStructCDef, Struct) then\n    Result := Struct.GetChapterType(dcBasePtr, dcEndPtr, Self);\nend;\n\nfunction TwbChapter.GetChapterTypeName: String;\nvar\n  Struct : IwbStructCDef;\nbegin\n  if Assigned(vbValueDef) and Supports(vbValueDef, IwbStructCDef, Struct) then\n    Result := Struct.GetChapterTypeName(dcBasePtr, dcEndPtr, Self)\n  else\n    Result := IntToStr(Struct.GetChapterType(dcBasePtr, dcEndPtr, Self));\nend;\n\nfunction TwbChapter.GetElementType: TwbElementType;\nbegin\n  Result := etStructChapter;\nend;\n\nfunction TwbChapter.GetSkipped: Boolean;\nbegin\n  Result := cChapterSkipped;\nend;\n\n{ TwbKeepAliveRoot }\n\nconstructor TwbKeepAliveRoot.Create;\nbegin\n  inherited;\n  Setup;\nend;\n\ndestructor TwbKeepAliveRoot.Destroy;\nbegin\n  inherited;\n  Teardown;\nend;\n\nprocedure TwbKeepAliveRoot.Done;\nbegin\n  Teardown;\nend;\n\nprocedure TwbKeepAliveRoot.Setup;\nbegin\n  New(karKAC);\n  karKAC.kacFinished := False;\n  karKAC.kacPrev := wbKeepAliveContext;\n  karKAC.kacHead := TwbContainer.Create(nil);\n  wbKeepAliveContext := karKAC;\nend;\n\nprocedure TwbKeepAliveRoot.Teardown;\nvar\n  KAC : PwbKeepAliveContext;\nbegin\n  if Assigned(karKAC) then begin\n    karKAC.kacFinished := True;\n    karKAC := nil;\n  end;\n\n  KAC := wbKeepAliveContext;\n  while Assigned(KAC) and KAC.kacFinished do begin\n    wbKeepAliveContext := KAC.kacPrev;\n    while Assigned(KAC.kacHead) do\n      KAC.kacHead := KAC.kacHead.ReleaseKeepAlive;\n    Dispose(KAC);\n    KAC := wbKeepAliveContext;\n  end;\nend;\n\ninitialization\n  wbContainedInDef[1] := wbFormIDCk('Worldspace', [WRLD], False, cpNormal, True);\n  wbContainedInDef[6] := wbFormIDCk('Cell', [CELL], False, cpNormal, True);\n  wbContainedInDef[7] := wbFormIDCk('Topic', [DIAL], False, cpNormal, True);\n  wbContainedInDef[10] := wbFormIDCk('Quest', [QUST], False, cpNormal, True);\n\n  SubRecordOrderList := TwbFastStringList.Create;\n  SubRecordOrderList.Sorted := True;\n  SubRecordOrderList.Duplicates := dupIgnore;\n\n  RecordToSkip := TwbFastStringList.Create;\n  RecordToSkip.Sorted := True;\n  RecordToSkip.Duplicates := dupIgnore;\n\n  GroupToSkip := TwbFastStringList.Create;\n  GroupToSkip.Sorted := True;\n  GroupToSkip.Duplicates := dupIgnore;\n\n  ChaptersToSkip := TwbFastStringList.Create;\n  ChaptersToSkip.Sorted := True;\n  ChaptersToSkip.Duplicates := dupIgnore;\n\n  FilesMap := TwbFastStringList.Create;\n  FilesMap.Sorted := True;\n  FilesMap.Duplicates := dupError;\nfinalization\n  WriteSubRecordOrderList;\n  FreeAndNil(SubRecordOrderList);\n  FreeAndNil(RecordToSkip);\n  FreeAndNil(GroupToSkip);\n  FreeAndNil(ChaptersToSkip);\n  FreeAndNil(FilesMap);\n  wbContainedInDef[1] := nil;\n  wbContainedInDef[6] := nil;\n  wbContainedInDef[7] := nil;\n  wbContainedInDef[10] := nil;\nend.\n"
  },
  {
    "path": "lib/xedit/wbInit.pas",
    "content": "{*******************************************************************************\n\n     The contents of this file are subject to the Mozilla Public License\n     Version 1.1 (the \"License\"); you may not use this file except in\n     compliance with the License. You may obtain a copy of the License at\n     http://www.mozilla.org/MPL/\n\n     Software distributed under the License is distributed on an \"AS IS\"\n     basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the\n     License for the specific language governing rights and limitations\n     under the License.\n\n*******************************************************************************}\n\nunit wbInit;\n\n{$I wbDefines.inc}\n\ninterface\n\nuses\n  Classes;\n\nvar\n  wbApplicationTitle   : string;\n  wbScriptsPath        : string;\n  wbScriptToRun        : string;\n  wbBackupPath         : string;\n  wbTempPath           : string;\n  wbSavePath           : string;\n  wbMyGamesTheGamePath : string;\n  wbPluginsFileName    : String;\n  wbSettingsFileName   : string;\n  wbModGroupFileName   : string;\n  wbPluginToUse        : string;  // Passed a specific plugin as parameter\n  wbLogFile            : string;  // Optional log file for this session\n  wbMyProfileName      : string;\n\n  wbMasterUpdateDone   : Boolean;\n  wbDontSave           : Boolean;\n  wbDontBackup         : Boolean = False;\n  wbRemoveTempPath     : Boolean = True;\n  wbQuickShowConflicts : Boolean;\n  wbQuickClean         : Boolean;\n\n  wbParamIndex         : integer = 1;     // First unused parameter\n  wbPluginsToUse       : TStringList;\n\nfunction wbFindNextValidCmdLineFileName(var startingIndex : integer; out aValue  : string; defaultPath : string = '') : Boolean;\nfunction wbFindNextValidCmdLinePlugin(var startingIndex : integer; out aValue  : string; defaultPath : string) : Boolean;\nfunction wbFindCmdLineParam(const aSwitch : string; out aValue : string): Boolean; overload;\n\nfunction wbLoadMOHookFile: Boolean;\nprocedure SwitchToCoSave;\n\nimplementation\n\nuses\n  SysUtils,\n  Windows,\n  Registry,\n  ShellApi,\n  Dialogs,\n  ShlObj,\n  IOUtils,\n  IniFiles,\n  wbHelpers,\n  wbInterface,\n  wbImplementation,\n  wbDefinitionsFNV,\n  wbDefinitionsFNVSaves,\n  wbDefinitionsFO3,\n  wbDefinitionsFO3Saves,\n  wbDefinitionsFO4,\n  wbDefinitionsFO4Saves,\n  wbDefinitionsTES3,\n  wbDefinitionsTES4,\n  wbDefinitionsTES4Saves,\n  wbDefinitionsTES5,\n  wbDefinitionsTES5Saves;\n\nfunction wbFindCmdLineParam(const aSwitch     : string;\n                            const aChars      : TSysCharSet;\n                                  aIgnoreCase : Boolean;\n                              out aValue      : string)\n                                              : Boolean; overload;\nvar\n  i : Integer;\n  s : string;\nbegin\n  Result := False;\n  aValue := '';\n  for i := 1 to ParamCount do begin\n    s := ParamStr(i);\n    if (aChars = []) or (s[1] in aChars) then\n      if aIgnoreCase then begin\n        if AnsiCompareText(Copy(s, 2, Length(aSwitch)), aSwitch) = 0 then begin\n          if (length(s)>(length(aSwitch)+2)) and (s[Length(aSwitch) + 2] = ':') then begin\n            aValue := Copy(s, Length(aSwitch) + 3, MaxInt);\n            Result := True;\n          end;\n          Exit;\n        end;\n      end else\n        if AnsiCompareStr(Copy(s, 2, Length(aSwitch)), aSwitch) = 0 then begin\n          if s[Length(aSwitch) + 2] = ':' then begin\n            aValue := Copy(s, Length(aSwitch) + 3, MaxInt);\n            Result := True;\n          end;\n          Exit;\n        end;\n  end;\nend;\n\nfunction wbFindCmdLineParam(var   startingIndex : integer;\n                            const aChars        : TSysCharSet;\n                              out aValue        : string)\n                                                : Boolean; overload;\nvar\n  i : integer;\n  s : string;\nbegin\n  Result := False;\n  aValue := '';\n  for i := startingIndex to ParamCount do begin\n    s := ParamStr(i);\n    if (aChars = []) or (s[1] in aChars) then // skipped\n      Inc(startingIndex)\n    else begin\n      aValue := ParamStr(i);\n      startingIndex := i+1;\n      Result := True;\n      break;\n    end\n  end;\nend;\n\nfunction wbFindCmdLineParam(const aSwitch : string;\n                              out aValue  : string)\n                                          : Boolean; overload;\nbegin\n  Result := wbFindCmdLineParam(aSwitch, SwitchChars, True, aValue);\nend;\n\nfunction wbFindCmdLineParam(var startingIndex : integer; out aValue  : string) : Boolean; overload;\nbegin\n  Result := wbFindCmdLineParam(startingIndex, SwitchChars, aValue);\nend;\n\nfunction wbCheckForValidExtension(aFilePath : string; const anExtension : string): Boolean; overload;\nbegin\n  Result := UpperCase(ExtractFileExt(aFilePath)) = UpperCase(anExtension);\nend;\n\nfunction wbCheckForPluginExtension(aFilePath : string): Boolean;\nbegin\n  Result := wbCheckForValidExtension(aFilePath, '.esp') or wbCheckForValidExtension(aFilePath, '.esm');\nend;\n\nfunction wbCheckForValidExtension(aFilePath : string): Boolean; overload;\nbegin\n  Result := wbCheckForPluginExtension(aFilePath) or\n            wbCheckForValidExtension(aFilePath, '.fos') or wbCheckForValidExtension(aFilePath, '.ess');\nend;\n\nfunction wbFindNextValidCmdLineFileName(var startingIndex : integer; out aValue  : string; defaultPath : string = '') : Boolean;\nbegin\n  Result := wbFindCmdLineParam(startingIndex, SwitchChars, aValue);\n  if Result and not FileExists(aValue) then\n    if (defaultPath<>'') then\n      if FileExists(defaultPath+'\\'+aValue) then\n        aValue := ExpandFileName(defaultPath+'\\'+aValue)\n      else\n        Result := False\n    else\n      Result := False;\nend;\n\nfunction wbFindNextValidCmdLinePlugin(var startingIndex : integer; out aValue  : string; defaultPath : string) : Boolean;\nbegin\n  repeat\n    Result := wbFindNextValidCmdLineFileName(startingIndex, aValue, defaultPath);\n  until not Result or wbCheckForPluginExtension(aValue);\n  if Result  then\n    if (AnsiCompareText(ExtractFilePath(ExpandFileName(aValue)), ExpandFileName(defaultPath)) = 0) then begin\n      aValue := ExtractFileName(aValue);\n      if not Assigned(wbPluginsToUse) then wbPluginsToUse := TStringList.Create;\n      wbPluginsToUse.Add(aValue);\n    end else\n      Result := False;\nend;\n\n// several ini settings should be read before record definitions\n// they may affect definitions like wbSimpleRecords\n// and should be overridden by command line parameters\nprocedure ReadSettings;\nvar\n  Settings: TMemIniFile;\nbegin\n  try\n    Settings := TMemIniFile.Create(wbSettingsFileName);\n    try\n      wbLoadBSAs := Settings.ReadBool('Options', 'LoadBSAs', wbLoadBSAs);\n      wbSimpleRecords := Settings.ReadBool('Options', 'SimpleRecords', wbSimpleRecords);\n      wbShowFlagEnumValue := Settings.ReadBool('Options', 'ShowFlagEnumValue', wbShowFlagEnumValue);\n      wbTrackAllEditorID := Settings.ReadBool('Options', 'TrackAllEditorID', wbTrackAllEditorID);\n    finally\n      Settings.Free;\n    end;\n  finally\n  end;\nend;\n\nfunction GetCSIDLShellFolder(CSIDLFolder: integer): string;\nbegin\n  SetLength(Result, MAX_PATH);\n  SHGetSpecialFolderPath(0, PChar(Result), CSIDLFolder, True);\n  SetLength(Result, StrLen(PChar(Result)));\n  if (Result <> '') then\n    Result := IncludeTrailingBackslash(Result);\nend;\n\nfunction CheckAppPath: string;\nconst\n  //gmFNV, gmFO3, gmTES3, gmTES4, gmTES5, gmSSE, gmFO4\n  ExeName : array[TwbGameMode] of string =\n    ('FalloutNV.exe', 'Fallout3.exe', 'Morrowind.exe', 'Oblivion.exe', 'TESV.exe', 'SkyrimSE.exe', 'Fallout4.exe');\nvar\n  s: string;\nbegin\n  Result := '';\n  s := ExtractFilePath(ParamStr(0));\n  while Length(s) > 3 do begin\n    if FileExists(s + ExeName[wbGameMode]) and DirectoryExists(s + 'Data') then begin\n      Result := s;\n      Exit;\n    end;\n    s := ExtractFilePath(ExcludeTrailingPathDelimiter(s));\n  end;\nend;\n\n{===SafeLoadLibrary============================================================}\n{$IFDEF CPUX86}\nfunction TestAndClearFPUExceptions(AExceptionMask: Word): Boolean;\nasm\n      PUSH    ECX\n      MOV     CX, AX\n      FSTSW   AX\n      TEST    AX, CX\n      JNE     @@bad\n      XOR     EAX, EAX\n      INC     EAX\n      JMP     @@exit\n@@bad:\n      XOR     EAX, EAX\n@@exit:\n      POP     ECX\n      FCLEX\n      RET\nend;\n{------------------------------------------------------------------------------}\nfunction SafeLoadLibrary(const Filename: string; ErrorMode: UINT): HMODULE;\nvar\n  OldMode: UINT;\n  FPUControlWord: Word;\nbegin\n  OldMode := SetErrorMode(ErrorMode);\n  try\n    FPUControlWord := Get8087CW();\n    Result := LoadLibrary(PChar(Filename));\n    TestAndClearFPUExceptions(0);\n    Set8087CW(FPUControlWord);\n  finally\n    SetErrorMode(OldMode);\n  end;\nend;\n{==============================================================================}\n{$ENDIF CPUX86}\n\n\nfunction wbLoadMOHookFile: Boolean;\nvar\n  HookDll : HMODULE;\n  Init    : function(logLevel: Integer; profileName: LPCWSTR): BOOL; cdecl;\nbegin\n  if not wbShouldLoadMOHookFile then\n    Exit(True);\n  Result := False;\n  if not FileExists(wbMOHookFile) then\n    Exit;\n\n  HookDll := SafeLoadLibrary(wbMOHookFile, SEM_NOOPENFILEERRORBOX);\n  if HookDll <> 0 then begin\n    Pointer(@Init) := GetProcAddress(HookDll, 'Init');\n    if Assigned(Pointer(@Init)) then\n      Result := Init(0, PWideChar(UnicodeString(wbMOProfile)));\n  end;\nend;\n\nprocedure DoInitPath(const ParamIndex: Integer);\nconst\n  sBethRegKey             = '\\SOFTWARE\\Bethesda Softworks\\';\n  sBethRegKey64           = '\\SOFTWARE\\Wow6432Node\\Bethesda Softworks\\';\nvar\n  s       : String;\n  IniFile : TIniFile;\nbegin\n  wbModGroupFileName := wbProgramPath + wbAppName + wbToolName + '.modgroups';\n\n  if not wbFindCmdLineParam('S', wbScriptsPath) then\n    wbScriptsPath := wbProgramPath + 'Edit Scripts\\';\n\n  if not wbFindCmdLineParam('T', wbTempPath) then\n    wbTempPath := IncludeTrailingPathDelimiter(TPath.GetTempPath + wbAppName + 'Edit')\n  else\n    wbRemoveTempPath := not DirectoryExists(wbTempPath);\n\n  if not wbFindCmdLineParam('D', wbDataPath) then begin\n    wbDataPath := CheckAppPath;\n\n    if wbDataPath = '' then with TRegistry.Create do try\n      RootKey := HKEY_LOCAL_MACHINE;\n\n      if not OpenKeyReadOnly(sBethRegKey + wbGameName2 + '\\') then\n        if not OpenKeyReadOnly(sBethRegKey64 + wbGameName2 + '\\') then begin\n          s := 'Fatal: Could not open registry key: ' + sBethRegKey + wbGameName + '\\';\n//          if wbGameMode = gmTES5 then // All game exists on steam now\n            ShowMessage(s+#13+#10+'This can happen after Steam updates, run game''s launcher to restore registry settings');\n          wbDontSave := True;\n          Exit;\n        end;\n\n      wbDataPath := ReadString('Installed Path');\n\n      if wbDataPath = '' then begin\n        s := 'Fatal: Could not determine '+wbGameName2+' installation path, no \"Installed Path\" registry key';\n//        if wbGameMode = gmTES5 then\n          ShowMessage(s+#13+#10+'This can happen after Steam updates, run game''s launcher to restore registry settings');\n        wbDontSave := True;\n      end;\n    finally\n      Free;\n    end;\n    if wbDataPath <>'' then\n      wbDataPath := IncludeTrailingPathDelimiter(wbDataPath) + 'Data\\';\n  end else\n    wbDataPath := IncludeTrailingPathDelimiter(wbDataPath);\n\n  wbOutputPath := wbDataPath;\n  if wbFindCmdLineParam('O', s) and (Length(s) > 0) then\n    if s[1] = '.' then\n      //assume relative path\n      wbOutputPath := IncludeTrailingPathDelimiter(wbOutputPath + s)\n    else\n      //assume absolute path\n      wbOutputPath := IncludeTrailingPathDelimiter(s);\n\n  wbMOHookFile := wbDataPath + '..\\Mod Organizer\\hook.dll';\n\n  if not wbFindCmdLineParam('I', wbTheGameIniFileName) then begin\n    wbMyProfileName := GetCSIDLShellFolder(CSIDL_PERSONAL);\n    if wbMyProfileName = '' then begin\n      ShowMessage('Fatal: Could not determine my documents folder');\n      Exit;\n    end;\n    wbMyGamesTheGamePath := wbMyProfileName + 'My Games\\'+ wbGameName2 +'\\';\n\n    if wbGameMode in [gmFO3, gmFNV] then\n      wbTheGameIniFileName := wbMyGamesTheGamePath + 'Fallout.ini'\n    else if wbGameMode = gmFO4 then\n      wbTheGameIniFileName := wbMyGamesTheGamePath + 'Fallout4.ini'\n    else\n      wbTheGameIniFileName := wbMyGamesTheGamePath + wbGameName + '.ini';\n  end;\n\n  if not wbFindCmdLineParam('G', wbSavePath) then begin\n    if wbMyGamesTheGamePath = '' then\n      wbMyGamesTheGamePath := ExtractFilePath(wbTheGameIniFileName);\n\n    s := 'Saves\\';\n    if FileExists(wbTheGameIniFileName) then begin\n      IniFile := TIniFile.Create(wbTheGameIniFileName);\n      try\n        s := IniFile.ReadString('General', 'SLocalSavePath', s);\n      finally\n        FreeAndNil(IniFile);\n      end;\n    end;\n    wbSavePath := wbMyGamesTheGamePath + s;\n  end;\n  wbSavePath := IncludeTrailingPathDelimiter(wbSavePath);\n\n  wbParamIndex := ParamIndex;\n  if not wbFindCmdLineParam('P', wbPluginsFileName) then\n    if not (wbFindNextValidCmdLineFileName(wbParamIndex, wbPluginsFileName) and SameText(ExtractFileExt(wbPluginsFileName), '.txt'))\n       or wbCheckForValidExtension(wbPluginsFileName)\n    then begin\n      wbParamIndex := ParamIndex;\n      wbPluginsFileName := GetCSIDLShellFolder(CSIDL_LOCAL_APPDATA);\n      if wbPluginsFileName = '' then begin\n        ShowMessage('Fatal: Could not determine the local application data folder');\n        Exit;\n      end;\n\n      wbPluginsFileName := wbPluginsFileName + wbGameName2 + '\\Plugins.txt';\n    end;\n\n  // settings in the ini file next to app, or in the same folder with plugins.txt\n  wbSettingsFileName := wbProgramPath + wbAppName + wbToolName + '.ini';\n  if not FileExists(wbSettingsFileName) then\n    wbSettingsFileName := ChangeFileExt(wbPluginsFileName, '.'+LowerCase(wbAppName)+'viewsettings');\n\n  wbBackupPath := '';\n  if not (wbDontSave or wbFindCmdLineParam('B', wbBackupPath)) then begin\n    wbBackupPath := wbDataPath + wbAppName + 'Edit Backups\\';\n    if not DirectoryExists(wbBackupPath) then\n      if not ForceDirectories(wbBackupPath) then\n        wbBackupPath := wbDataPath;\n  end;\n  wbFindCmdLineParam('R', wbLogFile);\nend;\n\nvar\n  wbForcedModes: string;\n  AppGameMode, AppToolMode, AppSourceMode: string;\n\nprocedure DetectAppMode;\nconst\n  SourceModes : array [1..2] of string = ('plugins', 'saves');\n  GameModes: array [1..6] of string = ('tes4', 'tes5', 'sse', 'fo3', 'fnv', 'fo4');\n  ToolModes: array [1..12] of string = (\n    'edit', 'view', 'lodgen', 'script', 'translate',\n    'setesm', 'clearesm', 'sortandclean', 'sortandcleanmasters',\n    'checkforerrors', 'checkforitm', 'checkfordr');\nvar\n  s, p: string;\nbegin\n  // Detecting game mode\n  // check command line params first for mode overrides\n  // they should take precendence over application name detection\n  // AppSourceMode := SourceModes[1];\n  for s in SourceModes do\n    if FindCmdLineSwitch(s) or wbFindCmdLineParam(s, p) or (Pos(s, wbForcedModes) <> 0) then begin\n      AppSourceMode := s;\n      Break;\n    end;\n  // if no overrrides, then check by executable name\n  if AppSourceMode = '' then\n    for s in SourceModes do\n      if (Pos(s, LowerCase(ExtractFileName(ParamStr(0)))) <> 0) or (Pos(s, wbForcedModes) <> 0) then begin\n        AppSourceMode := s;\n        Break;\n      end;\n  // if still nothing, then default value\n  if AppSourceMode = '' then\n    AppSourceMode := 'plugins';\n\n  for s in GameModes do\n    if FindCmdLineSwitch(s) or wbFindCmdLineParam(s, p) or (Pos(s, wbForcedModes) <> 0) then begin\n      AppGameMode := s;\n      Break;\n    end;\n  // if no overrrides, then check by executable name\n  if AppGameMode = '' then\n    for s in GameModes do\n      if (Pos(s, LowerCase(ExtractFileName(ParamStr(0)))) <> 0) or (Pos(s, wbForcedModes) <> 0) then begin\n        AppGameMode := s;\n        Break;\n      end;\n  // if still nothing, then default value\n  if AppGameMode = '' then\n    AppGameMode := 'fo4';\n\n  // the same for tool mode\n  for s in ToolModes do\n    if FindCmdLineSwitch(s) or wbFindCmdLineParam(s, p) or (Pos(s, wbForcedModes) <> 0) then begin\n      AppToolMode := s;\n      Break;\n    end;\n  if AppToolMode = '' then\n    for s in ToolModes do\n      if (Pos(s, LowerCase(ExtractFileName(ParamStr(0)))) <> 0) or (Pos(s, wbForcedModes) <> 0) then begin\n        AppToolMode := s;\n        Break;\n      end;\n  if AppToolMode = '' then\n    AppToolMode := 'edit';\nend;\n\nfunction isMode(aMode: String): Boolean;\nbegin\n  aMode := LowerCase(aMode);\n  Result := (AppGameMode = aMode) or (AppToolMode = aMode) or (AppSourceMode = aMode);\nend;\n\n// Force app modes\nfunction CheckForcedMode: Boolean;\nvar\n  s: string;\n  i: integer;\nbegin\n  Result := False;\n  // there is a game specific script provided to execute\n  // go into 'script' tool mode and detect game mode by script's extension\n  i := 1;\n  if wbFindCmdLineParam('script', s) or wbFindNextValidCmdLineFileName(i, s) then begin\n    if not FileExists(s) then\n      Exit;\n    wbScriptToRun := s;\n    s := ExtractFileExt(s);\n    i := Pos(UpperCase('pas'), UpperCase(s));\n    if (i > 0) and (i = Length(s) - 2) then begin\n      wbForcedModes := Copy(s, 2, Length(s) - 4) + ',script';\n      Result := True;\n    end;\n  end;\nend;\n\nprocedure wbDoInit;\nvar\n  s: string;\nbegin\n  wbReportMode := False;\n  wbEditAllowed := True;\n  wbDontSave    := False;\n\n  CheckForcedMode;\n  DetectAppMode;\n\n  if isMode('Saves') then begin\n    wbToolSource := tsSaves;\n    wbSourceName := 'Saves';\n    wbUseFalsePlugins := True;\n  end else begin // defaults to plugin\n    wbToolSource := tsPlugins;\n    wbSourceName := 'Plugins';\n  end;\n\n  if isMode('View') then begin\n    wbToolMode    := tmView;\n    wbToolName    := 'View';\n    wbEditAllowed := False;\n    wbDontSave    := True;\n  end else if isMode('MasterUpdate') then begin\n    wbToolMode    := tmMasterUpdate;\n    wbToolName    := 'MasterUpdate';\n  end else if isMode('MasterRestore') then begin\n    wbToolMode    := tmMasterRestore;\n    wbToolName    := 'MasterRestore';\n  end else if isMode('LODGen') then begin\n    wbToolMode    := tmLODgen;\n    wbToolName    := 'LODGen';\n    wbEditAllowed := False;\n    wbDontSave    := True;\n  end else if isMode('Script') then begin\n    wbToolMode    := tmScript;\n    wbToolName    := 'Script';\n  end else if isMode('Translate') then begin\n    wbToolMode    := tmTranslate;\n    wbToolName    := 'Trans';\n  end else if isMode('setESM') then begin\n    wbToolMode    := tmESMify;\n    wbToolName    := 'SettingESMflag';\n  end else if isMode('clearESM') then begin\n    wbToolMode    := tmESPify;\n    wbToolName    := 'ClearingESMflag';\n  end else if isMode('SortAndClean') then begin\n    wbToolMode    := tmSortAndCleanMasters;\n    wbToolName    := 'SortAndCleanMasters';\n  end else if isMode('CheckForErrors') then begin\n    wbToolMode    := tmCheckForErrors;\n    wbToolName    := 'CheckForErrors';\n  end else if isMode('CheckForITM') then begin\n    wbToolMode    := tmCheckForITM;\n    wbToolName    := 'CheckForITM';\n  end else if isMode('CheckForDR') then begin\n    wbToolMode    := tmCheckForDR;\n    wbToolName    := 'CheckForDR';\n  end else if isMode('Edit') then begin\n    wbToolMode    := tmEdit;\n    wbToolName    := 'Edit';\n  end else begin\n    ShowMessage('Application name must contain Edit, View, LODGen, MasterUpdate, MasterRestore, setESM, clearESM, sortAndCleanMasters, CheckForITM, CheckForDR or CheckForErrors to select mode.');\n    Exit;\n  end;\n\n  if isMode('FNV') then begin\n    wbGameMode := gmFNV;\n    wbAppName := 'FNV';\n    wbGameName := 'FalloutNV';\n    if not (wbToolMode in wbAlwaysMode) and not (wbToolMode in [tmMasterUpdate, tmMasterRestore]) then begin\n      ShowMessage('Application '+wbGameName+' does not currently support '+wbToolName);\n      Exit;\n    end;\n    if not (wbToolSource in [tsPlugins, tsSaves]) then begin\n      ShowMessage('Application '+wbGameName+' does not currently support '+wbSourceName);\n      Exit;\n    end;\n  end else if isMode('FO3') then begin\n    wbGameMode := gmFO3;\n    wbAppName := 'FO3';\n    wbGameName := 'Fallout3';\n    if not (wbToolMode in wbAlwaysMode) and not (wbToolMode in [tmMasterUpdate, tmMasterRestore]) then begin\n      ShowMessage('Application '+wbGameName+' does not currently support '+wbToolName);\n      Exit;\n    end;\n    if not (wbToolSource in [tsPlugins]) then begin\n      ShowMessage('Application '+wbGameName+' does not currently support '+wbSourceName);\n      Exit;\n    end;\n  end else if isMode('TES3') then begin\n    wbGameMode := gmTES3;\n    wbAppName := 'TES3';\n    wbGameName := 'Morrowind';\n    if not (wbToolMode in []) then begin\n      ShowMessage('Application '+wbGameName+' does not currently support '+wbToolName);\n      Exit;\n    end;\n    if not (wbToolSource in []) then begin\n      ShowMessage('Application '+wbGameName+' does not currently support '+wbSourceName);\n      Exit;\n    end;\n  end else if isMode('TES4') then begin\n    wbGameMode := gmTES4;\n    wbAppName := 'TES4';\n    wbGameName := 'Oblivion';\n    if not (wbToolMode in wbAlwaysMode) and not (wbToolMode in []) then begin\n      ShowMessage('Application '+wbGameName+' does not currently support '+wbToolName);\n      Exit;\n    end;\n    if not (wbToolSource in [tsPlugins]) then begin\n      ShowMessage('Application '+wbGameName+' does not currently support '+wbSourceName);\n      Exit;\n    end;\n  end else if isMode('TES5') then begin\n    wbGameMode := gmTES5;\n    wbAppName := 'TES5';\n    wbGameName := 'Skyrim';\n    if not (wbToolMode in wbAlwaysMode) and not (wbToolMode in [tmTranslate]) then begin\n      ShowMessage('Application '+wbGameName+' does not currently support '+wbToolName);\n      Exit;\n    end;\n    if not (wbToolSource in [tsPlugins, tsSaves]) then begin\n      ShowMessage('Application '+wbGameName+' does not currently support '+wbSourceName);\n      Exit;\n    end;\n  end else if isMode('SSE') then begin\n    wbGameMode := gmSSE;\n    wbAppName := 'SSE';\n    wbGameName := 'Skyrim';\n    wbGameName2 := 'Skyrim Special Edition';\n    if not (wbToolMode in wbAlwaysMode) and not (wbToolMode in [tmTranslate]) then begin\n      ShowMessage('Application '+wbGameName+' does not currently support '+wbToolName);\n      Exit;\n    end;\n    if not (wbToolSource in [tsPlugins, tsSaves]) then begin\n      ShowMessage('Application '+wbGameName+' does not currently support '+wbSourceName);\n      Exit;\n    end;\n  end else if isMode('FO4') then begin\n    wbGameMode := gmFO4;\n    wbAppName := 'FO4';\n    wbGameName := 'Fallout4';\n    wbArchiveExtension := '.ba2';\n    if not (wbToolMode in wbAlwaysMode) and not (wbToolMode in [tmTranslate]) then begin\n      ShowMessage('Application '+wbGameName+' does not currently support '+wbToolName);\n      Exit;\n    end;\n    if not (wbToolSource in [tsPlugins, tsSaves]) then begin\n      ShowMessage('Application '+wbGameName+' does not currently support '+wbSourceName);\n      Exit;\n    end;\n  end else begin\n    ShowMessage('Application name must contain FNV, FO3, FO4, SSE, TES4 or TES5 to select game.');\n    Exit;\n  end;\n  if (wbToolSource = tsSaves) and (wbToolMode = tmEdit) then begin\n    ShowMessage('Application '+wbGameName+' does not currently support '+wbSourceName+' in '+wbToolName+' mode.');\n    Exit;\n  end;\n\n  if wbGameName2 = '' then\n    wbGameName2 := wbGameName;\n\n  DoInitPath(wbParamIndex);\n\n  if wbGameMode = gmFNV then begin\n    wbVWDInTemporary := True;\n    wbLoadBSAs := False;\n    ReadSettings;\n  end else if wbGameMode = gmFO3 then begin\n    wbVWDInTemporary := True;\n    wbLoadBSAs := False;\n    ReadSettings;\n  end else if wbGameMode = gmTES3 then begin\n    wbLoadBSAs := False;\n    wbAllowInternalEdit := false;\n    ReadSettings;\n  end else if wbGameMode = gmTES4 then begin\n    wbLoadBSAs := True;\n    wbAllowInternalEdit := false;\n    ReadSettings;\n  end else if wbGameMode = gmTES5 then begin\n    wbVWDInTemporary := True;\n    wbLoadBSAs := True; // localization won't work otherwise\n    wbHideIgnored := False; // to show Form Version\n    ReadSettings;\n  end else if wbGameMode = gmSSE then begin\n    wbVWDInTemporary := True;\n    wbLoadBSAs := True; // localization won't work otherwise\n    wbHideIgnored := False; // to show Form Version\n    ReadSettings;\n  end else if wbGameMode = gmFO4 then begin\n    wbVWDInTemporary := True;\n    wbVWDAsQuestChildren := True;\n    wbLoadBSAs := True; // localization won't work otherwise\n    wbHideIgnored := False; // to show Form Version\n    ReadSettings;\n    //wbCreateContainedIn := False;\n  end else begin\n    Exit;\n  end;\n\n  case wbGameMode of\n    gmFNV:  case wbToolSource of\n      tsSaves:   DefineFNVSaves;\n      tsPlugins: DefineFNV;\n    end;\n    gmFO3:  case wbToolSource of\n      tsSaves:   DefineFO3Saves;\n      tsPlugins: DefineFO3;\n    end;\n    gmFO4:  case wbToolSource of\n      tsSaves:   DefineFO4Saves;\n      tsPlugins: DefineFO4;\n    end;\n    gmTES3: case wbToolSource of\n      tsPlugins: DefineTES3;\n    end;\n    gmTES4: case wbToolSource of\n      tsSaves:   DefineTES4Saves;\n      tsPlugins: DefineTES4;\n    end;\n    gmTES5: case wbToolSource of\n      tsSaves:   DefineTES5Saves;\n      tsPlugins: DefineTES5;\n    end;\n    gmSSE: case wbToolSource of\n      tsSaves:   DefineTES5Saves;\n      tsPlugins: DefineTES5;\n    end\n  else\n    ShowMessage('Application name must contain FNV, FO3, FO4, SSE, TES4 or TES5 to select game.');\n    Exit;\n  end;\n\n  case wbGameMode of\n    gmTES5, gmSSE:\n      wbLanguage := 'English';\n    gmFO4:\n      wbLanguage := 'En';\n  end;\n  if wbFindCmdLineParam('l', s) then\n    wbLanguage := s;\n\n  if wbFindCmdLineParam('cp', s) then begin\n    if SameText(s, 'utf-8') then\n      wbStringEncoding := seUTF8;\n  end;\n\n  if FindCmdLineSwitch('speed') then\n    wbSpeedOverMemory := True;\n  if FindCmdLineSwitch('memory') then\n    wbSpeedOverMemory := False;\n\n  if FindCmdLineSwitch('report') then\n    wbReportMode := (DebugHook <> 0);\n  if FindCmdLineSwitch('MoreInfoForIndex') then\n    wbMoreInfoForIndex := true;\n\n  if FindCmdLineSwitch('fixup') then\n    wbAllowInternalEdit := True\n  else if FindCmdLineSwitch('nofixup') then\n    wbAllowInternalEdit := False;\n\n  if FindCmdLineSwitch('skipbsa') then\n    wbLoadBSAs := False\n  else if FindCmdLineSwitch('forcebsa') then\n    wbLoadBSAs := True;\n\n  if FindCmdLineSwitch('skipInternalEditing') then\n    wbAllowInternalEdit := False\n  else if FindCmdLineSwitch('forceInternalEditing') then\n    wbAllowInternalEdit := True;\n\n  if FindCmdLineSwitch('showfixup') then\n    wbShowInternalEdit := True\n  else if FindCmdLineSwitch('hidefixup') then\n    wbShowInternalEdit := False;\n\n  if FindCmdLineSwitch('quickshowconflicts') then\n    wbQuickShowConflicts := True;\n\n  if FindCmdLineSwitch('IKnowWhatImDoing') then\n    wbIKnowWhatImDoing := True;\n\n  if FindCmdLineSwitch('quickclean') and (wbToolSource in [tsPlugins]) then\n    wbQuickClean := wbIKnowWhatImDoing;\n\n  if FindCmdLineSwitch('TrackAllEditorID') then\n    wbTrackAllEditorID := True;\n\n  if wbToolMode in wbPluginModes then // look for the file name\n    if not wbFindNextValidCmdLinePlugin(wbParamIndex, wbPluginToUse, wbDataPath) then begin\n      ShowMessage(wbToolName+' mode requires a valid plugin name!');\n      Exit;\n    end;\n\n  if wbToolMode = tmLODgen then begin\n    wbIKnowWhatImDoing := True;\n    wbAllowInternalEdit := False;\n    wbShowInternalEdit := False;\n    wbLoadBSAs := True;\n    wbBuildRefs := False;\n  end else if wbToolMode = tmScript then begin\n    wbIKnowWhatImDoing := True;\n    wbLoadBSAs := True;\n    wbBuildRefs := True;\n  end else if wbToolMode in [tmMasterUpdate, tmESMify] then begin\n    wbIKnowWhatImDoing := True;\n    wbAllowInternalEdit := False;\n    wbShowInternalEdit := False;\n    wbLoadBSAs := False;\n    wbBuildRefs := False;\n    wbMasterUpdateFilterONAM := wbToolMode in [tmESMify];\n    if FindCmdLineSwitch('filteronam') then\n      wbMasterUpdateFilterONAM := True\n    else if FindCmdLineSwitch('noFilteronam') then\n      wbMasterUpdateFilterONAM := True;\n    if FindCmdLineSwitch('FixPersistence') then\n      wbMasterUpdateFixPersistence := True\n    else if FindCmdLineSwitch('NoFixPersistence') then\n      wbMasterUpdateFixPersistence := False;\n  end else if wbToolMode in [tmMasterRestore, tmESPify, tmCheckForDR, tmCheckForITM, tmCheckForErrors] then begin\n    wbIKnowWhatImDoing := True;\n    wbAllowInternalEdit := False;\n    wbShowInternalEdit := False;\n    wbLoadBSAs := False;\n    wbBuildRefs := False;\n  end else if wbToolMode = tmTranslate then begin\n    wbTranslationMode := True;\n  end;\n\n  wbApplicationTitle := wbAppName + wbToolName + ' ' + VersionString;\n  {$IFDEF LiteVersion}\n  wbApplicationTitle := wbApplicationTitle + ' Lite';\n  {$ENDIF}\n  {$IFDEF WIN64}\n  wbApplicationTitle := wbApplicationTitle + ' x64';\n  {$ENDIF WIN64}\n\n  if FindCmdLineSwitch('fixuppgrd') then\n    wbFixupPGRD := True;\n\n  wbShouldLoadMOHookFile := wbFindCmdLineParam('moprofile', wbMOProfile);\n\n  if (wbToolMode = tmEdit) and not wbIsAssociatedWithExtension('.' + wbAppName + 'pas') then try\n    wbAssociateWithExtension('.' + wbAppName + 'pas', wbAppName + 'Script', wbAppName + wbToolName + ' script');\n  except end;\n\nend;\n\nprocedure SwitchToCoSave;\nbegin\n  case wbGameMode of\n    gmFNV:  SwitchToFNVCoSave;\n    gmFO3:  SwitchToFO3CoSave;\n    gmTES4: SwitchToTES4CoSave;\n    gmTES5: SwitchToTES5CoSave;\n    gmSSE:  SwitchToTES5CoSave;\n  end;\nend;\n\ninitialization\n  wbDoInit;\n\nend.\n"
  },
  {
    "path": "lib/xedit/wbInterface.pas",
    "content": "{******************************************************************************\n\n     The contents of this file are subject to the Mozilla Public License\n     Version 1.1 (the \"License\"); you may not use this file except in\n     compliance with the License. You may obtain a copy of the License at\n     http://www.mozilla.org/MPL/\n\n     Software distributed under the License is distributed on an \"AS IS\"\n     basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the\n     License for the specific language governing rights and limitations\n     under the License.\n\n*******************************************************************************}\n\nunit wbInterface;\n\n{$I wbDefines.inc}\n\ninterface\n\nuses\n  Classes,\n  SysUtils,\n  Graphics;\n\nconst\n  VersionString  = '3.2';\n  clOrange       = $004080FF;\n  wbFloatDigits  = 6;\n  wbHardcodedDat = '.Hardcoded.keep.this.with.the.exe.and.otherwise.ignore.it.I.really.mean.it.dat';\n\ntype\n  TwbProgressCallback = procedure(const aStatus: string);\n  TwbPointerArray = array [0..Pred(High(Integer) div SizeOf(Pointer))] of Pointer;\n  PwbPointerArray = ^TwbPointerArray;       {General array of pointer}\n\nthreadvar\n  wbProgressCallback : TwbProgressCallback;\n  wbCurrentTick      : Integer;\n  wbCurrentAction    : string;\n  wbStartTime        : TDateTime;\n  wbShowStartTime    : Integer;\n\nvar\n  wbDisplayLoadOrderFormID : Boolean  = False;\n  wbSimpleRecords          : Boolean  = True;\n  wbFixupPGRD              : Boolean  = False;\n  wbIKnowWhatImDoing       : Boolean  = False;\n  wbHideUnused             : Boolean  = True;\n  wbHideIgnored            : Boolean  = True;\n  wbHideNeverShow          : Boolean  = True;\n  wbShowFormVersion        : Boolean  = False;\n  wbShowFlagEnumValue      : Boolean  = False;\n  wbShowGroupRecordCount   : Boolean  = False;\n  wbDisplayShorterNames    : Boolean  = False;\n  wbSortSubRecords         : Boolean  = False;\n  wbSortFLST               : Boolean  = True;\n  wbSortGroupRecord        : Boolean  = False;\n  wbRemoveOffsetData       : Boolean  = True;\n  wbEditAllowed            : Boolean  = False;\n  wbFlagsAsArray           : Boolean  = False;\n  wbDelayLoadRecords       : Boolean  = True;\n  wbMoreInfoForUnknown     : Boolean  = False;\n  wbMoreInfoForIndex       : Boolean  = False;\n  wbTranslationMode        : Boolean  = False;\n  wbTestWrite              : Boolean  = False;\n  wbForceNewHeader         : Boolean  = False; // add wbNewHeaderAddon value to the headers of mainrecords and GRUP records\n  wbNewHeaderAddon         : Cardinal = 40;    // 4 additional bytes, 40 - new form version field\n  wbRequireLoadOrder       : Boolean  = False;\n  wbCreateContainedIn      : Boolean  = True;\n  wbVWDInTemporary         : Boolean  = False;\n  wbVWDAsQuestChildren     : Boolean  = False;\n  wbResolveAlias           : Boolean  = True;\n  wbActorTemplateHide      : Boolean  = True;\n  wbClampFormID            : Boolean  = True;\n  wbAllowErrors            : Boolean  = True;\n  wbDoNotBuildRefsFor      : TStringList;\n  wbCopyIsRunning          : Integer  = 0;\n\n  wbUDRSetXESP       : Boolean = True;\n  wbUDRSetScale      : Boolean = False;\n  wbUDRSetScaleValue : Single  = 0.0;\n  wbUDRSetZ          : Boolean = True;\n  wbUDRSetZValue     : Single  = -30000;\n  wbUDRSetMSTT       : Boolean = True;\n  wbUDRSetMSTTValue  : Int64   = $0000001B; { AshPile01 }\n\n  wbMasterUpdateFilterONAM     : Boolean = False;\n  wbMasterUpdateFixPersistence : Boolean = True;\n\n  wbAllowInternalEdit : Boolean = True;\n  wbShowInternalEdit  : Boolean = False;\n\n  wbReportMode                       : Boolean = False;\n  wbReportUnused                     : Boolean = False;\n  wbReportRequired                   : Boolean = True;\n  wbReportUnusedData                 : Boolean = True;\n  wbReportUnknownFormIDs             : Boolean = True;\n  wbReportUnknownFloats              : Boolean = True;\n  wbReportUnknownStrings             : Boolean = True;\n  wbReportEmpty                      : Boolean = True;\n  wbReportSometimesEmpty             : Boolean = True;\n  wbReportFormIDs                    : Boolean = True;\n  wbReportNotFoundButAllowedFormIDs  : Boolean = True;\n  wbReportUnknownFlags               : Boolean = True;\n  wbReportUnknownEnums               : Boolean = True;\n  wbReportFormIDNotAllowedReferences : Boolean = True;\n  wbReportUnknown                    : Boolean = True;\n  wbMoreInfoForRequired              : Boolean = False;\n  wbMoreInfoForDecider               : Boolean = False;\n  wbTrackAllEditorID                 : Boolean = False;\n  wbShowTip                          : Boolean = True;\n\n  wbCheckExpectedBytes : Boolean = True;\n\n  wbRotationFactor : Extended = 180/Pi;\n  wbRotationScale  : Integer = 4;\n\n  wbDumpOffset : Integer  = 0;  // 1= starting offset, 2 = Count, 3 = Offsets, size and count\n  wbBaseOffset : Cardinal = 0;\n\n  wbProgramPath        : string;\n  wbDataPath           : string;\n  wbOutputPath         : string;\n  wbTheGameIniFileName : string;\n\n  wbShouldLoadMOHookFile : Boolean;\n  wbMOProfile            : string;\n  wbMOHookFile           : string;\n\n  wbSpeedOverMemory : Boolean = False;\n\n{$IFDEF USE_CODESITE}\ntype\n  TwbLoggingArea = (\n    laAddIfMissing,\n    laElementAssign,\n    laElementCanAssign,\n    laElementSetToDefault,\n    laElementWriteToStream,\n    laElementMergeStorage,\n\n    laDummy\n  );\n  TwbLoggingAreas = set of TwbLoggingArea;\n\nvar\n  wbLoggingAreas : TwbLoggingAreas = [\n\n    laAddIfMissing,\n    laElementAssign,\n    laElementCanAssign,\n    laElementSetToDefault,\n    //laElementWriteToStream,\n    //laElementMergeStorage,\n\n    laDummy\n  ];\n\nfunction wbCodeSiteLoggingEnabled: Boolean;\nfunction wbBeginCodeSiteLogging: Integer;\nfunction wbEndCodeSiteLogging: Integer;\n{$ENDIF}\n\n\ntype\n  TConflictAll = (\n    caUnknown,\n    caOnlyOne,\n    caNoConflict,\n    caConflictBenign,\n    caOverride,\n    caConflict,\n    caConflictCritical\n    );\n\n  TByteSet = set of Byte;\n  TConflictAllSet = set of TConflictAll;\n  TConflictAllColors = array[TConflictAll] of TColor;\n\n  TConflictThis = (\n    ctUnknown,\n    ctIgnored,\n    ctNotDefined,\n    ctIdenticalToMaster,\n    ctOnlyOne,\n    ctHiddenByModGroup,\n    ctMaster,\n    ctConflictBenign,\n    ctOverride,\n    ctIdenticalToMasterWinsConflict,\n    ctConflictWins,\n    ctConflictLoses\n    );\n\n  TConflictThisSet = set of TConflictThis;\n  TConflictThisColors = array[TConflictThis] of TColor;\n\nvar\n  wbColorConflictAll: TConflictAllColors = (\n    clDefault, // caUnknown\n    clDefault, // caOnlyOne\n    clLime,    // caNoConflict\n    clYellow,  // caConflictBenign\n    clYellow,  // caOverride\n    clRed,     // caConflict\n    clFuchsia  // caConflictCritical\n  );\n\n  wbColorConflictThis: TConflictThisColors = (\n    clWindowText, // ctUnknown\n    clWindowText, // ctIgnored\n    clMedGray,    // ctNotDefined\n    clDkGray,     // ctIdenticalToMaster\n    clWindowText, // ctOnlyOne\n    clLtGray,     // ctHiddenByModGroup\n    clPurple,     // ctMaster\n    clWindowText, // ctConflictBenign\n    clGreen,      // ctOverride\n    clOlive,      // ctIdenticalToMasterWinsConflict\n    clOrange,     // ctConflictWins\n    clRed         // ctConflictLoses\n  );\n\ntype\n  TwbConflictPriority = (\n    cpIgnore,\n    cpBenignIfAdded,\n    cpBenign,\n    cpTranslate,\n    cpNormal,\n    cpNormalIgnoreEmpty,\n    cpCritical,\n    cpFormID\n  );\n\n  LongRecSmall = packed record\n    Lo, Hi: Smallint;\n  end;\n\n  PwbSignature = ^TwbSignature;\n  TwbSignature = array[0..3] of AnsiChar;\n  TwbSignatures = array of TwbSignature;\n  TwbFileMagic = string;\n\n  TwbIntType = (\n    it0,\n    itU8,\n    itS8,\n    itU16,\n    itS16,\n    itU32,\n    itS32,\n    itU64,\n    itS64,\n    itU24,\n    itU6to30\n  );\n\n  TwbDefType = (\n    dtRecord,\n    dtSubRecord,\n    dtSubRecordArray,\n    dtSubRecordStruct,\n    dtSubRecordUnion,\n    dtString,\n    dtLString,\n    dtLenString,\n    dtByteArray,\n    dtInteger,\n    dtIntegerFormater,\n    dtIntegerFormaterUnion,\n    dtFlag,\n    dtFloat,\n    dtArray,\n    dtStruct,\n    dtUnion,\n    dtEmpty,\n    dtStructChapter\n  );\n\n  TwbGroupTypes = set of Byte;\n  TwbStringEncoding = (seCP1252, seUTF8);\n\nvar\n  dtNonValues : set of TwbDefType = [\n    dtRecord,\n    dtSubRecord,\n    dtSubRecordArray,\n    dtSubRecordStruct,\n    dtSubRecordUnion,\n    dtArray,\n    dtStruct,\n    dtUnion,\n    dtStructChapter\n  ];\n\n  wbStringEncoding: TwbStringEncoding = seCP1252;\n\ntype\n  IwbDef = interface;\n\n  TwbDefs = array of IwbDef;\n  TwbDefPath = array of record\n    Def   : IwbDef;\n    Index : Integer;\n  end;\n\n  IwbElement = interface;\n\n  IwbDef = interface\n    ['{C7739FBD-3B58-48A2-9DD0-8057D3496892}']\n    function GetDefType: TwbDefType;\n    function GetDefTypeName: string;\n    function CanAssign(const aElement: IwbElement; aIndex: Integer; const aDef: IwbDef): Boolean;\n    function Assign(const aTarget: IwbElement; aIndex: Integer; const aSource: IwbElement; aOnlySK: Boolean): IwbElement;\n    function GetDefID: Cardinal;\n    function Equals(const aDef: IwbDef): Boolean;\n    function GetConflictPriority(const aElement: IwbElement): TwbConflictPriority;\n    function GetConflictPriorityCanChange: Boolean;\n    function GetRequired: Boolean;\n    function CanContainFormIDs: Boolean;\n    function GetDontShow(const aElement: IwbElement): Boolean;\n    function GetHasDontShow: Boolean;\n    function GetRoot: IwbDef;\n    function GetNoReach: Boolean;\n    function GetParent: IwbDef;\n\n    procedure Report(const aParents: TwbDefPath);\n    procedure Used(const aElement: IwbElement = nil; const s: string = '');\n    procedure PossiblyRequired;\n    procedure NotRequired;\n    function IsNotRequired: Boolean;\n\n    property DefType: TwbDefType\n      read GetDefType;\n    property DefTypeName: string\n      read GetDefTypeName;\n    property DefID: Cardinal\n      read GetDefID;\n    property ConflictPriority[const aElement: IwbElement]: TwbConflictPriority\n      read GetConflictPriority;\n    property ConflictPriorityCanChange: Boolean\n      read GetConflictPriorityCanChange;\n    property Required: Boolean\n      read GetRequired;\n    property DontShow[const aElement: IwbElement]: Boolean\n      read GetDontShow;\n    property HasDontShow: Boolean\n      read GetHasDontShow;\n    property Root: IwbDef\n      read GetRoot;\n    property NoReach: Boolean\n      read GetNoReach;\n    property Parent: IwbDef\n      read GetParent;\n  end;\n\n  TwbElementType = (\n    etFile,\n    etMainRecord,\n    etGroupRecord,\n    etSubRecord,\n    etSubRecordStruct,\n    etSubRecordArray,\n    etSubRecordUnion,\n    etArray,\n    etStruct,\n    etValue,\n    etFlag,\n    etStringListTerminator,\n    etUnion,\n    etStructChapter\n  );\n\n  TwbElementTypes = set of TwbElementType;\n\n  IwbContainer = interface;\n  IwbFile = interface;\n  IwbNamedDef = interface;\n  IwbValueDef = interface;\n  IwbMainRecord = interface;\n\n  TwbElementState = (\n    esModified,\n    esInternalModified,\n    esUnsaved,\n    esSortKeyValid,\n    esExtendedSortKeyValid,\n    esHidden,\n    esParentHidden,\n    esParentHiddenChecked,\n    esNotReachable,\n    esReachable,\n    esTagged,\n    esDeciding,\n    esNotSuitableToAddTo,\n    esDummy, {Used in wbScriptAdapter as a default value}\n    esConstructionComplete,\n    esDestroying,\n    esChangeNotified,\n    esModifiedUpdated,\n    esSorting\n  );\n\n  TwbElementStates = set of TwbElementState;\n\n  TwbEditType = (\n    etDefault,\n    etComboBox,\n    etCheckComboBox\n  );\n\n  TDynFiles = array of IwbFile;\n\n  IwbElement = interface\n    ['{F4B4637D-C794-415F-B5C7-587EAA4095B3}']\n\n    function GetElementID: Cardinal;\n    function GetElementStates: TwbElementStates;\n    procedure SetElementState(aState: TwbElementState; Clear: Boolean = false);\n    function Equals(const aElement: IwbElement): Boolean;\n\n    function GetValue: string;\n    function GetCheck: string;\n    function GetSortKey(aExtended: Boolean): string;\n    function GetSortPriority: Integer;\n    function GetName: string;\n    function GetBaseName: string;\n    function GetDisplayName: string;\n    function GetShortName: string;\n    function GetPath: string;\n    function GetFullPath: string;\n    function GetPathName: string;\n    function GetSkipped: Boolean;\n    function GetDef: IwbNamedDef;\n    function GetValueDef: IwbValueDef;\n    function GetResolvedValueDef: IwbValueDef;\n    function GetElementType: TwbElementType;\n    function GetContainer: IwbContainer;\n    function GetContainingMainRecord: IwbMainRecord;\n    function GetFile: IwbFile;\n    function GetReferenceFile: IwbFile;\n    function GetSortOrder: Integer;\n    procedure SetSortOrder(aSortOrder: Integer);\n    function GetMemoryOrder: Integer;\n    procedure SetMemoryOrder(aSortOrder: Integer);\n    procedure BuildRef;\n    function CompareExchangeFormID(aOldFormID: Cardinal; aNewFormID: Cardinal): Boolean;\n    function GetEditValue: string;\n    procedure SetEditValue(const aValue: string);\n    function GetNativeValue: Variant;\n    procedure SetNativeValue(const aValue: Variant);\n    function GetIsEditable: Boolean;\n    function GetIsRemoveable: Boolean;\n    procedure RequestStorageChange(var aBasePtr, aEndPtr: Pointer; aNewSize: Cardinal);\n    function GetConflictPriority: TwbConflictPriority;\n    function GetConflictPriorityCanChange: Boolean;\n    function GetModified: Boolean;\n    procedure MarkModifiedRecursive;\n    function GetIsInjected: Boolean;\n    function GetReferencesInjected: Boolean;\n    function GetInjectionSourceFiles: TDynFiles;\n    function GetIsNotReachable: Boolean;\n    function GetDataSize: Integer;\n    procedure SetDataSize(aSize: Integer);\n    procedure MergeStorage(var aBasePtr: Pointer; aEndPtr: Pointer);\n    procedure InformStorage(var aBasePtr: Pointer; aEndPtr: Pointer);\n    procedure AddReferencedFromID(aFormID: Cardinal);\n    function CanContainFormIDs: Boolean;\n    function GetLinksTo: IwbElement;\n    function GetNoReach: Boolean;\n    procedure ReportRequiredMasters(aStrings: TStrings; aAsNew: Boolean; recursive: Boolean = True; initial: Boolean = false);\n    function AddIfMissing(const aElement: IwbElement; aAsNew, aDeepCopy : Boolean; const aPrefixRemove, aPrefix, aSuffix: string): IwbElement;\n    procedure ResetConflict;\n    procedure ResetReachable;\n    function RemoveInjected(aCanRemove: Boolean): Boolean;\n    function GetEditType: TwbEditType;\n    function GetEditInfo: string;\n    function GetDontShow: Boolean;\n    procedure SetToDefault;\n\n    procedure NotifyChanged(aContainer: Pointer);\n\n    function CanAssign(aIndex: Integer; const aElement: IwbElement; aCheckDontShow: Boolean): Boolean;\n    function Assign(aIndex: Integer; const aElement: IwbElement; aOnlySK: Boolean): IwbElement;\n    procedure Remove;\n\n    function HasErrors: Boolean;\n\n    procedure Hide;\n    procedure Show;\n    function GetIsHidden: Boolean;\n\n    procedure MoveUp;\n    procedure MoveDown;\n    function CanMoveUp: Boolean;\n    function CanMoveDown: Boolean;\n\n    procedure NextMember;\n    procedure PreviousMember;\n    function CanChangeMember: Boolean;\n\n    procedure Tag;\n    procedure ResetTags;\n    function IsTagged: Boolean;\n\n    property IsHidden: Boolean\n      read GetIsHidden;\n\n    procedure WriteToStream(aStream: TStream; aResetModified: Boolean);\n\n    function CopyInto(const aFile: IwbFile; AsNew, DeepCopy: Boolean; const aPrefixRemove, aPrefix, aSuffix: string): IwbElement;\n\n    function GetTreeHead: Boolean;              // Is the element expected to be a \"header record\" in the tree navigator\n    function GetTreeBranch: Boolean;            // Is the element expected to show in the tree navigator\n\n    property ElementID: Cardinal\n      read GetElementID;\n    property ElementStates: TwbElementStates\n      read GetElementStates;\n\n    property Container: IwbContainer\n      read GetContainer;\n    property ContainingMainRecord: IwbMainRecord\n      read GetContainingMainRecord;\n    property _File: IwbFile\n      read GetFile;\n    property ReferenceFile: IwbFile\n      read GetReferenceFile;\n    property InjectionSourceFiles: TDynFiles\n      read GetInjectionSourceFiles;\n\n    property ElementType: TwbElementType\n      read GetElementType;\n    property Name: string\n      read GetName;\n    property BaseName: string\n      read GetBaseName;\n    property DisplayName: string\n      read GetDisplayName;\n    property ShortName: string\n      read GetShortName;\n    property Path: string\n      read GetPath;\n    property FullPath: string\n      read GetFullPath;\n    property PathName: string\n      read GetPathName;\n    property Skipped: Boolean\n      read GetSkipped;\n\n    property Value: string\n      read GetValue;\n    property SortKey[aExtended: Boolean]: string\n      read GetSortKey;\n    property Check: string\n      read GetCheck;\n\n    property Modified: Boolean\n      read GetModified;\n    property IsInjected: Boolean\n      read GetIsInjected;\n    property IsNotReachable: Boolean\n      read GetIsNotReachable;\n    property ReferencesInjected: Boolean\n      read GetReferencesInjected;\n\n    property IsEditable: Boolean\n      read GetIsEditable;\n    property EditValue: string\n      read GetEditValue\n      write SetEditValue;\n    property NativeValue: Variant\n      read GetNativeValue\n      write SetNativeValue;\n\n    property IsRemoveable: Boolean\n      read GetIsRemoveable;\n\n    property Def: IwbNamedDef\n      read GetDef;\n    property ValueDef: IwbValueDef\n      read GetValueDef;\n    property ResolvedValueDef: IwbValueDef\n      read GetResolvedValueDef;\n\n    property MemoryOrder: Integer\n      read GetMemoryOrder\n      write SetMemoryOrder;\n    property SortPriority: Integer\n      read GetSortPriority;\n    property SortOrder: Integer\n      read GetSortOrder\n      write SetSortOrder;\n\n    property ConflictPriority: TwbConflictPriority\n      read GetConflictPriority;\n    property ConflictPriorityCanChange: Boolean\n      read GetConflictPriorityCanChange;\n\n    property DataSize: Integer\n      read GetDataSize\n      write SetDataSize;\n\n    property LinksTo: IwbElement\n      read GetLinksTo;\n    property NoReach: Boolean\n      read GetNoReach;\n\n    property EditType: TwbEditType\n      read GetEditType;\n    property EditInfo: string\n      read GetEditInfo;\n\n    property DontShow: Boolean\n      read GetDontShow;\n\n    property TreeHead: Boolean\n      read GetTreeHead;\n\n    property TreeBranch: Boolean\n      read GetTreeBranch;\n  end;\n\n  IwbRecord = interface;\n\n  TwbContainerState = (\n    csInit,\n    csInitOnce,\n    csInitDone,\n    csInitializing,\n    csReseting,\n    csRefsBuild,\n    csAsCreatedEmpty\n  );\n\n  TwbContainerStates = set of TwbContainerState;\n\n  TDynStrings = array of string;\n\n  IwbContainerBase = interface(IwbElement)\n    ['{1484D26A-0F67-41FA-9044-8772E68CBA56}']\n\n    function GetElement(aIndex: Integer): IwbElement;\n    function GetElementCount: Integer;\n    function GetElementByName(const aName: string): IwbElement;\n    function GetRecordBySignature(const aSignature: TwbSignature): IwbRecord;\n    function GetElementByMemoryOrder(aSortOrder: Integer): IwbElement;\n    function GetElementBySignature(const aSignature: TwbSignature): IwbElement;\n    function GetElementBySortOrder(aSortOrder: Integer): IwbElement;\n    function GetAdditionalElementCount: Integer;\n    function GetContainerStates: TwbContainerStates;\n    function GetElementByPath(const aPath: string): IwbElement;\n    function GetElementValue(const aName: string): string;\n    function GetElementExists(const aName: string): Boolean;\n    function GetElementEditValue(const aName: string): string;\n    procedure SetElementEditValue(const aName, aValue: string);\n    function GetElementNativeValue(const aName: string): Variant;\n    procedure SetElementNativeValue(const aName: string; const aValue: Variant);\n    function GetElementLinksTo(const aName: string): IwbElement;\n    function GetElementSortKey(const aName: string; aExtended: Boolean): string;\n\n    procedure AddElement(const aElement: IwbElement);\n    procedure InsertElement(aPos: Integer; const aElement: IwbElement);\n    function RemoveElement(aPos: Integer; aMarkModified: Boolean = False): IwbElement; overload;\n    function RemoveElement(const aElement: IwbElement; aMarkModified: Boolean = False): IwbElement; overload;\n    function RemoveElement(const aName: string): IwbElement; overload;\n    procedure ReverseElements;\n\n    function LastElement: IwbElement;\n\n    function IsElementRemoveable(const aElement: IwbElement): Boolean;\n    function IsElementEditable(const aElement: IwbElement): Boolean;\n\n    function IndexOf(const aElement: IwbElement): Integer;\n\n    function CanElementReset: Boolean;\n\n    function GetAddList: TDynStrings;\n    function Add(const aName: string; aSilent: Boolean = True): IwbElement;\n\n    property Elements[aIndex: Integer]: IwbElement\n      read GetElement; default;\n    property ElementCount: Integer\n      read GetElementCount;\n    property AdditionalElementCount: Integer\n      read GetAdditionalElementCount;\n\n    property ElementByPath[const aPath: string]: IwbElement\n      read GetElementByPath;\n    property ElementValues[const aName: string]: string\n      read GetElementValue;\n    property ElementEditValues[const aName: string]: string\n      read GetElementEditValue\n      write SetElementEditValue;\n    property ElementNativeValues[const aName: string]: Variant\n      read GetElementNativeValue\n      write SetElementNativeValue;\n    property ElementLinksTo[const aName: string]: IwbElement\n      read GetElementLinksTo;\n    property ElementExists[const aName: string]: Boolean\n      read GetElementExists;\n    property ElementSortKeys[const aName: string; aExtended: Boolean]: string\n      read GetElementSortKey;\n\n\n    property ContainerStates: TwbContainerStates\n      read GetContainerStates;\n\n    property ElementByName[const aName: string]: IwbElement\n      read GetElementByName;\n    property RecordBySignature[const aSignature: TwbSignature]: IwbRecord\n      read GetRecordBySignature;\n    property ElementByMemoryOrder[aSortOrder: Integer]: IwbElement\n      read GetElementByMemoryOrder;\n    property ElementBySignature[const aSignature: TwbSignature]: IwbElement\n      read GetElementBySignature;\n    property ElementBySortOrder[aSortOrder: Integer]: IwbElement\n      read GetElementBySortOrder;\n  end;\n\n  IwbContainer = interface(IwbContainerBase)\n    ['{4C4FCDD0-C885-458A-B8F2-EA3EFF8B5EEE}']\n    procedure Bar;\n  end;\n\n  IwbContainerElementRef= interface(IwbContainerBase)\n    ['{4066BCCF-01AA-4638-9C3D-3475CD8D5749}']\n    function ReleaseKeepAlive: IwbContainerElementRef;\n  end;\n\n  IwbKeepAliveRoot = interface(IInterface)\n    ['{D1D2C080-CE73-428F-B88F-BF9503CB8619}']\n    procedure Done;\n  end;\n\n  IwbSortableContainer = interface(IwbContainer)\n    ['{A8A65D99-507C-4D2D-86EF-57BC99E09964}']\n    function GetSorted: Boolean;\n\n    property Sorted: Boolean\n      read GetSorted;\n  end;\n\n  IwbGroupRecord = interface;\n\n  TwbFileState = (\n    fsIsNew,\n    fsIsCompareLoad,\n    fsOnlyHeader,\n    fsIsHardcoded,\n    fsIsGameMaster,\n    fsIsTemporary,\n    fsHasNoFormID\n  );\n\n  TwbFileStates = set of TwbFileState;\n  TwbPluginExtensions = TDynStrings;\n\n  IwbFile = interface(IwbContainer)\n    ['{38AA15A6-F652-45C7-B875-9CB502E5DA92}']\n    function GetFileName: string;\n    function GetUnsavedSince: TDateTime;\n    function GetMaster(aIndex: Integer): IwbFile;\n    function GetMasterCount: Integer;\n    function GetRecordByFormID(aFormID: Cardinal; aAllowInjected: Boolean): IwbMainRecord;\n    function GetRecordByEditorID(const aEditorID: string): IwbMainRecord;\n    function GetLoadOrder: Integer;\n    procedure ForceLoadOrder(aValue: Integer);\n    function GetGroupBySignature(const aSignature: TwbSignature): IwbGroupRecord;\n    function HasGroup(const aSignature: TwbSignature): Boolean;\n    function GetFileStates: TwbFileStates;\n    procedure BuildReachable;\n\n    function LoadOrderFormIDtoFileFormID(aFormID: Cardinal): Cardinal;\n    function FileFormIDtoLoadOrderFormID(aFormID: Cardinal): Cardinal;\n\n    function LoadOrderFileIDtoFileFileID(aFileID: Byte): Byte;\n    function FileFileIDtoLoadOrderFileID(aFileID: Byte): Byte;\n\n    function NewFormID: Cardinal;\n\n    procedure AddMasters(aMasters: TStrings);\n    procedure AddMasterIfMissing(const aMaster: string);\n    procedure SortMasters;\n    procedure CleanMasters;\n\n    function GetRecord(aIndex: Integer): IwbMainRecord;\n    function GetRecordCount: Integer;\n    function GetHeader: IwbMainRecord;\n\n    function GetIsESM: Boolean;\n    procedure SetIsESM(Value: Boolean);\n\n    function GetIsLocalized: Boolean;\n    procedure SetIsLocalized(Value: Boolean);\n\n    function GetNextObjectID: Cardinal;\n    procedure SetNextObjectID(aObjectID: Cardinal);\n\n    function GetIsNotPlugin: Boolean;\n    function GetHasNoFormID: Boolean;\n    procedure SetHasNoFormID(Value: Boolean);\n\n    property FileName: string\n      read GetFileName;\n    property UnsavedSince: TDateTime\n      read GetUnsavedSince;\n\n    function HasMaster(const aFileName: string): Boolean;\n    property Masters[aIndex: Integer]: IwbFile\n      read GetMaster;\n    property MasterCount: Integer\n      read GetMasterCount;\n\n    property RecordByFormID[aFormID: Cardinal; aAllowInjected: Boolean]: IwbMainRecord\n      read GetRecordByFormID;\n    property RecordByEditorID[const aEditorID: string]: IwbMainRecord\n      read GetRecordByEditorID;\n     property GroupBySignature[const aSignature: TwbSignature]: IwbGroupRecord\n      read GetGroupBySignature;\n\n    property Records[aIndex: Integer]: IwbMainRecord\n      read GetRecord;\n    property RecordCount: Integer\n      read GetRecordCount;\n\n    property Header: IwbMainRecord\n      read GetHeader;\n\n    property LoadOrder: Integer\n      read GetLoadOrder;\n\n    property FileStates: TwbFileStates\n      read GetFileStates;\n\n    property IsESM: Boolean\n      read GetIsESM\n      write SetIsESM;\n\n    property IsLocalized: Boolean\n      read GetIsLocalized\n      write SetIsLocalized;\n\n    property NextObjectID: Cardinal\n      read GetNextObjectID\n      write SetNextObjectID;\n\n    property IsNotPlugin: Boolean   // Save or other file to display.\n      read GetIsNotPlugin;\n    property HasNoFormID: Boolean   // Like Morrowind for example. Also true for save/coSave.\n      read GetHasNoFormID\n      write SetHasNoFormID;\n  end;\n\n  IwbDataContainer = interface(IwbContainer)\n    ['{6E547F7C-87E4-4917-8F43-4D3CEE5AFE8C}']\n    function GetDataBasePtr: Pointer;\n    function GetDataEndPtr: Pointer;\n    function GetDataSize: Integer;\n    function GetDontCompare: Boolean;\n    function GetDontSave: Boolean;\n    function IsValidOffset(aBasePtr, aEndPtr: Pointer; anOffset: Integer): Boolean;\n    function IsLocalOffset(anOffset: Integer): Boolean;\n\n    property DataBasePtr: Pointer\n      read GetDataBasePtr;\n    property DataEndPtr: Pointer\n      read GetDataEndPtr;\n    property DataSize: Integer\n      read GetDataSize;\n\n    property DontCompare: Boolean\n      read GetDontCompare;\n    property DontSave: Boolean\n      read GetDontSave;\n  end;\n\n  TDynDataContainers = array of IwbDataContainer;\n\n  IwbRecord = interface(IwbDataContainer)\n    ['{4FC53881-25E2-421D-8AF6-F589979767E6}']\n    function GetSignature: TwbSignature;\n\n    property Signature: TwbSignature\n      read GetSignature;\n  end;\n\n  IwbHasSignature = interface(IwbElement)\n    ['{DF563D7C-A441-4864-B47A-49F3A96508F7}']\n    function GetSignature: TwbSignature;\n\n    property Signature: TwbSignature\n      read GetSignature;\n  end;\n\n  PwbMainRecordStructFlags = ^TwbMainRecordStructFlags;\n  TwbMainRecordStructFlags = packed record\n    _Flags: Cardinal;\n    function IsESM: Boolean; inline;\n    function IsDeleted: Boolean; inline;\n    function IsLocalized: Boolean; inline;\n    function CastsShadows: Boolean; inline;\n    function IsPersistent: Boolean; inline;\n    function IsInitiallyDisabled: Boolean; inline;\n    function IsIgnored: Boolean; inline;\n    function IsVisibleWhenDistant: Boolean; inline;\n    function IsDangerous: Boolean; inline;\n    function IsCompressed: Boolean; inline;\n    function CantWait: Boolean; inline;\n    function HasLODtree: Boolean; inline;\n\n    procedure SetESM(aValue: Boolean);\n    procedure SetDeleted(aValue: Boolean);\n    procedure SetLocalized(aValue: Boolean);\n    procedure SetPersistent(aValue: Boolean);\n    procedure SetCompressed(aValue: Boolean);\n    procedure SetInitiallyDisabled(aValue: Boolean);\n    procedure SetVisibleWhenDistant(aValue: Boolean);\n  end;\n\n  PwbMainRecordStructFlags3 = ^TwbMainRecordStructFlags3;\n  TwbMainRecordStructFlags3 = packed record\n    _Flags: Cardinal;\n  end;\n\n  TwbVector = packed record\n    x: Single;\n    y: Single;\n    z: Single;\n  end;\n\n  TwbGridCell = record\n    x, y: Integer;\n  end;\n\n  TDynMainRecords = array of IwbMainRecord;\n\n  IwbMainRecord = interface(IwbRecord)\n    ['{F06FD5E2-621D-4422-BA00-CB3CA72B3691}']\n    function GetFormID: Cardinal;\n    function GetFixedFormID: Cardinal;\n    function GetLoadOrderFormID: Cardinal;\n    procedure SetLoadOrderFormID(aFormID: Cardinal);\n    function GetEditorID: string;\n    function GetCanHaveEditorID: Boolean;\n    procedure SetEditorID(const aValue: string);\n    function GetFullName: string;\n    function GetDisplayNameKey: string;\n    function GetMaster: IwbMainRecord;\n    function GetIsMaster: Boolean;\n    function GetMasterOrSelf: IwbMainRecord;\n    function GetOverride(aIndex: Integer): IwbMainRecord;\n    function GetOverrideCount: Integer;\n    procedure AddReferencedBy(aMainRecord: IwbMainRecord);\n    procedure RemoveReferencedBy(aMainRecord: IwbMainRecord);\n    function GetReferencedBy(aIndex: Integer): IwbMainRecord;\n    function GetReferencedByCount: Integer;\n    function GetIsWinningOverride: Boolean;\n    function GetWinningOverride: IwbMainRecord;\n    function GetHighestOverrideOrSelf(aMaxLoadOrder: Integer): IwbMainRecord;\n    function GetFlags: TwbMainRecordStructFlags;\n    function GetChildGroup: IwbGroupRecord;\n    function EnsureChildGroup: IwbGroupRecord;\n    function GetBaseRecord: IwbMainRecord;\n    function GetBaseRecordID: Cardinal;\n\n    function GetConflictAll: TConflictAll;\n    procedure SetConflictAll(aValue: TConflictAll);\n    function GetConflictThis: TConflictThis;\n    procedure SetConflictThis(aValue: TConflictThis);\n\n    function GetIsESM: Boolean;\n    procedure SetIsESM(aValue: Boolean);\n    function GetIsPersistent: Boolean;\n    procedure SetIsPersistent(aValue: Boolean);\n    function GetIsDeleted: Boolean;\n    procedure SetIsDeleted(aValue: Boolean);\n    function GetIsLocalized: Boolean;\n    procedure SetIsLocalized(aValue: Boolean);\n    function GetIsCompressed: Boolean;\n    procedure SetIsCompressed(aValue: Boolean);\n    function GetIsVisibleWhenDistant: Boolean;\n    procedure SetIsVisibleWhenDistant(aValue: Boolean);\n    function GetHasVisibleWhenDistantMesh: Boolean;\n    function GetHasMesh: Boolean;\n    function GetHasPrecombinedMesh: Boolean;\n    function GetPrecombinedMesh: string;\n    function GetIsInitiallyDisabled: Boolean;\n    procedure SetIsInitiallyDisabled(aValue: Boolean);\n\n    procedure UpdateRefs;\n\n    function GetPosition(out aPosition: TwbVector): Boolean;\n    function SetPosition(const aPosition: TwbVector): Boolean;\n    function GetRotation(out aRotation: TwbVector): Boolean;\n    function GetScale(out aScale: Single): Boolean;\n\n    function GetGridCell(out aGridCell: TwbGridCell): Boolean;\n\n    procedure Delete;\n    procedure DeleteInto(const aFile: IwbFile);\n\n    function MasterRecordsFromMasterFilesAndSelf: TDynMainRecords;\n\n    function GetFormVersion: Cardinal;\n    procedure SetFormVersion(aFormVersion: Cardinal);\n\n    procedure ChangeFormSignature(aSignature: TwbSignature);\n    procedure ClampFormID(aIndex: Cardinal);\n\n    property Version: Cardinal\n      read GetFormVersion\n      write SetFormVersion;\n\n    property BaseRecord: IwbMainRecord\n      read GetBaseRecord;\n    property BaseRecordID: Cardinal\n      read GetBaseRecordID;\n    property FormID: Cardinal\n      read GetFormID;\n    property FixedFormID: Cardinal\n      read GetFixedFormID;\n    property LoadOrderFormID: Cardinal\n      read GetLoadOrderFormID\n      write SetLoadOrderFormID;\n    property EditorID: string\n      read GetEditorID\n      write SetEditorID;\n    property CanHaveEditorID: Boolean\n      read GetCanHaveEditorID;\n    property FullName: string\n      read GetFullName;\n    property DisplayNameKey: string\n      read GetDisplayNameKey;\n\n    property Flags: TwbMainRecordStructFlags\n      read GetFlags;\n\n    property Master: IwbMainRecord\n      read GetMaster;\n    property MasterOrSelf: IwbMainRecord\n      read GetMasterOrSelf;\n    property IsMaster: Boolean\n      read GetIsMaster;\n\n    property ChildGroup: IwbGroupRecord\n      read GetChildGroup;\n\n    property Overrides[aIndex: Integer]: IwbMainRecord\n      read GetOverride;\n    property OverrideCount: Integer\n      read GetOverrideCount;\n    property IsWinningOverride: Boolean\n      read GetIsWinningOverride;\n    property WinningOverride: IwbMainRecord\n      read GetWinningOverride;\n    property HighestOverrideOrSelf[aMaxLoadOrder: Integer]: IwbMainRecord\n      read GetHighestOverrideOrSelf;\n\n    property ReferencedBy[aIndex: Integer]: IwbMainRecord\n      read GetReferencedBy;\n    property ReferencedByCount: Integer\n      read GetReferencedByCount;\n\n    property IsESM: Boolean\n      read GetIsESM\n      write SetIsESM;\n    property IsPersistent: Boolean\n      read GetIsPersistent\n      write SetIsPersistent;\n    property IsDeleted: Boolean\n      read GetIsDeleted\n      write SetIsDeleted;\n    property IsCompressed: Boolean\n      read GetIsCompressed\n      write SetIsCompressed;\n    property IsLocalized: Boolean\n      read GetIsLocalized\n      write SetIslocalized;\n    property IsVisibleWhenDistant: Boolean\n      read GetIsVisibleWhenDistant\n      write SetIsVisibleWhenDistant;\n    property HasVisibleWhenDistantMesh: Boolean\n      read GetHasVisibleWhenDistantMesh;\n    property HasMesh: Boolean\n      read GetHasMesh;\n    property HasPrecombinedMesh: Boolean\n      read GetHasPrecombinedMesh;\n    property PrecombinedMesh: string\n      read GetPrecombinedMesh;\n    property IsInitiallyDisabled: Boolean\n      read GetIsInitiallyDisabled\n      write SetIsInitiallyDisabled;\n\n    property ConflictAll: TConflictAll\n      read GetConflictAll\n      write SetConflictAll;\n    property ConflictThis: TConflictThis\n      read GetConflictThis\n      write SetConflictThis;\n  end;\n\n  IwbFileHeader = interface(IwbDataContainer)\n    ['{E309EEE2-C20E-4506-BF46-B63F903706C9}']\n    function GetFileMagic: TwbFileMagic;\n\n    property FileMagic: TwbFileMagic\n      read GetFileMagic;\n  end;\n\n  IwbChapter = interface\n    ['{3E575648-EF6F-4e9f-956F-D2E184B670E4}']\n    function GetChapterType: Integer;\n    function GetChapterTypeName: String;\n    function GetChapterName: String;\n    property ChapterType: Integer\n      read GetChapterType;\n    property ChapterTypeName: String\n      read GetChapterTypeName;\n    property ChapterName: String\n      read GetChapterName;\n  end;\n\n  TDynElements = array of IwbElement;\n  {$IFDEF WIN32}\n  TDynCardinalArray = array of Cardinal;\n  {$ENDIF WIN32}\n  {$IFDEF WIN64}\n  TDynCardinalArray = array of UInt64;\n  {$ENDIF WIN32}\n\n  IwbSubRecord = interface(IwbRecord)\n    ['{CDE36A3D-64F6-4B8E-980E-FBAB8D9FCAF7}']\n    function GetSubRecordHeaderSize: Integer;\n    property SubRecordHeaderSize: Integer\n      read GetSubRecordHeaderSize;\n  end;\n\n  TDynGroupRecords = array of IwbGroupRecord;\n\n  IwbGroupRecord = interface(IwbRecord)\n    ['{BFF16E47-4E66-4EAD-9BEF-364728AE0A6B}']\n    function GetGroupType: Integer;\n    function GetGroupLabel: Cardinal;\n    procedure SetGroupLabel(aLabel: Cardinal);\n    function GetChildrenOf: IwbMainRecord;\n\n    function FindChildGroup(aType: Integer; aMainRecord: IwbMainRecord): IwbGroupRecord;\n\n    function GetMainRecordByEditorID(const aEditorID: string): IwbMainRecord;\n    function GetMainRecordByFormID(const aFormID: Cardinal): IwbMainRecord;\n\n    procedure AddElement(const aElement: IwbElement);\n\n    property GroupType: Integer\n      read GetGroupType;\n    property GroupLabel: Cardinal\n      read GetGroupLabel\n      write SetGroupLabel;\n\n    property ChildrenOf: IwbMainRecord\n      read GetChildrenOf;\n\n    property MainRecordByEditorID[const aEditorID: string]: IwbMainRecord\n      read GetMainRecordByEditorID;\n    property MainRecordByFormID[const aFormID: Cardinal]: IwbMainRecord\n      read GetMainRecordByFormID;\n  end;\n\n  IwbSubRecordArray = interface\n    ['{26937F7A-5F31-4D65-932F-038BD0FA9FEF}']\n  end;\n\n  IwbSubRecordStruct = interface\n    ['{E8C496D3-D396-4685-87EC-82E1FD2588B8}']\n  end;\n\n  IwbSubRecordUnion = interface\n    ['{11959F58-B396-4449-9D9D-5DF1251C3E76}']\n  end;\n\n  TwbCallbackType = (\n    ctToStr,\n    ctToSortKey,\n    ctCheck,\n    ctToEditValue,\n    ctEditType,\n    ctEditInfo\n  );\n\n  TwbAfterLoadCallback = procedure(const aElement: IwbElement);\n  TwbAfterSetCallback = procedure(const aElement: IwbElement; const aOldValue, aNewValue: Variant);\n  TwbDontShowCallback = function(const aElement: IwbElement): Boolean;\n  TwbFloatNormalizer = function(const aElement: IwbElement; aFloat: Extended): Extended;\n  TwbGetConflictPriority = procedure(const aElement: IwbElement; var aConflictPriority: TwbConflictPriority);\n  TwbIntToStrCallback = function(aInt: Int64; const aElement: IwbElement; aType: TwbCallbackType): string;\n  TwbStrToIntCallback = function(const aString: string; const aElement: IwbElement): Int64;\n  TwbAddInfoCallback = function(const aMainRecord: IwbMainRecord): string;\n  TwbUnionDecider = function(aBasePtr: Pointer; aEndPtr: Pointer; const aElement: IwbElement): Integer;\n  TwbIntegerDefFormaterUnionDecider = function(const aElement: IwbElement): Integer;\n  TwbIsSortedCallback = function(const aContainer: IwbContainer): Boolean;\n  TwbCountCallback = function(aBasePtr: Pointer; aEndPtr: Pointer; const aElement: IwbElement): Cardinal;\n  TwbSizeCallback = function(aBasePtr: Pointer; aEndPtr: Pointer; const aElement: IwbElement;var CompressedSize: Integer): Cardinal;\n  TwbGetChapterTypeCallback = function(aBasePtr: Pointer; aEndPtr: Pointer; const aElement: IwbElement): Integer;\n  TwbGetChapterTypeNameCallback = function(aBasePtr: Pointer; aEndPtr: Pointer; const aElement: IwbElement): String;\n  TwbGetChapterNameCallback = function(aBasePtr: Pointer; aEndPtr: Pointer; const aElement: IwbElement): String;\n\n  IwbNamedDef = interface(IwbDef)\n    ['{F8FEDE89-C089-42C5-B587-49A7D87055F0}']\n    function GetName: string;\n    function GetPath: string;\n    procedure AfterLoad(const aElement: IwbElement);\n    procedure AfterSet(const aElement: IwbElement; const aOldValue, aNewValue: Variant);\n\n    function GetTreeHead: Boolean;              // Is the element expected to be a \"header record\" in the tree navigator\n    procedure SetTreeHead(aValue: Boolean);     // Make the element a \"header record\" in the tree navigator;\n    function GetTreeBranch: Boolean;            // Is the element included in a \"leaf\" expected to be displayed in the view pane\n    procedure SetTreeBranch(aValue: Boolean);   // Make the element included in a \"leaf\" visible in the tree navigator;\n\n    property Name: string\n      read GetName;\n    property Path: string\n      read GetPath;\n\n    property TreeHead: Boolean\n      read GetTreeHead write SetTreeHead;\n\n    property TreeBranch: Boolean\n      read GetTreeBranch write SetTreeBranch;\n  end;\n\n  IwbSignatureDef = interface(IwbNamedDef)\n    ['{EF20E1A2-8719-4934-AC36-C91DC72C3F70}']\n    function GetDefaultSignature: TwbSignature;\n\n    function GetSignatures(const aIndex: Integer): TwbSignature;\n    function GetSignatureCount: Integer;\n\n    function CanHandle(aSignature     : TwbSignature;\n                 const aDataContainer : IwbDataContainer)\n                                      : Boolean;\n\n    property DefaultSignature: TwbSignature\n      read GetDefaultSignature;\n\n    property Signatures[const aIndex: Integer]: TwbSignature\n      read GetSignatures;\n    property SignatureCount: Integer\n      read GetSignatureCount;\n  end;\n\n  IwbRecordMemberDef = interface;\n\n  IwbStructDef = interface;\n\n  PwbRecordDef = ^IwbRecordDef;\n  IwbRecordDef = interface(IwbSignatureDef)\n    ['{89FE380F-7A0B-493C-AA9E-08957A4C167B}']\n    function ContainsMemberFor(aSignature     : TwbSignature;\n                         const aDataContainer : IwbDataContainer)\n                                              : Boolean;\n    function GetMemberFor(aSignature     : TwbSignature;\n                    const aDataContainer : IwbDataContainer)\n                                         : IwbRecordMemberDef;\n    function GetMemberIndexFor(aSignature     : TwbSignature;\n                         const aDataContainer : IwbDataContainer)\n                                              : Integer;\n\n    function AllowUnordered: Boolean;\n    function AdditionalInfoFor(const aMainRecord: IwbMainRecord): string;\n\n    function GetMember(aIndex: Integer): IwbRecordMemberDef;\n    function GetMemberCount: Integer;\n\n    function GetSkipSignature(const aSignature: TwbSignature): Boolean;\n\n    function GetQuickInitLimit: Integer;\n    function GetContainsEditorID: Boolean;\n\n    function GetRecordHeaderStruct: IwbStructDef;\n\n    property Members[aIndex: Integer]: IwbRecordMemberDef read GetMember;\n    property MemberCount: Integer read GetMemberCount;\n\n    property SkipSignature[const aSignature: TwbSignature]: Boolean\n      read GetSkipSignature;\n\n    property QuickInitLimit: Integer\n      read GetQuickInitLimit;\n    property ContainsEditorID: Boolean\n      read GetContainsEditorID;\n\n    property RecordHeaderStruct: IwbStructDef\n      read GetRecordHeaderStruct;\n  end;\n\n  IwbHasSortKeyDef = interface(IwbRecordDef)\n    ['{877FEF58-72B1-4735-9E08-166B5F4043F3}']\n    function GetSortKey(aIndex: Integer; aExtended: Boolean): Integer;\n    function GetSortKeyCount(aExtended: Boolean): Integer;\n    function IsInSK(aIndex: Integer): Boolean;\n\n    property SortKeys[aIndex: Integer; aExtended: Boolean]: Integer\n      read GetSortKey;\n    property SortKeyCount[aExtended: Boolean]: Integer\n      read GetSortKeyCount;\n  end;\n\n  IwbRecordMemberDef = interface(IwbSignatureDef)\n    ['{259F3F08-F4ED-439D-8C1A-48137C84E52A}']\n  end;\n\n  TwbUsedMasters = array[Byte] of Boolean;\n  PwbUsedMasters = ^TwbUsedMasters;\n\n  IwbValueDef = interface(IwbNamedDef)\n    ['{BBF684A6-0EE5-4EF6-83DD-D323A0D2919A}']\n    function ToString(aBasePtr, aEndPtr: Pointer; const aElement: IwbElement): string;\n    function ToSortKey(aBasePtr, aEndPtr: Pointer; const aElement: IwbElement; aExtended: Boolean): string;\n    function Check(aBasePtr, aEndPtr: Pointer; const aElement: IwbElement): string;\n    function GetSize(aBasePtr, aEndPtr: Pointer; const aElement: IwbElement): Integer;\n    function GetDefaultSize(aBasePtr, aEndPtr: Pointer; const aElement: IwbElement): Integer;\n    function GetLinksTo(aBasePtr, aEndPtr: Pointer; const aElement: IwbElement): IwbElement;\n    procedure BuildRef(aBasePtr, aEndPtr: Pointer; const aElement: IwbElement);\n    function GetIsVariableSize: Boolean;\n    function GetCanBeZeroSize: Boolean;\n    function ToEditValue(aBasePtr, aEndPtr: Pointer; const aElement: IwbElement): string;\n    procedure FromEditValue(aBasePtr, aEndPtr: Pointer; const aElement: IwbElement; const aValue: string);\n    function ToNativeValue(aBasePtr, aEndPtr: Pointer; const aElement: IwbElement): Variant;\n    procedure FromNativeValue(aBasePtr, aEndPtr: Pointer; const aElement: IwbElement; const aValue: Variant);\n    function GetIsEditable(aBasePtr, aEndPtr: Pointer; const aElement: IwbElement): Boolean;\n    function GetEditType(aBasePtr, aEndPtr: Pointer; const aElement: IwbElement): TwbEditType;\n    function GetEditInfo(aBasePtr, aEndPtr: Pointer; const aElement: IwbElement): string;\n    function SetToDefault(aBasePtr, aEndPtr: Pointer; const aElement: IwbElement): Boolean;\n\n    procedure MasterCountUpdated(aBasePtr, aEndPtr: Pointer; const aElement: IwbElement; aOld, aNew: Byte);\n    procedure MasterIndicesUpdated(aBasePtr, aEndPtr: Pointer; const aElement: IwbElement; const aOld, aNew: TBytes);\n    procedure FindUsedMasters(aBasePtr, aEndPtr: Pointer; const aElement: IwbElement; aMasters: PwbUsedMasters);\n    function CompareExchangeFormID(aBasePtr, aEndPtr: Pointer; const aElement: IwbElement; aOldFormID: Cardinal; aNewFormID: Cardinal): Boolean;\n\n    function GetElementMap: TDynCardinalArray;\n\n    property Size[aBasePtr, aEndPtr: Pointer; const aElement: IwbElement]: Integer\n      read GetSize;\n    property DefaultSize[aBasePtr, aEndPtr: Pointer; const aElement: IwbElement]: Integer\n      read GetDefaultSize;\n    property IsVariableSize: Boolean\n      read GetIsVariableSize;\n    property CanBeZeroSize: Boolean\n      read GetCanBeZeroSize;\n    property IsEditable[aBasePtr, aEndPtr: Pointer; const aElement: IwbElement]: Boolean\n      read GetIsEditable;\n    property EditValue[aBasePtr, aEndPtr: Pointer; const aElement: IwbElement]: string\n      read ToEditValue\n      write FromEditValue;\n    property NativeValue[aBasePtr, aEndPtr: Pointer; const aElement: IwbElement]: Variant\n      read ToNativeValue\n      write FromNativeValue;\n    property LinksTo[aBasePtr, aEndPtr: Pointer; const aElement: IwbElement]: IwbElement\n      read GetLinksTo;\n\n    property EditType[aBasePtr, aEndPtr: Pointer; const aElement: IwbElement]: TwbEditType\n      read GetEditType;\n    property EditInfo[aBasePtr, aEndPtr: Pointer; const aElement: IwbElement]: string\n      read GetEditInfo;\n  end;\n\n  IwbSubRecordDef = interface(IwbRecordMemberDef)\n    ['{D848E426-8768-45F4-B192-4DEFBE34D40A}']\n    function GetValue: IwbValueDef;\n    procedure HasUnusedData;\n\n    property Value: IwbValueDef read GetValue;\n  end;\n\n  IwbSubRecordArrayDef = interface(IwbRecordMemberDef)\n    ['{67943BAC-B558-4112-8DBC-C94A44E0B1D1}']\n    function GetElement: IwbRecordMemberDef;\n    function GetSorted(const aContainer: IwbContainer): Boolean;\n\n    property Element: IwbRecordMemberDef read GetElement;\n    property Sorted[const aContainer: IwbContainer]: Boolean read GetSorted;\n  end;\n\n  IwbSubRecordStructDef = interface(IwbRecordMemberDef)\n    ['{B5441812-5229-488B-AEA6-C182CEBED441}']\n  end;\n\n  IwbSubRecordUnionDef = interface(IwbRecordMemberDef)\n    ['{BC66ABFF-3108-4C64-B416-674A2A8F297D}']\n  end;\n\n  IwbUnionDef = interface(IwbValueDef)\n    ['{04D6B7BA-B457-4E43-9910-592395FEA0D6}']\n    function Decide(aBasePtr: Pointer; aEndPtr: Pointer; const aElement: IwbElement): IwbValueDef;\n\n    function GetMember(aIndex: Integer): IwbValueDef;\n    function GetMemberCount: Integer;\n\n    property Members[aIndex: Integer]: IwbValueDef read GetMember;\n    property MemberCount: Integer read GetMemberCount;\n  end;\n\n  IwbStringDef = interface(IwbValueDef)\n    ['{37B02D28-EDB4-41C6-B933-9F56C013A88A}']\n    function GetStringSize: Integer;\n\n    property StringSize: Integer\n      read GetStringSize;\n  end;\n\n  IwbLenStringDef = interface(IwbValueDef)\n    ['{1AD7FAE2-DAA7-4651-B78D-10E138EDF48B}']\n  end;\n\n  IwbByteArrayDef = interface(IwbValueDef)\n    ['{3069E1AC-4307-421B-93E4-797E18075EF9}']\n  end;\n\n  IwbEmptyDef = interface(IwbValueDef)\n    ['{0A858744-947B-4B6E-9972-D8BF5398C87C}']\n    function GetSorted: Boolean;\n\n    property Sorted: Boolean\n      read GetSorted;\n  end;\n\n  IwbIntegerDefFormater = interface;\n\n  IwbIntegerDef = interface(IwbValueDef)\n    ['{00A270B0-ACFC-444C-A7E8-A577BD40704E}']\n    function ToInt(aBasePtr, aEndPtr: Pointer; const aElement: IwbElement): Int64;\n    procedure FromInt(aValue: Int64; aBasePtr, aEndPtr: Pointer; const aElement: IwbElement);\n\n    function GetFormater(const aElement: IwbElement): IwbIntegerDefFormater;\n    function GetFormaterCanChange: Boolean;\n    function GetIntType: TwbIntType;\n    function GetExpectedLength(aValue: Int64 = 0): Integer;\n\n    property Formater[const aElement: IwbElement]: IwbIntegerDefFormater\n      read GetFormater;\n    property FormaterCanChange: Boolean\n      read GetFormaterCanChange;\n    property IntType: TwbIntType\n      read GetIntType;\n\n    property ExpectedLength[aValue: Int64 = 0]: Integer\n      read GetExpectedLength;\n  end;\n\n  IwbInternalIntegerDef = interface(IwbIntegerDef)\n    ['{16A15EF7-6295-4817-BA94-CDD7E8C1CF8B}']\n    procedure ReplaceFormater(const aFormater: IwbIntegerDefFormater);\n  end;\n\n  IwbFloatDef = interface(IwbValueDef)\n    ['{29F116C6-0208-4D55-ACA7-2A9BB17BF80B}']\n  end;\n\n  IwbArrayDef = interface(IwbValueDef)\n    ['{BD195F99-4AC3-4BD0-9193-267332E97D79}']\n    function GetElement: IwbValueDef;\n    function GetCount: Integer;\n    function GetElementLabel(aIndex: Integer): string;\n    function GetSorted: Boolean;\n    function GetCanAddTo: Boolean;\n    function GetCountCallBack: TwbCountCallback;\n    function GetPrefixSize(aBasePtr: Pointer): Integer;\n    function GetPrefixLength(aBasePtr: Pointer): Integer;\n    function GetPrefixCount(aBasePtr: Pointer): Cardinal;\n    procedure SetPrefixCount(aBasePtr: Pointer; aCount: Cardinal);\n\n    property Element: IwbValueDef\n      read GetElement;\n    property ElementCount: Integer\n      read GetCount;\n\n    property ElementLabel[aIndex: Integer]: string\n      read GetElementLabel;\n\n    property Sorted: Boolean\n      read GetSorted;\n\n    property CountCallBack: TwbCountCallback\n      read GetCountCallback;\n\n    property CanAddTo: Boolean\n      read GetCanAddTo;\n\n    property PrefixSize[aBasePtr: Pointer]: Integer    // how many bytes of storage for the prefix\n      read GetPrefixSize;\n    property PrefixLength[aBasePtr: Pointer]: Integer  // Integer size of the prefix\n      read GetPrefixLength;\n    property PrefixCount[aBasePtr: Pointer]: Cardinal  // Value stored in the prefix\n      read GetPrefixCount write SetPrefixCount;\n  end;\n\n  IwbStructDef = interface(IwbValueDef)\n    ['{9B20A03C-BC3F-433A-9781-E46BD5C660A9}']\n\n    function GetMemberCount: Integer;\n    function GetMember(aIndex: Integer): IwbValueDef;\n    function GetMemberByName(const aName: string): IwbValueDef;\n    function GetOptionalFromElement: Integer;\n\n    property MemberCount: Integer read GetMemberCount;\n    property Members[aIndex: Integer]: IwbValueDef read GetMember;\n    property MembersByName[const aName: string]: IwbValueDef read GetMemberByName;\n    property OptionalFromElement: Integer read GetOptionalFromElement;\n  end;\n\n  IwbStructCDef = interface(IwbStructDef)\n    ['{B72FD1AD-018D-47D3-91E7-5028C5E0E759}']\n    function GetSizing(aBasePtr: Pointer; aEndPtr: Pointer; const aElement: IwbElement;var CompressedSize: Integer): Cardinal;\n    function GetChapterType(aBasePtr: Pointer; aEndPtr: Pointer; const aElement: IwbElement): Integer;\n    function GetChapterTypeName(aBasePtr: Pointer; aEndPtr: Pointer; const aElement: IwbElement): String;\n    function GetChapterName(aBasePtr: Pointer; aEndPtr: Pointer; const aElement: IwbElement): String;\n  end;\n\n  TwbStructCompression = (\n    scNone,\n    scZComp,\n    scLZComp\n  );\n\n  IwbStructZDef = interface(IwbStructCDef) // Compressible structure !!! NOT SAFE FOR EDIT AT THE MOMEMNT !!!\n    ['{8ED8E461-E4BB-494E-8A3B-B352A245B9A0}']\n  end;\n\n  IwbStructLZDef = interface(IwbStructZDef) // Compressible structure using LZ4 !!! NOT SAFE FOR EDIT AT THE MOMEMNT !!!\n    ['{A5AB100F-83CA-4B53-B3CD-2BF926210900}']\n  end;\n\n  IwbIntegerDefFormater = interface(IwbDef)\n    ['{56A6EB7B-3A90-4F09-8E80-D7399569DFCC}']\n\n    function ToString(aInt: Int64; const aElement: IwbElement): string;\n    function ToSortKey(aInt: Int64; const aElement: IwbElement): string;\n    function Check(aInt: Int64; const aElement: IwbElement): string;\n    procedure BuildRef(aInt: Int64; const aElement: IwbElement);\n\n    function GetEditType(aInt: Int64; const aElement: IwbElement): TwbEditType;\n    function GetEditInfo(aInt: Int64; const aElement: IwbElement): string;\n\n    function ToEditValue(aInt: Int64; const aElement: IwbElement): string;\n    function FromEditValue(const aValue: string; const aElement: IwbElement): Int64;\n    function GetIsEditable(aInt: Int64; const aElement: IwbElement): Boolean;\n    function GetLinksTo(aInt: Int64; const aElement: IwbElement): IwbElement;\n\n    function CanAssign(const aElement: IwbElement; aIndex: Integer; const aDef: IwbDef): Boolean;\n\n    function MasterCountUpdated(aInt: Int64; aOld, aNew: Byte; const aElement: IwbElement): Int64;\n    function MasterIndicesUpdated(aInt: Int64; const aOld, aNew: TBytes; const aElement: IwbElement): Int64;\n    procedure FindUsedMasters(aInt: Int64; aMasters: PwbUsedMasters; const aElement: IwbElement);\n    function CompareExchangeFormID(var aInt: Int64; aOldFormID: Cardinal; aNewFormID: Cardinal; const aElement: IwbElement): Boolean;\n\n    function GetRequiresKey: Boolean;\n\n    property IsEditable[aInt: Int64; const aElement: IwbElement]: Boolean\n      read GetIsEditable;\n    property LinksTo[aInt: Int64; const aElement: IwbElement]: IwbElement\n      read GetLinksTo;\n\n    property EditType[aInt: Int64; const aElement: IwbElement]: TwbEditType\n      read GetEditType;\n    property EditInfo[aInt: Int64; const aElement: IwbElement]: string\n      read GetEditInfo;\n\n    property RequiresKey: Boolean\n      read GetRequiresKey;\n  end;\n\n  IwbIntegerDefFormaterUnion = interface(IwbIntegerDefFormater)\n    ['{C04B1181-A570-41AE-A31E-7977B722EE0A}']\n    function Decide(const aElement: IwbElement): IwbIntegerDefFormater;\n\n    function GetMember(aIndex: Integer): IwbIntegerDefFormater;\n    function GetMemberCount: Integer;\n\n    property Members[aIndex: Integer]: IwbIntegerDefFormater read GetMember;\n    property MemberCount: Integer read GetMemberCount;\n  end;\n\n  IwbDumpIntegerDefFormater = interface(IwbIntegerDefFormater)\n    ['{9767F3EF-0E6F-45FB-AC9F-31A9B4312760}']\n  end;\n\n  IwbFormID = interface(IwbIntegerDefFormater)\n    ['{71C4A255-B983-488C-9837-0A720132348A}']\n    function GetMainRecord(aInt: Int64; const aElement: IwbElement): IwbMainRecord;\n  end;\n\n  IwbRefID = interface(IwbFormID)\n    ['{F6EEAFDD-5AD7-4DB3-BF45-5D5DB53465D4}']\n  end;\n\n  IwbFormIDChecked = interface(IwbFormID)\n    ['{DC7CBC9F-07EC-430B-94EE-ECE1867A2660}']\n    function GetSignature(aIndex: Integer): TwbSignature;\n    function GetSignatureCount: Integer;\n\n    property Signatures[aIndex: Integer]: TwbSignature\n      read GetSignature;\n    property SignatureCount: Integer\n      read GetSignatureCount;\n  end;\n\n  IwbChar4 = interface(IwbIntegerDefFormater)\n    ['{CF657B3A-E7A6-48FE-AC68-8DF15962A531}']\n  end;\n\n  IwbStr4 = interface(IwbIntegerDefFormater)\t// 4 bytes strings stored as itU32 \n    ['{2DC5200E-C1F1-47e7-A927-3D110D59F55A}']\n  end;  // The interface handles swaping the character in readable order\n\n  IwbFlagsDef = interface;\n\n  IwbFlagDef = interface(IwbValueDef)\n    ['{CCD4FBC4-D1CA-4B91-9E2F-6EE6118D5D07}']\n    function GetFlagsDef: IwbFlagsDef;\n    function GetFlagIndex: Integer;\n\n    property FlagsDef: IwbFlagsDef\n      read GetFlagsDef;\n    property FlagIndex: Integer\n      read GetFlagIndex;\n  end;\n\n  IwbFlagsDef = interface(IwbIntegerDefFormater)\n    ['{EF564466-A671-453A-88CF-42A0AA32D849}']\n    function GetBaseFlagsDef: IwbFlagsDef;\n    function GetFlag(aIndex: Integer): string;\n    function GetFlagCount: Integer;\n    function GetFlagIgnoreConflict(aIndex: Integer): Boolean;\n    function GetFlagDontShow(const aElement: IwbElement; aIndex: Integer): Boolean;\n    function GetFlagHasDontShow(aIndex: Integer): Boolean;\n    procedure FlagGetCP(const aElement: IwbElement; aIndex: Integer; var aCP: TwbConflictPriority);\n    function GetFlagHasGetCP(aIndex: Integer): Boolean;\n    function GetFlagDef(aIndex : Integer): IwbFlagDef;\n\n    property BaseFlagsDef: IwbFlagsDef\n      read GetBaseFlagsDef;\n\n    property Flags[aIndex: Integer] : string\n      read GetFlag;\n    property FlagCount: Integer\n      read GetFlagCount;\n\n    property FlagIgnoreConflict[aIndex: Integer] : Boolean\n      read GetFlagIgnoreConflict;\n\n    property FlagDontShow[const aElement: IwbElement; aIndex: Integer]: Boolean\n      read GetFlagDontShow;\n    property FlagHasDontShow[aIndex: Integer]: Boolean\n      read GetFlagHasDontShow;\n    property FlagHasGetCP[aIndex: Integer]: Boolean\n      read GetFlagHasGetCP;\n\n    property FlagDef[aIndex: Integer]: IwbFlagDef\n      read GetFlagDef;\n  end;\n\n  IwbEnumDef = interface(IwbIntegerDefFormater)\n    ['{A3AFE02E-F72D-4E0E-BC56-219F7EE2B564}']\n\n    function GetName(aIndex: Integer): string;\n    function GetNameCount: Integer;\n\n    property Names[aIndex: Integer]: string\n      read GetName;\n    property NameCount: Integer\n      read GetNameCount;\n  end;\n\n  IwbKey2Data6EnumDef = interface(IwbEnumDef)\n    ['{A74C58CC-6280-4143-B72B-4AD4F68A9957}']\n  end;\n\n  IwbData6Key2EnumDef = interface(IwbEnumDef)\n    ['{AC7F99C9-9DF1-43BB-9052-6AD4B69E706F}']\n  end;\n\n  IwbCallbackDef = interface(IwbIntegerDefFormater)\n    ['{BF6A0830-F981-4E0A-B4F2-2A09D575CD19}']\n    function GetCallback: TwbIntToStrCallback;\n\n    property Callback: TwbIntToStrCallback\n      read GetCallback;\n  end;\n\n  IwbResourceContainer = interface;\n\n  IwbResource = interface(IInterface)\n    ['{B626E8BF-D2E3-40D1-8F3A-E6001D76B97B}']\n    function GetContainer: IwbResourceContainer;\n    function GetData: TBytes;\n\n    property Container: IwbResourceContainer\n      read GetContainer;\n  end;\n\n  IwbResourceContainer = interface(IInterface)\n    ['{023EA9C4-19B5-4587-B298-559EEF8F224E}']\n    function GetName: String;\n    function OpenResource(const aFileName: string): IwbResource;\n    function ResourceExists(const aFileName: string): Boolean;\n    procedure ResourceList(const aList: TStrings; const aFolder: string = '');\n    procedure ResolveHash(const aHash: Int64; var Results: TDynStrings);\n\n    property Name: string\n      read GetName;\n  end;\n\n  IwbFolder = interface(IwbResourceContainer)\n    ['{E71981ED-3C0C-4334-8476-116AEB0EEA1E}']\n    function GetPathName: string;\n\n    property PathName: string\n      read GetPathName;\n  end;\n\n  IwbBSAFile = interface(IwbResourceContainer)\n    ['{DC987017-9F5C-42D2-BAD2-E1A622E99081}']\n    function GetFileName: string;\n\n    property FileName: string\n      read GetFileName;\n  end;\n\n  IwbBA2File = interface(IwbResourceContainer)\n    ['{D05EAAEC-8A23-4CDD-83E4-7593AC846CE3}']\n    function GetFileName: string;\n\n    property FileName: string\n      read GetFileName;\n  end;\n\n  TDynResources = array of IwbResource;\n\n  IwbContainerHandler = interface(IInterface)\n    ['{0CC80043-EADC-4C7D-8677-8719735582C7}']\n    procedure AddFolder(const aPath: string);\n    procedure AddBSA(const aFileName: string);\n    procedure AddBA2(const aFileName: string);\n\n    function OpenResource(const aFileName: string): TDynResources;\n    function OpenResourceData(const aContainerName, aFileName: string): TBytes;\n    function ResolveHash(const aHash: Int64): TDynStrings;\n    function ContainerExists(aContainerName: string): Boolean;\n    procedure ContainerList(const aList: TStrings);\n    procedure ContainerResourceList(const aContainerName: string; const aList: TStrings;\n      const aFolder: string = '');\n    function ResourceExists(const aFileName: string): Boolean;\n    function ResourceCount(const aFileName: string; aContainers: TStrings = nil): Integer;\n    procedure ResourceCopy(const aContainerName, aFileName, aPathOut: string);\n  end;\n\nvar\n  SortedElementTypes : set of TwbElementType = [\n    etFile,\n    etMainRecord,\n    etGroupRecord,\n    etSubRecord,\n    etSubRecordArray,\n    etArray\n  ];\n  wbPluginExtensions : TwbPluginExtensions;\n\nfunction wbRecord(const aSignature      : TwbSignature;\n                  const aName           : string;\n                  const aMembers        : array of IwbRecordMemberDef;\n                        aAllowUnordered : Boolean = False;\n                        aAddInfoCallback: TwbAddInfoCallback = nil;\n                        aPriority       : TwbConflictPriority = cpNormal;\n                        aRequired       : Boolean = False;\n                        aAfterLoad      : TwbAfterLoadCallback = nil;\n                        aAfterSet       : TwbAfterSetCallback = nil)\n                                        : IwbRecordDef; overload;\n\nfunction wbRecord(const aSignature      : TwbSignature;\n                  const aName           : string;\n                  const aRecordFlags    : IwbIntegerDefFormater;\n                  const aMembers        : array of IwbRecordMemberDef;\n                        aAllowUnordered : Boolean = False;\n                        aAddInfoCallback: TwbAddInfoCallback = nil;\n                        aPriority       : TwbConflictPriority = cpNormal;\n                        aRequired       : Boolean = False;\n                        aAfterLoad      : TwbAfterLoadCallback = nil;\n                        aAfterSet       : TwbAfterSetCallback = nil)\n                                        : IwbRecordDef; overload;\n\nfunction wbSubRecord(const aSignature : TwbSignature;\n                     const aName      : string;\n                     const aValue     : IwbValueDef;\n                           aAfterLoad : TwbAfterLoadCallback = nil;\n                           aAfterSet  : TwbAfterSetCallback = nil;\n                           aPriority  : TwbConflictPriority = cpNormal;\n                           aRequired  : Boolean = False;\n                           aSizeMatch : Boolean = False;\n                           aDontShow  : TwbDontShowCallback = nil;\n                           aGetCP     : TwbGetConflictPriority = nil)\n                                      : IwbSubRecordDef; overload;\n\nfunction wbSubRecord(const aSignatures : array of TwbSignature;\n                     const aName       : string;\n                     const aValue      : IwbValueDef;\n                           aAfterLoad  : TwbAfterLoadCallback = nil;\n                           aAfterSet   : TwbAfterSetCallback = nil;\n                           aPriority   : TwbConflictPriority = cpNormal;\n                           aRequired   : Boolean = False;\n                           aSizeMatch  : Boolean = False;\n                           aDontShow   : TwbDontShowCallback = nil;\n                           aGetCP      : TwbGetConflictPriority = nil)\n                                       : IwbSubRecordDef; overload;\n\nfunction wbString(const aSignature : TwbSignature;\n                  const aName      : string = 'Unknown';\n                        aSize      : Integer = 0;\n                        aPriority  : TwbConflictPriority = cpNormal;\n                        aRequired  : Boolean = False;\n                        aDontShow  : TwbDontShowCallback = nil;\n                        aAfterSet  : TwbAfterSetCallback = nil;\n                        aGetCP     : TwbGetConflictPriority = nil)\n                                   : IwbSubRecordDef; overload;\n\nfunction wbString(const aName      : string = 'Unknown';\n                        aSize      : Integer = 0;\n                        aPriority  : TwbConflictPriority = cpNormal;\n                        aRequired  : Boolean = False;\n                        aDontShow  : TwbDontShowCallback = nil;\n                        aAfterSet  : TwbAfterSetCallback = nil;\n                        aGetCP     : TwbGetConflictPriority = nil)\n                                   : IwbStringDef; overload;\n\nfunction wbStringForward(const aSignature : TwbSignature;           // When the editor can leave chars after the ending #0\n                         const aName      : string = 'Unknown';\n                               aSize      : Integer = 0;\n                               aPriority  : TwbConflictPriority = cpNormal;\n                               aRequired  : Boolean = False;\n                               aDontShow  : TwbDontShowCallback = nil;\n                               aAfterSet  : TwbAfterSetCallback = nil;\n                               aGetCP     : TwbGetConflictPriority = nil)\n                                          : IwbSubRecordDef; overload;\n\nfunction wbString(      aForward   : Boolean = False;\n                  const aName      : string = 'Unknown';\n                        aSize      : Integer = 0;\n                        aPriority  : TwbConflictPriority = cpNormal;\n                        aRequired  : Boolean = False;\n                        aDontShow  : TwbDontShowCallback = nil;\n                        aAfterSet  : TwbAfterSetCallback = nil;\n                        aGetCP     : TwbGetConflictPriority = nil)\n                                   : IwbStringDef; overload;\n\nfunction wbStringT(const aSignature : TwbSignature;\n                   const aName      : string = 'Unknown';\n                         aSize      : Integer = 0;\n                         aPriority  : TwbConflictPriority = cpNormal;\n                         aRequired  : Boolean = False;\n                         aDontShow  : TwbDontShowCallback = nil;\n                         aAfterSet  : TwbAfterSetCallback = nil;\n                         aGetCP     : TwbGetConflictPriority = nil)\n                                    : IwbSubRecordDef; overload;\n\nfunction wbStringT(const aName      : string = 'Unknown';\n                         aSize      : Integer = 0;\n                         aPriority  : TwbConflictPriority = cpNormal;\n                         aRequired  : Boolean = False;\n                         aDontShow  : TwbDontShowCallback = nil;\n                         aAfterSet  : TwbAfterSetCallback = nil;\n                         aGetCP     : TwbGetConflictPriority = nil)\n                                    : IwbStringDef; overload;\n\nfunction wbStringScript(const aSignature : TwbSignature;\n                        const aName      : string;\n                              aSize      : Integer = 0;\n                              aPriority  : TwbConflictPriority = cpNormal;\n                              aRequired  : Boolean = False;\n                              aDontShow  : TwbDontShowCallback = nil;\n                              aAfterSet  : TwbAfterSetCallback = nil;\n                              aGetCP     : TwbGetConflictPriority = nil)\n                                         : IwbSubRecordDef; overload;\n\nfunction wbStringScript(const aName      : string;\n                              aSize      : Integer = 0;\n                              aPriority  : TwbConflictPriority = cpNormal;\n                              aRequired  : Boolean = False;\n                              aDontShow  : TwbDontShowCallback = nil;\n                              aAfterSet  : TwbAfterSetCallback = nil;\n                              aGetCP     : TwbGetConflictPriority = nil)\n                                         : IwbStringDef; overload;\n\nfunction wbStringLC(const aSignature : TwbSignature;\n                    const aName      : string;\n                          aSize      : Integer = 0;\n                          aPriority  : TwbConflictPriority = cpNormal;\n                          aRequired  : Boolean = False;\n                          aDontShow  : TwbDontShowCallback = nil;\n                          aAfterSet  : TwbAfterSetCallback = nil;\n                          aGetCP     : TwbGetConflictPriority = nil)\n                                     : IwbSubRecordDef; overload;\n\nfunction wbStringLC(const aName      : string;\n                          aSize      : Integer = 0;\n                          aPriority  : TwbConflictPriority = cpNormal;\n                          aRequired  : Boolean = False;\n                          aDontShow  : TwbDontShowCallback = nil;\n                          aAfterSet  : TwbAfterSetCallback = nil;\n                          aGetCP     : TwbGetConflictPriority = nil)\n                                     : IwbStringDef; overload;\n\nfunction wbStringKC(const aSignature : TwbSignature;\n                    const aName      : string;\n                          aSize      : Integer = 0;\n                          aPriority  : TwbConflictPriority = cpNormal;\n                          aRequired  : Boolean = False;\n                          aDontShow  : TwbDontShowCallback = nil;\n                          aAfterSet  : TwbAfterSetCallback = nil;\n                          aGetCP     : TwbGetConflictPriority = nil)\n                                     : IwbSubRecordDef; overload;\n\nfunction wbStringKC(const aName      : string;\n                          aSize      : Integer = 0;\n                          aPriority  : TwbConflictPriority = cpNormal;\n                          aRequired  : Boolean = False;\n                          aDontShow  : TwbDontShowCallback = nil;\n                          aAfterSet  : TwbAfterSetCallback = nil;\n                          aGetCP     : TwbGetConflictPriority = nil)\n                                     : IwbStringDef; overload;\n\nfunction wbLString(const aSignature : TwbSignature;\n                   const aName      : string;\n                         aSize      : Integer = 0;\n                         aPriority  : TwbConflictPriority = cpNormal;\n                         aRequired  : Boolean = False;\n                         aDontShow  : TwbDontShowCallback = nil;\n                         aAfterSet  : TwbAfterSetCallback = nil;\n                         aGetCP     : TwbGetConflictPriority = nil)\n                                    : IwbSubRecordDef; overload;\n\nfunction wbLString(const aName      : string;\n                         aSize      : Integer = 0;\n                         aPriority  : TwbConflictPriority = cpNormal;\n                         aRequired  : Boolean = False;\n                         aDontShow  : TwbDontShowCallback = nil;\n                         aAfterSet  : TwbAfterSetCallback = nil;\n                         aGetCP     : TwbGetConflictPriority = nil)\n                                    : IwbStringDef; overload;\n\nfunction wbLStringKC(const aSignature : TwbSignature;\n                     const aName      : string;\n                           aSize      : Integer = 0;\n                           aPriority  : TwbConflictPriority = cpNormal;\n                           aRequired  : Boolean = False;\n                           aDontShow  : TwbDontShowCallback = nil;\n                           aAfterSet  : TwbAfterSetCallback = nil;\n                           aGetCP     : TwbGetConflictPriority = nil)\n                                      : IwbSubRecordDef; overload;\n\nfunction wbLStringKC(const aName      : string;\n                           aSize      : Integer = 0;\n                           aPriority  : TwbConflictPriority = cpNormal;\n                           aRequired  : Boolean = False;\n                           aDontShow  : TwbDontShowCallback = nil;\n                           aAfterSet  : TwbAfterSetCallback = nil;\n                           aGetCP     : TwbGetConflictPriority = nil)\n                                      : IwbStringDef; overload;\n\nfunction wbStringMgefCode(const aSignature : TwbSignature;\n                          const aName      : string;\n                                aSize      : Integer = 0;\n                                aPriority  : TwbConflictPriority = cpNormal;\n                                aRequired  : Boolean = False;\n                                aDontShow  : TwbDontShowCallback = nil;\n                                aAfterSet  : TwbAfterSetCallback = nil;\n                                aGetCP     : TwbGetConflictPriority = nil)\n                                           : IwbSubRecordDef; overload;\n\nfunction wbStringMgefCode(const aName      : string;\n                                aSize      : Integer = 0;\n                                aPriority  : TwbConflictPriority = cpNormal;\n                                aRequired  : Boolean = False;\n                                aDontShow  : TwbDontShowCallback = nil;\n                                aAfterSet  : TwbAfterSetCallback = nil;\n                                aGetCP     : TwbGetConflictPriority = nil)\n                                           : IwbStringDef; overload;\n\nfunction wbLenString(const aSignature : TwbSignature;\n                     const aName      : string;\n                           aPrefix    : Integer = 4;\n                           aPriority  : TwbConflictPriority = cpNormal;\n                           aRequired  : Boolean = False;\n                           aDontShow  : TwbDontShowCallback = nil;\n                           aGetCP     : TwbGetConflictPriority = nil)\n                                      : IwbSubRecordDef; overload;\n\nfunction wbLenString(const aName      : string;\n                           aPrefix    : Integer = 4;\n                           aPriority  : TwbConflictPriority = cpNormal;\n                           aRequired  : Boolean = False;\n                           aDontShow  : TwbDontShowCallback = nil;\n                           aGetCP     : TwbGetConflictPriority = nil)\n                                      : IwbLenStringDef; overload;\n\nfunction wbLenStringT(const aSignature : TwbSignature;\n                      const aName      : string;\n                            aPrefix    : Integer = 4;\n                            aPriority  : TwbConflictPriority = cpNormal;\n                            aRequired  : Boolean = False;\n                            aDontShow  : TwbDontShowCallback = nil;\n                            aGetCP     : TwbGetConflictPriority = nil)\n                                       : IwbSubRecordDef; overload;\n\nfunction wbLenStringT(const aName      : string;\n                            aPrefix    : Integer = 4;\n                            aPriority  : TwbConflictPriority = cpNormal;\n                            aRequired  : Boolean = False;\n                            aDontShow  : TwbDontShowCallback = nil;\n                            aGetCP     : TwbGetConflictPriority = nil)\n                                       : IwbLenStringDef; overload;\nfunction wbUnion(const aSignature : TwbSignature;\n                 const aName      : string;\n                       aDecider   : TwbUnionDecider;\n                 const aMembers   : array of IwbValueDef;\n                       aPriority  : TwbConflictPriority = cpNormal;\n                       aRequired  : Boolean = False;\n                       aDontShow  : TwbDontShowCallback = nil;\n                       aGetCP     : TwbGetConflictPriority = nil)\n                                  : IwbSubRecordDef; overload;\n\nfunction wbUnion(const aName     : string;\n                       aDecider  : TwbUnionDecider;\n                 const aMembers  : array of IwbValueDef;\n                       aPriority : TwbConflictPriority = cpNormal;\n                       aRequired : Boolean = False;\n                       aDontShow : TwbDontShowCallback = nil;\n                       aAfterSet : TwbAfterSetCallback = nil;\n                       aGetCP    : TwbGetConflictPriority = nil)\n                                 : IwbUnionDef; overload;\n\n\nfunction wbByteArray(const aSignature : TwbSignature;\n                     const aName      : string = 'Unknown';\n                           aSize      : Int64 = 0;\n                           aPriority  : TwbConflictPriority = cpNormal;\n                           aRequired  : Boolean = False;\n                           aSizeMatch : Boolean = False;\n                           aDontShow  : TwbDontShowCallback = nil;\n                           aGetCP     : TwbGetConflictPriority = nil)\n                                      : IwbSubRecordDef; overload;\n\nfunction wbByteArray(const aName      : string = 'Unknown';\n                           aSize      : Int64 = 0;\n                           aPriority  : TwbConflictPriority = cpNormal;\n                           aRequired  : Boolean = False;\n                           aDontShow  : TwbDontShowCallback = nil;\n                           aGetCP     : TwbGetConflictPriority = nil)\n                                      : IwbByteArrayDef; overload;\n\nfunction wbByteArrayT(const aName      : string = 'Unknown';\n                            aSize      : Int64 = 0;\n                            aPriority  : TwbConflictPriority = cpNormal;\n                            aRequired  : Boolean = False;\n                            aDontShow  : TwbDontShowCallback = nil;\n                            aGetCP     : TwbGetConflictPriority = nil)\n                                       : IwbByteArrayDef; overload;\n\nfunction wbByteArray(const aName          : string;\n                           aCountCallback : TwbCountCallback;\n                           aPriority      : TwbConflictPriority = cpNormal;\n                           aRequired      : Boolean = False;\n                           aDontShow      : TwbDontShowCallback = nil;\n                           aGetCP         : TwbGetConflictPriority = nil)\n                                          : IwbByteArrayDef; overload;\n\nfunction wbUnknown(const aSignature : TwbSignature;\n                         aPriority  : TwbConflictPriority = cpNormal;\n                         aRequired  : Boolean = False;\n                         aDontShow  : TwbDontShowCallback = nil;\n                         aGetCP     : TwbGetConflictPriority = nil)\n                                    : IwbSubRecordDef; overload;\n\nfunction wbUnknown(aPriority : TwbConflictPriority = cpNormal;\n                   aRequired : Boolean = False;\n                   aDontShow : TwbDontShowCallback = nil;\n                   aGetCP    : TwbGetConflictPriority = nil)\n                             : IwbByteArrayDef; overload;\n\nfunction wbInteger(const aSignature : TwbSignature;\n                   const aName      : string;\n                   const aIntType   : TwbIntType;\n                   const aFormater  : IwbIntegerDefFormater = nil;\n                         aPriority  : TwbConflictPriority = cpNormal;\n                         aRequired  : Boolean = False;\n                         aMatchSize : Boolean = False;\n                         aDontShow  : TwbDontShowCallback = nil;\n                         aAfterSet  : TwbAfterSetCallback = nil;\n                         aDefault   : Int64 = 0;\n                         aGetCP     : TwbGetConflictPriority = nil)\n                                    : IwbSubRecordDef; overload;\n\nfunction wbInteger(const aName     : string;\n                   const aIntType  : TwbIntType;\n                   const aFormater : IwbIntegerDefFormater = nil;\n                         aPriority : TwbConflictPriority = cpNormal;\n                         aRequired : Boolean = False;\n                         aDontShow : TwbDontShowCallback = nil;\n                         aAfterSet : TwbAfterSetCallback = nil;\n                         aDefault  : Int64 = 0;\n                         aGetCP    : TwbGetConflictPriority = nil)\n                                   : IwbIntegerDef; overload;\n\nfunction wbInteger(const aSignature : TwbSignature;\n                   const aName      : string;\n                   const aIntType   : TwbIntType;\n                   const aToStr     : TwbIntToStrCallback;\n                   const aToInt     : TwbStrToIntCallback = nil;\n                         aPriority  : TwbConflictPriority = cpNormal;\n                         aRequired  : Boolean = False;\n                         aDontShow  : TwbDontShowCallback = nil;\n                         aAfterSet  : TwbAfterSetCallback = nil;\n                         aDefault   : Int64 = 0;\n                         aGetCP     : TwbGetConflictPriority = nil)\n                                    : IwbSubRecordDef; overload;\n\nfunction wbInteger(const aName     : string;\n                   const aIntType  : TwbIntType;\n                   const aToStr    : TwbIntToStrCallback;\n                   const aToInt    : TwbStrToIntCallback = nil;\n                         aPriority : TwbConflictPriority = cpNormal;\n                         aRequired : Boolean = False;\n                         aDontShow : TwbDontShowCallback = nil;\n                         aAfterSet : TwbAfterSetCallback = nil;\n                         aDefault  : Int64 = 0;\n                         aGetCP    : TwbGetConflictPriority = nil)\n                                   : IwbIntegerDef; overload;\n\n\nfunction wbIntegerT(const aSignature : TwbSignature;\n                    const aName      : string;\n                    const aIntType   : TwbIntType;\n                    const aFormater  : IwbIntegerDefFormater = nil;\n                          aPriority  : TwbConflictPriority = cpNormal;\n                          aRequired  : Boolean = False;\n                          aMatchSize : Boolean = False;\n                          aDontShow  : TwbDontShowCallback = nil;\n                          aAfterSet  : TwbAfterSetCallback = nil;\n                          aDefault   : Int64 = 0;\n                          aGetCP     : TwbGetConflictPriority = nil)\n                                     : IwbSubRecordDef; overload;\n\nfunction wbIntegerT(const aName     : string;\n                    const aIntType  : TwbIntType;\n                    const aFormater : IwbIntegerDefFormater = nil;\n                          aPriority : TwbConflictPriority = cpNormal;\n                          aRequired : Boolean = False;\n                          aDontShow : TwbDontShowCallback = nil;\n                          aAfterSet : TwbAfterSetCallback = nil;\n                          aDefault  : Int64= 0;\n                          aGetCP    : TwbGetConflictPriority = nil)\n                                    : IwbIntegerDef; overload;\n\nfunction wbIntegerT(const aSignature : TwbSignature;\n                    const aName      : string;\n                    const aIntType   : TwbIntType;\n                    const aToStr     : TwbIntToStrCallback;\n                    const aToInt     : TwbStrToIntCallback = nil;\n                          aPriority  : TwbConflictPriority = cpNormal;\n                          aRequired  : Boolean = False;\n                          aDontShow  : TwbDontShowCallback = nil;\n                          aAfterSet  : TwbAfterSetCallback = nil;\n                          aDefault   : Int64 = 0;\n                          aGetCP     : TwbGetConflictPriority = nil)\n                                     : IwbSubRecordDef; overload;\n\nfunction wbIntegerT(const aName     : string;\n                    const aIntType  : TwbIntType;\n                    const aToStr    : TwbIntToStrCallback;\n                    const aToInt    : TwbStrToIntCallback = nil;\n                          aPriority : TwbConflictPriority = cpNormal;\n                          aRequired : Boolean = False;\n                          aDontShow : TwbDontShowCallback = nil;\n                          aAfterSet : TwbAfterSetCallback = nil;\n                          aDefault  : Int64 = 0;\n                          aGetCP    : TwbGetConflictPriority = nil)\n                                    : IwbIntegerDef; overload;\n\nfunction wbFloat(const aSignature  : TwbSignature;\n                 const aName       : string = 'Unknown';\n                       aPriority   : TwbConflictPriority = cpNormal;\n                       aRequired   : Boolean = False;\n                       aScale      : Extended = 1.0;\n                       aDigits     : Integer = -1;\n                       aDontShow   : TwbDontShowCallback = nil;\n                       aNormalizer : TwbFloatNormalizer = nil;\n                       aDefault    : Extended = 0.0;\n                       aGetCP      : TwbGetConflictPriority = nil)\n                                   : IwbSubRecordDef; overload;\n\nfunction wbFloat(const aName       : string = 'Unknown';\n                       aPriority   : TwbConflictPriority = cpNormal;\n                       aRequired   : Boolean = False;\n                       aScale      : Extended = 1.0;\n                       aDigits     : Integer = -1;\n                       aDontShow   : TwbDontShowCallback = nil;\n                       aNormalizer : TwbFloatNormalizer = nil;\n                       aDefault    : Extended = 0.0;\n                       aGetCP      : TwbGetConflictPriority = nil)\n                                   : IwbFloatDef; overload;\n\nfunction wbFloat(const aName       : string;\n                       aPriority   : TwbConflictPriority;\n                       aRequired   : Boolean;\n                       aDontShow   : TwbDontShowCallback;\n                       aAfterSet   : TwbAfterSetCallback = nil;\n                       aNormalizer : TwbFloatNormalizer = nil;\n                       aDefault    : Extended = 0.0;\n                       aGetCP      : TwbGetConflictPriority = nil)\n                                   : IwbFloatDef; overload;\n\nfunction wbDouble(const aSignature  : TwbSignature;\n                  const aName       : string = 'Unknown';\n                        aPriority   : TwbConflictPriority = cpNormal;\n                        aRequired   : Boolean = False;\n                        aScale      : Extended = 1.0;\n                        aDigits     : Integer = -1;\n                        aDontShow   : TwbDontShowCallback = nil;\n                        aNormalizer : TwbFloatNormalizer = nil;\n                        aDefault    : Extended = 0.0;\n                        aGetCP      : TwbGetConflictPriority = nil)\n                                    : IwbSubRecordDef; overload;\n\nfunction wbDouble(const aName       : string = 'Unknown';\n                        aPriority   : TwbConflictPriority = cpNormal;\n                        aRequired   : Boolean = False;\n                        aScale      : Extended = 1.0;\n                        aDigits     : Integer = -1;\n                        aDontShow   : TwbDontShowCallback = nil;\n                        aNormalizer : TwbFloatNormalizer = nil;\n                        aDefault    : Extended = 0.0;\n                        aGetCP      : TwbGetConflictPriority = nil)\n                                    : IwbFloatDef; overload;\n\nfunction wbDouble(const aName       : string;\n                        aPriority   : TwbConflictPriority;\n                        aRequired   : Boolean;\n                        aDontShow   : TwbDontShowCallback;\n                        aAfterSet   : TwbAfterSetCallback = nil;\n                        aNormalizer : TwbFloatNormalizer = nil;\n                        aDefault    : Extended = 0.0;\n                        aGetCP      : TwbGetConflictPriority = nil)\n                                    : IwbFloatDef; overload;\n\nfunction wbFloatT(const aSignature  : TwbSignature;\n                  const aName       : string = 'Unknown';\n                        aPriority   : TwbConflictPriority = cpNormal;\n                        aRequired   : Boolean = False;\n                        aScale      : Extended = 1.0;\n                        aDigits     : Integer = -1;\n                        aDontShow   : TwbDontShowCallback = nil;\n                        aNormalizer : TwbFloatNormalizer = nil;\n                        aDefault    : Extended = 0.0;\n                        aGetCP      : TwbGetConflictPriority = nil)\n                                    : IwbSubRecordDef; overload;\n\nfunction wbFloatT(const aName       : string = 'Unknown';\n                        aPriority   : TwbConflictPriority = cpNormal;\n                        aRequired   : Boolean = False;\n                        aScale      : Extended = 1.0;\n                        aDigits     : Integer = -1;\n                        aDontShow   : TwbDontShowCallback = nil;\n                        aNormalizer : TwbFloatNormalizer = nil;\n                        aDefault    : Extended = 0.0;\n                        aGetCP      : TwbGetConflictPriority = nil)\n                                    : IwbFloatDef; overload;\n\nfunction wbFloatT(const aName       : string;\n                        aPriority   : TwbConflictPriority;\n                        aRequired   : Boolean;\n                        aDontShow   : TwbDontShowCallback;\n                        aAfterSet   : TwbAfterSetCallback = nil;\n                        aNormalizer : TwbFloatNormalizer = nil;\n                        aDefault    : Extended = 0.0;\n                        aGetCP      : TwbGetConflictPriority = nil)\n                                    : IwbFloatDef; overload;\n\nfunction wbDoubleT(const aSignature  : TwbSignature;\n                   const aName       : string = 'Unknown';\n                         aPriority   : TwbConflictPriority = cpNormal;\n                         aRequired   : Boolean = False;\n                         aScale      : Extended = 1.0;\n                         aDigits     : Integer = -1;\n                         aDontShow   : TwbDontShowCallback = nil;\n                         aNormalizer : TwbFloatNormalizer = nil;\n                         aDefault    : Extended = 0.0;\n                         aGetCP      : TwbGetConflictPriority = nil)\n                                     : IwbSubRecordDef; overload;\n\nfunction wbDoubleT(const aName       : string = 'Unknown';\n                         aPriority   : TwbConflictPriority = cpNormal;\n                         aRequired   : Boolean = False;\n                         aScale      : Extended = 1.0;\n                         aDigits     : Integer = -1;\n                         aDontShow   : TwbDontShowCallback = nil;\n                         aNormalizer : TwbFloatNormalizer = nil;\n                         aDefault    : Extended = 0.0;\n                         aGetCP      : TwbGetConflictPriority = nil)\n                                     : IwbFloatDef; overload;\n\nfunction wbDoubleT(const aName       : string;\n                         aPriority   : TwbConflictPriority;\n                         aRequired   : Boolean;\n                         aDontShow   : TwbDontShowCallback;\n                         aAfterSet   : TwbAfterSetCallback = nil;\n                         aNormalizer : TwbFloatNormalizer = nil;\n                         aDefault    : Extended = 0.0;\n                         aGetCP      : TwbGetConflictPriority = nil)\n                                     : IwbFloatDef; overload;\n\n{--- wbArray - list of identical elements -------------------------------------}\nfunction wbArray(const aSignature : TwbSignature;\n                 const aName      : string;\n                 const aElement   : IwbValueDef;\n                       aCount     : Integer = 0;\n                       aAfterLoad : TwbAfterLoadCallback = nil;\n                       aAfterSet  : TwbAfterSetCallback = nil;\n                       aPriority  : TwbConflictPriority = cpNormal;\n                       aRequired  : Boolean = False;\n                       aDontShow  : TwbDontShowCallback = nil;\n                       aGetCP     : TwbGetConflictPriority = nil)\n                                  : IwbSubRecordDef; overload;\n\nfunction wbArray(const aName     : string;\n                 const aElement  : IwbValueDef;\n                       aCount    : Integer = 0;\n                       aPriority : TwbConflictPriority = cpNormal;\n                       aRequired : Boolean = False;\n                       aDontShow : TwbDontShowCallback = nil;\n                       aGetCP    : TwbGetConflictPriority = nil)\n                                 : IwbArrayDef; overload;\n\nfunction wbArray(const aName      : string;\n                 const aElement   : IwbValueDef;\n                       aCount     : Integer;\n                       aAfterLoad : TwbAfterLoadCallback;\n                       aPriority  : TwbConflictPriority = cpNormal;\n                       aRequired  : Boolean = False;\n                       aDontShow  : TwbDontShowCallback = nil;\n                       aGetCP     : TwbGetConflictPriority = nil)\n                                  : IwbArrayDef; overload;\n\nfunction wbArray(const aSignature : TwbSignature;\n                 const aName      : string;\n                 const aElement   : IwbValueDef;\n                 const aLabels    : array of string;\n                       aPriority  : TwbConflictPriority = cpNormal;\n                       aRequired  : Boolean = False;\n                       aDontShow  : TwbDontShowCallback = nil;\n                       aGetCP     : TwbGetConflictPriority = nil)\n                                  : IwbSubRecordDef; overload;\n\nfunction wbArray(const aSignature     : TwbSignature;\n                 const aName          : string;\n                 const aElement       : IwbValueDef;\n                 const aLabels        : array of string;\n                       aCountCallback : TwbCountCallback;\n                       aPriority      : TwbConflictPriority = cpNormal;\n                       aRequired      : Boolean = False;\n                       aDontShow      : TwbDontShowCallback = nil;\n                       aGetCP         : TwbGetConflictPriority = nil)\n                                      : IwbSubRecordDef; overload;\n\nfunction wbArray(const aName     : string;\n                 const aElement  : IwbValueDef;\n                 const aLabels   : array of string;\n                       aPriority : TwbConflictPriority = cpNormal;\n                       aRequired : Boolean = False;\n                       aDontShow : TwbDontShowCallback = nil;\n                       aGetCP    : TwbGetConflictPriority = nil)\n                                 : IwbArrayDef; overload;\n\nfunction wbArray(const aName          : string;\n                 const aElement       : IwbValueDef;\n                 const aLabels        : array of string;\n                       aCountCallback : TwbCountCallback;\n                       aPriority      : TwbConflictPriority = cpNormal;\n                       aRequired      : Boolean = False;\n                       aDontShow      : TwbDontShowCallback = nil;\n                       aGetCP         : TwbGetConflictPriority = nil)\n                                      : IwbArrayDef; overload;\n\nfunction wbArray(const aName          : string;\n                 const aElement       : IwbValueDef;\n                       aCountCallback : TwbCountCallback;\n                       aPriority      : TwbConflictPriority = cpNormal;\n                       aRequired      : Boolean = False;\n                       aDontShow      : TwbDontShowCallback = nil;\n                       aGetCP         : TwbGetConflictPriority = nil)\n                                      : IwbArrayDef; overload;\n\nfunction wbArrayPT(const aSignature : TwbSignature;   // case where the prefix is terminated.\n                   const aName      : string;\n                   const aElement   : IwbValueDef;\n                         aCount     : Integer = 0;\n                         aAfterLoad : TwbAfterLoadCallback = nil;\n                         aAfterSet  : TwbAfterSetCallback = nil;\n                         aPriority  : TwbConflictPriority = cpNormal;\n                         aRequired  : Boolean = False;\n                         aDontShow  : TwbDontShowCallback = nil;\n                         aGetCP     : TwbGetConflictPriority = nil)\n                                    : IwbSubRecordDef; overload;\n\nfunction wbArrayPT(const aName     : string;\n                   const aElement  : IwbValueDef;\n                         aCount    : Integer = 0;\n                         aPriority : TwbConflictPriority = cpNormal;\n                         aRequired : Boolean = False;\n                         aDontShow : TwbDontShowCallback = nil;\n                         aGetCP    : TwbGetConflictPriority = nil)\n                                   : IwbArrayDef; overload;\n\nfunction wbArrayPT(const aName      : string;\n                   const aElement   : IwbValueDef;\n                         aCount     : Integer;\n                         aAfterLoad : TwbAfterLoadCallback;\n                         aPriority  : TwbConflictPriority = cpNormal;\n                         aRequired  : Boolean = False;\n                         aDontShow  : TwbDontShowCallback = nil;\n                         aGetCP     : TwbGetConflictPriority = nil)\n                                    : IwbArrayDef; overload;\n\nfunction wbArrayT(const aName      : string;   // case where members are not terminated, but the array itself yes\n                  const aElement   : IwbValueDef;\n                        aCount     : Integer;\n                  const aLabels    : array of string;\n                        aAfterLoad : TwbAfterLoadCallback;\n                        aPriority  : TwbConflictPriority = cpNormal;\n                        aRequired  : Boolean = False;\n                        aDontShow  : TwbDontShowCallback = nil;\n                        aGetCP     : TwbGetConflictPriority = nil)\n                                   : IwbArrayDef; overload;\n\nfunction wbArrayPT(const aSignature : TwbSignature;\n                   const aName      : string;\n                   const aElement   : IwbValueDef;\n                   const aLabels    : array of string;\n                         aPriority  : TwbConflictPriority = cpNormal;\n                         aRequired  : Boolean = False;\n                         aDontShow  : TwbDontShowCallback = nil;\n                         aGetCP     : TwbGetConflictPriority = nil)\n                                    : IwbSubRecordDef; overload;\n\nfunction wbArrayPT(const aSignature     : TwbSignature;\n                   const aName          : string;\n                   const aElement       : IwbValueDef;\n                   const aLabels        : array of string;\n                         aCountCallback : TwbCountCallback;\n                         aPriority      : TwbConflictPriority = cpNormal;\n                         aRequired      : Boolean = False;\n                         aDontShow      : TwbDontShowCallback = nil;\n                         aGetCP         : TwbGetConflictPriority = nil)\n                                        : IwbSubRecordDef; overload;\n\nfunction wbArrayPT(const aName     : string;\n                   const aElement  : IwbValueDef;\n                   const aLabels   : array of string;\n                         aPriority : TwbConflictPriority = cpNormal;\n                         aRequired : Boolean = False;\n                         aDontShow : TwbDontShowCallback = nil;\n                         aGetCP    : TwbGetConflictPriority = nil)\n                                   : IwbArrayDef; overload;\n\nfunction wbArrayPT(const aName          : string;\n                   const aElement       : IwbValueDef;\n                   const aLabels        : array of string;\n                         aCountCallback : TwbCountCallback;\n                         aPriority      : TwbConflictPriority = cpNormal;\n                         aRequired      : Boolean = False;\n                         aDontShow      : TwbDontShowCallback = nil;\n                         aGetCP         : TwbGetConflictPriority = nil)\n                                        : IwbArrayDef; overload;\n\nfunction wbArrayT(const aName          : string;   // case where members are not terminated, but the array itself yes\n                  const aElement       : IwbValueDef;\n                  const aLabels        : array of string;\n                        aCountCallback : TwbCountCallback;\n                        aPriority      : TwbConflictPriority = cpNormal;\n                        aRequired      : Boolean = False;\n                        aDontShow      : TwbDontShowCallback = nil;\n                        aGetCP         : TwbGetConflictPriority = nil)\n                                       : IwbArrayDef; overload;\n\nfunction wbArrayPT(const aName          : string;\n                   const aElement       : IwbValueDef;\n                         aCountCallback : TwbCountCallback;\n                         aPriority      : TwbConflictPriority = cpNormal;\n                         aRequired      : Boolean = False;\n                         aDontShow      : TwbDontShowCallback = nil;\n                         aGetCP         : TwbGetConflictPriority = nil)\n                                        : IwbArrayDef; overload;\n\nfunction wbRArray(const aName      : string;\n                  const aElement   : IwbRecordMemberDef;\n                        aPriority  : TwbConflictPriority = cpNormal;\n                        aRequired  : Boolean = False;\n                        aAfterLoad : TwbAfterLoadCallback = nil;\n                        aAfterSet  : TwbAfterSetCallback = nil;\n                        aDontShow  : TwbDontShowCallback = nil;\n                        aGetCP     : TwbGetConflictPriority = nil)\n                                   : IwbSubRecordArrayDef; overload;\n\nfunction wbArrayS(const aSignature : TwbSignature;\n                  const aName      : string;\n                  const aElement   : IwbValueDef;\n                        aCount     : Integer = 0;\n                        aPriority  : TwbConflictPriority = cpNormal;\n                        aRequired  : Boolean = False;\n                        aAfterLoad : TwbAfterLoadCallback = nil;\n                        aAfterSet  : TwbAfterSetCallback = nil;\n                        aDontShow  : TwbDontShowCallback = nil;\n                        aGetCP     : TwbGetConflictPriority = nil)\n                                   : IwbSubRecordDef; overload;\n\nfunction wbArrayS(const aName      : string;\n                  const aElement   : IwbValueDef;\n                        aCount     : Integer = 0;\n                        aPriority  : TwbConflictPriority = cpNormal;\n                        aRequired  : Boolean = False;\n                        aAfterLoad : TwbAfterLoadCallback = nil;\n                        aAfterSet  : TwbAfterSetCallback = nil;\n                        aDontShow  : TwbDontShowCallback = nil;\n                        aCanAddTo  : Boolean = True;\n                        aGetCP     : TwbGetConflictPriority = nil)\n                                   : IwbArrayDef; overload;\n\nfunction wbArrayS(const aName      : string;\n                  const aElement   : IwbValueDef;\n                        aCount     : Integer;\n                        aAfterLoad : TwbAfterLoadCallback;\n                        aPriority  : TwbConflictPriority = cpNormal;\n                        aRequired  : Boolean = False;\n                        aAfterSet  : TwbAfterSetCallback = nil;\n                        aDontShow  : TwbDontShowCallback = nil;\n                        aGetCP     : TwbGetConflictPriority = nil)\n                                   : IwbArrayDef; overload;\n\nfunction wbArrayS(const aName          : string;\n                  const aElement       : IwbValueDef;\n                        aCountCallback : TwbCountCallback;\n                        aPriority      : TwbConflictPriority = cpNormal;\n                        aRequired      : Boolean = False;\n                        aAfterLoad     : TwbAfterLoadCallback = nil;\n                        aAfterSet      : TwbAfterSetCallback = nil;\n                        aDontShow      : TwbDontShowCallback = nil;\n                        aGetCP         : TwbGetConflictPriority = nil)\n                                       : IwbArrayDef; overload;\n\nfunction wbArray(const aName          : string;\n                 const aElement       : IwbValueDef;\n                       aCountCallback : TwbCountCallback;\n                       aPriority      : TwbConflictPriority;\n                       aRequired      : Boolean;\n                       aAfterLoad     : TwbAfterLoadCallback;\n                       aAfterSet      : TwbAfterSetCallback;\n                       aDontShow      : TwbDontShowCallback = nil;\n                       aGetCP         : TwbGetConflictPriority = nil)\n                                       : IwbArrayDef; overload;\n\nfunction wbArrayS(const aSignature : TwbSignature;\n                  const aName      : string;\n                  const aElement   : IwbValueDef;\n                  const aLabels    : array of string;\n                        aPriority  : TwbConflictPriority = cpNormal;\n                        aRequired  : Boolean = False;\n                        aAfterLoad : TwbAfterLoadCallback = nil;\n                        aAfterSet  : TwbAfterSetCallback = nil;\n                        aDontShow  : TwbDontShowCallback = nil;\n                        aGetCP     : TwbGetConflictPriority = nil)\n                                   : IwbSubRecordDef; overload;\n\nfunction wbArrayS(const aName      : string;\n                  const aElement   : IwbValueDef;\n                  const aLabels    : array of string;\n                        aPriority  : TwbConflictPriority = cpNormal;\n                        aRequired  : Boolean = False;\n                        aAfterLoad : TwbAfterLoadCallback = nil;\n                        aAfterSet  : TwbAfterSetCallback = nil;\n                        aDontShow  : TwbDontShowCallback = nil;\n                        aGetCP     : TwbGetConflictPriority = nil)\n                                   : IwbArrayDef; overload;\n\n\nfunction wbRArrayS(const aName      : string;\n                   const aElement   : IwbRecordMemberDef;\n                         aPriority  : TwbConflictPriority = cpNormal;\n                         aRequired  : Boolean = False;\n                         aAfterLoad : TwbAfterLoadCallback = nil;\n                         aAfterSet  : TwbAfterSetCallback = nil;\n                         aDontShow  : TwbDontShowCallback = nil;\n                         aIsSorted  : TwbIsSortedCallback = nil;\n                         aGetCP     : TwbGetConflictPriority = nil)\n                                    : IwbSubRecordArrayDef; overload;\n\n{--- wbStruct - ordered list of members ----------------------------------------}\nfunction wbStructSK(const aSortKey             : array of Integer;\n                    const aName                : string;\n                    const aMembers             : array of IwbValueDef;\n                          aPriority            : TwbConflictPriority = cpNormal;\n                          aRequired            : Boolean = False;\n                          aDontShow            : TwbDontShowCallback = nil;\n                          aOptionalFromElement : Integer = -1;\n                          aAfterLoad           : TwbAfterLoadCallback = nil;\n                          aAfterSet            : TwbAfterSetCallback = nil;\n                          aGetCP               : TwbGetConflictPriority = nil)\n                                               : IwbStructDef; overload;\n\nfunction wbStructSK(const aSortKey             : array of Integer;\n                    const aName                : string;\n                    const aMembers             : array of IwbValueDef;\n                    {$IFDEF WIN32}\n                    const aElementMap          : array of Cardinal;\n                    {$ENDIF WIN32}\n                    {$IFDEF WIN64}\n                    const aElementMap          : array of UInt64;\n                    {$ENDIF WIN64}\n                          aPriority            : TwbConflictPriority = cpNormal;\n                          aRequired            : Boolean = False;\n                          aDontShow            : TwbDontShowCallback = nil;\n                          aOptionalFromElement : Integer = -1;\n                          aAfterLoad           : TwbAfterLoadCallback = nil;\n                          aAfterSet            : TwbAfterSetCallback = nil;\n                          aGetCP               : TwbGetConflictPriority = nil)\n                                               : IwbStructDef; overload;\n\nfunction wbStructSK(const aSignature           : TwbSignature;\n                    const aSortKey             : array of Integer;\n                    const aName                : string;\n                    const aMembers             : array of IwbValueDef;\n                          aPriority            : TwbConflictPriority = cpNormal;\n                          aRequired            : Boolean = False;\n                          aDontShow            : TwbDontShowCallback = nil;\n                          aOptionalFromElement : Integer = -1;\n                          aAfterLoad           : TwbAfterLoadCallback = nil;\n                          aAfterSet            : TwbAfterSetCallback = nil;\n                          aGetCP               : TwbGetConflictPriority = nil)\n                                               : IwbSubRecordDef; overload;\n\nfunction wbMultiStructSK(const aSignatures          : array of TwbSignature;\n                         const aSortKey             : array of Integer;\n                         const aName                : string;\n                         const aMembers             : array of IwbValueDef;\n                               aPriority            : TwbConflictPriority = cpNormal;\n                               aRequired            : Boolean = False;\n                               aDontShow            : TwbDontShowCallback = nil;\n                               aOptionalFromElement : Integer = -1;\n                               aAfterLoad           : TwbAfterLoadCallback = nil;\n                               aAfterSet            : TwbAfterSetCallback = nil;\n                               aGetCP               : TwbGetConflictPriority = nil)\n                                                    : IwbSubRecordDef;\n\nfunction wbStructExSK(const aSortKey             : array of Integer;\n                      const aExSortKey           : array of Integer;\n                      const aName                : string;\n                      const aMembers             : array of IwbValueDef;\n                            aPriority            : TwbConflictPriority = cpNormal;\n                            aRequired            : Boolean = False;\n                            aDontShow            : TwbDontShowCallback = nil;\n                            aOptionalFromElement : Integer = -1;\n                            aAfterLoad           : TwbAfterLoadCallback = nil;\n                            aAfterSet            : TwbAfterSetCallback = nil;\n                            aGetCP               : TwbGetConflictPriority = nil)\n                                                 : IwbStructDef; overload;\n\nfunction wbStructExSK(const aSignature           : TwbSignature;\n                      const aSortKey             : array of Integer;\n                      const aExSortKey           : array of Integer;\n                      const aName                : string;\n                      const aMembers             : array of IwbValueDef;\n                            aPriority            : TwbConflictPriority = cpNormal;\n                            aRequired            : Boolean = False;\n                            aDontShow            : TwbDontShowCallback = nil;\n                            aOptionalFromElement : Integer = -1;\n                            aAfterLoad           : TwbAfterLoadCallback = nil;\n                            aAfterSet            : TwbAfterSetCallback = nil;\n                            aGetCP               : TwbGetConflictPriority = nil)\n                                                 : IwbSubRecordDef; overload;\n\nfunction wbStruct(const aSignature           : TwbSignature;\n                  const aName                : string;\n                  const aMembers             : array of IwbValueDef;\n                        aPriority            : TwbConflictPriority = cpNormal;\n                        aRequired            : Boolean = False;\n                        aDontShow            : TwbDontShowCallback = nil;\n                        aOptionalFromElement : Integer = -1;\n                        aAfterLoad           : TwbAfterLoadCallback = nil;\n                        aAfterSet            : TwbAfterSetCallback = nil;\n                        aGetCP               : TwbGetConflictPriority = nil)\n                                             : IwbSubRecordDef; overload;\n\nfunction wbStruct(const aName                : string;\n                  const aMembers             : array of IwbValueDef;\n                        aPriority            : TwbConflictPriority = cpNormal;\n                        aRequired            : Boolean = False;\n                        aDontShow            : TwbDontShowCallback = nil;\n                        aOptionalFromElement : Integer = -1;\n                        aAfterLoad           : TwbAfterLoadCallback = nil;\n                        aAfterSet            : TwbAfterSetCallback = nil;\n                        aGetCP               : TwbGetConflictPriority = nil)\n                                             : IwbStructDef; overload;\n\nfunction wbStructC(const aName                : string;\n                         aSizing              : TwbSizeCallback;\n                         aGetChapterType      : TwbGetChapterTypeCallback;\n                         aGetChapterTypeName  : TwbGetChapterTypeNameCallback;\n                         aGetChapterName      : TwbGetChapterNameCallback;\n                   const aMembers             : array of IwbValueDef;\n                         aPriority            : TwbConflictPriority = cpNormal;\n                         aRequired            : Boolean = False;\n                         aDontShow            : TwbDontShowCallback = nil;\n                         aOptionalFromElement : Integer = -1;\n                         aAfterLoad           : TwbAfterLoadCallback = nil;\n                         aAfterSet            : TwbAfterSetCallback = nil;\n                         aGetCP               : TwbGetConflictPriority = nil)\n                                              : IwbStructDef; overload;\n\nfunction wbStructZ(const aName                : string;\n                         aSizing              : TwbSizeCallback;\n                         aGetChapterType      : TwbGetChapterTypeCallback;\n                         aGetChapterTypeName  : TwbGetChapterTypeNameCallback;\n                         aGetChapterName      : TwbGetChapterNameCallback;\n                   const aMembers             : array of IwbValueDef;\n                         aPriority            : TwbConflictPriority = cpNormal;\n                         aRequired            : Boolean = False;\n                         aDontShow            : TwbDontShowCallback = nil;\n                         aOptionalFromElement : Integer = -1;\n                         aAfterLoad           : TwbAfterLoadCallback = nil;\n                         aAfterSet            : TwbAfterSetCallback = nil;\n                         aGetCP               : TwbGetConflictPriority = nil)\n                                              : IwbStructDef; overload;\n\nfunction wbStructLZ(const aName                : string;\n                          aSizing              : TwbSizeCallback;\n                          aGetChapterType      : TwbGetChapterTypeCallback;\n                          aGetChapterTypeName  : TwbGetChapterTypeNameCallback;\n                          aGetChapterName      : TwbGetChapterNameCallback;\n                    const aMembers             : array of IwbValueDef;\n                          aPriority            : TwbConflictPriority = cpNormal;\n                          aRequired            : Boolean = False;\n                          aDontShow            : TwbDontShowCallback = nil;\n                          aOptionalFromElement : Integer = -1;\n                          aAfterLoad           : TwbAfterLoadCallback = nil;\n                          aAfterSet            : TwbAfterSetCallback = nil;\n                          aGetCP               : TwbGetConflictPriority = nil)\n                                               : IwbStructDef; overload;\n\nfunction wbRStruct(const aName           : string;\n                   const aMembers        : array of IwbRecordMemberDef;\n                   const aSkipSigs       : array of TwbSignature;\n                         aPriority       : TwbConflictPriority = cpNormal;\n                         aRequired       : Boolean = False;\n                         aDontShow       : TwbDontShowCallback = nil;\n                         aAllowUnordered : Boolean = False;\n                         aAfterLoad      : TwbAfterLoadCallback = nil;\n                         aAfterSet       : TwbAfterSetCallback = nil;\n                         aGetCP          : TwbGetConflictPriority = nil)\n                                         : IwbSubRecordStructDef; overload;\n\nfunction wbRStructSK(const aSortKey        : array of Integer;\n                     const aName           : string;\n                     const aMembers        : array of IwbRecordMemberDef;\n                     const aSkipSigs       : array of TwbSignature;\n                           aPriority       : TwbConflictPriority = cpNormal;\n                           aRequired       : Boolean = False;\n                           aDontShow       : TwbDontShowCallback = nil;\n                           aAllowUnordered : Boolean = False;\n                           aAfterLoad      : TwbAfterLoadCallback = nil;\n                           aAfterSet       : TwbAfterSetCallback = nil;\n                           aGetCP          : TwbGetConflictPriority = nil)\n                                           : IwbSubRecordStructDef; overload;\n\nfunction wbRStructExSK(const aSortKey        : array of Integer;\n                       const aExSortKey      : array of Integer;\n                       const aName           : string;\n                       const aMembers        : array of IwbRecordMemberDef;\n                       const aSkipSigs       : array of TwbSignature;\n                             aPriority       : TwbConflictPriority = cpNormal;\n                             aRequired       : Boolean = False;\n                             aDontShow       : TwbDontShowCallback = nil;\n                             aAllowUnordered : Boolean = False;\n                             aAfterLoad      : TwbAfterLoadCallback = nil;\n                             aAfterSet       : TwbAfterSetCallback = nil;\n                             aGetCP          : TwbGetConflictPriority = nil)\n                                             : IwbSubRecordStructDef; overload;\n\nfunction wbRUnion(const aName     : string;\n                  const aMembers  : array of IwbRecordMemberDef;\n                  const aSkipSigs : array of TwbSignature;\n                        aPriority : TwbConflictPriority = cpNormal;\n                        aRequired : Boolean = False;\n                        aDontShow : TwbDontShowCallback = nil;\n                        aGetCP    : TwbGetConflictPriority = nil)\n                                  : IwbSubRecordUnionDef;\n\n{--- wbStructS - array of struct ----------------------------------------------}\nfunction wbStructS(const aSignature   : TwbSignature;\n                   const aName        : string;\n                   const aElementName : string;\n                   const aMembers     : array of IwbValueDef;\n                         aPriority    : TwbConflictPriority = cpNormal;\n                         aRequired    : Boolean = False;\n                         aDontShow    : TwbDontShowCallback = nil;\n                         aGetCP       : TwbGetConflictPriority = nil)\n                                      : IwbSubRecordDef; overload;\n\nfunction wbStructS(const aName        : string;\n                   const aElementName : string;\n                   const aMembers     : array of IwbValueDef;\n                         aPriority    : TwbConflictPriority = cpNormal;\n                         aRequired    : Boolean = False;\n                         aDontShow    : TwbDontShowCallback = nil;\n                         aGetCP       : TwbGetConflictPriority = nil)\n                                      : IwbArrayDef; overload;\n\nfunction wbRStructS(const aName        : string;\n                    const aElementName : string;\n                    const aMembers     : array of IwbRecordMemberDef;\n                    const aSkipSigs    : array of TwbSignature;\n                          aPriority    : TwbConflictPriority = cpNormal;\n                          aRequired    : Boolean = False;\n                          aDontShow    : TwbDontShowCallback = nil;\n                          aGetCP       : TwbGetConflictPriority = nil)\n                                       : IwbSubRecordArrayDef; overload;\n\nfunction wbRStructsSK(const aName        : string;\n                      const aElementName : string;\n                      const aSortKey     : array of Integer;\n                      const aMembers     : array of IwbRecordMemberDef;\n                      const aSkipSigs    : array of TwbSignature;\n                            aPriority    : TwbConflictPriority = cpNormal;\n                            aRequired    : Boolean = False;\n                            aAfterLoad   : TwbAfterLoadCallback = nil;\n                            aAfterSet    : TwbAfterSetCallback = nil;\n                            aDontShow    : TwbDontShowCallback = nil;\n                            aGetCP       : TwbGetConflictPriority = nil)\n                                         : IwbSubRecordArrayDef; overload;\n\nfunction wbEmpty(const aSignature : TwbSignature;\n                 const aName      : string;\n                       aPriority  : TwbConflictPriority = cpNormal;\n                       aRequired  : Boolean = False;\n                       aDontShow  : TwbDontShowCallback = nil;\n                       aGetCP     : TwbGetConflictPriority = nil)\n                                  : IwbSubRecordDef; overload;\n\nfunction wbEmpty(const aName      : string;\n                       aPriority  : TwbConflictPriority = cpNormal;\n                       aRequired  : Boolean = False;\n                       aDontShow  : TwbDontShowCallback = nil;\n                       aSorted    : Boolean = False;\n                       aGetCP     : TwbGetConflictPriority = nil)\n                                  : IwbValueDef; overload;\n\nfunction wbRefID: IwbRefID; overload;\n\nfunction wbRefID(const aName      : string;\n                       aPriority  : TwbConflictPriority = cpNormal;\n                       aRequired  : Boolean = False;\n                       aDontShow  : TwbDontShowCallback = nil;\n                       aAfterSet  : TwbAfterSetCallback = nil;\n                       aGetCP     : TwbGetConflictPriority = nil)\n                                  : IwbIntegerDef; overload;\n\nfunction wbRefIDT(const aName      : string;\n                        aPriority  : TwbConflictPriority = cpNormal;\n                        aRequired  : Boolean = False;\n                        aDontShow  : TwbDontShowCallback = nil;\n                        aAfterSet  : TwbAfterSetCallback = nil;\n                        aGetCP     : TwbGetConflictPriority = nil)\n                                   : IwbIntegerDef; overload;\n\nfunction wbDumpInteger : IwbIntegerDefFormater; overload;\n\nfunction wbKey2Data6Enum(const aNames : array of string)\n                                      : IwbKey2Data6EnumDef; overload;\n\nfunction wbData6Key2Enum(const aNames : array of string)\n                                      : IwbData6Key2EnumDef; overload;\n\nfunction wbFormID: IwbFormID; overload;\n\nfunction wbFormID(const aValidRefs : array of TwbSignature;\n                        aPersistent: Boolean)\n                                   : IwbFormID; overload;\n\nfunction wbFormIDNoReach(const aValidRefs  : array of TwbSignature;\n                               aPersistent : Boolean)\n                                           : IwbFormID; overload;\n\nfunction wbFormID(const aValidRefs     : array of TwbSignature;\n                  const aValidFlstRefs : array of TwbSignature;\n                        aPersistent    : Boolean)\n                                       : IwbFormID; overload;\n\nfunction wbFormIDNoReach(const aValidRefs     : array of TwbSignature;\n                         const aValidFlstRefs : array of TwbSignature;\n                               aPersistent    : Boolean)\n                                              : IwbFormID; overload;\n\nfunction wbFormID(const aSignature : TwbSignature;\n                  const aName      : string = 'Unknown';\n                        aPriority  : TwbConflictPriority = cpNormal;\n                        aRequired  : Boolean = False;\n                        aDontShow  : TwbDontShowCallback = nil;\n                        aGetCP     : TwbGetConflictPriority = nil)\n                                   : IwbSubRecordDef; overload;\n\nfunction wbFormID(const aName      : string;\n                        aPriority  : TwbConflictPriority = cpNormal;\n                        aRequired  : Boolean = False;\n                        aDontShow  : TwbDontShowCallback = nil;\n                        aAfterSet  : TwbAfterSetCallback = nil)\n                                   : IwbIntegerDef; overload;\n\nfunction wbFormIDT(const aName      : string;\n                         aPriority  : TwbConflictPriority = cpNormal;\n                         aRequired  : Boolean = False;\n                         aDontShow  : TwbDontShowCallback = nil;\n                         aAfterSet  : TwbAfterSetCallback = nil;\n                         aGetCP     : TwbGetConflictPriority = nil)\n                                    : IwbIntegerDef; overload;\n\nfunction wbFormIDCk(const aSignature : TwbSignature;\n                    const aName      : string;\n                    const aValidRefs : array of TwbSignature;\n                          aPersistent: Boolean = False;\n                          aPriority  : TwbConflictPriority = cpNormal;\n                          aRequired  : Boolean = False;\n                          aDontShow  : TwbDontShowCallback = nil;\n                          aGetCP     : TwbGetConflictPriority = nil)\n                                     : IwbSubRecordDef; overload;\n\nfunction wbFormIDCkNoReach(const aSignature : TwbSignature;\n                           const aName      : string;\n                           const aValidRefs : array of TwbSignature;\n                                 aPersistent: Boolean = False;\n                                 aPriority  : TwbConflictPriority = cpNormal;\n                                 aRequired  : Boolean = False;\n                                 aDontShow  : TwbDontShowCallback = nil;\n                                 aGetCP     : TwbGetConflictPriority = nil)\n                                            : IwbSubRecordDef; overload;\n\nfunction wbFormIDCk(const aName      : string;\n                    const aValidRefs : array of TwbSignature;\n                          aPersistent: Boolean = False;\n                          aPriority  : TwbConflictPriority = cpNormal;\n                          aRequired  : Boolean = False;\n                          aDontShow  : TwbDontShowCallback = nil;\n                          aAfterSet  : TwbAfterSetCallback = nil)\n                                     : IwbIntegerDef; overload;\n\nfunction wbFormIDCkNoReach(const aName      : string;\n                           const aValidRefs : array of TwbSignature;\n                                 aPersistent: Boolean = False;\n                                 aPriority  : TwbConflictPriority = cpNormal;\n                                 aRequired  : Boolean = False;\n                                 aDontShow  : TwbDontShowCallback = nil;\n                                 aGetCP     : TwbGetConflictPriority = nil)\n                                            : IwbIntegerDef; overload;\n\nfunction wbFormIDCk(const aSignature     : TwbSignature;\n                    const aName          : string;\n                    const aValidRefs     : array of TwbSignature;\n                    const aValidFlstRefs : array of TwbSignature;\n                          aPersistent    : Boolean = False;\n                          aPriority      : TwbConflictPriority = cpNormal;\n                          aRequired      : Boolean = False;\n                          aDontShow      : TwbDontShowCallback = nil;\n                          aGetCP         : TwbGetConflictPriority = nil)\n                                         : IwbSubRecordDef; overload;\n\nfunction wbFormIDCk(const aName          : string;\n                    const aValidRefs     : array of TwbSignature;\n                    const aValidFlstRefs : array of TwbSignature;\n                          aPersistent    : Boolean = False;\n                          aPriority      : TwbConflictPriority = cpNormal;\n                          aRequired      : Boolean = False;\n                          aDontShow      : TwbDontShowCallback = nil;\n                          aGetCP         : TwbGetConflictPriority = nil)\n                                         : IwbIntegerDef; overload;\n\nfunction wbFormIDCkNoReach(const aName          : string;\n                           const aValidRefs     : array of TwbSignature;\n                           const aValidFlstRefs : array of TwbSignature;\n                                 aPersistent    : Boolean = False;\n                                 aPriority      : TwbConflictPriority = cpNormal;\n                                 aRequired      : Boolean = False;\n                                 aDontShow      : TwbDontShowCallback = nil;\n                                 aGetCP         : TwbGetConflictPriority = nil)\n                                                : IwbIntegerDef; overload;\n\nfunction wbChar4: IwbChar4;\n\nfunction wbStr4: IwbStr4;\n\nfunction wbFlags(const aNames           : array of string;\n                       aUnknownIsUnused : Boolean = False)\n                                        : IwbFlagsDef; overload;\nfunction wbFlags(const aNames           : array of string;\n                 const aFlagsToIgnore   : array of integer)\n                                        : IwbFlagsDef; overload;\nfunction wbFlags(const aNames           : array of string;\n                 const aDontShows       : array of TwbDontShowCallback;\n                       aUnknownIsUnused : Boolean = False)\n                                        : IwbFlagsDef; overload;\n\nfunction wbFlags(const aBaseFlagsDef    : IwbFlagsDef;\n                 const aNames           : array of string;\n                       aUnknownIsUnused : Boolean = False)\n                                        : IwbFlagsDef; overload;\nfunction wbFlags(const aBaseFlagsDef    : IwbFlagsDef;\n                 const aNames           : array of string;\n                 const aFlagsToIgnore   : array of integer)\n                                        : IwbFlagsDef; overload;\nfunction wbFlags(const aBaseFlagsDef    : IwbFlagsDef;\n                 const aNames           : array of string;\n                 const aDontShows       : array of TwbDontShowCallback;\n                       aUnknownIsUnused : Boolean = False)\n                                        : IwbFlagsDef; overload;\n\nfunction wbEnum(const aNames : array of string)\n                             : IwbEnumDef; overload;\nfunction wbEnum(const aNames       : array of string;\n                const aSparseNames : array of const)\n                                   : IwbEnumDef; overload;\n\n\nfunction wbDiv(aValue : Integer)\n                      : IwbIntegerDefFormater;\nfunction wbMul(aValue : Integer)\n                      : IwbIntegerDefFormater;\nfunction wbCallback(const aToStr : TwbIntToStrCallback;\n                    const aToInt : TwbStrToIntCallback)\n                                 : IwbIntegerDefFormater;\n\nfunction wbFormaterUnion(aDecider : TwbIntegerDefFormaterUnionDecider;\n                         aMembers : array of IwbIntegerDefFormater)\n                                  : IwbIntegerDefFormaterUnion;\n\nfunction wbIsPlugin(aFileName: string): Boolean;\n\nfunction wbStr4ToString(aInt: Int64): string;\n\ntype\n  PwbRecordDefEntry = ^TwbRecordDefEntry;\n  TwbRecordDefEntry = record\n    rdeSignature : TwbSignature;\n    rdeHash      : Integer;\n    rdeDef       : IwbRecordDef;\n    rdeNext      : Integer;\n  end;\n\n  TwbRecordDefEntries = array of TwbRecordDefEntry;\n\nconst\n  RecordDefHashMapSize = 1546;\n\nvar\n  wbRecordDefs       : TwbRecordDefEntries;\n  wbRecordDefHashMap : array[0..Pred(RecordDefHashMapSize)] of Integer;\n\n  wbIgnoreRecords    : TStringList;\n  wbGroupOrder       : TStringList;\n  wbLoadBSAs         : Boolean{} = True{};\n  wbLoadAllBSAs      : Boolean{} = False{};\n  wbArchiveExtension : string = '.bsa';\n  wbBuildRefs        : Boolean{} = True{};\n  wbContainerHandler : IwbContainerHandler;\n  wbLoaderDone       : Boolean;\n  wbLoaderError      : Boolean;\n\nprocedure wbAddGroupOrder(const aSignature: TwbSignature);\nfunction wbGetGroupOrder(const aSignature: TwbSignature): Integer;\n\nfunction IntToHex64(Value: Int64; Digits: Integer): string; inline;\nfunction CmpB8(a, b: Byte): Integer;\nfunction CmpI32(a, b : Integer) : Integer;\nfunction CmpW32(a, b: Cardinal): Integer;\nfunction CmpI64(const a, b : Int64) : Integer;\nfunction CompareElementsFormIDAndLoadOrder(Item1, Item2: Pointer): Integer;\n\nfunction ConflictAllToColor(aConflictAll: TConflictAll): TColor;\nfunction ConflictThisToColor(aConflictThis: TConflictThis): TColor;\n\nvar\n  wbGetFormIDCallback : function(const aElement: IwbElement): Cardinal;\n\nfunction wbFlagsList(aFlags: array of const; aDeleted : Boolean = True; aUnknowns: Boolean = False): TDynStrings;\nfunction wbGetFormID(const aElement: IwbElement): Cardinal;\nfunction wbPositionToGridCell(const aPosition: TwbVector): TwbGridCell;\nfunction wbSubBlockFromGridCell(const aGridCell: TwbGridCell): TwbGridCell;\nfunction wbBlockFromSubBlock(const aSubBlock: TwbGridCell): TwbGridCell;\nfunction wbGridCellToGroupLabel(const aGridCell: TwbGridCell): Cardinal;\nfunction wbIsInGridCell(const aPosition: TwbVector; const aGridCell: TwbGridCell): Boolean;\n\nvar\n  wbRecordFlags            : IwbIntegerDef;\n  wbMainRecordHeader       : IwbStructDef;\n  wbSizeOfMainRecordStruct : Integer;\n\ntype\n  TwbGameMode   = (gmFNV, gmFO3, gmTES3, gmTES4, gmTES5, gmSSE, gmFO4);\n  TwbToolMode   = (tmView, tmEdit, tmDump, tmExport, tmMasterUpdate, tmMasterRestore, tmLODgen, tmScript,\n                    tmTranslate, tmESMify, tmESPify, tmSortAndCleanMasters,\n                    tmCheckForErrors, tmCheckForITM, tmCheckForDR);\n  TwbToolSource = (tsPlugins, tsSaves);\n  TwbSetOfMode  = set of TwbToolMode;\n\nvar\n  wbGameMode    : TwbGameMode;\n  wbToolMode    : TwbToolMode;\n  wbToolSource  : TwbToolSource;\n  wbAppName     : string;\n  wbGameName    : string;\n  wbGameName2   : string; // game title name\n  wbToolName    : string;\n  wbSourceName  : String;\n  wbLanguage    : string;\n  wbAutoModes   : TwbSetOfMode = [ tmMasterUpdate, tmMasterRestore, tmLODgen, // Tool modes that run without user interaction until final status\n                    tmESMify, tmESPify, tmSortAndCleanMasters,\n                    tmCheckForErrors, tmCheckForITM, tmCheckForDR ];\n  wbPluginModes : TwbSetOfMode = [ tmESMify, tmESPify, tmSortAndCleanMasters,\n                                   tmCheckForErrors, tmCheckForITM, tmCheckForDR ];  // Auto modes that require a specific plugin to be provided.\n  wbAlwaysMode  : TwbSetOfMode = [ tmView, tmEdit, tmESMify, tmESPify, tmSortAndCleanMasters,\n                    tmLODgen, tmScript, tmCheckForITM, tmCheckForDR, tmCheckForErrors ]; // Modes available to all decoded games\n\nfunction wbDefToName(const aDef: IwbDef): string;\nfunction wbDefsToPath(const aDefs: TwbDefPath): string;\n\nprocedure ReportDefs;\n\ntype\n  IwbProgress = interface\n    ['{054006B0-096D-43CD-A92A-3095B525C854}']\n\n    procedure UpdateStatus(aPosition: Integer; const aStatus: string);\n  end;\n\n  IwbWaitForm = interface\n    ['{185C220C-3135-4A8A-8E0E-8001759F3C85}']\n    function GetIsCanceled: Boolean;\n\n    function CreateProgress(const aCaption : string;\n                            const aStatus  : string;\n                                  aMax     : Integer)\n                                           : IwbProgress;\n\n    property IsCanceled: Boolean\n      read GetIsCanceled;\n  end;\n\n  TwbCreateWaitForm = function(const aCaption     : string;\n                               const aMessage     : string;\n                                     aCanCancel   : Boolean;\n                                     aShowDelay   : Integer = 0;\n                                     aUpdateDelay : Integer = 0)\n                                                  : IwbWaitForm;\n\nfunction NullCreateWaitForm(const aCaption     : string;\n                            const aMessage     : string;\n                                  aCanCancel   : Boolean;\n                                  aShowDelay   : Integer = 0;\n                                  aUpdateDelay : Integer = 0)\n                                               : IwbWaitForm;\n\nvar\n  wbCreateWaitForm : TwbCreateWaitForm = NullCreateWaitForm;\n\ntype\n  TwbFastStringList = class(TStringList)\n  protected\n    function CompareStrings(const S1, S2: string): Integer; override;\n  public\n    constructor CreateSorted(aDups : TDuplicates = dupError);\n\n    procedure Clear(aFreeObjects: Boolean = False); reintroduce;\n  end;\n\n  TwbFastStringListCS = class(TwbFastStringList)\n  public\n    procedure AfterConstruction; override;\n  end;\n\n  TwbFastStringListIC = class(TwbFastStringList)\n  end;\n\nfunction RadiansNormalize(const aElement: IwbElement; aFloat: Extended): Extended;\n\nfunction wbBeginInternalEdit(aForce: Boolean = False): Boolean;\nprocedure wbEndInternalEdit;\nfunction wbIsInternalEdit: Boolean;\n\nfunction StrToSignature(const s: string): TwbSignature;\nfunction wbStringToAnsi(const aString: string; const aElement: IwbElement): AnsiString;\nfunction wbAnsiToString(const aString: AnsiString; const aElement: IwbElement): string;\n\nfunction FixupFormID(aFormID: Cardinal; const aOld, aNew: TBytes): Cardinal;\n\nthreadvar\n  _InternalEditCount: Integer;\n  _BlockInternalEdit: Boolean;\n\nvar\n  wbActorValueEnum: IwbEnumDef;\n\nfunction GetContainerFromUnion(const aElement: IwbElement): IwbContainer;\nfunction GetContainerRefFromUnionOrValue(const aElement: IwbElement): IwbContainerElementRef;\nfunction GetElementFromUnion(const aElement: IwbElement): IwbElement;\n\nvar\n  wbHeaderSignature   : TwbSignature = 'TES4';\n  wbFileMagic         : TwbFileMagic;\n  wbFilePlugins       : String = 'Master Files';\n  wbUseFalsePlugins   : Boolean = False;\n  wbFileHeader        : IwbStructDef;\n  wbFileChapters      : IwbStructDef;\n  wbBytesToSkip       : Cardinal = 0;\n  wbBytesToDump       : Cardinal = $FFFFFFFF;\n  wbBytesToGroup      : Cardinal = 4;\n  wbExtractInfo       : ^TByteSet;\n  wbTerminator        : Byte = Ord('|');\n  wbPlayerRefID       : Cardinal = $14;\n  wbChangedFormOffset : Integer = 10000;\n  wbOfficialDLC       : array of string;\n\ntype\n  {$IFDEF WIN32}\n  TwbRefIDArray = array of Cardinal;\n  {$ENDIF WIN32}\n  {$IFDEF WIN64}\n  TwbRefIDArray = array of UInt64;\n  {$ENDIF WIN64}\n\nfunction wbReadInteger24(aBasePtr: pointer): Int64;\nprocedure InitializeRefIDArray(anArray: TwbRefIDArray);\n\nfunction wbFindRecordDef(const aSignature : TwbSignature;\n                           out aRecordDef : PwbRecordDef)\n                                          : Boolean; overload;\n\nfunction wbFindRecordDef(const aSignature : AnsiString;\n                           out aRecordDef : PwbRecordDef)\n                                          : Boolean; overload;\n\nfunction _wbRecordDefMap: TStringList;\n\nimplementation\n\nuses\n  Windows,\n  Variants,\n  Math,\n  AnsiStrings,\n  TypInfo,\n  wbSort,\n  wbLocalization;\n\nfunction StrToSignature(const s: string): TwbSignature;\nvar\n  t: AnsiString;\nbegin\n  t := AnsiString(s);\n  if Length(t) >= 4 then\n    Result := PwbSignature(@t[1])^\n  else\n    raise Exception.Create('\"'+t+'\" is not a valid signature');\nend;\n\nfunction IsTranslatable(const aElement: IwbElement): Boolean;\nvar\n  Def: IwbDef;\nbegin\n  Result := False;\n\n  if Assigned(aElement) then begin\n    Def := aElement.ValueDef;\n    if not Assigned(Def) then\n      Def := aElement.Def;\n\n    if Assigned(Def) then\n       Result := Def.ConflictPriority[aElement] = cpTranslate;\n  end;\nend;\n\nfunction wbStringToAnsi(const aString: String; const aElement: IwbElement): AnsiString;\nvar\n  Translatable: Boolean;\nbegin\n  if Assigned(aElement) then\n    Translatable := IsTranslatable(aElement)\n  else\n    Translatable := True;\n\n  if Translatable and (wbStringEncoding = seUTF8) then\n    Result := UTF8Encode(aString)\n  else\n    Result := AnsiString(aString);\nend;\n\nfunction wbAnsiToString(const aString: AnsiString; const aElement: IwbElement): string;\nvar\n  Translatable: Boolean;\nbegin\n  if Assigned(aElement) then\n    Translatable := IsTranslatable(aElement)\n  else\n    Translatable := True;\n\n  if Translatable and (wbStringEncoding = seUTF8) then\n    Result := UTF8Decode(aString)\n  else\n    Result := string(aString);\nend;\n\nfunction wbBeginInternalEdit(aForce: Boolean): Boolean;\nbegin\n  Result := wbEditAllowed and (wbAllowInternalEdit or aForce) and not _BlockInternalEdit;\n  if Result then\n    Inc(_InternalEditCount);\nend;\n\nprocedure wbEndInternalEdit;\nbegin\n  Dec(_InternalEditCount);\nend;\n\nfunction wbIsInternalEdit: Boolean;\nbegin\n  Result := _InternalEditCount > 0;\nend;\n\n\nvar\n  OnePi : Single = 3.1415927;//(2!) 653589793238462643383279502884197169399375105820974944592307816406286208998628034825342117067;\n  TwoPi : Extended;\n\nfunction RoundToEx(const AValue: Extended; const ADigit: TRoundToRange): Extended;\nvar\n  LFactor: Extended;\nbegin\n  LFactor := IntPower(10, ADigit);\n  Result := Round(AValue / LFactor) * LFactor;\nend;\n\nfunction DoSingleSameValue(const A, B: Single): Boolean;\nconst\n  SingleResolution : Single = 0.000000499999999999999999999;\nbegin\n  Result := Abs(A - B) <= Max(Min(Abs(A), Abs(B)) * SingleResolution, SingleResolution)\nend;\n\nfunction SingleSameValue(const A, B: Extended): Boolean;\nvar\n  sA, sB: Single;\nbegin\n  sA := A;\n  sB := B;\n  Result := DoSingleSameValue(sA, sB);\nend;\n\nfunction RadiansNormalize(const aElement: IwbElement; aFloat: Extended): Extended;\nbegin\n//  Result := RoundToEx(aFloat, -6);\n  Result := aFloat;\n\n  if Abs(Result/TwoPi) > 100.0 then\n    Result := Result - Sign(Result)*TwoPi*Trunc(Abs(Result/TwoPi) - 100.0);\n\n  while Result < 0.0 do\n    Result := Result + TwoPi;\n  while Result > TwoPi do\n    Result := Result - TwoPi;\n  if SingleSameValue(Result, 0.0) or (Result < 0.0) then\n    Result := 0.0;\n  if SingleSameValue(Result, TwoPi) or (Result > TwoPi) then\n    Result := 0.0;\n\n//  Result := RoundToEx(Result, -6);\nend;\n\ntype\n  TwbNullWaitForm = class(TInterfacedObject, IwbWaitForm)\n  protected\n    {--- IwbWaitForm ---}\n    function GetIsCanceled: Boolean;\n\n    function CreateProgress(const aCaption : string;\n                            const aStatus  : string;\n                                  aMax     : Integer)\n                                           : IwbProgress;\n  end;\n\n  TwbNullProgress = class(TInterfacedObject, IwbProgress)\n  protected\n    {--- IwbProgress ---}\n    procedure UpdateStatus(aPosition: Integer; const aStatus: string);\n  end;\n\n{ TwbNullWaitForm }\n\nfunction TwbNullWaitForm.CreateProgress(const aCaption, aStatus: string; aMax: Integer): IwbProgress;\nbegin\n  Result := TwbNullProgress.Create;\nend;\n\nfunction TwbNullWaitForm.GetIsCanceled: Boolean;\nbegin\n  Result := False;\nend;\n\n{ TwbNullProgress }\n\nprocedure TwbNullProgress.UpdateStatus(aPosition: Integer; const aStatus: string);\nbegin\nend;\n\nfunction NullCreateWaitForm(const aCaption     : string;\n                            const aMessage     : string;\n                                  aCanCancel   : Boolean;\n                                  aShowDelay   : Integer = 0;\n                                  aUpdateDelay : Integer = 0)\n                                               : IwbWaitForm;\nbegin\n  Result := TwbNullWaitForm.Create;\nend;\n\nprocedure ReportDefs;\nvar\n  i: Integer;\nbegin\n  for i:= Low(wbRecordDefs) to High(wbRecordDefs) do\n    wbRecordDefs[i].rdeDef.Report(nil);\nend;\n\nfunction wbDefToName(const aDef: IwbDef): string;\nvar\n  SignatureDef : IwbSignatureDef;\n  Signature    : TwbSignature;\n  NamedDef     : IwbNamedDef;\n  i            : Integer;\nbegin\n  if Supports(aDef, IwbSignatureDef, SignatureDef) then begin\n    Signature := SignatureDef.DefaultSignature;\n    if Signature[0]=#0 then\n      Result := '$(00)'+Signature[1]+Signature[2]+Signature[3] + ' - ' + SignatureDef.Name\n    else\n      Result := Signature + ' - ' + SignatureDef.Name;\n  end else if Supports(aDef, IwbNamedDef, NamedDef) then begin\n    Result := NamedDef.Name;\n  end else if Assigned(aDef) then begin\n    Result := '<'+GetEnumName(TypeInfo(TwbDefType), Ord(aDef.DefType))+'>';\n  end else\n    Result := '<nil>';\n  for i := Length(Result) downto 1 do\n    if Result[i]<' ' then begin\n      Insert('$('+IntToHex(Ord(Result[i]), 2)+')', Result, i);\n      Delete(Result, i + 5, 1);\n    end;\nend;\n\nfunction wbDefsToPath(const aDefs: TwbDefPath): string;\nvar\n  i: Integer;\nbegin\n  Result := '';\n  for i := Low(aDefs) to High(aDefs) do begin\n    Result := Result + wbDefToName(aDefs[i].Def) + ' \\ ';\n    if aDefs[i].Index >= 0 then\n      Result := Result + '['+IntToStr(aDefs[i].Index)+'] ';\n  end;\nend;\nfunction wbIsInGridCell(const aPosition: TwbVector; const aGridCell: TwbGridCell): Boolean;\nvar\n  GridCell : TwbGridCell;\nbegin\n  GridCell := wbPositionToGridCell(aPosition);\n  Result := (GridCell.x = aGridCell.x) and (GridCell.y = aGridCell.y);\nend;\n\nfunction wbPositionToGridCell(const aPosition: TwbVector): TwbGridCell;\nbegin\n  Result.x := Trunc(aPosition.x / 4096);\n  if aPosition.x < 0 then\n    Dec(Result.x);\n  Result.y := Trunc(aPosition.y / 4096);\n  if aPosition.y < 0 then\n    Dec(Result.y);\nend;\n\nfunction wbSubBlockFromGridCell(const aGridCell: TwbGridCell): TwbGridCell;\nbegin\n  Result.x := aGridCell.x div 8;\n  if (aGridCell.x < 0) and ((aGridCell.x mod 8) <> 0) then\n    Dec(Result.x);\n  Result.y := aGridCell.y div 8;\n  if (aGridCell.y < 0) and ((aGridCell.y mod 8) <> 0) then\n    Dec(Result.y);\nend;\n\nfunction wbBlockFromSubBlock(const aSubBlock: TwbGridCell): TwbGridCell;\nbegin\n  Result.x := aSubBlock.x div 4;\n  if (aSubBlock.x < 0) and ((aSubBlock.x mod 4) <> 0) then\n    Dec(Result.x);\n  Result.y := aSubBlock.y div 4;\n  if (aSubBlock.y < 0) and ((aSubBlock.y mod 4) <> 0) then\n    Dec(Result.y);\nend;\n\nfunction wbGridCellToGroupLabel(const aGridCell: TwbGridCell): Cardinal;\nvar\n  x, y: Smallint;\n  xx,yy: Word;\nbegin\n  x := aGridCell.x;\n  y := aGridCell.y;\n  xx := PWord(@x)^;\n  yy := PWord(@y)^;\n  Result := Cardinal(yy) or (Cardinal(xx) shl 16);\nend;\n\nfunction wbGetFormID(const aElement: IwbElement): Cardinal;\nbegin\n  if Assigned(wbGetFormIDCallback) then\n    Result := wbGetFormIDCallback(aElement)\n  else\n    Result := 0;\nend;\n\nfunction ConflictAllToColor(aConflictAll: TConflictAll): TColor;\nbegin\n  Result := wbColorConflictAll[aConflictAll];\nend;\n\nfunction ConflictThisToColor(aConflictThis: TConflictThis): TColor;\nbegin\n  Result := wbColorConflictThis[aConflictThis];\nend;\n\nprocedure wbAddGroupOrder(const aSignature: TwbSignature);\nbegin\n  if not Assigned(wbGroupOrder) then\n    wbGroupOrder := TwbFastStringListCS.CreateSorted;\n  wbGroupOrder.AddObject(aSignature, Pointer(wbGroupOrder.Count));\nend;\n\nfunction wbGetGroupOrder(const aSignature: TwbSignature): Integer;\nbegin\n  if Assigned(wbGroupOrder) then begin\n    Result := wbGroupOrder.IndexOf(aSignature);\n    if Result >= 0 then\n      Result := Integer(wbGroupOrder.Objects[Result]);\n  end else\n    Result := -1;\nend;\n\nfunction CompareElementsFormIDAndLoadOrder(Item1, Item2: Pointer): Integer;\nvar\n  MainRecord1, MainRecord2: IwbMainRecord;\nbegin\n  if Item1 = Item2 then begin\n    Result := 0;\n    Exit;\n  end;\n\n  MainRecord1 := IwbElement(Item1) as IwbMainRecord;\n  MainRecord2 := IwbElement(Item2) as IwbMainRecord;\n\n  Result := CmpW32(\n    MainRecord1.LoadOrderFormID,\n    MainRecord2.LoadOrderFormID);\n  if Result = 0 then\n    Result := CmpI32(\n      MainRecord1._File.LoadOrder,\n      MainRecord2._File.LoadOrder);\nend;\n\nfunction wbFlagsList(aFlags: array of const; aDeleted : Boolean = True; aUnknowns: Boolean = False): TDynStrings;\nvar\n  e: IwbEnumDef;\n  i: integer;\n  s: string;\nbegin\n  e := wbEnum([], aFlags);\n  SetLength(Result, 32);\n  for i := 0 to 31 do\n    if i = 12 then\n      Result[i] := 'Ignored'\n    else if aDeleted and (i = 5) then\n      Result[i] := 'Deleted'\n    else begin\n      s := e.ToString(i, nil);\n      if Pos('<', s) <> 1 then\n        Result[i] := s\n      else if aUnknowns then\n        Result[i] := 'Unknown ' + IntToStr(i);\n    end\nend;\n\ntype\n  TwbDef = class;\n\n  IwbDefInternal = interface(IwbDef)\n    ['{8EBA62A9-AF6B-4377-B52C-A1CEBF5B3ED6}']\n    function SetParent(const aParent: TwbDef; aForceDuplicate: Boolean): IwbDef;\n  end;\n\n  TwbDefClass = class of TwbDef;\n  TwbDef = class(TInterfacedObject, IwbDef, IwbDefInternal)\n  private\n    defSource   : IwbDef;\n    defParent   : TwbDef;\n\n    defPriority : TwbConflictPriority;\n    defGetCP    : TwbGetConflictPriority;\n    defRequired : Boolean;\n\n    defUsed     : Boolean;\n    defReported : Boolean;\n    defPossiblyRequired : Boolean;\n    defNotRequired : Boolean;\n\n    IsUnknown        : Boolean;\n    IsUnknownChecked : Boolean;\n    UnknownValues    : TStringList;\n  protected\n    constructor Clone(const aSource: TwbDef); virtual;\n    constructor Create(aPriority: TwbConflictPriority; aRequired: Boolean; aGetCP: TwbGetConflictPriority);\n\n    {---IwbDef---}\n    function GetDefType: TwbDefType; virtual; abstract;\n    function GetDefTypeName: string; virtual; abstract;\n    function CanAssign(const aElement: IwbElement; aIndex: Integer; const aDef: IwbDef): Boolean; virtual;\n    function Assign(const aTarget: IwbElement; aIndex: Integer; const aSource: IwbElement; aOnlySK: Boolean): IwbElement; virtual;\n    function GetDefID: Cardinal;\n    function Equals(const aDef: IwbDef): Boolean; reintroduce; virtual;\n    function GetConflictPriority(const aElement: IwbElement): TwbConflictPriority; virtual;\n    function GetConflictPriorityCanChange: Boolean; virtual;\n    function GetRequired: Boolean;\n    function CanContainFormIDs: Boolean; virtual;\n    function GetDontShow(const aElement: IwbElement): Boolean; virtual;\n    function GetHasDontShow: Boolean; virtual;\n    function GetRoot: IwbDef;\n    function GetParent: IwbDef;\n\n    procedure Report(const aParents: TwbDefPath); virtual;\n    procedure Used(const aElement: IwbElement; const s: string);\n    procedure PossiblyRequired;\n    procedure NotRequired;\n    function IsNotRequired: Boolean;\n    function GetNoReach: Boolean; virtual;\n\n    {--- IwbDefInternal ---}\n    function SetParent(const aParent: TwbDef; aForceDuplicate: Boolean): IwbDef; virtual;\n    procedure ParentSet; virtual;\n\n    function Duplicate: TwbDef;\n  end;\n\n  TwbNamedDef = class(TwbDef, IwbNamedDef)\n  private\n    noName       : string;\n    noAfterLoad  : TwbAfterLoadCallback;\n    noAfterSet   : TwbAfterSetCallback;\n    noDontShow   : TwbDontShowCallback;\n    noTerminator : Boolean;\n    noUnused     : Boolean;\n    noTreeHead   : Boolean;\n    noTreeBranch : Boolean;\n  protected\n    constructor Clone(const aSource: TwbDef); override;\n    constructor Create(aPriority   : TwbConflictPriority;\n                       aRequired   : Boolean;\n                 const aName       : string;\n                       aAfterLoad  : TwbAfterLoadCallback;\n                       aAfterSet   : TwbAfterSetCallback;\n                       aDontShow   : TwbDontShowCallback;\n                       aGetCP      : TwbGetConflictPriority;\n                       aTerminator : Boolean);\n    {--- IwbDef ---}\n    function GetDontShow(const aElement: IwbElement): Boolean; override;\n    function GetHasDontShow: Boolean; override;\n\n    {--- IwbDefInternal ---}\n    procedure ParentSet; override;\n\n    {---IwbNamedDef---}\n    function GetName: string;\n    function GetPath: string;\n    procedure AfterLoad(const aElement: IwbElement); virtual;\n    procedure AfterSet(const aElement: IwbElement; const aOldValue, aNewValue: Variant);\n    function GetTreeHead: Boolean;              // Is the element expected to be a \"header record\" in the tree navigator\n    procedure SetTreeHead(aValue: Boolean);     // Make the element a \"header record\" in the tree navigator;\n    function GetTreeBranch: Boolean;            // Is the element included in a \"leaf\" expected to be displayed in the view pane\n    procedure SetTreeBranch(aValue: Boolean);   // Make the element included in a \"leaf\" visible in the tree navigator;\n  end;\n\n  TwbSignatureDef = class(TwbNamedDef, IwbSignatureDef)\n  private\n    soSignatures : TwbSignatures;\n  protected\n    constructor Clone(const aSource: TwbDef); override;\n    constructor Create(aPriority  : TwbConflictPriority;\n                       aRequired  : Boolean;\n                 const aSignature : TwbSignature;\n                 const aName      : string;\n                       aAfterLoad : TwbAfterLoadCallback;\n                       aAfterSet  : TwbAfterSetCallback;\n                       aDontShow  : TwbDontShowCallback;\n                       aGetCP     : TwbGetConflictPriority); overload;\n    constructor Create(aPriority   : TwbConflictPriority;\n                       aRequired   : Boolean;\n                 const aSignatures : array of TwbSignature;\n                 const aName       : string;\n                       aAfterLoad  : TwbAfterLoadCallback;\n                       aAfterSet   : TwbAfterSetCallback;\n                       aDontShow   : TwbDontShowCallback;\n                       aGetCP      : TwbGetConflictPriority); overload;\n\n    {---IwbSignatureDef---}\n    function GetDefaultSignature: TwbSignature;\n\n    function GetSignatures(const aIndex: Integer): TwbSignature;\n    function GetSignatureCount: Integer;\n\n    function CanHandle(aSignature     : TwbSignature;\n                 const aDataContainer : IwbDataContainer)\n                                      : Boolean; virtual;\n  end;\n\n  TwbRecordDef = class(TwbSignatureDef, IwbRecordDef)\n  private\n    recRecordFlags        : IwbIntegerDefFormater;\n    recRecordHeaderStruct : IwbStructDef;\n    recMembers            : array of IwbRecordMemberDef;\n    recSignatures         : TStringList;\n    recAllowUnordered     : Boolean;\n    recAddInfoCallback    : TwbAddInfoCallback;\n    recCanContainFormIDs  : Boolean;\n    recQuickInitLimit     : Integer;\n    recContainsEditorID   : Boolean;\n  protected\n    constructor Clone(const aSource: TwbDef); override;\n    constructor Create(aPriority        : TwbConflictPriority;\n                       aRequired        : Boolean;\n                 const aSignature       : TwbSignature;\n                 const aName            : string;\n                 const aRecordFlags     : IwbIntegerDefFormater;\n                 const aMembers         : array of IwbRecordMemberDef;\n                       aAllowUnordered  : Boolean;\n                       aAddInfoCallback : TwbAddInfoCallback;\n                       aAfterLoad       : TwbAfterLoadCallback;\n                       aAfterSet        : TwbAfterSetCallback);\n    destructor Destroy; override;\n\n    {---IwbDef---}\n    function GetDefType: TwbDefType; override;\n    function GetDefTypeName: string; override;\n    procedure Report(const aParents: TwbDefPath); override;\n\n    {---IwbRecordDef---}\n    function ContainsMemberFor(aSignature     : TwbSignature;\n                         const aDataContainer : IwbDataContainer)\n                                              : Boolean;\n    function GetMemberFor(aSignature     : TwbSignature;\n                    const aDataContainer : IwbDataContainer)\n                                         : IwbRecordMemberDef;\n    function GetMemberIndexFor(aSignature     : TwbSignature;\n                         const aDataContainer : IwbDataContainer)\n                                              : Integer;\n    function AllowUnordered: Boolean;\n    function AdditionalInfoFor(const aMainRecord: IwbMainRecord): string;\n\n    function GetMember(aIndex: Integer): IwbRecordMemberDef;\n    function GetMemberCount: Integer;\n    function CanContainFormIDs: Boolean; override;\n    function GetSkipSignature(const aSignature: TwbSignature): Boolean; virtual;\n    function GetQuickInitLimit: Integer;\n    function GetContainsEditorID: Boolean;\n    function GetRecordHeaderStruct: IwbStructDef;\n\n    procedure AfterLoad(const aElement: IwbElement); override;\n  end;\n\n  TwbSubRecordDef = class(TwbSignatureDef, IwbRecordMemberDef, IwbSubRecordDef)\n  private\n    srValue     : IwbValueDef;\n    srSizeMatch : Boolean;\n\n    srHasUnusedData: Boolean;\n  protected\n    constructor Clone(const aSource: TwbDef); override;\n    constructor Create(aPriority  : TwbConflictPriority;\n                       aRequired  : Boolean;\n                 const aSignature : TwbSignature;\n                 const aName      : string;\n                 const aValue     : IwbValueDef;\n                       aAfterLoad : TwbAfterLoadCallback;\n                       aAfterSet  : TwbAfterSetCallback;\n                       aSizeMatch : Boolean;\n                       aDontShow  : TwbDontShowCallback;\n                       aGetCP     : TwbGetConflictPriority); overload;\n    constructor Create(aPriority   : TwbConflictPriority;\n                       aRequired   : Boolean;\n                 const aSignatures : array of TwbSignature;\n                 const aName       : string;\n                 const aValue      : IwbValueDef;\n                       aAfterLoad  : TwbAfterLoadCallback;\n                       aAfterSet   : TwbAfterSetCallback;\n                       aSizeMatch  : Boolean;\n                       aDontShow   : TwbDontShowCallback;\n                       aGetCP      : TwbGetConflictPriority); overload;\n\n    {---IwbDef---}\n    function GetDefType: TwbDefType; override;\n    function GetDefTypeName: string; override;\n    function CanAssign(const aElement: IwbElement; aIndex: Integer; const aDef: IwbDef): Boolean; override;\n    procedure Report(const aParents: TwbDefPath); override;\n\n    {---IwbSubRecordDef---}\n    function GetValue: IwbValueDef;\n    function CanContainFormIDs: Boolean; override;\n    procedure HasUnusedData;\n    function CanHandle(aSignature     : TwbSignature;\n                 const aDataContainer : IwbDataContainer)\n                                      : Boolean; override;\n  end;\n\n  TwbSubRecordArrayDef = class(TwbNamedDef, IwbRecordMemberDef, IwbSubRecordArrayDef)\n  private\n    sraElement  : IwbRecordMemberDef;\n    sraSorted   : Boolean;\n    sraIsSorted : TwbIsSortedCallback;\n  public\n    constructor Clone(const aSource: TwbDef); override;\n    constructor Create(aPriority  : TwbConflictPriority; aRequired: Boolean;\n                 const aName      : string;\n                 const aElement   : IwbRecordMemberDef;\n                       aSorted    : Boolean;\n                       aAfterLoad : TwbAfterLoadCallback;\n                       aAfterSet  : TwbAfterSetCallback;\n                       aDontShow  : TwbDontShowCallback;\n                       aIsSorted  : TwbIsSortedCallback;\n                       aGetCP     : TwbGetConflictPriority);\n\n    {---IwbDef---}\n    function GetDefType: TwbDefType; override;\n    function GetDefTypeName: string; override;\n    function CanAssign(const aElement: IwbElement; aIndex: Integer; const aDef: IwbDef): Boolean; override;\n    function CanContainFormIDs: Boolean; override;\n    procedure Report(const aParents: TwbDefPath); override;\n\n    {---IwbNamedDef---}\n    procedure AfterLoad(const aElement: IwbElement); override;\n\n    {---IwbSignatureDef---}\n    function GetDefaultSignature: TwbSignature;\n\n    function GetSignatures(const aIndex: Integer): TwbSignature;\n    function GetSignatureCount: Integer;\n\n    function CanHandle(aSignature     : TwbSignature;\n                 const aDataContainer : IwbDataContainer)\n                                      : Boolean; virtual;\n\n    {---IwbSubRecordArrayDef---}\n    function GetElement: IwbRecordMemberDef;\n    function GetSorted(const aContainer: IwbContainer): Boolean;\n  end;\n\n  TwbSubRecordStructDef = class(TwbNamedDef, IwbRecordMemberDef, IwbSubRecordStructDef, IwbRecordDef)\n  private\n    srsMembers           : array of IwbRecordMemberDef;\n    srsSignatures        : TStringList;\n    srsSkipSignatures    : TStringList;\n    srsCanContainFormIDs : Boolean;\n    srsAllowUnordered    : Boolean;\n  public\n    constructor Clone(const aSource: TwbDef); override;\n    constructor Create(aPriority       : TwbConflictPriority;\n                       aRequired       : Boolean;\n                 const aName           : string;\n                 const aMembers        : array of IwbRecordMemberDef;\n                 const aSkipSigs       : array of TwbSignature;\n                       aDontShow       : TwbDontShowCallback;\n                       aAllowUnordered : Boolean;\n                       aAfterLoad      : TwbAfterLoadCallback;\n                       aAfterSet       : TwbAfterSetCallback;\n                       aGetCP          : TwbGetConflictPriority);\n    destructor Destroy; override;\n\n    {---IwbDef---}\n    function GetDefType: TwbDefType; override;\n    function GetDefTypeName: string; override;\n    function CanAssign(const aElement: IwbElement; aIndex: Integer; const aDef: IwbDef): Boolean; override;\n    function CanContainFormIDs: Boolean; override;\n    procedure Report(const aParents: TwbDefPath); override;\n\n    {---IwbNamedDef---}\n    procedure AfterLoad(const aElement: IwbElement); override;\n\n    {---IwbSignatureDef---}\n    function GetDefaultSignature: TwbSignature;\n\n    function GetSignatures(const aIndex: Integer): TwbSignature;\n    function GetSignatureCount: Integer;\n\n    function CanHandle(aSignature     : TwbSignature;\n                 const aDataContainer : IwbDataContainer)\n                                      : Boolean; virtual;\n\n    {---IwbRecordDef---}\n    function ContainsMemberFor(aSignature     : TwbSignature;\n                         const aDataContainer : IwbDataContainer)\n                                              : Boolean;\n    function GetMemberFor(aSignature     : TwbSignature;\n                    const aDataContainer : IwbDataContainer)\n                                         : IwbRecordMemberDef;\n    function GetMemberIndexFor(aSignature     : TwbSignature;\n                         const aDataContainer : IwbDataContainer)\n                                              : Integer;\n    function AllowUnordered: Boolean;\n    function AdditionalInfoFor(const aMainRecord: IwbMainRecord): string;\n\n    function GetMember(aIndex: Integer): IwbRecordMemberDef;\n    function GetMemberCount: Integer;\n    function GetSkipSignature(const aSignature: TwbSignature): Boolean; virtual;\n    function GetQuickInitLimit: Integer; virtual;\n    function GetContainsEditorID: Boolean;\n    function GetRecordHeaderStruct: IwbStructDef;\n  end;\n\n  TwbSubRecordUnionDef = class(TwbNamedDef, IwbRecordMemberDef, IwbSubRecordUnionDef, IwbRecordDef)\n  private\n    sruMembers           : array of IwbRecordMemberDef;\n    sruSignatures        : TStringList;\n    sruSkipSignatures    : TStringList;\n    sruCanContainFormIDs : Boolean;\n  public\n    constructor Clone(const aSource: TwbDef); override;\n    constructor Create(aPriority : TwbConflictPriority;\n                       aRequired : Boolean;\n                 const aName     : string;\n                 const aMembers  : array of IwbRecordMemberDef;\n                 const aSkipSigs : array of TwbSignature;\n                       aDontShow : TwbDontShowCallback;\n                       aGetCP    : TwbGetConflictPriority);\n    destructor Destroy; override;\n\n    {---IwbDef---}\n    function GetDefType: TwbDefType; override;\n    function GetDefTypeName: string; override;\n    function CanAssign(const aElement: IwbElement; aIndex: Integer; const aDef: IwbDef): Boolean; override;\n    function CanContainFormIDs: Boolean; override;\n    procedure Report(const aParents: TwbDefPath); override;\n\n    {---IwbSignatureDef---}\n    function GetDefaultSignature: TwbSignature;\n\n    function GetSignatures(const aIndex: Integer): TwbSignature;\n    function GetSignatureCount: Integer;\n\n    function CanHandle(aSignature     : TwbSignature;\n                 const aDataContainer : IwbDataContainer)\n                                      : Boolean; virtual;\n\n    {---IwbRecordDef---}\n    function ContainsMemberFor(aSignature     : TwbSignature;\n                         const aDataContainer : IwbDataContainer)\n                                              : Boolean;\n    function GetMemberFor(aSignature     : TwbSignature;\n                    const aDataContainer : IwbDataContainer)\n                                         : IwbRecordMemberDef;\n    function GetMemberIndexFor(aSignature     : TwbSignature;\n                         const aDataContainer : IwbDataContainer)\n                                              : Integer;\n    function AllowUnordered: Boolean;\n    function AdditionalInfoFor(const aMainRecord: IwbMainRecord): string;\n\n    function GetMember(aIndex: Integer): IwbRecordMemberDef;\n    function GetMemberCount: Integer;\n    function GetSkipSignature(const aSignature: TwbSignature): Boolean; virtual;\n    function GetQuickInitLimit: Integer; virtual;\n    function GetContainsEditorID: Boolean;\n    function GetRecordHeaderStruct: IwbStructDef;\n  end;\n\n\n  TwbSubRecordStructSKDef = class(TwbSubRecordStructDef, IwbHasSortKeyDef)\n  private\n    srsSortKey    : array of Integer;\n    srsExSortKey  : array of Integer;\n    srsMemberInSK : array of Boolean;\n  public\n    constructor Clone(const aSource: TwbDef); override;\n    constructor Create(aPriority       : TwbConflictPriority;\n                       aRequired       : Boolean;\n                 const aName           : string;\n                 const aMembers        : array of IwbRecordMemberDef;\n                 const aSkipSigs       : array of TwbSignature;\n                 const aSortKey        : array of Integer;\n                 const aExSortKey      : array of Integer;\n                       aDontShow       : TwbDontShowCallback;\n                       aAllowUnordered : Boolean;\n                       aAfterLoad      : TwbAfterLoadCallback;\n                       aAfterSet       : TwbAfterSetCallback;\n                       aGetCP          : TwbGetConflictPriority);\n\n    {---IwbHasSortKeyDef---}\n    function GetSortKey(aIndex: Integer; aExtended: Boolean): Integer;\n    function GetSortKeyCount(aExtended: Boolean): Integer;\n    function IsInSK(aIndex: Integer): Boolean;\n  end;\n\n  TwbValueDefState = (\n    vdsIsVariableSize,\n    vdsIsVariableSizeChecked\n  );\n  TwbValueDefStates = set of TwbValueDefState;\n\n  TwbValueDef = class(TwbNamedDef, IwbValueDef)\n  protected\n    vdStates: TwbValueDefStates;\n    {---IwbValueDef---}\n    function ToString(aBasePtr, aEndPtr: Pointer; const aElement: IwbElement): string; reintroduce; virtual; abstract;\n    function ToSortKey(aBasePtr, aEndPtr: Pointer; const aElement: IwbElement; aExtended: Boolean): string; virtual;\n    function Check(aBasePtr, aEndPtr: Pointer; const aElement: IwbElement): string; virtual;\n    function GetSize(aBasePtr, aEndPtr: Pointer; const aElement: IwbElement): Integer; virtual; abstract;\n    function GetDefaultSize(aBasePtr, aEndPtr: Pointer; const aElement: IwbElement): Integer; virtual; abstract;\n    function GetLinksTo(aBasePtr, aEndPtr: Pointer; const aElement: IwbElement): IwbElement; virtual;\n    procedure BuildRef(aBasePtr, aEndPtr: Pointer; const aElement: IwbElement); virtual;\n    function GetIsVariableSize: Boolean;\n    function GetIsVariableSizeInternal: Boolean; virtual;\n    function GetCanBeZeroSize: Boolean; virtual;\n    function ToEditValue(aBasePtr, aEndPtr: Pointer; const aElement: IwbElement): string; virtual;\n    procedure FromEditValue(aBasePtr, aEndPtr: Pointer; const aElement: IwbElement; const aValue: string); virtual;\n    function ToNativeValue(aBasePtr, aEndPtr: Pointer; const aElement: IwbElement): Variant; virtual;\n    procedure FromNativeValue(aBasePtr, aEndPtr: Pointer; const aElement: IwbElement; const aValue: Variant); virtual;\n    function GetIsEditable(aBasePtr, aEndPtr: Pointer; const aElement: IwbElement): Boolean; virtual;\n    function GetEditType(aBasePtr, aEndPtr: Pointer; const aElement: IwbElement): TwbEditType; virtual;\n    function GetEditInfo(aBasePtr, aEndPtr: Pointer; const aElement: IwbElement): string; virtual;\n    function SetToDefault(aBasePtr, aEndPtr: Pointer; const aElement: IwbElement): Boolean; virtual;\n    function GetElementMap: TDynCardinalArray; virtual;\n\n    procedure MasterCountUpdated(aBasePtr, aEndPtr: Pointer; const aElement: IwbElement; aOld, aNew: Byte); virtual;\n    procedure MasterIndicesUpdated(aBasePtr, aEndPtr: Pointer; const aElement: IwbElement; const aOld, aNew: TBytes); virtual;\n    procedure FindUsedMasters(aBasePtr, aEndPtr: Pointer; const aElement: IwbElement; aMasters: PwbUsedMasters); virtual;\n    function CompareExchangeFormID(aBasePtr, aEndPtr: Pointer; const aElement: IwbElement; aOldFormID: Cardinal; aNewFormID: Cardinal): Boolean; virtual;\n  end;\n\n  TwbUnionDef = class(TwbValueDef, IwbUnionDef)\n  protected {private}\n    udDecider: TwbUnionDecider;\n    udMembers: array of IwbValueDef;\n    ubCanContainFormIDs: Boolean;\n  protected\n    constructor Clone(const aSource: TwbDef); override;\n    constructor Create(aPriority : TwbConflictPriority;\n                       aRequired : Boolean;\n                 const aName     : string;\n                       aDecider  : TwbUnionDecider;\n                 const aMembers  : array of IwbValueDef;\n                       aDontShow : TwbDontShowCallback;\n                       aAfterSet : TwbAfterSetCallback;\n                       aGetCP    : TwbGetConflictPriority);\n\n    {---IwbDef---}\n    function GetDefType: TwbDefType; override;\n    function GetDefTypeName: string; override;\n    function CanAssign(const aElement: IwbElement; aIndex: Integer; const aDef: IwbDef): Boolean; override;\n    function CanContainFormIDs: Boolean; override;\n    procedure Report(const aParents: TwbDefPath); override;\n\n    {---IwbValueDef---}\n    function ToString(aBasePtr, aEndPtr: Pointer; const aElement: IwbElement): string; override;\n    function ToSortKey(aBasePtr, aEndPtr: Pointer; const aElement: IwbElement; aExtended: Boolean): string; override;\n    function Check(aBasePtr, aEndPtr: Pointer; const aElement: IwbElement): string; override;\n    function GetSize(aBasePtr, aEndPtr: Pointer; const aElement: IwbElement): Integer; override;\n    function GetDefaultSize(aBasePtr, aEndPtr: Pointer; const aElement: IwbElement): Integer; override;\n    function GetLinksTo(aBasePtr, aEndPtr: Pointer; const aElement: IwbElement): IwbElement; override;\n    procedure BuildRef(aBasePtr, aEndPtr: Pointer; const aElement: IwbElement); override;\n    function GetIsVariableSizeInternal: Boolean; override;\n    function ToEditValue(aBasePtr, aEndPtr: Pointer; const aElement: IwbElement): string; override;\n    procedure FromEditValue(aBasePtr, aEndPtr: Pointer; const aElement: IwbElement; const aValue: string); override;\n    function ToNativeValue(aBasePtr, aEndPtr: Pointer; const aElement: IwbElement): Variant; override;\n    procedure FromNativeValue(aBasePtr, aEndPtr: Pointer; const aElement: IwbElement; const aValue: Variant); override;\n    function GetIsEditable(aBasePtr, aEndPtr: Pointer; const aElement: IwbElement): Boolean; override;\n    function GetEditType(aBasePtr, aEndPtr: Pointer; const aElement: IwbElement): TwbEditType; override;\n    function GetEditInfo(aBasePtr, aEndPtr: Pointer; const aElement: IwbElement): string; override;\n    function SetToDefault(aBasePtr, aEndPtr: Pointer; const aElement: IwbElement): Boolean; override;\n\n    {---IwbUnionDef---}\n    function Decide(aBasePtr: Pointer; aEndPtr: Pointer; const aElement: IwbElement): IwbValueDef;\n    function GetMember(aIndex: Integer): IwbValueDef;\n    function GetMemberCount: Integer;\n  end;\n\n  TwbStringTransformType = (\n    ttToString,\n    ttToSortKey,\n    ttToEditValue,\n    ttFromEditValue,\n    ttToNativeValue,\n    ttFromNativeValue\n  );\n\n  TwbStringDef = class(TwbValueDef, IwbStringDef)\n  protected\n    sdSize: Integer;\n    sdForward: boolean;\n  protected\n    constructor Clone(const aSource: TwbDef); override;\n    constructor Create(aPriority   : TwbConflictPriority;\n                       aRequired   : Boolean;\n                 const aName       : string;\n                       aSize       : Integer;\n                       aAfterLoad  : TwbAfterLoadCallback;\n                       aAfterSet   : TwbAfterSetCallback;\n                       aDontShow   : TwbDontShowCallback;\n                       aGetCP      : TwbGetConflictPriority; \n                       aTerminator : Boolean;\n                       aForward    : boolean = false); virtual;\n    function ToStringNative(aBasePtr, aEndPtr: Pointer; const aElement: IwbElement): AnsiString; virtual;\n    function ToStringTransform(aBasePtr, aEndPtr: Pointer; const aElement: IwbElement; aTransformType: TwbStringTransformType): string;\n\n    procedure FromStringNative(aBasePtr, aEndPtr: Pointer; const aElement: IwbElement; const aValue: AnsiString); virtual;\n    procedure FromStringTransform(aBasePtr, aEndPtr: Pointer; const aElement: IwbElement; const aValue: string; aTransformType: TwbStringTransformType);\n\n    function TransformString(const s: AnsiString; aTransformType: TwbStringTransformType; const aElement: IwbElement): AnsiString; virtual;\n\n    {---IwbDef---}\n    function GetDefType: TwbDefType; override;\n    function GetDefTypeName: string; override;\n    function CanAssign(const aElement: IwbElement; aIndex: Integer; const aDef: IwbDef): Boolean; override;\n    function CanContainFormIDs: Boolean; override;\n\n    {---IwbValueDef---}\n    function ToString(aBasePtr, aEndPtr: Pointer; const aElement: IwbElement): string; override;\n    function ToSortKey(aBasePtr, aEndPtr: Pointer; const aElement: IwbElement; aExtended: Boolean): string; override;\n    function GetSize(aBasePtr, aEndPtr: Pointer; const aElement: IwbElement): Integer; override;\n    function GetDefaultSize(aBasePtr, aEndPtr: Pointer; const aElement: IwbElement): Integer; override;\n    function GetIsVariableSizeInternal: Boolean; override;\n    function ToEditValue(aBasePtr, aEndPtr: Pointer; const aElement: IwbElement): string; override;\n    procedure FromEditValue(aBasePtr, aEndPtr: Pointer; const aElement: IwbElement; const aValue: string); override;\n    function ToNativeValue(aBasePtr, aEndPtr: Pointer; const aElement: IwbElement): Variant; override;\n    procedure FromNativeValue(aBasePtr, aEndPtr: Pointer; const aElement: IwbElement; const aValue: Variant); override;\n    function GetIsEditable(aBasePtr, aEndPtr: Pointer; const aElement: IwbElement): Boolean; override;\n    function SetToDefault(aBasePtr, aEndPtr: Pointer; const aElement: IwbElement): Boolean; override;\n\n    {---IwbStringDef---}\n    function GetStringSize: Integer;\n  end;\n\n  TwbStringScriptDef = class(TwbStringDef)\n  protected\n    function TransformString(const s: AnsiString; aTransformType: TwbStringTransformType; const aElement: IwbElement): AnsiString; override;\n  end;\n\n  TwbStringLCDef = class(TwbStringDef)\n  protected\n    function TransformString(const s: AnsiString; aTransformType: TwbStringTransformType; const aElement: IwbElement): AnsiString; override;\n  end;\n\n  TwbStringKCDef = class(TwbStringDef)  // Keep Case\n  protected\n    function ToSortKey(aBasePtr, aEndPtr: Pointer; const aElement: IwbElement; aExtended: Boolean): string; override;\n  end;\n\n  TwbStringMgefCodeDef = class(TwbStringDef)\n  protected\n    function TransformString(const s: AnsiString; aTransformType: TwbStringTransformType; const aElement: IwbElement): AnsiString; override;\n\n    {---IwbDef---}\n    function CanContainFormIDs: Boolean; override;\n\n    {---IwbValueDef---}\n    function GetLinksTo(aBasePtr, aEndPtr: Pointer; const aElement: IwbElement): IwbElement; override;\n    procedure BuildRef(aBasePtr, aEndPtr: Pointer; const aElement: IwbElement); override;\n\n    procedure MasterCountUpdated(aBasePtr, aEndPtr: Pointer; const aElement: IwbElement; aOld, aNew: Byte); override;\n    procedure MasterIndicesUpdated(aBasePtr, aEndPtr: Pointer; const aElement: IwbElement; const aOld, aNew: TBytes); override;\n    procedure FindUsedMasters(aBasePtr, aEndPtr: Pointer; const aElement: IwbElement; aMasters: PwbUsedMasters); override;\n    function SetToDefault(aBasePtr, aEndPtr: Pointer; const aElement: IwbElement): Boolean; override;\n  end;\n\n  TwbLStringDef = class(TwbStringDef)\n  protected\n    function GetDefType: TwbDefType; override;\n    function GetDefTypeName: string; override;\n    function ToStringNative(aBasePtr, aEndPtr: Pointer; const aElement: IwbElement): AnsiString; override;\n    procedure FromStringNative(aBasePtr, aEndPtr: Pointer; const aElement: IwbElement; const aValue: AnsiString); override;\n    function GetSize(aBasePtr, aEndPtr: Pointer; const aElement: IwbElement): Integer; override;\n    function GetDefaultSize(aBasePtr, aEndPtr: Pointer; const aElement: IwbElement): Integer; override;\n  end;\n\n  TwbLStringKCDef = class(TwbLStringDef)\n  protected\n    function ToSortKey(aBasePtr, aEndPtr: Pointer; const aElement: IwbElement; aExtended: Boolean): string; override;\n  end;\n\n  TwbLenStringDef = class(TwbValueDef, IwbLenStringDef)\n  protected\n    Prefix: Integer;\n    constructor Clone(const aSource: TwbDef); override;\n    constructor Create(aPriority   : TwbConflictPriority;\n                       aRequired   : Boolean;\n                 const aName       : string;\n                       aPrefix     : integer;\n                       aAfterLoad  : TwbAfterLoadCallback;\n                       aAfterSet   : TwbAfterSetCallback;\n                       aDontShow   : TwbDontShowCallback;\n                       aGetCP      : TwbGetConflictPriority;\n                       aTerminator : Boolean);\n\n    {---IwbDef---}\n    function GetDefType: TwbDefType; override;\n    function GetDefTypeName: string; override;\n    function CanAssign(const aElement: IwbElement; aIndex: Integer; const aDef: IwbDef): Boolean; override;\n    function CanContainFormIDs: Boolean; override;\n\n    {---IwbValueDef---}\n    function ToString(aBasePtr, aEndPtr: Pointer; const aElement: IwbElement): string; override;\n    function Check(aBasePtr, aEndPtr: Pointer; const aElement: IwbElement): string; override;\n    function GetSize(aBasePtr, aEndPtr: Pointer; const aElement: IwbElement): Integer; override;\n    function GetDefaultSize(aBasePtr, aEndPtr: Pointer; const aElement: IwbElement): Integer; override;\n    function GetIsVariableSizeInternal: Boolean; override;\n    function ToEditValue(aBasePtr, aEndPtr: Pointer; const aElement: IwbElement): string; override;\n    procedure FromEditValue(aBasePtr, aEndPtr: Pointer; const aElement: IwbElement; const aValue: string); override;\n    function ToNativeValue(aBasePtr, aEndPtr: Pointer; const aElement: IwbElement): Variant; override;\n    procedure FromNativeValue(aBasePtr, aEndPtr: Pointer; const aElement: IwbElement; const aValue: Variant); override;\n    function GetIsEditable(aBasePtr, aEndPtr: Pointer; const aElement: IwbElement): Boolean; override;\n    function SetToDefault(aBasePtr, aEndPtr: Pointer; const aElement: IwbElement): Boolean; override;\n\n    function GetPrefixLen: Integer;\n    function GetPrefixOffset: Integer;\n    function GetPrefixValue(aBasePtr: Pointer; aEndPtr: Pointer; const aElement: IwbElement): Integer;\n    procedure SetPrefixValue(aBasePtr: Pointer; aEndPtr: Pointer; const aElement: IwbElement; aValue: Cardinal);\n  end;\n\n  TwbByteArrayDef = class(TwbValueDef, IwbByteArrayDef)\n  protected {private}\n    badSize                : Int64;\n\n    FoundFormIDAtOffSet    : array of Integer;\n    NotFoundFormIDAtOffSet : array of Integer;\n    SignaturesAtOffSet     : array of TStringList;\n    FormIDsAtOffSetFoundIn : array of TStringList;\n\n    FoundFloatAtOffSet     : array of Integer;\n    NotFoundFloatAtOffSet  : array of Integer;\n    FloatsAtOffSet         : array of TStringList;\n\n    FoundString            : Integer;\n    NotFoundString         : Integer;\n    Strings                : TStringList;\n\n//------------------------------------------------------------------------------\n// Added LString Routine\n//------------------------------------------------------------------------------\n    FoundLString            : Integer;\n    NotFoundLString         : Integer;\n\n    IsEmpty                 : Integer;\n    IsNotEmpty              : Integer;\n\n    badCountCallback        : TwbCountCallBack;\n  protected\n    constructor Clone(const aSource: TwbDef); override;\n    constructor Create(aPriority      : TwbConflictPriority;\n                       aRequired      : Boolean;\n                 const aName          : string;\n                       aSize          : Int64;\n                       aDontShow      : TwbDontShowCallback;\n                       aCountCallback : TwbCountCallback;\n                       aGetCP         : TwbGetConflictPriority;\n                       aTerminator    : Boolean);\n    {---IwbDef---}\n    function GetDefType: TwbDefType; override;\n    function GetDefTypeName: string; override;\n    function CanAssign(const aElement: IwbElement; aIndex: Integer; const aDef: IwbDef): Boolean; override;\n    function CanContainFormIDs: Boolean; override;\n\n    procedure Report(const aParents: TwbDefPath); override;\n\n    {---IwbValueDef---}\n    function ToString(aBasePtr, aEndPtr: Pointer; const aElement: IwbElement): string; override;\n    function GetSize(aBasePtr, aEndPtr: Pointer; const aElement: IwbElement): Integer; override;\n    function GetDefaultSize(aBasePtr, aEndPtr: Pointer; const aElement: IwbElement): Integer; override;\n    function GetIsVariableSizeInternal: Boolean; override;\n    function ToEditValue(aBasePtr, aEndPtr: Pointer; const aElement: IwbElement): string; override;\n    procedure FromEditValue(aBasePtr, aEndPtr: Pointer; const aElement: IwbElement; const aValue: string); override;\n    function ToNativeValue(aBasePtr, aEndPtr: Pointer; const aElement: IwbElement): Variant; override;\n    procedure FromNativeValue(aBasePtr, aEndPtr: Pointer; const aElement: IwbElement; const aValue: Variant); override;\n    function GetIsEditable(aBasePtr, aEndPtr: Pointer; const aElement: IwbElement): Boolean; override;\n    function SetToDefault(aBasePtr, aEndPtr: Pointer; const aElement: IwbElement): Boolean; override;\n  end;\n\n  TwbEmptyDef = class(TwbValueDef, IwbEmptyDef)\n  protected {private}\n    edSorted: Boolean;\n  protected\n    constructor Clone(const aSource: TwbDef); override;\n    constructor Create(aPriority  : TwbConflictPriority;\n                       aRequired  : Boolean;\n                 const aName      : string;\n                       aAfterLoad : TwbAfterLoadCallback; aAfterSet : TwbAfterSetCallback;\n                       aDontShow  : TwbDontShowCallback;\n                       aSorted    : Boolean;\n                       aGetCP     : TwbGetConflictPriority);\n\n    {---IwbDef---}\n    function GetDefType: TwbDefType; override;\n    function GetDefTypeName: string; override;\n    function CanContainFormIDs: Boolean; override;\n\n    {---IwbValueDef---}\n    function ToString(aBasePtr, aEndPtr: Pointer; const aElement: IwbElement): string; override;\n    function ToSortKey(aBasePtr, aEndPtr: Pointer; const aElement: IwbElement; aExtended: Boolean): string; override;\n    function GetSize(aBasePtr, aEndPtr: Pointer; const aElement: IwbElement): Integer; override;\n    function GetDefaultSize(aBasePtr, aEndPtr: Pointer; const aElement: IwbElement): Integer; override;\n    function GetCanBeZeroSize: Boolean; override;\n    procedure FromEditValue(aBasePtr, aEndPtr: Pointer; const aElement: IwbElement; const aValue: string); override;\n    function GetIsEditable(aBasePtr, aEndPtr: Pointer; const aElement: IwbElement): Boolean; override;\n\n    {--- IwbEmptyDef ---}\n    function GetSorted: Boolean;\n  end;\n\n  TwbIntegerDef = class(TwbValueDef, IwbIntegerDef, IwbInternalIntegerDef)\n  private\n    inType     : TwbIntType;\n    inFormater : IwbIntegerDefFormater;\n    inDefault  : Int64;\n  protected\n    constructor Clone(const aSource: TwbDef); override;\n    constructor Create(aPriority   : TwbConflictPriority;\n                       aRequired   : Boolean;\n                 const aName       : string;\n                 const aIntType    : TwbIntType;\n                 const aFormater   : IwbIntegerDefFormater;\n                       aDontShow   : TwbDontShowCallback;\n                       aAfterSet   : TwbAfterSetCallback;\n                       aDefault    : Int64;\n                       aGetCP      : TwbGetConflictPriority;\n                       aTerminator : Boolean);\n\n    {---IwbDef---}\n    function GetDefType: TwbDefType; override;\n    function GetDefTypeName: string; override;\n    function CanAssign(const aElement: IwbElement; aIndex: Integer; const aDef: IwbDef): Boolean; override;\n    function Assign(const aTarget: IwbElement; aIndex: Integer; const aSource: IwbElement; aOnlySK: Boolean): IwbElement; override;\n    function CanContainFormIDs: Boolean; override;\n    procedure Report(const aParents: TwbDefPath); override;\n    function GetNoReach: Boolean; override;\n\n    {---IwbValueDef---}\n    function ToString(aBasePtr, aEndPtr: Pointer; const aElement: IwbElement): string; override;\n    function ToSortKey(aBasePtr, aEndPtr: Pointer; const aElement: IwbElement; aExtended: Boolean): string; override;\n    function Check(aBasePtr, aEndPtr: Pointer; const aElement: IwbElement): string; override;\n    function GetSize(aBasePtr, aEndPtr: Pointer; const aElement: IwbElement): Integer; override;\n    function GetDefaultSize(aBasePtr, aEndPtr: Pointer; const aElement: IwbElement): Integer; override;\n    function GetLinksTo(aBasePtr, aEndPtr: Pointer; const aElement: IwbElement): IwbElement; override;\n    procedure BuildRef(aBasePtr, aEndPtr: Pointer; const aElement: IwbElement); override;\n    function ToEditValue(aBasePtr, aEndPtr: Pointer; const aElement: IwbElement): string; override;\n    procedure FromEditValue(aBasePtr, aEndPtr: Pointer; const aElement: IwbElement; const aValue: string); override;\n    function ToNativeValue(aBasePtr, aEndPtr: Pointer; const aElement: IwbElement): Variant; override;\n    procedure FromNativeValue(aBasePtr, aEndPtr: Pointer; const aElement: IwbElement; const aValue: Variant); override;\n    function GetIsEditable(aBasePtr, aEndPtr: Pointer; const aElement: IwbElement): Boolean; override;\n    function GetEditType(aBasePtr, aEndPtr: Pointer; const aElement: IwbElement): TwbEditType; override;\n    function GetEditInfo(aBasePtr, aEndPtr: Pointer; const aElement: IwbElement): string; override;\n    function SetToDefault(aBasePtr, aEndPtr: Pointer; const aElement: IwbElement): Boolean; override;\n\n    procedure MasterCountUpdated(aBasePtr, aEndPtr: Pointer; const aElement: IwbElement; aOld, aNew: Byte); override;\n    procedure MasterIndicesUpdated(aBasePtr, aEndPtr: Pointer; const aElement: IwbElement; const aOld, aNew: TBytes); override;\n    procedure FindUsedMasters(aBasePtr, aEndPtr: Pointer; const aElement: IwbElement; aMasters: PwbUsedMasters); override;\n    function CompareExchangeFormID(aBasePtr, aEndPtr: Pointer; const aElement: IwbElement; aOldFormID: Cardinal; aNewFormID: Cardinal): Boolean; override;\n\n    {---IwbIntegerDef---}\n    function ToInt(aBasePtr, aEndPtr: Pointer; const aElement: IwbElement): Int64;\n    procedure FromInt(aValue: Int64; aBasePtr, aEndPtr: Pointer; const aElement: IwbElement);\n    function GetFormater(const aElement: IwbElement): IwbIntegerDefFormater;\n    function GetFormaterCanChange: Boolean;\n    function GetIntType: TwbIntType;\n    function GetExpectedLength(aValue: Int64 = 0): Integer;\n\n    {---IwbInternalIntegerDef---}\n    procedure ReplaceFormater(const aFormater: IwbIntegerDefFormater);\n  end;\n\n  TwbFloatDef = class(TwbValueDef, IwbFloatDef)\n  private\n    fdDefault    : Extended;\n    fdScale      : Extended;\n    fdDigits     : Integer;\n    fdNormalizer : TwbFloatNormalizer;\n    fdDouble     : Boolean;\n  protected\n    constructor Clone(const aSource: TwbDef); override;\n    {---IwbDef---}\n    function GetDefType: TwbDefType; override;\n    function GetDefTypeName: string; override;\n    function CanAssign(const aElement: IwbElement; aIndex: Integer; const aDef: IwbDef): Boolean; override;\n    function CanContainFormIDs: Boolean; override;\n\n    {---IwbValueDef---}\n    function ToString(aBasePtr, aEndPtr: Pointer; const aElement: IwbElement): string; override;\n    function ToSortKey(aBasePtr, aEndPtr: Pointer; const aElement: IwbElement; aExtended: Boolean): string; override;\n    function GetSize(aBasePtr, aEndPtr: Pointer; const aElement: IwbElement): Integer; override;\n    function GetDefaultSize(aBasePtr, aEndPtr: Pointer; const aElement: IwbElement): Integer; override;\n    function ToEditValue(aBasePtr, aEndPtr: Pointer; const aElement: IwbElement): string; override;\n    procedure FromEditValue(aBasePtr, aEndPtr: Pointer; const aElement: IwbElement; const aValue: string); override;\n    function ToNativeValue(aBasePtr, aEndPtr: Pointer; const aElement: IwbElement): Variant; override;\n    procedure FromNativeValue(aBasePtr, aEndPtr: Pointer; const aElement: IwbElement; const aValue: Variant); override;\n    function GetIsEditable(aBasePtr, aEndPtr: Pointer; const aElement: IwbElement): Boolean; override;\n    function SetToDefault(aBasePtr, aEndPtr: Pointer; const aElement: IwbElement): Boolean; override;\n\n    function ToValue(aBasePtr, aEndPtr: Pointer; const aElement: IwbElement): Extended;\n  public\n    constructor Create(aPriority   : TwbConflictPriority;\n                       aRequired   : Boolean;\n                 const aName       : string;\n                       aAfterLoad  : TwbAfterLoadCallback;\n                       aAfterSet   : TwbAfterSetCallback;\n                       aScale      : Extended;\n                       aDigits     : Integer;\n                       aDontShow   : TwbDontShowCallback;\n                       aNormalizer : TwbFloatNormalizer;\n                       aDefault    : Extended;\n                       aGetCP      : TwbGetConflictPriority;\n                       aDouble     : Boolean;\n                       aTerminator : Boolean);\n  end;\n\n  TwbArrayDef = class(TwbValueDef, IwbArrayDef)\n  private\n    arCount         : Integer;\n    arCountCallback : TwbCountCallback;\n    arElement       : IwbValueDef;\n    arLabels        : array of string;\n    arSorted        : Boolean;\n    arCanAddTo      : Boolean;\n    arTerminated    : Boolean;\n  protected\n    constructor Clone(const aSource: TwbDef); override;\n\n    constructor Create(aPriority   : TwbConflictPriority;\n                       aRequired   : Boolean;\n                 const aName       : string;\n                 const aElement    : IwbValueDef;\n                       aCount      : Integer;\n                 const aLabels     : array of string;\n                       aSorted     : Boolean;\n                       aAfterLoad  : TwbAfterLoadCallback;\n                       aAfterSet   : TwbAfterSetCallback;\n                       aDontShow   : TwbDontShowCallback;\n                       aGetCP      : TwbGetConflictPriority;\n                       aCanAddTo   : Boolean;\n                       aTerminator : Boolean;\n                       aTerminated : Boolean); overload;\n\n    constructor Create(aPriority      : TwbConflictPriority;\n                       aRequired      : Boolean;\n                 const aName          : string;\n                 const aElement       : IwbValueDef;\n                       aCountCallback : TwbCountCallback;\n                 const aLabels        : array of string;\n                       aSorted        : Boolean;\n                       aAfterLoad     : TwbAfterLoadCallback;\n                       aAfterSet      : TwbAfterSetCallback;\n                       aDontShow      : TwbDontShowCallback;\n                       aGetCP         : TwbGetConflictPriority;\n                       aCanAddTo      : Boolean;\n                       aTerminator    : Boolean;\n                       aTerminated    : Boolean); overload;\n\n    {---IwbDef---}\n    function GetDefType: TwbDefType; override;\n    function GetDefTypeName: string; override;\n    function CanContainFormIDs: Boolean; override;\n    procedure Report(const aParents: TwbDefPath); override;\n\n    {---IwbValueDef---}\n    function GetSize(aBasePtr, aEndPtr: Pointer; const aElement: IwbElement): Integer; override;\n    function GetDefaultSize(aBasePtr, aEndPtr: Pointer; const aElement: IwbElement): Integer; override;\n    function ToString(aBasePtr, aEndPtr: Pointer; const aElement: IwbElement): string; override;\n    function GetIsVariableSizeInternal: Boolean; override;\n    function GetCanBeZeroSize: Boolean; override;\n    function CanAssign(const aElement: IwbElement; aIndex: Integer; const aDef: IwbDef): Boolean; override;\n\n    {---IwbArrayDef---}\n    function GetElement: IwbValueDef;\n    function GetCount: Integer;\n    function GetElementLabel(aIndex: Integer): string;\n    function GetSorted: Boolean;\n    function GetCanAddTo: Boolean;\n    function GetCountCallBack: TwbCountCallback;\n    function GetPrefixSize(aBasePtr: Pointer): Integer;\n    function GetPrefixLength(aBasePtr: Pointer): Integer;\n    function GetPrefixCount(aBasePtr: Pointer): Cardinal;\n    procedure SetPrefixCount(aBasePtr: Pointer; aValue: Cardinal);\n  end;\n\n  TwbStructDef = class(TwbValueDef, IwbStructDef)\n  private\n    stMembers             : array of IwbValueDef;\n    stSortKey             : array of Integer;\n    stExSortKey           : array of Integer;\n    stElementMap          : TDynCardinalArray;\n    stCanContainFormIDs   : Boolean;\n    stOptionalFromElement : Integer;\n  protected\n    constructor Clone(const aSource: TwbDef); override;\n    constructor Create(aPriority            : TwbConflictPriority;\n                       aRequired            : Boolean;\n                 const aName                : string;\n                 const aMembers             : array of IwbValueDef;\n                 const aSortKey             : array of Integer;\n                 const aExSortKey           : array of Integer;\n                 {$IFDEF WIN32}\n                 const aElementMap          : array of Cardinal;\n                 {$ENDIF WIN32}\n                 {$IFDEF WIN64}\n                 const aElementMap          : array of UInt64;\n                 {$ENDIF WIN64}\n                       aOptionalFromElement : Integer;\n                       aDontShow            : TwbDontShowCallback;\n                       aAfterLoad           : TwbAfterLoadCallback;\n                       aAfterSet            : TwbAfterSetCallback;\n                       aGetCP               : TwbGetConflictPriority);\n\n    {---IwbDef---}\n    function GetDefType: TwbDefType; override;\n    function GetDefTypeName: string; override;\n    function CanContainFormIDs: Boolean; override;\n    procedure Report(const aParents: TwbDefPath); override;\n\n    {---IwbValueDef---}\n    function GetSize(aBasePtr, aEndPtr: Pointer; const aElement: IwbElement): Integer; override;\n    function GetDefaultSize(aBasePtr, aEndPtr: Pointer; const aElement: IwbElement): Integer; override;\n    function ToString(aBasePtr, aEndPtr: Pointer; const aElement: IwbElement): string; override;\n    function ToSortKey(aBasePtr, aEndPtr: Pointer; const aElement: IwbElement; aExtended: Boolean): string; override;\n    function GetIsVariableSizeInternal: Boolean; override;\n    function CanAssign(const aElement: IwbElement; aIndex: Integer; const aDef: IwbDef): Boolean; override;\n    function GetElementMap: TDynCardinalArray; override;\n\n    {---IwbStructDef---}\n    function GetMemberCount: Integer;\n    function GetMember(aIndex: Integer): IwbValueDef;\n    function GetMemberByName(const aName: string): IwbValueDef;\n    function GetOptionalFromElement: Integer;\n  end;\n\n  TwbStructCDef = class(TwbStructDef, IwbStructCDef)\n  private\n    scSizeCallback       : TwbSizeCallback;\n    scGetChapterType     : TwbGetChapterTypeCallback;\n    scGetChapterTypeName : TwbGetChapterTypeNameCallback;\n    scGetChapterName     : TwbGetChapterNameCallback;\n  protected\n    constructor Clone(const aSource: TwbDef); override;\n    constructor Create(aPriority            : TwbConflictPriority;\n                       aRequired            : Boolean;\n                 const aName                : string;\n                 const aMembers             : array of IwbValueDef;\n                 const aSortKey             : array of Integer;\n                 const aExSortKey           : array of Integer;\n                       aOptionalFromElement : Integer;\n                       aDontShow            : TwbDontShowCallback;\n                       aAfterLoad           : TwbAfterLoadCallback;\n                       aAfterSet            : TwbAfterSetCallback;\n                       aSizeCallBack        : TwbSizeCallback;\n                       aGetChapterType      : TwbGetChapterTypeCallback;\n                       aGetChapterTypeName  : TwbGetChapterTypeNameCallback;\n                       aGetChapterName      : TwbGetChapterNameCallback;\n                       aGetCP               : TwbGetConflictPriority);\n    function GetDefType: TwbDefType; override;\n    function GetDefTypeName: string; override;\n  public\n    function GetSizing(aBasePtr: Pointer; aEndPtr: Pointer; const aElement: IwbElement;var CompressedSize: Integer): Cardinal; virtual;\n    function GetChapterType(aBasePtr: Pointer; aEndPtr: Pointer; const aElement: IwbElement): Integer; virtual;\n    function GetChapterTypeName(aBasePtr: Pointer; aEndPtr: Pointer; const aElement: IwbElement): String; virtual;\n    function GetChapterName(aBasePtr: Pointer; aEndPtr: Pointer; const aElement: IwbElement): String; virtual;\n  end;\n\n  TwbStructZDef = class(TwbStructCDef, IwbStructZDef)\n  end;\n\n  TwbStructLZDef = class(TwbStructCDef, IwbStructLZDef)\n  end;\n\n  TwbIntegerDefFormater = class(TwbDef, IwbIntegerDefFormater)\n  protected\n    constructor Clone(const aSource: TwbDef); override;\n\n    {---IwbDef---}\n    function GetDefType: TwbDefType; override;\n    function GetDefTypeName: string; override;\n\n    {---IwbIntegerDefFormater---}\n    function ToString(aInt: Int64; const aElement: IwbElement): string; reintroduce; virtual; abstract;\n    function ToSortKey(aInt: Int64; const aElement: IwbElement): string; virtual; abstract;\n    function Check(aInt: Int64; const aElement: IwbElement): string; virtual;\n    procedure BuildRef(aInt: Int64; const aElement: IwbElement); virtual;\n\n    function GetEditType(aInt: Int64; const aElement: IwbElement): TwbEditType; virtual;\n    function GetEditInfo(aInt: Int64; const aElement: IwbElement): string; virtual;\n\n    function ToEditValue(aInt: Int64; const aElement: IwbElement): string; virtual;\n    function FromEditValue(const aValue: string; const aElement: IwbElement): Int64; virtual;\n    function GetIsEditable(aInt: Int64; const aElement: IwbElement): Boolean; virtual;\n    function GetLinksTo(aInt: Int64; const aElement: IwbElement): IwbElement; virtual;\n\n    function CanAssign(const aElement: IwbElement; aIndex: Integer; const aDef: IwbDef): Boolean; override;\n\n    function MasterCountUpdated(aInt: Int64; aOld, aNew: Byte; const aElement: IwbElement): Int64; virtual;\n    function MasterIndicesUpdated(aInt: Int64; const aOld, aNew: TBytes; const aElement: IwbElement): Int64; virtual;\n    procedure FindUsedMasters(aInt: Int64; aMasters: PwbUsedMasters; const aElement: IwbElement); virtual;\n    function CompareExchangeFormID(var aInt: Int64; aOldFormID: Cardinal; aNewFormID: Cardinal; const aElement: IwbElement): Boolean; virtual;\n\n    function GetRequiresKey: Boolean; virtual;\n  end;\n\n  TwbIntegerDefFormaterUnion = class(TwbIntegerDefFormater, IwbIntegerDefFormaterUnion)\n  private\n    idfuDecider: TwbIntegerDefFormaterUnionDecider;\n    idfuMembers: array of IwbIntegerDefFormater;\n  protected\n    constructor Clone(const aSource: TwbDef); override;\n    constructor Create(aPriority : TwbConflictPriority;\n                       aRequired : Boolean;\n                       aGetCP    : TwbGetConflictPriority;\n                       aDecider  : TwbIntegerDefFormaterUnionDecider;\n                 const aMembers  : array of IwbIntegerDefFormater);\n\n    {---IwbDef---}\n    function GetDefType: TwbDefType; override;\n    function CanContainFormIDs: Boolean; override;\n    procedure Report(const aParents: TwbDefPath); override;\n    function GetNoReach: Boolean; override;\n\n    {---IwbIntegerDefFormater---}\n    function ToString(aInt: Int64; const aElement: IwbElement): string; override;\n    function ToSortKey(aInt: Int64; const aElement: IwbElement): string; override;\n    function Check(aInt: Int64; const aElement: IwbElement): string; override;\n    procedure BuildRef(aInt: Int64; const aElement: IwbElement); override;\n\n    function GetEditType(aInt: Int64; const aElement: IwbElement): TwbEditType; override;\n    function GetEditInfo(aInt: Int64; const aElement: IwbElement): string; override;\n\n    function ToEditValue(aInt: Int64; const aElement: IwbElement): string; override;\n    function FromEditValue(const aValue: string; const aElement: IwbElement): Int64; override;\n    function GetIsEditable(aInt: Int64; const aElement: IwbElement): Boolean; override;\n    function GetLinksTo(aInt: Int64; const aElement: IwbElement): IwbElement; override;\n\n    function CanAssign(const aElement: IwbElement; aIndex: Integer; const aDef: IwbDef): Boolean; override;\n\n    function MasterCountUpdated(aInt: Int64; aOld, aNew: Byte; const aElement: IwbElement): Int64; override;\n    function MasterIndicesUpdated(aInt: Int64; const aOld, aNew: TBytes; const aElement: IwbElement): Int64; override;\n    procedure FindUsedMasters(aInt: Int64; aMasters: PwbUsedMasters; const aElement: IwbElement); override;\n    function CompareExchangeFormID(var aInt: Int64; aOldFormID: Cardinal; aNewFormID: Cardinal; const aElement: IwbElement): Boolean; override;\n\n    {---IwbIntegerDefFormaterUnion---}\n    function Decide(const aElement: IwbElement): IwbIntegerDefFormater;\n\n    function GetMember(aIndex: Integer): IwbIntegerDefFormater;\n    function GetMemberCount: Integer;\n\n    property Members[aIndex: Integer]: IwbIntegerDefFormater read GetMember;\n    property MemberCount: Integer read GetMemberCount;\n  end;\n\n  TwbDumpIntegerDefFormater = class(TwbIntegerDefFormater, IwbDumpIntegerDefFormater)\n  protected\n    function ToString(aInt: Int64; const aElement: IwbElement): string; override;\n    function ToSortKey(aInt: Int64; const aElement: IwbElement): string; override;\n  end;\n\n  TwbFormID = class(TwbIntegerDefFormater, IwbFormID)\n  protected\n    FoundSignatures: TStringList;\n    FoundNotAllowedReferences: TStringList;\n    NotResolved: TStringList;\n\n    constructor Clone(const aSource: TwbDef); override;\n\n    function IsValid(const aSignature: TwbSignature): Boolean; virtual;\n    function IsValidFlst(const aSignature: TwbSignature): Boolean; virtual;\n    function CheckFlst(const aMainRecord: IwbMainRecord): Boolean; virtual;\n    function IsValidMainRecord(const aMainRecord: IwbMainRecord): Boolean; virtual;\n\n    function FindRecordForAVCode(aInt: Int64; const aElement: IwbElement): IwbMainRecord;\n\n    {---IwbDef---}\n    procedure Report(const aParents: TwbDefPath); override;\n\n    {---IwbIntegerDefFormater---}\n    function Check(aInt: Int64; const aElement: IwbElement): string; override;\n    function ToString(aInt: Int64; const aElement: IwbElement): string; override;\n    function ToSortKey(aInt: Int64; const aElement: IwbElement): string; override;\n    procedure BuildRef(aInt: Int64; const aElement: IwbElement); override;\n\n    function GetEditType(aInt: Int64; const aElement: IwbElement): TwbEditType; override;\n    function GetEditInfo(aInt: Int64; const aElement: IwbElement): string; override;\n\n    function ToEditValue(aInt: Int64; const aElement: IwbElement): string; override;\n    function FromEditValue(const aValue: string; const aElement: IwbElement): Int64; override;\n    function GetIsEditable(aInt: Int64; const aElement: IwbElement): Boolean; override;\n    function GetLinksTo(aInt: Int64; const aElement: IwbElement): IwbElement; override;\n\n    function CanAssign(const aElement: IwbElement; aIndex: Integer; const aDef: IwbDef): Boolean; override;\n    function CanContainFormIDs: Boolean; override;\n\n    function MasterCountUpdated(aInt: Int64; aOld, aNew: Byte; const aElement: IwbElement): Int64; override;\n    function MasterIndicesUpdated(aInt: Int64; const aOld, aNew: TBytes; const aElement: IwbElement): Int64; override;\n    procedure FindUsedMasters(aInt: Int64; aMasters: PwbUsedMasters; const aElement: IwbElement); override;\n    function CompareExchangeFormID(var aInt: Int64; aOldFormID: Cardinal; aNewFormID: Cardinal; const aElement: IwbElement): Boolean; override;\n\n    {---IwbFormID---}\n    function GetMainRecord(aInt: Int64; const aElement: IwbElement): IwbMainRecord; virtual;\n  end;\n\n  TwbRefID = class(TwbFormID, IwbRefID)\n  protected\n    {---IwbIntegerDefFormater---}\n    function ToString(aInt: Int64; const aElement: IwbElement): string; override;\n    procedure BuildRef(aInt: Int64; const aElement: IwbElement); override;\n  end;\n\n  TwbFormIDChecked = class(TwbFormID, IwbFormIDChecked)\n  protected {private}\n    fidcValidRefsArr     : array of TwbSignature;\n    fidcValidRefs        : TStringList;\n    fidcValidFlstRefsArr : array of TwbSignature;\n    fidcValidFlstRefs    : TStringList;\n    fidcPersistent       : Boolean;\n    fidcNoReach          : Boolean;\n  protected\n    constructor Clone(const aSource: TwbDef); override;\n    constructor Create(const aValidRefs     : array of TwbSignature;\n                       const aValidFlstRefs : array of TwbSignature;\n                             aPersistent    : Boolean;\n                             aNoReach       : Boolean = False);\n    destructor Destroy; override;\n\n    function IsValid(const aSignature: TwbSignature): Boolean; override;\n    function IsValidFlst(const aSignature: TwbSignature): Boolean; override;\n    function CheckFlst(const aMainRecord: IwbMainRecord): Boolean; override;\n    function IsValidMainRecord(const aMainRecord: IwbMainRecord): Boolean; override;\n\n    {---IwbDef---}\n    procedure Report(const aParents: TwbDefPath); override;\n    function GetNoReach: Boolean; override;\n\n    {---IwbIntegerDefFormater---}\n    function Check(aInt: Int64; const aElement: IwbElement): string; override;\n    function FromEditValue(const aValue: string; const aElement: IwbElement): Int64; override;\n    function CanAssign(const aElement: IwbElement; aIndex: Integer; const aDef: IwbDef): Boolean; override;\n\n    {---IwbFormIDChecked---}\n    function GetSignature(aIndex: Integer): TwbSignature;\n    function GetSignatureCount: Integer;\n  end;\n\n  TwbChar4 = class(TwbIntegerDefFormater, IwbChar4)\n  protected\n    constructor Clone(const aSource: TwbDef); override;\n\n    {---IwbIntegerDefFormater---}\n    function ToString(aInt: Int64; const aElement: IwbElement): string; override;\n    function ToSortKey(aInt: Int64; const aElement: IwbElement): string; override;\n    procedure BuildRef(aInt: Int64; const aElement: IwbElement); override;\n    function CanAssign(const aElement: IwbElement; aIndex: Integer; const aDef: IwbDef): Boolean; override;\n    function GetLinksTo(aInt: Int64; const aElement: IwbElement): IwbElement; override;\n\n    function ToEditValue(aInt: Int64; const aElement: IwbElement): string; override;\n    function FromEditValue(const aValue: string; const aElement: IwbElement): Int64; override;\n    function GetIsEditable(aInt: Int64; const aElement: IwbElement): Boolean; override;\n    function CanContainFormIDs: Boolean; override;\n  end;\n\n  TwbStr4 = class(TwbIntegerDefFormater, IwbStr4)\n  protected\n    constructor Clone(const aSource: TwbDef); override;\n\n    {---IwbIntegerDefFormater---}\n    function ToString(aInt: Int64; const aElement: IwbElement): string; override;\n    function ToSortKey(aInt: Int64; const aElement: IwbElement): string; override;\n    function CanAssign(const aElement: IwbElement; aIndex: Integer; const aDef: IwbDef): Boolean; override;\n\n    function ToEditValue(aInt: Int64; const aElement: IwbElement): string; override;\n    function FromEditValue(const aValue: string; const aElement: IwbElement): Int64; override;\n    function GetIsEditable(aInt: Int64; const aElement: IwbElement): Boolean; override;\n    function CanContainFormIDs: Boolean; override;\n  end;\n\n  TwbFlagsDef = class(TwbIntegerDefFormater, IwbFlagsDef)\n  private\n    flgBaseFlagsDef    : IwbFlagsDef;\n    flgNames           : array of string;\n    flgDontShows       : array of TwbDontShowCallback;\n    flgHasDontShows    : Boolean;\n    flgUnusedMask      : Int64;\n    flgIgnoreMask      : Int64;\n    flgUnknownIsUnused : Boolean;\n    flgGetCPs          : array of TwbGetConflictPriority;\n    flgHasGetCPs       : Boolean;\n    flgFlagDefs        : array of IwbFlagDef;\n\n    UnknownFlags       : array[0..63] of Integer;\n    HasUnknownFlags    : Boolean;\n  protected\n    constructor Clone(const aSource: TwbDef); override;\n    constructor Create(const aBaseFlagsDef    : IwbFlagsDef;\n                       const aNames           : array of string;\n                       const aDontShows       : array of TwbDontShowCallback;\n                             aUnknownIsUnused : Boolean;\n                             aIgnoreMask      : Int64;\n                       const aGetCPs          : array of TwbGetConflictPriority);\n\n    {---IwbDef---}\n    procedure Report(const aParents: TwbDefPath); override;\n    function GetDefTypeName: string; override;\n\n    {---IwbIntegerDefFormater---}\n    function Check(aInt: Int64; const aElement: IwbElement): string; override;\n    function ToString(aInt: Int64; const aElement: IwbElement): string; override;\n    function ToSortKey(aInt: Int64; const aElement: IwbElement): string; override;\n    function CanAssign(const aElement: IwbElement; aIndex: Integer; const aDef: IwbDef): Boolean; override;\n    function Assign(const aTarget: IwbElement; aIndex: Integer; const aSource: IwbElement; aOnlySK: Boolean): IwbElement; override;\n    function CanContainFormIDs: Boolean; override;\n\n    function GetEditType(aInt: Int64; const aElement: IwbElement): TwbEditType; override;\n    function GetEditInfo(aInt: Int64; const aElement: IwbElement): string; override;\n\n    function ToEditValue(aInt: Int64; const aElement: IwbElement): string; override;\n    function FromEditValue(const aValue: string; const aElement: IwbElement): Int64; override;\n    function GetIsEditable(aInt: Int64; const aElement: IwbElement): Boolean; override;\n\n    function GetRequiresKey: Boolean; override;\n\n    {---IwbFlagsDef---}\n    function GetBaseFlagsDef: IwbFlagsDef;\n    function GetFlag(aIndex: Integer): string;\n    function GetFlagCount: Integer;\n    function GetFlagIgnoreConflict(aIndex: Integer): Boolean;\n    function GetFlagDontShow(const aElement: IwbElement; aIndex: Integer): Boolean;\n    function GetFlagHasDontShow(aIndex: Integer): Boolean;\n    procedure FlagGetCP(const aElement: IwbElement; aIndex: Integer; var aCP: TwbConflictPriority);\n    function GetFlagHasGetCP(aIndex: Integer): Boolean;\n    function GetFlagDef(aIndex : Integer): IwbFlagDef;\n  end;\n\n  TwbFlagDef = class(TwbValueDef, IwbFlagDef)\n  private\n    fdFlagIndex : Integer;\n  protected\n    constructor Clone(const aSource: TwbDef); override;\n    constructor Create(aPriority   : TwbConflictPriority;\n                       aRequired   : Boolean;\n                 const aName       : string;\n                       aAfterLoad  : TwbAfterLoadCallback;\n                       aAfterSet   : TwbAfterSetCallback;\n                       aDontShow   : TwbDontShowCallback;\n                       aGetCP      : TwbGetConflictPriority;\n                       aTerminator : Boolean;\n                       aFlagIndex  : Integer);\n\n    {---IwbDef---}\n    function GetDefType: TwbDefType; override;\n    function GetDefTypeName: string; override;\n    function CanContainFormIDs: Boolean; override;\n    function GetHasDontShow: Boolean; override;\n    function GetDontShow(const aElement: IwbElement): Boolean; override;\n    function GetConflictPriority(const aElement: IwbElement): TwbConflictPriority; override;\n    function GetConflictPriorityCanChange: Boolean; override;\n    function GetCanBeZeroSize: Boolean; override;\n\n    {---IwbValueDef---}\n    function ToString(aBasePtr, aEndPtr: Pointer; const aElement: IwbElement): string; override;\n    function GetSize(aBasePtr, aEndPtr: Pointer; const aElement: IwbElement): Integer; override;\n    function GetDefaultSize(aBasePtr, aEndPtr: Pointer; const aElement: IwbElement): Integer; override;\n\n    {---IwbFlagDef---}\n    function GetFlagsDef: IwbFlagsDef;\n    function GetFlagIndex: Integer;\n  end;\n\n  PwbSparseName = ^TwbSparseName;\n  TwbSparseName = record\n    snIndex : Int64;\n    snName  : string;\n  end;\n\n  TwbEnumDef = class(TwbIntegerDefFormater, IwbEnumDef)\n  private\n    enNames          : array of string;\n    enSparseNames    : array of TwbSparseName;\n    enSparseNamesMap : array of PwbSparseName;\n    enEditInfo       : string;\n\n    UnknownEnums: TStringList;\n  protected\n    constructor Clone(const aSource: TwbDef); override;\n    constructor Create(const aNames       : array of string;\n                       const aSparseNames : array of const);\n\n    function FindSparseName(aSearchIndex: Int64; var Index: Integer): Boolean;\n\n    function CanContainFormIDs: Boolean; override;\n\n    {---IwbDef---}\n    procedure Report(const aParents: TwbDefPath); override;\n    function GetDefTypeName: string; override;\n\n    {---IwbIntegerDefFormater---}\n    function Check(aInt: Int64; const aElement: IwbElement): string; override;\n    function ToString(aInt: Int64; const aElement: IwbElement): string; override;\n    function ToSortKey(aInt: Int64; const aElement: IwbElement): string; override;\n    function CanAssign(const aElement: IwbElement; aIndex: Integer; const aDef: IwbDef): Boolean; override;\n\n    function GetEditType(aInt: Int64; const aElement: IwbElement): TwbEditType; override;\n    function GetEditInfo(aInt: Int64; const aElement: IwbElement): string; override;\n\n    function ToEditValue(aInt: Int64; const aElement: IwbElement): string; override;\n    function FromEditValue(const aValue: string; const aElement: IwbElement): Int64; override;\n    function GetIsEditable(aInt: Int64; const aElement: IwbElement): Boolean; override;\n\n    {---IwbEnumDef---}\n    function GetName(aIndex: Integer): string;\n    function GetNameCount: Integer;\n  end;\n\n  TwbKey2Data6EnumDef = class(TwbEnumDef, IwbKey2Data6EnumDef)\n  protected\n    {---IwbIntegerDefFormater---}\n    function ToString(aInt: Int64; const aElement: IwbElement): string; override;\n    function ToSortKey(aInt: Int64; const aElement: IwbElement): string; override;\n  end;\n\n  TwbData6Key2EnumDef = class(TwbEnumDef, IwbData6Key2EnumDef)\n  protected\n    {---IwbIntegerDefFormater---}\n    function ToString(aInt: Int64; const aElement: IwbElement): string; override;\n    function ToSortKey(aInt: Int64; const aElement: IwbElement): string; override;\n  end;\n\n  TwbDivDef = class(TwbIntegerDefFormater)\n  private\n    ddValue: Integer;\n  protected\n    constructor Clone(const aSource: TwbDef); override;\n    constructor Create(aValue: Integer);\n\n    function CanContainFormIDs: Boolean; override;\n\n    {---IwbIntegerDefFormater---}\n    function ToString(aInt: Int64; const aElement: IwbElement): string; override;\n    function ToSortKey(aInt: Int64; const aElement: IwbElement): string; override;\n    function CanAssign(const aElement: IwbElement; aIndex: Integer; const aDef: IwbDef): Boolean; override;\n\n    function ToEditValue(aInt: Int64; const aElement: IwbElement): string; override;\n    function FromEditValue(const aValue: string; const aElement: IwbElement): Int64; override;\n    function GetIsEditable(aInt: Int64; const aElement: IwbElement): Boolean; override;\n  end;\n\n  TwbMulDef = class(TwbIntegerDefFormater)\n  private\n    mdValue: Integer;\n  protected\n    constructor Clone(const aSource: TwbDef); override;\n    constructor Create(aValue: Integer);\n\n    function CanContainFormIDs: Boolean; override;\n\n    {---IwbIntegerDefFormater---}\n    function ToString(aInt: Int64; const aElement: IwbElement): string; override;\n    function ToSortKey(aInt: Int64; const aElement: IwbElement): string; override;\n    function CanAssign(const aElement: IwbElement; aIndex: Integer; const aDef: IwbDef): Boolean; override;\n\n    function ToEditValue(aInt: Int64; const aElement: IwbElement): string; override;\n    function FromEditValue(const aValue: string; const aElement: IwbElement): Int64; override;\n    function GetIsEditable(aInt: Int64; const aElement: IwbElement): Boolean; override;\n  end;\n\n  TwbCallbackDef = class(TwbIntegerDefFormater, IwbCallbackDef)\n  private\n    cdToStr: TwbIntToStrCallback;\n    cdToInt: TwbStrToIntCallback;\n  protected\n    constructor Clone(const aSource: TwbDef); override;\n    constructor Create(const aToStr : TwbIntToStrCallback;\n                       const aToInt : TwbStrToIntCallback);\n\n    function CanContainFormIDs: Boolean; override;\n\n    {---IwbIntegerDefFormater---}\n    function Check(aInt: Int64; const aElement: IwbElement): string; override;\n    function ToString(aInt: Int64; const aElement: IwbElement): string; override;\n    function ToSortKey(aInt: Int64; const aElement: IwbElement): string; override;\n    function CanAssign(const aElement: IwbElement; aIndex: Integer; const aDef: IwbDef): Boolean; override;\n\n    function GetEditType(aInt: Int64; const aElement: IwbElement): TwbEditType; override;\n    function GetEditInfo(aInt: Int64; const aElement: IwbElement): string; override;\n\n    function ToEditValue(aInt: Int64; const aElement: IwbElement): string; override;\n    function FromEditValue(const aValue: string; const aElement: IwbElement): Int64; override;\n    function GetIsEditable(aInt: Int64; const aElement: IwbElement): Boolean; override;\n\n    {---IwbCallbackDef---}\n    function GetCallback: TwbIntToStrCallback;\n  end;\n\n\nfunction wbRecord(const aSignature       : TwbSignature;\n                  const aName            : string;\n                  const aMembers         : array of IwbRecordMemberDef;\n                        aAllowUnordered  : Boolean = False;\n                        aAddInfoCallback : TwbAddInfoCallback = nil;\n                        aPriority        : TwbConflictPriority = cpNormal;\n                        aRequired        : Boolean = False;\n                        aAfterLoad       : TwbAfterLoadCallback = nil;\n                        aAfterSet        : TwbAfterSetCallback = nil)\n                                         : IwbRecordDef;\nbegin\n  Result := wbRecord(aSignature, aName, nil, aMembers, aAllowUnordered, aAddInfoCallback, aPriority, aRequired, aAfterLoad, aAfterSet);\nend;\n\nfunction wbRecord(const aSignature       : TwbSignature;\n                  const aName            : string;\n                  const aRecordFlags     : IwbIntegerDefFormater;\n                  const aMembers         : array of IwbRecordMemberDef;\n                        aAllowUnordered  : Boolean = False;\n                        aAddInfoCallback : TwbAddInfoCallback = nil;\n                        aPriority        : TwbConflictPriority = cpNormal;\n                        aRequired        : Boolean = False;\n                        aAfterLoad       : TwbAfterLoadCallback = nil;\n                        aAfterSet        : TwbAfterSetCallback = nil)\n                                         : IwbRecordDef;\nvar\n  Hash     : Integer;\n  Index    : Integer;\n  RDE      : PwbRecordDefEntry;\n  NewIndex : Integer;\nbegin\n  Hash := Cardinal(aSignature) mod RecordDefHashMapSize;\n  Index := Pred(wbRecordDefHashMap[Hash]);\n  if Index >= 0 then begin\n    RDE := @wbRecordDefs[Index];\n    while Assigned(RDE) do begin\n      if Cardinal(RDE.rdeSignature) = Cardinal(aSignature) then\n        raise Exception.CreateFmt('Duplicated record definition for signature %s', [String(aSignature)]);\n      if RDE.rdeNext >= 0 then\n        RDE := @wbRecordDefs[RDE.rdeNext]\n      else\n        RDE := nil;\n    end;\n  end;\n\n  Result := TwbRecordDef.Create(aPriority, aRequired, aSignature, aName, aRecordFlags, aMembers, aAllowUnordered, aAddInfoCallback, aAfterLoad, aAfterSet);\n  NewIndex := Length(wbRecordDefs);\n  SetLength(wbRecordDefs, Succ(NewIndex));\n  with wbRecordDefs[NewIndex] do begin\n    rdeDef := Result;\n    rdeSignature := aSignature;\n    rdeHash := Hash;\n    rdeNext := Index;\n  end;\n  wbRecordDefHashMap[Hash] := Succ(NewIndex);\nend;\n\nfunction wbSubRecord(const aSignature : TwbSignature;\n                     const aName      : string;\n                     const aValue     : IwbValueDef;\n                           aAfterLoad : TwbAfterLoadCallback = nil;\n                           aAfterSet  : TwbAfterSetCallback = nil;\n                           aPriority  : TwbConflictPriority = cpNormal;\n                           aRequired  : Boolean = False;\n                           aSizeMatch : Boolean = False;\n                           aDontShow  : TwbDontShowCallback = nil;\n                           aGetCP     : TwbGetConflictPriority = nil)\n                                      : IwbSubRecordDef;\nbegin\n  Result := TwbSubRecordDef.Create(aPriority, aRequired, aSignature, aName, aValue, aAfterLoad, aAfterSet, aSizeMatch, aDontShow, aGetCP);\nend;\n\nfunction wbSubRecord(const aSignatures : array of TwbSignature;\n                     const aName       : string;\n                     const aValue      : IwbValueDef;\n                           aAfterLoad  : TwbAfterLoadCallback = nil; aAfterSet: TwbAfterSetCallback = nil;\n                           aPriority   : TwbConflictPriority = cpNormal;\n                           aRequired   : Boolean = False;\n                           aSizeMatch  : Boolean = False;\n                           aDontShow   : TwbDontShowCallback = nil;\n                           aGetCP      : TwbGetConflictPriority = nil)\n                                       : IwbSubRecordDef;\nbegin\n  Result := TwbSubRecordDef.Create(aPriority, aRequired, aSignatures, aName, aValue, aAfterLoad, aAfterSet, aSizeMatch, aDontShow, aGetCP);\nend;\n\n\nfunction wbString(const aSignature : TwbSignature;\n                  const aName      : string = 'Unknown';\n                        aSize      : Integer = 0;\n                        aPriority  : TwbConflictPriority = cpNormal;\n                        aRequired  : Boolean = False;\n                        aDontShow  : TwbDontShowCallback = nil;\n                        aAfterSet  : TwbAfterSetCallback = nil;\n                        aGetCP     : TwbGetConflictPriority = nil)\n                                   : IwbSubRecordDef; overload;\nbegin\n  Result := wbSubRecord(aSignature, aName, wbString('', aSize, aPriority), nil, aAfterSet, aPriority, aRequired, False, aDontShow, aGetCP);\nend;\n\nfunction wbString(const aName      : string = 'Unknown';\n                        aSize      : Integer = 0;\n                        aPriority  : TwbConflictPriority = cpNormal;\n                        aRequired  : Boolean = False;\n                        aDontShow  : TwbDontShowCallback = nil;\n                        aAfterSet  : TwbAfterSetCallback = nil;\n                        aGetCP     : TwbGetConflictPriority = nil)\n                                   : IwbStringDef; overload;\nbegin\n  Result := TwbStringDef.Create(aPriority, aRequired, aName, aSize, nil, aAfterSet, aDontShow, aGetCP, False);\nend;\n\nfunction wbStringForward(const aSignature : TwbSignature;           // When the editor can leave chars after the ending #0\n                         const aName      : string = 'Unknown';\n                               aSize      : Integer = 0;\n                               aPriority  : TwbConflictPriority = cpNormal;\n                               aRequired  : Boolean = False;\n                               aDontShow  : TwbDontShowCallback = nil;\n                               aAfterSet  : TwbAfterSetCallback = nil;\n                               aGetCP     : TwbGetConflictPriority = nil)\n                                          : IwbSubRecordDef; overload;\nbegin\n  Result := wbSubRecord(aSignature, aName, wbString(True, '', aSize, aPriority, aRequired, aDontShow, aAfterSet), nil, aAfterSet, aPriority, aRequired, False, aDontShow);\nend;\n\nfunction wbString(      aForward   : Boolean = False;\n                  const aName      : string = 'Unknown';\n                        aSize      : Integer = 0;\n                        aPriority  : TwbConflictPriority = cpNormal;\n                        aRequired  : Boolean = False;\n                        aDontShow  : TwbDontShowCallback = nil;\n                        aAfterSet  : TwbAfterSetCallback = nil;\n                        aGetCP     : TwbGetConflictPriority = nil)\n                                   : IwbStringDef; overload;\nbegin\n  Result := TwbStringDef.Create(aPriority, aRequired, aName, aSize, nil, aAfterSet, aDontShow, aGetCP, False, aForward);\nend;\n\nfunction wbStringT(const aSignature : TwbSignature;\n                   const aName      : string = 'Unknown';\n                         aSize      : Integer = 0;\n                         aPriority  : TwbConflictPriority = cpNormal;\n                         aRequired  : Boolean = False;\n                         aDontShow  : TwbDontShowCallback = nil;\n                         aAfterSet  : TwbAfterSetCallback = nil;\n                         aGetCP     : TwbGetConflictPriority = nil)\n                                    : IwbSubRecordDef; overload;\nbegin\n  Result := wbSubRecord(aSignature, aName, wbStringT('', aSize, aPriority, aRequired, aDontShow, aAfterSet, aGetCP), nil, aAfterSet, aPriority, aRequired, False, aDontShow, aGetCP);\nend;\n\nfunction wbStringT(const aName      : string = 'Unknown';\n                         aSize      : Integer = 0;\n                         aPriority  : TwbConflictPriority = cpNormal;\n                         aRequired  : Boolean = False;\n                         aDontShow  : TwbDontShowCallback = nil;\n                         aAfterSet  : TwbAfterSetCallback = nil;\n                         aGetCP     : TwbGetConflictPriority = nil)\n                                    : IwbStringDef; overload;\nbegin\n  Result := TwbStringDef.Create(aPriority, aRequired, aName, aSize, nil, aAfterSet, aDontShow, aGetCP, True);\nend;\n\nfunction wbStringScript(const aSignature : TwbSignature;\n                        const aName      : string;\n                              aSize      : Integer = 0;\n                              aPriority  : TwbConflictPriority = cpNormal;\n                              aRequired  : Boolean = False;\n                              aDontShow  : TwbDontShowCallback = nil;\n                              aAfterSet  : TwbAfterSetCallback = nil;\n                              aGetCP     : TwbGetConflictPriority = nil)\n                                         : IwbSubRecordDef; overload;\nbegin\n  Result := wbSubRecord(aSignature, aName, wbStringScript('', aSize, aPriority), nil, aAfterSet, aPriority, aRequired, False, aDontShow, aGetCP);\nend;\n\nfunction wbStringScript(const aName      : string;\n                              aSize      : Integer = 0;\n                              aPriority  : TwbConflictPriority = cpNormal;\n                              aRequired  : Boolean = False;\n                              aDontShow  : TwbDontShowCallback = nil;\n                              aAfterSet  : TwbAfterSetCallback = nil;\n                              aGetCP     : TwbGetConflictPriority = nil)\n                                         : IwbStringDef; overload;\nbegin\n  Result := TwbStringScriptDef.Create(aPriority, aRequired, aName, aSize, nil, aAfterSet, aDontShow, aGetCP, False);\nend;\n\nfunction wbStringLC(const aSignature : TwbSignature;\n                    const aName      : string;\n                          aSize      : Integer = 0;\n                          aPriority  : TwbConflictPriority = cpNormal;\n                          aRequired  : Boolean = False;\n                          aDontShow  : TwbDontShowCallback = nil;\n                          aAfterSet  : TwbAfterSetCallback = nil;\n                          aGetCP     : TwbGetConflictPriority = nil)\n                                     : IwbSubRecordDef; overload;\nbegin\n  Result := wbSubRecord(aSignature, aName, wbStringLC('', aSize, aPriority), nil, aAfterSet, aPriority, aRequired, False, aDontShow, aGetCP);\nend;\n\nfunction wbStringLC(const aName      : string;\n                          aSize      : Integer = 0;\n                          aPriority  : TwbConflictPriority = cpNormal;\n                          aRequired  : Boolean = False;\n                          aDontShow  : TwbDontShowCallback = nil;\n                          aAfterSet  : TwbAfterSetCallback = nil;\n                          aGetCP     : TwbGetConflictPriority = nil)\n                                     : IwbStringDef; overload;\nbegin\n  Result := TwbStringLCDef.Create(aPriority, aRequired, aName, aSize, nil, aAfterSet, aDontShow, aGetCP, False);\nend;\n\nfunction wbStringKC(const aSignature : TwbSignature;\n                    const aName      : string;\n                          aSize      : Integer = 0;\n                          aPriority  : TwbConflictPriority = cpNormal;\n                          aRequired  : Boolean = False;\n                          aDontShow  : TwbDontShowCallback = nil;\n                          aAfterSet  : TwbAfterSetCallback = nil;\n                          aGetCP     : TwbGetConflictPriority = nil)\n                                     : IwbSubRecordDef; overload;\nbegin\n  Result := wbSubRecord(aSignature, aName, wbStringKC('', aSize, aPriority), nil, aAfterSet, aPriority, aRequired, False, aDontShow, aGetCP);\nend;\n\nfunction wbStringKC(const aName      : string;\n                          aSize      : Integer = 0;\n                          aPriority  : TwbConflictPriority = cpNormal;\n                          aRequired  : Boolean = False;\n                          aDontShow  : TwbDontShowCallback = nil;\n                          aAfterSet  : TwbAfterSetCallback = nil;\n                          aGetCP     : TwbGetConflictPriority = nil)\n                                     : IwbStringDef; overload;\nbegin\n  Result := TwbStringKCDef.Create(aPriority, aRequired, aName, aSize, nil, aAfterSet, aDontShow, aGetCP, False);\nend;\n\nfunction wbLString(const aSignature : TwbSignature;\n                   const aName      : string;\n                         aSize      : Integer = 0;\n                         aPriority  : TwbConflictPriority = cpNormal;\n                         aRequired  : Boolean = False;\n                         aDontShow  : TwbDontShowCallback = nil;\n                         aAfterSet  : TwbAfterSetCallback = nil;\n                         aGetCP     : TwbGetConflictPriority = nil)\n                                    : IwbSubRecordDef; overload;\nbegin\n  Result := wbSubRecord(aSignature, aName, wbLString('', aSize, aPriority), nil, aAfterSet, aPriority, aRequired, False, aDontShow, aGetCP);\nend;\n\nfunction wbLString(const aName      : string;\n                         aSize      : Integer = 0;\n                         aPriority  : TwbConflictPriority = cpNormal;\n                         aRequired  : Boolean = False;\n                         aDontShow  : TwbDontShowCallback = nil;\n                         aAfterSet  : TwbAfterSetCallback = nil;\n                         aGetCP     : TwbGetConflictPriority = nil)\n                                    : IwbStringDef; overload;\nbegin\n  Result := TwbLStringDef.Create(aPriority, aRequired, aName, aSize, nil, aAfterSet, aDontShow, aGetCP, False);\nend;\n\nfunction wbLStringKC(const aSignature : TwbSignature;\n                     const aName      : string;\n                           aSize      : Integer = 0;\n                           aPriority  : TwbConflictPriority = cpNormal;\n                           aRequired  : Boolean = False;\n                           aDontShow  : TwbDontShowCallback = nil;\n                           aAfterSet  : TwbAfterSetCallback = nil;\n                           aGetCP     : TwbGetConflictPriority = nil)\n                                      : IwbSubRecordDef; overload;\nbegin\n  Result := wbSubRecord(aSignature, aName, wbLStringKC('', aSize, aPriority), nil, aAfterSet, aPriority, aRequired, False, aDontShow, aGetCP);\nend;\n\nfunction wbLStringKC(const aName      : string;\n                           aSize      : Integer = 0;\n                           aPriority  : TwbConflictPriority = cpNormal;\n                           aRequired  : Boolean = False;\n                           aDontShow  : TwbDontShowCallback = nil;\n                           aAfterSet  : TwbAfterSetCallback = nil;\n                           aGetCP     : TwbGetConflictPriority = nil)\n                                      : IwbStringDef; overload;\nbegin\n  Result := TwbLStringKCDef.Create(aPriority, aRequired, aName, aSize, nil, aAfterSet, aDontShow, aGetCP, False);\nend;\n\nfunction wbStringMgefCode(const aSignature : TwbSignature;\n                    const aName      : string;\n                          aSize      : Integer = 0;\n                          aPriority  : TwbConflictPriority = cpNormal;\n                          aRequired  : Boolean = False;\n                          aDontShow  : TwbDontShowCallback = nil;\n                          aAfterSet  : TwbAfterSetCallback = nil;\n                          aGetCP     : TwbGetConflictPriority = nil)\n                                     : IwbSubRecordDef; overload;\nbegin\n  Result := wbSubRecord(aSignature, aName, wbStringMgefCode('', aSize, aPriority), nil, aAfterSet, aPriority, aRequired, False, aDontShow, aGetCP);\nend;\n\nfunction wbStringMgefCode(const aName      : string;\n                                aSize      : Integer = 0;\n                                aPriority  : TwbConflictPriority = cpNormal;\n                                aRequired  : Boolean = False;\n                                aDontShow  : TwbDontShowCallback = nil;\n                                aAfterSet  : TwbAfterSetCallback = nil;\n                                aGetCP     : TwbGetConflictPriority = nil)\n                                           : IwbStringDef; overload;\nbegin\n  Result := TwbStringMgefCodeDef.Create(aPriority, aRequired, aName, aSize, nil, aAfterSet, aDontShow, aGetCP, False);\nend;\n\nfunction wbLenString(const aSignature : TwbSignature;\n                     const aName      : string;\n                           aPrefix    : Integer = 4;\n                           aPriority  : TwbConflictPriority = cpNormal;\n                           aRequired  : Boolean = False;\n                           aDontShow  : TwbDontShowCallback = nil;\n                           aGetCP     : TwbGetConflictPriority = nil)\n                                      : IwbSubRecordDef; overload;\nbegin\n  Result := wbSubRecord(aSignature, aName, wbLenString('', aPrefix, aPriority), nil, nil, aPriority, aRequired, False, aDontShow, aGetCP);\nend;\n\nfunction wbLenString(const aName      : string;\n                           aPrefix    : Integer = 4;\n                           aPriority  : TwbConflictPriority = cpNormal;\n                           aRequired  : Boolean = False;\n                           aDontShow  : TwbDontShowCallback = nil;\n                           aGetCP     : TwbGetConflictPriority = nil)\n                                      : IwbLenStringDef; overload;\nbegin\n  Result := TwbLenStringDef.Create(aPriority, aRequired, aName, aPrefix, nil, nil, aDontShow, aGetCP, False);\nend;\n\nfunction wbLenStringT(const aSignature : TwbSignature;\n                      const aName      : string;\n                            aPrefix    : Integer = 4;\n                            aPriority  : TwbConflictPriority = cpNormal;\n                            aRequired  : Boolean = False;\n                            aDontShow  : TwbDontShowCallback = nil;\n                            aGetCP     : TwbGetConflictPriority = nil)\n                                       : IwbSubRecordDef; overload;\nbegin\n  Result := wbSubRecord(aSignature, aName, wbLenStringT('', aPrefix, aPriority), nil, nil, aPriority, aRequired, False, aDontShow, aGetCP);\nend;\n\nfunction wbLenStringT(const aName      : string;\n                            aPrefix    : Integer = 4;\n                            aPriority  : TwbConflictPriority = cpNormal;\n                            aRequired  : Boolean = False;\n                            aDontShow  : TwbDontShowCallback = nil;\n                            aGetCP     : TwbGetConflictPriority = nil)\n                                       : IwbLenStringDef; overload;\nbegin\n  Result := TwbLenStringDef.Create(aPriority, aRequired, aName, aPrefix, nil, nil, aDontShow, aGetCP, True);\nend;\n\nfunction wbUnion(const aSignature : TwbSignature;\n                 const aName      : string;\n                       aDecider   : TwbUnionDecider;\n                 const aMembers   : array of IwbValueDef;\n                       aPriority  : TwbConflictPriority = cpNormal;\n                       aRequired  : Boolean = False;\n                       aDontShow  : TwbDontShowCallback = nil;\n                       aGetCP     : TwbGetConflictPriority = nil)\n                                  : IwbSubRecordDef; overload;\nbegin\n  Result := wbSubRecord(aSignature, aName, wbUnion('', aDecider, aMembers, aPriority), nil, nil, aPriority, aRequired, False, aDontShow, aGetCP);\nend;\n\nfunction wbUnion(const aName     : string;\n                       aDecider  : TwbUnionDecider;\n                 const aMembers  : array of IwbValueDef;\n                       aPriority : TwbConflictPriority = cpNormal;\n                       aRequired : Boolean = False;\n                       aDontShow : TwbDontShowCallback = nil;\n                       aAfterSet : TwbAfterSetCallback = nil;\n                       aGetCP    : TwbGetConflictPriority = nil)\n                                 : IwbUnionDef; overload;\nbegin\n  Result := TwbUnionDef.Create(aPriority, aRequired, aName, aDecider, aMembers, aDontShow, aAfterSet, aGetCP);\nend;\n\n\nfunction wbByteArray(const aSignature : TwbSignature;\n                     const aName      : string = 'Unknown';\n                           aSize      : Int64 = 0;\n                           aPriority  : TwbConflictPriority = cpNormal;\n                           aRequired  : Boolean = False;\n                           aSizeMatch : Boolean = False;\n                           aDontShow  : TwbDontShowCallback = nil;\n                           aGetCP     : TwbGetConflictPriority = nil)\n                                      : IwbSubRecordDef; overload;\nbegin\n  Result := wbSubRecord(aSignature, aName, wbByteArray('', aSize, aPriority), nil, nil, aPriority, aRequired, aSizeMatch, aDontShow, aGetCP);\nend;\n\nfunction wbByteArray(const aName     : string = 'Unknown';\n                           aSize     : Int64 = 0;\n                           aPriority : TwbConflictPriority = cpNormal;\n                           aRequired : Boolean = False;\n                           aDontShow : TwbDontShowCallback = nil;\n                           aGetCP    : TwbGetConflictPriority = nil)\n                                     : IwbByteArrayDef; overload;\nbegin\n  Result := TwbByteArrayDef.Create(aPriority, aRequired, aName, aSize, aDontShow, nil, aGetCP, False);\nend;\n\nfunction wbByteArrayT(const aName     : string = 'Unknown';\n                            aSize     : Int64 = 0;\n                            aPriority : TwbConflictPriority = cpNormal;\n                            aRequired : Boolean = False;\n                            aDontShow : TwbDontShowCallback = nil;\n                            aGetCP    : TwbGetConflictPriority = nil)\n                                      : IwbByteArrayDef; overload;\nbegin\n  Result := TwbByteArrayDef.Create(aPriority, aRequired, aName, aSize, aDontShow, nil, aGetCP, True);\nend;\n\nfunction wbByteArray(const aName          : string;\n                           aCountCallback : TwbCountCallback;\n                           aPriority      : TwbConflictPriority = cpNormal;\n                           aRequired      : Boolean = False;\n                           aDontShow      : TwbDontShowCallback = nil;\n                           aGetCP         : TwbGetConflictPriority = nil)\n                                          : IwbByteArrayDef; overload;\nbegin\n  Result := TwbByteArrayDef.Create(aPriority, aRequired, aName, 0, aDontShow, aCountCallback, aGetCP, False);\nend;\n\nfunction wbUnknown(const aSignature : TwbSignature;\n                         aPriority  : TwbConflictPriority = cpNormal;\n                         aRequired  : Boolean = False;\n                         aDontShow  : TwbDontShowCallback = nil;\n                         aGetCP     : TwbGetConflictPriority = nil)\n                                    : IwbSubRecordDef;\nbegin\n  Result := wbByteArray(aSignature, 'Unknown', 0, aPriority, aRequired, False, aDontShow, aGetCP);\nend;\n\nfunction wbUnknown(aPriority : TwbConflictPriority = cpNormal;\n                   aRequired : Boolean = False;\n                   aDontShow : TwbDontShowCallback = nil;\n                   aGetCP    : TwbGetConflictPriority = nil)\n                             : IwbByteArrayDef;\nbegin\n  Result := wbByteArray('Unknown', 0, aPriority, aRequired, aDontShow, aGetCP);\nend;\n\nfunction wbInteger(const aSignature : TwbSignature;\n                   const aName      : string;\n                   const aIntType   : TwbIntType;\n                   const aFormater  : IwbIntegerDefFormater = nil;\n                         aPriority  : TwbConflictPriority = cpNormal;\n                         aRequired  : Boolean = False;\n                         aMatchSize : Boolean = False;\n                         aDontShow  : TwbDontShowCallback = nil;\n                         aAfterSet  : TwbAfterSetCallback = nil;\n                         aDefault   : Int64 = 0;\n                         aGetCP     : TwbGetConflictPriority = nil)\n                                    : IwbSubRecordDef; overload;\nbegin\n  Result := wbSubRecord(aSignature, aName, wbInteger('', aIntType, aFormater, aPriority, False, nil, nil, aDefault), nil, aAfterSet, aPriority, aRequired, aMatchSize, aDontShow, aGetCP);\nend;\n\nfunction wbIntegerT(const aSignature : TwbSignature;\n                    const aName      : string;\n                    const aIntType   : TwbIntType;\n                    const aFormater  : IwbIntegerDefFormater = nil;\n                          aPriority  : TwbConflictPriority = cpNormal;\n                          aRequired  : Boolean = False;\n                          aMatchSize : Boolean = False;\n                          aDontShow  : TwbDontShowCallback = nil;\n                          aAfterSet  : TwbAfterSetCallback = nil;\n                          aDefault   : Int64 = 0;\n                          aGetCP     : TwbGetConflictPriority = nil)\n                                     : IwbSubRecordDef; overload;\nbegin\n  Result := wbSubRecord(aSignature, aName, wbIntegerT('', aIntType, aFormater, aPriority, False, nil, nil, aDefault), nil, aAfterSet, aPriority, aRequired, aMatchSize, aDontShow, aGetCP);\nend;\n\nfunction wbInteger(const aName     : string;\n                   const aIntType  : TwbIntType;\n                   const aFormater : IwbIntegerDefFormater = nil;\n                         aPriority : TwbConflictPriority = cpNormal;\n                         aRequired : Boolean = False;\n                         aDontShow : TwbDontShowCallback = nil;\n                         aAfterSet : TwbAfterSetCallback = nil;\n                         aDefault  : Int64 = 0;\n                         aGetCP    : TwbGetConflictPriority = nil)\n                                   : IwbIntegerDef; overload;\nbegin\n  Result := TwbIntegerDef.Create(aPriority, aRequired, aName, aIntType, aFormater, aDontShow, aAfterSet, aDefault, aGetCP, False);\nend;\n\nfunction wbIntegerT(const aName     : string;\n                    const aIntType  : TwbIntType;\n                    const aFormater : IwbIntegerDefFormater = nil;\n                          aPriority : TwbConflictPriority = cpNormal;\n                          aRequired : Boolean = False;\n                          aDontShow : TwbDontShowCallback = nil;\n                          aAfterSet : TwbAfterSetCallback = nil;\n                          aDefault  : Int64 = 0;\n                          aGetCP    : TwbGetConflictPriority = nil)\n                                    : IwbIntegerDef; overload;\nbegin\n  Result := TwbIntegerDef.Create(aPriority, aRequired, aName, aIntType, aFormater, aDontShow, aAfterSet, aDefault, aGetCP, True);\nend;\n\nfunction wbInteger(const aSignature : TwbSignature;\n                   const aName      : string;\n                   const aIntType   : TwbIntType;\n                   const aToStr     : TwbIntToStrCallback;\n                   const aToInt     : TwbStrToIntCallback = nil;\n                         aPriority  : TwbConflictPriority = cpNormal;\n                         aRequired  : Boolean = False;\n                         aDontShow  : TwbDontShowCallback = nil;\n                         aAfterSet  : TwbAfterSetCallback = nil;\n                         aDefault   : Int64 = 0;\n                         aGetCP     : TwbGetConflictPriority = nil)\n                                    : IwbSubRecordDef; overload;\nvar\n  Callback: IwbIntegerDefFormater;\nbegin\n  if Assigned(aToStr) then\n    Callback := wbCallback(aToStr, aToInt);\n  Result := wbInteger(aSignature, aName, aIntType, Callback, aPriority, aRequired, False, aDontShow, aAfterSet, aDefault);\nend;\n\nfunction wbIntegerT(const aSignature : TwbSignature;\n                    const aName      : string;\n                    const aIntType   : TwbIntType;\n                    const aToStr     : TwbIntToStrCallback;\n                    const aToInt     : TwbStrToIntCallback = nil;\n                          aPriority  : TwbConflictPriority = cpNormal;\n                          aRequired  : Boolean = False;\n                          aDontShow  : TwbDontShowCallback = nil;\n                          aAfterSet  : TwbAfterSetCallback = nil;\n                          aDefault   : Int64 = 0;\n                          aGetCP     : TwbGetConflictPriority = nil)\n                                     : IwbSubRecordDef; overload;\nvar\n  Callback: IwbIntegerDefFormater;\nbegin\n  if Assigned(aToStr) then\n    Callback := wbCallback(aToStr, aToInt);\n  Result := wbIntegerT(aSignature, aName, aIntType, Callback, aPriority, aRequired, False, aDontShow, aAfterSet, aDefault, aGetCP);\nend;\n\nfunction wbInteger(const aName     : string;\n                   const aIntType  : TwbIntType;\n                   const aToStr    : TwbIntToStrCallback;\n                   const aToInt    : TwbStrToIntCallback = nil;\n                         aPriority : TwbConflictPriority = cpNormal;\n                         aRequired : Boolean = False;\n                         aDontShow : TwbDontShowCallback = nil;\n                         aAfterSet : TwbAfterSetCallback = nil;\n                         aDefault  : Int64 = 0;\n                         aGetCP    : TwbGetConflictPriority = nil)\n                                   : IwbIntegerDef; overload;\nvar\n  Callback: IwbIntegerDefFormater;\nbegin\n  if Assigned(aToStr) then\n    Callback := wbCallback(aToStr, aToInt);\n  Result := wbInteger(aName, aIntType, Callback, aPriority, aRequired, aDontShow, aAfterSet, aDefault);\nend;\n\nfunction wbIntegerT(const aName     : string;\n                    const aIntType  : TwbIntType;\n                    const aToStr    : TwbIntToStrCallback;\n                    const aToInt    : TwbStrToIntCallback = nil;\n                          aPriority : TwbConflictPriority = cpNormal;\n                          aRequired : Boolean = False;\n                          aDontShow : TwbDontShowCallback = nil;\n                          aAfterSet : TwbAfterSetCallback = nil;\n                          aDefault  : Int64 = 0;\n                          aGetCP    : TwbGetConflictPriority = nil)\n                                    : IwbIntegerDef; overload;\nvar\n  Callback: IwbIntegerDefFormater;\nbegin\n  if Assigned(aToStr) then\n    Callback := wbCallback(aToStr, aToInt);\n  Result := wbIntegerT(aName, aIntType, Callback, aPriority, aRequired, aDontShow, aAfterSet, aDefault, aGetCP);\nend;\n\nfunction wbFloat(const aSignature  : TwbSignature;\n                 const aName       : string = 'Unknown';\n                       aPriority   : TwbConflictPriority = cpNormal;\n                       aRequired   : Boolean = False;\n                       aScale      : Extended = 1.0;\n                       aDigits     : Integer = -1;\n                       aDontShow   : TwbDontShowCallback = nil;\n                       aNormalizer : TwbFloatNormalizer = nil;\n                       aDefault    : Extended = 0.0;\n                       aGetCP      : TwbGetConflictPriority = nil)\n                                   : IwbSubRecordDef; overload;\nbegin\n  Result := wbSubRecord(aSignature, aName, wbFloat('', aPriority, False, aScale, aDigits, nil, aNormalizer, aDefault, aGetCP), nil, nil, aPriority, aRequired, False, aDontShow, aGetCP);\nend;\n\nfunction wbDouble(const aSignature  : TwbSignature;\n                  const aName       : string = 'Unknown';\n                        aPriority   : TwbConflictPriority = cpNormal;\n                        aRequired   : Boolean = False;\n                        aScale      : Extended = 1.0;\n                        aDigits     : Integer = -1;\n                        aDontShow   : TwbDontShowCallback = nil;\n                        aNormalizer : TwbFloatNormalizer = nil;\n                        aDefault    : Extended = 0.0;\n                        aGetCP      : TwbGetConflictPriority = nil)\n                                    : IwbSubRecordDef; overload;\nbegin\n  Result := wbSubRecord(aSignature, aName, wbDouble('', aPriority, False, aScale, aDigits, nil, aNormalizer, aDefault), nil, nil, aPriority, aRequired, False, aDontShow, aGetCP);\nend;\n\nfunction wbFloat(const aName       : string = 'Unknown';\n                       aPriority   : TwbConflictPriority = cpNormal;\n                       aRequired   : Boolean = False;\n                       aScale      : Extended = 1.0;\n                       aDigits     : Integer = -1;\n                       aDontShow   : TwbDontShowCallback = nil;\n                       aNormalizer : TwbFloatNormalizer = nil;\n                       aDefault    : Extended = 0.0;\n                       aGetCP      : TwbGetConflictPriority = nil)\n                                   : IwbFloatDef; overload;\nbegin\n  Result := TwbFloatDef.Create(aPriority, aRequired, aName, nil, nil, aScale, aDigits, aDontShow, aNormalizer, aDefault, aGetCP, False, False);\nend;\n\nfunction wbDouble(const aName       : string = 'Unknown';\n                        aPriority   : TwbConflictPriority = cpNormal;\n                        aRequired   : Boolean = False;\n                        aScale      : Extended = 1.0;\n                        aDigits     : Integer = -1;\n                        aDontShow   : TwbDontShowCallback = nil;\n                        aNormalizer : TwbFloatNormalizer = nil;\n                        aDefault    : Extended = 0.0;\n                        aGetCP      : TwbGetConflictPriority = nil)\n                                    : IwbFloatDef; overload;\nbegin\n  Result := TwbFloatDef.Create(aPriority, aRequired, aName, nil, nil, aScale, aDigits, aDontShow, aNormalizer, aDefault, aGetCP, True, False);\nend;\n\nfunction wbFloat(const aName       : string;\n                       aPriority   : TwbConflictPriority;\n                       aRequired   : Boolean;\n                       aDontShow   : TwbDontShowCallback;\n                       aAfterSet   : TwbAfterSetCallback = nil;\n                       aNormalizer : TwbFloatNormalizer = nil;\n                       aDefault    : Extended = 0.0;\n                       aGetCP      : TwbGetConflictPriority = nil)\n                                   : IwbFloatDef; overload;\nbegin\n  Result := TwbFloatDef.Create(aPriority, aRequired, aName, nil, aAfterSet, 1.0, -1, aDontShow, aNormalizer, aDefault, aGetCP, False, False);\nend;\n\nfunction wbDouble(const aName       : string;\n                        aPriority   : TwbConflictPriority;\n                        aRequired   : Boolean;\n                        aDontShow   : TwbDontShowCallback;\n                        aAfterSet   : TwbAfterSetCallback = nil;\n                        aNormalizer : TwbFloatNormalizer = nil;\n                        aDefault    : Extended = 0.0;\n                        aGetCP      : TwbGetConflictPriority = nil)\n                                    : IwbFloatDef; overload;\nbegin\n  Result := TwbFloatDef.Create(aPriority, aRequired, aName, nil, aAfterSet, 1.0, -1, aDontShow, aNormalizer, aDefault, aGetCP, True, False);\nend;\n\nfunction wbFloatT(const aSignature  : TwbSignature;\n                  const aName       : string = 'Unknown';\n                        aPriority   : TwbConflictPriority = cpNormal;\n                        aRequired   : Boolean = False;\n                        aScale      : Extended = 1.0;\n                        aDigits     : Integer = -1;\n                        aDontShow   : TwbDontShowCallback = nil;\n                        aNormalizer : TwbFloatNormalizer = nil;\n                        aDefault    : Extended = 0.0;\n                        aGetCP      : TwbGetConflictPriority = nil)\n                                    : IwbSubRecordDef; overload;\nbegin\n  Result := wbSubRecord(aSignature, aName, wbFloatT('', aPriority, False, aScale, aDigits, nil, aNormalizer, aDefault), nil, nil, aPriority, aRequired, False, aDontShow, aGetCP);\nend;\n\nfunction wbDoubleT(const aSignature  : TwbSignature;\n                   const aName       : string = 'Unknown';\n                         aPriority   : TwbConflictPriority = cpNormal;\n                         aRequired   : Boolean = False;\n                         aScale      : Extended = 1.0;\n                         aDigits     : Integer = -1;\n                         aDontShow   : TwbDontShowCallback = nil;\n                         aNormalizer : TwbFloatNormalizer = nil;\n                         aDefault    : Extended = 0.0;\n                         aGetCP      : TwbGetConflictPriority = nil)\n                                     : IwbSubRecordDef; overload;\nbegin\n  Result := wbSubRecord(aSignature, aName, wbDoubleT('', aPriority, False, aScale, aDigits, nil, aNormalizer, aDefault), nil, nil, aPriority, aRequired, False, aDontShow, aGetCP);\nend;\n\nfunction wbFloatT(const aName       : string = 'Unknown';\n                        aPriority   : TwbConflictPriority = cpNormal;\n                        aRequired   : Boolean = False;\n                        aScale      : Extended = 1.0;\n                        aDigits     : Integer = -1;\n                        aDontShow   : TwbDontShowCallback = nil;\n                        aNormalizer : TwbFloatNormalizer = nil;\n                        aDefault    : Extended = 0.0;\n                        aGetCP      : TwbGetConflictPriority = nil)\n                                    : IwbFloatDef; overload;\nbegin\n  Result := TwbFloatDef.Create(aPriority, aRequired, aName, nil, nil, aScale, aDigits, aDontShow, aNormalizer, aDefault, aGetCP, False, True);\nend;\n\nfunction wbDoubleT(const aName       : string = 'Unknown';\n                         aPriority   : TwbConflictPriority = cpNormal;\n                         aRequired   : Boolean = False;\n                         aScale      : Extended = 1.0;\n                         aDigits     : Integer = -1;\n                         aDontShow   : TwbDontShowCallback = nil;\n                         aNormalizer : TwbFloatNormalizer = nil;\n                         aDefault    : Extended = 0.0;\n                         aGetCP      : TwbGetConflictPriority = nil)\n                                     : IwbFloatDef; overload;\nbegin\n  Result := TwbFloatDef.Create(aPriority, aRequired, aName, nil, nil, aScale, aDigits, aDontShow, aNormalizer, aDefault, aGetCP, True, True);\nend;\n\nfunction wbFloatT(const aName       : string;\n                        aPriority   : TwbConflictPriority;\n                        aRequired   : Boolean;\n                        aDontShow   : TwbDontShowCallback;\n                        aAfterSet   : TwbAfterSetCallback = nil;\n                        aNormalizer : TwbFloatNormalizer = nil;\n                        aDefault    : Extended = 0.0;\n                        aGetCP      : TwbGetConflictPriority = nil)\n                                    : IwbFloatDef; overload;\nbegin\n  Result := TwbFloatDef.Create(aPriority, aRequired, aName, nil, aAfterSet, 1.0, -1, aDontShow, aNormalizer, aDefault, aGetCP, False, True);\nend;\n\nfunction wbDoubleT(const aName       : string;\n                         aPriority   : TwbConflictPriority;\n                         aRequired   : Boolean;\n                         aDontShow   : TwbDontShowCallback;\n                         aAfterSet   : TwbAfterSetCallback = nil;\n                         aNormalizer : TwbFloatNormalizer = nil;\n                         aDefault    : Extended = 0.0;\n                         aGetCP      : TwbGetConflictPriority = nil)\n                                     : IwbFloatDef; overload;\nbegin\n  Result := TwbFloatDef.Create(aPriority, aRequired, aName, nil, aAfterSet, 1.0, -1, aDontShow, aNormalizer, aDefault, aGetCP, True, True);\nend;\n\n{--- wbArray - list of identical elements -------------------------------------}\nfunction wbArray(const aSignature : TwbSignature;\n                 const aName      : string;\n                 const aElement   : IwbValueDef;\n                       aCount     : Integer = 0;\n                       aAfterLoad : TwbAfterLoadCallback = nil;\n                       aAfterSet  : TwbAfterSetCallback = nil;\n                       aPriority  : TwbConflictPriority = cpNormal;\n                       aRequired  : Boolean = False;\n                       aDontShow  : TwbDontShowCallback = nil;\n                       aGetCP     : TwbGetConflictPriority = nil)\n                                  : IwbSubRecordDef; overload;\nbegin\n  Result := wbSubRecord(aSignature, aName, wbArray('', aElement, aCount, aPriority), aAfterLoad, aAfterSet, aPriority, aRequired, False, aDontShow, aGetCP);\nend;\n\nfunction wbArray(const aName      : string;\n                 const aElement   : IwbValueDef;\n                       aCount     : Integer = 0;\n                       aPriority  : TwbConflictPriority = cpNormal;\n                       aRequired  : Boolean = False;\n                       aDontShow  : TwbDontShowCallback = nil;\n                       aGetCP     : TwbGetConflictPriority = nil)\n                                  : IwbArrayDef; overload;\nbegin\n  Result := TwbArrayDef.Create(aPriority, aRequired, aName, aElement, aCount, [], False, nil, nil, aDontShow, aGetCP, True, False, False);\nend;\n\n\nfunction wbArray(const aName      : string;\n                 const aElement   : IwbValueDef;\n                       aCount     : Integer;\n                       aAfterLoad : TwbAfterLoadCallback;\n                       aPriority  : TwbConflictPriority = cpNormal;\n                       aRequired  : Boolean = False;\n                       aDontShow  : TwbDontShowCallback = nil;\n                       aGetCP     : TwbGetConflictPriority = nil)\n                                  : IwbArrayDef; overload;\nbegin\n  Result := TwbArrayDef.Create(aPriority, aRequired, aName, aElement, aCount, [], False, aAfterLoad, nil, aDontShow, aGetCP, True, False, False);\nend;\n\nfunction wbArrayPT(const aSignature : TwbSignature;\n                   const aName      : string;\n                   const aElement   : IwbValueDef;\n                         aCount     : Integer = 0;\n                         aAfterLoad : TwbAfterLoadCallback = nil;\n                         aAfterSet  : TwbAfterSetCallback = nil;\n                         aPriority  : TwbConflictPriority = cpNormal;\n                         aRequired  : Boolean = False;\n                         aDontShow  : TwbDontShowCallback = nil;\n                         aGetCP     : TwbGetConflictPriority = nil)\n                                    : IwbSubRecordDef; overload;\nbegin\n  Result := wbSubRecord(aSignature, aName, wbArrayPT('', aElement, aCount, aPriority), aAfterLoad, aAfterSet, aPriority, aRequired, False, aDontShow, aGetCP);\nend;\n\nfunction wbArrayPT(const aName      : string;\n                   const aElement   : IwbValueDef;\n                         aCount     : Integer = 0;\n                         aPriority  : TwbConflictPriority = cpNormal;\n                         aRequired  : Boolean = False;\n                         aDontShow  : TwbDontShowCallback = nil;\n                         aGetCP     : TwbGetConflictPriority = nil)\n                                    : IwbArrayDef; overload;\nbegin\n  Result := TwbArrayDef.Create(aPriority, aRequired, aName, aElement, aCount, [], False, nil, nil, aDontShow, aGetCP, True, True, False);\nend;\n\nfunction wbArrayPT(const aName      : string;\n                   const aElement   : IwbValueDef;\n                         aCount     : Integer;\n                         aAfterLoad : TwbAfterLoadCallback;\n                         aPriority  : TwbConflictPriority = cpNormal;\n                         aRequired  : Boolean = False;\n                         aDontShow  : TwbDontShowCallback = nil;\n                         aGetCP     : TwbGetConflictPriority = nil)\n                                    : IwbArrayDef; overload;\nbegin\n  Result := TwbArrayDef.Create(aPriority, aRequired, aName, aElement, aCount, [], False, aAfterLoad, nil, aDontShow, aGetCP, True, True, False);\nend;\n\nfunction wbArrayT(const aName      : string;\n                  const aElement   : IwbValueDef;\n                        aCount     : Integer;\n                  const aLabels    : array of string;\n                        aAfterLoad : TwbAfterLoadCallback;\n                        aPriority  : TwbConflictPriority = cpNormal;\n                        aRequired  : Boolean = False;\n                        aDontShow  : TwbDontShowCallback = nil;\n                        aGetCP     : TwbGetConflictPriority = nil)\n                                   : IwbArrayDef; overload;\nbegin\n  Result := TwbArrayDef.Create(aPriority, aRequired, aName, aElement, aCount, aLabels, False, aAfterLoad, nil, aDontShow, aGetCP, True, True, True);\nend;\n\nfunction wbRArray(const aName      : string;\n                  const aElement   : IwbRecordMemberDef;\n                        aPriority  : TwbConflictPriority = cpNormal;\n                        aRequired  : Boolean = False;\n                        aAfterLoad : TwbAfterLoadCallback = nil;\n                        aAfterSet  : TwbAfterSetCallback = nil;\n                        aDontShow  : TwbDontShowCallback = nil;\n                        aGetCP     : TwbGetConflictPriority = nil)\n                                   : IwbSubRecordArrayDef; overload;\nbegin\n  Result := TwbSubRecordArrayDef.Create(aPriority, aRequired, aName, aElement, False, aAfterLoad, aAfterSet, aDontShow, nil, aGetCP);\nend;\n\nfunction wbArray(const aSignature : TwbSignature;\n                 const aName      : string;\n                 const aElement   : IwbValueDef;\n                 const aLabels    : array of string;\n                       aPriority  : TwbConflictPriority = cpNormal;\n                       aRequired  : Boolean = False;\n                       aDontShow  : TwbDontShowCallback = nil;\n                       aGetCP     : TwbGetConflictPriority = nil)\n                                  : IwbSubRecordDef; overload;\nbegin\n  Result := wbSubRecord(aSignature, aName, wbArray('', aElement, aLabels, aPriority), nil, nil, aPriority, aRequired, False, aDontShow, aGetCP);\nend;\n\nfunction wbArray(const aSignature     : TwbSignature;\n                 const aName          : string;\n                 const aElement       : IwbValueDef;\n                 const aLabels        : array of string;\n                       aCountCallback : TwbCountCallback;\n                       aPriority      : TwbConflictPriority = cpNormal;\n                       aRequired      : Boolean = False;\n                       aDontShow      : TwbDontShowCallback = nil;\n                       aGetCP         : TwbGetConflictPriority = nil)\n                                      : IwbSubRecordDef; overload;\nbegin\n  Result := wbSubRecord(aSignature, aName, wbArray('', aElement, aLabels, aCountCallback, aPriority), nil, nil, aPriority, aRequired, False, aDontShow, aGetCP);\nend;\n\nfunction wbArray(const aName     : string;\n                 const aElement  : IwbValueDef;\n                 const aLabels   : array of string;\n                       aPriority : TwbConflictPriority = cpNormal;\n                       aRequired : Boolean = False;\n                       aDontShow : TwbDontShowCallback = nil;\n                       aGetCP    : TwbGetConflictPriority = nil)\n                                 : IwbArrayDef; overload;\nbegin\n  Result := TwbArrayDef.Create(aPriority, aRequired, aName, aElement, Length(aLabels), aLabels, False, nil, nil, aDontShow, aGetCP, True, False, False);\nend;\n\nfunction wbArray(const aName          : string;\n                 const aElement       : IwbValueDef;\n                 const aLabels        : array of string;\n                       aCountCallback : TwbCountCallback;\n                       aPriority      : TwbConflictPriority = cpNormal;\n                       aRequired      : Boolean = False;\n                       aDontShow      : TwbDontShowCallback = nil;\n                       aGetCP         : TwbGetConflictPriority = nil)\n                                      : IwbArrayDef; overload;\nbegin\n  Result := TwbArrayDef.Create(aPriority, aRequired, aName, aElement, aCountCallback, aLabels, False, nil, nil, aDontShow, aGetCP, True, False, False);\nend;\n\nfunction wbArray(const aName          : string;\n                 const aElement       : IwbValueDef;\n                       aCountCallback : TwbCountCallback;\n                       aPriority      : TwbConflictPriority = cpNormal;\n                       aRequired      : Boolean = False;\n                       aDontShow      : TwbDontShowCallback = nil;\n                       aGetCP         : TwbGetConflictPriority = nil)\n                                      : IwbArrayDef; overload;\nbegin\n  Result := TwbArrayDef.Create(aPriority, aRequired, aName, aElement, aCountCallback, [], False, nil, nil, aDontShow, aGetCP, True, False, False);\nend;\n\nfunction wbArrayPT(const aSignature : TwbSignature;\n                   const aName      : string;\n                   const aElement   : IwbValueDef;\n                   const aLabels    : array of string;\n                         aPriority  : TwbConflictPriority = cpNormal;\n                         aRequired  : Boolean = False;\n                         aDontShow  : TwbDontShowCallback = nil;\n                         aGetCP     : TwbGetConflictPriority = nil)\n                                    : IwbSubRecordDef; overload;\nbegin\n  Result := wbSubRecord(aSignature, aName, wbArrayPT('', aElement, aLabels, aPriority), nil, nil, aPriority, aRequired, False, aDontShow, aGetCP);\nend;\n\nfunction wbArrayPT(const aSignature     : TwbSignature;\n                   const aName          : string;\n                   const aElement       : IwbValueDef;\n                   const aLabels        : array of string;\n                         aCountCallback : TwbCountCallback;\n                         aPriority      : TwbConflictPriority = cpNormal;\n                         aRequired      : Boolean = False;\n                         aDontShow      : TwbDontShowCallback = nil;\n                         aGetCP         : TwbGetConflictPriority = nil)\n                                        : IwbSubRecordDef; overload;\nbegin\n  Result := wbSubRecord(aSignature, aName, wbArrayPT('', aElement, aLabels, aCountCallback, aPriority), nil, nil, aPriority, aRequired, False, aDontShow, aGetCP);\nend;\n\nfunction wbArrayPT(const aName     : string;\n                   const aElement  : IwbValueDef;\n                   const aLabels   : array of string;\n                         aPriority : TwbConflictPriority = cpNormal;\n                         aRequired : Boolean = False;\n                         aDontShow : TwbDontShowCallback = nil;\n                         aGetCP    : TwbGetConflictPriority = nil)\n                                   : IwbArrayDef; overload;\nbegin\n  Result := TwbArrayDef.Create(aPriority, aRequired, aName, aElement, Length(aLabels), aLabels, False, nil, nil, aDontShow, aGetCP, True, True, False);\nend;\n\nfunction wbArrayPT(const aName          : string;\n                   const aElement       : IwbValueDef;\n                   const aLabels        : array of string;\n                         aCountCallback : TwbCountCallback;\n                         aPriority      : TwbConflictPriority = cpNormal;\n                         aRequired      : Boolean = False;\n                         aDontShow      : TwbDontShowCallback = nil;\n                         aGetCP         : TwbGetConflictPriority = nil)\n                                        : IwbArrayDef; overload;\nbegin\n  Result := TwbArrayDef.Create(aPriority, aRequired, aName, aElement, aCountCallback, aLabels, False, nil, nil, aDontShow, aGetCP, True, True, False);\nend;\n\nfunction wbArrayT(const aName          : string;\n                  const aElement       : IwbValueDef;\n                  const aLabels        : array of string;\n                        aCountCallback : TwbCountCallback;\n                        aPriority      : TwbConflictPriority = cpNormal;\n                        aRequired      : Boolean = False;\n                        aDontShow      : TwbDontShowCallback = nil;\n                        aGetCP         : TwbGetConflictPriority = nil)\n                                       : IwbArrayDef; overload;\nbegin\n  Result := TwbArrayDef.Create(aPriority, aRequired, aName, aElement, aCountCallback, aLabels, False, nil, nil, aDontShow, aGetCP, True, True, True);\nend;\n\nfunction wbArrayPT(const aName          : string;\n                   const aElement       : IwbValueDef;\n                         aCountCallback : TwbCountCallback;\n                         aPriority      : TwbConflictPriority = cpNormal;\n                         aRequired      : Boolean = False;\n                         aDontShow      : TwbDontShowCallback = nil;\n                         aGetCP         : TwbGetConflictPriority = nil)\n                                        : IwbArrayDef; overload;\nbegin\n  Result := TwbArrayDef.Create(aPriority, aRequired, aName, aElement, aCountCallback, [], False, nil, nil, aDontShow, aGetCP, True, True, False);\nend;\n\n{--- wbArrayS - list of identical elements - gets sorted ----------------------}\nfunction wbArrayS(const aSignature : TwbSignature;\n                  const aName      : string;\n                  const aElement   : IwbValueDef;\n                        aCount     : Integer = 0;\n                        aPriority  : TwbConflictPriority = cpNormal;\n                        aRequired  : Boolean = False;\n                        aAfterLoad : TwbAfterLoadCallback = nil;\n                        aAfterSet  : TwbAfterSetCallback = nil;\n                        aDontShow  : TwbDontShowCallback = nil;\n                        aGetCP     : TwbGetConflictPriority = nil)\n                                   : IwbSubRecordDef; overload;\nbegin\n  Result := wbSubRecord(aSignature, aName, wbArrayS('', aElement, aCount, aPriority, False, aAfterLoad, aAfterSet), nil, nil, aPriority, aRequired, False, aDontShow, aGetCP);\nend;\n\nfunction wbArrayS(const aName      : string;\n                  const aElement   : IwbValueDef;\n                        aCount     : Integer = 0;\n                        aPriority  : TwbConflictPriority = cpNormal;\n                        aRequired  : Boolean = False;\n                        aAfterLoad : TwbAfterLoadCallback = nil;\n                        aAfterSet  : TwbAfterSetCallback = nil;\n                        aDontShow  : TwbDontShowCallback = nil;\n                        aCanAddTo  : Boolean = True;\n                        aGetCP     : TwbGetConflictPriority = nil)\n                                   : IwbArrayDef; overload;\nbegin\n  Result := TwbArrayDef.Create(aPriority, aRequired, aName, aElement, aCount, [], True, aAfterLoad, aAfterSet, aDontShow, aGetCP, aCanAddTo, False, False);\nend;\n\nfunction wbArrayS(const aName      : string;\n                  const aElement   : IwbValueDef;\n                        aCount     : Integer;\n                        aAfterLoad : TwbAfterLoadCallback;\n                        aPriority  : TwbConflictPriority = cpNormal;\n                        aRequired  : Boolean = False;\n                        aAfterSet  : TwbAfterSetCallback = nil;\n                        aDontShow  : TwbDontShowCallback = nil;\n                        aGetCP     : TwbGetConflictPriority = nil)\n                                   : IwbArrayDef; overload;\nbegin\n  Result := TwbArrayDef.Create(aPriority, aRequired, aName, aElement, aCount, [], True, aAfterLoad, aAfterSet, aDontShow, aGetCP, True, False, False);\nend;\n\nfunction wbArrayS(const aName          : string;\n                  const aElement       : IwbValueDef;\n                        aCountCallback : TwbCountCallback;\n                        aPriority      : TwbConflictPriority = cpNormal;\n                        aRequired      : Boolean = False;\n                        aAfterLoad     : TwbAfterLoadCallback = nil;\n                        aAfterSet      : TwbAfterSetCallback = nil;\n                        aDontShow      : TwbDontShowCallback = nil;\n                        aGetCP         : TwbGetConflictPriority = nil)\n                                       : IwbArrayDef; overload;\nbegin\n  Result := TwbArrayDef.Create(aPriority, aRequired, aName, aElement, aCountCallback, [], True, aAfterLoad, aAfterSet, aDontShow, aGetCP, True, False, False);\nend;\n\nfunction wbArray(const aName          : string;\n                 const aElement       : IwbValueDef;\n                       aCountCallback : TwbCountCallback;\n                       aPriority      : TwbConflictPriority;\n                       aRequired      : Boolean;\n                       aAfterLoad     : TwbAfterLoadCallback;\n                       aAfterSet      : TwbAfterSetCallback;\n                       aDontShow      : TwbDontShowCallback = nil;\n                       aGetCP         : TwbGetConflictPriority = nil)\n                                       : IwbArrayDef; overload;\nbegin\n  Result := TwbArrayDef.Create(aPriority, aRequired, aName, aElement, aCountCallback, [], False, aAfterLoad, aAfterSet, aDontShow, aGetCP, True, False, False);\nend;\n\nfunction wbRArrayS(const aName      : string;\n                   const aElement   : IwbRecordMemberDef;\n                         aPriority  : TwbConflictPriority = cpNormal;\n                         aRequired  : Boolean = False;\n                         aAfterLoad : TwbAfterLoadCallback = nil;\n                         aAfterSet  : TwbAfterSetCallback = nil;\n                         aDontShow  : TwbDontShowCallback = nil;\n                         aIsSorted  : TwbIsSortedCallback = nil;\n                         aGetCP     : TwbGetConflictPriority = nil)\n                                    : IwbSubRecordArrayDef; overload;\nbegin\n  Result := TwbSubRecordArrayDef.Create(aPriority, aRequired, aName, aElement, True, aAfterLoad, aAfterSet, aDontShow, aIsSorted, aGetCP);\nend;\n\nfunction wbArrayS(const aSignature : TwbSignature;\n                  const aName      : string;\n                  const aElement   : IwbValueDef;\n                  const aLabels    : array of string;\n                        aPriority  : TwbConflictPriority = cpNormal;\n                        aRequired  : Boolean = False;\n                        aAfterLoad : TwbAfterLoadCallback = nil;\n                        aAfterSet  : TwbAfterSetCallback = nil;\n                        aDontShow  : TwbDontShowCallback = nil;\n                        aGetCP     : TwbGetConflictPriority = nil)\n                                   : IwbSubRecordDef; overload;\nbegin\n  Result := wbSubRecord(aSignature, aName, wbArrayS('', aElement, aLabels, aPriority, False, aAfterLoad), nil, nil, aPriority, aRequired, False, aDontShow, aGetCP);\nend;\n\nfunction wbArrayS(const aName      : string;\n                  const aElement   : IwbValueDef;\n                  const aLabels    : array of string;\n                        aPriority  : TwbConflictPriority = cpNormal;\n                        aRequired  : Boolean = False;\n                        aAfterLoad : TwbAfterLoadCallback = nil;\n                        aAfterSet  : TwbAfterSetCallback = nil;\n                        aDontShow  : TwbDontShowCallback = nil;\n                        aGetCP     : TwbGetConflictPriority = nil)\n                                   : IwbArrayDef; overload;\nbegin\n  Result := TwbArrayDef.Create(aPriority, aRequired, aName, aElement, Length(aLabels), aLabels, True, aAfterLoad, aAfterSet, aDontShow, aGetCP, True, False, False);\nend;\n\n{--- wbStruct - ordered list of members ----------------------------------------}\nfunction wbStructSK(const aSignature           : TwbSignature;\n                    const aSortKey             : array of Integer;\n                    const aName                : string;\n                    const aMembers             : array of IwbValueDef;\n                          aPriority            : TwbConflictPriority = cpNormal;\n                          aRequired            : Boolean = False;\n                          aDontShow            : TwbDontShowCallback = nil;\n                          aOptionalFromElement : Integer = -1;\n                          aAfterLoad           : TwbAfterLoadCallback = nil;\n                          aAfterSet            : TwbAfterSetCallback = nil;\n                          aGetCP               : TwbGetConflictPriority = nil)\n                                               : IwbSubRecordDef; overload;\nbegin\n  Result := wbSubRecord(aSignature, aName, wbStructSK(aSortKey, '', aMembers, aPriority, False, nil, aOptionalFromElement), aAfterLoad, aAfterSet, aPriority, aRequired, False, aDontShow, aGetCP);\nend;\n\nfunction wbMultiStructSK(const aSignatures          : array of TwbSignature;\n                         const aSortKey             : array of Integer;\n                         const aName                : string;\n                         const aMembers             : array of IwbValueDef;\n                               aPriority            : TwbConflictPriority = cpNormal;\n                               aRequired            : Boolean = False;\n                               aDontShow            : TwbDontShowCallback = nil;\n                               aOptionalFromElement : Integer = -1;\n                               aAfterLoad           : TwbAfterLoadCallback = nil;\n                               aAfterSet            : TwbAfterSetCallback = nil;\n                               aGetCP               : TwbGetConflictPriority = nil)\n                                                    : IwbSubRecordDef;\nbegin\n  Result := wbSubRecord(aSignatures, aName, wbStructSK(aSortKey, '', aMembers, aPriority, False, nil, aOptionalFromElement), aAfterLoad, aAfterSet, aPriority, aRequired, False, aDontShow, aGetCP);\nend;\n\nfunction wbStructSK(const aSortKey             : array of Integer;\n                    const aName                : string;\n                    const aMembers             : array of IwbValueDef;\n                          aPriority            : TwbConflictPriority = cpNormal;\n                          aRequired            : Boolean = False;\n                          aDontShow            : TwbDontShowCallback = nil;\n                          aOptionalFromElement : Integer = -1;\n                          aAfterLoad           : TwbAfterLoadCallback = nil;\n                          aAfterSet            : TwbAfterSetCallback = nil;\n                          aGetCP               : TwbGetConflictPriority = nil)\n                                               : IwbStructDef; overload;\nbegin\n  Result := TwbStructDef.Create(aPriority, aRequired, aName, aMembers, aSortKey, [], [], aOptionalFromElement, aDontShow, aAfterLoad, aAfterSet, aGetCP);\nend;\n\nfunction wbStructSK(const aSortKey             : array of Integer;\n                    const aName                : string;\n                    const aMembers             : array of IwbValueDef;\n                    {$IFDEF WIN32}\n                    const aElementMap          : array of Cardinal;\n                    {$ENDIF WIN32}\n                    {$IFDEF WIN64}\n                    const aElementMap          : array of UInt64;\n                    {$ENDIF WIN64}\n                          aPriority            : TwbConflictPriority = cpNormal;\n                          aRequired            : Boolean = False;\n                          aDontShow            : TwbDontShowCallback = nil;\n                          aOptionalFromElement : Integer = -1;\n                          aAfterLoad           : TwbAfterLoadCallback = nil;\n                          aAfterSet            : TwbAfterSetCallback = nil;\n                          aGetCP               : TwbGetConflictPriority = nil)\n                                               : IwbStructDef; overload;\nbegin\n  Result := TwbStructDef.Create(aPriority, aRequired, aName, aMembers, aSortKey, [], aElementMap, aOptionalFromElement, aDontShow, aAfterLoad, aAfterSet, aGetCP);\nend;\n\n\nfunction wbStructExSK(const aSignature           : TwbSignature;\n                      const aSortKey             : array of Integer;\n                      const aExSortKey           : array of Integer;\n                      const aName                : string;\n                      const aMembers             : array of IwbValueDef;\n                            aPriority            : TwbConflictPriority = cpNormal;\n                            aRequired            : Boolean = False;\n                            aDontShow            : TwbDontShowCallback = nil;\n                            aOptionalFromElement : Integer = -1;\n                            aAfterLoad           : TwbAfterLoadCallback = nil;\n                            aAfterSet            : TwbAfterSetCallback = nil;\n                            aGetCP               : TwbGetConflictPriority = nil)\n                                                 : IwbSubRecordDef; overload;\nbegin\n  Result := wbSubRecord(aSignature, aName, wbStructExSK(aSortKey, aExSortKey, '', aMembers, aPriority, False, nil, aOptionalFromElement), aAfterLoad, aAfterSet, aPriority, aRequired, False, aDontShow, aGetCP);\nend;\n\nfunction wbStructExSK(const aSortKey             : array of Integer;\n                      const aExSortKey           : array of Integer;\n                      const aName                : string;\n                      const aMembers             : array of IwbValueDef;\n                            aPriority            : TwbConflictPriority = cpNormal;\n                            aRequired            : Boolean = False;\n                            aDontShow            : TwbDontShowCallback = nil;\n                            aOptionalFromElement : Integer = -1;\n                            aAfterLoad           : TwbAfterLoadCallback = nil;\n                            aAfterSet            : TwbAfterSetCallback = nil;\n                            aGetCP               : TwbGetConflictPriority = nil)\n                                                 : IwbStructDef; overload;\nbegin\n  Result := TwbStructDef.Create(aPriority, aRequired, aName, aMembers, aSortKey, aExSortKey, [], aOptionalFromElement, aDontShow, aAfterLoad, aAfterSet, aGetCP);\nend;\n\nfunction wbStruct(const aSignature           : TwbSignature;\n                  const aName                : string;\n                  const aMembers             : array of IwbValueDef;\n                        aPriority            : TwbConflictPriority = cpNormal;\n                        aRequired            : Boolean = False;\n                        aDontShow            : TwbDontShowCallback = nil;\n                        aOptionalFromElement : Integer = -1;\n                        aAfterLoad           : TwbAfterLoadCallback = nil;\n                        aAfterSet            : TwbAfterSetCallback = nil;\n                        aGetCP               : TwbGetConflictPriority = nil)\n                                             : IwbSubRecordDef; overload;\nbegin\n  Result := wbSubRecord(aSignature, aName, wbStruct('', aMembers, aPriority, False, nil, aOptionalFromElement), aAfterLoad, aAfterSet, aPriority, aRequired, False, aDontShow, aGetCP);\nend;\n\nfunction wbStruct(const aName                : string;\n                  const aMembers             : array of IwbValueDef;\n                        aPriority            : TwbConflictPriority = cpNormal;\n                        aRequired            : Boolean = False;\n                        aDontShow            : TwbDontShowCallback = nil;\n                        aOptionalFromElement : Integer = -1;\n                        aAfterLoad           : TwbAfterLoadCallback = nil;\n                        aAfterSet            : TwbAfterSetCallback = nil;\n                        aGetCP               : TwbGetConflictPriority = nil)\n                                             : IwbStructDef; overload;\nbegin\n  Result := TwbStructDef.Create(aPriority, aRequired, aName, aMembers, [], [], [], aOptionalFromElement, aDontShow, aAfterLoad, aAfterSet, aGetCP);\nend;\n\nfunction wbStructC(const aName                : string;\n                         aSizing              : TwbSizeCallback;\n                         aGetChapterType      : TwbGetChapterTypeCallback;\n                         aGetChapterTypeName  : TwbGetChapterTypeNameCallback;\n                         aGetChapterName      : TwbGetChapterNameCallback;\n                   const aMembers             : array of IwbValueDef;\n                         aPriority            : TwbConflictPriority = cpNormal;\n                         aRequired            : Boolean = False;\n                         aDontShow            : TwbDontShowCallback = nil;\n                         aOptionalFromElement : Integer = -1;\n                         aAfterLoad           : TwbAfterLoadCallback = nil;\n                         aAfterSet            : TwbAfterSetCallback = nil;\n                         aGetCP               : TwbGetConflictPriority = nil)\n                                              : IwbStructDef; overload;\nbegin\n  Result := TwbStructCDef.Create(aPriority, aRequired, aName, aMembers, [], [], aOptionalFromElement, aDontShow, aAfterLoad, aAfterSet, aSizing, aGetChapterType, aGetChapterTypeName, aGetChapterName, aGetCP);\nend;\n\nfunction wbStructZ(const aName                : string;\n                         aSizing              : TwbSizeCallback;\n                         aGetChapterType      : TwbGetChapterTypeCallback;\n                         aGetChapterTypeName  : TwbGetChapterTypeNameCallback;\n                         aGetChapterName      : TwbGetChapterNameCallback;\n                   const aMembers             : array of IwbValueDef;\n                         aPriority            : TwbConflictPriority = cpNormal;\n                         aRequired            : Boolean = False;\n                         aDontShow            : TwbDontShowCallback = nil;\n                         aOptionalFromElement : Integer = -1;\n                         aAfterLoad           : TwbAfterLoadCallback = nil;\n                         aAfterSet            : TwbAfterSetCallback = nil;\n                         aGetCP               : TwbGetConflictPriority = nil)\n                                              : IwbStructDef; overload;\nbegin\n  Result := TwbStructZDef.Create(aPriority, aRequired, aName, aMembers, [], [], aOptionalFromElement, aDontShow, aAfterLoad, aAfterSet, aSizing, aGetChapterType, aGetChapterTypeName, agetChapterName, aGetCP);\nend;\n\nfunction wbStructLZ(const aName                : string;\n                          aSizing              : TwbSizeCallback;\n                          aGetChapterType      : TwbGetChapterTypeCallback;\n                          aGetChapterTypeName  : TwbGetChapterTypeNameCallback;\n                          aGetChapterName      : TwbGetChapterNameCallback;\n                    const aMembers             : array of IwbValueDef;\n                          aPriority            : TwbConflictPriority = cpNormal;\n                          aRequired            : Boolean = False;\n                          aDontShow            : TwbDontShowCallback = nil;\n                          aOptionalFromElement : Integer = -1;\n                          aAfterLoad           : TwbAfterLoadCallback = nil;\n                          aAfterSet            : TwbAfterSetCallback = nil;\n                          aGetCP               : TwbGetConflictPriority = nil)\n                                               : IwbStructDef; overload;\nbegin\n  Result := TwbStructLZDef.Create(aPriority, aRequired, aName, aMembers, [], [], aOptionalFromElement, aDontShow, aAfterLoad, aAfterSet, aSizing, aGetChapterType, aGetChapterTypeName, agetChapterName, aGetCP);\nend;\n\nfunction wbRStruct(const aName           : string;\n                   const aMembers        : array of IwbRecordMemberDef;\n                   const aSkipSigs       : array of TwbSignature;\n                         aPriority       : TwbConflictPriority = cpNormal;\n                         aRequired       : Boolean = False;\n                         aDontShow       : TwbDontShowCallback = nil;\n                         aAllowUnordered : Boolean = False;\n                         aAfterLoad      : TwbAfterLoadCallback = nil;\n                         aAfterSet       : TwbAfterSetCallback = nil;\n                         aGetCP          : TwbGetConflictPriority = nil)\n                                         : IwbSubRecordStructDef; overload;\nbegin\n  Result := TwbSubRecordStructDef.Create(aPriority, aRequired, aName, aMembers, aSkipSigs, aDontShow, aAllowUnordered, aAfterLoad, aAfterSet, aGetCP);\nend;\n\nfunction wbRStructSK(const aSortKey        : array of Integer;\n                     const aName           : string;\n                     const aMembers        : array of IwbRecordMemberDef;\n                     const aSkipSigs       : array of TwbSignature;\n                           aPriority       : TwbConflictPriority = cpNormal;\n                           aRequired       : Boolean = False;\n                           aDontShow       : TwbDontShowCallback = nil;\n                           aAllowUnordered : Boolean = False;\n                           aAfterLoad      : TwbAfterLoadCallback = nil;\n                           aAfterSet       : TwbAfterSetCallback = nil;\n                           aGetCP          : TwbGetConflictPriority = nil)\n                                           : IwbSubRecordStructDef; overload;\nbegin\n  Result := TwbSubRecordStructSKDef.Create(aPriority, aRequired, aName, aMembers, aSkipSigs, aSortKey, [], aDontShow, aAllowUnordered, aAfterLoad, aAfterSet, aGetCP);\nend;\n\nfunction wbRStructExSK(const aSortKey        : array of Integer;\n                       const aExSortKey      : array of Integer;\n                       const aName           : string;\n                       const aMembers        : array of IwbRecordMemberDef;\n                       const aSkipSigs       : array of TwbSignature;\n                             aPriority       : TwbConflictPriority = cpNormal;\n                             aRequired       : Boolean = False;\n                             aDontShow       : TwbDontShowCallback = nil;\n                             aAllowUnordered : Boolean = False;\n                             aAfterLoad      : TwbAfterLoadCallback = nil;\n                             aAfterSet       : TwbAfterSetCallback = nil;\n                             aGetCP          : TwbGetConflictPriority = nil)\n                                             : IwbSubRecordStructDef; overload;\nbegin\n  Result := TwbSubRecordStructSKDef.Create(aPriority, aRequired, aName, aMembers, aSkipSigs, aSortKey, aExSortKey, aDontShow, aAllowUnordered, aAfterLoad, aAfterSet, aGetCP);\nend;\n\nfunction wbRUnion(const aName     : string;\n                  const aMembers  : array of IwbRecordMemberDef;\n                  const aSkipSigs : array of TwbSignature;\n                        aPriority : TwbConflictPriority = cpNormal;\n                        aRequired : Boolean = False;\n                        aDontShow : TwbDontShowCallback = nil;\n                        aGetCP    : TwbGetConflictPriority = nil)\n                                  : IwbSubRecordUnionDef; overload;\nbegin\n  Result := TwbSubRecordUnionDef.Create(aPriority, aRequired, aName, aMembers, aSkipSigs, aDontShow, aGetCP);\nend;\n\n{--- wbStructS - array of struct ----------------------------------------------}\nfunction wbStructS(const aSignature   : TwbSignature;\n                   const aName        : string;\n                   const aElementName : string;\n                   const aMembers     : array of IwbValueDef;\n                         aPriority    : TwbConflictPriority = cpNormal;\n                         aRequired    : Boolean = False;\n                         aDontShow    : TwbDontShowCallback = nil;\n                         aGetCP       : TwbGetConflictPriority = nil)\n                                      : IwbSubRecordDef; overload;\nbegin\n  Result := wbArray(aSignature, aName, wbStruct(aElementName, aMembers, aPriority), 0, nil, nil, aPriority, aRequired, aDontShow, aGetCP);\nend;\n\nfunction wbStructS(const aName        : string;\n                   const aElementName : string;\n                   const aMembers     : array of IwbValueDef;\n                         aPriority    : TwbConflictPriority = cpNormal;\n                         aRequired    : Boolean = False;\n                         aDontShow    : TwbDontShowCallback = nil;\n                         aGetCP       : TwbGetConflictPriority = nil)\n                                      : IwbArrayDef; overload;\nbegin\n  Result := wbArray(aName, wbStruct(aElementName, aMembers, aPriority), 0, aPriority, aRequired, aDontShow, aGetCP);\nend;\n\nfunction wbRStructS(const aName        : string;\n                    const aElementName : string;\n                    const aMembers     : array of IwbRecordMemberDef;\n                    const aSkipSigs    : array of TwbSignature;\n                          aPriority    : TwbConflictPriority = cpNormal;\n                          aRequired    : Boolean = False;\n                          aDontShow    : TwbDontShowCallback = nil;\n                          aGetCP       : TwbGetConflictPriority = nil)\n                                       : IwbSubRecordArrayDef; overload;\nbegin\n  Result := wbRArray(aName, wbRStruct(aElementName, aMembers, aSkipSigs ,aPriority), aPriority, aRequired, nil, nil, aDontShow, aGetCP);\nend;\n\nfunction wbRStructsSK(const aName        : string;\n                      const aElementName : string;\n                      const aSortKey     : array of Integer;\n                      const aMembers     : array of IwbRecordMemberDef;\n                      const aSkipSigs    : array of TwbSignature;\n                            aPriority    : TwbConflictPriority = cpNormal;\n                            aRequired    : Boolean = False;\n                            aAfterLoad   : TwbAfterLoadCallback = nil;\n                            aAfterSet    : TwbAfterSetCallback = nil;\n                            aDontShow    : TwbDontShowCallback = nil;\n                            aGetCP       : TwbGetConflictPriority = nil)\n                                         : IwbSubRecordArrayDef; overload;\nbegin\n  Result := wbRArrayS(aName, wbRStructSK(aSortKey, aElementName, aMembers, aSkipSigs, aPriority), aPriority, aRequired, aAfterLoad, aAfterSet, aDontShow, nil, aGetCP);\nend;\n\nfunction wbEmpty(const aSignature : TwbSignature;\n                 const aName      : string;\n                       aPriority  : TwbConflictPriority = cpNormal;\n                       aRequired  : Boolean = False;\n                       aDontShow  : TwbDontShowCallback = nil;\n                       aGetCP     : TwbGetConflictPriority = nil)\n                                  : IwbSubRecordDef;\nbegin\n  Result := wbSubRecord(aSignature, aName, wbEmpty('', aPriority, aRequired), nil, nil, aPriority, aRequired, False, aDontShow, aGetCP);\nend;\n\nfunction wbEmpty(const aName      : string;\n                       aPriority  : TwbConflictPriority = cpNormal;\n                       aRequired  : Boolean = False;\n                       aDontShow  : TwbDontShowCallback = nil;\n                       aSorted    : Boolean = False;\n                       aGetCP     : TwbGetConflictPriority = nil)\n                                  : IwbValueDef;\nbegin\n  Result := TwbEmptyDef.Create(aPriority, aRequired, aName, nil, nil, aDontShow, aSorted, aGetCP);\nend;\n\nfunction wbDumpInteger : IwbIntegerDefFormater;\nbegin\n  Result := TwbDumpIntegerDefFormater.Create(cpNormal, False, nil);\nend;\n\nfunction wbKey2Data6Enum(const aNames : array of string) : IwbKey2Data6EnumDef;\nbegin\n  Result := TwbKey2Data6EnumDef.Create(aNames, []);\nend;\n\nfunction wbData6Key2Enum(const aNames : array of string) : IwbData6Key2EnumDef;\nbegin\n  Result := TwbData6Key2EnumDef.Create(aNames, []);\nend;\n\nvar\n  _RefID: IwbRefID;\n\nfunction wbRefID: IwbRefID;\nbegin\n  if wbReportMode then\n    Result := TwbRefID.Create(cpNormal, False, nil)\n  else begin\n    if not Assigned(_RefID) then\n      _RefID := TwbRefID.Create(cpNormal, False, nil);\n    Result := _RefID;\n  end;\nend;\n\nfunction wbRefID(const aName     : string;\n                       aPriority : TwbConflictPriority = cpNormal;\n                       aRequired : Boolean = False;\n                       aDontShow : TwbDontShowCallback = nil;\n                       aAfterSet : TwbAfterSetCallback = nil;\n                       aGetCP    : TwbGetConflictPriority = nil)\n                                 : IwbIntegerDef; overload;\nbegin\n  Result := wbInteger(aName, itU24, wbRefID, aPriority, aRequired, aDontShow, aAfterSet, 0, aGetCP);\nend;\n\nfunction wbRefIDT(const aName     : string;\n                        aPriority : TwbConflictPriority = cpNormal;\n                        aRequired : Boolean = False;\n                        aDontShow : TwbDontShowCallback = nil;\n                        aAfterSet : TwbAfterSetCallback = nil;\n                        aGetCP    : TwbGetConflictPriority = nil)\n                                  : IwbIntegerDef; overload;\nbegin\n  Result := wbIntegerT(aName, itU24, wbRefID, aPriority, aRequired, aDontShow, aAfterSet, 0, aGetCP);\nend;\n\nvar\n  _FormID: IwbFormID;\n\nfunction wbFormID: IwbFormID;\nbegin\n  if wbReportMode then\n    Result := TwbFormID.Create(cpNormal, False, nil)\n  else begin\n    if not Assigned(_FormID) then\n      _FormID := TwbFormID.Create(cpNormal, False, nil);\n    Result := _FormID;\n  end;\nend;\n\nfunction wbFormID(const aValidRefs : array of TwbSignature;\n                        aPersistent: Boolean)\n                                   : IwbFormID;\nbegin\n  Result := TwbFormIDChecked.Create(aValidRefs, [], aPersistent);\nend;\n\nfunction wbFormID(const aValidRefs     : array of TwbSignature;\n                  const aValidFlstRefs : array of TwbSignature;\n                        aPersistent    : Boolean)\n                                       : IwbFormID;\nbegin\n  Result := TwbFormIDChecked.Create(aValidRefs, aValidFlstRefs, aPersistent);\nend;\n\nfunction wbFormIDNoReach(const aValidRefs : array of TwbSignature;\n                               aPersistent: Boolean)\n                                          : IwbFormID;\nbegin\n  Result := TwbFormIDChecked.Create(aValidRefs, [], aPersistent, True);\nend;\n\nfunction wbFormIDNoReach(const aValidRefs     : array of TwbSignature;\n                         const aValidFlstRefs : array of TwbSignature;\n                               aPersistent    : Boolean)\n                                              : IwbFormID;\nbegin\n  Result := TwbFormIDChecked.Create(aValidRefs, aValidFlstRefs, aPersistent, True);\nend;\n\n\nfunction wbChar4: IwbChar4;\nbegin\n  Result := TwbChar4.Create(cpNormal, False, nil);\nend;\n\nfunction wbStr4: IwbStr4;\nbegin\n  Result := TwbStr4.Create(cpNormal, False, nil);\nend;\n\nfunction wbFormID(const aSignature : TwbSignature;\n                  const aName      : string = 'Unknown';\n                        aPriority  : TwbConflictPriority = cpNormal;\n                        aRequired  : Boolean = False;\n                        aDontShow  : TwbDontShowCallback = nil;\n                        aGetCP     : TwbGetConflictPriority = nil)\n                                   : IwbSubRecordDef; overload;\nbegin\n  Result := wbInteger(\n              aSignature,\n              aName,\n              itU32,\n              wbFormID,\n              aPriority,\n              aRequired,\n              False,\n              aDontShow,\n              nil,\n              0,\n              aGetCP);\nend;\n\nfunction wbFormID(const aName     : string;\n                        aPriority : TwbConflictPriority = cpNormal;\n                        aRequired : Boolean = False;\n                        aDontShow : TwbDontShowCallback = nil;\n                        aAfterSet : TwbAfterSetCallback = nil)\n                                  : IwbIntegerDef; overload;\nbegin\n  Result := wbInteger(aName, itU32, wbFormID, aPriority, aRequired, aDontShow, aAfterSet);\nend;\n\nfunction wbFormIDT(const aName     : string;\n                         aPriority : TwbConflictPriority = cpNormal;\n                         aRequired : Boolean = False;\n                         aDontShow : TwbDontShowCallback = nil;\n                         aAfterSet : TwbAfterSetCallback = nil;\n                         aGetCP    : TwbGetConflictPriority = nil)\n                                   : IwbIntegerDef; overload;\nbegin\n  Result := wbIntegerT(aName, itU32, wbFormID, aPriority, aRequired, aDontShow, aAfterSet, 0, aGetCP);\nend;\n\nfunction wbFormIDCk(const aSignature : TwbSignature;\n                    const aName      : string;\n                    const aValidRefs : array of TwbSignature;\n                          aPersistent: Boolean = False;\n                          aPriority  : TwbConflictPriority = cpNormal;\n                          aRequired  : Boolean = False;\n                          aDontShow  : TwbDontShowCallback = nil;\n                          aGetCP     : TwbGetConflictPriority = nil)\n                                     : IwbSubRecordDef; overload;\nbegin\n  Result := wbInteger(aSignature, aName, itU32, wbFormID(aValidRefs, aPersistent), aPriority, aRequired, False, aDontShow, nil, 0, aGetCP);\nend;\n\nfunction wbFormIDCkNoReach(const aSignature : TwbSignature;\n                           const aName      : string;\n                           const aValidRefs : array of TwbSignature;\n                                 aPersistent: Boolean = False;\n                                 aPriority  : TwbConflictPriority = cpNormal;\n                                 aRequired  : Boolean = False;\n                                 aDontShow  : TwbDontShowCallback = nil;\n                                 aGetCP     : TwbGetConflictPriority = nil)\n                                            : IwbSubRecordDef; overload;\nbegin\n  Result := wbInteger(aSignature, aName, itU32, wbFormIDNoReach(aValidRefs, aPersistent), aPriority, aRequired, False, aDontShow, nil, 0, aGetCP);\nend;\n\nfunction wbFormIDCk(const aName      : string;\n                    const aValidRefs : array of TwbSignature;\n                          aPersistent: Boolean = False;\n                          aPriority  : TwbConflictPriority = cpNormal;\n                          aRequired  : Boolean = False;\n                          aDontShow  : TwbDontShowCallback = nil;\n                          aAfterSet  : TwbAfterSetCallback = nil)\n                                     : IwbIntegerDef; overload;\nbegin\n  Result := wbInteger(aName, itU32, wbFormID(aValidRefs, aPersistent), aPriority, aRequired, aDontShow, aAfterSet);\nend;\n\nfunction wbFormIDCkNoReach(const aName      : string;\n                           const aValidRefs : array of TwbSignature;\n                                 aPersistent: Boolean = False;\n                                 aPriority  : TwbConflictPriority = cpNormal;\n                                 aRequired  : Boolean = False;\n                                 aDontShow  : TwbDontShowCallback = nil;\n                                 aGetCP     : TwbGetConflictPriority = nil)\n                                            : IwbIntegerDef; overload;\nbegin\n  Result := wbInteger(aName, itU32, wbFormIDNoReach(aValidRefs, aPersistent), aPriority, aRequired, aDontShow, nil, 0, aGetCP);\nend;\n\n\nfunction wbFormIDCk(const aSignature     : TwbSignature;\n                    const aName          : string;\n                    const aValidRefs     : array of TwbSignature;\n                    const aValidFlstRefs : array of TwbSignature;\n                          aPersistent    : Boolean = False;\n                          aPriority      : TwbConflictPriority = cpNormal;\n                          aRequired      : Boolean = False;\n                          aDontShow      : TwbDontShowCallback = nil;\n                          aGetCP         : TwbGetConflictPriority = nil)\n                                         : IwbSubRecordDef; overload;\nbegin\n  Result := wbInteger(aSignature, aName, itU32, wbFormID(aValidRefs, aValidFlstRefs, aPersistent), aPriority, aRequired, False, aDontShow, nil, 0, aGetCP);\nend;\n\nfunction wbFormIDCk(const aName          : string;\n                    const aValidRefs     : array of TwbSignature;\n                    const aValidFlstRefs : array of TwbSignature;\n                          aPersistent    : Boolean = False;\n                          aPriority      : TwbConflictPriority = cpNormal;\n                          aRequired      : Boolean = False;\n                          aDontShow      : TwbDontShowCallback = nil;\n                          aGetCP         : TwbGetConflictPriority = nil)\n                                         : IwbIntegerDef; overload;\nbegin\n  Result := wbInteger(aName, itU32, wbFormID(aValidRefs, aValidFlstRefs, aPersistent), aPriority, aRequired, aDontShow, nil, 0, aGetCP);\nend;\n\nfunction wbFormIDCkNoReach(const aName          : string;\n                           const aValidRefs     : array of TwbSignature;\n                           const aValidFlstRefs : array of TwbSignature;\n                                 aPersistent    : Boolean = False;\n                                 aPriority      : TwbConflictPriority = cpNormal;\n                                 aRequired      : Boolean = False;\n                                 aDontShow      : TwbDontShowCallback = nil;\n                                 aGetCP         : TwbGetConflictPriority = nil)\n                                                : IwbIntegerDef; overload;\nbegin\n  Result := wbInteger(aName, itU32, wbFormIDNoReach(aValidRefs, aValidFlstRefs, aPersistent), aPriority, aRequired, aDontShow, nil, 0, aGetCP);\nend;\n\n\nfunction wbFlags(const aNames           : array of string;\n                       aUnknownIsUnused : Boolean = False)\n                                        : IwbFlagsDef;\nbegin\n  Result := wbFlags(nil, aNames, aUnknownIsUnused);\nend;\n\nfunction wbFlags(const aNames           : array of string;\n                 const aFlagsToIgnore   : array of integer)\n                                        : IwbFlagsDef; overload;\nbegin\n  Result := wbFlags(nil, aNames, aFlagsToIgnore);\nend;\n\n\nfunction wbFlags(const aNames           : array of string;\n                 const aDontShows       : array of TwbDontShowCallback;\n                       aUnknownIsUnused : Boolean = False)\n                                        : IwbFlagsDef; overload;\nbegin\n  Result := wbFlags(nil, aNames, aDontShows, aUnknownIsUnused);\nend;\n\nfunction wbFlags(const aBaseFlagsDef    : IwbFlagsDef;\n                 const aNames           : array of string;\n                       aUnknownIsUnused : Boolean = False)\n                                        : IwbFlagsDef;\nbegin\n  Result := TwbFlagsDef.Create(aBaseFlagsDef, aNames, [], aUnknownIsUnused, 0, []);\nend;\n\nfunction wbFlags(const aBaseFlagsDef    : IwbFlagsDef;\n                 const aNames           : array of string;\n                 const aFlagsToIgnore   : array of integer)\n                                        : IwbFlagsDef; overload;\nvar\n  IgnoreMask : Int64;\n  i          : Integer;\n  Index      : Int64;\nbegin\n  IgnoreMask := 0;\n  for i := Low(aFlagsToIgnore) to High(aFlagsToIgnore) do begin\n    Index := aFlagsToIgnore[i];\n    if (Index >= 0) and (Index <= High(aNames)) then\n      IgnoreMask := IgnoreMask or (1 shl Index);\n  end;\n  Result := TwbFlagsDef.Create(aBaseFlagsDef, aNames, [], False, IgnoreMask, []);\nend;\n\n\nfunction wbFlags(const aBaseFlagsDef    : IwbFlagsDef;\n                 const aNames           : array of string;\n                 const aDontShows       : array of TwbDontShowCallback;\n                       aUnknownIsUnused : Boolean = False)\n                                        : IwbFlagsDef; overload;\nbegin\n  Result := TwbFlagsDef.Create(aBaseFlagsDef, aNames, aDontShows, aUnknownIsUnused, 0, []);\nend;\n\nfunction wbEnum(const aNames : array of string)\n                              : IwbEnumDef;\nbegin\n  Result := TwbEnumDef.Create(aNames, []);\nend;\n\nfunction wbEnum(const aNames       : array of string;\n                const aSparseNames : array of const)\n                                   : IwbEnumDef; overload;\nbegin\n  Result := TwbEnumDef.Create(aNames, aSparseNames);\nend;\n\n\nfunction wbDiv(aValue : Integer)\n                      : IwbIntegerDefFormater;\nbegin\n  Result := TwbDivDef.Create(aValue);\nend;\n\nfunction wbMul(aValue : Integer)\n                      : IwbIntegerDefFormater;\nbegin\n  Result := TwbMulDef.Create(aValue);\nend;\n\nfunction wbCallback(const aToStr : TwbIntToStrCallback;\n                    const aToInt : TwbStrToIntCallback)\n                                 : IwbIntegerDefFormater;\nbegin\n  Result := TwbCallbackDef.Create(aToStr, aToInt);\nend;\n\nfunction wbFormaterUnion(aDecider : TwbIntegerDefFormaterUnionDecider;\n                         aMembers : array of IwbIntegerDefFormater)\n                                  : IwbIntegerDefFormaterUnion;\nbegin\n  Result := TwbIntegerDefFormaterUnion.Create(cpNormal, False, nil, aDecider, aMembers);\nend;\n\n{ TwbDef }\n\nfunction TwbDef.Assign(const aTarget : IwbElement;\n                             aIndex  : Integer;\n                       const aSource : IwbElement;\n                             aOnlySK : Boolean)\n                                     : IwbElement;\nbegin\n  Result := nil;\n  aTarget.SetEditValue(aSource.EditValue);\nend;\n\nfunction TwbDef.CanAssign(const aElement: IwbElement; aIndex: Integer; const aDef: IwbDef): Boolean;\nbegin\n  Result := False;\nend;\n\nfunction TwbDef.CanContainFormIDs: Boolean;\nbegin\n  Result := True;\nend;\n\nconstructor TwbDef.Clone(const aSource: TwbDef);\nbegin\n  with aSource do\n    Self.Create(defPriority, defRequired, defGetCP).defSource := aSource;\nend;\n\nconstructor TwbDef.Create(aPriority: TwbConflictPriority; aRequired: Boolean; aGetCP: TwbGetConflictPriority);\nbegin\n  defPriority := aPriority;\n  defRequired := aRequired;\n  defGetCP := aGetCP;\n  inherited Create;\nend;\n\nfunction TwbDef.Duplicate: TwbDef;\nbegin\n  Result := TwbDefClass(ClassType).Clone(Self);\nend;\n\nfunction TwbDef.Equals(const aDef: IwbDef): Boolean;\nbegin\n  Result := Assigned(aDef) and (aDef.DefID = GetDefID);\nend;\n\nfunction TwbDef.GetConflictPriority(const aElement: IwbElement): TwbConflictPriority;\nbegin\n  Result := defPriority;\n  if Assigned(defGetCP) then\n    defGetCP(aElement, Result);\nend;\n\nfunction TwbDef.GetConflictPriorityCanChange: Boolean;\nbegin\n  Result := Assigned(defGetCP);\nend;\n\nfunction TwbDef.GetDefID: Cardinal;\nbegin\n  Result := Cardinal(Self);\nend;\n\nfunction TwbDef.GetDontShow(const aElement: IwbElement): Boolean;\nbegin\n  Result := False;\nend;\n\nfunction TwbDef.GetHasDontShow: Boolean;\nbegin\n  Result := False;\nend;\n\nfunction TwbDef.GetNoReach: Boolean;\nbegin\n  Result := False;\nend;\n\nfunction TwbDef.GetParent: IwbDef;\nbegin\n  Result := defParent;\nend;\n\nfunction TwbDef.GetRequired: Boolean;\nbegin\n  Result := defRequired;\nend;\n\nfunction TwbDef.GetRoot: IwbDef;\nbegin\n  Result := defSource;\n  if not Assigned(Result) then\n    Result := Self\n  else\n    Result := Result.GetRoot;\nend;\n\nfunction TwbDef.IsNotRequired: Boolean;\nbegin\n  Result := defNotRequired;\nend;\n\nprocedure TwbDef.NotRequired;\nbegin\n  defNotRequired := True;\nend;\n\nprocedure TwbDef.ParentSet;\nbegin\n  {can be overriden}\nend;\n\nprocedure TwbDef.PossiblyRequired;\nbegin\n  defPossiblyRequired := True;\nend;\n\nprocedure TwbDef.Report(const aParents: TwbDefPath);\nvar\n  i, j : Integer;\n  sl   : TStringList;\nbegin\n  if defReported then\n    Exit;\n\n  if wbReportUnused then\n    if not defUsed then\n      WriteLn('Unused: ', wbDefsToPath(aParents), wbDefToName(Self));\n\n  if wbReportRequired and defPossiblyRequired then\n    if defNotRequired = defRequired then\n      if defNotRequired then\n        WriteLn('Not Required: ', wbDefsToPath(aParents), wbDefToName(Self))\n      else\n        WriteLn('Required: ', wbDefsToPath(aParents), wbDefToName(Self));\n\n  if wbReportUnknown then\n    if Assigned(UnknownValues) then begin\n      WriteLn('Unknown Field: ', wbDefsToPath(aParents), wbDefToName(Self), ' (', UnknownValues.Count ,')');\n      for i := 0 to Pred(UnknownValues.Count) do begin\n        sl := UnknownValues.Objects[i] as TStringList;\n        WriteLn('  ', UnknownValues[i], ' (', sl.Count ,')');\n        for j := 0 to Pred(sl.Count) do\n          WriteLn('    ', sl[j]);\n      end;\n    end else\n      if IsUnknown then\n        WriteLn('Unknown Field: ', wbDefsToPath(aParents), wbDefToName(Self));\n\n  defReported := True;\nend;\n\nfunction TwbDef.SetParent(const aParent: TwbDef; aForceDuplicate: Boolean): IwbDef;\nbegin\n  Assert(Assigned(aParent));\n  if Assigned(defParent) or aForceDuplicate then\n    Result := Duplicate.SetParent(aParent, False)\n  else begin\n    Result := Self;\n    defParent := aParent;\n    ParentSet;\n  end;\nend;\n\nprocedure TwbDef.Used(const aElement: IwbElement; const s: string);\nvar\n  i: Integer;\n  NamedDef: IwbNamedDef;\nbegin\n  if not wbReportMode then\n    Exit;\n\n  defUsed := True;\n\n  if not IsUnknown then\n    if not IsUnknownChecked then begin\n      IsUnknownChecked := True;\n      if Supports(defParent, IwbNamedDef, NamedDef) then\n        if Pos('unknown', LowerCase(NamedDef.Name)) > 0 then\n          IsUnknown := True;\n    end;\n\n  if wbReportUnknown then\n    if IsUnknown and Assigned(aElement) and (s <> '') then begin\n\n      if not Assigned(UnknownValues) then\n        UnknownValues := TwbFastStringListCS.CreateSorted;\n\n      if UnknownValues.Count < 20 then begin\n        if not UnknownValues.Find(s, i) then\n          i := UnknownValues.AddObject(s, TwbFastStringListCS.CreateSorted(dupIgnore));\n\n        with UnknownValues.Objects[i] as TStringList do\n          if Count < 20 then\n            Add(aElement.FullPath);\n      end;\n    end;\nend;\n\n{ TwbNamedDef }\n\nprocedure TwbNamedDef.AfterLoad(const aElement: IwbElement);\nbegin\n  Used(nil, '');\n  if Assigned(noAfterLoad) then\n    noAfterLoad(aElement);\nend;\n\n\nprocedure TwbNamedDef.AfterSet(const aElement: IwbElement; const aOldValue, aNewValue: Variant);\nbegin\n  if Assigned(noAfterSet) then\n    noAfterSet(aElement, aOldValue, aNewValue);\nend;\n\nconstructor TwbNamedDef.Clone(const aSource: TwbDef);\nbegin\n  with (aSource as TwbNamedDef) do begin\n    Self.Create(defPriority, defRequired, noName, noAfterLoad, noAfterSet, noDontShow, defGetCP, noTerminator).defSource := aSource;\n    Self.noTreeHead := GetTreeHead;\n    Self.notreeBranch := GetTreeBranch;\n  end\nend;\n\nconstructor TwbNamedDef.Create(aPriority   : TwbConflictPriority;\n                               aRequired   : Boolean;\n                         const aName       : string;\n                               aAfterLoad  : TwbAfterLoadCallback;\n                               aAfterSet   : TwbAfterSetCallback;\n                               aDontShow   : TwbDontShowCallback;\n                               aGetCP      : TwbGetConflictPriority;\n                               aTerminator : Boolean);\nbegin\n  noName := aName;\n  noDontShow := aDontShow;\n  noAfterLoad := aAfterLoad;\n  noAfterSet := aAfterSet;\n  noTerminator := aTerminator;\n  noTreeHead := False;\n  noTreeBranch := False;\n  if aName = 'Unused' then begin\n    noUnused := True;\n    if aPriority = cpNormal then\n        aPriority := cpIgnore;\n  end;\n  inherited Create(aPriority, aRequired, aGetCP);\n\n  if Pos('unknown', LowerCase(aName)) > 0 then\n    IsUnknown := True;\nend;\n\nfunction TwbNamedDef.GetDontShow(const aElement: IwbElement): Boolean;\nbegin\n  if Assigned(noDontShow) then\n    Result := noDontShow(aElement)\n  else\n    Result := wbHideUnused and noUnused;\nend;\n\nfunction TwbNamedDef.GetHasDontShow: Boolean;\nbegin\n  Result := Assigned(noDontShow) or (wbHideUnused and noUnused);\nend;\n\nfunction TwbNamedDef.GetName: string;\nbegin\n  Result := noName;\nend;\n\nfunction TwbNamedDef.GetPath: string;\nvar\n  Parent: IwbDef;\n  NamedDef: IwbNamedDef;\nbegin\n  Result := GetName;\n  Parent := defParent;\n  while Assigned(Parent) do begin\n    if Supports(Parent, IwbNamedDef, NamedDef) then\n      Result := NamedDef.Name + ' \\ ' + Result\n    else\n      Result := Parent.DefTypeName + ' \\ ' + Result;\n    Parent := Parent.Parent;\n  end;\nend;\n\nfunction TwbNamedDef.GetTreeBranch: Boolean;\nbegin\n  Result := noTreeBranch;\nend;\n\nfunction TwbNamedDef.GetTreeHead: Boolean;\nbegin\n  Result := noTreeHead;\nend;\n\nprocedure TwbNamedDef.ParentSet;\nvar\n  Parent: IwbNamedDef;\nbegin\n  inherited;\n  if not (IsUnknown or noUnused) and (noName = '') and Supports(defParent, IwbNamedDef, Parent) then begin\n    IsUnknown := IsUnknown or (Pos('unknown', LowerCase(Parent.Name)) > 0);\n    noUnused := noUnused or (Parent.Name = 'Unused');\n  end;\nend;\n\nprocedure TwbNamedDef.SetTreeBranch(aValue: Boolean);\nbegin\n  noTreeBranch := avalue;\nend;\n\nprocedure TwbNamedDef.SetTreeHead(aValue: Boolean);\nbegin\n  noTreeHead := aValue;\nend;\n\n{ TwbSignatureDef }\n\nfunction TwbSignatureDef.CanHandle(aSignature     : TwbSignature;\n                             const aDataContainer : IwbDataContainer)\n                                                  : Boolean;\nbegin\n  Result := aSignature = GetDefaultSignature;\nend;\n\nconstructor TwbSignatureDef.Create(aPriority  : TwbConflictPriority;\n                                   aRequired  : Boolean;\n                             const aSignature : TwbSignature;\n                             const aName      : string;\n                                   aAfterLoad : TwbAfterLoadCallback;\n                                   aAfterSet  : TwbAfterSetCallback;\n                                   aDontShow  : TwbDontShowCallback;\n                                   aGetCP     : TwbGetConflictPriority);\nbegin\n  SetLength(soSignatures, 1);\n  soSignatures[0] := aSignature;\n  inherited Create(aPriority, aRequired, aName, aAfterLoad, aAfterSet, aDontShow, aGetCP, False);\nend;\n\nconstructor TwbSignatureDef.Clone(const aSource: TwbDef);\nbegin\n  with (aSource as TwbSignatureDef) do\n    Self.Create(defPriority, defRequired, soSignatures, noName, noAfterLoad, noAfterSet, noDontShow, defGetCP).defSource := aSource;\nend;\n\nconstructor TwbSignatureDef.Create(aPriority   : TwbConflictPriority;\n                                   aRequired   : Boolean;\n                             const aSignatures : array of TwbSignature;\n                             const aName       : string;\n                                   aAfterLoad  : TwbAfterLoadCallback;\n                                   aAfterSet   : TwbAfterSetCallback;\n                                   aDontShow   : TwbDontShowCallback;\n                                   aGetCP      : TwbGetConflictPriority);\nvar\n  i: Integer;\nbegin\n  Assert(Length(aSignatures) >= 1);\n  SetLength(soSignatures, Length(aSignatures));\n  for i := Low(soSignatures) to High(soSignatures) do\n    soSignatures[i] := aSignatures[i];\n  inherited Create(aPriority, aRequired, aName, aAfterLoad, aAfterSet, aDontShow, aGetCP, False);\nend;\n\n\nfunction TwbSignatureDef.GetDefaultSignature: TwbSignature;\nbegin\n  Result := soSignatures[0];\nend;\n\nfunction TwbSignatureDef.GetSignatureCount: Integer;\nbegin\n  Result := Length(soSignatures);\nend;\n\nfunction TwbSignatureDef.GetSignatures(const aIndex: Integer): TwbSignature;\nbegin\n  Result := soSignatures[aIndex];\nend;\n\n{ TwbRecordDef }\n\nfunction TwbRecordDef.AdditionalInfoFor(const aMainRecord: IwbMainRecord): string;\nbegin\n  if (wbCopyIsRunning = 0) and Assigned(recAddInfoCallback) then\n    Result := recAddInfoCallback(aMainRecord)\n  else\n    Result := '';\nend;\n\nprocedure TwbRecordDef.AfterLoad(const aElement: IwbElement);\nvar\n  Found     : Boolean;\n  Container : IwbContainerElementRef;\n  Element   : IwbElement;\n  i, j      : Integer;\nbegin\n  inherited;\n  if wbReportMode and wbReportRequired and Supports(aElement, IwbContainerElementRef, Container) then begin\n    for i := Low(recMembers) to High(recMembers) do if not recMembers[i].IsNotRequired then begin\n      Found := False;\n      for j := 0 to Pred(Container.ElementCount) do begin\n        Element := Container.Elements[j];\n        if recMembers[i].Equals(Element.Def) or recMembers[i].Equals(Element.ValueDef) then begin\n          Found := True;\n          Break;\n        end;\n      end;\n      recMembers[i].PossiblyRequired;\n      if not Found then\n        recMembers[i].NotRequired;\n    end;\n  end;\nend;\n\nfunction TwbRecordDef.AllowUnordered: Boolean;\nbegin\n  Result := recAllowUnordered;\nend;\n\nfunction TwbRecordDef.CanContainFormIDs: Boolean;\nbegin\n  Result := recCanContainFormIDs;\nend;\n\nconstructor TwbRecordDef.Clone(const aSource: TwbDef);\nbegin\n  with aSource as TwbRecordDef do\n    Self.Create(defPriority, defRequired, GetDefaultSignature, noName, recRecordFlags, recMembers,\n      recAllowUnordered, recAddInfoCallback, noAfterLoad, noAfterSet).defSource := aSource;\nend;\n\nfunction TwbRecordDef.ContainsMemberFor(aSignature     : TwbSignature;\n                                  const aDataContainer : IwbDataContainer)\n                                                       : Boolean;\nvar\n  Dummy: Integer;\nbegin\n  Result := recSignatures.Find(aSignature, Dummy);\nend;\n\nconstructor TwbRecordDef.Create(aPriority        : TwbConflictPriority;\n                                aRequired        : Boolean;\n                          const aSignature       : TwbSignature;\n                          const aName            : string;\n                          const aRecordFlags     : IwbIntegerDefFormater;\n                          const aMembers         : array of IwbRecordMemberDef;\n                                aAllowUnordered  : Boolean;\n                                aAddInfoCallback : TwbAddInfoCallback;\n                                aAfterLoad       : TwbAfterLoadCallback;\n                                aAfterSet        : TwbAfterSetCallback);\nvar\n  i, j : Integer;\n  Sig  : TwbSignature;\nbegin\n  recRecordFlags := aRecordFlags;\n  recQuickInitLimit := -1;\n  recAllowUnordered := aAllowUnordered;\n  recAddInfoCallback := aAddInfoCallback;\n\n  if Assigned(recRecordFlags) and Assigned(wbRecordFlags) and Assigned(wbMainRecordHeader) then begin\n    recRecordHeaderStruct := (wbMainRecordHeader as IwbDefInternal).SetParent(Self, True) as IwbStructDef;\n    (recRecordHeaderStruct.MembersByName[wbRecordFlags.Name] as IwbInternalIntegerDef).ReplaceFormater(recRecordFlags);\n  end;\n\n  recSignatures := TwbFastStringListCS.CreateSorted(dupAccept);\n  if aAllowUnordered then\n    recSignatures.Duplicates := dupError;\n\n  SetLength(recMembers, Length(aMembers));\n  for i := Low(recMembers) to High(recMembers) do begin\n    recMembers[i] := (aMembers[i] as IwbDefInternal).SetParent(Self, False) as IwbRecordMemberDef;\n    recCanContainFormIDs := recCanContainFormIDs or aMembers[i].CanContainFormIDs;\n    for j := 0 to Pred(aMembers[i].SignatureCount) do begin\n      Sig := aMembers[i].Signatures[j];\n      if (Sig = 'EDID') or\n         (Sig = 'FULL') or\n         (\n           (Sig = 'NAME') and\n           (\n             (aSignature = 'REFR') or\n             (aSignature = 'ACHR') or\n             (aSignature = 'ACRE') or\n             (aSignature = 'PGRE') or\n             (aSignature = 'PMIS') or\n             (aSignature = 'PARW') or {>>> Skyrim <<<}\n             (aSignature = 'PBEA') or {>>> Skyrim <<<}\n             (aSignature = 'PFLA') or {>>> Skyrim <<<}\n             (aSignature = 'PCON') or {>>> Skyrim <<<}\n             (aSignature = 'PBAR') or {>>> Skyrim <<<}\n             (aSignature = 'PHZD')    {>>> Skyrim <<<}\n           )\n         ) then begin\n\n        recQuickInitLimit := i;\n        if Sig = 'EDID' then\n          recContainsEditorID := True;\n\n      end;\n      try\n        recSignatures.AddObject(Sig, Pointer(i) );\n      except\n        on E: Exception do\n          raise Exception.Create('Duplicate definition ' + Sig + ' in allow unordered record ' + aSignature);\n      end;\n    end;\n  end;\n\n  inherited Create(aPriority, aRequired, aSignature, aName, aAfterLoad, aAfterSet, nil, nil);\nend;\n\nfunction TwbRecordDef.GetMember(aIndex: Integer): IwbRecordMemberDef;\nbegin\n  Result := recMembers[aIndex];\nend;\n\nfunction TwbRecordDef.GetMemberCount: Integer;\nbegin\n  Result := Length(recMembers);\nend;\n\nfunction TwbRecordDef.GetMemberFor(aSignature     : TwbSignature;\n                             const aDataContainer : IwbDataContainer)\n                                                  : IwbRecordMemberDef;\nvar\n  i: Integer;\nbegin\n  if recSignatures.Find(aSignature, i) then\n    Result := recMembers[Integer(recSignatures.Objects[i])]\n  else\n    Result := nil;\nend;\n\nfunction TwbRecordDef.GetMemberIndexFor(aSignature     : TwbSignature;\n                                  const aDataContainer : IwbDataContainer)\n                                                       : Integer;\nvar\n  i: Integer;\nbegin\n  if recSignatures.Find(aSignature, i) then\n    Result := Integer(recSignatures.Objects[i])\n  else\n    Result := -1;\nend;\n\nfunction TwbRecordDef.GetQuickInitLimit: Integer;\nbegin\n  Result := recQuickInitLimit;\nend;\n\nfunction TwbRecordDef.GetRecordHeaderStruct: IwbStructDef;\nbegin\n  if Assigned(recRecordHeaderStruct) then\n    Result := recRecordHeaderStruct\n  else\n    Result := wbMainRecordHeader;\nend;\n\nfunction TwbRecordDef.GetSkipSignature(const aSignature: TwbSignature): Boolean;\nbegin\n  Result := False;\nend;\n\nprocedure TwbRecordDef.Report(const aParents: TwbDefPath);\nvar\n  Parents : TwbDefPath;\n  i       : Integer;\nbegin\n  if defReported then\n    Exit;\n\n  inherited;\n  Parents := aParents;\n  SetLength(Parents, Succ(Length(Parents)));\n  Parents[High(Parents)].Def := Self;\n  for i := Low(recMembers) to High(recMembers) do\n    if Assigned(recMembers[i]) then begin\n      Parents[High(Parents)].Index := i;\n      recMembers[i].Report(Parents);\n    end;\n\n  defReported := True;\nend;\n\ndestructor TwbRecordDef.Destroy;\nbegin\n  inherited;\n  FreeAndNil(recSignatures);\nend;\n\nfunction TwbRecordDef.GetContainsEditorID: Boolean;\nbegin\n  Result := recContainsEditorID;\nend;\n\nfunction TwbRecordDef.GetDefType: TwbDefType;\nbegin\n  Result := dtRecord;\nend;\n\nfunction TwbRecordDef.GetDefTypeName: string;\nbegin\n  Result := 'Record';\nend;\n\n{ TwbSubRecordDef }\n\nfunction TwbSubRecordDef.CanAssign(const aElement: IwbElement; aIndex: Integer; const aDef: IwbDef): Boolean;\nvar\n  SubRecordDef : IwbSubRecordDef;\nbegin\n  if Supports(aDef, IwbSubRecordDef, SubRecordDef) then\n    Result := Equals(aDef) or Assigned(srValue) and srValue.CanAssign(aElement, aIndex, SubRecordDef.Value)\n  else\n    Result := Assigned(srValue) and srValue.CanAssign(aElement, aIndex, aDef);\nend;\n\nfunction TwbSubRecordDef.CanContainFormIDs: Boolean;\nbegin\n  Result := srValue.CanContainFormIDs;\nend;\n\nfunction TwbSubRecordDef.CanHandle(aSignature     : TwbSignature;\n                             const aDataContainer : IwbDataContainer)\n                                                  : Boolean;\nbegin\n  Result := inherited CanHandle(aSignature, aDataContainer);\n  if Result and srSizeMatch and Assigned(aDataContainer) and Assigned(srValue) then\n    Result := aDataContainer.DataSize = srValue.DefaultSize[nil, nil, nil];\nend;\n\nconstructor TwbSubRecordDef.Clone(const aSource: TwbDef);\nbegin\n  with aSource as TwbSubRecordDef do\n    Self.Create(defPriority, defRequired, soSignatures, noName, srValue, noAfterLoad, noAfterSet, srSizeMatch, noDontShow, defGetCP).defSource := aSource;\nend;\n\nconstructor TwbSubRecordDef.Create(aPriority  : TwbConflictPriority;\n                                   aRequired  : Boolean;\n                             const aSignature : TwbSignature;\n                             const aName      : string;\n                             const aValue     : IwbValueDef;\n                                   aAfterLoad : TwbAfterLoadCallback;\n                                   aAfterSet  : TwbAfterSetCallback;\n                                   aSizeMatch : Boolean;\n                                   aDontShow  : TwbDontShowCallback;\n                                   aGetCP     : TwbGetConflictPriority);\nbegin\n  srSizeMatch := aSizeMatch;\n  if Assigned(aValue) then\n    srValue := (aValue as IwbDefInternal).SetParent(Self, False) as IwbValueDef;\n  inherited Create(aPriority, aRequired, aSignature, aName, aAfterLoad, aAfterSet, aDontShow, aGetCP);\nend;\n\nconstructor TwbSubRecordDef.Create(aPriority   : TwbConflictPriority;\n                                   aRequired   : Boolean;\n                             const aSignatures : array of TwbSignature;\n                             const aName       : string;\n                             const aValue      : IwbValueDef;\n                                   aAfterLoad  : TwbAfterLoadCallback;\n                                   aAfterSet   : TwbAfterSetCallback;\n                                   aSizeMatch  : Boolean;\n                                   aDontShow   : TwbDontShowCallback;\n                                   aGetCP      : TwbGetConflictPriority);\nbegin\n  srSizeMatch := aSizeMatch;\n  if Assigned(aValue) then\n    srValue := (aValue as IwbDefInternal).SetParent(Self, False) as IwbValueDef;\n  inherited Create(aPriority, aRequired, aSignatures, aName, aAfterLoad, aAfterSet, aDontShow, aGetCP);\nend;\n\nfunction TwbSubRecordDef.GetDefType: TwbDefType;\nbegin\n  Result := dtSubRecord;\nend;\n\nfunction TwbSubRecordDef.GetDefTypeName: string;\nbegin\n  Result := 'SubRecord of '+GetValue.GetDefTypeName;\nend;\n\nfunction TwbSubRecordDef.GetValue: IwbValueDef;\nbegin\n  Result := srValue;\nend;\n\nprocedure TwbSubRecordDef.HasUnusedData;\nbegin\n  srHasUnusedData := True;\nend;\n\nprocedure TwbSubRecordDef.Report(const aParents: TwbDefPath);\nvar\n  Parents : TwbDefPath;\nbegin\n  if defReported then\n    Exit;\n\n  inherited;\n  if Assigned(srValue) then begin\n    Parents := aParents;\n    SetLength(Parents, Succ(Length(Parents)));\n    Parents[High(Parents)].Def := Self;\n    Parents[High(Parents)].Index := -1;\n    srValue.Report(Parents);\n  end;\n  if wbReportUnusedData then\n    if srHasUnusedData then\n      WriteLn('Has Unused Data: ', wbDefsToPath(aParents), wbDefToName(Self));\n\n  defReported := True;\nend;\n\n{ TwbSubRecordArrayDef }\n\nprocedure TwbSubRecordArrayDef.AfterLoad(const aElement: IwbElement);\nvar\n  Container: IwbContainerElementRef;\nbegin\n  inherited;\n  if wbReportMode and wbReportRequired and Supports(aElement, IwbContainerElementRef, Container) then begin\n    sraElement.PossiblyRequired;\n    if Container.ElementCount < 1 then\n      sraElement.NotRequired;\n  end;\nend;\n\nfunction TwbSubRecordArrayDef.CanAssign(const aElement: IwbElement; aIndex: Integer; const aDef: IwbDef): Boolean;\nvar\n  SubRecordArrayDef : IwbSubRecordArrayDef;\nbegin\n  if aIndex = Low(Integer) then\n    Result := Supports(aDef, IwbSubRecordArrayDef, SubRecordArrayDef) and\n      GetElement.CanAssign(aElement, aIndex, SubRecordArrayDef.Element)\n  else if aIndex = High(Integer) then\n    Result := GetElement.CanAssign(aElement, Low(Integer), aDef)\n  else\n    Result := False;\nend;\n\nfunction TwbSubRecordArrayDef.CanContainFormIDs: Boolean;\nbegin\n  Result := sraElement.CanContainFormIDs;\nend;\n\nfunction TwbSubRecordArrayDef.CanHandle(aSignature     : TwbSignature;\n                                  const aDataContainer : IwbDataContainer)\n                                                       : Boolean;\nbegin\n  Result := sraElement.CanHandle(aSignature, aDataContainer);\nend;\n\nconstructor TwbSubRecordArrayDef.Clone(const aSource: TwbDef);\nbegin\n  with aSource as TwbSubRecordArrayDef do\n    Self.Create(defPriority, defRequired, noName, sraElement, sraSorted,\n      noAfterLoad, noAfterSet, noDontShow, sraIsSorted, defGetCP).defSource := aSource;\nend;\n\nconstructor TwbSubRecordArrayDef.Create(aPriority  : TwbConflictPriority; aRequired: Boolean;\n                                  const aName      : string;\n                                  const aElement   : IwbRecordMemberDef;\n                                        aSorted    : Boolean;\n                                        aAfterLoad : TwbAfterLoadCallback;\n                                        aAfterSet  : TwbAfterSetCallback;\n                                        aDontShow  : TwbDontShowCallback;\n                                        aIsSorted  : TwbIsSortedCallback;\n                                        aGetCP     : TwbGetConflictPriority);\nbegin\n  if Assigned(aElement) then\n    sraElement := (aElement as IwbDefInternal).SetParent(Self, False) as IwbRecordMemberDef;\n  sraSorted := aSorted;\n  sraIsSorted := aIsSorted;\n  inherited Create(aPriority, aRequired, aName, aAfterLoad, aAfterSet, aDontShow, aGetCP, False);\nend;\n\nfunction TwbSubRecordArrayDef.GetElement: IwbRecordMemberDef;\nbegin\n  Result := sraElement;\nend;\n\nfunction TwbSubRecordArrayDef.GetDefaultSignature: TwbSignature;\nbegin\n  Result := sraElement.GetDefaultSignature;\nend;\n\nfunction TwbSubRecordArrayDef.GetSignatureCount: Integer;\nbegin\n  Result := sraElement.GetSignatureCount;\nend;\n\nfunction TwbSubRecordArrayDef.GetSignatures(const aIndex: Integer): TwbSignature;\nbegin\n  Result := sraElement.GetSignatures(aIndex);\nend;\n\nfunction TwbSubRecordArrayDef.GetSorted(const aContainer: IwbContainer): Boolean;\nbegin\n  if Assigned(sraIsSorted) then\n    Result := sraIsSorted(aContainer)\n  else\n    Result := sraSorted;\nend;\n\nprocedure TwbSubRecordArrayDef.Report(const aParents: TwbDefPath);\nvar\n  Parents : TwbDefPath;\nbegin\n  if defReported then\n    Exit;\n\n  inherited;\n  if Assigned(sraElement) then begin\n    Parents := aParents;\n    SetLength(Parents, Succ(Length(Parents)));\n    Parents[High(Parents)].Def := Self;\n    Parents[High(Parents)].Index := -1;\n    sraElement.Report(Parents);\n  end;\n\n  defReported := True;\nend;\n\nfunction TwbSubRecordArrayDef.GetDefType: TwbDefType;\nbegin\n  Result := dtSubRecordArray;\nend;\n\nfunction TwbSubRecordArrayDef.GetDefTypeName: string;\nbegin\n  Result := 'SubRecordArray of '+GetElement.GetDefTypeName;\nend;\n\n{ TwbSubRecordStructDef }\n\nfunction TwbSubRecordStructDef.AdditionalInfoFor(const aMainRecord: IwbMainRecord): string;\nbegin\n  Result := '';\nend;\n\nprocedure TwbSubRecordStructDef.AfterLoad(const aElement: IwbElement);\nvar\n  Found     : Boolean;\n  Container : IwbContainerElementRef;\n  Element   : IwbElement;\n  i, j      : Integer;\nbegin\n  inherited;\n  if wbReportMode and wbReportRequired and  Supports(aElement, IwbContainerElementRef, Container) then begin\n    for i := 1 to High(srsMembers) do  if not srsMembers[i].IsNotRequired then begin\n      Found := False;\n      for j := 0 to Pred(Container.ElementCount) do begin\n        Element := Container.Elements[j];\n        if srsMembers[i].Equals(Element.Def) or srsMembers[i].Equals(Element.ValueDef) then begin\n          Found := True;\n          Break;\n        end;\n      end;\n      srsMembers[i].PossiblyRequired;\n      if not Found then\n        srsMembers[i].NotRequired;\n    end;\n  end;\nend;\n\nfunction TwbSubRecordStructDef.AllowUnordered: Boolean;\nbegin\n  Result := srsAllowUnordered;\nend;\n\nfunction TwbSubRecordStructDef.CanAssign(const aElement: IwbElement; aIndex: Integer; const aDef: IwbDef): Boolean;\nvar\n  SubRecordStructDef : IwbSubRecordStructDef;\n  RecordDef          : IwbRecordDef;\n  i                  : Integer;\nbegin\n  if Supports(aDef, IwbSubRecordStructDef, SubRecordStructDef) then begin\n    Result := Equals(aDef);\n    if not Result and\n      Supports(aDef, IwbRecordDef, RecordDef) and\n      (GetMemberCount = RecordDef.MemberCount)then begin\n      Result := True;\n      for i := 0 to Pred(GetMemberCount) do\n        if not srsMembers[i].CanAssign(aElement, aIndex, RecordDef.Members[i]) then begin\n          Result := False;\n          Break;\n        end;\n    end;\n  end else\n    Result := False;\nend;\n\nfunction TwbSubRecordStructDef.CanContainFormIDs: Boolean;\nbegin\n  Result := srsCanContainFormIDs;\nend;\n\nfunction TwbSubRecordStructDef.CanHandle(aSignature     : TwbSignature;\n                                   const aDataContainer : IwbDataContainer)\n                                                        : Boolean;\nbegin\n  if srsAllowUnordered then\n    Result := ContainsMemberFor(aSignature, aDataContainer)\n  else\n    Result := srsMembers[0].CanHandle(aSignature, aDataContainer);\nend;\n\nconstructor TwbSubRecordStructDef.Clone(const aSource: TwbDef);\nvar\n  SkipSigs : array of TwbSignature;\n  i        : Integer;\nbegin\n  with aSource as TwbSubRecordStructDef do begin\n    if Assigned(srsSkipSignatures) then begin\n      SetLength(SkipSigs, srsSkipSignatures.Count);\n      for i := 0 to Pred(srsSkipSignatures.Count) do\n        SkipSigs[i] := StrToSignature(srsSkipSignatures[i]);\n    end;\n    Self.Create(defPriority, defRequired, noName, srsMembers, SkipSigs, noDontShow, srsAllowUnordered, noAfterLoad, noAfterSet, defGetCP).defSource := aSource;\n  end;\nend;\n\nfunction TwbSubRecordStructDef.ContainsMemberFor(aSignature     : TwbSignature;\n                                           const aDataContainer : IwbDataContainer)\n                                                                : Boolean;\nvar\n  Dummy: Integer;\nbegin\n  Result := srsSignatures.Find(aSignature, Dummy);\nend;\n\nconstructor TwbSubRecordStructDef.Create(aPriority       : TwbConflictPriority;\n                                         aRequired       : Boolean;\n                                   const aName           : string;\n                                   const aMembers        : array of IwbRecordMemberDef;\n                                   const aSkipSigs       : array of TwbSignature;\n                                         aDontShow       : TwbDontShowCallback;\n                                         aAllowUnordered : Boolean;\n                                         aAfterLoad      : TwbAfterLoadCallback;\n                                         aAfterSet       : TwbAfterSetCallback;\n                                         aGetCP          : TwbGetConflictPriority);\nvar\n  i,j: Integer;\n  FoundRequired : Boolean;\nbegin\n  srsAllowUnordered := aAllowUnordered;\n  srsSignatures := TwbFastStringListCS.CreateSorted(dupIgnore);\n\n  FoundRequired := False;\n  SetLength(srsMembers, Length(aMembers));\n  for i := Low(srsMembers) to High(srsMembers) do begin\n    srsMembers[i] := (aMembers[i] as IwbDefInternal).SetParent(Self, False) as IwbRecordMemberDef;\n    srsCanContainFormIDs := srsCanContainFormIDs or aMembers[i].CanContainFormIDs;\n    FoundRequired := FoundRequired or srsMembers[i].Required;\n    for j := 0 to Pred(aMembers[i].SignatureCount) do\n      srsSignatures.AddObject(aMembers[i].Signatures[j], Pointer(i) );\n  end;\n\n  if Length(aSkipSigs) > 0 then begin\n    srsSkipSignatures := TwbFastStringListCS.CreateSorted(dupIgnore);\n    for i := Low(aSkipSigs) to High(aSkipSigs) do\n      srsSkipSignatures.Add(aSkipSigs[i]);\n  end;\n\n  inherited Create(aPriority, aRequired, aName, aAfterLoad, aAfterSet, aDontShow, aGetCP, False);\n\n  if srsAllowUnordered and not FoundRequired then\n   raise Exception.Create(GetPath + ' must contain at least one required element');\nend;\n\ndestructor TwbSubRecordStructDef.Destroy;\nbegin\n  inherited;\n  FreeAndNil(srsSignatures);\n  FreeAndNil(srsSkipSignatures);\nend;\n\nfunction TwbSubRecordStructDef.GetDefType: TwbDefType;\nbegin\n  Result := dtSubRecordStruct;\nend;\n\nfunction TwbSubRecordStructDef.GetDefTypeName: string;\nbegin\n  Result := 'SubRecordStruct';\nend;\n\nfunction TwbSubRecordStructDef.GetMember(aIndex: Integer): IwbRecordMemberDef;\nbegin\n  Result := srsMembers[aIndex];\nend;\n\nfunction TwbSubRecordStructDef.GetMemberCount: Integer;\nbegin\n  Result := Length(srsMembers);\nend;\n\nfunction TwbSubRecordStructDef.GetMemberFor(aSignature     : TwbSignature;\n                                      const aDataContainer : IwbDataContainer)\n                                                           : IwbRecordMemberDef;\nvar\n  i: Integer;\nbegin\n  if srsSignatures.Find(aSignature, i) then\n    Result := srsMembers[Integer(srsSignatures.Objects[i])]\n  else\n    Result := nil;\nend;\n\nfunction TwbSubRecordStructDef.GetMemberIndexFor(aSignature     : TwbSignature;\n                                           const aDataContainer : IwbDataContainer)\n                                                                : Integer;\nvar\n  i: Integer;\nbegin\n  if srsSignatures.Find(aSignature, i) then\n    Result := Integer(srsSignatures.Objects[i])\n  else\n    Result := -1;\nend;\n\nfunction TwbSubRecordStructDef.GetQuickInitLimit: Integer;\nbegin\n  Result := -1;\nend;\n\nfunction TwbSubRecordStructDef.GetRecordHeaderStruct: IwbStructDef;\nbegin\n  Result := wbMainRecordHeader;\nend;\n\nfunction TwbSubRecordStructDef.GetContainsEditorID: Boolean;\nbegin\n  Result := False;\nend;\n\nfunction TwbSubRecordStructDef.GetDefaultSignature: TwbSignature;\nbegin\n  Result := srsMembers[0].GetDefaultSignature;\nend;\n\nfunction TwbSubRecordStructDef.GetSignatureCount: Integer;\nbegin\n  if srsAllowUnordered then\n    Result := srsSignatures.Count\n  else\n    Result := srsMembers[0].GetSignatureCount;\nend;\n\nfunction TwbSubRecordStructDef.GetSignatures(const aIndex: Integer): TwbSignature;\nbegin\n  if srsAllowUnordered then\n    Result := StrToSignature(srsSignatures[aIndex])\n  else\n    Result := srsMembers[0].GetSignatures(aIndex);\nend;\n\nfunction TwbSubRecordStructDef.GetSkipSignature(const aSignature: TwbSignature): Boolean;\nvar\n  Dummy: Integer;\nbegin\n  Result := Assigned(srsSkipSignatures) and srsSkipSignatures.Find(aSignature, Dummy);\nend;\n\nprocedure TwbSubRecordStructDef.Report(const aParents: TwbDefPath);\nvar\n  Parents : TwbDefPath;\n  i       : Integer;\nbegin\n  if defReported then\n    Exit;\n\n  inherited;\n  Parents := aParents;\n  SetLength(Parents, Succ(Length(Parents)));\n  Parents[High(Parents)].Def := Self;\n  for i := Low(srsMembers) to High(srsMembers) do\n    if Assigned(srsMembers[i]) then begin\n      Parents[High(Parents)].Index := i;\n      srsMembers[i].Report(Parents);\n    end;\n\n  defReported := True;\nend;\n\n{ TwbSubRecordUnionDef }\n\nfunction TwbSubRecordUnionDef.AdditionalInfoFor(const aMainRecord: IwbMainRecord): string;\nbegin\n  Result := '';\nend;\n\nfunction TwbSubRecordUnionDef.AllowUnordered: Boolean;\nbegin\n  Result := True;\nend;\n\nfunction TwbSubRecordUnionDef.CanAssign(const aElement: IwbElement; aIndex: Integer; const aDef: IwbDef): Boolean;\nvar\n  SubRecordUnionDef : IwbSubRecordUnionDef;\n  RecordDef         : IwbRecordDef;\n  i                 : Integer;\nbegin\n  for i := Low(sruMembers) to High(sruMembers) do begin\n    Result := sruMembers[i].CanAssign(aElement, aIndex, aDef);\n    if Result = True then\n      Exit;\n  end;\n\n  if Supports(aDef, IwbSubRecordUnionDef, SubRecordUnionDef) then begin\n    Result := Equals(aDef);\n    if not Result and\n      Supports(aDef, IwbRecordDef, RecordDef) and\n      (GetMemberCount = RecordDef.MemberCount)then begin\n      Result := True;\n      for i := 0 to Pred(GetMemberCount) do\n        if not sruMembers[i].CanAssign(aElement, aIndex, RecordDef.Members[i]) then begin\n          Result := False;\n          Break;\n        end;\n    end;\n  end else\n    Result := False;\nend;\n\nfunction TwbSubRecordUnionDef.CanContainFormIDs: Boolean;\nbegin\n  Result := sruCanContainFormIDs;\nend;\n\nfunction TwbSubRecordUnionDef.CanHandle(aSignature     : TwbSignature;\n                                  const aDataContainer : IwbDataContainer)\n                                                       : Boolean;\nvar\n  i: Integer;\nbegin\n  Result := False;\n  for i := Low(sruMembers) to High(sruMembers) do begin\n    Result := sruMembers[i].CanHandle(aSignature, aDataContainer);\n    if Result then\n      Exit;\n  end;\nend;\n\nconstructor TwbSubRecordUnionDef.Clone(const aSource: TwbDef);\nvar\n  SkipSigs : array of TwbSignature;\n  i        : Integer;\nbegin\n  with aSource as TwbSubRecordUnionDef do begin\n    if Assigned(sruSkipSignatures) then begin\n      SetLength(SkipSigs, sruSkipSignatures.Count);\n      for i := 0 to Pred(sruSkipSignatures.Count) do\n        SkipSigs[i] := StrToSignature(sruSkipSignatures[i]);\n    end;\n    Self.Create(defPriority, defRequired, noName, sruMembers, SkipSigs, noDontShow, defGetCP).defSource := aSource;\n  end;\nend;\n\nfunction TwbSubRecordUnionDef.ContainsMemberFor(aSignature     : TwbSignature;\n                                          const aDataContainer : IwbDataContainer)\n                                                               : Boolean;\nbegin\n  Result := CanHandle(aSignature, aDataContainer);\nend;\n\nconstructor TwbSubRecordUnionDef.Create(aPriority : TwbConflictPriority;\n                                        aRequired : Boolean;\n                                  const aName     : string;\n                                  const aMembers  : array of IwbRecordMemberDef;\n                                  const aSkipSigs : array of TwbSignature;\n                                        aDontShow : TwbDontShowCallback;\n                                        aGetCP    : TwbGetConflictPriority);\nvar\n  i,j: Integer;\nbegin\n  sruSignatures := TwbFastStringListCS.CreateSorted(dupIgnore);\n\n  SetLength(sruMembers, Length(aMembers));\n  for i := Low(sruMembers) to High(sruMembers) do begin\n    sruMembers[i] := (aMembers[i] as IwbDefInternal).SetParent(Self, False) as IwbRecordMemberDef;\n    sruCanContainFormIDs := sruCanContainFormIDs or aMembers[i].CanContainFormIDs;\n    for j := 0 to Pred(aMembers[i].SignatureCount) do\n      sruSignatures.AddObject(aMembers[i].Signatures[j], Pointer(i));\n  end;\n\n  if Length(aSkipSigs) > 0 then begin\n    sruSkipSignatures := TwbFastStringListCS.CreateSorted(dupIgnore);\n    for i := Low(aSkipSigs) to High(aSkipSigs) do\n      sruSkipSignatures.Add(aSkipSigs[i]);\n  end;\n\n  inherited Create(aPriority, aRequired, aName, nil, nil, aDontShow, aGetCP, False);\nend;\n\ndestructor TwbSubRecordUnionDef.Destroy;\nbegin\n  inherited;\n  FreeAndNil(sruSignatures);\nend;\n\nfunction TwbSubRecordUnionDef.GetContainsEditorID: Boolean;\nbegin\n  Result := False;\nend;\n\nfunction TwbSubRecordUnionDef.GetDefaultSignature: TwbSignature;\nbegin\n  Result := sruMembers[0].GetDefaultSignature;\nend;\n\nfunction TwbSubRecordUnionDef.GetDefType: TwbDefType;\nbegin\n  Result := dtSubRecordUnion;\nend;\n\nfunction TwbSubRecordUnionDef.GetDefTypeName: string;\nbegin\n  Result := 'SubRecordUnion';\nend;\n\nfunction TwbSubRecordUnionDef.GetMember(aIndex: Integer): IwbRecordMemberDef;\nbegin\n  Result := sruMembers[aIndex];\nend;\n\nfunction TwbSubRecordUnionDef.GetMemberCount: Integer;\nbegin\n  Result := Length(sruMembers);\nend;\n\nfunction TwbSubRecordUnionDef.GetMemberFor(aSignature     : TwbSignature;\n                                     const aDataContainer : IwbDataContainer)\n                                                          : IwbRecordMemberDef;\nvar\n  i: Integer;\nbegin\n  Result := nil;\n  for i := Low(sruMembers) to High(sruMembers) do begin\n    if sruMembers[i].CanHandle(aSignature, aDataContainer) then begin\n      Result := sruMembers[i];\n      Exit;\n    end;\n  end;\nend;\n\nfunction TwbSubRecordUnionDef.GetMemberIndexFor(aSignature     : TwbSignature;\n                                          const aDataContainer : IwbDataContainer)\n                                                               : Integer;\nvar\n  i: Integer;\nbegin\n  Result := -1;\n  for i := Low(sruMembers) to High(sruMembers) do begin\n    if sruMembers[i].CanHandle(aSignature, aDataContainer) then begin\n      Result := i;\n      Exit;\n    end;\n  end;\nend;\n\nfunction TwbSubRecordUnionDef.GetQuickInitLimit: Integer;\nbegin\n  Result := -1;\nend;\n\nfunction TwbSubRecordUnionDef.GetRecordHeaderStruct: IwbStructDef;\nbegin\n  Result := wbMainRecordHeader;\nend;\n\nfunction TwbSubRecordUnionDef.GetSignatureCount: Integer;\nvar\n  i: Integer;\nbegin\n  Result := 0;\n  for i := Low(sruMembers) to High(sruMembers) do\n    Inc(Result, sruMembers[i].GetSignatureCount);\nend;\n\nfunction TwbSubRecordUnionDef.GetSignatures(const aIndex: Integer): TwbSignature;\nvar\n  i, j, k: Integer;\nbegin\n  j := aIndex;\n  for i := Low(sruMembers) to High(sruMembers) do begin\n    k := sruMembers[i].GetSignatureCount;\n    if k > 0 then begin\n      if j >= k then\n        Dec(j, k)\n      else begin\n        Result := sruMembers[i].GetSignatures(Pred(k));\n        Exit;\n      end;\n    end;\n  end;\n  raise Exception.Create('Invalid index');\nend;\n\nfunction TwbSubRecordUnionDef.GetSkipSignature(const aSignature: TwbSignature): Boolean;\nvar\n  Dummy: Integer;\nbegin\n  Result := Assigned(sruSkipSignatures) and sruSkipSignatures.Find(aSignature, Dummy);\nend;\n\nprocedure TwbSubRecordUnionDef.Report(const aParents: TwbDefPath);\nvar\n  Parents : TwbDefPath;\n  i       : Integer;\nbegin\n  if defReported then\n    Exit;\n\n  inherited;\n  Parents := aParents;\n  SetLength(Parents, Succ(Length(Parents)));\n  Parents[High(Parents)].Def := Self;\n  for i := Low(sruMembers) to High(sruMembers) do\n    if Assigned(sruMembers[i]) then begin\n      Parents[High(Parents)].Index := i;\n      sruMembers[i].Report(Parents);\n    end;\n\n  defReported := True;\nend;\n\nfunction wbReadInteger24(aBasePtr: pointer): Int64;\nvar\n  Buffer : array[0..3] of Byte;\nbegin\n  Result := 0;\n  Buffer[3] := 0;\n  Buffer[2] := PByte(aBasePtr)^; aBasePtr := Pointer(Cardinal(aBasePtr)+1);\n  Buffer[1] := PByte(aBasePtr)^; aBasePtr := Pointer(Cardinal(aBasePtr)+1);\n  Buffer[0] := PByte(aBasePtr)^;\n  Move(Buffer, Result, SizeOf(Result));\nend;\n\nprocedure WriteInteger24(aBasePtr: pointer; aValue: Int64);\nvar\n  Buffer : array[0..3] of Byte;\nbegin\n  Move(aValue, Buffer, SizeOf(aValue));\n  PByte(aBasePtr)^ := Buffer[2]; aBasePtr := Pointer(Cardinal(aBasePtr)+1);\n  PByte(aBasePtr)^ := Buffer[1]; aBasePtr := Pointer(Cardinal(aBasePtr)+1);\n  PByte(aBasePtr)^ := Buffer[0];\nend;\n\nfunction ReadIntegerCounterSize(aBasePtr: pointer): Int64;\nvar\n  Key : Byte;\nbegin\n  if Assigned(aBasePtr) then begin\n    Key := $3 and PByte(aBasePtr)^; // The counter length is coded into the 2 least significant bits\n    case key of\n      0: Result := 1;\n      1: Result := 2;\n      2: Result := 4;\n    else\n      Result := 1;\n    end\n  end else\n    Result := 1; // Minimum size\nend;\n\nfunction ReadIntegerCounter(aBasePtr: pointer): Int64;\nvar\n  Key    : Byte;\nbegin\n  Result := 0;\n  if Assigned(aBasePtr) then begin\n    Key := $3 and PByte(aBasePtr)^; // The counter length is coded into the 2 least significant bits\n    case key of\n      0: Move(PByte(aBasePtr)^,     Result, 1); // The 6 remaining bits are the count.\n      1: Move(PWord(aBasePtr)^,     Result, 2); // 6 + 8 bits of count\n      2: Move(PCardinal(aBasePtr)^, Result, 4); // 6 + 24 bits of count\n      3: ; // Not supposed to exist : zeroed out by the engine\n    end;\n    Result := Result shr 2;\n  end;\nend;\n\nprocedure WriteIntegerCounter(aBasePtr: pointer; aValue: Int64);\nvar\n  Buffer : array[0..3] of Byte;\nbegin\n  if Assigned(aBasePtr) then begin\n    Move(aValue, Buffer, SizeOf(aValue));\n    if Buffer[3] > 0 then begin // 4 bytes counter\n      Buffer[3] := (Buffer[3] shl 2 ) or 3;\n      PByte(aBasePtr)^ := Buffer[3]; aBasePtr := Pointer(Cardinal(aBasePtr)+1);\n      PByte(aBasePtr)^ := Buffer[2]; aBasePtr := Pointer(Cardinal(aBasePtr)+1);\n      PByte(aBasePtr)^ := Buffer[1]; aBasePtr := Pointer(Cardinal(aBasePtr)+1);\n      PByte(aBasePtr)^ := Buffer[0];\n    end else if Buffer[2] > 0 then begin\n      Buffer[2] := (Buffer[3] shl 2 ) or 2;\n      PByte(aBasePtr)^ := Buffer[2]; aBasePtr := Pointer(Cardinal(aBasePtr)+1);\n      PByte(aBasePtr)^ := Buffer[1]; aBasePtr := Pointer(Cardinal(aBasePtr)+1);\n      PByte(aBasePtr)^ := Buffer[0];\n    end else if Buffer[1] > 0 then begin\n      Buffer[1] := (Buffer[1] shl 2 ) or 1;\n      PByte(aBasePtr)^ := Buffer[1]; aBasePtr := Pointer(Cardinal(aBasePtr)+1);\n      PByte(aBasePtr)^ := Buffer[0];\n    end else begin\n      Buffer[0] := (Buffer[0] shl 2 ) or 0;\n      PByte(aBasePtr)^ := Buffer[0];\n    end;\n  end;\nend;\n\n{ TwbIntegerDef }\n\nfunction TwbIntegerDef.Assign(const aTarget : IwbElement;\n                                    aIndex  : Integer;\n                              const aSource : IwbElement;\n                                    aOnlySK : Boolean)\n                                            : IwbElement;\nbegin\n  if Assigned(inFormater) then\n    Result := inFormater.Assign(aTarget, aIndex, aSource, aOnlySK)\n  else\n    Result := inherited Assign(aTarget, aIndex, aSource, aOnlySK)\nend;\n\nprocedure TwbIntegerDef.BuildRef(aBasePtr, aEndPtr: Pointer; const aElement: IwbElement);\nvar\n  Value       : Int64;\nbegin\n  if Assigned(inFormater) then\n    if (Cardinal(aEndPtr) - Cardinal(aBasePtr)) >= GetExpectedLength then begin\n      case inType of\n        itU8:  Value := PByte(aBasePtr)^;\n        itS8:  Value := PShortInt(aBasePtr)^;\n        itU16: Value := PWord(aBasePtr)^;\n        itS16: Value := PSmallInt(aBasePtr)^;\n        itU24: Value := wbReadInteger24(aBasePtr);\n        itU32: Value := PCardinal(aBasePtr)^;\n        itS32: Value := PLongInt(aBasePtr)^;\n        itU64: Value := PUInt64(aBasePtr)^; //no U64 in delphi...\n        itS64: Value := PInt64(aBasePtr)^;\n        itU6to30: Value := ReadIntegerCounter(aBasePtr);\n      else\n        {it0:}  Value := 0;\n      end;\n      inFormater.BuildRef(Value, aElement);\n    end;\nend;\n\nfunction TwbIntegerDef.CanAssign(const aElement: IwbElement; aIndex: Integer; const aDef: IwbDef): Boolean;\nvar\n  IntegerDef : IwbIntegerDef;\nbegin\n  Result := Supports(aDef, IwbIntegerDef, IntegerDef);\n  if Result then begin\n    if Assigned(inFormater) then\n      Result := inFormater.CanAssign(aElement, aIndex, IntegerDef.Formater[aElement])\n    else if Assigned(IntegerDef.Formater[aElement]) then\n      Result := IntegerDef.Formater[aElement].CanAssign(aElement, aIndex, GetFormater(aElement));\n  end else\n    if Assigned(inFormater) then\n      Result := inFormater.CanAssign(aElement, aIndex, aDef);\nend;\n\nfunction TwbIntegerDef.CanContainFormIDs: Boolean;\nbegin\n  Result := Assigned(inFormater) and (inFormater.CanContainFormIDs);\nend;\n\nfunction TwbIntegerDef.Check(aBasePtr, aEndPtr: Pointer; const aElement: IwbElement): string;\nvar\n  Len         : Cardinal;\n  Value       : Int64;\nbegin\n  Result := '';\n  Len := Cardinal(aEndPtr) - Cardinal(aBasePtr);\n  if Len < GetExpectedLength then begin\n    if wbCheckExpectedBytes then\n      Result := Format('Expected %d bytes of data, found %d', [GetExpectedLength , Len])\n  end else begin\n    case inType of\n      itU8:  Value := PByte(aBasePtr)^;\n      itS8:  Value := PShortInt(aBasePtr)^;\n      itU16: Value := PWord(aBasePtr)^;\n      itS16: Value := PSmallInt(aBasePtr)^;\n      itU24: Value := wbReadInteger24(aBasePtr);\n      itU32: Value := PCardinal(aBasePtr)^;\n      itS32: Value := PLongInt(aBasePtr)^;\n      itU64: Value := PUInt64(aBasePtr)^; //no U64 in delphi...\n      itS64: Value := PInt64(aBasePtr)^;\n      itU6to30: Value := ReadIntegerCounter(aBasePtr);\n    else\n      {itU0:}  Value := 0;\n    end;\n    if Assigned(inFormater) then\n      Result := inFormater.Check(Value, aElement)\n    else\n      Result := '';\n  end;\nend;\n\nconstructor TwbIntegerDef.Clone(const aSource: TwbDef);\nbegin\n  with aSource as TwbIntegerDef do\n    Self.Create(defPriority, defRequired, noName, inType, inFormater, noDontShow, noAfterSet, inDefault, defGetCP, noTerminator).defSource := aSource;\nend;\n\nfunction TwbIntegerDef.CompareExchangeFormID(aBasePtr, aEndPtr: Pointer; const aElement: IwbElement; aOldFormID, aNewFormID: Cardinal): Boolean;\nvar\n  i: Int64;\nbegin\n  if Assigned(inFormater) then begin\n    i := ToInt(aBasePtr, aEndPtr, aElement);\n    Result := inFormater.CompareExchangeFormID(i, aOldFormID, aNewFormID, aElement);\n    if Result then\n      FromInt(i, aBasePtr, aEndPtr, aElement);\n  end else\n    Result := inherited CompareExchangeFormID(aBasePtr, aEndPtr, aElement, aOldFormID, aNewFormID);\nend;\n\nconstructor TwbIntegerDef.Create(aPriority   : TwbConflictPriority;\n                                 aRequired   : Boolean;\n                           const aName       : string;\n                           const aIntType    : TwbIntType;\n                           const aFormater   : IwbIntegerDefFormater;\n                                 aDontShow   : TwbDontShowCallback;\n                                 aAfterSet   : TwbAfterSetCallback;\n                                 aDefault    : Int64;\n                                 aGetCP      : TwbGetConflictPriority;\n                                 aTerminator : Boolean);\nbegin\n  inDefault := aDefault;\n  inType := aIntType;\n  if Assigned(aFormater) then\n  inFormater := (aFormater as IwbDefInternal).SetParent(Self, False) as IwbIntegerDefFormater;\n  inherited Create(aPriority, aRequired, aName, nil, aAfterSet, aDontShow, aGetCP, aTerminator);\nend;\n\nprocedure TwbIntegerDef.FindUsedMasters(aBasePtr, aEndPtr: Pointer; const aElement: IwbElement; aMasters: PwbUsedMasters);\nbegin\n  if Assigned(inFormater) then\n    inFormater.FindUsedMasters(ToInt(aBasePtr, aEndPtr, aElement), aMasters, aElement)\n  else\n    inherited FindUsedMasters(aBasePtr, aEndPtr, aElement, aMasters);\nend;\n\nprocedure TwbIntegerDef.FromEditValue(aBasePtr, aEndPtr: Pointer; const aElement: IwbElement; const aValue: string);\nvar\n  i: Int64;\nbegin\n  if aValue = '' then\n    i := 0\n  else if Assigned(inFormater) then\n    i := inFormater.FromEditValue(aValue, aElement)\n  else\n    i := StrToInt64(aValue);\n  FromInt(i, aBasePtr, aEndPtr, aElement);\nend;\n\nprocedure TwbIntegerDef.FromInt(aValue: Int64; aBasePtr, aEndPtr: Pointer; const aElement: IwbElement);\nbegin\n  aElement.RequestStorageChange(aBasePtr, aEndPtr, GetExpectedLength(aValue));\n  case inType of\n    itU8:  PByte(aBasePtr)^ := aValue;\n    itS8:  PShortInt(aBasePtr)^ := aValue;\n    itU16: PWord(aBasePtr)^ := aValue;\n    itS16: PSmallInt(aBasePtr)^ := aValue;\n    itU24: WriteInteger24(aBasePtr, aValue);\n    itU32: PCardinal(aBasePtr)^ := aValue;\n    itS32: PLongInt(aBasePtr)^ := aValue;\n    itU64: PUInt64(aBasePtr)^ := aValue;\n    itS64: PInt64(aBasePtr)^ := aValue;\n    itU6to30: WriteIntegerCounter(aBasePtr, aValue);\n  else\n    {it0: }\n  end;\nend;\n\nprocedure TwbIntegerDef.FromNativeValue(aBasePtr, aEndPtr: Pointer; const aElement: IwbElement; const aValue: Variant);\nbegin\n  aElement.RequestStorageChange(aBasePtr, aEndPtr, GetExpectedLength(aValue));\n  case inType of\n    itS8:  PShortInt(aBasePtr)^ := aValue;\n    itU16: PWord(aBasePtr)^ := aValue;\n    itS16: PSmallInt(aBasePtr)^ := aValue;\n    itU24: WriteInteger24(aBasePtr, aValue);\n    itU32: PCardinal(aBasePtr)^ := aValue;\n    itS32: PLongInt(aBasePtr)^ := aValue;\n    itU64: PUInt64(aBasePtr)^ := aValue;\n    itS64: PInt64(aBasePtr)^ := aValue;\n    itU6to30: WriteIntegerCounter(aBasePtr, aValue);\n  else\n    PByte(aBasePtr)^ := aValue;\n  end;\nend;\n\nfunction TwbIntegerDef.GetDefType: TwbDefType;\nbegin\n  Result := dtInteger;\nend;\n\nfunction TwbIntegerDef.GetDefTypeName: string;\nbegin\n  if Assigned(inFormater) then\n    Result := inFormater.GetDefTypeName\n  else case inType of\n    itS8:  Result := 'Signed Byte';\n    itU16: Result := 'Unsigned Word';\n    itS16: Result := 'Signed Word';\n    itU24: Result := 'RefID';\n    itU32: Result := 'Unsigned DWord';\n    itS32: Result := 'Signed DWord';\n    itU64: Result := 'Unsigned QWord';\n    itS64: Result := 'Signed QWord';\n    itU6to30: Result := 'Counter';\n  else\n    Result := 'Unsigned Byte';\n  end;\nend;\n\nfunction TwbIntegerDef.GetEditInfo(aBasePtr, aEndPtr: Pointer; const aElement: IwbElement): string;\nbegin\n  if Assigned(inFormater) then\n    Result := inFormater.EditInfo[ToInt(aBasePtr, aEndPtr, aElement), aElement]\n  else\n    Result := inherited GetEditInfo(aBasePtr, aEndPtr, aElement);\nend;\n\nfunction TwbIntegerDef.GetEditType(aBasePtr, aEndPtr: Pointer; const aElement: IwbElement): TwbEditType;\nbegin\n  if Assigned(inFormater) then\n    Result := inFormater.EditType[ToInt(aBasePtr, aEndPtr, aElement), aElement]\n  else\n    Result := inherited GetEditType(aBasePtr, aEndPtr, aElement);\nend;\n\nfunction TwbIntegerDef.GetExpectedLength(aValue: Int64 = 0): Integer;\nconst\n  ExpectedLen : array[TwbIntType] of Cardinal = (\n    0, 1, 1, 2, 2, 4, 4, 8, 8, 3, 1\n  );\nbegin\n  if inType = it0  then\n    Result := 0\n  else begin\n    Result := ExpectedLen[inType]+Ord(noTerminator);\n    if (inType=itU6to30) and (aValue<>0) then\n      case (aValue and 3) of\n        0 : Result := 1 + Ord(noTerminator);\n        1 : Result := 2 + Ord(noTerminator);\n        2 : Result := 4 + Ord(noTerminator);\n      end;\n  end;\nend;\n\nfunction TwbIntegerDef.GetFormater(const aElement: IwbElement): IwbIntegerDefFormater;\nvar\n  Union: IwbIntegerDefFormaterUnion;\nbegin\n  Result := inFormater;\n  while Supports(Result, IwbIntegerDefFormaterUnion, Union) do\n    Result := Union.Decide(aElement);\nend;\n\nfunction TwbIntegerDef.GetFormaterCanChange: Boolean;\nbegin\n  Result := Supports(inFormater, IwbIntegerDefFormaterUnion);\nend;\n\nfunction TwbIntegerDef.GetIntType: TwbIntType;\nbegin\n  Result := inType;\nend;\n\nfunction TwbIntegerDef.GetIsEditable(aBasePtr, aEndPtr: Pointer; const aElement: IwbElement): Boolean;\nbegin\n  Result := wbIsInternalEdit or (not Assigned(inFormater) or inFormater.IsEditable[ToInt(aBasePtr, aEndPtr, aElement), aElement]);\nend;\n\nfunction TwbIntegerDef.GetLinksTo(aBasePtr, aEndPtr: Pointer; const aElement: IwbElement): IwbElement;\nvar\n  Value       : Int64;\nbegin\n  Result := nil;\n  if Assigned(inFormater) then\n    if (Cardinal(aEndPtr) - Cardinal(aBasePtr)) >= GetExpectedLength then begin\n      case inType of\n        itU8:  Value := PByte(aBasePtr)^;\n        itS8:  Value := PShortInt(aBasePtr)^;\n        itU16: Value := PWord(aBasePtr)^;\n        itS16: Value := PSmallInt(aBasePtr)^;\n        itU24: Value := wbReadInteger24(aBasePtr);\n        itU32: Value := PCardinal(aBasePtr)^;\n        itS32: Value := PLongInt(aBasePtr)^;\n        itU64: Value := PUInt64(aBasePtr)^; //no U64 in delphi...\n        itS64: Value := PInt64(aBasePtr)^;\n        itU6to30: Value := ReadIntegerCounter(aBasePtr);\n      else\n        {it0:}  Value := 0;\n      end;\n      Result := inFormater.LinksTo[Value, aElement];\n    end;\nend;\n\nfunction TwbIntegerDef.GetNoReach: Boolean;\nbegin\n  Result := Assigned(inFormater) and inFormater.NoReach;\nend;\n\nfunction TwbIntegerDef.GetSize(aBasePtr, aEndPtr: Pointer; const aElement: IwbElement): Integer;\nbegin\n  if inType = it0 then\n    Result := 0\n  else if Assigned(aBasePtr) and Assigned(aEndPtr) and (Cardinal(aBasePtr)<Cardinal(aEndPtr)) then\n    case inType of\n      itU8:  Result := SizeOf(Byte)+Ord(noTerminator);\n      itS8:  Result := SizeOf(ShortInt)+Ord(noTerminator);\n      itU16: Result := SizeOf(Word)+Ord(noTerminator);\n      itS16: Result := SizeOf(SmallInt)+Ord(noTerminator);\n      itU24: Result := 3*SizeOf(Byte)+Ord(noTerminator);\n      itU32: Result := SizeOf(Cardinal)+Ord(noTerminator);\n      itS32: Result := SizeOf(LongInt)+Ord(noTerminator);\n      itU64: Result := SizeOf(UInt64)+Ord(noTerminator);\n      itS64: Result := SizeOf(Int64)+Ord(noTerminator);\n      itU6to30: Result := ReadIntegerCounterSize(aBasePtr)+Ord(noTerminator);\n    else\n      Result := 0;\n    end\n  else\n    Result := GetDefaultSize(aBasePtr, aEndPtr, aElement);\nend;\n\nfunction TwbIntegerDef.GetDefaultSize(aBasePtr, aEndPtr: Pointer; const aElement: IwbElement): Integer;\nbegin\n  case inType of\n    itU8:  Result := SizeOf(Byte)+Ord(noTerminator);\n    itS8:  Result := SizeOf(ShortInt)+Ord(noTerminator);\n    itU16: Result := SizeOf(Word)+Ord(noTerminator);\n    itS16: Result := SizeOf(SmallInt)+Ord(noTerminator);\n    itU24: Result := 3*SizeOf(Byte)+Ord(noTerminator);\n    itU32: Result := SizeOf(Cardinal)+Ord(noTerminator);\n    itS32: Result := SizeOf(LongInt)+Ord(noTerminator);\n    itU64: Result := SizeOf(UInt64)+Ord(noTerminator);\n    itS64: Result := SizeOf(Int64)+Ord(noTerminator);\n    itU6to30: Result := 1+Ord(noTerminator);\n  else\n    {it0:} Result := 0;\n  end;\nend;\n\nprocedure TwbIntegerDef.MasterCountUpdated(aBasePtr, aEndPtr: Pointer; const aElement: IwbElement; aOld, aNew: Byte);\nvar\n  OldValue : Int64;\n  NewValue : Int64;\nbegin\n  if Assigned(inFormater) then begin\n    OldValue := ToInt(aBasePtr, aEndPtr, aElement);\n    NewValue := inFormater.MasterCountUpdated(OldValue, aOld, aNew, aElement);\n    if OldValue <> NewValue then\n      FromInt(NewValue, aBasePtr, aEndPtr, aElement)\n  end else\n    inherited MasterCountUpdated(aBasePtr, aEndPtr, aElement, aOld, aNew);\nend;\n\nprocedure TwbIntegerDef.MasterIndicesUpdated(aBasePtr, aEndPtr: Pointer; const aElement: IwbElement; const aOld, aNew: TBytes);\nvar\n  OldValue : Int64;\n  NewValue : Int64;\nbegin\n  if Assigned(inFormater) then begin\n    OldValue := ToInt(aBasePtr, aEndPtr, aElement);\n    NewValue := inFormater.MasterIndicesUpdated(OldValue, aOld, aNew, aElement);\n    if OldValue <> NewValue then\n      FromInt(NewValue, aBasePtr, aEndPtr, aElement)\n  end else\n    inherited MasterIndicesUpdated(aBasePtr, aEndPtr, aElement, aOld, aNew);\nend;\n\nprocedure TwbIntegerDef.ReplaceFormater(const aFormater: IwbIntegerDefFormater);\nbegin\n  defSource := nil;\n  if Assigned(aFormater) then\n    inFormater := (aFormater as IwbDefInternal).SetParent(Self, True) as IwbIntegerDefFormater\n  else\n    inFormater := nil\nend;\n\nprocedure TwbIntegerDef.Report(const aParents: TwbDefPath);\nvar\n  Parents : TwbDefPath;\nbegin\n  if defReported then\n    Exit;\n\n  inherited;\n  if Assigned(inFormater) then begin\n    Parents := aParents;\n    SetLength(Parents, Succ(Length(Parents)));\n    Parents[High(Parents)].Def := Self;\n    Parents[High(Parents)].Index := -1;\n    inFormater.Report(aParents);\n  end;\n\n  defReported := True;\nend;\n\nfunction TwbIntegerDef.SetToDefault(aBasePtr, aEndPtr: Pointer; const aElement: IwbElement): Boolean;\nbegin\n  Result := not Assigned(aBasePtr) or (ToInt(aBasePtr, aEndPtr, aElement) <> inDefault);\n  if Result then\n    FromInt(inDefault, aBasePtr, aEndPtr, aElement);\nend;\n\nfunction IntToHex64(Value: Int64; Digits: Integer): string;\nbegin\n  Result := IntToHex(Value, Digits);\nend;\n\n\nfunction TwbIntegerDef.ToEditValue(aBasePtr, aEndPtr: Pointer;\n  const aElement: IwbElement): string;\nvar\n  Len   : Cardinal;\n  Value : Int64;\nconst\n  PlusMinus : array[Boolean] of string = ('+', '-');\nbegin\n  Len := Cardinal(aEndPtr) - Cardinal(aBasePtr);\n  if (Len < GetExpectedLength) or (inType = it0) then\n    Result := ''\n  else begin\n    case inType of\n      itU8:  Value := PByte(aBasePtr)^;\n      itS8:  Value := PShortInt(aBasePtr)^;\n      itU16: Value := PWord(aBasePtr)^;\n      itS16: Value := PSmallInt(aBasePtr)^;\n      itU24: Value := wbReadInteger24(aBasePtr);\n      itU32: Value := PCardinal(aBasePtr)^;\n      itS32: Value := PLongInt(aBasePtr)^;\n      itU64: Value := PUInt64(aBasePtr)^; //no U64 in delphi...\n      itS64: Value := PInt64(aBasePtr)^;\n      itU6to30: Value := ReadIntegerCounter(aBasePtr);\n    else\n      {it0:}  Value := 0;\n    end;\n\n    Result := '';\n    if Assigned(inFormater) then\n      Result := inFormater.ToEditValue(Value, aElement);\n\n    if Result = '' then\n      Result := IntToStr(Value);\n  end;\nend;\n\nfunction TwbIntegerDef.ToInt(aBasePtr, aEndPtr: Pointer; const aElement: IwbElement): Int64;\nvar\n  Len         : Cardinal;\nbegin\n  Len := Cardinal(aEndPtr) - Cardinal(aBasePtr);\n  if Len < GetExpectedLength then\n    Result := 0\n  else\n    case inType of\n      itU8:  Result := PByte(aBasePtr)^;\n      itS8:  Result := PShortInt(aBasePtr)^;\n      itU16: Result := PWord(aBasePtr)^;\n      itS16: Result := PSmallInt(aBasePtr)^;\n      itU24: Result := wbReadInteger24(aBasePtr);\n      itU32: Result := PCardinal(aBasePtr)^;\n      itS32: Result := PLongInt(aBasePtr)^;\n      itU64: Result := PUInt64(aBasePtr)^; //no U64 in delphi...\n      itS64: Result := PInt64(aBasePtr)^;\n      itU6to30: Result := ReadIntegerCounter(aBasePtr);\n    else\n      {it0:}  Result := 0;\n    end;\nend;\n\nfunction TwbIntegerDef.ToNativeValue(aBasePtr, aEndPtr: Pointer; const aElement: IwbElement): Variant;\nbegin\n  if (Cardinal(aEndPtr) - Cardinal(aBasePtr)) < GetExpectedLength then\n    VarClear(Result)\n  else\n    case inType of\n      itU8:  Result := PByte(aBasePtr)^;\n      itS8:  Result := PShortInt(aBasePtr)^;\n      itU16: Result := PWord(aBasePtr)^;\n      itS16: Result := PSmallInt(aBasePtr)^;\n      itU24: Result := wbReadInteger24(aBasePtr);\n      itU32: Result := PCardinal(aBasePtr)^;\n      itS32: Result := PLongInt(aBasePtr)^;\n      itU64: Result := PUInt64(aBasePtr)^; //no U64 in delphi...\n      itS64: Result := PInt64(aBasePtr)^;\n      itU6to30: Result := ReadIntegerCounter(aBasePtr);\n    else\n      {it0:}  Result := 0;\n    end;\nend;\n\nfunction TwbIntegerDef.ToSortKey(aBasePtr, aEndPtr: Pointer; const aElement: IwbElement; aExtended: Boolean): string;\nvar\n  Len   : Cardinal;\n  Value : Int64;\nconst\n  PlusMinus : array[Boolean] of string = ('+', '-');\nbegin\n  Len := Cardinal(aEndPtr) - Cardinal(aBasePtr);\n  if Len < GetExpectedLength then\n    if Assigned(inFormater) and inFormater.RequiresKey then\n      Result := inFormater.ToSortKey(0, aElement)\n    else\n      Result := ''\n  else begin\n    case inType of\n      itU8:  Value := PByte(aBasePtr)^;\n      itS8:  Value := PShortInt(aBasePtr)^;\n      itU16: Value := PWord(aBasePtr)^;\n      itS16: Value := PSmallInt(aBasePtr)^;\n      itU24: Value := wbReadInteger24(aBasePtr);\n      itU32: Value := PCardinal(aBasePtr)^;\n      itS32: Value := PLongInt(aBasePtr)^;\n      itU64: Value := PUInt64(aBasePtr)^; //no U64 in delphi...\n      itS64: Value := PInt64(aBasePtr)^;\n      itU6to30: Value := ReadIntegerCounter(aBasePtr);\n    else\n      {it0:}  Value := 0;\n    end;\n\n    Result := '';\n    if Assigned(inFormater) then\n      Result := inFormater.ToSortKey(Value, aElement);\n\n    if Result = '' then begin\n      case inType of\n        itS8:  Value := Value + Abs(Int64(Low(ShortInt)));\n        itS16: Value := Value + Abs(Int64(Low(SmallInt)));\n        itS32: Value := Value + Abs(Int64(Low(LongInt)));\n        itS64: Value := Value + Abs(Int64(Low(Int64)));\n      end;\n      Result := Result + IntToHex64(Value, Succ(GetExpectedLength(Value) * 2));\n    end;\n  end;\nend;\n\nfunction TwbIntegerDef.ToString(aBasePtr, aEndPtr: Pointer; const aElement: IwbElement): string;\nvar\n  Len         : Cardinal;\n  Value       : Int64;\nbegin\n  Result := '';\n\n  if inType = it0 then\n    Exit;\n\n  Len := Cardinal(aEndPtr) - Cardinal(aBasePtr);\n  if Len < GetExpectedLength then begin\n    if wbCheckExpectedBytes then\n      Result := Format('<Error: Expected %d bytes of data, found %d>', [GetExpectedLength, Len])\n  end else begin\n    case inType of\n      itU8:  Value := PByte(aBasePtr)^;\n      itS8:  Value := PShortInt(aBasePtr)^;\n      itU16: Value := PWord(aBasePtr)^;\n      itS16: Value := PSmallInt(aBasePtr)^;\n      itU24: Value := wbReadInteger24(aBasePtr);\n      itU32: Value := PCardinal(aBasePtr)^;\n      itS32: Value := PLongInt(aBasePtr)^;\n      itU64: Value := PUInt64(aBasePtr)^; //no U64 in delphi...\n      itS64: Value := PInt64(aBasePtr)^;\n      itU6to30: Value := ReadIntegerCounter(aBasePtr);\n    else\n      {it0:}  Value := 0;\n    end;\n    if Assigned(inFormater) then\n      Result := inFormater.ToString(Value, aElement)\n    else\n      Result := IntToStr(Value);\n    if (Len > GetExpectedLength) and not (inType in [itU6to30]) then begin\n      if wbCheckExpectedBytes then\n        Result := Result + Format(' <Warning: Expected %d bytes of data, found %d>', [GetExpectedLength , Len])\n    end;\n  end;\n  Used(aElement, Result);\nend;\n\n{ TwbArrayDef }\n\nconstructor TwbArrayDef.Create(aPriority   : TwbConflictPriority;\n                               aRequired   : Boolean;\n                         const aName       : string;\n                         const aElement    : IwbValueDef;\n                               aCount      : Integer;\n                         const aLabels     : array of string;\n                               aSorted     : Boolean;\n                               aAfterLoad  : TwbAfterLoadCallback;\n                               aAfterSet   : TwbAfterSetCallback;\n                               aDontShow   : TwbDontShowCallback;\n                               aGetCP      : TwbGetConflictPriority;\n                               aCanAddTo   : Boolean;\n                               aTerminator : Boolean;\n                               aTerminated : Boolean);\nvar\n  i: Integer;\nbegin\n  Assert((not aSorted) or (Length(aLabels) < 1));\n\n  SetLength(arLabels, Length(aLabels));\n  for i := Low(arLabels) to High(arLabels) do\n    arLabels[i] := aLabels[i];\n\n  arCount := aCount;\n  if Assigned(aElement) then\n    arElement := (aElement as IwbDefInternal).SetParent(Self, False) as IwbValueDef;\n  arSorted := aSorted;\n  arCanAddTo := aCanAddTo;\n  arTerminated := aTerminated;\n  inherited Create(aPriority, aRequired, aName, aAfterLoad, aAfterSet, aDontShow, aGetCP, aTerminator);\nend;\n\nfunction TwbArrayDef.CanAssign(const aElement: IwbElement; aIndex: Integer; const aDef: IwbDef): Boolean;\nvar\n  ArrayDef: IwbArrayDef;\nbegin\n  Result := (aIndex = Low(Integer)) and\n    Supports(aDef, IwbArrayDef, ArrayDef) and\n    ( ( arCount <= 0 ) or (arCount = ArrayDef.ElementCount) ) and\n    arElement.CanAssign(aElement, aIndex, ArrayDef.Element);\nend;\n\nfunction TwbArrayDef.CanContainFormIDs: Boolean;\nbegin\n  Result := arElement.CanContainFormIDs;\nend;\n\nconstructor TwbArrayDef.Clone(const aSource: TwbDef);\nbegin\n  with aSource as TwbArrayDef do\n    if Assigned(arCountCallback) then\n      Self.Create(defPriority, defRequired, noName, arElement, arCountCallback,\n        arLabels, arSorted, noAfterLoad, noAfterSet, noDontShow, defGetCP, arCanAddTo, noTerminator, arTerminated).defSource := aSource\n    else\n      Self.Create(defPriority, defRequired, noName, arElement, arCount,\n        arLabels, arSorted, noAfterLoad, noAfterSet, noDontShow, defGetCP, arCanAddTo, noTerminator, arTerminated).defSource := aSource;\nend;\n\nconstructor TwbArrayDef.Create(aPriority      : TwbConflictPriority;\n                               aRequired      : Boolean;\n                         const aName          : string;\n                         const aElement       : IwbValueDef;\n                               aCountCallback : TwbCountCallback;\n                         const aLabels        : array of string;\n                               aSorted        : Boolean;\n                               aAfterLoad     : TwbAfterLoadCallback;\n                               aAfterSet      : TwbAfterSetCallback;\n                               aDontShow      : TwbDontShowCallback;\n                               aGetCP         : TwbGetConflictPriority;\n                               aCanAddTo      : Boolean;\n                               aTerminator    : Boolean;\n                               aTerminated    : Boolean);\nbegin\n  arCountCallback := aCountCallback;\n  Create(aPriority, aRequired, aName, aElement, 0, aLabels, aSorted, aAfterLoad, aAfterSet, aDontShow, aGetCP, aCanAddTo, aTerminator, aTerminated);\nend;\n\nfunction TwbArrayDef.GetCanAddTo: Boolean;\nbegin\n  Result := arCanAddTo;\nend;\n\nfunction TwbArrayDef.GetCanBeZeroSize: Boolean;\nbegin\n  Result := True;\nend;\n\nfunction TwbArrayDef.GetCount: Integer;\nbegin\n  Result := arCount;\nend;\n\nfunction TwbArrayDef.GetCountCallBack: TwbCountCallback;\nbegin\n  Result := arCountCallBack;\nend;\n\nfunction TwbArrayDef.GetDefType: TwbDefType;\nbegin\n  Result := dtArray;\nend;\n\nfunction TwbArrayDef.GetDefTypeName: string;\nvar\n  Prefix: Integer;\nbegin\n  if arCount < 0 then begin\n    if arCount < -1 then\n      if arCount < -2 then\n        Prefix := 1\n      else\n        Prefix := 2\n    else\n      Prefix := 4;\n    if noTerminator then\n      Result := 'Separated Array with '+IntToStr(Prefix)+' Bytes Counter of '\n    else\n      Result := 'Array with '+IntToStr(Prefix)+' Bytes Counter of ';\n  end else begin\n    if (arCount < 1) and Assigned(arCountCallback) then\n      if noTerminator then\n        Result := 'Separated Variable Count Array'\n      else\n        Result := 'Variable Count Array'\n    else if arCount > 0 then\n      if noTerminator then\n        Result := 'Separated Array of '+IntToStr(arCount)+' '\n      else\n        Result := 'Array of '+IntToStr(arCount)+' '\n    else\n      if noTerminator then\n          Result := 'Separated Array of '\n      else\n        Result := 'Array of ';\n  end;\n  Result := Result + GetElement.GetDefTypeName;\nend;\n\nfunction TwbArrayDef.GetElement: IwbValueDef;\nbegin\n  Result := arElement;\nend;\n\nfunction TwbArrayDef.GetElementLabel(aIndex: Integer): string;\nbegin\n  if (aIndex >= Low(arLabels)) and (aIndex <= High(arLabels)) then\n    Result := arLabels[aIndex]\n  else\n    Result := '';\nend;\n\nfunction TwbArrayDef.GetIsVariableSizeInternal: Boolean;\nbegin\n  Result := (arCount <= 0) or arElement.IsVariableSize;\nend;\n\nfunction TwbArrayDef.GetPrefixCount(aBasePtr: Pointer): Cardinal;\nvar\n  Count : int64;\nbegin\n  Result := 0;\n  if arCount = -255 then\n    Result := 0\n  else if arCount = -254 then\n    Result := ReadIntegerCounter(aBasePtr)\n  else if arCount = -253 then begin  // Matrix of count * count\n    Count := ReadIntegerCounter(aBasePtr);\n    Result := Count * Count;\n  end\n  else if arCount = -241 then begin  // Matrix of cardinal * cardinal\n    Count := PCardinal(aBasePtr)^;\n    Result := Count * Count;\n  end\n  else if Assigned(aBasePtr) then\n    case GetPrefixlength(aBasePtr) of\n      1: Result := PByte(aBasePtr)^;\n      2: Result := PWord(aBasePtr)^;\n      4: Result := PCardinal(aBasePtr)^;\n    end;\nend;\n\nfunction TwbArrayDef.GetPrefixLength(aBasePtr: Pointer): Integer;\nbegin\n  Result := 0;\n  if arCount < 0 then\n    if arCount = -1 then\n      Result := 4\n    else if arCount = -2 then\n      Result := 2\n    else if arCount = -4 then\n      Result := 1\n    else if arCount = -241 then\n      Result := 4\n    else if arCount = -253 then\n      Result := ReadIntegerCounterSize(aBasePtr)\n    else if arCount = -254 then\n      Result := ReadIntegerCounterSize(aBasePtr);\nend;\n\nfunction TwbArrayDef.GetPrefixSize(aBasePtr: Pointer): Integer;\nbegin\n  Result := GetPrefixLength(aBasePtr);\n  if (Result>0) and noTerminator then\n    Inc(Result);\nend;\n\nfunction TwbArrayDef.GetSize(aBasePtr, aEndPtr: Pointer; const aElement: IwbElement): Integer;\nvar\n  Prefix           : Integer;\n  Count            : Integer;\n  Index            : Integer; // Used instead of count for easier debugging output.\n  Size             : Integer;\n  BasePtr          : Pointer;\n  CheckedContainer : Boolean;\n  ArrayContainer   : IwbContainerElementRef;\n  Element          : IwbElement;\n  DataContainer    : IwbDataContainer;\n  KnownSize        : Boolean;\n//  aName            : String;\n\n  function CheckContainer: IwbContainerElementRef;\n  begin\n    if Assigned(aElement) and (aElement.ValueDef.DefID = GetDefID) then\n      Supports(aElement, IwbContainerElementRef, ArrayContainer);\n    Result := ArrayContainer;\n    CheckedContainer := True;\n  end;\n\n  function Container: IwbContainerElementRef;\n  begin\n    if CheckedContainer then\n      Result := ArrayContainer\n    else\n      Result := CheckContainer;\n  end;\n\nbegin\n  Result := 0;\n  CheckedContainer := False;\n  ArrayContainer := nil;\n\n  if Assigned(aBasePtr) and Assigned(aEndPtr) and (Cardinal(aEndPtr)<Cardinal(aBasePtr)) then begin\n//    wbProgressCallback('Found an array with a negative size! (1) '+IntToHex64(Cardinal(aBasePtr), 8)+\n//      ' > '+IntToHex64(Cardinal(aEndPtr), 8)+'  for '+noName);\n    Exit;\n  end;\n\n  Prefix := GetPrefixSize(aBasePtr);\n  BasePtr := aBasePtr;\n  Count := arCount;\n  if Count < 0 then begin\n    Count := GetPrefixCount(aBasePtr);\n    Result := Prefix;\n  end else begin\n    if (Count < 1) and Assigned(arCountCallback) and not (Container=nil) then\n      Count := arCountCallback(BasePtr, aEndPtr, ArrayContainer);\n\n    if not Assigned(BasePtr) and (Count < 1) and not Assigned(arCountCallback) then // EXPERIMENT: Probably should not be done\n      Count := 1;\n\n    if (Count < 1) and not Assigned(arCountCallback) then begin\n      Result := High(Integer);\n      Exit;\n    end;\n  end;\n\n  if Assigned(BasePtr) then\n    Inc(PByte(BasePtr), Prefix);\n\n  if Count > 0 then\n    if arElement.IsVariableSize then begin\n      if Container = nil then begin // Make sure it won't be used if unassigned, and still delay FindOurself until it is effectivly required\n        if not Assigned(BasePtr) then\n          Result := arElement.DefaultSize[nil, nil, aElement]\n        else\n          Result := High(Integer);\n        Exit;\n      end;\n\n      if ArrayContainer.ElementCount = Count then begin\n        KnownSize := True;\n        for Index := 0 to Pred(Count) do begin\n          Element := ArrayContainer.Elements[Index];\n          if Supports(Element, IwbDataContainer, DataContainer) then begin\n            Size := Cardinal(DataContainer.DataEndPtr)-Cardinal(DataContainer.DataBasePtr);\n            Inc(Result, Size);\n          end else begin\n            KnownSize := False;\n            Break;\n          end;\n        end;\n      end else\n        KnownSize := False;\n\n      Index := 0;\n      if not KnownSize then\n        while (Count > Index) and (Cardinal(BasePtr) < Cardinal(aEndPtr)) do begin\n          Element := ArrayContainer.Elements[Index];\n          if not Assigned(Element) then begin\n            if wbMoreInfoForIndex and (DebugHook <> 0) and Assigned(wbProgressCallback) then\n              wbProgressCallback('Debug: ['+ ArrayContainer.Path +'] Index ' + IntToStr(Index) + ' of ' + IntToStr(Count) + ' greater than max '+\n                IntToStr(ArrayContainer.ElementCount-1));\n            Element := aElement; // If it is too soon, revert to previous way of doing things\n          end;\n          Size := arElement.Size[BasePtr, aEndPtr, Element];\n          if Size = High(Integer) then begin\n            Result := High(Integer);\n            Exit;\n          end;\n          Inc(Result, Size);\n          if Assigned(aBasePtr) and Assigned(aEndPtr) and (Cardinal(aEndPtr)<Cardinal(aBasePtr)+Result) then begin\n//            if Assigned(aBasePtr) and Assigned(aEndPtr) and (aEndPtr<>aBasePtr) then\n//              wbProgressCallback('Found an array with a negative size! (2) '+IntToHex64(Cardinal(aBasePtr)+Result, 8)+\n//                ' > '+IntToHex64(Cardinal(aEndPtr), 8)+'  for '+noName);\n            Result := Cardinal(aEndPtr)-Cardinal(aBasePtr)+Result;\n            Exit;\n          end;\n          if Assigned(BasePtr) then\n            Inc(PByte(BasePtr), Size);\n          Inc(Index);\n        end;\n\n    end else begin\n      if (Container <> nil) and (ArrayContainer.ElementCount > 0) then\n        Element := ArrayContainer.Elements[0]\n      else\n        Element := aElement;\n\n      Size := arElement.Size[BasePtr, aEndPtr, Element];\n      if Size = High(Integer) then begin\n        Result := High(Integer);\n        Exit;\n      end;\n      Result := (Count * Size) + Prefix;\n      if Assigned(aBasePtr) and Assigned(aEndPtr) and (Cardinal(aEndPtr)<Cardinal(aBasePtr)+Result) then begin\n//        if Assigned(aBasePtr) and Assigned(aEndPtr) and (aEndPtr<>aBasePtr) then\n//          wbProgressCallback('Found a static array with a negative size! (3) '+IntToHex64(Cardinal(aBasePtr)+Result, 8)+\n//            ' > '+IntToHex64(Cardinal(aEndPtr), 8)+'  for '+noName);\n        Result := Cardinal(aEndPtr)-Cardinal(aBasePtr);\n        Exit;\n      end;\n    end;\n  Inc(Result, Ord(arTerminated));\nend;\n\nfunction TwbArrayDef.GetDefaultSize(aBasePtr, aEndPtr: Pointer; const aElement: IwbElement): Integer;\nbegin\n  if ((arCount = 0) and not Assigned(arCountCallback)) then\n    Result := 0\n  else\n    Result := GetSize(aBasePtr, aEndPtr, aElement);\nend;\n\nfunction TwbArrayDef.GetSorted: Boolean;\nbegin\n  if wbCopyIsRunning = 0 then\n    Result := arSorted\n  else\n    Result := False;\nend;\n\nprocedure TwbArrayDef.Report(const aParents: TwbDefPath);\nvar\n  Parents : TwbDefPath;\nbegin\n  if defReported then\n    Exit;\n\n  inherited;\n  if Assigned(arElement) then begin\n    Parents := aParents;\n    SetLength(Parents, Succ(Length(Parents)));\n    Parents[High(Parents)].Def := Self;\n    Parents[High(Parents)].Index := -1;\n    arElement.Report(aParents);\n  end;\n\n  defReported := True;\nend;\n\nprocedure TwbArrayDef.SetPrefixCount(aBasePtr: Pointer; aValue: Cardinal);\nbegin\n  if arCount = -255 then\n  else if arCount = -254 then\n    WriteIntegerCounter(aBasePtr, aValue)\n  else if Assigned(aBasePtr) then\n    case GetPrefixlength(aBasePtr) of\n      1: PByte(aBasePtr)^ := aValue;\n      2: PWord(aBasePtr)^ := aValue;\n      4: PCardinal(aBasePtr)^ := aValue;\n    end;\nend;\n\nfunction TwbArrayDef.ToString(aBasePtr, aEndPtr: Pointer; const aElement: IwbElement): string;\nbegin\n  Result := '';\n  Used(aElement, Result);\nend;\n\n{ TwbStructDef }\n\nfunction TwbStructDef.CanAssign(const aElement: IwbElement; aIndex: Integer; const aDef: IwbDef): Boolean;\nvar\n  StructDef : IwbStructDef;\n  i         : Integer;\nbegin\n  Result := (aIndex = Low(Integer)) and\n    Supports(aDef, IwbStructDef, StructDef) and\n    ( GetMemberCount = StructDef.MemberCount);\n  if Result and not Equals(aDef) then\n    for i := 0 to Pred(GetMemberCount) do\n      if not stMembers[i].CanAssign(aElement, Low(Integer), StructDef.Members[i]) then begin\n        Result := False;\n        Exit;\n      end;\nend;\n\nfunction TwbStructDef.CanContainFormIDs: Boolean;\nbegin\n  Result := stCanContainFormIDs;\nend;\n\nconstructor TwbStructDef.Clone(const aSource: TwbDef);\nbegin\n  with aSource as TwbStructDef do\n    Self.Create(defPriority, defRequired, noName, stMembers, stSortKey,\n      stExSortKey, stElementMap, stOptionalFromElement, noDontShow, noAfterLoad, noAfterSet, defGetCP).defSource := aSource;\nend;\n\nconstructor TwbStructDef.Create(aPriority            : TwbConflictPriority;\n                                aRequired            : Boolean;\n                          const aName                : string;\n                          const aMembers             : array of IwbValueDef;\n                          const aSortKey             : array of Integer;\n                          const aExSortKey           : array of Integer;\n                          {$IFDEF WIN32}\n                          const aElementMap          : array of Cardinal;\n                          {$ENDIF WIN32}\n                          {$IFDEF WIN64}\n                          const aElementMap          : array of UInt64;\n                          {$ENDIF WIN64}\n                                aOptionalFromElement : Integer;\n                                aDontShow            : TwbDontShowCallback;\n                                aAfterLoad           : TwbAfterLoadCallback;\n                                aAfterSet            : TwbAfterSetCallback;\n                                aGetCP               : TwbGetConflictPriority);\nvar\n  i: Integer;\nbegin\n  stOptionalFromElement := aOptionalFromElement;\n  SetLength(stMembers, Length(aMembers));\n  for i := Low(stMembers) to High(stMembers) do begin\n    stMembers[i] := (aMembers[i] as IwbDefInternal).SetParent(Self, False) as IwbValueDef;\n    stCanContainFormIDs := stCanContainFormIDs or aMembers[i].CanContainFormIDs;\n  end;\n  SetLength(stSortKey, Length(aSortKey));\n  for i := Low(stSortKey) to High(stSortKey) do\n    stSortKey[i] := aSortKey[i];\n  SetLength(stExSortKey, Length(aExSortKey));\n  for i := Low(stExSortKey) to High(stExSortKey) do\n    stExSortKey[i] := aExSortKey[i];\n  SetLength(stElementMap, Length(aElementMap));\n  for i := Low(stElementMap) to High(stElementMap) do\n    stElementMap[i] := aElementMap[i];\n  if Length(stElementMap) > 0 then begin\n    Assert(Length(stElementMap) = Length(stMembers));\n    // should really check that the element map only contains valid values\n    // and that there are no optional elements...\n  end;\n  inherited Create(aPriority, aRequired, aName, aAfterLoad, aAfterSet, aDontShow, aGetCP, False);\nend;\n\nfunction TwbStructDef.GetDefType: TwbDefType;\nbegin\n  Result := dtStruct;\nend;\n\nfunction TwbStructDef.GetDefTypeName: string;\nbegin\n  Result := 'Structure';\nend;\n\nfunction TwbStructDef.GetElementMap: TDynCardinalArray;\nbegin\n  Result := stElementMap;\nend;\n\nfunction TwbStructDef.GetMember(aIndex: Integer): IwbValueDef;\nbegin\n  Result := stMembers[aIndex];\nend;\n\nfunction TwbStructDef.GetMemberByName(const aName: string): IwbValueDef;\nvar\n  i: Integer;\nbegin\n  for i := Low(stMembers) to High(stMembers) do\n    if SameText(stMembers[i].Name, aName) then\n      Exit(stMembers[i]);\n  Result := nil;\nend;\n\nfunction TwbStructDef.GetMemberCount: Integer;\nbegin\n  Result := Length(stMembers);\nend;\n\nfunction TwbStructDef.GetOptionalFromElement: Integer;\nbegin\n  Result := stOptionalFromElement;\nend;\n\nfunction TwbStructDef.GetSize(aBasePtr, aEndPtr: Pointer; const aElement: IwbElement): Integer;\nvar\n  i         : Integer;\n  Size      : Integer;\n  scDef     : IwbStructCDef;\n  BasePtr   : Pointer;\n  Container : IwbContainerElementRef;\n  Element   : IwbElement;\nbegin\n  Result := 0;\n  if Supports(Self, IwbStructCDef, scDef) then begin\n    scDef.GetSizing(aBasePtr, aEndPtr, aElement, Size);\n    if Size>0 then begin\n      Inc(Result, Size);\n      Exit;\n    end;\n  end;\n  if (Cardinal(aBasePtr) > Cardinal(aEndPtr)) then begin // if aBasePtr >= aEndPtr then no allocation (or error)\n//    wbProgressCallback('Found a struct with a negative size! (1) '+IntToHex64(Cardinal(aBasePtr), 8)+\n//      ' > '+IntToHex64(Cardinal(aEndPtr), 8)+' for '+ noName);\n  end else if (not Assigned(aBasePtr) or (Cardinal(aBasePtr) = Cardinal(aEndPtr))) and (GetIsVariableSizeInternal) then begin\n    Result := 0; // assuming we would have called GetDefaultSize otherwise... GetDefaultSize(aBasePtr, aEndPtr, aElement);\n  end else begin\n    BasePtr := aBasePtr;\n    if GetIsVariableSize and Supports(aElement, IwbContainerElementRef, Container) and Equals(Container.ValueDef) and\n        (Container.ElementCount > 0) then begin\n      for i := 0 to Pred(Container.ElementCount) do begin\n        Element := Container.Elements[i];\n        Size := Element.ValueDef.Size[BasePtr, aEndPtr, Element];\n        if Size = High(Integer) then begin\n          Result := High(Integer);\n          Break;\n        end;\n        Inc(Result, Size);\n        if Assigned(aBasePtr) and Assigned(aEndPtr) and (Cardinal(aEndPtr)<Cardinal(aBasePtr)+Result) then begin\n//          if Assigned(aBasePtr) and Assigned(aEndPtr) and (aEndPtr<>aBasePtr) then\n//          wbProgressCallback('Found a struct with a negative size! (2) '+IntToHex64(Cardinal(aBasePtr)+Size, 8)+\n//            ' < '+IntToHex64(Cardinal(aEndPtr), 8)+'  for '+noName);\n          Result := Cardinal(aEndPtr)-Cardinal(aBasePtr);\n          Break;\n        end;\n        if Assigned(BasePtr) then\n          Inc(PByte(BasePtr), Size);\n      end;\n    end else\n      for i := Low(stMembers) to High(stMembers) do begin\n        Size := stMembers[i].Size[BasePtr, aEndPtr, aElement];\n        if Size = High(Integer) then begin\n          Result := High(Integer);\n          Break;\n        end;\n        Inc(Result, Size);\n        if Assigned(aBasePtr) and Assigned(aEndPtr) and (Cardinal(aEndPtr)<Cardinal(aBasePtr)+Result) then begin\n//          if Assigned(aBasePtr) and Assigned(aEndPtr) and (aEndPtr<>aBasePtr) then\n//            wbProgressCallback('Found a struct with a negative size! (2) '+IntToHex64(Cardinal(aBasePtr)+Result, 8)+\n//              ' > '+IntToHex64(Cardinal(aEndPtr), 8)+'  for '+noName);\n          Result := Cardinal(aEndPtr)-Cardinal(aBasePtr);\n          Break;\n        end;\n        if Assigned(BasePtr) then\n          Inc(PByte(BasePtr), Size);\n      end;\n  end;\nend;\n\nfunction TwbStructDef.GetDefaultSize(aBasePtr, aEndPtr: Pointer; const aElement: IwbElement): Integer;\nvar\n  i     : Integer;\n  Size  : Integer;\nbegin\n  Result := 0;\n  for i := Low(stMembers) to High(stMembers) do begin\n    Size := stMembers[i].DefaultSize[aBasePtr, aEndPtr, aElement];\n    if Size = High(Integer) then begin\n      Result := High(Integer);\n      Break;\n    end;\n    if Assigned(aBasePtr) then\n      Inc(PByte(aBasePtr), Size);\n    Inc(Result, Size);\n  end;\nend;\n\nfunction TwbStructDef.GetIsVariableSizeInternal: Boolean;\nvar\n  i : Integer;\nbegin\n  Result := False;\n  for i := Low(stMembers) to High(stMembers) do\n    if stMembers[i].IsVariableSize then begin\n      Result := True;\n      Break;\n    end;\nend;\n\nprocedure TwbStructDef.Report(const aParents: TwbDefPath);\nvar\n  Parents : TwbDefPath;\n  i       : Integer;\nbegin\n  if defReported then\n    Exit;\n\n  inherited;\n  Parents := aParents;\n  SetLength(Parents, Succ(Length(Parents)));\n  Parents[High(Parents)].Def := Self;\n  for i := Low(stMembers) to High(stMembers) do\n    if Assigned(stMembers[i]) then begin\n      Parents[High(Parents)].Index := i;\n      stMembers[i].Report(Parents);\n    end;\n\n  defReported := True;\nend;\n\nfunction TwbStructDef.ToSortKey(aBasePtr, aEndPtr: Pointer; const aElement: IwbElement; aExtended: Boolean): string;\nvar\n  i, j        : Integer;\n  SortMember  : Integer;\n  BasePtr     : Pointer;\n  EndPtr      : Pointer;\nbegin\n  Result := '';\n  if (Length(stSortKey) > 0) or (aExtended and (Length(stExSortKey) > 0)) then begin\n    for i := Low(stSortKey) to High(stSortKey) do begin\n      SortMember := stSortKey[i];\n      if SortMember <= High(stMembers) then begin\n        BasePtr := aBasePtr;\n        for j := Low(stMembers) to Pred(SortMember) do begin\n          Inc(PByte(BasePtr), stMembers[j].Size[BasePtr, aEndPtr, aElement]);\n          if Cardinal(BasePtr) > Cardinal(aEndPtr) then\n            BasePtr := aEndPtr;\n        end;\n\n        EndPtr := Pointer( Cardinal(BasePtr) + Cardinal(stMembers[SortMember].Size[BasePtr, aEndPtr, aElement]) );\n\n        if Cardinal(BasePtr) > Cardinal(aEndPtr) then\n          BasePtr := aEndPtr;\n        if Cardinal(EndPtr) > Cardinal(aEndPtr) then\n          EndPtr := aEndPtr;\n\n        Result := Result + stMembers[SortMember].ToSortKey(BasePtr, EndPtr, aElement, aExtended);\n      end;\n\n      if i < High(stSortKey) then\n        Result := Result + '|';\n    end;\n    if aExtended then begin\n      if (Length(stSortKey) > 0) and (Length(stExSortKey) > 0) then\n        Result := Result + '|';\n\n      for i := Low(stExSortKey) to High(stExSortKey) do begin\n        SortMember := stExSortKey[i];\n        if SortMember <= High(stMembers) then begin\n          BasePtr := aBasePtr;\n          for j := Low(stMembers) to Pred(SortMember) do begin\n            Inc(PByte(BasePtr), stMembers[j].Size[BasePtr, aEndPtr, aElement]);\n            if Cardinal(BasePtr) > Cardinal(aEndPtr) then\n              BasePtr := aEndPtr;\n          end;\n\n          EndPtr := Pointer( Cardinal(BasePtr) + Cardinal(stMembers[SortMember].Size[BasePtr, aEndPtr, aElement]) );\n\n          if Cardinal(BasePtr) > Cardinal(aEndPtr) then\n            BasePtr := aEndPtr;\n          if Cardinal(EndPtr) > Cardinal(aEndPtr) then\n            EndPtr := aEndPtr;\n\n          Result := Result + stMembers[SortMember].ToSortKey(BasePtr, EndPtr, aElement, aExtended);\n        end;\n\n        if i < High(stExSortKey) then\n          Result := Result + '|';\n      end;\n    end;\n  end else begin\n    BasePtr := aBasePtr;\n    for j := Low(stMembers) to High(stMembers) do begin\n      EndPtr := Pointer( Cardinal(BasePtr) + Cardinal(stMembers[j].Size[BasePtr, aEndPtr, aElement]) );\n\n      if Cardinal(BasePtr) > Cardinal(aEndPtr) then\n        BasePtr := aEndPtr;\n      if Cardinal(EndPtr) > Cardinal(aEndPtr) then\n        EndPtr := aEndPtr;\n\n      Result := Result + stMembers[j].ToSortKey(BasePtr, EndPtr, aElement, aExtended);\n\n      BasePtr := EndPtr;\n\n      if j < High(stMembers) then\n        Result := Result + '|';\n    end;\n  end;\nend;\n\nfunction TwbStructDef.ToString(aBasePtr, aEndPtr: Pointer; const aElement: IwbElement): string;\nbegin\n  Result := '';\n  Used(aElement, Result);\nend;\n\n{ TwbFlagsDef }\n\nfunction TwbFlagsDef.Assign(const aTarget : IwbElement;\n                                  aIndex  : Integer;\n                            const aSource : IwbElement;\n                                  aOnlySK : Boolean)\n                                          : IwbElement;\nvar\n  FlagDef : IwbFlagDef;\n  i       : Int64;\nbegin\n  if Supports(aSource.ValueDef, IwbFlagDef, FlagDef) then begin\n    i := aTarget.NativeValue;\n    i := i or (1 shl FlagDef.FlagIndex);\n    aTarget.NativeValue := i;\n  end else\n    Result := inherited Assign(aTarget, aIndex, aSource, aOnlySK);\nend;\n\nfunction TwbFlagsDef.CanAssign(const aElement: IwbElement; aIndex: Integer; const aDef: IwbDef): Boolean;\nvar\n  FlagsDef : IwbFlagsDef;\n  FlagDef  : IwbFlagDef;\n  i        : Integer;\nbegin\n  if Supports(aDef, IwbFlagsDef, FlagsDef) then begin\n    Result := FlagsDef.FlagCount = GetFlagCount;\n    if Result and not GetRoot.Equals(FlagsDef.Root) then\n      for i := 0 to Pred(GetFlagCount) do\n        if not SameStr(FlagsDef.Flags[i], GetFlag(i)) then begin\n          Result := False;\n          Exit;\n        end;\n  end else if Supports(aDef, IwbFlagDef, FlagDef) then begin\n    FlagsDef := FlagDef.FlagsDef;\n    Result := GetBaseFlagsDef.Equals(FlagsDef.BaseFlagsDef);\n    if Result then begin\n      i := FlagDef.FlagIndex;\n      Result := SameStr(FlagsDef.Flags[i], GetFlag(i));\n    end;\n  end else\n    Result := false;\nend;\n\nfunction TwbFlagsDef.CanContainFormIDs: Boolean;\nbegin\n  Result := False;\nend;\n\nfunction TwbFlagsDef.Check(aInt: Int64; const aElement: IwbElement): string;\nvar\n  i: Integer;\n  s: string;\nbegin\n  Result := '';\n  if not flgUnknownIsUnused then begin\n    for i := 0 to 63 do\n      if (aInt and (Int64(1) shl i)) <> 0 then begin\n        s := '';\n        if i <= High(flgNames) then\n          s := flgNames[i];\n        if s = '' then begin\n          s := '<Unknown: '+IntToStr(i)+'>';\n          Result := Result + s + ', ';\n        end;\n      end;\n    SetLength(Result, Length(Result)-2);\n  end;\nend;\n\nconstructor TwbFlagsDef.Clone(const aSource: TwbDef);\nbegin\n  with aSource as TwbFlagsDef do\n    Self.Create(flgBaseFlagsDef, flgNames, flgDontShows, flgUnknownIsUnused, flgIgnoreMask, flgGetCPs).defSource := aSource;\nend;\n\nconstructor TwbFlagsDef.Create(const aBaseFlagsDef    : IwbFlagsDef;\n                               const aNames           : array of string;\n                               const aDontShows       : array of TwbDontShowCallback;\n                                     aUnknownIsUnused : Boolean;\n                                     aIgnoreMask      : Int64;\n                               const aGetCPs          : array of TwbGetConflictPriority);\nvar\n  i: Integer;\nbegin\n  if Assigned(aBaseFlagsDef) then\n    flgBaseFlagsDef := aBaseFlagsDef.Root as IwbFlagsDef;\n  flgIgnoreMask := aIgnoreMask;\n  flgUnknownIsUnused := aUnknownIsUnused;\n  flgUnusedMask := 0;\n  if flgUnknownIsUnused then\n    flgUnusedMask := not flgUnusedMask;\n  SetLength(flgNames, Length(aNames));\n  for i := Low(flgNames) to High(flgNames) do begin\n    flgNames[i] := aNames[i];\n    if SameText(flgNames[i], 'Unused') then\n      flgUnusedMask := flgUnusedMask or (Int64(1) shl i)\n    else if flgUnknownIsUnused and (flgNames[i] <> '') then\n      flgUnusedMask := flgUnusedMask and not (Int64(1) shl i);\n  end;\n  SetLength(flgFlagDefs, Length(flgNames));\n\n  SetLength(flgDontShows, Length(aDontShows));\n  for i := Low(flgDontShows) to High(flgDontShows) do begin\n    flgDontShows[i] := aDontShows[i];\n    flgHasDontShows := flgHasDontShows or Assigned(flgDontShows[i]);\n  end;\n\n  SetLength(flgGetCPs, Length(aGetCPs));\n  for i := Low(flgGetCPs) to High(flgGetCPs) do begin\n    flgGetCPs[i] := aGetCPs[i];\n    flgHasGetCPs := flgHasGetCPs or Assigned(flgGetCPs[i]);\n  end;\n\n  inherited Create(cpNormal, False, nil);\nend;\n\nfunction TwbFlagsDef.FromEditValue(const aValue: string; const aElement: IwbElement): Int64;\nvar\n  i: Integer;\nbegin\n  Result := 0;\n  for i := 1 to Length(aValue) do\n    case aValue[i] of\n      '0': {do nothing};\n      '1': Result := Result or (Int64(1) shl Pred(i));\n    else\n      raise Exception.Create('\"'+aValue[i]+'\" is not a valid character for a flag');\n    end;\n  Result := Result and not flgUnusedMask;\nend;\n\nfunction TwbFlagsDef.GetBaseFlagsDef: IwbFlagsDef;\nbegin\n  if Assigned(flgBaseFlagsDef) then\n    Result := flgBaseFlagsDef\n  else\n    Result := GetRoot as IwbFlagsDef;\nend;\n\nfunction TwbFlagsDef.GetDefTypeName: string;\nvar\n  i: Integer;\nbegin\n  if Length(flgNames)=0 then\n    inherited\n  else begin\n    Result := '('+flgNames[Low(flgNames)];\n    for i := 1 to High(flgNames) do\n      Result := Result+','+flgNames[i];\n    Result := Result+')'\n  end;\nend;\n\nfunction TwbFlagsDef.GetEditInfo(aInt: Int64; const aElement: IwbElement): string;\nvar\n  FlagCount  : Integer;\n  IntegerDef : IwbIntegerDef;\n  i          : Integer;\n  s          : string;\nbegin\n  FlagCount := 64;\n  if Assigned(aElement) and (Supports(aElement.Def, IwbIntegerDef, IntegerDef) or Supports(aElement.ValueDef, IwbIntegerDef, IntegerDef)) then\n    case IntegerDef.IntType of\n      it0: FlagCount := 0;\n      itU8, itS8: FlagCount := 8;\n      itU16, itS16: FlagCount := 16;\n      itU32, itS32: FlagCount := 32;\n    end;\n\n  with TStringList.Create do try\n    for i := 0 to Pred(FlagCount) do begin\n      s := '';\n      if i <= High(flgNames) then\n        s := flgNames[i];\n      if s = '' then\n        if flgUnknownIsUnused then\n          s := 'Unused'\n        else\n          s := '<Unknown: '+IntToStr(i)+'>';\n      if GetFlagDontShow(aElement, i) then\n        s := '(' + s + ')';\n      if wbShowFlagEnumValue then\n        s := s + ' (0x' + IntToHex(Int64(1) shl i, 8) + ')';\n      Add(s);\n    end;\n    Result := CommaText;\n  finally\n    Free;\n  end;\nend;\n\nfunction TwbFlagsDef.GetEditType(aInt: Int64; const aElement: IwbElement): TwbEditType;\nbegin\n  Result := etCheckComboBox;\nend;\n\nfunction TwbFlagsDef.GetFlag(aIndex: Integer): string;\nbegin\n  Result := flgNames[aIndex];\n  if wbShowFlagEnumValue then\n    Result := Result + ' (0x' + IntToHex(Int64(1) shl aIndex, 8) + ')';\nend;\n\nfunction TwbFlagsDef.GetFlagCount: Integer;\nbegin\n  Result := Length(flgNames);\nend;\n\nfunction TwbFlagsDef.GetFlagDef(aIndex: Integer): IwbFlagDef;\nvar\n  FlagDef: IwbFlagDef;\nbegin\n  Result := flgFlagDefs[aIndex];\n  if not Assigned(Result) then begin\n    FlagDef := TwbFlagDef.Create(defPriority, False, flgNames[aIndex], nil, nil,\n      nil, nil, False, aIndex).SetParent(Self, False) as IwbFlagDef;\n\n    {this really should be done threadsafe with a locked compare exchange}\n    flgFlagDefs[aIndex] := FlagDef;\n\n    Result := flgFlagDefs[aIndex];\n  end;\nend;\n\nfunction TwbFlagsDef.GetFlagDontShow(const aElement: IwbElement; aIndex: Integer): Boolean;\nbegin\n  Result := False;\n  if flgHasDontShows and (aIndex <= High(flgDontShows)) and Assigned(flgDontShows[aIndex]) then\n    Result := flgDontShows[aIndex](aElement);\nend;\n\nprocedure TwbFlagsDef.FlagGetCP(const aElement : IwbElement;\n                                     aIndex   : Integer;\n                                 var aCP      : TwbConflictPriority);\nbegin\n  if flgHasGetCPs and (aIndex <= High(flgGetCPs)) and Assigned(flgGetCPs[aIndex]) then\n    flgGetCPs[aIndex](aElement, aCP);\nend;\n\nfunction TwbFlagsDef.GetFlagHasDontShow(aIndex: Integer): Boolean;\nbegin\n  Result := flgHasDontShows and (aIndex <= High(flgDontShows)) and Assigned(flgDontShows[aIndex]);\nend;\n\nfunction TwbFlagsDef.GetFlagHasGetCP(aIndex: Integer): Boolean;\nbegin\n  Result := flgHasGetCPs and (aIndex <= High(flgGetCPs)) and Assigned(flgGetCPs[aIndex]);\nend;\n\nfunction TwbFlagsDef.GetFlagIgnoreConflict(aIndex: Integer): Boolean;\nbegin\n  Result := (flgIgnoreMask and (Int64(1) shl Int64(aIndex))) <> 0;\nend;\n\nfunction TwbFlagsDef.GetIsEditable(aInt: Int64; const aElement: IwbElement): Boolean;\nbegin\n  Result := True;\nend;\n\nprocedure TwbFlagsDef.Report(const aParents: TwbDefPath);\nvar\n  i: Integer;\nbegin\n  if defReported then\n    Exit;\n\n  inherited;\n  if wbReportMode and wbReportUnknownFlags and HasUnknownFlags then begin\n    WriteLn('Unknown Flags in: ', wbDefsToPath(aParents), wbDefToName(Self));\n    for i := 0 to 63 do\n      if UnknownFlags[i] > 0 then\n        WriteLn('  ', i,' (',UnknownFlags[i],')');\n  end;\n\n  defReported := True;\nend;\n\nfunction TwbFlagsDef.GetRequiresKey: Boolean;\nbegin\n  Result := True;\nend;\n\nfunction TwbFlagsDef.ToEditValue(aInt: Int64; const aElement: IwbElement): string;\nvar\n  i: Integer;\nbegin\n  aInt := aInt and not flgUnusedMask;\n  Result := StringOfChar('0', 64);\n  for i := 0 to 63 do\n    if (aInt and (Int64(1) shl i)) <> 0 then begin\n      Result[Succ(i)] := '1';\n      aInt := aInt and not (Int64(1) shl i);\n      if aInt = 0 then begin\n        SetLength(Result, Succ(i));\n        Exit;\n      end;\n    end;\nend;\n\nfunction TwbFlagsDef.ToSortKey(aInt: Int64; const aElement: IwbElement): string;\nvar\n  i: Integer;\nbegin\n  aInt := aInt and not flgUnusedMask;\n  Result := StringOfChar('0', 64);\n  for i := 0 to 63 do\n    if (aInt and (Int64(1) shl i)) <> 0 then\n      if not GetFlagDontShow(aElement, i) then\n        Result[Succ(i)] := '1';\nend;\n\nfunction TwbFlagsDef.ToString(aInt: Int64; const aElement: IwbElement): string;\nvar\n  i: Integer;\n  s: string;\nbegin\n  Result := '';\n  aInt := aInt and not flgUnusedMask;\n  for i := 0 to 63 do\n    if (aInt and (Int64(1) shl i)) <> 0 then begin\n      s := '';\n      if i <= High(flgNames) then\n        s := flgNames[i];\n      if s = '' then begin\n        s := '<Unknown: '+IntToStr(i)+'>';\n        if wbReportMode and wbReportUnknownFlags then begin\n          Inc(UnknownFlags[i]);\n          HasUnknownFlags := True;\n        end;\n      end;\n      if wbShowFlagEnumValue then\n        s := s + ' (0x' + IntToHex(Int64(1) shl i, 8) + ')';\n      if not GetFlagDontShow(aElement, i) then\n        Result := Result + s + ', ';\n    end;\n  SetLength(Result, Length(Result)-2);\n  Used(aElement, Result);\nend;\n\n{ TwbEnumDef }\n\nfunction TwbEnumDef.CanAssign(const aElement: IwbElement; aIndex: Integer; const aDef: IwbDef): Boolean;\nvar\n  EnumDef: IwbEnumDef;\n  i: Integer;\nbegin\n  Result := Supports(aDef, IwbEnumDef, EnumDef) and (EnumDef.NameCount = GetNameCount);\n  if Result and not Equals(EnumDef) then\n    for i := 0 to Pred(GetNameCount) do\n      if not SameStr(EnumDef.Names[i], GetName(i)) then begin\n        Result := False;\n        Exit;\n      end;\nend;\n\nfunction TwbEnumDef.CanContainFormIDs: Boolean;\nbegin\n  Result := False;\nend;\n\nfunction TwbEnumDef.Check(aInt: Int64; const aElement: IwbElement): string;\nvar\n  i: Integer;\nbegin\n  Result := '';\n\n  if (aInt >= Low(enNames)) and (aInt <= High(enNames)) then\n    Result := enNames[aInt];\n\n  if Result = '' then\n    if FindSparseName(aInt, i) then\n      Result := enSparseNamesMap[i].snName;\n\n  if Result = '' then\n    Result := '<Unknown: '+IntToStr(aInt)+'>'\n  else\n    Result := '';\nend;\n\nfunction CompareSparseName(Item1, Item2: Pointer): Integer;\nvar\n  Index1, Index2: Int64;\nbegin\n  Index1 := PwbSparseName(Item1).snIndex;\n  Index2 := PwbSparseName(Item2).snIndex;\n\n  if Index1 < Index2 then\n    Result := -1\n  else if Index1 = Index2 then\n    Result := 0\n  else\n    Result := 1;\nend;\n\nconstructor TwbEnumDef.Clone(const aSource: TwbDef);\nvar\n  i: Integer;\nbegin\n  with aSource as TwbEnumDef do begin\n    inherited Create(defPriority, defRequired, defGetCP).defSource := aSource;\n    Self.enNames := Copy(enNames, 0, Length(enNames));\n    Self.enSparseNames := Copy(enSparseNames, 0, Length(enSparseNames));\n    Self.enEditInfo := enEditInfo;\n  end;\n\n  SetLength(enSparseNamesMap, Length(enSparseNames));\n  for i := Low(enSparseNames) to High(enSparseNames) do\n    enSparseNamesMap[i] := @enSparseNames[i];\n  if Length(enSparseNames) > 0 then\n    wbMergeSort(@enSparseNamesMap[0], Length(enSparseNames), CompareSparseName);\nend;\n\nconstructor TwbEnumDef.Create(const aNames: array of string;\n                              const aSparseNames : array of const);\nvar\n  i        : Integer;\n  EditInfo : TStringList;\nbegin\n  EditInfo := TwbFastStringListIC.Create;\n  try\n    SetLength(enNames, Length(aNames));\n    for i := Low(enNames) to High(enNames) do begin\n      enNames[i] := aNames[i];\n      if aNames[i] <> '' then\n        if wbShowFlagEnumValue then\n          EditInfo.Add(aNames[i] + ' (' + IntToStr(i) + ')')\n        else\n          EditInfo.Add(aNames[i]);\n    end;\n\n    Assert(Length(aSparseNames) mod 2 = 0);\n    SetLength(enSparseNames, Length(aSparseNames) div 2);\n    for i := Low(enSparseNames) to High(enSparseNames) do begin\n      Assert(aSparseNames[     i * 2 ].VType in [vtInteger, vtInt64]);\n      Assert(aSparseNames[Succ(i * 2)].VType in [vtAnsiString, vtChar, vtUnicodeString, vtWideChar]);\n      with enSparseNames[i] do begin\n\n        if aSparseNames[i * 2].VType = vtInteger then\n          snIndex := aSparseNames[i * 2 ].VInteger\n        else\n          snIndex := aSparseNames[i * 2 ].VInt64^;\n\n        if aSparseNames[Succ(i * 2)].VType = vtAnsiString then\n          snName  := AnsiString(aSparseNames[Succ(i * 2)].VAnsiString)\n        else if aSparseNames[Succ(i * 2)].VType = vtChar then\n          snName  := aSparseNames[Succ(i * 2)].VChar\n        else if aSparseNames[Succ(i * 2)].VType = vtUnicodeString then\n          snName  := UnicodeString(aSparseNames[Succ(i * 2)].VUnicodeString)\n        else if aSparseNames[Succ(i * 2)].VType = vtWideChar then\n          snName  := aSparseNames[Succ(i * 2)].VWideChar;\n\n        if snName <> '' then\n          if wbShowFlagEnumValue then\n            EditInfo.Add(snName + ' (' + IntToStr(snIndex) + ')')\n          else\n            EditInfo.Add(snName);\n      end;\n    end;\n    EditInfo.Sort;\n    enEditInfo := EditInfo.CommaText;\n  finally\n    FreeAndNil(EditInfo);\n  end;\n\n  SetLength(enSparseNamesMap, Length(enSparseNames));\n  for i := Low(enSparseNames) to High(enSparseNames) do\n    enSparseNamesMap[i] := @enSparseNames[i];\n  if Length(enSparseNames) > 0 then\n    wbMergeSort(@enSparseNamesMap[0], Length(enSparseNames), CompareSparseName);\n\n  inherited Create(cpNormal, False, nil);\nend;\n\nfunction CmpB8(a, b: Byte): Integer;\nasm\n{$IFDEF WIN32}\n  xor ecx, ecx\n  cmp al, dl\n  ja @@GT\n  je @@EQ\n@@LT:\n  dec ecx\n  dec ecx\n@@GT:\n  inc ecx\n@@EQ:\n  mov eax, ecx\n{$ENDIF WIN32}\n{$IFDEF WIN64}\n  xor eax, eax\n  cmp ecx, edx\n  ja @@GT\n  je @@EQ\n@@LT:\n  dec eax\n  dec eax\n@@GT:\n  inc eax\n@@EQ:\n{$ENDIF WIN64}\nend;\n\nfunction CmpI32(a, b : Integer) : Integer;\nasm\n{$IFDEF WIN32}\n  xor ecx, ecx\n  cmp eax, edx\n  jg @@GT\n  je @@EQ\n@@LT:\n  dec ecx\n  dec ecx\n@@GT:\n  inc ecx\n@@EQ:\n  mov eax, ecx\n{$ENDIF WIN32}\n{$IFDEF WIN64}\n  xor eax, eax\n  cmp ecx, edx\n  jg @@GT\n  je @@EQ\n@@LT:\n  dec eax\n  dec eax\n@@GT:\n  inc eax\n@@EQ:\n{$ENDIF WIN64}\nend;\n\nfunction CmpW32(a, b: Cardinal): Integer;\nasm\n{$IFDEF WIN32}\n  xor ecx, ecx\n  cmp eax, edx\n  ja @@GT\n  je @@EQ\n@@LT:\n  dec ecx\n  dec ecx\n@@GT:\n  inc ecx\n@@EQ:\n  mov eax, ecx\n{$ENDIF WIN32}\n{$IFDEF WIN64}\n  xor eax, eax\n  cmp ecx, edx\n  ja @@GT\n  je @@EQ\n@@LT:\n  dec eax\n  dec eax\n@@GT:\n  inc eax\n@@EQ:\n{$ENDIF WIN64}\nend;\n\nfunction CmpI64(const a, b : Int64) : Integer;\n//begin\n//  if a = b then\n//    Result := nxEqual\n//  else if a < b then\n//    Result := nxSmallerThan\n//  else\n//    Result := nxGreaterThan;\n//end;\nasm\n{$IFDEF WIN32}\n  xor eax, eax\n  mov edx, [ebp+20]\n  cmp edx, [ebp+12]\n  jg @@GT\n  jl @@LT\n  mov edx, [ebp+16]\n  cmp edx, [ebp+8]\n  ja @@GT\n  je @@EQ\n@@LT:\n  dec eax\n  dec eax\n@@GT:\n  inc eax\n@@EQ:\n{$ENDIF WIN32}\n{$IFDEF WIN64}\n  xor rax, rax\n  cmp rcx, rdx\n  jg @@GT\n  je @@EQ\n@@LT:\n  dec rax\n  dec rax\n@@GT:\n  inc rax\n@@EQ:\n{$ENDIF WIN64}\nend;\n\nfunction TwbEnumDef.FindSparseName(aSearchIndex: Int64; var Index: Integer): Boolean;\nvar\n  L, H, I, C: Integer;\nbegin\n  Result := False;\n\n  L := Low(enSparseNamesMap);\n  H := High(enSparseNamesMap);\n  while L <= H do begin\n    I := (L + H) shr 1;\n    C := CmpI64(enSparseNamesMap[I].snIndex, aSearchIndex);\n    if C < 0 then\n      L := I + 1\n    else begin\n      H := I - 1;\n      if C = 0 then begin\n        Result := True;\n        L := I;\n      end;\n    end;\n  end;\n  Index := L;\nend;\n\nfunction TwbEnumDef.FromEditValue(const aValue: string; const aElement: IwbElement): Int64;\nvar\n  i, j: Integer;\n  Value: string;\nbegin\n  if aValue = '' then\n    Result := 0\n  else begin\n    Value := aValue;\n    if wbShowFlagEnumValue and (Value[Length(Value)] = ')') then begin\n      // remove an integer value of enum from enum string value\n      i := LastDelimiter('(', Value);\n      if (i > 0) and TryStrToInt(Copy(Value, Succ(i), Length(Value) - Succ(i)), j) then\n        Delete(Value, Pred(i), Length(Value));\n    end;\n    for i := Low(enNames) to High(enNames) do\n      if SameStr(enNames[i], Value) then begin\n        Result := i;\n        Exit;\n      end;\n    for i := Low(enSparseNames) to High(enSparseNames) do with enSparseNames[i] do\n      if SameStr(snName, Value) then begin\n        Result := snIndex;\n        Exit;\n      end;\n    Result := StrToInt64(Value);\n  end;\nend;\n\nfunction TwbEnumDef.GetDefTypeName: string;\nvar\n  i: Integer;\nbegin\n  if Length(enNames)=0 then\n    inherited\n  else begin\n    Result := '('+enNames[Low(enNames)];\n    for i := 1 to High(enNames) do\n      Result := Result+','+enNames[i];\n    Result := Result+')'\n  end;\nend;\n\nfunction TwbEnumDef.GetEditInfo(aInt: Int64; const aElement: IwbElement): string;\nbegin\n  Result := enEditInfo;\nend;\n\nfunction TwbEnumDef.GetEditType(aInt: Int64; const aElement: IwbElement): TwbEditType;\nbegin\n  Result := etComboBox;\nend;\n\nfunction TwbEnumDef.GetIsEditable(aInt: Int64; const aElement: IwbElement): Boolean;\nbegin\n  Result := True;\nend;\n\nfunction TwbEnumDef.GetName(aIndex: Integer): string;\nbegin\n  Result := enNames[aIndex];\nend;\n\nfunction TwbEnumDef.GetNameCount: Integer;\nbegin\n  Result := Length(enNames);\nend;\n\nprocedure TwbEnumDef.Report(const aParents: TwbDefPath);\nvar\n  i, j: Integer;\n  sl: TStringList;\nbegin\n  if defReported then\n    Exit;\n\n  inherited;\n  if wbReportMode and wbReportUnknownEnums and Assigned(UnknownEnums) then begin\n    WriteLn('Unknown Enums in: ', wbDefsToPath(aParents), wbDefToName(Self));\n    for i := 0 to Pred(UnknownEnums.Count) do begin\n      sl := UnknownEnums.Objects[i] as TStringList;\n      WriteLn('  ', UnknownEnums[i], ' (',sl.Count,')' );\n      for j := 0 to Pred(sl.Count) do\n        WriteLn('    ', sl[j], ' (',Integer(sl.Objects[j]),')' );\n    end;\n  end;\n\n  defReported := True;\nend;\n\nfunction TwbEnumDef.ToEditValue(aInt: Int64; const aElement: IwbElement): string;\nvar\n  i: Integer;\nbegin\n  Result := '';\n\n  if (aInt >= Low(enNames)) and (aInt <= High(enNames)) then begin\n    Result := enNames[aInt];\n    if wbShowFlagEnumValue then\n      Result := Result + ' (' + IntToStr(aInt) + ')';\n  end;\n\n  if Result = '' then\n    if FindSparseName(aInt, i) then begin\n      Result := enSparseNamesMap[i].snName;\n      if wbShowFlagEnumValue then\n        Result := Result + ' (' + IntToStr(enSparseNamesMap[i].snIndex) + ')';\n    end;\n\n  if Result = '' then begin\n    Result := IntToStr(aInt);\n    if wbShowFlagEnumValue then\n      Result := Result + ' (' + IntToStr(aInt) + ')';\n  end;\nend;\n\nfunction TwbEnumDef.ToSortKey(aInt: Int64; const aElement: IwbElement): string;\nbegin\n  Result := ''; {handled by IntegerDef}\nend;\n\nfunction TwbEnumDef.ToString(aInt: Int64; const aElement: IwbElement): string;\nvar\n  s: string;\n  i: Integer;\nbegin\n  Result := '';\n\n  if (aInt >= Low(enNames)) and (aInt <= High(enNames)) then begin\n    Result := enNames[aInt];\n    if wbShowFlagEnumValue and (Result <> '') then\n      Result := Result + ' (' + IntToStr(aInt) + ')';\n  end;\n\n  if Result = '' then begin\n    if FindSparseName(aInt, i) then begin\n      Result := enSparseNamesMap[i].snName;\n      if wbShowFlagEnumValue then\n        Result := Result + ' (' + IntToStr(enSparseNamesMap[i].snIndex) + ')';\n    end\n    else begin\n      Result := '<Unknown: '+IntToStr(aInt)+'>';\n      if wbReportMode and wbReportUnknownEnums then begin\n        if not Assigned(UnknownEnums) then\n          UnknownEnums := TwbFastStringListIC.CreateSorted;\n        if not UnknownEnums.Find(Result, i) then\n          i := UnknownEnums.AddObject(Result, TwbFastStringListIC.CreateSorted);\n        with UnknownEnums.Objects[i] as TStringList do begin\n          if Count < 10 then begin\n            s := aElement.FullPath;\n            if not Find(s, i) then\n              i := Add(s);\n            Objects[i] := TObject(Succ(Integer(Objects[i])));\n          end;\n        end;\n      end;\n    end;\n  end;\n  Used(aElement, Result);\nend;\n\n{ TwbStringDef }\n\nfunction TwbStringDef.CanAssign(const aElement: IwbElement; aIndex: Integer; const aDef: IwbDef): Boolean;\nvar\n  StringDef: IwbStringDef;\nbegin\n  Result := Supports(aDef, IwbStringDef, StringDef) and\n    ((sdSize = 0) or (StringDef.StringSize = 0) or (sdSize <= StringDef.StringSize));\nend;\n\nfunction TwbStringDef.CanContainFormIDs: Boolean;\nbegin\n  Result := False;\nend;\n\nconstructor TwbStringDef.Clone(const aSource: TwbDef);\nbegin\n  with aSource as TwbStringDef do\n    Self.Create(defPriority, defRequired, noName, sdSize, noAfterLoad, noAfterSet, noDontShow, defGetCP, noTerminator).defSource := aSource;\nend;\n\nconstructor TwbStringDef.Create(aPriority   : TwbConflictPriority;\n                                aRequired   : Boolean;\n                          const aName       : string;\n                                aSize       : Integer;\n                                aAfterLoad  : TwbAfterLoadCallback;\n                                aAfterSet   : TwbAfterSetCallback;\n                                aDontShow   : TwbDontShowCallback;\n                                aGetCP      : TwbGetConflictPriority;\n                                aTerminator : Boolean;\n                                aForward    : boolean);\nbegin\n  sdSize := aSize;\n  sdForward := aForward;\n  inherited Create(aPriority, aRequired, aName, aAfterLoad, aAfterSet, aDontShow, aGetCP, aTerminator);\nend;\n\nprocedure TwbStringDef.FromEditValue(aBasePtr, aEndPtr: Pointer; const aElement: IwbElement; const aValue: string);\nbegin\n  FromStringTransform(aBasePtr, aEndPtr, aElement, aValue, ttFromEditValue);\nend;\n\nprocedure TwbStringDef.FromNativeValue(aBasePtr, aEndPtr: Pointer; const aElement: IwbElement; const aValue: Variant);\nbegin\n  FromStringTransform(aBasePtr, aEndPtr, aElement, aValue, ttFromNativeValue);\nend;\n\nprocedure TwbStringDef.FromStringNative(aBasePtr, aEndPtr: Pointer; const aElement: IwbElement; const aValue: AnsiString);\nvar\n  NewSize : Integer;\nbegin\n  if sdSize > 0 then\n    NewSize := sdSize\n  else\n    NewSize := Succ(Length(aValue));\n\n  aElement.RequestStorageChange(aBasePtr, aEndPtr, NewSize + Ord(noTerminator));\n\n  if sdSize > 0 then begin\n    FillChar(aBasePtr^, sdSize, 0);\n    NewSize := Length(aValue);\n    if NewSize > 0 then\n      Move(aValue[1], aBasePtr^, NewSize);\n  end else begin\n    if NewSize > 1 then\n      Move(aValue[1], aBasePtr^, Length(aValue));\n\n    PAnsiChar(aBasePtr)[Pred(NewSize)] := #0;\n  end;\n  if noTerminator then\n    PAnsiChar(aBasePtr)[NewSize] := AnsiChar(wbTerminator);\nend;\n\nprocedure TwbStringDef.FromStringTransform(aBasePtr, aEndPtr: Pointer; const aElement: IwbElement; const aValue: string; aTransformType: TwbStringTransformType);\nbegin\n  FromStringNative(aBasePtr, aEndPtr, aElement, TransformString(wbStringToAnsi(aValue, aElement), aTransformType, aElement));\nend;\n\nfunction TwbStringDef.GetDefType: TwbDefType;\nbegin\n  Result := dtString;\nend;\n\nfunction TwbStringDef.GetDefTypeName: string;\nbegin\n  Result := 'Terminated String';\nend;\n\nfunction TwbStringDef.GetIsEditable(aBasePtr, aEndPtr: Pointer; const aElement: IwbElement): Boolean;\nbegin\n  Result := True;\nend;\n\nfunction TwbStringDef.GetIsVariableSizeInternal: Boolean;\nbegin\n  Result := sdSize = 0;\nend;\n\nfunction TwbStringDef.GetStringSize: Integer;\nbegin\n  Result := sdSize;\nend;\n\nfunction TwbStringDef.SetToDefault(aBasePtr, aEndPtr: Pointer;\n  const aElement: IwbElement): Boolean;\nbegin\n  Result := not Assigned(aBasePtr) or (ToString(aBasePtr, aEndPtr, aElement) <> '');\n  if Result then\n    FromEditValue(aBasePtr, aEndPtr, aElement, '');\nend;\n\nfunction TwbStringDef.GetSize(aBasePtr, aEndPtr: Pointer; const aElement: IwbElement): Integer;\nbegin\n  if sdSize > 0 then\n    Result := sdSize + Ord(noTerminator)\n  else begin\n    if aBasePtr = nil then\n      Result := 1 + Ord(noTerminator)\n    else begin\n      Result := Ord(noTerminator);\n      while Cardinal(aBasePtr) < Cardinal(aEndPtr) do begin\n        Inc(Result);\n        if PAnsiChar(aBasePtr)^ = #0 then\n          Exit;\n\n        Inc(PByte(aBasePtr));\n      end;\n    end;\n  end;\nend;\n\nfunction TwbStringDef.GetDefaultSize(aBasePtr, aEndPtr: Pointer; const aElement: IwbElement): Integer;\nbegin\n  if sdSize > 0 then\n    Result := sdSize + Ord(noTerminator)\n  else\n    Result := 1 + Ord(noTerminator);\nend;\n\nfunction TwbStringDef.ToEditValue(aBasePtr, aEndPtr: Pointer;\n  const aElement: IwbElement): string;\nbegin\n  Result := ToStringTransform(aBasePtr, aEndPtr, aElement, ttToEditValue);\nend;\n\nfunction TwbStringDef.ToNativeValue(aBasePtr, aEndPtr: Pointer; const aElement: IwbElement): Variant;\nbegin\n  Result := ToStringTransform(aBasePtr, aEndPtr, aElement, ttToNativeValue);\nend;\n\nfunction TwbStringDef.ToSortKey(aBasePtr, aEndPtr: Pointer; const aElement: IwbElement; aExtended: Boolean): string;\nbegin\n  Result := UpperCase(ToStringTransform(aBasePtr, aEndPtr, aElement, ttToSortKey));\nend;\n\nfunction TwbStringDef.ToString(aBasePtr, aEndPtr: Pointer; const aElement: IwbElement): string;\nbegin\n  Result := ToStringTransform(aBasePtr, aEndPtr, aElement, ttToString);\nend;\n\nfunction TwbStringDef.ToStringNative(aBasePtr, aEndPtr: Pointer; const aElement: IwbElement): AnsiString;\nvar\n  aLen, Len : Cardinal;\nbegin\n  Len := Cardinal(aEndPtr) - Cardinal(aBasePtr);\n  if sdSize > 0 then begin\n    if Len > Cardinal(sdSize) then\n      Len := sdSize;\n  end;\n\n  if sdForward then begin\n    aLen := 0;\n    while aLen < Len do begin\n      if PAnsiChar(aBasePtr)[aLen] = #0 then\n        Break;\n      Inc(aLen);\n    end;\n    Len := aLen;\n    //if aLen < Len then\n    //  Len := Succ(aLen);\n  end else\n    while (Len > 0) and (PAnsiChar(aBasePtr)[Pred(Len)] = #0) do\n      Dec(Len);\n\n  SetLength(Result, Len);\n  if Len > 0 then\n    Move(aBasePtr^, Result[1], Len);\n  Used(aElement, Result);\nend;\n\nfunction TwbStringDef.ToStringTransform(aBasePtr, aEndPtr: Pointer; const aElement: IwbElement; aTransformType: TwbStringTransformType): string;\nbegin\n  Result := wbAnsiToString(TransformString(ToStringNative(aBasePtr, aEndPtr, aElement), aTransformType, aElement), aElement);\nend;\n\nfunction TwbStringDef.TransformString(const s: AnsiString; aTransformType: TwbStringTransformType; const aElement: IwbElement): AnsiString;\nbegin\n  Result := s;\nend;\n\n{ TwbFloatDef }\n\nconst\n  SingleNaN : Single = 0.0/0.0;\n  DoubleNaN : Double = 0.0/0.0;\n  SingleInf : Single = 1.0/0.0;\n  DoubleInf : Double = 1.0/0.0;\n\nfunction TwbFloatDef.CanAssign(const aElement: IwbElement; aIndex: Integer; const aDef: IwbDef): Boolean;\nvar\n  FloatDef: IwbFloatDef;\nbegin\n  Result := Supports(aDef, IwbFloatDef, FloatDef);\nend;\n\nfunction TwbFloatDef.CanContainFormIDs: Boolean;\nbegin\n  Result := False;\nend;\n\nconstructor TwbFloatDef.Clone(const aSource: TwbDef);\nbegin\n  with aSource as TwbFloatDef do\n    Self.Create(defPriority, defRequired, noName, noAfterLoad, noAfterSet, fdScale, fdDigits, noDontShow,\n      fdNormalizer, fdDefault, defGetCP, fdDouble, noTerminator).defSource := aSource;\nend;\n\nconstructor TwbFloatDef.Create(aPriority   : TwbConflictPriority;\n                               aRequired   : Boolean;\n                         const aName       : string;\n                               aAfterLoad  : TwbAfterLoadCallback;\n                               aAfterSet   : TwbAfterSetCallback;\n                               aScale      : Extended;\n                               aDigits     : Integer;\n                               aDontShow   : TwbDontShowCallback;\n                               aNormalizer : TwbFloatNormalizer;\n                               aDefault    : Extended;\n                               aGetCP      : TwbGetConflictPriority;\n                               aDouble     : Boolean;\n                               aTerminator : Boolean);\nbegin\n  fdDefault := aDefault;\n  fdScale := aScale;\n  fdDigits := aDigits;\n  fdNormalizer := aNormalizer;\n  fdDouble := aDouble;\n  if fdDigits < 0 then\n    fdDigits := wbFloatDigits;\n  inherited Create(aPriority, aRequired, aName, aAfterLoad, aAfterSet, aDontShow, aGetCP, aTerminator);\nend;\n\nprocedure TwbFloatDef.FromEditValue(aBasePtr, aEndPtr: Pointer; const aElement: IwbElement; const aValue: string);\nvar\n  Value: Extended;\nbegin\n  aElement.RequestStorageChange(aBasePtr, aEndPtr, 4);\n  if aValue = '' then begin\n    if fdDouble then\n      PDouble(aBasePtr)^ := 0.0\n    else\n      PSingle(aBasePtr)^ := 0.0;\n  end else if SameText(aValue, 'NaN') then begin\n    if fdDouble then\n      PDouble(aBasePtr)^ := DoubleNaN\n    else\n      PSingle(aBasePtr)^ := SingleNaN;\n  end else if SameText(aValue, 'Inf') then begin\n    if fdDouble then\n      PDouble(aBasePtr)^ := DoubleInf\n    else\n      PSingle(aBasePtr)^ := SingleInf;\n  end else if SameText(aValue, 'Default') or SameText(aValue, 'Max') then begin\n    if fdDouble then\n      PInt64(aBasePtr)^ := $7FEFFFFFFFFFFFFF\n    else\n      PCardinal(aBasePtr)^ := $7F7FFFFF;\n  end else if SameText(aValue, 'Min') then begin\n    if fdDouble then\n      PInt64(aBasePtr)^ := -$10000000000001 // $FFEFFFFFFFFFFFFF\n    else\n      PCardinal(aBasePtr)^ := $FF7FFFFF;\n  end else begin\n    Value := RoundToEx(StrToFloat(aValue), -fdDigits);\n    Value := Value / fdScale;\n    if Assigned(fdNormalizer) then\n      Value := fdNormalizer(aElement, Value);\n    if fdDouble then\n      PDouble(aBasePtr)^ := Value\n    else\n      PSingle(aBasePtr)^ := Value;\n  end;\nend;\n\nprocedure TwbFloatDef.FromNativeValue(aBasePtr, aEndPtr: Pointer; const aElement: IwbElement; const aValue: Variant);\nvar\n  Clear : Boolean;\n  Value : Extended;\n  Size  : Integer;\nbegin\n  Clear := VarIsClear(aValue);\n  if not Clear then\n    Value := aValue\n  else\n    Value := 0;\n\n  if fdDouble then\n    Size := SizeOf(Double)+Ord(noTerminator)\n  else\n    Size := SizeOf(Single)+Ord(noTerminator);\n  aElement.RequestStorageChange(aBasePtr, aEndPtr, Size);\n  if Assigned(aBasePtr) then begin\n    if Clear then begin\n      if fdDouble then\n        PDouble(aBasePtr)^ := DoubleNaN\n      else\n        PSingle(aBasePtr)^ := SingleNaN;\n    end else if fdDouble and (SameValue(Value, MaxDouble) or (Value > MaxDouble)) then\n      PInt64(aBasePtr)^ := $7FEFFFFFFFFFFFFF\n    else if fdDouble and (SameValue(Value, -MaxDouble) or (Value < -MaxDouble)) then\n      PInt64(aBasePtr)^ := -$10000000000001 // $FFEFFFFFFFFFFFFF\n    else if not fdDouble and (SameValue(Value, MaxSingle) or (Value > MaxSingle)) then\n      PCardinal(aBasePtr)^ := $7F7FFFFF\n    else if not fdDouble and (SameValue(Value, -MaxSingle) or (Value < -MaxSingle)) then\n      PCardinal(aBasePtr)^ := $FF7FFFFF\n    else begin\n      Value := RoundToEx(Value, -fdDigits);\n      Value := Value / fdScale;\n      if Assigned(fdNormalizer) then\n        Value := fdNormalizer(aElement, Value);\n      if fdDouble then\n        PDouble(aBasePtr)^ := Value\n      else\n        PSingle(aBasePtr)^ := Value;\n    end;\n    if noTerminator then\n      PByte(aBasePtr)[SizeOf(Single)] := wbTerminator;\n  end;\nend;\n\nfunction TwbFloatDef.GetDefType: TwbDefType;\nbegin\n  Result := dtFloat;\nend;\n\nfunction TwbFloatDef.GetDefTypeName: string;\nbegin\n  Result := 'Float';\nend;\n\nfunction TwbFloatDef.GetIsEditable(aBasePtr, aEndPtr: Pointer; const aElement: IwbElement): Boolean;\nbegin\n  Result := True;\nend;\n\nfunction TwbFloatDef.GetSize(aBasePtr, aEndPtr: Pointer; const aElement: IwbElement): Integer;\nbegin\n  if Assigned(aBasePtr) and Assigned(aEndPtr) and (Cardinal(aBasePtr) >= Cardinal(aEndPtr)) then\n    Result := Ord(noTerminator)\n  else\n    Result := GetDefaultSize(aBasePtr, aEndPtr, aElement)\nend;\n\nfunction TwbFloatDef.GetDefaultSize(aBasePtr, aEndPtr: Pointer; const aElement: IwbElement): Integer;\nbegin\n  if fdDouble then\n    Result := SizeOf(Double) + Ord(noTerminator)\n  else\n    Result := SizeOf(Single) + Ord(noTerminator);\nend;\n\nfunction TwbFloatDef.SetToDefault(aBasePtr, aEndPtr: Pointer; const aElement: IwbElement): Boolean;\nvar\n  Value: Extended;\nbegin\n  Value := ToNativeValue(aBasePtr, aEndPtr, aElement);\n  if fdDouble then\n    Result := not Assigned(aBasePtr) or not SameValue(Value, fdDefault)\n  else\n    Result := not Assigned(aBasePtr) or not SingleSameValue(Value, fdDefault);\n  if Result then\n    FromNativeValue(aBasePtr, aEndPtr, aElement, fdDefault);\nend;\n\nfunction TwbFloatDef.ToValue(aBasePtr, aEndPtr: Pointer; const aElement: IwbElement): Extended;\nvar\n  Len   : Cardinal;\n  Value : Extended;\nbegin\n  Len := Cardinal(aEndPtr) - Cardinal(aBasePtr);\n  if Len < GetDefaultSize(aBasePtr, aEndPtr, aElement) then\n    Result := NaN\n  else if fdDouble then try\n    if PInt64(aBasePtr)^ = $7FEFFFFFFFFFFFFF then\n      Result := maxDouble\n    else if PInt64(aBasePtr)^ = $FFEFFFFFFFFFFFFF then\n      Result := -maxDouble\n    else begin\n      Value := PDouble(aBasePtr)^;\n      if IsInfinite(Value) or IsNan(Value) then\n        Result := Value\n      else begin\n        try\n          if Value <> 0.0 then\n            if SameValue(Value, 0.0) then\n              Value := 0.0;\n        except\n          Value := 0.0;\n        end;\n\n        if Assigned(fdNormalizer) then\n          Value := fdNormalizer(aElement, Value);\n        Value := Value * fdScale;\n        Result := RoundToEx(Value, -fdDigits);\n      end;\n    end;\n  except\n    Result := NaN;\n  end else try\n    if PCardinal(aBasePtr)^ = $7F7FFFFF then\n      Result := maxSingle\n    else if PCardinal(aBasePtr)^ = $FF7FFFFF then\n      Result := -maxSingle\n    else begin\n      Value := PSingle(aBasePtr)^;\n      if IsInfinite(Value) or IsNan(Value) then\n        Result := Value\n      else begin\n        try\n          if Value <> 0.0 then\n            if SingleSameValue(Value, 0.0) then\n              Value := 0.0;\n        except\n          Value := 0.0;\n        end;\n\n        if Assigned(fdNormalizer) then\n          Value := fdNormalizer(aElement, Value);\n        Value := Value * fdScale;\n        Result := RoundToEx(Value, -fdDigits);\n      end;\n    end;\n  except\n    Result := NaN;\n  end;\nend;\n\nfunction TwbFloatDef.ToEditValue(aBasePtr, aEndPtr: Pointer; const aElement: IwbElement): string;\nvar\n  Value : Extended;\nbegin\n  Value := ToValue(aBasePtr, aEndPtr, aElement);\n  if IsNaN(Value) then\n    Result := 'NaN'\n  else if IsInfinite(Value) then\n    Result := 'Inf'\n  else if (Value = maxDouble) or (Value = maxSingle) then\n    Result := 'Default' // 'Max' ??\n  else if (Value = -maxDouble) or (Value = -maxSingle) then\n    Result := 'Min'\n  else\n    Result := FloatToStrF(Value, ffFixed, 99, fdDigits);\nend;\n\nfunction TwbFloatDef.ToNativeValue(aBasePtr, aEndPtr: Pointer; const aElement: IwbElement): Variant;\nvar\n  Value: Extended;\nbegin\n  Value := ToValue(aBasePtr, aEndPtr, aElement);\n  if IsNaN(Value) then\n    VarClear(Result)\n  else if Value = maxDouble then\n    Result := maxDouble\n  else if Value = maxSingle then\n    Result := maxSingle\n  else\n    Result := Value;\nend;\n\nfunction TwbFloatDef.ToSortKey(aBasePtr, aEndPtr: Pointer; const aElement: IwbElement; aExtended: Boolean): string;\nvar\n  Value : Extended;\n  g     : Extended;\nconst\n  PlusMinus : array[Boolean] of string = ('+', '-');\nbegin\n  Value := ToValue(aBasePtr, aEndPtr, aElement);\n  if IsNaN(Value) then\n    Result := StringOfChar(' ', 23)\n  else if (Value = maxDouble) or (Value = maxSingle) then\n    Result := '+' + StringOfChar('9', 22)\n  else begin\n    g := Abs(Value);\n    Result := FloatToStrF(g, ffFixed, 99, fdDigits);\n\n    if Length(Result) < 22 then\n      Result := StringOfChar('0', 22 - Length(Result)) + Result;\n    Result := PlusMinus[(Value < 0) and not IsZero(Value, 0.0000009999999999)] + Result;\n  end;\nend;\n\nfunction TwbFloatDef.ToString(aBasePtr, aEndPtr: Pointer; const aElement: IwbElement): string;\nvar\n  Len   : Cardinal;\n  Value : Extended;\nbegin\n  Result := '';\n  Len := Cardinal(aEndPtr) - Cardinal(aBasePtr);\n  if Len < GetDefaultSize(aBasePtr, aEndPtr, aElement) then begin\n    if wbCheckExpectedBytes then\n      Result := Format('<Error: Expected %d bytes of data, found %d>', [GetDefaultSize(aBasePtr, aEndPtr, aElement), Len])\n  end else begin\n    Value := ToValue(aBasePtr, aEndPtr, aElement);\n    if IsNan(Value) then\n      Result := 'NaN'\n    else if IsInfinite(Value) then\n      Result := 'Inf'\n    else if (Value=maxDouble) or (Value=maxSingle) then\n      Result := 'Default' // 'Max' ??\n    else if (Value=-maxDouble) or (Value=-maxSingle) then\n      Result := 'Min'\n    else\n      Result := FloatToStrF(Value, ffFixed, 99, fdDigits);\n    if Len > GetDefaultSize(aBasePtr, aEndPtr, aElement) then\n      if wbCheckExpectedBytes then\n        Result := Format(' <Warning: Expected %d bytes of data, found %d>', [GetDefaultSize(aBasePtr, aEndPtr, aElement), Len]);\n  end;\n  Used(aElement, Result);\nend;\n\n{ TwbChar4 }\n\nprocedure TwbChar4.BuildRef(aInt: Int64; const aElement: IwbElement);\nvar\n  U32: Cardinal;\n  _File: IwbFile;\n  Rec: IwbMainRecord;\nbegin\n  U32 := aInt;\n\n  _File := aElement._File;\n  if Assigned(_File) then begin\n    Rec := _File.RecordByEditorID[PwbSignature(@U32)^];\n    if Assigned(Rec) then\n      aElement.AddReferencedFromID(Rec.LoadOrderFormID); // should always be 00, these are only defined in Oblivion.esm\n  end;\nend;\n\nfunction TwbChar4.CanAssign(const aElement: IwbElement; aIndex: Integer; const aDef: IwbDef): Boolean;\nbegin\n  Result := Supports(aDef, IwbChar4);\nend;\n\nfunction TwbChar4.CanContainFormIDs: Boolean;\nbegin\n  Result := True;\nend;\n\nconstructor TwbChar4.Clone(const aSource: TwbDef);\nbegin\n  with aSource as TwbChar4 do\n    Self.Create(defPriority, defRequired, defGetCP).defSource := aSource;\nend;\n\nfunction TwbChar4.FromEditValue(const aValue: string; const aElement: IwbElement): Int64;\nconst\n  Empty : TwbSignature = '    ';\nvar\n  s     : AnsiString;\nbegin\n  if aValue = '' then\n    Result := Cardinal(Empty)\n  else begin\n    s := AnsiString(aValue);\n    if Length(s) <> 4 then\n      raise Exception.Create('The value must be exactly 4 characters');\n\n    Result := PCardinal(@s[1])^;\n  end;\nend;\n\nfunction TwbChar4.GetIsEditable(aInt: Int64; const aElement: IwbElement): Boolean;\nbegin\n  Result := True;\nend;\n\nfunction TwbChar4.GetLinksTo(aInt: Int64; const aElement: IwbElement): IwbElement;\nvar\n  U32: Cardinal;\n  _File: IwbFile;\nbegin\n  Result := nil;\n  U32 := aInt;\n  _File := aElement._File;\n  if Assigned(_File) then\n    Result := _File.RecordByEditorID[PwbSignature(@U32)^];\nend;\n\nfunction TwbChar4.ToEditValue(aInt: Int64; const aElement: IwbElement): string;\nbegin\n  Result := ToSortKey(aInt, aElement);\nend;\n\nfunction TwbChar4.ToSortKey(aInt: Int64; const aElement: IwbElement): string;\nvar\n  U32: Cardinal;\nbegin\n  U32 := aInt;\n  Result := PwbSignature(@U32)^;\nend;\n\nfunction TwbChar4.ToString(aInt: Int64; const aElement: IwbElement): string;\nvar\n  U32: Cardinal;\n  _File: IwbFile;\n  Rec: IwbRecord;\nbegin\n  U32 := aInt;\n  Result := PwbSignature(@U32)^;\n\n  _File := aElement._File;\n  if Assigned(_File) then begin\n    Rec := _File.RecordByEditorID[Result];\n    if Assigned(Rec) then begin\n      Result := Rec.Name;\n      Used(aElement, Result);\n      Exit;\n    end;\n  end;\n\n  if U32 <> 0 then\n    Result := Result + ' <Warning: could not be resolved>';\n  Used(aElement, Result);\nend;\n\n{ TwbStr4 }\n\nfunction TwbStr4.CanAssign(const aElement: IwbElement; aIndex: Integer; const aDef: IwbDef): Boolean;\nbegin\n  Result := Supports(aDef, IwbStr4);\nend;\n\nfunction TwbStr4.CanContainFormIDs: Boolean;\nbegin\n  Result := False;\nend;\n\nconstructor TwbStr4.Clone(const aSource: TwbDef);\nbegin\n  with aSource as TwbStr4 do\n    Self.Create(defPriority, defRequired, defGetCP).defSource := aSource;\nend;\n\nfunction TwbStr4.FromEditValue(const aValue: string; const aElement: IwbElement): Int64;\nconst\n  Empty : TwbSignature = '    ';\nvar\n  s     : AnsiString;\n  Temp  : AnsiString;\n  i     : Integer;\nbegin\n  if aValue = '' then\n    Result := Cardinal(Empty)\n  else begin\n    s := AnsiString(aValue);\n    if Length(s) <> 4 then\n      raise Exception.Create('The value must be exactly 4 characters');\n    Temp := s;\n    for i := 1 to 4 do s[i] := Temp[5-i];\n\n    Result := PCardinal(@s[1])^;\n  end;\nend;\n\nfunction TwbStr4.GetIsEditable(aInt: Int64; const aElement: IwbElement): Boolean;\nbegin\n  Result := True;\nend;\n\nfunction TwbStr4.ToEditValue(aInt: Int64; const aElement: IwbElement): string;\nbegin\n  Result := ToSortKey(aInt, aElement);\nend;\n\nfunction TwbStr4.ToSortKey(aInt: Int64; const aElement: IwbElement): string;\nbegin\n  Result := wbStr4ToString(aInt);\nend;\n\nfunction TwbStr4.ToString(aInt: Int64; const aElement: IwbElement): string;\nbegin\n  Result := ToSortKey(aInt, aElement);\n  Used(aElement, Result);\nend;\n\n{ TwbFormID }\n\nprocedure TwbFormID.BuildRef(aInt: Int64; const aElement: IwbElement);\nbegin\n  if ((aInt < $800) or (aInt = $FFFFFFFF)) and IsValid('ACVA') then\n    Exit;\n\n  if (aInt <> 0) and (aInt <> $14) then\n    aElement.AddReferencedFromID(aInt);\nend;\n\nfunction TwbFormID.CanAssign(const aElement: IwbElement; aIndex: Integer; const aDef: IwbDef): Boolean;\nbegin\n  Result := Supports(aDef, IwbFormID);\nend;\n\nfunction TwbFormID.CanContainFormIDs: Boolean;\nbegin\n  Result := True;\nend;\n\nfunction TwbFormID.Check(aInt: Int64;\n  const aElement: IwbElement): string;\nvar\n  _File: IwbFile;\n  MainRecord: IwbMainRecord;\nbegin\n  Result := '';\n\n  if Assigned(aElement) then begin\n    _File := aElement._File;\n    if Assigned(_File) then begin\n      try\n        MainRecord := _File.RecordByFormID[aInt, True];\n        if Assigned(MainRecord) then\n          Exit;\n      except\n        on E: Exception do begin\n          Result := E.Message;\n          Exit;\n        end;\n      end;\n    end;\n  end;\n\n  if aInt > $800 then\n    Result := '['+IntToHex64(aInt,8)+'] < Error: Could not be resolved >';\nend;\n\nfunction TwbFormID.CheckFlst(const aMainRecord: IwbMainRecord): Boolean;\nbegin\n  Result := True;\nend;\n\nconstructor TwbFormID.Clone(const aSource: TwbDef);\nbegin\n  with aSource as TwbFormID do\n    Self.Create(defPriority, defRequired, defGetCP).defSource := aSource;\nend;\n\nfunction TwbFormID.CompareExchangeFormID(var aInt: Int64; aOldFormID: Cardinal; aNewFormID: Cardinal; const aElement: IwbElement): Boolean;\nvar\n  _File     : IwbFile;\n\n  FormID    : Cardinal;\n  FileID    : Integer;\n  NewFileID : Integer;\n  i         : Integer;\nbegin\n  Result := False;\n\n  if {(aInt < $800) or} (aInt = $FFFFFFFF) and IsValid('ACVA') then // Allows source to be reserverd as this does NOT change the record itself\n    Exit;\n\n  if Assigned(aElement) then begin\n    _File := aElement._File;\n    if Assigned(_File) then begin\n      FormID := aInt;\n      FileID := FormID shr 24;\n\n      if FileID >= _File.MasterCount then\n        FileID := _File.LoadOrder\n      else\n        FileID := _File.Masters[FileID].LoadOrder;\n\n      if FileID < 0 then\n        raise Exception.Create('Could not determine load order FormID for old value');\n\n      FormID := (FormID and $00FFFFFF) or (Cardinal(FileID) shl 24);\n      if FormID = aOldFormID then begin\n        FileID := aNewFormID shr 24;\n        NewFileID := -1;\n        if FileID = _File.LoadOrder then\n          NewFileID := _File.MasterCount\n        else\n          for i := 0 to Pred(_File.MasterCount) do\n            if _File.Masters[i].LoadOrder = FileID then begin\n              NewFileID := i;\n              break;\n            end;\n        if NewFileID < 0 then\n          raise Exception.Create('FormID ['+IntToHex64(aNewFormID, 8)+'] references a master which is not available in file ' + _File.Name);\n\n        FormID := (aNewFormID and $00FFFFFF) or (Cardinal(NewFileID) shl 24);\n        if aInt <> FormID then begin\n          aInt := FormID;\n          Result := True;\n        end;\n      end;\n    end;\n  end;\nend;\n\nfunction TwbFormID.FindRecordForAVCode(aInt: Int64; const aElement: IwbElement): IwbMainRecord;\nvar\n  CheckedFiles : TList;\n  MaxLoadOrder : Integer;\n\n  function CheckFile(aFile: IwbFile): IwbMainRecord;\n  var\n    Group : IwbContainerElementRef;\n    i     : Integer;\n    AV    : Variant;\n  begin\n    if CheckedFiles.IndexOf(Pointer(aFile)) >= 0 then\n      Exit(nil);\n    CheckedFiles.Add(Pointer(aFile));\n\n    if Supports(aFile.GroupBySignature['MISC'], IwbContainerElementRef, Group) then begin\n      for i := 0 to Pred(Group.ElementCount) do\n        if Supports(Group.Elements[i], IwbMainRecord, Result) then begin\n          Result := Result.HighestOverrideOrSelf[MaxLoadOrder];\n          if (Result.Flags._Flags and $000000C0) = $000000C0 then begin\n            AV := Result.ElementNativeValues['DATA\\Actor Value'];\n            if not (VarIsNull(AV) or VarIsEmpty(AV)) then begin\n              if AV = aInt then\n                Exit;\n            end;\n          end;\n        end;\n    end;\n    Result := nil;\n    for i := Pred(aFile.MasterCount) downto 0 do begin\n      Result := CheckFile(aFile.Masters[i]);\n      if Assigned(Result) then\n        Exit;\n    end;\n  end;\n\nvar\n  _File : IwbFile;\nbegin\n  Result := nil;\n\n  if not Assigned(aElement) then\n    Exit;\n\n  _File := aElement._File;\n  if not Assigned(_File) then\n    Exit;\n\n  if aInt < $800 then begin\n    CheckedFiles := TList.Create;\n    try\n      MaxLoadOrder := _File.LoadOrder;\n      Result := CheckFile(_File);\n    finally\n      CheckedFiles.Free;\n    end;\n  end else try\n    Result := _File.RecordByFormID[aInt, True];\n  except end;\nend;\n\nprocedure TwbFormID.FindUsedMasters(aInt: Int64; aMasters: PwbUsedMasters; const aElement: IwbElement);\nvar\n  OldValue   : Cardinal;\n  FileID     : Integer;\nbegin\n  if (aInt < $800) or (aInt = $FFFFFFFF) and IsValid('ACVA') then\n    Exit;\n\n  OldValue := aInt;\n  if OldValue <> 0 then begin\n    FileID := OldValue shr 24;\n    aMasters[FileID] := True;\n  end;\nend;\n\nfunction TwbFormID.FromEditValue(const aValue: string; const aElement: IwbElement): Int64;\nvar\n  _File     : IwbFile;\n\n  FormID    : Cardinal;\n  FileID    : Integer;\n  NewFileID : Integer;\n  i         : Integer;\n  s, t      : string;\nbegin\n  s := '';\n  t := aValue;\n  i := Pos('[', t);\n  while i > 0 do begin\n    Delete(t, 1, i);\n    i := Pos(']', t);\n    if i > 0 then begin\n      s := Copy(t, 1, Pred(i));\n      Delete(t, 1, i);\n      if (Length(s) = 13) and (s[5] = ':') then\n        Delete(s, 1, 5);\n    end;\n\n    try\n      StrToInt64('$' + s);\n      if Length(s) = 8 then\n        i := 0\n      else\n        i := Pos('[', t);\n    except\n      i := Pos('[', t);\n    end;\n  end;\n\n  if Length(s) = 8 then\n    Result := StrToInt64('$' + s)\n  else begin\n    if IsValid('ACVA') and SameText(Trim(aValue), 'None') then begin\n      Result := $FF;\n      Exit;\n    end else\n      Result := StrToInt64('$' + aValue);\n  end;\n\n  if not wbDisplayLoadOrderFormID then\n    Exit;\n\n  if Result < $800 then\n    Exit;\n\n  if Result = $FFFFFFFF then\n    Exit;\n\n  if Assigned(aElement) then begin\n    _File := aElement._File;\n    if Assigned(_File) then begin\n      FormID := Result;\n\n      FileID := FormID shr 24;\n      NewFileID := -1;\n      if FileID = _File.LoadOrder then\n        NewFileID := _File.MasterCount\n      else\n        for i := 0 to Pred(_File.MasterCount) do\n          if _File.Masters[i].LoadOrder = FileID then begin\n            NewFileID := i;\n            break;\n          end;\n\n      if NewFileID < 0 then\n        raise Exception.Create('FormID ['+IntToHex64(FormID, 8)+'] references a master which is not available in file ' + _File.Name);\n\n      FormID := (FormID and $00FFFFFF) or (Cardinal(NewFileID) shl 24);\n      Result := FormID;\n    end;\n  end;\nend;\n\nfunction TwbFormID.GetEditInfo(aInt: Int64; const aElement: IwbElement): string;\nvar\n  ACVAIsValid : Boolean;\n  Strings     : TStringList;\n  CheckAll    : Boolean;\n  Wait        : IwbWaitForm;\n  FilesProg   : IwbProgress;\n\n  procedure Process(const aFile: IwbFile);\n  var\n    i, j        : Integer;\n    s           : string;\n    MainRecord  : IwbMainRecord;\n    GroupRecord : IwbGroupRecord;\n    GroupsProg  : IwbProgress;\n    RecordsProg : IwbProgress;\n  begin\n    if CheckAll then begin\n      for i := 0 to Pred(aFile.RecordCount) do begin\n        MainRecord := aFile.Records[i];\n        if IsValid(MainRecord.Signature) and IsValidMainRecord(MainRecord) then begin\n          if MainRecord.CanHaveEditorID and (MainRecord.EditorID = '') then\n            Continue;\n\n          s := Trim(MainRecord.Name);\n          if s <> '' then begin\n            if s[1] = '<' then\n              Delete(s, 1, 1);\n\n            if CheckFlst(MainRecord) then\n              Strings.Add(s);\n\n            if not Assigned(RecordsProg) then\n              RecordsProg := Wait.CreateProgress('Records', s, Pred(aFile.RecordCount) )\n            else\n              RecordsProg.UpdateStatus(i, s);\n          end;\n        end;\n\n        if Wait.IsCanceled then\n          Exit;\n      end;\n    end else\n      for i := 0 to Pred(aFile.ElementCount) do begin\n\n        if not Assigned(GroupsProg) then\n          GroupsProg := Wait.CreateProgress('Groups', aFile.Elements[i].Name, Pred(aFile.ElementCount) )\n        else\n          GroupsProg.UpdateStatus(i, aFile.Elements[i].Name);\n\n        if Supports(aFile.Elements[i], IwbGroupRecord, GroupRecord) then\n          if GroupRecord.GroupType = 0 then\n            if IsValid(TwbSignature(GroupRecord.GroupLabel)) then\n              for j := 0 to Pred(GroupRecord.ElementCount) do begin\n\n                if Supports(GroupRecord.Elements[j], IwbMainRecord, MainRecord) then begin\n                  if IsValid(MainRecord.Signature) and IsValidMainRecord(MainRecord) then begin\n                    if MainRecord.CanHaveEditorID and (MainRecord.EditorID = '') then\n                      Continue;\n\n                    s := Trim(MainRecord.Name);\n                    if s <> '' then begin\n                      if s[1] = '<' then\n                        Delete(s, 1, 1);\n\n                      if CheckFlst(MainRecord) then\n                        Strings.Add(s);\n\n                      if not Assigned(RecordsProg) then\n                        RecordsProg := Wait.CreateProgress('Records', s, Pred(GroupRecord.ElementCount) )\n                      else\n                        RecordsProg.UpdateStatus(j, s);\n\n                    end;\n                  end;\n                end;\n\n                if Wait.IsCanceled then\n                  Exit;\n              end;\n\n        if Wait.IsCanceled then\n          Exit;\n      end;\n  end;\n\nvar\n  _File : IwbFile;\n  i     : Integer;\n  s     : string;\nbegin\n  Result := '';\n  if not wbDisplayLoadOrderFormID then\n    Exit;\n\n  ACVAIsValid := IsValid('ACVA');\n\n  if Assigned(aElement) then begin\n    _File := aElement._File;\n    if Assigned(_File) then begin\n      Strings := TwbFastStringListIC.Create;\n      try\n        CheckAll :=\n          IsValid('CELL') or\n          IsValid('LAND') or\n          IsValid('ROAD') or\n          IsValid('REFR') or\n          IsValid('ACHR') or\n          IsValid('ACRE') or\n          IsValid('PGRE') or\n          IsValid('PGRD') or\n          IsValid('PARW') or {>>> Skyrim <<<}\n          IsValid('PBAR') or {>>> Skyrim <<<}\n          IsValid('PBEA') or {>>> Skyrim <<<}\n          IsValid('PFLA') or {>>> Skyrim <<<}\n          IsValid('PCON') or {>>> Skyrim <<<}\n          IsValid('PHZD') or {>>> Skyrim <<<}\n          IsValid('NAVM') or\n          IsValid('INFO');\n\n        Wait := wbCreateWaitForm('Building DropDownList', 'The DropDown list is being built. Please Wait...', True, 2000, 500);\n\n        FilesProg := Wait.CreateProgress('Files', _File.Name, _File.MasterCount);\n        Process(_File);\n        for i := Pred(_File.MasterCount) downto 0 do if not Wait.IsCanceled then begin\n          FilesProg.UpdateStatus( _File.MasterCount - i, _File.Masters[i].Name );\n          Process(_File.Masters[i]);\n        end;\n\n        Wait := nil;\n        FilesProg := nil;\n\n        if ACVAIsValid then begin\n          for i := 0 to Pred(wbActorValueEnum.NameCount) do\n            Strings.Add(wbActorValueEnum.Names[i] + ' [ACVA:' + IntToHex64(i, 8) + ']');\n          Strings.Add(' None [ACVA:000000FF]');\n          Strings.Add(' Invalid [ACVA:00000048]');\n        end else begin\n          if IsValid('NULL') then\n            Strings.Add('NULL - Null Reference [00000000]');\n          if IsValid('FFFF') then\n            Strings.Add('FFFF - None Reference [FFFFFFFF]');\n          if IsValid('TRGT') then\n            Strings.Add('TARGET - Target Reference [00000000]');\n          if IsValid('PLYR') then\n            Strings.Add('Player [00000014]');\n        end;\n\n        Strings.Sort;\n        s := '';\n        for i := Pred(Strings.Count) downto 0 do\n          if Strings[i] <> s then\n            s := Strings[i]\n          else\n            Strings.Delete(i);\n\n        Result := Strings.CommaText;\n      finally\n        FreeAndNil(Strings);\n      end;\n    end;\n  end;\nend;\n\nfunction TwbFormID.GetEditType(aInt: Int64; const aElement: IwbElement): TwbEditType;\nbegin\n  Result := etComboBox;\nend;\n\nfunction TwbFormID.GetIsEditable(aInt: Int64; const aElement: IwbElement): Boolean;\nbegin\n  Result := True;\nend;\n\nfunction TwbFormID.GetLinksTo(aInt: Int64; const aElement: IwbElement): IwbElement;\nvar\n  _File : IwbFile;\nbegin\n  Result := nil;\n\n  if aInt = 0 then\n    Exit;\n  if aInt = $14 then\n    Exit;\n  if (aInt = $FFFFFFFF) and IsValid('FFFF') then\n    Exit;\n\n  if (aInt < $800) and IsValid('ACVA') then\n    Exit;\n\n  if Assigned(aElement) then begin\n    _File := aElement._File;\n    if Assigned(_File) then try\n      Result := _File.RecordByFormID[aInt, True];\n    except end;\n  end;\nend;\n\nfunction TwbFormID.GetMainRecord(aInt: Int64; const aElement: IwbElement): IwbMainRecord;\nvar\n  _File: IwbFile;\nbegin\n  Result := nil;\n  if Assigned(aElement) then begin\n    _File := aElement._File;\n    if Assigned(_File) then\n      Result := _File.RecordByFormID[aInt, True];\n  end;\nend;\n\nfunction TwbFormID.IsValid(const aSignature: TwbSignature): Boolean;\nbegin\n  Result := aSignature <> 'ACVA';\nend;\n\nfunction TwbFormID.IsValidFlst(const aSignature: TwbSignature): Boolean;\nbegin\n  Result := True;\nend;\n\nfunction TwbFormID.IsValidMainRecord(const aMainRecord: IwbMainRecord): Boolean;\nbegin\n  Result := True;\nend;\n\nfunction TwbFormID.MasterCountUpdated(aInt: Int64; aOld, aNew: Byte; const aElement: IwbElement): Int64;\nvar\n  OldValue   : Cardinal;\n  NewValue   : Cardinal;\n  FileID     : Cardinal;\nbegin\n  OldValue := aInt;\n  NewValue := OldValue;\n\n  if (aInt < $800) or (aInt = $FFFFFFFF) and (IsValid('ACVA') or IsValid('FFFF')) then begin\n    Result := NewValue;\n    Exit;\n  end;\n\n  if OldValue <> 0 then begin\n    FileID := OldValue shr 24;\n    if FileID >= aOld then begin\n      FileID := aNew;\n      NewValue := (OldValue and $00FFFFFF) or (FileID shl 24);\n    end;\n  end;\n\n  Result := NewValue;\nend;\n\nfunction FixupFormID(aFormID: Cardinal; const aOld, aNew: TBytes): Cardinal;\nvar\n  FileID : Integer;\n  i      : Integer;\nbegin\n  Result := aFormID;\n  if (Result = 0) or (Result = $14) or (Result = $FFFFFFFF) then\n    Exit;\n  FileID := aFormID shr 24;\n  for i := Low(aOld) to High(aOld) do\n    if aOld[i] = FileID then begin\n      Result := (aFormID and $00FFFFFF) or (Cardinal(aNew[i]) shl 24);\n      Exit;\n    end;\nend;\n\nfunction TwbFormID.MasterIndicesUpdated(aInt: Int64; const aOld, aNew: TBytes; const aElement: IwbElement): Int64;\nvar\n  OldValue   : Cardinal;\n  NewValue   : Cardinal;\nbegin\n  OldValue := aInt;\n  NewValue := OldValue;\n\n  if (aInt < $800) or (aInt = $FFFFFFFF) and (IsValid('ACVA') or IsValid('FFFF')) then begin\n    Result := NewValue;\n    Exit;\n  end;\n\n  if OldValue <> 0 then\n    NewValue := FixupFormID(OldValue, aOld, aNew);\n\n  Result := NewValue;\nend;\n\nprocedure TwbFormID.Report(const aParents: TwbDefPath);\nvar\n  i: Integer;\nbegin\n  if defReported then\n    Exit;\n\n  inherited;\n  if wbReportMode then\n    if wbReportFormIDs then begin\n      if Assigned(FoundSignatures) then\n        if ClassType = TwbFormID then begin\n          WriteLn('Unchecked FormID Formater: ', wbDefsToPath(aParents), wbDefToName(Self));\n          WriteLn('  ', FoundSignatures.CommaText);\n          for i := 0 to Pred(FoundSignatures.Count) do\n            WriteLn('  ', FoundSignatures.Strings[i], ' (', Integer(FoundSignatures.Objects[i]),')');\n        end;\n      if Assigned(NotResolved) then begin\n        WriteLn('FormID contains unresolvable values: ', wbDefsToPath(aParents), wbDefToName(Self));\n        for i := 0 to Pred(NotResolved.Count) do\n          WriteLn('  ', NotResolved.Strings[i], ' (', Integer(NotResolved.Objects[i]),')');\n      end;\n      if Assigned(FoundNotAllowedReferences) then begin\n        WriteLn('FormID contains not allowed references: ', wbDefsToPath(aParents), wbDefToName(Self));\n        for i := 0 to Pred(FoundNotAllowedReferences.Count) do\n          WriteLn('  ', FoundNotAllowedReferences.Strings[i], ' (', Integer(FoundNotAllowedReferences.Objects[i]),')');\n      end;\n    end;\n\n  defReported := True;\nend;\n\nfunction TwbFormID.ToEditValue(aInt: Int64; const aElement: IwbElement): string;\nbegin\n  if wbDisplayLoadOrderFormID then begin\n    Result := ToString(aInt, aElement);//ToSortKey(aInt, aElement)\n    if (Length(Result) > 0) and (Result[1] = '<') then\n      Delete(Result, 1, 1);\n  end else\n    Result := IntToHex64(aInt, 8);\nend;\n\nfunction TwbFormID.ToSortKey(aInt: Int64; const aElement: IwbElement): string;\nvar\n  MainRecord: IwbMainRecord;\nbegin\n  if (aInt < $800) or (aInt = $FFFFFFFF) then begin\n    Result := IntToHex64(aInt, 8);\n    Exit;\n  end;\n\n  MainRecord := GetMainRecord(aInt, aElement);\n  if Assigned(MainRecord) then begin\n    try\n      Result := IntToHex64(MainRecord.LoadOrderFormID, 8);\n      Exit;\n    except\n      on E: Exception do begin\n        Result := IntToHex64(aInt, 8);\n        Exit;\n      end;\n    end;\n  end;\n\n  Result := IntToHex64(aInt, 8);\nend;\n\nfunction TwbFormID.ToString(aInt: Int64; const aElement: IwbElement): string;\nvar\n  _File      : IwbFile;\n  i          : Integer;\n  s          : string;\n  MainRecord : IwbMainRecord;\nbegin\n  if ((aInt < $800) or (aInt = $FFFFFFFF)) and IsValid('ACVA') then begin\n    if (aInt = -1) or (aInt = $FF) or (aInt = $FFFFFFFF) then\n      Result := ' None [ACVA:000000FF]'\n    else if aInt = $48 then\n      Result := ' Invalid [ACVA:00000048]'\n    else begin\n      MainRecord := FindRecordForAVCode(aInt, aElement);\n      if Assigned(MainRecord) then\n        Result := MainRecord.FullName\n      else\n        Result := wbActorValueEnum.ToString(aInt, aElement);\n      Result := Result + ' [ACVA:' + IntToHex64(aInt,8) + ']';\n    end;\n    Exit;\n  end;\n\n  if aInt = 0 then begin\n    if IsValid('TRGT') and not IsValid('NULL') then begin\n      Result := 'TARGET - Target Reference ['+IntToHex64(aInt,8)+']';\n      if wbReportMode then\n        if wbReportFormIDs then begin\n          if not Assigned(FoundSignatures) then\n            FoundSignatures := TwbFastStringListCS.CreateSorted;\n          if not FoundSignatures.Find('TRGT', i) then\n            i := FoundSignatures.Add('TRGT');\n          FoundSignatures.Objects[i] := TObject(Succ(Integer(FoundSignatures.Objects[i])));\n        end;\n    end else begin\n      Result := 'NULL - Null Reference ['+IntToHex64(aInt,8)+']';\n      if wbReportMode then\n        if wbReportFormIDs then begin\n          if not Assigned(FoundSignatures) then\n            FoundSignatures := TwbFastStringListCS.CreateSorted;\n          if not FoundSignatures.Find('NULL', i) then\n            i := FoundSignatures.Add('NULL');\n          FoundSignatures.Objects[i] := TObject(Succ(Integer(FoundSignatures.Objects[i])));\n        end;\n    end;\n    Used(aElement, Result);\n    Exit;\n  end else if aInt = $FFFFFFFF then begin\n    Result := 'FFFF - None Reference ['+IntToHex64(aInt,8)+']';\n    if wbReportMode then\n      if wbReportFormIDs then begin\n        if not Assigned(FoundSignatures) then\n          FoundSignatures := TwbFastStringListCS.CreateSorted;\n        if not FoundSignatures.Find('FFFF', i) then\n          i := FoundSignatures.Add('FFFF');\n        FoundSignatures.Objects[i] := TObject(Succ(Integer(FoundSignatures.Objects[i])));\n      end;\n    Used(aElement, Result);\n    Exit;\n  end else if aInt = $14 then begin\n    if wbReportMode then\n      if wbReportFormIDs then begin\n        if not Assigned(FoundSignatures) then\n          FoundSignatures := TwbFastStringListCS.CreateSorted;\n        if not FoundSignatures.Find('PLYR', i) then\n          i := FoundSignatures.Add('PLYR');\n        FoundSignatures.Objects[i] := TObject(Succ(Integer(FoundSignatures.Objects[i])));\n      end;\n\n    Result := 'Player ['+IntToHex64(aInt,8)+']';\n    Used(aElement, Result);\n    Exit;\n  end;\n\n  if Assigned(aElement) then begin\n    _File := aElement._File;\n    if Assigned(_File) then begin\n      try\n        MainRecord := _File.RecordByFormID[aInt, True];\n        if Assigned(MainRecord) then begin\n          Result := MainRecord.Name;\n          if wbReportMode then\n            if wbReportFormIDs then begin\n              if not Assigned(FoundSignatures) then\n                FoundSignatures := TwbFastStringListCS.CreateSorted;\n              if not FoundSignatures.Find(MainRecord.Signature, i) then\n                i := FoundSignatures.Add(MainRecord.Signature);\n              FoundSignatures.Objects[i] := TObject(Succ(Integer(FoundSignatures.Objects[i])));\n            end;\n\n          if wbReportFormIDNotAllowedReferences and (ClassType = TwbFormIDChecked) then with TwbFormIDChecked(Self) do begin\n              if fidcValidRefs.IndexOf(MainRecord.Signature) < 0 then begin\n                if not Assigned(FoundNotAllowedReferences) then\n                  FoundNotAllowedReferences := TwbFastStringListCS.CreateSorted;\n                if not FoundNotAllowedReferences.Find(MainRecord.Name, i) then\n                  i := FoundNotAllowedReferences.Add(MainRecord.Name);\n                FoundNotAllowedReferences.Objects[i] := TObject(Succ(Integer(FoundNotAllowedReferences.Objects[i])));\n              end;\n          end;\n\n          Used(aElement, Result);\n          Exit;\n        end;\n      except\n        on E: Exception do begin\n          Result := '['+IntToHex64(aInt,8)+'] <Error: '+E.Message+'>';\n          if wbReportMode then\n            if wbReportFormIDs then begin\n              if not Assigned(FoundSignatures) then\n                FoundSignatures := TwbFastStringListCS.CreateSorted;\n              if not FoundSignatures.Find('Error', i) then\n                i := FoundSignatures.Add('Error');\n              FoundSignatures.Objects[i] := TObject(Succ(Integer(FoundSignatures.Objects[i])));\n            end;\n          Used(aElement, Result);\n          Exit;\n        end;\n      end;\n    end;\n  end;\n\n  if aInt < $800 then begin\n    s := IntToHex64(aInt,8);\n    Result := '['+s+'] <Warning: Could not be resolved, but is possibly hardcoded in the engine>';\n    if wbReportMode then\n      if wbReportFormIDs then begin\n        if not Assigned(FoundSignatures) then\n          FoundSignatures := TwbFastStringListCS.CreateSorted;\n        if not FoundSignatures.Find('Hardcoded', i) then\n          i := FoundSignatures.Add('Hardcoded');\n        FoundSignatures.Objects[i] := TObject(Succ(Integer(FoundSignatures.Objects[i])));\n\n        if not Assigned(NotResolved) then\n          NotResolved := TwbFastStringListCS.CreateSorted;\n        if NotResolved.Count < 50 then begin\n          if not NotResolved.Find(s, i) then\n            i := NotResolved.Add(s);\n          NotResolved.Objects[i] := TObject(Succ(Integer(NotResolved.Objects[i])));\n        end;\n      end;\n  end else begin\n    s := IntToHex64(aInt,8);\n    Result := '['+s+'] < Error: Could not be resolved >';\n    if wbReportMode then\n      if wbReportFormIDs then begin\n        if not Assigned(FoundSignatures) then\n          FoundSignatures := TwbFastStringListCS.CreateSorted;\n        if not FoundSignatures.Find('NotResolved', i) then\n          i := FoundSignatures.Add('NotResolved');\n        FoundSignatures.Objects[i] := TObject(Succ(Integer(FoundSignatures.Objects[i])));\n\n        if not Assigned(NotResolved) then\n          NotResolved := TwbFastStringListCS.CreateSorted;\n        if NotResolved.Count < 50 then begin\n          if not NotResolved.Find(s, i) then\n            i := NotResolved.Add(s);\n          NotResolved.Objects[i] := TObject(Succ(Integer(NotResolved.Objects[i])));\n        end;\n      end;\n  end;\n  Used(aElement, Result);\nend;\n\n{ TwbByteArrayDef }\n\nfunction TwbByteArrayDef.CanAssign(const aElement: IwbElement; aIndex: Integer; const aDef: IwbDef): Boolean;\nvar\n  ByteArrayDef: IwbByteArrayDef;\nbegin\n  Result := Supports(aDef, IwbByteArrayDef, ByteArrayDef);\n  if Result and (badSize > 0) then begin\n    Result := ByteArrayDef.IsVariableSize or (ByteArrayDef.DefaultSize[nil, nil, nil] <= Integer(badSize));\n  end;\nend;\n\nfunction TwbByteArrayDef.CanContainFormIDs: Boolean;\nbegin\n  Result := False;\nend;\n\nconstructor TwbByteArrayDef.Clone(const aSource: TwbDef);\nbegin\n  with aSource as TwbByteArrayDef do\n    Self.Create(defPriority, defRequired, noName, badSize, noDontShow, badCountCallBack, defGetCP, noTerminator).defSource := aSource;\nend;\n\nconstructor TwbByteArrayDef.Create(aPriority      : TwbConflictPriority;\n                                   aRequired      : Boolean;\n                             const aName          : string;\n                                   aSize          : Int64;\n                                   aDontShow      : TwbDontShowCallback;\n                                   aCountCallback : TwbCountCallback;\n                                   aGetCP         : TwbGetConflictPriority;\n                                   aTerminator    : Boolean);\nbegin\n  badSize := aSize;\n  badCountCallback := aCountCallback;\n  inherited Create(aPriority, aRequired, aName, nil, nil, aDontShow, aGetCP, aTerminator);\nend;\n\nprocedure TwbByteArrayDef.FromEditValue(aBasePtr, aEndPtr: Pointer; const aElement: IwbElement; const aValue: string);\nvar\n  Bytes  : array of Byte;\n  i, j   : Integer;\n  Prefix : Integer;\nbegin\n  SetLength(Bytes, Length(aValue) div 2);\n  i := 1;\n  j := 0;\n  while i <= Length(aValue) do begin\n    case aValue[i] of\n      ' ', ',', ';': {allowed whitespace}\n        Inc(i);\n      '0'..'9', 'a'..'f', 'A'..'F': begin\n        if i = Length(aValue) then\n          raise Exception.Create('Unexpected end of value. Single digit in hexadecimal pair');\n        if aValue[Succ(i)] in ['0'..'9', 'a'..'f', 'A'..'F'] then begin\n          Bytes[j] := StrToInt('$'+Copy(aValue,i, 2));\n          Inc(j);\n          Inc(i, 2);\n        end else\n          raise Exception.Create('\"'+aValue[Succ(i)]+'\" at position '+IntToStr(Succ(i))+' is not a valid character for ' + GetName);\n      end;\n    else\n      raise Exception.Create('\"'+aValue[i]+'\" at position '+IntToStr(i)+' is not a valid character for ' + GetName);\n    end;\n  end;\n\n  SetLength(Bytes, j);\n\n  case badSize of\n    -1 : Prefix := SizeOf(Cardinal);\n    -2 : Prefix := SizeOf(Word);\n    -4 : Prefix := SizeOf(Byte);\n  else\n    Prefix := 0;\n  end;\n  if (badSize > 0) then\n    SetLength(Bytes, badSize);\n\n  aElement.RequestStorageChange(aBasePtr, aEndPtr, Length(Bytes)+Prefix);\n\n  if Length(Bytes) > 0 then\n    Move(Bytes[0], Pointer(Cardinal(aBasePtr)+Prefix)^, Length(Bytes));\nend;\n\nprocedure TwbByteArrayDef.FromNativeValue(aBasePtr, aEndPtr: Pointer; const aElement: IwbElement; const aValue: Variant);\nvar\n  Bytes  : TBytes;\n  Prefix : Integer;\nbegin\n  Bytes := aValue;\n\n  case badSize of\n    -1 : Prefix := SizeOf(Cardinal);\n    -2 : Prefix := SizeOf(Word);\n    -4 : Prefix := SizeOf(Byte);\n  else\n    Prefix := 0;\n  end;\n  if (badSize > 0) then\n    SetLength(Bytes, badSize);\n\n  aElement.RequestStorageChange(aBasePtr, aEndPtr, Length(Bytes)+Prefix);\n\n  if Length(Bytes) > 0 then\n    Move(Bytes[0], Pointer(Cardinal(aBasePtr)+Prefix)^, Length(Bytes));\nend;\n\nfunction TwbByteArrayDef.GetDefType: TwbDefType;\nbegin\n  Result := dtByteArray;\nend;\n\nfunction TwbByteArrayDef.GetDefTypeName: string;\nbegin\n  if badSize > 0 then\n    Result := IntToStr(badSize)+' Bytes Array'\n  else if Assigned(badCountCallback) then\n    Result := 'Variable Size Byte Array'\n  else case badSize of\n        -1 : Result := 'Variable Size Byte Array with four bytes length';\n        -2 : Result := 'Variable Size Byte Array with two bytes length';\n        -4 : Result := 'Variable Size Byte Array with one byte length';\n      -255 : Result := 'Null';\n         0 : Result := 'Filler for remaining data';\n      end\nend;\n\nfunction TwbByteArrayDef.GetIsEditable(aBasePtr, aEndPtr: Pointer; const aElement: IwbElement): Boolean;\nbegin\n  Result := True;\nend;\n\nfunction TwbByteArrayDef.GetIsVariableSizeInternal: Boolean;\nbegin\n  Result := badSize <= 0;\nend;\n\nfunction TwbByteArrayDef.GetSize(aBasePtr, aEndPtr: Pointer; const aElement: IwbElement): Integer;\nbegin\n  if Assigned(aBasePtr) and Assigned(aEndPtr) and (Cardinal(aBasePtr) >= Cardinal(aEndPtr)) then\n    Result := 0\n  else if Assigned(badCountCallback) then\n    Result := badCountCallback(aBasePtr, aEndPtr, aElement)\n  else begin\n    Result := badSize;\n    if Assigned(aBasePtr) then\n      case Result of\n        -1 : Result := PCardinal(aBasePtr)^+SizeOf(Cardinal);\n        -2 : Result := PWord(aBasePtr)^+SizeOf(Word);\n        -4 : Result := PByte(aBasePtr)^+SizeOf(Byte);\n      -255 : Result := 0; // Explicitly null for wbNull (displays better in unions)\n         0 : Result := High(Integer);\n      end\n    else if Result < 0 then Result := 0;\n  end;\n  if Result>0 then Inc(Result, Ord(noTerminator));\nend;\n\nfunction TwbByteArrayDef.GetDefaultSize(aBasePtr, aEndPtr: Pointer; const aElement: IwbElement): Integer;\nbegin\n  if badSize>=0 then\n    Result := badSize\n  else\n    case badSize of\n      -1 : Result := SizeOf(Cardinal);\n      -2 : Result := SizeOf(Word);\n      -4 : Result := SizeOf(Byte);\n    -255 : Result := 0; // Explicitly null for wbNull (displays better in unions)\n    else\n      Result := 0;\n    end;\n  if Result>0 then Inc(Result, Ord(noTerminator));\nend;\n\nprocedure TwbByteArrayDef.Report(const aParents: TwbDefPath);\nvar\n  FoundOne: Boolean;\n  {i,} j, k, l : Integer;\n  s: string;\n  sl: TStringList;\n  BA: TwbByteArrayDef;\nbegin\n  if defReported then\n    Exit;\n\n  inherited;\n  BA := Self;\n\n  s := wbDefsToPath(aParents) + wbDefToName(Self);\n\n  if (Pos('Hashes', s) < 1) and\n     (Pos('SCDA', s) < 1) and\n     (Pos('SCTX', s) < 1) and\n     (Pos('MODT', s) < 1) and\n     (Pos('MO2T', s) < 1) and\n     (Pos('MO3T', s) < 1) and\n     (Pos('MO4T', s) < 1) and\n     (Pos('DMDT', s) < 1) and\n     (Pos('NIFT', s) < 1) and\n     (Pos('XRGD', s) < 1) and\n     (Pos('XCLP', s) < 1) and\n     (Pos('RCLR', s) < 1) then begin\n\n    if wbReportUnknownFormIDs then begin\n      FoundOne := False;\n      with BA do begin\n        for j := Low(FoundFormIDAtOffSet) to High(FoundFormIDAtOffSet) do\n          if (FoundFormIDAtOffSet[j] > 2) and (NotFoundFormIDAtOffSet[j] = 0) then begin\n            if not FoundOne then begin\n              FoundOne := True;\n              WriteLn('Found FormIDs: ', s);\n            end;\n            with SignaturesAtOffSet[j] do begin\n              WriteLn('  Offset ', j, ': ', Count, ' (', FoundFormIDAtOffSet[j],')');\n              for k := 0 to Pred(Count) do begin\n                sl := Objects[k] as TStringList;\n                WriteLn('    ', Strings[k], ' (', sl.Count,')');\n                with sl do\n                  for l := 0 to Pred(Count) do\n                    WriteLn('      ', Strings[l],' (',Integer(Objects[l]),') ');\n              end;\n              if Assigned(FormIDsAtOffSetFoundIn[j]) then with FormIDsAtOffSetFoundIn[j] do\n                for k := 0 to Pred(Count) do\n                  WriteLn('    ', Strings[k]);\n            end;\n          end;\n\n      end;\n    end;\n\n    if wbReportUnknownFloats then begin\n      FoundOne := False;\n      with BA do begin\n        for j := Low(FoundFloatAtOffSet) to High(FoundFloatAtOffSet) do\n          if (FoundFloatAtOffSet[j] > 2) and (NotFoundFloatAtOffSet[j] = 0) then begin\n            if not FoundOne then begin\n              FoundOne := True;\n              WriteLn('Found Floats: ', s);\n            end;\n            with FloatsAtOffSet[j] do begin\n              WriteLn('  Offset ', j, ': ', Count, ' (', FoundFloatAtOffSet[j],')');\n              for k := 0 to Pred(Count) do\n                WriteLn('    ', Strings[k], ' (', Integer(Objects[k]),')');\n            end;\n          end;\n      end;\n    end;\n\n  end;\n\n  if wbReportUnknownStrings then\n    if (FoundString > 0) and (NotFoundString < 1) then begin\n      WriteLn('Found Strings: ', s, ': ',Strings.Count,' (', FoundString, ')');\n      with Strings do\n        for k := 0 to Pred(Count) do\n          WriteLn('  ', Strings[k], ' (', Integer(Objects[k]),')');\n    end;\n\n  if wbReportEmpty then\n    if IsEmpty > 0 then\n      if IsNotEmpty > 0 then begin\n        if wbReportSometimesEmpty then\n          WriteLn('Sometimes Empty: ', s, ': ', IsEmpty, ' (Empty) vs. ', IsNotEmpty, ' (not Empty)')\n      end else\n        WriteLn('Always Empty: ', s, ': ', IsEmpty, ' (Empty) vs. ', IsNotEmpty, ' (not Empty)');\n\n  defReported := True;\nend;\n\nfunction TwbByteArrayDef.SetToDefault(aBasePtr, aEndPtr: Pointer; const aElement: IwbElement): Boolean;\nvar\n  Size : Integer;\n  Default : String;\nbegin\n  Size := GetSize(aBasePtr, aEndPtr, aElement);\n  if (Size > 0) and (Size < High(Integer))  then begin\n    Default := '00';\n    while Length(Default)<(Size*3-1) do\n      Default := Default + ' 00';\n  end else\n    Default := '';\n  Result := not Assigned(aBasePtr) or (ToString(aBasePtr, aEndPtr, aElement) <> Default);\n  if Result then\n    FromEditValue(aBasePtr, aEndPtr, aElement, Default);\nend;\n\nfunction TwbByteArrayDef.ToEditValue(aBasePtr, aEndPtr: Pointer;\n  const aElement: IwbElement): string;\nbegin\n  Result := ToString(aBasePtr, aEndPtr, aElement);\nend;\n\nfunction TwbByteArrayDef.ToNativeValue(aBasePtr, aEndPtr: Pointer; const aElement: IwbElement): Variant;\nvar\n  Bytes: TBytes;\nbegin\n  case badSize of\n    -1 : aBasePtr := Pointer(Cardinal(aBasePtr)+SizeOf(Cardinal));\n    -2 : aBasePtr := Pointer(Cardinal(aBasePtr)+SizeOf(Word));\n    -4 : aBasePtr := Pointer(Cardinal(aBasePtr)+SizeOf(Byte));\n  end;\n  SetLength(Bytes, Cardinal(aEndPtr) - Cardinal(aBasePtr));\n  if Length(Bytes) > 0 then\n    Move(aBasePtr^, Bytes[0], Length(Bytes));\n  Result := Bytes;\nend;\n\nfunction CountBits(aCardinal: Cardinal): Integer;\nvar\n  i: Integer;\nbegin\n  Result := 0;\n  for I := 0 to 31 do\n    if (aCardinal shr i) and 1 = 1 then\n      Inc(Result);\nend;\n\nfunction TwbByteArrayDef.ToString(aBasePtr, aEndPtr: Pointer; const aElement: IwbElement): string;\nvar\n  p: PByte;\n{}  _File: IwbFile;\n  MainRecord: IwbMainRecord;\n  OffSet: Integer;\n  aInt: Cardinal;\n// Path : string;\n  s: string;\n  i: Integer;\n  f, f2: Single;\nbegin\n  Result := '';\n  case badSize of\n    -1 : aBasePtr := Pointer(Cardinal(aBasePtr)+SizeOf(Cardinal));\n    -2 : aBasePtr := Pointer(Cardinal(aBasePtr)+SizeOf(Word));\n    -4 : aBasePtr := Pointer(Cardinal(aBasePtr)+SizeOf(Byte));\n  end;\n  p := aBasePtr;\n  while Cardinal(p) < Cardinal(aEndPtr) do begin\n    Result := Result + IntToHex64(p^, 2) + ' ';\n    Inc(p);\n  end;\n  SetLength(Result, Length(Result) - 1);\n\n  if wbReportMode then begin\n    if Assigned(aElement) and (Self.noName <> 'Unused') then begin\n      _File := aElement._File;\n\n      if wbReportUnknownFormIDs then begin\n        p := aBasePtr;\n        OffSet := 0;\n        while (Cardinal(p)+3) < Cardinal(aEndPtr) do begin\n          aInt := PCardinal(p)^;\n          if (aInt <> $0) and (aInt <> $14) and ((Length(NotFoundFormIDAtOffSet) < Succ(OffSet)) or (NotFoundFormIDAtOffSet[Offset] < 1)) then begin\n            MainRecord := nil;\n            try\n              MainRecord := _File.RecordByFormID[aInt, True];\n            except\n              on E: Exception do begin\n                MainRecord := nil;\n              end;\n            end;\n            if Length(FoundFormIDAtOffSet) < Succ(Offset) then\n              SetLength(FoundFormIDAtOffSet, Succ(Offset));\n            if Length(NotFoundFormIDAtOffSet) < Succ(Offset) then\n              SetLength(NotFoundFormIDAtOffSet, Succ(Offset));\n            if Length(SignaturesAtOffSet) < Succ(Offset) then\n              SetLength(SignaturesAtOffSet, Succ(Offset));\n            if Length(FormIDsAtOffSetFoundIn) < Succ(Offset) then\n              SetLength(FormIDsAtOffSetFoundIn, Succ(Offset));\n            if Assigned(MainRecord) then begin\n              if (aInt > $14) and (CountBits(aInt) > 4) then begin\n                Inc(FoundFormIDAtOffSet[Offset]);\n                if not Assigned(SignaturesAtOffSet[Offset]) then\n                  SignaturesAtOffSet[Offset] := TwbFastStringListCS.CreateSorted;\n                s := MainRecord.Signature;\n                if not SignaturesAtOffSet[Offset].Find(s, i) then\n                  i := SignaturesAtOffSet[Offset].AddObject(s, TwbFastStringListCS.CreateSorted);\n                s := MainRecord.Name;\n                with TStringList(SignaturesAtOffSet[Offset].Objects[i]) do\n                  if Find(s, i) then\n                    Objects[i] := TObject(Succ(Integer(Objects[i])))\n                  else\n                    if Count < 10 then\n                      AddObject(s, TObject(1));\n\n                if not Assigned(FormIDsAtOffSetFoundIn[Offset]) then\n                  FormIDsAtOffSetFoundIn[Offset] := TwbFastStringListCS.CreateSorted(dupIgnore);\n                if FormIDsAtOffSetFoundIn[Offset].Count < 50 then\n                  FormIDsAtOffSetFoundIn[Offset].Add(aElement.FullPath);\n              end;\n            end else\n              Inc(NotFoundFormIDAtOffSet[Offset]);\n          end;\n          Inc(p,4);\n          Inc(OffSet,4);\n        end;\n      end;\n\n      if wbReportUnknownFloats then begin\n        p := aBasePtr;\n        OffSet := 0;\n        while (Cardinal(p)+3) < Cardinal(aEndPtr) do begin\n          aInt := PCardinal(p)^;\n          f := PSingle(p)^;\n          if (aInt <> $0) and ((Length(NotFoundFloatAtOffSet) < Succ(OffSet)) or (NotFoundFloatAtOffSet[Offset] < 1)) then begin\n\n            if Length(FoundFloatAtOffSet) < Succ(Offset) then\n              SetLength(FoundFloatAtOffSet, Succ(Offset));\n            if Length(NotFoundFloatAtOffSet) < Succ(Offset) then\n              SetLength(NotFoundFloatAtOffSet, Succ(Offset));\n            if Length(FloatsAtOffSet) < Succ(Offset) then\n              SetLength(FloatsAtOffSet, Succ(Offset));\n\n            try\n              f2 := RoundToEx(f, -3); {>>> Floating Point Violation <<<}\n              if (f2 <> 0) and (Abs(f-f2) < 0.0002) then begin\n                if (f2 > -1000000) and (f2 < 1000000) then begin\n                  Inc(FoundFloatAtOffSet[Offset]);\n\n                  if not Assigned(FloatsAtOffSet[Offset]) then\n                    FloatsAtOffSet[Offset] := TwbFastStringListCS.CreateSorted;\n\n                  s := FloatToStr(RoundToEx(f,-7));\n                  with FloatsAtOffSet[Offset] do if Count < 15 then begin\n                    if not Find(s, i) then\n                      i := AddObject(s, TObject(0));\n                    Objects[i] := TObject(Succ(Integer(Objects[i])));\n                  end;\n                end;\n\n              end else\n                Inc(NotFoundFloatAtOffSet[Offset]);\n            except\n              Inc(NotFoundFloatAtOffSet[Offset]);\n            end;\n\n          end;\n          Inc(p,4);\n          Inc(OffSet,4);\n        end;\n      end;\n\n      if wbReportUnknownStrings then begin\n        if (badSize < 1) and (NotFoundString < 1) then begin\n          p := aBasePtr;\n          while (Cardinal(p)) < Cardinal(aEndPtr) do begin\n            if p^ < 32 then\n              if (Succ(Cardinal(p)) = Cardinal(aEndPtr)) and (p^ = 0) then begin\n                s := PAnsiChar(aBasePtr);\n                if Length(s) > 4 then begin\n                  Inc(FoundString);\n\n                  if not Assigned(Strings) then\n                    Strings := TwbFastStringListCS.CreateSorted;\n\n                  with Strings do if Count < 15 then begin\n                    if not Find(s, i) then\n                      i := AddObject(s, TObject(0));\n                    Objects[i] := TObject(Succ(Integer(Objects[i])));\n                  end;\n                end;\n              end else begin\n                Inc(NotFoundString);\n                Break;\n              end;\n\n            Inc(p);\n          end;\n        end;\n      end;\n\n      if wbReportEmpty then begin\n        if (Cardinal(aBasePtr)) < Cardinal(aEndPtr) then\n          Inc(IsNotEmpty)\n        else\n          Inc(IsEmpty);\n      end;\n\n    end;\n  end;\n  Used(aElement, Result);\nend;\n\n{ TwbDivDef }\n\nfunction TwbDivDef.CanAssign(const aElement: IwbElement; aIndex: Integer; const aDef: IwbDef): Boolean;\nbegin\n  Result := True;\nend;\n\nfunction TwbDivDef.CanContainFormIDs: Boolean;\nbegin\n  Result := False;\nend;\n\nconstructor TwbDivDef.Clone(const aSource: TwbDef);\nbegin\n  with aSource as TwbDivDef do\n    Self.Create(ddValue).defSource := aSource;\nend;\n\nconstructor TwbDivDef.Create(aValue: Integer);\nbegin\n  ddValue := aValue;\n  inherited Create(cpNormal, False, nil);\nend;\n\nfunction TwbDivDef.FromEditValue(const aValue: string; const aElement: IwbElement): Int64;\nbegin\n  Result := Round(StrToFloat(aValue) * ddValue);\nend;\n\nfunction TwbDivDef.GetIsEditable(aInt: Int64; const aElement: IwbElement): Boolean;\nbegin\n  Result := True;\nend;\n\nfunction TwbDivDef.ToEditValue(aInt: Int64; const aElement: IwbElement): string;\nbegin\n  Result := FloatToStrF(aInt / ddValue, ffFixed, 99, wbFloatDigits);\nend;\n\nfunction TwbDivDef.ToSortKey(aInt: Int64; const aElement: IwbElement): string;\nconst\n  PlusMinus : array[Boolean] of string = ('+', '-');\nbegin\n  Result := PlusMinus[aInt < 0] + IntToHex64(Abs(aInt), 16);\nend;\n\nfunction TwbDivDef.ToString(aInt: Int64; const aElement: IwbElement): string;\nbegin\n  Result := FloatToStrF(aInt / ddValue, ffFixed, 99, wbFloatDigits);\n  Used(aElement, Result);\nend;\n\n{ TwbMulDef }\n\nfunction TwbMulDef.CanAssign(const aElement: IwbElement; aIndex: Integer; const aDef: IwbDef): Boolean;\nbegin\n  Result := True;\nend;\n\nfunction TwbMulDef.CanContainFormIDs: Boolean;\nbegin\n  Result := False;\nend;\n\nconstructor TwbMulDef.Clone(const aSource: TwbDef);\nbegin\n  with aSource as TwbMulDef do\n    Self.Create(mdValue).defSource := aSource;\nend;\n\nconstructor TwbMulDef.Create(aValue: Integer);\nbegin\n  mdValue := aValue;\n  inherited Create(cpNormal, False, nil);\nend;\n\nfunction TwbMulDef.FromEditValue(const aValue: string; const aElement: IwbElement): Int64;\nbegin\n  Result := StrToInt64(aValue) div mdValue;\nend;\n\nfunction TwbMulDef.GetIsEditable(aInt: Int64; const aElement: IwbElement): Boolean;\nbegin\n  Result := True;\nend;\n\nfunction TwbMulDef.ToEditValue(aInt: Int64; const aElement: IwbElement): string;\nbegin\n  Result := IntToStr(aInt * mdValue);\nend;\n\nfunction TwbMulDef.ToSortKey(aInt: Int64; const aElement: IwbElement): string;\nbegin\n  Result := ''; {handled by integer def}\nend;\n\nfunction TwbMulDef.ToString(aInt: Int64; const aElement: IwbElement): string;\nbegin\n  Result := IntToStr(aInt * mdValue);\n  Used(aElement, Result);\nend;\n\n{ TwbCallbackDef }\n\nfunction TwbCallbackDef.CanAssign(const aElement: IwbElement; aIndex: Integer; const aDef: IwbDef): Boolean;\nvar\n  CallbackDef: IwbCallbackDef;\nbegin\n  Result := Supports(aDef, IwbCallbackDef, CallbackDef) and\n    (@CallbackDef.Callback = @cdToStr);\nend;\n\nfunction TwbCallbackDef.CanContainFormIDs: Boolean;\nbegin\n  Result := False;\nend;\n\nfunction TwbCallbackDef.Check(aInt: Int64; const aElement: IwbElement): string;\nbegin\n  Result := cdToStr(aInt, aElement, ctCheck);\nend;\n\nconstructor TwbCallbackDef.Clone(const aSource: TwbDef);\nbegin\n  with aSource as TwbCallbackDef do\n    Self.Create(cdToStr, cdToInt).defSource := aSource;\nend;\n\nconstructor TwbCallbackDef.Create(const aToStr : TwbIntToStrCallback;\n                                  const aToInt : TwbStrToIntCallback);\nbegin\n  cdToStr := aToStr;\n  cdToInt := aToInt;\n  inherited Create(cpNormal, False, nil);\nend;\n\nfunction TwbCallbackDef.FromEditValue(const aValue: string; const aElement: IwbElement): Int64;\nbegin\n  if Assigned(cdToInt) then\n    Result := cdToInt(aValue, aElement)\n  else\n    Result := StrToInt64(aValue)\nend;\n\nfunction TwbCallbackDef.GetCallback: TwbIntToStrCallback;\nbegin\n  Result := cdToStr;\nend;\n\nfunction TwbCallbackDef.GetEditInfo(aInt: Int64; const aElement: IwbElement): string;\nbegin\n  Result := cdToStr(aInt, aElement, ctEditInfo);\nend;\n\nfunction TwbCallbackDef.GetEditType(aInt: Int64; const aElement: IwbElement): TwbEditType;\nvar\n  s: string;\nbegin\n  Result := etDefault;\n  s := cdToStr(aInt, aElement, ctEditType);\n  if SameText(s, 'ComboBox') then\n    Result := etComboBox\n  else if SameText(s, 'CheckComboBox') then\n    Result := etCheckComboBox;\nend;\n\nfunction TwbCallbackDef.GetIsEditable(aInt: Int64; const aElement: IwbElement): Boolean;\nbegin\n  Result := True;\nend;\n\nfunction TwbCallbackDef.ToEditValue(aInt: Int64; const aElement: IwbElement): string;\nbegin\n  Result := cdToStr(aInt, aElement, ctToEditValue);\n  if Result = '' then\n    Result := IntToStr(aInt);\nend;\n\nfunction TwbCallbackDef.ToSortKey(aInt: Int64; const aElement: IwbElement): string;\nbegin\n  Result := cdToStr(aInt, aElement, ctToSortKey);\nend;\n\nfunction TwbCallbackDef.ToString(aInt: Int64; const aElement: IwbElement): string;\nbegin\n  Result := cdToStr(aInt, aElement, ctToStr);\n  Used(aElement, Result);\nend;\n\n{ TwbValueDef }\n\nprocedure TwbValueDef.BuildRef;\nbegin\n  {nothing}\nend;\n\nfunction TwbValueDef.Check(aBasePtr, aEndPtr: Pointer;\n  const aElement: IwbElement): string;\nbegin\n  Result := '';\nend;\n\nfunction TwbValueDef.CompareExchangeFormID(aBasePtr, aEndPtr: Pointer; const aElement: IwbElement; aOldFormID, aNewFormID: Cardinal): Boolean;\nbegin\n  {can be overriden}\n  Result := False;\nend;\n\nprocedure TwbValueDef.FindUsedMasters(aBasePtr, aEndPtr: Pointer; const aElement: IwbElement; aMasters: PwbUsedMasters);\nbegin\n  {can be overriden}\nend;\n\nprocedure TwbValueDef.FromEditValue(aBasePtr, aEndPtr: Pointer; const aElement: IwbElement; const aValue: string);\nbegin\n  raise Exception.Create(GetName + ' is not editable.');\nend;\n\nprocedure TwbValueDef.FromNativeValue(aBasePtr, aEndPtr: Pointer; const aElement: IwbElement; const aValue: Variant);\nbegin\n  raise Exception.Create(GetName + ' is not editable.');\nend;\n\nfunction TwbValueDef.GetCanBeZeroSize: Boolean;\nbegin\n  Result := False;\nend;\n\nfunction TwbValueDef.GetEditInfo(aBasePtr, aEndPtr: Pointer; const aElement: IwbElement): string;\nbegin\n  Result := '';\nend;\n\nfunction TwbValueDef.GetEditType(aBasePtr, aEndPtr: Pointer; const aElement: IwbElement): TwbEditType;\nbegin\n  Result := etDefault;\nend;\n\nfunction TwbValueDef.GetElementMap: TDynCardinalArray;\nbegin\n  Result := nil;\nend;\n\nfunction TwbValueDef.GetIsEditable(aBasePtr, aEndPtr: Pointer; const aElement: IwbElement): Boolean;\nbegin\n  Result := wbIsInternalEdit;\nend;\n\nfunction TwbValueDef.GetIsVariableSize: Boolean;\nbegin\n  if not (vdsIsVariableSizeChecked in vdStates) then begin\n    if GetIsVariableSizeInternal then\n      Include(vdStates, vdsIsVariableSize)\n    else\n      Exclude(vdStates, vdsIsVariableSize);\n    Include(vdStates, vdsIsVariableSizeChecked)\n  end;\n  Result := vdsIsVariableSize in vdStates;\nend;\n\nfunction TwbValueDef.GetIsVariableSizeInternal: Boolean;\nbegin\n  Result := False;\nend;\n\nfunction TwbValueDef.GetLinksTo(aBasePtr, aEndPtr: Pointer; const aElement: IwbElement): IwbElement;\nbegin\n  Result := nil;\nend;\n\nprocedure TwbValueDef.MasterCountUpdated(aBasePtr, aEndPtr: Pointer; const aElement: IwbElement; aOld, aNew: Byte);\nbegin\n  {can be overriden}\nend;\n\nprocedure TwbValueDef.MasterIndicesUpdated(aBasePtr, aEndPtr: Pointer; const aElement: IwbElement; const aOld, aNew: TBytes);\nbegin\n  {can be overriden}\nend;\n\nfunction TwbValueDef.SetToDefault(aBasePtr, aEndPtr: Pointer; const aElement: IwbElement): Boolean;\nbegin\n  Result := False;\n  {can be overriden}\nend;\n\nfunction TwbValueDef.ToEditValue(aBasePtr, aEndPtr: Pointer;\n  const aElement: IwbElement): string;\nbegin\n  Result := '';\nend;\n\nfunction TwbValueDef.ToNativeValue(aBasePtr, aEndPtr: Pointer; const aElement: IwbElement): Variant;\nbegin\n  VarClear(Result);\nend;\n\nfunction TwbValueDef.ToSortKey(aBasePtr, aEndPtr: Pointer; const aElement: IwbElement; aExtended: Boolean): string;\nbegin\n  Result := UpperCase(ToString(aBasePtr, aEndPtr, aElement));\nend;\n\n{ TwbSubRecordStructSKDef }\n\nconstructor TwbSubRecordStructSKDef.Clone(const aSource: TwbDef);\nvar\n  SkipSigs : array of TwbSignature;\n  i        : Integer;\nbegin\n  with aSource as TwbSubRecordStructSKDef do begin\n    if Assigned(srsSkipSignatures) then begin\n      SetLength(SkipSigs, srsSkipSignatures.Count);\n      for i := 0 to Pred(srsSkipSignatures.Count) do\n        SkipSigs[i] := StrToSignature(srsSkipSignatures[i]);\n    end;\n    Self.Create(defPriority, defRequired, noName, srsMembers, SkipSigs, srsSortKey, srsExSortKey, noDontShow, srsAllowUnordered, noAfterLoad, noAfterSet, defGetCP).defSource := aSource;\n  end;\nend;\n\nconstructor TwbSubRecordStructSKDef.Create(aPriority       : TwbConflictPriority;\n                                           aRequired       : Boolean;\n                                     const aName           : string;\n                                     const aMembers        : array of IwbRecordMemberDef;\n                                     const aSkipSigs       : array of TwbSignature;\n                                     const aSortKey        : array of Integer;\n                                     const aExSortKey      : array of Integer;\n                                           aDontShow       : TwbDontShowCallback;\n                                           aAllowUnordered : Boolean;\n                                           aAfterLoad      : TwbAfterLoadCallback;\n                                           aAfterSet       : TwbAfterSetCallback;\n                                           aGetCP          : TwbGetConflictPriority);\nvar\n  i: Integer;\nbegin\n  SetLength(srsMemberInSK, Length(aMembers));\n\n  SetLength(srsSortKey, Length(aSortKey));\n  for i := Low(srsSortKey) to High(srsSortKey) do begin\n    Assert( not srsMemberInSK[aSortKey[i]] );\n    srsMemberInSK[aSortKey[i]] := True;\n\n    srsSortKey[i] := aSortKey[i];\n  end;\n\n  SetLength(srsExSortKey, Length(aExSortKey));\n  for i := Low(srsExSortKey) to High(srsExSortKey) do\n    srsExSortKey[i] := aExSortKey[i];\n\n  inherited Create(aPriority, aRequired, aName, aMembers, aSkipSigs, aDontShow, aAllowUnordered, aAfterLoad, aAfterSet, aGetCP);\nend;\n\nfunction TwbSubRecordStructSKDef.GetSortKey(aIndex: Integer; aExtended: Boolean): Integer;\nbegin\n  if aIndex <= High(srsSortKey) then\n    Result := srsSortKey[aIndex]\n  else\n    Result := srsExSortKey[aIndex-Length(srsSortKey)];\nend;\n\nfunction TwbSubRecordStructSKDef.GetSortKeyCount(aExtended: Boolean): Integer;\nbegin\n  Result := Length(srsSortKey);\n  if aExtended then\n    Inc(Result, Length(srsExSortKey));\nend;\n\nfunction TwbSubRecordStructSKDef.IsInSK(aIndex: Integer): Boolean;\nbegin\n  Result := (aIndex >= Low(srsMemberInSK)) and (aIndex <= High(srsMemberInSK)) and srsMemberInSK[aIndex];\nend;\n\n{ TwbFormIDChecked }\n\nfunction TwbFormIDChecked.CanAssign(const aElement: IwbElement; aIndex: Integer; const aDef: IwbDef): Boolean;\nvar\n  FormIDChecked : IwbFormIDChecked;\n  i             : Integer;\n  Dummy         : Integer;\nbegin\n  if Supports(aDef, IwbFormIDChecked, FormIDChecked) then begin\n    Result := False;\n    for i := 0 to Pred(FormIDChecked.SignatureCount) do\n      if (FormIDChecked.Signatures[i] <> 'NULL') and (FormIDChecked.Signatures[i] <> 'TRGT') then\n        if fidcValidRefs.Find(FormIDChecked.Signatures[i], Dummy) then begin\n          Result := True;\n          Exit;\n        end;\n  end else\n    Result := inherited CanAssign(aElement, aIndex, aDef);\nend;\n\nfunction TwbFormIDChecked.Check(aInt: Int64;\n  const aElement: IwbElement): string;\nvar\n  _File: IwbFile;\n  MainRecord: IwbMainRecord;\n  Found: TwbSignature;\nbegin\n  Result := '';\n\n  {>>> No ACVA errors <<<}\n  if IsValid('ACVA') then\n    Exit;\n\n  if aInt = 0 then begin\n    if IsValid('TRGT') and not IsValid('NULL') then begin\n      Found := 'TRGT';\n      if fidcValidRefs.IndexOf(Found) < 0 then\n        Result := 'Found a TRGT reference, expected: ' + fidcValidRefs.CommaText;\n    end else begin\n      Found := 'NULL';\n      if fidcValidRefs.IndexOf(Found) < 0 then\n        Result := 'Found a NULL reference, expected: ' + fidcValidRefs.CommaText;\n    end;\n    Exit;\n  end else if aInt = $FFFFFFFF then begin\n    Found := 'FFFF';\n    if fidcValidRefs.IndexOf(Found) < 0 then\n      Result := 'Found a None (FFFFFFFF) reference, expected: ' + fidcValidRefs.CommaText;\n    Exit;\n  end else if aInt = $14 then begin\n    Found := 'PLYR';\n    if fidcValidRefs.IndexOf(Found) < 0 then\n      Result := 'Found a PLYR reference, expected: ' + fidcValidRefs.CommaText;\n    Exit;\n  end;\n\n  if Assigned(aElement) then begin\n    _File := aElement._File;\n    if Assigned(_File) then begin\n      try\n        MainRecord := _File.RecordByFormID[aInt, True];\n        if Assigned(MainRecord) then begin\n          Found := MainRecord.Signature;\n          if fidcValidRefs.IndexOf(Found) < 0 then\n            Result := 'Found a '+Found+' reference, expected: ' + fidcValidRefs.CommaText\n          else begin\n            if fidcPersistent then\n              if not MainRecord.WinningOverride.Flags.IsPersistent then begin\n                Result := 'Target is not persistent';\n                Exit;\n              end;\n            if not CheckFlst(MainRecord) then\n              Result := 'Referenced FLST contains invalid entry';\n          end;\n          Exit;\n        end;\n      except\n        on E: Exception do begin\n          Result := E.Message;\n          Exit;\n        end;\n      end;\n    end;\n  end;\n\n  if aInt > $800 then\n    Result := '['+IntToHex64(aInt,8)+'] < Error: Could not be resolved >';\nend;\n\nfunction TwbFormIDChecked.CheckFlst(const aMainRecord: IwbMainRecord): Boolean;\nvar\n  Container  : IwbContainerElementRef;\n  i, j       : Integer;\n  MainRecord : IwbMainRecord;\nbegin\n  Result := True;\n\n  if fidcValidFlstRefs.Count < 1 then\n    Exit;\n\n  if aMainRecord.Signature <> 'FLST' then\n    Exit;\n\n  if Supports(aMainRecord.ElementByName['FormIDs'], IwbContainerElementRef, Container) then\n    for i := 0 to Pred(Container.ElementCount) do\n      if Supports(Container.Elements[i].LinksTo, IwbMainRecord, MainRecord) then\n        if not fidcValidFlstRefs.Find(MainRecord.Signature, j) then begin\n          Result := False;\n          Exit;\n        end;\nend;\n\nconstructor TwbFormIDChecked.Clone(const aSource: TwbDef);\nbegin\n  with aSource as TwbFormIDChecked do\n    Self.Create(fidcValidRefsArr, fidcValidFlstRefsArr, fidcPersistent, fidcNoReach).defSource := aSource;\nend;\n\nconstructor TwbFormIDChecked.Create(const aValidRefs     : array of TwbSignature;\n                                    const aValidFlstRefs : array of TwbSignature;\n                                          aPersistent    : Boolean;\n                                          aNoReach       : Boolean);\nvar\n  i: Integer;\nbegin\n  fidcPersistent := aPersistent;\n  fidcNoReach := aNoReach;\n\n  fidcValidRefs := TwbFastStringListCS.CreateSorted;\n  SetLength(fidcValidRefsArr, Length(aValidRefs));\n  for i := Low(aValidRefs) to High(aValidRefs) do begin\n    fidcValidRefsArr[i] := aValidRefs[i];\n    fidcValidRefs.Add(aValidRefs[i]);\n  end;\n\n  fidcValidFlstRefs := TwbFastStringListCS.CreateSorted;\n  SetLength(fidcValidFlstRefsArr, Length(aValidFlstRefs));\n  for i := Low(aValidFlstRefs) to High(aValidFlstRefs) do begin\n    fidcValidFlstRefsArr[i] := aValidFlstRefs[i];\n    fidcValidFlstRefs.Add(aValidFlstRefs[i]);\n  end;\n\n  inherited Create(cpNormal, False, nil);\nend;\n\ndestructor TwbFormIDChecked.Destroy;\nbegin\n  FreeAndNil(fidcValidRefs);\n  FreeAndNil(fidcValidFlstRefs);\n  inherited;\nend;\n\nfunction TwbFormIDChecked.FromEditValue(const aValue: string; const aElement: IwbElement): Int64;\nvar\n  Error: string;\nbegin\n  Result := inherited FromEditValue(aValue, aElement);\n  if not wbAllowErrors then begin\n    Error := Check(Result, aElement);\n    if Error <> '' then\n      raise Exception.Create(Error);\n  end;\nend;\n\nfunction TwbFormIDChecked.GetNoReach: Boolean;\nbegin\n  Result := fidcNoReach;\nend;\n\nfunction TwbFormIDChecked.GetSignature(aIndex: Integer): TwbSignature;\nbegin\n  Result := StrToSignature(fidcValidRefs[aIndex]);\nend;\n\nfunction TwbFormIDChecked.GetSignatureCount: Integer;\nbegin\n  Result := fidcValidRefs.Count;\nend;\n\nfunction TwbFormIDChecked.IsValid(const aSignature: TwbSignature): Boolean;\nbegin\n  Result := fidcValidRefs.IndexOf(aSignature) >= 0;\nend;\n\nfunction TwbFormIDChecked.IsValidFlst(const aSignature: TwbSignature): Boolean;\nbegin\n  Result := (fidcValidFlstRefs.Count = 0) or (fidcValidFlstRefs.IndexOf(aSignature) >= 0);\nend;\n\nfunction TwbFormIDChecked.IsValidMainRecord(const aMainRecord: IwbMainRecord): Boolean;\nbegin\n  Result := not fidcPersistent or aMainRecord.IsPersistent;\nend;\n\nprocedure TwbFormIDChecked.Report(const aParents: TwbDefPath);\nvar\n  i, j : Integer;\n  s    : string;\n  Sigs : TStringList;\nbegin\n  if defReported then\n    Exit;\n\n  inherited;\n  if wbReportMode then\n    if wbReportFormIDs and Assigned(FoundSignatures) and (FoundSignatures.Count > 0) then begin\n      s := '';\n\n      Sigs := TwbFastStringListCS.CreateSorted;\n      try\n        Sigs.AddStrings(FoundSignatures);\n\n        for i := 0 to Pred(fidcValidRefs.Count) do\n          if Sigs.Find(fidcValidRefs[i], j) then\n            Sigs.Delete(j)\n          else\n            s := s + fidcValidRefs[i] + ',';\n        SetLength(s, Pred(Length(s)));\n\n        if not wbReportNotFoundButAllowedFormIDs then\n          s := '';\n\n        if (s <> '') or (Sigs.Count > 0) then begin\n          WriteLn('Differences in Checked FormID Formater: ', wbDefsToPath(aParents), wbDefToName(Self));\n          if s <> '' then\n            WriteLn('  Not found but allowed: ', s);\n          if Sigs.Count > 0 then begin\n            WriteLn('  Found but not allowed: ', Sigs.CommaText);\n            for i := 0 to Pred(Sigs.Count) do\n              WriteLn('    ', Sigs.Strings[i], ' (', Integer(Sigs.Objects[i]),')');\n          end;\n        end;\n      finally\n        Sigs.Free;\n      end;\n    end;\n\n  defReported := True;\nend;\n\n{ TwbIntegerDefFormater }\n\nprocedure TwbIntegerDefFormater.BuildRef(aInt: Int64;\n  const aElement: IwbElement);\nbegin\n  { nothing }\nend;\n\nfunction TwbIntegerDefFormater.CanAssign(const aElement: IwbElement; aIndex: Integer; const aDef: IwbDef): Boolean;\nbegin\n  Result := False;\nend;\n\nfunction TwbIntegerDefFormater.Check(aInt: Int64;\n  const aElement: IwbElement): string;\nbegin\n  Result := '';\nend;\n\nconstructor TwbIntegerDefFormater.Clone(const aSource: TwbDef);\nbegin\n  with aSource as TwbIntegerDefFormater do\n    Self.Create(defPriority, defRequired, defGetCP).defSource := aSource;\nend;\n\nfunction TwbIntegerDefFormater.CompareExchangeFormID(var aInt: Int64;\n  aOldFormID, aNewFormID: Cardinal; const aElement: IwbElement): Boolean;\nbegin\n  Result := False; // ? Should be overriden\nend;\n\nprocedure TwbIntegerDefFormater.FindUsedMasters(aInt: Int64; aMasters: PwbUsedMasters; const aElement: IwbElement);\nbegin\n  {can be overriden}\nend;\n\nfunction TwbIntegerDefFormater.FromEditValue(const aValue: string;\n  const aElement: IwbElement): Int64;\nbegin\n  raise Exception.Create(Classname + ' does not support editing');\nend;\n\nfunction TwbIntegerDefFormater.GetDefType: TwbDefType;\nbegin\n  Result := dtIntegerFormater;\nend;\n\nfunction TwbIntegerDefFormater.GetDefTypeName: string;\nbegin\n  Result := ClassName;\nend;\n\nfunction TwbIntegerDefFormater.GetEditInfo(aInt: Int64; const aElement: IwbElement): string;\nbegin\n  Result := '';\nend;\n\nfunction TwbIntegerDefFormater.GetEditType(aInt: Int64; const aElement: IwbElement): TwbEditType;\nbegin\n  Result := etDefault;\nend;\n\nfunction TwbIntegerDefFormater.GetIsEditable(aInt: Int64; const aElement: IwbElement): Boolean;\nbegin\n  Result := wbIsInternalEdit;\nend;\n\nfunction TwbIntegerDefFormater.GetLinksTo(aInt: Int64; const aElement: IwbElement): IwbElement;\nbegin\n  Result := nil;\nend;\n\nfunction TwbIntegerDefFormater.GetRequiresKey: Boolean;\nbegin\n  Result := False;\nend;\n\nfunction TwbIntegerDefFormater.MasterCountUpdated(aInt: Int64; aOld, aNew: Byte; const aElement: IwbElement): Int64;\nbegin\n  Result := aInt;\nend;\n\nfunction TwbIntegerDefFormater.MasterIndicesUpdated(aInt: Int64; const aOld, aNew: TBytes; const aElement: IwbElement): Int64;\nbegin\n  Result := aInt;\nend;\n\nfunction TwbIntegerDefFormater.ToEditValue(aInt: Int64;\n  const aElement: IwbElement): string;\nbegin\n  Result := '';\nend;\n\n{ TwbUnionDef }\n\nprocedure TwbUnionDef.BuildRef(aBasePtr, aEndPtr: Pointer; const aElement: IwbElement);\nvar\n  ValueDef : IwbValueDef;\nbegin\n  inherited;\n  ValueDef := Decide(aBasePtr, aEndPtr, aElement);\n  if Assigned(ValueDef) then\n    ValueDef.BuildRef(aBasePtr, aEndPtr, aElement);\nend;\n\nfunction TwbUnionDef.CanAssign(const aElement: IwbElement; aIndex: Integer; const aDef: IwbDef): Boolean;\nvar\n  UnionDef : IwbUnionDef;\n  i        : Integer;\nbegin\n  if Supports(aDef, IwbUnionDef, UnionDef) then begin\n    Result := Equals(aDef);\n    if not Result then\n      for i := 0 to Pred(UnionDef.MemberCount) do begin\n        Result := CanAssign(aElement, aIndex, UnionDef.Members[i]);\n        if Result then\n          Exit;\n      end;\n\n  end else begin\n    Result := False;\n    for i := 0 to Pred(GetMemberCount) do begin\n      Result := udMembers[i].CanAssign(aElement, aIndex, aDef);\n      if Result then\n        Exit;\n    end;\n  end;\nend;\n\nfunction TwbUnionDef.CanContainFormIDs: Boolean;\nbegin\n  Result := ubCanContainFormIDs;\nend;\n\nfunction TwbUnionDef.Check(aBasePtr, aEndPtr: Pointer; const aElement: IwbElement): string;\nbegin\n  Result := Decide(aBasePtr, aEndPtr, aElement).Check(aBasePtr, aEndPtr, aElement);\nend;\n\nconstructor TwbUnionDef.Clone(const aSource: TwbDef);\nbegin\n  with aSource as TwbUnionDef do\n    Self.Create(defPriority, defRequired, noName, udDecider, udMembers, noDontShow, noAfterSet, defGetCP).defSource := aSource;\nend;\n\nconstructor TwbUnionDef.Create(aPriority : TwbConflictPriority;\n                               aRequired : Boolean;\n                         const aName     : string;\n                               aDecider  : TwbUnionDecider;\n                         const aMembers  : array of IwbValueDef;\n                               aDontShow : TwbDontShowCallback;\n                               aAfterSet : TwbAfterSetCallback;\n                               aGetCP    : TwbGetConflictPriority);\nvar\n  i: Integer;\nbegin\n  inherited Create(aPriority, aRequired, aName, nil, aAfterSet, aDontShow, aGetCP, False);\n  udDecider := aDecider;\n  SetLength(udMembers, Length(aMembers));\n  for I := Low(udMembers) to High(udMembers) do begin\n    udMembers[i] := (aMembers[i] as IwbDefInternal).SetParent(Self, False) as IwbValueDef;\n    ubCanContainFormIDs := ubCanContainFormIDs or aMembers[i].CanContainFormIDs;\n  end;\nend;\n\nfunction TwbUnionDef.Decide(aBasePtr, aEndPtr: Pointer; const aElement: IwbElement): IwbValueDef;\nvar\n  aMemberIndex : Integer;\nbegin\n  aMemberIndex := udDecider(aBasePtr, aEndPtr, aElement);\n  if (aMemberIndex>=0) and (aMemberIndex<Length(udMembers))then\n    Result := udMembers[aMemberIndex]\n  else\n    Result := nil;\n  Used(nil, '');\nend;\n\nprocedure TwbUnionDef.FromEditValue(aBasePtr, aEndPtr: Pointer;\n  const aElement: IwbElement; const aValue: string);\nbegin\n  Decide(aBasePtr, aEndPtr, aElement).\n    EditValue[aBasePtr, aEndPtr, aElement] := aValue;\nend;\n\nprocedure TwbUnionDef.FromNativeValue(aBasePtr, aEndPtr: Pointer; const aElement: IwbElement; const aValue: Variant);\nbegin\n  Decide(aBasePtr, aEndPtr, aElement).\n    NativeValue[aBasePtr, aEndPtr, aElement] := aValue;\nend;\n\nfunction TwbUnionDef.GetDefType: TwbDefType;\nbegin\n  Result := dtUnion;\nend;\n\nfunction TwbUnionDef.GetDefTypeName: string;\nbegin\n  Result := 'Union';\nend;\n\nfunction TwbUnionDef.GetEditInfo(aBasePtr, aEndPtr: Pointer; const aElement: IwbElement): string;\nvar\n  ValueDef: IwbValueDef;\nbegin\n  ValueDef := Decide(aBasePtr, aEndPtr, aElement);\n  if Assigned(ValueDef) then\n    Result := ValueDef.EditInfo[aBasePtr, aEndPtr, aElement]\n  else\n    Result := '';\nend;\n\nfunction TwbUnionDef.GetEditType(aBasePtr, aEndPtr: Pointer; const aElement: IwbElement): TwbEditType;\nvar\n  ValueDef: IwbValueDef;\nbegin\n  ValueDef := Decide(aBasePtr, aEndPtr, aElement);\n  if Assigned(ValueDef) then\n    Result := ValueDef.EditType[aBasePtr, aEndPtr, aElement]\n  else\n    Result := etDefault;\nend;\n\nfunction TwbUnionDef.GetIsEditable(aBasePtr, aEndPtr: Pointer; const aElement: IwbElement): Boolean;\nvar\n  ValueDef: IwbValueDef;\nbegin\n  Result := wbIsInternalEdit;\n  if not Result then\n  begin\n    ValueDef := Decide(aBasePtr, aEndPtr, aElement);\n    if Assigned(ValueDef) then\n      Result := ValueDef.IsEditable[aBasePtr, aEndPtr, aElement]\n    else\n      Result := False;\n  end;\nend;\n\nfunction TwbUnionDef.GetIsVariableSizeInternal: Boolean;\nvar\n  i, j: Integer;\nbegin\n  Result := False;\n  for i := Low(udMembers) to High(udMembers) do begin\n    Result := udMembers[i].IsVariableSize;\n    if Result then\n      Break;\n  end;\n\n  if not Result then begin\n    j := udMembers[0].DefaultSize[nil, nil, nil];\n    for i := 1 to High(udMembers) do\n      if udMembers[i].DefaultSize[nil, nil, nil] <> j then begin\n        j := -1;\n        break;\n      end;\n    Result := j = -1;\n  end;\nend;\n\nfunction TwbUnionDef.GetLinksTo(aBasePtr, aEndPtr: Pointer; const aElement: IwbElement): IwbElement;\nvar\n  ValueDef: IwbValueDef;\nbegin\n  ValueDef := Decide(aBasePtr, aEndPtr, aElement);\n  if Assigned(ValueDef) then\n    Result := ValueDef.LinksTo[aBasePtr, aEndPtr, aElement]\n  else\n    Result := nil;\nend;\n\nfunction TwbUnionDef.GetMember(aIndex: Integer): IwbValueDef;\nbegin\n  Result := udMembers[aIndex];\nend;\n\nfunction TwbUnionDef.GetMemberCount: Integer;\nbegin\n  Result := Length(udMembers);\nend;\n\nfunction TwbUnionDef.GetSize(aBasePtr, aEndPtr: Pointer; const aElement: IwbElement): Integer;\nvar\n  i         : Integer;\n  Size      : Integer;\n  aMember   : IwbValueDef;\n  Container : IwbContainerElementRef;\n  Element   : IwbElement;\nbegin\n//  if Assigned(aBasePtr) and Assigned(aEndPtr) and (Cardinal(aEndPtr)<Cardinal(aBasePtr)) then begin\n//    wbProgressCallback('Found a union with a negative size! (1) '+IntToHex64(Cardinal(aBasePtr), 8)+\n//      ' > '+IntToHex64(Cardinal(aEndPtr), 8)+'  for '+noName);\n//  end;\n  if GetIsVariableSize then\n    aMember := Decide(aBasePtr, aEndPtr, aElement)\n  else\n    aMember := nil;;\n  if not Assigned(aMember) then begin\n    if Length(udMembers)>0 then\n      Result := udMembers[0].Size[aBasePtr, aEndPtr, aElement]\n    else\n      Result := Low(Integer);\n    if (Result > 0) and GetIsVariableSize then\n      for i := 1 to High(udMembers) do\n        if Result <> High(Integer) then begin\n          Size := udMembers[i].Size[aBasePtr, aEndPtr, aElement];\n          if Size = 0 then begin // No valid value can be found\n            Result := 0;\n            Break;\n          end else if Result < Size then\n            Result := Size;\n        end else\n          break;\n  end else begin\n    if GetIsVariableSize and Supports(aElement, IwbContainerElementRef, Container) and Equals(Container.ValueDef) and (Container.ElementCount = 1) then begin\n      Element := Container.Elements[0];\n      if not aMember.Equals(Element.ValueDef) then\n        Element := nil;\n    end;\n    if not Assigned(Element) then\n      Element := aElement;\n    Result := aMember.Size[aBasePtr, aEndPtr, Element];\n    if Result = High(Integer) then Exit;\n    if Assigned(aBasePtr) and Assigned(aEndPtr) and (Cardinal(aEndPtr)<Cardinal(aBasePtr)+Result) then begin\n//      if Assigned(aBasePtr) and Assigned(aEndPtr) and (aEndPtr<>aBasePtr) then\n//        wbProgressCallback('Found a union with a negative size! (2) '+IntToHex64(Cardinal(aBasePtr)+Result, 8)+\n//          ' > '+IntToHex64(Cardinal(aEndPtr), 8)+'  for '+noName);\n      Result := Cardinal(aEndPtr)-Cardinal(aBasePtr);\n    end;\n  end;\nend;\n\nfunction TwbUnionDef.GetDefaultSize(aBasePtr, aEndPtr: Pointer; const aElement: IwbElement): Integer;\nvar\n  aMember : IwbValueDef;\nbegin\n  aMember := Decide(aBasePtr, aEndPtr, aElement);\n  if Assigned(aMember) then\n    Result := aMember.DefaultSize[aBasePtr, aEndPtr, aElement]\n  else\n    Result := 0;\nend;\n\nprocedure TwbUnionDef.Report(const aParents: TwbDefPath);\nvar\n  Parents : TwbDefPath;\n  i       : Integer;\nbegin\n  if defReported then\n    Exit;\n\n  inherited;\n  Parents := aParents;\n  SetLength(Parents, Succ(Length(Parents)));\n  Parents[High(Parents)].Def := Self;\n  for i := Low(udMembers) to High(udMembers) do\n    if Assigned(udMembers[i]) then begin\n      Parents[High(Parents)].Index := i;\n      udMembers[i].Report(Parents);\n    end;\n\n  defReported := True;\nend;\n\nfunction TwbUnionDef.SetToDefault(aBasePtr, aEndPtr: Pointer; const aElement: IwbElement): Boolean;\nvar\n  ValueDef: IwbValueDef;\nbegin\n  ValueDef := Decide(aBasePtr, aEndPtr, aElement);\n  if Assigned(ValueDef) then\n    Result := ValueDef.SetToDefault(aBasePtr, aEndPtr, aElement)\n  else\n    Result := False;\nend;\n\nfunction TwbUnionDef.ToEditValue(aBasePtr, aEndPtr: Pointer; const aElement: IwbElement): string;\nvar\n  ValueDef: IwbValueDef;\nbegin\n  ValueDef := Decide(aBasePtr, aEndPtr, aElement);\n  if Assigned(ValueDef) then\n    Result := ValueDef.EditValue[aBasePtr, aEndPtr, aElement]\n  else\n    Result := '';\nend;\n\nfunction TwbUnionDef.ToNativeValue(aBasePtr, aEndPtr: Pointer; const aElement: IwbElement): Variant;\nvar\n  ValueDef: IwbValueDef;\nbegin\n  ValueDef := Decide(aBasePtr, aEndPtr, aElement);\n  if Assigned(ValueDef) then\n    Result := ValueDef.NativeValue[aBasePtr, aEndPtr, aElement]\n  else\n    Result := '';\nend;\n\nfunction TwbUnionDef.ToSortKey(aBasePtr, aEndPtr: Pointer; const aElement: IwbElement; aExtended: Boolean): string;\nvar\n  ValueDef: IwbValueDef;\nbegin\n  ValueDef := Decide(aBasePtr, aEndPtr, aElement);\n  if Assigned(ValueDef) then\n    Result := ValueDef.ToSortKey(aBasePtr, aEndPtr, aElement, aExtended)\n  else\n    Result := '';\nend;\n\nfunction TwbUnionDef.ToString(aBasePtr, aEndPtr: Pointer; const aElement: IwbElement): string;\nvar\n  ValueDef: IwbValueDef;\nbegin\n  ValueDef := Decide(aBasePtr, aEndPtr, aElement);\n  if Assigned(ValueDef) then\n    Result := ValueDef.ToString(aBasePtr, aEndPtr, aElement)\n  else\n    Result := '';\n  Used(aElement, Result);\nend;\n\n{ TwbEmptyDef }\n\nfunction TwbEmptyDef.CanContainFormIDs: Boolean;\nbegin\n  Result := False;\nend;\n\nconstructor TwbEmptyDef.Clone(const aSource: TwbDef);\nbegin\n  with aSource as TwbEmptyDef do\n    Self.Create(defPriority, defRequired, noName, noAfterLoad, noAfterSet, noDontShow, edSorted, defGetCP).defSource := aSource;\nend;\n\nconstructor TwbEmptyDef.Create(aPriority  : TwbConflictPriority;\n                               aRequired  : Boolean;\n                         const aName      : string;\n                               aAfterLoad : TwbAfterLoadCallback; aAfterSet : TwbAfterSetCallback;\n                               aDontShow  : TwbDontShowCallback;\n                               aSorted    : Boolean;\n                               aGetCP     : TwbGetConflictPriority);\nbegin\n  edSorted := aSorted;\n  inherited Create(aPriority, aRequired, aName, aAfterLoad, aAfterSet, aDontShow, aGetCP, False);\nend;\n\nprocedure TwbEmptyDef.FromEditValue(aBasePtr, aEndPtr: Pointer; const aElement: IwbElement; const aValue: string);\nbegin\nend;\n\nfunction TwbEmptyDef.GetCanBeZeroSize: Boolean;\nbegin\n  Result := True;\nend;\n\nfunction TwbEmptyDef.GetDefType: TwbDefType;\nbegin\n  Result := dtEmpty;\nend;\n\nfunction TwbEmptyDef.GetDefTypeName: string;\nbegin\n  Result := 'Place holder for optional elements';\nend;\n\nfunction TwbEmptyDef.GetIsEditable(aBasePtr, aEndPtr: Pointer; const aElement: IwbElement): Boolean;\nbegin\n  Result := True;\nend;\n\nfunction TwbEmptyDef.GetSize(aBasePtr, aEndPtr: Pointer; const aElement: IwbElement): Integer;\nbegin\n  Result := 0;\nend;\n\nfunction TwbEmptyDef.GetDefaultSize(aBasePtr, aEndPtr: Pointer; const aElement: IwbElement): Integer;\nbegin\n  Result := 0;\nend;\n\nfunction TwbEmptyDef.GetSorted: Boolean;\nbegin\n  Result := edSorted;\nend;\n\nfunction TwbEmptyDef.ToSortKey(aBasePtr, aEndPtr: Pointer; const aElement: IwbElement; aExtended: Boolean): string;\n//var\n//  NamedDef: IwbNamedDef;\nbegin\n//  Result := GetName;\n//  if (Result = '') and Supports(defParent, IwbNamedDef, NamedDef) then\n//    Result := NamedDef.Name;\n//  if Result = '' then\n    Result := '<Empty>';\n//  Result := '';\nend;\n\nfunction TwbEmptyDef.ToString(aBasePtr, aEndPtr: Pointer; const aElement: IwbElement): string;\n//var\n//  NamedDef: IwbNamedDef;\nbegin\n//  Result := GetName;\n//  if (Result = '') and Supports(defParent, IwbNamedDef, NamedDef) then\n//    Result := NamedDef.Name;\n  Result := '';\n\n  Used(aElement, Result);\nend;\n\n{ TwbMainRecordStructFlags }\n\nfunction TwbMainRecordStructFlags.CantWait: Boolean;\nbegin\n  Result := (_Flags and $00080000) <> 0;\nend;\n\nfunction TwbMainRecordStructFlags.CastsShadows: Boolean;\nbegin\n  Result := (_Flags and $00000200) <> 0;\nend;\n\nfunction TwbMainRecordStructFlags.HasLODtree: Boolean;\nbegin\n  Result := (_Flags and $00000040) <> 0;\nend;\n\nfunction TwbMainRecordStructFlags.IsCompressed: Boolean;\nbegin\n  Result := (_Flags and $00040000) <> 0;\nend;\n\nfunction TwbMainRecordStructFlags.IsDangerous: Boolean;\nbegin\n  Result := (_Flags and $00020000) <> 0;\nend;\n\nfunction TwbMainRecordStructFlags.IsDeleted: Boolean;\nbegin\n  Result := (_Flags and $00000020) <> 0;\nend;\n\nfunction TwbMainRecordStructFlags.IsLocalized: Boolean;\nbegin\n  Result := (_Flags and $00000080) <> 0;\nend;\n\nfunction TwbMainRecordStructFlags.IsESM: Boolean;\nbegin\n  Result := (_Flags and $00000001) <> 0;\nend;\n\nfunction TwbMainRecordStructFlags.IsIgnored: Boolean;\nbegin\n  Result := (_Flags and $00001000) <> 0;\nend;\n\nfunction TwbMainRecordStructFlags.IsInitiallyDisabled: Boolean;\nbegin\n  Result := (_Flags and $00000800) <> 0;\nend;\n\nfunction TwbMainRecordStructFlags.IsPersistent: Boolean;\nbegin\n  Result := (_Flags and $00000400) <> 0;\nend;\n\nfunction TwbMainRecordStructFlags.IsVisibleWhenDistant: Boolean;\nbegin\n  Result := (_Flags and $00008000) <> 0;\nend;\n\nprocedure TwbMainRecordStructFlags.SetCompressed(aValue: Boolean);\nbegin\n  if aValue then\n    _Flags := _Flags or $00040000\n  else\n    _Flags := _Flags and not $00040000;\nend;\n\nprocedure TwbMainRecordStructFlags.SetDeleted(aValue: Boolean);\nbegin\n  if aValue then\n    _Flags := _Flags or $00000020\n  else\n    _Flags := _Flags and not $00000020;\nend;\n\nprocedure TwbMainRecordStructFlags.SetESM(aValue: Boolean);\nbegin\n  if aValue then\n    _Flags := _Flags or $00000001\n  else\n    _Flags := _Flags and not $00000001;\nend;\n\nprocedure TwbMainRecordStructFlags.SetLocalized(aValue: Boolean);\nbegin\n  if aValue then\n    _Flags := _Flags or $00000080\n  else\n    _Flags := _Flags and not $00000080\nend;\n\nprocedure TwbMainRecordStructFlags.SetInitiallyDisabled(aValue: Boolean);\nbegin\n  if aValue then\n    _Flags := _Flags or $00000800\n  else\n    _Flags := _Flags and not $00000800;\nend;\n\nprocedure TwbMainRecordStructFlags.SetPersistent(aValue: Boolean);\nbegin\n  if aValue then\n    _Flags := _Flags or $00000400\n  else\n    _Flags := _Flags and not $00000400;\nend;\n\nprocedure TwbMainRecordStructFlags.SetVisibleWhenDistant(aValue: Boolean);\nbegin\n  if aValue then\n    _Flags := _Flags or $00008000\n  else\n    _Flags := _Flags and not $00008000;\nend;\n\n{ TwbLenStringDef }\n\nfunction TwbLenStringDef.CanAssign(const aElement: IwbElement; aIndex: Integer; const aDef: IwbDef) : Boolean;\nbegin\n  Result := aDef.DefType in [dtString, dtLString, dtLenString];\nend;\n\nfunction TwbLenStringDef.CanContainFormIDs: Boolean;\nbegin\n  Result := False;\nend;\n\nfunction TwbLenStringDef.Check(aBasePtr, aEndPtr: Pointer; const aElement: IwbElement): string;\nvar\n  Size : Cardinal;\n  Len  : Cardinal;\nbegin\n  Result := '';\n  Len := Cardinal(aEndPtr) - Cardinal(aBasePtr);\n  if Len < GetPrefixOffset then begin\n    if wbCheckExpectedBytes then\n      Result := Format('Expected at least %d bytes of data, found %d', [Abs(Prefix) , Len]);\n    Exit;\n  end;\n  Size := GetPrefixValue(aBasePtr, aEndPtr, aElement) + GetPrefixOffset;\n  if Len < Size then begin\n    if wbCheckExpectedBytes then\n      Result := Format('Expected %d bytes of data, found %d', [Size , Len]);\n  end;\nend;\n\nconstructor TwbLenStringDef.Clone(const aSource: TwbDef);\nbegin\n  with aSource as TwbLenStringDef do\n    Self.Create(defPriority, defRequired, noName, Prefix, noAfterLoad, noAfterSet, noDontShow, defGetCP, noTerminator).defSource := aSource;\nend;\n\nconstructor TwbLenStringDef.Create(aPriority    : TwbConflictPriority;\n                                   aRequired    : Boolean;\n                             const aName        : string;\n                                   aPrefix      : Integer;\n                                   aAfterLoad   : TwbAfterLoadCallback;\n                                   aAfterSet    : TwbAfterSetCallback;\n                                   aDontShow    : TwbDontShowCallback;\n                                   aGetCP       : TwbGetConflictPriority;\n                                   aTerminator  : Boolean);\nbegin\n  Prefix := aPrefix;\n  if not (Abs(Prefix) in [1, 2, 3, 4, 5]) then\n    Prefix := 4;\n\n  inherited Create(aPriority, aRequired, aName, aAfterLoad, aAfterSet, aDontShow, aGetCP, aTerminator);\nend;\n\nprocedure TwbLenStringDef.FromEditValue(aBasePtr, aEndPtr: Pointer; const aElement: IwbElement; const aValue: string);\nvar\n  Len     : Cardinal;\n  NewSize : Cardinal;\n  p       : Pointer;\n  s       : AnsiString;\nbegin\n  s := AnsiString(aValue);\n  Len := Length(s);\n  NewSize := Len + GetPrefixOffset;\n  aElement.RequestStorageChange(aBasePtr, aEndPtr, NewSize + Ord(noTerminator));\n  SetPrefixValue(aBasePtr, aEndPtr, aElement, Len);\n  p := Pointer(Cardinal(aBasePtr) + GetPrefixOffset);\n  if Len > 0 then\n    Move(s[1], p^, Len);\n  if noTerminator then begin\n    Inc(PByte(p), Len+1);\n    PByte(p)^ := wbTerminator;\n  end;\nend;\n\nprocedure TwbLenStringDef.FromNativeValue(aBasePtr, aEndPtr: Pointer; const aElement: IwbElement; const aValue: Variant);\nbegin\n  FromEditValue(aBasePtr, aEndPtr, aElement, aValue);\nend;\n\nfunction TwbLenStringDef.GetDefType: TwbDefType;\nbegin\n  Result := dtLenString;\nend;\n\nfunction TwbLenStringDef.GetDefTypeName: string;\nbegin\n  if Prefix > 0 then\n    Result := 'String with length of '+IntToStr(Prefix)+' bytes'\n  else\n    Result := 'Separated String with length of '+IntToStr(GetPrefixLen)+' bytes'\nend;\n\nfunction TwbLenStringDef.GetIsEditable(aBasePtr, aEndPtr: Pointer; const aElement: IwbElement): Boolean;\nbegin\n  Result := True;\nend;\n\nfunction TwbLenStringDef.GetIsVariableSizeInternal: Boolean;\nbegin\n  Result := True;\nend;\n\nfunction TwbLenStringDef.GetPrefixLen: Integer;\nbegin\n  case Prefix of\n    1, -2: Result := 1;\n    2, -3: Result := 2;\n    4, -5: Result := 4;\n  else\n    Result := 0;\n  end;\nend;\n\nfunction TwbLenStringDef.GetPrefixOffset: Integer;\nbegin\n    Result := Abs(Prefix);\nend;\n\nfunction TwbLenStringDef.GetPrefixValue(aBasePtr: Pointer; aEndPtr: Pointer; const aElement: IwbElement): Integer;\nbegin\n  case Prefix of\n    1, -2: Result := PByte(aBasePtr)^;\n    2, -3: Result := PWord(aBasePtr)^;\n    4, -5: Result := PCardinal(aBasePtr)^;\n  else\n    Result := 0;\n  end;\nend;\n\nfunction TwbLenStringDef.GetSize(aBasePtr, aEndPtr: Pointer; const aElement: IwbElement): Integer;\nvar\n  Len : Integer;\nbegin\n  if Assigned(aBasePtr) and Assigned(aEndPtr) then\n    if (Cardinal(aBasePtr) >= Cardinal(aEndPtr)) then\n      Result := 0\n    else begin\n      Result := Cardinal(aEndPtr) - Cardinal(aBasePtr);\n      Len := GetPrefixValue(aBasePtr, aEndPtr, aElement);\n      if Len>0 then\n        Len := Len+GetPrefixOffset+Ord(noTerminator)\n      else\n        Len := GetPrefixOffset;\n      if Len>Result then\n        Exit;\n      if Len < Result then\n        Result := Len;\n    end\n  else\n    Result := GetPrefixOffset;\nend;\n\nfunction TwbLenStringDef.GetDefaultSize(aBasePtr, aEndPtr: Pointer; const aElement: IwbElement): Integer;\nbegin\n  Result := GetPrefixOffset+Ord(noTerminator);\nend;\n\nprocedure TwbLenStringDef.SetPrefixValue(aBasePtr, aEndPtr: Pointer; const aElement: IwbElement; aValue: Cardinal);\nbegin\n  case Prefix of\n    1, -2: PByte(aBasePtr)^ := aValue;\n    2, -3: PWord(aBasePtr)^ := aValue;\n    4, -5: PCardinal(aBasePtr)^ := aValue;\n  end;\nend;\n\nfunction TwbLenStringDef.SetToDefault(aBasePtr, aEndPtr: Pointer;\n  const aElement: IwbElement): Boolean;\nbegin\n  Result := not Assigned(aBasePtr) or (ToString(aBasePtr, aEndPtr, aElement) <> '');\n  if Result then\n    FromEditValue(aBasePtr, aEndPtr, aElement, '');\nend;\n\nfunction TwbLenStringDef.ToEditValue(aBasePtr, aEndPtr: Pointer; const aElement: IwbElement): string;\nbegin\n  Result := ToString(aBasePtr, aEndPtr, aElement);\nend;\n\nfunction TwbLenStringDef.ToNativeValue(aBasePtr, aEndPtr: Pointer; const aElement: IwbElement): Variant;\nbegin\n  Result := ToString(aBasePtr, aEndPtr, aElement);\nend;\n\nfunction TwbLenStringDef.ToString(aBasePtr, aEndPtr: Pointer; const aElement: IwbElement): string;\nvar\n  Size : Cardinal;\n  Len  : Cardinal;\n  s    : AnsiString;\nbegin\n  s := '';\n  Len := Cardinal(aEndPtr) - Cardinal(aBasePtr);\n  if Len<GetPrefixOffset+Ord(noTerminator) then\n    Exit;\n\n  Size := GetPrefixValue(aBasePtr, aEndPtr, aElement);\n  Inc(PByte(aBasePtr), GetPrefixOffset);\n\n  if Len > Size then\n    Len := Size;\n\n  SetLength(s, Len);\n  if Len > 0 then\n    Move(aBasePtr^, s[1], Len);\n  Result := wbAnsiToString(s, aElement);\n  Used(aElement, Result);\nend;\n\n{ TwbFastStringList }\n\nprocedure TwbFastStringList.Clear(aFreeObjects: Boolean);\nvar\n  i: Integer;\nbegin\n  if aFreeObjects then\n    for i := 0 to Pred(Count) do\n      Objects[i].Free;\n  inherited Clear;\nend;\n\nfunction TwbFastStringList.CompareStrings(const S1, S2: string): Integer;\nbegin\n  if CaseSensitive then\n    Result := CompareStr(S1, S2)\n  else\n    Result := CompareText(S1, S2);\nend;\n\nconstructor TwbFastStringList.CreateSorted(aDups: TDuplicates);\nbegin\n  Create;\n  Duplicates := aDups;\n  Sorted := True;\nend;\n\n{ TwbFastStringListCS }\n\nprocedure TwbFastStringListCS.AfterConstruction;\nbegin\n  inherited;\n  CaseSensitive := True;\nend;\n\n{ TwbStringLCDef }\n\nfunction TwbStringLCDef.TransformString(const s: AnsiString; aTransformType: TwbStringTransformType; const aElement: IwbElement): AnsiString;\nbegin\n  Result := LowerCase(s);\nend;\n\n{ TwbLString }\n\nfunction TwbLStringDef.GetDefType: TwbDefType;\nbegin\n  Result := dtLString;\nend;\n\nfunction TwbLStringDef.GetDefTypeName: string;\nbegin\n  Result := 'Localized String';\nend;\n\nprocedure TwbLStringDef.FromStringNative(aBasePtr, aEndPtr: Pointer; const aElement: IwbElement; const aValue: AnsiString);\nvar\n  ID: Cardinal;\nbegin\n  if Copy(aValue, 1, Length(sStringID)) = sStringID then begin\n    aElement.RequestStorageChange(aBasePtr, aEndPtr, SizeOf(Cardinal));\n    PCardinal(aBasePtr)^ := StrToInt64Def('$' + Copy(aValue, Succ(Length(sStringID)), Length(aValue)), 0);\n    Exit;\n  end;\n\n  if aElement._File.IsLocalized then\n    if wbLocalizationHandler.NoTranslate then\n      // assign a string when delocalizing and NoTranslate is true\n      inherited FromStringNative(aBasePtr, aEndPtr, aElement, aValue)\n    else begin\n      // set localized string's value\n      ID := wbLocalizationHandler.SetValue(PCardinal(aBasePtr)^, aElement, aValue);\n      aElement.RequestStorageChange(aBasePtr, aEndPtr, SizeOf(Cardinal));\n      PCardinal(aBasePtr)^ := ID;\n      //raise Exception.Create('Can not assign to a localized string')\n    end\n  else\n    inherited FromStringNative(aBasePtr, aEndPtr, aElement, aValue);\nend;\n\nfunction TwbLStringDef.GetSize(aBasePtr, aEndPtr: Pointer; const aElement: IwbElement): Integer;\nbegin\n  if Assigned(aBasePtr) and Assigned(aEndPtr) and (Cardinal(aBasePtr) >= Cardinal(aEndPtr)) then\n    Result := 0\n  else if Assigned(aBasePtr) and Assigned(aEndPtr) and Assigned(aElement._File) and aElement._File.IsLocalized then\n    Result := Min(4, Cardinal(aEndPtr) - Cardinal(aBasePtr))\n  else\n    Result := inherited GetSize(aBasePtr, aEndPtr, aElement);\nend;\n\nfunction TwbLStringDef.GetDefaultSize(aBasePtr, aEndPtr: Pointer; const aElement: IwbElement): Integer;\nbegin\n  if Assigned(aElement._File) and aElement._File.IsLocalized then\n    Result := 4\n  else\n    Result := inherited GetDefaultSize(aBasePtr, aEndPtr, aElement);\nend;\n\nfunction TwbLStringDef.ToStringNative(aBasePtr, aEndPtr: Pointer; const aElement: IwbElement): AnsiString;\nbegin\n  if Assigned(aElement._File) and aElement._File.IsLocalized then begin\n    if (Cardinal(aEndPtr) - Cardinal(aBasePtr)) <> 4 then\n      Result := '< Error: lstring ID should be Int32 value >'\n    else\n      Result := wbStringToAnsi(wbLocalizationHandler.GetValue(PCardinal(aBasePtr)^, aElement), aElement)\n  end else\n    Result := inherited ToStringNative(aBasePtr, aEndPtr, aElement);\nend;\n\n{ TwbStringScriptDef }\n\nfunction TwbStringScriptDef.TransformString(const s: AnsiString; aTransformType: TwbStringTransformType; const aElement: IwbElement): AnsiString;\nvar\n  i: Integer;\nbegin\n  if aTransformType = ttToSortKey then begin\n    with TStringList.Create do try\n      Text := s;\n      for i := Pred(Count) downto 0 do begin\n        Strings[i] := Trim(Strings[i]);\n        if Strings[i] = '' then\n          Delete(i);\n      end;\n      Result := AnsiString(Text);\n    finally\n      Free;\n    end;\n  end else\n    Result := s;\nend;\n\n{ TwbStringMgefCodeDef }\n\nprocedure TwbStringMgefCodeDef.BuildRef(aBasePtr, aEndPtr: Pointer; const aElement: IwbElement);\nvar\n  _File : IwbFile;\n  Rec   : IwbMainRecord;\nbegin\n  _File := aElement._File;\n  if Assigned(_File) then begin\n    Rec := _File.RecordByEditorID[ToStringTransform(aBasePtr, aEndPtr, aElement, ttToSortKey)];\n    if Assigned(Rec) then\n      aElement.AddReferencedFromID(Rec.LoadOrderFormID);\n  end;\nend;\n\nfunction TwbStringMgefCodeDef.CanContainFormIDs: Boolean;\nbegin\n  Result := True;\nend;\n\nprocedure TwbStringMgefCodeDef.FindUsedMasters(aBasePtr, aEndPtr: Pointer; const aElement: IwbElement; aMasters: PwbUsedMasters);\nvar\n  s        : AnsiString;\n  MgefCode : PCardinal;\nbegin\n  s := ToStringNative(aBasePtr, aEndPtr, aElement);\n\n  if Length(s) <> 4 then\n    Exit;\n\n  MgefCode := PCardinal(@s[1]);\n\n  if (MgefCode^ and $80000000) <> 0 then\n    { yes, it's a dynamic code }\n    aMasters[(MgefCode^ and $000000FF)] := True;\nend;\n\nfunction TwbStringMgefCodeDef.GetLinksTo(aBasePtr, aEndPtr: Pointer; const aElement: IwbElement): IwbElement;\nvar\n  _File : IwbFile;\nbegin\n  Result := nil;\n  _File := aElement._File;\n  if Assigned(_File) then\n    Result := _File.RecordByEditorID[ToStringTransform(aBasePtr, aEndPtr, aElement, ttToSortKey)];\nend;\n\nprocedure TwbStringMgefCodeDef.MasterCountUpdated(aBasePtr, aEndPtr: Pointer; const aElement: IwbElement; aOld, aNew: Byte);\nvar\n  s        : AnsiString;\n  MgefCode : PCardinal;\nbegin\n  s := ToStringNative(aBasePtr, aEndPtr, aElement);\n\n  if Length(s) <> 4 then\n    Exit;\n\n  MgefCode := PCardinal(@s[1]);\n\n  if (MgefCode^ and $80000000) <> 0 then\n    { yes, it's a dynamic code }\n    if (MgefCode^ and $000000FF) >= aOld then begin\n      { yes, it refers to this file }\n      MgefCode^ := (MgefCode^ and $FFFFFF00) or aNew;\n      FromStringNative(aBasePtr, aEndPtr, aElement, s);\n      aElement.NotifyChanged(Pointer(aElement.Container));\n    end;\nend;\n\nprocedure TwbStringMgefCodeDef.MasterIndicesUpdated(aBasePtr, aEndPtr: Pointer; const aElement: IwbElement; const aOld, aNew: TBytes);\nvar\n  s        : AnsiString;\n  MgefCode : PCardinal;\n  i        : Integer;\nbegin\n  s := ToStringNative(aBasePtr, aEndPtr, aElement);\n\n  if Length(s) <> 4 then\n    Exit;\n\n  MgefCode := PCardinal(@s[1]);\n\n  Assert(Length(aOld) = Length(aNew));\n  if (MgefCode^ and $80000000) <> 0 then\n    { yes, it's a dynamic code }\n    for i := Low(aOld) to High(aOld) do\n      if (MgefCode^ and $000000FF) = aOld[i] then begin\n        { yes, it refers to this file }\n        MgefCode^ := (MgefCode^ and $FFFFFF00) or aNew[i];\n        FromStringNative(aBasePtr, aEndPtr, aElement, s);\n        aElement.NotifyChanged(Pointer(aElement.Container));\n        Exit;\n      end;\nend;\n\nfunction TwbStringMgefCodeDef.SetToDefault(aBasePtr, aEndPtr: Pointer; const aElement: IwbElement): Boolean;\nbegin\n  Result := not Assigned(aBasePtr) or (ToString(aBasePtr, aEndPtr, aElement) <> '____');\n  if Result then\n    FromEditValue(aBasePtr, aEndPtr, aElement, '____');\nend;\n\nfunction TwbStringMgefCodeDef.TransformString(const s: AnsiString; aTransformType: TwbStringTransformType; const aElement: IwbElement): AnsiString;\nvar\n  IsAlpha  : Boolean;\n  i, j     : Integer;\n  MgefCode : Cardinal;\n  _File    : IwbFile;\n  FileID   : Byte;\n  t        : AnsiString;\nbegin\n  case aTransformType of\n    ttToString, ttToSortKey, ttToEditValue, ttToNativeValue: begin\n      Result := s;\n      if Length(s) = 4 then begin\n        IsAlpha := True;\n        for i := 1 to 4 do\n          if not(s[i] in ['a'..'z', 'A'..'Z', '0'..'9', '_']) then begin\n            IsAlpha := False;\n            break;\n          end;\n        if not IsAlpha then begin\n          MgefCode := PCardinal(@s[1])^;\n          if (MgefCode and $80000000) <> 0 then begin\n            if Assigned(aElement) then begin\n              _File := aElement._File;\n              if Assigned(_File) then begin\n                FileID := MgefCode and $000000FF;\n\n                if FileID >= _File.MasterCount then\n                  Result := AnsiString(_File.Name)\n                else\n                  Result := AnsiString(_File.Masters[FileID].Name);\n\n                Result := Result + ':' + AnsiString(IntToStr((MgefCode and not $800000FF) shr 8));\n\n                Exit;\n              end;\n            end;\n          end;\n          Result := AnsiString(IntToHex64(MgefCode, 8));\n          if aTransformType = ttToString then\n            Result := Result + ' <Warning: Effect Code is neither alphanumeric nor dynamic>';\n        end;\n      end else if aTransformType = ttToString then\n        Result := Result + AnsiString(' <Warning: Expected 4 bytes but found ' + IntToStr(Length(s)) + '>');\n    end;\n    ttFromEditValue, ttFromNativeValue: begin\n      Result := Trim(s);\n      if S = '' then\n        Exit;\n      i := Pos(':', Result);\n      if i > 0 then begin\n\n        t := Copy(Result, 1, Pred(i));\n\n        FileID := $FF;\n\n        if Assigned(aElement) then begin\n          _File := aElement._File;\n          if Assigned(_File) then begin\n            if SameText(t, _File.FileName) then\n              FileID := _File.MasterCount\n            else if SameText(t, _File.Name) then\n              FileID := _File.MasterCount\n            else begin\n              for j := 0 to Pred(_File.MasterCount) do\n                if SameText(t, _File.Masters[j].Name) then begin\n                  FileID := j;\n                  break;\n                end;\n              if FileID = $FF then\n                for j := 0 to Pred(_File.MasterCount) do\n                  if SameText(t, _File.Masters[j].FileName) then begin\n                    FileID := j;\n                    break;\n                  end;\n            end;\n          end;\n        end;\n\n        if FileID = $FF then begin\n          if i > 1 then\n            FileID := StrToInt('$' + t);\n\n          if Assigned(aElement) then begin\n            _File := aElement._File;\n            if Assigned(_File) then\n              if FileID = $FF then\n                FileID := _File.MasterCount\n              else\n                FileID := _File.LoadOrderFileIDtoFileFileID(FileID);\n          end;\n        end;\n\n        t := Copy(Result, Succ(i), High(Integer));\n        MgefCode := StrToInt(t);\n        if MgefCode > $7FFFFF then\n          raise Exception.Create('\"'+t+'\" exceeds the maximum value for a dynamic magic effect code');\n        MgefCode := (MgefCode shl 8) or $80000000;\n\n        MgefCode := MgefCode or FileID;\n\n      end else if Length(Result) = 8 then begin\n\n        MgefCode := StrToInt('$' + Result);\n        if (MgefCode and $80000000) <> 0 then\n          raise Exception.Create('\"'+Result+'\" is not a valid magic effect code');\n\n      end else if Length(s) = 4 then begin\n\n        IsAlpha := True;\n        for i := 1 to 4 do\n          if not(s[i] in ['a'..'z', 'A'..'Z', '0'..'9', '_']) then begin\n            IsAlpha := False;\n            break;\n          end;\n        if not IsAlpha then\n          raise Exception.Create('\"'+Result+'\" is not a valid magic effect code');\n        MgefCode := PCardinal(@Result[1])^;\n\n      end else\n        raise Exception.Create('\"'+Result+'\" is not a valid magic effect code');\n\n      SetLength(Result, 4);\n      PCardinal(@Result[1])^ := MgefCode;\n    end;\n  end;\nend;\n\nfunction GetContainerFromUnion(const aElement: IwbElement): IwbContainer;\nbegin  // Should change the name to GetContainerFromUnionOrValue :)\n  if (aElement.ElementType = etUnion) or (aElement.ElementType = etValue) then begin\n    Result := aElement.Container;\n    while Result.ElementType = etUnion do\n      Result := Result.Container\n  end else\n    Result := aElement as IwbContainer;\nend;\n\nfunction GetContainerRefFromUnionOrValue(const aElement: IwbElement): IwbContainerElementRef;\nbegin\n  if (aElement.ElementType = etUnion) or (aElement.ElementType = etValue) then begin\n    Supports(aElement.Container, IwbContainerElementRef, Result);\n    while Result.ElementType = etUnion do\n      Supports(Result.Container, IwbContainerElementRef, Result);\n  end else\n    Supports(aElement, IwbContainerElementRef, Result);\nend;\n\nfunction GetElementFromUnion(const aElement: IwbElement): IwbElement;\nbegin\n  if (aElement.ElementType = etUnion) then begin\n    Result := aElement.Container;\n    while Result.ElementType = etUnion do\n      Result := Result.Container;\n  end else\n    Result := aElement;\nend;\n\n{ TwbStringKCDef }\n\nfunction TwbStringKCDef.ToSortKey(aBasePtr, aEndPtr: Pointer; const aElement: IwbElement; aExtended: Boolean): string;\nbegin\n  Result := ToStringTransform(aBasePtr, aEndPtr, aElement, ttToSortKey);\nend;\n\n{ TwbLStringKCDef }\n\nfunction TwbLStringKCDef.ToSortKey(aBasePtr, aEndPtr: Pointer; const aElement: IwbElement; aExtended: Boolean): string;\nbegin\n  Result := ToStringTransform(aBasePtr, aEndPtr, aElement, ttToSortKey);\nend;\n\n{ TwbRefID }\n\nvar\n  wbRefIDArray : TwbRefIDArray = nil;\n\nprocedure InitializeRefIDArray(anArray: TwbRefIDArray);\nbegin\n  wbRefIDArray := anArray;\nend;\n\nprocedure TwbRefID.BuildRef(aInt: Int64; const aElement: IwbElement);\nvar\n  key        : Integer;\n  val        : Integer;\nbegin\n  // First two bits are the key:\n  key := aInt shr 22;\n  val := aInt and $003FFFFF;\n  case key of\n    0: if (val > 0) and (val < Length(wbRefIDArray)) then\n         inherited BuildRef(wbRefIDArray[val - 1], aElement);\n    1: inherited BuildRef(val, aElement); // '['+IntToHex64(val, 8)+'] Skyrim.esm FormID';\n  end;\nend;\n\nfunction TwbRefID.ToString(aInt: Int64; const aElement: IwbElement): string;\nvar\n  key        : Integer;\n  val        : Integer;\nbegin\n  // First two bits are the key:\n  key := aInt shr 22;\n  val := aInt and $003FFFFF;\n  case key of\n    0: if val = 0 then\n         Result := '[00000000] NULL'\n       else if val < Length(wbRefIDArray) then begin\n         val := wbRefIDArray[val - 1];\n         Result := inherited ToString(val, aElement);\n         Result := Copy(Result, 1, Pos('[', Result)) + IntToHex64(val, 8) + Copy(Result, Pos(']', Result), Length(Result));\n       end else\n         Result := '['+IntToHex64(val-1, 8)+'] Index in FormID Array';\n    1: Result := inherited ToString(val, aElement);\n    2: Result := '[FF'+IntToHex64(val, 6)+'] Created FormID';\n    else\n      Result := '['+IntToHex64(aInt, 8)+']  <Error: bad key for RefID '+IntToStr(key)+'>';\n  end;\n  Result := IntToStr(aInt)+' '+Result;\n  Used(aElement, Result);\nend;\n\n{ TwbDumpIntegerDefFormater }\n\nfunction TwbDumpIntegerDefFormater.ToSortKey(aInt: Int64; const aElement: IwbElement): string;\nbegin\n  Result := IntToHex64(aInt, 8);\nend;\n\nfunction TwbDumpIntegerDefFormater.ToString(aInt: Int64; const aElement: IwbElement): string;\nbegin\n  Result := IntToStr(aInt) + ' [' + IntToHex64(aInt, 8) + '] ['+IntToStr(aInt and $03)+':'+IntToStr(aInt shr 2)+']';\nend;\n\n{ TwbStructCDef }\n\nconstructor TwbStructCDef.Clone(const aSource: TwbDef);\nbegin\n  with aSource as TwbStructCDef do\n    Self.Create(defPriority, defRequired, noName, stMembers, stSortKey,\n      stExSortKey, stOptionalFromElement, noDontShow, noAfterLoad, noAfterSet,\n      scSizeCallback, scGetChapterType, scGetChapterTypeName, scGetChapterName, defGetCP).defSource := aSource;\nend;\n\nconstructor TwbStructCDef.Create(aPriority: TwbConflictPriority;\n                                 aRequired            : Boolean;\n                           const aName                : string;\n                           const aMembers             : array of IwbValueDef;\n                           const aSortKey, aExSortKey : array of Integer;\n                                 aOptionalFromElement : Integer;\n                                 aDontShow            : TwbDontShowCallback;\n                                 aAfterLoad           : TwbAfterLoadCallback;\n                                 aAfterSet            : TwbAfterSetCallback;\n                                 aSizeCallBack        : TwbSizeCallback;\n                                 aGetChapterType      : TwbGetChapterTypeCallback;\n                                 aGetChapterTypeName  : TwbGetChapterTypeNameCallback;\n                                 aGetChapterName      : TwbGetChapterNameCallback;\n                                 aGetCP               : TwbGetConflictPriority);\nbegin\n  scSizeCallback := aSizeCallback;\n  scGetChapterType := aGetChapterType;\n  scGetChapterTypeName := aGetChapterTypeName;\n  scGetChapterName := aGetChapterName;\n  inherited Create(aPriority, aRequired, aName, aMembers, aSortKey, aExSortKey, [], aOptionalFromElement, aDontShow, aAfterLoad, aAfterSet, aGetCP);\n  noTreeBranch := False;\nend;\n\nfunction TwbStructCDef.GetDefType: TwbDefType;\nbegin\n  Result := dtStructChapter;\nend;\n\nfunction TwbStructCDef.GetDefTypeName: string;\nbegin\n  Result := 'Chapter';\nend;\n\nfunction TwbStructCDef.GetSizing(aBasePtr, aEndPtr: Pointer; const aElement: IwbElement; var CompressedSize: Integer): Cardinal;\nbegin\n  if Assigned(scSizeCallback) then\n    Result := scSizeCallback(aBasePtr, aEndPtr, aElement, CompressedSize)\n  else begin\n    CompressedSize := -1;\n    Result := 0;\n  end;\nend;\n\nfunction TwbStructCDef.GetChapterName(aBasePtr, aEndPtr: Pointer;\n  const aElement: IwbElement): String;\nbegin\n  if Assigned(scGetChapterName) then\n    Result := scGetChapterName(aBasePtr, aEndPtr, aElement)\n  else if Assigned(scGetChapterTypeName) then\n    Result := scGetChapterTypeName(aBasePtr, aEndPtr, aElement)\n  else\n    Result := GetName;\nend;\n\nfunction TwbStructCDef.GetChapterType(aBasePtr, aEndPtr: Pointer; const aElement: IwbElement): Integer;\nbegin\n  if Assigned(scGetChapterType) then\n    Result := scGetChapterType(aBasePtr, aEndPtr, aElement)\n  else\n    Result := -1;\nend;\n\nfunction TwbStructCDef.GetChapterTypeName(aBasePtr, aEndPtr: Pointer; const aElement: IwbElement): String;\nbegin\n  if Assigned(scGetChapterTypeName) then\n    Result := scGetChapterTypeName(aBasePtr, aEndPtr, aElement)\n  else\n    Result := IntToStr(GetChapterType(aBasePtr, aEndPtr, aElement));\nend;\n\n{ TwbKey2Data6EnumDef }\n\nfunction TwbKey2Data6EnumDef.ToSortKey(aInt: Int64; const aElement: IwbElement): string;\nbegin\n  Result := IntToHex64(aInt, 2);\nend;\n\nfunction TwbKey2Data6EnumDef.ToString(aInt: Int64; const aElement: IwbElement): string;\nvar\n  key : Integer;\n  val : Integer;\nbegin\n  key := aInt shr 6;\n  val := aInt and $3f;\n  if val>=Length(enNames) then\n    Result := 'Bad enum index: ' + IntToStr(val) + ' [' + IntToHex64(val, 2) + ']'\n  else\n    Result := enNames[val];\n  case key of\n    0: Result := Result + ' Small size';\n    1: Result := Result + ' Medium size';\n    2: Result := Result + ' Large size';\n  end;\nend;\n\n{ TwbData6Key2EnumDef }\n\nfunction TwbData6Key2EnumDef.ToSortKey(aInt: Int64; const aElement: IwbElement): string;\nbegin\n  Result := IntToHex64(aInt, 2);\nend;\n\nfunction TwbData6Key2EnumDef.ToString(aInt: Int64; const aElement: IwbElement): string;\nvar\n  key : Integer;\nbegin\n  if aInt < Power(2, 6) then\n    key := 0\n  else if aInt < Power(2, 14) then\n    key := 1\n  else if aInt < Power(2, 22) then\n    key := 2\n  else\n    key := 3;\n  Result := IntToStr(aInt);\n  case key of\n    0: Result := Result + ' Small size';\n    1: Result := Result + ' Medium size';\n    2: Result := Result + ' Large size';\n    3: Result := '0' + ' Null size';\n  end;\nend;\n\n{ TwbIntegerDefFormaterUnion }\n\nprocedure TwbIntegerDefFormaterUnion.BuildRef(aInt     : Int64;\n                                        const aElement : IwbElement);\nvar\n  IntegerDef: IwbIntegerDefFormater;\nbegin\n  IntegerDef := Decide(aElement);\n  if Assigned(IntegerDef) then\n    IntegerDef.BuildRef(aInt, aElement);\nend;\n\nfunction TwbIntegerDefFormaterUnion.CanAssign(const aElement : IwbElement;\n                                                    aIndex   : Integer;\n                                              const aDef     : IwbDef)\n                                                             : Boolean;\nvar\n  IntegerDef: IwbIntegerDefFormater;\nbegin\n  IntegerDef := Decide(aElement);\n  if Assigned(IntegerDef) then\n    Result := IntegerDef.CanAssign(aElement, aIndex, aDef)\n  else\n    Result := False;\nend;\n\nfunction TwbIntegerDefFormaterUnion.CanContainFormIDs: Boolean;\nvar\n  i: Integer;\nbegin\n  for i := Low(idfuMembers) to High(idfuMembers) do\n    if idfuMembers[i].CanContainFormIDs then\n      Exit(True);\n  Result := False;\nend;\n\nfunction TwbIntegerDefFormaterUnion.Check(aInt     : Int64;\n                                    const aElement : IwbElement)\n                                                   : string;\nbegin\n  Result := Decide(aElement).Check(aInt, aElement);\nend;\n\nconstructor TwbIntegerDefFormaterUnion.Clone(const aSource: TwbDef);\nbegin\n  with aSource as TwbIntegerDefFormaterUnion do\n    Self.Create(defPriority, defRequired, defGetCP, idfuDecider, idfuMembers).defSource := aSource;\nend;\n\nfunction TwbIntegerDefFormaterUnion.CompareExchangeFormID(var aInt       : Int64;\n                                                              aOldFormID : Cardinal;\n                                                              aNewFormID : Cardinal;\n                                                        const aElement   : IwbElement)\n                                                                         : Boolean;\nvar\n  IntegerDef: IwbIntegerDefFormater;\nbegin\n  IntegerDef := Decide(aElement);\n  if Assigned(IntegerDef) then\n    Result := IntegerDef.CompareExchangeFormID(aInt, aOldFormID, aNewFormID, aElement)\n  else\n    Result := False;\nend;\n\nconstructor TwbIntegerDefFormaterUnion.Create(aPriority : TwbConflictPriority;\n                                              aRequired : Boolean;\n                                              aGetCP    : TwbGetConflictPriority;\n                                              aDecider  : TwbIntegerDefFormaterUnionDecider;\n                                        const aMembers  : array of IwbIntegerDefFormater);\nvar\n  i: Integer;\nbegin\n  inherited Create(aPriority, aRequired, aGetCP);\n  idfuDecider := aDecider;\n  SetLength(idfuMembers, Length(aMembers));\n  for i := Low(aMembers) to High(aMembers) do\n    idfuMembers[i] := (aMembers[i] as IwbDefInternal).SetParent(Self, False) as IwbIntegerDefFormater;\nend;\n\nfunction TwbIntegerDefFormaterUnion.Decide(const aElement : IwbElement)\n                                                          : IwbIntegerDefFormater;\nvar\n  i: Integer;\nbegin\n  i := idfuDecider(aElement);\n  if (i>=0) and (i<Length(idfuMembers)) then\n    Result := idfuMembers[i]\n  else\n    Result := nil;\nend;\n\nprocedure TwbIntegerDefFormaterUnion.FindUsedMasters(aInt     : Int64;\n                                                     aMasters : PwbUsedMasters;\n                                               const aElement : IwbElement);\nvar\n  IntegerDef: IwbIntegerDefFormater;\nbegin\n  IntegerDef := Decide(aElement);\n  if Assigned(IntegerDef) then\n    IntegerDef.FindUsedMasters(aInt, aMasters, aElement);\nend;\n\nfunction TwbIntegerDefFormaterUnion.FromEditValue(const aValue   : string;\n                                                  const aElement : IwbElement)\n                                                                 : Int64;\nvar\n  IntegerDef: IwbIntegerDefFormater;\nbegin\n  IntegerDef := Decide(aElement);\n  if Assigned(IntegerDef) then\n    Result := IntegerDef.FromEditValue(aValue, aElement)\n  else\n    Result := 0;\nend;\n\nfunction TwbIntegerDefFormaterUnion.GetDefType: TwbDefType;\nbegin\n  Result := dtIntegerFormaterUnion;\nend;\n\nfunction TwbIntegerDefFormaterUnion.GetEditInfo(aInt     : Int64;\n                                          const aElement : IwbElement)\n                                                         : string;\nvar\n  IntegerDef: IwbIntegerDefFormater;\nbegin\n  IntegerDef := Decide(aElement);\n  if Assigned(IntegerDef) then\n    Result := IntegerDef.GetEditInfo(aInt, aElement)\n  else\n    Result := '';\nend;\n\nfunction TwbIntegerDefFormaterUnion.GetEditType(aInt     : Int64;\n                                          const aElement : IwbElement)\n                                                         : TwbEditType;\nvar\n  IntegerDef: IwbIntegerDefFormater;\nbegin\n  IntegerDef := Decide(aElement);\n  if Assigned(IntegerDef) then\n    Result := IntegerDef.GetEditType(aInt, aElement)\n  else\n    Result := etDefault;\nend;\n\nfunction TwbIntegerDefFormaterUnion.GetIsEditable(aInt     : Int64;\n                                            const aElement : IwbElement)\n                                                           : Boolean;\nvar\n  IntegerDef: IwbIntegerDefFormater;\nbegin\n  IntegerDef := Decide(aElement);\n  if Assigned(IntegerDef) then\n    Result := IntegerDef.GetIsEditable(aInt, aElement)\n  else\n    Result := False;\nend;\n\nfunction TwbIntegerDefFormaterUnion.GetLinksTo(aInt     : Int64;\n                                         const aElement : IwbElement)\n                                                        : IwbElement;\nvar\n  IntegerDef: IwbIntegerDefFormater;\nbegin\n  IntegerDef := Decide(aElement);\n  if Assigned(IntegerDef) then\n    Result := IntegerDef.GetLinksTo(aInt, aElement)\n  else\n    Result := nil;\nend;\n\nfunction TwbIntegerDefFormaterUnion.GetMember(aIndex: Integer): IwbIntegerDefFormater;\nbegin\n  if (aIndex>=0) and (aIndex<Length(idfuMembers)) then\n    Result := idfuMembers[aIndex];\nend;\n\nfunction TwbIntegerDefFormaterUnion.GetMemberCount: Integer;\nbegin\n  Result := Length(idfuMembers);\nend;\n\nfunction TwbIntegerDefFormaterUnion.GetNoReach: Boolean;\nvar\n  i: Integer;\nbegin\n  for i := Low(idfuMembers) to High(idfuMembers) do\n    if idfuMembers[i].NoReach then\n      Exit(True);\n  Result := False;\nend;\n\nfunction TwbIntegerDefFormaterUnion.MasterCountUpdated(aInt     : Int64;\n                                                       aOld     : Byte;\n                                                       aNew     : Byte;\n                                                 const aElement : IwbElement)\n                                                                : Int64;\nvar\n  IntegerDef: IwbIntegerDefFormater;\nbegin\n  IntegerDef := Decide(aElement);\n  if Assigned(IntegerDef) then\n    Result := IntegerDef.MasterCountUpdated(aInt, aOld, aNew, aElement)\n  else\n    Result := 0;\nend;\n\nfunction TwbIntegerDefFormaterUnion.MasterIndicesUpdated(aInt     : Int64;\n                                                   const aOld     : TBytes;\n                                                   const aNew     : TBytes;\n                                                   const aElement : IwbElement)\n                                                                  : Int64;\nvar\n  IntegerDef: IwbIntegerDefFormater;\nbegin\n  IntegerDef := Decide(aElement);\n  if Assigned(IntegerDef) then\n    Result := IntegerDef.MasterIndicesUpdated(aInt, aOld, aNew, aElement)\n  else\n    Result := 0;\nend;\n\nprocedure TwbIntegerDefFormaterUnion.Report(const aParents: TwbDefPath);\nbegin\n  inherited;\n\nend;\n\nfunction TwbIntegerDefFormaterUnion.ToEditValue(aInt     : Int64;\n                                          const aElement : IwbElement)\n                                                         : string;\nvar\n  IntegerDef: IwbIntegerDefFormater;\nbegin\n  IntegerDef := Decide(aElement);\n  if Assigned(IntegerDef) then\n    Result := IntegerDef.ToEditValue(aInt, aElement)\n  else\n    Result := '';\nend;\n\nfunction TwbIntegerDefFormaterUnion.ToSortKey(aInt     : Int64;\n                                        const aElement : IwbElement)\n                                                       : string;\nvar\n  IntegerDef: IwbIntegerDefFormater;\nbegin\n  IntegerDef := Decide(aElement);\n  if Assigned(IntegerDef) then\n    Result := IntegerDef.ToSortKey(aInt, aElement)\n  else\n    Result := '';\nend;\n\nfunction TwbIntegerDefFormaterUnion.ToString(aInt     : Int64;\n                                       const aElement : IwbElement)\n                                                      : string;\nvar\n  IntegerDef: IwbIntegerDefFormater;\nbegin\n  IntegerDef := Decide(aElement);\n  if Assigned(IntegerDef) then\n    Result := IntegerDef.ToString(aInt, aElement)\n  else\n    Result := '';\nend;\n\nfunction wbFindRecordDef(const aSignature : TwbSignature;\n                           out aRecordDef : PwbRecordDef)\n                                          : Boolean;\nvar\n  Hash     : Integer;\n  Index    : Integer;\n  RDE      : PwbRecordDefEntry;\n\nbegin\n  Hash := Cardinal(aSignature) mod RecordDefHashMapSize;\n  Index := Pred(wbRecordDefHashMap[Hash]);\n  if Index >= 0 then begin\n    RDE := @wbRecordDefs[Index];\n    while Assigned(RDE) do begin\n      if Cardinal(RDE.rdeSignature) = Cardinal(aSignature) then begin\n        aRecordDef := @RDE.rdeDef;\n        Exit(True);\n      end;\n      if RDE.rdeNext >= 0 then\n        RDE := @wbRecordDefs[RDE.rdeNext]\n      else\n        RDE := nil;\n    end;\n  end;\n  aRecordDef := nil;\n  Result := False;\nend;\n\nfunction wbFindRecordDef(const aSignature : AnsiString;\n                           out aRecordDef : PwbRecordDef)\n                                          : Boolean;\nbegin\n  Result := (Length(aSignature) = 4) and\n    wbFindRecordDef(PwbSignature(@aSignature[1])^, aRecordDef);\nend;\n\nvar\n  wbRecordDefMap: TStringList;\n\nfunction _wbRecordDefMap: TStringList;\nvar\n  i: Integer;\nbegin\n  if not Assigned(wbRecordDefMap) then begin\n    wbRecordDefMap := TwbFastStringList.Create;\n    for i := Low(wbRecordDefs) to High(wbRecordDefs) do\n      with wbRecordDefs[i] do\n        wbRecordDefMap.AddObject(rdeSignature, Pointer(rdeDef));\n    wbRecordDefMap.Sorted := True;\n  end;\n  Result := wbRecordDefMap;\nend;\n\n{$IFDEF USE_CODESITE}\nthreadvar\n  wbCodeSiteLoggingCount: Integer;\n\nfunction wbCodeSiteLoggingEnabled: Boolean;\nbegin\n  Result := wbCodeSiteLoggingCount > 0;\nend;\n\nfunction wbBeginCodeSiteLogging: Integer;\nbegin\n  Result := Succ(wbCodeSiteLoggingCount);\n  wbCodeSiteLoggingCount := Result;\nend;\n\nfunction wbEndCodeSiteLogging: Integer;\nbegin\n  Result := Pred(wbCodeSiteLoggingCount);\n  wbCodeSiteLoggingCount := Result;\nend;\n{$ENDIF}\n\n{ TwbFlagDef }\n\nfunction TwbFlagDef.CanContainFormIDs: Boolean;\nbegin\n  Result := False;\nend;\n\nconstructor TwbFlagDef.Clone(const aSource: TwbDef);\nbegin\n  with (aSource as TwbFlagDef) do\n    Self.Create(defPriority, defRequired, noName, noAfterLoad, noAfterSet,\n      noDontShow, defGetCP, noTerminator, fdFlagIndex).defSource := aSource;\nend;\n\nconstructor TwbFlagDef.Create(aPriority   : TwbConflictPriority;\n                              aRequired   : Boolean;\n                        const aName       : string;\n                              aAfterLoad  : TwbAfterLoadCallback;\n                              aAfterSet   : TwbAfterSetCallback;\n                              aDontShow   : TwbDontShowCallback;\n                              aGetCP      : TwbGetConflictPriority;\n                              aTerminator : Boolean;\n                              aFlagIndex  : Integer);\nbegin\n  fdFlagIndex := aFlagIndex;\n  inherited Create(aPriority, aRequired, aName, aAfterLoad, aAfterSet, aDontShow, aGetCP, aTerminator);\nend;\n\nfunction TwbFlagDef.GetCanBeZeroSize: Boolean;\nbegin\n  Result := True;\nend;\n\nfunction TwbFlagDef.GetConflictPriority(const aElement: IwbElement): TwbConflictPriority;\nbegin\n  with GetFlagsDef do begin\n    if FlagIgnoreConflict[GetFlagIndex] then\n      Result := cpIgnore\n    else\n      Result := cpNormal;\n    FlagGetCP(aElement, GetFlagIndex, Result);\n  end;\nend;\n\nfunction TwbFlagDef.GetConflictPriorityCanChange: Boolean;\nbegin\n  Result := GetFlagsDef.FlagHasGetCP[GetFlagIndex];\nend;\n\nfunction TwbFlagDef.GetDefaultSize(aBasePtr, aEndPtr: Pointer; const aElement: IwbElement): Integer;\nbegin\n  Result := 0;\nend;\n\nfunction TwbFlagDef.GetDefType: TwbDefType;\nbegin\n  Result := dtFlag;\nend;\n\nfunction TwbFlagDef.GetDefTypeName: string;\nbegin\n  Result := 'FlagDef';\nend;\n\nfunction TwbFlagDef.GetDontShow(const aElement: IwbElement): Boolean;\nbegin\n  Result := GetFlagsDef.FlagDontShow[aElement, GetFlagIndex];\nend;\n\nfunction TwbFlagDef.GetFlagIndex: Integer;\nbegin\n  Result := fdFlagIndex;\nend;\n\nfunction TwbFlagDef.GetFlagsDef: IwbFlagsDef;\nbegin\n  Result := defParent as IwbFlagsDef;\nend;\n\nfunction TwbFlagDef.GetHasDontShow: Boolean;\nbegin\n  Result := GetFlagsDef.FlagHasDontShow[GetFlagIndex];\nend;\n\nfunction TwbFlagDef.GetSize(aBasePtr, aEndPtr: Pointer; const aElement: IwbElement): Integer;\nbegin\n  Result := 0;\nend;\n\nfunction TwbFlagDef.ToString(aBasePtr, aEndPtr: Pointer; const aElement: IwbElement): string;\nbegin\n  Assert(False);\n  Result := '';\nend;\n\nfunction wbIsPlugin(aFileName: string): Boolean;\nvar\n  i: Integer;\nbegin\n  Result := Pos(UpperCase(wbHardcodedDat), UpperCase(aFileName))<>0;\n  if not Result then\n    for i := 0 to Pred(Length(wbPluginExtensions)) do\n      if Pos(UpperCase(wbPluginExtensions[i]), UpperCase(ExtractFileExt(aFileName)))=1 then begin\n        Result := True;\n        Exit;\n      end;\nend;\n\nfunction wbStr4ToString(aInt: Int64): string;\nvar\n  U32  : Cardinal;\n  Temp : String;\n  i    : Integer;\nbegin\n  if aInt=0 then\n    Result := '    '\n  else begin\n    U32 := aInt;\n    Result := PwbSignature(@U32)^;\n    if Length(Result)=4 then begin\n      Temp := Result;\n      for i := 1 to 4 do Result[i] := Temp[5-i];\n    end else begin\n      Result := '    ';\n      // wbProgressCallback('Found a str4 that does not have 4 characters! (1) '+IntToHex64(aInt, 8));\n    end;\n  end;\nend;\n\ninitialization\n  TwoPi := 2 * OnePi;\n\n  if (DebugHook = 0) then\n    wbReportMode := False;\n\n  wbIgnoreRecords := TStringList.Create;\n  wbIgnoreRecords.Sorted := True;\n  wbIgnoreRecords.Duplicates := dupIgnore;\n  wbDoNotBuildRefsFor := TStringList.Create;\n  wbDoNotBuildRefsFor.Sorted := True;\n  wbDoNotBuildRefsFor.Duplicates := dupIgnore;\n\n  wbProgramPath := IncludeTrailingPathDelimiter(ExtractFilePath(ParamStr(0)));\n\n  SetLength(wbPluginExtensions, 3);\n  wbPluginExtensions[0] := '.ESP';\n  wbPluginExtensions[1] := '.ESM';\n  wbPluginExtensions[2] := '.GHOST';\n\nfinalization\n  FreeAndNil(wbIgnoreRecords);\n  FreeAndNil(wbDoNotBuildRefsFor);\n  FreeAndNil(wbGroupOrder);\n  FreeAndNil(wbRecordDefMap);\n  wbRecordDefs := nil;\n  wbContainerHandler := nil;\nend.\n\n"
  },
  {
    "path": "lib/xedit/wbLocalization.pas",
    "content": "{*******************************************************************************\n\n     The contents of this file are subject to the Mozilla Public License\n     Version 1.1 (the \"License\"); you may not use this file except in\n     compliance with the License. You may obtain a copy of the License at\n     http://www.mozilla.org/MPL/\n\n     Software distributed under the License is distributed on an \"AS IS\"\n     basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the\n     License for the specific language governing rights and limitations\n     under the License.\n\n*******************************************************************************}\n\nunit wbLocalization;\n\n{$I wbDefines.inc}\n\ninterface\n\nuses\n  Classes, SysUtils, StrUtils, Math,\n  wbInterface, wbBSA;\n\nconst\n  sStringID = 'STRINGID:';\n\ntype\n  TwbLStringType = (\n    lsDLString,\n    lsILString,\n    lsString\n  );\n\n  TwbLocalizationFile = class\n  private\n    fName        : string;\n    fFileName    : string;\n    fFileType    : TwbLStringType;\n    fStrings     : TStrings;\n    fModified    : boolean;\n    fNextID      : Cardinal;\n\n    procedure Init;\n    function FileStringType(aFileName: string): TwbLStringType;\n    function ReadZString(aStream: TMemoryStream): AnsiString;\n    function ReadLenZString(aStream: TMemoryStream): AnsiString;\n    procedure WriteZString(aStream: TMemoryStream; aString: AnsiString);\n    procedure WriteLenZString(aStream: TMemoryStream; aString: AnsiString);\n    procedure ReadDirectory(aStream: TMemoryStream);\n  protected\n    function Get(Index: Cardinal): string;\n    procedure Put(Index: Cardinal; const S: string);\n  public\n    property Strings[Index: Cardinal]: string read Get write Put; default;\n    property Items: TStrings read fStrings;\n    property Name: string read fName;\n    property FileName: string read fFileName;\n    property Modified: boolean read fModified write fModified;\n    property NextID: Cardinal read fNextID;\n    constructor Create(const aFileName: string); overload;\n    constructor Create(const aFileName: string; aData: TBytes); overload;\n    destructor Destroy; override;\n    function Count: Integer;\n    function IndexToID(Index: Integer): Cardinal;\n    function IDExists(ID: Cardinal): boolean;\n    function AddString(ID: Integer; const S: string): boolean;\n    procedure WriteToStream(const aStream: TStream);\n    procedure ExportToFile(const aFileName: string);\n  end;\n\n  TwbLocalizationHandler = class\n  private\n    lFiles       : TStrings;\n    fReuseDup    : boolean;\n  protected\n    function Get(Index: Integer): TwbLocalizationFile;\n    function GetStringsPath: string;\n  public\n    NoTranslate: boolean;\n    property _Files[Index: Integer]: TwbLocalizationFile read Get; default;\n    property StringsPath: string read GetStringsPath;\n    property ReuseDup: Boolean read fReuseDup write fReuseDup;\n    constructor Create;\n    destructor Destroy; override;\n    procedure Clear;\n    function Count: Integer;\n    function LocalizedValueDecider(aElement: IwbElement): TwbLStringType;\n    function AvailableLanguages: TStringList;\n    function AvailableLocalizationFiles: TStringList;\n    procedure LoadForFile(aFileName: string);\n    function AddLocalization(const aFileName: string): TwbLocalizationFile; overload;\n    function AddLocalization(const aFileName: string; aData: TBytes): TwbLocalizationFile; overload;\n    function GetValue(ID: Cardinal; aElement: IwbElement): string;\n    function SetValue(ID: Cardinal; aElement: IwbElement; aValue: string): Cardinal;\n    function AddValue(aValue: string; aElement: IwbElement): Cardinal;\n    function GetLocalizationFileNameByElement(aElement: IwbElement): string;\n    function GetLocalizationFileNameByType(aPluginFile: string; ls: TwbLStringType): string;\n    procedure GetStringsFromFile(aFileName: string; const aList: TStrings);\n  end;\n\nconst\n  wbLocalizationExtension: array [TwbLStringType] of string = (\n    '.DLSTRINGS',\n    '.ILSTRINGS',\n    '.STRINGS'\n  );\n\nvar\n  wbLocalizationHandler: TwbLocalizationHandler;\n\nimplementation\n\nuses\n  WideStrUtils;\n\nconstructor TwbLocalizationFile.Create(const aFileName: string);\nvar\n  fs: TFileStream;\n  fStream: TMemoryStream;\n  Buffer: PByte;\nbegin\n  fFileName := aFileName;\n  Init;\n  // cache file in mem\n  fStream := TMemoryStream.Create;\n  try\n    fs := TFileStream.Create(aFileName, fmOpenRead or fmShareDenyNone);\n    GetMem(Buffer, fs.Size);\n    try\n      fs.ReadBuffer(Buffer^, fs.Size);\n      fStream.WriteBuffer(Buffer^, fs.Size);\n      fStream.Position := 0;\n      ReadDirectory(fStream);\n    finally\n      if Assigned(Buffer) then FreeMem(Buffer);\n    end;\n  finally\n    FreeAndNil(fs);\n    FreeAndNil(fStream);\n  end;\nend;\n\nconstructor TwbLocalizationFile.Create(const aFileName: string; aData: TBytes);\nvar\n  fStream: TMemoryStream;\nbegin\n  fFileName := aFileName;\n  Init;\n  fStream := TMemoryStream.Create;\n  try\n    fStream.WriteBuffer(aData[0], length(aData));\n    fStream.Position := 0;\n    ReadDirectory(fStream);\n  finally\n    FreeAndNil(fStream);\n  end;\nend;\n\ndestructor TwbLocalizationFile.Destroy;\nbegin\n  FreeAndNil(fStrings);\n  inherited;\nend;\n\nprocedure TwbLocalizationFile.Init;\nbegin\n  fModified := false;\n  fName := ExtractFileName(fFileName);\n  fFileType := FileStringType(fFileName);\n  fStrings := TwbFastStringList.Create;\n  fNextID := 1;\nend;\n\nfunction TwbLocalizationFile.FileStringType(aFileName: string): TwbLStringType;\nvar\n  ext: string;\n  i: TwbLStringType;\nbegin\n  Result := lsString;\n  ext := ExtractFileExt(aFileName);\n  for i := Low(TwbLStringType) to High(TwbLStringType) do\n    if SameText(ext, wbLocalizationExtension[i]) then\n      Result := i;\nend;\n\nfunction TwbLocalizationFile.ReadZString(aStream: TMemoryStream): AnsiString;\nvar\n  Position : Integer;\nbegin\n  Position := aStream.Position;\n  Result := PAnsiChar(@PByte(aStream.Memory)[Position]);\n  aStream.Position := aStream.Position + Succ(Length(Result));\nend;\n\nfunction TwbLocalizationFile.ReadLenZString(aStream: TMemoryStream): AnsiString;\nvar\n  Len: Cardinal;\nbegin\n  aStream.ReadBuffer(Len, 4);\n  Dec(Len); // trailing null\n  SetLength(Result, Len);\n  if Len > 0 then\n    aStream.ReadBuffer(Result[1], Len);\nend;\n\nprocedure TwbLocalizationFile.WriteZString(aStream: TMemoryStream; aString: AnsiString);\nconst\n  z: Byte = 0;\nbegin\n  aStream.WriteBuffer(aString[1], Length(aString));\n  aStream.WriteBuffer(z, SizeOf(z));\nend;\n\nprocedure TwbLocalizationFile.WriteLenZString(aStream: TMemoryStream; aString: AnsiString);\nconst\n  z: Byte = 0;\nvar\n  l: Cardinal;\nbegin\n  l := Length(aString) + SizeOf(z);\n  aStream.WriteBuffer(l, SizeOf(Cardinal));\n  aStream.WriteBuffer(aString[1], Length(aString));\n  aStream.WriteBuffer(z, SizeOf(z));\nend;\n\nprocedure TwbLocalizationFile.ReadDirectory(aStream: TMemoryStream);\nvar\n  i: integer;\n  scount, id, offset: Cardinal;\n  oldPos: int64;\n  s: AnsiString;\nbegin\n  if aStream.Size < 8 then\n    Exit;\n\n  aStream.Read(scount, 4); // number of strings\n  aStream.Position := aStream.Position + 4; // skip dataSize\n  if scount > 0 then\n    for i := 0 to scount - 1 do begin\n      aStream.Read(id, 4); // string ID\n      aStream.Read(offset, 4); // offset of string relative to data (header + dirsize)\n      oldPos := aStream.Position;\n      aStream.Position := 8 + scount*8 + offset; // header + dirsize + offset\n      if fFileType = lsString then\n        s := ReadZString(aStream)\n      else\n        s := ReadLenZString(aStream);\n      fStrings.AddObject(wbAnsiToString(s, nil), pointer(id));\n      if Succ(id) > fNextID then\n        fNextID := Succ(id);\n      aStream.Position := oldPos;\n    end;\nend;\n\nprocedure TwbLocalizationFile.WriteToStream(const aStream: TStream);\nvar\n  dir, data: TMemoryStream;\n  i: integer;\n  c: Cardinal;\nbegin\n  dir := TMemoryStream.Create;\n  data := TMemoryStream.Create;\n  c := fStrings.Count;\n  dir.WriteBuffer(c, SizeOf(c)); // number of strings\n  dir.WriteBuffer(c, SizeOf(c)); // dataSize, will overwrite later\n  try\n    for i := 0 to Pred(fStrings.Count) do begin\n      c := Cardinal(fStrings.Objects[i]);\n      dir.WriteBuffer(c, SizeOf(c)); // ID\n      c := data.Position;\n      dir.WriteBuffer(c, SizeOf(c)); // relative position\n      if fFileType = lsString then\n        WriteZString(data, wbStringToAnsi(fStrings[i], nil))\n      else\n        WriteLenZString(data, wbStringToAnsi(fStrings[i], nil));\n    end;\n    c := data.Size;\n    dir.Position := 4;\n    dir.WriteBuffer(c, SizeOf(c)); // dataSize\n\n    aStream.CopyFrom(dir, 0);\n    aStream.CopyFrom(data, 0);\n  finally\n    FreeAndNil(dir);\n    FreeAndNil(data);\n  end;\nend;\n\nfunction TwbLocalizationFile.Count: Integer;\nbegin\n  Result := fStrings.Count;\nend;\n\nfunction TwbLocalizationFile.IndexToID(Index: Integer): Cardinal;\nbegin\n  if Index < Count then\n    Result := Cardinal(fStrings.Objects[Index])\n  else\n    Result := 0;\nend;\n\nfunction TwbLocalizationFile.IDExists(ID: Cardinal): boolean;\nbegin\n  Result := fStrings.IndexOfObject(Pointer(ID)) <> -1;\nend;\n\nfunction TwbLocalizationFile.Get(Index: Cardinal): string;\nvar\n  idx: integer;\nbegin\n  Result := '';\n  idx := fStrings.IndexOfObject(Pointer(Index));\n  if idx <> -1 then\n    Result := fStrings[idx]\n  else\n    Result := '<Error: Unknown lstring ID ' + IntToHex(Index, 8) + '>';\nend;\n\nprocedure TwbLocalizationFile.Put(Index: Cardinal; const S: string);\nvar\n  idx: integer;\nbegin\n  idx := fStrings.IndexOfObject(Pointer(Index));\n  if idx <> -1 then\n    if fStrings[idx] <> S then begin\n      fStrings[idx] := S;\n      fModified := true;\n    end;\nend;\n\nfunction TwbLocalizationFile.AddString(ID: Integer; const S: string): boolean;\nbegin\n  Result := false;\n  if ID < NextID then\n    Exit;\n\n  fStrings.AddObject(S, Pointer(ID));\n  fNextID := Succ(ID);\n  fModified := true;\n\n  Result := true;\nend;\n\nprocedure TwbLocalizationFile.ExportToFile(const aFileName: string);\nvar\n  i: integer;\n  sl: TStringList;\nbegin\n  sl := TStringList.Create;\n  try\n    for i := 0 to Pred(fStrings.Count) do begin\n      sl.Add('[' + IntToHex(Integer(fStrings.Objects[i]), 8) + ']');\n      sl.Add(fStrings[i]);\n    end;\n    sl.SaveToFile(aFileName);\n  finally\n    FreeAndNil(sl);\n  end;\nend;\n\nconstructor TwbLocalizationHandler.Create;\nbegin\n  lFiles := TwbFastStringListCS.CreateSorted;\n  fReuseDup := false;\n  NoTranslate := false;\nend;\n\ndestructor TwbLocalizationHandler.Destroy;\nbegin\n  Clear;\n  FreeAndNil(lFiles);\nend;\n\nfunction TwbLocalizationHandler.Count: Integer;\nbegin\n  Result := lFiles.Count;\nend;\n\nprocedure TwbLocalizationHandler.Clear;\nvar\n  i: integer;\nbegin\n  for i := 0 to Pred(Count) do\n    _Files[i].Destroy;\n  lFiles.Clear;\nend;\n\nfunction TwbLocalizationHandler.Get(Index: Integer): TwbLocalizationFile;\nbegin\n  if Index < Count then\n    Result := TwbLocalizationFile(lFiles.Objects[Index])\n  else\n    Result := nil;\nend;\n\nfunction TwbLocalizationHandler.AddLocalization(const aFileName: string): TwbLocalizationFile;\nbegin\n  Result := TwbLocalizationFile.Create(aFileName);\n  lFiles.AddObject(ExtractFileName(aFileName), Result);\nend;\n\nfunction TwbLocalizationHandler.AddLocalization(const aFileName: string; aData: TBytes): TwbLocalizationFile;\nbegin\n  Result := TwbLocalizationFile.Create(aFileName, aData);\n  lFiles.AddObject(ExtractFileName(aFileName), Result);\nend;\n\nfunction TwbLocalizationHandler.LocalizedValueDecider(aElement: IwbElement): TwbLStringType;\nvar\n  sigElement, sigRecord: TwbSignature;\n  aRecord: IwbSubRecord;\nbegin\n  if Supports(aElement, IwbSubRecord, aRecord) then\n    sigElement := aRecord.Signature\n  else\n    sigElement := '';\n\n  sigRecord := aElement.ContainingMainRecord.Signature;\n\n  if (sigRecord <> 'LSCR') and (sigElement = 'DESC') then Result := lsDLString else // DESC always from dlstrings except LSCR\n  if (sigRecord = 'QUST') and (sigElement = 'CNAM') then Result := lsDLString else // quest log entry\n  if (sigRecord = 'BOOK') and (sigElement = 'CNAM') then Result := lsDLString else // Book CNAM description\n  if (sigRecord = 'INFO') and (sigElement <> 'RNAM') then Result := lsILString else // dialog, RNAM are lsString, others lsILString\n    Result := lsString; // others\nend;\n\nfunction TwbLocalizationHandler.GetStringsPath: string;\nbegin\n  Result := wbDataPath + 'Strings\\';\nend;\n\nfunction TwbLocalizationHandler.AvailableLanguages: TStringList;\nvar\n  F: TSearchRec;\n  p: integer;\n  s: string;\nbegin\n  Result := TStringList.Create;\n  if FindFirst(StringsPath + '*.*STRINGS', faAnyFile, F) = 0 then try\n    repeat\n      s := LowerCase(ChangeFileExt(F.Name, ''));\n      p := LastDelimiter('_', s);\n      if p > 0 then begin\n        s := Copy(s, p + 1, length(s));\n        if s = '' then Continue;\n        s := AnsiUpperCase(s[1]) + Copy(s, 2, Length(s));\n        if Result.IndexOf(s) = -1 then\n          Result.Add(s);\n      end;\n    until FindNext(F) <> 0;\n  finally\n    FindClose(F);\n  end;\nend;\n\nfunction TwbLocalizationHandler.AvailableLocalizationFiles: TStringList;\nvar\n  F: TSearchRec;\nbegin\n  Result := TStringList.Create;\n  if FindFirst(StringsPath + '*.*STRINGS', faAnyFile, F) = 0 then try\n    repeat\n      Result.Add(F.Name);\n    until FindNext(F) <> 0;\n  finally\n    FindClose(F);\n  end;\nend;\n\nprocedure TwbLocalizationHandler.LoadForFile(aFileName: string);\nvar\n  ls: TwbLStringType;\n  s: string;\n  res: TDynResources;\nbegin\n  if not Assigned(wbContainerHandler) then\n    Exit;\n\n  for ls := Low(TwbLStringType) to High(TwbLStringType) do begin\n    s := wbLocalizationHandler.GetLocalizationFileNameByType(aFileName, ls);\n    if lFiles.IndexOf(ExtractFileName(s)) = -1 then begin\n      res := wbContainerHandler.OpenResource(s);\n      if length(res) > 0 then begin\n        //wbProgressCallback('[' + s + '] Loading Localization.');\n        wbLocalizationHandler.AddLocalization(wbDataPath + s, res[High(res)].GetData);\n      end;\n    end;\n  end;\nend;\n\nfunction TwbLocalizationHandler.GetLocalizationFileNameByType(aPluginFile: string; ls: TwbLStringType): string;\nbegin\n  Result := Format('%s_%s%s', [\n    ChangeFileExt(aPluginFile, ''),\n    wbLanguage,\n    wbLocalizationExtension[ls]\n  ]);\n  // relative path to Data folder\n  Result := 'Strings\\' + Result;\nend;\n\nfunction TwbLocalizationHandler.GetLocalizationFileNameByElement(aElement: IwbElement): string;\nbegin\n  Result := '';\n\n  if not Assigned(aElement) then\n    Exit;\n\n  Result := GetLocalizationFileNameByType(aElement._File.FileName, LocalizedValueDecider(aElement));\nend;\n\n// create a new lstring from aValue for aElement\nfunction TwbLocalizationHandler.AddValue(aValue: string; aElement: IwbElement): Cardinal;\nvar\n  ls: TwbLStringType;\n  FileName: string;\n  wblf: array [TwbLStringType] of TwbLocalizationFile;\n  idx: integer;\n  data: TBytes;\n  ID: Cardinal;\nbegin\n  Result := 0;\n\n  if not Assigned(aElement) then\n    Exit;\n\n  if aValue = '' then\n    Exit;\n\n  // create localization files if absent\n  try\n    ID := 1;\n    for ls := Low(TwbLStringType) to High(TwbLStringType) do begin\n      FileName := GetLocalizationFileNameByType(aElement._File.FileName, ls);\n      idx := lFiles.IndexOf(ExtractFileName(FileName));\n      if idx = -1 then begin\n        wblf[ls] := AddLocalization(wbDataPath + FileName, data);\n        wblf[ls].Modified := true;\n      end else\n        wblf[ls] := _Files[idx];\n\n      if wblf[ls].NextID > ID then\n        ID := wblf[ls].NextID;\n    end;\n\n    ls := LocalizedValueDecider(aElement);\n\n    // detect a duplicate string\n    if ReuseDup then begin\n      idx := wblf[ls].fStrings.IndexOf(aValue);\n      if idx <> -1 then ID := Cardinal(wblf[ls].fStrings.Objects[idx]) else\n        wblf[ls].AddString(ID, aValue);\n    end else\n      wblf[ls].AddString(ID, aValue);\n\n    Result := ID;\n  finally\n\n  end;\nend;\n\nfunction TwbLocalizationHandler.SetValue(ID: Cardinal; aElement: IwbElement; aValue: string): Cardinal;\nvar\n  idx: integer;\n  FileName: string;\nbegin\n  Result := ID;\n\n  if not Assigned(aElement) then\n    Exit;\n\n  FileName := GetLocalizationFileNameByElement(aElement);\n  idx := lFiles.IndexOf(ExtractFileName(FileName));\n\n  if (idx = -1) or (ID = 0) then begin\n    // new string\n    Result := AddValue(aValue, aElement);\n    Exit;\n  end;\n\n  if not _Files[idx].IDExists(ID) then\n    // string doesn't exist, create new\n    Result := AddValue(aValue, aElement)\n  else\n    // modify existing\n    _Files[idx][ID] := aValue;\nend;\n\n\nfunction TwbLocalizationHandler.GetValue(ID: Cardinal; aElement: IwbElement): string;\nvar\n  lFileName: string;\n  idx: integer;\nbegin\n  Result := '';\n\n  if NoTranslate then begin\n    Result := IntToHex(ID, 8);\n    Exit;\n  end;\n\n  if ID = 0 then\n    Exit;\n\n  lFileName := ExtractFileName(GetLocalizationFileNameByElement(aElement));\n\n  if lFileName = '' then\n    Exit;\n\n  idx := lFiles.IndexOf(lFileName);\n\n  // load strings files if absent\n  if idx = - 1 then\n    LoadForFile(aElement._File.FileName);\n\n  // get file again\n  idx := lFiles.IndexOf(lFileName);\n  if idx = - 1 then begin\n    Result := '<Error: No strings file for lstring ID ' + IntToHex(ID, 8) + '>';\n    Exit;\n  end;\n\n  Result := _Files[idx][ID];\nend;\n\nprocedure TwbLocalizationHandler.GetStringsFromFile(aFileName: string; const aList: TStrings);\nvar\n  i: integer;\nbegin\n  if not Assigned(aList) then\n    Exit;\n\n  for i := 0 to Pred(lFiles.Count) do\n    if SameText(lFiles[i], aFileName) then begin\n      aList.Assign(_Files[i].fStrings);\n      Break;\n    end;\nend;\n\n\ninitialization\n  wbLocalizationHandler := TwbLocalizationHandler.Create;\nfinalization\n  FreeAndNil(wbLocalizationHandler);\nend.\n"
  },
  {
    "path": "lib/xedit/wbSort.pas",
    "content": "{*******************************************************************************\n\n     The contents of this file are subject to the Mozilla Public License\n     Version 1.1 (the \"License\"); you may not use this file except in\n     compliance with the License. You may obtain a copy of the License at\n     http://www.mozilla.org/MPL/\n\n     Software distributed under the License is distributed on an \"AS IS\"\n     basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the\n     License for the specific language governing rights and limitations\n     under the License.\n\n*******************************************************************************}\nunit wbSort;\n\n{$I wbDefines.inc}\n\ninterface\n\nuses\n  Classes, wbInterface;\n\nprocedure wbMergeSort(aList: Pointer; aCount: Integer; aCompare: TListSortCompare);\n\nimplementation\n\ntype\n  TwbMove = procedure(const Source; var Dest; Count : Integer);\n\nvar\n  wbMove    : TwbMove = nil;\n\nconst\n  // x64 - use InsertionSort instead MergeSort for small arrays\n  MIN_SIZE = 32;\n\n{$IFDEF WIN32}\nfunction wbMergeSortInternal(_A, _B: PwbPointerArray; _Count : Integer; _Compare: TListSortCompare): PwbPointerArray; register;\nconst\n  SizeOfPointer  = SizeOf(Pointer);\n  SizeOf2Pointer  = 2 * SizeOf(Pointer);\n\n  EspOffset      =  $38;\n\n  A              = EspOffset - SizeOfPointer * 1;\n  B              = EspOffset - SizeOfPointer * 2;\n  Compare        = EspOffset+$08; //sometimes ebp\n\n  Temp           = EspOffset - SizeOfPointer * 3;\n\n  Count          = EspOffset - SizeOfPointer * 4;\n  SegmentSize    = EspOffset - SizeOfPointer * 5;\n\n  Temp2          = EspOffset - SizeOfPointer * 6;\n\n  pRightEnd      = EspOffset - SizeOfPointer * 7;\n  pLeftEnd       = EspOffset - SizeOfPointer * 8;\n\n  pListEnd       = EspOffset - SizeOfPointer * 9;\n\n  pNextLeft      = EspOffset - SizeOfPointer * 10;\n  SavedCompares  = EspOffset - SizeOfPointer * 11;\nasm\n  { begin }\n        sub    esp, EspOffset\n        mov    [esp + 00], edi\n        mov    [esp + 08], esi\n        mov    [esp + 04], ebx\n\n        mov    [esp+Count], ecx\n        mov    [esp+B], edx\n        mov    [esp+A], eax\n\n  {======== first run =========================================================}\n        xor    ebp, ebp\n\n  { pBuffer := @b; }\n        mov    edi, [esp+B]\n  { pLeft := @a; }\n        mov    esi, [esp+A]\n  { pListEnd := @a[Pred(Count)]; }\n        mov    ebx, [esp+Count]\n        dec    ebx\n        lea    ebx, [esi+ebx*SizeOfPointer]\n\n        mov    dword ptr [esp+Temp], 0\n\n        jmp   @@FirstRun_CompareLoop\n\n        nop\n        nop\n        nop\n        nop\n        nop\n        nop\n        nop\n\n  @@FirstRun_CompareLoop:\n  { if Compare(pLeft^, pRight^) <= 0 then begin }\n        mov    eax, [esi]\n        mov    edx, [esi + SizeOfPointer]\n        call   [esp+Compare]\n        test   eax, eax\n        jg    @@FirstRun_MergeFromRight\n        jl    @@FirstRun_MergeFromLeft\n        add    dword ptr [esp+Temp], 1\n        jmp   @@FirstRun_MergeFromLeft\n\n        nop\n        nop\n        nop\n        nop\n        nop\n        nop\n        nop\n        nop\n        nop\n        nop\n\n  @@FirstRun_MergeFromLeft:\n  { pBuffer^ := pLeft^; }\n        mov    eax, [esi]\n        mov    [edi], eax\n  { pBuffer+1^ := pLeft+1^; }\n        mov    eax, [esi + SizeOfPointer]\n        mov    [edi + SizeOfPointer], eax\n  { Inc(pBuffer, 2); }\n        add    edi, SizeOf2Pointer\n  { Inc(pLeft, 2); }\n        add    esi, SizeOf2Pointer\n\n  { until pLeft+1 >= pListEnd }\n        cmp    esi, ebx\n        jb    @@FirstRun_CompareLoop\n        ja    @@FirstRun_NoRemaining\n        jmp   @@FirstRun_CopyRemaining\n\n        nop\n        nop\n        nop\n        nop\n        nop\n        nop\n        nop\n        nop\n\n  @@FirstRun_MergeFromRight:\n        lea    ebp, [ebp +1]\n  { pBuffer+1^ := pLeft^; }\n        mov    eax, [esi]\n        mov    [edi + SizeOfPointer], eax\n  { pBuffer^ := pLeft+1^; }\n        mov    eax, [esi + SizeOfPointer]\n        mov    [edi], eax\n  { Inc(pBuffer, 2); }\n        add    edi, SizeOf2Pointer\n  { Inc(pLeft, 2); }\n        add    esi, SizeOf2Pointer\n\n  { until pLeft+1 >= pListEnd }\n        cmp    esi, ebx\n        jb    @@FirstRun_CompareLoop\n        ja    @@FirstRun_NoRemaining\n\n   @@FirstRun_CopyRemaining:\n  { pBuffer^ := pLeft^; }\n        mov    eax, [esi]\n        mov    [edi], eax\n\n        nop\n        nop\n        nop\n\n   @@FirstRun_NoRemaining:\n        mov    edx, ebp\n        mov    ebp, [esp+Compare]\n\n        { if never merged from left... }\n        test   edx, edx\n        jz    @@ShortCutFwd_Entry\n\n        { if always merged from right... }\n        mov    eax, [esp+Count]\n        shr    eax, 1\n        add    edx, [esp+Temp]\n        cmp    edx, eax\n        je    @@ShortCutBwd_Entry\n\n  { T := A; }\n        mov    eax, [esp+A]\n  { A := B; }\n        mov    edx, [esp+B]\n        mov    [esp+A], edx\n  { B := T; }\n        mov    [esp+B], eax\n\n        jmp   @@SmallRuns_Entry\n\n  {======== shortcut forward run ==============================================}\n        nop\n        nop\n        nop\n\n  @@ShortCutFwd_Entry:\n  { pLeft := @a; }\n        mov    esi, [esp+A]\n  { pListEnd := @a[Pred(Count)]; - still valid}\n\n  { skip first element }\n        add    esi, SizeOfPointer\n\n        cmp    esi, ebx\n        jae   @@Exit\n\n        nop\n\n  @@ShortCutFwd_CompareLoop:\n  { if Compare(pLeft^, pRight^) <= 0 then begin }\n        mov    eax, [esi]\n        mov    edx, [esi + SizeOfPointer]\n        call   ebp\n        test   eax, eax\n  { if any element didn't fit, do a full merge }\n        jg    @@SmallRuns_Entry\n\n  { Inc(pLeft, 2); }\n        add    esi, SizeOf2Pointer\n\n  { until pLeft+1 >= pListEnd }\n        cmp    esi, ebx\n        jb    @@ShortCutFwd_CompareLoop\n        jmp   @@Exit\n\n  {======== shortcut forward run ==============================================}\n\n        nop\n        nop\n        nop\n        nop\n        nop\n\n  @@ShortCutBwd_Entry:\n        mov    esi, [esp+A]\n        mov    ebx, [esp + Count]\n        cmp    ebx, 2\n        je    @@ShortCutBwd_ExchangeLoop_Entry\n\n        sub    ebx, 3\n        or     ebx, 1\n        lea    ebx, [esi + ebx * 4]\n\n        cmp    esi, ebx\n        jae   @@Exit\n\n        nop\n        nop\n\n  @@ShortCutBwd_CompareLoop:\n  { if Compare(pLeft^, pRight^) <= 0 then begin }\n        mov    eax, [ebx]\n        mov    edx, [ebx + SizeOfPointer]\n        call   ebp\n        test   eax, eax\n  { if any element didn't fit, do a full merge }\n        jl    @@ShortCutBwd_Error\n\n  { Inc(pLeft, 2); }\n        sub    ebx, SizeOf2Pointer\n\n  { until pLeft+1 >= pListEnd }\n        cmp    esi, ebx\n        jb    @@ShortCutBwd_CompareLoop\n\n  @@ShortCutBwd_ExchangeLoop_Entry:\n        mov    esi, [esp+A]\n        mov    ebx, [esp + Count]\n        sub    ebx, 1\n        lea    ebx, [esi + ebx * 4]\n\n  @@ShortCutBwd_ExchangeLoop:\n        mov    eax, [esi]\n        mov    edx, [ebx]\n        mov    [ebx], eax\n        mov    [esi], edx\n\n        add    esi, SizeOfPointer\n        sub    ebx, SizeOfPointer\n\n        cmp    esi, ebx\n        jb    @@ShortCutBwd_ExchangeLoop\n\n        jmp   @@Exit\n\n        nop\n        nop\n        nop\n        nop\n        nop\n        nop\n        nop\n        nop\n        nop\n\n  @@ShortCutBwd_Error:\n\n  { T := A; }\n        mov    eax, [esp+A]\n  { A := B; }\n        mov    edx, [esp+B]\n        mov    [esp+A], edx\n  { B := T; }\n        mov    [esp+B], eax\n\n        jmp   @@SmallRuns_Entry\n\n  {======== small runs ====================================================}\n        nop\n        nop\n        nop\n        nop\n        nop\n        nop\n        nop\n        nop\n        nop\n        nop\n        nop\n        nop\n        nop\n        nop\n\n  @@SmallRuns_Entry:\n  { SegmentSize := 2; }\n        mov    eax, 2\n        mov    dword ptr [esp+SegmentSize], eax\n\n        nop\n        nop\n        nop\n        nop\n        nop\n        nop\n        nop\n  @@SmallRuns_OuterLoop_Entry:\n        mov    ebp, [esp + Compare]\n  @@SmallRuns_OuterLoop:  // requires SegmentSize in eax\n  { pBuffer := @b; }\n        mov    edi, [esp+B]\n  { pLeft := @a; }\n        mov    esi, [esp+A]\n  { pRight := @a[SegmentSize]; }\n        lea    ebx, [esi+eax*SizeOfPointer]\n  { pLeftEnd := pRight; }\n        mov    [esp+pLeftEnd], ebx\n  { pListEnd := @a[Count]; }\n        mov    edx, [esp+Count]\n        lea    edx, [esi+ edx*SizeOfPointer]\n        mov    [esp+pListEnd], edx\n  { pRightEnd := @a[SegmentSize + SegmentSize]; }\n        lea    eax, [ebx+eax*SizeOfPointer]\n        mov    [esp+pRightEnd], eax\n\n        jmp   @@SmallRuns_InnerLoopEntry //requires pRightEnd in eax and pListEnd in edx\n\n        nop\n        nop\n        nop\n        nop\n        nop\n        nop\n        nop\n        nop\n        nop\n\n  @@SmallRuns_InnerLoopSetRightEnd:\n  { pRightEnd := pListEnd; }\n        mov    [esp+pRightEnd], edx\n\n  @@SmallRuns_InnerLoop:\n  @@SmallRuns_CompareLoop:\n  { if Compare(pLeft^, pRight^) <= 0 then begin }\n        mov    edx, [ebx]\n        mov    eax, [esi]\n        call   ebp\n        test   eax, eax\n        jg    @@SmallRuns_MergeFromRight\n\n  @@SmallRuns_MergeFromLeft:\n  { pBuffer^ := pLeft^; }\n        mov    eax, [esi]\n        mov    [edi], eax\n  { Inc(pBuffer); }\n        add    edi, SizeOfPointer\n  { Inc(pLeft); }\n        add    esi, SizeOfPointer\n  { if Cardinal(pLeft) >= Cardinal(pLeftEnd) then begin }\n        cmp    esi, [esp+pLeftEnd]\n        jb    @@SmallRuns_CompareLoop\n\n        nop\n        nop\n\n  @@SmallRuns_CopyRemainingFromRight_Entry:\n        mov    edx, [esp+pRightEnd] //used in CopyRemainingFromRight\n  @@SmallRuns_CopyRemainingFromRight:\n  { pBuffer^ := pRight^; }\n        mov    eax, [ebx]\n        mov    [edi], eax\n  { Inc(pBuffer); }\n        add    edi, SizeOfPointer\n  { Inc(pRight); }\n        add    ebx, SizeOfPointer\n  { while Cardinal(pRight) < Cardinal(pRightEnd) do begin }\n        cmp    ebx, edx\n        jb    @@SmallRuns_CopyRemainingFromRight\n  { Break; }\n        jmp   @@SmallRuns_BreakOutOfCompareLoop\n\n  @@SmallRuns_MergeBoth:\n  { pBuffer^ := pRight^; }\n        mov    eax, [esi]\n        mov    [edi], eax\n        mov    eax, [ebx]\n        mov    [edi + SizeOfPointer], eax\n  { Inc(pBuffer); }\n        add    edi, SizeOf2Pointer\n  { Inc(pRight); }\n        add    ebx, SizeOfPointer\n        add    esi, SizeOfPointer\n\n        cmp    esi, [esp+pLeftEnd]\n        jae   @@SmallRuns_LeftDone\n\n        cmp    ebx, [esp+pRightEnd]\n        jb    @@SmallRuns_CompareLoop\n        jmp   @@SmallRuns_CopyRemainingFromLeft_Entry\n\n  @@SmallRuns_LeftDone:\n        cmp    ebx, [esp+pRightEnd]\n        jb    @@SmallRuns_CopyRemainingFromRight_Entry\n        jmp   @@SmallRuns_BreakOutOfCompareLoop\n\n  @@SmallRuns_MergeFromRight:\n  { pBuffer^ := pRight^; }\n        mov    eax, [ebx]\n        mov    [edi], eax\n  { Inc(pBuffer); }\n        add    edi, SizeOfPointer\n  { Inc(pRight); }\n        add    ebx, SizeOfPointer\n  { if Cardinal(pRight) >= Cardinal(pRightEnd) then begin }\n        cmp    ebx, [esp+pRightEnd]\n        jb    @@SmallRuns_CompareLoop\n\n  @@SmallRuns_CopyRemainingFromLeft_Entry:\n        mov    edx, [esp+pLeftEnd] // used in CopyRemainingFromLeft\n  @@SmallRuns_CopyRemainingFromLeft:\n\n  { pBuffer^ := pLeft^; }\n        mov    eax, [esi]\n        mov    [edi], eax\n  { Inc(pBuffer); }\n        add    edi, SizeOfPointer\n  { Inc(pLeft); }\n        add    esi, SizeOfPointer\n  { while Cardinal(pLeft) < Cardinal(pLeftEnd) do begin }\n        cmp    esi, edx\n        jb @@SmallRuns_CopyRemainingFromLeft\n\n  @@SmallRuns_BreakOutOfCompareLoop:\n  { Inc(pLeft, SegmentSize); }\n        mov    eax, [esp+SegmentSize]\n        shl    eax, 02h\n        add    esi, eax\n  { Inc(pRight, SegmentSize); }\n        add    ebx, eax\n  { pLeftEnd := pRight; }\n        mov    [esp+pLeftEnd], ebx\n  { Inc(pRightEnd, SegmentSize + SegmentSize); }\n        lea    eax, [ebx + eax]\n        mov    [esp+pRightEnd], eax\n\n        mov    edx, [esp+pListEnd]\n  @@SmallRuns_InnerLoopEntry: //requires pRightEnd in eax and pListEnd in edx\n  { while Cardinal(pRightEnd) <= Cardinal(pListEnd) do begin }\n        cmp    eax, edx\n        jbe   @@SmallRuns_InnerLoop\n\n  { if Cardinal(pLeft) < Cardinal(pListEnd) then begin }\n        cmp    edx, esi\n        jbe   @@SmallRuns_NoRemaining\n  { if Cardinal(pRight) < Cardinal(pListEnd) then begin }\n        cmp    edx, ebx\n        ja    @@SmallRuns_InnerLoopSetRightEnd\n\n  @@SmallRuns_CopyRemaining:\n\n  { pBuffer^ := pLeft^; }\n        mov    eax, [esi]\n        mov    [edi], eax\n  { Inc(pBuffer); }\n        add    edi, SizeOfPointer\n  { Inc(pLeft); }\n        add    esi, SizeOfPointer\n  { while Cardinal(pLeft) < Cardinal(pListEnd) do begin }\n        cmp    esi, edx\n        jb    @@SmallRuns_CopyRemaining\n\n  @@SmallRuns_NoRemaining:\n  { T := A; }\n        mov    eax, [esp+A]\n  { A := B; }\n        mov    edx, [esp+B]\n        mov    [esp+A], edx\n  { B := T; }\n        mov    [esp+B], eax\n  { SegmentSize := SegmentSize shl 1; }\n        mov    eax, [esp+SegmentSize]\n        shl    eax, 1\n        mov    [esp+SegmentSize], eax\n  { while SegmentSize < Count do begin }\n        cmp    eax, [esp+Count]\n        jge   @@Exit\n\n        cmp    eax, 128\n        jne   @@SmallRuns_OuterLoop // requires SegmentSize in eax\n\n  {======== large runs ====================================================}\n  @@LargeRuns_OuterLoop:  // requires SegmentSize in eax\n  { pBuffer := @b; }\n        mov    edi, [esp+B]\n  { pLeft := @a; }\n        mov    esi, [esp+A]\n  { pRight := @a[SegmentSize]; }\n        lea    ebx, [esi+eax*SizeOfPointer]\n  { pLeftEnd := pRight; }\n        mov    [esp+pLeftEnd], ebx\n  { pListEnd := @a[Count]; }\n        mov    edx, [esp+Count]\n        lea    edx, [esi+ edx*SizeOfPointer]\n        mov    [esp+pListEnd], edx\n  { pRightEnd := @a[SegmentSize + SegmentSize]; }\n        lea    eax, [ebx+eax*SizeOfPointer]\n        mov    [esp+pRightEnd], eax\n        mov    [esp+pNextLeft], eax\n\n        mov    [esp+SavedCompares], 0\n\n        jmp   @@LargeRuns_InnerLoopEntry //requires pRightEnd in eax and pListEnd in edx\n\n        nop\n        nop\n        nop\n\n  @@LargeRuns_InnerLoopSetRightEnd:\n  { pRightEnd := pListEnd; }\n        mov    [esp+pRightEnd], edx\n        mov    [esp+pNextLeft], edx\n\n  @@LargeRuns_InnerLoop:\n\n  { Compare(pLeft^, pRight^) }\n        mov    edx, [ebx]\n        mov    eax, [esi]\n        call   [esp+Compare]\n        test   eax, eax\n  { if equal -> perfect overlap, copy both, no need to waste a comparison... }\n        je    @@LargeRuns_CopyBoth\n\n        mov    edx, [esp+pLeftEnd]\n        jl    @@LargeRuns_MoveFromLeft // requires LeftEnd in edx\n\n  @@LargeRuns_SwitchLeftAndRight:\n\n  { if greater -> right one is smaller }\n\n  { move it over to the buffer, no need to waste a comparison}\n        mov    ecx, [ebx]\n        mov    [edi], ecx\n        add    ebx, SizeOfPointer\n        add    edi, SizeOfPointer\n\n  { switch left and right }\n        xchg   ebx, esi\n\n        mov    eax, [esp+pRightEnd]\n        mov    [esp+pLeftEnd], eax\n        mov    [esp+pRightEnd], edx\n\n  { if we reached the end, copy the rest }\n        cmp    esi, eax\n        jae   @@LargeRuns_CopyRemainingFromRight_Entry\n\n        mov    edx, eax\n        jmp   @@LargeRuns_CompareLeftEndAndRight\n\n        nop\n        nop\n        nop\n        nop\n        nop\n        nop\n        nop\n        nop\n        nop\n        nop\n        nop\n        nop\n        nop\n        nop\n\n  @@LargeRuns_MoveFromLeft: // requires LeftEnd in edx\n\n  { if lesser -> left one is smaller}\n\n  { move it over to the buffer, no need to waste a comparison}\n        mov    ecx, [esi]\n        mov    [edi], ecx\n        add    esi, SizeOfPointer\n        add    edi, SizeOfPointer\n\n  { if we reached the end, copy the rest }\n        cmp    esi, edx{LeftEnd}\n        jae   @@LargeRuns_CopyRemainingFromRight_Entry\n\n  @@LargeRuns_CompareLeftEndAndRight: // requires LeftEnd in edx\n\n        sub    edx, SizeOfPointer\n        mov    eax, [edx]\n        mov    edx, [ebx]\n        call   [esp+Compare]\n        test   eax, eax\n        jg    @@LargeRuns_BinarySearchLeft_Entry\n\n  { LeftEnd <= Right, no need to continue merging, just copy and get out of here }\n\n  { first copy just left }\n        mov    eax, esi\n        mov    edx, edi\n        mov    ecx, [esp+pLeftEnd]\n        sub    ecx, eax\n        add    edi, ecx\n        add    [esp+SavedCompares], ecx\n        call   [wbMove]\n\n  { then copy just right }\n        mov    eax, ebx\n        mov    edx, edi\n        mov    ecx, [esp+pRightEnd]\n        sub    ecx, eax\n        add    edi, ecx\n        add    [esp+SavedCompares], ecx\n        call   [wbMove]\n\n  { we are done here }\n        jmp   @@LargeRuns_BreakOutOfCompareLoop\n\n        nop\n        nop\n        nop\n        nop\n        nop\n        nop\n\n  @@LargeRuns_CopyBoth:\n        mov    eax, [ebx]\n        mov    [edi], eax\n        mov    eax, [esi]\n        mov    [edi + SizeOfPointer], eax\n\n        add    ebx, SizeOfPointer\n        add    esi, SizeOfPointer\n        add    edi, SizeOf2Pointer\n\n        cmp    esi, [esp+pLeftEnd]\n        jae   @@LargeRuns_CopyRemainingFromRight_Entry\n        cmp    ebx, [esp+pRightEnd]\n        jae   @@LargeRuns_CopyRemainingFromLeft_Entry\n\n        jmp   @@LargeRuns_InnerLoop\n\n        nop\n        nop\n        nop\n        nop\n        nop\n\n  @@LargeRuns_BinarySearchLeft_Entry:\n  { save our old Left }\n        mov    [esp+Temp], esi\n  { save our old Buffer }\n        mov    [esp+Temp2], edi\n\n        mov    edi, [esp+pLeftEnd]\n        sub    edi, SizeOfPointer\n\n  { we start with esi = Low and edi = High}\n\n        nop\n\n  @@LargeRuns_BinarySearchLeft_Loop:\n  { calculate the middle into ebp }\n        mov    ebp, edi\n        sub    ebp, esi\n        shr    ebp, 3\n\n        lea    ebp, [esi + ebp *4];\n\n  { compare middle with Right}\n        mov    eax, [ebp]\n        mov    edx, [ebx]\n        sub    [esp+SavedCompares], 4\n        call   [esp+Compare]\n        test   eax, eax\n        jg    @@LargeRuns_BinarySearchLeft_Greater\n\n  @@LargeRuns_BinarySearchLeft_LesserOrEqual:\n  { move the lower bound }\n        lea    esi, [ebp + SizeOfPointer]\n\n        cmp    esi, edi\n        jbe   @@LargeRuns_BinarySearchLeft_Loop\n        jmp   @@LargeRuns_BinarySearchLeft_Exit\n\n  @@LargeRuns_BinarySearchLeft_Greater:\n  { mov the higher bound }\n        lea    edi, [ebp - SizeOfPointer]\n\n        cmp    esi, edi\n        jbe   @@LargeRuns_BinarySearchLeft_Loop\n        jmp   @@LargeRuns_BinarySearchLeft_Exit\n\n        nop\n        nop\n        nop\n        nop\n        nop\n        nop\n        nop\n\n  @@LargeRuns_BinarySearchLeft_Exit:\n  { edi is pointing to the last entry that's <= Right }\n\n  { get our old left }\n        mov    esi, [esp+Temp]\n        mov    edx, edi\n  { restore Buffer}\n        mov    edi, [esp+Temp2]\n        jmp   @@LargeRuns_BinarySearchLeft_CopyLeadingLeft_Entry\n\n        nop\n        nop\n        nop\n        nop\n\n  @@LargeRuns_BinarySearchLeft_CopyLeadingLeft_Loop:\n  { pBuffer^ := pLeft^; }\n        mov    eax, [esi]\n        mov    [edi], eax\n  { Inc(pBuffer); }\n        add    edi, SizeOfPointer\n  { Inc(pLeft); }\n        add    esi, SizeOfPointer\n        add    [esp+SavedCompares], 4\n  { while Cardinal(pLeft) <= FoundItem do begin }\n  @@LargeRuns_BinarySearchLeft_CopyLeadingLeft_Entry:\n        cmp    esi, edx\n        jbe @@LargeRuns_BinarySearchLeft_CopyLeadingLeft_Loop\n\n  { we've copied all entries from Left that where <= Right }\n\n  { are we done with Left? }\n        cmp    esi, [esp+pLeftEnd]\n        jae   @@LargeRuns_CopyRemainingFromRight_Entry\n\n  { pBuffer^ := pRight^; }\n        mov    eax, [ebx]\n        mov    [edi], eax\n  { Inc(pBuffer); }\n        add    edi, SizeOfPointer\n  { Inc(pRight); }\n        add    ebx, SizeOfPointer\n\n  { are we done with Right? }\n        cmp    ebx, [esp+pRightEnd]\n        jae   @@LargeRuns_CopyRemainingFromLeft_Entry\n\n  { now we can start with the normal compare loop}\n        mov    ebp, [esp+Compare]\n\n        jmp   @@LargeRuns_CompareLoop\n\n        nop\n        nop\n        nop\n        nop\n        nop\n        nop\n\n  @@LargeRuns_CompareLoop:\n  { if Compare(pLeft^, pRight^) <= 0 then begin }\n        mov    edx, [ebx]\n        mov    eax, [esi]\n        call   ebp\n        test   eax, eax\n        jg    @@LargeRuns_MergeFromRight\n\n  @@LargeRuns_MergeFromLeft:\n  { pBuffer^ := pLeft^; }\n        mov    eax, [esi]\n        mov    [edi], eax\n  { Inc(pBuffer); }\n        add    edi, SizeOfPointer\n  { Inc(pLeft); }\n        add    esi, SizeOfPointer\n  { if Cardinal(pLeft) >= Cardinal(pLeftEnd) then begin }\n        cmp    esi, [esp+pLeftEnd]\n        jb    @@LargeRuns_CompareLoop\n\n        nop\n        nop\n\n  @@LargeRuns_CopyRemainingFromRight_Entry:\n        mov    edx, [esp+pRightEnd] //used in CopyRemainingFromRight\n  @@LargeRuns_CopyRemainingFromRight:\n  { pBuffer^ := pRight^; }\n        mov    eax, [ebx]\n        mov    [edi], eax\n  { Inc(pBuffer); }\n        add    edi, SizeOfPointer\n  { Inc(pRight); }\n        add    ebx, SizeOfPointer\n  { while Cardinal(pRight) < Cardinal(pRightEnd) do begin }\n        cmp    ebx, edx\n        jb    @@LargeRuns_CopyRemainingFromRight\n  { Break; }\n        jmp   @@LargeRuns_BreakOutOfCompareLoop\n\n  @@LargeRuns_MergeFromRight:\n  { pBuffer^ := pRight^; }\n        mov    eax, [ebx]\n        mov    [edi], eax\n  { Inc(pBuffer); }\n        add    edi, SizeOfPointer\n  { Inc(pRight); }\n        add    ebx, SizeOfPointer\n  { if Cardinal(pRight) >= Cardinal(pRightEnd) then begin }\n        cmp    ebx, [esp+pRightEnd]\n        jb    @@LargeRuns_CompareLoop\n\n  @@LargeRuns_CopyRemainingFromLeft_Entry:\n        mov    edx, [esp+pLeftEnd] // used in CopyRemainingFromLeft\n  @@LargeRuns_CopyRemainingFromLeft:\n\n  { pBuffer^ := pLeft^; }\n        mov    eax, [esi]\n        mov    [edi], eax\n  { Inc(pBuffer); }\n        add    edi, SizeOfPointer\n  { Inc(pLeft); }\n        add    esi, SizeOfPointer\n  { while Cardinal(pLeft) < Cardinal(pLeftEnd) do begin }\n        cmp    esi, edx\n        jb @@LargeRuns_CopyRemainingFromLeft\n\n  @@LargeRuns_BreakOutOfCompareLoop:\n  { Inc(pLeft, SegmentSize); }\n        mov    eax, [esp+SegmentSize]\n        shl    eax, 02h\n\n        mov    esi, [esp+pNextLeft]\n  { Inc(pRight, SegmentSize); }\n        lea    ebx, [esi + eax]\n  { pLeftEnd := pRight; }\n        mov    [esp+pLeftEnd], ebx\n  { Inc(pRightEnd, SegmentSize + SegmentSize); }\n        lea    eax, [ebx + eax]\n        mov    [esp+pRightEnd], eax\n        mov    [esp+pNextLeft], eax\n\n        mov    edx, [esp+pListEnd]\n  @@LargeRuns_InnerLoopEntry: //requires pRightEnd in eax and pListEnd in edx\n  { while Cardinal(pRightEnd) <= Cardinal(pListEnd) do begin }\n        cmp    eax, edx\n        jbe   @@LargeRuns_InnerLoop\n\n  { if Cardinal(pLeft) < Cardinal(pListEnd) then begin }\n        cmp    edx, esi\n        jbe   @@LargeRuns_NoRemaining\n  { if Cardinal(pRight) < Cardinal(pListEnd) then begin }\n        cmp    edx, ebx\n        ja    @@LargeRuns_InnerLoopSetRightEnd\n\n  @@LargeRuns_CopyRemaining:\n  { pBuffer^ := pLeft^; }\n        mov    eax, [esi]\n        mov    [edi], eax\n  { Inc(pBuffer); }\n        add    edi, SizeOfPointer\n  { Inc(pLeft); }\n        add    esi, SizeOfPointer\n  { while Cardinal(pLeft) < Cardinal(pListEnd) do begin }\n        cmp    esi, edx\n        jb    @@LargeRuns_CopyRemaining\n\n  @@LargeRuns_NoRemaining:\n  { T := A; }\n        mov    eax, [esp+A]\n  { A := B; }\n        mov    edx, [esp+B]\n        mov    [esp+A], edx\n  { B := T; }\n        mov    [esp+B], eax\n  { SegmentSize := SegmentSize shl 1; }\n        mov    eax, [esp+SegmentSize]\n        shl    eax, 1\n        mov    [esp+SegmentSize], eax\n  { while SegmentSize < Count do begin }\n        mov    edx, [esp+Count]\n        cmp    eax, edx\n        jge    @@Exit\n\n        cmp    [esp+SavedCompares], edx\n        jl    @@SmallRuns_OuterLoop_Entry\n\n        jmp   @@LargeRuns_OuterLoop // requires SegmentSize in eax\n\n  @@Exit:\n  { Result := A; }\n        mov    eax, [esp+A]\n\n  { end; }\n        mov    edi, [esp + 00]\n        mov    esi, [esp + 08]\n        mov    ebx, [esp + 04]\n\n        add    esp, EspOffset\nend;\n\n\nprocedure wbMergeSort(aList: Pointer; aCount: Integer; aCompare: TListSortCompare);\n\n  procedure UseStackBufferLarge;\n  var\n    Buffer: array[0..Pred(4 * 1024)] of Pointer;\n  begin\n    if wbMergeSortInternal(aList, @Buffer[0], aCount, aCompare) <> aList then\n      Move(Buffer, aList^, aCount * SizeOf(Pointer) );\n  end;\n\n  procedure UseStackBufferSmall;\n  var\n    Buffer: array[0..Pred(1024)] of Pointer;\n  begin\n    if wbMergeSortInternal(aList, @Buffer[0], aCount, aCompare) <> aList then\n      Move(Buffer, aList^, aCount * SizeOf(Pointer) );\n  end;\n\nvar\n  Buffer: Pointer;\nbegin\n  if (aCount < 2) or (not Assigned(aList)) then\n    Exit;\n\n  if aCount > 4 * 1024 then begin\n    GetMem(Buffer, aCount * SizeOf(Pointer));\n    if wbMergeSortInternal(aList, Buffer, aCount, aCompare) <> aList then\n      Move(Buffer^, aList^, aCount * SizeOf(Pointer));\n    FreeMem(Buffer);\n  end else if aCount > 1024 then\n    UseStackBufferLarge\n  else\n    UseStackBufferSmall;\n\nend;\n{$ENDIF WIN32}\n\n{$IFDEF WIN64}\nprocedure InsertionSort(aList: PwbPointerArray; left, right: integer; aCompare: TListSortCompare);\nvar\n  i: Integer;\n  j: integer;\n  temp: Pointer;\nbegin\n  for i := Succ(left) to right do begin\n    j := i;\n    temp := aList[j];\n    while (j > left) AND (aCompare(temp, aList[Pred(j)]) < 0) do begin\n      aList[j] := aList[Pred(j)];\n      dec(j);\n    end;\n    aList[j] := temp;\n end;\nend;\n\nprocedure MergeSort(ptrList: PwbPointerArray; left: Integer; right: Integer; aCompare: TListSortCompare; Buffer: PwbPointerArray);\nvar\n  i, j, k, mid, aCount: Integer;\nbegin\n  mid := (left + right) div 2;\n  if (left < mid) then begin\n    if (mid - left) <= MIN_SIZE then begin\n      InsertionSort(ptrList, left, mid, aCompare)\n    end\n    else begin\n      MergeSort(ptrList, left, mid, aCompare, Buffer);\n    end;\n  end;\n  if (succ(mid) < right) then begin\n    if (right - succ(mid)) <= MIN_SIZE then begin\n      InsertionSort(ptrList, succ(mid), right, aCompare);\n    end\n    else begin\n       MergeSort(ptrList, succ(mid), right, aCompare, Buffer);\n    end;\n  end;\n  if aCompare(ptrList[mid], ptrList[Succ(mid)]) < 0 then\n    exit;\n  aCount := succ(mid - left);\n  Move(ptrList[left], Buffer[0], aCount * SizeOf(Pointer));\n  i := 0;\n  j := succ(mid);\n  k := left;\n  while (i < aCount) and (j <= right) do begin\n    if (aCompare(Buffer[i], ptrList[j]) <= 0) then begin\n      ptrList[k] := Buffer[i];\n      inc(i);\n    end else begin\n      ptrList[k] := ptrList[j];\n      inc(j);\n    end;\n    inc(k);\n  end;\n  if (i < aCount) then begin\n    Move(Buffer[i], ptrList[k], (aCount - i) * SizeOf(Pointer));\n  end;\nend;\n\nprocedure wbMergeSort(aList: Pointer; aCount: Integer; aCompare: TListSortCompare);\nvar\n  Buffer: Pointer;\nbegin\n  if (aCount < 2) or (not Assigned(aList)) then\n    Exit;\n  if aCount <= MIN_SIZE then begin\n    InsertionSort(aList, 0, Pred(aCount), aCompare);\n  end\n  else begin\n    GetMem(Buffer, aCount * SizeOf(Pointer));\n    MergeSort(aList, 0, Pred(aCount), aCompare, Buffer);\n    FreeMem(Buffer, aCount * SizeOf(Pointer));\n  end;\nend;\n{$ENDIF WIN64}\n\ninitialization\n  wbMove := @Move;\nfinalization\nend.\n\n"
  },
  {
    "path": "lib/xedit/wbStreams.pas",
    "content": "{*******************************************************************************\n\n     The contents of this file are subject to the Mozilla Public License\n     Version 1.1 (the \"License\"); you may not use this file except in\n     compliance with the License. You may obtain a copy of the License at\n     http://www.mozilla.org/MPL/\n\n     Software distributed under the License is distributed on an \"AS IS\"\n     basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the\n     License for the specific language governing rights and limitations\n     under the License.\n\n*******************************************************************************}\n\nunit wbStreams;\n\n{$I wbDefines.inc}\n\ninterface\n\nuses\n  SysUtils, Math, Classes, Windows,\n  wbInterface;\n\ntype\n  TwbBaseCachedFileStreamClass = class of TwbBaseCachedFileStream;\n  TwbBaseCachedFileStream = class(TStream)\n  private\n    function QueryInterface(const IID: TGUID; out Obj): HResult; stdcall;\n    function _AddRef: Integer; stdcall;\n    function _Release: Integer; stdcall;\n  protected\n    FHandle: THandle;\n    FOwnsHandle: Boolean;\n    FCache: PByte;\n    FCacheSize: Integer;\n    FPosition: Int64;//the current position in the file (relative to the beginning of the file)\n    FCacheStart: Int64;//the postion in the file of the start of the cache (relative to the beginning of the file)\n    FCacheEnd: Int64;//the postion in the file of the end of the cache (relative to the beginning of the file)\n    FFileName: string;\n    FLastError: DWORD;\n    procedure HandleError(const Msg: string);\n    procedure RaiseSystemError(const Msg: string; LastError: DWORD); overload;\n    procedure RaiseSystemError(const Msg: string); overload;\n    procedure RaiseSystemErrorFmt(const Msg: string; const Args: array of const);\n    function CreateHandle(FlagsAndAttributes: DWORD): THandle; virtual; abstract;\n    function GetFileSize: Int64; virtual;\n    procedure SetSize(NewSize: Longint); override;\n    procedure SetSize(const NewSize: Int64); override;\n    function FileRead(var Buffer; Count: Longword): Integer;\n    function FileWrite(const Buffer; Count: Longword): Integer;\n    function FileSeek(const Offset: Int64; Origin: TSeekOrigin): Int64;\n  public\n    constructor Create(const FileName: string); overload;\n    constructor Create(const FileName: string; CacheSize: Integer); overload;\n    constructor Create(const FileName: string; CacheSize: Integer; Handle: THandle); overload; virtual;\n    destructor Destroy; override;\n    property CacheSize: Integer read FCacheSize;\n    function Read(var Buffer; Count: Longint): Longint; override;\n    function Write(const Buffer; Count: Longint): Longint; override;\n    function Seek(const Offset: Int64; Origin: TSeekOrigin): Int64; override;\n\n    function ReadSignature: TwbSignature; inline;\n    function ReadByte: Byte; inline;\n    function ReadWord: Word; inline;\n    function ReadCardinal: Cardinal; inline;\n    function ReadInt64: Int64; inline;\n    function ReadStringLen(Term: Boolean = True): string; inline;\n    function ReadStringLen16: string; inline;\n    function ReadStringTerm: string; inline;\n\n    procedure WriteCardinal(aCardinal: Cardinal); inline;\n    procedure WriteSmallInt(aSmallInt: SmallInt); inline;\n  end;\n\n  IDisableStreamReadCache = interface\n    ['{0B6D0004-88D1-42D5-BC0F-447911C0FC21}']\n    procedure DisableStreamReadCache;\n    procedure EnableStreamReadCache;\n  end;\n\n  TwbReadOnlyCachedFileStream = class(TwbBaseCachedFileStream, IDisableStreamReadCache)\n  (* This class works by filling the cache each time a call to Read is made and\n     FPosition is outside the existing cache.  By filling the cache we mean\n     reading from the file into the temporary cache.  Calls to Read when\n     FPosition is in the existing cache are then dealt with by filling the\n     buffer with bytes from the cache.\n  *)\n  private\n    FUseAlignedCache: Boolean;\n    FViewStart: Int64;\n    FViewLength: Int64;\n    FDisableStreamReadCacheRefCount: Integer;\n    procedure DisableStreamReadCache;\n    procedure EnableStreamReadCache;\n    procedure FlushCache;\n  protected\n    function CreateHandle(FlagsAndAttributes: DWORD): THandle; override;\n    function GetFileSize: Int64; override;\n  public\n    constructor Create(const FileName: string; CacheSize: Integer; Handle: THandle); overload; override;\n    property UseAlignedCache: Boolean read FUseAlignedCache write FUseAlignedCache;\n    function Read(var Buffer; Count: Longint): Longint; override;\n    procedure SetViewWindow(const ViewStart, ViewLength: Int64);\n  end;\n\n  TwbWriteCachedFileStream = class(TwbBaseCachedFileStream, IDisableStreamReadCache)\n  (* This class works by caching calls to Write.  By this we mean temporarily\n     storing the bytes to be written in the cache.  As each call to Write is\n     processed the cache grows.  The cache is written to file when:\n       1.  A call to Write is made when the cache is full.\n       2.  A call to Write is made and FPosition is outside the cache (this\n           must be as a result of a call to Seek).\n       3.  The class is destroyed.\n\n     Note that data can be read from these streams but the reading is not\n     cached and in fact a read operation will flush the cache before\n     attempting to read the data.\n  *)\n  private\n    FFileSize: Int64;\n    FReadStream: TwbReadOnlyCachedFileStream;\n    FReadStreamCacheSize: Integer;\n    FReadStreamUseAlignedCache: Boolean;\n    procedure DisableStreamReadCache;\n    procedure EnableStreamReadCache;\n    procedure CreateReadStream;\n    procedure FlushCache;\n  protected\n    function CreateHandle(FlagsAndAttributes: DWORD): THandle; override;\n    function GetFileSize: Int64; override;\n  public\n    constructor Create(const FileName: string; CacheSize, ReadStreamCacheSize: Integer; ReadStreamUseAlignedCache: Boolean); overload;\n    destructor Destroy; override;\n    function Read(var Buffer; Count: Longint): Longint; override;\n    function Write(const Buffer; Count: Longint): Longint; override;\n  end;\n\n  {\n  TwbFileStream = class(TFileStream)\n    function Duplicate: TwbFileStream;\n  end;\n  }\n\nimplementation\n\nfunction GetFileSizeEx(hFile: THandle; var FileSize: Int64): BOOL; stdcall; external kernel32;\nfunction SetFilePointerEx(hFile: THandle; DistanceToMove: Int64; lpNewFilePointer: PInt64; dwMoveMethod: DWORD): BOOL; stdcall; external kernel32;\n\n{ TwbBaseCachedFileStream }\n\nconstructor TwbBaseCachedFileStream.Create(const FileName: string);\nbegin\n  Create(FileName, 0);\nend;\n\nconstructor TwbBaseCachedFileStream.Create(const FileName: string; CacheSize: Integer);\nbegin\n  Create(FileName, CacheSize, 0);\nend;\n\nconstructor TwbBaseCachedFileStream.Create(const FileName: string; CacheSize: Integer; Handle: THandle);\nconst\n  DefaultCacheSize = 16*1024;\n  //16kb - this was chosen empirically - don't make it too large otherwise the progress report is 'jerky'\nbegin\n  inherited Create;\n  FFileName := FileName;\n  FOwnsHandle := Handle=0;\n  if FOwnsHandle then begin\n    FHandle := CreateHandle(FILE_ATTRIBUTE_NORMAL);\n  end else begin\n    FHandle := Handle;\n  end;\n  FCacheSize := CacheSize;\n  if FCacheSize<=0 then begin\n    FCacheSize := DefaultCacheSize;\n  end;\n  GetMem(FCache, FCacheSize);\nend;\n\ndestructor TwbBaseCachedFileStream.Destroy;\nbegin\n  FreeMem(FCache);\n  if FOwnsHandle and (FHandle<>0) then begin\n    CloseHandle(FHandle);\n  end;\n  inherited;\nend;\n\nfunction TwbBaseCachedFileStream.QueryInterface(const IID: TGUID; out Obj): HResult;\nbegin\n  if GetInterface(IID, Obj) then begin\n    Result := S_OK;\n  end else begin\n    Result := E_NOINTERFACE;\n  end;\nend;\n\nfunction TwbBaseCachedFileStream._AddRef: Integer;\nbegin\n  Result := -1;\nend;\n\nfunction TwbBaseCachedFileStream._Release: Integer;\nbegin\n  Result := -1;\nend;\n\nprocedure TwbBaseCachedFileStream.HandleError(const Msg: string);\nbegin\n  if FLastError<>0 then begin\n    RaiseSystemError(Msg, FLastError);\n  end;\nend;\n\nprocedure TwbBaseCachedFileStream.RaiseSystemError(const Msg: string; LastError: DWORD);\nbegin\n  raise EStreamError.Create(Trim(Msg+'  ')+SysErrorMessage(LastError));\nend;\n\nprocedure TwbBaseCachedFileStream.RaiseSystemError(const Msg: string);\nbegin\n  RaiseSystemError(Msg, GetLastError);\nend;\n\nprocedure TwbBaseCachedFileStream.RaiseSystemErrorFmt(const Msg: string; const Args: array of const);\nbegin\n  RaiseSystemError(Format(Msg, Args));\nend;\n\nfunction TwbBaseCachedFileStream.GetFileSize: Int64;\nbegin\n  if not GetFileSizeEx(FHandle, Result) then begin\n    RaiseSystemErrorFmt('GetFileSizeEx failed for %s.', [FFileName]);\n  end;\nend;\n\nprocedure TwbBaseCachedFileStream.SetSize(NewSize: Longint);\nbegin\n  SetSize(Int64(NewSize));\nend;\n\nprocedure TwbBaseCachedFileStream.SetSize(const NewSize: Int64);\nbegin\n  Seek(NewSize, soBeginning);\n  if not Windows.SetEndOfFile(FHandle) then begin\n    RaiseSystemErrorFmt('SetEndOfFile for %s.', [FFileName]);\n  end;\nend;\n\nfunction TwbBaseCachedFileStream.FileRead(var Buffer; Count: Longword): Integer;\nbegin\n  if Windows.ReadFile(FHandle, Buffer, Count, LongWord(Result), nil) then begin\n    FLastError := 0;\n  end else begin\n    FLastError := GetLastError;\n    Result := -1;\n  end;\nend;\n\nfunction TwbBaseCachedFileStream.FileWrite(const Buffer; Count: Longword): Integer;\nbegin\n  if Windows.WriteFile(FHandle, Buffer, Count, LongWord(Result), nil) then begin\n    FLastError := 0;\n  end else begin\n    FLastError := GetLastError;\n    Result := -1;\n  end;\nend;\n\nfunction TwbBaseCachedFileStream.FileSeek(const Offset: Int64; Origin: TSeekOrigin): Int64;\nbegin\n  if not SetFilePointerEx(FHandle, Offset, @Result, ord(Origin)) then begin\n    RaiseSystemErrorFmt('SetFilePointerEx failed for %s.', [FFileName]);\n  end;\nend;\n\nfunction TwbBaseCachedFileStream.Read(var Buffer; Count: Integer): Longint;\nbegin\n  raise EAssertionFailed.Create('Cannot read from this stream');\nend;\n\nfunction TwbBaseCachedFileStream.ReadCardinal: Cardinal;\nbegin\n  ReadBuffer(Result, SizeOf(Result));\nend;\n\nfunction TwbBaseCachedFileStream.ReadInt64: Int64;\nbegin\n  ReadBuffer(Result, SizeOf(Result));\nend;\n\nfunction TwbBaseCachedFileStream.ReadSignature: TwbSignature;\nbegin\n  ReadBuffer(Result, SizeOf(Result));\nend;\n\nfunction TwbBaseCachedFileStream.ReadByte: Byte;\nbegin\n  ReadBuffer(Result, SizeOf(Result));\nend;\n\nfunction TwbBaseCachedFileStream.ReadWord: Word;\nbegin\n  ReadBuffer(Result, SizeOf(Result));\nend;\n\nfunction TwbBaseCachedFileStream.ReadStringLen(Term: Boolean = True): string;\nvar\n  Len : Byte;\n  s   : AnsiString;\nbegin\n  ReadBuffer(Len, 1);\n  SetLength(s, Len);\n  if Len > 0 then begin\n    ReadBuffer(s[1], Len);\n    if Term then\n      SetLength(s, Pred(Length(s)));\n  end;\n  Result := s;\nend;\n\nfunction TwbBaseCachedFileStream.ReadStringLen16: string;\nvar\n  Len : Word;\n  s   : AnsiString;\nbegin\n  ReadBuffer(Len, 2);\n  SetLength(s, Len);\n  if Len > 0 then\n    ReadBuffer(s[1], Len);\n  Result := s;\nend;\n\nfunction TwbBaseCachedFileStream.ReadStringTerm: string;\nvar\n  i: Integer;\n  s: AnsiString;\nbegin\n  if (FCacheEnd - FPosition >= 256) and (FCacheStart >= FPosition) then begin\n    s := PAnsiChar(@FCache[FPosition - FCacheStart]);\n    Inc(FPosition, Succ(Length(s)));\n  end else begin\n    SetLength(s, 256);\n    i := 0;\n    repeat\n      Inc(i);\n      ReadBuffer(s[i], 1);\n    until s[i] = #0;\n    SetLength(s, Pred(i));\n  end;\n  Result := s;\nend;\n\nfunction TwbBaseCachedFileStream.Write(const Buffer; Count: Integer): Longint;\nbegin\n  raise EAssertionFailed.Create('Cannot write to this stream');\nend;\n\nprocedure TwbBaseCachedFileStream.WriteCardinal(aCardinal: Cardinal);\nbegin\n  WriteBuffer(aCardinal, SizeOf(aCardinal));\nend;\n\nprocedure TwbBaseCachedFileStream.WriteSmallInt(aSmallInt: SmallInt);\nbegin\n  WriteBuffer(aSmallInt, SizeOf(aSmallInt));\nend;\n\nfunction TwbBaseCachedFileStream.Seek(const Offset: Int64; Origin: TSeekOrigin): Int64;\n//Set FPosition to the value specified - if this has implications for the\n//cache then overriden Write and Read methods must deal with those.\nbegin\n  case Origin of\n  soBeginning:\n    FPosition := Offset;\n  soEnd:\n    FPosition := GetFileSize+Offset;\n  soCurrent:\n    inc(FPosition, Offset);\n  end;\n  Result := FPosition;\nend;\n\n{ TwbReadOnlyCachedFileStream }\n\nconstructor TwbReadOnlyCachedFileStream.Create(const FileName: string; CacheSize: Integer; Handle: THandle);\nbegin\n  inherited;\n  SetViewWindow(0, inherited GetFileSize);\nend;\n\nfunction TwbReadOnlyCachedFileStream.CreateHandle(FlagsAndAttributes: DWORD): THandle;\nbegin\n  Result := Windows.CreateFile(\n    PChar(FFileName),\n    GENERIC_READ,\n    FILE_SHARE_READ,\n    nil,\n    OPEN_EXISTING,\n    FlagsAndAttributes,\n    0\n  );\n  if Result=INVALID_HANDLE_VALUE then begin\n    RaiseSystemErrorFmt('Cannot open %s.', [FFileName]);\n  end;\nend;\n\nprocedure TwbReadOnlyCachedFileStream.DisableStreamReadCache;\nbegin\n  inc(FDisableStreamReadCacheRefCount);\nend;\n\nprocedure TwbReadOnlyCachedFileStream.EnableStreamReadCache;\nbegin\n  dec(FDisableStreamReadCacheRefCount);\nend;\n\nprocedure TwbReadOnlyCachedFileStream.FlushCache;\nbegin\n  FCacheStart := 0;\n  FCacheEnd := 0;\nend;\n\nfunction TwbReadOnlyCachedFileStream.GetFileSize: Int64;\nbegin\n  Result := FViewLength;\nend;\n\nprocedure TwbReadOnlyCachedFileStream.SetViewWindow(const ViewStart, ViewLength: Int64);\nbegin\n  if ViewStart<0 then begin\n    raise EAssertionFailed.Create('Invalid view window');\n  end;\n  if (ViewStart+ViewLength)>inherited GetFileSize then begin\n    raise EAssertionFailed.Create('Invalid view window');\n  end;\n  FViewStart := ViewStart;\n  FViewLength := ViewLength;\n  FPosition := 0;\n  FCacheStart := 0;\n  FCacheEnd := 0;\nend;\n\nfunction TwbReadOnlyCachedFileStream.Read(var Buffer; Count: Longint): Longint;\nvar\n  NumOfBytesToCopy, NumOfBytesLeft, NumOfBytesRead: Longint;\n  CachePtr, BufferPtr: PByte;\nbegin\n  if (FDisableStreamReadCacheRefCount>0) or (Count > FCacheSize) then begin\n    FileSeek(FPosition+FViewStart, soBeginning);\n    Result := FileRead(Buffer, Count);\n    if Result=-1 then begin\n      Result := 0;//contract is to return number of bytes that were read\n    end;\n    inc(FPosition, Result);\n  end else begin\n    Result := 0;\n    NumOfBytesLeft := Count;\n    BufferPtr := @Buffer;\n    while NumOfBytesLeft>0 do begin\n      if (FPosition<FCacheStart) or (FPosition>=FCacheEnd) then begin\n        //the current position is not available in the cache so we need to re-fill the cache\n        FCacheStart := FPosition;\n        if UseAlignedCache then begin\n          FCacheStart := FCacheStart - (FCacheStart mod CacheSize);\n        end;\n        FileSeek(FCacheStart+FViewStart, soBeginning);\n        NumOfBytesRead := FileRead(FCache^, CacheSize);\n        if NumOfBytesRead=-1 then begin\n          exit;\n        end;\n        Assert(NumOfBytesRead>=0);\n        FCacheEnd := FCacheStart+NumOfBytesRead;\n        if NumOfBytesRead=0 then begin\n          FLastError := ERROR_HANDLE_EOF;//must be at the end of the file\n          break;\n        end;\n      end;\n\n      //read from cache to Buffer\n      NumOfBytesToCopy := Min(FCacheEnd-FPosition, NumOfBytesLeft);\n      CachePtr := FCache;\n      inc(CachePtr, FPosition-FCacheStart);\n      Move(CachePtr^, BufferPtr^, NumOfBytesToCopy);\n      inc(Result, NumOfBytesToCopy);\n      inc(FPosition, NumOfBytesToCopy);\n      inc(BufferPtr, NumOfBytesToCopy);\n      dec(NumOfBytesLeft, NumOfBytesToCopy);\n    end;\n  end;\nend;\n\n{ TwbWriteCachedFileStream }\n\nconstructor TwbWriteCachedFileStream.Create(const FileName: string; CacheSize, ReadStreamCacheSize: Integer; ReadStreamUseAlignedCache: Boolean);\nbegin\n  inherited Create(FileName, CacheSize);\n  FReadStreamCacheSize := ReadStreamCacheSize;\n  FReadStreamUseAlignedCache := ReadStreamUseAlignedCache;\nend;\n\ndestructor TwbWriteCachedFileStream.Destroy;\nbegin\n  FlushCache;//make sure that the final calls to Write get recorded in the file\n  FreeAndNil(FReadStream);\n  inherited;\nend;\n\nfunction TwbWriteCachedFileStream.CreateHandle(FlagsAndAttributes: DWORD): THandle;\nbegin\n  Result := Windows.CreateFile(\n    PChar(FFileName),\n    GENERIC_READ or GENERIC_WRITE,\n    0,\n    nil,\n    CREATE_ALWAYS,\n    FlagsAndAttributes,\n    0\n  );\n  if Result=INVALID_HANDLE_VALUE then begin\n    RaiseSystemErrorFmt('Cannot create %s.', [FFileName]);\n  end;\nend;\n\nprocedure TwbWriteCachedFileStream.DisableStreamReadCache;\nbegin\n  CreateReadStream;\n  FReadStream.DisableStreamReadCache;\nend;\n\nprocedure TwbWriteCachedFileStream.EnableStreamReadCache;\nbegin\n  Assert(Assigned(FReadStream));\n  FReadStream.EnableStreamReadCache;\nend;\n\nfunction TwbWriteCachedFileStream.GetFileSize: Int64;\nbegin\n  Result := FFileSize;\nend;\n\nprocedure TwbWriteCachedFileStream.CreateReadStream;\nbegin\n  if not Assigned(FReadStream) then begin\n    FReadStream := TwbReadOnlyCachedFileStream.Create(FFileName, FReadStreamCacheSize, FHandle);\n    FReadStream.UseAlignedCache := FReadStreamUseAlignedCache;\n  end;\nend;\n\nprocedure TwbWriteCachedFileStream.FlushCache;\nvar\n  NumOfBytesToWrite: Longint;\nbegin\n  if Assigned(FCache) then begin\n    NumOfBytesToWrite := FCacheEnd-FCacheStart;\n    if NumOfBytesToWrite>0 then begin\n      FileSeek(FCacheStart, soBeginning);\n      if FileWrite(FCache^, NumOfBytesToWrite)<>NumOfBytesToWrite then begin\n        RaiseSystemErrorFmt('FileWrite failed for %s.', [FFileName]);\n      end;\n      if Assigned(FReadStream) then begin\n        FReadStream.FlushCache;\n      end;\n    end;\n    FCacheStart := FPosition;\n    FCacheEnd := FPosition;\n  end;\nend;\n\nfunction TwbWriteCachedFileStream.Read(var Buffer; Count: Integer): Longint;\nbegin\n  FlushCache;\n  CreateReadStream;\n  Assert(FReadStream.FViewStart=0);\n  if FReadStream.FViewLength<>FFileSize then begin\n    FReadStream.SetViewWindow(0, FFileSize);\n  end;\n  FReadStream.Position := FPosition;\n  Result := FReadStream.Read(Buffer, Count);\n  inc(FPosition, Result);\nend;\n\nfunction TwbWriteCachedFileStream.Write(const Buffer; Count: Longint): Longint;\nvar\n  NumOfBytesToCopy, NumOfBytesLeft: Longint;\n  CachePtr, BufferPtr: PByte;\nbegin\n  Result := 0;\n  NumOfBytesLeft := Count;\n  BufferPtr := @Buffer;\n  while NumOfBytesLeft>0 do begin\n    if ((FPosition<FCacheStart) or (FPosition>FCacheEnd))//the current position is outside the cache\n    or (FPosition-FCacheStart=FCacheSize)//the cache is full\n    then begin\n      FlushCache;\n      Assert(FCacheStart=FPosition);\n    end;\n\n    //write from Buffer to the cache\n    NumOfBytesToCopy := Min(FCacheSize-(FPosition-FCacheStart), NumOfBytesLeft);\n    CachePtr := FCache;\n    inc(CachePtr, FPosition-FCacheStart);\n    Move(BufferPtr^, CachePtr^, NumOfBytesToCopy);\n    inc(Result, NumOfBytesToCopy);\n    inc(FPosition, NumOfBytesToCopy);\n    FCacheEnd := Max(FCacheEnd, FPosition);\n    inc(BufferPtr, NumOfBytesToCopy);\n    dec(NumOfBytesLeft, NumOfBytesToCopy);\n  end;\n  FFileSize := Max(FFileSize, FPosition);\nend;\n\ninitialization\nfinalization\nend.\n"
  },
  {
    "path": "lib/xedit/zlib/ZLibEx.inc",
    "content": "{*************************************************************************************************\n*  ZLibEx.inc                                                                                    *\n*  copyright (c) 2006-2013 base2 technologies                                                    *\n*                                                                                                *\n*  version information for delphi/c++ builder                                                    *\n*                                                                                                *\n*  revision history                                                                              *\n*    2013.05.23  updated for delphi xe3 (2013)                                                   *\n*    2012.05.01  updated for delphi xe2 (2012)                                                   *\n*    2010.09.18  updated for delphi xe (2011)                                                    *\n*    2010.01.27  updated for delphi 2010                                                         *\n*    2009.04.11  updated to use CONDITIONALEXPRESSIONS and CompilerVersion                       *\n*    2009.01.28  updated for delphi 2009                                                         *\n*    2007.10.01  updated for delphi 2007                                                         *\n*    2005.11.29  created                                                                         *\n*                                                                                                *\n*  acknowledgments                                                                               *\n*    iztok kacin                                                                                 *\n*      2009.04.11  CONDITIONALEXPRESSIONS and CompilerVersion changes                            *\n*************************************************************************************************}\n\n{$ifndef CONDITIONALEXPRESSIONS}\n\n  {** delphi ************************************************************************************}\n\n  {$ifdef VER80}                        // delphi 1\n    {$define Delphi}\n\n    {$define Version1}\n  {$endif}\n\n  {$ifdef VER90}                        // delphi 2\n    {$define Delphi}\n\n    {$define Version2}\n  {$endif}\n\n  {$ifdef VER100}                       // delphi 3\n    {$define Delphi}\n\n    {$define Version3}\n  {$endif}\n\n  {$ifdef VER120}                       // delphi 4\n    {$define Delphi}\n\n    {$define Version4}\n  {$endif}\n\n  {** c++ builder *******************************************************************************}\n\n  {$ifdef VER93}                        // c++ builder 1\n    {$define CBuilder}\n\n    {$define Version1}\n  {$endif}\n\n  {$ifdef VER110}                       // c++ builder 3\n    {$define CBuilder}\n\n    {$define Version3}\n  {$endif}\n\n  {$ifdef VER125}                       // c++ builder 4\n    {$define CBuilder}\n\n    {$define Version4}\n  {$endif}\n\n  {** delphi/c++ builder (common) ***************************************************************}\n\n  {$ifdef VER130}                       // delphi/c++ builder 5\n    {$ifdef BCB}\n      {$define CBuilder}\n    {$ELSE}\n      {$define Delphi}\n    {$endif}\n\n    {$define Version5}\n\n    {$define Version5Plus}\n  {$endif}\n\n{$ELSE}\n\n  {$ifdef BCB}\n    {$define CBuilder}\n  {$ELSE}\n    {$define Delphi}\n  {$endif}\n\n  {$define Version5Plus}\n\n  {$if CompilerVersion >= 14.0}         // delphi 6\n    {$ifdef VER140}\n      {$define Version6}\n    {$endif}\n\n    {$define Version6Plus}\n  {$ifend}\n\n  {$if CompilerVersion >= 15.0}         // delphi 7\n    {$ifdef VER150}\n      {$define Version7}\n    {$endif}\n\n    {$define Version7Plus}\n  {$ifend}\n\n  {$if CompilerVersion >= 16.0}         // delphi 8 (.net)\n    {$ifdef VER160}\n      {$define Version8}\n    {$endif}\n\n    {$define Version8Plus}\n  {$ifend}\n\n  {$if CompilerVersion >= 17.0}         // delphi 2005\n    {$ifdef VER170}\n      {$define Version2005}\n    {$endif}\n\n    {$define Version2005Plus}\n  {$ifend}\n\n  {$if CompilerVersion >= 18.0}         // bds 2006\n    {$ifdef VER180}\n      {$define Version2006}\n    {$endif}\n\n    {$define Version2006Plus}\n  {$ifend}\n\n  {$if CompilerVersion >= 18.5}         // bds 2007\n    {$ifdef VER185}\n      {$define Version2007}\n    {$endif}\n\n    {$define Version2007Plus}\n  {$ifend}\n\n  {$if CompilerVersion >= 20.0}         // bds 2009\n    {$ifdef VER200}\n      {$define Version2009}\n    {$endif}\n\n    {$define Version2009Plus}\n  {$ifend}\n\n  {$if CompilerVersion >= 21.0}         // bds 2010\n    {$ifdef VER210}\n      {$define Version2010}\n    {$endif}\n\n    {$define Version2010Plus}\n  {$ifend}\n\n  {$if CompilerVersion >= 22.0}         // bds xe (2011)\n    {$ifdef VER220}\n      {$define Version2011}\n    {$endif}\n\n    {$define Version2011Plus}\n  {$ifend}\n\n  {$if CompilerVersion >= 23.0}         // bds xe2 (2012)\n    {$ifdef VER230}\n      {$define Version2012}\n    {$endif}\n\n    {$define Version2012Plus}\n  {$ifend}\n\n  {$if CompilerVersion >= 24.0}         // bds xe3 (2013)\n    {$ifdef VER240}\n      {$define Version2013}\n    {$endif}\n\n    {$define Version2013Plus}\n  {$ifend}\n\n{$endif}\n"
  },
  {
    "path": "lib/xedit/zlib/ZLibExApi.pas",
    "content": "{*************************************************************************************************\n*  ZLibExApi.pas                                                                                 *\n*                                                                                                *\n*  copyright (c) 2000-2013 base2 technologies                                                    *\n*  copyright (c) 1995-2002 Borland Software Corporation                                          *\n*                                                                                                *\n*  revision history                                                                              *\n*    2013.05.23  updated to zlib version 1.2.8                                                   *\n*    2012.05.21  updated for win64 (delphi xe2)                                                  *\n*                moved win32 obj files to win32 subfolder                                        *\n*                changed win32 obj options to exclude the underscore                             *\n*    2012.05.07  updated to zlib version 1.2.7                                                   *\n*    2012.03.05  udpated to zlib version 1.2.6                                                   *\n*    2010.04.20  updated to zlib version 1.2.5                                                   *\n*    2010.04.15  updated to zlib version 1.2.4                                                   *\n*    2005.07.25  updated to zlib version 1.2.3                                                   *\n*    2005.01.11  updated to zlib version 1.2.2                                                   *\n*    2004.01.06  updated to zlib version 1.2.1                                                   *\n*    2002.03.15  updated to zlib version 1.1.4                                                   *\n*                                                                                                *\n*  acknowledgments                                                                               *\n*    burak kalayci                                                                               *\n*      2002.03.15  informing me about the zlib 1.1.4 update                                      *\n*      2004.01.06  informing me about the zlib 1.2.1 update                                      *\n*                                                                                                *\n*    vicente sanchez-alarcos                                                                     *\n*      2005.01.11  informing me about the zlib 1.2.2 update                                      *\n*                                                                                                *\n*    mathijs van veluw                                                                           *\n*      2005.07.25  informing me about the zlib 1.2.3 update                                      *\n*                                                                                                *\n*    tommi prami                                                                                 *\n*      2012.03.05  informing me about the zlib 1.2.6 update                                      *\n*                                                                                                *\n*    marian pascalau                                                                             *\n*      2012.05.21  providing the win64 obj files and your win64 modifications                    *\n*                                                                                                *\n*    roman ganz                                                                                  *\n*      2013.05.23  informing me about the zlib 1.2.8 update                                      *\n*************************************************************************************************}\n\nunit ZLibExApi;\n\ninterface\n\n{$I ZLibEx.inc}\n\nconst\n  {** version ids *******************************************************************************}\n\n  ZLIB_VERSION: PAnsiChar = '1.2.8';\n\n  ZLIB_VERNUM = $1280;\n\n  ZLIB_VER_MAJOR = 1;\n  ZLIB_VER_MINOR = 2;\n  ZLIB_VER_REVISION = 8;\n  ZLIB_VER_SUBREVISION = 0;\n\n  {** compression methods ***********************************************************************}\n\n  Z_DEFLATED = 8;\n\n  {** information flags *************************************************************************}\n\n  Z_INFO_FLAG_SIZE  = $1;\n  Z_INFO_FLAG_CRC   = $2;\n  Z_INFO_FLAG_ADLER = $4;\n\n  Z_INFO_NONE       = 0;\n  Z_INFO_DEFAULT    = Z_INFO_FLAG_SIZE or Z_INFO_FLAG_CRC;\n\n  {** flush constants ***************************************************************************}\n\n  Z_NO_FLUSH      = 0;\n  Z_PARTIAL_FLUSH = 1;\n  Z_SYNC_FLUSH    = 2;\n  Z_FULL_FLUSH    = 3;\n  Z_FINISH        = 4;\n  Z_BLOCK         = 5;\n  Z_TREES         = 6;\n\n  {** return codes ******************************************************************************}\n\n  Z_OK            = 0;\n  Z_STREAM_END    = 1;\n  Z_NEED_DICT     = 2;\n  Z_ERRNO         = (-1);\n  Z_STREAM_ERROR  = (-2);\n  Z_DATA_ERROR    = (-3);\n  Z_MEM_ERROR     = (-4);\n  Z_BUF_ERROR     = (-5);\n  Z_VERSION_ERROR = (-6);\n\n  {** compression levels ************************************************************************}\n\n  Z_NO_COMPRESSION      =   0;\n  Z_BEST_SPEED          =   1;\n  Z_BEST_COMPRESSION    =   9;\n  Z_DEFAULT_COMPRESSION = (-1);\n\n  {** compression strategies ********************************************************************}\n\n  Z_FILTERED         = 1;\n  Z_HUFFMAN_ONLY     = 2;\n  Z_RLE              = 3;\n  Z_FIXED            = 4;\n  Z_DEFAULT_STRATEGY = 0;\n\n  {** data types ********************************************************************************}\n\n  Z_BINARY  = 0;\n  Z_TEXT    = 1;\n  Z_ASCII   = Z_TEXT;\n  Z_UNKNOWN = 2;\n\n  {** return code messages **********************************************************************}\n\n  z_errmsg: Array [0..9] of String = (\n    'Need dictionary',      // Z_NEED_DICT      (2)\n    'Stream end',           // Z_STREAM_END     (1)\n    'OK',                   // Z_OK             (0)\n    'File error',           // Z_ERRNO          (-1)\n    'Stream error',         // Z_STREAM_ERROR   (-2)\n    'Data error',           // Z_DATA_ERROR     (-3)\n    'Insufficient memory',  // Z_MEM_ERROR      (-4)\n    'Buffer error',         // Z_BUF_ERROR      (-5)\n    'Incompatible version', // Z_VERSION_ERROR  (-6)\n    ''\n  );\n\ntype\n  TZAlloc = function (opaque: Pointer; items, size: Integer): Pointer; cdecl;\n  TZFree  = procedure (opaque, block: Pointer); cdecl;\n\n  {** TZStreamRec *******************************************************************************}\n\n  TZStreamRec = packed record\n    next_in  : PByte;     // next input byte\n    avail_in : Cardinal;  // number of bytes available at next_in\n    total_in : Longword;  // total nb of input bytes read so far\n\n    next_out : PByte;     // next output byte should be put here\n    avail_out: Cardinal;  // remaining free space at next_out\n    total_out: Longword;  // total nb of bytes output so far\n\n    msg      : PAnsiChar; // last error message, NULL if no error\n    state    : Pointer;   // not visible by applications\n\n    zalloc   : TZAlloc;   // used to allocate the internal state\n    zfree    : TZFree;    // used to free the internal state\n    opaque   : Pointer;   // private data object passed to zalloc and zfree\n\n    data_type: Integer;   // best guess about the data type: ascii or binary\n    adler    : Longword;  // adler32 value of the uncompressed data\n    reserved : Longword;  // reserved for future use\n  end;\n\n{** macros **************************************************************************************}\n\nfunction deflateInit(var strm: TZStreamRec; level: Integer): Integer;\n  {$ifdef Version2005Plus} inline; {$endif}\n\nfunction deflateInit2(var strm: TZStreamRec; level, method, windowBits,\n  memLevel, strategy: Integer): Integer;\n  {$ifdef Version2005Plus} inline; {$endif}\n\nfunction inflateInit(var strm: TZStreamRec): Integer;\n  {$ifdef Version2005Plus} inline; {$endif}\n\nfunction inflateInit2(var strm: TZStreamRec; windowBits: Integer): Integer;\n  {$ifdef Version2005Plus} inline; {$endif}\n\n{** external routines ***************************************************************************}\n\nfunction deflateInit_(var strm: TZStreamRec; level: Integer;\n  version: PAnsiChar; recsize: Integer): Integer;\n\nfunction deflateInit2_(var strm: TZStreamRec; level, method, windowBits,\n  memLevel, strategy: Integer; version: PAnsiChar; recsize: Integer): Integer;\n\nfunction deflate(var strm: TZStreamRec; flush: Integer): Integer;\n\nfunction deflateEnd(var strm: TZStreamRec): Integer;\n\nfunction deflateReset(var strm: TZStreamRec): Integer;\n\nfunction inflateInit_(var strm: TZStreamRec; version: PAnsiChar;\n  recsize: Integer): Integer;\n\nfunction inflateInit2_(var strm: TZStreamRec; windowBits: Integer;\n  version: PAnsiChar; recsize: Integer): Integer;\n\nfunction inflate(var strm: TZStreamRec; flush: Integer): Integer;\n\nfunction inflateEnd(var strm: TZStreamRec): Integer;\n\nfunction inflateReset(var strm: TZStreamRec): Integer;\n\nfunction adler32(adler: Longint; const buf; len: Integer): Longint;\n\nfunction crc32(crc: Longint; const buf; len: Integer): Longint;\n\nimplementation\n\n{*************************************************************************************************\n*  link zlib code                                                                                *\n*                                                                                                *\n*  bcc32 flags                                                                                   *\n*    -c -O2 -Ve -X -pr -a8 -b -d -k- -vi -tWM -u-                                                *\n*                                                                                                *\n*  note: do not reorder the following -- doing so will result in external                        *\n*  functions being undefined                                                                     *\n*************************************************************************************************}\n\n{$ifdef WIN64}\n{$L win64\\deflate.obj}\n{$L win64\\inflate.obj}\n{$L win64\\inftrees.obj}\n{$L win64\\infback.obj}\n{$L win64\\inffast.obj}\n{$L win64\\trees.obj}\n{$L win64\\compress.obj}\n{$L win64\\adler32.obj}\n{$L win64\\crc32.obj}\n{$else}\n{$L win32\\deflate.obj}\n{$L win32\\inflate.obj}\n{$L win32\\inftrees.obj}\n{$L win32\\infback.obj}\n{$L win32\\inffast.obj}\n{$L win32\\trees.obj}\n{$L win32\\compress.obj}\n{$L win32\\adler32.obj}\n{$L win32\\crc32.obj}\n{$endif}\n\n{** macros **************************************************************************************}\n\nfunction deflateInit(var strm: TZStreamRec; level: Integer): Integer;\nbegin\n  result := deflateInit_(strm, level, ZLIB_VERSION, SizeOf(TZStreamRec));\nend;\n\nfunction deflateInit2(var strm: TZStreamRec; level, method, windowBits,\n  memLevel, strategy: Integer): Integer;\nbegin\n  result := deflateInit2_(strm, level, method, windowBits,\n    memLevel, strategy, ZLIB_VERSION, SizeOf(TZStreamRec));\nend;\n\nfunction inflateInit(var strm: TZStreamRec): Integer;\nbegin\n  result := inflateInit_(strm, ZLIB_VERSION, SizeOf(TZStreamRec));\nend;\n\nfunction inflateInit2(var strm: TZStreamRec; windowBits: Integer): Integer;\nbegin\n  result := inflateInit2_(strm, windowBits, ZLIB_VERSION,\n    SizeOf(TZStreamRec));\nend;\n\n{** external routines ***************************************************************************}\n\nfunction deflateInit_(var strm: TZStreamRec; level: Integer;\n  version: PAnsiChar; recsize: Integer): Integer;\n  external;\n\nfunction deflateInit2_(var strm: TZStreamRec; level, method, windowBits,\n  memLevel, strategy: Integer; version: PAnsiChar; recsize: Integer): Integer;\n  external;\n\nfunction deflate(var strm: TZStreamRec; flush: Integer): Integer;\n  external;\n\nfunction deflateEnd(var strm: TZStreamRec): Integer;\n  external;\n\nfunction deflateReset(var strm: TZStreamRec): Integer;\n  external;\n\nfunction inflateInit_(var strm: TZStreamRec; version: PAnsiChar;\n  recsize: Integer): Integer;\n  external;\n\nfunction inflateInit2_(var strm: TZStreamRec; windowBits: Integer;\n  version: PAnsiChar; recsize: Integer): Integer;\n  external;\n\nfunction inflate(var strm: TZStreamRec; flush: Integer): Integer;\n  external;\n\nfunction inflateEnd(var strm: TZStreamRec): Integer;\n  external;\n\nfunction inflateReset(var strm: TZStreamRec): Integer;\n  external;\n\nfunction adler32(adler: Longint; const buf; len: Integer): Longint;\n  external;\n\nfunction crc32(crc: Longint; const buf; len: Integer): Longint;\n  external;\n\n{** zlib function implementations ***************************************************************}\n\nfunction zcalloc(opaque: Pointer; items, size: Integer): Pointer;\nbegin\n  GetMem(result,items * size);\nend;\n\nprocedure zcfree(opaque, block: Pointer);\nbegin\n  FreeMem(block);\nend;\n\n{** c function implementations ******************************************************************}\n\nfunction memset(p: Pointer; b: Byte; count: Integer): Pointer; cdecl;\nbegin\n  FillChar(p^, count, b);\n\n  result := p;\nend;\n\nprocedure memcpy(dest, source: Pointer; count: Integer); cdecl;\nbegin\n  Move(source^, dest^, count);\nend;\n\n{$ifndef WIN64}\nprocedure _llmod;\nasm\n  jmp System.@_llmod;\nend;\n{$endif}\n\nend.\n"
  },
  {
    "path": "lib/xedit/zlib/zlibex.pas",
    "content": "{*************************************************************************************************\n*  ZLibEx.pas                                                                                    *\n*                                                                                                *\n*  copyright (c) 2000-2013 base2 technologies                                                    *\n*  copyright (c) 1995-2002 Borland Software Corporation                                          *\n*                                                                                                *\n*  revision history                                                                              *\n*    2012.05.21  updated for win64 (delphi xe2)                                                  *\n*                added NativeInt type for delphi 2007-                                           *\n*                added NativeUInt type for delphi 2007-                                          *\n*    2011.07.21  fixed routines to validate size before calling Move                             *\n*    2010.07.01  hide overloaded Z*String* routines for delphi 5                                 *\n*    2010.05.02  added ZDelfateEx and ZInflateEx                                                 *\n*    2010.04.20  added TZ*Buffer classes                                                         *\n*    2010.04.15  moved core zlib routines to separate unit (ZLibExApi.pas)                       *\n*                added ZDeflate* and ZInflate*                                                   *\n*    2010.04.14  fixed ZInternalCompress loops                                                   *\n*                fixed ZInternalDecompress loops                                                 *\n*                updated ZInternalCompressStream loops                                           *\n*                updated ZInternalDecompressStream loops                                         *\n*    2010.01.27  updated for delphi 2010                                                         *\n*    2009.04.14  added overloaded string routines for AnsiString and UnicodeString               *\n*    2009.01.28  updated for delphi 2009 String (UnicodeString)                                  *\n*    2008.05.15  added TStreamPos type for Stream.Position variants                              *\n*                added TCustomZStream.Stream* methods                                            *\n*    2007.08.17  modified TZCompressionStream.Write to use Write instead of WriteBuffer          *\n*    2007.03.15  moved gzip routines to separate unit (ZLibExGZ.pas)                             *\n*    2006.10.07  fixed EZLibError constructor for c++ builder compatibility                      *\n*    2006.03.28  moved Z_DEFLATED to interface section                                           *\n*                added custom compression levels zcLevel1 thru zcLevel9                          *\n*    2006.03.27  added ZCompressStreamWeb                                                        *\n*    2006.03.24  added ZAdler32 and ZCrc32                                                       *\n*    2005.11.29  changed FStreamPos to Int64 for delphi 6+                                       *\n*    2005.03.04  modified ZInternalCompressStream loops                                          *\n*                modified ZInternalDecompressStream loops                                        *\n*    2005.02.07  fixed ZInternalCompressStream loop conditions                                   *\n*                fixed ZInternalDecompressStream loop conditions                                 *\n*    2005.01.11  added ZCompressStrWeb                                                           *\n*    2003.04.14  added ZCompress2 and ZDecompress2                                               *\n*                added ZCompressStr2 and ZDecompressStr2                                         *\n*                added ZCompressStream2 and ZDecompressStream2                                   *\n*                added overloaded T*Stream constructors to support InflateInit2                  *\n*                  and DeflateInit2                                                              *\n*                fixed ZDecompressStream to use ZDecompressCheck instead of ZCompressCheck       *\n*    2001.11.27  enhanced TZDecompressionStream.Read to adjust source stream position upon end   *\n*                  of compression data                                                           *\n*                fixed endless loop in TZDecompressionStream.Read when destination count was     *\n*                  greater than uncompressed data                                                *\n*    2001.10.26  renamed unit to integrate \"nicely\" with delphi 6                                *\n*    2000.11.24  added soFromEnd condition to TZDecompressionStream.Seek                         *\n*                added ZCompressStream and ZDecompressStream                                     *\n*    2000.06.13  optimized, fixed, rewrote, and enhanced the zlib.pas unit included on the       *\n*                  delphi cd (zlib version 1.1.3)                                                *\n*                                                                                                *\n*  acknowledgments                                                                               *\n*    erik turner                                                                                 *\n*      2001.10.26  Z*Stream routines                                                             *\n*                                                                                                *\n*    david bennion                                                                               *\n*      2001.11.27  finding the nasty little endless loop quirk with the                          *\n*                    TZDecompressionStream.Read method                                           *\n*                                                                                                *\n*    luigi sandon                                                                                *\n*      2005.02.07  pointing out the missing loop condition (Z_STREAM_END) in                     *\n*                    ZInternalCompressStream and ZInternalDecompressStream                       *\n*                                                                                                *\n*    ferry van genderen                                                                          *\n*      2005.03.04  assisting me fine tune and beta test ZInternalCompressStream and              *\n*                    ZInternalDecompressStream                                                   *\n*                                                                                                *\n*    j. rathlev                                                                                  *\n*      2005.11.28  pointing out the FStreamPos and TStream.Position type inconsistency           *\n*                                                                                                *\n*    anders johansen                                                                             *\n*      2006.10.07  pointing out the ELibError constructor incompatibility with c++ builder       *\n*                                                                                                *\n*    marcin szafranski                                                                           *\n*      2009.01.28  beta testing the delphi 2009 changes                                          *\n*                                                                                                *\n*    iztok kacin                                                                                 *\n*      2009.04.14  assisting me design and further improve support for delphi 2009               *\n*                                                                                                *\n*    oleg matrozov                                                                               *\n*      2010.04.14  pointing out the missing loop condition (avail_in > 0) in ZInternalCompress   *\n*                    and ZInternalDecompress                                                     *\n*      2010.04.20  prototyping and assisting with the TZ*Buffer classes                          *\n*                                                                                                *\n*    edward koo                                                                                  *\n*      2010.07.01  pointing out the delphi 5 incompatibility with the overloaded Z*String*       *\n*                    routines                                                                    *\n*                                                                                                *\n*    egron elbra                                                                                 *\n*      2011.07.20  pointing out the range exception when moving empty strings                    *\n*                                                                                                *\n*    marian pascalau                                                                             *\n*      2012.05.21  providing their win64 modifications                                           *\n*                                                                                                *\n*  donations                                                                                     *\n*    2011.05.06  farshad mohajeri                                                                *\n*    2012.06.07  marat safin                                                                     *\n*    2012.12.14  moacir schmidt                                                                  *\n*    2013.05.23  roman ganz                                                                      *\n*************************************************************************************************}\n\nunit ZLibEx;\n\ninterface\n\n{$I ZLibEx.inc}\n\nuses\n  SysUtils, Classes, ZLibExApi;\n\ntype\n\n{$ifndef UNICODE}\n\n  RawByteString = AnsiString;\n\n  UnicodeString = WideString;\n  UnicodeChar = WideChar;\n\n{$else ifdef Version2010Plus}\n\n  UnicodeChar = WideChar;\n\n{$endif}\n\n{$ifndef Version2009Plus}\n\n  NativeInt = Integer;\n  NativeUInt = Cardinal;\n\n{$endif}\n\n  TStreamPos = {$ifdef Version6Plus} Int64 {$else} Longint {$endif};\n\n  TZCompressionLevel = (\n    zcNone,\n    zcFastest,\n    zcDefault,\n    zcMax,\n    zcLevel1,\n    zcLevel2,\n    zcLevel3,\n    zcLevel4,\n    zcLevel5,\n    zcLevel6,\n    zcLevel7,\n    zcLevel8,\n    zcLevel9\n  );\n\n  TZStrategy = (\n    zsDefault,\n    zsFiltered,\n    zsHuffman,\n    zsRLE,\n    zsFixed\n  );\n\n  TZError = (\n    zeError,\n    zeStreamError,\n    zeDataError,\n    zeMemoryError,\n    zeBufferError,\n    zeVersionError\n  );\n\n  TZFlush = (\n    zfNoFlush,\n    zfPartialFlush,\n    zfSyncFlush,\n    zfFullFlush,\n    zfFinish,\n    zfBlock,\n    zfTrees\n  );\n\nconst\n  ZLevels: Array [TZCompressionLevel] of Integer = (\n    Z_NO_COMPRESSION,       // zcNone\n    Z_BEST_SPEED,           // zcFastest\n    Z_DEFAULT_COMPRESSION,  // zcDefault\n    Z_BEST_COMPRESSION,     // zcMax\n    1,                      // zcLevel1\n    2,                      // zcLevel2\n    3,                      // zcLevel3\n    4,                      // zcLevel4\n    5,                      // zcLevel5\n    6,                      // zcLevel6\n    7,                      // zcLevel7\n    8,                      // zcLevel8\n    9                       // zcLevel9\n  );\n\n  ZStrategies: Array [TZStrategy] of Integer = (\n    Z_DEFAULT_STRATEGY,     // zsDefault\n    Z_FILTERED,             // zsFiltered\n    Z_HUFFMAN_ONLY,         // zsHuffman\n    Z_RLE,                  // zsRLE\n    Z_FIXED                 // zsFixed\n  );\n\n  ZErrors: Array [TZError] of Integer = (\n    Z_ERRNO,                // zeError\n    Z_STREAM_ERROR,         // zeStreamError\n    Z_DATA_ERROR,           // zeDataError\n    Z_MEM_ERROR,            // zeMemoryError\n    Z_BUF_ERROR,            // zeBufferError\n    Z_VERSION_ERROR         // zeVersionError\n  );\n\n  ZFlushes: Array [TZFlush] of Integer = (\n    Z_NO_FLUSH,             // zfNoFlush\n    Z_PARTIAL_FLUSH,        // zfPartialFlush\n    Z_SYNC_FLUSH,           // zfSyncFlush\n    Z_FULL_FLUSH,           // zfFullFlush\n    Z_FINISH,               // zfFinish\n    Z_BLOCK,                // zfBlock\n    Z_TREES                 // zfTrees\n  );\n\ntype\n  {** TZ*Function *******************************************************************************}\n\n  TZReadFunction = function (param: Pointer; var buffer;\n    size: Integer): Integer;\n\n  TZWriteFunction = function (param: Pointer; const buffer;\n    size: Integer): Integer;\n\n  {** TZInformation *****************************************************************************}\n\n  TZInformation = packed record\n    CompressedFlags  : Longint;\n    CompressedSize   : TStreamPos;\n    CompressedCrc    : Longint;\n    CompressedAdler  : Longint;\n\n    UncompressedFlags: Longint;\n    UncompressedSize : TStreamPos;\n    UncompressedCrc  : Longint;\n    UncompressedAdler: Longint;\n  end;\n\n  {** TCustomZStream ****************************************************************************}\n\n  TCustomZStream = class(TStream)\n  private\n    FStream    : TStream;\n    FStreamPos : TStreamPos;\n    FOnProgress: TNotifyEvent;\n\n    FZStream   : TZStreamRec;\n    FBuffer    : Array [Word] of Byte;\n\n    function  GetStreamPosition: TStreamPos;\n    procedure SetStreamPosition(value: TStreamPos);\n  protected\n    constructor Create(stream: TStream);\n\n    function  StreamRead(var buffer; count: Longint): Longint;\n    function  StreamWrite(const buffer; count: Longint): Longint;\n    function  StreamSeek(offset: Longint; origin: Word): Longint;\n\n    procedure StreamReadBuffer(var buffer; count: Longint);\n    procedure StreamWriteBuffer(const buffer; count: Longint);\n\n    procedure DoProgress; dynamic;\n\n    property StreamPosition: TStreamPos read GetStreamPosition write SetStreamPosition;\n\n    property OnProgress: TNotifyEvent read FOnProgress write FOnProgress;\n  end;\n\n  {** TZCompressionStream ***********************************************************************}\n\n  TZCompressionStream = class(TCustomZStream)\n  private\n    function GetCompressionRate: Single;\n  public\n    constructor Create(dest: TStream;\n      compressionLevel: TZCompressionLevel = zcDefault); overload;\n\n    constructor Create(dest: TStream; compressionLevel: TZCompressionLevel;\n      windowBits, memLevel: Integer; strategy: TZStrategy); overload;\n\n    destructor  Destroy; override;\n\n    function  Read(var buffer; count: Longint): Longint; override;\n    function  Write(const buffer; count: Longint): Longint; override;\n    function  Seek(offset: Longint; origin: Word): Longint; override;\n\n    property CompressionRate: Single read GetCompressionRate;\n    property OnProgress;\n  end;\n\n  {** TZDecompressionStream *********************************************************************}\n\n  TZDecompressionStream = class(TCustomZStream)\n  public\n    constructor Create(source: TStream); overload;\n    constructor Create(source: TStream; windowBits: Integer); overload;\n\n    destructor  Destroy; override;\n\n    function  Read(var buffer; count: Longint): Longint; override;\n    function  Write(const buffer; count: Longint): Longint; override;\n    function  Seek(offset: Longint; origin: Word): Longint; override;\n\n    property OnProgress;\n  end;\n\n  {** TZCustomBuffer ****************************************************************************}\n\n  TZCustomBuffer = class(TObject)\n  private\n    FBuffer        : Pointer;\n    FBufferCapacity: Integer;\n    FBufferSize    : Integer;\n  protected\n    FZStream: TZStreamRec;\n\n    procedure BufferWrite(const buffer: Pointer; size: Integer);\n    procedure BufferRead(var buffer: Pointer; size: Integer);\n\n    procedure BufferCapacity(capacity: Integer);\n\n    property BufferSize: Integer read FBufferSize;\n  public\n    constructor Create;\n    destructor  Destroy; override;\n\n    procedure Clear; virtual;\n\n    procedure Flush(flush: TZFlush); virtual;\n\n    function  Write(const buffer: Pointer; size: Integer): Integer; overload;\n      virtual; abstract;\n\n    function  Write(const s: AnsiString): Integer; overload;\n\n    function  Read(var buffer: Pointer; size: Integer): Integer; overload;\n    function  Read(var s: AnsiString): Integer; overload;\n  end;\n\n  {** TZCompressionBuffer ***********************************************************************}\n\n  TZCompressionBuffer = class(TZCustomBuffer)\n  public\n    constructor Create(level: TZCompressionLevel = zcDefault); overload;\n    constructor Create(level: TZCompressionLevel;\n      windowBits, memLevel: Integer; strategy: TZStrategy); overload;\n\n    destructor  Destroy; override;\n\n    procedure Clear; override;\n\n    procedure Flush(flush: TZFlush); override;\n\n    function  Write(const buffer: Pointer; size: Integer): Integer;\n      override;\n  end;\n\n  {** TZDecompressionBuffer *********************************************************************}\n\n  TZDecompressionBuffer = class(TZCustomBuffer)\n  public\n    constructor Create; overload;\n    constructor Create(windowBits: Integer); overload;\n\n    destructor  Destroy; override;\n\n    procedure Clear; override;\n\n    function  Write(const buffer: Pointer; size: Integer): Integer; override;\n  end;\n\n{** zlib deflate routines ***********************************************************************}\n\nfunction  ZDeflateInit(var stream: TZStreamRec;\n  level: TZCompressionLevel): Integer;\n  {$ifdef Version2005Plus} inline; {$endif}\n\nfunction  ZDeflateInit2(var stream: TZStreamRec;\n  level: TZCompressionLevel; windowBits, memLevel: Integer;\n  strategy: TZStrategy): Integer;\n  {$ifdef Version2005Plus} inline; {$endif}\n\nfunction  ZDeflate(var stream: TZStreamRec; flush: TZFlush): Integer;\n  {$ifdef Version2005Plus} inline; {$endif}\n\nfunction  ZDeflateEnd(var stream: TZStreamRec): Integer;\n  {$ifdef Version2005Plus} inline; {$endif}\n\nfunction  ZDeflateReset(var stream: TZStreamRec): Integer;\n  {$ifdef Version2005Plus} inline; {$endif}\n\n{** zlib inflate routines ***********************************************************************}\n\nfunction  ZInflateInit(var stream: TZStreamRec): Integer;\n  {$ifdef Version2005Plus} inline; {$endif}\n\nfunction  ZInflateInit2(var stream: TZStreamRec;\n  windowBits: Integer): Integer;\n  {$ifdef Version2005Plus} inline; {$endif}\n\nfunction  ZInflate(var stream: TZStreamRec; flush: TZFlush): Integer;\n  {$ifdef Version2005Plus} inline; {$endif}\n\nfunction  ZInflateEnd(var stream: TZStreamRec): Integer;\n  {$ifdef Version2005Plus} inline; {$endif}\n\nfunction  ZInflateReset(var stream: TZStreamRec): Integer;\n  {$ifdef Version2005Plus} inline; {$endif}\n\n{** zlib checksum routines **********************************************************************}\n\nfunction  ZAdler32(adler: Longint; const buffer; size: Integer): Longint;\n  {$ifdef Version2005Plus} inline; {$endif}\n\nfunction  ZCrc32(crc: Longint; const buffer; size: Integer): Longint;\n  {$ifdef Version2005Plus} inline; {$endif}\n\n{** zlib custom routines ************************************************************************}\n\nprocedure ZDeflateEx(var stream: TZStreamRec; param: Pointer;\n  read: TZReadFunction; write: TZWriteFunction; flush: TZFlush);\n\nprocedure ZInflateEx(var stream: TZStreamRec; param: Pointer;\n  read: TZReadFunction; write: TZWriteFunction; flush: TZFlush);\n\n{*************************************************************************************************\n*  ZCompress                                                                                     *\n*                                                                                                *\n*  pre-conditions                                                                                *\n*    inBuffer  = pointer to uncompressed data                                                    *\n*    inSize    = size of inBuffer (bytes)                                                        *\n*    outBuffer = pointer (unallocated)                                                           *\n*    level     = compression level                                                               *\n*                                                                                                *\n*  post-conditions                                                                               *\n*    outBuffer = pointer to compressed data (allocated)                                          *\n*    outSize   = size of outBuffer (bytes)                                                       *\n*************************************************************************************************}\n\nprocedure ZCompress(const inBuffer: Pointer; inSize: Integer;\n  out outBuffer: Pointer; out outSize: Integer;\n  level: TZCompressionLevel = zcDefault);\n\n{*************************************************************************************************\n*  ZCompress2                                                                                    *\n*                                                                                                *\n*  pre-conditions                                                                                *\n*    inBuffer   = pointer to uncompressed data                                                   *\n*    inSize     = size of inBuffer (bytes)                                                       *\n*    outBuffer  = pointer (unallocated)                                                          *\n*    level      = compression level                                                              *\n*    method     = compression method                                                             *\n*    windowBits = window bits                                                                    *\n*    memLevel   = memory level                                                                   *\n*    strategy   = compression strategy                                                           *\n*                                                                                                *\n*  post-conditions                                                                               *\n*    outBuffer = pointer to compressed data (allocated)                                          *\n*    outSize   = size of outBuffer (bytes)                                                       *\n*************************************************************************************************}\n\nprocedure ZCompress2(const inBuffer: Pointer; inSize: Integer;\n  out outBuffer: Pointer; out outSize: Integer; level: TZCompressionLevel;\n  windowBits, memLevel: Integer; strategy: TZStrategy);\n\n{*************************************************************************************************\n*  ZDecompress                                                                                   *\n*                                                                                                *\n*  pre-conditions                                                                                *\n*    inBuffer    = pointer to compressed data                                                    *\n*    inSize      = size of inBuffer (bytes)                                                      *\n*    outBuffer   = pointer (unallocated)                                                         *\n*    outEstimate = estimated size of uncompressed data (bytes)                                   *\n*                                                                                                *\n*  post-conditions                                                                               *\n*    outBuffer = pointer to decompressed data (allocated)                                        *\n*    outSize   = size of outBuffer (bytes)                                                       *\n*************************************************************************************************}\n\nprocedure ZDecompress(const inBuffer: Pointer; inSize: Integer;\n out outBuffer: Pointer; out outSize: Integer; outEstimate: Integer = 0);\n\n{*************************************************************************************************\n*  ZDecompress2                                                                                  *\n*                                                                                                *\n*  pre-conditions                                                                                *\n*    inBuffer    = pointer to compressed data                                                    *\n*    inSize      = size of inBuffer (bytes)                                                      *\n*    outBuffer   = pointer (unallocated)                                                         *\n*    windowBits  = window bits                                                                   *\n*    outEstimate = estimated size of uncompressed data (bytes)                                   *\n*                                                                                                *\n*  post-conditions                                                                               *\n*    outBuffer = pointer to decompressed data (allocated)                                        *\n*    outSize   = size of outBuffer (bytes)                                                       *\n*************************************************************************************************}\n\nprocedure ZDecompress2(const inBuffer: Pointer; inSize: Integer;\n out outBuffer: Pointer; out outSize: Integer; windowBits: Integer;\n outEstimate: Integer = 0);\n\n{** string routines *****************************************************************************}\n\n{*************************************************************************************************\n*  ZCompressStr                                                                                  *\n*                                                                                                *\n*  pre-conditions                                                                                *\n*    s     = uncompressed data string                                                            *\n*    level = compression level                                                                   *\n*                                                                                                *\n*  return                                                                                        *\n*    compressed data string                                                                      *\n*************************************************************************************************}\n\nfunction  ZCompressStr(const s: AnsiString;\n  level: TZCompressionLevel = zcDefault): RawByteString;\n\nprocedure ZCompressString(var result: RawByteString; const s: AnsiString;\n  level: TZCompressionLevel = zcDefault); overload;\n\n{$ifdef Version6Plus}\nprocedure ZCompressString(var result: RawByteString; const s: UnicodeString;\n  level: TZCompressionLevel = zcDefault); overload;\n{$endif}\n\n{*************************************************************************************************\n*  ZCompressStrEx                                                                                *\n*                                                                                                *\n*  pre-conditions                                                                                *\n*    s     = uncompressed data string                                                            *\n*    level = compression level                                                                   *\n*                                                                                                *\n*  return                                                                                        *\n*    compressed data string with 4 byte (integer) header indicating                              *\n*    original uncompressed data length                                                           *\n*************************************************************************************************}\n\nfunction  ZCompressStrEx(const s: AnsiString;\n  level: TZCompressionLevel = zcDefault): RawByteString;\n\nprocedure ZCompressStringEx(var result: RawByteString; const s: AnsiString;\n  level: TZCompressionLevel = zcDefault); overload;\n\n{$ifdef Version6Plus}\nprocedure ZCompressStringEx(var result: RawByteString; const s: UnicodeString;\n  level: TZCompressionLevel = zcDefault); overload;\n{$endif}\n\n{*************************************************************************************************\n*  ZCompressStr2                                                                                 *\n*                                                                                                *\n*  pre-conditions                                                                                *\n*    s          = uncompressed data string                                                       *\n*    level      = compression level                                                              *\n*    windowBits = window bits                                                                    *\n*    memLevel   = memory level                                                                   *\n*    strategy   = compression strategy                                                           *\n*                                                                                                *\n*  return                                                                                        *\n*    compressed data string                                                                      *\n*************************************************************************************************}\n\nfunction  ZCompressStr2(const s: AnsiString; level: TZCompressionLevel;\n  windowBits, memLevel: Integer; strategy: TZStrategy): RawByteString;\n\nprocedure ZCompressString2(var result: RawByteString; const s: AnsiString;\n  level: TZCompressionLevel; windowBits, memLevel: Integer;\n  strategy: TZStrategy); overload;\n\n{$ifdef Version6Plus}\nprocedure ZCompressString2(var result: RawByteString; const s: UnicodeString;\n  level: TZCompressionLevel; windowBits, memLevel: Integer;\n  strategy: TZStrategy); overload;\n{$endif}\n\n{*************************************************************************************************\n*  ZCompressStrWeb                                                                               *\n*                                                                                                *\n*  pre-conditions                                                                                *\n*    s = uncompressed data string                                                                *\n*                                                                                                *\n*  return                                                                                        *\n*    compressed data string                                                                      *\n*************************************************************************************************}\n\nfunction  ZCompressStrWeb(const s: AnsiString): RawByteString;\n\nprocedure ZCompressStringWeb(var result: RawByteString; const s: AnsiString);\n  overload;\n\n{$ifdef Version6Plus}\nprocedure  ZCompressStringWeb(var result: RawByteString;\n  const s: UnicodeString); overload;\n{$endif}\n\n{*************************************************************************************************\n*  ZDecompressStr                                                                                *\n*                                                                                                *\n*  pre-conditions                                                                                *\n*    s = compressed data string                                                                  *\n*                                                                                                *\n*  return                                                                                        *\n*    uncompressed data string                                                                    *\n*************************************************************************************************}\n\nfunction  ZDecompressStr(const s: RawByteString): AnsiString;\n\nprocedure ZDecompressString(var result: AnsiString; const s: RawByteString);\n  overload;\n\n{$ifdef Version6Plus}\nprocedure ZDecompressString(var result: UnicodeString;\n  const s: RawByteString); overload;\n{$endif}\n\n{*************************************************************************************************\n*  ZDecompressStrEx                                                                              *\n*                                                                                                *\n*  pre-conditions                                                                                *\n*    s = compressed data string with 4 byte (integer) header indicating                          *\n*        original uncompressed data length                                                       *\n*                                                                                                *\n*  return                                                                                        *\n*    uncompressed data string                                                                    *\n*************************************************************************************************}\n\nfunction  ZDecompressStrEx(const s: RawByteString): AnsiString;\n\nprocedure ZDecompressStringEx(var result: AnsiString; const s: RawByteString);\n  overload;\n\n{$ifdef Version6Plus}\nprocedure ZDecompressStringEx(var result: UnicodeString;\n  const s: RawByteString); overload;\n{$endif}\n\n{*************************************************************************************************\n*  ZDecompressStr2                                                                               *\n*                                                                                                *\n*  pre-conditions                                                                                *\n*    s          = compressed data string                                                         *\n*    windowBits = window bits                                                                    *\n*                                                                                                *\n*  return                                                                                        *\n*    uncompressed data string                                                                    *\n*************************************************************************************************}\n\nfunction  ZDecompressStr2(const s: RawByteString;\n  windowBits: Integer): AnsiString;\n\nprocedure ZDecompressString2(var result: AnsiString; const s: RawByteString;\n  windowBits: Integer); overload;\n\n{$ifdef Version6Plus}\nprocedure ZDecompressString2(var result: UnicodeString;\n  const s: RawByteString; windowBits: Integer); overload;\n{$endif}\n\n{** stream routines *****************************************************************************}\n\nprocedure ZCompressStream(inStream, outStream: TStream;\n  level: TZCompressionLevel = zcDefault);\n\nprocedure ZCompressStream2(inStream, outStream: TStream;\n  level: TZCompressionLevel; windowBits, memLevel: Integer;\n  strategy: TZStrategy);\n\nprocedure ZCompressStreamWeb(inStream, outStream: TStream);\n\nprocedure ZDecompressStream(inStream, outStream: TStream);\n\nprocedure ZDecompressStream2(inStream, outStream: TStream;\n  windowBits: Integer);\n\n{************************************************************************************************}\n\ntype\n  EZLibErrorClass = class of EZlibError;\n\n  EZLibError = class(Exception)\n  private\n    FErrorCode: Integer;\n  public\n    constructor Create(code: Integer; const dummy: String = ''); overload;\n    constructor Create(error: TZError; const dummy: String = ''); overload;\n\n    property ErrorCode: Integer read FErrorCode write FErrorCode;\n  end;\n\n  EZCompressionError = class(EZLibError);\n  EZDecompressionError = class(EZLibError);\n\n  { DecompressToUserBuf decompresses data, buffer to buffer, in one call.\n   In: InBuf = ptr to compressed data\n       InBytes = number of bytes in InBuf\n  Out: OutBuf = ptr to user-allocated buffer to contain decompressed data\n       BufSize = number of bytes in OutBuf   }\nprocedure DecompressToUserBuf(const InBuf: Pointer; InBytes: Integer;\n  const OutBuf: Pointer; BufSize: Integer);\n\nimplementation\n\nfunction DCheck(code: Integer): Integer;\nbegin\n  Result := code;\n  if code < 0 then\n    raise EZDecompressionError.Create(64673);  //!!\nend;\n\nconst\n  SZInvalid = 'Invalid ZStream operation!';\n\n{************************************************************************************************}\n\nfunction ZCompressCheck(code: Integer): Integer;\nbegin\n  result := code;\n\n  if code < 0 then\n  begin\n    raise EZCompressionError.Create(code);\n  end;\nend;\n\nfunction ZDecompressCheck(code: Integer; raiseBufferError: Boolean = True): Integer;\nbegin\n  Result := code;\n\n  if code < 0 then\n  begin\n    if (code <> Z_BUF_ERROR) or raiseBufferError then\n    begin\n      raise EZDecompressionError.Create(code);\n    end;\n  end;\nend;\n\n{** zlib deflate routines ***********************************************************************}\n\nfunction ZDeflateInit(var stream: TZStreamRec;\n  level: TZCompressionLevel): Integer;\nbegin\n  result := deflateInit_(stream, ZLevels[level], ZLIB_VERSION,\n    SizeOf(TZStreamRec));\nend;\n\nfunction ZDeflateInit2(var stream: TZStreamRec;\n  level: TZCompressionLevel; windowBits, memLevel: Integer;\n  strategy: TZStrategy): Integer;\nbegin\n  result := deflateInit2_(stream, ZLevels[level], Z_DEFLATED, windowBits,\n    memLevel, ZStrategies[strategy], ZLIB_VERSION, SizeOf(TZStreamRec));\nend;\n\nfunction ZDeflate(var stream: TZStreamRec; flush: TZFlush): Integer;\nbegin\n  result := deflate(stream, ZFlushes[flush]);\nend;\n\nfunction ZDeflateEnd(var stream: TZStreamRec): Integer;\nbegin\n  result := deflateEnd(stream);\nend;\n\nfunction ZDeflateReset(var stream: TZStreamRec): Integer;\nbegin\n  result := deflateReset(stream);\nend;\n\n{** zlib inflate routines ***********************************************************************}\n\nfunction ZInflateInit(var stream: TZStreamRec): Integer;\nbegin\n  result := inflateInit_(stream, ZLIB_VERSION, SizeOf(TZStreamRec));\nend;\n\nfunction ZInflateInit2(var stream: TZStreamRec;\n  windowBits: Integer): Integer;\nbegin\n  result := inflateInit2_(stream, windowBits, ZLIB_VERSION,\n    SizeOf(TZStreamRec));\nend;\n\nfunction ZInflate(var stream: TZStreamRec; flush: TZFlush): Integer;\nbegin\n  result := inflate(stream, ZFlushes[flush]);\nend;\n\nfunction ZInflateEnd(var stream: TZStreamRec): Integer;\nbegin\n  result := inflateEnd(stream);\nend;\n\nfunction ZInflateReset(var stream: TZStreamRec): Integer;\nbegin\n  result := inflateReset(stream);\nend;\n\n{** zlib checksum routines **********************************************************************}\n\nfunction ZAdler32(adler: Longint; const buffer; size: Integer): Longint;\nbegin\n  result := adler32(adler,buffer,size);\nend;\n\nfunction ZCrc32(crc: Longint; const buffer; size: Integer): Longint;\nbegin\n  result := crc32(crc,buffer,size);\nend;\n\n{** zlib extended routines **********************************************************************}\n\nprocedure ZDeflateEx(var stream: TZStreamRec; param: Pointer;\n  read: TZReadFunction; write: TZWriteFunction; flush: TZFlush);\nconst\n  bufferSize = 8192;\nvar\n  zresult    : Integer;\n  readBuffer : Array [0..bufferSize - 1] of Byte;\n  writeBuffer: Array [0..bufferSize - 1] of Byte;\n  writeSize  : Integer;\n  flushEx    : TZFlush;\nbegin\n  if Assigned(read) then\n  begin\n    stream.avail_in := read(param, readBuffer, bufferSize);\n  end\n  else stream.avail_in := 0;\n\n  repeat\n    stream.next_in := @readBuffer;\n\n    repeat\n      stream.avail_out := bufferSize;\n      stream.next_out := @writeBuffer;\n\n      flushEx := flush;\n\n      if (flushEx = zfFinish) and (stream.avail_in = bufferSize) then\n      begin\n        flushEx := zfNoFlush;\n      end;\n\n      zresult := ZCompressCheck(ZDeflate(stream, flushEx));\n\n      writeSize := bufferSize - stream.avail_out;\n\n      write(param, writeBuffer, writeSize);\n    until stream.avail_out > 0;\n\n    //assert: stream.avail_in = 0\n\n    if (zresult <> Z_STREAM_END) and Assigned(read) then\n    begin\n      stream.avail_in := read(param, readBuffer, bufferSize);\n    end;\n  until (stream.avail_in = 0) and (flush = flushEx);\nend;\n\nprocedure ZInflateEx(var stream: TZStreamRec; param: Pointer;\n  read: TZReadFunction; write: TZWriteFunction; flush: TZFlush);\nconst\n  bufferSize = 8192;\nvar\n  zresult    : Integer;\n  readBuffer : Array [0..bufferSize - 1] of Byte;\n  writeBuffer: Array [0..bufferSize - 1] of Byte;\n  writeSize  : Integer;\nbegin\n  if Assigned(read) then\n  begin\n    stream.avail_in := read(param, readBuffer, bufferSize);\n  end\n  else stream.avail_in := 0;\n\n  zresult := Z_OK;\n\n  while (zresult <> Z_STREAM_END) and (stream.avail_in > 0) do\n  begin\n    stream.next_in := @readBuffer;\n\n    repeat\n      stream.avail_out := bufferSize;\n      stream.next_out := @writeBuffer;\n\n      zresult := ZDecompressCheck(ZInflate(stream, flush), False);\n\n      writeSize := bufferSize - stream.avail_out;\n\n      write(param, writeBuffer, writeSize);\n    until stream.avail_out > 0;\n\n    if (zresult <> Z_STREAM_END) and Assigned(read) then\n    begin\n      stream.avail_in := read(param, readBuffer, bufferSize);\n    end;\n  end;\nend;\n\n{** private buffer routines *********************************************************************}\n\ntype\n  PZBufferParam = ^TZBufferParam;\n  TZBufferParam = packed record\n    InBuffer   : Pointer;\n    InPosition : Integer;\n    InSize     : Integer;\n    OutBuffer  : Pointer;\n    OutPosition: Integer;\n    OutSize    : Integer;\n  end;\n\nfunction ZBufferRead(p: Pointer; var buffer; size: Integer): Integer;\nvar\n  param: PZBufferParam;\nbegin\n  param := PZBufferParam(p);\n\n  result := param^.InSize - param^.InPosition;\n  if result > size then result := size;\n\n  Move(Pointer(Integer(param^.InBuffer) + param^.InPosition)^, buffer, result);\n\n  Inc(param^.InPosition, result);\nend;\n\nfunction ZBufferWrite(p: Pointer; const buffer; size: Integer): Integer;\nvar\n  param: PZBufferParam;\nbegin\n  param := PZBufferParam(p);\n\n  if param^.OutPosition + size > param^.OutSize then\n  begin\n    param^.OutSize := param^.OutPosition + size;\n\n    ReallocMem(Pointer(param^.OutBuffer), param^.OutSize);\n  end;\n\n  Move(buffer, Pointer(Integer(param^.OutBuffer) + param^.OutPosition)^, size);\n\n  Inc(param^.OutPosition, size);\n\n  result := size;\nend;\n\nprocedure ZInternalCompressEx(var zstream: TZStreamRec; const inBuffer: Pointer;\n  inSize: Integer; out outBuffer: Pointer; out outSize: Integer);\nvar\n  param: TZBufferParam;\nbegin\n  FillChar(param, SizeOf(TZBufferParam), 0);\n\n  outBuffer := Nil;\n  outSize := 0;\n\n  param.InBuffer := inBuffer;\n  param.InSize := inSize;\n\n  try\n    ZDeflateEx(zstream, @param, @ZBufferRead, @ZBufferWrite, zfFinish);\n\n    ZCompressCheck(ZDeflateEnd(zstream));\n\n    outBuffer := param.OutBuffer;\n    outSize := param.OutSize;\n  except\n    FreeMem(param.OutBuffer);\n\n    raise;\n  end;\nend;\n\nprocedure ZInternalDecompressEx(zstream: TZStreamRec; const inBuffer: Pointer;\n  inSize: Integer; out outBuffer: Pointer; out outSize: Integer;\n  outEstimate: Integer);\nvar\n  param: TZBufferParam;\nbegin\n  FillChar(param, SizeOf(TZBufferParam), 0);\n\n  outBuffer := Nil;\n  outSize := 0;\n\n  param.InBuffer := inBuffer;\n  param.InSize := inSize;\n\n  if outEstimate > 0 then\n  begin\n    GetMem(param.OutBuffer, outEstimate);\n\n    param.OutSize := outEstimate;\n  end;\n\n  try\n    ZInflateEx(zstream, @param, @ZBufferRead, @ZBufferWrite, zfNoFlush);\n\n    ZDecompressCheck(ZInflateEnd(zstream));\n\n    outBuffer := param.OutBuffer;\n    outSize := param.OutSize;\n  except\n    FreeMem(param.OutBuffer);\n\n    raise;\n  end;\nend;\n\nprocedure ZInternalCompress(var zstream: TZStreamRec; const inBuffer: Pointer;\n  inSize: Integer; out outBuffer: Pointer; out outSize: Integer);\nconst\n  delta = 256;\nvar\n  zresult: Integer;\nbegin\n  outSize := ((inSize + (inSize div 10) + 12) + 255) and not 255;\n\n  outBuffer := Nil;\n\n  try\n    try\n      zstream.next_in := inBuffer;\n      zstream.avail_in := inSize;\n\n      repeat\n        ReallocMem(outBuffer, outSize);\n\n        zstream.next_out := PByte(NativeUInt(outBuffer) + zstream.total_out);\n        zstream.avail_out := NativeUInt(outSize) - zstream.total_out;\n\n        zresult := ZCompressCheck(ZDeflate(zstream, zfNoFlush));\n\n        Inc(outSize, delta);\n      until (zresult = Z_STREAM_END) or (zstream.avail_in = 0);\n\n      while zresult <> Z_STREAM_END do\n      begin\n        ReallocMem(outBuffer, outSize);\n\n        zstream.next_out := PByte(NativeUInt(outBuffer) + zstream.total_out);\n        zstream.avail_out := NativeUInt(outSize) - zstream.total_out;\n\n        zresult := ZCompressCheck(ZDeflate(zstream, zfFinish));\n\n        Inc(outSize, delta);\n      end;\n    finally\n      ZCompressCheck(ZDeflateEnd(zstream));\n    end;\n\n    ReallocMem(outBuffer, zstream.total_out);\n\n    outSize := zstream.total_out;\n  except\n    FreeMem(outBuffer);\n    raise;\n  end;\nend;\n\nprocedure ZInternalDecompress(zstream: TZStreamRec; const inBuffer: Pointer;\n  inSize: Integer; out outBuffer: Pointer; out outSize: Integer;\n  outEstimate: Integer);\nvar\n  zresult: Integer;\n  delta  : Integer;\nbegin\n  delta := (inSize + 255) and not 255;\n\n  if outEstimate = 0 then outSize := delta\n  else outSize := outEstimate;\n\n  outBuffer := Nil;\n\n  try\n    try\n      zresult := Z_OK;\n\n      zstream.avail_in := inSize;\n      zstream.next_in := inBuffer;\n\n      while (zresult <> Z_STREAM_END) and (zstream.avail_in > 0) do\n      begin\n        repeat\n          ReallocMem(outBuffer, outSize);\n\n          zstream.next_out := PByte(NativeUInt(outBuffer) + zstream.total_out);\n          zstream.avail_out := NativeUInt(outSize) - zstream.total_out;\n\n          zresult := ZDecompressCheck(ZInflate(zstream, zfNoFlush), False);\n\n          Inc(outSize, delta);\n        until (zresult = Z_STREAM_END) or (zstream.avail_out > 0);\n      end;\n    finally\n      ZDecompressCheck(ZInflateEnd(zstream));\n    end;\n\n    ReallocMem(outBuffer, zstream.total_out);\n\n    outSize := zstream.total_out;\n  except\n    if Assigned(outBuffer) then FreeMem(outBuffer);\n\n    raise;\n  end;\nend;\n\n{** buffer routines *****************************************************************************}\n\nprocedure ZCompress(const inBuffer: Pointer; inSize: Integer;\n  out outBuffer: Pointer; out outSize: Integer;\n  level: TZCompressionLevel);\nvar\n  zstream: TZStreamRec;\nbegin\n  FillChar(zstream, SizeOf(TZStreamRec), 0);\n\n  ZCompressCheck(ZDeflateInit(zstream, level));\n\n  ZInternalCompress(zstream, inBuffer, inSize, outBuffer, outSize);\nend;\n\nprocedure ZCompress2(const inBuffer: Pointer; inSize: Integer;\n  out outBuffer: Pointer; out outSize: Integer; level: TZCompressionLevel;\n  windowBits, memLevel: Integer; strategy: TZStrategy);\nvar\n  zstream: TZStreamRec;\nbegin\n  FillChar(zstream, SizeOf(TZStreamRec), 0);\n\n  ZCompressCheck(ZDeflateInit2(zstream, level, windowBits, memLevel,\n    strategy));\n\n  ZInternalCompress(zstream, inBuffer, inSize, outBuffer, outSize);\nend;\n\nprocedure ZDecompress(const inBuffer: Pointer; inSize: Integer;\n  out outBuffer: Pointer; out outSize: Integer; outEstimate: Integer);\nvar\n  zstream: TZStreamRec;\nbegin\n  FillChar(zstream, SizeOf(TZStreamRec), 0);\n\n  ZDecompressCheck(ZInflateInit(zstream));\n\n  ZInternalDecompress(zstream, inBuffer, inSize, outBuffer, outSize,\n    outEstimate);\nend;\n\nprocedure ZDecompress2(const inBuffer: Pointer; inSize: Integer;\n  out outBuffer: Pointer; out outSize: Integer; windowBits: Integer;\n  outEstimate: Integer);\nvar\n  zstream: TZStreamRec;\nbegin\n  FillChar(zstream, SizeOf(TZStreamRec), 0);\n\n  ZDecompressCheck(ZInflateInit2(zstream, windowBits));\n\n  ZInternalDecompress(zstream, inBuffer, inSize, outBuffer, outSize,\n    outEstimate);\nend;\n\n{** string routines *****************************************************************************}\n\nfunction ZCompressStr(const s: AnsiString;\n  level: TZCompressionLevel): RawByteString;\nbegin\n  ZCompressString(result, s, level);\nend;\n\nprocedure ZCompressString(var result: RawByteString; const s: AnsiString;\n  level: TZCompressionLevel);\nvar\n  buffer: Pointer;\n  size  : Integer;\nbegin\n  ZCompress(Pointer(s), Length(s), buffer, size, level);\n\n  SetLength(result, size);\n\n  if size > 0 then\n  begin\n    Move(buffer^, result[1], size);\n  end;\n\n  FreeMem(buffer);\nend;\n\n{$ifdef Version6Plus}\nprocedure ZCompressString(var result: RawByteString; const s: UnicodeString;\n  level: TZCompressionLevel);\nvar\n  buffer: Pointer;\n  size  : Integer;\nbegin\n  ZCompress(Pointer(s), Length(s) * SizeOf(UnicodeChar), buffer, size, level);\n\n  SetLength(result, size);\n\n  if size > 0 then\n  begin\n    Move(buffer^, result[1], size);\n  end;\n\n  FreeMem(buffer);\nend;\n{$endif}\n\nfunction ZCompressStrEx(const s: AnsiString;\n  level: TZCompressionLevel): RawByteString;\nbegin\n  ZCompressStringEx(result, s, level);\nend;\n\nprocedure ZCompressStringEx(var result: RawByteString; const s: AnsiString;\n  level: TZCompressionLevel);\nvar\n  buffer: Pointer;\n  size  : Integer;\nbegin\n  ZCompress(Pointer(s), Length(s), buffer, size, level);\n\n  SetLength(result, size + SizeOf(Integer));\n\n  if size > 0 then\n  begin\n    Move(buffer^, result[1 + SizeOf(Integer)], size);\n  end;\n\n  size := Length(s);\n\n  Move(size, result[1], SizeOf(Integer));\n\n  FreeMem(buffer);\nend;\n\n{$ifdef Version6Plus}\nprocedure ZCompressStringEx(var result: RawByteString; const s: UnicodeString;\n  level: TZCompressionLevel);\nvar\n  buffer: Pointer;\n  size  : Integer;\nbegin\n  ZCompress(Pointer(s), Length(s) * SizeOf(UnicodeChar), buffer, size, level);\n\n  SetLength(result, size + SizeOf(Integer));\n\n  if size > 0 then\n  begin\n    Move(buffer^, result[1 + SizeOf(Integer)], size);\n  end;\n\n  size := Length(s) * SizeOf(UnicodeChar);\n\n  Move(size, result[1], SizeOf(Integer));\n\n  FreeMem(buffer);\nend;\n{$endif}\n\nfunction ZCompressStr2(const s: AnsiString; level: TZCompressionLevel;\n  windowBits, memLevel: Integer; strategy: TZStrategy): RawByteString;\nbegin\n  ZCompressString2(result, s, level, windowBits, memLevel, strategy);\nend;\n\nprocedure ZCompressString2(var result: RawByteString; const s: AnsiString;\n  level: TZCompressionLevel; windowBits, memLevel: Integer;\n  strategy: TZStrategy);\nvar\n  buffer: Pointer;\n  size  : Integer;\nbegin\n  ZCompress2(Pointer(s), Length(s), buffer, size, level, windowBits,\n    memLevel, strategy);\n\n  SetLength(result, size);\n\n  if size > 0 then\n  begin\n    Move(buffer^, result[1], size);\n  end;\n\n  FreeMem(buffer);\nend;\n\n{$ifdef Version6Plus}\nprocedure ZCompressString2(var result: RawByteString; const s: UnicodeString;\n  level: TZCompressionLevel; windowBits, memLevel: Integer;\n  strategy: TZStrategy);\nvar\n  buffer: Pointer;\n  size  : Integer;\nbegin\n  ZCompress2(Pointer(s), Length(s) * SizeOf(UnicodeChar), buffer, size,\n    level, windowBits, memLevel, strategy);\n\n  SetLength(result, size);\n\n  if size > 0 then\n  begin\n    Move(buffer^, result[1], size);\n  end;\n\n  FreeMem(buffer);\nend;\n{$endif}\n\nfunction ZCompressStrWeb(const s: AnsiString): RawByteString;\nbegin\n  ZCompressStringWeb(result, s);\nend;\n\nprocedure ZCompressStringWeb(var result: RawByteString; const s: AnsiString);\nbegin\n  ZCompressString2(result, s, zcFastest, -15, 9, zsDefault);\nend;\n\n{$ifdef Version6Plus}\nprocedure ZCompressStringWeb(var result: RawBytestring;\n  const s: UnicodeString);\nbegin\n  ZCompressString2(result, s, zcFastest, -15, 9, zsDefault);\nend;\n{$endif}\n\nfunction ZDecompressStr(const s: RawByteString): AnsiString;\nbegin\n  ZDecompressString(result, s);\nend;\n\nprocedure ZDecompressString(var result: AnsiString;\n  const s: RawByteString);\nvar\n  buffer: Pointer;\n  size  : Integer;\nbegin\n  ZDecompress(Pointer(s), Length(s), buffer, size);\n\n  SetLength(result, size);\n\n  if size > 0 then\n  begin\n    Move(buffer^, result[1], size);\n  end;\n\n  FreeMem(buffer);\nend;\n\n{$ifdef Version6Plus}\nprocedure ZDecompressString(var result: UnicodeString;\n  const s: RawByteString);\nvar\n  buffer: Pointer;\n  size  : Integer;\nbegin\n  ZDecompress(Pointer(s), Length(s), buffer, size);\n\n  SetLength(result, size div SizeOf(UnicodeChar));\n\n  if size > 0 then\n  begin\n    Move(buffer^, result[1], size);\n  end;\n\n  FreeMem(buffer);\nend;\n{$endif}\n\nfunction ZDecompressStrEx(const s: RawByteString): AnsiString;\nbegin\n  ZDecompressStringEx(result, s);\nend;\n\nprocedure ZDecompressStringEx(var result: AnsiString; const s: RawByteString);\nvar\n  buffer  : Pointer;\n  size    : Integer;\n  data    : AnsiString;\n  dataSize: Integer;\nbegin\n  Move(s[1], size, SizeOf(Integer));\n\n  dataSize := Length(s) - SizeOf(Integer);\n\n  SetLength(data, dataSize);\n\n  if dataSize > 0 then\n  begin\n    Move(s[1 + SizeOf(Integer)], data[1], dataSize);\n\n    ZDecompress(Pointer(data), dataSize, buffer, size, size);\n\n    SetLength(result, size);\n\n    if size > 0 then\n    begin\n      Move(buffer^, result[1], size);\n    end;\n\n    FreeMem(buffer);\n  end\n  else\n  begin\n    SetLength(result, 0);\n  end;\nend;\n\n{$ifdef Version6Plus}\nprocedure ZDecompressStringEx(var result: UnicodeString;\n  const s: RawByteString);\nvar\n  buffer  : Pointer;\n  size    : Integer;\n  data    : AnsiString;\n  dataSize: Integer;\nbegin\n  Move(s[1], size, SizeOf(Integer));\n\n  dataSize := Length(s) - SizeOf(Integer);\n\n  if dataSize > 0 then\n  begin\n    SetLength(data, dataSize);\n\n    Move(s[1 + SizeOf(Integer)], data[1], dataSize);\n\n    ZDecompress(Pointer(data), dataSize, buffer, size, size);\n\n    SetLength(result, size div SizeOf(UnicodeChar));\n\n    if size > 0 then\n    begin\n      Move(buffer^, result[1], size);\n    end;\n\n    FreeMem(buffer);\n  end\n  else\n  begin\n    SetLength(result, 0);\n  end;\nend;\n{$endif}\n\nfunction ZDecompressStr2(const s: RawByteString;\n  windowBits: Integer): AnsiString;\nbegin\n  ZDecompressString2(result, s, windowBits);\nend;\n\nprocedure ZDecompressString2(var result: AnsiString; const s: RawByteString;\n  windowBits: Integer);\nvar\n  buffer: Pointer;\n  size  : Integer;\nbegin\n  ZDecompress2(Pointer(s), Length(s), buffer, size, windowBits);\n\n  SetLength(result, size);\n\n  if size > 0 then\n  begin\n    Move(buffer^, result[1], size);\n  end;\n\n  FreeMem(buffer);\nend;\n\n{$ifdef Version6Plus}\nprocedure ZDecompressString2(var result: UnicodeString;\n  const s: RawByteString; windowBits: Integer);\nvar\n  buffer: Pointer;\n  size  : Integer;\nbegin\n  ZDecompress2(Pointer(s), Length(s), buffer, size, windowBits);\n\n  SetLength(result, size div SizeOf(UnicodeChar));\n\n  if size > 0 then\n  begin\n    Move(buffer^, result[1], size);\n  end;\n\n  FreeMem(buffer);\nend;\n{$endif}\n\n{** private stream routines *********************************************************************}\n\ntype\n  PZStreamParam = ^TZStreamParam;\n  TZStreamParam = packed record\n    InStream   : TStream;\n    OutStream  : TStream;\n  end;\n\nfunction ZStreamRead(p: Pointer; var buffer; size: Integer): Integer;\nvar\n  param: PZStreamParam;\nbegin\n  param := PZStreamParam(p);\n\n  result := param^.InStream.Read(buffer, size);\nend;\n\nfunction ZStreamWrite(p: Pointer; const buffer; size: Integer): Integer;\nvar\n  param: PZStreamParam;\nbegin\n  param := PZStreamParam(p);\n\n  result := param^.OutStream.Write(buffer, size);\nend;\n\nprocedure ZInternalCompressStreamEx(zstream: TZStreamRec; inStream,\n  outStream: TStream);\nvar\n  param: TZStreamParam;\nbegin\n  FillChar(param, SizeOf(TZStreamParam), 0);\n\n  param.InStream := inStream;\n  param.OutStream := outStream;\n\n  ZDeflateEx(zstream, @param, @ZBufferRead, @ZBufferWrite, zfFinish);\n\n  ZCompressCheck(ZDeflateEnd(zstream));\nend;\n\nprocedure ZInternalDecompressStreamEx(zstream: TZStreamRec; inStream,\n  outStream: TStream);\nvar\n  param: TZStreamParam;\nbegin\n  FillChar(param, SizeOf(TZStreamParam), 0);\n\n  param.InStream := inStream;\n  param.OutStream := outStream;\n\n  ZInflateEx(zstream, @param, @ZBufferRead, @ZBufferWrite, zfNoFlush);\n\n  ZDecompressCheck(ZInflateEnd(zstream));\nend;\n\nprocedure ZInternalCompressStream(zstream: TZStreamRec; inStream,\n  outStream: TStream);\nconst\n  bufferSize = 32768;\nvar\n  zresult  : Integer;\n  inBuffer : Array [0..bufferSize - 1] of Byte;\n  outBuffer: Array [0..bufferSize - 1] of Byte;\n  outSize  : Integer;\nbegin\n  zresult := Z_STREAM_END;\n\n  zstream.avail_in := inStream.Read(inBuffer, bufferSize);\n\n  while zstream.avail_in > 0 do\n  begin\n    zstream.next_in := @inBuffer;\n\n    repeat\n      zstream.next_out := @outBuffer;\n      zstream.avail_out := bufferSize;\n\n      zresult := ZCompressCheck(ZDeflate(zstream, zfNoFlush));\n\n      outSize := bufferSize - zstream.avail_out;\n\n      outStream.Write(outBuffer, outSize);\n    until (zresult = Z_STREAM_END) or (zstream.avail_in = 0);\n\n    zstream.avail_in := inStream.Read(inBuffer, bufferSize);\n  end;\n\n  while zresult <> Z_STREAM_END do\n  begin\n    zstream.next_out := @outBuffer;\n    zstream.avail_out := bufferSize;\n\n    zresult := ZCompressCheck(ZDeflate(zstream, zfFinish));\n\n    outSize := bufferSize - zstream.avail_out;\n\n    outStream.Write(outBuffer, outSize);\n  end;\n\n  ZCompressCheck(ZDeflateEnd(zstream));\nend;\n\nprocedure ZInternalDecompressStream(zstream: TZStreamRec; inStream,\n  outStream: TStream);\nconst\n  bufferSize = 32768;\nvar\n  zresult  : Integer;\n  inBuffer : Array [0..bufferSize-1] of Byte;\n  outBuffer: Array [0..bufferSize-1] of Byte;\n  outSize  : Integer;\nbegin\n  try\n    zresult := Z_OK;\n\n    zstream.avail_in := inStream.Read(inBuffer, bufferSize);\n\n    while (zresult <> Z_STREAM_END) and (zstream.avail_in > 0) do\n    begin\n      zstream.next_in := @inBuffer;\n\n      repeat\n        zstream.next_out := @outBuffer;\n        zstream.avail_out := bufferSize;\n\n        zresult := ZDecompressCheck(ZInflate(zstream, zfNoFlush), False);\n\n        outSize := bufferSize - zstream.avail_out;\n\n        outStream.Write(outBuffer, outSize);\n      until (zresult = Z_STREAM_END) or (zstream.avail_out > 0);\n\n      if zstream.avail_in > 0 then\n      begin\n        inStream.Position := inStream.Position - zstream.avail_in;\n      end;\n\n      if zresult <> Z_STREAM_END then\n      begin\n        zstream.avail_in := inStream.Read(inBuffer, bufferSize);\n      end;\n    end;\n  finally\n    ZDecompressCheck(ZInflateEnd(zstream));\n  end;\nend;\n\n{** stream routines *****************************************************************************}\n\n{procedure ZCompressStream(inStream, outStream: TStream;\n  level: TZCompressionLevel);\nvar\n  zstream: TZStreamRec;\nbegin\n  FillChar(zstream, SizeOf(TZStreamRec), 0);\n\n  ZCompressCheck(ZDeflateInit(zstream, level));\n\n  ZInternalCompressStream(zstream, inStream, outStream);\nend;}\n\nprocedure ZCompressStream(inStream, outStream: TStream;\n  level: TZCompressionLevel);\nconst\n  bufferSize = 32768;\nvar\n  zstream: TZStreamRec;\n  zresult: Integer;\n  inBuffer: array[0..bufferSize - 1] of Char;\n  outBuffer: array[0..bufferSize - 1] of Char;\n  inSize: Integer;\n  outSize: Integer;\nbegin\n  FillChar(zstream, SizeOf(TZStreamRec), 0);\n\n  ZCompressCheck(DeflateInit(zstream, ZLevels[level]));\n\n  inSize := inStream.Read(inBuffer, bufferSize);\n\n  while inSize > 0 do\n  begin\n    zstream.next_in := @inBuffer[0];\n    zstream.avail_in := inSize;\n\n    repeat\n      zstream.next_out := @outBuffer[0];\n      zstream.avail_out := bufferSize;\n\n      ZCompressCheck(deflate(zstream, Z_NO_FLUSH));\n\n      // outSize := zstream.next_out - outBuffer;\n      outSize := bufferSize - zstream.avail_out;\n\n      outStream.Write(outBuffer, outSize);\n    until (zstream.avail_in = 0) and (zstream.avail_out > 0);\n\n    inSize := inStream.Read(inBuffer, bufferSize);\n  end;\n\n  repeat\n    zstream.next_out := @outBuffer[0];\n    zstream.avail_out := bufferSize;\n\n    zresult := ZCompressCheck(deflate(zstream, Z_FINISH));\n\n    // outSize := zstream.next_out - outBuffer;\n    outSize := bufferSize - zstream.avail_out;\n\n    outStream.Write(outBuffer, outSize);\n  until (zresult = Z_STREAM_END) and (zstream.avail_out > 0);\n\n  ZCompressCheck(deflateEnd(zstream));\nend;\n\n\nprocedure ZCompressStream2(inStream, outStream: TStream;\n  level: TZCompressionLevel; windowBits, memLevel: Integer;\n  strategy: TZStrategy);\nvar\n  zstream: TZStreamRec;\nbegin\n  FillChar(zstream, SizeOf(TZStreamRec), 0);\n\n  ZCompressCheck(ZDeflateInit2(zstream, level, windowBits, memLevel,\n    strategy));\n\n  ZInternalCompressStream(zstream,inStream,outStream);\nend;\n\nprocedure ZCompressStreamWeb(inStream, outStream: TStream);\nbegin\n  ZCompressStream2(inStream, outStream, zcFastest, -15, 9, zsDefault);\nend;\n\nprocedure ZDecompressStream(inStream, outStream: TStream);\nvar\n  zstream: TZStreamRec;\nbegin\n  FillChar(zstream, SizeOf(TZStreamRec), 0);\n\n  ZDecompressCheck(ZInflateInit(zstream));\n\n  ZInternalDecompressStream(zstream, inStream, outStream);\nend;\n\nprocedure ZDecompressStream2(inStream, outStream: TStream;\n  windowBits: Integer);\nvar\n  zstream: TZStreamRec;\nbegin\n  FillChar(zstream, SizeOf(TZStreamRec), 0);\n\n  ZDecompressCheck(ZInflateInit2(zstream, windowBits));\n\n  ZInternalDecompressStream(zstream, inStream, outStream);\nend;\n\n{** TCustomZStream ******************************************************************************}\n\nconstructor TCustomZStream.Create(stream: TStream);\nbegin\n  inherited Create;\n\n  FStream := stream;\n  FStreamPos := stream.Position;\nend;\n\nfunction TCustomZStream.StreamRead(var buffer; count: Longint): Longint;\nbegin\n  if FStream.Position <> FStreamPos then FStream.Position := FStreamPos;\n\n  result := FStream.Read(buffer,count);\n\n  FStreamPos := FStreamPos + result;\nend;\n\nfunction TCustomZStream.StreamWrite(const buffer; count: Longint): Longint;\nbegin\n  if FStream.Position <> FStreamPos then FStream.Position := FStreamPos;\n\n  result := FStream.Write(buffer,count);\n\n  FStreamPos := FStreamPos + result;\nend;\n\nfunction TCustomZStream.StreamSeek(offset: Longint; origin: Word): Longint;\nbegin\n  if FStream.Position <> FStreamPos then FStream.Position := FStreamPos;\n\n  result := FStream.Seek(offset,origin);\n\n  FStreamPos := FStream.Position;\nend;\n\nprocedure TCustomZStream.StreamReadBuffer(var buffer; count: Longint);\nbegin\n  if FStream.Position <> FStreamPos then FStream.Position := FStreamPos;\n\n  FStream.ReadBuffer(buffer,count);\n\n  FStreamPos := FStreamPos + count;\nend;\n\nprocedure TCustomZStream.StreamWriteBuffer(const buffer; count: Longint);\nbegin\n  if FStream.Position <> FStreamPos then FStream.Position := FStreamPos;\n\n  FStream.WriteBuffer(buffer,count);\n\n  FStreamPos := FStreamPos + count;\nend;\n\nprocedure TCustomZStream.DoProgress;\nbegin\n  if Assigned(FOnProgress) then FOnProgress(Self);\nend;\n\nfunction TCustomZStream.GetStreamPosition: TStreamPos;\nbegin\n  result := FStream.Position;\nend;\n\nprocedure TCustomZStream.SetStreamPosition(value: TStreamPos);\nbegin\n  FStream.Position := value;\n  FStreamPos := FStream.Position;\nend;\n\n{** TZCompressionStream *************************************************************************}\n\nconstructor TZCompressionStream.Create(dest: TStream;\n  compressionLevel: TZCompressionLevel);\nbegin\n  inherited Create(dest);\n\n  FZStream.next_out := @FBuffer;\n  FZStream.avail_out := SizeOf(FBuffer);\n\n  ZCompressCheck(ZDeflateInit(FZStream, compressionLevel));\nend;\n\nconstructor TZCompressionStream.Create(dest: TStream;\n  compressionLevel: TZCompressionLevel; windowBits, memLevel: Integer;\n  strategy: TZStrategy);\nbegin\n  inherited Create(dest);\n\n  FZStream.next_out := @FBuffer;\n  FZStream.avail_out := SizeOf(FBuffer);\n\n  ZCompressCheck(ZDeflateInit2(FZStream, compressionLevel, windowBits,\n    memLevel, strategy));\nend;\n\ndestructor TZCompressionStream.Destroy;\nbegin\n  FZStream.next_in := Nil;\n  FZStream.avail_in := 0;\n\n  try\n    while ZCompressCheck(ZDeflate(FZStream, zfFinish)) <> Z_STREAM_END do\n    begin\n      StreamWriteBuffer(FBuffer, SizeOf(FBuffer) - FZStream.avail_out);\n\n      FZStream.next_out := @FBuffer;\n      FZStream.avail_out := SizeOf(FBuffer);\n    end;\n\n    if FZStream.avail_out < SizeOf(FBuffer) then\n    begin\n      StreamWriteBuffer(FBuffer, SizeOf(FBuffer) - FZStream.avail_out);\n    end;\n  finally\n    ZDeflateEnd(FZStream);\n  end;\n\n  inherited Destroy;\nend;\n\nfunction TZCompressionStream.Read(var buffer; count: Longint): Longint;\nbegin\n  raise EZCompressionError.Create(SZInvalid);\nend;\n\nfunction TZCompressionStream.Write(const buffer; count: Longint): Longint;\nvar\n  writeCount: Longint;\nbegin\n  result := count;\n\n  FZStream.next_in := @buffer;\n  FZStream.avail_in := count;\n\n  while FZStream.avail_in > 0 do\n  begin\n    ZCompressCheck(ZDeflate(FZStream, zfNoFlush));\n\n    if FZStream.avail_out = 0 then\n    begin\n      writeCount := StreamWrite(FBuffer,SizeOf(FBuffer));\n\n      if writeCount = SizeOf(FBuffer) then\n      begin\n        FZStream.next_out := @FBuffer;\n        FZStream.avail_out := SizeOf(FBuffer);\n\n        DoProgress;\n      end\n      else\n      begin\n        StreamPosition := StreamPosition - writeCount;\n\n        result := Cardinal(count) - FZStream.avail_in;\n\n        FZStream.avail_in := 0;\n      end;\n    end;\n  end;\nend;\n\nfunction TZCompressionStream.Seek(offset: Longint; origin: Word): Longint;\nbegin\n  if (offset = 0) and (origin = soFromCurrent) then\n  begin\n    result := FZStream.total_in;\n  end\n  else raise EZCompressionError.Create(SZInvalid);\nend;\n\nfunction TZCompressionStream.GetCompressionRate: Single;\nbegin\n  if FZStream.total_in = 0 then result := 0\n  else result := (1.0 - (FZStream.total_out / FZStream.total_in)) * 100.0;\nend;\n\n{** TZDecompressionStream ***********************************************************************}\n\nconstructor TZDecompressionStream.Create(source: TStream);\nbegin\n  inherited Create(source);\n\n  FZStream.next_in := @FBuffer;\n  FZStream.avail_in := 0;\n\n  ZDecompressCheck(ZInflateInit(FZStream));\nend;\n\nconstructor TZDecompressionStream.Create(source: TStream;\n  windowBits: Integer);\nbegin\n  inherited Create(source);\n\n  FZStream.next_in := @FBuffer;\n  FZStream.avail_in := 0;\n\n  ZDecompressCheck(ZInflateInit2(FZStream, windowBits));\nend;\n\ndestructor TZDecompressionStream.Destroy;\nbegin\n  ZInflateEnd(FZStream);\n\n  inherited Destroy;\nend;\n\nfunction TZDecompressionStream.Read(var buffer; count: Longint): Longint;\nvar\n  zresult: Integer;\nbegin\n  FZStream.next_out := @buffer;\n  FZStream.avail_out := count;\n\n  zresult := Z_OK;\n\n  while (FZStream.avail_out > 0) and (zresult <> Z_STREAM_END) do\n  begin\n    if FZStream.avail_in = 0 then\n    begin\n      FZStream.avail_in := StreamRead(FBuffer,SizeOf(FBuffer));\n\n      if FZStream.avail_in = 0 then\n      begin\n        result := Cardinal(count) - FZStream.avail_out;\n\n        Exit;\n      end;\n\n      FZStream.next_in := @FBuffer;\n\n      DoProgress;\n    end;\n\n    zresult := ZDecompressCheck(ZInflate(FZStream, zfNoFlush));\n  end;\n\n  if (zresult = Z_STREAM_END) and (FZStream.avail_in > 0) then\n  begin\n    StreamPosition := StreamPosition - FZStream.avail_in;\n\n    FZStream.avail_in := 0;\n  end;\n\n  result := Cardinal(count) - FZStream.avail_out;\nend;\n\nfunction TZDecompressionStream.Write(const Buffer; Count: Longint): Longint;\nbegin\n  raise EZDecompressionError.Create(SZInvalid);\nend;\n\nfunction TZDecompressionStream.Seek(Offset: Longint; Origin: Word): Longint;\nvar\n  buf: Array [0..8191] of Byte;\n  i  : Integer;\nbegin\n  if (offset = 0) and (origin = soFromBeginning) then\n  begin\n    ZDecompressCheck(ZInflateReset(FZStream));\n\n    FZStream.next_in := @FBuffer;\n    FZStream.avail_in := 0;\n\n    StreamPosition := 0;\n  end\n  else if ((offset >= 0) and (origin = soFromCurrent)) or\n          (((Cardinal(offset) - FZStream.total_out) > 0) and (origin = soFromBeginning)) then\n  begin\n    if origin = soFromBeginning then Dec(offset, FZStream.total_out);\n\n    if offset > 0 then\n    begin\n      for i := 1 to offset div SizeOf(buf) do ReadBuffer(buf, SizeOf(buf));\n      ReadBuffer(buf, offset mod SizeOf(buf));\n    end;\n  end\n  else if (offset = 0) and (origin = soFromEnd) then\n  begin\n    while Read(buf, SizeOf(buf)) > 0 do ;\n  end\n  else raise EZDecompressionError.Create(SZInvalid);\n\n  result := FZStream.total_out;\nend;\n\n{** TZCustomBuffer ******************************************************************************}\n\nconstructor TZCustomBuffer.Create;\nbegin\n  inherited Create;\n\n  FillChar(FZStream, SizeOf(TZStreamRec), 0);\n\n  FBuffer := Nil;\n  FBufferCapacity := 0;\n\n  FBufferSize := 0;\nend;\n\ndestructor TZCustomBuffer.Destroy;\nbegin\n  BufferCapacity(0);\n\n  inherited Destroy;\nend;\n\nprocedure TZCustomBuffer.Clear;\nbegin\n  BufferCapacity(0);\n\n  FBufferSize := 0;\nend;\n\nprocedure TZCustomBuffer.Flush(flush: TZFlush);\nbegin\n  // to be implemented by descendents as needed\nend;\n\nfunction TZCustomBuffer.Write(const s: AnsiString): Integer;\nbegin\n  result := Write(Pointer(s), Length(s));\nend;\n\nfunction TZCustomBuffer.Read(var buffer: Pointer; size: Integer): Integer;\nbegin\n  result := BufferSize;\n  if size < result then result := size;\n\n  BufferRead(buffer, result);\nend;\n\nfunction TZCustomBuffer.Read(var s: AnsiString): Integer;\nbegin\n  SetLength(s, BufferSize);\n\n  result := Read(Pointer(s), Length(s));\nend;\n\nprocedure TZCustomBuffer.BufferWrite(const buffer: Pointer; size: Integer);\nbegin\n  if size > 0 then\n  begin\n    BufferCapacity(FBufferSize + size);\n\n    Move(buffer^, Pointer(Integer(FBuffer) + FBufferSize)^, size);\n\n    Inc(FBufferSize, size);\n  end;\nend;\n\nprocedure TZCustomBuffer.BufferRead(var buffer: Pointer; size: Integer);\nbegin\n  if size > 0 then\n  begin\n    Move(FBuffer^, buffer^, size);\n\n    Move(Pointer(Integer(FBuffer) + size)^, FBuffer^, FBufferSize - size);\n\n    Dec(FBufferSize, size);\n  end;\nend;\n\nprocedure TZCustomBuffer.BufferCapacity(capacity: Integer);\nconst\n  delta = 8192; // must be a power of 2\nbegin\n  if capacity > 0 then\n  begin\n    capacity := (capacity + (delta - 1)) and not (delta - 1);\n  end;\n\n  if FBufferCapacity <> capacity then\n  begin\n    if capacity = 0 then FreeMem(FBuffer)\n    else if FBufferCapacity = 0 then GetMem(FBuffer, capacity)\n    else ReallocMem(FBuffer, capacity);\n\n    FBufferCapacity := capacity;\n  end;\nend;\n\n{** TZCompressionBuffer *************************************************************************}\n\nconstructor TZCompressionBuffer.Create(level: TZCompressionLevel);\nbegin\n  inherited Create;\n\n  ZCompressCheck(ZDeflateInit(FZStream, level));\nend;\n\nconstructor TZCompressionBuffer.Create(level: TZCompressionLevel;\n  windowBits, memLevel: Integer; strategy: TZStrategy);\nbegin\n  inherited Create;\n\n  ZCompressCheck(ZDeflateInit2(FZStream, level, windowBits, memLevel,\n    strategy));\nend;\n\ndestructor TZCompressionBuffer.Destroy;\nbegin\n  ZCompressCheck(ZDeflateEnd(FZStream));\n\n  inherited Destroy;\nend;\n\nprocedure TZCompressionBuffer.Clear;\nbegin\n  inherited Clear;\n\n  ZCompressCheck(ZDeflateReset(FZStream));\nend;\n\nprocedure TZCompressionBuffer.Flush(flush: TZFlush);\nconst\n  outSize = 32768;\nvar\n  zresult  : Integer;\n  outBuffer: Array [0..outSize - 1] of Byte;\n  outCount : Integer;\nbegin\n  FZStream.next_in := Nil;\n  FZStream.avail_in := 0;\n\n  repeat\n    FZStream.next_out := @outBuffer;\n    FZStream.avail_out := outSize;\n\n    zresult := ZCompressCheck(ZDeflate(FZStream, flush));\n\n    outCount := outSize - FZStream.avail_out;\n\n    BufferWrite(@outBuffer, outCount);\n  until (zresult = Z_STREAM_END) or (FZStream.avail_out > 0);\nend;\n\nfunction TZCompressionBuffer.Write(const buffer: Pointer;\n  size: Integer): Integer;\nconst\n  outSize = 32768;\nvar\n  zresult  : Integer;\n  outBuffer: Array [0..outSize - 1] of Byte;\n  outCount : Integer;\nbegin\n  zresult := Z_OK;\n\n  FZStream.next_in := buffer;\n  FZStream.avail_in := size;\n\n  while (zresult <> Z_STREAM_END) and (FZStream.avail_in > 0) do\n  begin\n    repeat\n      FZStream.next_out := @outBuffer;\n      FZStream.avail_out := outSize;\n\n      zresult := ZCompressCheck(ZDeflate(FZStream, zfNoFlush));\n\n      outCount := outSize - FZStream.avail_out;\n\n      BufferWrite(@outBuffer, outCount);\n    until (zresult = Z_STREAM_END) or (FZStream.avail_out > 0);\n  end;\n\n  result := Cardinal(size) - FZStream.avail_in;\nend;\n\n{** TZDecompressionBuffer ***********************************************************************}\n\nconstructor TZDecompressionBuffer.Create;\nbegin\n  inherited Create;\n\n  ZDecompressCheck(ZInflateInit(FZStream));\nend;\n\nconstructor TZDecompressionBuffer.Create(windowBits: Integer);\nbegin\n  inherited Create;\n\n  ZDecompressCheck(ZInflateInit2(FZStream, windowBits));\nend;\n\ndestructor TZDecompressionBuffer.Destroy;\nbegin\n  ZDecompressCheck(ZInflateEnd(FZStream));\n\n  inherited Destroy;\nend;\n\nprocedure TZDecompressionBuffer.Clear;\nbegin\n  inherited Clear;\n\n  ZDecompressCheck(ZInflateReset(FZStream));\nend;\n\nfunction TZDecompressionBuffer.Write(const buffer: Pointer;\n  size: Integer): Integer;\nconst\n  outSize = 32768;\nvar\n  zresult  : Integer;\n  outBuffer: Array [0..outSize - 1] of Byte;\n  outCount : Integer;\nbegin\n  zresult := Z_OK;\n\n  FZStream.next_in := buffer;\n  FZStream.avail_in := size;\n\n  while (zresult <> Z_STREAM_END) and (FZStream.avail_in > 0) do\n  begin\n    repeat\n      FZStream.next_out := @outBuffer;\n      FZStream.avail_out := outSize;\n\n      zresult := ZDecompressCheck(ZInflate(FZStream, zfNoFlush), False);\n\n      outCount := outSize - FZStream.avail_out;\n\n      BufferWrite(@outBuffer, outCount);\n    until (zresult = Z_STREAM_END) or (FZStream.avail_out > 0);\n  end;\n\n  result := Cardinal(size) - FZStream.avail_in;\nend;\n\n{** EZLibError **********************************************************************************}\n\nconstructor EZLibError.Create(code: Integer; const dummy: String);\nbegin\n  inherited Create(z_errmsg[2 - code]);\n\n  FErrorCode := code;\nend;\n\nconstructor EZLibError.Create(error: TZError; const dummy: String);\nbegin\n  Create(ZErrors[error], dummy);\nend;\n\nprocedure DecompressToUserBuf(const InBuf: Pointer; InBytes: Integer;\n  const OutBuf: Pointer; BufSize: Integer);\nvar\n  strm: TZStreamRec;\nbegin\n  FillChar(strm, sizeof(strm), 0);\n//  strm.zalloc := zlibAllocMem;\n//  strm.zfree := zlibFreeMem;\n  strm.next_in := InBuf;\n  strm.avail_in := InBytes;\n  strm.next_out := OutBuf;\n  strm.avail_out := BufSize;\n  DCheck(inflateInit_(strm, zlib_version, sizeof(strm)));\n  try\n    if DCheck(inflate(strm, Z_FINISH)) <> Z_STREAM_END then\n      raise EZlibError.CreateRes(64672);\n  finally\n    DCheck(inflateEnd(strm));\n  end;\nend;\n\nend.\n"
  },
  {
    "path": "lib/zeosdbo/doc/html/bugreporting.html",
    "content": "\n<!DOCTYPE html\n  PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">\n<html xmlns=\"http://www.w3.org/1999/xhtml\"><head>\n      <meta http-equiv=\"Content-Type\" content=\"text/html; charset=iso-8859-1\">\n   <title>Bug Reporting in ZEOS Library</title><link rel=\"stylesheet\" href=\"ede.css\" type=\"text/css\"><meta name=\"generator\" content=\"DocBook XSL Stylesheets V1.66.0\"><meta name=\"description\" content=\"&#xA;  (By Mark Daems, 29 May 2008) This Article is somewhat outdated as it describes some project organisational structures. (eg. QA group) This structure isn't available anymore. However, most observations concerning what a good bug report is still apply.&#xA; &#xA;  The currect bug reporting procedure is absolutely critical to improve&#xA;  the quality of ZEOS. It defines steps to fix bugs, to notify the reported&#xA;  user about the change and update the test harness to ensure the bug will&#xA;  never happen again. Unfortunately in free ware projets it's hard to maintain&#xA;  good test coverage. The Bug Report procedure allows to improve the test&#xA;  coverage and to increase the stability of the Libary afterward, when the code is&#xA;  written and released. It relieves developers because writing tests is partially&#xA;  moved to responsibilities of QA group.&#xA;  \"></head><body><div xmlns=\"\" id=\"customheader\"><a href=\"http://zeos.firmos.at/portal.php\" style=\"color: #fff; font-weight: bold;\">ZeosLib</a><b> - open source tools for your database solutions</b></div><div class=\"article\" lang=\"en\"><div class=\"titlepage\"><div><div><h1 class=\"title\"><a id=\"d4e1\"></a>Bug Reporting in ZEOS Library</h1></div><div><div class=\"author\"><h3 class=\"author\"><span class=\"firstname\">Michael</span> <span class=\"surname\">Seeger</span></h3></div></div><div><div class=\"abstract\"><p class=\"title\"><b>Abstract</b></p><p>\n  <div class=\"warning\" style=\"margin-left: 0.5in; margin-right: 0.5in;\"><table border=\"0\" summary=\"Warning\"><tr><td rowspan=\"2\" align=\"center\" valign=\"top\" width=\"25\"><img alt=\"[Warning]\" src=\"images/warning.png\"></td><th align=\"left\">Warning</th></tr><tr><td colspan=\"2\" align=\"left\" valign=\"top\"><p>(By Mark Daems, 29 May 2008) This Article is somewhat outdated as it describes some project organisational structures. (eg. QA group) This structure isn't available anymore. However, most observations concerning what a good bug report is still apply.</p></td></tr></table></div>\n</p><p>\n  The currect bug reporting procedure is absolutely critical to improve\n  the quality of ZEOS. It defines steps to fix bugs, to notify the reported\n  user about the change and update the test harness to ensure the bug will\n  never happen again. Unfortunately in free ware projets it's hard to maintain\n  good test coverage. The Bug Report procedure allows to improve the test\n  coverage and to increase the stability of the Libary afterward, when the code is\n  written and released. It relieves developers because writing tests is partially\n  moved to responsibilities of QA group.\n  </p></div></div></div><hr></div><div class=\"toc\"><p><b>Table of Contents</b></p><dl><dt><span class=\"section\"><a href=\"#Recommendation\">1. Recommendation to a Bug Report</a></span></dt><dt><span class=\"section\"><a href=\"#FixingProcedure\">2. Bug Fixing Proecedure</a></span></dt><dt><span class=\"section\"><a href=\"#FixingText\">3. Bug Fixing Test</a></span></dt><dt><span class=\"section\"><a href=\"#SampleBRTestCase\">4. Sample Bug Report Testcase</a></span></dt></dl></div><div class=\"section\" lang=\"en\"><div class=\"titlepage\"><div><div><h2 class=\"title\" style=\"clear: both\"><a id=\"Recommendation\"></a>1.&nbsp;Recommendation to a Bug Report</h2></div></div></div><p>\n  A \"valid\" bug report has to contain the following informations:\n  </p><div class=\"itemizedlist\"><ul type=\"disc\"><li><p>Database server and server version</p></li><li><p>Version of used components</p></li><li><p>Name component or class that raised the error</p></li><li><p>Information about user properties for components and/or classes</p></li><li><p>Exact description of the error</p></li><li><p>Sql query and table(s) structure and table(s) data for user specified table(s)</p></li></ul></div><p>\n  If it is necessary and possible the user may be asked for a sample application that\n  reproduces the error\n  </p></div><div class=\"section\" lang=\"en\"><div class=\"titlepage\"><div><div><h2 class=\"title\" style=\"clear: both\"><a id=\"FixingProcedure\"></a>2.&nbsp;Bug Fixing Proecedure</h2></div></div></div><div class=\"orderedlist\"><ol type=\"1\"><li><p>User submits a bug report on SourceForge Bug Tracker.</p></li><li><p>\n  Elaborate information about the bug and close the bug if it has no sense.\n  Notify the user about the action taken and exlain why this was done\n  (performed by QA Group)\n  </p></li><li><p>\n  Implement a Bug Report Test Case which relicates the problem (performed by\n  QA Group)\n  </p></li><li><p>Switch the bug to the responsible developer</p></li><li><p>\n  Fix the bug. Document yor changes in sourcecode, carefully! (performed by\n  responsible developer)\n  </p></li><li><p>\n  Fill out the bug report e-Form and document your doings, carefully!\n  The given Template (bug_report_form.txt has to be saved as <tt class=\"filename\">\n  BugID.txt</tt> where <tt class=\"filename\">ID</tt> means the Bug's\n  ID from the SourceForge Bug Tracker.\n  </p></li><li><p>\n  Close the bug report and notify the user about the changes done (if possible)\n  and mention when it will be officially released (performed by responsible\n  developer)\n  </p></li></ol></div></div><div class=\"section\" lang=\"en\"><div class=\"titlepage\"><div><div><h2 class=\"title\" style=\"clear: both\"><a id=\"FixingText\"></a>3.&nbsp;Bug Fixing Test</h2></div></div></div><p>\n  Bug Report Tests is a special category of tests it is obvious that bugs may\n  happen in all groups of finctional tests described before. From that p\n  erspective Bug Report Tests should repeat the hierarchy of functional tests:\n  </p><p>\n  <div class=\"orderedlist\"><ol type=\"1\"><li><p>TZAbstractBugReportTestCase - a base abstract class for Bug Report Tests.</p></li><li><p>\n  TZGenericBugReport, TZPortableSQLBugReport and TZSpecificSQLBugReport - abstract\n  classes for \"Generic\", \"SQL Prtable\" and \"SQL Specific\" tests.\n  </p></li><li><p>\n  TZCompPortableSQLBugReport, TZCompMySQLBugReport, TZCompInterbaseBugReport,\n  TZDbcPortableSQLBugReport, TZDbcMySQLBugReport, TZDbcInterbaseBugReport, etc. -\n  specific test cases.\n  </p></li></ol></div>\n  </p><p>\n  For Bug Report Test cases we set a convention to name test methodes as \"Test\" + ID, where\n  ID is a unique number of associated bug report in Bug Tracker on SourceForge. That convention\n  allows us to do following things:\n  </p><p>\n  <div class=\"orderedlist\"><ol type=\"1\"><li><p>Enforce creation of bug repot for each found bug.</p></li><li><p>Easy navigate between bug reports and related test cases.</p></li><li><p>\n  TZCompPortableSQLBugReport, TZCompMySQLBugReport, TZCompInterbaseBugReport,\n  TZDbcPortableSQLBugReport, TZDbcMySQLBugReport, TZDbcInterbaseBugReport, etc. -\n  specific test cases.\n  </p></li></ol></div>\n  </p><p>\n  During bug fixing developer usually have to run a specific test case many times.\n  To speed up the process we added to TZAbstractBugReportTestCase class a convenient\n  function called SkipClosed. If SkipClosed property ist set to true for \"bugreport\"\n  category in configuration file, SkipClosed returns true and allows to skip\n  completed tests for fixed bugs. It dramatically decreases number of tests to run\n  and makes developer's vork much more productive.\n  </p></div><div class=\"section\" lang=\"en\"><div class=\"titlepage\"><div><div><h2 class=\"title\" style=\"clear: both\"><a id=\"SampleBRTestCase\"></a>4.&nbsp;Sample Bug Report Testcase</h2></div></div></div><p>\n  <pre class=\"programlisting\">\n  UNIT ZTestCompCore;\n  &nbsp;\n  INTERFACE\n  &nbsp;\n  {$I ZBugReport.inc}\n  &nbsp;\n  USES Classed, DB, TestFramework, ZDataset, ZConnection, ZDbcIntfs, ZBugReport,\n       ZCompatibility, ZSqlUpdate, ZSqlProcessor;\n  &nbsp;\n  TYPE ZTestCompCoreBugReport = class (TZPortableSQLBugReportTestCase)\n          :\n          published\n             :\n             Procedure Test833197;\n             :\n       End;\n  &nbsp;\n  IMPLEMENTATION\n  &nbsp;\n  :\n  &nbsp;\n  {** Bugreport #833197:\n  Refresh problem with filtered data. }\n  &nbsp;\n  Procedure ZTestCompCoreBugReport.Test833197;\n  Var Connection: TZConnection;\n      Query     : TZQuery;\n  Begin\n     If SkipClosed Then Exit;\n     &nbsp;\n     Connection       := Self.CreateDatasetConnection;\n     Query            := TZQuery.Create (nil);\n     Query.Connection := Connection;\n     Query.SQL.Text   := 'SELECT * FROM poeple';\n     &nbsp;\n     Try\n        Query.Open;\n        Query.Filter   := 'p_name = \"Aleksey Petrov\"';\n        Query.Filtered := True;\n        CheckEquals (1, Query.RecordCount);\n        Query.Refresh;\n        CheckEquals (1, Query.RecordCount);\n        Query.Close;\n     Finally\n        Connection.Free;\n        Query.Free;\n     End;\n  End; // Test833197\n  &nbsp;\n  :\n  &nbsp;\n  INITIALIZATION\n  &nbsp;\n     TestFramework.RegisterTest (ZTestCompCoreBugReort.Suite);\n  &nbsp;\n  End.\n  </pre>\n  </p></div></div><div xmlns=\"\" id=\"customfooter\">\n(c) 1999 - 2006 The Zeos Development Group\n</div></body></html>"
  },
  {
    "path": "lib/zeosdbo/doc/html/buildingtests.html",
    "content": "\n<!DOCTYPE html\n  PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">\n<html xmlns=\"http://www.w3.org/1999/xhtml\"><head>\n      <meta http-equiv=\"Content-Type\" content=\"text/html; charset=iso-8859-1\">\n   <title>Building Tests for the ZEOS Library</title><link rel=\"stylesheet\" href=\"ede.css\" type=\"text/css\"><meta name=\"generator\" content=\"DocBook XSL Stylesheets V1.66.0\"><meta name=\"description\" content=\"&#xA;  This document describes how to set up the ZEOS Build &amp; Test environment&#xA;  and shows how to compile gui and console based test applications to test&#xA;  the ZEOSLib code. It also describes the setup that has to be made for&#xA;  testing the library with various databases.&#xA;  \"></head><body><div xmlns=\"\" id=\"customheader\"><a href=\"http://zeos.firmos.at/portal.php\" style=\"color: #fff; font-weight: bold;\">ZeosLib</a><b> - open source tools for your database solutions</b></div><div class=\"article\" lang=\"en\"><div class=\"titlepage\"><div><div><h1 class=\"title\"><a id=\"d4e1\"></a>Building Tests for the ZEOS Library</h1></div><div><div class=\"author\"><h3 class=\"author\"><span class=\"firstname\">Michael</span> <span class=\"surname\">Seeger</span></h3><tt class=\"email\">&lt;<a href=\"mailto:miseeger*at*users*dot*sourceforge*dot*net\">miseeger*at*users*dot*sourceforge*dot*net</a>&gt;</tt></div></div><div><div class=\"abstract\"><p class=\"title\"><b>Abstract</b></p><p>\n  This document describes how to set up the ZEOS Build &amp; Test environment\n  and shows how to compile gui and console based test applications to test\n  the ZEOSLib code. It also describes the setup that has to be made for\n  testing the library with various databases.\n  </p></div></div></div><hr></div><div class=\"toc\"><p><b>Table of Contents</b></p><dl><dt><span class=\"section\"><a href=\"#BTReqirements\">1. Requirements to build ZEOSLib tests</a></span></dt><dt><span class=\"section\"><a href=\"#BTConfig\">2. Build &amp; Test Configuration</a></span></dt><dt><span class=\"section\"><a href=\"#DBConfig\">3. Database Configuration</a></span></dt><dt><span class=\"section\"><a href=\"#Compiling\">4. Compiling Tests</a></span></dt><dt><span class=\"section\"><a href=\"#Running\">5. Running Tests</a></span></dt></dl></div><div class=\"section\" lang=\"en\"><div class=\"titlepage\"><div><div><h2 class=\"title\" style=\"clear: both\"><a id=\"BTReqirements\"></a>1.&nbsp;Requirements to build ZEOSLib tests</h2></div></div></div><p>\n  In order to run the tests for the ZEOSLib you have to be sure that you have\n  insalled the following software on your system:\n  </p><div class=\"itemizedlist\"><ul type=\"disc\"><li><p>Delphi Compiler / IDE (min. professional versions 5, 6, 7 or 2005)</p></li><li><p>DUnit Xtreme testing framework for Delphi  [<a href=\"http://dunit.sourceforge.net\" target=\"_top\">\n  Homepage</a> | <a href=\"https://sourceforge.net/projects/dunit\" target=\"_top\">\n  Download Page</a>]\n  </p></li><li><p>Java Runtime Environment or SDK (Version 1.4.2)  [<a href=\"http://java.sun.com\" target=\"_top\">Homepage</a> |\n  <a href=\"http://java.sun.com/j2se/1.4.2/download.htm\" target=\"_top\">Download Page</a>]\n  </p></li><li><p>Jakarta Ant  [<a href=\"http://ant.apache.org\" target=\"_top\">Download Page</a> |\n  <a href=\"http://ant.apache.org/bindownload.cgi\" target=\"_top\">Download Page</a>]\n  </p></li><li><p>The supported SQL Servers you want to test with</p></li></ul></div><p>\n  Make sure that the environment variable JAVA_HOME is set to the directory\n  where you installed the Java Runtine or SDK (e. g. JAVA_HOME = c:\\java\\j2sdk1.4.2_06).\n  </p><p>\n  Also set the environment variable ANT_HOME to the directory where you installed\n  Jakarta ANT (e. g. ANT_HOME = C:\\Programs\\ANT).\n  </p></div><div class=\"section\" lang=\"en\"><div class=\"titlepage\"><div><div><h2 class=\"title\" style=\"clear: both\"><a id=\"BTConfig\"></a>2.&nbsp;Build &amp; Test Configuration</h2></div></div></div><div class=\"toc\"><dl><dt><span class=\"section\"><a href=\"#BTConfigCommon\">2.1. Common Section</a></span></dt><dt><span class=\"section\"><a href=\"#BTConfigCompilers\">2.2. Compiler Section</a></span></dt><dt><span class=\"section\"><a href=\"#BTConfigTests\">2.3. Tests Section</a></span></dt></dl></div><p>\n  Before you are able to start compiling the ZEOS test applications you have to\n  configure the compiler environment. All settings for compiling building and\n  testing are stored in a file called build.properties. To get this file just\n  copy the build_template.properties file in build directory and name it\n  build.properties. The build.properties file has four sections that are important\n  for compiling the test applications: \"common\" and \"compilers\". There is another\n  section that determines which tests will be executed by calling test.cmd batchfile.\n  This section is not important for compiling tests but it will also be documented.\n  </p><p>\n  In a Windows environment it is recommended that you use double backslash as\n  directory  separator. \"Normal\" slash will work but causes some problems in a\n  Delphi 9 environment. In a Unix / Linux environment it is recommended use\n  the \"normal\" slash as direcrory separator.\n  </p><div class=\"section\" lang=\"en\"><div class=\"titlepage\"><div><div><h3 class=\"title\"><a id=\"BTConfigCommon\"></a>2.1.&nbsp;Common Section</h3></div></div></div><p>\n  The first section is the common-section it contains common informations for\n  building the test applications:\n  </p><pre class=\"programlisting\">\n  [common]\n  project.home=d:/workshop/zeosdbo_rework <a id=\"ph\"></a><img src=\"images/callouts/1.png\" alt=\"1\" border=\"0\">\n  release.version =6.5.2-beta  <a id=\"rv\"></a><img src=\"images/callouts/2.png\" alt=\"2\" border=\"0\">\n  copy.verbose=false <a id=\"cv\"></a><img src=\"images/callouts/3.png\" alt=\"3\" border=\"0\">\n  dunit.dir=d:/programme/borland/delphi7/dunit/src <a id=\"dd\"></a><img src=\"images/callouts/4.png\" alt=\"4\" border=\"0\">\n  kunit.dir= <a id=\"kd\"></a><img src=\"images/callouts/5.png\" alt=\"5\" border=\"0\">\n  </pre><div class=\"calloutlist\"><table border=\"0\" summary=\"Callout list\"><tr><td width=\"5%\" valign=\"top\" align=\"left\"><a href=\"#ph\"><img src=\"images/callouts/1.png\" alt=\"1\" border=\"0\"></a> </td><td valign=\"top\" align=\"left\"><p>The project directory</p></td></tr><tr><td width=\"5%\" valign=\"top\" align=\"left\"><a href=\"#rv\"><img src=\"images/callouts/2.png\" alt=\"2\" border=\"0\"></a> </td><td valign=\"top\" align=\"left\"><p>The version number of the ZEOSLib (put into version file).</p></td></tr><tr><td width=\"5%\" valign=\"top\" align=\"left\"><a href=\"#cv\"><img src=\"images/callouts/3.png\" alt=\"3\" border=\"0\"></a> </td><td valign=\"top\" align=\"left\"><p>Determines whether copy operations shall displayed on screen.</p></td></tr><tr><td width=\"5%\" valign=\"top\" align=\"left\"><a href=\"#dd\"><img src=\"images/callouts/4.png\" alt=\"4\" border=\"0\"></a> </td><td valign=\"top\" align=\"left\"><p>The source directory of DUnit.</p></td></tr><tr><td width=\"5%\" valign=\"top\" align=\"left\"><a href=\"#kd\"><img src=\"images/callouts/5.png\" alt=\"5\" border=\"0\"></a> </td><td valign=\"top\" align=\"left\"><p>The source directory of DUnit (for Kylix).</p></td></tr></table></div></div><div class=\"section\" lang=\"en\"><div class=\"titlepage\"><div><div><h3 class=\"title\"><a id=\"BTConfigCompilers\"></a>2.2.&nbsp;Compiler Section</h3></div></div></div><p>\n  The second section is the compiler-section it contains informations about the\n  active compilers to use for building the test applications. Each supported\n  compiler has its own \"section\". It describes wether the compiler (prefix of\n  the key (e. g. \"delphi5\")) is active and determines the installation directory\n  of the compiler.\n  </p><pre class=\"programlisting\">\n  [compilers]\n  delphi5.active=false <a id=\"da\"></a><img src=\"images/callouts/1.png\" alt=\"1\" border=\"0\">\n  delphi5.home=C:/Program Files/Borland/Delphi5 <a id=\"dh\"></a><img src=\"images/callouts/2.png\" alt=\"2\" border=\"0\">\n  :\n  delphi9.active=true\n  delphi9.home=d:\\\\programme\\\\borland\\\\bds\\\\3.0\n  delphi9.bpl.dir=c:\\\\dokumente und einstellungen\\\\user\\\\eigene dateien\\\\borland studio-projekte\\\\bpl <a id=\"bd\"></a><img src=\"images/callouts/3.png\" alt=\"3\" border=\"0\">\n  :\n  kylix3.active=false <a id=\"ks\"></a><img src=\"images/callouts/4.png\" alt=\"4\" border=\"0\">\n  kylix3.home=/opt/kylix3\n  </pre><div class=\"calloutlist\"><table border=\"0\" summary=\"Callout list\"><tr><td width=\"5%\" valign=\"top\" align=\"left\"><a href=\"#da\"><img src=\"images/callouts/1.png\" alt=\"1\" border=\"0\"></a> </td><td valign=\"top\" align=\"left\"><p>\"true\" if the compiler is installed (active), \"false\" if not.\n  </p></td></tr><tr><td width=\"5%\" valign=\"top\" align=\"left\"><a href=\"#dh\"><img src=\"images/callouts/2.png\" alt=\"2\" border=\"0\"></a> </td><td valign=\"top\" align=\"left\"><p>The installation path of the compiler (here: Delphi 5).</p></td></tr><tr><td width=\"5%\" valign=\"top\" align=\"left\"><a href=\"#bd\"><img src=\"images/callouts/3.png\" alt=\"3\" border=\"0\"></a> </td><td valign=\"top\" align=\"left\"><p>Special for Delhi 9: you have to specify your BPL-dir because in Delphi 9\n  the standardized ...\\projects\\bpl doesn't exist anymore (here: german\n  Delphi / WinXP example).\n  </p></td></tr><tr><td width=\"5%\" valign=\"top\" align=\"left\"><a href=\"#ks\"><img src=\"images/callouts/4.png\" alt=\"4\" border=\"0\"></a> </td><td valign=\"top\" align=\"left\"><p>Kylix 3 settings for compilation (Kylix 3 is not installed this is why\n  kylix3.active=false)\n  </p></td></tr></table></div></div><div class=\"section\" lang=\"en\"><div class=\"titlepage\"><div><div><h3 class=\"title\"><a id=\"BTConfigTests\"></a>2.3.&nbsp;Tests Section</h3></div></div></div><p>\n  This section is necessary to determine which tests will be run when executing\n  the test.cmd batchfile (only makes sense when compiling the test applications\n  as console applications).\n  </p><pre class=\"programlisting\">\n  [tests]\n  test.core=true <a id=\"tc\"></a><img src=\"images/callouts/1.png\" alt=\"1\" border=\"0\">\n  test.parsesql=true <a id=\"tp\"></a><img src=\"images/callouts/2.png\" alt=\"2\" border=\"0\">\n  test.dbc=true <a id=\"td\"></a><img src=\"images/callouts/3.png\" alt=\"3\" border=\"0\">\n  test.component=true <a id=\"tco\"></a><img src=\"images/callouts/4.png\" alt=\"4\" border=\"0\">\n  test.bugreport=true <a id=\"tb\"></a><img src=\"images/callouts/5.png\" alt=\"5\" border=\"0\">\n  test.performance=false <a id=\"tperf\"></a><img src=\"images/callouts/6.png\" alt=\"6\" border=\"0\">\n  </pre><div class=\"calloutlist\"><table border=\"0\" summary=\"Callout list\"><tr><td width=\"5%\" valign=\"top\" align=\"left\"><a href=\"#tc\"><img src=\"images/callouts/1.png\" alt=\"1\" border=\"0\"></a> </td><td valign=\"top\" align=\"left\"><p>Execute core tests if set to \"true\".</p></td></tr><tr><td width=\"5%\" valign=\"top\" align=\"left\"><a href=\"#tp\"><img src=\"images/callouts/2.png\" alt=\"2\" border=\"0\"></a> </td><td valign=\"top\" align=\"left\"><p>Execute parsing tests if set to \"true\".</p></td></tr><tr><td width=\"5%\" valign=\"top\" align=\"left\"><a href=\"#td\"><img src=\"images/callouts/3.png\" alt=\"3\" border=\"0\"></a> </td><td valign=\"top\" align=\"left\"><p>Execute connectivity tests if set to \"true\".</p></td></tr><tr><td width=\"5%\" valign=\"top\" align=\"left\"><a href=\"#tco\"><img src=\"images/callouts/4.png\" alt=\"4\" border=\"0\"></a> </td><td valign=\"top\" align=\"left\"><p>Execute component tests if set to \"true\".</p></td></tr><tr><td width=\"5%\" valign=\"top\" align=\"left\"><a href=\"#tb\"><img src=\"images/callouts/5.png\" alt=\"5\" border=\"0\"></a> </td><td valign=\"top\" align=\"left\"><p>Execute bug tests if set to \"true\".</p></td></tr><tr><td width=\"5%\" valign=\"top\" align=\"left\"><a href=\"#tperf\"><img src=\"images/callouts/6.png\" alt=\"6\" border=\"0\"></a> </td><td valign=\"top\" align=\"left\"><p>Execute performance tests if set to \"true\".</p></td></tr></table></div></div></div><div class=\"section\" lang=\"en\"><div class=\"titlepage\"><div><div><h2 class=\"title\" style=\"clear: both\"><a id=\"DBConfig\"></a>3.&nbsp;Database Configuration</h2></div></div></div><div class=\"toc\"><dl><dt><span class=\"section\"><a href=\"#DBConfigCommon\">3.1. Common Section</a></span></dt><dt><span class=\"section\"><a href=\"#DBDatabaseConfig\">3.2. Database Settings</a></span></dt></dl></div><p>\n  It is possible to run the ZEOS tests for a number of SQL servers that are\n  currently running on the test machine. Therefor the Build and Test Environment\n  has to be configured.\n  </p><p>\n  Setting up the database parameters is done in the test.properites file that is\n  located in the \"database\" direcory. To get this file just copy the\n  test_template.properties file and rename it to test.properties and then make\n  your settings.\n  </p><p>\n  At the moment we do not execute performance tests so only the common section\n  and the database sections are of importance for testing the ZEOS Library.\n  </p><div class=\"section\" lang=\"en\"><div class=\"titlepage\"><div><div><h3 class=\"title\"><a id=\"DBConfigCommon\"></a>3.1.&nbsp;Common Section</h3></div></div></div><p>\n  The first section is the common-section it contains common informations about\n  the databases to test by test applications:\n  </p><pre class=\"programlisting\">\n  [common]\n  common.connections=sqlite28,firebird15 <a id=\"cc\"></a><img src=\"images/callouts/1.png\" alt=\"1\" border=\"0\">\n  </pre><div class=\"calloutlist\"><table border=\"0\" summary=\"Callout list\"><tr><td width=\"5%\" valign=\"top\" align=\"left\"><a href=\"#tc\"><img src=\"images/callouts/1.png\" alt=\"1\" border=\"0\"></a> </td><td valign=\"top\" align=\"left\"><p>\n  This key holds the active servernames of the SQL servers that will be\n  tested in the test applications. Corresponding to the servers given here\n  there has to exist a \"database section\" with the same name that determines\n  the database settings for testing. The server names for this key have to\n  be seperated by comma.\n  </p></td></tr></table></div></div><div class=\"section\" lang=\"en\"><div class=\"titlepage\"><div><div><h3 class=\"title\"><a id=\"DBDatabaseConfig\"></a>3.2.&nbsp;Database Settings</h3></div></div></div><p>\n  Corresponding to the active servers listed in the common.connections key (here:\n  SQLite 2.8 and Firebird 1.5.x) there are configuration sections that contain the\n  settings for running tests with the given database. Each section consists of the\n  same keys so we will take the Firebird 1.5 database configuration to explain\n  them:\n  </p><pre class=\"programlisting\">\n  [firebird15]\n  firebird15.protocol=firebird-1.5 <a id=\"fbp\"></a><img src=\"images/callouts/1.png\" alt=\"1\" border=\"0\">\n  firebird15.alias=firebird_zeoslib <a id=\"fba\"></a><img src=\"images/callouts/2.png\" alt=\"2\" border=\"0\">\n  firebird15.host=localhost <a id=\"fbh\"></a><img src=\"images/callouts/3.png\" alt=\"3\" border=\"0\">\n  firebird15.port= <a id=\"fbport\"></a><img src=\"images/callouts/4.png\" alt=\"4\" border=\"0\">\n  firebird15.database=d:\\SQLServerFarm\\Firebird\\15\\Data\\zeoslib.fdb <a id=\"fbdb\"></a><img src=\"images/callouts/5.png\" alt=\"5\" border=\"0\">\n  firebird15.user=SYSDBA <a id=\"fbu\"></a><img src=\"images/callouts/6.png\" alt=\"6\" border=\"0\">\n  firebird15.password=masterkey <a id=\"fbpw\"></a><img src=\"images/callouts/7.png\" alt=\"7\" border=\"0\">\n  firebird15.rebuild=yes <a id=\"fbr\"></a><img src=\"images/callouts/8.png\" alt=\"8\" border=\"0\">\n  firebird15.delimiter.type=SetTerm <a id=\"fbdt\"></a><img src=\"images/callouts/9.png\" alt=\"9\" border=\"0\">\n  firebird15.delimiter=; <a id=\"fbdel\"></a><img src=\"images/callouts/10.png\" alt=\"10\" border=\"0\">\n  firebird15.create.scripts=create_interbase.sql,populate_any.sql,populate_interbase.sql,create_interbase_bugreport.sql <a id=\"fbcdbo\"></a>(11)\n  firebird15.drop.scripts=drop_interbase.sql,drop_interbase_bugreport.sql <a id=\"fbddbo\"></a>(12)\n  </pre><div class=\"calloutlist\"><table border=\"0\" summary=\"Callout list\"><tr><td width=\"5%\" valign=\"top\" align=\"left\"><a href=\"#fbp\"><img src=\"images/callouts/1.png\" alt=\"1\" border=\"0\"></a> </td><td valign=\"top\" align=\"left\"><p>DBC protocol name</p></td></tr><tr><td width=\"5%\" valign=\"top\" align=\"left\"><a href=\"#fba\"><img src=\"images/callouts/2.png\" alt=\"2\" border=\"0\"></a> </td><td valign=\"top\" align=\"left\"><p>BDE alias for performance tests</p></td></tr><tr><td width=\"5%\" valign=\"top\" align=\"left\"><a href=\"#fbh\"><img src=\"images/callouts/3.png\" alt=\"3\" border=\"0\"></a> </td><td valign=\"top\" align=\"left\"><p>Host name</p></td></tr><tr><td width=\"5%\" valign=\"top\" align=\"left\"><a href=\"#fbport\"><img src=\"images/callouts/4.png\" alt=\"4\" border=\"0\"></a> </td><td valign=\"top\" align=\"left\"><p>Port number</p></td></tr><tr><td width=\"5%\" valign=\"top\" align=\"left\"><a href=\"#fbdb\"><img src=\"images/callouts/5.png\" alt=\"5\" border=\"0\"></a> </td><td valign=\"top\" align=\"left\"><p>Database name</p></td></tr><tr><td width=\"5%\" valign=\"top\" align=\"left\"><a href=\"#fbu\"><img src=\"images/callouts/6.png\" alt=\"6\" border=\"0\"></a> </td><td valign=\"top\" align=\"left\"><p>User name</p></td></tr><tr><td width=\"5%\" valign=\"top\" align=\"left\"><a href=\"#fbpw\"><img src=\"images/callouts/7.png\" alt=\"7\" border=\"0\"></a> </td><td valign=\"top\" align=\"left\"><p>User password</p></td></tr><tr><td width=\"5%\" valign=\"top\" align=\"left\"><a href=\"#fbpw\"><img src=\"images/callouts/7.png\" alt=\"7\" border=\"0\"></a> </td><td valign=\"top\" align=\"left\"><p>User password</p></td></tr><tr><td width=\"5%\" valign=\"top\" align=\"left\"><a href=\"#fbpw\"><img src=\"images/callouts/7.png\" alt=\"7\" border=\"0\"></a> </td><td valign=\"top\" align=\"left\"><p>Flag to rebuild database before each test</p></td></tr><tr><td width=\"5%\" valign=\"top\" align=\"left\"><a href=\"#fbdt\"><img src=\"images/callouts/9.png\" alt=\"9\" border=\"0\"></a> </td><td valign=\"top\" align=\"left\"><p>SQL delimiter type in SQL scripts (Default, Go, SetTerm or EmptyLine)</p></td></tr><tr><td width=\"5%\" valign=\"top\" align=\"left\"><a href=\"#fbdel\"><img src=\"images/callouts/10.png\" alt=\"10\" border=\"0\"></a> </td><td valign=\"top\" align=\"left\"><p>SQL delimiter string</p></td></tr><tr><td width=\"5%\" valign=\"top\" align=\"left\"><a href=\"#fbcdbo\">(11)</a> </td><td valign=\"top\" align=\"left\"><p>SQL scripts to create database objects. All scripts have to be placed in\n  the \"database\" directory (where the test.properties file is located).\n  </p></td></tr><tr><td width=\"5%\" valign=\"top\" align=\"left\"><a href=\"#fbddbo\">(12)</a> </td><td valign=\"top\" align=\"left\"><p>SQL scripts to drop database objects. All scripts have to be placed in\n  the \"database\" directory (where the test.properties file is located).\n  </p></td></tr></table></div><p>\n  Due to techniques used in the ZEOS Testframework classes it is necessary to set\n  a prefix in front of the key that is identical to the section name followed by\n  a dot. E. g.: firebird15.password - where \"firebird15\" is the repeated name of the\n  section (see above).\n  </p></div></div><div class=\"section\" lang=\"en\"><div class=\"titlepage\"><div><div><h2 class=\"title\" style=\"clear: both\"><a id=\"Compiling\"></a>4.&nbsp;Compiling Tests</h2></div></div></div><p>\n  When all the required Software is installed and you made the configurations\n  that are necessary for your test environment you are ready to start compiling\n  the test applications. This is easyly done by calling the batch script\n  \"compiletests.cmd\" from commandline in \"build\" directory. When all applications\n  are successfully compiled you are able to test ZEOSLib funcionality.\n  </p><p>\n  ZEOS BTE splits the tests into seven parts (separate applications):\n  <div class=\"itemizedlist\"><ul type=\"disc\"><li><p>Bug Report Tests (ZTestBugReport.EXE)</p></li><li><p>Component Tests (ZTestComponentAll.EXE)</p></li><li><p>Core Tests (ZTestCoreAll.EXE)</p></li><li><p>Database Connectivity (DBC) Tests (ZTestDbcAll.EXE)</p></li><li><p>SQL Parser Tests (ZTestParseSqlAll.EXE)</p></li><li><p>Performance Tests - currently not executed - (ZTestPerformance.EXE)</p></li></ul></div>\n  </p><p>\n  The applications listed above are compiled into the build directory of the\n  corresponding package (e. g.: ...\\packages\\delphi7\\build). Normally the applications\n  are compiled to execute as console applications but if you want to run them\n  as GUI applications just remove the comment from \"{$DEFINE TESTGUI}\" in the\n  ZEOS.INC file. If you now call one of the test applications they are executed in\n  a GUI. If you want to create console test applications you just have to comment\n  the \"{$DEFINE TESTGUI}\" again (in ZEOS.INC).\n  </p></div><div class=\"section\" lang=\"en\"><div class=\"titlepage\"><div><div><h2 class=\"title\" style=\"clear: both\"><a id=\"Running\"></a>5.&nbsp;Running Tests</h2></div></div></div><p>\n  As written in section \"Compiling Tests\", it is possible to execute special\n  tests (e. g. only Bug Report Tests) by calling the EXE-file explicitly. Depending\n  on the settings you will start one console application or one GUI application.\n  You also may run all tests by running them sequentially via batch script (consider\n  to compile all the tests as a console application!)\n  </p><p>\n  Before you run tests make sure that all the database servers you want to test are\n  up and running!</p><p>\n  To do run all tests (that are defined to run in section \"tests\" of the build.properties\n  file), automatically, just type \"test\" from a commandline in \"build\" directory. The\n  test result is output to screen and into a log file located in the \"build\"\n  subdirectory \"logs\". The logfile is called \"test-YYYYMMDD.log\"  where \"YYYYMMDD\"\n  is the current date.\n  </p></div></div><div xmlns=\"\" id=\"customfooter\">\n(c) 1999 - 2006 The Zeos Development Group\n</div></body></html>"
  },
  {
    "path": "lib/zeosdbo/doc/html/changes.html",
    "content": "\n<!DOCTYPE html\n  PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">\n<html xmlns=\"http://www.w3.org/1999/xhtml\"><head>\n      <meta http-equiv=\"Content-Type\" content=\"text/html; charset=iso-8859-1\">\n   <title>ZeosDBO Change Notes</title><link rel=\"stylesheet\" href=\"ede.css\" type=\"text/css\"><meta name=\"generator\" content=\"DocBook XSL Stylesheets V1.66.0\"></head><body><div xmlns=\"\" id=\"customheader\"><a href=\"http://zeos.firmos.at/portal.php\" style=\"color: #fff; font-weight: bold;\">ZeosLib</a><b> - open source tools for your database solutions</b></div><div class=\"article\" lang=\"en\"><div class=\"titlepage\"><div><div><h1 class=\"title\"><a id=\"d4e1\"></a>ZeosDBO Change Notes</h1></div><div><h3 class=\"corpauthor\">ZeosLib Development Group</h3></div></div><hr></div><div class=\"toc\"><p><b>Table of Contents</b></p><dl><dt><span class=\"sect1\"><a href=\"#d4e5\">1. Changes in Release 7.0.1 - alpha (NOT RELEASED YET)</a></span></dt><dt><span class=\"sect1\"><a href=\"#d4e80\">2. Changes in Release 7.0.0 - alpha (30.12.2009)</a></span></dt><dt><span class=\"sect1\"><a href=\"#d4e214\">3. Changes in Release 6.6.7 - stable (NOT RELEASED YET)</a></span></dt><dt><span class=\"sect1\"><a href=\"#d4e290\">4. Changes in Release 6.6.6 - stable (30.12.2009)</a></span></dt><dt><span class=\"sect1\"><a href=\"#d4e351\">5. Changes in Release 6.6.5 - stable (25.05.2009)</a></span></dt><dt><span class=\"sect1\"><a href=\"#d4e460\">6. Changes in Release 6.6.4 - stable (01.11.2008)</a></span></dt><dt><span class=\"sect1\"><a href=\"#d4e537\">7. Changes in Release 6.6.3 - stable (08.08.2008)</a></span></dt><dt><span class=\"sect1\"><a href=\"#d4e668\">8. Changes in Release 6.6.2 - rc (12.12.2007)</a></span></dt><dt><span class=\"sect1\"><a href=\"#d4e854\">9. Changes in Release 6.6.1 - beta (25.02.2007)</a></span></dt><dt><span class=\"sect1\"><a href=\"#d4e912\">10. Changes in Release 6.6.0 - beta (20.10.2006)</a></span></dt><dt><span class=\"sect1\"><a href=\"#d4e1195\">11. Changes in Release 6.5</a></span></dt><dt><span class=\"sect1\"><a href=\"#d4e1470\">12. Changes in Release 6.1</a></span></dt><dt><span class=\"sect1\"><a href=\"#d4e2007\">13. Changes in Release 6.0</a></span></dt></dl></div><div class=\"sect1\" lang=\"en\"><div class=\"titlepage\"><div><div><h2 class=\"title\" style=\"clear: both\"><a id=\"d4e5\"></a>1.&nbsp;Changes in Release 7.0.1 - alpha (NOT RELEASED YET)</h2></div></div></div><div class=\"toc\"><dl><dt><span class=\"sect2\"><a href=\"#d4e7\">1.1. Bugs fixed from Mantis Bug Tracker</a></span></dt><dt><span class=\"sect2\"><a href=\"#d4e18\">1.2. Other Bugs fixed</a></span></dt><dt><span class=\"sect2\"><a href=\"#d4e38\">1.3. Features added</a></span></dt><dt><span class=\"sect2\"><a href=\"#d4e74\">1.4. Internal Changes</a></span></dt></dl></div><div class=\"sect2\" lang=\"en\"><div class=\"titlepage\"><div><div><h3 class=\"title\"><a id=\"d4e7\"></a>1.1.&nbsp;Bugs fixed from Mantis Bug Tracker</h3></div></div></div><p>The bug tracker can be found at: <a href=\"http://zeosbugs.firmos.at/\" target=\"_top\">http://zeosbugs.firmos.at</a></p><div class=\"itemizedlist\"><ul type=\"disc\" compact><li><a href=\"http://zeosbugs.firmos.at/view.php?id=216\" target=\"_top\">#0000216</a> [normal] Multiselect in TDbGrid wont work</li><li><a href=\"http://zeosbugs.firmos.at/view.php?id=211\" target=\"_top\">#0000211</a> [normal] Save blob with sqlite and Delphi 2009/2010</li></ul></div></div><div class=\"sect2\" lang=\"en\"><div class=\"titlepage\"><div><div><h3 class=\"title\"><a id=\"d4e18\"></a>1.2.&nbsp;Other Bugs fixed</h3></div></div></div><div class=\"itemizedlist\"><ul type=\"disc\" compact><li> FB/IB shortInteger parameters support added (<a href=\"http://zeos.firmos.at/viewtopic.php?t=3088\" target=\"_top\">http://zeos.firmos.at/viewtopic.php?t=3088</a>)</li><li> 3 Bugs in Master/Detail Mechanisms (<a href=\"http://zeos.firmos.at/viewtopic.php?t=3090\" target=\"_top\">http://zeos.firmos.at/viewtopic.php?t=3090</a>)</li><li> Reconnect-Bug in MySQL lib (<a href=\"http://zeos.firmos.at/viewtopic.php?t=3127\" target=\"_top\">http://zeos.firmos.at/viewtopic.php?t=3127</a>)</li><li> ADO SetParams-&gt;Reopen failure! (<a href=\"http://zeos.firmos.at/viewtopic.php?t=2988\" target=\"_top\">http://zeos.firmos.at/viewtopic.php?t=2988</a>)</li><li> SQLite strange characters on retrieval (D2010)</li><li> SQLite3 Connect Error (D2010) (<a href=\"http://zeos.firmos.at/viewtopic.php?t=2766\" target=\"_top\">http://zeos.firmos.at/viewtopic.php?t=2766</a>)</li></ul></div></div><div class=\"sect2\" lang=\"en\"><div class=\"titlepage\"><div><div><h3 class=\"title\"><a id=\"d4e38\"></a>1.3.&nbsp;Features added</h3></div></div></div><div class=\"itemizedlist\"><ul type=\"disc\" compact><li>[SQLITE] Enabled busy_timeout() using connection properties - by johank (<a href=\"http://zeos.firmos.at/viewtopic.php?t=2853\" target=\"_top\">http://zeos.firmos.at/viewtopic.php?t=2853</a>)</li><li>Start of Trigger Metadata (IB/FB)- by EgonHugeist (<a href=\"http://zeos.firmos.at/viewtopic.php?t=3140\" target=\"_top\">http://zeos.firmos.at/viewtopic.php?t=3140</a>)</li><li>[MYSQL] Added support for Mysql 5.5 (new library name and a few new constants</li><li>New GroupedConnection and ConnectionGroup components - by una.bicicleta (<a href=\"http://zeos.firmos.at/viewtopic.php?t=2760\" target=\"_top\">http://zeos.firmos.at/viewtopic.php?t=2760</a>)</li><li>Added ParamChar Property to Dataset components and SQLProcessor to indicate which character parameters start with</li><li>[Delphi XE] Compiles on Delphi XE (<a href=\"http://zeos.firmos.at/viewtopic.php?t=2956\" target=\"_top\">http://zeos.firmos.at/viewtopic.php?t=2956</a>)</li><li>[ORACLE] Handle OCI_SUCCESS_WITH_INFO as a warning (<a href=\"http://zeos.firmos.at/viewtopic.php?t=773\" target=\"_top\">http://zeos.firmos.at/viewtopic.php?t=773</a>)</li><li>[POSTGRES] Added support for TZStoredProc component(<a href=\"http://zeos.firmos.at/viewtopic.php?t=2905\" target=\"_top\">http://zeos.firmos.at/viewtopic.php?t=2905</a>)</li><li>[POSTGRES] Added TZPgEventAlerter component for asynchronous notifying(<a href=\"http://zeos.firmos.at/viewtopic.php?t=2757\" target=\"_top\">http://zeos.firmos.at/viewtopic.php?t=2757</a>)</li><li>[POSTGRES] Added support for new libpq.so.5 filename on Linux(<a href=\"http://zeos.firmos.at/viewtopic.php?t=2803\" target=\"_top\">http://zeos.firmos.at/viewtopic.php?t=2803</a>)</li><li>Added varUInt64 support to DecodeVariant function for D11+ (<a href=\"http://zeos.firmos.at/viewtopic.php?t=2736\" target=\"_top\">http://zeos.firmos.at/viewtopic.php?t=2736</a>)</li><li>[SQLite] Blobdata is now stored as original bytes, without conversion</li></ul></div></div><div class=\"sect2\" lang=\"en\"><div class=\"titlepage\"><div><div><h3 class=\"title\"><a id=\"d4e74\"></a>1.4.&nbsp;Internal Changes</h3></div></div></div><div class=\"itemizedlist\"><ul type=\"disc\" compact><li>[POSTGRES] Statements no longer keep a pointer to the connection handle but get it directly from the associated connection object (<a href=\"http://zeos.firmos.at/viewtopic.php?t=2599\" target=\"_top\">http://zeos.firmos.at/viewtopic.php?t=2599</a>)</li></ul></div></div></div><div class=\"sect1\" lang=\"en\"><div class=\"titlepage\"><div><div><h2 class=\"title\" style=\"clear: both\"><a id=\"d4e80\"></a>2.&nbsp;Changes in Release 7.0.0 - alpha (30.12.2009)</h2></div></div></div><div class=\"toc\"><dl><dt><span class=\"sect2\"><a href=\"#d4e82\">2.1. Bugs fixed from Mantis Bug Tracker</a></span></dt><dt><span class=\"sect2\"><a href=\"#d4e117\">2.2. Other Bugs fixed</a></span></dt><dt><span class=\"sect2\"><a href=\"#d4e132\">2.3. Features added</a></span></dt><dt><span class=\"sect2\"><a href=\"#d4e199\">2.4. Internal Changes</a></span></dt></dl></div><div class=\"sect2\" lang=\"en\"><div class=\"titlepage\"><div><div><h3 class=\"title\"><a id=\"d4e82\"></a>2.1.&nbsp;Bugs fixed from Mantis Bug Tracker</h3></div></div></div><p>The bug tracker can be found at: <a href=\"http://zeosbugs.firmos.at/\" target=\"_top\">http://zeosbugs.firmos.at</a></p><div class=\"itemizedlist\"><ul type=\"disc\" compact><li><a href=\"http://zeosbugs.firmos.at/view.php?id=208\" target=\"_top\">#0000208</a> [normal] TZAbstractRODataset bug and improvement (MIDAS IProviderSupport and IsUniDirectional)</li><li><a href=\"http://zeosbugs.firmos.at/view.php?id=209\" target=\"_top\">#0000209</a> [normal] honor compiler conditional defines for all packages</li><li><a href=\"http://zeosbugs.firmos.at/view.php?id=204\" target=\"_top\">#0000204</a> [normal] internalpost and bookmark</li><li><a href=\"http://zeosbugs.firmos.at/view.php?id=203\" target=\"_top\">#0000203</a> [normal] MySQL Driver Fix and Optimatization</li><li><a href=\"http://zeosbugs.firmos.at/view.php?id=202\" target=\"_top\">#0000202</a> [normal] Indonesian Translation Update</li><li><a href=\"http://zeosbugs.firmos.at/view.php?id=201\" target=\"_top\">#0000201</a> [normal] Patch to solve some lib problems with SQLite3 under Linux.</li><li><a href=\"http://zeosbugs.firmos.at/view.php?id=190\" target=\"_top\">#0000190</a> [normal] 64-bit support : first step (comon + mysql driver)</li><li><a href=\"http://zeosbugs.firmos.at/view.php?id=179\" target=\"_top\">#0000178</a> [normal] Error compiling Zeos under Linux.</li><li><a href=\"http://zeosbugs.firmos.at/view.php?id=178\" target=\"_top\">#0000178</a> [normal] INVALID_HANDLE_VALUE is undefined</li><li><a href=\"http://zeosbugs.firmos.at/view.php?id=126\" target=\"_top\">#0000126</a> [normal] Quoting specific to PostgreSQL</li></ul></div></div><div class=\"sect2\" lang=\"en\"><div class=\"titlepage\"><div><div><h3 class=\"title\"><a id=\"d4e117\"></a>2.2.&nbsp;Other Bugs fixed</h3></div></div></div><div class=\"itemizedlist\"><ul type=\"disc\" compact><li>[IB/FB] AV in TZInterbase6PreparedStatement.UnPrepareInParameters when opening an invalid sql command (<a href=\"http://zeos.firmos.at/viewtopic.php?t=2361\" target=\"_top\">http://zeos.firmos.at/viewtopic.php?t=2361</a>)</li><li>[Common] Overflow while converting variant of type (Int64) into type (Integer) when deleting a record (<a href=\"http://zeos.firmos.at/viewtopic.php?t=2286\" target=\"_top\">http://zeos.firmos.at/viewtopic.php?t=2286</a>)</li><li>[ADO] Column type metadata request for MSSQL returns no type (<a href=\"http://zeos.firmos.at/viewtopic.php?t=2155\" target=\"_top\">http://zeos.firmos.at/viewtopic.php?t=2155</a>)</li><li>[Common] Some dates of form 2008-1-1 seem not to work good with function TimestampStrToDateTime (<a href=\"http://zeos.firmos.at/viewtopic.php?t=2093\" target=\"_top\">http://zeos.firmos.at/viewtopic.php?t=2093</a>)</li></ul></div></div><div class=\"sect2\" lang=\"en\"><div class=\"titlepage\"><div><div><h3 class=\"title\"><a id=\"d4e132\"></a>2.3.&nbsp;Features added</h3></div></div></div><div class=\"itemizedlist\"><ul type=\"disc\" compact><li>[SQLite] removed support for SQLite2</li><li>[POSTGRES] Added new Postgres 8.4 SQL keywords (<a href=\"http://zeos.firmos.at/viewtopic.php?t=2523\" target=\"_top\">http://zeos.firmos.at/viewtopic.php?t=2523</a>)</li><li>[COMMON] TZConnection.Pingserver now resets the ZConnection state when failing (<a href=\"http://zeos.firmos.at/viewtopic.php?t=2293\" target=\"_top\">http://zeos.firmos.at/viewtopic.php?t=2293</a>)</li><li>[Common] Added ZURL unit to the core package. This unit provides splitting and composing routines for connect strings.</li><li>[IB/FB] Added support for milliseconds (<a href=\"http://zeos.firmos.at/viewtopic.php?t=2354\" target=\"_top\">http://zeos.firmos.at/viewtopic.php?t=2354</a>)</li><li>[Oracle] Connections are now made using the OCIEnvNlsCreate method instead of OCIEnvInit and use property 'codepage=[UTF8,0..max Word value]' (<a href=\"http://zeos.firmos.at/viewtopic.php?t=2172\" target=\"_top\">http://zeos.firmos.at/viewtopic.php?t=2172</a>)</li><li>[COMMON] Renamed IZObject.Hash to IZObject.GetHashCode after the new Delphi 2009 version (<a href=\"http://zeos.firmos.at/viewtopic.php?t=2131\" target=\"_top\">http://zeos.firmos.at/viewtopic.php?t=2131</a>)</li><li>[COMMON] Default strings to TWideString fields on Delphi 2009 (<a href=\"http://zeos.firmos.at/viewtopic.php?t=2119\" target=\"_top\">http://zeos.firmos.at/viewtopic.php?t=2119</a>)</li><li>[COMMON] Added BCB 2009 packages.</li><li>[COMMON] Added Delphi 2009 to the supported compilers. Big thanks to gto and mariuszekpl for this work!!</li><li>[COMMON] Added support for DefaultExpression TField property (<a href=\"http://zeosbugs.firmos.at/view.php?id=146\" target=\"_top\">#0000146</a>)</li><li>[COMMON] (Delphi only issue) Added a test to avoid opening a dataset when ComponentState=csDestroying</li><li>[Mysql] Implemented reuse of prepared statements for mysql</li><li>[Common] Added Prepared property and Prepare/Unprepare methods to TZAbstractRODataset</li><li>[IB/FB] ZDbcInterbase6Utils.AffectedRows now also returns a value for select statements (<a href=\"http://zeos.firmos.at/viewtopic.php?t=2002\" target=\"_top\">http://zeos.firmos.at/viewtopic.php?t=2002</a>)</li><li>[IB/FB] Add Connection timeout parameter (<a href=\"http://zeos.firmos.at/viewtopic.php?t=2002\" target=\"_top\">http://zeos.firmos.at/viewtopic.php?t=2002</a>)</li><li>[POSTGRES] Limited default output of TZPostgresSQLDatabaseMetadata.GetTables to 'TABLE', 'VIEW' and 'TEMPORARY TABLE' (<a href=\"http://zeos.firmos.at/viewtopic.php?t=1960\" target=\"_top\">http://zeos.firmos.at/viewtopic.php?t=1960</a>)</li><li>[COMMON] Sanity check: assert that row buffer length is not exceeded at a proper time - by HeidiSQL Team</li><li>[COMMON] Splitted IZDatabaseMetadata into IZDatabaseMetadata (retrieves info about DB content) and IZDatabaseInfo (retrieves info about server properties) (<a href=\"http://zeos.firmos.at/viewtopic.php?t=1946\" target=\"_top\">http://zeos.firmos.at/viewtopic.php?t=1946</a>)</li><li>[POSTGRES] PostgreSQL UTF8 Charset Patch</li><li>[MYSQL] Removed support for mysql &lt; 4.1</li><li>[COMMON] Removed packages for Delphi 5 and 6, Kylix 2 and CBuilder 5</li><li>[COMMON] New dataset option doDontSortOnPost (<a href=\"http://zeos.firmos.at/viewtopic.php?t=1931\" target=\"_top\">http://zeos.firmos.at/viewtopic.php?t=1931</a>)</li><li>[COMMON] Added ZQuery.RefreshCurrentRow method</li><li>[MYSQL] Added Prepared Statements support (Experimental)</li><li>[COMMON] ZQuery property ValidateUpdateCount true by default</li></ul></div></div><div class=\"sect2\" lang=\"en\"><div class=\"titlepage\"><div><div><h3 class=\"title\"><a id=\"d4e199\"></a>2.4.&nbsp;Internal Changes</h3></div></div></div><div class=\"itemizedlist\"><ul type=\"disc\" compact><li>[FPC] Removed T***IntDynArray types from ZCompatibility as FPC 2 and higher also defines these</li><li>[MYSQL] Cleanup of type/constant definitions in mysql plain drivers</li><li>[MYSQL] Updated libmysql versions in SVN repository</li><li>[COMMON] Added Delphi2009 to the automated build scripts and test suite</li><li>[DB2] Removed never used DB2 plain drivers</li><li>[COMMON] Reworked component bitmaps</li></ul></div></div></div><div class=\"sect1\" lang=\"en\"><div class=\"titlepage\"><div><div><h2 class=\"title\" style=\"clear: both\"><a id=\"d4e214\"></a>3.&nbsp;Changes in Release 6.6.7 - stable (NOT RELEASED YET)</h2></div></div></div><div class=\"toc\"><dl><dt><span class=\"sect2\"><a href=\"#d4e216\">3.1. Bugs fixed from Mantis Bug Tracker</a></span></dt><dt><span class=\"sect2\"><a href=\"#d4e227\">3.2. Other Bugs fixed</a></span></dt><dt><span class=\"sect2\"><a href=\"#d4e264\">3.3. Features added</a></span></dt><dt><span class=\"sect2\"><a href=\"#d4e272\">3.4. Internal Changes</a></span></dt></dl></div><div class=\"sect2\" lang=\"en\"><div class=\"titlepage\"><div><div><h3 class=\"title\"><a id=\"d4e216\"></a>3.1.&nbsp;Bugs fixed from Mantis Bug Tracker</h3></div></div></div><p>The bug tracker can be found at: <a href=\"http://zeosbugs.firmos.at/\" target=\"_top\">http://zeosbugs.firmos.at</a></p><div class=\"itemizedlist\"><ul type=\"disc\" compact><li><a href=\"http://zeosbugs.firmos.at/view.php?id=218\" target=\"_top\">#0000218</a> [normal] Oracle NUMBER wrong conversion - New Oracle tests</li><li><a href=\"http://zeosbugs.firmos.at/view.php?id=212\" target=\"_top\">#0000212</a> [normal] Oracle Dbc bugs</li></ul></div></div><div class=\"sect2\" lang=\"en\"><div class=\"titlepage\"><div><div><h3 class=\"title\"><a id=\"d4e227\"></a>3.2.&nbsp;Other Bugs fixed</h3></div></div></div><div class=\"itemizedlist\"><ul type=\"disc\" compact><li> Patch to fix problems on SQLite Blob Fields (<a href=\"http://zeos.firmos.at/viewtopic.php?t=3045\" target=\"_top\">http://zeos.firmos.at/viewtopic.php?t=3045</a>)</li><li> Error when trying to edit and save data without modification (<a href=\"http://zeos.firmos.at/viewtopic.php?t=2936\" target=\"_top\">http://zeos.firmos.at/viewtopic.php?t=2936</a>)</li><li> New QueryInterface handling by Lazarus (<a href=\"http://zeos.firmos.at/viewtopic.php?t=3009\" target=\"_top\">http://zeos.firmos.at/viewtopic.php?t=3009</a>)</li><li> ftFixedChar input parameters were not handled correctly (<a href=\"http://zeos.firmos.at/viewtopic.php?t=2979\" target=\"_top\">http://zeos.firmos.at/viewtopic.php?t=2979</a>)</li><li> Error Param.DataType in TZStoredProcedure (<a href=\"http://zeos.firmos.at/viewtopic.php?t=2742\" target=\"_top\">http://zeos.firmos.at/viewtopic.php?t=2742</a>)</li><li>[Common] alter and column were not on the list of AnsiSQLKeywords</li><li>[MySql] Added support for mysql 5.1 library on LINUX (<a href=\"http://zeos.firmos.at/viewtopic.php?t=2693\" target=\"_top\">http://zeos.firmos.at/viewtopic.php?t=2693</a>)</li><li>[Common] TZAbstractDataset.InternalPost sets unused bookmarks (<a href=\"http://zeos.firmos.at/viewtopic.php?t=2666\" target=\"_top\">http://zeos.firmos.at/viewtopic.php?t=2666</a>)</li><li>[FPC/Lazarus] Locale problems for decimal fields and fpc &lt; 2.3.1 (<a href=\"http://zeos.firmos.at/viewtopic.php?t=2643\" target=\"_top\">http://zeos.firmos.at/viewtopic.php?t=2643</a>)</li><li>[POSTGRES] AccessViolation when PostgreSQL server connection lost (<a href=\"http://zeos.firmos.at/viewtopic.php?t=2599\" target=\"_top\">http://zeos.firmos.at/viewtopic.php?t=2599</a>)</li><li>[SQLITE] Replaced 'SELECT LAST_INSERT_ROWID()' by LastRowId API call</li><li>[Common] TZTable and TZQuery Filter property do not work correctly with datetime fields (<a href=\"http://zeos.firmos.at/viewtopic.php?t=2055\" target=\"_top\">http://zeos.firmos.at/viewtopic.php?t=2055</a>)</li></ul></div></div><div class=\"sect2\" lang=\"en\"><div class=\"titlepage\"><div><div><h3 class=\"title\"><a id=\"d4e264\"></a>3.3.&nbsp;Features added</h3></div></div></div><div class=\"itemizedlist\"><ul type=\"disc\" compact><li>Zeoslib 6.6 is in it's stable phase. No features, except for eventual translations and docs, will (should) be added.</li><li>[POSTGRES] Added new Postgres 8.3 Enum support (<a href=\"http://zeos.firmos.at/viewtopic.php?t=2625\" target=\"_top\">http://zeos.firmos.at/viewtopic.php?t=2625</a>)</li></ul></div></div><div class=\"sect2\" lang=\"en\"><div class=\"titlepage\"><div><div><h3 class=\"title\"><a id=\"d4e272\"></a>3.4.&nbsp;Internal Changes</h3></div></div></div><div class=\"itemizedlist\"><ul type=\"disc\" compact><li>[Lazarus/FPC] More tests enabled for Lazarus/FPC.</li><li>FPC : changing types of FHandle and HModul to PtrInt in ZCompatibility.pas and ZPlainLoader.pas for 64-bit compatibility  (<a href=\"http://zeos.firmos.at/viewtopic.php?t=2358\" target=\"_top\">http://zeos.firmos.at/viewtopic.php?t=2358</a>)</li><li>Add system path to testing path (to avoid installing oracle oci in different testing environments)</li><li>TZVariant : Putting vtBoolean, vtInteger, vtFloat.vtDatetime and vtPointer in a case record saves memory without any loss in function (<a href=\"http://zeos.firmos.at/viewtopic.php?t=2696\" target=\"_top\">http://zeos.firmos.at/viewtopic.php?t=2696</a>)</li><li>[POSTGRES] A beter fix for bug report 136 (<a href=\"http://zeos.firmos.at/viewtopic.php?t=2599\" target=\"_top\">http://zeos.firmos.at/viewtopic.php?t=2599</a>)</li><li>[Lazarus/FPC] Test database rebuild for Lazarus/FPC added.</li></ul></div></div></div><div class=\"sect1\" lang=\"en\"><div class=\"titlepage\"><div><div><h2 class=\"title\" style=\"clear: both\"><a id=\"d4e290\"></a>4.&nbsp;Changes in Release 6.6.6 - stable (30.12.2009)</h2></div></div></div><div class=\"toc\"><dl><dt><span class=\"sect2\"><a href=\"#d4e292\">4.1. Bugs fixed from Mantis Bug Tracker</a></span></dt><dt><span class=\"sect2\"><a href=\"#d4e321\">4.2. Other Bugs fixed</a></span></dt><dt><span class=\"sect2\"><a href=\"#d4e336\">4.3. Features added</a></span></dt><dt><span class=\"sect2\"><a href=\"#d4e346\">4.4. Internal Changes</a></span></dt></dl></div><div class=\"sect2\" lang=\"en\"><div class=\"titlepage\"><div><div><h3 class=\"title\"><a id=\"d4e292\"></a>4.1.&nbsp;Bugs fixed from Mantis Bug Tracker</h3></div></div></div><p>The bug tracker can be found at: <a href=\"http://zeosbugs.firmos.at/\" target=\"_top\">http://zeosbugs.firmos.at</a></p><div class=\"itemizedlist\"><ul type=\"disc\" compact><li><a href=\"http://zeosbugs.firmos.at/view.php?id=177\" target=\"_top\">#0000177</a> [normal] Type mismatch error on runtime</li><li><a href=\"http://zeosbugs.firmos.at/view.php?id=210\" target=\"_top\">#0000210</a> [Oracle] Bug inserting blob with length = 0</li><li><a href=\"http://zeosbugs.firmos.at/view.php?id=187\" target=\"_top\">#0000187</a> [PostgreSQL] PingServer does (still) not detect lost connections</li><li><a href=\"http://zeosbugs.firmos.at/view.php?id=207\" target=\"_top\">#0000207</a> [PostgreSQL] BlobRead Memory Leak</li><li><a href=\"http://zeosbugs.firmos.at/view.php?id=194\" target=\"_top\">#0000194</a> [IB/FB] ZEOS is replicating NULL values on UPDATE statement </li><li><a href=\"http://zeosbugs.firmos.at/view.php?id=173\" target=\"_top\">#0000173</a> [normal] unable to activate login dialog</li><li><a href=\"http://zeosbugs.firmos.at/view.php?id=184\" target=\"_top\">#0000184</a> [Interbase 5] Can't get fields' list of dataset from Interbase 5.5 server</li><li><a href=\"http://zeosbugs.firmos.at/view.php?id=183\" target=\"_top\">#0000183</a> [Lazarus] Icon for TZIBEventAlerter added</li></ul></div></div><div class=\"sect2\" lang=\"en\"><div class=\"titlepage\"><div><div><h3 class=\"title\"><a id=\"d4e321\"></a>4.2.&nbsp;Other Bugs fixed</h3></div></div></div><div class=\"itemizedlist\"><ul type=\"disc\" compact><li>[PostgreSQL] Connection string optimization for postgresql (<a href=\"http://zeos.firmos.at/viewtopic.php?t=2636\" target=\"_top\">http://zeos.firmos.at/viewtopic.php?t=2636</a>)</li><li>[Linux] Sqlite3 library name fix for Linux (<a href=\"http://zeos.firmos.at/viewtopic.php?t=2600\" target=\"_top\">http://zeos.firmos.at/viewtopic.php?t=2600</a>)</li><li>[COMMON] Scriptparser error finding a multicharacter delimiter(<a href=\"http://zeos.firmos.at/viewtopic.php?t=2517\" target=\"_top\">http://zeos.firmos.at/viewtopic.php?t=2517</a>)</li><li>[Oracle] Memory leak when reading BLOB values (<a href=\"http://zeos.firmos.at/viewtopic.php?t=2504\" target=\"_top\">http://zeos.firmos.at/viewtopic.php?t=2504</a>)</li></ul></div></div><div class=\"sect2\" lang=\"en\"><div class=\"titlepage\"><div><div><h3 class=\"title\"><a id=\"d4e336\"></a>4.3.&nbsp;Features added</h3></div></div></div><div class=\"itemizedlist\"><ul type=\"disc\" compact><li>Zeoslib 6.6 is in it's stable phase. No features, except for eventual translations and docs, will (should) be added.</li><li>[COMMON] Added functions TRIM, VAL, CTOD, DTOS, LEFT and RIGHT.</li><li>[COMMON] New property FetchRow in ZDataSet (<a href=\"http://zeos.firmos.at/viewtopic.php?t=1857\" target=\"_top\">http://zeos.firmos.at/viewtopic.php?t=1857</a>)</li></ul></div></div><div class=\"sect2\" lang=\"en\"><div class=\"titlepage\"><div><div><h3 class=\"title\"><a id=\"d4e346\"></a>4.4.&nbsp;Internal Changes</h3></div></div></div><div class=\"itemizedlist\"><ul type=\"disc\" compact><li>[Lazarus/FPC] Test suite for Lazarus/FPC added.</li></ul></div></div></div><div class=\"sect1\" lang=\"en\"><div class=\"titlepage\"><div><div><h2 class=\"title\" style=\"clear: both\"><a id=\"d4e351\"></a>5.&nbsp;Changes in Release 6.6.5 - stable (25.05.2009)</h2></div></div></div><div class=\"toc\"><dl><dt><span class=\"sect2\"><a href=\"#d4e353\">5.1. Bugs fixed from Mantis Bug Tracker</a></span></dt><dt><span class=\"sect2\"><a href=\"#d4e382\">5.2. Other Bugs fixed</a></span></dt><dt><span class=\"sect2\"><a href=\"#d4e433\">5.3. Features added</a></span></dt><dt><span class=\"sect2\"><a href=\"#d4e455\">5.4. Internal Changes</a></span></dt></dl></div><div class=\"sect2\" lang=\"en\"><div class=\"titlepage\"><div><div><h3 class=\"title\"><a id=\"d4e353\"></a>5.1.&nbsp;Bugs fixed from Mantis Bug Tracker</h3></div></div></div><p>The bug tracker can be found at: <a href=\"http://zeosbugs.firmos.at/\" target=\"_top\">http://zeosbugs.firmos.at</a></p><div class=\"itemizedlist\"><ul type=\"disc\" compact><li><a href=\"http://zeosbugs.firmos.at/view.php?id=179\" target=\"_top\">#0000179</a> [normal] Case problem for unit ZPlainMySqlConstants on linux</li><li><a href=\"http://zeosbugs.firmos.at/view.php?id=2\" target=\"_top\">#0000002</a> [normal] FIREBIRD and NUMERIC/DECIMAL precision problem</li><li><a href=\"http://zeosbugs.firmos.at/view.php?id=124\" target=\"_top\">#0000124</a> [normal] TZSQLMonitor access violation when destroying</li><li><a href=\"http://zeosbugs.firmos.at/view.php?id=117\" target=\"_top\">#0000117</a> [normal] FPC - Float Fields with null values produce many exceptions</li><li><a href=\"http://zeosbugs.firmos.at/view.php?id=150\" target=\"_top\">#0000150</a> [normal] Second JOIN in from clause was stripped by the SQL parser after ON or USING clause</li><li><a href=\"http://zeosbugs.firmos.at/view.php?id=159\" target=\"_top\">#0000159</a> [normal] Fixed case of some *MySql* unit names</li><li><a href=\"http://zeosbugs.firmos.at/view.php?id=165\" target=\"_top\">#0000165</a> [normal] Incorrect autogeneration of INSERT statement</li><li><a href=\"http://zeosbugs.firmos.at/view.php?id=162\" target=\"_top\">#0000162</a> [normal] Precision issue when recording values from TClientDataSet</li></ul></div></div><div class=\"sect2\" lang=\"en\"><div class=\"titlepage\"><div><div><h3 class=\"title\"><a id=\"d4e382\"></a>5.2.&nbsp;Other Bugs fixed</h3></div></div></div><div class=\"itemizedlist\"><ul type=\"disc\" compact><li>[COMMON] Delphi compiler throws a hint that the assigned return value for ExecuteDirect is never used. (<a href=\"http://zeos.firmos.at/viewtopic.php?t=2369\" target=\"_top\">http://zeos.firmos.at/viewtopic.php?t=2369</a>)</li><li>[IB/FB] Memory leak in TZInterbase6CallableStatement.ExecuteUpdatePrepared (<a href=\"http://zeos.firmos.at/viewtopic.php?t=2250\" target=\"_top\">http://zeos.firmos.at/viewtopic.php?t=2250</a>)</li><li>[IB/FB] Buffer problem with FB2.1 isc_interprete implementation (<a href=\"http://zeos.firmos.at/viewtopic.php?t=2099\" target=\"_top\">http://zeos.firmos.at/viewtopic.php?t=2099</a>)</li><li>[IB/FB] Interbase/Firebid holding connection on shutdown (<a href=\"http://zeos.firmos.at/viewtopic.php?t=2309\" target=\"_top\">http://zeos.firmos.at/viewtopic.php?t=2309</a>)</li><li>[COMMON] Compilation error with SHOW_WARNING directive (<a href=\"http://zeos.firmos.at/viewtopic.php?t=2312\" target=\"_top\">http://zeos.firmos.at/viewtopic.php?t=2312</a>)</li><li>[ADO] SQLServer default GUID fieldlength incorrect (<a href=\"http://zeos.firmos.at/viewtopic.php?t=2300\" target=\"_top\">http://zeos.firmos.at/viewtopic.php?t=2300</a>)</li><li>[PostgreSQL] Bit type fields were not found (<a href=\"http://zeos.firmos.at/viewtopic.php?t=2260\" target=\"_top\">http://zeos.firmos.at/viewtopic.php?t=2260</a>)</li><li>[IB/FB] Subtype is 0 for a computed decimal field and not 1 as in all the other cases (<a href=\"http://zeos.firmos.at/viewtopic.php?t=2278\" target=\"_top\">http://zeos.firmos.at/viewtopic.php?t=2278</a>)</li><li>[COMMON] Make sure dbc connection is nil after ZConnection.Close, even when an exception occurs (<a href=\"http://zeos.firmos.at/viewtopic.php?t=2275\" target=\"_top\">http://zeos.firmos.at/viewtopic.php?t=2275</a>)</li><li>[COMMON] Query property &#8216;ValidateUpdateCount=true/false&#8217; was not added for TZUpdateSQL(<a href=\"http://zeos.firmos.at/viewtopic.php?t=2249\" target=\"_top\">http://zeos.firmos.at/viewtopic.php?t=2249</a>)</li><li>[IB/FB] TZInterbase6DatabaseMetadata.UncachedGetTables: Access Violation and duplicated rows (<a href=\"http://zeos.firmos.at/viewtopic.php?t=2236\" target=\"_top\">http://zeos.firmos.at/viewtopic.php?t=2236</a>)</li><li>[Lazarus] Removed libc from uses clauses when using fpc (<a href=\"http://zeos.firmos.at/viewtopic.php?t=2196\" target=\"_top\">http://zeos.firmos.at/viewtopic.php?t=2196</a>)</li><li>[DELPHI] Removed conditional compilation of database dependent Tokenizers (<a href=\"http://zeos.firmos.at/viewtopic.php?t=2138\" target=\"_top\">http://zeos.firmos.at/viewtopic.php?t=2138</a>)</li><li>[Lazarus] Updated ZUpdateSqlEditor.lrs to be compatible with the newest Lazarus release (<a href=\"http://zeos.firmos.at/viewtopic.php?t=2095\" target=\"_top\">http://zeos.firmos.at/viewtopic.php?t=2095</a>)</li><li>[Oracle] Added TZOracleCachedResolver class because oracle doesn't support queries without FROM clause (<a href=\"http://zeos.firmos.at/viewtopic.php?t=2080\" target=\"_top\">http://zeos.firmos.at/viewtopic.php?t=2080</a>)</li><li>[COMMON] Removed some compiler warnings (<a href=\"http://zeos.firmos.at/viewtopic.php?t=2081\" target=\"_top\">http://zeos.firmos.at/viewtopic.php?t=2081</a>)</li></ul></div></div><div class=\"sect2\" lang=\"en\"><div class=\"titlepage\"><div><div><h3 class=\"title\"><a id=\"d4e433\"></a>5.3.&nbsp;Features added</h3></div></div></div><div class=\"itemizedlist\"><ul type=\"disc\" compact><li>Zeoslib 6.6 is in it's stable phase. No features, except for eventual translations and docs, will (should) be added.</li><li>[COMMON] TZConnection.Pingserver now resets the ZConnection state when failing (<a href=\"http://zeos.firmos.at/viewtopic.php?t=2293\" target=\"_top\">http://zeos.firmos.at/viewtopic.php?t=2293</a>)</li><li>[GENERAL] Added ZEOS_DISABLE_XXXXX 'Conditional Defines' to Zeos.inc to allow compiling out database support on a per project basis(<a href=\"http://zeos.firmos.at/viewtopic.php?t=2195\" target=\"_top\">http://zeos.firmos.at/viewtopic.php?t=2195</a>)</li><li>[POSTGRES] Implemented ZConnection.ServerVersion for Postgres</li><li>[POSTGRES] Implemented Pingserver for Postgres (<a href=\"http://zeos.firmos.at/viewtopic.php?t=2156\" target=\"_top\">http://zeos.firmos.at/viewtopic.php?t=2156</a>)</li><li>[IB/FB] Implemented Pingserver for IB/FB (<a href=\"http://zeos.firmos.at/viewtopic.php?t=2274\" target=\"_top\">http://zeos.firmos.at/viewtopic.php?t=2274</a>)</li><li>[IB/FB] Added Firebird 2.1 driver (<a href=\"http://zeos.firmos.at/viewtopic.php?t=2099\" target=\"_top\">http://zeos.firmos.at/viewtopic.php?t=2099</a>)</li></ul></div></div><div class=\"sect2\" lang=\"en\"><div class=\"titlepage\"><div><div><h3 class=\"title\"><a id=\"d4e455\"></a>5.4.&nbsp;Internal Changes</h3></div></div></div><div class=\"itemizedlist\"><ul type=\"disc\" compact><li>NONE</li></ul></div></div></div><div class=\"sect1\" lang=\"en\"><div class=\"titlepage\"><div><div><h2 class=\"title\" style=\"clear: both\"><a id=\"d4e460\"></a>6.&nbsp;Changes in Release 6.6.4 - stable (01.11.2008)</h2></div></div></div><div class=\"toc\"><dl><dt><span class=\"sect2\"><a href=\"#d4e462\">6.1. Bugs fixed from Mantis Bug Tracker</a></span></dt><dt><span class=\"sect2\"><a href=\"#d4e491\">6.2. Other Bugs fixed</a></span></dt><dt><span class=\"sect2\"><a href=\"#d4e527\">6.3. Features added</a></span></dt><dt><span class=\"sect2\"><a href=\"#d4e532\">6.4. Internal Changes</a></span></dt></dl></div><div class=\"sect2\" lang=\"en\"><div class=\"titlepage\"><div><div><h3 class=\"title\"><a id=\"d4e462\"></a>6.1.&nbsp;Bugs fixed from Mantis Bug Tracker</h3></div></div></div><p>The bug tracker can be found at: <a href=\"http://zeosbugs.firmos.at/\" target=\"_top\">http://zeosbugs.firmos.at</a></p><div class=\"itemizedlist\"><ul type=\"disc\" compact><li><a href=\"http://zeosbugs.firmos.at/view.php?id=147\" target=\"_top\">#0000147</a> [normal] Column mapping problem with TZUpdateSql and Refreshing data</li><li><a href=\"http://zeosbugs.firmos.at/view.php?id=140\" target=\"_top\">#0000140</a> [normal] ZUpdateSQL set null as default datetime field value (Firebird)</li><li><a href=\"http://zeosbugs.firmos.at/view.php?id=136\" target=\"_top\">#0000136</a> [normal] Memory leaking on failed Postgres connection</li><li><a href=\"http://zeosbugs.firmos.at/view.php?id=139\" target=\"_top\">#0000139</a> [normal] Some MySQL units are still being compiled when only the SQLite protocol is enabled</li><li><a href=\"http://zeosbugs.firmos.at/view.php?id=137\" target=\"_top\">#0000137</a> [normal] Exception Field '...' cannot be modified (calculated, lookup field) (Adjusted fix for Mantis Bug 99)</li><li><a href=\"http://zeosbugs.firmos.at/view.php?id=133\" target=\"_top\">#0000133</a> [normal] Exception class EZSQLException : attempted update of read-only column (calculated)</li><li><a href=\"http://zeosbugs.firmos.at/view.php?id=131\" target=\"_top\">#0000131</a> [normal] ZIBEventAlerter compile error in Lazarus/Linux</li><li><a href=\"http://zeosbugs.firmos.at/view.php?id=129\" target=\"_top\">#0000129</a> [normal] Access Violation due to forget to assign Connection in TZQuery</li></ul></div></div><div class=\"sect2\" lang=\"en\"><div class=\"titlepage\"><div><div><h3 class=\"title\"><a id=\"d4e491\"></a>6.2.&nbsp;Other Bugs fixed</h3></div></div></div><div class=\"itemizedlist\"><ul type=\"disc\" compact><li>[COMMON] Bad letter case for unit ZSqlProcessor in ZSqlStrings.pas (<a href=\"http://zeos.firmos.at/viewtopic.php?t=2067\" target=\"_top\">http://zeos.firmos.at/viewtopic.php?t=2067</a>)</li><li>[Postgresql] Replaced the default notice processor which printed to stderr in console applications (and the test suite) (<a href=\"http://zeos.firmos.at/viewtopic.php?t=2021\" target=\"_top\">http://zeos.firmos.at/viewtopic.php?t=2021</a>)</li><li>[COMMON] Escape underscores from the stored procedure name before looking up it's parameters (<a href=\"http://zeos.firmos.at/viewtopic.php?t=2035\" target=\"_top\">http://zeos.firmos.at/viewtopic.php?t=2035</a>)</li><li>[COMMON] Removed table prefixes in generated insert/update statements in property editor for TZSQLUpdate (<a href=\"http://zeos.firmos.at/viewtopic.php?t=2023\" target=\"_top\">http://zeos.firmos.at/viewtopic.php?t=2023</a>)</li><li>[SQLITE] Fixed updates to tables from attached databases (<a href=\"http://zeos.firmos.at/viewtopic.php?t=2025\" target=\"_top\">http://zeos.firmos.at/viewtopic.php?t=2025</a>)</li><li>[ADO] Method calls (GetSchemaNames() and GetCatalogNames()) ran into an exception (<a href=\"http://zeos.firmos.at/viewtopic.php?t=1774\" target=\"_top\">http://zeos.firmos.at/viewtopic.php?t=1774</a>)</li><li>[COMMON] \"List out of bounds\" in Metadata (<a href=\"http://zeos.firmos.at/viewtopic.php?t=1995\" target=\"_top\">http://zeos.firmos.at/viewtopic.php?t=1995</a>)</li><li>[COMMON] TZSQLProcessor Tokenizer problem (<a href=\"http://zeos.firmos.at/viewtopic.php?t=1977\" target=\"_top\">http://zeos.firmos.at/viewtopic.php?t=1977</a>)</li><li>[MYSQL] Misprint in ZPlainMysqlFunc.inc (<a href=\"http://zeos.firmos.at/viewtopic.php?t=1979\" target=\"_top\">http://zeos.firmos.at/viewtopic.php?t=1979</a>)</li><li>[IB/FB] Memory Leak in TZIBEventAlerter (<a href=\"http://zeos.firmos.at/viewtopic.php?t=1962\" target=\"_top\">http://zeos.firmos.at/viewtopic.php?t=1962</a>)</li><li>[IB/FB] Only link TZIBEventAlerter when ENABLE_INTERBASE is defined (<a href=\"http://zeos.firmos.at/viewtopic.php?t=1949\" target=\"_top\">http://zeos.firmos.at/viewtopic.php?t=1949</a>)</li></ul></div></div><div class=\"sect2\" lang=\"en\"><div class=\"titlepage\"><div><div><h3 class=\"title\"><a id=\"d4e527\"></a>6.3.&nbsp;Features added</h3></div></div></div><div class=\"itemizedlist\"><ul type=\"disc\" compact><li>NONE. Zeoslib 6.6 is in it's stable phase. No features, except for eventual translations and docs, will be added.</li></ul></div></div><div class=\"sect2\" lang=\"en\"><div class=\"titlepage\"><div><div><h3 class=\"title\"><a id=\"d4e532\"></a>6.4.&nbsp;Internal Changes</h3></div></div></div><div class=\"itemizedlist\"><ul type=\"disc\" compact><li>NONE</li></ul></div></div></div><div class=\"sect1\" lang=\"en\"><div class=\"titlepage\"><div><div><h2 class=\"title\" style=\"clear: both\"><a id=\"d4e537\"></a>7.&nbsp;Changes in Release 6.6.3 - stable (08.08.2008)</h2></div></div></div><div class=\"toc\"><dl><dt><span class=\"sect2\"><a href=\"#d4e539\">7.1. Bugs fixed from Mantis Bug Tracker</a></span></dt><dt><span class=\"sect2\"><a href=\"#d4e604\">7.2. Other Bugs fixed</a></span></dt><dt><span class=\"sect2\"><a href=\"#d4e632\">7.3. Features added</a></span></dt><dt><span class=\"sect2\"><a href=\"#d4e655\">7.4. Internal Changes</a></span></dt></dl></div><div class=\"sect2\" lang=\"en\"><div class=\"titlepage\"><div><div><h3 class=\"title\"><a id=\"d4e539\"></a>7.1.&nbsp;Bugs fixed from Mantis Bug Tracker</h3></div></div></div><p>The bug tracker can be found at: <a href=\"http://zeosbugs.firmos.at/\" target=\"_top\">http://zeosbugs.firmos.at</a></p><div class=\"itemizedlist\"><ul type=\"disc\" compact><li><a href=\"http://zeosbugs.firmos.at/view.php?id=123\" target=\"_top\">#0000123</a> [normal] Can not open TZTable in PostgreSQL (Replaced fix for Mantis Bug 97 (SVN rev. 344) by a more correct one)</li><li><a href=\"http://zeosbugs.firmos.at/view.php?id=106\" target=\"_top\">#0000106</a> [normal] After Post of DataSet with Filtered=True, SortedFields defined, Row position is changed unexpectedly</li><li><a href=\"http://zeosbugs.firmos.at/view.php?id=122\" target=\"_top\">#0000122</a> [normal] Problem with quoted fields (PostgreSQL keywords)</li><li><a href=\"http://zeosbugs.firmos.at/view.php?id=121\" target=\"_top\">#0000121</a> [normal] ZQuery Insert/Update problem with MSSQL/ADO</li><li><a href=\"http://zeosbugs.firmos.at/view.php?id=119\" target=\"_top\">#0000119</a> [normal] Memory leak in ZDbcSqLiteResultSet.pas</li><li><a href=\"http://zeosbugs.firmos.at/view.php?id=113\" target=\"_top\">#0000113</a> [high] MYSQL - EZSQLException with message 'Column with name \"Extra\" was not found'. using latest MySQL 5.1.x</li><li><a href=\"http://zeosbugs.firmos.at/view.php?id=108\" target=\"_top\">#0000108</a> [normal] Duplicated result when using locate, loPartialKey and Filter</li><li><a href=\"http://zeosbugs.firmos.at/view.php?id=111\" target=\"_top\">#0000111</a> [normal] Lookup field value disappers on insert and edit and reappears after post or cancel</li><li><a href=\"http://zeosbugs.firmos.at/view.php?id=105\" target=\"_top\">#0000105</a> [normal] Fields default expresion is determined from the wrong source</li><li><a href=\"http://zeosbugs.firmos.at/view.php?id=95\" target=\"_top\">#0000095</a> [normal] It is impossible to be connected to base on tcpip</li><li><a href=\"http://zeosbugs.firmos.at/view.php?id=99\" target=\"_top\">#0000099</a> [normal] Read only fields not really read only</li><li><a href=\"http://zeosbugs.firmos.at/view.php?id=94\" target=\"_top\">#0000094</a> [normal] Invalid argument to time encode</li><li><a href=\"http://zeosbugs.firmos.at/view.php?id=97\" target=\"_top\">#0000097</a> [normal] Cannot open table where tablename is similar to database name (Quoting TZTable.tablename)</li><li><a href=\"http://zeosbugs.firmos.at/view.php?id=93\" target=\"_top\">#0000093</a> [normal] Wrong clearing of allocated data for SQLDA</li><li><a href=\"http://zeosbugs.firmos.at/view.php?id=90\" target=\"_top\">#0000090</a> [normal] Default values from table are not used / Corrected Null fields handling in combination with autoinc and default values</li><li><a href=\"http://zeosbugs.firmos.at/view.php?id=88\" target=\"_top\">#0000088</a> [normal] Delphi11 test packages missing in ZEOSLIB_TESTING_REV329</li><li><a href=\"http://zeosbugs.firmos.at/view.php?id=86\" target=\"_top\">#0000086</a> [normal] Field values truncated</li><li><a href=\"http://zeosbugs.firmos.at/view.php?id=87\" target=\"_top\">#0000087</a> [normal] Backslash gone in resultset</li><li><a href=\"http://zeosbugs.firmos.at/view.php?id=82\" target=\"_top\">#0000082</a> [normal] Incorrect catalog name when no schema present and incorrect order</li><li><a href=\"http://zeosbugs.firmos.at/view.php?id=80\" target=\"_top\">#0000080</a> [high] Naming convention in release build...</li></ul></div></div><div class=\"sect2\" lang=\"en\"><div class=\"titlepage\"><div><div><h3 class=\"title\"><a id=\"d4e604\"></a>7.2.&nbsp;Other Bugs fixed</h3></div></div></div><div class=\"itemizedlist\"><ul type=\"disc\" compact><li>[COMMON] Enabled BeforeRefresh and AfterRefresh Dataset properties for FPC2 (<a href=\"http://zeos.firmos.at/viewtopic.php?t=1749\" target=\"_top\">http://zeos.firmos.at/viewtopic.php?t=1749</a>)</li><li>[COMMON] Quoted Aliases in queries were not recognised (<a href=\"http://zeos.firmos.at/viewtopic.php?t=1797\" target=\"_top\">http://zeos.firmos.at/viewtopic.php?t=1797</a>)</li><li>[COMMON] In Delphi 2006 and FPC 2.1 TWideStringField.SetAsWideString() puts a PWideChar into the buffer, so deserializing it as a PWideString is probably wrong. (<a href=\"http://fisheye3.cenqua.com/changelog/heidisql?cs=1383\" target=\"_top\">http://fisheye3.cenqua.com/changelog/heidisql?cs=1383</a>)</li><li>[COMMON] Remove \"TextHeight = 13\" from UpdateSql Editor in Lazarus (<a href=\"http://zeos.firmos.at/viewtopic.php?t=1872\" target=\"_top\">http://zeos.firmos.at/viewtopic.php?t=1872</a>)</li><li>[COMMON] Don't use ASM call in TZCollection.Error when using FPC. FPC should be able to do this platform independent (<a href=\"http://zeos.firmos.at/viewtopic.php?t=1882\" target=\"_top\">http://zeos.firmos.at/viewtopic.php?t=1882</a>)</li><li>[COMMON] Fixed Delphi5 compilation</li><li>[COMMON] Join two tokens if the first is a ttInteger and the next a ttWord (<a href=\"http://zeos.firmos.at/viewtopic.php?t=1897\" target=\"_top\">http://zeos.firmos.at/viewtopic.php?t=1897</a>)</li><li>[IB/FB] Metadata.GetColumns corrected (<a href=\"http://zeos.firmos.at/viewtopic.php?t=1682\" target=\"_top\">http://zeos.firmos.at/viewtopic.php?t=1682</a>)</li><li>[IB/FB] Autocommit didn't work for TZStoredProcedure when using Firebird</li></ul></div></div><div class=\"sect2\" lang=\"en\"><div class=\"titlepage\"><div><div><h3 class=\"title\"><a id=\"d4e632\"></a>7.3.&nbsp;Features added</h3></div></div></div><div class=\"itemizedlist\"><ul type=\"disc\" compact><li>[COMMON] Added polish translation</li><li>[SQLite3] Improve Column Affinity (<a href=\"http://zeos.firmos.at/viewtopic.php?t=1605\" target=\"_top\">http://zeos.firmos.at/viewtopic.php?t=1605</a>)</li><li>[COMMON] Added ZConnection.ExecuteDirect and ZConnection.ExecuteUpdateDirect functions (<a href=\"http://zeos.firmos.at/viewtopic.php?t=1656\" target=\"_top\">http://zeos.firmos.at/viewtopic.php?t=1656</a>)</li><li>[COMMON] Automatically generated updates could update more than 1 row at once or no row at all. Query property &#8216;ValidateUpdateCount=true/false&#8217; added (<a href=\"http://zeos.firmos.at/viewtopic.php?t=1757\" target=\"_top\">http://zeos.firmos.at/viewtopic.php?t=1757</a>)</li><li>[COMMON] Added ZIBEventAlerter to the components package</li><li>[COMMON] Added TZTable.exists (<a href=\"http://zeos.firmos.at/viewtopic.php?t=1879)\" target=\"_top\">http://zeos.firmos.at/viewtopic.php?t=1879)</a>)</li><li>[IB/FB] Added support for Firebird hard commits. (Very experimental!!!)</li><li>[MYSQL] Added libmysql51.dll to list of possible dll's for protocol Mysql-5</li></ul></div></div><div class=\"sect2\" lang=\"en\"><div class=\"titlepage\"><div><div><h3 class=\"title\"><a id=\"d4e655\"></a>7.4.&nbsp;Internal Changes</h3></div></div></div><div class=\"itemizedlist\"><ul type=\"disc\" compact><li>[COMMON] ant build support for Linux added</li><li>[COMMON] Added GetXxxCacheKey functions (<a href=\"http://zeos.firmos.at/viewtopic.php?t=1881\" target=\"_top\">http://zeos.firmos.at/viewtopic.php?t=1881</a>)</li><li>[COMMON] Removed caching code that was identical between all descendent classes of TZAbstractDatabaseMetadata (<a href=\"http://zeos.firmos.at/viewtopic.php?t=1881\" target=\"_top\">http://zeos.firmos.at/viewtopic.php?t=1881</a>)</li><li>[MYSQL] Added new constants for mysql 5.1 library</li></ul></div></div></div><div class=\"sect1\" lang=\"en\"><div class=\"titlepage\"><div><div><h2 class=\"title\" style=\"clear: both\"><a id=\"d4e668\"></a>8.&nbsp;Changes in Release 6.6.2 - rc (12.12.2007)</h2></div></div></div><div class=\"toc\"><dl><dt><span class=\"sect2\"><a href=\"#d4e670\">8.1. Bugs fixed from Mantis Bug Tracker</a></span></dt><dt><span class=\"sect2\"><a href=\"#d4e751\">8.2. Other Bugs fixed</a></span></dt><dt><span class=\"sect2\"><a href=\"#d4e793\">8.3. Features added</a></span></dt><dt><span class=\"sect2\"><a href=\"#d4e839\">8.4. Internal changes</a></span></dt></dl></div><div class=\"sect2\" lang=\"en\"><div class=\"titlepage\"><div><div><h3 class=\"title\"><a id=\"d4e670\"></a>8.1.&nbsp;Bugs fixed from Mantis Bug Tracker</h3></div></div></div><p>The bug tracker can be found at: <a href=\"http://zeosbugs.firmos.at/\" target=\"_top\">http://zeosbugs.firmos.at</a></p><div class=\"itemizedlist\"><ul type=\"disc\" compact><li>#0000022: [general] Split ZPlainMysql.inc</li><li>#0000023: [component] Problem using WideStrings and ADO protocol when chaging any WideString Field Data, same nature as Issue 0010 (fduenas)</li><li>#0000016: [core] Integer field treated as Largeint </li><li>#0000005: [postgresql] Memory grow when connection failed</li><li>#0000013: [interbase/firebird] can not use a string as parameter value for integer/long parameters</li><li>#0000019: [interbase/firebird] string parameters don't work for blob fields</li><li>#0000033: [interbase/firebird] Fixes a bug in UpdateString procedure for ZDbcInterbase6Utils </li><li>#0000034: [interbase/firebird] Lookup field make other field in TZQuery lost the value (disappear from display but still exists in database)</li><li>#0000020: [interbase/firebird] second call to stored proc fail with a parameter mismatch error (cipto_kh)</li><li>#0000040: [component] Error in conversion int64 to variant in InternalPost on Delphi/C++Builder 5 (ZAbstractDataset.pas)</li><li>#0000042: [general] Using the same component (TZStoredProcedure) after ExecProc then using Open it will crash (cipto_kh)</li><li>#0000037: [component] ZEOS AND LAZARUS 0.9.23 and FPC 2.1.3 WIN32 ERROR</li><li>#0000038: [component] Can't open sqlite databases with Umlauts like &auml;&ouml;&uuml; in path (fixed)</li><li>#0000046: [component] fpc 2.1.4 cannot compile ZAbstractRODataset.pas</li><li>#0000028: [interbase/firebird] TZInterbase6DatabaseMetadata.HasNoWildcards - wrong result (cipto_kh)</li><li>#0000055: [component] Wrong index variable used when doing \"refresh\" in ZUpdateSQL component</li><li>#0000050: [postgresql] 'Access Violation' error on ZQuery.Open on table that has columns with non-standard type</li><li>#0000041: [postgresql] TZPostgreSQLDatabaseMetadata.GetSequences return not schema-qualified sequence list (ZDbcPostgreSqlMetadata.pas)</li><li>#0000049: [core] Lookup fields with int64 data type not work in Delphi/C++Builder 5</li><li>#0000007: [interbase/firebird] TZSequence error, value from prior database (cipto_kh)</li><li>#0000048: [general] TZSQLProcessor does not react when Script text is not properly delimited</li><li>#0000056: [component] Protection fault when doing an EAbort exception in BeforeConnect of TZConnection (patch incl.)</li><li>#0000064: [parsesql] Mysql /*! ...*/ special comments shouldn't be considered as real comments</li><li>#0000063: [component] TZSQLProcessor and comments handling</li><li>#0000061: [component] Wrong data returning in select</li><li>#0000065: [general] FPC 2.2 doesn't compile</li><li>#0000068: [postgresql] Wrong datatype declared</li><li>#0000043: [component] ReadOnlyQuery + TDataSetProvider = Blank fields on details</li><li>#0000059: [component] ZQuery-DSP-CDS empty field data fetched while using incremental fetching (PacketRecords&gt;0</li><li>#0000027: [interbase/firebird] problem handling DEFAULT NULL in domain *AND* in table</li><li>#0000069: [general] Compiler Warnings in Delphi 2006</li><li>#0000071: [interbase/firebird] Floating point not display correctly (cipto_kh)</li><li>#0000076: [mysql] SSL Connection Error</li><li>#0000075: [sqlite] Memory Error Detected</li><li>#0000070: [general] Missing license files</li><li>#0000079: [dbc] Typo in SQl statement in TZInterbase6Connection.Open;</li><li>#0000017: [mysql] LargeInt fields treated as Variant</li><li>#0000060: [sqlite] Memory leaks in sqlite-3 driver</li></ul></div></div><div class=\"sect2\" lang=\"en\"><div class=\"titlepage\"><div><div><h3 class=\"title\"><a id=\"d4e751\"></a>8.2.&nbsp;Other Bugs fixed</h3></div></div></div><div class=\"itemizedlist\"><ul type=\"disc\" compact><li>Metadata (mdTables) was missing remarks data (http://zeos.firmos.at/viewtopic.php?t=1567)</li><li>Memory leaks (http://zeos.firmos.at/viewtopic.php?t=1408)</li><li>Correction of child dataset refresh (http://zeos.firmos.at/viewtopic.php?t=1381)</li><li>Set autocommit issue when transaction isolation=tiNone (http://zeos.firmos.at/viewtopic.php?t=1251)</li><li>TZAdoDatabaseMetadata.GetColumns doesn't fetch database and schema names. (http://zeos.firmos.at/viewtopic.php?t=1252)</li><li>TZRowAccessor.CompareBuffers didn't work for stUnicodeStreams (http://zeos.firmos.at/viewtopic.php?t=1254)</li><li>TZSQLStrings.StatementCount = 1 when the statement is empty (http://zeos.firmos.at/viewtopic.php?t=1228)</li><li>Error handling empty string values (makes them NULLS) (http://zeos.firmos.at/viewtopic.php?t=1255)</li><li>Read blob truncates last byte for ADO (http://zeos.firmos.at/viewtopic.php?t=1250)</li><li>Close/Open sequence replaced by refresh in TZAbstractRODataset.RefreshParams (http://zeos.firmos.at/viewtopic.php?t=1093)</li><li>Wrong mysql version reference in GetMoreResults function</li><li>Required should be false if a field is not writable (http://zeos.firmos.at/viewtopic.php?t=767)</li><li>Avoid open/close of detail dataset on edit of master dataset (http://zeos.firmos.at/viewtopic.php?t=1093)</li><li>FreeAndNil fix in ZSequence - (http://zeos.firmos.at/viewtopic.php?t=1108)</li><li><p>Mysql fixes by HeidiSQL Team (Repository viewer at http://fisheye3.cenqua.com/changelog/heidisql)</p><div class=\"itemizedlist\"><ul type=\"circle\" compact><li>Avoid an access violation within a for loop which got run once even when there were 0 columns in a result. (HeidiSql rev. 993)</li><li>Fix bug \"SHOW FULL PROCESSLIST on mysql v4 server messes Zeos up\". (HeidiSql rev. 775 and 900)</li><li>Fix handling default values. (HeidiSql rev. 505)</li><li>Zeos did not recognize UNSIGNED ZEROFILL columns as being UNSIGNED. (HeidiSql rev. 521)</li></ul></div></li></ul></div></div><div class=\"sect2\" lang=\"en\"><div class=\"titlepage\"><div><div><h3 class=\"title\"><a id=\"d4e793\"></a>8.3.&nbsp;Features added</h3></div></div></div><div class=\"itemizedlist\"><ul type=\"disc\" compact><li>All mysql_options() and connection clientflag settings can now be set using TZConnection.Properties (http://zeos.firmos.at/viewtopic.php?t=1528)</li><li>Updated indonesian translations (by tohenk)</li><li>Added Russian translation (by ormada)</li><li>Use Mysql_real_escape_string instead of mysql_escape_string when executing mysql emulated prepared statements</li><li>Added IZConnection.EscapeString function. This funtion returns a string that can be used in SQL statements. Uses Mysql_real_escape_string or Mysql_escape_string functions for mysql databases and EncodeCString function for other databases</li><li>FPC changes -&gt; now zeoslib also works with MSEIDE - By MSEIDE team (http://www.homepage.bluewin.ch/msegui)</li><li>Added all reserved words, functions from mysql 5.1 documentation to metadata GetXXX functions (http://zeos.firmos.at/viewtopic.php?t=1213)</li><li>Replaced 'Select' in Getversion to Native library call</li><li>Added support for Mysql SSL connections</li><li>Added TZConnection.GetColumnNames function (http://zeos.firmos.at/viewtopic.php?t=1127)</li><li>Added Delphi2007 package files (http://zeos.firmos.at/viewtopic.php?t=1173)</li><li>Changed PingServer behaviour : Only return false when ping fails. No exception. This function is a check, so it should be allowed to return false. On demand of HeidiSql team. </li><li>Modified Readme text for mysql embedded server example</li><li>Added Multiple resultset support on Dbc level (http://zeos.firmos.at/viewtopic.php?t=459 and http://zeos.firmos.at/viewtopic.php?t=912)</li><li>ZDataset Events in Lazarus (http://zeos.firmos.at/viewtopic.php?t=1130)</li><li><p>New Features by HeidiSQL Team (Repository viewer at http://fisheye3.cenqua.com/changelog/heidisql)</p><div class=\"itemizedlist\"><ul type=\"circle\" compact><li>Added unknown data types from mysql_com.h. (HeidiSQL rev. 835)</li><li>Make ConvertMySQLHandleToSQLType() more readable (HeidiSql rev. 676)</li><li>Ignore columns that do not originate from the table when resolving updates (HeidiSql rev. 555)</li><li>Added function TZAbstractResultSetMetadata.HasDefaultValue (HeidiSql rev. 504)</li><li>TZConnection.Reconnect added (HeidiSql rev. 53)</li></ul></div></li></ul></div></div><div class=\"sect2\" lang=\"en\"><div class=\"titlepage\"><div><div><h3 class=\"title\"><a id=\"d4e839\"></a>8.4.&nbsp;Internal changes</h3></div></div></div><div class=\"itemizedlist\"><ul type=\"disc\" compact><li>Release build script has been rewritten</li><li>Fixed the automatic build system and test suite. Works now certainly for D5, D7, D2006, D2007</li><li>Added SVN ant utilities to repository so build scripts should run on a standard Ant installation</li><li>Added Lazarus/Fpc to the automatic build system. Test suite is not available, however. Package *.pas files are necessary for automated build system.</li><li>Removed some compiler warnings and unused units.</li><li>Start of the zeoslib documentation project using doxygen</li></ul></div></div></div><div class=\"sect1\" lang=\"en\"><div class=\"titlepage\"><div><div><h2 class=\"title\" style=\"clear: both\"><a id=\"d4e854\"></a>9.&nbsp;Changes in Release 6.6.1 - beta (25.02.2007)</h2></div></div></div><div class=\"toc\"><dl><dt><span class=\"sect2\"><a href=\"#d4e856\">9.1. Bugs fixed</a></span></dt></dl></div><div class=\"sect2\" lang=\"en\"><div class=\"titlepage\"><div><div><h3 class=\"title\"><a id=\"d4e856\"></a>9.1.&nbsp;Bugs fixed</h3></div></div></div><div class=\"itemizedlist\"><ul type=\"disc\" compact><li>#0000003: Field confusion in GetColumnInfo</li><li><p>#0000010: Widestring field's contents Using ado protocol and access database is unreadable</p><p>When using a TzQuery or TZTable using ado protocol and an access database with OLEDB Jet engine, the contents of any TWideString field is unreadable (it returns symbols) and sometimes throws Out of Memory error.</p></li><li>#0000016: Integer field treated as Largeint</li><li>#0000003: Field confusion in GetColumnInfo</li><li><p>#0000021: ClientVersion and ServerVersion properties fail on closed connection</p><p>When calling ClientVersion and ServerVersion on a closed mysql connection they refer to an unassigned object.</p></li><li><p>#0000023: Problem using WideStrings and ADO protocol when chaging any WideString Field Data, same nature as Issue #0000010</p><p>When using a TzQuery or TZTable using ado protocol and an access database with OLEDB Jet engine, when changing the the contents of any TWideString field, the values is unreadable (it returns symbols) and sometimes throws Out of Memory error.</p></li><li>EOutofMemory with Delphi 2006 + Firebird (http://zeos.firmos.at/viewtopic.php?t=972)</li><li>Zeos 6.6-Beta: func GetTableNames() / PingServer (http://zeos.firmos.at/viewtopic.php?t=992)</li><li>Race happens? (http://zeos.firmos.at/viewtopic.php?t=974)</li><li>MySQL and FLOAT fields (precision) (http://zeos.firmos.at/viewtopic.php?t=930)</li><li>Memory Leak - ZeosLib 6.5.1, MySQL 4.1, Lazarus (http://zeos.firmos.at/viewtopic.php?t=812)</li><li>Bug in ZAbstractRODataset (6.6.0 beta version) (http://zeos.firmos.at/viewtopic.php?t=898)</li><li>Bug in ZDbcPostgreSqlMetadata.pas(6.6 beta) (http://zeos.firmos.at/viewtopic.php?t=839)</li><li>Postgres Blob field bug (http://zeos.firmos.at/viewtopic.php?t=931)</li><li>Do not work sorterfields (http://zeos.firmos.at/viewtopic.php?t=920)</li><li>Fix for TZInterbase6DatabaseMetadata.GetSequence (http://zeos.firmos.at/viewtopic.php?t=864)</li><li>ERangeError after FormCreate (http://zeos.firmos.at/viewtopic.php?t=902)</li><li>Delphi5 and MySql5 (http://zeos.firmos.at/viewtopic.php?t=886)</li><li>Zquery and Ztable not accept numeric database (http://zeos.firmos.at/viewtopic.php?t=882)</li><li>BCB6 ZDbc.bpk (http://zeos.firmos.at/viewtopic.php?t=854)</li><li>Fix for Bug in ZInterbase6Sequence.GetNextValue (http://zeos.firmos.at/viewtopic.php?t=856)</li><li>ztable problem : editing and TableName (http://zeos.firmos.at/viewtopic.php?t=748)</li><li>MySQL: Cannot update this query type(backticks) (http://zeos.firmos.at/viewtopic.php?t=552)</li><li>InterBase/FireBird BLOB handling error (http://zeos.firmos.at/viewtopic.php?t=855)</li><li>Duplicate messages in portuguese language (ttp://zeos.firmos.at/viewtopic.php?t=848)</li></ul></div></div></div><div class=\"sect1\" lang=\"en\"><div class=\"titlepage\"><div><div><h2 class=\"title\" style=\"clear: both\"><a id=\"d4e912\"></a>10.&nbsp;Changes in Release 6.6.0 - beta (20.10.2006)</h2></div></div></div><div class=\"toc\"><dl><dt><span class=\"sect2\"><a href=\"#d4e914\">10.1. Features added</a></span></dt><dt><span class=\"sect2\"><a href=\"#d4e1029\">10.2. Patches applied</a></span></dt><dt><span class=\"sect2\"><a href=\"#d4e1046\">10.3. Bugs fixed</a></span></dt></dl></div><div class=\"sect2\" lang=\"en\"><div class=\"titlepage\"><div><div><h3 class=\"title\"><a id=\"d4e914\"></a>10.1.&nbsp;Features added</h3></div></div></div><div class=\"itemizedlist\"><ul type=\"disc\" compact><li>LinkedFieldNames vs. IndexFieldnames (See http://zeos.firmos.at/viewtopic.php?t=796) </li><li>New Dataset features : BeforeApplyUpdates (event), AfterApplyUpdates (event), SortType (property), EmptyDataSet (procedure) </li><li>Added separate drivers for embedded Firebird server (http://zeos.firmos.at/viewtopic.php?t=630) </li><li>Delphi 2006 packages </li><li>Mysql5 Support integrated </li><li>PostgreSQL 8.x Support integrated </li><li>Added Sybase Adapitive Serve Anywhere (ASA) Support for Versions 7, 8 and 9.</li><li>MySQL Ping Commando added </li><li>Insert \"const\" for ref-counted parameter (http://zeos.firmos.at/viewtopic.php?t=519) </li><li>MySQL Embedded Server Arguments (http://zeos.firmos.at/viewtopic.php?t=777) </li><li>separated Firebird from interbase/strict dll loading for Firebird </li><li>TZConnection: property 'Version', showing the current version </li><li>Support for fkInternalCalcFields in datasets </li><li>Added property DesignConnection: If DesignConnection is true connected is not set to true during runtime and must be set explicitly </li><li>Enabled all connection options for mysql. Now one can add the desired options by adding them to the connections property strings. </li><li>Rewrite of ZPlainMysqlXX files to add embedded server support for versions 4.0,4.1,5 of  mysql </li><li>Added new library functions to plain mysql drivers (4.1) </li><li>Added new library functions to plain mysql drivers (3.23 and 3.20) </li><li>Error handling for Postgres now returns result codes from server </li><li>Two Phase Commit for PostgreSQL </li><li>Added parameter capability to TZSQLProcessor so you now can use parameters inside your SQL scripts like you do in \"normal\" queries.</li><li>Added const \"ZEOS_VERSION\" to ZClasses and added property \"Version\" to TZConnection.</li><li>Added support of fkInternalCalcFields for ZEOS datasets.</li><li>Added property \"DesignConnection\" to turn off active design time connections during runtime, automatically.</li><li>Added PropertyEditor for TField-properties in several components.</li><li><p>Added default values to the following properties:</p><div class=\"itemizedlist\"><ul type=\"circle\" compact><li>TZAbstractRODataset.RequestLive: False</li><li>TZAbstractRODataset.ParamCheck: True</li><li>TZAbstractRODataset.ShowRecordTypes: [usUnmodified, usModified, usInserted]</li><li>TZAbstractRODataset.IsUniDirectional: False</li><li>TZAbstractRODataset.Options: [doCalcDefaults]</li><li>TZAbstractRODataset.ReadOnly: True</li><li>TZAbstractDataset.UpdateMode: umUpdateChanged</li><li>TZAbstractDataset.WhereMode: wmWhereKeyOnly</li><li>TZAbstractDataset.CachedUpdates: False</li><li>TZConnection.SQLHourGlass: False</li><li>TZQuery.ReadOnly: False</li><li>TZTable.ReadOnly: False</li><li>TZSqlMetadata.Scope: 0</li><li>TZSqlMetadata.Nullable: False</li><li>TZSqlMetadata.Unique: False</li><li>TZSqlMetadata.Approximate: False</li></ul></div></li><li><p>/<span class=\"othername\">SG</span>/ Changed default values for following properties:</p><div class=\"itemizedlist\"><ul type=\"circle\" compact><li>TZConnection.ReadOnly: False</li></ul></div></li><li><p>/<span class=\"othername\">SG</span>/ Changed following default initializations:</p><div class=\"itemizedlist\"><ul type=\"circle\" compact><li>- TZAbstractDataset.RequestLive := True;</li><li>TZConnection.ReadOnly := False;</li></ul></div></li><li><p>/<span class=\"othername\">SG</span>/ Changed following property names:</p><div class=\"itemizedlist\"><ul type=\"circle\" compact><li>TZQuery.RequestLive --&gt; TZQuery.ReadOnly</li></ul></div></li><li>/<span class=\"othername\">SG</span>/ Added parameter capability to TZSQLProcessor like in TZQuery.</li></ul></div></div><div class=\"sect2\" lang=\"en\"><div class=\"titlepage\"><div><div><h3 class=\"title\"><a id=\"d4e1029\"></a>10.2.&nbsp;Patches applied</h3></div></div></div><div class=\"itemizedlist\"><ul type=\"disc\" compact><li>Const and optimization (http://zeos.firmos.at/viewtopic.php?t=551)</li><li>MissingConsts, Inlining, SilentException (http://zeos.firmos.at/viewtopic.php?t=566)</li><li>Packages for delphi 6 (http://zeos.firmos.at/viewtopic.php?t=577)</li><li>PostgreSQL EncodeString() (http://zeos.firmos.at/viewtopic.php?t=589)</li><li>Date, Time and Float on Lazarus (http://zeos.firmos.at/viewtopic.php?t=598)</li><li>Updates for ZMessages (translations)</li><li>Const modifier added to function definitions where possible to improve speed (http://zeos.firmos.atviewtopic.php?t=519)</li></ul></div></div><div class=\"sect2\" lang=\"en\"><div class=\"titlepage\"><div><div><h3 class=\"title\"><a id=\"d4e1046\"></a>10.3.&nbsp;Bugs fixed</h3></div></div></div><div class=\"itemizedlist\"><ul type=\"disc\" compact><li>ZDbcConnection.pas contains wrong line breaks (http://zeos.firmos.at/viewtopic.php?t=553)</li><li>Other files with LF instead of CRLF (http://zeos.firmos.at/viewtopic.php?t=554)</li><li>svn rev. 59 (Linux filenames problem) (http://zeos.firmos.at/viewtopic.php?t=593)</li><li>error type date in lazarus (http://zeos.firmos.at/viewtopic.php?t=574)</li><li>MySQL v.5.0 .3+ and Decimals (http://zeos.firmos.at/viewtopic.php?t=605)</li><li>ZSqlUpdate append error (http://zeos.firmos.at/viewtopic.php?t=677)</li><li>Error opening Query (http://zeos.firmos.at/viewtopic.php?t=628)</li><li>Compiling in Borland C++ Builder 6 (http://zeos.firmos.at/viewtopic.php?t=694)</li><li>compiling for delphi5/6 (http://zeos.firmos.at/viewtopic.php?t=802)</li><li>Memory leak MSSQL2000 TZQuery.ExecSQL (http://zeos.firmos.at/viewtopic.php?t=788)</li><li>ZEOS_TESTING_REV_113 Sybase-Bug (http://zeos.firmos.at/viewtopic.php?t=822)</li><li>Removed Rangecheck Directive (all files) (FPC 2.0.2 is buggy)</li><li>Updated lazarus package for correct compilation. (Missing packages, corrupt package file,...)</li><li>Some more Lazarus package modifications</li><li>Memory leak bug fixed (http://zeos.firmos.at/viewtopic.php?t=461)</li><li>Delimiter problem in ZSQLProcessor fixed (http://zeos.firmos.at/viewtopic.php?t=527)</li><li>Fixed Delphi 5 install problems (http://zeos.firmos.at/viewtopic.php?t=335)</li><li>Added {$LIBSUFFIX 'X0'} to projectfiles of D7 and D2006 (http://zeos.firmos.at/viewtopic.php?t=561)</li><li>Removed ASA driver from Lazarus packages because not compilable in Lazarus.</li><li>Bug in GetIndexInfo (http://zeos.firmos.at/viewtopic.php?t=196)</li><li>Added GetClientVersion and GetServerVersion to Connection/Driver interfaces</li><li>Integrated contribution from Terence : Added more specific metadata clearcache possibilities.</li><li>Delphi 7 : Split up Component Package into Component and ComponentDesign (http://zeos.firmos.at/viewtopic.php?t=726)</li><li>Delphi 7 : Added compiler directives to avoid inclusion of not wanted database drivers. (http://zeos.firmos.at/viewtopic.php?t=746)</li><li>InternalPost (Procedure) (http://zeos.firmos.at/viewtopic.php?t=781)</li><li>Updatesql component (OnUpdate event)</li><li>Mssql Select * error (http://zeos.firmos.at/viewtopic.php?t=788)</li><li>Added Lazarus fixes : ASA support did not compile well.</li><li>Firebird: Memory leak bug fixed (http://zeos.firmos.at/viewtopic.php?t=461)</li><li>Corrections for non-strict dllloading</li><li>Bytea/blob - PostgreSQL - UNICODE/UTF8 (http://zeos.firmos.at/viewtopic.php?t=683)</li><li>Integrated patch from Fduenas concerning http://zeos.firmos.at/viewtopic.php?t=677</li><li>Mysql MetaData Patch to support temporary tables</li><li>Corrected the temporary tables patch. Now it tries to get information on a 'non-existing' table, just in case it is a temporarary one. If it is temporary the table is added to the cache If it's not, the resulting error is suppressed but the table will stay unknown.</li><li>Various modifications/extentions to Mysql DBC and Plain driver units - Written by fduenas and mdaems</li><li>Removed calls to Mysql datastructure where possible (Only necessary for mysql3.20) - written by mdaems</li><li>Bad tiReadCommited corrected (http://zeos.firmos.at/viewtopic.php?t=570)</li><li>Widestring Fields are always returning Null if one tries to access property Value.</li><li>Firebird 1.5: field named \"STATUS_REG\" that doesn't show in TZDataSet.</li><li>FPC/Lazarus: Connecting to a Firebird Database will cause a Range Check Error.</li><li>Zeos appears to be bringing back Postgresql money type as ftfloat instead of ftcurrency.</li><li>Row inserting is impossible with simple queries when TZQuery.ReadOnly property set to false and no TZQuery.UpdateObject defined.</li><li>In the metadata, all user tables were being reported as type VIEW.</li><li>Problem in ZSysUtils.BytesToVar().</li><li>Problem with TZAbstractDataset.InternalPost.</li><li>When using GetPChar()  Result of GetPChar() points to unallocated memory.</li><li>ZeosDBO (Ado) update problem with TZUpdateSQL</li><li>Username property not refreshed if changed in login box</li><li>Problem with TZTable refresh method</li><li>IProviderSupport - PSUpdateRecord</li><li>Firebird 1.5 Read Only Database on CD</li><li>ZQuery's FieldsEditor brings diff. types for the same field</li><li>Login Dialog unstable appearance</li><li>Wrong results for lookup fields</li><li>open cursors in Oracle</li><li>Change data when Dataset.State = dsBrowse</li><li>Exception when deleting record with ClientDataSet</li><li>Strange behaviour Zeos - DBLookUpComboBox</li><li>CreateStatement and Properties</li><li>WideString Updates</li><li>MySQL:zeos doesnt assign default '0000-00-00' to Date Fields</li><li>TZAbstractRODataset.RereadRows;</li><li>CaseSensitive locate on WideString fields</li><li>Filter issues</li><li>AV error when opening a DML with a TZQuery using doSmartOpen</li><li>Incorrect TZPostgreSQLNotify definition</li><li>Access violation on large string fields.</li><li>MySQL Date/Time bug + Fix</li><li>Firebird 1.5: unsupported datatype</li><li>Startup failing if compiled with \"Full Boolean Evaluation\"</li><li>SetFieldData for ftString don't refresh</li><li>ADO TDateTime parameter wrong type</li><li>TZTable's TabeleName Property - not list with ADO protocol</li></ul></div></div></div><div class=\"sect1\" lang=\"en\"><div class=\"titlepage\"><div><div><h2 class=\"title\" style=\"clear: both\"><a id=\"d4e1195\"></a>11.&nbsp;Changes in Release 6.5</h2></div></div></div><div class=\"toc\"><dl><dt><span class=\"sect2\"><a href=\"#d4e1197\">11.1. Release 6.5.1 - 23 Nov 2004</a></span></dt><dt><span class=\"sect2\"><a href=\"#d4e1208\">11.2. Release 6.5.1 - 17 July 2004</a></span></dt><dt><span class=\"sect2\"><a href=\"#d4e1271\">11.3. Release 6.5.0 - 10 March 2004</a></span></dt></dl></div><div class=\"sect2\" lang=\"en\"><div class=\"titlepage\"><div><div><h3 class=\"title\"><a id=\"d4e1197\"></a>11.1.&nbsp;Release 6.5.1 - 23 Nov 2004</h3></div></div></div><div class=\"itemizedlist\"><ul type=\"disc\" compact><li>/<span class=\"othername\">CNL</span>/ Fixed Bug#912639 Result sets were not decoded</li><li>/<span class=\"othername\">CNL</span>/ Another version of PostgreSQLToSQLType() is added to boost execution speed</li></ul></div></div><div class=\"sect2\" lang=\"en\"><div class=\"titlepage\"><div><div><h3 class=\"title\"><a id=\"d4e1208\"></a>11.2.&nbsp;Release 6.5.1 - 17 July 2004</h3></div></div></div><div class=\"itemizedlist\"><ul type=\"disc\" compact><li>/<span class=\"othername\">SM</span>/ Fixed Bug#1021705 Numeric values overflow</li><li>/<span class=\"othername\">SM</span>/ Fixed Bug#1034795 Metadata don't filter the table type</li><li>/<span class=\"othername\">SM</span>/ Fixed Bug#993352 problem with TZInterbase6DatabaseMetadata.GetTables table type SYSTEM TABLE</li><li>/<span class=\"othername\">SM</span>/ Fixed Bug#991069 Creation of a DB and FKs in Firebird</li><li>/<span class=\"othername\">SS</span>/ Fixed Bug#985629 Locate and Lookup don't find float fields.</li><li>/<span class=\"othername\">SS</span>/ Added database error codes to rethrown exceptions in dataset.</li><li>/<span class=\"othername\">SS</span>/ Fixed Bug#993981 MySQL and PostgreSQL drivers do not process float values if decimal separator other then &#8220;<span class=\"quote\">.</span>&#8221;.</li><li>/<span class=\"othername\">SS</span>/ Fixed Bug#995080 &#8220;<span class=\"quote\">List Index Out of Bounds</span>&#8221; exception in <tt class=\"classname\">Dataset</tt>.<tt class=\"methodname\">UpdateStatus</tt> on empty resultset.</li><li>/<span class=\"othername\">SS</span>/ Fixed Bug#999658 Truncation of BigDecimal fields. Thanks to Kestutis Laurinavicius.</li><li>/<span class=\"othername\">SS</span>/ Fixed Bug#1000534. SQL Parser error when &#8220;<span class=\"quote\">join ... on</span>&#8221; clause contains functions with parameters.</li><li>/<span class=\"othername\">SS</span>/ Fixed Bug#1004534 Access Violation when <tt class=\"methodname\">RecNo</tt> is called on closed Dataset.</li><li>/<span class=\"othername\">SS</span>/ Fixed Bug#1045286 Method <tt class=\"methodname\">IsNull</tt> returns incorrect result for fields containing &#8220;<span class=\"quote\"></span>&#8221; characters.</li><li>/<span class=\"othername\">SS</span>/ Added support for cidr, inet and macaddr column types into PostgreSQL driver.</li></ul></div></div><div class=\"sect2\" lang=\"en\"><div class=\"titlepage\"><div><div><h3 class=\"title\"><a id=\"d4e1271\"></a>11.3.&nbsp;Release 6.5.0 - 10 March 2004</h3></div></div></div><div class=\"itemizedlist\"><ul type=\"disc\" compact><li>/<span class=\"othername\">SS</span>/ Added IProviderSupport interface implementation to datasets.</li><li>/<span class=\"othername\">SS</span>/ Added support for MySQL 4.1 database.</li><li>/<span class=\"othername\">SS</span>/ Added support for PostgreSQL 7.4 database.</li><li>/<span class=\"othername\">SS</span>/ Added support for Oracle 9i database.</li><li>/<span class=\"othername\">SS</span>/ Fixed Bug#981208 SELECT * FROM mydb.mytable is not updateable.</li><li>/<span class=\"othername\">SS</span>/ Replaced thrown exception type from Datasets to <tt class=\"classname\">EZDatabaseError</tt> custom class.</li><li>/<span class=\"othername\">SS</span>/ Fixed Bug#966267 Fixed processing OnEditError, OnPostError, OnDeleteError events.</li><li>/<span class=\"othername\">SS</span>/ Fixed memory leak in <tt class=\"classname\">Statement</tt>.<tt class=\"methodname\">Execute</tt>. Now all <tt class=\"classname\">Connections</tt>, <tt class=\"classname\">Statements</tt> and <tt class=\"classname\">ResultSets</tt> must be explicitely closed before desposing.</li><li>/<span class=\"othername\">SS</span>/ Added doSmartOpen option to <tt class=\"classname\">Dataset</tt> to allow executing DML statements by <tt class=\"methodname\">Open</tt> without throwing exception. </li><li>/<span class=\"othername\">SM</span>/ Fixed Bug#959307 <tt class=\"classname\">TZDBLibCallableStatement</tt>.<tt class=\"methodname\">Execute</tt> Empty parameter string sever translate as null value</li><li>/<span class=\"othername\">SM</span>/ Fixed Bug#907497 <tt class=\"classname\">TZDBLibCallableStatement</tt>.<tt class=\"methodname\">ExecutePrepared</tt> Return incorrect string values of stored procedure</li><li>/<span class=\"othername\">SM</span>/ Fixed Bug#951881 <tt class=\"classname\">TZFirebirdNativeLibraryLoader</tt> Interbase do not work with INTERBASE_CRYPT enabled</li><li>/<span class=\"othername\">SM</span>/ Fixed #956613 <tt class=\"classname\">TZInterbase6DatabaseMetadata</tt>.<tt class=\"methodname\">GetTables</tt> Error in metadata reading</li><li>/<span class=\"othername\">SM</span>/ Fixed #947915 <tt class=\"classname\">TZInterbase6CallableStatement</tt>.<tt class=\"methodname\">ExecuteUpdatePrepared</tt> do noit raised exception in Stored Procedure</li><li>/<span class=\"othername\">SM</span>/ Fixed #945251 <tt class=\"classname\">TZAbstractDatabaseMetadata</tt>.<tt class=\"methodname\">GetTableTypes</tt> always returns &#8220;<span class=\"quote\">TABLE</span>&#8221; as result, never&#8220;<span class=\"quote\">VIEW</span>&#8221; and never &#8220;<span class=\"quote\">SYSTEM TABLE</span>&#8221;.</li><li>/<span class=\"othername\">SS</span>/ Fixed Bug#914057 <tt class=\"classname\">ZSQLMonitor</tt>.<tt class=\"methodname\">SaveToFile</tt> don't use <span class=\"property\">FileName</span>.</li><li>/<span class=\"othername\">SM</span>/ Fixed Bug #914436 Text fields with specified character set are not recognized in MySQL driver.</li><li>/<span class=\"othername\">SM</span>/ Fixed Bug #914369 Fixed memory leaks in Interbase driver</li><li>/<span class=\"othername\">SS</span>/ Fixed Bug#912220 PostgreSQL driver doesn't read oid blobs.</li><li>/<span class=\"othername\">SM</span>/ Fixed Bug#909181 do not sets fields to null</li><li>/<span class=\"othername\">SM</span>/ Fixed Bug #914436 Bug several MySQL TEXT Fields are not correct identified</li><li>/<span class=\"othername\">SS</span>/ Fixed Bug #919395 Memory leak in <tt class=\"classname\">TZExpressionParser</tt>.<tt class=\"methodname\">TokenizeExpression</tt>. Thanks to mocarts.</li><li>/<span class=\"othername\">SS</span>/ Fixed Bug #919401 When dataset is in Edit mode function <tt class=\"methodname\">UpdatesPending</tt> always returns true does matter were changes made or not. Thanks to mocarts.</li><li>/<span class=\"othername\">SS</span>/ Added processing for query parameters with ftGraphic type. Thanks to Pavel Blahovec.</li><li>/<span class=\"othername\">SS</span>/ Added support for SQL specific syntax in Query.SQL and UpdateSQL.</li><li>/<span class=\"othername\">SS</span>/ Added support for SQLite 2.8 database.</li><li>/<span class=\"othername\">SS</span>/ Fixed Bug #924861 Memory leak, when client cannot connect to server</li><li>/<span class=\"othername\">SS</span>/ Added depended compilation for drivers, included into TZConnection drivers list. Now users may select which drivers they want to use to decrease size of their applications. (See /src/Zeos.inc file for details)</li><li>/<span class=\"othername\">SS</span>/ Refactored ZDBC metadata classes.</li><li>/<span class=\"othername\">SS</span>/ Fixed processing of Int64 values in Dataset.Refresh.</li><li>/<span class=\"othername\">SS</span>/ Fixed Bug #933623 'current transaction is aborted, commands ignored until end of transaction block.' error in postgresql when previous statement in transaction fails. Now if autocommit mode is set components automatically rollback failed statements. In manual commit mode developer should explicitely call Connection.Rollback.</li><li>/<span class=\"othername\">SS</span>/ Added GetProtocolNames, GetCatalogNames, GetSchemaNames, GetTableNames, GetStoredProcNames methods into TZConnection component.</li><li>/<span class=\"othername\">SS</span>/ Fixed Bug #824786 TZMetadata shows PostgreSQL 7.4 system tables from 'information_schema' as regular tables.</li><li>/<span class=\"othername\">SS</span>/ Changed type for Dataset.ShowRecordTypes to TUpdateStatusSet.</li><li>/<span class=\"othername\">SS</span>/ Fixed duplicated <tt class=\"methodname\">AfterScroll</tt> event in <tt class=\"classname\">Query</tt>.<tt class=\"methodname\">Locate</tt> and <tt class=\"classname\">Query</tt>.<tt class=\"methodname\">FindRecord</tt> methods.</li><li>/<span class=\"othername\">SS</span>/ Fixed Bug#948940 Random &#8220;<span class=\"quote\">Can not update this query type</span>&#8221; error in PostgreSQL driver. Thanks to Sergio Freue.</li><li>/<span class=\"othername\">SS</span>/ Replaced <span class=\"property\">RequestLive</span> with <span class=\"property\">ReadOnly</span> property in <tt class=\"classname\">TZTable</tt> component to make it more compatible with standard <tt class=\"classname\">TTable</tt>.</li><li>/<span class=\"othername\">SS</span>/ Added <span class=\"property\">InTransaction</span> property in <tt class=\"classname\">TZConnection</tt>component.</li><li>/<span class=\"othername\">SS</span>/ Fixed Bug#957126 Incorrect processing of empty strings in default values in MySQL driver. Thanks to Alex/ghost3k.</li></ul></div></div></div><div class=\"sect1\" lang=\"en\"><div class=\"titlepage\"><div><div><h2 class=\"title\" style=\"clear: both\"><a id=\"d4e1470\"></a>12.&nbsp;Changes in Release 6.1</h2></div></div></div><div class=\"toc\"><dl><dt><span class=\"sect2\"><a href=\"#d4e1472\">12.1. Release 6.1.4 - 21 January 2004</a></span></dt><dt><span class=\"sect2\"><a href=\"#d4e1539\">12.2. Release 6.1.3 - 11 December 2003</a></span></dt><dt><span class=\"sect2\"><a href=\"#d4e1589\">12.3. Release 6.1.2 - 12 November 2003</a></span></dt><dt><span class=\"sect2\"><a href=\"#d4e1703\">12.4. Release 6.1.1 - 28 September 2003</a></span></dt><dt><span class=\"sect2\"><a href=\"#d4e1889\">12.5. Release 6.1.0 - 28 July 2003</a></span></dt></dl></div><div class=\"sect2\" lang=\"en\"><div class=\"titlepage\"><div><div><h3 class=\"title\"><a id=\"d4e1472\"></a>12.1.&nbsp;Release 6.1.4 - 21 January 2004</h3></div></div></div><div class=\"itemizedlist\"><ul type=\"disc\" compact><li>/<span class=\"othername\">SS</span>/ Fixed Bug#880459 Access Violation in <tt class=\"classname\">ZSQLProcessor</tt>.<tt class=\"methodname\">Execute</tt> method when <tt class=\"classname\">Connection</tt> is not assigned.</li><li>/<span class=\"othername\">SS</span>/ Fixed Access Violation in MySQL driver when opening a resultset for queries which do not return any data.</li><li>/<span class=\"othername\">SS</span>/ Fixed Bug#881634 Complex select statements return wrong field types.</li><li>/<span class=\"othername\">SS</span>/ Fixed Bug#883027 Wrong comparison for rows with Int64 and Binary Array fields. Thanks to sskacar.</li><li>/<span class=\"othername\">SS</span>/ Fixed Bug#884135 Problem in master-detail links with unsigned int keys.</li><li>/<span class=\"othername\">SS</span>/ Fixed Bug#882150 Incorrect processing empty strings in filter expressions.</li><li>/<span class=\"othername\">SS</span>/ Fixed Bug#887103 BeforeScroll and AfterScroll events are not working with <tt class=\"methodname\">SetRecNo</tt>. Thanks to Alexander Klenin.</li><li>/<span class=\"othername\">SS</span>/ Fixed Bug#886841 Error in processing default values for columns with type enum(y,n) in MySQL driver.</li><li>/<span class=\"othername\">SM</span>/ Fixed Bug#886914 Incorrect updating CHAR not null and empty fields in Interbase/Firebird driver.</li><li>/<span class=\"othername\">SM</span>/ Fixed Bug#886854 Problem with field types for system fields in Firebirb 1.5 RC8 type</li><li>/<span class=\"othername\">SM</span>/ Fixed Bug#882232 Invalid Color property value in ZUpdateSqlEditor.dfm</li><li>/<span class=\"othername\">SM</span>/ Fixed Bug#865299 Interbase 5.5 wrong metadata reading</li><li>/<span class=\"othername\">SS</span>/ Fixed a memory leak in TZSQLProcessor component. Thanks to Martin Fibiger.</li><li>/<span class=\"othername\">SS</span>/ Fixed Bug#894367 Incorrect parsing queries with non-unique field column names.</li><li>/<span class=\"othername\">SS</span>/ Fixed Bug#910804 Wrong processing regular expressions with '*abc' style patterns.</li></ul></div></div><div class=\"sect2\" lang=\"en\"><div class=\"titlepage\"><div><div><h3 class=\"title\"><a id=\"d4e1539\"></a>12.2.&nbsp;Release 6.1.3 - 11 December 2003</h3></div></div></div><div class=\"itemizedlist\"><ul type=\"disc\" compact><li>/<span class=\"othername\">SS</span>/ Fixed leaving cached statement object in <tt class=\"classname\">TDataset</tt>.<tt class=\"methodname\">ExecSQL</tt> after connection component changed.</li><li>/<span class=\"othername\">SS</span>/ Fixed Bug#862261 Empty blobs sometimes included into Where clause of generated DML statements as &lt;field&gt;=NULL. It caused missed updates.</li><li>/<span class=\"othername\">SS</span>/ Fixed compilation for Kylix 1 compiler.</li><li>/<span class=\"othername\">SS</span>/ Added functions CONCAT, UPPER, LOWER, SUBSTR and STRPOS to filter expressions.</li><li>/<span class=\"othername\">SS</span>/ Fixed Bug#864797 Filter Expressions don't process columns with <tt class=\"literal\">NULL</tt> values correctly.</li><li>/<span class=\"othername\">SM</span>/ Fixed Bug#860196 &amp; #851664 Call Stored Procedures and Firebird 1.5</li><li>/<span class=\"othername\">SM</span>/ Fixed bug #864622  ZQuery return numeric(3,1) fields as IntegerField</li><li>/<span class=\"othername\">SS</span>/ Fixed bug #869609  Wrong behaviour of MySQL AutoIncremented fields</li><li>/<span class=\"othername\">SS</span>/ Fixed error handling in CachedResultSet.DeleteRow method. Thanks for Tobias Giesen.</li><li>/<span class=\"othername\">SM</span>/ Fixed bug #865585 Wrong exception behavior in ExecuteQuery and ExecuteQueryPrepared Thanks for Alex Gilev.</li><li>/<span class=\"othername\">SS</span>/ Fixed processing connection timeout parameter for PostgreSQL.</li></ul></div></div><div class=\"sect2\" lang=\"en\"><div class=\"titlepage\"><div><div><h3 class=\"title\"><a id=\"d4e1589\"></a>12.3.&nbsp;Release 6.1.2 - 12 November 2003</h3></div></div></div><div class=\"itemizedlist\"><ul type=\"disc\" compact><li>/<span class=\"othername\">SS</span>/ Added <tt class=\"literal\">IS NULL</tt>, <tt class=\"literal\">IS NOT NULL</tt>, <tt class=\"literal\">NOT LIKE</tt> operations to Filter Expression.</li><li>/<span class=\"othername\">SS</span>/ Fixed Bug#842678 AV when removing <tt class=\"classname\">ZUpdateSQL</tt> from <tt class=\"classname\">ZQuery</tt>.</li><li>/<span class=\"othername\">SS</span>/ Added <i class=\"parameter\"><tt>codepage</tt></i> (client codepage) and <i class=\"parameter\"><tt>timeout</tt></i> connection timeout to MySQL and PostgreSQL drivers.</li><li>/<span class=\"othername\">SS</span>/ Added single line comments started with <tt class=\"literal\">--</tt> to MySQL parser.</li><li>/<span class=\"othername\">SS</span>/ Fixed Bug#841425 TZSQLProcessor did not skip empty statements and it cased database errors.</li><li>/<span class=\"othername\">SS</span>/ Fixed Bug#837764 Transaction Isolation Level not set after Commit and Rollback in PostgreSql driver.</li><li>/<span class=\"othername\">SS</span>/ Fixed Bug#840608 Where clause in generated DML statement was incorrect if it included <tt class=\"literal\">NULL</tt> values.</li><li>/<span class=\"othername\">SS</span>/ Fixed generation of UPDATE statements with <span class=\"property\">UpdateMode</span>=<tt class=\"literal\">UpdateChanged</tt>.</li><li>/<span class=\"othername\">SS</span>/ Fixed Bug#840218 <tt class=\"methodname\">Lookup</tt> method returned incorrect result field.</li><li>/<span class=\"othername\">SM</span>/ Fixed Bug#833766 FloatField don't load scale correct</li><li>/<span class=\"othername\">SM</span>/ Added support for interbase 7</li><li>/<span class=\"othername\">SM</span>/ Fixed Bug#845312 Wrong float/double updating in ZDbcInterbase6Utils</li><li>/<span class=\"othername\">SM</span>/ Fixed Bug#847593 Codepage don't set correctly</li><li>/<span class=\"othername\">SM</span>/ Fixed Bug#841559 Triggers and messages</li><li>/<span class=\"othername\">SM</span>/ Fixed Bug#843655 Blob fields don't updates</li><li>/<span class=\"othername\">SM</span>/ Fixed Bug#847594 Exceptions descriptions</li><li>/<span class=\"othername\">SM</span>/ Fixed Bug#844597 AV Error after closing window of ZQuery's <span class=\"property\">Properties</span> properties</li><li>/<span class=\"othername\">SM</span>/ Fixed Bug#841515 C++ Builder 4 Error installing ZeosDBO</li><li>/<span class=\"othername\">SS</span>/ Fixed Bug#849723 Time columns with &#8220;<span class=\"quote\">00:00:00</span>&#8221; values are converted to NULLs in MySQL driver.</li><li>/<span class=\"othername\">SS</span>/ Added doAlwaysDetailResync option to Dataset.Options which turns on/off synchronization between Master and Detail dataset when Master is in Edit or Insert mode.</li><li>/<span class=\"othername\">JF</span>/ Fixed Bug#853690 AutoInc fields in MS SQL</li><li>/<span class=\"othername\">JF</span>/ Fixed Bug#842694 Quoted Fields generated by <tt class=\"classname\">TZUpdateSQL</tt> not accepted by MySQL</li><li>/<span class=\"othername\">JF</span>/ Fixed Bug#841488 Problem with milliseconds in MS SQL dates</li><li>/<span class=\"othername\">SM</span>/ Added support PostgreSql-7.3. Added libpq73.dll and potocol postgresq-7.3</li></ul></div></div><div class=\"sect2\" lang=\"en\"><div class=\"titlepage\"><div><div><h3 class=\"title\"><a id=\"d4e1703\"></a>12.4.&nbsp;Release 6.1.1 - 28 September 2003</h3></div></div></div><div class=\"itemizedlist\"><ul type=\"disc\" compact><li>/<span class=\"othername\">SS</span>/ Added support for column default values defined in database. Default values of <tt class=\"classname\">TField</tt> are still unsupported.</li><li>/<span class=\"othername\">SS</span>/ Replaced Borland <span class=\"type\">Variants</span> with custom implementation. It solved many problems with data type convertions and Int64 support in filter expression, master/detail links, locate and many other places.</li><li>/<span class=\"othername\">SS</span>/ Optimized <tt class=\"methodname\">Locate</tt> and <tt class=\"methodname\">Lookup</tt> methods in <tt class=\"classname\">TDataset</tt>. The speed was increased up to 6 times.</li><li>/<span class=\"othername\">SS</span>/ Added <span class=\"property\">UpdateMode</span> and <span class=\"property\">WhereMode</span> properties to <tt class=\"classname\">TDataset</tt>. <span class=\"property\">UpdateMode</span> has two options: <tt class=\"literal\">umUpdateChanged</tt> to post to database only updated fields and <tt class=\"literal\">umUpdateAll</tt> to post all fields.<span class=\"property\">TZWhereMode</span> controls WHERE clause in posted DML statements. <tt class=\"literal\">wmWhereKeyOnly</tt> includes in WHERE only key fields if they exist, <tt class=\"literal\">wmWhereAll</tt> includes all fields.</li><li>/<span class=\"othername\">SS</span>/ Added <span class=\"property\">Options</span> property to <tt class=\"classname\">TDataset</tt>. Now it supports two options <tt class=\"constant\">doOemTranslate</tt> to turn on Ansi to OEM translation in visual controls and <tt class=\"constant\">doCalcDefaults</tt> to turn on/off calculation of column default values defined in database.</li><li>/<span class=\"othername\">SS</span>/ Fixed Bug#816846. PostgreSQL <span class=\"type\">text</span> columns are included now into WHERE clause in autogenerated DML statements. Before they were skipped and it caused problems for tables with <span class=\"type\">text</span> columns where primary key was not defined.</li><li>/<span class=\"othername\">SS</span>/ Fixed Bug#816850 &#8220;<span class=\"quote\">Changing blobs overwrite old values.</span>&#8221;</li><li>/<span class=\"othername\">SS</span>/ Added <span class=\"property\">SortedFields</span> property to <tt class=\"classname\">TDataset</tt>. The format of the <span class=\"property\">SortedFields</span> value should be:<span><b class=\"command\">&lt;Field Name&gt; [ASC | DESC] [,...]</b></span></li><li>/<span class=\"othername\">SS</span>/ Fixed Bug#810249. Added workaround to prevent objects self-destruction in contructors. The bug exist in Delphi 4 and C++ Builder 4 compilers. It decrements reference counter and destroys object if in constructor some interface method is called.</li><li>/<span class=\"othername\">SS</span>/ Excluded ADO driver from Delphi 4 and BCB 4 packages due to lack of support OLE data types in that compilers.</li><li>/<span class=\"othername\">SS</span>/ Fixed Bug#824792. Fixed &#8220;<span class=\"quote\">Interface not supported</span>&#8221; error in <tt class=\"classname\">TZMonitor</tt> in C++ Builder 5 compiler.</li><li>/<span class=\"othername\">SM</span>/ Fixed Bugs #824948 and #824875 &#8220;<span class=\"quote\">Firebird 1.5 - Statement not allowed</span>&#8221;.</li><li>/<span class=\"othername\">SM</span>/ Fixed Bug#815955 &#8220;<span class=\"quote\">Wrong mapping <span class=\"type\">numeric(15)</span> to <tt class=\"classname\">TIntegerField</tt></span>&#8221;</li><li>/<span class=\"othername\">SM</span>/ Fixed Bug#804112 &#8220;<span class=\"quote\">AutoCommit Interbase/Firebird transaction problem</span>&#8221;</li><li>/<span class=\"othername\">SM</span>/ Fixed Bug#789879 &#8220;<span class=\"quote\">Firebird: Float-&gt;Numeric</span>&#8221;</li><li>/<span class=\"othername\">SM</span>/ Fixed Bug#825029 &#8220;<span class=\"quote\">examples - Controls conflict names with Delphi7</span>&#8221;</li><li>/<span class=\"othername\">DD</span>/ Fixed Bug#817612 &#8220;<span class=\"quote\">C++ Builder hpp generation bug</span>&#8221;</li><li>/<span class=\"othername\">SS</span>/ Added support for PostgreSQL domains (user defined types). As a drawback all domain strings types have length 255 characters.</li><li>/<span class=\"othername\">SM</span>/ Fixed Bug#815861 &#8220;<span class=\"quote\">Incorrect parsing of the Version#</span>&#8221; for PostgreSql7.x betas.</li><li>/<span class=\"othername\">SS</span>/ Fixed Bug#831776 &#8220;<span class=\"quote\">TZLoggingEvent is not found</span>&#8221;.</li><li>/<span class=\"othername\">SS</span>/ Fixed Bug#831559 &#8220;<span class=\"quote\">Usage SQL keywords in column names</span>&#8221;.</li><li>/<span class=\"othername\">JF</span>/ Feature Requests#831925. Added several connection parameters to MS SQL: <i class=\"parameter\"><tt>application name</tt></i>, <i class=\"parameter\"><tt>workstation name</tt></i> and few more.</li><li>/<span class=\"othername\">JF</span>/ Fixed Bug#826621. Added reconnection in the case of network problems to MS SQL driver.</li><li>/<span class=\"othername\">JF</span>/ Fixed Bug#817400 &#8220;<span class=\"quote\">Schema support for <tt class=\"classname\">TZTable</tt></span>&#8221;</li><li>/<span class=\"othername\">SS</span>/ Fixed Bug#832467 &#8220;<span class=\"quote\">Filter expression does not process string constants contained single quote symbols inside</span>&#8221;.</li><li>/<span class=\"othername\">SS</span>/ Fixed Bug#830804 &#8220;<span class=\"quote\">Changing dataset fields order in runtime (dragging column in <tt class=\"classname\">DBGrid</tt> for example) causes AV</span>&#8221;.</li><li>/<span class=\"othername\">SS</span>/ Fixed Bug#833197 &#8220;<span class=\"quote\">Refresh problem with filtered data</span>&#8221;.</li><li>/<span class=\"othername\">JF</span>/ Fixed issues related to ADO in Delphi 4 and C++ Builder 4 compilers.</li><li>/<span class=\"othername\">SS</span>/ Added <tt class=\"literal\">STRICT_DLL_LOADING</tt> definition into <tt class=\"filename\">/src/Zeos.inc</tt> to prevent loading of <tt class=\"filename\">libmysql.dll</tt> and <tt class=\"filename\">libpq.dll</tt> libraries by default. If was done because of constant user problems with unsupported dlls. To enforce loading default libraries you should comment the definition and recompile the components.</li><li>/<span class=\"othername\">SS</span>/ Added optimization for switching transaction modes in MySQL driver.</li><li>/<span class=\"othername\">JF</span>/ Added support of SQLHourGlass cursor in the component.</li><li><p>/<span class=\"othername\">SS</span>/ Fixed Bug#834798 &#8220;<span class=\"quote\">Locate with [loCaseInsensitive] parameters does not work</span>&#8221;.</p></li><li><p>/<span class=\"othername\">SS</span>/ Fixed Bug#839540 Logical operations don't work properly in filter expression.</p></li></ul></div></div><div class=\"sect2\" lang=\"en\"><div class=\"titlepage\"><div><div><h3 class=\"title\"><a id=\"d4e1889\"></a>12.5.&nbsp;Release 6.1.0 - 28 July 2003</h3></div></div></div><div class=\"itemizedlist\"><ul type=\"disc\" compact><li>/<span class=\"othername\">SS</span>/ Rewritten SQL parsers, removed Parse package from the project.</li><li>/<span class=\"othername\">SS</span>/ Modified <tt class=\"classname\">TZSQLProcessor</tt> component.</li><li>/<span class=\"othername\">JF</span>/ ADO driver is added.</li><li>/<span class=\"othername\">JF</span>/ Modified <tt class=\"classname\">TZBlobStream</tt> to support notification about change.</li><li>/<span class=\"othername\">SS</span>/ Code has been optimized.</li><li>/<span class=\"othername\">SS</span>/ Finished source code review.</li><li>/<span class=\"othername\">SS</span>/ Added parameters to ZDBC statements.</li><li>/<span class=\"othername\">SS</span>/ Added multiple statements property to <tt class=\"classname\">TZUpdateSQL</tt>.</li><li>/<span class=\"othername\">SS</span>/ Added <tt class=\"classname\">TZSQLMonitor</tt> component.</li><li>/<span class=\"othername\">SS</span>/ Added filter expressions</li><li>/<span class=\"othername\">JF</span>/ Stored procedure support for mssql dblib interface, works for sybase also</li><li>/<span class=\"othername\">SS</span>/ Added <span class=\"property\">DataSource</span> property in <tt class=\"classname\">TDataset</tt> to support master-detail links.</li><li>/<span class=\"othername\">SS</span>/ Added <span class=\"property\">MasterSource</span>, <span class=\"property\">MasterFields</span> and <span class=\"property\">IndexFieldNames</span> to support master-detail links with client-side filtering</li><li>/<span class=\"othername\">SS</span>/ Added support for MySQL autoincremented fields</li><li>/<span class=\"othername\">JF</span>/ Added support for Sybase and MS SQL identity fields</li><li>/<span class=\"othername\">JF</span>/ Added support for exiting without error messages in case of broken connection</li><li>/<span class=\"othername\">JF</span>/ Added some new metadata columns to getcolumns to support calculated fields</li><li>/<span class=\"othername\">JF</span>/ Autoincremented field support for mssql, sybase and ado added  to return the generated value.</li><li>/<span class=\"othername\">JF</span>/ Added workaround for procedure parameter type query for sybase. It works only for ASE12.5 or above</li><li>/<span class=\"othername\">JF</span>/ Added workaround for sybase structure 'AND NULL IS NULL' resulted in error: Invalid operator for datatype op: is null type: VOID TYPE.</li><li>/<span class=\"othername\">SS</span>/ Added <tt class=\"classname\">TZTable</tt> component.</li><li>/<span class=\"othername\">SS</span>/ Added <tt class=\"classname\">TZSQLMetadata</tt> component.</li><li>/<span class=\"othername\">SS</span>/ Added caching for database metadata</li><li>/<span class=\"othername\">SM</span>/ Fixed Bug#804112 AutoCommit Interbase/Firebird transaction problem.</li><li>/<span class=\"othername\">SM</span>/ Fixed Bug#795832 Exception handling in Interbase statement</li><li>/<span class=\"othername\">SM</span>/ Added Plain API for DB2 </li></ul></div></div></div><div class=\"sect1\" lang=\"en\"><div class=\"titlepage\"><div><div><h2 class=\"title\" style=\"clear: both\"><a id=\"d4e2007\"></a>13.&nbsp;Changes in Release 6.0</h2></div></div></div><div class=\"toc\"><dl><dt><span class=\"sect2\"><a href=\"#d4e2009\">13.1. Release 6.0.12 Patch#3 - 28 September 2003</a></span></dt><dt><span class=\"sect2\"><a href=\"#d4e2038\">13.2. Release 6.0.12 Patch #2 - 28 September 2003</a></span></dt><dt><span class=\"sect2\"><a href=\"#d4e2070\">13.3. Release 6.0.12 Patch #1 - 28 September 2003</a></span></dt><dt><span class=\"sect2\"><a href=\"#d4e2095\">13.4. Release 6.0.12 - 18 July 2003</a></span></dt><dt><span class=\"sect2\"><a href=\"#d4e2128\">13.5. Release 6.0.11 - 08 July 2003</a></span></dt><dt><span class=\"sect2\"><a href=\"#d4e2185\">13.6. Release 6.0.10 - 13 June 2003</a></span></dt><dt><span class=\"sect2\"><a href=\"#d4e2266\">13.7. Release 6.0.9 - 18 May 2003</a></span></dt><dt><span class=\"sect2\"><a href=\"#d4e2372\">13.8. Release 6.0.8 - 15 April 2003</a></span></dt><dt><span class=\"sect2\"><a href=\"#d4e2387\">13.9. Release 6.0.7 - 13 April 2003</a></span></dt><dt><span class=\"sect2\"><a href=\"#d4e2434\">13.10. Release 6.0.6 - 30 March 2003</a></span></dt><dt><span class=\"sect2\"><a href=\"#d4e2481\">13.11. Release 6.0.5 - 18 March 2003</a></span></dt><dt><span class=\"sect2\"><a href=\"#d4e2536\">13.12. Release 6.0.4 - 24 February 2003</a></span></dt><dt><span class=\"sect2\"><a href=\"#d4e2571\">13.13. Release 6.0.3 - 17 February 2003</a></span></dt><dt><span class=\"sect2\"><a href=\"#d4e2590\">13.14. Release 6.0.2 - 9 February 2003</a></span></dt><dt><span class=\"sect2\"><a href=\"#d4e2621\">13.15. Release 6.0.1 - 2 February 2003</a></span></dt><dt><span class=\"sect2\"><a href=\"#d4e2648\">13.16. Release 6.0.0 - 25 January 2003</a></span></dt></dl></div><div class=\"sect2\" lang=\"en\"><div class=\"titlepage\"><div><div><h3 class=\"title\"><a id=\"d4e2009\"></a>13.1.&nbsp;Release 6.0.12 Patch#3 - 28 September 2003</h3></div></div></div><div class=\"itemizedlist\"><ul type=\"disc\" compact><li>/<span class=\"othername\">SS</span>/ Fixed Bug#817607 Fail refreshing Query when field names contain spaces.</li><li>/<span class=\"othername\">SS</span>/ Fixed AV when connection is destroyed before linked datasets (Thanks to Ask).</li><li>/<span class=\"othername\">SS</span>/ Fixed Bug#826624 Incorrect converting for <span class=\"type\">Int64</span> Params (Thanks to Dmitry Krylov)</li><li>/<span class=\"othername\">SS</span>/ Fixed Bug#816925 Wrong mapping of <span class=\"type\">Decimal</span> and <span class=\"type\">Numeric</span> fields in MySQL</li><li>/<span class=\"othername\">SS</span>/ Fixed Bug#826886 AV in <tt class=\"classname\">TDataset</tt>.<tt class=\"methodname\">ExecSQL</tt> after disconnecting <tt class=\"classname\">TZConnection</tt>.</li></ul></div></div><div class=\"sect2\" lang=\"en\"><div class=\"titlepage\"><div><div><h3 class=\"title\"><a id=\"d4e2038\"></a>13.2.&nbsp;Release 6.0.12 Patch #2 - 28 September 2003</h3></div></div></div><div class=\"itemizedlist\"><ul type=\"disc\" compact><li>/<span class=\"othername\">SS</span>/  Fixed Bug#803616 Fail posting inserted and then updated records in cached updates mode.</li><li>/<span class=\"othername\">SS</span>/ Fixed Bug#804323 Calculated fields in read only datasets.</li><li>/<span class=\"othername\">SS</span>/ Fixed Bug#804640 Calculated fields of type <tt class=\"classname\">TCurrencyField</tt> returns always 0.00.</li><li>/<span class=\"othername\">SS</span>/ Fixed Bug#802548 Error &#8220;<span class=\"quote\">List Index out of Bounds (-1)</span>&#8221; in <tt class=\"methodname\">Refresh</tt> method.</li><li>/<span class=\"othername\">SS</span>/ Added missed events to <tt class=\"classname\">TZSQLProcessor</tt> (Thanks to Josef Fuchs).</li><li>/<span class=\"othername\">SS</span>/ Added support for <span class=\"type\">LONGTEXT</span> field type in MySQL driver.</li></ul></div></div><div class=\"sect2\" lang=\"en\"><div class=\"titlepage\"><div><div><h3 class=\"title\"><a id=\"d4e2070\"></a>13.3.&nbsp;Release 6.0.12 Patch #1 - 28 September 2003</h3></div></div></div><div class=\"itemizedlist\"><ul type=\"disc\" compact><li>/<span class=\"othername\">SS</span>/ Fixed Bug#793351 access violation when assigning a field value</li><li>/<span class=\"othername\">JF</span>/ Fixed Bug#791101 Transaction not working with MS SQL</li><li>/<span class=\"othername\">JF</span>/ Fixed Bug#791096 &#8220;<span class=\"quote\">List index out of bounds</span>&#8221; problem when canceling a newly added row.</li><li>/<span class=\"othername\">SS</span>/ Fixed Bug#798336 Not passing large objects to Postgres DB.</li><li>/<span class=\"othername\">SS</span>/ Fixed Bug#799863 Cannot see <span class=\"type\">YEAR</span> type in Delphi.</li></ul></div></div><div class=\"sect2\" lang=\"en\"><div class=\"titlepage\"><div><div><h3 class=\"title\"><a id=\"d4e2095\"></a>13.4.&nbsp;Release 6.0.12 - 18 July 2003</h3></div></div></div><div class=\"itemizedlist\"><ul type=\"disc\" compact><li>/<span class=\"othername\">SS</span>/ Fixed Bug#773400. In plain interface for MySQL 4.0 the name of shared library was 'libmysqld.so' instead of 'libmysqlclient.so'</li><li>/<span class=\"othername\">SS</span>/ Fixed Bug#772926 with incorrect <tt class=\"classname\">TZDataset</tt>.<tt class=\"methodname\">Cancel</tt> behaviour.</li><li>/<span class=\"othername\">SS</span>/ Fixed out of range exception in <tt class=\"classname\">TZDataset</tt>.<tt class=\"methodname\">Last</tt> method.</li><li>/<span class=\"othername\">SS</span>/ Fixed problem with incorrect order of dataset input parameters.</li><li>/<span class=\"othername\">JF</span>/ <tt class=\"methodname\">Refresh</tt> problem solved                                                                         </li><li>/<span class=\"othername\">SM</span>/ Fixed Bug#768163 with <span class=\"type\">unsigned int</span> fields in MySQL</li></ul></div></div><div class=\"sect2\" lang=\"en\"><div class=\"titlepage\"><div><div><h3 class=\"title\"><a id=\"d4e2128\"></a>13.5.&nbsp;Release 6.0.11 - 08 July 2003</h3></div></div></div><div class=\"itemizedlist\"><ul type=\"disc\" compact><li>/<span class=\"othername\">SS</span>/ Eliminated all overrided methods in API, fixed support for C++ Builder 4,5,6 compilers.</li><li>/<span class=\"othername\">SS</span>/ Added optimization to <tt class=\"classname\">TZAbstractDODataset</tt>.<tt class=\"methodname\">ExecSQL</tt> and <tt class=\"classname\">TZEmulatedPreparedStatement</tt>. Now executing prepared statements without parameters about 10 times faster, with parameters - 25% faster.</li><li>/<span class=\"othername\">SS</span>/ Fixed <tt class=\"classname\">TZConnection</tt>.<tt class=\"methodname\">AutoCommit</tt> and <tt class=\"classname\">TZConnection</tt>.<tt class=\"methodname\">TransactIsolationLevel</tt> property behavior.</li><li>/<span class=\"othername\">JF</span>/ <span class=\"property\">LoginPrompt</span> support added. Delphi4 and Delphi5 needs some extra work.</li><li>/<span class=\"othername\">SM</span>/ Fixed Bug #759184 empty <span class=\"type\">string</span> field return by SQL query with concatination fields</li><li>/<span class=\"othername\">SM</span>/ Fixed Bug #707337 emty values for virtual columns</li><li>/<span class=\"othername\">SS</span>/ Added support for quoted parameters in <tt class=\"classname\">TZQuery</tt> and <tt class=\"classname\">TZUpdateSQL</tt>.</li><li>/<span class=\"othername\">SS</span>/ Fixed Bug#771217 caused by incorrect processing MySQL table names with special characters like 'my-table'</li><li>/<span class=\"othername\">SS</span>/ Fixed Bug#773022: wrong <tt class=\"classname\">TQuery</tt>.<tt class=\"methodname\">RecordCount</tt> after deletes</li><li>/<span class=\"othername\">SS</span>/ Changed processing of &#8220;<span class=\"quote\">0000-00-00</span>&#8221; dates in MySQL. Now they are treated as NULLs simular to ODBC drivers.</li></ul></div></div><div class=\"sect2\" lang=\"en\"><div class=\"titlepage\"><div><div><h3 class=\"title\"><a id=\"d4e2185\"></a>13.6.&nbsp;Release 6.0.10 - 13 June 2003</h3></div></div></div><div class=\"itemizedlist\"><ul type=\"disc\" compact><li>/<span class=\"othername\">SS</span>/ Fixed Bug#752603 in <tt class=\"classname\">TZDataset</tt>.<tt class=\"methodname\">GetFieldData</tt> method which set <span class=\"property\">Field</span>.<span class=\"property\">IsNull</span> = <tt class=\"constant\">True</tt> all the time.</li><li>/<span class=\"othername\">SS</span>/ Fixed Bug#753397: in bounds checking in <tt class=\"classname\">TZCollection</tt>.<tt class=\"methodname\">SetCapacity</tt> which followed to Access Violation in Delphi 4.</li><li>/<span class=\"othername\">SM</span>/ Finished scripts build &amp; test environment</li><li>/<span class=\"othername\">SM</span>/ Added Kylix2 support</li><li>/<span class=\"othername\">SM</span>/ Fixed test framework and tests for Kylix/Linux support</li><li>/<span class=\"othername\">SS</span>/ Fixed remaining issues with Delphi 4 and 5 compilers. The testing libraries for Delphi 4,5 are work as expected.</li><li>/<span class=\"othername\">SM</span>/ Fixed Interbase <span class=\"type\">datetime</span> parameters </li><li>/<span class=\"othername\">JF</span>/ Fixed <span class=\"type\">varbinary</span> datatype. It will be a <span class=\"type\">blob</span> field.</li><li>/<span class=\"othername\">SS</span>/ Fixed bug#750912: Interbase Lookup fields.</li><li>/<span class=\"othername\">SM</span>/ Fixed bug#754009: Cast error while fetching</li><li>/<span class=\"othername\">SM</span>/ Added Firebird 1.5 support</li><li>/<span class=\"othername\">SM</span>/ Fixed leak memory in <tt class=\"methodname\">GetBlob</tt> method for MySQL &amp; PostgreSql</li><li>/<span class=\"othername\">SS</span>/ Added support for MySQL 4.0 native client</li><li>/<span class=\"othername\">SS</span>/ Fixed Bug#761300 Memory leak in <tt class=\"classname\">TZReadOnlyQuery</tt></li><li>/<span class=\"othername\">JF</span>/ The <tt class=\"classname\">TDataset's</tt> default <tt class=\"methodname\">Translate</tt> method is overriden in order to provide basic OEM/ANSI translation, but later it should be database specific.</li><li>/<span class=\"othername\">JF</span>/ The previous one is removed because it caused more problems than it solved.</li></ul></div></div><div class=\"sect2\" lang=\"en\"><div class=\"titlepage\"><div><div><h3 class=\"title\"><a id=\"d4e2266\"></a>13.7.&nbsp;Release 6.0.9 - 18 May 2003</h3></div></div></div><div class=\"itemizedlist\"><ul type=\"disc\" compact><li>/<span class=\"othername\">SS</span>/ Fixed bugs in <tt class=\"classname\">TZCollection</tt> class and <tt class=\"classname\">TZAbstractObject</tt>.<span class=\"property\">Equals</span> (Thanks for Karl Waclawek).</li><li>/<span class=\"othername\">SS</span>/ Fixed Bug#733209 with incorrect decimal separator in <tt class=\"classname\">TZToken</tt>.<tt class=\"methodname\">GetString</tt>. (Thanks to Leonardo Quaggiotto).</li><li>/<span class=\"othername\">SS</span>/ Added support for MySQL <span class=\"type\">boolean</span> type  /<span class=\"type\">enum('Y','N')</span>/</li><li>/<span class=\"othername\">SS</span>/ Fixed Bug#726788 with mixed identificators in MySQL (Thanks to Maarten Bremer).</li><li>/<span class=\"othername\">SS</span>/ Fixed bug in numeric tokenizer. Combinations of symbols '.e' and '.E' were always processed as numbers. For example: a.eq_id was tokenized as 'a' '.e' 'q_id' instead 'a' '.' 'eq_id'</li><li>/<span class=\"othername\">SM</span>/ Added support Interbase 5, 6.X, Firebird 1.X</li><li>/<span class=\"othername\">SM</span>/ GetImportedKeys, GetExportedKeys, GetIndexInfo done for Interbase Database Metadata </li><li>/<span class=\"othername\">SS</span>/ Fixed Bug#740144 with search by Null fields in TZQuery.Locate</li><li>/<span class=\"othername\">SS</span>/ Fixed Bug#740899. Expressions Field=NULL were not properly converted into Field IS NULL in where clauses.</li><li>/<span class=\"othername\">SS</span>/ Completely rewritten SQL parsers because of peformance reasons.</li><li>/<span class=\"othername\">SS</span>/ Fixed Bug#739514 with national string convertion for postgresql.</li><li>/<span class=\"othername\">JF</span>/ Fixed Bug#728955 multiple results returned</li><li>/<span class=\"othername\">JF</span>/ Fixed datatype handling in metadata getColumn to match the modifications via Seroukhov</li><li>/<span class=\"othername\">SS</span>/ Fixed Bug#746225 with updating empty Memo fields.</li><li>/<span class=\"othername\">SM</span>/ Fixed Interbase metadata GetPrimaryKeys, GetProcedures, GetProcedureColumns</li><li>/<span class=\"othername\">SS</span>/ Fixed Bug#739448 with duplicated column names. Now if query returns columns: 'fld','fld','fld', result set will contain display labels 'fld','fld_1','fld_2'</li><li>/<span class=\"othername\">SS</span>/ Fixed Bug#733236 with time fields convertion in TDataset.Locate.</li><li>/<span class=\"othername\">SS</span>/ Optimized code, added DISABLE_CHECKING compiler definition into Zeos.inc file. According performance tests this definition gives about 10% speedup. </li><li>/<span class=\"othername\">SM</span>/ Fixed problem with WasNull in fetch processing in InterbaseResultSet.</li><li>/<span class=\"othername\">SM</span>/ Added example - controls.</li><li>/<span class=\"othername\">SS</span>/ Fixed Bug#725053 with empty lookup fields</li><li>/<span class=\"othername\">SS</span>/ Fixed Bug#739707: Variant convertion error in IZPreparedStatement.SetBlob</li><li>/<span class=\"othername\">JF</span>/ Fixed Numeric scale errors in sybase, was caused by usage of float type instead of double</li><li>/<span class=\"othername\">JF</span>/ Added a workaround for a bug? in mssql dblib interface. All text like '\\'#13 was replaced to just #13. I just double the backslash in this case.</li></ul></div></div><div class=\"sect2\" lang=\"en\"><div class=\"titlepage\"><div><div><h3 class=\"title\"><a id=\"d4e2372\"></a>13.8.&nbsp;Release 6.0.8 - 15 April 2003</h3></div></div></div><div class=\"itemizedlist\"><ul type=\"disc\" compact><li>/<span class=\"othername\">SS</span>/ Fixed Bug#722651 AV in TZDbcMySQLResultSet.GetTimestamp</li><li>/<span class=\"othername\">SS</span>/ Added caching for Server version and data types in PostgreSQL connection.</li><li>/<span class=\"othername\">RFC</span>/ Added packages for Kylix 1 and Kylix 3.</li></ul></div></div><div class=\"sect2\" lang=\"en\"><div class=\"titlepage\"><div><div><h3 class=\"title\"><a id=\"d4e2387\"></a>13.9.&nbsp;Release 6.0.7 - 13 April 2003</h3></div></div></div><div class=\"itemizedlist\"><ul type=\"disc\" compact><li>/<span class=\"othername\">SS</span>/ Fixed Bug#706278 related to performance problems in MySQL</li><li>/<span class=\"othername\">SS</span>/ Fixed Bug#715099 in TZAbstractRODataset.FindNext</li><li>/<span class=\"othername\">SS</span>/ Added select parser for PostgreSQL</li><li>/<span class=\"othername\">SS</span>/ Added generic support for case sensitive catalogs, tables and columns</li><li>/<span class=\"othername\">SS</span>/ Fixed Bug#720785 in CachedResultSet error handling.</li><li>/<span class=\"othername\">SS</span>/ Fixed Bug#720787 in SQL parser performance</li><li>/<span class=\"othername\">SS</span>/ Added GetPChar/SetPChar methods to prevent multiple strings convertion</li><li>/<span class=\"othername\">SS</span>/ Added performance optimization into PreparedStatement and GenericCacheResolver.</li><li>/<span class=\"othername\">SS</span>/ Added packages for Kylix 1</li><li>/<span class=\"othername\">JF</span>/ Fixed MS SQL and Sybase quotation problems</li><li>/<span class=\"othername\">JF</span>/ Fixed FindColumn to properly support case sensitive and case insensitive columns</li></ul></div></div><div class=\"sect2\" lang=\"en\"><div class=\"titlepage\"><div><div><h3 class=\"title\"><a id=\"d4e2434\"></a>13.10.&nbsp;Release 6.0.6 - 30 March 2003</h3></div></div></div><div class=\"itemizedlist\"><ul type=\"disc\" compact><li>/<span class=\"othername\">SS</span>/ Fixed AV in Dataset.GetFieldData method.</li><li>/<span class=\"othername\">SS</span>/ Set default port for MySQL</li><li>/<span class=\"othername\">SS</span>/ Fixed Bug#707339 caused by incorrect mapping for boolean type.</li><li>/<span class=\"othername\">SS</span>/ Fixed Bug#707337 in PostgreSQL calculated columns.</li><li>/<span class=\"othername\">SS</span>/ Fixed Bug#707364 AV in TZSQLProcessor when exception happens</li><li>/<span class=\"othername\">JF</span>/ Optimized blob handling internally</li><li>/<span class=\"othername\">SS</span>/ Added SetCachedUpdates method to permit changes after query open.</li><li>/<span class=\"othername\">SS</span>/ Added BeforeRefresh and AfterRefresh events in Query components.</li><li>/<span class=\"othername\">SS</span>/ Added useresult connection parameter for MySQL</li><li>/<span class=\"othername\">SS</span>/ Made several fixes for PostgreSQL blobs.</li><li>/<span class=\"othername\">DD</span>/ Added packages for C++ Builder 6.</li></ul></div></div><div class=\"sect2\" lang=\"en\"><div class=\"titlepage\"><div><div><h3 class=\"title\"><a id=\"d4e2481\"></a>13.11.&nbsp;Release 6.0.5 - 18 March 2003</h3></div></div></div><div class=\"itemizedlist\"><ul type=\"disc\" compact><li>/<span class=\"othername\">SS</span>/ Modified transaction support for MySQL (Thanks to Pavel Shibanov).</li><li>/<span class=\"othername\">SS</span>/ Added GetSupportedProtocols method to IZDriver</li><li>/<span class=\"othername\">SS</span>/ Added packages for C++ Builder 4,5</li><li>/<span class=\"othername\">SS</span>/ Fixed Access Violation in MySQL.GetColumns</li><li>/<span class=\"othername\">SS</span>/ Fixed behavior of TZDataset.Last method.</li><li>/<span class=\"othername\">SM</span>/ Added scripts for build &amp; test environment, restructured  project packages</li><li>/<span class=\"othername\">SS</span>/ Added a property editor for ZConnection.Protocol</li><li>/<span class=\"othername\">SS</span>/ Added 'oidasblob' connection parameter to PostgreSQL when oidasblob=false (default) Oid fields are treated as integer and bytea fields as Blobs. When oidasblob=true Oid fields represent Blobs and bytea fields are ByteArray[256].</li><li>/<span class=\"othername\">SS</span>/ Added classes for Bug Report Test Cases</li><li>/<span class=\"othername\">SS</span>/ Fixed bug#702368  \"... wrong size ...\" when column in bytea datatype.</li><li>/<span class=\"othername\">SM</span>/ Fixed PostgreSQLToSQLType for PostgreSQL timestamptz datatype</li><li>/<span class=\"othername\">SS</span>/ Fixed ArrayOutOfBounds exception in TZReadOnlyDataSet.Reread</li><li>/<span class=\"othername\">SS</span>/ Fixed refreshing FieldDefs after SQL query update.</li></ul></div></div><div class=\"sect2\" lang=\"en\"><div class=\"titlepage\"><div><div><h3 class=\"title\"><a id=\"d4e2536\"></a>13.12.&nbsp;Release 6.0.4 - 24 February 2003</h3></div></div></div><div class=\"itemizedlist\"><ul type=\"disc\" compact><li>/<span class=\"othername\">SS</span>/ Added a reference implementation for Plain API multiversion support. It includes TZNativeLibraryLoader, IZPlainDriver, IZMySQLPlainDriver and other classes and interfaces.</li><li>/<span class=\"othername\">SS</span>/ Fixed SetTransactionIsolation for MySQL and PostgreSQL.</li><li>/<span class=\"othername\">SS</span>/ Fixed MaxRows in CachedResultSet, MySQLResultSet and PostgreSQLResultSet.</li><li>/<span class=\"othername\">JF</span>/ Modified SetTransactionIsolation for MsSql and Sybase</li><li>/<span class=\"othername\">SS</span>/ Renamed ZUpdateSql into ZSqlUpdate and ZBlobStream into ZStreamBlob to prevent conflicts with an older zeos version.</li><li>/<span class=\"othername\">SS</span>/ Modified PostgreSQL DBC API to use plain drivers.</li><li>/<span class=\"othername\">SS</span>/ Added ErrorCode to EZSQLException</li><li>/<span class=\"othername\">SS</span>/ Added ZSqlScript component</li></ul></div></div><div class=\"sect2\" lang=\"en\"><div class=\"titlepage\"><div><div><h3 class=\"title\"><a id=\"d4e2571\"></a>13.13.&nbsp;Release 6.0.3 - 17 February 2003</h3></div></div></div><div class=\"itemizedlist\"><ul type=\"disc\" compact><li>/<span class=\"othername\">JF</span>/ Fixed problem with queries using parameters with the same name</li><li>/<span class=\"othername\">SS</span>/ Implemented persistence for SQL Params in TZDataset and TZUpdateSQL.</li><li>/<span class=\"othername\">SS</span>/ Added DesignTime test application.</li><li>/<span class=\"othername\">SS</span>/ Implemented restoring SQL Params values after SQL query updates.</li></ul></div></div><div class=\"sect2\" lang=\"en\"><div class=\"titlepage\"><div><div><h3 class=\"title\"><a id=\"d4e2590\"></a>13.14.&nbsp;Release 6.0.2 - 9 February 2003</h3></div></div></div><div class=\"itemizedlist\"><ul type=\"disc\" compact><li>/<span class=\"othername\">SS</span>/ Updated project examples</li><li>/<span class=\"othername\">SS</span>/ Implemented reading FieldDefs on closed dataset. This feature is required to work with dataset columns in visual designer.</li><li>/<span class=\"othername\">SS</span>/ Implemented writing PostgreSql blobs.</li><li>/<span class=\"othername\">SS</span>/ Fixed three interface cycle references in Parse API which followed to massive memory leaks (Many thanks to Vincent Mahon, the author of MemCheck utility!)</li><li>/<span class=\"othername\">SM</span>/ Added testing framework classes</li><li>/<span class=\"othername\">SS</span>/ Fixed three interface cycle references in DBC API. </li><li>/<span class=\"othername\">SS</span>/ Changed AbstractDatabaseMetadata and MySQLDatabaseMetadata classes to reduce repeatable code.</li></ul></div></div><div class=\"sect2\" lang=\"en\"><div class=\"titlepage\"><div><div><h3 class=\"title\"><a id=\"d4e2621\"></a>13.15.&nbsp;Release 6.0.1 - 2 February 2003</h3></div></div></div><div class=\"itemizedlist\"><ul type=\"disc\" compact><li>/<span class=\"othername\">SS</span>/ Fixed date, time and datetime columns handling</li><li>/<span class=\"othername\">SS</span>/ Implemented support primary keys in autogenerated where clauses</li><li>/<span class=\"othername\">SS</span>/ Fixed problems with delete and insert in cached updates mode</li><li>/<span class=\"othername\">SS</span>/ Added synchronization between TZConnection and TZDataset components</li><li>/<span class=\"othername\">SM</span>/ Added icons and registration for non-visual components</li><li>/<span class=\"othername\">JF</span>/ Made numerious changes in MS SQL connectivity API</li></ul></div></div><div class=\"sect2\" lang=\"en\"><div class=\"titlepage\"><div><div><h3 class=\"title\"><a id=\"d4e2648\"></a>13.16.&nbsp;Release 6.0.0 - 25 January 2003</h3></div></div></div><div class=\"itemizedlist\"><ul type=\"disc\" compact><li>Released the first alpha version with support for MySQL, PostgreSQL, Interbase 6+ and MS SQL.</li></ul></div></div></div></div><div xmlns=\"\" id=\"customfooter\">\n(c) 1999 - 2006 The Zeos Development Group\n</div></body></html>"
  },
  {
    "path": "lib/zeosdbo/doc/html/ede.css",
    "content": "/* >e-novative> DocBook Environment (eDE)                                     */\n/* (c) 2002 e-novative GmbH, Munich, Germany                                  */\n/* http://www.e-novative.de                                                   */\n\n/* eDE Cascading Stylesheet for articles                                      */\n\n/* This file is part of eDE                                                   */\n\n/* eDE is free software; you can redistribute it and/or modify                */\n/* it under the terms of the GNU General Public License as published by       */\n/* the Free Software Foundation; either version 2 of the License, or          */\n/* (at your option) any later version.                                        */\n\n/* eDE is distributed in the hope that it will be useful,                     */\n/* but WITHOUT ANY WARRANTY; without even the implied warranty of             */\n/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the              */\n/* GNU General Public License for more details.                               */\n\n/* You should have received a copy of the GNU General Public License          */\n/* along with eDe; if not, write to the Free Software                      */\n/* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA    */\n\n/* This CSS Stylesheet is used to format HTML articles generated by eDE.      */\n/* Note that due to different browser interpretation of the standards, the    */\n/* HTML pages still do not look exactly the same on every browser and system  */\n\n/* You should not modify this file directly (though you can), because         */\n/* any modifications to this file will be lost when you upgrade eDE.          */\n\n/* Instead, copy this file to article.css, then make your modifications.      */\n/* If a custom stylesheet article.css is present, eDE will use it.            */\n/* You can create a document-specific CSS stylesheet by creating a file named */\n/* document_[document name].css, replacing [document_name] with the name of   */\n/* the eDE document you want to use the stylesheet for.                       */\n\n/* You should never modify the CSS stylesheet in the output directory, since  */\n/* your changes would be overwritten when you transform the document again.   */\n/* eDE prefers document-specific stylesheets over custom stylesheets and      */\n/* custom stylesheets over the default e-novative stylesheet.                 */\n\n/* Note that all CSS stylesheets will be named ede.css on deployment.         */\n\n/* Basic Settings:                                                            */\n\nbody {\n\n  /* white background */\n  background-color: #fff;\n\n  /* black foreground */\n  color: #000;\n\n  /* center the body content in browser window */\n  margin: auto;\n\n  /* padding (\"inner margin\") leaves space between */\n  /* browser window border and html body content   */\n  padding: 24px;\n\n  /* set width according to browser window width */\n  width: auto;\n\n  /* text alignment */\n  text-align: justify;\n  /* text-align: left; */\n}\n\n/* sect1 heading */\nh2\n{\n  /* list of fonts provides fallbacks if a font is not present */\n  font-family: Verdana, Arial, Helvetica, Sans-Serif;\n  \n  /* font size, relative to body font size */\n  font-size: 125%;\n  \n  /* bold face, higher number is more bold */\n  font-weight: 600;\n  \n  /* underlined text */\n  text-decoration: none;\n  \n  /* foreground color: dark blue */\n  color: #009;\n  \n  /* background color: gray */\n  background-color: #ddd;\n  \n  /* margin settings are top - right - bottom - left (think clockwise) */\n  margin: 15px 0 15px 0;\n  \n  /* padding (\"inner margin\") settings are top - right - bottom - left */\n  /* (think clockwise)                                                 */\n  padding: 12px 15px 12px 15px;\n}\n\n\n\n\n/* para */\np\n{\n  /* font size, line height, font */\n  /* list of fonts provides fallbacks if a font is not present */\n  font: 12px/18px Verdana, Arial, Helvetica, Sans-Serif;\n\n  /* margin (top - right - bottom - left) */\n  margin: 0 15px 6px 15px;\n}\n\n\n\n\n/* NEEDS TO BE CLEARED UP */\n\n\np, td, li, dt, dd\n{\n  /* font size, line height, font */\n  /* list of fonts provides fallbacks if a font is not present */\n  font: 12px/18px Verdana, Arial, Helvetica, Sans-Serif;\n}\n\n\n\n/* set font for most elements                    */\n/* p: paragraphs (regular text, docbook <para>)  */\n/* (...) */\n/* body: anything else  */\nbody, p, td, li, dt, dd,\n{\n/* set font size and line height                             */\n/* list of fonts provides fallbacks if a font is not present */\nfont: 12px/18px Verdana, Arial, Helvetica, Sans-Serif;\n}\n\n\n\n\n/* images */\n/* docbook: <imageobject> */\nimg\n{\n/* no margin */\nmargin: 0;\n\n/* no padding (\"inner margin\") */\npadding: 0;\n\n/* no border */\nborder: 0;\n}\n\n\n/* emphasized text, can occur in most places */\n/* docbook: <emphasis> */\nem\n{\n/* bold face, higher number is more bold */\nfont-weight: 600;\n/* italic */\nfont-style: italic;\n}\n\n\n/* sect(ion)1 title */\nh2\n{\n/* list of fonts provides fallbacks if a font is not present */\nfont-family: Verdana, Arial, Helvetica, Sans-Serif;\n\n/* font size, relative to body font size */\nfont-size: 125%;\n\n/* bold face, higher number is more bold */\nfont-weight: 600;\n\n/* underlined text */\ntext-decoration: none;\n\n/* foreground color: dark blue */\ncolor: #009;\n\n/* background color: gray */\nbackground-color: #ddd;\n\n/* margin settings are top - right - bottom - left (think clockwise) */\nmargin: 15px 0 15px 0;\n\n/* padding (\"inner margin\") settings are top - right - bottom - left */\n/* (think clockwise)                                                 */\npadding: 12px 15px 12px 15px;\n}\n\n\n/* sect(ion)2 title */\nh3\n{\n/* list of fonts provides fallbacks if a font is not present */\nfont-family: Verdana, Arial, Helvetica, Sans-Serif;\n\n/* font size, relative to body font size */\nfont-size: 110%;\n\n/* bold face, higher number is more bold */\nfont-weight: 600;\n\n/* underlined text */\ntext-decoration: none;\n\n/* foreground color: dark blue */\ncolor: #009;\n\n/* background-color is a very light grey */\n/* alternative: #fff = white             */\nbackground-color: #fefefe;\n\n/* padding (\"inner margin\") settings are top - right - bottom - left */\n/* (think clockwise)                                                 */\npadding: 0 0 0 15px;\n}\n\n\n/* sect(ion)3 title */\nh4\n{\n/* list of fonts provides fallbacks if a font is not present */\nfont-family: Verdana, Arial, Helvetica, Sans-Serif;\n\n/* font size, relative to body font size */\nfont-size: 100%;\n\n/* bold face, higher number is more bold */\nfont-weight: 600;\n\n/* underlined text */\ntext-decoration: none;\n\n/* foreground color: dark blue */\ncolor: #009;\n\n/* background-color is a very light grey */\n/* alternative: #fff = white             */\nbackground-color: #fefefe;\n\n/* padding (\"inner margin\") settings are top - right - bottom - left */\n/* (think clockwise)                                                 */\npadding: 0 0 0 15px;\n}\n\n\n/* sect(ion)4 title */\nh5\n{\n/* list of fonts provides fallbacks if a font is not present */\nfont-family: Verdana, Arial, Helvetica, Sans-Serif;\n\n/* font size, relative to body font size */\nfont-size: 100%;\n\n/* bold face, higher number is more bold */\nfont-weight: 300;\n\n/* not underlined */\ntext-decoration: none ;\n\n/* foreground color: dark blue */\ncolor: #009;\n\n/* background-color is a very light grey */\n/* alternative: #fff = white             */\nbackground-color: #fefefe;\n\n/* padding (\"inner margin\") settings are top - right - bottom - left */\n/* (think clockwise)                                                 */\npadding: 0 0 0 15px;\n}\n\n/* the following formats refer to the docbook tags of the same name           */\n/* for more information, see the docbook reference at                         */\n/* http://www.docbook.org/tdg/en/html/docbook.html                            */\n\n.mediaobject\n{\n/* center */\ntext-align: center;\n}\n\n\n/*  */\n.calloutlist, .figure, .table\n{\n/* margin settings are top - right - bottom - left (think clockwise) */\nmargin: 15px 30px 15px 30px;\n}\n\n\n/*  */\n.itemizedlist, .variablelist {\n/* margin settings are top - right - bottom - left (think clockwise) */\nmargin: 15px 30px 15px 15px;\n}\n\n/* blockquote formatting is a little more complex    */\n/* because block quotes are rendered as a html table */\n\n/* blockquote block */\n.blockquote\n{\n/* override bottom margin, the other margins are inherited */\nmargin-bottom: 30px;\n}\n\n.blockquote p, .blockquote td\n{\n/* set font size and line height                             */\n/* list of fonts provides fallbacks if a font is not present */\nfont: 12px/18px Verdana, Arial, Helvetica, Sans-Serif;\n\n/* bold face, higher number is more bold */\nfont-weight: 450;\n}\n\n\n.epigraph\n{\n/* override bottom margin, the other margins are inherited */\nmargin-bottom: 30px;\n}\n\n.epigraph p, .epigraph td\n{\n/* set font size and line height                             */\n/* list of fonts provides fallbacks if a font is not present */\nfont: 10px/14px Verdana, Arial, Helvetica, Sans-Serif;\n\n/* bold face, higher number is more bold */\nfont-weight: 600;\n}\n\n\n\n/* custom e-novative header and footer that are displayed on all pages */\n#customheader, #customfooter\n{\n/* list of fonts provides fallbacks if a font is not present */\nfont-family: Verdana, Arial, Helvetica, Sans-Serif;\n\n/* font size, relative to body font size */\nfont-size: 80%;\n\n/* line height, relative to body font size */\nline-height: 200%;\n\n\ntext-align: center;\nvertical-align: middle;\ncolor: #fff;\nbackground-color: #009;\n}\n\n\n/* leave more space between last paragraph and footer  */\n/* some browser do not add up the bottom margin of the prior element */\n/* and the top margin of the footer */\n#customfooter {\nmargin-top: 15px;\n}\n\n\n\n/* table { margin: 0 15px 6px 15px; } */\n\n\n/* title and navigation links in header and footer */\n.navheader th, .navheader td, .navfooter th, .navfooter td\n{\nfont-size: 11px;\nfont-weight: 450;\n}\n\n\n/* table of contents, list of figures and list of tables */\n.toc, .list-of-figures, .list-of-tables, .list-of-examples\n{\n/* margin settings are top - right - bottom - left (think clockwise) */\nmargin: 15px 30px 15px 15px;\n}\n\n\n/* the \"headings\" are rendered as paragraphs */\n.toc p, .list-of-figures p, .list-of-tables p, .list-of-examples p\n{\n/* no margin */\nmargin: 0;\n}\n\n\n.figure\n{\n/* margin settings are top - right - bottom - left (think clockwise) */\nmargin: 5px 5px 5px 5px;\n\n/* no padding (\"inner border\") */\npadding: 0;\n\n/* no border */\nborder: 0;\n\n/* center text */\ntext-align: center;\n}\n\n\n/* figure title */\n.figure p, .table p, .example p\n{\nfont-size: 80%;\n}\n\n\n/*\nacronym {\n      border-bottom: 1px dashed #00cc00;\n      cursor: help;\n}\n*/\n\n\n/* admonition headings */\ndiv.note, div.important, div.warning, div.caution, div.tip\n{\npadding: 0px 15px 0px 0px;\n}\n\ndiv.note th, div.important th, div.warning th, div.caution th, div.tip th\n{\n/* set font size and line height                             */\n/* list of fonts provides fallbacks if a font is not present */\nfont: 12px/18px Verdana, Arial, Helvetica, Sans-Serif;\n\nfont-weight: 600;\n\ntext-decoration: underline;\n\n/* left align */\ntext-align: left;\n}\n\n.note p, .important p, .warning p, .caution p, .tip p\n{\nmargin: 0;\n}\n\n.note img, .important img, .warning img, .caution img, .tip img\n{\nmargin: 0px 15px 0px 15px;\n}\n\n\n/* programlisting */\npre.programlisting\n{\n/* non-proportional font */\n/* list of fonts provides fallbacks if a font is not present */\nfont-family: \"Courier New\", Courier, Monospace;\n\n/* color: black */\ncolor: #000;\n\n/* background color: gray */\nbackground-color: #eee;\n\n/* no margin */\nmargin: 0;\n\n/* gray dotted border, 1 px wide */\nborder: 1px dotted #ddd;\n\n/* padding (\"inner margin\") settings are top - right - bottom - left */\n/* (think clockwise)                                                 */\npadding: 6px 6px 6px 6px;\n}\n\n\n/* title page */\n\n\n/* heading1 is used for document title */\nh1\n{\n/* list of fonts provides fallbacks if a font is not present */\nfont-family: Verdana, Arial, Helvetica, Sans-Serif;\n\n/* font size, relative to body font size */\nfont-size: 150%;\n\n/* bold face, higher number is more bold */\nfont-weight: 600;\n\n/* line height, relative to body line height */\nline-height: 250%;\n\n/* center */\ntext-align: center;\n\n/* foreground color: dark blue */\ncolor: #009;\n\n/* background color: gray */\nbackground-color: #ddd;\n\n/* margin settings are top - right - bottom - left (think clockwise) */\nmargin: 15px 0 15px 0;\n\n/* no padding (\"inner margin\") */\npadding: 0;\n}\n\n\n\n/* author on title page is formatted as h3          */\n/* these settings overwrite the regular h3 settings */\nh3.author\n{\n/* set font size and line height                             */\n/* list of fonts provides fallbacks in case selected fonts are not present */\nfont: 12px/18px Verdana, Arial, Helvetica, Sans-Serif;\n\n/* bold face, higher number is more bold */\nfont-weight: 600;\n\n/* do not underline */\ntext-decoration: none;\n\n/* center text */\ntext-align: center;\n\n/* color: black */\ncolor: #000;\n\n/* background-color is a very light grey */\n/* alternative: #fff = white             */\nbackground-color: #fefefe;\n\n/* margin settings are top - right - bottom - left (think clockwise) */\nmargin: 0 15px 15px 15px;\n\n/* no padding */\npadding: 0;\n\n/* no border */\nborder: 0;\n}\n\n\n/* copyright and date */\n.copyright, .pubdate\n{\n/* list of fonts provides fallbacks if a font is not present */\nfont-family: Verdana, Arial, Helvetica, Sans-Serif;\n\n/* font size, relative to body font size */\nfont-size: 90%;\n\n/* center */\ntext-align: center;\n\n/* margin settings are top - right - bottom - left (think clockwise) */\nmargin: 15px 15px 15px 15px;\n\n/* no padding (\"inner margin\") */\npadding: 0;\n\n/* no border */\nborder: 0;\n}\n\n\n/* legal notice box */\ndiv.legalnotice\n{\n/* list of fonts provides fallbacks if a font is not present */\nfont-family: Verdana, Arial, Helvetica, Sans-Serif;\n\n/* font size, relative to body font size */\nfont-size: 90%;\n\n/* color: black */\ncolor: #000;\n\n/* background color: gray */\nbackground-color: #ddd;\n\n/* margin settings are top - right - bottom - left (think clockwise) */\nmargin: 10px 45px 10px 45px;\n\n/* padding (\"inner margin\") settings are top - right - bottom - left */\n/* (think clockwise)                                                 */\npadding: 5px 5px 5px 5px;\n\n/* solid black border, 1px wide */\nborder: 1px solid #000;\n}"
  },
  {
    "path": "lib/zeosdbo/doc/html/installation.html",
    "content": "\n<!DOCTYPE html\n  PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">\n<html xmlns=\"http://www.w3.org/1999/xhtml\"><head>\n      <meta http-equiv=\"Content-Type\" content=\"text/html; charset=iso-8859-1\">\n   <title>ZeosDBO Installation Guide</title><link rel=\"stylesheet\" href=\"ede.css\" type=\"text/css\"><meta name=\"generator\" content=\"DocBook XSL Stylesheets V1.66.0\"></head><body><div xmlns=\"\" id=\"customheader\"><a href=\"http://zeos.firmos.at/portal.php\" style=\"color: #fff; font-weight: bold;\">ZeosLib</a><b> - open source tools for your database solutions</b></div><div class=\"article\" lang=\"en\"><div class=\"titlepage\"><div><div><h1 class=\"title\"><a id=\"d4e1\"></a>ZeosDBO Installation Guide</h1></div><div><h3 class=\"corpauthor\">ZeosLib Development Group</h3></div><div><p class=\"pubdate\">28 May 2008 (Updated 29/5/2008)</p></div></div><hr></div><p>You can download the current (SVN) version from <a href=\"svn://www.firmos.at/zeos/trunk/\" target=\"_top\">svn://www.firmos.at/zeos/trunk/</a></p><p>The development/testing branch is at  <a href=\"svn://www.firmos.at/zeos/branches/testing/\" target=\"_top\">svn://www.firmos.at/zeos/branches/testing/</a></p><p>Snapshots can be found at <a href=\"http://zeosdownloads.firmos.at/downloads/snapshots/\" target=\"_top\">http://zeosdownloads.firmos.at/downloads/snapshots/</a></p><p>Official reaseses are published at the <a href=\"http://zeos.firmos.at/portal.php\" target=\"_top\">Zeoslib forum</a> and the <a href=\"http://sourceforge.net/projects/zeoslib\" target=\"_top\">Zeoslib Sourceforge Project pages</a></p><div class=\"orderedlist\"><ol type=\"1\"><li><p>Unpack the archive to a folder (not for SVN versions, of course)</p></li><li><p>Copy the required dlls for your database client to the windows system directory (usually <tt class=\"filename\">Windows\\System</tt> or <tt class=\"filename\">winnt\\system32</tt>) or use the database client installer.</p><i><span class=\"remark\">Attention : think about licence issues when working with the database client libraries. Not all software is freely distributable in all situations. These libraries are <span class=\"emphasis\"><em>NOT</em></span> a part of the zeoslib packages.</span></i></li><li><p>Add the <tt class=\"filename\">build</tt> Directory of the package you are about to install to Delphi's library path.</p></li><li><p>Locate the package directory associated with your compiler and open the <tt class=\"filename\">ZeosDbo.bpg</tt> project group. Load the project and compile the following components in the order listed (or just choose <tt class=\"filename\">compile all</tt> from <tt class=\"filename\">Project</tt>-Menu):\n\n\t\t\t<div class=\"itemizedlist\"><ul type=\"disc\"><li><tt class=\"filename\">ZCore.bpl</tt></li><li><tt class=\"filename\">ZParseSql.bpl</tt></li><li><tt class=\"filename\">ZPlain.bpl</tt></li><li><tt class=\"filename\">ZDbc.bpl</tt></li><li><tt class=\"filename\">ZComponent.bpl</tt></li></ul></div></p></li><li><p>If all the packages, listed above are successfully compiled you have to install the <tt class=\"filename\">ZComponentDesign.bpl</tt>. After that all ZEOS components are available in the IDE.</p><i><span class=\"remark\">If the <tt class=\"filename\">ZComponentDesign.bpl</tt> package isn't available for your compiler (eg. for fpc/lazarus), you should just install the <tt class=\"filename\">ZComponent.bpl</tt></span></i></li><li><p>Create your own project and start adding the compoents through the IDE and set connection properties. For a quick tutorial, use the example provided with the project or browse the resources on the web page.</p></li></ol></div><div class=\"orderedlist\"><p class=\"title\"><b>Observations:</b></p><ol type=\"1\"><li><p>When installing the library under C++ Builder (any version) it is highly recommended to remove any previously installed version of ZEOSDBO.</p><p>To do that you should first close C++ Builder (as some of these files may be locked) and remove the (ZCore|ZParseSql|ZPlain|Zdbc|ZComponent)(.bpl|.tds|.bpi|.lib) files from <tt class=\"filename\">$(BCB)\\Projects\\Lib</tt> and <tt class=\"filename\">$(BCB)\\Projects\\Bpl</tt> (where $(BCB) is something like <tt class=\"filename\">C:\\Program Files\\Borland\\CBuilder[4-6]</tt>).</p></li><li><p>When compiling the library from <tt class=\"filename\">ZeosDbo.bpg</tt> under C++ Builder you may receive some warnings like 'Unable to find package import <tt class=\"filename\">XXX.bpi</tt>' and you may have to press Cancel multiple times to continue.</p><p>We're trying to get rid of this annoying behaviour, but until then here are some possible ways to avoid it, if needed:\n\n\t\t\t\t<div class=\"orderedlist\"><ol type=\"a\"><li>Open, compile and install the packages (*.bpk) in the appropriate order (see Installation step #3) - i.e without using <tt class=\"filename\">ZeosDbo.bpg</tt>.</li><li><p>Open a command line in \\packages\\CBuilder[4-6] and do a manual make - like this: <span><b class=\"command\">make -f ZeosDbo.bpg</b></span>. This requires the <tt class=\"literal\">PATH</tt> and <tt class=\"literal\">LIB</tt> environment variables to be set properly, like this:\n\n\n\n<pre class=\"programlisting\">SET BCB=d:\\borland\\cbuilder6\n\nSET PATH=%BCB%\\bin\n\nSET LIB=%BCB%\\lib</pre>\n\n\n\nThen open <tt class=\"filename\">ZeosDbo.bpg</tt> in the IDE and install the packages the usual way.</p></li></ol></div></p></li><li><p>While installing ZEOSDBO under C++ Builder version 4 from the IDE, you may get this error when compiling the ZDbc package :\n\n\n\n<pre class=\"programlisting\">[Pascal Fatal Error] ZDbcMetadata.pas(3076): Internal error: SY876.</pre>\n\n\n\nCurrently, there is no known solution to this problem.  Therefore,it is recommended to compile Zeoslib from the command line (issuing a <span><b class=\"command\">make -f ZeosDBO.bpg</b></span> from the directory <tt class=\"filename\">/packages/cbuilder4</tt> should accomplish this)\n\nand then to install the packages through menu Component-&gt;Install Packages.</p></li></ol></div></div><div xmlns=\"\" id=\"customfooter\">\n(c) 1999 - 2006 The Zeos Development Group\n</div></body></html>"
  },
  {
    "path": "lib/zeosdbo/doc/html/knownbugs.html",
    "content": "\n<!DOCTYPE html\n  PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">\n<html xmlns=\"http://www.w3.org/1999/xhtml\"><head>\n      <meta http-equiv=\"Content-Type\" content=\"text/html; charset=iso-8859-1\">\n   <title>ZeosDBO Known Bugs</title><link rel=\"stylesheet\" href=\"ede.css\" type=\"text/css\"><meta name=\"generator\" content=\"DocBook XSL Stylesheets V1.66.0\"></head><body><div xmlns=\"\" id=\"customheader\"><a href=\"http://zeos.firmos.at/portal.php\" style=\"color: #fff; font-weight: bold;\">ZeosLib</a><b> - open source tools for your database solutions</b></div><div class=\"article\" lang=\"en\"><div class=\"titlepage\"><div><div><h1 class=\"title\"><a id=\"d4e1\"></a>ZeosDBO Known Bugs</h1></div><div><h3 class=\"corpauthor\">ZeosLib Development Group</h3></div><div><p class=\"pubdate\">23 September 2005</p></div></div><hr></div><div class=\"orderedlist\"><ol type=\"1\"><li>Even if ZConnection.SQLHourGlass is set to \"true\" the mousepointer looks like an arrow. This is no bug of Zeos. DBScreen is not nil when using the unit DB which is used by several units of zeos, BUT is is initialized with a class-object which is not changing the cursor, the user sees (Forms. Screen.Cursor). This Object is initialized in unit DBCtrls. If you want to see the SQLHourGlass then you should add the unit DBCtrls to your uses-clause. </li><li>Error while saving date using ADO and MSSQL Server. If a date has to be stored having a day less then 13, then it will be stored changing day with month (see: http://support.microsoft.com/default.aspx?scid=kb;en-us;327579).</li><li>ADO (with MSAccess) returns smallInt instead of boolean type. This is the \"normal\" behaiviour of ADO. (Tested and approved with a TADODataSet and this also created a TSmallIntField).</li><li>SQLHourGlass is never shown. Cursor is initialized in unit DBCtrls. If you want to see the SQLHourGlass then you have to add the unit DBCtrls to the uses-clause.</li><li>RequestLive (since V 6.5.2 renamed to ReadOnly), CachedUpdates and UpdateObject are processed by ZeosDBO Query differently from standard TQuery. In ZeosDBO there is no correlation between them as it done in VCL. If your query is alive you must set RequestLive=true doesn't matter have you set CachedUpdates+UpdateObject or not. Otherwise, if RequestLive=false your query will be always read-only. UpdateObject can be used in non-cached mode as well as in cached mode.</li><li>Because of the limitations of dblibrary only the first 255 char is returned for char and varchar columns.</li><li>LargeInt fields are not completely supported in Delphi 4,5 and C++ Builder 4,5.</li><li>Sybase does not support procedure parameter type query. Though a workaround was possible for ASE12.5 and above.</li><li>Oracle provider for ADO is case sensitive for the table name when getting schema columns, the MS version is working right. Identifier convertion must be reviewed for ADO.</li><li>If you are using dbgrid, all the records will be fetched because of a call to recordcount (in scrollbar). You can avoid this behavior if you turn on the Filtered property. In this case you can achieve fast open even on bigger resultsets.</li></ol></div></div><div xmlns=\"\" id=\"customfooter\">\n(c) 1999 - 2006 The Zeos Development Group\n</div></body></html>"
  },
  {
    "path": "lib/zeosdbo/doc/html/license.html",
    "content": "\n<!DOCTYPE html\n  PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">\n<html xmlns=\"http://www.w3.org/1999/xhtml\"><head>\n      <meta http-equiv=\"Content-Type\" content=\"text/html; charset=iso-8859-1\">\n   <title>GNU LESSER GENERAL PUBLIC LICENSE</title><link rel=\"stylesheet\" href=\"ede.css\" type=\"text/css\"><meta name=\"generator\" content=\"DocBook XSL Stylesheets V1.66.0\"></head><body><div xmlns=\"\" id=\"customheader\"><a href=\"http://zeos.firmos.at/portal.php\" style=\"color: #fff; font-weight: bold;\">ZeosLib</a><b> - open source tools for your database solutions</b></div><div class=\"article\" lang=\"en\"><div class=\"titlepage\"><div><div><h1 class=\"title\"><a id=\"d4e1\"></a>GNU LESSER GENERAL PUBLIC LICENSE</h1></div></div><hr></div><div class=\"toc\"><p><b>Table of Contents</b></p><dl><dt><span class=\"sect1\"><a href=\"#d4e6\">1. Preamble</a></span></dt><dt><span class=\"sect1\"><a href=\"#d4e23\">2. GNU LESSER GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION</a></span></dt><dt><span class=\"sect1\"><a href=\"#d4e74\">3. NO WARRANTY</a></span></dt><dt><span class=\"sect1\"><a href=\"#d4e78\">4. END OF TERMS AND CONDITIONS</a></span></dt><dt><span class=\"sect1\"><a href=\"#d4e81\">5. How to Apply These Terms to Your New Libraries</a></span></dt></dl></div><p>Copyright (C) 1991, 1999 Free Software Foundation, Inc. 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed.</p><p>[This is the first released version of the Lesser GPL.  It also counts as the successor of the GNU Library Public License, version 2, hence the version number 2.1.]</p><div class=\"sect1\" lang=\"en\"><div class=\"titlepage\"><div><div><h2 class=\"title\" style=\"clear: both\"><a id=\"d4e6\"></a>1.&nbsp;Preamble</h2></div></div></div><p>The licenses for most software are designed to take away your freedom to share and change it.  By contrast, the GNU General Public Licenses are intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users.</p><p>This license, the Lesser General Public License, applies to some specially designated software packages--typically libraries--of the Free Software Foundation and other authors who decide to use it.  You can use it too, but we suggest you first think carefully about whether this license or the ordinary General Public License is the better strategy to use in any particular case, based on the explanations below.</p><p>When we speak of free software, we are referring to freedom of use, 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 and use pieces of it in new free programs; and that you are informed that you can do these things.</p><p>To protect your rights, we need to make restrictions that forbid distributors to deny you these rights or to ask you to surrender these rights.  These restrictions translate to certain responsibilities for you if you distribute copies of the library or if you modify it.</p><p>For example, if you distribute copies of the library, whether gratis or for a fee, you must give the recipients all the rights that we gave you.  You must make sure that they, too, receive or can get the source code.  If you link other code with the library, you must provide complete object files to the recipients, so that they can relink them with the library after making changes to the library and recompiling it.  And you must show them these terms so they know their rights.</p><p>We protect your rights with a two-step method: (1) we copyright the library, and (2) we offer you this license, which gives you legal permission to copy, distribute and/or modify the library.</p><p>To protect each distributor, we want to make it very clear that there is no warranty for the free library.  Also, if the library is modified by someone else and passed on, the recipients should know that what they have is not the original version, so that the original author's reputation will not be affected by problems that might be introduced by others.</p><p>Finally, software patents pose a constant threat to the existence of any free program. We wish to make sure that a company cannot effectively restrict the users of a free program by obtaining a restrictive license from a patent holder.  Therefore, we insist that any patent license obtained for a version of the library must be consistent with the full freedom of use specified in this license.</p><p>Most GNU software, including some libraries, is covered by the ordinary GNU General Public License. This license, the GNU Lesser General Public License, applies to certain designated libraries, and is quite different from the ordinary General Public License.  We use this license for certain libraries in order to permit linking those libraries into non-free programs.</p><p>When a program is linked with a library, whether statically or using a shared library, the combination of the two is legally speaking a combined work, a derivative of the original library.  The ordinary General Public License therefore permits such linking only if the entire combination fits its criteria of freedom. The Lesser General Public License permits more lax criteria for linking other code with the library.</p><p>We call this license the \"Lesser\" General Public License because it does Less to protect the user's freedom than the ordinary General Public License.  It also provides other free software developers Less of an advantage over competing non-free programs.  These disadvantages are the reason we use the ordinary General Public License for many libraries.  However, the Lesser license provides advantages in certain special circumstances.</p><p>For example, on rare occasions, there may be a special need to encourage the widest possible use of a certain library, so that it becomes a de-facto standard.  To achieve this, non-free programs must be allowed to use the library.  A more frequent case is that a free library does the same job as widely used non-free libraries.  In this case, there is little to gain by limiting the free library to free software only, so we use the Lesser General Public License.</p><p>In other cases, permission to use a particular library in non-free programs enables a greater number of people to use a large body of free software.  For example, permission to use the GNU C Library in non-free programs enables many more people to use the whole GNU operating system, as well as its variant, the GNU/Linux operating system.</p><p>Although the Lesser General Public License is Less protective of the users' freedom, it does ensure that the user of a program that is linked with the Library has the freedom and the wherewithal to run that program using a modified version of the Library.</p><p>The precise terms and conditions for copying, distribution and modification follow.  Pay close attention to the difference between a \"work based on the library\" and a \"work that uses the library\".  The former contains code derived from the library, whereas the latter must be combined with the library in order to run.</p></div><div class=\"sect1\" lang=\"en\"><div class=\"titlepage\"><div><div><h2 class=\"title\" style=\"clear: both\"><a id=\"d4e23\"></a>2.&nbsp;GNU LESSER GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION</h2></div></div></div><p>0. This License Agreement applies to any software library or other program which contains a notice placed by the copyright holder or other authorized party saying it may be distributed under the terms of this Lesser General Public License (also called \"this License\"). Each licensee is addressed as \"you\".</p><p>A \"library\" means a collection of software functions and/or data prepared so as to be conveniently linked with application programs (which use some of those functions and data) to form executables.</p><p>The \"Library\", below, refers to any such software library or work which has been distributed under these terms.  A \"work based on the Library\" means either the Library or any derivative work under copyright law: that is to say, a work containing the Library or a portion of it, either verbatim or with modifications and/or translated straightforwardly into another language.  (Hereinafter, translation is included without limitation in the term \"modification\".)</p><p>\"Source code\" for a work means the preferred form of the work for making modifications to it.  For a library, 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 library.</p><p>Activities other than copying, distribution and modification are not covered by this License; they are outside its scope.  The act of running a program using the Library is not restricted, and output from such a program is covered only if its contents constitute a work based on the Library (independent of the use of the Library in a tool for writing it). Whether that is true depends on what the Library does and what the program that uses the Library does.</p><p>1. You may copy and distribute verbatim copies of the Library's complete 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 distribute a copy of this License along with the Library.</p><p>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.</p><p>2. You may modify your copy or copies of the Library or any portion of it, thus forming a work based on the Library, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions:</p><p>a) The modified work must itself be a software library.</p><p>b) You must cause the files modified to carry prominent notices stating that you changed the files and the date of any change.</p><p>c) You must cause the whole of the work to be licensed at no charge to all third parties under the terms of this License.</p><p>d) If a facility in the modified Library refers to a function or a table of data to be supplied by an application program that uses the facility, other than as an argument passed when the facility is invoked, then you must make a good faith effort to ensure that, in the event an application does not supply such function or table, the facility still operates, and performs whatever part of its purpose remains meaningful.</p><p>(For example, a function in a library to compute square roots has a purpose that is entirely well-defined independent of the application.  Therefore, Subsection 2d requires that any application-supplied function or table used by this function must be optional: if the application does not supply it, the square root function must still compute square roots.)</p><p>These requirements apply to the modified work as a whole.  If identifiable sections of that work are not derived from the Library, 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 Library, 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.</p><p>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 Library.</p><p>In addition, mere aggregation of another work not based on the Library with the Library (or with a work based on the Library) on a volume of a storage or distribution medium does not bring the other work under the scope of this License.</p><p>3. You may opt to apply the terms of the ordinary GNU General Public License instead of this License to a given copy of the Library.  To do this, you must alter all the notices that refer to this License, so that they refer to the ordinary GNU General Public License, version 2, instead of to this License.  (If a newer version than version 2 of the ordinary GNU General Public License has appeared, then you can specify that version instead if you wish.)  Do not make any other change in these notices.</p><p>Once this change is made in a given copy, it is irreversible for that copy, so the ordinary GNU General Public License applies to all subsequent copies and derivative works made from that copy.</p><p>This option is useful when you wish to copy part of the code of the Library into a program that is not a library.</p><p>4. You may copy and distribute the Library (or a portion or derivative of it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you 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.</p><p>If distribution of 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 satisfies the requirement to distribute the source code, even though third parties are not compelled to copy the source along with the object code.</p><p>5. A program that contains no derivative of any portion of the Library, but is designed to work with the Library by being compiled or linked with it, is called a \"work that uses the Library\".  Such a work, in isolation, is not a derivative work of the Library, and therefore falls outside the scope of this License.</p><p>However, linking a \"work that uses the Library\" with the Library creates an executable that is a derivative of the Library (because it contains portions of the Library), rather than a \"work that uses the library\".  The executable is therefore covered by this License. Section 6 states terms for distribution of such executables.</p><p>When a \"work that uses the Library\" uses material from a header file that is part of the Library, the object code for the work may be a derivative work of the Library even though the source code is not. Whether this is true is especially significant if the work can be linked without the Library, or if the work is itself a library.  The threshold for this to be true is not precisely defined by law.</p><p>If such an object file uses only numerical parameters, data structure layouts and accessors, and small macros and small inline functions (ten lines or less in length), then the use of the object file is unrestricted, regardless of whether it is legally a derivative work.  (Executables containing this object code plus portions of the Library will still fall under Section 6.)</p><p>Otherwise, if the work is a derivative of the Library, you may distribute the object code for the work under the terms of Section 6. Any executables containing that work also fall under Section 6, whether or not they are linked directly with the Library itself.</p><p>6. As an exception to the Sections above, you may also combine or link a \"work that uses the Library\" with the Library to produce a work containing portions of the Library, and distribute that work under terms of your choice, provided that the terms permit modification of the work for the customer's own use and reverse engineering for debugging such modifications.</p><p>You must give prominent notice with each copy of the work that the Library is used in it and that the Library and its use are covered by this License.  You must supply a copy of this License.  If the work during execution displays copyright notices, you must include the copyright notice for the Library among them, as well as a reference directing the user to the copy of this License.  Also, you must do one of these things:</p><p>a) Accompany the work with the complete corresponding machine-readable source code for the Library including whatever changes were used in the work (which must be distributed under Sections 1 and 2 above); and, if the work is an executable linked with the Library, with the complete machine-readable \"work that uses the Library\", as object code and/or source code, so that the user can modify the Library and then relink to produce a modified executable containing the modified Library.  (It is understood that the user who changes the contents of definitions files in the Library will not necessarily be able to recompile the application to use the modified definitions.)</p><p>b) Use a suitable shared library mechanism for linking with the Library.  A suitable mechanism is one that (1) uses at run time a copy of the library already present on the user's computer system, rather than copying library functions into the executable, and (2) will operate properly with a modified version of the library, if the user installs one, as long as the modified version is interface-compatible with the version that the work was made with.</p><p>c) Accompany the work with a written offer, valid for at least three years, to give the same user the materials specified in Subsection 6a, above, for a charge no more than the cost of performing this distribution.</p><p>d) If distribution of the work is made by offering access to copy from a designated place, offer equivalent access to copy the above specified materials from the same place.</p><p>e) Verify that the user has already received a copy of these materials or that you have already sent this user a copy.</p><p>For an executable, the required form of the \"work that uses the Library\" must include any data and utility programs needed for reproducing the executable from it.  However, as a special exception, the materials to be 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.</p><p>It may happen that this requirement contradicts the license restrictions of other proprietary libraries that do not normally accompany the operating system.  Such a contradiction means you cannot use both them and the Library together in an executable that you distribute.</p><p>7. You may place library facilities that are a work based on the Library side-by-side in a single library together with other library facilities not covered by this License, and distribute such a combined library, provided that the separate distribution of the work based on the Library and of the other library facilities is otherwise permitted, and provided that you do these two things:</p><p>a) Accompany the combined library with a copy of the same work based on the Library, uncombined with any other library facilities.  This must be distributed under the terms of the Sections above.</p><p>b) Give prominent notice with the combined library of the fact that part of it is a work based on the Library, and explaining where to find the accompanying uncombined form of the same work.</p><p>8. You may not copy, modify, sublicense, link with, or distribute the Library except as expressly provided under this License.  Any attempt otherwise to copy, modify, sublicense, link with, or distribute the Library 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.</p><p>9. 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 Library or its derivative works.  These actions are prohibited by law if you do not accept this License.  Therefore, by modifying or distributing the Library (or any work based on the Library), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Library or works based on it.</p><p>10. Each time you redistribute the Library (or any work based on the Library), the recipient automatically receives a license from the original licensor to copy, distribute, link with or modify the Library 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 with this License.</p><p>11. 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 Library at all.  For example, if a patent license would not permit royalty-free redistribution of the Library 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 Library.</p><p>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.</p><p>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.</p><p>This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License.</p><p>12. If the distribution and/or use of the Library is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Library 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.</p><p>13. The Free Software Foundation may publish revised and/or new versions of the Lesser 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.</p><p>Each version is given a distinguishing version number.  If the Library 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 Library does not specify a license version number, you may choose any version ever published by the Free Software Foundation.</p><p>14. If you wish to incorporate parts of the Library into other free programs whose distribution conditions are incompatible with these, 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.</p></div><div class=\"sect1\" lang=\"en\"><div class=\"titlepage\"><div><div><h2 class=\"title\" style=\"clear: both\"><a id=\"d4e74\"></a>3.&nbsp;NO WARRANTY</h2></div></div></div><p>15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE LIBRARY \"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 LIBRARY IS WITH YOU.  SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.</p><p>16. 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 LIBRARY 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 LIBRARY (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 LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. </p></div><div class=\"sect1\" lang=\"en\"><div class=\"titlepage\"><div><div><h2 class=\"title\" style=\"clear: both\"><a id=\"d4e78\"></a>4.&nbsp;END OF TERMS AND CONDITIONS</h2></div></div></div><p></p></div><div class=\"sect1\" lang=\"en\"><div class=\"titlepage\"><div><div><h2 class=\"title\" style=\"clear: both\"><a id=\"d4e81\"></a>5.&nbsp;How to Apply These Terms to Your New Libraries</h2></div></div></div><p>If you develop a new library, and you want it to be of the greatest possible use to the public, we recommend making it free software that everyone can redistribute and change.  You can do so by permitting redistribution under these terms (or, alternatively, under the terms of the ordinary General Public License).</p><p>To apply these terms, attach the following notices to the library.  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.</p><p>&lt;one line to give the library's name and a brief idea of what it does.&gt; Copyright (C)  &lt;year&gt;  &lt;name of author&gt;</p><p>This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version.</p><p>This library 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 Lesser General Public License for more details.</p><p>You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA</p><p>Also add information on how to contact you by electronic and paper mail.</p><p>You should also get your employer (if you work as a programmer) or your school, if any, to sign a \"copyright disclaimer\" for the library, if necessary.  Here is a sample; alter the names:</p><p>Yoyodyne, Inc., hereby disclaims all copyright interest in the library `Frob' (a library for tweaking knobs) written by James Random Hacker.</p><p>&lt;signature of Ty Coon&gt;, 1 April 1990 Ty Coon, President of Vice</p><p>That's all there is to it!</p></div></div><div xmlns=\"\" id=\"customfooter\">\n(c) 1999 - 2006 The Zeos Development Group\n</div></body></html>"
  },
  {
    "path": "lib/zeosdbo/doc/html/overview.html",
    "content": "\n<!DOCTYPE html\n  PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">\n<html xmlns=\"http://www.w3.org/1999/xhtml\"><head>\n      <meta http-equiv=\"Content-Type\" content=\"text/html; charset=iso-8859-1\">\n   <title>Overview of the Zeos Database Objects Architecture</title><link rel=\"stylesheet\" href=\"ede.css\" type=\"text/css\"><meta name=\"generator\" content=\"DocBook XSL Stylesheets V1.66.0\"></head><body><div xmlns=\"\" id=\"customheader\"><a href=\"http://zeos.firmos.at/portal.php\" style=\"color: #fff; font-weight: bold;\">ZeosLib</a><b> - open source tools for your database solutions</b></div><div class=\"article\" lang=\"en\"><div class=\"titlepage\"><div><div><h1 class=\"title\"><a id=\"d4e1\"></a>Overview of the Zeos Database Objects Architecture</h1></div><div><div class=\"author\"><h3 class=\"author\"><span class=\"firstname\">Sergey</span> <span class=\"surname\">Seroukhov</span></h3></div></div><div><div class=\"author\"><h3 class=\"author\"><span class=\"firstname\">Merlin</span> <span class=\"surname\">Moncure</span></h3></div></div><div><p class=\"pubdate\">26 November 2003 (Updated 29/5/2008 by Mark Daems)</p></div></div><hr></div><div class=\"toc\"><p><b>Table of Contents</b></p><dl><dt><span class=\"sect1\"><a href=\"#d4e28\">1. General Overview</a></span></dt><dt><span class=\"sect1\"><a href=\"#d4e44\">2. Plain API Layer</a></span></dt><dt><span class=\"sect1\"><a href=\"#d4e58\">3. Database Connectivity Layer</a></span></dt><dt><span class=\"sect1\"><a href=\"#d4e92\">4. Component Layer</a></span></dt><dt><span class=\"sect1\"><a href=\"#d4e134\">5. Epilog</a></span></dt></dl></div><p>Direct access to SQL databases continues to be a vital technology even in today's enterprise environment. Thousands of two-tier client server applications are developed and maintained in the international business community. Most of them are built off of specially designed application programming interfaces (APIs) to retrieve relational data and execute SQL statements.</p><p>Currently, there is several standardized and widely used APIs to access SQL databases, such as ODBC, JDBC, and ADO. Borland also released their proprietary database middleware interface for its development tools, called the Borland Database Engine (BDE). Despite being freely distributed with Borland's popular line of application development tools, the BDE was unpopular because of complexities in installation and poor performance. As Delphi became one of the leading application development tools for the Windows platform, individuals and companies proposed alternative interfaces to the BDE. These &#8220;<span class=\"quote\">BDE Alternatives</span>&#8221; optimized access to the database by directly using the native database driver, providing performance and feature advantages with respect to the BDE.</p><p>Realizing the limitations of the BDE, Borland proposed a new type of database interface called dbExpress. This interface was designed to broker access between Delphi and virtually any relational database through 3rd party drivers. Borland significantly improved the performance of dbExpress with respect to the BDE, but the implementation was buggy and supported only a limited subset of SQL that hampered functionality.</p><p>The Zeos Database Object component library (ZeosLib) is one of the best-known BDE alternatives. Originally the library was developed for MySQL and PostgreSQL databases, but support for other vendors was soon added. During the development process, certain limitations of the original design became more and more apparent. These limitations began to put a strain on the overall architecture and the development team decided a ground up rewrite was the best way to proceed. The new design was built to handle an extended feature list with several new requirements:\n\n\t\t<div class=\"orderedlist\"><ol type=\"1\"><li>Support for different compilers</li><li>Versioning database driver system</li><li>&#8220;<span class=\"quote\">Database Insensitive</span>&#8221; design for cross-database development</li><li>Support for multiple high level interfaces (TDataset, dbExpress, Midas)</li><li>Extensible feature system for server specific support</li></ol></div></p><div class=\"sect1\" lang=\"en\"><div class=\"titlepage\"><div><div><h2 class=\"title\" style=\"clear: both\"><a id=\"d4e28\"></a>1.&nbsp;General Overview</h2></div></div></div><p>To address multiple and sometimes inconsistent requirements the development team had to completely rethink the new architecture. It is complex with respect to previous designs but not over-designed. Each module put into the new design was carefully considered and carries special unique features. In this article we'll try to present you the new architecture and explain its purpose.</p><p>From a top-down view the library is separated into three logical layers:\n\n\t\t\t<div class=\"orderedlist\"><ol type=\"1\"><li>Plain API Layer</li><li>Database Connectivity Layer</li><li>Component Layer</li></ol></div></p><div class=\"mediaobject\"><img src=\"images/Overview001.gif\"></div><p>The Plain API implements low-level functions specific to each SQL server. The Component API encapsulates the main library interface that is utilized by application developers. The DBC API is the middleware that retrieves, stores and modifies data for the high level components.</p><p>Each layer has several horizontal and/or vertical sub-layers semi-independently from each other (see picture 1). Let's go through each layer and look how all that works.</p></div><div class=\"sect1\" lang=\"en\"><div class=\"titlepage\"><div><div><h2 class=\"title\" style=\"clear: both\"><a id=\"d4e44\"></a>2.&nbsp;Plain API Layer</h2></div></div></div><p>ZeosDBO components do not communicate directly with SQL servers. Instead they use native client libraries provided with SQL databases. The Plain API layer provides an access to functions of native client libraries, constants and data structures (usually written in plain C) from the Object Pascal language or C++.</p><p>That functionality was the original basis for ZeosDBO. Support for multiple versions of client libraries and SQL servers was the main deficiency of earlier designs...</p><p>Native library calls (dynamic libraries in Windows and shared libraries in Unix) are represented in programming language as regular functions. For example:\n\n<pre class=\"programlisting\">ZPlainMySql323.pas:\n\nfunction mysql_init(Handle: PMYSQL): PMYSQL; external 'libmysql.dll';</pre></p><p>Usually database APIs do not significantly change between versions. But because function calls do not allow polymorphism adding support for new versions of the Plain API is coding intensive. Hard coded approaches are inflexible and error-prone, which limit long term feasibility.\n\n<pre class=\"programlisting\">if Version = 'mysql-3.23' then\n  ZPlainMySql323.mysql_init(...)\nelse ZPlainMySql40.mysql_init(...);</pre></p><p>To implement polymorphism, simplify source code, and provide insulation from changes in SQL server protocols a new extremely thin interface layer was added into ZeosDBO. That layer is called &#8220;<span class=\"quote\">Plain Drivers</span>&#8221; and implemented as follows:\n\n<pre class=\"programlisting\">// Generic MySQL driver interface\nIZMySQLDriver = interface ...\n  function mysql_init(...)\nend;\n\n// MySQL driver for version 3.23\nTZMySQL323Driver = class (TInterfacedObject, IZMySQLDriver)\n  function mysql_init(...)\nend;\n\n// MySQL driver for version 4.0\nTZMySQL40Driver = class (TInterfacedObject, IZMySQLDriver)\n  function mysql_init(...)\nend;\n\nfunction TZMySQL323Driver.mysql_init(...)\nbegin\n  Result := ZPlainMySql323.mysql_init(...);\nend;\n\nfunction TZMySQL40Driver.mysql_init(...)\nbegin\n  Result := ZPlainMySql40.mysql_init(...);\nend;</pre></p><p>Using such thin class wrapper allows easy addition of new client interfaces. The specific functionality that requires overriding is encapsulated in the Plain driver. The rest of the code now has a uniform method of providing native database calls, without requiring specific knowledge about the database server.\n\n<pre class=\"programlisting\">// Initialize plain driver\nPlainDriver: IZMySqlDriver;\n\nif Version = 'mysql-3.23' then\n  PlainDriver := TZMySQL323Driver.Create()\nelse PlainDriver := TZMySQL40Driver.Create();\n\n// Use plain driver\nPlainDriver.mysql_init(...)</pre></p><p>With this approach it is possible to use the same API for different SQL servers, independently of version.</p></div><div class=\"sect1\" lang=\"en\"><div class=\"titlepage\"><div><div><h2 class=\"title\" style=\"clear: both\"><a id=\"d4e58\"></a>3.&nbsp;Database Connectivity Layer</h2></div></div></div><p>With native access provided to the database, Delphi database aware components can now expect database specific functionality in a uniform manner. However, each SQL server has different semantics that must be designed into the components to provide a universal generic interface. The main goal of the Zeos Database Objects is to provide this generic interface to the application developer.</p><p>In older versions of ZeosDBO, the intermediate interface was implemented as a class wrapper to the MySQL and PostgreSQL connection objects. These two databases have very similar capabilities so design of intermediate API was not complex. However, support for other SQL servers added new and very specific features. After several extensions to support these features the class architecture became was not clearly defined. Ultimately, the interface broke its encapsulation rules and the high level components were forced to make low level database calls.</p><p>To overcome this difficulty in the new version, the overall design was an abstract approach with an intermediate interface. Design of such an interface is not trivial. So to avoid new mistakes it was decided to avoid a proprietary design, and instead draw inspiration from a well-known database API.</p><p>As a prototype for the intermediate interface the development team chose JDBC 2.0. JDBC is one of the latest and more popular APIs in that database community. It covers various abstractions such as statements, result sets, stored procedures, blobs, and very rich metadata definitions.</p><p>JDBC API is implemented in Java through set of interfaces. Borland compilers support interfaces, so porting JDBC from Java to Object Pascal was straightforward. Data types and method names were generally preserved. Overloaded methods were avoided because of poor support in the C++ Builder family of compilers.</p><p>The main DBC interfaces are presented on picture 2.\n\n\t\t\t<div class=\"mediaobject\"><img src=\"images/Overview002.gif\"></div></p><p>Standard JDBC interfaces provide a uniform client API. To address functionality specific to different SQL servers, two general approaches were chosen.</p><p>1. Developers may initialize database connection object with list of string parameters. Each parameter switches server specific settings. For JDBC that method is not new.</p><p>Example: parameters can be defined in Connection URL -\n\n<pre class=\"programlisting\">zdbc:mysql://localhost/database?compress=true</pre>\n\nor parameters can be passed to connection factory method\n\n<pre class=\"programlisting\">Params.Values['compress'] := 'true';\nConnection := DriverManager.CreateConnectionWithParams(Url, Params);</pre></p><p>Additionally in ZeosDBO developers extended other DBC interfaces to initialize other object with specific parameters, particularly Statement object:\n\n<pre class=\"programlisting\">Params.Values['oidasblod'] := 'true';\nStatement := Connection.CreateStatementWithParams(Params);</pre></p><p> 2. In Object Pascal each class is able to implement multiple interfaces simultaneously.\nWe used that to extend standard JDBC interfaces with new methods specific for each particular SQL server. Now each class known not only a standard interface but a server specific interface as well:\n\n<pre class=\"programlisting\">IZMySQLConnection = interface (IZConnection)\n  function Ping(...);\n  function Kill(..);\nend;\n\nTZMySQLConnection = class (TInterfacedObject, IZConnection, IZMySQLConnection);\n...\nend;</pre></p><p>The next step in porting JDBC to Object Pascal was an implementation of cached data access. Actually, many servers provide support for sequential data access only. Caching data on the client side is the important element to implement random data access for the retrieved result sets. On the other hand, many high-level database interfaces use even more sophisticated caching algorithms. So implementation of universal caching algorithms in one place can be a compact and efficient solution.</p><p>Cached DBC layer has only few classes:\n\n\t\t\t<div class=\"orderedlist\"><ol type=\"1\"><li><tt class=\"classname\">TZRowAccessor</tt> - organize storage and access to fields of one single cached record in result set (pattern Flyweight).</li><li><tt class=\"classname\">TZCachedResultSet</tt> - is a cached result set with random data access. It works on the top of another native non-cached result set with sequencial data access (pattern Decorator).</li><li><tt class=\"classname\">IZCachedResolver</tt> - is an interface to handle special logic to post modified data back to SQL server (pattern Delegator).</li></ol></div></p><p>The good thing about DBC interfaces that they are so generic, that additionally to regular SQL drivers it's easy to implement special adapters to other database interfaces such as Active Data Objects (ADO) for example.</p><p>DBC interfaces are generic, so providing support for additional databases or connectivity layers such as ADO is trivial.</p></div><div class=\"sect1\" lang=\"en\"><div class=\"titlepage\"><div><div><h2 class=\"title\" style=\"clear: both\"><a id=\"d4e92\"></a>4.&nbsp;Component Layer</h2></div></div></div><p>The last top layer in ZeosDBO library implements dbware components. These components are used for development in Delphi, C++ Builder or Kylix. Currently Borland compilers support several standards for dbware components:\n\n\t\t\t<div class=\"orderedlist\"><ol type=\"1\"><li><tt class=\"classname\">TDataset</tt> descendent components</li><li>DbExpress drivers</li><li>Data providers for multi-tier Midas technology</li></ol></div></p><p>At the time of this writing this article ZeosDBO library only supported TDataset descendent components. Implementation of other component types is scheduled for future versions.</p><p>The component class diagram is presented on picture 3:\n\n\t\t\t<div class=\"mediaobject\"><img src=\"images/Overview003.gif\"></div><div class=\"orderedlist\"><ol type=\"1\"><li><tt class=\"classname\">TZAbstractRODataset</tt>, <tt class=\"classname\">TZAbstractDataset</tt>, <tt class=\"classname\">TZAbstractStoredProc</tt> - abstract classes for <tt class=\"classname\">TDataset</tt> descendant components</li><li><tt class=\"classname\">TZReadOnlyQuery</tt>, <tt class=\"classname\">TZQuery</tt>, <tt class=\"classname\">TZStoredProc</tt> - universal <tt class=\"classname\">TDataset</tt> descendant components</li><li><tt class=\"classname\">TZReadOnlyXXSQLQuery</tt>, <tt class=\"classname\">TZXXSQLQuery</tt>, <tt class=\"classname\">TZXXSQLStoredProc</tt> - <tt class=\"classname\">TDatasets</tt> specific for each supported SQL server. The way how they are propagating server specific functions is described in the previous chapter about DBC Layer.</li><li><tt class=\"classname\">TZSQLMonitor</tt>, <tt class=\"classname\">TZUpdateSQL</tt>, <tt class=\"classname\">TZSQLProcessor</tt> - generic auxiliary components</li></ol></div></p><p><tt class=\"classname\">TDataset</tt> uses maximum the DBC layer functionality to read, modify and store data. Additionally it implements extra functions to filter, search and sort data, connect to visual components and many other things.</p></div><div class=\"sect1\" lang=\"en\"><div class=\"titlepage\"><div><div><h2 class=\"title\" style=\"clear: both\"><a id=\"d4e134\"></a>5.&nbsp;Epilog</h2></div></div></div><p>In this article we described the main ideas of the new architecture of Zeos Database Objects component library for native database access. This architecture was introduced in version 6.0 and demonstrated high flexibility and effectiveness. In version 6.1 the code was seriously revised and optimized, but the main principles of the architecture was not changed.</p><p>Functionality and flexibility incorporated in the architecture will meet adapt to new requirements in the future. Support for new SQL servers will be added as well as access to SQL specific functionality and support for other high level interfaces like dbExpress and Midas.</p><p>To familiarize with the library you may visit the project website at <a href=\"http://zeos.firmos.at\" target=\"_top\">http://zeos.firmos.at</a> or the development page on SourceForge at<a href=\"http://www.sourceforge.net/projects/zeoslib\" target=\"_top\">http://www.sourceforge.net/projects/zeoslib</a></p></div></div><div xmlns=\"\" id=\"customfooter\">\n(c) 1999 - 2006 The Zeos Development Group\n</div></body></html>"
  },
  {
    "path": "lib/zeosdbo/doc/html/parameters.html",
    "content": "\n<!DOCTYPE html\n  PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">\n<html xmlns=\"http://www.w3.org/1999/xhtml\"><head>\n      <meta http-equiv=\"Content-Type\" content=\"text/html; charset=iso-8859-1\">\n   <title>ZeosDBO SQL Specific Parameters</title><link rel=\"stylesheet\" href=\"ede.css\" type=\"text/css\"><meta name=\"generator\" content=\"DocBook XSL Stylesheets V1.66.0\"></head><body><div xmlns=\"\" id=\"customheader\"><a href=\"http://zeos.firmos.at/portal.php\" style=\"color: #fff; font-weight: bold;\">ZeosLib</a><b> - open source tools for your database solutions</b></div><div class=\"article\" lang=\"en\"><div class=\"titlepage\"><div><div><h1 class=\"title\"><a id=\"d4e1\"></a>ZeosDBO SQL Specific Parameters</h1></div><div><h3 class=\"corpauthor\">ZeosLib Development Group</h3></div><div><p class=\"pubdate\">05 November 2003 (Updated 29/5/2008)</p></div></div><hr></div><div class=\"toc\"><p><b>Table of Contents</b></p><dl><dt><span class=\"sect1\"><a href=\"#d4e6\">1. Project options</a></span></dt><dt><span class=\"sect1\"><a href=\"#d4e29\">2. Generic Parameters</a></span></dt><dt><span class=\"sect1\"><a href=\"#d4e43\">3. MySQL Driver Parameters</a></span></dt><dt><span class=\"sect1\"><a href=\"#d4e72\">4. PostgreSQL Driver Parameters</a></span></dt><dt><span class=\"sect1\"><a href=\"#d4e96\">5. MS SQL Driver Parameters</a></span></dt><dt><span class=\"sect1\"><a href=\"#d4e115\">6. Interbase Driver Parameters</a></span></dt><dt><span class=\"sect1\"><a href=\"#d4e137\">7. Oracle Driver Parameters</a></span></dt><dt><span class=\"sect1\"><a href=\"#d4e144\">8. SQLite Driver Parameters</a></span></dt></dl></div><div class=\"sect1\" lang=\"en\"><div class=\"titlepage\"><div><div><h2 class=\"title\" style=\"clear: both\"><a id=\"d4e6\"></a>1.&nbsp;Project options</h2></div></div></div><div class=\"toc\"><dl><dt><span class=\"sect2\"><a href=\"#d4e8\">1.1. Conditional Defines</a></span></dt></dl></div><div class=\"sect2\" lang=\"en\"><div class=\"titlepage\"><div><div><h3 class=\"title\"><a id=\"d4e8\"></a>1.1.&nbsp;Conditional Defines</h3></div></div></div><p>It is possible to avoid databasedrivers are compiled into your program executable if you're not planning to support the use of them. You can do this by commenting out the ENABLE_XXXX DEFINES in zeos.inc before compiling and installing zeoslib.</p><p>A more flexible way is to install zeoslib using the standard zeos.inc file and add some conditional DEFINE's to your project options. Supported values are:\n      <div class=\"itemizedlist\"><ul type=\"disc\"><li>ZEOS_DISABLE_MYSQL</li><li>ZEOS_DISABLE_ORACLE</li><li>ZEOS_DISABLE_SQLITE</li><li>ZEOS_DISABLE_ASA</li><li>ZEOS_DISABLE_INTERBASE</li><li>ZEOS_DISABLE_DBLIB</li><li>ZEOS_DISABLE_POSTGRESQL</li><li>ZEOS_DISABLE_ADO</li></ul></div>\n      To use this feature you must add the zeoslib source dir's to the search path of your project. So only the required features will be compiled in your project executable. (Make sure the zeoslib units are recompiled as well)\n      </p></div></div><div class=\"sect1\" lang=\"en\"><div class=\"titlepage\"><div><div><h2 class=\"title\" style=\"clear: both\"><a id=\"d4e29\"></a>2.&nbsp;Generic Parameters</h2></div></div></div><div class=\"toc\"><dl><dt><span class=\"sect2\"><a href=\"#d4e31\">2.1. Connection parameters</a></span></dt><dt><span class=\"sect2\"><a href=\"#d4e36\">2.2. ZQuery parameters</a></span></dt></dl></div><div class=\"sect2\" lang=\"en\"><div class=\"titlepage\"><div><div><h3 class=\"title\"><a id=\"d4e31\"></a>2.1.&nbsp;Connection parameters</h3></div></div></div><div class=\"itemizedlist\"><ul type=\"disc\"><li><p>defaults=[yes,no] - Calculate default values for NULL fields.</p></li></ul></div></div><div class=\"sect2\" lang=\"en\"><div class=\"titlepage\"><div><div><h3 class=\"title\"><a id=\"d4e36\"></a>2.2.&nbsp;ZQuery parameters</h3></div></div></div><div class=\"itemizedlist\"><ul type=\"disc\"><li><p>defaults=[yes,no] - Calculate default values for NULL fields.</p></li><li><p>ValidateUpdateCount=[true,false] - Check if automatically generated updates of ZUpdateSQL updates only affect 1 record.</p></li></ul></div></div></div><div class=\"sect1\" lang=\"en\"><div class=\"titlepage\"><div><div><h2 class=\"title\" style=\"clear: both\"><a id=\"d4e43\"></a>3.&nbsp;MySQL Driver Parameters</h2></div></div></div><div class=\"toc\"><dl><dt><span class=\"sect2\"><a href=\"#d4e45\">3.1. Connection parameters</a></span></dt><dt><span class=\"sect2\"><a href=\"#d4e67\">3.2. Statement parameters</a></span></dt></dl></div><div class=\"sect2\" lang=\"en\"><div class=\"titlepage\"><div><div><h3 class=\"title\"><a id=\"d4e45\"></a>3.1.&nbsp;Connection parameters</h3></div></div></div><div class=\"itemizedlist\"><ul type=\"disc\"><li><p>compress=[yes,no] - Turn on/off compression protocol</p></li><li><p>dbless=[yes,no] - Connect to the real database or not (dbless mode)</p></li><li><p>useresult=[yes,no] - Fetching rows using UseResult instead StoreResult.</p></li><li><p>timeout=&lt;seconds&gt; - Connection timeout in seconds.</p></li><li><p>codepage=&lt;client codepage&gt; - Sets a client codepage. It executes a SET CHARACTER SET &lt;client codepage&gt; statement righ after connect. Refer your MySQL server manual for details.</p></li><li><p>all mysql_real_connect clientflags are now supported using the names from the enum type below. (Eg. CLIENT_MULTI_STATEMENTS=TRUE) :\n         <pre class=\"programlisting\">\nTMYSQL_CLIENT_OPTIONS =\n( CLIENT_LONG_PASSWORD,\t{  = 1;\t  { new more secure passwords }\n  CLIENT_FOUND_ROWS ,\t{\t  = 2;\t  { Found instead of affected rows }\n  CLIENT_LONG_FLAG\t ,\t{ = 4;\t  { Get all column flags }\n  CLIENT_CONNECT_WITH_DB ,\t{ = 8;\t  { One can specify db on connect }\n  CLIENT_NO_SCHEMA\t ,\t{  = 16;\t  { Don't allow database.table.column }\n  CLIENT_COMPRESS\t ,\t{  = 32;\t  { Can use compression protcol }\n  CLIENT_ODBC\t\t ,\t{  = 64;\t  { Odbc client }\n  CLIENT_LOCAL_FILES\t  ,\t{ = 128;  { Can use LOAD DATA LOCAL }\n  CLIENT_IGNORE_SPACE\t ,\t{  = 256;  { Ignore spaces before '(' }\n  CLIENT_CHANGE_USER    ,\t{  = 512;  { Support the mysql_change_user() }\n  CLIENT_INTERACTIVE    ,\t{  = 1024; { This is an interactive client }\n  CLIENT_SSL     ,\t{         = 2048; { Switch to SSL after handshake }\n  CLIENT_IGNORE_SIGPIPE  ,\t{ = 4096; { IGNORE sigpipes }\n  CLIENT_TRANSACTIONS    ,\t{ = 8196; { Client knows about transactions }\n  CLIENT_RESERVED     ,\t{    = 16384; { Old flag for 4.1 protocol  }\n  CLIENT_SECURE_CONNECTION  ,\t{= 32768; { New 4.1 authentication }\n  CLIENT_MULTI_STATEMENTS  ,\t{= 65536; { Enable/disable multi-stmt support }\n  CLIENT_MULTI_RESULTS  ,\t{  = 131072; { Enable/disable multi-results }\n  CLIENT_OPT_18,  {2^18 = 262144}\n  CLIENT_OPT_19,{2^19 = 524288}\n  CLIENT_OPT_20,  {2^20 = 1048576}\n  CLIENT_OPT_21,   {2^21 = 2097152 }\n  CLIENT_OPT_22,  {2^22 = 4194304}\n  CLIENT_OPT_23,  {2^23 = 8388608 }\n  CLIENT_OPT_24,   {2^24 = 16777216 }\n  CLIENT_OPT_25,   {2^25 = 33554432}\n  CLIENT_OPT_26,    {2^26 = 67108864}\n  CLIENT_OPT_27,    {2^27 = 134217728}\n  CLIENT_OPT_28,    {2^28 = 268435456}\n  CLIENT_OPT_29,    {2^29 = 536870912}\n  CLIENT_OPT_30,    {2^30 = 1073741824}\n  CLIENT_REMEMBER_OPTIONS\t{ = 2147483648; {Enable/disable multi-results });\n          </pre>\n</p></li><li><p>all mysql_options are now supported using the names from the enum type below. (Eg. MYSQL_READ_DEFAULT_FILE=&lt;filename&gt;) :\n         <pre class=\"programlisting\">\n  TMySqlOption = (\n    MYSQL_OPT_CONNECT_TIMEOUT,\n    MYSQL_OPT_COMPRESS,\n    MYSQL_OPT_NAMED_PIPE,\n    MYSQL_INIT_COMMAND,\n    MYSQL_READ_DEFAULT_FILE,\n    MYSQL_READ_DEFAULT_GROUP,\n    MYSQL_SET_CHARSET_DIR,\n    MYSQL_SET_CHARSET_NAME,\n    MYSQL_OPT_LOCAL_INFILE,\n    MYSQL_OPT_PROTOCOL,\n    MYSQL_SHARED_MEMORY_BASE_NAME,\n    MYSQL_OPT_READ_TIMEOUT,\n    MYSQL_OPT_WRITE_TIMEOUT,\n    MYSQL_OPT_USE_RESULT,\n    MYSQL_OPT_USE_REMOTE_CONNECTION,\n    MYSQL_OPT_USE_EMBEDDED_CONNECTION,\n    MYSQL_OPT_GUESS_CONNECTION,\n    MYSQL_SET_CLIENT_IP,\n    MYSQL_SECURE_AUTH\n  );\n          </pre>\n</p></li><li><p>SSL connections are supported using this connection properties (using mysql_sll_set library call) :\n         <pre class=\"programlisting\">\n    Properties.Strings = (\n      'MYSQL_SSL=TRUE'\n      'MYSQL_SSL_CA=D:/mysql/certs/ca-cert.pem'\n      'MYSQL_SSL_CERT=D:/mysql/certs/client-cert.pem'\n      'MYSQL_SSL_KEY=D:/mysql/certs/client-key.pem')\n          </pre>\n</p></li></ul></div></div><div class=\"sect2\" lang=\"en\"><div class=\"titlepage\"><div><div><h3 class=\"title\"><a id=\"d4e67\"></a>3.2.&nbsp;Statement parameters</h3></div></div></div><div class=\"itemizedlist\"><ul type=\"disc\"><li><p>useresult=[yes,no] - Fetching rows using UseResult instead StoreResult.</p></li></ul></div></div></div><div class=\"sect1\" lang=\"en\"><div class=\"titlepage\"><div><div><h2 class=\"title\" style=\"clear: both\"><a id=\"d4e72\"></a>4.&nbsp;PostgreSQL Driver Parameters</h2></div></div></div><div class=\"toc\"><dl><dt><span class=\"sect2\"><a href=\"#d4e74\">4.1. Connection parameters</a></span></dt><dt><span class=\"sect2\"><a href=\"#d4e91\">4.2. Statement parameters</a></span></dt></dl></div><div class=\"sect2\" lang=\"en\"><div class=\"titlepage\"><div><div><h3 class=\"title\"><a id=\"d4e74\"></a>4.1.&nbsp;Connection parameters</h3></div></div></div><div class=\"itemizedlist\"><ul type=\"disc\"><li><p>beginreq=[yes,no] - Is BEGIN required at the transaction start or not.</p></li><li><p>oidasblob=[yes,no] - Is Oid type treated as Large Object handle (blob) or as a regular integer.</p></li><li><p>timeout=&lt;seconds&gt; - Connection timeout in seconds.</p></li><li><p>codepage=&lt;client codepage&gt; - Sets a client codepage. It executes a SET CLIENT_ENCODING '&lt;client codepage&gt;' statement righ after connect.</p></li><li><p>sslmode=[disable, allow, prefer, require] - (From PostgreSQL docs:) This option determines whether or with what priority an SSL connection will be negotiated with the server. There are four modes: disable will attempt only an unencrypted SSL connection; allow will negotiate, trying first a non-SSL connection, then if that fails, trying an SSL connection; prefer (the default) will negotiate, trying first an SSL connection, then if that fails, trying a regular non-SSL connection; require will try only an SSL connection.\nIf PostgreSQL is compiled without SSL support, using option require will cause an error, while options allow and prefer will be accepted but libpq will not in fact attempt an SSL connection.</p></li><li><p>requiressl=[0,1] - This option is deprecated in favor of the sslmode setting.</p></li><li><p>application_name=&lt;application name&gt; - (From PostgreSQL docs:) This option is typically set by an application upon connection to the server. The name will be displayed in the pg_stat_activity view and included in CSV log entries.</p></li></ul></div></div><div class=\"sect2\" lang=\"en\"><div class=\"titlepage\"><div><div><h3 class=\"title\"><a id=\"d4e91\"></a>4.2.&nbsp;Statement parameters</h3></div></div></div><div class=\"itemizedlist\"><ul type=\"disc\"><li><p>oidasblob=[yes,no] - Is Oid type treated as Large Object handle (blob) or as a regular integer.</p></li></ul></div></div></div><div class=\"sect1\" lang=\"en\"><div class=\"titlepage\"><div><div><h2 class=\"title\" style=\"clear: both\"><a id=\"d4e96\"></a>5.&nbsp;MS SQL Driver Parameters</h2></div></div></div><div class=\"toc\"><dl><dt><span class=\"sect2\"><a href=\"#d4e98\">5.1. Connection parameters</a></span></dt></dl></div><div class=\"sect2\" lang=\"en\"><div class=\"titlepage\"><div><div><h3 class=\"title\"><a id=\"d4e98\"></a>5.1.&nbsp;Connection parameters</h3></div></div></div><div class=\"itemizedlist\"><ul type=\"disc\"><li><p>appname=&lt;application name&gt; - The given application name is sent to sqlserver.</p></li><li><p>workstation=&lt;workstation name&gt; - The given workstation name is sent to sqlserver</p></li><li><p>secure=[yes,no] - This means that SQL Server will use Windows Authentication security.</p></li><li><p>trusted=[yes,no] - This means that SQL Server will use Windows Authentication security.</p></li><li><p>language=&lt;national language name&gt; - The given language is sent to sqlserver. If language support is installed in the server, error messages are returned in the designated national language.</p></li><li><p>fallback=[yes,no] - Enables or disables failover support</p></li><li><p>timeout=&lt;seconds&gt; - Is the time-out value, or the number of seconds that DB-Library waits for a login response before timing out. A time-out value of 0 represents an infinite time-out period. The default time-out value is 60 seconds.</p></li></ul></div></div></div><div class=\"sect1\" lang=\"en\"><div class=\"titlepage\"><div><div><h2 class=\"title\" style=\"clear: both\"><a id=\"d4e115\"></a>6.&nbsp;Interbase Driver Parameters</h2></div></div></div><div class=\"toc\"><dl><dt><span class=\"sect2\"><a href=\"#d4e117\">6.1. Connection parameters</a></span></dt><dt><span class=\"sect2\"><a href=\"#d4e130\">6.2. Statement parameters</a></span></dt></dl></div><div class=\"sect2\" lang=\"en\"><div class=\"titlepage\"><div><div><h3 class=\"title\"><a id=\"d4e117\"></a>6.1.&nbsp;Connection parameters</h3></div></div></div><div class=\"itemizedlist\"><ul type=\"disc\"><li><p>codepage=&lt;national language name&gt; - The given language is sent to sqlserver. If language support is installed in the server, error messages are returned in the designated national language.</p></li><li><p>createNewDatabase=&lt;sql command database creation&gt; - Created new database before open database defined in TZConnection.</p></li><li><p>dialect=it is parameter of Interbase/Firebird sql dialect. dialect parameter is sinonim of isc_dpb_sql_dialect parameter.</p></li><li><p>RoleName=it is sinonim for isc_dpb_sql_role_name parameter Interbase/Firebird. It allow set user role name to work with database and to gain the privileges of that role.</p></li><li><p>hard_commit=[yes,no] - Use hard commits instead of soft commits.</p></li></ul></div></div><div class=\"sect2\" lang=\"en\"><div class=\"titlepage\"><div><div><h3 class=\"title\"><a id=\"d4e130\"></a>6.2.&nbsp;Statement parameters</h3></div></div></div><div class=\"itemizedlist\"><ul type=\"disc\"><li><p>cursor=&lt;cursor name&gt; - The given cusor name is sent to sql server.</p></li><li><p>cashedblob=[yes,no] - This means that blob data fetch immediate if [yes] or used interbase blob if [no].</p></li></ul></div></div></div><div class=\"sect1\" lang=\"en\"><div class=\"titlepage\"><div><div><h2 class=\"title\" style=\"clear: both\"><a id=\"d4e137\"></a>7.&nbsp;Oracle Driver Parameters</h2></div></div></div><div class=\"toc\"><dl><dt><span class=\"sect2\"><a href=\"#d4e139\">7.1. Connection parameters</a></span></dt></dl></div><div class=\"sect2\" lang=\"en\"><div class=\"titlepage\"><div><div><h3 class=\"title\"><a id=\"d4e139\"></a>7.1.&nbsp;Connection parameters</h3></div></div></div><div class=\"itemizedlist\"><ul type=\"disc\"><li><p>codepage=[utf8,UTF8,0..max word value] - The codepage used by the oracle OCI to interprete strings sent to the server. For Lazarus this should be set to UTF8.</p></li></ul></div></div></div><div class=\"sect1\" lang=\"en\"><div class=\"titlepage\"><div><div><h2 class=\"title\" style=\"clear: both\"><a id=\"d4e144\"></a>8.&nbsp;SQLite Driver Parameters</h2></div></div></div><div class=\"toc\"><dl><dt><span class=\"sect2\"><a href=\"#d4e146\">8.1. Connection parameters</a></span></dt></dl></div><div class=\"sect2\" lang=\"en\"><div class=\"titlepage\"><div><div><h3 class=\"title\"><a id=\"d4e146\"></a>8.1.&nbsp;Connection parameters</h3></div></div></div><div class=\"itemizedlist\"><ul type=\"disc\"><li><p>busytimeout=&lt;milliseconds&gt; - Timeout before throwing an error because the database to be opened is locked</p></li></ul></div></div></div></div><div xmlns=\"\" id=\"customfooter\">\n(c) 1999 - 2006 The Zeos Development Group\n</div></body></html>"
  },
  {
    "path": "lib/zeosdbo/doc/html/readme.html",
    "content": "\n<!DOCTYPE html\n  PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">\n<html xmlns=\"http://www.w3.org/1999/xhtml\"><head>\n      <meta http-equiv=\"Content-Type\" content=\"text/html; charset=iso-8859-1\">\n   <title>ZeosDBO Technical Info</title><link rel=\"stylesheet\" href=\"ede.css\" type=\"text/css\"><meta name=\"generator\" content=\"DocBook XSL Stylesheets V1.66.0\"></head><body><div xmlns=\"\" id=\"customheader\"><a href=\"http://zeos.firmos.at/portal.php\" style=\"color: #fff; font-weight: bold;\">ZeosLib</a><b> - open source tools for your database solutions</b></div><div class=\"article\" lang=\"en\"><div class=\"titlepage\"><div><div><h1 class=\"title\"><a id=\"d4e1\"></a>ZeosDBO Technical Info</h1></div><div><h3 class=\"corpauthor\">ZeosLib Development Group</h3></div><div><p class=\"pubdate\">09 July 2004 (Updated 29/5/2008)</p></div></div><hr></div><p>ZeosDBO is a database middleware components for Borland development tools, including Delphi, C++ Builder and Kylix.</p><p>The following compilers are supported:</p><div class=\"itemizedlist\"><ul type=\"disc\" compact><li>Delphi 5 - 7 and 9-11</li><li>Lazarus (FreePascal)</li><li>MSEide+MSEgui (FreePascal)</li><li>C++ Builder 5 - 6</li><li>Kylix 2 - 3</li></ul></div><p>ZeosDBO supports direct connectivity to the following databases using the vendor provided, native interface:</p><div class=\"itemizedlist\"><ul type=\"disc\" compact><li>MySQL 3.20 - 5.0</li><li>PostgreSQL 6.5 - 8.1</li><li>Firebird 1.0 - 2.0</li><li>Interbase 5.0 - 7.5</li><li>Microsoft SQL Server 7, 2000</li><li>Sybase ASE 12.0, 12.5</li><li>Oracle 9i</li><li>SQLite 2.8, 3.5</li></ul></div><p>For other databases we propose to use implemented Active Data Objects (ADO) Bridge.</p><p>Advantages of using ZeosDBO:</p><div class=\"itemizedlist\"><ul type=\"disc\" compact><li>Platform independance. The ZeosDBO is highly generic. Applications written in ZeosDBO can be migrated across databases without major changes.</li><li>ZeosDBO is open source, written for usability and extensibility.</li><li>ZeosDBO leverages the amazing power of the Delphi development environment without relying on a performance killing middleware.</li><li>ZeosDBO is an extremely thin abstraction layer, unlike 'thick' layered protocols like ADO and BDE.</li></ul></div><p>Package contents:</p><div class=\"orderedlist\"><ol type=\"1\" compact><li><tt class=\"classname\">ZCore</tt> - Core classes and interfaces. Contains Java style objects and collections as well as compatibility types and functions.</li><li><tt class=\"classname\">ZParseSql</tt> - SQL specific for syntax and lexical analysis.</li><li><tt class=\"classname\">ZPlain</tt> - Native plain API to supported SQL servers.</li><li><tt class=\"classname\">ZDbc</tt> - Port of Java Database Connectivity API (JDBC 2.0). DBC API acts as intermediate layer between Plain API and highlevel <tt class=\"classname\">TDataset</tt> or <tt class=\"classname\">DBExpress</tt> components</li><li><tt class=\"classname\">ZComponent</tt> - visual components descended from <tt class=\"classname\">TDataset</tt>.</li><li><tt class=\"classname\">ZComponentDesign</tt> - design time components. This package is not available for all compilers. If present it's only needed to install the components in the IDE.</li></ol></div><p>Installed components:</p><div class=\"orderedlist\"><ol type=\"1\" compact><li><tt class=\"classname\">TZConnection</tt>: This component encapsulates the database connection and transaction management.</li><li><tt class=\"classname\">TZReadOnlyQuery</tt>: TDataset component to execute SQL queries and process data in read-only mode.</li><li><tt class=\"classname\">TZQuery</tt>: TDataset component which allows data modifications in regular and cached mode.</li><li><tt class=\"classname\">TZUpdateSQL</tt>: Analog of standard TUpdateSQL component to explicite definition of Insert/Update/Delete SQL statements for TDataset modifications.</li><li><tt class=\"classname\">TZStoredProc</tt>: The component to execute SQL stored procedures.</li><li><tt class=\"classname\">TZSQLProcessor</tt>: The component to execute SQL scripts for different SQL and various delimiter types.</li><li><tt class=\"classname\">TZSQLMonitor</tt>: The component to monitor all outgoing SQL queries and other logging information.</li><li><tt class=\"classname\">TZSQLMetadata</tt>: Specialized TDataset component which provides an access to database metadata such as tables, columns, indices, etc.</li></ol></div><p>The project home page is here (for news, links and other project info): <a href=\"http://zeosfirmos.at/portal.php\" target=\"_top\">http://zeos.firmos.at</a></p><p>The sourceforge development site is located here (for technical resources and anonymous web based cvs access):<a href=\"http://www.sourceforge.net/projects/zeoslib\" target=\"_top\"> http://www.sourceforge.net/projects/zeoslib</a></p><p>Thank you for using our software,</p><p>The ZeosLib Development Group</p></div><div xmlns=\"\" id=\"customfooter\">\n(c) 1999 - 2006 The Zeos Development Group\n</div></body></html>"
  },
  {
    "path": "lib/zeosdbo/packages/DelphiXE/ZComponent.dpk",
    "content": "package ZComponent;\n{$R *.res}\n{$ALIGN 8}\n{$ASSERTIONS ON}\n{$BOOLEVAL OFF}\n{$DEBUGINFO ON}\n{$EXTENDEDSYNTAX ON}\n{$IMPORTEDDATA ON}\n{$IOCHECKS ON}\n{$LOCALSYMBOLS ON}\n{$LONGSTRINGS ON}\n{$OPENSTRINGS ON}\n{$OPTIMIZATION ON}\n{$OVERFLOWCHECKS ON}\n{$RANGECHECKS OFF}\n{$REFERENCEINFO ON}\n{$SAFEDIVIDE OFF}\n{$STACKFRAMES ON}\n{$TYPEDADDRESS OFF}\n{$VARSTRINGCHECKS ON}\n{$WRITEABLECONST OFF}\n{$MINENUMSIZE 1}\n{$IMAGEBASE $400000}\n{$DESCRIPTION 'Zeos Database Components'}\n{$LIBSUFFIX '150'}\n{$RUNONLY}\n{$IMPLICITBUILD OFF}\n{$I ZPackages.inc}\n\nrequires\n  rtl,\n  dbrtl,\n  ZPlain,\n  ZDbc,\n  ZCore,\n  ZParseSql,\n  vclactnband,\n  vcl;\n\ncontains\n  ZSqlUpdate in '..\\..\\src\\component\\ZSqlUpdate.pas',\n  ZAbstractDataset in '..\\..\\src\\component\\ZAbstractDataset.pas',\n  ZAbstractRODataset in '..\\..\\src\\component\\ZAbstractRODataset.pas',\n  ZStreamBlob in '..\\..\\src\\component\\ZStreamBlob.pas',\n  ZAbstractConnection in '..\\..\\src\\component\\ZAbstractConnection.pas',\n  ZGroupedConnection in '..\\..\\src\\component\\ZGroupedConnection.pas',\n  ZConnectionGroup in '..\\..\\src\\component\\ZConnectionGroup.pas',\n  ZConnection in '..\\..\\src\\component\\ZConnection.pas',\n  ZDataset in '..\\..\\src\\component\\ZDataset.pas',\n  ZDatasetUtils in '..\\..\\src\\component\\ZDatasetUtils.pas',\n  ZSqlStrings in '..\\..\\src\\component\\ZSqlStrings.pas',\n  ZSqlProcessor in '..\\..\\src\\component\\ZSqlProcessor.pas',\n  ZSqlMonitor in '..\\..\\src\\component\\ZSqlMonitor.pas',\n  ZStoredProcedure in '..\\..\\src\\component\\ZStoredProcedure.pas',\n  ZAbstractTable in '..\\..\\src\\component\\ZAbstractTable.pas',\n  ZSqlMetadata in '..\\..\\src\\component\\ZSqlMetadata.pas',\n  ZSequence in '..\\..\\src\\component\\ZSequence.pas'\n  {$IFDEF ENABLE_INTERBASE}, ZIBEventAlerter in '..\\..\\src\\component\\ZIBEventAlerter.pas' {$ENDIF}\n  {$IFDEF ENABLE_POSTGRESQL}, ZPgEventAlerter in '..\\..\\src\\component\\ZPgEventAlerter.pas' {$ENDIF};\n\nend.\n"
  },
  {
    "path": "lib/zeosdbo/packages/DelphiXE/ZComponent.dproj",
    "content": "﻿\t<Project xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n\t\t<PropertyGroup>\n\t\t\t<ProjectGuid>{242b1e2c-c412-44f0-8a86-cf22da726ef0}</ProjectGuid>\n\t\t\t<MainSource>ZComponent.dpk</MainSource>\n\t\t\t<Configuration Condition=\" '$(Configuration)' == '' \">Debug</Configuration>\n\t\t\t<DCC_DCCCompiler>DCC32</DCC_DCCCompiler>\n\t\t\t<DCC_DependencyCheckOutputName>C:\\Documents and Settings\\All Users\\Documentos\\RAD Studio\\5.0\\Bpl\\ZComponent110.bpl</DCC_DependencyCheckOutputName>\n\t\t\t<ProjectVersion>12.3</ProjectVersion>\n\t\t\t<Config Condition=\"'$(Config)'==''\">Debug</Config>\n\t\t\t<Base>True</Base>\n\t\t\t<Platform>Win32</Platform>\n\t\t\t<AppType>Package</AppType>\n\t\t\t<FrameworkType>VCL</FrameworkType>\n\t\t</PropertyGroup>\n\t\t<PropertyGroup Condition=\"'$(Config)'=='Base' or '$(Base)'!=''\">\n\t\t\t<Base>true</Base>\n\t\t</PropertyGroup>\n\t\t<PropertyGroup Condition=\"'$(Config)'=='Release' or '$(Cfg_1)'!=''\">\n\t\t\t<Cfg_1>true</Cfg_1>\n\t\t\t<CfgParent>Base</CfgParent>\n\t\t\t<Base>true</Base>\n\t\t</PropertyGroup>\n\t\t<PropertyGroup Condition=\"'$(Config)'=='Debug' or '$(Cfg_2)'!=''\">\n\t\t\t<Cfg_2>true</Cfg_2>\n\t\t\t<CfgParent>Base</CfgParent>\n\t\t\t<Base>true</Base>\n\t\t</PropertyGroup>\n\t\t<PropertyGroup Condition=\"'$(Base)'!=''\">\n\t\t\t<DCC_UnitAlias>WinTypes=Windows;WinProcs=Windows;DbiTypes=BDE;DbiProcs=BDE;DbiErrs=BDE;$(DCC_UnitAlias)</DCC_UnitAlias>\n\t\t\t<DCC_UnitSearchPath>build;$(DCC_UnitSearchPath)</DCC_UnitSearchPath>\n\t\t\t<DCC_DcuOutput>build</DCC_DcuOutput>\n\t\t\t<DCC_BplOutput>$(BDSCOMMONDIR)\\Bpl</DCC_BplOutput>\n\t\t\t<DCC_DcpOutput>$(BDSCOMMONDIR)\\Dcp</DCC_DcpOutput>\n\t\t\t<DCC_ImageBase>00400000</DCC_ImageBase>\n\t\t\t<DllSuffix>150</DllSuffix>\n\t\t\t<DCC_Description>Zeos Database Components</DCC_Description>\n\t\t\t<RuntimeOnlyPackage>true</RuntimeOnlyPackage>\n\t\t\t<DCC_DependencyCheckOutputName>build\\ZComponent150.bpl</DCC_DependencyCheckOutputName>\n\t\t\t<DCC_IntegerOverflowCheck>true</DCC_IntegerOverflowCheck>\n\t\t\t<DCC_OutputNeverBuildDcps>true</DCC_OutputNeverBuildDcps>\n\t\t\t<GenDll>true</GenDll>\n\t\t\t<DCC_GenerateStackFrames>true</DCC_GenerateStackFrames>\n\t\t\t<GenPackage>true</GenPackage>\n\t\t</PropertyGroup>\n\t\t<PropertyGroup Condition=\"'$(Cfg_1)'!=''\">\n\t\t\t<Version>7.0</Version>\n\t\t\t<DCC_DebugInformation>False</DCC_DebugInformation>\n\t\t\t<DCC_LocalDebugSymbols>False</DCC_LocalDebugSymbols>\n\t\t\t<DCC_IntegerOverflowCheck>True</DCC_IntegerOverflowCheck>\n\t\t\t<DCC_GenerateStackFrames>True</DCC_GenerateStackFrames>\n\t\t\t<DCC_SymbolReferenceInfo>0</DCC_SymbolReferenceInfo>\n\t\t\t<DCC_ObjOutput>build</DCC_ObjOutput>\n\t\t\t<DCC_HppOutput>build</DCC_HppOutput>\n\t\t\t<DCC_Define>RELEASE;$(DCC_Define)</DCC_Define>\n\t\t\t<DCC_ResourcePath>$(BDSCOMMONDIR)\\Bpl;$(DCC_ResourcePath)</DCC_ResourcePath>\n\t\t\t<DCC_ObjPath>$(BDSCOMMONDIR)\\Bpl;$(DCC_ObjPath)</DCC_ObjPath>\n\t\t\t<DCC_IncludePath>$(BDSCOMMONDIR)\\Bpl;$(DCC_IncludePath)</DCC_IncludePath>\n\t\t</PropertyGroup>\n\t\t<PropertyGroup Condition=\"'$(Cfg_2)'!=''\">\n\t\t\t<DCC_Define>DEBUG;$(DCC_Define)</DCC_Define>\n\t\t\t<Version>7.0</Version>\n\t\t\t<DCC_IntegerOverflowCheck>True</DCC_IntegerOverflowCheck>\n\t\t\t<DCC_GenerateStackFrames>True</DCC_GenerateStackFrames>\n\t\t\t<DCC_ObjOutput>build</DCC_ObjOutput>\n\t\t\t<DCC_HppOutput>build</DCC_HppOutput>\n\t\t\t<DCC_ResourcePath>$(BDSCOMMONDIR)\\Bpl;$(DCC_ResourcePath)</DCC_ResourcePath>\n\t\t\t<DCC_ObjPath>$(BDSCOMMONDIR)\\Bpl;$(DCC_ObjPath)</DCC_ObjPath>\n\t\t\t<DCC_IncludePath>$(BDSCOMMONDIR)\\Bpl;$(DCC_IncludePath)</DCC_IncludePath>\n\t\t</PropertyGroup>\n\t\t<ItemGroup>\n\t\t\t<DelphiCompile Include=\"ZComponent.dpk\">\n\t\t\t\t<MainSource>MainSource</MainSource>\n\t\t\t</DelphiCompile>\n\t\t\t<DCCReference Include=\"rtl.dcp\"/>\n\t\t\t<DCCReference Include=\"dbrtl.dcp\"/>\n\t\t\t<DCCReference Include=\"ZPlain.dcp\"/>\n\t\t\t<DCCReference Include=\"ZDbc.dcp\"/>\n\t\t\t<DCCReference Include=\"ZCore.dcp\"/>\n\t\t\t<DCCReference Include=\"ZParseSql.dcp\"/>\n\t\t\t<DCCReference Include=\"vclactnband.dcp\"/>\n\t\t\t<DCCReference Include=\"vcl.dcp\"/>\n\t\t\t<DCCReference Include=\"..\\..\\src\\component\\ZSqlUpdate.pas\"/>\n\t\t\t<DCCReference Include=\"..\\..\\src\\component\\ZAbstractDataset.pas\"/>\n\t\t\t<DCCReference Include=\"..\\..\\src\\component\\ZAbstractRODataset.pas\"/>\n\t\t\t<DCCReference Include=\"..\\..\\src\\component\\ZStreamBlob.pas\"/>\n\t\t\t<DCCReference Include=\"..\\..\\src\\component\\ZAbstractConnection.pas\"/>\n\t\t\t<DCCReference Include=\"..\\..\\src\\component\\ZGroupedConnection.pas\"/>\n\t\t\t<DCCReference Include=\"..\\..\\src\\component\\ZConnectionGroup.pas\"/>\n\t\t\t<DCCReference Include=\"..\\..\\src\\component\\ZConnection.pas\"/>\n\t\t\t<DCCReference Include=\"..\\..\\src\\component\\ZDataset.pas\"/>\n\t\t\t<DCCReference Include=\"..\\..\\src\\component\\ZDatasetUtils.pas\"/>\n\t\t\t<DCCReference Include=\"..\\..\\src\\component\\ZSqlStrings.pas\"/>\n\t\t\t<DCCReference Include=\"..\\..\\src\\component\\ZSqlProcessor.pas\"/>\n\t\t\t<DCCReference Include=\"..\\..\\src\\component\\ZSqlMonitor.pas\"/>\n\t\t\t<DCCReference Include=\"..\\..\\src\\component\\ZStoredProcedure.pas\"/>\n\t\t\t<DCCReference Include=\"..\\..\\src\\component\\ZAbstractTable.pas\"/>\n\t\t\t<DCCReference Include=\"..\\..\\src\\component\\ZSqlMetadata.pas\"/>\n\t\t\t<DCCReference Include=\"..\\..\\src\\component\\ZSequence.pas\">\n\t\t\t\t<Form>$ENDIF</Form>\n\t\t\t</DCCReference>\n\t\t\t<BuildConfiguration Include=\"Debug\">\n\t\t\t\t<Key>Cfg_2</Key>\n\t\t\t\t<CfgParent>Base</CfgParent>\n\t\t\t</BuildConfiguration>\n\t\t\t<BuildConfiguration Include=\"Base\">\n\t\t\t\t<Key>Base</Key>\n\t\t\t</BuildConfiguration>\n\t\t\t<BuildConfiguration Include=\"Release\">\n\t\t\t\t<Key>Cfg_1</Key>\n\t\t\t\t<CfgParent>Base</CfgParent>\n\t\t\t</BuildConfiguration>\n\t\t</ItemGroup>\n\t\t<Import Condition=\"Exists('$(BDS)\\Bin\\CodeGear.Delphi.Targets')\" Project=\"$(BDS)\\Bin\\CodeGear.Delphi.Targets\"/>\n\t\t<Import Condition=\"Exists('$(APPDATA)\\Embarcadero\\$(BDSAPPDATABASEDIR)\\$(PRODUCTVERSION)\\UserTools.proj')\" Project=\"$(APPDATA)\\Embarcadero\\$(BDSAPPDATABASEDIR)\\$(PRODUCTVERSION)\\UserTools.proj\"/>\n\t\t<ProjectExtensions>\n\t\t\t<Borland.Personality>Delphi.Personality.12</Borland.Personality>\n\t\t\t<Borland.ProjectType>Package</Borland.ProjectType>\n\t\t\t<BorlandProject>\n\t\t\t\t<Delphi.Personality>\n\t\t\t\t\t<Parameters/>\n\t\t\t\t\t<VersionInfo>\n\t\t\t\t\t\t<VersionInfo Name=\"IncludeVerInfo\">True</VersionInfo>\n\t\t\t\t\t\t<VersionInfo Name=\"AutoIncBuild\">False</VersionInfo>\n\t\t\t\t\t\t<VersionInfo Name=\"MajorVer\">1</VersionInfo>\n\t\t\t\t\t\t<VersionInfo Name=\"MinorVer\">0</VersionInfo>\n\t\t\t\t\t\t<VersionInfo Name=\"Release\">0</VersionInfo>\n\t\t\t\t\t\t<VersionInfo Name=\"Build\">0</VersionInfo>\n\t\t\t\t\t\t<VersionInfo Name=\"Debug\">False</VersionInfo>\n\t\t\t\t\t\t<VersionInfo Name=\"PreRelease\">False</VersionInfo>\n\t\t\t\t\t\t<VersionInfo Name=\"Special\">False</VersionInfo>\n\t\t\t\t\t\t<VersionInfo Name=\"Private\">False</VersionInfo>\n\t\t\t\t\t\t<VersionInfo Name=\"DLL\">False</VersionInfo>\n\t\t\t\t\t\t<VersionInfo Name=\"Locale\">1031</VersionInfo>\n\t\t\t\t\t\t<VersionInfo Name=\"CodePage\">1252</VersionInfo>\n\t\t\t\t\t</VersionInfo>\n\t\t\t\t\t<VersionInfoKeys>\n\t\t\t\t\t\t<VersionInfoKeys Name=\"CompanyName\"/>\n\t\t\t\t\t\t<VersionInfoKeys Name=\"FileDescription\"/>\n\t\t\t\t\t\t<VersionInfoKeys Name=\"FileVersion\">1.0.0.0</VersionInfoKeys>\n\t\t\t\t\t\t<VersionInfoKeys Name=\"InternalName\"/>\n\t\t\t\t\t\t<VersionInfoKeys Name=\"LegalCopyright\"/>\n\t\t\t\t\t\t<VersionInfoKeys Name=\"LegalTrademarks\"/>\n\t\t\t\t\t\t<VersionInfoKeys Name=\"OriginalFilename\"/>\n\t\t\t\t\t\t<VersionInfoKeys Name=\"ProductName\"/>\n\t\t\t\t\t\t<VersionInfoKeys Name=\"ProductVersion\">1.0.0.0</VersionInfoKeys>\n\t\t\t\t\t\t<VersionInfoKeys Name=\"Comments\"/>\n\t\t\t\t\t</VersionInfoKeys>\n\t\t\t\t\t<Source>\n\t\t\t\t\t\t<Source Name=\"MainSource\">ZComponent.dpk</Source>\n\t\t\t\t\t</Source>\n\t\t\t\t</Delphi.Personality>\n\t\t\t\t<Platforms>\n\t\t\t\t\t<Platform value=\"Win32\">True</Platform>\n\t\t\t\t</Platforms>\n\t\t\t</BorlandProject>\n\t\t\t<ProjectFileVersion>12</ProjectFileVersion>\n\t\t</ProjectExtensions>\n\t</Project>\n"
  },
  {
    "path": "lib/zeosdbo/packages/DelphiXE/ZComponentDesign.dpk",
    "content": "package ZComponentDesign;\n\n{$R *.res}\n{$R '..\\..\\src\\component\\ZComponent.dcr'}\n{$ALIGN 8}\n{$ASSERTIONS ON}\n{$BOOLEVAL OFF}\n{$DEBUGINFO ON}\n{$EXTENDEDSYNTAX ON}\n{$IMPORTEDDATA ON}\n{$IOCHECKS ON}\n{$LOCALSYMBOLS ON}\n{$LONGSTRINGS ON}\n{$OPENSTRINGS ON}\n{$OPTIMIZATION ON}\n{$OVERFLOWCHECKS ON}\n{$RANGECHECKS OFF}\n{$REFERENCEINFO ON}\n{$SAFEDIVIDE OFF}\n{$STACKFRAMES ON}\n{$TYPEDADDRESS OFF}\n{$VARSTRINGCHECKS ON}\n{$WRITEABLECONST OFF}\n{$MINENUMSIZE 1}\n{$IMAGEBASE $400000}\n{$DESCRIPTION 'Zeos Database Components'}\n{$LIBSUFFIX '150'}\n{$DESIGNONLY}\n{$IMPLICITBUILD OFF}\n\nrequires\n  dbrtl,\n  designide,\n  ZParseSql,\n  ZCore,\n  ZPlain,\n  ZDbc,\n  ZComponent;\n\ncontains\n  ZPropertyEditor in '..\\..\\src\\component\\ZPropertyEditor.pas',\n  ZUpdateSqlEditor in '..\\..\\src\\component\\ZUpdateSqlEditor.pas' {ZUpdateSQLEditForm},\n  ZComponentReg in '..\\..\\src\\component\\ZComponentReg.pas';\n\nend.\n"
  },
  {
    "path": "lib/zeosdbo/packages/DelphiXE/ZComponentDesign.dproj",
    "content": "﻿\t<Project xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n\t\t<PropertyGroup>\n\t\t\t<ProjectGuid>{1c20799f-272f-4399-9075-20c658d0214d}</ProjectGuid>\n\t\t\t<MainSource>ZComponentDesign.dpk</MainSource>\n\t\t\t<Configuration Condition=\" '$(Configuration)' == '' \">Debug</Configuration>\n\t\t\t<DCC_DCCCompiler>DCC32</DCC_DCCCompiler>\n\t\t\t<DCC_DependencyCheckOutputName>C:\\Documents and Settings\\All Users\\Documentos\\RAD Studio\\5.0\\Bpl\\ZComponentDesign110.bpl</DCC_DependencyCheckOutputName>\n\t\t\t<ProjectVersion>12.3</ProjectVersion>\n\t\t\t<Config Condition=\"'$(Config)'==''\">Debug</Config>\n\t\t\t<Base>True</Base>\n\t\t\t<Platform>Win32</Platform>\n\t\t\t<AppType>Package</AppType>\n\t\t\t<FrameworkType>None</FrameworkType>\n\t\t</PropertyGroup>\n\t\t<PropertyGroup Condition=\"'$(Config)'=='Base' or '$(Base)'!=''\">\n\t\t\t<Base>true</Base>\n\t\t</PropertyGroup>\n\t\t<PropertyGroup Condition=\"'$(Config)'=='Release' or '$(Cfg_1)'!=''\">\n\t\t\t<Cfg_1>true</Cfg_1>\n\t\t\t<CfgParent>Base</CfgParent>\n\t\t\t<Base>true</Base>\n\t\t</PropertyGroup>\n\t\t<PropertyGroup Condition=\"'$(Config)'=='Debug' or '$(Cfg_2)'!=''\">\n\t\t\t<Cfg_2>true</Cfg_2>\n\t\t\t<CfgParent>Base</CfgParent>\n\t\t\t<Base>true</Base>\n\t\t</PropertyGroup>\n\t\t<PropertyGroup Condition=\"'$(Base)'!=''\">\n\t\t\t<DCC_UnitAlias>WinTypes=Windows;WinProcs=Windows;DbiTypes=BDE;DbiProcs=BDE;DbiErrs=BDE;$(DCC_UnitAlias)</DCC_UnitAlias>\n\t\t\t<DCC_DcuOutput>build</DCC_DcuOutput>\n\t\t\t<DCC_UnitSearchPath>build;$(DCC_UnitSearchPath)</DCC_UnitSearchPath>\n\t\t\t<DCC_BplOutput>$(BDSCOMMONDIR)\\Bpl</DCC_BplOutput>\n\t\t\t<DCC_DcpOutput>$(BDSCOMMONDIR)\\Dcp</DCC_DcpOutput>\n\t\t\t<DesignOnlyPackage>true</DesignOnlyPackage>\n\t\t\t<DllSuffix>150</DllSuffix>\n\t\t\t<DCC_ImageBase>00400000</DCC_ImageBase>\n\t\t\t<DCC_Description>Zeos Database Components</DCC_Description>\n\t\t\t<DCC_DependencyCheckOutputName>build\\ZComponentDesign150.bpl</DCC_DependencyCheckOutputName>\n\t\t\t<DCC_GenerateStackFrames>true</DCC_GenerateStackFrames>\n\t\t\t<DCC_OutputNeverBuildDcps>true</DCC_OutputNeverBuildDcps>\n\t\t\t<GenDll>true</GenDll>\n\t\t\t<DCC_IntegerOverflowCheck>true</DCC_IntegerOverflowCheck>\n\t\t\t<GenPackage>true</GenPackage>\n\t\t</PropertyGroup>\n\t\t<PropertyGroup Condition=\"'$(Cfg_1)'!=''\">\n\t\t\t<Version>7.0</Version>\n\t\t\t<DCC_DebugInformation>False</DCC_DebugInformation>\n\t\t\t<DCC_LocalDebugSymbols>False</DCC_LocalDebugSymbols>\n\t\t\t<DCC_IntegerOverflowCheck>True</DCC_IntegerOverflowCheck>\n\t\t\t<DCC_GenerateStackFrames>True</DCC_GenerateStackFrames>\n\t\t\t<DCC_SymbolReferenceInfo>0</DCC_SymbolReferenceInfo>\n\t\t\t<DCC_ObjOutput>build</DCC_ObjOutput>\n\t\t\t<DCC_HppOutput>build</DCC_HppOutput>\n\t\t\t<DCC_ResourcePath>$(BDSCOMMONDIR)\\Bpl;$(DCC_ResourcePath)</DCC_ResourcePath>\n\t\t\t<DCC_ObjPath>$(BDSCOMMONDIR)\\Bpl;$(DCC_ObjPath)</DCC_ObjPath>\n\t\t\t<DCC_IncludePath>$(BDSCOMMONDIR)\\Bpl;$(DCC_IncludePath)</DCC_IncludePath>\n\t\t\t<DCC_Define>RELEASE</DCC_Define>\n\t\t</PropertyGroup>\n\t\t<PropertyGroup Condition=\"'$(Cfg_2)'!=''\">\n\t\t\t<DCC_Define>DEBUG;$(DCC_Define)</DCC_Define>\n\t\t\t<Version>7.0</Version>\n\t\t\t<DCC_IntegerOverflowCheck>True</DCC_IntegerOverflowCheck>\n\t\t\t<DCC_GenerateStackFrames>True</DCC_GenerateStackFrames>\n\t\t\t<DCC_ObjOutput>build</DCC_ObjOutput>\n\t\t\t<DCC_HppOutput>build</DCC_HppOutput>\n\t\t\t<DCC_ResourcePath>$(BDSCOMMONDIR)\\Bpl;$(DCC_ResourcePath)</DCC_ResourcePath>\n\t\t\t<DCC_ObjPath>$(BDSCOMMONDIR)\\Bpl;$(DCC_ObjPath)</DCC_ObjPath>\n\t\t\t<DCC_IncludePath>$(BDSCOMMONDIR)\\Bpl;$(DCC_IncludePath)</DCC_IncludePath>\n\t\t</PropertyGroup>\n\t\t<ItemGroup>\n\t\t\t<DelphiCompile Include=\"ZComponentDesign.dpk\">\n\t\t\t\t<MainSource>MainSource</MainSource>\n\t\t\t</DelphiCompile>\n\t\t\t<DCCReference Include=\"..\\..\\src\\component\\ZComponent.dcr\"/>\n\t\t\t<DCCReference Include=\"dbrtl.dcp\"/>\n\t\t\t<DCCReference Include=\"designide.dcp\"/>\n\t\t\t<DCCReference Include=\"ZParseSql.dcp\"/>\n\t\t\t<DCCReference Include=\"ZCore.dcp\"/>\n\t\t\t<DCCReference Include=\"ZPlain.dcp\"/>\n\t\t\t<DCCReference Include=\"ZDbc.dcp\"/>\n\t\t\t<DCCReference Include=\"ZComponent.dcp\"/>\n\t\t\t<DCCReference Include=\"..\\..\\src\\component\\ZPropertyEditor.pas\"/>\n\t\t\t<DCCReference Include=\"..\\..\\src\\component\\ZUpdateSqlEditor.pas\">\n\t\t\t\t<Form>ZUpdateSQLEditForm</Form>\n\t\t\t</DCCReference>\n\t\t\t<DCCReference Include=\"..\\..\\src\\component\\ZComponentReg.pas\"/>\n\t\t\t<BuildConfiguration Include=\"Debug\">\n\t\t\t\t<Key>Cfg_2</Key>\n\t\t\t\t<CfgParent>Base</CfgParent>\n\t\t\t</BuildConfiguration>\n\t\t\t<BuildConfiguration Include=\"Base\">\n\t\t\t\t<Key>Base</Key>\n\t\t\t</BuildConfiguration>\n\t\t\t<BuildConfiguration Include=\"Release\">\n\t\t\t\t<Key>Cfg_1</Key>\n\t\t\t\t<CfgParent>Base</CfgParent>\n\t\t\t</BuildConfiguration>\n\t\t</ItemGroup>\n\t\t<Import Condition=\"Exists('$(BDS)\\Bin\\CodeGear.Delphi.Targets')\" Project=\"$(BDS)\\Bin\\CodeGear.Delphi.Targets\"/>\n\t\t<Import Condition=\"Exists('$(APPDATA)\\Embarcadero\\$(BDSAPPDATABASEDIR)\\$(PRODUCTVERSION)\\UserTools.proj')\" Project=\"$(APPDATA)\\Embarcadero\\$(BDSAPPDATABASEDIR)\\$(PRODUCTVERSION)\\UserTools.proj\"/>\n\t\t<ProjectExtensions>\n\t\t\t<Borland.Personality>Delphi.Personality.12</Borland.Personality>\n\t\t\t<Borland.ProjectType>Package</Borland.ProjectType>\n\t\t\t<BorlandProject>\n\t\t\t\t<Delphi.Personality>\n\t\t\t\t\t<Parameters/>\n\t\t\t\t\t<VersionInfo>\n\t\t\t\t\t\t<VersionInfo Name=\"IncludeVerInfo\">True</VersionInfo>\n\t\t\t\t\t\t<VersionInfo Name=\"AutoIncBuild\">False</VersionInfo>\n\t\t\t\t\t\t<VersionInfo Name=\"MajorVer\">1</VersionInfo>\n\t\t\t\t\t\t<VersionInfo Name=\"MinorVer\">0</VersionInfo>\n\t\t\t\t\t\t<VersionInfo Name=\"Release\">0</VersionInfo>\n\t\t\t\t\t\t<VersionInfo Name=\"Build\">0</VersionInfo>\n\t\t\t\t\t\t<VersionInfo Name=\"Debug\">False</VersionInfo>\n\t\t\t\t\t\t<VersionInfo Name=\"PreRelease\">False</VersionInfo>\n\t\t\t\t\t\t<VersionInfo Name=\"Special\">False</VersionInfo>\n\t\t\t\t\t\t<VersionInfo Name=\"Private\">False</VersionInfo>\n\t\t\t\t\t\t<VersionInfo Name=\"DLL\">False</VersionInfo>\n\t\t\t\t\t\t<VersionInfo Name=\"Locale\">1033</VersionInfo>\n\t\t\t\t\t\t<VersionInfo Name=\"CodePage\">1252</VersionInfo>\n\t\t\t\t\t</VersionInfo>\n\t\t\t\t\t<VersionInfoKeys>\n\t\t\t\t\t\t<VersionInfoKeys Name=\"CompanyName\"/>\n\t\t\t\t\t\t<VersionInfoKeys Name=\"FileDescription\"/>\n\t\t\t\t\t\t<VersionInfoKeys Name=\"FileVersion\">1.0.0.0</VersionInfoKeys>\n\t\t\t\t\t\t<VersionInfoKeys Name=\"InternalName\"/>\n\t\t\t\t\t\t<VersionInfoKeys Name=\"LegalCopyright\"/>\n\t\t\t\t\t\t<VersionInfoKeys Name=\"LegalTrademarks\"/>\n\t\t\t\t\t\t<VersionInfoKeys Name=\"OriginalFilename\"/>\n\t\t\t\t\t\t<VersionInfoKeys Name=\"ProductName\"/>\n\t\t\t\t\t\t<VersionInfoKeys Name=\"ProductVersion\">1.0.0.0</VersionInfoKeys>\n\t\t\t\t\t\t<VersionInfoKeys Name=\"Comments\"/>\n\t\t\t\t\t</VersionInfoKeys>\n\t\t\t\t\t<Source>\n\t\t\t\t\t\t<Source Name=\"MainSource\">ZComponentDesign.dpk</Source>\n\t\t\t\t\t</Source>\n\t\t\t\t</Delphi.Personality>\n\t\t\t\t<Platforms>\n\t\t\t\t\t<Platform value=\"Win32\">True</Platform>\n\t\t\t\t</Platforms>\n\t\t\t</BorlandProject>\n\t\t\t<ProjectFileVersion>12</ProjectFileVersion>\n\t\t</ProjectExtensions>\n\t</Project>\n"
  },
  {
    "path": "lib/zeosdbo/packages/DelphiXE/ZCore.dpk",
    "content": "package ZCore;\n{$R *.res}\n{$ALIGN 8}\n{$ASSERTIONS ON}\n{$BOOLEVAL OFF}\n{$DEBUGINFO ON}\n{$EXTENDEDSYNTAX ON}\n{$IMPORTEDDATA ON}\n{$IOCHECKS ON}\n{$LOCALSYMBOLS ON}\n{$LONGSTRINGS ON}\n{$OPENSTRINGS ON}\n{$OPTIMIZATION ON}\n{$OVERFLOWCHECKS ON}\n{$RANGECHECKS OFF}\n{$REFERENCEINFO ON}\n{$SAFEDIVIDE OFF}\n{$STACKFRAMES ON}\n{$TYPEDADDRESS OFF}\n{$VARSTRINGCHECKS ON}\n{$WRITEABLECONST OFF}\n{$MINENUMSIZE 1}\n{$IMAGEBASE $400000}\n{$DESCRIPTION 'Zeos Core Classes and Interfaces'}\n{$LIBSUFFIX '150'}\n{$RUNONLY}\n{$IMPLICITBUILD OFF}\n\nrequires\n  rtl;\n\ncontains\n  ZVariant in '..\\..\\src\\core\\ZVariant.pas',\n  ZCollections in '..\\..\\src\\core\\ZCollections.pas',\n  ZCompatibility in '..\\..\\src\\core\\ZCompatibility.pas',\n  ZEncoding in '..\\..\\src\\core\\ZEncoding.pas',\n  ZExpression in '..\\..\\src\\core\\ZExpression.pas',\n  ZExprParser in '..\\..\\src\\core\\ZExprParser.pas',\n  ZExprToken in '..\\..\\src\\core\\ZExprToken.pas',\n  ZMatchPattern in '..\\..\\src\\core\\ZMatchPattern.pas',\n  ZSysUtils in '..\\..\\src\\core\\ZSysUtils.pas',\n  ZTokenizer in '..\\..\\src\\core\\ZTokenizer.pas',\n  ZVariables in '..\\..\\src\\core\\ZVariables.pas',\n  ZClasses in '..\\..\\src\\core\\ZClasses.pas',\n  ZMessages in '..\\..\\src\\core\\ZMessages.pas',\n  ZURL in '..\\..\\src\\core\\ZURL.pas',\n  ZFunctions in '..\\..\\src\\core\\ZFunctions.pas',\n  ZFunctionsConvert in '..\\..\\src\\core\\ZFunctionsConvert.pas',\n  ZFunctionsDateTime in '..\\..\\src\\core\\ZFunctionsDateTime.pas',\n  ZFunctionsMath in '..\\..\\src\\core\\ZFunctionsMath.pas',\n  ZFunctionsOther in '..\\..\\src\\core\\ZFunctionsOther.pas',\n  ZFunctionsStrings in '..\\..\\src\\core\\ZFunctionsStrings.pas';\n\nend.\n"
  },
  {
    "path": "lib/zeosdbo/packages/DelphiXE/ZCore.dproj",
    "content": "﻿\t<Project xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n\t\t<PropertyGroup>\n\t\t\t<ProjectGuid>{1a98c0b7-eb38-4725-9569-1c0bf5beb099}</ProjectGuid>\n\t\t\t<MainSource>ZCore.dpk</MainSource>\n\t\t\t<Configuration Condition=\" '$(Configuration)' == '' \">Debug</Configuration>\n\t\t\t<DCC_DCCCompiler>DCC32</DCC_DCCCompiler>\n\t\t\t<DCC_DependencyCheckOutputName>C:\\Documents and Settings\\All Users\\Documentos\\RAD Studio\\5.0\\Bpl\\ZCore110.bpl</DCC_DependencyCheckOutputName>\n\t\t\t<ProjectVersion>12.3</ProjectVersion>\n\t\t\t<Config Condition=\"'$(Config)'==''\">Debug</Config>\n\t\t\t<Base>True</Base>\n\t\t\t<Platform>Win32</Platform>\n\t\t\t<AppType>Package</AppType>\n\t\t\t<FrameworkType>None</FrameworkType>\n\t\t</PropertyGroup>\n\t\t<PropertyGroup Condition=\"'$(Config)'=='Base' or '$(Base)'!=''\">\n\t\t\t<Base>true</Base>\n\t\t</PropertyGroup>\n\t\t<PropertyGroup Condition=\"'$(Config)'=='Release' or '$(Cfg_1)'!=''\">\n\t\t\t<Cfg_1>true</Cfg_1>\n\t\t\t<CfgParent>Base</CfgParent>\n\t\t\t<Base>true</Base>\n\t\t</PropertyGroup>\n\t\t<PropertyGroup Condition=\"'$(Config)'=='Debug' or '$(Cfg_2)'!=''\">\n\t\t\t<Cfg_2>true</Cfg_2>\n\t\t\t<CfgParent>Base</CfgParent>\n\t\t\t<Base>true</Base>\n\t\t</PropertyGroup>\n\t\t<PropertyGroup Condition=\"'$(Base)'!=''\">\n\t\t\t<DCC_UnitAlias>WinTypes=Windows;WinProcs=Windows;DbiTypes=BDE;DbiProcs=BDE;DbiErrs=BDE;$(DCC_UnitAlias)</DCC_UnitAlias>\n\t\t\t<DCC_UnitSearchPath>build;$(DCC_UnitSearchPath)</DCC_UnitSearchPath>\n\t\t\t<DCC_DcuOutput>build</DCC_DcuOutput>\n\t\t\t<DCC_BplOutput>$(BDSCOMMONDIR)\\Bpl</DCC_BplOutput>\n\t\t\t<DCC_DcpOutput>$(BDSCOMMONDIR)\\Dcp</DCC_DcpOutput>\n\t\t\t<DCC_ImageBase>00400000</DCC_ImageBase>\n\t\t\t<DllSuffix>150</DllSuffix>\n\t\t\t<DCC_Description>Zeos Core Classes and Interfaces</DCC_Description>\n\t\t\t<RuntimeOnlyPackage>true</RuntimeOnlyPackage>\n\t\t\t<DCC_DependencyCheckOutputName>build\\ZCore150.bpl</DCC_DependencyCheckOutputName>\n\t\t\t<DCC_IntegerOverflowCheck>true</DCC_IntegerOverflowCheck>\n\t\t\t<DCC_OutputNeverBuildDcps>true</DCC_OutputNeverBuildDcps>\n\t\t\t<GenDll>true</GenDll>\n\t\t\t<DCC_GenerateStackFrames>true</DCC_GenerateStackFrames>\n\t\t\t<GenPackage>true</GenPackage>\n\t\t</PropertyGroup>\n\t\t<PropertyGroup Condition=\"'$(Cfg_1)'!=''\">\n\t\t\t<Version>7.0</Version>\n\t\t\t<DCC_DebugInformation>False</DCC_DebugInformation>\n\t\t\t<DCC_LocalDebugSymbols>False</DCC_LocalDebugSymbols>\n\t\t\t<DCC_IntegerOverflowCheck>True</DCC_IntegerOverflowCheck>\n\t\t\t<DCC_GenerateStackFrames>True</DCC_GenerateStackFrames>\n\t\t\t<DCC_SymbolReferenceInfo>0</DCC_SymbolReferenceInfo>\n\t\t\t<DCC_ObjOutput>build</DCC_ObjOutput>\n\t\t\t<DCC_HppOutput>build</DCC_HppOutput>\n\t\t\t<DCC_Define>RELEASE;$(DCC_Define)</DCC_Define>\n\t\t\t<DCC_ResourcePath>$(BDSCOMMONDIR)\\Bpl;$(DCC_ResourcePath)</DCC_ResourcePath>\n\t\t\t<DCC_ObjPath>$(BDSCOMMONDIR)\\Bpl;$(DCC_ObjPath)</DCC_ObjPath>\n\t\t\t<DCC_IncludePath>$(BDSCOMMONDIR)\\Bpl;$(DCC_IncludePath)</DCC_IncludePath>\n\t\t</PropertyGroup>\n\t\t<PropertyGroup Condition=\"'$(Cfg_2)'!=''\">\n\t\t\t<DCC_Define>DEBUG;$(DCC_Define)</DCC_Define>\n\t\t\t<Version>7.0</Version>\n\t\t\t<DCC_IntegerOverflowCheck>True</DCC_IntegerOverflowCheck>\n\t\t\t<DCC_GenerateStackFrames>True</DCC_GenerateStackFrames>\n\t\t\t<DCC_ObjOutput>build</DCC_ObjOutput>\n\t\t\t<DCC_HppOutput>build</DCC_HppOutput>\n\t\t\t<DCC_ResourcePath>$(BDSCOMMONDIR)\\Bpl;$(DCC_ResourcePath)</DCC_ResourcePath>\n\t\t\t<DCC_ObjPath>$(BDSCOMMONDIR)\\Bpl;$(DCC_ObjPath)</DCC_ObjPath>\n\t\t\t<DCC_IncludePath>$(BDSCOMMONDIR)\\Bpl;$(DCC_IncludePath)</DCC_IncludePath>\n\t\t</PropertyGroup>\n\t\t<ItemGroup>\n\t\t\t<DelphiCompile Include=\"ZCore.dpk\">\n\t\t\t\t<MainSource>MainSource</MainSource>\n\t\t\t</DelphiCompile>\n\t\t\t<DCCReference Include=\"rtl.dcp\"/>\n\t\t\t<DCCReference Include=\"..\\..\\src\\core\\ZVariant.pas\"/>\n\t\t\t<DCCReference Include=\"..\\..\\src\\core\\ZCollections.pas\"/>\n\t\t\t<DCCReference Include=\"..\\..\\src\\core\\ZCompatibility.pas\"/>\n\t\t\t<DCCReference Include=\"..\\..\\src\\core\\ZEncoding.pas\"/>\n\t\t\t<DCCReference Include=\"..\\..\\src\\core\\ZExpression.pas\"/>\n\t\t\t<DCCReference Include=\"..\\..\\src\\core\\ZExprParser.pas\"/>\n\t\t\t<DCCReference Include=\"..\\..\\src\\core\\ZExprToken.pas\"/>\n\t\t\t<DCCReference Include=\"..\\..\\src\\core\\ZMatchPattern.pas\"/>\n\t\t\t<DCCReference Include=\"..\\..\\src\\core\\ZSysUtils.pas\"/>\n\t\t\t<DCCReference Include=\"..\\..\\src\\core\\ZTokenizer.pas\"/>\n\t\t\t<DCCReference Include=\"..\\..\\src\\core\\ZVariables.pas\"/>\n\t\t\t<DCCReference Include=\"..\\..\\src\\core\\ZClasses.pas\"/>\n\t\t\t<DCCReference Include=\"..\\..\\src\\core\\ZMessages.pas\"/>\n\t\t\t<DCCReference Include=\"..\\..\\src\\core\\ZURL.pas\"/>\n\t\t\t<DCCReference Include=\"..\\..\\src\\core\\ZFunctions.pas\"/>\n\t\t\t<DCCReference Include=\"..\\..\\src\\core\\ZFunctionsConvert.pas\"/>\n\t\t\t<DCCReference Include=\"..\\..\\src\\core\\ZFunctionsDateTime.pas\"/>\n\t\t\t<DCCReference Include=\"..\\..\\src\\core\\ZFunctionsMath.pas\"/>\n\t\t\t<DCCReference Include=\"..\\..\\src\\core\\ZFunctionsOther.pas\"/>\n\t\t\t<DCCReference Include=\"..\\..\\src\\core\\ZFunctionsStrings.pas\"/>\n\t\t\t<BuildConfiguration Include=\"Debug\">\n\t\t\t\t<Key>Cfg_2</Key>\n\t\t\t\t<CfgParent>Base</CfgParent>\n\t\t\t</BuildConfiguration>\n\t\t\t<BuildConfiguration Include=\"Base\">\n\t\t\t\t<Key>Base</Key>\n\t\t\t</BuildConfiguration>\n\t\t\t<BuildConfiguration Include=\"Release\">\n\t\t\t\t<Key>Cfg_1</Key>\n\t\t\t\t<CfgParent>Base</CfgParent>\n\t\t\t</BuildConfiguration>\n\t\t</ItemGroup>\n\t\t<Import Condition=\"Exists('$(BDS)\\Bin\\CodeGear.Delphi.Targets')\" Project=\"$(BDS)\\Bin\\CodeGear.Delphi.Targets\"/>\n\t\t<Import Condition=\"Exists('$(APPDATA)\\Embarcadero\\$(BDSAPPDATABASEDIR)\\$(PRODUCTVERSION)\\UserTools.proj')\" Project=\"$(APPDATA)\\Embarcadero\\$(BDSAPPDATABASEDIR)\\$(PRODUCTVERSION)\\UserTools.proj\"/>\n\t\t<ProjectExtensions>\n\t\t\t<Borland.Personality>Delphi.Personality.12</Borland.Personality>\n\t\t\t<Borland.ProjectType>Package</Borland.ProjectType>\n\t\t\t<BorlandProject>\n\t\t\t\t<Delphi.Personality>\n\t\t\t\t\t<Parameters/>\n\t\t\t\t\t<VersionInfo>\n\t\t\t\t\t\t<VersionInfo Name=\"IncludeVerInfo\">True</VersionInfo>\n\t\t\t\t\t\t<VersionInfo Name=\"AutoIncBuild\">False</VersionInfo>\n\t\t\t\t\t\t<VersionInfo Name=\"MajorVer\">1</VersionInfo>\n\t\t\t\t\t\t<VersionInfo Name=\"MinorVer\">0</VersionInfo>\n\t\t\t\t\t\t<VersionInfo Name=\"Release\">0</VersionInfo>\n\t\t\t\t\t\t<VersionInfo Name=\"Build\">0</VersionInfo>\n\t\t\t\t\t\t<VersionInfo Name=\"Debug\">False</VersionInfo>\n\t\t\t\t\t\t<VersionInfo Name=\"PreRelease\">False</VersionInfo>\n\t\t\t\t\t\t<VersionInfo Name=\"Special\">False</VersionInfo>\n\t\t\t\t\t\t<VersionInfo Name=\"Private\">False</VersionInfo>\n\t\t\t\t\t\t<VersionInfo Name=\"DLL\">False</VersionInfo>\n\t\t\t\t\t\t<VersionInfo Name=\"Locale\">1031</VersionInfo>\n\t\t\t\t\t\t<VersionInfo Name=\"CodePage\">1252</VersionInfo>\n\t\t\t\t\t</VersionInfo>\n\t\t\t\t\t<VersionInfoKeys>\n\t\t\t\t\t\t<VersionInfoKeys Name=\"CompanyName\"/>\n\t\t\t\t\t\t<VersionInfoKeys Name=\"FileDescription\"/>\n\t\t\t\t\t\t<VersionInfoKeys Name=\"FileVersion\">1.0.0.0</VersionInfoKeys>\n\t\t\t\t\t\t<VersionInfoKeys Name=\"InternalName\"/>\n\t\t\t\t\t\t<VersionInfoKeys Name=\"LegalCopyright\"/>\n\t\t\t\t\t\t<VersionInfoKeys Name=\"LegalTrademarks\"/>\n\t\t\t\t\t\t<VersionInfoKeys Name=\"OriginalFilename\"/>\n\t\t\t\t\t\t<VersionInfoKeys Name=\"ProductName\"/>\n\t\t\t\t\t\t<VersionInfoKeys Name=\"ProductVersion\">1.0.0.0</VersionInfoKeys>\n\t\t\t\t\t</VersionInfoKeys>\n\t\t\t\t\t<Source>\n\t\t\t\t\t\t<Source Name=\"MainSource\">ZCore.dpk</Source>\n\t\t\t\t\t</Source>\n\t\t\t\t</Delphi.Personality>\n\t\t\t\t<Platforms>\n\t\t\t\t\t<Platform value=\"Win32\">True</Platform>\n\t\t\t\t</Platforms>\n\t\t\t</BorlandProject>\n\t\t\t<ProjectFileVersion>12</ProjectFileVersion>\n\t\t</ProjectExtensions>\n\t</Project>\n"
  },
  {
    "path": "lib/zeosdbo/packages/DelphiXE/ZDbc.dpk",
    "content": "package ZDbc;\n{$R *.res}\n{$ALIGN 8}\n{$ASSERTIONS ON}\n{$BOOLEVAL OFF}\n{$DEBUGINFO ON}\n{$EXTENDEDSYNTAX ON}\n{$IMPORTEDDATA ON}\n{$IOCHECKS ON}\n{$LOCALSYMBOLS ON}\n{$LONGSTRINGS ON}\n{$OPENSTRINGS ON}\n{$OPTIMIZATION ON}\n{$OVERFLOWCHECKS ON}\n{$RANGECHECKS OFF}\n{$REFERENCEINFO ON}\n{$SAFEDIVIDE OFF}\n{$STACKFRAMES ON}\n{$TYPEDADDRESS OFF}\n{$VARSTRINGCHECKS ON}\n{$WRITEABLECONST OFF}\n{$MINENUMSIZE 1}\n{$IMAGEBASE $400000}\n{$DESCRIPTION 'Zeos Low Level Database API'}\n{$LIBSUFFIX '150'}\n{$RUNONLY}\n{$IMPLICITBUILD OFF}\n{$I ZPackages.inc}\n\nrequires\n  ZParseSql,\n  ZPlain,\n  rtl,\n  dbrtl;\n\ncontains\n{$IFDEF ENABLE_DBLIB}\n  ZDbcDbLib in '..\\..\\src\\dbc\\ZDbcDbLib.pas',\n  ZDbcDbLibMetadata in '..\\..\\src\\dbc\\ZDbcDbLibMetadata.pas',\n  ZDbcDbLibResultSet in '..\\..\\src\\dbc\\ZDbcDbLibResultSet.pas',\n  ZDbcDbLibStatement in '..\\..\\src\\dbc\\ZDbcDbLibStatement.pas',\n  ZDbcDbLibUtils in '..\\..\\src\\dbc\\ZDbcDbLibUtils.pas',\n{$ENDIF}\n\n{$IFDEF ENABLE_INTERBASE}\n  ZDbcInterbase6 in '..\\..\\src\\dbc\\ZDbcInterbase6.pas',\n  ZDbcInterbase6Metadata in '..\\..\\src\\dbc\\ZDbcInterbase6Metadata.pas',\n  ZDbcInterbase6ResultSet in '..\\..\\src\\dbc\\ZDbcInterbase6ResultSet.pas',\n  ZDbcInterbase6Statement in '..\\..\\src\\dbc\\ZDbcInterbase6Statement.pas',\n  ZDbcInterbase6Utils in '..\\..\\src\\dbc\\ZDbcInterbase6Utils.pas',\n{$ENDIF}\n\n{$IFDEF ENABLE_MYSQL}\n  ZDbcMySql in '..\\..\\src\\dbc\\ZDbcMySql.pas',\n  ZDbcMySqlMetadata in '..\\..\\src\\dbc\\ZDbcMySqlMetadata.pas',\n  ZDbcMySqlResultSet in '..\\..\\src\\dbc\\ZDbcMySqlResultSet.pas',\n  ZDbcMySqlStatement in '..\\..\\src\\dbc\\ZDbcMySqlStatement.pas',\n  ZDbcMySqlUtils in '..\\..\\src\\dbc\\ZDbcMySqlUtils.pas',\n{$ENDIF}\n\n{$IFDEF ENABLE_POSTGRESQL}\n  ZDbcPostgreSql in '..\\..\\src\\dbc\\ZDbcPostgreSql.pas',\n  ZDbcPostgreSqlMetadata in '..\\..\\src\\dbc\\ZDbcPostgreSqlMetadata.pas',\n  ZDbcPostgreSqlResultSet in '..\\..\\src\\dbc\\ZDbcPostgreSqlResultSet.pas',\n  ZDbcPostgreSqlStatement in '..\\..\\src\\dbc\\ZDbcPostgreSqlStatement.pas',\n  ZDbcPostgreSqlUtils in '..\\..\\src\\dbc\\ZDbcPostgreSqlUtils.pas',\n{$ENDIF}\n\n{$IFDEF ENABLE_ADO}\n  ZDbcAdo in '..\\..\\src\\dbc\\ZDbcAdo.pas',\n  ZDbcAdoMetadata in '..\\..\\src\\dbc\\ZDbcAdoMetadata.pas',\n  ZDbcAdoResultSet in '..\\..\\src\\dbc\\ZDbcAdoResultSet.pas',\n  ZDbcAdoStatement in '..\\..\\src\\dbc\\ZDbcAdoStatement.pas',\n  ZDbcAdoUtils in '..\\..\\src\\dbc\\ZDbcAdoUtils.pas',\n{$ENDIF}\n\n{$IFDEF ENABLE_ORACLE}\n  ZDbcOracle in '..\\..\\src\\dbc\\ZDbcOracle.pas',\n  ZDbcOracleUtils in '..\\..\\src\\dbc\\ZDbcOracleUtils.pas',\n  ZDbcOracleStatement in '..\\..\\src\\dbc\\ZDbcOracleStatement.pas',\n  ZDbcOracleResultSet in '..\\..\\src\\dbc\\ZDbcOracleResultSet.pas',\n  ZDbcOracleMetadata in '..\\..\\src\\dbc\\ZDbcOracleMetadata.pas',\n{$ENDIF}\n\n{$IFDEF ENABLE_SQLITE}\n  ZDbcSqLite in '..\\..\\src\\dbc\\ZDbcSqLite.pas',\n  ZDbcSqLiteUtils in '..\\..\\src\\dbc\\ZDbcSqLiteUtils.pas',\n  ZDbcSqLiteStatement in '..\\..\\src\\dbc\\ZDbcSqLiteStatement.pas',\n  ZDbcSqLiteResultSet in '..\\..\\src\\dbc\\ZDbcSqLiteResultSet.pas',\n  ZDbcSqLiteMetadata in '..\\..\\src\\dbc\\ZDbcSqLiteMetadata.pas',\n{$ENDIF}\n\n{$IFDEF ENABLE_ASA}\n  ZDbcASAUtils in '..\\..\\src\\dbc\\ZDbcASAUtils.pas',\n  ZDbcASAMetadata in '..\\..\\src\\dbc\\ZDbcASAMetadata.pas',\n  ZDbcASAResultSet in '..\\..\\src\\dbc\\ZDbcASAResultSet.pas',\n  ZDbcASAStatement in '..\\..\\src\\dbc\\ZDbcASAStatement.pas',\n  ZDbcASA in '..\\..\\src\\dbc\\ZDbcASA.pas',\n{$ENDIF}\n\n{$IFDEF ENABLE_POOLED}\n  ZDbcPooled in '..\\..\\src\\dbc\\ZDbcPooled.pas',\n{$ENDIF}\n\n  ZDbcUtils in '..\\..\\src\\dbc\\ZDbcUtils.pas',\n  ZDbcCachedResultSet in '..\\..\\src\\dbc\\ZDbcCachedResultSet.pas',\n  ZDbcConnection in '..\\..\\src\\dbc\\ZDbcConnection.pas',\n  ZDbcGenericResolver in '..\\..\\src\\dbc\\ZDbcGenericResolver.pas',\n  ZDbcIntfs in '..\\..\\src\\dbc\\ZDbcIntfs.pas',\n  ZDbcMetadata in '..\\..\\src\\dbc\\ZDbcMetadata.pas',\n  ZDbcResultSet in '..\\..\\src\\dbc\\ZDbcResultSet.pas',\n  ZDbcResultSetMetadata in '..\\..\\src\\dbc\\ZDbcResultSetMetadata.pas',\n  ZDbcStatement in '..\\..\\src\\dbc\\ZDbcStatement.pas',\n  ZDbcCache in '..\\..\\src\\dbc\\ZDbcCache.pas',\n  ZDbcLogging in '..\\..\\src\\dbc\\ZDbcLogging.pas';\n\nend.\n"
  },
  {
    "path": "lib/zeosdbo/packages/DelphiXE/ZDbc.dproj",
    "content": "﻿\t<Project xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n\t\t<PropertyGroup>\n\t\t\t<ProjectGuid>{47d8573c-edfe-4827-93f9-d1e3ee5f6f1f}</ProjectGuid>\n\t\t\t<MainSource>ZDbc.dpk</MainSource>\n\t\t\t<Configuration Condition=\" '$(Configuration)' == '' \">Debug</Configuration>\n\t\t\t<DCC_DCCCompiler>DCC32</DCC_DCCCompiler>\n\t\t\t<DCC_DependencyCheckOutputName>C:\\Documents and Settings\\All Users\\Documentos\\RAD Studio\\5.0\\Bpl\\ZDbc110.bpl</DCC_DependencyCheckOutputName>\n\t\t\t<ProjectVersion>12.3</ProjectVersion>\n\t\t\t<Config Condition=\"'$(Config)'==''\">Debug</Config>\n\t\t\t<Base>True</Base>\n\t\t\t<Platform>Win32</Platform>\n\t\t\t<AppType>Package</AppType>\n\t\t\t<FrameworkType>None</FrameworkType>\n\t\t</PropertyGroup>\n\t\t<PropertyGroup Condition=\"'$(Config)'=='Base' or '$(Base)'!=''\">\n\t\t\t<Base>true</Base>\n\t\t</PropertyGroup>\n\t\t<PropertyGroup Condition=\"'$(Config)'=='Release' or '$(Cfg_1)'!=''\">\n\t\t\t<Cfg_1>true</Cfg_1>\n\t\t\t<CfgParent>Base</CfgParent>\n\t\t\t<Base>true</Base>\n\t\t</PropertyGroup>\n\t\t<PropertyGroup Condition=\"'$(Config)'=='Debug' or '$(Cfg_2)'!=''\">\n\t\t\t<Cfg_2>true</Cfg_2>\n\t\t\t<CfgParent>Base</CfgParent>\n\t\t\t<Base>true</Base>\n\t\t</PropertyGroup>\n\t\t<PropertyGroup Condition=\"'$(Base)'!=''\">\n\t\t\t<DCC_UnitAlias>WinTypes=Windows;WinProcs=Windows;DbiTypes=BDE;DbiProcs=BDE;DbiErrs=BDE;$(DCC_UnitAlias)</DCC_UnitAlias>\n\t\t\t<DCC_UnitSearchPath>build;$(DCC_UnitSearchPath)</DCC_UnitSearchPath>\n\t\t\t<DCC_DcuOutput>build</DCC_DcuOutput>\n\t\t\t<DCC_BplOutput>$(BDSCOMMONDIR)\\Bpl</DCC_BplOutput>\n\t\t\t<DCC_DcpOutput>$(BDSCOMMONDIR)\\Dcp</DCC_DcpOutput>\n\t\t\t<DCC_ImageBase>00400000</DCC_ImageBase>\n\t\t\t<DllSuffix>150</DllSuffix>\n\t\t\t<DCC_Description>Zeos Low Level Database API</DCC_Description>\n\t\t\t<RuntimeOnlyPackage>true</RuntimeOnlyPackage>\n\t\t\t<DCC_DependencyCheckOutputName>build\\ZDbc150.bpl</DCC_DependencyCheckOutputName>\n\t\t\t<DCC_IntegerOverflowCheck>true</DCC_IntegerOverflowCheck>\n\t\t\t<DCC_OutputNeverBuildDcps>true</DCC_OutputNeverBuildDcps>\n\t\t\t<GenDll>true</GenDll>\n\t\t\t<DCC_GenerateStackFrames>true</DCC_GenerateStackFrames>\n\t\t\t<GenPackage>true</GenPackage>\n\t\t</PropertyGroup>\n\t\t<PropertyGroup Condition=\"'$(Cfg_1)'!=''\">\n\t\t\t<Version>7.0</Version>\n\t\t\t<DCC_DebugInformation>False</DCC_DebugInformation>\n\t\t\t<DCC_LocalDebugSymbols>False</DCC_LocalDebugSymbols>\n\t\t\t<DCC_IntegerOverflowCheck>True</DCC_IntegerOverflowCheck>\n\t\t\t<DCC_GenerateStackFrames>True</DCC_GenerateStackFrames>\n\t\t\t<DCC_SymbolReferenceInfo>0</DCC_SymbolReferenceInfo>\n\t\t\t<DCC_ObjOutput>build</DCC_ObjOutput>\n\t\t\t<DCC_HppOutput>build</DCC_HppOutput>\n\t\t\t<DCC_Define>RELEASE;$(DCC_Define)</DCC_Define>\n\t\t\t<DCC_ResourcePath>$(BDSCOMMONDIR)\\Bpl;$(DCC_ResourcePath)</DCC_ResourcePath>\n\t\t\t<DCC_ObjPath>$(BDSCOMMONDIR)\\Bpl;$(DCC_ObjPath)</DCC_ObjPath>\n\t\t\t<DCC_IncludePath>$(BDSCOMMONDIR)\\Bpl;$(DCC_IncludePath)</DCC_IncludePath>\n\t\t</PropertyGroup>\n\t\t<PropertyGroup Condition=\"'$(Cfg_2)'!=''\">\n\t\t\t<DCC_Define>DEBUG;$(DCC_Define)</DCC_Define>\n\t\t\t<Version>7.0</Version>\n\t\t\t<DCC_IntegerOverflowCheck>True</DCC_IntegerOverflowCheck>\n\t\t\t<DCC_GenerateStackFrames>True</DCC_GenerateStackFrames>\n\t\t\t<DCC_ObjOutput>build</DCC_ObjOutput>\n\t\t\t<DCC_HppOutput>build</DCC_HppOutput>\n\t\t\t<DCC_ResourcePath>$(BDSCOMMONDIR)\\Bpl;$(DCC_ResourcePath)</DCC_ResourcePath>\n\t\t\t<DCC_ObjPath>$(BDSCOMMONDIR)\\Bpl;$(DCC_ObjPath)</DCC_ObjPath>\n\t\t\t<DCC_IncludePath>$(BDSCOMMONDIR)\\Bpl;$(DCC_IncludePath)</DCC_IncludePath>\n\t\t</PropertyGroup>\n\t\t<ItemGroup>\n\t\t\t<DelphiCompile Include=\"ZDbc.dpk\">\n\t\t\t\t<MainSource>MainSource</MainSource>\n\t\t\t</DelphiCompile>\n\t\t\t<DCCReference Include=\"ZParseSql.dcp\"/>\n\t\t\t<DCCReference Include=\"ZPlain.dcp\"/>\n\t\t\t<DCCReference Include=\"rtl.dcp\"/>\n\t\t\t<DCCReference Include=\"dbrtl.dcp\"/>\n\t\t\t<DCCReference Include=\"..\\..\\src\\dbc\\ZDbcUtils.pas\"/>\n\t\t\t<DCCReference Include=\"..\\..\\src\\dbc\\ZDbcCachedResultSet.pas\"/>\n\t\t\t<DCCReference Include=\"..\\..\\src\\dbc\\ZDbcConnection.pas\"/>\n\t\t\t<DCCReference Include=\"..\\..\\src\\dbc\\ZDbcGenericResolver.pas\"/>\n\t\t\t<DCCReference Include=\"..\\..\\src\\dbc\\ZDbcIntfs.pas\"/>\n\t\t\t<DCCReference Include=\"..\\..\\src\\dbc\\ZDbcMetadata.pas\"/>\n\t\t\t<DCCReference Include=\"..\\..\\src\\dbc\\ZDbcResultSet.pas\"/>\n\t\t\t<DCCReference Include=\"..\\..\\src\\dbc\\ZDbcResultSetMetadata.pas\"/>\n\t\t\t<DCCReference Include=\"..\\..\\src\\dbc\\ZDbcStatement.pas\"/>\n\t\t\t<DCCReference Include=\"..\\..\\src\\dbc\\ZDbcCache.pas\"/>\n\t\t\t<DCCReference Include=\"..\\..\\src\\dbc\\ZDbcLogging.pas\"/>\n\t\t\t<BuildConfiguration Include=\"Debug\">\n\t\t\t\t<Key>Cfg_2</Key>\n\t\t\t\t<CfgParent>Base</CfgParent>\n\t\t\t</BuildConfiguration>\n\t\t\t<BuildConfiguration Include=\"Base\">\n\t\t\t\t<Key>Base</Key>\n\t\t\t</BuildConfiguration>\n\t\t\t<BuildConfiguration Include=\"Release\">\n\t\t\t\t<Key>Cfg_1</Key>\n\t\t\t\t<CfgParent>Base</CfgParent>\n\t\t\t</BuildConfiguration>\n\t\t</ItemGroup>\n\t\t<Import Condition=\"Exists('$(BDS)\\Bin\\CodeGear.Delphi.Targets')\" Project=\"$(BDS)\\Bin\\CodeGear.Delphi.Targets\"/>\n\t\t<Import Condition=\"Exists('$(APPDATA)\\Embarcadero\\$(BDSAPPDATABASEDIR)\\$(PRODUCTVERSION)\\UserTools.proj')\" Project=\"$(APPDATA)\\Embarcadero\\$(BDSAPPDATABASEDIR)\\$(PRODUCTVERSION)\\UserTools.proj\"/>\n\t\t<ProjectExtensions>\n\t\t\t<Borland.Personality>Delphi.Personality.12</Borland.Personality>\n\t\t\t<Borland.ProjectType>Package</Borland.ProjectType>\n\t\t\t<BorlandProject>\n\t\t\t\t<Delphi.Personality>\n\t\t\t\t\t<Parameters/>\n\t\t\t\t\t<VersionInfo>\n\t\t\t\t\t\t<VersionInfo Name=\"IncludeVerInfo\">True</VersionInfo>\n\t\t\t\t\t\t<VersionInfo Name=\"AutoIncBuild\">False</VersionInfo>\n\t\t\t\t\t\t<VersionInfo Name=\"MajorVer\">1</VersionInfo>\n\t\t\t\t\t\t<VersionInfo Name=\"MinorVer\">0</VersionInfo>\n\t\t\t\t\t\t<VersionInfo Name=\"Release\">0</VersionInfo>\n\t\t\t\t\t\t<VersionInfo Name=\"Build\">0</VersionInfo>\n\t\t\t\t\t\t<VersionInfo Name=\"Debug\">False</VersionInfo>\n\t\t\t\t\t\t<VersionInfo Name=\"PreRelease\">False</VersionInfo>\n\t\t\t\t\t\t<VersionInfo Name=\"Special\">False</VersionInfo>\n\t\t\t\t\t\t<VersionInfo Name=\"Private\">False</VersionInfo>\n\t\t\t\t\t\t<VersionInfo Name=\"DLL\">False</VersionInfo>\n\t\t\t\t\t\t<VersionInfo Name=\"Locale\">1031</VersionInfo>\n\t\t\t\t\t\t<VersionInfo Name=\"CodePage\">1252</VersionInfo>\n\t\t\t\t\t</VersionInfo>\n\t\t\t\t\t<VersionInfoKeys>\n\t\t\t\t\t\t<VersionInfoKeys Name=\"CompanyName\"/>\n\t\t\t\t\t\t<VersionInfoKeys Name=\"FileDescription\"/>\n\t\t\t\t\t\t<VersionInfoKeys Name=\"FileVersion\">1.0.0.0</VersionInfoKeys>\n\t\t\t\t\t\t<VersionInfoKeys Name=\"InternalName\"/>\n\t\t\t\t\t\t<VersionInfoKeys Name=\"LegalCopyright\"/>\n\t\t\t\t\t\t<VersionInfoKeys Name=\"LegalTrademarks\"/>\n\t\t\t\t\t\t<VersionInfoKeys Name=\"OriginalFilename\"/>\n\t\t\t\t\t\t<VersionInfoKeys Name=\"ProductName\"/>\n\t\t\t\t\t\t<VersionInfoKeys Name=\"ProductVersion\">1.0.0.0</VersionInfoKeys>\n\t\t\t\t\t\t<VersionInfoKeys Name=\"Comments\"/>\n\t\t\t\t\t</VersionInfoKeys>\n\t\t\t\t\t<Source>\n\t\t\t\t\t\t<Source Name=\"MainSource\">ZDbc.dpk</Source>\n\t\t\t\t\t</Source>\n\t\t\t\t\t<Excluded_Packages>\n\t\t\t\t\t\t<Excluded_Packages Name=\"$(BDSBIN)\\dclnet120.bpl\">CodeGear Internet Components</Excluded_Packages>\n\t\t\t\t\t\t<Excluded_Packages Name=\"$(BDSBIN)\\dclwebsnap120.bpl\">CodeGear WebSnap Components</Excluded_Packages>\n\t\t\t\t\t\t<Excluded_Packages Name=\"$(BDSBIN)\\bcboffice2k120.bpl\">CodeGear C++Builder Office 2000 Servers Package</Excluded_Packages>\n\t\t\t\t\t\t<Excluded_Packages Name=\"$(BDSBIN)\\bcbofficexp120.bpl\">CodeGear C++Builder Office XP Servers Package</Excluded_Packages>\n\t\t\t\t\t\t<Excluded_Packages Name=\"$(BDSBIN)\\dcloffice2k120.bpl\">Microsoft Office 2000 Sample Automation Server Wrapper Components</Excluded_Packages>\n\t\t\t\t\t\t<Excluded_Packages Name=\"$(BDSBIN)\\dclofficexp120.bpl\">Microsoft Office XP Sample Automation Server Wrapper Components</Excluded_Packages>\n\t\t\t\t\t</Excluded_Packages>\n\t\t\t\t</Delphi.Personality>\n\t\t\t\t<Platforms>\n\t\t\t\t\t<Platform value=\"Win32\">True</Platform>\n\t\t\t\t</Platforms>\n\t\t\t</BorlandProject>\n\t\t\t<ProjectFileVersion>12</ProjectFileVersion>\n\t\t</ProjectExtensions>\n\t</Project>\n"
  },
  {
    "path": "lib/zeosdbo/packages/DelphiXE/ZPackages.inc",
    "content": "{$IFDEF FREEBSD}\n  {$DEFINE UNIX}\n{$ENDIF}\n\n{$IFDEF LINUX}\n  {$DEFINE UNIX}\n{$ENDIF}\n\n{$IFNDEF UNIX}\n{$I ..\\..\\src\\Zeos.inc}\n{$ELSE}\n{$I ../../src/Zeos.inc}\n{$ENDIF}\n"
  },
  {
    "path": "lib/zeosdbo/packages/DelphiXE/ZParseSql.dpk",
    "content": "package ZParseSql;\n{$R *.res}\n{$ALIGN 8}\n{$ASSERTIONS ON}\n{$BOOLEVAL OFF}\n{$DEBUGINFO ON}\n{$EXTENDEDSYNTAX ON}\n{$IMPORTEDDATA ON}\n{$IOCHECKS ON}\n{$LOCALSYMBOLS ON}\n{$LONGSTRINGS ON}\n{$OPENSTRINGS ON}\n{$OPTIMIZATION ON}\n{$OVERFLOWCHECKS ON}\n{$RANGECHECKS OFF}\n{$REFERENCEINFO ON}\n{$SAFEDIVIDE OFF}\n{$STACKFRAMES ON}\n{$TYPEDADDRESS OFF}\n{$VARSTRINGCHECKS ON}\n{$WRITEABLECONST OFF}\n{$MINENUMSIZE 1}\n{$IMAGEBASE $400000}\n{$DESCRIPTION 'Zeos SQL Parsing Classes and Interfaces'}\n{$LIBSUFFIX '150'}\n{$RUNONLY}\n{$IMPLICITBUILD OFF}\n{$I ZPackages.inc}\n\nrequires\n  ZCore;\n\ncontains\n\n{$IFDEF ENABLE_ADO}\n  ZAdoToken in '..\\..\\src\\parsesql\\ZAdoToken.pas',\n{$ENDIF}\n\n{$IFDEF ENABLE_INTERBASE}\n  ZInterbaseAnalyser in '..\\..\\src\\parsesql\\ZInterbaseAnalyser.pas',\n  ZInterbaseToken in '..\\..\\src\\parsesql\\ZInterbaseToken.pas',\n{$ENDIF}\n\n{$IFDEF ENABLE_MYSQL}\n  ZMySqlAnalyser in '..\\..\\src\\parsesql\\ZMySqlAnalyser.pas',\n  ZMySqlToken in '..\\..\\src\\parsesql\\ZMySqlToken.pas',\n{$ENDIF}\n\n{$IFDEF ENABLE_POSTGRESQL}\n  ZPostgreSqlAnalyser in '..\\..\\src\\parsesql\\ZPostgreSqlAnalyser.pas',\n  ZPostgreSqlToken in '..\\..\\src\\parsesql\\ZPostgreSqlToken.pas',\n{$ENDIF}\n\n{$IFDEF ENABLE_DBLIB}\n  ZSybaseAnalyser in '..\\..\\src\\parsesql\\ZSybaseAnalyser.pas',\n  ZSybaseToken in '..\\..\\src\\parsesql\\ZSybaseToken.pas',\n{$ENDIF}\n\n{$IFDEF ENABLE_ORACLE}\n  ZOracleToken in '..\\..\\src\\parsesql\\ZOracleToken.pas',\n  ZOracleAnalyser in '..\\..\\src\\parsesql\\ZOracleAnalyser.pas',\n{$ENDIF}\n\n{$IFDEF ENABLE_SQLITE}\n  ZSqLiteToken in '..\\..\\src\\parsesql\\ZSqLiteToken.pas',\n  ZSqLiteAnalyser in '..\\..\\src\\parsesql\\ZSqLiteAnalyser.pas',\n{$ENDIF}\n\n  ZGenericSqlToken in '..\\..\\src\\parsesql\\ZGenericSqlToken.pas',\n  ZGenericSqlAnalyser in '..\\..\\src\\parsesql\\ZGenericSqlAnalyser.pas',\n  ZScriptParser in '..\\..\\src\\parsesql\\ZScriptParser.pas',\n  ZSelectSchema in '..\\..\\src\\parsesql\\ZSelectSchema.pas';\n\nend.\n"
  },
  {
    "path": "lib/zeosdbo/packages/DelphiXE/ZParseSql.dproj",
    "content": "﻿\t<Project xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n\t\t<PropertyGroup>\n\t\t\t<ProjectGuid>{39c78988-998b-49f3-8023-aaa95d43cffd}</ProjectGuid>\n\t\t\t<MainSource>ZParseSql.dpk</MainSource>\n\t\t\t<Configuration Condition=\" '$(Configuration)' == '' \">Debug</Configuration>\n\t\t\t<DCC_DCCCompiler>DCC32</DCC_DCCCompiler>\n\t\t\t<DCC_DependencyCheckOutputName>C:\\Documents and Settings\\All Users\\Documentos\\RAD Studio\\5.0\\Bpl\\ZParseSql110.bpl</DCC_DependencyCheckOutputName>\n\t\t\t<ProjectVersion>12.3</ProjectVersion>\n\t\t\t<Config Condition=\"'$(Config)'==''\">Debug</Config>\n\t\t\t<Base>True</Base>\n\t\t\t<Platform>Win32</Platform>\n\t\t\t<AppType>Package</AppType>\n\t\t\t<FrameworkType>None</FrameworkType>\n\t\t</PropertyGroup>\n\t\t<PropertyGroup Condition=\"'$(Config)'=='Base' or '$(Base)'!=''\">\n\t\t\t<Base>true</Base>\n\t\t</PropertyGroup>\n\t\t<PropertyGroup Condition=\"'$(Config)'=='Release' or '$(Cfg_1)'!=''\">\n\t\t\t<Cfg_1>true</Cfg_1>\n\t\t\t<CfgParent>Base</CfgParent>\n\t\t\t<Base>true</Base>\n\t\t</PropertyGroup>\n\t\t<PropertyGroup Condition=\"'$(Config)'=='Debug' or '$(Cfg_2)'!=''\">\n\t\t\t<Cfg_2>true</Cfg_2>\n\t\t\t<CfgParent>Base</CfgParent>\n\t\t\t<Base>true</Base>\n\t\t</PropertyGroup>\n\t\t<PropertyGroup Condition=\"'$(Base)'!=''\">\n\t\t\t<DCC_UnitAlias>WinTypes=Windows;WinProcs=Windows;DbiTypes=BDE;DbiProcs=BDE;DbiErrs=BDE;$(DCC_UnitAlias)</DCC_UnitAlias>\n\t\t\t<DCC_UnitSearchPath>build;$(DCC_UnitSearchPath)</DCC_UnitSearchPath>\n\t\t\t<DCC_DcuOutput>build</DCC_DcuOutput>\n\t\t\t<DCC_BplOutput>$(BDSCOMMONDIR)\\Bpl</DCC_BplOutput>\n\t\t\t<DCC_DcpOutput>$(BDSCOMMONDIR)\\Dcp</DCC_DcpOutput>\n\t\t\t<DCC_ImageBase>00400000</DCC_ImageBase>\n\t\t\t<DllSuffix>150</DllSuffix>\n\t\t\t<DCC_Description>Zeos SQL Parsing Classes and Interfaces</DCC_Description>\n\t\t\t<RuntimeOnlyPackage>true</RuntimeOnlyPackage>\n\t\t\t<DCC_DependencyCheckOutputName>build\\ZParseSql150.bpl</DCC_DependencyCheckOutputName>\n\t\t\t<DCC_IntegerOverflowCheck>true</DCC_IntegerOverflowCheck>\n\t\t\t<DCC_OutputNeverBuildDcps>true</DCC_OutputNeverBuildDcps>\n\t\t\t<GenDll>true</GenDll>\n\t\t\t<DCC_GenerateStackFrames>true</DCC_GenerateStackFrames>\n\t\t\t<GenPackage>true</GenPackage>\n\t\t</PropertyGroup>\n\t\t<PropertyGroup Condition=\"'$(Cfg_1)'!=''\">\n\t\t\t<Version>7.0</Version>\n\t\t\t<DCC_DebugInformation>False</DCC_DebugInformation>\n\t\t\t<DCC_LocalDebugSymbols>False</DCC_LocalDebugSymbols>\n\t\t\t<DCC_IntegerOverflowCheck>True</DCC_IntegerOverflowCheck>\n\t\t\t<DCC_GenerateStackFrames>True</DCC_GenerateStackFrames>\n\t\t\t<DCC_SymbolReferenceInfo>0</DCC_SymbolReferenceInfo>\n\t\t\t<DCC_ObjOutput>build</DCC_ObjOutput>\n\t\t\t<DCC_HppOutput>build</DCC_HppOutput>\n\t\t\t<DCC_Define>RELEASE;$(DCC_Define)</DCC_Define>\n\t\t\t<DCC_ResourcePath>$(BDSCOMMONDIR)\\Bpl;$(DCC_ResourcePath)</DCC_ResourcePath>\n\t\t\t<DCC_ObjPath>$(BDSCOMMONDIR)\\Bpl;$(DCC_ObjPath)</DCC_ObjPath>\n\t\t\t<DCC_IncludePath>$(BDSCOMMONDIR)\\Bpl;$(DCC_IncludePath)</DCC_IncludePath>\n\t\t</PropertyGroup>\n\t\t<PropertyGroup Condition=\"'$(Cfg_2)'!=''\">\n\t\t\t<DCC_Define>DEBUG;$(DCC_Define)</DCC_Define>\n\t\t\t<Version>7.0</Version>\n\t\t\t<DCC_IntegerOverflowCheck>True</DCC_IntegerOverflowCheck>\n\t\t\t<DCC_GenerateStackFrames>True</DCC_GenerateStackFrames>\n\t\t\t<DCC_ObjOutput>build</DCC_ObjOutput>\n\t\t\t<DCC_HppOutput>build</DCC_HppOutput>\n\t\t\t<DCC_ResourcePath>$(BDSCOMMONDIR)\\Bpl;$(DCC_ResourcePath)</DCC_ResourcePath>\n\t\t\t<DCC_ObjPath>$(BDSCOMMONDIR)\\Bpl;$(DCC_ObjPath)</DCC_ObjPath>\n\t\t\t<DCC_IncludePath>$(BDSCOMMONDIR)\\Bpl;$(DCC_IncludePath)</DCC_IncludePath>\n\t\t</PropertyGroup>\n\t\t<ItemGroup>\n\t\t\t<DelphiCompile Include=\"ZParseSql.dpk\">\n\t\t\t\t<MainSource>MainSource</MainSource>\n\t\t\t</DelphiCompile>\n\t\t\t<DCCReference Include=\"ZCore.dcp\"/>\n\t\t\t<DCCReference Include=\"..\\..\\src\\parsesql\\ZGenericSqlToken.pas\"/>\n\t\t\t<DCCReference Include=\"..\\..\\src\\parsesql\\ZGenericSqlAnalyser.pas\"/>\n\t\t\t<DCCReference Include=\"..\\..\\src\\parsesql\\ZScriptParser.pas\"/>\n\t\t\t<DCCReference Include=\"..\\..\\src\\parsesql\\ZSelectSchema.pas\"/>\n\t\t\t<BuildConfiguration Include=\"Debug\">\n\t\t\t\t<Key>Cfg_2</Key>\n\t\t\t\t<CfgParent>Base</CfgParent>\n\t\t\t</BuildConfiguration>\n\t\t\t<BuildConfiguration Include=\"Base\">\n\t\t\t\t<Key>Base</Key>\n\t\t\t</BuildConfiguration>\n\t\t\t<BuildConfiguration Include=\"Release\">\n\t\t\t\t<Key>Cfg_1</Key>\n\t\t\t\t<CfgParent>Base</CfgParent>\n\t\t\t</BuildConfiguration>\n\t\t</ItemGroup>\n\t\t<Import Condition=\"Exists('$(BDS)\\Bin\\CodeGear.Delphi.Targets')\" Project=\"$(BDS)\\Bin\\CodeGear.Delphi.Targets\"/>\n\t\t<Import Condition=\"Exists('$(APPDATA)\\Embarcadero\\$(BDSAPPDATABASEDIR)\\$(PRODUCTVERSION)\\UserTools.proj')\" Project=\"$(APPDATA)\\Embarcadero\\$(BDSAPPDATABASEDIR)\\$(PRODUCTVERSION)\\UserTools.proj\"/>\n\t\t<ProjectExtensions>\n\t\t\t<Borland.Personality>Delphi.Personality.12</Borland.Personality>\n\t\t\t<Borland.ProjectType>Package</Borland.ProjectType>\n\t\t\t<BorlandProject>\n\t\t\t\t<Delphi.Personality>\n\t\t\t\t\t<Parameters/>\n\t\t\t\t\t<VersionInfo>\n\t\t\t\t\t\t<VersionInfo Name=\"IncludeVerInfo\">True</VersionInfo>\n\t\t\t\t\t\t<VersionInfo Name=\"AutoIncBuild\">False</VersionInfo>\n\t\t\t\t\t\t<VersionInfo Name=\"MajorVer\">1</VersionInfo>\n\t\t\t\t\t\t<VersionInfo Name=\"MinorVer\">0</VersionInfo>\n\t\t\t\t\t\t<VersionInfo Name=\"Release\">0</VersionInfo>\n\t\t\t\t\t\t<VersionInfo Name=\"Build\">0</VersionInfo>\n\t\t\t\t\t\t<VersionInfo Name=\"Debug\">False</VersionInfo>\n\t\t\t\t\t\t<VersionInfo Name=\"PreRelease\">False</VersionInfo>\n\t\t\t\t\t\t<VersionInfo Name=\"Special\">False</VersionInfo>\n\t\t\t\t\t\t<VersionInfo Name=\"Private\">False</VersionInfo>\n\t\t\t\t\t\t<VersionInfo Name=\"DLL\">False</VersionInfo>\n\t\t\t\t\t\t<VersionInfo Name=\"Locale\">1031</VersionInfo>\n\t\t\t\t\t\t<VersionInfo Name=\"CodePage\">1252</VersionInfo>\n\t\t\t\t\t</VersionInfo>\n\t\t\t\t\t<VersionInfoKeys>\n\t\t\t\t\t\t<VersionInfoKeys Name=\"CompanyName\"/>\n\t\t\t\t\t\t<VersionInfoKeys Name=\"FileDescription\"/>\n\t\t\t\t\t\t<VersionInfoKeys Name=\"FileVersion\">1.0.0.0</VersionInfoKeys>\n\t\t\t\t\t\t<VersionInfoKeys Name=\"InternalName\"/>\n\t\t\t\t\t\t<VersionInfoKeys Name=\"LegalCopyright\"/>\n\t\t\t\t\t\t<VersionInfoKeys Name=\"LegalTrademarks\"/>\n\t\t\t\t\t\t<VersionInfoKeys Name=\"OriginalFilename\"/>\n\t\t\t\t\t\t<VersionInfoKeys Name=\"ProductName\"/>\n\t\t\t\t\t\t<VersionInfoKeys Name=\"ProductVersion\">1.0.0.0</VersionInfoKeys>\n\t\t\t\t\t\t<VersionInfoKeys Name=\"Comments\"/>\n\t\t\t\t\t</VersionInfoKeys>\n\t\t\t\t\t<Source>\n\t\t\t\t\t\t<Source Name=\"MainSource\">ZParseSql.dpk</Source>\n\t\t\t\t\t</Source>\n\t\t\t\t</Delphi.Personality>\n\t\t\t\t<Platforms>\n\t\t\t\t\t<Platform value=\"Win32\">True</Platform>\n\t\t\t\t</Platforms>\n\t\t\t</BorlandProject>\n\t\t\t<ProjectFileVersion>12</ProjectFileVersion>\n\t\t</ProjectExtensions>\n\t</Project>\n"
  },
  {
    "path": "lib/zeosdbo/packages/DelphiXE/ZPlain.dpk",
    "content": "package ZPlain;\n{$R *.res}\n{$ALIGN 8}\n{$ASSERTIONS ON}\n{$BOOLEVAL OFF}\n{$DEBUGINFO ON}\n{$EXTENDEDSYNTAX ON}\n{$IMPORTEDDATA ON}\n{$IOCHECKS ON}\n{$LOCALSYMBOLS ON}\n{$LONGSTRINGS ON}\n{$OPENSTRINGS ON}\n{$OPTIMIZATION OFF}\n{$OVERFLOWCHECKS ON}\n{$RANGECHECKS ON}\n{$REFERENCEINFO ON}\n{$SAFEDIVIDE OFF}\n{$STACKFRAMES ON}\n{$TYPEDADDRESS OFF}\n{$VARSTRINGCHECKS ON}\n{$WRITEABLECONST OFF}\n{$MINENUMSIZE 1}\n{$IMAGEBASE $400000}\n{$DESCRIPTION 'Zeos Plain Database API'}\n{$LIBSUFFIX '150'}\n{$RUNONLY}\n{$IMPLICITBUILD OFF}\n{$I ZPackages.inc}\n\nrequires\n  ZCore,\n  rtl,\n  vcl;\n\ncontains\n{$IFDEF ENABLE_DBLIB}\n  ZPlainDbLibDriver in '..\\..\\src\\plain\\ZPlainDbLibDriver.pas',\n  ZPlainDbLibConstants in '..\\..\\src\\plain\\ZPlainDbLibConstants.pas',\n{$ENDIF}\n\n{$IFDEF ENABLE_INTERBASE}\n  ZPlainFirebirdDriver in '..\\..\\src\\plain\\ZPlainFirebirdDriver.pas',\n  ZPlainFirebirdInterbaseConstants in '..\\..\\src\\plain\\ZPlainFirebirdInterbaseConstants.pas',\n{$ENDIF}\n\n{$IFDEF ENABLE_MYSQL}\n  ZPlainMySqlDriver in '..\\..\\src\\plain\\ZPlainMySqlDriver.pas',\n  ZPlainMySqlConstants in '..\\..\\src\\plain\\ZPlainMySqlConstants.pas',\n{$ENDIF}\n\n{$IFDEF ENABLE_POSTGRESQL}\n  ZPlainPostgreSqlDriver in '..\\..\\src\\plain\\ZPlainPostgreSqlDriver.pas',\n{$ENDIF}\n\n{$IFDEF ENABLE_ADO}\n  ZPlainAdoDriver in '..\\..\\src\\plain\\ZPlainAdoDriver.pas',\n  ZPlainAdo in '..\\..\\src\\plain\\ZPlainAdo.pas',\n{$ENDIF}\n\n{$IFDEF ENABLE_ORACLE}\n  ZPlainOracleDriver in '..\\..\\src\\plain\\ZPlainOracleDriver.pas',\n  ZPlainOracleConstants in '..\\..\\src\\plain\\ZPlainOracleConstants.pas',\n{$ENDIF}\n\n{$IFDEF ENABLE_SQLITE}\n  ZPlainSqLiteDriver in '..\\..\\src\\plain\\ZPlainSqLiteDriver.pas',\n{$ENDIF}\n\n{$IFDEF ENABLE_ASA}\n  ZPlainASADriver in '..\\..\\src\\plain\\ZPlainASADriver.pas',\n  ZPlainASAConstants in '..\\..\\src\\plain\\ZPlainASAConstants.pas',\n{$ENDIF}\n\n  ZPlainDriver in '..\\..\\src\\plain\\ZPlainDriver.pas',\n  ZPlainLoader in '..\\..\\src\\plain\\ZPlainLoader.pas';\nend.\n"
  },
  {
    "path": "lib/zeosdbo/packages/DelphiXE/ZPlain.dproj",
    "content": "﻿\t<Project xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n\t\t<PropertyGroup>\n\t\t\t<ProjectGuid>{839de593-a9a2-4848-98f6-2cab1973ee45}</ProjectGuid>\n\t\t\t<MainSource>ZPlain.dpk</MainSource>\n\t\t\t<Configuration Condition=\" '$(Configuration)' == '' \">Debug</Configuration>\n\t\t\t<DCC_DCCCompiler>DCC32</DCC_DCCCompiler>\n\t\t\t<DCC_DependencyCheckOutputName>C:\\Documents and Settings\\All Users\\Documentos\\RAD Studio\\5.0\\Bpl\\ZPlain110.bpl</DCC_DependencyCheckOutputName>\n\t\t\t<ProjectVersion>12.3</ProjectVersion>\n\t\t\t<Config Condition=\"'$(Config)'==''\">Debug</Config>\n\t\t\t<Base>True</Base>\n\t\t\t<Platform>Win32</Platform>\n\t\t\t<AppType>Package</AppType>\n\t\t\t<FrameworkType>VCL</FrameworkType>\n\t\t</PropertyGroup>\n\t\t<PropertyGroup Condition=\"'$(Config)'=='Base' or '$(Base)'!=''\">\n\t\t\t<Base>true</Base>\n\t\t</PropertyGroup>\n\t\t<PropertyGroup Condition=\"'$(Config)'=='Release' or '$(Cfg_1)'!=''\">\n\t\t\t<Cfg_1>true</Cfg_1>\n\t\t\t<CfgParent>Base</CfgParent>\n\t\t\t<Base>true</Base>\n\t\t</PropertyGroup>\n\t\t<PropertyGroup Condition=\"'$(Config)'=='Debug' or '$(Cfg_2)'!=''\">\n\t\t\t<Cfg_2>true</Cfg_2>\n\t\t\t<CfgParent>Base</CfgParent>\n\t\t\t<Base>true</Base>\n\t\t</PropertyGroup>\n\t\t<PropertyGroup Condition=\"'$(Base)'!=''\">\n\t\t\t<DCC_UnitAlias>WinTypes=Windows;WinProcs=Windows;DbiTypes=BDE;DbiProcs=BDE;DbiErrs=BDE;$(DCC_UnitAlias)</DCC_UnitAlias>\n\t\t\t<DCC_BplOutput>$(BDSCOMMONDIR)\\Bpl</DCC_BplOutput>\n\t\t\t<DCC_DcuOutput>build</DCC_DcuOutput>\n\t\t\t<DCC_UnitSearchPath>build;$(DCC_UnitSearchPath)</DCC_UnitSearchPath>\n\t\t\t<DCC_DcpOutput>$(BDSCOMMONDIR)\\Dcp</DCC_DcpOutput>\n\t\t\t<DCC_DependencyCheckOutputName>build\\ZPlain150.bpl</DCC_DependencyCheckOutputName>\n\t\t\t<DCC_ImageBase>00400000</DCC_ImageBase>\n\t\t\t<RuntimeOnlyPackage>true</RuntimeOnlyPackage>\n\t\t\t<DCC_RangeChecking>true</DCC_RangeChecking>\n\t\t\t<DCC_Optimize>false</DCC_Optimize>\n\t\t\t<DCC_Description>Zeos Plain Database API</DCC_Description>\n\t\t\t<DCC_IntegerOverflowCheck>true</DCC_IntegerOverflowCheck>\n\t\t\t<DCC_OutputNeverBuildDcps>true</DCC_OutputNeverBuildDcps>\n\t\t\t<GenDll>true</GenDll>\n\t\t\t<GenPackage>true</GenPackage>\n\t\t\t<DllSuffix>150</DllSuffix>\n\t\t\t<DCC_GenerateStackFrames>true</DCC_GenerateStackFrames>\n\t\t</PropertyGroup>\n\t\t<PropertyGroup Condition=\"'$(Cfg_1)'!=''\">\n\t\t\t<Version>7.0</Version>\n\t\t\t<DCC_DebugInformation>False</DCC_DebugInformation>\n\t\t\t<DCC_LocalDebugSymbols>False</DCC_LocalDebugSymbols>\n\t\t\t<DCC_Optimize>False</DCC_Optimize>\n\t\t\t<DCC_IntegerOverflowCheck>True</DCC_IntegerOverflowCheck>\n\t\t\t<DCC_RangeChecking>True</DCC_RangeChecking>\n\t\t\t<DCC_GenerateStackFrames>True</DCC_GenerateStackFrames>\n\t\t\t<DCC_SymbolReferenceInfo>0</DCC_SymbolReferenceInfo>\n\t\t\t<DCC_MapFile>3</DCC_MapFile>\n\t\t\t<DCC_ObjOutput>build</DCC_ObjOutput>\n\t\t\t<DCC_HppOutput>build</DCC_HppOutput>\n\t\t\t<DCC_Define>RELEASE;$(DCC_Define)</DCC_Define>\n\t\t\t<DCC_ResourcePath>$(BDSCOMMONDIR)\\Bpl;$(DCC_ResourcePath)</DCC_ResourcePath>\n\t\t\t<DCC_ObjPath>$(BDSCOMMONDIR)\\Bpl;$(DCC_ObjPath)</DCC_ObjPath>\n\t\t\t<DCC_IncludePath>$(BDSCOMMONDIR)\\Bpl;$(DCC_IncludePath)</DCC_IncludePath>\n\t\t</PropertyGroup>\n\t\t<PropertyGroup Condition=\"'$(Cfg_2)'!=''\">\n\t\t\t<DCC_Define>DEBUG;$(DCC_Define)</DCC_Define>\n\t\t\t<Version>7.0</Version>\n\t\t\t<DCC_Optimize>False</DCC_Optimize>\n\t\t\t<DCC_IntegerOverflowCheck>True</DCC_IntegerOverflowCheck>\n\t\t\t<DCC_RangeChecking>True</DCC_RangeChecking>\n\t\t\t<DCC_GenerateStackFrames>True</DCC_GenerateStackFrames>\n\t\t\t<DCC_MapFile>3</DCC_MapFile>\n\t\t\t<DCC_ObjOutput>build</DCC_ObjOutput>\n\t\t\t<DCC_HppOutput>build</DCC_HppOutput>\n\t\t\t<DCC_ResourcePath>$(BDSCOMMONDIR)\\Bpl;$(DCC_ResourcePath)</DCC_ResourcePath>\n\t\t\t<DCC_ObjPath>$(BDSCOMMONDIR)\\Bpl;$(DCC_ObjPath)</DCC_ObjPath>\n\t\t\t<DCC_IncludePath>$(BDSCOMMONDIR)\\Bpl;$(DCC_IncludePath)</DCC_IncludePath>\n\t\t</PropertyGroup>\n\t\t<ItemGroup>\n\t\t\t<DelphiCompile Include=\"ZPlain.dpk\">\n\t\t\t\t<MainSource>MainSource</MainSource>\n\t\t\t</DelphiCompile>\n\t\t\t<DCCReference Include=\"ZCore.dcp\"/>\n\t\t\t<DCCReference Include=\"rtl.dcp\"/>\n\t\t\t<DCCReference Include=\"vcl.dcp\"/>\n\t\t\t<DCCReference Include=\"..\\..\\src\\plain\\ZPlainDriver.pas\"/>\n\t\t\t<DCCReference Include=\"..\\..\\src\\plain\\ZPlainLoader.pas\"/>\n\t\t\t<BuildConfiguration Include=\"Debug\">\n\t\t\t\t<Key>Cfg_2</Key>\n\t\t\t\t<CfgParent>Base</CfgParent>\n\t\t\t</BuildConfiguration>\n\t\t\t<BuildConfiguration Include=\"Base\">\n\t\t\t\t<Key>Base</Key>\n\t\t\t</BuildConfiguration>\n\t\t\t<BuildConfiguration Include=\"Release\">\n\t\t\t\t<Key>Cfg_1</Key>\n\t\t\t\t<CfgParent>Base</CfgParent>\n\t\t\t</BuildConfiguration>\n\t\t</ItemGroup>\n\t\t<Import Condition=\"Exists('$(BDS)\\Bin\\CodeGear.Delphi.Targets')\" Project=\"$(BDS)\\Bin\\CodeGear.Delphi.Targets\"/>\n\t\t<Import Condition=\"Exists('$(APPDATA)\\Embarcadero\\$(BDSAPPDATABASEDIR)\\$(PRODUCTVERSION)\\UserTools.proj')\" Project=\"$(APPDATA)\\Embarcadero\\$(BDSAPPDATABASEDIR)\\$(PRODUCTVERSION)\\UserTools.proj\"/>\n\t\t<ProjectExtensions>\n\t\t\t<Borland.Personality>Delphi.Personality.12</Borland.Personality>\n\t\t\t<Borland.ProjectType>Package</Borland.ProjectType>\n\t\t\t<BorlandProject>\n\t\t\t\t<Delphi.Personality>\n\t\t\t\t\t<Parameters/>\n\t\t\t\t\t<VersionInfo>\n\t\t\t\t\t\t<VersionInfo Name=\"IncludeVerInfo\">True</VersionInfo>\n\t\t\t\t\t\t<VersionInfo Name=\"AutoIncBuild\">False</VersionInfo>\n\t\t\t\t\t\t<VersionInfo Name=\"MajorVer\">1</VersionInfo>\n\t\t\t\t\t\t<VersionInfo Name=\"MinorVer\">0</VersionInfo>\n\t\t\t\t\t\t<VersionInfo Name=\"Release\">0</VersionInfo>\n\t\t\t\t\t\t<VersionInfo Name=\"Build\">0</VersionInfo>\n\t\t\t\t\t\t<VersionInfo Name=\"Debug\">False</VersionInfo>\n\t\t\t\t\t\t<VersionInfo Name=\"PreRelease\">False</VersionInfo>\n\t\t\t\t\t\t<VersionInfo Name=\"Special\">False</VersionInfo>\n\t\t\t\t\t\t<VersionInfo Name=\"Private\">False</VersionInfo>\n\t\t\t\t\t\t<VersionInfo Name=\"DLL\">False</VersionInfo>\n\t\t\t\t\t\t<VersionInfo Name=\"Locale\">1031</VersionInfo>\n\t\t\t\t\t\t<VersionInfo Name=\"CodePage\">1252</VersionInfo>\n\t\t\t\t\t</VersionInfo>\n\t\t\t\t\t<VersionInfoKeys>\n\t\t\t\t\t\t<VersionInfoKeys Name=\"FileVersion\">1.0.0.0</VersionInfoKeys>\n\t\t\t\t\t\t<VersionInfoKeys Name=\"ProductVersion\">1.0.0.0</VersionInfoKeys>\n\t\t\t\t\t\t<VersionInfoKeys Name=\"CompanyName\"/>\n\t\t\t\t\t\t<VersionInfoKeys Name=\"FileDescription\"/>\n\t\t\t\t\t\t<VersionInfoKeys Name=\"InternalName\"/>\n\t\t\t\t\t\t<VersionInfoKeys Name=\"LegalCopyright\"/>\n\t\t\t\t\t\t<VersionInfoKeys Name=\"LegalTrademarks\"/>\n\t\t\t\t\t\t<VersionInfoKeys Name=\"OriginalFilename\"/>\n\t\t\t\t\t\t<VersionInfoKeys Name=\"ProductName\"/>\n\t\t\t\t\t</VersionInfoKeys>\n\t\t\t\t\t<Source>\n\t\t\t\t\t\t<Source Name=\"MainSource\">ZPlain.dpk</Source>\n\t\t\t\t\t</Source>\n\t\t\t\t</Delphi.Personality>\n\t\t\t\t<Platforms>\n\t\t\t\t\t<Platform value=\"Win32\">True</Platform>\n\t\t\t\t</Platforms>\n\t\t\t</BorlandProject>\n\t\t\t<ProjectFileVersion>12</ProjectFileVersion>\n\t\t</ProjectExtensions>\n\t</Project>\n"
  },
  {
    "path": "lib/zeosdbo/packages/DelphiXE/ZeosDbo.groupproj",
    "content": "﻿<Project xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n  <PropertyGroup>\n    <ProjectGuid>{6c337a05-41a2-4a84-b176-c57f5e15e0c9}</ProjectGuid>\n  </PropertyGroup>\n\t\t<ItemGroup>\n\t\t\t<Projects Include=\"ZCore.dproj\">\n\t\t\t\t<Dependencies/>\n\t\t\t</Projects>\n\t\t\t<Projects Include=\"ZPlain.dproj\">\n\t\t\t\t<Dependencies/>\n\t\t\t</Projects>\n\t\t\t<Projects Include=\"ZParseSql.dproj\">\n\t\t\t\t<Dependencies/>\n\t\t\t</Projects>\n\t\t\t<Projects Include=\"ZDbc.dproj\">\n\t\t\t\t<Dependencies/>\n\t\t\t</Projects>\n\t\t\t<Projects Include=\"ZComponent.dproj\">\n\t\t\t\t<Dependencies/>\n\t\t\t</Projects>\n\t\t\t<Projects Include=\"ZComponentDesign.dproj\">\n\t\t\t\t<Dependencies/>\n\t\t\t</Projects>\n\t\t</ItemGroup>\n  <ProjectExtensions>\n\t\t\t<Borland.Personality>Default.Personality.12</Borland.Personality>\n    <Borland.ProjectType />\n    <BorlandProject>\n\t\t\t\t<BorlandProject>\n\t\t\t\t\t<Default.Personality/>\n\t\t\t\t</BorlandProject>\n\t\t\t</BorlandProject>\n  </ProjectExtensions>\n  <Target Name=\"ZCore\">\n\t\t\t<MSBuild Projects=\"ZCore.dproj\"/>\n  </Target>\n  <Target Name=\"ZCore:Clean\">\n\t\t\t<MSBuild Targets=\"Clean\" Projects=\"ZCore.dproj\"/>\n  </Target>\n  <Target Name=\"ZCore:Make\">\n\t\t\t<MSBuild Targets=\"Make\" Projects=\"ZCore.dproj\"/>\n  </Target>\n  <Target Name=\"ZPlain\">\n\t\t\t<MSBuild Projects=\"ZPlain.dproj\"/>\n  </Target>\n  <Target Name=\"ZPlain:Clean\">\n\t\t\t<MSBuild Targets=\"Clean\" Projects=\"ZPlain.dproj\"/>\n  </Target>\n  <Target Name=\"ZPlain:Make\">\n\t\t\t<MSBuild Targets=\"Make\" Projects=\"ZPlain.dproj\"/>\n  </Target>\n  <Target Name=\"ZParseSql\">\n\t\t\t<MSBuild Projects=\"ZParseSql.dproj\"/>\n  </Target>\n  <Target Name=\"ZParseSql:Clean\">\n\t\t\t<MSBuild Targets=\"Clean\" Projects=\"ZParseSql.dproj\"/>\n  </Target>\n  <Target Name=\"ZParseSql:Make\">\n\t\t\t<MSBuild Targets=\"Make\" Projects=\"ZParseSql.dproj\"/>\n  </Target>\n  <Target Name=\"ZDbc\">\n\t\t\t<MSBuild Projects=\"ZDbc.dproj\"/>\n  </Target>\n  <Target Name=\"ZDbc:Clean\">\n\t\t\t<MSBuild Targets=\"Clean\" Projects=\"ZDbc.dproj\"/>\n  </Target>\n  <Target Name=\"ZDbc:Make\">\n\t\t\t<MSBuild Targets=\"Make\" Projects=\"ZDbc.dproj\"/>\n  </Target>\n  <Target Name=\"ZComponent\">\n\t\t\t<MSBuild Projects=\"ZComponent.dproj\"/>\n  </Target>\n  <Target Name=\"ZComponent:Clean\">\n\t\t\t<MSBuild Targets=\"Clean\" Projects=\"ZComponent.dproj\"/>\n  </Target>\n  <Target Name=\"ZComponent:Make\">\n\t\t\t<MSBuild Targets=\"Make\" Projects=\"ZComponent.dproj\"/>\n  </Target>\n  <Target Name=\"ZComponentDesign\">\n\t\t\t<MSBuild Projects=\"ZComponentDesign.dproj\"/>\n  </Target>\n  <Target Name=\"ZComponentDesign:Clean\">\n\t\t\t<MSBuild Targets=\"Clean\" Projects=\"ZComponentDesign.dproj\"/>\n  </Target>\n  <Target Name=\"ZComponentDesign:Make\">\n\t\t\t<MSBuild Targets=\"Make\" Projects=\"ZComponentDesign.dproj\"/>\n  </Target>\n  <Target Name=\"Build\">\n    <CallTarget Targets=\"ZCore;ZPlain;ZParseSql;ZDbc;ZComponent;ZComponentDesign\" />\n  </Target>\n  <Target Name=\"Clean\">\n    <CallTarget Targets=\"ZCore:Clean;ZPlain:Clean;ZParseSql:Clean;ZDbc:Clean;ZComponent:Clean;ZComponentDesign:Clean\" />\n  </Target>\n  <Target Name=\"Make\">\n    <CallTarget Targets=\"ZCore:Make;ZPlain:Make;ZParseSql:Make;ZDbc:Make;ZComponent:Make;ZComponentDesign:Make\" />\n  </Target>\n\t\t<Import Project=\"$(BDS)\\Bin\\CodeGear.Group.Targets\" Condition=\"Exists('$(BDS)\\Bin\\CodeGear.Group.Targets')\"/>\n</Project>"
  },
  {
    "path": "lib/zeosdbo/packages/DelphiXE/events good.txt",
    "content": "﻿Thread Start: Thread ID: 5176. Process ZSimple.exe (5388)\nProcess Start: F:\\Users\\Mator\\Downloads\\ZEOSDBO-7.1.4-stable\\examples\\simple\\ZSimple.exe. Base Address: $00400000. Process ZSimple.exe (5388)\nModule Load: ZSimple.exe. Has Debug Info. Base Address: $00400000. Process ZSimple.exe (5388)\nModule Load: ntdll.dll. No Debug Info. Base Address: $76FB0000. Process ZSimple.exe (5388)\nModule Load: KERNEL32.dll. No Debug Info. Base Address: $75530000. Process ZSimple.exe (5388)\nModule Load: KERNELBASE.dll. No Debug Info. Base Address: $75910000. Process ZSimple.exe (5388)\nModule Load: OLEAUT32.dll. No Debug Info. Base Address: $76960000. Process ZSimple.exe (5388)\nModule Load: ole32.dll. No Debug Info. Base Address: $751F0000. Process ZSimple.exe (5388)\nModule Load: msvcrt.dll. No Debug Info. Base Address: $749A0000. Process ZSimple.exe (5388)\nModule Load: GDI32.dll. No Debug Info. Base Address: $754A0000. Process ZSimple.exe (5388)\nModule Load: USER32.dll. No Debug Info. Base Address: $74A50000. Process ZSimple.exe (5388)\nModule Load: ADVAPI32.dll. No Debug Info. Base Address: $76B10000. Process ZSimple.exe (5388)\nModule Load: SECHOST.dll. No Debug Info. Base Address: $75990000. Process ZSimple.exe (5388)\nModule Load: RPCRT4.dll. No Debug Info. Base Address: $74DB0000. Process ZSimple.exe (5388)\nModule Load: SspiCli.dll. No Debug Info. Base Address: $74940000. Process ZSimple.exe (5388)\nModule Load: CRYPTBASE.dll. No Debug Info. Base Address: $74930000. Process ZSimple.exe (5388)\nModule Load: LPK.dll. No Debug Info. Base Address: $76AE0000. Process ZSimple.exe (5388)\nModule Load: USP10.dll. No Debug Info. Base Address: $74EC0000. Process ZSimple.exe (5388)\nModule Load: MSIMG32.dll. No Debug Info. Base Address: $6F400000. Process ZSimple.exe (5388)\nModule Load: VERSION.dll. No Debug Info. Base Address: $72BD0000. Process ZSimple.exe (5388)\nModule Load: COMCTL32.dll. No Debug Info. Base Address: $6E180000. Process ZSimple.exe (5388)\nModule Load: WINSPOOL.DRV. No Debug Info. Base Address: $6E760000. Process ZSimple.exe (5388)\nModule Load: apphelp.dll. No Debug Info. Base Address: $6EBC0000. Process ZSimple.exe (5388)\nModule Load: NULL.dll. No Debug Info. Base Address: $672F0000. Process ZSimple.exe (5388)\nModule Load: SHELL32.dll. No Debug Info. Base Address: $75BF0000. Process ZSimple.exe (5388)\nModule Load: SHLWAPI.dll. No Debug Info. Base Address: $76A80000. Process ZSimple.exe (5388)\nModule Load: USERENV.dll. No Debug Info. Base Address: $74D60000. Process ZSimple.exe (5388)\nModule Load: profapi.dll. No Debug Info. Base Address: $769F0000. Process ZSimple.exe (5388)\nModule Load: MPR.dll. No Debug Info. Base Address: $6F3E0000. Process ZSimple.exe (5388)\nModule Load: IMM32.dll. No Debug Info. Base Address: $75B50000. Process ZSimple.exe (5388)\nModule Load: MSCTF.dll. No Debug Info. Base Address: $74B60000. Process ZSimple.exe (5388)\nModule Load: UxTheme.dll. No Debug Info. Base Address: $6D910000. Process ZSimple.exe (5388)\nModule Load: dwmapi.dll. No Debug Info. Base Address: $6EBA0000. Process ZSimple.exe (5388)\nModule Load: COMCTL32.dll. No Debug Info. Base Address: $6F100000. Process ZSimple.exe (5388)\nModule Load: ole32.dll. No Debug Info. Base Address: $058B0000. Process ZSimple.exe (5388)\nModule Unload: ole32.dll. Process ZSimple.exe (5388)\nModule Load: ole32.dll. No Debug Info. Base Address: $05CA0000. Process ZSimple.exe (5388)\nModule Unload: ole32.dll. Process ZSimple.exe (5388)\nModule Load: CLBCatQ.DLL. No Debug Info. Base Address: $75640000. Process ZSimple.exe (5388)\nModule Load: libmysql.dll. No Debug Info. Base Address: $53EB0000. Process ZSimple.exe (5388)\nModule Load: Secur32.dll. No Debug Info. Base Address: $6E210000. Process ZSimple.exe (5388)\nModule Load: WS2_32.dll. No Debug Info. Base Address: $76A00000. Process ZSimple.exe (5388)\nModule Load: NSI.dll. No Debug Info. Base Address: $76A40000. Process ZSimple.exe (5388)\nModule Load: nlaapi.dll. No Debug Info. Base Address: $6E7C0000. Process ZSimple.exe (5388)\nModule Load: NAPINSP.dll. No Debug Info. Base Address: $6ECC0000. Process ZSimple.exe (5388)\nThread Start: Thread ID: 4300. Process ZSimple.exe (5388)\nModule Load: PNRPNSP.dll. No Debug Info. Base Address: $6E520000. Process ZSimple.exe (5388)\nModule Load: MSWSOCK.dll. No Debug Info. Base Address: $6F950000. Process ZSimple.exe (5388)\nModule Load: DNSAPI.dll. No Debug Info. Base Address: $72CD0000. Process ZSimple.exe (5388)\nModule Load: WINRNR.dll. No Debug Info. Base Address: $6E510000. Process ZSimple.exe (5388)\nModule Load: mdnsNSP.dll. No Debug Info. Base Address: $6E540000. Process ZSimple.exe (5388)\nModule Load: IPHLPAPI.DLL. No Debug Info. Base Address: $72C90000. Process ZSimple.exe (5388)\nModule Load: WINNSI.DLL. No Debug Info. Base Address: $72C80000. Process ZSimple.exe (5388)\nModule Load: rasadhlp.dll. No Debug Info. Base Address: $6EB90000. Process ZSimple.exe (5388)\nModule Load: WSHTCPIP.dll. No Debug Info. Base Address: $6F8C0000. Process ZSimple.exe (5388)\nFirst chance exception at $7591C42D. Exception class EZSQLException with message 'SQL Error: Table 'mergeplugins.tsite' doesn't exist'. Process ZSimple.exe (5388)\nThread Start: Thread ID: 4468. Process ZSimple.exe (5388)\nThread Start: Thread ID: 4624. Process ZSimple.exe (5388)\nThread Start: Thread ID: 3592. Process ZSimple.exe (5388)\n"
  },
  {
    "path": "lib/zeosdbo/src/Zeos.inc",
    "content": "{@********************************************************}\n{    Copyright (c) 1999-2012 Zeos Development Group       }\n{                                                         }\n{ License Agreement:                                      }\n{                                                         }\n{ This library is distributed in the hope that it will be }\n{ useful, but WITHOUT ANY WARRANTY; without even the      }\n{ implied warranty of MERCHANTABILITY or FITNESS FOR      }\n{ A PARTICULAR PURPOSE.  See the GNU Lesser General       }\n{ Public License for more details.                        }\n{                                                         }\n{ The source code of the ZEOS Libraries and packages are  }\n{ distributed under the Library GNU General Public        }\n{ License (see the file COPYING / COPYING.ZEOS)           }\n{ with the following  modification:                       }\n{ As a special exception, the copyright holders of this   }\n{ library give you permission to link this library with   }\n{ independent modules to produce an executable,           }\n{ regardless of the license terms of these independent    }\n{ modules, and to copy and distribute the resulting       }\n{ executable under terms of your choice, provided that    }\n{ you also meet, for each linked independent module,      }\n{ the terms and conditions of the license of that module. }\n{ An independent module is a module which is not derived  }\n{ from or based on this library. If you modify this       }\n{ library, you may extend this exception to your version  }\n{ of the library, but you are not obligated to do so.     }\n{ If you do not wish to do so, delete this exception      }\n{ statement from your version.                            }\n{                                                         }\n{                                                         }\n{ The project web site is located on:                     }\n{   http://zeos.firmos.at  (FORUM)                        }\n{   http://sourceforge.net/p/zeoslib/tickets/ (BUGTRACKER)}\n{   svn://svn.code.sf.net/p/zeoslib/code-0/trunk (SVN)    }\n{                                                         }\n{   http://www.sourceforge.net/projects/zeoslib.          }\n{                                                         }\n{                                                         }\n{                                 Zeos Development Group. }\n{********************************************************@}\n// Compilation directives for Lazarus\n{$IFDEF FPC}\n {$I ZeosLazarus.inc}\n{$ELSE}\n {$DEFINE DELPHI}\n  // Defines that go for ALL still supported Delphi's   (usually means they were under ifndef fpc)\n {$DEFINE WITH_DBCONSTS}        // Delphi DBCONSTS, FPC DBCONST\n {$DEFINE WITH_ASLARGEINT}      // tlargeint aslargeint. Fixed 2.6.0+ or 2.6.2+ probably\n {$DEFINE WITH_ASCURRENCY}      // Has AsCurrency.\n {$DEFINE WITH_ASVARIANT}\n {$DEFINE WITH_IPROVIDER}       // Turn on IProviderSupport interface\n {$DEFINE WITH_CHECKFIELDCOMPATIBILITY}\n {$DEFINE WITH_WIDEMEMO}        // Have WIDEMEMO,  For Delphi we turn these off if not applicable\n {$DEFINE WITH_FTWIDESTRING}    // Have ftwidestring, For Delphi we turn these off if not applicable\n {$DEFINE WITH_WIDEFIELDS}\t// Wide-fields are supported (common define for ftWideString/ftWideMemo)\n {$DEFINE WITH_DBTABLES}        // Have the BDE DBTables Unit\n {$DEFINE WITH_INLINE_ANSICOMPARETEXT}\n {$DEFINE WITH_FTDATASETSUPPORT} //ftDataSet is supported\n {$DEFINE WITH_CLASS_VARS}      // Class variables/methods are supported\n {$DEFINE WITH_INLINE}          // compiler supports inline methodes\n {$DEFINE WITH_FTGUID}          // ftGuid is supported (binary 16Bytes)\n {$DEFINE WITH_FUNIDIRECTIONAL} //TDataSet have SetUniDirectional and GetUnidirectional\n{$ENDIF}\n\n// Compilation directives for Delphi4\n// Not supported since Zeoslib 7.X\n{$IFDEF VER120}\n   \"Delphi versions below Delphi 7 aren't supported anymore\"\n{$ENDIF}\n\n// Compilation directives for Delphi 5\n// Not supported since Zeoslib 7.X\n{$IFDEF VER130}\n        \"Delphi versions below Delphi 7 aren't supported anymore\"\n{$ENDIF}\n\n// Compilation directives for Delphi 6\n// Not supported since Zeoslib 7.X\n{$IFDEF VER140}\n    \"Kylix3, CBuilder/Delphi Versions below version 7 aren't supported anymore\"\n{$ENDIF}\n\n// Compilation directives for Delphi 7\n{$IFDEF VER150}\n  {$DEFINE VER150BELOW} // Used in zeos.inc only\n{$ENDIF}\n\n// Compilation directives for Delphi 8\n{$IFDEF VER160}\n  {$DEFINE VER150BELOW} // Used in zeos.inc only\n{$ENDIF}\n\n// Compilation directives for Delphi 9 (DELPHI 2005)\n{$IFDEF VER170}\n// No directives needed\n  {$DEFINE VER150BELOW} // Used in zeos.inc only\n  {$DEFINE VER170BELOW} // Used in Zeos.inc only\n{$ENDIF}\n\n// Compilation directives for BDS 2006 (Delphi 2006, BCB 2006)\n{$IFDEF VER180}\n  {$DEFINE BDS4_UP} // Used in code\n{$ENDIF}\n\n// Compilation directives for Delphi 2007, Delphi .NET 2007\n{$IFDEF VER185}\n  {$DEFINE BDS4_UP} // Used in code\n{$ENDIF}\n\n// Compilation directives for Delphi 2009\n{$IFDEF VER200}\n  {$DEFINE VER200BELOW} // Used in code\n  {$DEFINE DELPHI12_UP} // Used in code\n  {$DEFINE BDS4_UP} // Used in code\n  {$DEFINE BDS5_UP} // Used in code\n  {$DEFINE WITH_INLINE_ANSISTRLCOMP}\n{$ENDIF}\n\n// Compilation directives for Delphi 2010\n{$IFDEF VER210}\n  {$DEFINE VER200BELOW} // Used in code\n  {$DEFINE DELPHI12_UP} // Used in code\n  {$DEFINE DELPHI14_UP} // used in tests only\n  {$DEFINE BDS4_UP} // Used in code\n  {$DEFINE BDS5_UP} // Used in code\n{$ENDIF}\n\n// Compilation directives for Delphi XE\n{$IFDEF VER220}\n  {$DEFINE VER200BELOW} // Used in code\n  {$DEFINE DELPHI12_UP} // Used in code\n  {$DEFINE DELPHI14_UP} // used in tests only\n  {$DEFINE DELPHI15_UP} // Used in zeos.inc only\n  {$DEFINE BDS4_UP} // Used in code\n  {$DEFINE BDS5_UP} // Used in code\n{$ENDIF}\n{$IFDEF LINUX}\n  {$DEFINE UNIX}\n{$ENDIF}\n\n// Compilation directives for Delphi XE2\n{$IFDEF VER230}\n  {$DEFINE VER200BELOW} // Used in code\n  {$DEFINE DELPHI12_UP} // Used in code\n  {$DEFINE DELPHI14_UP} // used in tests only\n  {$DEFINE DELPHI15_UP} // Used in zeos.inc only\n  {$DEFINE DELPHI16_UP} // Used in code\n  {$DEFINE BDS4_UP} // Used in code\n  {$DEFINE BDS5_UP} // Used in code\n{$ENDIF}\n\n// Compilation directives for Delphi XE3\n{$IFDEF VER240}\n  {$DEFINE VER200BELOW} // Used in code\n  {$DEFINE DELPHI12_UP} // Used in code\n  {$DEFINE DELPHI14_UP} // used in tests only\n  {$DEFINE DELPHI15_UP} // Used in zeos.inc only\n  {$DEFINE DELPHI16_UP} // Used in code\n  {$DEFINE DELPHI17_UP} // Used in code\n  {$DEFINE BDS4_UP} // Used in code\n  {$DEFINE BDS5_UP} // Used in code\n{$ENDIF}\n\n// Compilation directives for Delphi XE4\n{$IFDEF VER250}\n  {$DEFINE VER200BELOW} // Used in code\n  {$DEFINE DELPHI12_UP} // Used in code\n  {$DEFINE DELPHI14_UP} // used in tests only\n  {$DEFINE DELPHI15_UP} // Used in zeos.inc only\n  {$DEFINE DELPHI16_UP} // Used in code\n  {$DEFINE DELPHI17_UP} // Used in zeos.inc only\n  {$DEFINE DELPHI18_UP} // Used in zeos.inc only\n  {$DEFINE BDS4_UP} // Used in code\n  {$DEFINE BDS5_UP} // Used in code\n{$ENDIF}\n\n// Compilation directives for Delphi XE5\n{$IFDEF VER260}\n  {$DEFINE VER200BELOW} // Used in code\n  {$DEFINE DELPHI12_UP} // Used in code\n  {$DEFINE DELPHI14_UP} // used in tests only\n  {$DEFINE DELPHI15_UP} // Used in zeos.inc only\n  {$DEFINE DELPHI16_UP} // Used in code\n  {$DEFINE DELPHI17_UP} // Used in zeos.inc only\n  {$DEFINE DELPHI18_UP} // Used in zeos.inc only\n  {$DEFINE DELPHI19_UP}\n  {$DEFINE BDS4_UP} // Used in code\n  {$DEFINE BDS5_UP} // Used in code\n{$ENDIF}\n\n// Compilation directives for Delphi XE6 by dieletro\n{$IFDEF VER270}\n  {$DEFINE VER200BELOW} // Used in code\n  {$DEFINE DELPHI12_UP} // Used in code\n  {$DEFINE DELPHI14_UP} // used in tests only\n  {$DEFINE DELPHI15_UP} // Used in zeos.inc only\n  {$DEFINE DELPHI16_UP} // Used in code\n  {$DEFINE DELPHI17_UP} // Used in zeos.inc only\n  {$DEFINE DELPHI18_UP} // Used in zeos.inc only\n  {$DEFINE DELPHI19_UP} // Used in zeos.inc only\n  {$DEFINE DELPHI20_UP} //By dieletro Used in zeos.inc only\n  {$DEFINE BDS4_UP} // Used in code\n  {$DEFINE BDS5_UP} // Used in code\n{$ENDIF}\n\n// Compilation directives for Delphi XE7 by miab3\n{$IFDEF VER280}\n  {$DEFINE VER200BELOW} // Used in code\n  {$DEFINE DELPHI12_UP} // Used in code\n  {$DEFINE DELPHI14_UP} // used in tests only\n  {$DEFINE DELPHI15_UP} // Used in zeos.inc only\n  {$DEFINE DELPHI16_UP} // Used in code\n  {$DEFINE DELPHI17_UP} // Used in zeos.inc only\n  {$DEFINE DELPHI18_UP} // Used in zeos.inc only\n  {$DEFINE DELPHI19_UP} // Used in zeos.inc only\n  {$DEFINE DELPHI20_UP} //By dieletro Used in zeos.inc only\n  {$DEFINE DELPHI21_UP} //Used in zeos.inc only\n  {$DEFINE BDS4_UP} // Used in code\n  {$DEFINE BDS5_UP} // Used in code\n{$ENDIF}\n\n// END of per Delphi version defines\n\n{$IFDEF BDS4_UP}\n  {$DEFINE WITH_WIDESTRINGS_GETFIELDNAMES} //overload of GetFieldNames(List: TWideStrings) does exists;\n  {$DEFINE WIDE_DATASET}                // TWidedataset exists\n  {$DEFINE WITH_PWIDECHAR_TOWIDESTRING} // Able to pass pwidechar to a widestring parameter\n  {$DEFINE WITH_IPROVIDERWIDE}          // IProvider -W widestring using interface\n  {$DEFINE WITH_WIDESTRUTILS}           // WideStrUtils Unit.\n  {$DEFINE WITH_REPORTMEMORYLEAKSONSHUTDOWN} //ReportMemoryLeaksOnShutdown property does exists (testsuites)\n{$ENDIF}\n\n{$IFDEF DELPHI12_UP}\n  {$DEFINE WITH_TBOOKMARK}              // Have TBookmark\n  {$DEFINE WITH_TRECORDBUFFER}          // Abstract buffer type (pansichar or pbyte)\n  {$DEFINE WITH_STSTRINGUNICODE}        // ststring is unicodestring.\n  {$DEFINE WITH_NEWTOBJECT}             // allows new methods in TObject (D2009+/FPC 2.4.4)\n  {$DEFINE WITH_CHARINSET}              // D2009's poor substitute for character specific \"xx in yy\"\n  {$DEFINE WITH_FTSHORTINT}             // ftShortInt is supported\n  {$DEFINE WITH_FTBYTE}                 // ftByte is supported\n  {$DEFINE WITH_FTEXTENDED}             // ftExtended is supported\n  {$DEFINE WITH_FTLONGWORD}             // ftLongWord is supported\n  {$DEFINE WITH_ASBYTES}                //  AsBytes is supported\n  {$DEFINE WITH_RAWBYTESTRING}          // Have RawByteString CP $FFFFF\n  {$DEFINE WITH_DEFAULTSYSTEMCODEPAGE}  // determine the AnsiString CP\n  {$DEFINE WITH_UNITANSISTRINGS}        // Have unit AnsiStrings\n  {$DEFINE WITH_TENCODING_CLASS}        // Have class TEncoding\n  {$UNDEF WITH_IPROVIDERWIDE}           // IProvider -W widestring using interface is deprecated since UNICODE and wo't be called anymore\n  {$DEFINE PWIDECHAR_IS_PUNICODECHAR}   // PWideChar = ^UnicodeString\n{$ENDIF}\n\n{$IFDEF DELPHI14_UP}\n  {$UNDEF WITH_INLINE_ANSICOMPARETEXT}  // AnsiCompareText is no more inline declared\n  {$DEFINE WITH_UINT64}                 // D2010 has virtually UInt64\n  {$DEFINE WITH_PUINT64}                // D2010 has virtually PUInt64\n{$ENDIF}\n\n{$IFDEF DELPHI15_UP}\n  {$DEFINE WITH_FORMATSETTINGS}\n  {$DEFINE WITH_UNICODEFROMLOCALECHARS}\n  {$IFDEF WIN64}\n    {$UNDEF WITH_DBTABLES} //BDE unit DBTables (TestSuites) isn't supported on CPU64\n  {$ENDIF}\n{$ENDIF}\n\n{$IFDEF VER150BELOW}\n  {$UNDEF WITH_WIDEMEMO}\n  {$UNDEF WITH_FTWIDESTRING}    // D7 doesn't support TField.AsWideString\n  {$UNDEF WITH_WIDEFIELDS}      // absolutely no TWide-Fields support\n  {$UNDEF WITH_CLASS_VARS}      // absolutely no Class var/method support\n  {$IFNDEF VER170BELOW} //D2005 supports inline\n    {$UNDEF WITH_INLINE}          // D7 doesn't support inline declarations\n  {$ENDIF}\n  {$DEFINE WITH_MILLISECONDOFTHEYEAR_BUG} //D7-D005 Bug -> a Int64 Cast of SecondOfTheYear(AValue) is missing\n{$ENDIF}\n\n{$IFDEF DELPHI16_UP}\n  {$DEFINE WITH_SYSTEMCLASSES}          //Need System.Classes\n  {$DEFINE WITH_MAXLISTSIZE_DEPRECATED} //Since XE2 64Bit Integer = Int64 this value is deprecated\n  {$DEFINE WITH_VCL_PREFIX}\n{$ENDIF}\n\n{$IFDEF DELPHI17_UP}\n  {$UNDEF WIDE_DATASET}                // TWideDataset and TDataSet are merged together: https://forums.embarcadero.com/thread.jspa?messageID=499588\n  {$DEFINE WITH_TVALUEBUFFER}          // SetFieldData/GetFieldData and Parameters using TValueBuffer instead of Pointer\n  {$DEFINE WITH_BOOKMARKDATA_TBOOKMARK}\n  {$UNDEF WITH_WIDESTRINGS_GETFIELDNAMES} //GetFieldNames with TWideStrings has been removed\n  {$DEFINE WITH_GENERIC_TLISTTFIELD} //GetFieldList() uses the generic TList<TField>\n{$ENDIF}\n\n{$IFDEF DELPHI18_UP}\n  {$DEFINE WITH_VAR_TVALUEBUFFER}\t//GetFieldata overloads using !var! Buffer: TValueBuffer\n  {$DEFINE WITH_BUFFERS_IS_TRECBUF} //Buffers[index] is TRecBuf type NativeInt\n  {$DEFINE WITH_ANSISTRINGPOS_DEPRECATED} //AnsiStringPos deprecated moved to AnsiStrings\n  {$DEFINE WITH_STRLEN_DEPRECATED} //StrLen deprecated moved to AnsiStrings\n  {$DEFINE WITH_TOBJECTLIST_INLINE} //TObjectList.Remove, add ... are inlined \tneed System.Types\n  {$DEFINE WITH_ANSISTRCOMP_DEPRECATED} //AnsiStrComp is deprecated moved to AnsiStrings\n  {$DEFINE WITH_ANSISTRLCOMP_DEPRECATED} //AnsiStrLComp is deprecated moved to AnsiStrings\n  {$DEFINE WITH_STRDISPOSE_DEPRECATED} //StrDispose is deprecated moved to AnsiStrings\n  {$DEFINE WITH_STRNEW_DEPRECATED} //StrNew is deprecated moved to AnsiStrings\n  {$DEFINE WITH_STRCOPY_DEPRECATED} //StrCopy is deprecated moved to AnsiStrings\n  {$DEFINE WITH_STRPCOPY_DEPRECATED} //StrPCopy is deprecated moved to AnsiStrings\n  {$DEFINE WITH_STRPLCOPY_DEPRECATED} //StrPLCopy is deprecated moved to AnsiStrings\n  {$DEFINE WITH_STRLCOPY_DEPRECATED} //StrLCopy is deprecated moved to AnsiStrings\n  {$DEFINE WITH_STRLICOPY_DEPRECATED} //StrLICopy is deprecated moved to AnsiStrings\n  {$DEFINE WITH_STRLICOMP_DEPRECATED} //StrLIComp is deprecated moved to AnsiStrings\n  {$DEFINE WITH_GETCALCFIELDS_TRECBUF} //GetCalcFields expected no TRecordBuffer use TRecBuf type NativeInt instead\n{$ENDIF}\n\n{$IFDEF DELPHI20_UP}\n  {$DEFINE WITH_IPROVIDERSUPPORT_NG} //supports IProviderSupportNG / IProviderSupport is deprecated\n  {$DEFINE TFIELD_HAS_ASLONGWORD} //TField has supports virtual AsLongWord Gettet & Setter \n{$ENDIF}\n\n{$IFDEF DELPHI21_UP}\n  {$UNDEF WITH_DBTABLES} //M.A. In Delphi XE7 no BDE\n{$ENDIF}\n\n{$IFNDEF WIN32} //global undefines\n  {$UNDEF USE_FAST_TRUNC}\n{$ENDIF}\n// Debug/release compiler options\n{$D+}\n\n//force 4 byte enumerations. We are interfacing with c libraries !!\n{$Z+}\n\n{$IFOPT D-}\n{$DEFINE BINARY_RELEASE}\n{$ENDIF}\n\n{$IFDEF BINARY_RELEASE}\n// Settings for Release mode\n{$C-}\n{$I-}\n{$R-}\n{$L-}\n{$Q-}\n{$IFNDEF FPC}\n{$O+}\n{$W-}\n{$ENDIF}\n\n{$ELSE}\n\n// Settings for Debug mode\n{.$C+}\n{.$I+}\n{.$R+}\n{.$L+}\n{.$Q+}\n{.$IFNDEF FPC}\n{.$O-}\n{.$W+}\n{.$ENDIF}\n\n{$ENDIF}\n\n// Disables checking code.\n// Use Range checking option to turn on/off optimization\n{$IFOPT R-}\n{$DEFINE DISABLE_CHECKING}\n{$ENDIF}\n\n// Uncomment these defines to disable some DB drivers (reduce binary size)\n{.$DEFINE ZEOS_DISABLE_MYSQL}\n{.$DEFINE ZEOS_DISABLE_POSTGRESQL}\n{.$DEFINE ZEOS_DISABLE_DBLIB}\n{.$DEFINE ZEOS_DISABLE_ADO}\n{.$DEFINE ZEOS_DISABLE_INTERBASE}\n{.$DEFINE ZEOS_DISABLE_SQLITE}\n{.$DEFINE ZEOS_DISABLE_ORACLE}\n{.$DEFINE ZEOS_DISABLE_ASA}\n\n// Enables MySQL support in TZConnection/TZDataset\n{$IFNDEF ZEOS_DISABLE_MYSQL}\n{$DEFINE ENABLE_MYSQL}\n{$ENDIF}\n\n// Enables PostgreSQL support in TZConnection/TZDataset\n{$IFNDEF ZEOS_DISABLE_POSTGRESQL}\n{$DEFINE ENABLE_POSTGRESQL}\n{$ENDIF}\n\n// Enables Sybase/MSSQL support in TZConnection/TZDataset\n{$IFNDEF ZEOS_DISABLE_DBLIB}\n{$DEFINE ENABLE_DBLIB}\n{$ENDIF}\n\n// Enables ADO support in TZConnection/TZDataset\n{$IFNDEF ZEOS_DISABLE_ADO}\n{$IFNDEF FPC}\n {$IFNDEF UNIX}\n  {$DEFINE ENABLE_ADO}\n {$ENDIF}\n{$ENDIF}\n{$ENDIF}\n\n// Enables Interbase/Firebird support in TZConnection/TZDataset\n{$IFNDEF ZEOS_DISABLE_INTERBASE}\n{$DEFINE ENABLE_INTERBASE}\n{$ENDIF}\n\n// Enables SQLite support in TZConnection/TZDataset\n{$IFNDEF ZEOS_DISABLE_SQLITE}\n{$DEFINE ENABLE_SQLITE}\n{$ENDIF}\n\n// Enables Oracle support in TZConnection/TZDataset\n{$IFNDEF ZEOS_DISABLE_ORACLE}\n{$DEFINE ENABLE_ORACLE}\n{$ENDIF}\n\n// Enables ASA support in TZConnection/TZDataset\n{$IFNDEF ZEOS_DISABLE_ASA}\n{$DEFINE ENABLE_ASA}\n{$ENDIF}\n\n// Enables Pooled connection support for all enabled db drivers in TZConnection/TZDataset\n{$IFNDEF ZEOS_DISABLE_POOLED}\n{$DEFINE ENABLE_POOLED}\n{$ENDIF}\n\n// Supported language. Now available languages:\n// ENGLISH, GERMAN, PORTUGUESE, DUTCH, SPANISH, ROMANA, INDONESIAN, RUSSIAN, CZECH, POLISH\n{$DEFINE ENGLISH}\n\n// Prevents loading default libmysql.dll\n{.$DEFINE MYSQL_STRICT_DLL_LOADING}\n\n// Prevents loading default firebird.dll\n{.$DEFINE FIREBIRD_STRICT_DLL_LOADING}\n\n// Prevents loading default libpq.dll\n{.$DEFINE POSTGRESQL_STRICT_DLL_LOADING}\n\n//Allows to see SQL exceptions as strings\n{$DEFINE INTERBASE_EXTENDED_MESSAGES}\n\n// Loads libcrypt.so before Firebird client library.\n// It fixes error \"Undefined symbol: crypt\".\n{$DEFINE INTERBASE_CRYPT}\n\n// Excludes old ZeosDBO from the performance tests\n{$DEFINE EXCLUDE_OLD_ZEOS_TEST}\n\n// Excludes DBExpress from the performance tests\n{$DEFINE EXCLUDE_DBX_TEST}\n\n// Excludes IBX from the performance tests\n{$DEFINE EXCLUDE_IBX_TEST}\n\n// Excludes BDE from the performance tests\n{$DEFINE EXCLUDE_BDE_TEST}\n\n// Registers property editors for the components.\n{$DEFINE WITH_PROPERTY_EDITOR}\n\n\n// Turn on multithreading\n{$DEFINE MULTI_THREADED}\n\n// In Version 6.1.5 there are several bugs with the TZSQLMetadata-Component\n// For Version 6.5.0 you should uncomment the following line\n{$DEFINE USE_METADATA}\n\n//Default. To validate an optimal updatecount of 1. Comment this define if this\n//dafault behavior isn't wanted. On the other hand you can suppress this\n//validation by adding the line ValidateUpdateCount=-1 or FALSE or OFF into the\n// TZDataSet-Component.Properties(TStrings)\n{$DEFINE WITH_VALIDATE_UPDATE_COUNT}\n\n// A large database may have many tables, colums and/or procedures!!!\n// Therefore there is the ability to show a warning\n// before retrieving a list of these database objects\n{.$DEFINE SHOW_WARNING}\n\n// Use libfbclient.so under linux\n// and not libfbembed.so when Firebird 1.5.2 is used under linux\n{$DEFINE USELIBFBCLIENTSO}\n\n// Use SynEdit for the SQL Editors.\n// Uncomment it when you will use SynEdit instead of a MemoEdit.\n// The SynEdit component must be installed on your system.\n// You can get SynEdit at http://synedit.sourceforge.net/\n{.$DEFINE USE_SYNEDIT}\n"
  },
  {
    "path": "lib/zeosdbo/src/ZeosLazarus.inc",
    "content": "{@********************************************************}\n{    Copyright (c) 1999-2012 Zeos Development Group       }\n{                                                         }\n{ License Agreement:                                      }\n{                                                         }\n{ This library is distributed in the hope that it will be }\n{ useful, but WITHOUT ANY WARRANTY; without even the      }\n{ implied warranty of MERCHANTABILITY or FITNESS FOR      }\n{ A PARTICULAR PURPOSE.  See the GNU Lesser General       }\n{ Public License for more details.                        }\n{                                                         }\n{ The source code of the ZEOS Libraries and packages are  }\n{ distributed under the Library GNU General Public        }\n{ License (see the file COPYING / COPYING.ZEOS)           }\n{ with the following  modification:                       }\n{ As a special exception, the copyright holders of this   }\n{ library give you permission to link this library with   }\n{ independent modules to produce an executable,           }\n{ regardless of the license terms of these independent    }\n{ modules, and to copy and distribute the resulting       }\n{ executable under terms of your choice, provided that    }\n{ you also meet, for each linked independent module,      }\n{ the terms and conditions of the license of that module. }\n{ An independent module is a module which is not derived  }\n{ from or based on this library. If you modify this       }\n{ library, you may extend this exception to your version  }\n{ of the library, but you are not obligated to do so.     }\n{ If you do not wish to do so, delete this exception      }\n{ statement from your version.                            }\n{                                                         }\n{                                                         }\n{ The project web site is located on:                     }\n{   http://zeos.firmos.at  (FORUM)                        }\n{   http://sourceforge.net/p/zeoslib/tickets/ (BUGTRACKER)}\n{   svn://svn.code.sf.net/p/zeoslib/code-0/trunk (SVN)    }\n{                                                         }\n{   http://www.sourceforge.net/projects/zeoslib.          }\n{                                                         }\n{                                                         }\n{                                 Zeos Development Group. }\n{********************************************************@}\n// Compilation directives for Lazarus\n\n{$DEFINE WITH_UNIDIRECTIONALBUG} //still buggy with IsUnidirectional prop of TDataSet FPC still moves the recordBuffer-> visit TestReadOnlyQueryUniDirectional and TZAbstractRODataset.GetRecord\n\n// These are in a spearate file as Delphi compilers don't digest the macros stuff very well\n{$MACRO ON}             // Macros needed for FPC_VERSION and FPC_RELEASE\n  {$MODE DELPHI}\n\n  {$INTERFACES COM}\n  {$IFDEF FPC_FULLVERSION}  // FPC_FULLVERSION was added in FPC 2.2.4\n    {$IF FPC_FULLVERSION<=20204}\n      {$DEFINE OLDFPC}\n    {$IFEND}\n\n//    {$IF FPC_FULLVERSION>=20400}  // 2.4.0 status is unknown. 2.4.2+ should be generally fine.\n//      {$DEFINE FPC2_4UP}\n//    {$IFEND}\n\n    {$DEFINE WITH_FTWIDESTRING}  // Supported from somewhere between 2.2 and 2.4\n\n    {$IF FPC_FULLVERSION>=20500}  // Upgrade to 2.6.x asap.\n      {$DEFINE FPC2_5UP} // Used in code\n      {$DEFINE WITH_NEWTOBJECT}\n      {$DEFINE WITH_IPROVIDER}\n    {$IFEND}\n    {$IF FPC_FULLVERSION>=20600}  // assumes 2.5.1 pretty close to 2.6.0. Summer 2011 or newer\n       {$DEFINE WITH_WIDEMEMO}\n       {$DEFINE WITH_ASLARGEINT}      // tlargeint aslargeint. Fixed 2.6.0+ or 2.6.2+ probably\n       {$DEFINE WITH_ASCURRENCY}      // Has AsCurrency.\n       {$DEFINE WITH_ASVARIANT}\n       {$DEFINE WITH_FORMATSETTINGS}\n       {$DEFINE WITH_WIDEFIELDS}\t// Wide-fields are supported (common define for ftWideString/ftWideMemo)\n       {$DEFINE PWIDECHAR_IS_PUNICODECHAR}\n       {$DEFINE WITH_FTGUID} //TStringField descendant TGuidField is supported \n       {$DEFINE FPC2_6UP}\n    {$IFEND}\n\n    {$IF FPC_FULLVERSION>=20602}\n       {$DEFINE HAVE_TBYTES}         // TBytes is declared only in FPC 2.6.2 instead of 2.6.0 as declared...\n    {$ENDIF}\n\n    {$IFDEF LCL}\n      {$DEFINE WITH_LCONVENCODING} //Only available for Lazarus\n    {$ENDIF}\n    {$DEFINE LAZARUSUTF8HACK} // Places that fixed for the Lazarus convention that all strings are UTF8  are marked with this\n                              // ifdef. But probably most of them are adhoc hacks, and need revisiting in time.\n    {$DEFINE WITH_FPC_FTTIME_BUG} //http://zeos.firmos.at/viewtopic.php?t=3534&postdays=0&postorder=asc&start=0\n    {$DEFINE WITH_FPC_BOF_BUG} //http://bugs.freepascal.org/view.php?id=22377\n    {$DEFINE WITH_FPC_MODIFIED_BUG} //http://bugs.freepascal.org/view.php?id=22381\n    {$DEFINE WITHOUT_VARBYTESASSTRING}\n    {$DEFINE WITH_PWIDECHAR_TOWIDESTRING}\n    {$DEFINE WITH_CLASS_VARS}\n  {$ELSE}\n    {$FATAL Versions Older than 2.2.4 are not supported!}\n  {$ENDIF}\n\n  {$DEFINE WITH_FUNIDIRECTIONAL} // FPC has references a field instead of a setter here.  (at least in 2.6.0)\n\n  {$IFDEF FPC_FULLVERSION>20601}\n    {$UNDEF WITH_FPC_FTTIME_BUG} //seems like the never FPC2.6.2 also have fixed the NativData bug for TTimeFields+TDataSet\n  {$ENDIF}\n  {$IF FPC_FULLVERSION>20602}       // will be introduced in 2.6.2 (and up to date 2.6.1)\n    {$DEFINE WITH_INLINE}           // compiler supports inline methodes\n  {$IFEND}\n  {$IF FPC_FULLVERSION>20700}       // will be introduced in 2.7+\n    {$DEFINE WITH_TRECORDBUFFER}\n    {$DEFINE WITH_TBOOKMARK}        // Have TBookmark\n    {$UNDEF WITH_FPC_BOF_BUG}\n    {$UNDEF WITH_FPC_MODIFIED_BUG}\n    {$DEFINE WITH_RAWBYTESTRING}          // Have RawByteString CP $FFFFF\n    {$DEFINE WITH_FPC_STRING_CONVERSATION} //After string conversations to RawByteString like AnsiZoUTF8 the results are equal to original value\n    {$DEFINE WITH_DEFAULTSYSTEMCODEPAGE}\n    {$DEFINE MISS_RBS_SETSTRING_OVERLOAD} //SetString overload for RawByteString is missing\n    {$IFNDEF FPC_HAS_BUILTIN_WIDESTR_MANAGER} //Hack for *nix systems where i couldn't locate this define )):\n      {$DEFINE FPC_HAS_BUILTIN_WIDESTR_MANAGER}\n    {$ENDIF}\n  {$IFEND}\n\n  // todo\n  //   VIRTUALSETFIELDDATA: in nativeformat versions of SETFIELDDATA, inherited wasn't called.\n  //                Afaik that methoid is virtual in FPC since December 2006, and there is no comment why\n  //                it was ifdefed. We'll leave it off, and see if sb complains.\n  //   LAZARUSUTF8HACK :  Places that fixed for the Lazarus convention that all strings are UTF8  are marked with this\n  //                             ifdef. But probably most of them are adhoc hacks, and need constant reevaluation.\n  //   OLDFPC      : IFDEF FPC's so old that I can't remember which version are put under IFDEF OLDFPC. In time these\n  //                   blocks can be killed.\n\n{$IF defined(WITH_LCONVENCODING) and (defined(MSWINDOWS) or defined(FPC_HAS_BUILTIN_WIDESTR_MANAGER))}\n  {$UNDEF WITH_LCONVENCODING}\n{$IFEND}\n\n{$IFDEF WITH_LCONVENCODING}\n  {$IF declared(lcl_fullversion)}\n    {$if lcl_fullversion>=1000000} //Lazarus >= 1.0.0 with delphi fix.\n      {$DEFINE LCONVENCODING_HAS_CP852_FUNCTIONS}\n    {$ifend}\n  {$ifend}\n{$ENDIF}\n"
  },
  {
    "path": "lib/zeosdbo/src/component/ZAbstractConnection.pas",
    "content": "{*********************************************************}\n{                                                         }\n{                 Zeos Database Objects                   }\n{              Database Connection Component              }\n{                                                         }\n{        Originally written by Sergey Seroukhov           }\n{                                                         }\n{*********************************************************}\n\n{@********************************************************}\n{    Copyright (c) 1999-2012 Zeos Development Group       }\n{                                                         }\n{ License Agreement:                                      }\n{                                                         }\n{ This library is distributed in the hope that it will be }\n{ useful, but WITHOUT ANY WARRANTY; without even the      }\n{ implied warranty of MERCHANTABILITY or FITNESS FOR      }\n{ A PARTICULAR PURPOSE.  See the GNU Lesser General       }\n{ Public License for more details.                        }\n{                                                         }\n{ The source code of the ZEOS Libraries and packages are  }\n{ distributed under the Library GNU General Public        }\n{ License (see the file COPYING / COPYING.ZEOS)           }\n{ with the following  modification:                       }\n{ As a special exception, the copyright holders of this   }\n{ library give you permission to link this library with   }\n{ independent modules to produce an executable,           }\n{ regardless of the license terms of these independent    }\n{ modules, and to copy and distribute the resulting       }\n{ executable under terms of your choice, provided that    }\n{ you also meet, for each linked independent module,      }\n{ the terms and conditions of the license of that module. }\n{ An independent module is a module which is not derived  }\n{ from or based on this library. If you modify this       }\n{ library, you may extend this exception to your version  }\n{ of the library, but you are not obligated to do so.     }\n{ If you do not wish to do so, delete this exception      }\n{ statement from your version.                            }\n{                                                         }\n{                                                         }\n{ The project web site is located on:                     }\n{   http://zeos.firmos.at  (FORUM)                        }\n{   http://sourceforge.net/p/zeoslib/tickets/ (BUGTRACKER)}\n{   svn://svn.code.sf.net/p/zeoslib/code-0/trunk (SVN)    }\n{                                                         }\n{   http://www.sourceforge.net/projects/zeoslib.          }\n{                                                         }\n{                                                         }\n{                                 Zeos Development Group. }\n{********************************************************@}\n\nunit ZAbstractConnection;\n\ninterface\n\n{$I ZComponent.inc}\n\nuses\n  Types,\n{$IFNDEF UNIX}\n{$IFDEF ENABLE_ADO}\n  ZDbcAdo,\n{$ENDIF}\n{$ENDIF}\n{$IFDEF ENABLE_DBLIB}\n  ZDbcDbLib,\n{$ENDIF}\n{$IFDEF ENABLE_MYSQL}\n  ZDbcMySql,\n{$ENDIF}\n{$IFDEF ENABLE_POSTGRESQL}\n  ZDbcPostgreSql,\n{$ENDIF}\n{$IFDEF ENABLE_INTERBASE}\n  ZDbcInterbase6,\n{$ENDIF}\n{$IFDEF ENABLE_SQLITE}\n  ZDbcSqLite,\n{$ENDIF}\n{$IFDEF ENABLE_ORACLE}\n  ZDbcOracle,\n{$ENDIF}\n{$IFDEF ENABLE_ASA}\n  ZDbcASA,\n{$ENDIF}\n{$IFDEF ENABLE_POOLED}\n  ZDbcPooled,\n{$ENDIF}\n\n  SysUtils, Classes, {$IFDEF MSEgui}mclasses, mdb{$ELSE}DB{$ENDIF},\n  ZDbcIntfs, ZCompatibility, ZURL;\n\n\ntype\n  //HA 090811 New Type TZLoginEvent to make Username and Password persistent\n  TZLoginEvent = procedure(Sender: TObject; var Username:string ; var Password: string) of object;\n\n  {** Represents a component which wraps a connection to database. }\n\n  { TZAbstractConnection }\n\n  TZAbstractConnection = class(TComponent)\n  private\n    FUseMetaData: Boolean;\n    {$IFNDEF UNICODE}FAutoEncode: Boolean;{$ENDIF}\n    FControlsCodePage: TZControlsCodePage;\n    {$IFDEF ZEOS_TEST_ONLY}\n    FTestMode: Byte;\n    {$ENDIF}\n    function GetVersion: string;\n    procedure SetUseMetadata(AValue: Boolean);\n    procedure SetVersion(const Value: string);\n    procedure SetControlsCodePage(const Value: TZControlsCodePage);\n  protected\n    FURL: TZURL;\n    FCatalog: string;\n    FAutoCommit: Boolean;\n    FReadOnly: Boolean;\n    FTransactIsolationLevel: TZTransactIsolationLevel;\n    FConnection: IZConnection;\n    FDatasets: TList;\n    // Modified by cipto 8/1/2007 1:44:22 PM\n    FSequences: TList;\n\n    FLoginPrompt: Boolean;\n    FStreamedConnected: Boolean;\n    FExplicitTransactionCounter: Integer;\n    FSQLHourGlass: Boolean;\n    FDesignConnection: Boolean;\n\n    FBeforeConnect: TNotifyEvent;\n    FBeforeDisconnect: TNotifyEvent;\n    FAfterDisconnect: TNotifyEvent;\n    FAfterConnect: TNotifyEvent;\n    FBeforeReconnect: TNotifyEvent;\n    FAfterReconnect: TNotifyEvent;\n    FOnCommit: TNotifyEvent;\n    FOnRollback: TNotifyEvent;\n    FOnStartTransaction: TNotifyEvent;\n    //HA 090811 Change Type of FOnLogin to new TZLoginEvent\n    //FOnLogin: TLoginEvent;\n    FOnLogin: TZLoginEvent;\n    FClientCodepage: String;\n\n    function GetAutoEncode: Boolean;\n    procedure SetAutoEncode(Value: Boolean);\n    function GetHostName: string;\n    procedure SetHostName(const Value: String);\n    function GetConnPort: Integer;\n    procedure SetConnPort(const Value: Integer);\n    function GetDatabase: string;\n    procedure SetDatabase(const Value: String);\n    function GetUser: string;\n    procedure SetUser(const Value: String);\n    function GetPassword: string;\n    procedure SetPassword(const Value: String);\n    function GetLibLocation: String;\n    procedure SetLibLocation(const Value: String);\n    function GetProtocol: String;\n    procedure SetProtocol(const Value: String);\n    function GetProperties: TStrings;\n    function GetConnected: Boolean;\n    procedure SetConnected(Value: Boolean);\n    procedure SetProperties(Value: TStrings);\n    procedure SetTransactIsolationLevel(Value: TZTransactIsolationLevel);\n    procedure SetAutoCommit(Value: Boolean);\n    function GetDbcDriver: IZDriver;\n    function GetInTransaction: Boolean;\n    function GetClientVersion: Integer;\n    function GetServerVersion: Integer;\n    function GetClientVersionStr: String;\n    function GetServerVersionStr: String;\n    procedure DoBeforeConnect;\n    procedure DoAfterConnect;\n    procedure DoBeforeDisconnect;\n    procedure DoAfterDisconnect;\n    procedure DoBeforeReconnect;\n    procedure DoAfterReconnect;\n    procedure DoCommit;\n    procedure DoRollback;\n    procedure DoStartTransaction;\n\n    procedure CheckConnected;\n    procedure CheckAutoCommitMode;\n    procedure CheckNonAutoCommitMode;\n\n    function ConstructURL(const UserName, Password: string): string;\n\n    procedure CloseAllDataSets;\n    procedure UnregisterAllDataSets;\n\n    // Modified by cipto 8/1/2007 1:48:17 PM\n    procedure CloseAllSequences;\n    ////////////////////////////////////////\n\n    procedure Notification(AComponent: TComponent;\n      Operation: TOperation); override;\n    procedure Loaded; override;\n\n    property StreamedConnected: Boolean read FStreamedConnected write FStreamedConnected;\n\n    procedure SetClientCodePage(Const Value: String); //Egonhugeist\n  public\n    constructor Create(AOwner: TComponent); override;\n    destructor Destroy; override;\n\n    procedure Connect; virtual;\n    procedure Disconnect; virtual;\n    procedure Reconnect;\n    function Ping: Boolean; virtual;\n\n    procedure StartTransaction; virtual;\n    procedure Commit; virtual;\n    procedure Rollback; virtual;\n\n    procedure PrepareTransaction(const transactionid: string); virtual;\n    procedure CommitPrepared(const transactionid: string); virtual;\n    procedure RollbackPrepared(const transactionid: string); virtual;\n    function PingServer: Boolean; virtual;\n\n    procedure RegisterDataSet(DataSet: TDataset);\n    procedure UnregisterDataSet(DataSet: TDataset);\n    function ExecuteDirect(SQL:string):boolean;overload;\n    function ExecuteDirect(SQL:string; var RowsAffected:integer):boolean;overload;\n    // Modified by cipto 8/2/2007 10:16:50 AM\n    procedure RegisterSequence(Sequence: TComponent);\n    procedure UnregisterSequence(Sequence: TComponent);\n    ///////////////////////////////////////////////////\n\n    procedure GetProtocolNames(List: TStrings);\n    procedure GetCatalogNames(List: TStrings);\n    procedure GetSchemaNames(List: TStrings);\n    procedure GetTableNames(const Pattern: string; List: TStrings);overload;\n    procedure GetTableNames(const schemaPattern, tablePattern: string; List: TStrings);overload;\n    procedure GetTableNames(const schemaPattern, tablePattern: string; Types: TStringDynArray; List: TStrings);overload;\n    procedure GetColumnNames(const TablePattern, ColumnPattern: string; List: TStrings);\n\n    procedure GetStoredProcNames(const Pattern: string; List: TStrings);\n    procedure GetTriggerNames(const TablePattern, SchemaPattern: string; List: TStrings);\n\n    //EgonHugeist\n    function GetBinaryEscapeStringFromString(const BinaryString: AnsiString): String; overload;\n    function GetBinaryEscapeStringFromStream(const Stream: TStream): String; overload;\n    function GetBinaryEscapeStringFromFile(const FileName: String): String; overload;\n    function GetAnsiEscapeString(const Ansi: AnsiString): String;\n    function GetURL: String;\n\n    property InTransaction: Boolean read GetInTransaction;\n\n    property HostName: string read GetHostName write SetHostName;\n    property Port: Integer read GetConnPort write SetConnPort;\n    property Database: string read GetDatabase write SetDatabase;\n    property User: string read GetUser write SetUser;\n    property Password: string read GetPassword write SetPassword;\n    property Protocol: string read GetProtocol write SetProtocol;\n    property LibLocation: string read GetLibLocation write SetLibLocation;\n\n    property DbcDriver: IZDriver read GetDbcDriver;\n    property DbcConnection: IZConnection read FConnection;\n    property ClientVersion: Integer read GetClientVersion;\n    property ServerVersion: Integer read GetServerVersion;\n    property ClientVersionStr: String read GetClientVersionStr;\n    property ServerVersionStr: String read GetServerVersionStr;\n    procedure ShowSQLHourGlass;\n    procedure HideSQLHourGlass;\n  published\n    property ControlsCodePage: TZControlsCodePage read FControlsCodePage write SetControlsCodePage;\n    property AutoEncodeStrings: Boolean read GetAutoEncode write SetAutoEncode default True;\n    property ClientCodepage: String read FClientCodepage write SetClientCodePage; //EgonHugeist\n    property Catalog: string read FCatalog write FCatalog;\n    property Properties: TStrings read GetProperties write SetProperties;\n    property AutoCommit: Boolean read FAutoCommit write SetAutoCommit\n      default True;\n    property ReadOnly: Boolean read FReadOnly write FReadOnly\n      default False;\n    property UseMetadata: Boolean read FUseMetaData write SetUseMetadata default true;\n    property TransactIsolationLevel: TZTransactIsolationLevel\n      read FTransactIsolationLevel write SetTransactIsolationLevel\n      default tiNone;\n    property Connected: Boolean read GetConnected write SetConnected\n      default False;\n    property LoginPrompt: Boolean read FLoginPrompt write FLoginPrompt\n      default False;\n    property Version: string read GetVersion write SetVersion stored False;\n    property DesignConnection: Boolean read FDesignConnection\n      write FDesignConnection default False;\n\n    property BeforeConnect: TNotifyEvent\n      read FBeforeConnect write FBeforeConnect;\n    property AfterConnect: TNotifyEvent\n      read FAfterConnect write FAfterConnect;\n    property BeforeDisconnect: TNotifyEvent\n      read FBeforeDisconnect write FBeforeDisconnect;\n    property AfterDisconnect: TNotifyEvent\n      read FAfterDisconnect write FAfterDisconnect;\n    property BeforeReconnect: TNotifyEvent\n      read FBeforeReconnect write FBeforeReconnect;\n    property AfterReconnect: TNotifyEvent\n      read FAfterReconnect write FAfterReconnect;\n    property SQLHourGlass: Boolean read FSQLHourGlass write FSQLHourGlass\n      default False;\n    property OnCommit: TNotifyEvent read FOnCommit write FOnCommit;\n    property OnRollback: TNotifyEvent read FOnRollback write FOnRollback;\n    //HA 090811 Change Type of FOnLogin to new TZLoginEvent\n    //property OnLogin: TLoginEvent read FOnLogin write FOnLogin;\n    property OnLogin: TZLoginEvent read FOnLogin write FOnLogin;\n    property OnStartTransaction: TNotifyEvent\n      read FOnStartTransaction write FOnStartTransaction;\n    {$IFDEF ZEOS_TEST_ONLY}\n    property TestMode : Byte read FTestMode write FTestMode;\n    {$ENDIF}\n  end;\n\nimplementation\n\nuses ZMessages, ZClasses, ZAbstractRODataset, ZSysUtils,\n      // Modified by cipto 8/2/2007 10:00:22 AM\n      ZSequence, ZAbstractDataset, ZEncoding;\n\nvar\n  SqlHourGlassLock: Integer;\n  CursorBackup: TDBScreenCursor;\n\n{ TZAbstractConnection }\n\n{**\n  Constructs this component and assignes the main properties.\n  @param AOwner an owner component.\n}\nconstructor TZAbstractConnection.Create(AOwner: TComponent);\nbegin\n  {$IFDEF UNICODE}\n  FControlsCodePage := cCP_UTF16;\n  {$ELSE}\n    {$IFDEF FPC}\n    FControlsCodePage := cCP_UTF8;\n    {$ELSE}\n    FControlsCodePage := cGET_ACP;\n    {$ENDIF}\n  {$ENDIF}\n  FURL := TZURL.Create;\n  inherited Create(AOwner);\n  FAutoCommit := True;\n  FReadOnly := False;\n  FTransactIsolationLevel := tiNone;\n  FConnection := nil;\n  FUseMetadata := True;\n  FDatasets := TList.Create;\n  // Modified by cipto 8/1/2007 1:45:56 PM\n  FSequences:= TList.Create;\n  FLoginPrompt := False;\n  FDesignConnection := False;\nend;\n\n{**\n  Destroys this component and cleanups the memory.\n}\ndestructor TZAbstractConnection.Destroy;\nbegin\n  Disconnect;\n  UnregisterAllDataSets;\n  FDatasets.Free;\n  FURL.Free;\n  // Modified by cipto 8/1/2007 1:47:37 PM\n  FSequences.Clear;\n  FSequences.Free;\n  ////////////////////////////////////////\n  inherited Destroy;\nend;\n\nfunction TZAbstractConnection.GetHostName: string;\nbegin\n  Result := FURL.HostName;\nend;\n\nprocedure TZAbstractConnection.SetHostName(const Value: String);\nbegin\n  FURL.HostName := Value;\nend;\n\nfunction TZAbstractConnection.GetConnPort: Integer;\nbegin\n  Result := FURL.Port;\nend;\n\nprocedure TZAbstractConnection.SetConnPort(const Value: Integer);\nbegin\n  FURL.Port := Value;\nend;\n\nfunction TZAbstractConnection.GetDatabase: string;\nbegin\n  Result := FURL.Database;\nend;\n\nprocedure TZAbstractConnection.SetDatabase(const Value: String);\nbegin\n  FURL.Database := Value;\nend;\n\nfunction TZAbstractConnection.GetUser: string;\nbegin\n  Result := FURL.UserName;\nend;\n\nprocedure TZAbstractConnection.SetUser(const Value: String);\nbegin\n  FURL.UserName := Value;\nend;\n\nfunction TZAbstractConnection.GetPassword: string;\nbegin\n  Result := FURL.Password;\nend;\n\nprocedure TZAbstractConnection.SetPassword(const Value: String);\nbegin\n  FURL.Password := Value;\nend;\n\nfunction TZAbstractConnection.GetLibLocation: String;\nbegin\n  Result := FURL.LibLocation;\nend;\n\nprocedure TZAbstractConnection.SetLibLocation(const Value: String);\nbegin\n  FURL.LibLocation := Value;\nend;\n\nfunction TZAbstractConnection.GetProtocol: String;\nbegin\n  Result := FURL.Protocol;\nend;\n\nprocedure TZAbstractConnection.SetProtocol(const Value: String);\nbegin\n  FURL.Protocol := Value;\nend;\n\nfunction TZAbstractConnection.GetProperties: TStrings;\nbegin\n  Result := FURL.Properties;\nend;\n\n{**\n  This methode is required to support proper component initialization.\n  Without it, the connection can start connecting before every property is loaded!\n}\nprocedure TZAbstractConnection.Loaded;\nbegin\n  inherited Loaded;\n  try\n    if FStreamedConnected then\n      if (csDesigning in ComponentState) or not FDesignConnection then\n        SetConnected(True);\n  except\n    if csDesigning in ComponentState then\n      if Assigned(Classes.ApplicationHandleException) then\n        Classes.ApplicationHandleException(ExceptObject)\n      else\n        ShowException(ExceptObject, ExceptAddr)\n    else\n      raise;\n  end;\nend;\n\n{**\n  EgonHugeist:\n  Sets the ClientCode-Page-Property and adds or corrects it in the\n    Info(Properties)-Strings\n  @param <code>string</code> the ClientCharacterSet\n}\nprocedure TZAbstractConnection.SetClientCodePage(Const Value: String);\nbegin\n  if ( Value = 'Not Connected!' ) or ( Value = 'Not implementet!' ) then\n    //possible! -> result of PropertyEditor if not complete yet\n    //Later we should remove this if the MeataData/Plaindriver-Informations\n    //where complete\n    FClientCodepage := Trim(FURL.Properties.Values['codepage'])\n  else\n    Self.FClientCodepage := Value;\n  if ( Trim(FURL.Properties.Values['codepage']) <> FClientCodepage ) then\n    FURL.Properties.Values['codepage'] := FClientCodepage;\nend;\n\n{**\n  Gets an open connection flag.\n  @return <code>True</code> if the connection is open\n    or <code>False</code> otherwise.\n}\nfunction TZAbstractConnection.GetConnected: Boolean;\nbegin\n  Result := (FConnection <> nil) and not FConnection.IsClosed;\nend;\n\n{**\n  Sets a new open connection flag.\n  @param Value <code>True</code> to open the connection\n    and <code>False</code> to close it.\n}\nprocedure TZAbstractConnection.SetConnected(Value: Boolean);\nbegin\n  if (csReading in ComponentState) and Value then\n    FStreamedConnected := True\n  else\n  begin\n    if Value <> GetConnected then\n    begin\n      if Value then\n        Connect\n      else\n        Disconnect;\n    end;\n  end;\nend;\n\n{**\n  Sets a new connection properties.\n  @param Value a list with new connection properties.\n}\nprocedure TZAbstractConnection.SetProperties(Value: TStrings);\nbegin\n  if Value <> nil then\n  begin\n    if ( Trim(Value.Values['codepage']) <> '' ) then\n      FClientCodepage := Trim(Value.Values['codepage'])\n    else\n      Value.Values['codepage'] := FClientCodepage;\n\n    { check autoencodestrings }\n    {$IF (defined(MSWINDOWS) or defined(WITH_LCONVENCODING) or defined(FPC_HAS_BUILTIN_WIDESTR_MANAGER)) and not defined(UNICODE)}\n    if Connected then\n      DbcConnection.AutoEncodeStrings := Value.Values['AutoEncodeStrings'] = 'ON';\n    FAutoEncode := Value.Values['AutoEncodeStrings'] = 'ON';\n    {$ELSE}\n      {$IFDEF UNICODE}\n      Value.Values['AutoEncodeStrings'] := 'ON';\n      {$ELSE}\n      Value.Values['AutoEncodeStrings'] := '';\n      {$ENDIF}\n    {$IFEND}\n\n    if Value.IndexOf('controls_cp') = -1 then\n      {$IFDEF UNICODE}\n      if ControlsCodePage = cCP_UTF16 then\n        Value.values['controls_cp'] := 'CP_UTF16'\n      else\n        Value.values['controls_cp'] := 'GET_ACP'\n      {$ELSE}\n      case ControlsCodePage of //automated check..\n        cCP_UTF16: Value.values['controls_cp'] := 'CP_UTF16';\n        cCP_UTF8: Value.values['controls_cp'] := 'CP_UTF8';\n        cGET_ACP: Value.values['controls_cp'] := 'GET_ACP';\n      end\n      {$ENDIF}\n    else\n      {$IFDEF UNICODE}\n      if Value.values['controls_cp'] = 'CP_UTF8' then\n      begin\n        Value.values['controls_cp'] := 'CP_UTF16';\n        FControlsCodePage := cCP_UTF16;\n      end;\n      {$ELSE}\n        {$IFNDEF WITH_WIDEFIELDS} //old FPC and D7\n        if Value.values['controls_cp'] = 'CP_UTF16' then\n        begin\n          FControlsCodePage := cGET_ACP;\n          Value.values['controls_cp'] := {$IFDEF DLEPHI}'GET_ACP'{$ELSE}'CP_UTF8'{$ENDIF};\n        end;\n        {$ELSE}\n        if Value.values['controls_cp'] = 'GET_ACP' then\n          FControlsCodePage := cGET_ACP\n        else\n          if Value.values['controls_cp'] = 'CP_UTF8' then\n            FControlsCodePage := cCP_UTF8\n          else\n            if Value.values['controls_cp'] = 'CP_UTF16' then\n              FControlsCodePage := cCP_UTF16\n            else\n              case ControlsCodePage of //automated check..\n                cCP_UTF16: Value.values['controls_cp'] := 'CP_UTF16';\n                cCP_UTF8: Value.values['controls_cp'] := 'CP_UTF8';\n                cGET_ACP: Value.values['controls_cp'] := 'GET_ACP';\n              end;\n        {$ENDIF}\n      {$ENDIF}\n    FURL.Properties.Text := Value.Text;\n  end\n  else\n    FURL.Properties.Clear;\nend;\n\n{**\n  Sets autocommit flag.\n  @param Value <code>True</code> to turn autocommit on.\n}\nprocedure TZAbstractConnection.SetAutoCommit(Value: Boolean);\nbegin\n  if FAutoCommit <> Value then\n  begin\n    if FExplicitTransactionCounter > 0 then\n      raise Exception.Create(SInvalidOperationInTrans);\n    FAutoCommit := Value;\n    ShowSQLHourGlass;\n    try\n      if FConnection <> nil then\n        FConnection.SetAutoCommit(Value);\n    finally\n      HideSqlHourGlass\n    end;\n  end;\nend;\n\n{**\n  Sets transact isolation level.\n  @param Value a transact isolation level.\n}\nprocedure TZAbstractConnection.SetTransactIsolationLevel(\n  Value: TZTransactIsolationLevel);\nbegin\n  if FTransactIsolationLevel <> Value then\n  begin\n    FTransactIsolationLevel := Value;\n    ShowSqlhourGlass;\n    try\n      if FConnection <> nil then\n        FConnection.SetTransactionIsolation(Value);\n    finally\n      HideSqlHourGlass\n    end;\n  end;\nend;\n\n{**\n  Gets a ZDBC driver for the specified protocol.\n  @returns a ZDBC driver interface.\n}\nfunction TZAbstractConnection.GetDbcDriver: IZDriver;\nbegin\n  if FConnection <> nil then\n    Result := FConnection.GetDriver\n  else\n    Result := DriverManager.GetDriver(ConstructURL('', ''));\nend;\n\n{**\n  Checks is the connection started a transaction.\n  @returns <code>True</code> if connection in manual transaction mode\n    and transaction is started.\n}\nfunction TZAbstractConnection.GetInTransaction: Boolean;\nbegin\n  CheckConnected;\n  Result := not FAutoCommit or (FExplicitTransactionCounter > 0);\nend;\n\n{**\n  Gets client's full version number.\n  The format of the version resturned must be XYYYZZZ where\n   X   = Major version\n   YYY = Minor version\n   ZZZ = Sub version\n  @return this clients's full version number\n}\nfunction TZAbstractConnection.GetClientVersion: Integer;\nbegin\n  if FConnection <> nil then\n    Result := DbcConnection.GetClientVersion\n  else\n    Result := DriverManager.GetClientVersion(ConstructURL('', ''));\nend;\n\n{**\n  Gets server's full version number.\n  The format of the version resturned must be XYYYZZZ where\n   X   = Major version\n   YYY = Minor version\n   ZZZ = Sub version\n  @return this clients's full version number\n}\nfunction TZAbstractConnection.GetServerVersion: Integer;\nbegin\n  CheckConnected;\n  Result := DbcConnection.GetHostVersion;\nend;\n\n{**\n  Gets client's full version number.\n  The format of the version resturned must be XYYYZZZ where\n   X   = Major version\n   YYY = Minor version\n   ZZZ = Sub version\n  @return this clients's full version number\n}\nfunction TZAbstractConnection.GetClientVersionStr: String;\nbegin\n  Result := FormatSQLVersion(GetClientVersion);\nend;\n\n{**\n  Gets server's full version number.\n  The format of the version resturned must be XYYYZZZ where\n   X   = Major version\n   YYY = Minor version\n   ZZZ = Sub version\n  @return this clients's full version number\n}\nfunction TZAbstractConnection.GetServerVersionStr: String;\nbegin\n  Result := FormatSQLVersion(GetServerVersion);\nend;\n\n{**\n  Constructs ZDBC connection URL string.\n  @param UserName a name of the user.\n  @param Password a user password.\n  @returns a constructed connection URL.\n}\nfunction TZAbstractConnection.ConstructURL(const UserName, Password: string): string;\nbegin\n  Result := DriverManager.ConstructURL(FURL.Protocol, FURL.HostName, FURL.Database, UserName,\n    Password, FURL.Port, FURL.Properties, FURL.LibLocation);\nend;\n\n{**\n  Fires an event before connection open\n}\nprocedure TZAbstractConnection.DoBeforeConnect;\nbegin\n  if Assigned(FBeforeConnect) then\n    FBeforeConnect(Self);\nend;\n\n{**\n  Fires an event after connection open\n}\nprocedure TZAbstractConnection.DoAfterConnect;\nbegin\n  if Assigned(FAfterConnect) then\n    FAfterConnect(Self);\nend;\n\n{**\n  Fires an event before connection close\n}\nprocedure TZAbstractConnection.DoBeforeDisconnect;\nbegin\n  if Assigned(FBeforeDisconnect) then\n    FBeforeDisconnect(Self);\nend;\n\n{**\n  Fires an event after connection close\n}\nprocedure TZAbstractConnection.DoAfterDisconnect;\nbegin\n  if Assigned(FAfterDisconnect) then\n    FAfterDisconnect(Self);\nend;\n\n{**\n  Fires an event before reconnect\n}\nprocedure TZAbstractConnection.DoBeforeReconnect;\nbegin\n  if Assigned(FBeforeReconnect) then\n    FBeforeReconnect(Self);\nend;\n\n{**\n  Fires an event after reconnect\n}\nprocedure TZAbstractConnection.DoAfterReconnect;\nbegin\n  if Assigned(FAfterReconnect) then\n    FAfterReconnect(Self);\nend;\n\n{**\n  Fires an event after transaction commit\n}\nprocedure TZAbstractConnection.DoCommit;\nbegin\n  if Assigned(FOnCommit) then\n    FOnCommit(Self);\nend;\n\n{**\n  Fires an event after transaction rollback\n}\nprocedure TZAbstractConnection.DoRollback;\nbegin\n  if Assigned(FOnRollback) then\n    FOnRollback(Self);\nend;\n\n{**\n  Fires an event after transaction start\n}\nprocedure TZAbstractConnection.DoStartTransaction;\nbegin\n  if Assigned(FOnStartTransaction) then\n    FOnStartTransaction(Self);\nend;\n\n{**\n  Establish a connection with database.\n}\nprocedure TZAbstractConnection.Connect;\nvar\n//Local variables declared in order to preserve the original property value\n//and to avoid the storage of password\n  Username, Password: string;\nbegin\n  if FConnection = nil then\n  begin\n// Fixes Zeos Bug 00056\n//    try\n      DoBeforeConnect;\n//    except\n//This is here to support aborting the Connection in BeforeConnect event without fatal errors\n//      on E: EAbort do\n//        Exit;\n//    end;\n\n    UserName := FURL.UserName;\n    Password := FURL.Password;\n\n    if FLoginPrompt then\n    begin\n\n      if Assigned(FOnLogin) then\n        FOnLogin(Self, UserName, Password)\n      else\n      begin\n        if Assigned(LoginDialogProc) then\n        begin\n          if not LoginDialogProc(FURL.Database, UserName, Password) then\n            Exit;\n        end\n        else\n          raise Exception.Create(SLoginPromptFailure);\n      end;\n    end;\n\n    ShowSqlHourGlass;\n    try\n      FConnection := DriverManager.GetConnectionWithParams(\n        ConstructURL(UserName, Password), FURL.Properties);\n      try\n        with FConnection do\n        begin\n          SetAutoCommit(FAutoCommit);\n          SetReadOnly(FReadOnly);\n          SetCatalog(FCatalog);\n          SetTransactionIsolation(FTransactIsolationLevel);\n          SetUseMetadata(FUseMetadata);\n          Open;\n          {$IFDEF ZEOS_TEST_ONLY}\n          SetTestMode(FTestMode);\n          {$ENDIF}\n        end;\n      except\n        FConnection := nil;\n        raise;\n      end;\n    finally\n      HideSqlHourGlass;\n    end;\n\n    if not FConnection.IsClosed then\n      DoAfterConnect;\n  end;\nend;\n\n{**\n  Closes and removes the connection with database\n}\nprocedure TZAbstractConnection.Disconnect;\nbegin\n  if FConnection <> nil then\n  begin\n    DoBeforeDisconnect;\n\n    ShowSqlHourGlass;\n    try\n      CloseAllDataSets;\n      // Modified by cipto 8/2/2007 10:11:02 AM\n      CloseAllSequences;\n      FConnection.Close;\n    finally\n      FConnection := nil;\n      HideSqlHourGlass;\n    end;\n\n    DoAfterDisconnect;\n  end;\nend;\n\n\n{**\n  Sends a ping to the server.\n}\nfunction TZAbstractConnection.Ping: Boolean;\nbegin\n  Result := (FConnection <> nil) and (FConnection.PingServer=0);\nend;\n\n{**\n  Reconnect, doesn't destroy DataSets if successful.\n}\nprocedure TZAbstractConnection.Reconnect;\nbegin\n  if FConnection <> nil then\n  begin\n    DoBeforeReconnect;\n\n    ShowSqlHourGlass;\n    try\n      try\n        FConnection.Close;\n        FConnection.Open;\n      except\n        CloseAllDataSets;\n        raise;\n      end;\n    finally\n      HideSqlHourGlass;\n    end;\n\n    DoAfterReconnect;\n  end;\nend;\n\n{**  Checks if this connection is active.\n}\nprocedure TZAbstractConnection.CheckConnected;\nbegin\n  if FConnection = nil then\n    raise EZDatabaseError.Create(SConnectionIsNotOpened);\nend;\n\n{**\n  Checks if this connection is in auto-commit mode.\n}\nprocedure TZAbstractConnection.CheckNonAutoCommitMode;\nbegin\n  if FAutoCommit then\n    raise EZDatabaseError.Create(SInvalidOpInAutoCommit);\nend;\n\n{**\n  Checks if this connection is in auto-commit mode.\n}\nprocedure TZAbstractConnection.CheckAutoCommitMode;\nbegin\n  if not FAutoCommit and (FExplicitTransactionCounter = 0) then\n    raise EZDatabaseError.Create(SInvalidOpInNonAutoCommit);\nend;\n\n{**\n  Commits the current transaction.\n}\nprocedure TZAbstractConnection.StartTransaction;\nbegin\n  CheckAutoCommitMode;\n\n  if FExplicitTransactionCounter = 0 then\n    AutoCommit := False;\n  DoStartTransaction;\n  Inc(FExplicitTransactionCounter);\nend;\n\n{**\n  Commits the current transaction.\n}\ntype //To get protected methodes\n  THack_ZAbstractDataset = Class(TZAbstractDataset);\nprocedure TZAbstractConnection.Commit;\nvar\n  ExplicitTran: Boolean;\n  i: Integer;\nbegin\n  CheckConnected;\n  CheckNonAutoCommitMode;\n\n  ExplicitTran := FExplicitTransactionCounter > 0;\n  if FExplicitTransactionCounter < 2 then\n  //when 0 then AutoCommit was turned off, when 1 StartTransaction was used\n  begin\n    ShowSQLHourGlass;\n    try\n      try\n        for i := 0 to FDatasets.Count -1 do\n          if Assigned(FDatasets[i]) then\n            if TObject(FDatasets[i]) is TZAbstractDataset then\n              THack_ZAbstractDataset(FDatasets[i]).DisposeCachedUpdates;\n        FConnection.Commit;\n      finally\n        FExplicitTransactionCounter := 0;\n        if ExplicitTran then\n          AutoCommit := True;\n      end;\n    finally\n      HideSQLHourGlass;\n    end;\n    DoCommit;\n  end\n  else\n    Dec(FExplicitTransactionCounter);\nend;\n\nprocedure TZAbstractConnection.CommitPrepared(const transactionid: string);\nvar\n  oldlev: TZTransactIsolationLevel;\nbegin\n  CheckAutoCommitMode;\n  oldlev := TransactIsolationLevel;\n  TransactIsolationLevel := tiNone;\n  FConnection.CommitPrepared(transactionid);\n  TransactIsolationLevel := oldLev;\nend;\n\n{**\n  Rollbacks the current transaction.\n}\nprocedure TZAbstractConnection.Rollback;\nvar\n  ExplicitTran: Boolean;\nbegin\n  CheckConnected;\n  CheckNonAutoCommitMode;\n\n  ExplicitTran := FExplicitTransactionCounter > 0;\n  if FExplicitTransactionCounter < 2 then\n  //when 0 then AutoCommit was turned off, when 1 StartTransaction was used\n  begin\n    ShowSQLHourGlass;\n    try\n      try\n        FConnection.RollBack;\n      finally\n        FExplicitTransactionCounter := 0;\n        if ExplicitTran then\n          AutoCommit := True;\n      end;\n    finally\n      HideSQLHourGlass;\n    end;\n    DoRollback;\n  end\n  else\n    Dec(FExplicitTransactionCounter);\nend;\n\nprocedure TZAbstractConnection.RollbackPrepared(const transactionid: string);\nvar\n  oldlev: TZTransactIsolationLevel;\nbegin\n  CheckAutoCommitMode;\n  oldlev := TransactIsolationLevel;\n  TransactIsolationLevel := tiNone;\n  FConnection.RollbackPrepared(transactionid);\n  TransactIsolationLevel := oldLev;\nend;\n\n{**\n  Processes component notifications.\n  @param AComponent a changed component object.\n  @param Operation a component operation code.\n}\nprocedure TZAbstractConnection.Notification(AComponent: TComponent;\n  Operation: TOperation);\nbegin\n  inherited Notification(AComponent, Operation);\n\n  if (Operation = opRemove) then\n  begin\n    if (AComponent is TDataset) then\n      UnregisterDataSet(TDataset(AComponent));\n    if (AComponent is TZSequence) then\n      UnregisterSequence(TZSequence(AComponent));\n  end;\nend;\n\nFunction TZAbstractConnection.PingServer: Boolean;\nvar\n  LastState : boolean;\nbegin\n  Result := false;\n  // Check connection status\n  LastState := GetConnected;\n  If FConnection <> Nil Then\n    Begin\n      Result := (FConnection.PingServer=0);\n      // Connection now is false but was true\n      If (Not Result) And (LastState) Then\n        // Generate OnDisconnect event\n        SetConnected(Result);\n    End\n  Else\n    // Connection now is false but was true\n    If LastState Then\n      SetConnected(false);\nend;\n\nprocedure TZAbstractConnection.PrepareTransaction(const transactionid: string);\n{var\n  ExplicitTran: Boolean;}\nbegin\n  CheckConnected;\n  CheckNonAutoCommitMode;\n  if FExplicitTransactionCounter <> 1 then\n  begin\n    raise EZDatabaseError.Create(SInvalidOpPrepare);\n  end;\n    ShowSQLHourGlass;\n    try\n      try\n        FConnection.PrepareTransaction(transactionid);\n      finally\n        FExplicitTransactionCounter := 0;\n        AutoCommit := True;\n      end;\n    finally\n      HideSQLHourGlass;\n    end;\nend;\n\n\n{**\n  Closes all registered datasets.\n}\nprocedure TZAbstractConnection.CloseAllDataSets;\nvar\n  I: Integer;\n  Current: TZAbstractRODataset;\nbegin\n  for I := 0 to FDatasets.Count - 1 do\n  begin\n    Current := TZAbstractRODataset(FDatasets[I]);\n    try\n      Current.UnPrepare;\n      Current.Close;\n    except\n      // Ignore.\n    end;\n  end;\nend;\n\n{**\n  Registers a new dataset object.\n  @param DataSet a new dataset to be registered.\n}\nprocedure TZAbstractConnection.RegisterDataSet(DataSet: TDataset);\nbegin\n  FDatasets.Add(DataSet);\nend;\n\n{**\n  Unregisters a new dataset object.\n  @param DataSet a new dataset to be unregistered.\n}\nprocedure TZAbstractConnection.UnregisterDataSet(DataSet: TDataset);\nbegin\n  FDatasets.Remove(DataSet);\nend;\n\n{**\n  Unregisters all dataset objects.\n}\nprocedure TZAbstractConnection.UnregisterAllDataSets;\nvar\n  I: Integer;\n  Current: TZAbstractRODataset;\nbegin\n  for I := FDatasets.Count - 1 downto 0 do\n  begin\n    Current := TZAbstractRODataset(FDatasets[I]);\n    FDatasets.Remove(Current);\n    try\n      Current.Connection := nil;\n    except\n      // Ignore.\n    end;\n  end;\nend;\n\n{**\n  Turn on sql hourglass cursor\n}\nprocedure TZAbstractConnection.ShowSQLHourGlass;\nbegin\n  if not FSqlHourGlass then\n    Exit;\n\n  if SqlHourGlassLock = 0 then\n  begin\n    if Assigned(DBScreen) then\n    begin\n      CursorBackup := DBScreen.Cursor;\n      if CursorBackup <> dcrOther then\n        DBScreen.Cursor := dcrSQLWait;\n    end;\n  end;\n  Inc(SqlHourGlassLock);\nend;\n\n{**\n  Turn off sql hourglass cursor\n}\nprocedure TZAbstractConnection.HideSQLHourGlass;\nbegin\n  if not FSqlHourGlass then\n    Exit;\n\n  if SqlHourGlassLock > 0 then\n    Dec(SqlHourGlassLock);\n  if SqlHourGlassLock = 0 then\n  begin\n    if CursorBackup <> dcrOther then\n      if Assigned(DBScreen) then\n        DBScreen.Cursor := CursorBackup;\n  end;\nend;\n\n{**\n  Fills string list with registered protocol names.\n  @param List a string list to fill out.\n}\nprocedure TZAbstractConnection.GetProtocolNames(List: TStrings);\nvar\n  I, J: Integer;\n  Drivers: IZCollection;\n  Driver: IZDriver;\n  Protocols: TStringDynArray;\nbegin\n  List.Clear;\n  Protocols := nil; // Makes compiler happy\n  Drivers := DriverManager.GetDrivers;\n  for I := 0 to Drivers.Count - 1 do\n  begin\n    Driver := Drivers[I] as IZDriver;\n    Protocols := Driver.GetSupportedProtocols;\n    for J := Low(Protocols) to High(Protocols) do\n      List.Add(Protocols[J]);\n  end;\nend;\n\n{**\n  Fills string list with catalog names.\n  @param List a string list to fill out.\n}\nprocedure TZAbstractConnection.GetCatalogNames(List: TStrings);\nvar\n  Metadata: IZDatabaseMetadata;\n  ResultSet: IZResultSet;\nbegin\n  CheckConnected;\n\n  List.Clear;\n  Metadata := DbcConnection.GetMetadata;\n  ResultSet := Metadata.GetCatalogs;\n  while ResultSet.Next do\n    List.Add(ResultSet.GetStringByName('TABLE_CAT'));\nend;\n\n{**\n  Fills string list with schema names.\n  @param List a string list to fill out.\n}\nprocedure TZAbstractConnection.GetSchemaNames(List: TStrings);\nvar\n  Metadata: IZDatabaseMetadata;\n  ResultSet: IZResultSet;\nbegin\n  CheckConnected;\n\n  List.Clear;\n  Metadata := DbcConnection.GetMetadata;\n  ResultSet := Metadata.GetSchemas;\n  while ResultSet.Next do\n    List.Add(ResultSet.GetStringByName('TABLE_SCHEM'));\nend;\n\n{**\n  Fills string list with table names.\n  @param Pattern a pattern for table names.\n  @param List a string list to fill out.\n}\nprocedure TZAbstractConnection.GetTableNames(const Pattern: string; List: TStrings);\nbegin\n  GetTableNames('', Pattern, nil, List);\nend;\n\n{**\n  Fills string list with table names.\n  @param tablePattern a pattern for table names.\n  @param schemaPattern a pattern for schema names.\n  @param List a string list to fill out.\n}\nprocedure TZAbstractConnection.GetTableNames(const schemaPattern, tablePattern: string; List: TStrings);\nbegin\n  GetTableNames(schemaPattern, tablePattern, nil,List);\nend;\n\n{**\n  Fills string list with table names.\n  @param tablePattern a pattern for table names.\n  @param schemaPattern a pattern for schema names.\n  @param types a TStringDynArray specifying the table types to look for.\n    possible values can be found by reading\n     TZAbstractConnection.DbcConnection.GetMetadata.GetTableTypes\n     eg. for PostGreSQL this includes :'TABLE', 'VIEW', 'INDEX', 'SEQUENCE',\n                                       'SYSTEM TABLE', 'SYSTEM TOAST TABLE',\n                                       'SYSTEM TOAST INDEX', 'SYSTEM VIEW',\n                                       'SYSTEM INDEX', 'TEMPORARY TABLE',\n                                       'TEMPORARY INDEX'\n  @param List a string list to fill out.\n}\nprocedure TZAbstractConnection.GetTableNames(const schemaPattern, tablePattern: string; Types: TStringDynArray; List: TStrings);\nvar\n  Metadata: IZDatabaseMetadata;\n  ResultSet: IZResultSet;\nbegin\n  CheckConnected;\n\n  List.Clear;\n  Metadata := DbcConnection.GetMetadata;\n  ResultSet := Metadata.GetTables('', schemaPattern, tablePattern, types);\n  while ResultSet.Next do\n    List.Add(ResultSet.GetStringByName('TABLE_NAME'));\nend;\n\n{**\n  Fills string list with column names.\n  @param TablePattern a pattern for table names.\n  @param ColumnPattern a pattern for column names.\n  @param List a string list to fill out.\n}\nprocedure TZAbstractConnection.GetColumnNames(const TablePattern, ColumnPattern: string; List: TStrings);\nvar\n  Metadata: IZDatabaseMetadata;\n  ResultSet: IZResultSet;\nbegin\n  CheckConnected;\n  List.Clear;\n  Metadata := DbcConnection.GetMetadata;\n  ResultSet := Metadata.GetColumns('', '', TablePattern, ColumnPattern);\n  while ResultSet.Next do\n    List.Add(ResultSet.GetStringByName('COLUMN_NAME'));\nend;\n\n{**\n  Fills string list with stored procedure names.\n  @param Pattern a pattern for table names.\n  @param List a string list to fill out.\n}\nprocedure TZAbstractConnection.GetStoredProcNames(const Pattern: string;\n  List: TStrings);\nvar\n  Metadata: IZDatabaseMetadata;\n  ResultSet: IZResultSet;\nbegin\n  CheckConnected;\n\n  List.Clear;\n  Metadata := DbcConnection.GetMetadata;\n  ResultSet := Metadata.GetProcedures('', '', Pattern);\n  while ResultSet.Next do\n    List.Add(ResultSet.GetStringByName('PROCEDURE_NAME'));\nend;\n\n{**\n  EgonHugeist Returns Database-Triggers\n  @Param TablePattern is a \"like\"-pattern to get Triggers of specified Table\n  @SchemaPattern is Pattern to filter Schema-Trigger\n  @List the Result-Trigger-List\n}\nprocedure TZAbstractConnection.GetTriggerNames(const TablePattern,\n  SchemaPattern: string; List: TStrings);\nbegin\n  CheckConnected;\n\n  List.Clear;\n  with DbcConnection.GetMetadata.GetTriggers('', SchemaPattern, TablePattern, '') do\n  begin\n    while Next do\n     List.Add(GetStringByName('TRIGGER_NAME'));\n    Close;\n  end;\nend;\n\n{**\n  EgonHugeist: Returns a EscapeState detectable String to inform the Tokenizer\n    to do no UTF8Encoding if neccessary\n  @param BinaryString Represents the BinaryString wich has to prepered\n  @Result: A Prepared String like '~<|1023|<~''Binary-data-string(1023 Bytes)''~<|1023|<~\n}\nfunction TZAbstractConnection.GetBinaryEscapeStringFromString(const BinaryString: AnsiString): String;\nbegin\n  CheckConnected;\n\n  if Assigned(FConnection) then\n    Result := FConnection.GetBinaryEscapeString(BinaryString);\nend;\n\n{**\n  EgonHugeist: Returns a BinaryState detectable String to inform the Tokenizer\n    to do no UTF8Encoding if neccessary\n  @param Strem Represents the Stream wich has to prepered\n  @Result: A Prepared String like '~<|1023|<~''Binary-data-string(1023 Char's)''~<|1023|<~\n}\nfunction TZAbstractConnection.GetBinaryEscapeStringFromStream(const Stream: TStream): String;\nvar\n  FBlobSize: Integer;\n  FBlobData: Pointer;\n  TempAnsi: AnsiString;\nbegin\n  CheckConnected;\n\n  if Assigned(FConnection) then\n  begin\n    if Assigned(Stream) then\n    begin\n      FBlobSize := Stream.Size;\n      if FBlobSize > 0 then\n      begin\n        GetMem(FBlobData, FBlobSize);\n        Stream.Position := 0;\n        Stream.ReadBuffer(FBlobData^, FBlobSize);\n      end\n      else\n        FBlobData := nil;\n    end\n    else\n    begin\n      FBlobSize := -1;\n      FBlobData := nil;\n    end;\n    if (FBlobSize > 0) and Assigned(FBlobData) then\n      System.SetString(TempAnsi, PAnsiChar(FBlobData), FBlobSize)\n    else\n      TempAnsi := '';\n    if Assigned(FBlobData) then\n      FreeMem(FBlobData);\n\n    Result := FConnection.GetBinaryEscapeString(TempAnsi);\n  end;\nend;\n\n{**\n  EgonHugeist: Returns a BinaryState detectable String to inform the Tokenizer\n    to do no UTF8Encoding if neccessary\n  @param FileNaem Represents the File wich has to prepered\n  @Result: A Prepared String like '~<|1023|<~''Binary-data-string(1023 Char's)''~<|1023|<~\n}\nfunction TZAbstractConnection.GetBinaryEscapeStringFromFile(const FileName: String): String;\nvar\n  FStream: TFileStream;\nbegin\n  CheckConnected;\n\n  if FileExists(FileName) then\n  begin\n    FStream := TFileStream.Create(FileName, fmOpenRead);\n    Result := GetBinaryEscapeStringFromStream(FStream);\n    FreeAndNil(FStream);\n  end;\nend;\n\n{**\n  EgonHugeist: Returns a detectable String to inform the Tokenizer\n    to do no UTF8Encoding if neccessary\n  @param Ansi Represents the AnsiString wich has to prepered\n  @Result: A Prepared String like '~<|1023|<~''Binary-data-string(1023 Char's)''~<|1023|<~\n}\nfunction TZAbstractConnection.GetAnsiEscapeString(const Ansi: AnsiString): String;\nbegin\n  Result := DbcConnection.GetDriver.GetTokenizer.GetEscapeString(String(Ansi));\nend;\n\nfunction TZAbstractConnection.GetURL: String;\nbegin\n  Result := ConstructURL(FURL.UserName, FURL.Password);\nend;\n\nfunction TZAbstractConnection.GetAutoEncode: Boolean;\nbegin\n  {$IFDEF UNICODE}\n  Result := True;\n  {$ELSE}\n    {$IF defined(MSWINDOWS) or defined(WITH_LCONVENCODING) or defined(FPC_HAS_BUILTIN_WIDESTR_MANAGER)}\n    if Connected then\n    begin\n      Result := DbcConnection.GetConSettings.AutoEncode;\n      FAutoEncode := Result;\n    end\n    else\n      Result := FAutoEncode;\n    {$ELSE}\n    Result := False;\n    {$IFEND}\n  {$ENDIF}\nend;\n\nprocedure TZAbstractConnection.SetAutoEncode(Value: Boolean);\nbegin\n  {$IFNDEF UNICODE}\n    {$IF defined(MSWINDOWS) or defined(WITH_LCONVENCODING) or defined(FPC_HAS_BUILTIN_WIDESTR_MANAGER)}\n    if Value then\n      FURL.Properties.Values['AutoEncodeStrings'] := 'ON'\n    else\n      FURL.Properties.Values['AutoEncodeStrings'] := '';\n\n    if Value <> FAutoEncode then\n    begin\n      FAutoEncode := Value;\n      if Self.Connected then\n      begin\n        Connected := False;\n        Connected := True;\n      end;\n    end;\n    {$ELSE}\n    FURL.Properties.Values['AutoEncodeStrings'] := '';\n    {$IFEND}\n  {$ENDIF}\nend;\n\n{**\n  Returns the current version of zeosdbo.\n}\nfunction TZAbstractConnection.GetVersion: string;\nbegin\n  Result := ZEOS_VERSION;\nend;\n\nprocedure TZAbstractConnection.SetUseMetadata(AValue: Boolean);\nbegin\n  if FUseMetaData=AValue then Exit;\n  FUseMetaData:=AValue;\n  if FConnection <> nil then\n    FConnection.SetUseMetadata(FUseMetadata);\nend;\n\nprocedure TZAbstractConnection.SetControlsCodePage(const Value: TZControlsCodePage);\n  procedure SetValue;\n  begin\n    {$IFDEF UNICODE}\n    case Value of\n      cCP_UTF16:\n        begin\n          Properties.values['controls_cp'] := 'CP_UTF16';\n          FControlsCodePage := Value;\n        end;\n      cCP_UTF8:\n        begin\n          Properties.values['controls_cp'] := 'CP_UTF16';\n          FControlsCodePage := cCP_UTF16;\n        end;\n      cGET_ACP:\n        begin\n          Properties.values['controls_cp'] := 'GET_ACP';\n          FControlsCodePage := Value;\n        end;\n    end;\n    {$ELSE}\n      {$IFDEF WITH_WIDEFIELDS}\n      case Value of\n        cCP_UTF16:\n          begin\n            Properties.values['controls_cp'] := 'CP_UTF16';\n            FControlsCodePage := Value;\n          end;\n        cCP_UTF8:\n          begin\n            Properties.values['controls_cp'] := 'CP_UTF8';\n            FControlsCodePage := Value;\n          end;\n        cGET_ACP:\n          if ZDefaultSystemCodePage = zCP_UTF8 then\n          begin\n            Properties.values['controls_cp'] := 'CP_UTF8';\n            FControlsCodePage := cCP_UTF8;\n          end\n          else\n          begin\n            Properties.values['controls_cp'] := 'GET_ACP';\n            FControlsCodePage := Value;\n          end;\n      end;\n      {$ELSE} //D7 or old FPC\n      case Value of\n        cCP_UTF16:\n          begin\n            Properties.values['controls_cp'] := 'CP_UTF8';\n            FControlsCodePage := cCP_UTF8;\n          end;\n        cCP_UTF8:\n          begin\n            Properties.values['controls_cp'] := 'CP_UTF8';\n            FControlsCodePage := Value;\n          end;\n        cGET_ACP:\n          if ZDefaultSystemCodePage = zCP_UTF8 then\n          begin\n            Properties.values['controls_cp'] := 'CP_UTF8';\n            FControlsCodePage := cCP_UTF8;\n          end\n          else\n          begin\n            Properties.values['controls_cp'] := 'GET_ACP';\n            FControlsCodePage := Value;\n          end;\n      end;\n      {$ENDIF}\n    {$ENDIF}\n  end;\nbegin\n  if Value <> FControlsCodePage then\n    if Connected then\n    begin\n      Connected := False;\n      SetValue;\n      Connected := True;\n    end\n    else\n      SetValue;\nend;\n\nprocedure TZAbstractConnection.SetVersion(const Value: string);\nbegin\nend;\n\nprocedure TZAbstractConnection.CloseAllSequences;\nvar\n  I: Integer;\n  Current: TZSequence;\nbegin\n  for I := 0 to FSequences.Count - 1 do\n  begin\n    Current := TZSequence(FSequences[I]);\n    try\n      Current.CloseSequence;\n    except\n      // Ignore.\n    end;\n  end;\nend;\n\nprocedure TZAbstractConnection.RegisterSequence(Sequence: TComponent);\nbegin\n  FSequences.Add(TZSequence(Sequence));\nend;\n\nprocedure TZAbstractConnection.UnregisterSequence(Sequence: TComponent);\nbegin\n  if Assigned(FSequences) then\n    FSequences.Remove(TZSequence(Sequence));\nend;\n\n{**\n  Executes the SQL statement immediately without the need of a TZQuery component\n  @param SQL the statement to be executed.\n  Returns an indication if execution was succesfull.\n}\nfunction TZAbstractConnection.ExecuteDirect(SQL : String) : boolean;\nvar\n  dummy : Integer;\nbegin\n  result:= ExecuteDirect(SQL,dummy);\nend;\n\n{**\n  Executes the SQL statement immediately without the need of a TZQuery component\n  @param SQL the statement to be executed.\n  @param RowsAffected the number of rows that were affected by the statement.\n  Returns an indication if execution was succesfull.\n}\nfunction TZAbstractConnection.ExecuteDirect(SQL: string;\n  var RowsAffected: integer):boolean;\nvar\n  stmt : IZStatement;\nbegin\n  try\n    try\n      CheckConnected;\n      stmt := DbcConnection.CreateStatement;\n      RowsAffected:= stmt.ExecuteUpdate(SQL);\n      result := (RowsAffected <> -1);\n    except\n      RowsAffected := -1;\n      result := False;\n      raise; {------ added by Henk 09-10-2012 --------}\n    end;\n  finally\n    stmt:=nil;\n  end;\nend;\n\ninitialization\n  SqlHourGlassLock := 0;\nend.\n\n"
  },
  {
    "path": "lib/zeosdbo/src/component/ZAbstractDataset.pas",
    "content": "{*********************************************************}\n{                                                         }\n{                 Zeos Database Objects                   }\n{          Abstract Read/Write Dataset component          }\n{                                                         }\n{        Originally written by Sergey Seroukhov           }\n{                                                         }\n{*********************************************************}\n\n{@********************************************************}\n{    Copyright (c) 1999-2012 Zeos Development Group       }\n{                                                         }\n{ License Agreement:                                      }\n{                                                         }\n{ This library is distributed in the hope that it will be }\n{ useful, but WITHOUT ANY WARRANTY; without even the      }\n{ implied warranty of MERCHANTABILITY or FITNESS FOR      }\n{ A PARTICULAR PURPOSE.  See the GNU Lesser General       }\n{ Public License for more details.                        }\n{                                                         }\n{ The source code of the ZEOS Libraries and packages are  }\n{ distributed under the Library GNU General Public        }\n{ License (see the file COPYING / COPYING.ZEOS)           }\n{ with the following  modification:                       }\n{ As a special exception, the copyright holders of this   }\n{ library give you permission to link this library with   }\n{ independent modules to produce an executable,           }\n{ regardless of the license terms of these independent    }\n{ modules, and to copy and distribute the resulting       }\n{ executable under terms of your choice, provided that    }\n{ you also meet, for each linked independent module,      }\n{ the terms and conditions of the license of that module. }\n{ An independent module is a module which is not derived  }\n{ from or based on this library. If you modify this       }\n{ library, you may extend this exception to your version  }\n{ of the library, but you are not obligated to do so.     }\n{ If you do not wish to do so, delete this exception      }\n{ statement from your version.                            }\n{                                                         }\n{                                                         }\n{ The project web site is located on:                     }\n{   http://zeos.firmos.at  (FORUM)                        }\n{   http://sourceforge.net/p/zeoslib/tickets/ (BUGTRACKER)}\n{   svn://svn.code.sf.net/p/zeoslib/code-0/trunk (SVN)    }\n{                                                         }\n{   http://www.sourceforge.net/projects/zeoslib.          }\n{                                                         }\n{                                                         }\n{                                 Zeos Development Group. }\n{********************************************************@}\n\nunit ZAbstractDataset;\n\ninterface\n\n{$I ZComponent.inc}\n\nuses\n  Variants,\n  SysUtils,  Classes, {$IFDEF MSEgui}mdb, mclasses{$ELSE}DB{$ENDIF},\n  ZSqlUpdate, ZDbcIntfs, ZVariant, ZDbcCache, ZDbcCachedResultSet,\n  ZAbstractRODataset, ZCompatibility, ZSequence;\n\ntype\n  {$IFDEF oldFPC} // added in 2006, probably pre 2.2.4\n  TUpdateAction = (uaFail, uaAbort, uaSkip, uaRetry, uaApplied);\n  {$ENDIF}\n\n  {** Update Event type. }\n  TUpdateRecordEvent = procedure(DataSet: TDataSet; UpdateKind: TUpdateKind;\n    var UpdateAction: TUpdateAction) of object;\n\n  {** Defines update modes for the resultsets. }\n  TZUpdateMode = (umUpdateChanged, umUpdateAll);\n\n  {** Defines where form types for resultsets. }\n  TZWhereMode = (wmWhereKeyOnly, wmWhereAll);\n\n  {**\n    Abstract dataset component which supports read/write access and\n    cached updates.\n  }\n  TZAbstractDataset = class(TZAbstractRODataset)\n  private\n    FCachedUpdatesBeforeMasterUpdate: Boolean;\n    FCachedUpdates: Boolean;\n    FUpdateObject: TZUpdateSQL;\n    FCachedResultSet: IZCachedResultSet;\n    FCachedResolver: IZCachedResolver;\n    FOnApplyUpdateError: TDataSetErrorEvent;\n    FOnUpdateRecord: TUpdateRecordEvent;\n    FUpdateMode: TZUpdateMode;\n    FWhereMode: TZWhereMode;\n    FSequence: TZSequence;\n    FSequenceField: string;\n\n    FBeforeApplyUpdates: TNotifyEvent; {bangfauzan addition}\n    FAfterApplyUpdates: TNotifyEvent; {bangfauzan addition}\n    FDetailDataSets: TList;\n    FDetailCachedUpdates: array of Boolean;\n  private\n    function GetUpdatesPending: Boolean;\n    procedure SetUpdateObject(Value: TZUpdateSQL);\n    procedure SetCachedUpdates(Value: Boolean);\n    procedure SetWhereMode(Value: TZWhereMode);\n    procedure SetUpdateMode(Value: TZUpdateMode);\n\n  protected\n    property CachedResultSet: IZCachedResultSet read FCachedResultSet\n      write FCachedResultSet;\n    property CachedResolver: IZCachedResolver read FCachedResolver\n      write FCachedResolver;\n    property UpdateMode: TZUpdateMode read FUpdateMode write SetUpdateMode\n      default umUpdateChanged;\n    property WhereMode: TZWhereMode read FWhereMode write SetWhereMode\n      default wmWhereKeyOnly;\n\n    procedure InternalClose; override;\n    procedure InternalEdit; override;\n    procedure InternalAddRecord(Buffer: Pointer; Append: Boolean); override;\n    procedure InternalPost; override;\n    procedure InternalDelete; override;\n    procedure InternalUpdate;\n    procedure InternalCancel; override;\n\n    procedure DOBeforeApplyUpdates; {bangfauzan addition}\n    procedure DOAfterApplyUpdates; {bangfauzan addition}\n\n\n    function CreateStatement(const SQL: string; Properties: TStrings):\n      IZPreparedStatement; override;\n    function CreateResultSet(const SQL: string; MaxRows: Integer):\n      IZResultSet; override;\n    procedure Notification(AComponent: TComponent; Operation: TOperation);\n      override;\n\n  {$IFDEF WITH_IPROVIDER}\n    function PSUpdateRecord(UpdateKind: TUpdateKind;\n      Delta: TDataSet): Boolean; override;\n  {$ENDIF}\n    procedure RegisterDetailDataSet(Value: TZAbstractDataset; CachedUpdates: Boolean);\n    procedure DisposeCachedUpdates;\n  public\n    constructor Create(AOwner: TComponent); override;\n    destructor Destroy; override;\n\n    procedure ApplyUpdates;\n    procedure CommitUpdates;\n    procedure CancelUpdates;\n    procedure RevertRecord;\n    procedure RefreshCurrentRow(const RefreshDetails:Boolean); //FOS+ 07112006\n\n    procedure EmptyDataSet; {bangfauzan addition}\n\n  public\n    property UpdatesPending: Boolean read GetUpdatesPending;\n    property Sequence: TZSequence read FSequence write FSequence;\n    property SequenceField: string read FSequenceField write FSequenceField;\n\n  published\n    property UpdateObject: TZUpdateSQL read FUpdateObject write SetUpdateObject;\n    property CachedUpdates: Boolean read FCachedUpdates write SetCachedUpdates\n      default False;\n\n    property OnApplyUpdateError: TDataSetErrorEvent read FOnApplyUpdateError\n      write FOnApplyUpdateError;\n    property OnUpdateRecord: TUpdateRecordEvent read FOnUpdateRecord\n      write FOnUpdateRecord;\n\n    property BeforeApplyUpdates: TNotifyEvent read FBeforeApplyUpdates\n      write FBeforeApplyUpdates; {bangfauzan addition}\n    property AfterApplyUpdates: TNotifyEvent read FAfterApplyUpdates\n      write FAfterApplyUpdates; {bangfauzan addition}\n\n\n  published\n    property BeforeInsert;\n    property AfterInsert;\n    property BeforeEdit;\n    property AfterEdit;\n    property BeforePost;\n    property AfterPost;\n    property BeforeCancel;\n    property AfterCancel;\n    property BeforeDelete;\n    property AfterDelete;\n    property OnDeleteError;\n    property OnEditError;\n    property OnPostError;\n    property OnNewRecord;\n  end;\n\nimplementation\n\nuses Math, ZMessages, ZDatasetUtils;\n\n{ TZAbstractDataset }\n\n{**\n  Constructs this object and assignes the mail properties.\n  @param AOwner a component owner.\n}\nconstructor TZAbstractDataset.Create(AOwner: TComponent);\nbegin\n  inherited Create(AOwner);\n\n  FWhereMode := wmWhereKeyOnly;\n  FUpdateMode := umUpdateChanged;\n  RequestLive := True;\n  FDetailDataSets := TList.Create;\nend;\n\n{**\n  Destroys this object and cleanups the memory.\n}\ndestructor TZAbstractDataset.Destroy;\nbegin\n  FreeAndNil(FDetailDataSets);\n  inherited Destroy;\nend;\n\n{**\n  Sets a new UpdateSQL object.\n  @param Value a new UpdateSQL object.\n}\nprocedure TZAbstractDataset.SetUpdateObject(Value: TZUpdateSQL);\nbegin\n  if FUpdateObject <> Value then\n  begin\n    if Assigned(FUpdateObject) then\n      FUpdateObject.RemoveFreeNotification(Self);\n    FUpdateObject := Value;\n    if Assigned(FUpdateObject) then\n      FUpdateObject.FreeNotification(Self);\n    if Assigned(FUpdateObject) then\n      FUpdateObject.DataSet := Self;\n    if Active and (CachedResultSet <> nil) then\n    begin\n      if FUpdateObject <> nil then\n        CachedResultSet.SetResolver(FUpdateObject)\n      else\n        CachedResultSet.SetResolver(CachedResolver);\n    end;\n  end;\nend;\n\n{**\n  Sets a new CachedUpdates property value.\n  @param Value a new CachedUpdates value.\n}\nprocedure TZAbstractDataset.SetCachedUpdates(Value: Boolean);\nbegin\n  if FCachedUpdates <> Value then\n  begin\n    FCachedUpdates := Value;\n    if Active and (CachedResultSet <> nil) then\n      CachedResultSet.SetCachedUpdates(Value);\n  end;\nend;\n\n{**\n  Sets a new UpdateMode property value.\n  @param Value a new UpdateMode value.\n}\nprocedure TZAbstractDataset.SetUpdateMode(Value: TZUpdateMode);\nbegin\n  if FUpdateMode <> Value then\n  begin\n    FUpdateMode := Value;\n    if Active then\n      Close;\n  end;\nend;\n\n{**\n  Sets a new WhereMode property value.\n  @param Value a new WhereMode value.\n}\nprocedure TZAbstractDataset.SetWhereMode(Value: TZWhereMode);\nbegin\n  if FWhereMode <> Value then\n  begin\n    FWhereMode := Value;\n    if Active then\n      Close;\n  end;\nend;\n\n{**\n  Creates a DBC statement for the query.\n  @param SQL an SQL query.\n  @param Properties a statement specific properties.\n  @returns a created DBC statement.\n}\nfunction TZAbstractDataset.CreateStatement(\n  const SQL: string; Properties: TStrings): IZPreparedStatement;\nvar\n  Temp: TStrings;\nbegin\n  Temp := TStringList.Create;\n  try\n    Temp.AddStrings(Properties);\n\n    { Sets update mode property.}\n    case FUpdateMode of\n      umUpdateAll: Temp.Values['update'] := 'all';\n      umUpdateChanged: Temp.Values['update'] := 'changed';\n    end;\n    { Sets where mode property. }\n    case FWhereMode of\n      wmWhereAll: Temp.Values['where'] := 'all';\n      wmWhereKeyOnly: Temp.Values['where'] := 'keyonly';\n    end;\n\n    Result := inherited CreateStatement(SQL, Temp);\n  finally\n    Temp.Free;\n  end;\nend;\n\n{**\n  Creates a DBC resultset for the query.\n  @param SQL an SQL query.\n  @param MaxRows a maximum rows number (-1 for all).\n  @returns a created DBC resultset.\n}\nfunction TZAbstractDataset.CreateResultSet(const SQL: string; MaxRows: Integer):\n  IZResultSet;\nbegin\n  Result := inherited CreateResultSet(SQL, MaxRows);\n\n  if not Assigned(Result) then\n    Exit;\n\n  if Result.QueryInterface(IZCachedResultSet, FCachedResultSet) = 0 then\n  begin\n    CachedResultSet := Result as IZCachedResultSet;\n    CachedResolver := CachedResultSet.GetResolver;\n    CachedResultSet.SetCachedUpdates(CachedUpdates);\n    if FUpdateObject <> nil then\n      CachedResultSet.SetResolver(FUpdateObject);\n  end;\nend;\n\n{**\n  Performs internal query closing.\n}\nprocedure TZAbstractDataset.InternalClose;\nbegin\n  inherited InternalClose;\n\n  if not DoNotCloseResultset then\n  begin\n    if Assigned(CachedResultSet) then\n      CachedResultSet.Close;\n    CachedResultSet := nil;\n    CachedResolver := nil;\n  end;\nend;\n\n{**\n  Performs an internal action before switch into edit mode.\n}\nprocedure TZAbstractDataset.InternalEdit;\nbegin\nend;\n\n{**\n  Performs an internal record updates.\n}\n{$IFDEF FPC}\n  {$HINTS OFF}\n{$ENDIF}\nprocedure TZAbstractDataset.InternalUpdate;\nvar\n  RowNo: Integer;\n  RowBuffer: PZRowBuffer;\nbegin\n  if (CachedResultSet <> nil) and GetActiveBuffer(RowBuffer) then\n  begin\n    RowNo := Integer(CurrentRows[CurrentRow - 1]);\n    CachedResultSet.MoveAbsolute(RowNo);\n    RowAccessor.RowBuffer := RowBuffer;\n    PostToResultSet(CachedResultSet, FieldsLookupTable, Fields, RowAccessor);\n    try\n      CachedResultSet.UpdateRow;\n    except on E: EZSQLThrowable do\n      raise EZDatabaseError.CreateFromException(E);\n    end;\n\n    { Filters the row }\n    if not FilterRow(RowNo) then\n    begin\n      CurrentRows.Delete(CurrentRow - 1);\n      CurrentRow := Min(CurrentRows.Count, CurrentRow);\n    end;\n  end;\nend;\n{$IFDEF FPC}\n  {$HINTS ON}\n{$ENDIF}\n\n{**\n  Performs an internal adding a new record.\n  @param Buffer a buffer of the new adding record.\n  @param Append <code>True</code> if record should be added to the end\n    of the result set.\n}\n{$IFDEF FPC}\n  {$HINTS OFF}\n{$ENDIF}\nprocedure TZAbstractDataset.InternalAddRecord(Buffer: Pointer; Append: Boolean);\nvar\n  RowNo: Integer;\n  RowBuffer: PZRowBuffer;\nbegin\n  if not GetActiveBuffer(RowBuffer) or (RowBuffer <> Buffer) then\n    raise EZDatabaseError.Create(SInternalError);\n\n  if Append then\n    FetchRows(0);\n\n  if CachedResultSet <> nil then\n  begin\n    CachedResultSet.MoveToInsertRow;\n    RowAccessor.RowBuffer := RowBuffer;\n    PostToResultSet(CachedResultSet, FieldsLookupTable, Fields, RowAccessor);\n    try\n      CachedResultSet.InsertRow;\n    except on E: EZSQLThrowable do\n      raise EZDatabaseError.CreateFromException(E);\n    end;\n    RowNo := CachedResultSet.GetRow;\n    FetchCount := FetchCount + 1;\n\n    { Filters the row }\n    if FilterRow(RowNo) then\n    begin\n      if Append then\n      begin\n        CurrentRows.Add(Pointer(RowNo));\n        CurrentRow := CurrentRows.Count;\n      end\n      else\n      begin\n        CurrentRow := Max(CurrentRow, 1);\n        CurrentRows.Insert(CurrentRow - 1, Pointer(RowNo));\n      end;\n    end;\n  end;\nend;\n{$IFDEF FPC}\n  {$HINTS ON}\n{$ENDIF}\n\n\n{**\n  Performs an internal post updates.\n}\n{$IFDEF FPC}\n  {$HINTS OFF}\n{$ENDIF}\nprocedure TZAbstractDataset.InternalPost;\nvar\n  RowBuffer: PZRowBuffer;\n  {$IFDEF WITH_TBOOKMARK}\n  BM: TBookMark;\n  {$ELSE}\n  BM:TBookMarkStr;\n  {$ENDIF}\n  I: Integer;\nbegin\n  if (FSequenceField <> '') and Assigned(FSequence) then\n  begin\n    if FieldByName(FSequenceField).IsNull then\n      FieldByName(FSequenceField).Value := FSequence.GetNextValue;\n  end;\n\n  //inherited;  //AVZ - Firebird defaults come through when this is commented out\n\n\n  if not GetActiveBuffer(RowBuffer) then\n    raise EZDatabaseError.Create(SInternalError);\n\n  Connection.ShowSqlHourGlass;\n  try\n    //revert Master Detail updates makes it possible to update\n    // with ForeignKey contraints\n    if Assigned(MasterLink.DataSet) then\n      if (TDataSet(MasterLink.DataSet) is TZAbstractDataset) then\n        if ( doUpdateMasterFirst in TZAbstractDataset(MasterLink.DataSet).Options )\n         or ( doUpdateMasterFirst in Options ) then\n        begin //This is an detail-table\n          FCachedUpdatesBeforeMasterUpdate := CachedUpdates; //buffer old value\n          if not(CachedUpdates) then\n            CachedUpdates := True; //Execute without writing\n          TZAbstractDataset(MasterLink.DataSet).RegisterDetailDataSet(Self,\n            TZAbstractDataset(MasterLink.DataSet).CachedUpdates);\n        end;\n\n    if State = dsInsert then\n      InternalAddRecord(RowBuffer, False)\n    else\n      InternalUpdate;\n\n    // Apply Detail updates now\n    if FDetailDataSets.Count > 0 then\n      for i := 0 to FDetailDataSets.Count -1 do\n        if (TDataSet(FDetailDataSets.Items[i]) is TZAbstractDataset) then\n          begin\n            if not (Self.FDetailCachedUpdates[I]) then\n              TZAbstractDataset(TDataSet(FDetailDataSets.Items[i])).ApplyUpdates;\n            TZAbstractDataset(TDataSet(FDetailDataSets.Items[i])).CachedUpdates := Self.FDetailCachedUpdates[I];\n          end;\n    FDetailDataSets.Clear;\n    SetLength(FDetailCachedUpdates, 0);\n\n    {BUG-FIX: bangfauzan addition}\n    if (SortedFields <> '') and not (doDontSortOnPost in Options) then\n    begin\n      FreeFieldBuffers;\n      SetState(dsBrowse);\n      Resync([]);\n      BM := Bookmark;\n      if BookmarkValid({$IFDEF WITH_TBOOKMARK}BM{$ELSE}@BM{$ENDIF}) Then\n      begin\n        InternalGotoBookmark({$IFDEF WITH_TBOOKMARK}BM{$ELSE}@BM{$ENDIF});\n        Resync([rmExact, rmCenter]);\n      end;\n      DisableControls;\n      InternalSort;\n      BookMark:=BM;\n      UpdateCursorPos;\n      EnableControls;\n    end;\n    {end of bangfauzan addition}\n  finally\n    Connection.HideSqlHourGlass;\n    //DetailLinks.Free;\n  end;\nend;\n\n{**\n  Performs an internal record removing.\n}\nprocedure TZAbstractDataset.InternalDelete;\nvar\n  RowNo: Integer;\n  RowBuffer: PZRowBuffer;\nbegin\n  if (CachedResultSet <> nil) and GetActiveBuffer(RowBuffer) then\n  begin\n    Connection.ShowSqlHourGlass;\n    try\n      RowNo := Integer(CurrentRows[CurrentRow - 1]);\n      CachedResultSet.MoveAbsolute(RowNo);\n      try\n        CachedResultSet.DeleteRow;\n      except on E: EZSQLThrowable do\n        raise EZDatabaseError.CreateFromException(E);\n      end;\n\n      { Filters the row }\n      if not FilterRow(RowNo) then\n      begin\n        CurrentRows.Delete(CurrentRow - 1);\n        if not FetchRows(CurrentRow) then\n          CurrentRow := Min(CurrentRows.Count, CurrentRow);\n      end;\n    finally\n      Connection.HideSQLHourGlass;\n    end;\n  end;\nend;\n\n{**\n  Performs an internal cancel updates.\n}\nprocedure TZAbstractDataset.InternalCancel;\nvar\n  RowNo: Integer;\n  RowBuffer: PZRowBuffer;\nbegin\n  if (CachedResultSet <> nil) and GetActiveBuffer(RowBuffer)\n    and (CurrentRow > 0) and (State = dsEdit) then\n  begin\n    RowNo := Integer(CurrentRows[CurrentRow - 1]);\n    CachedResultSet.MoveAbsolute(RowNo);\n    RowAccessor.RowBuffer := RowBuffer;\n    FetchFromResultSet(CachedResultSet, FieldsLookupTable, Fields,\n         RowAccessor);\n  end;\nend;\n{$IFDEF FPC}\n  {$HINTS ON}\n{$ENDIF}\n\n{**\n  Processes component notifications.\n  @param AComponent a changed component object.\n  @param Operation a component operation code.\n}\nprocedure TZAbstractDataset.Notification(AComponent: TComponent;\n  Operation: TOperation);\nbegin\n  inherited Notification(AComponent, Operation);\n\n  if (Operation = opRemove) then\n  begin\n    if (AComponent = FUpdateObject) then\n    begin\n      Close;\n      FUpdateObject := nil;\n    end;\n    if (AComponent = FSequence) then\n    begin\n      FSequence := nil;\n    end;\n  end;\nend;\n\n{**\n   Applies all cached updates stored in the resultset.\n}\nprocedure TZAbstractDataset.ApplyUpdates;\nbegin\n  if not Active then\n    Exit;\n\n  Connection.ShowSQLHourGlass;\n  try\n    if State in [dsEdit, dsInsert] then\n       Post;\n\n    DoBeforeApplyUpdates; {bangfauzan addition}\n\n    if CachedResultSet <> nil then\n      if Connection.AutoCommit and\n        not ( Connection.TransactIsolationLevel in [tiReadCommitted, tiSerializable] ) then\n        CachedResultSet.PostUpdates\n      else\n        CachedResultSet.PostUpdatesCached;\n\n    if not (State in [dsInactive]) then\n      Resync([]);\n\n  DOAfterApplyUpdates; {bangfauzan addition}\n\n  finally\n    Connection.HideSqlHourGlass;\n  end;\nend;\n\n{**\n   Dispose all cached updates stored in the resultset.\n}\nprocedure TZAbstractDataset.DisposeCachedUpdates;\nbegin\n  if Active then\n    if Assigned(CachedResultSet) then\n      CachedResultSet.DisposeCachedUpdates;\nend;\n\n{**\n  Clears cached updates buffer.\n}\nprocedure TZAbstractDataset.CommitUpdates;\nbegin\n  CheckBrowseMode;\n\n  if CachedResultSet <> nil then\n    CachedResultSet.CancelUpdates;\nend;\n\n{**\n  Cancels all cached updates and clears the buffer.\n}\nprocedure TZAbstractDataset.CancelUpdates;\nbegin\n  if State in [dsEdit, dsInsert] then\n    Cancel;\n\n  if CachedResultSet <> nil then\n    CachedResultSet.CancelUpdates;\n\n  if not (State in [dsInactive]) then\n    RereadRows;\nend;\n\n{**\n  Reverts the previous status for the current row.\n}\nprocedure TZAbstractDataset.RefreshCurrentRow(const RefreshDetails:Boolean);\nvar\n    RowNo: integer;\n    i: Integer;\n    ostate:TDataSetState;\nbegin\n  if State=dsBrowse then\n  begin\n    if CachedResultSet <> nil then\n    begin\n      UpdateCursorPos;\n      RowNo := Integer(CurrentRows[CurrentRow - 1]);\n      CachedResultSet.MoveAbsolute(RowNo);\n      CachedResultSet.RefreshRow;\n      if not (State in [dsInactive]) then\n      begin\n        if RefreshDetails then\n          Resync([])\n        else\n        begin\n          FetchFromResultSet(ResultSet, FieldsLookupTable, Fields, RowAccessor);\n          ostate:=State;\n          SetTempState(dsInternalCalc);\n          try\n            for I := 0 to Fields.Count - 1 do\n              DataEvent(deFieldChange,ULong(Fields[i]));\n          finally\n            RestoreState(ostate);\n          end;\n        end;\n      end;\n    end;\n  end\n  else\n  begin\n    raise EZDatabaseError.Create(SInternalError);\n  end;\nend;\n\n\nprocedure TZAbstractDataset.RevertRecord;\nbegin\n  if State in [dsInsert] then\n  begin\n    Cancel;\n    Exit;\n  end;\n  if State in [dsEdit] then\n    Cancel;\n\n  if CachedResultSet <> nil then\n    CachedResultSet.RevertRecord;\n\n  if not (State in [dsInactive]) then\n    Resync([]);\nend;\n\n{**\n  Checks is there cached updates pending in the buffer.\n  @return <code>True</code> if there some pending cached updates.\n}\nfunction TZAbstractDataset.GetUpdatesPending: Boolean;\nbegin\n  if State = dsInactive then\n    Result := False\n  else if (CachedResultSet <> nil) and CachedResultSet.IsPendingUpdates then\n    Result := True\n  else if (State in [dsInsert, dsEdit]) then\n    Result := Modified\n  else\n    Result := False;\nend;\n\n{$IFDEF WITH_IPROVIDER}\n\n{**\n  Applies a single update to the underlying database table or tables.\n  @param UpdateKind an update type.\n  @param Delta a dataset where the current position shows the row to update.\n  @returns <code>True</code> if updates were successfully applied.\n}\n{$IFDEF FPC}\n  {$HINTS OFF}\n{$ENDIF}\nfunction TZAbstractDataset.PSUpdateRecord(UpdateKind: TUpdateKind;\n  Delta: TDataSet): Boolean;\n\nvar\n  Bookmark: TBookmark;\n  ActiveMode: Boolean;\n  UpdateMode: Boolean;\n\n  function LocateRecord: Boolean;\n  var\n    I: Integer;\n    KeyFields: string;\n    Temp: Variant;\n    SrcField: TField;\n    KeyValues: Variant;\n    FieldRefs: TObjectDynArray;\n    OnlyDataFields: Boolean;\n  begin\n    if Properties.Values['KeyFields'] <> '' then\n      KeyFields := Properties.Values['KeyFields']\n    else\n      KeyFields := DefineKeyFields(Fields);\n    FieldRefs := DefineFields(Self, KeyFields, OnlyDataFields);\n    Temp := VarArrayCreate([0, Length(FieldRefs) - 1], varVariant);\n\n    for I := 0 to Length(FieldRefs) - 1 do\n    begin\n      SrcField := Delta.FieldByName(TField(FieldRefs[I]).FieldName);\n      if SrcField <> nil then\n      begin\n          Temp[I] := SrcField.OldValue;\n      end\n      else\n        Temp[I] := Null;\n    end;\n\n    if Length(FieldRefs) = 1 then\n      KeyValues := Temp[0]\n    else\n      KeyValues := Temp;\n\n    if KeyFields <> '' then\n      Result := Locate(KeyFields, KeyValues, [])\n    else\n      Result := False;\n  end;\n\n  procedure CopyRecord(SrcDataset: TDataset; DestDataset: TDataset);\n  var\n    I: Integer;\n    SrcField: TField;\n    DestField: TField;\n    SrcStream: TStream;\n    DestStream: TStream;\n  begin\n    for I := 0 to DestDataset.FieldCount - 1 do\n    begin\n      DestField := DestDataset.Fields[I];\n      SrcField := SrcDataset.FieldByName(DestField.FieldName);\n      if (SrcField = nil) or VarIsEmpty(SrcField.NewValue) then\n        Continue;\n\n      if SrcField.IsNull then\n      begin\n        DestField.Clear;\n        Continue;\n      end;\n\n      case DestField.DataType of\n        ftLargeInt:\n          begin\n            if SrcField.DataType = ftLargeInt then\n            begin\n              TLargeIntField(DestField).AsLargeInt :=\n                TLargeIntField(SrcField).AsLargeInt;\n            end\n            else\n              DestField.AsInteger := SrcField.AsInteger;\n          end;\n        ftBlob, ftMemo {$IFDEF WITH_WIDEMEMO}, ftWideMemo{$ENDIF}:\n          begin\n            if SrcField.DataType in [ftBlob, ftMemo {$IFDEF WITH_WIDEMEMO}, ftWideMemo{$ENDIF}] then\n            begin\n              SrcStream := SrcDataset.CreateBlobStream(SrcField, bmRead);\n              try\n                DestStream := DestDataset.CreateBlobStream(DestField, bmWrite);\n                try\n                  DestStream.CopyFrom(SrcStream, 0);\n                finally\n                  DestStream.Free;\n                end;\n              finally\n                SrcStream.Free;\n              end;\n            end\n            else\n              DestField.AsVariant := SrcField.AsVariant;\n          end;\n        else\n          DestField.AsVariant := SrcField.AsVariant;\n      end;\n    end;\n  end;\n\nbegin\n  Result := False;\n  ActiveMode := Self.Active;\n  UpdateMode := Self.RequestLive;\n\n  if Self.RequestLive = False then\n    Self.RequestLive := True;\n  if Self.Active = False then\n    Self.Open;\n\n  CheckBrowseMode;\n  try\n    Self.DisableControls;\n\n    { Saves the current position. }\n    Bookmark := Self.GetBookmark;\n\n    { Applies updates. }\n    try\n      case UpdateKind of\n        ukModify:\n          begin\n            if LocateRecord then\n            begin\n              Self.Edit;\n              CopyRecord(Delta, Self);\n              Self.Post;\n              Result := True;\n            end;\n          end;\n        ukInsert:\n          begin\n            Self.Append;\n            CopyRecord(Delta, Self);\n            Self.Post;\n            Result := True;\n          end;\n        ukDelete:\n          begin\n            if LocateRecord then\n            begin\n              Self.Delete;\n              Result := True;\n            end;\n          end;\n      end;\n    except\n      Result := False;\n    end;\n\n    { Restores the previous position. }\n    try\n      Self.GotoBookmark(Bookmark);\n    except\n      Self.First;\n    end;\n    Self.FreeBookmark(Bookmark);\n  finally\n    EnableControls;\n    Self.RequestLive := UpdateMode;\n    Self.Active := ActiveMode;\n  end;\nend;\n{$IFDEF FPC}\n  {$HINTS ON}\n{$ENDIF}\n\n{$ENDIF}\nprocedure TZAbstractDataset.RegisterDetailDataSet(Value: TZAbstractDataset;\n  CachedUpdates: Boolean);\nbegin\n  FDetailDataSets.Add(Value);\n  SetLength(Self.FDetailCachedUpdates, Length(FDetailCachedUpdates)+1);\n  FDetailCachedUpdates[High(FDetailCachedUpdates)] := CachedUpdates;\nend;\n\n{============================bangfauzan addition===================}\n\nprocedure TZAbstractDataset.DOBeforeApplyUpdates;\nbegin\n  if assigned(BeforeApplyUpdates) then\n    FBeforeApplyUpdates(Self);\nend;\n\nprocedure TZAbstractDataset.DOAfterApplyUpdates;\nbegin\n  if assigned(AfterApplyUpdates) then\n    FAfterApplyUpdates(Self);\nend;\n\nprocedure TZAbstractDataset.EmptyDataSet;\nbegin\n  if Active then\n  begin\n    Self.CancelUpdates;\n    Self.CurrentRows.Clear;\n    Self.CurrentRow:=0;\n    Resync([]);\n    InitRecord(ActiveBuffer);\n  end;\nend;\n\n{========================end of bangfauzan addition================}\n\nend.\n\n"
  },
  {
    "path": "lib/zeosdbo/src/component/ZAbstractRODataset.pas",
    "content": "{*********************************************************}\n{                                                         }\n{                 Zeos Database Objects                   }\n{          Abstract Read/Only Dataset component           }\n{                                                         }\n{        Originally written by Sergey Seroukhov           }\n{                                                         }\n{*********************************************************}\n\n{@********************************************************}\n{    Copyright (c) 1999-2012 Zeos Development Group       }\n{                                                         }\n{ License Agreement:                                      }\n{                                                         }\n{ This library is distributed in the hope that it will be }\n{ useful, but WITHOUT ANY WARRANTY; without even the      }\n{ implied warranty of MERCHANTABILITY or FITNESS FOR      }\n{ A PARTICULAR PURPOSE.  See the GNU Lesser General       }\n{ Public License for more details.                        }\n{                                                         }\n{ The source code of the ZEOS Libraries and packages are  }\n{ distributed under the Library GNU General Public        }\n{ License (see the file COPYING / COPYING.ZEOS)           }\n{ with the following  modification:                       }\n{ As a special exception, the copyright holders of this   }\n{ library give you permission to link this library with   }\n{ independent modules to produce an executable,           }\n{ regardless of the license terms of these independent    }\n{ modules, and to copy and distribute the resulting       }\n{ executable under terms of your choice, provided that    }\n{ you also meet, for each linked independent module,      }\n{ the terms and conditions of the license of that module. }\n{ An independent module is a module which is not derived  }\n{ from or based on this library. If you modify this       }\n{ library, you may extend this exception to your version  }\n{ of the library, but you are not obligated to do so.     }\n{ If you do not wish to do so, delete this exception      }\n{ statement from your version.                            }\n{                                                         }\n{                                                         }\n{ The project web site is located on:                     }\n{   http://zeos.firmos.at  (FORUM)                        }\n{   http://sourceforge.net/p/zeoslib/tickets/ (BUGTRACKER)}\n{   svn://svn.code.sf.net/p/zeoslib/code-0/trunk (SVN)    }\n{                                                         }\n{   http://www.sourceforge.net/projects/zeoslib.          }\n{                                                         }\n{                                                         }\n{                                 Zeos Development Group. }\n{********************************************************@}\n\nunit ZAbstractRODataset;\n\ninterface\n\n{$I ZComponent.inc}\n\nuses\n{$IFNDEF UNIX}\n  Windows,\n{$ENDIF}\n  Variants,\n  Types, SysUtils, Classes, {$IFDEF MSEgui}mclasses, mdb{$ELSE}DB{$ENDIF},\n  ZSysUtils, ZAbstractConnection, ZDbcIntfs, ZSqlStrings,\n  Contnrs, ZDbcCache, ZDbcCachedResultSet, ZCompatibility, ZExpression\n  {$IFDEF WITH_GENERIC_TLISTTFIELD}, Generics.Collections{$ENDIF};\n\ntype\n  {$IFDEF xFPC} // fixed in r3943 or earlier 2006-06-25\n  TUpdateStatusSet = set of TUpdateStatus;\n\n  EUpdateError = class(EDatabaseError)\n  end;\n  {$ENDIF}\n\n  TSortType = (stAscending, stDescending, stIgnored);   {bangfauzan addition}\n\n  {** Options for dataset. }\n  TZDatasetOption = (doOemTranslate, doCalcDefaults, doAlwaysDetailResync,\n    doSmartOpen, doPreferPrepared, doDontSortOnPost, doUpdateMasterFirst);\n\n  {** Set of dataset options. }\n  TZDatasetOptions = set of TZDatasetOption;\n\n  // Forward declarations.\n  TZAbstractRODataset = class;\n\n  {** Implements a Zeos specific database exception with SQL error code. }\n  EZDatabaseError = class(EDatabaseError)\n  private\n    FErrorCode: Integer;\n    FStatusCode: String;\n    procedure SetStatusCode(const Value: String);\n   public\n    constructor Create(const Msg: string);\n    constructor CreateFromException(E: EZSQLThrowable);\n\n    property ErrorCode: Integer read FErrorCode write FErrorCode;\n    property StatusCode: String read FStatusCode write SetStatusCode;\n  end;\n\n  {** Dataset Linker class. }\n  TZDataLink = class(TMasterDataLink)\n  private\n    FDataset: TZAbstractRODataset;\n  protected\n    procedure ActiveChanged; override;\n    procedure RecordChanged(Field: TField); override;\n  public\n    constructor Create(ADataset: TZAbstractRODataset); {$IFDEF FPC}reintroduce;{$ENDIF}\n  end;\n\n  {** Abstract dataset component optimized for read/only access. }\n  {$IFDEF WITH_WIDEDATASET}\n  TZAbstractRODataset = class(TWideDataSet)\n  {$ELSE}\n  TZAbstractRODataset = class(TDataSet)\n  {$ENDIF}\n  private\n{$IFNDEF WITH_FUNIDIRECTIONAL}\n    FUniDirectional: Boolean;\n{$ENDIF}\n    FCurrentRow: Integer;\n    FRowAccessor: TZRowAccessor;\n    FOldRowBuffer: PZRowBuffer;\n    FNewRowBuffer: PZRowBuffer;\n    FCurrentRows: TZSortedList;\n    FFetchCount: Integer;\n    FFieldsLookupTable: TIntegerDynArray;\n    FRowsAffected: Integer;\n\n    FFilterEnabled: Boolean;\n    FFilterExpression: IZExpression;\n    FFilterStack: TZExecutionStack;\n    FFilterFieldRefs: TObjectDynArray;\n    FInitFilterFields: Boolean;\n\n    FRequestLive: Boolean;\n    FFetchRow: integer;    // added by Patyi\n\n    FSQL: TZSQLStrings;\n    FParams: TParams;\n    FShowRecordTypes: TUpdateStatusSet;\n    FOptions: TZDatasetOptions;\n\n    FProperties: TStrings;\n    FConnection: TZAbstractConnection;\n    FStatement: IZPreparedStatement;\n    FResultSet: IZResultSet;\n\n    FRefreshInProgress: Boolean;\n\n    FDataLink: TDataLink;\n    FMasterLink: TMasterDataLink;\n    FLinkedFields: string; {renamed by bangfauzan}\n    FIndexFieldNames : String; {bangfauzan addition}\n\n    FIndexFields: {$IFDEF WITH_GENERIC_TLISTTFIELD}TList<TField>{$ELSE}TList{$ENDIF};\n\n    FSortType : TSortType; {bangfauzan addition}\n\n    FSortedFields: string;\n    FSortedFieldRefs: TObjectDynArray;\n    FSortedFieldIndices: TIntegerDynArray;\n    FSortedFieldDirs: TBooleanDynArray;\n    FSortedOnlyDataFields: Boolean;\n    FSortRowBuffer1: PZRowBuffer;\n    FSortRowBuffer2: PZRowBuffer;\n    FPrepared: Boolean;\n    FDoNotCloseResultset: Boolean;\n    FUseCurrentStatment: Boolean;\n  private\n    function GetReadOnly: Boolean;\n    procedure SetReadOnly(Value: Boolean);\n    function GetSQL: TStrings;\n    procedure SetSQL(Value: TStrings);\n    function GetParamCheck: Boolean;\n    procedure SetParamCheck(Value: Boolean);\n    function GetParamChar: Char;\n    procedure SetParamChar(Value: Char);\n    procedure SetParams(Value: TParams);\n    function GetShowRecordTypes: TUpdateStatusSet;\n    procedure SetShowRecordTypes(Value: TUpdateStatusSet);\n    procedure SetConnection(Value: TZAbstractConnection);\n    procedure SetDataSource(Value: TDataSource);\n    function GetMasterFields: string;\n    procedure SetMasterFields(const Value: string);\n    function GetMasterDataSource: TDataSource;\n    procedure SetMasterDataSource(Value: TDataSource);\n    function GetLinkedFields: string; {renamed by bangfauzan}\n    procedure SetLinkedFields(const Value: string);  {renamed by bangfauzan}\n    function GetIndexFieldNames : String; {bangfauzan addition}\n    procedure SetIndexFieldNames(Value : String); {bangfauzan addition}\n    procedure SetOptions(Value: TZDatasetOptions);\n    procedure SetSortedFields({const} Value: string); {bangfauzan modification}\n    procedure SetProperties(const Value: TStrings);\n\n    function GetSortType : TSortType; {bangfauzan addition}\n    Procedure SetSortType(Value : TSortType); {bangfauzan addition}\n\n    procedure UpdateSQLStrings(Sender: TObject);\n    procedure ReadParamData(Reader: TReader);\n    procedure WriteParamData(Writer: TWriter);\n\n    procedure SetPrepared(Value : Boolean);\n    {$IFNDEF WITH_FUNIDIRECTIONAL}\n    procedure SetUniDirectional(const Value: boolean);\n    {$ENDIF}\n    function  GetUniDirectional: boolean;\n\n  protected\n    procedure CheckOpened;\n    procedure CheckConnected;\n    procedure CheckBiDirectional;\n    procedure CheckSQLQuery; virtual;\n    procedure RaiseReadOnlyError;\n\n    function FetchOneRow: Boolean;\n    function FetchRows(RowCount: Integer): Boolean;\n    function FilterRow(RowNo: Integer): Boolean;\n    function GotoRow(RowNo: Integer): Boolean; // added by tohenk\n    procedure RereadRows;\n    procedure SetStatementParams(Statement: IZPreparedStatement;\n      ParamNames: TStringDynArray; Params: TParams;\n      DataLink: TDataLink); virtual;\n    procedure MasterChanged(Sender: TObject);\n    procedure MasterDisabled(Sender: TObject);\n    procedure DoOnNewRecord; override;\n\n    function GetDataSource: TDataSource; override;\n\n  protected\n    { Internal protected properties. }\n    property RowAccessor: TZRowAccessor read FRowAccessor write FRowAccessor;\n    property CurrentRow: Integer read FCurrentRow write FCurrentRow;\n    property OldRowBuffer: PZRowBuffer read FOldRowBuffer write FOldRowBuffer;\n    property NewRowBuffer: PZRowBuffer read FNewRowBuffer write FNewRowBuffer;\n    property CurrentRows: TZSortedList read FCurrentRows write FCurrentRows;\n    property FetchCount: Integer read FFetchCount write FFetchCount;\n    property FieldsLookupTable: TIntegerDynArray read FFieldsLookupTable\n      write FFieldsLookupTable;\n\n    property FilterEnabled: Boolean read FFilterEnabled write FFilterEnabled;\n    property FilterExpression: IZExpression read FFilterExpression\n      write FFilterExpression;\n    property FilterStack: TZExecutionStack read FFilterStack write FFilterStack;\n    property FilterFieldRefs: TObjectDynArray read FFilterFieldRefs\n      write FFilterFieldRefs;\n    property InitFilterFields: Boolean read FInitFilterFields\n      write FInitFilterFields;\n\n    property Statement: IZPreparedStatement read FStatement write FStatement;\n    property ResultSet: IZResultSet read FResultSet write FResultSet;\n\n    property DataLink: TDataLink read FDataLink;\n    property MasterLink: TMasterDataLink read FMasterLink;\n    property IndexFields: {$IFDEF WITH_GENERIC_TLISTTFIELD}TList<TField>{$ELSE}TList{$ENDIF} read FIndexFields;\n\n    { External protected properties. }\n    property RequestLive: Boolean read FRequestLive write FRequestLive\n      default False;\n    property FetchRow: integer read FFetchRow write FFetchRow default 0;  // added by Patyi\n    property SQL: TStrings read GetSQL write SetSQL;\n    property ParamCheck: Boolean read GetParamCheck write SetParamCheck\n      default True;\n    property ParamChar: Char read GetParamChar write SetParamChar\n      default ':';\n    property Params: TParams read FParams write SetParams;\n    property ReadOnly: Boolean read GetReadOnly write SetReadOnly default True;\n    property ShowRecordTypes: TUpdateStatusSet read GetShowRecordTypes\n      write SetShowRecordTypes default [usUnmodified, usModified, usInserted];\n    property IsUniDirectional: Boolean read GetUniDirectional\n      write SetUniDirectional default False;\n    property Properties: TStrings read FProperties write SetProperties;\n    property Options: TZDatasetOptions read FOptions write SetOptions\n      default [doCalcDefaults];\n    property DataSource: TDataSource read GetDataSource write SetDataSource;\n    property MasterFields: string read GetMasterFields\n      write SetMasterFields;\n    property MasterSource: TDataSource read GetMasterDataSource\n      write SetMasterDataSource;\n    property LinkedFields: string read GetLinkedFields\n      write SetLinkedFields; {renamed by bangfauzan}\n    property IndexFieldNames:String read GetIndexFieldNames\n      write SetIndexFieldNames; {bangfauzan addition}\n    property DoNotCloseResultset: Boolean read FDoNotCloseResultset;\n  protected\n    { Abstracts methods }\n    procedure InternalAddRecord(Buffer: Pointer; Append: Boolean); override;\n    procedure InternalDelete; override;\n    procedure InternalPost; override;\n\n    procedure SetFieldData(Field: TField; Buffer: {$IFDEF WITH_TVALUEBUFFER}TValueBuffer{$ELSE}Pointer{$ENDIF};\n      NativeFormat: Boolean); override;\n    procedure SetFieldData(Field: TField; Buffer: {$IFDEF WITH_TVALUEBUFFER}TValueBuffer{$ELSE}Pointer{$ENDIF}); override;\n    procedure DefineProperties(Filer: TFiler); override;\n\n{$IFDEF WITH_TRECORDBUFFER}\n    function GetRecord(Buffer: TRecordBuffer; GetMode: TGetMode; DoCheck: Boolean):\n      TGetResult; override;\n{$ELSE}\n    function GetRecord(Buffer: PChar; GetMode: TGetMode; DoCheck: Boolean):\n      TGetResult; override;\n{$ENDIF}\n    function GetRecordSize: Word; override;\n    function GetActiveBuffer(var RowBuffer: PZRowBuffer): Boolean;\n{$IFDEF WITH_TRECORDBUFFER}\n    function AllocRecordBuffer: TRecordBuffer; override;\n    procedure FreeRecordBuffer(var Buffer: TRecordBuffer); override;\n{$ELSE}\n    function AllocRecordBuffer: PChar; override;\n    procedure FreeRecordBuffer(var Buffer: PChar); override;\n{$ENDIF}\n{$IFDEF WITH_FTDATASETSUPPORT}\n    function CreateNestedDataSet(DataSetField: TDataSetField): TDataSet; override;\n{$ENDIF}\n    procedure CloseBlob(Field: TField); override;\n    function CreateStatement(const SQL: string; Properties: TStrings):\n      IZPreparedStatement; virtual;\n    function CreateResultSet(const SQL: string; MaxRows: Integer):\n      IZResultSet; virtual;\n\n    procedure CheckFieldCompatibility(Field: TField; FieldDef: TFieldDef); {$IFDEF WITH_CHECKFIELDCOMPATIBILITY} override;{$ENDIF}\n{$IFDEF WITH_TRECORDBUFFER}\n    procedure ClearCalcFields(Buffer: TRecordBuffer); override;\n{$ELSE}\n    procedure ClearCalcFields(Buffer: PChar); override;\n{$ENDIF}\n\n    procedure InternalInitFieldDefs; override;\n    procedure InternalOpen; override;\n    procedure InternalClose; override;\n    procedure InternalFirst; override;\n    procedure InternalLast; override;\n{$IFDEF WITH_TRECORDBUFFER}\n    procedure InternalInitRecord(Buffer: TRecordBuffer); override;\n{$ELSE}\n    procedure InternalInitRecord(Buffer: PChar); override;\n{$ENDIF}\n    procedure InternalGotoBookmark(Bookmark: Pointer); override;\n    procedure InternalRefresh; override;\n    procedure InternalHandleException; override;\n{$IFDEF WITH_TRECORDBUFFER}\n    procedure InternalSetToRecord(Buffer: TRecordBuffer); override;\n\n    procedure GetBookmarkData(Buffer: TRecordBuffer;\n      Data:{$IFDEF WITH_BOOKMARKDATA_TBOOKMARK}TBookMark{$ELSE}Pointer{$ENDIF}); override;\n    function GetBookmarkFlag(Buffer: TRecordBuffer): TBookmarkFlag; override;\n    procedure SetBookmarkFlag(Buffer: TRecordBuffer; Value: TBookmarkFlag); override;\n    procedure SetBookmarkData(Buffer: TRecordBuffer;\n      Data: {$IFDEF WITH_BOOKMARKDATA_TBOOKMARK}TBookMark{$ELSE}Pointer{$ENDIF}); override;\n{$ELSE}\n    procedure InternalSetToRecord(Buffer: PChar); override;\n\n    procedure GetBookmarkData(Buffer: PChar; Data: Pointer); override;\n    function GetBookmarkFlag(Buffer: PChar): TBookmarkFlag; override;\n    procedure SetBookmarkFlag(Buffer: PChar; Value: TBookmarkFlag); override;\n    procedure SetBookmarkData(Buffer: PChar; Data: Pointer); override;\n{$ENDIF}\n    function InternalLocate(const KeyFields: string; const KeyValues: Variant;\n      Options: TLocateOptions): LongInt;\n    function FindRecord(Restart, GoForward: Boolean): Boolean; override;\n    procedure SetFiltered(Value: Boolean); override;\n    procedure SetFilterText(const Value: string); override;\n\n    procedure SetAnotherResultset(const Value: IZResultSet);\n    procedure InternalSort;\n    function ClearSort(Item1, Item2: Pointer): Integer;\n    function HighLevelSort(Item1, Item2: Pointer): Integer;\n    function LowLevelSort(Item1, Item2: Pointer): Integer;\n\n    function GetCanModify: Boolean; override;\n    function GetRecNo: Integer; override;\n    function GetRecordCount: Integer; override;\n    procedure MoveRecNo(Value: Integer);\n    procedure SetRecNo(Value: Integer); override;\n    function IsCursorOpen: Boolean; override;\n\n    procedure Notification(AComponent: TComponent;\n      Operation: TOperation); override;\n\n    procedure RefreshParams; virtual;\n\n    procedure InternalPrepare; virtual;\n    procedure InternalUnPrepare; virtual;\n  protected\n  {$IFDEF WITH_IPROVIDER}\n    procedure PSStartTransaction; override;\n    procedure PSEndTransaction(Commit: Boolean); override;\n    // Silvio Clecio\n    {$IFDEF WITH_IPROVIDERWIDE}\n    function PSGetTableNameW: WideString; override;\n    function PSGetQuoteCharW: WideString; override;\n    function PSGetKeyFieldsW: WideString; override;\n    procedure PSSetCommandText(const CommandText: WideString); overload; override;\n    procedure PSSetCommandText(const CommandText: string); overload; override;\n    //??     function PSGetCommandTextW: WideString; override;\n    function PSExecuteStatement(const ASQL: WideString; AParams: TParams;\n      ResultSet: Pointer = nil): Integer; override;\n    {$ELSE}\n    function PSGetTableName: string; override;\n    function PSGetQuoteChar: string; override;\n    function PSGetKeyFields: string; override;\n    function PSExecuteStatement(const ASQL: string; AParams: TParams;\n      ResultSet: Pointer = nil): Integer; override;\n    procedure PSSetCommandText(const CommandText: string); override;\n    {$ENDIF}\n    function PSGetUpdateException(E: Exception;\n      Prev: EUpdateError): EUpdateError; override;\n    function PSIsSQLBased: Boolean; override;\n    function PSIsSQLSupported: Boolean; override;\n    procedure PSReset; override;\n    function PSUpdateRecord(UpdateKind: TUpdateKind;\n      Delta: TDataSet): Boolean; override;\n    procedure PSExecute; override;\n    function PSGetParams: TParams; override;\n    procedure PSSetParams(AParams: TParams); override;\n    function PSInTransaction: Boolean; override;\n  {$ENDIF}\n\n  public\n    constructor Create(AOwner: TComponent); override;\n    destructor Destroy; override;\n\n    procedure FetchAll; virtual;  // added by Patyi\n    procedure ExecSQL; virtual;\n    function RowsAffected: LongInt;\n    function ParamByName(const Value: string): TParam;\n\n    function Locate(const KeyFields: string; const KeyValues: Variant;\n      Options: TLocateOptions): Boolean; override;\n    function Lookup(const KeyFields: string; const KeyValues: Variant;\n      const ResultFields: string): Variant; override;\n    function IsSequenced: Boolean; override;\n\n    function CompareBookmarks(Bookmark1, Bookmark2: TBookmark): Integer;\n      override;\n    function BookmarkValid(Bookmark: TBookmark): Boolean; override;\n\n    function GetFieldData(Field: TField; {$IFDEF WITH_VAR_TVALUEBUFFER}var{$ENDIF}Buffer: {$IFDEF WITH_TVALUEBUFFER}TValueBuffer{$ELSE}Pointer{$ENDIF}): Boolean; override;\n    function GetFieldData(Field: TField; {$IFDEF WITH_VAR_TVALUEBUFFER}var{$ENDIF}Buffer: {$IFDEF WITH_TVALUEBUFFER}TValueBuffer{$ELSE}Pointer{$ENDIF};\n      NativeFormat: Boolean): Boolean; override;\n    function CreateBlobStream(Field: TField; Mode: TBlobStreamMode): TStream;\n      override;\n    function UpdateStatus: TUpdateStatus; override;\n    function Translate(Src, Dest: PAnsiChar; ToOem: Boolean): Integer; override;\n    procedure Prepare;\n    procedure Unprepare;\n\n  public\n    property Active;\n    property Prepared: Boolean read FPrepared write SetPrepared;\n    property FieldDefs stored False;\n    property DbcStatement: IZPreparedStatement read FStatement;\n    property DbcResultSet: IZResultSet read FResultSet;\n\n  published\n    property Connection: TZAbstractConnection read FConnection write SetConnection;\n    property SortedFields: string read FSortedFields write SetSortedFields;\n    property SortType : TSortType read FSortType write SetSortType\n      default stAscending; {bangfauzan addition}\n\n    property AutoCalcFields;\n    property BeforeOpen;\n    property AfterOpen;\n    property BeforeClose;\n    property AfterClose;\n    property BeforeRefresh;\n    property AfterRefresh;\n    property BeforeScroll;\n    property AfterScroll;\n    property OnCalcFields;\n    property OnFilterRecord;\n    property Filter;\n    property Filtered;\n  end;\n\nimplementation\n\nuses Math, ZVariant, ZMessages, ZDatasetUtils, ZStreamBlob, ZSelectSchema,\n  ZGenericSqlToken, ZTokenizer, ZGenericSqlAnalyser, ZAbstractDataset\n  {$IFDEF WITH_DBCONSTS}, DBConsts {$ELSE}, DBConst{$ENDIF}\n  {$IFDEF WITH_WIDESTRUTILS}, WideStrUtils{$ENDIF}\n  {$IFDEF WITH_UNITANSISTRINGS}, AnsiStrings{$ENDIF};\n\n{ EZDatabaseError }\n\n{**\n  Constructs a database exception with a string message.\n  @param Msg a string message which describes the error.\n}\nconstructor EZDatabaseError.Create(const Msg: string);\nbegin\n  inherited Create(Msg);\nend;\n\n{**\n  Constructs a database exception from TZSQLThrowable instance.\n  @param E an original TZSQLThrowable instance.\n}\nconstructor EZDatabaseError.CreateFromException(E: EZSQLThrowable);\nbegin\n  inherited Create(E.Message);\n  ErrorCode := E.ErrorCode;\n  Statuscode:= E.StatusCode;\nend;\n\nprocedure EZDatabaseError.SetStatusCode(const Value: String);\nbegin\n  FStatusCode := value;\nend;\n\n{ TZDataLink }\n\n{**\n  Creates this dataset link object.\n  @param ADataset an owner linked dataset component.\n}\nconstructor TZDataLink.Create(ADataset: TZAbstractRODataset);\nbegin\n  inherited Create(ADataset);\n  FDataset := ADataset;\nend;\n\n{**\n  Processes changes in state of linked dataset.\n}\nprocedure TZDataLink.ActiveChanged;\nbegin\n  if FDataset.Active then\n    FDataset.RefreshParams;\nend;\n\n{**\n  Processes changes in fields of the linked dataset.\n  @param Field a field which was changed.\n}\nprocedure TZDataLink.RecordChanged(Field: TField);\nbegin\n  if (Field = nil) and FDataset.Active then\n    FDataset.RefreshParams;\nend;\n\n{ TZAbstractRODataset }\n\n{**\n  Constructs this object and assignes the mail properties.\n  @param AOwner a component owner.\n}\nconstructor TZAbstractRODataset.Create(AOwner: TComponent);\nbegin\n  inherited Create(AOwner);\n\n  FSQL := TZSQLStrings.Create;\n  TZSQLStrings(FSQL).Dataset := Self;\n  TZSQLStrings(FSQL).MultiStatements := False;\n  FSQL.OnChange := UpdateSQLStrings;\n  FParams := TParams.Create(Self);\n  FCurrentRows := TZSortedList.Create;\n  BookmarkSize := SizeOf(Integer);\n  FShowRecordTypes := [usModified, usInserted, usUnmodified];\n  FRequestLive := False;\n  FFetchRow := 0;                // added by Patyi\n  FOptions := [doCalcDefaults];\n\n  FFilterEnabled := False;\n  FProperties := TStringList.Create;\n  FFilterExpression := TZExpression.Create;\n  FFilterExpression.Tokenizer := CommonTokenizer;\n  FFilterStack := TZExecutionStack.Create;\n\n  FDataLink := TZDataLink.Create(Self);\n  FMasterLink := TMasterDataLink.Create(Self);\n  FMasterLink.OnMasterChange := MasterChanged;\n  FMasterLink.OnMasterDisable := MasterDisabled;\n  {$IFDEF WITH_GENERIC_TLISTTFIELD}\n  FIndexFields := TList<TField>.Create;\n  {$ELSE}\n  FIndexFields := TList.Create;\n  {$ENDIF}\nend;\n\n{**\n  Destroys this object and cleanups the memory.\n}\ndestructor TZAbstractRODataset.Destroy;\nbegin\n  Unprepare;\n  if Assigned(Connection) then\n  begin\n    try\n      SetConnection(nil);\n    except\n    end;\n  end;\n\n  FreeAndNil(FSQL);\n  FreeAndNil(FParams);\n  FreeAndNil(FCurrentRows);\n  FreeAndNil(FProperties);\n  FreeAndNil(FFilterStack);\n\n  FreeAndNil(FDataLink);\n  FreeAndNil(FMasterLink);\n  FreeAndNil(FIndexFields);\n\n  inherited Destroy;\nend;\n\n{**\n  Sets database connection object.\n  @param Value a database connection object.\n}\nprocedure TZAbstractRODataset.SetConnection(Value: TZAbstractConnection);\nbegin\n  if FConnection <> Value then\n  begin\n    if Active then\n       Close;\n    if Assigned(Statement) then\n      Statement.Close;\n    Statement := nil;\n    if FConnection <> nil then\n      FConnection.UnregisterDataSet(Self);\n    FConnection := Value;\n    if FConnection <> nil then\n      FConnection.RegisterDataSet(Self);\n  end;\nend;\n\n{**\n  Gets the SQL query.\n  @return the SQL query strings.\n}\n\nfunction TZAbstractRODataset.GetSQL: TStrings;\nbegin\n  Result := FSQL;\nend;\n\n{$IFNDEF WITH_FUNIDIRECTIONAL}\nfunction TZAbstractRODataset.SetUniDirectional(const Value: boolean);\nbegin\n  FUniDirectional := Value;\nend;\n{$ENDIF}\n{**\n  Gets unidirectional state of dataset.\n  @return the unidirectional flag (delphi).\n}\nfunction TZAbstractRODataset.GetUniDirectional: boolean;\nbegin\n  Result := {$IFNDEF WITH_FUNIDIRECTIONAL}FUniDirectional{$ELSE}inherited IsUniDirectional{$ENDIF};\nend;\n\n{**\n  Sets a new SQL query.\n  @param Value a new SQL query.\n}\nprocedure TZAbstractRODataset.SetSQL(Value: TStrings);\nbegin\n  FSQL.Assign(Value);\nend;\n\n{**\n  Gets a parameters check value.\n  @return a parameters check value.\n}\nfunction TZAbstractRODataset.GetParamCheck: Boolean;\nbegin\n  Result := FSQL.ParamCheck;\nend;\n\n{**\n  Sets a new parameters check value.\n  @param Value a parameters check value.\n}\nprocedure TZAbstractRODataset.SetParamCheck(Value: Boolean);\nbegin\n  FSQL.ParamCheck := Value;\n  UpdateSQLStrings(Self);\nend;\n\n{**\n  Gets a parameters marker.\n  @return a parameter marker.\n}\nfunction TZAbstractRODataset.GetParamChar: Char;\nbegin\n  Result := FSQL.ParamChar;\nend;\n\n{**\n  Sets a new parameter marker.\n  @param Value a parameter marker.\n}\nprocedure TZAbstractRODataset.SetParamChar(Value: Char);\nbegin\n  FSQL.ParamChar := Value;\n  UpdateSQLStrings(Self);\nend;\n\n{**\n  Sets a new set of parameters.\n  @param Value a set of parameters.\n}\nprocedure TZAbstractRODataset.SetParams(Value: TParams);\nbegin\n  FParams.AssignValues(Value);\nend;\n\n{**\n  Defines a persistent dataset properties.\n  @param Filer a persistent manager object.\n}\nprocedure TZAbstractRODataset.DefineProperties(Filer: TFiler);\n\n  function WriteData: Boolean;\n  begin\n    if Filer.Ancestor <> nil then\n      Result := not FParams.IsEqual(TZAbstractRODataset(Filer.Ancestor).FParams)\n    else\n      Result := FParams.Count > 0;\n  end;\n\nbegin\n  inherited DefineProperties(Filer);\n  Filer.DefineProperty('ParamData', ReadParamData, WriteParamData, WriteData);\nend;\n\n{**\n  Reads parameter data from persistent storage.\n  @param Reader an input data stream.\n}\nprocedure TZAbstractRODataset.ReadParamData(Reader: TReader);\nbegin\n  Reader.ReadValue;\n  Reader.ReadCollection(FParams);\nend;\n\n{**\n  Writes parameter data from persistent storage.\n  @param Writer an output data stream.\n}\nprocedure TZAbstractRODataset.WriteParamData(Writer: TWriter);\nbegin\n  Writer.WriteCollection(Params);\nend;\n\n{**\n  Gets a SQL parameter by its name.\n  @param Value a parameter name.\n  @return a found parameter object.\n}\nfunction TZAbstractRODataset.ParamByName(const Value: string): TParam;\nbegin\n  Result := FParams.ParamByName(Value);\nend;\n\n{**\n  Updates parameters from SQL statement.\n  @param Sender an event sender object.\n}\nprocedure TZAbstractRODataset.UpdateSQLStrings(Sender: TObject);\nvar\n  I: Integer;\n  OldParams: TParams;\nbegin\n  FieldDefs.Clear;\n  if Active then\n    Close\n  else\n    begin\n    if assigned(Statement) then\n      Statement.Close;\n    Statement := nil;\n    end;\n\n  UnPrepare;\n\n  OldParams := TParams.Create;\n  OldParams.Assign(FParams);\n  FParams.Clear;\n\n  try\n    for I := 0 to FSQL.ParamCount - 1 do\n      FParams.CreateParam(ftUnknown, FSQL.ParamNames[I], ptUnknown);\n    FParams.AssignValues(OldParams);\n  finally\n    OldParams.Free;\n  end;\nend;\n\n{**\n  Gets the ReadOnly property.\n  @return <code>True</code> if the opened result set read only.\n}\nfunction TZAbstractRODataset.GetReadOnly: Boolean;\nbegin\n  Result := not RequestLive;\nend;\n\n{**\n  Sets a new ReadOnly property.\n  @param Value <code>True</code> to set result set read-only.\n}\nprocedure TZAbstractRODataset.SetReadOnly(Value: Boolean);\nbegin\n  RequestLive := not Value;\nend;\n\n{**\n  Gets a visible updated records types.\n  @param return visible UpdateRecordTypes value.\n}\nfunction TZAbstractRODataset.GetShowRecordTypes: TUpdateStatusSet;\nbegin\n  Result := FShowRecordTypes;\nend;\n\n{**\n  Sets a new visible updated records types.\n  @param Value a new visible UpdateRecordTypes value.\n}\nprocedure TZAbstractRODataset.SetShowRecordTypes(Value: TUpdateStatusSet);\nbegin\n  if Value <> FShowRecordTypes then\n  begin\n    FShowRecordTypes := Value;\n    RereadRows;\n  end;\nend;\n\n{**\n  Checks if this dataset is opened.\n}\nprocedure TZAbstractRODataset.CheckOpened;\nbegin\n  if not Active then\n    DatabaseError(SOperationIsNotAllowed4);\nend;\n\n{**\n  Checks if the database connection is assigned\n  and tries to connect.\n}\nprocedure TZAbstractRODataset.CheckConnected;\nbegin\n  if Connection = nil then\n    raise EZDatabaseError.Create(SConnectionIsNotAssigned);\n  Connection.Connect;\nend;\n\n{**\n  Checks is the database has bidirectional access.\n}\nprocedure TZAbstractRODataset.CheckBiDirectional;\nbegin\n  if IsUniDirectional then\n    raise EZDatabaseError.Create(SOperationIsNotAllowed1);\nend;\n\n{**\n  Checks the correct SQL query.\n}\nprocedure TZAbstractRODataset.CheckSQLQuery;\nbegin\n  if FSQL.StatementCount < 1 then\n    raise EZDatabaseError.Create(SQueryIsEmpty);\n  if FSQL.StatementCount > 1 then\n    raise EZDatabaseError.Create(SCanNotExecuteMoreQueries);\nend;\n\n{**\n  Raises an error 'Operation is not allowed in read-only dataset.\n}\nprocedure TZAbstractRODataset.RaiseReadOnlyError;\nbegin\n  raise EZDatabaseError.Create(SOperationIsNotAllowed2);\nend;\n\n{**\n  Fetches specified number of records.\n  @param RowCount a specified number of rows to be fetched.\n  @return <code>True</code> if all required rows were fetched.\n}\nfunction TZAbstractRODataset.FetchRows(RowCount: Integer): Boolean;\nbegin\n  Connection.ShowSQLHourGlass;\n  try\n    if RowCount = 0 then\n    begin\n      while FetchOneRow do;\n      Result := True;\n    end\n    else\n    begin\n      while (CurrentRows.Count < RowCount) do\n      begin\n        if not FetchOneRow then\n          Break;\n      end;\n      Result := CurrentRows.Count >= RowCount;\n    end;\n  finally\n    Connection.HideSQLHourGlass;\n  end;\nend;\n\n{**\n  Fetches one row from the result set.\n  @return <code>True</code> if record was successfully fetched.\n}\nfunction TZAbstractRODataset.FetchOneRow: Boolean;\nbegin\n  repeat\n    if (FetchCount = 0) or (ResultSet.GetRow = FetchCount)\n      or ResultSet.MoveAbsolute(FetchCount) then\n      Result := ResultSet.Next\n    else\n      Result := False;\n    if Result then\n    begin\n      Inc(FFetchCount);\n      if FilterRow(ResultSet.GetRow) then\n        CurrentRows.Add(Pointer(ResultSet.GetRow))\n      else\n        Continue;\n    end;\n  until True;\nend;\n\n{**\n  Checks the specified row with the all filters.\n  @param RowNo a number of the row.\n  @return <code>True</code> if the row sutisfy to all filters.\n}\nfunction TZAbstractRODataset.FilterRow(RowNo: Integer): Boolean;\nvar\n  I: Integer;\n  SavedRow: Integer;\n  SavedRows: TZSortedList;\n  SavedState: TDatasetState;\nbegin\n  Result := True;\n\n  { Locates the result set to the specified row. }\n  if ResultSet.GetRow <> RowNo then\n  begin\n    if not ResultSet.MoveAbsolute(RowNo) then\n      Result := False;\n  end;\n  if not Result then\n     Exit;\n\n  { Checks record by ShowRecordType }\n  if ResultSet.RowUpdated then\n    Result := usModified in ShowRecordTypes\n  else if ResultSet.RowInserted then\n    Result := usInserted in ShowRecordTypes\n  else if ResultSet.RowDeleted then\n    Result := usDeleted in ShowRecordTypes\n  else\n    Result := usUnmodified in ShowRecordTypes;\n  if not Result then\n     Exit;\n\n  { Check master-detail links }\n  if MasterLink.Active then\n  begin\n    for I := 0 to MasterLink.Fields.Count - 1 do\n    begin\n      if I < IndexFields.Count then\n        Result := CompareKeyFields(TField(IndexFields[I]), ResultSet,\n          TField(MasterLink.Fields[I]));\n\n      if not Result then\n        Break;\n    end;\n  end;\n  if not Result then\n     Exit;\n\n  { Checks record by OnFilterRecord event }\n  if FilterEnabled and Assigned(OnFilterRecord) then\n  begin\n    SavedRow := CurrentRow;\n    SavedRows := CurrentRows;\n    CurrentRows := TZSortedList.Create;\n\n    SavedState := SetTempState(dsNewValue);\n    CurrentRows.Add(Pointer(RowNo));\n    CurrentRow := 1;\n\n    try\n      OnFilterRecord(Self, Result);\n    except\n      if Assigned(ApplicationHandleException)\n      then ApplicationHandleException(Self);\n    end;\n\n    CurrentRow := SavedRow;\n    CurrentRows.Free;\n    CurrentRows := SavedRows;\n    RestoreState(SavedState);\n\n  end;\n  if not Result then\n     Exit;\n\n  { Check the record by filter expression. }\n  if FilterEnabled and (FilterExpression.Expression <> '') then\n  begin\n    if not InitFilterFields then\n    begin\n      FilterFieldRefs := DefineFilterFields(Self, FilterExpression);\n      InitFilterFields := True;\n    end;\n    CopyDataFieldsToVars(FilterFieldRefs, ResultSet,\n      FilterExpression.DefaultVariables);\n    Result := FilterExpression.VariantManager.GetAsBoolean(\n      FilterExpression.Evaluate4(FilterExpression.DefaultVariables,\n      FilterExpression.DefaultFunctions, FilterStack));\n  end;\n  if not Result then\n     Exit;\nend;\n\n{**\n  Go to specified row.\n  @param RowNo a number of the row.\n  @return <code>True</code> if the row successfully located.\n}\nfunction TZAbstractRODataset.GotoRow(RowNo: Integer): Boolean;\nvar\n  Index: Integer;\nbegin\n  Result := False;\n  Index := CurrentRows.IndexOf(Pointer(RowNo));\n  if Index >= 0 then\n  begin\n    if Index < CurrentRow then\n      CheckBiDirectional;\n    CurrentRow := Index + 1;\n    Result := True;\n  end;\nend;\n\n{**\n  Rereads all rows and applies a filter.\n}\nprocedure TZAbstractRODataset.RereadRows;\nvar\n  I, RowNo: Integer;\nbegin\n  if not (State in [dsInactive]) and not IsUniDirectional then\n  begin\n    if (CurrentRow > 0) and (CurrentRow <= CurrentRows.Count) and\n      (CurrentRows.Count > 0) then\n      RowNo := Integer(CurrentRows[CurrentRow - 1])\n    else\n      RowNo := -1;\n    CurrentRows.Clear;\n\n    for I := 1 to FetchCount do\n    begin\n      if FilterRow(I) then\n        CurrentRows.Add(Pointer(I));\n    end;\n\n    CurrentRow := CurrentRows.IndexOf(Pointer(RowNo)) + 1;\n    CurrentRow := Min(Max(1, CurrentRow), CurrentRows.Count);\n\n    if FSortedFields <> '' then\n      InternalSort\n    else\n      Resync([]);\n  end;\nend;\n\n{**\n  Fill prepared statement with parameters.\n  @param Statement a prepared SQL statement.\n  @param ParamNames an array of parameter names.\n  @param Params a collection of SQL parameters.\n  @param DataLink a datalink to get parameters.\n}\nprocedure TZAbstractRODataset.SetStatementParams(Statement: IZPreparedStatement;\n  ParamNames: TStringDynArray; Params: TParams; DataLink: TDataLink);\nvar\n  I: Integer;\n  TempParam, Param: TParam;\n  Dataset: TDataset;\n  Field: TField;\nbegin\n  if DataLink.Active then\n    Dataset := DataLink.DataSet\n  else\n    Dataset := nil;\n\n  TempParam := TParam.Create(nil);\n\n  try\n    for I := Low(ParamNames) to High(ParamNames) do\n    begin\n      if Assigned(Dataset) then\n        Field := Dataset.FindField(ParamNames[I])\n      else\n        Field := nil;\n\n      if Assigned(Field) then\n      begin\n        TempParam.AssignField(Field);\n        Param := TempParam;\n      end\n      else\n      begin\n        Param := Params.FindParam(ParamNames[I]);\n        if not Assigned(Param) or (Param.ParamType in [ptOutput, ptResult]) then\n          Continue;\n      end;\n\n      SetStatementParam(I+ 1, Statement, Param);\n    end;\n  finally\n    TempParam.Free;\n  end;\nend;\n\n{**\n  Locates a specified record in dataset.\n  @param Buffer a record buffer to put the contents of the row.\n  @param GetMode a location mode.\n  @param DoCheck flag to perform checking.\n  @return a location result.\n}\n\n{$IFDEF WITH_TRECORDBUFFER}\nfunction TZAbstractRODataset.GetRecord(Buffer: TRecordBuffer; GetMode: TGetMode;\n  DoCheck: Boolean): TGetResult;\n{$ELSE}\n\nfunction TZAbstractRODataset.GetRecord(Buffer: PChar; GetMode: TGetMode;\n  DoCheck: Boolean): TGetResult;\n{$ENDIF}\nvar\n  RowNo: Integer;\nbegin\n  // mad stub for unidirectional (problem in TDataSet.MoveBuffer) - dont know about FPC\n  // we always use same TDataSet-level buffer, because we can see only one row\n  {$IFNDEF WITH_UNIDIRECTIONALBUG}\n  if IsUniDirectional then\n    Buffer := {$IFDEF WITH_BUFFERS_IS_TRECBUF}Pointer{$ENDIF}(Buffers[0]);\n  {$ENDIF}\n\n  Result := grOK;\n  case GetMode of\n    gmNext:\n      begin\n        if FetchRows(CurrentRow + 1) then\n          CurrentRow := CurrentRow + 1\n        else\n          Result := grEOF;\n      end;\n    gmPrior:\n      begin\n        CheckBiDirectional;\n        if (CurrentRow > 1) and (CurrentRows.Count > 0) then\n          CurrentRow := CurrentRow - 1\n        else\n          Result := grBOF;\n      end;\n    gmCurrent:\n      begin\n        if CurrentRow < CurrentRows.Count then\n          CheckBiDirectional;\n\n        if CurrentRow = 0 then\n        begin\n          if CurrentRows.Count = 0 then\n            FetchRows(1);\n          CurrentRow := Min(CurrentRows.Count, 1);\n        end\n        else if not FetchRows(CurrentRow) then\n          CurrentRow := Max(1, Min(CurrentRows.Count, CurrentRow));\n\n        if CurrentRows.Count = 0 then\n          Result := grError;\n      end;\n  end;\n\n  if Result = grOK then\n  begin\n    RowNo := Integer(CurrentRows[CurrentRow - 1]);\n    if ResultSet.GetRow <> RowNo then\n      ResultSet.MoveAbsolute(RowNo);\n    RowAccessor.RowBuffer := PZRowBuffer(Buffer);\n    RowAccessor.RowBuffer^.Index := RowNo;\n    FetchFromResultSet(ResultSet, FieldsLookupTable, Fields, RowAccessor);\n    FRowAccessor.RowBuffer^.BookmarkFlag := Ord(bfCurrent);\n    GetCalcFields({$IFDEF WITH_GETCALCFIELDS_TRECBUF}NativeInt{$ENDIF}(Buffer));\n  end;\n\n  if (Result = grError) and DoCheck then\n    raise EZDatabaseError.Create(SNoMoreRecords);\nend;\n\n{**\n  Gets the current record buffer depended on the current dataset state.\n  @param RowBuffer a reference to the result row buffer.\n  @return <code>True</code> if the buffer was defined.\n}\nfunction TZAbstractRODataset.GetActiveBuffer(var RowBuffer: PZRowBuffer):\n  Boolean;\nvar\n  RowNo: Integer;\n  CachedResultSet: IZCachedResultSet;\nbegin\n  RowBuffer := nil;\n  case State of\n    dsBrowse,dsblockread:\n      if not IsEmpty then\n        RowBuffer := PZRowBuffer(ActiveBuffer);\n    dsEdit, dsInsert:\n      RowBuffer := PZRowBuffer(ActiveBuffer);\n    dsCalcFields:\n      RowBuffer := PZRowBuffer(CalcBuffer);\n    dsOldValue, dsNewValue, dsCurValue:\n      begin\n        RowNo := Integer(CurrentRows[CurrentRow - 1]);\n        if RowNo <> ResultSet.GetRow then\n          CheckBiDirectional;\n\n        if State = dsOldValue then\n          RowBuffer := OldRowBuffer\n        else\n          RowBuffer := NewRowBuffer;\n\n        if RowBuffer.Index <> RowNo then\n        begin\n          RowAccessor.RowBuffer := RowBuffer;\n          RowAccessor.Clear;\n          if (ResultSet.GetRow = RowNo) or ResultSet.MoveAbsolute(RowNo) then\n          begin\n            if (State = dsOldValue) and (ResultSet.\n              QueryInterface(IZCachedResultSet, CachedResultSet) = 0) then\n              CachedResultSet.MoveToInitialRow;\n            FetchFromResultSet(ResultSet, FieldsLookupTable, Fields, RowAccessor);\n            RowBuffer.Index := RowNo;\n            ResultSet.MoveToCurrentRow;\n          end\n          else\n            RowBuffer := nil;\n        end;\n      end;\n  end;\n  Result := RowBuffer <> nil;\nend;\n\nfunction TZAbstractRODataset.GetFieldData(Field: TField;\n  {$IFDEF WITH_VAR_TVALUEBUFFER}var{$ENDIF}Buffer:\n  {$IFDEF WITH_TVALUEBUFFER}TValueBuffer{$ELSE}Pointer{$ENDIF};\n  NativeFormat: Boolean): Boolean;\nbegin\n  if Field.DataType in [ftWideString] then\n    NativeFormat := True;\n  Result := inherited GetFieldData(Field, Buffer, NativeFormat);\nend;\n\n{**\n  Retrieves the column value and stores it into the field buffer.\n  @param Field an field object to be retrieved.\n  @param Buffer a field value buffer.\n  @return <code>True</code> if non-null value was retrieved.\n}\nfunction TZAbstractRODataset.GetFieldData(Field: TField;\n  {$IFDEF WITH_VAR_TVALUEBUFFER}var{$ENDIF}Buffer:\n    {$IFDEF WITH_TVALUEBUFFER}TValueBuffer{$ELSE}Pointer{$ENDIF}): Boolean;\nvar\n  ColumnIndex: Integer;\n  RowBuffer: PZRowBuffer;\n  ACurrency: Double;\n  Bts: TByteDynArray;\n  {$IFNDEF WITH_WIDESTRUTILS}\n  WS: WideString;\n  {$ENDIF}\nbegin\n  if GetActiveBuffer(RowBuffer) then\n  begin\n    ColumnIndex := DefineFieldIndex(FieldsLookupTable, Field);\n    RowAccessor.RowBuffer := RowBuffer;\n    if Buffer <> nil then\n    begin\n      case Field.DataType of\n        { Processes DateTime fields. }\n        ftDate, ftTime, ftDateTime:\n          begin\n            if Field.DataType <> ftTime then\n              DateTimeToNative(Field.DataType,\n                RowAccessor.GetTimestamp(ColumnIndex, Result), Buffer)\n            else\n              DateTimeToNative(Field.DataType,\n                RowAccessor.GetTime(ColumnIndex, Result), Buffer);\n            Result := not Result;\n          end;\n        { Processes binary array fields. }\n        ftBytes:\n          begin\n            Bts := RowAccessor.GetBytes(ColumnIndex, Result);\n            System.Move(PAnsiChar(Bts)^,\n              PAnsiChar(Buffer)^, Min(Length(Bts), RowAccessor.GetColumnDataSize(ColumnIndex)));\n            Result := not Result;\n          end;\n        { Processes blob fields. }\n        ftBlob, ftMemo, ftGraphic, ftFmtMemo {$IFDEF WITH_WIDEMEMO},ftWideMemo{$ENDIF} :\n          Result := not RowAccessor.GetBlob(ColumnIndex, Result).IsEmpty;\n        ftWideString:\n          begin\n            {$IFDEF WITH_WIDESTRUTILS}\n            WStrCopy(PWideChar(Buffer), PWideChar(RowAccessor.GetUnicodeString(ColumnIndex, Result)));\n            {$ELSE}\n            //FPC: WideStrings are COM managed fields\n            WS:=RowAccessor.GetUnicodeString(ColumnIndex, Result);\n            //include null terminator in copy\n            System.Move(PWideChar(WS)^,buffer^,(length(WS)+1)*sizeof(WideChar));\n            {$ENDIF}\n            Result := not Result;\n          end;\n        ftString{$IFDEF WITH_FTGUID}, ftGUID{$ENDIF}:\n          begin\n            {$IFDEF WITH_STRCOPY_DEPRECATED}AnsiStrings.{$ENDIF}StrCopy(PAnsiChar(Buffer), PAnsiChar({$IFDEF UNICODE}AnsiString{$ENDIF}(RowAccessor.GetString(ColumnIndex, Result))));\n            Result := not Result;\n          end;\n        {$IFDEF WITH_FTDATASETSUPPORT}\n        ftDataSet:\n          Result := not RowAccessor.GetDataSet(ColumnIndex, Result).IsEmpty;\n        {$ENDIF}\n        { Processes all other fields. }\n        ftCurrency:\n          begin\n            {SizeOf(double) = 8Byte but SizeOf(Extented) = 10 Byte, so i need to convert the value}\n            ACurrency := RowAccessor.GetDouble(ColumnIndex, Result);\n            System.Move(Pointer(@ACurrency)^, Pointer(Buffer)^, SizeOf(Double));\n            Result := not Result;\n          end;\n        else\n          begin\n            System.Move(RowAccessor.GetColumnData(ColumnIndex, Result)^,\n              Pointer(Buffer)^, RowAccessor.GetColumnDataSize(ColumnIndex));\n            Result := not Result;\n          end;\n      end;\n    end\n    else\n    begin\n      if Field.DataType in [ftBlob, ftMemo, ftGraphic, ftFmtMemo {$IFDEF WITH_WIDEMEMO},ftWideMemo{$ENDIF}] then\n        Result := not RowAccessor.GetBlob(ColumnIndex, Result).IsEmpty\n      else\n        Result := not RowAccessor.IsNull(ColumnIndex);\n    end;\n  end\n  else\n    Result := False;\nend;\n\n{**\n  Support for widestring field\n}\nprocedure TZAbstractRODataset.SetFieldData(Field: TField; Buffer: {$IFDEF WITH_TVALUEBUFFER}TValueBuffer{$ELSE}Pointer{$ENDIF};\n  NativeFormat: Boolean);\nbegin\n  if Field.DataType in [ftWideString{$IFDEF WITH_WIDEMEMO}, ftWideMemo{$ENDIF}] then\n    NativeFormat := True;\n\n  {$IFNDEF VIRTUALSETFIELDDATA}\n  inherited;\n  {$ELSE}\n  SetFieldData(Field, Buffer);\n  {$ENDIF}\nend;\n\n{**\n  Stores the column value from the field buffer.\n  @param Field an field object to be stored.\n  @param Buffer a field value buffer.\n}\nprocedure TZAbstractRODataset.SetFieldData(Field: TField; Buffer: {$IFDEF WITH_TVALUEBUFFER}TValueBuffer{$ELSE}Pointer{$ENDIF});\nvar\n  ColumnIndex: Integer;\n  RowBuffer: PZRowBuffer;\n  WasNull: Boolean;\n  {$IFNDEF UNICODE}\n  L: Cardinal;\n  Temp: String;\n  {$ENDIF}\nbegin\n  WasNull := False;\n  if not Active then\n    raise EZDatabaseError.Create(SOperationIsNotAllowed4);\n  if not RequestLive and (Field.FieldKind = fkData) then\n    RaiseReadOnlyError;\n  // Check for readonly updates\n  // Lookup values are requeried automatically on edit of all fields.\n  // Didn't find a way to avoid this...\n  if Field.ReadOnly and (Field.FieldKind <> fkLookup)\n                    and not (State in [dsSetKey, dsCalcFields, dsFilter, dsBlockRead, dsInternalCalc, dsOpening]) then\n    DatabaseErrorFmt(SFieldReadOnly, [Field.DisplayName]);\n  if not (State in dsWriteModes) then\n    DatabaseError(SNotEditing, Self);\n\n  if GetActiveBuffer(RowBuffer) then\n  begin\n    ColumnIndex := DefineFieldIndex(FieldsLookupTable, Field);\n    RowAccessor.RowBuffer := RowBuffer;\n\n    if State in [dsEdit, dsInsert] then\n      Field.Validate(Buffer);\n\n    if Assigned(Buffer) then\n    begin\n      case Field.DataType of\n        ftDate, ftDateTime: { Processes Date/DateTime fields. }\n          RowAccessor.SetTimestamp(ColumnIndex, NativeToDateTime(Field.DataType, Buffer));\n        ftTime: { Processes Time fields. }\n          RowAccessor.SetTime(ColumnIndex, NativeToDateTime(Field.DataType, Buffer));\n        ftBytes: { Processes binary array fields. }\n          RowAccessor.SetBytes(ColumnIndex, BufferToBytes(Pointer(Buffer), Field.Size));\n        ftWideString: { Processes widestring fields. }\n          {$IFDEF WITH_PWIDECHAR_TOWIDESTRING}\n          RowAccessor.SetUnicodeString(ColumnIndex, PWideChar(Buffer));\n          {$ELSE}\n          RowAccessor.SetUnicodeString(ColumnIndex, PWideString(Buffer)^);\n          {$ENDIF}\n        ftString{$IFDEF WITH_FTGUID}, ftGUID{$ENDIF}: { Processes string fields. }\n          {$IFDEF UNICODE}\n          RowAccessor.SetString(ColumnIndex, String(PAnsichar(Buffer)));\n          {$ELSE}\n          begin\n            L := {$IFDEF WITH_STRLEN_DEPRECATED}AnsiStrings.{$ENDIF}StrLen(PAnsiChar(Buffer));\n            SetLength(Temp, L);\n            Move(PAnsiChar(Buffer)^, PAnsiChar(Temp)^, L);\n            RowAccessor.SetString(ColumnIndex, Temp);\n          end;\n          {$ENDIF}\n        ftCurrency:\n            {SizeOf(curreny) = 8Byte but SizeOf(Extented) = 10 Byte, so i need to convert the value}\n            RowAccessor.SetDouble(ColumnIndex, PDouble(Buffer)^); //cast Currrency to Extented\n        else  { Processes all other fields. }\n          begin\n            System.Move(Pointer(Buffer)^, RowAccessor.GetColumnData(ColumnIndex, WasNull)^,\n            RowAccessor.GetColumnDataSize(ColumnIndex));\n            RowAccessor.SetNotNull(ColumnIndex);\n          end;\n      end;\n    end\n    else\n      RowAccessor.SetNull(ColumnIndex);\n\n    if not (State in [dsCalcFields, dsFilter, dsNewValue]) then\n      DataEvent(deFieldChange, ULong(Field));\n  end\n  else\n    raise EZDatabaseError.Create(SRowDataIsNotAvailable);\n\n  if Field.FieldKind = fkData then\n  begin\n    OldRowBuffer.Index := -1;\n    NewRowBuffer.Index := -1;\n  end;\nend;\n\n{**\n  Checks is the cursor opened.\n  @return <code>True</code> if the cursor is opened.\n}\nfunction TZAbstractRODataset.IsCursorOpen: Boolean;\nbegin\n  Result := ResultSet <> nil;\nend;\n\n{**\n  Gets an affected rows by the last executed statement.\n  @return a number of last updated rows.\n}\nfunction TZAbstractRODataset.RowsAffected: LongInt;\nbegin\n  Result := FRowsAffected;\nend;\n\n{**\n  Gets the size of the record buffer.\n  @return the size of the record buffer.\n}\nfunction TZAbstractRODataset.GetRecordSize: Word;\nbegin\n  Result := RowAccessor.RowSize;\nend;\n\n{**\n  Allocates a buffer for new record.\n  @return an allocated record buffer.\n}\n\n{$IFDEF WITH_TRECORDBUFFER}\n\nfunction TZAbstractRODataset.AllocRecordBuffer: TRecordBuffer;\nbegin\n   Result := TRecordBuffer(RowAccessor.Alloc);\nend;\n{$ELSE}\n\nfunction TZAbstractRODataset.AllocRecordBuffer: PChar;\nbegin\n  Result := PChar(RowAccessor.Alloc);\nend;\n{$ENDIF}\n\n{**\n  Frees a previously allocated record buffer.\n  @param Buffer a previously allocated buffer.\n}\n\n{$IFDEF WITH_TRECORDBUFFER}\n\nprocedure TZAbstractRODataset.FreeRecordBuffer(var Buffer: TRecordBuffer);\n{$ELSE}\n\nprocedure TZAbstractRODataset.FreeRecordBuffer(var Buffer: PChar);\n{$ENDIF}\nbegin\n  RowAccessor.DisposeBuffer(PZRowBuffer(Buffer));\nend;\n\n{**\n  Fetch all records. Added by Patyi\n}\nprocedure TZAbstractRODataset.FetchAll;\nbegin\n  Connection.ShowSQLHourGlass;\n  FetchRows(0);\n  if Active then\n    UpdateCursorPos;\n  Connection.HideSQLHourGlass;\nend;\n\n{**\n  Executes a DML SQL statement.\n}\nprocedure TZAbstractRODataset.ExecSQL;\nbegin\n  if Active then\n    begin\n      Connection.ShowSQLHourGlass;\n      try\n        Close;\n      finally\n        Connection.HideSQLHourGlass;\n      end;\n    end;\n\n  Prepare;\n\n  Connection.ShowSQLHourGlass;\n  try\n    SetStatementParams(Statement, FSQL.Statements[0].ParamNamesArray,\n      FParams, FDataLink);\n\n    FRowsAffected := Statement.ExecuteUpdatePrepared;\n  finally\n    Connection.HideSQLHourGlass;\n  end;\nend;\n\n{**\n  Performs an internal initialization of field defiitions.\n}\nprocedure TZAbstractRODataset.InternalInitFieldDefs;\nvar\n  I, J, Size: Integer;\n  AutoInit: Boolean;\n  FieldType: TFieldType;\n  ResultSet: IZResultSet;\n  FieldName: string;\n  FName: string;\nbegin\n  FieldDefs.Clear;\n  ResultSet := Self.ResultSet;\n  AutoInit := ResultSet = nil;\n\n  try\n    { Opens an internal result set if query is closed. }\n    if AutoInit then\n    begin\n      CheckSQLQuery;\n      CheckConnected;\n      Prepare;\n      ResultSet := CreateResultSet(FSQL.Statements[0].SQL, 0);\n    end;\n    if not Assigned(ResultSet) then\n      raise Exception.Create(SCanNotOpenResultSet);\n\n    { Reads metadata from resultset. }\n\n    with ResultSet.GetMetadata do\n    begin\n    if GetColumnCount > 0 then\n      for I := 1 to GetColumnCount do\n      begin\n        FieldType := ConvertDbcToDatasetType(GetColumnType(I));\n        //if IsCurrency(I) then\n          //FieldType := ftCurrency;\n        if FieldType in [ftBytes, ftString, ftWidestring] then\n          Size := GetPrecision(I)\n        else\n          {$IFDEF WITH_FTGUID}\n          if FieldType = ftGUID then\n            Size := 38\n          else\n          {$ENDIF}\n            Size := 0;\n\n        J := 0;\n        FieldName := GetColumnLabel(I);\n        FName := FieldName;\n        while FieldDefs.IndexOf(FName) >= 0 do\n        begin\n          Inc(J);\n          FName := Format('%s_%d', [FieldName, J]);\n        end;\n\n        with TFieldDef.Create(FieldDefs, FName, FieldType,\n          Size, False, I) do\n        begin\n          {$IFNDEF OLDFPC}\n          Required := IsWritable(I) and (IsNullable(I) = ntNoNulls);\n          {$ENDIF}\n          if IsReadOnly(I) then Attributes := Attributes + [faReadonly];\n          Precision := GetPrecision(I);\n          DisplayName := FName;\n        end;\n      end;\n    end;\n\n  finally\n    { Closes localy opened resultset. }\n    if AutoInit then\n    begin\n      if ResultSet <> nil then\n      begin\n        ResultSet.Close;\n        ResultSet := nil;\n      end;\n      UnPrepare;\n    end;\n  end;\nend;\n\n{**\n  Creates a DBC statement for the query.\n  @param SQL an SQL query.\n  @param Properties a statement specific properties.\n  @returns a created DBC statement.\n}\nfunction TZAbstractRODataset.CreateStatement(const SQL: string; Properties: TStrings):\n  IZPreparedStatement;\nvar\n  Temp: TStrings;\nbegin\n  Temp := TStringList.Create;\n  try\n    if Assigned(Properties) then\n      Temp.AddStrings(Properties);\n    { Define TDataset specific parameters. }\n    if doCalcDefaults in FOptions then\n      Temp.Values['defaults'] := 'true'\n    else\n      Temp.Values['defaults'] := 'false';\n    if doPreferPrepared in FOptions then\n      Temp.Values['preferprepared'] := 'true'\n    else\n      Temp.Values['preferprepared'] := 'false';\n\n    Result := FConnection.DbcConnection.PrepareStatementWithParams(SQL, Temp);\n  finally\n    Temp.Free;\n  end;\nend;\n\n{**\n  Creates a DBC resultset for the query.\n  @param SQL an SQL query.\n  @param MaxRows a maximum rows number (-1 for all).\n  @returns a created DBC resultset.\n}\nfunction TZAbstractRODataset.CreateResultSet(const SQL: string;\n  MaxRows: Integer): IZResultSet;\nbegin\n  Connection.ShowSQLHourGlass;\n  try\n    SetStatementParams(Statement, FSQL.Statements[0].ParamNamesArray,\n      FParams, FDataLink);\n    if RequestLive then\n      Statement.SetResultSetConcurrency(rcUpdatable)\n    else\n      Statement.SetResultSetConcurrency(rcReadOnly);\n    Statement.SetFetchDirection(fdForward);\n    if IsUniDirectional then\n      Statement.SetResultSetType(rtForwardOnly)\n    else\n      Statement.SetResultSetType(rtScrollInsensitive);\n    if MaxRows > 0 then\n      Statement.SetMaxRows(MaxRows);\n\n    if doSmartOpen in FOptions then\n    begin\n      if Statement.ExecutePrepared then\n        Result := Statement.GetResultSet\n      else\n        Result := nil;\n    end\n    else\n      Result := Statement.ExecuteQueryPrepared;\n  finally\n    Connection.HideSQLHourGlass;\n  end;\nend;\n\n{**\n  Performs internal query opening.\n}\nprocedure TZAbstractRODataset.InternalOpen;\nvar\n  ColumnList: TObjectList;\n  I: Integer;\nbegin\n  {$IFNDEF FPC}\n  If (csDestroying in Componentstate) then\n    raise Exception.Create(SCanNotOpenDataSetWhenDestroying);\n  {$ENDIF}\n  if not FUseCurrentStatment then Prepare;\n\n  CurrentRow := 0;\n  FetchCount := 0;\n  CurrentRows.Clear;\n\n  Connection.ShowSQLHourGlass;\n  try\n    { Creates an SQL statement and resultsets }\n    if not FUseCurrentStatment then\n      if FSQL.StatementCount> 0 then\n        ResultSet := CreateResultSet(FSQL.Statements[0].SQL, -1)\n      else\n        ResultSet := CreateResultSet('', -1);\n      if not Assigned(ResultSet) then\n      begin\n        if not (doSmartOpen in FOptions) then\n          raise Exception.Create(SCanNotOpenResultSet)\n        else\n          Exit;\n      end;\n\n    { Initializes field and index defs. }\n    if not FRefreshInProgress then\n      InternalInitFieldDefs;\n\n    if DefaultFields and not FRefreshInProgress then\n    begin\n      CreateFields;\n      for i := 0 to Fields.Count -1 do\n        if Fields[i].DataType in [ftString, ftWideString{$IFDEF WITH_FTGUID}, ftGUID{$ENDIF}] then\n          {$IFDEF WITH_FTGUID}\n          if Fields[i].DataType = ftGUID then\n            Fields[i].DisplayWidth := 40 //to get a full view of the GUID values\n          else\n          {$ENDIF}\n            if not (ResultSet.GetMetadata.GetColumnDisplaySize(I+1) = 0) then\n            begin\n              {$IFNDEF FPC}Fields[i].Size := ResultSet.GetMetadata.GetColumnDisplaySize(I+1);{$ENDIF}\n              Fields[i].DisplayWidth := ResultSet.GetMetadata.GetColumnDisplaySize(I+1);\n            end;\n    end;\n    BindFields(True);\n\n    { Initializes accessors and buffers. }\n    ColumnList := ConvertFieldsToColumnInfo(Fields);\n    try\n      RowAccessor := TZRowAccessor.Create(ColumnList, Connection.DbcConnection.GetConSettings);\n    finally\n      ColumnList.Free;\n    end;\n    FOldRowBuffer := PZRowBuffer(AllocRecordBuffer);\n    FNewRowBuffer := PZRowBuffer(AllocRecordBuffer);\n\n    FieldsLookupTable := CreateFieldsLookupTable(Fields);\n    InitFilterFields := False;\n\n    IndexFields.Clear;\n    GetFieldList(IndexFields, FLinkedFields); {renamed by bangfauzan}\n\n    { Performs sorting. }\n    if FSortedFields <> '' then\n      InternalSort;\n  finally\n    Connection.HideSQLHourGlass;\n  end;\nend;\n\n{**\n  Performs internal query closing.\n}\nprocedure TZAbstractRODataset.InternalClose;\nbegin\n  if ResultSet <> nil then\n    if not FDoNotCloseResultSet then ResultSet.Close;\n  ResultSet := nil;\n\n  if FOldRowBuffer <> nil then\n{$IFDEF WITH_TRECORDBUFFER}\n    FreeRecordBuffer(TRecordBuffer(FOldRowBuffer));   // TRecordBuffer can be both pbyte and pchar in FPC. Don't assume.\n{$ELSE}\n    FreeRecordBuffer(PChar(FOldRowBuffer));\n{$ENDIF}\n  FOldRowBuffer := nil;\n  if FNewRowBuffer <> nil then\n{$IFDEF WITH_TRECORDBUFFER}\n    FreeRecordBuffer(TRecordBuffer(FNewRowBuffer));\n{$ELSE}\n    FreeRecordBuffer(PChar(FNewRowBuffer));\n{$ENDIF}\n  FNewRowBuffer := nil;\n\n  if RowAccessor <> nil then\n    RowAccessor.Free;\n  RowAccessor := nil;\n\n  { Destroy default fields }\n  if DefaultFields and not FRefreshInProgress then\n    DestroyFields;\n\n  CurrentRows.Clear;\n  FieldsLookupTable := nil;\nend;\n\n{**\n  Performs internal go to first record.\n}\nprocedure TZAbstractRODataset.InternalFirst;\nbegin\n  if CurrentRow > 0 then\n    CheckBiDirectional;\n  CurrentRow := 0;\nend;\n\n{**\n  Performs internal go to last record.\n}\nprocedure TZAbstractRODataset.InternalLast;\nbegin\n  FetchRows(0);\n  if CurrentRows.Count > 0 then\n    CurrentRow := CurrentRows.Count + 1\n  else\n    CurrentRow := 0;\nend;\n\n{**\n  Processes internal exception handling.\n}\nprocedure TZAbstractRODataset.InternalHandleException;\nbegin\n//  Application.HandleException(Self);\nend;\n\n{**\n  Gets the maximum records count.\n  @return the maximum records count.\n}\nfunction TZAbstractRODataset.GetRecordCount: LongInt;\nbegin\n  CheckActive;\n  if not IsUniDirectional then\n    FetchRows(FFetchRow);     // the orginal code was FetchRows(0); modifyed by Patyi\n  Result := CurrentRows.Count;\nend;\n\n{**\n  Gets the current record number.\n  @return the current record number.\n}\nfunction TZAbstractRODataset.GetRecNo: Longint;\nbegin\n  if Active then\n    UpdateCursorPos;\n  Result := CurrentRow;\nend;\n\n{**\n  Moves current record to the specified record.\n  @param Value a new current record number.\n}\nprocedure TZAbstractRODataset.MoveRecNo(Value: Integer);\nvar\n  PreviousCurrentRow: Integer;\nbegin\n  Value := Max(1, Value);\n  if Value < CurrentRow then\n    CheckBiDirectional;\n\n  if FetchRows(Value) then\n    CurrentRow := Value\n  else\n    CurrentRow := CurrentRows.Count;\n\n  PreviousCurrentRow := CurrentRow;//Resync moves the current row away\n  try\n    if not (State in [dsInactive]) then\n       Resync([]);\n  finally\n    CurrentRow := PreviousCurrentRow;\n  end;\n  UpdateCursorPos;\nend;\n\n{**\n  Sets a new currenct record number.\n  @param Value a new current record number.\n}\nprocedure TZAbstractRODataset.SetRecNo(Value: Integer);\nbegin\n  CheckOpened;\n  Value := Max(1, Value);\n  if Value < CurrentRow then\n    CheckBiDirectional;\n\n  DoBeforeScroll;\n  MoveRecNo(Value);\n  DoAfterScroll;\nend;\n\n{**\n  Defines is the query editable?\n  @return <code>True</code> if the query is editable.\n}\nfunction TZAbstractRODataset.GetCanModify: Boolean;\nbegin\n  Result := RequestLive;\nend;\n\n{**\n  Gets a linked datasource.\n  @returns a linked datasource.\n}\nfunction TZAbstractRODataset.GetDataSource: TDataSource;\nbegin\n  Result := DataLink.DataSource;\nend;\n\n{**\n  Sets the value of the Prepared property.\n  Setting to <code>True</code> prepares the query. Setting to <code>False</code> unprepares.\n  @param Value a new value for the Prepared property.\n}\nprocedure TZAbstractRODataset.SetPrepared(Value: Boolean);\nbegin\n  FUseCurrentStatment := False;\n  FDoNotCloseResultSet := False;\n  If Value <> FPrepared then\n    begin\n      If Value then\n        InternalPrepare\n      else\n        InternalUnprepare;\n      FPrepared := Value;\n    end;\nend;\n\n{**\n  Sets a new linked datasource.\n  @param Value a new linked datasource.\n}\nprocedure TZAbstractRODataset.SetDataSource(Value: TDataSource);\nbegin\n  {$IFNDEF FPC}\n  if IsLinkedTo(Value) then\n  {$ELSE}\n  if Value.IsLinkedTo(Self) then\n  {$ENDIF}\n    raise EZDatabaseError.Create(SCircularLink);\n  DataLink.DataSource := Value;\nend;\n\n{**\n  Gets a master datasource.\n  @returns a master datasource.\n}\nfunction TZAbstractRODataset.GetMasterDataSource: TDataSource;\nbegin\n  Result := MasterLink.DataSource;\nend;\n\n{**\n  Sets a new master datasource.\n  @param Value a new master datasource.\n}\nprocedure TZAbstractRODataset.SetMasterDataSource(Value: TDataSource);\nbegin\n  {$IFNDEF FPC}\n  if IsLinkedTo(Value) then\n  {$ELSE}\n  if Value.IsLinkedTo(Self) then\n  {$ENDIF}\n    raise EZDatabaseError.Create(SCircularLink);\n  MasterLink.DataSource := Value;\n  RereadRows;\nend;\n\n{**\n  Gets master link fields.\n  @returns a list with master fields.\n}\nfunction TZAbstractRODataset.GetMasterFields: string;\nbegin\n  Result := FMasterLink.FieldNames;\nend;\n\n{**\n  Sets master link fields.\n  @param Value a new master link fields.\n}\nprocedure TZAbstractRODataset.SetMasterFields(const Value: string);\nbegin\n  if FMasterLink.FieldNames <> Value then\n  begin\n    FMasterLink.FieldNames := Value;\n    RereadRows;\n  end;\nend;\n\n{**\n  Processes change events from the master dataset.\n  @param Sender an event sender object.\n}\nprocedure TZAbstractRODataset.MasterChanged(Sender: TObject);\nbegin\n  CheckBrowseMode;\n  if (doAlwaysDetailResync in FOptions) or (FMasterLink.DataSet = nil)\n    or not (FMasterLink.DataSet.State in [dsEdit, dsInsert]) then\n    RereadRows;\nend;\n\n{**\n  Processes disable events from the master dataset.\n  @param Sender an event sender object.\n}\nprocedure TZAbstractRODataset.MasterDisabled(Sender: TObject);\nbegin\n  RereadRows;\nend;\n\n{**\n  Initializes new record with master fields.\n}\n{$WARNINGS OFF}\nprocedure TZAbstractRODataset.DoOnNewRecord;\nvar\n  I: Integer;\n  MasterField, DetailField: TField;\n  Temp: Int64;\n  P1, P2 : Integer;\nbegin\n  if MasterLink.Active and (MasterLink.Fields.Count > 0) then\n  begin\n    for I := 0 to MasterLink.Fields.Count - 1 do\n    begin\n      if I < IndexFields.Count then\n      begin\n        MasterField := TField(MasterLink.Fields[I]);\n        DetailField := TField(IndexFields[I]);\n        // Processes LargeInt fields.\n        if (MasterField is TLargeIntField)\n          or (DetailField is TLargeIntField) then\n        begin\n          if MasterField is TLargeIntField then\n            Temp := TLargeIntField(\n              MasterField).{$IFDEF WITH_ASLARGEINT}AsLargeInt{$ELSE}Value{$ENDIF}\n          else\n            Temp := MasterField.AsInteger;\n          if DetailField is TLargeIntField then\n            TLargeIntField(DetailField).{$IFDEF WITH_ASLARGEINT}AsLargeInt{$ELSE}Value{$ENDIF} := Temp\n          else\n            DetailField.AsString := IntToStr(Temp);\n        end\n        // Processes all other fields.\n        else\n          DetailField.Value := MasterField.Value;\n      end;\n    end;\n  end\n  else\n  begin\n    if DataLink.Active and (DataLink.dataset.Fields.Count > 0) then\n    begin\n      p1 := 1; p2 := 1;\n      while (P1 <= Length(LinkedFields)) and (p2 <= Length(MasterFields)) do\n      begin\n        DetailField := FieldByName(ExtractFieldName(LinkedFields, P1));\n        MasterField := DataLink.DataSet.FieldByName (ExtractFieldName(MasterFields, P2));\n        DetailField.Assign(MasterField);\n      end;\n    end;\n  end;\n  inherited DoOnNewRecord;\nend;\n{$WARNINGS ON}\n\n{**\n  Gets a list of index field names.\n  @returns a list of index field names.\n}\nfunction TZAbstractRODataset.GetLinkedFields: string; {renamed by bangfauzan}\nbegin\n  Result := FLinkedFields; {renamed by bangfauzan}\nend;\n\n{**\n  Sets a new list of index field names.\n  @param Value a new list of index field names.\n}\nprocedure TZAbstractRODataset.SetLinkedFields(const Value: string); {renamed by bangfauzan}\nbegin\n  if FLinkedFields <> Value then {renamed by bangfauzan}\n  begin\n    FLinkedFields := Value; {renamed by bangfauzan}\n    IndexFields.Clear;\n    if State <> dsInactive then\n    begin\n      GetFieldList(IndexFields, FLinkedFields); {renamed by bangfauzan}\n      RereadRows;\n    end;\n  end;\nend;\n\n{**\n  Sets a new set of dataset options.\n  @param Value a new set of dataset options.\n}\nprocedure TZAbstractRODataset.SetOptions(Value: TZDatasetOptions);\nbegin\n  if FOptions <> Value then\n    FOptions := Value;\nend;\n\n{**\n  Sets a new sorted fields.\n  @param Value a new sorted fields.\n}\nprocedure TZAbstractRODataset.SetSortedFields({const} Value: string); {bangfauzan modification}\nbegin\n  Value:=Trim(Value); {bangfauzan addition}\n  if (FSortedFields <> Value) or (FIndexFieldNames <> Value)then {bangfauzan modification}\n  begin\n    FIndexFieldNames:=Value;\n    FSortType := GetSortType; {bangfauzan addition}\n    {removing ASC or DESC behind space}\n    if (FSortType <> stIgnored) then\n    begin {pawelsel modification}\n       Value:=StringReplace(Value,' Desc','',[rfReplaceAll,rfIgnoreCase]);\n       Value:=StringReplace(Value,' Asc','',[rfReplaceAll,rfIgnoreCase]);\n    end;\n    FSortedFields := Value;\n    if Active then\n      {InternalSort;}\n      {bangfauzan modification}\n      if (FSortedFields = '') then\n        Self.InternalRefresh\n      else\n        InternalSort;\n      {end of bangfauzan modification}\n  end;\nend;\n\n{**\n  Refreshes parameters and reopens the dataset.\n}\nprocedure TZAbstractRODataset.RefreshParams;\nvar\n  DataSet: TDataSet;\nbegin\n  DisableControls;\n  try\n    if FDataLink.DataSource <> nil then\n    begin\n      DataSet := FDataLink.DataSource.DataSet;\n      if DataSet <> nil then\n        if DataSet.Active and not (DataSet.State in [dsSetKey, dsEdit]) then\n        begin\n          Refresh;\n        end;\n    end;\n  finally\n    EnableControls;\n  end;\nend;\n\n{**\n  Performs the internal preparation of the query.\n}\nprocedure TZAbstractRODataset.InternalPrepare;\nbegin\n  CheckSQLQuery;\n  CheckInactive;  //AVZ - Need to check this\n  CheckConnected;\n\n  Connection.ShowSQLHourGlass;\n  try\n    if (FSQL.StatementCount > 0) and((Statement = nil) or (Statement.GetConnection.IsClosed)) then\n      Statement := CreateStatement(FSQL.Statements[0].SQL, Properties)\n    else\n      if (Assigned(Statement)) then\n         Statement.ClearParameters;\n  finally\n    Connection.HideSQLHourGlass;\n  end;\nend;\n\n{**\n  Rolls back the internal preparation of the query.\n}\nprocedure TZAbstractRODataset.InternalUnPrepare;\nbegin\n  if Statement <> nil then\n    begin\n      Statement.Close;\n      Statement := nil;\n    end;\nend;\n\n{**\n  Performs internal switch to the specified bookmark.\n  @param Bookmark a specified bookmark.\n}\nprocedure TZAbstractRODataset.InternalGotoBookmark(Bookmark: Pointer);\nbegin\n  if not GotoRow(PInteger(Bookmark)^) then\n    raise EZDatabaseError.Create(SBookmarkWasNotFound);\nend;\n\n{**\n  Performs an internal switch to the specified record.\n  @param Buffer the specified row buffer.\n}\n\n{$IFDEF WITH_TRECORDBUFFER}\nprocedure TZAbstractRODataset.InternalSetToRecord(Buffer: TRecordBuffer);\n{$ELSE}\nprocedure TZAbstractRODataset.InternalSetToRecord(Buffer: PChar);\n{$ENDIF}\nbegin\n  GotoRow(PZRowBuffer(Buffer)^.Index);\nend;\n\n{**\n  Performs an internal adding a new record.\n  @param Buffer a buffer of the new adding record.\n  @param Append <code>True</code> if record should be added to the end\n    of the result set.\n}\nprocedure TZAbstractRODataset.InternalAddRecord(Buffer: Pointer;\n  Append: Boolean);\nbegin\n  RaiseReadOnlyError;\nend;\n\n{**\n  Performs an internal record removing.\n}\nprocedure TZAbstractRODataset.InternalDelete;\nbegin\n  RaiseReadOnlyError;\nend;\n\n{**\n  Performs an internal post updates.\n}\nprocedure TZAbstractRODataset.InternalPost;\n  procedure Checkrequired;\n  var\n    I: longint;\n    columnindex : integer;\n  begin\n    For I:=0 to Fields.Count-1 do\n      With Fields[i] do\n        Case State of\n         dsEdit:\n          if Required and not ReadOnly and (FieldKind=fkData) and IsNull then\n            raise EZDatabaseError.Create(Format(SNeedField,[DisplayName]));\n         dsInsert:\n          if Required and not ReadOnly and (FieldKind=fkData) and IsNull then\n            begin\n           // allow autoincrement and defaulted fields to be null;\n              columnindex := Resultset.FindColumn(Fields[i].FieldName);\n              if (Columnindex = 0) or\n                 (not Resultset.GetMetadata.HasDefaultValue(columnIndex) and\n                  not Resultset.GetMetadata.IsAutoIncrement(columnIndex)) then\n                raise EZDatabaseError.Create(Format(SNeedField,[DisplayName]));\n            end;\n        End;\n  end;\n\nbegin\n  if not (Self is TZAbstractDataset) then\n    RaiseReadOnlyError;\n\n  Checkrequired;\nend;\n\n{**\n  Gets a bookmark flag from the specified record.\n  @param Buffer a pointer to the record buffer.\n  @return a bookmark flag from the specified record.\n}\n\n{$IFDEF WITH_TRECORDBUFFER}\n\nfunction TZAbstractRODataset.GetBookmarkFlag(Buffer: TRecordBuffer): TBookmarkFlag;\n{$ELSE}\n\nfunction TZAbstractRODataset.GetBookmarkFlag(Buffer: PChar): TBookmarkFlag;\n{$ENDIF}\nbegin\n  Result := TBookmarkFlag(PZRowBuffer(Buffer)^.BookmarkFlag);\nend;\n\n{**\n  Sets a new bookmark flag to the specified record.\n  @param Buffer a pointer to the record buffer.\n  @param Value a new bookmark flag to the specified record.\n}\n\n{$IFDEF WITH_TRECORDBUFFER}\nprocedure TZAbstractRODataset.SetBookmarkFlag(Buffer: TRecordBuffer;\n  Value: TBookmarkFlag);\n{$ELSE}\nprocedure TZAbstractRODataset.SetBookmarkFlag(Buffer: PChar;\n  Value: TBookmarkFlag);\n{$ENDIF}\nbegin\n  PZRowBuffer(Buffer)^.BookmarkFlag := Ord(Value);\nend;\n\n{**\n  Gets bookmark value from the specified record.\n  @param Buffer a pointer to the record buffer.\n  @param Data a pointer to the bookmark value.\n}\n\nprocedure TZAbstractRODataset.GetBookmarkData(\n  Buffer: {$IFDEF WITH_TRECORDBUFFER}TRecordBuffer{$ELSE}PChar{$ENDIF};\n  Data: {$IFDEF WITH_BOOKMARKDATA_TBOOKMARK}TBookMark{$ELSE}Pointer{$ENDIF});\nbegin\n  PInteger(Data)^ := PZRowBuffer(Buffer)^.Index;\nend;\n\n{**\n  Sets a new bookmark value from the specified record.\n  @param Buffer a pointer to the record buffer.\n  @param Data a pointer to the bookmark value.\n}\n\n\nprocedure TZAbstractRODataset.SetBookmarkData(\n  Buffer: {$IFDEF WITH_TRECORDBUFFER}TRecordBuffer{$ELSE}PChar{$ENDIF};\n  Data: {$IFDEF WITH_BOOKMARKDATA_TBOOKMARK}TBookMark{$ELSE}Pointer{$ENDIF});\nbegin\n  PZRowBuffer(Buffer)^.Index := PInteger(Data)^;\nend;\n\n{**\n  Compare two specified bookmarks.\n  @param Bookmark1 the first bookmark object.\n  @param Bookmark2 the second bookmark object.\n  @return 0 if bookmarks are equal, -1 if the first bookmark is less,\n    1 if the first bookmark is greatter.\n}\nfunction TZAbstractRODataset.CompareBookmarks(Bookmark1,\n  Bookmark2: TBookmark): Integer;\nvar\n  Index1, Index2: Integer;\nbegin\n  Result := 0;\n  if not Assigned(Bookmark1) or not Assigned(Bookmark2) then\n    Exit;\n\n  Index1 := CurrentRows.IndexOf(Pointer(PInteger(Bookmark1)^));\n  Index2 := CurrentRows.IndexOf(Pointer(PInteger(Bookmark2)^));\n\n  if Index1 < Index2 then Result := -1\n  else if Index1 > Index2 then Result := 1;\nend;\n\n{**\n  Checks is the specified bookmark valid.\n  @param Bookmark a bookmark object.\n  @return <code>True</code> if the bookmark is valid.\n}\nfunction TZAbstractRODataset.BookmarkValid(Bookmark: TBookmark): Boolean;\nbegin\n  Result := False;\n  if Active and Assigned(Bookmark) and (FResultSet <> nil) then\n    try\n      Result := CurrentRows.IndexOf(Pointer(PInteger(Bookmark)^)) >= 0;\n    except\n      Result := False;\n    end;\nend;\n\n{**\n  Performs an internal initialization of record buffer.\n  @param Buffer a record buffer for initialization.\n}\n\n{$IFDEF WITH_TRECORDBUFFER}\nprocedure TZAbstractRODataset.InternalInitRecord(Buffer: TRecordBuffer);\n{$ELSE}\nprocedure TZAbstractRODataset.InternalInitRecord(Buffer: PChar);\n{$ENDIF}\nbegin\n  RowAccessor.ClearBuffer(PZRowBuffer(Buffer));\nend;\n\n{**\n  Performs an internal refreshing.\n}\nprocedure TZAbstractRODataset.InternalRefresh;\nvar\n  RowNo: Integer;\n  Found: Boolean;\n  KeyFields: string;\n  Temp: TZVariantDynArray;\n  KeyValues: Variant;\n  FieldRefs: TObjectDynArray;\n  OnlyDataFields: Boolean;\nbegin\n  OnlyDataFields := False;\n  FieldRefs := nil;\n  if Active then\n  begin\n    if CurrentRow > 0 then\n    begin\n      RowNo := Integer(CurrentRows[CurrentRow - 1]);\n      if ResultSet.GetRow <> RowNo then\n        ResultSet.MoveAbsolute(RowNo);\n\n      if Properties.Values['KeyFields'] <> '' then\n        KeyFields := Properties.Values['KeyFields']\n      else\n        KeyFields := DefineKeyFields(Fields);\n      FieldRefs := DefineFields(Self, KeyFields, OnlyDataFields);\n      SetLength(Temp, Length(FieldRefs));\n      RetrieveDataFieldsFromResultSet(FieldRefs, ResultSet, Temp);\n      if Length(FieldRefs) = 1 then\n        KeyValues := EncodeVariant(Temp[0])\n      else\n        KeyValues := EncodeVariantArray(Temp);\n    end\n    else\n    begin\n      KeyFields := '';\n      KeyValues := Unassigned;\n    end;\n\n    DisableControls;\n    try\n      try\n        FRefreshInProgress := True;\n        InternalClose;\n        InternalOpen;\n      finally\n        FRefreshInProgress := False;\n      end;\n\n      DoBeforeScroll;\n      if KeyFields <> '' then\n        Found := Locate(KeyFields, KeyValues, [])\n      else\n        Found := False;\n    finally\n      EnableControls;\n    end;\n\n    if not Found then\n    begin\n      DoBeforeScroll;\n      DoAfterScroll;\n    end;\n  end;\nend;\n\n{**\n  Finds the next record in a filtered query.\n  @param Restart a <code>True</code> to find from the start of the query.\n  @param GoForward <code>True</code> to navigate in the forward direction.\n  @return <code>True</code> if a sutisfied row was found.\n}\nfunction TZAbstractRODataset.FindRecord(Restart, GoForward: Boolean): Boolean;\nvar\n  Index: Integer;\n  SavedFilterEnabled: Boolean;\nbegin\n  { Checks the current state. }\n  CheckBrowseMode;\n  DoBeforeScroll;\n  Result := False;\n\n  { Defines an initial position position. }\n  if Restart then\n  begin\n    if GoForward then\n      Index := 1\n    else\n    begin\n      FetchRows(0);\n      Index := CurrentRows.Count;\n    end\n  end\n  else\n  begin\n    Index := CurrentRow;\n    if GoForward then\n    begin\n      Inc(Index);\n      if Index > CurrentRows.Count then\n        FetchOneRow;\n    end\n    else\n      Dec(Index);\n  end;\n\n  { Finds a record. }\n  SavedFilterEnabled := FilterEnabled;\n  try\n    FilterEnabled := True;\n    while (Index >= 1) and (Index <= CurrentRows.Count) do\n    begin\n      if FilterRow(Index) then\n      begin\n        Result := True;\n        Break;\n      end;\n      if GoForward then\n      begin\n        Inc(Index);\n        if Index > CurrentRows.Count then\n          FetchOneRow;\n      end\n      else\n        Dec(Index)\n    end\n  finally\n    FilterEnabled := SavedFilterEnabled;\n  end;\n\n  { Sets a new found position. }\n  SetFound(Result);\n  if Result then\n  begin\n    MoveRecNo(Index);\n    DoAfterScroll;\n  end;\nend;\n\n{**\n  Sets a filtering control flag.\n  @param Value <code>True</code> to turn filtering On.\n}\nprocedure TZAbstractRODataset.SetFiltered(Value: Boolean);\nbegin\n  if Value <> FilterEnabled then\n  begin\n    FilterEnabled := Value;\n    inherited SetFiltered(Value);\n    RereadRows;\n  end;\nend;\n\n{**\n  Sets a new filter expression string.\n  @param Value a new filter expression.\n}\nprocedure TZAbstractRODataset.SetFilterText(const Value: string);\nbegin\n  inherited SetFilterText(Value);\n  FilterExpression.DefaultVariables.Clear;\n  FilterExpression.Expression := Value;\n  InitFilterFields := False;\n  if FilterEnabled then\n    RereadRows;\nend;\n\n{**\n  Checks is the opened resultset sequensed?\n  @return <code>True</code> if the opened resultset is sequenced.\n}\nfunction TZAbstractRODataset.IsSequenced: Boolean;\nbegin\n  Result := (not FilterEnabled);\nend;\n\n{**\n  Processes component notifications.\n  @param AComponent a changed component object.\n  @param Operation a component operation code.\n}\nprocedure TZAbstractRODataset.Notification(AComponent: TComponent;\n  Operation: TOperation);\nbegin\n  inherited Notification(AComponent, Operation);\n\n  if (Operation = opRemove) and (AComponent = FConnection) then\n  begin\n    Close;\n    FConnection := nil;\n  end;\n\n  if (Operation = opRemove) and Assigned(FDataLink)\n    and (AComponent = FDataLink.Datasource) then\n    FDataLink.DataSource := nil;\n\n  if (Operation = opRemove) and Assigned(FMasterLink)\n    and (AComponent = FMasterLink.Datasource) then\n  begin\n    FMasterLink.DataSource := nil;\n    RereadRows;\n  end;\nend;\n\n{**\n  Performs an internal record search.\n  @param KeyFields a list of field names.\n  @param KeyValues a list of field values.\n  @param Options a search options.\n  @return an index of found row or -1 if nothing was found.\n}\nfunction TZAbstractRODataset.InternalLocate(const KeyFields: string;\n  const KeyValues: Variant; Options: TLocateOptions): LongInt;\nvar\n  I, RowNo, RowCount: Integer;\n  FieldRefs: TObjectDynArray;\n  FieldIndices: TIntegerDynArray;\n  OnlyDataFields: Boolean;\n  SearchRowBuffer: PZRowBuffer;\n  DecodedKeyValues: TZVariantDynArray;\n  RowValues: TZVariantDynArray;\n  PartialKey: Boolean;\n  CaseInsensitive: Boolean;\nbegin\n  OnlyDataFields := False;\n  CheckBrowseMode;\n  Result := -1;\n  DecodedKeyValues := nil;\n\n  PartialKey := loPartialKey in Options;\n  CaseInsensitive := loCaseInsensitive in Options;\n\n  FieldRefs := DefineFields(Self, KeyFields, OnlyDataFields);\n  FieldIndices := nil;\n  if FieldRefs = nil then\n     Exit;\n  DecodedKeyValues := DecodeVariantArray(KeyValues);\n\n  { Checks for equal field and values number }\n  if Length(FieldRefs) <> Length(DecodedKeyValues) then\n    raise EZDatabaseError.Create(SIncorrectSearchFieldsNumber);\n  SetLength(RowValues, Length(DecodedKeyValues));\n\n  if not OnlyDataFields then\n  begin\n    { Processes fields if come calculated or lookup fields are involved. }\n    SearchRowBuffer := PZRowBuffer(AllocRecordBuffer);\n    try\n      I := 0;\n      FieldIndices := DefineFieldIndices(FieldsLookupTable, FieldRefs);\n      RowCount := CurrentRows.Count;\n      while True do\n      begin\n        while (I >= RowCount) and FetchOneRow do\n          RowCount := CurrentRows.Count;\n        if I >= RowCount then\n          Break;\n\n        RowNo := Integer(CurrentRows[I]);\n        ResultSet.MoveAbsolute(RowNo);\n\n        RowAccessor.RowBuffer := SearchRowBuffer;\n        RowAccessor.RowBuffer^.Index := RowNo;\n        FetchFromResultSet(ResultSet, FieldsLookupTable, Fields, RowAccessor);\n{$IFDEF WITH_TRECORDBUFFER}\n        GetCalcFields({$IFDEF WITH_GETCALCFIELDS_TRECBUF}NativeInt{$ELSE}TRecordBuffer{$ENDIF}(SearchRowBuffer));\n{$ELSE}\n        GetCalcFields(PChar(SearchRowBuffer));\n{$ENDIF}\n        RetrieveDataFieldsFromRowAccessor(\n          FieldRefs, FieldIndices, RowAccessor, RowValues);\n\n        if CompareDataFields(DecodedKeyValues, RowValues,\n          PartialKey, CaseInsensitive) then\n        begin\n          Result := I + 1;\n          Break;\n        end;\n\n        Inc(I);\n      end;\n    finally\n      if SearchRowBuffer <> nil then\n{$IFDEF WITH_TRECORDBUFFER}\n        FreeRecordBuffer(TRecordBuffer(SearchRowBuffer));\n{$ELSE}\n        FreeRecordBuffer(PChar(SearchRowBuffer));\n{$ENDIF}\n    end;\n  end\n  else\n  begin\n    PrepareValuesForComparison(FieldRefs, DecodedKeyValues,\n      ResultSet, PartialKey, CaseInsensitive);\n\n    { Processes only data fields. }\n    I := 0;\n    RowCount := CurrentRows.Count;\n    while True do\n    begin\n      while (I >= RowCount) and FetchOneRow do\n        RowCount := CurrentRows.Count;\n      if I >= RowCount then\n        Break;\n\n      RowNo := Integer(CurrentRows[I]);\n      ResultSet.MoveAbsolute(RowNo);\n\n      if CompareFieldsFromResultSet(FieldRefs, DecodedKeyValues,\n        ResultSet, PartialKey, CaseInsensitive) then\n      begin\n        Result := I + 1;\n        Break;\n      end;\n\n      Inc(I);\n    end;\n  end;\nend;\n\n{**\n  Locates an interested record by specified search criteria.\n  @param KeyFields a list of field names.\n  @param KeyValues a list of field values.\n  @param Options a search options.\n  @return <code>True</code> if record was found or <code>False</code> otherwise.\n}\nfunction TZAbstractRODataset.Locate(const KeyFields: string;\n  const KeyValues: Variant; Options: TLocateOptions): Boolean;\nvar\n  Index: Integer;\nbegin\n  DoBeforeScroll;\n  if (Active) then //AVZ Check if the dataset is active before performing locate - return false otherwise\n  begin\n    Index := InternalLocate(KeyFields, KeyValues, Options);\n    if Index > 0 then\n    begin\n      MoveRecNo(Index);\n      DoAfterScroll;\n      Result := True;\n    end\n    else\n      Result := False;\n    SetFound(Result);\n\n  end\n    else\n  begin\n    Result := False;\n  end;\nend;\n\n{**\n  Lookups specified fields from the searched record.\n  @param KeyValues a list of field names to search record.\n  @param KeyValues an array of field values to search record.\n  @param ResultFields a list of field names to return as a result.\n  @return an array of requested field values.\n}\nfunction TZAbstractRODataset.Lookup(const KeyFields: string;\n  const KeyValues: Variant; const ResultFields: string): Variant;\nvar\n  RowNo: Integer;\n  FieldRefs: TObjectDynArray;\n  FieldIndices: TIntegerDynArray;\n  OnlyDataFields: Boolean;\n  SearchRowBuffer: PZRowBuffer;\n  ResultValues: TZVariantDynArray;\nbegin\n  OnlyDataFields := False;\n  Result := Null;\n  RowNo := InternalLocate(KeyFields, KeyValues, []);\n  FieldRefs := nil;\n  FieldIndices := nil;\n  if RowNo < 0 then\n     Exit;\n\n  { Fill result array }\n  FieldRefs := DefineFields(Self, ResultFields, OnlyDataFields);\n  FieldIndices := DefineFieldIndices(FieldsLookupTable, FieldRefs);\n  SetLength(ResultValues, Length(FieldRefs));\n  SearchRowBuffer := PZRowBuffer(AllocRecordBuffer);\n  try\n    RowNo := Integer(CurrentRows[RowNo - 1]);\n    if ResultSet.GetRow <> RowNo then\n      ResultSet.MoveAbsolute(RowNo);\n\n    RowAccessor.RowBuffer := SearchRowBuffer;\n    RowAccessor.RowBuffer^.Index := RowNo;\n    FetchFromResultSet(ResultSet, FieldsLookupTable, Fields, RowAccessor);\n{$IFDEF WITH_TRECORDBUFFER}\n    GetCalcFields({$IFDEF WITH_GETCALCFIELDS_TRECBUF}NativeInt{$ELSE}TRecordBuffer{$ENDIF}(SearchRowBuffer));\n{$ELSE}\n    GetCalcFields(PChar(SearchRowBuffer));\n{$ENDIF}\n    RetrieveDataFieldsFromRowAccessor(\n      FieldRefs, FieldIndices, RowAccessor, ResultValues);\n  finally\n{$IFDEF WITH_TRECORDBUFFER}\n    FreeRecordBuffer(TRecordBuffer(SearchRowBuffer));\n{$ELSE}\n    FreeRecordBuffer(PChar(SearchRowBuffer));\n{$ENDIF}\n  end;\n\n  if Length(FieldIndices) = 1 then\n    Result := EncodeVariant(ResultValues[0])\n  else\n    Result := EncodeVariantArray(ResultValues);\nend;\n\n{**\n  Gets the updated status for the current row.\n  @return the UpdateStatus value for the current row.\n}\nfunction TZAbstractRODataset.UpdateStatus: TUpdateStatus;\nvar\n  RowNo: Integer;\nbegin\n  Result := usUnmodified;\n  if (ResultSet <> nil) and (CurrentRows.Count > 0) then\n  begin\n    RowNo := Integer(CurrentRows[CurrentRow - 1]);\n    if ResultSet.GetRow <> RowNo then\n      ResultSet.MoveAbsolute(RowNo);\n\n    if ResultSet.RowInserted then\n      Result := usInserted\n    else if ResultSet.RowUpdated then\n      Result := usModified\n    else if ResultSet.RowDeleted then\n      Result := usDeleted;\n  end;\nend;\n\n{**\n  Translates strings between ansi and oem character sets.\n}\nfunction TZAbstractRODataset.Translate(Src, Dest: PAnsiChar; ToOem: Boolean):\n   Integer;\nbegin\n  if (Src <> nil) then\n  begin\n    Result := {$IFDEF WITH_STRLEN_DEPRECATED}AnsiStrings.{$ENDIF}StrLen(Src);\n  {$IFNDEF UNIX}\n    if doOemTranslate in FOptions then\n    begin\n      if ToOem then\n        CharToOemA(Src, Dest)\n      else\n        OemToCharA(Src, Dest);\n      Dest[Result] := #0;\n    end\n    else\n  {$ENDIF}\n    begin\n      if (Src <> Dest) then\n      {$IFDEF WITH_STRCOPY_DEPRECATED}AnsiStrings.{$ENDIF}StrCopy(Dest, Src);\n    end;\n  end\n  else\n    Result := 0;\nend;\n\n{**\n  Prepares the query.\n  If this actually does happen at the database connection level depends on the\n  specific implementation.\n}\nprocedure TZAbstractRODataset.Prepare;\nbegin\n  Prepared := True;\nend;\n\n{**\n  Unprepares the query.\n  Before the query gets executed it must be prepared again.\n}\nprocedure TZAbstractRODataset.Unprepare;\nbegin\n  Prepared := False;\nend;\n\n{**\n  Creates a stream object for specified blob field.\n  @param Field an interested field object.\n  @param Mode a blob open mode.\n  @return a created stream object.\n}\nfunction TZAbstractRODataset.CreateBlobStream(Field: TField;\n  Mode: TBlobStreamMode): TStream;\nvar\n  ColumnIndex: Integer;\n  RowBuffer: PZRowBuffer;\n  Blob: IZBlob;\n  WasNull: Boolean;\nbegin\n  WasNull := False;\n  CheckActive;\n\n  Result := nil;\n  if (Field.DataType in [ftBlob, ftMemo, ftGraphic, ftFmtMemo {$IFDEF WITH_WIDEMEMO},ftWideMemo{$ENDIF}])\n    and GetActiveBuffer(RowBuffer) then\n  begin\n    ColumnIndex := DefineFieldIndex(FieldsLookupTable, Field);\n    RowAccessor.RowBuffer := RowBuffer;\n\n    if Mode = bmRead then\n    begin\n      case Field.DataType of\n      ftMemo, ftFmtMemo:\n        Result := RowAccessor.GetAsciiStream(ColumnIndex, WasNull);\n      {$IFDEF WITH_WIDEMEMO}\n      ftWideMemo:\n        Result := RowAccessor.GetUnicodeStream(ColumnIndex, WasNull)\n      {$ENDIF}\n      else\n        Result := RowAccessor.GetBinaryStream(ColumnIndex, WasNull);\n      end;\n    end\n    else\n    begin\n      Blob := RowAccessor.GetBlob(ColumnIndex, WasNull);\n      if Blob <> nil then\n        Blob := Blob.Clone;\n      RowAccessor.SetBlob(ColumnIndex, Blob);\n      Result := TZBlobStream.Create(Field as TBlobField, Blob, Mode,\n        FConnection.DbcConnection.GetConSettings);\n    end;\n  end;\n  if Result = nil then\n    Result := TMemoryStream.Create;\nend;\n\n{$IFDEF WITH_FTDATASETSUPPORT}\nfunction TZAbstractRODataset.CreateNestedDataSet(DataSetField: TDataSetField): TDataSet;\nbegin\n  Result := inherited CreateNestedDataSet(DataSetField);\nend;\n{$ENDIF}\n\n{**\n  Closes the specified BLOB field.\n  @param a BLOB field object.\n}\nprocedure TZAbstractRODataset.CloseBlob(Field: TField);\nbegin\nend;\n\n{**\n  Closes the cursor-handles. Releases(not closing) the current resultset\n  and opens the cursorhandles. The current statment is used further.\n  @param the NewResultSet\n}\nprocedure TZAbstractRODataset.SetAnotherResultset(const Value: IZResultSet);\nbegin\n  {EgonHugeist: I was forced to go this stupid sequence\n    first i wanted to exclude parts of InternalOpen/Close but this didn't solve\n    the DataSet issues. You can't init the fields as long the Cursor is not\n    closed.. Which is equal to cursor open}\n  if Assigned(Value) and ( Value <> ResultSet ) then\n  begin\n    FDoNotCloseResultSet := True; //hint for InternalClose\n    SetState(dsInactive);\n    CloseCursor; //Calls InternalOpen in his sequence so InternalClose must be prepared\n    FDoNotCloseResultSet := False; //reset hint for InternalClose\n    ResultSet := Value; //Assign the new resultset\n    if not ResultSet.IsBeforeFirst then\n      ResultSet.BeforeFirst; //need this. All from dataset buffered resultsets are EOR\n    FUseCurrentStatment := True; //hint for InternalOpen\n    OpenCursor{$IFDEF FPC}(False){$ENDIF}; //Calls InternalOpen in his sequence so InternalOpen must be prepared\n    OpenCursorComplete; //set DataSet to dsActive\n    FUseCurrentStatment := False; //reset hint for InternalOpen\n  end;\nend;\n\n{**\n  Performs sorting of the internal rows.\n}\nprocedure TZAbstractRODataset.InternalSort;\nvar\n  I, RowNo: Integer;\n  SavedRowBuffer: PZRowBuffer;\nbegin\n  if FIndexFieldNames = '' then exit; {bangfauzan addition}\n  if (ResultSet <> nil) and not IsUniDirectional then\n  begin\n    FIndexFieldNames := Trim(FIndexFieldNames); {bangfauzan modification}\n    DefineSortedFields(Self, {FSortedFields} FIndexFieldNames {bangfauzan modification},\n    FSortedFieldRefs, FSortedFieldDirs, FSortedOnlyDataFields);\n\n    if (CurrentRow <= CurrentRows.Count) and (CurrentRows.Count > 0)\n      and (CurrentRow > 0) then\n      RowNo := Integer(CurrentRows[CurrentRow - 1])\n    else\n      RowNo := -1;\n\n    { Restores the previous order. }\n    if Length(FSortedFieldRefs) = 0 then\n    begin\n      CurrentRows.Sort(ClearSort);\n    end\n    else\n    begin\n      FetchRows(0);\n      if FSortedOnlyDataFields then\n      begin\n        { Converts field objects into field indices. }\n        SetLength(FSortedFieldIndices, Length(FSortedFieldRefs));\n        for I := 0 to High(FSortedFieldRefs) do\n          FSortedFieldIndices[I] := TField(FSortedFieldRefs[I]).FieldNo;\n        { Performs a sorting. }\n        CurrentRows.Sort(LowLevelSort);\n      end\n      else\n      begin\n        SavedRowBuffer := RowAccessor.RowBuffer;\n        { Sorts using generic highlevel approach. }\n        try\n          { Allocates buffers for sorting. }\n          RowAccessor.AllocBuffer(FSortRowBuffer1);\n          RowAccessor.AllocBuffer(FSortRowBuffer2);\n          { Converts field objects into field indices. }\n          SetLength(FSortedFieldIndices, Length(FSortedFieldRefs));\n          for I := 0 to High(FSortedFieldRefs) do\n          begin\n            FSortedFieldIndices[I] := DefineFieldIndex(FieldsLookupTable,\n              TField(FSortedFieldRefs[I]));\n          end;\n          { Performs sorting. }\n          CurrentRows.Sort(HighLevelSort);\n        finally\n          { Disposed buffers for sorting. }\n          RowAccessor.DisposeBuffer(FSortRowBuffer1);\n          RowAccessor.DisposeBuffer(FSortRowBuffer2);\n          RowAccessor.RowBuffer := SavedRowBuffer;\n        end;\n      end;\n    end;\n\n    CurrentRow := CurrentRows.IndexOf(Pointer(RowNo)) + 1;\n    CurrentRow := Min(Max(0, CurrentRow), CurrentRows.Count);\n    if not (State in [dsInactive]) then\n       Resync([]);\n  end;\nend;\n\n{**\n  Clears list sorting and restores the previous order.\n  @param Item1 a reference to the first row.\n  @param Item2 a reference to the second row.\n  @returns &gt;0 if Item1 &gt; Item2, &lt;0 it Item1 &lt; Item2 and 0\n    if Item1 and Item2 are equal.\n}\nfunction TZAbstractRODataset.ClearSort(Item1, Item2: Pointer): Integer;\nbegin\n  Result := Integer(Item1) - Integer(Item2);\nend;\n\n{**\n  Sorting list using generic approach which is slow but may be used\n  with calculated fields.\n\n  @param Item1 a reference to the first row.\n  @param Item2 a reference to the second row.\n  @returns &gt;0 if Item1 &gt; Item2, &lt;0 it Item1 &lt; Item2 and 0\n    if Item1 and Item2 are equal.\n}\nfunction TZAbstractRODataset.HighLevelSort(Item1, Item2: Pointer): Integer;\nvar\n  RowNo: Integer;\nbegin\n  { Gets the first row. }\n  RowNo := Integer(Item1);\n  ResultSet.MoveAbsolute(RowNo);\n  RowAccessor.RowBuffer := FSortRowBuffer1;\n  RowAccessor.RowBuffer^.Index := RowNo;\n  FetchFromResultSet(ResultSet, FieldsLookupTable, Fields, RowAccessor);\n  FRowAccessor.RowBuffer^.BookmarkFlag := Ord(bfCurrent);\n{$IFDEF WITH_TRECORDBUFFER}\n  GetCalcFields({$IFDEF WITH_GETCALCFIELDS_TRECBUF}NativeInt{$ELSE}TRecordBuffer{$ENDIF}(FSortRowBuffer1));\n{$ELSE}\n  GetCalcFields(PChar(FSortRowBuffer1));\n{$ENDIF}\n\n  { Gets the second row. }\n  RowNo := Integer(Item2);\n  ResultSet.MoveAbsolute(RowNo);\n  RowAccessor.RowBuffer := FSortRowBuffer2;\n  RowAccessor.RowBuffer^.Index := RowNo;\n  FetchFromResultSet(ResultSet, FieldsLookupTable, Fields, RowAccessor);\n  FRowAccessor.RowBuffer^.BookmarkFlag := Ord(bfCurrent);\n{$IFDEF WITH_TRECORDBUFFER}\n  GetCalcFields({$IFDEF WITH_GETCALCFIELDS_TRECBUF}NativeInt{$ELSE}TRecordBuffer{$ENDIF}(FSortRowBuffer2));\n{$ELSE}\n  GetCalcFields(PChar(FSortRowBuffer2));\n{$ENDIF}\n\n  { Compare both records. }\n  Result := RowAccessor.CompareBuffers(FSortRowBuffer1, FSortRowBuffer2,\n    FSortedFieldIndices, FSortedFieldDirs);\nend;\n\n{**\n  Sorting list using lowlevel approach which is fast but may not be used\n  with calculated fields.\n\n  @param Item1 a reference to the first row.\n  @param Item2 a reference to the second row.\n  @returns &gt;0 if Item1 &gt; Item2, &lt;0 it Item1 &lt; Item2 and 0\n    if Item1 and Item2 are equal.\n}\nfunction TZAbstractRODataset.LowLevelSort(Item1, Item2: Pointer): Integer;\nbegin\n  Result := ResultSet.CompareRows(Integer(Item1), Integer(Item2),\n    FSortedFieldIndices, FSortedFieldDirs);\nend;\n\n{**\n   Sets a new dataset properties.\n   @param Value a dataset properties.\n}\nprocedure TZAbstractRODataset.SetProperties(const Value: TStrings);\nbegin\n  FProperties.Assign(Value);\nend;\n\n{$IFDEF WITH_IPROVIDER}\n\n{**\n  Starts a new transaction.\n}\nprocedure TZAbstractRODataset.PSStartTransaction;\nbegin\n  if Assigned(FConnection) and not FConnection.AutoCommit then\n  begin\n    if not FConnection.Connected then\n      FConnection.Connect;\n    FConnection.StartTransaction;\n  end;\nend;\n\n{**\n  Completes previously started transaction.\n  @param Commit a commit transaction flag.\n}\nprocedure TZAbstractRODataset.PSEndTransaction(Commit: Boolean);\nbegin\n  if Assigned(FConnection) and FConnection.Connected\n    and not FConnection.AutoCommit then\n  begin\n      if Commit then\n         FConnection.Commit\n      else\n         FConnection.Rollback;\n  end;\nend;\n\n{**\n  Checks if this query is in transaction mode.\n  @returns <code>True</code> if query in transaction.\n}\nfunction TZAbstractRODataset.PSInTransaction: Boolean;\nbegin\n  Result := Assigned(FConnection) and FConnection.Connected\n    and (FConnection.TransactIsolationLevel <> tiNone)\n    and not FConnection.AutoCommit;\nend;\n\n{**\n  Returns a string quote character.\n  @retuns a quote character.\n}\n{$IFDEF WITH_IPROVIDERWIDE}\nfunction TZAbstractRODataset.PSGetQuoteCharW: WideString;\n{$ELSE}\nfunction TZAbstractRODataset.PSGetQuoteChar: string;\n{$ENDIF}\nbegin\n  if Assigned(FConnection) then\n  begin\n    if not FConnection.Connected then\n      FConnection.Connect;\n    Result := FConnection.DbcConnection.GetMetadata.GetDatabaseInfo.GetIdentifierQuoteString;\n    if Length(Result) > 1 then\n      Result := Copy(Result, 1, 1);\n  end\n  else\n    Result := '\"';\nend;\n\n{**\n  Checks if dataset can execute any commands?\n  @returns <code>True</code> if the query can execute any commands.\n}\nfunction TZAbstractRODataset.PSIsSQLSupported: Boolean;\nbegin\n  Result := True;\nend;\n\n{**\n  Checks if dataset can execute SQL queries?\n  @returns <code>True</code> if the query can execute SQL.\n}\nfunction TZAbstractRODataset.PSIsSQLBased: Boolean;\nbegin\n  Result := True;\nend;\n\n{**\n  Resets this dataset.\n}\nprocedure TZAbstractRODataset.PSReset;\nbegin\n  inherited PSReset;\n  if Active then\n  begin\n    Refresh;\n    First;\n  end;\nend;\n\n{**\n  Execute statement a SQL query.\n}\nprocedure TZAbstractRODataset.PSExecute;\nbegin\n  ExecSQL;\nend;\n\n{**\n  Gets query parameters.\n  @returns parameters of this query.\n}\nfunction TZAbstractRODataset.PSGetParams: TParams;\nbegin\n  Result := Params;\nend;\n\n{**\n  Set new query parameters\n  @param AParams new parameters to set into this query.\n}\nprocedure TZAbstractRODataset.PSSetParams(AParams: TParams);\nbegin\n  if AParams.Count > 0 then\n    Params.Assign(AParams);\nend;\n\n{**\n  Sets a command text for this query to execute.\n  @param CommandText a command text for this query.\n}\n\n{$IFDEF WITH_IPROVIDERWIDE}\nprocedure TZAbstractRODataset.PSSetCommandText(const CommandText: string);\nbegin\n  SQL.Text := CommandText;\nend;\n\nprocedure TZAbstractRODataset.PSSetCommandText(const CommandText: WideString);\n{$ELSE}\nprocedure TZAbstractRODataset.PSSetCommandText(const CommandText: string);\n{$ENDIF}\nbegin\n  SQL.Text := CommandText;\nend;\n\n{**\n  Updates a record in the specified dataset.\n  @param UpdateKind a type of the update.\n  @param Delta a dataset with updates.\n}\nfunction TZAbstractRODataset.PSUpdateRecord(UpdateKind: TUpdateKind;\n  Delta: TDataSet): Boolean;\nbegin\n  Result := False;\nend;\n\n{**\n  Generates an EUpdateError object based on another exception object.\n  @param E occured exception.\n  @param Prev a previous update error.\n  @returns a new created update error.\n}\nfunction TZAbstractRODataset.PSGetUpdateException(E: Exception;\n  Prev: EUpdateError): EUpdateError;\nvar\n  PrevErrorCode: Integer;\nbegin\n  if E is EZSQLException then\n  begin\n    if Assigned(Prev) then\n      PrevErrorCode := Prev.ErrorCode\n    else\n      PrevErrorCode := 0;\n\n    Result := EUpdateError.Create(E.Message, '',\n      EZSQLException(E).ErrorCode, PrevErrorCode, E);\n  end\n  else\n    Result := EUpdateError.Create(E.Message, '', -1, -1, E);\nend;\n\n{**\n  Gets a table name if table is only one in the SELECT SQL statement.\n  @returns a table name or an empty string is SQL query is complex SELECT\n    or not SELECT statement.\n}\n{$IFDEF WITH_IPROVIDERWIDE}\nfunction TZAbstractRODataset.PSGetTableNameW: WideString;\n{$ELSE}\nfunction TZAbstractRODataset.PSGetTableName: string;\n{$ENDIF}\nvar\n  Driver: IZDriver;\n  Tokenizer: IZTokenizer;\n  StatementAnalyser: IZStatementAnalyser;\n  SelectSchema: IZSelectSchema;\nbegin\n  Result := '';\n  if FConnection <> nil then\n  begin\n    Driver := FConnection.DbcDriver;\n    Tokenizer := Driver.GetTokenizer;\n    StatementAnalyser := Driver.GetStatementAnalyser;\n    SelectSchema := StatementAnalyser.DefineSelectSchemaFromQuery(\n      Tokenizer, SQL.Text);\n    if Assigned(SelectSchema) and (SelectSchema.TableCount = 1) then\n      Result := SelectSchema.Tables[0].FullName;\n  end;\nend;\n\n{**\n  Defines a list of query primary key fields.\n  @returns a semicolon delimited list of query key fields.\n}\n// Silvio Clecio\n{$IFDEF WITH_IPROVIDERWIDE}\n{$WARNINGS OFF}\nfunction TZAbstractRODataset.PSGetKeyFieldsW: WideString;\nbegin\n  Result := inherited PSGetKeyFieldsW;\nend;\n{$WARNINGS ON}\n{$ELSE}\nfunction TZAbstractRODataset.PSGetKeyFields: string;\nbegin\n  Result := inherited PSGetKeyFields;\nend;\n{$ENDIF}\n\n{**\n  Executes a SQL statement with parameters.\n  @param ASQL a SQL statement with parameters defined with question marks.\n  @param AParams a collection of statement parameters.\n  @param ResultSet a supplied result set reference (just ignored).\n  @returns a number of updated rows.\n}\n\n{$IFDEF WITH_IPROVIDERWIDE}\nfunction TZAbstractRODataset.PSExecuteStatement(const ASQL: WideString; AParams: TParams;\n  ResultSet: Pointer = nil): Integer;\n{$ELSE}\nfunction TZAbstractRODataset.PSExecuteStatement(const ASQL: string;\n  AParams: TParams; ResultSet: Pointer): Integer;\n{$ENDIF}\nvar\n  I: Integer;\n  Statement: IZPreparedStatement;\n  ParamValue: TParam;\nbegin\n  if Assigned(FConnection) then\n  begin\n    if not FConnection.Connected then\n      FConnection.Connect;\n    Statement := FConnection.DbcConnection.PrepareStatement(ASQL);\n    if (AParams <> nil) and (AParams.Count > 0) then\n      for I := 0 to AParams.Count - 1 do\n      begin\n        ParamValue := AParams[I];\n        SetStatementParam(I+1, Statement, ParamValue);\n      end;\n    Result := Statement.ExecuteUpdatePrepared;\n  end\n  else\n    Result := 0;\nend;\n\n{$ENDIF}\n\nprocedure TZAbstractRODataset.CheckFieldCompatibility(Field: TField;FieldDef: TFieldDef);\nconst\n  {EH: hint all commented types are the fields the RowAccessor can't handle -> avoid stack killing moves in Get/SetFieldData()\n  this Error trapping is made for User-added fields like calulateds ....}\n  BaseFieldTypes: array[TFieldType] of TFieldType = (\n    //generic TFieldTypes of FPC and Delphi(since D7, of course):\n    ftUnknown, ftString, ftSmallint, ftInteger, ftWord, // 0..4\n    ftBoolean, ftFloat, ftCurrency, ftFloat{ftBCD}, ftDate,  ftTime, ftDateTime, // 5..11\n    ftBytes, ftBytes{ftVarBytes}, ftInteger{ftAutoInc}, ftBlob, ftMemo, ftBlob{ftGraphic}, ftMemo{ftFmtMemo}, // 12..18\n    ftBlob{ftParadoxOle}, ftBlob{ftDBaseOle}, ftBlob{ftTypedBinary}, ftUnknown{ftCursor}, ftString{ftFixedChar}, ftWideString, // 19..24\n    ftLargeint, ftUnknown{ftADT}, ftUnknown{ftArray}, ftUnknown{ftReference}, ftDataSet, ftBlob{ftOraBlob}, ftMemo{ftOraClob}, // 25..31\n    ftUnknown{ftVariant}, ftUnknown{ftInterface}, ftUnknown{ftIDispatch}, ftGuid, ftTimeStamp, ftFloat{ftFMTBcd} // 32..37\n{$IFDEF FPC} //addition types for FPC\n    , ftWideString{ftFixedWideChar}, ftWideMemo // 38..39\n{$ELSE !FPC}\n{$IF CompilerVersion >= 18} //additional Types since D2006 and D2007\n    , ftWideString{ftFixedWideChar}, ftWideMemo, ftDateTime{ftOraTimeStamp}, ftDateTime{ftOraInterval} // 38..41\n{$IF CompilerVersion >= 20} //additional Types since D2009\n    , ftLongWord, ftShortint, ftByte, ftExtended, ftUnknown{ftConnection}, ftUnknown{ftParams}, ftBlob{ftStream} //42..48\n{$IF CompilerVersion >= 21} //additional Types since D2010\n    , ftDateTime{ftTimeStampOffset}, ftUnknown{ftObject}, ftSingle //49..51\n{$IFEND CompilerVersion >= 21}\n{$IFEND CompilerVersion >= 20}\n{$IFEND CompilerVersion >= 18}\n{$ENDIF FPC}\n  );\n  CheckTypeSizes = [ftBytes, ftVarBytes, ftBCD, ftReference];\nbegin\n  with Field do\n  begin\n    if (BaseFieldTypes[DataType] <> BaseFieldTypes[FieldDef.DataType]) then\n      DatabaseErrorFmt(SFieldTypeMismatch, [DisplayName,\n        FieldTypeNames[DataType], FieldTypeNames[FieldDef.DataType]], Self);\n    if (DataType in CheckTypeSizes) and (Size <> FieldDef.Size) then\n        DatabaseErrorFmt(SFieldSizeMismatch, [DisplayName, Size,\n          FieldDef.Size], Self);\n  end;\nend;\n\n{**\n  Reset the calculated (includes fkLookup) fields\n  @param Buffer\n}\n\n{$IFDEF WITH_TRECORDBUFFER}\n\nprocedure TZAbstractRODataset.ClearCalcFields(Buffer: TRecordBuffer);\n{$ELSE}\n\nprocedure TZAbstractRODataset.ClearCalcFields(Buffer: PChar);\n{$ENDIF}\nvar\n  Index: Integer;\nbegin\n  RowAccessor.RowBuffer := PZRowBuffer(Buffer);\n  for Index := 1 to Fields.Count do\n    if (Fields[Index-1].FieldKind in [fkCalculated, fkLookup]) then\n      RowAccessor.SetNull(DefineFieldindex(FFieldsLookupTable,Fields[Index-1]));\nend;\n\n{=======================bangfauzan addition========================}\nfunction TZAbstractRODataset.GetSortType: TSortType;\nvar\n  AscCount, DescCount: Integer;\n  s: String;\nbegin\n  {pawelsel modification}\n  AscCount:=0;\n  DescCount:=0;\n  s:=StringReplace(FIndexFieldNames,';',',',[rfReplaceAll]);\n  while Pos(',',s)>0 do\n  begin\n    if Pos(' DESC',UpperCase(Copy(s,1,Pos(',',s))))>0 then\n      Inc(DescCount)\n    else\n      Inc(AscCount);\n    s:=Copy(s,Pos(',',s)+1,Length(s)-Pos(',',s));\n  end;\n  if Length(s)>0 then\n    if Pos(' DESC',UpperCase(s))>0 then\n      Inc(DescCount)\n    else\n      Inc(AscCount);\n  if (DescCount > 0) and (AscCount > 0) then\n     Result:=stIgnored\n  else if (DescCount > 0) then\n     Result:=stDescending\n  else\n     Result:=stAscending;\nend;\n\nprocedure TZAbstractRODataset.SetSortType(Value: TSortType);\nbegin\n  if FSortType <> Value then\n  begin\n    FSortType := Value;\n    if (FSortType <> stIgnored) then\n    begin {pawelsel modification}\n       FSortedFields:=StringReplace(FSortedFields,' Desc','',[rfReplaceAll,rfIgnoreCase]);\n       FSortedFields:=StringReplace(FSortedFields,' Asc','',[rfReplaceAll,rfIgnoreCase]);\n    end;\n    FIndexFieldNames:=GetIndexFieldNames;\n    if Active then\n       if (FSortedFields = '') then\n          Self.InternalRefresh\n      else\n          InternalSort;\n  end;\nend;\n\nfunction TZAbstractRODataset.GetIndexFieldNames : String;\nbegin\n  Result:=FSortedFields;\n  if Result <> '' then\n  begin {pawelsel modification}\n    if FSortType = stAscending then\n    begin\n       Result:=StringReplace(Result,';',' Asc;',[rfReplaceAll]);\n       Result:=StringReplace(Result,',',' Asc,',[rfReplaceAll]);\n       Result:=Result+' Asc';\n    end;\n    if FSortType = stDescending then\n    begin\n       Result:=StringReplace(Result,';',' Desc;',[rfReplaceAll]);\n       Result:=StringReplace(Result,',',' Desc,',[rfReplaceAll]);\n       Result:=Result+' Desc';\n    end;\n  end;\nend;\n\nprocedure TZAbstractRODataset.SetIndexFieldNames(Value: String);\nbegin\n  Value:=Trim(Value);\n  {pawelsel modification}\n  Value:=StringReplace(Value,'[','',[rfReplaceAll]);\n  Value:=StringReplace(Value,']','',[rfReplaceAll]);\n\n  if FIndexFieldNames <> Value then\n  begin\n     FIndexFieldNames := Value;\n     FSortType:=GetSortType;\n     if (FSortType <> stIgnored) then\n     begin {pawelsel modification}\n        Value:=StringReplace(Value,' Desc','',[rfReplaceAll,rfIgnoreCase]);\n        Value:=StringReplace(Value,' Asc','',[rfReplaceAll,rfIgnoreCase]);\n     end;\n     FSortedFields:=Value;\n  end;\n\n  {Perform sorting}\n  if Active then\n     if (FSortedFields = '') then\n        Self.InternalRefresh\n     else\n        InternalSort;\nend;\n\n{====================end of bangfauzan addition====================}\n\nend.\n\n\n\n"
  },
  {
    "path": "lib/zeosdbo/src/component/ZAbstractTable.pas",
    "content": "{*********************************************************}\n{                                                         }\n{                 Zeos Database Objects                   }\n{               Abstract Table component                  }\n{                                                         }\n{        Originally written by Sergey Seroukhov           }\n{                                                         }\n{*********************************************************}\n\n{@********************************************************}\n{    Copyright (c) 1999-2012 Zeos Development Group       }\n{                                                         }\n{ License Agreement:                                      }\n{                                                         }\n{ This library is distributed in the hope that it will be }\n{ useful, but WITHOUT ANY WARRANTY; without even the      }\n{ implied warranty of MERCHANTABILITY or FITNESS FOR      }\n{ A PARTICULAR PURPOSE.  See the GNU Lesser General       }\n{ Public License for more details.                        }\n{                                                         }\n{ The source code of the ZEOS Libraries and packages are  }\n{ distributed under the Library GNU General Public        }\n{ License (see the file COPYING / COPYING.ZEOS)           }\n{ with the following  modification:                       }\n{ As a special exception, the copyright holders of this   }\n{ library give you permission to link this library with   }\n{ independent modules to produce an executable,           }\n{ regardless of the license terms of these independent    }\n{ modules, and to copy and distribute the resulting       }\n{ executable under terms of your choice, provided that    }\n{ you also meet, for each linked independent module,      }\n{ the terms and conditions of the license of that module. }\n{ An independent module is a module which is not derived  }\n{ from or based on this library. If you modify this       }\n{ library, you may extend this exception to your version  }\n{ of the library, but you are not obligated to do so.     }\n{ If you do not wish to do so, delete this exception      }\n{ statement from your version.                            }\n{                                                         }\n{                                                         }\n{ The project web site is located on:                     }\n{   http://zeos.firmos.at  (FORUM)                        }\n{   http://sourceforge.net/p/zeoslib/tickets/ (BUGTRACKER)}\n{   svn://svn.code.sf.net/p/zeoslib/code-0/trunk (SVN)    }\n{                                                         }\n{   http://www.sourceforge.net/projects/zeoslib.          }\n{                                                         }\n{                                                         }\n{                                 Zeos Development Group. }\n{********************************************************@}\n\nunit ZAbstractTable;\n\ninterface\n\n{$I ZComponent.inc}\n\nuses\n  SysUtils, Classes, {$IFDEF MSEgui}mclasses,{$ENDIF}\n  ZAbstractDataset;\n\ntype\n\n  {**\n    Abstract dataset component which works with one specified table.\n  }\n  TZAbstractTable = class(TZAbstractDataset)\n  private\n    FTableName: string;\n\n  private\n    function GetExists: Boolean;\n    procedure SetTableName(const Value: string);\n\n  protected\n  {$IFDEF WITH_IPROVIDER}\n    function PSIsSQLBased: Boolean; override;\n    {$IFDEF  WITH_IPROVIDERWIDE}\n    function PSGetTableNameW: WideString; override;\n    {$ELSE}\n    function PSGetTableName: string; override;\n    {$ENDIF}\n    procedure PSSetCommandText(const ACommandText: string); override;\n  {$ENDIF}\n\n  protected\n    property Exists: Boolean read GetExists;\n    property TableName: string read FTableName write SetTableName;\n  end;\n\nimplementation\n\n\n{ TZAbstractTable }\n\n{**\n  Checks if a table with the corresponding name exists in the database.\n  @return <code>True</code> if the the table exists.\n}\nfunction TZAbstractTable.GetExists: Boolean;\nvar\n  TableList: TStringList;\nbegin\n  TableList := TStringList.Create;\n  try\n    CheckConnected;\n    Connection.GetTableNames(TableName, TableList);\n    TableList.CaseSensitive := False;\n    Result := (TableList.IndexOf(TableName) >= 0); // look for an exact match\n  finally\n    TableList.Free;\n  end;\nend;\n\n{**\n  Sets a new table name and generates a related SQL statement.\n  @param Value a new name of table.\n}\nprocedure TZAbstractTable.SetTableName(const Value: string);\nbegin\n  if FTableName <> Value then\n  begin\n    FTableName := Value;\n    if Value <> '' then\n      SQL.Text := Format('SELECT * FROM %s', [FTableName])\n    else SQL.Text := '';\n  end;\nend;\n\n{$IFDEF WITH_IPROVIDER}\n\n{**\n  Checks if dataset can execute SQL queries?\n  @returns <code>True</code> if the query can execute SQL.\n}\nfunction TZAbstractTable.PSIsSQLBased: Boolean;\nbegin\n  Result := False;\nend;\n\n{**\n  Gets the name of the table.\n  @returns the name of this table.\n}\n{$IFDEF WITH_IPROVIDERWIDE}\nfunction TZAbstractTable.PSGetTableNameW: WideString;\n{$ELSE}\nfunction TZAbstractTable.PSGetTableName: string;\n{$ENDIF}\nbegin\n  Result := TableName;\nend;\n\n{**\n  Assignes a new name for this table.\n  @param ACommandText a new name for this table.\n}\nprocedure TZAbstractTable.PSSetCommandText(const ACommandText: string);\nbegin\n  TableName := ACommandText;\nend;\n\n{$ENDIF}\n\nend.\n"
  },
  {
    "path": "lib/zeosdbo/src/component/ZComponent.inc",
    "content": "{@********************************************************}\n{    Copyright (c) 1999-2012 Zeos Development Group       }\n{                                                         }\n{ License Agreement:                                      }\n{                                                         }\n{ This library is distributed in the hope that it will be }\n{ useful, but WITHOUT ANY WARRANTY; without even the      }\n{ implied warranty of MERCHANTABILITY or FITNESS FOR      }\n{ A PARTICULAR PURPOSE.  See the GNU Lesser General       }\n{ Public License for more details.                        }\n{                                                         }\n{ The source code of the ZEOS Libraries and packages are  }\n{ distributed under the Library GNU General Public        }\n{ License (see the file COPYING / COPYING.ZEOS)           }\n{ with the following  modification:                       }\n{ As a special exception, the copyright holders of this   }\n{ library give you permission to link this library with   }\n{ independent modules to produce an executable,           }\n{ regardless of the license terms of these independent    }\n{ modules, and to copy and distribute the resulting       }\n{ executable under terms of your choice, provided that    }\n{ you also meet, for each linked independent module,      }\n{ the terms and conditions of the license of that module. }\n{ An independent module is a module which is not derived  }\n{ from or based on this library. If you modify this       }\n{ library, you may extend this exception to your version  }\n{ of the library, but you are not obligated to do so.     }\n{ If you do not wish to do so, delete this exception      }\n{ statement from your version.                            }\n{                                                         }\n{                                                         }\n{ The project web site is located on:                     }\n{   http://zeos.firmos.at  (FORUM)                        }\n{   http://sourceforge.net/p/zeoslib/tickets/ (BUGTRACKER)}\n{   svn://svn.code.sf.net/p/zeoslib/code-0/trunk (SVN)    }\n{                                                         }\n{   http://www.sourceforge.net/projects/zeoslib.          }\n{                                                         }\n{                                                         }\n{                                 Zeos Development Group. }\n{********************************************************@}\n\n{$IFDEF LINUX}\n  {$DEFINE UNIX}\n{$ENDIF}\n\n{$IFNDEF UNIX}\n{$I ..\\Zeos.inc}\n{$ELSE}\n{$I ../Zeos.inc}\n{$ENDIF}\n"
  },
  {
    "path": "lib/zeosdbo/src/component/ZComponentReg.lrs",
    "content": "LazarusResources.Add('TZConnection','XPM',[\n  '/* XPM */'#13#10'static char * TZConnection.xpm_xpm[] = {'#13#10'\"24 24 97 2'\n  +'\",'#13#10'\"  '#9'c #23236E\",'#13#10'\". '#9'c #000058\",'#13#10'\"+ '#9'c None'\n  +'\",'#13#10'\"@ '#9'c #C8C8DA\",'#13#10'\"# '#9'c #282B6F\",'#13#10'\"$ '#9'c #ACD'\n  +'5AC\",'#13#10'\"% '#9'c #89C489\",'#13#10'\"& '#9'c #65B265\",'#13#10'\"* '#9'c #'\n  +'42A042\",'#13#10'\"= '#9'c #229022\",'#13#10'\"- '#9'c #349934\",'#13#10'\"; '#9\n  +'c #58AB58\",'#13#10'\"> '#9'c #7CBD7C\",'#13#10'\", '#9'c #A0CEA0\",'#13#10'\"'' '\n  +#9'c #C4E0C4\",'#13#10'\") '#9'c #FCFDFC\",'#13#10'\"! '#9'c #595D90\",'#13#10'\"~'\n  +' '#9'c #004627\",'#13#10'\"{ '#9'c #007F00\",'#13#10'\"] '#9'c #259225\",'#13#10\n  +'\"^ '#9'c #B9DCB9\",'#13#10'\"/ '#9'c #F4F4F7\",'#13#10'\"( '#9'c #060B58\",'#13\n  +#10'\"_ '#9'c #000355\",'#13#10'\": '#9'c #00700A\",'#13#10'\"< '#9'c #148C14\",'\n  +#13#10'\"[ '#9'c #ACACC8\",'#13#10'\"} '#9'c #001F41\",'#13#10'\"| '#9'c #008300\"'\n  +','#13#10'\"1 '#9'c #00A500\",'#13#10'\"2 '#9'c #4B4B89\",'#13#10'\"3 '#9'c #003B'\n  +'1F\",'#13#10'\"4 '#9'c #006A00\",'#13#10'\"5 '#9'c #007300\",'#13#10'\"6 '#9'c #0'\n  +'07900\",'#13#10'\"7 '#9'c #007D00\",'#13#10'\"8 '#9'c #008000\",'#13#10'\"9 '#9'c'\n  +' #008100\",'#13#10'\"0 '#9'c #008500\",'#13#10'\"a '#9'c #008B00\",'#13#10'\"b '#9\n  +'c #009200\",'#13#10'\"c '#9'c #009C00\",'#13#10'\"d '#9'c #00AF00\",'#13#10'\"e '\n  +#9'c #00B800\",'#13#10'\"f '#9'c #E8E8EF\",'#13#10'\"g '#9'c #0A0A5E\",'#13#10'\"h'\n  +' '#9'c #040758\",'#13#10'\"i '#9'c #005705\",'#13#10'\"j '#9'c #006400\",'#13#10\n  +'\"k '#9'c #006B00\",'#13#10'\"l '#9'c #007200\",'#13#10'\"m '#9'c #008700\",'#13\n  +#10'\"n '#9'c #008E00\",'#13#10'\"o '#9'c #009500\",'#13#10'\"p '#9'c #00A300\",'\n  +#13#10'\"q '#9'c #00AA00\",'#13#10'\"r '#9'c #00B100\",'#13#10'\"s '#9'c #9797BA\"'\n  +','#13#10'\"t '#9'c #20325A\",'#13#10'\"u '#9'c #005D00\",'#13#10'\"v '#9'c #3838'\n  +'7C\",'#13#10'\"w '#9'c #4A735D\",'#13#10'\"x '#9'c #010158\",'#13#10'\"y '#9'c #0'\n  +'00255\",'#13#10'\"z '#9'c #B8B8EA\",'#13#10'\"A '#9'c #5F945F\",'#13#10'\"B '#9'c'\n  +' #00A711\",'#13#10'\"C '#9'c #1717BE\",'#13#10'\"D '#9'c #00B001\",'#13#10'\"E '#9\n  +'c #003385\",'#13#10'\"F '#9'c #0000B8\",'#13#10'\"G '#9'c #006054\",'#13#10'\"H '\n  +#9'c #DFDFF5\",'#13#10'\"I '#9'c #008726\",'#13#10'\"J '#9'c #0003B4\",'#13#10'\"K'\n  +' '#9'c #009B09\",'#13#10'\"L '#9'c #00189E\",'#13#10'\"M '#9'c #003B75\",'#13#10\n  +'\"N '#9'c #6A9C6A\",'#13#10'\"O '#9'c #033488\",'#13#10'\"P '#9'c #DEE9DE\",'#13\n  +#10'\"Q '#9'c #2A772A\",'#13#10'\"R '#9'c #0CB40C\",'#13#10'\"S '#9'c #8ECF9E\",'\n  +#13#10'\"T '#9'c #FDFEFD\",'#13#10'\"U '#9'c #B3D1B3\",'#13#10'\"V '#9'c #84B884\"'\n  +','#13#10'\"W '#9'c #61A861\",'#13#10'\"X '#9'c #3D993D\",'#13#10'\"Y '#9'c #1A8C'\n  +'1A\",'#13#10'\"Z '#9'c #0D930D\",'#13#10'\"` '#9'c #30A830\",'#13#10'\" .'#9'c #5'\n  +'4BD54\",'#13#10'\"..'#9'c #78CD78\",'#13#10'\"+.'#9'c #9CDE9C\",'#13#10'\"@.'#9'c'\n  +' #EDF9ED\",'#13#10'\"#.'#9'c #F9FCF9\",'#13#10'\"  . . . . + + + + + + + + + + '\n  +'+ + + + + + + + + \",'#13#10'\"+ + @ . # $ % & * = - ; > , '' ) + + + + + + +'\n  +' + \",'#13#10'\"+ + ! . ~ { { { { { { { { { { ] ^ + + + + + + + \",'#13#10'\"+ '\n  +'/ ( _ : { { { { { { { { { { { < + + + + + + + \",'#13#10'\"+ [ . } { { { { { '\n  +'{ { { { { { | 1 + + + + + + + \",'#13#10'\"+ 2 . 3 4 5 6 7 { 8 9 0 a b c d e '\n  +'+ + + + + + + \",'#13#10'\"f g h i j k l 6 8 m n o c p q r e + + + + + + + \",'\n  +#13#10'\"s . t u j k l 6 8 m n o c p q r e + + + + + + + \",'#13#10'\"v . w u j'\n  +' k l 6 8 m n o c p q r e + + + + + + + \",'#13#10'\". . x y y k l 6 8 m n o c'\n  +' p q r e z + + + + + + \",'#13#10'\"+ + A u j k l 6 8 m n o c p q r B C + + +'\n  +' + + + \",'#13#10'\"+ + A u j k l 6 8 m n o c p q D E F + + + + + + \",'#13#10\n  +'\"+ + A u j k l 6 8 m n o c p q G F F H H H H H + \",'#13#10'\"+ + A u j k l 6'\n  +' 8 m n o c p I J F F F F F F F + \",'#13#10'\"+ + A u j k l 6 8 m n o c K L F'\n  +' F F F F F F F + \",'#13#10'\"+ + A u j k l 6 8 m n o c M F F F F F F F F F +'\n  +' \",'#13#10'\"+ + A u j k l 6 8 m n o c M F F F F F F F F F + \",'#13#10'\"+ + '\n  +'A u j k l 6 8 m n o c K L F F F F F F F F + \",'#13#10'\"+ + A u j k l 6 8 m '\n  +'n o c p I J F F F F F F F + \",'#13#10'\"+ + A u j k l 6 8 m n o c p q G F F '\n  +'H H H H H + \",'#13#10'\"+ + N u j k l 6 8 m n o c p q D O F + + + + + + \",'\n  +#13#10'\"+ + P Q j k l 6 8 m n o c p q R S C + + + + + + \",'#13#10'\"+ + + T U'\n  +' V W X Y m Z `  ...+.@.+ z + + + + + + \",'#13#10'\"+ + + + + + + + + #.+ + +'\n  +' + + + + + + + + + + + \"};'#13#10\n]);\nLazarusResources.Add('TZReadOnlyQuery','XPM',[\n  '/* XPM */'#13#10'static char * TZReadOnlyQuery.xpm_xpm[] = {'#13#10'\"24 24 1'\n  +'55 2\",'#13#10'\"  '#9'c #23236E\",'#13#10'\". '#9'c #000058\",'#13#10'\"+ '#9'c '\n  +'None\",'#13#10'\"@ '#9'c #FBC5C5\",'#13#10'\"# '#9'c #F55050\",'#13#10'\"$ '#9'c '\n  +'#F23535\",'#13#10'\"% '#9'c #C8C8DA\",'#13#10'\"& '#9'c #2F2F76\",'#13#10'\"* '#9\n  +'c #F88787\",'#13#10'\"= '#9'c #F10202\",'#13#10'\"- '#9'c #F10000\",'#13#10'\"; '\n  +#9'c #F1CCCC\",'#13#10'\"> '#9'c #22167D\",'#13#10'\", '#9'c #342690\",'#13#10'\"'\n  +''' '#9'c #6149C1\",'#13#10'\") '#9'c #634CC4\",'#13#10'\"! '#9'c #6551C6\",'#13\n  +#10'\"~ '#9'c #6755C8\",'#13#10'\"{ '#9'c #6A59CA\",'#13#10'\"] '#9'c #6C5ECC\",'\n  +#13#10'\"^ '#9'c #6E62CF\",'#13#10'\"/ '#9'c #7166D1\",'#13#10'\"( '#9'c #736AD4\"'\n  +','#13#10'\"_ '#9'c #9154A5\",'#13#10'\": '#9'c #F00001\",'#13#10'\"< '#9'c #F001'\n  +'01\",'#13#10'\"[ '#9'c #A172B5\",'#13#10'\"} '#9'c #F4F4F7\",'#13#10'\"| '#9'c #0'\n  +'6045E\",'#13#10'\"1 '#9'c #02015A\",'#13#10'\"2 '#9'c #533DB2\",'#13#10'\"3 '#9'c'\n  +' #634DC3\",'#13#10'\"4 '#9'c #6651C5\",'#13#10'\"5 '#9'c #6755C7\",'#13#10'\"6 '#9\n  +'c #6A59CB\",'#13#10'\"7 '#9'c #6C5DCD\",'#13#10'\"8 '#9'c #6F62CF\",'#13#10'\"9 '\n  +#9'c #7165D2\",'#13#10'\"0 '#9'c #736AD3\",'#13#10'\"a '#9'c #CA2243\",'#13#10'\"b'\n  +' '#9'c #D02E4A\",'#13#10'\"c '#9'c #ACACC8\",'#13#10'\"d '#9'c #171071\",'#13#10\n  +'\"e '#9'c #5E45BE\",'#13#10'\"f '#9'c #6049C0\",'#13#10'\"g '#9'c #634DC4\",'#13\n  +#10'\"h '#9'c #6551C5\",'#13#10'\"i '#9'c #6A5ACA\",'#13#10'\"j '#9'c #6C5DCC\",'\n  +#13#10'\"k '#9'c #7165D1\",'#13#10'\"l '#9'c #E52832\",'#13#10'\"m '#9'c #F1EBEB\"'\n  +','#13#10'\"n '#9'c #E72C34\",'#13#10'\"o '#9'c #4B4B89\",'#13#10'\"p '#9'c #A3A3'\n  +'C2\",'#13#10'\"q '#9'c #B3B3B3\",'#13#10'\"r '#9'c #EB2F2F\",'#13#10'\"s '#9'c #E'\n  +'8E8EF\",'#13#10'\"t '#9'c #0A0A5E\",'#13#10'\"u '#9'c #09095C\",'#13#10'\"v '#9'c'\n  +' #EFEFF4\",'#13#10'\"w '#9'c #FEFEFE\",'#13#10'\"x '#9'c #F54F4F\",'#13#10'\"y '#9\n  +'c #DD3838\",'#13#10'\"z '#9'c #9797BA\",'#13#10'\"A '#9'c #3D3D77\",'#13#10'\"B '\n  +#9'c #B4B4B4\",'#13#10'\"C '#9'c #C18B8B\",'#13#10'\"D '#9'c #C18A8A\",'#13#10'\"E'\n  +' '#9'c #38387C\",'#13#10'\"F '#9'c #8B8B9F\",'#13#10'\"G '#9'c #F78686\",'#13#10\n  +'\"H '#9'c #020259\",'#13#10'\"I '#9'c #06065B\",'#13#10'\"J '#9'c #FDFDFD\",'#13\n  +#10'\"K '#9'c #9494B8\",'#13#10'\"L '#9'c #181864\",'#13#10'\"M '#9'c #1A1A69\",'\n  +#13#10'\"N '#9'c #616197\",'#13#10'\"O '#9'c #E7E7EF\",'#13#10'\"P '#9'c #D7D7E4\"'\n  +','#13#10'\"Q '#9'c #4E4E8B\",'#13#10'\"R '#9'c #101060\",'#13#10'\"S '#9'c #1010'\n  +'62\",'#13#10'\"T '#9'c #3F3F81\",'#13#10'\"U '#9'c #C1C1D6\",'#13#10'\"V '#9'c #2'\n  +'72771\",'#13#10'\"W '#9'c #C9C9DB\",'#13#10'\"X '#9'c #3A3A75\",'#13#10'\"Y '#9'c'\n  +' #6F6F90\",'#13#10'\"Z '#9'c #323271\",'#13#10'\"` '#9'c #2A2A6D\",'#13#10'\" .'#9\n  +'c #9D9DA8\",'#13#10'\"..'#9'c #07075B\",'#13#10'\"+.'#9'c #5B5B86\",'#13#10'\"@.'\n  +#9'c #62628A\",'#13#10'\"#.'#9'c #131361\",'#13#10'\"$.'#9'c #88889D\",'#13#10'\"%'\n  +'.'#9'c #1B1B65\",'#13#10'\"&.'#9'c #C0C0D5\",'#13#10'\"*.'#9'c #4F4F80\",'#13#10\n  +'\"=.'#9'c #E3E3EC\",'#13#10'\"-.'#9'c #ECECF2\",'#13#10'\";.'#9'c #9898BB\",'#13\n  +#10'\">.'#9'c #A5A5C4\",'#13#10'\",.'#9'c #68689C\",'#13#10'\"''.'#9'c #A9A9C6\",'\n  +#13#10'\").'#9'c #D1D1E0\",'#13#10'\"!.'#9'c #404081\",'#13#10'\"~.'#9'c #424283\"'\n  +','#13#10'\"{.'#9'c #34347A\",'#13#10'\"].'#9'c #8686AF\",'#13#10'\"^.'#9'c #F8F8'\n  +'FA\",'#13#10'\"/.'#9'c #3A3A7D\",'#13#10'\"(.'#9'c #F0F0F5\",'#13#10'\"_.'#9'c #1'\n  +'71767\",'#13#10'\":.'#9'c #131364\",'#13#10'\"<.'#9'c #FCFCFD\",'#13#10'\"[.'#9'c'\n  +' #85859B\",'#13#10'\"}.'#9'c #4B4B7E\",'#13#10'\"|.'#9'c #151562\",'#13#10'\"1.'#9\n  +'c #3E3E77\",'#13#10'\"2.'#9'c #28286C\",'#13#10'\"3.'#9'c #A7A7AD\",'#13#10'\"4.'\n  +#9'c #B2B2B3\",'#13#10'\"5.'#9'c #0F0F5F\",'#13#10'\"6.'#9'c #0E0E5F\",'#13#10'\"7'\n  +'.'#9'c #F7F7F9\",'#13#10'\"8.'#9'c #0F0F61\",'#13#10'\"9.'#9'c #69699C\",'#13#10\n  +'\"0.'#9'c #ADADC9\",'#13#10'\"a.'#9'c #EEEEF3\",'#13#10'\"b.'#9'c #B6B6CF\",'#13\n  +#10'\"c.'#9'c #B7B7CF\",'#13#10'\"d.'#9'c #39397D\",'#13#10'\"e.'#9'c #9292B7\",'\n  +#13#10'\"f.'#9'c #5F5F96\",'#13#10'\"g.'#9'c #434383\",'#13#10'\"h.'#9'c #E1E1EB\"'\n  +','#13#10'\"i.'#9'c #0B0B5F\",'#13#10'\"j.'#9'c #121263\",'#13#10'\"k.'#9'c #8080'\n  +'AB\",'#13#10'\"l.'#9'c #24246F\",'#13#10'\"m.'#9'c #010158\",'#13#10'\"n.'#9'c #D'\n  +'3D3E2\",'#13#10'\"o.'#9'c #191968\",'#13#10'\"p.'#9'c #ABABC7\",'#13#10'\"q.'#9'c'\n  +' #BCBCD3\",'#13#10'\"r.'#9'c #252570\",'#13#10'\"s.'#9'c #5C5C94\",'#13#10'\"t.'#9\n  +'c #E5E5ED\",'#13#10'\"u.'#9'c #D6D6E4\",'#13#10'\"v.'#9'c #181867\",'#13#10'\"w.'\n  +#9'c #333379\",'#13#10'\"x.'#9'c #9C9CBE\",'#13#10'\"  . . . . + + + + + + + + +'\n  +' + + @ # $ $ # @ + + \",'#13#10'\"+ + % . & + + + + + + + + + + * = - ; ; - ='\n  +' * + \",'#13#10'\"+ + > . , '' ) ! ~ { ] ^ / ( _ : - - ; ; - - < [ \",'#13#10\n  +'\"+ } | 1 2 '' 3 4 5 6 7 8 9 0 a - - - ; ; - - - b \",'#13#10'\"+ c . d e f g '\n  +'h ~ i j ^ k 0 l ; ; ; m m ; ; ; n \",'#13#10'\"+ o . p + + + + + + + q + + $ '\n  +'; ; ; m m ; ; ; r \",'#13#10'\"s t u v + + + + + + + q w w x - - - ; ; - - - '\n  +'y \",'#13#10'\"z . A q q q q q q q q q B B C < - - ; ; - - < D \",'#13#10'\"E .'\n  +' F + + + + + + + + q + + + G = - ; ; - = * q \",'#13#10'\". . H I I + + + + +'\n  +' + q w w w J @ # $ $ # @ + q \",'#13#10'\"+ + q q q q q q q q q q B B B q q q'\n  +' q q q q q q \",'#13#10'\"+ + q + + + + + + + + q + + + + + + + + + + + q \",'\n  ,#13#10'\"+ + q w w w w w w w + q w w w w w w w w w w w q \",'#13#10'\"+ + q B B'\n  +' B B B B B B q B B B B B B B B B B B q \",'#13#10'\"+ + q + + + + + + + + q +'\n  +' + + + + + + + + + + q \",'#13#10'\"+ K L I M N O + + P Q R S T U + + . V w w'\n  +' w w q \",'#13#10'\"W . X Y Z . ` q  ...u +.@.#.. $.B . %.B B B B q \",'#13#10\n  +'\"&.. *.=.-.;.>.+ ,.. ''.q + ).. !.+ . V + + + + q \",'#13#10'\"J ~.. . {.].^.'\n  +'+ /.. (.q + + _.:.+ . V w w w w q \",'#13#10'\"+ <.[.}.|.. 1.q 2.. 3.q q 4.5.'\n  +'6.q . %.q q q q q \",'#13#10'\";.E O + 7.t 8.+ 9.. 0.a.9.b.. o + . V + + + + '\n  +'+ \",'#13#10'\"c.. d.e.f.. g.+ h.i.j.k.l.. m.n.+ . o.p.p.p.q.+ \",'#13#10'\"+ ;'\n  +'.r.I o.s.t.+ + u.o v.:.g.t ~.+ . . . . . w.+ \",'#13#10'\"+ + + + + + + + + +'\n  +' + + + + s x.+ + + + + + + + \"};'#13#10\n]);\nLazarusResources.Add('TZConnectionGroup','XPM',[\n  '/* XPM */'#13#10'static char * TZConnectionGroup.xpm_xpm[] = {'#13#10'\"24 24'\n  +' 100 2\",'#13#10'\"  '#9'c #23236E\",'#13#10'\". '#9'c #000058\",'#13#10'\"+ '#9\n  +'c None\",'#13#10'\"@ '#9'c #F8FAF8\",'#13#10'\"# '#9'c #95CA95\",'#13#10'\"$ '#9\n  +'c #5FAF5F\",'#13#10'\"% '#9'c #2F972F\",'#13#10'\"& '#9'c #0B850B\",'#13#10'\"* '\n  +#9'c #000000\",'#13#10'\"= '#9'c #080808\",'#13#10'\"- '#9'c #2F2F2F\",'#13#10'\";'\n  +' '#9'c #A5A5A5\",'#13#10'\"> '#9'c #C8C8DA\",'#13#10'\", '#9'c #2F2F76\",'#13#10\n  +'\"'' '#9'c #44A144\",'#13#10'\") '#9'c #007F00\",'#13#10'\"! '#9'c #ADADAD\",'#13\n  +#10'\"~ '#9'c #616197\",'#13#10'\"{ '#9'c #8D8DB4\",'#13#10'\"] '#9'c #017701\",'\n  +#13#10'\"^ '#9'c #018901\",'#13#10'\"/ '#9'c #FDFDFD\",'#13#10'\"( '#9'c #E9E9E9\"'\n  +','#13#10'\"_ '#9'c #797979\",'#13#10'\": '#9'c #414141\",'#13#10'\"< '#9'c #F4F4'\n  +'F7\",'#13#10'\"[ '#9'c #111163\",'#13#10'\"} '#9'c #07075C\",'#13#10'\"| '#9'c #E'\n  +'2E2EC\",'#13#10'\"1 '#9'c #005C00\",'#13#10'\"2 '#9'c #007200\",'#13#10'\"3 '#9'c'\n  +' #007B00\",'#13#10'\"4 '#9'c #007E00\",'#13#10'\"5 '#9'c #008000\",'#13#10'\"6 '#9\n  +'c #008600\",'#13#10'\"7 '#9'c #009000\",'#13#10'\"8 '#9'c #00AA00\",'#13#10'\"9 '\n  +#9'c #F6F6F6\",'#13#10'\"0 '#9'c #171717\",'#13#10'\"a '#9'c #ACACC8\",'#13#10'\"b'\n  +' '#9'c #424283\",'#13#10'\"c '#9'c #005A00\",'#13#10'\"d '#9'c #006400\",'#13#10\n  +'\"e '#9'c #006F00\",'#13#10'\"f '#9'c #007900\",'#13#10'\"g '#9'c #008300\",'#13\n  +#10'\"h '#9'c #008E00\",'#13#10'\"i '#9'c #009800\",'#13#10'\"j '#9'c #00A200\",'\n  +#13#10'\"k '#9'c #00AD00\",'#13#10'\"l '#9'c #070707\",'#13#10'\"m '#9'c #4B4B89\"'\n  +','#13#10'\"n '#9'c #A3A3C2\",'#13#10'\"o '#9'c #010101\",'#13#10'\"p '#9'c #E8E8'\n  +'EF\",'#13#10'\"q '#9'c #0A0A5E\",'#13#10'\"r '#9'c #0D0D60\",'#13#10'\"s '#9'c #E'\n  +'FEFF4\",'#13#10'\"t '#9'c #9797BA\",'#13#10'\"u '#9'c #575790\",'#13#10'\"v '#9'c'\n  +' #090909\",'#13#10'\"w '#9'c #38387C\",'#13#10'\"x '#9'c #C7C7DA\",'#13#10'\"y '#9\n  +'c #212121\",'#13#10'\"z '#9'c #DFDFDF\",'#13#10'\"A '#9'c #030359\",'#13#10'\"B '\n  +#9'c #06065B\",'#13#10'\"C '#9'c #565656\",'#13#10'\"D '#9'c #969696\",'#13#10'\"E'\n  +' '#9'c #146614\",'#13#10'\"F '#9'c #14B314\",'#13#10'\"G '#9'c #CCCCCC\",'#13#10\n  +'\"H '#9'c #060606\",'#13#10'\"I '#9'c #0B0B0B\",'#13#10'\"J '#9'c #9D9D9D\",'#13\n  +#10'\"K '#9'c #AECBAE\",'#13#10'\"L '#9'c #1D751D\",'#13#10'\"M '#9'c #1DAC1D\",'\n  +#13#10'\"N '#9'c #B3E6B3\",'#13#10'\"O '#9'c #B8B8B8\",'#13#10'\"P '#9'c #1A1A1A\"'\n  +','#13#10'\"Q '#9'c #E7F0E7\",'#13#10'\"R '#9'c #B7D8B7\",'#13#10'\"S '#9'c #93CA'\n  +'93\",'#13#10'\"T '#9'c #B7DFB7\",'#13#10'\"U '#9'c #E7F5E7\",'#13#10'\"V '#9'c #A'\n  +'4A4A4\",'#13#10'\"W '#9'c #161616\",'#13#10'\"X '#9'c #B6B6B6\",'#13#10'\"Y '#9'c'\n  +' #404040\",'#13#10'\"Z '#9'c #949494\",'#13#10'\"` '#9'c #E0E0E0\",'#13#10'\" .'#9\n  +'c #F7F7F7\",'#13#10'\"..'#9'c #FEFEFE\",'#13#10'\"+.'#9'c #040404\",'#13#10'\"@.'\n  +#9'c #6F6F6F\",'#13#10'\"#.'#9'c #323232\",'#13#10'\"$.'#9'c #B3CEB3\",'#13#10'\"%'\n  +'.'#9'c #A0A0A0\",'#13#10'\"&.'#9'c #2D2D2D\",'#13#10'\"  . . . . + + + @ # $ % '\n  +'& % $ # @ * = - ; + + + \",'#13#10'\"+ + > . , + + + '' ) ) ) ) ) ) ) '' * * '\n  +'* * ! + + \",'#13#10'\"+ + ~ . { + + + ] ) ) ) ) ) ) ) ^ / ( _ * : + + \",'#13\n  +#10'\"+ < [ } | + + + 1 2 3 4 ) 5 6 7 8 + + 9 * 0 + + \",'#13#10'\"+ a . b + + '\n  +'+ + c d e f g h i j k + + + * l + + \",'#13#10'\"+ m . n + + + + c d e f g h '\n  +'i j k + + + * o + + \",'#13#10'\"p q r s + + + + c d e f g h i j k + + + o * '\n  +'+ + \",'#13#10'\"t . u + + + + + c d e f g h i j k + + + v * 9 + \",'#13#10'\"w'\n  +' . x + + + + + c d e f g h i j k + + + y * z + \",'#13#10'\". . A B B + + + c'\n  +' d e f g h i j k + + + C * D + \",'#13#10'\"+ + + + + + + + E d e f g h i j F'\n  +' + + + G H I J \",'#13#10'\"@ # $ % & % $ # K L e f g h i M N + + + + O P * \"'\n  +','#13#10'\"'' ) ) ) ) ) ) ) '' + Q R S T U + + + + + + V W * \",'#13#10'\"] ) '\n  +') ) ) ) ) ) ^ + + + + + + + + + + + X o I J \",'#13#10'\"1 2 3 4 ) 5 6 7 8 + '\n  +'+ + + + + + + + + + Y * Z + \",'#13#10'\"c d e f g h i j k + + + + + + + + + '\n  +'+ + l * ` + \",'#13#10'\"c d e f g h i j k + + + + + + + + + + + * *  .+ \",'\n  +#13#10'\"c d e f g h i j k + + + + + + + + + + + * * + + \",'#13#10'\"c d e f g'\n  +' h i j k + + + + + + + + + + + * * + + \",'#13#10'\"c d e f g h i j k + + + +'\n  +' + + + + + + ..* * + + \",'#13#10'\"c d e f g h i j k + + + + + + + + + + ( *'\n  +' +.+ + \",'#13#10'\"E d e f g h i j F + + + + + + + + ..( @.* #.+ + \",'#13#10\n  +'\"$.L e f g h i M N + + + + + + + + * * * * %.+ + \",'#13#10'\"+ + Q R S T U +'\n  +' + + + + + + + + + * l &.J + + + \"};'#13#10\n]);\nLazarusResources.Add('TZPgEventAlerter','XPM',[\n  '/* XPM */'#13#10'static char * TZPgEventAlerter.xpm_xpm[] = {'#13#10'\"24 24 '\n  +'259 2\",'#13#10'\"  '#9'c #23236E\",'#13#10'\". '#9'c #000058\",'#13#10'\"+ '#9'c'\n  +' None\",'#13#10'\"@ '#9'c #B0B0B0\",'#13#10'\"# '#9'c #000000\",'#13#10'\"$ '#9'c'\n  +' #D4D4D4\",'#13#10'\"% '#9'c #C8C8DA\",'#13#10'\"& '#9'c #2F2F76\",'#13#10'\"* '#9\n  +'c #EBCF7C\",'#13#10'\"= '#9'c #616197\",'#13#10'\"- '#9'c #8D8DB4\",'#13#10'\"; '\n  +#9'c #584E1E\",'#13#10'\"> '#9'c #F2DB88\",'#13#10'\", '#9'c #F6EAB4\",'#13#10'\"'\n  +''' '#9'c #C4A94C\",'#13#10'\") '#9'c #403816\",'#13#10'\"! '#9'c #F4F4F7\",'#13\n  +#10'\"~ '#9'c #101062\",'#13#10'\"{ '#9'c #06065C\",'#13#10'\"] '#9'c #DADAE4\",'\n  +#13#10'\"^ '#9'c #FDFDFD\",'#13#10'\"/ '#9'c #F7F7F7\",'#13#10'\"( '#9'c #EFEFEF\"'\n  +','#13#10'\"_ '#9'c #F3F3F3\",'#13#10'\": '#9'c #DFDFDF\",'#13#10'\"< '#9'c #D5D5'\n  +'D5\",'#13#10'\"[ '#9'c #C6B165\",'#13#10'\"} '#9'c #FAF3CF\",'#13#10'\"| '#9'c #F'\n  +'CF2BE\",'#13#10'\"1 '#9'c #F4E18F\",'#13#10'\"2 '#9'c #BD9D37\",'#13#10'\"3 '#9'c'\n  +' #E9E9E9\",'#13#10'\"4 '#9'c #6D6D8A\",'#13#10'\"5 '#9'c #212163\",'#13#10'\"6 '#9\n  +'c #868687\",'#13#10'\"7 '#9'c #929292\",'#13#10'\"8 '#9'c #A6A6A6\",'#13#10'\"9 '\n  +#9'c #9C9C9C\",'#13#10'\"0 '#9'c #878888\",'#13#10'\"a '#9'c #7E7F80\",'#13#10'\"b'\n  +' '#9'c #7E7F7F\",'#13#10'\"c '#9'c #838383\",'#13#10'\"d '#9'c #828486\",'#13#10\n  +'\"e '#9'c #6C6F71\",'#13#10'\"f '#9'c #F7E6A6\",'#13#10'\"g '#9'c #FEFAE7\",'#13\n  +#10'\"h '#9'c #FBEB9C\",'#13#10'\"i '#9'c #C5AA4A\",'#13#10'\"j '#9'c #594E1F\",'\n  +#13#10'\"k '#9'c #989898\",'#13#10'\"l '#9'c #252869\",'#13#10'\"m '#9'c #4D6190\"'\n  +','#13#10'\"n '#9'c #7E9BB2\",'#13#10'\"o '#9'c #899EB0\",'#13#10'\"p '#9'c #A3A9'\n  +'AD\",'#13#10'\"q '#9'c #8C98A3\",'#13#10'\"r '#9'c #849EB4\",'#13#10'\"s '#9'c #7'\n  +'495B0\",'#13#10'\"t '#9'c #7D9BB3\",'#13#10'\"u '#9'c #A4B8C7\",'#13#10'\"v '#9'c'\n  +' #B7C8D6\",'#13#10'\"w '#9'c #C1A342\",'#13#10'\"x '#9'c #FAF2C4\",'#13#10'\"y '#9\n  +'c #FEF8D3\",'#13#10'\"z '#9'c #FFFADA\",'#13#10'\"A '#9'c #FDF1A8\",'#13#10'\"B '\n  +#9'c #EED060\",'#13#10'\"C '#9'c #AF820E\",'#13#10'\"D '#9'c #707D8F\",'#13#10'\"E'\n  +' '#9'c #03055A\",'#13#10'\"F '#9'c #02055A\",'#13#10'\"G '#9'c #2D5E8B\",'#13#10\n  +'\"H '#9'c #31658F\",'#13#10'\"I '#9'c #5580A3\",'#13#10'\"J '#9'c #92AEC4\",'#13\n  +#10'\"K '#9'c #527EA1\",'#13#10'\"L '#9'c #356892\",'#13#10'\"M '#9'c #334553\",'\n  +#13#10'\"N '#9'c #9D9153\",'#13#10'\"O '#9'c #FAE98D\",'#13#10'\"P '#9'c #FFF4B3\"'\n  +','#13#10'\"Q '#9'c #FFF5BC\",'#13#10'\"R '#9'c #FFF092\",'#13#10'\"S '#9'c #FDEB'\n  +'7A\",'#13#10'\"T '#9'c #F4D750\",'#13#10'\"U '#9'c #D8A717\",'#13#10'\"V '#9'c #7'\n  +'97979\",'#13#10'\"W '#9'c #485A8D\",'#13#10'\"X '#9'c #11226B\",'#13#10'\"Y '#9'c'\n  +' #326690\",'#13#10'\"Z '#9'c #86A4BD\",'#13#10'\"` '#9'c #698FAD\",'#13#10'\" .'#9\n  +'c #295477\",'#13#10'\"..'#9'c #221E0C\",'#13#10'\"+.'#9'c #F0D262\",'#13#10'\"@.'\n  +#9'c #F8E379\",'#13#10'\"#.'#9'c #FAF0AC\",'#13#10'\"$.'#9'c #FAE77C\",'#13#10'\"%'\n  +'.'#9'c #F9E161\",'#13#10'\"&.'#9'c #F1D145\",'#13#10'\"*.'#9'c #E6BE28\",'#13#10\n  +'\"=.'#9'c #C99507\",'#13#10'\"-.'#9'c #845C00\",'#13#10'\";.'#9'c #131C68\",'#13\n  +#10'\">.'#9'c #274F83\",'#13#10'\",.'#9'c #3F7097\",'#13#10'\"''.'#9'c #92ADC3\",'\n  +#13#10'\").'#9'c #3A6C94\",'#13#10'\"!.'#9'c #C4A14E\",'#13#10'\"~.'#9'c #CDB369\"'\n  +','#13#10'\"{.'#9'c #D2BA78\",'#13#10'\"].'#9'c #D8C38A\",'#13#10'\"^.'#9'c #D0B8'\n  +'70\",'#13#10'\"/.'#9'c #C7AA53\",'#13#10'\"(.'#9'c #B78F23\",'#13#10'\"_.'#9'c #A'\n  +'97A02\",'#13#10'\":.'#9'c #A07000\",'#13#10'\"<.'#9'c #8E6100\",'#13#10'\"[.'#9'c'\n  +' #5B3C00\",'#13#10'\"}.'#9'c #000158\",'#13#10'\"|.'#9'c #010259\",'#13#10'\"1.'#9\n  +'c #9BB4C8\",'#13#10'\"2.'#9'c #6C91AF\",'#13#10'\"3.'#9'c #7295B2\",'#13#10'\"4.'\n  +#9'c #517DA0\",'#13#10'\"5.'#9'c #0F0F0F\",'#13#10'\"6.'#9'c #5D86A7\",'#13#10'\"7'\n  +'.'#9'c #5C85A6\",'#13#10'\"8.'#9'c #B4C7D6\",'#13#10'\"9.'#9'c #88A6BE\",'#13#10\n  +'\"0.'#9'c #B1C5D4\",'#13#10'\"a.'#9'c #97B1C6\",'#13#10'\"b.'#9'c #3C6D95\",'#13\n  +#10'\"c.'#9'c #6189A9\",'#13#10'\"d.'#9'c #A9BFD0\",'#13#10'\"e.'#9'c #90ACC2\",'\n  +#13#10'\"f.'#9'c #A1B9CC\",'#13#10'\"g.'#9'c #FFEF8C\",'#13#10'\"h.'#9'c #D2D2D2\"'\n  +','#13#10'\"i.'#9'c #5983A5\",'#13#10'\"j.'#9'c #87A5BE\",'#13#10'\"k.'#9'c #8FAB'\n  +'C2\",'#13#10'\"l.'#9'c #507CA0\",'#13#10'\"m.'#9'c #6A90AE\",'#13#10'\"n.'#9'c #7'\n  +'99AB6\",'#13#10'\"o.'#9'c #96B0C6\",'#13#10'\"p.'#9'c #254864\",'#13#10'\"q.'#9'c'\n  +' #575858\",'#13#10'\"r.'#9'c #849CB0\",'#13#10'\"s.'#9'c #5882A4\",'#13#10'\"t.'#9\n  +'c #81A1BA\",'#13#10'\"u.'#9'c #82A2BB\",'#13#10'\"v.'#9'c #8BA8C0\",'#13#10'\"w.'\n  +#9'c #447399\",'#13#10'\"x.'#9'c #407097\",'#13#10'\"y.'#9'c #84939F\",'#13#10'\"z'\n  +'.'#9'c #919191\",'#13#10'\"A.'#9'c #8795A1\",'#13#10'\"B.'#9'c #6088A9\",'#13#10\n  +'\"C.'#9'c #7C9DB8\",'#13#10'\"D.'#9'c #326590\",'#13#10'\"E.'#9'c #87A5BD\",'#13\n  +#10'\"F.'#9'c #366992\",'#13#10'\"G.'#9'c #8CA9C0\",'#13#10'\"H.'#9'c #7396B2\",'\n  +#13#10'\"I.'#9'c #7F8385\",'#13#10'\"J.'#9'c #C2C2C2\",'#13#10'\"K.'#9'c #83888D\"'\n  +','#13#10'\"L.'#9'c #5781A4\",'#13#10'\"M.'#9'c #5F87A8\",'#13#10'\"N.'#9'c #84A3'\n  +'BC\",'#13#10'\"O.'#9'c #376A93\",'#13#10'\"P.'#9'c #90ACC3\",'#13#10'\"Q.'#9'c #4'\n  +'6749A\",'#13#10'\"R.'#9'c #6A8FAE\",'#13#10'\"S.'#9'c #8D9FAE\",'#13#10'\"T.'#9'c'\n  +' #888888\",'#13#10'\"U.'#9'c #7C9AB3\",'#13#10'\"V.'#9'c #5E87A7\",'#13#10'\"W.'#9\n  +'c #356891\",'#13#10'\"X.'#9'c #9CB5C9\",'#13#10'\"Y.'#9'c #D9E2E9\",'#13#10'\"Z.'\n  ,#9'c #7F8386\",'#13#10'\"`.'#9'c #A4A4A4\",'#13#10'\" +'#9'c #959595\",'#13#10'\".'\n  +'+'#9'c #82929F\",'#13#10'\"++'#9'c #A0B7CA\",'#13#10'\"@+'#9'c #99A8B3\",'#13#10\n  +'\"#+'#9'c #B4C4D2\",'#13#10'\"$+'#9'c #98B1C6\",'#13#10'\"%+'#9'c #396B94\",'#13\n  +#10'\"&+'#9'c #81A0BA\",'#13#10'\"*+'#9'c #BDC5CC\",'#13#10'\"=+'#9'c #666667\",'\n  +#13#10'\"-+'#9'c #818183\",'#13#10'\";+'#9'c #808080\",'#13#10'\">+'#9'c #BABABA\"'\n  +','#13#10'\",+'#9'c #C9C9C9\",'#13#10'\"''+'#9'c #86888A\",'#13#10'\")+'#9'c #779'\n  +'9B4\",'#13#10'\"!+'#9'c #7094B1\",'#13#10'\"~+'#9'c #838C92\",'#13#10'\"{+'#9'c #'\n  +'5E5E5E\",'#13#10'\"]+'#9'c #97A4AF\",'#13#10'\"^+'#9'c #A5BCCE\",'#13#10'\"/+'#9\n  +'c #7195B2\",'#13#10'\"(+'#9'c #32658F\",'#13#10'\"_+'#9'c #92ADC4\",'#13#10'\":+'\n  +#9'c #8AA7BF\",'#13#10'\"<+'#9'c #8EA6BA\",'#13#10'\"[+'#9'c #C0CCD5\",'#13#10'\"}'\n  +'+'#9'c #828385\",'#13#10'\"|+'#9'c #AEAEAE\",'#13#10'\"1+'#9'c #FEFEFE\",'#13#10\n  +'\"2+'#9'c #77838C\",'#13#10'\"3+'#9'c #91ABC0\",'#13#10'\"4+'#9'c #87929B\",'#13\n  +#10'\"5+'#9'c #A3A6A8\",'#13#10'\"6+'#9'c #A3B4C3\",'#13#10'\"7+'#9'c #98ADBF\",'\n  +#13#10'\"8+'#9'c #3E6F96\",'#13#10'\"9+'#9'c #B4C0CB\",'#13#10'\"0+'#9'c #89949C\"'\n  +','#13#10'\"a+'#9'c #828A90\",'#13#10'\"b+'#9'c #7D7F80\",'#13#10'\"c+'#9'c #8E8E'\n  +'8E\",'#13#10'\"d+'#9'c #F6F6F6\",'#13#10'\"e+'#9'c #EAEAEA\",'#13#10'\"f+'#9'c #7'\n  +'07172\",'#13#10'\"g+'#9'c #696969\",'#13#10'\"h+'#9'c #828282\",'#13#10'\"i+'#9'c'\n  +' #7C8286\",'#13#10'\"j+'#9'c #797E82\",'#13#10'\"k+'#9'c #808081\",'#13#10'\"l+'#9\n  +'c #7997AF\",'#13#10'\"m+'#9'c #47769B\",'#13#10'\"n+'#9'c #899198\",'#13#10'\"o+'\n  +#9'c #858585\",'#13#10'\"p+'#9'c #B1B1B1\",'#13#10'\"q+'#9'c #FAFAFA\",'#13#10'\"r'\n  +'+'#9'c #E6E6E6\",'#13#10'\"s+'#9'c #F9F9F9\",'#13#10'\"t+'#9'c #C3C3C3\",'#13#10\n  +'\"u+'#9'c #8F8F8F\",'#13#10'\"v+'#9'c #7A98B0\",'#13#10'\"w+'#9'c #5580A2\",'#13\n  +#10'\"x+'#9'c #84898D\",'#13#10'\"y+'#9'c #D0D0D0\",'#13#10'\"z+'#9'c #9F9FA0\",'\n  +#13#10'\"A+'#9'c #809BB1\",'#13#10'\"B+'#9'c #658BAA\",'#13#10'\"C+'#9'c #7D7F81\"'\n  +','#13#10'\"D+'#9'c #DDDDDD\",'#13#10'\"E+'#9'c #ACACAC\",'#13#10'\"F+'#9'c #89A0'\n  +'B2\",'#13#10'\"G+'#9'c #F1F1F1\",'#13#10'\"H+'#9'c #88939C\",'#13#10'\"I+'#9'c #7'\n  +'E8C97\",'#13#10'\"J+'#9'c #A5A5A5\",'#13#10'\"  . . . . + + + + + + + + + + + @'\n  +' # $ + + + + + \",'#13#10'\"+ + % . & + + + + + + + + + + @ # * # $ + + + + \"'\n  +','#13#10'\"+ + = . - + + + + + + + + + $ ; > , '' ) $ + + + \",'#13#10'\"+ ! ~'\n  +' { ] ^ + + / ( _ _ : < # [ } | 1 2 # + + + \",'#13#10'\"3 4 . 5 6 7 8 9 0 a b'\n  +' c d e ; f g + h i j $ + + \",'#13#10'\"k l . m n o p q r s t u v # w x y z A'\n  +' B C # + + \",'#13#10'\"D E F G H I J K H H H L M N O P Q R S T U j V + \",'#13\n  +#10'\"W . X Y Y Z ` Y Y Y Y  ...+.@.#.$.%.&.*.=.-.# $ \",'#13#10'\";.. >.Y ,.'''\n  +'.).H Y Y Y # !.~.{.].^./.(._.:.<.[.# \",'#13#10'\". . }.|.|.1.2.3.4.Y Y # # 5'\n  +'.# # # # # # # # # # \",'#13#10'\"6.Y Y Y 7.8.9.0.a.b.Y Y c.d.e.f.# g.# h.+ +'\n  +' + + \",'#13#10'\"s H Y Y i.j.Y 7.k.l.Y H m.n.4.o.p.# q.( + + + + \",'#13#10'\"'\n  +'r.Y Y Y s.t.Y H u.7.Y Y I v.w.o.x.y.z.+ + + + + \",'#13#10'\"A.b.Y Y B.C.H D.'\n  +'E.i.Y Y F.G.6.o.H.I.J.+ + + + + \",'#13#10'\"K.L.Y Y M.N.H O.P.Q.Y Y Y R.e.1.'\n  +'S.T./ + + + + + \",'#13#10'\"6 U.H Y w.v.l.V.9.Y Y Y Y W.X.Y.Z.`.3 + + + + + '\n  +'\",'#13#10'\" +.+b.Y H ++@+#+$+%+Y Y Y H &+*+=+-+;+>++ + + + \",'#13#10'\",+''+'\n  +')+H !+~+{+]+^+/+(+Y Y %+_+:+<+[+}+|++ + + + \",'#13#10'\"1+7 2+3+4+5+6+Z 7+j.'\n  +'Y Y Y 8+9+0+a+b+c+d++ + + + \",'#13#10'\"+ e+c+f+g+h+i+j+k+l+Y Y Y m+n+o+p+$ '\n  +'1++ + + + + \",'#13#10'\"+ + q+r+s+: t+J.u+v+Y Y Y w+x+y++ + + + + + + + \",'\n  +#13#10'\"+ + + + + + + ^ z+A+Y Y Y B+C+D++ + + + + + + + \",'#13#10'\"+ + + + +'\n  +' + + + E+F+Y Y H t 0 G++ + + + + + + + \",'#13#10'\"+ + + + + + + + J.H+s.).B'\n  +'.I+J++ + + + + + + + + \"};'#13#10\n]);\nLazarusResources.Add('TZGroupedConnection','XPM',[\n  '/* XPM */'#13#10'static char * TZGroupedConnection.xpm_xpm[] = {'#13#10'\"24 '\n  +'24 101 2\",'#13#10'\"  '#9'c #23236E\",'#13#10'\". '#9'c #000058\",'#13#10'\"+ '#9\n  +'c None\",'#13#10'\"@ '#9'c #000000\",'#13#10'\"# '#9'c #080808\",'#13#10'\"$ '#9\n  +'c #2F2F2F\",'#13#10'\"% '#9'c #A5A5A5\",'#13#10'\"& '#9'c #C8C8DA\",'#13#10'\"* '\n  +#9'c #2F2F76\",'#13#10'\"= '#9'c #ADADAD\",'#13#10'\"- '#9'c #616197\",'#13#10'\";'\n  +' '#9'c #8D8DB4\",'#13#10'\"> '#9'c #FDFDFD\",'#13#10'\", '#9'c #E9E9E9\",'#13#10\n  +'\"'' '#9'c #797979\",'#13#10'\") '#9'c #414141\",'#13#10'\"! '#9'c #F4F4F7\",'#13\n  +#10'\"~ '#9'c #111163\",'#13#10'\"{ '#9'c #07075C\",'#13#10'\"] '#9'c #E2E2EC\",'\n  +#13#10'\"^ '#9'c #F6F6F6\",'#13#10'\"/ '#9'c #171717\",'#13#10'\"( '#9'c #ACACC8\"'\n  +','#13#10'\"_ '#9'c #424283\",'#13#10'\": '#9'c #070707\",'#13#10'\"< '#9'c #4B4B'\n  +'89\",'#13#10'\"[ '#9'c #A3A3C2\",'#13#10'\"} '#9'c #010101\",'#13#10'\"| '#9'c #E'\n  +'8E8EF\",'#13#10'\"1 '#9'c #0A0A5E\",'#13#10'\"2 '#9'c #0D0D60\",'#13#10'\"3 '#9'c'\n  +' #EFEFF4\",'#13#10'\"4 '#9'c #F8FAF8\",'#13#10'\"5 '#9'c #95CA95\",'#13#10'\"6 '#9\n  +'c #5FAF5F\",'#13#10'\"7 '#9'c #2F972F\",'#13#10'\"8 '#9'c #0B850B\",'#13#10'\"9 '\n  +#9'c #9797BA\",'#13#10'\"0 '#9'c #575790\",'#13#10'\"a '#9'c #44A144\",'#13#10'\"b'\n  +' '#9'c #007F00\",'#13#10'\"c '#9'c #090909\",'#13#10'\"d '#9'c #38387C\",'#13#10\n  +'\"e '#9'c #C7C7DA\",'#13#10'\"f '#9'c #017701\",'#13#10'\"g '#9'c #018901\",'#13\n  +#10'\"h '#9'c #212121\",'#13#10'\"i '#9'c #DFDFDF\",'#13#10'\"j '#9'c #030359\",'\n  +#13#10'\"k '#9'c #06065B\",'#13#10'\"l '#9'c #005C00\",'#13#10'\"m '#9'c #007200\"'\n  +','#13#10'\"n '#9'c #007B00\",'#13#10'\"o '#9'c #007E00\",'#13#10'\"p '#9'c #0080'\n  +'00\",'#13#10'\"q '#9'c #008600\",'#13#10'\"r '#9'c #009000\",'#13#10'\"s '#9'c #0'\n  +'0AA00\",'#13#10'\"t '#9'c #565656\",'#13#10'\"u '#9'c #969696\",'#13#10'\"v '#9'c'\n  +' #005A00\",'#13#10'\"w '#9'c #006400\",'#13#10'\"x '#9'c #006F00\",'#13#10'\"y '#9\n  +'c #007900\",'#13#10'\"z '#9'c #008300\",'#13#10'\"A '#9'c #008E00\",'#13#10'\"B '\n  +#9'c #009800\",'#13#10'\"C '#9'c #00A200\",'#13#10'\"D '#9'c #00AD00\",'#13#10'\"E'\n  +' '#9'c #CCCCCC\",'#13#10'\"F '#9'c #060606\",'#13#10'\"G '#9'c #0B0B0B\",'#13#10\n  +'\"H '#9'c #9D9D9D\",'#13#10'\"I '#9'c #EDEDED\",'#13#10'\"J '#9'c #B8B8B8\",'#13\n  +#10'\"K '#9'c #1A1A1A\",'#13#10'\"L '#9'c #A4A4A4\",'#13#10'\"M '#9'c #161616\",'\n  +#13#10'\"N '#9'c #B6B6B6\",'#13#10'\"O '#9'c #ECECEC\",'#13#10'\"P '#9'c #404040\"'\n  +','#13#10'\"Q '#9'c #949494\",'#13#10'\"R '#9'c #E0E0E0\",'#13#10'\"S '#9'c #1466'\n  +'14\",'#13#10'\"T '#9'c #14B314\",'#13#10'\"U '#9'c #F7F7F7\",'#13#10'\"V '#9'c #B'\n  +'3CEB3\",'#13#10'\"W '#9'c #1D751D\",'#13#10'\"X '#9'c #1DAC1D\",'#13#10'\"Y '#9'c'\n  +' #B3E6B3\",'#13#10'\"Z '#9'c #E7F0E7\",'#13#10'\"` '#9'c #B7D8B7\",'#13#10'\" .'#9\n  +'c #93CA93\",'#13#10'\"..'#9'c #B7DFB7\",'#13#10'\"+.'#9'c #E7F5E7\",'#13#10'\"@.'\n  +#9'c #FEFEFE\",'#13#10'\"#.'#9'c #040404\",'#13#10'\"$.'#9'c #6F6F6F\",'#13#10'\"%'\n  +'.'#9'c #323232\",'#13#10'\"&.'#9'c #A0A0A0\",'#13#10'\"*.'#9'c #2D2D2D\",'#13#10\n  +'\"  . . . . + + + + + + + + + + + @ # $ % + + + + \",'#13#10'\"+ + & . * + + +'\n  +' + + + + + + + + @ @ @ @ = + + + \",'#13#10'\"+ + - . ; + + + + + + + + + + +'\n  +' > , '' @ ) + + + \",'#13#10'\"+ ! ~ { ] + + + + + + + + + + + + + ^ @ / + + '\n  +'+ \",'#13#10'\"+ ( . _ + + + + + + + + + + + + + + + @ : + + + \",'#13#10'\"+ <'\n  +' . [ + + + + + + + + + + + + + + + @ } + + + \",'#13#10'\"| 1 2 3 + 4 5 6 7 8'\n  +' 7 6 5 4 + + + + + } @ + + + \",'#13#10'\"9 . 0 + + a b b b b b b b a + + + +'\n  +' + c @ ^ + + \",'#13#10'\"d . e + + f b b b b b b b g + + + + + h @ i + + \",'\n  +#13#10'\". . j k k l m n o b p q r s + + + + + t @ u + + \",'#13#10'\"+ + + + +'\n  +' v w x y z A B C D + + + + + E F G H I \",'#13#10'\"+ + + + + v w x y z A B C'\n  +' D + + + + + + J K @ @ \",'#13#10'\"+ + + + + v w x y z A B C D + + + + + + L'\n  +' M @ @ \",'#13#10'\"+ + + + + v w x y z A B C D + + + + + N } G H O \",'#13#10\n  +'\"+ + + + + v w x y z A B C D + + + + + P @ Q + + \",'#13#10'\"+ + + + + v w x'\n  +' y z A B C D + + + + + : @ R + + \",'#13#10'\"+ + + + + S w x y z A B C T + +'\n  +' + + + @ @ U + + \",'#13#10'\"+ + + + + V W x y z A B X Y + + + + + @ @ + + +'\n  +' \",'#13#10'\"+ + + + + + + Z `  ...+.+ + + + + + + @ @ + + + \",'#13#10'\"+ + '\n  +'+ + + + + + + + + + + + + + + + @.@ @ + + + \",'#13#10'\"+ + + + + + + + + + '\n  +'+ + + + + + + + , @ #.+ + + \",'#13#10'\"+ + + + + + + + + + + + + + + + @., '\n  +'$.@ %.+ + + \",'#13#10'\"+ + + + + + + + + + + + + + + + @ @ @ @ &.+ + + \",'\n  +#13#10'\"+ + + + + + + + + + + + + + + + @ : *.H + + + + \"};'#13#10\n]);\nLazarusResources.Add('TZQuery','XPM',[\n  '/* XPM */'#13#10'static char * TZQuery.xpm_xpm[] = {'#13#10'\"24 24 156 2\",'\n  +#13#10'\"  '#9'c #23236E\",'#13#10'\". '#9'c #000058\",'#13#10'\"+ '#9'c None\",'\n  +#13#10'\"@ '#9'c #C8C8DA\",'#13#10'\"# '#9'c #2F2F76\",'#13#10'\"$ '#9'c #22167D\"'\n  +','#13#10'\"% '#9'c #342690\",'#13#10'\"& '#9'c #6149C1\",'#13#10'\"* '#9'c #634C'\n  +'C4\",'#13#10'\"= '#9'c #6551C6\",'#13#10'\"- '#9'c #6755C8\",'#13#10'\"; '#9'c #6'\n  +'A59CA\",'#13#10'\"> '#9'c #6C5ECC\",'#13#10'\", '#9'c #6E62CF\",'#13#10'\"'' '#9\n  +'c #7166D1\",'#13#10'\") '#9'c #736AD4\",'#13#10'\"! '#9'c #756ED6\",'#13#10'\"~ '\n  +#9'c #7872D8\",'#13#10'\"{ '#9'c #7976DB\",'#13#10'\"] '#9'c #7C7ADE\",'#13#10'\"^'\n  +' '#9'c #7E7FE0\",'#13#10'\"/ '#9'c #8183E2\",'#13#10'\"( '#9'c #8288E4\",'#13#10\n  +'\"_ '#9'c #858BE6\",'#13#10'\": '#9'c #8790E9\",'#13#10'\"< '#9'c #8A94EB\",'#13\n  +#10'\"[ '#9'c #F4F4F7\",'#13#10'\"} '#9'c #06045E\",'#13#10'\"| '#9'c #02015A\",'\n  +#13#10'\"1 '#9'c #533DB2\",'#13#10'\"2 '#9'c #634DC3\",'#13#10'\"3 '#9'c #6651C5\"'\n  +','#13#10'\"4 '#9'c #6755C7\",'#13#10'\"5 '#9'c #6A59CB\",'#13#10'\"6 '#9'c #6C5D'\n  +'CD\",'#13#10'\"7 '#9'c #6F62CF\",'#13#10'\"8 '#9'c #7165D2\",'#13#10'\"9 '#9'c #7'\n  +'36AD3\",'#13#10'\"0 '#9'c #7A77DB\",'#13#10'\"a '#9'c #7C7BDD\",'#13#10'\"b '#9'c'\n  +' #7E7FDF\",'#13#10'\"c '#9'c #8387E4\",'#13#10'\"d '#9'c #858CE7\",'#13#10'\"e '#9\n  +'c #878FE9\",'#13#10'\"f '#9'c #8994EC\",'#13#10'\"g '#9'c #ACACC8\",'#13#10'\"h '\n  +#9'c #171071\",'#13#10'\"i '#9'c #5E45BE\",'#13#10'\"j '#9'c #6049C0\",'#13#10'\"k'\n  +' '#9'c #634DC4\",'#13#10'\"l '#9'c #6551C5\",'#13#10'\"m '#9'c #6A5ACA\",'#13#10\n  +'\"n '#9'c #6C5DCC\",'#13#10'\"o '#9'c #7165D1\",'#13#10'\"p '#9'c #7773D8\",'#13\n  +#10'\"q '#9'c #7F7FDF\",'#13#10'\"r '#9'c #8083E2\",'#13#10'\"s '#9'c #8388E4\",'\n  +#13#10'\"t '#9'c #858BE7\",'#13#10'\"u '#9'c #8994EB\",'#13#10'\"v '#9'c #4B4B89\"'\n  +','#13#10'\"w '#9'c #A3A3C2\",'#13#10'\"x '#9'c #B3B3B3\",'#13#10'\"y '#9'c #E8E8'\n  +'EF\",'#13#10'\"z '#9'c #0A0A5E\",'#13#10'\"A '#9'c #09095C\",'#13#10'\"B '#9'c #E'\n  +'FEFF4\",'#13#10'\"C '#9'c #FEFEFE\",'#13#10'\"D '#9'c #FDFDFD\",'#13#10'\"E '#9'c'\n  +' #9797BA\",'#13#10'\"F '#9'c #3D3D77\",'#13#10'\"G '#9'c #B4B4B4\",'#13#10'\"H '#9\n  +'c #38387C\",'#13#10'\"I '#9'c #8B8B9F\",'#13#10'\"J '#9'c #020259\",'#13#10'\"K '\n  +#9'c #06065B\",'#13#10'\"L '#9'c #9494B8\",'#13#10'\"M '#9'c #181864\",'#13#10'\"N'\n  +' '#9'c #1A1A69\",'#13#10'\"O '#9'c #616197\",'#13#10'\"P '#9'c #E7E7EF\",'#13#10\n  +'\"Q '#9'c #D7D7E4\",'#13#10'\"R '#9'c #4E4E8B\",'#13#10'\"S '#9'c #101060\",'#13\n  +#10'\"T '#9'c #101062\",'#13#10'\"U '#9'c #3F3F81\",'#13#10'\"V '#9'c #C1C1D6\",'\n  +#13#10'\"W '#9'c #272771\",'#13#10'\"X '#9'c #C9C9DB\",'#13#10'\"Y '#9'c #3A3A75\"'\n  +','#13#10'\"Z '#9'c #6F6F90\",'#13#10'\"` '#9'c #323271\",'#13#10'\" .'#9'c #2A2A'\n  +'6D\",'#13#10'\"..'#9'c #9D9DA8\",'#13#10'\"+.'#9'c #07075B\",'#13#10'\"@.'#9'c #5'\n  +'B5B86\",'#13#10'\"#.'#9'c #62628A\",'#13#10'\"$.'#9'c #131361\",'#13#10'\"%.'#9'c'\n  +' #88889D\",'#13#10'\"&.'#9'c #1B1B65\",'#13#10'\"*.'#9'c #C0C0D5\",'#13#10'\"=.'#9\n  +'c #4F4F80\",'#13#10'\"-.'#9'c #E3E3EC\",'#13#10'\";.'#9'c #ECECF2\",'#13#10'\">.'\n  +#9'c #9898BB\",'#13#10'\",.'#9'c #A5A5C4\",'#13#10'\"''.'#9'c #68689C\",'#13#10'\"'\n  +').'#9'c #A9A9C6\",'#13#10'\"!.'#9'c #D1D1E0\",'#13#10'\"~.'#9'c #404081\",'#13#10\n  +'\"{.'#9'c #424283\",'#13#10'\"].'#9'c #34347A\",'#13#10'\"^.'#9'c #8686AF\",'#13\n  +#10'\"/.'#9'c #F8F8FA\",'#13#10'\"(.'#9'c #3A3A7D\",'#13#10'\"_.'#9'c #F0F0F5\",'\n  +#13#10'\":.'#9'c #171767\",'#13#10'\"<.'#9'c #131364\",'#13#10'\"[.'#9'c #FCFCFD\"'\n  +','#13#10'\"}.'#9'c #85859B\",'#13#10'\"|.'#9'c #4B4B7E\",'#13#10'\"1.'#9'c #1515'\n  +'62\",'#13#10'\"2.'#9'c #3E3E77\",'#13#10'\"3.'#9'c #28286C\",'#13#10'\"4.'#9'c #A'\n  +'7A7AD\",'#13#10'\"5.'#9'c #B2B2B3\",'#13#10'\"6.'#9'c #0F0F5F\",'#13#10'\"7.'#9'c'\n  +' #0E0E5F\",'#13#10'\"8.'#9'c #F7F7F9\",'#13#10'\"9.'#9'c #0F0F61\",'#13#10'\"0.'#9\n  +'c #69699C\",'#13#10'\"a.'#9'c #ADADC9\",'#13#10'\"b.'#9'c #EEEEF3\",'#13#10'\"c.'\n  +#9'c #B6B6CF\",'#13#10'\"d.'#9'c #B7B7CF\",'#13#10'\"e.'#9'c #39397D\",'#13#10'\"f'\n  +'.'#9'c #9292B7\",'#13#10'\"g.'#9'c #5F5F96\",'#13#10'\"h.'#9'c #434383\",'#13#10\n  +'\"i.'#9'c #E1E1EB\",'#13#10'\"j.'#9'c #0B0B5F\",'#13#10'\"k.'#9'c #121263\",'#13\n  +#10'\"l.'#9'c #8080AB\",'#13#10'\"m.'#9'c #24246F\",'#13#10'\"n.'#9'c #010158\",'\n  +#13#10'\"o.'#9'c #D3D3E2\",'#13#10'\"p.'#9'c #191968\",'#13#10'\"q.'#9'c #ABABC7\"'\n  +','#13#10'\"r.'#9'c #BCBCD3\",'#13#10'\"s.'#9'c #252570\",'#13#10'\"t.'#9'c #5C5C'\n  +'94\",'#13#10'\"u.'#9'c #E5E5ED\",'#13#10'\"v.'#9'c #D6D6E4\",'#13#10'\"w.'#9'c #1'\n  +'81867\",'#13#10'\"x.'#9'c #333379\",'#13#10'\"y.'#9'c #9C9CBE\",'#13#10'\"  . . .'\n  +' . + + + + + + + + + + + + + + + + + + + \",'#13#10'\"+ + @ . # + + + + + + +'\n  +' + + + + + + + + + + + + \",'#13#10'\"+ + $ . % & * = - ; > , '' ) ! ~ { ] ^ '\n  +'/ ( _ : < \",'#13#10'\"+ [ } | 1 & 2 3 4 5 6 7 8 9 ! ~ 0 a b / c d e f \",'#13\n  +#10'\"+ g . h i j k l - m n , o 9 ! p 0 a q r s t : u \",'#13#10'\"+ v . w + + '\n  +'+ + + + + x + + + + + + + + + + + x \",'#13#10'\"y z A B + + + + + + + x C C '\n  +'C D + + + + + + + x \",'#13#10'\"E . F x x x x x x x x x G G G x x x x x x x '\n  +'x x \",'#13#10'\"H . I + + + + + + + + x + + + C + + + + + + + x \",'#13#10'\".'\n  +' . J K K + + + + + + x C C C D + + + + + + + x \",'#13#10'\"+ + x x x x x x x'\n  +' x x x G G G x x x x x x x x x \",'#13#10'\"+ + x + + + + + + + + x + + + + +'\n  ,' + + + + + + x \",'#13#10'\"+ + x C C C C C C C + x C C C C C C C C C C C x \"'\n  +','#13#10'\"+ + x G G G G G G G G x G G G G G G G G G G G x \",'#13#10'\"+ + x '\n  +'+ + + + + + + + x + + + + + + + + + + + x \",'#13#10'\"+ L M K N O P + + Q R '\n  +'S T U V + + . W C C C C x \",'#13#10'\"X . Y Z ` .  .x ..+.A @.#.$.. %.G . &.'\n  +'G G G G x \",'#13#10'\"*.. =.-.;.>.,.+ ''.. ).x + !.. ~.+ . W + + + + x \",'#13\n  +#10'\"D {.. . ].^./.+ (.. _.x + + :.<.+ . W C C C C x \",'#13#10'\"+ [.}.|.1.. '\n  +'2.x 3.. 4.x x 5.6.7.x . &.x x x x x \",'#13#10'\">.H P + 8.z 9.+ 0.. a.b.0.c.'\n  +'. v + . W + + + + + \",'#13#10'\"d.. e.f.g.. h.+ i.j.k.l.m.. n.o.+ . p.q.q.q.'\n  +'r.+ \",'#13#10'\"+ >.s.K p.t.u.+ + v.v w.<.h.z {.+ . . . . . x.+ \",'#13#10'\"+'\n  +' + + + + + + + + + + + + + y y.+ + + + + + + + \"};'#13#10\n]);\nLazarusResources.Add('TZUpdateSql','XPM',[\n  '/* XPM */'#13#10'static char * TZUpdateSql.xpm_xpm[] = {'#13#10'\"24 24 192 2'\n  +'\",'#13#10'\"  '#9'c #23236E\",'#13#10'\". '#9'c #000058\",'#13#10'\"+ '#9'c None'\n  +'\",'#13#10'\"@ '#9'c #F2C9C9\",'#13#10'\"# '#9'c #FDF3F3\",'#13#10'\"$ '#9'c #C8C'\n  +'8DA\",'#13#10'\"% '#9'c #2F2F76\",'#13#10'\"& '#9'c #FFFEFE\",'#13#10'\"* '#9'c #'\n  +'FEFDFD\",'#13#10'\"= '#9'c #FEFCFC\",'#13#10'\"- '#9'c #E68A8A\",'#13#10'\"; '#9\n  +'c #C80C0C\",'#13#10'\"> '#9'c #F7D8D8\",'#13#10'\", '#9'c #22167D\",'#13#10'\"'' '\n  +#9'c #342690\",'#13#10'\") '#9'c #6149C1\",'#13#10'\"! '#9'c #634CC4\",'#13#10'\"~'\n  +' '#9'c #6551C6\",'#13#10'\"{ '#9'c #6755C8\",'#13#10'\"] '#9'c #6A59CA\",'#13#10\n  +'\"^ '#9'c #6C5ECC\",'#13#10'\"/ '#9'c #6E62CF\",'#13#10'\"( '#9'c #7166D1\",'#13\n  +#10'\"_ '#9'c #7467CF\",'#13#10'\": '#9'c #8F4A91\",'#13#10'\"< '#9'c #BE0B15\",'\n  +#13#10'\"[ '#9'c #C70000\",'#13#10'\"} '#9'c #9D5E98\",'#13#10'\"| '#9'c #8A94EB\"'\n  +','#13#10'\"1 '#9'c #F4F4F7\",'#13#10'\"2 '#9'c #06045E\",'#13#10'\"3 '#9'c #0201'\n  +'5A\",'#13#10'\"4 '#9'c #533DB2\",'#13#10'\"5 '#9'c #634DC3\",'#13#10'\"6 '#9'c #6'\n  +'651C5\",'#13#10'\"7 '#9'c #6755C7\",'#13#10'\"8 '#9'c #6A59CB\",'#13#10'\"9 '#9'c'\n  +' #6C5DCD\",'#13#10'\"0 '#9'c #6F62CF\",'#13#10'\"a '#9'c #775DC2\",'#13#10'\"b '#9\n  +'c #C1070E\",'#13#10'\"c '#9'c #927CC6\",'#13#10'\"d '#9'c #ACACC8\",'#13#10'\"e '\n  +#9'c #171071\",'#13#10'\"f '#9'c #5E45BE\",'#13#10'\"g '#9'c #6049C0\",'#13#10'\"h'\n  +' '#9'c #634DC4\",'#13#10'\"i '#9'c #6551C5\",'#13#10'\"j '#9'c #6A5ACA\",'#13#10\n  +'\"k '#9'c #6C5DCC\",'#13#10'\"l '#9'c #B01A36\",'#13#10'\"m '#9'c #9965A4\",'#13\n  +#10'\"n '#9'c #8994EB\",'#13#10'\"o '#9'c #4B4B89\",'#13#10'\"p '#9'c #A3A3C2\",'\n  +#13#10'\"q '#9'c #B3B3B3\",'#13#10'\"r '#9'c #C90A0A\",'#13#10'\"s '#9'c #CD1D1D\"'\n  +','#13#10'\"t '#9'c #ECADAD\",'#13#10'\"u '#9'c #F9F5F4\",'#13#10'\"v '#9'c #F2C5'\n  +'C5\",'#13#10'\"w '#9'c #C60404\",'#13#10'\"x '#9'c #F3D0D0\",'#13#10'\"y '#9'c #F'\n  +'2FBF2\",'#13#10'\"z '#9'c #E8E8EF\",'#13#10'\"A '#9'c #0A0A5E\",'#13#10'\"B '#9'c'\n  +' #09095C\",'#13#10'\"C '#9'c #EFEFF4\",'#13#10'\"D '#9'c #DF6F6F\",'#13#10'\"E '#9\n  +'c #FEFBFB\",'#13#10'\"F '#9'c #E4F7E4\",'#13#10'\"G '#9'c #53CB53\",'#13#10'\"H '\n  +#9'c #FAECEC\",'#13#10'\"I '#9'c #FAE5E5\",'#13#10'\"J '#9'c #D8F3D8\",'#13#10'\"K'\n  +' '#9'c #0CB60C\",'#13#10'\"L '#9'c #B2B2B2\",'#13#10'\"M '#9'c #9797BA\",'#13#10\n  +'\"N '#9'c #3D3D77\",'#13#10'\"O '#9'c #B4B4B4\",'#13#10'\"P '#9'c #9BB39B\",'#13\n  +#10'\"Q '#9'c #04B304\",'#13#10'\"R '#9'c #0BB30B\",'#13#10'\"S '#9'c #86B386\",'\n  +#13#10'\"T '#9'c #88B388\",'#13#10'\"U '#9'c #84B284\",'#13#10'\"V '#9'c #7AB37A\"'\n  +','#13#10'\"W '#9'c #21B321\",'#13#10'\"X '#9'c #00B300\",'#13#10'\"Y '#9'c #B2B3'\n  +'B2\",'#13#10'\"Z '#9'c #38387C\",'#13#10'\"` '#9'c #8B8B9F\",'#13#10'\" .'#9'c #D'\n  +'3F2D3\",'#13#10'\"..'#9'c #02B202\",'#13#10'\"+.'#9'c #64D064\",'#13#10'\"@.'#9'c'\n  +' #020259\",'#13#10'\"#.'#9'c #06065B\",'#13#10'\"$.'#9'c #A0E2A0\",'#13#10'\"%.'#9\n  +'c #6BD16B\",'#13#10'\"&.'#9'c #FDFFFD\",'#13#10'\"*.'#9'c #89B389\",'#13#10'\"=.'\n  +#9'c #01B201\",'#13#10'\"-.'#9'c #57B357\",'#13#10'\";.'#9'c #6AB26A\",'#13#10'\">'\n  +'.'#9'c #6EB36E\",'#13#10'\",.'#9'c #77B277\",'#13#10'\"''.'#9'c #A9B2A9\",'#13#10\n  +'\").'#9'c #E5F7E5\",'#13#10'\"!.'#9'c #16B916\",'#13#10'\"~.'#9'c #FEFEFE\",'#13\n  +#10'\"{.'#9'c #F8FCF8\",'#13#10'\"].'#9'c #9494B8\",'#13#10'\"^.'#9'c #181864\",'\n  +#13#10'\"/.'#9'c #1A1A69\",'#13#10'\"(.'#9'c #616197\",'#13#10'\"_.'#9'c #E7E7EF\"'\n  +','#13#10'\":.'#9'c #D7D7E4\",'#13#10'\"<.'#9'c #4E4E8B\",'#13#10'\"[.'#9'c #1010'\n  +'60\",'#13#10'\"}.'#9'c #101062\",'#13#10'\"|.'#9'c #3F3F81\",'#13#10'\"1.'#9'c #C'\n  +'1C1D6\",'#13#10'\"2.'#9'c #272771\",'#13#10'\"3.'#9'c #C9C9DB\",'#13#10'\"4.'#9'c'\n  +' #3A3A75\",'#13#10'\"5.'#9'c #6F6F90\",'#13#10'\"6.'#9'c #323271\",'#13#10'\"7.'#9\n  +'c #2A2A6D\",'#13#10'\"8.'#9'c #9D9DA8\",'#13#10'\"9.'#9'c #07075B\",'#13#10'\"0.'\n  +#9'c #5B5B86\",'#13#10'\"a.'#9'c #62628A\",'#13#10'\"b.'#9'c #131361\",'#13#10'\"c'\n  +'.'#9'c #88889D\",'#13#10'\"d.'#9'c #1B1B65\",'#13#10'\"e.'#9'c #C0C0D5\",'#13#10\n  +'\"f.'#9'c #4F4F80\",'#13#10'\"g.'#9'c #E3E3EC\",'#13#10'\"h.'#9'c #ECECF2\",'#13\n  +#10'\"i.'#9'c #9898BB\",'#13#10'\"j.'#9'c #A5A5C4\",'#13#10'\"k.'#9'c #68689C\",'\n  +#13#10'\"l.'#9'c #A9A9C6\",'#13#10'\"m.'#9'c #D1D1E0\",'#13#10'\"n.'#9'c #404081\"'\n  +','#13#10'\"o.'#9'c #FDFDFD\",'#13#10'\"p.'#9'c #424283\",'#13#10'\"q.'#9'c #3434'\n  +'7A\",'#13#10'\"r.'#9'c #8686AF\",'#13#10'\"s.'#9'c #F8F8FA\",'#13#10'\"t.'#9'c #3'\n  +'A3A7D\",'#13#10'\"u.'#9'c #F0F0F5\",'#13#10'\"v.'#9'c #171767\",'#13#10'\"w.'#9'c'\n  +' #131364\",'#13#10'\"x.'#9'c #FCFCFD\",'#13#10'\"y.'#9'c #85859B\",'#13#10'\"z.'#9\n  +'c #4B4B7E\",'#13#10'\"A.'#9'c #151562\",'#13#10'\"B.'#9'c #3E3E77\",'#13#10'\"C.'\n  +#9'c #28286C\",'#13#10'\"D.'#9'c #A7A7AD\",'#13#10'\"E.'#9'c #B2B2B3\",'#13#10'\"F'\n  +'.'#9'c #0F0F5F\",'#13#10'\"G.'#9'c #0E0E5F\",'#13#10'\"H.'#9'c #F7F7F9\",'#13#10\n  +'\"I.'#9'c #0F0F61\",'#13#10'\"J.'#9'c #69699C\",'#13#10'\"K.'#9'c #ADADC9\",'#13\n  +#10'\"L.'#9'c #EEEEF3\",'#13#10'\"M.'#9'c #B6B6CF\",'#13#10'\"N.'#9'c #B7B7CF\",'\n  +#13#10'\"O.'#9'c #39397D\",'#13#10'\"P.'#9'c #9292B7\",'#13#10'\"Q.'#9'c #5F5F96\"'\n  +','#13#10'\"R.'#9'c #434383\",'#13#10'\"S.'#9'c #E1E1EB\",'#13#10'\"T.'#9'c #0B0B'\n  +'5F\",'#13#10'\"U.'#9'c #121263\",'#13#10'\"V.'#9'c #8080AB\",'#13#10'\"W.'#9'c #2'\n  +'4246F\",'#13#10'\"X.'#9'c #010158\",'#13#10'\"Y.'#9'c #D3D3E2\",'#13#10'\"Z.'#9'c'\n  ,' #191968\",'#13#10'\"`.'#9'c #ABABC7\",'#13#10'\" +'#9'c #BCBCD3\",'#13#10'\".+'#9\n  +'c #252570\",'#13#10'\"++'#9'c #5C5C94\",'#13#10'\"@+'#9'c #E5E5ED\",'#13#10'\"#+'\n  +#9'c #D6D6E4\",'#13#10'\"$+'#9'c #181867\",'#13#10'\"%+'#9'c #333379\",'#13#10'\"&'\n  +'+'#9'c #9C9CBE\",'#13#10'\"  . . . . + + + + + + + + + + + + + + @ # + + + \",'\n  +#13#10'\"+ + $ . % + + + + + + + + + + + & * = - ; > + + \",'#13#10'\"+ + , . '\n  +''' ) ! ~ { ] ^ / ( _ : < [ [ [ [ [ [ } | \",'#13#10'\"+ 1 2 3 4 ) 5 6 7 8 9 0'\n  +' a b [ [ [ [ [ [ [ [ [ c \",'#13#10'\"+ d . e f g h i { j k / l [ [ [ [ [ [ ['\n  +' [ [ m n \",'#13#10'\"+ o . p + + + + + + + q r s t u * & + v w x y q \",'#13\n  +#10'\"z A B C + + + + + + + q D E F G + + + H I J K L \",'#13#10'\"M . N q q q '\n  +'q q q q q q O P Q R S T U V W X X Y \",'#13#10'\"Z . ` + + + + + + + + q  ...'\n  +'X X X X X X X X +.q \",'#13#10'\". . @.#.#.+ + + + + + q $.X X X X X X X X %.'\n  +'&.q \",'#13#10'\"+ + q q q q q q q q q q O *.=.X -.;.>.,.''.q q q \",'#13#10'\"'\n  +'+ + q + + + + + + + + q + + ).!.+ + + + + + + q \",'#13#10'\"+ + q ~.~.~.~.~.'\n  +'~.~.+ q ~.~.~.{.~.~.~.~.~.~.~.q \",'#13#10'\"+ + q O O O O O O O O q O O O O '\n  +'O O O O O O O q \",'#13#10'\"+ + q + + + + + + + + q + + + + + + + + + + + q '\n  +'\",'#13#10'\"+ ].^.#./.(._.+ + :.<.[.}.|.1.+ + . 2.~.~.~.~.q \",'#13#10'\"3.. 4'\n  +'.5.6.. 7.q 8.9.B 0.a.b.. c.O . d.O O O O q \",'#13#10'\"e.. f.g.h.i.j.+ k.. l'\n  +'.q + m.. n.+ . 2.+ + + + q \",'#13#10'\"o.p.. . q.r.s.+ t.. u.q + + v.w.+ . 2'\n  +'.~.~.~.~.q \",'#13#10'\"+ x.y.z.A.. B.q C.. D.q q E.F.G.q . d.q q q q q \",'#13\n  +#10'\"i.Z _.+ H.A I.+ J.. K.L.J.M.. o + . 2.+ + + + + \",'#13#10'\"N.. O.P.Q.. '\n  +'R.+ S.T.U.V.W.. X.Y.+ . Z.`.`.`. ++ \",'#13#10'\"+ i..+#.Z.++@++ + #+o $+w.R.'\n  +'A p.+ . . . . . %++ \",'#13#10'\"+ + + + + + + + + + + + + + z &++ + + + + + '\n  +'+ + \"};'#13#10\n]);\nLazarusResources.Add('TZSqlProcessor','XPM',[\n  '/* XPM */'#13#10'static char * TZSqlProcessor.xpm_xpm[] = {'#13#10'\"24 24 19'\n  +'6 2\",'#13#10'\"  '#9'c #23236E\",'#13#10'\". '#9'c #000058\",'#13#10'\"+ '#9'c N'\n  +'one\",'#13#10'\"@ '#9'c #F8FAF8\",'#13#10'\"# '#9'c #95CA95\",'#13#10'\"$ '#9'c #'\n  +'5FAF5F\",'#13#10'\"% '#9'c #2F972F\",'#13#10'\"& '#9'c #0B850B\",'#13#10'\"* '#9\n  +'c #C8C8DA\",'#13#10'\"= '#9'c #191960\",'#13#10'\"- '#9'c #888A85\",'#13#10'\"; '\n  +#9'c #248123\",'#13#10'\"> '#9'c #007F00\",'#13#10'\", '#9'c #44A144\",'#13#10'\"'\n  +''' '#9'c #616197\",'#13#10'\") '#9'c #8D8DB4\",'#13#10'\"! '#9'c #017701\",'#13\n  +#10'\"~ '#9'c #018901\",'#13#10'\"{ '#9'c #F4F4F7\",'#13#10'\"] '#9'c #111163\",'\n  +#13#10'\"^ '#9'c #030359\",'#13#10'\"/ '#9'c #E2E2EC\",'#13#10'\"( '#9'c #DEDEDE\"'\n  +','#13#10'\"_ '#9'c #E1E1E1\",'#13#10'\": '#9'c #E0E0E0\",'#13#10'\"< '#9'c #E2E2'\n  +'E2\",'#13#10'\"[ '#9'c #E3E3E3\",'#13#10'\"} '#9'c #E4E4E4\",'#13#10'\"| '#9'c #0'\n  +'05C00\",'#13#10'\"1 '#9'c #007200\",'#13#10'\"2 '#9'c #007B00\",'#13#10'\"3 '#9'c'\n  +' #007E00\",'#13#10'\"4 '#9'c #008000\",'#13#10'\"5 '#9'c #008600\",'#13#10'\"6 '#9\n  +'c #009000\",'#13#10'\"7 '#9'c #00AA00\",'#13#10'\"8 '#9'c #ACACC8\",'#13#10'\"9 '\n  +#9'c #232363\",'#13#10'\"0 '#9'c #DFDFDF\",'#13#10'\"a '#9'c #B6B6B6\",'#13#10'\"b'\n  +' '#9'c #B7B7B7\",'#13#10'\"c '#9'c #005A00\",'#13#10'\"d '#9'c #006400\",'#13#10\n  +'\"e '#9'c #006F00\",'#13#10'\"f '#9'c #007900\",'#13#10'\"g '#9'c #008300\",'#13\n  +#10'\"h '#9'c #008E00\",'#13#10'\"i '#9'c #009800\",'#13#10'\"j '#9'c #00A200\",'\n  +#13#10'\"k '#9'c #00AD00\",'#13#10'\"l '#9'c #4B4B89\",'#13#10'\"m '#9'c #565874\"'\n  +','#13#10'\"n '#9'c #E6E6E6\",'#13#10'\"o '#9'c #CE5C00\",'#13#10'\"p '#9'c #D276'\n  +'2C\",'#13#10'\"q '#9'c #E7E7E7\",'#13#10'\"r '#9'c #E8E8EF\",'#13#10'\"s '#9'c #0'\n  +'A0A5E\",'#13#10'\"t '#9'c #0D0D60\",'#13#10'\"u '#9'c #7F8182\",'#13#10'\"v '#9'c'\n  +' #F5D400\",'#13#10'\"w '#9'c #FCAF3E\",'#13#10'\"x '#9'c #C47D44\",'#13#10'\"y '#9\n  +'c #9797BA\",'#13#10'\"z '#9'c #575790\",'#13#10'\"A '#9'c #E5E5E5\",'#13#10'\"B '\n  +#9'c #CE5E03\",'#13#10'\"C '#9'c #F57900\",'#13#10'\"D '#9'c #D68543\",'#13#10'\"E'\n  +' '#9'c #38387C\",'#13#10'\"F '#9'c #C7C7DA\",'#13#10'\"G '#9'c #ADAFAC\",'#13#10\n  +'\"H '#9'c #CB6411\",'#13#10'\"I '#9'c #CA6A1C\",'#13#10'\"J '#9'c #B7B5B3\",'#13\n  +#10'\"K '#9'c #06065B\",'#13#10'\"L '#9'c #F47A03\",'#13#10'\"M '#9'c #DAA172\",'\n  +#13#10'\"N '#9'c #E8E8E8\",'#13#10'\"O '#9'c #F37B06\",'#13#10'\"P '#9'c #C98147\"'\n  +','#13#10'\"Q '#9'c #C2C2C2\",'#13#10'\"R '#9'c #0F620F\",'#13#10'\"S '#9'c #14B3'\n  +'14\",'#13#10'\"T '#9'c #DCDCDC\",'#13#10'\"U '#9'c #D78D50\",'#13#10'\"V '#9'c #E'\n  +'AEAEA\",'#13#10'\"W '#9'c #A4BFA4\",'#13#10'\"X '#9'c #1A731A\",'#13#10'\"Y '#9'c'\n  +' #1DAC1D\",'#13#10'\"Z '#9'c #B3E6B3\",'#13#10'\"` '#9'c #FDFDFD\",'#13#10'\" .'#9\n  +'c #D06815\",'#13#10'\"..'#9'c #000000\",'#13#10'\"+.'#9'c #8A7B62\",'#13#10'\"@.'\n  +#9'c #DB9F6E\",'#13#10'\"#.'#9'c #ECECEC\",'#13#10'\"$.'#9'c #EEEEEE\",'#13#10'\"%'\n  +'.'#9'c #EBEBEB\",'#13#10'\"&.'#9'c #D5DFD5\",'#13#10'\"*.'#9'c #AACCAA\",'#13#10\n  +'\"=.'#9'c #92C992\",'#13#10'\"-.'#9'c #618B5F\",'#13#10'\";.'#9'c #E7F5E7\",'#13\n  +#10'\">.'#9'c #343434\",'#13#10'\",.'#9'c #B6B6B5\",'#13#10'\"''.'#9'c #FCFCFC\",'\n  +#13#10'\").'#9'c #EDEDED\",'#13#10'\"!.'#9'c #F4F4F4\",'#13#10'\"~.'#9'c #878984\"'\n  +','#13#10'\"{.'#9'c #9494B8\",'#13#10'\"].'#9'c #1A1A69\",'#13#10'\"^.'#9'c #5858'\n  +'8E\",'#13#10'\"/.'#9'c #D3D3DC\",'#13#10'\"(.'#9'c #9999A6\",'#13#10'\"_.'#9'c #3'\n  +'73774\",'#13#10'\":.'#9'c #111160\",'#13#10'\"<.'#9'c #0B0B5D\",'#13#10'\"[.'#9'c'\n  +' #2C2C6E\",'#13#10'\"}.'#9'c #89899E\",'#13#10'\"|.'#9'c #1B1B66\",'#13#10'\"1.'#9\n  +'c #C9C9DB\",'#13#10'\"2.'#9'c #54548F\",'#13#10'\"3.'#9'c #545674\",'#13#10'\"4.'\n  +#9'c #484887\",'#13#10'\"5.'#9'c #37377A\",'#13#10'\"6.'#9'c #CFCFD9\",'#13#10'\"7'\n  +'.'#9'c #7777A2\",'#13#10'\"8.'#9'c #8484AC\",'#13#10'\"9.'#9'c #1A1A68\",'#13#10\n  +'\"0.'#9'c #B6B6CB\",'#13#10'\"a.'#9'c #24246F\",'#13#10'\"b.'#9'c #848681\",'#13\n  +#10'\"c.'#9'c #C0C0D5\",'#13#10'\"d.'#9'c #7171A2\",'#13#10'\"e.'#9'c #797A80\",'\n  +#13#10'\"f.'#9'c #ECECF2\",'#13#10'\"g.'#9'c #8A8AAD\",'#13#10'\"h.'#9'c #9898B7\"'\n  +','#13#10'\"i.'#9'c #606094\",'#13#10'\"j.'#9'c #9D9DBA\",'#13#10'\"k.'#9'c #C2C2'\n  +'D2\",'#13#10'\"l.'#9'c #3B3B7D\",'#13#10'\"m.'#9'c #24246E\",'#13#10'\"n.'#9'c #4'\n  +'24283\",'#13#10'\"o.'#9'c #34347A\",'#13#10'\"p.'#9'c #7979A3\",'#13#10'\"q.'#9'c'\n  +' #E4E4E6\",'#13#10'\"r.'#9'c #353579\",'#13#10'\"s.'#9'c #E1E1E7\",'#13#10'\"t.'#9\n  +'c #F0F0F0\",'#13#10'\"u.'#9'c #151565\",'#13#10'\"v.'#9'c #FCFCFD\",'#13#10'\"w.'\n  +#9'c #BEBED4\",'#13#10'\"x.'#9'c #39396A\",'#13#10'\"y.'#9'c #1E1E6B\",'#13#10'\"z'\n  +'.'#9'c #595992\",'#13#10'\"A.'#9'c #3A3A7D\",'#13#10'\"B.'#9'c #EFEFF4\",'#13#10\n  +'\"C.'#9'c #161666\",'#13#10'\"D.'#9'c #272771\",'#13#10'\"E.'#9'c #9898BB\",'#13\n  +#10'\"F.'#9'c #E7E7EF\",'#13#10'\"G.'#9'c #B0B1AE\",'#13#10'\"H.'#9'c #838583\",'\n  +#13#10'\"I.'#9'c #050559\",'#13#10'\"J.'#9'c #08085A\",'#13#10'\"K.'#9'c #38386A\"'\n  +','#13#10'\"L.'#9'c #5C5D76\",'#13#10'\"M.'#9'c #7E8082\",'#13#10'\"N.'#9'c #6162'\n  +'78\",'#13#10'\"O.'#9'c #282865\",'#13#10'\"P.'#9'c #14155E\",'#13#10'\"Q.'#9'c #B'\n  +'1B1B0\",'#13#10'\"R.'#9'c #B7B7CF\",'#13#10'\"S.'#9'c #39397D\",'#13#10'\"T.'#9'c'\n  +' #9292B7\",'#13#10'\"U.'#9'c #5F5F96\",'#13#10'\"V.'#9'c #434383\",'#13#10'\"W.'#9\n  +'c #E1E1EB\",'#13#10'\"X.'#9'c #0B0B5F\",'#13#10'\"Y.'#9'c #121263\",'#13#10'\"Z.'\n  ,#9'c #8080AB\",'#13#10'\"`.'#9'c #010158\",'#13#10'\" +'#9'c #D3D3E2\",'#13#10'\".'\n  +'+'#9'c #191968\",'#13#10'\"++'#9'c #ABABC7\",'#13#10'\"@+'#9'c #BCBCD3\",'#13#10\n  +'\"#+'#9'c #252570\",'#13#10'\"$+'#9'c #5C5C94\",'#13#10'\"%+'#9'c #E5E5ED\",'#13\n  +#10'\"&+'#9'c #D6D6E4\",'#13#10'\"*+'#9'c #181867\",'#13#10'\"=+'#9'c #131364\",'\n  +#13#10'\"-+'#9'c #333379\",'#13#10'\";+'#9'c #9C9CBE\",'#13#10'\"  . . . . + + + '\n  +'+ + + + + + + @ # $ % & % $ # @ \",'#13#10'\"+ + * . = - - - - - - - - - - ; '\n  +'> > > > > > > , \",'#13#10'\"+ + '' . ) + + + + + + + + + + ! > > > > > > > ~'\n  +' \",'#13#10'\"+ { ] ^ / ( _ : _ < < [ } } } | 1 2 3 > 4 5 6 7 \",'#13#10'\"+ 8 '\n  +'. 9 + 0 < _ a a b b b b b c d e f g h i j k \",'#13#10'\"+ l . m + : [ < < n '\n  +'n o p q q c d e f g h i j k \",'#13#10'\"r s t u + _ } } a a o v w x a c d e '\n  +'f g h i j k \",'#13#10'\"y . z - + < n A A B v w C D A c d e f g h i j k \",'\n  +#13#10'\"E . F - + G n 0 H v w C I J a c d e f g h i j k \",'#13#10'\". . ^ ^ K'\n  +' } + o v w L M N N N c d e f g h i j k \",'#13#10'\"+ + + - + n o v w O P Q Q'\n  +' Q Q R d e f g h i j S \",'#13#10'\"+ + + - + T o w L U V V V V V W X e f g h'\n  +' i Y Z \",'#13#10'\"+ + + - `  ...+.@.#.$.%.#.$.%.#.%.&.*.=.-.;.+ + \",'#13#10\n  +'\"+ + + - + >.o V ,.,.,.,.,.,.,.,.,.,.,.''.- + + + \",'#13#10'\"+ + + - + q + '\n  +'%.V V ).V V V V V V V V !.~.+ + + \",'#13#10'\"+ {.  ^ ].^./.%.,.(._.:.<.[.}.'\n  +',.,.. |.+ ~.+ + + \",'#13#10'\"1.. 2.3.4.. 5.%.6.s t 7.8.9.. 0.%.. a.+ b.+ + '\n  +'+ \",'#13#10'\"c.. d.e.f.g.h.%.i.. j.#.).k.. l.#.. m.+ ~.+ + + \",'#13#10'\"` n'\n  +'.. . o.p.q.%.r.. s.).$.t.u.] ).. a.+ - + + + \",'#13#10'\"+ v.w.x.y.. z.+ A..'\n  +' B.+ + + C.u.+ . D.+ - + + + \",'#13#10'\"E.E F.G.H.I.J.- K.. L.M.K.N.. O.- .'\n  +' P.- Q.+ + + \",'#13#10'\"R.. S.T.U.. V.+ W.X.Y.Z.a.. `. ++ . .+++++++@++ \",'\n  +#13#10'\"+ E.#+K .+$+%++ + &+l *+=+V.s n.+ . . . . . -++ \",'#13#10'\"+ + + + +'\n  +' + + + + + + + + + r ;++ + + + + + + + \"};'#13#10\n]);\nLazarusResources.Add('TZTable','XPM',[\n  '/* XPM */'#13#10'static char * TZTable.xpm_xpm[] = {'#13#10'\"24 24 77 2\",'#13\n  +#10'\"  '#9'c #23236E\",'#13#10'\". '#9'c #000058\",'#13#10'\"+ '#9'c None\",'#13\n  +#10'\"@ '#9'c #C8C8DA\",'#13#10'\"# '#9'c #2F2F76\",'#13#10'\"$ '#9'c #22167D\",'\n  +#13#10'\"% '#9'c #342690\",'#13#10'\"& '#9'c #6149C1\",'#13#10'\"* '#9'c #634CC4\"'\n  +','#13#10'\"= '#9'c #6551C6\",'#13#10'\"- '#9'c #6755C8\",'#13#10'\"; '#9'c #6A59'\n  +'CA\",'#13#10'\"> '#9'c #6C5ECC\",'#13#10'\", '#9'c #6E62CF\",'#13#10'\"'' '#9'c #'\n  +'7166D1\",'#13#10'\") '#9'c #736AD4\",'#13#10'\"! '#9'c #756ED6\",'#13#10'\"~ '#9\n  +'c #7872D8\",'#13#10'\"{ '#9'c #7976DB\",'#13#10'\"] '#9'c #7C7ADE\",'#13#10'\"^ '\n  +#9'c #7E7FE0\",'#13#10'\"/ '#9'c #8183E2\",'#13#10'\"( '#9'c #8288E4\",'#13#10'\"_'\n  +' '#9'c #858BE6\",'#13#10'\": '#9'c #8790E9\",'#13#10'\"< '#9'c #8A94EB\",'#13#10\n  +'\"[ '#9'c #F4F4F7\",'#13#10'\"} '#9'c #06045E\",'#13#10'\"| '#9'c #02015A\",'#13\n  +#10'\"1 '#9'c #533DB2\",'#13#10'\"2 '#9'c #634DC3\",'#13#10'\"3 '#9'c #6651C5\",'\n  +#13#10'\"4 '#9'c #6755C7\",'#13#10'\"5 '#9'c #6A59CB\",'#13#10'\"6 '#9'c #6C5DCD\"'\n  +','#13#10'\"7 '#9'c #6F62CF\",'#13#10'\"8 '#9'c #7165D2\",'#13#10'\"9 '#9'c #736A'\n  +'D3\",'#13#10'\"0 '#9'c #7A77DB\",'#13#10'\"a '#9'c #7C7BDD\",'#13#10'\"b '#9'c #7'\n  +'E7FDF\",'#13#10'\"c '#9'c #8387E4\",'#13#10'\"d '#9'c #858CE7\",'#13#10'\"e '#9'c'\n  +' #878FE9\",'#13#10'\"f '#9'c #8994EC\",'#13#10'\"g '#9'c #ACACC8\",'#13#10'\"h '#9\n  +'c #171071\",'#13#10'\"i '#9'c #5E45BE\",'#13#10'\"j '#9'c #6049C0\",'#13#10'\"k '\n  +#9'c #634DC4\",'#13#10'\"l '#9'c #6551C5\",'#13#10'\"m '#9'c #6A5ACA\",'#13#10'\"n'\n  +' '#9'c #6C5DCC\",'#13#10'\"o '#9'c #7165D1\",'#13#10'\"p '#9'c #7773D8\",'#13#10\n  +'\"q '#9'c #7F7FDF\",'#13#10'\"r '#9'c #8083E2\",'#13#10'\"s '#9'c #8388E4\",'#13\n  +#10'\"t '#9'c #858BE7\",'#13#10'\"u '#9'c #8994EB\",'#13#10'\"v '#9'c #4B4B89\",'\n  +#13#10'\"w '#9'c #A3A3C2\",'#13#10'\"x '#9'c #B3B3B3\",'#13#10'\"y '#9'c #E8E8EF\"'\n  +','#13#10'\"z '#9'c #0A0A5E\",'#13#10'\"A '#9'c #09095C\",'#13#10'\"B '#9'c #EFEF'\n  +'F4\",'#13#10'\"C '#9'c #FEFEFE\",'#13#10'\"D '#9'c #FDFDFD\",'#13#10'\"E '#9'c #9'\n  +'797BA\",'#13#10'\"F '#9'c #3D3D77\",'#13#10'\"G '#9'c #B4B4B4\",'#13#10'\"H '#9'c'\n  +' #38387C\",'#13#10'\"I '#9'c #8B8B9F\",'#13#10'\"J '#9'c #020259\",'#13#10'\"K '#9\n  +'c #06065B\",'#13#10'\"L '#9'c #B2B2B3\",'#13#10'\"  . . . . + + + + + + + + + +'\n  +' + + + + + + + + + \",'#13#10'\"+ + @ . # + + + + + + + + + + + + + + + + + +'\n  +' + \",'#13#10'\"+ + $ . % & * = - ; > , '' ) ! ~ { ] ^ / ( _ : < \",'#13#10'\"+'\n  +' [ } | 1 & 2 3 4 5 6 7 8 9 ! ~ 0 a b / c d e f \",'#13#10'\"+ g . h i j k l -'\n  +' m n , o 9 ! p 0 a q r s t : u \",'#13#10'\"+ v . w + + + + + + + x + + + + +'\n  +' + + + + + + x \",'#13#10'\"y z A B + + + + + + + x C C C D + + + + + + + x \"'\n  +','#13#10'\"E . F x x x x x x x x x G G G x x x x x x x x x \",'#13#10'\"H . I '\n  +'+ + + + + + + + x + + + C + + + + + + + x \",'#13#10'\". . J K K + + + + + + '\n  +'x C C C D + + + + + + + x \",'#13#10'\"+ + x x x x x x x x x x G G G x x x x '\n  +'x x x x x \",'#13#10'\"+ + x + + + + + + + + x + + + + + + + + + + + x \",'#13\n  +#10'\"+ + x C C C C C C C + x C C C C C C C C C C C x \",'#13#10'\"+ + x G G G '\n  +'G G G G G x G G G G G G G G G G G x \",'#13#10'\"+ + x + + + + + + + + x + + '\n  +'+ + + + + + + + + x \",'#13#10'\"+ + x + + + + + + + + x + + + + + + + C C C '\n  +'C x \",'#13#10'\"+ + x x x x x x x x x x x x x G G x x G G G G x \",'#13#10'\"+'\n  +' + x + + + + + + + + x + + + + + + + + + + + x \",'#13#10'\"+ + x + + + + + +'\n  +' + + x + + + + + + + C C C C x \",'#13#10'\"+ + x x x x x x x x x x x L x x x'\n  +' x x x x x x x \",'#13#10'\"+ + + + + + + + + + + + + + + + + + + + + + + + \"'\n  +','#13#10'\"+ + + + + + + + + + + + + + + + + + + + + + + + \",'#13#10'\"+ + + '\n  +'+ + + + + + + + + + + + + + + + + + + + + \",'#13#10'\"+ + + + + + + + + + + '\n  +'+ + + + + + + + + + + + + \"};'#13#10\n]);\nLazarusResources.Add('TZStoredProc','XPM',[\n  '/* XPM */'#13#10'static char * TZStoredProc.xpm_xpm[] = {'#13#10'\"24 24 169 '\n  +'2\",'#13#10'\"  '#9'c #23236E\",'#13#10'\". '#9'c #000058\",'#13#10'\"+ '#9'c Non'\n  +'e\",'#13#10'\"@ '#9'c #457ABE\",'#13#10'\"# '#9'c #C8C8DA\",'#13#10'\"$ '#9'c #28'\n  +'2B6F\",'#13#10'\"% '#9'c #ACD5AC\",'#13#10'\"& '#9'c #89C489\",'#13#10'\"* '#9'c '\n  +'#65B265\",'#13#10'\"= '#9'c #42A042\",'#13#10'\"- '#9'c #229022\",'#13#10'\"; '#9\n  +'c #349934\",'#13#10'\"> '#9'c #58AB58\",'#13#10'\", '#9'c #64997A\",'#13#10'\"'' '\n  +#9'c #B8C3CE\",'#13#10'\") '#9'c #BCCDE3\",'#13#10'\"! '#9'c #BAC4D0\",'#13#10'\"~'\n  +' '#9'c #595D90\",'#13#10'\"{ '#9'c #004627\",'#13#10'\"] '#9'c #007F00\",'#13#10\n  +'\"^ '#9'c #86A7D2\",'#13#10'\"/ '#9'c #6490C7\",'#13#10'\"( '#9'c #9DB8DA\",'#13\n  +#10'\"_ '#9'c #F4F4F7\",'#13#10'\": '#9'c #060B58\",'#13#10'\"< '#9'c #000355\",'\n  +#13#10'\"[ '#9'c #00700A\",'#13#10'\"} '#9'c #ACACC8\",'#13#10'\"| '#9'c #001F41\"'\n  +','#13#10'\"1 '#9'c #137029\",'#13#10'\"2 '#9'c #7CA1CF\",'#13#10'\"3 '#9'c #427B'\n  +'B1\",'#13#10'\"4 '#9'c #5686C3\",'#13#10'\"5 '#9'c #4D7FBC\",'#13#10'\"6 '#9'c #8'\n  +'2A5D1\",'#13#10'\"7 '#9'c #4B4B89\",'#13#10'\"8 '#9'c #003B1F\",'#13#10'\"9 '#9'c'\n  +' #006A00\",'#13#10'\"0 '#9'c #007300\",'#13#10'\"a '#9'c #007900\",'#13#10'\"b '#9\n  +'c #007D00\",'#13#10'\"c '#9'c #008000\",'#13#10'\"d '#9'c #008100\",'#13#10'\"e '\n  +#9'c #427CB1\",'#13#10'\"f '#9'c #2D836A\",'#13#10'\"g '#9'c #B9C3CF\",'#13#10'\"h'\n  +' '#9'c #8DA2BC\",'#13#10'\"i '#9'c #5584BE\",'#13#10'\"j '#9'c #E8E8EF\",'#13#10\n  +'\"k '#9'c #0A0A5E\",'#13#10'\"l '#9'c #040758\",'#13#10'\"m '#9'c #005705\",'#13\n  +#10'\"n '#9'c #006400\",'#13#10'\"o '#9'c #006B00\",'#13#10'\"p '#9'c #007200\",'\n  +#13#10'\"q '#9'c #008700\",'#13#10'\"r '#9'c #008E00\",'#13#10'\"s '#9'c #139529\"'\n  +','#13#10'\"t '#9'c #9797BA\",'#13#10'\"u '#9'c #20325A\",'#13#10'\"v '#9'c #005D'\n  +'00\",'#13#10'\"w '#9'c #4980B7\",'#13#10'\"x '#9'c #458C93\",'#13#10'\"y '#9'c #7'\n  +'192BB\",'#13#10'\"z '#9'c #38387C\",'#13#10'\"A '#9'c #4A735D\",'#13#10'\"B '#9'c'\n  +' #009500\",'#13#10'\"C '#9'c #138329\",'#13#10'\"D '#9'c #8FAED5\",'#13#10'\"E '#9\n  +'c #010158\",'#13#10'\"F '#9'c #000255\",'#13#10'\"G '#9'c #5F945F\",'#13#10'\"H '\n  +#9'c #009C00\",'#13#10'\"I '#9'c #139129\",'#13#10'\"J '#9'c #00A300\",'#13#10'\"K'\n  +' '#9'c #00AA00\",'#13#10'\"L '#9'c #00B100\",'#13#10'\"M '#9'c #00B800\",'#13#10\n  +'\"N '#9'c #9494B8\",'#13#10'\"O '#9'c #0D1458\",'#13#10'\"P '#9'c #000A4F\",'#13\n  +#10'\"Q '#9'c #002836\",'#13#10'\"R '#9'c #006708\",'#13#10'\"S '#9'c #00710D\",'\n  +#13#10'\"T '#9'c #002B3D\",'#13#10'\"U '#9'c #000E4F\",'#13#10'\"V '#9'c #000952\"'\n  +','#13#10'\"W '#9'c #002842\",'#13#10'\"X '#9'c #008015\",'#13#10'\"Y '#9'c #2727'\n  +'71\",'#13#10'\"Z '#9'c #C9C9DB\",'#13#10'\"` '#9'c #1F305A\",'#13#10'\" .'#9'c #0'\n  +'03921\",'#13#10'\"..'#9'c #001C3F\",'#13#10'\"+.'#9'c #001B42\",'#13#10'\"@.'#9'c'\n  +' #000554\",'#13#10'\"#.'#9'c #000753\",'#13#10'\"$.'#9'c #004B2B\",'#13#10'\"%.'#9\n  +'c #005627\",'#13#10'\"&.'#9'c #00114E\",'#13#10'\"*.'#9'c #008615\",'#13#10'\"=.'\n  +#9'c #C0C0D5\",'#13#10'\"-.'#9'c #2A415B\",'#13#10'\";.'#9'c #005209\",'#13#10'\">'\n  +'.'#9'c #005C06\",'#13#10'\",.'#9'c #003F23\",'#13#10'\"''.'#9'c #00491F\",'#13#10\n  +'\").'#9'c #003434\",'#13#10'\"!.'#9'c #005E1D\",'#13#10'\"~.'#9'c #00850F\",'#13\n  +#10'\"{.'#9'c #002C41\",'#13#10'\"].'#9'c #FDFDFD\",'#13#10'\"^.'#9'c #424283\",'\n  +#13#10'\"/.'#9'c #001446\",'#13#10'\"(.'#9'c #003829\",'#13#10'\"_.'#9'c #006E02\"'\n  +','#13#10'\":.'#9'c #001D43\",'#13#10'\"<.'#9'c #008505\",'#13#10'\"[.'#9'c #000F'\n  +'50\",'#13#10'\"}.'#9'c #000D51\",'#13#10'\"|.'#9'c #FCFCFD\",'#13#10'\"1.'#9'c #4'\n  +'66E5D\",'#13#10'\"2.'#9'c #002733\",'#13#10'\"3.'#9'c #000B4D\",'#13#10'\"4.'#9'c'\n  +' #002739\",'#13#10'\"5.'#9'c #000E50\",'#13#10'\"6.'#9'c #9898BB\",'#13#10'\"7.'#9\n  +'c #608D68\",'#13#10'\"8.'#9'c #006002\",'#13#10'\"9.'#9'c #000454\",'#13#10'\"0.'\n  +#9'c #000652\",'#13#10'\"a.'#9'c #003433\",'#13#10'\"b.'#9'c #00601C\",'#13#10'\"c'\n  +'.'#9'c #008B05\",'#13#10'\"d.'#9'c #004033\",'#13#10'\"e.'#9'c #007419\",'#13#10\n  +'\"f.'#9'c #00343E\",'#13#10'\"g.'#9'c #0ABA0A\",'#13#10'\"h.'#9'c #B7B7CF\",'#13\n  +#10'\"i.'#9'c #313475\",'#13#10'\"j.'#9'c #18443D\",'#13#10'\"k.'#9'c #002537\",'\n  +#13#10'\"l.'#9'c #001D40\",'#13#10'\"m.'#9'c #000A51\",'#13#10'\"n.'#9'c #004A2B\"'\n  +','#13#10'\"o.'#9'c #00164B\",'#13#10'\"p.'#9'c #000057\",'#13#10'\"q.'#9'c #0994'\n  +'19\",'#13#10'\"r.'#9'c #9CE39C\",'#13#10'\"s.'#9'c #191968\",'#13#10'\"t.'#9'c #A'\n  +'BABC7\",'#13#10'\"u.'#9'c #BCBCD3\",'#13#10'\"v.'#9'c #252570\",'#13#10'\"w.'#9'c'\n  +' #05055B\",'#13#10'\"x.'#9'c #111460\",'#13#10'\"y.'#9'c #2F4267\",'#13#10'\"z.'#9\n  +'c #579660\",'#13#10'\"A.'#9'c #3D993D\",'#13#10'\"B.'#9'c #1A8C1A\",'#13#10'\"C.'\n  +#9'c #00710E\",'#13#10'\"D.'#9'c #032B41\",'#13#10'\"E.'#9'c #040F54\",'#13#10'\"F'\n  +'.'#9'c #060E57\",'#13#10'\"G.'#9'c #1F3560\",'#13#10'\"H.'#9'c #06085A\",'#13#10\n  +'\"I.'#9'c #3D407E\",'#13#10'\"J.'#9'c #333379\",'#13#10'\"K.'#9'c #F9FCF9\",'#13\n  +#10'\"L.'#9'c #9C9CBE\",'#13#10'\"  . . . . + + + + + + + + + + + @ @ @ + + + +'\n  +' + \",'#13#10'\"+ + # . $ % & * = - ; > , @ @ '' @ ) @ ! @ @ + + \",'#13#10'\"+'\n  +' + ~ . { ] ] ] ] ] ] ] @ ) ^ @ / ( / @ ^ ) @ + \",'#13#10'\"+ _ : < [ ] ] ] ]'\n  +' ] ] ] @ ^ ( ( ( ( ( ( ( ^ @ + \",'#13#10'\"+ } . | ] ] ] ] ] ] ] ] 1 @ ( 2 3'\n  +' 4 5 6 ( @ ! + \",'#13#10'\"+ 7 . 8 9 0 a b ] c d @ @ / ( e f g h i ( / @ @ \"'\n  ,','#13#10'\"j k l m n o p a c q r @ ) ( ( 4 s + g 4 ( ( ) @ \",'#13#10'\"t . u '\n  +'v n o p a c q r @ @ / ( w x g y 5 ( / @ @ \",'#13#10'\"z . A v n o p a c q r '\n  +'B C @ ) 2 w 4 5 D ( @ ! + \",'#13#10'\". . E F F o p a c q r B @ ^ ( ( ( ( ( '\n  +'( ( ^ @ + \",'#13#10'\"+ + G v n o p a c q r B @ ) ^ @ / ( / @ ^ ) @ + \",'#13\n  +#10'\"+ + G v n o p a c q r B H @ @ I @ ) @ ! @ @ + + \",'#13#10'\"+ + G v n o '\n  +'p a c q r B H J K L @ @ @ + + + + + \",'#13#10'\"+ + G v n o p a c q r B H J '\n  +'K L M + + + + + + + \",'#13#10'\"+ + G v n o p a c q r B H J K L M + + + + + '\n  +'+ + \",'#13#10'\"+ N O F P Q R a c S T U V W X L M . Y + + + + + \",'#13#10'\"Z'\n  +' . `  .... +.a [ @.#.$.%.&.. *.M . Y + + + + + \",'#13#10'\"=.. -.;.>.,.''.a '\n  +').. !.B H ~.. {.M . Y + + + + + \",'#13#10'\"].^.. . /.(._.a :.. <.B H J [.}.'\n  +'M . Y + + + + + \",'#13#10'\"+ |.1.2.3.. 4.a :.. <.B H J 5.5.M . Y + + + + + '\n  +'\",'#13#10'\"6.z 7.v 8.9.0.a a.. b.c.d.e.. f.g.. Y + + + + + \",'#13#10'\"h.. i'\n  +'.j.k.. l.a [ @.m.n.o.. p.q.r.. s.t.t.t.u.+ \",'#13#10'\"+ 6.v.w.x.y.z.A.B.C.D'\n  +'.E.F.G.H.I.+ . . . . . J.+ \",'#13#10'\"+ + + + + + + + + K.+ + + + j L.+ + +'\n  +' + + + + + \"};'#13#10\n]);\nLazarusResources.Add('TZSqlMonitor','XPM',[\n  '/* XPM */'#13#10'static char * TZSqlMonitor.xpm_xpm[] = {'#13#10'\"24 24 230 '\n  +'2\",'#13#10'\"  '#9'c #23236E\",'#13#10'\". '#9'c #000058\",'#13#10'\"+ '#9'c Non'\n  +'e\",'#13#10'\"@ '#9'c #C8C8DA\",'#13#10'\"# '#9'c #2F2F76\",'#13#10'\"$ '#9'c #DA'\n  +'EBDA\",'#13#10'\"% '#9'c #ACD5AC\",'#13#10'\"& '#9'c #89C489\",'#13#10'\"* '#9'c '\n  +'#65B265\",'#13#10'\"= '#9'c #42A042\",'#13#10'\"- '#9'c #229022\",'#13#10'\"; '#9\n  +'c #349934\",'#13#10'\"> '#9'c #58AB58\",'#13#10'\", '#9'c #698968\",'#13#10'\"'' '\n  +#9'c #4C544B\",'#13#10'\") '#9'c #3E3F3E\",'#13#10'\"! '#9'c #414141\",'#13#10'\"~'\n  +' '#9'c #404040\",'#13#10'\"{ '#9'c #3D3E3F\",'#13#10'\"] '#9'c #43443C\",'#13#10\n  +'\"^ '#9'c #A8A9A7\",'#13#10'\"/ '#9'c #616197\",'#13#10'\"( '#9'c #2B5C53\",'#13\n  +#10'\"_ '#9'c #007F00\",'#13#10'\": '#9'c #374A35\",'#13#10'\"< '#9'c #A3A4A1\",'\n  +#13#10'\"[ '#9'c #E1DCE1\",'#13#10'\"} '#9'c #D8D2DB\",'#13#10'\"| '#9'c #D8D2DA\"'\n  +','#13#10'\"1 '#9'c #D9D3DC\",'#13#10'\"2 '#9'c #D7D2D9\",'#13#10'\"3 '#9'c #9695'\n  +'92\",'#13#10'\"4 '#9'c #595B57\",'#13#10'\"5 '#9'c #F4F4F7\",'#13#10'\"6 '#9'c #1'\n  +'11163\",'#13#10'\"7 '#9'c #020458\",'#13#10'\"8 '#9'c #00700A\",'#13#10'\"9 '#9'c'\n  +' #84B454\",'#13#10'\"0 '#9'c #699A39\",'#13#10'\"a '#9'c #72A145\",'#13#10'\"b '#9\n  +'c #71A143\",'#13#10'\"c '#9'c #72A144\",'#13#10'\"d '#9'c #699A38\",'#13#10'\"e '\n  +#9'c #85B556\",'#13#10'\"f '#9'c #C3C4BF\",'#13#10'\"g '#9'c #ACACC8\",'#13#10'\"h'\n  +' '#9'c #162557\",'#13#10'\"i '#9'c #007800\",'#13#10'\"j '#9'c #3F403F\",'#13#10\n  +'\"k '#9'c #679B36\",'#13#10'\"l '#9'c #70A241\",'#13#10'\"m '#9'c #6FA140\",'#13\n  +#10'\"n '#9'c #679E35\",'#13#10'\"o '#9'c #699A3A\",'#13#10'\"p '#9'c #BABBB6\",'\n  +#13#10'\"q '#9'c #4B4B89\",'#13#10'\"r '#9'c #3C5E5C\",'#13#10'\"s '#9'c #005D00\"'\n  +','#13#10'\"t '#9'c #006A00\",'#13#10'\"u '#9'c #007300\",'#13#10'\"v '#9'c #0079'\n  +'00\",'#13#10'\"w '#9'c #007D00\",'#13#10'\"x '#9'c #008000\",'#13#10'\"y '#9'c #0'\n  +'08100\",'#13#10'\"z '#9'c #008500\",'#13#10'\"A '#9'c #DBD4DD\",'#13#10'\"B '#9'c'\n  +' #73A145\",'#13#10'\"C '#9'c #77A74B\",'#13#10'\"D '#9'c #76A649\",'#13#10'\"E '#9\n  +'c #77A64A\",'#13#10'\"F '#9'c #70A240\",'#13#10'\"G '#9'c #BBBDB8\",'#13#10'\"H '\n  +#9'c #E8E8EF\",'#13#10'\"I '#9'c #0A0A5E\",'#13#10'\"J '#9'c #0D0D60\",'#13#10'\"K'\n  +' '#9'c #598A5E\",'#13#10'\"L '#9'c #006400\",'#13#10'\"M '#9'c #006B00\",'#13#10\n  +'\"N '#9'c #007200\",'#13#10'\"O '#9'c #008700\",'#13#10'\"P '#9'c #008E00\",'#13\n  +#10'\"Q '#9'c #009500\",'#13#10'\"R '#9'c #404140\",'#13#10'\"S '#9'c #D4CDD7\",'\n  +#13#10'\"T '#9'c #78A54B\",'#13#10'\"U '#9'c #79AA4B\",'#13#10'\"V '#9'c #81AF56\"'\n  +','#13#10'\"W '#9'c #7FAE53\",'#13#10'\"X '#9'c #7FAF54\",'#13#10'\"Y '#9'c #7AAC'\n  +'4C\",'#13#10'\"Z '#9'c #78A54C\",'#13#10'\"` '#9'c #B6B7B3\",'#13#10'\" .'#9'c #9'\n  +'797BA\",'#13#10'\"..'#9'c #575790\",'#13#10'\"+.'#9'c #5F945F\",'#13#10'\"@.'#9'c'\n  +' #D1CCD2\",'#13#10'\"#.'#9'c #538B1D\",'#13#10'\"$.'#9'c #457F0D\",'#13#10'\"%.'#9\n  +'c #4F8619\",'#13#10'\"&.'#9'c #4C8517\",'#13#10'\"*.'#9'c #4D8618\",'#13#10'\"=.'\n  +#9'c #44800C\",'#13#10'\"-.'#9'c #538A1D\",'#13#10'\";.'#9'c #B7B8B3\",'#13#10'\">'\n  +'.'#9'c #38387C\",'#13#10'\",.'#9'c #C7C7DA\",'#13#10'\"''.'#9'c #3D3E3C\",'#13#10\n  +'\").'#9'c #CBC9CA\",'#13#10'\"!.'#9'c #DAECC8\",'#13#10'\"~.'#9'c #BCCDAD\",'#13\n  +#10'\"{.'#9'c #C4D4B5\",'#13#10'\"].'#9'c #C3D2B3\",'#13#10'\"^.'#9'c #C4D2B3\",'\n  +#13#10'\"/.'#9'c #BFCFAE\",'#13#10'\"(.'#9'c #D9EBC7\",'#13#10'\"_.'#9'c #B7B9B4\"'\n  +','#13#10'\":.'#9'c #030359\",'#13#10'\"<.'#9'c #020358\",'#13#10'\"[.'#9'c #0002'\n  +'55\",'#13#10'\"}.'#9'c #424440\",'#13#10'\"|.'#9'c #959693\",'#13#10'\"1.'#9'c #F'\n  +'FF7FF\",'#13#10'\"2.'#9'c #FFF9FF\",'#13#10'\"3.'#9'c #FFFAFF\",'#13#10'\"4.'#9'c'\n  +' #91938F\",'#13#10'\"5.'#9'c #118311\",'#13#10'\"6.'#9'c #3F6A3E\",'#13#10'\"7.'#9\n  +'c #898B86\",'#13#10'\"8.'#9'c #7E817B\",'#13#10'\"9.'#9'c #80827C\",'#13#10'\"0.'\n  +#9'c #898B87\",'#13#10'\"a.'#9'c #727370\",'#13#10'\"b.'#9'c #CBCCCB\",'#13#10'\"c'\n  +'.'#9'c #009C00\",'#13#10'\"d.'#9'c #00A300\",'#13#10'\"e.'#9'c #00AA00\",'#13#10\n  +'\"f.'#9'c #00B100\",'#13#10'\"g.'#9'c #00B800\",'#13#10'\"h.'#9'c #9494B8\",'#13\n  +#10'\"i.'#9'c #00094F\",'#13#10'\"j.'#9'c #002636\",'#13#10'\"k.'#9'c #006008\",'\n  +#13#10'\"l.'#9'c #006B0D\",'#13#10'\"m.'#9'c #00293D\",'#13#10'\"n.'#9'c #000D4F\"'\n  +','#13#10'\"o.'#9'c #000952\",'#13#10'\"p.'#9'c #002642\",'#13#10'\"q.'#9'c #007B'\n  +'15\",'#13#10'\"r.'#9'c #272771\",'#13#10'\"s.'#9'c #C9C9DB\",'#13#10'\"t.'#9'c #5'\n  +'4548F\",'#13#10'\"u.'#9'c #3B5C5C\",'#13#10'\"v.'#9'c #001A3F\",'#13#10'\"w.'#9'c'\n  +' #001942\",'#13#10'\"x.'#9'c #006A0A\",'#13#10'\"y.'#9'c #000554\",'#13#10'\"z.'#9\n  +'c #000753\",'#13#10'\"A.'#9'c #00482B\",'#13#10'\"B.'#9'c #005227\",'#13#10'\"C.'\n  +#9'c #00114E\",'#13#10'\"D.'#9'c #008115\",'#13#10'\"E.'#9'c #C0C0D5\",'#13#10'\"F'\n  +'.'#9'c #7171A2\",'#13#10'\"G.'#9'c #54835E\",'#13#10'\"H.'#9'c #005606\",'#13#10\n  +'\"I.'#9'c #003B23\",'#13#10'\"J.'#9'c #00451F\",'#13#10'\"K.'#9'c #003134\",'#13\n  +#10'\"L.'#9'c #00591D\",'#13#10'\"M.'#9'c #007F0F\",'#13#10'\"N.'#9'c #002A41\",'\n  +#13#10'\"O.'#9'c #FDFDFD\",'#13#10'\"P.'#9'c #424283\",'#13#10'\"Q.'#9'c #001246\"'\n  +','#13#10'\"R.'#9'c #003429\",'#13#10'\"S.'#9'c #006802\",'#13#10'\"T.'#9'c #001B'\n  +'43\",'#13#10'\"U.'#9'c #007F05\",'#13#10'\"V.'#9'c #000E50\",'#13#10'\"W.'#9'c #0'\n  +'00C51\",'#13#10'\"X.'#9'c #FCFCFD\",'#13#10'\"Y.'#9'c #BEBED4\",'#13#10'\"Z.'#9'c'\n  ,' #273E5A\",'#13#10'\"`.'#9'c #000A4D\",'#13#10'\" +'#9'c #002539\",'#13#10'\".+'#9\n  +'c #007E05\",'#13#10'\"++'#9'c #9898BB\",'#13#10'\"@+'#9'c #E7E7EF\",'#13#10'\"#+'\n  +#9'c #6A9C6A\",'#13#10'\"$+'#9'c #005A02\",'#13#10'\"%+'#9'c #000354\",'#13#10'\"&'\n  +'+'#9'c #000652\",'#13#10'\"*+'#9'c #003133\",'#13#10'\"=+'#9'c #005B1C\",'#13#10\n  +'\"-+'#9'c #008405\",'#13#10'\";+'#9'c #003D33\",'#13#10'\">+'#9'c #006F19\",'#13\n  +#10'\",+'#9'c #00323E\",'#13#10'\"''+'#9'c #B7B7CF\",'#13#10'\")+'#9'c #39397D\",'\n  +#13#10'\"!+'#9'c #7F85A4\",'#13#10'\"~+'#9'c #0F2C46\",'#13#10'\"{+'#9'c #001C40\"'\n  +','#13#10'\"]+'#9'c #000951\",'#13#10'\"^+'#9'c #00472B\",'#13#10'\"/+'#9'c #0015'\n  +'4B\",'#13#10'\"(+'#9'c #000057\",'#13#10'\"_+'#9'c #008C0F\",'#13#10'\":+'#9'c #0'\n  +'CB40C\",'#13#10'\"<+'#9'c #191968\",'#13#10'\"[+'#9'c #ABABC7\",'#13#10'\"}+'#9'c'\n  +' #BCBCD3\",'#13#10'\"|+'#9'c #252570\",'#13#10'\"1+'#9'c #06065B\",'#13#10'\"2+'#9\n  +'c #181868\",'#13#10'\"3+'#9'c #404B78\",'#13#10'\"4+'#9'c #76A57F\",'#13#10'\"5+'\n  +#9'c #61A861\",'#13#10'\"6+'#9'c #3D993D\",'#13#10'\"7+'#9'c #157523\",'#13#10'\"8'\n  +'+'#9'c #00273E\",'#13#10'\"9+'#9'c #010D50\",'#13#10'\"0+'#9'c #030C55\",'#13#10\n  +'\"a+'#9'c #163156\",'#13#10'\"b+'#9'c #040859\",'#13#10'\"c+'#9'c #283969\",'#13\n  +#10'\"d+'#9'c #EDF9ED\",'#13#10'\"e+'#9'c #333379\",'#13#10'\"f+'#9'c #F9FCF9\",'\n  +#13#10'\"g+'#9'c #9C9CBE\",'#13#10'\"  . . . . + + + + + + + + + + + + + + + + '\n  +'+ + + \",'#13#10'\"+ + @ . # $ % & * = - ; > , '' ) ! ~ ~ ~ ~ { ] ^ \",'#13#10\n  +'\"+ + / . ( _ _ _ _ _ _ _ _ : < [ } | 1 } 2 [ 3 4 \",'#13#10'\"+ 5 6 7 8 _ _ _'\n  +' _ _ _ _ _ ) [ 9 0 a b c d e f ) \",'#13#10'\"+ g . h i _ _ _ _ _ _ _ _ j } 0'\n  +' k l m l n o p ! \",'#13#10'\"+ q . r s t u v w _ x y z j A B m C D E F B G j'\n  +' \",'#13#10'\"H I J K s L M N v x O P Q R S T U V W X Y Z ` R \",'#13#10'\" .. '\n  +'..+.s L M N v x O P Q ! @.#.$.%.&.*.=.-.;.! \",'#13#10'\">.. ,.+.s L M N v x '\n  +'O P Q ''.).!.~.{.].^./.(._.''.\",'#13#10'\". . :.<.[.L M N v x O P Q }.|.+ 1.'\n  +'2.2.2.3.+ 4.}.\",'#13#10'\"+ + + +.s L M N v x O P Q 5.6.7.8.8.8.8.9.0.a.b.\",'\n  +#13#10'\"+ + + +.s L M N v x O P Q c.d.e.f.g.+ + + + + + \",'#13#10'\"+ + + +.s'\n  +' L M N v x O P Q c.d.e.f.g.+ + + + + + \",'#13#10'\"+ + + +.s L M N v x O P Q'\n  +' c.d.e.f.g.+ + + + + + \",'#13#10'\"+ + + +.s L M N v x O P Q c.d.e.f.g.+ + +'\n  +' + + + \",'#13#10'\"+ h.  <.i.j.k.N v l.m.n.o.p.q.e.f.. r.+ + + + + \",'#13#10\n  +'\"s.. t.u.v.. w.N x.y.z.A.B.C.. D.f.. r.+ + + + + \",'#13#10'\"E.. F.G.H.I.J.N'\n  +' K.. L.P Q M.. N.f.. r.+ + + + + \",'#13#10'\"O.P.. . Q.R.S.N T.. U.P Q c.V.W'\n  +'.f.. r.+ + + + + \",'#13#10'\"+ X.Y.Z.`..  +N T.. .+P Q c.V.V.f.. r.+ + + + +'\n  +' \",'#13#10'\"++>.@+#+$+%+&+N *+. =+-+;+>+. ,+f.. r.+ + + + + \",'#13#10'\"''+.'\n  +' )+!+~+. {+N x.y.]+^+/+. (+_+:+. <+[+[+[+}++ \",'#13#10'\"+ ++|+1+2+3+4+5+6+7'\n  +'+8+9+0+a+b+c+d+. . . . . e++ \",'#13#10'\"+ + + + + + + + + + f++ + + H g++ +'\n  +' + + + + + + \"};'#13#10\n]);\nLazarusResources.Add('TZSqlMetaData','XPM',[\n  '/* XPM */'#13#10'static char * TZSqlMetaData.xpm_xpm[] = {'#13#10'\"24 24 173'\n  +' 2\",'#13#10'\"  '#9'c #23236E\",'#13#10'\". '#9'c #000058\",'#13#10'\"+ '#9'c No'\n  +'ne\",'#13#10'\"@ '#9'c #C8C8DA\",'#13#10'\"# '#9'c #282B6F\",'#13#10'\"$ '#9'c #A'\n  +'CD5AC\",'#13#10'\"% '#9'c #89C489\",'#13#10'\"& '#9'c #65B265\",'#13#10'\"* '#9'c'\n  +' #42A042\",'#13#10'\"= '#9'c #229022\",'#13#10'\"- '#9'c #349934\",'#13#10'\"; '#9\n  +'c #58AB58\",'#13#10'\"> '#9'c #7CBD7C\",'#13#10'\", '#9'c #A0CEA0\",'#13#10'\"'' '\n  +#9'c #C4E0C4\",'#13#10'\") '#9'c #FCFDFC\",'#13#10'\"! '#9'c #E7D99B\",'#13#10'\"~'\n  +' '#9'c #CDAF2A\",'#13#10'\"{ '#9'c #C4A000\",'#13#10'\"] '#9'c #595D90\",'#13#10\n  +'\"^ '#9'c #004627\",'#13#10'\"/ '#9'c #007F00\",'#13#10'\"( '#9'c #259225\",'#13\n  +#10'\"_ '#9'c #BDC470\",'#13#10'\": '#9'c #FCE94F\",'#13#10'\"< '#9'c #F4F4F7\",'\n  +#13#10'\"[ '#9'c #060B58\",'#13#10'\"} '#9'c #000355\",'#13#10'\"| '#9'c #00700A\"'\n  +','#13#10'\"1 '#9'c #A79C03\",'#13#10'\"2 '#9'c #EDD400\",'#13#10'\"3 '#9'c #ACAC'\n  +'C8\",'#13#10'\"4 '#9'c #001F41\",'#13#10'\"5 '#9'c #A40000\",'#13#10'\"6 '#9'c #4'\n  +'B4B89\",'#13#10'\"7 '#9'c #003B1F\",'#13#10'\"8 '#9'c #006A00\",'#13#10'\"9 '#9'c'\n  +' #007300\",'#13#10'\"0 '#9'c #007900\",'#13#10'\"a '#9'c #007D00\",'#13#10'\"b '#9\n  +'c #008000\",'#13#10'\"c '#9'c #008100\",'#13#10'\"d '#9'c #008500\",'#13#10'\"e '\n  +#9'c #EF2929\",'#13#10'\"f '#9'c #204A87\",'#13#10'\"g '#9'c #A3A230\",'#13#10'\"h'\n  +' '#9'c #E8E8EF\",'#13#10'\"i '#9'c #0A0A5E\",'#13#10'\"j '#9'c #040758\",'#13#10\n  +'\"k '#9'c #005705\",'#13#10'\"l '#9'c #006400\",'#13#10'\"m '#9'c #006B00\",'#13\n  +#10'\"n '#9'c #007200\",'#13#10'\"o '#9'c #008700\",'#13#10'\"p '#9'c #008E00\",'\n  +#13#10'\"q '#9'c #009500\",'#13#10'\"r '#9'c #CC0000\",'#13#10'\"s '#9'c #709DCD\"'\n  +','#13#10'\"t '#9'c #9797BA\",'#13#10'\"u '#9'c #20325A\",'#13#10'\"v '#9'c #005D'\n  +'00\",'#13#10'\"w '#9'c #804550\",'#13#10'\"x '#9'c #5A87BA\",'#13#10'\"y '#9'c #9'\n  +'49157\",'#13#10'\"z '#9'c #38387C\",'#13#10'\"A '#9'c #4A735D\",'#13#10'\"B '#9'c'\n  +' #729FCF\",'#13#10'\"C '#9'c #4070AC\",'#13#10'\"D '#9'c #010158\",'#13#10'\"E '#9\n  +'c #000255\",'#13#10'\"F '#9'c #6C465B\",'#13#10'\"G '#9'c #3D68A0\",'#13#10'\"H '\n  +#9'c #5280B8\",'#13#10'\"I '#9'c #3465A4\",'#13#10'\"J '#9'c #37629B\",'#13#10'\"K'\n  +' '#9'c #B8C1CE\",'#13#10'\"L '#9'c #5F945F\",'#13#10'\"M '#9'c #009C00\",'#13#10\n  +'\"N '#9'c #00A300\",'#13#10'\"O '#9'c #00AA00\",'#13#10'\"P '#9'c #00B100\",'#13\n  +#10'\"Q '#9'c #00B800\",'#13#10'\"R '#9'c #9494B8\",'#13#10'\"S '#9'c #0D1458\",'\n  +#13#10'\"T '#9'c #000A4F\",'#13#10'\"U '#9'c #002836\",'#13#10'\"V '#9'c #006708\"'\n  +','#13#10'\"W '#9'c #00710D\",'#13#10'\"X '#9'c #002B3D\",'#13#10'\"Y '#9'c #000E'\n  +'4F\",'#13#10'\"Z '#9'c #000952\",'#13#10'\"` '#9'c #002842\",'#13#10'\" .'#9'c #0'\n  +'08015\",'#13#10'\"..'#9'c #272771\",'#13#10'\"+.'#9'c #C9C9DB\",'#13#10'\"@.'#9'c'\n  +' #1F305A\",'#13#10'\"#.'#9'c #003921\",'#13#10'\"$.'#9'c #001C3F\",'#13#10'\"%.'#9\n  +'c #001B42\",'#13#10'\"&.'#9'c #000554\",'#13#10'\"*.'#9'c #000753\",'#13#10'\"=.'\n  +#9'c #004B2B\",'#13#10'\"-.'#9'c #005627\",'#13#10'\";.'#9'c #00114E\",'#13#10'\">'\n  +'.'#9'c #008615\",'#13#10'\",.'#9'c #C0C0D5\",'#13#10'\"''.'#9'c #2A415B\",'#13#10\n  +'\").'#9'c #005209\",'#13#10'\"!.'#9'c #005C06\",'#13#10'\"~.'#9'c #003F23\",'#13\n  +#10'\"{.'#9'c #00491F\",'#13#10'\"].'#9'c #003434\",'#13#10'\"^.'#9'c #005E1D\",'\n  +#13#10'\"/.'#9'c #00850F\",'#13#10'\"(.'#9'c #002C41\",'#13#10'\"_.'#9'c #FDFDFD\"'\n  +','#13#10'\":.'#9'c #424283\",'#13#10'\"<.'#9'c #001446\",'#13#10'\"[.'#9'c #0038'\n  +'29\",'#13#10'\"}.'#9'c #006E02\",'#13#10'\"|.'#9'c #001D43\",'#13#10'\"1.'#9'c #0'\n  +'08505\",'#13#10'\"2.'#9'c #000F50\",'#13#10'\"3.'#9'c #000D51\",'#13#10'\"4.'#9'c'\n  +' #FCFCFD\",'#13#10'\"5.'#9'c #466E5D\",'#13#10'\"6.'#9'c #002733\",'#13#10'\"7.'#9\n  +'c #000B4D\",'#13#10'\"8.'#9'c #002739\",'#13#10'\"9.'#9'c #000E50\",'#13#10'\"0.'\n  +#9'c #9898BB\",'#13#10'\"a.'#9'c #608D68\",'#13#10'\"b.'#9'c #006002\",'#13#10'\"c'\n  +'.'#9'c #000454\",'#13#10'\"d.'#9'c #000652\",'#13#10'\"e.'#9'c #003433\",'#13#10\n  +'\"f.'#9'c #00601C\",'#13#10'\"g.'#9'c #008B05\",'#13#10'\"h.'#9'c #004033\",'#13\n  +#10'\"i.'#9'c #007419\",'#13#10'\"j.'#9'c #00343E\",'#13#10'\"k.'#9'c #0ABA0A\",'\n  +#13#10'\"l.'#9'c #B7B7CF\",'#13#10'\"m.'#9'c #313475\",'#13#10'\"n.'#9'c #18443D\"'\n  +','#13#10'\"o.'#9'c #002537\",'#13#10'\"p.'#9'c #001D40\",'#13#10'\"q.'#9'c #000A'\n  +'51\",'#13#10'\"r.'#9'c #004A2B\",'#13#10'\"s.'#9'c #00164B\",'#13#10'\"t.'#9'c #0'\n  +'00057\",'#13#10'\"u.'#9'c #099419\",'#13#10'\"v.'#9'c #9CE39C\",'#13#10'\"w.'#9'c'\n  +' #191968\",'#13#10'\"x.'#9'c #ABABC7\",'#13#10'\"y.'#9'c #BCBCD3\",'#13#10'\"z.'#9\n  +'c #252570\",'#13#10'\"A.'#9'c #05055B\",'#13#10'\"B.'#9'c #111460\",'#13#10'\"C.'\n  +#9'c #2F4267\",'#13#10'\"D.'#9'c #579660\",'#13#10'\"E.'#9'c #3D993D\",'#13#10'\"F'\n  +'.'#9'c #1A8C1A\",'#13#10'\"G.'#9'c #00710E\",'#13#10'\"H.'#9'c #032B41\",'#13#10\n  +'\"I.'#9'c #040F54\",'#13#10'\"J.'#9'c #060E57\",'#13#10'\"K.'#9'c #1F3560\",'#13\n  +#10'\"L.'#9'c #06085A\",'#13#10'\"M.'#9'c #3D407E\",'#13#10'\"N.'#9'c #333379\",'\n  +#13#10'\"O.'#9'c #F9FCF9\",'#13#10'\"P.'#9'c #9C9CBE\",'#13#10'\"  . . . . + + + '\n  +'+ + + + + + + + + + + + + + + + \",'#13#10'\"+ + @ . # $ % & * = - ; > , '' )'\n  +' + ! ~ { ~ ! + + \",'#13#10'\"+ + ] . ^ / / / / / / / / / / ( _ { : : : { ! +'\n  +' \",'#13#10'\"+ < [ } | / / / / / / / / / / / 1 : 2 2 2 : ~ + \",'#13#10'\"+ 3 '\n  ,'. 4 / / / / / / / / 5 5 5 5 5 5 2 2 2 : { + \",'#13#10'\"+ 6 . 7 8 9 0 a / b '\n  +'c d 5 e e e e 5 f g 2 : ~ + \",'#13#10'\"h i j k l m n 0 b o p q 5 e r r e f '\n  +'s f : { ! + \",'#13#10'\"t . u v l m n 0 b o p q 5 e r r w f x f y ! + + \",'\n  +#13#10'\"z . A v l m n 0 b o p q 5 e r r f B C B f + + + \",'#13#10'\". . D E E'\n  +' m n 0 b o p q 5 e e F G H I H J K + + \",'#13#10'\"+ + L v l m n 0 b o p q 5'\n  +' 5 5 f B B B B B f + + \",'#13#10'\"+ + L v l m n 0 b o p q M N O f f f f f f'\n  +' f + + \",'#13#10'\"+ + L v l m n 0 b o p q M N O P Q + + + + + + + \",'#13#10\n  +'\"+ + L v l m n 0 b o p q M N O P Q + + + + + + + \",'#13#10'\"+ + L v l m n 0'\n  +' b o p q M N O P Q + + + + + + + \",'#13#10'\"+ R S E T U V 0 b W X Y Z `  .P'\n  +' Q . ..+ + + + + \",'#13#10'\"+.. @.#.$.. %.0 | &.*.=.-.;.. >.Q . ..+ + + + +'\n  +' \",'#13#10'\",.. ''.).!.~.{.0 ].. ^.q M /.. (.Q . ..+ + + + + \",'#13#10'\"_.:'\n  +'.. . <.[.}.0 |.. 1.q M N 2.3.Q . ..+ + + + + \",'#13#10'\"+ 4.5.6.7.. 8.0 |..'\n  +' 1.q M N 9.9.Q . ..+ + + + + \",'#13#10'\"0.z a.v b.c.d.0 e.. f.g.h.i.. j.k..'\n  +' ..+ + + + + \",'#13#10'\"l.. m.n.o.. p.0 | &.q.r.s.. t.u.v.. w.x.x.x.y.+ \",'\n  +#13#10'\"+ 0.z.A.B.C.D.E.F.G.H.I.J.K.L.M.+ . . . . . N.+ \",'#13#10'\"+ + + + +'\n  +' + + + + O.+ + + + h P.+ + + + + + + + \"};'#13#10\n]);\nLazarusResources.Add('TZSequence','XPM',[\n  '/* XPM */'#13#10'static char * TZSequence.xpm_xpm[] = {'#13#10'\"24 24 116 2\"'\n  +','#13#10'\"  '#9'c #23236E\",'#13#10'\". '#9'c #000058\",'#13#10'\"+ '#9'c None\"'\n  +','#13#10'\"@ '#9'c #FBC5C5\",'#13#10'\"# '#9'c #F55050\",'#13#10'\"$ '#9'c #F235'\n  +'35\",'#13#10'\"% '#9'c #C8C8DA\",'#13#10'\"& '#9'c #2F2F76\",'#13#10'\"* '#9'c #D'\n  +'AEBDA\",'#13#10'\"= '#9'c #ACD5AC\",'#13#10'\"- '#9'c #89C489\",'#13#10'\"; '#9'c'\n  +' #65B265\",'#13#10'\"> '#9'c #42A042\",'#13#10'\", '#9'c #229022\",'#13#10'\"'' '\n  +#9'c #349934\",'#13#10'\") '#9'c #58AB58\",'#13#10'\"! '#9'c #7CBD7C\",'#13#10'\"~'\n  +' '#9'c #A0CEA0\",'#13#10'\"{ '#9'c #D97667\",'#13#10'\"] '#9'c #F10101\",'#13#10\n  +'\"^ '#9'c #F10000\",'#13#10'\"/ '#9'c #F1CCCC\",'#13#10'\"( '#9'c #F10202\",'#13\n  +#10'\"_ '#9'c #F88787\",'#13#10'\": '#9'c #616197\",'#13#10'\"< '#9'c #2B5C53\",'\n  +#13#10'\"[ '#9'c #007F00\",'#13#10'\"} '#9'c #366200\",'#13#10'\"| '#9'c #EF0000\"'\n  +','#13#10'\"1 '#9'c #F4F4F7\",'#13#10'\"2 '#9'c #111163\",'#13#10'\"3 '#9'c #0204'\n  +'58\",'#13#10'\"4 '#9'c #00700A\",'#13#10'\"5 '#9'c #A52700\",'#13#10'\"6 '#9'c #A'\n  +'CACC8\",'#13#10'\"7 '#9'c #162557\",'#13#10'\"8 '#9'c #007800\",'#13#10'\"9 '#9'c'\n  +' #DB2A1E\",'#13#10'\"0 '#9'c #F1EBEB\",'#13#10'\"a '#9'c #4B4B89\",'#13#10'\"b '#9\n  +'c #3C5E5C\",'#13#10'\"c '#9'c #005D00\",'#13#10'\"d '#9'c #006A00\",'#13#10'\"e '\n  +#9'c #007300\",'#13#10'\"f '#9'c #007900\",'#13#10'\"g '#9'c #007D00\",'#13#10'\"h'\n  +' '#9'c #008000\",'#13#10'\"i '#9'c #008100\",'#13#10'\"j '#9'c #008500\",'#13#10\n  +'\"k '#9'c #008B00\",'#13#10'\"l '#9'c #DB2C1E\",'#13#10'\"m '#9'c #E8E8EF\",'#13\n  +#10'\"n '#9'c #0A0A5E\",'#13#10'\"o '#9'c #0D0D60\",'#13#10'\"p '#9'c #598A5E\",'\n  +#13#10'\"q '#9'c #006400\",'#13#10'\"r '#9'c #006B00\",'#13#10'\"s '#9'c #007200\"'\n  +','#13#10'\"t '#9'c #008700\",'#13#10'\"u '#9'c #008E00\",'#13#10'\"v '#9'c #0095'\n  +'00\",'#13#10'\"w '#9'c #009C00\",'#13#10'\"x '#9'c #A53300\",'#13#10'\"y '#9'c #9'\n  +'797BA\",'#13#10'\"z '#9'c #575790\",'#13#10'\"A '#9'c #5F945F\",'#13#10'\"B '#9'c'\n  +' #367D00\",'#13#10'\"C '#9'c #EF0100\",'#13#10'\"D '#9'c #38387C\",'#13#10'\"E '#9\n  +'c #C7C7DA\",'#13#10'\"F '#9'c #00A300\",'#13#10'\"G '#9'c #715A00\",'#13#10'\"H '\n  +#9'c #030359\",'#13#10'\"I '#9'c #020358\",'#13#10'\"J '#9'c #000255\",'#13#10'\"K'\n  +' '#9'c #00AA00\",'#13#10'\"L '#9'c #368800\",'#13#10'\"M '#9'c #A53900\",'#13#10\n  +'\"N '#9'c #00B100\",'#13#10'\"O '#9'c #00B800\",'#13#10'\"P '#9'c #4174B4\",'#13\n  +#10'\"Q '#9'c #B9C2CE\",'#13#10'\"R '#9'c #125827\",'#13#10'\"S '#9'c #B2C2D7\",'\n  +#13#10'\"T '#9'c #126A27\",'#13#10'\"U '#9'c #7F9EC7\",'#13#10'\"V '#9'c #5F88BC\"'\n  +','#13#10'\"W '#9'c #95AECE\",'#13#10'\"X '#9'c #7598C4\",'#13#10'\"Y '#9'c #3F73'\n  +'A8\",'#13#10'\"Z '#9'c #517FB9\",'#13#10'\"` '#9'c #7B9CC6\",'#13#10'\" .'#9'c #1'\n  +'27827\",'#13#10'\"..'#9'c #2A6464\",'#13#10'\"+.'#9'c #126127\",'#13#10'\"@.'#9'c'\n  +' #23664F\",'#13#10'\"#.'#9'c #4075A4\",'#13#10'\"$.'#9'c #125D27\",'#13#10'\"%.'#9\n  +'c #126627\",'#13#10'\"&.'#9'c #4677AE\",'#13#10'\"*.'#9'c #41768B\",'#13#10'\"=.'\n  +#9'c #2F6B75\",'#13#10'\"-.'#9'c #3F74A8\",'#13#10'\";.'#9'c #87A5CA\",'#13#10'\">'\n  +'.'#9'c #0ABA0A\",'#13#10'\",.'#9'c #0CB40C\",'#13#10'\"''.'#9'c #9CE39C\",'#13#10\n  +'\").'#9'c #B8C1CD\",'#13#10'\"!.'#9'c #3A7F4F\",'#13#10'\"~.'#9'c #0D930D\",'#13\n  +#10'\"{.'#9'c #30A830\",'#13#10'\"].'#9'c #54BD54\",'#13#10'\"^.'#9'c #78CD78\",'\n  +#13#10'\"/.'#9'c #9CDE9C\",'#13#10'\"(.'#9'c #EDF9ED\",'#13#10'\"_.'#9'c #F9FCF9\"'\n  +','#13#10'\"  . . . . + + + + + + + + + + + @ # $ $ # @ + + \",'#13#10'\"+ + % '\n  +'. & * = - ; > , '' ) ! ~ { ] ^ / / ^ ( _ + \",'#13#10'\"+ + : . < [ [ [ [ [ ['\n  +' [ [ [ } | ^ ^ / / ^ ^ ( @ \",'#13#10'\"+ 1 2 3 4 [ [ [ [ [ [ [ [ [ 5 ^ ^ ^ /'\n  +' / ^ ^ ^ # \",'#13#10'\"+ 6 . 7 8 [ [ [ [ [ [ [ [ [ 9 / / / 0 0 / / / $ \",'#13\n  +#10'\"+ a . b c d e f g [ h i j k l / / / 0 0 / / / $ \",'#13#10'\"m n o p c q '\n  +'r s f h t u v w x ^ ^ ^ / / ^ ^ ^ # \",'#13#10'\"y . z A c q r s f h t u v w '\n  +'B C ^ ^ / / ^ ^ ( @ \",'#13#10'\"D . E A c q r s f h t u v w F G C ^ / / ^ ( '\n  +'_ + \",'#13#10'\". . H I J q r s f h t u v w F K L M $ $ # @ + + \",'#13#10'\"+'\n  +' + + A c q r s f h t u v w F K N O + + + + + + \",'#13#10'\"+ + + A c P P P f'\n  +' h t u v w F K N O + + + + + + \",'#13#10'\"+ Q P P R P S P T P P u v w F K N'\n  +' O + + + + + + \",'#13#10'\"+ P S U P V W V P U S P v w F K N O + + + + + + \"'\n  +','#13#10'\"+ P U W W W W W W W U P v w F K N O + + + + + + \",'#13#10'\"+ Q P '\n  +'W X Y Z Y ` W P  .v w F K N O + + + + + + \",'#13#10'\"P P V W Y ..+.@.#.W V '\n  +'P P w F K N O + + + + + + \",'#13#10'\"P S W W Z $.r %.Z W W S P w F K N O + '\n  +'+ + + + + \",'#13#10'\"P P V W &.*.+.=.-.W V P P w F K N O + + + + + + \",'#13\n  +#10'\"+ Q P S X &.Z Y ;.W P  .v w F K N O + + + + + + \",'#13#10'\"+ P U W W W '\n  +'W W W W U P v w F K N >.+ + + + + + \",'#13#10'\"+ P S U P V W V P U S P v w '\n  +'F K ,.''.+ + + + + + \",'#13#10'\"+ + P P ).P S P !.P P ~.{.].^./.(.+ + + + +'\n  +' + + \",'#13#10'\"+ + + + + P P P + + _.+ + + + + + + + + + + + + \"};'#13#10\n]);\nLazarusResources.Add('TZIBEventAlerter','XPM',[\n  '/* XPM */'#13#10'static char * TZIBEventAlerter.xpm_xpm[] = {'#13#10'\"24 24 '\n  +'158 2\",'#13#10'\"  '#9'c #23236E\",'#13#10'\". '#9'c #000058\",'#13#10'\"+ '#9'c'\n  +' None\",'#13#10'\"@ '#9'c #B0B0B0\",'#13#10'\"# '#9'c #000000\",'#13#10'\"$ '#9'c'\n  +' #D4D4D4\",'#13#10'\"% '#9'c #C8C8DA\",'#13#10'\"& '#9'c #2F2F76\",'#13#10'\"* '#9\n  +'c #EBCF7C\",'#13#10'\"= '#9'c #616197\",'#13#10'\"- '#9'c #8D8DB4\",'#13#10'\"; '\n  +#9'c #584E1E\",'#13#10'\"> '#9'c #F2DB88\",'#13#10'\", '#9'c #F6EAB4\",'#13#10'\"'\n  +''' '#9'c #C4A94C\",'#13#10'\") '#9'c #403816\",'#13#10'\"! '#9'c #F4F4F7\",'#13\n  +#10'\"~ '#9'c #111163\",'#13#10'\"{ '#9'c #07075C\",'#13#10'\"] '#9'c #E2E2EC\",'\n  +#13#10'\"^ '#9'c #806A04\",'#13#10'\"/ '#9'c #E6CD62\",'#13#10'\"( '#9'c #FCFDDD\"'\n  +','#13#10'\"_ '#9'c #F9ECBF\",'#13#10'\": '#9'c #8B7826\",'#13#10'\"< '#9'c #C6B1'\n  +'65\",'#13#10'\"[ '#9'c #FAF3CF\",'#13#10'\"} '#9'c #FCF2BE\",'#13#10'\"| '#9'c #F'\n  +'4E18F\",'#13#10'\"1 '#9'c #BD9D37\",'#13#10'\"2 '#9'c #ACACC8\",'#13#10'\"3 '#9'c'\n  +' #424283\",'#13#10'\"4 '#9'c #E2BD3B\",'#13#10'\"5 '#9'c #FCFDAC\",'#13#10'\"6 '#9\n  +'c #F7E6A6\",'#13#10'\"7 '#9'c #FEFAE7\",'#13#10'\"8 '#9'c #FBEB9C\",'#13#10'\"9 '\n  +#9'c #C5AA4A\",'#13#10'\"0 '#9'c #594E1F\",'#13#10'\"a '#9'c #4B4B89\",'#13#10'\"b'\n  +' '#9'c #8F888B\",'#13#10'\"c '#9'c #E3C649\",'#13#10'\"d '#9'c #C1A342\",'#13#10\n  +'\"e '#9'c #FAF2C4\",'#13#10'\"f '#9'c #FEF8D3\",'#13#10'\"g '#9'c #FFFADA\",'#13\n  +#10'\"h '#9'c #FDF1A8\",'#13#10'\"i '#9'c #EED060\",'#13#10'\"j '#9'c #AF820E\",'\n  +#13#10'\"k '#9'c #E8E8EF\",'#13#10'\"l '#9'c #0A0A5E\",'#13#10'\"m '#9'c #0C0B5D\"'\n  +','#13#10'\"n '#9'c #D3B13C\",'#13#10'\"o '#9'c #797979\",'#13#10'\"p '#9'c #9D91'\n  +'53\",'#13#10'\"q '#9'c #FAE98D\",'#13#10'\"r '#9'c #FFF4B3\",'#13#10'\"s '#9'c #F'\n  +'FF5BC\",'#13#10'\"t '#9'c #FFF092\",'#13#10'\"u '#9'c #FDEB7A\",'#13#10'\"v '#9'c'\n  +' #F4D750\",'#13#10'\"w '#9'c #D8A717\",'#13#10'\"x '#9'c #9797BA\",'#13#10'\"y '#9\n  +'c #533A40\",'#13#10'\"z '#9'c #E4AC31\",'#13#10'\"A '#9'c #C08414\",'#13#10'\"B '\n  +#9'c #221E0C\",'#13#10'\"C '#9'c #F0D262\",'#13#10'\"D '#9'c #F8E379\",'#13#10'\"E'\n  +' '#9'c #FAF0AC\",'#13#10'\"F '#9'c #FAE77C\",'#13#10'\"G '#9'c #F9E161\",'#13#10\n  +'\"H '#9'c #F1D145\",'#13#10'\"I '#9'c #E6BE28\",'#13#10'\"J '#9'c #C99507\",'#13\n  +#10'\"K '#9'c #845C00\",'#13#10'\"L '#9'c #38387C\",'#13#10'\"M '#9'c #C4B792\",'\n  +#13#10'\"N '#9'c #FCF4DB\",'#13#10'\"O '#9'c #93691D\",'#13#10'\"P '#9'c #F89B0A\"'\n  +','#13#10'\"Q '#9'c #A06707\",'#13#10'\"R '#9'c #F8A309\",'#13#10'\"S '#9'c #C4A1'\n  +'4E\",'#13#10'\"T '#9'c #CDB369\",'#13#10'\"U '#9'c #D2BA78\",'#13#10'\"V '#9'c #D'\n  +'8C38A\",'#13#10'\"W '#9'c #D0B870\",'#13#10'\"X '#9'c #C7AA53\",'#13#10'\"Y '#9'c'\n  +' #B78F23\",'#13#10'\"Z '#9'c #A97A02\",'#13#10'\"` '#9'c #A07000\",'#13#10'\" .'#9\n  +'c #8E6100\",'#13#10'\"..'#9'c #5B3C00\",'#13#10'\"+.'#9'c #030359\",'#13#10'\"@.'\n  +#9'c #06065B\",'#13#10'\"#.'#9'c #F99408\",'#13#10'\"$.'#9'c #0F0F0F\",'#13#10'\"%'\n  +'.'#9'c #E1AB71\",'#13#10'\"&.'#9'c #E39427\",'#13#10'\"*.'#9'c #F18C12\",'#13#10\n  +'\"=.'#9'c #E29D3F\",'#13#10'\"-.'#9'c #F4B46E\",'#13#10'\";.'#9'c #FC8D04\",'#13\n  +#10'\">.'#9'c #F6CCA1\",'#13#10'\",.'#9'c #FFEF8C\",'#13#10'\"''.'#9'c #E0A468\",'\n  +#13#10'\").'#9'c #EC9C2E\",'#13#10'\"!.'#9'c #F98407\",'#13#10'\"~.'#9'c #ADAE98\"'\n  +','#13#10'\"{.'#9'c #FB7C05\",'#13#10'\"].'#9'c #E97419\",'#13#10'\"^.'#9'c #E4B2'\n  +'90\",'#13#10'\"/.'#9'c #904E30\",'#13#10'\"(.'#9'c #FB7405\",'#13#10'\"_.'#9'c #E'\n  +'97C1C\",'#13#10'\":.'#9'c #CC7328\",'#13#10'\"<.'#9'c #EA6C15\",'#13#10'\"[.'#9'c'\n  +' #D18954\",'#13#10'\"}.'#9'c #A9551C\",'#13#10'\"|.'#9'c #FB6804\",'#13#10'\"1.'#9\n  +'c #FCE4BC\",'#13#10'\"2.'#9'c #B26426\",'#13#10'\"3.'#9'c #D97425\",'#13#10'\"4.'\n  +#9'c #E86417\",'#13#10'\"5.'#9'c #D86C25\",'#13#10'\"6.'#9'c #C45B24\",'#13#10'\"7'\n  +'.'#9'c #FB5804\",'#13#10'\"8.'#9'c #EC7B4E\",'#13#10'\"9.'#9'c #C6642A\",'#13#10\n  +'\"0.'#9'c #E95C16\",'#13#10'\"a.'#9'c #FCAC78\",'#13#10'\"b.'#9'c #FCA67F\",'#13\n  +#10'\"c.'#9'c #FB4804\",'#13#10'\"d.'#9'c #B2664A\",'#13#10'\"e.'#9'c #FCEDDF\",'\n  +#13#10'\"f.'#9'c #DA4D1D\",'#13#10'\"g.'#9'c #DFA48B\",'#13#10'\"h.'#9'c #E75414\"'\n  +','#13#10'\"i.'#9'c #FB3C04\",'#13#10'\"j.'#9'c #EA4511\",'#13#10'\"k.'#9'c #FB35'\n  +'04\",'#13#10'\"l.'#9'c #DF3C14\",'#13#10'\"m.'#9'c #FCDCD1\",'#13#10'\"n.'#9'c #F'\n  +'B2B04\",'#13#10'\"o.'#9'c #DF3315\",'#13#10'\"p.'#9'c #FB2404\",'#13#10'\"q.'#9'c'\n  +' #FB1C04\",'#13#10'\"r.'#9'c #FC866E\",'#13#10'\"s.'#9'c #DF2412\",'#13#10'\"t.'#9\n  +'c #AC320C\",'#13#10'\"u.'#9'c #FC1504\",'#13#10'\"v.'#9'c #DC1D13\",'#13#10'\"w.'\n  +#9'c #C61816\",'#13#10'\"x.'#9'c #FCC4BD\",'#13#10'\"y.'#9'c #FB0304\",'#13#10'\"z'\n  +'.'#9'c #FA8C8A\",'#13#10'\"A.'#9'c #E90B09\",'#13#10'\"  . . . . + + + + + + + '\n  +'+ + + + @ # $ + + + + + \",'#13#10'\"+ + % . & + + + + + + + + + + @ # * # $ '\n  +'+ + + + \",'#13#10'\"+ + = . - + + + + + + + + + $ ; > , '' ) $ + + + \",'#13\n  +#10'\"+ ! ~ { ] + + ^ / ( + _ / : # < [ } | 1 # + + + \",'#13#10'\"+ 2 . 3 + 4 '\n  +'5 + + + + + + $ ; 6 7 + 8 9 0 $ + + \",'#13#10'\"+ a . b c + + + + + + + + # '\n  +'d e f g h i j # + + \",'#13#10'\"k l m n + + + + + + + + o p q r s t u v w 0 '\n  +'o + \",'#13#10'\"x . y + + + + + z A _ $ B C D E F G H I J K # $ \",'#13#10'\"L'\n  +' . M + + + N O P Q R # S T U V W X Y Z `  ...# \",'#13#10'\". . +.@.@.( #.#.#'\n  +'.#.P # # $.# # # # # # # # # # \",'#13#10'\"%.&.+ + + + *.=.-.;.;.;.;.>.+ + #'\n  ,' ,.# ;.+ + + + \",'#13#10'\"*.''.+ + + + + + + ).!.!.!.*.+ + @ # ~.{.-.+ + + '\n  +'\",'#13#10'\"].^.+ + + + + + /.(.(.(.(._.+ + + + ( (.:.+ + + \",'#13#10'\"<.[.+'\n  +' + + + }.|.|.|.|.|.|.1.+ + + + 2.|.3.+ + + \",'#13#10'\"4.5.+ + + 6.7.|.|.7.7'\n  +'.|.8.+ + + + + 7.|.9.+ + + \",'#13#10'\"0.7.+ + + 7.7.7.7.7.7.7.+ + + + + 0.7'\n  +'.7.a.+ + + \",'#13#10'\"b.c.d.+ e.c.c.c.c.c.c.f.+ + + g.h.c.c.7.( + + + \",'#13\n  +#10'\"+ i.c.N + i.i.i.i.i.c.i.j.j.j.i.i.i.i.j.+ + + + \",'#13#10'\"+ f.k.l.+ k.'\n  +'k.k.k.k.k.k.k.k.k.k.k.k.k.m.+ + + + \",'#13#10'\"+ + n.n.o.o.n.p.n.p.p.p.p.n.'\n  +'n.n.n.n.l.+ + + + + \",'#13#10'\"+ + e.q.q.r.q.q.q.q.q.q.q.q.q.q.q.s.+ + + + '\n  +'+ + \",'#13#10'\"+ + + e.q.t.q.u.u.u.u.u.u.u.u.u.v.+ + + + + + + \",'#13#10'\"+'\n  +' + + + N w.x.y.y.y.y.y.y.y.y.z.+ + + + + + + + \",'#13#10'\"+ + + + + + + e.w'\n  +'.y.y.A.w.x.+ + + + + + + + + + \"};'#13#10\n]);\n"
  },
  {
    "path": "lib/zeosdbo/src/component/ZComponentReg.pas",
    "content": "{*********************************************************}\n{                                                         }\n{                 Zeos Database Objects                   }\n{            Database Components Registration             }\n{                                                         }\n{        Originally written by Sergey Seroukhov           }\n{                                                         }\n{*********************************************************}\n\n{@********************************************************}\n{    Copyright (c) 1999-2012 Zeos Development Group       }\n{                                                         }\n{ License Agreement:                                      }\n{                                                         }\n{ This library is distributed in the hope that it will be }\n{ useful, but WITHOUT ANY WARRANTY; without even the      }\n{ implied warranty of MERCHANTABILITY or FITNESS FOR      }\n{ A PARTICULAR PURPOSE.  See the GNU Lesser General       }\n{ Public License for more details.                        }\n{                                                         }\n{ The source code of the ZEOS Libraries and packages are  }\n{ distributed under the Library GNU General Public        }\n{ License (see the file COPYING / COPYING.ZEOS)           }\n{ with the following  modification:                       }\n{ As a special exception, the copyright holders of this   }\n{ library give you permission to link this library with   }\n{ independent modules to produce an executable,           }\n{ regardless of the license terms of these independent    }\n{ modules, and to copy and distribute the resulting       }\n{ executable under terms of your choice, provided that    }\n{ you also meet, for each linked independent module,      }\n{ the terms and conditions of the license of that module. }\n{ An independent module is a module which is not derived  }\n{ from or based on this library. If you modify this       }\n{ library, you may extend this exception to your version  }\n{ of the library, but you are not obligated to do so.     }\n{ If you do not wish to do so, delete this exception      }\n{ statement from your version.                            }\n{                                                         }\n{                                                         }\n{ The project web site is located on:                     }\n{   http://zeos.firmos.at  (FORUM)                        }\n{   http://sourceforge.net/p/zeoslib/tickets/ (BUGTRACKER)}\n{   svn://svn.code.sf.net/p/zeoslib/code-0/trunk (SVN)    }\n{                                                         }\n{   http://www.sourceforge.net/projects/zeoslib.          }\n{                                                         }\n{                                                         }\n{                                 Zeos Development Group. }\n{********************************************************@}\n\nunit ZComponentReg;\n\ninterface\n\n{$I ZComponent.inc}\n\n{ Zeos palette names }\nconst\n  ZEOS_DB_PALETTE = 'Zeos Access';\n\nprocedure Register;\n\nimplementation\n\nuses\n{$IFDEF WITH_PROPERTY_EDITOR}\n  ZPropertyEditor,\n{$IFDEF FPC}\n  PropEdits,\n  ZUpdateSqlEditor,\n  ComponentEditors,\n  LResources,\n{$ELSE}\n{$IFNDEF UNIX}\n{$IFNDEF FPC}\n  ZUpdateSqlEditor,\n{$ENDIF}\n{$ENDIF}\n  DesignIntf,\n  SysUtils,                                     // **** Pitfiend addition, required to be able to put info in the delphi ide splash screen and about box \n  ToolsAPI,                                     //\n{$ENDIF}\n{$ENDIF}\n  Classes, ZConnection, ZAbstractConnection, ZDataset, ZSqlUpdate, ZSqlProcessor,\n  ZStoredProcedure, ZGroupedConnection, ZConnectionGroup ,\n  ZSqlMonitor, ZSqlMetadata, ZSequence\n  {$IFDEF ENABLE_INTERBASE}, ZIBEventAlerter {$ENDIF}\n  {$IFDEF ENABLE_POSTGRESQL}, ZPgEventAlerter {$ENDIF};\n\n{**\n  Registers components in a component palette.\n}\nprocedure Register;\n{$IFNDEF FPC}                                   // **** Pitfiend addition start\n{$IF DECLARED(IOTAAboutBoxServices)}            //   this allow to put a nice and pro entry in the delphi ide splash screen and about box\nvar                                             //\n  AboutSvcs: IOTAAboutBoxServices;              //\n{$IFEND}                                        //\n{$ENDIF}                                        // **** Pitfiend addition end\nbegin\n  RegisterComponents(ZEOS_DB_PALETTE, [\n    TZConnection, TZReadOnlyQuery, TZQuery, TZTable, TZUpdateSQL,\n    TZConnectionGroup, TZGroupedConnection,\n    TZStoredProc, TZSQLMetadata, TZSQLProcessor, TZSQLMonitor, TZSequence\n    {$IFDEF ENABLE_INTERBASE}, TZIBEventAlerter {$ENDIF}\n    {$IFDEF ENABLE_POSTGRESQL}, TZPgEventAlerter{$ENDIF}]) ;\n\n  {$IFDEF WITH_ZSTRINGFIELDS}\n  RegisterClasses([TZWideStringField, TZStringField]);\n  {$ENDIF}\n{$IFNDEF FPC}                                   // **** Pitfiend addition start\n{$IF DECLARED(IOTAAboutBoxServices)}\n    if Assigned(SplashScreenServices) then\n       SplashScreenServices.AddPluginBitmap('ZEOSLib Open Source Database Objects', 0); // to have a nice icon, a .res file must be included, then replace 0 by loadbitmap(HInstance, 'RESOURCENAME') \n    if (BorlandIDEServices<>nil) and supports(BorlandIDEServices, IOTAAboutBoxServices, AboutSvcs) then\n       AboutSvcs.AddPluginInfo('ZEOSLib', 'ZEOSLib'+sLineBreak+'OpenSource database components collection'+sLineBreak+sLineBreak+'Forum:http://zeoslib.sourceforge.net', 0, False, 'OpenSource'); // replace 0 by loadbitmap(HInstance, 'RESOURCENAME')\n{$IFEND}\n{$ENDIF}                                        // **** Pitfiend addition end\n\n{$IFDEF WITH_PROPERTY_EDITOR}\n\n  RegisterPropertyEditor(TypeInfo(string), TZConnection, 'ClientCodepage', TZClientCodePagePropertyEditor); {EgonHugeist}\n  RegisterPropertyEditor(TypeInfo(string), TZConnection, 'Protocol', TZProtocolPropertyEditor);\n  RegisterPropertyEditor(TypeInfo(string), TZConnection, 'Database', TZDatabasePropertyEditor);\n  RegisterPropertyEditor(TypeInfo(string), TZConnection, 'Catalog', TZCatalogPropertyEditor);\n  RegisterPropertyEditor(TypeInfo(string), TZConnection, 'LibraryLocation', TZLibLocationPropertyEditor);\n\n  RegisterPropertyEditor(TypeInfo(string), TZConnectionGroup, 'Protocol', TZProtocolPropertyEditor);\n  RegisterPropertyEditor(TypeInfo(string), TZConnectionGroup, 'Database', TZConnectionGroupPropertyEditor);\n  RegisterPropertyEditor(TypeInfo(string), TZGroupedConnection, 'Catalog', TZGroupedConnectionCatalogPropertyEditor);\n  RegisterPropertyEditor(TypeInfo(string), TZConnectionGroup, 'LibraryLocation', TZConnectionGroupLibLocationPropertyEditor);\n\n  RegisterPropertyEditor(TypeInfo(string), TZQuery, 'LinkedFields', TZDataFieldPropertyEditor); {renamed by bangfauzan}\n  RegisterPropertyEditor(TypeInfo(string), TZQuery, 'MasterFields', TZMasterFieldPropertyEditor);\n  RegisterPropertyEditor(TypeInfo(string), TZQuery, 'SortedFields', TZDataFieldPropertyEditor);\n  RegisterPropertyEditor(TypeInfo(string), TZQuery, 'SequenceField', TZDataFieldPropertyEditor);\n\n  RegisterPropertyEditor(TypeInfo(string), TZReadOnlyQuery, 'LinkedFields', TZDataFieldPropertyEditor); {renamed by bangfauzan}\n  RegisterPropertyEditor(TypeInfo(string), TZReadOnlyQuery, 'MasterFields', TZMasterFieldPropertyEditor);\n  RegisterPropertyEditor(TypeInfo(string), TZReadOnlyQuery, 'SortedFields', TZDataFieldPropertyEditor);\n\n  RegisterPropertyEditor(TypeInfo(string), TZTable, 'TableName', TZTableNamePropertyEditor);\n  RegisterPropertyEditor(TypeInfo(string), TZTable, 'LinkedFields', TZDataFieldPropertyEditor); {renamed by bangfauzan}\n  RegisterPropertyEditor(TypeInfo(string), TZTable, 'MasterFields', TZMasterFieldPropertyEditor);\n  RegisterPropertyEditor(TypeInfo(string), TZTable, 'SortedFields', TZDataFieldPropertyEditor);\n  RegisterPropertyEditor(TypeInfo(string), TZTable, 'SequenceField', TZDataFieldPropertyEditor);\n\n  RegisterPropertyEditor(TypeInfo(string), TZStoredProc, 'StoredProcName', TZProcedureNamePropertyEditor);\n  RegisterPropertyEditor(TypeInfo(string), TZStoredProc, 'SortedFields', TZDataFieldPropertyEditor);\n\n  RegisterPropertyEditor(TypeInfo(string), TZSequence, 'SequenceName', TZSequenceNamePropertyEditor);\n\n{$IFDEF USE_METADATA}\n  RegisterPropertyEditor(TypeInfo(string), TZSQLMetadata, 'Catalog', TZCatalogProperty);\n  RegisterPropertyEditor(TypeInfo(string), TZSQLMetadata, 'ColumnName', TZColumnNamePropertyEditor);\n  RegisterPropertyEditor(TypeInfo(string), TZSQLMetadata, 'ForeignCatalog', TZCatalogProperty);\n  RegisterPropertyEditor(TypeInfo(string), TZSQLMetadata, 'ForeignSchema', TZSchemaPropertyEditor);\n  RegisterPropertyEditor(TypeInfo(string), TZSQLMetadata, 'ForeignTableName', TZTableNamePropertyEditor);\n  RegisterPropertyEditor(TypeInfo(string), TZSQLMetadata, 'LinkedFields', TZDataFieldPropertyEditor); {renamed by bangfauzan}\n  RegisterPropertyEditor(TypeInfo(string), TZSQLMetadata, 'MasterFields', TZMasterFieldPropertyEditor);\n  RegisterPropertyEditor(TypeInfo(string), TZSQLMetadata, 'ProcedureName', TZProcedureNamePropertyEditor);\n  RegisterPropertyEditor(TypeInfo(string), TZSQLMetadata, 'Schema', TZSchemaPropertyEditor);\n  RegisterPropertyEditor(TypeInfo(string), TZSQLMetadata, 'SequenceName', TZSequenceNamePropertyEditor);\n  RegisterPropertyEditor(TypeInfo(string), TZSQLMetadata, 'SortedFields', TZDataFieldPropertyEditor);\n  RegisterPropertyEditor(TypeInfo(string), TZSQLMetadata, 'TableName', TZTableNamePropertyEditor);\n  RegisterPropertyEditor(TypeInfo(string), TZSQLMetadata, 'TypeName', TZTypeNamePropertyEditor);\n{$ENDIF}\n{$IFDEF FPC}\n  RegisterComponentEditor(TZUpdateSQL, TZUpdateSQLEditor);\n{$ELSE}\n    {$IFNDEF UNIX}\n  RegisterComponentEditor(TZUpdateSQL, TZUpdateSQLEditor);\n    {$ENDIF}\n  {$ENDIF}\n{$ENDIF}\nend;\n\n{$IFDEF FPC}\ninitialization\n  {$I ZComponentReg.lrs}\n{$ENDIF}\n\nend.\n\n"
  },
  {
    "path": "lib/zeosdbo/src/component/ZConnection.pas",
    "content": "{*********************************************************}\n{                                                         }\n{                 Zeos Database Objects                   }\n{              Database Connection Component              }\n{                                                         }\n{        Originally written by Sergey Seroukhov           }\n{                                                         }\n{*********************************************************}\n\n{@********************************************************}\n{    Copyright (c) 1999-2012 Zeos Development Group       }\n{                                                         }\n{ License Agreement:                                      }\n{                                                         }\n{ This library is distributed in the hope that it will be }\n{ useful, but WITHOUT ANY WARRANTY; without even the      }\n{ implied warranty of MERCHANTABILITY or FITNESS FOR      }\n{ A PARTICULAR PURPOSE.  See the GNU Lesser General       }\n{ Public License for more details.                        }\n{                                                         }\n{ The source code of the ZEOS Libraries and packages are  }\n{ distributed under the Library GNU General Public        }\n{ License (see the file COPYING / COPYING.ZEOS)           }\n{ with the following  modification:                       }\n{ As a special exception, the copyright holders of this   }\n{ library give you permission to link this library with   }\n{ independent modules to produce an executable,           }\n{ regardless of the license terms of these independent    }\n{ modules, and to copy and distribute the resulting       }\n{ executable under terms of your choice, provided that    }\n{ you also meet, for each linked independent module,      }\n{ the terms and conditions of the license of that module. }\n{ An independent module is a module which is not derived  }\n{ from or based on this library. If you modify this       }\n{ library, you may extend this exception to your version  }\n{ of the library, but you are not obligated to do so.     }\n{ If you do not wish to do so, delete this exception      }\n{ statement from your version.                            }\n{                                                         }\n{                                                         }\n{ The project web site is located on:                     }\n{   http://zeos.firmos.at  (FORUM)                        }\n{   http://sourceforge.net/p/zeoslib/tickets/ (BUGTRACKER)}\n{   svn://svn.code.sf.net/p/zeoslib/code-0/trunk (SVN)    }\n{                                                         }\n{   http://www.sourceforge.net/projects/zeoslib.          }\n{                                                         }\n{                                                         }\n{                                 Zeos Development Group. }\n{********************************************************@}\n\nunit ZConnection;\n\ninterface\n\n{$I ZComponent.inc}\n\nuses\n  SysUtils, Classes,  ZAbstractConnection, ZClasses;\n\nconst\n  ZEOS_MAJOR_VERSION = ZClasses.ZEOS_MAJOR_VERSION;\n  ZEOS_MINOR_VERSION = ZClasses.ZEOS_MINOR_VERSION;\n  ZEOS_SUB_VERSION = ZClasses.ZEOS_SUB_VERSION;\n  ZEOS_STATUS = ZClasses.ZEOS_STATUS;\n  ZEOS_VERSION = ZClasses.ZEOS_VERSION;\n\n\ntype\n  {** Represents a component which wraps a connection to database. }\n  TZConnection = class(TZAbstractConnection)\n  published\n    property HostName: string read GetHostName write SetHostName;\n    property Port: Integer read GetConnPort write SetConnPort;\n    property Database: string read GetDatabase write SetDatabase;\n    property User: string read GetUser write SetUser;\n    property Password: string read GetPassword write SetPassword;\n    property Protocol: string read GetProtocol write SetProtocol;\n    property Catalog: string read FCatalog write FCatalog;\n    property LibraryLocation: String read GetLibLocation write SetLibLocation;\n  end;\n\nimplementation\n\nend.\n"
  },
  {
    "path": "lib/zeosdbo/src/component/ZConnectionGroup.pas",
    "content": "{*********************************************************}\n{                                                         }\n{                 Zeos Database Objects                   }\n{              Database Connection Component              }\n{                                                         }\n{        Originally written by una.bicicleta              }\n{*********************************************************}\n\n{@********************************************************}\n{    Copyright (c) 1999-2012 Zeos Development Group       }\n{                                                         }\n{ License Agreement:                                      }\n{                                                         }\n{ This library is distributed in the hope that it will be }\n{ useful, but WITHOUT ANY WARRANTY; without even the      }\n{ implied warranty of MERCHANTABILITY or FITNESS FOR      }\n{ A PARTICULAR PURPOSE.  See the GNU Lesser General       }\n{ Public License for more details.                        }\n{                                                         }\n{ The source code of the ZEOS Libraries and packages are  }\n{ distributed under the Library GNU General Public        }\n{ License (see the file COPYING / COPYING.ZEOS)           }\n{ with the following  modification:                       }\n{ As a special exception, the copyright holders of this   }\n{ library give you permission to link this library with   }\n{ independent modules to produce an executable,           }\n{ regardless of the license terms of these independent    }\n{ modules, and to copy and distribute the resulting       }\n{ executable under terms of your choice, provided that    }\n{ you also meet, for each linked independent module,      }\n{ the terms and conditions of the license of that module. }\n{ An independent module is a module which is not derived  }\n{ from or based on this library. If you modify this       }\n{ library, you may extend this exception to your version  }\n{ of the library, but you are not obligated to do so.     }\n{ If you do not wish to do so, delete this exception      }\n{ statement from your version.                            }\n{                                                         }\n{                                                         }\n{ The project web site is located on:                     }\n{   http://zeos.firmos.at  (FORUM)                        }\n{   http://sourceforge.net/p/zeoslib/tickets/ (BUGTRACKER)}\n{   svn://svn.code.sf.net/p/zeoslib/code-0/trunk (SVN)    }\n{                                                         }\n{   http://www.sourceforge.net/projects/zeoslib.          }\n{                                                         }\n{                                                         }\n{                                 Zeos Development Group. }\n{********************************************************@}\n\nunit ZConnectionGroup;\n\ninterface\n{$I ZComponent.inc}\n\nuses\n  SysUtils, Classes, {$IFDEF MSEgui}mclasses,{$ENDIF} Forms, Dialogs,\n  ZDbcIntfs,ZCompatibility;\n\nconst\n  mask = '#20#39-VFFV';  { define your own mask  }\n\ntype\n  TZConnectionGroup = class;\n  TZConnectionGroupLink = class;\n\n  TZConnectionGroupLink = class(TObject)\n  private\n    FSender: TObject;\n    FOnChange: TNotifyEvent;\n  public\n    destructor Destroy; override;\n    procedure Change;\n    dynamic;\n    property OnChange: TNotifyEvent read FOnChange write FOnChange;\n    property Sender: TObject read FSender write FSender;\n  end;\n\n{$HINTS OFF}\n  TZConnectionGroup = class(TComponent)\n  private\n    FOnChange: TNotifyEvent;\n    procedure DoChange(Sender: TObject);\n    procedure Change;\n  protected\n    FClients: tList;\n    FProtocol: string;\n    FHostName: string;\n    FPort: Integer;\n    FDatabase: string;\n    FUser: string;\n    FPassword: string;\n    FLibLocation: String;\n    //FCatalog:string;\n\n    procedure UnregisterAllDataSets;\n    procedure SetUser(const Value: string);\n    procedure SetPassword(const Value: string);\n    procedure DefineProperties(filer: tfiler);override;\n\n    procedure SetProtocol(const Value: string);\n    procedure SetHostName(const Value: string);\n    procedure SetConnPort(const Value: integer);\n    procedure SetDatabase(const Value: string);\n    procedure SetLibLocation(const Value: String);\n    //procedure SetCatalog(const Value: string);\n\n    function Encrypt(const str: string): string; //virtual;\n    function Decrypt(const str: string): string; //virtual;\n  public\n    constructor Create(AOwner: TComponent); override;\n    destructor Destroy; override;\n    procedure ReadPass(reader:treader);\n    procedure WritePass(writer:twriter);\n    procedure ReadUser(reader:treader);\n    procedure WriteUser(writer:twriter);\n    procedure RegisterChanges(Value: TZConnectionGroupLink);\n    procedure UnregisterChanges(Value: TZConnectionGroupLink);\n  published\n    property Protocol: string read FProtocol write SetProtocol;\n    property HostName: string read FHostName write SetHostName;\n    property Port: Integer read FPort write SetConnPort default 0;\n    property Database: string read FDatabase write SetDatabase;\n    property User: string read FUser write SetUser  stored false;\n    property Password: string read FPassword write SetPassword  stored false;\n    property LibraryLocation: String read FLibLocation write SetLibLocation;\n    //property Catalog: string read FCatalog write SetCatalog;\n    property OnChange: TNotifyEvent read FOnChange write FOnChange;\n    // -- todo ----\n    // add another property or event ?\n  end;\n{$HINTS ON}\n\nimplementation\n\n// === { TZConnectionGroupLink } ====================================================\ndestructor TZConnectionGroupLink.Destroy;\nbegin\n  if Sender is TZConnectionGroup then\n    TZConnectionGroup(Sender).UnregisterChanges(Self);\n  inherited Destroy;\nend;\n\nprocedure TZConnectionGroupLink.Change;\nbegin\n  if Assigned(FOnChange) then\n    FOnChange(Sender);\nend;\n\n\n// === { TZConnectionGroup } =============================================\nconstructor TZConnectionGroup.Create(AOwner: TComponent);\nbegin\n  inherited Create(AOwner);\n  FClients := tList.Create;\nend;\n\ndestructor TZConnectionGroup.Destroy;\nbegin\n  UnregisterAllDataSets;\n  FClients := nil;\n  FClients.Free;\n  inherited Destroy;\nend;\n\nprocedure TZConnectionGroup.DoChange(Sender: TObject);\nbegin\n  Change;\nend;\n\nprocedure TZConnectionGroup.Change;\n  var i:Integer;\nbegin\n  if Assigned(FOnChange) then\n  begin\n    FOnChange(Self);\n  end;\n  if FClients <> nil then\n    for I := 0 to FClients.Count - 1 do\n      TZConnectionGroupLink(FClients[I]).Change;\nend;\n\n// === { TZConnectionGroup } =============================================\nfunction TZConnectionGroup.Decrypt(const str: string): string;\nvar n: integer;\nbegin\n   result:='';\n   for n:=1 to length(str) do\n      result:=result+\n        chr(ord(str[n]) xor ord(mask[((n-1) mod length(mask)) +1]));\nend;\n\nfunction TZConnectionGroup.Encrypt(const str: string): string;\nbegin\n   result:=Decrypt(str); { symmetrical encryption }\nend;\n\nprocedure TZConnectionGroup.ReadPass(reader:treader);\nbegin\n   reader.readlistbegin;\n   FPassword := Decrypt(reader.readstring);\n   reader.readlistend;\nend;\n\nprocedure TZConnectionGroup.WritePass(writer:twriter);\nbegin\n   writer.writelistbegin;\n   writer.writestring(Encrypt(FPassword));\n   writer.writelistend;\nend;\n\nprocedure TZConnectionGroup.ReadUser(reader:treader);\nbegin\n   reader.readlistbegin;\n   FUser := Decrypt(reader.readstring);\n   reader.readlistend;\nend;\n\nprocedure TZConnectionGroup.WriteUser(writer:twriter);\nbegin\n   writer.writelistbegin;\n   writer.writestring(Encrypt(FUser));\n   writer.writelistend;\nend;\n\nprocedure TZConnectionGroup.DefineProperties(filer: tfiler);\nbegin\n   inherited defineproperties(filer);\n   filer.DefineProperty('str1',ReadUser,WriteUser,true);\n   filer.DefineProperty('str2',ReadPass,WritePass,true);\nend;\n\n\nprocedure TZConnectionGroup.SetUser(const Value: string);\nbegin\n  if FUser <> Value then\n  begin\n    FUser := Value;\n    Change;\n  end;\nend;\n\nprocedure TZConnectionGroup.SetPassword(const Value: string);\nbegin\n  if FPassword <> Value then\n  begin\n    FPassword := Value;\n    Change;\n  end;\nend;\n\nprocedure TZConnectionGroup.SetProtocol(const Value: string);\nbegin\n  if FProtocol <> Value then\n  begin\n    FProtocol := Value;\n    Change;\n  end;\nend;\n\nprocedure TZConnectionGroup.SetHostName(const Value: string);\nbegin\n  if FHostName <> Value then\n  begin\n    FHostName := Value;\n    Change;\n  end;\nend;\n\nprocedure TZConnectionGroup.SetDatabase(const Value: string);\nbegin\n  if FDatabase <> Value then\n  begin\n    FDatabase := Value;\n    Change;\n  end;\nend;\n\nprocedure TZConnectionGroup.SetLibLocation(const Value: String);\nbegin\n  if FLibLocation <> Value then\n  begin\n    FLibLocation := Value;\n    Change;\n  end;\nend;\n\n{\nprocedure TZConnectionGroup.SetCatalog(const Value: string);\nbegin\n  if FCatalog <> Value then\n  begin\n    FCatalog := Value;\n    Change;\n  end;\nend;\n}\n\nprocedure TZConnectionGroup.SetConnPort(const Value: integer);\nbegin\n  if FPort <> Value then\n  begin\n    FPort := Value;\n    Change;\n  end;\nend;\n\nprocedure TZConnectionGroup.UnregisterAllDataSets;\nvar\n  I: Integer;\n  Current: TZConnectionGroupLink;\nbegin\n  for I := FClients.Count - 1 downto 0 do\n  begin\n    Current := TZConnectionGroupLink(FClients[I]);\n    FClients.Remove(Current);\n//    try\n//       Current := nil;\n//    except\n//       //Ignore\n//    end;\n  end;\nend;\n\nprocedure TZConnectionGroup.RegisterChanges(Value: TZConnectionGroupLink);\nbegin\n  Value.Sender := Self;\n  if FClients <> nil then\n    FClients.Add(Value);\nend;\n\nprocedure TZConnectionGroup.UnregisterChanges(Value: TZConnectionGroupLink);\nvar\n  I: Integer;\nbegin\n  if FClients <> nil then\n    for I := 0 to FClients.Count - 1 do\n      if FClients[I] = Value then\n      begin\n        Value.Sender := nil;\n        FClients.Delete(I);\n        Break;\n      end;\nend;\n\nend.\n"
  },
  {
    "path": "lib/zeosdbo/src/component/ZDataset.pas",
    "content": "{*********************************************************}\n{                                                         }\n{                 Zeos Database Objects                   }\n{               Universal Dataset component               }\n{                                                         }\n{        Originally written by Sergey Seroukhov           }\n{                                                         }\n{*********************************************************}\n\n{@********************************************************}\n{    Copyright (c) 1999-2012 Zeos Development Group       }\n{                                                         }\n{ License Agreement:                                      }\n{                                                         }\n{ This library is distributed in the hope that it will be }\n{ useful, but WITHOUT ANY WARRANTY; without even the      }\n{ implied warranty of MERCHANTABILITY or FITNESS FOR      }\n{ A PARTICULAR PURPOSE.  See the GNU Lesser General       }\n{ Public License for more details.                        }\n{                                                         }\n{ The source code of the ZEOS Libraries and packages are  }\n{ distributed under the Library GNU General Public        }\n{ License (see the file COPYING / COPYING.ZEOS)           }\n{ with the following  modification:                       }\n{ As a special exception, the copyright holders of this   }\n{ library give you permission to link this library with   }\n{ independent modules to produce an executable,           }\n{ regardless of the license terms of these independent    }\n{ modules, and to copy and distribute the resulting       }\n{ executable under terms of your choice, provided that    }\n{ you also meet, for each linked independent module,      }\n{ the terms and conditions of the license of that module. }\n{ An independent module is a module which is not derived  }\n{ from or based on this library. If you modify this       }\n{ library, you may extend this exception to your version  }\n{ of the library, but you are not obligated to do so.     }\n{ If you do not wish to do so, delete this exception      }\n{ statement from your version.                            }\n{                                                         }\n{                                                         }\n{ The project web site is located on:                     }\n{   http://zeos.firmos.at  (FORUM)                        }\n{   http://sourceforge.net/p/zeoslib/tickets/ (BUGTRACKER)}\n{   svn://svn.code.sf.net/p/zeoslib/code-0/trunk (SVN)    }\n{                                                         }\n{   http://www.sourceforge.net/projects/zeoslib.          }\n{                                                         }\n{                                                         }\n{                                 Zeos Development Group. }\n{********************************************************@}\n\nunit ZDataset;\n\ninterface\n\n{$I ZComponent.inc}\n\nuses ZAbstractRODataset, ZAbstractDataset, ZAbstractTable {$IFDEF OLDFPC}, DB {$ENDIF};\n\ntype\n\n  {** Implements an universal SQL query for read/only data access. }\n  TZReadOnlyQuery = class (TZAbstractRODataSet)\n  published\n    property Active;\n    property IsUniDirectional;\n    property SQL;\n    property ParamCheck;\n    property Params;\n    property FetchRow;     // added by Patyi\n    property Properties;\n    property DataSource;\n    property MasterFields;\n    property MasterSource;\n    property LinkedFields; {renamed by bangfauzan}\n    property IndexFieldNames; {bangfauzan addition}\n    property Options;\n  end;\n\n  {** Implements an universal SQL query for read/write data access. }\n  TZQuery = class (TZAbstractDataSet)\n  published\n    property Active;\n    property ReadOnly default False;\n    property SQL;\n    property ParamCheck;\n    property ParamChar;\n    property Params;\n    property FetchRow;      // added by Patyi\n    property ShowRecordTypes;\n    property Properties;\n    property DataSource;\n    property MasterFields;\n    property MasterSource;\n    property LinkedFields; {renamed by bangfauzan}\n    property IndexFieldNames; {bangfauzan addition}\n    property UpdateMode;\n    property WhereMode;\n    property Options;\n    property Sequence;\n    property SequenceField;\n  end;\n\n  {** Implements an universal SQL query for single table access. }\n  TZTable = class (TZAbstractTable)\n  public\n    property Exists;\n  published\n    property Active;\n    property ReadOnly default False;\n    property TableName;\n    property ShowRecordTypes;\n    property Properties;\n    property FetchRow;      // added by Patyi\n    property MasterFields;\n    property MasterSource;\n    property LinkedFields; {renamed by bangfauzan}\n    property IndexFieldNames; {bangfauzan addition}\n    property UpdateMode;\n    property WhereMode;\n    property Options;\n    property Sequence;\n    property SequenceField;\n  end;\n\nimplementation\n\nend.\n\n\n"
  },
  {
    "path": "lib/zeosdbo/src/component/ZDatasetUtils.pas",
    "content": "{*********************************************************}\n{                                                         }\n{                 Zeos Database Objects                   }\n{        Dataset utility functions and classes            }\n{                                                         }\n{        Originally written by Sergey Seroukhov           }\n{                                                         }\n{*********************************************************}\n\n{@********************************************************}\n{    Copyright (c) 1999-2012 Zeos Development Group       }\n{                                                         }\n{ License Agreement:                                      }\n{                                                         }\n{ This library is distributed in the hope that it will be }\n{ useful, but WITHOUT ANY WARRANTY; without even the      }\n{ implied warranty of MERCHANTABILITY or FITNESS FOR      }\n{ A PARTICULAR PURPOSE.  See the GNU Lesser General       }\n{ Public License for more details.                        }\n{                                                         }\n{ The source code of the ZEOS Libraries and packages are  }\n{ distributed under the Library GNU General Public        }\n{ License (see the file COPYING / COPYING.ZEOS)           }\n{ with the following  modification:                       }\n{ As a special exception, the copyright holders of this   }\n{ library give you permission to link this library with   }\n{ independent modules to produce an executable,           }\n{ regardless of the license terms of these independent    }\n{ modules, and to copy and distribute the resulting       }\n{ executable under terms of your choice, provided that    }\n{ you also meet, for each linked independent module,      }\n{ the terms and conditions of the license of that module. }\n{ An independent module is a module which is not derived  }\n{ from or based on this library. If you modify this       }\n{ library, you may extend this exception to your version  }\n{ of the library, but you are not obligated to do so.     }\n{ If you do not wish to do so, delete this exception      }\n{ statement from your version.                            }\n{                                                         }\n{                                                         }\n{ The project web site is located on:                     }\n{   http://zeos.firmos.at  (FORUM)                        }\n{   http://sourceforge.net/p/zeoslib/tickets/ (BUGTRACKER)}\n{   svn://svn.code.sf.net/p/zeoslib/code-0/trunk (SVN)    }\n{                                                         }\n{   http://www.sourceforge.net/projects/zeoslib.          }\n{                                                         }\n{                                                         }\n{                                 Zeos Development Group. }\n{********************************************************@}\n\nunit ZDatasetUtils;\n\ninterface\n\n{$I ZComponent.inc}\n\nuses\n  Types, Classes, SysUtils, {$IFDEF MSEgui}mclasses, mdb{$ELSE}Db{$ENDIF},\n  Contnrs, {$IFDEF WITH_UNITANSISTRINGS}AnsiStrings, {$ENDIF}\n  ZDbcIntfs, ZDbcCache, ZCompatibility, ZExpression, ZVariant, ZTokenizer;\n\n{**\n  Converts DBC Field Type to TDataset Field Type.\n  @param Value an initial DBC field type.\n  @return a converted TDataset field type.\n}\nfunction ConvertDbcToDatasetType(Value: TZSQLType): TFieldType;\n\n{**\n  Converts TDataset Field Type to DBC Field Type.\n  @param Value an initial TDataset field type.\n  @return a converted DBC field type.\n}\nfunction ConvertDatasetToDbcType(Value: TFieldType): TZSQLType;\n\n{**\n  Converts field definitions into column information objects.\n  @param Fields a collection of field definitions.\n  @return a collection of column information objects.\n}\nfunction ConvertFieldsToColumnInfo(Fields: TFields): TObjectList;\n\n{**\n  Fetches columns from specified resultset.\n  @param ResultSet a source resultset.\n  @param FieldsLookupTable a lookup table to define original index.\n  @param Fields a collection of field definitions.\n  @param RowAccessor a destination row accessor.\n}\nprocedure FetchFromResultSet(ResultSet: IZResultSet;\n  const FieldsLookupTable: TIntegerDynArray; Fields: TFields;\n  RowAccessor: TZRowAccessor);\n\n{**\n  Posts columns from specified resultset.\n  @param ResultSet a source resultset.\n  @param FieldsLookupTable a lookup table to define original index.\n  @param Fields a collection of field definitions.\n  @param RowAccessor a destination row accessor.\n}\nprocedure PostToResultSet(ResultSet: IZResultSet;\n  const FieldsLookupTable: TIntegerDynArray; Fields: TFields;\n  RowAccessor: TZRowAccessor);\n\n{**\n  Defines fields indices for the specified dataset.\n  @param DataSet a dataset object.\n  @param FieldNames a list of field names.\n  @param OnlyDataFields <code>True</code> if only data fields selected.\n}\nfunction DefineFields(DataSet: TDataset; const FieldNames: string;\n  var OnlyDataFields: Boolean): TObjectDynArray;\n\n{**\n  Defins a indices of filter fields.\n  @param Dataset a dataset object.\n  @param Expression a expression calculator.\n  @returns an array with field object references.\n}\nfunction DefineFilterFields(DataSet: TDataset;\n  Expression: IZExpression): TObjectDynArray;\n\n{**\n  Retrieves a set of specified field values.\n  @param FieldRefs an array with interested field object references.\n  @param ResultSet an initial result set object.\n  @param ResultValues a container for result values.\n  @return an array with field values.\n}\nprocedure RetrieveDataFieldsFromResultSet(const FieldRefs: TObjectDynArray;\n  ResultSet: IZResultSet; var ResultValues: TZVariantDynArray);\n\n{**\n  Retrieves a set of specified field values.\n  @param FieldRefs an array with interested field object references.\n  @param FieldIndices an array with interested field indices.\n  @param RowAccessor a row accessor object.\n  @param ResultValues a container for result values.\n  @return an array with field values.\n}\nprocedure RetrieveDataFieldsFromRowAccessor(const FieldRefs: TObjectDynArray;\n  const FieldIndices: TIntegerDynArray; RowAccessor: TZRowAccessor;\n  var ResultValues: TZVariantDynArray);\n\n{**\n  Copy a set of specified field values to variables.\n  @param Fields an array with interested field object references.\n  @param ResultSet an initial result set object.\n  @param Variables a list of variables.\n}\nprocedure CopyDataFieldsToVars(const Fields: TObjectDynArray;\n  ResultSet: IZResultSet; Variables: IZVariablesList);\n\n{**\n  Prepares values for comparison by CompareFieldsFromResultSet.\n  @param FieldRefs an array with interested field object references.\n  @param DecodedKeyValues given values.\n  @param ResultSet  a resultset to get field values.\n  @param PartialKey <code>True</code> if values should be started with the keys.\n  @param CaseInsensitive <code>True</code> if keys are case insensitive.\n}\nprocedure PrepareValuesForComparison(const FieldRefs: TObjectDynArray;\n  var DecodedKeyValues: TZVariantDynArray; ResultSet: IZResultSet;\n  PartialKey: Boolean; CaseInsensitive: Boolean);\n\n{**\n  Compares row field values with the given ones.\n  @param KeyValues given values.\n  @param RowValues row field values.\n  @param PartialKey <code>True</code> if values should be started with the keys.\n  @param CaseInsensitive <code>True</code> if keys are case insensitive.\n  @return <code> if values are equal.\n}\nfunction CompareDataFields(const KeyValues, RowValues: TZVariantDynArray;\n  PartialKey: Boolean; CaseInsensitive: Boolean): Boolean;\n\n{**\n  Compares row field values with the given ones.\n  @param FieldRefs an array with interested field object references.\n  @param KeyValues given values.\n  @param RowValues row field values.\n  @param PartialKey <code>True</code> if values should be started with the keys.\n  @param CaseInsensitive <code>True</code> if keys are case insensitive.\n  @return <code> if values are equal.\n}\nfunction CompareFieldsFromResultSet(const FieldRefs: TObjectDynArray;\n  const KeyValues: TZVariantDynArray; ResultSet: IZResultSet; PartialKey: Boolean;\n  CaseInsensitive: Boolean): Boolean;\n\n{**\n  Defines a list of key field names.\n  @param Fields a collection of dataset fields.\n  @return a list of key field names.\n}\nfunction DefineKeyFields(Fields: TFields): string;\n\n{**\n  Converts datetime value into TDataset internal presentation.\n  @param DataType a type of date-time field.\n  @param Data a data which contains a value.\n  @param Buffer a field buffer pointer\n}\nprocedure DateTimeToNative(DataType: TFieldType; Data: TDateTime; Buffer: Pointer);\n\n{**\n  Converts date times from TDataset internal presentation into datetime value.\n  @param DataType a type of date-time field.\n  @param Buffer a field buffer pointer\n  @return a data which contains a value.\n}\nfunction NativeToDateTime(DataType: TFieldType; Buffer: Pointer): TDateTime;\n\n{**\n  Compare values from two key fields.\n  @param Field1 the first field object.\n  @param ResultSet the resultset to read the first field value.\n  @param Field2 the second field object.\n}\nfunction CompareKeyFields(Field1: TField; ResultSet: IZResultSet;\n  Field2: TField): Boolean;\n\n{**\n  Defins a indices and directions for sorted fields.\n  @param Dataset a dataset object.\n  @param SortedFields an encoded fields for sorting in the format\n    <Field Name> [ASC | DESC] [, ...]\n  @param FieldRefs a decoded field object references.\n  @param FieldDirs a decoded field directions.\n  @param OnlyDataFields <code>True</code> if only data fields selected.\n}\nprocedure DefineSortedFields(DataSet: TDataset;\n  const SortedFields: string; var FieldRefs: TObjectDynArray;\n  var FieldDirs: TBooleanDynArray; var OnlyDataFields: Boolean);\n\n{**\n  Creates a fields lookup table to define fixed position\n  of the field in dataset.\n  @param Fields a collection of TDataset fields in initial order.\n  @returns a fields lookup table.\n}\nfunction CreateFieldsLookupTable(Fields: TFields): TIntegerDynArray;\n\n{**\n  Defines an original field index in the dataset.\n  @param FieldsLookupTable a lookup table to define original index.\n  @param Field a TDataset field object.\n  @returns an original fields index or -1 otherwise.\n}\nfunction DefineFieldIndex(const FieldsLookupTable: TIntegerDynArray;\n  Field: TField): Integer;\n\n{**\n  Defines an original field indices in the dataset.\n  @param FieldsLookupTable a lookup table to define original index.\n  @param FieldRefs a TDataset field object references.\n  @returns an array with original fields indices.\n}\nfunction DefineFieldIndices(const FieldsLookupTable: TIntegerDynArray;\n  const FieldRefs: TObjectDynArray): TIntegerDynArray;\n\n{**\n  Splits up a qualified object name into pieces. Catalog, schema\n  and objectname.\n}\nprocedure SplitQualifiedObjectName(QualifiedName: string;\n  var Catalog, Schema, ObjectName: string); overload;\n\n{**\n  Splits up a qualified object name into pieces. Catalog, schema\n  and objectname.\n}\nprocedure SplitQualifiedObjectName(QualifiedName: string;\n  const SupportsCatalogs, SupportsSchemas: Boolean;\n  var Catalog, Schema, ObjectName: string); overload;\n\n{**\n  Assigns a Statement value from a TParam\n  @param Index the index of Statement.SetParam(Idex..);\n  @param Statement the PrepredStatement where the values have been assigned\n  @param Param the TParam where the value is assigned from\n}\nprocedure SetStatementParam(Index: Integer;\n  Statement: IZPreparedStatement; Param: TParam);\n\n{** Common variables. }\nvar\n  CommonTokenizer: IZTokenizer;\n\nimplementation\n\nuses\n  ZMessages, ZGenericSqlToken, ZDbcResultSetMetadata, ZAbstractRODataset,\n  ZDbcUtils\n  {$IFNDEF WITHOUT_VARBYTESASSTRING}, ZSysUtils{$ENDIF}\n  {$IFDEF WITH_INLINE_ANSISTRLCOMP}, Windows{$ENDIF};\n\n{**\n  Converts DBC Field Type to TDataset Field Type.\n  @param Value an initial DBC field type.\n  @return a converted TDataset field type.\n}\nfunction ConvertDbcToDatasetType(Value: TZSQLType): TFieldType;\nbegin\n  case Value of\n    stBoolean:\n      Result := ftBoolean;\n    stByte, stShort:\n      Result := ftSmallInt;\n    stInteger:\n      Result := ftInteger;\n    stLong:\n      Result := ftLargeInt;\n    stFloat, stDouble, stBigDecimal:\n      Result := ftFloat;\n    stString:\n      Result := ftString;\n    stBytes{$IFNDEF WITH_FTGUID}, stGUID{$ENDIF}:\n      Result := ftBytes;\n    {$IFDEF WITH_FTGUID}\n    stGUID:\n      Result := ftGUID;\n    {$ENDIF}\n    stDate:\n      Result := ftDate;\n    stTime:\n      Result := ftTime;\n    stTimestamp:\n      Result := ftDateTime;\n    stAsciiStream:\n      Result := ftMemo;\n    stBinaryStream:\n      Result := ftBlob;\n    stUnicodeString:\n      Result := ftWideString;\n    stUnicodeStream:\n      Result := {$IFNDEF WITH_WIDEMEMO}ftWideString{$ELSE}ftWideMemo{$ENDIF};\n    {$IFDEF WITH_FTDATASETSUPPORT}\n    stDataSet:\n      Result := ftDataSet;\n    {$ENDIF}\n    else\n      Result := ftUnknown;\n  end;\nend;\n\n{**\n  Converts TDataset Field Type to DBC Field Type.\n  @param Value an initial TDataset field type.\n  @return a converted DBC field type.\n}\nfunction ConvertDatasetToDbcType(Value: TFieldType): TZSQLType;\nbegin\n  case Value of\n    ftBoolean:\n      Result := stBoolean;\n    ftSmallInt:\n      Result := stShort;\n    ftInteger, ftAutoInc:\n      Result := stInteger;\n    ftFloat:\n      Result := stDouble;\n    ftLargeInt:\n      Result := stLong;\n    ftCurrency:\n      Result := stBigDecimal;\n    ftString:\n      Result := stString;\n    ftBytes:\n      Result := stBytes;\n    ftDate:\n      Result := stDate;\n    ftTime:\n      Result := stTime;\n    ftDateTime:\n      Result := stTimestamp;\n    ftMemo:\n      Result := stAsciiStream;\n    ftBlob:\n      Result := stBinaryStream;\n    ftWideString:\n      Result := stUnicodeString;\n    {$IFDEF WITH_FTGUID}\n    ftGuid:\n      Result := stGUID;\n    {$ENDIF}\n    {$IFDEF WITH_WIDEMEMO}\n    ftWideMemo:\n      Result := stUnicodeStream;\n    {$ENDIF}\n    {$IFDEF WITH_FTDATASETSUPPORT}\n    ftDataSet:\n      Result := stDataSet;\n    {$ENDIF}\n    else\n      Result := stUnknown;\n  end;\nend;\n\n{**\n  Converts field definitions into column information objects.\n  @param Fields a collection of field definitions.\n  @return a collection of column information objects.\n}\nfunction ConvertFieldsToColumnInfo(Fields: TFields): TObjectList;\nvar\n  I: Integer;\n  Current: TField;\n  ColumnInfo: TZColumnInfo;\nbegin\n  Result := TObjectList.Create(True);\n  for I := 0 to Fields.Count - 1 do\n  begin\n    Current := Fields[I];\n    ColumnInfo := TZColumnInfo.Create;\n\n    ColumnInfo.ColumnType := ConvertDatasetToDbcType(Current.DataType);\n    ColumnInfo.ColumnName := Current.FieldName;\n    ColumnInfo.Precision := Current.Size;\n//This is a hack for stUnicodeStream because there is only ftWideString for both type\n    if ColumnInfo.ColumnType = stUnicodeString then\n      if Current.Size > 10240 then\n        ColumnInfo.ColumnType := stUnicodeStream;\n    ColumnInfo.Scale := 0;\n    ColumnInfo.ColumnLabel := Current.DisplayName;\n    ColumnInfo.ColumnDisplaySize := Current.DisplayWidth;\n    ColumnInfo.DefaultExpression := Current.DefaultExpression;\n\n    Result.Add(ColumnInfo);\n  end;\nend;\n\n{**\n  Fetches columns from specified resultset.\n  @param ResultSet a source resultset.\n  @param FieldsLookupTable a lookup table to define original index.\n  @param Fields a collection of field definitions.\n  @param RowAccessor a destination row accessor.\n}\nprocedure FetchFromResultSet(ResultSet: IZResultSet;\n  const FieldsLookupTable: TIntegerDynArray; Fields: TFields;\n  RowAccessor: TZRowAccessor);\nvar\n  I, FieldIndex: Integer;\n  Current: TField;\n  ColumnIndex, ColumnCount: Integer;\nbegin\n  RowAccessor.RowBuffer.Index := ResultSet.GetRow;\n  ColumnCount := ResultSet.GetMetadata.GetColumnCount;\n\n  for I := 0 to Fields.Count - 1 do\n  begin\n    Current := Fields[I];\n    if not (Current.FieldKind in [fkData, fkInternalCalc]) then\n      Continue;\n\n    ColumnIndex := Current.FieldNo;\n    FieldIndex := DefineFieldIndex(FieldsLookupTable, Current);\n    if (ColumnIndex < 1) or (ColumnIndex > ColumnCount) then\n      Continue;\n\n    case Current.DataType of\n      ftBoolean:\n        RowAccessor.SetBoolean(FieldIndex, ResultSet.GetBoolean(ColumnIndex));\n      ftSmallInt:\n        RowAccessor.SetShort(FieldIndex, ResultSet.GetShort(ColumnIndex));\n      ftInteger, ftAutoInc:\n        RowAccessor.SetInt(FieldIndex, ResultSet.GetInt(ColumnIndex));\n      ftFloat:\n        RowAccessor.SetDouble(FieldIndex, ResultSet.GetDouble(ColumnIndex));\n      ftLargeInt:\n        RowAccessor.SetLong(FieldIndex, ResultSet.GetLong(ColumnIndex));\n      ftCurrency:\n        RowAccessor.SetBigDecimal(FieldIndex, ResultSet.GetBigDecimal(ColumnIndex));\n      ftString:\n        // gto: do we need PChar here?\n        //RowAccessor.SetPChar(FieldIndex, ResultSet.GetPChar(ColumnIndex));\n        RowAccessor.SetString(FieldIndex, ResultSet.GetString(ColumnIndex));\n      ftWidestring:\n        RowAccessor.SetUnicodeString(FieldIndex, ResultSet.GetUnicodeString(ColumnIndex));\n      ftBytes{$IFDEF WITH_FTGUID}, ftGuid{$ENDIF}:\n        RowAccessor.SetBytes(FieldIndex, ResultSet.GetBytes(ColumnIndex));\n      ftDate:\n        RowAccessor.SetDate(FieldIndex, ResultSet.GetDate(ColumnIndex));\n      ftTime:\n        RowAccessor.SetTime(FieldIndex, ResultSet.GetTime(ColumnIndex));\n      ftDateTime:\n        RowAccessor.SetTimestamp(FieldIndex, ResultSet.GetTimestamp(ColumnIndex));\n      ftMemo, ftBlob {$IFDEF WITH_WIDEMEMO}, ftWideMemo{$ENDIF}:\n        RowAccessor.SetBlob(FieldIndex, ResultSet.GetBlob(ColumnIndex));\n      {$IFDEF WITH_FTDATASETSUPPORT}\n      ftDataSet:\n        RowAccessor.SetDataSet(FieldIndex, ResultSet.GetDataSet(ColumnIndex));\n      {$ENDIF}\n    end;\n\n    if ResultSet.WasNull then\n      RowAccessor.SetNull(FieldIndex);\n  end;\nend;\n\n{**\n  Posts columns from specified resultset.\n  @param ResultSet a source resultset.\n  @param FieldsLookupTable a lookup table to define original index.\n  @param Fields a collection of field definitions.\n  @param RowAccessor a destination row accessor.\n}\nprocedure PostToResultSet(ResultSet: IZResultSet;\n  const FieldsLookupTable: TIntegerDynArray; Fields: TFields;\n  RowAccessor: TZRowAccessor);\nvar\n  I, FieldIndex: Integer;\n  Current: TField;\n  WasNull: Boolean;\n  ColumnIndex, ColumnCount: Integer;\n  Stream: TStream;\nbegin\n  WasNull := False;\n  RowAccessor.RowBuffer.Index := ResultSet.GetRow;\n  ColumnCount := ResultSet.GetMetadata.GetColumnCount;\n\n  for I := 0 to Fields.Count - 1 do\n  begin\n    Current := Fields[I];\n    if Current.FieldKind <> fkData then\n      Continue;\n\n    ColumnIndex := Current.FieldNo;\n    FieldIndex := DefineFieldIndex(FieldsLookupTable, Current);\n    if (ColumnIndex < 1) or (ColumnIndex > ColumnCount) then\n      Continue;\n\n//    if (Current.Required = True) and (WasNull = True) then\n//      raise EZDatabaseError.Create(Format(SFieldCanNotBeNull, [Current.FieldName]));\n    case Current.DataType of\n      ftBoolean:\n        ResultSet.UpdateBoolean(ColumnIndex, RowAccessor.GetBoolean(FieldIndex, WasNull));\n      ftSmallInt:\n        ResultSet.UpdateShort(ColumnIndex, RowAccessor.GetShort(FieldIndex, WasNull));\n      ftInteger, ftAutoInc:\n        ResultSet.UpdateInt(ColumnIndex, RowAccessor.GetInt(FieldIndex, WasNull));\n      ftFloat:\n        ResultSet.UpdateDouble(ColumnIndex, RowAccessor.GetDouble(FieldIndex, WasNull));\n      ftLargeInt:\n        ResultSet.UpdateLong(ColumnIndex, RowAccessor.GetLong(FieldIndex, WasNull));\n      ftCurrency:\n        ResultSet.UpdateBigDecimal(ColumnIndex,\n          RowAccessor.GetBigDecimal(FieldIndex, WasNull));\n      ftString:\n        ResultSet.UpdateString(ColumnIndex, RowAccessor.GetString(FieldIndex, WasNull));\n      ftWidestring:\n        ResultSet.UpdateUnicodeString(ColumnIndex,\n          RowAccessor.GetUnicodeString(FieldIndex, WasNull));\n      ftBytes{$IFDEF WITH_FTGUID}, ftGuid{$ENDIF}:\n        ResultSet.UpdateBytes(ColumnIndex, RowAccessor.GetBytes(FieldIndex, WasNull));\n      ftDate:\n        ResultSet.UpdateDate(ColumnIndex, RowAccessor.GetDate(FieldIndex, WasNull));\n      ftTime:\n        ResultSet.UpdateTime(ColumnIndex, RowAccessor.GetTime(FieldIndex, WasNull));\n      ftDateTime:\n        ResultSet.UpdateTimestamp(ColumnIndex,\n          RowAccessor.GetTimestamp(FieldIndex, WasNull));\n      ftMemo:\n        begin\n          Stream := RowAccessor.GetAsciiStream(FieldIndex, WasNull);\n          try\n            ResultSet.UpdateAsciiStream(ColumnIndex, Stream);\n          finally\n            Stream.Free;\n          end;\n        end;\n      {$IFDEF WITH_WIDEMEMO}\n      ftWideMemo:\n        begin\n          Stream := RowAccessor.GetUnicodeStream(FieldIndex, WasNull);\n          try\n            ResultSet.UpdateUnicodeStream(ColumnIndex, Stream);\n          finally\n            Stream.Free;\n          end;\n        end;\n      {$ENDIF}\n      ftBlob:\n        begin\n          Stream := RowAccessor.GetBinaryStream(FieldIndex, WasNull);\n          try\n            ResultSet.UpdateBinaryStream(ColumnIndex, Stream);\n          finally\n            Stream.Free;\n          end;\n        end;\n      {$IFDEF WITH_FTDATASETSUPPORT}\n      ftDataSet:\n        ResultSet.UpdateDataSet(ColumnIndex, RowAccessor.GetDataSet(FieldIndex, WasNull));\n      {$ENDIF}\n    end;\n\n    if WasNull then\n      begin\n        // Performance thing :\n        // The default expression will only be set when necessary : if the value really IS null\n        Resultset.UpdateDefaultExpression(ColumnIndex, RowAccessor.GetColumnDefaultExpression(FieldIndex));\n        ResultSet.UpdateNull(ColumnIndex);\n      end;\n  end;\nend;\n\n{**\n  Defines fields indices for the specified dataset.\n  @param DataSet a dataset object.\n  @param FieldNames a list of field names.\n  @param OnlyDataFields <code>True</code> if only data fields selected.\n}\nfunction DefineFields(DataSet: TDataset; const FieldNames: string;\n  var OnlyDataFields: Boolean): TObjectDynArray;\nvar\n  I: Integer;\n  Tokens: TStrings;\n  TokenType: TZTokenType;\n  TokenValue: string;\n  Field: TField;\n  FieldCount: Integer;\nbegin\n  OnlyDataFields := True;\n  FieldCount := 0;\n  SetLength(Result, FieldCount);\n  Tokens := CommonTokenizer.TokenizeBufferToList(FieldNames,\n    [toSkipEOF, toSkipWhitespaces, toUnifyNumbers, toDecodeStrings]);\n\n  try\n    for I := 0 to Tokens.Count - 1 do\n    begin\n      TokenType := TZTokenType({$IFDEF oldFPC}Pointer({$ENDIF}\n        Tokens.Objects[I]{$IFDEF oldFPC}){$ENDIF});\n      TokenValue := Tokens[I];\n      Field := nil;\n\n      if TokenType in [ttWord, ttQuoted] then\n      begin\n        Field := DataSet.FieldByName(TokenValue);\n      end\n      else if (TokenType = ttNumber)\n        and (StrToIntDef(TokenValue, 0) < Dataset.Fields.Count) then\n      begin\n        Field := Dataset.Fields[StrToIntDef(TokenValue, 0)];\n      end\n      else if (TokenValue <> ',') and (TokenValue <> ';') then\n      begin\n        raise EZDatabaseError.Create(Format(SIncorrectSymbol, [TokenValue]));\n      end;\n\n      if Field <> nil then\n      begin\n        OnlyDataFields := OnlyDataFields and (Field.FieldKind = fkData);\n        Inc(FieldCount);\n        SetLength(Result, FieldCount);\n        Result[FieldCount - 1] := Field;\n      end;\n    end;\n  finally\n    Tokens.Free;\n  end;\n\n  if Length(Result) = 0 then\n    Result := nil;\nend;\n\n{**\n  Defins a indices of filter fields.\n  @param Dataset a dataset object.\n  @param Expression a expression calculator.\n  @returns an array with field object references.\n}\nfunction DefineFilterFields(DataSet: TDataset;\n  Expression: IZExpression): TObjectDynArray;\nvar\n  I: Integer;\n  Current: TField;\nbegin\n  if Expression.Expression <> '' then\n  begin\n    SetLength(Result, Expression.DefaultVariables.Count);\n    for I := 0 to Expression.DefaultVariables.Count - 1 do\n    begin\n      Current := DataSet.FindField(Expression.DefaultVariables.Names[I]);\n      if Current <> nil then\n        Result[I] := Current\n      else\n        Result[I] := nil;\n    end;\n  end\n  else\n    SetLength(Result, 0);\nend;\n\n{**\n  Retrieves a set of specified field values.\n  @param FieldRefs an array with interested field object references.\n  @param ResultSet an initial result set object.\n  @param ResultValues a container for result values.\n  @return an array with field values.\n}\nprocedure RetrieveDataFieldsFromResultSet(const FieldRefs: TObjectDynArray;\n  ResultSet: IZResultSet; var ResultValues: TZVariantDynArray);\nvar\n  I, ColumnIndex: Integer;\nbegin\n  for I := 0 to High(FieldRefs) do\n  begin\n    ColumnIndex := TField(FieldRefs[I]).FieldNo;\n    if ColumnIndex >= 0 then\n    begin\n      case TField(FieldRefs[I]).DataType of\n        ftString:\n          DefVarManager.SetAsString(ResultValues[I],\n            ResultSet.GetString(ColumnIndex));\n        ftBoolean:\n          DefVarManager.SetAsBoolean(ResultValues[I],\n            ResultSet.GetBoolean(ColumnIndex));\n        ftSmallInt, ftInteger, ftAutoInc:\n          DefVarManager.SetAsInteger(ResultValues[I],\n            ResultSet.GetInt(ColumnIndex));\n        ftFloat:\n          DefVarManager.SetAsFloat(ResultValues[I],\n            ResultSet.GetDouble(ColumnIndex));\n        ftLargeInt:\n          DefVarManager.SetAsInteger(ResultValues[I],\n            ResultSet.GetLong(ColumnIndex));\n        ftCurrency:\n          DefVarManager.SetAsFloat(ResultValues[I],\n            ResultSet.GetBigDecimal(ColumnIndex));\n        ftDate, ftTime, ftDateTime:\n          DefVarManager.SetAsDateTime(ResultValues[I],\n            ResultSet.GetTimestamp(ColumnIndex));\n        ftWidestring:\n          DefVarManager.SetAsUnicodeString(ResultValues[I],\n            ResultSet.GetUnicodeString(ColumnIndex));\n        else\n          DefVarManager.SetAsString(ResultValues[I],\n            ResultSet.GetString(ColumnIndex));\n      end;\n      if ResultSet.WasNull then\n        ResultValues[I] := NullVariant;\n    end\n    else\n      ResultValues[I] := NullVariant;\n  end;\nend;\n\n{**\n  Retrieves a set of specified field values.\n  @param FieldRefs an array with interested field object references.\n  @param FieldIndices an array with interested field indices.\n  @param RowAccessor a row accessor object.\n  @param ResultValues a container for result values.\n  @return an array with field values.\n}\nprocedure RetrieveDataFieldsFromRowAccessor(const FieldRefs: TObjectDynArray;\n  const FieldIndices: TIntegerDynArray; RowAccessor: TZRowAccessor;\n  var ResultValues: TZVariantDynArray);\nvar\n  I: Integer;\n  ColumnIndex: Integer;\n  WasNull: Boolean;\nbegin\n  WasNull := False;\n  for I := 0 to High(FieldRefs) do\n  begin\n    ColumnIndex := FieldIndices[I];\n    case TField(FieldRefs[I]).DataType of\n      ftString:\n        DefVarManager.SetAsString(ResultValues[I],\n          RowAccessor.GetString(ColumnIndex, WasNull));\n      ftBoolean:\n        DefVarManager.SetAsBoolean(ResultValues[I],\n          RowAccessor.GetBoolean(ColumnIndex, WasNull));\n      ftSmallInt, ftInteger, ftAutoInc:\n        DefVarManager.SetAsInteger(ResultValues[I],\n          RowAccessor.GetInt(ColumnIndex, WasNull));\n      ftFloat:\n        DefVarManager.SetAsFloat(ResultValues[I],\n          RowAccessor.GetDouble(ColumnIndex, WasNull));\n      ftLargeInt:\n        DefVarManager.SetAsInteger(ResultValues[I],\n          RowAccessor.GetLong(ColumnIndex, WasNull));\n      ftCurrency:\n        DefVarManager.SetAsFloat(ResultValues[I],\n          RowAccessor.GetBigDecimal(ColumnIndex, WasNull));\n      ftDate, ftTime, ftDateTime:\n        DefVarManager.SetAsDateTime(ResultValues[I],\n          RowAccessor.GetTimestamp(ColumnIndex, WasNull));\n      ftWidestring:\n        DefVarManager.SetAsUnicodeString(ResultValues[I],\n          RowAccessor.GetUnicodeString(ColumnIndex, WasNull));\n      else\n        DefVarManager.SetAsString(ResultValues[I],\n          RowAccessor.GetString(ColumnIndex, WasNull));\n    end;\n    if WasNull then\n      ResultValues[I] := NullVariant;\n  end;\nend;\n\n{**\n  Copy a set of specified field values to variables.\n  @param Fields an array with interested field object references.\n  @param ResultSet an initial result set object.\n  @param Variables a list of variables.\n}\n{$IFDEF FPC}\n  {$HINTS OFF} //Temp seems not to be init...\n{$ENDIF}\nprocedure CopyDataFieldsToVars(const Fields: TObjectDynArray;\n  ResultSet: IZResultSet; Variables: IZVariablesList);\nvar\n  I, ColumnIndex: Integer;\n  Temp: TZVariant;\nbegin\n  for I := 0 to Length(Fields) - 1 do\n  begin\n    if Fields[I] = nil then\n      Continue;\n\n    ColumnIndex := TField(Fields[I]).FieldNo;\n    if not ResultSet.IsNull(ColumnIndex) then\n    begin\n      case TField(Fields[I]).DataType of\n        ftBoolean:\n          DefVarManager.SetAsBoolean(Temp, ResultSet.GetBoolean(ColumnIndex));\n        ftSmallInt, ftInteger, ftAutoInc:\n          DefVarManager.SetAsInteger(Temp, ResultSet.GetInt(ColumnIndex));\n        ftFloat:\n          DefVarManager.SetAsFloat(Temp, ResultSet.GetDouble(ColumnIndex));\n        ftLargeInt:\n          DefVarManager.SetAsInteger(Temp, ResultSet.GetLong(ColumnIndex));\n        ftCurrency:\n          DefVarManager.SetAsFloat(Temp, ResultSet.GetBigDecimal(ColumnIndex));\n        ftDate:\n          DefVarManager.SetAsDateTime(Temp, ResultSet.GetDate(ColumnIndex));\n        ftTime:\n          DefVarManager.SetAsDateTime(Temp, ResultSet.GetTime(ColumnIndex));\n        ftDateTime:\n          DefVarManager.SetAsDateTime(Temp, ResultSet.GetTimestamp(ColumnIndex));\n        ftWidestring:\n          DefVarManager.SetAsUnicodeString(Temp,\n            ResultSet.GetUnicodeString(ColumnIndex));\n        else\n          DefVarManager.SetAsString(Temp, ResultSet.GetString(ColumnIndex));\n      end;\n      Variables.Values[I] := Temp;\n    end\n    else\n    begin\n      DefVarManager.SetNull(Temp);\n      Variables.Values[I] := Temp;\n    end;\n  end;\nend;\n{$IFDEF FPC}\n  {$HINTS OFF}\n{$ENDIF}\n\n{**\n  Compares row field values with the given ones.\n  @param KeyValues given values.\n  @param RowValues row field values.\n  @param PartialKey <code>True</code> if values should be started with the keys.\n  @param CaseInsensitive <code>True</code> if keys are case insensitive.\n  @return <code> if values are equal.\n}\nfunction CompareDataFields(const KeyValues, RowValues: TZVariantDynArray;\n  PartialKey: Boolean; CaseInsensitive: Boolean): Boolean;\nvar\n  I: Integer;\n  Value1, Value2: AnsiString;\n  WValue1, WValue2: WideString;\nbegin\n  Result := True;\n  for I := 0 to High(KeyValues) do\n  begin\n    case KeyValues[I].VType of\n      vtUnicodeString:\n        begin\n          if CaseInsensitive then\n          begin\n            WValue1 := WideUpperCase(SoftVarManager.GetAsUnicodeString(KeyValues[I]));\n            WValue2 := WideUpperCase(SoftVarManager.GetAsUnicodeString(RowValues[I]));\n            if PartialKey then\n            begin\n              {$IFDEF UNICODE}\n              Result := SysUtils.AnsiStrLComp(PWideChar(WValue2), PWideChar(WValue1), Length(WValue1)) = 0;\n              {$ELSE}\n              Value1 := AnsiString(WValue1);\n              Value2 := AnsiString(WValue2);\n              Result := AnsiStrLComp(PAnsiChar(Value2), PAnsiChar(Value1), Length(Value1)) = 0;\n              {$ENDIF}\n            end\n            else\n              Result := WValue1 = WValue2\n          end\n          else\n          begin\n            WValue1 := SoftVarManager.GetAsUnicodeString(KeyValues[I]);\n            WValue1 := SoftVarManager.GetAsUnicodeString(RowValues[I]);\n            if PartialKey then\n            begin\n              {$IFDEF UNICODE}\n              Result := SysUtils.AnsiStrLComp(PWideChar(WValue2), PWideChar(WValue1), Length(WValue1)) = 0;\n              {$ELSE}\n              Value1 := AnsiString(WValue1);\n              Value2 := AnsiString(WValue2);\n              Result := AnsiStrLComp(PAnsiChar(Value2), PAnsiChar(Value1), Length(Value1)) = 0;\n              {$ENDIF}\n            end\n            else\n              Result := SoftVarManager.Compare(KeyValues[I], RowValues[I]) = 0;\n          end;\n        end;\n      else\n      begin\n        if CaseInsensitive then\n        begin\n          Value1 := AnsiString(AnsiUpperCase(SoftVarManager.GetAsString(KeyValues[I])));\n          Value2 := AnsiString(AnsiUpperCase(SoftVarManager.GetAsString(RowValues[I])));\n          if PartialKey then\n\n            Result := {$IFDEF WITH_ANSISTRLCOMP_DEPRECATED}AnsiStrings.{$ENDIF}AnsiStrLComp(PAnsiChar(Value2), PAnsiChar(Value1), Length(Value1)) = 0\n          else\n            Result := Value1 = Value2\n        end\n        else\n        begin\n          Value1 := AnsiString(SoftVarManager.GetAsString(KeyValues[I]));\n          Value2 := AnsiString(SoftVarManager.GetAsString(RowValues[I]));\n          if PartialKey then\n            Result := {$IFDEF WITH_ANSISTRLCOMP_DEPRECATED}AnsiStrings.{$ENDIF}AnsiStrLComp(PAnsiChar(Value2), PAnsiChar(Value1), Length(Value1)) = 0\n          else\n            Result := SoftVarManager.Compare(KeyValues[I], RowValues[I]) = 0;\n        end;\n      end;\n    end;\n\n    if not Result then\n      Break;\n  end;\nend;\n\n{**\n  Prepares values for comparison by CompareFieldsFromResultSet.\n  @param FieldRefs an array with interested field object references.\n  @param DecodedKeyValues given values.\n  @param ResultSet  a resultset to get field values.\n  @param PartialKey <code>True</code> if values should be started with the keys.\n  @param CaseInsensitive <code>True</code> if keys are case insensitive.\n}\nprocedure PrepareValuesForComparison(const FieldRefs: TObjectDynArray;\n  var DecodedKeyValues: TZVariantDynArray; ResultSet: IZResultSet;\n  PartialKey: Boolean; CaseInsensitive: Boolean);\nvar\n  I: Integer;\n  Current: TField;\n  CurrentType : TZSQLType;\nbegin\n  { Preprocesses cycle variables. }\n  for I := 0 to High(FieldRefs) do\n  begin\n    Current := TField(FieldRefs[I]);\n\n    if DecodedKeyValues[I].VType = vtNull then\n      Continue;\n\n    CurrentType := ResultSet.GetMetadata.GetColumnType(Current.FieldNo);\n\n    if PartialKey then\n    begin\n      if CurrentType = stUnicodeString then\n      begin\n        DecodedKeyValues[I] := SoftVarManager.Convert(\n          DecodedKeyValues[I], vtUnicodeString);\n        if CaseInsensitive then\n        begin\n          if DecodedKeyValues[I].VType = vtString then\n          begin\n            DecodedKeyValues[I].VString := Uppercase(DecodedKeyValues[I].VString);\n            DecodedKeyValues[I].VUnicodeString := DecodedKeyValues[I].VString;\n          end\n          else\n          begin\n            DecodedKeyValues[I].VUnicodeString :=\n              WideUpperCase(DecodedKeyValues[I].VUnicodeString);\n          end;\n        end;\n      end\n      else\n      begin\n        DecodedKeyValues[I] := SoftVarManager.Convert(\n          DecodedKeyValues[I], vtString);\n        if CaseInsensitive then\n        begin\n          {$IFDEF LAZARUSUTF8HACK} // Is this correct? Assumes the Lazarus convention all strings are UTF8. But is that\n                       // true in this point, or should that be converted higher up?\n          DecodedKeyValues[I].VString := \n            WideUpperCase(UTF8Decode (DecodedKeyValues[I].VString)); \n          {$ELSE} \n          DecodedKeyValues[I].VString := \n            AnsiUpperCase(DecodedKeyValues[I].VString); \n          {$ENDIF} \n        end;\n      end;\n    end\n    else\n    begin\n      case CurrentType of\n        stBoolean:\n          DecodedKeyValues[I] := SoftVarManager.Convert(\n            DecodedKeyValues[I], vtBoolean);\n        stByte, stShort, stInteger, stLong:\n          DecodedKeyValues[I] := SoftVarManager.Convert(\n            DecodedKeyValues[I], vtInteger);\n        stFloat, stDouble, stBigDecimal:\n          DecodedKeyValues[I] := SoftVarManager.Convert(\n            DecodedKeyValues[I], vtFloat);\n        stUnicodeString:\n          begin\n            if CaseInsensitive then\n            begin\n              if DecodedKeyValues[I].VType = vtString then\n              begin\n                DecodedKeyValues[I].VString := Uppercase(DecodedKeyValues[I].VString);\n                DecodedKeyValues[I].VUnicodeString := DecodedKeyValues[I].VString;\n              end\n              else\n              begin\n                DecodedKeyValues[I].VUnicodeString :=\n                  WideUpperCase(DecodedKeyValues[I].VUnicodeString);\n              end;\n            end\n            else\n            begin\n              DecodedKeyValues[I] := SoftVarManager.Convert(\n                DecodedKeyValues[I], vtUnicodeString);\n            end;\n          end;\n        stDate, stTime, stTimestamp:\n          DecodedKeyValues[I] := SoftVarManager.Convert(\n            DecodedKeyValues[I], vtDateTime);\n        else\n          if CaseInsensitive then\n          begin\n            DecodedKeyValues[I] := SoftVarManager.Convert( \n              DecodedKeyValues[I], vtString); \n            {$IFDEF LAZARUSUTF8HACK}\n                    // Is this correct? Assumes the Lazarus convention all strings are UTF8. But is that\n                    // true in this point, or should that be converted higher up?\n            DecodedKeyValues[I].VString :=\n              WideUpperCase(UTF8Decode (DecodedKeyValues[I].VString));\n            {$ELSE} \n            DecodedKeyValues[I].VString := \n              AnsiUpperCase(DecodedKeyValues[I].VString); \n            {$ENDIF} \n          end\n          else\n          begin\n            DecodedKeyValues[I] := SoftVarManager.Convert(\n              DecodedKeyValues[I], vtString);\n          end;\n      end;\n    end;\n  end;\nend;\n\n{**\n  Compares row field values with the given ones.\n  @param FieldRefs an array with interested field object references.\n  @param KeyValues given values.\n  @param ResultSet  a resultset to get field values.\n  @param PartialKey <code>True</code> if values should be started with the keys.\n  @param CaseInsensitive <code>True</code> if keys are case insensitive.\n  @return <code> if values are equal.\n}\nfunction CompareFieldsFromResultSet(const FieldRefs: TObjectDynArray;\n  const KeyValues: TZVariantDynArray; ResultSet: IZResultSet; PartialKey: Boolean;\n  CaseInsensitive: Boolean): Boolean;\nvar\n  I: Integer;\n  ColumnIndex: Integer;\n  AValue1, AValue2: AnsiString;\n  WValue1, WValue2: WideString;\n  CurrentType : TZSQLType;\nbegin\n  Result := True;\n  for I := 0 to High(KeyValues) do\n  begin\n    ColumnIndex := TField(FieldRefs[I]).FieldNo;\n\n    if KeyValues[I].VType = vtNull then\n    begin\n      Result := ResultSet.IsNull(ColumnIndex);\n      if not Result then\n         Break;\n      Continue;\n    end;\n\n    CurrentType := ResultSet.GetMetadata.GetColumnType(ColumnIndex);\n\n    if PartialKey then\n    begin\n      if CurrentType = stUnicodeString then\n      begin\n        WValue1 := KeyValues[I].VUnicodeString;\n        WValue2 := ResultSet.GetUnicodeString(ColumnIndex);\n\n        if CaseInsensitive then\n          WValue2 := WideUpperCase(WValue2);\n        {$IFDEF UNICODE}\n        Result := SysUtils.AnsiStrLComp(PWideChar(WValue2), PWideChar(WValue1), Length(WValue1)) = 0;\n        {$ELSE}\n          AValue1 := UTF8ToAnsi(UTF8Encode(WValue1));\n          AValue2 := UTF8ToAnsi(UTF8Encode(WValue2));\n          Result := AnsiStrLComp(PAnsiChar(AValue2), PAnsiChar(AValue1), Length(AValue1)) = 0;\n        {$ENDIF}\n      end\n      else\n      begin\n        AValue1 := AnsiString(KeyValues[I].VString);\n        if (ResultSet.GetConSettings.ClientCodePage^.Encoding = ceAnsi)\n          or (ResultSet.GetConSettings.AutoEncode and ( ResultSet.GetConSettings.CTRL_CP <> 65001 )) then\n          AValue2 := AnsiString(ResultSet.GetString(ColumnIndex))\n        else\n          AValue2 := AnsiString({$IFNDEF UNICODE}UTF8ToAnsi{$ENDIF}(ResultSet.GetString(ColumnIndex)));\n\n        if CaseInsensitive then\n          AValue2 := {$IFDEF WITH_UNITANSISTRINGS}AnsiStrings.{$ENDIF}AnsiUpperCase(AValue2);\n        Result := {$IFDEF WITH_ANSISTRLCOMP_DEPRECATED}AnsiStrings.{$ENDIF}AnsiStrLComp(PAnsiChar(AValue2), PAnsiChar(AValue1), Length(AValue1)) = 0;\n      end;\n\n    end\n    else\n    begin\n      case CurrentType of\n        stBoolean:\n          begin\n            Result := KeyValues[I].VBoolean =\n              ResultSet.GetBoolean(ColumnIndex);\n          end;\n        stByte,\n        stShort,\n        stInteger,\n        stLong:\n          begin\n            Result := KeyValues[I].VInteger =\n              ResultSet.GetLong(ColumnIndex);\n          end;\n        stFloat:\n            Result := Abs(KeyValues[I].VFloat -\n              ResultSet.GetBigDecimal(ColumnIndex)) < FLOAT_COMPARE_PRECISION_SINGLE;\n        stDouble,\n        stBigDecimal:\n          begin\n            Result := Abs(KeyValues[I].VFloat -\n              ResultSet.GetBigDecimal(ColumnIndex)) < FLOAT_COMPARE_PRECISION;\n          end;\n        stDate,\n        stTime,\n        stTimestamp:\n          begin\n            Result := KeyValues[I].VDateTime =\n              ResultSet.GetTimestamp(ColumnIndex);\n          end;\n        stUnicodeString:\n          begin\n            if CaseInsensitive then\n            begin\n              Result := KeyValues[I].VUnicodeString =\n                WideUpperCase(ResultSet.GetUnicodeString(ColumnIndex));\n            end\n            else\n            begin\n              Result := KeyValues[I].VUnicodeString =\n                ResultSet.GetUnicodeString(ColumnIndex);\n            end;\n          end;\n        else\n          if CaseInsensitive then\n          begin\n            {$IFDEF LAZARUSUTF8HACK}\n            Result := KeyValues[I].VString = \n              AnsiUpperCase (Utf8ToAnsi(ResultSet.GetString(ColumnIndex))); \n            {$ELSE} \n            Result := KeyValues[I].VString = \n              AnsiUpperCase(ResultSet.GetString(ColumnIndex)); \n            {$ENDIF} \n          end\n          else\n          begin\n            Result := KeyValues[I].VString =\n              ResultSet.GetString(ColumnIndex);\n          end;\n      end;\n    end;\n\n    Result := Result and not ResultSet.WasNull;\n    if not Result then\n      Break;\n  end;\nend;\n\n{**\n  Defines a list of key field names.\n  @param Fields a collection of dataset fields.\n  @return a list of key field names.\n}\nfunction DefineKeyFields(Fields: TFields): string;\nvar\n  I: Integer;\n  Temp: string;\nbegin\n  Result := '';\n  for I := 0 to Fields.Count - 1 do\n  begin\n    if (Fields[I].FieldKind = fkData)\n      and not (Fields[I].DataType in [ftBlob, ftMemo, ftBytes {$IFDEF WITH_WIDEMEMO}, ftWideMemo{$ENDIF}]) then\n    begin\n      if Result <> '' then\n        Result := Result + ',';\n      Temp := Fields[I].FieldName;\n      if (Pos(' ', Temp) > 0) or (Pos('-', Temp) > 0) or (Pos('.', Temp) > 0) then\n        Temp := '\"' + Temp + '\"';\n      Result := Result + Temp;\n    end;\n  end;\nend;\n\n{**\n  Converts datetime value into TDataset internal presentation.\n  @param DataType a type of date-time field.\n  @param Data a data which contains a value.\n  @param Buffer a field buffer pointer\n}\nprocedure DateTimeToNative(DataType: TFieldType; Data: TDateTime;\n  Buffer: Pointer);\nvar\n  TimeStamp: TTimeStamp;\nbegin\n  TimeStamp := DateTimeToTimeStamp(Data);\n  case DataType of\n    ftDate: Integer(Buffer^) := TimeStamp.Date;\n    ftTime: Integer(Buffer^) := TimeStamp.Time;\n  else\n    TDateTime(Buffer^) := TimeStampToMSecs(TimeStamp);\n  end;\nend;\n\n{**\n  Converts date times from TDataset internal presentation into datetime value.\n  @param DataType a type of date-time field.\n  @param Buffer a field buffer pointer\n  @return a data which contains a value.\n}\nfunction NativeToDateTime(DataType: TFieldType; Buffer: Pointer): TDateTime;\n{$IFNDEF OLDFPC}\nvar\n  TimeStamp: TTimeStamp;\nbegin\n  case DataType of\n    ftDate:\n      begin\n        TimeStamp.Time := 0;\n        TimeStamp.Date := Integer(Buffer^);\n      end;\n    ftTime:\n      begin\n        {$IFDEF WITH_FPC_FTTIME_BUG}\n        TimeStamp := DateTimeToTimeStamp(TDateTime(Buffer^));\n        {$ELSE}\n        TimeStamp.Time := Integer(Buffer^);\n        TimeStamp.Date := DateDelta;\n        {$ENDIF}\n      end;\n  else\n    try\n      {$IF not defined(cpui386) and defined(FPC)}\n      TimeStamp := MSecsToTimeStamp(System.Trunc(Int(TDateTime(Buffer^))));\n      {$ELSE}\n        TimeStamp := MSecsToTimeStamp(TDateTime(Buffer^));\n      {$IFEND}\n    except\n      TimeStamp.Time := 0;\n      TimeStamp.Date := 0;\n    end;\n  end;\n  Result := TimeStampToDateTime(TimeStamp);\n{$ELSE}\nbegin\n  Result := TDateTime(Buffer^);\n{$ENDIF}\nend;\n\n{**\n  Compare values from two key fields.\n  @param Field1 the first field object.\n  @param ResultSet the resultset to read the first field value.\n  @param Field2 the second field object.\n}\nfunction CompareKeyFields(Field1: TField; ResultSet: IZResultSet;\n  Field2: TField): Boolean;\nbegin\n  Result := False;\n  if Field1.FieldNo >= 1 then\n  begin\n    case Field1.DataType of\n      ftBoolean:\n        Result := ResultSet.GetBoolean(Field1.FieldNo) = Field2.AsBoolean;\n      ftSmallInt, ftInteger, ftAutoInc:\n        Result := ResultSet.GetInt(Field1.FieldNo) = Field2.AsInteger;\n      ftFloat:\n        begin\n          Result := Abs(ResultSet.GetFloat(Field1.FieldNo)\n            - Field2.AsFloat) < FLOAT_COMPARE_PRECISION;\n        end;\n      ftLargeInt:\n        begin\n          if Field2 is TLargeIntField then\n            Result := ResultSet.GetLong(Field1.FieldNo)\n              = TLargeIntField(Field2).AsLargeInt\n          else\n            Result := ResultSet.GetInt(Field1.FieldNo) = Field2.AsInteger;\n        end;\n      ftCurrency:\n        begin \n          Result := Abs(ResultSet.GetBigDecimal(Field1.FieldNo) \n            - Field2.{$IFDEF WITH_ASCURRENCY}AsCurrency{$ELSE}AsFloat{$ENDIF})\n            < FLOAT_COMPARE_PRECISION;\n        end;\n      ftDate:\n        Result := ResultSet.GetDate(Field1.FieldNo) = Field2.AsDateTime;\n      ftTime:\n        Result := ResultSet.GetTime(Field1.FieldNo) = Field2.AsDateTime;\n      ftDateTime:\n        Result := ResultSet.GetTimestamp(Field1.FieldNo) = Field2.AsDateTime;\n      ftWideString:\n        Result := ResultSet.GetUnicodeString(Field1.FieldNo) =\n          Field2.{$IFDEF WITH_ASVARIANT}AsVariant{$ELSE}AsString{$ENDIF};\n      else\n        Result := ResultSet.GetString(Field1.FieldNo) = Field2.AsString;\n    end;\n  end;\nend;\n\n{**\n  Defins a indices and directions for sorted fields.\n  @param Dataset a dataset object.\n  @param SortedFields an encoded fields for sorting in the format\n    <Field Name> [ASC | DESC] [, ...]\n  @param FieldRefs a decoded field object references.\n  @param FieldDirs a decoded field directions.\n  @param OnlyDataFields <code>True</code> if only data fields selected.\n}\nprocedure DefineSortedFields(DataSet: TDataset;\n  const SortedFields: string; var FieldRefs: TObjectDynArray;\n  var FieldDirs: TBooleanDynArray; var OnlyDataFields: Boolean);\nvar\n  I: Integer;\n  Tokens: TStrings;\n  TokenType: TZTokenType;\n  TokenValue: string;\n  Field: TField;\n  FieldCount: Integer;\nbegin\n  OnlyDataFields := True;\n  FieldCount := 0;\n  SetLength(FieldRefs, FieldCount);\n  SetLength(FieldDirs, FieldCount);\n  Tokens := CommonTokenizer.TokenizeBufferToList(SortedFields,\n    [toSkipEOF, toSkipWhitespaces, toUnifyNumbers, toDecodeStrings]);\n\n  try\n    for I := 0 to Tokens.Count - 1 do\n    begin\n      TokenType := TZTokenType({$IFDEF OLDFPC}Pointer({$ENDIF}\n        Tokens.Objects[I]{$IFDEF OLDFPC}){$ENDIF});\n      TokenValue := Tokens[I];\n      Field := nil;\n\n      if ((UpperCase(TokenValue) = 'DESC')\n        or (UpperCase(TokenValue) = 'ASC')) and (FieldCount > 0) then\n      begin\n        FieldDirs[FieldCount - 1] := (UpperCase(TokenValue) <> 'DESC');\n      end\n      else if TokenType in [ttWord, ttQuoted] then\n      begin\n        Field := DataSet.FieldByName(TokenValue)\n      end\n      else if (TokenType = ttNumber)\n        and (StrToIntDef(TokenValue, 0) < Dataset.Fields.Count) then\n      begin\n        Field := Dataset.Fields[StrToIntDef(TokenValue, 0)];\n      end\n      else if (TokenValue <> ',') and (TokenValue <> ';') then\n      begin\n        raise EZDatabaseError.Create(Format(SIncorrectSymbol, [TokenValue]));\n      end;\n\n      if Field <> nil then\n      begin\n        OnlyDataFields := OnlyDataFields and (Field.FieldKind = fkData);\n        Inc(FieldCount);\n        SetLength(FieldRefs, FieldCount);\n        SetLength(FieldDirs, FieldCount);\n        FieldRefs[FieldCount - 1] := Field;\n        FieldDirs[FieldCount - 1] := True;\n      end;\n    end;\n  finally\n    Tokens.Free;\n  end;\nend;\n\n{**\n  Creates a fields lookup table to define fixed position\n  of the field in dataset.\n  @param Fields a collection of TDataset fields in initial order.\n  @returns a fields lookup table.\n}\nfunction CreateFieldsLookupTable(Fields: TFields): TIntegerDynArray;\nvar\n  I: Integer;\nbegin\n  SetLength(Result, Fields.Count);\n  for I := 0 to Fields.Count - 1 do\n    Result[I] := Integer(Fields[I]);\nend;\n\n{**\n  Defines an original field index in the dataset.\n  @param FieldsLookupTable a lookup table to define original index.\n  @param Field a TDataset field object.\n  @returns an original fields index or -1 otherwise.\n}\nfunction DefineFieldIndex(const FieldsLookupTable: TIntegerDynArray;\n  Field: TField): Integer;\nvar\n  I: Integer;\nbegin\n  Result := -1;\n  for I := 0 to High(FieldsLookupTable) do\n  begin\n    if FieldsLookupTable[I] = Integer(Field) then\n    begin\n      Result := I + 1;\n      Break;\n    end;\n  end;\nend;\n\n{**\n  Defines an original field indices in the dataset.\n  @param FieldsLookupTable a lookup table to define original index.\n  @param FieldRefs a TDataset field object references.\n  @returns an array with original fields indices.\n}\nfunction DefineFieldIndices(const FieldsLookupTable: TIntegerDynArray;\n  const FieldRefs: TObjectDynArray): TIntegerDynArray;\nvar\n  I: Integer;\nbegin\n  if FieldRefs = nil then\n  begin\n    Result := nil;\n    Exit;\n  end;\n\n  SetLength(Result, Length(FieldRefs));\n  for I := 0 to High(Result) do\n    Result[I] := DefineFieldIndex(FieldsLookupTable, TField(FieldRefs[I]));\nend;\n\n{**\n  Splits up a qualified object name into pieces. Catalog, schema\n  and objectname.\n}\nprocedure SplitQualifiedObjectName(QualifiedName: string;\n  var Catalog, Schema, ObjectName: string);\n\n{$IFDEF OLDFPC}\nfunction ExtractStrings(Separators, WhiteSpace: TSysCharSet; Content: PChar;\n  Strings: TStrings): Integer;\nvar\n  Head, Tail: PChar;\n  EOS, InQuote: Boolean;\n  QuoteChar: Char;\n  Item: string;\nbegin\n  Result := 0;\n  if (Content = nil) or (Content^ = #0) or (Strings = nil) then\n     Exit;\n  Tail := Content;\n  InQuote := False;\n  QuoteChar := #0;\n  Strings.BeginUpdate;\n  try\n    repeat\n      while CharInSet(Tail^, WhiteSpace + [#13, #10]) do\n        Inc(Tail);\n      Head := Tail;\n      while True do\n      begin\n        while (InQuote and not CharInSet(Tail^, [QuoteChar, #0])) or\n               not CharInSet(Tail^, Separators + [#0, #13, #10, '''', '\"']) do\n           Inc(Tail);\n        if CharInSet(Tail^, ['''', '\"']) then\n        begin\n          if (QuoteChar <> #0) and (QuoteChar = Tail^) then\n            QuoteChar := #0\n          else\n            QuoteChar := Tail^;\n          InQuote := QuoteChar <> #0;\n          Inc(Tail);\n        end\n        else\n          Break;\n      end;\n      EOS := Tail^ = #0;\n      if (Head <> Tail) and (Head^ <> #0) then\n      begin\n        if Strings <> nil then\n        begin\n          SetString(Item, Head, Tail - Head);\n          Strings.Add(Item);\n        end;\n        Inc(Result);\n      end;\n      Inc(Tail);\n    until EOS;\n  finally\n    Strings.EndUpdate;\n  end;\nend;\n{$ENDIF}\n\nvar\n  SL: TStringList;\n  I: Integer;\nbegin\n  SL := TStringList.Create;\n  try\n    Catalog := '';\n    Schema := '';\n    ObjectName := QualifiedName;\n    ExtractStrings(['.'], [' '], PChar(QualifiedName), SL);\n    case SL.Count of\n      0, 1: ;\n      2: begin\n           Schema := SL.Strings[0];\n           ObjectName := SL.Strings[1];\n         end;\n      3: begin\n           Catalog := SL.Strings[0];\n           Schema := SL.Strings[1];\n           ObjectName := SL.Strings[2];\n         end;\n    else\n      begin\n        ObjectName := SL.Strings[SL.Count - 1];\n        Schema := SL.Strings[SL.Count - 2];\n        for I := 0 to SL.Count - 3 do\n        begin\n          Catalog := Catalog + SL.Strings[I];\n          if I < SL.Count - 3 then\n            Catalog := Catalog + '.';\n        end;\n      end;\n    end;\n  finally\n    SL.Free;\n  end;\nend;\n\n{**\n  Splits up a qualified object name into pieces. Catalog, schema\n  and objectname.\n}\nprocedure SplitQualifiedObjectName(QualifiedName: string;\n  const SupportsCatalogs, SupportsSchemas: Boolean;\n  var Catalog, Schema, ObjectName: string);\nvar\n  SL: TStringList;\n  I: Integer;\nbegin\n  if SupportsCatalogs and SupportsSchemas then\n    SplitQualifiedObjectName(QualifiedName, Catalog, Schema, ObjectName)\n  else\n  begin\n    SL := TStringList.Create;\n    try\n      Catalog := '';\n      Schema := '';\n      ObjectName := QualifiedName;\n      ExtractStrings(['.'], [' '], PChar(QualifiedName), SL);\n      case SL.Count of\n        0, 1: ;\n        2:\n          begin\n            if SupportsCatalogs then\n            begin\n              Catalog := SL.Strings[0];\n              if SupportsSchemas then\n                Schema := SL.Strings[1]\n              else\n                ObjectName := SL.Strings[1];\n            end\n            else\n              if SupportsSchemas then\n              begin\n                Schema := SL.Strings[0];\n                ObjectName := SL.Strings[1];\n              end\n              else\n                ObjectName := SL.Strings[0]+'.'+SL.Strings[1];\n          end;\n        3:\n          if SupportsCatalogs then\n          begin\n            Catalog := SL.Strings[0];\n            if SupportsSchemas then\n            begin\n              Schema := SL.Strings[1];\n              ObjectName := SL.Strings[2]\n            end\n            else\n              ObjectName := SL.Strings[1]+'.'+SL.Strings[2];\n          end\n          else\n            if SupportsSchemas then\n            begin\n              Schema := SL.Strings[0];\n              ObjectName := SL.Strings[1]+'.'+SL.Strings[2];\n            end\n            else\n              ObjectName := SL.Strings[0]+'.'+SL.Strings[1]+'.'+SL.Strings[2];\n        else\n          if SupportsCatalogs then\n          begin\n            Catalog := SL.Strings[0];\n            if SupportsSchemas then\n            begin\n              Schema := SL.Strings[1];\n              for i := 2 to SL.Count-1 do\n                if i = 2 then\n                  ObjectName := SL.Strings[i]\n                else\n                  ObjectName := ObjectName+'.'+SL.Strings[i];\n            end\n            else\n            begin\n              ObjectName := '';\n              for i := 2 to SL.Count-1 do\n                if I = 2 then\n                  ObjectName := SL.Strings[i]\n                else\n                  ObjectName := ObjectName+'.'+SL.Strings[i];\n            end;\n          end\n          else\n            if SupportsSchemas then\n            begin\n              Schema := SL.Strings[0];\n              for i := 1 to SL.Count-1 do\n                if i = 1 then\n                  ObjectName := SL.Strings[i]\n                else\n                  ObjectName := ObjectName+'.'+SL.Strings[i];\n            end\n            else\n              for i := 0 to SL.Count-1 do\n                if I = 0 then\n                  ObjectName := SL.Strings[i]\n                else\n                  ObjectName := ObjectName+'.'+SL.Strings[i];\n        end;\n    finally\n      SL.Free;\n    end;\n  end;\nend;\n\n{**\n  Assigns a Statement value from a TParam\n  @param Index the index of Statement.SetXxxx(ColumnIndex, xxx);\n  @param Statement the PrepredStatement where the values have been assigned\n  @param Param the TParam where the value is assigned from\n}\nprocedure SetStatementParam(Index: Integer;\n  Statement: IZPreparedStatement; Param: TParam);\nvar\n  Stream: TStream;\n  TempBytes: TByteDynArray;\n  {$IFDEF WITH_ASBYTES}Bts: TBytes;{$ENDIF}\n  {$IFDEF WITHOUT_VARBYTESASSTRING}V: Variant;{$ENDIF}\nbegin\n  if Param.IsNull then\n    Statement.SetNull(Index, ConvertDatasetToDbcType(Param.DataType))\n  else\n  begin\n    case Param.DataType of\n      ftBoolean:\n        Statement.SetBoolean(Index, Param.AsBoolean);\n      ftSmallInt{$IFDEF WITH_FTSHORTINT}, ftShortInt{$ENDIF}:\n        Statement.SetShort(Index, Param.AsSmallInt);\n      ftInteger, ftAutoInc{$IFDEF WITH_FTBYTE}, ftByte{$ENDIF}:\n        Statement.SetInt(Index, Param.AsInteger);\n      ftFloat{$IFDEF WITH_FTEXTENDED}, ftExtended{$ENDIF}:\n        Statement.SetDouble(Index, Param.AsFloat);\n      {$IFDEF WITH_FTLONGWORD}\n      ftLongWord:\n        Statement.SetInt(Index, Integer(Param.AsLongWord));\n      {$ENDIF}\n      ftLargeInt:\n        Statement.SetLong(Index, StrToInt64(Param.AsString));\n      ftCurrency, ftBCD:\n        Statement.SetBigDecimal(Index, Param.AsCurrency);\n      ftString, ftFixedChar:\n        Statement.SetString(Index, Param.AsString);\n      {$IFDEF WITH_FTWIDESTRING}\n      ftWideString:\n        Statement.SetUnicodeString(Index, Param.AsWideString);\n      {$ENDIF}\n      ftBytes, ftVarBytes{$IFDEF WITH_FTGUID}, ftGuid{$ENDIF}:\n        begin\n          {$IFDEF WITH_ASBYTES}\n          Bts := Param.AsBytes;\n          SetLength(TempBytes, High(Bts)+1);\n          System.Move(PAnsichar(Bts)^, PAnsichar(TempBytes)^, High(Bts)+1);\n          {$ELSE}\n            {$IFDEF WITHOUT_VARBYTESASSTRING}\n            V := Param.Value;\n            TempBytes := V;\n            {$ELSE}\n            TempBytes := StrToBytes(Param.AsString);\n            {$ENDIF}\n          {$ENDIF}\n          Statement.SetBytes(Index, TempBytes);\n        end;\n      ftDate:\n        Statement.SetDate(Index, Param.AsDate);\n      ftTime:\n        Statement.SetTime(Index, Param.AsTime);\n      ftDateTime:\n        Statement.SetTimestamp(Index, Param.AsDateTime);\n      ftMemo:\n        begin\n          {EgonHugeist: On reading a Param as Memo the Stream reads Byte-wise\n            on Changing to stUnicodeString/Delphi12Up a String is from\n            Type wide/unicode so we have to give him back as\n            Stream!}\n            {$IFDEF UNICODE}\n            Stream := Param.AsStream;\n            {$ELSE}\n            Stream := TStringStream.Create(Param.AsMemo);\n            {$ENDIF}\n          try\n            Statement.SetAsciiStream(Index, Stream);\n          finally\n            Stream.Free;\n          end;\n        end;\n      {$IFDEF WITH_WIDEMEMO}\n      ftWideMemo:\n        begin\n          Stream := WideStringStream(Param.AsWideString);\n          try\n            Statement.SetUnicodeStream(Index, Stream);\n           finally\n             Stream.Free;\n           end;\n        end;\n      {$ENDIF}\n      ftBlob, ftGraphic:\n        begin\n          Stream := TStringStream.Create(Param.AsBlob);\n          try\n            Statement.SetBinaryStream(Index, Stream);\n          finally\n            Stream.Free;\n          end;\n        end;\n      else\n        raise EZDatabaseError.Create(SUnKnownParamDataType + IntToStr(Ord(Param.DataType)));\n    end;\n  end;\nend;\n\ninitialization\n  CommonTokenizer := TZGenericSQLTokenizer.Create;\nfinalization\n  CommonTokenizer := nil;\nend.\n\n"
  },
  {
    "path": "lib/zeosdbo/src/component/ZGroupedConnection.pas",
    "content": "{*********************************************************}\n{                                                         }\n{                 Zeos Database Objects                   }\n{      Grouped Database Connection Component              }\n{                                                         }\n{        Originally written by una.bicicleta              }\n{*********************************************************}\n\n{@********************************************************}\n{    Copyright (c) 1999-2012 Zeos Development Group       }\n{                                                         }\n{ License Agreement:                                      }\n{                                                         }\n{ This library is distributed in the hope that it will be }\n{ useful, but WITHOUT ANY WARRANTY; without even the      }\n{ implied warranty of MERCHANTABILITY or FITNESS FOR      }\n{ A PARTICULAR PURPOSE.  See the GNU Lesser General       }\n{ Public License for more details.                        }\n{                                                         }\n{ The source code of the ZEOS Libraries and packages are  }\n{ distributed under the Library GNU General Public        }\n{ License (see the file COPYING / COPYING.ZEOS)           }\n{ with the following  modification:                       }\n{ As a special exception, the copyright holders of this   }\n{ library give you permission to link this library with   }\n{ independent modules to produce an executable,           }\n{ regardless of the license terms of these independent    }\n{ modules, and to copy and distribute the resulting       }\n{ executable under terms of your choice, provided that    }\n{ you also meet, for each linked independent module,      }\n{ the terms and conditions of the license of that module. }\n{ An independent module is a module which is not derived  }\n{ from or based on this library. If you modify this       }\n{ library, you may extend this exception to your version  }\n{ of the library, but you are not obligated to do so.     }\n{ If you do not wish to do so, delete this exception      }\n{ statement from your version.                            }\n{                                                         }\n{                                                         }\n{ The project web site is located on:                     }\n{   http://zeos.firmos.at  (FORUM)                        }\n{   http://sourceforge.net/p/zeoslib/tickets/ (BUGTRACKER)}\n{   svn://svn.code.sf.net/p/zeoslib/code-0/trunk (SVN)    }\n{                                                         }\n{   http://www.sourceforge.net/projects/zeoslib.          }\n{                                                         }\n{                                                         }\n{                                 Zeos Development Group. }\n{********************************************************@}\n\nunit ZGroupedConnection;\n\ninterface\n{$I ZComponent.inc}\n\nuses\n  SysUtils, Messages, Classes, ZDbcIntfs, DB,Forms,\n  ZCompatibility, ZAbstractConnection, ZSequence, Dialogs,\n  ZConnectionGroup {$IFDEF FPC}, LMessages{$ENDIF};\n\n{$IFNDEF FPC}\n const  CM_ZCONNECTIONGROUPCHANGED = WM_USER + 100;\n const  CM_ZCONNECTIONGROUPCHANGE  = WM_USER + 101;\n{$ELSE}\nconst  CM_ZCONNECTIONGROUPCHANGED = LM_USER + 100;\nconst  CM_ZCONNECTIONGROUPCHANGE  = LM_USER + 101;\n{$ENDIF}\n\ntype\n  TMsgZDbConnecitionChange = record\n    Msg: Cardinal;\n    Sender: TComponent;\n    ZConnectionGroup: TZConnectionGroup;\n    Result: Longint;\n  end;\n\n{$HINTS OFF}\ntype\n  TZGroupedConnection  = class(tZAbstractConnection)\n  protected\n    FZConnectionGroup: TZConnectionGroup;\n    FZConnectionGroupLink: TZConnectionGroupLink;\n    procedure SetConnectionGroup(Value: TZConnectionGroup);\n    procedure Notification(AComponent: TComponent; Operation: TOperation);\n      override;\n  private\n    function getUser: string;\n    function getPassword: string;\n    function getHostName: string;\n    function getDatabase: string;\n    function GetLibLocation: String;\n    //function getCatalog: string;\n    procedure DoZConnectionGroupChange(Sender: TObject);\n    procedure ParentZConnectionGroupChange(var Msg: TMessage);\n  published\n    property ConnectionGroup: TZConnectionGroup read FZConnectionGroup write SetConnectionGroup;\n  public\n    constructor Create(AOwner: TComponent); override;\n    destructor Destroy; override;\n  end;\n{$HINTS ON}\n\nimplementation\n\nprocedure InternalZConnectionGroupChanged(AControl: TComponent; AZConnectionGroup: TZConnectionGroup);\nvar\n  Msg: TMsgZDbConnecitionChange;\nbegin\n  Msg.Msg := CM_ZCONNECTIONGROUPCHANGED;\n  Msg.Sender := AControl;\n  Msg.ZConnectionGroup := AZConnectionGroup;\n  Msg.Result := 0;\n  //AControl.Broadcast(Msg);\nend;\n\n// === { TZGroupedConnection  } =============================================\nconstructor TZGroupedConnection .Create(AOwner: TComponent);\nbegin\n  inherited Create(AOwner);\n  FZConnectionGroupLink := TZConnectionGroupLink.Create;\n  FZConnectionGroupLink.OnChange := DoZConnectionGroupChange;\nend;\n\ndestructor TZGroupedConnection .Destroy;\nbegin\n  FZConnectionGroupLink.Free;\n  inherited Destroy;\nend;\n\nprocedure TZGroupedConnection .DoZConnectionGroupChange(Sender: TObject);\nbegin\n  if (Sender is TZConnectionGroup) then\n  begin\n    FURL.UserName := (Sender as TZConnectionGroup).User;\n    FURL.Protocol := (Sender as TZConnectionGroup).Protocol;\n    FURL.Password := (Sender as TZConnectionGroup).Password;\n    FURL.HostName := (Sender as TZConnectionGroup).HostName;\n    FURL.Database := (Sender as TZConnectionGroup).Database;\n    FURL.LibLocation := (Sender as TZConnectionGroup).LibraryLocation;\n  end;\nend;\n\nprocedure TZGroupedConnection .ParentZConnectionGroupChange(var Msg: TMessage);\nbegin\n  InternalZConnectionGroupChanged(Self, FZConnectionGroup);\nend;\n\nprocedure TZGroupedConnection .Notification(AComponent: TComponent;\n  Operation: TOperation);\nbegin\n  inherited Notification(AComponent, Operation);\n\n  if (Operation = opRemove) then\n  begin\n    if (AComponent is TDataset) then\n      UnregisterDataSet(TDataset(AComponent));\n    if (AComponent is TZSequence) then\n      UnregisterSequence(TZSequence(AComponent));\n    if (AComponent = FZConnectionGroup) then\n      FZConnectionGroup := nil;\n  end;\nend;\n\nprocedure TZGroupedConnection .SetConnectionGroup(Value: TZConnectionGroup);\nbegin\n  if FZConnectionGroup<>nil then\n    FZConnectionGroup.UnRegisterChanges(FZConnectionGroupLink);\n\n  FZConnectionGroup := Value;\n  if Value <> nil then\n  begin\n    FZConnectionGroup.RegisterChanges(FZConnectionGroupLink);\n    FURL.UserName := FZConnectionGroup.User;\n    FURL.Protocol := FZConnectionGroup.Protocol;\n    FURL.Password := FZConnectionGroup.Password;\n    FURL.HostName := FZConnectionGroup.HostName;\n    FURL.Database := FZConnectionGroup.Database;\n    FURL.LibLocation := FZConnectionGroup.LibraryLocation;\n  end;\n  InternalZConnectionGroupChanged(Self, Value);\nend;\n\nfunction TZGroupedConnection .getUser: string;\nbegin\n  if FZConnectionGroup <> nil then\n  begin\n    FURL.UserName := FZConnectionGroup.User;\n    Result := FURL.UserName;\n  end\n  else\n    FURL.UserName := '';\nend;\n\n{\nfunction TZGroupedConnection .getProtocol: string;\nbegin\n  if FZConnectionGroup <> nil then\n  begin\n    FProtocol := FZConnectionGroup.Protocol;\n    Result := FProtocol;\n  end\n  else\n    FProtocol := '';\nend;\n}\n\nfunction TZGroupedConnection .getPassword: string;\nbegin\n  if FZConnectionGroup <> nil then\n  begin\n    FURL.Password := FZConnectionGroup.Password;\n    Result := FURL.Password;\n  end\n  else\n    FURL.Password := '';\nend;\n\nfunction TZGroupedConnection .getHostName: string;\nbegin\n  if FZConnectionGroup <> nil then\n  begin\n    FURL.HostName := FZConnectionGroup.HostName;\n    Result := FURL.HostName;\n  end\n  else\n    FURL.HostName := '';\nend;\n\nfunction TZGroupedConnection .getDatabase: string;\nbegin\n  if FZConnectionGroup <> nil then\n  begin\n    FURL.Database := FZConnectionGroup.Database;\n    Result := FURL.Database;\n  end\n  else\n    FURL.Database := '';\nend;\n\nfunction TZGroupedConnection.GetLibLocation: String;\nbegin\n  if FZConnectionGroup <> nil then\n  begin\n    FURL.LibLocation := FZConnectionGroup.LibraryLocation;\n    Result := FURL.LibLocation;\n  end\n  else\n    FURL.LibLocation := '';\nend;\n\n{\nfunction TZGroupedConnection .getCatalog: string;\nbegin\n  if FZConnectionGroup <> nil then\n  begin\n    FCatalog := FZConnectionGroup.Catalog;\n    Result := FCatalog;\n  end\n  else\n    FCatalog := '';\nend;\n}\n\nend.\n"
  },
  {
    "path": "lib/zeosdbo/src/component/ZIBEventAlerter.pas",
    "content": "{*********************************************************}\n{                                                         }\n{                 Zeos Database Objects                   }\n{         Interbase Database Connectivity Classes         }\n{                                                         }\n{    Copyright (c) 1999-2003 Zeos Development Group       }\n{            Written by Sergey Merkuriev                  }\n{                                                         }\n{*********************************************************}\n\n{@********************************************************}\n{    Copyright (c) 1999-2012 Zeos Development Group       }\n{                                                         }\n{ License Agreement:                                      }\n{                                                         }\n{ This library is distributed in the hope that it will be }\n{ useful, but WITHOUT ANY WARRANTY; without even the      }\n{ implied warranty of MERCHANTABILITY or FITNESS FOR      }\n{ A PARTICULAR PURPOSE.  See the GNU Lesser General       }\n{ Public License for more details.                        }\n{                                                         }\n{ The source code of the ZEOS Libraries and packages are  }\n{ distributed under the Library GNU General Public        }\n{ License (see the file COPYING / COPYING.ZEOS)           }\n{ with the following  modification:                       }\n{ As a special exception, the copyright holders of this   }\n{ library give you permission to link this library with   }\n{ independent modules to produce an executable,           }\n{ regardless of the license terms of these independent    }\n{ modules, and to copy and distribute the resulting       }\n{ executable under terms of your choice, provided that    }\n{ you also meet, for each linked independent module,      }\n{ the terms and conditions of the license of that module. }\n{ An independent module is a module which is not derived  }\n{ from or based on this library. If you modify this       }\n{ library, you may extend this exception to your version  }\n{ of the library, but you are not obligated to do so.     }\n{ If you do not wish to do so, delete this exception      }\n{ statement from your version.                            }\n{                                                         }\n{                                                         }\n{ The project web site is located on:                     }\n{   http://zeos.firmos.at  (FORUM)                        }\n{   http://sourceforge.net/p/zeoslib/tickets/ (BUGTRACKER)}\n{   svn://svn.code.sf.net/p/zeoslib/code-0/trunk (SVN)    }\n{                                                         }\n{   http://www.sourceforge.net/projects/zeoslib.          }\n{                                                         }\n{                                                         }\n{                                 Zeos Development Group. }\n{********************************************************@}\n\nunit ZIBEventAlerter;\n\n{$I ZComponent.inc}\n\ninterface\n\nuses\n  SysUtils, Classes,\n{$IF defined(MSWINDOWS)and not defined(FPC)}\n  Windows,\n{$IFEND}\n  ZDbcInterbase6, ZConnection, ZDbcIntfs,\n  ZPlainFirebirdDriver, ZPlainFirebirdInterbaseConstants;\n\ntype\n\n  TEventAlert = procedure(Sender: TObject; EventName: string; EventCount: longint;\n    var CancelAlerts: boolean) of object;\n  TErrorEvent = procedure(Sender: TObject; ErrorCode: integer) of object;\n\n  TZIBEventAlerter = class(TComponent)\n  private\n    FEvents: TStrings;\n    FOnEventAlert: TEventAlert;\n    FThreads: TList;\n    FNativeHandle: PISC_DB_HANDLE;\n    ThreadException: boolean;\n    FConnection: TZConnection;\n    FOnError: TErrorEvent;\n    FAutoRegister: boolean;\n    FRegistered: boolean;\n\n    procedure SetConnection(Value: TZConnection);\n    procedure SetEvents(Value: TStrings);\n    function GetRegistered: boolean;\n    procedure SetRegistered(const Value: boolean);\n    function GetPlainDriver: IZInterbasePlainDriver;\n  protected\n    { Protected declarations }\n    function GetNativeHandle: PISC_DB_HANDLE; virtual;\n    procedure EventChange(Sender: TObject); virtual;\n    procedure ThreadEnded(Sender: TObject); virtual;\n    procedure Notification(AComponent: TComponent; Operation: TOperation); override;\n  public\n    { Public declarations }\n    constructor Create(AOwner: TComponent); override;\n    destructor Destroy; override;\n    procedure RegisterEvents; virtual;\n    procedure UnRegisterEvents; virtual;\n    property NativeHandle: PISC_DB_HANDLE read GetNativeHandle;\n    property PlainDriver: IZInterbasePlainDriver read GetPlainDriver;\n    procedure SetAutoRegister(const Value: boolean);\n    function GetAutoRegister: boolean;\n  published\n    { Published declarations }\n    property AutoRegister: boolean read GetAutoRegister write SetAutoRegister;\n    property Connection: TZConnection read FConnection write SetConnection;\n    property Events: TStrings read FEvents write SetEvents;\n    property Registered: boolean read GetRegistered write SetRegistered;\n    property OnEventAlert: TEventAlert read FOnEventAlert write FOnEventAlert;\n    property OnError: TErrorEvent read FOnError write FOnError;\n  end;\n\nimplementation\n\nuses\n  SyncObjs;\n\nconst\n  IB_MAX_EVENT_BLOCK = 15;   // maximum events handled per block by InterBase\n  IB_MAX_EVENT_LENGTH = 64;  // maximum event name length\nthreadvar\n  FStatusVector: TARRAY_ISC_STATUS;\n\ntype\n\n  { TIBEventThread }\n  TIBEventThread = class(TThread)\n  private\n    // IB API call parameters\n    WhichEvent: integer;\n    EventID: ISC_LONG;\n    EventBuffer: PAnsiChar;\n    EventBufferLen: Short;\n    ResultBuffer: PAnsiChar;\n    // Local use variables\n    Signal: TSimpleEvent;\n    EventsReceived,\n    FirstTime: boolean;\n    EventGroup,\n    EventCount: integer;\n    Parent: TZIBEventAlerter;\n    FExceptObject: TObject;\n    FExceptAddr: Pointer;\n    FCancelAlerts: boolean;\n  protected\n    procedure Execute; override;\n    procedure SignalEvent; virtual;\n    procedure SignalTerminate; virtual;\n    procedure RegisterEvents; virtual;\n    procedure UnRegisterEvents; virtual;\n    procedure QueueEvents; virtual;\n    procedure SQueEvents;\n    procedure ProcessEvents; virtual;\n    procedure DoEvent;\n    procedure DoHandleException;\n    function HandleException: boolean; virtual;\n    procedure UpdateResultBuffer(Length: UShort; Updated: PAnsiChar);\n  public\n    constructor Create(Owner: TZIBEventAlerter; EventGrp: integer;\n      TermEvent: TNotifyEvent); virtual;\n    destructor Destroy; override;\n  end;\n\n  Tsib_event_block = function(EventBuffer, ResultBuffer: PPAnsiChar; IDCount: UShort;\n    Event1, Event2, Event3, Event4, Event5, Event6, Event7, Event8, Event9,\n    Event10, Event11, Event12, Event13, Event14, Event15: PAnsiChar): ISC_LONG;\n  cdecl;\n\nfunction TZIBEventAlerter.GetNativeHandle: PISC_DB_HANDLE;\nbegin\n  Result := (FConnection.DbcConnection as IZInterbase6Connection).GetDBHandle;\nend;\n\nfunction StatusVector: PISC_STATUS;\nbegin\n  Result := @FStatusVector;\nend;\n\nfunction StatusVectorArray: TARRAY_ISC_STATUS;\nbegin\n  Result := FStatusVector;\nend;\n\n{ TZIBEventAlerter }\n\nconstructor TZIBEventAlerter.Create(AOwner: TComponent);\nbegin\n  inherited Create(AOwner);\n\n  ThreadException := False;\n  FOnEventAlert := nil;\n  FNativeHandle := nil;\n  FConnection := nil;\n  FAutoRegister := False;\n  FEvents := TStringList.Create;\n  with TStringList(FEvents) do\n  begin\n    Sorted := True;  // dupIgnore only works when the TStringList is sorted\n    OnChange := EventChange; // assign the routine which validates the event lenghts\n    Duplicates := dupIgnore; // don't allow duplicate events\n  end;\n  FThreads := TList.Create;\nend;\n\ndestructor TZIBEventAlerter.Destroy;\nbegin\n  try\n    if Registered then\n      UnRegisterEvents;\n  except\n    // silence any exceptions which might be raised\n    // by UnRegisterEvents during destruction\n  end;\n\n{  If Assigned(FConnection) then\n    FConnection.RemoveEventNotifier(Self);\n}\n\n  FThreads.Free;\n  FEvents.Free;\n\n  inherited Destroy;\nend;\n\nprocedure TZIBEventAlerter.Notification(AComponent: TComponent;\n  Operation: TOperation);\nbegin\n  inherited Notification(AComponent, Operation);\n  if (Operation = opRemove) and (AComponent = FConnection) then\n  begin\n    if Registered then\n      UnRegisterEvents;\n    FConnection := nil;\n  end;\nend;\n\n\n// -> ms, 18/08/2004:\n//    Modified so that now the DB connection will be made when events are registered\n//    this is because the method UnregisterEvents of TIBEventThread needs a native\n//    DB handle that can only be retrieved when DB connection is active. If the events\n//    are registered correctly the DB connection must be established. If it is not\n//    established this will be done here. This means that whenever events are registered\n//    (by setting AutoRegister := True or calling RegisterEvents explicitly) and the\n//    DB connection ist not established, this will be done here automatically (including\n//    the retrieval of the native DB handle).\nProcedure TZIBEventAlerter.RegisterEvents;\nVar i: Integer;\nBegin\n   If (not (csDesigning in ComponentState)) and (Assigned(FConnection)) Then Begin\n      Try\n         If (FThreads.Count = 0) Then Begin\n            If (FEvents.Count > 0) Then Begin\n               For i := 0 To ((FEvents.Count - 1) div IB_MAX_EVENT_BLOCK) Do\n                 FThreads.Add(TIBEventThread.Create(Self, i, ThreadEnded));\n            End;\n         End;\n      Finally\n         FRegistered := FThreads.Count <> 0;\n         If FRegistered Then Begin\n            If not FConnection.Connected Then\n               FConnection.Connect;\n            FNativeHandle := GetNativeHandle;\n         End;\n      End;\n   End;\nEnd; // RegisterEvents\n\n\n// -> ms, 18/08/2004:\n//    Modified so that the native DB handle will now be retrieved by\n//    method RegisterEvents. Retrieving it here caused an Exception\n//    even if DB was connected.\nProcedure TZIBEventAlerter.SetConnection(Value: TZConnection);\nVar\n  WasRegistered: boolean;\nBegin\n   If (Value <> FConnection) Then Begin\n      If (csDesigning in ComponentState) Then\n         FConnection := Value\n      Else Begin\n         WasRegistered := Registered;\n         If WasRegistered Then\n            UnRegisterEvents;\n         FConnection := Value;\n         If WasRegistered Then\n            RegisterEvents;\n      End;\n   End;\nEnd; // SetConnection\n\n\nprocedure TZIBEventAlerter.SetEvents(Value: TStrings);\nbegin\n  FEvents.Assign(Value);\nend;\n\nprocedure TZIBEventAlerter.SetRegistered(const Value: boolean);\nbegin\n  FRegistered := Value;\n  if csDesigning in ComponentState then\n    exit;\n  if Value then\n    RegisterEvents\n  else\n    UnRegisterEvents;\nend;\n\nprocedure TZIBEventAlerter.UnregisterEvents;\nvar\n  i: integer;\n  Temp: TIBEventThread;\nbegin\n  if csDesigning in ComponentState then\n    exit;\n  if (FThreads.Count > 0) then\n  begin\n    for i := (FThreads.Count - 1) downto 0 do\n    begin\n      Temp := TIBEventThread(FThreads[i]);\n      FThreads.Delete(i);\n\n      Temp.SignalTerminate;\n      Temp.WaitFor;\n      Temp.Free;\n    end;\n  end;\n  FRegistered := FThreads.Count <> 0;\nend;\n\nfunction TZIBEventAlerter.GetPlainDriver: IZInterbasePlainDriver;\nbegin\n  Result := (FConnection.DbcConnection as IZInterbase6Connection).GetPlainDriver;\nend;\n\n{ TIBEventThread }\n\nprocedure EventCallback(P: Pointer; Length: Short; Updated: PAnsiChar); cdecl;\nbegin\n  if (Assigned(P) and Assigned(Updated)) then\n  begin\n    TIBEventThread(P).UpdateResultBuffer(Length, Updated);\n    TIBEventThread(P).SignalEvent;\n  end;\nend;\n\nprocedure TIBEventThread.DoEvent;\nbegin\n  Parent.FOnEventAlert(Parent, Parent.FEvents[((EventGroup * IB_MAX_EVENT_BLOCK) + WhichEvent)],\n    StatusVectorArray[WhichEvent], FCancelAlerts)\nend;\n\nprocedure TIBEventThread.UpdateResultBuffer(Length: UShort; Updated: PAnsiChar);\nbegin\n  Move(Updated[0], ResultBuffer[0], Length);\nend;\n\nprocedure TIBEventThread.QueueEvents;\nbegin\n  EventsReceived := False;\n  Signal.ResetEvent;\n  Synchronize(SQueEvents);\nend;\n\nprocedure TIBEventThread.ProcessEvents;\nvar\n  i: integer;\nbegin\n  Parent.PlainDriver.isc_event_counts(StatusVector, EventBufferLen,\n    EventBuffer, ResultBuffer);\n  if (Assigned(Parent.FOnEventAlert) and (not FirstTime)) then\n  begin\n    FCancelAlerts := False;\n    for i := 0 to (EventCount - 1) do\n    begin\n      if (StatusVectorArray[i] <> 0) then\n      begin\n        WhichEvent := i;\n        Synchronize(DoEvent)\n      end;\n    end;\n  end;\n  FirstTime := False;\nend;\n\nprocedure TIBEventThread.UnRegisterEvents;\nbegin\n  Parent.PlainDriver.isc_cancel_events(StatusVector, Parent.FNativeHandle, @EventID);\n  Parent.PlainDriver.isc_free(EventBuffer);\n  EventBuffer := nil;\n  Parent.PlainDriver.isc_free(ResultBuffer);\n  ResultBuffer := nil;\nend;\n\nprocedure TIBEventThread.RegisterEvents;\nvar\n  sib_event_block: Tsib_event_block;\n\n  function EBP(Index: integer): PAnsiChar;\n  begin\n    Inc(Index, (EventGroup * IB_MAX_EVENT_BLOCK));\n    if (Index > Parent.FEvents.Count) then\n      Result := nil\n    else\n  {$IFDEF UNICODE}\n      Result := PAnsiChar(AnsiString(Parent.FEvents[Index - 1]));\n  {$ELSE}\n      Result := PAnsiChar(Parent.FEvents[Index - 1]);\n  {$ENDIF}\n  end;\nbegin\n  EventBuffer := nil;\n  ResultBuffer := nil;\n  EventBufferLen := 0;\n  FirstTime := True;\n  EventCount := (Parent.FEvents.Count - (EventGroup * IB_MAX_EVENT_BLOCK));\n  if (EventCount > IB_MAX_EVENT_BLOCK) then\n    EventCount := IB_MAX_EVENT_BLOCK;\n\n{\n  if Parent.Connection.Protocol='interbase-6' then\n    sib_event_block := Tsib_event_block(ZPlainInterbase6.isc_event_block)\n    else if Parent.Connection.Protocol='firebird-1.0' then\n      sib_event_block := Tsib_event_block(ZPlainFirebird10.isc_event_block)\n    else if Parent.Connection.Protocol='firebird-1.5' then\n      sib_event_block := Tsib_event_block(ZPlainFirebird15.isc_event_block)\n    else if Parent.Connection.Protocol='firebirdd-1.5' then\n      sib_event_block := Tsib_event_block(ZPlainFirebird15.isc_event_block)\n    else if Parent.Connection.Protocol='firebird-2.0' then\n      sib_event_block := Tsib_event_block(ZPlainFirebird20.isc_event_block)\n    else if Parent.Connection.Protocol='firebirdd-2.0' then\n      sib_event_block := Tsib_event_block(ZPlainFirebird20.isc_event_block)\n    else if Parent.Connection.Protocol='firebird-2.1' then\n      sib_event_block := Tsib_event_block(ZPlainFirebird21.isc_event_block)\n    else if Parent.Connection.Protocol='firebirdd-2.1' then\n      sib_event_block := Tsib_event_block(ZPlainFirebird21.isc_event_block)\n\n  else\n    sib_event_block := Tsib_event_block(ZPlainInterbase6.isc_event_block);\n  }\n  sib_event_block := Tsib_event_block(Parent.GetPlainDriver.GetFirebirdAPI.isc_event_block);\n  EventBufferLen := sib_event_block(@EventBuffer,\n    @ResultBuffer, EventCount,\n    EBP(1), EBP(2),  EBP(3),  EBP(4),  EBP(5),  EBP(6),  EBP(7), EBP(8),\n    EBP(9), EBP(10), EBP(11), EBP(12), EBP(13), EBP(14), EBP(15));\n\n\nend;\n\nprocedure TIBEventThread.SignalEvent;\nbegin\n  EventsReceived := True;\n  Signal.SetEvent;\nend;\n\nprocedure TIBEventThread.SignalTerminate;\nbegin\n  if not Terminated then\n  begin\n    Terminate;\n    Signal.SetEvent;\n  end;\nend;\n\nprocedure TIBEventThread.DoHandleException;\nbegin\n  SysUtils.ShowException(FExceptObject, FExceptAddr);\nend;\n\nfunction TIBEventThread.HandleException: boolean;\nbegin\n  if not Parent.ThreadException then\n  begin\n    Result := True;\n    Parent.ThreadException := True;\n    FExceptObject := ExceptObject;\n    FExceptAddr := ExceptAddr;\n    try\n      if not (FExceptObject is EAbort) then\n        Synchronize(DoHandleException);\n    finally\n      FExceptObject := nil;\n      FExceptAddr := nil;\n    end;\n  end\n  else\n    Result := False;\nend;\n\nprocedure TIBEventThread.Execute;\nbegin\n  RegisterEvents;\n  QueueEvents;\n  try\n    repeat\n      Signal.WaitFor(INFINITE);\n      if EventsReceived then\n      begin\n        ProcessEvents;\n        QueueEvents;\n      end;\n    until Terminated;\n    ReturnValue := 0;\n  except\n    if HandleException then\n      ReturnValue := 1\n    else\n      ReturnValue := 0;\n  end;\nend;\n\n{$WARNINGS OFF}\nconstructor TIBEventThread.Create(Owner: TZIBEventAlerter;\n  EventGrp: integer; TermEvent: TNotifyEvent);\nbegin\n  inherited Create(True);\n  FCancelAlerts := False;\n  Signal := TSimpleEvent.Create;\n  Parent := Owner;\n  EventGroup := EventGrp;\n  OnTerminate := TermEvent;\n  Resume;\nend;\n{$WARNINGS ON}\n\ndestructor TIBEventThread.Destroy;\nbegin\n  try\n    UnRegisterEvents;\n  except\n    if HandleException then\n      ReturnValue := 1\n    else\n      ReturnValue := 0;\n  end;\n  Signal.Free;\n  inherited Destroy;\nend;\n\nprocedure TZIBEventAlerter.EventChange(Sender: TObject);\nvar\n  i: integer;\n  WasRegistered: boolean;\nbegin\n  WasRegistered := Registered;\n  try\n    if WasRegistered then\n      UnRegisterEvents;\n    TStringList(FEvents).OnChange := nil;\n    try\n      for i := (FEvents.Count - 1) downto 0 do\n      begin\n        if (FEvents[i] = EmptyStr) then\n        begin\n          FEvents.Delete(i);\n        end\n        else if (Length(FEvents[i]) > (IB_MAX_EVENT_LENGTH - 1)) then\n        begin\n          FEvents[i] := Copy(FEvents[i], 1, (IB_MAX_EVENT_LENGTH - 1));\n        end;\n      end;\n    finally\n      TStringList(FEvents).OnChange := EventChange;\n    end;\n  finally\n    if WasRegistered then\n      RegisterEvents;\n  end;\nend;\n\nfunction TZIBEventAlerter.GetRegistered: boolean;\nbegin\n  Result := FRegistered;\nend;\n\nprocedure TZIBEventAlerter.ThreadEnded(Sender: TObject);\nvar\n  ThreadIdx: integer;\nbegin\n  if (Sender is TIBEventThread) then\n  begin\n    ThreadIdx := FThreads.IndexOf(Sender);\n    if (ThreadIdx > -1) then\n      FThreads.Delete(ThreadIdx);\n    if (TIBEventThread(Sender).ReturnValue = 1) then\n    begin\n      if Registered then\n        UnRegisterEvents;\n      ThreadException := False;\n    end\n  end;\nend;\n\nprocedure TZIBEventAlerter.SetAutoRegister(const Value: boolean);\nbegin\n  if FAutoRegister <> Value then\n  begin\n    FAutoRegister := Value;\n    if FAutoRegister and (not Registered) and\n      Assigned(FConnection) and FConnection.Connected then\n      RegisterEvents;\n  end;\nend;\n\nfunction TZIBEventAlerter.GetAutoRegister: boolean;\nbegin\n  Result := FAutoRegister;\nend;\n\nprocedure TIBEventThread.SQueEvents;\nvar\n  Status: ISC_STATUS;\nbegin\n  Status := -999999;\n  try\n    Status := Parent.PlainDriver.isc_que_events(StatusVector,\n      Parent.FNativeHandle, @EventID, EventBufferLen,\n      EventBuffer, TISC_CALLBACK(@EventCallback), PVoid(Self));\n  except\n    on E: Exception do\n      if Status <> -999999 then\n        if Assigned(Parent.OnError) then\n          if E is EZSQLException then\n            Parent.OnError(Parent, EZSQLException(E).ErrorCode)\n          else\n            Parent.OnError(Parent, 0);\n  end;\nend;\n\nend.\n\n"
  },
  {
    "path": "lib/zeosdbo/src/component/ZPgEventAlerter.pas",
    "content": "{*********************************************************}\n{                                                         }\n{                 Zeos Database Objects                   }\n{         Interbase Database Connectivity Classes         }\n{                                                         }\n{    Copyright (c) 1999-2003 Zeos Development Group       }\n{            Written by Sergey Merkuriev                  }\n{                                                         }\n{*********************************************************}\n\n{@********************************************************}\n{    Copyright (c) 1999-2012 Zeos Development Group       }\n{                                                         }\n{ License Agreement:                                      }\n{                                                         }\n{ This library is distributed in the hope that it will be }\n{ useful, but WITHOUT ANY WARRANTY; without even the      }\n{ implied warranty of MERCHANTABILITY or FITNESS FOR      }\n{ A PARTICULAR PURPOSE.  See the GNU Lesser General       }\n{ Public License for more details.                        }\n{                                                         }\n{ The source code of the ZEOS Libraries and packages are  }\n{ distributed under the Library GNU General Public        }\n{ License (see the file COPYING / COPYING.ZEOS)           }\n{ with the following  modification:                       }\n{ As a special exception, the copyright holders of this   }\n{ library give you permission to link this library with   }\n{ independent modules to produce an executable,           }\n{ regardless of the license terms of these independent    }\n{ modules, and to copy and distribute the resulting       }\n{ executable under terms of your choice, provided that    }\n{ you also meet, for each linked independent module,      }\n{ the terms and conditions of the license of that module. }\n{ An independent module is a module which is not derived  }\n{ from or based on this library. If you modify this       }\n{ library, you may extend this exception to your version  }\n{ of the library, but you are not obligated to do so.     }\n{ If you do not wish to do so, delete this exception      }\n{ statement from your version.                            }\n{                                                         }\n{                                                         }\n{ The project web site is located on:                     }\n{   http://zeos.firmos.at  (FORUM)                        }\n{   http://sourceforge.net/p/zeoslib/tickets/ (BUGTRACKER)}\n{   svn://svn.code.sf.net/p/zeoslib/code-0/trunk (SVN)    }\n{                                                         }\n{   http://www.sourceforge.net/projects/zeoslib.          }\n{                                                         }\n{                                                         }\n{                                 Zeos Development Group. }\n{********************************************************@}\n\n{*********************************************************}\n{                                                         }\n{ TZPgEventAlerter, Asynchronous notifying.               }\n{   By Ivan Rog - 2010                                    }\n{                                                         }\n{ Contributors:                                           }\n{   Silvio Clecio - http://silvioprog.com.br              }\n{                                                         }\n{*********************************************************}\n\nunit ZPgEventAlerter;\n\ninterface\n{$I ZComponent.inc}\nuses\n  SysUtils, Classes, ExtCtrls,\n  ZDbcPostgreSql, ZPlainPostgreSqlDriver, ZConnection, ZAbstractRODataset;\n\ntype\n  TZPgNotifyEvent = procedure(Sender: TObject; Event: string;\n    ProcessID: Integer; Payload: string) of object;\n\n  { TZPgEventAlerter }\n\n  TZPgEventAlerter = class (TComponent)\n  private\n    FActive      : Boolean;\n    FEvents      : TStrings;\n\n    FTimer       : TTimer;\n    FConnection: TZConnection;\n    FNotifyFired : TZPgNotifyEvent;\n\n    FProcessor   : TZPgEventAlerter; //processor component - it will actually handle notifications received from DB\n    //if processor is not assignet - component is handling notifications by itself\n    FChildAlerters :TList; //list of TZPgEventAlerter that have our component attached as processor\n    FChildEvents : TStrings; //list of actual events to be handled - gathered from events of all childe\n  protected\n    procedure SetActive     (Value: Boolean);\n    function  GetInterval   : Cardinal;\n    procedure SetInterval   (Value: Cardinal);\n    procedure SetEvents     (Value: TStrings);\n    procedure SetConnection (Value: TZConnection);\n    procedure TimerTick     (Sender: TObject);\n    procedure CheckEvents;\n    procedure OpenNotify;\n    procedure CloseNotify;\n\n    procedure SetProcessor(Value: TZPgEventAlerter);\n    procedure AddChildAlerter(Child: TZPgEventAlerter);\n    procedure RemoveChildAlerter(Child: TZPgEventAlerter);\n    procedure HandleNotify(Notify: PZPostgreSQLNotify); //launching OnNotify event fo Self and all child components (if event name is matched)\n    procedure SetChildEvents     (Value: TStrings);\n    procedure RefreshEvents; //gathering all events from all child components (no duplicates), also propagating these events \"down\" to our processor\n  public\n    constructor Create     (AOwner: TComponent); override;\n    destructor  Destroy; override;\n  published\n    property Connection: TZConnection     read FConnection   write SetConnection;\n    property Active:     Boolean          read FActive       write SetActive;\n    property Events:     TStrings         read FEvents       write SetEvents;\n    property Interval:   Cardinal         read GetInterval   write SetInterval    default 250;\n    property OnNotify:   TZPgNotifyEvent  read FNotifyFired  write FNotifyFired;\n    property Processor:     TZPgEventAlerter          read FProcessor       write SetProcessor; //property to assign processor handling notifications\n    property ChildEvents:   TStrings         read FChildEvents write SetChildEvents; //read onlu property to keep all events in one place\n  end;\n\nimplementation\n\n{$IFDEF WITH_UNITANSISTRINGS}\nuses AnsiStrings;\n{$ENDIF}\n\n{ TZPgEventAlerter }\n\nconstructor TZPgEventAlerter.Create(AOwner: TComponent);\nvar\n  I: Integer;\nbegin\n  inherited Create(AOwner);\n  FEvents := TStringList.Create;\n  FChildAlerters := TList.Create;\n  FChildEvents := TStringList.Create;\n  with TStringList(FEvents) do\n  begin\n    Duplicates := dupIgnore;\n  end;\n\n  with TStringList(FChildEvents) do\n  begin\n    Duplicates := dupIgnore;\n  end;\n\n  FTimer         := TTimer.Create(Self);\n  FTimer.Enabled := False;\n  SetInterval(250);\n  FTimer.OnTimer := TimerTick;\n  FActive        := False;\n  if (csDesigning in ComponentState) and Assigned(AOwner) then\n   for I := AOwner.ComponentCount - 1 downto 0 do\n    if AOwner.Components[I] is TZConnection then\n     begin\n        FConnection := AOwner.Components[I] as TZConnection;\n      Break;\n     end;\nend;\n\ndestructor TZPgEventAlerter.Destroy;\nbegin\n  if FProcessor = nil then\n    CloseNotify;\n  FEvents.Free;\n  FTimer.Free;\n  FChildAlerters.Free;\n  FChildEvents.Free;\n  inherited Destroy;\nend;\n\nprocedure TZPgEventAlerter.SetInterval(Value: Cardinal);\nbegin\n  FTimer.Interval := Value;\nend;\n\nfunction TZPgEventAlerter.GetInterval: Cardinal;\nbegin\n  Result := FTimer.Interval;\nend;\n\nprocedure TZPgEventAlerter.SetEvents(Value: TStrings);\nvar\n  I: Integer;\nbegin\n  FEvents.Assign(Value);\n\n  for I := 0 to FEvents.Count -1 do\n    FEvents[I] := Trim(FEvents[I]);\n  RefreshEvents; //we must propagate events down to our processor\nend;\n\nprocedure TZPgEventAlerter.SetActive(Value: Boolean);\nbegin\n  if FActive <> Value then\n  begin\n    if FProcessor = nil then\n    begin\n      if Value then\n      begin\n        RefreshEvents;\n        OpenNotify;\n      end\n      else\n      begin\n        CloseNotify;\n      end\n    end\n    else  //we have processor attached - we dont need to open or close notifications\n    begin\n      FActive := Value;\n      FProcessor.RefreshEvents;\n    end;\n  end;\nend;\n\nprocedure TZPgEventAlerter.SetConnection(Value: TZConnection);\nbegin\n  if FConnection <> Value then\n  begin\n    if FProcessor = nil then //we are closing notifiers only whern there is no processor attached\n      CloseNotify;\n    FConnection := Value;\n  end;\nend;\n\nprocedure TZPgEventAlerter.TimerTick(Sender: TObject);\nbegin\n  if not FActive then\n   FTimer.Enabled := False\n  else\n  begin\n    if FProcessor <> nil then\n      FTimer.Enabled := False\n    else\n     CheckEvents;\n  end;\nend;\n\nprocedure TZPgEventAlerter.OpenNotify;\nvar\n  I        : Integer;\n  Tmp      : array [0..255] of AnsiChar;\n  Handle   : PZPostgreSQLConnect;\n  ICon     : IZPostgreSQLConnection;\n  PlainDRV : IZPostgreSQLPlainDriver;\n  Res: PGresult;\nbegin\n  if not Boolean(Pos('postgresql', FConnection.Protocol)) then\n    raise EZDatabaseError.Create('Ivalid connection protocol. Need <postgres>, get ' +\n      FConnection.Protocol + '.');\n  if FActive then\n    Exit;\n  if not Assigned(FConnection) then\n    Exit;\n  if ((csLoading in ComponentState) or (csDesigning in ComponentState)) then\n    Exit;\n  if not FConnection.Connected then\n    Exit;\n  ICon     := (FConnection.DbcConnection as IZPostgreSQLConnection);\n  Handle   := ICon.GetConnectionHandle;\n  PlainDRV := ICon.GetPlainDriver;\n  if Handle = nil then\n    Exit;\n    for I := 0 to FChildEvents.Count-1 do\n  begin\n    {$IFDEF WITH_STRPCOPY_DEPRECATED}AnsiStrings.{$ENDIF}StrPCopy(Tmp, 'listen ' + AnsiString(FChildEvents.Strings[I]));\n    Res := PlainDRV.ExecuteQuery(Handle, Tmp);\n    if (PlainDRV.GetResultStatus(Res) <> TZPostgreSQLExecStatusType(\n      PGRES_COMMAND_OK)) then\n   begin\n      PlainDRV.Clear(Res);\n    Exit;\n   end;\n    PlainDRV.Clear(Res);\n  end;\n  FActive        := True;\n  FTimer.Enabled := True;\nend;\n\nprocedure TZPgEventAlerter.CloseNotify;\nvar\n  I        : Integer;\n  tmp      : array [0..255] of AnsiChar;\n  Handle   : PZPostgreSQLConnect;\n  ICon     : IZPostgreSQLConnection;\n  PlainDRV : IZPostgreSQLPlainDriver;\n  Res: PGresult;\nbegin\n  if not FActive then\n    Exit;\n  FActive        := False;\n  FTimer.Enabled := False;\n  ICon           := (FConnection.DbcConnection as IZPostgreSQLConnection);\n  Handle         := ICon.GetConnectionHandle;\n  PlainDRV       := ICon.GetPlainDriver;\n  if Handle = nil then\n    Exit;\n  for I := 0 to FChildEvents.Count-1 do\n  begin\n    {$IFDEF WITH_STRPCOPY_DEPRECATED}AnsiStrings.{$ENDIF}StrPCopy(Tmp, 'unlisten ' + AnsiString(FChildEvents.Strings[i]));\n    Res := PlainDRV.ExecuteQuery(Handle, Tmp);\n    if (PlainDRV.GetResultStatus(Res) <> TZPostgreSQLExecStatusType(\n      PGRES_COMMAND_OK)) then\n   begin\n      PlainDRV.Clear(Res);\n    Exit;\n   end;\n    PlainDRV.Clear(Res);\n  end;\nend;\n\nprocedure TZPgEventAlerter.CheckEvents;\nvar\n  Notify: PZPostgreSQLNotify;\n  Handle   : PZPostgreSQLConnect;\n  ICon     : IZPostgreSQLConnection;\n  PlainDRV : IZPostgreSQLPlainDriver;\nbegin\n  ICon      := (FConnection.DbcConnection as IZPostgreSQLConnection);\n  Handle    := ICon.GetConnectionHandle;\n  if Handle=nil then\n  begin\n    FTimer.Enabled := False;\n    FActive := False;\n    Exit;\n  end;\n  if not FConnection.Connected then\n  begin\n    CloseNotify;\n    Exit;\n  end;\n  PlainDRV  := ICon.GetPlainDriver;\n\n  if PlainDRV.ConsumeInput(Handle)=1 then\n  begin\n    while True do\n    begin\n      Notify := PlainDRV.Notifies(Handle);\n      if Notify = nil then\n        Break;\n      HandleNotify(Notify);\n      PlainDRV.FreeNotify(Notify);\n    end;\n  end;\nend;\n\nprocedure TZPgEventAlerter.HandleNotify(Notify: PZPostgreSQLNotify);\nvar\n  i: Integer;\n  CurrentChild: TZPgEventAlerter;\nbegin\n  if Assigned(FNotifyFired) and (FEvents.IndexOf(String(Notify{$IFDEF OLDFPC}^{$ENDIF}.relname)) <> -1) then\n    FNotifyFired(Self, String(Notify{$IFDEF OLDFPC}^{$ENDIF}.relname), Notify{$IFDEF OLDFPC}^{$ENDIF}.be_pid,String(Notify{$IFDEF OLDFPC}^{$ENDIF}.payload));\n\n  for I := 0 to FChildAlerters.Count-1 do //propagating event to child listeners\n  begin\n    CurrentChild :=TZPgEventAlerter(FChildAlerters[i]);\n    if CurrentChild.Active and (CurrentChild.ChildEvents.IndexOf(String(Notify{$IFDEF OLDFPC}^{$ENDIF}.relname)) <> -1) then //but only active ones\n      CurrentChild.HandleNotify(Notify);\n  end;\nend;\n\nprocedure TZPgEventAlerter.SetProcessor(Value: TZPgEventAlerter);\nbegin\n  if FProcessor <> Value then\n  begin\n    if FProcessor <> nil then //remove assignment from old processor\n    begin\n      FProcessor.RemoveChildAlerter(Self);\n    end;\n    FProcessor := Value;\n    if FProcessor <> nil then      //add assignment to new processor\n    begin\n      if FProcessor.Connection <> FConnection then\n      begin\n        raise Exception.Create('Cannot set processor with different connection');\n        Exit;\n      end;\n      FProcessor.AddChildAlerter(Self);\n    end;\n\n  end;\nend;\n\nprocedure TZPgEventAlerter.RefreshEvents;\nvar\n  i,j: integer;\n  CurrentChild: TZPgEventAlerter;\nbegin\n  FChildEvents.Clear;\n  for I := 0 to FChildAlerters.Count-1 do\n  begin\n    CurrentChild := TZPgEventAlerter(FChildAlerters[i]);\n    if CurrentChild.Active or ((csLoading in ComponentState) or (csDesigning in ComponentState)) then\n    begin  //gathering vent namse from all childs\n      for j := 0 to CurrentChild.ChildEvents.Count-1 do\n        if FChildEvents.IndexOf(CurrentChild.ChildEvents.Strings[j]) = -1 then\n          FChildEvents.Add(CurrentChild.ChildEvents.Strings[j]);\n    end;\n  end;\n\n  for i := 0 to Events.Count-1 do\n    if FChildEvents.IndexOf(Events.Strings[i]) = -1 then\n      FChildEvents.Add(Events.Strings[i]);\n\n  if FProcessor <> nil then  //refreshing eventrs in our processor\n    FProcessor.RefreshEvents\n  else\n  begin\n    if Active then //refreshing listeners after change of events - to make sure we will listen for everything\n    begin\n      Active := False;\n      Active := True;\n    end;\n  end;\nend;\n\nprocedure TZPgEventAlerter.AddChildAlerter(Child: TZPgEventAlerter);\nbegin\n  FChildAlerters.Add(Child);\n  RefreshEvents;\nend;\n\nprocedure TZPgEventAlerter.RemoveChildAlerter(Child: TZPgEventAlerter);\nvar\n  i: integer;\nbegin\n  i := FChildAlerters.IndexOf(Child);\n  FChildAlerters.Delete(i);\n  RefreshEvents;\nend;\n\nprocedure TZPgEventAlerter.SetChildEvents(Value: TStrings);\nbegin\n  Exit;\nend;\n\nend.\n\n"
  },
  {
    "path": "lib/zeosdbo/src/component/ZPropertyEditor.pas",
    "content": "{*********************************************************}\n{                                                         }\n{                 Zeos Database Objects                   }\n{               Component Property Editors                }\n{                                                         }\n{        Originally written by Sergey Seroukhov           }\n{                                                         }\n{*********************************************************}\n\n{@********************************************************}\n{    Copyright (c) 1999-2012 Zeos Development Group       }\n{                                                         }\n{ License Agreement:                                      }\n{                                                         }\n{ This library is distributed in the hope that it will be }\n{ useful, but WITHOUT ANY WARRANTY; without even the      }\n{ implied warranty of MERCHANTABILITY or FITNESS FOR      }\n{ A PARTICULAR PURPOSE.  See the GNU Lesser General       }\n{ Public License for more details.                        }\n{                                                         }\n{ The source code of the ZEOS Libraries and packages are  }\n{ distributed under the Library GNU General Public        }\n{ License (see the file COPYING / COPYING.ZEOS)           }\n{ with the following  modification:                       }\n{ As a special exception, the copyright holders of this   }\n{ library give you permission to link this library with   }\n{ independent modules to produce an executable,           }\n{ regardless of the license terms of these independent    }\n{ modules, and to copy and distribute the resulting       }\n{ executable under terms of your choice, provided that    }\n{ you also meet, for each linked independent module,      }\n{ the terms and conditions of the license of that module. }\n{ An independent module is a module which is not derived  }\n{ from or based on this library. If you modify this       }\n{ library, you may extend this exception to your version  }\n{ of the library, but you are not obligated to do so.     }\n{ If you do not wish to do so, delete this exception      }\n{ statement from your version.                            }\n{                                                         }\n{                                                         }\n{ The project web site is located on:                     }\n{   http://zeos.firmos.at  (FORUM)                        }\n{   http://sourceforge.net/p/zeoslib/tickets/ (BUGTRACKER)}\n{   svn://svn.code.sf.net/p/zeoslib/code-0/trunk (SVN)    }\n{                                                         }\n{   http://www.sourceforge.net/projects/zeoslib.          }\n{                                                         }\n{                                                         }\n{                                 Zeos Development Group. }\n{********************************************************@}\n\nunit ZPropertyEditor;\n\ninterface\n\n{$I ZComponent.inc}\n\n{$IFDEF WITH_PROPERTY_EDITOR}\n\nuses\n  Types, Classes, ZClasses, ZCompatibility, ZDbcIntfs,\n  ZConnectionGroup, ZAbstractConnection, ZURL,\n{$IFDEF BDS4_UP}\n  WideStrings,\n{$ENDIF}\n{$IFNDEF FPC}\n  DesignIntf, DesignEditors;\n{$ELSE}\n    PropEdits;\n{$ENDIF}\n\ntype\n\n  {** Implements the basic methods of the property editor. }\n  TZStringProperty = class(TStringProperty)\n  public\n    function  GetAttributes: TPropertyAttributes; override;\n    procedure GetValueList(List: TStrings); virtual; abstract;\n    procedure GetValues(Proc: TGetStrProc); override;\n    function  GetZComponent:TPersistent; virtual;\n  end;\n\n  {** Shows all Fields received from FieldDefs. }\n  TZDataFieldPropertyEditor = class(TZStringProperty)\n  public\n    procedure GetValueList(List: TStrings); override;\n  end;\n\n  {** Shows all Fields received from IndexDefs - not used yet. }\n  TZIndexFieldPropertyEditor = class(TZStringProperty)\n  public\n    procedure GetValueList(List: TStrings); override;\n  end;\n\n  {** Shows all Fields received from the MasterSource's DataSet.FieldDefs. }\n  TZMasterFieldPropertyEditor = class(TZStringProperty)\n  public\n    procedure GetValueList(List: TStrings); override;\n  end;\n\n  {** Shows all Tables received from Connection.IZDatabaseMetadata. }\n  TZTableNamePropertyEditor = class(TZStringProperty)\n  public\n    procedure GetValueList(List: TStrings); override;\n  end;\n\n  {** Shows all Procedures received from Connection.IZDatabaseMetadata. }\n  TZProcedureNamePropertyEditor = class(TZStringProperty)\n  public\n    procedure GetValueList(List: TStrings); override;\n  end;\n\n  {** Shows all Sequences received from Connection.IZDatabaseMetadata. }\n  TZSequenceNamePropertyEditor = class(TZStringProperty)\n  public\n    procedure GetValueList(List: TStrings); override;\n  end;\n\n  {** Implements a property editor for ZConnection.Protocol property. }\n  TZProtocolPropertyEditor = class(TZStringProperty)\n  public\n    function  GetValue: string; override;\n    procedure GetValueList(List: TStrings); override;\n    procedure SetValue(const Value: string); override;\n  end;\n\n  {** Implements a property editor for ZConnection.ClientCodePage property. }\n  TZClientCodePagePropertyEditor = class(TZStringProperty)\n  public\n    function  GetValue: string; override;\n    procedure GetValueList(List: TStrings); override;\n    procedure SetValue(const Value: string); override;\n  end;\n\n  {** Implements a property editor for ZConnection.Database property. }\n  TZDatabasePropertyEditor = class(TZStringProperty)\n  public\n    function  GetAttributes: TPropertyAttributes; override;\n    function  GetValue: string; override;\n    procedure Edit; override;\n    procedure GetValueList(List: TStrings); override;\n    procedure SetValue(const Value: string); override;\n  end;\n\n  {** Implements a property editor for ZConnection.LibLocation property. }\n  TZLibLocationPropertyEditor = class(TZStringProperty)\n  public\n    function  GetAttributes: TPropertyAttributes; override;\n    function  GetValue: string; override;\n    procedure Edit; override;\n    procedure SetValue(const Value: string); override;\n  end;\n\n  // Modified by Una.Bicicleta 2010/10/31\n  {** Implements a property editor for ZConnectionGroup.Database property. }\n  TZConnectionGroupPropertyEditor = class(TZStringProperty)\n  public\n    function  GetAttributes: TPropertyAttributes; override;\n    function  GetValue: string; override;\n    procedure Edit; override;\n    procedure GetValueList(List: TStrings); override;\n    procedure SetValue(const Value: string); override;\n  end;\n\n  {** Implements a property editor for ZGroupedConnection.Catalog property. }\n  TZGroupedConnectionCatalogPropertyEditor = class(TZStringProperty)\n  public\n    function  GetValue: string; override;\n    procedure GetValueList(List: TStrings); override;\n    procedure SetValue(const Value: string); override;\n  end;\n\n  {** Implements a property editor for ZGroupedConnection.LibLocation property. }\n  {** added 2013/02/20 }\n  TZConnectionGroupLibLocationPropertyEditor = class(TZStringProperty)\n  public\n    function  GetAttributes: TPropertyAttributes; override;\n    function  GetValue: string; override;\n    procedure Edit; override;\n    procedure SetValue(const Value: string); override;\n  end;\n  /////////////////////////////////////////////////////////\n\n\n  {** Implements a property editor for ZConnection.Catalog property. }\n  TZCatalogPropertyEditor = class(TZStringProperty)\n  public\n    function  GetValue: string; override;\n    procedure GetValueList(List: TStrings); override;\n    procedure SetValue(const Value: string); override;\n  end;\n\n{$IFDEF USE_METADATA}\n  {** Shows all Catalogs received from Connection.IZDatabaseMetadata. }\n  TZCatalogProperty = class(TZStringProperty)\n  public\n    procedure GetValueList(List: TStrings); override;\n  end;\n\n  {** Shows all Columns received from Connection.IZDatabaseMetadata. }\n  TZColumnNamePropertyEditor = class(TZStringProperty)\n  public\n    procedure GetValueList(List: TStrings); override;\n  end;\n\n  {** Shows all Schemes received from Connection.IZDatabaseMetadata. }\n  TZSchemaPropertyEditor = class(TZStringProperty)\n  public\n    procedure GetValueList(List: TStrings); override;\n  end;\n\n  {** Shows all Types received from Connection.IZDatabaseMetadata. }\n  TZTypeNamePropertyEditor = class(TZStringProperty)\n  public\n    procedure GetValueList(List: TStrings); override;\n  end;\n{$ENDIF}\n\nconst\n  CRLF = LineEnding;\n\n{$ENDIF}\n\nimplementation\n\n{$IFDEF WITH_PROPERTY_EDITOR}\n\nuses SysUtils, Forms, Dialogs, Controls, DB, TypInfo, ZSysUtils, ZSelectSchema\n{$IFDEF USE_METADATA}\n  , ZSqlMetadata\n{$ENDIF}\n{$IFNDEF UNIX}\n  {$IFNDEF FPC}\n  {$IFDEF ENABLE_ADO}\n, ZDbcAdoUtils\n  {$ENDIF}\n  {$ENDIF}\n{$ENDIF}\n{$IFDEF SHOW_WARNING}\n,ZMessages\n{$ENDIF SHOW_WARNING}\n;\n\n{$IFDEF FPC}\nprocedure GetItemNames(FieldDefs: TFieldDefs; List: TStrings); overload;\nvar\n  i: Integer;\nbegin\n  List.Clear;\n  for i := 0 to Pred(FieldDefs.Count) do\n    List.Append(FieldDefs[i].Name);\nend;\n\nprocedure GetItemNames(IndexDefs: TIndexDefs; List: TStrings); overload;\nvar\n  i: Integer;\nbegin\n  List.Clear;\n  for i := 0 to Pred(IndexDefs.Count) do\n    List.Append(IndexDefs[i].Name);\nend;\n{$ENDIF}\n\n{ Returns the IndexDefs from Dataset }\nfunction GetIndexDefs(Component: TPersistent): TIndexDefs;\nvar\n  DataSet: TDataSet;\nbegin\n  DataSet := Component as TDataSet;\n  Result := GetObjectProp(DataSet, 'IndexDefs') as TIndexDefs;\n  if Assigned(Result) then\n  begin\n    Result.Updated := False;\n    Result.Update;\n  end;\nend;\n\nfunction IsEmpty(const s: string): Boolean;\nbegin\n  Result := Trim(s) = '';\nend;\n\n{ TZStringProperty }\n\n{**\n  Gets a type of property attributes.\n  @return a type of property attributes.\n}\nfunction TZStringProperty.GetAttributes: TPropertyAttributes;\nbegin\n  Result := [paValueList, paSortList];\nend;\n\n{**\n  Processes a list of list items.\n  @param Proc a procedure to process the list items.\n}\nprocedure TZStringProperty.GetValues(Proc: TGetStrProc);\nvar\n  i: Integer;\n  Values: TStringList;\nbegin\n  Values := TStringList.Create;\n  try\n    GetValueList(Values);\n    for i := 0 to Pred(Values.Count) do\n      Proc(Values[i]);\n  finally\n    Values.Free;\n  end;\nend;\n\n{**\n  Gets the component that has the property.\n}\nfunction TZStringProperty.GetZComponent:TPersistent;\nbegin\n  Result:=GetComponent(0);\nend;\n\n{ TZDataFieldPropertyEditor }\n\n{**\n  Processes a list of list items.\n  @param List the list to process the list items.\n}\nprocedure TZDataFieldPropertyEditor.GetValueList(List: TStrings);\nbegin\n  try\n    with (GetZComponent as TDataSet) do\n    begin\n      // Update the FieldDefs and return the Fieldnames\n      FieldDefs.Updated := False;\n      FieldDefs.Update;\n      {$IFNDEF FPC}\n      FieldDefs.GetItemNames(List);\n      {$ELSE}\n      GetItemNames(FieldDefs, List);\n      {$ENDIF}\n    end;\n  except\n  end;\nend;\n\n{ TZIndexFieldPropertyEditor }\n\nprocedure TZIndexFieldPropertyEditor.GetValueList(List: TStrings);\nbegin\n  {$IFNDEF FPC}\n  GetIndexDefs(GetZComponent).GetItemNames(List);\n  {$ELSE}\n  GetItemNames(GetIndexDefs(GetZComponent), List);\n  {$ENDIF}\nend;\n\n{ TZMasterFieldPropertyEditor }\n\nprocedure TZMasterFieldPropertyEditor.GetValueList(List: TStrings);\nvar\n  DataSource: TDataSource;\nbegin\n  DataSource := GetObjectProp(GetZComponent, 'MasterSource') as TDataSource;\n  if (DataSource <> nil) and (DataSource.DataSet <> nil) then\n    {$IFDEF WITH_WIDESTRINGS_GETFIELDNAMES}\n    DataSource.DataSet.GetFieldNames(TWideStrings(List));\n    {$ELSE}\n    DataSource.DataSet.GetFieldNames(List);\n    {$ENDIF}\nend;\n\n{ TZTableNamePropertyEditor }\n\n{**\n  Processes a list of list items.\n  @param List the list to process the list items.\n}\nprocedure TZTableNamePropertyEditor.GetValueList(List: TStrings);\nvar\n  Connection: TZAbstractConnection;\n  Metadata: IZDatabaseMetadata;\n  ResultSet: IZResultSet;\n  Schema, Tablename:String;\n  IdentifierConvertor: IZIdentifierConvertor;\n  Catalog: string;\nbegin\n  Connection := GetObjectProp(GetZComponent, 'Connection') as TZAbstractConnection;\n  if Assigned(Connection) and Connection.Connected then\n  begin\n    Metadata := Connection.DbcConnection.GetMetadata;\n    IdentifierConvertor := Metadata.GetIdentifierConvertor;\n    Catalog := Connection.Catalog;\n    Schema := '';\n{$IFDEF USE_METADATA}\n    if GetZComponent is TZSqlMetadata then\n    begin\n      Catalog := GetStrProp(GetZComponent, 'Catalog');\n      Schema := GetStrProp(GetZComponent, 'Schema');\n{$IFDEF SHOW_WARNING}\n      if not (IsEmpty(Catalog) and IsEmpty(Schema)) or\n       (MessageDlg(SPropertyQuery + CRLF + SPropertyTables + CRLF +\n        SPropertyExecute, mtWarning, [mbYes,mbNo], 0) = mrYes) then\n        begin\n        // continue\n        end\n      else\n        exit;\n{$ENDIF}\n    end;\n{$ENDIF}\n    begin\n      try\n        // Look for the Tables of the defined Catalog and Schema\n        ResultSet := Metadata.GetTables(Catalog, Schema, '', nil);\n        while ResultSet.Next do\n          begin\n            TableName := ResultSet.GetStringByName('TABLE_NAME');\n            TableName := IdentifierConvertor.Quote(TableName);\n            Schema := ResultSet.GetStringByName('TABLE_SCHEM');\n            (*if Connection.DbcConnection.GetMetadata.GetDatabaseInfo.SupportsCatalogsInTableDefinitions then\n              if Catalog <> '' then\n                if Schema <> '' then\n                  TableName := IdentifierConvertor.Quote(Catalog) + IdentifierConvertor.Quote(Schema) + '.' + TableName\n                else\n                  TableName := {IdentifierConvertor.Quote(Catalog) + '.' + }TableName\n              else\n                if Schema <> '' then\n                  TableName := IdentifierConvertor.Quote(Schema) + '.' + TableName\n                else\n                  TableName := TableName\n            else\n              if Schema <> '' then\n                TableName := IdentifierConvertor.Quote(Schema) + '.' + TableName\n              else\n                TableName := TableName;*)\n            if Schema <> '' then\n              TableName := IdentifierConvertor.Quote(Schema) + '.' + TableName;\n            if Catalog <> '' then\n              TableName := IdentifierConvertor.Quote(Catalog) + '.' + TableName;\n            List.Add(TableName);\n          end;\n      finally\n        ResultSet.Close;\n      end;\n    end;\n  end;\nend;\n\n{ TZProcedureNamePropertyEditor }\n\n{**\n  Processes a list of list items.\n  @param List the list to process the list items.\n}\nprocedure TZProcedureNamePropertyEditor.GetValueList(List: TStrings);\nvar\n  Connection: TZAbstractConnection;\n  Metadata: IZDatabaseMetadata;\n  IdentifierConvertor: IZIdentifierConvertor;\n  ResultSet: IZResultSet;\n  Catalog, Schema: string;\n  ProcedureName: string;\n\n  procedure ExtractOverload(OverloadSeparator: String);\n  var\n    I: Integer;\n    SL: TStrings;\n  begin\n    SL := TStringList.Create;\n    PutSplitString(SL, ProcedureName, OverloadSeparator);\n    if SL.Count > 1 then\n    begin\n      SL.Delete(SL.Count -1);\n      ProcedureName := '';\n      for i := 0 to SL.Count -1 do\n        if ProcedureName = '' then\n          ProcedureName := ProcedureName + SL[i]\n        else\n          ProcedureName :=  ProcedureName +OverloadSeparator+ SL[i]; //don't forget to give the delimiter back too\n    end;\n  end;\nbegin\n  Connection := GetObjectProp(GetZComponent, 'Connection') as TZAbstractConnection;\n  if Assigned(Connection) and Connection.Connected then\n  begin\n    Metadata := Connection.DbcConnection.GetMetadata;\n    IdentifierConvertor := Metadata.GetIdentifierConvertor;\n    Catalog := Connection.Catalog;\n    Schema := '';\n{$IFDEF USE_METADATA}\n    if GetZComponent is TZSqlMetadata then\n    begin\n      Catalog := GetStrProp(GetZComponent, 'Catalog');\n      Schema := GetStrProp(GetZComponent, 'Schema');\n{$IFDEF SHOW_WARNING}\n      if not (IsEmpty(Catalog) and IsEmpty(Schema)) or\n       (MessageDlg(SPropertyQuery + CRLF + SPropertyProcedures + CRLF +\n        SPropertyExecute, mtWarning, [mbYes,mbNo], 0) = mrYes) then\n        begin\n        // continue\n        end\n      else\n        exit;\n{$ENDIF}\n    end;\n{$ENDIF}\n    begin\n      try\n        Metadata := Connection.DbcConnection.GetMetadata;\n        // Look for the Procedures\n        ResultSet := Metadata.GetProcedures(Catalog, Schema, '');\n        while ResultSet.Next do\n        begin\n          ProcedureName := ResultSet.GetStringByName('PROCEDURE_NAME');\n          if ( not Metadata.GetDatabaseInfo.SupportsOverloadPrefixInStoredProcedureName ) then\n            if not ( StartsWith(ProcedureName, MetaData.GetDatabaseInfo.GetIdentifierQuoteString) or\n                     EndsWith(ProcedureName, MetaData.GetDatabaseInfo.GetIdentifierQuoteString) or\n                     (Pos('.', ProcedureName) > 0) ) then\n              ProcedureName := IdentifierConvertor.Quote(ProcedureName);\n          Schema := ResultSet.GetStringByName('PROCEDURE_SCHEM');\n          if Metadata.GetDatabaseInfo.SupportsCatalogsInProcedureCalls then\n            if Catalog <> '' then\n              if Schema <> '' then\n                ProcedureName := IdentifierConvertor.Quote(Catalog) +'.'+ IdentifierConvertor.Quote(Schema) + '.' + ProcedureName\n              else\n                ProcedureName := ProcedureName\n            else\n              if Schema <> '' then\n                ProcedureName := IdentifierConvertor.Quote(Schema) + '.' + ProcedureName\n              else\n                ProcedureName := ProcedureName\n          else\n            if Schema <> '' then\n              ProcedureName := IdentifierConvertor.Quote(Schema) + '.' + ProcedureName\n            else\n              ProcedureName := ProcedureName;\n          List.Add(ProcedureName);\n        end;\n      finally\n        ResultSet.Close;\n      end;\n    end;\n  end;\nend;\n\n{ TZSequenceNamePropertyEditor }\n\n{**\n  Gets a selected string value.\n  @return a selected string value.\n}\nprocedure TZSequenceNamePropertyEditor.GetValueList(List: TStrings);\nvar\n  Connection: TZAbstractConnection;\n  Metadata: IZDatabaseMetadata;\n  ResultSet: IZResultSet;\n{$IFDEF USE_METADATA}\n  Catalog, Schema: string;\n{$ENDIF}\nbegin\n  Connection := GetObjectProp(GetZComponent, 'Connection') as TZAbstractConnection;\n  if Assigned(Connection) and Connection.Connected then\n  begin\n{$IFDEF USE_METADATA}\n    if GetZComponent is TZSqlMetadata then\n    begin\n      Catalog := GetStrProp(GetZComponent, 'Catalog');\n      Schema := GetStrProp(GetZComponent, 'Schema');\n{$IFDEF SHOW_WARNING}\n      if not (IsEmpty(Catalog) and IsEmpty(Schema)) or\n       (MessageDlg(SPropertyQuery + CRLF + SPropertySequences + CRLF +\n        SPropertyExecute, mtWarning, [mbYes,mbNo], 0) = mrYes) then\n{$ENDIF}\n      try\n        Metadata := Connection.DbcConnection.GetMetadata;\n        // Look for the Procedures of the defined Catalog and Schema\n        ResultSet := Metadata.GetSequences(Catalog, Schema, '');\n        while ResultSet.Next do\n          List.Add(ResultSet.GetStringByName('SEQUENCE_NAME'));\n      finally\n        ResultSet.Close;\n      end;\n    end\n    else\n{$ENDIF}\n    begin\n      try\n        Metadata := Connection.DbcConnection.GetMetadata;\n        // Look for the Procedures\n        ResultSet := Metadata.GetSequences(Connection.Catalog, '', '');\n        while ResultSet.Next do\n          if ResultSet.GetStringByName('SEQUENCE_SCHEM') <> '' then\n            List.Add(ResultSet.GetStringByName('SEQUENCE_SCHEM')+\n              '.'+ResultSet.GetStringByName('SEQUENCE_NAME'))\n          else\n            List.Add(ResultSet.GetStringByName('SEQUENCE_NAME'));\n      finally\n        ResultSet.Close;\n      end;\n    end;\n  end;\nend;\n\n{ TZProtocolPropertyEditor }\n\n{**\n  Gets a selected string value.\n  @return a selected string value.\n}\nfunction TZProtocolPropertyEditor.GetValue: string;\nbegin\n  Result := GetStrValue;\nend;\n\n{**\n  Sets a new selected string value.\n  @param Value a new selected string value.\n}\nprocedure TZProtocolPropertyEditor.SetValue(const Value: string);\nbegin\n  SetStrValue(Value);\n  if GetZComponent is TZAbstractConnection then\n    (GetZComponent as TZAbstractConnection).Connected := False;\nend;\n\n{**\n  Processes a list of list items.\n  @param List the list to process the list items.\n}\nprocedure TZProtocolPropertyEditor.GetValueList(List: TStrings);\nvar\n  I, J: Integer;\n  Drivers: IZCollection;\n  Protocols: TStringDynArray;\nbegin\n  Drivers := DriverManager.GetDrivers;\n  Protocols := nil;\n  for I := 0 to Drivers.Count - 1 do\n  begin\n    Protocols := (Drivers[I] as IZDriver).GetSupportedProtocols;\n    for J := Low(Protocols) to High(Protocols) do\n      List.Append(Protocols[J]);\n  end;\nend;\n\n{TZClientCodePagePropertyEditor -> EgonHugeist 19.01.2012}\n\n{**\n  Sets a new selected string value.\n  @param Value a new selected string value.\n}\nfunction  TZClientCodePagePropertyEditor.GetValue: string;\nbegin\n  Result := GetStrValue;\nend;\n\n{**\n  Processes a list of list items.\n  @param List the list to process the list items.\n}\nprocedure TZClientCodePagePropertyEditor.GetValueList(List: TStrings);\nvar\n  Connection: TZAbstractConnection;\n  I: Integer;\n  SDyn: TStringDynArray;\n  Url: TZURL;\nbegin\n\n  if GetZComponent is TZAbstractConnection then\n    Connection := (GetZComponent as TZAbstractConnection)\n  else\n    Connection := nil;\n\n  if Assigned(Connection) then\n  begin\n    if Connection.Protocol = '' then\n      List.Append('No Protocol selected!')\n    else\n    begin\n      Url := TZURL.Create;\n      Url.Protocol :=  Connection.Protocol;\n      SDyn := DriverManager.GetDriver(Url.URL).GetSupportedClientCodePages(Url,\n        {$IFNDEF UNICODE}Connection.AutoEncodeStrings, {$ENDIF}True, Connection.ControlsCodePage);\n      Url.Free;\n      for i := 0 to high(SDyn) do\n        List.Append(SDyn[i]);\n\n      TStringList(List).Sort;\n    end;\n  end;\nend;\n\n{**\n  Sets a new selected string value.\n  @param Value a new selected string value.\n}\nprocedure TZClientCodePagePropertyEditor.SetValue(const Value: string);\nbegin\n  SetStrValue(Value);\n  if GetZComponent is TZAbstractConnection then\n    (GetZComponent as TZAbstractConnection).Connected := False;\nend;\n\n\n{ TZDatabasePropertyEditor }\n\n{**\n  Gets a type of property attributes.\n  @return a type of property attributes.\n}\nfunction TZDatabasePropertyEditor.GetAttributes: TPropertyAttributes;\nbegin\n  if GetZComponent is TZAbstractConnection then\n  begin\n    if ((GetZComponent as TZAbstractConnection).Protocol = 'mssql') or\n    ((GetZComponent as TZAbstractConnection).Protocol = 'sybase') then\n      Result := inherited GetAttributes\n    else\n      Result := [paDialog];\n  end;\nend;\n\n{**\n  Gets a selected string value.\n  @return a selected string value.\n}\nfunction TZDatabasePropertyEditor.GetValue: string;\nbegin\n  Result := GetStrValue;\nend;\n\n{**\n  Sets a new selected string value.\n  @param Value a new selected string value.\n}\nprocedure TZDatabasePropertyEditor.SetValue(const Value: string);\nbegin\n  SetStrValue(Value);\n  if GetZComponent is TZAbstractConnection then\n    (GetZComponent as TZAbstractConnection).Connected := False;\nend;\n\n{**\n  Processes a list of list items.\n  @param List the list to process the list items.\n}\nprocedure TZDatabasePropertyEditor.GetValueList(List: TStrings);\nvar\n  DbcConnection: IZConnection;\n  Url: string;\nbegin\n  if GetZComponent is TZAbstractConnection then\n  try\n    URL := (GetZComponent as TZAbstractConnection).GetURL;\n      (GetZComponent as TZAbstractConnection).ShowSqlHourGlass;\n    try\n      DbcConnection := DriverManager.GetConnectionWithParams(Url,\n        (GetZComponent as TZAbstractConnection).Properties);\n\n      with DbcConnection.GetMetadata.GetCatalogs do\n      try\n        while Next do\n          List.Append(GetStringByName('TABLE_CAT'));\n      finally\n        Close;\n      end;\n\n    finally\n      (GetZComponent as TZAbstractConnection).HideSqlHourGlass;\n    end;\n  except\n//    raise;\n  end;\nend;\n\n{**\n  Brings up the proper database property editor dialog.\n}\nprocedure TZDatabasePropertyEditor.Edit;\nvar\n  OD: TOpenDialog;\nbegin\n  if GetZComponent is TZAbstractConnection then\n  begin\n    if ((GetZComponent as TZAbstractConnection).Protocol = 'mssql') or\n    ((GetZComponent as TZAbstractConnection).Protocol = 'sybase') then\n      inherited\n{$IFNDEF UNIX}\n{$IFNDEF FPC}\n{$IFDEF ENABLE_ADO}\n    else\n    if ((GetZComponent as TZAbstractConnection).Protocol = 'ado') then\n      (GetZComponent as TZAbstractConnection).Database := PromptDataSource(Application.Handle,\n        (GetZComponent as TZAbstractConnection).Database)\n{$ENDIF}\n{$ENDIF}\n{$ENDIF}\n    else\n    begin\n      OD := TOpenDialog.Create(nil);\n      try\n        OD.InitialDir := ExtractFilePath((GetZComponent as TZAbstractConnection).Database);\n        if OD.Execute then\n          (GetZComponent as TZAbstractConnection).Database := OD.FileName;\n      finally\n        OD.Free;\n      end;\n    end;\n  end\n  else\n    inherited;\nend;\n\n{ TZLibLocationPropertyEditor }\n\n{**\n  Gets a type of property attributes.\n  @return a type of property attributes.\n}\nfunction TZLibLocationPropertyEditor.GetAttributes: TPropertyAttributes;\nbegin\n  if GetZComponent is TZAbstractConnection then\n    Result := [paDialog];\nend;\n\n{**\n  Gets a selected string value.\n  @return a selected string value.\n}\nfunction TZLibLocationPropertyEditor.GetValue: string;\nbegin\n  Result := GetStrValue;\nend;\n\n{**\n  Sets a new selected string value.\n  @param Value a new selected string value.\n}\nprocedure TZLibLocationPropertyEditor.SetValue(const Value: string);\nbegin\n  SetStrValue(Value);\n  if GetZComponent is TZAbstractConnection then\n    (GetZComponent as TZAbstractConnection).Connected := False;\nend;\n\n{**\n  Brings up the proper LibLocation property editor dialog.\n}\nprocedure TZLibLocationPropertyEditor.Edit;\nvar\n  OD: TOpenDialog;\nbegin\n  if GetZComponent is TZAbstractConnection then\n  begin\n    OD := TOpenDialog.Create(nil);\n    try\n      OD.InitialDir := ExtractFilePath((GetZComponent as TZAbstractConnection).LibLocation);\n      if OD.Execute then\n        (GetZComponent as TZAbstractConnection).LibLocation := OD.FileName;\n    finally\n      OD.Free;\n    end;\n  end\n  else\n    inherited;\nend;\n\n{ TZCatalogPropertyEditor }\n\n{**\n  Gets a selected string value.\n  @return a selected string value.\n}\nfunction TZCatalogPropertyEditor.GetValue: string;\nbegin\n  Result := GetStrValue;\nend;\n\n{**\n  Sets a new selected string value.\n  @param Value a new selected string value.\n}\nprocedure TZCatalogPropertyEditor.SetValue(const Value: string);\nbegin\n  SetStrValue(Value);\nend;\n\n{**\n  Processes a list of list items.\n  @param List the list to process the list items.\n}\nprocedure TZCatalogPropertyEditor.GetValueList(List: TStrings);\nvar\n  DbcConnection: IZConnection;\n  Url: string;\nbegin\n  if GetZComponent is TZAbstractConnection then\n  try\n    URL := (GetZComponent as TZAbstractConnection).GetURL;\n    (GetZComponent as TZAbstractConnection).ShowSqlHourGlass;\n    try\n      DbcConnection := DriverManager.GetConnectionWithParams(Url,\n        (GetZComponent as TZAbstractConnection).Properties);\n\n      if Assigned(DbcConnection) then\n        if DbcConnection.GetMetadata.GetDatabaseInfo.SupportsCatalogsInDataManipulation then\n          with DbcConnection.GetMetadata.GetCatalogs do\n          try\n            while Next do\n              List.Append(GetStringByName('TABLE_CAT'));\n          finally\n            Close;\n          end\n        else if DbcConnection.GetMetadata.GetDatabaseInfo.SupportsSchemasInDataManipulation then\n          with DbcConnection.GetMetadata.GetSchemas do\n          try\n            while Next do\n              List.Append(GetStringByName('TABLE_SCHEM'));\n          finally\n            Close;\n          end;\n    finally\n      (GetZComponent as TZAbstractConnection).HideSqlHourGlass;\n    end;\n  except\n//    raise;\n  end;\nend;\n\n{$IFDEF USE_METADATA}\n\n{ TZCatalogProperty }\n\n{**\n  Processes a list of list items.\n  @param List the list to process the list items.\n}\nprocedure TZCatalogProperty.GetValueList(List: TStrings);\nvar\n  Connection: TZAbstractConnection;\n  Metadata: IZDatabaseMetadata;\n  ResultSet: IZResultSet;\nbegin\n  Connection := GetObjectProp(GetZComponent, 'Connection') as TZAbstractConnection;\n  if Assigned(Connection) and Connection.Connected then\n  try\n    Metadata := Connection.DbcConnection.GetMetadata;\n    ResultSet := Metadata.GetCatalogs;\n    while ResultSet.Next do\n      List.Add(ResultSet.GetStringByName('TABLE_CAT'));\n  finally\n    ResultSet.Close;\n  end;\nend;\n\n{ TZColumnNamePropertyEditor }\n\n{**\n  Processes a list of list items.\n  @param List the list to process the list items.\n}\nprocedure TZColumnNamePropertyEditor.GetValueList(List: TStrings);\nvar\n  Connection: TZAbstractConnection;\n  Metadata: IZDatabaseMetadata;\n  ResultSet: IZResultSet;\n  Catalog, Schema, TableName: string;\nbegin\n  Connection := GetObjectProp(GetZComponent, 'Connection') as TZAbstractConnection;\n  if Assigned(Connection) and Connection.Connected then\n  begin\n    Catalog := GetStrProp(GetZComponent, 'Catalog');\n    Schema := GetStrProp(GetZComponent, 'Schema');\n    TableName := GetStrProp(GetZComponent, 'TableName');\n{$IFDEF SHOW_WARNING}\n    if not IsEmpty(TableName) or not (IsEmpty(Schema) and IsEmpty(Schema)) or\n     (MessageDlg(SPropertyQuery + CRLF + SPropertyTables + CRLF +\n      SPropertyExecute, mtWarning, [mbYes,mbNo], 0) = mrYes) then\n{$ENDIF}\n    try\n      Metadata := Connection.DbcConnection.GetMetadata;\n      // Look for the Columns of the defined Catalog, Schema and TableName\n      ResultSet := Metadata.GetColumns(Catalog, Schema, TableName, '');\n      while ResultSet.Next do\n        if List.IndexOf(ResultSet.GetStringByName('COLUMN_NAME')) = -1 then\n          List.Add(ResultSet.GetStringByName('COLUMN_NAME'));\n    finally\n      ResultSet.Close;\n    end;\n  end;\nend;\n\n{ TZSchemaPropertyEditor }\n\n{**\n  Processes a list of list items.\n  @param List the list to process the list items.\n}\nprocedure TZSchemaPropertyEditor.GetValueList(List: TStrings);\nvar\n  Connection: TZAbstractConnection;\n  Metadata: IZDatabaseMetadata;\n  ResultSet: IZResultSet;\nbegin\n  Connection := GetObjectProp(GetZComponent, 'Connection') as TZAbstractConnection;\n  if Assigned(Connection) and Connection.Connected then\n  try\n    Metadata := Connection.DbcConnection.GetMetadata;\n    ResultSet := Metadata.GetSchemas;\n    while ResultSet.Next do\n      List.Add(ResultSet.GetStringByName('TABLE_SCHEM'));\n  finally\n    ResultSet.Close;\n  end;\nend;\n\n{ TZTypeNamePropertyEditor }\n\n{**\n  Processes a list of list items.\n  @param List the list to process the list items.\n}\nprocedure TZTypeNamePropertyEditor.GetValueList(List: TStrings);\nvar\n  Connection: TZAbstractConnection;\n  Metadata: IZDatabaseMetadata;\n  ResultSet: IZResultSet;\nbegin\n  Connection := GetObjectProp(GetZComponent, 'Connection') as TZAbstractConnection;\n  if Assigned(Connection) and Connection.Connected then\n  try\n    Metadata := Connection.DbcConnection.GetMetadata;\n    ResultSet := Metadata.GetTypeInfo;\n    while ResultSet.Next do\n      List.Add(ResultSet.GetStringByName('TYPE_NAME'));\n  finally\n    ResultSet.Close;\n  end;\nend;\n\n\n//xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\n\n{ TZConnectionGroupCatalogPropertyEditor }\n\n\nfunction TZGroupedConnectionCatalogPropertyEditor.GetValue: string;\nbegin\n  Result := GetStrValue;\nend;\n\nprocedure TZGroupedConnectionCatalogPropertyEditor.SetValue(const Value: string);\nbegin\n  SetStrValue(Value);\nend;\n\nprocedure TZGroupedConnectionCatalogPropertyEditor.GetValueList(List: TStrings);\nvar\n  DbcConnection: IZConnection;\n  Url: string;\nbegin\n  if GetZComponent is TZAbstractConnection then\n  try\n    URL := (GetZComponent as TZAbstractConnection).GetURL;\n    (GetZComponent as TZAbstractConnection).ShowSqlHourGlass;\n    try\n      DbcConnection := DriverManager.GetConnectionWithParams(Url,\n        (GetZComponent as TZAbstractConnection).Properties);\n\n      with DbcConnection.GetMetadata.GetCatalogs do\n      try\n        while Next do\n          List.Append(GetStringByName('TABLE_CAT'));\n      finally\n        Close;\n      end;\n\n    finally\n      (GetZComponent as TZAbstractConnection).HideSqlHourGlass;\n    end;\n  except\n//    raise;\n  end;\nend;\n\n\n\n\n{ TZConnectionGroupPropertyEditor }\n\n{**\n  Gets a type of property attributes.\n  @return a type of property attributes.\n}\nfunction TZConnectionGroupPropertyEditor.GetAttributes: TPropertyAttributes;\nbegin\n  if GetZComponent is TZConnectionGroup then\n  begin\n    if ((GetZComponent as TZConnectionGroup).Protocol = 'mssql') or\n    ((GetZComponent as TZConnectionGroup).Protocol = 'sybase') then\n      Result := inherited GetAttributes\n    else\n      Result := [paDialog];\n  end;\nend;\n\n{**\n  Gets a selected string value.\n  @return a selected string value.\n}\nfunction TZConnectionGroupPropertyEditor.GetValue: string;\nbegin\n  Result := GetStrValue;\nend;\n\n{**\n  Sets a new selected string value.\n  @param Value a new selected string value.\n}\nprocedure TZConnectionGroupPropertyEditor.SetValue(const Value: string);\nbegin\n  SetStrValue(Value);\n//  if GetZComponent is TZConnectionGroup then\n//    (GetZComponent as TZConnectionGroup).Connected := False;\nend;\n\n{**\n  Processes a list of list items.\n  @param List the list to process the list items.\n}\nprocedure TZConnectionGroupPropertyEditor.GetValueList(List: TStrings);\nvar\n  DbcConnection: IZConnection;\nbegin\n  if GetZComponent is TZConnectionGroup then\n  try\n    DbcConnection := (GetZComponent as TZAbstractConnection).DbcConnection;\n    with DbcConnection.GetMetadata.GetCatalogs do\n    try\n      while Next do\n        List.Append(GetStringByName('TABLE_CAT'));\n    finally\n      Close;\n    end;\n  except\n//    raise;\n  end;\nend;\n\n{**\n  Brings up the proper database property editor dialog.\n}\nprocedure TZConnectionGroupPropertyEditor.Edit;\nvar\n  OD: TOpenDialog;\nbegin\n  if GetZComponent is TZConnectionGroup then\n  begin\n    if ((GetZComponent as TZConnectionGroup).Protocol = 'mssql') or\n    ((GetZComponent as TZConnectionGroup).Protocol = 'sybase') then\n      inherited\n{$IFNDEF UNIX}\n{$IFNDEF FPC}\n{$IFDEF ENABLE_ADO}\n    else\n    if ((GetZComponent as TZConnectionGroup).Protocol = 'ado') then\n      (GetZComponent as TZConnectionGroup).Database := PromptDataSource(Application.Handle,\n        (GetZComponent as TZConnectionGroup).Database)\n{$ENDIF}\n{$ENDIF}\n{$ENDIF}\n    else\n    begin\n      OD := TOpenDialog.Create(nil);\n      try\n        OD.InitialDir := ExtractFilePath((GetZComponent as TZConnectionGroup).Database);\n        if OD.Execute then\n          (GetZComponent as TZConnectionGroup).Database := OD.FileName;\n      finally\n        OD.Free;\n      end;\n    end;\n  end\n  else\n    inherited;\nend;\n\n{** added 2013/02/20 }\n{ TZConnectionGroupLibLocationPropertyEditor }\n\n{**\n  Gets a type of property attributes.\n  @return a type of property attributes.\n}\nfunction TZConnectionGroupLibLocationPropertyEditor.GetAttributes: TPropertyAttributes;\nbegin\n  if GetZComponent is TZConnectionGroup then\n    Result := [paDialog];\nend;\n\n{**\n  Gets a selected string value.\n  @return a selected string value.\n}\nfunction TZConnectionGroupLibLocationPropertyEditor.GetValue: string;\nbegin\n  Result := GetStrValue;\nend;\n\n{**\n  Sets a new selected string value.\n  @param Value a new selected string value.\n}\nprocedure TZConnectionGroupLibLocationPropertyEditor.SetValue(const Value: string);\nbegin\n  SetStrValue(Value);\n  //if GetZComponent is TZAbstractConnection then\n  //  (GetZComponent as TZAbstractConnection).Connected := False;\nend;\n\n{**\n  Brings up the proper LibLocation property editor dialog.\n}\nprocedure TZConnectionGroupLibLocationPropertyEditor.Edit;\nvar\n  OD: TOpenDialog;\nbegin\n  if GetZComponent is TZConnectionGroup then\n  begin\n    OD := TOpenDialog.Create(nil);\n    try\n      OD.InitialDir := ExtractFilePath((GetZComponent as TZConnectionGroup).LibraryLocation);\n      if OD.Execute then\n        (GetZComponent as TZConnectionGroup).LibraryLocation := OD.FileName;\n    finally\n      OD.Free;\n    end;\n  end\n  else\n    inherited;\nend;\n\n{$ENDIF}\n\n{$ENDIF}\n\nend.\n\n\n"
  },
  {
    "path": "lib/zeosdbo/src/component/ZQuerySQLEditor.pas",
    "content": "{*********************************************************}\n{                                                         }\n{                 Zeos Database Objects                   }\n{                 SQL Monitor component                   }\n{                                                         }\n{        Originally written by Sergey Seroukhov           }\n{                                                         }\n{*********************************************************}\n\n{@********************************************************}\n{    Copyright (c) 1999-2012 Zeos Development Group       }\n{                                                         }\n{ License Agreement:                                      }\n{                                                         }\n{ This library is distributed in the hope that it will be }\n{ useful, but WITHOUT ANY WARRANTY; without even the      }\n{ implied warranty of MERCHANTABILITY or FITNESS FOR      }\n{ A PARTICULAR PURPOSE.  See the GNU Lesser General       }\n{ Public License for more details.                        }\n{                                                         }\n{ The source code of the ZEOS Libraries and packages are  }\n{ distributed under the Library GNU General Public        }\n{ License (see the file COPYING / COPYING.ZEOS)           }\n{ with the following  modification:                       }\n{ As a special exception, the copyright holders of this   }\n{ library give you permission to link this library with   }\n{ independent modules to produce an executable,           }\n{ regardless of the license terms of these independent    }\n{ modules, and to copy and distribute the resulting       }\n{ executable under terms of your choice, provided that    }\n{ you also meet, for each linked independent module,      }\n{ the terms and conditions of the license of that module. }\n{ An independent module is a module which is not derived  }\n{ from or based on this library. If you modify this       }\n{ library, you may extend this exception to your version  }\n{ of the library, but you are not obligated to do so.     }\n{ If you do not wish to do so, delete this exception      }\n{ statement from your version.                            }\n{                                                         }\n{                                                         }\n{ The project web site is located on:                     }\n{   http://zeos.firmos.at  (FORUM)                        }\n{   http://sourceforge.net/p/zeoslib/tickets/ (BUGTRACKER)}\n{   svn://svn.code.sf.net/p/zeoslib/code-0/trunk (SVN)    }\n{                                                         }\n{   http://www.sourceforge.net/projects/zeoslib.          }\n{                                                         }\n{                                                         }\n{                                 Zeos Development Group. }\n{********************************************************@}\n\nunit ZQuerySQLEditor;\n\n{$I ZComponent.inc}\n\ninterface\n\nuses\n{$IFDEF MSWINDOWS}\n  Windows, Messages,\n{$ENDIF}\n  {$IFDEF FPC}\n  LCLIntf,\n  {$ENDIF}\n  SysUtils, Classes, Graphics, Controls, Forms, Dialogs, Graphtype,\n  StdCtrls, ExtCtrls, ComCtrls, Buttons, ZDataset, Menus, ZMessages;\n  //{$IFDEF USE_SYNEDIT}\n  //, SynEdit, SynEditHighlighter, SynHighlighterSQL\n  //{$IFDEF FPC}\n  //, SynCompletion\n  //{$ELSE}\n  //, SynCompletionProposal\n  //{$ENDIF}\n  //{$ENDIF};\n\ntype\n\n  { TZQuerySQLEditorForm }\n\n  TZQuerySQLEditorForm = class(TForm)\n  private\n    mnuSave: TMenuItem;\n    mnuLoad: TMenuItem;\n    dlgOpen: TOpenDialog;\n    PopupMenu1: TPopupMenu;\n    dlgSave: TSaveDialog;\n    btnOk: TBitBtn;\n    btnCancel: TBitBtn;\n    Panel2: TPanel;\n    tbsSelect: TTabSheet;\n    Panel1: TPanel;\n    Splitter2: TSplitter;\n    ListBoxRelations: TListBox;\n    ListBoxFields: TListBox;\n    Splitter1: TSplitter;\n    Panel3: TPanel;\n    lblAlias: TLabel;\n    edtAlias: TEdit;\n    btnGenerate: TButton;\n    btnCheck: TButton;\n    chkReplace: TCheckBox;\n    btnTest: TButton;\n    edtSelect: TMemo;\n    //{$IFDEF USE_SYNEDIT}\n    //edtSelect: TSynEdit;\n    //SynSQLSyn1: TSynSQLSyn;\n    //{$IFDEF FPC}\n    //SynCompletion:TSynCompletion;\n    //{$ELSE}\n    //SynCompletion:TSynCompletionProposal;\n    //{$ENDIF}\n    //{$ELSE}\n    //edtSelect: TMemo;\n    //{$ENDIF}\n    FDS: TZQuery;\n    FSaveConnected: Boolean;\n    procedure FormClose(Sender: TObject; var Action: TCloseAction);\n    procedure ListBoxRelationsDblClick(Sender: TObject);\n    procedure ListBoxRelationsSelectionChange(Sender: TObject; User: boolean);\n    procedure PageControl1Change(Sender: TObject);\n    procedure ZeosQuerySQLEditorDestroy(Sender: TObject);\n    procedure btnGenerateClick(Sender: TObject);\n    procedure btnTestClick(Sender: TObject);\n    procedure mnuLoadClick(Sender: TObject);\n    procedure mnuSaveClick(Sender: TObject);\n    procedure LoadTableList;\n    procedure FillIdentifier;\n    function ActiveEditor:TMemo;\n    //function ActiveEditor:{$IFDEF USE_SYNEDIT} TSynEdit {$ELSE} TMemo {$ENDIF};\n    //{$IFDEF USE_SYNEDIT}\n    //{$IFDEF FPC}\n    //procedure ccComplete(var Value: ansistring; Shift: TShiftState);\n    //procedure ccExecute(Sender: TObject);\n    //{$ELSE}\n    //procedure ccComplete(Sender: TObject; var Value: string;\n      //Shift: TShiftState; Index: Integer; EndToken: Char);\n    //procedure ccExecute(Kind: SynCompletionType; Sender: TObject;\n      //var CurrentInput: string; var x, y: Integer; var CanExecute: Boolean);\n    //{$ENDIF}\n    //{$ENDIF}\n  public\n    PageControl1: TPageControl;\n    constructor CreateEditor(ADS:TZQuery);\n  end;\n\nvar\n  ZeosQuerySQLEditorForm: TZQuerySQLEditorForm;\n\nimplementation\nuses\n  ZSqlTestForm, ZDbcIntfs, ZCompatibility;\n\nconst\n  SQLDefaultFilter = 'SQL files (*.sql)|*.sql';\n  \n{ TZeosROSQLEditor }\n\nconstructor TZQuerySQLEditorForm.CreateEditor(ADS: TZQuery);\nbegin\n  inherited CreateNew(Application,0);\n\n  Height := 613;\n  Left := 315;\n  Top := 142;\n  TextHeight := 13;\n  Width := 768;\n  Position := poDesktopCenter;\n  Caption := sFormEditor;\n  OnClose := FormClose;\n  OnDestroy := ZeosQuerySQLEditorDestroy;\n  btnOk := TBitBtn.Create(self);\n  with btnOk do\n  begin\n    Parent := self;\n    Anchors := [akRight, akBottom];\n    Default := True;\n    Height := 25;\n    Kind := bkOk;\n    Left := 593;\n    ModalResult := mrOk;\n    TabOrder := 3;\n    TabStop := True;\n    Top := 552;\n    Width := 75;\n    Caption := SButtonOk;\n  end;\n  btnCancel := TBitBtn.Create(self);\n  with btnCancel do\n  begin\n    Parent := self;\n    Anchors := [akRight, akBottom];\n    Default := True;\n    Height := 25;\n    Kind := bkCancel;\n    Left := 677;\n    ModalResult := mrCancel;\n    TabOrder := 4;\n    TabStop := True;\n    Top := 552;\n    Width := 75;\n    Caption := SButtonCancel;\n  end;\n  btnGenerate := TButton.Create(self);\n  with btnGenerate do\n  begin\n    Parent := self;\n    Anchors := [akLeft,akBottom];\n    Caption := SButtonGenerate;\n    Height := 25;\n    Left := 8;\n    OnClick := btnGenerateClick;\n    TabOrder := 0;\n    TabStop := True;\n    Top := 552;\n    Width := 75;\n  end;\n  btnCheck := TButton.Create(self);\n  with btnCheck do\n  begin\n    Parent := self;\n    Anchors := [akLeft,akBottom];\n    Caption := SButtonCheck;\n    Enabled := False;\n    Height := 25;\n    Left := 88;\n    TabOrder := 1;\n    TabStop := True;\n    Top := 552;\n    Visible := False;\n    Width := 75;\n  end;\n  btnTest := TButton.Create(self);\n  with btnTest do\n  begin\n    Parent := self;\n    Anchors := [akLeft,akBottom];\n    Caption := SButtonTest;\n    Height := 25;\n    Left := 168;\n    OnClick := btnTestClick;\n    TabOrder := 2;\n    TabStop := True;\n    Top := 552;\n    Width := 75;\n  end;\n  dlgOpen := TOpenDialog.Create(self);\n  with dlgOpen do\n  begin\n    FilterIndex :=0;\n    Options := [ofEnableSizing,ofViewDetail];\n    Title := SDialogOpenTitle;\n    Filter := SQLDefaultFilter;\n  end;\n  dlgSave := TSaveDialog.Create(self);\n  with dlgSave do\n  begin\n    FilterIndex :=0;\n    Options := [ofEnableSizing,ofViewDetail];\n    Title := SDialogSaveTitle;\n    Filter := SQLDefaultFilter;\n  end;\n  mnuLoad := TMenuItem.Create(self);\n  with mnuLoad do\n  begin\n    Caption := SMenuLoad;\n    OnClick := mnuLoadClick;\n  end;\n  mnuSave := TMenuItem.Create(self);\n  with mnuSave do\n  begin\n    Caption := SMenuSave;\n    OnClick := mnuSaveClick;\n  end;\n  PopupMenu1 := TPopupMenu.Create(self);\n  with PopupMenu1 do\n  begin\n    AutoPopup := true;\n    Items.Add(mnuLoad);\n    Items.Add(mnuSave);\n  end;\n  Panel2 := TPanel.Create(self);\n  with Panel2 do\n  begin\n    Parent := self;\n    Align := alTop;\n    Anchors := [akTop,akLeft,akRight,akBottom];\n    FullRepaint := False;\n    Height := 545;\n    Left := 0;\n    TabOrder := 5;\n    TabStop := False;\n    Top := 0;\n    Width := 768;\n  end;\n  Splitter1 := TSplitter.Create(self);\n  with Splitter1 do\n  begin\n    Parent := Panel2;\n    Align := alRight;\n    Anchors := [akTop,akRight,akBottom];\n    Height := 543;\n    Left := 518;\n    Top := 1;\n    Width := 5;\n  end;\n  PageControl1 := TPageControl.Create(self);\n  with PageControl1 do\n  begin\n    Parent := Panel2;\n    Align := alClient;\n    Anchors := [akTop,akLeft,akRight,akBottom];\n    Height := 543;\n    Left := 1;\n    OnChange := PageControl1Change;\n    TabIndex := 0;\n    TabOrder := 0;\n    TabPosition := tpTop;\n    TabStop := True;\n    Top := 1;\n    Width := 517;\n  end;\n  tbsSelect := TTabSheet.Create(self);\n  with tbsSelect do\n  begin\n    Parent := PageControl1;\n    Caption := STabSheetSelect;\n    Height := 513;\n    Left := 2;\n    Top := 28;\n    Width := 513;\n  end;\n  Panel1 := TPanel.Create(self);\n  with Panel1 do\n  begin\n    Parent := Panel2;\n    Align := alRight;\n    Anchors := [akTop,akRight,akBottom];\n    FullRepaint := false;\n    Height := 543;\n    Left := 523;\n    TabOrder := 1;\n    TabStop := False;\n    Top := 1;\n    Width := 244;\n  end;\n  Splitter2 := TSplitter.Create(self);\n  with Splitter2 do\n  begin\n    Parent := Panel1;\n    Align := alBottom;\n    Anchors := [akLeft,akRight,akBottom];\n    Cursor := crVSplit;\n    Height := 9;\n    Left := 1;\n    Top := 271;\n    Width := 242;\n  end;\n  ListBoxRelations := TListBox.Create(self);\n  with ListBoxRelations do\n  begin\n    Parent := Panel1;\n    Align := alClient;\n    Anchors := [akTop,akLeft,akRight,akBottom];\n    Height := 198;\n    ItemHeight := 13;\n    Left := 1;\n    OnDblClick := ListBoxRelationsDblClick;\n    OnSelectionChange := ListBoxRelationsSelectionChange;\n    TabOrder := 0;\n    Top := 73;\n    Width := 242\n  end;\n  ListBoxFields := TListBox.Create(self);\n  with ListBoxFields do\n  begin\n    Parent := Panel1;\n    Align := alBottom;\n    Anchors := [akLeft,akRight,akBottom];\n    Height := 262;\n    ItemHeight := 13;\n    Left := 1;\n    MultiSelect := True;\n    TabOrder := 1;\n    Top := 280;\n    Width := 242;\n  end;\n  Panel3 := TPanel.Create(self);\n  with Panel3 do\n  begin\n    Parent := Panel1;\n    Align := alTop;\n    Anchors := [akTop,akLeft,akRight,akBottom];\n    BevelOuter := bvNone;\n    FullRepaint := False;\n    Height := 72;\n    Left := 1;\n    TabOrder := 2;\n    TabStop := False;\n    Top := 1;\n    Width := 242;\n  end;\n  edtAlias := TEdit.Create(self);\n  with edtAlias do\n  begin\n    Parent := Panel3;\n    Anchors := [akTop,akLeft];\n    Height := 21;\n    Left := 80;\n    TabOrder := 0;\n    Top := 8;\n    Width := 153;\n  end;\n  lblAlias := TLabel.Create(self);\n  with lblAlias do\n  begin\n    Parent := Panel3;\n    Anchors := [akTop, akLeft];\n    Caption := STableAlias;\n    FocusControl := edtAlias;\n    Height := 13;\n    Left := 8;\n    Top := 16;\n    Width := 68;\n  end;\n  chkReplace := TCheckBox.Create(self);\n  with chkReplace do\n  begin\n    Parent := Panel3;\n    Anchors := [akTop,akLeft];\n    Caption := SReplaceSQL;\n    Checked := True;\n    Height := 17;\n    Left := 8;\n    TabOrder := 1;\n    TabStop := True;\n    Top := 40;\n    Width := 97;\n  end;\n  edtSelect := TMemo.Create(self);\n  with edtSelect do\n  begin\n    Parent := tbsSelect;\n    Align := alClient;\n    Anchors := [akTop,akLeft,akRight,akBottom];\n    Font.Height := -14;\n    {$IFDEF MSWINDOWS}\n    Font.Name := 'Courier New';\n    {$ENDIF}\n    Font.Pitch := fpFixed;\n    Height := 513;\n    Left := 0;\n    PopupMenu := PopupMenu1;\n    TabOrder := 0;\n    TabStop := True;\n    Top := 0;\n    Width := 513;\n  end;\n  //{$IFDEF USE_SYNEDIT}\n  //with SynSQLSyn1 do\n  //begin\n    //TableNameAttri.Background:=clWindow;\n    //TableNameAttri.Foreground:=clGreen;\n    //TableNameAttri.Style:=[fsUnderline];\n    //with ADS.Connection do\n      //if (strpos(PChar(Protocol),'firebird') <> nil) or\n        //(strpos(PChar(Protocol),'interbase') <> nil) then\n      //begin\n        //SQLDialect:=sqlInterbase6;\n      //end\n      //else if Protocol = 'mssql' then\n      //begin\n        //SQLDialect:=sqlMSSQL2K;\n      //end\n      //else if (strpos(PChar(Protocol),'mysql') <> nil) then\n      //begin\n        //SQLDialect:=sqlMySQL;\n      //end\n      //else if (strpos(PChar(Protocol),'postgresql') <> nil) then\n      //begin\n        //SQLDialect:=sqlStandard;\n      //end\n      //else if Protocol = 'sybase' then\n      //begin\n        //SQLDialect:=sqlSybase;\n      //end;\n    //DefaultFilter:=SQLDefaultFilter;\n  //end;\n  //{$IFDEF FPC}\n  //SynCompletion:=TSynCompletion.Create(Self);\n  //{$ELSE}\n  //SynCompletion:=TSynCompletionProposal.Create(Self);\n  //{$ENDIF}\n  //with SynCompletion do begin\n    //AddEditor(edtSelect);\n    //ItemList.Clear;\n    //OnCodeCompletion:=ccComplete;\n    //OnExecute:=ccExecute;\n  //end;\n  //{$ENDIF}\n  FSaveConnected := True;\n  FDS:=ADS;\n  if Assigned(FDS) then\n  begin\n    if not FDS.Connection.Connected then\n    begin\n      FSaveConnected := False;\n      FDS.Connection.Connected := True;\n    end;\n    edtSelect.Lines.Text:=FDS.SQL.Text;\n    LoadTableList;\n    FillIdentifier;\n  end;\n\nend;\n\nprocedure TZQuerySQLEditorForm.FillIdentifier;\nvar\n  i:integer;\nbegin\n  //{$IFDEF USE_SYNEDIT}\n  //SynSQLSyn1.TableNames.Clear;\n  //for i:=0 to ListBoxRelations.Items.Count-1 do\n  //begin\n    //SynSQLSyn1.TableNames.Add(ListBoxRelations.Items[i]);\n  //end;\n  //{$ENDIF}\nend;\n\nprocedure TZQuerySQLEditorForm.FormClose(Sender: TObject;\n  var Action: TCloseAction);\nbegin\n  if (ModalResult=mrOk) and Assigned(FDS) then\n  begin\n    FDS.SQL.Text:=edtSelect.Lines.Text;\n  end;\nend;\n\nprocedure TZQuerySQLEditorForm.LoadTableList;\nvar\n  Metadata: IZDatabaseMetadata;\n  TableTypes: TStringDynArray;\nbegin\n  if Assigned(FDS.Connection) and FDS.Connection.Connected then\n  begin\n    Metadata := FDS.Connection.DbcConnection.GetMetadata;\n    SetLength(TableTypes, 2);\n    TableTypes[0] := 'TABLE';\n    TableTypes[1] := 'VIEW';\n    FDS.Connection.ShowSQLHourGlass;\n    ListBoxRelations.Items.Clear;\n    with Metadata.GetTables(FDS.Connection.Catalog, '', '', TableTypes) do\n    try\n      while Next do\n        if ListBoxRelations.Items.IndexOf(trim(GetString(3))) = -1 then\n          ListBoxRelations.Items.Add(trim(GetString(3)));\n    finally\n      Close;\n    end;\n    FDS.Connection.HideSQLHourGlass;\n  end;\nend;\n\nfunction TZQuerySQLEditorForm.ActiveEditor:TMemo;\n//function TZQuerySQLEditorForm.ActiveEditor:\n  //{$IFDEF USE_SYNEDIT}TSynEdit{$ELSE}TMemo{$ENDIF};\nbegin\n  case PageControl1.ActivePageIndex of\n    0:Result:=edtSelect;\n  end;\nend;\n\nprocedure TZQuerySQLEditorForm.ListBoxRelationsDblClick(\n  Sender: TObject);\nvar\n  i:integer;\n  Als, FieldsStr:string;\nbegin\n  if ActiveEditor<>nil then\n  with ActiveEditor do\n  begin\n    if chkReplace.Checked then Lines.Clear;\n    if ListBoxFields.SelCount=0 then\n    begin\n      Lines.Add('select');\n      Lines.Add('  *');\n      Lines.Add('from');\n      Lines.Add('  '+ListBoxRelations.Items[ListBoxRelations.ItemIndex]+' '+edtAlias.Text);\n    end\n    else\n    begin\n      Lines.Add('select');\n      if edtAlias.Text<>'' then Als:=edtAlias.Text\n      else Als:=ListBoxRelations.Items[ListBoxRelations.ItemIndex];\n      FieldsStr:='';\n      for i:=0 to ListBoxFields.Items.Count-1 do\n      begin\n        if ListBoxFields.Selected[i] then\n        begin\n         if FieldsStr<>'' then\n           Lines.Add(FieldsStr+',');\n         FieldsStr:='  '+Als+'.'+ListBoxFields.Items[i];\n        end;\n      end;\n      if FieldsStr<>'' then Lines.Add(FieldsStr);\n      Lines.Add('from');\n      Lines.Add('  '+ListBoxRelations.Items[ListBoxRelations.ItemIndex]+' '+edtAlias.Text);\n    end;\n  end;\nend;\n\nprocedure TZQuerySQLEditorForm.ListBoxRelationsSelectionChange(Sender: TObject;\n  User: boolean);\nvar\n  Metadata: IZDatabaseMetadata;\n  TPName: string;\n  StrEsc: string;\nbegin\n  if Assigned(FDS.Connection) and FDS.Connection.Connected then\n  begin\n    FDS.Connection.ShowSQLHourGlass;\n    Metadata := FDS.Connection.DbcConnection.GetMetadata;\n    with ListBoxFields do begin\n      ItemIndex := -1;\n      Items.BeginUpdate;\n      Items.Clear;\n      Items.EndUpdate;\n    end;\n    if ListBoxRelations.ItemIndex >= 0 then\n    begin\n      TPName := ListBoxRelations.Items[ListBoxRelations.ItemIndex];\n      with Metadata.GetColumns(FDS.Connection.Catalog,'', TPName,'') do\n      try\n        while Next do\n          if ListBoxFields.Items.IndexOf(GetStringByName('COLUMN_NAME')) = -1 then\n            ListBoxFields.Items.Add(GetStringByName('COLUMN_NAME'));\n      finally\n        Close;\n      end;\n    end;\n    FDS.Connection.HideSQLHourGlass;\n  end;\nend;\n\nprocedure TZQuerySQLEditorForm.PageControl1Change(Sender: TObject);\nbegin\n  case PageControl1.ActivePageIndex of\n    0:edtSelect.SetFocus;\n  end;\nend;\n\nprocedure TZQuerySQLEditorForm.ZeosQuerySQLEditorDestroy(Sender: TObject);\nbegin\n  if not FSaveConnected then\n    FDS.Connection.Connected := False;\nend;\n\nprocedure TZQuerySQLEditorForm.btnGenerateClick(Sender: TObject);\nbegin\n  ListBoxRelationsDblClick(nil);\nend;\n\nprocedure TZQuerySQLEditorForm.btnTestClick(Sender: TObject);\nbegin\n  if Assigned(FDS.Connection) and FDS.Connection.Connected then\n  begin\n    ZeosSQLEditorTestForm:=TZeosSQLEditorTestForm.Create(Application);\n    with ZeosSQLEditorTestForm do\n    begin\n      try\n        ZeosSQL.Connection:=FDS.Connection;\n        ZeosSQL.SQL.Text:=ActiveEditor.Lines.Text;\n        ZeosSQL.Active := true;\n        ShowModal\n      except\n        on E:Exception do\n          ShowMessage(E.Message);\n      end;\n      Free;\n    end;\n  end;\nend;\n\nprocedure TZQuerySQLEditorForm.mnuLoadClick(Sender: TObject);\nbegin\n  if (dlgOpen.Execute) then\n    ActiveEditor.Lines.LoadFromFile(dlgOpen.FileName);\nend;\n\nprocedure TZQuerySQLEditorForm.mnuSaveClick(Sender: TObject);\nbegin\n  if dlgSave.Execute then\n    ActiveEditor.Lines.SaveToFile(dlgSave.FileName);\nend;\n\n//{$IFDEF USE_SYNEDIT}\n//procedure TZQuerySQLEditorForm.ccComplete\n//{$IFDEF FPC}\n//(var Value: ansistring;\n  //Shift: TShiftState)\n//{$ELSE}\n//(Sender: TObject; var Value: string;\n      //Shift: TShiftState; Index: Integer; EndToken: Char)\n//{$ENDIF}\n//;\n//begin\n//end;\n\n//procedure TZQuerySQLEditorForm.ccExecute\n//{$IFDEF FPC}\n//(Sender: TObject)\n//{$ELSE}\n//(Kind: SynCompletionType; Sender: TObject;\n      //var CurrentInput: string; var x, y: Integer; var CanExecute: Boolean)\n//{$ENDIF}\n//;\n//function GetCurWord:string;\n//var\n  //S:string;\n  //i,j:integer;\n//begin\n  //Result:='';\n  //with ActiveEditor do\n  //begin\n    //S:=Trim(Copy(LineText, 1, CaretX));\n    //I:=Length(S);\n    //while (i>0) and (S[i]<>'.') do Dec(I);\n    //if (I>0) then\n    //begin\n      //J:=i-1;\n      ////Get table name\n      //while (j>0) and CharInSet(S[j], ['A'..'z','\"']) do Dec(j);\n      //Result:=trim(Copy(S, j+1, i-j-1));\n    //end;\n  //end;\n//end;\n//var\n  //S:string;\n  //Metadata: IZDatabaseMetadata;\n  //StrEsc: string;\n//begin\n  //S:=AnsiUpperCase(GetCurWord);\n  //if S<>'' then\n  //begin\n    //if Assigned(FDS.Connection) and FDS.Connection.Connected then\n    //begin\n      //FDS.Connection.ShowSQLHourGlass;\n      //Metadata := FDS.Connection.DbcConnection.GetMetadata;\n      //SynCompletion.ItemList.Clear;\n      //{$IFDEF FPC}\n      //SynCompletion.OnPaintItem;\n      //{$ELSE}\n      //{$ENDIF}\n      //with Metadata.GetColumns(FDS.Connection.Catalog,'',S,'') do\n      //try\n        //while Next do\n        //if SynCompletion.ItemList.IndexOf(GetStringByName('COLUMN_NAME')) = -1 then\n          //SynCompletion.ItemList.Add(GetStringByName('COLUMN_NAME'));\n      //finally\n        //Close;\n      //end;\n      //FDS.Connection.HideSQLHourGlass;\n    //end;\n  //end;\n//end;\n//{$ENDIF}\n\nend.\n\n"
  },
  {
    "path": "lib/zeosdbo/src/component/ZROSqlEditor.pas",
    "content": "{*********************************************************}\n{                                                         }\n{                 Zeos Database Objects                   }\n{                 SQL Monitor component                   }\n{                                                         }\n{        Originally written by Sergey Seroukhov           }\n{                                                         }\n{*********************************************************}\n\n{@********************************************************}\n{    Copyright (c) 1999-2012 Zeos Development Group       }\n{                                                         }\n{ License Agreement:                                      }\n{                                                         }\n{ This library is distributed in the hope that it will be }\n{ useful, but WITHOUT ANY WARRANTY; without even the      }\n{ implied warranty of MERCHANTABILITY or FITNESS FOR      }\n{ A PARTICULAR PURPOSE.  See the GNU Lesser General       }\n{ Public License for more details.                        }\n{                                                         }\n{ The source code of the ZEOS Libraries and packages are  }\n{ distributed under the Library GNU General Public        }\n{ License (see the file COPYING / COPYING.ZEOS)           }\n{ with the following  modification:                       }\n{ As a special exception, the copyright holders of this   }\n{ library give you permission to link this library with   }\n{ independent modules to produce an executable,           }\n{ regardless of the license terms of these independent    }\n{ modules, and to copy and distribute the resulting       }\n{ executable under terms of your choice, provided that    }\n{ you also meet, for each linked independent module,      }\n{ the terms and conditions of the license of that module. }\n{ An independent module is a module which is not derived  }\n{ from or based on this library. If you modify this       }\n{ library, you may extend this exception to your version  }\n{ of the library, but you are not obligated to do so.     }\n{ If you do not wish to do so, delete this exception      }\n{ statement from your version.                            }\n{                                                         }\n{                                                         }\n{ The project web site is located on:                     }\n{   http://zeos.firmos.at  (FORUM)                        }\n{   http://sourceforge.net/p/zeoslib/tickets/ (BUGTRACKER)}\n{   svn://svn.code.sf.net/p/zeoslib/code-0/trunk (SVN)    }\n{                                                         }\n{   http://www.sourceforge.net/projects/zeoslib.          }\n{                                                         }\n{                                                         }\n{                                 Zeos Development Group. }\n{********************************************************@}\n\nunit ZROSqlEditor;\n\n{$I ZComponent.inc}\n\ninterface\n\nuses\n{$IFDEF MSWINDOWS} // 64-bit too\n  Windows, Messages,\n{$ENDIF}\n  {$IFDEF FPC}\n  LCLIntf,\n  {$ENDIF}\n  SysUtils, Classes, Graphics, Controls, Forms, Dialogs, Graphtype,\n  StdCtrls, ExtCtrls, ComCtrls, Buttons, ZDataset, Menus, ZMessages;\n  //{$IFDEF USE_SYNEDIT}\n  //, SynEdit, SynEditHighlighter, SynHighlighterSQL\n  //{$IFDEF FPC}\n  //, SynCompletion\n  //{$ELSE}\n  //, SynCompletionProposal\n  //{$ENDIF}\n  //{$ENDIF};\n\ntype\n\n  { TZROSQLEditorForm }\n\n  TZROSQLEditorForm = class(TForm)\n  private\n    mnuSave: TMenuItem;\n    mnuLoad: TMenuItem;\n    dlgOpen: TOpenDialog;\n    PopupMenu1: TPopupMenu;\n    dlgSave: TSaveDialog;\n    btnOk: TBitBtn;\n    btnCancel: TBitBtn;\n    Panel2: TPanel;\n    tbsSelect: TTabSheet;\n    Panel1: TPanel;\n    Splitter2: TSplitter;\n    ListBoxRelations: TListBox;\n    ListBoxFields: TListBox;\n    Splitter1: TSplitter;\n    Panel3: TPanel;\n    lblAlias: TLabel;\n    edtAlias: TEdit;\n    btnGenerate: TButton;\n    btnCheck: TButton;\n    chkReplace: TCheckBox;\n    btnTest: TButton;\n    edtSelect: TMemo;\n    //{$IFDEF USE_SYNEDIT}\n    //edtSelect: TSynEdit;\n    //SynSQLSyn1: TSynSQLSyn;\n    //{$IFDEF FPC}\n    //SynCompletion:TSynCompletion;\n    //{$ELSE}\n    //SynCompletion:TSynCompletionProposal;\n    //{$ENDIF}\n    //{$ELSE}\n    //edtSelect: TMemo;\n    //{$ENDIF}\n    FDS: TZReadOnlyQuery;\n    FSaveConnected: Boolean;\n    procedure FormClose(Sender: TObject; var Action: TCloseAction);\n    procedure ListBoxRelationsDblClick(Sender: TObject);\n    procedure ListBoxRelationsSelectionChange(Sender: TObject; User: boolean);\n    procedure PageControl1Change(Sender: TObject);\n    procedure ZeosROSQLEditorDestroy(Sender: TObject);\n    procedure btnGenerateClick(Sender: TObject);\n    procedure btnTestClick(Sender: TObject);\n    procedure mnuLoadClick(Sender: TObject);\n    procedure mnuSaveClick(Sender: TObject);\n    procedure LoadTableList;\n    procedure FillIdentifier;\n    function ActiveEditor:TMemo;\n    //function ActiveEditor:{$IFDEF USE_SYNEDIT} TSynEdit {$ELSE} TMemo {$ENDIF};\n    //{$IFDEF USE_SYNEDIT}\n    //{$IFDEF FPC}\n    //procedure ccComplete(var Value: ansistring; Shift: TShiftState);\n    //procedure ccExecute(Sender: TObject);\n    //{$ELSE}\n    //procedure ccComplete(Sender: TObject; var Value: string;\n      //Shift: TShiftState; Index: Integer; EndToken: Char);\n    //procedure ccExecute(Kind: SynCompletionType; Sender: TObject;\n      //var CurrentInput: string; var x, y: Integer; var CanExecute: Boolean);\n    //{$ENDIF}\n    //{$ENDIF}\n  public\n    PageControl1: TPageControl;\n    constructor CreateEditor(ADS:TZReadOnlyQuery);\n  end;\n\nvar\n  ZeosROSQLEditorForm: TZROSQLEditorForm;\n\nimplementation\nuses\n  ZSqlTestForm, ZDbcIntfs, ZCompatibility;\n\nconst\n  SQLDefaultFilter = 'SQL files (*.sql)|*.sql';\n  \n{ TZeosROSQLEditor }\n\nconstructor TZROSQLEditorForm.CreateEditor(ADS: TZReadOnlyQuery);\nbegin\n  inherited CreateNew(Application,0);\n\n  Height := 613;\n  Left := 315;\n  Top := 142;\n  TextHeight := 13;\n  Width := 768;\n  Position := poDesktopCenter;\n  Caption := sFormEditor;\n  OnClose := FormClose;\n  OnDestroy := ZeosROSQLEditorDestroy;\n  btnOk := TBitBtn.Create(self);\n  with btnOk do\n  begin\n    Parent := self;\n    Anchors := [akRight, akBottom];\n    Default := True;\n    Height := 25;\n    Kind := bkOk;\n    Left := 593;\n    ModalResult := mrOk;\n    TabOrder := 3;\n    TabStop := True;\n    Top := 552;\n    Width := 75;\n    Caption := SButtonOk;\n  end;\n  btnCancel := TBitBtn.Create(self);\n  with btnCancel do\n  begin\n    Parent := self;\n    Anchors := [akRight, akBottom];\n    Default := True;\n    Height := 25;\n    Kind := bkCancel;\n    Left := 677;\n    ModalResult := mrCancel;\n    TabOrder := 4;\n    TabStop := True;\n    Top := 552;\n    Width := 75;\n    Caption := SButtonCancel;\n  end;\n  btnGenerate := TButton.Create(self);\n  with btnGenerate do\n  begin\n    Parent := self;\n    Anchors := [akLeft,akBottom];\n    Caption := SButtonGenerate;\n    Height := 25;\n    Left := 8;\n    OnClick := btnGenerateClick;\n    TabOrder := 0;\n    TabStop := True;\n    Top := 552;\n    Width := 75;\n  end;\n  btnCheck := TButton.Create(self);\n  with btnCheck do\n  begin\n    Parent := self;\n    Anchors := [akLeft,akBottom];\n    Caption := SButtonCheck;\n    Enabled := False;\n    Height := 25;\n    Left := 88;\n    TabOrder := 1;\n    TabStop := True;\n    Top := 552;\n    Visible := False;\n    Width := 75;\n  end;\n  btnTest := TButton.Create(self);\n  with btnTest do\n  begin\n    Parent := self;\n    Anchors := [akLeft,akBottom];\n    Caption := SButtonTest;\n    Height := 25;\n    Left := 168;\n    OnClick := btnTestClick;\n    TabOrder := 2;\n    TabStop := True;\n    Top := 552;\n    Width := 75;\n  end;\n  dlgOpen := TOpenDialog.Create(self);\n  with dlgOpen do\n  begin\n    FilterIndex :=0;\n    Options := [ofEnableSizing,ofViewDetail];\n    Title := SDialogOpenTitle;\n    Filter := SQLDefaultFilter;\n  end;\n  dlgSave := TSaveDialog.Create(self);\n  with dlgSave do\n  begin\n    FilterIndex :=0;\n    Options := [ofEnableSizing,ofViewDetail];\n    Title := SDialogSaveTitle;\n    Filter := SQLDefaultFilter;\n  end;\n  mnuLoad := TMenuItem.Create(self);\n  with mnuLoad do\n  begin\n    Caption := SMenuLoad;\n    OnClick := mnuLoadClick;\n  end;\n  mnuSave := TMenuItem.Create(self);\n  with mnuSave do\n  begin\n    Caption := SMenuSave;\n    OnClick := mnuSaveClick;\n  end;\n  PopupMenu1 := TPopupMenu.Create(self);\n  with PopupMenu1 do\n  begin\n    AutoPopup := true;\n    Items.Add(mnuLoad);\n    Items.Add(mnuSave);\n  end;\n  Panel2 := TPanel.Create(self);\n  with Panel2 do\n  begin\n    Parent := self;\n    Align := alTop;\n    Anchors := [akTop,akLeft,akRight,akBottom];\n    FullRepaint := False;\n    Height := 545;\n    Left := 0;\n    TabOrder := 5;\n    TabStop := False;\n    Top := 0;\n    Width := 768;\n  end;\n  Splitter1 := TSplitter.Create(self);\n  with Splitter1 do\n  begin\n    Parent := Panel2;\n    Align := alRight;\n    Anchors := [akTop,akRight,akBottom];\n    Height := 543;\n    Left := 518;\n    Top := 1;\n    Width := 5;\n  end;\n  PageControl1 := TPageControl.Create(self);\n  with PageControl1 do\n  begin\n    Parent := Panel2;\n    Align := alClient;\n    Anchors := [akTop,akLeft,akRight,akBottom];\n    Height := 543;\n    Left := 1;\n    OnChange := PageControl1Change;\n    TabIndex := 0;\n    TabOrder := 0;\n    TabPosition := tpTop;\n    TabStop := True;\n    Top := 1;\n    Width := 517;\n  end;\n  tbsSelect := TTabSheet.Create(self);\n  with tbsSelect do\n  begin\n    Parent := PageControl1;\n    Caption := STabSheetSelect;\n    Height := 513;\n    Left := 2;\n    Top := 28;\n    Width := 513;\n  end;\n  Panel1 := TPanel.Create(self);\n  with Panel1 do\n  begin\n    Parent := Panel2;\n    Align := alRight;\n    Anchors := [akTop,akRight,akBottom];\n    FullRepaint := false;\n    Height := 543;\n    Left := 523;\n    TabOrder := 1;\n    TabStop := False;\n    Top := 1;\n    Width := 244;\n  end;\n  Splitter2 := TSplitter.Create(self);\n  with Splitter2 do\n  begin\n    Parent := Panel1;\n    Align := alBottom;\n    Anchors := [akLeft,akRight,akBottom];\n    Cursor := crVSplit;\n    Height := 9;\n    Left := 1;\n    Top := 271;\n    Width := 242;\n  end;\n  ListBoxRelations := TListBox.Create(self);\n  with ListBoxRelations do\n  begin\n    Parent := Panel1;\n    Align := alClient;\n    Anchors := [akTop,akLeft,akRight,akBottom];\n    Height := 198;\n    ItemHeight := 13;\n    Left := 1;\n    OnDblClick := ListBoxRelationsDblClick;\n    OnSelectionChange := ListBoxRelationsSelectionChange;\n    TabOrder := 0;\n    Top := 73;\n    Width := 242\n  end;\n  ListBoxFields := TListBox.Create(self);\n  with ListBoxFields do\n  begin\n    Parent := Panel1;\n    Align := alBottom;\n    Anchors := [akLeft,akRight,akBottom];\n    Height := 262;\n    ItemHeight := 13;\n    Left := 1;\n    MultiSelect := True;\n    TabOrder := 1;\n    Top := 280;\n    Width := 242;\n  end;\n  Panel3 := TPanel.Create(self);\n  with Panel3 do\n  begin\n    Parent := Panel1;\n    Align := alTop;\n    Anchors := [akTop,akLeft,akRight,akBottom];\n    BevelOuter := bvNone;\n    FullRepaint := False;\n    Height := 72;\n    Left := 1;\n    TabOrder := 2;\n    TabStop := False;\n    Top := 1;\n    Width := 242;\n  end;\n  edtAlias := TEdit.Create(self);\n  with edtAlias do\n  begin\n    Parent := Panel3;\n    Anchors := [akTop,akLeft];\n    Height := 21;\n    Left := 80;\n    TabOrder := 0;\n    Top := 8;\n    Width := 153;\n  end;\n  lblAlias := TLabel.Create(self);\n  with lblAlias do\n  begin\n    Parent := Panel3;\n    Anchors := [akTop, akLeft];\n    Caption := STableAlias;\n    FocusControl := edtAlias;\n    Height := 13;\n    Left := 8;\n    Top := 16;\n    Width := 68;\n  end;\n  chkReplace := TCheckBox.Create(self);\n  with chkReplace do\n  begin\n    Parent := Panel3;\n    Anchors := [akTop,akLeft];\n    Caption := SReplaceSQL;\n    Checked := True;\n    Height := 17;\n    Left := 8;\n    TabOrder := 1;\n    TabStop := True;\n    Top := 40;\n    Width := 97;\n  end;\n  edtSelect := TMemo.Create(self);\n  with edtSelect do\n  begin\n    Parent := tbsSelect;\n    Align := alClient;\n    Anchors := [akTop,akLeft,akRight,akBottom];\n    Font.Height := -14;\n    {$IFDEF MSWINDOWS}\n    Font.Name := 'Courier New';\n    {$ENDIF}\n    Font.Pitch := fpFixed;\n    Height := 513;\n    Left := 0;\n    PopupMenu := PopupMenu1;\n    TabOrder := 0;\n    TabStop := True;\n    Top := 0;\n    Width := 513;\n  end;\n  //{$IFDEF USE_SYNEDIT}\n  //with SynSQLSyn1 do\n  //begin\n    //TableNameAttri.Background:=clWindow;\n    //TableNameAttri.Foreground:=clGreen;\n    //TableNameAttri.Style:=[fsUnderline];\n    //with ADS.Connection do\n      //if (strpos(PChar(Protocol),'firebird') <> nil) or\n        //(strpos(PChar(Protocol),'interbase') <> nil) then\n      //begin\n        //SQLDialect:=sqlInterbase6;\n      //end\n      //else if Protocol = 'mssql' then\n      //begin\n        //SQLDialect:=sqlMSSQL2K;\n      //end\n      //else if (strpos(PChar(Protocol),'mysql') <> nil) then\n      //begin\n        //SQLDialect:=sqlMySQL;\n      //end\n      //else if (strpos(PChar(Protocol),'postgresql') <> nil) then\n      //begin\n        //SQLDialect:=sqlStandard;\n      //end\n      //else if Protocol = 'sybase' then\n      //begin\n        //SQLDialect:=sqlSybase;\n      //end;\n    //DefaultFilter:=SQLDefaultFilter;\n  //end;\n  //{$IFDEF FPC}\n  //SynCompletion:=TSynCompletion.Create(Self);\n  //{$ELSE}\n  //SynCompletion:=TSynCompletionProposal.Create(Self);\n  //{$ENDIF}\n  //with SynCompletion do begin\n    //AddEditor(edtSelect);\n    //ItemList.Clear;\n    //OnCodeCompletion:=ccComplete;\n    //OnExecute:=ccExecute;\n  //end;\n  //{$ENDIF}\n  FSaveConnected := True;\n  FDS:=ADS;\n  if Assigned(FDS) then\n  begin\n    if not FDS.Connection.Connected then\n    begin\n      FSaveConnected := False;\n      FDS.Connection.Connected := True;\n    end;\n    edtSelect.Lines.Text:=FDS.SQL.Text;\n    LoadTableList;\n    FillIdentifier;\n  end;\n\nend;\n\nprocedure TZROSQLEditorForm.FillIdentifier;\nvar\n  i:integer;\nbegin\n  //{$IFDEF USE_SYNEDIT}\n  //SynSQLSyn1.TableNames.Clear;\n  //for i:=0 to ListBoxRelations.Items.Count-1 do\n  //begin\n    //SynSQLSyn1.TableNames.Add(ListBoxRelations.Items[i]);\n  //end;\n  //{$ENDIF}\nend;\n\nprocedure TZROSQLEditorForm.FormClose(Sender: TObject;\n  var Action: TCloseAction);\nbegin\n  if (ModalResult=mrOk) and Assigned(FDS) then\n  begin\n    FDS.SQL.Text:=edtSelect.Lines.Text;\n  end;\nend;\n\nprocedure TZROSQLEditorForm.LoadTableList;\nvar\n  Metadata: IZDatabaseMetadata;\n  TableTypes: TStringDynArray;\nbegin\n  if Assigned(FDS.Connection) and FDS.Connection.Connected then\n  begin\n    Metadata := FDS.Connection.DbcConnection.GetMetadata;\n    SetLength(TableTypes, 2);\n    TableTypes[0] := 'TABLE';\n    TableTypes[1] := 'VIEW';\n    FDS.Connection.ShowSQLHourGlass;\n    ListBoxRelations.Items.Clear;\n    with Metadata.GetTables(FDS.Connection.Catalog, '', '', TableTypes) do\n    try\n      while Next do\n        if ListBoxRelations.Items.IndexOf(trim(GetString(3))) = -1 then\n          ListBoxRelations.Items.Add(trim(GetString(3)));\n    finally\n      Close;\n    end;\n    FDS.Connection.HideSQLHourGlass;\n  end;\nend;\n\nfunction TZROSQLEditorForm.ActiveEditor:TMemo;\n//function TZROSQLEditorForm.ActiveEditor:\n  //{$IFDEF USE_SYNEDIT}TSynEdit{$ELSE}TMemo{$ENDIF};\nbegin\n  case PageControl1.ActivePageIndex of\n    0:Result:=edtSelect;\n  end;\nend;\n\nprocedure TZROSQLEditorForm.ListBoxRelationsDblClick(\n  Sender: TObject);\nvar\n  i:integer;\n  Als, FieldsStr:string;\nbegin\n  if ActiveEditor<>nil then\n  with ActiveEditor do\n  begin\n    if chkReplace.Checked then Lines.Clear;\n    if ListBoxFields.SelCount=0 then\n    begin\n      Lines.Add('select');\n      Lines.Add('  *');\n      Lines.Add('from');\n      Lines.Add('  '+ListBoxRelations.Items[ListBoxRelations.ItemIndex]+' '+edtAlias.Text);\n    end\n    else\n    begin\n      Lines.Add('select');\n      if edtAlias.Text<>'' then Als:=edtAlias.Text\n      else Als:=ListBoxRelations.Items[ListBoxRelations.ItemIndex];\n      FieldsStr:='';\n      for i:=0 to ListBoxFields.Items.Count-1 do\n      begin\n        if ListBoxFields.Selected[i] then\n        begin\n         if FieldsStr<>'' then\n           Lines.Add(FieldsStr+',');\n         FieldsStr:='  '+Als+'.'+ListBoxFields.Items[i];\n        end;\n      end;\n      if FieldsStr<>'' then Lines.Add(FieldsStr);\n      Lines.Add('from');\n      Lines.Add('  '+ListBoxRelations.Items[ListBoxRelations.ItemIndex]+' '+edtAlias.Text);\n    end;\n  end;\nend;\n\nprocedure TZROSQLEditorForm.ListBoxRelationsSelectionChange(Sender: TObject;\n  User: boolean);\nvar\n  Metadata: IZDatabaseMetadata;\n  TPName: string;\n  StrEsc: string;\nbegin\n  if Assigned(FDS.Connection) and FDS.Connection.Connected then\n  begin\n    FDS.Connection.ShowSQLHourGlass;\n    Metadata := FDS.Connection.DbcConnection.GetMetadata;\n    with ListBoxFields do begin\n      ItemIndex := -1;\n      Items.BeginUpdate;\n      Items.Clear;\n      Items.EndUpdate;\n    end;\n    if ListBoxRelations.ItemIndex >= 0 then\n    begin\n      TPName := ListBoxRelations.Items[ListBoxRelations.ItemIndex];\n      with Metadata.GetColumns(FDS.Connection.Catalog,'', TPName,'') do\n      try\n        while Next do\n          if ListBoxFields.Items.IndexOf(GetStringByName('COLUMN_NAME')) = -1 then\n            ListBoxFields.Items.Add(GetStringByName('COLUMN_NAME'));\n      finally\n        Close;\n      end;\n    end;\n    FDS.Connection.HideSQLHourGlass;\n  end;\nend;\n\nprocedure TZROSQLEditorForm.PageControl1Change(Sender: TObject);\nbegin\n  case PageControl1.ActivePageIndex of\n    0:edtSelect.SetFocus;\n  end;\nend;\n\nprocedure TZROSQLEditorForm.ZeosROSQLEditorDestroy(Sender: TObject);\nbegin\n  if not FSaveConnected then\n    FDS.Connection.Connected := False;\nend;\n\nprocedure TZROSQLEditorForm.btnGenerateClick(Sender: TObject);\nbegin\n  ListBoxRelationsDblClick(nil);\nend;\n\nprocedure TZROSQLEditorForm.btnTestClick(Sender: TObject);\nbegin\n  if Assigned(FDS.Connection) and FDS.Connection.Connected then\n  begin\n    ZeosSQLEditorTestForm:=TZeosSQLEditorTestForm.Create(Application);\n    with ZeosSQLEditorTestForm do\n    begin\n      try\n        ZeosSQL.Connection:=FDS.Connection;\n        ZeosSQL.SQL.Text:=ActiveEditor.Lines.Text;\n        ZeosSQL.Active := true;\n        ShowModal\n      except\n        on E:Exception do\n          ShowMessage(E.Message);\n      end;\n      Free;\n    end;\n  end;\nend;\n\nprocedure TZROSQLEditorForm.mnuLoadClick(Sender: TObject);\nbegin\n  if (dlgOpen.Execute) then\n    ActiveEditor.Lines.LoadFromFile(dlgOpen.FileName);\nend;\n\nprocedure TZROSQLEditorForm.mnuSaveClick(Sender: TObject);\nbegin\n  if dlgSave.Execute then\n    ActiveEditor.Lines.SaveToFile(dlgSave.FileName);\nend;\n\n//{$IFDEF USE_SYNEDIT}\n//procedure TZROSQLEditorForm.ccComplete\n//{$IFDEF FPC}\n//(var Value: ansistring;\n  //Shift: TShiftState)\n//{$ELSE}\n//(Sender: TObject; var Value: string;\n      //Shift: TShiftState; Index: Integer; EndToken: Char)\n//{$ENDIF}\n//;\n//begin\n//end;\n\n//procedure TZROSQLEditorForm.ccExecute\n//{$IFDEF FPC}\n//(Sender: TObject)\n//{$ELSE}\n//(Kind: SynCompletionType; Sender: TObject;\n      //var CurrentInput: string; var x, y: Integer; var CanExecute: Boolean)\n//{$ENDIF}\n//;\n//function GetCurWord:string;\n//var\n  //S:string;\n  //i,j:integer;\n//begin\n  //Result:='';\n  //with ActiveEditor do\n  //begin\n    //S:=Trim(Copy(LineText, 1, CaretX));\n    //I:=Length(S);\n    //while (i>0) and (S[i]<>'.') do Dec(I);\n    //if (I>0) then\n    //begin\n      //J:=i-1;\n      ////Get table name\n      //while (j>0) and CharInSet(S[j], ['A'..'z','\"']) do Dec(j);\n      //Result:=trim(Copy(S, j+1, i-j-1));\n    //end;\n  //end;\n//end;\n//var\n  //S:string;\n  //Metadata: IZDatabaseMetadata;\n  //StrEsc: string;\n//begin\n  //S:=AnsiUpperCase(GetCurWord);\n  //if S<>'' then\n  //begin\n    //if Assigned(FDS.Connection) and FDS.Connection.Connected then\n    //begin\n      //FDS.Connection.ShowSQLHourGlass;\n      //Metadata := FDS.Connection.DbcConnection.GetMetadata;\n      //SynCompletion.ItemList.Clear;\n      //{$IFDEF FPC}\n      //SynCompletion.OnPaintItem;\n      //{$ELSE}\n      //{$ENDIF}\n      //with Metadata.GetColumns(FDS.Connection.Catalog,'',S,'') do\n      //try\n        //while Next do\n        //if SynCompletion.ItemList.IndexOf(GetStringByName('COLUMN_NAME')) = -1 then\n          //SynCompletion.ItemList.Add(GetStringByName('COLUMN_NAME'));\n      //finally\n        //Close;\n      //end;\n      //FDS.Connection.HideSQLHourGlass;\n    //end;\n  //end;\n//end;\n//{$ENDIF}\n\nend.\n\n"
  },
  {
    "path": "lib/zeosdbo/src/component/ZSequence.pas",
    "content": "{*********************************************************}\n{                                                         }\n{                 Zeos Database Objects                   }\n{              Database Sequence Component                }\n{                                                         }\n{        Originally written by Stefan Glienke             }\n{                                                         }\n{*********************************************************}\n\n{@********************************************************}\n{    Copyright (c) 1999-2012 Zeos Development Group       }\n{                                                         }\n{ License Agreement:                                      }\n{                                                         }\n{ This library is distributed in the hope that it will be }\n{ useful, but WITHOUT ANY WARRANTY; without even the      }\n{ implied warranty of MERCHANTABILITY or FITNESS FOR      }\n{ A PARTICULAR PURPOSE.  See the GNU Lesser General       }\n{ Public License for more details.                        }\n{                                                         }\n{ The source code of the ZEOS Libraries and packages are  }\n{ distributed under the Library GNU General Public        }\n{ License (see the file COPYING / COPYING.ZEOS)           }\n{ with the following  modification:                       }\n{ As a special exception, the copyright holders of this   }\n{ library give you permission to link this library with   }\n{ independent modules to produce an executable,           }\n{ regardless of the license terms of these independent    }\n{ modules, and to copy and distribute the resulting       }\n{ executable under terms of your choice, provided that    }\n{ you also meet, for each linked independent module,      }\n{ the terms and conditions of the license of that module. }\n{ An independent module is a module which is not derived  }\n{ from or based on this library. If you modify this       }\n{ library, you may extend this exception to your version  }\n{ of the library, but you are not obligated to do so.     }\n{ If you do not wish to do so, delete this exception      }\n{ statement from your version.                            }\n{                                                         }\n{                                                         }\n{ The project web site is located on:                     }\n{   http://zeos.firmos.at  (FORUM)                        }\n{   http://sourceforge.net/p/zeoslib/tickets/ (BUGTRACKER)}\n{   svn://svn.code.sf.net/p/zeoslib/code-0/trunk (SVN)    }\n{                                                         }\n{   http://www.sourceforge.net/projects/zeoslib.          }\n{                                                         }\n{                                                         }\n{                                 Zeos Development Group. }\n{********************************************************@}\n\nunit ZSequence;\n\ninterface\n\n{$I ZComponent.inc}\n\nuses\n  SysUtils, Classes, {$IFDEF MSEgui}mclasses,{$ENDIF}\n  ZDbcIntfs, ZConnection;\n\ntype\n  {** Represents a component which wraps a sequence to database. }\n  TZSequence = class(TComponent)\n  private\n    FSequence: IZSequence;\n    FConnection: TZConnection;\n    FSequenceName: string;\n    FBlockSize: Integer;\n    procedure SetConnection(const Value: TZConnection);\n    procedure SetBlockSize(const Value: Integer);\n    procedure SetSequenceName(const Value: string);\n  protected\n    procedure Notification(AComponent: TComponent;\n      Operation: TOperation); override;\n    function GetSequence: IZSequence;\n  public\n    constructor Create(AOwner: TComponent); override;\n    // Modified by cipto 8/2/2007 12:09:21 PM\n    destructor Destroy; override;\n\n    function GetCurrentValue: Int64;\n    function GetNextValue: Int64;\n    function  GetCurrentValueSQL: string; // Get the Sequence as SQL-Text\n    function  GetNextValueSQL: string;   // Get the Sequence as SQL-Text\n    // Modified by cipto 8/2/2007 10:04:41 AM\n    procedure CloseSequence;\n  published\n    property BlockSize: Integer read FBlockSize write SetBlockSize default 1;\n    property Connection: TZConnection read FConnection write SetConnection;\n    property SequenceName: string read FSequenceName write SetSequenceName;\n  end;\n\nimplementation\n\n{ TZSequence }\n\nprocedure TZSequence.CloseSequence;\nbegin\n  if Assigned(FSequence) then\n    FSequence:=nil;\nend;\n\nconstructor TZSequence.Create(AOwner: TComponent);\nbegin\n  inherited;\n  FBlockSize := 1;\nend;\n\n{**\n  Gets the current unique key generated by this sequence.\n  @param the next generated unique key.\n}\ndestructor TZSequence.Destroy;\nbegin\n  // Modified by cipto 8/3/2007 10:35:41 AM\n  if Assigned(FConnection) then\n     FConnection.UnregisterSequence(self);\n  inherited;\nend;\n\nfunction TZSequence.GetCurrentValue: Int64;\nbegin\n  GetSequence;\n  if Assigned(FSequence) then\n    Result := FSequence.GetCurrentValue\n  else\n    Result := 0;\nend;\n\nfunction TZSequence.GetCurrentValueSQL: string;\nbegin\n  GetSequence;\n  if Assigned(FSequence) then begin\n    Result := FSequence.GetCurrentValueSQL;\n  end else begin\n    Result := 'IMPLEMENT';\n  end;\nend;\n\n{**\n  Gets the next unique key generated by this sequence.\n  @param the next generated unique key.\n}\nfunction TZSequence.GetNextValue: Int64;\nbegin\n  GetSequence;\n  if Assigned(FSequence) then\n    Result := FSequence.GetNextValue\n  else\n    Result := 0;\nend;\n\nfunction TZSequence.GetNextValueSQL: string;\nbegin\n  GetSequence;\n  if Assigned(FSequence) then begin\n    Result := FSequence.GetNextValueSQL;\n  end else begin\n    Result := 'IMPLEMENT';\n  end;\nend;\n\nfunction TZSequence.GetSequence: IZSequence;\nbegin\n  if not Assigned(FSequence) then\n  begin\n    if Assigned(FConnection) and Assigned(FConnection.DbcConnection) then\n      FSequence := FConnection.DbcConnection.CreateSequence(\n        FSequenceName, FBlockSize);\n  end;\n  Result := FSequence;\nend;\n\n{**\n  Processes component notifications.\n  @param AComponent a changed component object.\n  @param Operation a component operation code.\n}\nprocedure TZSequence.Notification(AComponent: TComponent;\n  Operation: TOperation);\nbegin\n  inherited Notification(AComponent, Operation);\n\n  if (Operation = opRemove) and (AComponent = FConnection) then\n  begin\n    // Modified by cipto 8/2/2007 12:07:57 PM\n    FConnection := nil;\n    if Assigned(FSequence) then\n      FSequence := nil;\n  end;\nend;\n\nprocedure TZSequence.SetBlockSize(const Value: Integer);\nbegin\n  FBlockSize := Value;\n  GetSequence;\n  if Assigned(FSequence) then\n    FSequence.SetBlockSize(FBlockSize);\nend;\n\nprocedure TZSequence.SetConnection(const Value: TZConnection);\nbegin\n  if FConnection <> Value then\n  begin\n    if Assigned(FSequence) then\n      FSequence := nil;\n    FConnection := Value;\n    // Modified by cipto 8/2/2007 11:59:58 AM\n    if Assigned(FConnection) then\n      FConnection.RegisterSequence(self);\n    GetSequence;\n  end;\nend;\n\nprocedure TZSequence.SetSequenceName(const Value: string);\nbegin\n  FSequenceName := Value;\n  GetSequence;\n  if Assigned(FSequence) then\n    FSequence.SetName(FSequenceName);\nend;\n\nend.\n"
  },
  {
    "path": "lib/zeosdbo/src/component/ZSqlMetadata.pas",
    "content": "{*********************************************************}\n{                                                         }\n{                 Zeos Database Objects                   }\n{            SQL Metadata Dataset component               }\n{                                                         }\n{        Originally written by Sergey Seroukhov           }\n{                                                         }\n{*********************************************************}\n\n{@********************************************************}\n{    Copyright (c) 1999-2012 Zeos Development Group       }\n{                                                         }\n{ License Agreement:                                      }\n{                                                         }\n{ This library is distributed in the hope that it will be }\n{ useful, but WITHOUT ANY WARRANTY; without even the      }\n{ implied warranty of MERCHANTABILITY or FITNESS FOR      }\n{ A PARTICULAR PURPOSE.  See the GNU Lesser General       }\n{ Public License for more details.                        }\n{                                                         }\n{ The source code of the ZEOS Libraries and packages are  }\n{ distributed under the Library GNU General Public        }\n{ License (see the file COPYING / COPYING.ZEOS)           }\n{ with the following  modification:                       }\n{ As a special exception, the copyright holders of this   }\n{ library give you permission to link this library with   }\n{ independent modules to produce an executable,           }\n{ regardless of the license terms of these independent    }\n{ modules, and to copy and distribute the resulting       }\n{ executable under terms of your choice, provided that    }\n{ you also meet, for each linked independent module,      }\n{ the terms and conditions of the license of that module. }\n{ An independent module is a module which is not derived  }\n{ from or based on this library. If you modify this       }\n{ library, you may extend this exception to your version  }\n{ of the library, but you are not obligated to do so.     }\n{ If you do not wish to do so, delete this exception      }\n{ statement from your version.                            }\n{                                                         }\n{                                                         }\n{ The project web site is located on:                     }\n{   http://zeos.firmos.at  (FORUM)                        }\n{   http://sourceforge.net/p/zeoslib/tickets/ (BUGTRACKER)}\n{   svn://svn.code.sf.net/p/zeoslib/code-0/trunk (SVN)    }\n{                                                         }\n{   http://www.sourceforge.net/projects/zeoslib.          }\n{                                                         }\n{                                                         }\n{                                 Zeos Development Group. }\n{********************************************************@}\n\nunit ZSqlMetadata;\n\ninterface\n\n{$I ZComponent.inc}\n\nuses\n  SysUtils, Classes, ZDbcIntfs, ZAbstractRODataset;\n\ntype\n\n  {** Defines an enumiration for SQL metadata resultsets. }\n  TZMetadataType = (mdProcedures, mdProcedureColumns, mdTables, mdSchemas,\n    mdCatalogs, mdTableTypes, mdColumns, mdColumnPrivileges, mdTablePrivileges,\n    mdBestRowIdentifier, mdVersionColumns, mdPrimaryKeys, mdImportedKeys,\n    mdExportedKeys, mdCrossReference, mdTypeInfo, mdTriggers, mdIndexInfo, mdSequences,\n    mdUserDefinedTypes);\n\n  {**\n    Abstract dataset component which works with one specified table.\n  }\n  TZSQLMetadata = class(TZAbstractRODataset)\n  private\n    FMetadataType: TZMetadataType;\n    FCatalog: string;\n    FSchema: string;\n    FTableName: string;\n    FTriggerName: string;\n    FColumnName: string;\n    FProcedureName: string;\n    FScope: Integer;\n    FNullable: Boolean;\n    FForeignCatalog: string;\n    FForeignSchema: string;\n    FForeignTableName: string;\n    FUnique: Boolean;\n    FApproximate: Boolean;\n    FTypeName: string;\n    FSequenceName: string;\n\n    procedure SetMetadataType(Value: TZMetadataType);\n  protected\n    function CreateResultSet(const SQL: string; MaxRows: Integer): IZResultSet;\n      override;\n    procedure CheckSQLQuery; override;\n  published\n    property MetadataType: TZMetadataType read FMetadataType write SetMetadataType;\n    property Catalog: string read FCatalog write FCatalog;\n    property Schema: string read FSchema write FSchema;\n    property TableName: string read FTableName write FTableName;\n    property ColumnName: string read FColumnName write FColumnName;\n    property ProcedureName: string read FProcedureName write FProcedureName;\n    property Scope: Integer read FScope write FScope default 0;\n    property Nullable: Boolean read FNullable write FNullable default False;\n    property ForeignCatalog: string read FForeignCatalog write FForeignCatalog;\n    property ForeignSchema: string read FForeignSchema write FForeignSchema;\n    property ForeignTableName: string read FForeignTableName write FForeignTableName;\n    property Unique: Boolean read FUnique write FUnique default False;\n    property Approximate: Boolean read FApproximate write FApproximate default False;\n    property TypeName: string read FTypeName write FTypeName;\n    property SequenceName: string read FSequenceName write FSequenceName;\n    property TriggerName: String read FTriggerName write FTriggerName;\n    property Active;\n    property MasterFields;\n    property MasterSource;\n    property LinkedFields; {renamed by bangfauzan}\n  end;\n\nimplementation\n\n{ TZSQLMetadata }\n\n{**\n  Sets a new SQL metadata type.\n  @param Value a new SQL metadata type.\n}\nprocedure TZSQLMetadata.SetMetadataType(Value: TZMetadataType);\nbegin\n  if FMetadataType <> Value then\n  begin\n    Active := False;\n    FMetadataType := Value;\n  end;\nend;\n\n{**\n  Creates a DBC resultset for the query.\n  @param SQL an SQL query.\n  @param MaxRows a maximum rows number (-1 for all).\n  @returns a created DBC resultset.\n}\n{$IFDEF FPC}\n  {$HINTS OFF}\n{$ENDIF}\nfunction TZSQLMetadata.CreateResultSet(const SQL: string; MaxRows: Integer):\n  IZResultSet;\nvar\n  Metadata: IZDatabaseMetadata;\nbegin\n  Connection.ShowSQLHourGlass;\n  try\n    Metadata := Connection.DbcConnection.GetMetadata;\n\n    case FMetadataType of\n      mdProcedures:\n        Result := Metadata.GetProcedures(FCatalog, FSchema, FProcedureName);\n      mdProcedureColumns:\n        Result := Metadata.GetProcedureColumns(FCatalog, FSchema,\n          FProcedureName, FColumnName);\n      mdTables:\n        Result := Metadata.GetTables(FCatalog, FSchema, FTableName, nil);\n      mdSchemas:\n        Result := Metadata.GetSchemas;\n      mdCatalogs:\n        Result := Metadata.GetCatalogs;\n      mdTableTypes:\n        Result := Metadata.GetTableTypes;\n      mdTriggers:\n        Result := Metadata.GetTriggers(FCatalog, FSchema, FTableName, FTriggerName);\n      mdColumns:\n        Result := Metadata.GetColumns(FCatalog, FSchema, FTableName,\n          FColumnName);\n      mdColumnPrivileges:\n        Result := Metadata.GetColumnPrivileges(FCatalog, FSchema, FTableName,\n          FColumnName);\n      mdTablePrivileges:\n        Result := Metadata.GetTablePrivileges(FCatalog, FSchema, FTableName);\n      mdBestRowIdentifier:\n        Result := Metadata.GetBestRowIdentifier(FCatalog, FSchema, FTableName,\n          FScope, FNullable);\n      mdVersionColumns:\n        Result := Metadata.GetVersionColumns(FCatalog, FSchema, FTableName);\n      mdPrimaryKeys:\n        Result := Metadata.GetPrimaryKeys(FCatalog, FSchema, FTableName);\n      mdImportedKeys:\n        Result := Metadata.GetImportedKeys(FCatalog, FSchema, FTableName);\n      mdExportedKeys:\n        Result := Metadata.GetExportedKeys(FCatalog, FSchema, FTableName);\n      mdCrossReference:\n        Result := Metadata.GetCrossReference(FCatalog, FSchema, FTableName,\n          FForeignCatalog, FForeignSchema, FForeignTableName);\n      mdTypeInfo:\n        Result := Metadata.GetTypeInfo;\n      mdIndexInfo:\n        Result := Metadata.GetIndexInfo(FCatalog, FSchema, FTableName, FUnique,\n          FApproximate);\n      mdSequences:\n        Result := Metadata.GetSequences(FCatalog, FSchema, FSequenceName);\n      mdUserDefinedTypes:\n        Result := Metadata.GetUDTs(FCatalog, FSchema, FTypeName, nil);\n     end;\n  finally\n    Connection.HideSQLHourGlass;\n  end;\nend;\n{$IFDEF FPC}\n  {$HINTS ON}\n{$ENDIF}\n\n{**\n  Checks the SQL query. The query has no meaning for this class.\n}\nprocedure TZSQLMetadata.CheckSQLQuery;\nbegin\n  // Here sql has no meaning. So it should not be tested.\nend;\n\nend.\n"
  },
  {
    "path": "lib/zeosdbo/src/component/ZSqlMonitor.pas",
    "content": "{*********************************************************}\n{                                                         }\n{                 Zeos Database Objects                   }\n{                 SQL Monitor component                   }\n{                                                         }\n{        Originally written by Sergey Seroukhov           }\n{                                                         }\n{*********************************************************}\n\n{@********************************************************}\n{    Copyright (c) 1999-2012 Zeos Development Group       }\n{                                                         }\n{ License Agreement:                                      }\n{                                                         }\n{ This library is distributed in the hope that it will be }\n{ useful, but WITHOUT ANY WARRANTY; without even the      }\n{ implied warranty of MERCHANTABILITY or FITNESS FOR      }\n{ A PARTICULAR PURPOSE.  See the GNU Lesser General       }\n{ Public License for more details.                        }\n{                                                         }\n{ The source code of the ZEOS Libraries and packages are  }\n{ distributed under the Library GNU General Public        }\n{ License (see the file COPYING / COPYING.ZEOS)           }\n{ with the following  modification:                       }\n{ As a special exception, the copyright holders of this   }\n{ library give you permission to link this library with   }\n{ independent modules to produce an executable,           }\n{ regardless of the license terms of these independent    }\n{ modules, and to copy and distribute the resulting       }\n{ executable under terms of your choice, provided that    }\n{ you also meet, for each linked independent module,      }\n{ the terms and conditions of the license of that module. }\n{ An independent module is a module which is not derived  }\n{ from or based on this library. If you modify this       }\n{ library, you may extend this exception to your version  }\n{ of the library, but you are not obligated to do so.     }\n{ If you do not wish to do so, delete this exception      }\n{ statement from your version.                            }\n{                                                         }\n{                                                         }\n{ The project web site is located on:                     }\n{   http://zeos.firmos.at  (FORUM)                        }\n{   http://sourceforge.net/p/zeoslib/tickets/ (BUGTRACKER)}\n{   svn://svn.code.sf.net/p/zeoslib/code-0/trunk (SVN)    }\n{                                                         }\n{   http://www.sourceforge.net/projects/zeoslib.          }\n{                                                         }\n{                                                         }\n{                                 Zeos Development Group. }\n{********************************************************@}\n\nunit ZSqlMonitor;\n\ninterface\n\n{$I ZComponent.inc}\n\nuses\n  SysUtils, Classes, Contnrs, {$IFDEF MSEgui}mclasses,{$ENDIF}\n  ZClasses, ZCompatibility, ZDbcIntfs, ZDbcLogging;\n\ntype\n\n  {** Repeat declaration of TZLoggingEvent. }\n  TZLoggingEvent = ZDbcLogging.TZLoggingEvent;\n\n  {** Repeat declaration of TZLoggingFormatter. }\n  IZLoggingFormatter = ZDbcLogging.IZLoggingFormatter;\n  TZLoggingFormatter = ZDbcLogging.TZLoggingFormatter;\n\n  {** Declares event before logging. }\n  TZTraceEvent = procedure(Sender: TObject; Event: TZLoggingEvent;\n    var LogTrace: Boolean) of object;\n\n  {** Declares event after logging. }\n  TZTraceLogEvent = procedure(Sender: TObject; Event: TZLoggingEvent) of object;\n\n  {**\n    Implements an object to log events from SQL client.\n  }\n  TZSQLMonitor = class(TComponent, IZLoggingListener, IZInterface)\n  private\n    FActive: Boolean;\n    FAutoSave: Boolean;\n    FFileName: string;\n    FMaxTraceCount: Integer;\n    FTraceList: TObjectList;\n    FOnTrace: TZTraceEvent;\n    FOnLogTrace: TZTraceLogEvent;\n    FLoggingFormatter : IZLoggingFormatter;\n\n    function GetTraceCount: Integer;\n    function GetTraceItem(Index: Integer): TZLoggingEvent;\n    procedure SetActive(const Value: Boolean);\n    procedure SetMaxTraceCount(const Value: Integer);\n\n    procedure TruncateTraceList(Count: Integer);\n    procedure DoTrace(Event: TZLoggingEvent; var LogTrace: Boolean);\n    procedure DoLogTrace(Event: TZLoggingEvent);\n  public\n    constructor Create(AOwner: TComponent); override;\n    destructor Destroy; override;\n\n    procedure LogEvent(Event: TZLoggingEvent);\n    procedure Save();\n    procedure SaveToFile(const FileName: string);\n\n    property TraceCount: Integer read GetTraceCount;\n    property TraceList[Index: Integer]: TZLoggingEvent read GetTraceItem;\n    property LoggingFormatter: IZLoggingFormatter read FLoggingFormatter write FLoggingFormatter;\n  published\n    property Active: Boolean read FActive write SetActive default False;\n    property AutoSave: Boolean read FAutoSave write FAutoSave default False;\n    property FileName: string read FFileName write FFileName;\n    property MaxTraceCount: Integer read FMaxTraceCount write SetMaxTraceCount;\n\n    property OnTrace: TZTraceEvent read FOnTrace write FOnTrace;\n    property OnLogTrace: TZTraceLogEvent read FOnLogTrace write FOnLogTrace;\n  end;\n\nimplementation\n\n{$IFDEF WITH_UNITANSISTRINGS}\nuses AnsiStrings;\n{$ENDIF}\n\n{ TZSQLMonitor }\n\n{**\n  Constructs this object and assignes main properties.\n  @param AOwner a component owner.\n}\nconstructor TZSQLMonitor.Create(AOwner: TComponent);\nbegin\n  inherited Create(AOwner);\n  FTraceList := TObjectList.Create;\n  FMaxTraceCount := 100;\nend;\n\n{**\n  Destroys this object and cleanups the memory.\n}\ndestructor TZSQLMonitor.Destroy;\nbegin\n  SetActive(False);\n  FTraceList.Free;\n  inherited Destroy;\nend;\n\n{**\n  Gets a number of stored logging events.\n  @returns a number of stored logging events.\n}\nfunction TZSQLMonitor.GetTraceCount: Integer;\nbegin\n  Result := FTraceList.Count;\nend;\n\n{**\n  Gets a logging event by it's index.\n  @param Index an event index.\n  @retuns a requested event object.\n}\nfunction TZSQLMonitor.GetTraceItem(Index: Integer): TZLoggingEvent;\nbegin\n  Result := TZLoggingEvent(FTraceList[Index]);\nend;\n\n{**\n  Sets an active state for this monitor.\n  @param Value <code>True</code> to activate this monitor\n    and <code>False</code> to deactivate it.\n}\nprocedure TZSQLMonitor.SetActive(const Value: Boolean);\nbegin\n  if FActive <> Value then\n  begin\n    if Value then\n      DriverManager.AddLoggingListener(Self)\n    else\n      if Assigned(DriverManager) then\n         DriverManager.RemoveLoggingListener(Self);\n    FActive := Value;\n  end;\nend;\n\n{**\n  Sets a new number of logging events in the storage.\n  @param Value a new number of logging events.\n}\nprocedure TZSQLMonitor.SetMaxTraceCount(const Value: Integer);\nbegin\n  if Value <> FMaxTraceCount then\n  begin\n    FMaxTraceCount := Value;\n    TruncateTraceList(Value);\n  end;\nend;\n\n{**\n  Truncates a storage of logging events to the specified limit.\n  @param Count a number of events in the storage.\n}\nprocedure TZSQLMonitor.TruncateTraceList(Count: Integer);\nbegin\n  while FTraceList.Count > Count do\n    FTraceList.Delete(0);\nend;\n\n{**\n  Invokes an event listener after logging event.\n  @param Event a logging event object.\n}\nprocedure TZSQLMonitor.DoLogTrace(Event: TZLoggingEvent);\nbegin\n  if Assigned(FOnLogTrace) then\n    FOnLogTrace(Self, Event);\nend;\n\n{**\n  Invokes an event listener before logging event.\n  @param Event a logging event object.\n  @param LogTrace a flag which switches storing the event.\n}\nprocedure TZSQLMonitor.DoTrace(Event: TZLoggingEvent;\n  var LogTrace: Boolean);\nbegin\n  if Assigned(FOnTrace) then\n    FOnTrace(Self, Event, LogTrace);\nend;\n\n{**\n  Saves the logging events into predefined file\n  set in FileName property.\n}\nprocedure TZSQLMonitor.Save;\nbegin\n  SaveToFile(FFileName);\nend;\n\n{**\n  Saves the logging events to the specified file.\n  @param FileName a name of the file to write the events.\n}\nprocedure TZSQLMonitor.SaveToFile(const FileName: string);\nvar\n  I: Integer;\n  Stream: TFileStream;\nTemp: Ansistring; \nBuffer: PAnsiChar; \nbegin\n  if not FileExists(FileName) then\n    Stream := TFileStream.Create(FileName, fmCreate)\n  else\n    Stream := TFileStream.Create(FileName, fmOpenWrite or fmShareDenyWrite);\n  try\n    for I := 0 to FTraceList.Count - 1 do\n    begin\n      Temp := AnsiString(TZLoggingEvent(FTraceList[I]).AsString + LineEnding);\n      Buffer := PAnsiChar(Temp);\n      Stream.Write(Buffer^, {$IFDEF WITH_STRLEN_DEPRECATED}AnsiStrings.{$ENDIF}StrLen(Buffer) * sizeof(Ansichar));\n    end;\n  finally\n    Stream.Free;\n  end;\nend;\n\n{**\n  Handles a new incoming logging event.\n  @param Event an incoming logging event.\n}\nprocedure TZSQLMonitor.LogEvent(Event: TZLoggingEvent);\nvar\n  LogTrace: Boolean;\n  Stream: TFileStream;\nTemp: Ansistring; \nBuffer: PAnsiChar; \nbegin\n  LogTrace := True;\n  DoTrace(Event, LogTrace);\n  if not LogTrace then Exit;\n\n  { Store the event. }\n  if FMaxTraceCount <> 0 then\n  begin\n    if FMaxTraceCount > 0 then\n      TruncateTraceList(FMaxTraceCount - 1);\n    FTraceList.Add(TZLoggingEvent.Create(Event.Category, Event.Protocol,\n      Event.Message, Event.ErrorCode, Event.Error));\n  end;\n\n  { Save the event. }\n  if FAutoSave and (FFileName <> '') then\n  begin\n    if not FileExists(FFileName) then\n      Stream := TFileStream.Create(FFileName, fmCreate)\n    else\n      Stream := TFileStream.Create(FFileName, fmOpenReadWrite or fmShareDenyWrite);\n    try\n      Stream.Seek(0, soFromEnd);\n      Temp := AnsiString(Event.AsString(FLoggingFormatter) + LineEnding);\n      Buffer := PAnsiChar(Temp);\n      Stream.Write(Buffer^, {$IFDEF WITH_STRLEN_DEPRECATED}AnsiStrings.{$ENDIF}StrLen(Buffer)*sizeof(Ansichar));\n    finally\n      Stream.Free;\n    end;\n  end;\n\n  DoLogTrace(Event);\nend;\n\nend.\n"
  },
  {
    "path": "lib/zeosdbo/src/component/ZSqlProcessor.pas",
    "content": "{*********************************************************}\n{                                                         }\n{                 Zeos Database Objects                   }\n{             Unidatabase SQLProcessor component          }\n{                                                         }\n{        Originally written by Sergey Seroukhov           }\n{                                                         }\n{*********************************************************}\n\n{@********************************************************}\n{    Copyright (c) 1999-2012 Zeos Development Group       }\n{                                                         }\n{ License Agreement:                                      }\n{                                                         }\n{ This library is distributed in the hope that it will be }\n{ useful, but WITHOUT ANY WARRANTY; without even the      }\n{ implied warranty of MERCHANTABILITY or FITNESS FOR      }\n{ A PARTICULAR PURPOSE.  See the GNU Lesser General       }\n{ Public License for more details.                        }\n{                                                         }\n{ The source code of the ZEOS Libraries and packages are  }\n{ distributed under the Library GNU General Public        }\n{ License (see the file COPYING / COPYING.ZEOS)           }\n{ with the following  modification:                       }\n{ As a special exception, the copyright holders of this   }\n{ library give you permission to link this library with   }\n{ independent modules to produce an executable,           }\n{ regardless of the license terms of these independent    }\n{ modules, and to copy and distribute the resulting       }\n{ executable under terms of your choice, provided that    }\n{ you also meet, for each linked independent module,      }\n{ the terms and conditions of the license of that module. }\n{ An independent module is a module which is not derived  }\n{ from or based on this library. If you modify this       }\n{ library, you may extend this exception to your version  }\n{ of the library, but you are not obligated to do so.     }\n{ If you do not wish to do so, delete this exception      }\n{ statement from your version.                            }\n{                                                         }\n{                                                         }\n{ The project web site is located on:                     }\n{   http://zeos.firmos.at  (FORUM)                        }\n{   http://sourceforge.net/p/zeoslib/tickets/ (BUGTRACKER)}\n{   svn://svn.code.sf.net/p/zeoslib/code-0/trunk (SVN)    }\n{                                                         }\n{   http://www.sourceforge.net/projects/zeoslib.          }\n{                                                         }\n{                                                         }\n{                                 Zeos Development Group. }\n{********************************************************@}\n\nunit ZSqlProcessor;\n\ninterface\n\n{$I ZComponent.inc}\n\nuses Types, Classes, SysUtils, {$IFDEF MSEgui}mclasses, mdb{$ELSE}DB{$ENDIF},\n  ZDbcIntfs, ZAbstractConnection, ZScriptParser, ZSqlStrings, ZCompatibility;\n\ntype\n\n  {** Forward definition of TZSQLProcessor. }\n  TZSQLProcessor = class;\n\n  {** Defines an error handle action. }\n  TZErrorHandleAction = (eaFail, eaAbort, eaSkip, eaRetry);\n\n  {** Defines an Processor notification event. }\n  TZProcessorNotifyEvent = procedure(Processor: TZSQLProcessor;\n    StatementIndex: Integer) of object;\n\n  {** Defines an Processor error handling event. }\n  TZProcessorErrorEvent = procedure(Processor: TZSQLProcessor;\n    StatementIndex: Integer; E: Exception;\n    var ErrorHandleAction: TZErrorHandleAction) of object;\n\n  {**\n    Implements a unidatabase component which parses and executes SQL Scripts.\n  }\n\n  { TZSQLProcessor }\n\n  TZSQLProcessor = class (TComponent)\n  private\n    FParams: TParams;\n    FScript: TZSQLStrings;\n    FScriptParser: TZSQLScriptParser;\n    FConnection: TZAbstractConnection;\n    FBeforeExecute: TZProcessorNotifyEvent;\n    FAfterExecute: TZProcessorNotifyEvent;\n    FOnError: TZProcessorErrorEvent;\n\n    procedure SetParams(Value: TParams);\n    function GetScript: TStrings;\n    procedure SetScript(Value: TStrings);\n    function GetStatementCount: Integer;\n    function GetStatement(Index: Integer): string;\n    procedure SetConnection(Value: TZAbstractConnection);\n    function GetDelimiterType: TZDelimiterType;\n    procedure SetDelimiterType(Value: TZDelimiterType);\n    function GetDelimiter: string;\n    procedure SetDelimiter(const Value: string);\n    function GetCleanupStatements: Boolean;\n    procedure SetCleanupStatements(const Value: Boolean);\n\n    function GetParamCheck: Boolean;\n    procedure SetParamCheck(Value: Boolean);\n    function GetParamChar: Char;\n    procedure SetParamChar(Value: Char);\n    procedure UpdateSQLStrings(Sender: TObject);\n  protected\n    procedure CheckConnected;\n    function DoOnError(StatementIndex: Integer; E: Exception):\n      TZErrorHandleAction;\n    procedure DoBeforeExecute(StatementIndex: Integer);\n    procedure DoAfterExecute(StatementIndex: Integer);\n\n    function CreateStatement(const SQL: string; Properties: TStrings):\n      IZPreparedStatement; virtual;\n    procedure SetStatementParams(Statement: IZPreparedStatement;\n      const ParamNames: TStringDynArray; Params: TParams); virtual;\n  public\n    constructor Create(AOwner: TComponent); override;\n    destructor Destroy; override;\n\n    procedure LoadFromStream(Stream: TStream);\n    procedure LoadFromFile(const FileName: string);\n\n    procedure Execute;\n    procedure Parse;\n    procedure Clear;\n\n    function ParamByName(const Value: string): TParam;\n\n    property StatementCount: Integer read GetStatementCount;\n    property Statements[Index: Integer]: string read GetStatement;\n  published\n    property ParamCheck: Boolean read GetParamCheck write SetParamCheck\n      default True;\n    property ParamChar: Char read GetParamChar write SetParamChar\n      default ':';\n    property Params: TParams read FParams write SetParams;\n    property Script: TStrings read GetScript write SetScript;\n    property Connection: TZAbstractConnection read FConnection write SetConnection;\n    property DelimiterType: TZDelimiterType read GetDelimiterType\n      write SetDelimiterType default dtDefault;\n    property Delimiter: string read GetDelimiter write SetDelimiter;\n    property CleanupStatements: Boolean read GetCleanupStatements\n      write SetCleanupStatements default False; \n    property OnError: TZProcessorErrorEvent read FOnError write FOnError;\n    property AfterExecute: TZProcessorNotifyEvent read FAfterExecute write FAfterExecute;\n    property BeforeExecute: TZProcessorNotifyEvent read FBeforeExecute write FBeforeExecute;\n  end;\n\nimplementation\n\nuses ZMessages, ZDbcUtils, ZAbstractRODataset, ZDatasetUtils;\n\n{ TZSQLProcessor }\n\n{**\n  Creates this Processor component and assignes the main properties.\n  @param AOwner an owner component.\n}\nconstructor TZSQLProcessor.Create(AOwner: TComponent);\nbegin\n  inherited Create(AOwner);\n\n  FParams := TParams.Create(Self);\n  FScript := TZSQLStrings.Create;\n  FScript.Dataset := Self;\n  FScript.OnChange := UpdateSQLStrings;\n  FScriptParser := TZSQLScriptParser.Create;\n  FScriptParser.DelimiterType := dtDefault;\n  FScriptParser.Delimiter := ';';\n  FScriptParser.CleanupStatements := False;\nend;\n\n{**\n  Destroys this component and cleanups the memory.\n}\ndestructor TZSQLProcessor.Destroy;\nbegin\n  FreeAndNil(FParams);\n  FreeAndNil(FScript);\n  FreeAndNil(FScriptParser);\n  FConnection := nil;\n  inherited Destroy;\nend;\n\n{**\n  Gets a parsed statement by it's index.\n  @return a SQL statement.\n}\nfunction TZSQLProcessor.GetStatement(Index: Integer): string;\nbegin\n  if (FScriptParser.UncompletedStatement <> '')\n    and (Index = FScriptParser.StatementCount) then\n    Result := FScriptParser.UncompletedStatement\n  else Result := FScriptParser.Statements[Index];\nend;\n\n{**\n  Gets a statements count.\n  @return a number of parsed statements.\n}\nfunction TZSQLProcessor.GetStatementCount: Integer;\nbegin\n  Result := FScriptParser.StatementCount;\n  if FScriptParser.UncompletedStatement <> '' then\n    Inc(Result);\nend;\n\n{**\n  Sets a new SQL connection component.\n  @param Value am SQL connection component.\n}\nprocedure TZSQLProcessor.SetConnection(Value: TZAbstractConnection);\nbegin\n  if FConnection <> Value then\n  begin\n    FConnection := Value;\n    FScriptParser.ClearUncompleted;\n  end;\nend;\n\n{**\n  Gets a script delimiter type;\n}\nfunction TZSQLProcessor.GetDelimiterType: TZDelimiterType;\nbegin\n  Result := FScriptParser.DelimiterType;\nend;\n\n{**\n  Sets a new Processor delimiter type.\n  @param Value a new Processor delimiter type.\n}\nprocedure TZSQLProcessor.SetDelimiterType(Value: TZDelimiterType);\nbegin\n  if FScriptParser.DelimiterType <> Value then\n  begin\n    FScriptParser.DelimiterType := Value;\n    FScriptParser.ClearUncompleted;\n  end;\nend;\n\n{**\n  Gets a script delimiter;\n}\nfunction TZSQLProcessor.GetDelimiter: string;\nbegin\n  Result := FScriptParser.Delimiter;\nend;\n\n{**\n  Sets a new Processor delimiter.\n  @param Value a new Processor delimiter.\n}\nprocedure TZSQLProcessor.SetDelimiter(const Value: string);\nbegin\n  if FScriptParser.Delimiter <> Value then\n  begin\n    FScriptParser.Delimiter := Value;\n    FScriptParser.ClearUncompleted;\n  end;\nend;\n\n{**\n  Sets a new set of parameters.\n  @param Value a set of parameters.\n}\nprocedure TZSQLProcessor.SetParams(Value: TParams);\nbegin\n  FParams.AssignValues(Value);\nend;\n\n{**\n  Sets a new SQL script.\n  @param Value a new SQL script.\n}\nprocedure TZSQLProcessor.SetScript(Value: TStrings);\nbegin\n  FScript.Assign(Value);\n  FScriptParser.ClearUncompleted;\nend;\n\n{**\n  Checks is the database connection assignes and tries to connect.\n}\nprocedure TZSQLProcessor.CheckConnected;\nbegin\n  if Connection = nil then\n    raise EZDatabaseError.Create(SConnectionIsNotAssigned);\n  Connection.Connect;\nend;\n\n{**\n  Clears Processor contents and all parsed statements.\n}\nprocedure TZSQLProcessor.Clear;\nbegin\n  FScript.Clear;\n  FScriptParser.ClearUncompleted;\nend;\n\n{**\n  Performs OnError Event and returns an error handle action.\n  @param StatementIndex an index of the statement which failt.\n  @param E an exception object.\n  @return an error handle action.\n}\nfunction TZSQLProcessor.DoOnError(StatementIndex: Integer;\n  E: Exception): TZErrorHandleAction;\nbegin\n  Result := eaFail;\n  if Assigned(FOnError) then\n    FOnError(Self, StatementIndex, E, Result);\nend;\n\n{**\n  Performs an action before execute a statement.\n  @param StatementIndex an index of the executing statement.\n}\nprocedure TZSQLProcessor.DoBeforeExecute(StatementIndex: Integer);\nbegin\n  if Assigned(FBeforeExecute) then\n    FBeforeExecute(Self, StatementIndex);\nend;\n\n{**\n  Performs an action action execute a statement.\n  @param StatementIndex an index of the executing statement.\n}\nprocedure TZSQLProcessor.DoAfterExecute(StatementIndex: Integer);\nbegin\n  if Assigned(FAfterExecute) then\n    FAfterExecute(Self, StatementIndex);\nend;\n\n{**\n  Loads a SQL Processor from the local file.\n  @param FileName a name of the file.\n}\nprocedure TZSQLProcessor.LoadFromFile(const FileName: string);\nbegin\n  FScript.LoadFromFile(FileName);\nend;\n\n{**\n  Loads a SQL Processor from the stream.\n  @param Stream a stream object.\n}\nprocedure TZSQLProcessor.LoadFromStream(Stream: TStream);\nbegin\n  FScript.LoadFromStream(Stream);\nend;\n\n{**\n  Executes a parsed SQL Processor.\n}\nprocedure TZSQLProcessor.Execute;\nvar\n  I: Integer;\n  Statement: IZPreparedStatement;\n  Action: TZErrorHandleAction;\n  SQL: TZSQLStrings;\nbegin\n  if Connection = nil then\n    raise EZDatabaseError.Create(SConnectionIsNotAssigned);\n\n  FConnection.ShowSQLHourGlass;\n  try\n    SQL := TZSQLStrings.Create;\n    SQL.Dataset := Self;\n    SQL.ParamCheck := FScript.ParamCheck;\n    SQL.MultiStatements := False;\n    Parse;\n\n    for I := 0 to Pred(StatementCount) do\n    begin\n      Action := eaSkip;\n      DoBeforeExecute(I);\n      repeat\n        try\n          SQL.Text := GetStatement(I);\n{http://zeos.firmos.at/viewtopic.php?t=2885&start=0&postdays=0&postorder=asc&highlight=}\n          if SQL.StatementCount > 0 then\n            begin\n              Statement := CreateStatement(SQL.Statements[0].SQL, nil);\n              SetStatementParams(Statement, SQL.Statements[0].ParamNamesArray,\n                FParams);\n              Statement.ExecuteUpdatePrepared;\n            end;\n          Statement := nil;\n        except\n          on E: Exception do\n          begin\n            if Assigned(Statement) then\n              Statement := nil;\n            Action := DoOnError(I, E);\n            if Action = eaFail then\n              RaiseSQLException(E)\n            else if Action = eaAbort then\n              Exit;\n          end;\n        end;\n      until Action <> eaRetry;\n      DoAfterExecute(I);\n\n    end;\n  finally\n    FreeAndNil(SQL);\n    Connection.HideSQLHourGlass;\n  end;\nend;\n\n{**\n  Gets a SQL parameter by its name.\n  @param Value a parameter name.\n  @return a found parameter object.\n}\nfunction TZSQLProcessor.ParamByName(const Value: string): TParam;\nbegin\n  Result := FParams.ParamByName(Value);\nend;\n\n{**\n  Parses the loaded SQL Processor.\n}\nprocedure TZSQLProcessor.Parse;\nbegin\n  CheckConnected;\n  FScriptParser.Tokenizer := Connection.DbcDriver.GetTokenizer;\n// mdaems 20060429 : Clear would reset the delimiter of the scriptparser\n//  FScriptParser.Clear;\n  FScriptParser.ClearUncompleted;\n  FScriptParser.ParseText(FScript.Text);\nend;\n\n{**\n  Creates a DBC statement for the query.\n  @param SQL an SQL query.\n  @param Properties a statement specific properties.\n  @returns a created DBC statement.\n}\nfunction TZSQLProcessor.CreateStatement(const SQL: string;\n  Properties: TStrings): IZPreparedStatement;\nvar\n  Temp: TStrings;\nbegin\n  Temp := TStringList.Create;\n  try\n    if Assigned(Properties) then\n      Temp.AddStrings(Properties);\n\n    Result := FConnection.DbcConnection.PrepareStatementWithParams(SQL, Temp);\n  finally\n    Temp.Free;\n  end;\nend;\n\n{**\n  Fill prepared statement with parameters.\n  @param Statement a prepared SQL statement.\n  @param ParamNames an array of parameter names.\n  @param Params a collection of SQL parameters.\n}\nprocedure TZSQLProcessor.SetStatementParams(Statement: IZPreparedStatement;\n  const ParamNames: TStringDynArray; Params: TParams);\nvar\n  I: Integer;\n  TempParam, Param: TParam;\nbegin\n  TempParam := TParam.Create(nil);\n\n  try\n    for I := Low(ParamNames) to High(ParamNames) do\n    begin\n      Param := Params.FindParam(ParamNames[I]);\n      if not Assigned(Param) or (Param.ParamType in [ptOutput, ptResult]) then\n        Continue;\n      SetStatementParam(I+1, Statement, Param);\n    end;\n  finally\n    TempParam.Free;\n  end;\nend;\n\n{**\n  Gets the SQL script.\n  @return the SQL script strings.\n}\nfunction TZSQLProcessor.GetScript: TStrings;\nbegin\n  Result := FScript;\nend;\n\n{**\n  Updates parameters from SQL statement.\n  @param Sender an event sender object.\n}\nprocedure TZSQLProcessor.UpdateSQLStrings(Sender: TObject);\nvar\n  I: Integer;\n  OldParams: TParams;\nbegin\n  OldParams := TParams.Create;\n  OldParams.Assign(FParams);\n  FParams.Clear;\n\n  try\n    for I := 0 to FScript.ParamCount - 1 do\n      FParams.CreateParam(ftUnknown, FScript.ParamNames[I], ptUnknown);\n    FParams.AssignValues(OldParams);\n  finally\n    OldParams.Free;\n  end;\nend;\n\n{**\n  Gets a parameters check value.\n  @return a parameters check value.\n}\nfunction TZSQLProcessor.GetParamCheck: Boolean;\nbegin\n  Result := FScript.ParamCheck;\nend;\n\n{**\n  Sets a new parameters check value.\n  @param Value a parameters check value.\n}\nprocedure TZSQLProcessor.SetParamCheck(Value: Boolean);\nbegin\n  FScript.ParamCheck := Value;\n  UpdateSQLStrings(Self);\nend;\n\n{**\n  Gets a parameters marker.\n  @return a parameter marker.\n}\nfunction TZSQLProcessor.GetParamChar: Char;\nbegin\n  Result := FScript.ParamChar;\nend;\n\n{**\n  Sets a new parameter marker.\n  @param Value a parameter marker.\n}\nprocedure TZSQLProcessor.SetParamChar(Value: Char);\nbegin\n  FScript.ParamChar := Value;\n  UpdateSQLStrings(Self);\nend;\n\nfunction TZSQLProcessor.GetCleanupStatements: Boolean;\nbegin\n  Result := FScriptParser.CleanupStatements;\nend;\n\nprocedure TZSQLProcessor.SetCleanupStatements(const Value: Boolean);\nbegin\n  if FScriptParser.CleanupStatements <> Value then\n  begin\n    FScriptParser.CleanupStatements := Value;\n    FScriptParser.ClearUncompleted;\n  end;\nend;\n\nend.\n\n"
  },
  {
    "path": "lib/zeosdbo/src/component/ZSqlStrings.pas",
    "content": "{*********************************************************}\n{                                                         }\n{                 Zeos Database Objects                   }\n{               SQL Query Strings component               }\n{                                                         }\n{        Originally written by Sergey Seroukhov           }\n{                                                         }\n{*********************************************************}\n\n{@********************************************************}\n{    Copyright (c) 1999-2012 Zeos Development Group       }\n{                                                         }\n{ License Agreement:                                      }\n{                                                         }\n{ This library is distributed in the hope that it will be }\n{ useful, but WITHOUT ANY WARRANTY; without even the      }\n{ implied warranty of MERCHANTABILITY or FITNESS FOR      }\n{ A PARTICULAR PURPOSE.  See the GNU Lesser General       }\n{ Public License for more details.                        }\n{                                                         }\n{ The source code of the ZEOS Libraries and packages are  }\n{ distributed under the Library GNU General Public        }\n{ License (see the file COPYING / COPYING.ZEOS)           }\n{ with the following  modification:                       }\n{ As a special exception, the copyright holders of this   }\n{ library give you permission to link this library with   }\n{ independent modules to produce an executable,           }\n{ regardless of the license terms of these independent    }\n{ modules, and to copy and distribute the resulting       }\n{ executable under terms of your choice, provided that    }\n{ you also meet, for each linked independent module,      }\n{ the terms and conditions of the license of that module. }\n{ An independent module is a module which is not derived  }\n{ from or based on this library. If you modify this       }\n{ library, you may extend this exception to your version  }\n{ of the library, but you are not obligated to do so.     }\n{ If you do not wish to do so, delete this exception      }\n{ statement from your version.                            }\n{                                                         }\n{                                                         }\n{ The project web site is located on:                     }\n{   http://zeos.firmos.at  (FORUM)                        }\n{   http://sourceforge.net/p/zeoslib/tickets/ (BUGTRACKER)}\n{   svn://svn.code.sf.net/p/zeoslib/code-0/trunk (SVN)    }\n{                                                         }\n{   http://www.sourceforge.net/projects/zeoslib.          }\n{                                                         }\n{                                                         }\n{                                 Zeos Development Group. }\n{********************************************************@}\n\nunit ZSqlStrings;\n\ninterface\n\n{$I ZComponent.inc}\n\nuses\n  Types, Classes, SysUtils, {$IFDEF MSEgui}mclasses,{$ENDIF}Contnrs,\n  ZDbcIntfs, ZTokenizer, ZGenericSqlToken, ZCompatibility;\n\ntype\n  {** Represents a SQL statement description object. }\n  TZSQLStatement = class (TObject)\n  private\n    FSQL: string;\n    FParamIndices: TIntegerDynArray;\n    FParams: TStrings;\n\n    function GetParamCount: Integer;\n    function GetParamName(Index: Integer): string;\n    function GetParamNamesArray: TStringDynArray;\n  public\n    constructor Create(const SQL: string; const ParamIndices: TIntegerDynArray;\n      Params: TStrings);\n    property SQL: string read FSQL;\n    property ParamCount: Integer read GetParamCount;\n    property ParamNames[Index: Integer]: string read GetParamName;\n    property ParamIndices: TIntegerDynArray read FParamIndices;\n    property ParamNamesArray: TStringDynArray read GetParamNamesArray;\n  end;\n\n  {** Imlements a string list with SQL statements. }\n\n  { TZSQLStrings }\n\n  TZSQLStrings = class (TStringList)\n  private\n    FDataset: TObject;\n    FParamCheck: Boolean;\n    FStatements: TObjectList;\n    FParams: TStringList;\n    FMultiStatements: Boolean;\n    FParamChar: Char;\n\n    function GetParamCount: Integer;\n    function GetParamName(Index: Integer): string;\n    function GetStatement(Index: Integer): TZSQLStatement;\n    function GetStatementCount: Integer;\n    function GetTokenizer: IZTokenizer;\n    procedure SetDataset(Value: TObject);\n    procedure SetParamCheck(Value: Boolean);\n    procedure SetParamChar(Value: Char);\n    procedure SetMultiStatements(Value: Boolean);\n  protected\n    procedure Changed; override;\n    function FindParam(const ParamName: string): Integer;\n    procedure RebuildAll;\n  public\n    constructor Create;\n    destructor Destroy; override;\n\n    property Dataset: TObject read FDataset write SetDataset;\n    property ParamCheck: Boolean read FParamCheck write SetParamCheck;\n    property ParamCount: Integer read GetParamCount;\n    property ParamChar: Char read FParamChar write SetParamChar;\n    property ParamNames[Index: Integer]: string read GetParamName;\n    property StatementCount: Integer read GetStatementCount;\n    property Statements[Index: Integer]: TZSQLStatement read GetStatement;\n    property MultiStatements: Boolean read FMultiStatements\n      write SetMultiStatements;\n  end;\n\nimplementation\n\nuses ZMessages, ZAbstractRODataset, ZDatasetUtils, ZSqlProcessor;\n\n{ TZSQLStatement }\n\n{**\n  Creates a SQL statement object and assignes the main properties.\n  @param SQL a SQL statement.\n  @param ParamIndices a parameter indices.\n  @param Params a list with all parameter names.\n}\nconstructor TZSQLStatement.Create(const SQL: string;\n  const ParamIndices: TIntegerDynArray; Params: TStrings);\nbegin\n  FSQL := SQL;\n  FParamIndices := ParamIndices;\n  FParams := Params;\nend;\n\n{**\n  Gets a parameters count for this statement.\n  @return a parameters count.\n}\nfunction TZSQLStatement.GetParamCount: Integer;\nbegin\n  if Assigned(FParamIndices) then\n    Result := High(FParamIndices) - Low(FParamIndices) + 1\n  else Result := 0;\nend;\n\n{**\n  Gets a parameter name by it's index inside the statement.\n  @return a parameter name.\n}\nfunction TZSQLStatement.GetParamName(Index: Integer): string;\nbegin\n  if Assigned(FParamIndices) then\n    Result := FParams[FParamIndices[Index + Low(FParamIndices)]]\n  else Result := '';\nend;\n\n{**\n  Gets an array of parameter names.\n  @return an array of parameter names.\n}\nfunction TZSQLStatement.GetParamNamesArray: TStringDynArray;\nvar\n  I: Integer;\nbegin\n  SetLength(Result, High(FParamIndices) - Low(FParamIndices) + 1);\n  for I := Low(Result) to High(Result) do\n    Result[I] := FParams[FParamIndices[I + Low(FParamIndices)]];\nend;\n\n{ TZSQLStrings }\n\n{**\n  Creates a SQL strings object and assigns the main properties.\n}\nconstructor TZSQLStrings.Create;\nbegin\n  inherited Create; { -> needed to run the TestSuite else Inheritance(Self).Methods fails}\n  FParams := TStringList.Create;\n  FParamCheck := True;\n  FStatements := TObjectList.Create;\n  FMultiStatements := True;\n  FParamChar :=':';\nend;\n\n{**\n  Destroys this object and cleanups the memory.\n}\ndestructor TZSQLStrings.Destroy;\nbegin\n  FreeAndNil(FParams);\n  FreeAndNil(FStatements);\n  FDataSet := nil;\n  inherited Destroy;\nend;\n\n{**\n  Gets a parameter count.\n  @return a count of SQL parameters.\n}\nfunction TZSQLStrings.GetParamCount: Integer;\nbegin\n  Result := FParams.Count;\nend;\n\n{**\n  Gets parameter name by it's index.\n  @param Index a parameter index.\n  @return a parameter name.\n}\nfunction TZSQLStrings.GetParamName(Index: Integer): string;\nbegin\n  Result := FParams[Index];\nend;\n\n{**\n  Gets a SQL statements count.\n  @return a SQL statements count.\n}\nfunction TZSQLStrings.GetStatementCount: Integer;\nbegin\n  Result := FStatements.Count;\nend;\n\nfunction TZSQLStrings.GetTokenizer: IZTokenizer;\nvar\n  Tokenizer: IZTokenizer;\n  Driver: IZDriver;\nbegin\n  { Defines a SQL specific tokenizer object. }\n  Tokenizer := CommonTokenizer;\n  if FDataset is TZAbstractRODataset then\n  begin\n    if Assigned(TZAbstractRODataset(FDataset).Connection) then\n    begin\n      Driver := TZAbstractRODataset(FDataset).Connection.DbcDriver;\n      if Assigned(Driver) then\n        Tokenizer := Driver.GetTokenizer;\n    end;\n  end\n  else if FDataset is TZSQLProcessor then\n  begin\n    if Assigned(TZSQLProcessor(FDataset).Connection) then\n    begin\n      Driver := TZSQLProcessor(FDataset).Connection.DbcDriver;\n      if Assigned(Driver) then\n        Tokenizer := Driver.GetTokenizer;\n    end;\n  end;\n  Result:=Tokenizer;\nend;\n\n{**\n  Gets a SQL statement by it's index.\n  @param Index a SQL statement index.\n  @return a SQL statement object.\n}\nfunction TZSQLStrings.GetStatement(Index: Integer): TZSQLStatement;\nbegin\n  Result := TZSQLStatement(FStatements[Index]);\nend;\n\n{**\n  Sets a new ParamCheck value.\n  @param Value a new ParamCheck value.\n}\nprocedure TZSQLStrings.SetParamCheck(Value: Boolean);\nbegin\n  if FParamCheck <> Value then\n  begin\n    FParamCheck := Value;\n    RebuildAll;\n  end;\nend;\n\n{**\n  Sets a new ParamChar value.\n  @param Value a new ParamCheck value.\n}\nprocedure TZSQLStrings.SetParamChar(Value: Char);\nbegin\n  if FParamChar <> Value then\n  begin\n    If not(GetTokenizer.GetCharacterState(Value) is TZSymbolstate) Then\n      raise EZDatabaseError.Create('Ongeldige ParamChar waarde : '+Value);\n    FParamChar := Value;\n    RebuildAll;\n  end;\nend;\n\n{**\n  Sets a new MultiStatements value.\n  @param Value a new MultiStatements value.\n}\nprocedure TZSQLStrings.SetMultiStatements(Value: Boolean);\nbegin\n  if FMultiStatements <> Value then\n  begin\n    FMultiStatements := Value;\n    RebuildAll;\n  end;\nend;\n\n{**\n  Sets a new correspondent dataset object.\n  @param Value a new dataset object.\n}\nprocedure TZSQLStrings.SetDataset(Value: TObject);\nbegin\n  if FDataset <> Value then\n  begin\n    FDataset := Value;\n    RebuildAll;\n  end;\nend;\n\n{**\n  Finds a parameter by it's name.\n  @param ParamName a parameter name.\n  @return an index of found parameters or -1 if nothing was found.\n}\nfunction TZSQLStrings.FindParam(const ParamName: string): Integer;\nbegin\n  FParams.CaseSensitive := False;\n  Result := FParams.IndexOf(ParamName);\nend;\n\n{**\n  Rebuilds all SQL statements.\n}\nprocedure TZSQLStrings.RebuildAll;\nvar\n  Tokens: TStrings;\n  TokenValue: string;\n  TokenType: TZTokenType;\n  TokenIndex: Integer;\n  ParamIndex: Integer;\n  ParamIndices: TIntegerDynArray;\n  ParamIndexCount: Integer;\n  ParamName, SQL: string;\n  Tokenizer: IZTokenizer;\n\n  procedure NextToken;\n  begin\n    TokenType := TZTokenType({$IFDEF FPC}Pointer({$ENDIF}\n      Tokens.Objects[TokenIndex]{$IFDEF FPC}){$ENDIF});\n    TokenValue := Tokens[TokenIndex];\n    Inc(TokenIndex);\n  end;\n\nbegin\n  if not (Assigned(FParams) and Assigned(FStatements)) then exit; //Alexs\n\n  FParams.Clear;\n  FStatements.Clear;\n  SQL := '';\n  ParamIndexCount := 0;\n  SetLength(ParamIndices, ParamIndexCount);\n  \n  { Optimization for empty query. }\n  If Length(Trim(Text)) = 0 then\n    Exit;\n\n  { Optimization for single query without parameters. }\n  if (not FParamCheck or (Pos(FParamChar, Text) = 0))\n    and (not FMultiStatements or (Pos(';', Text) = 0)) then\n  begin\n    FStatements.Add(TZSQLStatement.Create(Text, ParamIndices, FParams));\n    Exit;\n  end;\n\n  Tokenizer:=GetTokenizer;\n  Tokens := Tokenizer.TokenizeBufferToList(Text,\n    [toSkipComments, toUnifyWhitespaces]);\n  try\n    TokenIndex := 0;\n    repeat\n      NextToken;\n      { Processes parameters. }\n      if ParamCheck and (TokenValue = FParamChar) then\n      begin\n        NextToken;\n        if (TokenType <> ttEOF) and (TokenValue <> FParamChar) then\n        begin\n          { Check for correct parameter type. }\n          if not (TokenType in [ttWord, ttQuoted, ttQuotedIdentifier, ttKeyWord]) then\n            raise EZDatabaseError.Create(SIncorrectToken);\n\n          SQL := SQL + '?';\n\n          ParamName := TokenValue;\n          if (ParamName <> '') and CharInSet(ParamName[1], [#39, '`', '\"', '[']) then\n          begin\n            ParamName := Tokenizer.GetQuoteState.\n              DecodeString(ParamName, ParamName[1]);\n          end;\n\n          ParamIndex := FindParam(ParamName);\n          if ParamIndex < 0 then\n            ParamIndex := FParams.Add(ParamName);\n\n          Inc(ParamIndexCount);\n          SetLength(ParamIndices, ParamIndexCount);\n          ParamIndices[ParamIndexCount - 1] := ParamIndex;\n\n          Continue;\n        end;\n      end;\n\n      { Adds a DML statement. }\n      if (TokenType = ttEOF) or (FMultiStatements and (TokenValue = ';')) then\n      begin\n        SQL := Trim(SQL);\n        if SQL <> '' then\n          FStatements.Add(TZSQLStatement.Create(SQL, ParamIndices, FParams));\n\n        SQL := '';\n        ParamIndexCount := 0;\n        SetLength(ParamIndices, ParamIndexCount);\n      end\n      { Adds a default token. }\n      else\n        SQL := SQL + TokenValue;\n    until TokenType = ttEOF;\n  finally\n    Tokens.Free;\n  end;\nend;\n\n{**\n  Performs action when the content of this string list is changed.\n}\nprocedure TZSQLStrings.Changed;\nbegin\n  if UpdateCount = 0 then\n    RebuildAll;\n  inherited Changed;\nend;\n\nend.\n"
  },
  {
    "path": "lib/zeosdbo/src/component/ZSqlTestForm.pas",
    "content": "{*********************************************************}\n{                                                         }\n{                 Zeos Database Objects                   }\n{                 SQL Monitor component                   }\n{                                                         }\n{        Originally written by Sergey Seroukhov           }\n{                                                         }\n{*********************************************************}\n\n{@********************************************************}\n{    Copyright (c) 1999-2012 Zeos Development Group       }\n{                                                         }\n{ License Agreement:                                      }\n{                                                         }\n{ This library is distributed in the hope that it will be }\n{ useful, but WITHOUT ANY WARRANTY; without even the      }\n{ implied warranty of MERCHANTABILITY or FITNESS FOR      }\n{ A PARTICULAR PURPOSE.  See the GNU Lesser General       }\n{ Public License for more details.                        }\n{                                                         }\n{ The source code of the ZEOS Libraries and packages are  }\n{ distributed under the Library GNU General Public        }\n{ License (see the file COPYING / COPYING.ZEOS)           }\n{ with the following  modification:                       }\n{ As a special exception, the copyright holders of this   }\n{ library give you permission to link this library with   }\n{ independent modules to produce an executable,           }\n{ regardless of the license terms of these independent    }\n{ modules, and to copy and distribute the resulting       }\n{ executable under terms of your choice, provided that    }\n{ you also meet, for each linked independent module,      }\n{ the terms and conditions of the license of that module. }\n{ An independent module is a module which is not derived  }\n{ from or based on this library. If you modify this       }\n{ library, you may extend this exception to your version  }\n{ of the library, but you are not obligated to do so.     }\n{ If you do not wish to do so, delete this exception      }\n{ statement from your version.                            }\n{                                                         }\n{                                                         }\n{ The project web site is located on:                     }\n{   http://zeos.firmos.at  (FORUM)                        }\n{   http://sourceforge.net/p/zeoslib/tickets/ (BUGTRACKER)}\n{   svn://svn.code.sf.net/p/zeoslib/code-0/trunk (SVN)    }\n{                                                         }\n{   http://www.sourceforge.net/projects/zeoslib.          }\n{                                                         }\n{                                                         }\n{                                 Zeos Development Group. }\n{********************************************************@}\n\nunit ZSqlTestForm;\n\n{$I ZComponent.inc}\n\ninterface\n\nuses\n\n{$IFDEF MSWINDOWS}\n  Windows, Messages,\n{$ENDIF}\n  Classes, SysUtils, Forms, Controls, Graphics, Dialogs, ExtCtrls,\n  DBGrids, Buttons, DB, ZDataset, ZMessages;\n\ntype\n\n  { TZeosSQLEditorTestForm }\n\n  TZeosSQLEditorTestForm = class(TForm)\n  private\n    { private declarations }\n    Button1: TButton;\n    Datasource1: TDatasource;\n    dbGrid1: TdbGrid;\n    Panel1: TPanel;\n  public\n    { public declarations }\n    ZeosSQL: TZReadOnlyQuery;\n    constructor Create(AOwner: TComponent);\n  end;\n\nvar\n  ZeosSQLEditorTestForm: TZeosSQLEditorTestForm;\n\nimplementation\n\nconstructor TZeosSQLEditorTestForm.Create(AOwner: TComponent);\nbegin\n  inherited Create(AOwner);\n  Caption := SFormTest;\n  ClientHeight := 300;\n  ClientWidth := 683;\n  Height := 300;\n  Left := 291;\n  Top := 323;\n  Width := 683;\n  ZeosSQL := TZReadOnlyQuery.Create(self);\n  Datasource1 := TDataSource.Create(self);\n  Datasource1.DataSet := ZeosSQL;\n  Panel1 := TPanel.Create(self);\n  with Panel1 do\n  begin\n    Parent := self;\n    Anchors := [akTop,akLeft,akRight];\n    Align := alTop;\n    Left :=0;\n    Height := 42;\n    Top := 0;\n    Width := 683;\n    TabStop := False;\n  end;\n  Button1 := TButton.Create(self);\n  with Button1 do\n  begin\n    Parent := Panel1;\n    Anchors := [akTop,akLeft];\n    Cancel := True;\n    Default := True;\n    ModalResult := mrOk;\n    Caption := SButtonClose;\n    Left := 600;\n    Height := 25;\n    Top := 8;\n    Width := 75;\n    TabOrder := 0;\n    TabStop := True;\n  end;\n  dbGrid1 := TdbGrid.Create(self);\n  with dbGrid1 do\n  begin\n    Parent := self;\n    Anchors := [akTop,akLeft,akRight,akBottom];\n    DataSource := Datasource1;\n    Options := [dgTitles,dgIndicator,dgColumnResize,dgColLines,dgRowLines,\n                dgTabs,dgAlwaysShowSelection,dgConfirmDelete,dgCancelOnExit];\n    ReadOnly := True;\n    Align := alClient;\n    DefaultRowHeight := 24;\n    Left := 0;\n    Height := 258;\n    TabOrder := 1;\n    TabStop := True;\n    Top := 42;\n    Width := 683;\n  end;\nend;\n\nend.\n\n"
  },
  {
    "path": "lib/zeosdbo/src/component/ZSqlUpdate.pas",
    "content": "{*********************************************************}\n{                                                         }\n{                 Zeos Database Objects                   }\n{             Unidatabase UpdateSQL component             }\n{                                                         }\n{        Originally written by Sergey Seroukhov           }\n{                                                         }\n{*********************************************************}\n\n{@********************************************************}\n{    Copyright (c) 1999-2012 Zeos Development Group       }\n{                                                         }\n{ License Agreement:                                      }\n{                                                         }\n{ This library is distributed in the hope that it will be }\n{ useful, but WITHOUT ANY WARRANTY; without even the      }\n{ implied warranty of MERCHANTABILITY or FITNESS FOR      }\n{ A PARTICULAR PURPOSE.  See the GNU Lesser General       }\n{ Public License for more details.                        }\n{                                                         }\n{ The source code of the ZEOS Libraries and packages are  }\n{ distributed under the Library GNU General Public        }\n{ License (see the file COPYING / COPYING.ZEOS)           }\n{ with the following  modification:                       }\n{ As a special exception, the copyright holders of this   }\n{ library give you permission to link this library with   }\n{ independent modules to produce an executable,           }\n{ regardless of the license terms of these independent    }\n{ modules, and to copy and distribute the resulting       }\n{ executable under terms of your choice, provided that    }\n{ you also meet, for each linked independent module,      }\n{ the terms and conditions of the license of that module. }\n{ An independent module is a module which is not derived  }\n{ from or based on this library. If you modify this       }\n{ library, you may extend this exception to your version  }\n{ of the library, but you are not obligated to do so.     }\n{ If you do not wish to do so, delete this exception      }\n{ statement from your version.                            }\n{                                                         }\n{                                                         }\n{ The project web site is located on:                     }\n{   http://zeos.firmos.at  (FORUM)                        }\n{   http://sourceforge.net/p/zeoslib/tickets/ (BUGTRACKER)}\n{   svn://svn.code.sf.net/p/zeoslib/code-0/trunk (SVN)    }\n{                                                         }\n{   http://www.sourceforge.net/projects/zeoslib.          }\n{                                                         }\n{                                                         }\n{                                 Zeos Development Group. }\n{********************************************************@}\n\nunit ZSqlUpdate;\n\ninterface\n\n{$I ZComponent.inc}\n\nuses\n  SysUtils, Classes, {$IFDEF MSEgui}mclasses, mdb{$ELSE}DB{$ENDIF},\n  ZDbcIntfs, ZDbcCachedResultSet, ZDbcCache, ZSqlStrings;\n\ntype\n  {ADDED BY fduenas}\n  TZBeforeSQLStatementEvent = procedure(const Sender: TObject;\n    StatementIndex: Integer; out Execute: Boolean ) of object;\n\n  TZAfterSQLStatementEvent = procedure(const Sender: TObject;\n    StatementIndex: Integer) of object;\n\n  TZAfterInsertSQLStatementEvent = procedure(const Sender: TObject;\n    StatementIndex: Integer; out UpdateAutoIncFields: Boolean ) of object;\n\n  {**\n    Implements an object which manages SQL DML statements to update TDatasets.\n  }\n  TZUpdateSQL = class(TComponent, IZCachedResolver)\n  private\n    FDataSet: TDataSet;\n\n    FDeleteSQL: TZSQLStrings;\n    FInsertSQL: TZSQLStrings;\n    FModifySQL: TZSQLStrings;\n    //FOSPATCH\n    FRefreshSQL: TZSQLStrings;\n    //FOSPATCH\n\n    FParamCheck: Boolean;\n    FParams: TParams;\n    FMultiStatements: Boolean;\n    FBeforeDeleteSQL: TNotifyEvent;\n    FBeforeInsertSQL: TNotifyEvent;\n    FBeforeModifySQL: TNotifyEvent;\n    FAfterDeleteSQL: TNotifyEvent;\n    FAfterInsertSQL: TNotifyEvent;\n    FAfterModifySQL: TNotifyEvent;\n    FUseSequenceFieldForRefreshSQL: Boolean;\n    {New Statement Events added by Fduenas}\n    FBeforeDeleteSQLStatement: TZBeforeSQLStatementEvent;\n    FAfterDeleteSQLStatement: TZAfterSQLStatementEvent;\n    FBeforeInsertSQLStatement: TZBeforeSQLStatementEvent;\n    FAfterInsertSQLStatement: TZAfterInsertSQLStatementEvent;\n    FBeforeModifySQLStatement: TZBeforeSQLStatementEvent;\n    FAfterModifySQLStatement: TZAfterSQLStatementEvent;\n\n    procedure SetUseSequenceFieldForRefreshSQL(const Value: Boolean);\n    procedure SetDataset(Value: TDataset);\n    function GetSQL(UpdateKind: TUpdateKind): TStrings;\n    procedure SetSQL(UpdateKind: TUpdateKind; Value: TStrings);\n    function GetParamsCount: Word;\n    procedure SetParamsList(Value: TParams);\n    procedure SetParamCheck(Value: Boolean);\n    procedure SetMultiStatements(Value: Boolean);\n\n    function GetDeleteSQL: TStrings;\n    procedure SetDeleteSQL(Value: TStrings);\n    function GetInsertSQL: TStrings;\n    procedure SetInsertSQL(Value: TStrings);\n    function GetModifySQL: TStrings;\n    procedure SetModifySQL(Value: TStrings);\n\n    //FOSPATCH\n    function GetRefreshSQL: TStrings;\n    procedure SetRefreshSQL(Value: TStrings);\n    //FOSPATCH\n\n    procedure ReadParamData(Reader: TReader);\n    procedure WriteParamData(Writer: TWriter);\n\n\n  protected\n    procedure Apply_RefreshResultSet(const Sender:IZCachedResultSet;const RefreshResultSet: IZResultSet;const RefreshRowAccessor:TZRowAccessor);\n\n    procedure DefineProperties(Filer: TFiler); override;\n    procedure CalculateDefaults(Sender: IZCachedResultSet;\n      RowAccessor: TZRowAccessor);\n    procedure PostUpdates(Sender: IZCachedResultSet; UpdateType: TZRowUpdateType;\n      OldRowAccessor, NewRowAccessor: TZRowAccessor);\n    {BEGIN of PATCH [1185969]: Do tasks after posting updates. ie: Updating AutoInc fields in MySQL }\n    procedure UpdateAutoIncrementFields(Sender: IZCachedResultSet; UpdateType: TZRowUpdateType;\n      OldRowAccessor, NewRowAccessor: TZRowAccessor; Resolver: IZCachedResolver);\n    {END of PATCH [1185969]: Do tasks after posting updates. ie: Updating AutoInc fields in MySQL }\n\n    procedure RefreshCurrentRow(Sender: IZCachedResultSet;RowAccessor: TZRowAccessor);//FOS+ 07112006\n\n    procedure Rebuild(SQLStrings: TZSQLStrings);\n    procedure RebuildAll;\n    procedure FillStatement(ResultSet: IZCachedResultSet;\n      Statement: IZPreparedStatement; Config: TZSQLStatement;\n      OldRowAccessor, NewRowAccessor: TZRowAccessor);\n    procedure UpdateParams(Sender: TObject);\n\n    procedure DoBeforeDeleteSQL;\n    procedure DoBeforeInsertSQL;\n    procedure DoBeforeModifySQL;\n    procedure DoAfterDeleteSQL;\n    procedure DoAfterInsertSQL;\n    procedure DoAfterModifySQL;\n\n    procedure DoBeforeDeleteSQLStatement(const Sender: TObject;\n      StatementIndex: Integer; out Execute: Boolean);\n    procedure DoBeforeInsertSQLStatement(const Sender: TObject;\n      StatementIndex: Integer; out Execute: Boolean);\n    procedure DoBeforeModifySQLStatement(const Sender: TObject;\n      StatementIndex: Integer; out Execute: Boolean);\n    procedure DoAfterDeleteSQLStatement(const Sender: TObject;\n      StatementIndex: Integer);\n    procedure DoAfterInsertSQLStatement(const Sender: TObject;\n      StatementIndex: Integer; out UpdateAutoIncFields: Boolean) ;\n    procedure DoAfterModifySQLStatement(const Sender: TObject;\n      StatementIndex: Integer);\n  public\n    constructor Create(AOwner: TComponent); override;\n    destructor Destroy; override;\n\n    property SQL[UpdateKind: TUpdateKind]: TStrings read GetSQL write SetSQL;\n    property ParamCount: Word read GetParamsCount;\n    property DataSet: TDataSet read FDataSet write SetDataSet;\n\n  published\n    property DeleteSQL: TStrings read GetDeleteSQL write SetDeleteSQL;\n    property InsertSQL: TStrings read GetInsertSQL write SetInsertSQL;\n    property ModifySQL: TStrings read GetModifySQL write SetModifySQL;\n    //FOSPATCH\n    property RefreshSQL: TStrings read GetRefreshSQL write SetRefreshSQL;\n    //FOSPATCH\n    property UseSequenceFieldForRefreshSQL:Boolean read FUseSequenceFieldForRefreshSQL write SetUseSequenceFieldForRefreshSQL;\n\n\n    property Params: TParams read FParams write SetParamsList stored False;\n    property ParamCheck: Boolean read FParamCheck write SetParamCheck default True;\n    property MultiStatements: Boolean read FMultiStatements write SetMultiStatements default True;\n\n    property BeforeDeleteSQL: TNotifyEvent\n      read FBeforeDeleteSQL write FBeforeDeleteSQL;\n    property BeforeInsertSQL: TNotifyEvent\n      read FBeforeInsertSQL write FBeforeInsertSQL;\n    property BeforeModifySQL: TNotifyEvent\n      read FBeforeModifySQL write FBeforeModifySQL;\n    property AfterDeleteSQL: TNotifyEvent\n      read FAfterDeleteSQL write FAfterDeleteSQL;\n    property AfterInsertSQL: TNotifyEvent\n      read FAfterInsertSQL write FAfterInsertSQL;\n    property AfterModifySQL: TNotifyEvent\n      read FAfterModifySQL write FAfterModifySQL;\n\n    {New Events Fired by executed Statement}\n    property BeforeDeleteSQLStatement: TZBeforeSQLStatementEvent\n      read FBeforeDeleteSQLStatement write FBeforeDeleteSQLStatement;\n    property BeforeInsertSQLStatement: TZBeforeSQLStatementEvent\n      read FBeforeInsertSQLStatement write FBeforeInsertSQLStatement;\n    property BeforeModifySQLStatement: TZBeforeSQLStatementEvent\n      read FBeforeModifySQLStatement write FBeforeModifySQLStatement;\n    property AfterDeleteSQLStatement: TZAfterSQLStatementEvent\n      read FAfterDeleteSQLStatement write FAfterDeleteSQLStatement;\n    property AfterInsertSQLStatement: TZAfterInsertSQLStatementEvent\n      read FAfterInsertSQLStatement write FAfterInsertSQLStatement;\n    property AfterModifySQLStatement: TZAfterSQLStatementEvent\n      read FAfterModifySQLStatement write FAfterModifySQLStatement;\n  end;\n\nimplementation\n\nuses ZGenericSqlToken, ZDatasetUtils, ZAbstractRODataset,ZAbstractDataset,\n  ZSysUtils, ZDbcUtils,ZMessages;\n\n{ TZUpdateSQL }\n\n{**\n  Constructs this object and assignes main properties.\n  @param AOwner a component owner.\n}\nconstructor TZUpdateSQL.Create(AOwner: TComponent);\nbegin\n  inherited Create(AOwner);\n\n  FDeleteSQL := TZSQLStrings.Create;\n  FDeleteSQL.OnChange := UpdateParams;\n  FInsertSQL := TZSQLStrings.Create;\n  FInsertSQL.OnChange := UpdateParams;\n  FModifySQL := TZSQLStrings.Create;\n  FModifySQL.OnChange := UpdateParams;\n\n//FOSPATCH\n  FRefreshSQL := TZSQLStrings.Create;\n  FRefreshSQL.OnChange:= UpdateParams;\n//FOSPATCH\n\n  FParams := TParams.Create(Self);\n  FParamCheck := True;\n  FMultiStatements := True;\nend;\n\n{**\n  Destroys this object and cleanups the memory.\n}\ndestructor TZUpdateSQL.Destroy;\nbegin\n  FParams.Free;\n  FDeleteSQL.Free;\n  FInsertSQL.Free;\n  FModifySQL.Free;\n  FRefreshSQL.Free;\n  \n  inherited Destroy;\nend;\n\n{**\n  Store the related dataset object for update sql editor\n}\nprocedure TZUpdateSQL.SetDataset(Value: TDataset);\nbegin\n  FDataSet := Value;\n  FDeleteSQL.Dataset := Value;\n  FInsertSQL.Dataset := Value;\n  FModifySQL.Dataset := Value;\nend;\n\n{**\n  Gets a DML statements for specified action.\n  @param UpdateKind a type of the DML statements.\n  @return a stored DML statement.\n}\nfunction TZUpdateSQL.GetSQL(UpdateKind: TUpdateKind): TStrings;\nbegin\n  case UpdateKind of\n    ukModify: Result := FModifySQL;\n    ukInsert: Result := FInsertSQL;\n  else\n    Result := FDeleteSQL;\n  end;\nend;\n\n{**\n  Sets a DML statements for specified action.\n  @param UpdateKind a type of the DML statements.\n  @param Value a DML statements to be set.\n}\nprocedure TZUpdateSQL.SetSQL(UpdateKind: TUpdateKind; Value: TStrings);\nbegin\n  case UpdateKind of\n    ukModify: FModifySQL.Assign(Value);\n    ukInsert: FInsertSQL.Assign(Value);\n    ukDelete: FDeleteSQL.Assign(Value);\n  end;\nend;\n\n{**\n  Get parameters count.\n  @return a parameters count.\n}\nfunction TZUpdateSQL.GetParamsCount: Word;\nbegin\n  Result := FParams.Count;\nend;\n\nfunction TZUpdateSQL.GetRefreshSQL: TStrings;\nbegin\n  Result := FRefreshSQL;\nend;\n\n{**\n  Sets parameters checking flag.\n  @param Value a new parameters checking flag.\n}\nprocedure TZUpdateSQL.SetParamCheck(Value: Boolean);\nbegin\n  if FParamCheck <> Value then\n  begin\n    FParamCheck := Value;\n    FModifySQL.ParamCheck := Value;\n    FInsertSQL.ParamCheck := Value;\n    FDeleteSQL.ParamCheck := Value;\n    RebuildAll;\n  end;\nend;\n\n{**\n  Sets multiple statements flag.\n  @param Value a new multiple statements flag.\n}\nprocedure TZUpdateSQL.SetMultiStatements(Value: Boolean);\nbegin\n  if FMultiStatements <> Value then\n  begin\n    FMultiStatements := Value;\n    FModifySQL.MultiStatements := Value;\n    FInsertSQL.MultiStatements := Value;\n    FDeleteSQL.MultiStatements := Value;\n    RebuildAll;\n  end;\nend;\n\n{**\n  Set a new list of SQL parameters.\n  @param Value a new list of SQL parameters.\n}\nprocedure TZUpdateSQL.SetParamsList(Value: TParams);\nbegin\n  FParams.AssignValues(Value);\nend;\n\nprocedure TZUpdateSQL.SetRefreshSQL(Value: TStrings);\nbegin\n  FRefreshSQL.Assign(Value);\nend;\n\nprocedure TZUpdateSQL.SetUseSequenceFieldForRefreshSQL(const Value: Boolean);\nbegin\n  FUseSequenceFieldForRefreshSQL := Value;\nend;\n\n{**\n  Defines a persistent dataset properties.\n  @param Filer a persistent manager object.\n}\nprocedure TZUpdateSQL.DefineProperties(Filer: TFiler);\n\n  function WriteData: Boolean;\n  begin\n    if Filer.Ancestor <> nil then\n      Result := not FParams.IsEqual(TZUpdateSQL(Filer.Ancestor).FParams)\n    else\n      Result := FParams.Count > 0;\n  end;\n\nbegin\n  inherited DefineProperties(Filer);\n  Filer.DefineProperty('ParamData', ReadParamData, WriteParamData, WriteData);\nend;\n\n{**\n  Reads parameter data from persistent storage.\n  @param Reader an input data stream.\n}\nprocedure TZUpdateSQL.ReadParamData(Reader: TReader);\nbegin\n  Reader.ReadValue;\n  Reader.ReadCollection(FParams);\nend;\n\n{**\n  Writes parameter data from persistent storage.\n  @param Writer an output data stream.\n}\nprocedure TZUpdateSQL.WriteParamData(Writer: TWriter);\nbegin\n  Writer.WriteCollection(Params);\nend;\n\n{**\n  Gets strings with Delete statements.\n  @return strings with Delete statements.\n}\nfunction TZUpdateSQL.GetDeleteSQL: TStrings;\nbegin\n  Result := FDeleteSQL;\nend;\n\n{**\n  Sets a new Delete SQL statement.\n  @param Value a new Delete SQL statement.\n}\nprocedure TZUpdateSQL.SetDeleteSQL(Value: TStrings);\nbegin\n  FDeleteSQL.Assign(Value);\nend;\n\n{**\n  Gets strings with Insert statements.\n  @return strings with Insert statements.\n}\nfunction TZUpdateSQL.GetInsertSQL: TStrings;\nbegin\n  Result := FInsertSQL;\nend;\n\n{**\n  Sets a new Insert SQL statement.\n  @param Value a new Insert SQL statement.\n}\nprocedure TZUpdateSQL.SetInsertSQL(Value: TStrings);\nbegin\n  FInsertSQL.Assign(Value);\nend;\n\n{**\n  Gets strings with Modify statements.\n  @return strings with Modify statements.\n}\nfunction TZUpdateSQL.GetModifySQL: TStrings;\nbegin\n  Result := FModifySQL;\nend;\n\n{**\n  Sets a new  Modify SQL statement.\n  @param Value a new Modify SQL statement.\n}\nprocedure TZUpdateSQL.SetModifySQL(Value: TStrings);\nbegin\n  FModifySQL.Assign(Value);\nend;\n\n{**\n  Updates all parameters.\n  @param Sender an event sender object.\n}\nprocedure TZUpdateSQL.UpdateParams(Sender: TObject);\nbegin\n  RebuildAll;\nend;\n\n{**\n  Rebuilds parameters and inserts a new one from specified sql statements.\n  @param SQLStrings a strings with SQL statements.\n}\nprocedure TZUpdateSQL.Rebuild(SQLStrings: TZSQLStrings);\nvar\n  I: Integer;\nbegin\n  for I := 0 to SQLStrings.ParamCount - 1 do\n  begin\n    if FParams.FindParam(SQLStrings.ParamNames[I]) = nil then\n      FParams.CreateParam(ftUnknown, SQLStrings.ParamNames[I], ptUnknown);\n  end;\nend;\n\n{**\n  Rebuilds all internal structures including parameters from SQL statements.\n}\nprocedure TZUpdateSQL.RebuildAll;\nvar\n  OldParams: TParams;\nbegin\n  OldParams := TParams.Create;\n  OldParams.Assign(FParams);\n  FParams.Clear;\n  try\n    Rebuild(FModifySQL);\n    Rebuild(FInsertSQL);\n    Rebuild(FDeleteSQL);\n//FOSPATCH\n    Rebuild(FRefreshSQL);\n//FOSPATCH\n    FParams.AssignValues(OldParams);\n  finally\n    OldParams.Free;\n  end;\nend;\n\nprocedure TZUpdateSQL.RefreshCurrentRow(Sender: IZCachedResultSet; RowAccessor: TZRowAccessor);\nvar\n    Config: TZSQLStrings;\n    Statement: IZPreparedStatement;\n    RefreshResultSet: IZResultSet;\nbegin\n Config:=FRefreshSQL;\n if CONFIG.StatementCount=1 then\n begin\n  Statement := Sender.GetStatement.GetConnection.PrepareStatement(Config.Statements[0].SQL);\n  FillStatement(Sender, Statement, Config.Statements[0],RowAccessor, RowAccessor);\n  RefreshResultSet:=Statement.ExecuteQueryPrepared;\n  Apply_RefreshResultSet(Sender,RefreshResultSet,RowAccessor);\n end;\nend;\n\n{**\n  Fills the specified statement with stored or given parameters.\n  @param ResultSet a source result set object.\n  @param Statement a DBC statement object.\n  @param Config a SQLStatement configuration.\n  @param OldRowAccessor an accessor object to old column values.\n  @param NewRowAccessor an accessor object to new column values.\n}\nprocedure TZUpdateSQL.FillStatement(ResultSet: IZCachedResultSet;\n  Statement: IZPreparedStatement; Config: TZSQLStatement;\n  OldRowAccessor, NewRowAccessor: TZRowAccessor);\nvar\n  I, ColumnIndex: Integer;\n  ParamValue: TParam;\n  ParamName: string;\n  OldParam: Boolean;\n  WasNull: Boolean;\n  RowAccessor: TZRowAccessor;\n  TempBlob: IZBlob;\nbegin\n  WasNull := False;\n  for I := 0 to Config.ParamCount - 1 do\n  begin\n    ParamValue := Params.FindParam(Config.ParamNames[I]);\n    ParamName := Config.ParamNames[I];\n    OldParam := False;{Seqparam:=False;}\n    if StrLIComp(PChar(ParamName), 'NEW_', 4) = 0 then\n    begin\n      ParamName := Copy(ParamName, 5, Length(ParamName) - 4)\n    end\n    else if StrLIComp(PChar(ParamName), 'OLD_', 4) = 0 then\n    begin\n      ParamName := Copy(ParamName, 5, Length(ParamName) - 4);\n      OldParam := True;\n    end;\n\n    ColumnIndex := ResultSet.FindColumn(ParamName);\n    if ColumnIndex > 0 then\n    begin\n      if OldParam then\n        RowAccessor := OldRowAccessor\n      else\n        RowAccessor := NewRowAccessor;\n\n      if StrToBoolEx(DefineStatementParameter(\n        ResultSet.GetStatement, 'defaults', 'true')) then\n        Statement.SetDefaultValue(I + 1,\n          ResultSet.GetMetadata.GetDefaultValue(ColumnIndex));\n\n      case ResultSet.GetMetadata.GetColumnType(ColumnIndex) of\n        stBoolean:\n          Statement.SetBoolean(I + 1,\n            RowAccessor.GetBoolean(ColumnIndex, WasNull));\n        stByte:\n          Statement.SetByte(I + 1, RowAccessor.GetByte(ColumnIndex, WasNull));\n        stShort:\n          Statement.SetShort(I + 1, RowAccessor.GetShort(ColumnIndex, WasNull));\n        stInteger:\n          Statement.SetInt(I + 1, RowAccessor.GetInt(ColumnIndex, WasNull));\n        stLong:\n          Statement.SetLong(I + 1, RowAccessor.GetLong(ColumnIndex, WasNull));\n        stFloat:\n          Statement.SetFloat(I + 1, RowAccessor.GetFloat(ColumnIndex, WasNull));\n        stDouble:\n          Statement.SetDouble(I + 1, RowAccessor.GetDouble(ColumnIndex, WasNull));\n        stBigDecimal:\n          Statement.SetBigDecimal(I + 1,\n            RowAccessor.GetBigDecimal(ColumnIndex, WasNull));\n        stString:\n          Statement.SetString(I + 1, RowAccessor.GetString(ColumnIndex, WasNull)); //smells like DataLoss\n        stUnicodeString:\n          Statement.SetUnicodeString(I + 1, RowAccessor.GetUnicodeString(ColumnIndex, WasNull));\n        stBytes:\n          Statement.SetBytes(I + 1, RowAccessor.GetBytes(ColumnIndex, WasNull));\n        stDate:\n          Statement.SetDate(I + 1, RowAccessor.GetDate(ColumnIndex, WasNull));\n        stTime:\n          Statement.SetTime(I + 1, RowAccessor.GetTime(ColumnIndex, WasNull));\n        stTimestamp:\n          Statement.SetTimestamp(I + 1,\n            RowAccessor.GetTimestamp(ColumnIndex, WasNull));\n        stAsciiStream:\n          begin\n            TempBlob := RowAccessor.GetBlob(ColumnIndex, WasNull);\n            if not TempBlob.IsEmpty then\n              Statement.SetBlob(I + 1, stAsciiStream, TempBlob)\n            else\n              Statement.SetNull(I + 1, stAsciiStream);\n          end;\n        stUnicodeStream:\n          begin\n            TempBlob := RowAccessor.GetBlob(ColumnIndex, WasNull);\n            if not TempBlob.IsEmpty then\n              Statement.SetBlob(I + 1, stUnicodeStream, TempBlob)\n            else\n              Statement.SetNull(I + 1, stUnicodeStream);\n          end;\n        stBinaryStream:\n          begin\n            TempBlob := RowAccessor.GetBlob(ColumnIndex, WasNull);\n            if not TempBlob.IsEmpty then\n              Statement.SetBlob(I + 1, stBinaryStream, TempBlob)\n            else\n              Statement.SetNull(I + 1, stBinaryStream);\n          end;\n      end;\n      if WasNull then\n      begin\n        Statement.SetNull(I + 1,\n          ResultSet.GetMetadata.GetColumnType(ColumnIndex))\n      end;\n    end\n    else\n      SetStatementParam(I+1, Statement, ParamValue);\n  end;\nend;\n\n{**\n  Apply the Refreshed values.\n  @param RefreshResultSet a result set object.\n  @param RefreshRowAccessor an accessor object to column values.\n}\n\nprocedure TZUpdateSQL.Apply_RefreshResultSet(const Sender:IZCachedResultSet;\n  const RefreshResultSet: IZResultSet; const RefreshRowAccessor: TZRowAccessor);\nvar\n    I: Integer;\n    RefreshColumnIndex:integer;\n    RefreshColumnName:String;\n    RefreshColumnType:TZSQLType;\n\nbegin\n    if Assigned(RefreshResultSet) then begin\n      if not RefreshResultSet.First then begin\n        raise EZDatabaseError.Create(SUpdateSQLNoResult);\n      end;\n      for I := 1 to RefreshResultSet.GetMetadata.GetColumnCount do begin\n        RefreshColumnName:=RefreshResultSet.GetMetadata.GetColumnLabel(I); // What Column from Resultset should be updated\n        RefreshColumnIndex := Sender.FindColumn(RefreshColumnName); // Is the Column available in the select ?\n        if RefreshColumnIndex=0 then begin\n          continue; // Column not found in Select from Dataset\n        end;\n        if RefreshResultSet.IsNull(I) then begin\n          RefreshRowAccessor.SetNull(RefreshColumnIndex);\n        end else begin\n          RefreshColumnType  := RefreshResultSet.GetMetadata.GetColumnType(I); // Type of Column ?\n          case RefreshColumnType of\n            stBoolean: RefreshRowAccessor.SetBoolean(RefreshColumnIndex, RefreshResultSet.GetBoolean(I));\n            stByte: RefreshRowAccessor.SetByte(RefreshColumnIndex, RefreshResultSet.GetByte(I));\n            stShort: RefreshRowAccessor.SetShort(RefreshColumnIndex, RefreshResultSet.GetShort(I));\n            stInteger: RefreshRowAccessor.SetInt(RefreshColumnIndex, RefreshResultSet.GetInt(I));\n            stLong: RefreshRowAccessor.SetLong(RefreshColumnIndex, RefreshResultSet.GetLong(I));\n            stFloat: RefreshRowAccessor.SetFloat(RefreshColumnIndex, RefreshResultSet.GetFloat(I));\n            stDouble: RefreshRowAccessor.SetDouble(RefreshColumnIndex, RefreshResultSet.GetDouble(I));\n            stBigDecimal: RefreshRowAccessor.SetBigDecimal(RefreshColumnIndex, RefreshResultSet.GetBigDecimal(I));\n               // gto: do we need PChar here?\n\t\t\t   //stString: RefreshRowAccessor.SetPChar(RefreshColumnIndex, RefreshResultSet.GetPChar(I));\n\t\t\t      stString: RefreshRowAccessor.SetString(RefreshColumnIndex, String(RefreshResultSet.GetString(I)));\n            stUnicodeString: RefreshRowAccessor.SetUnicodeString(RefreshColumnIndex, RefreshResultSet.GetUnicodeString(I));\n            stBytes: RefreshRowAccessor.SetBytes(RefreshColumnIndex, RefreshResultSet.GetBytes(I));\n            stDate: RefreshRowAccessor.SetDate(RefreshColumnIndex, RefreshResultSet.GetDate(I));\n            stTime: RefreshRowAccessor.SetTime(RefreshColumnIndex, RefreshResultSet.GetTime(I));\n            stTimestamp: RefreshRowAccessor.SetTimestamp(RefreshColumnIndex, RefreshResultSet.GetTimestamp(I));\n            stAsciiStream, stUnicodeStream, stBinaryStream:RefreshRowAccessor.SetBlob(RefreshColumnIndex, RefreshResultSet.GetBlob(I));\n          end;\n        end;\n      end;\n    end;\nend;\n{**\n  Calculate default values for the fields.\n  @param Sender a cached result set object.\n  @param RowAccessor an accessor object to column values.\n}\n\nprocedure TZUpdateSQL.CalculateDefaults(Sender: IZCachedResultSet;\n  RowAccessor: TZRowAccessor);\nbegin\n {BEGIN PATCH [1214009] TZUpdateSQL - implemented feature to Calculate default values}\n Sender.GetNativeResolver.CalculateDefaults(Sender, RowAccessor);\n {END PATCH [1214009] TZUpdateSQL - implemented feature to Calculate default values}\nend;\n\n{**\n  Posts updates to database.\n  @param Sender a cached result set object.\n  @param UpdateType a type of updates.\n  @param OldRowAccessor an accessor object to old column values.\n  @param NewRowAccessor an accessor object to new column values.\n}\nprocedure TZUpdateSQL.PostUpdates(Sender: IZCachedResultSet;\n UpdateType: TZRowUpdateType; OldRowAccessor, NewRowAccessor: TZRowAccessor);\nvar\n    I: Integer;\n    Statement: IZPreparedStatement;\n    Config: TZSQLStrings;\n    CalcDefaultValues,\n    ExecuteStatement,\n    UpdateAutoIncFields: Boolean;\n    Refresh_OldSQL:String;\n    RefreshResultSet: IZResultSet;\n    lValidateUpdateCount : Boolean;\n    lUpdateCount : Integer;\nbegin\n  if (UpdateType = utDeleted)\n    and (OldRowAccessor.RowBuffer.UpdateType = utInserted) then\n    Exit;\n\n  case UpdateType of\n    utInserted:\n      Config := FInsertSQL;\n    utDeleted:\n      Config := FDeleteSQL;\n    utModified:\n      Config := FModifySQL;\n    else\n      Exit;\n  end;\n\n  case UpdateType of\n    utInserted:\n      DoBeforeInsertSQL;\n    utDeleted:\n      DoBeforeDeleteSQL;\n    utModified:\n      DoBeforeModifySQL;\n  end;\n\n  if Dataset is TZAbstractRODataset then\n    (Dataset as TZAbstractRODataset).Connection.ShowSqlHourGlass;\n  CalcDefaultValues :=\n    ZSysUtils.StrToBoolEx(DefineStatementParameter(Sender.GetStatement,'defaults','true'));\n  try\n    for I := 0 to Config.StatementCount - 1 do\n    begin\n      Statement := Sender.GetStatement.GetConnection.\n        PrepareStatement(Config.Statements[I].SQL);\n      FillStatement(Sender, Statement, Config.Statements[I],\n        OldRowAccessor, NewRowAccessor);\n      {BEGIN of PATCH [1185969]: Do tasks after posting updates. ie: Updating AutoInc fields in MySQL }\n      {Update AutoInc Field Tasks will be only executed if the UpdateAutoIncFields\n       in the AfterInsertSQLStatement event returns true\n      }\n      ExecuteStatement := true;\n      UpdateAutoIncFields := false;\n      case UpdateType of\n           utDeleted:\n             DoBeforeDeleteSQLStatement(Self, I, ExecuteStatement);\n           utInserted:\n             DoBeforeInsertSQLStatement(Self, I, ExecuteStatement);\n           utModified:\n             DoBeforeModifySQLStatement(Self, I, ExecuteStatement);\n      end;\n      if ExecuteStatement then\n      begin\n        lValidateUpdateCount := StrToBoolEx( \n          Sender.GetStatement.GetParameters.Values['ValidateUpdateCount']); \n\n        lUpdateCount := Statement.ExecuteUpdatePrepared; \n        if  (lValidateUpdateCount) and (lUpdateCount <> 1) then \n          raise EZSQLException.Create(Format(SInvalidUpdateCount, [lUpdateCount]));\n\n       case UpdateType of\n            utDeleted:\n              DoAfterDeleteSQLStatement(Self, I);\n            utInserted:\n              begin\n               DoAfterInsertSQLStatement(Self, I, UpdateAutoIncFields);\n               if CalcDefaultValues and UpdateAutoIncFields then\n                  UpdateAutoIncrementFields(Sender, UpdateType,\n                                            OldRowAccessor, NewRowAccessor, Self);\n              end;\n            utModified:\n              DoAfterModifySQLStatement(Self,I);\n       end;\n      end;\n      {END of PATCH [1185969]: Do tasks after posting updates. ie: Updating AutoInc fields in MySQL }\n    end;\n//FOSPATCH\n    case UpdateType of\n      utInserted,utModified: begin\n       if FRefreshSql.Text<>'' then begin\n        Refresh_OldSQL:=FRefreshSql.Text;\n        try\n         Config:=FRefreshSQL;\n         if UpdateType=utInserted then begin\n          if Dataset is TZAbstractDataset then begin\n           if FUseSequenceFieldForRefreshSQL then begin\n            if assigned(TZAbstractDataset(DataSet).Sequence) and (TZAbstractDataset(DataSet).SequenceField<>'') then begin\n             Config.Text :=\n               StringReplace(UpperCase(Config.Text),\n                 ':OLD_'+UpperCase(TZAbstractDataset(DataSet).SequenceField),\n                 TZAbstractDataset(DataSet).Sequence.GetCurrentValueSQL,[rfReplaceAll]);\n            end;\n           end;\n          end;\n         end;\n         if CONFIG.StatementCount=1 then begin\n          Statement := Sender.GetStatement.GetConnection.PrepareStatement(Config.Statements[0].SQL);\n          FillStatement(Sender, Statement, Config.Statements[0],OldRowAccessor, NewRowAccessor);\n          RefreshResultSet:=Statement.ExecuteQueryPrepared;\n          Apply_RefreshResultSet(Sender,RefreshResultSet,NewRowAccessor);\n         end;\n        finally\n         FRefreshSQL.Text:=Refresh_OldSQL;\n        end;\n      end;\n    end;\n  end;\n//FOSPATCH\n\n  finally\n    if Dataset is TZAbstractRODataset then\n      (Dataset as TZAbstractRODataset).Connection.HideSQLHourGlass;\n  end;\n\n  case UpdateType of\n    utInserted:\n      DoAfterInsertSQL;\n    utDeleted:\n      DoAfterDeleteSQL;\n    utModified:\n      DoAfterModifySQL;\n  end;\nend;\n\n{**\n  Fires an event before delete Statement\n}\nprocedure TZUpdateSQL.DoBeforeDeleteSQL;\nbegin\n  if Assigned(FBeforeDeleteSQL) then\n    FBeforeDeleteSQL(Self);\nend;\n\n{**\n  Fires an event before insert Statement\n}\nprocedure TZUpdateSQL.DoBeforeInsertSQL;\nbegin\n  if Assigned(BeforeInsertSQL) then\n    FBeforeInsertSQL(Self);\nend;\n\n{**\n  Fires an event before modify Statement\n}\nprocedure TZUpdateSQL.DoBeforeModifySQL;\nbegin\n  if Assigned(FBeforeModifySQL) then\n    FBeforeModifySQL(Self);\nend;\n\n{**\n  Fires an event after delete Statement\n}\nprocedure TZUpdateSQL.DoAfterDeleteSQL;\nbegin\n  if Assigned(FAfterDeleteSQL) then\n    FAfterDeleteSQL(Self);\nend;\n\n{**\n  Fires an event after insert Statement\n}\nprocedure TZUpdateSQL.DoAfterInsertSQL;\nbegin\n  if Assigned(FAfterInsertSQL) then\n    FAfterInsertSQL(Self);\nend;\n\n{**\n  Fires an event after modify Statement\n}\nprocedure TZUpdateSQL.DoAfterModifySQL;\nbegin\n  if Assigned(FAfterModifySQL) then\n    FAfterModifySQL(Self);\nend;\n\n{BEGIN of PATCH [1185969]: Do tasks after posting updates. ie: Updating AutoInc fields in MySQL }\nprocedure TZUpdateSQL.UpdateAutoIncrementFields(Sender: IZCachedResultSet;\n  UpdateType: TZRowUpdateType; OldRowAccessor,\n  NewRowAccessor: TZRowAccessor; Resolver: IZCachedResolver);\nbegin\n with Sender.GetNativeResolver do\n begin\n  UpdateAutoIncrementFields(Sender, UpdateType,\n   OldRowAccessor, NewRowAccessor, Resolver);\n end;\nend;\n{END of PATCH [1185969]: Do tasks after posting updates. ie: Updating AutoInc fields in MySQL }\n\n{NEW Methods for Events to validate at Statement level }\nprocedure TZUpdateSQL.DoAfterDeleteSQLStatement(const Sender: TObject;\n  StatementIndex: Integer);\nbegin\n if Assigned(FAfterDeleteSQLStatement) then\n    FAfterDeleteSQLStatement(Self, StatementIndex);\nend;\n\nprocedure TZUpdateSQL.DoAfterInsertSQLStatement(const Sender: TObject;\n  StatementIndex: Integer; out UpdateAutoIncFields: Boolean);\nbegin\n if Assigned(FAfterInsertSQLStatement) then\n    FAfterInsertSQLStatement(Self, StatementIndex, UpdateAutoIncFields);\nend;\n\nprocedure TZUpdateSQL.DoAfterModifySQLStatement(const Sender: TObject;\n  StatementIndex: Integer);\nbegin\n if Assigned(FAfterModifySQLStatement) then\n    FAfterModifySQLStatement(Self, StatementIndex);\nend;\n\nprocedure TZUpdateSQL.DoBeforeDeleteSQLStatement(const Sender: TObject;\n  StatementIndex: Integer; out Execute: Boolean);\nbegin\n if Assigned(FBeforeDeleteSQLStatement) then\n    FBeforeDeleteSQLStatement(Self, StatementIndex, Execute);\nend;\n\nprocedure TZUpdateSQL.DoBeforeInsertSQLStatement(const Sender: TObject;\n  StatementIndex: Integer; out Execute: Boolean);\nbegin\n if Assigned(FBeforeInsertSQLStatement) then\n    FBeforeInsertSQLStatement(Self, StatementIndex, Execute);\nend;\n\nprocedure TZUpdateSQL.DoBeforeModifySQLStatement(const Sender: TObject;\n  StatementIndex: Integer; out Execute: Boolean);\nbegin\n if Assigned(FBeforeModifySQLStatement) then\n    FBeforeModifySQLStatement(Self, StatementIndex, Execute);\nend;\n\nend.\n"
  },
  {
    "path": "lib/zeosdbo/src/component/ZStoredProcedure.pas",
    "content": "{*********************************************************}\n{                                                         }\n{                 Zeos Database Objects                   }\n{              Abstract StoredProc component              }\n{                                                         }\n{        Originally written by Sergey Seroukhov           }\n{                            & Janos Fegyverneki          }\n{                                                         }\n{*********************************************************}\n\n{@********************************************************}\n{    Copyright (c) 1999-2012 Zeos Development Group       }\n{                                                         }\n{ License Agreement:                                      }\n{                                                         }\n{ This library is distributed in the hope that it will be }\n{ useful, but WITHOUT ANY WARRANTY; without even the      }\n{ implied warranty of MERCHANTABILITY or FITNESS FOR      }\n{ A PARTICULAR PURPOSE.  See the GNU Lesser General       }\n{ Public License for more details.                        }\n{                                                         }\n{ The source code of the ZEOS Libraries and packages are  }\n{ distributed under the Library GNU General Public        }\n{ License (see the file COPYING / COPYING.ZEOS)           }\n{ with the following  modification:                       }\n{ As a special exception, the copyright holders of this   }\n{ library give you permission to link this library with   }\n{ independent modules to produce an executable,           }\n{ regardless of the license terms of these independent    }\n{ modules, and to copy and distribute the resulting       }\n{ executable under terms of your choice, provided that    }\n{ you also meet, for each linked independent module,      }\n{ the terms and conditions of the license of that module. }\n{ An independent module is a module which is not derived  }\n{ from or based on this library. If you modify this       }\n{ library, you may extend this exception to your version  }\n{ of the library, but you are not obligated to do so.     }\n{ If you do not wish to do so, delete this exception      }\n{ statement from your version.                            }\n{                                                         }\n{                                                         }\n{ The project web site is located on:                     }\n{   http://zeos.firmos.at  (FORUM)                        }\n{   http://sourceforge.net/p/zeoslib/tickets/ (BUGTRACKER)}\n{   svn://svn.code.sf.net/p/zeoslib/code-0/trunk (SVN)    }\n{                                                         }\n{   http://www.sourceforge.net/projects/zeoslib.          }\n{                                                         }\n{                                                         }\n{                                 Zeos Development Group. }\n{********************************************************@}\n\nunit ZStoredProcedure;\n\ninterface\n\n{$I ZComponent.inc}\n\nuses\n  Types, SysUtils, Classes, {$IFDEF MSEgui}mclasses, mdb{$ELSE}DB{$ENDIF},\n  ZDbcIntfs, ZAbstractDataset, ZCompatibility;\n\ntype\n\n  {**\n    Abstract dataset to access to stored procedures.\n  }\n  TZStoredProc = class(TZAbstractDataset)\n  private\n    FMetaResultSet: IZResultset;\n    procedure RetrieveParamValues;\n    function GetStoredProcName: string;\n    procedure SetStoredProcName(const Value: string);\n    function GetParamType(const Value: TZProcedureColumnType): TParamType;\n  protected\n    function CreateStatement(const SQL: string; Properties: TStrings):\n      IZPreparedStatement; override;\n    procedure SetStatementParams(Statement: IZPreparedStatement;\n      ParamNames: TStringDynArray; Params: TParams;\n      DataLink: TDataLink); override;\n    procedure InternalOpen; override;\n    procedure InternalClose; override;\n\n  protected\n  {$IFDEF WITH_IPROVIDER}\n    function PSIsSQLBased: Boolean; override;\n    procedure PSExecute; override;\n    {$IFDEF WITH_IPROVIDERWIDE}\n    function PSGetTableNameW: WideString; override;\n    {$ELSE}\n    function PSGetTableName: string; override;\n    {$ENDIF}\n    procedure PSSetCommandText(const ACommandText: string); override;\n  {$ENDIF}\n\n  public\n    procedure ExecProc; virtual;\n\n    procedure FirstResultSet;\n    procedure PreviousResultSet;\n    procedure NextResultSet;\n    procedure LastResultSet;\n    procedure SetResultSet(const Index: Integer);\n    function ResultSetCount: Integer;\n    function BOR: Boolean;\n    function EOR: Boolean;\n  published\n    property Active;\n    property ParamCheck;\n    property Params;\n    property ShowRecordTypes;\n    property Options;\n    property StoredProcName: string read GetStoredProcName\n      write SetStoredProcName;\n  end;\n\nimplementation\n\nuses\n  ZAbstractRODataset, ZMessages, ZDatasetUtils\n  {$IFDEF WITH_ASBYTES}, ZSysUtils{$ENDIF}\n  {$IFDEF WITH_INLINE_ANSICOMPARETEXT}, Windows{$ENDIF};\n\n{ TZStoredProc }\n\n{**\n  Creates a DBC statement for the query.\n  @param SQL an SQL query.\n  @param Properties a statement specific properties.\n  @returns a created DBC statement.\n}\n{$IFDEF FPC}\n  {$HINTS OFF}\n{$ENDIF}\nfunction TZStoredProc.CreateStatement(const SQL: string; Properties: TStrings):\n  IZPreparedStatement;\nvar\n  I: Integer;\n  CallableStatement: IZCallableStatement;\n  Catalog, Schema, ObjectName: string;\nbegin\n  CallableStatement := Connection.DbcConnection.PrepareCallWithParams(\n    Trim(SQL), Properties);\n\n  CallableStatement.ClearParameters;\n\n  if Supports(CallableStatement, IZParamNamedCallableStatement) then\n    if Assigned(FMetaResultSet) then\n      FMetaResultSet.BeforeFirst\n    else\n    begin //i need allways all types to cast and there names\n      SplitQualifiedObjectName(Trim(SQL), Catalog, Schema, ObjectName);\n      ObjectName := Connection.DbcConnection.GetMetadata.AddEscapeCharToWildcards(ObjectName);\n      FMetaResultSet := Connection.DbcConnection.GetMetadata.GetProcedureColumns(Catalog, Schema, ObjectName, '');\n    end;\n\n  for I := 0 to Params.Count - 1 do\n  begin\n    CallableStatement.RegisterParamType( I+1, ord(Params[I].ParamType));\n\n    if Params[I].ParamType in [ptResult, ptOutput, ptInputOutput] then\n      CallableStatement.RegisterOutParameter(I + 1,\n        Ord(ConvertDatasetToDbcType(Params[I].DataType)));\n\n    if Supports(CallableStatement, IZParamNamedCallableStatement) and\n      Assigned(FMetaResultSet) then\n      if FMetaResultSet.Next then\n        (CallableStatement as IZParamNamedCallableStatement).RegisterParamTypeAndName(\n          I, FMetaResultSet.GetString(7), Params[i].Name, FMetaResultSet.GetInt(8),\n          FMetaResultSet.GetInt(9));\n  end;\n  Result := CallableStatement;\nend;\n{$IFDEF FPC}\n  {$HINTS ON}\n{$ENDIF}\n\n{**\n  Fill prepared statement with parameters.\n  @param Statement a prepared SQL statement.\n  @param ParamNames an array of parameter names.\n  @param Params a collection of SQL parameters.\n  @param DataLink a datalink to get parameters.\n}\n{$IFDEF FPC}\n  {$HINTS OFF}\n{$ENDIF}\nprocedure TZStoredProc.SetStatementParams(Statement: IZPreparedStatement;\n  ParamNames: TStringDynArray; Params: TParams; DataLink: TDataLink);\nvar\n  I: Integer;\n  Param: TParam;\nbegin\n  for I := 0 to Params.Count - 1 do\n  begin\n    Param := Params[I];\n\n    if Params[I].ParamType in [ptResult, ptOutput] then\n     Continue;\n\n    SetStatementParam(I+1, Statement, Param);\n  end;\nend;\n{$IFDEF FPC}\n  {$HINTS ON}\n{$ENDIF}\n\n{**\n  Retrieves parameter values from callable statement.\n}\nprocedure TZStoredProc.RetrieveParamValues;\nvar\n  I: Integer;\n  Param: TParam;\n  FCallableStatement: IZCallableStatement;\n  TempBlob: IZBlob;\nbegin\n  if Assigned(Statement) then\n    Statement.QueryInterface(IZCallableStatement, FCallableStatement);\n  if not Assigned(FCallableStatement) then\n    Exit;\n\n  for I := 0 to Params.Count - 1 do\n  begin\n    Param := Params[I];\n\n    if not (Param.ParamType in [ptResult, ptOutput, ptInputOutput]) then\n      Continue;\n\n    if FCallableStatement.IsNull(I + 1) then\n      Param.Clear\n    else\n      case Param.DataType of\n        ftBoolean:\n          Param.AsBoolean := FCallableStatement.GetBoolean(I + 1);\n        ftSmallInt:\n          Param.AsSmallInt := FCallableStatement.GetShort(I + 1);\n        ftInteger, ftAutoInc:\n          Param.AsInteger := FCallableStatement.GetInt(I + 1);\n        ftFloat:\n          Param.AsFloat := FCallableStatement.GetDouble(I + 1);\n        ftLargeInt:\n          Param.Value := FCallableStatement.GetLong(I + 1);\n        ftString:\n          begin\n            Param.AsString := FCallableStatement.GetString(I + 1);\n            {$IFDEF UNICODE}Param.DataType := ftString;{$ENDIF} //Hack: D12_UP sets ftWideString on assigning a UnicodeString\n          end;\n        ftWideString:\n          {$IFDEF WITH_FTWIDESTRING}Param.AsWideString{$ELSE}Param.Value{$ENDIF} := FCallableStatement.GetUnicodeString(I + 1);\n        ftMemo:\n          begin\n            Param.AsMemo := FCallableStatement.GetString(I + 1);\n            {$IFDEF UNICODE}Param.DataType := ftMemo;{$ENDIF} //Hack: D12_UP sets ftWideMemo on assigning a UnicodeString\n          end;\n        {$IFDEF WITH_WIDEMEMO}\n        ftWideMemo:\n        begin\n          Param.AsWideString := FCallableStatement.GetUnicodeString(I + 1);\n          Param.DataType := ftWideMemo;\n        end;\n        {$ENDIF}\n        ftBytes, ftVarBytes:\n          Param.Value := FCallableStatement.GetBytes(I + 1);\n        ftDate:\n          Param.AsDate := FCallableStatement.GetDate(I + 1);\n        ftTime:\n          Param.AsTime := FCallableStatement.GetTime(I + 1);\n        ftDateTime:\n          Param.AsDateTime := FCallableStatement.GetTimestamp(I + 1);\n        ftBlob:\n          begin\n            TempBlob := FCallableStatement.GetValue(I +1).VInterface as IZBlob;\n            if not TempBlob.IsEmpty then\n              Param.SetBlobData({$IFDEF WITH_TVALUEBUFFER}TValueBuffer{$ENDIF}(TempBlob.GetBuffer), TempBlob.Length);\n            TempBlob := nil;\n          end\n        else\n           raise EZDatabaseError.Create(SUnKnownParamDataType);\n      end;\n  end;\nend;\n\n{**\n  Performs internal query opening.\n}\nprocedure TZStoredProc.InternalOpen;\nbegin\n  inherited InternalOpen;\n\n  RetrieveParamValues;\nend;\n\n{**\n  Performs internal query closing.\n}\nprocedure TZStoredProc.InternalClose;\nbegin\n  inherited InternalClose;\nend;\n\nfunction TZStoredProc.GetStoredProcName: string;\nbegin\n  Result := Trim(SQL.Text);\nend;\n\n{$IFDEF FPC}\n  {$HINTS OFF}\n{$ENDIF}\nprocedure TZStoredProc.SetStoredProcName(const Value: string);\nvar\n  OldParams: TParams;\n  Catalog, Schema, ObjectName: string;\n  ColumnType: Integer;\nbegin\n  if AnsiCompareText(Trim(SQL.Text), Trim(Value)) <> 0 then\n  begin\n    SQL.Text := Value;\n    if ParamCheck and (Value <> '') and not (csLoading in ComponentState) and Assigned(Connection) then\n    begin\n      CheckConnected;\n      Connection.ShowSQLHourGlass;\n      try\n        SplitQualifiedObjectName(Value,\n          Connection.DbcConnection.GetMetadata.GetDatabaseInfo.SupportsCatalogsInProcedureCalls,\n          Connection.DbcConnection.GetMetadata.GetDatabaseInfo.SupportsSchemasInProcedureCalls,\n          Catalog, Schema, ObjectName);\n        ObjectName := Connection.DbcConnection.GetMetadata.AddEscapeCharToWildcards(ObjectName);\n        FMetaResultSet := Connection.DbcConnection.GetMetadata.GetProcedureColumns(Catalog, Schema, ObjectName, '');\n        OldParams := TParams.Create;\n        try\n          OldParams.Assign(Params);\n          Params.Clear;\n          while FMetaResultSet.Next do\n          begin\n            ColumnType := FMetaResultSet.GetIntByName('COLUMN_TYPE');\n            if ColumnType >= 0 then //-1 is result column\n              Params.CreateParam(ConvertDbcToDatasetType(TZSqlType(FMetaResultSet.GetIntByName('DATA_TYPE'))),\n                FMetaResultSet.GetStringByName('COLUMN_NAME'),\n                GetParamType(TZProcedureColumnType(ColumnType)));\n          end;\n          Params.AssignValues(OldParams);\n        finally\n          OldParams.Free;\n        end;\n      finally\n        Connection.HideSQLHourGlass;\n      end;\n    end;\n  end;\nend;\n{$IFDEF FPC}\n  {$HINTS ON}\n{$ENDIF}\n\nprocedure TZStoredProc.ExecProc;\nbegin\n  Connection.ShowSQLHourGlass;\n  try\n    if Active then\n      Close;\n    ExecSQL;\n    RetrieveParamValues;\n  finally\n    Connection.HideSQLHourGlass;\n  end;\nend;\n\n{**\n  Procedure the First retrieved resultset if the givens\n}\nprocedure TZStoredProc.FirstResultSet;\nbegin\n  if Assigned(Statement) then\n    if (Statement as IZCallableStatement).HasMoreResultSets then\n      SetAnotherResultset((Statement as IZCallableStatement).GetFirstResultSet);\nend;\n\n{**\n  Procedure the Previous retrieved resultset if the givens\n}\nprocedure TZStoredProc.PreviousResultSet;\nbegin\n  if Assigned(Statement) then\n    if (Statement as IZCallableStatement).HasMoreResultSets then\n      SetAnotherResultset((Statement as IZCallableStatement).GetPreviousResultSet);\nend;\n\n{**\n  Procedure the Next retrieved resultset if the givens\n}\nprocedure TZStoredProc.NextResultSet;\nbegin\n  if Assigned(Statement) then\n    if (Statement as IZCallableStatement).HasMoreResultSets then\n      SetAnotherResultset((Statement as IZCallableStatement).GetNextResultSet);\nend;\n\n{**\n  Procedure the Last retrieved resultset if the givens\n}\nprocedure TZStoredProc.LastResultSet;\nbegin\n  if Assigned(Statement) then\n    if (Statement as IZCallableStatement).HasMoreResultSets then\n      SetAnotherResultset((Statement as IZCallableStatement).GetLastResultSet);\nend;\n\n{**\n  Retrieves a ResultSet by his index.\n  @param Integer the index of the Resultset\n  @result <code>IZResultSet</code> of the Index or nil.\n}\nprocedure TZStoredProc.SetResultSet(const Index: Integer);\nbegin\n  if Assigned(Statement) then\n    if ( Index < 0 ) or ( Index > (Statement as IZCallableStatement).GetResultSetCount -1 ) then\n      raise Exception.Create(Format(SListIndexError, [Index]))\n    else\n      SetAnotherResultset((Statement as IZCallableStatement).GetResultSetByIndex(Index));\nend;\n\n{**\n  Returns the Count of retrived ResultSets.\n  @result <code>Integer</code> Count\n}\nfunction TZStoredProc.ResultSetCount: Integer;\nbegin\n  Result := 0;\n  if Assigned(Statement) then\n    if (Statement as IZCallableStatement).HasMoreResultSets then\n      Result := (Statement as IZCallableStatement).GetResultSetCount;\nend;\n\n{**\n  First ResultSet?\n  @result <code>True</code> if first ResultSet\n}\nfunction TZStoredProc.BOR: Boolean;\nbegin\n  Result := True;\n  if Assigned(Statement) then\n    if (Statement as IZCallableStatement).HasMoreResultSets then\n      Result := (Statement as IZCallableStatement).BOR;\nend;\n\n{**\n  Last ResultSet?\n  @result <code>True</code> if Last ResultSet\n}\nfunction TZStoredProc.EOR: Boolean;\nbegin\n  Result := True;\n  if Assigned(Statement) then\n    if (Statement as IZCallableStatement).HasMoreResultSets then\n      Result := (Statement as IZCallableStatement).EOR;\nend;\n\n{**\n  Converts procedure column type to dataset param type.\n  @param Value a initial procedure column type.\n  @return a corresponding param type.\n}\nfunction TZStoredProc.GetParamType(const Value: TZProcedureColumnType): TParamType;\nbegin\n  case Value of\n    pctIn:\n      Result := ptInput;\n    pctInOut:\n      Result := ptInputOutput;\n    pctOut:\n      Result := ptOutput;\n    pctReturn:\n      Result := ptResult;\n    pctResultSet:\n      Result := ptResult;\n  else\n    Result := ptUnknown;\n  end;\nend;\n\n{$IFDEF WITH_IPROVIDER}\n{**\n  Checks if dataset can execute SQL queries?\n  @returns <code>True</code> if the query can execute SQL.\n}\nfunction TZStoredProc.PSIsSQLBased: Boolean;\nbegin\n  Result := False;\nend;\n\n{**\n  Gets the name of the stored procedure.\n  @returns the name of this stored procedure.\n}\n{$IFDEF WITH_IPROVIDERWIDE}\nfunction TZStoredProc.PSGetTableNameW: WideString;\n{$ELSE}\nfunction TZStoredProc.PSGetTableName: string;\n{$ENDIF}\nbegin\n  Result := StoredProcName;\nend;\n\n{**\n  Executes this stored procedure.\n}\nprocedure TZStoredProc.PSExecute;\nbegin\n  ExecProc;\nend;\n\n{**\n  Assignes a new name for this stored procedure.\n  @param ACommandText a new name for this stored procedure.\n}\nprocedure TZStoredProc.PSSetCommandText(const ACommandText: string);\nbegin\n  StoredProcName := ACommandText;\nend;\n{$ENDIF}\n\nend.\n"
  },
  {
    "path": "lib/zeosdbo/src/component/ZStreamBlob.pas",
    "content": "{*********************************************************}\n{                                                         }\n{                 Zeos Database Objects                   }\n{                  Blob streams classes                   }\n{                                                         }\n{        Originally written by Sergey Seroukhov           }\n{                                                         }\n{*********************************************************}\n\n{@********************************************************}\n{    Copyright (c) 1999-2012 Zeos Development Group       }\n{                                                         }\n{ License Agreement:                                      }\n{                                                         }\n{ This library is distributed in the hope that it will be }\n{ useful, but WITHOUT ANY WARRANTY; without even the      }\n{ implied warranty of MERCHANTABILITY or FITNESS FOR      }\n{ A PARTICULAR PURPOSE.  See the GNU Lesser General       }\n{ Public License for more details.                        }\n{                                                         }\n{ The source code of the ZEOS Libraries and packages are  }\n{ distributed under the Library GNU General Public        }\n{ License (see the file COPYING / COPYING.ZEOS)           }\n{ with the following  modification:                       }\n{ As a special exception, the copyright holders of this   }\n{ library give you permission to link this library with   }\n{ independent modules to produce an executable,           }\n{ regardless of the license terms of these independent    }\n{ modules, and to copy and distribute the resulting       }\n{ executable under terms of your choice, provided that    }\n{ you also meet, for each linked independent module,      }\n{ the terms and conditions of the license of that module. }\n{ An independent module is a module which is not derived  }\n{ from or based on this library. If you modify this       }\n{ library, you may extend this exception to your version  }\n{ of the library, but you are not obligated to do so.     }\n{ If you do not wish to do so, delete this exception      }\n{ statement from your version.                            }\n{                                                         }\n{                                                         }\n{ The project web site is located on:                     }\n{   http://zeos.firmos.at  (FORUM)                        }\n{   http://sourceforge.net/p/zeoslib/tickets/ (BUGTRACKER)}\n{   svn://svn.code.sf.net/p/zeoslib/code-0/trunk (SVN)    }\n{                                                         }\n{   http://www.sourceforge.net/projects/zeoslib.          }\n{                                                         }\n{                                                         }\n{                                 Zeos Development Group. }\n{********************************************************@}\n\nunit ZStreamBlob;\n\ninterface\n\n{$I ZComponent.inc}\n\nuses Classes, SysUtils, {$IFDEF MSEgui}mclasses, mdb{$ELSE}DB{$ENDIF},\n  {$IFDEF WITH_WIDESTRUTILS}WideStrUtils, {$ENDIF}\n  ZDbcIntfs, ZCompatibility;\n\ntype\n  {** Implements a class for blobs stream. }\n  TZBlobStream = class(TMemoryStream)\n  private\n    FField: TBlobField;\n    FBlob: IZBlob;\n    FMode: TBlobStreamMode;\n    FConSettings: PZConSettings;\n  protected\n    property Blob: IZBlob read FBlob write FBlob;\n    property Mode: TBlobStreamMode read FMode write FMode;\n  public\n    constructor Create(Field: TBlobField; Blob: IZBlob; Mode: TBlobStreamMode;\n      ConSettings: PZConSettings);\n    destructor Destroy; override;\n  end;\n\nimplementation\n\nuses ZEncoding;\n\n{ TZBlobStream }\n\n{**\n  Constructs this object and assignes the main properties.\n  @param Blob\n}\nconstructor TZBlobStream.Create(Field: TBlobField; Blob: IZBlob;\n  Mode: TBlobStreamMode; ConSettings: PZConSettings);\nvar\n  TempStream: TStream;\nbegin\n  inherited Create;\n\n  FBlob := Blob;\n  FMode := Mode;\n  FField := Field;\n  FConSettings := ConSettings;\n  if (Mode in [bmRead, bmReadWrite]) and not Blob.IsEmpty then\n  begin\n    TempStream := Blob.GetStream;\n    try\n      TempStream.Position := 0;\n      CopyFrom(TempStream, TempStream.Size);\n      Position := 0;\n    finally\n      TempStream.Free;\n    end;\n  end\nend;\n\ntype THackedDataset = class(TDataset);\n\n{**\n  Destroys this object and cleanups the memory.\n}\ndestructor TZBlobStream.Destroy;\n{$IFDEF WITH_WIDEMEMO}\nvar\n  TempStream: TStream;\n{$ENDIF}\nbegin\n  if Mode in [bmWrite, bmReadWrite] then\n  begin\n    if Assigned(Self.Memory) then\n    begin\n    {$IFDEF WITH_WIDEMEMO}\n      if FField.DataType = ftWideMemo then\n      begin\n        TempStream := GetValidatedUnicodeStream(Memory, Cardinal(Size),\n          FConSettings, False);\n        Blob.SetStream(TempStream, True);\n        TempStream.Free;\n      end\n      else\n    {$ENDIF}\n      Blob.SetStream(Self)\n    end\n    else\n      Blob.SetStream(nil);\n    try\n      if Assigned(FField.Dataset) then\n        THackedDataset(FField.DataSet).DataEvent(deFieldChange, ULong(FField));\n    except\n        ApplicationHandleException(Self);\n    end;\n  end;\n  inherited Destroy;\nend;\n\nend.\n\n"
  },
  {
    "path": "lib/zeosdbo/src/component/ZUpdateSqlEditor.dfm",
    "content": "object ZUpdateSQLEditForm: TZUpdateSQLEditForm\n  Left = 339\n  Top = 271\n  Width = 406\n  Height = 293\n  ActiveControl = UpdateTableName\n  Color = clBtnFace\n  Font.Charset = DEFAULT_CHARSET\n  Font.Color = clWindowText\n  Font.Height = -11\n  Font.Name = 'MS Sans Serif'\n  Font.Style = []\n  OldCreateOrder = True\n  Position = poScreenCenter\n  OnCloseQuery = FormCloseQuery\n  OnCreate = FormCreate\n  OnDestroy = FormDestroy\n  PixelsPerInch = 96\n  TextHeight = 13\n  object PageControl: TPageControl\n    Left = 0\n    Top = 0\n    Width = 390\n    Height = 223\n    ActivePage = SQLPage\n    Align = alClient\n    TabOrder = 0\n    OnChanging = PageControlChanging\n    object FieldsPage: TTabSheet\n      Caption = 'Options'\n      object GroupBox1: TGroupBox\n        Left = 0\n        Top = 0\n        Width = 382\n        Height = 195\n        Align = alClient\n        Caption = ' SQL Generation '\n        TabOrder = 0\n        DesignSize = (\n          382\n          195)\n        object Label1: TLabel\n          Left = 8\n          Top = 24\n          Width = 61\n          Height = 13\n          Caption = 'Table &Name:'\n          FocusControl = UpdateTableName\n        end\n        object Label3: TLabel\n          Left = 128\n          Top = 24\n          Width = 51\n          Height = 13\n          Anchors = [akTop, akRight]\n          Caption = '&Key Fields:'\n          FocusControl = KeyFieldList\n        end\n        object Label4: TLabel\n          Left = 256\n          Top = 24\n          Width = 68\n          Height = 13\n          Anchors = [akTop, akRight]\n          Caption = 'Update &Fields:'\n          FocusControl = UpdateFieldList\n        end\n        object UpdateTableName: TComboBox\n          Left = 8\n          Top = 40\n          Width = 113\n          Height = 21\n          TabOrder = 0\n          OnChange = UpdateTableNameChange\n          OnClick = UpdateTableNameClick\n        end\n        object KeyFieldList: TListBox\n          Left = 126\n          Top = 40\n          Width = 117\n          Height = 146\n          Anchors = [akLeft, akTop, akBottom]\n          ItemHeight = 13\n          MultiSelect = True\n          PopupMenu = FieldListPopup\n          TabOrder = 6\n          OnClick = SettingsChanged\n        end\n        object UpdateFieldList: TListBox\n          Left = 254\n          Top = 40\n          Width = 120\n          Height = 146\n          Anchors = [akLeft, akTop, akRight, akBottom]\n          ItemHeight = 13\n          MultiSelect = True\n          PopupMenu = FieldListPopup\n          TabOrder = 7\n          OnClick = SettingsChanged\n        end\n        object GenerateButton: TButton\n          Left = 8\n          Top = 136\n          Width = 113\n          Height = 22\n          Caption = '&Generate SQL'\n          TabOrder = 4\n          OnClick = GenerateButtonClick\n        end\n        object PrimaryKeyButton: TButton\n          Left = 8\n          Top = 112\n          Width = 113\n          Height = 22\n          Caption = 'Select &Primary Keys'\n          TabOrder = 3\n          OnClick = PrimaryKeyButtonClick\n        end\n        object DefaultButton: TButton\n          Left = 8\n          Top = 88\n          Width = 113\n          Height = 21\n          Caption = '&Dataset Defaults'\n          Enabled = False\n          TabOrder = 2\n          OnClick = DefaultButtonClick\n        end\n        object QuoteFields: TCheckBox\n          Left = 8\n          Top = 168\n          Width = 113\n          Height = 15\n          Caption = '&Quote Field Names'\n          TabOrder = 5\n          OnClick = SettingsChanged\n        end\n        object GetTableFieldsButton: TButton\n          Left = 8\n          Top = 64\n          Width = 113\n          Height = 21\n          Caption = 'Get &Table Fields'\n          TabOrder = 1\n          OnClick = GetTableFieldsButtonClick\n        end\n      end\n    end\n    object SQLPage: TTabSheet\n      Caption = 'SQL'\n      object Label2: TLabel\n        Left = 8\n        Top = 40\n        Width = 48\n        Height = 13\n        Caption = 'S&QL Text:'\n        FocusControl = SQLMemo\n      end\n      object SQLMemo: TMemo\n        Left = 8\n        Top = 56\n        Width = 368\n        Height = 130\n        Align = alCustom\n        Anchors = [akLeft, akTop, akRight, akBottom]\n        ScrollBars = ssVertical\n        TabOrder = 0\n        WordWrap = False\n        OnKeyPress = SQLMemoKeyPress\n      end\n      object StatementType: TRadioGroup\n        Left = 0\n        Top = 0\n        Width = 382\n        Height = 35\n        Align = alTop\n        Caption = 'Statement Type'\n        Columns = 3\n        Items.Strings = (\n          '&Modify'\n          '&Insert'\n          '&Delete')\n        TabOrder = 1\n        OnClick = StatementTypeClick\n      end\n    end\n  end\n  object Panel1: TPanel\n    Left = 0\n    Top = 223\n    Width = 390\n    Height = 34\n    Align = alBottom\n    TabOrder = 1\n    DesignSize = (\n      390\n      34)\n    object OkButton: TButton\n      Left = 162\n      Top = 5\n      Width = 65\n      Height = 22\n      Anchors = [akRight, akBottom]\n      Caption = '&OK'\n      Default = True\n      ModalResult = 1\n      TabOrder = 0\n      OnClick = OkButtonClick\n    end\n    object CancelButton: TButton\n      Left = 239\n      Top = 5\n      Width = 65\n      Height = 22\n      Anchors = [akRight, akBottom]\n      Cancel = True\n      Caption = 'Cancel'\n      ModalResult = 2\n      TabOrder = 1\n    end\n    object HelpButton: TButton\n      Left = 315\n      Top = 5\n      Width = 65\n      Height = 22\n      Anchors = [akRight, akBottom]\n      Caption = '&Help'\n      TabOrder = 2\n      OnClick = HelpButtonClick\n    end\n  end\n  object FieldListPopup: TPopupMenu\n    Left = 54\n    Top = 270\n    object miSelectAll: TMenuItem\n      Caption = '&Select All'\n      OnClick = SelectAllClick\n    end\n    object miClearAll: TMenuItem\n      Caption = '&Clear All'\n      OnClick = ClearAllClick\n    end\n  end\nend\n"
  },
  {
    "path": "lib/zeosdbo/src/component/ZUpdateSqlEditor.lfm",
    "content": "object ZUpdateSQLEditForm: TZUpdateSQLEditForm\n  Left = 447\n  Height = 258\n  Top = 246\n  Width = 398\n  Caption = 'ZUpdateSQLEditForm'\n  ClientHeight = 258\n  ClientWidth = 398\n  Font.Height = -11\n  Font.Name = 'MS Sans Serif'\n  OnCloseQuery = FormCloseQuery\n  OnCreate = FormCreate\n  OnDestroy = FormDestroy\n  OnResize = FormResize\n  Position = poScreenCenter\n  LCLVersion = '1.1'\n  object PageControl: TPageControl\n    Left = 0\n    Height = 221\n    Top = 0\n    Width = 398\n    ActivePage = SQLPage\n    Align = alClient\n    TabIndex = 1\n    TabOrder = 0\n    OnChanging = PageControlChanging\n    object FieldsPage: TTabSheet\n      Caption = 'Options'\n      ClientHeight = 195\n      ClientWidth = 390\n      object GroupBox1: TGroupBox\n        Left = 0\n        Height = 195\n        Top = 0\n        Width = 390\n        Align = alClient\n        Caption = ' SQL Generation '\n        ClientHeight = 177\n        ClientWidth = 386\n        TabOrder = 0\n        object Label1: TLabel\n          Left = 16\n          Height = 14\n          Top = 8\n          Width = 62\n          Caption = 'Table &Name:'\n          FocusControl = UpdateTableName\n          ParentColor = False\n        end\n        object Label3: TLabel\n          Left = 143\n          Height = 14\n          Top = 8\n          Width = 52\n          Anchors = [akTop, akRight]\n          Caption = '&Key Fields:'\n          FocusControl = KeyFieldList\n          ParentColor = False\n        end\n        object Label4: TLabel\n          Left = 265\n          Height = 14\n          Top = 8\n          Width = 69\n          Anchors = [akTop, akRight]\n          Caption = 'Update &Fields:'\n          FocusControl = UpdateFieldList\n          ParentColor = False\n        end\n        object QuoteFields: TCheckBox\n          Left = 16\n          Height = 17\n          Top = 152\n          Width = 110\n          Caption = '&Quote Field Names'\n          OnClick = SettingsChanged\n          TabOrder = 5\n        end\n        object UpdateTableName: TComboBox\n          Left = 16\n          Height = 21\n          Top = 24\n          Width = 113\n          ItemHeight = 13\n          OnChange = UpdateTableNameChange\n          OnClick = UpdateTableNameClick\n          TabOrder = 0\n        end\n        object GenerateButton: TButton\n          Left = 16\n          Height = 22\n          Top = 120\n          Width = 113\n          Caption = '&Generate SQL'\n          OnClick = GenerateButtonClick\n          TabOrder = 4\n        end\n        object PrimaryKeyButton: TButton\n          Left = 16\n          Height = 22\n          Top = 96\n          Width = 113\n          Caption = 'Select &Primary Keys'\n          OnClick = PrimaryKeyButtonClick\n          TabOrder = 3\n        end\n        object DefaultButton: TButton\n          Left = 16\n          Height = 21\n          Top = 72\n          Width = 113\n          Caption = '&Dataset Defaults'\n          Enabled = False\n          OnClick = DefaultButtonClick\n          TabOrder = 2\n        end\n        object GetTableFieldsButton: TButton\n          Left = 16\n          Height = 21\n          Top = 48\n          Width = 113\n          Caption = 'Get &Table Fields'\n          OnClick = GetTableFieldsButtonClick\n          TabOrder = 1\n        end\n        object UpdateFieldList: TListBox\n          Left = 264\n          Height = 144\n          Top = 24\n          Width = 118\n          Anchors = [akTop, akRight, akBottom]\n          ItemHeight = 0\n          MultiSelect = True\n          OnClick = SettingsChanged\n          PopupMenu = FieldListPopup\n          TabOrder = 7\n        end\n        object KeyFieldList: TListBox\n          Left = 136\n          Height = 144\n          Top = 24\n          Width = 117\n          Anchors = [akTop, akLeft, akRight, akBottom]\n          ItemHeight = 0\n          MultiSelect = True\n          OnClick = SettingsChanged\n          PopupMenu = FieldListPopup\n          TabOrder = 6\n        end\n      end\n    end\n    object SQLPage: TTabSheet\n      Caption = 'SQL'\n      ClientHeight = 195\n      ClientWidth = 390\n      object Label2: TLabel\n        Left = 8\n        Height = 14\n        Top = 40\n        Width = 49\n        Caption = 'S&QL Text:'\n        FocusControl = SQLMemo\n        ParentColor = False\n      end\n      object SQLMemo: TMemo\n        Left = 8\n        Height = 129\n        Top = 56\n        Width = 373\n        Align = alCustom\n        Anchors = [akTop, akLeft, akRight, akBottom]\n        OnKeyPress = SQLMemoKeyPress\n        ScrollBars = ssVertical\n        TabOrder = 0\n        WordWrap = False\n      end\n      object StatementType: TRadioGroup\n        Left = 0\n        Height = 35\n        Top = 0\n        Width = 390\n        Align = alTop\n        AutoFill = True\n        Caption = 'Statement Type'\n        ChildSizing.LeftRightSpacing = 6\n        ChildSizing.TopBottomSpacing = 6\n        ChildSizing.EnlargeHorizontal = crsHomogenousChildResize\n        ChildSizing.EnlargeVertical = crsHomogenousChildResize\n        ChildSizing.ShrinkHorizontal = crsScaleChilds\n        ChildSizing.ShrinkVertical = crsScaleChilds\n        ChildSizing.Layout = cclLeftToRightThenTopToBottom\n        ChildSizing.ControlsPerLine = 3\n        ClientHeight = 17\n        ClientWidth = 386\n        Columns = 3\n        Items.Strings = (\n          '&Modify'\n          '&Insert'\n          '&Delete'\n        )\n        OnClick = StatementTypeClick\n        TabOrder = 1\n      end\n    end\n  end\n  object Panel1: TPanel\n    Left = 0\n    Height = 37\n    Top = 221\n    Width = 398\n    Align = alBottom\n    BevelOuter = bvNone\n    ClientHeight = 37\n    ClientWidth = 398\n    TabOrder = 1\n    object OkButton: TButton\n      Left = 168\n      Height = 22\n      Top = 7\n      Width = 65\n      Anchors = [akRight, akBottom]\n      Caption = '&OK'\n      Default = True\n      ModalResult = 1\n      OnClick = OkButtonClick\n      TabOrder = 0\n    end\n    object CancelButton: TButton\n      Left = 245\n      Height = 22\n      Top = 7\n      Width = 65\n      Anchors = [akRight, akBottom]\n      Cancel = True\n      Caption = 'Cancel'\n      ModalResult = 2\n      TabOrder = 1\n    end\n    object HelpButton: TButton\n      Left = 321\n      Height = 22\n      Top = 7\n      Width = 65\n      Anchors = [akRight, akBottom]\n      Caption = '&Help'\n      OnClick = HelpButtonClick\n      TabOrder = 2\n    end\n  end\n  object FieldListPopup: TPopupMenu\n    left = 54\n    top = 270\n    object miSelectAll: TMenuItem\n      Caption = '&Select All'\n      OnClick = SelectAllClick\n    end\n    object miClearAll: TMenuItem\n      Caption = '&Clear All'\n      OnClick = ClearAllClick\n    end\n  end\nend\n"
  },
  {
    "path": "lib/zeosdbo/src/component/ZUpdateSqlEditor.lrs",
    "content": "{ This is an automatically generated lazarus resource file }\n\nLazarusResources.Add('TZUpdateSQLEditForm','FORMDATA',[\n  'TPF0'#19'TZUpdateSQLEditForm'#18'ZUpdateSQLEditForm'#4'Left'#3#191#1#6'Heigh'\n  +'t'#3#2#1#3'Top'#3#246#0#5'Width'#3#142#1#7'Caption'#6#18'ZUpdateSQLEditForm'\n  +#12'ClientHeight'#3#2#1#11'ClientWidth'#3#142#1#11'Font.Height'#2#245#9'Font'\n  +'.Name'#6#13'MS Sans Serif'#12'OnCloseQuery'#7#14'FormCloseQuery'#8'OnCreate'\n  +#7#10'FormCreate'#9'OnDestroy'#7#11'FormDestroy'#8'OnResize'#7#10'FormResize'\n  +#8'Position'#7#14'poScreenCenter'#10'LCLVersion'#6#3'1.1'#0#12'TPageControl'\n  +#11'PageControl'#4'Left'#2#0#6'Height'#3#221#0#3'Top'#2#0#5'Width'#3#142#1#10\n  +'ActivePage'#7#7'SQLPage'#5'Align'#7#8'alClient'#8'TabIndex'#2#1#8'TabOrder'\n  +#2#0#10'OnChanging'#7#19'PageControlChanging'#0#9'TTabSheet'#10'FieldsPage'#7\n  +'Caption'#6#7'Options'#12'ClientHeight'#3#195#0#11'ClientWidth'#3#134#1#0#9\n  +'TGroupBox'#9'GroupBox1'#4'Left'#2#0#6'Height'#3#195#0#3'Top'#2#0#5'Width'#3\n  +#134#1#5'Align'#7#8'alClient'#7'Caption'#6#16' SQL Generation '#12'ClientHei'\n  +'ght'#3#177#0#11'ClientWidth'#3#130#1#8'TabOrder'#2#0#0#6'TLabel'#6'Label1'#4\n  +'Left'#2#16#6'Height'#2#14#3'Top'#2#8#5'Width'#2'>'#7'Caption'#6#12'Table &N'\n  +'ame:'#12'FocusControl'#7#15'UpdateTableName'#11'ParentColor'#8#0#0#6'TLabel'\n  +#6'Label3'#4'Left'#3#143#0#6'Height'#2#14#3'Top'#2#8#5'Width'#2'4'#7'Anchors'\n  +#11#5'akTop'#7'akRight'#0#7'Caption'#6#12'&Key Fields:'#12'FocusControl'#7#12\n  +'KeyFieldList'#11'ParentColor'#8#0#0#6'TLabel'#6'Label4'#4'Left'#3#9#1#6'Hei'\n  +'ght'#2#14#3'Top'#2#8#5'Width'#2'E'#7'Anchors'#11#5'akTop'#7'akRight'#0#7'Ca'\n  +'ption'#6#15'Update &Fields:'#12'FocusControl'#7#15'UpdateFieldList'#11'Pare'\n  +'ntColor'#8#0#0#9'TCheckBox'#11'QuoteFields'#4'Left'#2#16#6'Height'#2#17#3'T'\n  +'op'#3#152#0#5'Width'#2'n'#7'Caption'#6#18'&Quote Field Names'#7'OnClick'#7\n  +#15'SettingsChanged'#8'TabOrder'#2#5#0#0#9'TComboBox'#15'UpdateTableName'#4\n  +'Left'#2#16#6'Height'#2#21#3'Top'#2#24#5'Width'#2'q'#10'ItemHeight'#2#13#8'O'\n  +'nChange'#7#21'UpdateTableNameChange'#7'OnClick'#7#20'UpdateTableNameClick'#8\n  +'TabOrder'#2#0#0#0#7'TButton'#14'GenerateButton'#4'Left'#2#16#6'Height'#2#22\n  +#3'Top'#2'x'#5'Width'#2'q'#7'Caption'#6#13'&Generate SQL'#7'OnClick'#7#19'Ge'\n  +'nerateButtonClick'#8'TabOrder'#2#4#0#0#7'TButton'#16'PrimaryKeyButton'#4'Le'\n  +'ft'#2#16#6'Height'#2#22#3'Top'#2'`'#5'Width'#2'q'#7'Caption'#6#20'Select &P'\n  +'rimary Keys'#7'OnClick'#7#21'PrimaryKeyButtonClick'#8'TabOrder'#2#3#0#0#7'T'\n  +'Button'#13'DefaultButton'#4'Left'#2#16#6'Height'#2#21#3'Top'#2'H'#5'Width'#2\n  +'q'#7'Caption'#6#17'&Dataset Defaults'#7'Enabled'#8#7'OnClick'#7#18'DefaultB'\n  +'uttonClick'#8'TabOrder'#2#2#0#0#7'TButton'#20'GetTableFieldsButton'#4'Left'\n  +#2#16#6'Height'#2#21#3'Top'#2'0'#5'Width'#2'q'#7'Caption'#6#17'Get &Table Fi'\n  +'elds'#7'OnClick'#7#25'GetTableFieldsButtonClick'#8'TabOrder'#2#1#0#0#8'TLis'\n  +'tBox'#15'UpdateFieldList'#4'Left'#3#8#1#6'Height'#3#144#0#3'Top'#2#24#5'Wid'\n  +'th'#2'v'#7'Anchors'#11#5'akTop'#7'akRight'#8'akBottom'#0#10'ItemHeight'#2#0\n  +#11'MultiSelect'#9#7'OnClick'#7#15'SettingsChanged'#9'PopupMenu'#7#14'FieldL'\n  +'istPopup'#8'TabOrder'#2#7#0#0#8'TListBox'#12'KeyFieldList'#4'Left'#3#136#0#6\n  +'Height'#3#144#0#3'Top'#2#24#5'Width'#2'u'#7'Anchors'#11#5'akTop'#6'akLeft'#7\n  +'akRight'#8'akBottom'#0#10'ItemHeight'#2#0#11'MultiSelect'#9#7'OnClick'#7#15\n  +'SettingsChanged'#9'PopupMenu'#7#14'FieldListPopup'#8'TabOrder'#2#6#0#0#0#0#9\n  +'TTabSheet'#7'SQLPage'#7'Caption'#6#3'SQL'#12'ClientHeight'#3#195#0#11'Clien'\n  +'tWidth'#3#134#1#0#6'TLabel'#6'Label2'#4'Left'#2#8#6'Height'#2#14#3'Top'#2'('\n  +#5'Width'#2'1'#7'Caption'#6#10'S&QL Text:'#12'FocusControl'#7#7'SQLMemo'#11\n  +'ParentColor'#8#0#0#5'TMemo'#7'SQLMemo'#4'Left'#2#8#6'Height'#3#129#0#3'Top'\n  +#2'8'#5'Width'#3'u'#1#5'Align'#7#8'alCustom'#7'Anchors'#11#5'akTop'#6'akLeft'\n  +#7'akRight'#8'akBottom'#0#10'OnKeyPress'#7#15'SQLMemoKeyPress'#10'ScrollBars'\n  +#7#10'ssVertical'#8'TabOrder'#2#0#8'WordWrap'#8#0#0#11'TRadioGroup'#13'State'\n  +'mentType'#4'Left'#2#0#6'Height'#2'#'#3'Top'#2#0#5'Width'#3#134#1#5'Align'#7\n  +#5'alTop'#8'AutoFill'#9#7'Caption'#6#14'Statement Type'#28'ChildSizing.LeftR'\n  +'ightSpacing'#2#6#28'ChildSizing.TopBottomSpacing'#2#6#29'ChildSizing.Enlarg'\n  +'eHorizontal'#7#24'crsHomogenousChildResize'#27'ChildSizing.EnlargeVertical'\n  +#7#24'crsHomogenousChildResize'#28'ChildSizing.ShrinkHorizontal'#7#14'crsSca'\n  +'leChilds'#26'ChildSizing.ShrinkVertical'#7#14'crsScaleChilds'#18'ChildSizin'\n  +'g.Layout'#7#29'cclLeftToRightThenTopToBottom'#27'ChildSizing.ControlsPerLin'\n  +'e'#2#3#12'ClientHeight'#2#17#11'ClientWidth'#3#130#1#7'Columns'#2#3#13'Item'\n  +'s.Strings'#1#6#7'&Modify'#6#7'&Insert'#6#7'&Delete'#0#7'OnClick'#7#18'State'\n  +'mentTypeClick'#8'TabOrder'#2#1#0#0#0#0#6'TPanel'#6'Panel1'#4'Left'#2#0#6'He'\n  +'ight'#2'%'#3'Top'#3#221#0#5'Width'#3#142#1#5'Align'#7#8'alBottom'#10'BevelO'\n  +'uter'#7#6'bvNone'#12'ClientHeight'#2'%'#11'ClientWidth'#3#142#1#8'TabOrder'\n  +#2#1#0#7'TButton'#8'OkButton'#4'Left'#3#168#0#6'Height'#2#22#3'Top'#2#7#5'Wi'\n  +'dth'#2'A'#7'Anchors'#11#7'akRight'#8'akBottom'#0#7'Caption'#6#3'&OK'#7'Defa'\n  +'ult'#9#11'ModalResult'#2#1#7'OnClick'#7#13'OkButtonClick'#8'TabOrder'#2#0#0\n  ,#0#7'TButton'#12'CancelButton'#4'Left'#3#245#0#6'Height'#2#22#3'Top'#2#7#5'W'\n  +'idth'#2'A'#7'Anchors'#11#7'akRight'#8'akBottom'#0#6'Cancel'#9#7'Caption'#6#6\n  +'Cancel'#11'ModalResult'#2#2#8'TabOrder'#2#1#0#0#7'TButton'#10'HelpButton'#4\n  +'Left'#3'A'#1#6'Height'#2#22#3'Top'#2#7#5'Width'#2'A'#7'Anchors'#11#7'akRigh'\n  +'t'#8'akBottom'#0#7'Caption'#6#5'&Help'#7'OnClick'#7#15'HelpButtonClick'#8'T'\n  +'abOrder'#2#2#0#0#0#10'TPopupMenu'#14'FieldListPopup'#4'left'#2'6'#3'top'#3\n  +#14#1#0#9'TMenuItem'#11'miSelectAll'#7'Caption'#6#11'&Select All'#7'OnClick'\n  +#7#14'SelectAllClick'#0#0#9'TMenuItem'#10'miClearAll'#7'Caption'#6#10'&Clear'\n  +' All'#7'OnClick'#7#13'ClearAllClick'#0#0#0#0\n]);\n"
  },
  {
    "path": "lib/zeosdbo/src/component/ZUpdateSqlEditor.pas",
    "content": "{*********************************************************}\n{                                                         }\n{                 Zeos Database Objects                   }\n{               UpdateSql property editor                 }\n{                                                         }\n{        Originally written by Janos Fegyverneki          }\n{                                                         }\n{*********************************************************}\n\n{@********************************************************}\n{    Copyright (c) 1999-2012 Zeos Development Group       }\n{                                                         }\n{ License Agreement:                                      }\n{                                                         }\n{ This library is distributed in the hope that it will be }\n{ useful, but WITHOUT ANY WARRANTY; without even the      }\n{ implied warranty of MERCHANTABILITY or FITNESS FOR      }\n{ A PARTICULAR PURPOSE.  See the GNU Lesser General       }\n{ Public License for more details.                        }\n{                                                         }\n{ The source code of the ZEOS Libraries and packages are  }\n{ distributed under the Library GNU General Public        }\n{ License (see the file COPYING / COPYING.ZEOS)           }\n{ with the following  modification:                       }\n{ As a special exception, the copyright holders of this   }\n{ library give you permission to link this library with   }\n{ independent modules to produce an executable,           }\n{ regardless of the license terms of these independent    }\n{ modules, and to copy and distribute the resulting       }\n{ executable under terms of your choice, provided that    }\n{ you also meet, for each linked independent module,      }\n{ the terms and conditions of the license of that module. }\n{ An independent module is a module which is not derived  }\n{ from or based on this library. If you modify this       }\n{ library, you may extend this exception to your version  }\n{ of the library, but you are not obligated to do so.     }\n{ If you do not wish to do so, delete this exception      }\n{ statement from your version.                            }\n{                                                         }\n{                                                         }\n{ The project web site is located on:                     }\n{   http://zeos.firmos.at  (FORUM)                        }\n{   http://sourceforge.net/p/zeoslib/tickets/ (BUGTRACKER)}\n{   svn://svn.code.sf.net/p/zeoslib/code-0/trunk (SVN)    }\n{                                                         }\n{   http://www.sourceforge.net/projects/zeoslib.          }\n{                                                         }\n{                                                         }\n{                                 Zeos Development Group. }\n{********************************************************@}\n\nunit ZUpdateSqlEditor;\n\ninterface\n\n{$I ZComponent.inc}\n\nuses\n{$IFNDEF FPC}\n  DesignEditors,\n{$ELSE}\n  PropEdits, Buttons, ComponentEditors,\n{$ENDIF}\n  Forms, DB, ExtCtrls, StdCtrls, Controls, ComCtrls,\n  Classes, SysUtils, {$IFNDEF FPC}Windows, {$ELSE}LCLIntf, LResources, {$ENDIF}\n  Menus, ZAbstractDataset,\n{$IFDEF UNIX}\n  {$IFNDEF FPC}\n    QMenus, QTypes, QExtCtrls, QStdCtrls, QControls, QComCtrls,\n  {$ENDIF}\n{$ENDIF}\n  ZSqlUpdate;\n\ntype\n\n  TWaitMethod = procedure of object;\n\n  { TZUpdateSQLEditForm }\n\n  TZUpdateSQLEditForm = class(TForm)\n    Label2: TLabel;\n    Label3: TLabel;\n    Label4: TLabel;\n    GenerateButton: TButton;\n    Panel1: TPanel;\n    PrimaryKeyButton: TButton;\n    DefaultButton: TButton;\n    UpdateTableName: TComboBox;\n    FieldsPage: TTabSheet;\n    SQLPage: TTabSheet;\n    PageControl: TPageControl;\n    KeyFieldList: TListBox;\n    UpdateFieldList: TListBox;\n    GroupBox1: TGroupBox;\n    Label1: TLabel;\n    SQLMemo: TMemo;\n    StatementType: TRadioGroup;\n    QuoteFields: TCheckBox;\n    GetTableFieldsButton: TButton;\n    FieldListPopup: TPopupMenu;\n    miSelectAll: TMenuItem;\n    miClearAll: TMenuItem;\n    OkButton: TButton;\n    CancelButton: TButton;\n    HelpButton: TButton;\n    procedure FormCreate(Sender: TObject);\n    procedure FormResize(Sender: TObject);\n    procedure HelpButtonClick(Sender: TObject);\n    procedure StatementTypeClick(Sender: TObject);\n    procedure OkButtonClick(Sender: TObject);\n    procedure DefaultButtonClick(Sender: TObject);\n    procedure GenerateButtonClick(Sender: TObject);\n    procedure PrimaryKeyButtonClick(Sender: TObject);\n    procedure PageControlChanging(Sender: TObject;\n      var AllowChange: Boolean);\n    procedure FormDestroy(Sender: TObject);\n    procedure GetTableFieldsButtonClick(Sender: TObject);\n    procedure SettingsChanged(Sender: TObject);\n    procedure FormCloseQuery(Sender: TObject; var CanClose: Boolean);\n    procedure UpdateTableNameChange(Sender: TObject);\n    procedure UpdateTableNameClick(Sender: TObject);\n    procedure SelectAllClick(Sender: TObject);\n    procedure ClearAllClick(Sender: TObject);\n    procedure SQLMemoKeyPress(Sender: TObject; var Key: Char);\n  private\n    StmtIndex: Integer;\n    DataSet: TZAbstractDataset;\n    QuoteChar: string;\n    ConnectionOpened: Boolean;\n    UpdateSQL: TZUpdateSQL;\n    FSettingsChanged: Boolean;\n    FDatasetDefaults: Boolean;\n    SQLText: array[TUpdateKind] of TStrings;\n    function GetTableRef(const TabName: string): string;\n    function Edit: Boolean;\n    procedure GenWhereClause(const TabAlias: string; KeyFields, SQL: TStrings);\n    procedure GenDeleteSQL(const TableName: string; KeyFields, SQL: TStrings);\n    procedure GenInsertSQL(const TableName: string; UpdateFields, SQL: TStrings);\n    procedure GenModifySQL(const TableName: string; KeyFields, UpdateFields,\n      SQL: TStrings);\n    procedure GenerateSQL;\n    procedure GetDataSetFieldNames;\n    procedure GetTableFieldNames;\n    procedure InitGenerateOptions;\n    procedure InitUpdateTableNames;\n    procedure SetButtonStates;\n    procedure SelectPrimaryKeyFields;\n    procedure SetDefaultSelections;\n    procedure ShowWait(WaitMethod: TWaitMethod);\n  end;\n\n{ TSQLParser }\n\n  TSQLToken = (stSymbol, stAlias, stNumber, stComma, stEQ, stOther, stLParen,\n    stRParen, stEnd, stSemiColon);\n\n  TSQLParser = class\n  private\n    FText: string;\n    FSourcePtr: PChar;\n    FTokenPtr: PChar;\n    FTokenString: string;\n    FToken: TSQLToken;\n    FSymbolQuoted: Boolean;\n    FQuoteString: string;\n    function NextToken: TSQLToken;\n    function TokenSymbolIs(const S: string): Boolean;\n    procedure Reset;\n  public\n    constructor Create(const Text, QuoteString: string);\n    procedure GetSelectTableNames(List: TStrings);\n    procedure GetUpdateTableName(var TableName: string);\n    procedure GetUpdateFields(List: TStrings);\n    procedure GetWhereFields(List: TStrings);\n  end;\n\n  TZUpdateSqlEditor = class(TComponentEditor)\n  public\n    procedure ExecuteVerb(Index: Integer); override;\n    function GetVerb(Index: Integer): string; override;\n    function GetVerbCount: Integer; override;\n    procedure Edit; override;\n  end;\n\nfunction EditUpdateSQL(AZUpdateSQL: TZUpdateSQL): Boolean;\n\nresourcestring\n  SSQLDataSetOpen = 'Unable to determine field names for %s';\n  SNoDataSet = 'No dataset association';\n  SSQLGenSelect = 'Must select at least one key field and one update field';\n  SSQLNotGenerated = 'Update SQL statements not generated, exit anyway?';\n\nimplementation\n\n{$IFNDEF FPC}\n{$R *.dfm}\n{$ENDIF}\n\nuses Dialogs, {$IFNDEF FPC}LibHelp, {$ENDIF}TypInfo, ZCompatibility, ZSqlMetadata,\n  ZDbcIntfs, ZTokenizer, ZGenericSqlAnalyser, ZSelectSchema, ZDbcMetadata;\n\nfunction InternalQuoteIdentifier(const S, QuoteString: string): string;\nbegin\n  Result := S;\n  if Length(QuoteString) > 1 then\n    Result := QuoteString[1] + Result + QuoteString[2]\n  else if Length(QuoteString) = 1 then\n    Result := QuoteString[1] + Result + QuoteString[1];\nend;\n\n{ TZUpdateSqlEditor }\n\nprocedure TZUpdateSqlEditor.ExecuteVerb(Index: Integer);\nbegin\n  if Index = 0 then\n    EditUpdateSQL(TZUpdateSQL(Component));\nend;\n\n{$IFDEF FPC}\n  {$HINTS OFF}\n{$ENDIF}\nfunction TZUpdateSqlEditor.GetVerb(Index: Integer): string;\nbegin\n  Result := 'UpdateSql editor...';\nend;\n{$IFDEF FPC}\n  {$HINTS ON}\n{$ENDIF}\n\n\nfunction TZUpdateSqlEditor.GetVerbCount: Integer;\nbegin\n  Result := 1;\nend;\n\nprocedure TZUpdateSqlEditor.Edit;\nbegin\n  EditUpdateSQL(TZUpdateSQL(Component));\nend;\n\n{ Global Interface functions }\n\nfunction EditUpdateSQL(AZUpdateSQL: TZUpdateSQL): Boolean;\nbegin\n  with TZUpdateSQLEditForm.Create(Application) do\n  try\n    UpdateSQL := AZUpdateSQL;\n    Result := Edit;\n  finally\n    Free;\n  end;\nend;\n\n{ Utility Routines }\n\nprocedure GetSelectedItems(ListBox: TListBox; List: TStrings);\nvar\n  I: Integer;\nbegin\n  List.Clear;\n  for I := 0 to ListBox.Items.Count - 1 do\n    if ListBox.Selected[I] then\n      List.AddObject(ListBox.Items[I], ListBox.Items.Objects[I]);\nend;\n\nfunction SetSelectedItems(ListBox: TListBox; List: TStrings): Integer;\nvar\n  I: Integer;\nbegin\n  Result := 0;\n  ListBox.Items.BeginUpdate;\n  try\n    for I := 0 to ListBox.Items.Count - 1 do\n      if List.IndexOf(ListBox.Items[I]) > -1 then\n      begin\n        ListBox.Selected[I] := True;\n        Inc(Result);\n      end\n      else\n        ListBox.Selected[I] := False;\n    if ListBox.Items.Count > 0 then\n    begin\n      ListBox.ItemIndex := 0;\n      ListBox.TopIndex := 0;\n    end;\n  finally\n    ListBox.Items.EndUpdate;\n  end;\nend;\n\nprocedure SelectAll(ListBox: TListBox);\nvar\n  I: Integer;\nbegin\n  ListBox.Items.BeginUpdate;\n  try\n    with ListBox do\n      for I := 0 to Items.Count - 1 do\n        Selected[I] := True;\n    if ListBox.Items.Count > 0 then\n    begin\n      ListBox.ItemIndex := 0;\n      ListBox.TopIndex := 0;\n    end;\n  finally\n    ListBox.Items.EndUpdate;\n  end;\nend;\n\nprocedure GetDataKeyNames(Dataset: TDataset; ErrorName: string; List: TStrings);\nvar\n  I: Integer;\nbegin\n  with Dataset do\n  try\n    FieldDefs.Update;\n    List.BeginUpdate;\n    try\n      List.Clear;\n      for I := 0 to FieldDefs.Count - 1 do\n      {$IFNDEF FPC}\n        if not (FieldDefs[I].DataType in [Low(TBlobType)..High(TBlobType)]) then\n      {$ELSE}\n        if not (FieldDefs[I].DataType in [ftBlob..ftTypedBinary]) then\n      {$ENDIF}\n          List.AddObject(FieldDefs[I].Name, Pointer(not FieldDefs[I].Required));\n    finally\n      List.EndUpdate;\n    end;\n  except\n    if ErrorName <> '' then\n      MessageDlg(Format(SSQLDataSetOpen, [ErrorName]), mtError, [mbOK], 0);\n  end;\nend;\n\nprocedure GetDataFieldNames(Dataset: TDataset; ErrorName: string; List: TStrings);\nvar\n  I: Integer;\nbegin\n  with Dataset do\n  try\n    FieldDefs.Update;\n    List.BeginUpdate;\n    try\n      List.Clear;\n      for I := 0 to FieldDefs.Count - 1 do\n        List.AddObject(FieldDefs[I].Name, Pointer(not FieldDefs[I].Required));\n    finally\n      List.EndUpdate;\n    end;\n  except\n    if ErrorName <> '' then\n      MessageDlg(Format(SSQLDataSetOpen, [ErrorName]), mtError, [mbOK], 0);\n  end;\nend;\n\nprocedure ParseUpdateSQL(const SQL, QuoteString: string; var TableName: string;\n  UpdateFields: TStrings; WhereFields: TStrings);\nbegin\n  with TSQLParser.Create(SQL, QuoteString) do\n  try\n    GetUpdateTableName(TableName);\n    if Assigned(UpdateFields) then\n    begin\n      Reset;\n      GetUpdateFields(UpdateFields);\n    end;\n    if Assigned(WhereFields) then\n    begin\n      Reset;\n      GetWhereFields(WhereFields);\n    end;\n  finally\n    Free;\n  end;\nend;\n\n{ TSQLParser }\n\nconstructor TSQLParser.Create(const Text, QuoteString: string);\nbegin\n  FText := Text;\n  FSourcePtr := PChar(Text);\n  FQuoteString := QuoteString;\n  if FQuoteString = '' then\n    FQuoteString := '\"\"';\n  if Length(FQuoteString) = 1 then\n    FQuoteString := FQuoteString + FQuoteString;\n  NextToken;\nend;\n\nfunction TSQLParser.NextToken: TSQLToken;\nvar\n  P, TokenStart: PChar;\n  IsParam: Boolean;\n\n  {$IFNDEF FPC}\n  function IsKatakana(const Chr: Byte): Boolean;\n  begin\n    Result := (SysLocale.PriLangID = LANG_JAPANESE) and (Chr in [$A1..$DF]);\n  end;\n  {$ENDIF}\n\nbegin\n  if FToken = stEnd then SysUtils.Abort;\n  FTokenString := '';\n  FSymbolQuoted := False;\n  P := FSourcePtr;\n  while (P^ <> #0) and (P^ <= ' ') do Inc(P);\n  FTokenPtr := P;\n  case P^ of\n    'A'..'Z', 'a'..'z', '_', '$', #127..#255:\n      begin\n        TokenStart := P;\n        if not SysLocale.FarEast then\n        begin\n          Inc(P);\n          while CharInSet(P^, ['A'..'Z', 'a'..'z', '0'..'9', '_', '\"', '$', #127..#255] ) do Inc(P);\n          if P^ = '.' then Inc(P);//!!! This must be added for syslocale fareast also\n        end\n        else\n          begin\n            while TRUE do\n            begin\n              if CharInSet(P^, ['A'..'Z', 'a'..'z', '0'..'9', '_', '.', '\"', '$']) or\n                 {$IFNDEF FPC}IsKatakana(Byte(P^)){$ELSE}False{$ENDIF} then\n                Inc(P)\n              else\n                if CharInSet(P^, LeadBytes) then\n                  Inc(P, 2)\n                else\n                  Break;\n            end;\n          end;\n        SetString(FTokenString, TokenStart, P - TokenStart);\n        FToken := stSymbol;\n      end;\n    '-', '0'..'9':\n      begin\n        TokenStart := P;\n        Inc(P);\n        while CharInSet(P^, ['0'..'9', '.', 'e', 'E', '+', '-'] )do Inc(P);\n        SetString(FTokenString, TokenStart, P - TokenStart);\n        FToken := stNumber;\n      end;\n    ',':\n      begin\n        Inc(P);\n        FToken := stComma;\n      end;\n    ';':\n      begin\n        Inc(P);\n        FToken := stSemiColon;\n      end;\n    '=':\n      begin\n        Inc(P);\n        FToken := stEQ;\n      end;\n    '(':\n      begin\n        Inc(P);\n        FToken := stLParen;\n      end;\n    ')':\n      begin\n        Inc(P);\n        FToken := stRParen;\n      end;\n    #0:\n      FToken := stEnd;\n  else\n    if P^ = FQuoteString[1] then\n    begin\n      Inc(P);\n      IsParam := P^ = ':';\n      if IsParam then Inc(P);\n      TokenStart := P;\n      while not CharInSet(P^, [FQuoteString[2], #0]) do Inc(P);\n      SetString(FTokenString, TokenStart, P - TokenStart);\n      Inc(P);\n      if P^ = '.' then\n      begin\n        FTokenString := FTokenString + '.';\n        Inc(P);\n      end;\n      Trim(FTokenString);\n      FToken := stSymbol;\n      FSymbolQuoted := True;\n    end\n    else\n    begin\n      FToken := stOther;\n      Inc(P);\n    end;\n  end;\n  FSourcePtr := P;\n  if (FToken = stSymbol) and\n    (FTokenString[Length(FTokenString)] = '.') then FToken := stAlias;\n  Result := FToken;\nend;\n\nprocedure TSQLParser.Reset;\nbegin\n  FSourcePtr := PChar(FText);\n  FToken := stSymbol;\n  NextToken;\nend;\n\nfunction TSQLParser.TokenSymbolIs(const S: string): Boolean;\nbegin\n  Result := (FToken = stSymbol) and (CompareText(FTokenString, S) = 0);\nend;\n\nprocedure TSQLParser.GetSelectTableNames(List: TStrings);\nbegin\n  List.BeginUpdate;\n  try\n    List.Clear;\n    if TokenSymbolIs('SELECT') then { Do not localize }\n    try\n      while not TokenSymbolIs('FROM') do NextToken; { Do not localize }\n      NextToken;\n      while FToken = stSymbol do\n      begin\n        List.AddObject(FTokenString, Pointer(Integer(FSymbolQuoted)));\n        if NextToken = stSymbol then NextToken;\n        if FToken = stComma then NextToken\n        else break;\n      end;\n    except\n    end;\n  finally\n    List.EndUpdate;\n  end;\nend;\n\nprocedure TSQLParser.GetUpdateTableName(var TableName: string);\nbegin\n  if TokenSymbolIs('UPDATE') and (NextToken = stSymbol) then { Do not localize }\n    TableName := FTokenString else\n    TableName := '';\nend;\n\nprocedure TSQLParser.GetUpdateFields(List: TStrings);\nbegin\n  List.BeginUpdate;\n  try\n    List.Clear;\n    if TokenSymbolIs('UPDATE') then { Do not localize }\n    try\n      while not TokenSymbolIs('SET') do NextToken; { Do not localize }\n      NextToken;\n      while True do\n      begin\n        if FToken = stAlias then NextToken;\n        if FToken <> stSymbol then Break;\n        List.Add(FTokenString);\n        if NextToken <> stEQ then Break;\n        while NextToken <> stComma do\n          if TokenSymbolIs('WHERE') or TokenSymbolIs('UPDATE') then Exit;{ Do not localize }\n        NextToken;\n      end;\n    except\n    end;\n  finally\n    List.EndUpdate;\n  end;\nend;\n\nprocedure TSQLParser.GetWhereFields(List: TStrings);\nbegin\n  List.BeginUpdate;\n  try\n    List.Clear;\n    if TokenSymbolIs('UPDATE') then { Do not localize }\n    try\n      while not TokenSymbolIs('WHERE') do NextToken; { Do not localize }\n      NextToken;\n      while True do\n      begin\n        while FToken in [stLParen, stRParen, stAlias, stOther] do NextToken;\n        if FToken <> stSymbol then Break;\n        List.Add(FTokenString);\n        NextToken;\n        if (FToken <> stEQ) and not TokenSymbolIs('IS') then Break;\n        while true do\n        begin\n          NextToken;\n          if FToken in [stEnd, stSemiColon] then Exit; //!!!!stSemiColon should be the statement separator\n          if TokenSymbolIs('AND') then Break; { Do not localize }\n        end;\n        NextToken;\n      end;\n    except\n    end;\n  finally\n    List.EndUpdate;\n  end;\nend;\n\n{ TUpdateSQLEditor }\n\n{ Private Methods }\n\nfunction TZUpdateSQLEditForm.Edit: Boolean;\nvar\n  Index: TUpdateKind;\n  DataSetName: string;\nbegin\n  Result := False;\n  ConnectionOpened := False;\n  if Assigned(UpdateSQL.DataSet) and (UpdateSQL.DataSet is TZAbstractDataset) then\n  begin\n    DataSet := TZAbstractDataset(UpdateSQL.DataSet);\n    DataSetName := Format('%s%s%s', [DataSet.Owner.Name, DotSep, DataSet.Name]);\n    if Assigned(DataSet.Connection) and not DataSet.Connection.Connected then\n    begin\n      DataSet.Connection.Connect;\n      ConnectionOpened := True;\n    end;\n  end else\n    DataSetName := SNoDataSet;\n  Caption := Format('%s%s%s (%s)', [UpdateSQL.Owner.Name, DotSep, UpdateSQL.Name, DataSetName]);\n  try\n    for Index := Low(TUpdateKind) to High(TUpdateKind) do\n    begin\n      SQLText[Index] := TStringList.Create;\n      SQLText[Index].Assign(UpdateSQL.SQL[Index]);\n    end;\n    StatementType.ItemIndex := 0;\n    StatementTypeClick(Self);\n    InitUpdateTableNames;\n    ShowWait(InitGenerateOptions);\n    PageControl.ActivePage := PageControl.Pages[0];\n    if ShowModal = mrOk then\n    begin\n      for Index := low(TUpdateKind) to high(TUpdateKind) do\n        UpdateSQL.SQL[Index] := SQLText[Index];\n      Result := True;\n    end;\n  finally\n    for Index := Low(TUpdateKind) to High(TUpdateKind) do\n      SQLText[Index].Free;\n  end;\nend;\n\nprocedure TZUpdateSQLEditForm.GenWhereClause(const TabAlias: string;\n  KeyFields, SQL: TStrings);\nvar\n  I: Integer;\n  BindText: string;\n  FieldName: string;\n  OldFieldName: string;\nbegin\n  SQL.Add('WHERE'); { Do not localize }\n  for I := 0 to KeyFields.Count - 1 do\n  begin\n    FieldName := KeyFields[I];\n    OldFieldName := 'OLD_' + FieldName;\n    if QuoteFields.Checked then\n      FieldName := InternalQuoteIdentifier(FieldName, QuoteChar);\n    if not Assigned(KeyFields.Objects[I]) then\n      BindText := Format('  %s%s = :%s', { Do not localize }\n        [TabAlias, FieldName, OldFieldName])\n    else\n      BindText := Format('  ((%0:s%1:s IS NULL AND :%2:s IS NULL) OR (%0:s%1:s = :%2:s))', { Do not localize }\n        [TabAlias, FieldName, OldFieldName]);\n    if I < KeyFields.Count - 1 then\n      BindText := Format('%s AND',[BindText]); { Do not localize }\n    SQL.Add(BindText);\n  end;\nend;\n\nprocedure TZUpdateSQLEditForm.GenDeleteSQL(const TableName: string;\n  KeyFields, SQL: TStrings);\nbegin\n  SQL.Add(Format('DELETE FROM %s', [TableName])); { Do not localize }\n  GenWhereClause(GetTableRef(TableName), KeyFields, SQL);\nend;\n\nprocedure TZUpdateSQLEditForm.GenInsertSQL(const TableName: string;\n  UpdateFields, SQL: TStrings);\n\n  procedure GenFieldList(const TabName, ParamChar: String);\n  var\n    L: string;\n    I: integer;\n    Comma: string;\n    FieldName: string;\n  begin\n    L := '  (';\n    Comma := ', ';\n    for I := 0 to UpdateFields.Count - 1 do\n    begin\n      if I = UpdateFields.Count - 1 then Comma := '';\n      FieldName := UpdateFields[I];\n      if QuoteFields.Checked and (ParamChar = '') then\n        FieldName := InternalQuoteIdentifier(FieldName, QuoteChar);\n      L := Format('%s%s%s%s',[L, ParamChar, FieldName, Comma]);\n      if (Length(L) > 70) and (I <> UpdateFields.Count - 1) then\n      begin\n        SQL.Add(L);\n        L := '   ';\n      end;\n    end;\n    SQL.Add(L+')');\n  end;\n\nbegin\n  SQL.Add(Format('INSERT INTO %s', [TableName])); { Do not localize }\n  GenFieldList(GetTableRef(TableName), '');\n  SQL.Add('VALUES'); { Do not localize }\n  GenFieldList('', ':');\nend;\n\nprocedure TZUpdateSQLEditForm.GenModifySQL(const TableName: string;\n  KeyFields, UpdateFields, SQL: TStrings);\nvar\n  I: integer;\n  Comma: string;\n  TableRef: string;\n  FieldName: string;\nbegin\n  SQL.Add(Format('UPDATE %s SET', [TableName]));  { Do not localize }\n  Comma := ',';\n  TableRef := GetTableRef(TableName);\n  for I := 0 to UpdateFields.Count - 1 do\n  begin\n    if I = UpdateFields.Count -1 then Comma := '';\n    FieldName := UpdateFields[I];\n    if QuoteFields.Checked then\n      FieldName := InternalQuoteIdentifier(FieldName, QuoteChar);\n    SQL.Add(Format('  %s = :%s%s',\n      [FieldName, UpdateFields[I], Comma]));\n  end;\n  GenWhereClause(TableRef, KeyFields, SQL);\nend;\n\nprocedure TZUpdateSQLEditForm.GenerateSQL;\n\n  function QuotedTableName(const BaseName: string): string;\n  begin\n    if QuoteFields.Checked then\n      Result := InternalQuoteIdentifier(BaseName, QuoteChar)\n    else\n      Result := BaseName;\n  end;\n\nvar\n  KeyFields: TStringList;\n  UpdateFields: TStringList;\n  TableName: string;\nbegin\n  if (KeyFieldList.SelCount = 0) or (UpdateFieldList.SelCount = 0) then\n    raise Exception.Create(SSQLGenSelect);\n  KeyFields := TStringList.Create;\n  try\n    GetSelectedItems(KeyFieldList, KeyFields);\n    UpdateFields := TStringList.Create;\n    try\n      GetSelectedItems(UpdateFieldList, UpdateFields);\n      TableName := QuotedTableName(UpdateTableName.Text);\n      if (SQLText[ukDelete].Text <> '') or (SQLText[ukInsert].Text <> '') or (SQLText[ukModify].Text <> '') then\n        if MessageDlg('The SQL property is not empty. Do you want to clear it before the generation?', mtWarning, [mbYes, mbNo], 0) = mrYes then\n        begin\n          SQLText[ukDelete].Clear;\n          SQLText[ukInsert].Clear;\n          SQLText[ukModify].Clear;\n        end\n        else\n        begin\n          SQLText[ukDelete].Text := SQLText[ukDelete].Text + '';//!!!Statement separator should be added\n          SQLText[ukDelete].Add('');\n          SQLText[ukInsert].Text := SQLText[ukInsert].Text + '';//!!!Statement separator should be added\n          SQLText[ukInsert].Add('');\n          SQLText[ukModify].Text := SQLText[ukModify].Text + '';//!!!Statement separator should be added\n          SQLText[ukModify].Add('');\n        end;\n      GenDeleteSQL(TableName, KeyFields, SQLText[ukDelete]);\n      GenInsertSQL(TableName, UpdateFields, SQLText[ukInsert]);\n      GenModifySQL(TableName, KeyFields, UpdateFields,\n        SQLText[ukModify]);\n      SQLMemo.Modified := False;\n      StatementTypeClick(Self);\n      PageControl.SelectNextPage(True);\n    finally\n      UpdateFields.Free;\n    end;\n  finally\n    KeyFields.Free;\n  end;\nend;\n\nprocedure TZUpdateSQLEditForm.GetDataSetFieldNames;\nbegin\n  if Assigned(DataSet) and Assigned(Dataset.Connection) then\n  begin\n    GetDataKeyNames(DataSet, DataSet.Name, KeyFieldList.Items);\n    GetDataFieldNames(DataSet, DataSet.Name, UpdateFieldList.Items);\n  end;\nend;\n\nprocedure TZUpdateSQLEditForm.GetTableFieldNames;\nvar\n  ResultSet: IZResultSet;\nbegin\n  if Assigned(DataSet) and Assigned(DataSet.Connection) and Assigned(DataSet.Connection.dbcConnection)then\n  begin\n    KeyFieldList.Clear;\n    UpdateFieldList.Clear;\n    ResultSet := DataSet.Connection.DbcConnection.GetMetadata.GetColumns('', '', UpdateTableName.Text, '');\n    if Assigned(ResultSet) then\n    begin\n      while ResultSet.Next do\n      begin\n        if ResultSet.GetBooleanByName('SEARCHABLE') then\n          KeyFieldList.Items.AddObject(ResultSet.GetStringByName('COLUMN_NAME'), Pointer(ResultSet.GetIntByName('NULLABLE') <> 0));\n        if ResultSet.GetBooleanByName('WRITABLE') then\n          UpdateFieldList.Items.Add(ResultSet.GetStringByName('COLUMN_NAME')) ;\n      end;\n    end;\n    FDatasetDefaults := False;\n  end;\nend;\n\nfunction TZUpdateSQLEditForm.GetTableRef(const TabName: string): string;\nbegin\n  if QuoteChar <> '' then\n    Result :=  TabName + '.' else\n    REsult := '';\nend;\n\nprocedure TZUpdateSQLEditForm.InitGenerateOptions;\nvar\n  UpdTabName: string;\n\n  procedure InitFromDataSet;\n  begin\n    // If this is a Query with more than 1 table in the \"from\" clause then\n    //  initialize the list of fields from the table rather than the dataset.\n    if (UpdateTableName.Items.Count > 1) then\n      GetTableFieldNames\n    else\n    begin\n      GetDataSetFieldNames;\n      FDatasetDefaults := True;\n    end;\n    SetDefaultSelections;\n  end;\n\n  procedure InitFromUpdateSQL;\n  var\n    UpdFields,\n    WhFields: TStrings;\n  begin\n    UpdFields := TStringList.Create;\n    try\n      WhFields := TStringList.Create;\n      try\n        ParseUpdateSQL(SQLText[ukModify].Text, QuoteChar, UpdTabName, UpdFields, WhFields);\n        GetDataSetFieldNames;\n        if SetSelectedItems(UpdateFieldList, UpdFields) < 1 then\n          SelectAll(UpdateFieldList);\n        if SetSelectedItems(KeyFieldList, WhFields) < 1 then\n          SelectAll(KeyFieldList);\n      finally\n        WhFields.Free;\n      end;\n    finally\n      UpdFields.Free;\n    end;\n  end;\n\nbegin\n  // If there are existing update SQL statements, try to initialize the\n  // dialog with the fields that correspond to them.\n  if SQLText[ukModify].Count > 0 then\n  begin\n    ParseUpdateSQL(SQLText[ukModify].Text, QuoteChar, UpdTabName, nil, nil);\n    // If the table name from the update statement is not part of the\n    // dataset, then initialize from the dataset instead.\n    if (UpdateTableName.Items.Count > 0) and\n       (UpdateTableName.Items.IndexOf(UpdTabName) > -1) then\n    begin\n      UpdateTableName.Text := UpdTabName;\n      InitFromUpdateSQL;\n    end else\n    begin\n      InitFromDataSet;\n      UpdateTableName.Items.Add(UpdTabName);\n    end;\n  end else\n    InitFromDataSet;\n  SetButtonStates;\nend;\n\ntype\n  THackDataSet = class(TZAbstractDataset);\n  \nprocedure TZUpdateSQLEditForm.InitUpdateTableNames;\nvar\n  I: Integer;\n  TableName: string;\n  Tokenizer: IZTokenizer;\n  StatementAnalyser: IZStatementAnalyser;\n  SelectSchema: IZSelectSchema;\nbegin\n  QuoteChar := '\"\"';\n  if Assigned(DataSet) and Assigned(DataSet.Connection)\n    and Assigned(DataSet.Connection.DbcConnection)then\n  begin\n    QuoteChar := DataSet.Connection.DbcConnection.GetMetadata.GetDatabaseInfo.\n      GetIdentifierQuoteString;\n    if Length(QuoteChar) = 1 then\n      QuoteChar := QuoteChar + QuoteChar;\n    { Parses the Select statement and retrieves a schema object. }\n    Tokenizer := DataSet.Connection.DbcDriver.GetTokenizer;\n    StatementAnalyser := DataSet.Connection.DbcDriver.GetStatementAnalyser;\n    SelectSchema := StatementAnalyser.DefineSelectSchemaFromQuery(Tokenizer,\n      THackDataSet(DataSet).SQL.Text);\n    if Assigned(SelectSchema) then\n    begin\n      UpdateTableName.Clear;\n      for I := 0 to SelectSchema.TableCount - 1 do\n        UpdateTableName.Items.Add(SelectSchema.Tables[I].Table);//!!!Schema support\n    end;\n  end\n  else\n    if Assigned(Dataset) then\n    begin\n      TableName := '';\n      if SQLText[ukModify].Count > 0 then\n        ParseUpdateSql(SQLText[ukModify].Text, QuoteChar, TableName, nil, nil);\n      if TableName <> '' then\n        UpdateTableName.Items.Add(TableName);\n    end;\n  if UpdateTableName.Items.Count > 0 then\n     UpdateTableName.ItemIndex := 0;\nend;\n\nprocedure TZUpdateSQLEditForm.SetButtonStates;\nbegin\n  GetTableFieldsButton.Enabled := UpdateTableName.Text <> '';\n  PrimaryKeyButton.Enabled := GetTableFieldsButton.Enabled and\n    (KeyFieldList.Items.Count > 0);\n  GenerateButton.Enabled := GetTableFieldsButton.Enabled and\n    (UpdateFieldList.Items.Count > 0) and (KeyFieldList.Items.Count > 0);\n  DefaultButton.Enabled := Assigned(DataSet) and not FDatasetDefaults;\nend;\n\nprocedure TZUpdateSQLEditForm.SelectPrimaryKeyFields;\nvar\n  I: Integer;\n  Index: Integer;\n  PKeys: TZSQLMetadata;\nbegin\n  if KeyFieldList.Items.Count < 1 then Exit;\n  with Dataset do\n  begin\n    for I := 0 to KeyFieldList.Items.Count - 1  do\n      KeyFieldList.Selected[I] := False;\n    PKeys := TZSQLMetadata.Create(nil);\n    try\n      PKeys.Connection := Connection;\n      PKeys.TableName := UpdateTableName.Text;\n      PKeys.MetadataType := mdPrimaryKeys;\n      PKeys.Open;\n      PKeys.First;\n      while not PKeys.Eof do\n      begin\n        Index := KeyFieldList.Items.IndexOf(PKeys.FieldByName('COLUMN_NAME').AsString);\n        if Index > -1 then KeyFieldList.Selected[Index] := True;\n        PKeys.Next;\n      end;\n    finally\n      PKeys.Free;\n    end;\n  end;\nend;\n\nprocedure TZUpdateSQLEditForm.SetDefaultSelections;\nvar\n  DSFields: TStringList;\nbegin\n  if FDatasetDefaults or not Assigned(DataSet) then\n  begin\n    SelectAll(UpdateFieldList);\n    SelectAll(KeyFieldList);\n  end\n  else if (DataSet.FieldDefs.Count > 0) then\n  begin\n    DSFields := TStringList.Create;\n    try\n      GetDataFieldNames(DataSet, '', DSFields);\n      SetSelectedItems(KeyFieldList, DSFields);\n      SetSelectedItems(UpdateFieldList, DSFields);\n    finally\n      DSFields.Free;\n    end;\n  end;\nend;\n\nprocedure TZUpdateSQLEditForm.ShowWait(WaitMethod: TWaitMethod);\nbegin\n  Screen.Cursor := crHourGlass;\n  try\n    WaitMethod;\n  finally\n    Screen.Cursor := crDefault;\n  end;\nend;\n\n{ Event Handlers }\n\nprocedure TZUpdateSQLEditForm.FormCreate(Sender: TObject);\nbegin\n//  HelpContext := hcDUpdateSQL;\nend;\n\nprocedure TZUpdateSQLEditForm.FormResize(Sender: TObject);\nVar i: Integer;\nbegin\n  i := PageControl.Height - 92;\n  If i < 0 Then i := 0;\n  SQLMemo.Height := i;\nend;\n\nprocedure TZUpdateSQLEditForm.HelpButtonClick(Sender: TObject);\nbegin\n  Application.HelpContext(HelpContext);\nend;\n\nprocedure TZUpdateSQLEditForm.StatementTypeClick(Sender: TObject);\nbegin\n  if SQLMemo.Modified then\n    SQLText[TUpdateKind(StmtIndex)].Assign(SQLMemo.Lines);\n  StmtIndex := StatementType.ItemIndex;\n  SQLMemo.Lines.Assign(SQLText[TUpdateKind(StmtIndex)]);\nend;\n\nprocedure TZUpdateSQLEditForm.OkButtonClick(Sender: TObject);\nbegin\n  if SQLMemo.Modified then\n    SQLText[TUpdateKind(StmtIndex)].Assign(SQLMemo.Lines);\nend;\n\nprocedure TZUpdateSQLEditForm.DefaultButtonClick(Sender: TObject);\nbegin\n  with UpdateTableName do\n    if Items.Count > 0 then ItemIndex := 0;\n  ShowWait(GetDataSetFieldNames);\n  FDatasetDefaults := True;\n  SetDefaultSelections;\n  KeyfieldList.SetFocus;\n  SetButtonStates;\nend;\n\nprocedure TZUpdateSQLEditForm.GenerateButtonClick(Sender: TObject);\nbegin\n  GenerateSQL;\n  FSettingsChanged := False;\nend;\n\nprocedure TZUpdateSQLEditForm.PrimaryKeyButtonClick(Sender: TObject);\nbegin\n  ShowWait(SelectPrimaryKeyFields);\n  SettingsChanged(Sender);\nend;\n\nprocedure TZUpdateSQLEditForm.PageControlChanging(Sender: TObject;\n  var AllowChange: Boolean);\nbegin\n  if (PageControl.ActivePage = PageControl.Pages[0]) and\n    not SQLPage.Enabled then\n    AllowChange := False;\nend;\n\nprocedure TZUpdateSQLEditForm.FormDestroy(Sender: TObject);\nbegin\n  if ConnectionOpened then\n    DataSet.Connection.Disconnect;\nend;\n\nprocedure TZUpdateSQLEditForm.GetTableFieldsButtonClick(Sender: TObject);\nbegin\n  ShowWait(GetTableFieldNames);\n  SetDefaultSelections;\n  SettingsChanged(Sender);\nend;\n\nprocedure TZUpdateSQLEditForm.SettingsChanged(Sender: TObject);\nbegin\n  FSettingsChanged := True;\n  FDatasetDefaults := False;\n  SetButtonStates;\nend;\n\nprocedure TZUpdateSQLEditForm.FormCloseQuery(Sender: TObject;\n  var CanClose: Boolean);\nbegin\n  if (ModalResult = mrOK) and FSettingsChanged then\n    CanClose := MessageDlg(SSQLNotGenerated, mtConfirmation,\n      mbYesNoCancel, 0) = mrYes;\nend;\n\nprocedure TZUpdateSQLEditForm.UpdateTableNameChange(Sender: TObject);\nbegin\n  SettingsChanged(Sender);\nend;\n\nprocedure TZUpdateSQLEditForm.UpdateTableNameClick(Sender: TObject);\nbegin\n  if not Visible then Exit;\n  GetTableFieldsButtonClick(Sender);\nend;\n\nprocedure TZUpdateSQLEditForm.SelectAllClick(Sender: TObject);\nbegin\n  SelectAll(FieldListPopup.PopupComponent as TListBox);\nend;\n\nprocedure TZUpdateSQLEditForm.ClearAllClick(Sender: TObject);\nvar\n  I: Integer;\nbegin\n  with FieldListPopup.PopupComponent as TListBox do\n  begin\n    Items.BeginUpdate;\n    try\n      for I := 0 to Items.Count - 1 do\n        Selected[I] := False;\n    finally\n      Items.EndUpdate;\n    end;\n  end;\nend;\n\nprocedure TZUpdateSQLEditForm.SQLMemoKeyPress(Sender: TObject;\n  var Key: Char);\nbegin\n  if Key = #27 then Close;\nend;\n\n{$IFDEF FPC}\ninitialization\n{$i ZUpdateSqlEditor.lrs}\n{$ENDIF}\n\nend.\n"
  },
  {
    "path": "lib/zeosdbo/src/core/ZClasses.pas",
    "content": "{*********************************************************}\n{                                                         }\n{                 Zeos Database Objects                   }\n{             Core classes and interfaces                 }\n{                                                         }\n{          Originally written by Sergey Seroukhov         }\n{                                                         }\n{*********************************************************}\n\n{@********************************************************}\n{    Copyright (c) 1999-2012 Zeos Development Group       }\n{                                                         }\n{ License Agreement:                                      }\n{                                                         }\n{ This library is distributed in the hope that it will be }\n{ useful, but WITHOUT ANY WARRANTY; without even the      }\n{ implied warranty of MERCHANTABILITY or FITNESS FOR      }\n{ A PARTICULAR PURPOSE.  See the GNU Lesser General       }\n{ Public License for more details.                        }\n{                                                         }\n{ The source code of the ZEOS Libraries and packages are  }\n{ distributed under the Library GNU General Public        }\n{ License (see the file COPYING / COPYING.ZEOS)           }\n{ with the following  modification:                       }\n{ As a special exception, the copyright holders of this   }\n{ library give you permission to link this library with   }\n{ independent modules to produce an executable,           }\n{ regardless of the license terms of these independent    }\n{ modules, and to copy and distribute the resulting       }\n{ executable under terms of your choice, provided that    }\n{ you also meet, for each linked independent module,      }\n{ the terms and conditions of the license of that module. }\n{ An independent module is a module which is not derived  }\n{ from or based on this library. If you modify this       }\n{ library, you may extend this exception to your version  }\n{ of the library, but you are not obligated to do so.     }\n{ If you do not wish to do so, delete this exception      }\n{ statement from your version.                            }\n{                                                         }\n{                                                         }\n{ The project web site is located on:                     }\n{   http://zeos.firmos.at  (FORUM)                        }\n{   http://sourceforge.net/p/zeoslib/tickets/ (BUGTRACKER)}\n{   svn://svn.code.sf.net/p/zeoslib/code-0/trunk (SVN)    }\n{                                                         }\n{   http://www.sourceforge.net/projects/zeoslib.          }\n{                                                         }\n{                                                         }\n{                                 Zeos Development Group. }\n{********************************************************@}\n\nunit ZClasses;\n\ninterface\n\n{$I ZCore.inc}\n\nuses\n  SysUtils, Classes;\n\nconst\n  ZEOS_MAJOR_VERSION = 7;\n  ZEOS_MINOR_VERSION = 1;\n  ZEOS_SUB_VERSION = 4;\n  ZEOS_STATUS = 'stable';\n  ZEOS_VERSION = '7.1.4-stable';\n{$IFDEF ENABLE_POOLED}\n  {Pooled Protocol Prefix, including final dot}\n  PooledPrefix = 'pooled.';\n{$ENDIF}\n\n\ntype\n  {$IFDEF OLDFPC}\n  PDateTime = ^TDateTime;\n\n  TAggregatedObject = class(TObject)\n  private\n    FController: Pointer;\n    function GetController: IInterface;\n  protected\n    {$IFDEF FPC2_5UP}\n    function QueryInterface({$IFDEF FPC_HAS_CONSTREF}constref{$ELSE}const{$ENDIF} iid : tguid;out obj) : longint;{$IFNDEF WINDOWS}cdecl{$ELSE}stdcall{$ENDIF}; virtual;\n    function _AddRef : longint;{$IFNDEF WINDOWS}cdecl{$ELSE}stdcall{$ENDIF};\n    function _Release : longint;{$IFNDEF WINDOWS}cdecl{$ELSE}stdcall{$ENDIF};\n    {$ELSE}\n    function QueryInterface(const iid : tguid;out obj) : longint;stdcall;\n    function _AddRef : longint;stdcall;\n    function _Release : longint;stdcall;\n    {$ENDIF}\n  public\n    constructor Create(const Controller: IInterface);\n    property Controller: IInterface read GetController;\n  end;\n\n  TContainedObject = class(TAggregatedObject, IInterface)\n  protected\n    {$IFDEF FPC2_5UP}\n    function QueryInterface({$IFDEF FPC_HAS_CONSTREF}constref{$ELSE}const{$ENDIF} iid : tguid;out obj) : longint;{$IFNDEF WINDOWS}cdecl{$ELSE}stdcall{$ENDIF}; override;\n    {$ELSE}\n    function QueryInterface(const iid : tguid;out obj) : longint;stdcall;\n    {$ENDIF}\n\n  end;\n  {$ENDIF}\n\n  {** Replacement for generic interface type. }\n  IZInterface = IUnknown;\n\n  {** Represents an interface for all abstract object. }\n  IZObject = interface(IZInterface)\n    ['{EF46E5F7-00CF-4DDA-BED0-057D6686AEE0}']\n    function Equals(const Value: IZInterface): Boolean;\n    function GetHashCode: LongInt;\n    function Clone: IZInterface;\n    function ToString: string;\n    function InstanceOf(const IId: TGUID): Boolean;\n  end;\n\n  {** Represents a fake interface for coparable objects. }\n  IZComparable = interface(IZObject)\n    ['{04112081-F07B-4BBF-A757-817816EB67C1}']\n  end;\n\n  {** Represents an interface to clone objects. }\n  IZClonnable = interface(IZObject)\n    ['{ECB7F3A4-7B2E-4130-BA66-54A2D43C0149}']\n  end;\n\n  {** Represents a generic collection iterator interface. }\n  IZIterator = interface(IZObject)\n    ['{D964DDD0-2308-4D9B-BD36-5810632512F7}']\n    function HasNext: Boolean;\n    function Next: IZInterface;\n  end;\n\n  {** Represents a collection of object interfaces. }\n  IZCollection = interface(IZClonnable)\n    ['{51417C87-F992-4CAD-BC53-CF3925DD6E4C}']\n\n    function Get(Index: Integer): IZInterface;\n    procedure Put(Index: Integer; const Item: IZInterface);\n    function IndexOf(const Item: IZInterface): Integer;\n    function GetCount: Integer;\n    function GetIterator: IZIterator;\n\n    function First: IZInterface;\n    function Last: IZInterface;\n\n    function Add(const Item: IZInterface): Integer;\n    procedure Insert(Index: Integer; const Item: IZInterface);\n    function Remove(const Item: IZInterface): Integer;\n\n    procedure Exchange(Index1, Index2: Integer);\n    procedure Delete(Index: Integer);\n    procedure Clear;\n\n    function Contains(const Item: IZInterface): Boolean;\n    function ContainsAll(const Col: IZCollection): Boolean;\n    function AddAll(const Col: IZCollection): Boolean;\n    function RemoveAll(const Col: IZCollection): Boolean;\n\n    property Count: Integer read GetCount;\n    property Items[Index: Integer]: IZInterface read Get write Put; default;\n  end;\n\n  {** Represents a hash map interface. }\n  IZHashMap = interface(IZClonnable)\n    ['{782C64F4-AD09-4F56-AF2B-E4193A05BBCE}']\n\n    function Get(const Key: IZInterface): IZInterface;\n    procedure Put(const Key: IZInterface; const Value: IZInterface);\n    function GetKeys: IZCollection;\n    function GetValues: IZCollection;\n    function GetCount: Integer;\n\n    function Remove(Key: IZInterface): Boolean;\n    procedure Clear;\n\n    property Count: Integer read GetCount;\n    property Keys: IZCollection read GetKeys;\n    property Values: IZCollection read GetValues;\n  end;\n\n  {** Represents a stack interface. }\n  IZStack = interface(IZClonnable)\n    ['{8FEA0B3F-0C02-4E70-BD8D-FB0F42D4497B}']\n\n    function Peek: IZInterface;\n    function Pop: IZInterface;\n    procedure Push(Value: IZInterface);\n    function GetCount: Integer;\n\n    property Count: Integer read GetCount;\n  end;\n\n{$IFDEF WITH_NEWTOBJECT} // to suppress the overload warning of the Equals overload, Marco. (overload a non overload-declared funtion)\n  {$WARNINGS OFF}\n{$ENDIF}\n  {** Implements an abstract interfaced object. }\n  TZAbstractObject = class(TInterfacedObject, IZObject)\n  public\n    function Equals(const Value: IZInterface): Boolean; {$IFDEF WITH_NEWTOBJECT}overload;{$ENDIF} virtual;\n    function GetHashCode: LongInt;\n    function Clone: IZInterface; virtual;\n    function ToString: string;{$IFDEF WITH_NEWTOBJECT}override{$ELSE} virtual{$ENDIF} ;\n    function InstanceOf(const IId: TGUID): Boolean;\n  end;\n{$IFDEF WITH_NEWTOBJECT}\n  {$WARNINGS ON}\n{$ENDIF}\n\nimplementation\n\nuses ZMessages, ZCompatibility;\n\n{$IFDEF oldFPC}\n\n{ TAggregatedObject }\n\nconstructor TAggregatedObject.Create(const Controller: IInterface);\nbegin\n  FController := Pointer(Controller);\nend;\n\nfunction TAggregatedObject.GetController: IInterface;\nbegin\n  Result := IInterface(FController);\nend;\n\n{$IFDEF FPC2_5UP}\nfunction TAggregatedObject.QueryInterface({$IFDEF FPC_HAS_CONSTREF}constref{$ELSE}const{$ENDIF} iid : tguid;out obj) : longint;\n{$ELSE}\nfunction TAggregatedObject.QueryInterface(const iid : tguid;out obj) : longint;stdcall;\n{$ENDIF}\nbegin\n  Result := IInterface(FController).QueryInterface(IID, Obj);\nend;\n\nfunction TAggregatedObject._AddRef: longint;\nbegin\n  Result := IInterface(FController)._AddRef;\nend;\n\nfunction TAggregatedObject._Release : longint;\nbegin\n  Result := IInterface(FController)._Release;\nend;\n\n{ TContainedObject }\n\n{$IFDEF FPC2_5UP}\nfunction TContainedObject.QueryInterface({$IFDEF FPC_HAS_CONSTREF}constref{$ELSE}const{$ENDIF} iid : tguid;out obj) : longint;{$IFNDEF WINDOWS}cdecl{$ELSE}stdcall{$ENDIF};\n{$ELSE}\nfunction TContainedObject.QueryInterface(const iid : tguid;out obj) : longint;stdcall;\n{$ENDIF}\n\nbegin\n  if GetInterface(IID, Obj) then\n    Result := S_OK\n  else\n    Result := E_NOINTERFACE;\nend;\n\n{$ENDIF}\n\n{ TZAbstractObject }\n\n{**\n  Checks is the specified value equals to this object.\n  @param Value an interface to some object.\n  @return <code>True</code> if the objects are identical.\n}\nfunction TZAbstractObject.Equals(const Value: IZInterface): Boolean;\nbegin\n  if Value <> nil then\n  begin\n    Result := (IZInterface(Self) = Value)\n      or ((Self as IZInterface) = (Value as IZInterface));\n  end else\n   Result := False;\nend;\n\n{**\n  Gets a unique hash for this object.\n  @return a unique hash for this object.\n}\nfunction TZAbstractObject.GetHashCode: LongInt;\nbegin\n  Result := LongInt(Self);\nend;\n\n{**\n  Clones an object instance.\n  @return a clonned object instance.\n}\nfunction TZAbstractObject.Clone: IZInterface;\nbegin\n  raise Exception.Create(SClonningIsNotSupported);\n  result := nil;\nend;\n\n{**\n  Checks is this object implements a specified interface.\n  @param IId an interface id.\n  @return <code>True</code> if this object support the interface.\n}\nfunction TZAbstractObject.InstanceOf(const IId: TGUID): Boolean;\nbegin\n  Result := GetInterfaceEntry(IId) <> nil;\nend;\n\n{**\n  Converts this object into the string representation.\n  @return a string representation for this object.\n}\nfunction TZAbstractObject.ToString: string;\nbegin\n  Result := Format('%s <%p>', [ClassName, Pointer(Self)])\nend;\n\nend.\n\n"
  },
  {
    "path": "lib/zeosdbo/src/core/ZCollections.pas",
    "content": "{*********************************************************}\n{                                                         }\n{                 Zeos Database Objects                   }\n{           Core collection and map classes               }\n{                                                         }\n{          Originally written by Sergey Seroukhov         }\n{                                                         }\n{*********************************************************}\n\n{@********************************************************}\n{    Copyright (c) 1999-2012 Zeos Development Group       }\n{                                                         }\n{ License Agreement:                                      }\n{                                                         }\n{ This library is distributed in the hope that it will be }\n{ useful, but WITHOUT ANY WARRANTY; without even the      }\n{ implied warranty of MERCHANTABILITY or FITNESS FOR      }\n{ A PARTICULAR PURPOSE.  See the GNU Lesser General       }\n{ Public License for more details.                        }\n{                                                         }\n{ The source code of the ZEOS Libraries and packages are  }\n{ distributed under the Library GNU General Public        }\n{ License (see the file COPYING / COPYING.ZEOS)           }\n{ with the following  modification:                       }\n{ As a special exception, the copyright holders of this   }\n{ library give you permission to link this library with   }\n{ independent modules to produce an executable,           }\n{ regardless of the license terms of these independent    }\n{ modules, and to copy and distribute the resulting       }\n{ executable under terms of your choice, provided that    }\n{ you also meet, for each linked independent module,      }\n{ the terms and conditions of the license of that module. }\n{ An independent module is a module which is not derived  }\n{ from or based on this library. If you modify this       }\n{ library, you may extend this exception to your version  }\n{ of the library, but you are not obligated to do so.     }\n{ If you do not wish to do so, delete this exception      }\n{ statement from your version.                            }\n{                                                         }\n{                                                         }\n{ The project web site is located on:                     }\n{   http://zeos.firmos.at  (FORUM)                        }\n{   http://sourceforge.net/p/zeoslib/tickets/ (BUGTRACKER)}\n{   svn://svn.code.sf.net/p/zeoslib/code-0/trunk (SVN)    }\n{                                                         }\n{   http://www.sourceforge.net/projects/zeoslib.          }\n{                                                         }\n{                                                         }\n{                                 Zeos Development Group. }\n{********************************************************@}\n\nunit ZCollections;\n\ninterface\n\n{$I ZCore.inc}\n\nuses Classes, ZClasses;\n\ntype\n\n  {** Implements an iterator for regular TZCollection collection. }\n  TZIterator = class (TZAbstractObject, IZIterator)\n  private\n    FCollection: IZCollection;\n    FCurrentIndex: Integer;\n  public\n    constructor Create(const Col: IZCollection);\n\n    function HasNext: Boolean;\n    function Next: IZInterface;\n  end;\n\n  {** Interface list types. }\n  TZInterfaceList = array[0..{$IFDEF WITH_MAXLISTSIZE_DEPRECATED}Maxint div 16{$ELSE}MaxListSize{$ENDIF} - 1] of IZInterface;\n  PZInterfaceList = ^TZInterfaceList;\n\n  {** Implenments a collection of interfaces. }\n  TZCollection = class(TZAbstractObject, IZCollection, IZClonnable)\n  private\n    FList: PZInterfaceList;\n    FCount: Integer;\n    FCapacity: Integer;\n  protected\n    class procedure Error(const Msg: string; Data: Integer);\n    procedure Grow;\n    procedure SetCapacity(NewCapacity: Integer);\n    procedure SetCount(NewCount: Integer);\n  public\n    constructor Create;\n    destructor Destroy; override;\n\n    function Clone: IZInterface; override;\n    function ToString: string; override;\n\n    function Get(Index: Integer): IZInterface;\n    procedure Put(Index: Integer; const Item: IZInterface);\n    function IndexOf(const Item: IZInterface): Integer;\n    function GetCount: Integer;\n    function GetIterator: IZIterator;\n\n    function First: IZInterface;\n    function Last: IZInterface;\n\n    function Add(const Item: IZInterface): Integer;\n    procedure Insert(Index: Integer; const Item: IZInterface);\n    function Remove(const Item: IZInterface): Integer;\n\n    procedure Exchange(Index1, Index2: Integer);\n    procedure Delete(Index: Integer);\n    procedure Clear;\n\n    function Contains(const Item: IZInterface): Boolean;\n    function ContainsAll(const Col: IZCollection): Boolean;\n    function AddAll(const Col: IZCollection): Boolean;\n    function RemoveAll(const Col: IZCollection): Boolean;\n\n    property Count: Integer read GetCount;\n    property Items[Index: Integer]: IZInterface read Get write Put; default;\n  end;\n\n  {** Implements an unmodifiable collection of interfaces. }\n  TZUnmodifiableCollection = class(TZAbstractObject, IZCollection, IZClonnable)\n  private\n    FCollection: IZCollection;\n  private\n    procedure RaiseException;\n  public\n    constructor Create(Collection: IZCollection);\n    destructor Destroy; override;\n\n    function Clone: IZInterface; override;\n    function ToString: string; override;\n\n    function Get(Index: Integer): IZInterface;\n    procedure Put(Index: Integer; const Item: IZInterface);\n    function IndexOf(const Item: IZInterface): Integer;\n    function GetCount: Integer;\n    function GetIterator: IZIterator;\n\n    function First: IZInterface;\n    function Last: IZInterface;\n\n    function Add(const Item: IZInterface): Integer;\n    procedure Insert(Index: Integer; const Item: IZInterface);\n    function Remove(const Item: IZInterface): Integer;\n\n    procedure Exchange(Index1, Index2: Integer);\n    procedure Delete(Index: Integer);\n    procedure Clear;\n\n    function Contains(const Item: IZInterface): Boolean;\n    function ContainsAll(const Col: IZCollection): Boolean;\n    function AddAll(const Col: IZCollection): Boolean;\n    function RemoveAll(const Col: IZCollection): Boolean;\n\n    property Count: Integer read GetCount;\n    property Items[Index: Integer]: IZInterface read Get write Put; default;\n  end;\n\n  {** Implements a hash map of interfaces. }\n  TZHashMap = class(TZAbstractObject, IZHashMap, IZClonnable)\n  private\n    FKeys: IZCollection;\n    FReadOnlyKeys: IZCollection;\n    FValues: IZCollection;\n    FReadOnlyValues: IZCollection;\n  public\n    constructor Create;\n    destructor Destroy; override;\n\n    function Clone: IZInterface; override;\n\n    function Get(const Key: IZInterface): IZInterface;\n    procedure Put(const Key: IZInterface; const Value: IZInterface);\n    function GetKeys: IZCollection;\n    function GetValues: IZCollection;\n    function GetCount: Integer;\n\n    function Remove(Key: IZInterface): Boolean;\n    procedure Clear;\n\n    property Count: Integer read GetCount;\n    property Keys: IZCollection read GetKeys;\n    property Values: IZCollection read GetValues;\n  end;\n\n  {** Implements a stack of interfaces. }\n  TZStack = class(TZAbstractObject, IZStack, IZClonnable)\n  private\n    FValues: IZCollection;\n  public\n    constructor Create;\n    destructor Destroy; override;\n\n    function Clone: IZInterface; override;\n    function ToString: string; override;\n\n    function Peek: IZInterface;\n    function Pop: IZInterface;\n    procedure Push(Value: IZInterface);\n    function GetCount: Integer;\n\n    property Count: Integer read GetCount;\n  end;\n\nimplementation\n\nuses SysUtils, ZMessages;\n\n{$IFDEF FPC}\n  {$HINTS OFF}\n{$ENDIF}\n\n{ TZIterator }\n\n{**\n  Creates this iterator for the specified interface list.\n  @param List a list of interfaces.\n}\nconstructor TZIterator.Create(const Col: IZCollection);\nbegin\n  FCollection := Col;\n  FCurrentIndex := 0;\nend;\n\n{**\n  Checks has the iterated collection more elements.\n  @return <code>True</code> if iterated collection has more elements.\n}\nfunction TZIterator.HasNext: Boolean;\nbegin\n  Result := FCurrentIndex < FCollection.Count;\nend;\n\n{**\n  Gets a next iterated element from the collection.\n  @return a next iterated element from the collection or <code>null</code>\n    if no more elements.\n}\nfunction TZIterator.Next: IZInterface;\nbegin\n  if FCurrentIndex < FCollection.Count then\n  begin\n    Result := FCollection[FCurrentIndex];\n    Inc(FCurrentIndex);\n  end else\n    Result := nil;\nend;\n\n{ TZCollection }\n\n{**\n  Creates this collection and assignes main properties.\n}\nconstructor TZCollection.Create;\nbegin\nend;\n\n{**\n  Destroys this object and frees the memory.\n}\ndestructor TZCollection.Destroy;\nbegin\n  Clear;\nend;\n\n{**\n  Raises a collection error.\n  @param Msg an error message.\n  @param Data a integer value to describe an error.\n}\nclass procedure TZCollection.Error(const Msg: string; Data: Integer);\n\n{$IFNDEF FPC}\n  function ReturnAddr: Pointer;\n  asm\n          MOV     EAX,[EBP+4]\n  end;\n{$ENDIF}\n\nbegin\n  {$IFDEF FPC}\n  raise EListError.CreateFmt(Msg,[Data]) at get_caller_addr(get_frame);\n  {$ELSE}\n  raise EListError.CreateFmt(Msg, [Data]) at ReturnAddr;\n  {$ENDIF}\nend;\n\n{**\n  Increases an element count.\n}\nprocedure TZCollection.Grow;\nvar\n  Delta: Integer;\nbegin\n  if FCapacity > 64 then\n    Delta := FCapacity div 4\n  else\n  begin\n    if FCapacity > 8 then\n      Delta := 16\n    else\n      Delta := 4;\n  end;\n  SetCapacity(FCapacity + Delta);\nend;\n\n{**\n  Sets a new list capacity.\n  @param NewCapacity a new list capacity.\n}\nprocedure TZCollection.SetCapacity(NewCapacity: Integer);\nbegin\n{$IFOPT R+}\n  if (NewCapacity < FCount) or (NewCapacity > {$IFDEF WITH_MAXLISTSIZE_DEPRECATED}Maxint div 16{$ELSE}MaxListSize{$ENDIF}) then\n    Error(SListCapacityError, NewCapacity);\n{$ENDIF}\n  if NewCapacity <> FCapacity then\n  begin\n    ReallocMem(FList, NewCapacity * SizeOf(IZInterface));\n    if NewCapacity > FCapacity then\n         FillChar(FList^[FCount], (NewCapacity - FCapacity) *\n            SizeOf(IZInterface), 0);\n    FCapacity := NewCapacity;\n  end;\nend;\n\n{**\n  Sets a new element count.\n  @param NewCount a new element count.\n}\nprocedure TZCollection.SetCount(NewCount: Integer);\nvar\n  I: Integer;\nbegin\n{$IFOPT R+}\n  if (NewCount < 0) or (NewCount > {$IFDEF WITH_MAXLISTSIZE_DEPRECATED}Maxint div 16{$ELSE}MaxListSize{$ENDIF}) then\n    Error(SListCountError, NewCount);\n{$ENDIF}\n  if NewCount > FCapacity then\n    SetCapacity(NewCount);\n  if NewCount < FCount then\n  begin\n    for I := FCount - 1 downto NewCount do\n      FList^[I] := nil;\n  end;\n  FCount := NewCount;\nend;\n\n{**\n  Clones the instance of this object.\n  @return a reference to the clonned object.\n}\nfunction TZCollection.Clone: IZInterface;\nvar\n  I: Integer;\n  Collection: IZCollection;\n  Clonnable: IZClonnable;\nbegin\n  Collection := TZCollection.Create;\n  for I := 0 to FCount - 1 do\n  begin\n    if FList^[I].QueryInterface(IZClonnable, Clonnable) = 0 then\n      Collection.Add(Clonnable.Clone)\n      else\n         Collection.Add(FList^[I]);\n  end;\n  Result := Collection;\nend;\n\n{**\n  Adds a new object at the and of this collection.\n  @param Item an object to be added.\n  @return a position of the added object.\n}\nfunction TZCollection.Add(const Item: IZInterface): Integer;\nbegin\n  Result := FCount;\n  if Result = FCapacity then\n    Grow;\n//  FList^[Result] := Item as IZInterface; // enourmous Memory Hole in FPC > 2.0.2 Release\n  FList^[Result] := Item;\n  Inc(FCount);\nend;\n\n{**\n  Adds all elements from the specified collection into this collection.\n  @param Col a collection of objects to be added.\n  @return <code>True</code> is the collection was changed.\n}\nfunction TZCollection.AddAll(const Col: IZCollection): Boolean;\nvar\n  I: Integer;\nbegin\n  Result := Col.Count > 0;\n  for I := 0 to Col.Count - 1 do\n    Add(Col[I]);\nend;\n\n{**\n  Clears the content of this collection.\n}\nprocedure TZCollection.Clear;\nbegin\n  SetCount(0);\n  SetCapacity(0);\nend;\n\n{**\n  Checks is the specified object is stored in this collection.\n  @return <code>True</code> if the object was found in the collection.\n}\nfunction TZCollection.Contains(const Item: IZInterface): Boolean;\nbegin\n  Result := IndexOf(Item) >= 0;\nend;\n\n{**\n  Checks are all the object in this collection.\n  @param Col a collection of objects to be checked.\n  @return <code>True</code> if all objects are in this collection.\n}\nfunction TZCollection.ContainsAll(const Col: IZCollection): Boolean;\nvar\n  I: Integer;\nbegin\n  Result := Col.Count > 0;\n  for I := 0 to Col.Count - 1 do\n  begin\n    if IndexOf(Col[I]) < 0 then\n    begin\n      Result := False;\n      Break;\n    end;\n  end;\nend;\n\n{**\n  Deletes an object from the specified position.\n}\nprocedure TZCollection.Delete(Index: Integer);\nbegin\n{$IFOPT R+}\n  if (Index < 0) or (Index >= FCount) then\n    Error(SListIndexError, Index);\n{$ENDIF}\n  FList^[Index] := nil;\n  Dec(FCount);\n  if Index < FCount then\n  begin\n    System.Move(FList^[Index + 1], FList^[Index],\n      (FCount - Index) * SizeOf(IZInterface));\n    {now nil pointer or on replacing the entry we'll get a bad interlockdecrement}\n    Pointer(FList^[FCount]) := nil; //see http://sourceforge.net/p/zeoslib/tickets/100/\n  end;\nend;\n\n{**\n  Exchanges two element in the collection.\n  @param Index1 an index of the first element.\n  @param Index2 an index of the second element.\n}\nprocedure TZCollection.Exchange(Index1, Index2: Integer);\nvar\n  Item: IZInterface;\nbegin\n{$IFOPT R+}\n  if (Index1 < 0) or (Index1 >= FCount) then\n    Error(SListIndexError, Index1);\n  if (Index2 < 0) or (Index2 >= FCount) then\n    Error(SListIndexError, Index2);\n{$ENDIF}\n  Item := FList^[Index1];\n  FList^[Index1] := FList^[Index2];\n  FList^[Index2] := Item;\nend;\n\n{**\n  Gets the first element from this collection.\n  @return the first element.\n}\nfunction TZCollection.First: IZInterface;\nbegin\n  Result := Get(0);\nend;\n\n{**\n  Gets a collection element from the specified position.\n  @param Index a position index of the element.\n  @return a requested element.\n}\nfunction TZCollection.Get(Index: Integer): IZInterface;\nbegin\n{$IFOPT R+}\n  if (Index < 0) or (Index >= FCount) then\n    Error(SListIndexError, Index);\n{$ENDIF}\n  Result := FList^[Index];\nend;\n\n{**\n  Gets a number of the stored element in this collection.\n  @return a number of stored elements.\n}\nfunction TZCollection.GetCount: Integer;\nbegin\n  Result := FCount;\nend;\n\n{**\n  Gets a created iterator for this collection.\n  @return a created iterator for this collection.\n}\nfunction TZCollection.GetIterator: IZIterator;\nbegin\n  Result := TZIterator.Create(Self);\nend;\n\n{**\n  Defines an index of the specified object inside this colleciton.\n  @param Item an object to be found.\n  @return an object position index or -1 if it was not found.\n}\nfunction TZCollection.IndexOf(const Item: IZInterface): Integer;\nvar\n  I: Integer;\n  Comparable: IZComparable;\n  Unknown: IZInterface;\nbegin\n  Result := -1;\n  if (FCount = 0) or (Item = nil) then\n    Exit;\n\n  { Find IComparable objects }\n  if Item.QueryInterface(IZComparable, Comparable) = 0 then\n  begin\n    for I := 0 to FCount - 1 do\n    begin\n      if Comparable.Equals(FList^[I]) then\n      begin\n        Result := I;\n        Break;\n      end;\n    end;\n    Comparable := nil;\n  end\n  { Find ordinary objects }\n  else\n  begin\n    Unknown := Item;\n    for I := 0 to FCount - 1 do\n    begin\n      if Unknown = FList^[I] then\n      begin\n        Result := I;\n        Break;\n      end;\n    end;\n    Unknown := nil;\n  end;\nend;\n\n{**\n  Inserts an object into specified position.\n  @param Index a position index.\n  @param Item an object to be inserted.\n}\nprocedure TZCollection.Insert(Index: Integer; const Item: IZInterface);\nbegin\n{$IFOPT R+}\n  if (Index < 0) or (Index > FCount) then\n    Error(SListIndexError, Index);\n{$ENDIF}\n  if FCount = FCapacity then\n    Grow;\n  if Index < FCount then\n  begin\n    System.Move(FList^[Index], FList^[Index + 1],\n      (FCount - Index) * SizeOf(IZInterface));\n    {now nil pointer or on replacing the entry we'll get a bad interlockdecrement}\n    Pointer(Flist^[Index]) := nil; //see http://sourceforge.net/p/zeoslib/tickets/100/\n  end;\n  FList^[Index] := Item;\n  Inc(FCount);\nend;\n\n{**\n  Gets the last object from this collection.\n  @return the last object.\n}\nfunction TZCollection.Last: IZInterface;\nbegin\n  Result := Get(FCount - 1);\nend;\n\n{**\n  Puts a specified object into defined position.\n  @param Index a position index.\n  @param Items ab object to be put.\n}\nprocedure TZCollection.Put(Index: Integer; const Item: IZInterface);\nbegin\n{$IFOPT R+}\n  if (Index < 0) or (Index >= FCount) then\n    Error(SListIndexError, Index);\n{$ENDIF}\n  FList^[Index] := Item;\nend;\n\n{**\n  Removes an existed object which equals to the specified one.\n  @param Item an object to be removed.\n  @return an index of the removed object.\n}\nfunction TZCollection.Remove(const Item: IZInterface): Integer;\nbegin\n  Result := IndexOf(Item);\n  if Result >= 0 then\n    Delete(Result);\nend;\n\n{**\n  Removes all the elements from the specified collection.\n  @param Col a collection of object to be removed.\n  @return <code>True</code> if this collection was changed.\n}\nfunction TZCollection.RemoveAll(const Col: IZCollection): Boolean;\nvar\n  I: Integer;\nbegin\n  Result := False;\n  for I := 0 to Col.Count - 1 do\n    Result := (Remove(Col[I]) >= 0) or Result;\nend;\n\n{**\n  Gets a string representation for this object.\n}\nfunction TZCollection.ToString: string;\nvar\n  I: Integer;\n  TempObject: IZObject;\nbegin\n  Result := '';\n  for I := 0 to FCount - 1 do\n  begin\n    if I > 0 then\n      Result := Result + ',';\n    if FList^[I].QueryInterface(IZObject, TempObject) = 0 then\n      Result := Result + TempObject.ToString\n      else\n         Result := Result + Format('<%p>', [Pointer(FList^[I])]);\n  end;\n  Result := '[' + Result + ']';\nend;\n\n{ TZUnmodifiableCollection }\n\n{**\n  Constructs this object and assignes main properties.\n  @param Collection an initial modifiable list of interfaces.\n}\nconstructor TZUnmodifiableCollection.Create(Collection: IZCollection);\nbegin\n  inherited Create;\n  FCollection := Collection;\nend;\n\n{**\n  Destroys this object and frees the memory.\n}\ndestructor TZUnmodifiableCollection.Destroy;\nbegin\n  FCollection := nil;\n  inherited Destroy;\nend;\n\n{**\n  Clones the instance of this object.\n  @return a reference to the clonned object.\n}\nfunction TZUnmodifiableCollection.Clone: IZInterface;\nbegin\n  Result := TZUnmodifiableCollection.Create(FCollection);\nend;\n\n{**\n  Raises invalid operation exception.\n}\nprocedure TZUnmodifiableCollection.RaiseException;\nbegin\n  raise EInvalidOperation.Create(SImmutableOpIsNotAllowed);\nend;\n\n{**\n  Adds a new object at the and of this collection.\n  @param Item an object to be added.\n  @return a position of the added object.\n}\nfunction TZUnmodifiableCollection.Add(const Item: IZInterface): Integer;\nbegin\n  Result := -1;\n  RaiseException;\nend;\n\n{**\n  Adds all elements from the specified collection into this collection.\n  @param Col a collection of objects to be added.\n  @return <code>True</code> is the collection was changed.\n}\nfunction TZUnmodifiableCollection.AddAll(const Col: IZCollection): Boolean;\nbegin\n  Result := False;\n  RaiseException;\nend;\n\n{**\n  Clears the content of this collection.\n}\nprocedure TZUnmodifiableCollection.Clear;\nbegin\n  RaiseException;\nend;\n\n{**\n  Checks is the specified object is stored in this collection.\n  @return <code>True</code> if the object was found in the collection.\n}\nfunction TZUnmodifiableCollection.Contains(const Item: IZInterface): Boolean;\nbegin\n  Result := FCollection.Contains(Item);\nend;\n\n{**\n  Checks are all the object in this collection.\n  @param Col a collection of objects to be checked.\n  @return <code>True</code> if all objects are in this collection.\n}\nfunction TZUnmodifiableCollection.ContainsAll(const Col: IZCollection): Boolean;\nbegin\n  Result := FCollection.ContainsAll(Col);\nend;\n\n{**\n  Deletes an object from the specified position.\n}\nprocedure TZUnmodifiableCollection.Delete(Index: Integer);\nbegin\n  RaiseException;\nend;\n\n{**\n  Exchanges two element in the collection.\n  @param Index1 an index of the first element.\n  @param Index2 an index of the second element.\n}\nprocedure TZUnmodifiableCollection.Exchange(Index1, Index2: Integer);\nbegin\n  RaiseException;\nend;\n\n{**\n  Gets the first element from this collection.\n  @return the first element.\n}\nfunction TZUnmodifiableCollection.First: IZInterface;\nbegin\n  Result := FCollection.First;\nend;\n\n{**\n  Gets a collection element from the specified position.\n  @param Index a position index of the element.\n  @return a requested element.\n}\nfunction TZUnmodifiableCollection.Get(Index: Integer): IZInterface;\nbegin\n  Result := FCollection[Index];\nend;\n\n{**\n  Gets a number of the stored element in this collection.\n  @return a number of stored elements.\n}\nfunction TZUnmodifiableCollection.GetCount: Integer;\nbegin\n  Result := FCollection.Count;\nend;\n\n{**\n  Gets a created iterator for this collection.\n  @return a created iterator for this collection.\n}\nfunction TZUnmodifiableCollection.GetIterator: IZIterator;\nbegin\n  Result := TZIterator.Create(Self);\nend;\n\n{**\n  Defines an index of the specified object inside this colleciton.\n  @param Item an object to be found.\n  @return an object position index or -1 if it was not found.\n}\nfunction TZUnmodifiableCollection.IndexOf(const Item: IZInterface): Integer;\nbegin\n  Result := FCollection.IndexOf(Item);\nend;\n\n{**\n  Inserts an object into specified position.\n  @param Index a position index.\n  @param Item an object to be inserted.\n}\nprocedure TZUnmodifiableCollection.Insert(Index: Integer; const Item: IZInterface);\nbegin\n  RaiseException;\nend;\n\n{**\n  Gets the last object from this collection.\n  @return the last object.\n}\nfunction TZUnmodifiableCollection.Last: IZInterface;\nbegin\n  Result := FCollection.Last;\nend;\n\n{**\n  Puts a specified object into defined position.\n  @param Index a position index.\n  @param Items ab object to be put.\n}\nprocedure TZUnmodifiableCollection.Put(Index: Integer; const Item: IZInterface);\nbegin\n  RaiseException;\nend;\n\n{**\n  Removes an existed object which equals to the specified one.\n  @param Item an object to be removed.\n  @return an index of the removed object.\n}\nfunction TZUnmodifiableCollection.Remove(const Item: IZInterface): Integer;\nbegin\n  Result := -1;\n  RaiseException;\nend;\n\n{**\n  Removes all the elements from the specified collection.\n  @param Col a collection of object to be removed.\n  @return <code>True</code> if this collection was changed.\n}\nfunction TZUnmodifiableCollection.RemoveAll(const Col: IZCollection): Boolean;\nbegin\n  Result := False;\n  RaiseException;\nend;\n\n{**\n  Gets a string representation for this object.\n}\nfunction TZUnmodifiableCollection.ToString: string;\nbegin\n  Result := FCollection.ToString;\nend;\n\n{ TZHashMap }\n\n{**\n  Creates this hash map and assignes main properties.\n}\nconstructor TZHashMap.Create;\nbegin\n  inherited Create;\n  FKeys := TZCollection.Create;\n  FValues := TZCollection.Create;\n  FReadOnlyKeys := TZUnmodifiableCollection.Create(FKeys);\n  FReadOnlyValues := TZUnmodifiableCollection.Create(FValues);\nend;\n\n{**\n  Destroys this object and frees the memory.\n}\ndestructor TZHashMap.Destroy;\nbegin\n  FReadOnlyKeys := nil;\n  FReadOnlyValues := nil;\n  FKeys := nil;\n  FValues := nil;\n  inherited Destroy;\nend;\n\n{**\n  Clones the instance of this object.\n  @return a reference to the clonned object.\n}\nfunction TZHashMap.Clone: IZInterface;\nvar\n  HashMap: TZHashMap;\nbegin\n  HashMap := TZHashMap.Create;\n  HashMap.FKeys := IZCollection(FKeys.Clone);\n  HashMap.FReadOnlyKeys := IZCollection(FReadOnlyKeys.Clone);\n  HashMap.FValues := IZCollection(FValues.Clone);\n  HashMap.FReadOnlyValues := IZCollection(FReadOnlyValues.Clone);\n  Result := HashMap;\nend;\n\n{**\n  Gets a interface by it's key.\n  @param Key a key interface.\n  @return a found value interface or <code>nil</code> otherwise.\n}\nfunction TZHashMap.Get(const Key: IZInterface): IZInterface;\nvar\n  Index: Integer;\nbegin\n  Index := FKeys.IndexOf(Key);\n  if Index >= 0 then\n    Result := FValues[Index]\n   else\n      Result := nil;\nend;\n\n{**\n  Put a new key/value pair interfaces.\n  @param Key a key interface.\n  @param Value a value interface.\n}\nprocedure TZHashMap.Put(const Key: IZInterface; const Value: IZInterface);\nvar\n Index: Integer;\nbegin\n  Index := FKeys.IndexOf(Key);\n  if Index >= 0 then\n    FValues[Index] := Value\n  else\n  begin\n    FKeys.Add(Key);\n    FValues.Add(Value);\n  end;\nend;\n\n{**\n  Gets a readonly collection of keys.\n  @return a readonly collection of keys.\n}\nfunction TZHashMap.GetKeys: IZCollection;\nbegin\n  Result := FReadOnlyKeys;\nend;\n\n{**\n  Gets a readonly collection of values.\n  @return a readonly collection of values.\n}\nfunction TZHashMap.GetValues: IZCollection;\nbegin\n  Result := FReadOnlyValues;\nend;\n\n{**\n  Gets a number of elements in this hash map.\n  @return a number of elements in this hash map.\n}\nfunction TZHashMap.GetCount: Integer;\nbegin\n  Result := FKeys.Count;\nend;\n\n{**\n  Removes the element from the map by it's key.\n  @param Key a key of the element.\n  @return <code>true</code> of the hash map was changed.\n}\nfunction TZHashMap.Remove(Key: IZInterface): Boolean;\nvar\n  Index: Integer;\nbegin\n  Index := FKeys.IndexOf(Key);\n  if Index >= 0 then\n  begin\n    FKeys.Delete(Index);\n    FValues.Delete(Index);\n    Result := True;\n   end\n   else\n    Result := False;\nend;\n\n{**\n  Clears this hash map and removes all elements.\n}\nprocedure TZHashMap.Clear;\nbegin\n  FKeys.Clear;\n  FValues.Clear;\nend;\n\n{ TZStack }\n\n{**\n  Constructs this object and assignes the main properties.\n}\nconstructor TZStack.Create;\nbegin\n  FValues := TZCollection.Create;\nend;\n\n{**\n  Destroys this object and cleanups the memory.\n}\ndestructor TZStack.Destroy;\nbegin\n  FValues := nil;\n  inherited Destroy;\nend;\n\n{**\n  Clones the instance of this object.\n  @return a reference to the clonned object.\n}\nfunction TZStack.Clone: IZInterface;\nvar\n  Stack: TZStack;\nbegin\n  Stack := TZStack.Create;\n  Stack.FValues := IZCollection(FValues.Clone);\n  Result := Stack;\nend;\n\n{**\n  Gets a count of the stored elements.\n  @return an elements count.\n}\nfunction TZStack.GetCount: Integer;\nbegin\n  Result := FValues.Count;\nend;\n\n{**\n  Gets an element from the top this stack without removing it.\n  @return an element from the top of the stack.\n}\nfunction TZStack.Peek: IZInterface;\nbegin\n  if FValues.Count > 0 then\n    Result := FValues[FValues.Count - 1]\n   else\n      Result := nil;\nend;\n\n{**\n  Gets an element from the top this stack and remove it.\n  @return an element from the top of the stack.\n}\nfunction TZStack.Pop: IZInterface;\nbegin\n  if FValues.Count > 0 then\n  begin\n    Result := FValues[FValues.Count - 1];\n    FValues.Delete(FValues.Count - 1);\n   end\n   else\n    Result := nil;\nend;\n\n{**\n  Puts a new element to the top of this stack.\n  @param Value a new element to be put.\n}\nprocedure TZStack.Push(Value: IZInterface);\nbegin\n  FValues.Add(Value);\nend;\n\n{**\n  Gets a string representation for this object.\n}\nfunction TZStack.ToString: string;\nbegin\n  Result := FValues.ToString;\nend;\n\nend.\n"
  },
  {
    "path": "lib/zeosdbo/src/core/ZCompatibility.pas",
    "content": "{*********************************************************}\n{                                                         }\n{                 Zeos Database Objects                   }\n{            Compatibility Classes and Functions          }\n{                                                         }\n{          Originally written by Sergey Seroukhov         }\n{                                                         }\n{*********************************************************}\n\n{@********************************************************}\n{    Copyright (c) 1999-2012 Zeos Development Group       }\n{                                                         }\n{ License Agreement:                                      }\n{                                                         }\n{ This library is distributed in the hope that it will be }\n{ useful, but WITHOUT ANY WARRANTY; without even the      }\n{ implied warranty of MERCHANTABILITY or FITNESS FOR      }\n{ A PARTICULAR PURPOSE.  See the GNU Lesser General       }\n{ Public License for more details.                        }\n{                                                         }\n{ The source code of the ZEOS Libraries and packages are  }\n{ distributed under the Library GNU General Public        }\n{ License (see the file COPYING / COPYING.ZEOS)           }\n{ with the following  modification:                       }\n{ As a special exception, the copyright holders of this   }\n{ library give you permission to link this library with   }\n{ independent modules to produce an executable,           }\n{ regardless of the license terms of these independent    }\n{ modules, and to copy and distribute the resulting       }\n{ executable under terms of your choice, provided that    }\n{ you also meet, for each linked independent module,      }\n{ the terms and conditions of the license of that module. }\n{ An independent module is a module which is not derived  }\n{ from or based on this library. If you modify this       }\n{ library, you may extend this exception to your version  }\n{ of the library, but you are not obligated to do so.     }\n{ If you do not wish to do so, delete this exception      }\n{ statement from your version.                            }\n{                                                         }\n{                                                         }\n{ The project web site is located on:                     }\n{   http://zeos.firmos.at  (FORUM)                        }\n{   http://sourceforge.net/p/zeoslib/tickets/ (BUGTRACKER)}\n{   svn://svn.code.sf.net/p/zeoslib/code-0/trunk (SVN)    }\n{                                                         }\n{   http://www.sourceforge.net/projects/zeoslib.          }\n{                                                         }\n{                                                         }\n{                                 Zeos Development Group. }\n{********************************************************@}\n\nunit ZCompatibility;\n\ninterface\n\n{$I ZCore.inc}\n\nuses\n  Variants,\n{$IFDEF FPC}\n  {$IFDEF UNIX}\n    dynlibs,\n  {$endif}\n{$ENDIF}\n  {$IFDEF WITH_WIDESTRUTILS}\n  WideStrUtils,\n  {$ENDIF}\n  {$If defined(MSWINDOWS) and not defined(FPC)}\n  Windows,\n  {$IFEND}\n  Classes,\n  {$IFDEF MSEgui}mclasses,{$ENDIF}\n  {$IFDEF WITH_LCONVENCODING} LConvEncoding,{$ENDIF}\n  Types,\n  SysUtils;\n\ntype\n{$IFDEF FPC}\n  ULong                 = {$IFDEF WIN64}LongWord{$ELSE}PTRUINT{$ENDIF};\n                            // EgonHugeist: Use always a 4Byte Integer as long the PlainDriver dll's are 32Bit for Windows64\n                            //on the other hand MySQL64 and FB64 have problems on Win64!\n  ULongLong             = QWord;\n  NativeInt             = PtrInt;\n  NativeUInt            = PtrUInt;\n  PNativeUInt           = ^NativeUInt;\n{$ELSE}\n  {$IFNDEF DELPHI16_UP}\n  NativeInt             = Integer;\n  NativeUInt            = LongWord;\n  PNativeUInt           = ^NativeUInt;\n  PWord                 = ^Word; // M.A.\n  {$ENDIF}\n  ULong                 = LongWord;\n  ULongLong             = {$IFDEF WITH_UINT64}Uint64{$ELSE}Int64{$ENDIF}; //delphi dont have Unsigned Int64 type\n{$ENDIF}\n  PULong                = ^ULong;\n  PULongLong            = ^ULongLong;\n\n  UInt                  = LongWord;\n  PUInt                 = ^UInt;\n  ZPPWideChar            = ^PWideChar;//BCB issue: PPWideChar is not part of system\n\n  TObjectDynArray       = array of TObject;\n{$IFDEF FPC}\ntype\n  TDBScreenCursor = (dcrDefault, dcrHourGlass, dcrSQLWait, dcrOther);\n\n  IDBScreen = interface\n    ['{29A1C508-6ADC-44CD-88DE-4F51B25D5995}']\n    function GetCursor: TDBScreenCursor;\n    procedure SetCursor(Cursor: TDBScreenCursor);\n\n    property Cursor: TDBScreenCursor read GetCursor write SetCursor;\n  end;\n\nvar\n  LoginDialogProc: function (const ADatabaseName: string; var AUserName,\n    APassword: string): Boolean;\n  DBScreen: IDBScreen;\n{$ENDIF}\n\n{$IFNDEF FPC} //delphi and windows\nconst\n  LineEnding = #13#10;\n  Brackets = ['(',')','[',']','{','}'];\n  StdWordDelims = [#0..' ',',','.',';','/','\\',':','''','\"','`'] + Brackets;\n\nfunction Hash(S : AnsiString) : LongWord;\nfunction AnsiProperCase(const S: string; const WordDelims: TSysCharSet): string;\n\n{$ENDIF}\n\n{$IFDEF WINDOWS}\nconst SharedSuffix='.dll';\n{$ELSE}\n  {$IFDEF DARWIN}\n  const SharedSuffix='.dylib';\n  {$ELSE}\n    {$IFDEF UNIX}\n      const SharedSuffix='.so';\n    {$ELSE}\n      const SharedSuffix='.dll'; //Delphi\n    {$ENDIF}\n  {$ENDIF}\n{$ENDIF}\n\n{$IFDEF UNIX}\n  {$IFDEF FPC}\nconst\n  RTLD_GLOBAL = $101;\n  INVALID_HANDLE_VALUE = 0;\n\ntype\n  HMODULE = PtrInt;\n\nfunction LoadLibrary(ModuleName: PChar): HMODULE;\nfunction FreeLibrary(Module: HMODULE): LongBool;\nfunction GetProcAddress(Module: HMODULE; Proc: PChar): Pointer;\n  {$ENDIF}\n{$ENDIF}\n\n{EgonHugeist:}\ntype\n  {$IFNDEF WITH_RAWBYTESTRING}\n  RawByteString = AnsiString;\n  {$ENDIF}\n\n  ZWideString = {$IFDEF PWIDECHAR_IS_PUNICODECHAR}UnicodeString{$ELSE}WideString{$ENDIF};\n\ntype\n  {declare move or converter functions for the String Types}\n  TZAnsiToRaw = function (const Src: AnsiString; const RawCP: Word): RawByteString;\n  TZRawToAnsi = function (const Src: RawByteString; const RawCP: Word): AnsiString;\n  TZAnsiToUTF8 = function (const Src: AnsiString): UTF8String;\n  TZUTF8ToAnsi = function (const Src: UTF8String): AnsiString;\n  TZRawToUTF8 = function (const Src: RawByteString; const CP: Word): UTF8String;\n  TZUTF8ToRaw = function (const Src: UTF8String; const CP: Word): RawByteString;\n  TZRawToString = function (const Src: RawByteString; const RawCP, StringCP: Word): String;\n  TZStringToRaw = function (const Src: String; const StringCP, RawCP: Word): RawByteString;\n  TZUTF8ToString = function (const Src: UTF8String; const StringCP: Word): String;\n  TZStringToUTF8 = function (const Src: String; const StringCP: Word): UTF8String;\n  TZAnsiToString = function (const Src: AnsiString; const StringCP: Word): String;\n  TZStringToAnsi = function (const Src: String; const StringCP: Word): AnsiString;\n  TZRawToUnicode = function (const S: RawByteString; const CP: Word): ZWideString;\n  TZUnicodeToRaw = function (const US: ZWideString; CP: Word): RawByteString;\n  TZUnicodeToString = function (const Src: ZWideString; const StringCP: Word): String;\n  TZStringToUnicode = function (const Src: String; const StringCP: Word): ZWideString;\n\n  {** Defines the Target Ansi codepages for the Controls }\n  TZControlsCodePage = ({$IFDEF UNICODE}cCP_UTF16, cCP_UTF8, cGET_ACP{$ELSE}{$IFDEF FPC}cCP_UTF8, cCP_UTF16, cGET_ACP{$ELSE}cGET_ACP, cCP_UTF8, cCP_UTF16{$ENDIF}{$ENDIF});\n\n  TZCharEncoding = (\n    ceDefault,  //Internal switch for the two Functions below do not use it as a CodePage-declaration!\n    ceAnsi,     //Base Ansi-String: prefered CodePage\n    ceUTF8,     //UTF8_Unicode: 1-4Byte/Char\n    ceUTF16,    //Wide or Unicode string encoding for Field-mapping\n    ceUTF32);   //reserved\n\n    {Here it's possible to add some more, to handle the Ansi->Unicode-Translations}\n\n  PZCodePage = ^TZCodePage;\n  TZCodePage = record\n    Name: String;             //Name of Client-CharacterSet\n    ID:  Integer;             //may be an ordinal value of predefined Types or the database used id}\n    CharWidth: Integer;       //count of Bytes per char\n    Encoding: TZCharEncoding; //The Type of String-Translation handling\n    CP:  Word;                //The CodePage the AnsiString must have to\n    ZAlias: String;           //A possible (saver?) CharacterSet which is more Zeos compatible... If it's empty it will be ignored!!!\n    IsStringFieldCPConsistent: Boolean; //Is the current client characterset codepage consistent for all codepages?\n  end;\n\n  TConvertEncodingFunctions = record\n    ZAnsiToUTF8: TZAnsiToUTF8;\n    ZUTF8ToAnsi: TZUTF8ToAnsi;\n    ZUTF8ToString: TZUTF8ToString;\n    ZStringToUTF8: TZStringToUTF8;\n    ZAnsiToRaw: TZAnsiToRaw;\n    ZRawToAnsi: TZRawToAnsi;\n    ZRawToUTF8: TZRawToUTF8;\n    ZUTF8ToRaw: TZUTF8ToRaw;\n    ZStringToRaw: TZStringToRaw;\n    ZRawToString: TZRawToString;\n    ZAnsiToString: TZAnsiToString;\n    ZStringToAnsi: TZStringToAnsi;\n    ZUnicodeToRaw: TZUnicodeToRaw;\n    ZRawToUnicode: TZRawToUnicode;\n    ZUnicodeToString: TZUnicodeToString;\n    ZStringToUnicode: TZStringToUnicode;\n  end;\n\n  PZConSettings = ^TZConSettings;\n  TZConSettings = record\n    AutoEncode: Boolean;        //Check Encoding and or convert string with FromCP ToCP\n    CPType: TZControlsCodePage; //the CP-Settings type the controls do expect\n    CTRL_CP: Word;              //Target CP of string conversion (CP_ACP/CP_UPF8)\n    ConvFuncs: TConvertEncodingFunctions; //a rec for the Convert functions used by the objects\n    ClientCodePage: PZCodePage; //The codepage informations of the current characterset\n    DateFormat: String;\n    {$IFDEF WITH_LCONVENCODING}\n    PlainConvertFunc: TConvertEncodingFunction;\n    DbcConvertFunc: TConvertEncodingFunction;\n    {$ENDIF}\n  end;\n\n  TZCodePagedObject = Class(TInterfacedObject)\n  private\n    FConSettings: PZConSettings;\n  protected\n    function ZDbcString(const Ansi: RawByteString; ConSettings: PZConSettings): String; overload;\n    function ZDbcString(const Ansi: RawByteString; FromCP: Word): String; overload;\n    function ZDbcString(const Ansi: RawByteString; const Encoding: TZCharEncoding = ceDefault): String; overload;\n    function ZDbcString(const AStr: ZWideString; const Encoding: TZCharEncoding = ceDefault): String; overload;\n    function ZDbcUnicodeString(const AStr: RawByteString): ZWideString; overload;\n    function ZDbcUnicodeString(const AStr: RawByteString; const FromCP: Word): ZWideString; overload;\n    {$IFDEF WITH_RAWBYTESTRING}\n    function ZDbcUnicodeString(const AStr: String; const FromCP: Word): ZWideString; overload;\n    {$ENDIF}\n    function ZPlainString(const AStr: String; ConSettings: PZConSettings): RawByteString; overload;\n    function ZPlainString(const AStr: String; ConSettings: PZConSettings; const ToCP: Word): RawByteString; overload;\n    function ZPlainString(const AStr: String; const Encoding: TZCharEncoding = ceDefault): RawByteString; overload;\n    function ZPlainString(const AStr: WideString; const Encoding: TZCharEncoding = ceDefault): RawByteString; overload;\n    function ZPlainString(const AStr: WideString; ConSettings: PZConSettings): RawByteString; overload;\n    function ZPlainString(const AStr: WideString; ConSettings: PZConSettings; const ToCP: Word): RawByteString; overload;\n    function ZPlainUnicodeString(const AStr: String): WideString;\n    procedure SetConSettingsFromInfo(Info: TStrings);\n    property ConSettings: PZConSettings read FConSettings write FConSettings;\n  public\n    destructor Destroy; override;\n  end;\n\n  {$IFDEF WITH_LCONVENCODING}\n  function NoConvert(const s: string): string;\n  {$ENDIF}\n\n\n{$IF not Declared(DetectUTF8Encoding)}\n{$DEFINE ZDetectUTF8Encoding}\nType\n  TEncodeType = (etUSASCII, etUTF8, etANSI);\n\nfunction DetectUTF8Encoding(Ansi: RawByteString): TEncodeType;\n{$IFEND}\n\n{$IFNDEF WITH_CHARINSET}\nfunction CharInSet(C: AnsiChar; const CharSet: TSysCharSet): Boolean; overload;\nfunction CharInSet(C: WideChar; const CharSet: TSysCharSet): Boolean; overload;\n{$ENDIF}\n\n{$IF not Declared(UTF8ToString)}\n{$DEFINE ZUTF8ToString}\nfunction UTF8ToString(const s: RawByteString): ZWideString;\n{$IFEND}\n\nvar\n  ClientCodePageDummy: TZCodepage =\n    (Name: ''; ID: 0; CharWidth: 1; Encoding: ceAnsi;\n      CP: $ffff; ZAlias: '');\n\n  ConSettingsDummy: TZConSettings =\n    (AutoEncode: False;\n      CPType: {$IFDEF DELPHI}{$IFDEF UNICODE}cCP_UTF16{$ELSE}cGET_ACP{$ENDIF}{$ELSE}cCP_UTF8{$ENDIF};\n      ClientCodePage: @ClientCodePageDummy;\n      {$IFDEF WITH_LCONVENCODING}\n      PlainConvertFunc: @NoConvert;\n      DbcConvertFunc: @NoConvert;\n      {$ENDIF}\n    );\n\nimplementation\n\nuses ZEncoding;\n\n{$IFDEF ZDetectUTF8Encoding}\nfunction DetectUTF8Encoding(Ansi: RawByteString): TEncodeType; //EgonHugeist: Detect a valid UTF8Sequence\nvar\n  I, Len: Integer;\n  Source: PAnsiChar;\n\n  function P(Pos: Integer = 0): Byte;\n  begin\n    Result := Byte(Source[Pos]);\n  end;\n\n  procedure IncPos(X: Integer = 1);\n  begin\n    inc(Source, X);\n    inc(i, X);\n  end;\nbegin\n  Result := etUSASCII;\n  if Ansi = '' then Exit;\n\n  Len := Length(Ansi);\n  Source := PAnsiChar(Ansi);\n\n  // skip US-ASCII Chars they are allways valid.\n  I := 0;\n  while ( I <= Len ) do\n  begin\n    if P >= $80 then break;\n    IncPos;\n  end;\n\n  if i > Len then exit; //US ACII\n\n  //No US-Ascii at all.\n  while I < Len do\n  begin\n    case p of\n      $00..$7F: //Ascii\n        IncPos;\n\n      $C2..$DF: // non-overlong 2-byte\n        if (I+1 < Len)\n            and (P(1) in [$80..$BF]) then\n          IncPos(2)\n        else\n          break;\n\n      $E0: // excluding overlongs\n        if (I+2 < Len)\n            and (P(1) in [$A0..$BF])\n            and (P(2) in [$80..$BF]) then\n          IncPos(3)\n        else\n          break;\n\n      $E1..$EF: // straight 3-byte & excluding surrogates\n        if (i+2 < Len)\n            and (P(1) in [$80..$BF])\n            and (P(2) in [$80..$BF]) then\n          IncPos(3)\n        else\n          break;\n\n      $F0: // planes 1-3\n        if (i+3 < Len)\n            and (P(1) in [$90..$BF])\n            and (P(2) in [$80..$BF])\n            and (P(3) in [$80..$BF]) then\n          IncPos(4)\n        else\n          break;\n\n      $F1..$F3: // planes 4-15\n        if (i+3 < Len)\n            and (P(1) in [$80..$BF])\n            and (P(2) in [$80..$BF])\n            and (P(3) in [$80..$BF]) then\n          IncPos(4)\n        else\n          break;\n\n      $F4: // plane 16\n        if (i+3 < Len)\n            and (P(1) in [$80..$8F])\n            and (P(2) in [$80..$BF])\n            and (P(3) in [$80..$BF]) then\n          IncPos(4)\n        else\n          break;\n    else\n      break;\n    end;\n  end;\n\n  if i = Len then\n    Result := etUTF8  //UTF8\n  else\n    Result := etANSI; //Ansi\nend;\n{$ENDIF}\n\n{**\n  EgonHugeist:\n  Now use the new Functions to get encoded Strings instead of\n  hard-coded Compiler-Directives or UTF8Encode/Decode:\n\n  function ZDbcString(const Ansi: AnsiString; const Encoding: TZCharEncoding = ceDefault): String;\n  function ZPlainString(const Str: String; const Encoding: TZCharEncoding = ceDefault): AnsiString;\n\n  These functions do auto arrange the in/out-coming AnsiStrings in\n  dependency of the used CharacterSet and the used Compiler whithout\n  String-DataLoss!!.\n  So my thouths where use only these two function for all\n  String/Ansi/Unicode-handlings of DBC-layer. Which means in full effect\n  no more directives in Zeos Source-Code then here to do this handling.\n  @param Ansi: the String which has to be handled.\n  @param Encoding is set to Default-Character-Set we've choosen bevor (on conecting)\n    Change this if you need some Transtations to a specified Encoding.\n    Example: CharacterSet was set to Latin1 and some \"special\"-String MUST BE\n     UTF8 instead of Latin1. (SSL-Keys eventualy)\n  @param Convert ignored for Delphi means if the Chararacters should be propper\n    to the specified codepage\n\n\n  IS there a need for it? AnsiEncoded adaps automaticaly to WideString\n  So what about coming UTF16/32????\n}\nfunction TZCodePagedObject.ZDbcString(const Ansi: RawByteString;\n  ConSettings: PZConSettings): String;\n{$IFDEF WITH_FPC_STRING_CONVERSATION}\nvar TempAnsi: RawByteString;\n{$ENDIF}\nbegin\n  {$IFNDEF UNICODE}\n  if not ConSettings^.AutoEncode then\n    Result := Ansi\n  else\n  {$ENDIF}\n    case ConSettings^.ClientCodePage^.Encoding of\n      ceUTF8:\n        {$IFDEF UNICODE}\n          Result := UTF8ToString(Ansi);\n        {$ELSE}\n          if ( ConSettings^.CPType in [cCP_UTF8, cCP_UTF16] ) then\n            Result := Ansi\n          else\n            {$IFDEF WITH_LCONVENCODING}\n            Result := ConSettings.DbcConvertFunc(Ansi);\n            {$ELSE}\n              {$IFDEF WITH_FPC_STRING_CONVERSATION}\n              begin\n                //avoid string conversion -> move memory\n                TempAnsi := AnsiToStringEx(Ansi, ConSettings^.ClientCodePage^.CP, ConSettings^.CTRL_CP);\n                SetLength(Result, Length(TempAnsi));\n                Move(PAnsiChar(TempAnsi)^, PAnsiChar(Result)^, Length(TempAnsi));\n              end;\n              {$ELSE}\n              Result := AnsiToStringEx(Ansi, ConSettings^.ClientCodePage^.CP, ConSettings^.CTRL_CP);\n              {$ENDIF}\n            {$ENDIF}\n        {$ENDIF}\n      else\n        {$IFDEF UNICODE}\n        Result := AnsiToStringEx(Ansi, ConSettings^.ClientCodePage^.CP);\n        {$ELSE}\n          if ConSettings.AutoEncode then\n            if ConSettings^.ClientCodePage^.CP = zCP_NONE then //that's not nice it slows down the incoming strings! Find a way to determine allways the current server CP\n              case DetectUTF8Encoding(Ansi) of\n                etUSASCII: Result := Ansi;\n                etAnsi:\n                  if ConSettings^.CTRL_CP = zCP_UTF8 then\n                    {$IFDEF WITH_FPC_STRING_CONVERSATION}\n                    begin\n                      //avoid string conversion -> move memory\n                      TempAnsi := AnsiToUTF8(Ansi); //hope we've compatible results ))):\n                      SetLength(Result, Length(TempAnsi));\n                      Move(PAnsiChar(TempAnsi)^, PAnsiChar(Result)^, Length(TempAnsi));\n                    end\n                    {$ELSE}\n                    Result := AnsiToUTF8(Ansi) //hope we've compatible results ))):\n                    {$ENDIF}\n                  else\n                    Result := Ansi;\n                else\n                  if ConSettings^.CTRL_CP = zCP_UTF8 then\n                    Result := Ansi\n                  else\n                    {$IFDEF WITH_FPC_STRING_CONVERSATION}\n                    begin\n                      //avoid string conversion -> move memory\n                      TempAnsi := AnsiToStringEx(Ansi, zCP_UTF8, ConSettings.CTRL_CP);\n                      SetLength(Result, Length(TempAnsi));\n                      Move(PAnsiChar(TempAnsi)^, PAnsiChar(Result)^, Length(TempAnsi));\n                    end;\n                    {$ELSE}\n                      {$IFDEF WITH_LCONVENCODING}\n                      Result := Ansi;\n                      {$ELSE}\n                      Result := AnsiToStringEx(Ansi, zCP_UTF8, ConSettings.CTRL_CP);\n                      {$ENDIF}\n                    {$ENDIF}\n              end\n            else\n              {$IFDEF WITH_LCONVENCODING}\n              Result := ConSettings.DbcConvertFunc(Ansi)\n              {$ELSE}\n                {$IFDEF WITH_FPC_STRING_CONVERSATION}\n                begin\n                  //avoid string conversion -> move memory\n                  TempAnsi := AnsiToStringEx(Ansi, ConSettings.ClientCodePage.CP, ConSettings.CTRL_CP);\n                  SetLength(Result, Length(TempAnsi));\n                  Move(PAnsiChar(TempAnsi)^, PAnsiChar(Result)^, Length(TempAnsi));\n                end\n                {$ELSE}\n                Result := AnsiToStringEx(Ansi, ConSettings.ClientCodePage.CP, ConSettings.CTRL_CP)\n                {$ENDIF}\n              {$ENDIF}\n          else\n            Result := Ansi;\n        {$ENDIF}\n      end;\nend;\n\nfunction TZCodePagedObject.ZDbcString(const Ansi: RawByteString; FromCP: Word): String;\nvar\n  CurrentCP: Word;\n  CurrentEncoding: TZCharEncoding;\nbegin\n  if FromCP = FConsettings.ClientCodePage.CP then\n    Result := ZDbcString(Ansi, ConSettings)\n  else\n  begin\n    CurrentCP := FConsettings.ClientCodePage.CP;\n    CurrentEncoding := FConSettings.ClientCodePage.Encoding;\n    if ( FromCP = zCP_UTF8 ) then\n      FConSettings.ClientCodePage.Encoding := ceUTF8\n    else\n      FConSettings.ClientCodePage.Encoding := ceAnsi;\n    FConsettings.ClientCodePage.CP := FromCP;\n    Result := ZDbcString(Ansi, FConSettings);\n    FConsettings.ClientCodePage.CP := CurrentCP;\n    FConSettings.ClientCodePage.Encoding := CurrentEncoding;\n  end;\nend;\n\nfunction TZCodePagedObject.ZDbcString(const Ansi: RawByteString;\n  const Encoding: TZCharEncoding = ceDefault): String;\nvar\n  TempEncoding, UseEncoding: TZCharEncoding;\nbegin\n  if Encoding = ceDefault then\n    if not Assigned(FConSettings.ClientCodePage) then\n      raise Exception.Create('CodePage-Informations not Assigned!')\n    else\n      UseEncoding := FConSettings.ClientCodePage^.Encoding\n  else\n    UseEncoding := Encoding;\n\n  {$IFNDEF UNICODE}\n  if not FConSettings.AutoEncode and ( FConSettings.ClientCodePage^.Encoding = UseEncoding ) then\n    Result := Ansi\n  else\n  {$ENDIF}\n  begin\n    TempEncoding := FConSettings^.ClientCodePage^.Encoding;\n    FConSettings.ClientCodePage^.Encoding := UseEncoding;\n    Result := ZDbcString(Ansi, FConSettings);\n    FConSettings^.ClientCodePage^.Encoding := TempEncoding;\n  end;\nend;\n\nfunction TZCodePagedObject.ZDbcUnicodeString(const AStr: RawByteString): ZWideString;\nbegin\n  {$IFNDEF WITH_LCONVENCODING}\n  Result := ZRawToUnicode(AStr, FConSettings.ClientCodePage.CP);\n  {$ELSE}\n    case Consettings.ClientCodePage.Encoding of\n      ceAnsi:\n        Result := UTF8Decode(ConSettings.DbcConvertFunc(AStr)); //!!!!SLOW, Job down twice (Ansi up to wide to UTF8 to Wide)\n      else\n        Result := UTF8ToString(AStr)\n    end;\n  {$ENDIF}\nend;\n\nfunction TZCodePagedObject.ZDbcString(const AStr: ZWideString; const Encoding: TZCharEncoding = ceDefault): String;\n{$IFDEF WITH_FPC_STRING_CONVERSATION}\nvar\n  TempAnsi: RawByteString;\n{$ENDIF}\nbegin\n  {$IFDEF UNICODE}\n  Result := AStr;\n  {$ELSE}\n    if not ConSettings.AutoEncode then\n      Result := String(AStr)\n    else\n    {$IFDEF WITH_LCONVENCODING}\n    Result := UTF8Encode(AStr);\n    {$ELSE}\n      {$IFDEF WITH_FPC_STRING_CONVERSATION}\n      begin\n        //avoid string conversion -> move memory\n        TempAnsi := ZUnicodeToRaw(AStr, FConSettings.CTRL_CP);\n        SetLength(Result, Length(TempAnsi));\n        Move(PAnsiChar(TempAnsi)^, PAnsiChar(Result)^, Length(TempAnsi));\n      end\n      {$ELSE}\n      Result := ZUnicodeToRaw(AStr, FConSettings.CTRL_CP);\n      {$ENDIF}\n    {$ENDIF}\n  {$ENDIF}\nend;\n\nfunction TZCodePagedObject.ZDbcUnicodeString(const AStr: RawByteString;\n  const FromCP: Word): ZWideString;\nbegin\n  {$IFNDEF WITH_LCONVENCODING}\n  Result := ZRawToUnicode(AStr, FromCP);\n  {$ELSE}\n  if FromCP = zCP_UTF8 then\n    Result := UTF8Decode(AStr)\n  else\n    if FromCP = ConSettings.ClientCodePage.CP then\n      Result := UTF8Decode(ConSettings.DbcConvertFunc(AStr))\n    else\n      Result := WideString(AStr); //default WideString cast, can't convert\n  {$ENDIF}\nend;\n\n{$IFDEF WITH_RAWBYTESTRING}\nfunction TZCodePagedObject.ZDbcUnicodeString(const AStr: String; const FromCP: Word): ZWideString;\nbegin\n  {$IFDEF UNICODE}\n  Result := AStr;\n  {$ELSE}\n    {$IFNDEF WITH_LCONVENCODING}\n    Result := ZRawToUnicode(AStr, FromCP);\n    {$ELSE}\n    if FromCP = zCP_UTF8 then\n      Result := UTF8Decode(AStr)\n    else\n      if FromCP = ConSettings.ClientCodePage.CP then\n        Result := UTF8Decode(ConSettings.DbcConvertFunc(AStr))\n      else\n        Result := WideString(AStr); //default WideString cast, can't convert\n    {$ENDIF}\n  {$ENDIF}\nend;\n{$ENDIF}\n\n{**\nEgonHugeist:\n  Now use the new Functions to get encoded Strings instead of\n  hard-Coded Compiler-Directives or UTF8Encode/Decode:\n\n  function ZPlainString(const Str: String; const Encoding: TZCharEncoding = ceDefault): AnsiString;\n\n  These functions do auto arrange the in/out-coming AnsiStrings in\n  dependency of the used CharacterSet and the database uses whithout\n  String-DataLoss!! (if possible -> UTF8 is save).\n  @param AStr: the String which has to be handled.\n  @param Encoding is set to Default-Character-Set we've choosen bevor (on conecting)\n    Change this if you need some Transtations to a specified Encoding.\n    Example: CharacterSet was set to Latin1 and some \"special\"-String MUST BE\n     UTF8 instead of Latin1. (SSL-Keys eventualy)\n}\nfunction TZCodePagedObject.ZPlainString(const AStr: String;\n  ConSettings: PZConSettings): RawByteString;\n{$IFDEF WITH_FPC_STRING_CONVERSATION}\nvar\n  TempAnsi: RawByteString;\n{$ENDIF}\nbegin\n  case ConSettings.ClientCodePage.Encoding of\n    ceUTF8:\n      {$IFDEF UNICODE}\n      Result := UTF8Encode(AStr);\n      {$ELSE}\n        if ConSettings.AutoEncode then\n          if DetectUTF8Encoding(AStr) in [etUTF8, etUSASCII] then\n            Result := AStr\n          else\n            if ( ConSettings.CTRL_CP = zCP_UTF8 ) or (ConSettings.CTRL_CP = zCP_UTF8) then //avoid \"no success\" for expected Codepage UTF8 of the Controls\n              {$IFDEF WITH_FPC_STRING_CONVERSATION}\n              begin\n                //avoid string conversion -> move memory\n                TempAnsi := AnsiToUTF8(AStr);\n                SetLength(Result, Length(TempAnsi));\n                Move(PAnsiChar(TempAnsi)^, PAnsiChar(Result)^, Length(TempAnsi));\n              end\n              {$ELSE}\n              Result := AnsiToUTF8(AStr)\n              {$ENDIF}\n            else\n              {$IFDEF WITH_FPC_STRING_CONVERSATION}\n              begin\n                //avoid string conversion -> move memory\n                TempAnsi := StringToAnsiEx(AStr, ConSettings.CTRL_CP, zCP_UTF8);\n                SetLength(Result, Length(TempAnsi));\n                Move(PAnsiChar(TempAnsi)^, PAnsiChar(Result)^, Length(TempAnsi));\n              end\n              {$ELSE}\n                {$IFDEF WITH_LCONVENCODING}\n                Result := AnsiToUTF8(AStr)\n                {$ELSE}\n                Result := StringToAnsiEx(AStr, ConSettings.CTRL_CP, zCP_UTF8)\n                {$ENDIF}\n              {$ENDIF}\n        else\n          Result := AStr;\n      {$ENDIF}\n    else\n      begin\n      {$IFDEF UNICODE}\n        Result := StringToAnsiEx(AStr, ConSettings.ClientCodePage.CP);\n      {$ELSE}\n        if ConSettings.AutoEncode then\n          case DetectUTF8Encoding(AStr) of\n            etUSASCII: Result := AStr;\n            etAnsi:\n              {$IFDEF WITH_LCONVENCODING}\n              if ConSettings.CTRL_CP = ConSettings.ClientCodePage.CP then\n                Result := AStr\n              else\n                Result := ConSettings.PlainConvertFunc(AnsiToUTF8(AStr));\n              {$ELSE}\n              Result := Astr;\n              {$ENDIF}\n            else\n              {$IFDEF WITH_LCONVENCODING}\n              Result := ConSettings.PlainConvertFunc(AStr);\n              {$ELSE}\n                {$IFDEF WITH_FPC_STRING_CONVERSATION}\n                begin\n                  if ConSettings.ClientCodePage.CP = zCP_NONE then\n                    TempAnsi := UTF8ToAnsi(AStr) //hope it's compatible we don't know the server CP here!!\n                  else\n                    TempAnsi := StringToAnsiEx(AStr, zCP_UTF8, ConSettings.ClientCodePage.CP);\n                  //avoid string conversion -> move memory\n                  SetLength(Result, Length(TempAnsi));\n                  Move(PAnsiChar(TempAnsi)^, PAnsiChar(Result)^, Length(TempAnsi));\n                end;\n                {$ELSE}\n                if ConSettings.ClientCodePage.CP = zCP_NONE then\n                  Result := UTF8ToAnsi(AStr) //hope it's compatible we don't know the server CP here!!\n                else\n                  Result := StringToAnsiEx(AStr, zCP_UTF8, ConSettings.ClientCodePage.CP);\n                {$ENDIF}\n              {$ENDIF}\n          end\n        else\n          Result := AStr;\n      {$ENDIF}\n    end;\n  end;\nend;\n\nfunction TZCodePagedObject.ZPlainString(const AStr: String; ConSettings: PZConSettings; const ToCP: Word): RawByteString;\nvar\n  CurrentCP: Word;\n  CurrentEncoding: TZCharEncoding;\nbegin\n  if ToCP = ConSettings.ClientCodePage.CP then\n    Result := ZPlainString(AStr, ConSettings)\n  else\n  begin\n    CurrentCP := ConSettings.ClientCodePage.CP;\n    CurrentEncoding := ConSettings.ClientCodePage.Encoding;\n    ConSettings.ClientCodePage.CP := ToCP;\n    if ( ToCP = zCP_UTF8 ) then\n      ConSettings.ClientCodePage.Encoding := ceUTF8\n    else\n      ConSettings.ClientCodePage.Encoding := ceAnsi;\n    Result := ZPlainString(AStr, ConSettings);\n    ConSettings.ClientCodePage.CP := CurrentCP;\n    ConSettings.ClientCodePage.Encoding := CurrentEncoding;\n  end;\nend;\n\nfunction TZCodePagedObject.ZPlainString(const AStr: String;\n  const Encoding: TZCharEncoding = ceDefault): RawByteString;\nvar\n  TempEncoding, UseEncoding: TZCharEncoding;\nbegin\n  if Encoding = ceDefault then\n    if not Assigned(FConSettings.ClientCodePage) then\n      raise Exception.Create('CodePage-Informations not Assigned!')\n    else\n      UseEncoding := FConSettings.ClientCodePage^.Encoding\n  else\n    UseEncoding := Encoding;\n\n  {$IFNDEF UNICODE}\n  if not FConSettings.AutoEncode and ( FConSettings.ClientCodePage^.Encoding = UseEncoding ) then\n    Result := AStr\n  else\n  {$ENDIF}\n  begin\n    TempEncoding := FConSettings.ClientCodePage.Encoding;\n    FConSettings.ClientCodePage.Encoding := UseEncoding;\n    Result := ZPlainString(AStr, FConSettings);\n    FConSettings.ClientCodePage.Encoding := TempEncoding;\n  end;\nend;\n\nfunction TZCodePagedObject.ZPlainString(const AStr: WideString;\n  const Encoding: TZCharEncoding = ceDefault): RawByteString;\nvar\n  TempEncoding, UseEncoding: TZCharEncoding;\nbegin\n  if Encoding = ceDefault then\n    if not Assigned(FConSettings.ClientCodePage) then\n      raise Exception.Create('CodePage-Informations not Assigned!')\n    else\n      UseEncoding := FConSettings.ClientCodePage^.Encoding\n  else\n    UseEncoding := Encoding;\n\n  TempEncoding := FConSettings.ClientCodePage.Encoding;\n  FConSettings.ClientCodePage.Encoding := UseEncoding;\n  Result := ZPlainString(AStr, FConSettings);\n  FConSettings.ClientCodePage.Encoding := TempEncoding;\nend;\n\nfunction TZCodePagedObject.ZPlainString(const AStr: WideString;\n  ConSettings: PZConSettings): RawByteString;\nbegin\n  {$IFDEF WITH_LCONVENCODING}\n  Result := ConSettings.PlainConvertFunc(UTF8Encode(AStr));\n  {$ELSE}\n  Result := ZUnicodeToRaw(AStr, ConSettings^.ClientCodePage^.CP);\n  {$ENDIF}\nend;\n\nfunction TZCodePagedObject.ZPlainString(const AStr: WideString; ConSettings: PZConSettings; const ToCP: Word): RawByteString;\nvar\n  CurrentCP: Word;\n  CurrentEncoding: TZCharEncoding;\nbegin\n  if ToCP = ConSettings.ClientCodePage.CP then\n    Result := ZPlainString(AStr, ConSettings)\n  else\n  begin\n    CurrentCP := ConSettings.ClientCodePage.CP;\n    CurrentEncoding := ConSettings.ClientCodePage.Encoding;\n    ConSettings.ClientCodePage.CP := ToCP;\n    if ( ToCP = zCP_UTF8 ) then\n      ConSettings.ClientCodePage.Encoding := ceUTF8\n    else\n      ConSettings.ClientCodePage.Encoding := ceAnsi;\n    Result := ZPlainString(AStr, ConSettings);\n    ConSettings.ClientCodePage.CP := CurrentCP;\n    ConSettings.ClientCodePage.Encoding := CurrentEncoding;\n  end;\nend;\n\nfunction TZCodePagedObject.ZPlainUnicodeString(const AStr: String): WideString;\nbegin\n  {$IFDEF UNICODE}\n  Result := AStr;\n  {$ELSE}\n    if FConSettings.AutoEncode then\n      case DetectUTF8Encoding(AStr) of\n        etUTF8, etUSASCII: Result := UTF8Decode(AStr);\n        else\n          Result := WideString(AStr);\n      end\n    else\n      {$IFDEF WITH_LCONVENCODING}\n      Result := UTF8ToString(AStr);\n      {$ELSE}\n      Result := ZRawToUnicode(AStr, FConSettings.CTRL_CP);\n      {$ENDIF}\n  {$ENDIF}\nend;\n\nprocedure TZCodePagedObject.SetConSettingsFromInfo(Info: TStrings);\nbegin\n  if Assigned(Info) and Assigned(FConSettings) then\n  begin\n    {$IFDEF UNICODE}\n    ConSettings.CTRL_CP := ZDefaultSystemCodePage;\n    if Info.values['controls_cp'] = 'GET_ACP' then\n      ConSettings.CPType := cGET_ACP\n    else\n      ConSettings.CPType := cCP_UTF16;\n    ConSettings.AutoEncode := True;\n    {$ELSE}\n      {$IF defined(MSWINDOWS) or defined(FPC_HAS_BUILTIN_WIDESTR_MANAGER) or defined(WITH_LCONVENCODING)}\n      ConSettings.AutoEncode := Info.Values['AutoEncodeStrings'] = 'ON'; //compatibitity Option for existing Applications;\n      {$ELSE}\n      ConSettings.AutoEncode := False;\n      {$IFEND}\n    if Info.values['controls_cp'] = 'GET_ACP' then\n    begin\n      ConSettings.CPType := cGET_ACP;\n      ConSettings.CTRL_CP := ZDefaultSystemCodePage;\n    end\n    else\n      if Info.values['controls_cp'] = 'CP_UTF8' then\n      begin\n        ConSettings.CPType := cCP_UTF8;\n        ConSettings.CTRL_CP := zCP_UTF8;\n      end\n      else\n        if Info.values['controls_cp'] = 'CP_UTF16' then\n        begin\n          {$IF defined(MSWINDOWS) or defined(FPC_HAS_BUILTIN_WIDESTR_MANAGER) or defined(WITH_LCONVENCODING)}\n          ConSettings.CPType := {$IFDEF WITH_WIDEFIELDS}cCP_UTF16{$ELSE}cCP_UTF8{$ENDIF};\n          ConSettings.CTRL_CP := ZDefaultSystemCodePage;\n          ConSettings.AutoEncode := True;\n          {$ELSE}\n          if ConSettings.ClientCodePage.Encoding = ceUTF8 then\n          begin\n            ConSettings.CPType := {$IFDEF WITH_WIDEFIELDS}cCP_UTF16{$ELSE}cCP_UTF8{$ENDIF};\n            ConSettings.CTRL_CP := zCP_UTF8;\n            ConSettings.AutoEncode := True;\n          end\n          else\n          begin\n            ConSettings.CPType := cCP_UTF8;\n            ConSettings.CTRL_CP := zCP_UTF8;\n            ConSettings.AutoEncode := False;\n          end;\n          {$IFEND}\n        end\n        else // nothing was found set defaults\n        begin\n          {$IFDEF FPC}\n          ConSettings.CPType := cCP_UTF8;\n          ConSettings.CTRL_CP := zCP_UTF8;\n          {$ELSE}\n          ConSettings.CPType := cGET_ACP;\n          ConSettings.CTRL_CP := GetACP;\n          {$ENDIF}\n        end;\n    {$ENDIF}\n  end;\nend;\n\ndestructor TZCodePagedObject.Destroy;\nbegin\n  inherited Destroy;\nend;\n\n{$IFDEF WITH_LCONVENCODING}\nfunction NoConvert(const s: string): string;\nbegin\n  Result := S;\nend;\n{$ENDIF}\n\n\n{$IFDEF UNIX}\n  {$IFDEF FPC}\nfunction LoadLibrary(ModuleName: PChar): HMODULE;\nbegin\n  Result := dynlibs.LoadLibrary(ModuleName);\nend;\n\nfunction FreeLibrary(Module: HMODULE): LongBool;\nbegin\n  Result := dynlibs.FreeLibrary(Module);\nend;\n\nfunction GetProcAddress(Module: HMODULE; Proc: PChar): Pointer;\nbegin\n  Result := dynlibs.GetProcAddress(Module,Proc)\nend;\n  {$ENDIF}\n{$ENDIF}\n\n{$IFNDEF FPC}\nfunction Hash(S : AnsiString) : LongWord;\nVar\n  thehash,g,I : LongWord;\nbegin\n   thehash:=0;\n   For I:=1 to Length(S) do { 0 terminated }\n     begin\n     thehash:=thehash shl 4;\n     {$IFOPT Q+}\n       {$DEFINE OverFlowCheckEnabled}\n       {$OVERFLOWCHECKS OFF}\n     {$ENDIF}\n     inc(theHash,Ord(S[i]));\n     {$IFDEF OverFlowCheckEnabled}\n       {$OVERFLOWCHECKS ON}\n     {$ENDIF}\n     g:=thehash and LongWord($f shl 28);\n     if g<>0 then\n       begin\n       thehash:=thehash xor (g shr 24);\n       thehash:=thehash xor g;\n       end;\n     end;\n   If theHash=0 then\n     Hash:=$ffffffff\n   else\n     Hash:=TheHash;\nend;\n\nfunction AnsiProperCase(const S: string; const WordDelims: TSysCharSet): string;\nvar\n  P,PE : PChar;\n\nbegin\n  Result:=AnsiLowerCase(S);\n  P:=PChar(pointer(Result));\n  PE:=P+Length(Result);\n  while (P<PE) do\n    begin\n    while (P<PE) and CharInSet(P^, WordDelims) do\n      inc(P);\n    if (P<PE) then\n      P^:=UpCase(P^);\n    while (P<PE) and not (CharInSet(P^, WordDelims)) do\n      inc(P);\n    end;\nend;\n{$ENDIF}\n\n{$IFNDEF WITH_CHARINSET}\nfunction CharInSet(C: AnsiChar; const CharSet: TSysCharSet): Boolean;\nbegin\n  result := C in Charset;\nend;\n\nfunction CharInSet(C: WideChar; const CharSet: TSysCharSet): Boolean;\nbegin\n  result := Char(C) in Charset;\nend;\n{$ENDIF}\n\n{$IFDEF  ZUTF8ToString}\nfunction UTF8ToString(const s: RawByteString): ZWideString;\nbegin\n  Result := UTF8Decode(s);\nend;\n{$UNDEF ZUTF8ToString}\n{$ENDIF}\n\n\ninitialization\n  case ConSettingsDummy.CPType of\n    cCP_UTF16, cGET_ACP: ConSettingsDummy.CTRL_CP := ZDefaultSystemCodePage;\n    cCP_UTF8: ConSettingsDummy.CTRL_CP := zCP_UTF8;\n  end;\n  SetConvertFunctions(@ConSettingsDummy);\n  \nend.\n\n\n\n\n"
  },
  {
    "path": "lib/zeosdbo/src/core/ZCore.inc",
    "content": "{@********************************************************}\n{    Copyright (c) 1999-2012 Zeos Development Group       }\n{                                                         }\n{ License Agreement:                                      }\n{                                                         }\n{ This library is distributed in the hope that it will be }\n{ useful, but WITHOUT ANY WARRANTY; without even the      }\n{ implied warranty of MERCHANTABILITY or FITNESS FOR      }\n{ A PARTICULAR PURPOSE.  See the GNU Lesser General       }\n{ Public License for more details.                        }\n{                                                         }\n{ The source code of the ZEOS Libraries and packages are  }\n{ distributed under the Library GNU General Public        }\n{ License (see the file COPYING / COPYING.ZEOS)           }\n{ with the following  modification:                       }\n{ As a special exception, the copyright holders of this   }\n{ library give you permission to link this library with   }\n{ independent modules to produce an executable,           }\n{ regardless of the license terms of these independent    }\n{ modules, and to copy and distribute the resulting       }\n{ executable under terms of your choice, provided that    }\n{ you also meet, for each linked independent module,      }\n{ the terms and conditions of the license of that module. }\n{ An independent module is a module which is not derived  }\n{ from or based on this library. If you modify this       }\n{ library, you may extend this exception to your version  }\n{ of the library, but you are not obligated to do so.     }\n{ If you do not wish to do so, delete this exception      }\n{ statement from your version.                            }\n{                                                         }\n{                                                         }\n{ The project web site is located on:                     }\n{   http://zeos.firmos.at  (FORUM)                        }\n{   http://sourceforge.net/p/zeoslib/tickets/ (BUGTRACKER)}\n{   svn://svn.code.sf.net/p/zeoslib/code-0/trunk (SVN)    }\n{                                                         }\n{   http://www.sourceforge.net/projects/zeoslib.          }\n{                                                         }\n{                                                         }\n{                                 Zeos Development Group. }\n{********************************************************@}\n\n{$IFDEF LINUX}\n  {$DEFINE UNIX}\n{$ENDIF}\n\n{$IFNDEF UNIX}\n{$I ..\\Zeos.inc}\n{$ELSE}\n{$I ../Zeos.inc}\n{$ENDIF}\n"
  },
  {
    "path": "lib/zeosdbo/src/core/ZEncoding.pas",
    "content": "{*********************************************************}\n{                                                         }\n{                 Zeos Database Objects                   }\n{         PostgreSQL Database Connectivity Classes        }\n{                                                         }\n{        Originally written by Sergey Seroukhov           }\n{                                                         }\n{*********************************************************}\n\n{@********************************************************}\n{    Copyright (c) 1999-2012 Zeos Development Group       }\n{                                                         }\n{ License Agreement:                                      }\n{                                                         }\n{ This library is distributed in the hope that it will be }\n{ useful, but WITHOUT ANY WARRANTY; without even the      }\n{ implied warranty of MERCHANTABILITY or FITNESS FOR      }\n{ A PARTICULAR PURPOSE.  See the GNU Lesser General       }\n{ Public License for more details.                        }\n{                                                         }\n{ The source code of the ZEOS Libraries and packages are  }\n{ distributed under the Library GNU General Public        }\n{ License (see the file COPYING / COPYING.ZEOS)           }\n{ with the following  modification:                       }\n{ As a special exception, the copyright holders of this   }\n{ library give you permission to link this library with   }\n{ independent modules to produce an executable,           }\n{ regardless of the license terms of these independent    }\n{ modules, and to copy and distribute the resulting       }\n{ executable under terms of your choice, provided that    }\n{ you also meet, for each linked independent module,      }\n{ the terms and conditions of the license of that module. }\n{ An independent module is a module which is not derived  }\n{ from or based on this library. If you modify this       }\n{ library, you may extend this exception to your version  }\n{ of the library, but you are not obligated to do so.     }\n{ If you do not wish to do so, delete this exception      }\n{ statement from your version.                            }\n{                                                         }\n{                                                         }\n{ The project web site is located on:                     }\n{   http://zeos.firmos.at  (FORUM)                        }\n{   http://sourceforge.net/p/zeoslib/tickets/ (BUGTRACKER)}\n{   svn://svn.code.sf.net/p/zeoslib/code-0/trunk (SVN)    }\n{                                                         }\n{   http://www.sourceforge.net/projects/zeoslib.          }\n{                                                         }\n{                                                         }\n{                                 Zeos Development Group. }\n{********************************************************@}\n\nunit ZEncoding;\n\ninterface\n\n{$I ZCore.inc}\n\nuses\n  Classes, {$IFDEF MSEgui}mclasses,{$ENDIF} Math,\n  {$IFDEF WITH_LCONVENCODING}\n  {$MACRO ON}\n   LCLVersion, LConvEncoding,\n  {$ENDIF}\n  {$IF defined(MSWINDOWS) and not defined(WITH_UNICODEFROMLOCALECHARS)}\n  Windows,\n  {$IFEND}\n  ZCompatibility;\n\nconst\n  //zCP_ACP = 0; {ASCII US}\n  zCP_EBC037 = 37; {IBM EBCDIC US-Canada}\n  zCP_EBC273 = 273; {EBCDIC Code Page 273/1 8-bit Austrian German}\n  zCP_EBC277 = 277; {EBCDIC Code Page 277/1 8-bit Danish}\n  zCP_EBC278 = 278; {EBCDIC Code Page 278/1 8-bit Swedish}\n  zCP_EBC280 = 280; {EBCDIC Code Page 280/1 8-bit Italian}\n  zCP_EBC284 = 284; {EBCDIC Code Page 284 8-bit Latin American/Spanish}\n\n  zCP_DOS437 = 437; {IBM437/MS-DOS odepage 437 (US)}\n  zCP_DOS500 = 500; {IBM EBCDIC International}\n  zCP_DOS708 = 708; {Arabic (ASMO 708)}\n  zCP_DOS709 = 709; {Arabic (ASMO-449+, BCON V4)}\n  zCP_DOS710 = 710; {Arabic - Transparent Arabic}\n  zCP_DOS720 = 720; {Arabic (Transparent ASMO); Arabic (DOS)}\n  zCP_DOS737 = 737; {OEM Greek (formerly 437G); Greek (DOS)}\n  zCP_DOS775 = 775; {MS-DOS Codepage 775 (BaltRim)}\n  zCP_DOS850 = 850;\t{MS-DOS Codepage 850 (Multilingual Latin 1)}\n  zCP_DOS851 = 851; {MS-DOS Codepage 851 (Greece) - obsolete}\n  zCP_DOS852 = 852; {ibm852 852 east european(DOS)}\n  zCP_DOS853 = 853;\t{MS-DOS Codepage 853 (Multilingual Latin 3)}\n  zCP_DOS855 = 855;\t{MS-DOS Codepage 855 (Russia) - obsolete}\n  zCP_DOS856 = 856;\n  zCP_DOS857 = 857;\t{MS-DOS Codepage 857 (Multilingual Latin 5)}\n  zCP_DOS858 = 858; {MS-DOS Codepage 858  Latin I + Euro symbol}\n  zCP_DOS895 = 895; {MS-DOS Codepage 895 (Kamenicky CS)}\n  zCP_DOS860 = 860;\t{MS-DOS Codepage 860 (Portugal)}\n  zCP_DOS861 = 861;\t{MS-DOS Codepage 861 (Iceland)}\n  zCP_DOS862 = 862;\t{MS-DOS Codepage 862 (Israel)}\n  zCP_DOS863 = 863;\t{MS-DOS Codepage 863 (Canada (French))}\n  zCP_DOS864 = 864;\t{MS-DOS Codepage 864 (Arabic) without BOX DRAWINGS below 20}\n  zCP_DOS865 = 865;\t{MS-DOS Codepage 865 (Norway)}\n  zCP_DOS866 = 866; {ibm866\t866\tCyrl (DOS)}\n  zCP_DOS869 = 869; {MS-DOS Codepage 869 (Greece)}\n  zCP_DOS870 = 870; {IBM EBCDIC Multilingual/ROECE (Latin 2); IBM EBCDIC Multilingual Latin 2}\n  zCP_DOS874 = 874; {ANSI/OEM Thai (same as 28605, ISO 8859-15); Thai (Windows)}\n  zCP_EBC875 = 875;\t{EBCDIC Codepage 875 (Greek)}\n  zCP_MSWIN921 = 921;\n  zCP_MSWIN923 = 923;\n  zCP_EBC924 = 924; {Latin 9 EBCDIC 924}\n  zCP_SHIFTJS = 932; {ANSI/OEM Japanese; Japanese (Shift-JIS)}\n  zCP_GB2312 = 936; {ANSI/OEM Simplified Chinese (PRC, Singapore); Chinese Simplified (GB2312)}\n  zCP_EUCKR = 949; {ANSI/OEM Korean (Unified Hangul Code)}\n  zCP_Big5 = 950; {ANSI/OEM Traditional Chinese (Taiwan; Hong Kong SAR, PRC); Chinese Traditional (Big5)}\n  zCP_IBM1026 = 1026; {EBCDIC Code Page 1026 8-bit Turkish}\n  zCP_IBM01047 = 1047; {IBM EBCDIC Latin 1/Open System}\n  zCP_IBM01140 = 1140; {IBM EBCDIC US-Canada (037 + Euro symbol); IBM EBCDIC (US-Canada-Euro)}\n  zCP_IBM01141 = 1141; {IBM EBCDIC Germany (20273 + Euro symbol); IBM EBCDIC (Germany-Euro)}\n  zCP_IBM01142 = 1142; {IBM EBCDIC Denmark-Norway (20277 + Euro symbol); IBM EBCDIC (Denmark-Norway-Euro)}\n  zCP_IBM01143 = 1143; {IBM EBCDIC Finland-Sweden (20278 + Euro symbol); IBM EBCDIC (Finland-Sweden-Euro)}\n  zCP_IBM01144 = 1144; {IBM EBCDIC Italy (20280 + Euro symbol); IBM EBCDIC (Italy-Euro)}\n  zCP_IBM01145 = 1145; {IBM EBCDIC Latin America-Spain (20284 + Euro symbol); IBM EBCDIC (Spain-Euro)}\n  zCP_IBM01146 = 1146; {IBM EBCDIC United Kingdom (20285 + Euro symbol); IBM EBCDIC (UK-Euro)}\n  zCP_IBM01147 = 1147; {IBM EBCDIC France (20297 + Euro symbol); IBM EBCDIC (France-Euro)}\n  zCP_IBM01148 = 1148; {IBM EBCDIC International (500 + Euro symbol); IBM EBCDIC (International-Euro)}\n  zCP_IBM01149 = 1149; {IBM EBCDIC Icelandic (20871 + Euro symbol); IBM EBCDIC (Icelandic-Euro)}\n\n  zCP_UTF16 = 1200; {utf-16; Indicates the Unicode character set, Windows code page 1200}\n  zCP_UTF16BE = 1201; {Unicode UTF-16, big endian byte order; available only to managed applications}\n  zCP_WIN1250 = 1250; {Microsoft Windows Codepage 1250 (East European)}\n  zCP_WIN1251 = 1251; {Microsoft Windows Codepage 1251 (Cyrl)}\n  zCP_WIN1252 = 1252; {Microsoft Windows Codepage 1252 (ANSI), USASCCI}\n  zCP_WIN1253 = 1253; {Microsoft Windows Codepage 1253 (Greek)}\n  zCP_WIN1254 = 1254; {Microsoft Windows Codepage 1254 (Turk)}\n  zCP_WIN1255 = 1255; {Microsoft Windows Codepage 1255 (Hebrew)}\n  cCP_WIN1256 = 1256; {Microsoft Windows Codepage 1256 (Arab)}\n  zCP_WIN1257 = 1257; {Microsoft Windows Codepage 1257 (BaltRim)}\n  zCP_WIN1258 = 1258; {Microsoft Windows Codepage 1258 (Viet), TCVN-5712}\n  ZCP_JOHAB = 1361; {Korean (Johab)}\n  zCP_KOREAN = 2022; {iso-2022-kr\t50225\tKorean (ISO)}\n\n  zCP_macintosh = 10000; {MAC Roman; Western European (Mac)}\n  zCP_x_mac_japanese = 10001; {Japanese (Mac)}\n  zCP_x_mac_chinesetrad = 10002; {MAC Traditional Chinese (Big5); Chinese Traditional (Mac)}\n  zCP_x_mac_korean = 10003; {Korean (Mac)}\n  zCP_x_mac_arabic = 10004;\t{Arabic (Mac)}\n  zCP_x_mac_hebrew = 10005; {Hebrew (Mac)}\n  zCP_x_mac_greek = 10006;\t{Greek (Mac)}\n  zCP_x_mac_cyrillic = 10007; {Cyrillic (Mac)}\n  zCP_x_mac_chinesesimp = 10008; {MAC Simplified Chinese (GB 2312); Chinese Simplified (Mac)}\n  zCP_x_mac_romanian = 10010; {Romanian (Mac)}\n  zCP_x_mac_ukrainian = 10017; {Ukrainian (Mac)}\n  zCP_x_mac_thai = 10021; {Thai (Mac)}\n  zCP_x_mac_ce = 10029; {MAC Latin 2; Central European (Mac)}\n  zCP_x_mac_icelandic = 10079;\t{Icelandic (Mac)}\n  zCP_x_mac_turkish = 10081;\t{Turkish (Mac)}\n  zCP_x_mac_croatian = 10082; {Croatian (Mac)}\n  zCP_utf32 = 12000; {Unicode UTF-32, little endian byte order; available only to managed applications}\n  zCP_utf32BE = 12001; {Unicode UTF-32, big endian byte order; available only to managed applications}\n\n  zCP_x_Chinese_CNS = 20000; {CNS Taiwan; Chinese Traditional (CNS)}\n  zCP_x_cp20001 = 20001; {TCA Taiwan}\n  zCP_x_Chinese_Eten = 20002; {Eten Taiwan; Chinese Traditional (Eten)}\n  zCP_x_cp20003 = 20003; {IBM5550 Taiwan}\n  zCP_x_cp20004 = 20004; {TeleText Taiwan}\n  zCP_x_cp20005 = 20005; {Wang Taiwan}\n  zCP_x_IA5 = 20105; {IA5 (IRV International Alphabet No. 5, 7-bit); Western European (IA5)}\n  zCP_x_IA5_German = 20106; {IA5 German (7-bit)}\n  zCP_x_IA5_Swedish = 20107; {IA5 Swedish (7-bit)}\n  zCP_x_IA5_Norwegian = 20108; {IA5 Norwegian (7-bit)}\n  zCP_us_ascii = 20127; {US-ASCII (7-bit)}\n  zCP_x_cp20261 = 20261; {T.61}\n  zCP_x_cp20269 = 20269; {ISO 6937 Non-Spacing Accent}\n  zCP_IBM273 = 20273; {IBM EBCDIC Germany}\n  zCP_IBM277 = 20277; {IBM EBCDIC Denmark-Norway}\n  zCP_IBM278 = 20278; {IBM EBCDIC Finland-Sweden}\n  zCP_IBM280 = 20280; {IBM EBCDIC Italy}\n  zCP_IBM284 = 20284; {IBM EBCDIC Latin America-Spain}\n  zCP_IBM285 = 20285; {IBM EBCDIC United Kingdom}\n  zCP_IBM290 = 20290; {IBM EBCDIC Japanese Katakana Extended}\n  zCP_IBM297 = 20297; {IBM EBCDIC France}\n  zCP_IBM420 = 20420; {IBM EBCDIC Arabic}\n  zCP_IBM423 = 20423; {IBM EBCDIC Greek}\n  zCP_IBM424 = 20424; {IBM EBCDIC Hebrew}\n  zCP_x_EBCDIC_KoreanExtended = 20833; {IBM EBCDIC Korean Extended}\n  zCP_IBM_Thai = 20838; {IBM EBCDIC Thai / TIS-620}\n  zCP_KOI8R = 20866; {cskoi8r\t20866\tCyrillic (KOI8-R)}\n  zCP_IBM871 = 20871; {IBM EBCDIC Icelandic}\n  zCP_IBM880 = 20880; {IBM EBCDIC Cyrillic Russian}\n  zCP_IBM905 = 20905; {IBM EBCDIC Turkish}\n  zCP_IBM00924 = 20924; {IBM EBCDIC Latin 1/Open System (1047 + Euro symbol)}\n  zCP_EUC_JP = 20932; {Japanese (JIS 0208-1990 and 0121-1990)}\n  zCP_x_cp20936 = 20936;\t{Simplified Chinese (GB2312); Chinese Simplified (GB2312-80)}\n  zCP_x_cp20949 = 20949;\t{Korean Wansung}\n  zCP_cp1025 = 21025;\t{IBM EBCDIC Cyrillic Serbian-Bulgarian}\n  //21027 (deprecated)}}\n  zCP_KOI8U = 21866; {KOI8-U is an 8-bit character encoding, designed to cover Ukrainian, which uses the Cyrillic alphabet.}\n  zCP_L1_ISO_8859_1 = 28591; {8-bit single-byte coded graphic character sets Part 1: Latin alphabet No. 1, is part of the ISO/IEC 8859 series of ASCII-based standard character encodings}\n  zCP_L2_ISO_8859_2 = 28592; {latin2\teast european (ISO), 8-bit single-byte coded graphic character sets - Part 2: Latin alphabet No. 2, is part of the ISO/IEC 8859 series of ASCII-based standard character encodings}\n  zCP_L3_ISO_8859_3 = 28593; {ISO 8859-3 Latin 3}\n  zCP_L4_ISO_8859_4 = 28594; {ISO 8859-4 Baltic}\n  zCP_L5_ISO_8859_5 = 28595; {8bit single-byte coded graphic character sets - Part 5: Latin/Cyrillic alphabet, is part of the ISO/IEC 8859 series of ASCII-based standard character encodings}\n  zCP_L6_ISO_8859_6 = 28596; {ISO 8859-6 Arabic}\n  zCP_L7_ISO_8859_7 = 28597; {ISO 8859-7 Greek}\n  zCP_L8_ISO_8859_8 = 28598; {ISO 8859-8 Hebrew; Hebrew (ISO-Visual)}\n  zCP_L5_ISO_8859_9 = 28599; {ISO 8859-9 Turkish}\n  zCP_L6_ISO_8859_10 = 28600; { ISO 8859-10, ECMA 144 \tNordic }\n  zCP_L7_ISO_8859_13 = 28603; {ISO 8859-13 Estonian}\n  zCP_L8_ISO_8859_14 = 28604; { ISO 8859-14 \tCeltic }\n  zCP_L9_ISO_8859_15 = 28605; {ISO 8859-15 Latin 9}\n  zCP_L10_ISO_8859_16 = 28606;  { ISO 8859-16, ASRO SR 14111 \tRomanian }\n  zCP_x_Europa = 29001; {Europa 3}\n  zCP_iso_8859_8_i = 38598;\t{ISO 8859-8 Hebrew; Hebrew (ISO-Logical)}\n\n  zCP_iso_2022_jp = 50220;\t{ISO 2022 Japanese with no halfwidth Katakana; Japanese (JIS)}\n  zCP_csISO2022JP = 50221;\t{ISO 2022 Japanese with halfwidth Katakana; Japanese (JIS-Allow 1 byte Kana)}\n  zCP_x_iso_2022_jp = 50222;\t{ISO 2022 Japanese JIS X 0201-1989; Japanese (JIS-Allow 1 byte Kana - SO/SI)}\n  zCP_iso_2022_kr = 50225; {ISO 2022 Korean}\n  zCP_x_cp50227 = 50227;\t{ISO 2022 Simplified Chinese; Chinese Simplified (ISO 2022)}\n  zCP_EUC_TC_ISO220 = 50229; {ISO 2022 Traditional Chinese}\n  zCP_EBCDIC_euc_jpe = 50930;\t{EBCDIC Japanese (Katakana) Extended}\n  zCP_EBCDIC_euc_jp = 50931; {EBCDIC US-Canada and Japanese}\n  zCP_euc_jp_auto = 50932; {EUC Japanese, Indicates Japanese auto-detect (50932). }\n  zCP_EBCDIC_euc_kr = 50933; {EBCDIC Korean Extended and Korean}\n  zCP_EBCDIC_euc_cn = 50935; {EBCDIC Simplified Chinese Extended and Simplified Chinese}\n  zCP_EBCDIC_euc_sc = 50936; {EBCDIC Simplified Chinese}\n  zCP_EBCDIC_USC_TC = 50937; {EBCDIC US-Canada and Traditional Chinese}\n  zCP_euc_cn_auto = 50939; {EBCDIC Japanese (Latin) Extended and Japanese}\n  zCP_euc_kr_auto = 50949; {EUC Korean, Indicates Korean auto-detect (50949).}\n  zCP_euc_JP_win = 51932; {EUC Japanese}\n  zCP_EUC_CN = 51936; {EUC Simplified Chinese; Chinese Simplified (EUC)}\n  zCP_euc_kr = 51949; {EUC Korean}\n  zCP_euc_tc = 51950; {EUC Traditional Chinese}\n  zCP_hz_gb_2312 = 52936; {HZ-GB2312 Simplified Chinese; Chinese Simplified (HZ)}\n  zCP_GB18030 = 54936;\t{Windows XP and later: GB18030 Simplified Chinese (4 byte); Chinese Simplified (GB18030)}\n  zCP_x_iscii_de = 57002;\t{ISCII Devanagari}\n  zCP_x_iscii_be = 57003; {ISCII Bengali}\n  zCP_x_iscii_ta = 57004; {ISCII Tamil}\n  zCP_x_iscii_te = 57005; {ISCII Telugu}\n  zCP_x_iscii_as = 57006; {ISCII Assamese}\n  zCP_x_iscii_or = 57007; {ISCII Oriya}\n  zCP_x_iscii_ka = 57008; {ISCII Kannada}\n  zCP_x_iscii_ma = 57009; {ISCII Malayalam}\n  zCP_x_iscii_gu = 57010; {ISCII Gujarati}\n  zCP_x_iscii_pa = 57011; {ISCII Punjabi}\n  zCP_UTF8 = 65001;\n  zCP_UTF7 = 65000;\n  zCP_NONE = $ffff;\n\n{$IFDEF WITH_LCONVENCODING}\nconst\n  ZLConvCodepages: array[0..16] of Word = (\n    28591,  //ISO_8859_1\n    28592,  //ISO_8859_2\n    1250,   //WIN1250\n    1251,   //WIN1251\n    1252,   //WIN1252\n    1253,   //WIN1253\n    1254,   //WIN1254\n    1255,   //WIN1255\n    1256,   //WIN1256\n    1257,   //WIN1257\n    1258,   //WIN1258\n    437,    //CP437\n    850,    //CP850\n    852,    //CP852\n    866,    //CP866\n    874,    //CP874\n    20866   //KOI8 (Russian)\n    );\n\nfunction IsLConvEncodingCodePage(const CP: Word): Boolean;\nprocedure SetConvertFunctions(const CTRL_CP, DB_CP: Word;\n  out PlainConvert, DbcConvert: TConvertEncodingFunction); overload;\n{$ELSE}\n\nfunction StringToAnsiEx(const s: String; const {$IFNDEF UNICODE}FromCP,{$ENDIF} ToCP: Word): RawByteString; {$IFDEF WITH_INLINE}inline;{$ENDIF}\nfunction AnsiToStringEx(const s: RawByteString; const FromCP{$IFNDEF UNICODE}, ToCP{$ENDIF}: Word): String; {$IFDEF WITH_INLINE}inline;{$ENDIF}\n{$ENDIF}\n\nfunction ZRawToUnicode(const S: RawByteString; const CP: Word): ZWideString;\nfunction ZUnicodeToRaw(const US: ZWideString; CP: Word): RawByteString;\n\n{converter functions for the String-types}\nfunction ZConvertAnsiToRaw(const Src: AnsiString; const RawCP: Word): RawByteString;\nfunction ZConvertRawToAnsi(const Src: RawByteString; const RawCP: Word): AnsiString;\nfunction ZConvertAnsiToUTF8(const Src: AnsiString): UTF8String;\nfunction ZConvertUTF8ToAnsi(const Src: UTF8String): AnsiString;\nfunction ZConvertRawToUTF8(const Src: RawByteString; const CP: Word): UTF8String;\nfunction ZConvertUTF8ToRaw(Const Src: UTF8String; const CP: Word): RawByteString;\nfunction ZConvertRawToString(const Src: RawByteString; const RawCP, StringCP: Word): String;\nfunction ZConvertStringToRaw(const Src: String; const StringCP, RawCP: Word): RawByteString;\nfunction ZConvertStringToRawWithAutoEncode(const Src: String; const StringCP, RawCP: Word): RawByteString;\nfunction ZConvertUTF8ToString(const Src: UTF8String; const StringCP: Word): String;\nfunction ZConvertStringToUTF8(const Src: String; const StringCP: Word): UTF8String;\nfunction ZConvertStringToUTF8WithAutoEncode(const Src: String; const StringCP: Word): UTF8String;\nfunction ZConvertStringToAnsi(const Src: String; const StringCP: Word): AnsiString;\nfunction ZConvertStringToAnsiWithAutoEncode(const Src: String; const StringCP: Word): AnsiString;\nfunction ZConvertAnsiToString(const Src: AnsiString; const StringCP: Word): String;\nfunction ZConvertUnicodeToString(const Src: ZWideString; const StringCP: Word): String;\nfunction ZConvertUnicodeToString_CPUTF8(const Src: ZWideString; const StringCP: Word): String;\nfunction ZConvertStringToUnicode(const Src: String; const StringCP: Word): ZWideString;\nfunction ZConvertString_CPUTF8ToUnicode(const Src: String; const StringCP: Word): ZWideString;\nfunction ZConvertStringToUnicodeWithAutoEncode(const Src: String; const StringCP: Word): ZWideString;\n{move functions for the String types}\nfunction ZMoveAnsiToRaw(const Src: AnsiString; const RawCP: Word): RawByteString;\nfunction ZMoveRawToAnsi(const Src: RawByteString; const RawCP: Word): AnsiString;\nfunction ZMoveAnsiToUTF8(const Src: AnsiString): UTF8String;\nfunction ZMoveUTF8ToAnsi(const Src: UTF8String): AnsiString;\nfunction ZMoveRawToUTF8(const Src: RawByteString; const CP: Word): UTF8String;\nfunction ZMoveUTF8ToRaw(Const Src: UTF8String; const CP: Word): RawByteString;\nfunction ZMoveStringToAnsi(Const Src: String; const StringCP: Word): AnsiString;\nfunction ZMoveAnsiToString(const Src: AnsiString; const StringCP: Word): String;\nfunction ZMoveRawToString(const Src: RawByteString; const RawCP, StringCP: Word): String;\nfunction ZMoveStringToRaw(const Src: String; const StringCP, RawCP: Word): RawByteString;\nfunction ZMoveUTF8ToString(const Src: UTF8String; StringCP: Word): String;\nfunction ZMoveStringToUTF8(const Src: String; const StringCP: Word): UTF8String;\n\nfunction ZUnknownRawToUnicode(const S: RawByteString; const CP: Word): ZWideString;\nfunction ZUnknownRawToUnicodeWithAutoEncode(const S: RawByteString;\n  const CP: Word): ZWideString;\nfunction ZUnicodeToUnknownRaw(const US: ZWideString; CP: Word): RawByteString;\n\n{**\n  Get the current system codepage of AnsiString\n  @return current system codepage of AnsiString\n}\nfunction ZDefaultSystemCodePage: Word;\n\n{**\n  Is the codepage equal or compatible?\n  @param CP1 word the first codepage to compare\n  @param CP2 word the second codepage to compare\n  @returns Boolean True if codepage is equal or compatible\n}\nfunction ZCompatibleCodePages(const CP1, CP2: Word): Boolean; {$IFDEF WITH_INLINE}inline;{$ENDIF}\n\n{**\n  Set the string-types conversion funtion in relation to the Connection-Settings.\n  The Results should be as optimal as possible to speed up the behavior\n  @param ConSettings a Pointer to the ConnectionSetting\n}\nprocedure SetConvertFunctions(ConSettings: PZConSettings); {$IFDEF WITH_LCONVENCODING}overload;{$ENDIF}\n\n{**\n  GetValidatedTextStream the incoming Stream for his given Memory and\n  returns a valid UTF8/Ansi StringStream\n  @param Stream the Stream with the unknown format and data\n  @return a valid utf8 encoded stringstram\n}\nfunction GetValidatedAnsiStringFromBuffer(const Buffer: Pointer; Size: Cardinal;\n  ConSettings: PZConSettings): RawByteString; overload;\n\nfunction GetValidatedAnsiStringFromBuffer(const Buffer: Pointer; Size: Cardinal;\n  ConSettings: PZConSettings; ToCP: Word): RawByteString; overload;\n\nfunction GetValidatedAnsiStringFromBuffer(const Buffer: Pointer; Size: Cardinal;\n  WasDecoded: Boolean; ConSettings: PZConSettings): RawByteString; overload;\n\nfunction GetValidatedAnsiString(const Ansi: RawByteString;\n  ConSettings: PZConSettings; const FromDB: Boolean): RawByteString; overload;\n\nfunction GetValidatedAnsiString(const Uni: ZWideString;\n  ConSettings: PZConSettings; const FromDB: Boolean): RawByteString; overload;\n\n{**\n  GetValidatedUnicodeStream the incoming Stream for his given Memory and\n  returns a valid Unicode/Widestring Stream\n  @param Buffer the pointer to the Data\n  @return a valid Unicode encoded stringstram\n}\nfunction GetValidatedUnicodeStream(const Buffer: Pointer; Size: Cardinal;\n  ConSettings: PZConSettings; FromDB: Boolean): TStream; overload;\n\nfunction GetValidatedUnicodeStream(const Ansi: RawByteString;\n  ConSettings: PZConSettings; FromDB: Boolean): TStream; overload;\n\nimplementation\n\nuses SysUtils, Types {$IFDEF WITH_WIDESTRUTILS},WideStrUtils{$ENDIF},\n  ZSysUtils{$IFDEF WITH_STRLEN_DEPRECATED}, AnsiStrings{$ENDIF};\n\n{$IFDEF FPC}\n  {$HINTS OFF}\n{$ENDIF}\nfunction ZUnknownRawToUnicode(const S: RawByteString;\n  const CP: Word): ZWideString;\nbegin\n  Result := ZWideString(S);\nend;\n\nfunction ZUnknownRawToUnicodeWithAutoEncode(const S: RawByteString;\n  const CP: Word): ZWideString;\nbegin\n  case DetectUTF8Encoding(S) of\n    etUSASCII, etUTF8: Result := UTF8ToString(S);\n    else\n      Result := ZWideString(S);\n  end;\nend;\n\nfunction ZUnicodeToUnknownRaw(const US: ZWideString; CP: Word):\n  RawByteString;\nbegin\n  Result := RawByteString(US);\nend;\n{$IFDEF FPC}\n  {$HINTS ON}\n{$ENDIF}\n\nfunction ZRawToUnicode(const S: RawByteString; const CP: Word): ZWideString;\n{$IFDEF WITH_LCONVENCODING}\nbegin\n  case CP of\n    28591: //ISO_8859_1\n      Result := UTF8Decode(ISO_8859_1ToUTF8(PAnsiChar(S)));\n    28592:  //ISO_8859_2\n      Result := UTF8Decode(ISO_8859_2ToUTF8(PAnsiChar(S)));\n    1250: //WIN1250\n      Result := UTF8Decode(CP1250ToUTF8(PAnsiChar(S)));\n    1251: //WIN1251\n      Result := UTF8Decode(CP1251ToUTF8(PAnsiChar(S)));\n    1252: //WIN1252\n      Result := UTF8Decode(CP1252ToUTF8(PAnsiChar(S)));\n    1253: //WIN1253\n      Result := UTF8Decode(CP1253ToUTF8(PAnsiChar(S)));\n    1254: //WIN1254\n      Result := UTF8Decode(CP1254ToUTF8(PAnsiChar(S)));\n    1255: //WIN1255\n      Result := UTF8Decode(CP1255ToUTF8(PAnsiChar(S)));\n    1256: //WIN1256\n      Result := UTF8Decode(CP1256ToUTF8(PAnsiChar(S)));\n    1257: //WIN1257\n      Result := UTF8Decode(CP1257ToUTF8(PAnsiChar(S)));\n    1258: //WIN1258\n      Result := UTF8Decode(CP1258ToUTF8(PAnsiChar(S)));\n    437: //CP437\n      Result := UTF8Decode(CP437ToUTF8(PAnsiChar(S)));\n    850: //CP850\n      Result := UTF8Decode(CP850ToUTF8(PAnsiChar(S)));\n    {$IFDEF LCONVENCODING_HAS_CP852_FUNCTIONS}\n    852: //CP852\n      Result := UTF8Decode(CP852ToUTF8(PAnsiChar(S)));\n    {$ENDIF}\n    866: //CP866\n      Result := UTF8Decode(CP866ToUTF8(PAnsiChar(S)));\n    874: //CP874\n      Result := UTF8Decode(CP874ToUTF8(PAnsiChar(S)));\n    20866: //KOI8 (Russian)\n      Result := UTF8Decode(KOI8ToUTF8(PAnsiChar(S)));\n    65001: //UTF8\n      Result := UTF8Decode(PAnsiChar(s));\n    else\n      Result := ZWideString(S); //random success!\n  end;\nend;\n{$ELSE}\n{$IF defined(MSWINDOWS) or defined(WITH_UNICODEFROMLOCALECHARS)}\nvar\n  {$IFDEF WITH_UNICODEFROMLOCALECHARS}\n  wlen, ulen: Integer;\n  {$ELSE}\n  l: Integer;\n  US: WideString;\n  {$ENDIF}\n{$IFEND}\nbegin\n  Result := '';\n  if CP = zCP_NONE  then\n    Result := ZUnknownRawToUnicode(s, CP)\n  else\n    {$IF defined(MSWINDOWS) or defined(WITH_UNICODEFROMLOCALECHARS)}\n    begin\n      {$IFDEF WITH_UNICODEFROMLOCALECHARS}\n      ulen := Length(s);\n      wlen := UnicodeFromLocaleChars(cp, 0, PAnsiChar(S), ulen, NIL, 0); // wlen is the number of UCS2 without NULL terminater.\n      if wlen = 0 then exit;\n      SetLength(result, wlen);\n      UnicodeFromLocaleChars(cp, 0, PAnsiChar(S), ulen, PWideChar(Result), wlen);\n      {$ELSE}\n      l := MultiByteToWideChar(CP, 0, PAnsiChar(@s[1]), - 1, nil, 0); //Checkout the Result-Lengh\n      if l = 0 then Exit;\n      SetLength(US, l - 1); //Set Result-Length\n      MultiByteToWideChar(CP, 0, PAnsiChar(@s[1]),\n        - 1, PWideChar(@US[1]), l - 1); //Convert Ansi to Wide with supported Chars\n      Result := US;\n      {$ENDIF}\n    end;\n    {$ELSE}\n      {$IFDEF FPC_HAS_BUILTIN_WIDESTR_MANAGER} //FPC2.7+\n      WidestringManager.Ansi2WideMoveProc(PAnsiChar(s), CP, Result, Length(s));\n      {$ELSE}\n      if ZCompatibleCodePages(CP, zCP_UTF8) then\n        Result := UTF8Encode(s)\n      else\n        Result := ZWideString(s);\n      {$ENDIF}\n    {$IFEND}\nend;\n{$ENDIF}\n\nfunction ZUnicodeToRaw(const US: ZWideString; CP: Word): RawByteString;\n{$IFDEF WITH_LCONVENCODING}\nbegin\n  case CP of\n    28591: //ISO_8859_1\n      Result := UTF8ToISO_8859_1(UTF8Encode(US));\n    28592:  //ISO_8859_2\n      Result := UTF8ToISO_8859_2(UTF8Encode(US));\n    1250: //WIN1250\n      Result := UTF8ToCP1250(UTF8Encode(US));\n    1251: //WIN1251\n      Result := UTF8ToCP1251(UTF8Encode(US));\n    1252: //WIN1252\n      Result := UTF8ToCP1252(UTF8Encode(US));\n    1253: //WIN1253\n      Result := UTF8ToCP1253(UTF8Encode(US));\n    1254: //WIN1254\n      Result := UTF8ToCP1254(UTF8Encode(US));\n    1255: //WIN1255\n      Result := UTF8ToCP1255(UTF8Encode(US));\n    1256: //WIN1256\n      Result := UTF8ToCP1256(UTF8Encode(US));\n    1257: //WIN1257\n      Result := UTF8ToCP1257(UTF8Encode(US));\n    1258: //WIN1258\n      Result := UTF8ToCP1258(UTF8Encode(US));\n    437: //CP437\n      Result := UTF8ToCP437(UTF8Encode(US));\n    850: //CP850\n      Result := UTF8ToCP850(UTF8Encode(US));\n    {$IFDEF LCONVENCODING_HAS_CP852_FUNCTIONS}\n    852: //CP852\n      Result := UTF8ToCP852(UTF8Encode(US));\n    {$ENDIF}\n    866: //CP866\n      Result := UTF8ToCP866(UTF8Encode(US));\n    874: //CP874\n      Result := UTF8ToCP874(UTF8Encode(US));\n    20866: //KOI8 (Russian)\n      Result := UTF8ToKOI8(UTF8Encode(US));\n    65001: //UTF8\n      Result := UTF8Encode(US);\n    else\n      Result := RawByteString(US); //random success!\n  end;\nend;\n{$ELSE}\n{$IF defined(MSWINDOWS) or defined(WITH_UNICODEFROMLOCALECHARS)}\nvar\n  {$IFDEF WITH_UNICODEFROMLOCALECHARS}\n  wlen, ulen: Integer;\n  {$ELSE}\n  l: Integer;\n  WS: WideString;\n  {$ENDIF}\n{$IFEND}\nbegin\n  Result := '';\n  if CP = zCP_NONE then\n    Result := RawByteString(US) //random success\n  else\n    {$IF defined(MSWINDOWS) or defined(WITH_UNICODEFROMLOCALECHARS)}\n    begin\n      {$IFDEF WITH_UNICODEFROMLOCALECHARS}\n      wlen := Length(US);\n      ulen := LocaleCharsFromUnicode(CP, 0, PWideChar(US), wlen, NIL, 0, NIL, NIL);\n      setlength(Result, ulen);\n      LocaleCharsFromUnicode(CP, 0, PWideChar(US), wlen, PAnsiChar(Result), ulen, NIL, NIL);\n      {$ELSE}\n      WS := US;\n      l := WideCharToMultiByte(CP,0, @WS[1], - 1, nil, 0, nil, nil); //Checkout the result length\n      if l = 0 then Exit;\n      SetLength(Result, l - 1); //SetResult Length\n      WideCharToMultiByte(CP,0, @WS[1], - 1, @Result[1], l - 1, nil, nil); // Convert Wide down to Ansi\n      {$ENDIF}\n    end;\n    {$ELSE}\n      {$IFDEF FPC_HAS_BUILTIN_WIDESTR_MANAGER} //FPC2.7+\n      WidestringManager.Unicode2AnsiMoveProc(PWideChar(US), Result, CP, Length(US));\n      {$ELSE}\n      if ZCompatibleCodePages(CP, zCP_UTF8) then\n        Result := UTF8Encode(US)\n      else\n        Result := RawByteString(US); //random success\n      {$ENDIF}\n    {$IFEND}\nend;\n{$ENDIF}\n\n{$IFNDEF WITH_LCONVENCODING}\nfunction AnsiToStringEx(const s: RawByteString;\n  const FromCP{$IFNDEF UNICODE}, ToCP{$ENDIF}: Word): String;\nbegin\n  if s = '' then\n    Result := ''\n  else\n    if ( FromCP = zCP_NONE ) {$IFNDEF UNICODE} or ( FromCP = ToCP ){$ENDIF}then\n      Result := String(s)\n    else\n      {$IFDEF UNICODE}\n      if FromCP = zCP_UTF8 then\n        result := UTF8ToString(s)\n      else\n        Result := ZRawToUnicode(s, FromCP);\n      {$ELSE} //Ansi-Compiler\n        Result := ZUnicodeToRaw(ZRawToUnicode(s, FromCP), ToCP);\n      {$ENDIF}\nend;\n\nfunction StringToAnsiEx(const s: String; const {$IFNDEF UNICODE}FromCP, {$ENDIF} ToCP: Word): RawByteString;\nbegin\n  if s = '' then\n    Result := ''\n  else\n    if ( ToCP = zCP_NONE ) {$IFNDEF UNICODE} or ( FromCP = ToCP ){$ENDIF}then\n      Result := RawByteString(s)\n    else\n      {$IFDEF UNICODE}\n      if ToCP = zCP_UTF8 then\n        result := UTF8Encode(s)\n      else\n        Result := ZUnicodeToRaw(s, ToCP);\n      {$ELSE} //Ansi-Compiler\n        Result := ZUnicodeToRaw(ZRawToUnicode(s, FromCP), ToCP);\n      {$ENDIF}\nend;\n\n{$ELSE}\n\nfunction IsLConvEncodingCodePage(const CP: Word): Boolean;\nvar\n  I: Integer;\nbegin\n  for i := 0 to High(ZLConvCodepages) do\n  begin\n    Result := CP = ZLConvCodepages[i];\n    if Result then Break;\n  end;\nend;\n\nfunction NoConvert(const s: string): string;\nbegin\n  Result := s;\nend;\n\nprocedure SetConvertFunctions(const CTRL_CP, DB_CP: Word;\n  out PlainConvert, DbcConvert: TConvertEncodingFunction);\nbegin\n  if CTRL_CP = DB_CP then\n  begin\n    PlainConvert := @NoConvert;\n    DbcConvert := @NoConvert;\n  end\n  else\n  begin\n    case DB_CP of\n      28591: //ISO_8859_1\n        begin\n          DbcConvert := @ISO_8859_1ToUTF8;\n          PlainConvert := @UTF8ToISO_8859_1;\n        end;\n      28592:  //ISO_8859_2\n        begin\n          DbcConvert := @ISO_8859_2ToUTF8;\n          PlainConvert := @UTF8ToISO_8859_2;\n        end;\n      1250: //WIN1250\n        begin\n          DbcConvert := @CP1250ToUTF8;\n          PlainConvert := @UTF8ToCP1250;\n        end;\n      1251: //WIN1251\n        begin\n          DbcConvert := @CP1251ToUTF8;\n          PlainConvert := @UTF8ToCP1251;\n        end;\n      1252: //WIN1252\n        begin\n          DbcConvert := @CP1252ToUTF8;\n          PlainConvert := @UTF8ToCP1252;\n        end;\n      1253: //WIN1253\n        begin\n          DbcConvert := @CP1253ToUTF8;\n          PlainConvert := @UTF8ToCP1253;\n        end;\n      1254: //WIN1254\n        begin\n          DbcConvert := @CP1254ToUTF8;\n          PlainConvert := @UTF8ToCP1254;\n        end;\n      1255: //WIN1255\n        begin\n          DbcConvert := @CP1255ToUTF8;\n          PlainConvert := @UTF8ToCP1255;\n        end;\n      1256: //WIN1256\n        begin\n          DbcConvert := @CP1256ToUTF8;\n          PlainConvert := @UTF8ToCP1256;\n        end;\n      1257: //WIN1257\n        begin\n          DbcConvert := @CP1257ToUTF8;\n          PlainConvert := @UTF8ToCP1257;\n        end;\n      1258: //WIN1258\n        begin\n          DbcConvert := @CP1258ToUTF8;\n          PlainConvert := @UTF8ToCP1258;\n        end;\n      437: //CP437\n        begin\n          DbcConvert := @CP437ToUTF8;\n          PlainConvert := @UTF8ToCP437;\n        end;\n      850: //CP850\n        begin\n          DbcConvert := @CP850ToUTF8;\n          PlainConvert := @UTF8ToCP850;\n        end;\n      {$IFDEF LCONVENCODING_HAS_CP852_FUNCTIONS}\n      852: //CP852\n        begin\n          DbcConvert := @CP852ToUTF8;\n          PlainConvert := @UTF8ToCP852;\n        end;\n      {$ENDIF}\n      866: //CP866\n        begin\n          DbcConvert := @CP866ToUTF8;\n          PlainConvert := @UTF8ToCP866;\n        end;\n      874: //CP874\n        begin\n          DbcConvert := @CP874ToUTF8;\n          PlainConvert := @UTF8ToCP874;\n        end;\n      20866: //KOI8 (Russian)\n        begin\n          DbcConvert := @KOI8ToUTF8;\n          PlainConvert := @UTF8ToKOI8;\n        end\n      else\n        begin\n          DbcConvert := @NoConvert;\n          PlainConvert := @NoConvert;\n        end;\n    end;\n  end;\nend;\n{$ENDIF}\n\nfunction ZDefaultSystemCodePage: Word;\nbegin\n  {$IFDEF WITH_DEFAULTSYSTEMCODEPAGE}\n  Result := Word(DefaultSystemCodePage);\n  {$ELSE}\n    {$IFDEF MSWINDOWS}\n    Result := GetACP; //available for Windows and WinCE\n    {$ELSE}\n    Result := zCP_UTF8; //how to determine the current OS CP?\n    {$ENDIF}\n  {$ENDIF}\nend;\n\n{**\n  Is the codepage equal or compatible?\n  @param CP1 word the first codepage to compare\n  @param CP2 word the second codepage to compare\n  @returns Boolean True if codepage is equal or compatible\n}\nfunction ZCompatibleCodePages(const CP1, CP2: Word): Boolean;\nbegin\n  Result := (CP1 = CP2) or (CP1 = zCP_us_ascii) or (CP2 = zCP_us_ascii);\nend;\n\n{$IFDEF FPC}\n  {$HINTS OFF}\n{$ENDIF}\nfunction TestEncoding(const Bytes: TByteDynArray; const Size: Cardinal;\n  const ConSettings: PZConSettings): TZCharEncoding;\nbegin\n  Result := ceDefault;\n  {EgonHugeist:\n    Step one: Findout, wat's comming in! To avoid User-Bugs as good as possible\n      it is possible that a PAnsiChar OR a PWideChar was written into\n      the Stream!!!  And these chars could be trunced with changing the\n      Stream.Size.\n      I know this can lead to pain with two byte ansi chars, but what else can i do?\n    step two: detect the encoding }\n\n  if ( {$IFDEF WITH_STRLEN_DEPRECATED}AnsiStrings.{$ENDIF}StrLen(PAnsiChar(Bytes)) < Size ) then //Sure PWideChar written!! A #0 was in the byte-sequence!\n    result := ceUTF16\n  else\n    if ConSettings.AutoEncode then\n      case DetectUTF8Encoding(PAnsichar(Bytes)) of\n        etUSASCII: Result := ceDefault; //Exact!\n        etAnsi:\n          { Sure this isn't right in all cases!\n            Two/four byte WideChars causing the same result!\n            Leads to pain! Is there a way to get a better test?\n            I've to start from the premise the function which calls this func\n            should decide wether ansi or unicode}\n          Result := ceAnsi;\n        etUTF8: Result := ceUTF8; //Exact!\n      end\n    else\n      Result := ceDefault\nend;\n{$IFDEF FPC}\n  {$HINTS ON}\n{$ENDIF}\n\nfunction ZConvertAnsiToRaw(const Src: AnsiString; const RawCP: Word): RawByteString;\nvar US: ZWideString; //COM based. So localize the String to avoid Buffer overrun\nbegin\n  if Src = '' then\n    Result := ''\n  else\n  begin\n    US := ZWideString(Src);\n    Result := ZUnicodeToRaw(US, RawCP);\n  end;\nend;\n\nfunction ZConvertRawToAnsi(const Src: RawByteString; const RawCP: Word): AnsiString;\nvar US: ZWideString; //COM based. So localize the String to avoid Buffer overrun\nbegin\n  if Src = '' then\n    Result := ''\n  else\n  begin\n    US := ZRawToUnicode(Src, RawCP);\n    Result := AnsiString(US); //use compiler convertation\n  end;\nend;\n\nfunction ZConvertAnsiToUTF8(const Src: AnsiString): UTF8String;\nvar US: ZWideString; //COM based. So localize the String to avoid Buffer overrun\nbegin\n  if Src = '' then\n    Result := ''\n  else\n  begin\n    US := ZWideString(Src);\n    Result := {$IFDEF WITH_RAWBYTESTRING}UTF8String{$ELSE}UTF8Encode{$ENDIF}(US);\n  end;\nend;\n\nfunction ZConvertUTF8ToAnsi(const Src: UTF8String): AnsiString;\nvar US: ZWideString; //COM based. So localize the String to avoid Buffer overrun\nbegin\n  if Src = '' then\n    Result := ''\n  else\n  begin\n    US := {$IFDEF WITH_RAWBYTESTRING}ZWideString{$ELSE}UTF8Decode{$ENDIF}(Src);\n    Result := AnsiString(US);\n  end;\nend;\n\nfunction ZConvertRawToUTF8(const Src: RawByteString; const CP: Word): UTF8String;\nvar\n  {$IFDEF WITH_LCONVENCODING}\n  sUTF8: String;\n  {$ELSE}\n  US: ZWideString; //COM based. So localize the String to avoid Buffer overrun\n  {$ENDIF}\nbegin\n  if Src = '' then\n    Result := ''\n  else\n  begin\n    {$IFDEF WITH_LCONVENCODING}\n    Result := '';\n    case CP of\n      28591: //ISO_8859_1\n        sUTF8 := ISO_8859_1ToUTF8(PAnsiChar(Src));\n      28592:  //ISO_8859_2\n        sUTF8 := ISO_8859_2ToUTF8(PAnsiChar(Src));\n      1250: //WIN1250\n        sUTF8 := CP1250ToUTF8(PAnsiChar(Src));\n      1251: //WIN1251\n        sUTF8 := CP1251ToUTF8(PAnsiChar(Src));\n      1252: //WIN1252\n        sUTF8 := CP1252ToUTF8(PAnsiChar(Src));\n      1253: //WIN1253\n        sUTF8 := CP1253ToUTF8(PAnsiChar(Src));\n      1254: //WIN1254\n        sUTF8 := CP1254ToUTF8(PAnsiChar(Src));\n      1255: //WIN1255\n        sUTF8 := CP1255ToUTF8(PAnsiChar(Src));\n      1256: //WIN1256\n        sUTF8 := CP1256ToUTF8(PAnsiChar(Src));\n      1257: //WIN1257\n        sUTF8 := CP1257ToUTF8(PAnsiChar(Src));\n      1258: //WIN1258\n        sUTF8 := CP1258ToUTF8(PAnsiChar(Src));\n      437: //CP437\n        sUTF8 := CP437ToUTF8(PAnsiChar(Src));\n      850: //CP850\n        sUTF8 := CP850ToUTF8(PAnsiChar(Src));\n      852: //CP852\n        sUTF8 := CP852ToUTF8(PAnsiChar(Src));\n      866: //CP866\n        sUTF8 := CP866ToUTF8(PAnsiChar(Src));\n      874: //CP874\n        sUTF8 := CP874ToUTF8(PAnsiChar(Src));\n      20866: //KOI8 (Russian)\n        sUTF8 := KOI8ToUTF8(PAnsiChar(Src));\n      65001: //utf8\n        sUTF8 := PAnsiChar(Src);\n      else\n        sUTF8 := PAnsiChar(Src);\n    end;\n    ZSetString(PAnsichar(sUTF8), Result);\n  {$ELSE}\n    US := ZRawToUnicode(Src, CP);\n    Result := {$IFDEF WITH_RAWBYTESTRING}UTF8String{$ELSE}UTF8Encode{$ENDIF}(US);\n  {$ENDIF}\n  end;\nend;\n\nfunction ZConvertUTF8ToRaw(Const Src: UTF8String; const CP: Word): RawByteString;\nvar\n  {$IFDEF WITH_LCONVENCODING}\n  sUTF8: String;\n  {$ELSE}\n  US: ZWideString; //COM based. So localize the String to avoid Buffer overrun\n  {$ENDIF}\nbegin\n  if Src = '' then\n    Result := ''\n  else\n  begin\n  {$IFDEF WITH_LCONVENCODING}\n    case CP of\n      28591: //ISO_8859_1\n        sUTF8 := UTF8ToISO_8859_1(PAnsiChar(Src));\n      28592:  //ISO_8859_2\n        sUTF8 := UTF8ToISO_8859_2(PAnsiChar(Src));\n      1250: //WIN1250\n        sUTF8 := UTF8ToCP1250(PAnsiChar(Src));\n      1251: //WIN1251\n        sUTF8 := UTF8ToCP1251(PAnsiChar(Src));\n      1252: //WIN1252\n        sUTF8 := UTF8ToCP1252(PAnsiChar(Src));\n      1253: //WIN1253\n        sUTF8 := UTF8ToCP1253(PAnsiChar(Src));\n      1254: //WIN1254\n        sUTF8 := UTF8ToCP1254(PAnsiChar(Src));\n      1255: //WIN1255\n        sUTF8 := UTF8ToCP1255(PAnsiChar(Src));\n      1256: //WIN1256\n        sUTF8 := UTF8ToCP1256(PAnsiChar(Src));\n      1257: //WIN1257\n        sUTF8 := UTF8ToCP1257(PAnsiChar(Src));\n      1258: //WIN1258\n        sUTF8 := UTF8ToCP1258(PAnsiChar(Src));\n      437: //CP437\n        sUTF8 := UTF8ToCP437(PAnsiChar(Src));\n      850: //CP850\n        sUTF8 := UTF8ToCP850(PAnsiChar(Src));\n      852: //CP852\n        sUTF8 := UTF8ToCP852(PAnsiChar(Src));\n      866: //CP866\n        sUTF8 := UTF8ToCP866(PAnsiChar(Src));\n      874: //CP874\n        sUTF8 := UTF8ToCP874(PAnsiChar(Src));\n      20866: //KOI8 (Russian)\n        sUTF8 := UTF8ToKOI8(PAnsiChar(Src));\n      65001: //UTF8\n        sUTF8 := PAnsiChar(Src);\n      else\n        sUTF8 := PAnsiChar(Src);\n    end;\n    Result := ''; //Makes compler happy\n    ZSetString(PAnsiChar(sUTF8), Result);\n  {$ELSE}\n    US := UTF8ToString(PAnsiChar(Src));\n    Result := ZUnicodeToRaw(US, CP);\n  {$ENDIF}\n  end;\nend;\n\n{$IFDEF FPC}\n  {$HINTS OFF}\n{$ENDIF}\nfunction ZConvertRawToString(const Src: RawByteString;\n  const RawCP, StringCP: Word): String;\n{$IFNDEF UNICODE}\nvar\n  {$IFDEF WITH_LCONVENCODING}\n  sUTF8: String;\n  {$ELSE}\n  US: ZWideString; //COM based. So localize the String to avoid Buffer overrun\n  {$ENDIF}\n{$ENDIF}\nbegin\n  if Src = '' then\n    Result := ''\n  else\n  begin\n    {$IFDEF WITH_LCONVENCODING}\n    sUTF8 := ''; //Makes Compiler happy\n    ZSetString(PAnsichar(Src), sUTF8);\n    case RawCP of\n      28591: //ISO_8859_1\n        Result := ISO_8859_1ToUTF8(PAnsiChar(sUTF8));\n      28592:  //ISO_8859_2\n        Result := ISO_8859_2ToUTF8(PAnsiChar(sUTF8));\n      1250: //WIN1250\n        Result := CP1250ToUTF8(PAnsiChar(sUTF8));\n      1251: //WIN1251\n        Result := CP1251ToUTF8(PAnsiChar(sUTF8));\n      1252: //WIN1252\n        Result := CP1252ToUTF8(PAnsiChar(sUTF8));\n      1253: //WIN1253\n        Result := CP1253ToUTF8(PAnsiChar(sUTF8));\n      1254: //WIN1254\n        Result := CP1254ToUTF8(PAnsiChar(sUTF8));\n      1255: //WIN1255\n        Result := CP1255ToUTF8(PAnsiChar(sUTF8));\n      1256: //WIN1256\n        Result := CP1256ToUTF8(PAnsiChar(sUTF8));\n      1257: //WIN1257\n        Result := CP1257ToUTF8(PAnsiChar(sUTF8));\n      1258: //WIN1258\n        Result := CP1258ToUTF8(PAnsiChar(sUTF8));\n      437: //CP437\n        Result := CP437ToUTF8(PAnsiChar(sUTF8));\n      850: //CP850\n        Result := CP850ToUTF8(PAnsiChar(sUTF8));\n      {$IFDEF LCONVENCODING_HAS_CP852_FUNCTIONS}\n      852: //CP852\n        Result := CP852ToUTF8(PAnsiChar(sUTF8));\n      {$ENDIF}\n      866: //CP866\n        Result := CP866ToUTF8(PAnsiChar(sUTF8));\n      874: //CP874\n        Result := CP874ToUTF8(PAnsiChar(sUTF8));\n      20866: //KOI8 (Russian)\n        Result := KOI8ToUTF8(PAnsiChar(sUTF8));\n      65001: //utf8\n        Result := PAnsiChar(sUTF8);\n      else\n        Result := PAnsiChar(sUTF8);\n    end;\n  {$ELSE}\n    {$IFDEF UNICODE}\n    Result := ZRawToUnicode(Src, RawCP);\n    {$ELSE}\n    US := ZRawToUnicode(Src, RawCP);\n    ZSetString(PAnsiChar(ZUnicodeToRaw(US, StringCP)), Result);\n    {$ENDIF}\n  {$ENDIF}\n  end;\nend;\n\nfunction ZConvertStringToRaw(const Src: String; const StringCP, RawCP: Word): RawByteString;\n{$IFNDEF UNICODE}\nvar\n  {$IFDEF WITH_LCONVENCODING}\n  sUTF8: String;\n  {$ELSE}\n  US: ZWideString; //COM based, so let's localize the value to avoid Buffer overrun\n  {$ENDIF}\n{$ENDIF}\nbegin\n  if Src = '' then\n    Result := ''\n  else\n  {$IFDEF WITH_LCONVENCODING}\n  begin\n    case RawCP of\n      28591: //ISO_8859_1\n        sUTF8 := UTF8ToISO_8859_1(Src);\n      28592:  //ISO_8859_2\n        sUTF8 := UTF8ToISO_8859_2(Src);\n      1250: //WIN1250\n        sUTF8 := UTF8ToCP1250(Src);\n      1251: //WIN1251\n        sUTF8 := UTF8ToCP1251(Src);\n      1252: //WIN1252\n        sUTF8 := UTF8ToCP1252(Src);\n      1253: //WIN1253\n        sUTF8 := UTF8ToCP1253(Src);\n      1254: //WIN1254\n        sUTF8 := UTF8ToCP1254(Src);\n      1255: //WIN1255\n        sUTF8 := UTF8ToCP1255(Src);\n      1256: //WIN1256\n        sUTF8 := UTF8ToCP1256(Src);\n      1257: //WIN1257\n        sUTF8 := UTF8ToCP1257(Src);\n      1258: //WIN1258\n        sUTF8 := UTF8ToCP1258(Src);\n      437: //CP437\n        sUTF8 := UTF8ToCP437(Src);\n      850: //CP850\n        sUTF8 := UTF8ToCP850(Src);\n      {$IFDEF LCONVENCODING_HAS_CP852_FUNCTIONS}\n      852: //CP852\n        sUTF8 := UTF8ToCP852(Src);\n      {$ENDIF}\n      866: //CP866\n        sUTF8 := UTF8ToCP866(Src);\n      874: //CP874\n        sUTF8 := UTF8ToCP874(Src);\n      20866: //KOI8 (Russian)\n        sUTF8 := UTF8ToKOI8(Src);\n      65001: //UTF8\n        sUTF8 := Src;\n      else\n        sUTF8 := Src;\n    end;\n    Result := ''; //Makes compler happy\n    ZSetString(PAnsiChar(sUTF8), Result);\n  end;\n  {$ELSE}\n    {$IFDEF UNICODE}\n    Result := ZUnicodeToRaw(Src, RawCP);\n    {$ELSE}\n    begin\n      US := ZRawToUnicode(Src, StringCP);\n      Result := ZUnicodeToRaw(US, RawCP);\n    end;\n    {$ENDIF}\n  {$ENDIF}\nend;\n{$IFDEF FPC}\n  {$HINTS ON}\n{$ENDIF}\n\n{$WARNINGS OFF}\nfunction ZConvertStringToRawWithAutoEncode(const Src: String;\n  const StringCP, RawCP: Word): RawByteString;\nbegin\n  {$IFDEF UNICODE}\n  Result := ZUnicodeToRaw(Src, RawCP);\n  {$ELSE}\n  Result := ''; //init for FPC\n  case DetectUTF8Encoding(Src) of\n    etUSASCII: ZSetString(PAnsiChar(Src), Result);\n    etAnsi:\n      if (RawCP = zCP_UTF8) then\n        if ZCompatibleCodePages(StringCP, zCP_UTF8 ) then\n          Result := ZUnicodeToRaw(ZWideString(Src), RawCP) //Random success unknown String CP\n        else\n          Result := ZConvertStringToRaw(Src, StringCP, RawCP)\n      else\n        ZSetString(PAnsiChar(Src), Result);\n    etUTF8:\n      if (RawCP = zCP_UTF8) then\n        ZSetString(PAnsiChar(Src), Result)\n      else\n        Result := ZConvertStringToRaw(Src, zCP_UTF8, RawCP);\n  end;\n  {$ENDIF}\nend;\n{$WARNINGS ON}\n\nfunction ZConvertUTF8ToString(const Src: UTF8String;\n  const StringCP: Word): String;\n{$IFNDEF UNICODE}\nvar\n  US: ZWideString; //COM based. Localize the Value to avoid buffer overrun\n  S: RawByteString;\n{$ENDIF}\nbegin\n  if Src = '' then\n    Result := ''\n  else\n    {$IFDEF UNICODE}\n    Result := UTF8ToString(PAnsiChar(Src));\n    {$ELSE}\n    begin\n      Result := ''; //Makes Compiler happy\n      US := UTF8ToString(PAnsiChar(Src));\n      S := ZUnicodeToRaw(US, StringCP);\n      ZSetString(PAnsiChar(S), Result);\n    end;\n    {$ENDIF}\nend;\n\nfunction ZConvertStringToUTF8(const Src: String;\n  const StringCP: Word): UTF8String;\n{$IFNDEF UNICODE}\nvar\n  US: ZWideString; //COM based. Localize the Value to avoid buffer overrun\n{$ENDIF}\nbegin\n  if Src = '' then\n    Result := ''\n  else\n    {$IFDEF UNICODE}\n    Result := UTF8String(Src);\n    {$ELSE}\n    begin\n      US := ZRawToUnicode(Src, StringCP);\n      {$IFDEF WITH_RAWBYTESTRING}\n      Result := UTF8String(US);\n      {$ELSE}\n      Result := UTF8Encode(US);\n      {$ENDIF}\n    end;\n    {$ENDIF}\nend;\n\nfunction ZConvertStringToUTF8WithAutoEncode(const Src: String;\n  const StringCP: Word): UTF8String;\n{$IFNDEF UNICODE}\nvar Tmp: ZWideString; //COM based. Localize the Value to avoid buffer overrun\n{$ENDIF}\nbegin\n  {$IFDEF UNICODE}\n  Result := UTF8String(Src);\n  {$ELSE}\n  Result := '';\n  If DetectUTF8Encoding(PAnsiChar(Src)) in [etUSASCII, etUTF8] then\n    ZSetString(PAnsiChar(Src), Result)\n  else //Ansi\n  begin\n    if ZCompatibleCodePages(StringCP, zCP_UTF8)  then\n      Tmp := ZWideString(Src)\n    else\n      Tmp := ZRawToUnicode(PAnsiChar(Src), StringCP);\n    {$IFDEF WITH_RAWBYTESTRING}\n    Result := UTF8String(Tmp);\n    {$ELSE}\n    Result := UTF8Encode(Tmp);\n    {$ENDIF}\n  end;\n  {$ENDIF}\nend;\n\nfunction ZConvertStringToAnsi(const Src: String;\n  const StringCP: Word): AnsiString;\n{$IFNDEF UNICODE}\nvar Tmp: ZWideString; //COM based. Localize the Value to avoid buffer overrun\n{$ENDIF}\nbegin\n  {$IFDEF UNICODE}\n  Result := AnsiString(Src);\n  {$ELSE}\n  Tmp := ZRawToUnicode(PAnsiChar(Src), StringCP);\n  Result := AnsiString(Tmp);\n  {$ENDIF}\nend;\n\n{$IFDEF FPC}\n  {$HINTS OFF}\n{$ENDIF}\nfunction ZConvertStringToAnsiWithAutoEncode(const Src: String;\n  const StringCP: Word): AnsiString;\n{$IFNDEF UNICODE}\nvar Tmp: ZWideString; //COM based. Localize the Value to avoid buffer overrun\n{$ENDIF}\nbegin\n  {$IFDEF UNICODE}\n  Result := AnsiString(Src);\n  {$ELSE}\n  Result := '';\n  If DetectUTF8Encoding(PAnsiChar(Src)) in [etUSASCII, etAnsi] then\n    ZSetString(PAnsiChar(Src), Result)\n  else\n  begin\n    Tmp := UTF8ToString(PAnsiChar(Src));\n    Result := AnsiString(Tmp);\n  end;\n  {$ENDIF}\nend;\n{$IFDEF FPC}\n  {$HINTS ON}\n{$ENDIF}\n\nfunction ZConvertAnsiToString(const Src: AnsiString;\n  const StringCP: Word): String;\n{$IFNDEF UNICODE}\nvar Tmp: ZWideString; //COM based. Localize the Value to avoid buffer overrun\n{$ENDIF}\nbegin\n  {$IFDEF UNICODE}\n  Result := String(Src);\n  {$ELSE}\n  Result := '';\n  Tmp := ZRawToUnicode(PAnsiChar(Src), ZDefaultSystemCodePage);\n  ZSetString(PAnsiChar(ZUnicodeToRaw(Tmp, StringCP)), Result);\n  {$ENDIF}\nend;\n\nfunction ZConvertUnicodeToString(const Src: ZWideString;\n  const StringCP: Word): String;\n{$IFNDEF UNICODE}\nvar Tmp: RawByteString;\n{$ENDIF}\nbegin\n  {$IFDEF UNICODE}\n  Result := Src;\n  {$ELSE}\n  Tmp := ZUnicodeToRaw(Src, StringCP);\n  ZSetString(PAnsiChar(Tmp), Result);\n  {$ENDIF}\nend;\n\n{$IFDEF FPC}\n  {$HINTS OFF}\n{$ENDIF}\nfunction ZConvertUnicodeToString_CPUTF8(const Src: ZWideString;\n  const StringCP: Word): String;\n{$IFNDEF UNICODE}\nvar Tmp: RawByteString;\n{$ENDIF}\nbegin\n  {$IFDEF UNICODE}\n  Result := Src;\n  {$ELSE}\n  Tmp := UTF8Encode(Src);\n  ZSetString(PAnsiChar(Tmp), Result);\n  {$ENDIF}\nend;\n{$IFDEF FPC}\n  {$HINTS ON}\n{$ENDIF}\n\nfunction ZConvertStringToUnicode(const Src: String;\n  const StringCP: Word): ZWideString;\n{$IFNDEF UNICODE}\nvar Tmp: RawByteString;\n{$ENDIF}\nbegin\n  {$IFDEF UNICODE}\n  Result := Src;\n  {$ELSE}\n  Tmp := ''; //Makes compiler Happy\n  ZSetString(PAnsiChar(Src), Tmp);\n  Result := ZRawToUnicode(Tmp, StringCP);\n  {$ENDIF}\nend;\n\n{$IFDEF FPC}\n  {$HINTS OFF}\n{$ENDIF}\nfunction ZConvertString_CPUTF8ToUnicode(const Src: String;\n  const StringCP: Word): ZWideString;\n{$IFNDEF UNICODE}\nvar Tmp: RawByteString;\n{$ENDIF}\nbegin\n  {$IFDEF UNICODE}\n  Result := Src;\n  {$ELSE}\n  Tmp := ''; //Makes Compiler happy\n  ZSetString(PAnsiChar(Src), Tmp);\n  Result := UTF8ToString(Tmp);\n  {$ENDIF}\nend;\n{$IFDEF FPC}\n  {$HINTS ON}\n{$ENDIF}\n\n\nfunction ZConvertStringToUnicodeWithAutoEncode(const Src: String;\n  const StringCP: Word): ZWideString;\nbegin\n  {$IFDEF UNICODE}\n  Result := Src;\n  {$ELSE}\n  If DetectUTF8Encoding(PAnsiChar(Src)) in [etUSASCII, etUTF8] then\n    Result := UTF8ToString(PAnsiChar(Src))\n  else\n    if ZCompatibleCodePages(StringCP, zCP_UTF8)  then\n      Result := ZWideString(Src)\n    else\n      Result := ZRawToUnicode(PAnsiChar(Src), StringCP);\n  {$ENDIF}\nend;\n\n\n{$IFDEF FPC}\n  {$HINTS OFF}\n{$ENDIF}\nfunction ZMoveAnsiToRaw(const Src: AnsiString; const RawCP: Word): RawByteString;\nbegin\n  ZSetString(PAnsiChar(Src), Result);\nend;\n\nfunction ZMoveRawToAnsi(const Src: RawByteString; const RawCP: Word): AnsiString;\nbegin\n  ZSetString(PAnsiChar(Src), Result);\nend;\n\nfunction ZMoveAnsiToUTF8(const Src: AnsiString): UTF8String;\nbegin\n  ZSetString(PAnsiChar(Src), Result);\nend;\n\nfunction ZMoveUTF8ToAnsi(const Src: UTF8String): AnsiString;\nbegin\n  ZSetString(PAnsiChar(Src), Result);\nend;\n\nfunction ZMoveRawToUTF8(const Src: RawByteString; const CP: Word): UTF8String;\nbegin\n  ZSetString(PAnsiChar(Src), Result);\nend;\n\nfunction ZMoveUTF8ToRaw(Const Src: UTF8String; const CP: Word): RawByteString;\nbegin\n  ZSetString(PAnsiChar(Src), Result);\nend;\n\nfunction ZMoveStringToAnsi(Const Src: String; const StringCP: Word): AnsiString;\nbegin\n  {$IFDEF UNICODE}\n  Result := AnsiString(Src);\n  {$ELSE}\n  ZSetString(PAnsiChar(Src), Result);\n  {$ENDIF}\nend;\n\nfunction ZMoveAnsiToString(const Src: AnsiString; const StringCP: Word): String;\nbegin\n  {$IFDEF UNICODE}\n  Result := String(Src);\n  {$ELSE}\n  ZSetString(PAnsiChar(Src), Result);\n  {$ENDIF}\nend;\n\n\nfunction ZMoveRawToString(const Src: RawByteString;\n  const RawCP, StringCP: Word): String;\nbegin\n  {$IFDEF UNICODE}\n  Result := ZRawToUnicode(Src, RawCP);\n  {$ELSE}\n  ZSetString(PAnsiChar(Src), Result);\n  {$ENDIF}\nend;\n\nfunction ZMoveStringToRaw(const Src: String;\n  const StringCP, RawCP: Word): RawByteString;\nbegin\n  {$IFDEF UNICODE}\n  Result := ZUnicodeToRaw(Src, RawCP);\n  {$ELSE}\n  ZSetString(PAnsiChar(Src), Result);\n  {$ENDIF}\nend;\n\nfunction ZMoveUTF8ToString(const Src: UTF8String; StringCP: Word): String;\nbegin\n  {$IFDEF UNICODE}\n  Result := String(Src);\n  {$ELSE}\n  ZSetString(PAnsiChar(Src), Result);\n  {$ENDIF}\nend;\n\nfunction ZMoveStringToUTF8(const Src: String; const StringCP: Word): UTF8String;\nbegin\n  {$IFDEF UNICODE}\n  Result := UTF8String(Src);\n  {$ELSE}\n  ZSetString(PAnsiChar(Src), Result);\n  {$ENDIF}\nend;\n\n{$IFDEF FPC}\n  {$HINTS ON}\n{$ENDIF}\n\n{**\n  GetValidatedTextStream the incoming Stream for his given Memory and\n  returns a valid UTF8/Ansi StringStream\n  @param Stream the Stream with the unknown format and data\n  @return a valid utf8 encoded stringstram\n}\n{$WARNINGS OFF}\nfunction GetValidatedAnsiStringFromBuffer(const Buffer: Pointer; Size: Cardinal;\n  ConSettings: PZConSettings): RawByteString;\nvar\n  US: ZWideString;\n  Bytes: TByteDynArray;\nbegin\n  if Size = 0 then\n    Result := ''\n  else\n  begin\n    SetLength(Bytes, Size +2);\n    System.move(Buffer^, Pointer(Bytes)^, Size);\n    case TestEncoding(Bytes, Size, ConSettings) of\n      ceDefault: Result := PAnsiChar(Bytes);\n      ceAnsi:\n        if ConSettings.ClientCodePage.Encoding = ceAnsi then\n          if ( ConSettings.CTRL_CP = zCP_UTF8) or (ConSettings.CTRL_CP = ConSettings.ClientCodePage.CP) then //second test avoids encode the string twice\n            Result := PAnsiChar(Bytes)  //should be exact\n          else\n            {$IFDEF WITH_LCONVENCODING}\n            Result := Consettings.PlainConvertFunc(AnsiToUTF8(PAnsiChar(Bytes)))  //no other possibility\n            {$ELSE}\n            Result := ZUnicodeToRaw(ZRawToUnicode(PAnsiChar(Bytes), ConSettings.CTRL_CP), ConSettings.ClientCodePage.CP)\n            {$ENDIF}\n        else  //Database expects UTF8\n          if ( ConSettings.CTRL_CP = zCP_UTF8) then\n            Result := AnsiToUTF8(String(PAnsiChar(Bytes))) //Can't localize the ansi CP\n          else\n            {$IFDEF WITH_LCONVENCODING}\n            Result := AnsiToUTF8(PAnsiChar(Bytes));\n            {$ELSE}\n            Result := UTF8Encode(ZRawToUnicode(PAnsiChar(Bytes), ConSettings.CTRL_CP));\n            {$ENDIF}\n      ceUTF8:\n        if ConSettings.ClientCodePage.Encoding = ceAnsi then //ansi expected\n          {$IFDEF WITH_LCONVENCODING}\n          Result := Consettings.PlainConvertFunc(String(PAnsiChar(Bytes)))\n          {$ELSE}\n          Result := ZUnicodeToRaw(UTF8ToString(PAnsiChar(Bytes)), ConSettings.ClientCodePage.CP)\n          {$ENDIF}\n         else //UTF8 Expected\n           Result := PAnsiChar(Bytes);\n      ceUTF16:\n        begin\n          SetLength(US, Size div 2);\n          System.Move(PWideChar(Bytes)^, PWideChar(US)^, Size);\n          if ConSettings.ClientCodePage.Encoding = ceAnsi then\n            {$IFDEF WITH_LCONVENCODING}\n            Result := Consettings.PlainConvertFunc(UTF8Encode(US))\n            {$ELSE}\n            Result := ZUnicodeToRaw(US, ConSettings.ClientCodePage.CP)\n            {$ENDIF}\n          else\n            Result := UTF8Encode(US);\n        end;\n      else\n        Result := '';\n    end;\n  end;\nend;\n{$WARNINGS ON}\n\nfunction GetValidatedAnsiStringFromBuffer(const Buffer: Pointer; Size: Cardinal;\n  ConSettings: PZConSettings; ToCP: Word): RawByteString;\nvar DB_CP: Word;\nbegin\n  DB_CP := ConSettings.ClientCodePage.CP;\n  ConSettings.ClientCodePage.CP := ToCP;\n  Result := GetValidatedAnsiStringFromBuffer(Buffer, Size, ConSettings);\n  ConSettings.ClientCodePage.CP := DB_CP;\nend;\n\nfunction GetValidatedAnsiString(const Ansi: RawByteString;\n  ConSettings: PZConSettings; const FromDB: Boolean): RawByteString;\nbegin\n  if FromDB then\n    if ( ConSettings.CTRL_CP = ConSettings.ClientCodePage.CP ) or not ConSettings.AutoEncode then\n      Result := Ansi\n    else\n      {$IFDEF WITH_LCONVENCODING}\n      Result := Consettings.DbcConvertFunc(Ansi)\n      {$ELSE}\n      Result := ZUnicodeToRaw(ZRawToUnicode(Ansi, ConSettings^.ClientCodePage^.CP), ConSettings^.CTRL_CP)\n      {$ENDIF}\n  else\n    Result := ''; // not done yet  and not needed. Makes the compiler happy\nend;\n\nfunction GetValidatedAnsiString(const Uni: ZWideString;\n  ConSettings: PZConSettings; const FromDB: Boolean): RawByteString;\nbegin\n  if FromDB then\n    {$IFDEF WITH_LCONVENCODING}\n    Result := UTF8Encode(Uni)\n    {$ELSE}\n    Result := ZUnicodeToRaw(Uni, ConSettings^.CTRL_CP)\n    {$ENDIF}\n  else\n    Result := ''; // not done yet  and not needed. Makes the compiler happy\nend;\n\nfunction GetValidatedAnsiStringFromBuffer(const Buffer: Pointer; Size: Cardinal;\n  WasDecoded: Boolean; ConSettings: PZConSettings): RawByteString;\nvar\n  US: ZWideString;\nbegin\n  if WasDecoded then\n  begin\n    SetLength(US, Size div 2);\n    System.Move(Buffer^, PWideChar(US)^, Size);\n    Result := ZUnicodeToRaw(US, ConSettings.ClientCodePage.CP);\n  end\n  else\n    Result := GetValidatedAnsiStringFromBuffer(Buffer, Size, ConSettings);\nend;\n{**\n  GetValidatedUnicodeStream the incoming Stream for his given Memory and\n  returns a valid Unicode/Widestring Stream\n  @param Stream the Stream with the unknown format and data\n  @return a valid Unicode encoded stringstram\n}\nfunction GetValidatedUnicodeStream(const Buffer: Pointer; Size: Cardinal;\n  ConSettings: PZConSettings; FromDB: Boolean): TStream;\nvar\n  Len: Integer;\n  US: ZWideString;\n  Bytes: TByteDynArray;\n\n  procedure SetFromWide;\n  begin\n    SetLength(US, Size div 2);\n    System.Move(PWideChar(Bytes)^, PWideChar(US)^, Size);\n  end;\nbegin\n  Result := nil;\n  US := '';\n  if Assigned(Buffer) and ( Size > 0 ) then\n  begin\n    SetLength(Bytes, Size +2);\n    System.move(Buffer^, Pointer(Bytes)^, Size);\n    if FromDB then //do not check encoding twice\n      Result := GetValidatedUnicodeStream(PAnsiChar(Bytes), ConSettings, FromDB)\n    else\n      case TestEncoding(Bytes, Size, ConSettings) of\n        ceDefault:\n          case Consettings.ClientCodePage.Encoding of\n            ceUTF8: US := UTF8ToString(PAnsiChar(Bytes));\n            ceAnsi:\n              {$IFDEF WITH_LCONVENCODING}\n              US := ZWideString(PAnsiChar(Bytes)); //cast means random success\n              {$ELSE}\n              if ( ConSettings.CTRL_CP = zCP_UTF8) then\n                US := ZWideString(PAnsiChar(Bytes)) //random success\n              else\n                US := ZRawToUnicode(PAnsiChar(Bytes), ConSettings.CTRL_CP);\n             {$ENDIF}\n            end;\n        ceAnsi: //We've to start from the premisse we've got a Unicode string i there\n          begin\n            SetLength(US, Size div 2);\n            System.Move(PWideChar(Bytes)^, PWideChar(US)^, Size);\n          end;\n        ceUTF8: US := UTF8ToString(PAnsiChar(Bytes));\n        ceUTF16:\n          begin\n            SetLength(US, Size div 2);\n            System.Move(PWideChar(Bytes)^, PWideChar(US)^, Size);\n          end;\n      end;\n\n    Len := Length(US)*2;\n    if not Assigned(Result) and (Len > 0) then\n    begin\n      Result := TMemoryStream.Create;\n      Result.Size := Len;\n      System.Move(PWideChar(US)^, TMemoryStream(Result).Memory^, Len);\n      Result.Position := 0;\n    end;\n    SetLength(Bytes, 0);\n  end;\nend;\n\nfunction GetValidatedUnicodeStream(const Ansi: RawByteString;\n  ConSettings: PZConSettings; FromDB: Boolean): TStream;\nvar\n  Len: Integer;\n  US: ZWideString;\nbegin\n  Result := nil;\n  if Ansi <> '' then\n  begin\n    if FromDB then\n      {$IFDEF WITH_LCONVENCODING}\n      US := UTF8ToString(Consettings.DbcConvertFunc(Ansi))\n      {$ELSE}\n      US := ZRawToUnicode(Ansi, ConSettings.ClientCodePage.CP)\n      {$ENDIF}\n    else\n      case DetectUTF8Encoding(Ansi) of\n        etUSASCII, etUTF8: US := UTF8ToString(Ansi);\n        etAnsi:\n          {$IFDEF WITH_LCONVENCODING}\n          US := ZWideString(Ansi); //random success\n          {$ELSE}\n          if ( ConSettings.CTRL_CP = zCP_UTF8) then\n            US := ZWideString(Ansi) //random success\n          else\n            US := ZRawToUnicode(Ansi, ConSettings.CTRL_CP);\n         {$ENDIF}\n      end;\n\n    Len := Length(US)*2;\n    if Len > 0 then\n    begin\n      Result := TMemoryStream.Create;\n      Result.Size := Len;\n      System.Move(PWideChar(US)^, TMemoryStream(Result).Memory^, Len);\n      Result.Position := 0;\n    end;\n  end;\nend;\n\nprocedure SetConvertFunctions(ConSettings: PZConSettings);\nbegin\n  ConSettings^.ConvFuncs.ZAnsiToUTF8 := nil;\n  ConSettings^.ConvFuncs.ZUTF8ToAnsi:= nil;\n  ConSettings^.ConvFuncs.ZUTF8ToString:= nil;\n  ConSettings^.ConvFuncs.ZStringToUTF8:= nil;\n  ConSettings^.ConvFuncs.ZAnsiToRaw:= nil;\n  ConSettings^.ConvFuncs.ZRawToAnsi:= nil;\n  ConSettings^.ConvFuncs.ZRawToUTF8:= nil;\n  ConSettings^.ConvFuncs.ZUTF8ToRaw:= nil;\n  ConSettings^.ConvFuncs.ZStringToRaw:= nil;\n  ConSettings^.ConvFuncs.ZAnsiToString := nil;\n  ConSettings^.ConvFuncs.ZStringToAnsi := nil;\n  ConSettings^.ConvFuncs.ZRawToString:= nil;\n  ConSettings^.ConvFuncs.ZUnicodeToRaw:= nil;\n  ConSettings^.ConvFuncs.ZRawToUnicode:= nil;\n  ConSettings^.ConvFuncs.ZUnicodeToString:= nil;\n  ConSettings^.ConvFuncs.ZStringToUnicode:= nil;\n\n  //Let's start with the AnsiTo/From types..\n  // Ansi to/from UTF8String\n  if ZCompatibleCodePages(ZDefaultSystemCodePage, zCP_UTF8) then\n  begin\n    ConSettings^.ConvFuncs.ZAnsiToUTF8 := @ZMoveAnsiToUTF8;\n    ConSettings^.ConvFuncs.ZUTF8ToAnsi := @ZMoveUTF8ToAnsi;\n  end\n  else\n  begin\n    ConSettings^.ConvFuncs.ZAnsiToUTF8 := @ZConvertAnsiToUTF8;\n    ConSettings^.ConvFuncs.ZUTF8ToAnsi := @ZConvertUTF8ToAnsi;\n  end;\n\n  // Ansi to/from String\n  if ZCompatibleCodePages(ZDefaultSystemCodePage, ConSettings^.CTRL_CP) then\n  begin\n    ConSettings^.ConvFuncs.ZAnsiToString := @ZMoveAnsiToString;\n    if ConSettings^.AutoEncode then\n      ConSettings^.ConvFuncs.ZStringToAnsi := @ZConvertStringToAnsiWithAutoEncode\n    else\n      ConSettings^.ConvFuncs.ZStringToAnsi := @ZMoveStringToAnsi;\n  end\n  else\n  begin\n    ConSettings^.ConvFuncs.ZAnsiToString := @ZConvertAnsiToString;\n    if ConSettings^.AutoEncode then\n      ConSettings^.ConvFuncs.ZStringToAnsi := @ZConvertStringToAnsiWithAutoEncode\n    else\n      ConSettings^.ConvFuncs.ZStringToAnsi := @ZConvertStringToAnsi;\n  end;\n\n  if ConSettings^.ClientCodePage^.IsStringFieldCPConsistent then\n  begin\n    // raw to/from UTF8\n    if ZCompatibleCodePages(ConSettings^.ClientCodePage^.CP, zCP_UTF8) then\n    begin\n      ConSettings^.ConvFuncs.ZRawToUTF8 := @ZMoveRawToUTF8;\n      ConSettings^.ConvFuncs.ZUTF8ToRaw := @ZMoveUTF8ToRaw;\n    end\n    else\n    begin\n      ConSettings^.ConvFuncs.ZRawToUTF8 := @ZConvertRawToUTF8;\n      ConSettings^.ConvFuncs.ZUTF8ToRaw := @ZConvertUTF8ToRaw;\n    end;\n\n    // raw to/from ansi\n    if ZCompatibleCodePages(ConSettings^.ClientCodePage^.CP, ZDefaultSystemCodePage) then\n    begin\n      ConSettings^.ConvFuncs.ZAnsiToRaw := @ZMoveAnsiToRaw;\n      ConSettings^.ConvFuncs.ZRawToAnsi := @ZMoveRawToAnsi;\n    end\n    else\n    begin\n      ConSettings^.ConvFuncs.ZAnsiToRaw := @ZConvertAnsiToRaw;\n      ConSettings^.ConvFuncs.ZRawToAnsi := @ZConvertRawToAnsi;\n    end;\n\n    // raw to/from unicode\n    if ConSettings^.ClientCodePage^.CP = zCP_NONE then\n    begin\n      if ConSettings^.AutoEncode then\n        ConSettings^.ConvFuncs.ZRawToUnicode := @ZUnknownRawToUnicodeWithAutoEncode\n      else\n        ConSettings^.ConvFuncs.ZRawToUnicode := @ZUnknownRawToUnicode;\n      ConSettings^.ConvFuncs.ZUnicodeToRaw := @ZUnicodeToUnknownRaw;\n    end\n    else\n    begin\n      ConSettings^.ConvFuncs.ZRawToUnicode := @ZRawToUnicode;\n      ConSettings^.ConvFuncs.ZUnicodeToRaw := @ZUnicodeToRaw;\n    end;\n\n    //last but not least the String to/from converters\n    //string represents the DataSet/IZResultSet Strings\n    if ZCompatibleCodePages(ConSettings^.CTRL_CP, zCP_UTF8) then\n    begin\n      ConSettings^.ConvFuncs.ZUTF8ToString := @ZMoveUTF8ToString;\n      if ConSettings^.AutoEncode then\n        ConSettings^.ConvFuncs.ZStringToUTF8 := @ZConvertStringToUTF8WithAutoEncode\n      else\n        ConSettings^.ConvFuncs.ZStringToUTF8 := @ZMoveStringToUTF8;\n    end\n    else\n    begin\n      ConSettings^.ConvFuncs.ZUTF8ToString := @ZConvertUTF8ToString;\n      if ConSettings^.AutoEncode then\n        ConSettings^.ConvFuncs.ZStringToUTF8 := @ZConvertStringToUTF8WithAutoEncode\n      else\n        ConSettings^.ConvFuncs.ZStringToUTF8 := @ZConvertStringToUTF8\n    end;\n\n    {$IFDEF UNICODE}\n    Consettings^.ConvFuncs.ZStringToRaw := @ZConvertStringToRaw;\n    Consettings^.ConvFuncs.ZRawToString := @ZConvertRawToString;\n\n    ConSettings^.ConvFuncs.ZUnicodeToString := @ZConvertUnicodeToString;\n    Consettings^.ConvFuncs.ZStringToUnicode := @ZConvertStringToUnicode;\n    {$ELSE}\n      {String To/From Raw}\n      if ZCompatibleCodePages(ConSettings^.ClientCodePage^.CP, ConSettings^.CTRL_CP) then\n      begin\n        Consettings^.ConvFuncs.ZRawToString := @ZMoveRawToString;\n        if ConSettings^.AutoEncode then\n          Consettings^.ConvFuncs.ZStringToRaw := @ZConvertStringToRawWithAutoEncode\n        else\n          Consettings^.ConvFuncs.ZStringToRaw := @ZMoveStringToRaw;\n      end\n      else\n        if ConSettings^.AutoEncode then\n        begin\n          Consettings^.ConvFuncs.ZRawToString := @ZConvertRawToString;\n          Consettings^.ConvFuncs.ZStringToRaw := @ZConvertStringToRawWithAutoEncode;\n        end\n        else\n        begin\n          Consettings^.ConvFuncs.ZStringToRaw := @ZMoveStringToRaw;\n          Consettings^.ConvFuncs.ZRawToString := @ZMoveRawToString;\n        end;\n\n      {String To/From Unicode}\n      if ConSettings^.CTRL_CP = zCP_UTF8 then\n        Consettings^.ConvFuncs.ZUnicodeToString := @ZConvertUnicodeToString_CPUTF8\n      else\n        Consettings^.ConvFuncs.ZUnicodeToString := @ZConvertUnicodeToString;\n\n      if ConSettings^.AutoEncode then\n        Consettings^.ConvFuncs.ZStringToUnicode := @ZConvertStringToUnicodeWithAutoEncode\n      else\n        if ConSettings^.CTRL_CP = zCP_UTF8 then\n          Consettings^.ConvFuncs.ZStringToUnicode := @ZConvertString_CPUTF8ToUnicode\n        else\n          Consettings^.ConvFuncs.ZStringToUnicode := @ZConvertStringToUnicode;\n    {$ENDIF}\n  end\n  else //autoencode strings is allways true\n  begin\n    ConSettings^.ConvFuncs.ZUTF8ToString := @ZConvertUTF8ToString;\n    ConSettings^.ConvFuncs.ZStringToUTF8 := @ZConvertStringToUTF8WithAutoEncode;\n    ConSettings^.ConvFuncs.ZAnsiToRaw := @ZConvertAnsiToRaw;\n    ConSettings^.ConvFuncs.ZRawToAnsi := @ZConvertRawToAnsi;\n    ConSettings^.ConvFuncs.ZRawToUTF8 := @ZConvertRawToUTF8;\n    ConSettings^.ConvFuncs.ZUTF8ToRaw := @ZConvertUTF8ToRaw;\n    Consettings^.ConvFuncs.ZStringToRaw := @ZConvertStringToRawWithAutoEncode;\n    Consettings^.ConvFuncs.ZRawToString := @ZConvertRawToString;\n    Consettings^.ConvFuncs.ZUnicodeToRaw := @ZUnicodeToRaw;\n    Consettings^.ConvFuncs.ZRawToUnicode := @ZRawToUnicode;\n    ConSettings^.ConvFuncs.ZUnicodeToString := @ZConvertUnicodeToString;\n    Consettings^.ConvFuncs.ZStringToUnicode := @ZConvertStringToUnicodeWithAutoEncode;\n  end;\nend;\n\nend.\n\n"
  },
  {
    "path": "lib/zeosdbo/src/core/ZExprParser.pas",
    "content": "{*********************************************************}\n{                                                         }\n{                 Zeos Database Objects                   }\n{         Expression Parser classes and interfaces        }\n{                                                         }\n{         Originally written by Sergey Seroukhov          }\n{                                                         }\n{*********************************************************}\n\n{@********************************************************}\n{    Copyright (c) 1999-2012 Zeos Development Group       }\n{                                                         }\n{ License Agreement:                                      }\n{                                                         }\n{ This library is distributed in the hope that it will be }\n{ useful, but WITHOUT ANY WARRANTY; without even the      }\n{ implied warranty of MERCHANTABILITY or FITNESS FOR      }\n{ A PARTICULAR PURPOSE.  See the GNU Lesser General       }\n{ Public License for more details.                        }\n{                                                         }\n{ The source code of the ZEOS Libraries and packages are  }\n{ distributed under the Library GNU General Public        }\n{ License (see the file COPYING / COPYING.ZEOS)           }\n{ with the following  modification:                       }\n{ As a special exception, the copyright holders of this   }\n{ library give you permission to link this library with   }\n{ independent modules to produce an executable,           }\n{ regardless of the license terms of these independent    }\n{ modules, and to copy and distribute the resulting       }\n{ executable under terms of your choice, provided that    }\n{ you also meet, for each linked independent module,      }\n{ the terms and conditions of the license of that module. }\n{ An independent module is a module which is not derived  }\n{ from or based on this library. If you modify this       }\n{ library, you may extend this exception to your version  }\n{ of the library, but you are not obligated to do so.     }\n{ If you do not wish to do so, delete this exception      }\n{ statement from your version.                            }\n{                                                         }\n{                                                         }\n{ The project web site is located on:                     }\n{   http://zeos.firmos.at  (FORUM)                        }\n{   http://sourceforge.net/p/zeoslib/tickets/ (BUGTRACKER)}\n{   svn://svn.code.sf.net/p/zeoslib/code-0/trunk (SVN)    }\n{                                                         }\n{   http://www.sourceforge.net/projects/zeoslib.          }\n{                                                         }\n{                                                         }\n{                                 Zeos Development Group. }\n{********************************************************@}\n\nunit ZExprParser;\n\ninterface\n\n{$I ZCore.inc}\n\nuses SysUtils, Classes, {$IFDEF MSEgui}mclasses,{$ENDIF} Contnrs,\n  ZCompatibility, ZVariant, ZTokenizer;\n\ntype\n  {** Define types of expression tokens. }\n  TZExpressionTokenType = (\n    ttUnknown, ttLeftBrace, ttRightBrace, ttLeftSquareBrace,\n    ttRightSquareBrace, ttPlus, ttMinus, ttStar, ttSlash, ttProcent, ttPower,\n    ttEqual, ttNotEqual, ttMore, ttLess, ttEqualMore, ttEqualLess,\n    ttAnd, ttOr, ttXor, ttIs, ttNull, ttNot, ttLike, ttNotLike, ttIsNull,\n    ttIsNotNull, ttComma, ttUnary, ttFunction, ttVariable, ttConstant\n  );\n\n  {** Defines a parser exception. }\n  TZParseError = class (Exception);\n\n  {** Defines an expression token holder. }\n  TZExpressionToken = class (TObject)\n  private\n    FTokenType: TZExpressionTokenType;\n    FValue: TZVariant;\n  public\n    constructor Create(TokenType: TZExpressionTokenType; const Value: TZVariant);\n\n    property TokenType: TZExpressionTokenType read FTokenType write FTokenType;\n    property Value: TZVariant read FValue write FValue;\n  end;\n\n  {** Implements an expression parser class. }\n  TZExpressionParser = class (TObject)\n  private\n    FTokenizer: IZTokenizer;\n    FExpression: string;\n    FInitialTokens: TObjectList;\n    FTokenIndex: Integer;\n    FResultTokens: TObjectList;\n    FVariables: TStrings;\n\n    function HasMoreTokens: Boolean;\n    function GetToken: TZExpressionToken;\n    function GetNextToken: TZExpressionToken;\n    procedure ShiftToken;\n    function CheckTokenTypes(\n      TokenTypes: array of TZExpressionTokenType): Boolean;\n\n    procedure TokenizeExpression;\n\n    procedure SyntaxAnalyse;\n    procedure SyntaxAnalyse1;\n    procedure SyntaxAnalyse2;\n    procedure SyntaxAnalyse3;\n    procedure SyntaxAnalyse4;\n    procedure SyntaxAnalyse5;\n    procedure SyntaxAnalyse6;\n  public\n    constructor Create(Tokenizer: IZTokenizer);\n    destructor Destroy; override;\n\n    procedure Parse(Expression: string);\n    procedure Clear;\n\n    property Tokenizer: IZTokenizer read FTokenizer write FTokenizer;\n    property Expression: string read FExpression write Parse;\n    property ResultTokens: TObjectList read FResultTokens;\n    property Variables: TStrings read FVariables;\n  end;\n\nimplementation\n\nuses ZSysUtils, ZMessages;\n\n{ TZExpressionToken }\n\n{**\n  Creates an expression token object.\n  @param TokenType a type of the token.\n  @param Value a token value.\n}\nconstructor TZExpressionToken.Create(TokenType: TZExpressionTokenType;\n  const Value: TZVariant);\nbegin\n  FTokenType := TokenType;\n  FValue := Value;\nend;\n\nconst\n  {** Defines a list of operators. }\n  OperatorTokens: array[0..24] of string = (\n    '(', ')', '[', ']', '+', '-', '*', '/', '%', '^',\n    '=', '<>', '!=', '>', '<', '>=', '<=',\n    'AND', 'OR', 'XOR', 'NOT', 'IS', 'NULL', 'LIKE', ','\n  );\n\n  {** Defines a list of operator codes. }\n  OperatorCodes: array[0..24] of TZExpressionTokenType = (\n    ttLeftBrace, ttRightBrace, ttLeftSquareBrace, ttRightSquareBrace,\n    ttPlus, ttMinus, ttStar, ttSlash, ttProcent, ttPower, ttEqual, ttNotEqual,\n    ttNotEqual, ttMore, ttLess, ttEqualMore, ttEqualLess, ttAnd, ttOr, ttXor,\n    ttNot, ttIs, ttNull, ttLike, ttComma\n  );\n\n{ TZExpressionParser }\n\n{**\n  Creates this expression parser object.\n  @param Tokenizer an expression tokenizer.\n}\nconstructor TZExpressionParser.Create(Tokenizer: IZTokenizer);\nbegin\n  FTokenizer := Tokenizer;\n  FExpression := '';\n  FInitialTokens := TObjectList.Create;\n  FTokenIndex := 0;\n  FResultTokens := TObjectList.Create;\n  FVariables := TStringList.Create;\nend;\n\n{**\n  Destroyes this object and cleanups the memory.\n}\ndestructor TZExpressionParser.Destroy;\nbegin\n  FreeAndNil(FInitialTokens);\n  FreeAndNil(FResultTokens);\n  FreeAndNil(FVariables);\n  FTokenizer := Nil;\n  inherited Destroy;\nend;\n\n{**\n  Clears parsing result.\n}\nprocedure TZExpressionParser.Clear;\nbegin\n  FExpression := '';\n  FInitialTokens.Clear;\n  FResultTokens.Clear;\n  FTokenIndex := 0;\n  FVariables.Clear;\nend;\n\n{**\n  Sets a new expression string and parses it into internal byte code.\n  @param expression a new expression string.\n}\nprocedure TZExpressionParser.Parse(Expression: string);\nbegin\n  Clear;\n  FExpression := Trim(Expression);\n  if FExpression <> '' then\n  begin\n    TokenizeExpression;\n    SyntaxAnalyse;\n    if HasMoreTokens then\n    begin\n      raise TZParseError.Create(\n        Format(SSyntaxErrorNear, [SoftVarManager.GetAsString(GetToken.Value)]));\n    end;\n  end;\nend;\n\n{**\n  Checks are there more tokens for processing.\n  @return <code>TRUE</code> if some tokens are present.\n}\nfunction TZExpressionParser.HasMoreTokens: Boolean;\nbegin\n  Result := FTokenIndex < FInitialTokens.Count;\nend;\n\n{**\n  Gets the current token object.\n  @param tokens a collection of tokens.\n  @returns the current token object.\n}\nfunction TZExpressionParser.GetToken: TZExpressionToken;\nbegin\n  if FTokenIndex < FInitialTokens.Count then\n    Result := TZExpressionToken(FInitialTokens[FTokenIndex])\n   else\n      Result := nil;\nend;\n\n{**\n  Gets the next token object.\n  @param tokens a collection of tokens.\n  @returns the next token object.\n}\nfunction TZExpressionParser.GetNextToken: TZExpressionToken;\nbegin\n  if (FTokenIndex + 1) < FInitialTokens.Count then\n    Result := TZExpressionToken(FInitialTokens[FTokenIndex + 1])\n   else\n      Result := nil;\nend;\n\n{**\n  Shifts the current token object.\n}\nprocedure TZExpressionParser.ShiftToken;\nbegin\n  Inc(FTokenIndex);\nend;\n\n{**\n  Checks available token types with token types from the list.\n  If they match it shifts the tokens.\n  @param TokenTypes a list of token types to compare.\n  @return <code>True</code> if token types match.\n}\nfunction TZExpressionParser.CheckTokenTypes(\n  TokenTypes: array of TZExpressionTokenType): Boolean;\nvar\n  I: Integer;\n  Temp: TZExpressionToken;\nbegin\n  Result := False;\n  for I := Low(TokenTypes) to High(TokenTypes) do\n  begin\n    if (FTokenIndex + I) < FInitialTokens.Count then\n    begin\n      Temp := TZExpressionToken(FInitialTokens[FTokenIndex + I]);\n      Result := Temp.TokenType = TokenTypes[I];\n      end\n      else\n      Result := False;\n\n    if not Result then\n      Break;\n  end;\n  if Result then\n    Inc(FTokenIndex, Length(TokenTypes));\nend;\n\n{**\n  Tokenizes the given expression and prepares an initial tokens list.\n}\nprocedure TZExpressionParser.TokenizeExpression;\nvar\n  I: Integer;\n  TokenIndex: Integer;\n  Temp: string;\n  Tokens: TStrings;\n  TokenType: TZExpressionTokenType;\n  TokenValue: TZVariant;\nbegin\n  Tokens := FTokenizer.TokenizeBufferToList(FExpression,\n    [toSkipWhitespaces, toSkipComments, toSkipEOF, toDecodeStrings]);\n  try\n    TokenIndex := 0;\n\n    while TokenIndex < Tokens.Count do\n    begin\n      TokenType := ttUnknown;\n      TokenValue := NullVariant;\n      case TZTokenType({$IFDEF FPC}Pointer({$ENDIF}\n        Tokens.Objects[TokenIndex]{$IFDEF FPC}){$ENDIF}) of\n        ttKeyword:\n          begin\n            Temp := UpperCase(Tokens[TokenIndex]);\n            if Temp = 'TRUE' then\n            begin\n              TokenType := ttConstant;\n              TokenValue:= EncodeBoolean(True);\n            end\n            else if Temp = 'FALSE' then\n            begin\n              TokenType := ttConstant;\n              TokenValue:= EncodeBoolean(False);\n            end\n            else\n            begin\n              for I := Low(OperatorTokens) to High(OperatorTokens) do\n              begin\n                if OperatorTokens[I] = Temp then\n                begin\n                  TokenType := OperatorCodes[I];\n                  Break;\n                end;\n              end;\n            end;\n          end;\n        ttWord:\n          begin\n            TokenType := ttVariable;\n            Temp := Tokens[TokenIndex];\n            if FVariables.IndexOf(Temp) < 0 then\n              FVariables.Add(Temp);\n            TokenValue:= EncodeString(Temp);\n          end;\n        ttInteger:\n          begin\n            TokenType := ttConstant;\n            TokenValue:= EncodeInteger(StrToInt64(Tokens[TokenIndex]));\n          end;\n        ttFloat:\n          begin\n            TokenType := ttConstant;\n            TokenValue:= EncodeFloat(SqlStrToFloat(AnsiString(Tokens[TokenIndex])));\n          end;\n        ttQuoted:\n          begin\n            TokenType := ttConstant;\n            TokenValue:= EncodeString(Tokens[TokenIndex]);\n          end;\n        ttSymbol:\n          begin\n            Temp := Tokens[TokenIndex];\n            for I := Low(OperatorTokens) to High(OperatorTokens) do\n            begin\n              if Temp = OperatorTokens[I] then\n              begin\n                TokenType := OperatorCodes[I];\n                Break;\n              end;\n            end;\n          end;\n        ttTime,ttDate,ttDateTime:\n          begin\n            TokenType := ttConstant;\n            TokenValue:= EncodeDateTime(StrToDateTime(Tokens[TokenIndex]));\n          end;\n      end;\n\n      if TokenType = ttUnknown then\n        raise TZParseError.Create(Format(SUnknownSymbol, [Tokens[TokenIndex]]));\n\n      Inc(TokenIndex);\n      FInitialTokens.Add(TZExpressionToken.Create(TokenType, TokenValue));\n    end;\n  finally\n    Tokens.Free;\n  end;\nend;\n\n{**\n  Performs a syntax analyze at level 0.\n}\nprocedure TZExpressionParser.SyntaxAnalyse;\nvar\n  Token: TZExpressionToken;\nbegin\n  if not HasMoreTokens then\n    raise TZParseError.Create(SUnexpectedExprEnd);\n\n  SyntaxAnalyse1;\n  while HasMoreTokens do\n  begin\n    Token := GetToken;\n    if not (Token.TokenType in [ttAnd, ttOr, ttXor]) then\n      Break;\n    ShiftToken;\n    SyntaxAnalyse1;\n    FResultTokens.Add(TZExpressionToken.Create(Token.TokenType, NullVariant));\n  end;\nend;\n\n{**\n  Performs a syntax analyze at level 1.\n}\nprocedure TZExpressionParser.SyntaxAnalyse1;\nvar\n  Token: TZExpressionToken;\nbegin\n  if not HasMoreTokens then\n    raise TZParseError.Create(SUnexpectedExprEnd);\n\n  Token := GetToken;\n  if Token.TokenType = ttNot then\n  begin\n    ShiftToken;\n    SyntaxAnalyse2;\n    FResultTokens.Add(TZExpressionToken.Create(Token.TokenType, NullVariant));\n   end\n   else\n    SyntaxAnalyse2;\nend;\n\n{**\n  Performs a syntax analyze at level 2.\n}\nprocedure TZExpressionParser.SyntaxAnalyse2;\nvar\n  Token: TZExpressionToken;\nbegin\n  if not HasMoreTokens then\n    raise TZParseError.Create(SUnexpectedExprEnd);\n\n  SyntaxAnalyse3;\n  while HasMoreTokens do\n  begin\n    Token := GetToken;\n    if not (Token.TokenType in [ttEqual, ttNotEqual, ttMore, ttLess,\n      ttEqualMore, ttEqualLess]) then\n      Break;\n    ShiftToken;\n    SyntaxAnalyse3;\n    FResultTokens.Add(TZExpressionToken.Create(Token.TokenType, NullVariant));\n  end;\nend;\n\n{**\n  Performs a syntax analyze at level 3.\n}\nprocedure TZExpressionParser.SyntaxAnalyse3;\nvar\n  Token: TZExpressionToken;\nbegin\n  if not HasMoreTokens then\n    raise TZParseError.Create(SUnexpectedExprEnd);\n\n  SyntaxAnalyse4;\n  while HasMoreTokens do\n  begin\n    Token := GetToken;\n    if Token.TokenType in [ttPlus, ttMinus, ttLike] then\n    begin\n      ShiftToken;\n      SyntaxAnalyse4;\n      FResultTokens.Add(TZExpressionToken.Create(Token.TokenType, NullVariant));\n    end\n    else if CheckTokenTypes([ttNot, ttLike]) then\n    begin\n      SyntaxAnalyse4;\n      FResultTokens.Add(TZExpressionToken.Create(ttNotLike, NullVariant));\n    end\n    else if CheckTokenTypes([ttIs, ttNull]) then\n    begin\n      FResultTokens.Add(TZExpressionToken.Create(ttIsNull, NullVariant));\n    end\n    else if CheckTokenTypes([ttIs, ttNot, ttNull]) then\n    begin\n      FResultTokens.Add(TZExpressionToken.Create(ttIsNotNull, NullVariant));\n      end\n      else\n      Break;\n  end;\nend;\n\n{**\n  Performs a syntax analyze at level 4.\n}\nprocedure TZExpressionParser.SyntaxAnalyse4;\nvar\n  Token: TZExpressionToken;\nbegin\n  if not HasMoreTokens then\n    raise TZParseError.Create(SUnexpectedExprEnd);\n\n  SyntaxAnalyse5;\n  while HasMoreTokens do\n  begin\n    Token := GetToken;\n    if not (Token.TokenType in [ttStar, ttSlash, ttProcent]) then\n      Break;\n    ShiftToken;\n    SyntaxAnalyse5;\n    FResultTokens.Add(TZExpressionToken.Create(Token.TokenType, NullVariant));\n  end;\nend;\n\n{**\n  Performs a syntax analyze at level 5.\n}\nprocedure TZExpressionParser.SyntaxAnalyse5;\nvar\n  Token: TZExpressionToken;\nbegin\n  if not HasMoreTokens then\n    raise TZParseError.Create(SUnexpectedExprEnd);\n\n  SyntaxAnalyse6;\n  while HasMoreTokens do\n  begin\n    Token := GetToken;\n    if Token.TokenType <> ttPower then\n      Break;\n    ShiftToken;\n    SyntaxAnalyse6;\n    FResultTokens.Add(TZExpressionToken.Create(Token.TokenType, NullVariant));\n  end;\nend;\n\n{**\n  Performs a syntax analyze at level 6.\n}\nprocedure TZExpressionParser.SyntaxAnalyse6;\nvar\n  ParamsCount: Integer;\n  Unary, Token: TZExpressionToken;\n  Primitive, NextToken: TZExpressionToken;\n  Temp: TZVariant;\nbegin\n  if not HasMoreTokens then\n    raise TZParseError.Create(SUnexpectedExprEnd);\n\n  Unary := GetToken;\n  if Unary.TokenType = ttPlus then\n  begin\n    Unary := nil;\n    ShiftToken;\n  end\n  else if Unary.TokenType = ttMinus then\n  begin\n    Unary.TokenType := ttUnary;\n    ShiftToken;\n   end\n   else\n    Unary := nil;\n\n  if not HasMoreTokens then\n    raise TZParseError.Create(SUnexpectedExprEnd);\n\n  Primitive := GetToken;\n  NextToken := GetNextToken;\n  if (Primitive.TokenType = ttVariable) and (NextToken <> nil)\n    and (NextToken.TokenType = ttLeftBrace) then\n    Primitive.TokenType := ttFunction;\n\n  if Primitive.TokenType in [ttConstant, ttVariable] then\n  begin\n    ShiftToken;\n    FResultTokens.Add(TZExpressionToken.Create(\n      Primitive.TokenType, Primitive.Value));\n  end\n  else if Primitive.TokenType = ttLeftBrace then\n  begin\n    ShiftToken;\n    SyntaxAnalyse;\n    if not HasMoreTokens then\n      raise TZParseError.Create(SUnexpectedExprEnd);\n    Primitive := GetToken;\n    if Primitive.TokenType <> ttRightBrace then\n      raise TZParseError.Create(SRightBraceExpected);\n    ShiftToken;\n  end\n  else if Primitive.TokenType = ttFunction then\n  begin\n    ShiftToken;\n    Token := GetToken;\n    if Token.TokenType <> ttLeftBrace then\n      raise TZParseError.Create(SInternalError);\n    ParamsCount := 0;\n    repeat\n      ShiftToken;\n      Token := GetToken;\n      if (Token = nil) or (Token.TokenType = ttRightBrace) then\n        Break;\n      Inc(ParamsCount);\n      SyntaxAnalyse;\n      Token := GetToken;\n    until (Token = nil) or (Token.TokenType <> ttComma);\n\n    if not HasMoreTokens then\n      raise TZParseError.Create(SUnexpectedExprEnd);\n    if Token.TokenType <> ttRightBrace then\n      raise TZParseError.Create(SRightBraceExpected);\n    ShiftToken;\n\n    Temp:= EncodeInteger(ParamsCount);\n    FResultTokens.Add(TZExpressionToken.Create(ttConstant, Temp));\n    FResultTokens.Add(TZExpressionToken.Create(Primitive.TokenType,\n      Primitive.Value));\n   end\n   else\n    raise TZParseError.Create(SSyntaxError);\n\n  if Unary <> nil then\n    FResultTokens.Add(TZExpressionToken.Create(Unary.TokenType, NullVariant));\nend;\n\nend.\n"
  },
  {
    "path": "lib/zeosdbo/src/core/ZExprToken.pas",
    "content": "{*********************************************************}\n{                                                         }\n{                 Zeos Database Objects                   }\n{        String tokenizing classes for Expressions        }\n{                                                         }\n{          Originally written by Sergey Seroukhov         }\n{                                                         }\n{*********************************************************}\n\n{@********************************************************}\n{    Copyright (c) 1999-2012 Zeos Development Group       }\n{                                                         }\n{ License Agreement:                                      }\n{                                                         }\n{ This library is distributed in the hope that it will be }\n{ useful, but WITHOUT ANY WARRANTY; without even the      }\n{ implied warranty of MERCHANTABILITY or FITNESS FOR      }\n{ A PARTICULAR PURPOSE.  See the GNU Lesser General       }\n{ Public License for more details.                        }\n{                                                         }\n{ The source code of the ZEOS Libraries and packages are  }\n{ distributed under the Library GNU General Public        }\n{ License (see the file COPYING / COPYING.ZEOS)           }\n{ with the following  modification:                       }\n{ As a special exception, the copyright holders of this   }\n{ library give you permission to link this library with   }\n{ independent modules to produce an executable,           }\n{ regardless of the license terms of these independent    }\n{ modules, and to copy and distribute the resulting       }\n{ executable under terms of your choice, provided that    }\n{ you also meet, for each linked independent module,      }\n{ the terms and conditions of the license of that module. }\n{ An independent module is a module which is not derived  }\n{ from or based on this library. If you modify this       }\n{ library, you may extend this exception to your version  }\n{ of the library, but you are not obligated to do so.     }\n{ If you do not wish to do so, delete this exception      }\n{ statement from your version.                            }\n{                                                         }\n{                                                         }\n{ The project web site is located on:                     }\n{   http://zeos.firmos.at  (FORUM)                        }\n{   http://sourceforge.net/p/zeoslib/tickets/ (BUGTRACKER)}\n{   svn://svn.code.sf.net/p/zeoslib/code-0/trunk (SVN)    }\n{                                                         }\n{   http://www.sourceforge.net/projects/zeoslib.          }\n{                                                         }\n{                                                         }\n{                                 Zeos Development Group. }\n{********************************************************@}\n\nunit ZExprToken;\n\ninterface\n\n{$I ZCore.inc}\n\nuses\n  Classes, {$IFDEF MSEgui}mclasses,{$ENDIF} SysUtils,\n  ZSysUtils, ZTokenizer;\n\ntype\n\n  {** Implements an Expression-specific number state object. }\n  TZExpressionNumberState = class (TZNumberState)\n  public\n    function NextToken(Stream: TStream; FirstChar: Char;\n      Tokenizer: TZTokenizer): TZToken; override;\n  end;\n\n  {** Implements an Expression-specific quote string state object. }\n  TZExpressionQuoteState = class (TZQuoteState)\n  public\n    function NextToken(Stream: TStream; FirstChar: Char;\n      Tokenizer: TZTokenizer): TZToken; override;\n\n    function EncodeString(const Value: string; QuoteChar: Char): string; override;\n    function DecodeString(const Value: string; QuoteChar: Char): string; override;\n  end;\n\n  {**\n    This state will either delegate to a comment-handling\n    state, or return a token with just a slash in it.\n  }\n  TZExpressionCommentState = class (TZCppCommentState)\n  public\n    function NextToken(Stream: TStream; FirstChar: Char;\n      Tokenizer: TZTokenizer): TZToken; override;\n  end;\n\n  {** Implements a symbol state object. }\n  TZExpressionSymbolState = class (TZSymbolState)\n  public\n    constructor Create;\n  end;\n\n  {** Implements a word state object. }\n  TZExpressionWordState = class (TZWordState)\n  public\n    constructor Create;\n    function NextToken(Stream: TStream; FirstChar: Char;\n      Tokenizer: TZTokenizer): TZToken; override;\n  end;\n\n  {** Implements a default tokenizer object. }\n  TZExpressionTokenizer = class (TZTokenizer)\n  public\n    constructor Create;\n  end;\n\nimplementation\nuses ZCompatibility;\n\nconst\n  {** List of keywords. }\n  Keywords: array [0..8] of string = (\n    'AND','OR','NOT','XOR','LIKE','IS','NULL','TRUE','FALSE'\n  );\n\n{ TZExpressionNumberState }\n\n\n//gto: all operations on Streams should be done without presuming the size\n//     of the read var, like Stream.Read(LastChar, 1), to read 1 char\n//\n//     Instead, operations should use SizeOf(Type), like this:\n//     Stream.Read(LastChar, 1 * SizeOf(Char))\n//\n//     This is unicode safe and ansi (Delphi under 2009) compatible\n\n{**\n  Return a number token from a reader.\n  @return a number token from a reader\n}\nfunction TZExpressionNumberState.NextToken(Stream: TStream; FirstChar: Char;\n  Tokenizer: TZTokenizer): TZToken;\nvar\n  TempChar: Char;\n  FloatPoint: Boolean;\n  LastChar: Char;\n\n  function ReadDecDigits: string;\n  begin\n    Result := '';\n    LastChar := #0;\n    while Stream.Read(LastChar, 1 * SizeOf(Char)) > 0 do\n    begin\n      if CharInSet(LastChar, ['0'..'9']) then\n      begin\n        Result := Result + LastChar;\n        LastChar := #0;\n      end\n      else\n      begin\n        Stream.Seek(-(1 * SizeOf(Char)), soFromCurrent);\n        Break;\n      end;\n    end;\n  end;\n\nbegin\n  FloatPoint := FirstChar = '.';\n  Result.Value := FirstChar;\n  Result.TokenType := ttUnknown;\n  LastChar := #0;\n\n  { Reads the first part of the number before decimal point }\n  if not FloatPoint then\n  begin\n    Result.Value := Result.Value + ReadDecDigits;\n    FloatPoint := LastChar = '.';\n    if FloatPoint then\n    begin\n      Stream.Read(TempChar, 1 * SizeOf(Char));\n      Result.Value := Result.Value + TempChar;\n    end;\n  end;\n\n  { Reads the second part of the number after decimal point }\n  if FloatPoint then\n    Result.Value := Result.Value + ReadDecDigits;\n\n  { Reads a power part of the number }\n  if CharInSet(LastChar, ['e', 'E']) then\n  begin\n    Stream.Read(TempChar, 1 * SizeOf(Char));\n    Result.Value := Result.Value + TempChar;\n    FloatPoint := True;\n\n    Stream.Read(TempChar, 1 * SizeOf(Char));\n    if CharInSet(TempChar, ['0'..'9', '-', '+']) then\n      Result.Value := Result.Value + TempChar + ReadDecDigits\n    else\n    begin\n      Result.Value := Copy(Result.Value, 1, Length(Result.Value) - 1);\n      Stream.Seek(-(2 * SizeOf(Char)), soFromCurrent);\n    end;\n  end;\n\n  { Prepare the result }\n  if Result.Value = '.' then\n  begin\n    if Tokenizer.SymbolState <> nil then\n      Result := Tokenizer.SymbolState.NextToken(Stream, FirstChar, Tokenizer);\n  end\n  else\n  begin\n    if FloatPoint then\n      Result.TokenType := ttFloat\n      else\n         Result.TokenType := ttInteger;\n  end;\nend;\n\n{ TZExpressionSQLQuoteState }\n\n{**\n  Return a quoted string token from a reader. This method\n  will collect characters until it sees a match to the\n  character that the tokenizer used to switch to this state.\n\n  @return a quoted string token from a reader\n}\nfunction TZExpressionQuoteState.NextToken(Stream: TStream;\n  FirstChar: Char; Tokenizer: TZTokenizer): TZToken;\nvar\n  ReadChar: Char;\n  LastChar: Char;\nbegin\n  if FirstChar = '\"' then\n    Result.TokenType := ttWord\n   else\n      Result.TokenType := ttQuoted;\n  Result.Value := FirstChar;\n  LastChar := #0;\n\n  while Stream.Read(ReadChar, 1 * SizeOf(Char)) > 0 do\n  begin\n    if (LastChar = FirstChar) and (ReadChar <> FirstChar) then\n    begin\n      Stream.Seek(-(1 * SizeOf(Char)), soFromCurrent);\n      Break;\n    end;\n    Result.Value := Result.Value + ReadChar;\n    if LastChar = '\\' then\n      LastChar := #0\n    else if (LastChar = FirstChar) and (ReadChar = FirstChar) then\n      LastChar := #0\n      else\n         LastChar := ReadChar;\n  end;\nend;\n\n{**\n  Encodes a string value.\n  @param Value a string value to be encoded.\n  @param QuoteChar a string quote character.\n  @returns an encoded string.\n}\nfunction TZExpressionQuoteState.EncodeString(const Value: string;\n  QuoteChar: Char): string;\nbegin\n  if CharInSet(QuoteChar, ['''', '\"']) then\n    Result := QuoteChar + EncodeCString(Value) + QuoteChar\n  else\n    Result := Value;\nend;\n\n{**\n  Decodes a string value.\n  @param Value a string value to be decoded.\n  @param QuoteChar a string quote character.\n  @returns an decoded string.\n}\nfunction TZExpressionQuoteState.DecodeString(const Value: string;\n  QuoteChar: Char): string;\nbegin\n  if (Length(Value) >= 2) and CharInSet(QuoteChar, ['''', '\"'])\n     and (Value[1] = QuoteChar) and (Value[Length(Value)] = QuoteChar) then\n    Result := DecodeCString(Copy(Value, 2, Length(Value) - 2))\n   else\n      Result := Value;\nend;\n\n{ TZExpressionCommentState }\n\n{**\n  Gets an Expression specific comments like /* */.\n  @return either just a slash token, or the results of\n    delegating to a comment-handling state\n}\nfunction TZExpressionCommentState.NextToken(Stream: TStream;\n  FirstChar: Char; Tokenizer: TZTokenizer): TZToken;\nvar\n  ReadChar: Char;\n  ReadNum: Integer;\nbegin\n  Result.TokenType := ttUnknown;\n  Result.Value := FirstChar;\n\n  if FirstChar = '/' then\n  begin\n    ReadNum := Stream.Read(ReadChar, 1 * SizeOf(Char));\n    if (ReadNum > 0) and (ReadChar = '*') then\n    begin\n      Result.TokenType := ttComment;\n      Result.Value := '/*' + GetMultiLineComment(Stream);\n    end\n    else\n    begin\n      if ReadNum > 0 then\n        Stream.Seek(-(1 * SizeOf(Char)), soFromCurrent);\n    end;\n  end;\n\n  if (Result.TokenType = ttUnknown) and (Tokenizer.SymbolState <> nil) then\n    Result := Tokenizer.SymbolState.NextToken(Stream, FirstChar, Tokenizer);\nend;\n\n{ TZExpressionSymbolState }\n\n{**\n  Creates this Expression-specific symbol state object.\n}\nconstructor TZExpressionSymbolState.Create;\nbegin\n  inherited Create;\n  Add('<=');\n  Add('>=');\n  Add('<>');\n  Add('!=');\nend;\n\n{ TZExpressionWordState }\n\n{**\n  Constructs this Expression-specific word state object.\n}\nconstructor TZExpressionWordState.Create;\nbegin\n  SetWordChars(#0, #191, False);\n  SetWordChars(#192, high(char), True);\n  SetWordChars('a', 'z', True);\n  SetWordChars('A', 'Z', True);\n  SetWordChars('0', '9', True);\n  SetWordChars('_', '_', True);\nend;\n\n{**\n  Gets a word tokens or special operators.\n  @return a processed token.\n}\nfunction TZExpressionWordState.NextToken(Stream: TStream; FirstChar: Char;\n  Tokenizer: TZTokenizer): TZToken;\nvar\n  I: Integer;\n  Temp: string;\nbegin\n  Result := inherited NextToken(Stream, FirstChar, Tokenizer);\n  Temp := UpperCase(Result.Value);\n\n  for I := Low(Keywords) to High(Keywords) do\n  begin\n    if Temp = Keywords[I] then\n    begin\n      Result.TokenType := ttKeyword;\n      Break;\n    end;\n  end;\nend;\n\n{ TZExpressionTokenizer }\n\n{**\n  Constructs a tokenizer with a default state table (as\n  described in the class comment).\n}\nconstructor TZExpressionTokenizer.Create;\nbegin\n  WhitespaceState := TZWhitespaceState.Create;\n\n  SymbolState := TZExpressionSymbolState.Create;\n  NumberState := TZExpressionNumberState.Create;\n  QuoteState := TZExpressionQuoteState.Create;\n  WordState := TZExpressionWordState.Create;\n  CommentState := TZExpressionCommentState.Create;\n\n  SetCharacterState(#0, #32, WhitespaceState);\n  SetCharacterState(#33, #191, SymbolState);\n  SetCharacterState(#192, High(Char), WordState);\n\n  SetCharacterState('a', 'z', WordState);\n  SetCharacterState('A', 'Z', WordState);\n  SetCharacterState('_', '_', WordState);\n\n  SetCharacterState('0', '9', NumberState);\n  SetCharacterState('.', '.', NumberState);\n\n  SetCharacterState('\"', '\"', QuoteState);\n  SetCharacterState('''', '''', QuoteState);\n\n  SetCharacterState('/', '/', CommentState);\nend;\n\nend.\n\n"
  },
  {
    "path": "lib/zeosdbo/src/core/ZExpression.pas",
    "content": "{*********************************************************}\n{                                                         }\n{                 Zeos Database Objects                   }\n{             Expression classes and interfaces           }\n{                                                         }\n{          Originally written by Sergey Seroukhov         }\n{                                                         }\n{*********************************************************}\n\n{@********************************************************}\n{    Copyright (c) 1999-2012 Zeos Development Group       }\n{                                                         }\n{ License Agreement:                                      }\n{                                                         }\n{ This library is distributed in the hope that it will be }\n{ useful, but WITHOUT ANY WARRANTY; without even the      }\n{ implied warranty of MERCHANTABILITY or FITNESS FOR      }\n{ A PARTICULAR PURPOSE.  See the GNU Lesser General       }\n{ Public License for more details.                        }\n{                                                         }\n{ The source code of the ZEOS Libraries and packages are  }\n{ distributed under the Library GNU General Public        }\n{ License (see the file COPYING / COPYING.ZEOS)           }\n{ with the following  modification:                       }\n{ As a special exception, the copyright holders of this   }\n{ library give you permission to link this library with   }\n{ independent modules to produce an executable,           }\n{ regardless of the license terms of these independent    }\n{ modules, and to copy and distribute the resulting       }\n{ executable under terms of your choice, provided that    }\n{ you also meet, for each linked independent module,      }\n{ the terms and conditions of the license of that module. }\n{ An independent module is a module which is not derived  }\n{ from or based on this library. If you modify this       }\n{ library, you may extend this exception to your version  }\n{ of the library, but you are not obligated to do so.     }\n{ If you do not wish to do so, delete this exception      }\n{ statement from your version.                            }\n{                                                         }\n{                                                         }\n{ The project web site is located on:                     }\n{   http://zeos.firmos.at  (FORUM)                        }\n{   http://sourceforge.net/p/zeoslib/tickets/ (BUGTRACKER)}\n{   svn://svn.code.sf.net/p/zeoslib/code-0/trunk (SVN)    }\n{                                                         }\n{   http://www.sourceforge.net/projects/zeoslib.          }\n{                                                         }\n{                                                         }\n{                                 Zeos Development Group. }\n{********************************************************@}\n\nunit ZExpression;\n\ninterface\n\n{$I ZCore.inc}\n\nuses SysUtils, Classes, {$IFDEF WITH_TOBJECTLIST_INLINE}System.Contnrs, {$ENDIF}\n  ZClasses, ZCompatibility, ZVariant, ZTokenizer, ZExprParser;\n\ntype\n  {** Defines an expression exception. }\n  TZExpressionError = class (Exception);\n\n  {** Defines an execution stack object. }\n  TZExecutionStack = class (TObject)\n  private\n    FValues: TZVariantDynArray;\n    FCount: Integer;\n    FCapacity: Integer;\n\n    function GetValue(Index: Integer): TZVariant;\n  public\n    constructor Create;\n\n    procedure DecStackPointer(const Value : integer);\n    function Pop: TZVariant;\n    function Peek: TZVariant;\n    procedure Push(Value: TZVariant);\n    function GetParameter(Index: Integer): TZVariant;\n    procedure Swap;\n\n    procedure Clear;\n\n    property Count: Integer read FCount;\n    property Values[Index: Integer]: TZVariant read GetValue;\n  end;\n\n  {** Defines a list of variables. }\n  IZVariablesList = interface (IZInterface)\n    ['{F4347F46-32F3-4021-B6DB-7A39BF171275}']\n\n    function GetCount: Integer;\n    function GetName(Index: Integer): string;\n    function GetValue(Index: Integer): TZVariant;\n    procedure SetValue(Index: Integer; const Value: TZVariant);\n    function GetValueByName(const Name: string): TZVariant;\n    procedure SetValueByName(const Name: string; const Value: TZVariant);\n\n    procedure Add(const Name: string; const Value: TZVariant);\n    procedure Remove(const Name: string);\n    function FindByName(const Name: string): Integer;\n\n    procedure ClearValues;\n    procedure Clear;\n\n    property Count: Integer read GetCount;\n    property Names[Index: Integer]: string read GetName;\n    property Values[Index: Integer]: TZVariant read GetValue write SetValue;\n    property NamedValues[const Index: string]: TZVariant read GetValueByName\n      write SetValueByName;\n  end;\n\n  {** Defines a function interface. }\n  IZFunction = interface (IZInterface)\n    ['{E9B3AFF9-6CD9-49C8-AB66-C8CF60ED8686}']\n\n    function GetName: string;\n\n    function Execute(Stack: TZExecutionStack;\n      VariantManager: IZVariantManager): TZVariant;\n\n    property Name: string read GetName;\n  end;\n\n  {** Defines a list of functions. }\n  IZFunctionsList = interface (IZInterface)\n    ['{54453054-F012-475B-84C3-7E5C46187FDB}']\n\n    function GetCount: Integer;\n    function GetName(Index: Integer): string;\n    function GetFunction(Index: Integer): IZFunction;\n\n    procedure Add(Func: IZFunction);\n    procedure Remove(const Name: string);\n    function FindByName(const Name: string): Integer;\n    procedure Clear;\n\n    property Count: Integer read GetCount;\n    property Names[Index: Integer]: string read GetName;\n    property Functions[Index: Integer]: IZFunction read GetFunction;\n  end;\n\n  {** Defines an interface to expression calculator. }\n  IZExpression = interface (IZInterface)\n    ['{26F9D379-5618-446C-8999-D50FBB2F8560}']\n\n    function GetTokenizer: IZTokenizer;\n    procedure SetTokenizer(Value: IZTokenizer);\n    function GetExpression: string;\n    procedure SetExpression(const Value: string);\n    function GetVariantManager: IZVariantManager;\n    procedure SetVariantManager(Value: IZVariantManager);\n    function GetDefaultVariables: IZVariablesList;\n    procedure SetDefaultVariables(Value: IZVariablesList);\n    function GetDefaultFunctions: IZFunctionsList;\n    procedure SetDefaultFunctions(Value: IZFunctionsList);\n    function GetAutoVariables: Boolean;\n    procedure SetAutoVariables(Value: Boolean);\n\n    function Evaluate: TZVariant;\n    function Evaluate2(Variables: IZVariablesList): TZVariant;\n    function Evaluate3(Variables: IZVariablesList;\n      Functions: IZFunctionsList): TZVariant;\n    function Evaluate4(Variables: IZVariablesList;\n      Functions: IZFunctionsList; Stack: TZExecutionStack): TZVariant;\n\n    procedure CreateVariables(Variables: IZVariablesList);\n    procedure Clear;\n\n    property Tokenizer: IZTokenizer read GetTokenizer write SetTokenizer;\n    property Expression: string read GetExpression write SetExpression;\n    property VariantManager: IZVariantManager read GetVariantManager\n      write SetVariantManager;\n    property DefaultVariables: IZVariablesList read GetDefaultVariables\n      write SetDefaultVariables;\n    property DefaultFunctions: IZFunctionsList read GetDefaultFunctions\n      write SetDefaultFunctions;\n    property AutoVariables: Boolean read GetAutoVariables\n      write SetAutoVariables;\n  end;\n\n  {** Implements an expression calculator class. }\n  TZExpression = class (TInterfacedObject, IZExpression)\n  private\n    FTokenizer: IZTokenizer;\n    FDefaultVariables: IZVariablesList;\n    FDefaultFunctions: IZFunctionsList;\n    FVariantManager: IZVariantManager;\n    FParser: TZExpressionParser;\n    FAutoVariables: Boolean;\n\n    function GetTokenizer: IZTokenizer;\n    procedure SetTokenizer(Value: IZTokenizer);\n    function GetExpression: string;\n    procedure SetExpression(const Value: string);\n    function GetVariantManager: IZVariantManager;\n    procedure SetVariantManager(Value: IZVariantManager);\n    function GetDefaultVariables: IZVariablesList;\n    procedure SetDefaultVariables(Value: IZVariablesList);\n    function GetDefaultFunctions: IZFunctionsList;\n    procedure SetDefaultFunctions(Value: IZFunctionsList);\n    function GetAutoVariables: Boolean;\n    procedure SetAutoVariables(Value: Boolean);\n  public\n    constructor Create;\n    constructor CreateWithExpression(const Expression: string);\n    destructor Destroy; override;\n\n    function Evaluate: TZVariant;\n    function Evaluate2(Variables: IZVariablesList): TZVariant;\n    function Evaluate3(Variables: IZVariablesList;\n      Functions: IZFunctionsList): TZVariant;\n    function Evaluate4(Variables: IZVariablesList;\n      Functions: IZFunctionsList; Stack: TZExecutionStack): TZVariant;\n\n    procedure CreateVariables(Variables: IZVariablesList);\n    procedure Clear;\n\n    property Expression: string read GetExpression write SetExpression;\n    property VariantManager: IZVariantManager read GetVariantManager\n      write SetVariantManager;\n    property DefaultVariables: IZVariablesList read GetDefaultVariables\n      write SetDefaultVariables;\n    property DefaultFunctions: IZFunctionsList read GetDefaultFunctions\n      write SetDefaultFunctions;\n    property AutoVariables: Boolean read GetAutoVariables\n      write SetAutoVariables;\n  end;\n\nimplementation\n\nuses\n  ZMessages, ZExprToken, ZVariables, ZFunctions, ZMatchPattern;\n\n{ TZExecutionStack }\n\n{**\n  Creates this object.\n}\nconstructor TZExecutionStack.Create;\nbegin\n  FCapacity := 100;\n  SetLength(FValues, FCapacity);\n  FCount := 0;\nend;\n\n{**\n  Gets a value from absolute position in the stack.\n  @param Index a value index.\n  @returns a variant value from requested position.\n}\nfunction TZExecutionStack.GetValue(Index: Integer): TZVariant;\nbegin\n  Result := FValues[Index];\nend;\n\n{**\n  Gets a value from the top of the stack without removing it.\n  @returns a value from the top.\n}\nfunction TZExecutionStack.Peek: TZVariant;\nbegin\n  if FCount > 0 then\n    Result := FValues[FCount - 1]\n  else Result := NullVariant;\nend;\n\n{**\n  Gets a function parameter by index.\n  @param a function parameter index. O is used for parameter count.\n  @returns a parameter value.\n}\nfunction TZExecutionStack.GetParameter(Index: Integer): TZVariant;\nbegin\n  if FCount <= Index then\n    raise TZExpressionError.Create(SStackIsEmpty);\n  Result := FValues[FCount - Index - 1];\nend;\n\nprocedure TZExecutionStack.DecStackPointer(const Value : integer);\nbegin\n  Dec(FCount, Value);\n  if FCount < 0 then\n  begin\n    FCount := 0;\n    raise TZExpressionError.Create(SStackIsEmpty);\n  end;\nend;\n\n{**\n  Gets a value from the top and removes it from the stack.\n  @returns a value from the top.\n}\nfunction TZExecutionStack.Pop: TZVariant;\nbegin\n  Result := NullVariant;\n  if FCount <= 0 then\n    raise TZExpressionError.Create(SStackIsEmpty);\n  Dec(FCount);\n  Result := FValues[FCount];\nend;\n\n{**\n  Puts a value to the top of the stack.\n}\nprocedure TZExecutionStack.Push(Value: TZVariant);\nbegin\n  if FCapacity = FCount then\n  begin\n    Inc(FCapacity, 64);\n    SetLength(FValues, FCapacity);\n  end;\n  DefVarManager.Assign(Value, FValues[FCount]);\n  Inc(FCount);\nend;\n\n{**\n  Swaps two values on the top of the stack.\n}\nprocedure TZExecutionStack.Swap;\nvar\n  Temp: TZVariant;\nbegin\n  if FCount <= 1 then\n    raise TZExpressionError.Create(SStackIsEmpty);\n\n  Temp := FValues[FCount - 1];\n  FValues[FCount - 1] := FValues[FCount - 2];\n  FValues[FCount - 2] := Temp;\nend;\n\n{**\n  Clears this stack.\n}\nprocedure TZExecutionStack.Clear;\nbegin\n  FCount := 0;\nend;\n\n{ TZExpression }\n\n{**\n  Creates this expression calculator object.\n}\nconstructor TZExpression.Create;\nbegin\n  FTokenizer := TZExpressionTokenizer.Create;\n  FDefaultVariables := TZVariablesList.Create;\n  FDefaultFunctions := TZDefaultFunctionsList.Create;\n  FVariantManager := TZSoftVariantManager.Create;\n  FParser := TZExpressionParser.Create(FTokenizer);\n  FAutoVariables := True;\nend;\n\n{**\n  Creates this expression calculator and assignes expression string.\n  @param Expression an expression string.\n}\nconstructor TZExpression.CreateWithExpression(const Expression: string);\nbegin\n  Create;\n  SetExpression(Expression);\nend;\n\n{**\n  Destroys this object and cleanups the memory.\n}\ndestructor TZExpression.Destroy;\nbegin\n  FTokenizer := nil;\n  FDefaultVariables := nil;\n  FDefaultFunctions := nil;\n  FVariantManager := nil;\n  FParser.Free;\n\n  inherited Destroy;\nend;\n\n{**\n  Gets the current auto variables create flag.\n  @returns the auto variables create flag.\n}\nfunction TZExpression.GetAutoVariables: Boolean;\nbegin\n  Result := FAutoVariables;\nend;\n\n{**\n  Sets a new auto variables create flag.\n  @param value a new auto variables create flag.\n}\nprocedure TZExpression.SetAutoVariables(Value: Boolean);\nbegin\n  FAutoVariables := Value;\nend;\n\n{**\n  Gets a list of default functions.\n  @returns a list of default functions.\n}\nfunction TZExpression.GetDefaultFunctions: IZFunctionsList;\nbegin\n  Result := FDefaultFunctions;\nend;\n\n{**\n  Sets a new list of functions.\n  @param Value a new list of functions.\n}\nprocedure TZExpression.SetDefaultFunctions(Value: IZFunctionsList);\nbegin\n  FDefaultFunctions := Value;\nend;\n\n{**\n  Gets a list of default variables.\n  @returns a list of default variables.\n}\nfunction TZExpression.GetDefaultVariables: IZVariablesList;\nbegin\n  Result := FDefaultVariables;\nend;\n\n{**\n  Sets a new list of variables.\n  @param Value a new list of variables.\n}\nprocedure TZExpression.SetDefaultVariables(Value: IZVariablesList);\nbegin\n  FDefaultVariables := Value;\nend;\n\n{**\n  Gets the current set expression string.\n  @returns the current expression string.\n}\nfunction TZExpression.GetExpression: string;\nbegin\n  Result := FParser.Expression;\nend;\n\n{**\n  Sets a new expression string.\n  @param Value a new expression string.\n}\nprocedure TZExpression.SetExpression(const Value: string);\nbegin\n  FParser.Expression := Value;\n  if FAutoVariables then\n    CreateVariables(FDefaultVariables);\nend;\n\n{**\n  Gets a reference to the current variant manager.\n  @returns a reference to the current variant manager.\n}\nfunction TZExpression.GetVariantManager: IZVariantManager;\nbegin\n  Result := FVariantManager;\nend;\n\n{**\n  Sets a new variant manager.\n  @param Value a new variant manager.\n}\nprocedure TZExpression.SetVariantManager(Value: IZVariantManager);\nbegin\n  FVariantManager := Value;\nend;\n\n{**\n  Gets the current expression tokenizer.\n  @returns the current expression tokenizer.\n}\nfunction TZExpression.GetTokenizer: IZTokenizer;\nbegin\n  Result := FTokenizer;\nend;\n\n{**\n  Sets a new expression tokenizer.\n  @param Value a new expression tokenizer.\n}\nprocedure TZExpression.SetTokenizer(Value: IZTokenizer);\nbegin\n  FTokenizer := Value;\n  FParser.Tokenizer := Value;\nend;\n\n{**\n  Clears this class from all data.\n}\nprocedure TZExpression.Clear;\nbegin\n  FParser.Clear;\n  FDefaultVariables.Clear;\nend;\n\n{**\n  Creates an empty variables.\n  @param Variables a list of variables.\n}\nprocedure TZExpression.CreateVariables(Variables: IZVariablesList);\nvar\n  I: Integer;\n  Name: string;\nbegin\n  for I := 0 to FParser.Variables.Count - 1 do\n  begin\n    Name := FParser.Variables[I];\n    if Variables.FindByName(Name) < 0 then\n      Variables.Add(Name, NullVariant);\n  end;\nend;\n\n{**\n  Evaluates this expression.\n  @returns an evaluated expression value.\n}\nfunction TZExpression.Evaluate: TZVariant;\nbegin\n  Result := Evaluate3(FDefaultVariables, FDefaultFunctions);\nend;\n\n{**\n  Evaluates this expression.\n  @param Variables a list of variables.\n  @returns an evaluated expression value.\n}\nfunction TZExpression.Evaluate2(Variables: IZVariablesList): TZVariant;\nbegin\n  Result := Evaluate3(Variables, FDefaultFunctions);\nend;\n\n{**\n  Evaluates this expression.\n  @param Variables a list of variables.\n  @param Functions a list of functions.\n  @returns an evaluated expression value.\n}\nfunction TZExpression.Evaluate3(Variables: IZVariablesList;\n  Functions: IZFunctionsList): TZVariant;\nvar\n  Stack: TZExecutionStack;\nbegin\n  Stack := TZExecutionStack.Create;\n  try\n    Result := Evaluate4(Variables, Functions, Stack);\n  finally\n    Stack.Free;\n  end;\nend;\n\n{**\n  Evaluates this expression.\n  @param Variables a list of variables.\n  @param Functions a list of functions.\n  @param Stack an execution stack.\n  @returns an evaluated expression value.\n}\nfunction TZExpression.Evaluate4(Variables: IZVariablesList;\n  Functions: IZFunctionsList; Stack: TZExecutionStack): TZVariant;\nvar\n  I, Index, ParamsCount: Integer;\n  Current: TZExpressionToken;\n  Value1, Value2: TZVariant;\nbegin\n  Stack.Clear;\n\n  for I := 0 to FParser.ResultTokens.Count - 1 do\n  begin\n    Current := TZExpressionToken(FParser.ResultTokens[I]);\n    case Current.TokenType of\n      ttConstant:\n        Stack.Push(Current.Value);\n{      ttVariable:\n        begin\n          Index := Variables.FindByName(DefVarManager.GetAsString(Current.Value));\n          if Index < 0 then\n          begin\n            raise TZExpressionError.Create(\n              Format(SVariableWasNotFound, [DefVarManager.GetAsString(Current.Value)]));\n          end;\n          Value1 := Variables.Values[Index];\n          Stack.Push(Value1)\n        end;\n}      ttVariable:\n        begin\n          if Current.Value.VType = vtString then\n          begin\n            Index := Variables.FindByName(Current.Value.VString);\n            if Index < 0 then\n            begin\n              raise TZExpressionError.Create(\n                Format(SVariableWasNotFound, [Current.Value.VString]));\n            end;\n           Current.Value := EncodeInteger(Index);\n          end;\n          if Current.Value.VType = vtInteger then\n            Stack.Push(Variables.Values[Current.Value.VInteger])\n          else\n            raise TZExpressionError.Create(\n                Format(SSyntaxErrorNear, [SoftVarManager.GetAsString(Current.Value)]));\n        end;\n{      ttFunction:\n        begin\n          Index := Functions.FindByName(DefVarManager.GetAsString(Current.Value));\n          if Index < 0 then\n          begin\n            raise TZExpressionError.Create(\n              Format(SFunctionWasNotFound, [DefVarManager.GetAsString(Current.Value)]));\n          end;\n          Value1 := Functions.Functions[Index].Execute(Stack, FVariantManager);\n          ParamsCount := DefVarManager.GetAsInteger(Stack.Pop);\n          while ParamsCount > 0 do\n          begin\n            Stack.Pop;\n            Dec(ParamsCount);\n          end;\n          Stack.Push(Value1);\n        end;\n}      ttFunction:\n        begin\n          if Current.Value.VType = vtString then\n          begin\n            Index := Functions.FindByName(Current.Value.VString);\n            if Index < 0 then\n            begin\n              raise TZExpressionError.Create(\n                Format(SFunctionWasNotFound, [Current.Value.VString]));\n            end;\n            Current.Value := EncodeInterface(Functions.Functions[Index]);\n          end;\n          if Current.Value.VType = vtInterface then\n          begin\n            Value1 := IZFunction(Current.Value.VInterface).Execute(Stack, FVariantManager);\n            ParamsCount := DefVarManager.GetAsInteger(Stack.Pop);\n            Stack.DecStackPointer(ParamsCount);\n            Stack.Push(Value1);\n          end\n          else\n            raise TZExpressionError.Create(\n                Format(SSyntaxErrorNear, [SoftVarManager.GetAsString(Current.Value)]));\n        end;\n      ttAnd:\n        begin\n          Value2 := Stack.Pop;\n          Value1 := Stack.Pop;\n          Stack.Push(FVariantManager.OpAnd(Value1, Value2));\n        end;\n      ttOr:\n        begin\n          Value2 := Stack.Pop;\n          Value1 := Stack.Pop;\n          Stack.Push(FVariantManager.OpOr(Value1, Value2));\n        end;\n      ttXor:\n        begin\n          Value2 := Stack.Pop;\n          Value1 := Stack.Pop;\n          Stack.Push(FVariantManager.OpXor(Value1, Value2));\n        end;\n      ttNot:\n        Stack.Push(FVariantManager.OpNot(Stack.Pop));\n      ttPlus:\n        begin\n          Value2 := Stack.Pop;\n          Value1 := Stack.Pop;\n          Stack.Push(FVariantManager.OpAdd(Value1, Value2));\n        end;\n      ttMinus:\n        begin\n          Value2 := Stack.Pop;\n          Value1 := Stack.Pop;\n          Stack.Push(FVariantManager.OpSub(Value1, Value2));\n        end;\n      ttStar:\n        begin\n          Value2 := Stack.Pop;\n          Value1 := Stack.Pop;\n          Stack.Push(FVariantManager.OpMul(Value1, Value2));\n        end;\n      ttSlash:\n        begin\n          Value2 := Stack.Pop;\n          Value1 := Stack.Pop;\n          Stack.Push(FVariantManager.OpDiv(Value1, Value2));\n        end;\n      ttProcent:\n        begin\n          Value2 := Stack.Pop;\n          Value1 := Stack.Pop;\n          Stack.Push(FVariantManager.OpMod(Value1, Value2));\n        end;\n      ttEqual:\n        begin\n          Value2 := Stack.Pop;\n          Value1 := Stack.Pop;\n          Stack.Push(FVariantManager.OpEqual(Value1, Value2));\n        end;\n      ttNotEqual:\n        begin\n          Value2 := Stack.Pop;\n          Value1 := Stack.Pop;\n          Stack.Push(FVariantManager.OpNotEqual(Value1, Value2));\n        end;\n      ttMore:\n        begin\n          Value2 := Stack.Pop;\n          Value1 := Stack.Pop;\n          Stack.Push(FVariantManager.OpMore(Value1, Value2));\n        end;\n      ttLess:\n        begin\n          Value2 := Stack.Pop;\n          Value1 := Stack.Pop;\n          Stack.Push(FVariantManager.OpLess(Value1, Value2));\n        end;\n      ttEqualMore:\n        begin\n          Value2 := Stack.Pop;\n          Value1 := Stack.Pop;\n          Stack.Push(FVariantManager.OpMoreEqual(Value1, Value2));\n        end;\n      ttEqualLess:\n        begin\n          Value2 := Stack.Pop;\n          Value1 := Stack.Pop;\n          Stack.Push(FVariantManager.OpLessEqual(Value1, Value2));\n        end;\n      ttPower:\n        begin\n          Value2 := Stack.Pop;\n          Value1 := Stack.Pop;\n          Stack.Push(FVariantManager.OpPow(Value1, Value2));\n        end;\n      ttUnary:\n        Stack.Push(FVariantManager.OpNegative(Stack.Pop));\n      ttLike:\n        begin\n          Value2 := Stack.Pop;\n          Value1 := Stack.Pop;\n          Stack.Push(EncodeBoolean(\n                       IsMatch(FVariantManager.GetAsString(Value2),\n                               FVariantManager.GetAsString(Value1))));\n        end;\n      ttNotLike:\n        begin\n          Value2 := Stack.Pop;\n          Value1 := Stack.Pop;\n          Stack.Push(EncodeBoolean(\n                       not IsMatch(FVariantManager.GetAsString(Value2),\n                                   FVariantManager.GetAsString(Value1))));\n        end;\n      ttIsNull:\n        begin\n          Value1 := Stack.Pop;\n          Stack.Push(EncodeBoolean(FVariantManager.IsNull(Value1)));\n        end;\n      ttIsNotNull:\n        begin\n          Value1 := Stack.Pop;\n          Stack.Push(EncodeBoolean(not FVariantManager.IsNull(Value1)));\n        end;\n      else\n        raise TZExpressionError.Create(SInternalError);\n    end;\n  end;\n\n  if Stack.Count <> 1 then\n    raise TZExpressionError.Create(SInternalError);\n  Result := Stack.Pop;\nend;\n\nend.\n"
  },
  {
    "path": "lib/zeosdbo/src/core/ZFunctions.pas",
    "content": "{*********************************************************}\n{                                                         }\n{                 Zeos Database Objects                   }\n{             Variables classes and interfaces            }\n{                                                         }\n{           Originally written by Sergey Seroukhov        }\n{                                                         }\n{*********************************************************}\n\n{@********************************************************}\n{    Copyright (c) 1999-2012 Zeos Development Group       }\n{                                                         }\n{ License Agreement:                                      }\n{                                                         }\n{ This library is distributed in the hope that it will be }\n{ useful, but WITHOUT ANY WARRANTY; without even the      }\n{ implied warranty of MERCHANTABILITY or FITNESS FOR      }\n{ A PARTICULAR PURPOSE.  See the GNU Lesser General       }\n{ Public License for more details.                        }\n{                                                         }\n{ The source code of the ZEOS Libraries and packages are  }\n{ distributed under the Library GNU General Public        }\n{ License (see the file COPYING / COPYING.ZEOS)           }\n{ with the following  modification:                       }\n{ As a special exception, the copyright holders of this   }\n{ library give you permission to link this library with   }\n{ independent modules to produce an executable,           }\n{ regardless of the license terms of these independent    }\n{ modules, and to copy and distribute the resulting       }\n{ executable under terms of your choice, provided that    }\n{ you also meet, for each linked independent module,      }\n{ the terms and conditions of the license of that module. }\n{ An independent module is a module which is not derived  }\n{ from or based on this library. If you modify this       }\n{ library, you may extend this exception to your version  }\n{ of the library, but you are not obligated to do so.     }\n{ If you do not wish to do so, delete this exception      }\n{ statement from your version.                            }\n{                                                         }\n{                                                         }\n{ The project web site is located on:                     }\n{   http://zeos.firmos.at  (FORUM)                        }\n{   http://sourceforge.net/p/zeoslib/tickets/ (BUGTRACKER)}\n{   svn://svn.code.sf.net/p/zeoslib/code-0/trunk (SVN)    }\n{                                                         }\n{   http://www.sourceforge.net/projects/zeoslib.          }\n{                                                         }\n{                                                         }\n{                                 Zeos Development Group. }\n{********************************************************@}\n\nunit ZFunctions;\n\ninterface\n\n{$I ZCore.inc}\n\nuses SysUtils, Classes, ZClasses, ZCollections, ZCompatibility, ZVariant,\n  ZExpression;\n\ntype\n\n  {** Implements a list of functions. }\n\n  { TZFunctionsList }\n\n  TZFunctionsList = class (TInterfacedObject, IZFunctionsList)\n  private\n    FFunctions: IZCollection;\n    FCapacity : Integer;\n    FKeys     : Array of LongInt;\n\n    procedure SetKeyCapacity(const NewCapacity : Integer);\n    procedure SetKey(const aKey : LongInt; const aPosition : Integer);\n    procedure RegenerateKey(const aPosition : Integer);\n    procedure RegenerateKeys;\n  protected\n    property Functions: IZCollection read FFunctions write FFunctions;\n    function FindByKeyAndName(const aKey : LongInt; const aName: string): Integer;\n  public\n    constructor Create;\n    destructor Destroy; override;\n\n    function GetCount: Integer;\n    function GetName(Index: Integer): string;\n    function GetFunction(Index: Integer): IZFunction;\n\n    procedure Add(Func: IZFunction);\n    procedure Remove(const Name: string);\n    function FindByName(const Name: string): Integer;\n\n    procedure Clear;\n  end;\n\n  {** Implements an abstract function. }\n\n  { TZAbstractFunction }\n\n  TZAbstractFunction = class (TInterfacedObject, IZFunction)\n  private\n    FName: string;\n  protected\n    function GetName: string;\n    function CheckParamsCount(Stack: TZExecutionStack;\n      ExpectedCount: Integer): Integer;\n  public\n    constructor Create(aName : string);\n    function Execute(Stack: TZExecutionStack;\n      VariantManager: IZVariantManager): TZVariant; virtual; abstract;\n\n    property Name: string read GetName;\n  end;\n\n  {** Implements a default function list. }\n  TZDefaultFunctionsList = class (TZFunctionsList)\n  public\n    constructor Create;\n  end;\n\nimplementation\n\nuses ZMessages, ZFunctionsMath, ZFunctionsDateTime, ZFunctionsStrings,\n     ZFunctionsConvert, ZFunctionsOther;\n\n{ TZFunctionsList }\n\n{**\n  Constructs this object.\n}\nconstructor TZFunctionsList.Create;\nbegin\n  FFunctions := TZCollection.Create;\n  SetKeyCapacity(0);\nend;\n\n{**\n  Destroys this object and cleanup the memory.\n}\ndestructor TZFunctionsList.Destroy;\nbegin\n  SetKeyCapacity(0);\n  FFunctions := nil;\n  inherited Destroy;\nend;\n\n{**\n  Sets the capacity of the internal Keystorage.\n}\nprocedure TZFunctionsList.SetKeyCapacity(const NewCapacity : Integer);\nbegin\n  if NewCapacity <> FCapacity then\n  begin\n    SetLength(FKeys, NewCapacity);\n    FCapacity := NewCapacity;\n  end;\nend;\n\n{**\n  Sets a key to the Keystorage\n}\nprocedure TZFunctionsList.SetKey(const aKey : LongInt; const aPosition : Integer);\nbegin\n  if aPosition >= FCapacity then\n    SetKeyCapacity(FCapacity+16);\n  FKeys[aPosition] := aKey\nend;\n\n{**\n  Regenerates a given key\n}\nprocedure TZFunctionsList.RegenerateKey(const aPosition : Integer);\n\nbegin\n  SetKey(Hash({$IFDEF UNICODE}AnsiString{$ENDIF}((FFunctions[aPosition] as IZFunction).Name)), aPosition);\nend;\n\n{**\n  Regenerates all keys\n}\nprocedure TZFunctionsList.RegenerateKeys;\n\nvar\n  I       : Integer;\n\nbegin\n  SetKeyCapacity(0);\n  for I := 0 to FFunctions.Count - 1 do\n    RegenerateKey(i);\nend;\n\n{**\n  Finds a function reference by its Name and Hashkey\n}\nfunction TZFunctionsList.FindByKeyAndName(const aKey : LongInt; const aName: string): Integer;\n\nvar\n  I: Integer;\n\nbegin\n  Result := -1;\n  for I := 0 to FFunctions.Count - 1 do\n  begin\n    if aKey = FKeys[i] then\n    begin\n      if aName = (FFunctions[I] as IZFunction).Name then\n      begin\n        Result := I;\n        Break;\n      end;\n    end;\n  end;\nend;\n\n{**\n  Finds a function reference\n}\nfunction TZFunctionsList.FindByName(const Name: string): Integer;\nvar\n  aName: string;\n\nbegin\n  aName := Uppercase(Name);\n  Result := FindByKeyAndName(Hash({$IFDEF UNICODE}AnsiString{$ENDIF}(aName)), aName);\nend;\n\n{**\n  Adds a new function to this list.\n  @param Func a function reference.\n}\nprocedure TZFunctionsList.Add(Func: IZFunction);\nvar\n  Index: Integer;\n  aKey : LongInt;\n  aName: string;\n\nbegin\n  aName := Uppercase(Func.Name);\n  aKey  := Hash({$IFDEF UNICODE}AnsiString{$ENDIF}(aName));\n  Index := FindByKeyAndName(aKey, aName);\n  if Index < 0 then\n  begin\n    FFunctions.Add(Func);\n    SetKey(aKey, FFunctions.Count-1);\n  end\n  else\n    raise TZExpressionError.Create('Function '+Func.Name+' already defined!');\nend;\n\n{**\n  Removes a reference to a function by it's name.\n  @param Name a name of the function to be removed.\n}\nprocedure TZFunctionsList.Remove(const Name: string);\nvar\n  Index: Integer;\nbegin\n  Index := FindByName(Name);\n  if Index >= 0 then\n  begin\n    FFunctions.Delete(Index);\n    RegenerateKeys;\n  end;\nend;\n\n{**\n  Cleans the list of registered functions.\n}\nprocedure TZFunctionsList.Clear;\nbegin\n  FFunctions.Clear;\n  SetKeyCapacity(0);\nend;\n\n{**\n  Gets a number of registered functions.\n  @returns a number of registered functions.\n}\nfunction TZFunctionsList.GetCount: Integer;\nbegin\n  Result := FFunctions.Count;\nend;\n\n{**\n  Gets a function reference by it's index.\n  @param Index a function index.\n  @returns a function reference.\n}\nfunction TZFunctionsList.GetFunction(Index: Integer): IZFunction;\nbegin\n  Result := FFunctions[Index] as IZFunction;\nend;\n\n{**\n  Gets a name of the functions by it's index.\n  @param Index a functon index.\n  @returns a name of the function.\n}\nfunction TZFunctionsList.GetName(Index: Integer): string;\nbegin\n  Result := (FFunctions[Index] as IZFunction).Name;\nend;\n\n{ TZDefaultFunctionsList }\n\n{**\n  Constructs a default functions list and adds all available\n  standard functions.\n}\nconstructor TZDefaultFunctionsList.Create;\nbegin\n  inherited Create;\n  AddMathFunctions(Self);\n  AddStringFunctions(Self);\n  AddConvertFunctions(Self);\n  AddOtherFunctions(Self);\n  AddDateTimeFunctions(Self);\nend;\n\n{ TZAbstractFunction }\n\n{**\n  Creates the function with a user defined name.\n}\nconstructor TZAbstractFunction.Create(aName : string);\nbegin\n  inherited Create;\n  FName := UpperCase(aName);\nend;\n\n{**\n  Gets the assigned function name.\n  @returns the assigned function name.\n}\nfunction TZAbstractFunction.GetName: string;\nbegin\n  Result := FName;\nend;\n\n{**\n  Checks the function parameter count number.\n  @param Stack a stack object.\n  @param ExpectedCount a number of expected parameters.\n  @returns a real number of parameters.\n}\nfunction TZAbstractFunction.CheckParamsCount(Stack: TZExecutionStack;\n  ExpectedCount: Integer): Integer;\nbegin\n  Result := DefVarManager.GetAsInteger(Stack.GetParameter(0));\n  if Result <> ExpectedCount then\n  begin\n    raise TZExpressionError.Create(Format(SParametersError,\n      [ExpectedCount, Result]));\n  end;\nend;\n\nend.\n\n"
  },
  {
    "path": "lib/zeosdbo/src/core/ZFunctionsConvert.pas",
    "content": "{*********************************************************}\n{                                                         }\n{                 Zeos Database Objects                   }\n{             Variables classes and interfaces            }\n{                                                         }\n{           Originally written by Sergey Seroukhov        }\n{                                                         }\n{*********************************************************}\n\n{@********************************************************}\n{    Copyright (c) 1999-2012 Zeos Development Group       }\n{                                                         }\n{ License Agreement:                                      }\n{                                                         }\n{ This library is distributed in the hope that it will be }\n{ useful, but WITHOUT ANY WARRANTY; without even the      }\n{ implied warranty of MERCHANTABILITY or FITNESS FOR      }\n{ A PARTICULAR PURPOSE.  See the GNU Lesser General       }\n{ Public License for more details.                        }\n{                                                         }\n{ The source code of the ZEOS Libraries and packages are  }\n{ distributed under the Library GNU General Public        }\n{ License (see the file COPYING / COPYING.ZEOS)           }\n{ with the following  modification:                       }\n{ As a special exception, the copyright holders of this   }\n{ library give you permission to link this library with   }\n{ independent modules to produce an executable,           }\n{ regardless of the license terms of these independent    }\n{ modules, and to copy and distribute the resulting       }\n{ executable under terms of your choice, provided that    }\n{ you also meet, for each linked independent module,      }\n{ the terms and conditions of the license of that module. }\n{ An independent module is a module which is not derived  }\n{ from or based on this library. If you modify this       }\n{ library, you may extend this exception to your version  }\n{ of the library, but you are not obligated to do so.     }\n{ If you do not wish to do so, delete this exception      }\n{ statement from your version.                            }\n{                                                         }\n{                                                         }\n{ The project web site is located on:                     }\n{   http://zeos.firmos.at  (FORUM)                        }\n{   http://sourceforge.net/p/zeoslib/tickets/ (BUGTRACKER)}\n{   svn://svn.code.sf.net/p/zeoslib/code-0/trunk (SVN)    }\n{                                                         }\n{   http://www.sourceforge.net/projects/zeoslib.          }\n{                                                         }\n{                                                         }\n{                                 Zeos Development Group. }\n{********************************************************@}\n\nunit ZFunctionsConvert;\n\ninterface\n\n{$I ZCore.inc}\n\nuses\n  SysUtils, ZFunctions, ZExpression, ZVariant;\n\n{**  Conversion functions }\n\ntype\n\n{**  Str <> Float}\n  {** Implements a VAL function. }\n  TZValFunction = class (TZAbstractFunction)\n  public\n    function Execute(Stack: TZExecutionStack;\n      VariantManager: IZVariantManager): TZVariant; override;\n  end;\n\n{**  Str <> Date}\n  {** Implements a CTOD function. }\n  TZCtodFunction = class (TZAbstractFunction)\n  public\n    function Execute(Stack: TZExecutionStack;\n      VariantManager: IZVariantManager): TZVariant; override;\n  end;\n\n  {** Implements a DTOS function. }\n  TZDtosFunction = class (TZAbstractFunction)\n  public\n    function Execute(Stack: TZExecutionStack;\n      VariantManager: IZVariantManager): TZVariant; override;\n  end;\n\n  {** Implements a DTOS function. }\n  TZFormatDateTimeFunction = class (TZAbstractFunction)\n  public\n    function Execute(Stack: TZExecutionStack;\n      VariantManager: IZVariantManager): TZVariant; override;\n  end;\n\nprocedure AddConvertFunctions(Functions : TZFunctionsList);\n\nimplementation\n\nvar\n  InternalDefaultFormatSettings : TFormatSettings;\n\n{*******\n    DefaultFormatSettings : TFormatSettings = (\n    CurrencyFormat: 1;\n    NegCurrFormat: 5;\n    ThousandSeparator: ',';\n    DecimalSeparator: '.';\n    CurrencyDecimals: 2;\n    DateSeparator: '-';\n    TimeSeparator: ':';\n    ListSeparator: ',';\n    CurrencyString: '$';\n    ShortDateFormat: 'd/m/y';\n    LongDateFormat: 'dd\" \"mmmm\" \"yyyy';\n    TimeAMString: 'AM';\n    TimePMString: 'PM';\n    ShortTimeFormat: 'hh:nn';\n    LongTimeFormat: 'hh:nn:ss';\n    ShortMonthNames: ('Jan','Feb','Mar','Apr','May','Jun',\n                      'Jul','Aug','Sep','Oct','Nov','Dec');\n    LongMonthNames: ('January','February','March','April','May','June',\n                     'July','August','September','October','November','December');\n    ShortDayNames: ('Sun','Mon','Tue','Wed','Thu','Fri','Sat');\n    LongDayNames:  ('Sunday','Monday','Tuesday','Wednesday','Thursday','Friday','Saturday');\n    TwoDigitYearCenturyWindow: 50;\n  );\n******}\n\n { TZValFunction }\n\nfunction TZValFunction.Execute(Stack: TZExecutionStack;\n  VariantManager: IZVariantManager): TZVariant;\nbegin\n  CheckParamsCount(Stack, 1);\n  VariantManager.SetAsFloat(Result, StrToFloatDef(Stack.GetParameter(1).VString, 0, InternalDefaultFormatSettings));\nend;\n\n{ TZCtodFunction }\n\nfunction TZCtodFunction.Execute(Stack: TZExecutionStack;\n  VariantManager: IZVariantManager): TZVariant;\nvar\n  Value: TZVariant;\nbegin\n  CheckParamsCount(Stack, 1);\n  Value := Stack.GetParameter(1);\n  VariantManager.SetAsDateTime(Result, StrToDateDef(Value.VString, 0));\nend;\n\n{ TZDtosFunction }\n\nfunction TZDtosFunction.Execute(Stack: TZExecutionStack;\n  VariantManager: IZVariantManager): TZVariant;\nvar\n  Value: TZVariant;\nbegin\n  CheckParamsCount(Stack, 1);\n  Value := Stack.GetParameter(1);\n  VariantManager.SetAsString(Result, FormatDateTime('yyyymmdd', Value.VDateTime));\nend;\n\n{ TZFormatDateTimeFunction }\n\nfunction TZFormatDateTimeFunction.Execute(Stack: TZExecutionStack;\n  VariantManager: IZVariantManager): TZVariant;\nbegin\n  CheckParamsCount(Stack, 2);\n  VariantManager.SetAsString(Result, FormatDateTime(Stack.GetParameter(2).VString, Stack.GetParameter(1).VDateTime));\nend;\n\nprocedure AddConvertFunctions(Functions : TZFunctionsList);\nbegin\n  Functions.Add(TZValFunction.Create('VAL'));\n  Functions.Add(TZDtosFunction.Create('DTOS'));\n  Functions.Add(TZCtodFunction.Create('CTOD'));\n  Functions.Add(TZFormatDateTimeFunction.Create('FORMATDATETIME'));\nend;\n\ninitialization\n//  InternalDefaultFormatSettings := DefaultFormatSettings;\n  InternalDefaultFormatSettings.ThousandSeparator   := ',';\n  InternalDefaultFormatSettings.DecimalSeparator    := '.';\nend.\n"
  },
  {
    "path": "lib/zeosdbo/src/core/ZFunctionsDateTime.pas",
    "content": "{*********************************************************}\n{                                                         }\n{                 Zeos Database Objects                   }\n{             Variables classes and interfaces            }\n{                                                         }\n{           Originally written by Sergey Seroukhov        }\n{                                                         }\n{*********************************************************}\n\n{@********************************************************}\n{    Copyright (c) 1999-2012 Zeos Development Group       }\n{                                                         }\n{ License Agreement:                                      }\n{                                                         }\n{ This library is distributed in the hope that it will be }\n{ useful, but WITHOUT ANY WARRANTY; without even the      }\n{ implied warranty of MERCHANTABILITY or FITNESS FOR      }\n{ A PARTICULAR PURPOSE.  See the GNU Lesser General       }\n{ Public License for more details.                        }\n{                                                         }\n{ The source code of the ZEOS Libraries and packages are  }\n{ distributed under the Library GNU General Public        }\n{ License (see the file COPYING / COPYING.ZEOS)           }\n{ with the following  modification:                       }\n{ As a special exception, the copyright holders of this   }\n{ library give you permission to link this library with   }\n{ independent modules to produce an executable,           }\n{ regardless of the license terms of these independent    }\n{ modules, and to copy and distribute the resulting       }\n{ executable under terms of your choice, provided that    }\n{ you also meet, for each linked independent module,      }\n{ the terms and conditions of the license of that module. }\n{ An independent module is a module which is not derived  }\n{ from or based on this library. If you modify this       }\n{ library, you may extend this exception to your version  }\n{ of the library, but you are not obligated to do so.     }\n{ If you do not wish to do so, delete this exception      }\n{ statement from your version.                            }\n{                                                         }\n{                                                         }\n{ The project web site is located on:                     }\n{   http://zeos.firmos.at  (FORUM)                        }\n{   http://sourceforge.net/p/zeoslib/tickets/ (BUGTRACKER)}\n{   svn://svn.code.sf.net/p/zeoslib/code-0/trunk (SVN)    }\n{                                                         }\n{   http://www.sourceforge.net/projects/zeoslib.          }\n{                                                         }\n{                                                         }\n{                                 Zeos Development Group. }\n{********************************************************@}\n\nunit ZFunctionsDateTime;\n\ninterface\n\n{$I ZCore.inc}\n\nuses\n  SysUtils, ZFunctions, ZExpression, ZVariant;\n\n{** Date & time functions}\n\ntype\n  {** Implements a DATE function. }\n  TZDateFunction = class (TZAbstractFunction)\n  public\n    function Execute(Stack: TZExecutionStack;\n      VariantManager: IZVariantManager): TZVariant; override;\n  end;\n\n  {** Implements a TIME function. }\n  TZTimeFunction = class (TZAbstractFunction)\n  public\n    function Execute(Stack: TZExecutionStack;\n      VariantManager: IZVariantManager): TZVariant; override;\n  end;\n\n  {** Implements a NOW function. }\n  TZNowFunction = class (TZAbstractFunction)\n  public\n    function Execute(Stack: TZExecutionStack;\n      VariantManager: IZVariantManager): TZVariant; override;\n  end;\n\n  {** Implements a ENCODEDATE function. }\n  TZEncodeDateFunction = class (TZAbstractFunction)\n  public\n    function Execute(Stack: TZExecutionStack;\n      VariantManager: IZVariantManager): TZVariant; override;\n  end;\n\n  {** Implements a ENCODETIME function. }\n  TZEncodeTimeFunction = class (TZAbstractFunction)\n  public\n    function Execute(Stack: TZExecutionStack;\n      VariantManager: IZVariantManager): TZVariant; override;\n  end;\n\n  {** Implements a COMPOSEDATETIME function. }\n\n  { TZComposeDateTimeFunction }\n\n  TZComposeDateTimeFunction = class (TZAbstractFunction)\n  public\n    function Execute(Stack: TZExecutionStack;\n      VariantManager: IZVariantManager): TZVariant; override;\n  end;\n\n  {** Implements a INCDATE function. }\n  TZIncDateFunction = class (TZAbstractFunction)\n  public\n    function Execute(Stack: TZExecutionStack;\n      VariantManager: IZVariantManager): TZVariant; override;\n  end;\n\n  {** Implements a INCTIME function. }\n  TZIncTimeFunction = class (TZAbstractFunction)\n  public\n    function Execute(Stack: TZExecutionStack;\n      VariantManager: IZVariantManager): TZVariant; override;\n  end;\n\n  {** Implements a ISLEAPYEAR function. }\n  TZIsLeapYearFunction = class (TZAbstractFunction)\n  public\n    function Execute(Stack: TZExecutionStack;\n      VariantManager: IZVariantManager): TZVariant; override;\n  end;\n\n{-------------------- Extracting functions ----------------------------}\n  {** Implements a DATEOF function. }\n  TZDateOfFunction = class (TZAbstractFunction)\n  public\n    function Execute(Stack: TZExecutionStack;\n      VariantManager: IZVariantManager): TZVariant; override;\n  end;\n\n  {** Implements a TIMEOF function. }\n  TZTimeOfFunction = class (TZAbstractFunction)\n  public\n    function Execute(Stack: TZExecutionStack;\n      VariantManager: IZVariantManager): TZVariant; override;\n  end;\n\n  {** Implements a YEAROF function. }\n  TZYearOfFunction = class (TZAbstractFunction)\n  public\n    function Execute(Stack: TZExecutionStack;\n      VariantManager: IZVariantManager): TZVariant; override;\n  end;\n\n  {** Implements a MONTHOF function. }\n  TZMonthOfFunction = class (TZAbstractFunction)\n  public\n    function Execute(Stack: TZExecutionStack;\n      VariantManager: IZVariantManager): TZVariant; override;\n  end;\n\n  {** Implements a DAYOF function. }\n  TZDayOfFunction = class (TZAbstractFunction)\n  public\n    function Execute(Stack: TZExecutionStack;\n      VariantManager: IZVariantManager): TZVariant; override;\n  end;\n\n  {** Implements a HOUROF function. }\n  TZHourOfFunction = class (TZAbstractFunction)\n  public\n    function Execute(Stack: TZExecutionStack;\n      VariantManager: IZVariantManager): TZVariant; override;\n  end;\n\n  {** Implements a MINUTEOF function. }\n  TZMinuteOfFunction = class (TZAbstractFunction)\n  public\n    function Execute(Stack: TZExecutionStack;\n      VariantManager: IZVariantManager): TZVariant; override;\n  end;\n\n  {** Implements a SECONDOF function. }\n  TZSecondOfFunction = class (TZAbstractFunction)\n  public\n    function Execute(Stack: TZExecutionStack;\n      VariantManager: IZVariantManager): TZVariant; override;\n  end;\n\n  {** Implements a MILLISECONDOF function. }\n  TZMilliSecondOfFunction = class (TZAbstractFunction)\n  public\n    function Execute(Stack: TZExecutionStack;\n      VariantManager: IZVariantManager): TZVariant; override;\n  end;\n\n{-------------------- *OFTHEYEAR Extracting functions ----------------------------}\n  {** Implements a WEEKOFTHEYEAR function. }\n  TZWeekOfTheYearFunction = class (TZAbstractFunction)\n  public\n    function Execute(Stack: TZExecutionStack;\n      VariantManager: IZVariantManager): TZVariant; override;\n  end;\n\n  {** Implements a DAYOFTHEYEAR function. }\n  TZDayOfTheYearFunction = class (TZAbstractFunction)\n  public\n    function Execute(Stack: TZExecutionStack;\n      VariantManager: IZVariantManager): TZVariant; override;\n  end;\n\n  {** Implements a HOUROFTHEYEAR function. }\n  TZHourOfTheYearFunction = class (TZAbstractFunction)\n  public\n    function Execute(Stack: TZExecutionStack;\n      VariantManager: IZVariantManager): TZVariant; override;\n  end;\n\n  {** Implements a MINUTEOFTHEYEAR function. }\n  TZMinuteOfTheYearFunction = class (TZAbstractFunction)\n  public\n    function Execute(Stack: TZExecutionStack;\n      VariantManager: IZVariantManager): TZVariant; override;\n  end;\n\n  {** Implements a SECONDOFTHEYEAR function. }\n  TZSecondOfTheYearFunction = class (TZAbstractFunction)\n  public\n    function Execute(Stack: TZExecutionStack;\n      VariantManager: IZVariantManager): TZVariant; override;\n  end;\n\n  {** Implements a MILLISECONDOFTHEYEAR function. }\n  TZMilliSecondOfTheYearFunction = class (TZAbstractFunction)\n  public\n    function Execute(Stack: TZExecutionStack;\n      VariantManager: IZVariantManager): TZVariant; override;\n  end;\n\n{-------------------- *OFTHEMONTH Extracting functions ----------------------------}\n  {** Implements a WEEKOFTHEMONTH function. }\n  TZWeekOfTheMonthFunction = class (TZAbstractFunction)\n  public\n    function Execute(Stack: TZExecutionStack;\n      VariantManager: IZVariantManager): TZVariant; override;\n  end;\n\n  {** Implements a HOUROFTHEMONTH function. }\n  TZHourOfTheMonthFunction = class (TZAbstractFunction)\n  public\n    function Execute(Stack: TZExecutionStack;\n      VariantManager: IZVariantManager): TZVariant; override;\n  end;\n\n  {** Implements a MINUTEOFTHEMONTH function. }\n  TZMinuteOfTheMonthFunction = class (TZAbstractFunction)\n  public\n    function Execute(Stack: TZExecutionStack;\n      VariantManager: IZVariantManager): TZVariant; override;\n  end;\n\n  {** Implements a SECONDOFTHEMONTH function. }\n  TZSecondOfTheMonthFunction = class (TZAbstractFunction)\n  public\n    function Execute(Stack: TZExecutionStack;\n      VariantManager: IZVariantManager): TZVariant; override;\n  end;\n\n  {** Implements a MILLISECONDOFTHEMONTH function. }\n  TZMilliSecondOfTheMonthFunction = class (TZAbstractFunction)\n  public\n    function Execute(Stack: TZExecutionStack;\n      VariantManager: IZVariantManager): TZVariant; override;\n  end;\n\n{-------------------- *OFTHEWEEK Extracting functions ----------------------------}\n  {** Implements a DAYOfTheWeek function. }\n  TZDayOfTheWeekFunction = class (TZAbstractFunction)\n  public\n    function Execute(Stack: TZExecutionStack;\n      VariantManager: IZVariantManager): TZVariant; override;\n  end;\n\n  {** Implements a HOUROfTheWeek function. }\n  TZHourOfTheWeekFunction = class (TZAbstractFunction)\n  public\n    function Execute(Stack: TZExecutionStack;\n      VariantManager: IZVariantManager): TZVariant; override;\n  end;\n\n  {** Implements a MINUTEOfTheWeek function. }\n  TZMinuteOfTheWeekFunction = class (TZAbstractFunction)\n  public\n    function Execute(Stack: TZExecutionStack;\n      VariantManager: IZVariantManager): TZVariant; override;\n  end;\n\n  {** Implements a SECONDOfTheWeek function. }\n  TZSecondOfTheWeekFunction = class (TZAbstractFunction)\n  public\n    function Execute(Stack: TZExecutionStack;\n      VariantManager: IZVariantManager): TZVariant; override;\n  end;\n\n  {** Implements a MILLISECONDOfTheWeek function. }\n  TZMilliSecondOfTheWeekFunction = class (TZAbstractFunction)\n  public\n    function Execute(Stack: TZExecutionStack;\n      VariantManager: IZVariantManager): TZVariant; override;\n  end;\n\n\n{---------------- *OFTHEDAY Extracting functions --------------------}\n  {** Implements a MINUTEOFTHEDAY function. }\n  TZMinuteOfTheDayFunction = class (TZAbstractFunction)\n  public\n    function Execute(Stack: TZExecutionStack;\n      VariantManager: IZVariantManager): TZVariant; override;\n  end;\n\n  {** Implements a SECONDOFTHEDAY function. }\n  TZSecondOfTheDayFunction = class (TZAbstractFunction)\n  public\n    function Execute(Stack: TZExecutionStack;\n      VariantManager: IZVariantManager): TZVariant; override;\n  end;\n\n  {** Implements a MILLISECONDOFTHEDAY function. }\n  TZMilliSecondOfTheDayFunction = class (TZAbstractFunction)\n  public\n    function Execute(Stack: TZExecutionStack;\n      VariantManager: IZVariantManager): TZVariant; override;\n  end;\n\n{---------------- *OfTheHour Extracting functions --------------------}\n  {** Implements a SECONDOFTHEHOUR function. }\n  TZSecondOfTheHourFunction = class (TZAbstractFunction)\n  public\n    function Execute(Stack: TZExecutionStack;\n      VariantManager: IZVariantManager): TZVariant; override;\n  end;\n\n  {** Implements a MILLISECONDOFTHEHOUR function. }\n  TZMilliSecondOfTheHourFunction = class (TZAbstractFunction)\n  public\n    function Execute(Stack: TZExecutionStack;\n      VariantManager: IZVariantManager): TZVariant; override;\n  end;\n\n{---------------- *OFTHEMINUTE Extracting functions --------------------}\n  {** Implements a MILLISECONDOfTheHour function. }\n  TZMilliSecondOfTheMinuteFunction = class (TZAbstractFunction)\n  public\n    function Execute(Stack: TZExecutionStack;\n      VariantManager: IZVariantManager): TZVariant; override;\n  end;\n\n{---------------- *BETWEEN functions --------------------}\n  {** Implements a YEARSBETWEEN function. }\n  TZYearsBetweenFunction = class (TZAbstractFunction)\n  public\n    function Execute(Stack: TZExecutionStack;\n      VariantManager: IZVariantManager): TZVariant; override;\n  end;\n\n  {** Implements a MONTHSBETWEEN function. }\n  TZMonthsBetweenFunction = class (TZAbstractFunction)\n  public\n    function Execute(Stack: TZExecutionStack;\n      VariantManager: IZVariantManager): TZVariant; override;\n  end;\n\n  {** Implements a WEEKSBETWEEN function. }\n  TZWeeksBetweenFunction = class (TZAbstractFunction)\n  public\n    function Execute(Stack: TZExecutionStack;\n      VariantManager: IZVariantManager): TZVariant; override;\n  end;\n\n  {** Implements a DAYSBETWEEN function. }\n  TZDaysBetweenFunction = class (TZAbstractFunction)\n  public\n    function Execute(Stack: TZExecutionStack;\n      VariantManager: IZVariantManager): TZVariant; override;\n  end;\n\n  {** Implements a HOURSBETWEEN function. }\n  TZHoursBetweenFunction = class (TZAbstractFunction)\n  public\n    function Execute(Stack: TZExecutionStack;\n      VariantManager: IZVariantManager): TZVariant; override;\n  end;\n\n  {** Implements a MINUTESBETWEEN function. }\n  TZMinutesBetweenFunction = class (TZAbstractFunction)\n  public\n    function Execute(Stack: TZExecutionStack;\n      VariantManager: IZVariantManager): TZVariant; override;\n  end;\n\n  {** Implements a SECONDSBETWEEN function. }\n  TZSecondsBetweenFunction = class (TZAbstractFunction)\n  public\n    function Execute(Stack: TZExecutionStack;\n      VariantManager: IZVariantManager): TZVariant; override;\n  end;\n\n  {** Implements a MILLISECONDSBETWEEN function. }\n  TZMillisecondsBetweenFunction = class (TZAbstractFunction)\n  public\n    function Execute(Stack: TZExecutionStack;\n      VariantManager: IZVariantManager): TZVariant; override;\n  end;\n\nprocedure AddDateTimeFunctions(Functions : TZFunctionsList);\n\nimplementation\n\nuses\n  ZMessages, DateUtils;\n\nFunction IncDate(const aDate : TDateTime; const aYear, aMonth, aWeek, aDay : LongInt) : TDateTime;\nbegin\n  Result := aDate;\n  if aYear  <> 0 then Result := IncYear(Result, aYear);\n  if aMonth <> 0 then Result := IncMonth(Result, aMonth);\n  if aWeek  <> 0 then Result := IncWeek(Result, aWeek);\n  if aDay   <> 0 then Result := IncDay(Result, aDay);\nend;\n\nFunction IncTime(const aDate : TDateTime; const aHour, aMinute, aSecond, aMillisec : LongInt) : TDateTime;\nbegin\n  Result := IncHour(IncMinute(IncSecond(IncMillisecond(aDate, aMilliSec),aSecond),aMinute),aHour);\nend;\n\n{ TZDateFunction }\n\nfunction TZDateFunction.Execute(Stack: TZExecutionStack;\n  VariantManager: IZVariantManager): TZVariant;\nbegin\n  CheckParamsCount(Stack, 0);\n  VariantManager.SetAsDateTime(Result, Date);\nend;\n\n{ TZTimeFunction }\n\n{**\n  Executes this function.\n  @param Stack the stack object.\n  @param VariantManager a reference to variant processor object.\n  @returns a function value.\n}\nfunction TZTimeFunction.Execute(Stack: TZExecutionStack;\n  VariantManager: IZVariantManager): TZVariant;\nbegin\n  CheckParamsCount(Stack, 0);\n  VariantManager.SetAsDateTime(Result, Time);\nend;\n\n{ TZNowFunction }\n\nfunction TZNowFunction.Execute(Stack: TZExecutionStack;\n  VariantManager: IZVariantManager): TZVariant;\nbegin\n  CheckParamsCount(Stack, 0);\n  VariantManager.SetAsDateTime(Result, Now);\nend;\n\n{ TZEncodeDateFunction }\n\nfunction TZEncodeDateFunction.Execute(Stack: TZExecutionStack;\n  VariantManager: IZVariantManager): TZVariant;\nvar\n  ParamsCount: Integer;\n  Year , Month, Day : LongInt;\nbegin\n  ParamsCount := VariantManager.GetAsInteger(Stack.GetParameter(0));\n\n  Year  := 0;\n  Month := 1;\n  Day   := 1;\n\n  if ParamsCount > 0 then\n    Year := VariantManager.GetAsInteger(Stack.GetParameter(ParamsCount));\n  if ParamsCount > 1 then\n    Month := VariantManager.GetAsInteger(Stack.GetParameter(ParamsCount-1));\n  if ParamsCount > 2 then\n    Day := VariantManager.GetAsInteger(Stack.GetParameter(ParamsCount-2));\n\n  VariantManager.SetAsDateTime(Result, EncodeDate(Year,Month,Day));\nend;\n\n{ TZEncodeDateFunction }\n\nfunction TZEncodeTimeFunction.Execute(Stack: TZExecutionStack;\n  VariantManager: IZVariantManager): TZVariant;\nvar\n  ParamsCount: Integer;\n  Hour , Minute, Second, MilliSecond : LongInt;\nbegin\n  ParamsCount := VariantManager.GetAsInteger(Stack.GetParameter(0));\n\n  Hour        := 0;\n  Minute      := 0;\n  Second      := 0;\n  MilliSecond := 0;\n\n  if ParamsCount > 0 then\n    Hour := VariantManager.GetAsInteger(Stack.GetParameter(ParamsCount));\n  if ParamsCount > 1 then\n    Minute := VariantManager.GetAsInteger(Stack.GetParameter(ParamsCount-1));\n  if ParamsCount > 2 then\n    Second := VariantManager.GetAsInteger(Stack.GetParameter(ParamsCount-2));\n  if ParamsCount > 3 then\n    MilliSecond := VariantManager.GetAsInteger(Stack.GetParameter(ParamsCount-3));\n\n  VariantManager.SetAsDateTime(Result, EncodeTime(Hour,Minute,Second,MilliSecond));\nend;\n\n{ TZComposeDateTimeFunction }\n\nfunction TZComposeDateTimeFunction.Execute(Stack: TZExecutionStack;\n  VariantManager: IZVariantManager): TZVariant;\nbegin\n  CheckParamsCount(Stack, 2);\n  VariantManager.SetAsDateTime(Result, VariantManager.GetAsDateTime(Stack.GetParameter(2))+\n    VariantManager.GetAsDateTime(Stack.GetParameter(1)));\nend;\n\n{ TZIncDateFunction }\n\nfunction TZIncDateFunction.Execute(Stack: TZExecutionStack;\n  VariantManager: IZVariantManager): TZVariant;\nvar\n  ParamsCount: Integer;\n  Date : TDateTime;\n  Year , Month, Week, Day : LongInt;\nbegin\n  ParamsCount := VariantManager.GetAsInteger(Stack.GetParameter(0));\n\n  if (ParamsCount <= 2) then\n    raise TZExpressionError.Create(SExpectedMoreParams);\n\n  Date  := VariantManager.GetAsDateTime(Stack.GetParameter(ParamsCount));\n  Year  := VariantManager.GetAsInteger(Stack.GetParameter(ParamsCount-1));\n  Month := 0;\n  Week  := 0;\n  Day   := 0;\n  if ParamsCount > 2 then\n     Month := VariantManager.GetAsInteger(Stack.GetParameter(ParamsCount-2));\n  if ParamsCount > 3 then\n     Week := VariantManager.GetAsInteger(Stack.GetParameter(ParamsCount-3));\n  if ParamsCount > 4 then\n     Day := VariantManager.GetAsInteger(Stack.GetParameter(ParamsCount-4));\n\n  VariantManager.SetAsDateTime(Result, IncDate(Date,Year,Month,Week,Day));\nend;\n\n{ TZIncTimeFunction }\n\nfunction TZIncTimeFunction.Execute(Stack: TZExecutionStack;\n  VariantManager: IZVariantManager): TZVariant;\nvar\n  ParamsCount: Integer;\n  Date : TDateTime;\n  Hour , Minute, Second, MilliSecond : LongInt;\nbegin\n  ParamsCount := VariantManager.GetAsInteger(Stack.GetParameter(0));\n\n  if (ParamsCount <= 2) then\n    raise TZExpressionError.Create(SExpectedMoreParams);\n\n  Date := VariantManager.GetAsDateTime(Stack.GetParameter(ParamsCount));\n  Hour := VariantManager.GetAsInteger(Stack.GetParameter(ParamsCount-1));\n\n  Minute      := 0;\n  Second      := 0;\n  MilliSecond := 0;\n\n  if ParamsCount > 2 then\n    Minute := VariantManager.GetAsInteger(Stack.GetParameter(ParamsCount-2));\n  if ParamsCount > 3 then\n    Second := VariantManager.GetAsInteger(Stack.GetParameter(ParamsCount-3));\n  if ParamsCount > 4 then\n    MilliSecond := VariantManager.GetAsInteger(Stack.GetParameter(ParamsCount-4));\n\n  VariantManager.SetAsDateTime(Result, IncTime(Date, Hour,Minute,Second,MilliSecond));\nend;\n\n{ TZIsLeapYearFunction }\n\nfunction TZIsLeapYearFunction.Execute(Stack: TZExecutionStack;\n  VariantManager: IZVariantManager): TZVariant;\nbegin\n  CheckParamsCount(Stack, 1);\n  VariantManager.SetAsBoolean(Result, IsLeapYear(\n    VariantManager.GetAsInteger(Stack.GetParameter(1))));\nend;\n\n{ TZDateOfFunction }\n\nfunction TZDateOfFunction.Execute(Stack: TZExecutionStack;\n  VariantManager: IZVariantManager): TZVariant;\nbegin\n  CheckParamsCount(Stack, 1);\n  VariantManager.SetAsDateTime(Result, DateOf(\n    VariantManager.GetAsDateTime(Stack.GetParameter(1))));\nend;\n\n{ TZTimeOfFunction }\n\nfunction TZTimeOfFunction.Execute(Stack: TZExecutionStack;\n  VariantManager: IZVariantManager): TZVariant;\nbegin\n  CheckParamsCount(Stack, 1);\n  VariantManager.SetAsDateTime(Result, TimeOf(\n    VariantManager.GetAsDateTime(Stack.GetParameter(1))));\nend;\n\n{ TZYearOfFunction }\n\nfunction TZYearOfFunction.Execute(Stack: TZExecutionStack;\n  VariantManager: IZVariantManager): TZVariant;\nbegin\n  CheckParamsCount(Stack, 1);\n  VariantManager.SetAsInteger(Result, YearOf(\n    VariantManager.GetAsDateTime(Stack.GetParameter(1))));\nend;\n\n{ TZMonthOfFunction }\n\nfunction TZMonthOfFunction.Execute(Stack: TZExecutionStack;\n  VariantManager: IZVariantManager): TZVariant;\nbegin\n  CheckParamsCount(Stack, 1);\n  VariantManager.SetAsInteger(Result, MonthOf(\n    VariantManager.GetAsDateTime(Stack.GetParameter(1))));\nend;\n\n{ TZDayOfFunction }\n\nfunction TZDayOfFunction.Execute(Stack: TZExecutionStack;\n  VariantManager: IZVariantManager): TZVariant;\nbegin\n  CheckParamsCount(Stack, 1);\n  VariantManager.SetAsInteger(Result, DayOf(\n    VariantManager.GetAsDateTime(Stack.GetParameter(1))));\nend;\n\n{ TZHourOfFunction }\n\nfunction TZHourOfFunction.Execute(Stack: TZExecutionStack;\n  VariantManager: IZVariantManager): TZVariant;\nbegin\n  CheckParamsCount(Stack, 1);\n  VariantManager.SetAsInteger(Result, HourOf(\n    VariantManager.GetAsDateTime(Stack.GetParameter(1))));\nend;\n\n{ TZMinuteOfFunction }\n\nfunction TZMinuteOfFunction.Execute(Stack: TZExecutionStack;\n  VariantManager: IZVariantManager): TZVariant;\nbegin\n  CheckParamsCount(Stack, 1);\n  VariantManager.SetAsInteger(Result, MinuteOf(\n    VariantManager.GetAsDateTime(Stack.GetParameter(1))));\nend;\n\n{ TZSecondOfFunction }\n\nfunction TZSecondOfFunction.Execute(Stack: TZExecutionStack;\n  VariantManager: IZVariantManager): TZVariant;\nbegin\n  CheckParamsCount(Stack, 1);\n  VariantManager.SetAsInteger(Result, SecondOf(\n    VariantManager.GetAsDateTime(Stack.GetParameter(1))));\nend;\n\n{ TZMilliSecondOfFunction }\n\nfunction TZMilliSecondOfFunction.Execute(Stack: TZExecutionStack;\n  VariantManager: IZVariantManager): TZVariant;\nbegin\n  CheckParamsCount(Stack, 1);\n  VariantManager.SetAsInteger(Result, MilliSecondOf(\n    VariantManager.GetAsDateTime(Stack.GetParameter(1))));\nend;\n\n{ TZWeekOfTheYearFunction }\n\nfunction TZWeekOfTheYearFunction.Execute(Stack: TZExecutionStack;\n  VariantManager: IZVariantManager): TZVariant;\nbegin\n  CheckParamsCount(Stack, 1);\n  VariantManager.SetAsInteger(Result, WeekOfTheYear(\n    VariantManager.GetAsDateTime(Stack.GetParameter(1))));\nend;\n\n{ TZDayOfTheYearFunction }\n\nfunction TZDayOfTheYearFunction.Execute(Stack: TZExecutionStack;\n  VariantManager: IZVariantManager): TZVariant;\nbegin\n  CheckParamsCount(Stack, 1);\n  VariantManager.SetAsInteger(Result, DayOfTheYear(\n    VariantManager.GetAsDateTime(Stack.GetParameter(1))));\nend;\n\n{ TZHourOfTheYearFunction }\n\nfunction TZHourOfTheYearFunction.Execute(Stack: TZExecutionStack;\n  VariantManager: IZVariantManager): TZVariant;\nbegin\n  CheckParamsCount(Stack, 1);\n  VariantManager.SetAsInteger(Result, HourOfTheYear(\n    VariantManager.GetAsDateTime(Stack.GetParameter(1))));\nend;\n\n{ TZMinuteOfTheYearFunction }\n\nfunction TZMinuteOfTheYearFunction.Execute(Stack: TZExecutionStack;\n  VariantManager: IZVariantManager): TZVariant;\nbegin\n  CheckParamsCount(Stack, 1);\n  VariantManager.SetAsInteger(Result, MinuteOfTheYear(\n    VariantManager.GetAsDateTime(Stack.GetParameter(1))));\nend;\n\n{ TZSecondOfTheYearFunction }\n\nfunction TZSecondOfTheYearFunction.Execute(Stack: TZExecutionStack;\n  VariantManager: IZVariantManager): TZVariant;\nbegin\n  CheckParamsCount(Stack, 1);\n  VariantManager.SetAsInteger(Result, SecondOfTheYear(\n    VariantManager.GetAsDateTime(Stack.GetParameter(1))));\nend;\n\n{ TZMilliSecondOfTheYearFunction }\n\nfunction TZMilliSecondOfTheYearFunction.Execute(Stack: TZExecutionStack;\n  VariantManager: IZVariantManager): TZVariant;\n  {$IFDEF WITH_MILLISECONDOFTHEYEAR_BUG}\n  function MilliSecondOfTheYear(const AValue: TDateTime): Int64;\n  begin\n    Result := MilliSecondOf(AValue) + Int64(SecondOfTheYear(AValue)) * MSecsPerSec;\n  end;\n  {$ENDIF}\nbegin\n  CheckParamsCount(Stack, 1);\n  VariantManager.SetAsInteger(Result, MilliSecondOfTheYear(\n    VariantManager.GetAsDateTime(Stack.GetParameter(1))));\nend;\n\n{ TZWeekOfTheMonthFunction }\n\nfunction TZWeekOfTheMonthFunction.Execute(Stack: TZExecutionStack;\n  VariantManager: IZVariantManager): TZVariant;\nbegin\n  CheckParamsCount(Stack, 1);\n  VariantManager.SetAsInteger(Result, WeekOfTheMonth(\n    VariantManager.GetAsDateTime(Stack.GetParameter(1))));\nend;\n\n{ TZHourOfTheMonthFunction }\n\nfunction TZHourOfTheMonthFunction.Execute(Stack: TZExecutionStack;\n  VariantManager: IZVariantManager): TZVariant;\nbegin\n  CheckParamsCount(Stack, 1);\n  VariantManager.SetAsInteger(Result, HourOfTheMonth(\n    VariantManager.GetAsDateTime(Stack.GetParameter(1))));\nend;\n\n{ TZMinuteOfTheMonthFunction }\n\nfunction TZMinuteOfTheMonthFunction.Execute(Stack: TZExecutionStack;\n  VariantManager: IZVariantManager): TZVariant;\nbegin\n  CheckParamsCount(Stack, 1);\n  VariantManager.SetAsInteger(Result, MinuteOfTheMonth(\n    VariantManager.GetAsDateTime(Stack.GetParameter(1))));\nend;\n\n{ TZSecondOfTheMonthFunction }\n\nfunction TZSecondOfTheMonthFunction.Execute(Stack: TZExecutionStack;\n  VariantManager: IZVariantManager): TZVariant;\nbegin\n  CheckParamsCount(Stack, 1);\n  VariantManager.SetAsInteger(Result, SecondOfTheMonth(\n    VariantManager.GetAsDateTime(Stack.GetParameter(1))));\nend;\n\n{ TZMilliSecondOfTheMonthFunction }\n\nfunction TZMilliSecondOfTheMonthFunction.Execute(Stack: TZExecutionStack;\n  VariantManager: IZVariantManager): TZVariant;\nbegin\n  CheckParamsCount(Stack, 1);\n  VariantManager.SetAsInteger(Result, MilliSecondOfTheMonth(\n    VariantManager.GetAsDateTime(Stack.GetParameter(1))));\nend;\n\n{ TZDayOfTheWeekFunction }\n\nfunction TZDayOfTheWeekFunction.Execute(Stack: TZExecutionStack;\n  VariantManager: IZVariantManager): TZVariant;\nbegin\n  CheckParamsCount(Stack, 1);\n  VariantManager.SetAsInteger(Result, DayOfTheWeek(\n    VariantManager.GetAsDateTime(Stack.GetParameter(1))));\nend;\n\n{ TZHourOfTheWeekFunction }\n\nfunction TZHourOfTheWeekFunction.Execute(Stack: TZExecutionStack;\n  VariantManager: IZVariantManager): TZVariant;\nbegin\n  CheckParamsCount(Stack, 1);\n  VariantManager.SetAsInteger(Result, HourOfTheWeek(\n    VariantManager.GetAsDateTime(Stack.GetParameter(1))));\nend;\n\n{ TZMinuteOfTheWeekFunction }\n\nfunction TZMinuteOfTheWeekFunction.Execute(Stack: TZExecutionStack;\n  VariantManager: IZVariantManager): TZVariant;\nbegin\n  CheckParamsCount(Stack, 1);\n  VariantManager.SetAsInteger(Result, MinuteOfTheWeek(\n    VariantManager.GetAsDateTime(Stack.GetParameter(1))));\nend;\n\n{ TZSecondOfTheWeekFunction }\n\nfunction TZSecondOfTheWeekFunction.Execute(Stack: TZExecutionStack;\n  VariantManager: IZVariantManager): TZVariant;\nbegin\n  CheckParamsCount(Stack, 1);\n  VariantManager.SetAsInteger(Result, SecondOfTheWeek(\n    VariantManager.GetAsDateTime(Stack.GetParameter(1))));\nend;\n\n{ TZMilliSecondOfTheWeekFunction }\n\nfunction TZMilliSecondOfTheWeekFunction.Execute(Stack: TZExecutionStack;\n  VariantManager: IZVariantManager): TZVariant;\nbegin\n  CheckParamsCount(Stack, 1);\n  VariantManager.SetAsInteger(Result, MilliSecondOfTheWeek(\n    VariantManager.GetAsDateTime(Stack.GetParameter(1))));\nend;\n\n{ TZMinuteOfTheDayFunction }\n\nfunction TZMinuteOfTheDayFunction.Execute(Stack: TZExecutionStack;\n  VariantManager: IZVariantManager): TZVariant;\nbegin\n  CheckParamsCount(Stack, 1);\n  VariantManager.SetAsInteger(Result, MinuteOfTheDay(\n    VariantManager.GetAsDateTime(Stack.GetParameter(1))));\nend;\n\n{ TZSecondOfTheDayFunction }\n\nfunction TZSecondOfTheDayFunction.Execute(Stack: TZExecutionStack;\n  VariantManager: IZVariantManager): TZVariant;\nbegin\n  CheckParamsCount(Stack, 1);\n  VariantManager.SetAsInteger(Result, SecondOfTheDay(\n    VariantManager.GetAsDateTime(Stack.GetParameter(1))));\nend;\n\n{ TZMilliSecondOfTheDayFunction }\n\nfunction TZMilliSecondOfTheDayFunction.Execute(Stack: TZExecutionStack;\n  VariantManager: IZVariantManager): TZVariant;\nbegin\n  CheckParamsCount(Stack, 1);\n  VariantManager.SetAsInteger(Result, MilliSecondOfTheDay(\n    VariantManager.GetAsDateTime(Stack.GetParameter(1))));\nend;\n\n{ TZSecondOfTheHourFunction }\n\nfunction TZSecondOfTheHourFunction.Execute(Stack: TZExecutionStack;\n  VariantManager: IZVariantManager): TZVariant;\nbegin\n  CheckParamsCount(Stack, 1);\n  VariantManager.SetAsInteger(Result, SecondOfTheHour(\n    VariantManager.GetAsDateTime(Stack.GetParameter(1))));\nend;\n\n{ TZMilliSecondOfTheHourFunction }\n\nfunction TZMilliSecondOfTheHourFunction.Execute(Stack: TZExecutionStack;\n  VariantManager: IZVariantManager): TZVariant;\nbegin\n  CheckParamsCount(Stack, 1);\n  VariantManager.SetAsInteger(Result, MilliSecondOfTheHour(\n    VariantManager.GetAsDateTime(Stack.GetParameter(1))));\nend;\n\n{ TZMilliSecondOfTheMinuteFunction }\n\nfunction TZMilliSecondOfTheMinuteFunction.Execute(Stack: TZExecutionStack;\n  VariantManager: IZVariantManager): TZVariant;\nbegin\n  CheckParamsCount(Stack, 1);\n  VariantManager.SetAsInteger(Result, MilliSecondOfTheMinute(\n    VariantManager.GetAsDateTime(Stack.GetParameter(1))));\nend;\n\n{ TZYearsBetweenFunction }\n\nfunction TZYearsBetweenFunction.Execute(Stack: TZExecutionStack;\n  VariantManager: IZVariantManager): TZVariant;\nbegin\n  CheckParamsCount(Stack, 2);\n  VariantManager.SetAsInteger(Result, YearsBetween(\n    VariantManager.GetAsDateTime(Stack.GetParameter(2)),\n    VariantManager.GetAsDateTime(Stack.GetParameter(1))));\nend;\n\n{ TZMonthsBetweenFunction }\n\nfunction TZMonthsBetweenFunction.Execute(Stack: TZExecutionStack;\n  VariantManager: IZVariantManager): TZVariant;\nbegin\n  CheckParamsCount(Stack, 2);\n  VariantManager.SetAsInteger(Result, MonthsBetween(\n    VariantManager.GetAsDateTime(Stack.GetParameter(2)),\n    VariantManager.GetAsDateTime(Stack.GetParameter(1))));\nend;\n\n{ TZWeeksBetweenFunction }\n\nfunction TZWeeksBetweenFunction.Execute(Stack: TZExecutionStack;\n  VariantManager: IZVariantManager): TZVariant;\nbegin\n  CheckParamsCount(Stack, 2);\n  VariantManager.SetAsInteger(Result, WeeksBetween(\n    VariantManager.GetAsDateTime(Stack.GetParameter(2)),\n    VariantManager.GetAsDateTime(Stack.GetParameter(1))));\nend;\n\n{ TZDaysBetweenFunction }\n\nfunction TZDaysBetweenFunction.Execute(Stack: TZExecutionStack;\n  VariantManager: IZVariantManager): TZVariant;\nbegin\n  CheckParamsCount(Stack, 2);\n  VariantManager.SetAsInteger(Result, DaysBetween(\n    VariantManager.GetAsDateTime(Stack.GetParameter(2)),\n    VariantManager.GetAsDateTime(Stack.GetParameter(1))));\nend;\n\n{ TZHoursBetweenFunction }\n\nfunction TZHoursBetweenFunction.Execute(Stack: TZExecutionStack;\n  VariantManager: IZVariantManager): TZVariant;\nbegin\n  CheckParamsCount(Stack, 2);\n  VariantManager.SetAsInteger(Result, HoursBetween(\n    VariantManager.GetAsDateTime(Stack.GetParameter(2)),\n    VariantManager.GetAsDateTime(Stack.GetParameter(1))));\nend;\n\n{ TZMinutesBetweenFunction }\n\nfunction TZMinutesBetweenFunction.Execute(Stack: TZExecutionStack;\n  VariantManager: IZVariantManager): TZVariant;\nbegin\n  CheckParamsCount(Stack, 2);\n  VariantManager.SetAsInteger(Result, MinutesBetween(\n    VariantManager.GetAsDateTime(Stack.GetParameter(2)),\n    VariantManager.GetAsDateTime(Stack.GetParameter(1))));\nend;\n\n{ TZSecondsBetweenFunction }\n\nfunction TZSecondsBetweenFunction.Execute(Stack: TZExecutionStack;\n  VariantManager: IZVariantManager): TZVariant;\nbegin\n  CheckParamsCount(Stack, 2);\n  VariantManager.SetAsInteger(Result, SecondsBetween(\n    VariantManager.GetAsDateTime(Stack.GetParameter(2)),\n    VariantManager.GetAsDateTime(Stack.GetParameter(1))));\nend;\n\n{ TZHoursBetweenFunction }\n\nfunction TZMillisecondsBetweenFunction.Execute(Stack: TZExecutionStack;\n  VariantManager: IZVariantManager): TZVariant;\nbegin\n  CheckParamsCount(Stack, 2);\n  VariantManager.SetAsInteger(Result, MillisecondsBetween(\n    VariantManager.GetAsDateTime(Stack.GetParameter(2)),\n    VariantManager.GetAsDateTime(Stack.GetParameter(1))));\nend;\n\nprocedure AddDateTimeFunctions(Functions : TZFunctionsList);\nbegin\n  Functions.Add(TZDateFunction.Create('DATE'));\n  Functions.Add(TZTimeFunction.Create('TIME'));\n  Functions.Add(TZNowFunction.Create('NOW'));\n\n// First the Aliases\n\n  Functions.Add(TZEncodeDateFunction.Create('ENCD'));\n  Functions.Add(TZEncodeTimeFunction.Create('ENCT'));\n//  Functions.Add(TZComposeDateTimeFunction.Create('COMPDT'));\n\n  Functions.Add(TZIncDateFunction.Create('INCD'));\n  Functions.Add(TZIncTimeFunction.Create('INCT'));\n\n  Functions.Add(TZIsLeapYearFunction.Create('LEAPY'));\n\n//  Functions.Add(TZDateOfFunction.Create('DATEOF'));\n//  Functions.Add(TZTimeOfFunction.Create('TIMEOF'));\n\n//  Functions.Add(TZYearOfFunction.Create('YEAROF'));\n//  Functions.Add(TZMonthOfFunction.Create('MONTHOF'));\n//  Functions.Add(TZDayOfFunction.Create('DAYOF'));\n//  Functions.Add(TZHourOfFunction.Create('HOUROF'));\n\n  Functions.Add(TZMinuteOfFunction.Create('MINOF'));\n  Functions.Add(TZSecondOfFunction.Create('SECOF'));\n  Functions.Add(TZMilliSecondOfFunction.Create('MSECOF'));\n\n  Functions.Add(TZWeekOfTheYearFunction.Create('WofY'));\n  Functions.Add(TZDayOfTheYearFunction.Create('DofY'));\n  Functions.Add(TZHourOfTheYearFunction.Create('HofY'));\n  Functions.Add(TZMinuteOfTheYearFunction.Create('MINofY'));\n  Functions.Add(TZSecondOfTheYearFunction.Create('SECofY'));\n  Functions.Add(TZMilliSecondOfTheYearFunction.Create('MSECofY'));\n\n  Functions.Add(TZWeekOfTheMonthFunction.Create('WofM'));\n  Functions.Add(TZHourOfTheMonthFunction.Create('HofM'));\n  Functions.Add(TZMinuteOfTheMonthFunction.Create('MINofM'));\n  Functions.Add(TZSecondOfTheMonthFunction.Create('SECofM'));\n  Functions.Add(TZMilliSecondOfTheMonthFunction.Create('MSECofM'));\n\n  Functions.Add(TZDayOfTheWeekFunction.Create('DofW'));\n  Functions.Add(TZHourOfTheWeekFunction.Create('HofW'));\n  Functions.Add(TZMinuteOfTheWeekFunction.Create('MINofW'));\n  Functions.Add(TZSecondOfTheWeekFunction.Create('SECofW'));\n  Functions.Add(TZMilliSecondOfTheWeekFunction.Create('MSECofW'));\n\n  Functions.Add(TZMinuteOfTheDayFunction.Create('MINofD'));\n  Functions.Add(TZSecondOfTheDayFunction.Create('SECofD'));\n  Functions.Add(TZMilliSecondOfTheDayFunction.Create('MSECofD'));\n\n  Functions.Add(TZSecondOfTheHourFunction.Create('SECofH'));\n  Functions.Add(TZMilliSecondOfTheHourFunction.Create('MSECofH'));\n\n  Functions.Add(TZMilliSecondOfTheMinuteFunction.Create('MSECofMIN'));\n\n  Functions.Add(TZYearsBetweenFunction.Create('YBTW'));\n  Functions.Add(TZMonthsBetweenFunction.Create('MBTW'));\n  Functions.Add(TZWeeksBetweenFunction.Create('WBTW'));\n  Functions.Add(TZDaysBetweenFunction.Create('DBTW'));\n  Functions.Add(TZHoursBetweenFunction.Create('HBTW'));\n  Functions.Add(TZMinutesBetweenFunction.Create('MINBTW'));\n  Functions.Add(TZSecondsBetweenFunction.Create('SECBTW'));\n  Functions.Add(TZMilliSecondsBetweenFunction.Create('MSECBTW'));\n\n// End of Aliases\n\n  Functions.Add(TZEncodeDateFunction.Create('ENCODEDATE'));\n  Functions.Add(TZEncodeTimeFunction.Create('ENCODETIME'));\n  Functions.Add(TZComposeDateTimeFunction.Create('COMPOSEDATETIME'));\n\n  Functions.Add(TZIncDateFunction.Create('INCDATE'));\n  Functions.Add(TZIncTimeFunction.Create('INCTIME'));\n\n  Functions.Add(TZIsLeapYearFunction.Create('ISLEAPYEAR'));\n\n  Functions.Add(TZDateOfFunction.Create('DATEOF'));\n  Functions.Add(TZTimeOfFunction.Create('TIMEOF'));\n\n  Functions.Add(TZYearOfFunction.Create('YEAROF'));\n  Functions.Add(TZMonthOfFunction.Create('MONTHOF'));\n  Functions.Add(TZDayOfFunction.Create('DAYOF'));\n  Functions.Add(TZHourOfFunction.Create('HOUROF'));\n\n  Functions.Add(TZMinuteOfFunction.Create('MINUTEOF'));\n  Functions.Add(TZSecondOfFunction.Create('SECONDOF'));\n  Functions.Add(TZMilliSecondOfFunction.Create('MILLISECONDOF'));\n\n  Functions.Add(TZWeekOfTheYearFunction.Create('WEEKOFTHEYEAR'));\n  Functions.Add(TZDayOfTheYearFunction.Create('DAYOFTHEYEAR'));\n  Functions.Add(TZHourOfTheYearFunction.Create('HOUROFTHEYEAR'));\n  Functions.Add(TZMinuteOfTheYearFunction.Create('MINUTEOFTHEYEAR'));\n  Functions.Add(TZSecondOfTheYearFunction.Create('SECONDOFTHEYEAR'));\n  Functions.Add(TZMilliSecondOfTheYearFunction.Create('MILLISECONDOFTHEYEAR'));\n\n  Functions.Add(TZWeekOfTheMonthFunction.Create('WEEKOFTHEMONTH'));\n  Functions.Add(TZHourOfTheMonthFunction.Create('HOUROFTHEMONTH'));\n  Functions.Add(TZMinuteOfTheMonthFunction.Create('MINUTEOFTHEMONTH'));\n  Functions.Add(TZSecondOfTheMonthFunction.Create('SECONDOFTHEMONTH'));\n  Functions.Add(TZMilliSecondOfTheMonthFunction.Create('MILLISECONDOFTHEMONTH'));\n\n  Functions.Add(TZDayOfTheWeekFunction.Create('DAYOFTHEWEEK'));\n  Functions.Add(TZHourOfTheWeekFunction.Create('HOUROFTHEWEEK'));\n  Functions.Add(TZMinuteOfTheWeekFunction.Create('MINUTEOFTHEWEEK'));\n  Functions.Add(TZSecondOfTheWeekFunction.Create('SECONDOFTHEWEEK'));\n  Functions.Add(TZMilliSecondOfTheWeekFunction.Create('MILLISECONDOFTHEWEEK'));\n\n  Functions.Add(TZMinuteOfTheDayFunction.Create('MINUTEOFTHEDAY'));\n  Functions.Add(TZSecondOfTheDayFunction.Create('SECONDOFTHEDAY'));\n  Functions.Add(TZMilliSecondOfTheDayFunction.Create('MILLISECONDOFTHEDAY'));\n\n  Functions.Add(TZSecondOfTheHourFunction.Create('SECONDOFTHEHOUR'));\n  Functions.Add(TZMilliSecondOfTheHourFunction.Create('MILLISECONDOFTHEHOUR'));\n\n  Functions.Add(TZMilliSecondOfTheMinuteFunction.Create('MILLISECONDOFTHEMINUTE'));\n\n  Functions.Add(TZYearsBetweenFunction.Create('YEARSBETWEEN'));\n  Functions.Add(TZMonthsBetweenFunction.Create('MONTHSBETWEEN'));\n  Functions.Add(TZWeeksBetweenFunction.Create('WEEKSBETWEEN'));\n  Functions.Add(TZDaysBetweenFunction.Create('DAYSBETWEEN'));\n  Functions.Add(TZHoursBetweenFunction.Create('HOURSBETWEEN'));\n  Functions.Add(TZMinutesBetweenFunction.Create('MINUTESBETWEEN'));\n  Functions.Add(TZSecondsBetweenFunction.Create('SECONDSBETWEEN'));\n  Functions.Add(TZMilliSecondsBetweenFunction.Create('MILLISECONDSBETWEEN'));\n\nend;\n\nend.\n"
  },
  {
    "path": "lib/zeosdbo/src/core/ZFunctionsMath.pas",
    "content": "{*********************************************************}\n{                                                         }\n{                 Zeos Database Objects                   }\n{             Variables classes and interfaces            }\n{                                                         }\n{           Originally written by Sergey Seroukhov        }\n{                                                         }\n{*********************************************************}\n\n{@********************************************************}\n{    Copyright (c) 1999-2012 Zeos Development Group       }\n{                                                         }\n{ License Agreement:                                      }\n{                                                         }\n{ This library is distributed in the hope that it will be }\n{ useful, but WITHOUT ANY WARRANTY; without even the      }\n{ implied warranty of MERCHANTABILITY or FITNESS FOR      }\n{ A PARTICULAR PURPOSE.  See the GNU Lesser General       }\n{ Public License for more details.                        }\n{                                                         }\n{ The source code of the ZEOS Libraries and packages are  }\n{ distributed under the Library GNU General Public        }\n{ License (see the file COPYING / COPYING.ZEOS)           }\n{ with the following  modification:                       }\n{ As a special exception, the copyright holders of this   }\n{ library give you permission to link this library with   }\n{ independent modules to produce an executable,           }\n{ regardless of the license terms of these independent    }\n{ modules, and to copy and distribute the resulting       }\n{ executable under terms of your choice, provided that    }\n{ you also meet, for each linked independent module,      }\n{ the terms and conditions of the license of that module. }\n{ An independent module is a module which is not derived  }\n{ from or based on this library. If you modify this       }\n{ library, you may extend this exception to your version  }\n{ of the library, but you are not obligated to do so.     }\n{ If you do not wish to do so, delete this exception      }\n{ statement from your version.                            }\n{                                                         }\n{                                                         }\n{ The project web site is located on:                     }\n{   http://zeos.firmos.at  (FORUM)                        }\n{   http://sourceforge.net/p/zeoslib/tickets/ (BUGTRACKER)}\n{   svn://svn.code.sf.net/p/zeoslib/code-0/trunk (SVN)    }\n{                                                         }\n{   http://www.sourceforge.net/projects/zeoslib.          }\n{                                                         }\n{                                                         }\n{                                 Zeos Development Group. }\n{********************************************************@}\n\nunit ZFunctionsMath;\n\ninterface\n\n{$I ZCore.inc}\n\nuses\n  SysUtils, ZFunctions, ZExpression, ZVariant;\n\n{**  Math functions }\n\ntype\n  {** Implements a E function. }\n  TZEFunction = class (TZAbstractFunction)\n  public\n    function Execute(Stack: TZExecutionStack;\n      VariantManager: IZVariantManager): TZVariant; override;\n  end;\n\n  {** Implements a PI function. }\n  TZPIFunction = class (TZAbstractFunction)\n  public\n    function Execute(Stack: TZExecutionStack;\n      VariantManager: IZVariantManager): TZVariant; override;\n  end;\n\n  {** Implements a RND function. }\n  TZRndFunction = class (TZAbstractFunction)\n  public\n    function Execute(Stack: TZExecutionStack;\n      VariantManager: IZVariantManager): TZVariant; override;\n  end;\n\n  {** Implements a ABS function. }\n  TZAbsFunction = class (TZAbstractFunction)\n  public\n    function Execute(Stack: TZExecutionStack;\n      VariantManager: IZVariantManager): TZVariant; override;\n  end;\n\n{** Trigonometric }\n  {** Implements a COS function. }\n  TZCosFunction = class (TZAbstractFunction)\n  public\n    function Execute(Stack: TZExecutionStack;\n      VariantManager: IZVariantManager): TZVariant; override;\n  end;\n\n  {** Implements a COT function. }\n  TZCotFunction = class (TZAbstractFunction)\n  public\n    function Execute(Stack: TZExecutionStack;\n      VariantManager: IZVariantManager): TZVariant; override;\n  end;\n\n  {** Implements a SIN function. }\n  TZSinFunction = class (TZAbstractFunction)\n  public\n    function Execute(Stack: TZExecutionStack;\n      VariantManager: IZVariantManager): TZVariant; override;\n  end;\n\n  {** Implements a TAN function. }\n  TZTanFunction = class (TZAbstractFunction)\n  public\n    function Execute(Stack: TZExecutionStack;\n      VariantManager: IZVariantManager): TZVariant; override;\n  end;\n\n  {** Implements a ACOS function. }\n  TZAcosFunction = class (TZAbstractFunction)\n  public\n    function Execute(Stack: TZExecutionStack;\n      VariantManager: IZVariantManager): TZVariant; override;\n  end;\n\n  {** Implements a ASIN function. }\n  TZAsinFunction = class (TZAbstractFunction)\n  public\n    function Execute(Stack: TZExecutionStack;\n      VariantManager: IZVariantManager): TZVariant; override;\n  end;\n\n  {** Implements a ATAN function. }\n  TZAtanFunction = class (TZAbstractFunction)\n  public\n    function Execute(Stack: TZExecutionStack;\n      VariantManager: IZVariantManager): TZVariant; override;\n  end;\n\n{** Rounding }\n  {** Implements a ROUND function. }\n  TZRoundFunction = class (TZAbstractFunction)\n  public\n    function Execute(Stack: TZExecutionStack;\n      VariantManager: IZVariantManager): TZVariant; override;\n  end;\n\n  {** Implements a TRUNC function. }\n  TZTruncFunction = class (TZAbstractFunction)\n  public\n    function Execute(Stack: TZExecutionStack;\n      VariantManager: IZVariantManager): TZVariant; override;\n  end;\n\n  {** Implements a INT function. }\n  TZIntFunction = class (TZAbstractFunction)\n  public\n    function Execute(Stack: TZExecutionStack;\n      VariantManager: IZVariantManager): TZVariant; override;\n  end;\n\n  {** Implements a FRAC function. }\n  TZFracFunction = class (TZAbstractFunction)\n  public\n    function Execute(Stack: TZExecutionStack;\n      VariantManager: IZVariantManager): TZVariant; override;\n  end;\n\n  {** Implements a CEIL function. }\n  TZCeilFunction = class (TZAbstractFunction)\n  public\n    function Execute(Stack: TZExecutionStack;\n      VariantManager: IZVariantManager): TZVariant; override;\n  end;\n\n  {** Implements a FLOOR function. }\n  TZFloorFunction = class (TZAbstractFunction)\n  public\n    function Execute(Stack: TZExecutionStack;\n      VariantManager: IZVariantManager): TZVariant; override;\n  end;\n\n{** Logarithmic }\n  {** Implements a EXP function. }\n  TZExpFunction = class (TZAbstractFunction)\n  public\n    function Execute(Stack: TZExecutionStack;\n      VariantManager: IZVariantManager): TZVariant; override;\n  end;\n\n  {** Implements a LOG function. }\n  TZLogFunction = class (TZAbstractFunction)\n  public\n    function Execute(Stack: TZExecutionStack;\n      VariantManager: IZVariantManager): TZVariant; override;\n  end;\n\n  {** Implements a LOG10 function. }\n  TZLog10Function = class (TZAbstractFunction)\n  public\n    function Execute(Stack: TZExecutionStack;\n      VariantManager: IZVariantManager): TZVariant; override;\n  end;\n\n  {** Implements a SQR function. }\n  TZSqrFunction = class (TZAbstractFunction)\n  public\n    function Execute(Stack: TZExecutionStack;\n      VariantManager: IZVariantManager): TZVariant; override;\n  end;\n\nprocedure AddMathFunctions(Functions : TZFunctionsList);\n\nimplementation\n\nuses\n  Math;\n\n{$IFDEF FPC}\n  {$HINTS OFF}\n{$ENDIF}\n\n{ TZEFunction }\n\n{**\n  Executes this function.\n  @param Stack the stack object.\n  @param VariantManager a reference to variant processor object.\n  @returns a function value.\n}\nfunction TZEFunction.Execute(Stack: TZExecutionStack;\n  VariantManager: IZVariantManager): TZVariant;\nbegin\n  CheckParamsCount(Stack, 0);\n  VariantManager.SetAsFloat(Result, Exp(1));\nend;\n\n{ TZPIFunction }\n\n{**\n  Executes this function.\n  @param Stack the stack object.\n  @param VariantManager a reference to variant processor object.\n  @returns a function value.\n}\nfunction TZPIFunction.Execute(Stack: TZExecutionStack;\n  VariantManager: IZVariantManager): TZVariant;\nbegin\n  CheckParamsCount(Stack, 0);\n  VariantManager.SetAsFloat(Result, PI);\nend;\n\n{ TZRndFunction }\n\n{**\n  Executes this function.\n  @param Stack the stack object.\n  @param VariantManager a reference to variant processor object.\n  @returns a function value.\n}\nfunction TZRndFunction.Execute(Stack: TZExecutionStack;\n  VariantManager: IZVariantManager): TZVariant;\nbegin\n  CheckParamsCount(Stack, 0);\n  VariantManager.SetAsFloat(Result, Random);\nend;\n\n{ TZAbsFunction }\n\n{**\n  Executes this function.\n  @param Stack the stack object.\n  @param VariantManager a reference to variant processor object.\n  @returns a function value.\n}\nfunction TZAbsFunction.Execute(Stack: TZExecutionStack;\n  VariantManager: IZVariantManager): TZVariant;\nvar\n  Value: TZVariant;\nbegin\n  CheckParamsCount(Stack, 1);\n  Value := Stack.GetParameter(1);\n  if Value.VType = vtInteger then\n    VariantManager.SetAsInteger(Result, Abs(Value.VInteger))\n  else if Value.VType = vtFloat then\n    VariantManager.SetAsFloat(Result, Abs(Value.VFloat))\n  else\n    Result := Value;\nend;\n\n{ TZExpFunction }\n\n{**\n  Executes this function.\n  @param Stack the stack object.\n  @param VariantManager a reference to variant processor object.\n  @returns a function value.\n}\nfunction TZExpFunction.Execute(Stack: TZExecutionStack;\n  VariantManager: IZVariantManager): TZVariant;\nbegin\n  CheckParamsCount(Stack, 1);\n  VariantManager.SetAsFloat(Result, Exp(\n    VariantManager.GetAsFloat(Stack.GetParameter(1))));\nend;\n\n{ TZLogFunction }\n\n{**\n  Executes this function.\n  @param Stack the stack object.\n  @param VariantManager a reference to variant processor object.\n  @returns a function value.\n}\nfunction TZLogFunction.Execute(Stack: TZExecutionStack;\n  VariantManager: IZVariantManager): TZVariant;\nbegin\n  CheckParamsCount(Stack, 1);\n  VariantManager.SetAsFloat(Result, Ln(\n    VariantManager.GetAsFloat(Stack.GetParameter(1))));\nend;\n\n{ TZLog10Function }\n\n{**\n  Executes this function.\n  @param Stack the stack object.\n  @param VariantManager a reference to variant processor object.\n  @returns a function value.\n}\nfunction TZLog10Function.Execute(Stack: TZExecutionStack;\n  VariantManager: IZVariantManager): TZVariant;\nbegin\n  CheckParamsCount(Stack, 1);\n  VariantManager.SetAsFloat(Result, Log10(\n    VariantManager.GetAsFloat(Stack.GetParameter(1))));\nend;\n\n{ TZCosFunction }\n\n{**\n  Executes this function.\n  @param Stack the stack object.\n  @param VariantManager a reference to variant processor object.\n  @returns a function value.\n}\nfunction TZCosFunction.Execute(Stack: TZExecutionStack;\n  VariantManager: IZVariantManager): TZVariant;\nbegin\n  CheckParamsCount(Stack, 1);\n  VariantManager.SetAsFloat(Result, Cos(\n    VariantManager.GetAsFloat(Stack.GetParameter(1))));\nend;\n\n{ TZCotFunction }\n\n{**\n  Executes this function.\n  @param Stack the stack object.\n  @param VariantManager a reference to variant processor object.\n  @returns a function value.\n}\nfunction TZCotFunction.Execute(Stack: TZExecutionStack;\n  VariantManager: IZVariantManager): TZVariant;\nbegin\n  CheckParamsCount(Stack, 1);\n  VariantManager.SetAsFloat(Result, Cotan(\n    VariantManager.GetAsFloat(Stack.GetParameter(1))));\nend;\n\n{ TZSinFunction }\n\n{**\n  Executes this function.\n  @param Stack the stack object.\n  @param VariantManager a reference to variant processor object.\n  @returns a function value.\n}\nfunction TZSinFunction.Execute(Stack: TZExecutionStack;\n  VariantManager: IZVariantManager): TZVariant;\nbegin\n  CheckParamsCount(Stack, 1);\n  VariantManager.SetAsFloat(Result, Sin(\n    VariantManager.GetAsFloat(Stack.GetParameter(1))));\nend;\n\n{ TZTanFunction }\n\n{**\n  Executes this function.\n  @param Stack the stack object.\n  @param VariantManager a reference to variant processor object.\n  @returns a function value.\n}\nfunction TZTanFunction.Execute(Stack: TZExecutionStack;\n  VariantManager: IZVariantManager): TZVariant;\nbegin\n  CheckParamsCount(Stack, 1);\n  VariantManager.SetAsFloat(Result, Tan(\n    VariantManager.GetAsFloat(Stack.GetParameter(1))));\nend;\n\n{ TZAcosFunction }\n\n{**\n  Executes this function.\n  @param Stack the stack object.\n  @param VariantManager a reference to variant processor object.\n  @returns a function value.\n}\nfunction TZAcosFunction.Execute(Stack: TZExecutionStack;\n  VariantManager: IZVariantManager): TZVariant;\nbegin\n  CheckParamsCount(Stack, 1);\n  VariantManager.SetAsFloat(Result, ArcCos(\n    VariantManager.GetAsFloat(Stack.GetParameter(1))));\nend;\n\n{ TZAsinFunction }\n\n{**\n  Executes this function.\n  @param Stack the stack object.\n  @param VariantManager a reference to variant processor object.\n  @returns a function value.\n}\nfunction TZAsinFunction.Execute(Stack: TZExecutionStack;\n  VariantManager: IZVariantManager): TZVariant;\nbegin\n  CheckParamsCount(Stack, 1);\n  VariantManager.SetAsFloat(Result, ArcSin(\n    VariantManager.GetAsFloat(Stack.GetParameter(1))));\nend;\n\n{ TZAtanFunction }\n\n{**\n  Executes this function.\n  @param Stack the stack object.\n  @param VariantManager a reference to variant processor object.\n  @returns a function value.\n}\nfunction TZAtanFunction.Execute(Stack: TZExecutionStack;\n  VariantManager: IZVariantManager): TZVariant;\nbegin\n  CheckParamsCount(Stack, 1);\n  VariantManager.SetAsFloat(Result, ArcTan(\n    VariantManager.GetAsFloat(Stack.GetParameter(1))));\nend;\n\n{ TZCeilFunction }\n\n{**\n  Executes this function.\n  @param Stack the stack object.\n  @param VariantManager a reference to variant processor object.\n  @returns a function value.\n}\nfunction TZCeilFunction.Execute(Stack: TZExecutionStack;\n  VariantManager: IZVariantManager): TZVariant;\nbegin\n  CheckParamsCount(Stack, 1);\n  VariantManager.SetAsInteger(Result, Ceil(\n    VariantManager.GetAsFloat(Stack.GetParameter(1))));\nend;\n\n{ TZFloorFunction }\n\n{**\n  Executes this function.\n  @param Stack the stack object.\n  @param VariantManager a reference to variant processor object.\n  @returns a function value.\n}\nfunction TZFloorFunction.Execute(Stack: TZExecutionStack;\n  VariantManager: IZVariantManager): TZVariant;\nbegin\n  CheckParamsCount(Stack, 1);\n  VariantManager.SetAsInteger(Result, Floor(\n    VariantManager.GetAsFloat(Stack.GetParameter(1))));\nend;\n\n{ TZRoundFunction }\n\n{**\n  Executes this function.\n  @param Stack the stack object.\n  @param VariantManager a reference to variant processor object.\n  @returns a function value.\n}\nfunction TZRoundFunction.Execute(Stack: TZExecutionStack;\n  VariantManager: IZVariantManager): TZVariant;\nbegin\n  CheckParamsCount(Stack, 1);\n  VariantManager.SetAsInteger(Result, Round(VariantManager.GetAsFloat(Stack.GetParameter(1))));\nend;\n\n{ TZTruncFunction }\n\n{**\n  Executes this function.\n  @param Stack the stack object.\n  @param VariantManager a reference to variant processor object.\n  @returns a function value.\n}\nfunction TZTruncFunction.Execute(Stack: TZExecutionStack;\n  VariantManager: IZVariantManager): TZVariant;\nbegin\n  CheckParamsCount(Stack, 1);\n  VariantManager.SetAsInteger(Result, Trunc(VariantManager.GetAsFloat(Stack.GetParameter(1))));\nend;\n\n{ TZIntFunction }\n\n{**\n  Executes this function.\n  @param Stack the stack object.\n  @param VariantManager a reference to variant processor object.\n  @returns a function value.\n}\nfunction TZIntFunction.Execute(Stack: TZExecutionStack;\n  VariantManager: IZVariantManager): TZVariant;\nbegin\n  CheckParamsCount(Stack, 1);\n  VariantManager.SetAsFloat(Result, Int(VariantManager.GetAsFloat(Stack.GetParameter(1))));\nend;\n\n{ TZFracFunction }\n\n{**\n  Executes this function.\n  @param Stack the stack object.\n  @param VariantManager a reference to variant processor object.\n  @returns a function value.\n}\nfunction TZFracFunction.Execute(Stack: TZExecutionStack;\n  VariantManager: IZVariantManager): TZVariant;\nbegin\n  CheckParamsCount(Stack, 1);\n  VariantManager.SetAsFloat(Result, Frac(VariantManager.GetAsFloat(Stack.GetParameter(1))));\nend;\n\n{ TZSqrFunction }\n\n{**\n  Executes this function.\n  @param Stack the stack object.\n  @param VariantManager a reference to variant processor object.\n  @returns a function value.\n}\nfunction TZSqrFunction.Execute(Stack: TZExecutionStack;\n  VariantManager: IZVariantManager): TZVariant;\nbegin\n  CheckParamsCount(Stack, 1);\n  VariantManager.SetAsFloat(Result, Sqrt(\n    VariantManager.GetAsFloat(Stack.GetParameter(1))));\nend;\n\nprocedure AddMathFunctions(Functions : TZFunctionsList);\nbegin\n  Functions.Add(TZEFunction.Create('E'));\n  Functions.Add(TZPIFunction.Create('PI'));\n  Functions.Add(TZRndFunction.Create('RND'));\n  Functions.Add(TZAbsFunction.Create('ABS'));\n  Functions.Add(TZExpFunction.Create('EXP'));\n  Functions.Add(TZLogFunction.Create('LOG'));\n  Functions.Add(TZLog10Function.Create('LOG10'));\n  Functions.Add(TZCosFunction.Create('COS'));\n  Functions.Add(TZSinFunction.Create('SIN'));\n  Functions.Add(TZTanFunction.Create('TAN'));\n  Functions.Add(TZCotFunction.Create('COT'));\n  Functions.Add(TZAcosFunction.Create('ACOS'));\n  Functions.Add(TZAsinFunction.Create('ASIN'));\n  Functions.Add(TZAtanFunction.Create('ATAN'));\n  Functions.Add(TZRoundFunction.Create('ROUND'));\n  Functions.Add(TZCeilFunction.Create('CEIL'));\n  Functions.Add(TZFloorFunction.Create('FLOOR'));\n  Functions.Add(TZIntFunction.Create('INT'));\n  Functions.Add(TZTruncFunction.Create('TRUNC'));\n  Functions.Add(TZFracFunction.Create('FRAC'));\n  Functions.Add(TZSqrFunction.Create('SQR'));\n  Functions.Add(TZSqrFunction.Create('SQRT'));\nend;\n\nend.\n"
  },
  {
    "path": "lib/zeosdbo/src/core/ZFunctionsOther.pas",
    "content": "{*********************************************************}\n{                                                         }\n{                 Zeos Database Objects                   }\n{             Variables classes and interfaces            }\n{                                                         }\n{           Originally written by Sergey Seroukhov        }\n{                                                         }\n{*********************************************************}\n\n{@********************************************************}\n{    Copyright (c) 1999-2012 Zeos Development Group       }\n{                                                         }\n{ License Agreement:                                      }\n{                                                         }\n{ This library is distributed in the hope that it will be }\n{ useful, but WITHOUT ANY WARRANTY; without even the      }\n{ implied warranty of MERCHANTABILITY or FITNESS FOR      }\n{ A PARTICULAR PURPOSE.  See the GNU Lesser General       }\n{ Public License for more details.                        }\n{                                                         }\n{ The source code of the ZEOS Libraries and packages are  }\n{ distributed under the Library GNU General Public        }\n{ License (see the file COPYING / COPYING.ZEOS)           }\n{ with the following  modification:                       }\n{ As a special exception, the copyright holders of this   }\n{ library give you permission to link this library with   }\n{ independent modules to produce an executable,           }\n{ regardless of the license terms of these independent    }\n{ modules, and to copy and distribute the resulting       }\n{ executable under terms of your choice, provided that    }\n{ you also meet, for each linked independent module,      }\n{ the terms and conditions of the license of that module. }\n{ An independent module is a module which is not derived  }\n{ from or based on this library. If you modify this       }\n{ library, you may extend this exception to your version  }\n{ of the library, but you are not obligated to do so.     }\n{ If you do not wish to do so, delete this exception      }\n{ statement from your version.                            }\n{                                                         }\n{                                                         }\n{ The project web site is located on:                     }\n{   http://zeos.firmos.at  (FORUM)                        }\n{   http://sourceforge.net/p/zeoslib/tickets/ (BUGTRACKER)}\n{   svn://svn.code.sf.net/p/zeoslib/code-0/trunk (SVN)    }\n{                                                         }\n{   http://www.sourceforge.net/projects/zeoslib.          }\n{                                                         }\n{                                                         }\n{                                 Zeos Development Group. }\n{********************************************************@}\n\nunit ZFunctionsOther;\n\ninterface\n\n{$I ZCore.inc}\n\nuses\n  SysUtils, ZFunctions, ZExpression, ZVariant;\n\n{** Other functions}\n\ntype\n\n  {** Implements a EMPTY function. }\n  TZEmptyFunction = class (TZAbstractFunction)\n  public\n    function Execute(Stack: TZExecutionStack;\n      VariantManager: IZVariantManager): TZVariant; override;\n  end;\n\n  {** Implements a MIN function. }\n  TZMinFunction = class (TZAbstractFunction)\n  public\n    function Execute(Stack: TZExecutionStack;\n      VariantManager: IZVariantManager): TZVariant; override;\n  end;\n\n  {** Implements a MAX function. }\n  TZMaxFunction = class (TZAbstractFunction)\n  public\n    function Execute(Stack: TZExecutionStack;\n      VariantManager: IZVariantManager): TZVariant; override;\n  end;\n\n  {** Implements a SUM function. }\n  TZSumFunction = class (TZAbstractFunction)\n  public\n    function Execute(Stack: TZExecutionStack;\n      VariantManager: IZVariantManager): TZVariant; override;\n  end;\n\n  {** Implements a IIF function. }\n  TZIIFFunction = class (TZAbstractFunction)\n  public\n    function Execute(Stack: TZExecutionStack;\n      VariantManager: IZVariantManager): TZVariant; override;\n  end;\n\n  {** Implements a CASEF function. }\n  TZCASEFFunction = class (TZAbstractFunction)\n  public\n    function Execute(Stack: TZExecutionStack;\n      VariantManager: IZVariantManager): TZVariant; override;\n  end;\n\nprocedure AddOtherFunctions(Functions : TZFunctionsList);\n\nimplementation\n\nuses\n  ZMessages;\n\n{ TZEmptyFunction }\n\n{**\n  Executes this function.\n  @param Stack the stack object.\n  @param VariantManager a reference to variant processor object.\n  @returns a function value.\n}\nfunction TZEmptyFunction.Execute(Stack: TZExecutionStack;\n  VariantManager: IZVariantManager): TZVariant;\nvar\n  Value: TZVariant;\nbegin\n  CheckParamsCount(Stack, 1);\n  Value := Stack.GetParameter(1);\n  VariantManager.SetAsBoolean(Result, VariantManager.IsNull(Value));\nend;\n\n{ TZMinFunction }\n\n{**\n  Executes this function.\n  @param Stack the stack object.\n  @param VariantManager a reference to variant processor object.\n  @returns a function value.\n}\nfunction TZMinFunction.Execute(Stack: TZExecutionStack;\n  VariantManager: IZVariantManager): TZVariant;\nvar\n  I, ParamsCount: Integer;\n  Value: TZVariant;\nbegin\n  ParamsCount := VariantManager.GetAsInteger(Stack.GetParameter(0));\n  if ParamsCount < 2 then\n    raise TZExpressionError.Create(SExpectedMoreParams);\n\n  Result := Stack.GetParameter(ParamsCount);\n  for I := 1 to ParamsCount - 1 do\n  begin\n    Value := Stack.GetParameter(I);\n    if VariantManager.Compare(Result, Value) > 0 then\n      Result := Value;\n  end;\nend;\n\n{ TZMaxFunction }\n\n{**\n  Executes this function.\n  @param Stack the stack object.\n  @param VariantManager a reference to variant processor object.\n  @returns a function value.\n}\nfunction TZMaxFunction.Execute(Stack: TZExecutionStack;\n  VariantManager: IZVariantManager): TZVariant;\nvar\n  I, ParamsCount: Integer;\n  Value: TZVariant;\nbegin\n  ParamsCount := VariantManager.GetAsInteger(Stack.GetParameter(0));\n  if ParamsCount < 2 then\n    raise TZExpressionError.Create(SExpectedMoreParams);\n\n  Result := Stack.GetParameter(ParamsCount);\n  for I := 1 to ParamsCount - 1 do\n  begin\n    Value := Stack.GetParameter(I);\n    if VariantManager.Compare(Result, Value) < 0 then\n      Result := Value;\n  end;\nend;\n\n{ TZSumFunction }\n\n{**\n  Executes this function.\n  @param Stack the stack object.\n  @param VariantManager a reference to variant processor object.\n  @returns a function value.\n}\nfunction TZSumFunction.Execute(Stack: TZExecutionStack;\n  VariantManager: IZVariantManager): TZVariant;\nvar\n  I, ParamsCount: Integer;\nbegin\n  ParamsCount := VariantManager.GetAsInteger(Stack.GetParameter(0));\n  if ParamsCount < 2 then\n    raise TZExpressionError.Create(SExpectedMoreParams);\n\n  Result := Stack.GetParameter(ParamsCount);\n  for I := ParamsCount - 1 downto 1 do\n    Result := VariantManager.OpAdd(Result, Stack.GetParameter(I));\nend;\n\n{ TZIIFFunction }\n\n{**\n  Executes this function.\n  @param Stack the stack object.\n  @param VariantManager a reference to variant processor object.\n  @returns a function value.\n}\nfunction TZIIFFunction.Execute(Stack: TZExecutionStack;\n  VariantManager: IZVariantManager): TZVariant;\nbegin\n  CheckParamsCount(Stack, 3);\n  if VariantManager.GetAsBoolean(Stack.GetParameter(3)) then\n     Result := Stack.GetParameter(2)\n   else\n     Result := Stack.GetParameter(1);\nend;\n\n{ TZCASEFFunction }\n\n{**\n  Executes this function.\n  @param Stack the stack object.\n  @param VariantManager a reference to variant processor object.\n  @returns a function value.\n}\nfunction TZCASEFFunction.Execute(Stack: TZExecutionStack;\n  VariantManager: IZVariantManager): TZVariant;\nvar\n  ParamsCount, Index : Integer;\n\nbegin\n  ParamsCount := VariantManager.GetAsInteger(Stack.GetParameter(0));\n  if ParamsCount < 2 then\n    raise TZExpressionError.Create(SExpectedMoreParams);\n  Index := VariantManager.GetAsInteger(Stack.GetParameter(ParamsCount));\n  if ParamsCount < (Index+2) then\n    raise TZExpressionError.Create(SExpectedMoreParams);\n  Result := Stack.GetParameter(ParamsCount-Index-1)\nend;\n\nprocedure AddOtherFunctions(Functions : TZFunctionsList);\nbegin\n  Functions.Add(TZEmptyFunction.Create('EMPTY'));\n  Functions.Add(TZMinFunction.Create('MIN'));\n  Functions.Add(TZMaxFunction.Create('MAX'));\n  Functions.Add(TZSumFunction.Create('SUM'));\n  Functions.Add(TZIIFFunction.Create('IIF'));\n  Functions.Add(TZCASEFFunction.Create('CASEF'));\nend;\n\nend.\n"
  },
  {
    "path": "lib/zeosdbo/src/core/ZFunctionsStrings.pas",
    "content": "{*********************************************************}\n{                                                         }\n{                 Zeos Database Objects                   }\n{             Variables classes and interfaces            }\n{                                                         }\n{           Originally written by Sergey Seroukhov        }\n{                                                         }\n{*********************************************************}\n\n{@********************************************************}\n{    Copyright (c) 1999-2012 Zeos Development Group       }\n{                                                         }\n{ License Agreement:                                      }\n{                                                         }\n{ This library is distributed in the hope that it will be }\n{ useful, but WITHOUT ANY WARRANTY; without even the      }\n{ implied warranty of MERCHANTABILITY or FITNESS FOR      }\n{ A PARTICULAR PURPOSE.  See the GNU Lesser General       }\n{ Public License for more details.                        }\n{                                                         }\n{ The source code of the ZEOS Libraries and packages are  }\n{ distributed under the Library GNU General Public        }\n{ License (see the file COPYING / COPYING.ZEOS)           }\n{ with the following  modification:                       }\n{ As a special exception, the copyright holders of this   }\n{ library give you permission to link this library with   }\n{ independent modules to produce an executable,           }\n{ regardless of the license terms of these independent    }\n{ modules, and to copy and distribute the resulting       }\n{ executable under terms of your choice, provided that    }\n{ you also meet, for each linked independent module,      }\n{ the terms and conditions of the license of that module. }\n{ An independent module is a module which is not derived  }\n{ from or based on this library. If you modify this       }\n{ library, you may extend this exception to your version  }\n{ of the library, but you are not obligated to do so.     }\n{ If you do not wish to do so, delete this exception      }\n{ statement from your version.                            }\n{                                                         }\n{                                                         }\n{ The project web site is located on:                     }\n{   http://zeos.firmos.at  (FORUM)                        }\n{   http://sourceforge.net/p/zeoslib/tickets/ (BUGTRACKER)}\n{   svn://svn.code.sf.net/p/zeoslib/code-0/trunk (SVN)    }\n{                                                         }\n{   http://www.sourceforge.net/projects/zeoslib.          }\n{                                                         }\n{                                                         }\n{                                 Zeos Development Group. }\n{********************************************************@}\n\nunit ZFunctionsStrings;\n\ninterface\n\n{$I ZCore.inc}\n\nuses\n  SysUtils, ZFunctions, ZExpression, ZVariant;\n\n{**  String functions}\n\ntype\n  {** Implements a CONCAT function. }\n  TZConcatFunction = class (TZAbstractFunction)\n  public\n    function Execute(Stack: TZExecutionStack;\n      VariantManager: IZVariantManager): TZVariant; override;\n  end;\n\n  {** Implements a SUBSTR function. }\n  TZSubStrFunction = class (TZAbstractFunction)\n  public\n    function Execute(Stack: TZExecutionStack;\n      VariantManager: IZVariantManager): TZVariant; override;\n  end;\n\n  {** Implements a LEFT function. }\n  TZLeftFunction = class (TZAbstractFunction)\n  public\n    function Execute(Stack: TZExecutionStack;\n      VariantManager: IZVariantManager): TZVariant; override;\n  end;\n\n  {** Implements a RIGHT function. }\n  TZRightFunction = class (TZAbstractFunction)\n  public\n    function Execute(Stack: TZExecutionStack;\n      VariantManager: IZVariantManager): TZVariant; override;\n  end;\n\n  {** Implements a STRPOS function. }\n  TZStrPosFunction = class (TZAbstractFunction)\n  public\n    function Execute(Stack: TZExecutionStack;\n      VariantManager: IZVariantManager): TZVariant; override;\n  end;\n\n  {** Implements a LENGTH function. }\n  TZLengthFunction = class (TZAbstractFunction)\n  public\n    function Execute(Stack: TZExecutionStack;\n      VariantManager: IZVariantManager): TZVariant; override;\n  end;\n\n  {** Implements a UPPER function. }\n  TZUpperFunction = class (TZAbstractFunction)\n  public\n    function Execute(Stack: TZExecutionStack;\n      VariantManager: IZVariantManager): TZVariant; override;\n  end;\n\n  {** Implements a LOWER function. }\n  TZLowerFunction = class (TZAbstractFunction)\n  public\n    function Execute(Stack: TZExecutionStack;\n      VariantManager: IZVariantManager): TZVariant; override;\n  end;\n\n  {** Implements a CAPITALIZE function. }\n  TZCapitalizeFunction = class (TZAbstractFunction)\n  public\n    function Execute(Stack: TZExecutionStack;\n      VariantManager: IZVariantManager): TZVariant; override;\n  end;\n\n  {** Implements a TRIM function. }\n  TZTrimFunction = class (TZAbstractFunction)\n  public\n    function Execute(Stack: TZExecutionStack;\n      VariantManager: IZVariantManager): TZVariant; override;\n  end;\n\n  {** Implements a LTRIM function. }\n  TZLTrimFunction = class (TZAbstractFunction)\n  public\n    function Execute(Stack: TZExecutionStack;\n      VariantManager: IZVariantManager): TZVariant; override;\n  end;\n\n  {** Implements a RTRIM function. }\n  TZRTrimFunction = class (TZAbstractFunction)\n  public\n    function Execute(Stack: TZExecutionStack;\n      VariantManager: IZVariantManager): TZVariant; override;\n  end;\n\n  {** Implements a SOUNDEX function. }\n  TZSoundexFunction = class (TZAbstractFunction)\n  public\n    function Execute(Stack: TZExecutionStack;\n      VariantManager: IZVariantManager): TZVariant; override;\n  end;\n\n  {** Implements a LEVENSHTEINDIST function. }\n  TZLevenshteinDistanceFunction = class (TZAbstractFunction)\n  public\n    function Execute(Stack: TZExecutionStack;\n      VariantManager: IZVariantManager): TZVariant; override;\n  end;\n\nFunction Capitalize(const s:string; Delims : string = '') : string;\nFunction LevenshteinDistance(const s1, s2: string; const DoUpcase : BOOLEAN = TRUE): Integer;\nprocedure AddStringFunctions(Functions : TZFunctionsList);\n\n{$IFNDEF FPC}\n{$ENDIF}\n\nimplementation\n\nuses\n  Math, StrUtils, ZMessages, ZCompatibility;\n\nFunction Capitalize(const s:string; Delims : string = '') : string;\nvar\n  sDelims : set of ansichar;\n  i : integer;\nbegin\n  if Delims = '' then\n    sDelims := StdWordDelims\n  else\n  begin\n    sDelims := [];\n    for i:=1 to Length(Delims) do\n      Include(sDelims,AnsiChar(Delims[i]))\n  end;\n  Result := AnsiProperCase(s, sDelims);\nend;\n\nFunction LevenshteinDistance(const s1, s2: string; const DoUpcase : BOOLEAN = TRUE): Integer;\n\nvar\n  d      : array of array of Integer;\n  s,t    : string;\n  Start,\n  Len1,\n  Len2,\n  i, j,\n  Cost : Integer;\n\nbegin\n  Len1 := Length(s1);\n  Len2 := Length(s2);\n\n  if Len1 = 0 then\n  begin\n    Result := Len2;\n    Exit;\n  end;\n  if Len2 = 0 then\n  begin\n    Result := Len1;\n    Exit;\n  end;\n  if DoUpcase then\n  begin\n    s := Uppercase(s1);\n    t := Uppercase(s2);\n  end\n  else\n  begin\n    s := s1;\n    t := s2;\n  end;\n  start := 1;\n//  trim off the matching items at the beginning\n  while (start <= Len1) and (start <= Len2) and (s[start] = t[start]) do\n      INC(start);\n//  trim off the matching items at the end\n  while (start <= Len1) and (start <= Len2) and (s[Len1] = t[Len2]) do\n  begin\n    DEC(Len1);\n    DEC(Len2);\n  end;\n\n  DEC(Start);\n\n  DEC(Len1, Start);\n  DEC(Len2, Start);\n\n  if Len1 = 0 then\n  begin\n    Result := Len2;\n    Exit;\n  end;\n  if Len2 = 0 then\n  begin\n    Result := Len1;\n    Exit;\n  end;\n\n  setlength(d, Len1 + 1, Len2 + 1);\n  for i := 0 to Len1 do\n    d[i, 0] := i;\n  for j := 0 to Len2 do\n    d[0, j] := j;\n\n//  only loop over the items that are different\n  for i := 1 to Len1 do\n  begin\n    for j := 1 to Len2 do\n    begin\n      Cost := ABS(ORD(s[i+start] <> t[j+start]));\n      d[i, j] := Min(\n                     Min(d[i-1,j]+1,          // deletion\n                         d[i,j-1]+1),         // insertion\n                         d[i-1,j-1]+Cost);    // substitution\n    end;\n  end;\n  Result := d[Len1, Len2];\nend;\n\n{****  This is the original not optimized version\nFunction LevenshteinDistance(const s1, s2: string; const DoUpcase : BOOLEAN = TRUE): Integer;\n\nvar\n  d      : array of array of Integer;\n  s,t    : string;\n  Len1,\n  Len2,\n  i, j,\n  Cost : Integer;\nbegin\n  Len1 := Length(s1);\n  Len2 := Length(s2);\n  if Len1 = 0 then\n  begin\n    Result := Len2;\n    Exit;\n  end;\n  if Len2 = 0 then\n  begin\n    Result := Len1;\n    Exit;\n  end;\n  if DoUpcase then\n  begin\n    s := Upcase(s1);\n    t := Upcase(s2);\n  end\n  else\n  begin\n    s := s1;\n    t := s2;\n  end;\n  setlength(d, Len1 + 1, Len2 + 1);\n  for i := 0 to Len1 do\n    d[i, 0] := i;\n  for j := 0 to Len2 do\n    d[0, j] := j;\n  for i := 1 to Len1 do\n  begin\n    for j := 1 to Len2 do\n    begin\n      Cost := ABS(ORD(s[i] <> t[j]));\n      d[i, j] := Min(\n                     Min(d[i-1,j]+1,\n                         d[i,j-1]+1),\n                         d[i-1,j-1]+Cost);\n    end;\n  end;\n  Result := d[Len1, Len2];\nend;\n******}\n\n{ TZConcatFunction }\n\n{**\n  Executes this function.\n  @param Stack the stack object.\n  @param VariantManager a reference to variant processor object.\n  @returns a function value.\n}\nfunction TZConcatFunction.Execute(Stack: TZExecutionStack;\n  VariantManager: IZVariantManager): TZVariant;\nvar\n  I, ParamsCount: Integer;\n  Temp: string;\nbegin\n  ParamsCount := VariantManager.GetAsInteger(Stack.GetParameter(0));\n  if ParamsCount < 2 then\n    raise TZExpressionError.Create(SExpectedMoreParams);\n\n  Temp := VariantManager.GetAsString(Stack.GetParameter(ParamsCount));\n  for I := ParamsCount - 1 downto 1 do\n    Temp := Temp + VariantManager.GetAsString(Stack.GetParameter(I));\n  VariantManager.SetAsString(Result, Temp);\nend;\n\n{ TZSubStrFunction }\n\n{**\n  Executes this function.\n  @param Stack the stack object.\n  @param VariantManager a reference to variant processor object.\n  @returns a function value.\n}\nfunction TZSubStrFunction.Execute(Stack: TZExecutionStack;\n  VariantManager: IZVariantManager): TZVariant;\nbegin\n  CheckParamsCount(Stack, 3);\n  VariantManager.SetAsString(Result, Copy(\n    VariantManager.GetAsString(Stack.GetParameter(3)),\n    VariantManager.GetAsInteger(Stack.GetParameter(2)),\n    VariantManager.GetAsInteger(Stack.GetParameter(1))));\nend;\n\n{ TZLeftFunction }\nfunction TZLeftFunction.Execute(Stack: TZExecutionStack;\n  VariantManager: IZVariantManager): TZVariant;\nvar\n  Value1, Value2: TZVariant;\nbegin\n  CheckParamsCount(Stack, 2);\n  Value1 := Stack.GetParameter(2);\n  Value2 := Stack.GetParameter(1);\n  VariantManager.SetAsString(Result, LeftStr(Value1.VString, Value2.VInteger));\nend;\n\n{ TZRightFunction }\nfunction TZRightFunction.Execute(Stack: TZExecutionStack;\n  VariantManager: IZVariantManager): TZVariant;\nvar\n  Value1, Value2: TZVariant;\nbegin\n  CheckParamsCount(Stack, 2);\n  Value1 := Stack.GetParameter(2);\n  Value2 := Stack.GetParameter(1);\n  VariantManager.SetAsString(Result, RightStr(Value1.VString, Value2.VInteger));\nend;\n\n{ TZStrPosFunction }\n\n{**\n  Executes this function.\n  @param Stack the stack object.\n  @param VariantManager a reference to variant processor object.\n  @returns a function value.\n}\nfunction TZStrPosFunction.Execute(Stack: TZExecutionStack;\n  VariantManager: IZVariantManager): TZVariant;\nbegin\n  CheckParamsCount(Stack, 2);\n  VariantManager.SetAsInteger(Result, Pos(\n    VariantManager.GetAsString(Stack.GetParameter(2)),\n    VariantManager.GetAsString(Stack.GetParameter(1))));\nend;\n\n{ TZLengthFunction }\n\n{**\n  Executes this function.\n  @param Stack the stack object.\n  @param VariantManager a reference to variant processor object.\n  @returns a function value.\n}\nfunction TZLengthFunction.Execute(Stack: TZExecutionStack;\n  VariantManager: IZVariantManager): TZVariant;\nbegin\n  CheckParamsCount(Stack, 1);\n  VariantManager.SetAsInteger(Result, Length(VariantManager.GetAsString(Stack.GetParameter(1))));\nend;\n\n{ TZLowerFunction }\n\n{**\n  Executes this function.\n  @param Stack the stack object.\n  @param VariantManager a reference to variant processor object.\n  @returns a function value.\n}\nfunction TZLowerFunction.Execute(Stack: TZExecutionStack;\n  VariantManager: IZVariantManager): TZVariant;\nbegin\n  CheckParamsCount(Stack, 1);\n  VariantManager.SetAsString(Result, AnsiLowerCase(\n    VariantManager.GetAsString(Stack.GetParameter(1))));\nend;\n\n{ TZUpperFunction }\n\n{**\n  Executes this function.\n  @param Stack the stack object.\n  @param VariantManager a reference to variant processor object.\n  @returns a function value.\n}\nfunction TZUpperFunction.Execute(Stack: TZExecutionStack;\n  VariantManager: IZVariantManager): TZVariant;\nbegin\n  CheckParamsCount(Stack, 1);\n  VariantManager.SetAsString(Result, AnsiUpperCase(\n    VariantManager.GetAsString(Stack.GetParameter(1))));\nend;\n\n{ TZCapitalizeFunction }\n\nfunction TZCapitalizeFunction.Execute(Stack: TZExecutionStack;\n  VariantManager: IZVariantManager): TZVariant;\nvar\n  ParamsCount: Integer;\nbegin\n  ParamsCount := VariantManager.GetAsInteger(Stack.GetParameter(0));\n  if (ParamsCount < 1) then\n    raise TZExpressionError.Create(SExpectedMoreParams);\n  if (ParamsCount < 2) then\n    VariantManager.SetAsString(Result, Capitalize(\n      VariantManager.GetAsString(Stack.GetParameter(1))))\n  else\n    VariantManager.SetAsString(Result, Capitalize(\n      VariantManager.GetAsString(Stack.GetParameter(2)),\n      VariantManager.GetAsString(Stack.GetParameter(1))))\nend;\n\n{ TZTrimFunction }\n\nfunction TZTrimFunction.Execute(Stack: TZExecutionStack;\n  VariantManager: IZVariantManager): TZVariant;\nvar\n  Value: TZVariant;\nbegin\n  CheckParamsCount(Stack, 1);\n  Value := Stack.GetParameter(1);\n  VariantManager.SetAsString(Result, Trim(Value.VString));\nend;\n\n{ TZLTrimFunction }\n\nfunction TZLTrimFunction.Execute(Stack: TZExecutionStack;\n  VariantManager: IZVariantManager): TZVariant;\nvar\n  Value: TZVariant;\nbegin\n  CheckParamsCount(Stack, 1);\n  Value := Stack.GetParameter(1);\n  VariantManager.SetAsString(Result, TrimLeft(Value.VString));\nend;\n\n{ TZRTrimFunction }\n\nfunction TZRTrimFunction.Execute(Stack: TZExecutionStack;\n  VariantManager: IZVariantManager): TZVariant;\nvar\n  Value: TZVariant;\nbegin\n  CheckParamsCount(Stack, 1);\n  Value := Stack.GetParameter(1);\n  VariantManager.SetAsString(Result, TrimRight(Value.VString));\nend;\n\n{ TZSoundexFunction }\n\nfunction TZSoundexFunction.Execute(Stack: TZExecutionStack;\n  VariantManager: IZVariantManager): TZVariant;\nvar\n  ParamsCount: Integer;\nbegin\n  ParamsCount := VariantManager.GetAsInteger(Stack.GetParameter(0));\n  if (ParamsCount < 1) then\n    raise TZExpressionError.Create(SExpectedMoreParams);\n  if (ParamsCount < 2) then\n    VariantManager.SetAsString(Result, Soundex(\n      VariantManager.GetAsString(Stack.GetParameter(1))))\n  else\n    VariantManager.SetAsString(Result, Soundex(\n      VariantManager.GetAsString(Stack.GetParameter(2)),\n      VariantManager.GetAsInteger(Stack.GetParameter(1))))\nend;\n\nfunction TZLevenshteinDistanceFunction.Execute(Stack: TZExecutionStack;\n  VariantManager: IZVariantManager): TZVariant;\n\nvar\n  ParamsCount: Integer;\nbegin\n  ParamsCount := VariantManager.GetAsInteger(Stack.GetParameter(0));\n  if (ParamsCount < 2) then\n    raise TZExpressionError.Create(SExpectedMoreParams);\n  if (ParamsCount < 3) then\n    VariantManager.SetAsInteger(Result,\n                                  LevenshteinDistance(\n                                    VariantManager.GetAsString(Stack.GetParameter(2)),\n                                    VariantManager.GetAsString(Stack.GetParameter(1))))\n  else\n    VariantManager.SetAsInteger(Result,\n                                LevenshteinDistance(\n                                  VariantManager.GetAsString(Stack.GetParameter(3)),\n                                  VariantManager.GetAsString(Stack.GetParameter(2)),\n                                  VariantManager.GetAsBoolean(Stack.GetParameter(1))))\nend;\n\nprocedure AddStringFunctions(Functions : TZFunctionsList);\nbegin\n  Functions.Add(TZConcatFunction.Create('CONCAT'));\n  Functions.Add(TZSubStrFunction.Create('SUBSTR'));\n  Functions.Add(TZLeftFunction.Create('LEFT'));\n  Functions.Add(TZRightFunction.Create('RIGHT'));\n  Functions.Add(TZStrPosFunction.Create('STRPOS'));\n  Functions.Add(TZLengthFunction.Create('LENGTH'));\n\n  Functions.Add(TZUpperFunction.Create('UPPER'));\n  Functions.Add(TZLowerFunction.Create('LOWER'));\n  Functions.Add(TZCapitalizeFunction.Create('CAP'));\n  Functions.Add(TZCapitalizeFunction.Create('CAPITALIZE'));\n\n  Functions.Add(TZTrimFunction.Create('TRIM'));\n  Functions.Add(TZLTrimFunction.Create('LTRIM'));\n  Functions.Add(TZRTrimFunction.Create('RTRIM'));\n\n  Functions.Add(TZSoundexFunction.Create('SOUNDEX'));\n  Functions.Add(TZLevenshteinDistanceFunction.Create('LEVDIST'));\n  Functions.Add(TZLevenshteinDistanceFunction.Create('LEVENSHTEINDISTANCE'));\nend;\n\nend.\n\n"
  },
  {
    "path": "lib/zeosdbo/src/core/ZMatchPattern.pas",
    "content": "{*********************************************************}\n{                                                         }\n{                 Zeos Database Objects                   }\n{                  Regular Expressions                    }\n{                                                         }\n{            Originally written by Sergey Seroukhov       }\n{                                                         }\n{*********************************************************}\n\n{@********************************************************}\n{    Copyright (c) 1999-2012 Zeos Development Group       }\n{                                                         }\n{ License Agreement:                                      }\n{                                                         }\n{ This library is distributed in the hope that it will be }\n{ useful, but WITHOUT ANY WARRANTY; without even the      }\n{ implied warranty of MERCHANTABILITY or FITNESS FOR      }\n{ A PARTICULAR PURPOSE.  See the GNU Lesser General       }\n{ Public License for more details.                        }\n{                                                         }\n{ The source code of the ZEOS Libraries and packages are  }\n{ distributed under the Library GNU General Public        }\n{ License (see the file COPYING / COPYING.ZEOS)           }\n{ with the following  modification:                       }\n{ As a special exception, the copyright holders of this   }\n{ library give you permission to link this library with   }\n{ independent modules to produce an executable,           }\n{ regardless of the license terms of these independent    }\n{ modules, and to copy and distribute the resulting       }\n{ executable under terms of your choice, provided that    }\n{ you also meet, for each linked independent module,      }\n{ the terms and conditions of the license of that module. }\n{ An independent module is a module which is not derived  }\n{ from or based on this library. If you modify this       }\n{ library, you may extend this exception to your version  }\n{ of the library, but you are not obligated to do so.     }\n{ If you do not wish to do so, delete this exception      }\n{ statement from your version.                            }\n{                                                         }\n{                                                         }\n{ The project web site is located on:                     }\n{   http://zeos.firmos.at  (FORUM)                        }\n{   http://sourceforge.net/p/zeoslib/tickets/ (BUGTRACKER)}\n{   svn://svn.code.sf.net/p/zeoslib/code-0/trunk (SVN)    }\n{                                                         }\n{   http://www.sourceforge.net/projects/zeoslib.          }\n{                                                         }\n{                                                         }\n{                                 Zeos Development Group. }\n{********************************************************@}\n\nunit ZMatchPattern;\n{\n  Author: Kevin Boylan\n  Ported By: Sergey Seroukhov\n\n  This code is meant to allow wildcard pattern matches.\n  It is VERY useful for matching filename wildcard patterns.\n  It allows unix grep-like pattern comparisons, for instance:\n\n\t?\t   \tMatches any single characer\n\t*\t   \tMatches any contiguous characters\n\t[abc]  \tMatches a or b or c at that position\n\t[^abc]\tMatches anything but a or b or c at that position\n\t[!abc]\tDitto\n\t[a-e]  \tMatches a through e at that position\n\n\t'ma?ch.*'\t-Would match match.exe, mavch.dat, march.on, etc\n\t'this [e-n]s a [!zy]est' - Would match 'this is a test',\n                               but would not match 'this as a yest'\n\n  This is a Delphi VCL translation from C code that was downloaded from CIS.\n  C code was written by J. Kerceval and released to public domain 02/20/1991.\n  This code is ofcourse also public domain. I would appreciate it if you would\n  let me know if you find any bugs.  I would also appreciate any notes sent my\n  way letting me know if you find it useful.\n}\n\n{$I ZCore.inc}\n\ninterface\n\nuses SysUtils;\n\n{ Check if Text equal to pattern }\nfunction IsMatch(const Pattern, Text: string): Boolean;\n\nimplementation\n\nconst\n{ Match defines }\n  MATCH_PATTERN\t  = 6;\n  MATCH_LITERAL\t  = 5;\n  MATCH_RANGE\t  = 4;\n  MATCH_ABORT\t  = 3;\n  MATCH_END\t  = 2;\n  MATCH_VALID\t  = 1;\n{ Pattern defines }\n{  PATTERN_VALID\t  =  0;\n  PATTERN_ESC\t  = -1;\n  PATTERN_RANGE\t  = -2;\n  PATTERN_CLOSE\t  = -3;\n  PATTERN_EMPTY\t  = -4;\n}{ Character defines }\n  MATCH_CHAR_SINGLE\t        = '?';\n  MATCH_CHAR_KLEENE_CLOSURE     = '*';\n  MATCH_CHAR_RANGE_OPEN\t        = '[';\n  MATCH_CHAR_RANGE\t        = '-';\n  MATCH_CHAR_RANGE_CLOSE        = ']';\n  MATCH_CHAR_CARET_NEGATE       = '^';\n  MATCH_CHAR_EXCLAMATION_NEGATE\t= '!';\n\nfunction Matche(Pattern, Text: string): Integer; forward;\nfunction MatchAfterStar(Pattern, Text: string): Integer; forward;\n//function IsPattern(Pattern: string): Boolean; forward;\n\nfunction IsMatch(const Pattern, Text: string): Boolean;\nbegin\n  Result := (Matche(Pattern, Text) = 1);\nend;\n\nfunction Matche(Pattern, Text: string): Integer;\nvar\n  RangeStart, RangeEnd, P, T, PLen, TLen: Integer;\n  Invert, MemberMatch, Loop: Boolean;\nbegin\n  P := 1;\n  T := 1;\n  Pattern := AnsiLowerCase(pattern);\n  Text    := AnsiLowerCase(Text);\n  PLen    := Length(pattern);\n  TLen    := Length(text);\n  Result  := 0;\n  while ((Result = 0) and (P <= PLen)) do\n  begin\n    if T > TLen then\n    begin\n      if (Pattern[P] = MATCH_CHAR_KLEENE_CLOSURE) and (P+1 > PLen) then\n        Result := MATCH_VALID\n      else\n        Result := MATCH_ABORT;\n      Exit;\n    end\n    else\n      case (Pattern[P]) of\n        MATCH_CHAR_KLEENE_CLOSURE:\n          Result := MatchAfterStar(Copy(Pattern,P,PLen),Copy(Text,T,TLen));\n        MATCH_CHAR_RANGE_OPEN:\n          begin\n            Inc(P);\n            Invert := False;\n            if (Pattern[P] = MATCH_CHAR_EXCLAMATION_NEGATE) or\n              (Pattern[P] = MATCH_CHAR_CARET_NEGATE) then\n            begin\n              Invert := True;\n              Inc(P);\n            end;\n            if (Pattern[P] = MATCH_CHAR_RANGE_CLOSE) then\n            begin\n              Result := MATCH_PATTERN;\n              Exit;\n            end;\n            MemberMatch := False;\n            Loop := True;\n            while (Loop and (Pattern[P] <> MATCH_CHAR_RANGE_CLOSE)) do\n            begin\n              RangeStart := P;\n              RangeEnd := P;\n              Inc(P);\n              if P > PLen then\n              begin\n                Result := MATCH_PATTERN;\n                Exit;\n              end;\n              if Pattern[P] = MATCH_CHAR_RANGE then\n              begin\n                Inc(P);\n                RangeEnd := P;\n              if (P > PLen) or (Pattern[RangeEnd] = MATCH_CHAR_RANGE_CLOSE) then\n              begin\n                Result := MATCH_PATTERN;\n                Exit;\n              end;\n              Inc(P);\n            end;\n            if P > PLen then\n            begin\n              Result := MATCH_PATTERN;\n              Exit;\n            end;\n            if RangeStart < RangeEnd then\n            begin\n              if (Text[T] >= Pattern[RangeStart]) and\n                (Text[T] <= Pattern[RangeEnd]) then\n              begin\n                MemberMatch := True;\n                Loop := False;\n              end;\n            end\n            else\n            begin\n              if (Text[T] >= Pattern[RangeEnd]) and\n                (Text[T] <= Pattern[RangeStart]) then\n              begin\n                MemberMatch := True;\n                Loop := False;\n              end;\n            end;\n          end;\n          if (Invert and MemberMatch) or (not (Invert or MemberMatch)) then\n          begin\n            Result := MATCH_RANGE;\n            Exit;\n          end;\n          if MemberMatch then\n            while (P <= PLen) and (Pattern[P] <> MATCH_CHAR_RANGE_CLOSE) do\n              Inc(P);\n            if P > PLen then\n            begin\n              Result := MATCH_PATTERN;\n              Exit;\n            end;\n          end;\n        else\n          if Pattern[P] <> MATCH_CHAR_SINGLE then\n            if Pattern[P] <> Text[T] then\n              Result := MATCH_LITERAL;\n      end;\n    Inc(P);\n    Inc(T);\n  end;\n  if Result = 0 then\n    if T <= TLen then\n      Result := MATCH_END\n    else\n      Result := MATCH_VALID;\nend;\n\nfunction MatchAfterStar(Pattern, Text: string): Integer;\nvar\n  P, T, PLen, TLen: Integer;\nbegin\n  Result := 0;\n  P := 1;\n  T := 1;\n  PLen := Length(Pattern);\n  TLen := Length(Text);\n  if (TLen = 1) and (PLen = 1) then //pattern like '*ring*' schould not match if Text 'A'\n  begin\n    Result := MATCH_VALID;\n    Exit;\n  end;\n  if (PLen = 0) or (TLen = 0) then\n  begin\n    Result := MATCH_ABORT;\n    Exit;\n  end;\n  while ((T <= TLen) and (P < PLen)) and ((Pattern[P] = MATCH_CHAR_SINGLE) or\n    (Pattern[P] = MATCH_CHAR_KLEENE_CLOSURE)) do\n  begin\n    if Pattern[P] = MATCH_CHAR_SINGLE then\n      Inc(T);\n    Inc(P);\n  end;\n  if T >= TLen then\n  begin\n    Result := MATCH_ABORT;\n    Exit;\n  end;\n  if P >= PLen then\n  begin\n    Result := MATCH_VALID;\n    Exit;\n  end;\n  repeat\n    if (Pattern[P] = Text[T]) or (Pattern[P] = MATCH_CHAR_RANGE_OPEN) then\n    begin\n      Pattern := Copy(Pattern, P, PLen);\n      Text    := Copy(Text, T, TLen);\n      PLen    := Length(Pattern);\n      TLen    := Length(Text);\n      p := 1;\n      t := 1;\n      Result  := Matche(Pattern, Text);\n      if Result <> MATCH_VALID then\n        Result := 0;//retry until end of Text, (check below) or Result valid\n    end;\n    Inc(T);\n    if (T > TLen) or (P > PLen) then\n    begin\n      Result := MATCH_ABORT;\n      Exit;\n    end;\n  until Result <> 0;\nend;\n\n(*\nfunction IsPattern(const Pattern: string): Boolean;\nvar\n  I: Integer;\nbegin\n  Result := False;\n  for I := 1 to Length(Pattern) do\n    if Pos(Pattern[I], '[]?*') > 0 then\n    begin\n      Result := True;\n      Exit;\n    end;\nend;\n*)\n\nend.\n\n\n"
  },
  {
    "path": "lib/zeosdbo/src/core/ZMessages.pas",
    "content": "{*********************************************************}\n{                                                         }\n{                 Zeos Database Objects                   }\n{             Constant messages used by Zeos              }\n{                                                         }\n{ This unit contains all the messages that are output by  }\n{ ZEOS methods. One of the given language can be activated}\n{ by setting the language in ->                           }\n{ ZEOS.inc (e.g.: $DEFINE GERMAN).                        }\n{ If no language is defined english will be used.         }\n{                                                         }\n{*********************************************************}\n\n{@********************************************************}\n{    Copyright (c) 1999-2012 Zeos Development Group       }\n{                                                         }\n{ License Agreement:                                      }\n{                                                         }\n{ This library is distributed in the hope that it will be }\n{ useful, but WITHOUT ANY WARRANTY; without even the      }\n{ implied warranty of MERCHANTABILITY or FITNESS FOR      }\n{ A PARTICULAR PURPOSE.  See the GNU Lesser General       }\n{ Public License for more details.                        }\n{                                                         }\n{ The source code of the ZEOS Libraries and packages are  }\n{ distributed under the Library GNU General Public        }\n{ License (see the file COPYING / COPYING.ZEOS)           }\n{ with the following  modification:                       }\n{ As a special exception, the copyright holders of this   }\n{ library give you permission to link this library with   }\n{ independent modules to produce an executable,           }\n{ regardless of the license terms of these independent    }\n{ modules, and to copy and distribute the resulting       }\n{ executable under terms of your choice, provided that    }\n{ you also meet, for each linked independent module,      }\n{ the terms and conditions of the license of that module. }\n{ An independent module is a module which is not derived  }\n{ from or based on this library. If you modify this       }\n{ library, you may extend this exception to your version  }\n{ of the library, but you are not obligated to do so.     }\n{ If you do not wish to do so, delete this exception      }\n{ statement from your version.                            }\n{                                                         }\n{                                                         }\n{ The project web site is located on:                     }\n{   http://zeos.firmos.at  (FORUM)                        }\n{   http://sourceforge.net/p/zeoslib/tickets/ (BUGTRACKER)}\n{   svn://svn.code.sf.net/p/zeoslib/code-0/trunk (SVN)    }\n{                                                         }\n{   http://www.sourceforge.net/projects/zeoslib.          }\n{                                                         }\n{                                                         }\n{                                 Zeos Development Group. }\n{********************************************************@}\n\nunit ZMessages;\n\ninterface\n\n{$I ZCore.inc}\n\nprocedure loadmessages();\n\nresourcestring\n\n  cSLibraryNotCompatible = 'Client-Library %s found but could not be loaded. Check compile-target and library compatibility!';\n//--- added by Serge Girard --------------------------------------------------------\n{$IFDEF FRENCH}\n  cSSQLError1 = 'Erreur SQL: %s';\n  cSSQLError2 = 'Erreur SQL: %s Code: %d';\n  cSSQLError3 = 'Erreur SQL: %s Code: %d SQL: %s';\n  cSSQLError4 = 'Erreur SQL: %s Code: %d Message: %s';\n\n  cSListCapacityError = 'Capacit de liste hors limite (%d)';\n  cSListCountError = 'Compteur de liste (count) hors limite (%d)';\n  cSListIndexError = 'Index de liste hors limite (%d)';\n\n  cSClonningIsNotSupported = 'Le clonage n''est pas support pour cette classe';\n  cSImmutableOpIsNotAllowed = 'L''opration n''est pas permise sur des collections non modifiables';\n  cSStackIsEmpty = 'La pile est vide';\n  cSVariableWasNotFound = 'Variable \"%s\" non trouve';\n  cSFunctionWasNotFound = 'Fonction \"%s\" non trouve';\n  cSInternalError = 'Erreur interne';\n  cSSyntaxErrorNear = 'Erreur de syntaxe proche de \"%s\"';\n  cSSyntaxError = 'Erreur de syntaxe';\n  cSUnknownSymbol = 'Symbole inconnu \"%s\"';\n  cSUnexpectedExprEnd = 'Fin d''expression imprvue';\n  cSRightBraceExpected = ') attendue';\n  cSParametersError = '%d paramtres attendus mais %d ont t trouvs';\n  cSExpectedMoreParams = 'Plus de deux paramtres sont attendus';\n  cSInvalidVarByteArray = 'Tableau de VarByte non valide';\n  cSVariableAlreadyExists = 'La variable \"%s\" existe dj';\n  cSTypesMismatch = 'Types non concordants';\n  cSUnsupportedVariantType = 'Type variant non support';\n  cSUnsupportedOperation = 'Opration non supporte';\n\n  cSTokenizerIsNotDefined = 'l''objet Tokenizer n''est pas dfini';\n  cSLibraryNotFound = 'Acune des bibliothques dynamiques ne peut tre trouve ou charge: %s !'#10#13'Utilisez TZConnection.LibraryLocation si l''emplacement est incorrect.';\n  cSEncodeDateIsNotSupported = 'Cette version ne supporte pas isc_encode_sql_date';\n  cSEncodeTimeIsNotSupported = 'Cette version ne supporte pas isc_encode_sql_time';\n  cSEncodeTimestampIsNotSupported = 'Cette version ne supporte pas isc_encode_sql_timestamp';\n  cSDecodeDateIsNotSupported = 'Cette version ne supporte pas isc_decode_sql_date';\n  cSDecodeTimeIsNotSupported = 'Cette version ne supporte pas isc_decode_sql_time';\n  cSDecodeTimestampIsNotSupported = 'Cette version ne supporte pas isc_decode_sql_timestamp';\n\n  cSCanNotRetrieveResultSetData = 'Ne peut rcuprer l''ensemble de donnes rsultant';\n  cSRowBufferIsNotAssigned = 'Le buffer de ligne n''est pas assign';\n  cSColumnIsNotAccessable = 'Colonne d''index %d inaccessible';\n  cSConvertionIsNotPossible = 'Conversion impossible de la colonne %d de %s vers %s';\n  cSCanNotAccessBlobRecord = 'Ne peut accder au blob de la colonne %d avec le type %s';\n  cSRowDataIsNotAvailable = 'Ligne de donnes non disponible';\n  cSResolverIsNotSpecified = 'L''objet Resolver n''est pas indiqu';\n  cSResultsetIsAlreadyOpened = 'L''ensemble rsultat est dj ouvert';\n  cSCanNotUpdateEmptyRow = 'Ne peut mettre  jour une ligne vide';\n  cSCanNotUpdateDeletedRow = 'Ne peut mettre  jour une ligne supprime';\n  cSCanNotDeleteEmptyRow = 'Ne peut supprimer un ligne vide';\n  cSCannotUseCommit = 'Vous ne pouvez pas utiliser COMMIT en mode AUTOCOMMIT';\n  cSCannotUseRollBack = 'Vous ne pouvez pas utiliser ROLLBACK en mode AUTOCOMMIT';\n  cSCanNotUpdateComplexQuery = 'Ne peut mettre  jour une requte complexe impliquant plus d''une table';\n  cSCanNotUpdateThisQueryType = 'Ne peut mettre  jour ce type de requte';\n  cSDriverWasNotFound = 'Le driver de base de donnes demand n''a pas t trouv';\n  cSCanNotConnectToServer = 'Ne peut se connecter au serveur SQL';\n  cSTableIsNotSpecified = 'La table n''est pas spcifie';\n  cSLiveResultSetsAreNotSupported = 'Une requte actualisable n''est pas supporte par cette classe';\n  cSInvalidInputParameterCount = 'Le nombre de paramtres attendu est infrieur au prvu';\n  cSIsolationIsNotSupported = 'Niveau d''isolation de transaction non support';\n  cSColumnWasNotFound = 'Colonne de nom \"%s\" non trouve';\n  cSWrongTypeForBlobParameter = 'Type incorrect pour le paramtre Blob';\n  cSIncorrectConnectionURL = 'Connexion URL: %s incorrect';\n  cSUnsupportedProtocol = 'Protocole: %s non support';\n  cSUnsupportedByDriver    = 'Le driver d''origine ne supporte pas cette fonctionnalit: [%s]';\n\n  cSConnectionIsNotOpened = 'Connexion non encore ouverte';\n  cSInvalidOpInAutoCommit = 'Opration non valide en mode AutoCommit';\n  cSInvalidOpInNonAutoCommit = 'Opration non valide si le mode n''est pas AutoCommit';\n  cSInvalidOpPrepare = 'Prparer une transaction n''est possible qu''en en dmarrant une (Starttransaction) d''abord (!)';\n\n  cSConnectionIsNotAssigned = 'La connexion  la base donnes n''est pas indiqu';\n  cSQueryIsEmpty = 'La requte SQL est vide';\n  cSCanNotExecuteMoreQueries = 'Ne peut excuter plus d''une requte';\n  cSOperationIsNotAllowed1 = 'Cette opration n''est pas permise en mode FORWARD ONLY';\n  cSOperationIsNotAllowed2 = 'Cette opration n''est pas permise en mode READ ONLY';\n  cSOperationIsNotAllowed3 = 'Cette opration n''est pas permise en mode %s';\n  cSOperationIsNotAllowed4 = 'Cette opration n''est pas permise en mode sur un ensemble de donnes ferm';\n  cSNoMoreRecords = 'Plus d''enregistrements dans l''ensemble de donnes';\n  cSCanNotOpenResultSet = 'Ne peut ouvrir un ensemble de donnes';\n  cSCanNotOpenDataSetWhenDestroying ='Ne peut ouvrir un ensemble de donnes alors que l''tat du composant est dsDestroying';\n  cSCircularLink = 'Lien circulaire cr par le Datasource';\n  cSBookmarkWasNotFound = 'Le marque page (Bookmark) n''a pas t trouv';\n  cSIncorrectSearchFieldsNumber = 'Nombre incorrect de valeurs de recherche';\n  cSInvalidOperationInTrans = 'Opration invalide dans un mode de transaction explicite';\n  cSIncorrectSymbol = 'Symbole incorrect dans la liste des champs \"%s\".';\n  cSIncorrectToken = 'Token incorrect suivi par \":\"';\n  cSIncorrectParamChar = 'Valeur non valide pour ParamChar';\n\n  cSSelectedTransactionIsolation = 'Le niveau d''isolation de transaction slectionn n''est pas support';\n  cSDriverNotSupported = 'Driver non support %s';\n  cSPattern2Long = 'Le Pattern est trop long';\n  cSDriverNotCapableOutParameters = 'Le Driver n''est pas capable d''utiliser des paramtres';\n  cSStatementIsNotAllowed = 'Dclaration non permise';\n  cSStoredProcIsNotAllowed = 'La procdure stocke n''est pas permise';\n  cSCannotPerformOperation = 'Ne peut effectuer cette opration sur une ensemble de donnes ferm';\n  cSInvalidState = 'tat non valide';\n  cSErrorConvertion = 'Erreur de conversion';\n  cSDataTypeDoesNotSupported = 'Type de donne non support';\n  cSUnsupportedParameterType = 'Type de paramtre non support';\n  cSUnsupportedDataType = 'Type de donne non support';\n  cSErrorConvertionField = 'Erreur de conversion pour le champ \"%s\" vers le type SQL \"%s\"';\n  cSBadOCI = 'Mauvaise version OCI [%s] . Version 8.0.3 ou plus ancienne requise';\n  cSConnect2AsUser = 'Connexion  \"%s\" en tant qu''utilisateur \"%s\"';\n  cSUnknownError = 'Erreur inconnue';\n  cSFieldNotFound1 = 'Champ \"%s\" non trouv';\n  cSFieldNotFound2 = 'Champ %d non trouv';\n\n  cSLoginPromptFailure = 'Ne peut trouver le dialogue d''identification par dfaut. Ajoutez ,S.V.P. DBLogDlg dans la section uses section de votre fichier principal.';\n\n  cSPropertyQuery = 'La requte peut prendre un certain temps sur des bases de donnes importantes!';\n  cSPropertyTables = 'Vous devriez la limiter via Catalogue et/ou Schma.';\n  cSPropertyColumns = 'Vous devriez la limiter via Catalogue, Schma et/ou Nom de Table.';\n  cSPropertyProcedures = 'Vous devriez la limiter via Catalogue et/ou Schema.';\n  cSPropertySequences = 'Vous devriez la limiter via Catalogue et/ou Schema.';\n  cSPropertyExecute = 'La Requte doit-elle s''excuter quand mme?';\n\n  cSFormTest = 'diteur SQL ZEOS Test';\n  cSButtonClose = '&Fermer';\n  cSFormEditor = 'diteur SQL ZEOS';\n  cSTabSheetSelect = 'Select SQL';\n  cSMenuLoad = 'Charger';\n  cSMenuSave = 'Sauver';\n  cSButtonGenerate = '&Gnrer';\n  cSButtonCheck = '&Vrifier';\n  cSButtonTest = '&Tester';\n  cSButtonOk = '&OK';\n  cSButtonCancel = 'A&nnuler';\n  cSTableAlias = 'T&able alias';\n  cSReplaceSQL = '&Remplacer le SQL';\n  cSDialogOpenTitle = 'Ouvrir fichier SQL';\n  cSDialogSaveTitle = 'Sauver dans un fichier SQL';\n  cSSQLEditor = 'diteur SQL';\n  cSDatabaseDialog = 'Ouvrir base existante';\n\n  cSUpdateSQLNoResult = '\"Update Refresh SQL\" ne fourni aucun ensemble de rsultat';\n  cSUpdateSQLRefreshStatementcount ='La dclaration de l''\"Update Refresh SQL\" ne peut tre qu''unique';\n\n  {$IFDEF FPC}\n  cSNotEditing = 'L''ensemble de donnes n''est ni en modification ni en insertion';\n  cSFieldTypeMismatch = 'Diffrence de type pour le champ ''%s'', attendu: %s trouv: %s';\n  cSFieldSizeMismatch = 'Diffrence de taille pour le champ ''%s'', attendue: %d trouve: %d';\n  {$ENDIF}\n  cSNeedField               = 'Le champ %s est requis, mais non renseign.';\n\n  cSFailedtoInitPrepStmt   = 'La dclaration a choue  l''initialisation';\n  cSFailedtoPrepareStmt    = 'La dclaration a choue durant le processus de prparation';\n  cSFailedToBindAllValues  = 'L''application a chou  pr-relier toutes les valeurs';\n  cSAttemptExecOnBadPrep   = 'Tentative d''excuter une dclaration avant une prparation russie.';\n  cSBindingFailure         = 'chec  relier l''ensemble des paramtres';\n  cSPreparedStmtExecFailure = 'La prparation de la dclaration a chou';\n  cSBoundVarStrIndexMissing = 'Nom de la variable de relation \"%s\" inexistant';\n  cSBindVarOutOfRange      = 'Index de la variable de relation hors limite: %d';\n  cSFailedToBindResults    = 'L''application a chou  lier l''ensemble rsultat';\n\n//FOS+ 07112006\n  cSRefreshRowOnlySupportedWithUpdateObject = 'La mthode \"refreshrow\" n''est permise qu''avec un objet de mise  jour(Update)';\n  cSMustBeInBrowseMode = 'Opration uniquement permise dans l''tat dsBROWSE';\n\n  cSUnKnownParamDataType = 'Param.DataType inconnu';\n  cSFieldReadOnly        = ' A un champ en lecture seule on ne peut assigner une valeur : %s';\n  cSInvalidUpdateCount     = '%d enregistrement(s) mis  jour. Un seul urait du l''tre.';\n\n  cSRowBufferWidthExceeded ='La taille du buffer de lignes a t dpasse. Essayez d''utiliser moins ou de plus longues colonnes dans la requte SQL.';\n//--- end added by Serge Girard ------------------------------------\n{$ELSE !FRENCH}\n// -> ms, 09/05/2005\n{$IFDEF PORTUGUESE}\n  cSSQLError1 = 'Erro SQL: %s';\n  cSSQLError2 = 'Erro SQL: %s Cdigo: %d';\n  cSSQLError3 = 'Erro SQL: %s Cdigo: %d SQL: %s';\n  cSSQLError4 = 'Erro SQL: %s Cdigo: %d Mensagem: %s';\n\n  cSListCapacityError = 'Capacidade da Lista fora do limite (%d)';\n  cSListCountError = 'Contagem da Lista fora do limite (%d)';\n  cSListIndexError = 'ndice da Lista fora do limite (%d)';\n\n  cSClonningIsNotSupported = 'Clonagem no  suportada por esta classe';\n  cSImmutableOpIsNotAllowed = 'A operao no  permitida para coleo imutvel';\n  cSStackIsEmpty = 'Pilha est vazia';\n  cSVariableWasNotFound = 'Varivel \"%s\" no foi encontrada';\n  cSFunctionWasNotFound = 'Function \"%s\" no foi encontrada';\n  cSInternalError = 'Erro interno';\n  cSSyntaxErrorNear = 'Erro de sintaxe prximo a \"%s\"';\n  cSSyntaxError = 'Erro de sintaxe';\n  cSUnknownSymbol = 'Smbolo desconhecido \"%s\"';\n  cSUnexpectedExprEnd = 'Final inesperado de expresso';\n  cSRightBraceExpected = ') esperado';\n  cSParametersError = 'Esperado %d parmetros mas foi encontrado %d';\n  cSExpectedMoreParams = 'Esperado mais que 2 parmetros';\n  cSInvalidVarByteArray = 'VarByte array invlido';\n  cSVariableAlreadyExists = 'Varivel \"%s\" j existe';\n  cSTypesMismatch = 'Tipos no combinam';\n  cSUnsupportedVariantType = 'Tipo variante no suportado';\n  cSUnsupportedOperation = 'Operao no suportada';\n\n  cSTokenizerIsNotDefined = 'Sinalizador no definido';\n  cSLibraryNotFound = 'Nenhuma biblioteca dinmica da lista %s foi encontrada';\n  cSEncodeDateIsNotSupported = 'Esta verso no suporta isc_encode_sql_date';\n  cSEncodeTimeIsNotSupported = 'Esta verso no suporta supported isc_encode_sql_time';\n  cSEncodeTimestampIsNotSupported = 'Esta verso no suporta supported isc_encode_sql_timestamp';\n  cSDecodeDateIsNotSupported = 'Esta verso no suporta isc_decode_sql_date';\n  cSDecodeTimeIsNotSupported = 'Esta verso no suporta isc_decode_sql_time';\n  cSDecodeTimestampIsNotSupported = 'Esta verso no suporta isc_decode_sql_timestamp';\n\n  cSCanNotRetrieveResultSetData = 'No foi possvel obter os dados do ResultSet';\n  cSRowBufferIsNotAssigned = 'Buffer da Linha no atribudo';\n  cSColumnIsNotAccessable = 'Coluna com ndice %d no  acessvel';\n  cSConvertionIsNotPossible = 'A converso da coluna %d de %s para %s no  possvel';\n  cSCanNotAccessBlobRecord = 'No  possvel acessar um registro BLOB na coluna %d com o tipo %s';\n  cSRowDataIsNotAvailable = 'Dados na Linha no disponveis';\n  cSResolverIsNotSpecified = 'Resolver no foi especificado para este ResultSet';\n  cSResultsetIsAlreadyOpened = 'ResultSet j est aberto';\n  cSCanNotUpdateEmptyRow = 'No  possvel atualizar uma linha vazia';\n  cSCanNotUpdateDeletedRow = 'No  possvel atualizar uma linha apagada';\n  cSCanNotDeleteEmptyRow = 'No  possvel apagar uma linha vazia';\n  cSCannotUseCommit = 'Voc no pode usar Commit no modo AutoCommit';\n  cSCannotUseRollBack = 'Voc no pode usar Rollback no modo AutoCommit';\n  cSCanNotUpdateComplexQuery = 'No  possvel atualizar uma query complexa com mais de uma tabela';\n  cSCanNotUpdateThisQueryType = 'No  possvel atualizar este tipo de query';\n  cSDriverWasNotFound = 'O driver de banco de dados requisitado no foi encontrado';\n  cSCanNotConnectToServer = 'No foi possvel conectar ao servidor SQL';\n  cSTableIsNotSpecified = 'Tabela no especificada';\n  cSLiveResultSetsAreNotSupported = 'Live query no  suportado por esta classe';\n  cSInvalidInputParameterCount = 'A contagem do parmetro de entrada  menor que o esperado';\n  cSIsolationIsNotSupported = 'O nvel de isolamento da Transao no  suportado';\n  cSColumnWasNotFound = 'Coluna com o nome \"%s\" no foi encontrada';\n  cSWrongTypeForBlobParameter = 'Tipo errado para parmetro Blob';\n  cSIncorrectConnectionURL = 'Conexo incorreta URL: %s';\n  cSUnsupportedProtocol = 'Protocolo no suportado: %s';\n  cSUnsupportedByDriver    = 'O Driver no suporta este recurso nativamente: [%s]';\n\n  cSConnectionIsNotOpened = 'Conexo ainda no est aberta.';\n  cSInvalidOpInAutoCommit = 'Operao invlida no modo AutoCommit.';\n  cSInvalidOpInNonAutoCommit = 'Operao invlida quando o modo AutoCommit  False.';\n  cSInvalidOpPrepare = 'Prepare transaction somente  possvel aps comandar StartTransaction';\n\n  cSConnectionIsNotAssigned = 'Componente de conexo de banco de dados no atribudo';\n  cSQueryIsEmpty = 'A consulta SQL est vazia';\n  cSCanNotExecuteMoreQueries = 'No  possvel executar mais que uma query';\n  cSOperationIsNotAllowed1 = 'Operao no permitida no modo FORWARD ONLY';\n  cSOperationIsNotAllowed2 = 'Operao no permitida no modo READ ONLY';\n  cSOperationIsNotAllowed3 = 'Operao no permitida no modo %s';\n  cSOperationIsNotAllowed4 = 'Operao no permitida para DataSet fechado';\n  cSNoMoreRecords = 'Nenhum registro no ResultSet';\n  cSCanNotOpenResultSet = 'No foi possvel abrir o ResultSet';\n  cSCanNotOpenDataSetWhenDestroying ='Translate : Cannot open a dataset when the componentstate is dsDestroying';\n  cSCircularLink = 'DataSource possui um link circular';\n  cSBookmarkWasNotFound = 'Bookmark no foi encontrado';\n  cSIncorrectSearchFieldsNumber = 'Nmero incorreto de valores de campos de procura';\n  cSInvalidOperationInTrans = 'Operao invlida no modo de transao explcita';\n  cSIncorrectSymbol = 'Smbolo incorreto na lista de campos \"%s\".';\n  cSIncorrectToken = 'Sinal incorreto seguido por \":\"';\n  cSIncorrectParamChar = 'TRANSLATE : Invalid value for ParamChar';\n\n  cSSelectedTransactionIsolation = 'O nvel selecionado do isolamento da transao no  suportado';\n  cSDriverNotSupported = 'Driver no suportado %s';\n  cSPattern2Long = 'Padro  muito longo';\n  cSDriverNotCapableOutParameters = 'O Driver no suporta a passagem de parmetros';\n  cSStatementIsNotAllowed = 'Declarao no permitida';\n  cSStoredProcIsNotAllowed = 'A stored procedure no  permitida';\n  cSCannotPerformOperation = 'No  possvel executar a operao num ResultSet fechado';\n  cSInvalidState = 'Estado invlido';\n  cSErrorConvertion = 'Erro de converso';\n  cSDataTypeDoesNotSupported = 'Tipo de dado no suportado';\n  cSUnsupportedParameterType = 'Tipo de parmetro no suportado';\n  cSUnsupportedDataType = 'Tipo de dado no suportado';\n  cSErrorConvertionField = 'Erro de converso para do campo \"%s\" para SQLType \"%s\"';\n  cSBadOCI = 'Verso de OCI incompatvel [% s]. Requer 8.0.3 ou mais antigo';\n  cSConnect2AsUser = 'Conecte \"% s\" como usurio \"% s\"';\n  cSUnknownError = 'Erro desconhecido';\n  cSFieldNotFound1 = 'Campo \"%s\" no foi encontrado';\n  cSFieldNotFound2 = 'Campo %d no foi encontrado';\n\n  cSLoginPromptFailure = 'No foi possvel encontrar o dilogo padro de login. Por favor adicione DBLogDlg para a seo uses de seu arquivo principal.';\n\n  cSPropertyQuery = 'A Query poder demorar em bancos de dados grandes!';\n  cSPropertyTables = 'Voc deveria limitar por Catalogo e/ou Esquema.';\n  cSPropertyColumns = 'Voc deveria limitar por Catalogo, Esquema e/ou Tabela.';\n  cSPropertyProcedures = 'Voc deveria limitar por Catalogo e/ou Esquema.';\n  cSPropertySequences = 'Voc deveria limitar por Catalogo e/ou Esquema..';\n  cSPropertyExecute = 'Executar a Query de qualquer maneira?';\n\n  cSFormTest = 'Teste Editor ZEOS SQL';\n  cSButtonClose = '&Fechar';\n  cSFormEditor = 'Editor ZEOS SQL';\n  cSTabSheetSelect = 'SQL Select';\n  cSMenuLoad = 'Carregar';\n  cSMenuSave = 'Salvar';\n  cSButtonGenerate = '&Gerar';\n  cSButtonCheck = '&Verificar';\n  cSButtonTest = '&Testar';\n  cSButtonOk = '&OK';\n  cSButtonCancel = '&Cancelar';\n  cSTableAlias = '&Alias Tabela';\n  cSReplaceSQL = '&Substituir SQL';\n  cSDialogOpenTitle = 'Abrir Arquivo SQL';\n  cSDialogSaveTitle = 'Salvar Arquivo SQL';\n  cSSQLEditor = 'Editor SQL';\n  cSDatabaseDialog = 'Abrir Banco de Dados existente';\n\n  cSUpdateSQLNoResult = 'SQL Update Refresh resultou num conjunto vazio';\n  cSUpdateSQLRefreshStatementcount ='Usar somente 1 declarao SQL para Update Refresh';\n  {$IFDEF FPC}\n  cSNotEditing = 'Dataset no est em modo de edio ou insero';\n  cSFieldTypeMismatch = 'Tipo invlido para o campo ''%s'', esperado: %s atual: %s';\n  cSFieldSizeMismatch = 'Tamanho Invlido para o campo ''%s'', esperado: %d atual: %d';\n  {$ENDIF}\n  cSNeedField               = 'O campo %s  obrigatrio, mas no foi preenchido.';\n\n  cSFailedtoInitPrepStmt   = 'A declarao preparada falhou ao inicializar';\n  cSFailedtoPrepareStmt    = 'A declarao falhou durante o processo de preparo';\n  cSFailedToBindAllValues  = 'A Aplicao falhou na traduo de todos os valores';\n  cSAttemptExecOnBadPrep   = 'Tentativa de executar uma declarao que no foi corretamente preparada';\n  cSBindingFailure         = 'Falha ao traduzir o conjunto de parmetros';\n  cSPreparedStmtExecFailure = 'A declarao preparada falhou ao executar';\n  cSBoundVarStrIndexMissing = 'ndice de texto \"%s\" da varivel de limite no existe';\n  cSBindVarOutOfRange      = 'ndice da varivel de limite fora de alcance: %d';\n  cSFailedToBindResults    = 'A Aplicao falhou ao tratar o result set';\n  \n\n  cSRefreshRowOnlySupportedWithUpdateObject = 'O mtodo RefreshRow somente  suportado com um update object';\n  cSMustBeInBrowseMode = 'A Operao  permitida somente no modo dsBrowse';\n\n  cSUnKnownParamDataType = 'Param.DataType  de tipo desconhecido';\n  cSFieldReadOnly        = 'O campo %d  somente leitura e no pde receber dados';\n  cSInvalidUpdateCount   = '%d registro(s) atualizados. Apenas um registro deveria ter sido atualizado.';\n\n  cSRowBufferWidthExceeded ='O tamanho do buffer para linhas (Rows) foi excedido. Tente usar menos ou mais colunas na query SQL';\n{$ELSE}\n\n{$IFDEF DUTCH}\n  cSSQLError1 = 'SQL Fout: %s';\n  cSSQLError2 = 'SQL Fout: %s Code: %d';\n  cSSQLError3 = 'SQL Fout: %s Code: %d SQL: %s';\n  cSSQLError4 = 'SQL Fout: %s Code: %d Bericht: %s';\n\n  cSListCapacityError = 'Lijst capaciteit buiten bereik (%d)';\n  cSListCountError = 'Lijst aantal buiten bereik (%d)';\n  cSListIndexError = 'Lijst index buiten bereik (%d)';\n\n  cSClonningIsNotSupported = 'Kloonen worden niet ondersteund in deze klasse';\n  cSImmutableOpIsNotAllowed = 'Deze operatie is niet ondersteund voor immutable collection';\n  cSStackIsEmpty = 'Stack is leeg';\n  cSVariableWasNotFound = 'Variabele \"%s\" niet gevonden';\n  cSFunctionWasNotFound = 'Functie \"%s\" niet gevonden';\n  cSInternalError = 'Interne fout';\n  cSSyntaxErrorNear = 'Syntaxis fout bij \"%s\"';\n  cSSyntaxError = 'Syntaxis fout';\n  cSUnknownSymbol = 'Onbekend symbool \"%s\"';\n  cSUnexpectedExprEnd = 'Onverwacht einde van de expressie';\n  cSRightBraceExpected = ') verwacht';\n  cSParametersError = 'Verwacht worden %d parameters maar er zijn er %d gevonden';\n  cSExpectedMoreParams = 'Meer dan 2 parameters werden verwacht';\n  cSInvalidVarByteArray = 'Ongeldig VarByte array';\n  cSVariableAlreadyExists = 'Variabele \"%s\" bestaat al';\n  cSTypesMismatch = 'Types komen niet overeen';\n  cSUnsupportedVariantType = 'Niet ondersteund variant type';\n  cSUnsupportedOperation = 'Niet ondersteunde operatie';\n\n  cSTokenizerIsNotDefined = 'Tokenizer is niet gedefinieerd';\n  cSLibraryNotFound = 'DLL van de lijst %s werd niet gevonden';\n  cSEncodeDateIsNotSupported = 'Deze versie ondersteunt isc_encode_sql_date niet';\n  cSEncodeTimeIsNotSupported = 'Deze versie ondersteunt isc_encode_sql_time niet';\n  cSEncodeTimestampIsNotSupported = 'Deze versie ondersteunt isc_encode_sql_timestamp niet';\n  cSDecodeDateIsNotSupported = 'Deze versie ondersteunt isc_decode_sql_date niet';\n  cSDecodeTimeIsNotSupported = 'Deze versie ondersteunt isc_decode_sql_time niet';\n  cSDecodeTimestampIsNotSupported = 'Deze versie ondersteunt isc_decode_sql_timestamp niet';\n\n  cSCanNotRetrieveResultSetData = 'Kan ResultSet data niet ophalen';\n  cSRowBufferIsNotAssigned = 'Row buffer is niet toegekend';\n  cSColumnIsNotAccessable = 'Kolom met index %d is niet bereikbaar';\n  cSConvertionIsNotPossible = 'Conversie is niet mogelijk voor kolom %d van %s tot %s';\n  cSCanNotAccessBlobRecord = 'Kan het blob record in kolom %d met type %s niet benaderen';\n  cSRowDataIsNotAvailable = 'Rij data is niet beschikbaar';\n  cSResolverIsNotSpecified = 'Resolver is niet gespecificeerd voor deze ResultSet';\n  cSResultsetIsAlreadyOpened = 'ResultSet is al geopend';\n  cSCanNotUpdateEmptyRow = 'Kan een lege rij niet updaten';\n  cSCanNotUpdateDeletedRow = 'Kan een verwijderde rij niet updaten';\n  cSCanNotDeleteEmptyRow = 'Kan een lege rij niet verwijderen';\n  cSCannotUseCommit = 'Commit in autocommit mode is niet mogelijk';\n  cSCannotUseRollBack = 'Rollback in autocommit mode is niet mogelijk';\n  cSCanNotUpdateComplexQuery = 'Kan een complexe query met meerdere tabellen niet updaten';\n  cSCanNotUpdateThisQueryType = 'Kan dit query type niet updaten';\n  cSDriverWasNotFound = 'Gevraagde database driver is niet gevonden';\n  cSCanNotConnectToServer = 'Kan geen verbinding maken met de SQL server';\n  cSTableIsNotSpecified = 'Tabel is niet gespecifieerd';\n  cSLiveResultSetsAreNotSupported = 'Live query is niet ondersteund door deze klasse';\n  cSInvalidInputParameterCount = 'Input parameter aantal is lager dan verwacht';\n  cSIsolationIsNotSupported = 'Transactie isolatie niveau wordt niet ondersteund';\n  cSColumnWasNotFound = 'Kolom met naam \"%s\" bestaat niet';\n  cSWrongTypeForBlobParameter = 'Verkeerde type voor Blob parameter';\n  cSIncorrectConnectionURL = 'Ongeldige connectie URL: %s';\n  cSUnsupportedProtocol = 'Niet ondersteund protocol: %s';\n  cSUnsupportedByDriver    = 'De driver ondersteunt deze functie niet: [%s]';\n\n  cSConnectionIsNotOpened = 'Verbinding is niet gemaakt.';\n  cSInvalidOpInAutoCommit = 'Ongeldige operatie in AutoCommit mode.';\n  cSInvalidOpInNonAutoCommit = 'Ongeldige operatie in non AutoCommit mode.';\n  cSInvalidOpPrepare = 'Transactie voorbereiden is enkel mogelijk bij de eerste aanroep van Starttransaction!';\n\n  cSConnectionIsNotAssigned = 'Database connectie component is niet toegekend';\n  cSQueryIsEmpty = 'SQL Query is leeg';\n  cSCanNotExecuteMoreQueries = 'Kan niet meerdere queries uitvoeren';\n  cSOperationIsNotAllowed1 = 'Bewerking is niet toegestaan in FORWARD ONLY mode';\n  cSOperationIsNotAllowed2 = 'Bewerking is niet toegestaan in READ ONLY mode';\n  cSOperationIsNotAllowed3 = 'Bewerking is niet toegestaan in %s mode';\n  cSOperationIsNotAllowed4 = 'Bewerking is niet toegestaan voor gesloten dataset';\n  cSNoMoreRecords = 'Geen records meer aanwezig in ResultSet';\n  cSCanNotOpenResultSet = 'Kan een ResultSet niet openen';\n  cSCanNotOpenDataSetWhenDestroying ='Kan een Dataset niet openen wanneer de componentstate=dsDestroying';\n  cSCircularLink = 'Databron maakt een oneindige verbindingslus';\n  cSBookmarkWasNotFound = 'Bookmark niet gevonden';\n  cSIncorrectSearchFieldsNumber = 'Incorrect aantal zoekvelden';\n  cSInvalidOperationInTrans = 'Ongeldige operatie in explicit transaction mode';\n  cSIncorrectSymbol = 'Ongeldig symbool in veld lijst \"%s\".';\n  cSIncorrectToken = 'Ongeldig teken gevolgd door \":\"';\n  cSIncorrectParamChar = 'TRANSLATE : Invalid value for ParamChar';\n\n  cSSelectedTransactionIsolation = 'Geselecteerd transactie isolatie niveau niet ondersteund';\n  cSDriverNotSupported = 'Driver niet ondersteund %s';\n  cSPattern2Long = 'Patroon is te lang';\n  cSDriverNotCapableOutParameters = 'Driver ondersteunt geen out parameters';\n  cSStatementIsNotAllowed = 'Statement is niet toegestaan';\n  cSStoredProcIsNotAllowed = 'Stored procedures zijn niet toegestaan';\n  cSCannotPerformOperation = 'Kan operatie niet uitvoeren op een gesloten ResultSet';\n  cSInvalidState = 'Ongeldige status';\n  cSErrorConvertion = 'Conversiefout';\n  cSDataTypeDoesNotSupported = 'Data type is niet onderstuend';\n  cSUnsupportedParameterType = 'Niet ondersteund parameter type';\n  cSUnsupportedDataType = 'Niet ondersteund data type';\n  cSErrorConvertionField = 'Conversie fout voor veld \"%s\" naar SQLType \"%s\"';\n  cSBadOCI = 'Ongeschikte OCI version [%s]. Vereist is 8.0.3 of nieuwer';\n  cSConnect2AsUser = 'Verbinden met \"%s\" als gebruiker \"%s\"';\n  cSUnknownError = 'Onbekende fout';\n  cSFieldNotFound1 = 'Veld \"%s\" niet gevonden';\n  cSFieldNotFound2 = 'Veld %d niet gevonden';\n\n  cSLoginPromptFailure = 'Kan de standaard login prompt niet vinden.  Voeg DBLogDlg toe aan de uses sectie.';\n\n  cSPropertyQuery = 'De Query kan enige tijd duren bij grote databases!';\n  cSPropertyTables = 'Limiet op Catalog en/of Schema is vereist.';\n  cSPropertyColumns = 'Limiet op Catalog, Schema en/of tablenaam is vereist.';\n  cSPropertyProcedures = 'Limiet op Catalog en/of Schema is vereist.';\n  cSPropertySequences = 'Limiet op Catalog en/of Schema is vereist.';\n  cSPropertyExecute = 'Dient de Query toch te worden uitgevoerd?';\n\n  cSFormTest = 'ZEOS SQL Editor Test';\n  cSButtonClose = '&Sluiten';\n  cSFormEditor = 'ZEOS SQL Editor';\n  cSTabSheetSelect = 'Select SQL';\n  cSMenuLoad = 'Laden';\n  cSMenuSave = 'Opslaan';\n  cSButtonGenerate = '&Genereren';\n  cSButtonCheck = 'C&heck';\n  cSButtonTest = '&Test';\n  cSButtonOk = '&OK';\n  cSButtonCancel = '&Annuleren';\n  cSTableAlias = 'Tabel al&ias';\n  cSReplaceSQL = '&Vervang SQL';\n  cSDialogOpenTitle = 'SQL Bestand Openen';\n  cSDialogSaveTitle = 'SQL Bestand Opslaan';\n  cSSQLEditor = 'SQL Editor';\n  cSDatabaseDialog = 'Open bestaande database';\n\n  cSUpdateSQLNoResult = 'Der zuvor aktualisierte SQL liefert kein Resultset zurck';\n  cSUpdateSQLRefreshStatementcount ='Update Refresh SQL Statement count moet 1 zijn';\n\n  {$IFDEF FPC}\n  cSNotEditing = 'Dataset is niet in edit of insert modus';\n  cSFieldTypeMismatch = 'Type mismatch voor veld ''%s'', verwacht: %s actueel: %s';\n  cSFieldSizeMismatch = 'Size mismatch voor veld ''%s'', verwacht: %d actueel: %d';\n  {$ENDIF}\n  cSNeedField               = 'Veld %s is verplicht, maar niet ingevuld.';\n\n  cSFailedtoInitPrepStmt   = 'Initialisatie van Prepared statement mislukt';\n  cSFailedtoPrepareStmt    = 'Statement mislukt tijdens prepare';\n  cSFailedToBindAllValues  = 'Pre-bind van alle waarden is mislukt';\n  cSAttemptExecOnBadPrep   = 'Poging om een statement uit te voeren voor een succesvolle prepare';\n  cSBindingFailure         = 'Binding van parameterset mislukt';\n  cSPreparedStmtExecFailure = 'Uitvoeren van Prepared statement mislukt';\n  cSBoundVarStrIndexMissing = 'Tekst index van bound variable bestaat niet: \"%s\"';\n  cSBindVarOutOfRange      = 'Bound variable index buiten bereik: %d';\n  cSFailedToBindResults    = 'Binding van resultaat mislukt';\n\n  cSRefreshRowOnlySupportedWithUpdateObject = 'De refreshrow methode is enkel ondersteund vooreen update object';\n  cSMustBeInBrowseMode = 'Bewerking is enkel toegestaan in dsBROWSE status';\n\n  cSUnKnownParamDataType = 'Param.DataType is onbekend';\n  cSFieldReadOnly        = 'Readonly veld kan geen waarde toegewezen krijgen: %d';\n  cSInvalidUpdateCount     = '%d record(s) gewijzigd. Slechts 1 record had gewijzigd mogen zijn.';\n\n  cSRowBufferWidthExceeded ='Rij buffer grootte overschreden. Probeer minder kolommen te gebruiken in je SQL query.';\n{$ELSE}\n// <- ms, 09/05/2005\n\n// -> ms, 03/05/2005\n{$IFDEF GERMAN}\n  cSSQLError1 = 'SQL Fehler: %s';\n  cSSQLError2 = 'SQL Fehler: %s Code: %d';\n  cSSQLError3 = 'SQL Fehler: %s Code: %d SQL: %s';\n  cSSQLError4 = 'SQL Fehler: %s Code: %d Meldung: %s';\n\n  cSListCapacityError = 'Die Listenkapazitt bersteigt die definierte Grenze (%d)';\n  cSListCountError = 'Der Listenzhler ist auerhalb seiner definierten Grenzen (%d)';\n  cSListIndexError = 'Der Listenindex ist auerhalb der definierten Grenzen (%d)';\n\n  cSClonningIsNotSupported = 'Diese Klasse kann nicht geklont werden';\n  cSImmutableOpIsNotAllowed = 'Diese Operation ist bei nicht nderbaren Collections nicht erlaubt';\n  cSStackIsEmpty = 'Der Stack ist leer';\n  cSVariableWasNotFound = 'Die Variable \"%s\" wurde nicht gefunden';\n  cSFunctionWasNotFound = 'Die Funktion \"%s\" wurde nicht gefunden';\n  cSInternalError = 'Interner Fehler';\n  cSSyntaxErrorNear = 'Syntax Fehler bei \"%s\"';\n  cSSyntaxError = 'Syntax Fehler';\n  cSUnknownSymbol = 'Unbekanntes Symbol \"%s\"';\n  cSUnexpectedExprEnd = 'Unerwartetes Ende des Ausdrucks';\n  cSRightBraceExpected = ') erwartet';\n  cSParametersError = 'Es werden %d Parameter erwartet, aber nur %d Parameter gefunden';\n  cSExpectedMoreParams = 'Es werden mehr als zwei Parameter erwartet';\n  cSInvalidVarByteArray = 'Ungltiges VarByte Array';\n  cSVariableAlreadyExists = 'Die Variable \"%s\" existiert bereits';\n  cSTypesMismatch = 'Inkompatible Typen';\n  cSUnsupportedVariantType = 'Nicht untersttzter Variant-Typ';\n  cSUnsupportedOperation = 'Nicht untersttzte Operation';\n  cSUnsupportedByDriver    = 'Der Treiber untersttzt dieses Feature nicht von haus aus: [%s]';\n\n  cSTokenizerIsNotDefined = 'Tokenizer wurde nicht definiert';\n  cSLibraryNotFound = 'Es wurde keine der in %s gelisteten DLL''s gefunden';\n  cSEncodeDateIsNotSupported = 'Diese Version untersttzt \"isc_encode_sql_date\" nicht';\n  cSEncodeTimeIsNotSupported = 'Diese Version untersttzt \"isc_encode_sql_time\" nicht';\n  cSEncodeTimestampIsNotSupported = 'Diese Version untersttzt \"isc_encode_sql_timestamp\" nicht';\n  cSDecodeDateIsNotSupported = 'Diese Version untersttzt \"isc_decode_sql_date\" nicht';\n  cSDecodeTimeIsNotSupported = 'Diese Version untersttzt \"isc_decode_sql_time\" nicht';\n  cSDecodeTimestampIsNotSupported = 'Diese Version untersttzt \"isc_decode_sql_timestamp\" nicht';\n\n  cSCanNotRetrieveResultSetData = 'Die Ergebnismenge kann nicht ermittelt werden';\n  cSRowBufferIsNotAssigned = 'Der Zeilen-Buffer ist nicht zugewiesen';\n  cSColumnIsNotAccessable = 'Auf die Spalte (Tabellenfeld) mit dem Index %d kann nicht zugegriffen werden';\n  cSConvertionIsNotPossible = 'Eine Konvertierung der Spalte (Tabellenfeld) %d von %s bis %s kann nicht durchgefhrt werden';\n  cSCanNotAccessBlobRecord = 'Auf den BLOB-Datensatz in Spalte (Tabellenfeld) %d vom Typ %s kann nicht zugegriffen werden';\n  cSRowDataIsNotAvailable = 'Die Zeilendaten (Datensatzdaten) sind nicht verfgbar';\n  cSResolverIsNotSpecified = 'Fr diese Ergebnismenge wurde kein sog. \"Resolver\" angegeben';\n  cSResultsetIsAlreadyOpened = 'Die Ergebnismenge ist bereits geffnet';\n  cSCanNotUpdateEmptyRow = 'Eine leere Datenzeile kann nicht aktualisiert werden';\n  cSCanNotUpdateDeletedRow = 'Eine gelschte Datenzeile kann nicht aktualisiert werden';\n  cSCanNotDeleteEmptyRow = 'Eine leere Datenzeile kann nicht gelscht werden';\n  cSCannotUseCommit = 'COMMIT kann im AUTOCOMMIT-Modus nicht verwendet werden';\n  cSCannotUseRollBack = 'ROLLBACK kann im AUTOCOMMIT-Modus nicht verwendet werden';\n  cSCanNotUpdateComplexQuery = 'Ein Query, dessen Ergebnismenge aus mehr als einer Tabelle stammt, kann nicht aktualisiert werden';\n  cSCanNotUpdateThisQueryType = 'Diese Art von Queries kann nicht aktualisiert werden';\n  cSDriverWasNotFound = 'Der angegebene Datenbanktreiber wurde nicht gefunden';\n  cSCanNotConnectToServer = 'Kann keine Verbindung zum SQL Server herstellen';\n  cSTableIsNotSpecified = 'Tabelle ist nicht spezifiziert';\n  cSLiveResultSetsAreNotSupported = 'Ein \"Live Query\" wird von dieser Klasse nicht untersttzt';\n  cSInvalidInputParameterCount = 'Es wurden weniger Eingabeparameter angegeben, als erwartet';\n  cSIsolationIsNotSupported = 'Der gewhlte Trasaktions-Isolationslevel wird nicht untersttzt';\n  cSColumnWasNotFound = 'Eine Tabellenspalte namens \"%s\" wurde nicht gefunden';\n  cSWrongTypeForBlobParameter = 'Falscher Typ fr einen BLOB-Parameter';\n  cSIncorrectConnectionURL = 'Falsche Verbindungs-URL: %s';\n  cSUnsupportedProtocol = 'Nicht untersttztes Protokoll: %s';\n\n  cSConnectionIsNotOpened = 'Die Verbindung zur Datenbank ist noch nicht hergestellt';\n  cSInvalidOpInAutoCommit = 'Ungltige Operation im AUTOCOMMIT-Modus';\n  cSInvalidOpInNonAutoCommit = 'Ungltige Operation auerhalb des AUTOCOMMIT-Modus';\n  cSInvalidOpPrepare = 'Transaktion vorzubereiten ist nur beim ersten Aufruf von Starttransaction mglich!';\n\n  cSConnectionIsNotAssigned = 'Die Datenbank-Verbindungskomponente ist nicht angegeben';\n  cSQueryIsEmpty = 'SQL Query leer';\n  cSCanNotExecuteMoreQueries = 'Mehr als ein Query kann nicht abgearbeitet werden';\n  cSOperationIsNotAllowed1 = 'Die Operation ist im FORWARD ONLY Modus nicht erlaubt';\n  cSOperationIsNotAllowed2 = 'Die Operation ist im READ ONLY Modus nicht erlaubt';\n  cSOperationIsNotAllowed3 = 'Die Operation ist im %s Modus nicht erlaubt';\n  cSOperationIsNotAllowed4 = 'Die Operation ist bei einem geschlossenen DataSet nicht erlaubt';\n  cSNoMoreRecords = 'Es gibt keine weiteren Datenstze in der Ergebnismenge';\n  cSCanNotOpenResultSet = 'Die Ergebnismenge kann nicht geffnet werden';\n  cSCanNotOpenDataSetWhenDestroying ='Translate : Cannot open a dataset when the componentstate is dsDestroying';\n  cSCircularLink = 'Die DataSource hat einen zirkulren Verweis';\n  cSBookmarkWasNotFound = 'Das Lesezeichen (Bookmark) wurde nicht gefunden';\n  cSIncorrectSearchFieldsNumber = 'Die Anzahl der Suchfeldwerte ist nicht korrekt';\n  cSInvalidOperationInTrans = 'Ungltige Operatio im Zustand einer expliziten Transaktion';\n  cSIncorrectSymbol = 'Falsches Symbol in der Feldliste \"%s\".';\n  cSIncorrectToken = 'Falsches Token gefolgt von \":\"';\n  cSIncorrectParamChar = 'TRANSLATE : Invalid value for ParamChar';\n\n  cSSelectedTransactionIsolation = 'Der gewhlte Transaktions-Isolationslevel wird nicht untersttzt';\n  cSDriverNotSupported = 'Der Treiber wird nicht untersttzt: %s';\n  cSPattern2Long = 'Das Muster (Pattern) ist zu lang';\n  cSDriverNotCapableOutParameters = 'Der Treiber beherrscht keine Parameter';\n  cSStatementIsNotAllowed = 'Diese Anweisung ist nicht erlaubt';\n  cSStoredProcIsNotAllowed = 'Diese Stored Procedure ist nicht erlaubt';\n  cSCannotPerformOperation = 'Auf eine geschlossene Ergebnismenge knnen keine Operationen ausgefhrt werden';\n  cSInvalidState = 'Ungltiger Status';\n  cSErrorConvertion = 'Konvertierungsfehler';\n  cSDataTypeDoesNotSupported = 'Der Datentyp wird nicht untersttzt';\n  cSUnsupportedParameterType = 'Der Parametertyp wird nicht untersttzt';\n  cSUnsupportedDataType = 'Der Datentyp wird nicht untersttzt';\n  cSErrorConvertionField = 'Konvertierungsfehler bei Feld \"%s\" nach SQL-Typ \"%s\"';\n  cSBadOCI = 'Die OCI Version 8.0.3 (oder lter) wird bentigt! Aktuelle Version: %s';\n  cSConnect2AsUser = 'Verbinde zu \"%s\" als User \"%s\"';\n  cSUnknownError = 'Unbekannter Fehler';\n  cSFieldNotFound1 = 'Das Feld \"%s\" wurde nicht gefunden';\n  cSFieldNotFound2 = 'Das Feld %d wurde nicht gefunden';\n\n  cSLoginPromptFailure = 'Der Standard-Login-Dialog konnte nicht gefunden werden. Bitte DBLogDlg in die USES-Sektion der Haupt-Unit hinzufgen';\n\n  cSPropertyQuery = 'Die Abfrage kann bei groen Datenbanken eine Weile dauern!';\n  cSPropertyTables = 'Sie sollte durch die Angabe von Catalog und/oder Schema eingeschrnkt werden.';\n  cSPropertyColumns = 'Sie sollte durch die Angabe von Catalog, Schema und/oder Tabellenname eingeschrnkt werden.';\n  cSPropertyProcedures = 'Sie sollte durch die Angabe von Catalog und/oder Schema eingeschrnkt werden.';\n  cSPropertySequences = 'Sie sollte durch die Angabe von Catalog und/oder Schema eingeschrnkt werden.';\n  cSPropertyExecute = 'Soll die Abfrage trotzdem ausgefhrt werden?';\n\n  cSFormTest = 'ZEOS SQL Editor Test';\n  cSButtonClose = '&Schlieen';\n  cSFormEditor = 'ZEOS SQL Editor';\n  cSTabSheetSelect = 'SQL aus&whlen';\n  cSMenuLoad = 'ffnen';\n  cSMenuSave = 'Speichern';\n  cSButtonGenerate = '&Generieren';\n  cSButtonCheck = 'Syntax &Prfen';\n  cSButtonTest = 'Befehl &Testen';\n  cSButtonOk = '&OK';\n  cSButtonCancel = '&Abbruch';\n  cSTableAlias = 'Tabllen-Alias';\n  cSReplaceSQL = 'SQL &ersetzen';\n  cSDialogOpenTitle = 'SQL Script ffnen';\n  cSDialogSaveTitle = 'SQL Script speichern';\n  cSSQLEditor = 'SQL Editor';\n  cSDatabaseDialog = 'Existierende Datenbank ffnen';\n\n  cSUpdateSQLNoResult = 'Translate : Update Refresh SQL delivered no resultset';\n  cSUpdateSQLRefreshStatementcount ='Translate : Update Refresh SQL Statement count must be 1';\n\n  {$IFDEF FPC}\n  cSNotEditing = 'Das DataSet ist nicht im \"edit\" oder \"insert\" Modus.';\n  cSFieldTypeMismatch = 'Der Typ fr Feld ''%s'' stimmt nicht. Erwartet wird %s der Typ ist aber momentan %s';\n  cSFieldSizeMismatch = 'Die Gre des Feldes ''%s'' stimmt nicht. Erwartet wird  %d die Gre ist aber momentan %d';\n  {$ENDIF}\n  cSNeedField               = 'Translate: Field %s is required, but not supplied.';\n\n  cSFailedtoInitPrepStmt   = 'Translate: Prepared statement failed to initialize';\n  cSFailedtoPrepareStmt    = 'Translate: Statement failed during prepare process';\n  cSFailedToBindAllValues  = 'Translate: Application failed to pre-bind all values';\n  cSAttemptExecOnBadPrep   = 'Translate: Attempt made to execute a statement before a successful preparation.';\n  cSBindingFailure         = 'Translate: Failed to bind parameter set';\n  cSPreparedStmtExecFailure = 'Translate: Prepared statement failed to execute';\n  cSBoundVarStrIndexMissing = 'Translate: Bound variable text index \"%s\" does not exist';\n  cSBindVarOutOfRange      = 'Translate: Bound variable index out of range: %d';\n  cSFailedToBindResults    = 'Translate: Application failed to bind to the result set';\n\n  cSRefreshRowOnlySupportedWithUpdateObject = 'TRANSLATE: The refreshrow method is only supported with an update object';\n  cSMustBeInBrowseMode = 'TRANSLATE: Operation is only allowed in dsBROWSE state';\n\n  cSUnKnownParamDataType = 'TRANSLATE: Unknown Param.DataType';\n  cSFieldReadOnly          = 'Translate : Readonly field can''t be assigned a value: %d';\n  cSInvalidUpdateCount     = 'Translate : %d record(s) updated. Only one record should have been updated.';\n\n  cSRowBufferWidthExceeded ='Translate: Row buffer width exceeded. Try using fewer or longer columns in SQL query.';\n{$ELSE}\n  // -> fduenas, 28/06/2005\n{$IFDEF SPANISH} //Spanish translations\n  cSSQLError1 = 'Error SQL: %s';\n  cSSQLError2 = 'Error SQL: %s Cdigo: %d';\n  cSSQLError3 = 'Error SQL: %s Cdigo: %d SQL: %s';\n  cSSQLError4 = 'Error SQL: %s Cdigo: %d Mensage: %s';\n\n  cSListCapacityError = 'List capacity fuera de lmites (%d)';\n  cSListCountError = 'List count fuera de lmites (%d)';\n  cSListIndexError = 'List index fuera de lmites (%d)';\n\n  cSClonningIsNotSupported = 'La Clonacin no est soportada por esta clase';\n  cSImmutableOpIsNotAllowed = 'Operacin no permitida en colecciones no modificables';\n  cSStackIsEmpty = 'La Pila (Stack) est vaca';\n  cSVariableWasNotFound = 'Variable \"%s\" no encontrada';\n  cSFunctionWasNotFound = 'Funcin \"%s\" no encontrada';\n  cSInternalError = 'Error interno';\n  cSSyntaxErrorNear = 'Error de sintaxis cerca de \"%s\"';\n  cSSyntaxError = 'Error de sintaxis';\n  cSUnknownSymbol = 'Smbolo \"%s\" desconocido';\n  cSUnexpectedExprEnd = 'Fin de expresin inesperado';\n  cSRightBraceExpected = ') esperado';\n  cSParametersError = 'Se esperaban %d parmetros pero solo %d fueron encontrados';\n  cSExpectedMoreParams = 'Se esperaban ms de dos parmetros';\n  cSInvalidVarByteArray = 'Arreglo VarByte invlido';\n  cSVariableAlreadyExists = 'La variable \"%s\" ya existe';\n  cSTypesMismatch = 'Los Tipos no coinciden';\n  cSUnsupportedVariantType = 'Tipo de Variant no soportando';\n  cSUnsupportedOperation = 'Operacin no soportada';\n\n  cSTokenizerIsNotDefined = 'El objeto Tokenizer no est definido';\n  cSLibraryNotFound = 'Ninguna librera dinmica de la lista %s fue encontrada';\n  cSEncodeDateIsNotSupported = 'Esta versin no soporta isc_encode_sql_date';\n  cSEncodeTimeIsNotSupported = 'Esta versin no soporta isc_encode_sql_time';\n  cSEncodeTimestampIsNotSupported = 'Esta versin no soporta isc_encode_sql_timestamp';\n  cSDecodeDateIsNotSupported = 'Esta versin no soporta isc_decode_sql_date';\n  cSDecodeTimeIsNotSupported = 'Esta versin no soporta isc_decode_sql_time';\n  cSDecodeTimestampIsNotSupported = 'Esta versin no soporta isc_decode_sql_timestamp';\n\n  cSCanNotRetrieveResultSetData = 'No se pueden obtener datos del Resultset';\n  cSRowBufferIsNotAssigned = 'Buffer de lnea no asignado';\n  cSColumnIsNotAccessable = 'La columna con ndice %d no est accesible';\n  cSConvertionIsNotPossible = 'La conversin no es posible para la columna %d de %s a %s';\n  cSCanNotAccessBlobRecord = 'No se puede accesar al registro del blob en la columna %d con tipo %s';\n  cSRowDataIsNotAvailable = 'Datos de lnea no disponibles';\n  cSResolverIsNotSpecified = 'El objeto Resolver no est especificado para este ResultSet';\n  cSResultsetIsAlreadyOpened = 'El Resultset ya est abierto';\n  cSCanNotUpdateEmptyRow = 'No se puede actualizar una lnea vaca';\n  cSCanNotUpdateDeletedRow = 'No se puede actualizar una lnea borrada';\n  cSCanNotDeleteEmptyRow = 'No se puede borrar una lnea vaca';\n  cSCannotUseCommit = 'No se puede usar COMMIT en modo AUTOCOMMIT';\n  cSCannotUseRollBack = 'No se puede usar ROLLBACK en modo AUTOCOMMIT';\n  cSCanNotUpdateComplexQuery = 'No se puede actualizar una consulta compleja que haga referencia a ms de una tabla';\n  cSCanNotUpdateThisQueryType = 'No se puede actualizar este tipo de consulta';\n  cSDriverWasNotFound = 'No se encontr el controlador de base de datos solicitado';\n  cSCanNotConnectToServer = 'No puede conectarse al servidor SQL';\n  cSTableIsNotSpecified = 'La Tabla no est especificada';\n  cSLiveResultSetsAreNotSupported = 'La consulta actualizable no es soportada por esta clase';\n  cSInvalidInputParameterCount = 'El nmero de parmetros de tipo Input es menor al esperado';\n  cSIsolationIsNotSupported = 'Nivel de aislamiento de transaccin no soportado';\n  cSColumnWasNotFound = 'Columna con nombre \"%s\" no encontrada';\n  cSWrongTypeForBlobParameter = 'Tipo incorrecto para el parmetro Blob';\n  cSIncorrectConnectionURL = 'URL de conexin incorrecta: %s';\n  cSUnsupportedProtocol = 'Protocolo no soportado: %s';\n  cSUnsupportedByDriver    = 'Translate: Driver can not support this feature natively: [%s]';\n\n  cSConnectionIsNotOpened = 'La conexin no ha sido abierta todava';\n  cSInvalidOpInAutoCommit = 'Operacin invlida en modo AutoCommit';\n  cSInvalidOpInNonAutoCommit = 'Operacin invlida en modo No-AutoCommit';\n  cSInvalidOpPrepare = 'Translate : Prepare transaction only possible on matching first(!) Starttransaction';\n\n  cSConnectionIsNotAssigned = 'El componente de conexin a base de datos no est asigando';\n  cSQueryIsEmpty = 'La Consulta SQL est vaca';\n  cSCanNotExecuteMoreQueries = 'No se puede ejecutar ms de una consulta';\n  cSOperationIsNotAllowed1 = 'Operacin no permitida en modo FORWARD ONLY';\n  cSOperationIsNotAllowed2 = 'Operacin no permitida en modo READ ONLY (Solo lectura)';\n  cSOperationIsNotAllowed3 = 'Operacin no permitida en modo %s';\n  cSOperationIsNotAllowed4 = 'Operacin no permitida en un dataset cerrado';\n  cSNoMoreRecords = 'No hay ms registros en el Resultset';\n  cSCanNotOpenResultSet = 'No se puede abrir el Resultset';\n  cSCanNotOpenDataSetWhenDestroying ='Translate : Cannot open a dataset when the componentstate is dsDestroying';\n  cSCircularLink = 'Datasource hace una referencia cclica';\n  cSBookmarkWasNotFound = 'Bookmark no encontrado';\n  cSIncorrectSearchFieldsNumber = 'Nmero incorrecto de valores de bsqueda';\n  cSInvalidOperationInTrans = 'Operacin invlida en modo de transaccin explcita';\n  cSIncorrectSymbol = 'Smbolo incorrecto en la lista de campos \"%s\".';\n  cSIncorrectToken = 'Token incorrecto seguido de \":\"';\n  cSIncorrectParamChar = 'TRANSLATE : Invalid value for ParamChar';\n\n  cSSelectedTransactionIsolation = 'El Nivel seleccionado de aislamiento de transaccin no est soportado';\n  cSDriverNotSupported = 'Controlador %s no soportado';\n  cSPattern2Long = 'Patrn de bsqueda demasiado largo';\n  cSDriverNotCapableOutParameters = 'El controlador no tiene cualidades para manejar parmetros';\n  cSStatementIsNotAllowed = 'Sentencia no permitida';\n  cSStoredProcIsNotAllowed = 'El procedimiento alamacenado no est permitido';\n  cSCannotPerformOperation = 'No se puede efectuar la operacin en un resultset cerrado';\n  cSInvalidState = 'Estado Invlido';\n  cSErrorConvertion = 'Error de conversin';\n  cSDataTypeDoesNotSupported = 'Tipo de datos no soportado';\n  cSUnsupportedParameterType = 'Tipo de parmetro no soportado';\n  cSUnsupportedDataType = 'Tipo de datos no soportado';\n  cSErrorConvertionField = 'Error de conversin del campo \"%s\" al Tipo SQL \"%s\"';\n  cSBadOCI = 'Versin de OCI [%s] no aceptable. Se requiere versin 8.0.3 o menor';\n  cSConnect2AsUser = 'Conectando a \"%s\" como usuario \"%s\"';\n  cSUnknownError = 'Error desconocido';\n  cSFieldNotFound1 = 'Campo \"%s\" no encontrado';\n  cSFieldNotFound2 = 'Campo %d no encontrado';\n\n  cSLoginPromptFailure = 'Cuadro de Dilogo por omisin para autenticacin no encontrado.'+#10#13+\n                        'Por favor agregue la unidad DBLogDlg a la seccin uses de la unidad principal de su proyecto.';\n\n  cSPropertyQuery = 'La Consulta puede tardar un poco en bases de datos extensas!';\n  cSPropertyTables = 'Debera limitarlas mediante Catalog y/o Schema.';\n  cSPropertyColumns = 'Debera limitarlas mediante Catalog, Schema y/o TableName.';\n  cSPropertyProcedures = 'Debera limitarlos mediante Catalog y/or Schema.';\n  cSPropertySequences = 'Debera limitarlos mediante Catalog y/or Schema.';\n  cSPropertyExecute = 'Desea ejecutar la consulta de todos modos?';\n\n  cSFormTest = 'Prueba del Editor ZEOS SQL';\n  cSButtonClose = '&Cerrar';\n  cSFormEditor = 'Editor ZEOS SQL';\n  cSTabSheetSelect = 'Seleccionar SQL';\n  cSMenuLoad = 'Cargar...';\n  cSMenuSave = 'Guardar...';\n  cSButtonGenerate = '&Generar';\n  cSButtonCheck = 'C&hecar';\n  cSButtonTest = 'Pro&bar';\n  cSButtonOk = '&Aceptar';\n  cSButtonCancel = '&Cancelar';\n  cSTableAlias = 'A&lias de la tabla';\n  cSReplaceSQL = '&Reemplazar SQL';\n  cSDialogOpenTitle = 'Abrir archivo SQL';\n  cSDialogSaveTitle = 'Guardar archivo SQL';\n  cSSQLEditor = 'Editor SQL';\n  cSDatabaseDialog = 'Abrir base de datos existente';\n\n  cSUpdateSQLNoResult = 'Translate : Update Refresh SQL delivered no resultset';\n  cSUpdateSQLRefreshStatementcount ='Translate : Update Refresh SQL Statement count must be 1';\n\n  {$IFDEF FPC}\n  cSNotEditing = 'El Dataset no se encuentra en modo de edicin o insercin';\n  cSFieldTypeMismatch = 'El Tipo de dato no coincide para el campo ''%s'', se espera: %s, actual: %s';\n  cSFieldSizeMismatch = 'El Tamao de dato no coincide para el campo ''%s'', se espera: %d, actual: %d';\n  {$ENDIF}\n  cSNeedField               = 'Translate: Field %s is required, but not supplied.';\n\n  cSFailedtoInitPrepStmt   = 'Translate: Prepared statement failed to initialize';\n  cSFailedtoPrepareStmt    = 'Translate: Statement failed during prepare process';\n  cSFailedToBindAllValues  = 'Translate: Application failed to pre-bind all values';\n  cSAttemptExecOnBadPrep   = 'Translate: Attempt made to execute a statement before a successful preparation.';\n  cSBindingFailure         = 'Translate: Failed to bind parameter set';\n  cSPreparedStmtExecFailure = 'Translate: Prepared statement failed to execute';\n  cSBoundVarStrIndexMissing = 'Translate: Bound variable text index \"%s\" does not exist';\n  cSBindVarOutOfRange      = 'Translate: Bound variable index out of range: %d';\n  cSFailedToBindResults    = 'Translate: Application failed to bind to the result set';\n\n  cSRefreshRowOnlySupportedWithUpdateObject = 'TRANSLATE: The refreshrow method is only supported with an update object';\n  cSMustBeInBrowseMode = 'TRANSLATE: Operation is only allowed in dsBROWSE state';\n\n  cSUnKnownParamDataType = 'TRANSLATE: Unknown Param.DataType';\n  cSFieldReadOnly          = 'Translate : Readonly field can''t be assigned a value: %d';\n  cSInvalidUpdateCount     = 'Translate : %d record(s) updated. Only one record should have been updated.';\n\n  cSRowBufferWidthExceeded ='Translate: Row buffer width exceeded. Try using fewer or longer columns in SQL query.';\n{$ELSE}\n\n{$IFDEF ROMANA}\n\n\n SSQLError1 = 'SQL Eroare: %s';\n  cSSQLError2 = 'SQL Eroare: %s Cod: %d';\n  cSSQLError3 = 'SQL Eroare: %s Cod: %d SQL: %s';\n  cSSQLError4 = 'SQL Eroare: %s Cod: %d Mesaj: %s';\n\n  cSListCapacityError = 'Capacitatea listei este n afara limitelor (%d)';\n  cSListCountError = 'Contorul listei este n afara limitelor (%d)';\n  cSListIndexError = 'Indexul listei este n afara limitelor (%d)';\n\n  cSClonningIsNotSupported = 'Clonning nu este suportat de aceast clas';\n  cSImmutableOpIsNotAllowed = 'Operaia nu este permis ori colecia nu este modificabil';\n  cSStackIsEmpty = 'Stiva este goal';\n  cSVariableWasNotFound = 'Variabila \"%s\" nu a fost gsit';\n  cSFunctionWasNotFound = 'Funcia \"%s\" nu a fost gsit';\n  cSInternalError = 'Eroare Intern';\n  cSSyntaxErrorNear = 'Eroare de sintax lng \"%s\"';\n  cSSyntaxError = 'Eroare de sintax';\n  cSUnknownSymbol = 'Simbol necunoscut \"%s\"';\n  cSUnexpectedExprEnd = 'Final neateptat pentru expresie';\n  cSRightBraceExpected = ') ateptat';\n  cSParametersError = 'parametrul %d a fost ateptat dar %d a fost gsit';\n  cSExpectedMoreParams = 'Mai nult de doi parametrii sunt ateptai';\n  cSInvalidVarByteArray = 'Arie VarByte invalid';\n  cSVariableAlreadyExists = 'Variabila \"%s\" deja exist';\n  cSTypesMismatch = 'Tip nepotrivit';\n  cSUnsupportedVariantType = 'Tip variant neasteptat';\n  cSUnsupportedOperation = 'Operaie nesuportat';\n\n  cSTokenizerIsNotDefined = 'Simbolistica nu este definit';\n  cSLibraryNotFound = 'None of the dynamic libraries can be found: %s';\n  cSEncodeDateIsNotSupported = 'Aceast versiune nu suport isc_encode_sql_date';\n  cSEncodeTimeIsNotSupported = 'Aceast versiune nu suport isc_encode_sql_time';\n  cSEncodeTimestampIsNotSupported = 'Aceast versiune nu suport isc_encode_sql_timestamp';\n  cSDecodeDateIsNotSupported = 'Aceast versiune nu suport isc_decode_sql_date';\n  cSDecodeTimeIsNotSupported = 'Aceast versiune nu suport isc_decode_sql_time';\n  cSDecodeTimestampIsNotSupported = 'Aceast versiune nu suport isc_decode_sql_timestamp';\n\n  cSCanNotRetrieveResultSetData = 'Nu pot returna  Resultset data';\n  cSRowBufferIsNotAssigned = 'Row buffer nu este asignat';\n  cSColumnIsNotAccessable = 'Column with index %d nu este accesibil';\n  cSConvertionIsNotPossible = 'Conversia nu este posibil pentru coloana %d din %s n %s';\n  cSCanNotAccessBlobRecord = 'Nu pot aceesa nregistrarea blob n coloana %d cu tipul %s';\n  cSRowDataIsNotAvailable = 'Row data nu este disponibil';\n  cSResolverIsNotSpecified = 'Resolver nu este specificat pentru acest ResultSet';\n  cSResultsetIsAlreadyOpened = 'Resultset este deja deschis';\n  cSCanNotUpdateEmptyRow = 'Nu pot updata o nregistrare goal';\n  cSCanNotUpdateDeletedRow = 'Nu pot updata o nregistrare tears';\n  cSCanNotDeleteEmptyRow = 'Nu pot terge o nregistrare goal';\n  cSCannotUseCommit = 'Nu poi folosi COMMIT n modul AUTOCOMMIT ';\n  cSCannotUseRollBack = 'Nu poi folosi ROLLBACK n modul AUTOCOMMIT ';\n  cSCanNotUpdateComplexQuery = 'Nu pot updata un query complex cu mai mult de un tabel';\n  cSCanNotUpdateThisQueryType = 'Nu pot updata acest tip de query';\n  cSDriverWasNotFound = 'Driverul pentru baza de date nu a fost gsit';\n  cSCanNotConnectToServer = 'Nu ma pot conecta la serverul SQL';\n  cSTableIsNotSpecified = 'Tbelul nu este specificat';\n  cSLiveResultSetsAreNotSupported = 'Live query is not supported by this class';\n  cSInvalidInputParameterCount = 'Input parameter count is less then expected';\n  cSIsolationIsNotSupported = 'Transaction isolation level nu este suportat';\n  cSColumnWasNotFound = 'Coloana cu numele \"%s\" nu a fost fsit';\n  cSWrongTypeForBlobParameter = 'Tip greit pentru parametru Blob';\n  cSIncorrectConnectionURL = 'Conexiune URL incorect: %s';\n  cSUnsupportedProtocol = 'Protocol nesuportat: %s';\n  cSUnsupportedByDriver    = 'Driver nu poate suporta aceast facilitate : [%s]';\n\n  cSConnectionIsNotOpened = 'Conexiune nu este deschis inc';\n  cSInvalidOpInAutoCommit = 'Operaie invalid n modul AutoCommit';\n  cSInvalidOpInNonAutoCommit = 'Operaie invalid n modul non AutoCommit ';\n  cSInvalidOpPrepare = 'Prepare transaction only possible on matching first(!) Starttransaction';\n\n  cSConnectionIsNotAssigned = 'Nu este asignat o component Database connection';\n  cSQueryIsEmpty = 'SQL Query este gol';\n  cSCanNotExecuteMoreQueries = 'Nu pot executa mai mult de un query';\n  cSOperationIsNotAllowed1 = 'Operaia nu este permis n modul FORWARD ONLY ';\n  cSOperationIsNotAllowed2 = 'Operaia nu este permis n modul READ ONLY';\n  cSOperationIsNotAllowed3 = 'Operaia nu este permis n modul %s ';\n  cSOperationIsNotAllowed4 = 'Operaia nu este permis pentru n dataset nchis';\n  cSNoMoreRecords = 'Nu mai sunt nregistrri n Resultset';\n  cSCanNotOpenResultSet = 'Nu pot deschide Resultset';\n  cSCanNotOpenDataSetWhenDestroying ='Translate : Cannot open a dataset when the componentstate is dsDestroying';\n  cSCircularLink = 'Datasource makes a circular link';\n  cSBookmarkWasNotFound = 'Bookmark nu a fost gsit';\n  cSIncorrectSearchFieldsNumber = 'Numr incorect of search field values';\n  cSInvalidOperationInTrans = 'Operaie invalid n modul explicit transaction';\n  cSIncorrectSymbol = 'Simbol incorect n lista de cmpuri  \"%s\".';\n  cSIncorrectToken = 'Incorect token dup \":\"';\n  cSIncorrectParamChar = 'TRANSLATE : Invalid value for ParamChar';\n\n  cSSelectedTransactionIsolation = 'Selected transaction isolation level is not supported';\n  cSDriverNotSupported = 'Driver nesuportat %s';\n  cSPattern2Long = 'Pattern is too long';\n  cSDriverNotCapableOutParameters = 'Driver nu este capabil s mnuie parametrii';\n  cSStatementIsNotAllowed = 'Statement nu sunt permise';\n  cSStoredProcIsNotAllowed = 'The stored proc nu sunt permise';\n  cSCannotPerformOperation = 'Nu se pot face operaii cu Resultset nchis';\n  cSInvalidState = 'Stare invalid';\n  cSErrorConvertion = 'Eroare de conversie';\n  cSDataTypeDoesNotSupported = 'Tip de dat nesuportat';\n  cSUnsupportedParameterType = 'Tip parametru nesuportat';\n  cSUnsupportedDataType = 'Tip dat nesuportat';\n  cSErrorConvertionField = 'Eroare de conversie pentru cmpul \"%s\" n TipSQL \"%s\"';\n  cSBadOCI = 'Bad OCI version [%s]. Version 8.0.3 or older is required';\n  cSConnect2AsUser = 'Conectare la \"%s\" ca utlizator \"%s\"';\n  cSUnknownError = 'Eroare necunoscut';\n  cSFieldNotFound1 = 'Cmpul \"%s\" nu a fost gsit';\n  cSFieldNotFound2 = 'Cmpul %d nu a fost gsit';\n\n  cSLoginPromptFailure = 'Nu gsesc fereastra de dialog implicit pentru login. V rog adugai DBLogDlg n seciunea uses.';\n\n  cSPropertyQuery = 'The Query may last a while on large databases!';\n  cSPropertyTables = 'You should limit it by Catalog and/or Schema.';\n  cSPropertyColumns = 'You should limit it by Catalog, Schema and/or TableName.';\n  cSPropertyProcedures = 'You should limit it by Catalog and/or Schema.';\n  cSPropertySequences = 'You should limit it by Catalog and/or Schema.';\n  cSPropertyExecute = 'Query va fi executat oricum?';\n\n  cSFormTest = 'ZEOS SQL Editor Test';\n  cSButtonClose = 'n&chide';\n  cSFormEditor = 'ZEOS SQL Editor';\n  cSTabSheetSelect = 'Select SQL';\n  cSMenuLoad = 'Deschide';\n  cSMenuSave = 'Salvare';\n  cSButtonGenerate = '&Generare';\n  cSButtonCheck = 'Verificare';\n  cSButtonTest = '&Test';\n  cSButtonOk = '&OK';\n  cSButtonCancel = 'Revo&care';\n  cSTableAlias = 'T&able alias';\n  cSReplaceSQL = '&Replace SQL';\n  cSDialogOpenTitle = 'Deschide Fiier SQL';\n  cSDialogSaveTitle = 'Salveaz Fiier SQL';\n  cSSQLEditor = 'SQL Editor';\n  cSDatabaseDialog = 'Deschide baz date existent';\n\n  cSUpdateSQLNoResult = '\"Update Refresh SQL\" furnizat nu este un recordset';\n  cSUpdateSQLRefreshStatementcount ='Declaraia \"Update Refresh SQL\" ca numr trebuie s fie una';\n\n  {$IFDEF FPC}\n  cSNotEditing = 'Dataset nu este n modul de editare sau inserare';\n  cSFieldTypeMismatch = 'Tip nepotrivit pentru cmpul ''%s'', ateptat: %s actual: %s';\n  cSFieldSizeMismatch = 'Dimensiune nepotrivit pentru cmpul  ''%s'', ateptat: %d actual: %d';\n  {$ENDIF}\n  cSNeedField               = 'Translate: Field %s is required, but not supplied.';\n\n  cSFailedtoInitPrepStmt   = 'Translate: Prepared statement failed to initialize';\n  cSFailedtoPrepareStmt    = 'Translate: Statement failed during prepare process';\n  cSFailedToBindAllValues  = 'Translate: Application failed to pre-bind all values';\n  cSAttemptExecOnBadPrep   = 'Translate: Attempt made to execute a statement before a successful preparation.';\n  cSBindingFailure         = 'Translate: Failed to bind parameter set';\n  cSPreparedStmtExecFailure = 'Translate: Prepared statement failed to execute';\n  cSBoundVarStrIndexMissing = 'Translate: Bound variable text index \"%s\" does not exist';\n  cSBindVarOutOfRange      = 'Translate: Bound variable index out of range: %d';\n  cSFailedToBindResults    = 'Translate: Application failed to bind to the result set';\n\n  cSRefreshRowOnlySupportedWithUpdateObject = 'TRANSLATE: The refreshrow method is only supported with an update object';\n  cSMustBeInBrowseMode = 'TRANSLATE: Operation is only allowed in dsBROWSE state';\n\n  cSUnKnownParamDataType = 'TRANSLATE: Unknown Param.DataType';\n\n  cSRowBufferWidthExceeded ='Translate: Row buffer width exceeded. Try using fewer or longer columns in SQL query.';\n  // <-- added by tohenk\n  {$ELSE}\n  {$IFDEF INDONESIAN}\n  cSSQLError1 = 'Kesalahan SQL: %s';\n  cSSQLError2 = 'Kesalahan SQL: %s Kode: %d';\n  cSSQLError3 = 'Kesalahan SQL: %s Kode: %d SQL: %s';\n  cSSQLError4 = 'Kesalahan SQL: %s Kode: %d Pesan: %s';\n\n  cSListCapacityError = 'Kapasitas List diluar jangkauan (%d)';\n  cSListCountError = 'Jumlah List diluar jangkauan (%d)';\n  cSListIndexError = 'Indeks List diluar jangkauan (%d)';\n\n  cSClonningIsNotSupported = 'Class ini tidak mendukung kloning';\n  cSImmutableOpIsNotAllowed = 'Operasi tidak diperkenankan pada koleksi yang tidak dapat diubah';\n  cSStackIsEmpty = 'Stack kosong';\n  cSVariableWasNotFound = 'Variabel \"%s\" tidak ada';\n  cSFunctionWasNotFound = 'Fungsi \"%s\" tidak ada';\n  cSInternalError = 'Kesalahan internal';\n  cSSyntaxErrorNear = 'Kesalahan Syntax di dekat \"%s\"';\n  cSSyntaxError = 'Kesalahan Syntax';\n  cSUnknownSymbol = 'Simbol tidak dikenali \"%s\"';\n  cSUnexpectedExprEnd = 'Tidak dibutuhkan, akhir dari ekspresi';\n  cSRightBraceExpected = ') dibutuhkan';\n  cSParametersError = '%d parameter dibutuhkan tapi terdapat %d parameter';\n  cSExpectedMoreParams = 'Dibutuhkan lebih dari dua parameter';\n  cSInvalidVarByteArray = 'array VarByte tidak valid';\n  cSVariableAlreadyExists = 'Variabel \"%s\" sudah ada';\n  cSTypesMismatch = 'Tipe tidak sesuai';\n  cSUnsupportedVariantType = 'Tipe variant tidak didukung';\n  cSUnsupportedOperation = 'Operasi tidak didukung';\n\n  cSTokenizerIsNotDefined = 'Tokenizer belum ditentukan';\n  cSLibraryNotFound = 'Tidak ada library ditemukan: %s';\n  cSEncodeDateIsNotSupported = 'Versi ini tidak mendukung isc_encode_sql_date';\n  cSEncodeTimeIsNotSupported = 'Versi ini tidak mendukung isc_encode_sql_time';\n  cSEncodeTimestampIsNotSupported = 'Versi ini tidak mendukung isc_encode_sql_timestamp';\n  cSDecodeDateIsNotSupported = 'Versi ini tidak mendukung isc_decode_sql_date';\n  cSDecodeTimeIsNotSupported = 'Versi ini tidak mendukung isc_decode_sql_time';\n  cSDecodeTimestampIsNotSupported = 'Versi ini tidak mendukung isc_decode_sql_timestamp';\n\n  cSCanNotRetrieveResultSetData = 'Tidak dapat mengambil data Resultset';\n  cSRowBufferIsNotAssigned = 'Row buffer tidak disediakan';\n  cSColumnIsNotAccessable = 'Kolom dengan indeks %d tidak dapat diakses';\n  cSConvertionIsNotPossible = 'Konversi tidak dimungkinkan pada kolom %d dari %s ke %s';\n  cSCanNotAccessBlobRecord = 'Tidak dapat mengakses rekord `blob` pada kolom %d dengan tipe %s';\n  cSRowDataIsNotAvailable = 'Data Row tidak tersedia';\n  cSResolverIsNotSpecified = 'Resolver belum ditentukan pada ResultSet ini';\n  cSResultsetIsAlreadyOpened = 'Resultset sudah terbuka';\n  cSCanNotUpdateEmptyRow = 'Tidak dapat meng-update row kosong';\n  cSCanNotUpdateDeletedRow = 'Tidak dapat meng-update row terhapus';\n  cSCanNotDeleteEmptyRow = 'Tidak dapat meng-hapus row kosong';\n  cSCannotUseCommit = 'COMMIT tidak dapat digunakan pada mode AUTOCOMMIT';\n  cSCannotUseRollBack = 'ROLLBACK tidak dapat digunakan pada mode AUTOCOMMIT';\n  cSCanNotUpdateComplexQuery = 'Tidak dapat meng-update query kompleks dengan lebih dari satu tabel';\n  cSCanNotUpdateThisQueryType = 'Tidak dapat meng-update query dengan tipe ini';\n  cSDriverWasNotFound = 'Driver database yang diminta tidak ada';\n  cSCanNotConnectToServer = 'Tidak dapat terhubung ke server SQL';\n  cSTableIsNotSpecified = 'Tabel belum ditentukan';\n  cSLiveResultSetsAreNotSupported = 'Live query tidak didukung oleh Class ini';\n  cSInvalidInputParameterCount = 'Jumlah parameter Input kurang dari yang dibutuhkan';\n  cSIsolationIsNotSupported = 'Level Isolasi Transaksi tidak didukung';\n  cSColumnWasNotFound = 'Kolom dengan nama \"%s\" tidak ada';\n  cSWrongTypeForBlobParameter = 'Salah tipe untuk parameter Blob';\n  cSIncorrectConnectionURL = 'Salah koneksi URL: %s';\n  cSUnsupportedProtocol = 'Protokol tidak didukung: %s';\n  cSUnsupportedByDriver    = 'Driver tidak mendukung fitur: [%s]';\n\n  cSConnectionIsNotOpened = 'Koneksi belum dibuka';\n  cSInvalidOpInAutoCommit = 'Operasi tidak valid pada mode AUTOCOMMIT';\n  cSInvalidOpInNonAutoCommit = 'Operasi tidak valid pada mode non AUTOCOMMIT';\n  cSInvalidOpPrepare = 'Persiapan transaksi hanya mungkin pada (!) Starttransaction pertama';\n\n  cSConnectionIsNotAssigned = 'Komponen koneksi Database tidak ditentukan';\n  cSQueryIsEmpty = 'Query SQL kosong';\n  cSCanNotExecuteMoreQueries = 'Tidak dapat meng-eksekusi lebih dari satu query';\n  cSOperationIsNotAllowed1 = 'Operasi tidak diperkenankan pada mode FORWARD ONLY';\n  cSOperationIsNotAllowed2 = 'Operasi tidak diperkenankan pada mode READ ONLY';\n  cSOperationIsNotAllowed3 = 'Operasi tidak diperkenankan pada mode %s';\n  cSOperationIsNotAllowed4 = 'Operasi tidak diperkenankan pada dataset tertutup';\n  cSNoMoreRecords = 'Tidak ada rekord lagi pada Resultset';\n  cSCanNotOpenResultSet = 'Tidak dapat membuka Resultset';\n  cSCanNotOpenDataSetWhenDestroying ='Translate : Cannot open a dataset when the componentstate is dsDestroying';\n  cSCircularLink = 'Terjadi hubungan Datasource circular';\n  cSBookmarkWasNotFound = 'Bookmark tidak ada';\n  cSIncorrectSearchFieldsNumber = 'Salah jumlah nilai field pada pencarian';\n  cSInvalidOperationInTrans = 'Operasi tidak valid pada mode explicit transaction';\n  cSIncorrectSymbol = 'Simbol salah pada daftar field \"%s\".';\n  cSIncorrectToken = 'Token salah setelah \":\"';\n  cSIncorrectParamChar = 'TRANSLATE : Invalid value for ParamChar';\n\n  cSSelectedTransactionIsolation = 'Level Isolasi Transaksi terpilih tidak didukung';\n  cSDriverNotSupported = 'Driver tidak mendukung %s';\n  cSPattern2Long = 'Pola terlalu panjang';\n  cSDriverNotCapableOutParameters = 'Driver tidak mampu menangani parameter';\n  cSStatementIsNotAllowed = 'Statement tidak diperbolehkan';\n  cSStoredProcIsNotAllowed = 'StoredProc tidak diperbolehkan';\n  cSCannotPerformOperation = 'Tidak dapat melakukan operasi pada Resultset tertutup';\n  cSInvalidState = 'Sate tidak valid';\n  cSErrorConvertion = 'Kesalahan konversi';\n  cSDataTypeDoesNotSupported = 'Tipe Data tidak didukung';\n  cSUnsupportedParameterType = 'Tidak mendukung tipe parameter';\n  cSUnsupportedDataType = 'Tidak mendukung tipe data';\n  cSErrorConvertionField = 'Kesalahan konversi field \"%s\" ke Tipe SQL \"%s\"';\n  cSBadOCI = 'OCI version [%s] tidak sah. Dibutuhkan versi 8.0.3 atau terdahulu';\n  cSConnect2AsUser = 'Koneksi ke \"%s\" dengan user \"%s\"';\n  cSUnknownError = 'Kesalahan tidak diketahui';\n  cSFieldNotFound1 = 'Field \"%s\" tidak ada';\n  cSFieldNotFound2 = 'Field %d tidak ada';\n\n  cSLoginPromptFailure = 'Tidak ada dialog Login default. Silahkan tambahkan DBLogDlg ke klausula `uses` pada file utama.';\n\n  cSPropertyQuery = 'Query mungkin berlangsung lama pada database besar!';\n  cSPropertyTables = 'Batasi dengan Katalog data/atau Skema.';\n  cSPropertyColumns = 'Batasi dengan Katalog, Skema dan/atau Nama Tabel.';\n  cSPropertyProcedures = 'Batasi dengan Katalog dan/atau Skema.';\n  cSPropertySequences = 'Batasi dengan Katalog dan/atau Skema.';\n  cSPropertyExecute = 'Apakah Query jadi dieksekusi?';\n\n  cSFormTest = 'Tes Editor SQLZEOS';\n  cSButtonClose = '&Tutup';\n  cSFormEditor = 'Editor SQL ZEOS';\n  cSTabSheetSelect = 'SQL Select';\n  cSMenuLoad = 'Ambil';\n  cSMenuSave = 'Simpan';\n  cSButtonGenerate = '&Generate';\n  cSButtonCheck = '&Cek';\n  cSButtonTest = 'T&es';\n  cSButtonOk = '&OK';\n  cSButtonCancel = '&Batal';\n  cSTableAlias = 'Alias T&abel';\n  cSReplaceSQL = 'SQL &Replace';\n  cSDialogOpenTitle = 'Buka File SQL';\n  cSDialogSaveTitle = 'Simpan File SQL';\n  cSSQLEditor = 'Editor SQL';\n  cSDatabaseDialog = 'Buka database yang tersedia';\n\n  cSUpdateSQLNoResult = 'Tidak ada Resultset pada Update Refresh SQL';\n  cSUpdateSQLRefreshStatementcount ='Jumlah Statement pada Update Refresh SQL harus 1';\n\n  {$IFDEF FPC}\n  cSNotEditing = 'Dataset tidak dalam mode edit atau sisip';\n  cSFieldTypeMismatch = 'Tipe tidak sesuai pada field ''%s'', seharusnya: %s aktual: %s';\n  cSFieldSizeMismatch = 'Ukuran tidak sesuai pada field ''%s'', seharusnya: %d aktual: %d';\n  {$ENDIF}\n  cSNeedField               = 'Field %s diperlukan, namun tidak disediakan.';\n\n  cSFailedtoInitPrepStmt   = 'Gagal inisialisasi Prepared statement';\n  cSFailedtoPrepareStmt    = 'Statemen gagal sewaktu proses persiapan';\n  cSFailedToBindAllValues  = 'Aplikasi gagal dalam penggabungan pendahuluan semua nilai';\n  cSAttemptExecOnBadPrep   = 'Percobaan eksekusi statemen dilakukan sebelum persiapan berhasil.';\n  cSBindingFailure         = 'Gagal menggabungkan parameter';\n  cSPreparedStmtExecFailure = 'Prepared Statement gagal dieksekusi';\n  cSBoundVarStrIndexMissing = 'Teks variabel indeks \"%s\" tidak ada';\n  cSBindVarOutOfRange      = 'Variabel indeks diluar jangkauan: %d';\n  cSFailedToBindResults    = 'Aplikasi gagal pada penggabungan ke Resultset';\n\n  cSRefreshRowOnlySupportedWithUpdateObject = 'Metode RefreshRow hanya didukung oleh obyek Update';\n  cSMustBeInBrowseMode = 'Operasi hanya diperbolehkan pada status dsBrowse';\n\n  cSUnKnownParamDataType = 'Param.DataType tidak dikenal';\n  cSFieldReadOnly          = 'Field readonly tidak dapat diberikan nilai: %d';\n  cSInvalidUpdateCount     = '%d rekord terupdate. Seharusnya hanya satu rekord yang terupdate.';\n\n  cSRowBufferWidthExceeded = 'Lebar buffer baris terlampaui. Coba kurangi atau gunakan kolom yang lebih panjang dalam query SQL.';\n  // <--- end added by tohenk\n  //--- begin added by ORMADA --------------------------------------------------\n{$ELSE}\n{$IFDEF RUSSIAN}\n  cSSQLError1                               = '  SQL : %s';\n  cSSQLError2                               = '  SQL : %s  : %d';\n  cSSQLError3                               = '  SQL : %s  : %d SQL: %s';\n  cSSQLError4                               = '  SQL : %s  : %d : %s';\n\n  cSListCapacityError                       = '     (%d)';\n  cSListCountError                          = '     (%d)';\n  cSListIndexError                          = '     (%d)';\n\n  cSClonningIsNotSupported                  = '    ';\n  cSImmutableOpIsNotAllowed                 = '     ';\n  cSStackIsEmpty                            = ' ';\n  cSVariableWasNotFound                     = ' \"%s\"  ';\n  cSFunctionWasNotFound                     = ' \"%s\"  ';\n  cSInternalError                           = ' ';\n  cSSyntaxErrorNear                         = '   \"%s\"';\n  cSSyntaxError                             = '  ';\n  cSUnknownSymbol                           = '  \"%s\"';\n  cSUnexpectedExprEnd                       = '  ';\n  cSRightBraceExpected                      = ') ';\n  cSParametersError                         = ' %d ,  %d';\n  cSExpectedMoreParams                      = '  2- ';\n  cSInvalidVarByteArray                     = '  (VarByte)';\n  cSVariableAlreadyExists                   = ' \"%s\"  ';\n  cSTypesMismatch                           = ' ';\n  cSUnsupportedVariantType                  = '  (variant) ';\n  cSUnsupportedOperation                    = ' ';\n\n  cSTokenizerIsNotDefined                   = '  ';\n  cSLibraryNotFound                         = '     : %s';\n  cSEncodeDateIsNotSupported                = '    isc_encode_sql_date';\n  cSEncodeTimeIsNotSupported                = '    isc_encode_sql_time';\n  cSEncodeTimestampIsNotSupported           = '    isc_encode_sql_timestamp';\n  cSDecodeDateIsNotSupported                = '    isc_decode_sql_date';\n  cSDecodeTimeIsNotSupported                = '    isc_decode_sql_time';\n  cSDecodeTimestampIsNotSupported           = '    isc_decode_sql_timestamp';\n\n  cSCanNotRetrieveResultSetData             = '    (Resultset)';\n  cSRowBufferIsNotAssigned                  = '   ';\n  cSColumnIsNotAccessable                   = '    %d';\n  cSConvertionIsNotPossible                 = '    %d  %s  %s';\n  cSCanNotAccessBlobRecord                  = '    blob    %d   %s';\n  cSRowDataIsNotAvailable                   = '  ';\n  cSResolverIsNotSpecified                  = '    (ResultSet)   Resolver';\n  cSResultsetIsAlreadyOpened                = '  (Resultset)  ';\n  cSCanNotUpdateEmptyRow                    = '   ';\n  cSCanNotUpdateDeletedRow                  = '   ';\n  cSCanNotDeleteEmptyRow                    = '   ';\n  cSCannotUseCommit                         = '  COMMIT  AUTOCOMMIT ';\n  cSCannotUseRollBack                       = '  ROLLBACK  AUTOCOMMIT ';\n  cSCanNotUpdateComplexQuery                = '        ';\n  cSCanNotUpdateThisQueryType               = '    ';\n  cSDriverWasNotFound                       = '    ';\n  cSCanNotConnectToServer                   = '   SQL ';\n  cSTableIsNotSpecified                     = '  ';\n  cSLiveResultSetsAreNotSupported           = '      ';\n  cSInvalidInputParameterCount              = '   is   ';\n  cSIsolationIsNotSupported                 = '    ';\n  cSColumnWasNotFound                       = '     \"%s\"';\n  cSWrongTypeForBlobParameter               = '   Blob ';\n  cSIncorrectConnectionURL                  = '  (URL)  : %s';\n  cSUnsupportedProtocol                     = ' : %s';\n  cSUnsupportedByDriver                     = '     : [%s]';\n\n  cSConnectionIsNotOpened                   = '  ';\n  cSInvalidOpInAutoCommit                   = '     (AutoCommit)';\n  cSInvalidOpInNonAutoCommit                = '      (non AutoCommit)';\n  cSInvalidOpPrepare                        = '      (!) StartTransaction';\n\n  cSConnectionIsNotAssigned                 = '    ';\n  cSQueryIsEmpty                            = 'SQL  ';\n  cSCanNotExecuteMoreQueries                = '    ';\n  cSOperationIsNotAllowed1                  = '       (FORWARD ONLY)';\n  cSOperationIsNotAllowed2                  = '        (READ ONLY)';\n  cSOperationIsNotAllowed3                  = '    %s ';\n  cSOperationIsNotAllowed4                  = '      ';\n  cSNoMoreRecords                           = '   (Resultset)  ';\n  cSCanNotOpenResultSet                     = '    (Resultset)';\n  cSCanNotOpenDataSetWhenDestroying ='Translate : Cannot open a dataset when the componentstate is dsDestroying';\n  cSCircularLink                            = '  (Datasource)   ';\n  cSBookmarkWasNotFound                     = ' (Bookmark)  ';\n  cSIncorrectSearchFieldsNumber             = '   Incorrect number of search field values';\n  cSInvalidOperationInTrans                 = '    ';\n  cSIncorrectSymbol                         = '     \"%s\".';\n  cSIncorrectToken                          = '   \":\"';\n  cSIncorrectParamChar = 'TRANSLATE : Invalid value for ParamChar';\n\n  cSSelectedTransactionIsolation            = '     ';\n  cSDriverNotSupported                      = '   %s';\n  cSPattern2Long                            = '  ';\n  cSDriverNotCapableOutParameters           = '    ';\n  cSStatementIsNotAllowed                   = '  ';\n  cSStoredProcIsNotAllowed                  = '   ';\n  cSCannotPerformOperation                  = '       (Resultset)';\n  cSInvalidState                            = ' ';\n  cSErrorConvertion                         = ' ';\n  cSDataTypeDoesNotSupported                = '   ';\n  cSUnsupportedParameterType                = '  ';\n  cSUnsupportedDataType                     = '  ';\n  cSErrorConvertionField                    = '    \"%s\"  SQLType \"%s\"';\n  cSBadOCI                                  = '  OCI [%s].   8.0.3  ';\n  cSConnect2AsUser                          = '   \"%s\"  \"%s\"';\n  cSUnknownError                            = ' ';\n  cSFieldNotFound1                          = ' \"%s\"  ';\n  cSFieldNotFound2                          = ' %d  ';\n\n  cSLoginPromptFailure                      = '     .   DBLogDlg   uses   .';\n\n  cSPropertyQuery                           = '        The Query may last a while on large databases!';\n  cSPropertyTables                          = '  (Catalog) /  (Schema)';\n  cSPropertyColumns                         = '   (Catalog),  (Schema) /  (TableName).';\n  cSPropertyProcedures                      = '  (Catalog) /  (Schema).';\n  cSPropertySequences                       = '  (Catalog) /  (Schema).';\n  cSPropertyExecute                         = '    ?';\n\n  cSFormTest                                = 'ZEOS SQL  ';\n  cSButtonClose                             = '&';\n  cSFormEditor                              = 'ZEOS SQL ';\n  cSTabSheetSelect                          = ' SQL';\n  cSMenuLoad                                = '';\n  cSMenuSave                                = '';\n  cSButtonGenerate                          = '&';\n  cSButtonCheck                             = '&';\n  cSButtonTest                              = '&';\n  cSButtonOk                                = '&';\n  cSButtonCancel                            = '&';\n  cSTableAlias                              = '& ';\n  cSReplaceSQL                              = '& SQL';\n  cSDialogOpenTitle                         = ' SQL ';\n  cSDialogSaveTitle                         = ' SQL ';\n  cSSQLEditor                               = 'SQL ';\n  cSDatabaseDialog                          = '  ';\n\n  cSUpdateSQLNoResult                       = '   (Refresh)   ';\n  cSUpdateSQLRefreshStatementcount          = 'Refresh     ';\n\n{$IFDEF FPC}\n  cSNotEditing                              = '  (Dataset)      ';\n  cSFieldTypeMismatch                       = '    ''%s'',  %s : %s';\n  cSFieldSizeMismatch                       = '  ''%s''  , : %d : %d';\n{$ENDIF}\n  cSNeedField               = 'Translate: Field %s is required, but not supplied.';\n\n  cSFailedtoInitPrepStmt                    = '   ';\n  cSFailedtoPrepareStmt                     = '     ';\n  cSFailedToBindAllValues                   = '  - ';\n  cSAttemptExecOnBadPrep                    = '     .';\n  cSBindingFailure                          = '   ';\n  cSPreparedStmtExecFailure                 = '   ';\n  cSBoundVarStrIndexMissing                 = '     \"%s\"  ';\n  cSBindVarOutOfRange                       = '     : %d';\n  cSFailedToBindResults                     = ' (bind)  ';\n\n  cSRefreshRowOnlySupportedWithUpdateObject = '   (RefreshRow)     ';\n  cSMustBeInBrowseMode                      = '      (dsBROWSE)';\n\n  cSUnKnownParamDataType                    = '   (Param.DataType)';\n  //--- end added by ORMADA ----------------------------------------------------\n  cSFieldReadOnly          = 'Translate : Readonly field can''t be assigned a value: %d';\n  cSInvalidUpdateCount     = 'Translate : %d record(s) updated. Only one record should have been updated.';\n\n  cSRowBufferWidthExceeded ='Translate: Row buffer width exceeded. Try using fewer or longer columns in SQL query.';\n{$ELSE}\n\n//--- added by Petr Stasiak - pestasoft.com ------------------------------------\n{$IFDEF CZECH}\n  cSSQLError1 = 'SQL chyba: %s';\n  cSSQLError2 = 'SQL chyba: %s kd: %d';\n  cSSQLError3 = 'SQL chyba: %s kd: %d SQL: %s';\n  cSSQLError4 = 'SQL chyba: %s kd: %d Hlen: %s';\n\n  cSListCapacityError = 'Kapacita seznamu je mimo rozsah (%d)';\n  cSListCountError = 'Poet seznam je mimo rozsah (%d)';\n  cSListIndexError = 'Index v seznamu je mimo rozsah (%d)';\n\n  cSClonningIsNotSupported = 'Klonovn nen v tto td podporovno';\n  cSImmutableOpIsNotAllowed = 'Tato operace nen povolena na nemniteln \"collections\"';\n  cSStackIsEmpty = 'Zsobnk je przdn';\n  cSVariableWasNotFound = 'Promn \"%s\" neexistuje';\n  cSFunctionWasNotFound = 'Funkce \"%s\" neexistuje';\n  cSInternalError = 'Intern chyba';\n  cSSyntaxErrorNear = 'Chybn syntaxe \"%s\"';\n  cSSyntaxError = 'Chybn syntaxe';\n  cSUnknownSymbol = 'Neznm symbol \"%s\"';\n  cSUnexpectedExprEnd = 'Neoekvan konec vrazu';\n  cSRightBraceExpected = ') oekvn(o/a/y)';\n  cSParametersError = '%d parametr oekvno, ale %d existuje';\n  cSExpectedMoreParams = 'Je oekvno vce, ne 2 parametry';\n  cSInvalidVarByteArray = 'Nesprvn VarByte array';\n  cSVariableAlreadyExists = 'Promn \"%s\" ji existuje';\n  cSTypesMismatch = 'Nesouhlasn typy';\n  cSUnsupportedVariantType = 'Nepodporovan typ variant';\n  cSUnsupportedOperation = 'Nepodporovan operace';\n\n  cSTokenizerIsNotDefined = 'Nen definovn \"Tokenizer\"';\n  cSLibraryNotFound = 'Neexistuje dll knihovna(y): %s';\n  cSEncodeDateIsNotSupported = 'Tato verze nepodporuje isc_encode_sql_date';\n  cSEncodeTimeIsNotSupported = 'Tato verze nepodporuje isc_encode_sql_time';\n  cSEncodeTimestampIsNotSupported = 'Tato verze nepodporuje isc_encode_sql_timestamp';\n  cSDecodeDateIsNotSupported = 'Tato verze nepodporuje isc_decode_sql_date';\n  cSDecodeTimeIsNotSupported = 'Tato verze nepodporuje isc_decode_sql_time';\n  cSDecodeTimestampIsNotSupported = 'Tato verze nepodporuje isc_decode_sql_timestamp';\n\n  cSCanNotRetrieveResultSetData = 'Nelze zskat data \"Resultset\"';\n  cSRowBufferIsNotAssigned = 'Nen piazen dkov buffer';\n  cSColumnIsNotAccessable = 'Sloupec s indexem %d nen pstupn';\n  cSConvertionIsNotPossible = 'Pevod sloupce %d  nen mon z %s na %s';\n  cSCanNotAccessBlobRecord = 'Nelze pistupovat k blob zznamu ze zloupce %d pes typ %s';\n  cSRowDataIsNotAvailable = 'dkov data nejsou pstupn';\n  cSResolverIsNotSpecified = 'Nen specifikovn \"rozklada\" pro tento vsledek';\n  cSResultsetIsAlreadyOpened = '\"Resultset\" byl ji oteven';\n  cSCanNotUpdateEmptyRow = 'Nelze aktualizovat przdn dek';\n  cSCanNotUpdateDeletedRow = 'Nelze aktualizovat smazan dek';\n  cSCanNotDeleteEmptyRow = 'Nelze vymazat przdn dek';\n  cSCannotUseCommit = 'Nepouvejte COMMIT v mdu AUTOCOMMIT';\n  cSCannotUseRollBack = 'Nelze pout ROLLBACK v AUTOCOMMIT mdu';\n  cSCanNotUpdateComplexQuery = 'Nelze aktualizovat komplexn dotaz pro vce, ne jednu tabulku';\n  cSCanNotUpdateThisQueryType = 'Nelze aktualizovat tento typ dotazu';\n  cSDriverWasNotFound = 'Poadovan databzov ovlada nenalezen';\n  cSCanNotConnectToServer = 'Nezdailo se pipojen k SQL serveru';\n  cSTableIsNotSpecified = 'Tabulka nen specifikovna';\n  cSLiveResultSetsAreNotSupported = '\"iv\" dotaz nen podporovn v tto td';\n  cSInvalidInputParameterCount = 'Poet vstupnch parametr neodpovd oekvanmu potu';\n  cSIsolationIsNotSupported = 'Mra izolace transakce nen podporovna';\n  cSColumnWasNotFound = 'Sloupec s nzvem \"%s\" neexistuje';\n  cSWrongTypeForBlobParameter = 'Nesprvn typ pro Blob parametr';\n  cSIncorrectConnectionURL = 'Nesprvn tvar URL adresy: %s';\n  cSUnsupportedProtocol = 'Nepodporovan protokol: %s';\n  cSUnsupportedByDriver    = 'Ovlada nepodporuje tuto vlastnost: [%s]';\n\n  cSConnectionIsNotOpened = 'Spojen nen oteveno';\n  cSInvalidOpInAutoCommit = 'Nesprvn operace v mdu AutoCommit';\n  cSInvalidOpInNonAutoCommit = 'Nesprvn operace v mdu NE AutoCommit';\n  cSInvalidOpPrepare = '\"Prepare\" transakce je mon pouze jako prvn! Starttransaction';\n\n  cSConnectionIsNotAssigned = 'Nen piazen komponent \"connection\"';\n  cSQueryIsEmpty = 'SQL dotaz je przdn';\n  cSCanNotExecuteMoreQueries = 'Nelze spustit vce, ne 1 dotaz';\n  cSOperationIsNotAllowed1 = 'Operace nen povolena v mdu \"FORWARD ONLY\"';\n  cSOperationIsNotAllowed2 = 'Operace nen povolena v mdu \"READ ONLY\"';\n  cSOperationIsNotAllowed3 = 'Operace nen povolena v mdu \"%s\"';\n  cSOperationIsNotAllowed4 = 'Operace nen povolena pro zaven zdroj dat (dataset)';\n  cSNoMoreRecords = 'Nejsou dal zznamy';\n  cSCanNotOpenResultSet = 'Nelze otevt vsledek dotazu';\n  cSCanNotOpenDataSetWhenDestroying ='Translate : Cannot open a dataset when the componentstate is dsDestroying';\n  cSCircularLink = 'Datasource vytv cyklick dotaz';\n  cSBookmarkWasNotFound = 'Zloka neexistuje';\n  cSIncorrectSearchFieldsNumber = 'Nesprvn poet vyhledvanch poloek';\n  cSInvalidOperationInTrans = 'Nesprvn operace v explicitnm transaknm mdu';\n  cSIncorrectSymbol = 'Nesprvn symbol v seznamu poloek \"%s\".';\n  cSIncorrectToken = 'Za \":\" nsleduje nesprvn znak';\n  cSIncorrectParamChar = 'TRANSLATE : Invalid value for ParamChar';\n\n  cSSelectedTransactionIsolation = 'Vybran mra izolace transakc nen podporovna';\n  cSDriverNotSupported = 'Ovlada %s nen podporovn';\n  cSPattern2Long = 'Pattern je pli dlouh';\n  cSDriverNotCapableOutParameters = 'Ovlada nen schopen pijmat parametry';\n  cSStatementIsNotAllowed = 'Pkaz nen povolen';\n  cSStoredProcIsNotAllowed = '\"stored proc\" nen povolena';\n  cSCannotPerformOperation = 'Nelze provst operaci na uzavenm vsledku dotazu (Resultset)';\n  cSInvalidState = 'Nesprvn stav';\n  cSErrorConvertion = 'Chyba pevodu';\n  cSDataTypeDoesNotSupported = 'Tento typ dat nen podporovn';\n  cSUnsupportedParameterType = 'Nepodporovan typ parametru';\n  cSUnsupportedDataType = 'Nepodporovan typ dat';\n  cSErrorConvertionField = 'Chyba pevodu sloupce \"%s\" na SQLTyp \"%s\"';\n  cSBadOCI = 'patn verze OCI [%s]. Je vyadovna 8.0.3 nebo star';\n  cSConnect2AsUser = 'Pipojit k \"%s\" jako \"%s\"';\n  cSUnknownError = 'Neznm chyba';\n  cSFieldNotFound1 = 'Sloupec \"%s\" neexistuje';\n  cSFieldNotFound2 = 'Sloupec %d neexistuje';\n\n  cSLoginPromptFailure = 'Nelze najt vchoz pihlaovac dialog. Prosm pidejte DBLogDlg do sekce USES vaeho zdrojovho souboru.';\n\n  cSPropertyQuery = 'Dotaz me bt posledn u vlelkch databz!';\n  cSPropertyTables = 'Mlo by bt limitovno katalogen a/nebo schmatem.';\n  cSPropertyColumns = 'Mlo by bt limitovno katalogem, schmatem a/nebo nzvem tabulky.';\n  cSPropertyProcedures = 'Mlo by bt limitovno katalogen a/nebo schmatem.';\n  cSPropertySequences = 'Mlo by bt limitovno katalogen a/nebo schmatem.';\n  cSPropertyExecute = 'M se dotaz pesto vykonat?';\n\n  cSFormTest = 'ZEOS SQL Editor Test';\n  cSButtonClose = '&Zavt';\n  cSFormEditor = 'ZEOS SQL Editor';\n  cSTabSheetSelect = 'Select SQL';\n  cSMenuLoad = 'Nast';\n  cSMenuSave = 'Uloit';\n  cSButtonGenerate = '&Generovat';\n  cSButtonCheck = '&Kontrola';\n  cSButtonTest = '&Test';\n  cSButtonOk = '&OK';\n  cSButtonCancel = 'Z&ruit';\n  cSTableAlias = '&Alias tabulky';\n  cSReplaceSQL = 'Nah&radit SQL';\n  cSDialogOpenTitle = 'Otevt SQL soubor';\n  cSDialogSaveTitle = 'Uloit SQL soubor';\n  cSSQLEditor = 'SQL Editor';\n  cSDatabaseDialog = 'Otevt existujc databzi';\n\n  cSUpdateSQLNoResult = 'Update Refresh SQL nevrtilo dn vsledek';\n  cSUpdateSQLRefreshStatementcount ='Poet Update Refresh SQL pkaz mus bt 1';\n\n  {$IFDEF FPC}\n  cSNotEditing = 'Dataset nen v editanm (edit), ani vkldacm (insert) reimu';\n  cSFieldTypeMismatch = 'Nesprvn typ pro sloupec ''%s'', oekvno: %s aktuln: %s';\n  cSFieldSizeMismatch = 'Nesprvn velikost sloupce ''%s'', oekvno: %d aktuln: %d';\n  {$ENDIF}\n  cSNeedField               = 'Sloupce %s je poadovn, ale nezadn.';\n\n  cSFailedtoInitPrepStmt   = 'Pipravovan pkaz nelze inicializovat';\n  cSFailedtoPrepareStmt    = 'Pkaz selhal bhem ppravy procesu';\n  cSFailedToBindAllValues  = 'Aplikace zkolabovala ped ppravou vech hodnot';\n  cSAttemptExecOnBadPrep   = 'Pokoute sespustit pkaz ped dokonenm jeho ppravy.';\n  cSBindingFailure         = 'Chyba pi zskvn sady parametr';\n  cSPreparedStmtExecFailure = 'Pipravovan pkaz selhal pi vykonvn';\n  cSBoundVarStrIndexMissing = 'Index textov promn \"%s\" neexistuje';\n  cSBindVarOutOfRange      = 'Index promen je mimo rozsah: %d';\n  cSFailedToBindResults    = 'Aplikace selhala pi zskvn vsledk dotazu';\n\n//FOS+ 07112006\n  cSRefreshRowOnlySupportedWithUpdateObject = 'Metoda \"refreshrow\" je podporovna pouze v \"update object\"';\n  cSMustBeInBrowseMode = 'Operace je povolena pouze ve stavu dsBROWSE';\n\n  cSUnKnownParamDataType = 'Neznm parametr.typ dat (Param.DataType)';\n  cSFieldReadOnly        = 'Sloupec pouze pro ten neme bt piazen k hodnot: %d';\n  cSInvalidUpdateCount     = '%d zznam() aktualizovno. Pouze jeden zznam byl zmnn.';\n\n  cSRowBufferWidthExceeded ='Translate: Row buffer width exceeded. Try using fewer or longer columns in SQL query.';\n//--- end added by Petr Stasiak - pestasoft.com ------------------------------------\n\n{$ELSE}\n\n//--- added by pawelsel --------------------------------------------------------\n{$IFDEF POLISH}\n\n  cSSQLError1 = 'Bd SQL: %s';\n  cSSQLError2 = 'Bd SQL: %s Kod: %d';\n  cSSQLError3 = 'Bd SQL: %s Kod: %d SQL: %s';\n  cSSQLError4 = 'Bd SQL: %s Kod: %d Komunikat: %s';\n\n  cSListCapacityError = 'Przekroczona pojemno listy (%d)';\n  cSListCountError = 'Licznik listy poza zakresem (%d)';\n  cSListIndexError = 'Indeks listy poza zakresem (%d)';\n\n  cSClonningIsNotSupported = 'Ta klasa nie obsuguje klonowania';\n  cSImmutableOpIsNotAllowed = 'Niedozwolona operacja na niezmienialnych kolekcjach';\n  cSStackIsEmpty = 'Stos jest pusty';\n  cSVariableWasNotFound = 'Nie znaleziono zmiennej \"%s\"';\n  cSFunctionWasNotFound = 'Nie znaleziono funkcji \"%s\"';\n  cSInternalError = 'Bd wewntrzny';\n  cSSyntaxErrorNear = 'Bd skadni przy \"%s\"';\n  cSSyntaxError = 'Bd skadni';\n  cSUnknownSymbol = 'Nieznany symbol \"%s\"';\n  cSUnexpectedExprEnd = 'Nieoczekiwany koniec wyraenia';\n  cSRightBraceExpected = 'Oczekiwano znaku )';\n  cSParametersError = 'Oczekiwana ilo parametrw: %d, znaleziono: %d';\n  cSExpectedMoreParams = 'Oczekiwano wicej ni dwa parametry';\n  cSInvalidVarByteArray = 'Bdna tablica VarByte';\n  cSVariableAlreadyExists = 'Zmienna \"%s\" ju istnieje';\n  cSTypesMismatch = 'Niezgodno typw';\n  cSUnsupportedVariantType = 'Nieznany typ danych';\n  cSUnsupportedOperation = 'Nieznana operacja';\n\n  cSTokenizerIsNotDefined = 'Nie zdefiniowano tokenizera';\n  cSLibraryNotFound = 'Nie znaleziono adnej z bibliotek dynamicznych: %s';\n  cSEncodeDateIsNotSupported = 'Ta wersja nie obsuguje isc_encode_sql_date';\n  cSEncodeTimeIsNotSupported = 'Ta wersja nie obsuguje isc_encode_sql_time';\n  cSEncodeTimestampIsNotSupported = 'Ta wersja nie obsuguje isc_encode_sql_timestamp';\n  cSDecodeDateIsNotSupported = 'Ta wersja nie obsuguje isc_decode_sql_date';\n  cSDecodeTimeIsNotSupported = 'Ta wersja nie obsuguje isc_decode_sql_time';\n  cSDecodeTimestampIsNotSupported = 'Ta wersja nie obsuguje isc_decode_sql_timestamp';\n\n  cSCanNotRetrieveResultSetData = 'Nie mona pobra danych wynikowych';\n  cSRowBufferIsNotAssigned = 'Nie przypisano bufora wiersza';\n  cSColumnIsNotAccessable = 'Kolumna o numerze %d jest niedostpna';\n  cSConvertionIsNotPossible = 'Konwersja kolumny o numerze %d z %s na %s jest niemoliwa';\n  cSCanNotAccessBlobRecord = 'Brak dostpu do rekordu typu blob w kolumnie %d z typem %s';\n  cSRowDataIsNotAvailable = 'Dane wiersza s niedostpne';\n  cSResolverIsNotSpecified = 'Ten ResultSet nie ma okrelonego Resolver-a';\n  cSResultsetIsAlreadyOpened = 'ResultSet jest ju otwarty';\n  cSCanNotUpdateEmptyRow = 'Nie mona aktualizowa pustego wiersza';\n  cSCanNotUpdateDeletedRow = 'Nie mona aktualizowa usunitego wiersza';\n  cSCanNotDeleteEmptyRow = 'Nie mona usun pustego wiersza';\n  cSCannotUseCommit = 'Nie mona uy COMMIT w trybie AUTOCOMMIT';\n  cSCannotUseRollBack = 'Nie mona uy ROLLBACK w trybie AUTOCOMMIT';\n  cSCanNotUpdateComplexQuery = 'Nie mona aktualizowa zapytania zoonego z wicej ni jednej tabeli';\n  cSCanNotUpdateThisQueryType = 'Nie mona aktualizowa tego typu zapytania';\n  cSDriverWasNotFound = 'Nie znaleziono wymaganego sterownika bazy danych';\n  cSCanNotConnectToServer = 'Nie mona poczy si z serwerem SQL';\n  cSTableIsNotSpecified = 'Nie okrelono tabeli';\n  cSLiveResultSetsAreNotSupported = '\"Live query\" nie jest obsugiwane przez t klas';\n  cSInvalidInputParameterCount = 'Liczba parametrw wejsciowych jest mniejsza ni oczekiwana';\n  cSIsolationIsNotSupported = 'Poziom izolacji transakcji nie jest obsugiwany';\n  cSColumnWasNotFound = 'Nie znaleziono kolumny o nazwie \"%s\"';\n  cSWrongTypeForBlobParameter = 'Bdny typ parametru Blob';\n  cSIncorrectConnectionURL = 'Bdny URL poczenia: %s';\n  cSUnsupportedProtocol = 'Nieobsugiwany protok: %s';\n  cSUnsupportedByDriver    = 'Sterownik nie obsuguje tej waciwoci natywnie: [%s]';\n\n  cSConnectionIsNotOpened = 'Jeszcze nie nawizano poczenia';\n  cSInvalidOpInAutoCommit = 'Bdna operacja w trybie AutoCommit';\n  cSInvalidOpInNonAutoCommit = 'Bdna operacja przy wyczonym AutoCommit';\n  cSInvalidOpPrepare = 'Przygotowanie transakcji moliwe jest tylko przy pierwszym(!) Starttransaction';\n\n  cSConnectionIsNotAssigned = 'Nie przypisano komponentu poczenia do bazy danych';\n  cSQueryIsEmpty = 'Zapytanie SQL jest puste';\n  cSCanNotExecuteMoreQueries = 'Nie mona wykona wicej ni jednego zapytania';\n  cSOperationIsNotAllowed1 = 'Niedozwolona operacja w trybie FORWARD ONLY';\n  cSOperationIsNotAllowed2 = 'Niedozwolona operacja w trybie READ ONLY';\n  cSOperationIsNotAllowed3 = 'Niedozwolona operacja w trybie %s';\n  cSOperationIsNotAllowed4 = 'Niedozwolona operacja przy zamnitym rdle danych';\n  cSNoMoreRecords = 'Nie ma ju wicej rekordw wynikowych';\n  cSCanNotOpenResultSet = 'Nie mozna otworzy danych wynikowych';\n  cSCanNotOpenDataSetWhenDestroying ='Translate : Cannot open a dataset when the componentstate is dsDestroying';\n  cSCircularLink = 'Datasource tworzy powizanie cykliczne';\n  cSBookmarkWasNotFound = 'Nie znaleziono zakadki (Bookmark)';\n  cSIncorrectSearchFieldsNumber = 'Bdna liczba pl do wyszukiwania';\n  cSInvalidOperationInTrans = 'Bdna operacja w trybie transakcji';\n  cSIncorrectSymbol = 'Bdny symbol w licie pl \"%s\".';\n  cSIncorrectToken = 'Bdny wyraz za \":\"';\n  cSIncorrectParamChar = 'TRANSLATE : Invalid value for ParamChar';\n\n  cSSelectedTransactionIsolation = 'Wybrany poziom izolacji transakcji nie jest obsugiwany';\n  cSDriverNotSupported = 'Nie obsugiwany sterownik %s';\n  cSPattern2Long = 'Wzorzec jest zbyt dugi';\n  cSDriverNotCapableOutParameters = 'Sterownik nie potrafi obsuy parametrw';\n  cSStatementIsNotAllowed = 'Niedozwolone wyraenie';\n  cSStoredProcIsNotAllowed = 'Niedozwolona procedura skadowana';\n  cSCannotPerformOperation = 'Nie mona wykona operacji na zamknitym zbiorze danych';\n  cSInvalidState = 'Bdny stan';\n  cSErrorConvertion = 'Bd konwersji';\n  cSDataTypeDoesNotSupported = 'Nieobsugiwany typ dannych';\n  cSUnsupportedParameterType = 'Nieobsugiwany typ parametru';\n  cSUnsupportedDataType = 'Nieobsugiwany typ danych';\n  cSErrorConvertionField = 'Bd konwersji pola \"%s\" na SQLType \"%s\"';\n  cSBadOCI = 'Za wersja OCI [%s]. Wymagana wersja 8.0.3 lub starsza';\n  cSConnect2AsUser = 'Poczenie z \"%s\" jako uytkownik \"%s\"';\n  cSUnknownError = 'Nieznany bd';\n  cSFieldNotFound1 = 'Nie znaleziono pola \"%s\"';\n  cSFieldNotFound2 = 'Nie znaleziono pola %d';\n\n  cSLoginPromptFailure = 'Nie znaleziono domylnego dialogu logowania. Prosz doda DBLogDlg do sekcji uses gwnego pliku aplikacji.';\n\n  cSPropertyQuery = 'Zapytanie moe chwil potrwa na wikszej bazie danych!';\n  cSPropertyTables = 'Powiniene ucili Katalog i/lub Schemat.';\n  cSPropertyColumns = 'Powiniene ucili Katalog, Schemat i/lub NazwTabeli.';\n  cSPropertyProcedures = 'Powiniene ucili Katalog i/lub Schemat.';\n  cSPropertySequences = 'Powiniene ucili Katalog i/lub Schemat.';\n  cSPropertyExecute = 'Czy mimo to wykona zapytanie?';\n\n  cSFormTest = 'Test Edytora SQL ZEOS';\n  cSButtonClose = '&Zamknij';\n  cSFormEditor = 'Edytor SQL ZEOS';\n  cSTabSheetSelect = 'Wybr SQL';\n  cSMenuLoad = 'aduj';\n  cSMenuSave = 'Zapisz';\n  cSButtonGenerate = '&Generuj';\n  cSButtonCheck = '&Sprawd';\n  cSButtonTest = '&Test';\n  cSButtonOk = '&OK';\n  cSButtonCancel = 'A&nuluj';\n  cSTableAlias = '&Alias tabeli';\n  cSReplaceSQL = 'Za&mie SQL';\n  cSDialogOpenTitle = 'Otwrz plik SQL';\n  cSDialogSaveTitle = 'Zapisz plik SQL';\n  cSSQLEditor = 'Edytor SQL';\n  cSDatabaseDialog = 'Otwrz istniejc baz';\n\n  cSUpdateSQLNoResult = 'Update Refresh SQL nie zwrcio adnych danych';\n  cSUpdateSQLRefreshStatementcount ='Wyraenie Update Refresh SQL musi zwrci 1 rekord danych';\n\n  {$IFDEF FPC}\n  cSNotEditing = 'Dataset nie jest w trybie \"edit\" lub \"insert\"';\n  cSFieldTypeMismatch = 'Niezgodno typw dla pola ''%s'', oczekiwano: %s otrzymano: %s';\n  cSFieldSizeMismatch = 'Niezgodno rozmiarw pola ''%s'', oczekiwano: %d otrzymano: %d';\n  {$ENDIF}\n  cSNeedField               = 'Pole %s jest wymagane.';\n\n  cSFailedtoInitPrepStmt   = 'Nie udao si zainicjalizowa przygotowanego zapytania';\n  cSFailedtoPrepareStmt    = 'Bd w wyraeniu podczas procesu przygotowania';\n  cSFailedToBindAllValues  = 'Bd aplikacji podczas przypisywania danych';\n  cSAttemptExecOnBadPrep   = 'Prba uruchomienia wyraenia przed zakoczeniem przygotowywania.';\n  cSBindingFailure         = 'Bd przypisywania zbioru parametrw';\n  cSPreparedStmtExecFailure = 'Bd wykonania przygotowanego zapytania';\n  cSBoundVarStrIndexMissing = 'Nie istnieje zmienna licznikowa \"%s\"';\n  cSBindVarOutOfRange      = 'Warto zmiennej licznikowej poza zakresem: %d';\n  cSFailedToBindResults    = 'Bd aplikacji podczas czenia do wynikw zapytania';\n\n//FOS+ 07112006\n  cSRefreshRowOnlySupportedWithUpdateObject = 'Metoda refreshrow jest obsugiwana tylko przez obiekt typu \"update\"';\n  cSMustBeInBrowseMode = 'Operacja jest dozwolona tylko w stanie dsBROWSE';\n\n  cSUnKnownParamDataType = 'Nieznany Param.DataType';\n  cSFieldReadOnly        = 'Nie mona przypisa do pola tylko do odczytu wartoci: %d';\n  cSInvalidUpdateCount     = 'Liczba zaktualizowanych rekordw: %d. tylko jeden rekord powinien by zaktualizowany.';\n\n  cSRowBufferWidthExceeded ='Translate: Row buffer width exceeded. Try using fewer or longer columns in SQL query.';\n\n{$ELSE} // default: ENGLISH\n\n\n  cSSQLError1 = 'SQL Error: %s';\n  cSSQLError2 = 'SQL Error: %s Code: %d';\n  cSSQLError3 = 'SQL Error: %s Code: %d SQL: %s';\n  cSSQLError4 = 'SQL Error: %s Code: %d Message: %s';\n\n  cSListCapacityError = 'List capacity out of bounds (%d)';\n  cSListCountError = 'List count out of bounds (%d)';\n  cSListIndexError = 'List index out of bounds (%d)';\n\n  cSClonningIsNotSupported = 'Clonning is not supported by this class';\n  cSImmutableOpIsNotAllowed = 'The operation is not allowed on not changeable collections';\n  cSStackIsEmpty = 'Stack is empty';\n  cSVariableWasNotFound = 'Variable \"%s\" was not found';\n  cSFunctionWasNotFound = 'Function \"%s\" was not found';\n  cSInternalError = 'Internal error';\n  cSSyntaxErrorNear = 'Syntax error near \"%s\"';\n  cSSyntaxError = 'Syntax error';\n  cSUnknownSymbol = 'Unknown symbol \"%s\"';\n  cSUnexpectedExprEnd = 'Unexpected end of expression';\n  cSRightBraceExpected = ') expected';\n  cSParametersError = '%d parameters were expected but %d were found';\n  cSExpectedMoreParams = 'More than two parameters are expected';\n  cSInvalidVarByteArray = 'Invalid VarByte array';\n  cSVariableAlreadyExists = 'Variable \"%s\" already exists';\n  cSTypesMismatch = 'Types mismatch';\n  cSUnsupportedVariantType = 'Unsupported variant type';\n  cSUnsupportedOperation = 'Unsupported operation';\n\n  cSTokenizerIsNotDefined = 'Tokenizer is not defined';\n  cSLibraryNotFound = 'None of the dynamic libraries can be found or is not loadable: %s !'#10#13'Use TZConnection.LibraryLocation if the location is invalid.';\n  cSEncodeDateIsNotSupported = 'This version does not support isc_encode_sql_date';\n  cSEncodeTimeIsNotSupported = 'This version does not support isc_encode_sql_time';\n  cSEncodeTimestampIsNotSupported = 'This version does not support isc_encode_sql_timestamp';\n  cSDecodeDateIsNotSupported = 'This version does not support isc_decode_sql_date';\n  cSDecodeTimeIsNotSupported = 'This version does not support isc_decode_sql_time';\n  cSDecodeTimestampIsNotSupported = 'This version does not support isc_decode_sql_timestamp';\n\n  cSCanNotRetrieveResultSetData = 'Cannot retrieve Resultset data';\n  cSRowBufferIsNotAssigned = 'Row buffer is not assigned';\n  cSColumnIsNotAccessable = 'Column with index %d is not accessable';\n  cSConvertionIsNotPossible = 'Convertion is not possible for column %d from %s to %s';\n  cSCanNotAccessBlobRecord = 'Cannot access blob record in column %d with type %s';\n  cSRowDataIsNotAvailable = 'Row data is not available';\n  cSResolverIsNotSpecified = 'Resolver is not specified for this ResultSet';\n  cSResultsetIsAlreadyOpened = 'Resultset is already open';\n  cSCanNotUpdateEmptyRow = 'Cannot update an empty row';\n  cSCanNotUpdateDeletedRow = 'Cannot update a deleted row';\n  cSCanNotDeleteEmptyRow = 'Cannot delete an empty row';\n  cSCannotUseCommit = 'You cannot use COMMIT in AUTOCOMMIT mode';\n  cSCannotUseRollBack = 'You cannot use ROLLBACK in AUTOCOMMIT mode';\n  cSCanNotUpdateComplexQuery = 'Cannot update a complex query with more then one table';\n  cSCanNotUpdateThisQueryType = 'Cannot update this query type';\n  cSDriverWasNotFound = 'Requested database driver was not found';\n  cSCanNotConnectToServer = 'Cannot connect to SQL server';\n  cSTableIsNotSpecified = 'Table is not specified';\n  cSLiveResultSetsAreNotSupported = 'Live query is not supported by this class';\n  cSInvalidInputParameterCount = 'Input parameter count is less then expected';\n  cSIsolationIsNotSupported = 'Transaction isolation level is not supported';\n  cSColumnWasNotFound = 'Column with name \"%s\" was not found';\n  cSWrongTypeForBlobParameter = 'Wrong type for Blob parameter';\n  cSIncorrectConnectionURL = 'Incorrect connection URL: %s';\n  cSUnsupportedProtocol = 'Unsupported protocol: %s';\n  cSUnsupportedByDriver    = 'Driver can not support this feature natively: [%s]';\n\n  cSConnectionIsNotOpened = 'Connection is not opened yet';\n  cSInvalidOpInAutoCommit = 'Invalid operation in AutoCommit mode';\n  cSInvalidOpInNonAutoCommit = 'Invalid operation in non AutoCommit mode';\n  cSInvalidOpPrepare = 'Prepare transaction only possible on matching first(!) Starttransaction';\n\n  cSConnectionIsNotAssigned = 'Database connection component is not assigned';\n  cSQueryIsEmpty = 'SQL Query is empty';\n  cSCanNotExecuteMoreQueries = 'Cannot execute more then one query';\n  cSOperationIsNotAllowed1 = 'Operation is not allowed in FORWARD ONLY mode';\n  cSOperationIsNotAllowed2 = 'Operation is not allowed in READ ONLY mode';\n  cSOperationIsNotAllowed3 = 'Operation is not allowed in %s mode';\n  cSOperationIsNotAllowed4 = 'Operation is not allowed for closed dataset';\n  cSNoMoreRecords = 'No more records in the Resultset';\n  cSCanNotOpenResultSet = 'Can not open a Resultset';\n  cSCanNotOpenDataSetWhenDestroying ='Cannot open a dataset when the componentstate is dsDestroying';\n  cSCircularLink = 'Datasource makes a circular link';\n  cSBookmarkWasNotFound = 'Bookmark was not found';\n  cSIncorrectSearchFieldsNumber = 'Incorrect number of search field values';\n  cSInvalidOperationInTrans = 'Invalid operation in explicit transaction mode';\n  cSIncorrectSymbol = 'Incorrect symbol in field list \"%s\".';\n  cSIncorrectToken = 'Incorrect token followed by \":\"';\n  cSIncorrectParamChar = 'Invalid value for ParamChar';\n\n  cSSelectedTransactionIsolation = 'Selected transaction isolation level is not supported';\n  cSDriverNotSupported = 'Driver not supported %s';\n  cSPattern2Long = 'Pattern is too long';\n  cSDriverNotCapableOutParameters = 'Driver is not capable to handle parameters';\n  cSStatementIsNotAllowed = 'Statement is not allowed';\n  cSStoredProcIsNotAllowed = 'The stored proc is not allowed';\n  cSCannotPerformOperation = 'Can not perform operation on closed Resultset';\n  cSInvalidState = 'Invalid state';\n  cSErrorConvertion = 'Convertion error';\n  cSDataTypeDoesNotSupported = 'Data type is not supported';\n  cSUnsupportedParameterType = 'Unsupported parameter type';\n  cSUnsupportedDataType = 'Unsupported data type';\n  cSErrorConvertionField = 'Conversion error for field \"%s\" to SQLType \"%s\"';\n  cSBadOCI = 'Bad OCI version [%s]. Version 8.0.3 or older is required';\n  cSConnect2AsUser = 'Connect to \"%s\" as user \"%s\"';\n  cSUnknownError = 'Unknown error';\n  cSFieldNotFound1 = 'Field \"%s\" was not found';\n  cSFieldNotFound2 = 'Field %d was not found';\n\n  cSLoginPromptFailure = 'Can not find default login prompt dialog. Please add DBLogDlg to the uses section of your main file.';\n\n  cSPropertyQuery = 'The Query may last a while on large databases!';\n  cSPropertyTables = 'You should limit it by Catalog and/or Schema.';\n  cSPropertyColumns = 'You should limit it by Catalog, Schema and/or TableName.';\n  cSPropertyProcedures = 'You should limit it by Catalog and/or Schema.';\n  cSPropertySequences = 'You should limit it by Catalog and/or Schema.';\n  cSPropertyExecute = 'Should the Query be executed anyway?';\n\n  cSFormTest = 'ZEOS SQL Editor Test';\n  cSButtonClose = '&Close';\n  cSFormEditor = 'ZEOS SQL Editor';\n  cSTabSheetSelect = 'Select SQL';\n  cSMenuLoad = 'Load';\n  cSMenuSave = 'Save';\n  cSButtonGenerate = '&Generate';\n  cSButtonCheck = 'C&heck';\n  cSButtonTest = '&Test';\n  cSButtonOk = '&OK';\n  cSButtonCancel = '&Cancel';\n  cSTableAlias = 'T&able alias';\n  cSReplaceSQL = '&Replace SQL';\n  cSDialogOpenTitle = 'Open SQL File';\n  cSDialogSaveTitle = 'Save SQL File';\n  cSSQLEditor = 'SQL Editor';\n  cSDatabaseDialog = 'Open existing database';\n\n  cSUpdateSQLNoResult = 'Update Refresh SQL delivered no resultset';\n  cSUpdateSQLRefreshStatementcount ='Update Refresh SQL Statement count must be 1';\n\n  {$IFDEF FPC}\n  cSNotEditing = 'Dataset not in edit or insert mode';\n  cSFieldTypeMismatch = 'Type mismatch for field ''%s'', expecting: %s actual: %s';\n  cSFieldSizeMismatch = 'Size mismatch for field ''%s'', expecting: %d actual: %d';\n  {$ENDIF}\n  cSNeedField               = 'Field %s is required, but not supplied.';\n\n  cSFailedtoInitPrepStmt   = 'Prepared statement failed to initialize';\n  cSFailedtoPrepareStmt    = 'Statement failed during prepare process';\n  cSFailedToBindAllValues  = 'Application failed to pre-bind all values';\n  cSAttemptExecOnBadPrep   = 'Attempt made to execute a statement before a successful preparation.';\n  cSBindingFailure         = 'Failed to bind parameter set';\n  cSPreparedStmtExecFailure = 'Prepared statement failed to execute';\n  cSBoundVarStrIndexMissing = 'Bound variable text index \"%s\" does not exist';\n  cSBindVarOutOfRange      = 'Bound variable index out of range: %d';\n  cSFailedToBindResults    = 'Application failed to bind to the result set';\n\n//FOS+ 07112006\n  cSRefreshRowOnlySupportedWithUpdateObject = 'The refreshrow method is only supported with an update object';\n  cSMustBeInBrowseMode = 'Operation is only allowed in dsBROWSE state';\n\n  cSUnKnownParamDataType = 'Unknown Param.DataType';\n  cSFieldReadOnly        = 'Readonly field can''t be assigned a value: %s';\n  cSInvalidUpdateCount     = '%d record(s) updated. Only one record should have been updated.';\n\n  cSRowBufferWidthExceeded ='Row buffer width exceeded. Try using fewer or longer columns in SQL query.';\n\n{$ENDIF} // POLISH\n\n{$ENDIF} // CZECH\n\n{$ENDIF} // RUSSIAN\n\n{$ENDIF}   // INDONESIAN <--- added by tohenk\n\n{$ENDIF}   // ROMANA\n\n{$ENDIF} //SPANISH\n\n{$ENDIF} // GERMAN\n\n{$ENDIF} // DUTCH\n\n{$ENDIF} // PORTUGUESE\n\n{$ENDIF FRENCH}\n\nvar\n  SSQLError1: String;\n  SSQLError2: String;\n  SSQLError3: String;\n  SSQLError4: String;\n\n  SListCapacityError: String;\n  SListCountError: String;\n  SListIndexError: String;\n\n  SClonningIsNotSupported: String;\n  SImmutableOpIsNotAllowed: String;\n  SStackIsEmpty: String;\n  SVariableWasNotFound: String;\n  SFunctionWasNotFound: String;\n  SInternalError: String;\n  SSyntaxErrorNear: String;\n  SSyntaxError: String;\n  SUnknownSymbol: String;\n  SUnexpectedExprEnd: String;\n  SRightBraceExpected: String;\n  SParametersError: String;\n  SExpectedMoreParams: String;\n  SInvalidVarByteArray: String;\n  SVariableAlreadyExists: String;\n  STypesMismatch: String;\n  SUnsupportedVariantType: String;\n  SUnsupportedOperation: String;\n\n  STokenizerIsNotDefined: String;\n  SLibraryNotFound: String;\n  SLibraryNotCompatible: String;\n  SEncodeDateIsNotSupported: String;\n  SEncodeTimeIsNotSupported: String;\n  SEncodeTimestampIsNotSupported: String;\n  SDecodeDateIsNotSupported: String;\n  SDecodeTimeIsNotSupported: String;\n  SDecodeTimestampIsNotSupported: String;\n\n  SCanNotRetrieveResultSetData: String;\n  SRowBufferIsNotAssigned: String;\n  SColumnIsNotAccessable: String;\n  SConvertionIsNotPossible: String;\n  SCanNotAccessBlobRecord: String;\n  SRowDataIsNotAvailable: String;\n  SResolverIsNotSpecified: String;\n  SResultsetIsAlreadyOpened: String;\n  SCanNotUpdateEmptyRow: String;\n  SCanNotUpdateDeletedRow: String;\n  SCanNotDeleteEmptyRow: String;\n  SCannotUseCommit: String;\n  SCannotUseRollBack: String;\n  SCanNotUpdateComplexQuery: String;\n  SCanNotUpdateThisQueryType: String;\n  SDriverWasNotFound: String;\n  SCanNotConnectToServer: String;\n  STableIsNotSpecified: String;\n  SLiveResultSetsAreNotSupported: String;\n  SInvalidInputParameterCount: String;\n  SIsolationIsNotSupported: String;\n  SColumnWasNotFound: String;\n  SWrongTypeForBlobParameter: String;\n  SIncorrectConnectionURL: String;\n  SUnsupportedProtocol: String;\n  SUnsupportedByDriver   : String;\n\n  SConnectionIsNotOpened: String;\n  SInvalidOpInAutoCommit: String;\n  SInvalidOpInNonAutoCommit: String;\n  SInvalidOpPrepare: String;\n\n  SConnectionIsNotAssigned: String;\n  SQueryIsEmpty: String;\n  SCanNotExecuteMoreQueries: String;\n  SOperationIsNotAllowed1: String;\n  SOperationIsNotAllowed2: String;\n  SOperationIsNotAllowed3: String;\n  SOperationIsNotAllowed4: String;\n  SNoMoreRecords: String;\n  SCanNotOpenResultSet: String;\n  SCanNotOpenDataSetWhenDestroying: String;\n  SCircularLink: String;\n  SBookmarkWasNotFound: String;\n  SIncorrectSearchFieldsNumber: String;\n  SInvalidOperationInTrans: String;\n  SIncorrectSymbol: String;\n  SIncorrectToken: String;\n  SIncorrectParamChar: String;\n\n  SSelectedTransactionIsolation: String;\n  SDriverNotSupported: String;\n  SPattern2Long: String;\n  SDriverNotCapableOutParameters: String;\n  SStatementIsNotAllowed: String;\n  SStoredProcIsNotAllowed: String;\n  SCannotPerformOperation: String;\n  SInvalidState: String;\n  SErrorConvertion: String;\n  SDataTypeDoesNotSupported: String;\n  SUnsupportedParameterType: String;\n  SUnsupportedDataType: String;\n  SErrorConvertionField: String;\n  SBadOCI: String;\n  SConnect2AsUser: String;\n  SUnknownError: String;\n  SFieldNotFound1: String;\n  SFieldNotFound2: String;\n\n  SLoginPromptFailure: String;\n\n  SPropertyQuery: String;\n  SPropertyTables: String;\n  SPropertyColumns: String;\n  SPropertyProcedures: String;\n  SPropertySequences: String;\n  SPropertyExecute: String;\n\n  SFormTest: String;\n  SButtonClose: String;\n  SFormEditor: String;\n  STabSheetSelect: String;\n  SMenuLoad: String;\n  SMenuSave: String;\n  SButtonGenerate: String;\n  SButtonCheck: String;\n  SButtonTest: String;\n  SButtonOk: String;\n  SButtonCancel: String;\n  STableAlias: String;\n  SReplaceSQL: String;\n  SDialogOpenTitle: String;\n  SDialogSaveTitle: String;\n  SSQLEditor: String;\n  SDatabaseDialog: String;\n\n  SUpdateSQLNoResult: String;\n  SUpdateSQLRefreshStatementcount: String;\n  {$IFDEF FPC}\n  SNotEditing: String;\n  SFieldTypeMismatch: String;\n  SFieldSizeMismatch: String;\n  {$ENDIF}\n  SNeedField: String;\n\n  SFailedtoInitPrepStmt: String;\n  SFailedtoPrepareStmt: String;\n  SFailedToBindAllValues: String;\n  SAttemptExecOnBadPrep: String;\n  SBindingFailure: String;\n  SPreparedStmtExecFailure: String;\n  SBoundVarStrIndexMissing: String;\n  SBindVarOutOfRange: String;\n  SFailedToBindResults: String;\n\n\n  SRefreshRowOnlySupportedWithUpdateObject: String;\n  SMustBeInBrowseMode: String;\n\n  SUnKnownParamDataType: String;\n  SFieldReadOnly: String;\n  SInvalidUpdateCount: String;\n\n  SRowBufferWidthExceeded: String;\n\nimplementation\n\nprocedure loadmessages();\nbegin\n  SSQLError1 := cSSQLError1;\n  SSQLError2 := cSSQLError2;\n  SSQLError3 := cSSQLError3;\n  SSQLError4 := cSSQLError4;\n\n  SListCapacityError := cSListCapacityError;\n  SListCountError := cSListCountError;\n  SListIndexError := cSListIndexError;\n\n  SClonningIsNotSupported := cSClonningIsNotSupported;\n  SImmutableOpIsNotAllowed := cSImmutableOpIsNotAllowed;\n  SStackIsEmpty := cSStackIsEmpty;\n  SVariableWasNotFound := cSVariableWasNotFound;\n  SFunctionWasNotFound := cSFunctionWasNotFound;\n  SInternalError := cSInternalError;\n  SSyntaxErrorNear := cSSyntaxErrorNear;\n  SSyntaxError := cSSyntaxError;\n  SUnknownSymbol := cSUnknownSymbol;\n  SUnexpectedExprEnd := cSUnexpectedExprEnd;\n  SRightBraceExpected := cSRightBraceExpected;\n  SParametersError := cSParametersError;\n  SExpectedMoreParams := cSExpectedMoreParams;\n  SInvalidVarByteArray := cSInvalidVarByteArray;\n  SVariableAlreadyExists := cSVariableAlreadyExists;\n  STypesMismatch := cSTypesMismatch;\n  SUnsupportedVariantType := cSUnsupportedVariantType;\n  SUnsupportedOperation := cSUnsupportedOperation;\n\n  STokenizerIsNotDefined := cSTokenizerIsNotDefined;\n  SLibraryNotFound := cSLibraryNotFound;\n  SLibraryNotCompatible := cSLibraryNotCompatible;\n  SEncodeDateIsNotSupported := cSEncodeDateIsNotSupported;\n  SEncodeTimeIsNotSupported := cSEncodeTimeIsNotSupported;\n  SEncodeTimestampIsNotSupported := cSEncodeTimestampIsNotSupported;\n  SDecodeDateIsNotSupported := cSDecodeDateIsNotSupported;\n  SDecodeTimeIsNotSupported := cSDecodeTimeIsNotSupported;\n  SDecodeTimestampIsNotSupported := cSDecodeTimestampIsNotSupported;\n\n  SCanNotRetrieveResultSetData := cSCanNotRetrieveResultSetData;\n  SRowBufferIsNotAssigned := cSRowBufferIsNotAssigned;\n  SColumnIsNotAccessable := cSColumnIsNotAccessable;\n  SConvertionIsNotPossible := cSConvertionIsNotPossible;\n  SCanNotAccessBlobRecord := cSCanNotAccessBlobRecord;\n  SRowDataIsNotAvailable := cSRowDataIsNotAvailable;\n  SResolverIsNotSpecified := cSResolverIsNotSpecified;\n  SResultsetIsAlreadyOpened := cSResultsetIsAlreadyOpened;\n  SCanNotUpdateEmptyRow := cSCanNotUpdateEmptyRow;\n  SCanNotUpdateDeletedRow := cSCanNotUpdateDeletedRow;\n  SCanNotDeleteEmptyRow := cSCanNotDeleteEmptyRow;\n  SCannotUseCommit := cSCannotUseCommit;\n  SCannotUseRollBack := cSCannotUseRollBack;\n  SCanNotUpdateComplexQuery := cSCanNotUpdateComplexQuery;\n  SCanNotUpdateThisQueryType := cSCanNotUpdateThisQueryType;\n  SDriverWasNotFound := cSDriverWasNotFound;\n  SCanNotConnectToServer := cSCanNotConnectToServer;\n  STableIsNotSpecified := cSTableIsNotSpecified;\n  SLiveResultSetsAreNotSupported := cSLiveResultSetsAreNotSupported;\n  SInvalidInputParameterCount := cSInvalidInputParameterCount;\n  SIsolationIsNotSupported := cSIsolationIsNotSupported;\n  SColumnWasNotFound := cSColumnWasNotFound;\n  SWrongTypeForBlobParameter := cSWrongTypeForBlobParameter;\n  SIncorrectConnectionURL := cSIncorrectConnectionURL;\n  SUnsupportedProtocol := cSUnsupportedProtocol;\n  SUnsupportedByDriver := cSUnsupportedByDriver;\n\n  SConnectionIsNotOpened := cSConnectionIsNotOpened;\n  SInvalidOpInAutoCommit := cSInvalidOpInAutoCommit;\n  SInvalidOpInNonAutoCommit := cSInvalidOpInNonAutoCommit;\n  SInvalidOpPrepare := cSInvalidOpPrepare;\n\n  SConnectionIsNotAssigned := cSConnectionIsNotAssigned;\n  SQueryIsEmpty := cSQueryIsEmpty;\n  SCanNotExecuteMoreQueries := cSCanNotExecuteMoreQueries;\n  SOperationIsNotAllowed1 := cSOperationIsNotAllowed1;\n  SOperationIsNotAllowed2 := cSOperationIsNotAllowed2;\n  SOperationIsNotAllowed3 := cSOperationIsNotAllowed3;\n  SOperationIsNotAllowed4 := cSOperationIsNotAllowed4;\n  SNoMoreRecords := cSNoMoreRecords;\n  SCanNotOpenResultSet := cSCanNotOpenResultSet;\n  SCanNotOpenDataSetWhenDestroying := cSCanNotOpenDataSetWhenDestroying;\n  SCircularLink := cSCircularLink;\n  SBookmarkWasNotFound := cSBookmarkWasNotFound;\n  SIncorrectSearchFieldsNumber := cSIncorrectSearchFieldsNumber;\n  SInvalidOperationInTrans := cSInvalidOperationInTrans;\n  SIncorrectSymbol := cSIncorrectSymbol;\n  SIncorrectToken := cSIncorrectToken;\n  SIncorrectParamChar := cSIncorrectParamChar;\n\n  SSelectedTransactionIsolation := cSSelectedTransactionIsolation;\n  SDriverNotSupported := cSDriverNotSupported;\n  SPattern2Long := cSPattern2Long;\n  SDriverNotCapableOutParameters := cSDriverNotCapableOutParameters;\n  SStatementIsNotAllowed := cSStatementIsNotAllowed;\n  SStoredProcIsNotAllowed := cSStoredProcIsNotAllowed;\n  SCannotPerformOperation := cSCannotPerformOperation;\n  SInvalidState := cSInvalidState;\n  SErrorConvertion := cSErrorConvertion;\n  SDataTypeDoesNotSupported := cSDataTypeDoesNotSupported;\n  SUnsupportedParameterType := cSUnsupportedParameterType;\n  SUnsupportedDataType := cSUnsupportedDataType;\n  SErrorConvertionField := cSErrorConvertionField;\n  SBadOCI := cSBadOCI;\n  SConnect2AsUser := cSConnect2AsUser;\n  SUnknownError := cSUnknownError;\n  SFieldNotFound1 := cSFieldNotFound1;\n  SFieldNotFound2 := cSFieldNotFound2;\n\n  SLoginPromptFailure := cSLoginPromptFailure;\n\n  SPropertyQuery := cSPropertyQuery;\n  SPropertyTables := cSPropertyTables;\n  SPropertyColumns := cSPropertyColumns;\n  SPropertyProcedures := cSPropertyProcedures;\n  SPropertySequences := cSPropertySequences;\n  SPropertyExecute := cSPropertyExecute;\n\n  SFormTest := cSFormTest;\n  SButtonClose := cSButtonClose;\n  SFormEditor := cSFormEditor;\n  STabSheetSelect := cSTabSheetSelect;\n  SMenuLoad := cSMenuLoad;\n  SMenuSave := cSMenuSave;\n  SButtonGenerate := cSButtonGenerate;\n  SButtonCheck := cSButtonCheck;\n  SButtonTest := cSButtonTest;\n  SButtonOk := cSButtonOk;\n  SButtonCancel := cSButtonCancel;\n  STableAlias := cSTableAlias;\n  SReplaceSQL := cSReplaceSQL;\n  SDialogOpenTitle := cSDialogOpenTitle;\n  SDialogSaveTitle := cSDialogSaveTitle;\n  SSQLEditor := cSSQLEditor;\n  SDatabaseDialog := cSDatabaseDialog;\n\n  SUpdateSQLNoResult := cSUpdateSQLNoResult;\n  SUpdateSQLRefreshStatementcount := cSUpdateSQLRefreshStatementcount;\n  {$IFDEF FPC}\n  SNotEditing := cSNotEditing;\n  SFieldTypeMismatch := cSFieldTypeMismatch;\n  SFieldSizeMismatch := cSFieldSizeMismatch;\n  {$ENDIF}\n  SNeedField := cSNeedField;\n\n  SFailedtoInitPrepStmt := cSFailedtoInitPrepStmt;\n  SFailedtoPrepareStmt := cSFailedtoPrepareStmt;\n  SFailedToBindAllValues := cSFailedToBindAllValues;\n  SAttemptExecOnBadPrep := cSAttemptExecOnBadPrep;\n  SBindingFailure := cSBindingFailure;\n  SPreparedStmtExecFailure := cSPreparedStmtExecFailure;\n  SBoundVarStrIndexMissing := cSBoundVarStrIndexMissing;\n  SBindVarOutOfRange := cSBindVarOutOfRange;\n  SFailedToBindResults := cSFailedToBindResults;\n\n\n  SRefreshRowOnlySupportedWithUpdateObject := cSRefreshRowOnlySupportedWithUpdateObject;\n  SMustBeInBrowseMode := cSMustBeInBrowseMode;\n\n  SUnKnownParamDataType := cSUnKnownParamDataType;\n  SFieldReadOnly := cSFieldReadOnly;\n  SInvalidUpdateCount := cSInvalidUpdateCount;\n\n  SRowBufferWidthExceeded := cSRowBufferWidthExceeded;\nend;\n\ninitialization\n  loadmessages;\nend.\n\n\n\n\n"
  },
  {
    "path": "lib/zeosdbo/src/core/ZSysUtils.pas",
    "content": "{*********************************************************}\n{                                                         }\n{                 Zeos Database Objects                   }\n{           System Utility Classes and Functions          }\n{                                                         }\n{          Originally written by Sergey Seroukhov         }\n{                                                         }\n{*********************************************************}\n\n{@********************************************************}\n{    Copyright (c) 1999-2012 Zeos Development Group       }\n{                                                         }\n{ License Agreement:                                      }\n{                                                         }\n{ This library is distributed in the hope that it will be }\n{ useful, but WITHOUT ANY WARRANTY; without even the      }\n{ implied warranty of MERCHANTABILITY or FITNESS FOR      }\n{ A PARTICULAR PURPOSE.  See the GNU Lesser General       }\n{ Public License for more details.                        }\n{                                                         }\n{ The source code of the ZEOS Libraries and packages are  }\n{ distributed under the Library GNU General Public        }\n{ License (see the file COPYING / COPYING.ZEOS)           }\n{ with the following  modification:                       }\n{ As a special exception, the copyright holders of this   }\n{ library give you permission to link this library with   }\n{ independent modules to produce an executable,           }\n{ regardless of the license terms of these independent    }\n{ modules, and to copy and distribute the resulting       }\n{ executable under terms of your choice, provided that    }\n{ you also meet, for each linked independent module,      }\n{ the terms and conditions of the license of that module. }\n{ An independent module is a module which is not derived  }\n{ from or based on this library. If you modify this       }\n{ library, you may extend this exception to your version  }\n{ of the library, but you are not obligated to do so.     }\n{ If you do not wish to do so, delete this exception      }\n{ statement from your version.                            }\n{                                                         }\n{                                                         }\n{ The project web site is located on:                     }\n{   http://zeos.firmos.at  (FORUM)                        }\n{   http://sourceforge.net/p/zeoslib/tickets/ (BUGTRACKER)}\n{   svn://svn.code.sf.net/p/zeoslib/code-0/trunk (SVN)    }\n{                                                         }\n{   http://www.sourceforge.net/projects/zeoslib.          }\n{                                                         }\n{                                                         }\n{                                 Zeos Development Group. }\n{********************************************************@}\n\nunit ZSysUtils;\n\ninterface\n\n{$I ZCore.inc}\n\nuses\n  Variants, Classes, {$IFDEF MSEgui}mclasses,{$ENDIF} SysUtils, Types,\n  ZMessages, ZCompatibility;\n\ntype\n  {** Modified comaprison function. }\n  TZListSortCompare = function (Item1, Item2: Pointer): Integer of object;\n\n  {** Modified list of pointers. }\n  TZSortedList = class (TList)\n  protected\n    procedure QuickSort(SortList: PPointerList; L, R: Integer;\n      SCompare: TZListSortCompare);\n  public\n    procedure Sort(Compare: TZListSortCompare);\n  end;\n\n{**\n  Determines a position of a first delimiter.\n  @param Delimiters a string with possible delimiters.\n  @param Str a string to be checked.\n  @return a position of the first found delimiter or 0 if no delimiters was found.\n}\nfunction FirstDelimiter(const Delimiters, Str: string): Integer;\n\n{**\n  Determines a position of a LAST delimiter.\n  @param Delimiters a string with possible delimiters.\n  @param Str a string to be checked.\n  @return a position of the last found delimiter or 0 if no delimiters was found.\n}\nfunction LastDelimiter(const Delimiters, Str: string): Integer;\n\n{**\n  Compares two PWideChars without stopping at #0 (Unicode Version)\n  @param P1 first PWideChars\n  @param P2 seconds PWideChars\n  @return <code>True</code> if the memory at P1 and P2 are equal\n}\nfunction MemLCompUnicode(P1, P2: PWideChar; Len: Integer): Boolean;\n\n{**\n  Compares two PAnsiChars without stopping at #0\n  @param P1 first PAnsiChar\n  @param P2 seconds PAnsiChar\n  @return <code>True</code> if the memory at P1 and P2 are equal\n}\nfunction MemLCompAnsi(P1, P2: PAnsiChar; Len: Integer): Boolean;\n\n{**\n  Checks is the string starts with substring.\n  @param Str a string to be checked.\n  @param SubStr a string to test at the start of the Str.\n  @return <code>True</code> if Str started with SubStr;\n}\nfunction StartsWith(const Str, SubStr: ZWideString): Boolean; overload;\nfunction StartsWith(const Str, SubStr: RawByteString): Boolean; overload;\n{**\n  Checks is the string ends with substring.\n  @param Str a string to be checked.\n  @param SubStr a string to test at the end of the Str.\n  @return <code>True</code> if Str ended with SubStr;\n}\nfunction EndsWith(const Str, SubStr: ZWideString): Boolean; overload;\nfunction EndsWith(const Str, SubStr: RawByteString): Boolean; overload;\n\n{**\n  Converts SQL string into float value.\n  @param Str an SQL string with comma delimiter.\n  @param Def a default value if the string can not be converted.\n  @return a converted value or Def if conversion was failt.\n}\n{$IFDEF WITH_RAWBYTESTRING}\nfunction SQLStrToFloatDef(Str: RawByteString; Def: Extended): Extended; overload;\n{$ENDIF}\nfunction SQLStrToFloatDef(Str: String; Def: Extended): Extended; overload;\n\n{**\n  Converts SQL string into float value.\n  @param Str an SQL string with comma delimiter.\n  @return a converted value or Def if conversion was failt.\n}\nfunction SQLStrToFloat(const Str: AnsiString): Extended;\n\n{**\n  Converts a character buffer into pascal string.\n  @param Buffer a character buffer pointer.\n  @param Length a buffer length.\n  @return a string retrived from the buffer.\n}\nfunction BufferToStr(Buffer: PWideChar; Length: LongInt): string; overload;\nfunction BufferToStr(Buffer: PAnsiChar; Length: LongInt): string; overload;\nfunction BufferToBytes(Buffer: Pointer; Length: LongInt): TByteDynArray;\n\n{**\n  Converts a string into boolean value.\n  @param Str a string value.\n  @return <code>True</code> is Str = 'Y'/'YES'/'T'/'TRUE'/<>0\n}\nfunction StrToBoolEx(Str: string): Boolean;\n\n{**\n  Converts a boolean into string value.\n  @param Bool a boolean value.\n  @return <code>\"True\"</code> or <code>\"False\"</code>\n}\nfunction BoolToStrEx(Bool: Boolean): String;\n\n{**\n  Checks if the specified string can represent an IP address.\n  @param Str a string value.\n  @return <code>True</code> if the string can represent an IP address\n    or <code>False</code> otherwise.\n}\nfunction IsIpAddr(const Str: string): Boolean;\n\n{**\n  Splits string using the multiple chars.\n  @param Str the source string\n  @param Delimiters the delimiters string\n  @return the result list where plased delimited string\n}\nfunction SplitString(const Str, Delimiters: string): TStrings;\n\n{**\n  Puts to list a splitted string using the multiple chars which replaces\n  the previous list content.\n  @param List a list with strings.\n  @param Str the source string\n  @param Delimiters the delimiters string\n}\nprocedure PutSplitString(List: TStrings; const Str, Delimiters: string);\n\n{**\n  Appends to list a splitted string using the multiple chars.\n  @param List a list with strings.\n  @param Str the source string\n  @param Delimiters the delimiters string\n}\nprocedure AppendSplitString(List: TStrings; const Str, Delimiters: string);\n\n{**\n  Composes a string from the specified strings list delimited with\n  a special character.\n  @param List a list of strings.\n  @param Delimiter a delimiter string.\n  @return a composed string from the list.\n}\nfunction ComposeString(List: TStrings; const Delimiter: string): string;\n\n{**\n  Converts a float value into SQL string with '.' delimiter.\n  @param Value a float value to be converted.\n  @return a converted string value.\n}\nfunction FloatToSQLStr(Value: Extended): string;\n\n{**\n  Puts to list a splitted string using the delimiter string which replaces\n  the previous list content.\n  @param List a list with strings.\n  @param Str the source string\n  @param Delimiters the delimiter string\n}\nprocedure PutSplitStringEx(List: TStrings; const Str, Delimiter: string);\n\n{**\n  Splits string using the delimiter string.\n  @param Str the source string\n  @param Delimiters the delimiter string\n  @return the result list where plased delimited string\n}\nfunction SplitStringEx(const Str, Delimiter: string): TStrings;\n\n{**\n  Appends to list a splitted string using the delimeter string.\n  @param List a list with strings.\n  @param Str the source string\n  @param Delimiters the delimiters string\n}\nprocedure AppendSplitStringEx(List: TStrings; const Str, Delimiter: string);\n\n{**\n  Converts bytes into a AnsiString representation.\n  @param Value an array of bytes to be converted.\n  @return a converted AnsiString.\n}\nfunction BytesToStr(const Value: TByteDynArray): AnsiString;\n\n{**\n  Converts AnsiString into an array of bytes.\n  @param Value a AnsiString to be converted.\n  @return a converted array of bytes.\n}\nfunction StrToBytes(const Value: AnsiString): TByteDynArray; overload;\n\n{$IFDEF WITH_RAWBYTESTRING}\n{**\n  Converts a UTF8String into an array of bytes.\n  @param Value a UTF8String to be converted.\n  @return a converted array of bytes.\n}\nfunction StrToBytes(const Value: UTF8String): TByteDynArray; overload;\n{**\n  Converts a UTF8String into an array of bytes.\n  @param Value a UTF8String to be converted.\n  @return a converted array of bytes.\n}\nfunction StrToBytes(const Value: RawByteString): TByteDynArray; overload;\n{**\n  Converts a RawByteString into an array of bytes.\n  @param Value a RawByteString to be converted.\n  @return a converted array of bytes.\n}\n{$ENDIF}\nfunction StrToBytes(const Value: WideString): TByteDynArray; overload;\n{**\n  Converts a String into an array of bytes.\n  @param Value a String to be converted.\n  @return a converted array of bytes.\n}\n{$IFDEF PWIDECHAR_IS_PUNICODECHAR}\nfunction StrToBytes(const Value: UnicodeString): TByteDynArray; overload;\n{$ENDIF}\n{**\n  Converts bytes into a variant representation.\n  @param Value an array of bytes to be converted.\n  @return a converted variant.\n}\nfunction BytesToVar(const Value: TByteDynArray): Variant;\n\n{**\n  Converts variant into an array of bytes.\n  @param Value a varaint to be converted.\n  @return a converted array of bytes.\n}\nfunction VarToBytes(const Value: Variant): TByteDynArray;\n\n{**\n  Converts Ansi SQL Date/Time to TDateTime\n  @param Value a date and time string.\n  @return a decoded TDateTime value.\n}\nfunction AnsiSQLDateToDateTime(const Value: string): TDateTime;\n\n{**\n  Converts Timestamp String to TDateTime\n  @param Value a timestamp string.\n  @return a decoded TDateTime value.\n}\nfunction TimestampStrToDateTime(const Value: string): TDateTime;\n\n{**\n  Converts TDateTime to Ansi SQL Date/Time\n  @param Value an encoded TDateTime value.\n  @return a  date and time string.\n}\nfunction DateTimeToAnsiSQLDate(Value: TDateTime; WithMMSec: Boolean = False): string;\n\n{**\n  Converts an string into escape PostgreSQL format.\n  @param Value a regular string.\n  @return a string in PostgreSQL escape format.\n}\nfunction EncodeCString(const Value: string): string;\n\n{**\n  Converts an string from escape PostgreSQL format.\n  @param Value a string in PostgreSQL escape format.\n  @return a regular string.\n}\nfunction DecodeCString(const Value: string): string;\n\n{**\n  Replace chars in the string\n  @param Source a char to search.\n  @param Target a char to replace.\n  @param Str a source string.\n  @return a string with replaced chars.\n}\nfunction ReplaceChar(const Source, Target: Char; const Str: string): string;\n\n{**\n   Copy buffer to the pascal string\n   @param Buffer a buffer with data\n   @param Length a buffer length\n   @return a buffer content\n}\nfunction MemPas(Buffer: PChar; Length: LongInt): string;\n\n{**\n  Decodes a Full Version Value encoded with the format:\n   (major_version * 1,000,000) + (minor_version * 1,000) + sub_version\n  into separated major, minor and subversion values\n  @param FullVersion an integer containing the Full Version to decode.\n  @param MajorVersion an integer containing the Major Version decoded.\n  @param MinorVersion an integer containing the Minor Version decoded.\n  @param SubVersion an integer contaning the Sub Version (revision) decoded.\n}\nprocedure DecodeSQLVersioning(const FullVersion: Integer;\n out MajorVersion: Integer; out MinorVersion: Integer;\n out SubVersion: Integer);\n\n{**\n  Encodes major, minor and subversion (revision) values in this format:\n   (major_version * 1,000,000) + (minor_version * 1,000) + sub_version\n  For example, 4.1.12 is returned as 4001012.\n  @param MajorVersion an integer containing the Major Version.\n  @param MinorVersion an integer containing the Minor Version.\n  @param SubVersion an integer containing the Sub Version (revision).\n  @return an integer containing the full version.\n}\nfunction EncodeSQLVersioning(const MajorVersion: Integer;\n const MinorVersion: Integer; const SubVersion: Integer): Integer;\n\n{**\n  Formats a Zeos SQL Version format to X.Y.Z where:\n   X = major_version\n   Y = minor_version\n   Z = sub version\n  @param SQLVersion an integer\n  @return Formated Zeos SQL Version Value.\n}\nfunction FormatSQLVersion( const SQLVersion: Integer ): String;\n\n{**\n  Arranges thousand and decimal separator to a System-defaults\n  @param the value which has to be converted and arranged\n  @return a valid floating value\n}\nfunction ZStrToFloat(Value: PAnsiChar): Extended; overload;\n\n{**\n  Arranges thousand and decimal separator to a System-defaults\n  @param the value which has to be converted and arranged\n  @return a valid floating value\n}\nfunction ZStrToFloat(Value: AnsiString): Extended; overload;\n\nprocedure ZSetString(const Src: PAnsiChar; var Dest: AnsiString); overload;\nprocedure ZSetString(const Src: PAnsiChar; const Len: Cardinal; var Dest: AnsiString); overload;\nprocedure ZSetString(const Src: PAnsiChar; var Dest: UTF8String); overload;\nprocedure ZSetString(const Src: PAnsiChar; const Len: Cardinal; var Dest: UTF8String); overload;\nprocedure ZSetString(const Src: PAnsiChar; const Len: Cardinal; var Dest: ZWideString); overload;\n{$IFDEF WITH_RAWBYTESTRING}\nprocedure ZSetString(const Src: PAnsiChar; var Dest: RawByteString); overload;\nprocedure ZSetString(const Src: PAnsiChar; const Len: Cardinal; var Dest: RawByteString); overload;\n{$ENDIF}\n\nimplementation\n\nuses ZMatchPattern, StrUtils {$IFDEF WITH_UNITANSISTRINGS}, AnsiStrings{$ENDIF};\n\n{**\n  Determines a position of a first delimiter.\n  @param Delimiters a string with possible delimiters.\n  @param Str a string to be checked.\n  @return a position of the first found delimiter or 0 if no delimiters was found.\n}\nfunction FirstDelimiter(const Delimiters, Str: string): Integer;\nvar\n  I, Index: Integer;\nbegin\n  Result := 0;\n  for I := 1 to Length(Delimiters) do\n  begin\n    Index := Pos(Delimiters[I], Str);\n    if (Index > 0) and ((Index < Result) or (Result = 0)) then\n      Result := Index;\n  end;\nend;\n\n{**\n  Determines a position of a LAST delimiter.\n  @param Delimiters a string with possible delimiters.\n  @param Str a string to be checked.\n  @return a position of the last found delimiter or 0 if no delimiters was found.\n}\nfunction LastDelimiter(const Delimiters, Str: string): Integer;\nvar\n  I, Index: Integer;\nbegin\n  Result := 0;\n  for I := Length(Str) downto 1 do\n  begin\n    Index := Pos(Str[I], Delimiters);\n    if (Index > 0) then\n    begin\n      Result := I;\n      Break;\n    end;\n  end;\nend;\n\n\n{**\n  Compares two PWideChars without stopping at #0 (Unicode Version)\n  @param P1 first PWideChar\n  @param P2 seconds PWideChar\n  @return <code>True</code> if the memory at P1 and P2 are equal\n}\nfunction MemLCompUnicode(P1, P2: PWideChar; Len: Integer): Boolean;\nbegin\n  while (Len > 0) and (P1^ = P2^) do\n  begin\n    Inc(P1);\n    Inc(P2);\n    Dec(Len);\n  end;\n  Result := Len = 0;\nend;\n\n{**\n  Compares two PAnsiChars without stopping at #0\n  @param P1 first PAnsiChar\n  @param P2 seconds PAnsiChar\n  @return <code>True</code> if the memory at P1 and P2 are equal\n}\nfunction MemLCompAnsi(P1, P2: PAnsiChar; Len: Integer): Boolean;\nbegin\n  while (Len > 0) and (P1^ = P2^) do\n  begin\n    Inc(P1);\n    Inc(P2);\n    Dec(Len);\n  end;\n  Result := Len = 0;\nend;\n\n{**\n  Checks is the string starts with substring.\n  @param Str a string to be checked.\n  @param SubStr a string to test at the start of the Str.\n  @return <code>True</code> if Str started with SubStr;\n}\nfunction StartsWith(const Str, SubStr: ZWideString): Boolean;\nvar\n  LenSubStr: Integer;\nbegin\n  LenSubStr := Length(SubStr);\n  if SubStr = '' then\n    Result := True\n  else if LenSubStr <= Length(Str) then\n    Result := MemLCompUnicode(PWideChar(Str), PWideChar(SubStr), LenSubStr)\n  else\n    Result := False;\nend;\n\nfunction StartsWith(const Str, SubStr: RawByteString): Boolean; overload;\nvar\n  LenSubStr: Integer;\nbegin\n  LenSubStr := Length(SubStr);\n  if SubStr = '' then\n    Result := True\n   else\n    if LenSubStr <= Length(Str) then\n      Result := MemLCompAnsi(PAnsiChar(Str), PAnsiChar(SubStr), LenSubStr)\n    else\n      Result := False;\nend;\n\n{**\n  Checks is the string ends with substring.\n  @param Str a string to be checked.\n  @param SubStr a string to test at the end of the Str.\n  @return <code>True</code> if Str ended with SubStr;\n}\nfunction EndsWith(const Str, SubStr: ZWideString): Boolean;\nvar\n  LenSubStr: Integer;\n  LenStr: Integer;\nbegin\n  if SubStr = '' then\n    Result := False // act like Delphi's AnsiEndsStr()\n  else\n  begin\n    LenSubStr := Length(SubStr);\n    LenStr := Length(Str);\n    if LenSubStr <= LenStr then\n      Result := MemLCompUnicode(PWideChar(Pointer(Str)) + LenStr - LenSubStr,\n         Pointer(SubStr), LenSubStr)\n    else\n      Result := False;\n  end;\nend;\n\nfunction EndsWith(const Str, SubStr: RawByteString): Boolean;\nvar\n  LenSubStr: Integer;\n  LenStr: Integer;\nbegin\n  if SubStr = '' then\n    Result := False // act like Delphi's AnsiEndsStr()\n  else\n  begin\n    LenSubStr := Length(SubStr);\n    LenStr := Length(Str);\n    if LenSubStr <= LenStr then\n      Result := MemLCompAnsi(PAnsiChar(Pointer(Str)) + LenStr - LenSubStr,\n         Pointer(SubStr), LenSubStr)\n    else\n      Result := False;\n  end;\nend;\n\nfunction ConvertMoneyToFloat(MoneyString: String): String;\nvar\n  I: Integer;\nbegin\n  if MoneyString = '' then\n    Result := ''\n  else\n  begin\n    if CharInSet(Char(MoneyString[1]), ['0'..'9', '-']) then\n      Result := MoneyString\n    else\n      for i := 1 to Length(MoneyString) do\n        if CharInSet(Char(MoneyString[I]), ['0'..'9', '-']) then\n        begin\n          if I > 1 then\n          begin //Money type\n            Result := Copy(MoneyString, I, Length(MoneyString)-i+1);\n            if Pos(',', Result) > 0 then\n              if Pos('.', Result) > 0  then\n              begin\n                Result := Copy(Result, 1, Pos(',', Result)-1);\n                while Pos('.', Result) > 0  do\n                  Result := Copy(Result, 1, Pos('.', Result)-1)+Copy(Result, Pos('.', Result)+1, Length(Result)); //remove ThousandSeparator\n                Result := Result + '.'+Copy(MoneyString, Pos(',', MoneyString)+1, Length(MoneyString));\n              end\n              else\n                Result[Pos(',', Result)] := '.';\n          end;\n          Break;\n        end;\n  end;\nend;\n{**\n  Converts SQL string into float value.\n  @param Str an SQL string with comma delimiter.\n  @param Def a default value if the string can not be converted.\n  @return a converted value or Def if conversion was failt.\n}\n{$IFDEF WITH_RAWBYTESTRING}\nfunction SQLStrToFloatDef(Str: RawByteString; Def: Extended): Extended;\nvar\n  OldDecimalSeparator: Char;\n  OldThousandSeparator: Char;\n  AString: String;\nbegin\n  if Str = '' then\n    Result := Def\n  else\n  begin\n    OldDecimalSeparator := {$IFDEF WITH_FORMATSETTINGS}FormatSettings.{$ENDIF}DecimalSeparator;\n    OldThousandSeparator := {$IFDEF WITH_FORMATSETTINGS}FormatSettings.{$ENDIF}ThousandSeparator;\n    {$IFDEF WITH_FORMATSETTINGS}FormatSettings.{$ENDIF}DecimalSeparator := '.';\n    {$IFDEF WITH_FORMATSETTINGS}FormatSettings.{$ENDIF}ThousandSeparator := ',';\n    if not CharInSet(Char(String(Str)[1]), ['0'..'9', '-']) then\n      AString := ConvertMoneyToFloat(String(Str))\n    else\n      AString := String(Str);\n    Result := StrToFloatDef(AString, Def);\n    {$IFDEF WITH_FORMATSETTINGS}FormatSettings.{$ENDIF}DecimalSeparator := OldDecimalSeparator;\n    {$IFDEF WITH_FORMATSETTINGS}FormatSettings.{$ENDIF}ThousandSeparator := OldThousandSeparator;\n  end;\nend;\n{$ENDIF}\n\nfunction SQLStrToFloatDef(Str: String; Def: Extended): Extended;\nvar\n  OldDecimalSeparator: Char;\n  OldThousandSeparator: Char;\n  AString: String;\nbegin\n  if Str = '' then\n    Result := Def\n  else\n  begin\n    OldDecimalSeparator := {$IFDEF WITH_FORMATSETTINGS}FormatSettings.{$ENDIF}DecimalSeparator;\n    OldThousandSeparator := {$IFDEF WITH_FORMATSETTINGS}FormatSettings.{$ENDIF}ThousandSeparator;\n    {$IFDEF WITH_FORMATSETTINGS}FormatSettings.{$ENDIF}DecimalSeparator := '.';\n    {$IFDEF WITH_FORMATSETTINGS}FormatSettings.{$ENDIF}ThousandSeparator := ',';\n    if not CharInSet(Char(Str[1]), ['0'..'9', '-']) then\n      AString := ConvertMoneyToFloat(Str)\n    else\n      AString := Str;\n    Result := StrToFloatDef(AString, Def);\n    {$IFDEF WITH_FORMATSETTINGS}FormatSettings.{$ENDIF}DecimalSeparator := OldDecimalSeparator;\n    {$IFDEF WITH_FORMATSETTINGS}FormatSettings.{$ENDIF}ThousandSeparator := OldThousandSeparator;\n  end;\nend;\n\n{**\n  Converts SQL string into float value.\n  @param Str an SQL string with comma delimiter.\n  @return a converted value or Def if conversion was failt.\n}\nfunction SQLStrToFloat(const Str: AnsiString): Extended;\nvar\n  OldDecimalSeparator: Char;\nbegin\n  OldDecimalSeparator := {$IFDEF WITH_FORMATSETTINGS}FormatSettings.{$ENDIF}DecimalSeparator;\n  {$IFDEF WITH_FORMATSETTINGS}FormatSettings.{$ENDIF}DecimalSeparator := '.';\n  try\n    Result := StrToFloat(String(Str));\n  finally\n    {$IFDEF WITH_FORMATSETTINGS}FormatSettings.{$ENDIF}DecimalSeparator := OldDecimalSeparator;\n  end;\nend;\n\n{ Convert string buffer into pascal string }\n\nfunction BufferToStr(Buffer: PWideChar; Length: LongInt): string;\nvar s : Widestring;\nbegin\n   Result := '';\n   if Assigned(Buffer) then\n   begin\n      SetString(s, Buffer, Length div SizeOf(Char));\n      Result := s;\n   end;\nend;\n\n{ Convert string buffer into pascal string }\n\nfunction BufferToStr(Buffer: PAnsiChar; Length: LongInt): string;\nbegin\n  Result := '';\n  if Assigned(Buffer) then\n    SetString(Result, Buffer, Length);\nend;\n\nfunction BufferToBytes(Buffer: Pointer; Length: LongInt): TByteDynArray;\nbegin\n  SetLength(Result, Length);\n  System.Move(Buffer^, Pointer(Result)^, Length);\nend;\n\n{**\n  Converts a string into boolean value.\n  @param Str a string value.\n  @return <code>True</code> is Str = 'Y'/'YES'/'T'/'TRUE'/<>0\n}\nfunction StrToBoolEx(Str: string): Boolean;\nbegin\n  Str := UpperCase(Str);\n  Result := (Str = 'Y') or (Str = 'YES') or (Str = 'T') or (Str = 'TRUE')\n    or (StrToIntDef(Str, 0) <> 0);\nend;\n\n{**\n  Converts a boolean into string value.\n  @param Bool a boolean value.\n  @return <code>\"True\"</code> or <code>\"False\"</code>\n}\nfunction BoolToStrEx(Bool: Boolean): String;\nbegin\n  if Bool then\n    Result := 'True'\n  else\n    Result := 'False';\nend;\n\n{**\n  Checks if the specified string can represent an IP address.\n  @param Str a string value.\n  @return <code>True</code> if the string can represent an IP address\n    or <code>False</code> otherwise.\n}\nfunction IsIpAddr(const Str: string): Boolean;\nvar\n  I, N, M, Pos, Val: Integer;\nbegin\n  if IsMatch('*.*.*.*', Str) then\n  begin\n    N := 0;\n    M := 0;\n    Pos := 1;\n    for I := 1 to Length(Str) do\n    begin\n      if I - Pos > 3 then\n        Break;\n      if Str[I] = '.' then\n      begin\n        {ticked #73/#24 patch }\n        Val := StrToIntDef(Copy(Str, Pos, I - Pos), -1);\n        if not ((Val > -1 ) and (Val < 256)) then\n          Break;\n       Inc(N);\n       Pos := I + 1;\n      end;\n      if CharInSet(Str[I], ['0'..'9']) then\n        Inc(M);\n    end;\n    Result := (M + N = Length(Str)) and (N = 3);\n  end\n  else\n    Result := False;\nend;\n\nprocedure SplitToStringList(List: TStrings; Str: string; const Delimiters: string);\nvar\n  DelimPos: Integer;\nbegin\n  repeat\n    DelimPos := FirstDelimiter(Delimiters, Str);\n    if DelimPos > 0 then\n    begin\n      if DelimPos > 1 then\n        List.Add(Copy(Str, 1, DelimPos - 1));\n      Str := Copy(Str, DelimPos + 1, Length(Str) - DelimPos);\n      end\n      else\n      Break;\n  until DelimPos <= 0;\n  if Str <> '' then\n    List.Add(Str);\nend;\n\n{**\n  Splits string using the multiple chars.\n  @param Str the source string\n  @param Delimiters the delimiters string\n  @return the result list where plased delimited string\n}\nfunction SplitString(const Str, Delimiters: string): TStrings;\nbegin\n  Result := TStringList.Create;\n  try\n    SplitToStringList(Result, Str, Delimiters);\n  except\n    Result.Free;\n    raise;\n  end;\nend;\n\n{**\n  Puts to list a splitted string using the multiple chars which replaces\n  the previous list content.\n  @param List a list with strings.\n  @param Str the source string\n  @param Delimiters the delimiters string\n}\nprocedure PutSplitString(List: TStrings; const Str, Delimiters: string);\nbegin\n  List.Clear;\n  SplitToStringList(List, Str, Delimiters);\nend;\n\n{**\n  Appends to list a splitted string using the multiple chars.\n  @param List a list with strings.\n  @param Str the source string\n  @param Delimiters the delimiters string\n}\nprocedure AppendSplitString(List: TStrings; const Str, Delimiters: string);\nbegin\n  SplitToStringList(List, Str, Delimiters);\nend;\n\n{**\n  Composes a string from the specified strings list delimited with\n  a special character.\n  @param List a list of strings.\n  @param Delimiter a delimiter string.\n  @return a composed string from the list.\n}\nfunction ComposeString(List: TStrings; const Delimiter: string): string;\nvar\n  i, Len, DelimLen: Integer;\n  S: string;\n  P: PChar;\nbegin\n  DelimLen := Length(Delimiter);\n  Len := 0;\n  if List.Count > 0 then\n  begin\n    Inc(Len, Length(List[0]));\n    for i := 1 to List.Count - 1 do\n      Inc(Len, DelimLen + Length(List[i]));\n  end;\n  SetLength(Result, Len);\n  P := Pointer(Result);\n  for i := 0 to List.Count - 1 do\n  begin\n    if (i > 0) and (DelimLen > 0) then\n    begin\n      Move(Pointer(Delimiter)^, P^, DelimLen * SizeOf(Char));\n      Inc(P, DelimLen);\n    end;\n    S := List[i];\n    Len := Length(S);\n    if Len > 0 then\n    begin\n      Move(Pointer(S)^, P^, Len * SizeOf(Char));\n      Inc(P, Len);\n    end;\n  end;\nend;\n\n{**\n  Converts a float value into SQL string with '.' delimiter.\n  @param Value a float value to be converted.\n  @return a converted string value.\n}\nfunction FloatToSQLStr(Value: Extended): string;\nvar\n  OldDecimalSeparator: Char;\nbegin\n  OldDecimalSeparator := {$IFDEF WITH_FORMATSETTINGS}FormatSettings.{$ENDIF}DecimalSeparator;\n  {$IFDEF WITH_FORMATSETTINGS}FormatSettings.{$ENDIF}DecimalSeparator := '.';\n  try\n    Result := FloatToStr(Value);\n  finally\n    {$IFDEF WITH_FORMATSETTINGS}FormatSettings.{$ENDIF}DecimalSeparator := OldDecimalSeparator;\n  end;\nend;\n\n{**\n  Split a single string using the delimiter, appending the resulting strings\n  to the List. (gto: New version, now unicode safe and without the bug which\n  adds a blank line before the last found string)\n  @param List a list to append the result.\n  @param Str the source string\n  @param Delimiters the delimiter string\n}\nprocedure SplitToStringListEx(List: TStrings; const Str, Delimiter: string);\nvar\n   temp: string;\n   i: integer;\nbegin\n   temp := Str + Delimiter;\n   repeat\n      i := List.Add(Copy(temp, 0, AnsiPos(Delimiter, temp) - 1));\n      Delete(temp, 1, Length(List[i] + Delimiter));\n   until\n      temp = '';\nend;\n\n{**\n  Puts to list a splitted string using the delimiter string which replaces\n  the previous list content.\n  @param List a list with strings.\n  @param Str the source string\n  @param Delimiters the delimiter string\n}\nprocedure PutSplitStringEx(List: TStrings; const Str, Delimiter: string);\nbegin\n  List.Clear;\n  SplitToStringListEx(List, Str, Delimiter);\nend;\n\n{**\n  Splits string using the delimiter string.\n  @param Str the source string\n  @param Delimiters the delimiter string\n  @return the result list where plased delimited string\n}\nfunction SplitStringEx(const Str, Delimiter: string): TStrings;\nbegin\n  Result := TStringList.Create;\n  try\n    SplitToStringListEx(Result, Str, Delimiter);\n  except\n    Result.Free;\n    raise;\n  end;\nend;\n\n{**\n  Appends to list a splitted string using the delimeter string.\n  @param List a list with strings.\n  @param Str the source string\n  @param Delimiters the delimiters string\n}\nprocedure AppendSplitStringEx(List: TStrings; const Str, Delimiter: string);\nbegin\n  SplitToStringListEx(List, Str, Delimiter);\nend;\n\n{**\n  Converts bytes into a AnsiString representation.\n  @param Value an array of bytes to be converted.\n  @return a converted AnsiString.\n}\nfunction BytesToStr(const Value: TByteDynArray): AnsiString;\nbegin\n  SetString(Result, PAnsiChar(@Value[0]), Length(Value))\nend;\n\n{**\n  Converts AnsiString into an array of bytes.\n  @param Value a AnsiString to be converted.\n  @return a converted array of bytes.\n}\nfunction StrToBytes(const Value: AnsiString): TByteDynArray;\nvar L: Integer;\nbegin\n  L := Length(Value);\n  SetLength(Result, L);\n  if Value <> '' then\n    Move(Value[1], Result[0], L)\nend;\n\n{$IFDEF WITH_RAWBYTESTRING}\n{**\n  Converts a UTF8String into an array of bytes.\n  @param Value a UTF8String to be converted.\n  @return a converted array of bytes.\n}\nfunction StrToBytes(const Value: UTF8String): TByteDynArray;\nvar L: Integer;\nbegin\n  L := Length(Value);\n  SetLength(Result, L);\n  if Value <> '' then\n    Move(Value[1], Result[0], L)\nend;\n{**\n  Converts a RawByteString into an array of bytes.\n  @param Value a RawByteString to be converted.\n  @return a converted array of bytes.\n}\nfunction StrToBytes(const Value: RawByteString): TByteDynArray;\nvar L: Integer;\nbegin\n  L := Length(Value);\n  SetLength(Result, L);\n  if Value <> '' then\n    Move(Value[1], Result[0], L)\nend;\n{$ENDIF}\n{**\n  Converts a WideString into an array of bytes.\n  @param Value a String to be converted.\n  @return a converted array of bytes.\n}\nfunction StrToBytes(const Value: WideString): TByteDynArray;\nvar L: Integer;\nbegin\n  L := Length(Value)*2;\n  SetLength(Result, L);\n  if Value <> '' then\n    Move(Value[1], Result[0], L)\nend;\n{**\n  Converts a String into an array of bytes.\n  @param Value a String to be converted.\n  @return a converted array of bytes.\n}\n{$IFDEF PWIDECHAR_IS_PUNICODECHAR}\nfunction StrToBytes(const Value: UnicodeString): TByteDynArray;\nvar L: Integer;\nbegin\n  L := Length(Value) * SizeOf(Char);\n  SetLength(Result, L);\n  if Value <> '' then\n    Move(Value[1], Result[0], L)\nend;\n{$ENDIF}\n{**\n  Converts bytes into a variant representation.\n  @param Value an array of bytes to be converted.\n  @return a converted variant.\n}\nfunction BytesToVar(const Value: TByteDynArray): Variant;\nvar\n  I: Integer;\nbegin\n  Result := VarArrayCreate([0, Length(Value) - 1], varByte);\n  for I := 0 to Length(Value) - 1 do\n    Result[I] := Value[I];\nend;\n\n{**\n  Converts variant into an array of bytes.\n  @param Value a varaint to be converted.\n  @return a converted array of bytes.\n}\nfunction VarToBytes(const Value: Variant): TByteDynArray;\nvar\n  I: Integer;\nbegin\n  if not (VarIsArray(Value) and (VarArrayDimCount(Value) = 1) and\n     ((VarType(Value) and VarTypeMask) = varByte)) then\n    raise Exception.Create(SInvalidVarByteArray);\n\n  SetLength(Result, VarArrayHighBound(Value, 1) + 1);\n  for I := 0 to VarArrayHighBound(Value, 1) do\n    Result[I] := Value[I];\nend;\n\n{**\n  Converts Ansi SQL Date/Time (yyyy-mm-dd hh:nn:ss or yyyy-mm-dd hh:nn:ss.zzz)\n  to TDateTime\n  @param Value a date and time string.\n  @return a decoded TDateTime value.\n}\nfunction AnsiSQLDateToDateTime(const Value: string): TDateTime;\nvar\n  Year, Month, Day, Hour, Min, Sec, MSec: Word;\n  Temp: string;\n  DateFound: Boolean;\n\n  procedure ExtractTime(AString: String);\n  var dotPos: Integer;\n  begin\n    Hour := StrToIntDef(Copy(AString, 1, 2), 0);\n    Min := StrToIntDef(Copy(AString, 4, 2), 0);\n    Sec := StrToIntDef(Copy(AString, 7, 2), 0);\n\n    //it the time Length is bigger than 8, it can have milliseconds and it ...\n    dotPos := 0;\n    MSec := 0;\n    if Length(AString) > 8 then\n      dotPos :=Pos ('.', AString);\n\n    //if the dot are found, milliseconds are present.\n    if dotPos > 0 then begin\n      MSec := StrToIntDef(LeftStr(RightStr(AString,Length(AString)-dotPos)+'000',3),0);\n    end;\n  end;\nbegin\n  Temp := Value;\n  Result := 0;\n  DateFound := False;\n\n  if Length(Temp) >= 10 then\n  begin\n    Year := StrToIntDef(Copy(Temp, 1, 4), 0);\n    Month := StrToIntDef(Copy(Temp, 6, 2), 0);\n    Day := StrToIntDef(Copy(Temp, 9, 2), 0);\n\n    if (Year <> 0) and (Month <> 0) and (Day <> 0) then\n    begin\n      try\n        Result := EncodeDate(Year, Month, Day);\n        DateFound := True;\n      except\n      end;\n    end;\n    Temp := RightStr(Temp, Length(Temp)-11);\n  end;\n\n  if (Length(Temp) >= 8) or ( not DateFound ) then\n  begin\n    if DateFound then\n      ExtractTime(Temp)\n    else\n      ExtractTime(Value);\n    try\n      if Result >= 0 then\n        Result := Result + EncodeTime(Hour, Min, Sec, MSec)\n      else\n        Result := Result - EncodeTime(Hour, Min, Sec, MSec)\n    except\n    end;\n  end;\nend;\n\n{**\n  Converts Timestamp String to TDateTime\n  @param Value a timestamp string.\n  @return a decoded TDateTime value.\n}\nfunction TimestampStrToDateTime(const Value: string): TDateTime;\nvar\n  Year, Month, Day, Hour, Min, Sec: Integer;\n  StrLength, StrPos, StrPosPrev: Integer;\n  //\n  function CharMatch( matchchars: string ): boolean;\n  // try to match as much characters as possible\n  begin\n    StrPosPrev:= StrPos;\n    Result:= false;\n    while StrPos<=StrLength do\n       if pos(Value[StrPos], matchchars) > 0 then\n         begin\n            inc(StrPos);\n            Result := true;\n         end\n       else\n         break;\n  end;\nbegin\n  Result := 0;\n  StrPos:= 1;\n  StrLength := Length(Value);\n\n  if not CharMatch('1234567890') then\n     exit; // year\n  Year := StrToIntDef(Copy(Value, StrPosPrev, StrPos-StrPosPrev), 0);\n  if not CharMatch('-/\\') then\n     exit;\n  if not CharMatch('1234567890') then\n     exit; // month\n  Month:= StrToIntDef(Copy(Value, StrPosPrev, StrPos-StrPosPrev), 0);\n  if not CharMatch('-/\\') then\n     exit;\n  if not CharMatch('1234567890') then\n     exit; // day\n  Day:= StrToIntDef(Copy(Value, StrPosPrev, StrPos-StrPosPrev), 0);\n  try\n    Result := EncodeDate(Year, Month, Day);\n  except\n  end;\n  //\n  if not CharMatch(' ') then\n     exit;\n  if not CharMatch('1234567890') then\n     exit; // hour\n  Hour := StrToIntDef(Copy(Value, StrPosPrev, StrPos-StrPosPrev), 0);\n  if not CharMatch('-/\\') then\n     exit;\n  if not CharMatch('1234567890') then\n     exit; // minute\n  Min:= StrToIntDef(Copy(Value, StrPosPrev, StrPos-StrPosPrev), 0);\n  if not CharMatch('-/\\') then\n     exit;\n  if not CharMatch('1234567890') then\n     exit; // second\n  Sec:= StrToIntDef(Copy(Value, StrPosPrev, StrPos-StrPosPrev), 0);\n  try\n    Result := REsult + EncodeTime(Hour, Min, Sec,0);\n  except\n  end;\n\nend;\n\n\n{**\n  Converts TDateTime to Ansi SQL Date/Time\n  @param Value an encoded TDateTime value.\n  @return a  date and time string.\n}\nfunction DateTimeToAnsiSQLDate(Value: TDateTime; WithMMSec: Boolean = False): string;\nvar\n  a, MSec:Word;\nbegin\n  if WithMMSec then\n  begin\n    DecodeTime(Value,a,a,a,MSec);\n    if MSec=0 then\n      Result := FormatDateTime('yyyy-mm-dd hh:nn:ss', Value)\n    else\n      Result := FormatDateTime('yyyy-mm-dd hh:nn:ss.zzz', Value);\n  end\n  else\n    Result := FormatDateTime('yyyy-mm-dd hh:nn:ss', Value)\nend;\n\n{ TZSortedList }\n\n{**\n  Performs quick sort algorithm for the list.\n}\nprocedure TZSortedList.QuickSort(SortList: PPointerList; L, R: Integer;\n  SCompare: TZListSortCompare);\nvar\n  I, J: Integer;\n  P, T: Pointer;\nbegin\n  repeat\n    I := L;\n    J := R;\n    P := SortList^[(L + R) shr 1];\n    repeat\n      while (I < R) And (SCompare(SortList^[I], P) < 0) do //check I against R too since the pointer can be nil\n        Inc(I);\n      while (J > L) And (SCompare(SortList^[J], P) > 0) do //check j against L too since the pointer can be nil\n        Dec(J);\n      if I <= J then\n      begin\n        T := SortList^[I];\n        SortList^[I] := SortList^[J];\n        SortList^[J] := T;\n        Inc(I);\n        Dec(J);\n      end;\n    until I > J;\n    if L < J then\n      QuickSort(SortList, L, J, SCompare);\n    L := I;\n  until I >= R;\nend;\n\n{**\n  Performs sorting for this list.\n  @param Compare a comparison function.\n}\nprocedure TZSortedList.Sort(Compare: TZListSortCompare);\nbegin\n  if (List <> nil) and (Count > 0) then\n    {$IFDEF DELPHI16_UP}\n    QuickSort(@List, 0, Count - 1, Compare);\n    {$ELSE}\n    QuickSort(List, 0, Count - 1, Compare);\n    {$ENDIF}\nend;\n\n{**\n  Converts an string into escape PostgreSQL format.\n  @param Value a regular string.\n  @return a string in PostgreSQL escape format.\n}\nfunction EncodeCString(const Value: string): string;\nvar\n  I: Integer;\n  SrcLength, DestLength: Integer;\n  SrcBuffer, DestBuffer: PChar;\nbegin\n  SrcLength := Length(Value);\n  SrcBuffer := PChar(Value);\n  DestLength := 0;\n  for I := 1 to SrcLength do\n  begin\n    if CharInSet(SrcBuffer^, [#0]) then\n       Inc(DestLength, 4)\n    else if CharInSet(SrcBuffer^, ['\"', '''', '\\']) then\n       Inc(DestLength, 2)\n    else\n       Inc(DestLength);\n    Inc(SrcBuffer);\n  end;\n\n  SrcBuffer := PChar(Value);\n  SetLength(Result, DestLength);\n  DestBuffer := PChar(Result);\n\n  for I := 1 to SrcLength do\n  begin\n    if CharInSet(SrcBuffer^, [#0]) then\n    begin\n      DestBuffer[0] := '\\';\n      DestBuffer[1] := Chr(Ord('0') + (Byte(SrcBuffer^) shr 6));\n      DestBuffer[2] := Chr(Ord('0') + ((Byte(SrcBuffer^) shr 3) and $07));\n      DestBuffer[3] := Chr(Ord('0') + (Byte(SrcBuffer^) and $07));\n      Inc(DestBuffer, 4);\n    end\n    else if CharInSet(SrcBuffer^, ['\"', '''', '\\']) then\n    begin\n      DestBuffer[0] := '\\';\n      DestBuffer[1] := SrcBuffer^;\n      Inc(DestBuffer, 2);\n    end\n    else\n    begin\n      DestBuffer^ := SrcBuffer^;\n      Inc(DestBuffer);\n    end;\n    Inc(SrcBuffer);\n  end;\nend;\n\n{**\n  Converts an string from escape PostgreSQL format.\n  @param Value a string in PostgreSQL escape format.\n  @return a regular string.\n}\nfunction DecodeCString(const Value: string): string;\nvar\n  SrcLength, DestLength: Integer;\n  SrcBuffer, DestBuffer: PChar;\nbegin\n  SrcLength := Length(Value);\n  SrcBuffer := PChar(Value);\n  SetLength(Result, SrcLength);\n  DestLength := 0;\n  DestBuffer := PChar(Result);\n\n  while SrcLength > 0 do\n  begin\n    if SrcBuffer^ = '\\' then\n    begin\n      Inc(SrcBuffer);\n      if CharInSet(SrcBuffer^, ['0'..'9']) then\n      begin\n        DestBuffer^ := Chr(((Byte(SrcBuffer[0]) - Ord('0')) shl 6)\n          or ((Byte(SrcBuffer[1]) - Ord('0')) shl 3)\n          or ((Byte(SrcBuffer[2]) - Ord('0'))));\n        Inc(SrcBuffer, 3);\n        Dec(SrcLength, 4);\n      end\n      else\n      begin\n        case SrcBuffer^ of\n          'r': DestBuffer^ := #13;\n          'n': DestBuffer^ := #10;\n          't': DestBuffer^ := #9;\n        else\n               DestBuffer^ := SrcBuffer^;\n        end;\n        Inc(SrcBuffer);\n        Dec(SrcLength, 2);\n      end\n    end\n    else\n    begin\n      DestBuffer^ := SrcBuffer^;\n      Inc(SrcBuffer);\n      Dec(SrcLength);\n    end;\n    Inc(DestBuffer);\n    Inc(DestLength);\n  end;\n  SetLength(Result, DestLength);\nend;\n\n\n{**\n  Replace chars in the string\n  @param Source a char to search.\n  @param Target a char to replace.\n  @param Str a source string.\n  @return a string with replaced chars.\n}\nfunction ReplaceChar(const Source, Target: Char; const Str: string): string;\nvar\n  P: PChar;\n  I:Integer;\nbegin\n  Result := Str;\n  UniqueString(Result);\n  P := Pointer(Result);\n  for i := 0 to Length(Str) - 1 do\n  begin\n    if P^ = Source then\n      P^ := Target;\n    Inc(P);\n  end;\nend;\n\n{**\n   Copy buffer to the pascal string\n   @param Buffer a buffer with data\n   @param Length a buffer length\n   @return a buffer content\n}\nfunction MemPas(Buffer: PChar; Length: LongInt): string;\nbegin\n  Result := '';\n  if Assigned(Buffer) then\n    SetString(Result, Buffer, Length);\nend;\n\n{**\n  Decodes a full version value encoded with Zeos SQL format:\n   (major_version * 1,000,000) + (minor_version * 1,000) + sub_version\n  into separated major, minor and subversion values\n  @param FullVersion an integer containing the Full Version to decode.\n  @param MajorVersion an integer containing the Major Version decoded.\n  @param MinorVersion an integer containing the Minor Version decoded.\n  @param SubVersion an integer contaning the Sub Version (revision) decoded.\n}\nprocedure DecodeSQLVersioning(const FullVersion: Integer;\n out MajorVersion: Integer; out MinorVersion: Integer;\n out SubVersion: Integer);\nbegin\n MajorVersion := FullVersion div 1000000;\n MinorVersion := (FullVersion - (MajorVersion * 1000000)) div 1000;\n SubVersion   := FullVersion-(MajorVersion*1000000)-(MinorVersion*1000);\nend;\n\n{**\n  Encodes major, minor and subversion (revision) values in Zeos SQL format:\n   (major_version * 1,000,000) + (minor_version * 1,000) + sub_version\n  For example, 4.1.12 is returned as 4001012.\n  @param MajorVersion an integer containing the Major Version.\n  @param MinorVersion an integer containing the Minor Version.\n  @param SubVersion an integer containing the Sub Version (revision).\n  @return an integer containing the full version.\n}\nfunction EncodeSQLVersioning(const MajorVersion: Integer;\n const MinorVersion: Integer; const SubVersion: Integer): Integer;\nbegin\n Result := (MajorVersion * 1000000) + (MinorVersion * 1000) + SubVersion;\nend;\n\n{**\n  Formats a Zeos SQL Version format to X.Y.Z where:\n   X = major_version\n   Y = minor_version\n   Z = sub version\n  @param SQLVersion an integer\n  @return Formated Zeos SQL Version Value.\n}\n\nfunction FormatSQLVersion(const SQLVersion: Integer): string;\nvar\n   MajorVersion, MinorVersion, SubVersion: Integer;\nbegin\n DecodeSQLVersioning(SQLVersion, MajorVersion, MinorVersion, SubVersion);\n Result := IntToStr(MajorVersion)+'.'+IntToStr(MinorVersion)+'.'+IntToStr(SubVersion);\nend;\n\n{**\n  Arranges thousand and decimal separator to a System-defaults\n  @param the value which has to be converted and arranged\n  @return a valid floating value\n}\nfunction ZStrToFloat(Value: PAnsiChar): Extended;\nvar\n  OldDecimalSeparator, OldThousandSeparator: Char;\nbegin\n  OldDecimalSeparator := {$IFDEF WITH_FORMATSETTINGS}FormatSettings.{$ENDIF}DecimalSeparator;\n  OldThousandSeparator := {$IFDEF WITH_FORMATSETTINGS}FormatSettings.{$ENDIF}ThousandSeparator;\n\n  if {$IFDEF WITH_ANSISTRINGPOS_DEPRECATED}AnsiStrings.{$ENDIF}AnsiStrPos(PAnsiChar(Value), PAnsiChar(AnsiString(OldDecimalSeparator))) = nil then\n    if {$IFDEF WITH_ANSISTRINGPOS_DEPRECATED}AnsiStrings.{$ENDIF}AnsiStrPos(PAnsiChar(Value), PAnsiChar(AnsiString(OldThousandSeparator))) = nil then\n      //No DecimalSeparator and no ThousandSeparator\n      Result := StrToFloat(String(Value))\n    else\n    begin\n      //wrong DecimalSepartor\n      {$IFDEF WITH_FORMATSETTINGS}FormatSettings.{$ENDIF}DecimalSeparator := OldThousandSeparator;\n      {$IFDEF WITH_FORMATSETTINGS}FormatSettings.{$ENDIF}ThousandSeparator := OldDecimalSeparator;\n      Result := StrToFloat(String(Value));\n    end\n  else\n    if {$IFDEF WITH_ANSISTRINGPOS_DEPRECATED}AnsiStrings.{$ENDIF}AnsiStrPos(PAnsiChar(Value), PAnsiChar(AnsiString(OldThousandSeparator))) = nil then\n      //default DecimalSepartor\n      Result := StrToFloat(String(Value))\n    else\n      if {$IFDEF WITH_STRLEN_DEPRECATED}AnsiStrings.{$ENDIF}StrLen({$IFDEF WITH_ANSISTRINGPOS_DEPRECATED}AnsiStrings.{$ENDIF}AnsiStrPos(PAnsiChar(Value), PAnsiChar(AnsiString(OldDecimalSeparator)))) <\n          {$IFDEF WITH_STRLEN_DEPRECATED}AnsiStrings.{$ENDIF}StrLen({$IFDEF WITH_ANSISTRINGPOS_DEPRECATED}AnsiStrings.{$ENDIF}AnsiStrPos(PAnsiChar(Value), PAnsiChar(AnsiString(OldThousandSeparator)))) then\n          //default DecimalSepartor and ThousandSeparator\n        Result := StrToFloat(String(Value))\n      else\n      begin\n        //wrong DecimalSepartor and ThousandSeparator\n        {$IFDEF WITH_FORMATSETTINGS}FormatSettings.{$ENDIF}DecimalSeparator := OldThousandSeparator;\n        {$IFDEF WITH_FORMATSETTINGS}FormatSettings.{$ENDIF}ThousandSeparator := OldDecimalSeparator;\n        Result := StrToFloat(String(Value));\n      end;\n\n  {$IFDEF WITH_FORMATSETTINGS}FormatSettings.{$ENDIF}DecimalSeparator := OldDecimalSeparator;\n  {$IFDEF WITH_FORMATSETTINGS}FormatSettings.{$ENDIF}ThousandSeparator := OldThousandSeparator;\nend;\n\n{**\n  Arranges thousand and decimal separator to a System-defaults\n  @param the value which has to be converted and arranged\n  @return a valid floating value\n}\nfunction ZStrToFloat(Value: AnsiString): Extended;\nbegin\n  Result := ZStrToFloat(PAnsiChar(Value));\nend;\n\nprocedure ZSetString(const Src: PAnsiChar; var Dest: AnsiString);\nbegin\n  if Assigned(Src) then\n    ZSetString(Src, {$IFDEF WITH_STRLEN_DEPRECATED}AnsiStrings.{$ENDIF}StrLen(Src), Dest)\n  else\n    Dest := '';\nend;\n\nprocedure ZSetString(const Src: PAnsiChar; const Len: Cardinal; var Dest: AnsiString);\nbegin\n  if ( Len = 0 ) or ( Src = nil ) then\n    Dest := ''\n  else\n  begin\n    SetLength(Dest, Len);\n    Move(Src^, PAnsiChar(Dest)^, Len);\n  end;\nend;\n\nprocedure ZSetString(const Src: PAnsiChar; var Dest: UTF8String);\nbegin\n  if Assigned(Src) then\n    ZSetString(Src, {$IFDEF WITH_STRLEN_DEPRECATED}AnsiStrings.{$ENDIF}StrLen(Src), Dest)\n  else\n    Dest := '';\nend;\n\nprocedure ZSetString(const Src: PAnsiChar; const Len: Cardinal; var Dest: UTF8String);\nbegin\n  if ( Len = 0 ) or ( Src = nil ) then\n    Dest := ''\n  else\n  begin\n    SetLength(Dest, Len);\n    Move(Src^, PAnsiChar(Dest)^, Len);\n  end;\nend;\n\nprocedure ZSetString(const Src: PAnsiChar; const Len: Cardinal; var Dest: ZWideString); overload;\nbegin\n  if ( Len = 0 ) or ( Src = nil ) then\n    Dest := ''\n  else\n  begin\n    SetLength(Dest, Len div 2);\n    Move(Src^, PWideChar(Dest)^, Len);\n  end;\nend;\n\n{$IFDEF WITH_RAWBYTESTRING}\nprocedure ZSetString(const Src: PAnsiChar; var Dest: RawByteString);\nbegin\n  if Assigned(Src) then\n    ZSetString(Src, {$IFDEF WITH_STRLEN_DEPRECATED}AnsiStrings.{$ENDIF}StrLen(Src), Dest)\n  else\n    Dest := '';\nend;\n\nprocedure ZSetString(const Src: PAnsiChar; const Len: Cardinal; var Dest: RawByteString);\nbegin\n  if ( Len = 0 ) or ( Src = nil ) then\n    Dest := ''\n  else\n  begin\n    SetLength(Dest, Len);\n    Move(Src^, PAnsiChar(Dest)^, Len);\n  end;\nend;\n{$ENDIF}\n\nend.\n"
  },
  {
    "path": "lib/zeosdbo/src/core/ZTokenizer.pas",
    "content": "{*********************************************************}\n{                                                         }\n{                 Zeos Database Objects                   }\n{        String tokenizing classes and interfaces         }\n{                                                         }\n{         Originally written by Sergey Seroukhov          }\n{                                                         }\n{*********************************************************}\n\n{@********************************************************}\n{    Copyright (c) 1999-2012 Zeos Development Group       }\n{                                                         }\n{ License Agreement:                                      }\n{                                                         }\n{ This library is distributed in the hope that it will be }\n{ useful, but WITHOUT ANY WARRANTY; without even the      }\n{ implied warranty of MERCHANTABILITY or FITNESS FOR      }\n{ A PARTICULAR PURPOSE.  See the GNU Lesser General       }\n{ Public License for more details.                        }\n{                                                         }\n{ The source code of the ZEOS Libraries and packages are  }\n{ distributed under the Library GNU General Public        }\n{ License (see the file COPYING / COPYING.ZEOS)           }\n{ with the following  modification:                       }\n{ As a special exception, the copyright holders of this   }\n{ library give you permission to link this library with   }\n{ independent modules to produce an executable,           }\n{ regardless of the license terms of these independent    }\n{ modules, and to copy and distribute the resulting       }\n{ executable under terms of your choice, provided that    }\n{ you also meet, for each linked independent module,      }\n{ the terms and conditions of the license of that module. }\n{ An independent module is a module which is not derived  }\n{ from or based on this library. If you modify this       }\n{ library, you may extend this exception to your version  }\n{ of the library, but you are not obligated to do so.     }\n{ If you do not wish to do so, delete this exception      }\n{ statement from your version.                            }\n{                                                         }\n{                                                         }\n{ The project web site is located on:                     }\n{   http://zeos.firmos.at  (FORUM)                        }\n{   http://sourceforge.net/p/zeoslib/tickets/ (BUGTRACKER)}\n{   svn://svn.code.sf.net/p/zeoslib/code-0/trunk (SVN)    }\n{                                                         }\n{   http://www.sourceforge.net/projects/zeoslib.          }\n{                                                         }\n{                                                         }\n{                                 Zeos Development Group. }\n{********************************************************@}\n\nunit ZTokenizer;\n\ninterface\n\n{$I ZCore.inc}\n\nuses\n   Classes, {$IFDEF MSEgui}mclasses,{$ENDIF} SysUtils,\n   ZClasses, ZCompatibility;\n\ntype\n\n  {**\n    Objects of this class represent a type of token,\n    such as \"number\", \"symbol\" or \"word\".\n  }\n  TZTokenType = (ttUnknown, ttEOF, ttFloat, ttInteger, ttHexDecimal,\n    ttNumber, ttSymbol, ttQuoted, ttQuotedIdentifier, ttWord, ttKeyword,\n    ttWhitespace, ttComment, ttSpecial, ttTime, ttDate, ttDateTime, ttEscape);\n\n  {**\n    Defines options for tokenizing strings.\n  }\n  TZTokenOption = (toSkipUnknown, toSkipWhitespaces, toSkipComments,\n    toSkipEOF, toUnifyWhitespaces, toUnifyNumbers, toDecodeStrings);\n  TZTokenOptions = set of TZTokenOption;\n\n  {**\n    A token represents a logical chunk of a string. For\n    example, a typical tokenizer would break the string\n    <code>\"1.23 <= 12.3\"</code> into three tokens: the number\n    1.23, a less-than-or-equal symbol, and the number 12.3. A\n    token is a receptacle, and relies on a tokenizer to decide\n    precisely how to divide a string into tokens.\n  }\n  TZToken = {$ifndef FPC_REQUIRES_PROPER_ALIGNMENT}packed{$endif} record\n    Value: string;\n    TokenType: TZTokenType;\n  end;\n\n  {** Defines a dynamic array of tokens. }\n  TZTokenDynArray = array of TZToken;\n\n  // Forward declaration\n  TZTokenizer = class;\n\n  {**\n    A tokenizerState returns a token, given a reader, an initial character\n    read from the reader, and a tokenizer that is conducting an overall\n    tokenization of the reader. The tokenizer will typically have a character\n    state table that decides which state to use, depending on an initial\n    character. If a single character is insufficient, a state such\n    as <code>SlashState</code> will read a second character, and may delegate\n    to another state, such as <code>SlashStarState</code>. This prospect\n    of delegation is the reason that the <code>nextToken()</code> method has a\n    tokenizer argument.\n  }\n  TZTokenizerState = class (TObject)\n  public\n    function NextToken(Stream: TStream; FirstChar: Char;\n      Tokenizer: TZTokenizer): TZToken; virtual; abstract;\n  end;\n\n  {**\n    EgonHugeist:\n    A <code>EsacapeState</code> object returns bininary/String-data from a reader.\n    This\n    state's idea is save work-around of DataSet given binary/String-Data.\n    So it has some requirements to pick out this data from the SQL-\n    String:\n\n      First: We have to define one or some Chars to detect this state.\n        Example: If data data was given like;\n        ~<|:%d|<~'...Binary/StringData...'~<|:%d|<~\n        we are able to predetect this State.\n\n      Second: The parameter d represents an Integer(Count of Chars)\n        if we do not use this it's possible that the Tokenizer is\n        vinny-nilly on getting binary-Data!\n\n      Third: The GenerigResolver who assambles the insert/update\n        Statements has to add this ass prefix and suffix.\n\n      Fourth: The User of this Component has to know this too. So has to do this\n        previously if he want to insert/update binary-data in a self\n        assembled Query. So i think it would be better to add an published\n        read-only Property like:\n          EscapeChars: String;\n\n    If we did this corectly we are able to disassemble all queries and\n      do execute the nessesary UTF8Encoding of the TZQuoteState and\n      TZWordState which represents either Quoted-String-Data or\n      Catalog/Table/Alias/Field name-spaces.\n\n    This State is only neccessary for <code>Delphi2009+</code> ( 2009 and later)\n    and results of it's mixing nByte-Chars and binary-Data 1Byte-Chars.\n  }\n  TZEscapeState = class (TZTokenizerState)\n    function NextToken(Stream: TStream; FirstChar: Char;\n      Tokenizer: TZTokenizer): TZToken; override;\n  end;\n  {**\n    A NumberState object returns a number from a reader. This\n    state's idea of a number allows an optional, initial\n    minus sign, followed by one or more digits. A decimal\n    point and another string of digits may follow these digits.\n  }\n  TZNumberState = class (TZTokenizerState)\n  public\n    function NextToken(Stream: TStream; FirstChar: Char;\n      Tokenizer: TZTokenizer): TZToken; override;\n  end;\n\n  {**\n    A quoteState returns a quoted string token from a reader.\n    This state will collect characters until it sees a match\n    to the character that the tokenizer used to switch to\n    this state. For example, if a tokenizer uses a double-\n    quote character to enter this state, then <code>\n    nextToken()</code> will search for another double-quote\n    until it finds one or finds the end of the reader.\n  }\n  TZQuoteState = class (TZTokenizerState)\n  public\n    function NextToken(Stream: TStream; FirstChar: Char;\n      Tokenizer: TZTokenizer): TZToken; override;\n\n    function EncodeString(const Value: string; QuoteChar: Char): string; virtual;\n    function DecodeString(const Value: string; QuoteChar: Char): string; virtual;\n  end;\n\n  {**\n    A CommentState object returns a comment from a reader.\n  }\n  TZCommentState = class (TZTokenizerState)\n  public\n    function NextToken(Stream: TStream; FirstChar: Char;\n      Tokenizer: TZTokenizer): TZToken; override;\n  end;\n\n  {**\n    This state will either delegate to a comment-handling\n    state, or return a token with just a slash in it.\n  }\n  TZCppCommentState = class (TZCommentState)\n  protected\n    function GetMultiLineComment(Stream: TStream): string; virtual;\n    function GetSingleLineComment(Stream: TStream): string; virtual;\n  public\n    function NextToken(Stream: TStream; FirstChar: Char;\n      Tokenizer: TZTokenizer): TZToken; override;\n  end;\n\n  {**\n    This state will either delegate to a comment-handling\n    state, or return a token with just a slash in it.\n  }\n  TZCCommentState = class (TZCppCommentState)\n  public\n    function NextToken(Stream: TStream; FirstChar: Char;\n      Tokenizer: TZTokenizer): TZToken; override;\n  end;\n\n  {*Fix for C++ Builder hpp generation bug - #817612 *}\n  (*$HPPEMIT 'namespace Ztokenizer {class DELPHICLASS TZSymbolNode;}' *)\n  // Forward declaration\n  TZSymbolNode = class;\n  TZSymbolNodeArray = array of TZSymbolNode;\n\n  {**\n    A <code>SymbolNode</code> object is a member of a tree that\n    contains all possible prefixes of allowable symbols. Multi-\n    character symbols appear in a <code>SymbolNode</code> tree\n    with one node for each character.\n\n    For example, the symbol <code>=:~</code> will appear in a\n    tree as three nodes. The first node contains an equals sign,\n    and has a child; that child contains a colon and has a\n    child; this third child contains a tilde, and has no\n    children of its own. If the colon node had another child\n    for a dollar sign character, then the tree would contain\n    the symbol <code>=:$</code>.\n\n    A tree of <code>SymbolNode</code> objects collaborate to\n    read a (potentially multi-character) symbol from an input\n    stream. A root node with no character of its own finds an\n    initial node that represents the first character in the\n    input. This node looks to see if the next character in the\n    stream matches one of its children. If so, the node\n    delegates its reading task to its child. This approach\n    walks down the tree, pulling symbols from the input that\n    match the path down the tree.\n\n    When a node does not have a child that matches the next\n    character, we will have read the longest possible symbol\n    prefix. This prefix may or may not be a valid symbol.\n    Consider a tree that has had <code>=:~</code> added and has\n    not had <code>=:</code> added. In this tree, of the three\n    nodes that contain <code>=:~</code>, only the first and\n    third contain complete symbols. If, say, the input contains\n    <code>=:a</code>, the colon node will not have a child that\n    matches the 'a' and so it will stop reading. The colon node\n    has to \"unread\": it must push back its character, and ask\n    its parent to unread. Unreading continues until it reaches\n    an ancestor that represents a valid symbol.\n  }\n  TZSymbolNode = class (TObject)\n  private\n    FCharacter: Char;\n    FChildren: TZSymbolNodeArray;\n    FValid: Boolean;\n    FParent: TZSymbolNode;\n  protected\n    procedure AddDescendantLine(const Value: string);\n    function DeepestRead(Stream: TStream): TZSymbolNode;\n    function EnsureChildWithChar(Value: Char): TZSymbolNode;\n    function FindChildWithChar(Value: Char): TZSymbolNode; virtual;\n    function FindDescendant(const Value: string): TZSymbolNode;\n    function UnreadToValid(Stream: TStream): TZSymbolNode;\n\n    property Children: TZSymbolNodeArray read FChildren write FChildren;\n    property Character: Char read FCharacter write FCharacter;\n    property Valid: Boolean read FValid write FValid;\n    property Parent: TZSymbolNode read FParent write FParent;\n  public\n    constructor Create(Parent: TZSymbolNode; Character: Char);\n    destructor Destroy; override;\n\n    function Ancestry: string; virtual;\n  end;\n\n  {**\n    This class is a special case of a <code>SymbolNode</code>. A\n    <code>SymbolRootNode</code> object has no symbol of its\n    own, but has children that represent all possible symbols.\n  }\n  TZSymbolRootNode = class (TZSymbolNode)\n  protected\n    function FindChildWithChar(Value: Char): TZSymbolNode; override;\n  public\n    constructor Create;\n\n    procedure Add(const Value: string);\n    function Ancestry: string; override;\n    function NextSymbol(Stream: TStream; FirstChar: Char): string;\n  end;\n\n  {**\n    The idea of a symbol is a character that stands on its\n    own, such as an ampersand or a parenthesis. For example,\n    when tokenizing the expression <code>(isReady)&\n    (isWilling) </code>, a typical tokenizer would return 7\n    tokens, including one for each parenthesis and one for\n    the ampersand. Thus a series of symbols such as\n    <code>)&( </code> becomes three tokens, while a series\n    of letters such as <code>isReady</code> becomes a single\n    word token.\n    <p>\n    Multi-character symbols are an exception to the rule\n    that a symbol is a standalone character.  For example, a\n    tokenizer may want less-than-or-equals to tokenize as a\n    single token. This class provides a method for\n    establishing which multi-character symbols an object of\n    this class should treat as single symbols. This allows,\n    for example, <code>\"cat <= dog\"</code> to tokenize as\n    three tokens, rather than splitting the less-than and\n    equals symbols into separate tokens.\n    <p>\n    By default, this state recognizes the following multi-\n    character symbols: <code>!=, :-, <=, >=</code>\n  }\n  TZSymbolState = class (TZTokenizerState)\n  private\n    FSymbols: TZSymbolRootNode;\n  protected\n    property Symbols: TZSymbolRootNode read FSymbols write FSymbols;\n  public\n    constructor Create;\n    destructor Destroy; override;\n\n    function NextToken(Stream: TStream; FirstChar: Char;\n      Tokenizer: TZTokenizer): TZToken; override;\n    procedure Add(const Value: string); virtual;\n  end;\n\n  {**\n    A whitespace state ignores whitespace (such as blanks\n    and tabs), and returns the tokenizer's next token. By\n    default, all characters from 0 to 32 are whitespace.\n  }\n  TZWhitespaceState = class (TZTokenizerState)\n  private\n    FWhitespaceChars: array[0..ord(high(char))] of Boolean;\n  public\n    constructor Create;\n\n    function NextToken(Stream: TStream; FirstChar: Char;\n      Tokenizer: TZTokenizer): TZToken; override;\n    procedure SetWhitespaceChars(FromChar: Char; ToChar: Char; Enable: Boolean);\n  end;\n\n  {**\n    A wordState returns a word from a reader. Like other\n    states, a tokenizer transfers the job of reading to this\n    state, depending on an initial character. Thus, the\n    tokenizer decides which characters may begin a word, and\n    this state determines which characters may appear as a\n    second or later character in a word. These are typically\n    different sets of characters; in particular, it is typical\n    for digits to appear as parts of a word, but not as the\n    initial character of a word.\n    <p>\n    By default, the following characters may appear in a word.\n    The method <code>setWordChars()</code> allows customizing\n    this.\n    <blockquote><pre>\n        From    To\n         'a', 'z'\n         'A', 'Z'\n         '0', '9'\n\n        as well as: minus sign, underscore, and apostrophe.\n    </pre></blockquote>\n  }\n  TZWordState = class (TZTokenizerState)\n  private\n    FWordChars: array[0..ord(high(char))] of Boolean;\n  public\n    constructor Create;\n\n    function NextToken(Stream: TStream; FirstChar: Char;\n      Tokenizer: TZTokenizer): TZToken; override;\n    procedure SetWordChars(FromChar: Char; ToChar: Char; Enable: Boolean);\n  end;\n\n  {**\n    A tokenizer divides a string into tokens. This class is\n    highly customizable with regard to exactly how this division\n    occurs, but it also has defaults that are suitable for many\n    languages. This class assumes that the character values read\n    from the string lie in the range 0-255. For example, the\n    Unicode value of a capital A is 65, so\n    <code> System.out.println((char)65); </code> prints out a\n    capital A.\n    <p>\n    The behavior of a tokenizer depends on its character state\n    table. This table is an array of 256 <code>TokenizerState\n    </code>  states. The state table decides which state to\n    enter upon reading a character from the input string.\n    <p>\n    For example, by default, upon reading an 'A', a tokenizer\n    will enter a \"word\" state. This means the tokenizer will\n    ask a <code>WordState</code> object to consume the 'A',\n    along with the characters after the 'A' that form a word.\n    The state's responsibility is to consume characters and\n    return a complete token.\n    <p>\n    The default table sets a SymbolState for every character\n    from 0 to 255, and then overrides this with:\n    <blockquote><pre>\n        From    To     State\n          0     ' '    whitespaceState\n         'a'    'z'    wordState\n         'A'    'Z'    wordState\n        160     255    wordState\n         '0'    '9'    numberState\n         '-'    '-'    numberState\n         '.'    '.'    numberState\n         '\"'    '\"'    quoteState\n        '\\''   '\\''    quoteState\n         '/'    '/'    slashState\n    </pre></blockquote>\n    In addition to allowing modification of the state table,\n    this class makes each of the states above available. Some\n    of these states are customizable. For example, wordState\n    allows customization of what characters can be part of a\n    word, after the first character.\n  }\n  IZTokenizer = interface (IZInterface)\n    ['{C7CF190B-C45B-4AB4-A406-5999643DF6A0}']\n\n    function TokenizeBufferToList(const Buffer: string; Options: TZTokenOptions):\n      TStrings;\n    function TokenizeStreamToList(Stream: TStream; Options: TZTokenOptions):\n      TStrings;\n\n    function TokenizeBuffer(const Buffer: string; Options: TZTokenOptions):\n      TZTokenDynArray;\n    function TokenizeStream(Stream: TStream; Options: TZTokenOptions):\n      TZTokenDynArray;\n\n    function GetCommentState: TZCommentState;\n    function GetNumberState: TZNumberState;\n    function GetQuoteState: TZQuoteState;\n    function GetSymbolState: TZSymbolState;\n    function GetWhitespaceState: TZWhitespaceState;\n    function GetWordState: TZWordState;\n    function GetCharacterState(StartChar: Char): TZTokenizerState;\n    function AnsiGetEscapeString(const Ansi: RawByteString): String;\n    {$IF defined(FPC) and defined(WITH_RAWBYTESTRING)}\n    function GetEscapeString(const EscapeString: RawByteString): RawByteString;\n    {$ELSE}\n    function GetEscapeString(const EscapeString: String): String;\n    {$IFEND}\n  end;\n\n  {** Implements a default tokenizer object. }\n  TZTokenizer = class (TZAbstractObject, IZTokenizer)\n  private\n    FCharacterStates: array[0..ord(high(char))] of TZTokenizerState;\n    FCommentState: TZCommentState;\n    FNumberState: TZNumberState;\n    FQuoteState: TZQuoteState;\n    FSymbolState: TZSymbolState;\n    FWhitespaceState: TZWhitespaceState;\n    FWordState: TZWordState;\n    FEscapeState: TZEscapeState; //EgonHugeist\n  protected\n    function CheckEscapeState(const ActualState: TZTokenizerState;\n      Stream: TStream; const FirstChar: Char): TZTokenizerState; virtual;\n  public\n    constructor Create;\n    destructor Destroy; override;\n\n    function AnsiGetEscapeString(const EscapeString: RawByteString): String; virtual;\n    {$IF defined(FPC) and defined(WITH_RAWBYTESTRING)}\n    function GetEscapeString(const EscapeString: RawByteString): RawByteString;\n    {$ELSE}\n    function GetEscapeString(const EscapeString: String): String;\n    {$IFEND}\n    function TokenizeBufferToList(const Buffer: string; Options: TZTokenOptions):\n      TStrings;\n    function TokenizeStreamToList(Stream: TStream; Options: TZTokenOptions):\n      TStrings;\n\n    function TokenizeBuffer(const Buffer: string; Options: TZTokenOptions):\n      TZTokenDynArray;\n    function TokenizeStream(Stream: TStream; Options: TZTokenOptions):\n      TZTokenDynArray;\n\n    function GetCharacterState(StartChar: Char): TZTokenizerState;\n    procedure SetCharacterState(FromChar, ToChar: Char; State: TZTokenizerState);\n\n    function GetEscapeState: TZEscapeState;\n    function GetCommentState: TZCommentState;\n    function GetNumberState: TZNumberState;\n    function GetQuoteState: TZQuoteState;\n    function GetSymbolState: TZSymbolState;\n    function GetWhitespaceState: TZWhitespaceState;\n    function GetWordState: TZWordState;\n\n    property EscapeState: TZEscapeState read FEscapeState write FEscapeState;\n    property CommentState: TZCommentState read FCommentState write FCommentState;\n    property NumberState: TZNumberState read FNumberState write FNumberState;\n    property QuoteState: TZQuoteState read FQuoteState write FQuoteState;\n    property SymbolState: TZSymbolState read FSymbolState write FSymbolState;\n    property WhitespaceState: TZWhitespaceState read FWhitespaceState\n      write FWhitespaceState;\n    property WordState: TZWordState read FWordState write FWordState;\n  end;\n\nconst\n  EscapeMarkSequence = String('~<|');\n\n\nimplementation\n\nuses\n  Math, StrUtils;\n\n{$IFDEF FPC}\n  {$HINTS OFF}\n{$ENDIF}\n\n{ TZEscapeState } //EgonHugeist\n\n{**\n  Return a quoted Escape-data-string of token from a reader. This method\n  will collect characters until it sees a match to the\n  character that the tokenizer used to switch to this state.\n\n  @return a quoted string token from a reader\n}\nfunction TZEscapeState.NextToken(Stream: TStream; FirstChar: Char;\n  Tokenizer: TZTokenizer): TZToken;\nvar\n  TempChar: Char;\n  TempStr, LenString: string;\n  I, IReadCount: Integer;\n\n  function ReadNextCharToTempChar: Boolean;\n  begin\n    Result := True;\n    if Stream.Read(TempChar, 1 * SizeOf(Char)) = 0 then\n    begin\n      Result := False;\n      TempChar := #0;\n    end\n    else\n      Inc(iReadCount);\n  end;\n\n  procedure RollbackStream;\n  begin\n    Stream.Seek(-(iReadCount * SizeOf(Char)), soFromCurrent);\n    Result.Value := '';\n    IReadCount := 0;\n  end;\n\n  function CheckMarkChars(Marks: String): Boolean;\n  var\n    iMark: Integer;\n  begin\n    Result := False;\n\n    if ( TempChar = Copy(Marks, 1, 1) ) then\n      for iMark := 2 to Length(Marks) do  //First Char was predetected\n      begin\n        if ReadNextCharToTempChar then\n        begin\n          if not ( TempChar = Copy(Marks, iMark, 1) ) then\n          begin\n            RollbackStream;\n            Exit;\n          end;\n        end else\n        begin\n          RollbackStream;\n          Exit;\n        end;\n      end\n    else\n    begin\n      RollbackStream;\n      Exit;\n    end;\n    Result := True;\n  end;\n\n  function ReadLengthString: String;\n  var\n    B: Boolean;\n  begin\n    Result := ''; //init value\n    repeat\n      B := ReadNextCharToTempChar;\n      if B then\n        if CharInSet(TempChar, ['0'..'9']) then\n          Result := Result+TempChar;\n    until ( not CharInSet(TempChar, ['0'..'9'])) or ( not B );\n  end;\nbegin\n  Result.TokenType := ttUnknown;\n  Result.Value := '';\n\n  iReadCount := 0; //init Value\n  TempStr := '';\n  TempChar := FirstChar; //FirstChar: ~\n\n  if not CheckMarkChars(EscapeMarkSequence) then Exit;\n\n  //All inMark-Chars where test.\n  //Now Check for Numeric Chars until MarkOut was found or #0 was Resulted\n  LenString := ReadLengthString;\n  if LenString = '' then\n  begin\n    RollbackStream;\n    Exit;\n  end;\n\n  //Now Check the TempChar for it's hits on cBinDetectCharsOut\n  if not CheckMarkChars(ReverseString(EscapeMarkSequence)) then Exit;\n\n  //OutMarks where Found too. So let's read the BinarayData to the TempStr\n  //Including the Quotes\n  for i := 0 to StrToInt(LenString) do\n  begin\n    if not ReadNextCharToTempChar then\n      Exit\n    else\n      TempStr := TempStr + TempChar;\n  end;\n  //Done and still in here! Post Data to Result!\n  Result.Value := Copy(TempStr, 1, Length(TempStr)-1);\n\n  //Now Check for in Chars again..\n  if not CheckMarkChars(EscapeMarkSequence) then Exit;\n  //MarkIn-Chars where found now compare the read-length\n  TempStr := LenString; //Save to before compare\n  LenString := ReadLengthString;\n  if ( LenString = '' ) or ( LenString <> TempStr ) then\n  begin\n    RollbackStream;\n    Exit;\n  end;\n\n  //Now Check the TempChar for it's hits on Escape-Detect-CharsOut again..\n  if not CheckMarkChars(ReverseString(EscapeMarkSequence)) then Exit;\n  //MarkOut-Chars where found again now we are ready here\n\n  //everything was fine! Now we are sure Escape data was here\n  Result.TokenType := ttEscape;\n  //End..\nend;\n\n{ TZNumberState }\n\n{**\n  Return a number token from a reader.\n  @return a number token from a reader\n}\nfunction TZNumberState.NextToken(Stream: TStream; FirstChar: Char;\n  Tokenizer: TZTokenizer): TZToken;\nvar\n  ReadNum: Integer;\n  AbsorbedLeadingMinus: Boolean;\n  AbsorbedDot: Boolean;\n  GotAdigit: Boolean;\n\n  function AbsorbDigits: string;\n  begin\n    Result := '';\n    while CharInSet(FirstChar, ['0'..'9']) do\n    begin\n      GotAdigit := True;\n      Result := Result + FirstChar;\n      ReadNum := Stream.Read(FirstChar, 1 * SizeOf(Char));\n      if ReadNum = 0 then\n        Break;\n    end;\n  end;\n\nbegin\n  { Initializes the process. }\n  ReadNum := 0;\n  AbsorbedLeadingMinus := False;\n  AbsorbedDot := False;\n  GotAdigit := False;\n\n  Result.TokenType := ttUnknown;\n  Result.Value := '';\n\n  { Parses left part of the number. }\n  if FirstChar = '-' then\n  begin\n    ReadNum := Stream.Read(FirstChar, 1 * SizeOf(Char));\n    Result.Value := '-';\n    AbsorbedLeadingMinus := True;\n  end;\n  Result.Value := Result.Value + AbsorbDigits;\n\n  { Parses right part of the number. }\n  if FirstChar = '.' then\n  begin\n    AbsorbedDot := True;\n    Result.Value := Result.Value + '.';\n    ReadNum := Stream.Read(FirstChar, 1 * SizeOf(Char));\n    if ReadNum > 0 then\n      Result.Value := Result.Value + AbsorbDigits;\n  end;\n\n  { Pushback wrong symbols. }\n  Stream.Seek(-ReadNum, soFromCurrent);\n\n  { Gets a token result. }\n  if not GotAdigit then\n  begin\n    if AbsorbedLeadingMinus and AbsorbedDot then\n    begin\n      Stream.Seek(-(1 * SizeOf(Char)), soFromCurrent);\n      if Tokenizer.SymbolState <> nil then\n        Result := Tokenizer.SymbolState.NextToken(Stream, '-', Tokenizer);\n    end\n    else if AbsorbedLeadingMinus then\n    begin\n      if Tokenizer.SymbolState <> nil then\n      Result := Tokenizer.SymbolState.NextToken(Stream, '-', Tokenizer)\n    end\n    else if AbsorbedDot then\n    begin\n      if Tokenizer.SymbolState <> nil then\n        Result := Tokenizer.SymbolState.NextToken(Stream, '.', Tokenizer);\n    end;\n  end\n  else\n  begin\n    if AbsorbedDot then\n      Result.TokenType := ttFloat\n    else\n      Result.TokenType := ttInteger;\n  end;\nend;\n\n{ TZQuoteState }\n\n{**\n  Return a quoted string token from a reader. This method\n  will collect characters until it sees a match to the\n  character that the tokenizer used to switch to this state.\n\n  @return a quoted string token from a reader\n}\nfunction TZQuoteState.NextToken(Stream: TStream; FirstChar: Char;\n  Tokenizer: TZTokenizer): TZToken;\nvar\n  TempChar: Char;\n  TempStr: string;\nbegin\n  TempStr := FirstChar;\n  repeat\n    if Stream.Read(TempChar, 1 * SizeOf(Char)) = 0 then\n      TempChar := FirstChar;\n    TempStr := TempStr + TempChar;\n  until TempChar = FirstChar;\n\n  Result.TokenType := ttQuoted;\n  Result.Value := TempStr;\nend;\n\n{**\n  Encodes a string value.\n  @param Value a string value to be encoded.\n  @param QuoteChar a string quote character.\n  @returns an encoded string.\n}\nfunction TZQuoteState.EncodeString(const Value: string; QuoteChar: Char): string;\nbegin\n  Result := QuoteChar + Value + QuoteChar;\nend;\n\n{**\n  Decodes a string value.\n  @param Value a string value to be decoded.\n  @param QuoteChar a string quote character.\n  @returns an decoded string.\n}\nfunction TZQuoteState.DecodeString(const Value: string; QuoteChar: Char): string;\nbegin\n  if (Length(Value) >= 2) and (Value[1] = QuoteChar)\n    and (Value[Length(Value)] = Value[1]) then\n    Result := Copy(Value, 2, Length(Value) - 2)\n  else\n    Result := Value;\nend;\n\n{ TZBasicCommentState }\n\n{**\n  Either delegate to a comment-handling state, or return a\n  token with just a slash in it.\n\n  @return either just a slash token, or the results of\n    delegating to a comment-handling state\n}\nfunction TZCommentState.NextToken(Stream: TStream; FirstChar: Char;\n  Tokenizer: TZTokenizer): TZToken;\nvar\n  ReadChar: Char;\n  ReadStr: string;\nbegin\n  ReadStr := FirstChar;\n  while (Stream.Read(ReadChar, 1 * SizeOf(Char)) > 0) and not CharInSet(ReadChar, [#10, #13]) do\n      ReadStr := ReadStr + ReadChar;\n    if CharInSet(ReadChar, [#10, #13]) then\n    Stream.Seek(-(1 * SizeOf(Char)), soFromCurrent);\n\n  Result.TokenType := ttComment;\n  Result.Value := ReadStr;\nend;\n\n{ TZCppCommentState }\n\n{**\n  Ignore everything up to a closing star and slash, and\n  then return the tokenizer's next token.\n  @return the tokenizer's next token\n}\nfunction TZCppCommentState.GetMultiLineComment(Stream: TStream): string;\nvar\n  ReadChar, LastChar: Char;\nbegin\n  LastChar := #0;\n  Result := '';\n  while Stream.Read(ReadChar, 1 * SizeOf(Char)) > 0 do\n  begin\n    Result := Result + ReadChar;\n    if (LastChar = '*') and (ReadChar = '/') then\n      Break;\n    LastChar := ReadChar;\n  end;\nend;\n\n{**\n  Ignore everything up to an end-of-line and return the tokenizer's next token.\n  @return the tokenizer's next token\n}\nfunction TZCppCommentState.GetSingleLineComment(Stream: TStream): string;\nvar\n  ReadChar: Char;\nbegin\n  Result := '';\n  while (Stream.Read(ReadChar, 1 * SizeOf(Char)) > 0) and not CharInSet(ReadChar, [#10, #13]) do\n      Result := Result + ReadChar;\n\n  // mdaems : for single line comments the line ending must be included\n  // as it should never be stripped off or unified with other whitespace characters\n  if CharInSet(ReadChar, [#10, #13]) then\n    begin\n      Result := Result + ReadChar;\n      // ludob Linux line terminator is just LF, don't read further if we already have LF\n      if (ReadChar<>#10) and (Stream.Read(ReadChar, 1 * SizeOf(Char)) > 0) then\n        if CharInSet(ReadChar, [#10, #13]) then\n          Result := Result + ReadChar\n        else\n          Stream.Seek(-(1 * SizeOf(Char)), soFromCurrent);\n    end;\nend;\n\n{**\n  Either delegate to a comment-handling state, or return a\n  token with just a slash in it.\n\n  @return either just a slash token, or the results of\n    delegating to a comment-handling state\n}\nfunction TZCppCommentState.NextToken(Stream: TStream; FirstChar: Char;\n  Tokenizer: TZTokenizer): TZToken;\nvar\n  ReadChar: Char;\n  ReadNum: Integer;\nbegin\n  Result.TokenType := ttUnknown;\n  Result.Value := FirstChar;\n\n  ReadNum := Stream.Read(ReadChar, 1 * SizeOf(Char));\n  if (ReadNum > 0) and (ReadChar = '*') then\n  begin\n    Result.TokenType := ttComment;\n    Result.Value := '/*' + GetMultiLineComment(Stream);\n  end\n  else if (ReadNum > 0) and (ReadChar = '/') then\n  begin\n    Result.TokenType := ttComment;\n    Result.Value := '//' + GetSingleLineComment(Stream);\n  end\n  else\n  begin\n    if ReadNum > 0 then\n      Stream.Seek(-(1 * SizeOf(Char)), soFromCurrent);\n    if Tokenizer.SymbolState <> nil then\n      Result := Tokenizer.SymbolState.NextToken(Stream, FirstChar, Tokenizer);\n  end;\nend;\n\n{ TZCCommentState }\n\n{**\n  Gets a C specific comments like /* */.\n  @return either just a slash token, or the results of\n    delegating to a comment-handling state\n}\nfunction TZCCommentState.NextToken(Stream: TStream; FirstChar: Char;\n  Tokenizer: TZTokenizer): TZToken;\nvar\n  ReadChar: Char;\n  ReadNum: Integer;\nbegin\n  Result.TokenType := ttUnknown;\n  Result.Value := FirstChar;\n\n  if FirstChar = '/' then\n  begin\n    ReadNum := Stream.Read(ReadChar, 1 * SizeOf(Char));\n    if (ReadNum > 0) and (ReadChar = '*') then\n    begin\n      Result.TokenType := ttComment;\n      Result.Value := '/*' + GetMultiLineComment(Stream);\n    end\n    else\n    begin\n      if ReadNum > 0 then\n        Stream.Seek(-(1 * SizeOf(Char)), soFromCurrent);\n    end;\n  end;\n\n  if (Result.TokenType = ttUnknown) and (Tokenizer.SymbolState <> nil) then\n    Result := Tokenizer.SymbolState.NextToken(Stream, FirstChar, Tokenizer);\nend;\n\n{ TZSymbolNode }\n\n{**\n  Constructs a SymbolNode with the given parent, representing\n  the given character.\n  @param Parent this node's parent\n  @param Character this node's character\n}\nconstructor TZSymbolNode.Create(Parent: TZSymbolNode; Character: Char);\nbegin\n  FParent := Parent;\n  FCharacter := Character;\n  FValid := False;\n  SetLength(FChildren, 256);\nend;\n\n{**\n  Destroys this symbol object and cleanups the memory.\n}\ndestructor TZSymbolNode.Destroy;\nvar\n  I: Integer;\nbegin\n  for I := 0 to 255 do\n  begin\n    if FChildren[I] <> nil then\n      FChildren[I].Free\n    else\n         Break;\n  end;\n  SetLength(FChildren, 0);\n  FParent := nil;\n  inherited Destroy;\nend;\n\n{**\n  Add a line of descendants that represent the characters in the given string.\n}\nprocedure TZSymbolNode.AddDescendantLine(const Value: string);\nvar\n  Node: TZSymbolNode;\nbegin\n  if Length(Value) > 0 then\n  begin\n    Node := EnsureChildWithChar(Value[1]);\n    Node.AddDescendantLine(Copy(Value, 2, Length(Value) - 1));\n  end;\nend;\n\n{**\n  Show the symbol this node represents.\n  @return the symbol this node represents\n}\nfunction TZSymbolNode.Ancestry: string;\nbegin\n  Result := FParent.Ancestry + FCharacter;\nend;\n\n{**\n  Find the descendant that takes as many characters as possible from the input.\n}\nfunction TZSymbolNode.DeepestRead(Stream: TStream): TZSymbolNode;\nvar\n  TempChar: Char;\n  Node: TZSymbolNode;\n  ReadNum: Integer;\nbegin\n  ReadNum := Stream.Read(TempChar, 1 * SizeOf(Char));\n  if ReadNum > 0 then\n    Node := FindChildWithChar(TempChar)\n  else\n    Node := nil;\n\n  if Node = nil then\n  begin\n    Stream.Seek(-ReadNum, soFromCurrent);\n    Result := Self;\n  end\n  else\n    Result := Node.DeepestRead(Stream);\nend;\n\n{**\n  Find or create a child for the given character.\n}\nfunction TZSymbolNode.EnsureChildWithChar(Value: Char): TZSymbolNode;\nvar\n  N: Integer;\nbegin\n  Result := FindChildWithChar(Value);\n  if Result = nil then\n  begin\n    N := 0;\n    while (FChildren[N] <> nil) and (N <= 255) do\n      Inc(N);\n    if N <= 255 then\n    begin\n      Result := TZSymbolNode.Create(Self, Value);\n      FChildren[N] := Result;\n    end;\n  end;\nend;\n\n{**\n  Find a child with the given character.\n}\nfunction TZSymbolNode.FindChildWithChar(Value: Char): TZSymbolNode;\nvar\n  I: Integer;\n  Current: TZSymbolNode;\nbegin\n  Result := nil;\n  for I := 0 to 255 do\n  begin\n    Current := Children[I];\n    if (Current = nil) or (Current.Character = Value) then\n    begin\n      Result := Current;\n      Break;\n    end;\n  end;\nend;\n\n{**\n  Find a descendant which is down the path the given string indicates.\n}\nfunction TZSymbolNode.FindDescendant(const Value: string): TZSymbolNode;\nvar\n  TempChar: Char;\nbegin\n  if Length(Value) > 0 then\n    TempChar := Value[1]\n  else\n    TempChar := #0;\n  Result := FindChildWithChar(TempChar);\n  if (Length(Value) > 1) and (Result <> nil) then\n    Result := Result.FindDescendant(Copy(Value, 2, Length(Value) - 1));\nend;\n\n{**\n  Unwind to a valid node; this node is \"valid\" if its\n  ancestry represents a complete symbol. If this node is\n  not valid, put back the character and ask the parent to unwind.\n}\nfunction TZSymbolNode.UnreadToValid(Stream: TStream): TZSymbolNode;\nbegin\n  if not FValid then\n  begin\n    Stream.Seek(-(1 * SizeOf(Char)), soFromCurrent);\n    Result := FParent.UnreadToValid(Stream);\n  end\n  else\n    Result := Self;\nend;\n\n{ TZSymbolRootNode }\n\n{**\n  Create and initialize a root node.\n}\nconstructor TZSymbolRootNode.Create;\nvar\n  I: Integer;\nbegin\n  inherited Create(nil, #0);\n\n  for I := 0 to 255 do\n  begin\n    FChildren[I] := TZSymbolNode.Create(Self, Chr(I));\n    FChildren[I].Valid := True;\n  end;\nend;\n\n{**\n  Add the given string as a symbol.\n  @param   String   the character sequence to add\n}\nprocedure TZSymbolRootNode.Add(const Value: string);\nvar\n  TempChar: Char;\n  Node: TZSymbolNode;\nbegin\n  if Length(Value) > 0 then\n    TempChar := Value[1]\n  else\n     TempChar := #0;\n  Node := EnsureChildWithChar(TempChar);\n  Node.AddDescendantLine(Copy(Value, 2, Length(Value) - 1));\n  FindDescendant(Value).Valid := True;\nend;\n\n{**\n  A root node has no parent and no character of its own, so its ancestry is \"\".\n  @return an empty string\n}\nfunction TZSymbolRootNode.Ancestry: string;\nbegin\n  Result := '';\nend;\n\n{**\n  A root node maintains its children in an array instead of\n  a Vector, to be faster.\n}\nfunction TZSymbolRootNode.FindChildWithChar(Value: Char): TZSymbolNode;\nbegin\n  Result := FChildren[Ord(Value)];\nend;\n\n{**\n  Return a symbol string from a reader.\n\n  @param Stream a reader to read from\n  @param FirstChar the first character of this symbol, already\n    read from the reader\n  @return a symbol string from a reader\n}\nfunction TZSymbolRootNode.NextSymbol(Stream: TStream; FirstChar: Char): string;\nvar\n  Node: TZSymbolNode;\nbegin\n  Node := FindChildWithChar(FirstChar);\n  Node := Node.DeepestRead(Stream);\n  Node := Node.UnreadToValid(Stream);\n  Result := Node.Ancestry;\nend;\n\n{ TZSymbolState }\n\n{**\n  Constructs a symbol state with a default idea of what\n  multi-character symbols to accept (as described in the class comment).\n}\nconstructor TZSymbolState.Create;\nbegin\n  FSymbols := TZSymbolRootNode.Create;\nend;\n\n{**\n  Destroys this object and cleanups the memory.\n}\ndestructor TZSymbolState.Destroy;\nbegin\n  FSymbols.Free;\n  inherited Destroy;\nend;\n\n{**\n  Add a multi-character symbol.\n  @param Value the symbol to add, such as \"=:=\"\n}\nprocedure TZSymbolState.Add(const Value: string);\nbegin\n  FSymbols.Add(Value);\nend;\n\n{**\n  Return a symbol token from a reader.\n  @return a symbol token from a reader\n}\nfunction TZSymbolState.NextToken(Stream: TStream; FirstChar: Char;\n  Tokenizer: TZTokenizer): TZToken;\nbegin\n  Result.TokenType := ttSymbol;\n  Result.Value := FSymbols.NextSymbol(Stream, FirstChar);\nend;\n\n{ TZWhitespaceState }\n\n{**\n  Constructs a whitespace state with a default idea of what\n  characters are, in fact, whitespace.\n}\nconstructor TZWhitespaceState.Create;\nbegin\n  SetWhitespaceChars(' ', high(char), False);\n  SetWhitespaceChars(Chr(0), ' ', True);\nend;\n\n{**\n  Ignore whitespace (such as blanks and tabs), and return\n  the tokenizer's next token.\n  @return the tokenizer's next token\n}\nfunction TZWhitespaceState.NextToken(Stream: TStream; FirstChar: Char;\n  Tokenizer: TZTokenizer): TZToken;\nvar\n  ReadNum: Integer;\n  ReadChar: Char;\n  ReadStr: string;\nbegin\n  ReadStr := FirstChar;\n  ReadNum := 0;\n  while True do\n  begin\n    ReadNum := Stream.Read(ReadChar, 1 * SizeOf(Char));\n    if (ReadNum = 0) or not FWhitespaceChars[Ord(ReadChar)] then\n      Break;\n    ReadStr := ReadStr + ReadChar;\n  end;\n\n  if ReadNum > 0 then\n    Stream.Seek(-(1 * SizeOf(Char)), soFromCurrent);\n  Result.TokenType := ttWhitespace;\n  Result.Value := ReadStr;\nend;\n\n{**\n  Establish the given characters as whitespace to ignore.\n  @param FromChar first character index.\n  @param ToChar last character index.\n  @param Enable true, if this state should ignore characters in the given range\n}\nprocedure TZWhitespaceState.SetWhitespaceChars(FromChar, ToChar: Char;\n  Enable: Boolean);\nvar\n  I: Integer;\nbegin\n  for I := Ord(FromChar) to MinIntValue([Ord(ToChar), 255]) do\n    FWhitespaceChars[I] := Enable;\nend;\n\n{ TZWordState }\n\n{**\n  Constructs a word state with a default idea of what characters\n  are admissible inside a word (as described in the class comment).\n}\nconstructor TZWordState.Create;\nbegin\n  SetWordChars(#0, #191, False);\n  SetWordChars(#192, high(char), True);\n  SetWordChars('a', 'z', True);\n  SetWordChars('A', 'Z', True);\n  SetWordChars('0', '9', True);\n  SetWordChars('-', '-', True);\n  SetWordChars('_', '_', True);\n  SetWordChars('''', '''', True);\nend;\n\n{**\n  Return a word token from a reader.\n  @return a word token from a reader\n}\nfunction TZWordState.NextToken(Stream: TStream; FirstChar: Char;\n  Tokenizer: TZTokenizer): TZToken;\nvar\n  TempChar: Char;\n  ReadNum: Integer;\n  Value: string;\nbegin\n  Value := FirstChar;\n  repeat\n    ReadNum := Stream.Read(TempChar, 1 * SizeOf(Char));\n    if (ReadNum = 0) or not FWordChars[Ord(TempChar)] then\n      Break;\n    Value := Value + TempChar;\n  until False;\n\n  if ReadNum > 0 then\n    Stream.Seek(-(1 * SizeOf(Char)), soFromCurrent);\n  Result.TokenType := ttWord;\n  Result.Value := Value;\nend;\n\n{**\n  Establish characters in the given range as valid\n  characters for part of a word after the first character.\n  Note that the tokenizer must determine which characters\n  are valid as the beginning character of a word.\n  @param FromChar first character index.\n  @param ToChar last character index.\n  @param Enable true, if this state should ignore characters in the given range\n}\nprocedure TZWordState.SetWordChars(FromChar, ToChar: Char; Enable: Boolean);\nvar\n  I: Integer;\nbegin\n  for I := Ord(FromChar) to MinIntValue([Ord(ToChar), Ord(high(char)) ]) do\n    FWordChars[I] := Enable;\nend;\n\n{ TZTokenizer }\n\n{**\n  Constructs a tokenizer with a default state table (as\n  described in the class comment).\n}\nconstructor TZTokenizer.Create;\nbegin\n  FSymbolState := TZSymbolState.Create;\n  with TZSymbolState(FSymbolState) do\n  begin\n    Add('<>');\n    Add('<=');\n    Add('>=');\n  end;\n  FEscapeState := TZEscapeState.Create;\n  FNumberState := TZNumberState.Create;\n  FQuoteState := TZQuoteState.Create;\n  FWhitespaceState := TZWhitespaceState.Create;\n  FWordState := TZWordState.Create;\n  FCommentState := TZCppCommentState.Create;\n\n  SetCharacterState(#0, #32, FWhitespaceState);\n  SetCharacterState(#33, #191, FSymbolState);\n  SetCharacterState(#192, High(Char), FWordState);\n\n  SetCharacterState('a', 'z', FWordState);\n  SetCharacterState('A', 'Z', FWordState);\n  SetCharacterState('0', '9', FNumberState);\n  SetCharacterState('-', '-', FNumberState);\n  SetCharacterState('.', '.', FNumberState);\n  SetCharacterState('\"', '\"', FQuoteState);\n  SetCharacterState('''', '''', FQuoteState);\n  SetCharacterState('/', '/', FCommentState);\nend;\n\n{**\n  Destroys this object and cleanups the memory.\n}\ndestructor TZTokenizer.Destroy;\nbegin\n  if FEscapeState <> nil then\n    FEscapeState.Free;\n  if FCommentState <> nil then\n    FCommentState.Free;\n  if FNumberState <> nil then\n    FNumberState.Free;\n  if FQuoteState <> nil then\n    FQuoteState.Free;\n  if FSymbolState <> nil then\n    FSymbolState.Free;\n  if FWhitespaceState <> nil then\n    FWhitespaceState.Free;\n  if FWordState <> nil then\n    FWordState.Free;\n\n  inherited Destroy;\nend;\n\n{**\n  Gets an initial state object for the specified character.\n  @return an initial state object for the character.\n}\nfunction TZTokenizer.GetCharacterState(StartChar: Char): TZTokenizerState;\nbegin\n  Result := FCharacterStates[Ord(StartChar)];\nend;\n\n{**\n  Change the state the tokenizer will enter upon reading\n  any character between \"from\" and \"to\".\n\n  @param FromChar first character index.\n  @param ToChar last character index.\n  @param State the state to enter upon reading a\n    character between \"fromChar\" and \"toChar\"\n}\nprocedure TZTokenizer.SetCharacterState(FromChar, ToChar: Char;\n  State: TZTokenizerState);\nvar\n  I: Integer;\nconst\n  ORDMAXCHAR = ord(high(char));\nbegin\n  for I := Ord(FromChar) to MinIntValue([Ord(ToChar), ORDMAXCHAR]) do\n    FCharacterStates[I] := State;\nend;\n\n{**\n  Tokenizes a string buffer into a dynamic array of tokens.\n  @param Buffer a string buffer to be tokenized.\n  @param Options a set of tokenizer options.\n  @returns a dynamic array of tokens\n}\nfunction TZTokenizer.TokenizeBuffer(const Buffer: string;\n  Options: TZTokenOptions): TZTokenDynArray;\nvar\n  Stream: TStream;\nbegin\n  Stream := TStringStream.Create(Buffer{$IFDEF WITH_TENCODING_CLASS}, TEncoding.Unicode{$ENDIF});\n  try\n    Result := TokenizeStream(Stream, Options);\n  finally\n    Stream.Free;\n  end;\nend;\n\nfunction TZTokenizer.AnsiGetEscapeString(const EscapeString: RawByteString): String;\nvar\n  Temp: String;\nbegin\n  Temp := EscapeMarkSequence+IntToStr(Length(EscapeString))+ReverseString(EscapeMarkSequence);\n\n  if Length(EscapeString) > 0 then\n    Result := Temp+String(EscapeString)+Temp\n  else\n    Result := 'NULL';\nend;\n\n{$IF defined(FPC) and defined(WITH_RAWBYTESTRING)}\nfunction TZTokenizer.GetEscapeString(const EscapeString: RawByteString): RawByteString;\n{$ELSE}\nfunction TZTokenizer.GetEscapeString(const EscapeString: String): String;\n{$IFEND}\nvar\n  Temp: String;\nbegin\n  Temp := EscapeMarkSequence+IntToStr(Length(EscapeString))+ReverseString(EscapeMarkSequence);\n\n  if Length(EscapeString) > 0 then\n    {$IF defined(FPC) and defined(WITH_RAWBYTESTRING)}\n    Result := RawByteString(Temp)+EscapeString+RawByteString(Temp)\n    {$ELSE}\n    Result := Temp+EscapeString+Temp\n    {$IFEND}\n  else\n    Result := '';\nend;\n\n{**\n  EgonHugeist:\n  Checks if SymboState is EscapeState and sets it ...\n  @param Stream the Read-Stream which has to checked for Next-Chars.\n  @FirstChar The FirstChar which was readed and sets the Symbolstate\n  @returns either the given SymbolState or the EscapeState\n}\nfunction TZTokenizer.CheckEscapeState(const ActualState: TZTokenizerState;\n  Stream: TStream; const FirstChar: Char): TZTokenizerState;\nvar\n  NextChar: Char;\n  iReadCount, I: Integer;\nbegin\n  Result := ActualState;\n  iReadCount := 0;\n  if  ( FirstChar = EscapeMarkSequence[1]) then //Token was set so check if its Escape\n  begin\n    for i := 2 to Length(EscapeMarkSequence) do\n      if Stream.Read(NextChar, 1 * SizeOf(Char)) > 0  then //Read next Char\n      begin\n        Inc(IReadCount); //increment count of read-Chars\n        if NextChar <> EscapeMarkSequence[I] then //Compare Chars\n        begin\n          Stream.Seek(-(iReadCount * SizeOf(Char)), soFromCurrent); //Seek Stream back to starting Position\n          Exit;\n        end\n      end\n      else Continue;\n  end\n  else\n    Exit;\n  Stream.Seek(-(iReadCount * SizeOf(Char)), soFromCurrent); //Seek Stream back to starting Position\n  Result := Self.EscapeState;\nend;\n\n{**\n  Tokenizes a string buffer into a list of tokens.\n  @param Buffer a string buffer to be tokenized.\n  @param Options a set of tokenizer options.\n  @returns a string list where Items are tokens and\n    Objects are token types.\n}\nfunction TZTokenizer.TokenizeBufferToList(const Buffer: string;\n  Options: TZTokenOptions): TStrings;\nvar\n  Stream: TStream;\nbegin\n  Stream := TStringStream.Create(Buffer{$IFDEF WITH_TENCODING_CLASS}, TEncoding.Unicode{$ENDIF});\n  try\n    Result := TokenizeStreamToList(Stream, Options);\n  finally\n    Stream.Free;\n  end;\nend;\n\n{**\n  Tokenizes a stream into a dynamic array of tokens.\n  @param Stream a stream to be tokenized.\n  @param Options a set of tokenizer options.\n  @returns a dynamic array of tokens\n}\nfunction TZTokenizer.TokenizeStream(Stream: TStream;\n  Options: TZTokenOptions): TZTokenDynArray;\nvar\n  I: Integer;\n  List: TStrings;\nbegin\n  List := TokenizeStreamToList(Stream, Options);\n  try\n    SetLength(Result, List.Count);\n    for I := 0  to List.Count - 1 do\n    begin\n      Result[I].Value := List[I];\n      Result[I].TokenType := TZTokenType({$IFDEF FPC}Pointer({$ENDIF}\n        List.Objects[I]{$IFDEF FPC}){$ENDIF});\n    end;\n  finally\n    List.Free;\n  end;\nend;\n\n{**\n  Tokenizes a stream into a string list of tokens.\n  @param Stream a stream to be tokenized.\n  @param Options a set of tokenizer options.\n  @returns a string list where Items are tokens and\n    Objects are token types.\n}\nfunction TZTokenizer.TokenizeStreamToList(Stream: TStream;\n  Options: TZTokenOptions): TStrings;\nvar\n  FirstChar: Char;\n  Token: TZToken;\n  LastTokenType: TZTokenType;\n  State: TZTokenizerState;\nbegin\n  Result := TStringList.Create;\n  LastTokenType := ttUnknown;\n\n  while Stream.Read(FirstChar, 1 * SizeOf(Char)) > 0 do\n  begin\n    State := FCharacterStates[Ord(FirstChar)];\n    if State <> nil then\n    begin\n      State := CheckEscapeState(State, Stream, FirstChar);\n\n      Token := State.NextToken(Stream, FirstChar, Self);\n      { Decode strings. }\n      if (State is TZQuoteState)\n        and (toDecodeStrings in Options) then\n      begin\n        Token.Value := (State as TZQuoteState).DecodeString(\n          Token.Value, FirstChar);\n      end;\n      { Skips comments if option set. }\n      if (Token.TokenType = ttComment)\n        and (toSkipComments in Options) then\n        Continue;\n      { Skips whitespaces if option set. }\n      if (Token.TokenType = ttWhitespace)\n        and (toSkipWhitespaces in Options) then\n        Continue;\n      { Unifies whitespaces if option set. }\n      if (Token.TokenType = ttWhitespace)\n        and (toUnifyWhitespaces in Options) then\n      begin\n        if LastTokenType = ttWhitespace then\n          Continue;\n        Token.Value := ' ';\n      end;\n      { Unifies numbers if option set. }\n      if (Token.TokenType in [ttInteger, ttFloat, ttHexDecimal])\n        and (toUnifyNumbers in Options) then\n        Token.TokenType := ttNumber;\n      { If an integer is immediately followed by a string they should be seen as one string}\n      if ((Token.TokenType = ttWord)and(LastTokenType = ttInteger)) then\n      begin\n        Token.Value := Result[Result.Count-1] + Token.Value;\n        Result.Delete(Result.Count-1);\n      end;\n      { Add a read token. }\n      LastTokenType := Token.TokenType;\n      Result.AddObject(Token.Value, TObject(Ord(Token.TokenType)));\n    end\n    { Skips unknown chars if option set. }\n    else if not (toSkipUnknown in Options) then\n      Result.AddObject(FirstChar, TObject(Ord(ttUnknown)));\n  end;\n  { Adds an EOF if option is not set. }\n  if not (toSkipEOF in Options) then\n    Result.AddObject('', TObject(Ord(ttEOF)));\nend;\n\n{**\n  Gets a tokenizer default Escape state.\n  @returns a tokenizer default Escape state.\n}\nfunction TZTokenizer.GetEscapeState: TZEscapeState;\nbegin\n  Result := EscapeState;\nend;\n\n{**\n  Gets a tokenizer default comment state.\n  @returns a tokenizer default comment state.\n}\nfunction TZTokenizer.GetCommentState: TZCommentState;\nbegin\n  Result := CommentState;\nend;\n\n{**\n  Gets a tokenizer default number state.\n  @returns a tokenizer default number state.\n}\nfunction TZTokenizer.GetNumberState: TZNumberState;\nbegin\n  Result := NumberState;\nend;\n\n{**\n  Gets a tokenizer default quote state.\n  @returns a tokenizer default quote state.\n}\nfunction TZTokenizer.GetQuoteState: TZQuoteState;\nbegin\n  Result := QuoteState;\nend;\n\n{**\n  Gets a tokenizer default symbol state.\n  @returns a tokenizer default symbol state.\n}\nfunction TZTokenizer.GetSymbolState: TZSymbolState;\nbegin\n  Result := SymbolState;\nend;\n\n{**\n  Gets a tokenizer default whitespace state.\n  @returns a tokenizer default whitespace state.\n}\nfunction TZTokenizer.GetWhitespaceState: TZWhitespaceState;\nbegin\n  Result := WhitespaceState;\nend;\n\n{**\n  Gets a tokenizer default word state.\n  @returns a tokenizer default word state.\n}\nfunction TZTokenizer.GetWordState: TZWordState;\nbegin\n  Result := WordState;\nend;\n\nend.\n\n"
  },
  {
    "path": "lib/zeosdbo/src/core/ZURL.pas",
    "content": "{*********************************************************}\n{                                                         }\n{                 Zeos Database Objects                   }\n{            Test Case for TZURL Class                    }\n{                                                         }\n{*********************************************************}\n\n{@********************************************************}\n{    Copyright (c) 1999-2012 Zeos Development Group       }\n{                                                         }\n{ License Agreement:                                      }\n{                                                         }\n{ This library is distributed in the hope that it will be }\n{ useful, but WITHOUT ANY WARRANTY; without even the      }\n{ implied warranty of MERCHANTABILITY or FITNESS FOR      }\n{ A PARTICULAR PURPOSE.  See the GNU Lesser General       }\n{ Public License for more details.                        }\n{                                                         }\n{ The source code of the ZEOS Libraries and packages are  }\n{ distributed under the Library GNU General Public        }\n{ License (see the file COPYING / COPYING.ZEOS)           }\n{ with the following  modification:                       }\n{ As a special exception, the copyright holders of this   }\n{ library give you permission to link this library with   }\n{ independent modules to produce an executable,           }\n{ regardless of the license terms of these independent    }\n{ modules, and to copy and distribute the resulting       }\n{ executable under terms of your choice, provided that    }\n{ you also meet, for each linked independent module,      }\n{ the terms and conditions of the license of that module. }\n{ An independent module is a module which is not derived  }\n{ from or based on this library. If you modify this       }\n{ library, you may extend this exception to your version  }\n{ of the library, but you are not obligated to do so.     }\n{ If you do not wish to do so, delete this exception      }\n{ statement from your version.                            }\n{                                                         }\n{                                                         }\n{ The project web site is located on:                     }\n{   http://zeos.firmos.at  (FORUM)                        }\n{   http://sourceforge.net/p/zeoslib/tickets/ (BUGTRACKER)}\n{   svn://svn.code.sf.net/p/zeoslib/code-0/trunk (SVN)    }\n{                                                         }\n{   http://www.sourceforge.net/projects/zeoslib.          }\n{                                                         }\n{                                                         }\n{                                 Zeos Development Group. }\n{********************************************************@}\nunit ZURL;\n\ninterface\n{$I ZCore.inc}\n\nuses\n  Classes, {$IFDEF MSEgui}mclasses,{$ENDIF}\n  SysUtils;\n\ntype\n  TZURLStringList = Class(TStringList)\n  protected\n    function GetTextStr: string; override;\n    procedure SetTextStr(const Value: string); override;\n    function GetURLText: String;\n  public\n    property URLText: String read GetURLText;\n  end;\n\n  TZURL = class\n  private\n    FPrefix: string;\n    FProtocol: string;\n    FHostName: string;\n    FPort: Integer;\n    FDatabase: string;\n    FUserName: string;\n    FPassword: string;\n    FLibLocation: String;\n    FProperties: TZURLStringList;\n    FOnPropertiesChange: TNotifyEvent;\n    procedure SetPrefix(const Value: string);\n    procedure SetProtocol(const Value: string);\n    procedure SetHostName(const Value: string);\n    procedure SetConnPort(const Value: Integer);\n    function GetDatabase: string;\n    procedure SetDatabase(const Value: string);\n    function GetUserName: string;\n    procedure SetUserName(const Value: string);\n    function GetPassword: string;\n    procedure SetPassword(const Value: string);\n    function GetLibLocation: String;\n    procedure SetLibLocation(const Value: String);\n    function GetURL: string;\n    procedure SetURL(const Value: string);\n    procedure DoOnPropertiesChange(Sender: TObject);\n    function GetParamAndValue(AString: String; Var Param, Value: String): Boolean;\n    procedure AddValues(Values: TStrings);\n  public\n    constructor Create; overload;\n    constructor Create(const AURL: String); overload;\n    constructor Create(const AURL: String; Info: TStrings); overload;\n    constructor Create(const AURL: TZURL); overload;\n    constructor Create(Const AURL, AHostName: string; const APort: Integer;\n      const ADatabase, AUser, APassword: string; Info: TStrings); overload;\n\n    destructor Destroy; override;\n    property Prefix: string read FPrefix write SetPrefix;\n    property Protocol: string read FProtocol write SetProtocol;\n    property HostName: string read FHostName write SetHostName;\n    property Port: Integer read FPort write SetConnPort;\n    property Database: string read GetDatabase write SetDatabase;\n    property UserName: string read GetUserName write SetUserName;\n    property Password: string read GetPassword write SetPassword;\n    property LibLocation: string read GetLibLocation write SetLibLocation;\n    property Properties: TZURLStringList read FProperties;\n    property URL: string read GetURL write SetURL;\n\n    property OnPropertiesChange: TNotifyEvent read FOnPropertiesChange write FOnPropertiesChange;\n  end;\n\nimplementation\n\nuses ZCompatibility, StrUtils;\n\n{TZURLStringList}\nfunction TZURLStringList.GetTextStr: string;\nbegin\n  Result := inherited GetTextStr;\n  Result := StringReplace(Result, #9, ';', [rfReplaceAll]); //unescape the #9 char to ';'\nend;\n\nprocedure TZURLStringList.SetTextStr(const Value: string);\nbegin\n  inherited SetTextStr(StringReplace(Value, ';', #9, [rfReplaceAll])); //escape the ';' char to #9\nend;\n\nfunction TZURLStringList.GetURLText: String;\nbegin\n  Result := StringReplace(GetTextStr, ';', #9, [rfReplaceAll]); //keep all ';' escaped\n  Result := StringReplace(Result, LineEnding, ';', [rfReplaceAll]);  //return a URL-usable string\n  if Result[Length(Result)] = ';' then\n    Result := Copy(Result, 1, Length(Result)-1);\nend;\n\n{ TZURL }\n\nconstructor TZURL.Create;\nbegin\n  inherited;\n\n  FPrefix := 'zdbc';\n  FProperties := TZURLStringList.Create;\n  FProperties.CaseSensitive := False;\n  FProperties.NameValueSeparator := '=';\n  FProperties.OnChange := DoOnPropertiesChange;\nend;\n\nconstructor TZURL.Create(const AURL: String);\nbegin\n  Create;\n  Self.URL := AURL;\nend;\n\nconstructor TZURL.Create(const AURL: String; Info: TStrings);\nbegin\n  Create(AURL);\n  if Assigned(Info) then\n    AddValues(Info);\nend;\n\nconstructor TZURL.Create(const AURL: TZURL);\nbegin\n  Create(AURL.URL);\nend;\n\nconstructor TZURL.Create(Const AURL, AHostName: string; const APort: Integer;\n  const ADatabase, AUser, APassword: string; Info: TStrings);\nbegin\n  Create(AURL);\n  Self.HostName := AHostName;\n  Self.Port := APort;\n  Self.Database := ADataBase;\n  Self.UserName := AUser;\n  Self.Password := APassword;\n  if Assigned(Info) then\n    AddValues(Info);\nend;\n\ndestructor TZURL.Destroy;\nbegin\n  FProperties.Free;\n\n  inherited;\nend;\n\nprocedure TZURL.SetPrefix(const Value: string);\nbegin\n  FPrefix := Value;\nend;\n\nprocedure TZURL.SetProtocol(const Value: string);\nbegin\n  FProtocol := Value;\nend;\n\nprocedure TZURL.SetHostName(const Value: string);\nbegin\n  FHostName := StringReplace(Value, ';', #9, [rfReplaceAll]); //escape the ';' char to #9\nend;\n\nprocedure TZURL.SetConnPort(const Value: Integer);\nbegin\n  FPort := Value;\nend;\n\nfunction TZURL.GetDatabase: string;\nbegin\n  Result := StringReplace(FDatabase, #9, ';', [rfReplaceAll]); //unescape the #9 char to ';'\nend;\n\nprocedure TZURL.SetDatabase(const Value: string);\nbegin\n  FDatabase := StringReplace(Value, ';', #9, [rfReplaceAll]); //escape the ';' char to #9\nend;\n\nfunction TZURL.GetUserName: string;\nbegin\n  Result := StringReplace(FUserName, #9, ';', [rfReplaceAll]); //unescape the #9 char to ';'\nend;\n\nprocedure TZURL.SetUserName(const Value: string);\nbegin\n  FUserName := StringReplace(Value, ';', #9, [rfReplaceAll]); //escape the ';' char to #9\nend;\n\nfunction TZURL.GetPassword: string;\nbegin\n  Result := StringReplace(FPassword, #9, ';', [rfReplaceAll]); //unescape the #9 char to ';'\nend;\n\nprocedure TZURL.SetPassword(const Value: string);\nbegin\n  FPassword := StringReplace(Value, ';', #9, [rfReplaceAll]); //escape the ';' char to #9\nend;\n\nfunction TZURL.GetLibLocation: String;\nbegin\n  Result := StringReplace(FLibLocation, #9, ';', [rfReplaceAll]); //unescape the #9 char to ';'\nend;\n\nprocedure TZURL.SetLibLocation(const Value: String);\nbegin\n  FLibLocation := StringReplace(Value, ';', #9, [rfReplaceAll]); //escape the ';' char to #9\nend;\n\nfunction TZURL.GetURL: string;\nvar\n  hasParamPart : boolean;\n  procedure AddParamPart(const ParamPart: String);\n  begin\n    if hasParamPart then\n      Result := Result + ';'\n    else\n      Result := Result + '?';\n    Result := Result + ParamPart;\n    hasParamPart := True;\n  end;\n\nbegin\n  Result := '';\n  hasParamPart := false;\n\n  // Prefix\n  Result := Result + Prefix + ':';\n\n  // Protocol\n  Result := Result + Protocol + ':';\n\n  Result := Result + '//'; //Allways set the doubleslash  to avoid unix '/' path issues if host is empty\n\n  // HostName/Port\n  if HostName <> '' then\n  begin\n    Result := Result + HostName;\n    if Port <> 0 then\n      Result := Result + ':' + IntToStr(Port);\n  end;\n\n  // Database\n  if Database <> '' then\n    Result := Result + '/' + FDatabase;\n\n  // UserName\n  if FUserName <> '' then\n    AddParamPart('username=' + FUserName);\n\n  // Password\n  if FPassword <> '' then\n    AddParamPart('password=' + FPassword);\n\n  // Properties\n  if Properties.Count > 0 then\n    AddParamPart(Properties.GetURLText); //Adds the escaped string\n\n  // LibLocation\n    if FLibLocation <> '' then\n      AddParamPart('LibLocation='+ FLibLocation);\nend;\n\nprocedure TZURL.SetURL(const Value: string);\nvar\n  APrefix: string;\n  AProtocol: string;\n  AHostName: string;\n  APort: string;\n  ADatabase: string;\n  AUserName: string;\n  APassword: string;\n  AProperties: TStrings;\n  AValue: string;\n  I: Integer;\nbegin\n  APrefix := '';\n  AProtocol := '';\n  AHostName := '';\n  APort := '';\n  ADatabase := '';\n  AUserName := '';\n  APassword := '';\n  AProperties := TStringList.Create;\n\n  try\n    AValue := Value;\n\n    // APrefix\n    I := Pos(':', AValue);\n    if I = 0 then\n      raise Exception.Create('TZURL.SetURL - The prefix is missing');\n    APrefix := Copy(AValue, 1, I - 1);\n    Delete(AValue, 1, I);\n\n    // AProtocol\n    I := Pos(':', AValue);\n    if I = 0 then\n      raise Exception.Create('TZURL.SetURL - The protocol is missing');\n    AProtocol := Copy(AValue, 1, I - 1);\n    Delete(AValue, 1, I);\n\n    // AHostName\n    if Pos('//', AValue) = 1 then\n    begin\n      Delete(AValue, 1, 2);\n      if (Pos(':', AValue) > 0) and ((Pos(':', AValue) < Pos('/', AValue)) or (Pos('/', AValue)=0)) then\n        AHostName := Copy(AValue, 1, Pos(':', AValue) - 1)\n      else if Pos('/', AValue) > 0 then\n        AHostName := Copy(AValue, 1, Pos('/', AValue) - 1)\n      else if Pos('?', AValue) > 0 then\n        AHostName := Copy(AValue, 1, Pos('?', AValue) - 1)\n      else\n        AHostName := AValue;\n\n      Delete(AValue, 1, Length(AHostName));\n\n      // APort\n      if Pos(':', AValue) = 1 then\n      begin\n        Delete(AValue, 1, 1);\n        if Pos('/', AValue) > 0 then\n          APort := Copy(AValue, 1, Pos('/', AValue) - 1)\n        else if Pos('?', AValue) > 0 then\n          APort := Copy(AValue, 1, Pos('?', AValue) - 1)\n        else\n          APort := AValue;\n\n        Delete(AValue, 1, Length(APort));\n      end;\n    end;\n\n    if Pos('/', AValue) = 1 then\n      Delete(AValue, 1, 1);\n\n    // ADatabase\n    I := Pos('?', AValue);\n    if I > 0 then\n    begin\n      ADatabase := Copy(AValue, 1, I - 1);\n      Delete(AValue, 1, I);\n      AProperties.Text := StringReplace(AValue, ';', LineEnding, [rfReplaceAll]);\n    end\n    else\n      ADatabase := AValue;\n\n    FPrefix := APrefix;\n    FProtocol := AProtocol;\n    FHostName := AHostName;\n    FPort := StrToIntDef(APort, 0);\n    FDatabase := ADatabase;\n    FUserName := AUserName;\n    FPassword := APassword;\n    FProperties.Text := AProperties.Text;\n  finally\n    AProperties.Free;\n  end;\nend;\n\nprocedure TZURL.DoOnPropertiesChange(Sender: TObject);\nbegin\n  FProperties.OnChange := nil;\n  try\n    if FProperties.Values['UID'] <> '' then\n    begin\n      UserName := FProperties.Values['UID'];\n      FProperties.Delete(FProperties.IndexOfName('UID'));\n    end;\n\n    if FProperties.Values['PWD'] <> '' then\n    begin\n      Password := FProperties.Values['PWD'];\n      FProperties.Delete(FProperties.IndexOfName('PWD'));\n    end;\n\n    if FProperties.Values['username'] <> '' then\n    begin\n      UserName := FProperties.Values['username'];\n      FProperties.Delete(FProperties.IndexOfName('username'));\n    end;\n\n    if FProperties.Values['password'] <> '' then\n    begin\n      Password := FProperties.Values['password'];\n      FProperties.Delete(FProperties.IndexOfName('password'));\n    end;\n\n    if FProperties.Values['LibLocation'] <> '' then\n    begin\n      LibLocation := FProperties.Values['LibLocation'];\n      FProperties.Delete(FProperties.IndexOfName('LibLocation'));\n    end;\n\n  finally\n    FProperties.OnChange := DoOnPropertiesChange;\n  end;\n\n  if Assigned(FOnPropertiesChange) then\n    FOnPropertiesChange(Sender);\nend;\n\nfunction TZURL.GetParamAndValue(AString: String; Var Param, Value: String): Boolean;\nvar\n  DelimPos: Integer;\nbegin\n  DelimPos := PosEx('=', AString);\n  Result := DelimPos <> 0;\n  Param := '';\n  Value := '';\n  if DelimPos <> 0 then\n  begin\n    Param := Copy(AString, 1, DelimPos -1);\n    Value := Copy(AString, DelimPos+1, Length(AString)-DelimPos);\n    Result := Value <> ''; //avoid loosing empty but added Params. e.g TestIdentifierQuotes\n  end;\nend;\n\nprocedure TZURL.AddValues(Values: TStrings);\nvar\n  I: Integer;\n  Param, Value: String;\nbegin\n  for i := 0 to Values.Count -1 do\n    if GetParamAndValue(Values[i], Param, Value) then\n      FProperties.Values[Param] := Value\n    else\n      FProperties.Add(Values[i]);\nend;\n\nend.\n\n"
  },
  {
    "path": "lib/zeosdbo/src/core/ZVariables.pas",
    "content": "{*********************************************************}\n{                                                         }\n{                 Zeos Database Objects                   }\n{             Variables classes and interfaces            }\n{                                                         }\n{            Originally written by Sergey Seroukhov       }\n{                                                         }\n{*********************************************************}\n\n{@********************************************************}\n{    Copyright (c) 1999-2012 Zeos Development Group       }\n{                                                         }\n{ License Agreement:                                      }\n{                                                         }\n{ This library is distributed in the hope that it will be }\n{ useful, but WITHOUT ANY WARRANTY; without even the      }\n{ implied warranty of MERCHANTABILITY or FITNESS FOR      }\n{ A PARTICULAR PURPOSE.  See the GNU Lesser General       }\n{ Public License for more details.                        }\n{                                                         }\n{ The source code of the ZEOS Libraries and packages are  }\n{ distributed under the Library GNU General Public        }\n{ License (see the file COPYING / COPYING.ZEOS)           }\n{ with the following  modification:                       }\n{ As a special exception, the copyright holders of this   }\n{ library give you permission to link this library with   }\n{ independent modules to produce an executable,           }\n{ regardless of the license terms of these independent    }\n{ modules, and to copy and distribute the resulting       }\n{ executable under terms of your choice, provided that    }\n{ you also meet, for each linked independent module,      }\n{ the terms and conditions of the license of that module. }\n{ An independent module is a module which is not derived  }\n{ from or based on this library. If you modify this       }\n{ library, you may extend this exception to your version  }\n{ of the library, but you are not obligated to do so.     }\n{ If you do not wish to do so, delete this exception      }\n{ statement from your version.                            }\n{                                                         }\n{                                                         }\n{ The project web site is located on:                     }\n{   http://zeos.firmos.at  (FORUM)                        }\n{   http://sourceforge.net/p/zeoslib/tickets/ (BUGTRACKER)}\n{   svn://svn.code.sf.net/p/zeoslib/code-0/trunk (SVN)    }\n{                                                         }\n{   http://www.sourceforge.net/projects/zeoslib.          }\n{                                                         }\n{                                                         }\n{                                 Zeos Development Group. }\n{********************************************************@}\n\nunit ZVariables;\n\ninterface\n\n{$I ZCore.inc}\n\nuses SysUtils, Classes, Contnrs, ZCompatibility, ZVariant, ZExpression;\n\ntype\n  {** Implements a variable holder object. }\n  TZVariable = class (TObject)\n  private\n    FName: string;\n    FValue: TZVariant;\n  public\n    constructor Create(const Name: string; const Value: TZVariant);\n\n    property Name: string read FName write FName;\n    property Value: TZVariant read FValue write FValue;\n  end;\n\n  {** Implements a variables list. }\n  TZVariablesList = class (TInterfacedObject, IZVariablesList)\n  private\n    FVariables: TObjectList;\n  public\n    constructor Create;\n    destructor Destroy; override;\n\n    function GetCount: Integer;\n    function GetName(Index: Integer): string;\n    function GetValue(Index: Integer): TZVariant;\n    procedure SetValue(Index: Integer; const Value: TZVariant);\n    function GetValueByName(const Name: string): TZVariant;\n    procedure SetValueByName(const Name: string; const Value: TZVariant);\n\n    procedure Add(const Name: string; const Value: TZVariant);\n    procedure Remove(const Name: string);\n    function FindByName(const Name: string): Integer;\n\n    procedure ClearValues;\n    procedure Clear;\n  end;\n\nimplementation\n\nuses ZMessages;\n\n{ TZVariable }\n\n{**\n  Creates a new instance of variable\n  @param Name a variable name.\n  @param Value a variable value.\n}\nconstructor TZVariable.Create(const Name: string; const Value: TZVariant);\nbegin\n  FName := Name;\n  FValue := Value;\nend;\n\n{ TZVariablesList }\n\n{**\n  Creates this variable list object.\n}\nconstructor TZVariablesList.Create;\nbegin\n  FVariables := TObjectList.Create(True);\nend;\n\n{**\n  Destroys this object and cleanups the memory.\n}\ndestructor TZVariablesList.Destroy;\nbegin\n  FVariables.Clear;\n  FreeAndNil(FVariables);\n  inherited Destroy;\nend;\n\n{**\n  Finds a variable by specified name.\n  @param Name a name of the variable.\n  @returns a found variable index or <code>-1</code> otherwise.\n}\nfunction TZVariablesList.FindByName(const Name: string): Integer;\nvar\n  I: Integer;\n  Current: TZVariable;\n  UpperName: string;\nbegin\n  Result := -1;\n  UpperName := UpperCase(Name);\n  for I := 0 to FVariables.Count - 1 do\n  begin\n    Current := TZVariable(FVariables[I]);\n    if Current.Name = UpperName then\n    begin\n      Result := I;\n      Break;\n    end;\n  end;\nend;\n\n{**\n  Adds a new variable with value.\n  @param Name a name of the new variable.\n  @param Value a value for the new variable.\n}\nprocedure TZVariablesList.Add(const Name: string; const Value: TZVariant);\nbegin\n  if FindByName(Name) >= 0 then\n    raise Exception.Create(Format(SVariableAlreadyExists, [Name]));\n  FVariables.Add(TZVariable.Create(UpperCase(Name), Value));\nend;\n\n{**\n  Removes a variable by specified name.\n  @param Name a name of variable to be removed.\n}\nprocedure TZVariablesList.Remove(const Name: string);\nvar\n  Index: Integer;\nbegin\n  Index := FindByName(Name);\n  if Index >= 0 then\n    FVariables.Delete(Index);\nend;\n\n{**\n  Clears all variables.\n}\nprocedure TZVariablesList.Clear;\nbegin\n  FVariables.Clear;\nend;\n\n{**\n  Clears only variable values.\n}\nprocedure TZVariablesList.ClearValues;\nvar\n  I: Integer;\nbegin\n  for I := 0 to FVariables.Count - 1 do\n    TZVariable(FVariables[I]).Value := NullVariant;\nend;\n\n{**\n  Gets a number of registered variables.\n  @returns a number of all registered variables.\n}\nfunction TZVariablesList.GetCount: Integer;\nbegin\n  Result := FVariables.Count;\nend;\n\n{**\n  Gets a variable name by it's index.\n  @param Index a variable index.\n  @returns a variable name.\n}\nfunction TZVariablesList.GetName(Index: Integer): string;\nbegin\n  Result := TZVariable(FVariables[Index]).Name;\nend;\n\n{**\n  Gets a variable value by it's index.\n  @param Index a variable index.\n  @returns a variable value\n}\nfunction TZVariablesList.GetValue(Index: Integer): TZVariant;\nbegin\n  Result := TZVariable(FVariables[Index]).Value;\nend;\n\n{**\n  Gets a variable name by it's name.\n  @param Name a variable name.\n  @returns a variable value.\n}\nfunction TZVariablesList.GetValueByName(const Name: string): TZVariant;\nvar\n  Index: Integer;\nbegin\n  Index := FindByName(Name);\n  if Index >= 0 then\n    Result := TZVariable(FVariables[Index]).Value\n  else\n    Result := NullVariant;\nend;\n\n{**\n  Sets a variable name by it's index.\n  @param Index a variable index.\n  @param Value a variable value.\n}\nprocedure TZVariablesList.SetValue(Index: Integer; const Value: TZVariant);\nbegin\n  TZVariable(FVariables[Index]).Value := Value;\nend;\n\n{**\n  Sets a variable name by it's name.\n  @param Index a variable name.\n  @param Value a variable value.\n}\nprocedure TZVariablesList.SetValueByName(const Name: string; const Value: TZVariant);\nvar\n  Index: Integer;\nbegin\n  Index := FindByName(Name);\n  if Index >= 0 then\n    TZVariable(FVariables[Index]).Value := Value\n  else\n    Add(Name, Value);\nend;\n\nend.\n"
  },
  {
    "path": "lib/zeosdbo/src/core/ZVariant.pas",
    "content": "{*********************************************************}\n{                                                         }\n{                 Zeos Database Objects                   }\n{               Variant Processing Classes                }\n{                                                         }\n{            Originally written by Sergey Seroukhov       }\n{                                                         }\n{*********************************************************}\n\n{@********************************************************}\n{    Copyright (c) 1999-2012 Zeos Development Group       }\n{                                                         }\n{ License Agreement:                                      }\n{                                                         }\n{ This library is distributed in the hope that it will be }\n{ useful, but WITHOUT ANY WARRANTY; without even the      }\n{ implied warranty of MERCHANTABILITY or FITNESS FOR      }\n{ A PARTICULAR PURPOSE.  See the GNU Lesser General       }\n{ Public License for more details.                        }\n{                                                         }\n{ The source code of the ZEOS Libraries and packages are  }\n{ distributed under the Library GNU General Public        }\n{ License (see the file COPYING / COPYING.ZEOS)           }\n{ with the following  modification:                       }\n{ As a special exception, the copyright holders of this   }\n{ library give you permission to link this library with   }\n{ independent modules to produce an executable,           }\n{ regardless of the license terms of these independent    }\n{ modules, and to copy and distribute the resulting       }\n{ executable under terms of your choice, provided that    }\n{ you also meet, for each linked independent module,      }\n{ the terms and conditions of the license of that module. }\n{ An independent module is a module which is not derived  }\n{ from or based on this library. If you modify this       }\n{ library, you may extend this exception to your version  }\n{ of the library, but you are not obligated to do so.     }\n{ If you do not wish to do so, delete this exception      }\n{ statement from your version.                            }\n{                                                         }\n{                                                         }\n{ The project web site is located on:                     }\n{   http://zeos.firmos.at  (FORUM)                        }\n{   http://sourceforge.net/p/zeoslib/tickets/ (BUGTRACKER)}\n{   svn://svn.code.sf.net/p/zeoslib/code-0/trunk (SVN)    }\n{                                                         }\n{   http://www.sourceforge.net/projects/zeoslib.          }\n{                                                         }\n{                                                         }\n{                                 Zeos Development Group. }\n{********************************************************@}\n\nunit ZVariant;\n\ninterface\n\n{$I ZCore.inc}\n\nuses\n  {$IFNDEF FPC}\n  Windows, //need for inline\n  {$ENDIF}\n  Classes, SysUtils, Types, ZCompatibility, ZClasses, ZSysUtils;\n\nconst\n  {** Precision for float values comparison }\n  FLOAT_COMPARE_PRECISION = 1.0e-5;\n  FLOAT_COMPARE_PRECISION_SINGLE = 1.5e-5;\n\n  {FPC - Compatibility for SQLite (currently) }\n  JULIAN_DAY_DISTANCE = 2415018.5; //distance from \"julian day 0\" (January 1, 4713 BC 12:00AM) to \"1899-12-30 00:00AM\"}\n\ntype\n  {** Defines variant types. }\n  TZVariantType = (vtNull, vtBoolean, vtInteger, vtFloat, vtBytes,\n    vtString, vtAnsiString, vtUTF8String, vtRawByteString, vtUnicodeString, //String Types\n    vtDateTime, vtPointer, vtInterface);\n\n  {** Defines a variant structure. }\n  TZVariant = {$ifndef FPC_REQUIRES_PROPER_ALIGNMENT}packed{$endif} record\n    VType: TZVariantType;\n    VString: String;\n    VAnsiString: AnsiString;\n    VRawByteString: RawByteString;\n    VUTF8String: UTF8String;\n    VUnicodeString: ZWideString;\n    VBytes: TByteDynArray;\n    VInterface: IZInterface;\n    case TZVariantType of\n      vtBoolean: (VBoolean: Boolean);\n      vtInteger: (VInteger: Int64);\n      vtFloat: (VFloat: Extended);\n      VtDateTime: (VDateTime: Double);  // M.A. was TDateTime\n      VtPointer: (VPointer: Pointer);\n  end;\n\n  PZVariant = ^TZVariant;\n\n  {** Defines an array of variants. }\n  TZVariantDynArray = array of TZVariant;\n\n  {** Defines a variant processing exception. }\n  EZVariantException = class (Exception);\n\n  {** Defines an interface for variant data. }\n  {** Defines a Variant Manager interface. }\n  IZVariantManager = interface (IZInterface)\n    ['{DAA373D9-1A98-4AA8-B65E-4C23167EE83F}']\n\n    function IsNull(const Value: TZVariant): Boolean;\n    procedure SetNull(var Value: TZVariant);\n\n    function Convert(const Value: TZVariant; NewType: TZVariantType): TZVariant;\n    procedure Assign(const SrcValue: TZVariant; var DstValue: TZVariant);\n    function Clone(const Value: TZVariant): TZVariant;\n    function Compare(const Value1, Value2: TZVariant): Integer;\n\n    function GetAsBoolean(const Value: TZVariant): Boolean;\n    function GetAsBytes(const Value: TZVariant): TByteDynArray;\n    function GetAsInteger(const Value: TZVariant): Int64;\n    function GetAsFloat(const Value: TZVariant): Extended;\n    function GetAsString(const Value: TZVariant): String;\n    function GetAsAnsiString(const Value: TZVariant): AnsiString;\n    function GetAsRawByteString(const Value: TZVariant): RawByteString; overload;\n    function GetAsUTF8String(const Value: TZVariant): UTF8String;\n    function GetAsUnicodeString(const Value: TZVariant): ZWideString;\n    function GetAsDateTime(const Value: TZVariant): TDateTime;\n    function GetAsPointer(const Value: TZVariant): Pointer;\n    function GetAsInterface(const Value: TZVariant): IZInterface;\n\n    procedure SetAsBoolean(var Value: TZVariant; Data: Boolean);\n    procedure SetAsBytes(var Value: TZVariant; const Data: TByteDynArray);\n    procedure SetAsInteger(var Value: TZVariant; Data: Int64);\n    procedure SetAsFloat(var Value: TZVariant; Data: Extended);\n    procedure SetAsString(var Value: TZVariant; const Data: String);\n    procedure SetAsAnsiString(var Value: TZVariant; const Data: AnsiString);\n    procedure SetAsUTF8String(var Value: TZVariant; const Data: UTF8String);\n    procedure SetAsRawByteString(var Value: TZVariant; const Data: RawByteString);\n    procedure SetAsUnicodeString(var Value: TZVariant; const Data: ZWideString);\n    procedure SetAsDateTime(var Value: TZVariant; Data: TDateTime);\n    procedure SetAsPointer(var Value: TZVariant; Data: Pointer);\n    procedure SetAsInterface(var Value: TZVariant; Data: IZInterface);\n\n    function OpAdd(const Value1, Value2: TZVariant): TZVariant;\n    function OpSub(const Value1, Value2: TZVariant): TZVariant;\n    function OpMul(const Value1, Value2: TZVariant): TZVariant;\n    function OpDiv(const Value1, Value2: TZVariant): TZVariant;\n    function OpMod(const Value1, Value2: TZVariant): TZVariant;\n    function OpPow(const Value1, Value2: TZVariant): TZVariant;\n    function OpAnd(const Value1, Value2: TZVariant): TZVariant;\n    function OpOr(const Value1, Value2: TZVariant): TZVariant;\n    function OpXor(const Value1, Value2: TZVariant): TZVariant;\n    function OpNot(const Value: TZVariant): TZVariant;\n    function OpNegative(const Value: TZVariant): TZVariant;\n    function OpEqual(const Value1, Value2: TZVariant): TZVariant;\n    function OpNotEqual(const Value1, Value2: TZVariant): TZVariant;\n    function OpMore(const Value1, Value2: TZVariant): TZVariant;\n    function OpLess(const Value1, Value2: TZVariant): TZVariant;\n    function OpMoreEqual(const Value1, Value2: TZVariant): TZVariant;\n    function OpLessEqual(const Value1, Value2: TZVariant): TZVariant;\n  end;\n\n  {** Implements a variant manager with strict convertion rules. }\n  TZDefaultVariantManager = class (TInterfacedObject, IZVariantManager)\n  private\n    ZAnsiToUTF8: TZAnsiToUTF8;\n    ZUTF8ToAnsi: TZUTF8ToAnsi;\n    ZUTF8ToString: TZUTF8ToString;\n    ZStringToUTF8: TZStringToUTF8;\n    FSystemCodePage: Word;\n  protected\n    procedure RaiseTypeMismatchError;\n    procedure RaiseUnsupportedOperation;\n  public\n    constructor Create;\n    function Convert(const Value: TZVariant; NewType: TZVariantType): TZVariant;\n      virtual;\n    procedure Assign(const SrcValue: TZVariant; var DstValue: TZVariant);\n    function Clone(const Value: TZVariant): TZVariant;\n    function Compare(const Value1, Value2: TZVariant): Integer;\n\n    function IsNull(const Value: TZVariant): Boolean;\n    procedure SetNull(var Value: TZVariant);\n\n    function GetAsBoolean(const Value: TZVariant): Boolean;\n    function GetAsBytes(const Value: TZVariant): TByteDynArray;\n    function GetAsInteger(const Value: TZVariant): Int64;\n    function GetAsFloat(const Value: TZVariant): Extended;\n    function GetAsString(const Value: TZVariant): String;\n    function GetAsAnsiString(const Value: TZVariant): AnsiString;\n    function GetAsUTF8String(const Value: TZVariant): UTF8String;\n    function GetAsRawByteString(const Value: TZVariant): RawByteString; overload;\n    function GetAsUnicodeString(const Value: TZVariant): ZWideString;\n    function GetAsDateTime(const Value: TZVariant): TDateTime;\n    function GetAsPointer(const Value: TZVariant): Pointer;\n    function GetAsInterface(const Value: TZVariant): IZInterface;\n\n    procedure SetAsBoolean(var Value: TZVariant; Data: Boolean);\n    procedure SetAsBytes(var Value: TZVariant; const Data: TByteDynArray);\n    procedure SetAsInteger(var Value: TZVariant; Data: Int64);\n    procedure SetAsFloat(var Value: TZVariant; Data: Extended);\n    procedure SetAsString(var Value: TZVariant; const Data: String);\n    procedure SetAsAnsiString(var Value: TZVariant; const Data: AnsiString);\n    procedure SetAsUTF8String(var Value: TZVariant; const Data: UTF8String);\n    procedure SetAsRawByteString(var Value: TZVariant; const Data: RawByteString);\n    procedure SetAsUnicodeString(var Value: TZVariant; const Data: ZWideString);\n    procedure SetAsDateTime(var Value: TZVariant; Data: TDateTime);\n    procedure SetAsPointer(var Value: TZVariant; Data: Pointer);\n    procedure SetAsInterface(var Value: TZVariant; Data: IZInterface);\n\n    function OpAdd(const Value1, Value2: TZVariant): TZVariant;\n    function OpSub(const Value1, Value2: TZVariant): TZVariant;\n    function OpMul(const Value1, Value2: TZVariant): TZVariant;\n    function OpDiv(const Value1, Value2: TZVariant): TZVariant;\n    function OpMod(const Value1, Value2: TZVariant): TZVariant;\n    function OpPow(const Value1, Value2: TZVariant): TZVariant;\n    function OpAnd(const Value1, Value2: TZVariant): TZVariant;\n    function OpOr(const Value1, Value2: TZVariant): TZVariant;\n    function OpXor(const Value1, Value2: TZVariant): TZVariant;\n    function OpNot(const Value: TZVariant): TZVariant;\n    function OpNegative(const Value: TZVariant): TZVariant;\n    function OpEqual(const Value1, Value2: TZVariant): TZVariant;\n    function OpNotEqual(const Value1, Value2: TZVariant): TZVariant;\n    function OpMore(const Value1, Value2: TZVariant): TZVariant;\n    function OpLess(const Value1, Value2: TZVariant): TZVariant;\n    function OpMoreEqual(const Value1, Value2: TZVariant): TZVariant;\n    function OpLessEqual(const Value1, Value2: TZVariant): TZVariant;\n  end;\n\n  {** Implements a variant manager with soft convertion rules. }\n  TZSoftVariantManager = class (TZDefaultVariantManager)\n  public\n    function Convert(const Value: TZVariant; NewType: TZVariantType): TZVariant;\n      override;\n  end;\n\n  IZClientVariantManager = Interface(IZVariantManager)\n    ['{73A1A2C7-7C38-4620-B7FE-2426BF839BE5}']\n    function GetAsRawByteString(const Value: TZVariant; const RawCP: Word): RawByteString; overload;\n  End;\n\n  {** Implements a variant manager with connection related convertion rules. }\n  TZClientVariantManager = class (TZDefaultVariantManager, IZClientVariantManager)\n  private\n    FConSettings: PZConSettings;\n  public\n    constructor Create(const ConSettings: PZConSettings);\n    function Convert(const Value: TZVariant; NewType: TZVariantType): TZVariant;\n      override;\n    function GetAsRawByteString(const Value: TZVariant; const RawCP: Word): RawByteString; overload;\n  end;\n\ntype\n\n  {** Represents any value interface. }\n  IZAnyValue = interface (IZClonnable)\n    ['{E81988B3-FD0E-4524-B658-B309B02F0B6A}']\n\n    function IsNull: Boolean;\n    function GetValue: TZVariant;\n\n    function GetBoolean: Boolean;\n    function GetBytes: TByteDynArray;\n    function GetInteger: Int64;\n    function GetFloat: Extended;\n    function GetString: String;\n    function GetAnsiString: AnsiString;\n    function GetUTF8String: UTF8String;\n    function GetUnicodeString: ZWideString;\n    function GetDateTime: TDateTime;\n  end;\n\n  {** Implements an any value object. }\n  TZAnyValue = class(TZAbstractObject, IZAnyValue, IZComparable)\n  private\n    FValue: TZVariant;\n  public\n    constructor Create(const Value: TZVariant);\n    constructor CreateWithBoolean(Value: Boolean);\n    constructor CreateWithInteger(Value: Int64);\n    constructor CreateWithFloat(Value: Extended);\n    constructor CreateWithString(const Value: String);\n    {$IFDEF UNICODE}\n    // unicodeType is a (dummy) default parameter to avoid\n    // the problem described in https://forums.codegear.com/thread.jspa?messageID=65681\n    // when dcc creates header (.hpp)-files for c++ builder. Both 'String' and\n    // 'UnicodeString' translate into 'UnicodeString' in C++ builder 2009/2010, and\n    // CreateWithString and CreateWithUnicodeString would result in duplicate\n    // C++ constructors.\n    constructor CreateWithUnicodeString(const Value: String; unicodeType: Boolean=true);\n    {$ELSE}\n    constructor CreateWithUnicodeString(const Value: WideString);\n    {$ENDIF}\n    constructor CreateWithDateTime(Value: TDateTime);\n\n    function IsNull: Boolean;\n    function GetValue: TZVariant;\n\n    function GetBoolean: Boolean;\n    function GetBytes: TByteDynArray;\n    function GetInteger: Int64;\n    function GetFloat: Extended;\n    function GetString: String;\n    function GetAnsiString: AnsiString;\n    function GetUTF8String: UTF8String;\n    function GetUnicodeString: ZWideString;\n    function GetDateTime: TDateTime;\n\n    function Equals(const Value: IZInterface): Boolean; override;\n    function Clone: IZInterface; override;\n    function ToString: string; override;\n  end;\n\n{**\n  Encodes a custom variant value into standard variant.\n  @param Value a custom variant value to be encoded.\n  @returns an encoded standard variant.\n}\nfunction EncodeVariant(const Value: TZVariant): Variant;\n\n{**\n  Encodes an array of custom variant values into array of standard variants.\n  @param Value an array of custom variant values to be encoded.\n  @returns an encoded array of standard variants.\n}\nfunction EncodeVariantArray(const Value: TZVariantDynArray): Variant;\n\n{**\n  Decodes a standard variant value into custom variant.\n  @param Value a standard variant value to be decoded.\n  @returns an decoded custom variant.\n}\nfunction DecodeVariant(const Value: Variant): TZVariant;\n\n{**\n  Decodes an array of standard variant values into array of custom variants.\n  @param Value an array of standard variant values to be decoded.\n  @returns an decoded array of custom variants.\n}\nfunction DecodeVariantArray(const Value: Variant): TZVariantDynArray;\n\n{**\n  Encodes null into a custom variant.\n  @returns an decoded custom variant.\n}\nfunction EncodeNull : TZVariant;\n{**\n  Encodes a boolean into a custom variant.\n  @param Value a boolean value to be encoded.\n  @returns an encoded custom variant.\n}\nfunction EncodeBoolean(const Value: Boolean): TZVariant;\n{**\n  Encodes a Byte array into a custom variant.\n  @param Value a boolean value to be encoded.\n  @returns an encoded custom variant.\n}\nfunction EncodeBytes(const Value: TByteDynArray): TZVariant;\n{**\n  Encodes an integer into a custom variant.\n  @param Value an intger value to be encoded.\n  @returns an encoded custom variant.\n}\nfunction EncodeInteger(const Value: Int64): TZVariant;\n{**\n  Encodes a float into a custom variant.\n  @param Value a float value to be encoded.\n  @returns an encoded custom variant.\n}\nfunction EncodeFloat(const Value: Extended): TZVariant;\n{**\n  Encodes a String into a custom variant.\n  @param Value a String value to be encoded.\n  @returns an encoded custom variant.\n}\nfunction EncodeString(const Value: String): TZVariant;\n{**\n  Encodes a AnsiString into a custom variant.\n  @param Value a AnsiString value to be encoded.\n  @returns an encoded custom variant.\n}\nfunction EncodeAnsiString(const Value: AnsiString): TZVariant;\n{**\n  Encodes a UTF8String into a custom variant.\n  @param Value a UTF8String value to be encoded.\n  @returns an encoded custom variant.\n}\nfunction EncodeUTF8String(const Value: UTF8String): TZVariant;\n{**\n  Encodes a RawByteString into a custom variant.\n  @param Value a RawByteString value to be encoded.\n  @param CP the CoodePage of the Value string.\n  @returns an encoded custom variant.\n}\nfunction EncodeRawByteString(const Value: RawByteString): TZVariant;\n{**\n  Encodes a unicodestring into a custom variant.\n  @param Value a unicodestring value to be encoded.\n  @returns an encoded custom variant.\n}\nfunction EncodeUnicodeString(const Value: ZWideString): TZVariant;\n{**\n  Encodes a TDateTime into a custom variant.\n  @param Value a TDateTime value to be encoded.\n  @returns an encoded custom variant.\n}\nfunction EncodeDateTime(const Value: TDateTime): TZVariant;\n{**\n  Encodes a pointer into a custom variant.\n  @param Value a pointer value to be encoded.\n  @returns an encoded custom variant.\n}\nfunction EncodePointer(const Value: Pointer): TZVariant;\n{**\n  Encodes an interface into a custom variant.\n  @param Value an interface value to be encoded.\n  @returns an encoded custom variant.\n}\nfunction EncodeInterface(const Value: IZInterface): TZVariant;\n\nvar\n  {** Declares a default variant manager with strict convertion rules. }\n  DefVarManager: IZVariantManager;\n\n  {** Declares a variant manager with soft convertion rules. }\n  SoftVarManager: IZVariantManager;\n\n  {** A NULL Variant Value. }\n  NullVariant: TZVariant;\n\nimplementation\n\nuses\n  Variants, Math, ZMessages, ZEncoding\n  {$IFDEF WITH_ANSISTRCOMP_DEPRECATED}, AnsiStrings{$ENDIF};\n\n{ TZDefaultVariantManager }\n\n{**\n  Constructs this object and assignes the main properties.\n}\nconstructor TZDefaultVariantManager.Create;\nbegin\n  inherited;\n  FSystemCodePage := ZDefaultSystemCodePage;\n  if ZCompatibleCodePages(zCP_UTF8, FSystemCodePage) then\n  begin\n    ZAnsiToUTF8 := @ZMoveAnsiToUTF8;\n    ZUTF8ToAnsi := @ZMoveUTF8ToAnsi;\n    ZUTF8ToString := @ZMoveUTF8ToString;\n    ZStringToUTF8 := @ZMoveStringToUTF8;\n  end\n  else\n  begin\n    ZAnsiToUTF8 := @ZConvertAnsiToUTF8;\n    ZUTF8ToAnsi := @ZConvertUTF8ToAnsi;\n    ZUTF8ToString := @ZConvertUTF8ToString;\n    ZStringToUTF8 := @ZConvertStringToUTF8;\n  end;\nend;\n\n{**\n  Assignes one variant value to another one.\n  @param SrcValue a source variant value.\n  @param DstValue a destination variant value.\n}\nprocedure TZDefaultVariantManager.Assign(const SrcValue: TZVariant;\n  var DstValue: TZVariant);\nbegin\n  DstValue.VType := SrcValue.VType;\n  case SrcValue.VType of\n    vtBoolean: DstValue.VBoolean := SrcValue.VBoolean;\n    vtBytes: DstValue.VBytes := SrcValue.VBytes;\n    vtInteger: DstValue.VInteger := SrcValue.VInteger;\n    vtFloat: DstValue.VFloat := SrcValue.VFloat;\n    vtString: DstValue.VString := SrcValue.VString;\n    vtAnsiString: DstValue.VAnsiString := SrcValue.VAnsiString;\n    vtRawByteString: DstValue.VRawByteString := SrcValue.VRawByteString;\n    vtUTF8String: DstValue.VUTF8String := SrcValue.VUTF8String;\n    vtUnicodeString: DstValue.VUnicodeString := SrcValue.VUnicodeString;\n    vtDateTime: DstValue.VDateTime := SrcValue.VDateTime;\n    vtPointer: DstValue.VPointer := SrcValue.VPointer;\n    vtInterface: DstValue.VInterface := SrcValue.VInterface;\n  end;\nend;\n\n{**\n  Clones a variant value.\n  @param Value a source variant value.\n  @returns a clonned variant value.\n}\nfunction TZDefaultVariantManager.Clone(const Value: TZVariant): TZVariant;\nbegin\n  Assign(Value, Result);\nend;\n\n{**\n  Raises a type mismatch exception.\n}\nprocedure TZDefaultVariantManager.RaiseTypeMismatchError;\nbegin\n  raise EZVariantException.Create(STypesMismatch);\nend;\n\n{**\n  Raises an unsupported operation exception.\n}\nprocedure TZDefaultVariantManager.RaiseUnsupportedOperation;\nbegin\n  raise EZVariantException.Create(SUnsupportedOperation);\nend;\n\n{**\n  Converts a specified variant value to a new type.\n  @param Value a variant value to be converted.\n  @param NewType a type of the result variant value.\n  @returns a converted variant value.\n}\nfunction TZDefaultVariantManager.Convert(const Value: TZVariant;\n  NewType: TZVariantType): TZVariant;\nbegin\n  Result.VType := NewType;\n  case NewType of\n    vtBoolean:\n      case Value.VType of\n        vtNull:\n          Result.VBoolean := False;\n        vtBoolean:\n          Result.VBoolean := Value.VBoolean;\n        else\n          RaiseTypeMismatchError;\n      end;\n    vtBytes:\n      case Value.VType of\n        vtNull:\n          Result.VBytes := nil;\n        vtBytes:\n          Result.VBytes := Value.VBytes;\n        vtString:\n          Result.VBytes := StrToBytes(Value.VString);\n        vtAnsiString:\n          Result.VBytes := StrToBytes(Value.VAnsiString);\n        vtRawByteString:\n          Result.VBytes := StrToBytes(Value.VRawByteString);\n        vtUTF8String:\n          Result.VBytes := StrToBytes(Value.VUTF8String);\n        vtUnicodeString:\n          Result.VBytes := StrToBytes(Value.VUnicodeString);\n        else\n          RaiseTypeMismatchError;\n      end;\n    vtInteger:\n      case Value.VType of\n        vtNull:\n          Result.VInteger := 0;\n        vtBoolean:\n          if Value.VBoolean then\n            Result.VInteger := 1\n          else\n            Result.VInteger := 0;\n        vtInteger:\n          Result.VInteger := Value.VInteger;\n        else\n          RaiseTypeMismatchError;\n      end;\n    vtFloat:\n      case Value.VType of\n        vtNull:\n          Result.VFloat := 0;\n        vtBoolean:\n          if Value.VBoolean then\n            Result.VFloat := 1\n          else\n            Result.VFloat := 0;\n        vtInteger:\n          Result.VFloat := Value.VInteger;\n        vtFloat:\n          Result.VFloat := Value.VFloat;\n        else\n          RaiseTypeMismatchError;\n      end;\n    vtString:\n      case Value.VType of\n        vtNull:\n          Result.VString := '';\n        vtBytes:\n          Result.VString := {$IFDEF UNICODE}String{$ENDIF}(BytesToStr(Value.VBytes));\n        vtString:\n          Result.VString := Value.VString;\n        vtAnsiString:\n          Result.VString := {$IFDEF UNICODE}String{$ENDIF}(Value.VAnsiString);\n        vtUTF8String:\n          Result.VString := ZUTF8ToString(Value.VUTF8String, FSystemCodePage);\n        vtUnicodeString:\n          Result.VString := {$IFNDEF UNICODE}String{$ENDIF}(Value.VUnicodeString);\n        else\n          RaiseTypeMismatchError;\n      end;\n    vtAnsiString:\n      case Value.VType of\n        vtNull:\n          Result.VAnsiString := '';\n        vtBytes:\n          Result.VAnsiString := BytesToStr(Value.VBytes);\n        vtString:\n          Result.VAnsiString := {$IFDEF UNICODE}AnsiString{$ENDIF}(Value.VString);\n        vtAnsiString:\n          Result.VAnsiString := Value.VAnsiString;\n        vtUTF8String:\n          Result.VAnsiString := ZUTF8ToAnsi(Value.VUTF8String);\n        vtUnicodeString:\n          Result.VAnsiString := AnsiString(Value.VUnicodeString);\n        else\n          RaiseTypeMismatchError;\n      end;\n    vtUTF8String:\n      case Value.VType of\n        vtNull:\n          Result.VUTF8String := '';\n        vtBytes:\n          ZSetString(PAnsiChar(Value.VBytes), Length(Value.VBytes), Result.VUTF8String);\n        vtString:\n          Result.VUTF8String := ZStringToUTF8(Value.VString, FSystemCodePage);\n       vtAnsiString:\n          Result.VUTF8String := ZAnsiToUTF8(Value.VAnsiString);\n        vtUTF8String:\n          Result.VUTF8String := Value.VUTF8String;\n        vtUnicodeString:\n          {$IFDEF WITH_RAWBYTESTRING}\n          Result.VUTF8String := UTF8String(Value.VUnicodeString);\n          {$ELSE}\n          Result.VUTF8String := UTF8Encode(Value.VUnicodeString);\n          {$ENDIF}\n        else\n          RaiseTypeMismatchError;\n      end;\n    vtRawByteString:\n      case Value.VType of\n        vtNull:\n          Result.VRawByteString := '';\n        vtBytes:\n          ZSetString(PAnsiChar(Value.VBytes), Length(Value.VBytes), Result.VRawByteString);\n        vtRawByteString:\n          Result.VRawByteString := Value.VRawByteString;\n        else\n          RaiseTypeMismatchError;\n      end;\n    vtUnicodeString:\n      case Value.VType of\n        vtNull:\n          Result.VUnicodeString := '';\n        vtString:\n          Result.VUnicodeString := {$IFNDEF UNICODE}ZWideString{$ENDIF}(Value.VString); //Cast ansi to Wide/Unicode\n        vtAnsiString:\n          Result.VUnicodeString := ZWideString(Value.VAnsiString); //Cast ansi to Wide/Unicode\n        vtUTF8String:\n          Result.VUnicodeString :=\n            {$IFDEF WITH_RAWBYTESTRING}\n            ZWideString(Value.VUTF8String);\n            {$ELSE}\n            UTF8ToString(PAnsiChar(Value.VUTF8String));\n            {$ENDIF}\n        vtUnicodeString:\n          Result.VUnicodeString := Value.VUnicodeString;\n        else\n          RaiseTypeMismatchError;\n      end;\n    vtDateTime:\n      case Value.VType of\n        vtNull:\n          Result.VDateTime := 0;\n        vtDateTime:\n          Result.VDateTime := Value.VDateTime;\n        else\n          RaiseTypeMismatchError;\n      end;\n    vtPointer:\n      case Value.VType of\n        vtNull:\n          Result.VPointer := nil;\n        vtPointer:\n          Result.VPointer := Value.VPointer;\n        else\n          RaiseTypeMismatchError;\n      end;\n    vtInterface:\n      case Value.VType of\n        vtNull:\n          Result.VInterface := nil;\n        vtInterface:\n          Result.VInterface := Value.VInterface;\n        else\n          RaiseTypeMismatchError;\n      end;\n  end;\nend;\n\n{**\n  Compares two variant values.\n  @param Value1 the first variant value.\n  @param Value2 the second variant value.\n  @return <0 if Value1 < Value 2, =0 if Value1 = Value2, >0 if Value1 > Value2\n}\nfunction TZDefaultVariantManager.Compare(const Value1,\n  Value2: TZVariant): Integer;\nvar\n  TempFloat: Extended;\n  TempDateTime: TDateTime;\nbegin\n  case Value1.VType of\n    vtNull:\n      begin\n        if IsNull(Value2) then\n          Result := 0\n        else\n          Result := -1;\n      end;\n    vtBoolean:\n      begin\n        if GetAsBoolean(Value2) then\n        begin\n          if Value1.VBoolean then\n            Result := 0\n          else\n            Result := -1;\n        end\n        else\n        begin\n          if Value1.VBoolean then\n            Result := 1\n          else\n            Result := 0;\n        end;\n      end;\n    vtInteger:\n      Result := Value1.VInteger - GetAsInteger(Value2);\n    vtFloat:\n      begin\n        TempFloat := GetAsFloat(Value2);\n        if Value1.VFloat - TempFloat < -FLOAT_COMPARE_PRECISION then\n          Result := -1\n        else if Value1.VFloat - TempFloat > FLOAT_COMPARE_PRECISION then\n          Result := 1\n        else\n          Result := 0;\n      end;\n{ TODO -oEgonHugeist -cOptimierung :\n  String typed needs to be reviewed for a more optimal way.\n  Simple ByteCompare instead of functions which are codepage dependent should be faster, thought. }\n    vtString:\n      Result := AnsiStrComp(PChar(Value1.VString), PChar(GetAsString(Value2)));\n    vtAnsiString:\n      Result := {$IFDEF WITH_ANSISTRCOMP_DEPRECATED}AnsiStrings.{$ENDIF}AnsiStrComp(PAnsiChar(Value1.VAnsiString), PAnsiChar(GetAsAnsiString(Value2)));\n    vtUTF8String:\n      Result := {$IFDEF WITH_ANSISTRCOMP_DEPRECATED}AnsiStrings.{$ENDIF}AnsiStrComp(PAnsiChar(GetAsAnsiString(Value1)), PAnsiChar(GetAsAnsiString(Value2)));\n    vtRawByteString:\n      Result := {$IFDEF WITH_ANSISTRCOMP_DEPRECATED}AnsiStrings.{$ENDIF}AnsiStrComp(PAnsiChar(GetAsAnsiString(Value1)), PAnsiChar(GetAsAnsiString(Value2)));\n    vtUnicodeString:\n{$IFNDEF FPC}\n   {$IFDEF UNICODE}\n      Result := AnsiCompareStr(Value1.VUnicodeString, GetAsUnicodeString(Value2));\n   {$ELSE}\n      Result := WideCompareStr(Value1.VUnicodeString, GetAsUnicodeString(Value2));\n   {$ENDIF}\n{$ELSE}\n      Result := AnsiCompareStr(AnsiString(Value1.VUnicodeString), GetAsString(Value2));\n{$ENDIF}\n    vtDateTime:\n      begin\n        TempDateTime := GetAsDateTime(Value2);\n        if Value1.VDateTime < TempDateTime then\n          Result := -1\n        else if Value1.VDateTime > TempDateTime then\n          Result := 1\n        else\n          Result := 0;\n      end;\n    vtPointer:\n      Result := sign(NativeInt(Value1.VPointer) - GetAsInteger(Value2));\n    else\n      Result := 0;\n  end;\nend;\n\n{**\n  Checks is the specified value NULL.\n  @param Value a value to be checked.\n  @returns <code>True</code> if variant has NULL value.\n}\nfunction TZDefaultVariantManager.IsNull(const Value: TZVariant): Boolean;\nbegin\n  Result := Value.VType = vtNull;\nend;\n\n{**\n  Sets the NULL value to specified variant.\n  @param Value variant value to be set to NULL.\n}\nprocedure TZDefaultVariantManager.SetNull(var Value: TZVariant);\nbegin\n  Value := EncodeNull;\nend;\n\n{**\n  Gets a variant to boolean value.\n  @param Value a variant to be converted.\n  @param a result value.\n}\nfunction TZDefaultVariantManager.GetAsBoolean(\n  const Value: TZVariant): Boolean;\nbegin\n  Result := Convert(Value, vtBoolean).VBoolean;\nend;\n\n{**\n  Gets a variant to boolean value.\n  @param Value a variant to be converted.\n  @param a result value.\n}\nfunction TZDefaultVariantManager.GetAsBytes(\n  const Value: TZVariant): TByteDynArray;\nbegin\n  Result := Convert(Value, vtBytes).VBytes;\nend;\n{**\n  Gets a variant to integer value.\n  @param Value a variant to be converted.\n  @param a result value.\n}\nfunction TZDefaultVariantManager.GetAsInteger(\n  const Value: TZVariant): Int64;\nbegin\n  Result := Convert(Value, vtInteger).VInteger;\nend;\n\n{**\n  Gets a variant to float value.\n  @param Value a variant to be converted.\n  @param a result value.\n}\nfunction TZDefaultVariantManager.GetAsFloat(\n  const Value: TZVariant): Extended;\nbegin\n  Result := Convert(Value, vtFloat).VFloat;\nend;\n\n{**\n  Gets a variant to string value.\n  @param Value a variant to be converted.\n  @param a result value.\n}\nfunction TZDefaultVariantManager.GetAsString(\n  const Value: TZVariant): String;\nbegin\n  Result := Convert(Value, vtString).VString;\nend;\n\n{**\n  Gets a variant to string value.\n  @param Value a variant to be converted.\n  @param a result value.\n}\nfunction TZDefaultVariantManager.GetAsAnsiString(\n  const Value: TZVariant): AnsiString;\nbegin\n  Result := Convert(Value, vtAnsiString).VAnsiString;\nend;\n\nfunction TZDefaultVariantManager.GetAsUTF8String(const Value: TZVariant): UTF8String;\nbegin\n  Result := Convert(Value, vtUTF8String).VUTF8String;\nend;\n\nfunction TZDefaultVariantManager.GetAsRawByteString(const Value: TZVariant): RawByteString;\nbegin\n  Result := Convert(Value, vtRawByteString).VRawByteString;\nend;\n\n{**\n  Gets a variant to unicode string value.\n  @param Value a variant to be converted.\n  @param a result value.\n}\nfunction TZDefaultVariantManager.GetAsUnicodeString(\n  const Value: TZVariant): ZWideString;\nbegin\n  Result := Convert(Value, vtUnicodeString).VUnicodeString;\nend;\n\n{**\n  Gets a variant to date and time value.\n  @param Value a variant to be converted.\n  @param a result value.\n}\nfunction TZDefaultVariantManager.GetAsDateTime(\n  const Value: TZVariant): TDateTime;\nbegin\n  Result := Convert(Value, vtDateTime).VDateTime;\nend;\n\n{**\n  Gets a variant to pointer value.\n  @param Value a variant to be converted.\n  @param a result value.\n}\nfunction TZDefaultVariantManager.GetAsPointer(\n  const Value: TZVariant): Pointer;\nbegin\n  Result := Convert(Value, vtPointer).VPointer;\nend;\n\n{**\n  Gets a variant to interface value.\n  @param Value a variant to be converted.\n  @param a result value.\n}\nfunction TZDefaultVariantManager.GetAsInterface(\n  const Value: TZVariant): IZInterface;\nbegin\n  Result := Convert(Value, vtInterface).VInterface;\nend;\n\n{**\n  Assignes a boolean value to variant.\n  @param Value a variant to store the value.\n  @param Data a value to be assigned.\n}\nprocedure TZDefaultVariantManager.SetAsBoolean(var Value: TZVariant;\n  Data: Boolean);\nbegin\n  Value := EncodeBoolean(Data);\nend;\n\n{**\n  Assignes a Byte array value to variant.\n  @param Value a variant to store the value.\n  @param Data a value to be assigned.\n}\nprocedure TZDefaultVariantManager.SetAsBytes(var Value: TZVariant;\n  const Data: TByteDynArray);\nbegin\n  Value := EncodeBytes(Data);\nend;\n\n{**\n  Assignes an integer value to variant.\n  @param Value a variant to store the value.\n  @param Data a value to be assigned.\n}\nprocedure TZDefaultVariantManager.SetAsInteger(var Value: TZVariant;\n  Data: Int64);\nbegin\n  Value := EncodeInteger(Data);\nend;\n\n{**\n  Assignes a float value to variant.\n  @param Value a variant to store the value.\n  @param Data a value to be assigned.\n}\nprocedure TZDefaultVariantManager.SetAsFloat(var Value: TZVariant;\n  Data: Extended);\nbegin\n  Value := EncodeFloat(Data);\nend;\n\n{**\n  Assignes a String value to variant.\n  @param Value a variant to store the value.\n  @param Data a value to be assigned.\n}\nprocedure TZDefaultVariantManager.SetAsString(var Value: TZVariant;\n  const Data: String);\nbegin\n  Value := EncodeString(Data);\nend;\n\n{**\n  Assignes a AnsiString value to variant.\n  @param Value a variant to store the value.\n  @param Data a value to be assigned.\n}\nprocedure TZDefaultVariantManager.SetAsAnsiString(var Value: TZVariant;\n  const Data: AnsiString);\nbegin\n  Value := EncodeAnsiString(Data);\nend;\n\n{**\n  Assignes a UTF8string value to variant.\n  @param Value a variant to store the value.\n  @param Data a value to be assigned.\n}\nprocedure TZDefaultVariantManager.SetAsUTF8String(var Value: TZVariant;\n  const Data: UTF8String);\nbegin\n  Value := EncodeUTF8String(Data);\nend;\n\n{**\n  Assignes a RawByteString value to variant.\n  @param Value a variant to store the value.\n  @param Data a value to be assigned.\n  @param CP the CodePage of the Data string\n}\nprocedure TZDefaultVariantManager.SetAsRawByteString(var Value: TZVariant;\n  const Data: RawByteString);\nbegin\n  Value := EncodeRawByteString(Data);\nend;\n\n{**\n  Assignes a unicode string value to variant.\n  @param Value a variant to store the value.\n  @param Data a value to be assigned.\n}\nprocedure TZDefaultVariantManager.SetAsUnicodeString(var Value: TZVariant;\n  const Data: ZWideString);\nbegin\n  Value := EncodeUnicodeString(Data);\nend;\n\n{**\n  Assignes a datetime value to variant.\n  @param Value a variant to store the value.\n  @param Data a value to be assigned.\n}\nprocedure TZDefaultVariantManager.SetAsDateTime(var Value: TZVariant;\n  Data: TDateTime);\nbegin\n  Value := EncodeDateTime(Data);\nend;\n\n{**\n  Assignes a pointer value to variant.\n  @param Value a variant to store the value.\n  @param Data a value to be assigned.\n}\nprocedure TZDefaultVariantManager.SetAsPointer(var Value: TZVariant;\n  Data: Pointer);\nbegin\n  Value := EncodePointer(Data);\nend;\n\n{**\n  Assignes a interface value to variant.\n  @param Value a variant to store the value.\n  @param Data a value to be assigned.\n}\nprocedure TZDefaultVariantManager.SetAsInterface(var Value: TZVariant;\n  Data: IZInterface);\nbegin\n  Value := EncodeInterface(Data);\nend;\n\n{**\n  Performs '+' operation.\n  @param Value1 the first variant argument.\n  @param Value2 the second variant argument.\n  @returns an operation result.\n}\nfunction TZDefaultVariantManager.OpAdd(const Value1,\n  Value2: TZVariant): TZVariant;\nbegin\n  case Value1.VType of\n    vtNull: Result := EncodeNull;\n    vtInteger: Result := EncodeInteger(Value1.VInteger + GetAsInteger(Value2));\n    vtFloat: Result := EncodeFloat(Value1.VFloat + GetAsFloat(Value2));\n    vtString: Result := EncodeString(Value1.VString + GetAsString(Value2));\n    vtAnsiString: Result := EncodeAnsiString(Value1.VAnsiString + GetAsAnsiString(Value2));\n    vtUTF8String: Result := EncodeUTF8String(Value1.VUTF8String + GetAsUTF8String(Value2));\n    vtRawByteString: Result := EncodeRawByteString(Value1.VRawByteString + GetAsRawByteString(Value2));\n    vtUnicodeString: Result := EncodeUnicodeString(Value1.VUnicodeString + GetAsUnicodeString(Value2));\n    vtDateTime: Result := EncodeDateTime(Value1.VDateTime + GetAsDateTime(Value2));\n    else RaiseUnsupportedOperation;\n  end;\nend;\n\n{**\n  Performs '&' operation.\n  @param Value1 the first variant argument.\n  @param Value2 the second variant argument.\n  @returns an operation result.\n}\nfunction TZDefaultVariantManager.OpAnd(const Value1,\n  Value2: TZVariant): TZVariant;\nbegin\n  case Value1.VType of\n    vtNull: Result := EncodeNull;\n    vtBoolean: Result := EncodeBoolean(Value1.VBoolean and GetAsBoolean(Value2));\n    vtInteger: Result := EncodeInteger(Value1.VInteger and GetAsInteger(Value2));\n    else RaiseUnsupportedOperation;\n  end;\nend;\n\n{**\n  Performs '/' operation.\n  @param Value1 the first variant argument.\n  @param Value2 the second variant argument.\n  @returns an operation result.\n}\nfunction TZDefaultVariantManager.OpDiv(const Value1,\n  Value2: TZVariant): TZVariant;\nbegin\n  case Value1.VType of\n    vtNull: Result := EncodeNull;\n    vtInteger: Result := EncodeInteger(Value1.VInteger div GetAsInteger(Value2));\n    vtFloat: Result := EncodeFloat(Value1.VFloat / GetAsFloat(Value2));\n    else RaiseUnsupportedOperation;\n  end;\nend;\n\n{**\n  Performs '=' operation.\n  @param Value1 the first variant argument.\n  @param Value2 the second variant argument.\n  @returns an operation result.\n}\nfunction TZDefaultVariantManager.OpEqual(const Value1,\n  Value2: TZVariant): TZVariant;\nbegin\n  Result := EncodeBoolean(Compare(Value1, Value2) = 0);\nend;\n\n{**\n  Performs '<' operation.\n  @param Value1 the first variant argument.\n  @param Value2 the second variant argument.\n  @returns an operation result.\n}\nfunction TZDefaultVariantManager.OpLess(const Value1,\n  Value2: TZVariant): TZVariant;\nbegin\n  Result := EncodeBoolean(Compare(Value1, Value2) < 0);\nend;\n\n{**\n  Performs '<=' operation.\n  @param Value1 the first variant argument.\n  @param Value2 the second variant argument.\n  @returns an operation result.\n}\nfunction TZDefaultVariantManager.OpLessEqual(const Value1,\n  Value2: TZVariant): TZVariant;\nbegin\n  Result := EncodeBoolean(Compare(Value1, Value2) <= 0);\nend;\n\n{**\n  Performs '%' operation.\n  @param Value1 the first variant argument.\n  @param Value2 the second variant argument.\n  @returns an operation result.\n}\nfunction TZDefaultVariantManager.OpMod(const Value1,\n  Value2: TZVariant): TZVariant;\nbegin\n  case Value1.VType of\n    vtNull: Result := EncodeNull;\n    vtInteger: Result := EncodeInteger(Value1.VInteger mod GetAsInteger(Value2));\n    else RaiseUnsupportedOperation;\n  end;\nend;\n\n{**\n  Performs '>' operation.\n  @param Value1 the first variant argument.\n  @param Value2 the second variant argument.\n  @returns an operation result.\n}\nfunction TZDefaultVariantManager.OpMore(const Value1,\n  Value2: TZVariant): TZVariant;\nbegin\n  Result := EncodeBoolean(Compare(Value1, Value2) > 0);\nend;\n\n{**\n  Performs '>=' operation.\n  @param Value1 the first variant argument.\n  @param Value2 the second variant argument.\n  @returns an operation result.\n}\nfunction TZDefaultVariantManager.OpMoreEqual(const Value1,\n  Value2: TZVariant): TZVariant;\nbegin\n  Result := EncodeBoolean(Compare(Value1, Value2) >= 0);\nend;\n\n{**\n  Performs '*' operation.\n  @param Value1 the first variant argument.\n  @param Value2 the second variant argument.\n  @returns an operation result.\n}\nfunction TZDefaultVariantManager.OpMul(const Value1,\n  Value2: TZVariant): TZVariant;\nbegin\n  case Value1.VType of\n    vtNull: Result := EncodeNull;\n    vtInteger: Result := EncodeInteger(Value1.VInteger * GetAsInteger(Value2));\n    vtFloat: Result := EncodeFloat(Value1.VFloat * GetAsFloat(Value2));\n    else RaiseUnsupportedOperation;\n  end;\nend;\n\n{**\n  Performs unary '-' operation.\n  @param Value the variant argument.\n  @returns an operation result.\n}\nfunction TZDefaultVariantManager.OpNegative(const Value: TZVariant): TZVariant;\nbegin\n  case Value.VType of\n    vtNull: Result := EncodeNull;\n    vtInteger: Result := EncodeInteger(-Value.VInteger);\n    vtFloat: Result := EncodeFloat(-Value.VFloat);\n    else RaiseUnsupportedOperation;\n  end;\nend;\n\n{**\n  Performs '~' operation.\n  @param Value the variant argument.\n  @returns an operation result.\n}\nfunction TZDefaultVariantManager.OpNot(const Value: TZVariant): TZVariant;\nbegin\n  case Value.VType of\n    vtNull: Result := EncodeNull;\n    vtBoolean: Result := EncodeBoolean(not Value.VBoolean);\n    vtInteger: Result := EncodeInteger(not Value.VInteger);\n    else RaiseUnsupportedOperation;\n  end;\nend;\n\n{**\n  Performs '<>' operation.\n  @param Value1 the first variant argument.\n  @param Value2 the second variant argument.\n  @returns an operation result.\n}\nfunction TZDefaultVariantManager.OpNotEqual(const Value1,\n  Value2: TZVariant): TZVariant;\nbegin\n  Result := EncodeBoolean(Compare(Value1, Value2) <> 0);\nend;\n\n{**\n  Performs '|' operation.\n  @param Value1 the first variant argument.\n  @param Value2 the second variant argument.\n  @returns an operation result.\n}\nfunction TZDefaultVariantManager.OpOr(const Value1,\n  Value2: TZVariant): TZVariant;\nbegin\n  case Value1.VType of\n    vtNull: SetNull(Result);\n    vtBoolean: Result := EncodeBoolean(Value1.VBoolean or GetAsBoolean(Value2));\n    vtInteger: Result := EncodeInteger(Value1.VInteger or GetAsInteger(Value2));\n    else RaiseUnsupportedOperation;\n  end;\nend;\n\n{**\n  Performs '^' operation.\n  @param Value1 the first variant argument.\n  @param Value2 the second variant argument.\n  @returns an operation result.\n}\nfunction TZDefaultVariantManager.OpPow(const Value1,\n  Value2: TZVariant): TZVariant;\nbegin\n  case Value1.VType of\n    vtNull: Result := EncodeNull;\n    vtInteger: Result := EncodeFloat(Power(Value1.VInteger, GetAsInteger(Value2)));\n    vtFloat: Result := EncodeFloat(Power(Value1.VFloat, GetAsFloat(Value2)));\n    else RaiseUnsupportedOperation;\n  end;\nend;\n\n{**\n  Performs '-' operation.\n  @param Value1 the first variant argument.\n  @param Value2 the second variant argument.\n  @returns an operation result.\n}\nfunction TZDefaultVariantManager.OpSub(const Value1,\n  Value2: TZVariant): TZVariant;\nbegin\n  case Value1.VType of\n    vtNull: Result := EncodeNull;\n    vtInteger: Result := EncodeInteger(Value1.VInteger - GetAsInteger(Value2));\n    vtFloat: Result := EncodeFloat(Value1.VFloat - GetAsFloat(Value2));\n    else RaiseUnsupportedOperation;\n  end;\nend;\n\n{**\n  Performs '^' operation.\n  @param Value1 the first variant argument.\n  @param Value2 the second variant argument.\n  @returns an operation result.\n}\nfunction TZDefaultVariantManager.OpXor(const Value1,\n  Value2: TZVariant): TZVariant;\nvar\n  TempBool1, TempBool2: Boolean;\n  TempInteger1, TempInteger2: Int64;\nbegin\n  case Value1.VType of\n    vtNull: Result := EncodeNull;\n    vtBoolean:\n      begin\n        TempBool1 := Value1.VBoolean;\n        TempBool2 := GetAsBoolean(Value2);\n        Result := EncodeBoolean((TempBool1 and not TempBool2)\n          or (not TempBool1 and TempBool2));\n      end;\n    vtInteger:\n      begin\n        TempInteger1 := Value1.VInteger;\n        TempInteger2 := GetAsInteger(Value2);\n        Result := EncodeInteger((TempInteger1 and not TempInteger2)\n          or (not TempInteger1 and TempInteger2));\n      end;\n    else RaiseUnsupportedOperation;\n  end;\nend;\n\n{ TZSoftVariantManager }\n\n{**\n  Converts a specified variant value to a new type.\n  @param Value a variant value to be converted.\n  @param NewType a type of the result variant value.\n  @returns a converted variant value.\n}\nfunction TZSoftVariantManager.Convert(const Value: TZVariant;\n  NewType: TZVariantType): TZVariant;\nbegin\n  Result.VType := NewType;\n  case NewType of\n    vtBoolean:\n      case Value.VType of\n        vtNull:\n          Result.VBoolean := False;\n        vtBoolean:\n          Result.VBoolean := Value.VBoolean;\n        vtInteger:\n          Result.VBoolean := Value.VInteger <> 0;\n        vtFloat:\n          Result.VBoolean := Value.VFloat <> 0;\n        vtString:\n          Result.VBoolean := StrToBoolEx(Value.VString);\n        vtAnsiString:\n          Result.VBoolean := StrToBoolEx({$IFDEF UNICODE}String{$ENDIF}(Value.VAnsiString));\n        vtUTF8String:\n          Result.VBoolean := StrToBoolEx({$IFDEF UNICODE}String{$ENDIF}(Value.VUTF8String));\n        vtRawByteString:\n          Result.VBoolean := StrToBoolEx({$IFDEF UNICODE}String{$ENDIF}(Value.VRawByteString));\n        vtUnicodeString:\n          Result.VBoolean := StrToBoolEx({$IFNDEF UNICODE}String{$ENDIF}(Value.VUnicodeString));\n        vtDateTime:\n          Result.VBoolean := Value.VDateTime <> 0;\n        vtPointer:\n          RaiseTypeMismatchError;\n        vtInterface:\n          RaiseTypeMismatchError;\n      end;\n    vtBytes:\n      case Value.VType of\n        vtNull:\n          Result.VBytes := nil;\n        vtBytes:\n          Result.VBytes := Value.VBytes;\n        vtString:\n          Result.VBytes := StrToBytes(Value.VString);\n        vtAnsiString:\n          Result.VBytes := StrToBytes(Value.VAnsiString);\n        vtRawByteString:\n          Result.VBytes := StrToBytes(Value.VRawByteString);\n        vtUTF8String:\n          Result.VBytes := StrToBytes(Value.VUTF8String);\n        vtUnicodeString:\n          Result.VBytes := StrToBytes(Value.VUnicodeString);\n        else\n          RaiseTypeMismatchError;\n      end;\n    vtInteger:\n      case Value.VType of\n        vtNull:\n          Result.VInteger := 0;\n        vtBoolean:\n          if Value.VBoolean then\n            Result.VInteger := 1\n          else\n            Result.VInteger := 0;\n        vtInteger:\n          Result.VInteger := Value.VInteger;\n        vtFloat:\n          Result.VInteger := Trunc(Value.VFloat);\n        vtString:\n          Result.VInteger := StrToInt64Def(Value.VString, 0);\n        vtAnsiString:\n          Result.VInteger := StrToInt64Def({$IFDEF UNICODE}String{$ENDIF}(Value.VAnsiString), 0);\n        vtUTF8String:\n          Result.VInteger := StrToInt64Def({$IFDEF UNICODE}String{$ENDIF}(Value.VUTF8String), 0);\n        vtRawByteString:\n          Result.VInteger := StrToInt64Def({$IFDEF UNICODE}String{$ENDIF}(Value.VRawByteString), 0);\n        vtUnicodeString:\n          Result.VInteger := StrToInt64Def({$IFNDEF UNICODE}String{$ENDIF}(Value.VUnicodeString), 0);\n        vtDateTime:\n          Result.VInteger := Trunc(Value.VDateTime);\n        vtPointer:\n          Result.VInteger := NativeInt(Value.VPointer);\n        vtInterface:\n          RaiseTypeMismatchError;\n      end;\n    vtFloat:\n      case Value.VType of\n        vtNull:\n          Result.VFloat := 0;\n        vtBoolean:\n          if Value.VBoolean then\n            Result.VFloat := 1\n          else\n            Result.VFloat := 0;\n        vtInteger:\n          Result.VFloat := Value.VInteger;\n        vtFloat:\n          Result.VFloat := Value.VFloat;\n        vtString:\n          Result.VFloat := SqlStrToFloatDef(Value.VString, 0);\n        vtAnsiString:\n          Result.VFloat := SqlStrToFloatDef({$IFDEF UNICODE}String{$ENDIF}(Value.VAnsiString), 0);\n        vtUTF8String:\n          Result.VFloat := SqlStrToFloatDef({$IFDEF UNICODE}String{$ENDIF}(Value.VUTF8String), 0);\n        vtRawByteString:\n          Result.VFloat := SqlStrToFloatDef(Value.VRawByteString, 0);\n        vtUnicodeString:\n          Result.VFloat := SqlStrToFloatDef(AnsiString(Value.VUnicodeString), 0);\n        vtDateTime:\n          Result.VFloat := Value.VDateTime;\n        else\n          RaiseTypeMismatchError;\n      end;\n    vtString:\n      case Value.VType of\n        vtNull:\n          Result.VString := '';\n        vtBoolean:\n          if Value.VBoolean then\n            Result.VString := 'TRUE'\n          else\n            Result.VString := 'FALSE';\n        vtBytes:\n          ZSetString(PAnsiChar(Value.VBytes), Length(Value.VBytes), Result.VString);\n        vtInteger:\n          Result.VString := IntToStr(Value.VInteger);\n        vtFloat:\n          Result.VString := FloatToSqlStr(Value.VFloat);\n        vtString:\n          Result.VString := Value.VString;\n        vtAnsiString:\n          Result.VString := {$IFDEF UNICODE}String{$ENDIF}(Value.VAnsiString);\n        vtUTF8String:\n          Result.VString := ZUTF8ToString(Value.VUTF8String, FSystemCodePage);\n        vtUnicodeString:\n          Result.VString := Value.VUnicodeString; //hint: VarArrayOf(['Test']) returns allways varOleStr which is type WideString don't change that again\n        vtDateTime:\n          Result.VString := DateTimeToAnsiSQLDate(Value.VDateTime);\n          // gto: Not a real threat, as it's converting dates (unicode safe)\n        else\n          RaiseTypeMismatchError;\n      end;\n    vtAnsiString:\n      case Value.VType of\n        vtNull:\n          Result.VAnsiString := '';\n        vtBoolean:\n          if Value.VBoolean then\n            Result.VAnsiString := 'TRUE'\n          else\n            Result.VAnsiString := 'FALSE';\n        vtInteger:\n          Result.VAnsiString := {$IFDEF UNICODE}AnsiString{$ENDIF}(IntToStr(Value.VInteger));\n        vtFloat:\n          Result.VAnsiString := {$IFDEF UNICODE}AnsiString{$ENDIF}(FloatToSqlStr(Value.VFloat));\n        vtString:\n          Result.VAnsiString := {$IFDEF UNICODE}AnsiString{$ENDIF}(Value.VString);\n        vtAnsiString:\n          Result.VAnsiString := Value.VAnsiString;\n        vtUTF8String:\n          Result.VAnsiString := ZUTF8ToAnsi(Value.VUTF8String);\n        vtUnicodeString:\n          Result.VAnsiString := AnsiString(Value.VUnicodeString);\n        vtDateTime:\n          Result.VAnsiString := {$IFDEF UNICODE}AnsiString{$ENDIF}(DateTimeToAnsiSQLDate(Value.VDateTime));\n        else\n          RaiseTypeMismatchError;\n      end;\n    vtUTF8String:\n      case Value.VType of\n        vtNull:\n          Result.VUTF8String := '';\n        vtBoolean:\n          if Value.VBoolean then\n            Result.VUTF8String := 'TRUE'\n          else\n            Result.VUTF8String := 'FALSE';\n        vtInteger:\n          Result.VUTF8String := UTF8String(IntToStr(Value.VInteger));\n        vtFloat:\n          Result.VUTF8String := UTF8String(FloatToSqlStr(Value.VFloat));\n        vtString:\n          Result.VUTF8String := ZStringToUTF8(Value.VString, FSystemCodePage);\n        vtAnsiString:\n          Result.VUTF8String := ZAnsiToUTF8(Value.VAnsiString);\n        vtUTF8String:\n          Result.VUTF8String := Value.VUTF8String;\n        vtUnicodeString:\n          {$IFDEF WITH_RAWBYTESTRING}\n          Result.VUTF8String := UTF8String(Value.VUnicodeString);\n          {$ELSE}\n          Result.VUTF8String := UTF8Encode(Value.VUnicodeString);\n          {$ENDIF}\n        vtDateTime:\n          Result.VUTF8String := UTF8String(DateTimeToAnsiSQLDate(Value.VDateTime));\n        else\n          RaiseTypeMismatchError;\n      end;\n    vtUnicodeString:\n      case Value.VType of\n        vtNull:\n          Result.VUnicodeString := '';\n        vtBoolean:\n          if Value.VBoolean then\n            Result.VUnicodeString := 'TRUE'\n          else\n            Result.VUnicodeString := 'FALSE';\n        vtInteger:\n          Result.VUnicodeString := {$IFNDEF UNICODE}ZWideString{$ENDIF}(IntToStr(Value.VInteger));\n        vtFloat:\n          Result.VUnicodeString := {$IFNDEF UNICODE}ZWideString{$ENDIF}(FloatToSqlStr(Value.VFloat));\n        vtString:\n          Result.VUnicodeString := {$IFNDEF UNICODE}ZWideString{$ENDIF}(Value.VString);\n        vtAnsiString:\n          Result.VUnicodeString := ZWideString(Value.VAnsiString);\n        vtUTF8String:\n          Result.VUnicodeString := {$IFDEF UNICODE}UTF8ToString{$ELSE}UTF8Decode{$ENDIF}(PAnsiChar(Value.VUTF8String));\n        vtUnicodeString:\n          Result.VUnicodeString := Value.VUnicodeString;\n        vtDateTime:\n          Result.VUnicodeString := ZWideString(DateTimeToAnsiSQLDate(Value.VDateTime));\n        else\n          RaiseTypeMismatchError;\n      end;\n    vtDateTime:\n      case Value.VType of\n        vtNull:\n          Result.VDateTime := 0;\n        vtBoolean:\n          RaiseTypeMismatchError;\n        vtInteger:\n          Result.VDateTime := Value.VInteger;\n        vtFloat:\n          Result.VDateTime := Value.VFloat;\n        vtString:\n          Result.VDateTime := AnsiSQLDateToDateTime(Value.VString);\n        vtAnsiString:\n          Result.VDateTime := AnsiSQLDateToDateTime({$IFDEF UNICODE}String{$ENDIF}(Value.VAnsiString));\n        vtUTF8String:\n          Result.VDateTime := AnsiSQLDateToDateTime({$IFDEF UNICODE}String{$ENDIF}(Value.VUTF8String));\n        vtRawByteString:\n          Result.VDateTime := AnsiSQLDateToDateTime({$IFDEF UNICODE}String{$ENDIF}(Value.VRawByteString));\n        vtUnicodeString:\n          Result.VDateTime := AnsiSQLDateToDateTime({$IFNDEF UNICODE}String{$ENDIF}(Value.VUnicodeString));\n        vtDateTime:\n          Result.VDateTime := Value.VDateTime;\n        else\n          RaiseTypeMismatchError;\n      end;\n    vtPointer:\n      case Value.VType of\n        vtNull:\n          Result.VPointer := nil;\n        vtBoolean:\n          RaiseTypeMismatchError;\n        vtInteger:\n          Result.VPointer := Pointer(Value.VInteger);\n        else\n          RaiseTypeMismatchError;\n      end;\n    vtInterface:\n      case Value.VType of\n        vtNull:\n          Result.VInterface := nil;\n        vtInterface:\n          Result.VInterface := Value.VInterface;\n        else\n      end;\n  end;\nend;\n\n{ TZClientVariantManager }\n\n{**\n  Constructs this object and assignes the main properties.\n  @param ClientCodePage the current ClientCodePage.\n}\nconstructor TZClientVariantManager.Create(const ConSettings: PZConSettings);\nbegin\n  inherited Create; //Set all standart converters functions\n\n  FConSettings := ConSettings;\nend;\n\n{**\n  Converts a specified variant value to a new type.\n  @param Value a variant value to be converted.\n  @param NewType a type of the result variant value.\n  @returns a converted variant value.\n}\nfunction TZClientVariantManager.Convert(const Value: TZVariant;\n  NewType: TZVariantType): TZVariant;\nbegin\n  Result.VType := NewType;\n  case NewType of\n    vtBoolean:\n      case Value.VType of\n        vtNull:\n          Result.VBoolean := False;\n        vtBoolean:\n          Result.VBoolean := Value.VBoolean;\n        vtInteger:\n          Result.VBoolean := Value.VInteger <> 0;\n        vtFloat:\n          Result.VBoolean := Value.VFloat <> 0;\n        vtString:\n          Result.VBoolean := StrToBoolEx(Value.VString);\n        vtAnsiString:\n          Result.VBoolean := StrToBoolEx({$IFDEF UNICODE}String{$ENDIF}(Value.VAnsiString));\n        vtUTF8String:\n          Result.VBoolean := StrToBoolEx({$IFDEF UNICODE}String{$ENDIF}(Value.VUTF8String));\n        vtRawByteString:\n          Result.VBoolean := StrToBoolEx({$IFDEF UNICODE}String{$ENDIF}(Value.VRawByteString));\n        vtUnicodeString:\n          Result.VBoolean := StrToBoolEx({$IFNDEF UNICODE}String{$ENDIF}(Value.VUnicodeString));\n        vtDateTime:\n          Result.VBoolean := Value.VDateTime <> 0;\n        else\n          RaiseTypeMismatchError;\n      end;\n    vtBytes:\n      case Value.VType of\n        vtNull:\n          Result.VBytes := nil;\n        vtBytes:\n          Result.VBytes := Value.VBytes;\n        vtString:\n          Result.VBytes := StrToBytes(Value.VString);\n        vtAnsiString:\n          Result.VBytes := StrToBytes(Value.VAnsiString);\n        vtRawByteString:\n          Result.VBytes := StrToBytes(Value.VRawByteString);\n        vtUTF8String:\n          Result.VBytes := StrToBytes(Value.VUTF8String);\n        vtUnicodeString:\n          Result.VBytes := StrToBytes(Value.VUnicodeString);\n        else\n          RaiseTypeMismatchError;\n      end;\n    vtInteger:\n      case Value.VType of\n        vtNull:\n          Result.VInteger := 0;\n        vtBoolean:\n          if Value.VBoolean then\n            Result.VInteger := 1\n          else\n            Result.VInteger := 0;\n        vtInteger:\n          Result.VInteger := Value.VInteger;\n        vtFloat:\n          Result.VInteger := Trunc(Value.VFloat);\n        vtString:\n          Result.VInteger := StrToInt64Def(Value.VString, 0);\n        vtAnsiString:\n          Result.VInteger := StrToInt64Def({$IFDEF UNICODE}String{$ENDIF}(Value.VAnsiString), 0);\n        vtUTF8String:\n          Result.VInteger := StrToInt64Def({$IFDEF UNICODE}String{$ENDIF}(Value.VUTF8String), 0);\n        vtRawByteString:\n          Result.VInteger := StrToInt64Def({$IFDEF UNICODE}String{$ENDIF}(Value.VRawByteString), 0);\n        vtUnicodeString:\n          Result.VInteger := StrToInt64Def({$IFNDEF UNICODE}String{$ENDIF}(Value.VUnicodeString), 0);\n        vtDateTime:\n          Result.VInteger := Trunc(Value.VDateTime);\n        vtPointer:\n          Result.VInteger := NativeInt(Value.VPointer);\n        vtInterface:\n          RaiseTypeMismatchError;\n      end;\n    vtFloat:\n      case Value.VType of\n        vtNull:\n          Result.VFloat := 0;\n        vtBoolean:\n          if Value.VBoolean then\n            Result.VFloat := 1\n          else\n            Result.VFloat := 0;\n        vtInteger:\n          Result.VFloat := Value.VInteger;\n        vtFloat:\n          Result.VFloat := Value.VFloat;\n        vtString:\n          Result.VFloat := SqlStrToFloatDef(Value.VString, 0);\n        vtAnsiString:\n          Result.VFloat := SqlStrToFloatDef({$IFDEF UNICODE}String{$ENDIF}(Value.VAnsiString), 0);\n        vtUTF8String:\n          Result.VFloat := SqlStrToFloatDef({$IFDEF UNICODE}String{$ENDIF}(Value.VUTF8String), 0);\n        vtRawByteString:\n          Result.VFloat := SqlStrToFloatDef(Value.VRawByteString, 0);\n        vtUnicodeString:\n          Result.VFloat := SqlStrToFloatDef({$IFNDEF UNICODE}String{$ENDIF}(Value.VUnicodeString), 0);\n        vtDateTime:\n          Result.VFloat := Value.VDateTime;\n        else\n          RaiseTypeMismatchError;\n      end;\n    vtString:\n      case Value.VType of\n        vtNull:\n          Result.VString := '';\n        vtBoolean:\n          if Value.VBoolean then\n            Result.VString := 'TRUE'\n          else\n            Result.VString := 'FALSE';\n        vtBytes:\n          Result.VString := {$IFDEF UNICODE}String{$ENDIF}(BytesToStr(Value.VBytes));\n        vtInteger:\n          Result.VString := IntToStr(Value.VInteger);\n        vtFloat:\n          Result.VString := FloatToSqlStr(Value.VFloat);\n        vtString:\n          Result.VString := Value.VString;\n        vtAnsiString:\n          Result.VString := FConSettings^.ConvFuncs.ZAnsiToString(Value.VAnsiString, FConSettings^.CTRL_CP);\n        vtUTF8String:\n          Result.VString := FConSettings^.ConvFuncs.ZUTF8ToString(Value.VUTF8String, FConSettings^.CTRL_CP);\n        vtRawByteString:\n          Result.VString := FConSettings^.ConvFuncs.ZRawToString(Value.VRawByteString, FConSettings^.ClientCodePage^.CP, FConSettings^.CTRL_CP);\n        vtUnicodeString:\n          //hint: VarArrayOf(['Test']) returns allways varOleStr which is type WideString don't change that again\n          //this hint means a cast instead of convert. The user should better use WideString constants!\n          Result.VString := FConSettings^.ConvFuncs.ZUnicodeToString(Value.VUnicodeString, FConSettings^.CTRL_CP);\n        vtDateTime:\n          Result.VString := DateTimeToAnsiSQLDate(Value.VDateTime);\n        else\n          RaiseTypeMismatchError;\n      end;\n    vtAnsiString:\n      case Value.VType of\n        vtNull:\n          Result.VAnsiString := '';\n        vtBoolean:\n          if Value.VBoolean then\n            Result.VAnsiString := 'TRUE'\n          else\n            Result.VAnsiString := 'FALSE';\n        vtInteger:\n          Result.VAnsiString := {$IFDEF UNICODE}AnsiString{$ENDIF}(IntToStr(Value.VInteger));\n        vtFloat:\n          Result.VAnsiString := {$IFDEF UNICODE}AnsiString{$ENDIF}(FloatToSqlStr(Value.VFloat));\n        vtString:\n          Result.VAnsiString := FConSettings^.ConvFuncs.ZStringToAnsi(Value.VString, FConSettings^.CTRL_CP);\n        vtAnsiString:\n          Result.VAnsiString := Value.VAnsiString;\n        vtUTF8String:\n          Result.VAnsiString := FConSettings^.ConvFuncs.ZUTF8ToAnsi(Value.VUTF8String);\n        vtRawByteString:\n          Result.VAnsiString := FConSettings^.ConvFuncs.ZRawToAnsi(Value.VRawByteString, FConSettings^.ClientCodePage^.CP);\n        vtUnicodeString:\n          Result.VAnsiString := AnsiString(Value.VUnicodeString);\n        vtDateTime:\n          Result.VAnsiString := {$IFDEF UNICODE}AnsiString{$ENDIF}(DateTimeToAnsiSQLDate(Value.VDateTime));\n        else\n          RaiseTypeMismatchError;\n      end;\n    vtUTF8String:\n      case Value.VType of\n        vtNull:\n          Result.VUTF8String := '';\n        vtBoolean:\n          if Value.VBoolean then\n            Result.VUTF8String := 'TRUE'\n          else\n            Result.VUTF8String := 'FALSE';\n        vtInteger:\n          Result.VUTF8String := {$IFDEF WITH_RAWBYTESTRING}UTF8String{$ENDIF}(IntToStr(Value.VInteger));\n        vtFloat:\n          Result.VUTF8String := {$IFDEF WITH_RAWBYTESTRING}UTF8String{$ENDIF}(FloatToSqlStr(Value.VFloat));\n        vtString:\n          Result.VUTF8String := FConSettings^.ConvFuncs.ZStringToUTF8(Value.VString, FConSettings^.CTRL_CP);\n        vtAnsiString:\n          Result.VUTF8String := FConSettings^.ConvFuncs.ZAnsiToUTF8(Value.VAnsiString);\n        vtUTF8String:\n          Result.VUTF8String := Value.VUTF8String;\n        vtRawByteString:\n          Result.VUTF8String := FConSettings^.ConvFuncs.ZRawToUTF8(Value.VRawByteString, FConSettings^.ClientCodePage^.CP);\n        vtUnicodeString:\n          {$IFDEF WITH_RAWBYTESTRING}\n          Result.VUTF8String := UTF8String(Value.VUnicodeString);\n          {$ELSE}\n          Result.VUTF8String := UTF8Encode(Value.VUnicodeString);\n          {$ENDIF}\n        vtDateTime:\n          Result.VUTF8String := {$IFDEF WITH_RAWBYTESTRING}UTF8String{$ENDIF}(DateTimeToAnsiSQLDate(Value.VDateTime));\n        else\n          RaiseTypeMismatchError;\n      end;\n    vtRawByteString:\n      case Value.VType of\n        vtNull:\n          Result.VRawByteString := '';\n        vtBoolean:\n          if Value.VBoolean then\n            Result.VRawByteString := 'TRUE'\n          else\n            Result.VRawByteString := 'FALSE';\n        vtInteger:\n          Result.VRawByteString := {$IFDEF WITH_RAWBYTESTRING}RawByteString{$ENDIF}(IntToStr(Value.VInteger));\n        vtFloat:\n          Result.VRawByteString := {$IFDEF WITH_RAWBYTESTRING}RawByteString{$ENDIF}(FloatToSqlStr(Value.VFloat));\n        vtString:\n          Result.VRawByteString := FConSettings^.ConvFuncs.ZStringToRaw(Value.VString, FConSettings^.CTRL_CP, FConSettings^.ClientCodePage^.CP);\n        vtAnsiString:\n          Result.VRawByteString := FConSettings^.ConvFuncs.ZAnsiToRaw(Value.VAnsiString, FConSettings^.ClientCodePage^.CP);\n        vtUTF8String:\n          Result.VRawByteString := FConSettings^.ConvFuncs.ZUTF8ToRaw(Value.VUTF8String, FConSettings^.ClientCodePage^.CP);\n        vtRawByteString:\n          Result.VRawByteString := Value.VRawByteString;\n        vtUnicodeString:\n          Result.VRawByteString := FConSettings^.ConvFuncs.ZUnicodeToRaw(Value.VUnicodeString, FConSettings^.ClientCodePage^.CP);\n        vtDateTime:\n          Result.VRawByteString := {$IFDEF WITH_RAWBYTESTRING}RawByteString{$ENDIF}(DateTimeToAnsiSQLDate(Value.VDateTime));\n        else\n          RaiseTypeMismatchError;\n      end;\n    vtUnicodeString:\n      case Value.VType of\n        vtNull:\n          Result.VUnicodeString := '';\n        vtBoolean:\n          if Value.VBoolean then\n            Result.VUnicodeString := 'TRUE'\n          else\n            Result.VUnicodeString := 'FALSE';\n        vtInteger:\n          Result.VUnicodeString := ZWideString(IntToStr(Value.VInteger));\n        vtFloat:\n          Result.VUnicodeString := ZWideString(FloatToSqlStr(Value.VFloat));\n        vtString:\n          Result.VUnicodeString := FConSettings^.ConvFuncs.ZStringToUnicode(Value.VString, FConSettings^.CTRL_CP);\n        vtAnsiString:\n          Result.VUnicodeString := ZWideString(Value.VAnsiString);\n        vtUTF8String:\n          Result.VUnicodeString := {$IFDEF UNICODE}UTF8ToString{$ELSE}UTF8Decode{$ENDIF}(PAnsiChar(Value.VUTF8String));\n        vtRawByteString:\n          Result.VUnicodeString := FConSettings^.ConvFuncs.ZRawToUnicode(Value.VRawByteString, FConSettings^.ClientCodePage^.CP);\n        vtUnicodeString:\n          Result.VUnicodeString := Value.VUnicodeString;\n        vtDateTime:\n          Result.VUnicodeString := ZWideString(DateTimeToAnsiSQLDate(Value.VDateTime));\n        else\n          RaiseTypeMismatchError;\n      end;\n    vtDateTime:\n      case Value.VType of\n        vtNull:\n          Result.VDateTime := 0;\n        vtInteger:\n          Result.VDateTime := Value.VInteger;\n        vtFloat:\n          Result.VDateTime := Value.VFloat;\n        vtString:\n          Result.VDateTime := AnsiSQLDateToDateTime(Value.VString);\n        vtAnsiString:\n          Result.VDateTime := AnsiSQLDateToDateTime({$IFDEF UNICODE}String{$ENDIF}(Value.VAnsiString));\n        vtUTF8String:\n          Result.VDateTime := AnsiSQLDateToDateTime({$IFDEF WITH_RAWBYTESTRING}String{$ENDIF}(Value.VUTF8String));\n        vtRawByteString:\n          Result.VDateTime := AnsiSQLDateToDateTime({$IFDEF WITH_RAWBYTESTRING}String{$ENDIF}(Value.VRawByteString));\n        vtUnicodeString:\n          Result.VDateTime := AnsiSQLDateToDateTime({$IFNDEF UNICODE}String{$ENDIF}(Value.VUnicodeString));\n        vtDateTime:\n          Result.VDateTime := Value.VDateTime;\n        else\n          RaiseTypeMismatchError;\n      end;\n    vtPointer:\n      case Value.VType of\n        vtNull:\n          Result.VPointer := nil;\n        vtBoolean:\n          RaiseTypeMismatchError;\n        vtInteger:\n          Result.VPointer := Pointer(Value.VInteger);\n        else\n          RaiseTypeMismatchError;\n      end;\n    vtInterface:\n      case Value.VType of\n        vtNull:\n          Result.VInterface := nil;\n        vtInterface:\n          Result.VInterface := Value.VInterface;\n        else RaiseTypeMismatchError;\n      end;\n  end;\nend;\n\n{$WARNINGS OFF} //suppress [Pascal Warning] ZVariant.pas(1926): W1035 Return value of function 'TZClientVariantManager.GetAsRawByteString' might be undefined\nfunction TZClientVariantManager.GetAsRawByteString(const Value: TZVariant;\n  const RawCP: Word): RawByteString;\nvar US: ZWideString;\nbegin\n  case Value.VType of\n    vtNull:\n      Result := '';\n    vtBoolean:\n      if Value.VBoolean then\n        Result := 'TRUE'\n      else\n        Result := 'FALSE';\n    vtBytes:\n      ZSetString(PAnsiChar(Value.VBytes), Length(Value.VBytes), Result);\n    vtInteger:\n      Result := {$IFDEF WITH_RAWBYTESTRING}RawByteString{$ENDIF}(IntToStr(Value.VInteger));\n    vtFloat:\n      Result := {$IFDEF WITH_RAWBYTESTRING}RawByteString{$ENDIF}(FloatToSqlStr(Value.VFloat));\n    vtString:\n      Result := ZConvertStringToRawWithAutoEncode(Value.VString, FConSettings^.CTRL_CP, RawCP);\n    vtAnsiString:\n      if ZCompatibleCodePages(ZDefaultSystemCodePage, RawCP) then\n        Result := ZMoveAnsiToRaw(Value.VAnsiString, RawCP)\n      else\n        Result := ZConvertAnsiToRaw(Value.VAnsiString, RawCP);\n    vtUTF8String:\n      if ZCompatibleCodePages(zCP_UTF8, RawCP) then\n        Result := ZMoveUTF8ToRaw(Value.VUTF8String, RawCP)\n      else\n        Result := ZConvertUTF8ToRaw(Value.VUTF8String, RawCP);\n    vtRawByteString:\n      if ZCompatibleCodePages(FConSettings^.ClientCodePage^.CP, RawCP) then\n        Result := Value.VRawByteString\n      else\n      begin\n        US := ZRawToUnicode(Value.VRawByteString, FConSettings^.ClientCodePage^.CP);\n        Result := ZUnicodeToRaw(US, RawCP);\n      end;\n    vtUnicodeString:\n      Result := ZUnicodeToRaw(Value.VUnicodeString, RawCP);\n    vtDateTime:\n      Result := {$IFDEF WITH_RAWBYTESTRING}RawByteString{$ENDIF}(DateTimeToAnsiSQLDate(Value.VDateTime));\n    else\n      RaiseTypeMismatchError;\n  end;\nend;\n{$WARNINGS ON}\n\n{ TZAnyValue }\n\n{**\n  Constructs this object and assignes the main properties.\n  @param Value an any value.\n}\nconstructor TZAnyValue.Create(const Value: TZVariant);\nbegin\n  FValue := Value;\nend;\n\n{**\n  Constructs this object and assignes the main properties.\n  @param Value a boolean value.\n}\nconstructor TZAnyValue.CreateWithBoolean(Value: Boolean);\nbegin\n  FValue := EncodeBoolean(Value);\nend;\n\n{**\n  Constructs this object and assignes the main properties.\n  @param Value a datetime value.\n}\nconstructor TZAnyValue.CreateWithDateTime(Value: TDateTime);\nbegin\n  FValue := EncodeDateTime(Value);\nend;\n\n{**\n  Constructs this object and assignes the main properties.\n  @param Value a float value.\n}\nconstructor TZAnyValue.CreateWithFloat(Value: Extended);\nbegin\n  FValue := EncodeFloat(Value);\nend;\n\n{**\n  Constructs this object and assignes the main properties.\n  @param Value a integer value.\n}\nconstructor TZAnyValue.CreateWithInteger(Value: Int64);\nbegin\n  FValue := EncodeInteger(Value);\nend;\n\n{**\n  Constructs this object and assignes the main properties.\n  @param Value a string value.\n}\nconstructor TZAnyValue.CreateWithString(const Value: String);\nbegin\n  FValue := EncodeString(Value);\nend;\n\n{**\n  Constructs this object and assignes the main properties.\n  @param Value a unicode string value.\n}\n{$IFDEF UNICODE}\nconstructor TZAnyValue.CreateWithUnicodeString(const Value: String; unicodeType : Boolean = true);\n{$ELSE}\nconstructor TZAnyValue.CreateWithUnicodeString(const Value: WideString);\n{$ENDIF}\nbegin\n  FValue := EncodeUnicodeString(Value);\nend;\n\n{**\n  Clones an object instance.\n  @return a clonned object instance.\n}\nfunction TZAnyValue.Clone: IZInterface;\nbegin\n  Result := TZAnyValue.Create(FValue);\nend;\n\n{**\n  Compares this and another property.\n  @return <code>True</code> is properties are equal.\n}\nfunction TZAnyValue.Equals(const Value: IZInterface): Boolean;\nvar\n  Temp: IZAnyValue;\nbegin\n  if Value <> nil then\n  begin\n    if Value.QueryInterface(IZAnyValue, Temp) = 0 then\n    begin\n      Result := SoftVarManager.Compare(FValue, Temp.GetValue) = 0;\n      Temp := nil;\n    end\n    else\n      Result := inherited Equals(Value);\n  end\n  else\n    Result := False;\nend;\n\n{**\n  Gets a stored any value.\n  @return a stored any value.\n}\nfunction TZAnyValue.GetValue: TZVariant;\nbegin\n  Result := FValue;\nend;\n\n{**\n  Converts this object into the string representation.\n  @return a string representation for this object.\n}\nfunction TZAnyValue.ToString: string;\nbegin\n  Result := GetString;\nend;\n\n{**\n  Checks is the stored value contains NULL.\n  @returns <code>True</code> if NULL is stored.\n}\nfunction TZAnyValue.IsNull: Boolean;\nbegin\n  Result := SoftVarManager.IsNull(FValue);\nend;\n\n{**\n  Gets a stored value converted to double.\n  @return a stored value converted to double.\n}\nfunction TZAnyValue.GetFloat: Extended;\nbegin\n  Result := SoftVarManager.GetAsFloat(FValue);\nend;\n\n{**\n  Gets a stored value converted to integer.\n  @return a stored value converted to integer.\n}\nfunction TZAnyValue.GetInteger: Int64;\nbegin\n  Result := SoftVarManager.GetAsInteger(FValue);\nend;\n\n{**\n  Gets a stored value converted to String.\n  @return a stored value converted to string.\n}\nfunction TZAnyValue.GetString: String;\nbegin\n  Result := SoftVarManager.GetAsString(FValue);\nend;\n\n{**\n  Gets a stored value converted to AnsiString.\n  @return a stored value converted to string.\n}\nfunction TZAnyValue.GetAnsiString: AnsiString;\nbegin\n  Result := SoftVarManager.GetAsAnsiString(FValue);\nend;\n\n{**\n  Gets a stored value converted to AnsiString.\n  @return a stored value converted to string.\n}\nfunction TZAnyValue.GetUTF8String: UTF8String;\nbegin\n  Result := SoftVarManager.GetAsUTF8String(FValue);\nend;\n\n{**\n  Gets a stored value converted to boolean.\n  @return a stored value converted to boolean.\n}\nfunction TZAnyValue.GetBoolean: Boolean;\nbegin\n  Result := SoftVarManager.GetAsBoolean(FValue);\nend;\n\n{**\n  Gets a stored value converted to byte array.\n  @return a stored value converted to a byte array.\n}\nfunction TZAnyValue.GetBytes: TByteDynArray;\nbegin\n  Result := SoftVarManager.GetAsBytes(FValue);\nend;\n\n{**\n  Gets a stored value converted to unicode string.\n  @return a stored value converted to unicode string.\n}\nfunction TZAnyValue.GetUnicodeString: ZWideString;\nbegin\n  Result := SoftVarManager.GetAsUnicodeString(FValue);\nend;\n\n{**\n  Gets a stored value converted to datetime.\n  @return a stored value converted to datetime.\n}\nfunction TZAnyValue.GetDateTime: TDateTime;\nbegin\n  Result := SoftVarManager.GetAsDateTime(FValue);\nend;\n\n{**\n  Encodes a custom variant value into standard variant.\n  @param Value a custom variant value to be encoded.\n  @returns an encoded standard variant.\n}\nfunction EncodeVariant(const Value: TZVariant): Variant;\nbegin\n  case Value.VType of\n    vtBoolean: Result := Value.VBoolean;\n    vtBytes: Result := BytesToVar(Value.VBytes);\n    vtInteger:\n      if (Value.VInteger > -MaxInt) and (Value.VInteger < MaxInt) then\n        Result := Integer(Value.VInteger)\n      else\n{$ifdef fpc}\n        Result := Value.VInteger;\n{$else}\n        Result := IntToStr(Value.VInteger);\n{$endif}\n    vtFloat: Result := Value.VFloat;\n    vtString: Result := Value.VString;\n    vtAnsiString: Result := Value.VAnsiString;\n    vtUTF8String: Result := Value.VUTF8String;\n    vtRawByteString: Result := Value.VRawByteString;\n    vtUnicodeString: Result := Value.VUnicodeString;\n    vtDateTime: Result := Value.VDateTime;\n    vtPointer:\n    {$ifdef fpc}\n        Result := NativeInt(Value.VPointer);\n    {$else}\n        Result := NativeUInt(Value.VPointer);\n    {$endif}\n    vtInterface: Result := Value.VInterface;\n  else\n    Result := Null;\n  end;\nend;\n\n{**\n  Encodes an array of custom variant values into array of standard variants.\n  @param Value an array of custom variant values to be encoded.\n  @returns an encoded array of standard variants.\n}\nfunction EncodeVariantArray(const Value: TZVariantDynArray): Variant;\nvar\n  I, L: Integer;\nbegin\n  L := Length(Value);\n  Result := VarArrayCreate([0, L - 1], varVariant);\n  for I := 0 to L - 1 do\n    Result[I] := EncodeVariant(Value[I]);\nend;\n\n{**\n  Decodes a standard variant value into custom variant.\n  @param Value a standard variant value to be decoded.\n  @returns an decoded custom variant.\n}\nfunction DecodeVariant(const Value: Variant): TZVariant;\nbegin\n  case VarType(Value) of\n    varSmallint, varInteger, varByte:\n      Result := EncodeInteger(Integer(Value));\n    varBoolean: Result := EncodeBoolean(Value);\n    varString: Result := EncodeString(Value);\n   {$IFDEF UNICODE}\n   varUString: Result := EncodeUnicodeString(Value);\n   {$ENDIF}\n    varSingle, varDouble, varCurrency:\n      Result := EncodeFloat(Value);\n    varUnknown: Result := EncodeInterface(Value);\n    varOleStr:\n      Result := EncodeUnicodeString(Value);\n    varDate: Result := EncodeDateTime(Value);\n    varShortInt, varWord, varLongWord:\n      Result := EncodeInteger(Value);\n    varInt64{$IFDEF BDS5_UP},varUInt64{$ENDIF}:\n      Result := EncodeInteger(Value);\n  else\n    Result := EncodeNull;\n  end;\nend;\n\n{**\n  Decodes an array of standard variant values into array of custom variants.\n  @param Value an array of standard variant values to be decoded.\n  @returns an decoded array of custom variants.\n}\nfunction DecodeVariantArray(const Value: Variant): TZVariantDynArray;\nvar\n  I, L, H: Integer;\nbegin\n  if VarIsArray(Value) then\n  begin\n    L := VarArrayLowBound(Value, 1);\n    H := VarArrayHighBound(Value, 1);\n    SetLength(Result, H - L + 1);\n    for I := L to H do\n      Result[I - L] := DecodeVariant(Value[I]);\n  end\n  else\n  begin\n    SetLength(Result, 1);\n    Result[0] := DecodeVariant(Value);\n  end;\nend;\n\n{**\n  Creates a null variant.\n}\nfunction EncodeNull: TZVariant;\nbegin\n  Result.VType := vtNull;\nend;\n\n{**\n  Creates a boolean variant.\n  @param Value a value to be assigned.\n}\nfunction EncodeBoolean(const Value: Boolean): TZVariant;\nbegin\n  Result.VType := vtBoolean;\n  Result.VBoolean := Value;\nend;\n\n{**\n  Creates a bytes array variant.\n  @param Value a value to be assigned.\n}\nfunction EncodeBytes(const Value: TByteDynArray): TZVariant;\nbegin\n  Result.VType := vtBytes;\n  Result.VBytes := Value;\nend;\n\n{**\n  Creates a integer variant.\n  @param Value a value to be assigned.\n}\nfunction EncodeInteger(const Value: Int64): TZVariant;\nbegin\n  Result.VType := vtInteger;\n  Result.VInteger := Value;\nend;\n\n{**\n  Creates a float variant.\n  @param Value a value to be assigned.\n}\nfunction EncodeFloat(const Value: Extended): TZVariant;\nbegin\n  Result.VType := vtFloat;\n  Result.VFloat := Value;\nend;\n\n{**\n  Creates a AnsiString variant.\n  @param Value a value to be assigned.\n}\nfunction EncodeString(const Value: String): TZVariant;\nbegin\n  Result.VType := vtString;\n  Result.VString := Value;\nend;\n\n{**\n  Creates a AnsiString variant.\n  @param Value a value to be assigned.\n}\nfunction EncodeAnsiString(const Value: AnsiString): TZVariant;\nbegin\n  Result.VType := vtAnsiString;\n  Result.VAnsiString := Value;\nend;\n\n{**\n  Creates a UTF8String variant.\n  @param Value a value to be assigned.\n}\nfunction EncodeUTF8String(const Value: UTF8String): TZVariant;\nbegin\n  Result.VType := vtUTF8String;\n  Result.VUTF8String := Value;\nend;\n\n{**\n  Creates a UTF8String variant.\n  @param Value a value to be assigned.\n}\nfunction EncodeRawByteString(const Value: RawByteString): TZVariant;\nbegin\n  Result.VType := vtRawByteString;\n  Result.VRawByteString := Value;\nend;\n\n{**\n  Creates a UnicodeString variant.\n  @param Value a value to be assigned.\n}\nfunction EncodeUnicodeString(const Value: ZWideString): TZVariant;\nbegin\n  Result.VType := vtUnicodeString;\n  Result.VUnicodeString := Value;\nend;\n\n{**\n  Creates a TDateTime variant.\n  @param Value a value to be assigned.\n}\nfunction EncodeDateTime(const Value: TDateTime): TZVariant;\nbegin\n  Result.VType := vtDateTime;\n  Result.VDateTime := Value;\nend;\n\n{**\n  Creates a pointer variant.\n  @param Value a value to be assigned.\n}\nfunction EncodePointer(const Value: Pointer): TZVariant;\nbegin\n  Result.VType := vtPointer;\n  Result.VPointer := Value;\nend;\n\n{**\n  Creates an Interface variant.\n  @param Value a value to be assigned.\n}\nfunction EncodeInterface(const Value: IZInterface): TZVariant;\nbegin\n  Result.VType := vtInterface;\n  Result.VInterface := Value;\nend;\n\ninitialization\n  DefVarManager  := TZDefaultVariantManager.Create;\n  SoftVarManager := TZSoftVariantManager.Create;\n  NullVariant    := EncodeNull;\nfinalization\n  DefVarManager  := nil;\n  SoftVarManager := nil;\nend.\n\n\n"
  },
  {
    "path": "lib/zeosdbo/src/dbc/ZDbc.inc",
    "content": "{@********************************************************}\n{    Copyright (c) 1999-2012 Zeos Development Group       }\n{                                                         }\n{ License Agreement:                                      }\n{                                                         }\n{ This library is distributed in the hope that it will be }\n{ useful, but WITHOUT ANY WARRANTY; without even the      }\n{ implied warranty of MERCHANTABILITY or FITNESS FOR      }\n{ A PARTICULAR PURPOSE.  See the GNU Lesser General       }\n{ Public License for more details.                        }\n{                                                         }\n{ The source code of the ZEOS Libraries and packages are  }\n{ distributed under the Library GNU General Public        }\n{ License (see the file COPYING / COPYING.ZEOS)           }\n{ with the following  modification:                       }\n{ As a special exception, the copyright holders of this   }\n{ library give you permission to link this library with   }\n{ independent modules to produce an executable,           }\n{ regardless of the license terms of these independent    }\n{ modules, and to copy and distribute the resulting       }\n{ executable under terms of your choice, provided that    }\n{ you also meet, for each linked independent module,      }\n{ the terms and conditions of the license of that module. }\n{ An independent module is a module which is not derived  }\n{ from or based on this library. If you modify this       }\n{ library, you may extend this exception to your version  }\n{ of the library, but you are not obligated to do so.     }\n{ If you do not wish to do so, delete this exception      }\n{ statement from your version.                            }\n{                                                         }\n{                                                         }\n{ The project web site is located on:                     }\n{   http://zeos.firmos.at  (FORUM)                        }\n{   http://sourceforge.net/p/zeoslib/tickets/ (BUGTRACKER)}\n{   svn://svn.code.sf.net/p/zeoslib/code-0/trunk (SVN)    }\n{                                                         }\n{   http://www.sourceforge.net/projects/zeoslib.          }\n{                                                         }\n{                                                         }\n{                                 Zeos Development Group. }\n{********************************************************@}\n\n{$IFDEF LINUX}\n  {$DEFINE UNIX}\n{$ENDIF}\n\n{$IFNDEF UNIX}\n{$I ..\\Zeos.inc}\n{$ELSE}\n{$I ../Zeos.inc}\n{$ENDIF}\n"
  },
  {
    "path": "lib/zeosdbo/src/dbc/ZDbcASA.pas",
    "content": "{*********************************************************}\n{                                                         }\n{                 Zeos Database Objects                   }\n{         Interbase Database Connectivity Classes         }\n{                                                         }\n{        Originally written by Sergey Merkuriev           }\n{                                                         }\n{*********************************************************}\n\n{@********************************************************}\n{    Copyright (c) 1999-2012 Zeos Development Group       }\n{                                                         }\n{ License Agreement:                                      }\n{                                                         }\n{ This library is distributed in the hope that it will be }\n{ useful, but WITHOUT ANY WARRANTY; without even the      }\n{ implied warranty of MERCHANTABILITY or FITNESS FOR      }\n{ A PARTICULAR PURPOSE.  See the GNU Lesser General       }\n{ Public License for more details.                        }\n{                                                         }\n{ The source code of the ZEOS Libraries and packages are  }\n{ distributed under the Library GNU General Public        }\n{ License (see the file COPYING / COPYING.ZEOS)           }\n{ with the following  modification:                       }\n{ As a special exception, the copyright holders of this   }\n{ library give you permission to link this library with   }\n{ independent modules to produce an executable,           }\n{ regardless of the license terms of these independent    }\n{ modules, and to copy and distribute the resulting       }\n{ executable under terms of your choice, provided that    }\n{ you also meet, for each linked independent module,      }\n{ the terms and conditions of the license of that module. }\n{ An independent module is a module which is not derived  }\n{ from or based on this library. If you modify this       }\n{ library, you may extend this exception to your version  }\n{ of the library, but you are not obligated to do so.     }\n{ If you do not wish to do so, delete this exception      }\n{ statement from your version.                            }\n{                                                         }\n{                                                         }\n{ The project web site is located on:                     }\n{   http://zeos.firmos.at  (FORUM)                        }\n{   http://sourceforge.net/p/zeoslib/tickets/ (BUGTRACKER)}\n{   svn://svn.code.sf.net/p/zeoslib/code-0/trunk (SVN)    }\n{                                                         }\n{   http://www.sourceforge.net/projects/zeoslib.          }\n{                                                         }\n{                                                         }\n{                                 Zeos Development Group. }\n{********************************************************@}\n\nunit ZDbcASA;\n\ninterface\n\n{$I ZDbc.inc}\n\nuses\n  ZCompatibility, Classes, {$IFDEF MSEgui}mclasses,{$ENDIF} Contnrs, SysUtils,\n  ZDbcIntfs, ZDbcConnection, ZPlainASADriver, ZTokenizer, ZDbcGenericResolver,\n  ZURL, ZPlainDriver, ZGenericSqlAnalyser, ZPlainASAConstants;\n\ntype\n  {** Implements a ASA Database Driver. }\n  {$WARNINGS OFF}\n  TZASADriver = class(TZAbstractDriver)\n  public\n    constructor Create; override;\n    function Connect(const Url: TZURL): IZConnection; override;\n    function GetMajorVersion: Integer; override;\n    function GetMinorVersion: Integer; override;\n    function GetTokenizer: IZTokenizer; override;\n    function GetStatementAnalyser: IZStatementAnalyser; override;\n  end;\n  {$WARNINGS ON}\n\n  {** Represents a ASA specific connection interface. }\n  IZASAConnection = interface (IZConnection)\n    ['{FAAAFCE0-F550-4098-96C6-580145813EBF}']\n    function GetDBHandle: PZASASQLCA;\n    function GetPlainDriver: IZASAPlainDriver;\n//    procedure CreateNewDatabase(SQL: String);\n  end;\n\n  {** Implements ASA Database Connection. }\n  TZASAConnection = class(TZAbstractConnection, IZASAConnection)\n  private\n    FSQLCA: TZASASQLCA;\n    FHandle: PZASASQLCA;\n  private\n    procedure StartTransaction; virtual;\n    function DetermineASACharSet: String;\n  protected\n    procedure InternalCreate; override;\n  public\n    destructor Destroy; override;\n\n    function GetDBHandle: PZASASQLCA;\n    function GetPlainDriver: IZASAPlainDriver;\n//    procedure CreateNewDatabase(SQL: String);\n\n    function CreateRegularStatement(Info: TStrings): IZStatement; override;\n    function CreatePreparedStatement(const SQL: string; Info: TStrings):\n      IZPreparedStatement; override;\n    function CreateCallableStatement(const SQL: string; Info: TStrings):\n      IZCallableStatement; override;\n\n    procedure Commit; override;\n    procedure Rollback; override;\n    procedure SetOption(Temporary: Integer; User: PAnsiChar; const Option: string;\n      const Value: string);\n\n    procedure Open; override;\n    procedure Close; override;\n  end;\n\n  {** Implements a specialized cached resolver for ASA. }\n  TZASACachedResolver = class(TZGenericCachedResolver)\n  public\n    function FormCalculateStatement(Columns: TObjectList): string; override;\n  end;\n\n\nvar\n  {** The common driver manager object. }\n  ASADriver: IZDriver;\n\nimplementation\n\nuses\n  ZDbcASAMetadata, ZDbcASAStatement, ZDbcASAUtils, ZSybaseToken,\n  ZSybaseAnalyser, ZDbcLogging{$IFDEF WITH_UNITANSISTRINGS}, AnsiStrings{$ENDIF};\n\n{ TZASADriver }\n\n{**\n  Attempts to make a database connection to the given URL.\n  The driver should return \"null\" if it realizes it is the wrong kind\n  of driver to connect to the given URL.  This will be common, as when\n  the JDBC driver manager is asked to connect to a given URL it passes\n  the URL to each loaded driver in turn.\n\n  <P>The driver should raise a SQLException if it is the right\n  driver to connect to the given URL, but has trouble connecting to\n  the database.\n\n  <P>The java.util.Properties argument can be used to passed arbitrary\n  string tag/value pairs as connection arguments.\n  Normally at least \"user\" and \"password\" properties should be\n  included in the Properties.\n\n  @param url the URL of the database to which to connect\n  @param info a list of arbitrary string tag/value pairs as\n    connection arguments. Normally at least a \"user\" and\n    \"password\" property should be included.\n  @return a <code>Connection</code> object that represents a\n    connection to the URL\n}\n{$WARNINGS OFF}\nfunction TZASADriver.Connect(const Url: TZURL): IZConnection;\nbegin\n  Result := TZASAConnection.Create(Url);\nend;\n{$WARNINGS ON}\n\n{**\n  Constructs this object with default properties.\n}\nconstructor TZASADriver.Create;\nbegin\n  inherited Create;\n  AddSupportedProtocol(AddPlainDriverToCache(TZASA7PlainDriver.Create));\n  AddSupportedProtocol(AddPlainDriverToCache(TZASA8PlainDriver.Create));\n  AddSupportedProtocol(AddPlainDriverToCache(TZASA9PlainDriver.Create));\n  AddSupportedProtocol(AddPlainDriverToCache(TZASA12PlainDriver.Create));\nend;\n\n{**\n  Gets the driver's major version number. Initially this should be 1.\n  @return this driver's major version number\n}\nfunction TZASADriver.GetMajorVersion: Integer;\nbegin\n  Result := 1;\nend;\n\n{**\n  Gets the driver's minor version number. Initially this should be 0.\n  @return this driver's minor version number\n}\nfunction TZASADriver.GetMinorVersion: Integer;\nbegin\n  Result := 0;\nend;\n\n{**\n  Gets a SQL syntax tokenizer.\n  @returns a SQL syntax tokenizer object.\n}\nfunction TZASADriver.GetTokenizer: IZTokenizer;\nbegin\n  if Tokenizer = nil then\n    Tokenizer := TZSybaseTokenizer.Create;\n  Result := Tokenizer;\nend;\n\n{**\n  Creates a statement analyser object.\n  @returns a statement analyser object.\n}\nfunction TZASADriver.GetStatementAnalyser: IZStatementAnalyser;\nbegin\n  if Analyser = nil then\n    Analyser := TZSybaseStatementAnalyser.Create;\n  Result := Analyser;\nend;\n\n{ TZASAConnection }\n\n{**\n  Releases a Connection's database and JDBC resources\n  immediately instead of waiting for\n  them to be automatically released.\n\n  <P><B>Note:</B> A Connection is automatically closed when it is\n  garbage collected. Certain fatal errors also result in a closed\n  Connection.\n}\nprocedure TZASAConnection.Close;\nbegin\n  if Closed or (not Assigned(PlainDriver))then\n     Exit;\n\n  if AutoCommit then\n    Commit\n  else\n    Rollback;\n\n  GetPlainDriver.db_string_disconnect( FHandle, nil);\n  CheckASAError( GetPlainDriver, FHandle, lcDisconnect);\n\n  FHandle := nil;\n  if GetPlainDriver.db_fini( @FSQLCA) = 0 then\n  begin\n    DriverManager.LogError( lcConnect, PlainDriver.GetProtocol, 'Inititalizing SQLCA',\n      0, 'Error closing SQLCA');\n    raise EZSQLException.CreateWithCode( 0,\n      'Error closing SQLCA');\n  end;\n\n  DriverManager.LogMessage(lcDisconnect, PlainDriver.GetProtocol,\n      Format('DISCONNECT FROM \"%s\"', [Database]));\n\n  inherited Close;\nend;\n\n{**\n   Commit current transaction\n}\nprocedure TZASAConnection.Commit;\nbegin\n  if Closed or AutoCommit then\n     Exit;\n\n  if FHandle <> nil then\n  begin\n    GetPlainDriver.db_commit( FHandle, 0);\n    CheckASAError( GetPlainDriver, FHandle, lcTransaction);\n    DriverManager.LogMessage(lcTransaction,\n      PlainDriver.GetProtocol, 'TRANSACTION COMMIT');\n  end;\nend;\n\n{**\n  Constructs this object and assignes the main properties.\n}\nprocedure TZASAConnection.InternalCreate;\nbegin\n  Self.FMetadata := TZASADatabaseMetadata.Create(Self, URL);\nend;\n\n{**\n  Creates a <code>CallableStatement</code> object for calling\n  database stored procedures.\n  The <code>CallableStatement</code> object provides\n  methods for setting up its IN and OUT parameters, and\n  methods for executing the call to a stored procedure.\n\n  <P><B>Note:</B> This method is optimized for handling stored\n  procedure call statements. Some drivers may send the call\n  statement to the database when the method <code>prepareCall</code>\n  is done; others\n  may wait until the <code>CallableStatement</code> object\n  is executed. This has no\n  direct effect on users; however, it does affect which method\n  throws certain SQLExceptions.\n\n  Result sets created using the returned CallableStatement will have\n  forward-only type and read-only concurrency, by default.\n\n  @param sql a SQL statement that may contain one or more '?'\n    parameter placeholders. Typically this  statement is a JDBC\n    function call escape string.\n  @param Info a statement parameters.\n  @return a new CallableStatement object containing the\n    pre-compiled SQL statement\n}\nfunction TZASAConnection.CreateCallableStatement(const SQL: string;\n  Info: TStrings): IZCallableStatement;\nbegin\n  if IsClosed then\n     Open;\n  Result := TZASACallableStatement.Create(Self, SQL, Info);\nend;\n\n{**\n  Creates a <code>PreparedStatement</code> object for sending\n  parameterized SQL statements to the database.\n\n  A SQL statement with or without IN parameters can be\n  pre-compiled and stored in a PreparedStatement object. This\n  object can then be used to efficiently execute this statement\n  multiple times.\n\n  <P><B>Note:</B> This method is optimized for handling\n  parametric SQL statements that benefit from precompilation. If\n  the driver supports precompilation,\n  the method <code>prepareStatement</code> will send\n  the statement to the database for precompilation. Some drivers\n  may not support precompilation. In this case, the statement may\n  not be sent to the database until the <code>PreparedStatement</code> is\n  executed.  This has no direct effect on users; however, it does\n  affect which method throws certain SQLExceptions.\n\n  Result sets created using the returned PreparedStatement will have\n  forward-only type and read-only concurrency, by default.\n\n  @param sql a SQL statement that may contain one or more '?' IN\n    parameter placeholders\n  @return a new PreparedStatement object containing the\n    pre-compiled statement\n}\nfunction TZASAConnection.CreatePreparedStatement(const SQL: string;\n  Info: TStrings): IZPreparedStatement;\nbegin\n  if IsClosed then\n     Open;\n  Result := TZASAPreparedStatement.Create(Self, SQL, Info);\nend;\n\n{**\n  Creates a <code>Statement</code> object for sending\n  SQL statements to the database.\n  SQL statements without parameters are normally\n  executed using Statement objects. If the same SQL statement\n  is executed many times, it is more efficient to use a\n  <code>PreparedStatement</code> object.\n  <P>\n  Result sets created using the returned <code>Statement</code>\n  object will by default have forward-only type and read-only concurrency.\n\n  @param Info a statement parameters.\n  @return a new Statement object\n}\nfunction TZASAConnection.CreateRegularStatement(\n  Info: TStrings): IZStatement;\nbegin\n  if IsClosed then\n     Open;\n  Result := TZASAStatement.Create(Self, Info);\nend;\n\n{**\n  Destroys this object and cleanups the memory.\n}\ndestructor TZASAConnection.Destroy;\nbegin\n  if not Closed then\n    Close;\n\n  inherited;\nend;\n\n{**\n   Get database connection handle.\n   @return database handle\n}\nfunction TZASAConnection.GetDBHandle: PZASASQLCA;\nbegin\n  Result := FHandle;\nend;\n\n{**\n   Return native interbase plain driver\n   @return plain driver\n}\nfunction TZASAConnection.GetPlainDriver: IZASAPlainDriver;\nbegin\n  Result := PlainDriver as IZASAPlainDriver;\nend;\n\n{**\n  Opens a connection to database server with specified parameters.\n}\nprocedure TZASAConnection.Open;\nvar\n  ConnectionString, Links: string;\nbegin\n  if not Closed then\n     Exit;\n\n  FHandle := nil;\n  ConnectionString := '';\n  try\n    if GetPlainDriver.db_init( @FSQLCA) = 0 then\n    begin\n      DriverManager.LogError( lcConnect, PlainDriver.GetProtocol, 'Inititalizing SQLCA',\n        0, 'Error initializing SQLCA');\n      raise EZSQLException.CreateWithCode( 0,\n        'Error initializing SQLCA');\n    end;\n    FHandle := @FSQLCA;\n\n    if HostName <> '' then\n      ConnectionString := ConnectionString + 'ENG=\"' + HostName + '\"; ';\n    if User <> '' then\n      ConnectionString := ConnectionString + 'UID=\"' + User + '\"; ';\n    if Password <> '' then\n      ConnectionString := ConnectionString + 'PWD=\"' + Password + '\"; ';\n    if Database <> '' then\n    begin\n      if CompareText( ExtractFileExt( Database), '.db') = 0 then\n        ConnectionString := ConnectionString + 'DBF=\"' + Database + '\"; '\n      else\n        ConnectionString := ConnectionString + 'DBN=\"' + Database + '\"; ';\n    end;\n\n    Links := '';\n    if Info.Values['CommLinks'] <> ''\n      then Links := 'CommLinks=' + Info.Values['CommLinks'];\n    if Info.Values['LINKS'] <> ''\n      then Links := 'LINKS=' + Info.Values['LINKS'];\n    if (Links = '') and (Port <> 0)\n      then Links := 'LINKS=tcpip(PORT=' + IntToStr(Port) + ')';\n    if Links <> ''\n      then ConnectionString := ConnectionString + Links + '; ';\n\n    GetPlainDriver.db_string_connect(FHandle, PAnsiChar(AnsiString(ConnectionString)));\n    CheckASAError( GetPlainDriver, FHandle, lcConnect);\n\n    DriverManager.LogMessage(lcConnect, PlainDriver.GetProtocol,\n      Format('CONNECT TO \"%s\" AS USER \"%s\"', [Database, User]));\n\n    if ( FClientCodePage <> '' ) then\n      if ( GetPlainDriver.db_change_char_charset(FHandle, PAnsiChar(AnsiString(FClientCodePage))) = 0 ) or\n         ( GetPlainDriver.db_change_nchar_charset(FHandle, PAnsiChar(AnsiString(FClientCodePage))) = 0 ) then\n        CheckASAError( GetPlainDriver, FHandle, lcOther, 'Set client CharacterSet failed.');\n\n    StartTransaction;\n\n    //SetConnOptions     RowCount;\n\n  except\n    on E: Exception do\n    begin\n      if Assigned( FHandle) then\n        GetPlainDriver.db_fini( FHandle);\n      FHandle := nil;\n      raise;\n    end;\n  end;\n\n  inherited Open;\n\n  if FClientCodePage = ''  then\n    CheckCharEncoding(DetermineASACharSet);\nend;\n\n{**\n  Drops all changes made since the previous\n  commit/rollback and releases any database locks currently held\n  by this Connection. This method should be used only when auto-\n  commit has been disabled.\n  @see #setAutoCommit\n}\nprocedure TZASAConnection.Rollback;\nbegin\n  if Closed or AutoCommit then\n     Exit;\n\n  if Assigned( FHandle) then\n  begin\n    GetPlainDriver.db_rollback( FHandle, 0);\n    CheckASAError( GetPlainDriver, FHandle, lcTransaction);\n    DriverManager.LogMessage(lcTransaction,\n      PlainDriver.GetProtocol, 'TRANSACTION ROLLBACK');\n  end;\nend;\n\nprocedure TZASAConnection.SetOption(Temporary: Integer; User: PAnsiChar;\n  const Option: string; const Value: string);\nvar\n  SQLDA: PASASQLDA;\n  Sz: Integer;\n  S: string;\nbegin\n  if Assigned( FHandle) then\n  begin\n    Sz := SizeOf( TASASQLDA) - 32767 * SizeOf( TZASASQLVAR);\n    SQLDA := AllocMem( Sz);\n    try\n      {$IFDEF WITH_STRPLCOPY_DEPRECATED}AnsiStrings.{$ENDIF}StrPLCopy( SQLDA.sqldaid, 'SQLDA   ', 8);\n      SQLDA.sqldabc := Sz;\n      SQLDA.sqln := 1;\n      SQLDA.sqld := 1;\n      SQLDA.sqlVar[0].sqlType := DT_STRING;\n      SQLDA.sqlVar[0].sqlLen := Length( Value)+1;\n      SQLDA.sqlVar[0].sqlData := PAnsiChar(AnsiString(Value));\n      GetPlainDriver.db_setoption(FHandle, Temporary, User, PAnsiChar(AnsiString(Option)), SQLDA);\n\n      CheckASAError( GetPlainDriver, FHandle, lcOther);\n      S := String(User);\n      DriverManager.LogMessage( lcOther, PlainDriver.GetProtocol,\n        Format( 'SET OPTION %s.%s = %s', [ S, Option, Value]));\n    finally\n      FreeMem( SQLDA);\n    end;\n  end;\nend;\n\n{**\n   Start transaction\n}\nprocedure TZASAConnection.StartTransaction;\nvar\n  ASATL: integer;\nbegin\n  if AutoCommit then\n    SetOption( 1, nil, 'CHAINED', 'OFF')\n  else\n    SetOption( 1, nil, 'CHAINED', 'ON');\n  ASATL := Ord( TransactIsolationLevel);\n  if ASATL > 1 then\n    ASATL := ASATL - 1;\n  SetOption( 1, nil, 'ISOLATION_LEVEL', IntToStr( ASATL));\nend;\n\nfunction TZASAConnection.DetermineASACharSet: String;\nvar\n  Stmt: IZStatement;\n  RS: IZResultSet;\nbegin\n  Stmt := Self.CreateRegularStatement(Info);\n  RS := Stmt.ExecuteQuery('SELECT DB_PROPERTY( ''CharSet'')');\n  if RS.Next then\n    Result := RS.GetString(1)\n  else\n    Result := '';\n  RS := nil;\n  Stmt.Close;\n  Stmt := nil;\nend;\n\n{ TZASACachedResolver }\n\n{**\n  Forms a where clause for SELECT statements to calculate default values.\n  @param Columns a collection of key columns.\n  @param OldRowAccessor an accessor object to old column values.\n}\nfunction TZASACachedResolver.FormCalculateStatement(\n  Columns: TObjectList): string;\nvar\n  I: Integer;\n  Current: TZResolverParameter;\nbegin\n  Result := '';\n  if Columns.Count = 0 then\n     Exit;\n\n  for I := 0 to Columns.Count - 1 do\n  begin\n    Current := TZResolverParameter(Columns[I]);\n    if Result <> '' then\n      Result := Result + ',';\n    if Current.DefaultValue <> '' then\n      Result := Result + Current.DefaultValue\n    else\n      Result := Result + 'NULL';\n  end;\n  Result := 'SELECT ' + Result;\nend;\n\ninitialization\n  ASADriver := TZASADriver.Create;\n  DriverManager.RegisterDriver(ASADriver);\n\nfinalization\n  if Assigned(DriverManager) then\n    DriverManager.DeregisterDriver(ASADriver);\n  ASADriver := nil;\nend.\n"
  },
  {
    "path": "lib/zeosdbo/src/dbc/ZDbcASAMetadata.pas",
    "content": "{*********************************************************}\n{                                                         }\n{                 Zeos Database Objects                   }\n{         Interbase Database Connectivity Classes         }\n{                                                         }\n{        Originally written by Sergey Merkuriev           }\n{                                                         }\n{*********************************************************}\n\n{@********************************************************}\n{    Copyright (c) 1999-2012 Zeos Development Group       }\n{                                                         }\n{ License Agreement:                                      }\n{                                                         }\n{ This library is distributed in the hope that it will be }\n{ useful, but WITHOUT ANY WARRANTY; without even the      }\n{ implied warranty of MERCHANTABILITY or FITNESS FOR      }\n{ A PARTICULAR PURPOSE.  See the GNU Lesser General       }\n{ Public License for more details.                        }\n{                                                         }\n{ The source code of the ZEOS Libraries and packages are  }\n{ distributed under the Library GNU General Public        }\n{ License (see the file COPYING / COPYING.ZEOS)           }\n{ with the following  modification:                       }\n{ As a special exception, the copyright holders of this   }\n{ library give you permission to link this library with   }\n{ independent modules to produce an executable,           }\n{ regardless of the license terms of these independent    }\n{ modules, and to copy and distribute the resulting       }\n{ executable under terms of your choice, provided that    }\n{ you also meet, for each linked independent module,      }\n{ the terms and conditions of the license of that module. }\n{ An independent module is a module which is not derived  }\n{ from or based on this library. If you modify this       }\n{ library, you may extend this exception to your version  }\n{ of the library, but you are not obligated to do so.     }\n{ If you do not wish to do so, delete this exception      }\n{ statement from your version.                            }\n{                                                         }\n{                                                         }\n{ The project web site is located on:                     }\n{   http://zeos.firmos.at  (FORUM)                        }\n{   http://sourceforge.net/p/zeoslib/tickets/ (BUGTRACKER)}\n{   svn://svn.code.sf.net/p/zeoslib/code-0/trunk (SVN)    }\n{                                                         }\n{   http://www.sourceforge.net/projects/zeoslib.          }\n{                                                         }\n{                                                         }\n{                                 Zeos Development Group. }\n{********************************************************@}\n\nunit ZDbcASAMetadata;\n\ninterface\n\n{$I ZDbc.inc}\n\nuses\n  Types, Classes, SysUtils, ZDbcIntfs, ZDbcMetadata, ZCompatibility,\n  ZDbcConnection, ZDbcASA, ZURL;\n\ntype\n\n  // technobot 2008-06-28 - methods moved as is from TZASADatabaseMetadata:\n  {** Implements ASA Database Information. }\n  TZASADatabaseInfo = class(TZAbstractDatabaseInfo)\n  public\n    constructor Create(const Metadata: TZAbstractDatabaseMetadata);\n    destructor Destroy; override;\n\n    // database/driver/server info:\n    function GetDatabaseProductName: string; override;\n    function GetDatabaseProductVersion: string; override;\n    function GetDriverName: string; override;\n//    function GetDriverVersion: string; override; -> Same as parent\n    function GetDriverMajorVersion: Integer; override;\n    function GetDriverMinorVersion: Integer; override;\n//    function GetServerVersion: string; -> Not implemented\n\n    // capabilities (what it can/cannot do):\n//    function AllProceduresAreCallable: Boolean; override; -> Not implemented\n//    function AllTablesAreSelectable: Boolean; override; -> Not implemented\n    function SupportsMixedCaseIdentifiers: Boolean; override;\n    function SupportsMixedCaseQuotedIdentifiers: Boolean; override;\n//    function SupportsAlterTableWithAddColumn: Boolean; override; -> Not implemented\n//    function SupportsAlterTableWithDropColumn: Boolean; override; -> Not implemented\n//    function SupportsColumnAliasing: Boolean; override; -> Not implemented\n//    function SupportsConvert: Boolean; override; -> Not implemented\n//    function SupportsConvertForTypes(FromType: TZSQLType; ToType: TZSQLType):\n//      Boolean; override; -> Not implemented\n//    function SupportsTableCorrelationNames: Boolean; override; -> Not implemented\n//    function SupportsDifferentTableCorrelationNames: Boolean; override; -> Not implemented\n    function SupportsExpressionsInOrderBy: Boolean; override;\n    function SupportsOrderByUnrelated: Boolean; override;\n    function SupportsGroupBy: Boolean; override;\n    function SupportsGroupByUnrelated: Boolean; override;\n    function SupportsGroupByBeyondSelect: Boolean; override;\n//    function SupportsLikeEscapeClause: Boolean; override; -> Not implemented\n//    function SupportsMultipleResultSets: Boolean; override; -> Not implemented\n//    function SupportsMultipleTransactions: Boolean; override; -> Not implemented\n//    function SupportsNonNullableColumns: Boolean; override; -> Not implemented\n//    function SupportsMinimumSQLGrammar: Boolean; override; -> Not implemented\n//    function SupportsCoreSQLGrammar: Boolean; override; -> Not implemented\n//    function SupportsExtendedSQLGrammar: Boolean; override; -> Not implemented\n//    function SupportsANSI92EntryLevelSQL: Boolean; override; -> Not implemented\n//    function SupportsANSI92IntermediateSQL: Boolean; override; -> Not implemented\n//    function SupportsANSI92FullSQL: Boolean; override; -> Not implemented\n    function SupportsIntegrityEnhancementFacility: Boolean; override;\n//    function SupportsOuterJoins: Boolean; override; -> Not implemented\n//    function SupportsFullOuterJoins: Boolean; override; -> Not implemented\n//    function SupportsLimitedOuterJoins: Boolean; override; -> Not implemented\n    function SupportsSchemasInDataManipulation: Boolean; override;\n    function SupportsSchemasInProcedureCalls: Boolean; override;\n    function SupportsSchemasInTableDefinitions: Boolean; override;\n    function SupportsSchemasInIndexDefinitions: Boolean; override;\n    function SupportsSchemasInPrivilegeDefinitions: Boolean; override;\n    function SupportsCatalogsInDataManipulation: Boolean; override;\n    function SupportsCatalogsInProcedureCalls: Boolean; override;\n    function SupportsCatalogsInTableDefinitions: Boolean; override;\n    function SupportsCatalogsInIndexDefinitions: Boolean; override;\n    function SupportsCatalogsInPrivilegeDefinitions: Boolean; override;\n    function SupportsPositionedDelete: Boolean; override;\n    function SupportsPositionedUpdate: Boolean; override;\n    function SupportsSelectForUpdate: Boolean; override;\n    function SupportsStoredProcedures: Boolean; override;\n    function SupportsSubqueriesInComparisons: Boolean; override;\n    function SupportsSubqueriesInExists: Boolean; override;\n    function SupportsSubqueriesInIns: Boolean; override;\n    function SupportsSubqueriesInQuantifieds: Boolean; override;\n    function SupportsCorrelatedSubqueries: Boolean; override;\n    function SupportsUnion: Boolean; override;\n    function SupportsUnionAll: Boolean; override;\n    function SupportsOpenCursorsAcrossCommit: Boolean; override;\n    function SupportsOpenCursorsAcrossRollback: Boolean; override;\n    function SupportsOpenStatementsAcrossCommit: Boolean; override;\n    function SupportsOpenStatementsAcrossRollback: Boolean; override;\n    function SupportsTransactions: Boolean; override;\n    function SupportsTransactionIsolationLevel(Level: TZTransactIsolationLevel):\n      Boolean; override;\n    function SupportsDataDefinitionAndDataManipulationTransactions: Boolean; override;\n    function SupportsDataManipulationTransactionsOnly: Boolean; override;\n    function SupportsResultSetType(_Type: TZResultSetType): Boolean; override;\n    function SupportsResultSetConcurrency(_Type: TZResultSetType;\n      Concurrency: TZResultSetConcurrency): Boolean; override;\n//    function SupportsBatchUpdates: Boolean; override; -> Not implemented\n\n    // maxima:\n    function GetMaxBinaryLiteralLength: Integer; override;\n    function GetMaxCharLiteralLength: Integer; override;\n    function GetMaxColumnNameLength: Integer; override;\n    function GetMaxColumnsInGroupBy: Integer; override;\n    function GetMaxColumnsInIndex: Integer; override;\n    function GetMaxColumnsInOrderBy: Integer; override;\n    function GetMaxColumnsInSelect: Integer; override;\n    function GetMaxColumnsInTable: Integer; override;\n    function GetMaxConnections: Integer; override;\n    function GetMaxCursorNameLength: Integer; override;\n    function GetMaxIndexLength: Integer; override;\n    function GetMaxSchemaNameLength: Integer; override;\n    function GetMaxProcedureNameLength: Integer; override;\n    function GetMaxCatalogNameLength: Integer; override;\n    function GetMaxRowSize: Integer; override;\n    function GetMaxStatementLength: Integer; override;\n    function GetMaxStatements: Integer; override;\n    function GetMaxTableNameLength: Integer; override;\n    function GetMaxTablesInSelect: Integer; override;\n    function GetMaxUserNameLength: Integer; override;\n\n    // policies (how are various data and operations handled):\n//    function IsReadOnly: Boolean; override; -> Not implemented\n//    function IsCatalogAtStart: Boolean; override; -> Not implemented\n    function DoesMaxRowSizeIncludeBlobs: Boolean; override;\n//    function NullsAreSortedHigh: Boolean; override; -> Not implemented\n//    function NullsAreSortedLow: Boolean; override; -> Not implemented\n    function NullsAreSortedAtStart: Boolean; override;\n//    function NullsAreSortedAtEnd: Boolean; override; -> Not implemented\n//    function NullPlusNonNullIsNull: Boolean; override; -> Not implemented\n    function UsesLocalFiles: Boolean; override;\n    function UsesLocalFilePerTable: Boolean; override;\n    function StoresUpperCaseIdentifiers: Boolean; override;\n    function StoresLowerCaseIdentifiers: Boolean; override;\n    function StoresMixedCaseIdentifiers: Boolean; override;\n    function StoresUpperCaseQuotedIdentifiers: Boolean; override;\n    function StoresLowerCaseQuotedIdentifiers: Boolean; override;\n    function StoresMixedCaseQuotedIdentifiers: Boolean; override;\n    function GetDefaultTransactionIsolation: TZTransactIsolationLevel; override;\n    function DataDefinitionCausesTransactionCommit: Boolean; override;\n    function DataDefinitionIgnoredInTransactions: Boolean; override;\n\n    // interface details (terms, keywords, etc):\n//    function GetIdentifierQuoteString: string; override; -> Not implemented\n    function GetSchemaTerm: string; override;\n    function GetProcedureTerm: string; override;\n    function GetCatalogTerm: string; override;\n    function GetCatalogSeparator: string; override;\n    function GetSQLKeywords: string; override;\n    function GetNumericFunctions: string; override;\n    function GetStringFunctions: string; override;\n    function GetSystemFunctions: string; override;\n    function GetTimeDateFunctions: string; override;\n    function GetSearchStringEscape: string; override;\n    function GetExtraNameCharacters: string; override;\n  end;\n\n  {** Implements ASA Database Metadata. }\n  TZASADatabaseMetadata = class(TZAbstractDatabaseMetadata)\n  private\n    FASAConnection: TZASAConnection;\n    function ComposeObjectString(const S: String; Const NullText: String = 'null';\n      QuoteChar: Char = #39): String;\n  protected\n    function CreateDatabaseInfo: IZDatabaseInfo; override; // technobot 2008-06-28\n\n    function UncachedGetTables(const Catalog: string; const SchemaPattern: string;\n      const TableNamePattern: string; const Types: TStringDynArray): IZResultSet; override;\n    function UncachedGetSchemas: IZResultSet; override;\n//    function UncachedGetCatalogs: IZResultSet; override; -> Not implemented\n    function UncachedGetTableTypes: IZResultSet; override;\n    function UncachedGetColumns(const Catalog: string; const SchemaPattern: string;\n      const TableNamePattern: string; const ColumnNamePattern: string): IZResultSet; override;\n    function UncachedGetTablePrivileges(const Catalog: string; const SchemaPattern: string;\n      const TableNamePattern: string): IZResultSet; override;\n    function UncachedGetColumnPrivileges(const Catalog: string; const Schema: string;\n      const Table: string; const ColumnNamePattern: string): IZResultSet; override;\n    function UncachedGetPrimaryKeys(const Catalog: string; const Schema: string;\n      const Table: string): IZResultSet; override;\n    function UncachedGetImportedKeys(const Catalog: string; const Schema: string;\n      const Table: string): IZResultSet; override;\n    function UncachedGetExportedKeys(const Catalog: string; const Schema: string;\n      const Table: string): IZResultSet; override;\n    function UncachedGetCrossReference(const PrimaryCatalog: string; const PrimarySchema: string;\n      const PrimaryTable: string; const ForeignCatalog: string; const ForeignSchema: string;\n      const ForeignTable: string): IZResultSet; override;\n    function UncachedGetIndexInfo(const Catalog: string; const Schema: string; const Table: string;\n      Unique: Boolean; Approximate: Boolean): IZResultSet; override;\n//     function UncachedGetSequences(const Catalog: string; const SchemaPattern: string;\n//      const SequenceNamePattern: string): IZResultSet; virtual; -> Not implemented\n    function UncachedGetProcedures(const Catalog: string; const SchemaPattern: string;\n      const ProcedureNamePattern: string): IZResultSet; override;\n    function UncachedGetProcedureColumns(const Catalog: string; const SchemaPattern: string;\n      const ProcedureNamePattern: string; const ColumnNamePattern: string):\n      IZResultSet; override;\n    function UncachedGetVersionColumns(const Catalog: string; const Schema: string;\n      const Table: string): IZResultSet; override;\n    function UncachedGetTypeInfo: IZResultSet; override;\n    function UncachedGetUDTs(const Catalog: string; const SchemaPattern: string;\n      const TypeNamePattern: string; const Types: TIntegerDynArray): IZResultSet; override;\n  public\n    constructor Create(Connection: TZAbstractConnection; const Url: TZURL); override;\n  end;\n\nimplementation\n\nuses ZDbcASAUtils, ZDbcUtils;\n\n{ TZASADatabaseInfo }\n\n{**\n  Constructs this object.\n  @param Metadata the interface of the correpsonding database metadata object\n}\nconstructor TZASADatabaseInfo.Create(const Metadata: TZAbstractDatabaseMetadata);\nbegin\n  inherited;\nend;\n\n{**\n  Destroys this object and cleanups the memory.\n}\ndestructor TZASADatabaseInfo.Destroy;\nbegin\n  inherited;\nend;\n\n//----------------------------------------------------------------------\n// First, a variety of minor information about the target database.\n\n{**\n  Are NULL values sorted at the start regardless of sort order?\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZASADatabaseInfo.NullsAreSortedAtStart: Boolean;\nbegin\n  Result := True;\nend;\n\n{**\n  What's the name of this database product?\n  @return database product name\n}\nfunction TZASADatabaseInfo.GetDatabaseProductName: string;\nbegin\n  Result := 'Sybase ASA';\nend;\n\n{**\n  What's the version of this database product?\n  @return database version\n}\nfunction TZASADatabaseInfo.GetDatabaseProductVersion: string;\nbegin\n  Result := '7.0+';\nend;\n\n{**\n  What's the name of this JDBC driver?\n  @return JDBC driver name\n}\nfunction TZASADatabaseInfo.GetDriverName: string;\nbegin\n  Result := 'Zeos Database Connectivity Driver for Sybase ASA';\nend;\n\n{**\n  What's this JDBC driver's major version number?\n  @return JDBC driver major version\n}\nfunction TZASADatabaseInfo.GetDriverMajorVersion: Integer;\nbegin\n  Result := 1;\nend;\n\n{**\n  What's this JDBC driver's minor version number?\n  @return JDBC driver minor version number\n}\nfunction TZASADatabaseInfo.GetDriverMinorVersion: Integer;\nbegin\n  Result := 0;\nend;\n\n{**\n  Does the database store tables in a local file?\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZASADatabaseInfo.UsesLocalFiles: Boolean;\nbegin\n  Result := False;\nend;\n\n{**\n  Does the database use a file for each table?\n  @return true if the database uses a local file for each table\n}\nfunction TZASADatabaseInfo.UsesLocalFilePerTable: Boolean;\nbegin\n  Result := False;\nend;\n\n{**\n  Does the database treat mixed case unquoted SQL identifiers as\n  case sensitive and as a result store them in mixed case?\n  A JDBC Compliant<sup><font size=-2>TM</font></sup> driver will always return false.\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZASADatabaseInfo.SupportsMixedCaseIdentifiers: Boolean;\nbegin\n  Result := False;\nend;\n\n{**\n  Does the database treat mixed case unquoted SQL identifiers as\n  case insensitive and store them in upper case?\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZASADatabaseInfo.StoresUpperCaseIdentifiers: Boolean;\nbegin\n  Result := False;\nend;\n\n{**\n  Does the database treat mixed case unquoted SQL identifiers as\n  case insensitive and store them in lower case?\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZASADatabaseInfo.StoresLowerCaseIdentifiers: Boolean;\nbegin\n  Result := False;\nend;\n\n{**\n  Does the database treat mixed case unquoted SQL identifiers as\n  case insensitive and store them in mixed case?\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZASADatabaseInfo.StoresMixedCaseIdentifiers: Boolean;\nbegin\n  Result := True;\nend;\n\n{**\n  Does the database treat mixed case quoted SQL identifiers as\n  case sensitive and as a result store them in mixed case?\n  A JDBC Compliant<sup><font size=-2>TM</font></sup> driver will always return true.\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZASADatabaseInfo.SupportsMixedCaseQuotedIdentifiers: Boolean;\nbegin\n  Result := False;\nend;\n\n{**\n  Does the database treat mixed case quoted SQL identifiers as\n  case insensitive and store them in upper case?\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZASADatabaseInfo.StoresUpperCaseQuotedIdentifiers: Boolean;\nbegin\n  Result := False;\nend;\n\n{**\n  Does the database treat mixed case quoted SQL identifiers as\n  case insensitive and store them in lower case?\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZASADatabaseInfo.StoresLowerCaseQuotedIdentifiers: Boolean;\nbegin\n  Result := False;\nend;\n\n{**\n  Does the database treat mixed case quoted SQL identifiers as\n  case insensitive and store them in mixed case?\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZASADatabaseInfo.StoresMixedCaseQuotedIdentifiers: Boolean;\nbegin\n  Result := True;\nend;\n\n{**\n  Gets a comma-separated list of all a database's SQL keywords\n  that are NOT also SQL92 keywords.\n  @return the list\n}\nfunction TZASADatabaseInfo.GetSQLKeywords: string;\nbegin\n  Result := 'add,all,alter,and,any,as,asc,backup,begin,between,bigint,binary,'+\n            'bit,bottom,break,by,call,capability,cascade,case,cast,char,'+\n            'char_convert,character,check,checkpoint,close,comment,commit,'+\n            'connect,constraint,contains,continue,convert,create,cross,cube,'+\n            'current,cursor,date,dbspace,deallocate,dec,decimal,declare,'+\n            'default,delete,deleting,desc,distinct,do,double,drop,dynamic,'+\n            'else,elseif,encrypted,end,endif,escape,exception,exec,execute,'+\n            'existing,exists,externlogin,fetch,first,float,for,foreign,'+\n            'forward,from,full,goto,grant,group,having,holdlock,identified,'+\n            'if,in,index,inner,inout,insensitive,insert,inserting,install,'+\n            'instead,int,integer,integrated,into,iq,is,isolation,join,key,'+\n            'left,like,lock,login,long,match,membership,message,mode,modify,'+\n            'natural,new,no,noholdlock,not,notify,null,numeric,of,off,on,open,'+\n            'option,options,or,order,others,out,outer,over,passthrough,'+\n            'precision,prepare,primary,print,privileges,proc,procedure,'+\n            'publication,raiserror,readtext,real,reference,references,release,'+\n            'remote,remove,rename,reorganize,resource,restore,restrict,return'+\n            'revoke,right,rollback,rollup,save,savepoint,schedule,scroll,'+\n            'select,sensitive,session,set,setuser,share,smallint,some,sqlcode,'+\n            'sqlstate,start,stop,subtrans,subtransaction,synchronize,'+\n            'syntax_error,table,temporary,then,time,timestamp,tinyint,to,top,'+\n            'tran,trigger,truncate,tsequal,union,unique,unknown,unsigned,'+\n            'update,updating,user,using,validate,values,varbinary,varchar,'+\n            'variable,varying,view,wait,waitfor,when,where,while,with,'+\n            'with_lparen,work,writetext';\nend;\n\n{**\n  Gets a comma-separated list of math functions.  These are the\n  X/Open CLI math function names used in the JDBC function escape\n  clause.\n  @return the list\n}\nfunction TZASADatabaseInfo.GetNumericFunctions: string;\nbegin\n  Result := 'ABS,ACOS,ASIN,ATAN,ATN2,CEILING,COS,COT,DEGREES,EXP,FLOOR,LOG,'+\n            'LOG10,MOD,PI,POWER,RADIANS,RAND,REMAINDER,ROUND,SIGN,SIN,SQRT,'+\n            'TAN,TRUNCATE,TRUNCNUM';\nend;\n\n{**\n  Gets a comma-separated list of string functions.  These are the\n  X/Open CLI string function names used in the JDBC function escape\n  clause.\n  @return the list\n}\nfunction TZASADatabaseInfo.GetStringFunctions: string;\nbegin\n  Result := 'ASCII,BYTE_LENGTH,BYTE_SUBSTR,CHAR,CHARINDEX,CHAR_LENGTH,COMPARE,'+\n            'CSCONVERT,DIFFERENCE,INSERTSTR,LCASE,LEFT,LENGTH,LOCATE,LOWER,'+\n            'LTRIM,PATINDEX,REPEAT,REPLACE,REPLICATE,RIGHT,RTRIM,SIMILAR,'+\n            'SORTKEY,SOUNDEX,SPACE,STR,STRING,STRTOUUID,STUFF,SUBSTRING,TRIM,'+\n            'UCASE,UPPER,UUIDTOSTR';\nend;\n\n{**\n  Gets a comma-separated list of system functions.  These are the\n  X/Open CLI system function names used in the JDBC function escape\n  clause.\n  @return the list\n}\nfunction TZASADatabaseInfo.GetSystemFunctions: string;\nbegin\n  Result := 'CONNECTION_PROPERTY,DATALENGTH,DB_ID,DB_NAME,DB_PROPERTY,'+\n            'EVENT_CONDITION,EVENT_CONDITION_NAME,EVENT_PARAMETER,'+\n            'NEXT_CONNECTION,NEXT_DATABASE,PROPERTY,PROPERTY_DESCRIPTION,'+\n            'PROPERTY_NAME,PROPERTY_NUMBER,Col_length,Col_name,Datalength,'+\n            'Index_col,Object_id,Object_name,Suser_id,Suser_name,Tsequal,'+\n            'User_id,User_name,ARGN,COALESCE,ESTIMATE,ESTIMATE_SOURCE,'+\n            'EXPERIENCE_ESTIMATE,EXPLANATION,GET_IDENTITY,GRAPHICAL_PLAN,'+\n            'GRAPHICAL_ULPLAN,GREATER,IDENTITY,IFNULL,INDEX_ESTIMATE,ISNULL,'+\n            'LESSER,LONG_ULPLAN,NEWID,NULLIF,NUMBER,PLAN,REWRITE,SHORT_ULPLAN,'+\n            'SQLDIALECT,TRACEBACK,TRANSACTSQL,VAREXISTS,WATCOMSQL,TEXTPTR';\nend;\n\n{**\n  Gets a comma-separated list of time and date functions.\n  @return the list\n}\nfunction TZASADatabaseInfo.GetTimeDateFunctions: string;\nbegin\n  Result := 'DATE,DATEADD,DATEDIFF,DATEFORMAT,DATENAME,DATEPART,DATETIME,DAY,'+\n            'DAYNAME,DAYS,DOW,GETDATE,HOUR,HOURS,MINUTE,MINUTES,MONTH,'+\n            'MONTHNAME,MONTHS,NOW,QUARTER,SECOND,SECONDS,TODAY,WEEKS,YEARS,YMD';\nend;\n\n{**\n  Gets the string that can be used to escape wildcard characters.\n  This is the string that can be used to escape '_' or '%' in\n  the string pattern style catalog search parameters.\n\n  <P>The '_' character represents any single character.\n  <P>The '%' character represents any sequence of zero or\n  more characters.\n\n  @return the string used to escape wildcard characters\n}\nfunction TZASADatabaseInfo.GetSearchStringEscape: string;\nbegin\n  Result := '\\';\nend;\n\n{**\n  Gets all the \"extra\" characters that can be used in unquoted\n  identifier names (those beyond a-z, A-Z, 0-9 and _).\n  @return the string containing the extra characters\n}\nfunction TZASADatabaseInfo.GetExtraNameCharacters: string;\nbegin\n  Result := '@#$';\nend;\n\n//--------------------------------------------------------------------\n// Functions describing which features are supported.\n\n{**\n  Are expressions in \"ORDER BY\" lists supported?\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZASADatabaseInfo.SupportsExpressionsInOrderBy: Boolean;\nbegin\n  Result := True;\nend;\n\n{**\n  Can an \"ORDER BY\" clause use columns not in the SELECT statement?\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZASADatabaseInfo.SupportsOrderByUnrelated: Boolean;\nbegin\n  Result := True;\nend;\n\n{**\n  Is some form of \"GROUP BY\" clause supported?\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZASADatabaseInfo.SupportsGroupBy: Boolean;\nbegin\n  Result := True;\nend;\n\n{**\n  Can a \"GROUP BY\" clause use columns not in the SELECT?\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZASADatabaseInfo.SupportsGroupByUnrelated: Boolean;\nbegin\n  Result := True;\nend;\n\n{**\n  Can a \"GROUP BY\" clause add columns not in the SELECT\n  provided it specifies all the columns in the SELECT?\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZASADatabaseInfo.SupportsGroupByBeyondSelect: Boolean;\nbegin\n  Result := False;\nend;\n\n{**\n  Is the SQL Integrity Enhancement Facility supported?\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZASADatabaseInfo.SupportsIntegrityEnhancementFacility: Boolean;\nbegin\n  Result := True;\nend;\n\n{**\n  What's the database vendor's preferred term for \"schema\"?\n  @return the vendor term\n}\nfunction TZASADatabaseInfo.GetSchemaTerm: string;\nbegin\n  Result := 'OWNER';\nend;\n\n{**\n  What's the database vendor's preferred term for \"procedure\"?\n  @return the vendor term\n}\nfunction TZASADatabaseInfo.GetProcedureTerm: string;\nbegin\n  Result := 'PROCEDURE';\nend;\n\n{**\n  What's the database vendor's preferred term for \"catalog\"?\n  @return the vendor term\n}\nfunction TZASADatabaseInfo.GetCatalogTerm: string;\nbegin\n  Result := '';\nend;\n\n{**\n  What's the separator between catalog and table name?\n  @return the separator string\n}\nfunction TZASADatabaseInfo.GetCatalogSeparator: string;\nbegin\n  Result := '';\nend;\n\n{**\n  Can a schema name be used in a data manipulation statement?\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZASADatabaseInfo.SupportsSchemasInDataManipulation: Boolean;\nbegin\n  Result := True;\nend;\n\n{**\n  Can a schema name be used in a procedure call statement?\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZASADatabaseInfo.SupportsSchemasInProcedureCalls: Boolean;\nbegin\n  Result := True;\nend;\n\n{**\n  Can a schema name be used in a table definition statement?\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZASADatabaseInfo.SupportsSchemasInTableDefinitions: Boolean;\nbegin\n  Result := True;\nend;\n\n{**\n  Can a schema name be used in an index definition statement?\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZASADatabaseInfo.SupportsSchemasInIndexDefinitions: Boolean;\nbegin\n  Result := False;\nend;\n\n{**\n  Can a schema name be used in a privilege definition statement?\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZASADatabaseInfo.SupportsSchemasInPrivilegeDefinitions: Boolean;\nbegin\n  Result := False;\nend;\n\n{**\n  Can a catalog name be used in a data manipulation statement?\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZASADatabaseInfo.SupportsCatalogsInDataManipulation: Boolean;\nbegin\n  Result := False;\nend;\n\n{**\n  Can a catalog name be used in a procedure call statement?\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZASADatabaseInfo.SupportsCatalogsInProcedureCalls: Boolean;\nbegin\n  Result := False;\nend;\n\n{**\n  Can a catalog name be used in a table definition statement?\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZASADatabaseInfo.SupportsCatalogsInTableDefinitions: Boolean;\nbegin\n  Result := False;\nend;\n\n{**\n  Can a catalog name be used in an index definition statement?\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZASADatabaseInfo.SupportsCatalogsInIndexDefinitions: Boolean;\nbegin\n  Result := False;\nend;\n\n{**\n  Can a catalog name be used in a privilege definition statement?\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZASADatabaseInfo.SupportsCatalogsInPrivilegeDefinitions: Boolean;\nbegin\n  Result := False;\nend;\n\n{**\n  Is positioned DELETE supported?\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZASADatabaseInfo.SupportsPositionedDelete: Boolean;\nbegin\n  Result := True;\nend;\n\n{**\n  Is positioned UPDATE supported?\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZASADatabaseInfo.SupportsPositionedUpdate: Boolean;\nbegin\n  Result := True;\nend;\n\n{**\n  Is SELECT for UPDATE supported?\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZASADatabaseInfo.SupportsSelectForUpdate: Boolean;\nbegin\n  Result := True;\nend;\n\n{**\n  Are stored procedure calls using the stored procedure escape\n  syntax supported?\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZASADatabaseInfo.SupportsStoredProcedures: Boolean;\nbegin\n  Result := True;\nend;\n\n{**\n  Are subqueries in comparison expressions supported?\n  A JDBC Compliant<sup><font size=-2>TM</font></sup> driver always returns true.\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZASADatabaseInfo.SupportsSubqueriesInComparisons: Boolean;\nbegin\n  Result := True;\nend;\n\n{**\n  Are subqueries in 'exists' expressions supported?\n  A JDBC Compliant<sup><font size=-2>TM</font></sup> driver always returns true.\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZASADatabaseInfo.SupportsSubqueriesInExists: Boolean;\nbegin\n  Result := True;\nend;\n\n{**\n  Are subqueries in 'in' statements supported?\n  A JDBC Compliant<sup><font size=-2>TM</font></sup> driver always returns true.\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZASADatabaseInfo.SupportsSubqueriesInIns: Boolean;\nbegin\n  Result := True;\nend;\n\n{**\n  Are subqueries in quantified expressions supported?\n  A JDBC Compliant<sup><font size=-2>TM</font></sup> driver always returns true.\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZASADatabaseInfo.SupportsSubqueriesInQuantifieds: Boolean;\nbegin\n  Result := True;\nend;\n\n{**\n  Are correlated subqueries supported?\n  A JDBC Compliant<sup><font size=-2>TM</font></sup> driver always returns true.\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZASADatabaseInfo.SupportsCorrelatedSubqueries: Boolean;\nbegin\n  Result := True;\nend;\n\n{**\n  Is SQL UNION supported?\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZASADatabaseInfo.SupportsUnion: Boolean;\nbegin\n  Result := True;\nend;\n\n{**\n  Is SQL UNION ALL supported?\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZASADatabaseInfo.SupportsUnionAll: Boolean;\nbegin\n  Result := True;\nend;\n\n{**\n  Can cursors remain open across commits?\n  @return <code>true</code> if cursors always remain open;\n        <code>false</code> if they might not remain open\n}\nfunction TZASADatabaseInfo.SupportsOpenCursorsAcrossCommit: Boolean;\nbegin\n  Result := True;\nend;\n\n{**\n  Can cursors remain open across rollbacks?\n  @return <code>true</code> if cursors always remain open;\n        <code>false</code> if they might not remain open\n}\nfunction TZASADatabaseInfo.SupportsOpenCursorsAcrossRollback: Boolean;\nbegin\n  Result := True;\nend;\n\n{**\n  Can statements remain open across commits?\n  @return <code>true</code> if statements always remain open;\n        <code>false</code> if they might not remain open\n}\nfunction TZASADatabaseInfo.SupportsOpenStatementsAcrossCommit: Boolean;\nbegin\n  Result := True;\nend;\n\n{**\n  Can statements remain open across rollbacks?\n  @return <code>true</code> if statements always remain open;\n        <code>false</code> if they might not remain open\n}\nfunction TZASADatabaseInfo.SupportsOpenStatementsAcrossRollback: Boolean;\nbegin\n  Result := True;\nend;\n\n//----------------------------------------------------------------------\n// The following group of methods exposes various limitations\n// based on the target database with the current driver.\n// Unless otherwise specified, a result of zero means there is no\n// limit, or the limit is not known.\n\n{**\n  How many hex characters can you have in an inline binary literal?\n  @return max binary literal length in hex characters;\n       a result of zero means that there is no limit or the limit is not known\n}\nfunction TZASADatabaseInfo.GetMaxBinaryLiteralLength: Integer;\nbegin\n  Result := 0;\nend;\n\n{**\n  What's the max length for a character literal?\n  @return max literal length;\n       a result of zero means that there is no limit or the limit is not known\n}\nfunction TZASADatabaseInfo.GetMaxCharLiteralLength: Integer;\nbegin\n  Result := 32768;\nend;\n\n{**\n  What's the limit on column name length?\n  @return max column name length;\n       a result of zero means that there is no limit or the limit is not known\n}\nfunction TZASADatabaseInfo.GetMaxColumnNameLength: Integer;\nbegin\n  Result := 128;\nend;\n\n{**\n  What's the maximum number of columns in a \"GROUP BY\" clause?\n  @return max number of columns;\n       a result of zero means that there is no limit or the limit is not known\n}\nfunction TZASADatabaseInfo.GetMaxColumnsInGroupBy: Integer;\nbegin\n  Result := 0;\nend;\n\n{**\n  What's the maximum number of columns allowed in an index?\n  @return max number of columns;\n       a result of zero means that there is no limit or the limit is not known\n}\nfunction TZASADatabaseInfo.GetMaxColumnsInIndex: Integer;\nbegin\n  Result := 1000000;\nend;\n\n{**\n  What's the maximum number of columns in an \"ORDER BY\" clause?\n  @return max number of columns;\n       a result of zero means that there is no limit or the limit is not known\n}\nfunction TZASADatabaseInfo.GetMaxColumnsInOrderBy: Integer;\nbegin\n  Result := 1000000;\nend;\n\n{**\n  What's the maximum number of columns in a \"SELECT\" list?\n  @return max number of columns;\n       a result of zero means that there is no limit or the limit is not known\n}\nfunction TZASADatabaseInfo.GetMaxColumnsInSelect: Integer;\nbegin\n  Result := 1000000;\nend;\n\n{**\n  What's the maximum number of columns in a table?\n  @return max number of columns;\n       a result of zero means that there is no limit or the limit is not known\n}\nfunction TZASADatabaseInfo.GetMaxColumnsInTable: Integer;\nbegin\n  Result := 1000000;\nend;\n\n{**\n  How many active connections can we have at a time to this database?\n  @return max number of active connections;\n       a result of zero means that there is no limit or the limit is not known\n}\nfunction TZASADatabaseInfo.GetMaxConnections: Integer;\nbegin\n  Result := 0;\nend;\n\n{**\n  What's the maximum cursor name length?\n  @return max cursor name length in bytes;\n       a result of zero means that there is no limit or the limit is not known\n}\nfunction TZASADatabaseInfo.GetMaxCursorNameLength: Integer;\nbegin\n  Result := 128;\nend;\n\n{**\n  Retrieves the maximum number of bytes for an index, including all\n  of the parts of the index.\n  @return max index length in bytes, which includes the composite of all\n   the constituent parts of the index;\n   a result of zero means that there is no limit or the limit is not known\n}\nfunction TZASADatabaseInfo.GetMaxIndexLength: Integer;\nbegin\n  Result := 0;\nend;\n\n{**\n  What's the maximum length allowed for a schema name?\n  @return max name length in bytes;\n       a result of zero means that there is no limit or the limit is not known\n}\nfunction TZASADatabaseInfo.GetMaxSchemaNameLength: Integer;\nbegin\n  Result := 128;\nend;\n\n{**\n  What's the maximum length of a procedure name?\n  @return max name length in bytes;\n       a result of zero means that there is no limit or the limit is not known\n}\nfunction TZASADatabaseInfo.GetMaxProcedureNameLength: Integer;\nbegin\n  Result := 128;\nend;\n\n{**\n  What's the maximum length of a catalog name?\n  @return max name length in bytes;\n       a result of zero means that there is no limit or the limit is not known\n}\nfunction TZASADatabaseInfo.GetMaxCatalogNameLength: Integer;\nbegin\n  Result := 0;\nend;\n\n{**\n  What's the maximum length of a single row?\n  @return max row size in bytes;\n       a result of zero means that there is no limit or the limit is not known\n}\nfunction TZASADatabaseInfo.GetMaxRowSize: Integer;\nbegin\n  Result := 0;\nend;\n\n{**\n  Did getMaxRowSize() include LONGVARCHAR and LONGVARBINARY\n  blobs?\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZASADatabaseInfo.DoesMaxRowSizeIncludeBlobs: Boolean;\nbegin\n  Result := False;\nend;\n\n{**\n  What's the maximum length of an SQL statement?\n  @return max length in bytes;\n       a result of zero means that there is no limit or the limit is not known\n}\nfunction TZASADatabaseInfo.GetMaxStatementLength: Integer;\nbegin\n  Result := 0;\nend;\n\n{**\n  How many active statements can we have open at one time to this\n  database?\n  @return the maximum number of statements that can be open at one time;\n       a result of zero means that there is no limit or the limit is not known\n}\nfunction TZASADatabaseInfo.GetMaxStatements: Integer;\nbegin\n  Result := 0;\nend;\n\n{**\n  What's the maximum length of a table name?\n  @return max name length in bytes;\n       a result of zero means that there is no limit or the limit is not known\n}\nfunction TZASADatabaseInfo.GetMaxTableNameLength: Integer;\nbegin\n  Result := 128;\nend;\n\n{**\n  What's the maximum number of tables in a SELECT statement?\n  @return the maximum number of tables allowed in a SELECT statement;\n       a result of zero means that there is no limit or the limit is not known\n}\nfunction TZASADatabaseInfo.GetMaxTablesInSelect: Integer;\nbegin\n  Result := 0;\nend;\n\n{**\n  What's the maximum length of a user name?\n  @return max user name length  in bytes;\n       a result of zero means that there is no limit or the limit is not known\n}\nfunction TZASADatabaseInfo.GetMaxUserNameLength: Integer;\nbegin\n  Result := 30;\nend;\n\n//----------------------------------------------------------------------\n\n{**\n  What's the database's default transaction isolation level?  The\n  values are defined in <code>java.sql.Connection</code>.\n  @return the default isolation level\n  @see Connection\n}\nfunction TZASADatabaseInfo.GetDefaultTransactionIsolation:\n  TZTransactIsolationLevel;\nbegin\n  Result := tiReadUncommitted;\nend;\n\n{**\n  Are transactions supported? If not, invoking the method\n  <code>commit</code> is a noop and the isolation level is TRANSACTION_NONE.\n  @return <code>true</code> if transactions are supported; <code>false</code> otherwise\n}\nfunction TZASADatabaseInfo.SupportsTransactions: Boolean;\nbegin\n  Result := True;\nend;\n\n{**\n  Does this database support the given transaction isolation level?\n  @param level the values are defined in <code>java.sql.Connection</code>\n  @return <code>true</code> if so; <code>false</code> otherwise\n  @see Connection\n}\nfunction TZASADatabaseInfo.SupportsTransactionIsolationLevel(\n  Level: TZTransactIsolationLevel): Boolean;\nbegin\n  Result := True;\nend;\n\n{**\n  Are both data definition and data manipulation statements\n  within a transaction supported?\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZASADatabaseInfo.\n  SupportsDataDefinitionAndDataManipulationTransactions: Boolean;\nbegin\n  Result := True;\nend;\n\n{**\n  Are only data manipulation statements within a transaction\n  supported?\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZASADatabaseInfo.\n  SupportsDataManipulationTransactionsOnly: Boolean;\nbegin\n  Result := False;\nend;\n\n{**\n  Does a data definition statement within a transaction force the\n  transaction to commit?\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZASADatabaseInfo.DataDefinitionCausesTransactionCommit: Boolean;\nbegin\n  Result := True;\nend;\n\n{**\n  Is a data definition statement within a transaction ignored?\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZASADatabaseInfo.DataDefinitionIgnoredInTransactions: Boolean;\nbegin\n  Result := False;\nend;\n\n{**\n  Does the database support the given result set type?\n  @param type defined in <code>java.sql.ResultSet</code>\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZASADatabaseInfo.SupportsResultSetType(\n  _Type: TZResultSetType): Boolean;\nbegin\n  Result := True;\nend;\n\n{**\n  Does the database support the concurrency type in combination\n  with the given result set type?\n\n  @param type defined in <code>java.sql.ResultSet</code>\n  @param concurrency type defined in <code>java.sql.ResultSet</code>\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZASADatabaseInfo.SupportsResultSetConcurrency(\n  _Type: TZResultSetType; Concurrency: TZResultSetConcurrency): Boolean;\nbegin\n  Result := True;\nend;\n\n{ TZASADatabaseMetadata }\n\n{**\n  Constructs this object and assignes the main properties.\n  @param Connection a database connection object.\n  @param Url a database connection url string.\n  @param Info an extra connection properties.\n}\nconstructor TZASADatabaseMetadata.Create(Connection: TZAbstractConnection;\n  const Url: TZURL);\nbegin\n  inherited Create(Connection, Url);\n  FASAConnection := Connection as TZASAConnection;\nend;\n\n{**\n  Composes a object name, AnsiQuotedStr or NullText\n  @param S the object string\n  @param NullText the \"NULL\"-Text default: 'null'\n  @param QuoteChar the QuoteChar default: '\n  @return 'null' if S is '' or S if s is already Quoted or AnsiQuotedStr(S, #39)\n}\nfunction TZASADatabaseMetadata.ComposeObjectString(const S: String;\n  Const NullText: String = 'null'; QuoteChar: Char = #39): String;\nbegin\n  if S = '' then\n    Result := NullText\n  else\n    if IC.IsQuoted(s) then\n      Result := S\n    else\n      Result := AnsiQuotedStr(S, QuoteChar);\nend;\n\n{**\n  Constructs a database information object and returns the interface to it. Used\n  internally by the constructor.\n  @return the database information object interface\n}\nfunction TZASADatabaseMetadata.CreateDatabaseInfo: IZDatabaseInfo;\nbegin\n  Result := TZASADatabaseInfo.Create(Self);\nend;\n\n{**\n  Gets a description of the stored procedures available in a\n  catalog.\n\n  <P>Only procedure descriptions matching the schema and\n  procedure name criteria are returned.  They are ordered by\n  PROCEDURE_SCHEM, and PROCEDURE_NAME.\n\n  <P>Each procedure description has the the following columns:\n   <OL>\n \t<LI><B>PROCEDURE_CAT</B> String => procedure catalog (may be null)\n \t<LI><B>PROCEDURE_SCHEM</B> String => procedure schema (may be null)\n \t<LI><B>PROCEDURE_NAME</B> String => procedure name\n   <LI> reserved for future use\n   <LI> reserved for future use\n   <LI> reserved for future use\n \t<LI><B>REMARKS</B> String => explanatory comment on the procedure\n \t<LI><B>PROCEDURE_TYPE</B> short => kind of procedure:\n       <UL>\n       <LI> procedureResultUnknown - May return a result\n       <LI> procedureNoResult - Does not return a result\n       <LI> procedureReturnsResult - Returns a result\n       </UL>\n   </OL>\n\n  @param catalog a catalog name; \"\" retrieves those without a\n  catalog; null means drop catalog name from the selection criteria\n  @param schemaPattern a schema name pattern; \"\" retrieves those\n  without a schema\n  @param procedureNamePattern a procedure name pattern\n  @return <code>ResultSet</code> - each row is a procedure description\n  @see #getSearchStringEscape\n}\nfunction TZASADatabaseMetadata.UncachedGetProcedures(const Catalog: string;\n  const SchemaPattern: string; const ProcedureNamePattern: string): IZResultSet;\nbegin\n    Result:=inherited UncachedGetProcedures(Catalog, SchemaPattern, ProcedureNamePattern);\n\n    with GetStatement.ExecuteQuery(\n      Format('exec sp_jdbc_stored_procedures %s, %s, %s',\n      [ComposeObjectString(Catalog), ComposeObjectString(SchemaPattern), ComposeObjectString(ProcedureNamePattern)])) do\n    begin\n      while Next do\n      begin\n        Result.MoveToInsertRow;\n        Result.UpdateStringByName('PROCEDURE_CAT',\n          '');\n        Result.UpdateStringByName('PROCEDURE_SCHEM',\n          GetStringByName('PROCEDURE_SCHEM'));\n        Result.UpdateStringByName('PROCEDURE_NAME',\n          GetStringByName('PROCEDURE_NAME'));\n        Result.UpdateStringByName('REMARKS',\n          GetStringByName('REMARKS'));\n        Result.UpdateShortByName('PROCEDURE_TYPE',\n          GetShortByName('PROCEDURE_TYPE'));\n        Result.InsertRow;\n      end;\n      Close;\n    end;\nend;\n\n{**\n  Gets a description of a catalog's stored procedure parameters\n  and result columns.\n\n  <P>Only descriptions matching the schema, procedure and\n  parameter name criteria are returned.  They are ordered by\n  PROCEDURE_SCHEM and PROCEDURE_NAME. Within this, the return value,\n  if any, is first. Next are the parameter descriptions in call\n  order. The column descriptions follow in column number order.\n\n  <P>Each row in the <code>ResultSet</code> is a parameter description or\n  column description with the following fields:\n   <OL>\n \t<LI><B>PROCEDURE_CAT</B> String => procedure catalog (may be null)\n \t<LI><B>PROCEDURE_SCHEM</B> String => procedure schema (may be null)\n \t<LI><B>PROCEDURE_NAME</B> String => procedure name\n \t<LI><B>COLUMN_NAME</B> String => column/parameter name\n \t<LI><B>COLUMN_TYPE</B> Short => kind of column/parameter:\n       <UL>\n       <LI> procedureColumnUnknown - nobody knows\n       <LI> procedureColumnIn - IN parameter\n       <LI> procedureColumnInOut - INOUT parameter\n       <LI> procedureColumnOut - OUT parameter\n       <LI> procedureColumnReturn - procedure return value\n       <LI> procedureColumnResult - result column in <code>ResultSet</code>\n       </UL>\n   <LI><B>DATA_TYPE</B> short => SQL type from java.sql.Types\n \t<LI><B>TYPE_NAME</B> String => SQL type name, for a UDT type the\n   type name is fully qualified\n \t<LI><B>PRECISION</B> int => precision\n \t<LI><B>LENGTH</B> int => length in bytes of data\n \t<LI><B>SCALE</B> short => scale\n \t<LI><B>RADIX</B> short => radix\n \t<LI><B>NULLABLE</B> short => can it contain NULL?\n       <UL>\n       <LI> procedureNoNulls - does not allow NULL values\n       <LI> procedureNullable - allows NULL values\n       <LI> procedureNullableUnknown - nullability unknown\n       </UL>\n \t<LI><B>REMARKS</B> String => comment describing parameter/column\n   </OL>\n\n  <P><B>Note:</B> Some databases may not return the column\n  descriptions for a procedure. Additional columns beyond\n  REMARKS can be defined by the database.\n\n  @param catalog a catalog name; \"\" retrieves those without a\n  catalog; null means drop catalog name from the selection criteria\n  @param schemaPattern a schema name pattern; \"\" retrieves those\n  without a schema\n  @param procedureNamePattern a procedure name pattern\n  @param columnNamePattern a column name pattern\n  @return <code>ResultSet</code> - each row describes a stored procedure parameter or\n       column\n  @see #getSearchStringEscape\n}\nfunction TZASADatabaseMetadata.UncachedGetProcedureColumns(const Catalog: string;\n  const SchemaPattern: string; const ProcedureNamePattern: string;\n  const ColumnNamePattern: string): IZResultSet;\nbegin\n    Result:=inherited UncachedGetProcedureColumns(Catalog, SchemaPattern, ProcedureNamePattern, ColumnNamePattern);\n\n    with GetStatement.ExecuteQuery(\n      Format('exec sp_jdbc_getprocedurecolumns %s, %s, %s, %s',\n      [ComposeObjectString(Catalog), ComposeObjectString(SchemaPattern), ComposeObjectString(ProcedureNamePattern),\n       ComposeObjectString(ColumnNamePattern)])) do\n    begin\n      while Next do\n      begin\n        Result.MoveToInsertRow;\n        Result.UpdateStringByName('PROCEDURE_CAT',\n          '');\n        Result.UpdateStringByName('PROCEDURE_SCHEM',\n          GetStringByName('PROCEDURE_SCHEM'));\n        Result.UpdateStringByName('PROCEDURE_NAME',\n          GetStringByName('PROCEDURE_NAME'));\n        Result.UpdateStringByName('COLUMN_NAME',\n          GetStringByName('COLUMN_NAME'));\n        case GetShortByName('COLUMN_TYPE') of\n          1: Result.UpdateShortByName('COLUMN_TYPE', Ord(pctIn));\n          2: Result.UpdateShortByName('COLUMN_TYPE', Ord(pctInOut));\n          3: Result.UpdateShortByName('COLUMN_TYPE', Ord(pctOut));\n          5: Result.UpdateShortByName('COLUMN_TYPE', Ord(pctReturn));\n        else\n          Result.UpdateShortByName('COLUMN_TYPE', Ord(pctUnknown));\n        end;\n        Result.UpdateShortByName('DATA_TYPE',\n          Ord(ConvertASAJDBCToSqlType(GetShortByName('DATA_TYPE'),\n            ConSettings.CPType)));\n        Result.UpdateStringByName('TYPE_NAME',\n          GetStringByName('TYPE_NAME'));\n        Result.UpdateIntByName('PRECISION',\n          GetIntByName('PRECISION'));\n        Result.UpdateIntByName('LENGTH',\n          GetIntByName('LENGTH'));\n        Result.UpdateShortByName('SCALE',\n          GetShortByName('SCALE'));\n        Result.UpdateShortByName('RADIX',\n          GetShortByName('RADIX'));\n        Result.UpdateShortByName('NULLABLE', \n          GetShortByName('NULLABLE'));\n        Result.UpdateStringByName('REMARKS',\n          GetStringByName('REMARKS'));\n        Result.InsertRow;\n      end;\n      Close;\n    end;\nend;\n\n{**\n  Gets a description of tables available in a catalog.\n\n  <P>Only table descriptions matching the catalog, schema, table\n  name and type criteria are returned.  They are ordered by\n  TABLE_TYPE, TABLE_SCHEM and TABLE_NAME.\n\n  <P>Each table description has the following columns:\n   <OL>\n \t<LI><B>TABLE_CAT</B> String => table catalog (may be null)\n \t<LI><B>TABLE_SCHEM</B> String => table schema (may be null)\n \t<LI><B>TABLE_NAME</B> String => table name\n \t<LI><B>TABLE_TYPE</B> String => table type.  Typical types are \"TABLE\",\n \t\t\t\"VIEW\",\t\"SYSTEM TABLE\", \"GLOBAL TEMPORARY\",\n \t\t\t\"LOCAL TEMPORARY\", \"ALIAS\", \"SYNONYM\".\n \t<LI><B>REMARKS</B> String => explanatory comment on the table\n   </OL>\n\n  <P><B>Note:</B> Some databases may not return information for\n  all tables.\n\n  @param catalog a catalog name; \"\" retrieves those without a\n  catalog; null means drop catalog name from the selection criteria\n  @param schemaPattern a schema name pattern; \"\" retrieves those\n  without a schema\n  @param tableNamePattern a table name pattern\n  @param types a list of table types to include; null returns all types\n  @return <code>ResultSet</code> - each row is a table description\n  @see #getSearchStringEscape\n}\nfunction TZASADatabaseMetadata.UncachedGetTables(const Catalog: string;\n  const SchemaPattern: string; const TableNamePattern: string;\n  const Types: TStringDynArray): IZResultSet;\nvar\n  I: Integer;\n  TableTypes: string;\nbegin\n    Result:=inherited UncachedGetTables(Catalog, SchemaPattern, TableNamePattern, Types);\n\n    TableTypes := '';\n    for I := 0 to Length(Types) - 1 do\n    begin\n      if TableTypes <> '' then\n        TableTypes := TableTypes + ',';\n      TableTypes := TableTypes + AnsiQuotedStr(Types[I], '''');\n    end;\n\n    with GetStatement.ExecuteQuery(\n      Format('exec sp_jdbc_tables %s, %s, %s, %s',\n        [ComposeObjectString(TableNamePattern), ComposeObjectString(SchemaPattern), ComposeObjectString(Catalog),\n         ComposeObjectString(TableTypes, 'null', '\"')])) do\n    begin\n      while Next do\n      begin\n        Result.MoveToInsertRow;\n        Result.UpdateStringByName('TABLE_CAT',\n          '');\n        Result.UpdateStringByName('TABLE_SCHEM',\n          GetStringByName('TABLE_SCHEM'));\n        Result.UpdateStringByName('TABLE_NAME',\n          GetStringByName('TABLE_NAME'));\n        Result.UpdateStringByName('TABLE_TYPE',\n          GetStringByName('TABLE_TYPE'));\n        Result.UpdateStringByName('REMARKS',\n          GetStringByName('REMARKS'));\n        Result.InsertRow;\n      end;\n      Close;\n    end;\nend;\n\n{**\n  Gets the schema names available in this database.  The results\n  are ordered by schema name.\n\n  <P>The schema column is:\n   <OL>\n \t<LI><B>TABLE_SCHEM</B> String => schema name\n   </OL>\n\n  @return <code>ResultSet</code> - each row has a single String column that is a\n  schema name\n}\nfunction TZASADatabaseMetadata.UncachedGetSchemas: IZResultSet;\nbegin\n    Result:=inherited UncachedGetSchemas;\n\n    with GetStatement.ExecuteQuery('select TABLE_SCHEM=name  from sysusers where suid >= -2 order by name'\n {'exec sp_jdbc_getschemas'}) do\n    begin\n      while Next do\n      begin\n        Result.MoveToInsertRow;\n        Result.UpdateStringByName('TABLE_SCHEM',\n          GetStringByName('TABLE_SCHEM'));\n        Result.InsertRow;\n      end;\n      Close;\n    end;\nend;\n\n{**\n  Gets the table types available in this database.  The results\n  are ordered by table type.\n\n  <P>The table type is:\n   <OL>\n \t<LI><B>TABLE_TYPE</B> String => table type.  Typical types are \"TABLE\",\n \t\t\t\"VIEW\",\t\"SYSTEM TABLE\", \"GLOBAL TEMPORARY\",\n \t\t\t\"LOCAL TEMPORARY\", \"ALIAS\", \"SYNONYM\".\n   </OL>\n\n  @return <code>ResultSet</code> - each row has a single String column that is a\n  table type\n}\nfunction TZASADatabaseMetadata.UncachedGetTableTypes: IZResultSet;\nconst\n  TablesTypes: array [0..4] of String = ( 'TABLE', 'BASE', 'SYSTEM', 'VIEW',\n    'GLOBAL TEMPORARY');\nvar\n  I: Integer;\nbegin\n    Result:=inherited UncachedGetTableTypes;\n\n    for I := 0 to 4 do\n    begin\n      Result.MoveToInsertRow;\n      Result.UpdateString(1, TablesTypes[I]);\n      Result.InsertRow;\n    end;\nend;\n\n{**\n  Gets a description of table columns available in\n  the specified catalog.\n\n  <P>Only column descriptions matching the catalog, schema, table\n  and column name criteria are returned.  They are ordered by\n  TABLE_SCHEM, TABLE_NAME and ORDINAL_POSITION.\n\n  <P>Each column description has the following columns:\n   <OL>\n \t<LI><B>TABLE_CAT</B> String => table catalog (may be null)\n \t<LI><B>TABLE_SCHEM</B> String => table schema (may be null)\n \t<LI><B>TABLE_NAME</B> String => table name\n \t<LI><B>COLUMN_NAME</B> String => column name\n \t<LI><B>DATA_TYPE</B> short => SQL type from java.sql.Types\n \t<LI><B>TYPE_NAME</B> String => Data source dependent type name,\n   for a UDT the type name is fully qualified\n \t<LI><B>COLUMN_SIZE</B> int => column size.  For char or date\n \t    types this is the maximum number of characters, for numeric or\n \t    decimal types this is precision.\n \t<LI><B>BUFFER_LENGTH</B> is not used.\n \t<LI><B>DECIMAL_DIGITS</B> int => the number of fractional digits\n \t<LI><B>NUM_PREC_RADIX</B> int => Radix (typically either 10 or 2)\n \t<LI><B>NULLABLE</B> int => is NULL allowed?\n       <UL>\n       <LI> columnNoNulls - might not allow NULL values\n       <LI> columnNullable - definitely allows NULL values\n       <LI> columnNullableUnknown - nullability unknown\n       </UL>\n \t<LI><B>REMARKS</B> String => comment describing column (may be null)\n \t<LI><B>COLUMN_DEF</B> String => default value (may be null)\n \t<LI><B>SQL_DATA_TYPE</B> int => unused\n \t<LI><B>SQL_DATETIME_SUB</B> int => unused\n \t<LI><B>CHAR_OCTET_LENGTH</B> int => for char types the\n        maximum number of bytes in the column\n \t<LI><B>ORDINAL_POSITION</B> int\t=> index of column in table\n       (starting at 1)\n \t<LI><B>IS_NULLABLE</B> String => \"NO\" means column definitely\n       does not allow NULL values; \"YES\" means the column might\n       allow NULL values.  An empty string means nobody knows.\n   </OL>\n\n  @param catalog a catalog name; \"\" retrieves those without a\n  catalog; null means drop catalog name from the selection criteria\n  @param schemaPattern a schema name pattern; \"\" retrieves those\n  without a schema\n  @param tableNamePattern a table name pattern\n  @param columnNamePattern a column name pattern\n  @return <code>ResultSet</code> - each row is a column description\n  @see #getSearchStringEscape\n}\nfunction TZASADatabaseMetadata.UncachedGetColumns(const Catalog: string;\n  const SchemaPattern: string; const TableNamePattern: string;\n  const ColumnNamePattern: string): IZResultSet;\nbegin\n    Result:=inherited UncachedGetColumns(Catalog, SchemaPattern, TableNamePattern, ColumnNamePattern);\n\n    with GetStatement.ExecuteQuery(\n      Format('exec sp_jdbc_columns %s, %s, %s, %s',\n      [ComposeObjectString(TableNamePattern), ComposeObjectString(SchemaPattern), ComposeObjectString(Catalog),\n       ComposeObjectString(ColumnNamePattern)])) do\n    begin\n      while Next do\n      begin\n        Result.MoveToInsertRow;\n        Result.UpdateStringByName('TABLE_CAT',\n          '');\n        Result.UpdateStringByName('TABLE_SCHEM',\n          GetStringByName('TABLE_SCHEM'));\n        Result.UpdateStringByName('TABLE_NAME',\n          GetStringByName('TABLE_NAME'));\n        Result.UpdateStringByName('COLUMN_NAME',\n          GetStringByName('COLUMN_NAME'));\n  //The value in the resultset will be used\n  //      Result.UpdateShortByName('DATA_TYPE',\n  //        Ord(ConvertASAJDBCToSqlType(GetShortByName('DATA_TYPE'))));\n        Result.UpdateStringByName('TYPE_NAME',\n          GetStringByName('TYPE_NAME'));\n        //Result.UpdateIntByName('COLUMN_SIZE',\n          //GetIntByName('COLUMN_SIZE'));\n        Result.UpdateIntByName('BUFFER_LENGTH',\n          GetIntByName('BUFFER_LENGTH'));\n        Result.UpdateIntByName('DECIMAL_DIGITS',\n          GetIntByName('DECIMAL_DIGITS'));\n        Result.UpdateIntByName('NUM_PREC_RADIX',\n          GetShortByName('NUM_PREC_RADIX'));\n        Result.UpdateStringByName('REMARKS',\n          GetStringByName('REMARKS'));\n        Result.UpdateStringByName('COLUMN_DEF',\n          GetStringByName('COLUMN_DEF'));\n        Result.UpdateShortByName('SQL_DATA_TYPE',\n          GetShortByName('SQL_DATA_TYPE'));\n        Result.UpdateShortByName('SQL_DATETIME_SUB',\n          GetShortByName('SQL_DATETIME_SUB'));\n        Result.UpdateIntByName('CHAR_OCTET_LENGTH',\n          GetIntByName('CHAR_OCTET_LENGTH'));\n        Result.UpdateIntByName('ORDINAL_POSITION',\n          GetIntByName('ORDINAL_POSITION'));\n\n        Result.UpdateBooleanByName('AUTO_INCREMENT',\n          CompareText( Trim( String(GetStringByName('COLUMN_DEF'))), 'autoincrement') = 0 );\n        Result.UpdateNullByName('CASE_SENSITIVE');\n        Result.UpdateBooleanByName('SEARCHABLE', False);\n        Result.UpdateStringByName('IS_NULLABLE', GetStringByName( 'IS_NULLABLE'));\n        Result.UpdateShortByName('NULLABLE', GetShortByName( 'NULLABLE'));\n        Result.UpdateBooleanByName('WRITABLE', True);\n        Result.UpdateBooleanByName('DEFINITELYWRITABLE', True);\n        Result.UpdateBooleanByName('READONLY', False);\n        Result.InsertRow;\n      end;\n      Close;\n    end;\n    Result.First;\n    with GetStatement.ExecuteQuery(\n        Format('select c.column_id,c.nulls '+\n          'from SYS.SYSCOLUMN as c join SYS.SYSTABLE as t on c.table_id=t.table_id '+\n          'where t.table_name like %s escape ''\\'' and '+\n          'USER_NAME(t.creator) like %s escape ''\\'' and '+\n          'c.column_name like %s escape ''\\'' and c.column_type=''C'' '+\n          'order by USER_NAME(t.creator) asc,t.table_name asc,c.column_id asc',\n          [ComposeObjectString(TableNamePattern, '''%'''),\n           ComposeObjectString(SchemaPattern, '''%'''),\n           ComposeObjectString(ColumnNamePattern, '''%''')])) do\n    begin\n      while Next do\n      begin\n        while Result.GetIntByName( 'ORDINAL_POSITION') <>\n                GetIntByName( 'column_id') do\n          Result.Next;\n        Result.UpdateBooleanByName( 'WRITABLE', False);\n        Result.UpdateBooleanByName( 'DEFINITELYWRITABLE', False);\n        Result.UpdateBooleanByName( 'READONLY', True);\n        if GetStringByName( 'nulls') = 'N' then\n        begin\n          Result.UpdateShortByName( 'NULLABLE', 0);\n          Result.UpdateStringByName( 'IS_NULLABLE', 'NO');\n        end;\n        Result.UpdateRow;\n      end;\n      Close;\n    end;\nend;\n\n{**\n  Gets a description of the access rights for a table's columns.\n\n  <P>Only privileges matching the column name criteria are\n  returned.  They are ordered by COLUMN_NAME and PRIVILEGE.\n\n  <P>Each privilige description has the following columns:\n   <OL>\n \t<LI><B>TABLE_CAT</B> String => table catalog (may be null)\n \t<LI><B>TABLE_SCHEM</B> String => table schema (may be null)\n \t<LI><B>TABLE_NAME</B> String => table name\n \t<LI><B>COLUMN_NAME</B> String => column name\n \t<LI><B>GRANTOR</B> => grantor of access (may be null)\n \t<LI><B>GRANTEE</B> String => grantee of access\n \t<LI><B>PRIVILEGE</B> String => name of access (SELECT,\n       INSERT, UPDATE, REFRENCES, ...)\n \t<LI><B>IS_GRANTABLE</B> String => \"YES\" if grantee is permitted\n       to grant to others; \"NO\" if not; null if unknown\n   </OL>\n\n  @param catalog a catalog name; \"\" retrieves those without a\n  catalog; null means drop catalog name from the selection criteria\n  @param schema a schema name; \"\" retrieves those without a schema\n  @param table a table name\n  @param columnNamePattern a column name pattern\n  @return <code>ResultSet</code> - each row is a column privilege description\n  @see #getSearchStringEscape\n}\nfunction TZASADatabaseMetadata.UncachedGetColumnPrivileges(const Catalog: string;\n  const Schema: string; const Table: string; const ColumnNamePattern: string): IZResultSet;\nbegin\n    Result:=inherited UncachedGetColumnPrivileges(Catalog, Schema, Table, ColumnNamePattern);\n\n    with GetStatement.ExecuteQuery(\n      Format('exec sp_jdbc_getcolumnprivileges %s, %s, %s, %s',\n      [ComposeObjectString(Catalog), ComposeObjectString(Schema), ComposeObjectString(Table), ComposeObjectString(ColumnNamePattern)])) do\n    begin\n      while Next do\n      begin\n        Result.MoveToInsertRow;\n        Result.UpdateStringByName('TABLE_CAT',\n          '');\n        Result.UpdateStringByName('TABLE_SCHEM',\n          GetStringByName('TABLE_SCHEM'));\n        Result.UpdateStringByName('TABLE_NAME',\n          GetStringByName('TABLE_NAME'));\n        Result.UpdateStringByName('COLUMN_NAME',\n          GetStringByName('COLUMN_NAME'));\n        Result.UpdateStringByName('GRANTOR',\n          GetStringByName('GRANTOR'));\n        Result.UpdateStringByName('GRANTEE',\n          GetStringByName('GRANTEE'));\n        Result.UpdateStringByName('PRIVILEGE',\n          GetStringByName('PRIVILEGE'));\n        Result.UpdateStringByName('IS_GRANTABLE',\n          GetStringByName('IS_GRANTABLE'));\n        Result.InsertRow;\n      end;\n      Close;\n    end;\nend;\n\n{**\n  Gets a description of the access rights for each table available\n  in a catalog. Note that a table privilege applies to one or\n  more columns in the table. It would be wrong to assume that\n  this priviledge applies to all columns (this may be true for\n  some systems but is not true for all.)\n\n  <P>Only privileges matching the schema and table name\n  criteria are returned.  They are ordered by TABLE_SCHEM,\n  TABLE_NAME, and PRIVILEGE.\n\n  <P>Each privilige description has the following columns:\n   <OL>\n \t<LI><B>TABLE_CAT</B> String => table catalog (may be null)\n \t<LI><B>TABLE_SCHEM</B> String => table schema (may be null)\n \t<LI><B>TABLE_NAME</B> String => table name\n \t<LI><B>GRANTOR</B> => grantor of access (may be null)\n \t<LI><B>GRANTEE</B> String => grantee of access\n \t<LI><B>PRIVILEGE</B> String => name of access (SELECT,\n       INSERT, UPDATE, REFRENCES, ...)\n \t<LI><B>IS_GRANTABLE</B> String => \"YES\" if grantee is permitted\n       to grant to others; \"NO\" if not; null if unknown\n   </OL>\n\n  @param catalog a catalog name; \"\" retrieves those without a\n  catalog; null means drop catalog name from the selection criteria\n  @param schemaPattern a schema name pattern; \"\" retrieves those\n  without a schema\n  @param tableNamePattern a table name pattern\n  @return <code>ResultSet</code> - each row is a table privilege description\n  @see #getSearchStringEscape\n}\nfunction TZASADatabaseMetadata.UncachedGetTablePrivileges(const Catalog: string;\n  const SchemaPattern: string; const TableNamePattern: string): IZResultSet;\nbegin\n    Result:=inherited UncachedGetTablePrivileges(Catalog, SchemaPattern, TableNamePattern);\n\n    with GetStatement.ExecuteQuery(\n      Format('exec sp_jdbc_gettableprivileges %s, %s, %s',\n      [ComposeObjectString(Catalog), ComposeObjectString(SchemaPattern), ComposeObjectString(TableNamePattern)])) do\n    begin\n      while Next do\n      begin\n        Result.MoveToInsertRow;\n        Result.UpdateStringByName('TABLE_CAT',\n          '');\n        Result.UpdateStringByName('TABLE_SCHEM',\n          GetStringByName('TABLE_SCHEM'));\n        Result.UpdateStringByName('TABLE_NAME',\n          GetStringByName('TABLE_NAME'));\n        Result.UpdateStringByName('GRANTOR',\n          GetStringByName('GRANTOR'));\n        Result.UpdateStringByName('GRANTEE',\n          GetStringByName('GRANTEE'));\n        Result.UpdateStringByName('PRIVILEGE',\n          GetStringByName('PRIVILEGE'));\n        Result.UpdateStringByName('IS_GRANTABLE',\n          GetStringByName('IS_GRANTABLE'));\n        Result.InsertRow;\n      end;\n      Close;\n    end;\nend;\n\n{**\n  Gets a description of a table's columns that are automatically\n  updated when any value in a row is updated.  They are\n  unordered.\n\n  <P>Each column description has the following columns:\n   <OL>\n \t<LI><B>SCOPE</B> short => is not used\n \t<LI><B>COLUMN_NAME</B> String => column name\n \t<LI><B>DATA_TYPE</B> short => SQL data type from java.sql.Types\n \t<LI><B>TYPE_NAME</B> String => Data source dependent type name\n \t<LI><B>COLUMN_SIZE</B> int => precision\n \t<LI><B>BUFFER_LENGTH</B> int => length of column value in bytes\n \t<LI><B>DECIMAL_DIGITS</B> short\t => scale\n \t<LI><B>PSEUDO_COLUMN</B> short => is this a pseudo column\n       like an Oracle ROWID\n       <UL>\n       <LI> versionColumnUnknown - may or may not be pseudo column\n       <LI> versionColumnNotPseudo - is NOT a pseudo column\n       <LI> versionColumnPseudo - is a pseudo column\n       </UL>\n   </OL>\n\n  @param catalog a catalog name; \"\" retrieves those without a\n  catalog; null means drop catalog name from the selection criteria\n  @param schema a schema name; \"\" retrieves those without a schema\n  @param table a table name\n  @return <code>ResultSet</code> - each row is a column description\n  @exception SQLException if a database access error occurs\n}\nfunction TZASADatabaseMetadata.UncachedGetVersionColumns(const Catalog: string;\n  const Schema: string; const Table: string): IZResultSet;\nbegin\n    Result:=inherited UncachedGetVersionColumns(Catalog, Schema, Table);\n\n    with GetStatement.ExecuteQuery(\n      Format('exec sp_jdbc_getversioncolumns %s, %s, %s',\n      [ComposeObjectString(Catalog), ComposeObjectString(Schema), ComposeObjectString(Table)])) do\n    begin\n      while Next do\n      begin\n        Result.MoveToInsertRow;\n        Result.UpdateShortByName('SCOPE',\n          GetShortByName('SCOPE'));\n        Result.UpdateStringByName('COLUMN_NAME',\n          GetStringByName('COLUMN_NAME'));\n        Result.UpdateShortByName('DATA_TYPE',\n          Ord(ConvertASAJDBCToSqlType(GetShortByName('DATA_TYPE'),\n            ConSettings.CPType)));\n        Result.UpdateStringByName('TYPE_NAME',\n          GetStringByName('TYPE_NAME'));\n        Result.UpdateIntByName('COLUMN_SIZE',\n          GetIntByName('COLUMN_SIZE'));\n        Result.UpdateIntByName('BUFFER_LENGTH',\n          GetIntByName('BUFFER_LENGTH'));\n        Result.UpdateIntByName('DECIMAL_DIGITS',\n          GetIntByName('DECIMAL_DIGITS'));\n        Result.UpdateShortByName('PSEUDO_COLUMN',\n          GetShortByName('PSEUDO_COLUMN'));\n        Result.InsertRow;\n      end;\n      Close;\n    end;\nend;\n\n{**\n  Gets a description of a table's primary key columns.  They\n  are ordered by COLUMN_NAME.\n\n  <P>Each primary key column description has the following columns:\n   <OL>\n \t<LI><B>TABLE_CAT</B> String => table catalog (may be null)\n \t<LI><B>TABLE_SCHEM</B> String => table schema (may be null)\n \t<LI><B>TABLE_NAME</B> String => table name\n \t<LI><B>COLUMN_NAME</B> String => column name\n \t<LI><B>KEY_SEQ</B> short => sequence number within primary key\n \t<LI><B>PK_NAME</B> String => primary key name (may be null)\n   </OL>\n\n  @param catalog a catalog name; \"\" retrieves those without a\n  catalog; null means drop catalog name from the selection criteria\n  @param schema a schema name; \"\" retrieves those\n  without a schema\n  @param table a table name\n  @return <code>ResultSet</code> - each row is a primary key column description\n  @exception SQLException if a database access error occurs\n}\nfunction TZASADatabaseMetadata.UncachedGetPrimaryKeys(const Catalog: string;\n  const Schema: string; const Table: string): IZResultSet;\nbegin\n    Result:=inherited UncachedGetPrimaryKeys(Catalog, Schema, Table);\n\n    with GetStatement.ExecuteQuery(\n      Format('exec sp_jdbc_primarykey %s, %s, %s',\n      [ComposeObjectString(Catalog), ComposeObjectString(Schema), ComposeObjectString(Table)])) do\n    begin\n      while Next do\n      begin\n        Result.MoveToInsertRow;\n        Result.UpdateStringByName('TABLE_CAT',\n          '');\n        Result.UpdateStringByName('TABLE_SCHEM',\n          GetStringByName('TABLE_SCHEM'));\n        Result.UpdateStringByName('TABLE_NAME',\n          GetStringByName('TABLE_NAME'));\n        Result.UpdateStringByName('COLUMN_NAME',\n          GetStringByName('COLUMN_NAME'));\n        Result.UpdateShortByName('KEY_SEQ',\n          GetShortByName('KEY_SEQ'));\n        Result.UpdateStringByName('PK_NAME',\n          GetStringByName('PK_NAME'));\n        Result.InsertRow;\n      end;\n      Close;\n    end;\nend;\n\n{**\n  Gets a description of the primary key columns that are\n  referenced by a table's foreign key columns (the primary keys\n  imported by a table).  They are ordered by PKTABLE_CAT,\n  PKTABLE_SCHEM, PKTABLE_NAME, and KEY_SEQ.\n\n  <P>Each primary key column description has the following columns:\n   <OL>\n \t<LI><B>PKTABLE_CAT</B> String => primary key table catalog\n       being imported (may be null)\n \t<LI><B>PKTABLE_SCHEM</B> String => primary key table schema\n       being imported (may be null)\n \t<LI><B>PKTABLE_NAME</B> String => primary key table name\n       being imported\n \t<LI><B>PKCOLUMN_NAME</B> String => primary key column name\n       being imported\n \t<LI><B>FKTABLE_CAT</B> String => foreign key table catalog (may be null)\n \t<LI><B>FKTABLE_SCHEM</B> String => foreign key table schema (may be null)\n \t<LI><B>FKTABLE_NAME</B> String => foreign key table name\n \t<LI><B>FKCOLUMN_NAME</B> String => foreign key column name\n \t<LI><B>KEY_SEQ</B> short => sequence number within foreign key\n \t<LI><B>UPDATE_RULE</B> short => What happens to\n        foreign key when primary is updated:\n       <UL>\n       <LI> importedNoAction - do not allow update of primary\n                key if it has been imported\n       <LI> importedKeyCascade - change imported key to agree\n                with primary key update\n       <LI> importedKeySetNull - change imported key to NULL if\n                its primary key has been updated\n       <LI> importedKeySetDefault - change imported key to default values\n                if its primary key has been updated\n       <LI> importedKeyRestrict - same as importedKeyNoAction\n                                  (for ODBC 2.x compatibility)\n       </UL>\n \t<LI><B>DELETE_RULE</B> short => What happens to\n       the foreign key when primary is deleted.\n       <UL>\n       <LI> importedKeyNoAction - do not allow delete of primary\n                key if it has been imported\n       <LI> importedKeyCascade - delete rows that import a deleted key\n       <LI> importedKeySetNull - change imported key to NULL if\n                its primary key has been deleted\n       <LI> importedKeyRestrict - same as importedKeyNoAction\n                                  (for ODBC 2.x compatibility)\n       <LI> importedKeySetDefault - change imported key to default if\n                its primary key has been deleted\n       </UL>\n \t<LI><B>FK_NAME</B> String => foreign key name (may be null)\n \t<LI><B>PK_NAME</B> String => primary key name (may be null)\n \t<LI><B>DEFERRABILITY</B> short => can the evaluation of foreign key\n       constraints be deferred until commit\n       <UL>\n       <LI> importedKeyInitiallyDeferred - see SQL92 for definition\n       <LI> importedKeyInitiallyImmediate - see SQL92 for definition\n       <LI> importedKeyNotDeferrable - see SQL92 for definition\n       </UL>\n   </OL>\n\n  @param catalog a catalog name; \"\" retrieves those without a\n  catalog; null means drop catalog name from the selection criteria\n  @param schema a schema name; \"\" retrieves those\n  without a schema\n  @param table a table name\n  @return <code>ResultSet</code> - each row is a primary key column description\n  @see #getExportedKeys\n}\nfunction TZASADatabaseMetadata.UncachedGetImportedKeys(const Catalog: string;\n  const Schema: string; const Table: string): IZResultSet;\nbegin\n    Result:=inherited UncachedGetImportedKeys(Catalog, Schema, Table);\n\n    with GetStatement.ExecuteQuery(\n      Format('exec sp_jdbc_importkey %s, %s, %s',\n      [ComposeObjectString(Catalog), ComposeObjectString(Schema), ComposeObjectString(Table)])) do\n    begin\n      while Next do\n      begin\n        Result.MoveToInsertRow;\n        Result.UpdateStringByName('PKTABLE_CAT',\n          '');\n        Result.UpdateStringByName('PKTABLE_SCHEM',\n          GetStringByName('PKTABLE_SCHEM'));\n        Result.UpdateStringByName('PKTABLE_NAME',\n          GetStringByName('PKTABLE_NAME'));\n        Result.UpdateStringByName('PKCOLUMN_NAME',\n          GetStringByName('PKCOLUMN_NAME'));\n        Result.UpdateStringByName('FKTABLE_CAT',\n          '');\n        Result.UpdateStringByName('FKTABLE_SCHEM',\n          GetStringByName('FKTABLE_SCHEM'));\n        Result.UpdateStringByName('FKTABLE_NAME',\n          GetStringByName('FKTABLE_NAME'));\n        Result.UpdateStringByName('FKCOLUMN_NAME',\n          GetStringByName('FKCOLUMN_NAME'));\n        Result.UpdateShortByName('KEY_SEQ',\n          GetShortByName('KEY_SEQ'));\n        Result.UpdateShortByName('UPDATE_RULE',\n          GetShortByName('UPDATE_RULE'));\n        Result.UpdateShortByName('DELETE_RULE',\n          GetShortByName('DELETE_RULE'));\n        Result.UpdateStringByName('FK_NAME',\n          GetStringByName('FK_NAME'));\n        Result.UpdateStringByName('PK_NAME',\n          GetStringByName('PK_NAME'));\n        Result.UpdateIntByName('DEFERRABILITY',\n          GetIntByName('DEFERRABILITY'));\n        Result.InsertRow;\n      end;\n      Close;\n    end;\nend;\n\n{**\n  Gets a description of the foreign key columns that reference a\n  table's primary key columns (the foreign keys exported by a\n  table).  They are ordered by FKTABLE_CAT, FKTABLE_SCHEM,\n  FKTABLE_NAME, and KEY_SEQ.\n\n  <P>Each foreign key column description has the following columns:\n   <OL>\n \t<LI><B>PKTABLE_CAT</B> String => primary key table catalog (may be null)\n \t<LI><B>PKTABLE_SCHEM</B> String => primary key table schema (may be null)\n \t<LI><B>PKTABLE_NAME</B> String => primary key table name\n \t<LI><B>PKCOLUMN_NAME</B> String => primary key column name\n \t<LI><B>FKTABLE_CAT</B> String => foreign key table catalog (may be null)\n       being exported (may be null)\n \t<LI><B>FKTABLE_SCHEM</B> String => foreign key table schema (may be null)\n       being exported (may be null)\n \t<LI><B>FKTABLE_NAME</B> String => foreign key table name\n       being exported\n \t<LI><B>FKCOLUMN_NAME</B> String => foreign key column name\n       being exported\n \t<LI><B>KEY_SEQ</B> short => sequence number within foreign key\n \t<LI><B>UPDATE_RULE</B> short => What happens to\n        foreign key when primary is updated:\n       <UL>\n       <LI> importedNoAction - do not allow update of primary\n                key if it has been imported\n       <LI> importedKeyCascade - change imported key to agree\n                with primary key update\n       <LI> importedKeySetNull - change imported key to NULL if\n                its primary key has been updated\n       <LI> importedKeySetDefault - change imported key to default values\n                if its primary key has been updated\n       <LI> importedKeyRestrict - same as importedKeyNoAction\n                                  (for ODBC 2.x compatibility)\n       </UL>\n \t<LI><B>DELETE_RULE</B> short => What happens to\n       the foreign key when primary is deleted.\n       <UL>\n       <LI> importedKeyNoAction - do not allow delete of primary\n                key if it has been imported\n       <LI> importedKeyCascade - delete rows that import a deleted key\n       <LI> importedKeySetNull - change imported key to NULL if\n                its primary key has been deleted\n       <LI> importedKeyRestrict - same as importedKeyNoAction\n                                  (for ODBC 2.x compatibility)\n       <LI> importedKeySetDefault - change imported key to default if\n                its primary key has been deleted\n       </UL>\n \t<LI><B>FK_NAME</B> String => foreign key name (may be null)\n \t<LI><B>PK_NAME</B> String => primary key name (may be null)\n \t<LI><B>DEFERRABILITY</B> short => can the evaluation of foreign key\n       constraints be deferred until commit\n       <UL>\n       <LI> importedKeyInitiallyDeferred - see SQL92 for definition\n       <LI> importedKeyInitiallyImmediate - see SQL92 for definition\n       <LI> importedKeyNotDeferrable - see SQL92 for definition\n       </UL>\n   </OL>\n\n  @param catalog a catalog name; \"\" retrieves those without a\n  catalog; null means drop catalog name from the selection criteria\n  @param schema a schema name; \"\" retrieves those\n  without a schema\n  @param table a table name\n  @return <code>ResultSet</code> - each row is a foreign key column description\n  @see #getImportedKeys\n}\nfunction TZASADatabaseMetadata.UncachedGetExportedKeys(const Catalog: string;\n  const Schema: string; const Table: string): IZResultSet;\nvar KeySeq: Integer;\nbegin\n  Result:=inherited UncachedGetExportedKeys(Catalog, Schema, Table);\n\n  KeySeq := 0;\n  with GetStatement.ExecuteQuery(\n    Format('exec sp_jdbc_exportkey %s, %s, %s',\n    [ComposeObjectString(Catalog), ComposeObjectString(Schema), ComposeObjectString(Table)])) do\n  begin\n    while Next do\n    begin\n      Inc(KeySeq);\n      Result.MoveToInsertRow;\n      Result.UpdateStringByName('PKTABLE_CAT',\n        '');\n      Result.UpdateStringByName('PKTABLE_SCHEM',\n        GetStringByName('PKTABLE_SCHEM'));\n      Result.UpdateStringByName('PKTABLE_NAME',\n        GetStringByName('PKTABLE_NAME'));\n      Result.UpdateStringByName('PKCOLUMN_NAME',\n        GetStringByName('PKCOLUMN_NAME'));\n      Result.UpdateStringByName('FKTABLE_CAT',\n        '');\n      Result.UpdateStringByName('FKTABLE_SCHEM',\n        GetStringByName('FKTABLE_SCHEM'));\n      Result.UpdateStringByName('FKTABLE_NAME',\n        GetStringByName('FKTABLE_NAME'));\n      Result.UpdateStringByName('FKCOLUMN_NAME',\n        GetStringByName('FKCOLUMN_NAME'));\n      Result.UpdateShortByName('KEY_SEQ', KeySeq);\n      Result.UpdateShortByName('UPDATE_RULE',\n        GetShortByName('UPDATE_RULE'));\n      Result.UpdateShortByName('DELETE_RULE',\n        GetShortByName('DELETE_RULE'));\n      Result.UpdateStringByName('FK_NAME',\n        GetStringByName('FK_NAME'));\n      Result.UpdateStringByName('PK_NAME',\n        GetStringByName('PK_NAME'));\n      Result.UpdateIntByName('DEFERRABILITY',\n        GetIntByName('DEFERRABILITY'));\n      Result.InsertRow;\n    end;\n    Close;\n  end;\nend;\n\n{**\n  Gets a description of the foreign key columns in the foreign key\n  table that reference the primary key columns of the primary key\n  table (describe how one table imports another's key.) This\n  should normally return a single foreign key/primary key pair\n  (most tables only import a foreign key from a table once.)  They\n  are ordered by FKTABLE_CAT, FKTABLE_SCHEM, FKTABLE_NAME, and\n  KEY_SEQ.\n\n  <P>Each foreign key column description has the following columns:\n   <OL>\n \t<LI><B>PKTABLE_CAT</B> String => primary key table catalog (may be null)\n \t<LI><B>PKTABLE_SCHEM</B> String => primary key table schema (may be null)\n \t<LI><B>PKTABLE_NAME</B> String => primary key table name\n \t<LI><B>PKCOLUMN_NAME</B> String => primary key column name\n \t<LI><B>FKTABLE_CAT</B> String => foreign key table catalog (may be null)\n       being exported (may be null)\n \t<LI><B>FKTABLE_SCHEM</B> String => foreign key table schema (may be null)\n       being exported (may be null)\n \t<LI><B>FKTABLE_NAME</B> String => foreign key table name\n       being exported\n \t<LI><B>FKCOLUMN_NAME</B> String => foreign key column name\n       being exported\n \t<LI><B>KEY_SEQ</B> short => sequence number within foreign key\n \t<LI><B>UPDATE_RULE</B> short => What happens to\n        foreign key when primary is updated:\n       <UL>\n       <LI> importedNoAction - do not allow update of primary\n                key if it has been imported\n       <LI> importedKeyCascade - change imported key to agree\n                with primary key update\n       <LI> importedKeySetNull - change imported key to NULL if\n                its primary key has been updated\n       <LI> importedKeySetDefault - change imported key to default values\n                if its primary key has been updated\n       <LI> importedKeyRestrict - same as importedKeyNoAction\n                                  (for ODBC 2.x compatibility)\n       </UL>\n \t<LI><B>DELETE_RULE</B> short => What happens to\n       the foreign key when primary is deleted.\n       <UL>\n       <LI> importedKeyNoAction - do not allow delete of primary\n                key if it has been imported\n       <LI> importedKeyCascade - delete rows that import a deleted key\n       <LI> importedKeySetNull - change imported key to NULL if\n                its primary key has been deleted\n       <LI> importedKeyRestrict - same as importedKeyNoAction\n                                  (for ODBC 2.x compatibility)\n       <LI> importedKeySetDefault - change imported key to default if\n                its primary key has been deleted\n       </UL>\n \t<LI><B>FK_NAME</B> String => foreign key name (may be null)\n \t<LI><B>PK_NAME</B> String => primary key name (may be null)\n \t<LI><B>DEFERRABILITY</B> short => can the evaluation of foreign key\n       constraints be deferred until commit\n       <UL>\n       <LI> importedKeyInitiallyDeferred - see SQL92 for definition\n       <LI> importedKeyInitiallyImmediate - see SQL92 for definition\n       <LI> importedKeyNotDeferrable - see SQL92 for definition\n       </UL>\n   </OL>\n\n  @param primaryCatalog a catalog name; \"\" retrieves those without a\n  catalog; null means drop catalog name from the selection criteria\n  @param primarySchema a schema name; \"\" retrieves those\n  without a schema\n  @param primaryTable the table name that exports the key\n  @param foreignCatalog a catalog name; \"\" retrieves those without a\n  catalog; null means drop catalog name from the selection criteria\n  @param foreignSchema a schema name; \"\" retrieves those\n  without a schema\n  @param foreignTable the table name that imports the key\n  @return <code>ResultSet</code> - each row is a foreign key column description\n  @see #getImportedKeys\n}\nfunction TZASADatabaseMetadata.UncachedGetCrossReference(const PrimaryCatalog: string;\n  const PrimarySchema: string; const PrimaryTable: string; const ForeignCatalog: string;\n  const ForeignSchema: string; const ForeignTable: string): IZResultSet;\nbegin\n    Result:=inherited UncachedGetCrossReference(PrimaryCatalog, PrimarySchema, PrimaryTable,\n                                                ForeignCatalog, ForeignSchema, ForeignTable);\n\n    with GetStatement.ExecuteQuery(\n      Format('exec sp_jdbc_getcrossreferences %s, %s, %s, %s, %s, %s',\n      [ComposeObjectString(PrimaryCatalog), ComposeObjectString(PrimarySchema), ComposeObjectString(PrimaryTable),\n       ComposeObjectString(ForeignCatalog), ComposeObjectString(ForeignSchema), ComposeObjectString(ForeignTable)])) do\n    begin\n      while Next do\n      begin\n        Result.MoveToInsertRow;\n        Result.UpdateStringByName('PKTABLE_CAT',\n          '');\n        Result.UpdateStringByName('PKTABLE_SCHEM',\n          GetStringByName('PKTABLE_SCHEM'));\n        Result.UpdateStringByName('PKTABLE_NAME',\n          GetStringByName('PKTABLE_NAME'));\n        Result.UpdateStringByName('PKCOLUMN_NAME',\n          GetStringByName('PKCOLUMN_NAME'));\n        Result.UpdateStringByName('FKTABLE_CAT',\n          '');\n        Result.UpdateStringByName('FKTABLE_SCHEM',\n          GetStringByName('FKTABLE_SCHEM'));\n        Result.UpdateStringByName('FKTABLE_NAME',\n          GetStringByName('FKTABLE_NAME'));\n        Result.UpdateStringByName('FKCOLUMN_NAME',\n          GetStringByName('FKCOLUMN_NAME'));\n        Result.UpdateShortByName('KEY_SEQ',\n          GetShortByName('KEY_SEQ'));\n        Result.UpdateShortByName('UPDATE_RULE',\n          GetShortByName('UPDATE_RULE'));\n        Result.UpdateShortByName('DELETE_RULE',\n          GetShortByName('DELETE_RULE'));\n        Result.UpdateStringByName('FK_NAME',\n          GetStringByName('FK_NAME'));\n        Result.UpdateStringByName('PK_NAME',\n          GetStringByName('PK_NAME'));\n        Result.UpdateIntByName('DEFERRABILITY',\n          GetIntByName('DEFERRABILITY'));\n        Result.InsertRow;\n      end;\n      Close;\n    end;\nend;\n\n{**\n  Gets a description of all the standard SQL types supported by\n  this database. They are ordered by DATA_TYPE and then by how\n  closely the data type maps to the corresponding JDBC SQL type.\n\n  <P>Each type description has the following columns:\n   <OL>\n \t<LI><B>TYPE_NAME</B> String => Type name\n \t<LI><B>DATA_TYPE</B> short => SQL data type from java.sql.Types\n \t<LI><B>PRECISION</B> int => maximum precision\n \t<LI><B>LITERAL_PREFIX</B> String => prefix used to quote a literal\n       (may be null)\n \t<LI><B>LITERAL_SUFFIX</B> String => suffix used to quote a literal\n        (may be null)\n \t<LI><B>CREATE_PARAMS</B> String => parameters used in creating\n       the type (may be null)\n \t<LI><B>NULLABLE</B> short => can you use NULL for this type?\n       <UL>\n       <LI> typeNoNulls - does not allow NULL values\n       <LI> typeNullable - allows NULL values\n       <LI> typeNullableUnknown - nullability unknown\n       </UL>\n \t<LI><B>CASE_SENSITIVE</B> boolean=> is it case sensitive?\n \t<LI><B>SEARCHABLE</B> short => can you use \"WHERE\" based on this type:\n       <UL>\n       <LI> typePredNone - No support\n       <LI> typePredChar - Only supported with WHERE .. LIKE\n       <LI> typePredBasic - Supported except for WHERE .. LIKE\n       <LI> typeSearchable - Supported for all WHERE ..\n       </UL>\n \t<LI><B>UNSIGNED_ATTRIBUTE</B> boolean => is it unsigned?\n \t<LI><B>FIXED_PREC_SCALE</B> boolean => can it be a money value?\n \t<LI><B>AUTO_INCREMENT</B> boolean => can it be used for an\n       auto-increment value?\n \t<LI><B>LOCAL_TYPE_NAME</B> String => localized version of type name\n       (may be null)\n \t<LI><B>MINIMUM_SCALE</B> short => minimum scale supported\n \t<LI><B>MAXIMUM_SCALE</B> short => maximum scale supported\n \t<LI><B>SQL_DATA_TYPE</B> int => unused\n \t<LI><B>SQL_DATETIME_SUB</B> int => unused\n \t<LI><B>NUM_PREC_RADIX</B> int => usually 2 or 10\n   </OL>\n\n  @return <code>ResultSet</code> - each row is an SQL type description\n}\nfunction TZASADatabaseMetadata.UncachedGetTypeInfo: IZResultSet;\nbegin\n    Result:=inherited UncachedGetTypeInfo;\n\n    with GetStatement.ExecuteQuery('exec sp_jdbc_datatype_info') do\n    begin\n      while Next do\n      begin\n        Result.MoveToInsertRow;\n        Result.UpdateStringByName('TYPE_NAME',\n          GetStringByName('TYPE_NAME'));\n        Result.UpdateShortByName('DATA_TYPE',\n          Ord(ConvertASAJDBCToSqlType(GetShortByName('DATA_TYPE'),\n            ConSettings.CPType)));\n        Result.UpdateIntByName('PRECISION',\n          GetIntByName('PRECISION'));\n        Result.UpdateStringByName('LITERAL_PREFIX',\n          GetStringByName('LITERAL_PREFIX'));\n        Result.UpdateStringByName('LITERAL_SUFFIX',\n          GetStringByName('LITERAL_SUFFIX'));\n        Result.UpdateStringByName('CREATE_PARAMS',\n          GetStringByName('CREATE_PARAMS'));\n        Result.UpdateShortByName('NULLABLE',\n          GetShortByName('NULLABLE'));\n        Result.UpdateBooleanByName('CASE_SENSITIVE',\n          GetShortByName('CASE_SENSITIVE') = 1);\n        Result.UpdateShortByName('SEARCHABLE',\n          GetShortByName('SEARCHABLE'));\n        Result.UpdateBooleanByName('UNSIGNED_ATTRIBUTE',\n          GetShortByName('UNSIGNED_ATTRIBUTE') = 1);\n        Result.UpdateBooleanByName('FIXED_PREC_SCALE',\n          GetShortByName('FIXED_PREC_SCALE') = 1);\n        Result.UpdateBooleanByName('AUTO_INCREMENT',\n          GetShortByName('AUTO_INCREMENT') = 1);\n        Result.UpdateStringByName('LOCAL_TYPE_NAME',\n          GetStringByName('LOCAL_TYPE_NAME'));\n        Result.UpdateShortByName('MINIMUM_SCALE',\n          GetShortByName('MINIMUM_SCALE'));\n        Result.UpdateShortByName('MAXIMUM_SCALE',\n          GetShortByName('MAXIMUM_SCALE'));\n        Result.UpdateShortByName('SQL_DATA_TYPE',\n          GetShortByName('SQL_DATA_TYPE'));\n        Result.UpdateShortByName('SQL_DATETIME_SUB',\n          GetShortByName('SQL_DATETIME_SUB'));\n        Result.UpdateShortByName('NUM_PREC_RADIX',\n          GetShortByName('NUM_PREC_RADIX'));\n        Result.InsertRow;\n      end;\n      Close;\n    end;\nend;\n\n{**\n  Gets a description of a table's indices and statistics. They are\n  ordered by NON_UNIQUE, TYPE, INDEX_NAME, and ORDINAL_POSITION.\n\n  <P>Each index column description has the following columns:\n   <OL>\n \t<LI><B>TABLE_CAT</B> String => table catalog (may be null)\n \t<LI><B>TABLE_SCHEM</B> String => table schema (may be null)\n \t<LI><B>TABLE_NAME</B> String => table name\n \t<LI><B>NON_UNIQUE</B> boolean => Can index values be non-unique?\n       false when TYPE is tableIndexStatistic\n \t<LI><B>INDEX_QUALIFIER</B> String => index catalog (may be null);\n       null when TYPE is tableIndexStatistic\n \t<LI><B>INDEX_NAME</B> String => index name; null when TYPE is\n       tableIndexStatistic\n \t<LI><B>TYPE</B> short => index type:\n       <UL>\n       <LI> tableIndexStatistic - this identifies table statistics that are\n            returned in conjuction with a table's index descriptions\n       <LI> tableIndexClustered - this is a clustered index\n       <LI> tableIndexHashed - this is a hashed index\n       <LI> tableIndexOther - this is some other style of index\n       </UL>\n \t<LI><B>ORDINAL_POSITION</B> short => column sequence number\n       within index; zero when TYPE is tableIndexStatistic\n \t<LI><B>COLUMN_NAME</B> String => column name; null when TYPE is\n       tableIndexStatistic\n \t<LI><B>ASC_OR_DESC</B> String => column sort sequence, \"A\" => ascending,\n       \"D\" => descending, may be null if sort sequence is not supported;\n       null when TYPE is tableIndexStatistic\n \t<LI><B>CARDINALITY</B> int => When TYPE is tableIndexStatistic, then\n       this is the number of rows in the table; otherwise, it is the\n       number of unique values in the index.\n \t<LI><B>PAGES</B> int => When TYPE is  tableIndexStatisic then\n       this is the number of pages used for the table, otherwise it\n       is the number of pages used for the current index.\n \t<LI><B>FILTER_CONDITION</B> String => Filter condition, if any.\n       (may be null)\n   </OL>\n\n  @param catalog a catalog name; \"\" retrieves those without a\n  catalog; null means drop catalog name from the selection criteria\n  @param schema a schema name; \"\" retrieves those without a schema\n  @param table a table name\n  @param unique when true, return only indices for unique values;\n      when false, return indices regardless of whether unique or not\n  @param approximate when true, result is allowed to reflect approximate\n      or out of data values; when false, results are requested to be\n      accurate\n  @return <code>ResultSet</code> - each row is an index column description\n}\nfunction TZASADatabaseMetadata.UncachedGetIndexInfo(const Catalog: string;\n  const Schema: string; const Table: string; Unique: Boolean;\n  Approximate: Boolean): IZResultSet;\nvar\n  Is_Unique, Accuracy: string;\nbegin\n    Result:=inherited UncachedGetIndexInfo(Catalog, Schema, Table, Unique, Approximate);\n\n    if Unique then\n      Is_Unique := '''1'''\n    else\n      Is_Unique := '''0''';\n\n    if Approximate then\n      Accuracy := '''1'''\n    else\n      Accuracy := '''0''';\n\n    with GetStatement.ExecuteQuery(\n      Format('exec sp_jdbc_getindexinfo %s, %s, %s, %s, %s',\n      [ComposeObjectString(Catalog), ComposeObjectString(Schema), ComposeObjectString(Table), Is_Unique, Accuracy])) do\n    begin\n      while Next do\n      begin\n        Result.MoveToInsertRow;\n        Result.UpdateStringByName('TABLE_CAT',\n          '');\n        Result.UpdateStringByName('TABLE_SCHEM',\n          GetStringByName('TABLE_SCHEM'));\n        Result.UpdateStringByName('TABLE_NAME',\n          GetStringByName('TABLE_NAME'));\n        Result.UpdateBooleanByName('NON_UNIQUE',\n          GetShortByName('NON_UNIQUE') = 1);\n        Result.UpdateStringByName('INDEX_QUALIFIER',\n          GetStringByName('INDEX_QUALIFIER'));\n        Result.UpdateStringByName('INDEX_NAME',\n          GetStringByName('INDEX_NAME'));\n        Result.UpdateShortByName('TYPE',\n          GetShortByName('TYPE'));\n        Result.UpdateShortByName('ORDINAL_POSITION',\n          GetShortByName('ORDINAL_POSITION'));\n        Result.UpdateStringByName('COLUMN_NAME',\n          GetStringByName('COLUMN_NAME'));\n        Result.UpdateStringByName('ASC_OR_DESC',\n          GetStringByName('ASC_OR_DESC'));\n        Result.UpdateIntByName('CARDINALITY',\n          GetIntByName('CARDINALITY'));\n        Result.UpdateIntByName('PAGES',\n          GetIntByName('PAGES'));\n        Result.UpdateStringByName('FILTER_CONDITION',\n          GetStringByName('FILTER_CONDITION'));\n        Result.InsertRow;\n      end;\n      Close;\n    end;\nend;\n\n{**\n  Gets a description of the user-defined types defined in a particular\n  schema.  Schema-specific UDTs may have type JAVA_OBJECT, STRUCT,\n  or DISTINCT.\n\n  <P>Only types matching the catalog, schema, type name and type\n  criteria are returned.  They are ordered by DATA_TYPE, TYPE_SCHEM\n  and TYPE_NAME.  The type name parameter may be a fully-qualified\n  name.  In this case, the catalog and schemaPattern parameters are\n  ignored.\n\n  <P>Each type description has the following columns:\n   <OL>\n \t<LI><B>TYPE_CAT</B> String => the type's catalog (may be null)\n \t<LI><B>TYPE_SCHEM</B> String => type's schema (may be null)\n \t<LI><B>TYPE_NAME</B> String => type name\n   <LI><B>CLASS_NAME</B> String => Java class name\n \t<LI><B>DATA_TYPE</B> String => type value defined in java.sql.Types.\n   One of JAVA_OBJECT, STRUCT, or DISTINCT\n \t<LI><B>REMARKS</B> String => explanatory comment on the type\n   </OL>\n\n  <P><B>Note:</B> If the driver does not support UDTs, an empty\n  result set is returned.\n\n  @param catalog a catalog name; \"\" retrieves those without a\n  catalog; null means drop catalog name from the selection criteria\n  @param schemaPattern a schema name pattern; \"\" retrieves those\n  without a schema\n  @param typeNamePattern a type name pattern; may be a fully-qualified name\n  @param types a list of user-named types to include (JAVA_OBJECT,\n  STRUCT, or DISTINCT); null returns all types\n  @return <code>ResultSet</code> - each row is a type description\n}\nfunction TZASADatabaseMetadata.UncachedGetUDTs(const Catalog: string;\n  const SchemaPattern: string; const TypeNamePattern: string;\n  const Types: TIntegerDynArray): IZResultSet;\nvar\n  I: Integer;\n  UDTypes: string;\nbegin\n    Result:=inherited UncachedGetUDTs(Catalog, SchemaPattern, TypeNamePattern, Types);\n\n    UDTypes := '';\n    for I := 0 to Length(Types) - 1 do\n    begin\n      if Length(UDTypes) > 0 then\n        UDTypes := UDTypes + ',';\n      UDTypes := UDTypes + AnsiQuotedStr(IntToStr(Types[I]), '''');\n    end;\n\n    with GetStatement.ExecuteQuery(\n      Format('exec sp_jdbc_getudts %s, %s, %s, %s',\n      [ComposeObjectString(Catalog), ComposeObjectString(SchemaPattern, '''%'''),\n       ComposeObjectString(TypeNamePattern, '''%'''),\n       ComposeObjectString(UDTypes, 'null', '\"')])) do\n    begin\n      while Next do\n      begin\n        Result.MoveToInsertRow;\n        Result.UpdateStringByName('TYPE_CAT',\n          GetStringByName('TYPE_CAT'));\n        Result.UpdateStringByName('TYPE_SCHEM',\n          GetStringByName('TYPE_SCHEM'));\n        Result.UpdateStringByName('TYPE_NAME',\n          GetStringByName('TYPE_NAME'));\n        Result.UpdateStringByName('JAVA_CLASS',\n          GetStringByName('JAVA_CLASS'));\n        Result.UpdateShortByName('DATA_TYPE',\n          Ord(ConvertASAJDBCToSqlType(GetShortByName('DATA_TYPE'),\n            ConSettings.CPType)));\n        Result.UpdateStringByName('REMARKS',\n          GetStringByName('REMARKS'));\n        Result.InsertRow;\n      end;\n      Close;\n    end;\nend;\n\nend.\n\n\n"
  },
  {
    "path": "lib/zeosdbo/src/dbc/ZDbcASAResultSet.pas",
    "content": "{*********************************************************}\n{                                                         }\n{                 Zeos Database Objects                   }\n{         Interbase Database Connectivity Classes         }\n{                                                         }\n{        Originally written by Sergey Merkuriev           }\n{                                                         }\n{*********************************************************}\n\n{@********************************************************}\n{    Copyright (c) 1999-2012 Zeos Development Group       }\n{                                                         }\n{ License Agreement:                                      }\n{                                                         }\n{ This library is distributed in the hope that it will be }\n{ useful, but WITHOUT ANY WARRANTY; without even the      }\n{ implied warranty of MERCHANTABILITY or FITNESS FOR      }\n{ A PARTICULAR PURPOSE.  See the GNU Lesser General       }\n{ Public License for more details.                        }\n{                                                         }\n{ The source code of the ZEOS Libraries and packages are  }\n{ distributed under the Library GNU General Public        }\n{ License (see the file COPYING / COPYING.ZEOS)           }\n{ with the following  modification:                       }\n{ As a special exception, the copyright holders of this   }\n{ library give you permission to link this library with   }\n{ independent modules to produce an executable,           }\n{ regardless of the license terms of these independent    }\n{ modules, and to copy and distribute the resulting       }\n{ executable under terms of your choice, provided that    }\n{ you also meet, for each linked independent module,      }\n{ the terms and conditions of the license of that module. }\n{ An independent module is a module which is not derived  }\n{ from or based on this library. If you modify this       }\n{ library, you may extend this exception to your version  }\n{ of the library, but you are not obligated to do so.     }\n{ If you do not wish to do so, delete this exception      }\n{ statement from your version.                            }\n{                                                         }\n{                                                         }\n{ The project web site is located on:                     }\n{   http://zeos.firmos.at  (FORUM)                        }\n{   http://sourceforge.net/p/zeoslib/tickets/ (BUGTRACKER)}\n{   svn://svn.code.sf.net/p/zeoslib/code-0/trunk (SVN)    }\n{                                                         }\n{   http://www.sourceforge.net/projects/zeoslib.          }\n{                                                         }\n{                                                         }\n{                                 Zeos Development Group. }\n{********************************************************@}\n\nunit ZDbcASAResultSet;\n\ninterface\n\n{$I ZDbc.inc}\n\nuses\n  {$IFDEF WITH_TOBJECTLIST_INLINE}System.Types, System.Contnrs{$ELSE}Types{$ENDIF},\n  Classes, {$IFDEF MSEgui}mclasses,{$ENDIF}\n  ZSysUtils, ZDbcIntfs, ZDbcResultSet, ZDbcASA, ZPlainASADriver, ZCompatibility,\n  ZDbcResultSetMetadata, ZDbcASAUtils, ZMessages, ZVariant;\n\ntype\n\n  {** Implements ASA ResultSet. }\n  TZASAResultSet = class(TZAbstractResultSet)\n  private\n    FCachedBlob: boolean;\n    FFetchStat: Integer;\n    FCursorName: AnsiString;\n    FStmtNum: SmallInt;\n    FSqlData: IZASASQLDA;\n    FParamsSqlData: IZASASQLDA;\n    FUpdateSqlData: IZASASQLDA;\n    FASAConnection: IZASAConnection;\n    FInsert: Boolean;\n    FUpdate: Boolean;\n    FDelete: Boolean;\n  protected\n    procedure Open; override;\n    procedure PrepareUpdateSQLData; virtual;\n    function GetFieldValue(ColumnIndex: Integer): Variant;\n    function InternalGetString(ColumnIndex: Integer): RawByteString; override;\n  public\n    constructor Create(Statement: IZStatement; SQL: string;\n      var StmtNum: SmallInt; CursorName: AnsiString;\n      SqlData: IZASASQLDA; ParamsSqlData: IZASASQLDA;\n      CachedBlob: boolean);\n\n    function GetCursorName: AnsiString; override;\n    procedure Close; override;\n\n    function IsNull(ColumnIndex: Integer): Boolean; override;\n    function GetBoolean(ColumnIndex: Integer): Boolean; override;\n    function GetByte(ColumnIndex: Integer): Byte; override;\n    function GetShort(ColumnIndex: Integer): SmallInt; override;\n    function GetInt(ColumnIndex: Integer): Integer; override;\n    function GetLong(ColumnIndex: Integer): Int64; override;\n    function GetFloat(ColumnIndex: Integer): Single; override;\n    function GetDouble(ColumnIndex: Integer): Double; override;\n    function GetBigDecimal(ColumnIndex: Integer): Extended; override;\n    function GetBytes(ColumnIndex: Integer): TByteDynArray; override;\n    function GetDate(ColumnIndex: Integer): TDateTime; override;\n    function GetTime(ColumnIndex: Integer): TDateTime; override;\n    function GetTimestamp(ColumnIndex: Integer): TDateTime; override;\n    function GetBlob(ColumnIndex: Integer): IZBlob; override;\n\n    function Last: Boolean; override;\n    function MoveAbsolute(Row: Integer): Boolean; override;\n    function MoveRelative(Rows: Integer): Boolean; override;\n    function Previous: Boolean; override;\n    function Next: Boolean; override;\n\n    function RowUpdated: Boolean; override;\n    function RowInserted: Boolean; override;\n    function RowDeleted: Boolean; override;\n\n    procedure UpdateNull(ColumnIndex: Integer); override;\n    procedure UpdateBoolean(ColumnIndex: Integer; Value: Boolean); override;\n    procedure UpdateByte(ColumnIndex: Integer; Value: ShortInt); override;\n    procedure UpdateShort(ColumnIndex: Integer; Value: SmallInt); override;\n    procedure UpdateInt(ColumnIndex: Integer; Value: Integer); override;\n    procedure UpdateLong(ColumnIndex: Integer; Value: Int64); override;\n    procedure UpdateFloat(ColumnIndex: Integer; Value: Single); override;\n    procedure UpdateDouble(ColumnIndex: Integer; Value: Double); override;\n    procedure UpdateBigDecimal(ColumnIndex: Integer; Value: Extended); override;\n    procedure UpdatePChar(ColumnIndex: Integer; Value: PChar); override;\n    procedure UpdateString(ColumnIndex: Integer; const Value: String); override;\n    procedure UpdateUnicodeString(ColumnIndex: Integer; const Value: WideString); override;\n    procedure UpdateBytes(ColumnIndex: Integer; const Value: TByteDynArray); override;\n    procedure UpdateDate(ColumnIndex: Integer; Value: TDateTime); override;\n    procedure UpdateTime(ColumnIndex: Integer; Value: TDateTime); override;\n    procedure UpdateTimestamp(ColumnIndex: Integer; Value: TDateTime); override;\n    procedure UpdateAsciiStream(ColumnIndex: Integer; Value: TStream); override;\n    procedure UpdateUnicodeStream(ColumnIndex: Integer; Value: TStream); override;\n    procedure UpdateBinaryStream(ColumnIndex: Integer; Value: TStream); override;\n    procedure UpdateValue(ColumnIndex: Integer; const Value: TZVariant); override;\n\n    procedure InsertRow; override;\n    procedure UpdateRow; override;\n    procedure DeleteRow; override;\n    procedure RefreshRow; override;\n    procedure CancelRowUpdates; override;\n    procedure MoveToInsertRow; override;\n    procedure MoveToCurrentRow; override;\n\n    property SQLData: IZASASQLDA read FSQLData;\n  end;\n\n  IZASABlob = interface(IZBlob)\n    ['{1E043426-5856-4953-88B8-F6FB276B7B61}']\n    procedure ReadBlob;\n  end;\n\n  {** Implements external blob wrapper object for PostgreSQL. }\n  TZASABlob = class(TZAbstractBlob, IZASABlob)\n  private\n    FBlobRead: Boolean;\n    FResultSet: TZASAResultSet;\n    FColID: Integer;\n  protected\n    procedure ReadBlob;\n  public\n    constructor Create( ResultSet: TZASAResultSet; ColID: Integer);\n    constructor CreateWithStream(Stream: TStream; Connection: IZConnection);\n    constructor CreateWithData(Data: Pointer; Size: Integer; Connection: IZConnection);\n\n    function IsEmpty: Boolean; override;\n    function Clone: IZBlob; override;\n    function GetStream: TStream; override;\n    function GetString: RawByteString; override;\n    function GetUnicodeString: WideString; override;\n    function GetBytes: TByteDynArray; override;\n    property BlobSize;\n    property BlobData;\n  end;\n\nimplementation\n\nuses\n{$IFNDEF FPC}\n  Variants,\n{$ENDIF}\n  SysUtils, Math, ZdbcLogging, ZPlainASAConstants, ZDbcUtils, ZEncoding;\n\n{ TZASAResultSet }\n\n{**\n  Constructs this object, assignes main properties and\n  opens the record set.\n  @param Statement a related SQL statement object.\n  @param handle a Interbase6 database connect handle.\n  @param the statement previously prepared\n  @param the sql out data previously allocated\n  @param the Interbase sql dialect\n}\nconstructor TZASAResultSet.Create(Statement: IZStatement; SQL: string;\n      var StmtNum: SmallInt; CursorName: AnsiString;\n      SqlData: IZASASQLDA; ParamsSqlData: IZASASQLDA;\n      CachedBlob: boolean);\nbegin\n  inherited Create( Statement, SQL, nil,Statement.GetConnection.GetConSettings);\n\n  FFetchStat := 0;\n  FSqlData := SqlData;\n  FCursorName := CursorName;\n  FCachedBlob := CachedBlob;\n  FASAConnection := Statement.GetConnection as IZASAConnection;\n  FDelete := False;\n  FInsert := False;\n  FUpdate := False;\n\n  FParamsSqlData := ParamsSqlData;\n  FStmtNum := StmtNum;\n  ResultSetType := rtScrollSensitive;\n  ResultSetConcurrency := rcUpdatable;\n\n  Open;\nend;\n\n{**\n   Return field value by it index\n   @param the index column 0 first, 1 second ...\n   @return the field value as variant type\n}\nfunction TZASAResultSet.GetFieldValue(ColumnIndex: Integer): Variant;\nbegin\n  CheckClosed;\n  if FInsert or ( FUpdate and FUpdateSQLData.IsAssigned( ColumnIndex - 1)) then\n    Result := FUpdateSqlData.GetValue( ColumnIndex - 1)\n  else\n    Result := FSqlData.GetValue( ColumnIndex - 1);\n  LastWasNull := IsNull( ColumnIndex);\nend;\n\n{**\n  Gets the value of the designated column in the current row\n  of this <code>ResultSet</code> object as\n  a <code>java.sql.BigDecimal</code> in the Java programming language.\n\n  @param columnIndex the first column is 1, the second is 2, ...\n  @param scale the number of digits to the right of the decimal point\n  @return the column value; if the value is SQL <code>NULL</code>, the\n    value returned is <code>null</code>\n}\nfunction TZASAResultSet.GetBigDecimal(ColumnIndex: Integer): Extended;\nbegin\n  CheckClosed;\n  CheckColumnConvertion(ColumnIndex, stBigDecimal);\n  if FInsert or ( FUpdate and FUpdateSQLData.IsAssigned( ColumnIndex - 1)) then\n    Result := FUpdateSqlData.GetBigDecimal( ColumnIndex - 1)\n  else\n    Result := FSqlData.GetBigDecimal( ColumnIndex - 1);\n  LastWasNull := IsNull( ColumnIndex);\nend;\n\n{**\n  Returns the value of the designated column in the current row\n  of this <code>ResultSet</code> object as a <code>Blob</code> object\n  in the Java programming language.\n\n  @param ColumnIndex the first column is 1, the second is 2, ...\n  @return a <code>Blob</code> object representing the SQL <code>BLOB</code> value in\n    the specified column\n}\nfunction TZASAResultSet.GetBlob(ColumnIndex: Integer): IZBlob;\nvar\n  Blob: IZASABlob;\n  TempStream: TStream;\nbegin\n  Result := nil;\n  CheckClosed;\n  CheckBlobColumn(ColumnIndex);\n\n  LastWasNull := IsNull(ColumnIndex);\n  if LastWasNull then\n     Exit;\n\n  Blob := TZASABlob.Create( Self, ColumnIndex - 1);\n  if FCachedBlob then\n    Blob.ReadBlob;\n  if ( GetMetadata.GetColumnType(ColumnIndex) in [stUnicodeStream, stAsciiStream] ) then\n  begin\n    case GetMetaData.GetColumnType(ColumnIndex) of\n      stAsciiStream:\n        Blob.SetString(GetValidatedAnsiString(Blob.GetString, ConSettings, True));\n      else\n      begin\n        TempStream := GetValidatedUnicodeStream(Blob.GetBuffer, Blob.Length, ConSettings, True);\n        Blob.SetStream(TempStream, True);\n        TempStream.Free;\n      end;\n    end;\n  end;\n  Result := Blob;\nend;\n\n{**\n  Gets the value of the designated column in the current row\n  of this <code>ResultSet</code> object as\n  a <code>boolean</code> in the Java programming language.\n\n  @param columnIndex the first column is 1, the second is 2, ...\n  @return the column value; if the value is SQL <code>NULL</code>, the\n    value returned is <code>false</code>\n}\nfunction TZASAResultSet.GetBoolean(ColumnIndex: Integer): Boolean;\nbegin\n  CheckClosed;\n  CheckColumnConvertion(ColumnIndex, stBoolean);\n  if FInsert or ( FUpdate and FUpdateSQLData.IsAssigned( ColumnIndex - 1)) then\n    Result := FUpdateSqlData.GetBoolean( ColumnIndex - 1)\n  else\n    Result := FSqlData.GetBoolean( ColumnIndex - 1);\n  LastWasNull := IsNull( ColumnIndex);\nend;\n\n{**\n  Gets the value of the designated column in the current row\n  of this <code>ResultSet</code> object as\n  a <code>byte</code> in the Java programming language.\n\n  @param columnIndex the first column is 1, the second is 2, ...\n  @return the column value; if the value is SQL <code>NULL</code>, the\n    value returned is <code>0</code>\n}\nfunction TZASAResultSet.GetByte(ColumnIndex: Integer): Byte;\nbegin\n  CheckClosed;\n  CheckColumnConvertion(ColumnIndex, stByte);\n  if FInsert or ( FUpdate and FUpdateSQLData.IsAssigned( ColumnIndex - 1)) then\n    Result := FUpdateSqlData.GetByte( ColumnIndex - 1)\n  else\n    Result := FSqlData.GetByte( ColumnIndex - 1);\n  LastWasNull := IsNull( ColumnIndex);\nend;\n\n{**\n  Gets the value of the designated column in the current row\n  of this <code>ResultSet</code> object as\n  a <code>byte</code> array in the Java programming language.\n  The bytes represent the raw values returned by the driver.\n\n  @param columnIndex the first column is 1, the second is 2, ...\n  @return the column value; if the value is SQL <code>NULL</code>, the\n    value returned is <code>null</code>\n}\nfunction TZASAResultSet.GetBytes(\n  ColumnIndex: Integer): TByteDynArray;\nbegin\n  CheckClosed;\n  CheckColumnConvertion(ColumnIndex, stBytes);\n  if FInsert or ( FUpdate and FUpdateSQLData.IsAssigned( ColumnIndex - 1)) then\n    Result := FUpdateSqlData.GetBytes( ColumnIndex - 1)\n  else\n    Result := FSqlData.GetBytes( ColumnIndex - 1);\n  LastWasNull := IsNull( ColumnIndex);\nend;\n\n{**\n  Gets the value of the designated column in the current row\n  of this <code>ResultSet</code> object as\n  a <code>java.sql.Date</code> object in the Java programming language.\n\n  @param columnIndex the first column is 1, the second is 2, ...\n  @return the column value; if the value is SQL <code>NULL</code>, the\n    value returned is <code>null</code>\n}\nfunction TZASAResultSet.GetDate(ColumnIndex: Integer): TDateTime;\nbegin\n  CheckClosed;\n  CheckColumnConvertion(ColumnIndex, stDate);\n  if FInsert or ( FUpdate and FUpdateSQLData.IsAssigned( ColumnIndex - 1)) then\n    Result := FUpdateSqlData.GetDate( ColumnIndex - 1)\n  else\n    Result := FSqlData.GetDate( ColumnIndex - 1);\n  LastWasNull := IsNull( ColumnIndex);\nend;\n\n{**\n  Gets the value of the designated column in the current row\n  of this <code>ResultSet</code> object as\n  a <code>double</code> in the Java programming language.\n\n  @param columnIndex the first column is 1, the second is 2, ...\n  @return the column value; if the value is SQL <code>NULL</code>, the\n    value returned is <code>0</code>\n}\nfunction TZASAResultSet.GetDouble(ColumnIndex: Integer): Double;\nbegin\n  CheckClosed;\n  CheckColumnConvertion(ColumnIndex, stDouble);\n  if FInsert or ( FUpdate and FUpdateSQLData.IsAssigned( ColumnIndex - 1)) then\n    Result := FUpdateSqlData.GetDouble( ColumnIndex - 1)\n  else\n    Result := FSqlData.GetDouble( ColumnIndex - 1);\n  LastWasNull := IsNull( ColumnIndex);\nend;\n\n{**\n  Gets the value of the designated column in the current row\n  of this <code>ResultSet</code> object as\n  a <code>float</code> in the Java programming language.\n\n  @param columnIndex the first column is 1, the second is 2, ...\n  @return the column value; if the value is SQL <code>NULL</code>, the\n    value returned is <code>0</code>\n}\nfunction TZASAResultSet.GetFloat(ColumnIndex: Integer): Single;\nbegin\n  CheckClosed;\n  CheckColumnConvertion(ColumnIndex, stFloat);\n  if FInsert or ( FUpdate and FUpdateSQLData.IsAssigned( ColumnIndex - 1)) then\n    Result := FUpdateSqlData.GetFloat( ColumnIndex - 1)\n  else\n    Result := FSqlData.GetFloat( ColumnIndex - 1);\n  LastWasNull := IsNull( ColumnIndex);\nend;\n\n{**\n  Gets the value of the designated column in the current row\n  of this <code>ResultSet</code> object as\n  an <code>int</code> in the Java programming language.\n\n  @param columnIndex the first column is 1, the second is 2, ...\n  @return the column value; if the value is SQL <code>NULL</code>, the\n    value returned is <code>0</code>\n}\nfunction TZASAResultSet.GetInt(ColumnIndex: Integer): Integer;\nbegin\n  CheckClosed;\n  CheckColumnConvertion(ColumnIndex, stInteger);\n  if FInsert or ( FUpdate and FUpdateSQLData.IsAssigned( ColumnIndex - 1)) then\n    Result := FUpdateSqlData.GetInt( ColumnIndex - 1)\n  else\n    Result := FSqlData.GetInt( ColumnIndex - 1);\n  LastWasNull := IsNull( ColumnIndex);\nend;\n\n{**\n  Gets the value of the designated column in the current row\n  of this <code>ResultSet</code> object as\n  a <code>long</code> in the Java programming language.\n\n  @param columnIndex the first column is 1, the second is 2, ...\n  @return the column value; if the value is SQL <code>NULL</code>, the\n    value returned is <code>0</code>\n}\nfunction TZASAResultSet.GetLong(ColumnIndex: Integer): Int64;\nbegin\n  CheckClosed;\n  CheckColumnConvertion(ColumnIndex, stLong);\n  if FInsert or ( FUpdate and FUpdateSQLData.IsAssigned( ColumnIndex - 1)) then\n    Result := FUpdateSqlData.GetLong( ColumnIndex - 1)\n  else\n    Result := FSqlData.GetLong( ColumnIndex - 1);\n  LastWasNull := IsNull( ColumnIndex);\nend;\n\n{**\n  Gets the value of the designated column in the current row\n  of this <code>ResultSet</code> object as\n  a <code>short</code> in the Java programming language.\n\n  @param columnIndex the first column is 1, the second is 2, ...\n  @return the column value; if the value is SQL <code>NULL</code>, the\n    value returned is <code>0</code>\n}\nfunction TZASAResultSet.GetShort(ColumnIndex: Integer): SmallInt;\nbegin\n  CheckClosed;\n  CheckColumnConvertion(ColumnIndex, stShort);\n  if FInsert or ( FUpdate and FUpdateSQLData.IsAssigned( ColumnIndex - 1)) then\n    Result := FUpdateSqlData.GetShort( ColumnIndex - 1)\n  else\n    Result := FSqlData.GetShort( ColumnIndex - 1);\n  LastWasNull := IsNull( ColumnIndex);\nend;\n\n{**\n  Gets the value of the designated column in the current row\n  of this <code>ResultSet</code> object as\n  a <code>String</code> in the Java programming language.\n\n  @param columnIndex the first column is 1, the second is 2, ...\n  @return the column value; if the value is SQL <code>NULL</code>, the\n    value returned is <code>null</code>\n}\nfunction TZASAResultSet.InternalGetString(ColumnIndex: Integer): RawByteString;\nbegin\n  CheckClosed;\n  CheckColumnConvertion( ColumnIndex, stString);\n  if FInsert or ( FUpdate and FUpdateSQLData.IsAssigned( ColumnIndex - 1)) then\n    Result := FUpdateSqlData.GetString( ColumnIndex - 1)\n  else\n    Result := FSqlData.GetString( ColumnIndex - 1);\n  LastWasNull := IsNull( ColumnIndex);\nend;\n\n{**\n  Gets the value of the designated column in the current row\n  of this <code>ResultSet</code> object as\n  a <code>java.sql.Time</code> object in the Java programming language.\n\n  @param columnIndex the first column is 1, the second is 2, ...\n  @return the column value; if the value is SQL <code>NULL</code>, the\n    value returned is <code>null</code>\n}\nfunction TZASAResultSet.GetTime(ColumnIndex: Integer): TDateTime;\nbegin\n  CheckClosed;\n  CheckColumnConvertion(ColumnIndex, stTime);\n  if FInsert or ( FUpdate and FUpdateSQLData.IsAssigned( ColumnIndex - 1)) then\n    Result := FUpdateSqlData.GetTime( ColumnIndex - 1)\n  else\n    Result := FSqlData.GetTime( ColumnIndex - 1);\n  LastWasNull := IsNull( ColumnIndex);\nend;\n\n{**\n  Gets the value of the designated column in the current row\n  of this <code>ResultSet</code> object as\n  a <code>java.sql.Timestamp</code> object in the Java programming language.\n\n  @param columnIndex the first column is 1, the second is 2, ...\n  @return the column value; if the value is SQL <code>NULL</code>, the\n  value returned is <code>null</code>\n  @exception SQLException if a database access error occurs\n}\nfunction TZASAResultSet.GetTimestamp(ColumnIndex: Integer): TDateTime;\nbegin\n  CheckClosed;\n  CheckColumnConvertion(ColumnIndex, stTimestamp);\n  if FInsert or ( FUpdate and FUpdateSQLData.IsAssigned( ColumnIndex - 1)) then\n    Result := FUpdateSqlData.GetTimestamp( ColumnIndex - 1)\n  else\n    Result := FSqlData.GetTimestamp( ColumnIndex - 1);\n  LastWasNull := IsNull( ColumnIndex);\nend;\n\n{**\n  Indicates if the value of the designated column in the current row\n  of this <code>ResultSet</code> object is Null.\n\n  @param columnIndex the first column is 1, the second is 2, ...\n  @return if the value is SQL <code>NULL</code>, the\n    value returned is <code>true</code>. <code>false</code> otherwise.\n}\nfunction TZASAResultSet.IsNull(ColumnIndex: Integer): Boolean;\nbegin\n  CheckClosed;\n  if FInsert or ( FUpdate and FUpdateSQLData.IsAssigned( ColumnIndex - 1)) then\n    Result := FUpdateSqlData.IsNull( ColumnIndex - 1)\n  else\n    Result := FSqlData.IsNull(ColumnIndex - 1);\nend;\n\nfunction TZASAResultSet.Last: Boolean;\nbegin\n  if LastRowNo <> MaxInt then\n    Result := MoveAbsolute( LastRowNo)\n  else\n    Result := MoveAbsolute( -1);\nend;\n\n{**\n  Moves the cursor to the given row number in\n  this <code>ResultSet</code> object.\n\n  <p>If the row number is positive, the cursor moves to\n  the given row number with respect to the\n  beginning of the result set.  The first row is row 1, the second\n  is row 2, and so on.\n\n  <p>If the given row number is negative, the cursor moves to\n  an absolute row position with respect to\n  the end of the result set.  For example, calling the method\n  <code>absolute(-1)</code> positions the\n  cursor on the last row; calling the method <code>absolute(-2)</code>\n  moves the cursor to the next-to-last row, and so on.\n\n  <p>An attempt to position the cursor beyond the first/last row in\n  the result set leaves the cursor before the first row or after\n  the last row.\n\n  <p><B>Note:</B> Calling <code>absolute(1)</code> is the same\n  as calling <code>first()</code>. Calling <code>absolute(-1)</code>\n  is the same as calling <code>last()</code>.\n\n  @return <code>true</code> if the cursor is on the result set;\n    <code>false</code> otherwise\n}\nfunction TZASAResultSet.MoveAbsolute(Row: Integer): Boolean;\nbegin\n  Result := False;\n  if (MaxRows > 0) and (Row >= MaxRows) then\n    Exit;\n\n  FASAConnection.GetPlainDriver.db_fetch( FASAConnection.GetDBHandle,\n    PAnsiChar(FCursorName), CUR_ABSOLUTE, Row, FSqlData.GetData, BlockSize, CUR_FORREGULAR);\n  ZDbcASAUtils.CheckASAError( FASAConnection.GetPlainDriver,\n    FASAConnection.GetDBHandle, lcOther);\n\n  if FASAConnection.GetDBHandle.sqlCode <> SQLE_NOTFOUND then\n  begin\n    RowNo := Row;\n    Result := True;\n    FFetchStat := 0;\n    FDelete := False;\n    FInsert := False;\n    FUpdate := False;\n  end\n  else\n  begin\n    FFetchStat := FASAConnection.GetDBHandle.sqlerrd[2];\n    if FFetchStat > 0 then\n      LastRowNo := Max( Row - FFetchStat, 0);\n  end;\nend;\n\nfunction TZASAResultSet.MoveRelative(Rows: Integer): Boolean;\nbegin\n  Result := False;\n  if (RowNo > LastRowNo) or ((MaxRows > 0) and (RowNo >= MaxRows)) then\n    Exit;\n  FASAConnection.GetPlainDriver.db_fetch( FASAConnection.GetDBHandle,\n    PAnsiChar( FCursorName), CUR_RELATIVE, Rows, FSqlData.GetData, BlockSize, CUR_FORREGULAR);\n    ZDbcASAUtils.CheckASAError( FASAConnection.GetPlainDriver,\n      FASAConnection.GetDBHandle, lcOther, '', SQLE_CURSOR_NOT_OPEN); //handle a known null resultset issue (cursor not open)\n  if FASAConnection.GetDBHandle.sqlCode = SQLE_CURSOR_NOT_OPEN then Exit;\n  if FASAConnection.GetDBHandle.sqlCode <> SQLE_NOTFOUND then\n  begin\n    if ( RowNo > 0) or ( RowNo + Rows < 0) then\n      RowNo := RowNo + Rows;\n    Result := True;\n    FFetchStat := 0;\n    FDelete := False;\n    FInsert := False;\n    FUpdate := False;\n  end\n  else\n  begin\n    FFetchStat := FASAConnection.GetDBHandle.sqlerrd[2];\n    if ( FFetchStat > 0) and ( RowNo > 0) then\n      LastRowNo := Max( RowNo + Rows - FFetchStat, 0);\n  end;\nend;\n\nfunction TZASAResultSet.Previous: Boolean;\nbegin\n  Result := MoveRelative( -1);\nend;\n\n{**\n  Moves the cursor down one row from its current position.\n  A <code>ResultSet</code> cursor is initially positioned\n  before the first row; the first call to the method\n  <code>next</code> makes the first row the current row; the\n  second call makes the second row the current row, and so on.\n\n  <P>If an input stream is open for the current row, a call\n  to the method <code>next</code> will\n  implicitly close it. A <code>ResultSet</code> object's\n  warning chain is cleared when a new row is read.\n\n  @return <code>true</code> if the new current row is valid;\n    <code>false</code> if there are no more rows\n}\nfunction TZASAResultSet.Next: Boolean;\nbegin\n  Result := MoveRelative( 1);\nend;\n\n{**\n  Opens this recordset.\n}\nprocedure TZASAResultSet.Open;\nvar\n  i: Integer;\n  FieldSqlType: TZSQLType;\n  ColumnInfo: TZColumnInfo;\nbegin\n  if FStmtNum = 0 then\n    raise EZSQLException.Create(SCanNotRetrieveResultSetData);\n\n  ColumnsInfo.Clear;\n  for i := 0 to FSqlData.GetFieldCount - 1 do\n  begin\n    ColumnInfo := TZColumnInfo.Create;\n    with ColumnInfo, FSqlData  do\n    begin\n      FieldSqlType := GetFieldSqlType(I);\n      ColumnName := GetFieldName(I);\n//      TableName := GetFieldRelationName(I);\n      ColumnLabel := ColumnName;\n      ColumnType := FieldSqlType;\n\n      case FieldSqlType of\n        stString,\n        stUnicodeString: Precision := GetFieldSize(FieldSqlType, ConSettings,\n          GetFieldLength(I)-4, ConSettings.ClientCodePage.CharWidth, @ColumnDisplaySize, True);\n      end;\n\n      ReadOnly := False;\n\n      if IsNullable(I) then\n        Nullable := ntNullable\n      else\n        Nullable := ntNoNulls;\n      Nullable := ntNullable;\n\n      Scale := GetFieldScale(I);\n      AutoIncrement := False;\n      //Signed := False;\n      CaseSensitive := False;\n    end;\n    ColumnsInfo.Add(ColumnInfo);\n  end;\n  LastRowNo := MaxInt;\n  inherited Open;\nend;\n\nprocedure TZASAResultSet.Close;\nbegin\n  FSqlData := nil;\n  FParamsSqlData := nil;\n  FUpdateSqlData := nil;\n  if FCursorName <> '' then\n  begin\n    FASAConnection.GetPlainDriver.db_close(FASAConnection.GetDBHandle, PAnsiChar(FCursorName));\n    FCursorName := '';\n  end;\n  inherited Close;\nend;\n\nfunction TZASAResultSet.GetCursorName: AnsiString;\nbegin\n  Result := FCursorName;\nend;\n\nfunction TZASAResultSet.RowUpdated: Boolean;\nbegin\n  Result := FUpdate;\nend;\n\nfunction TZASAResultSet.RowInserted: Boolean;\nbegin\n  Result := FInsert;\nend;\n\nfunction TZASAResultSet.RowDeleted: Boolean;\nbegin\n  Result := FDelete;\nend;\n\nprocedure TZASAResultSet.PrepareUpdateSQLData;\nbegin\n  FUpdate := not FInsert;\n  if not Assigned( FUpdateSQLData) then\n  begin\n    FUpdateSQLData := TZASASQLDA.Create( FASAConnection.GetPlainDriver,\n      FASAConnection.GetDBHandle, FCursorName, ConSettings, FSQLData.GetFieldCount);\n  end\n  else if FUpdateSQLData.GetFieldCount = 0 then\n    FUpdateSQLData.AllocateSQLDA( FSQLData.GetFieldCount);\nend;\n\nprocedure TZASAResultSet.UpdateNull(ColumnIndex: Integer);\nbegin\n  PrepareUpdateSQLData;\n  FUpdateSqlData.UpdateNull( ColumnIndex, True);\nend;\n\nprocedure TZASAResultSet.UpdateBoolean(ColumnIndex: Integer; Value: Boolean);\nbegin\n  PrepareUpdateSQLData;\n  FUpdateSqlData.UpdateBoolean( ColumnIndex, Value);\nend;\n\nprocedure TZASAResultSet.UpdateByte(ColumnIndex: Integer; Value: ShortInt);\nbegin\n  PrepareUpdateSQLData;\n  FUpdateSqlData.UpdateByte( ColumnIndex, Value);\nend;\n\nprocedure TZASAResultSet.UpdateShort(ColumnIndex: Integer; Value: SmallInt);\nbegin\n  PrepareUpdateSQLData;\n  FUpdateSqlData.UpdateShort( ColumnIndex, Value);\nend;\n\nprocedure TZASAResultSet.UpdateInt(ColumnIndex: Integer; Value: Integer);\nbegin\n  PrepareUpdateSQLData;\n  FUpdateSqlData.UpdateInt( ColumnIndex, Value);\nend;\n\nprocedure TZASAResultSet.UpdateLong(ColumnIndex: Integer; Value: Int64);\nbegin\n  PrepareUpdateSQLData;\n  FUpdateSqlData.UpdateLong( ColumnIndex, Value);\nend;\n\nprocedure TZASAResultSet.UpdateFloat(ColumnIndex: Integer; Value: Single);\nbegin\n  PrepareUpdateSQLData;\n  FUpdateSqlData.UpdateFloat( ColumnIndex, Value);\nend;\n\nprocedure TZASAResultSet.UpdateDouble(ColumnIndex: Integer; Value: Double);\nbegin\n  PrepareUpdateSQLData;\n  FUpdateSqlData.UpdateDouble( ColumnIndex, Value);\nend;\n\nprocedure TZASAResultSet.UpdateBigDecimal(ColumnIndex: Integer; Value: Extended);\nbegin\n  PrepareUpdateSQLData;\n  FUpdateSqlData.UpdateBigDecimal( ColumnIndex, Value);\nend;\n\nprocedure TZASAResultSet.UpdatePChar(ColumnIndex: Integer; Value: PChar);\nbegin\n  PrepareUpdateSQLData;\n  FUpdateSqlData.UpdatePChar( ColumnIndex, Value);\nend;\n\nprocedure TZASAResultSet.UpdateString(ColumnIndex: Integer; const Value: String);\nbegin\n  PrepareUpdateSQLData;\n  FUpdateSqlData.UpdateString(ColumnIndex, ZPlainString(Value));\nend;\n\nprocedure TZASAResultSet.UpdateUnicodeString(ColumnIndex: Integer; const Value: WideString);\nbegin\n  PrepareUpdateSQLData;\n  FUpdateSqlData.UpdateString(ColumnIndex, ZPlainString(Value));\nend;\n\nprocedure TZASAResultSet.UpdateBytes(ColumnIndex: Integer; const Value: TByteDynArray);\nbegin\n  PrepareUpdateSQLData;\n  FUpdateSqlData.UpdateBytes( ColumnIndex, Value);\nend;\n\nprocedure TZASAResultSet.UpdateDate(ColumnIndex: Integer; Value: TDateTime);\nbegin\n  PrepareUpdateSQLData;\n  FUpdateSqlData.UpdateDate( ColumnIndex, Value);\nend;\n\nprocedure TZASAResultSet.UpdateTime(ColumnIndex: Integer; Value: TDateTime);\nbegin\n  PrepareUpdateSQLData;\n  FUpdateSqlData.UpdateTime( ColumnIndex, Value);\nend;\n\nprocedure TZASAResultSet.UpdateTimestamp(ColumnIndex: Integer; Value: TDateTime);\nbegin\n  PrepareUpdateSQLData;\n  FUpdateSqlData.UpdateTimestamp( ColumnIndex, Value);\nend;\n\nprocedure TZASAResultSet.UpdateAsciiStream(ColumnIndex: Integer; Value: TStream);\nbegin\n  PrepareUpdateSQLData;\n  FUpdateSqlData.WriteBlob( ColumnIndex, Value, stAsciiStream);\nend;\n\nprocedure TZASAResultSet.UpdateUnicodeStream(ColumnIndex: Integer; Value: TStream);\nbegin\n  PrepareUpdateSQLData;\n  FUpdateSqlData.WriteBlob( ColumnIndex, Value, stUnicodeStream);\nend;\n\nprocedure TZASAResultSet.UpdateBinaryStream(ColumnIndex: Integer; Value: TStream);\nbegin\n  PrepareUpdateSQLData;\n  FUpdateSqlData.WriteBlob( ColumnIndex, Value, stBinaryStream);\nend;\n\nprocedure TZASAResultSet.UpdateValue(ColumnIndex: Integer; const Value: TZVariant);\nbegin\n  PrepareUpdateSQLData;\n  FUpdateSqlData.UpdateValue( ColumnIndex, EncodeVariant( Value));\nend;\n\nprocedure TZASAResultSet.InsertRow;\nbegin\n  if Assigned( FUpdateSQLData) and FInsert then\n  begin\n    FASAConnection.GetPlainDriver.db_put_into( FASAConnection.GetDBHandle,\n      PAnsiChar(FCursorName), FUpdateSQLData.GetData, FSQLData.GetData);\n    ZDbcASAUtils.CheckASAError( FASAConnection.GetPlainDriver,\n      FASAConnection.GetDBHandle, lcOther, 'Insert row');\n\n    FInsert := false;\n    FUpdateSQLData.FreeSQLDA;\n  end;\nend;\n\nprocedure TZASAResultSet.UpdateRow;\nbegin\n  if Assigned( FUpdateSQLData) and FUpdate then\n  begin\n    FASAConnection.GetPlainDriver.db_update( FASAConnection.GetDBHandle,\n      PAnsiChar(FCursorName), FUpdateSQLData.GetData);\n    ZDbcASAUtils.CheckASAError( FASAConnection.GetPlainDriver,\n      FASAConnection.GetDBHandle, lcOther, 'Update row:' + IntToStr( RowNo));\n\n    FUpdate := false;\n    FUpdateSQLData.FreeSQLDA;\n  end;\nend;\n\nprocedure TZASAResultSet.DeleteRow;\nbegin\n  FASAConnection.GetPlainDriver.db_delete( FASAConnection.GetDBHandle,\n    PAnsiChar(FCursorName));\n  ZDbcASAUtils.CheckASAError( FASAConnection.GetPlainDriver,\n    FASAConnection.GetDBHandle, lcOther, 'Delete row:' + IntToStr( RowNo));\n\n  FDelete := True;\n  if LastRowNo <> MaxInt then\n    LastRowNo := LastRowNo - FASAConnection.GetDBHandle.sqlerrd[2];\nend;\n\nprocedure TZASAResultSet.RefreshRow;\nbegin\n  MoveRelative( 0);\nend;\n\nprocedure TZASAResultSet.CancelRowUpdates;\nbegin\n  FUpdate := false;\n  if Assigned( FUpdateSQLData) then\n    FUpdateSQLData.FreeSQLDA;\nend;\n\nprocedure TZASAResultSet.MoveToInsertRow;\nbegin\n  FInsert := true;\nend;\n\nprocedure TZASAResultSet.MoveToCurrentRow;  \nbegin\n  FInsert := false;\n  if Assigned( FUpdateSQLData) then\n    FUpdateSQLData.FreeSQLDA;\nend;\n\n{ TZASABlob }\n\nfunction TZASABlob.Clone: IZBlob;\nvar\n  Dt: Pointer;\nbegin\n  Dt := nil;\n  if BlobSize > 0 then\n  begin\n    GetMem( Dt, BlobSize);\n    System.Move( BlobData^, Dt^, BlobSize);\n  end;\n  Result := TZASABlob.CreateWithData( Dt, BlobSize, FConnection);\nend;\n\n{**\n  Reads the blob information by blob handle.\n  @param handle a Interbase6 database connect handle.\n  @param the statement previously prepared\n}\nconstructor TZASABlob.Create( ResultSet: TZASAResultSet; ColID: Integer);\nbegin\n  inherited Create;\n  FConnection := ResultSet.GetStatement.GetConnection;\n  FBlobRead := False;\n  FResultSet := ResultSet;\n  FColID := ColID;\nend;\n\nconstructor TZASABlob.CreateWithStream(Stream: TStream; Connection: IZConnection);\nbegin\n  inherited CreateWithStream(Stream, Connection);\n  FBlobRead := true;\nend;\n\nconstructor TZASABlob.CreateWithData(Data: Pointer; Size: Integer;\n  Connection: IZConnection);\nbegin\n  inherited Create;\n  FConnection := Connection;\n  BlobData := Data;\n  BlobSize := Size;\n  Updated := False;\n  FBlobRead := true;\nend;\n\nfunction TZASABlob.GetBytes: TByteDynArray;\nbegin\n  ReadBlob;\n  Result := inherited GetBytes;\nend;\n\nfunction TZASABlob.GetStream: TStream;\nbegin\n  ReadBlob;\n  Result := inherited GetStream;\nend;\n\nfunction TZASABlob.GetString: RawByteString;\nbegin\n  ReadBlob;\n  Result := inherited GetString;\nend;\n\nfunction TZASABlob.GetUnicodeString: WideString;\nbegin\n  Result := inherited GetUnicodeString;\nend;\n\nfunction TZASABlob.IsEmpty: Boolean;\nbegin\n  ReadBlob;\n  Result := inherited IsEmpty;\nend;\n\nprocedure TZASABlob.ReadBlob;\nvar\n  Size: LongWord;\n  Buffer: Pointer;\nbegin\n  if FBlobRead then\n   Exit;\n  if Assigned(BlobData) then\n    FreeMem(BlobData);\n\n  if FResultSet.FInsert or ( FResultSet.FUpdate and FResultSet.FUpdateSQLData.IsAssigned( FColID)) then\n    FResultSet.FUpdateSQLData.ReadBlobToMem( FColID, Buffer, Size)\n  else\n    FResultSet.FSQLData.ReadBlobToMem( FColID, Buffer, Size);\n  BlobSize := Size;\n  BlobData := Buffer;\n  FBlobRead := True;\nend;\n\nend.\n"
  },
  {
    "path": "lib/zeosdbo/src/dbc/ZDbcASAStatement.pas",
    "content": "{*********************************************************}\n{                                                         }\n{                 Zeos Database Objects                   }\n{         Interbase Database Connectivity Classes         }\n{                                                         }\n{        Originally written by Sergey Merkuriev           }\n{                                                         }\n{*********************************************************}\n\n{@********************************************************}\n{    Copyright (c) 1999-2012 Zeos Development Group       }\n{                                                         }\n{ License Agreement:                                      }\n{                                                         }\n{ This library is distributed in the hope that it will be }\n{ useful, but WITHOUT ANY WARRANTY; without even the      }\n{ implied warranty of MERCHANTABILITY or FITNESS FOR      }\n{ A PARTICULAR PURPOSE.  See the GNU Lesser General       }\n{ Public License for more details.                        }\n{                                                         }\n{ The source code of the ZEOS Libraries and packages are  }\n{ distributed under the Library GNU General Public        }\n{ License (see the file COPYING / COPYING.ZEOS)           }\n{ with the following  modification:                       }\n{ As a special exception, the copyright holders of this   }\n{ library give you permission to link this library with   }\n{ independent modules to produce an executable,           }\n{ regardless of the license terms of these independent    }\n{ modules, and to copy and distribute the resulting       }\n{ executable under terms of your choice, provided that    }\n{ you also meet, for each linked independent module,      }\n{ the terms and conditions of the license of that module. }\n{ An independent module is a module which is not derived  }\n{ from or based on this library. If you modify this       }\n{ library, you may extend this exception to your version  }\n{ of the library, but you are not obligated to do so.     }\n{ If you do not wish to do so, delete this exception      }\n{ statement from your version.                            }\n{                                                         }\n{                                                         }\n{ The project web site is located on:                     }\n{   http://zeos.firmos.at  (FORUM)                        }\n{   http://sourceforge.net/p/zeoslib/tickets/ (BUGTRACKER)}\n{   svn://svn.code.sf.net/p/zeoslib/code-0/trunk (SVN)    }\n{                                                         }\n{   http://www.sourceforge.net/projects/zeoslib.          }\n{                                                         }\n{                                                         }\n{                                 Zeos Development Group. }\n{********************************************************@}\n\nunit ZDbcASAStatement;\n\ninterface\n\n{$I ZDbc.inc}\n\nuses Classes, {$IFDEF MSEgui}mclasses,{$ENDIF} SysUtils,\n  ZDbcIntfs, ZDbcStatement, ZDbcASA, ZDbcASAUtils, ZDbcASAResultSet,\n  ZPlainASADriver, ZCompatibility, ZDbcLogging, ZVariant, ZMessages;\n\ntype\n\n  {** Implements Generic ASA Statement. }\n  TZASAStatement = class(TZAbstractStatement)\n  private\n    FCachedBlob: Boolean;\n    FStmtNum: SmallInt;\n    FASAConnection: IZASAConnection;\n    FSQLData: IZASASQLDA;\n    FMoreResults: Boolean;\n    function InternalExecuteQuery(const SQL: RawByteString): IZResultSet;\n  public\n    constructor Create(Connection: IZConnection; Info: TStrings);\n    destructor Destroy; override;\n\n    procedure Close; override;\n    procedure Cancel; override;\n    function GetWarnings: EZSQLWarning; override;\n    procedure ClearWarnings; override;\n    function GetMoreResults: Boolean; override;\n    function ExecuteQuery(const SQL: RawByteString): IZResultSet; override;\n    function ExecuteUpdate(const SQL: RawByteString): Integer; override;\n    function Execute(const SQL: RawByteString): Boolean; override;\n  end;\n\n  {** Implements Prepared SQL Statement. }\n  TZASAPreparedStatement = class(TZAbstractPreparedStatement)\n  private\n    FCachedBlob: boolean;\n    FStmtNum: SmallInt;\n    FASAConnection: IZASAConnection;\n    FParamSQLData: IZASASQLDA;\n    FSQLData: IZASASQLDA;\n    FMoreResults: Boolean;\n    FPrepared: Boolean;\n  public\n    constructor Create(Connection: IZConnection; const SQL: string; Info: TStrings);\n    destructor Destroy; override;\n\n    procedure Close; override;\n    procedure Cancel; override;\n    function GetWarnings: EZSQLWarning; override;\n    procedure ClearWarnings; override;\n    function GetMoreResults: Boolean; override;\n    function ExecuteQuery(const SQL: RawByteString): IZResultSet; override;\n    function ExecuteUpdate(const SQL: RawByteString): Integer; override;\n    function Execute(const SQL: RawByteString): Boolean; override;\n\n    function ExecuteQueryPrepared: IZResultSet; override;\n    function ExecuteUpdatePrepared: Integer; override;\n    function ExecutePrepared: Boolean; override;\n  end;\n\n  TZASACallableStatement = class(TZAbstractCallableStatement)\n  private\n    FCachedBlob: boolean;\n    FStmtNum: SmallInt;\n    FASAConnection: IZASAConnection;\n    FParamSQLData: IZASASQLDA;\n    FSQLData: IZASASQLDA;\n    FMoreResults: Boolean;\n    FPrepared: Boolean;\n  protected\n    procedure FetchOutParams( Value: IZASASQLDA);\n    function GetProcedureSQL: RawByteString;\n  public\n    constructor Create(Connection: IZConnection; const SQL: string; Info: TStrings);\n    destructor Destroy; override;\n\n    procedure Close; override;\n    procedure Cancel; override;\n    function GetWarnings: EZSQLWarning; override;\n    procedure ClearWarnings; override;\n    function GetMoreResults: Boolean; override;\n    function ExecuteQuery(const SQL: RawByteString): IZResultSet; override;\n    function ExecuteUpdate(const SQL: RawByteString): Integer; override;\n    function Execute(const SQL: RawByteString): Boolean; override;\n\n    function ExecuteQueryPrepared: IZResultSet; override;\n    function ExecuteUpdatePrepared: Integer; override;\n    function ExecutePrepared: Boolean; override;\n  end;\n\nimplementation\n\nuses ZSysUtils, ZDbcUtils, ZPlainASAConstants;\n\n{ TZASAStatement }\n\nfunction TZASAStatement.InternalExecuteQuery(const SQL: RawByteString): IZResultSet;\nvar\n  Cursor: AnsiString;\n  CursorOptions: SmallInt;\nbegin\n  Close;\n  with FASAConnection do\n  begin\n    try\n      GetPlainDriver.db_prepare_describe( GetDBHandle, nil, @FStmtNum,\n            PAnsiChar(ASQL), FSQLData.GetData, SQL_PREPARE_DESCRIBE_STMTNUM +\n            SQL_PREPARE_DESCRIBE_OUTPUT + SQL_PREPARE_DESCRIBE_VARRESULT, 0);\n      ZDbcASAUtils.CheckASAError(GetPlainDriver, GetDBHandle, lcExecute, LogSQL);\n\n      FMoreResults := GetDBHandle.sqlerrd[2] = 0;\n      if not FMoreResults then\n      begin\n        if FSQLData.GetData^.sqld <= 0 then\n        begin\n          Result := nil;\n          Exit;\n        end\n        else\n          if ( FSQLData.GetData^.sqld > FSQLData.GetData^.sqln) then\n          begin\n            FSQLData.AllocateSQLDA( FSQLData.GetData^.sqld);\n            GetPlainDriver.db_describe( GetDBHandle, nil, @FStmtNum,\n              FSQLData.GetData, SQL_DESCRIBE_OUTPUT);\n            ZDbcASAUtils.CheckASAError( GetPlainDriver, GetDBHandle, lcExecute, LogSQL);\n          end;\n        FSQLData.InitFields;\n      end;\n      if ResultSetConcurrency = rcUpdatable then\n        CursorOptions := CUR_OPEN_DECLARE + CUR_UPDATE\n      else\n        CursorOptions := CUR_OPEN_DECLARE + CUR_READONLY;\n      if ResultSetType = rtScrollInsensitive then\n        CursorOptions := CursorOptions + CUR_INSENSITIVE;\n      Cursor := CursorName;\n      GetPlainDriver.db_open(GetDBHandle, PAnsiChar(Cursor), nil, @FStmtNum,\n            nil, FetchSize, 0, CursorOptions);\n      ZDbcASAUtils.CheckASAError( GetPlainDriver, GetDBHandle, lcExecute, LogSQL);\n      Closed := false;\n      if FMoreResults then\n        DescribeCursor( FASAConnection, FSQLData, Cursor, LogSQL);\n\n      LastUpdateCount := -1;\n      Result := GetCachedResultSet( LogSQL, Self,\n        TZASAResultSet.Create( Self, LogSQL, FStmtNum, Cursor, FSQLData, nil,\n        FCachedBlob));\n      { Logging SQL Command }\n      DriverManager.LogMessage( lcExecute, GetPlainDriver.GetProtocol, LogSQL);\n    except\n      on E: Exception do\n      begin\n        Self.Close;\n        raise;\n      end;\n    end;\n  end;\nend;\n{**\n  Constructs this object and assignes the main properties.\n  @param Connection a database connection object.\n  @param Handle a connection handle pointer.\n  @param Dialect a dialect Interbase SQL must be 1 or 2 or 3.\n  @param Info a statement parameters.\n}\nconstructor TZASAStatement.Create(Connection: IZConnection;\n  Info: TStrings);\nbegin\n  inherited Create(Connection, Info);\n\n  FASAConnection := Connection as IZASAConnection;\n  FetchSize := BlockSize;\n  ResultSetConcurrency := rcUpdatable;\n  ResultSetType := rtScrollSensitive;\n  FCachedBlob := StrToBoolEx(DefineStatementParameter(Self, 'cashedblob', 'true'));\n  CursorName := AnsiString(RandomString(12));\n  FSQLData := TZASASQLDA.Create( FASAConnection.GetPlainDriver,\n    FASAConnection.GetDBHandle, CursorName, ConSettings);\nend;\n\ndestructor TZASAStatement.Destroy;\nbegin\n  FSQLData := nil;\n  inherited;\nend;\n\nprocedure TZASAStatement.Close;\nbegin\n  if not Closed then\n  begin\n    FASAConnection.GetPlainDriver.db_close(FASAConnection.GetDBHandle, PAnsiChar(CursorName));\n    Closed := false;\n  end;\n  if FStmtNum <> 0 then\n  begin\n    FASAConnection.GetPlainDriver.db_dropstmt( FASAConnection.GetDBHandle, nil,\n     nil, @FStmtNum);\n    FStmtNum := 0;\n  end;\n  inherited;\nend;\n\nprocedure TZASAStatement.Cancel;\nbegin\n  with FASAConnection do\n  begin\n    GetPlainDriver.db_cancel_request( GetDBHandle);\n    ZDbcASAUtils.CheckASAError( GetPlainDriver, GetDBHandle, lcExecute);\n  end;\nend;\n\nfunction TZASAStatement.GetWarnings: EZSQLWarning;\nbegin\n  Result := inherited GetWarnings;\nend;\n\nprocedure TZASAStatement.ClearWarnings;\nbegin\n  inherited;\nend;\n\nfunction TZASAStatement.GetMoreResults: Boolean;\nvar\n  SQLData: IZASASQLDA;\nbegin\n  Result := FMoreResults;\n  if FMoreResults then\n  begin\n    with FASAConnection do\n    begin\n      GetPlainDriver.db_resume(GetDBHandle, PAnsiChar(CursorName));\n      ZDbcASAUtils.CheckASAError( GetPlainDriver, GetDBHandle, lcExecute);\n      if GetDBHandle.sqlcode = SQLE_PROCEDURE_COMPLETE then\n        Result := false\n      else\n      begin\n        SQLData := TZASAResultSet(LastResultSet).SQLData;\n        DescribeCursor( FASAConnection, TZASASQLDA( SQLData), CursorName, '');\n      end;\n    end;\n  end;\nend;\n\n{**\n  Executes an SQL statement that returns a single <code>ResultSet</code> object.\n  @param sql typically this is a static SQL <code>SELECT</code> statement\n  @return a <code>ResultSet</code> object that contains the data produced by the\n    given query; never <code>null</code>\n}\nfunction TZASAStatement.ExecuteQuery(const SQL: RawByteString): IZResultSet;\nbegin\n  ASQL := SQL;\n  Result := InternalExecuteQuery(ASQL);\n  if Result = nil then\n    raise EZSQLException.Create( SCanNotRetrieveResultSetData)\nend;\n\n{**\n  Executes an SQL <code>INSERT</code>, <code>UPDATE</code> or\n  <code>DELETE</code> statement. In addition,\n  SQL statements that return nothing, such as SQL DDL statements,\n  can be executed.\n\n  @param sql an SQL <code>INSERT</code>, <code>UPDATE</code> or\n    <code>DELETE</code> statement or an SQL statement that returns nothing\n  @return either the row count for <code>INSERT</code>, <code>UPDATE</code>\n    or <code>DELETE</code> statements, or 0 for SQL statements that return nothing\n}\n{$HINTS OFF}\nfunction TZASAStatement.ExecuteUpdate(const SQL: RawByteString): Integer;\nbegin\n  ASQL := SQL;\n  Close;\n  Result := -1;\n  with FASAConnection do\n  begin\n    GetPlainDriver.db_execute_imm(GetDBHandle, PAnsiChar(ASQL));\n    ZDbcASAUtils.CheckASAError( GetPlainDriver, GetDBHandle, lcExecute, LogSQL);\n\n    Result := GetDBHandle.sqlErrd[2];\n    LastUpdateCount := Result;\n\n    { Logging SQL Command }\n    DriverManager.LogMessage(lcExecute, GetPlainDriver.GetProtocol, LogSQL);\n  end;\nend;\n{$HINTS ON}\n\n{**\n  Executes an SQL statement that may return multiple results.\n  Under some (uncommon) situations a single SQL statement may return\n  multiple result sets and/or update counts.  Normally you can ignore\n  this unless you are (1) executing a stored procedure that you know may\n  return multiple results or (2) you are dynamically executing an\n  unknown SQL string.  The  methods <code>execute</code>,\n  <code>getMoreResults</code>, <code>getResultSet</code>,\n  and <code>getUpdateCount</code> let you navigate through multiple results.\n\n  The <code>execute</code> method executes an SQL statement and indicates the\n  form of the first result.  You can then use the methods\n  <code>getResultSet</code> or <code>getUpdateCount</code>\n  to retrieve the result, and <code>getMoreResults</code> to\n  move to any subsequent result(s).\n\n  @param sql any SQL statement\n  @return <code>true</code> if the next result is a <code>ResultSet</code> object;\n  <code>false</code> if it is an update count or there are no more results\n  @see #getResultSet\n  @see #getUpdateCount\n  @see #getMoreResults\n}\nfunction TZASAStatement.Execute(const SQL: RawByteString): Boolean;\nbegin\n  ASQL := SQL;\n  LastResultSet := InternalExecuteQuery(ASQL);\n  Result := Assigned(LastResultSet);\n  if not Result then\n    ExecuteUpdate(ASQL);\nend;\n\n{ TZASAPreparedStatement }\n\n{**\n  Constructs this object and assignes the main properties.\n  @param Connection a database connection object.\n  @param Handle a connection handle pointer.\n  @param Dialect a dialect Interbase SQL must be 1 or 2 or 3.\n  @param Info a statement parameters.\n}\nconstructor TZASAPreparedStatement.Create(Connection: IZConnection;\n  const SQL: string; Info: TStrings);\nbegin\n  inherited Create(Connection, SQL, Info);\n\n  FASAConnection := Connection as IZASAConnection;\n  FetchSize := BlockSize;\n  ResultSetConcurrency := rcUpdatable;\n  ResultSetType := rtScrollSensitive;\n  FCachedBlob := StrToBoolEx(DefineStatementParameter(Self, 'cashedblob', 'true'));\n  CursorName := AnsiString(RandomString(12));\n  FParamSQLData := TZASASQLDA.Create( FASAConnection.GetPlainDriver,\n    FASAConnection.GetDBHandle, CursorName, ConSettings);\n  FSQLData := TZASASQLDA.Create( FASAConnection.GetPlainDriver,\n    FASAConnection.GetDBHandle, CursorName, ConSettings);\n  ASAPrepare( FASAConnection, FSQLData, FParamSQLData, ASQL, LogSQL, @FStmtNum, FPrepared,\n    FMoreResults);\nend;\n\ndestructor TZASAPreparedStatement.Destroy;\nbegin\n  FSQLData := nil;\n  FParamSQLData := nil;\n  inherited;\nend;\n\nprocedure TZASAPreparedStatement.Close;\nbegin\n  if not Closed then\n  begin\n    FASAConnection.GetPlainDriver.db_close( FASAConnection.GetDBHandle, PAnsiChar(CursorName));\n    Closed := false;\n  end;\n  if FStmtNum <> 0 then\n  begin\n    FASAConnection.GetPlainDriver.db_dropstmt( FASAConnection.GetDBHandle, nil, nil, @FStmtNum);\n    FStmtNum := 0;\n  end;\n  inherited;\nend;\n\nprocedure TZASAPreparedStatement.Cancel;\nbegin\n  with FASAConnection do\n  begin\n    GetPlainDriver.db_cancel_request( GetDBHandle);\n    ZDbcASAUtils.CheckASAError( GetPlainDriver, GetDBHandle, lcExecute, SQL);\n  end;\nend;\n\nfunction TZASAPreparedStatement.GetWarnings: EZSQLWarning;\nbegin\n  Result := inherited GetWarnings;\nend;\n\nprocedure TZASAPreparedStatement.ClearWarnings;\nbegin\n  inherited;\nend;\n\nfunction TZASAPreparedStatement.GetMoreResults: Boolean;\nbegin\n  Result := FMoreResults;\n  if FMoreResults then\n  begin\n    with FASAConnection do\n    begin\n      GetPlainDriver.db_resume(GetDBHandle, PAnsiChar(CursorName));\n      ZDbcASAUtils.CheckASAError( GetPlainDriver, GetDBHandle, lcExecute);\n      if GetDBHandle.sqlcode = SQLE_PROCEDURE_COMPLETE then\n        Result := false\n      else\n        DescribeCursor( FASAConnection, TZASASQLDA( FSQLData), CursorName, '');\n    end;\n  end;\nend;\n\n{**\n  Executes an SQL statement that may return multiple results.\n  Under some (uncommon) situations a single SQL statement may return\n  multiple result sets and/or update counts.  Normally you can ignore\n  this unless you are (1) executing a stored procedure that you know may\n  return multiple results or (2) you are dynamically executing an\n  unknown SQL string.  The  methods <code>execute</code>,\n  <code>getMoreResults</code>, <code>getResultSet</code>,\n  and <code>getUpdateCount</code> let you navigate through multiple results.\n\n  The <code>execute</code> method executes an SQL statement and indicates the\n  form of the first result.  You can then use the methods\n  <code>getResultSet</code> or <code>getUpdateCount</code>\n  to retrieve the result, and <code>getMoreResults</code> to\n  move to any subsequent result(s).\n\n  @param sql any SQL statement\n  @return <code>true</code> if the next result is a <code>ResultSet</code> object;\n  <code>false</code> if it is an update count or there are no more results\n  @see #getResultSet\n  @see #getUpdateCount\n  @see #getMoreResults\n}\n\nfunction TZASAPreparedStatement.Execute(const SQL: RawByteString): Boolean;\nbegin\n  if ASQL <> SQL then\n  begin\n    Close;\n    ASQL := SQL;\n    ASAPrepare( FASAConnection, FSQLData, FParamSQLData, ASQL, LogSQL, @FStmtNum, FPrepared,\n      FMoreResults);\n  end;\n  Result := ExecutePrepared;\nend;\n\n{**\n  Executes any kind of SQL statement.\n  Some prepared statements return multiple results; the <code>execute</code>\n  method handles these complex statements as well as the simpler\n  form of statements handled by the methods <code>executeQuery</code>\n  and <code>executeUpdate</code>.\n  @see Statement#execute\n}\nfunction TZASAPreparedStatement.ExecutePrepared: Boolean;\nbegin\n  if FMoreResults or ( FSQLData.GetData.sqld > 0) then\n  begin\n    LastResultSet := ExecuteQueryPrepared;\n    Result := true;\n  end\n  else\n  begin\n    ExecuteUpdatePrepared;\n    Result := false;\n  end;\nend;\n\n{**\n  Executes an SQL statement that returns a single <code>ResultSet</code> object.\n  @param sql typically this is a static SQL <code>SELECT</code> statement\n  @return a <code>ResultSet</code> object that contains the data produced by the\n    given query; never <code>null</code>\n}\nfunction TZASAPreparedStatement.ExecuteQuery(const SQL: RawByteString): IZResultSet;\nbegin\n  if ASQL <> SQL then\n  begin\n    Close;\n    ASQL := SQL;\n    ASAPrepare( FASAConnection, FSQLData, FParamSQLData, ASQL, LogSQL, @FStmtNum,\n      FPrepared, FMoreResults);\n  end;\n  Result := ExecuteQueryPrepared;\nend;\n\n{**\n  Executes the SQL query in this <code>PreparedStatement</code> object\n  and returns the result set generated by the query.\n\n  @return a <code>ResultSet</code> object that contains the data produced by the\n    query; never <code>null</code>\n}\n{$HINTS OFF}\nfunction TZASAPreparedStatement.ExecuteQueryPrepared: IZResultSet;\nvar\n  Cursor: AnsiString;\n  CursorOptions: SmallInt;\nbegin\n  with FASAConnection do\n  begin\n    PrepareParameters( GetPlainDriver, InParamValues, InParamTypes,\n      InParamCount, FParamSQLData, FASAConnection.GetConSettings);\n    if ResultSetConcurrency = rcUpdatable then\n      CursorOptions := CUR_OPEN_DECLARE + CUR_UPDATE\n    else\n      CursorOptions := CUR_OPEN_DECLARE + CUR_READONLY;\n    if ResultSetType = rtScrollInsensitive then\n      CursorOptions := CursorOptions + CUR_INSENSITIVE;\n    Cursor := CursorName;\n    GetPlainDriver.db_open(GetDBHandle, PAnsiChar(Cursor), nil, @FStmtNum,\n      FParamSQLData.GetData, FetchSize, 0, CursorOptions);\n    ZDbcASAUtils.CheckASAError( GetPlainDriver, GetDBHandle, lcExecute,\n      SQL);\n    Closed := false;\n    try\n      if FMoreResults then\n        DescribeCursor( FASAConnection, TZASASQLDA( FSQLData), Cursor, '');\n\n      LastUpdateCount := -1;\n      Result := GetCachedResultSet( SQL, Self,\n        TZASAResultSet.Create( Self, SQL, FStmtNum, Cursor, FSQLData, nil,\n        FCachedBlob));\n\n      { Logging SQL Command }\n      DriverManager.LogMessage( lcExecute, GetPlainDriver.GetProtocol, LogSQL);\n    except\n      on E: Exception do\n      begin\n        Self.Close;\n        raise;\n      end;\n    end;\n  end;\nend;\n{$HINTS ON}\n\n{**\n  Executes an SQL <code>INSERT</code>, <code>UPDATE</code> or\n  <code>DELETE</code> statement. In addition,\n  SQL statements that return nothing, such as SQL DDL statements,\n  can be executed.\n\n  @param sql an SQL <code>INSERT</code>, <code>UPDATE</code> or\n    <code>DELETE</code> statement or an SQL statement that returns nothing\n  @return either the row count for <code>INSERT</code>, <code>UPDATE</code>\n    or <code>DELETE</code> statements, or 0 for SQL statements that return nothing\n}\nfunction TZASAPreparedStatement.ExecuteUpdate(const SQL: RawByteString): Integer;\nbegin\n  if ASQL <> SQL then\n  begin\n    Close;\n    ASQL := SQL;\n    ASAPrepare( FASAConnection, FSQLData, FParamSQLData, ASQL, LogSQL, @FStmtNum,\n      FPrepared, FMoreResults);\n  end;\n  Result := ExecuteUpdatePrepared;\nend;\n\n{**\n  Executes the SQL INSERT, UPDATE or DELETE statement\n  in this <code>PreparedStatement</code> object.\n  In addition,\n  SQL statements that return nothing, such as SQL DDL statements,\n  can be executed.\n\n  @return either the row count for INSERT, UPDATE or DELETE statements;\n  or 0 for SQL statements that return nothing\n}\n{$HINTS OFF}\nfunction TZASAPreparedStatement.ExecuteUpdatePrepared: Integer;\nbegin\n  Result := -1;\n  with FASAConnection do\n  begin\n\n    PrepareParameters( GetPlainDriver, InParamValues, InParamTypes,\n      InParamCount, FParamSQLData, FASAConnection.GetConSettings);\n    GetPlainDriver.db_execute_into( GetDBHandle, nil, nil, @FStmtNum,\n      FParamSQLData.GetData, nil);\n    ZDbcASAUtils.CheckASAError( GetPlainDriver, GetDBHandle, lcExecute, SQL,\n      SQLE_TOO_MANY_RECORDS);\n\n    Result := GetDBHandle.sqlErrd[2];\n    LastUpdateCount := Result;\n\n    { Logging SQL Command }\n    DriverManager.LogMessage(lcExecute, GetPlainDriver.GetProtocol, SQL);\n  end;\nend;\n{$HINTS ON}\n\n\n{ TZASACallableStatement }\n\n{**\n  Constructs this object and assignes the main properties.\n  @param Connection a database connection object.\n  @param Handle a connection handle pointer.\n  @param Info a statement parameters.\n}\nconstructor TZASACallableStatement.Create(Connection: IZConnection;\n  const SQL: string; Info: TStrings);\nbegin\n  inherited Create(Connection, SQL, Info);\n\n  FASAConnection := Connection as IZASAConnection;\n  FetchSize := BlockSize;\n  ResultSetConcurrency := rcUpdatable;\n  ResultSetType := rtScrollSensitive;\n  FCachedBlob := StrToBoolEx(DefineStatementParameter(Self, 'cashedblob', 'true'));\n  CursorName := AnsiString(RandomString(12));\n  FParamSQLData := TZASASQLDA.Create( FASAConnection.GetPlainDriver,\n    FASAConnection.GetDBHandle, CursorName, ConSettings);\n  FSQLData := TZASASQLDA.Create( FASAConnection.GetPlainDriver,\n    FASAConnection.GetDBHandle, CursorName, ConSettings);\nend;\n\ndestructor TZASACallableStatement.Destroy;\nbegin\n  FSQLData := nil;\n  FParamSQLData := nil;\n  inherited;\nend;\n\nprocedure TZASACallableStatement.Close;\nbegin\n  if not Closed then\n  begin\n    FASAConnection.GetPlainDriver.db_close(FASAConnection.GetDBHandle, PAnsiChar(CursorName));\n    Closed := false;\n  end;\n  if FStmtNum <> 0 then\n  begin\n    FASAConnection.GetPlainDriver.db_dropstmt( FASAConnection.GetDBHandle, nil,\n     nil, @FStmtNum);\n    FStmtNum := 0;\n  end;\n  inherited;\nend;\n\nprocedure TZASACallableStatement.Cancel;\nbegin\n  with FASAConnection do\n  begin\n    GetPlainDriver.db_cancel_request( GetDBHandle);\n    ZDbcASAUtils.CheckASAError( GetPlainDriver, GetDBHandle, lcExecute, SQL);\n  end;\nend;\n\nfunction TZASACallableStatement.GetWarnings: EZSQLWarning;\nbegin\n  Result := inherited GetWarnings;\nend;\n\nprocedure TZASACallableStatement.ClearWarnings;\nbegin\n  inherited;\nend;\n\nfunction TZASACallableStatement.GetMoreResults: Boolean;\nbegin\n  Result := FMoreResults;\n  if FMoreResults then\n  begin\n    with FASAConnection do\n    begin\n      GetPlainDriver.db_resume(GetDBHandle, PAnsiChar(CursorName));\n      ZDbcASAUtils.CheckASAError( GetPlainDriver, GetDBHandle, lcExecute);\n      if GetDBHandle.sqlcode = SQLE_PROCEDURE_COMPLETE then\n        Result := false\n      else\n        DescribeCursor( FASAConnection, TZASASQLDA( FSQLData), CursorName, '');\n    end;\n  end;\nend;\n\n{**\n  Executes an SQL statement that may return multiple results.\n  Under some (uncommon) situations a single SQL statement may return\n  multiple result sets and/or update counts.  Normally you can ignore\n  this unless you are (1) executing a stored procedure that you know may\n  return multiple results or (2) you are dynamically executing an\n  unknown SQL string.  The  methods <code>execute</code>,\n  <code>getMoreResults</code>, <code>getResultSet</code>,\n  and <code>getUpdateCount</code> let you navigate through multiple results.\n\n  The <code>execute</code> method executes an SQL statement and indicates the\n  form of the first result.  You can then use the methods\n  <code>getResultSet</code> or <code>getUpdateCount</code>\n  to retrieve the result, and <code>getMoreResults</code> to\n  move to any subsequent result(s).\n\n  @param sql any SQL statement\n  @return <code>true</code> if the next result is a <code>ResultSet</code> object;\n  <code>false</code> if it is an update count or there are no more results\n  @see #getResultSet\n  @see #getUpdateCount\n  @see #getMoreResults\n}\n\nfunction TZASACallableStatement.Execute(const SQL: RawByteString): Boolean;\nvar\n  ProcSQL: RawByteString;\nbegin\n  TrimInParameters;\n  ProcSQL := GetProcedureSQL;\n  if not FPrepared or ( ASQL <> ProcSQL) then\n  begin\n    Close;\n    ASQL := ProcSQL;\n    ASAPrepare( FASAConnection, FSQLData, FParamSQLData, ASQL, LogSQL, @FStmtNum,\n      FPrepared, FMoreResults);\n  end;\n  Result := ExecutePrepared;\nend;\n\n{**\n  Executes any kind of SQL statement.\n  Some prepared statements return multiple results; the <code>execute</code>\n  method handles these complex statements as well as the simpler\n  form of statements handled by the methods <code>executeQuery</code>\n  and <code>executeUpdate</code>.\n  @see Statement#execute\n}\nfunction TZASACallableStatement.ExecutePrepared: Boolean;\nbegin\n  if not FPrepared then\n    Result := Execute(ASQL)\n  else\n  begin\n    if FMoreResults or ( ( FSQLData.GetData.sqld > 0) and\n      ( FSQLData.GetData.sqlVar[0].sqlInd^ and DT_PROCEDURE_OUT = 0)) then\n    begin\n      LastResultSet := ExecuteQueryPrepared;\n      Result := true;\n    end\n    else\n    begin\n      ExecuteUpdatePrepared;\n      Result := false;\n    end;\n  end;\nend;\n\n{**\n  Executes an SQL statement that returns a single <code>ResultSet</code> object.\n  @param sql typically this is a static SQL <code>SELECT</code> statement\n  @return a <code>ResultSet</code> object that contains the data produced by the\n    given query; never <code>null</code>\n}\nfunction TZASACallableStatement.ExecuteQuery(const SQL: RawByteString): IZResultSet;\nvar\n  ProcSQL: RawByteString;\nbegin\n  TrimInParameters;\n  ProcSQL := GetProcedureSQL;\n  if not FPrepared or ( ASQL <> ProcSQL) then\n  begin\n    Close;\n    ASQL := ProcSQL;\n    ASAPrepare( FASAConnection, FSQLData, FParamSQLData, ASQL, LogSQL, @FStmtNum,\n      FPrepared, FMoreResults);\n  end;\n  Result := ExecuteQueryPrepared;\nend;\n\n{**\n  Executes the SQL query in this <code>PreparedStatement</code> object\n  and returns the result set generated by the query.\n\n  @return a <code>ResultSet</code> object that contains the data produced by the\n    query; never <code>null</code>\n}\n{$HINTS OFF}\nfunction TZASACallableStatement.ExecuteQueryPrepared: IZResultSet;\nvar\n  Cursor: AnsiString;\n  CursorOptions: SmallInt;\nbegin\n  if not FPrepared then\n    Result := ExecuteQuery(ASQL)\n  else\n  begin\n    with FASAConnection do\n    begin\n      PrepareParameters( GetPlainDriver, InParamValues, InParamTypes,\n        InParamCount, FParamSQLData, FASAConnection.GetConSettings);\n      if ResultSetConcurrency = rcUpdatable then\n        CursorOptions := CUR_OPEN_DECLARE + CUR_UPDATE\n      else\n        CursorOptions := CUR_OPEN_DECLARE + CUR_READONLY;\n      if ResultSetType = rtScrollInsensitive then\n        CursorOptions := CursorOptions + CUR_INSENSITIVE;\n      Cursor := CursorName;\n      GetPlainDriver.db_open(GetDBHandle, PAnsiChar(Cursor), nil, @FStmtNum,\n        FParamSQLData.GetData, FetchSize, 0, CursorOptions);\n      ZDbcASAUtils.CheckASAError( GetPlainDriver, GetDBHandle, lcExecute, LogSQL);\n      Closed := false;\n      try\n        if FMoreResults then\n          DescribeCursor( FASAConnection, TZASASQLDA( FSQLData), Cursor, LogSQL);\n\n        LastUpdateCount := -1;\n        Result := GetCachedResultSet( LogSQL, Self,\n          TZASAResultSet.Create( Self, LogSQL, FStmtNum, Cursor, FSQLData, nil,\n          FCachedBlob));\n\n        { Logging SQL Command }\n        DriverManager.LogMessage( lcExecute, GetPlainDriver.GetProtocol, LogSQL);\n      except\n        on E: Exception do\n        begin\n          Self.Close;\n          raise;\n        end;\n      end;\n    end;\n  end;\nend;\n{$HINTS ON}\n\n{**\n  Executes an SQL <code>INSERT</code>, <code>UPDATE</code> or\n  <code>DELETE</code> statement. In addition,\n  SQL statements that return nothing, such as SQL DDL statements,\n  can be executed.\n\n  @param sql an SQL <code>INSERT</code>, <code>UPDATE</code> or\n    <code>DELETE</code> statement or an SQL statement that returns nothing\n  @return either the row count for <code>INSERT</code>, <code>UPDATE</code>\n    or <code>DELETE</code> statements, or 0 for SQL statements that return nothing\n}\nfunction TZASACallableStatement.ExecuteUpdate(const SQL: RawByteString): Integer;\nvar\n  ProcSQL: RawByteString;\nbegin\n  TrimInParameters;\n  ProcSQL := GetProcedureSQL;\n  if not FPrepared or ( ASQL <> ProcSQL) then\n  begin\n    Close;\n    ASQL := ProcSQL;\n    ASAPrepare( FASAConnection, FSQLData, FParamSQLData, ASQL, LogSQL, @FStmtNum,\n      FPrepared, FMoreResults);\n  end;\n  Result := ExecuteUpdatePrepared;\nend;\n\n{**\n  Executes the SQL INSERT, UPDATE or DELETE statement\n  in this <code>PreparedStatement</code> object.\n  In addition,\n  SQL statements that return nothing, such as SQL DDL statements,\n  can be executed.\n\n  @return either the row count for INSERT, UPDATE or DELETE statements;\n  or 0 for SQL statements that return nothing\n}\nfunction TZASACallableStatement.ExecuteUpdatePrepared: Integer;\nbegin\n  if not FPrepared then\n    Result := ExecuteUpdate( SQL)\n  else\n  begin\n//    Result := -1;\n    with FASAConnection do\n    begin\n\n      PrepareParameters( GetPlainDriver, InParamValues, InParamTypes,\n        InParamCount, FParamSQLData, FASAConnection.GetConSettings);\n      GetPlainDriver.db_execute_into( GetDBHandle, nil, nil, @FStmtNum,\n        FParamSQLData.GetData, FSQLData.GetData);\n      ZDbcASAUtils.CheckASAError( GetPlainDriver, GetDBHandle, lcExecute, SQL);\n\n      Result := GetDBHandle.sqlErrd[2];\n      LastUpdateCount := Result;\n      { Fetch data and fill Output params }\n      FetchOutParams( FSQLData);\n\n      { Logging SQL Command }\n      DriverManager.LogMessage(lcExecute, GetPlainDriver.GetProtocol, SQL);\n    end;\n  end;\nend;\n\n{**\n  Set output parameters values from IZResultSQLDA.\n  @param Value a IZASASQLDA object.\n}\nprocedure TZASACallableStatement.FetchOutParams( Value: IZASASQLDA);\nvar\n  I: Integer;\n  L: LongWord;\n  Temp: TZVariant;\n  TempBlob: IZBlob;\n  P: Pointer;\nbegin\n  SetOutParamCount(Value.GetFieldCount);\n  for I := 0 to Value.GetFieldCount-1 do\n  begin\n    if Value.IsNull(I) then\n      DefVarManager.SetNull(Temp)\n    else\n    case Value.GetFieldSqlType(I) of\n      stBoolean:\n        DefVarManager.SetAsBoolean(Temp, Value.GetBoolean(I));\n      stByte:\n        DefVarManager.SetAsInteger(Temp, Value.GetByte(I));\n      stShort:\n        DefVarManager.SetAsInteger(Temp, Value.GetShort(I));\n      stInteger:\n        DefVarManager.SetAsInteger(Temp, Value.GetInt(I));\n      stLong:\n        DefVarManager.SetAsInteger(Temp, Value.GetLong(I));\n      stFloat:\n        DefVarManager.SetAsFloat(Temp, Value.GetFloat(I));\n      stDouble:\n        DefVarManager.SetAsFloat(Temp, Value.GetDouble(I));\n      stBigDecimal:\n        DefVarManager.SetAsFloat(Temp, Value.GetBigDecimal(I));\n      stString:\n        DefVarManager.SetAsString(Temp, ZDbcString(Value.GetString(I)));\n      stUnicodeString:\n        DefVarManager.SetAsUnicodeString(Temp, ZDbcUnicodeString(Value.GetString(I)));\n      stBytes:\n        DefVarManager.SetAsBytes( Temp, Value.GetBytes( I));\n      stDate:\n        DefVarManager.SetAsDateTime(Temp, Value.GetDate(I));\n      stTime:\n        DefVarManager.SetAsDateTime(Temp, Value.GetTime(I));\n      stTimestamp:\n        DefVarManager.SetAsDateTime(Temp, Value.GetTimestamp(I));\n      stAsciiStream,\n      stUnicodeStream,\n      stBinaryStream:\n        begin\n          GetMem( P, PZASABlobStruct( Value.GetData.sqlvar[I].sqlData).untrunc_len);\n          Value.ReadBlobToMem( I, P, L);\n          TempBlob := TZASABlob.CreateWithData( P, L, GetConnection);\n          FreeMem(P);\n          DefVarManager.SetAsInterface( Temp, TempBlob);\n        end;\n    end;\n    OutParamValues[I] := Temp;\n  end;\nend;\n\n{**\n   Create sql string for calling stored procedure.\n   @param SelectProc indicate use <b>EXECUTE PROCEDURE</b> or\n    <b>SELECT</b> staement\n   @return a Stored Procedure SQL string\n}\nfunction TZASACallableStatement.GetProcedureSql: RawByteString;\n\n  function GenerateParamsStr(Count: integer): string;\n  var\n    I: integer;\n  begin\n    for I := 0 to Count - 1 do\n    begin\n      if Result <> '' then\n        Result := Result + ',';\n      Result := Result + '?';\n    end;\n  end;\n\nvar\n  InParams: string;\nbegin\n  InParams := GenerateParamsStr( High( InParamValues) + 1);\n  if InParams <> '' then\n    InParams := '(' + InParams + ')';\n  Result := ZPlainString('call ' + SQL + InParams);\nend;\n\nend.\n\n\n"
  },
  {
    "path": "lib/zeosdbo/src/dbc/ZDbcASAUtils.pas",
    "content": "{*********************************************************}\n{                                                         }\n{                 Zeos Database Objects                   }\n{           ASA Database Connectivity Classes             }\n{                                                         }\n{         Originally written by Sergey Seroukhov          }\n{                           and Sergey Merkuriev          }\n{                                                         }\n{*********************************************************}\n\n{@********************************************************}\n{    Copyright (c) 1999-2012 Zeos Development Group       }\n{                                                         }\n{ License Agreement:                                      }\n{                                                         }\n{ This library is distributed in the hope that it will be }\n{ useful, but WITHOUT ANY WARRANTY; without even the      }\n{ implied warranty of MERCHANTABILITY or FITNESS FOR      }\n{ A PARTICULAR PURPOSE.  See the GNU Lesser General       }\n{ Public License for more details.                        }\n{                                                         }\n{ The source code of the ZEOS Libraries and packages are  }\n{ distributed under the Library GNU General Public        }\n{ License (see the file COPYING / COPYING.ZEOS)           }\n{ with the following  modification:                       }\n{ As a special exception, the copyright holders of this   }\n{ library give you permission to link this library with   }\n{ independent modules to produce an executable,           }\n{ regardless of the license terms of these independent    }\n{ modules, and to copy and distribute the resulting       }\n{ executable under terms of your choice, provided that    }\n{ you also meet, for each linked independent module,      }\n{ the terms and conditions of the license of that module. }\n{ An independent module is a module which is not derived  }\n{ from or based on this library. If you modify this       }\n{ library, you may extend this exception to your version  }\n{ of the library, but you are not obligated to do so.     }\n{ If you do not wish to do so, delete this exception      }\n{ statement from your version.                            }\n{                                                         }\n{                                                         }\n{ The project web site is located on:                     }\n{   http://zeos.firmos.at  (FORUM)                        }\n{   http://sourceforge.net/p/zeoslib/tickets/ (BUGTRACKER)}\n{   svn://svn.code.sf.net/p/zeoslib/code-0/trunk (SVN)    }\n{                                                         }\n{   http://www.sourceforge.net/projects/zeoslib.          }\n{                                                         }\n{                                                         }\n{                                 Zeos Development Group. }\n{********************************************************@}\n\nunit ZDbcASAUtils;\n\ninterface\n\n{$I ZDbc.inc}\n\nuses\n  Classes, {$IFDEF MSEgui}mclasses,{$ENDIF} SysUtils, Types,\n  ZSysUtils, ZDbcIntfs, ZPlainASADriver, ZDbcLogging, ZCompatibility, ZDbcASA,\n  ZDbcStatement, ZVariant, ZPlainASAConstants;\n\nconst\n  StdVars = 20;\n  MinBLOBSize = 256;\n  BlockSize = 20;\n\ntype\n  { ASA Error Class}\n  EZASAConvertError = class(Exception);\n\n  TZASADECLTYPE = record\n    sqlType: SmallInt;\n    sqlLen : Word;\n  end;\n\n  { Base interface for sqlda }\n  IZASASQLDA = interface\n    ['{7606E8EB-9FC8-4F76-8D91-E23AB96409E1}']\n    procedure AllocateSQLDA( NumVars: Word);\n    procedure InitFields;\n    procedure FreeSQLDA;\n\n    function GetData: PASASQLDA;\n    function IsBlob(const Index: Word): boolean;\n    function IsNullable(const Index: Word): boolean;\n\n    function GetFieldCount: Integer;\n    function GetFieldName(const Index: Word): string;\n    function GetFieldIndex(const Name: String): Word;\n    function GetFieldScale(const Index: Word): integer;\n    function GetFieldSqlType(const Index: Word): TZSQLType;\n    function GetFieldLength(const Index: Word): Word;\n\n    procedure UpdateNull(const Index: Integer; Value: boolean);\n    procedure UpdateBoolean(const Index: Integer; Value: boolean);\n    procedure UpdateByte(const Index: Integer; Value: Byte);\n    procedure UpdateShort(const Index: Integer; Value: SmallInt);\n    procedure UpdateInt(const Index: Integer; Value: Integer);\n    procedure UpdateLong(const Index: Integer; Value: Int64);\n    procedure UpdateFloat(const Index: Integer; Value: Single);\n    procedure UpdateDouble(const Index: Integer; Value: Double);\n    procedure UpdateBigDecimal(const Index: Integer; Value: Extended);\n    procedure UpdatePChar(const Index: Integer; Value: PChar);\n    procedure UpdateString(const Index: Integer; Value: RawByteString);\n    procedure UpdateBytes(const Index: Integer; Value: TByteDynArray);\n    procedure UpdateDate(const Index: Integer; Value: TDateTime);\n    procedure UpdateTime(const Index: Integer; Value: TDateTime);\n    procedure UpdateTimestamp(const Index: Integer; Value: TDateTime);\n    procedure UpdateValue(const Index: Word; Value: Variant);\n    procedure WriteBlob(const Index: Integer; Stream: TStream; const BlobType: TZSQLType);\n\n    function IsNull(const Index: Integer): Boolean;\n    function IsAssigned(const Index: Integer): Boolean;\n    function GetBoolean(const Index: Integer): Boolean;\n    function GetByte(const Index: Integer): Byte;\n    function GetShort(const Index: Integer): SmallInt;\n    function GetInt(const Index: Integer): Integer;\n    function GetLong(const Index: Integer): Int64;\n    function GetFloat(const Index: Integer): Single;\n    function GetDouble(const Index: Integer): Double;\n    function GetBigDecimal(const Index: Integer): Extended;\n    function GetPChar(const Index: Integer): PAnsiChar;\n    function GetString(const Index: Integer): RawByteString;\n    function GetBytes(const Index: Integer): TByteDynArray;\n    function GetDate(const Index: Integer): TDateTime;\n    function GetTime(const Index: Integer): TDateTime;\n    function GetTimestamp(const Index: Integer): TDateTime;\n    function GetValue(const Index: Word): Variant;\n\n    procedure ReadBlobToMem(const Index: Word; var Buffer: Pointer; var Length: LongWord);\n    procedure ReadBlobToStream(const Index: Word; Stream: TStream);\n    procedure ReadBlobToString(const Index: Word; var str: RawByteString);\n    procedure ReadBlobToVariant(const Index: Word; var Value: Variant);\n  end;\n\n  { Base class contain core functions to work with sqlda structure\n    Can allocate memory for sqlda structure get basic information }\n  TZASASQLDA = class (TInterfacedObject, IZASASQLDA)\n  private\n    FConSettings: PZConSettings;\n    FSQLDA: PASASQLDA;\n    FPlainDriver: IZASAPlainDriver;\n    FHandle: PZASASQLCA;\n    FCursorName: AnsiString;\n    procedure CreateException( Msg: string);\n    procedure CheckIndex(const Index: Word);\n    procedure CheckRange(const Index: Word);\n    procedure SetFieldType(const Index: Word; ASAType: Smallint; Len: LongWord;\n      SetDeclType: Boolean = true); overload;\n    procedure SetFieldType(ToSQLDA: PASASQLDA; const Index: Word; ASAType: Smallint; Len: LongWord;\n      SetDeclType: Boolean = true); overload;\n  protected\n    FDeclType: array of TZASADECLTYPE;\n    procedure ReadBlob(const Index: Word; Buffer: Pointer; Length: LongWord);\n  public\n    constructor Create(PlainDriver: IZASAPlainDriver; Handle: PZASASQLCA;\n      CursorName: AnsiString; ConSettings: PZConSettings; NumVars: Word = StdVars);\n    destructor Destroy; override;\n\n    procedure AllocateSQLDA( NumVars: Word);\n    procedure InitFields;\n    procedure FreeSQLDA;\n\n    function GetData: PASASQLDA;\n    function IsBlob(const Index: Word): boolean;\n    function IsNullable(const Index: Word): boolean;\n\n    function GetFieldCount: Integer;\n    function GetFieldName(const Index: Word): string;\n    function GetFieldIndex(const Name: String): Word;\n    function GetFieldScale(const Index: Word): Integer;\n    function GetFieldSqlType(const Index: Word): TZSQLType;\n    function GetFieldLength(const Index: Word): Word;\n\n    procedure UpdateNull(const Index: Integer; Value: boolean);\n    procedure UpdateBoolean(const Index: Integer; Value: boolean);\n    procedure UpdateByte(const Index: Integer; Value: Byte);\n    procedure UpdateShort(const Index: Integer; Value: SmallInt);\n    procedure UpdateInt(const Index: Integer; Value: Integer);\n    procedure UpdateLong(const Index: Integer; Value: Int64);\n    procedure UpdateFloat(const Index: Integer; Value: Single);\n    procedure UpdateDouble(const Index: Integer; Value: Double);\n    procedure UpdateBigDecimal(const Index: Integer; Value: Extended);\n    procedure UpdatePChar(const Index: Integer; Value: PChar);\n    procedure UpdateString(const Index: Integer; Value: RawByteString);\n    procedure UpdateBytes(const Index: Integer; Value: TByteDynArray);\n    procedure UpdateDate(const Index: Integer; Value: TDateTime);\n    procedure UpdateTime(const Index: Integer; Value: TDateTime);\n    procedure UpdateDateTime(const Index: Integer; Value: TDateTime);\n    procedure UpdateTimestamp(const Index: Integer; Value: TDateTime);\n    procedure UpdateValue(const Index: Word; Value: Variant);\n    procedure WriteBlob(const Index: Integer; Stream: TStream; const BlobType: TZSQLType);\n\n    function IsNull(const Index: Integer): Boolean;\n    function IsAssigned(const Index: Integer): Boolean;\n    function GetBoolean(const Index: Integer): Boolean;\n    function GetByte(const Index: Integer): Byte;\n    function GetShort(const Index: Integer): SmallInt;\n    function GetInt(const Index: Integer): Integer;\n    function GetLong(const Index: Integer): Int64;\n    function GetFloat(const Index: Integer): Single;\n    function GetDouble(const Index: Integer): Double;\n    function GetBigDecimal(const Index: Integer): Extended;\n    function GetPChar(const Index: Integer): PAnsiChar;\n    function GetString(const Index: Integer): RawByteString;\n    function GetBytes(const Index: Integer): TByteDynArray;\n    function GetDate(const Index: Integer): TDateTime;\n    function GetTime(const Index: Integer): TDateTime;\n    function GetTimestamp(const Index: Integer): TDateTime;\n    function GetValue(const Index: Word): Variant;\n\n    procedure ReadBlobToMem(const Index: Word; var Buffer: Pointer; var Length: LongWord);\n    procedure ReadBlobToStream(const Index: Word; Stream: TStream);\n    procedure ReadBlobToString(const Index: Word; var str: RawByteString);\n    procedure ReadBlobToVariant(const Index: Word; var Value: Variant);\n  end;\n\n{**\n  Converts a ASA native type into ZDBC SQL types.\n  @param FieldHandle a handler to field description structure.\n  @return a SQL undepended type.\n}\nfunction ConvertASATypeToSQLType(const SQLType: SmallInt; const CtrlsCPType: TZControlsCodePage): TZSQLType;\n\n{**\n  Converts a ASA native type into String.\n  @param SQLType Field of TASASQLVar structure.\n  @return type description.\n}\nfunction ConvertASATypeToString( SQLType: SmallInt): String;\n\nfunction ConvertASAJDBCToSqlType(const FieldType: SmallInt;\n  CtrlsCPType: TZControlsCodePage): TZSQLType;\n{\nprocedure TSQLTimeStampToASADateTime( DT: TSQLTimeStamp; const ASADT: PZASASQLDateTime);\nfunction ASADateTimeToSQLTimeStamp( ASADT: PZASASQLDateTime): TSQLTimeStamp;\n}\n{**\n  Checks for possible sql errors.\n  @param PlainDriver a MySQL plain driver.\n  @param Handle a MySQL connection handle.\n  @param LogCategory a logging category.\n  @param LogMessage a logging message.\n}\nprocedure CheckASAError(PlainDriver: IZASAPlainDriver;\n  Handle: PZASASQLCA; LogCategory: TZLoggingCategory; LogMessage: string = '';\n  SupressExceptionID: Integer = 0);\n\nfunction GetCachedResultSet(SQL: string;\n  Statement: IZStatement; NativeResultSet: IZResultSet): IZResultSet;\n\nprocedure DescribeCursor( FASAConnection: IZASAConnection; FSQLData: IZASASQLDA;\n  Cursor: AnsiString; SQL: String);\n\nprocedure ASAPrepare( FASAConnection: IZASAConnection; FSQLData, FParamsSQLData: IZASASQLDA;\n   const SQL: RawByteString; const LogSQL: String; StmtNum: PSmallInt; var FPrepared, FMoreResults: Boolean);\n\nprocedure PrepareParameters( PlainDriver: IZASAPlainDriver;\n  InParamValues: TZVariantDynArray; InParamTypes: TZSQLTypeArray;\n  InParamCount: Integer; ParamSqlData: IZASASQLDA;\n  ConSettings: PZConSettings);\n\nfunction RandomString( Len: integer): string;\n\nimplementation\n\nuses Variants, ZMessages, ZDbcCachedResultSet, Math, ZEncoding\n  {$IFDEF WITH_UNITANSISTRINGS}, AnsiStrings{$ENDIF};\n\n{ TZASASQLDA }\n\nprocedure TZASASQLDA.CreateException( Msg: string);\nbegin\n  DriverManager.LogError( lcOther, FPlainDriver.GetProtocol, '', -1, Msg);\n  raise EZSQLException.Create( Format( SSQLError1, [ Msg]));\nend;\n\n{**\n   Check range count fields. If index out of range raised exception.\n   @param Index the index field\n}\nprocedure TZASASQLDA.CheckIndex(const Index: Word);\nbegin\n  Assert( Assigned( FSQLDA), 'SQLDA not initialized.');\n  Assert( Index < Word(FSQLDA.sqld), 'Out of Range.');\nend;\n\nprocedure TZASASQLDA.CheckRange(const Index: Word);\nbegin\n  CheckIndex( Index);\n  Assert( Assigned( FSQLDA.sqlVar[ Index].sqlData),\n    'No memory for variable in SQLDA.');\nend;\n\nprocedure TZASASQLDA.SetFieldType(ToSQLDA: PASASQLDA; const Index: Word;\n  ASAType: Smallint; Len: LongWord; SetDeclType: Boolean = true);\nbegin\n  CheckIndex(Index);\n  with ToSQLDA.sqlvar[Index] do\n  begin\n    if ( ASAType and $FFFE = DT_LONGBINARY) or\n       ( ASAType and $FFFE = DT_LONGNVARCHAR) or\n       ( ASAType and $FFFE = DT_LONGVARCHAR) then\n    begin\n      if Assigned( sqlData) then\n        ReallocMem( sqlData, SizeOf( TZASABlobStruct) + Len)\n      else\n        GetMem( sqlData, SizeOf( TZASABlobStruct) + Len);\n      PZASABlobStruct( sqlData).array_len := Len;\n      PZASABlobStruct( sqlData).stored_len := 0;\n      PZASABlobStruct( sqlData).untrunc_len := 0;\n      PZASABlobStruct( sqlData).arr[0] := #0;\n      Inc( Len, SizeOf( TZASABlobStruct));\n    end\n    else\n    begin\n      if ( ASAType and $FFFE = DT_BINARY) or\n         ( ASAType and $FFFE = DT_VARCHAR) then\n        Inc( Len, SizeOf( TZASASQLSTRING));\n      if Assigned( sqlData) then\n        ReallocMem( sqlData, Len)\n      else\n        GetMem( sqlData, Len);\n      if ( ASAType and $FFFE = DT_BINARY) or\n         ( ASAType and $FFFE = DT_VARCHAR) then\n        PZASASQLSTRING( sqlData).length := 0;\n    end;\n    sqlType := ASAType;\n    sqllen := Len;\n    if SetDeclType then\n    begin\n      FDeclType[Index].sqlType := sqlType;\n      FDeclType[Index].sqlLen := sqlLen;\n    end;\n  end;\nend;\n\nprocedure TZASASQLDA.SetFieldType(const Index: Word; ASAType: Smallint;\n  Len: LongWord; SetDeclType: Boolean = true);\nbegin\n  SetFieldType(FSQLDA, Index, ASAType, Len, SetDeclType);\nend;\n\nconstructor TZASASQLDA.Create(PlainDriver: IZASAPlainDriver; Handle: PZASASQLCA;\n   CursorName: AnsiString; ConSettings: PZConSettings; NumVars: Word = StdVars);\nbegin\n  FPlainDriver := PlainDriver;\n  FHandle := Handle;\n  FCursorName := CursorName;\n  AllocateSQLDA(NumVars);\n  FConSettings := ConSettings;\n  inherited Create;\nend;\n\ndestructor TZASASQLDA.Destroy;\nbegin\n  FreeSQLDA;\n  inherited;\nend;\n\n{**\n   Reallocate SQLDA to fields count length\n   @param Value the count fields\n}\nprocedure TZASASQLDA.AllocateSQLDA( NumVars: Word);\nbegin\n  FreeSQLDA;\n  FSQLDA := FPlainDriver.db_alloc_sqlda( NumVars);\n  if not Assigned( FSQLDA) then\n    CreateException( 'Not enough memory for SQLDA');\n  SetLength(FDeclType, FSQLDA.sqln);\nend;\n\n{**\n   Allocate memory for SQLVar in SQLDA structure for every\n   fields by it length.\n}\nprocedure TZASASQLDA.InitFields;\nvar\n  i: Integer;\nbegin\n  if Assigned( FSQLDA) then\n  begin\n    for i := 0 to FSQLDA.sqld-1 do\n    begin\n      FDeclType[i].sqlType := FSQLDA.sqlVar[i].sqlType;\n      FDeclType[i].sqlLen := FSQLDA.sqlVar[i].sqlLen;\n      case FSQLDA.sqlVar[i].sqlType and $FFFE of\n        DT_DATE,\n        DT_TIME,\n        DT_TIMESTAMP:\n                        begin\n                          FSQLDA.sqlVar[i].sqlType := DT_TIMESTAMP_STRUCT +\n                            ( FSQLDA.sqlVar[i].sqlType and $0001);\n                          FSQLDA.sqlVar[i].sqlLen := SizeOf( TZASASQLDateTime);\n                        end;\n        DT_DECIMAL:\n                        begin\n                          FSQLDA.sqlVar[i].sqlType := DT_DOUBLE +\n                            ( FSQLDA.sqlVar[i].sqlType and $0001);\n                          FSQLDA.sqlVar[i].sqlLen := SizeOf( Double);\n                        end;\n        DT_STRING,\n        DT_FIXCHAR,\n        DT_VARCHAR,\n        DT_LONGVARCHAR: if FSQLDA.sqlVar[i].sqlLen < MinBLOBSize then\n                          FSQLDA.sqlVar[i].sqlType := DT_VARCHAR +\n                            ( FSQLDA.sqlVar[i].sqlType and $0001)\n                        else\n                        begin\n                          FSQLDA.sqlVar[i].sqlType := DT_LONGVARCHAR +\n                            ( FSQLDA.sqlVar[i].sqlType and $0001);\n                          FSQLDA.sqlVar[i].sqlLen := 0;\n                        end;\n        DT_BINARY,\n        DT_LONGBINARY:  if FSQLDA.sqlVar[i].sqlLen < MinBLOBSize then\n                          FSQLDA.sqlVar[i].sqlType := DT_BINARY +\n                            ( FSQLDA.sqlVar[i].sqlType and $0001)\n                        else\n                        begin\n                          FSQLDA.sqlVar[i].sqlType := DT_LONGBINARY +\n                            ( FSQLDA.sqlVar[i].sqlType and $0001);\n                          FSQLDA.sqlVar[i].sqlLen := 0;\n                        end;\n      end;\n      SetFieldType( i, FSQLDA.sqlVar[i].sqlType, FSQLDA.sqlVar[i].sqlLen, False);\n    end;\n  end;\nend;\n\n{**\n   Clear allocated data for SQLDA parameters\n}\nprocedure TZASASQLDA.FreeSQLDA;\nvar\n  i: integer;\nbegin\n  if Assigned( FSQLDA) then\n  begin\n    for i := 0 to FSQLDA.sqln-1 do\n    begin\n      FSQLDA.sqlVar[i].sqlInd := nil;\n      if Assigned( FSQLDA.sqlVar[i].sqlData) then\n      begin\n        FreeMem( FSQLDA.sqlVar[i].sqlData);\n        FSQLDA.sqlVar[i].sqlData := nil;\n      end;\n    end;\n    FPlainDriver.db_free_sqlda( FSQLDA);\n    FSQLDA := nil;\n  end;\n  SetLength(FDeclType, 0);\n  FDeclType := nil;\nend;\n\n{**\n   Return pointer to SQLDA structure\n}\nfunction TZASASQLDA.GetData: PASASQLDA;\nbegin\n  Result := FSQLDA;\nend;\n\n{**\n   Indicate blob field\n   @param Index the index fields\n   @return true if blob field overwise false\n}\nfunction TZASASQLDA.IsBlob(const Index: Word): boolean;\nbegin\n  Result := GetFieldSqlType( Index) in\n    [ stAsciiStream, stUnicodeStream, stBinaryStream];\nend;\n\n{**\n   Indicate nullable field\n   @param Index the index fields\n   @return true if field nullable overwise false\n}\nfunction TZASASQLDA.IsNullable(const Index: Word): boolean;\nbegin\n  CheckIndex(Index);\n  Result := FSQLDA.sqlvar[Index].sqlType and 1 = 1\nend;\n\n{**\n   Get fields count not allocated.\n   @return fields count\n}\nfunction TZASASQLDA.GetFieldCount: Integer;\nbegin\n  if Assigned( FSQLDA) then\n    Result := FSQLDA.sqld\n  else\n    Result := 0;\nend;\n\n{**\n   Return Name for field\n   @param Index the index fields\n   @return the name\n}\nfunction TZASASQLDA.GetFieldName(const Index: Word): string;\n{$IFDEF WITH_RAWBYTESTRING}\nvar Temp: RawByteString;\n{$ENDIF}\nbegin\n  CheckIndex(Index);\n  {$IFDEF WITH_RAWBYTESTRING}\n  SetLength(Temp, FSQLDA.sqlvar[Index].sqlname.length-1);\n  Move(FSQLDA.sqlvar[Index].sqlname.data, PAnsiChar(Temp)^, FSQLDA.sqlvar[Index].sqlname.length-1);\n  Result := FPlainDriver.ZDbcString(Temp, FConSettings);\n  {$ELSE}\n  SetString( Result, FSQLDA.sqlvar[Index].sqlname.data,\n    FSQLDA.sqlvar[Index].sqlname.length-1);\n  {$ENDIF}\nend;\n\n{**\n   Return field index by it name\n   @param Index the index fields\n   @return the index field\n}\nfunction TZASASQLDA.GetFieldIndex(const Name: String): Word;\nbegin\n  for Result := 0 to FSQLDA.sqld - 1 do\n    if FSQLDA.sqlvar[Result].sqlname.length = Length(name) then\n      if {$IFDEF WITH_STRLICOMP_DEPRECATED}AnsiStrings.{$ENDIF}StrLIComp(@FSQLDA.sqlvar[Result].sqlname.data, PAnsiChar(FPlainDriver.ZPlainString(Name, FConSettings)), Length(name)) = 0 then\n            Exit;\n  CreateException( Format( SFieldNotFound1, [name]));\n  Result := 0; // satisfy compiler\nend;\n\n{**\n   Return field length\n   @param Index the index fields\n   @return the field lenth\n}\nfunction TZASASQLDA.GetFieldLength(const Index: Word): Word;\nbegin\n  CheckIndex( Index);\n  if FSQLDA.sqlvar[Index].sqlType and $FFFE <> DT_DECIMAL then\n    Result := FSQLDA.sqlvar[Index].sqlLen\n  else\n    Result := (FSQLDA.sqlvar[Index].sqlLen and $FF) div 2 + 1;\nend;\n\n{**\n   Return field scale\n   @param Index the index fields\n   @return the field scale\n}\nfunction TZASASQLDA.GetFieldScale(const Index: Word): integer;\nbegin\n  CheckIndex(Index);\n  if FSQLDA.sqlvar[Index].sqlType and $FFFE <> DT_DECIMAL then\n    Result := 0\n  else\n    Result := FSQLDA.sqlvar[Index].sqlLen div 256;\nend;\n\n{**\n   Convert ASA sql type to SQLType\n   @param Index the index fields\n   @return the SQLType\n}\nfunction TZASASQLDA.GetFieldSqlType(const Index: Word): TZSQLType;\nbegin\n  CheckIndex(Index);\n  if FSQLDA.sqlvar[Index].sqlType and $FFFE <> DT_TIMESTAMP_STRUCT then\n    Result := ConvertASATypeToSQLType(FSQLDA.sqlvar[Index].sqlType,\n      FConSettings.CPType)\n  else\n    Result := ConvertASATypeToSQLType( FDeclType[Index].sqlType,\n      FConSettings.CPType)\nend;\n\n{**\n   Set up parameter null value\n   @param Index the target parameter index\n   @param Value the source value\n}\nprocedure TZASASQLDA.UpdateNull(const Index: Integer; Value: Boolean);\nbegin\n  CheckIndex( Index);\n  with FSQLDA.sqlvar[ Index] do\n  begin\n    if not Assigned( sqlData) then\n      SetFieldType( Index, DT_TINYINT or 1, SizeOf( Byte));\n    if Value then\n      sqlind^ := -1 //NULL\n    else\n      sqlind^ :=  0; //NOT NULL\n  end;\nend;\n\n{**\n   Set up parameter Boolean value\n   @param Index the target parameter index\n   @param Value the source value\n}\nprocedure TZASASQLDA.UpdateBoolean(const Index: Integer; Value: boolean);\nbegin\n  CheckIndex( Index);\n  SetFieldType( Index, DT_BIT or 1, SizeOf( Byte));\n  with FSQLDA.sqlvar[Index] do\n  begin\n    case sqlType and $FFFE of\n      DT_SMALLINT,\n      DT_UNSSMALLINT      : PSmallint(sqldata)^ := ord(Value);\n      DT_INT,\n      DT_UNSINT           : PInteger(sqldata)^ := ord(Value);\n      DT_FLOAT            : PSingle(sqldata)^ := ord(Value);\n      DT_DOUBLE           : PDouble(sqldata)^ := ord(Value);\n      DT_VARCHAR:\n                            begin\n                              PZASASQLSTRING( sqlData).length := 1;\n                              {$IFDEF WITH_STRPLCOPY_DEPRECATED}AnsiStrings.{$ENDIF}StrPLCopy( @PZASASQLSTRING( sqlData).data[0],\n                                AnsiString(IntToStr(ord(Value))), sqllen-3);\n                            end;\n      DT_TINYINT,\n      DT_BIT              : PByte(sqldata)^ := ord(Value);\n      DT_BIGINT,\n      DT_UNSBIGINT        : PInt64(sqldata)^ := ord(Value);\n    else\n      CreateException( SUnsupportedParameterType);\n    end;\n    if (sqlind <> nil) then\n       sqlind^ := 0; // not null\n  end;\nend;\n\n{**\n   Set up parameter Byte value\n   @param Index the target parameter index\n   @param Value the source value\n}\nprocedure TZASASQLDA.UpdateByte(const Index: Integer; Value: Byte);\nbegin\n  CheckIndex( Index);\n  SetFieldType( Index, DT_TINYINT or 1, SizeOf( Byte));\n  with FSQLDA.sqlvar[Index] do\n  begin\n    case sqlType and $FFFE of\n      DT_SMALLINT,\n      DT_UNSSMALLINT      : PWord(sqldata)^ := Value; //was PSmallint\n      DT_INT,\n      DT_UNSINT           : PInteger(sqldata)^ := Value;\n      DT_FLOAT            : PSingle(sqldata)^ := Value;\n      DT_DOUBLE           : PDouble(sqldata)^ := Value;\n      DT_VARCHAR:\n                            begin\n                              PZASASQLSTRING( sqlData).length :=\n                                Length( IntToStr( Value));\n                              {$IFDEF WITH_STRPLCOPY_DEPRECATED}AnsiStrings.{$ENDIF}StrPLCopy( @PZASASQLSTRING( sqlData).data[0],\n                                AnsiString(IntToStr(Value)), sqllen-3);\n                            end;\n      DT_TINYINT,\n      DT_BIT              : PByte(sqldata)^ := Value;\n      DT_BIGINT,\n      DT_UNSBIGINT        : PInt64(sqldata)^ := Value;\n    else\n      CreateException( SUnsupportedParameterType);\n    end;\n    if (sqlind <> nil) then\n       sqlind^ := 0; // not null\n  end;\nend;\n\n{**\n   Set up parameter short value\n   @param Index the target parameter index\n   @param Value the source value\n}\nprocedure TZASASQLDA.UpdateShort(const Index: Integer; Value: SmallInt);\nbegin\n  CheckIndex( Index);\n  SetFieldType( Index, DT_SMALLINT or 1, SizeOf( SmallInt));\n  with FSQLDA.sqlvar[Index] do\n  begin\n    case sqlType and $FFFE of\n      DT_SMALLINT,\n      DT_UNSSMALLINT      : PSmallInt(sqldata)^ := Value;\n      DT_INT,\n      DT_UNSINT           : PInteger(sqldata)^ := Value;\n      DT_FLOAT            : PSingle(sqldata)^ := Value;\n      DT_DOUBLE           : PDouble(sqldata)^ := Value;\n      DT_VARCHAR:\n                            begin\n                              PZASASQLSTRING( sqlData).length :=\n                                Length( IntToStr( Value));\n                              {$IFDEF WITH_STRPLCOPY_DEPRECATED}AnsiStrings.{$ENDIF}StrPLCopy( @PZASASQLSTRING( sqlData).data[0],\n                                AnsiString(IntToStr(Value)), sqllen-3);\n                            end;\n      DT_TINYINT,\n      DT_BIT              : PByte(sqldata)^ := Value;\n      DT_BIGINT,\n      DT_UNSBIGINT        : PInt64(sqldata)^ := Value;\n    else\n      CreateException( SUnsupportedParameterType);\n    end;\n    if (sqlind <> nil) then\n       sqlind^ := 0; // not null\n  end;\nend;\n\n{**\n   Set up parameter integer value\n   @param Index the target parameter index\n   @param Value the source value\n}\nprocedure TZASASQLDA.UpdateInt(const Index: Integer; Value: Integer);\nbegin\n  CheckIndex( Index);\n  SetFieldType( Index, DT_INT or 1, SizeOf( Integer));\n  with FSQLDA.sqlvar[Index] do\n  begin\n    case sqlType and $FFFE of\n      DT_SMALLINT,\n      DT_UNSSMALLINT      : PSmallint(sqldata)^ := Value;\n      DT_INT,\n      DT_UNSINT           : PInteger(sqldata)^ := Value;\n      DT_FLOAT            : PSingle(sqldata)^ := Value;\n      DT_DOUBLE           : PDouble(sqldata)^ := Value;\n      DT_VARCHAR:\n                            begin\n                              PZASASQLSTRING( sqlData).length :=\n                                Length( IntToStr(Value));\n                              {$IFDEF WITH_STRPLCOPY_DEPRECATED}AnsiStrings.{$ENDIF}StrPLCopy( @PZASASQLSTRING( sqlData).data[0],\n                                AnsiString(IntToStr( Value)), sqllen-3);\n                            end;\n      DT_TINYINT,\n      DT_BIT              : PByte(sqldata)^ := Value;\n      DT_BIGINT,\n      DT_UNSBIGINT        : PInt64(sqldata)^ := Value;\n    else\n      CreateException( SUnsupportedParameterType);\n    end;\n    if (sqlind <> nil) then\n       sqlind^ := 0; // not null\n  end;\nend;\n\n{**\n   Set up parameter Long value\n   @param Index the target parameter index\n   @param Value the source value\n}\nprocedure TZASASQLDA.UpdateLong(const Index: integer; Value: Int64);\nbegin\n  CheckIndex( Index);\n  SetFieldType( Index, DT_BIGINT or 1, SizeOf( Int64));\n  with FSQLDA.sqlvar[Index] do\n  begin\n    case sqlType and $FFFE of\n      DT_SMALLINT,\n      DT_UNSSMALLINT      : PSmallint(sqldata)^ := Value;\n      DT_INT,\n      DT_UNSINT           : PInteger(sqldata)^ := Value;\n      DT_FLOAT            : PSingle(sqldata)^ := Value;\n      DT_DOUBLE           : PDouble(sqldata)^ := Value;\n      DT_VARCHAR:\n                            begin\n                              PZASASQLSTRING( sqlData).length :=\n                                Length( IntToStr( Value));\n                              {$IFDEF WITH_STRPLCOPY_DEPRECATED}AnsiStrings.{$ENDIF}StrPLCopy( @PZASASQLSTRING( sqlData).data[0],\n                                AnsiString(IntToStr(Value)), sqllen-3);\n                            end;\n      DT_TINYINT,\n      DT_BIT              : PByte(sqldata)^ := Value;\n      DT_BIGINT,\n      DT_UNSBIGINT        : PInt64(sqldata)^ := Value;\n    else\n      CreateException( SUnsupportedParameterType);\n    end;\n    if (sqlind <> nil) then\n       sqlind^ := 0; // not null\n  end;\nend;\n\n{**\n   Set up parameter Float value\n   @param Index the target parameter index\n   @param Value the source value\n}\nprocedure TZASASQLDA.UpdateFloat(const Index: Integer; Value: Single);\nbegin\n  CheckIndex( Index);\n  SetFieldType( Index, DT_FLOAT or 1, SizeOf( Single));\n  with FSQLDA.sqlvar[Index] do\n  begin\n    case sqlType and $FFFE of\n      DT_SMALLINT,\n      DT_UNSSMALLINT      : PSmallint(sqldata)^ := Trunc( Value);\n      DT_INT,\n      DT_UNSINT           : PInteger(sqldata)^ := Trunc( Value);\n      DT_FLOAT            : PSingle(sqldata)^ := Value;\n      DT_DOUBLE           : PDouble(sqldata)^ := Value;\n      DT_VARCHAR:\n                            begin\n                              PZASASQLSTRING( sqlData).length :=\n                                Length( FloatToStr( Value));\n                              {$IFDEF WITH_STRPLCOPY_DEPRECATED}AnsiStrings.{$ENDIF}StrPLCopy( @PZASASQLSTRING( sqlData).data[0],\n                                AnsiString(FloatToStr(Value)), sqllen-3);\n                            end;\n      DT_TINYINT,\n      DT_BIT              : PByte(sqldata)^ := Trunc( Value);\n      DT_BIGINT,\n      DT_UNSBIGINT        : PInt64(sqldata)^ := Trunc( Value);\n    else\n      CreateException( SUnsupportedParameterType);\n    end;\n    if (sqlind <> nil) then\n       sqlind^ := 0; // not null\n  end;\nend;\n\n{**\n   Set up parameter Double value\n   @param Index the target parameter index\n   @param Value the source value\n}\nprocedure TZASASQLDA.UpdateDouble(const Index: Integer; Value: Double);\nbegin\n  CheckIndex( Index);\n  SetFieldType( Index, DT_DOUBLE or 1, SizeOf( Double));\n  with FSQLDA.sqlvar[Index] do\n  begin\n    case sqlType and $FFFE of\n      DT_SMALLINT,\n      DT_UNSSMALLINT      : PSmallint(sqldata)^ := Trunc( Value);\n      DT_INT,\n      DT_UNSINT           : PInteger(sqldata)^ := Trunc( Value);\n      DT_FLOAT            : PSingle(sqldata)^ := Value;\n      DT_DOUBLE           : PDouble(sqldata)^ := Value;\n      DT_VARCHAR:\n                            begin\n                              PZASASQLSTRING( sqlData).length :=\n                                Length( FloatToStr( Value));\n                              {$IFDEF WITH_STRPLCOPY_DEPRECATED}AnsiStrings.{$ENDIF}StrPLCopy( @PZASASQLSTRING( sqlData).data[0],\n                                AnsiString(FloatToStr( Value)), sqllen-3);\n                            end;\n      DT_TINYINT,\n      DT_BIT              : PByte(sqldata)^ := Trunc( Value);\n      DT_BIGINT,\n      DT_UNSBIGINT        : PInt64(sqldata)^ := Trunc( Value);\n    else\n      CreateException( SUnsupportedParameterType);\n    end;\n    if (sqlind <> nil) then\n       sqlind^ := 0; // not null\n  end;\nend;\n\n{**\n   Set up parameter BigDecimal value\n   @param Index the target parameter index\n   @param Value the source value\n}\nprocedure TZASASQLDA.UpdateBigDecimal(const Index: Integer; Value: Extended);\nbegin\n  CheckIndex( Index);\n  SetFieldType( Index, DT_DOUBLE or 1, SizeOf( Double));\n  with FSQLDA.sqlvar[Index] do\n  begin\n    case sqlType and $FFFE of\n      DT_SMALLINT,\n      DT_UNSSMALLINT      : PSmallint(sqldata)^ := Trunc( Value);\n      DT_INT,\n      DT_UNSINT           : PInteger(sqldata)^ := Trunc( Value);\n      DT_FLOAT            : PSingle(sqldata)^ := Value;\n      DT_DOUBLE           : PDouble(sqldata)^ := Value;\n      DT_VARCHAR:\n                            begin\n                              PZASASQLSTRING( sqlData).length :=\n                                Length( FloatToStr( Value));\n                              {$IFDEF WITH_STRPLCOPY_DEPRECATED}AnsiStrings.{$ENDIF}StrPLCopy( @PZASASQLSTRING( sqlData).data[0],\n                                AnsiString(FloatToStr( Value)), sqllen-3);\n                            end;\n      DT_TINYINT,\n      DT_BIT              : PByte(sqldata)^ := Trunc( Value);\n      DT_BIGINT,\n      DT_UNSBIGINT        : PInt64(sqldata)^ := Trunc( Value);\n    else\n      CreateException( SUnsupportedParameterType);\n    end;\n    if (sqlind <> nil) then\n       sqlind^ := 0; // not null\n  end;\nend;\n\n{**\n   Set up parameter PAnsiChar value\n   @param Index the target parameter index\n   @param Value the source value\n}\nprocedure TZASASQLDA.UpdatePChar(const Index: Integer; Value: PChar);\nvar\n  BlobSize: Integer;\n  AnsiTmp: RawByteString;\nbegin\n  CheckIndex( Index);\n  AnsiTmp := FPlainDriver.ZPlainString(Value, FConSettings);\n  BlobSize := StrLen( Value);\n  if BlobSize < MinBLOBSize then\n    SetFieldType( Index, DT_VARCHAR or 1, MinBLOBSize - 1)\n  else\n    SetFieldType( Index, DT_LONGVARCHAR or 1, BlobSize);\n  with FSQLDA.sqlvar[Index] do\n  begin\n    case sqlType and $FFFE of\n      DT_VARCHAR:\n        begin\n          PZASASQLSTRING( sqlData).length := BlobSize;\n          {$IFDEF WITH_STRLCOPY_DEPRECATED}AnsiStrings.{$ENDIF}StrLCopy( @PZASASQLSTRING( sqlData).data[0],\n            PAnsiChar(AnsiTmp), BlobSize);\n        end;\n      DT_LONGVARCHAR:\n        begin\n          {$IFDEF WITH_STRLCOPY_DEPRECATED}AnsiStrings.{$ENDIF}StrLCopy( @PZASABlobStruct( sqlData).arr[0],\n            PAnsiChar(AnsiTmp), BlobSize);\n          PZASABlobStruct( sqlData).stored_len := BlobSize;\n          PZASABlobStruct( sqlData).untrunc_len := BlobSize;\n        end;\n    else\n      CreateException( SUnsupportedParameterType);\n    end;\n    if (sqlind <> nil) then\n       sqlind^ := 0; // not null\n  end;\nend;\n\n{**\n   Set up parameter String value\n   @param Index the target parameter index\n   @param Value the source value\n}\nprocedure TZASASQLDA.UpdateString(const Index: Integer; Value: RawByteString);\nvar\n  BlobSize: Integer;\nbegin\n  CheckIndex( Index);\n  BlobSize := Length( Value);\n  if BlobSize < MinBLOBSize then\n    SetFieldType( Index, DT_VARCHAR or 1, MinBLOBSize - 1)\n  else\n    SetFieldType( Index, DT_LONGVARCHAR or 1, BlobSize);\n  with FSQLDA.sqlvar[Index] do\n  begin\n    case sqlType and $FFFE of\n      DT_VARCHAR:\n        begin\n          PZASASQLSTRING( sqlData).length := BlobSize;\n          {$IFDEF WITH_STRPLCOPY_DEPRECATED}AnsiStrings.{$ENDIF}StrPLCopy( @PZASASQLSTRING( sqlData).data[0],\n            Value, BlobSize);\n        end;\n      DT_LONGVARCHAR:\n        begin\n          {$IFDEF WITH_STRPLCOPY_DEPRECATED}AnsiStrings.{$ENDIF}StrPLCopy( @PZASABlobStruct( sqlData).arr[0], Value,\n            BlobSize);\n          PZASABlobStruct( sqlData).stored_len := BlobSize;\n          PZASABlobStruct( sqlData).untrunc_len := BlobSize;\n        end;\n      else\n        CreateException( SUnsupportedParameterType);\n    end;\n    if (sqlind <> nil) then\n       sqlind^ := 0; // not null\n  end;\nend;\n\n{**\n   Set up parameter byte value\n   @param Index the target parameter index\n   @param Value the source value\n}\nprocedure TZASASQLDA.UpdateBytes(const Index: Integer; Value: TByteDynArray);\nvar\n  BlobSize: Integer;\nbegin\n  CheckIndex( Index);\n  BlobSize := Length( Value);\n  if BlobSize < MinBLOBSize then\n    SetFieldType( Index, DT_BINARY or 1, MinBLOBSize - 1)\n  else\n    SetFieldType( Index, DT_LONGBINARY or 1, BlobSize);\n  with FSQLDA.sqlvar[Index] do\n  begin\n    case sqlType and $FFFE of\n         DT_BINARY:\n                            begin\n                              PZASASQLSTRING( sqlData).length := BlobSize;\n                              Move( Value[0], PZASASQLSTRING( sqlData).data[0], BlobSize);\n                            end;\n         DT_LONGBINARY:\n                            begin\n                              Move( Value[0], PZASABlobStruct( sqlData).arr[0], BlobSize);\n                              PZASABlobStruct( sqlData).stored_len := BlobSize;\n                              PZASABlobStruct( sqlData).untrunc_len := BlobSize;\n                            end;\n    else\n      CreateException( SUnsupportedParameterType);\n    end;\n    if (sqlind <> nil) then\n       sqlind^ := 0; // not null\n  end;\nend;\n\n{**\n   Set up parameter Date value\n   @param Index the target parameter index\n   @param Value the source value\n}\nprocedure TZASASQLDA.UpdateDate(const Index: Integer; Value: TDateTime);\nbegin\n  UpdateDateTime(Index, Value);\n  FDeclType[Index].sqlType := DT_DATE;\nend;\n\n{**\n   Set up parameter Time value\n   @param Index the target parameter index\n   @param Value the source value\n}\nprocedure TZASASQLDA.UpdateTime(const Index: Integer; Value: TDateTime);\nbegin\n  UpdateDateTime(Index, Value);\n  FDeclType[Index].sqlType := DT_TIME;\nend;\n\n{**\n   Set up parameter DateTime value\n   @param Index the target parameter index\n   @param Value the source value\n}\nprocedure TZASASQLDA.UpdateDateTime(const Index: Integer;\n  Value: TDateTime);\nvar\n  y, m, d: word;\n  hr, min, sec, msec: word;\nbegin\n  CheckIndex( Index);\n  SetFieldType( Index, DT_TIMESTAMP_STRUCT or 1, SizeOf( TZASASQLDateTime));\n  with FSQLDA.sqlvar[Index] do\n  begin\n    case sqlType and $FFFE of\n         DT_TIMESTAMP_STRUCT:\n                            begin\n                              DecodeDate( Value, y, m, d);\n                              DecodeTime( Value, hr, min, sec, msec);\n                              PZASASQLDateTime( sqlData).Year := y;\n                              PZASASQLDateTime( sqlData).Month := m - 1;\n                              PZASASQLDateTime( sqlData).Day := d;\n                              PZASASQLDateTime( sqlData).Hour := hr;\n                              PZASASQLDateTime( sqlData).Minute := min;\n                              PZASASQLDateTime( sqlData).Second := sec;\n                              PZASASQLDateTime( sqlData).MicroSecond :=\n                                msec * 1000;\n                              PZASASQLDateTime( sqlData).Day_of_Week := 0;\n                              PZASASQLDateTime( sqlData).Day_of_Year := 0;\n                            end;\n    else\n      CreateException( SUnsupportedParameterType);\n    end;\n    if (sqlind <> nil) then\n       sqlind^ := 0; // not null\n  end;\n  FDeclType[Index].sqlType := DT_TIMESTAMP;\nend;\n\n{**\n   Set up parameter Timestamp value\n   @param Index the target parameter index\n   @param Value the source value\n}\nprocedure TZASASQLDA.UpdateTimestamp(const Index: Integer; Value: TDateTime);\nbegin\n  UpdateDateTime(Index, Value);\nend;\n\n{**\n   Set up parameter Type value\n   @param Index the target parameter index\n   @param Value the source value\n}\nprocedure TZASASQLDA.UpdateValue(const Index: Word; Value: Variant);\nbegin\n  case VarType(Value) of\n    varEmpty,\n    varNull       : UpdateNull( Index, True);\n    varSmallint   : UpdateShort( Index, Value);\n    varInteger    : UpdateInt( Index, Value);\n    varSingle     : UpdateFloat( Index, Value);\n    varDouble     : UpdateDouble( Index, Value);\n    varCurrency   : UpdateBigDecimal( Index, Value);\n    varDate       : UpdateDateTime( Index, Value);\n    varStrArg,\n    varString     : UpdateString(Index, AnsiString(Value));\n    varOleStr     : UpdateString(Index, FPlainDriver.ZPlainString(WideString(Value), FConSettings));\n    varBoolean    : UpdateBoolean( Index, Value);\n    varByte       : UpdateByte( Index, Value);\n    varInt64      : UpdateLong( Index, Value);\n    varShortInt   : UpdateByte( Index, Value);\n    varLongWord   : UpdateInt( Index, Value);\n    varWord       : UpdateShort( Index, Value);\n  else\n    if VarArrayDimCount( Value) = 1 then\n    begin\n      UpdateBytes( Index, VarArrayLock( Value));\n      VarArrayUnlock( Value);\n    end\n    else\n      CreateException( SUnsupportedParameterType);\n  end;\nend;\n\n{**\n   Write stream to blob field\n   @param Index an index field number\n   @param Stream the souse data stream\n}\nprocedure TZASASQLDA.WriteBlob(const Index: Integer; Stream: TStream;\n  const BlobType: TZSQLType);\nvar\n  BlobSize: Integer;\nbegin\n  CheckIndex( Index);\n  stream.Position := 0;\n  BlobSize := stream.Size;\n  case BlobType of\n    stAsciiStream:   SetFieldType( Index, DT_LONGVARCHAR or 1, BlobSize);\n    stUnicodeStream: SetFieldType( Index, DT_LONGNVARCHAR or 1, BlobSize);\n    stBinaryStream:  SetFieldType( Index, DT_LONGBINARY or 1, BlobSize);\n    else\n      CreateException( SUnsupportedParameterType);\n  end;\n  {case FSQLDA.sqlvar[Index].sqlType and $FFFE of\n      DT_LONGVARCHAR:\n        SetFieldType( Index, DT_LONGVARCHAR or 1, BlobSize);\n      DT_LONGBINARY:\n       SetFieldType( Index, DT_LONGBINARY or 1, BlobSize);\n      DT_LONGNVARCHAR:\n       SetFieldType( Index, DT_LONGNVARCHAR or 1, BlobSize);\n  end;\n  SetFieldType( Index, DT_LONGBINARY or 1, BlobSize);}\n  with FSQLDA.sqlvar[Index] do\n  begin\n    case sqlType and $FFFE of\n      DT_LONGVARCHAR, DT_LONGNVARCHAR,\n      DT_LONGBINARY:\n        begin\n          stream.ReadBuffer( PZASABlobStruct( sqlData).arr[0], BlobSize);\n          stream.Position := 0;\n          PZASABlobStruct( sqlData).stored_len := BlobSize;\n          PZASABlobStruct( sqlData).untrunc_len := BlobSize;\n        end;\n    else\n      CreateException( SUnsupportedParameterType);\n    end;\n    if (sqlind <> nil) then\n       sqlind^ := 0; // not null\n  end;\nend;\n\n{**\n   Indicate field null\n   @param Index the field index\n   @return true if fied value NULL overwise false\n}\nfunction TZASASQLDA.IsNull(const Index: Integer): Boolean;\nbegin\n  CheckIndex( Index);\n  with FSQLDA.sqlvar[Index] do\n    Result := Assigned( sqlind) and (sqlind^ < 0);\nend;\n\n{**\n   Indicate sqldata assigned\n   @param Index the field index\n   @return true if assigned field data\n}\nfunction TZASASQLDA.IsAssigned(const Index: Integer): Boolean;\nbegin\n  CheckIndex( Index);\n  with FSQLDA.sqlvar[Index] do\n    Result := Assigned( sqldata);\nend;\n\n{**\n   Return BigDecimal field value\n   @param Index the field index\n   @return the field BigDecimal value\n}\nfunction TZASASQLDA.GetBigDecimal(const Index: Integer): Extended;\nvar\n  s: RawByteString;\nbegin\n  CheckRange(Index);\n  with FSQLDA.sqlvar[Index] do\n  begin\n    Result := 0;\n    if (sqlind^ < 0) then\n       Exit;\n\n    case sqlType and $FFFE of\n      DT_SMALLINT    : Result := PSmallint(sqldata)^;\n      DT_UNSSMALLINT : Result := PWord(sqldata)^;\n      DT_INT         : Result := PInteger(sqldata)^;\n      DT_UNSINT      : Result := PLongWord(sqldata)^;\n      DT_FLOAT       : Result := PSingle(sqldata)^;\n      DT_DOUBLE      : Result := PDouble(sqldata)^;\n      DT_VARCHAR:\n        begin\n          {$IFDEF WITH_RAWBYTESTRING}\n          SetLength(s, PZASASQLSTRING( sqlData).length);\n          Move(PAnsiChar(@PZASASQLSTRING(sqlData).data[0])^, PAnsichar(s)^, PZASASQLSTRING( sqlData).length);\n          {$ELSE}\n          SetString(s, PAnsiChar(@PZASASQLSTRING(sqlData).data[0]), PZASASQLSTRING( sqlData).length);\n          {$ENDIF}\n          Result := ZStrToFloat(s);\n        end;\n      DT_TINYINT,\n      DT_BIT         : Result := PByte(sqldata)^;\n      DT_BIGINT,\n      DT_UNSBIGINT   : Result := PInt64(sqldata)^;\n    else\n      CreateException( Format( SErrorConvertionField,\n        [ GetFieldName(Index), ConvertASATypeToString( sqlType)]));\n    end;\n  end;\nend;\n\n{**\n   Return Boolean field value\n   @param Index the field index\n   @return the field boolean value\n}\nfunction TZASASQLDA.GetBoolean(const Index: Integer): Boolean;\nvar\n  s: RawByteString;\nbegin\n  CheckRange(Index);\n  with FSQLDA.sqlvar[Index] do\n  begin\n    Result := False;\n    if (sqlind^ < 0) then\n       Exit;\n\n    case sqlType and $FFFE of\n      DT_SMALLINT    : Result := PSmallint(sqldata)^ <> 0;\n      DT_UNSSMALLINT : Result := PWord(sqldata)^ <> 0;\n      DT_INT         : Result := PInteger(sqldata)^ <> 0;\n      DT_UNSINT      : Result := PLongWord(sqldata)^ <> 0;\n      DT_FLOAT       : Result := PSingle(sqldata)^ <> 0;\n      DT_DOUBLE      : Result := PDouble(sqldata)^ <> 0;\n      DT_VARCHAR:\n         begin\n           {$IFDEF WITH_RAWBYTESTRING}\n           SetLength(s, PZASASQLSTRING( sqlData).length);\n           Move(PAnsiChar(@PZASASQLSTRING(sqlData).data[0])^, PAnsiChar(S)^, PZASASQLSTRING( sqlData).length);\n           {$ELSE}\n           SetString(s, PAnsiChar(@PZASASQLSTRING(sqlData).data[0]), PZASASQLSTRING( sqlData).length);\n           {$ENDIF}\n           Result := StrToInt(String(s)) = 1;\n         end;\n      DT_TINYINT,\n      DT_BIT         : Result := PByte(sqldata)^ <> 0;\n      DT_BIGINT,\n      DT_UNSBIGINT   : Result := PInt64(sqldata)^ <> 0;\n    else\n      CreateException( Format( SErrorConvertionField,\n        [ GetFieldName(Index), ConvertASATypeToString( sqlType)]));\n    end;\n  end;\nend;\n\n{**\n   Return Byte field value\n   @param Index the field index\n   @return the field Byte value\n}\nfunction TZASASQLDA.GetByte(const Index: Integer): Byte;\nvar\n  s: RawByteString;\nbegin\n  CheckRange(Index);\n  with FSQLDA.sqlvar[Index] do\n  begin\n    Result := 0;\n    if (sqlind^ < 0) then\n       Exit;\n\n    case sqlType and $FFFE of\n      DT_SMALLINT    : Result := PSmallint(sqldata)^;\n      DT_UNSSMALLINT : Result := PWord(sqldata)^;\n      DT_INT         : Result := PInteger(sqldata)^;\n      DT_UNSINT      : Result := PLongWord(sqldata)^;\n      DT_FLOAT       : Result := Trunc( PSingle(sqldata)^);\n      DT_DOUBLE      : Result := Trunc( PDouble(sqldata)^);\n      DT_VARCHAR:\n         begin\n           {$IFDEF WITH_RAWBYTESTRING}\n           SetLength(s, PZASASQLSTRING( sqlData).length);\n           Move(PAnsiChar(@PZASASQLSTRING(sqlData).data[0])^, PAnsiChar(S)^, PZASASQLSTRING( sqlData).length);\n           {$ELSE}\n           SetString(s, PAnsiChar(@PZASASQLSTRING(sqlData).data[0]), PZASASQLSTRING( sqlData).length);\n           {$ENDIF}\n           Result := StrToInt(String(s));\n         end;\n      DT_TINYINT,\n      DT_BIT         : Result := PByte(sqldata)^;\n      DT_BIGINT,\n      DT_UNSBIGINT   : Result := PInt64(sqldata)^;\n    else\n      CreateException( Format( SErrorConvertionField,\n        [ GetFieldName(Index), ConvertASATypeToString( sqlType)]));\n    end;\n  end;\nend;\n\n{**\n   Return Bytes field value\n   @param Index the field index\n   @return the field Bytes value\n}\nfunction TZASASQLDA.GetBytes(const Index: Integer): TByteDynArray;\nbegin\n  CheckRange(Index);\n  with FSQLDA.sqlvar[Index] do\n  begin\n    Result := nil;\n    if (sqlind^ < 0) then\n       Exit;\n\n    case sqlType and $FFFE of\n         DT_BINARY:\n                            begin\n                              SetLength( Result, PZASASQLSTRING( sqlData).length);\n                              Move(PZASASQLSTRING(sqlData).data[0], Result[0], PZASASQLSTRING(sqlData).length);\n                            end;\n    else\n      CreateException( Format( SErrorConvertionField,\n        [ GetFieldName(Index), ConvertASATypeToString( sqlType)]));\n    end;\n  end;\nend;\n\n{**\n   Return Date field value\n   @param Index the field index\n   @return the field Date value\n}\nfunction TZASASQLDA.GetDate(const Index: Integer): TDateTime;\nbegin\n  Result := Trunc( GetTimestamp( Index));\nend;\n\n{**\n   Return Double field value\n   @param Index the field index\n   @return the field Double value\n}\nfunction TZASASQLDA.GetDouble(const Index: Integer): Double;\nvar\n  s: RawByteString;\nbegin\n  CheckRange(Index);\n  with FSQLDA.sqlvar[Index] do\n  begin\n    Result := 0;\n    if (sqlind^ < 0) then\n       Exit;\n\n    case sqlType and $FFFE of\n      DT_SMALLINT    : Result := PSmallint(sqldata)^;\n      DT_UNSSMALLINT : Result := PWord(sqldata)^;\n      DT_INT         : Result := PInteger(sqldata)^;\n      DT_UNSINT      : Result := PLongWord(sqldata)^;\n      DT_FLOAT       : Result := PSingle(sqldata)^;\n      DT_DOUBLE      : Result := PDouble(sqldata)^;\n      DT_VARCHAR:\n         begin\n           {$IFDEF WITH_RAWBYTESTRING}\n           SetLength(s, PZASASQLSTRING( sqlData).length);\n           Move(PAnsiChar(@PZASASQLSTRING(sqlData).data[0])^, PAnsiChar(S)^, PZASASQLSTRING( sqlData).length);\n           {$ELSE}\n           SetString(s, PAnsiChar(@PZASASQLSTRING(sqlData).data[0]), PZASASQLSTRING( sqlData).length);\n           {$ENDIF}\n           Result := ZStrToFloat(s);\n         end;\n      DT_TINYINT,\n      DT_BIT         : Result := PByte(sqldata)^;\n      DT_BIGINT,\n      DT_UNSBIGINT   : Result := PInt64(sqldata)^;\n    else\n      CreateException( Format( SErrorConvertionField,\n        [ GetFieldName(Index), ConvertASATypeToString( sqlType)]));\n    end;\n  end;\nend;\n\n{**\n   Return Float field value\n   @param Index the field index\n   @return the field Float value\n}\nfunction TZASASQLDA.GetFloat(const Index: Integer): Single;\nvar\n  s: RawByteString;\nbegin\n  CheckRange(Index);\n  with FSQLDA.sqlvar[Index] do\n  begin\n    Result := 0;\n    if (sqlind^ < 0) then\n       Exit;\n\n    case sqlType and $FFFE of\n      DT_SMALLINT    : Result := PSmallint(sqldata)^;\n      DT_UNSSMALLINT : Result := PWord(sqldata)^;\n      DT_INT         : Result := PInteger(sqldata)^;\n      DT_UNSINT      : Result := PLongWord(sqldata)^;\n      DT_FLOAT       : Result := PSingle(sqldata)^;\n      DT_DOUBLE      : Result := PDouble(sqldata)^;\n      DT_VARCHAR:\n         begin\n           {$IFDEF WITH_RAWBYTESTRING}\n           SetLength(s, PZASASQLSTRING( sqlData).length);\n           Move(PAnsiChar(@PZASASQLSTRING(sqlData).data[0])^, PAnsiChar(S)^, PZASASQLSTRING( sqlData).length);\n           {$ELSE}\n           SetString(s, PAnsiChar(@PZASASQLSTRING(sqlData).data[0]), PZASASQLSTRING( sqlData).length);\n           {$ENDIF}\n           Result := ZStrToFloat(s);\n         end;\n      DT_TINYINT,\n      DT_BIT         : Result := PByte(sqldata)^;\n      DT_BIGINT,\n      DT_UNSBIGINT   : Result := PInt64(sqldata)^;\n    else\n      CreateException( Format( SErrorConvertionField,\n        [ GetFieldName(Index), ConvertASATypeToString( sqlType)]));\n    end;\n  end;\nend;\n\n{**\n   Return Integer field value\n   @param Index the field index\n   @return the field Integer value\n}\nfunction TZASASQLDA.GetInt(const Index: Integer): Integer;\nvar\n  s: RawByteString;\nbegin\n  CheckRange(Index);\n  with FSQLDA.sqlvar[Index] do\n  begin\n    Result := 0;\n    if (sqlind^ < 0) then\n       Exit;\n\n    case sqlType and $FFFE of\n      DT_SMALLINT    : Result := PSmallint(sqldata)^;\n      DT_UNSSMALLINT : Result := PWord(sqldata)^;\n      DT_INT         : Result := PInteger(sqldata)^;\n      DT_UNSINT      : Result := PLongWord(sqldata)^;\n      DT_FLOAT       : Result := Trunc( PSingle(sqldata)^);\n      DT_DOUBLE      : Result := Trunc( PDouble(sqldata)^);\n      DT_VARCHAR:\n         begin\n           {$IFDEF WITH_RAWBYTESTRING}\n           SetLength(s, PZASASQLSTRING( sqlData).length);\n           Move(PAnsiChar(@PZASASQLSTRING(sqlData).data[0])^, PAnsiChar(S)^, PZASASQLSTRING( sqlData).length);\n           {$ELSE}\n           SetString(s, PAnsiChar(@PZASASQLSTRING(sqlData).data[0]), PZASASQLSTRING( sqlData).length);\n           {$ENDIF}\n           Result := StrToInt(String(s));\n         end;\n      DT_TINYINT,\n      DT_BIT         : Result := PByte(sqldata)^;\n      DT_BIGINT,\n      DT_UNSBIGINT   : Result := PInt64(sqldata)^;\n    else\n      CreateException( Format( SErrorConvertionField,\n        [ GetFieldName(Index), ConvertASATypeToString( sqlType)]));\n    end;\n  end;\nend;\n\n{**\n   Return Long field value\n   @param Index the field index\n   @return the field Long value\n}\nfunction TZASASQLDA.GetLong(const Index: Integer): Int64;\nvar\n  s: RawByteString;\nbegin\n  CheckRange(Index);\n  with FSQLDA.sqlvar[Index] do\n  begin\n    Result := 0;\n    if (sqlind^ < 0) then\n       Exit;\n\n    case sqlType and $FFFE of\n      DT_SMALLINT    : Result := PSmallint(sqldata)^;\n      DT_UNSSMALLINT : Result := PWord(sqldata)^;\n      DT_INT         : Result := PInteger(sqldata)^;\n      DT_UNSINT      : Result := PLongWord(sqldata)^;\n      DT_FLOAT       : Result := Trunc( PSingle(sqldata)^);\n      DT_DOUBLE      : Result := Trunc( PDouble(sqldata)^);\n      DT_VARCHAR:\n         begin\n           {$IFDEF WITH_RAWBYTESTRING}\n           SetLength(s, PZASASQLSTRING( sqlData).length);\n           Move(PAnsiChar(@PZASASQLSTRING(sqlData).data[0])^, PAnsiChar(S)^, PZASASQLSTRING( sqlData).length);\n           {$ELSE}\n           SetString(s, PAnsiChar(@PZASASQLSTRING(sqlData).data[0]), PZASASQLSTRING( sqlData).length);\n           {$ENDIF}\n           Result := StrToInt64(String(s));\n         end;\n      DT_TINYINT,\n      DT_BIT         : Result := PByte(sqldata)^;\n      DT_BIGINT,\n      DT_UNSBIGINT   : Result := PInt64(sqldata)^;\n    else\n      CreateException( Format( SErrorConvertionField,\n        [ GetFieldName(Index), ConvertASATypeToString( sqlType)]));\n    end;\n  end;\nend;\n\n{**\n   Return PAnsiChar field value\n   @param Index the field index\n   @return the field PAnsiChar value\n}\nfunction TZASASQLDA.GetPChar(const Index: Integer): PAnsiChar;\nbegin\n  CheckRange(Index);\n  with FSQLDA.sqlvar[Index] do\n  begin\n    Result := nil;\n    if (sqlind^ < 0) then\n       Exit;\n\n    case sqlType and $FFFE of\n         DT_VARCHAR:\n            begin\n              GetMem( Result, PZASASQLSTRING( sqlData).length + 1);\n              {$IFDEF WITH_STRLCOPY_DEPRECATED}AnsiStrings.{$ENDIF}StrLCopy( Result, @PZASASQLSTRING( sqlData).data[0], PZASASQLSTRING( sqlData).length);\n            end;\n    else\n      Result := PAnsiChar(GetString(Index));\n    end;\n  end;\nend;\n\n{**\n   Return String field value\n   @param Index the field index\n   @return the field String value\n}\nfunction TZASASQLDA.GetString(const Index: Integer): RawByteString;\nbegin\n  CheckRange(Index);\n  with FSQLDA.sqlvar[Index] do\n  begin\n    Result := '';\n    if (sqlind^ < 0) then\n       Exit;\n\n    case sqlType and $FFFE of\n      DT_SMALLINT    : Result := RawByteString(IntToStr( PSmallint(sqldata)^));\n      DT_UNSSMALLINT : Result := RawByteString(IntToStr( PWord(sqldata)^));\n      DT_INT         : Result := RawByteString(IntToStr( PInteger(sqldata)^));\n      DT_UNSINT      : Result := RawByteString(IntToStr( PLongWord(sqldata)^));\n      DT_FLOAT       : Result := RawByteString(FloatToStr( PSingle(sqldata)^));\n      DT_DOUBLE      : Result := RawByteString(FloatToStr( PDouble(sqldata)^));\n      DT_VARCHAR     :\n         begin\n           {$IFDEF WITH_RAWBYTESTRING}\n           SetLength(Result, PZASASQLSTRING( sqlData).length);\n           Move(PAnsiChar(@PZASASQLSTRING(sqlData).data[0])^, PAnsiChar(Result)^, PZASASQLSTRING( sqlData).length);\n           {$ELSE}\n           SetString(Result, PAnsiChar(@PZASASQLSTRING(sqlData).data[0]), PZASASQLSTRING( sqlData).length);\n           {$ENDIF}\n         end;\n      DT_LONGVARCHAR : ReadBlobToString( Index, Result);\n      DT_TIMESTAMP_STRUCT : Result := RawByteString(DateToStr( GetTimestamp( Index)));\n      DT_TINYINT     : Result := RawByteString(IntToStr( PByte(sqldata)^));\n      DT_BIT         : Result := RawByteString(BoolToStr( ( PByte(sqldata)^ = 1), True));\n      DT_BIGINT,\n      DT_UNSBIGINT   : Result := RawByteString(IntToStr( PInt64(sqldata)^));\n    else\n      CreateException( Format( SErrorConvertionField,\n        [ GetFieldName(Index), ConvertASATypeToString( sqlType)]));\n    end;\n  end;\nend;\n\n{**\n   Return Short field value\n   @param Index the field index\n   @return the field Short value\n}\nfunction TZASASQLDA.GetShort(const Index: Integer): SmallInt;\nvar\n  s: RawByteString;\nbegin\n  CheckRange(Index);\n  with FSQLDA.sqlvar[Index] do\n  begin\n    Result := 0;\n    if (sqlind^ < 0) then\n       Exit;\n\n    case sqlType and $FFFE of\n      DT_SMALLINT    : Result := PSmallint(sqldata)^;\n      DT_UNSSMALLINT : Result := PWord(sqldata)^;\n      DT_INT         : Result := PInteger(sqldata)^;\n//      DT_UNSINT      : Result := PLongWord(sqldata)^;\n      DT_FLOAT       : Result := Trunc( PSingle(sqldata)^);\n      DT_DOUBLE      : Result := Trunc( PDouble(sqldata)^);\n      DT_VARCHAR:\n         begin\n           {$IFDEF WITH_RAWBYTESTRING}\n           SetLength(s, PZASASQLSTRING( sqlData).length);\n           Move(PAnsiChar(@PZASASQLSTRING(sqlData).data[0])^, PAnsiChar(S)^, PZASASQLSTRING( sqlData).length);\n           {$ELSE}\n           SetString(s, PAnsiChar(@PZASASQLSTRING(sqlData).data[0]), PZASASQLSTRING( sqlData).length);\n           {$ENDIF}\n           Result := StrToInt(String(s));\n         end;\n      DT_TINYINT,\n      DT_BIT         : Result := PByte(sqldata)^;\n      DT_BIGINT,\n      DT_UNSBIGINT   : Result := PInt64(sqldata)^;\n    else\n      CreateException( Format( SErrorConvertionField,\n        [ GetFieldName(Index), ConvertASATypeToString( sqlType)]));\n    end;\n  end;\nend;\n\n{**\n   Return Time field value\n   @param Index the field index\n   @return the field Time value\n}\nfunction TZASASQLDA.GetTime(const Index: Integer): TDateTime;\nbegin\n  Result := Frac( GetTimestamp( Index));\nend;\n\n{**\n   Return Timestamp field value\n   @param Index the field index\n   @return the field Timestamp value\n}\nfunction TZASASQLDA.GetTimestamp(const Index: Integer): TDateTime;\nbegin\n  CheckRange( Index);\n  with FSQLDA.sqlvar[Index] do\n  begin\n    Result := 0;\n    if (sqlind^ < 0) then\n       Exit;\n\n    case sqlType and $FFFE of\n         DT_TIMESTAMP_STRUCT:\n            begin\n              Result := EncodeDate( PZASASQLDateTime( sqlData).Year,\n                                    PZASASQLDateTime( sqlData).Month + 1,\n                                    PZASASQLDateTime( sqlData).Day) +\n                                    EncodeTime( PZASASQLDateTime( sqlData).Hour,\n                                    PZASASQLDateTime( sqlData).Minute,\n                                    PZASASQLDateTime( sqlData).Second,\n                                    PZASASQLDateTime( sqlData).MicroSecond div 1000);\n            end;\n    else\n      CreateException( Format( SErrorConvertionField,\n        [ GetFieldName(Index), ConvertASATypeToString( sqlType)]));\n    end;\n  end;\nend;\n\n{**\n   Return Variant field value\n   @param Index the field index\n   @return the field Variant value\n}\nfunction TZASASQLDA.GetValue(const Index: Word): Variant;\nvar\n  s: RawByteString;\nbegin\n  CheckRange(Index);\n  with FSQLDA.sqlvar[Index] do\n  begin\n    VarClear(Result);\n    if (sqlind^ < 0) then\n       Exit;\n\n    case sqlType and $FFFE of\n      DT_SMALLINT    : Result := PSmallint(sqldata)^;\n      DT_UNSSMALLINT : Result := PWord(sqldata)^;\n      DT_INT         : Result := PInteger(sqldata)^;\n//      DT_UNSINT      : Result := PLongWord(sqldata)^;\n      DT_FLOAT       : Result := PSingle(sqldata)^;\n      DT_DOUBLE      : Result := PDouble(sqldata)^;\n      DT_VARCHAR:\n         begin\n           {$IFDEF WITH_RAWBYTESTRING}\n           SetLength(s, PZASASQLSTRING( sqlData).length);\n           Move(PAnsiChar(@PZASASQLSTRING(sqlData).data[0])^, PAnsiChar(S)^, PZASASQLSTRING( sqlData).length);\n           {$ELSE}\n           SetString(s, PAnsiChar(@PZASASQLSTRING(sqlData).data[0]), PZASASQLSTRING( sqlData).length);\n           {$ENDIF}\n           Result := s;\n         end;\n      DT_LONGVARCHAR,\n      DT_LONGBINARY  : ReadBlobToVariant(Index, Result);\n      DT_TIMESTAMP_STRUCT : Result := GetTimeStamp( Index);\n      DT_TINYINT     : Result := PByte(sqldata)^;\n      DT_BIT         : Result := Boolean( PByte(sqldata)^);\n      DT_BIGINT,\n      DT_UNSBIGINT   : Result := PInt64(sqldata)^;\n    else\n      CreateException( Format( SErrorConvertionField,\n        [ GetFieldName(Index), ConvertASATypeToString( sqlType)]));\n    end;\n  end;\nend;\n\nprocedure TZASASQLDA.ReadBlob(const Index: Word; Buffer: Pointer;\n  Length: LongWord);\nvar\n  TempSQLDA: PASASQLDA;\n  Offs, Rd: LongWord;\nconst\n  BlockSize = 32700;\nbegin\n  with FSQLDA.sqlvar[Index] do\n  begin\n    if ( ( sqlType and $FFFE = DT_LONGVARCHAR) or\n         ( sqlType and $FFFE = DT_LONGNVARCHAR) or\n         ( sqlType and $FFFE = DT_LONGBINARY)) and\n       ( PZASABlobStruct( sqlData).array_len > 0) then\n    begin\n      Assert( PZASABlobStruct( sqlData).array_len = PZASABlobStruct( sqlData).untrunc_len,\n        'Blob Record is not correctly initialized');\n      if PZASABlobStruct( sqlData).array_len <> Length then\n        CreateException( 'Could''nt complete BLOB-Read');\n      move( PZASABlobStruct( sqlData).arr[0], PAnsiChar( Buffer)[0], PZASABlobStruct( sqlData).array_len);\n    end\n    else\n    begin\n      TempSQLDA := FPlainDriver.db_alloc_sqlda( 1);\n      if not Assigned( TempSQLDA) then\n        CreateException( 'Not enough memory for SQLDA');\n      try\n        with TempSQLDA.sqlvar[ 0] do\n        begin\n          case Self.GetFieldSqlType(Index) of\n            stAsciiStream:\n              SetFieldType(TempSQLDA, 0, DT_LONGVARCHAR, Min( BlockSize, Length));\n            stUnicodeStream:\n              SetFieldType(TempSQLDA, 0, DT_LONGNVARCHAR, Min( BlockSize, Length));\n            stBinaryStream:\n              SetFieldType(TempSQLDA, 0, DT_LONGBINARY, Min( BlockSize, Length));\n            else\n              sqlType := DT_FIXCHAR;\n          end;\n          sqlname.length := 0;\n          sqlname.data[0] := #0;\n          TempSQLDA.sqld := TempSQLDA.sqln;\n\n          Offs := 0;\n          Rd := 0;\n\n          while True do\n          begin\n            FPlainDriver.db_get_data(FHandle, PAnsiChar(FCursorName), Index + 1, Offs, TempSQLDA);\n            CheckASAError( FPlainDriver, FHandle, lcOther);\n            if ( sqlind^ < 0 ) then\n              break;\n            Inc( Rd, PZASABlobStruct( sqlData)^.stored_len);\n            if Offs = 0 then ReallocMem(Buffer, PZASABlobStruct( sqlData)^.untrunc_len);\n            Move((PZASABlobStruct( sqlData)^.arr[0]), (PAnsiChar(Buffer)+Offs)^, PZASABlobStruct( sqlData)^.stored_len);\n            if ( sqlind^ = 0 ) or ( RD = Length) then\n              break;\n            Inc( Offs, PZASABlobStruct( sqlData)^.stored_len);\n            sqllen := Min( BlockSize, Length-Rd);\n          end;\n          if Rd <> Length then\n            CreateException( 'Could''nt complete BLOB-Read');\n\n          DriverManager.LogMessage( lcExecute, FPlainDriver.GetProtocol,\n            Format( 'GET DATA for Column: %s', [ GetFieldName(Index)]));\n          FreeMem(sqlData, SizeOf(TZASABlobStruct)+Min( BlockSize, Length));\n          FPlainDriver.db_free_sqlda( TempSQLDA);\n          TempSQLDA := nil;\n        end;\n      except\n        if Assigned( TempSQLDA) then\n          FPlainDriver.db_free_sqlda( TempSQLDA);\n        raise;\n      end;\n    end;\n  end;\nend;\n\n{**\n   Read blob data to Buffer\n   @param Index an filed index\n   @param Str destination string\n}\nprocedure TZASASQLDA.ReadBlobToMem(const Index: Word; var Buffer: Pointer;\n  var Length: LongWord);\nbegin\n  CheckRange(Index);\n  with FSQLDA.sqlvar[Index] do\n  begin\n    Buffer := nil;\n    Length := 0;\n    if (sqlind^ < 0) then\n       Exit;\n\n    if ( ( sqlType and $FFFE = DT_LONGVARCHAR) or\n         ( sqlType and $FFFE = DT_LONGBINARY)) then\n    begin\n      Length := PZASABlobStruct( sqlData).untrunc_len;\n      GetMem( Buffer, Length);\n      ReadBlob( Index, Buffer, Length);\n    end\n    else\n      CreateException( Format( SErrorConvertionField,\n        [ GetFieldName(Index), ConvertASATypeToString( sqlType)]));\n  end;\nend;\n\n{**\n   Read blob data to string\n   @param Index an filed index\n   @param Str destination string\n}\nprocedure TZASASQLDA.ReadBlobToString(const Index: Word; var Str: RawByteString);\nbegin\n  CheckRange(Index);\n  with FSQLDA.sqlvar[Index] do\n  begin\n    Str := '';\n    if (sqlind^ < 0) then\n       Exit;\n\n    if sqlType and $FFFE = DT_LONGVARCHAR then\n    begin\n      SetLength( Str, PZASABlobStruct( sqlData).untrunc_len);\n      ReadBlob(Index, PAnsiChar(Str), Length(Str));\n    end\n    else\n      CreateException( Format( SErrorConvertionField,\n        [ GetFieldName(Index), ConvertASATypeToString( sqlType)]));\n  end;\nend;\n\n{**\n   Read blob data to stream\n   @param Index an filed index\n   @param Stream destination stream object\n}\nprocedure TZASASQLDA.ReadBlobToStream(const Index: Word; Stream: TStream);\nbegin\n  CheckRange(Index);\n  with FSQLDA.sqlvar[Index] do\n  begin\n    Stream.Size := 0;\n    if (sqlind^ < 0) then\n       Exit;\n\n    if ( ( sqlType and $FFFE = DT_LONGVARCHAR) or\n         ( sqlType and $FFFE = DT_LONGBINARY)) and\n      ( Stream is TMemoryStream) then\n    begin\n      Stream.Size := PZASABlobStruct( sqlData).untrunc_len;\n      ReadBlob( Index, TMemoryStream( Stream).Memory, Stream.Size);\n    end\n    else\n      CreateException( Format( SErrorConvertionField,\n        [ GetFieldName(Index), ConvertASATypeToString( sqlType)]));\n  end;\nend;\n\n{**\n   Read blob data to variant value\n   @param Index an filed index\n   @param Value destination variant value\n}\nprocedure TZASASQLDA.ReadBlobToVariant(const Index: Word;\n  var Value: Variant);\nvar\n  PData: Pointer;\nbegin\n  CheckRange(Index);\n  with FSQLDA.sqlvar[Index] do\n  begin\n    Value := Null;\n    if (sqlind^ < 0) then\n       Exit;\n\n    if ( ( sqlType and $FFFE = DT_LONGVARCHAR) or\n         ( sqlType and $FFFE = DT_LONGBINARY)) then\n    begin\n      Value := VarArrayCreate( [ 0, PZASABlobStruct( sqlData).untrunc_len-1], varByte);\n      PData := VarArrayLock( Value);\n      try\n        ReadBlob( Index, PData, PZASABlobStruct( sqlData).untrunc_len);\n      finally\n        VarArrayUnlock( Value);\n      end;\n    end\n    else\n      CreateException( Format( SErrorConvertionField,\n        [ GetFieldName(Index), ConvertASATypeToString( sqlType)]));\n  end;\nend;\n\n{**\n  Converts a ASA native types into ZDBC SQL types.\n  @param SQLType Field of TASASQLVar structure.\n  @return a SQL undepended type.\n}\nfunction ConvertASATypeToSQLType(const SQLType: SmallInt;\n  const CtrlsCPType: TZControlsCodePage): TZSQLType;\nbegin\n  case SQLType and $FFFE of\n    DT_NOTYPE:\n      Result := stUnknown;\n    DT_SMALLINT:\n      Result := stShort;\n    DT_INT:\n      Result := stInteger;\n    DT_DECIMAL:\n      Result := stDouble; //BCD Fields not supported\n    DT_FLOAT:\n      Result := stFloat;\n    DT_DOUBLE:\n      Result := stDouble;\n    DT_DATE:\n      Result := stDate;\n    DT_VARIABLE, DT_STRING, DT_FIXCHAR, DT_VARCHAR, DT_NSTRING, DT_NFIXCHAR, DT_NVARCHAR:\n      if (CtrlsCPType = cCP_UTF16) then\n        Result := stUnicodeString\n      else\n        Result := stString;\n    DT_LONGVARCHAR, DT_LONGNVARCHAR:\n      if (CtrlsCPType = cCP_UTF16) then\n        Result := stUnicodeStream\n      else\n        Result := stAsciiStream;\n    DT_TIME:\n      Result := stTime;\n    DT_TIMESTAMP:\n      Result := stTimestamp;\n    DT_TIMESTAMP_STRUCT:\n      Result := stTimestamp;\n    DT_BINARY:\n      Result := stBytes;\n    DT_LONGBINARY:\n      Result := stBinaryStream;\n    DT_TINYINT:\n      Result := stByte;\n    DT_BIGINT:\n      Result := stLong;\n    DT_UNSINT:\n      Result := stInteger;\n    DT_UNSSMALLINT:\n      Result := stShort;\n    DT_UNSBIGINT:\n      Result := stLong;\n    DT_BIT:\n      Result := stBoolean;\n  else\n    Result := stUnknown;\n  end;\nend;\n\n{**\n  Converts a ASA native type into String.\n  @param SQLType Field of TASASQLVar structure.\n  @return type description.\n}\nfunction ConvertASATypeToString( SQLType: SmallInt): String;\nbegin\n  case SQLType and $FFFE of\n    DT_SMALLINT:\n      Result := 'DT_SMALLINT';\n    DT_INT:\n      Result := 'DT_INT';\n    DT_DECIMAL:\n      Result := 'DT_DECIMAL'; //BCD Fields not supported\n    DT_FLOAT:\n      Result := 'DT_FLOAT';\n    DT_DOUBLE:\n      Result := 'DT_DOUBLE';\n    DT_DATE:\n      Result := 'DT_DATE';\n    DT_VARIABLE:\n      Result := 'DT_VARIABLE';\n    DT_STRING:\n      Result := 'DT_STRING';\n    DT_FIXCHAR:\n      Result := 'DT_FIXCHAR';\n    DT_VARCHAR:\n      Result := 'DT_VARCHAR';\n    DT_LONGVARCHAR:\n      Result := 'DT_LONGVARCHAR';\n    DT_TIME:\n      Result := 'DT_TIME';\n    DT_TIMESTAMP:\n      Result := 'DT_TIMESTAMP';\n    DT_TIMESTAMP_STRUCT:\n      Result := 'DT_TIMESTAMP_STRUCT';\n    DT_BINARY:\n      Result := 'DT_BINARY';\n    DT_LONGBINARY:\n      Result := 'DT_LONGBINARY';\n    DT_TINYINT:\n      Result := 'DT_TINYINT';\n    DT_BIGINT:\n      Result := 'DT_BIGINT';\n    DT_UNSINT:\n      Result := 'DT_UNSINT';\n    DT_UNSSMALLINT:\n      Result := 'DT_UNSSMALLINT';\n    DT_UNSBIGINT:\n      Result := 'DT_UNSBIGINT';\n    DT_BIT:\n      Result := 'DT_BIT';\n    DT_NSTRING:\n      Result := 'DT_NSTRING';\n    DT_NFIXCHAR:\n      Result := 'DT_NFIXCHAR';\n    DT_NVARCHAR:\n      Result := 'DT_NVARCHAR';\n    DT_LONGNVARCHAR:\n      Result := 'DT_LONGNVARCHAR';\n  else\n    Result := 'Unknown';\n  end;\nend;\n\n{**\n  Converts an ODBC native types into ZDBC SQL types.\n  @param FieldType dblibc native field type.\n  @return a SQL undepended type.\n}\nfunction ConvertASAJDBCToSqlType(const FieldType: SmallInt;\n  CtrlsCPType: TZControlsCodePage): TZSQLType;\nbegin\n  case FieldType of\n    1, 12, -8, -9:\n      if (CtrlsCPType = cCP_UTF16) then\n        Result := stUnicodeString\n      else\n        Result := stString;\n    -7: Result := stBoolean;\n    -6: Result := stByte;\n    5: Result := stShort;\n    4: Result := stInteger;\n    -5 : Result := stLong;\n    6, 7, 8: Result := stDouble;\n    2, 3: Result := stDouble;  //BCD Feld\n    11, 93: Result := stTimestamp;\n    -1, -10:\n      if (CtrlsCPType = cCP_UTF16) then\n        Result := stUnicodeStream\n      else\n        Result := stAsciiStream;\n    -4, -11, 1111: Result := stBinaryStream;\n    -3, -2: Result := stBytes;\n    92: Result := stTime;\n    91: Result := stDate;\n  else\n    Result := stUnknown;\n  end;\nend;\n{\nprocedure TSQLTimeStampToASADateTime( DT: TSQLTimeStamp; const ASADT: PZASASQLDateTime);\nbegin\n  ASADT.Year := DT.Year;\n  ASADT.Month := DT.Month - 1;\n  ASADT.Day := DT.Day;\n  ASADT.Hour := DT.Hour;\n  ASADT.Minute := DT.Minute;\n  ASADT.Second := DT.Second;\n  ASADT.MicroSecond := DT.Fractions * 10;\n  ASADT.Day_of_Week := 0;\n  ASADT.Day_of_Year := 0;\nend;\n\nfunction ASADateTimeToSQLTimeStamp( ASADT: PZASASQLDateTime): TSQLTimeStamp;\nbegin\n  DT.Year := ASADT.Year;\n  DT.Month := ASADT.Month + 1;\n  DT.Day := ASADT.Day;\n  DT.Hour := ASADT.Hour;\n  DT.Minute := ASADT.Minute;\n  DT.Second := ASADT.Second;\n  DT.Fractions := ASADT.MicroSecond div 10;\nend;\n}\n{**\n  Checks for possible sql errors.\n  @param PlainDriver a MySQL plain driver.\n  @param Handle a MySQL connection handle.\n  @param LogCategory a logging category.\n  @param LogMessage a logging message.\n}\nprocedure CheckASAError( PlainDriver: IZASAPlainDriver;\n  Handle: PZASASQLCA; LogCategory: TZLoggingCategory; LogMessage: string = '';\n  SupressExceptionID: Integer = 0);\nvar\n  ErrorBuf: array[0..1024] of AnsiChar;\n  ErrorMessage: string;\nbegin\n  if Handle.SqlCode < SQLE_NOERROR then\n  begin\n    ErrorMessage := String(PlainDriver.sqlError_Message( Handle, ErrorBuf, SizeOf( ErrorBuf)));\n    //SyntaxError Position in SQLCount\n    if not (SupressExceptionID = Handle.SqlCode ) then\n    begin\n      DriverManager.LogError( LogCategory, PlainDriver.GetProtocol, LogMessage,\n        Handle.SqlCode, ErrorMessage);\n\n      raise EZSQLException.CreateWithCode( Handle.SqlCode,\n        Format(SSQLError1, [ErrorMessage]));\n    end;\n  end;\nend;\n\n{**\n  Create CachedResultSet with using TZCachedResultSet and return it.\n  @param SQL a sql query command\n  @param Statement a zeos statement object\n  @param NativeResultSet a native result set\n  @return cached ResultSet\n}\nfunction GetCachedResultSet(SQL: string;\n  Statement: IZStatement; NativeResultSet: IZResultSet): IZResultSet;\nvar\n  CachedResultSet: TZCachedResultSet;\nbegin\n  if (Statement.GetResultSetConcurrency <> rcReadOnly)\n    or (Statement.GetResultSetType <> rtForwardOnly) then\n  begin\n    CachedResultSet := TZCachedResultSet.Create( NativeResultSet, SQL, nil,\n      Statement.GetConnection.GetConSettings);\n    CachedResultSet.SetResolver( TZASACachedResolver.Create(\n      Statement, NativeResultSet.GetMetadata));\n    CachedResultSet.SetConcurrency( Statement.GetResultSetConcurrency);\n    Result := CachedResultSet;\n  end\n  else\n    Result := NativeResultSet;\nend;\n\nprocedure DescribeCursor( FASAConnection: IZASAConnection; FSQLData: IZASASQLDA;\n  Cursor: AnsiString; SQL: String);\nbegin\n  FSQLData.AllocateSQLDA( StdVars);\n  with FASAConnection do\n  begin\n    GetPlainDriver.db_describe_cursor(GetDBHandle, PAnsiChar(Cursor), FSQLData.GetData, SQL_DESCRIBE_OUTPUT);\n    ZDbcASAUtils.CheckASAError( GetPlainDriver, GetDBHandle, lcExecute, SQL);\n    if FSQLData.GetData^.sqld <= 0 then\n      raise EZSQLException.Create( SCanNotRetrieveResultSetData)\n    else if ( FSQLData.GetData^.sqld > FSQLData.GetData^.sqln) then\n    begin\n      FSQLData.AllocateSQLDA( FSQLData.GetData^.sqld);\n      GetPlainDriver.db_describe_cursor(GetDBHandle, PAnsiChar(Cursor), FSQLData.GetData, SQL_DESCRIBE_OUTPUT);\n       ZDbcASAUtils.CheckASAError(GetPlainDriver, GetDBHandle, lcExecute, SQL);\n    end;\n    FSQLData.InitFields;\n  end;\nend;\n\nprocedure ASAPrepare( FASAConnection: IZASAConnection; FSQLData, FParamsSQLData: IZASASQLDA;\n   const SQL: RawByteString; const LogSQL: String; StmtNum: PSmallInt; var FPrepared, FMoreResults: Boolean);\nbegin\n  with FASAConnection do\n  begin\n    if FPrepared then\n    begin\n      FParamsSQLData.AllocateSQLDA( StdVars);\n      FSQLData.AllocateSQLDA( StdVars);\n      if StmtNum^ <> 0 then\n      begin\n        GetPlainDriver.db_dropstmt( GetDBHandle, nil, nil, StmtNum);\n        StmtNum^ := 0;\n      end;\n    end;\n    try\n      GetPlainDriver.db_prepare_describe( GetDBHandle, nil, StmtNum,\n            PAnsiChar(SQL), FParamsSQLData.GetData, SQL_PREPARE_DESCRIBE_STMTNUM +\n            SQL_PREPARE_DESCRIBE_INPUT + SQL_PREPARE_DESCRIBE_VARRESULT, 0);\n      ZDbcASAUtils.CheckASAError(GetPlainDriver, GetDBHandle, lcExecute, LogSQL);\n\n      FMoreResults := GetDBHandle.sqlerrd[2] = 0;\n\n      if FParamsSQLData.GetData^.sqld > FParamsSQLData.GetData^.sqln then\n      begin\n        FParamsSQLData.AllocateSQLDA( FParamsSQLData.GetData^.sqld);\n        GetPlainDriver.db_describe( GetDBHandle, nil, StmtNum,\n          FParamsSQLData.GetData, SQL_DESCRIBE_INPUT);\n        ZDbcASAUtils.CheckASAError( GetPlainDriver, GetDBHandle, lcExecute, LogSQL);\n      end;\n\n      if not FMoreResults then\n      begin\n        GetPlainDriver.db_describe( GetDBHandle, nil, StmtNum,\n          FSQLData.GetData, SQL_DESCRIBE_OUTPUT);\n        ZDbcASAUtils.CheckASAError( GetPlainDriver, GetDBHandle, lcExecute, LogSQL);\n        if FSQLData.GetData^.sqld > FSQLData.GetData^.sqln then\n        begin\n          FSQLData.AllocateSQLDA( FSQLData.GetData^.sqld);\n          GetPlainDriver.db_describe( GetDBHandle, nil, StmtNum,\n            FSQLData.GetData, SQL_DESCRIBE_OUTPUT);\n          ZDbcASAUtils.CheckASAError( GetPlainDriver, GetDBHandle, lcExecute, LogSQL);\n        end;\n        FSQLData.InitFields;\n      end;\n\n      FPrepared := true;\n      { Logging SQL Command }\n      DriverManager.LogMessage( lcExecute, GetPlainDriver.GetProtocol,\n        'Prepare: '+ LogSQL);\n    except\n      on E: Exception do\n      begin\n        if StmtNum^ <> 0 then\n          GetPlainDriver.db_dropstmt( GetDBHandle, nil, nil, StmtNum);\n        raise;\n      end;\n    end;\n  end;\nend;\n\nprocedure PrepareParameters( PlainDriver: IZASAPlainDriver;\n  InParamValues: TZVariantDynArray; InParamTypes: TZSQLTypeArray;\n  InParamCount: Integer; ParamSqlData: IZASASQLDA; ConSettings: PZConSettings);\nvar\n  i: Integer;\n  TempBlob: IZBlob;\n  TempStream: TStream;\nbegin\n  if InParamCount <> ParamSqlData.GetFieldCount then\n    raise EZSQLException.Create( SInvalidInputParameterCount);\n  for i := 0 to ParamSqlData.GetFieldCount-1 do\n    if DefVarManager.IsNull( InParamValues[i])then\n      ParamSqlData.UpdateNull( i, True)\n    else\n      case InParamTypes[i] of\n        stBoolean:\n          ParamSqlData.UpdateBoolean( i,\n            SoftVarManager.GetAsBoolean( InParamValues[i]));\n        stByte:\n          ParamSqlData.UpdateByte( i,\n            SoftVarManager.GetAsInteger( InParamValues[i]));\n        stShort:\n          ParamSqlData.UpdateShort( i,\n            SoftVarManager.GetAsInteger( InParamValues[i]));\n        stInteger:\n          ParamSqlData.UpdateInt( i,\n            SoftVarManager.GetAsInteger( InParamValues[i]));\n        stLong:\n          ParamSqlData.UpdateLong( i,\n            SoftVarManager.GetAsInteger( InParamValues[i]));\n        stFloat:\n          ParamSqlData.UpdateFloat( i,\n            SoftVarManager.GetAsFloat( InParamValues[i]));\n        stDouble:\n          ParamSqlData.UpdateDouble( i,\n            SoftVarManager.GetAsFloat( InParamValues[i]));\n        stBigDecimal:\n          ParamSqlData.UpdateBigDecimal( i,\n            SoftVarManager.GetAsFloat( InParamValues[i]));\n        stString:\n          ParamSqlData.UpdateString( i,\n            PlainDriver.ZPlainString(SoftVarManager.GetAsString( InParamValues[i]), ConSettings));\n        stUnicodeString:\n          ParamSqlData.UpdateString( i,\n            PlainDriver.ZPlainString(SoftVarManager.GetAsUnicodeString( InParamValues[i]), ConSettings));\n        stBytes:\n          ParamSqlData.UpdateBytes( i, SoftVarManager.GetAsBytes( InParamValues[i]));\n        stDate:\n          ParamSqlData.UpdateDate( i,\n            SoftVarManager.GetAsDateTime( InParamValues[i]));\n        stTime:\n          ParamSqlData.UpdateTime( i,\n            SoftVarManager.GetAsDateTime( InParamValues[i]));\n        stTimestamp:\n          ParamSqlData.UpdateTimestamp( i,\n            SoftVarManager.GetAsDateTime( InParamValues[i]));\n        stAsciiStream,\n        stUnicodeStream,\n        stBinaryStream:\n          begin\n            TempBlob := DefVarManager.GetAsInterface(InParamValues[I]) as IZBlob;\n            if not TempBlob.IsEmpty then\n            begin\n              if (InParamTypes[i] in [stUnicodeStream, stAsciiStream]) then\n                TempStream := TStringStream.Create(GetValidatedAnsiStringFromBuffer(TempBlob.GetBuffer,\n                  TempBlob.Length, TempBlob.WasDecoded, ConSettings))\n              else\n                TempStream := TempBlob.GetStream;\n              if Assigned(TempStream) then\n              begin\n                ParamSqlData.WriteBlob(I, TempStream, InParamTypes[i]);\n                TempStream.Free;\n              end;\n            end;\n          end;\n        else\n          raise EZASAConvertError.Create( SUnsupportedParameterType);\n    end;\nend;\n\n{**\n   Generate specific length random string and return it\n   @param Len a length result string\n   @return random string\n}\nfunction RandomString( Len: integer): string;\nbegin\n  Result := '';\n  while Length( Result) < Len do\n    Result := Result + IntToStr( Trunc( Random( High( Integer))));\n  if Length( Result) > Len then\n    Result := Copy( Result, 1, Len);\nend;\n\nend.\n\n"
  },
  {
    "path": "lib/zeosdbo/src/dbc/ZDbcAdo.pas",
    "content": "{*********************************************************}\n{                                                         }\n{                 Zeos Database Objects                   }\n{               ADO Connectivity Classes                  }\n{                                                         }\n{        Originally written by Janos Fegyverneki          }\n{                                                         }\n{*********************************************************}\n\n{@********************************************************}\n{    Copyright (c) 1999-2012 Zeos Development Group       }\n{                                                         }\n{ License Agreement:                                      }\n{                                                         }\n{ This library is distributed in the hope that it will be }\n{ useful, but WITHOUT ANY WARRANTY; without even the      }\n{ implied warranty of MERCHANTABILITY or FITNESS FOR      }\n{ A PARTICULAR PURPOSE.  See the GNU Lesser General       }\n{ Public License for more details.                        }\n{                                                         }\n{ The source code of the ZEOS Libraries and packages are  }\n{ distributed under the Library GNU General Public        }\n{ License (see the file COPYING / COPYING.ZEOS)           }\n{ with the following  modification:                       }\n{ As a special exception, the copyright holders of this   }\n{ library give you permission to link this library with   }\n{ independent modules to produce an executable,           }\n{ regardless of the license terms of these independent    }\n{ modules, and to copy and distribute the resulting       }\n{ executable under terms of your choice, provided that    }\n{ you also meet, for each linked independent module,      }\n{ the terms and conditions of the license of that module. }\n{ An independent module is a module which is not derived  }\n{ from or based on this library. If you modify this       }\n{ library, you may extend this exception to your version  }\n{ of the library, but you are not obligated to do so.     }\n{ If you do not wish to do so, delete this exception      }\n{ statement from your version.                            }\n{                                                         }\n{                                                         }\n{ The project web site is located on:                     }\n{   http://zeos.firmos.at  (FORUM)                        }\n{   http://sourceforge.net/p/zeoslib/tickets/ (BUGTRACKER)}\n{   svn://svn.code.sf.net/p/zeoslib/code-0/trunk (SVN)    }\n{                                                         }\n{   http://www.sourceforge.net/projects/zeoslib.          }\n{                                                         }\n{                                                         }\n{                                 Zeos Development Group. }\n{********************************************************@}\n\nunit ZDbcAdo;\n\ninterface\n\n{$I ZDbc.inc}\n\nuses\n  Types, Classes, ZDbcConnection, ZDbcIntfs, ZCompatibility, ZPlainDriver,\n  ZPlainAdoDriver, ZPlainAdo, ZURL, ZTokenizer;\n\ntype\n  {** Implements Ado Database Driver. }\n  {$WARNINGS OFF}\n  TZAdoDriver = class(TZAbstractDriver)\n  public\n    constructor Create; override;\n    function Connect(const Url: TZURL): IZConnection; override;\n    function GetMajorVersion: Integer; override;\n    function GetMinorVersion: Integer; override;\n    function GetTokenizer: IZTokenizer; override;\n  end;\n  {$WARNINGS ON}\n\n  {** Represents an Ado specific connection interface. }\n  IZAdoConnection = interface (IZConnection)\n    ['{50D1AF76-0174-41CD-B90B-4FB770EFB14F}']\n    function GetAdoConnection: ZPlainAdo.Connection;\n    procedure InternalExecuteStatement(const SQL: string);\n    procedure CheckAdoError;\n  end;\n\n  {** Implements a generic Ado Connection. }\n  TZAdoConnection = class(TZAbstractConnection, IZAdoConnection)\n  private\n    procedure ReStartTransactionSupport;\n  protected\n    FAdoConnection: ZPlainAdo.Connection;\n    function GetAdoConnection: ZPlainAdo.Connection;\n    procedure InternalExecuteStatement(const SQL: string);\n    procedure CheckAdoError;\n    procedure StartTransaction;\n    procedure InternalCreate; override;\n  public\n    destructor Destroy; override;\n\n    function GetBinaryEscapeString(const Value: TByteDynArray): String; overload; override;\n    function GetBinaryEscapeString(const Value: RawByteString): String; overload; override;\n    function CreateRegularStatement(Info: TStrings): IZStatement; override;\n    function CreatePreparedStatement(const SQL: string; Info: TStrings):\n      IZPreparedStatement; override;\n    function CreateCallableStatement(const SQL: string; Info: TStrings):\n      IZCallableStatement; override;\n\n    function NativeSQL(const SQL: string): string; override;\n\n    procedure SetAutoCommit(AutoCommit: Boolean); override;\n    procedure SetTransactionIsolation(Level: TZTransactIsolationLevel); override;\n\n    procedure Commit; override;\n    procedure Rollback; override;\n\n    procedure Open; override;\n    procedure Close; override;\n\n    procedure SetReadOnly(ReadOnly: Boolean); override;\n\n    procedure SetCatalog(const Catalog: string); override;\n    function GetCatalog: string; override;\n\n    function GetWarnings: EZSQLWarning; override;\n    procedure ClearWarnings; override;\n  end;\n\nvar\n  {** The common driver manager object. }\n  AdoDriver: IZDriver;\n\nimplementation\n\nuses\n  Variants,\n  SysUtils, ActiveX, ZDbcUtils, ZDbcLogging, ZAdoToken, ZSysUtils,\n  ZDbcAdoStatement, ZDbcAdoMetaData;\n\nconst                                                //adXactUnspecified\n  IL: array[TZTransactIsolationLevel] of TOleEnum = (adXactChaos, adXactReadUncommitted, adXactReadCommitted, adXactRepeatableRead, adXactSerializable);\n\n{ TZDBLibDriver }\n\n{**\n  Constructs this object with default properties.\n}\nconstructor TZAdoDriver.Create;\nbegin\n  inherited Create;\n  AddSupportedProtocol(AddPlainDriverToCache(TZAdoPlainDriver.Create));\nend;\n\n{**\n  Attempts to make a database connection to the given URL.\n}\n{$WARNINGS OFF}\nfunction TZAdoDriver.Connect(const Url: TZURL): IZConnection;\nbegin\n  Result := TZAdoConnection.Create(Url);\nend;\n{$WARNINGS ON}\n\n{**\n  Gets the driver's major version number. Initially this should be 1.\n  @return this driver's major version number\n}\nfunction TZAdoDriver.GetMajorVersion: Integer;\nbegin\n  Result := 1;\nend;\n\n{**\n  Gets the driver's minor version number. Initially this should be 0.\n  @return this driver's minor version number\n}\nfunction TZAdoDriver.GetMinorVersion: Integer;\nbegin\n  Result := 0;\nend;\n\nfunction TZAdoDriver.GetTokenizer: IZTokenizer;\nbegin\n  if Tokenizer = nil then\n    Tokenizer := TZAdoSQLTokenizer.Create;\n  Result := Tokenizer;\nend;\n\n{ TZAdoConnection }\n\nprocedure TZAdoConnection.InternalCreate;\nbegin\n  FAdoConnection := CoConnection.Create;\n  Self.FMetadata := TZAdoDatabaseMetadata.Create(Self, URL);\n  Open;\nend;\n\n{**\n  Destroys this object and cleanups the memory.\n}\ndestructor TZAdoConnection.Destroy;\nbegin\n  Close;\n  FAdoConnection := nil;\n  inherited Destroy;\nend;\n\n{**\n  Just return the Ado Connection\n}\nfunction TZAdoConnection.GetAdoConnection: ZPlainAdo.Connection;\nbegin\n  Result := FAdoConnection;\nend;\n\n{**\n  Executes simple statements internally.\n}\nprocedure TZAdoConnection.InternalExecuteStatement(const SQL: string);\nvar\n  RowsAffected: OleVariant;\nbegin\n  try\n    FAdoConnection.Execute(SQL, RowsAffected, adExecuteNoRecords);\n    DriverManager.LogMessage(lcExecute, PlainDriver.GetProtocol, SQL);\n  except\n    on E: Exception do\n    begin\n      DriverManager.LogError(lcExecute, PlainDriver.GetProtocol, SQL, 0, E.Message);\n      raise;\n    end;\n  end;\nend;\n\nprocedure TZAdoConnection.CheckAdoError;\nbegin\nend;\n\n{**\n  Starts a transaction support.\n}\nprocedure TZAdoConnection.ReStartTransactionSupport;\nbegin\n  if Closed then Exit;\n\n  if not (AutoCommit or (GetTransactionIsolation = tiNone)) then\n    StartTransaction;\nend;\n\n{**\n  Opens a connection to database server with specified parameters.\n}\nprocedure TZAdoConnection.Open;\nvar\n  LogMessage: string;\nbegin\n  if not Closed then Exit;\n\n  LogMessage := Format('CONNECT TO \"%s\" AS USER \"%s\"', [Database, User]);\n  try\n    if ReadOnly then\n      FAdoConnection.Set_Mode(adModeRead)\n    else\n      FAdoConnection.Set_Mode(adModeUnknown);\n    FAdoConnection.Open(Database, User, Password, -1{adConnectUnspecified});\n    FAdoConnection.Set_CursorLocation(adUseClient);\n    DriverManager.LogMessage(lcConnect, PLainDriver.GetProtocol, LogMessage);\n    if FClientCodePage <> 'CP_ADO' then CheckCharEncoding('CP_ADO', True)\n  except\n    on E: Exception do\n    begin\n      DriverManager.LogError(lcConnect, PlainDriver.GetProtocol, LogMessage, 0, E.Message);\n      raise;\n    end;\n  end;\n\n  inherited Open;\n\n  FAdoConnection.IsolationLevel := IL[GetTransactionIsolation];\n  ReStartTransactionSupport;\nend;\n\nfunction TZAdoConnection.GetBinaryEscapeString(const Value: TByteDynArray): String;\nbegin\n  Result := GetSQLHexString(PAnsiChar(Value), Length(Value), True);\n  if GetAutoEncodeStrings then\n    Result := GetDriver.GetTokenizer.GetEscapeString(Result)\nend;\n\nfunction TZAdoConnection.GetBinaryEscapeString(const Value: RawByteString): String;\nbegin\n  Result := GetSQLHexString(PAnsiChar(Value), Length(Value), True);\n  if GetAutoEncodeStrings then\n    Result := GetDriver.GetTokenizer.GetEscapeString(Result)\nend;\n\n{**\n  Creates a <code>Statement</code> object for sending\n  SQL statements to the database.\n  SQL statements without parameters are normally\n  executed using Statement objects. If the same SQL statement\n  is executed many times, it is more efficient to use a\n  <code>PreparedStatement</code> object.\n  <P>\n  Result sets created using the returned <code>Statement</code>\n  object will by default have forward-only type and read-only concurrency.\n\n  @param Info a statement parameters.\n  @return a new Statement object\n}\nfunction TZAdoConnection.CreateRegularStatement(Info: TStrings): IZStatement;\nbegin\n  if IsClosed then Open;\n  Result := TZAdoStatement.Create(PlainDriver, Self, '', Info);\nend;\n\n{**\n  Creates a <code>PreparedStatement</code> object for sending\n  parameterized SQL statements to the database.\n\n  A SQL statement with or without IN parameters can be\n  pre-compiled and stored in a PreparedStatement object. This\n  object can then be used to efficiently execute this statement\n  multiple times.\n\n  <P><B>Note:</B> This method is optimized for handling\n  parametric SQL statements that benefit from precompilation. If\n  the driver supports precompilation,\n  the method <code>prepareStatement</code> will send\n  the statement to the database for precompilation. Some drivers\n  may not support precompilation. In this case, the statement may\n  not be sent to the database until the <code>PreparedStatement</code> is\n  executed.  This has no direct effect on users; however, it does\n  affect which method throws certain SQLExceptions.\n\n  Result sets created using the returned PreparedStatement will have\n  forward-only type and read-only concurrency, by default.\n\n  @param sql a SQL statement that may contain one or more '?' IN\n    parameter placeholders\n  @param Info a statement parameters.\n  @return a new PreparedStatement object containing the\n    pre-compiled statement\n}\nfunction TZAdoConnection.CreatePreparedStatement(\n  const SQL: string; Info: TStrings): IZPreparedStatement;\nbegin\n  if IsClosed then Open;\n  Result := TZAdoPreparedStatement.Create(PlainDriver, Self, SQL, Info);\nend;\n\n{**\n  Creates a <code>CallableStatement</code> object for calling\n  database stored procedures.\n  The <code>CallableStatement</code> object provides\n  methods for setting up its IN and OUT parameters, and\n  methods for executing the call to a stored procedure.\n\n  <P><B>Note:</B> This method is optimized for handling stored\n  procedure call statements. Some drivers may send the call\n  statement to the database when the method <code>prepareCall</code>\n  is done; others\n  may wait until the <code>CallableStatement</code> object\n  is executed. This has no\n  direct effect on users; however, it does affect which method\n  throws certain SQLExceptions.\n\n  Result sets created using the returned CallableStatement will have\n  forward-only type and read-only concurrency, by default.\n\n  @param sql a SQL statement that may contain one or more '?'\n    parameter placeholders. Typically this  statement is a JDBC\n    function call escape string.\n  @param Info a statement parameters.\n  @return a new CallableStatement object containing the\n    pre-compiled SQL statement\n}\nfunction TZAdoConnection.CreateCallableStatement(const SQL: string; Info: TStrings):\n  IZCallableStatement;\nbegin\n  if IsClosed then Open;\n  Result := TZAdoCallableStatement.Create(PlainDriver, Self, SQL, Info);\nend;\n\n{**\n  Converts the given SQL statement into the system's native SQL grammar.\n  A driver may convert the JDBC sql grammar into its system's\n  native SQL grammar prior to sending it; this method returns the\n  native form of the statement that the driver would have sent.\n\n  @param sql a SQL statement that may contain one or more '?'\n    parameter placeholders\n  @return the native form of this statement\n}\nfunction TZAdoConnection.NativeSQL(const SQL: string): string;\nbegin\n  Result := SQL;\nend;\n\n{**\n  Sets this connection's auto-commit mode.\n  If a connection is in auto-commit mode, then all its SQL\n  statements will be executed and committed as individual\n  transactions.  Otherwise, its SQL statements are grouped into\n  transactions that are terminated by a call to either\n  the method <code>commit</code> or the method <code>rollback</code>.\n  By default, new connections are in auto-commit mode.\n\n  The commit occurs when the statement completes or the next\n  execute occurs, whichever comes first. In the case of\n  statements returning a ResultSet, the statement completes when\n  the last row of the ResultSet has been retrieved or the\n  ResultSet has been closed. In advanced cases, a single\n  statement may return multiple results as well as output\n  parameter values. In these cases the commit occurs when all results and\n  output parameter values have been retrieved.\n\n  @param autoCommit true enables auto-commit; false disables auto-commit.\n}\nprocedure TZAdoConnection.SetAutoCommit(AutoCommit: Boolean);\nbegin\n  if GetAutoCommit = AutoCommit then  Exit;\n  if not Closed and AutoCommit then\n  begin\n    if (FAdoConnection.State = adStateOpen) and\n       (GetTransactionIsolation <> tiNone) then\n      begin\n        FAdoConnection.CommitTrans;\n        DriverManager.LogMessage(lcExecute, PlainDriver.GetProtocol, 'COMMIT');\n      end;\n  end;\n  inherited;\n  ReStartTransactionSupport;\nend;\n\n{**\n  Attempts to change the transaction isolation level to the one given.\n  The constants defined in the interface <code>Connection</code>\n  are the possible transaction isolation levels.\n\n  <P><B>Note:</B> This method cannot be called while\n  in the middle of a transaction.\n\n  @param level one of the TRANSACTION_* isolation values with the\n    exception of TRANSACTION_NONE; some databases may not support other values\n  @see DatabaseMetaData#supportsTransactionIsolationLevel\n}\nprocedure TZAdoConnection.SetTransactionIsolation(\n  Level: TZTransactIsolationLevel);\nbegin\n  if GetTransactionIsolation = Level then Exit;\n\n  if not Closed and not AutoCommit and (GetTransactionIsolation <> tiNone) then\n  begin\n    FAdoConnection.CommitTrans;\n    DriverManager.LogMessage(lcExecute, PlainDriver.GetProtocol, 'COMMIT');\n  end;\n\n  inherited;\n\n  if not Closed then\n    FAdoConnection.IsolationLevel := IL[Level];\n\n  RestartTransactionSupport;\nend;\n\n{**\n  Starts a new transaction. Used internally.\n}\nprocedure TZAdoConnection.StartTransaction;\nvar\n  LogMessage: string;\nbegin\n  LogMessage := 'BEGIN TRANSACTION';\n  try\n    FAdoConnection.BeginTrans;\n    DriverManager.LogMessage(lcExecute, PlainDriver.GetProtocol, LogMessage);\n  except\n    on E: Exception do\n    begin\n      DriverManager.LogError(lcExecute, PlainDriver.GetProtocol, LogMessage, 0, E.Message);\n      raise;\n    end;\n  end;\nend;\n\n{**\n  Makes all changes made since the previous\n  commit/rollback permanent and releases any database locks\n  currently held by the Connection. This method should be\n  used only when auto-commit mode has been disabled.\n  @see #setAutoCommit\n}\nprocedure TZAdoConnection.Commit;\nvar\n  LogMessage: string;\nbegin\n  LogMessage := 'COMMIT';\n  if not (AutoCommit or (GetTransactionIsolation = tiNone)) then\n  try\n    FAdoConnection.CommitTrans;\n    DriverManager.LogMessage(lcExecute, PlainDriver.GetProtocol, LogMessage);\n    StartTransaction;\n  except\n    on E: Exception do\n    begin\n      DriverManager.LogError(lcExecute, PlainDriver.GetProtocol, LogMessage, 0, E.Message);\n      raise;\n    end;\n  end;\nend;\n\n{**\n  Drops all changes made since the previous\n  commit/rollback and releases any database locks currently held\n  by this Connection. This method should be used only when auto-\n  commit has been disabled.\n  @see #setAutoCommit\n}\nprocedure TZAdoConnection.Rollback;\nvar\n  LogMessage: string;\nbegin\n  LogMessage := 'ROLLBACK';\n  if not (AutoCommit or (GetTransactionIsolation = tiNone)) then\n  try\n    FAdoConnection.RollbackTrans;\n    DriverManager.LogMessage(lcExecute, PlainDriver.GetProtocol, LogMessage);\n    StartTransaction;\n  except\n    on E: Exception do\n    begin\n      DriverManager.LogError(lcExecute, PlainDriver.GetProtocol, LogMessage, 0, E.Message);\n      raise;\n    end;\n  end;\nend;\n\n{**\n  Releases a Connection's database and JDBC resources\n  immediately instead of waiting for\n  them to be automatically released.\n\n  <P><B>Note:</B> A Connection is automatically closed when it is\n  garbage collected. Certain fatal errors also result in a closed\n  Connection.\n}\nprocedure TZAdoConnection.Close;\nvar\n  LogMessage: string;\nbegin\n  if Closed or (not Assigned(PlainDriver)) then\n    Exit;\n\n  SetAutoCommit(True);\n\n  LogMessage := Format('CLOSE CONNECTION TO \"%s\"', [Database]);\n  try\n    if FAdoConnection.State = adStateOpen then\n      FAdoConnection.Close;\n    DriverManager.LogMessage(lcExecute, PlainDriver.GetProtocol, LogMessage);\n  except\n    on E: Exception do\n    begin\n      DriverManager.LogError(lcExecute, PlainDriver.GetProtocol, LogMessage, 0, E.Message);\n      raise;\n    end;\n  end;\n\n  inherited;\nend;\n\n{**\n  Puts this connection in read-only mode as a hint to enable\n  database optimizations.\n\n  <P><B>Note:</B> This method cannot be called while in the\n  middle of a transaction.\n\n  @param readOnly true enables read-only mode; false disables\n    read-only mode.\n}\nprocedure TZAdoConnection.SetReadOnly(ReadOnly: Boolean);\nbegin\n  inherited;\nend;\n\n{**\n  Sets a catalog name in order to select\n  a subspace of this Connection's database in which to work.\n  If the driver does not support catalogs, it will\n  silently ignore this request.\n}\nprocedure TZAdoConnection.SetCatalog(const Catalog: string);\nvar\n  LogMessage: string;\nbegin\n  if Closed then Exit;\n\n  LogMessage := Format('SET CATALOG %s', [Catalog]);\n  try\n    FAdoConnection.DefaultDatabase := Catalog;\n    DriverManager.LogMessage(lcExecute, PlainDriver.GetProtocol, LogMessage);\n  except\n    on E: Exception do\n    begin\n      DriverManager.LogError(lcExecute, PlainDriver.GetProtocol, LogMessage, 0, E.Message);\n      raise;\n    end;\n  end;\nend;\n\n{**\n  Returns the Connection's current catalog name.\n  @return the current catalog name or null\n}\nfunction TZAdoConnection.GetCatalog: string;\nbegin\n  Result := FAdoConnection.DefaultDatabase;\nend;\n\n{**\n  Returns the first warning reported by calls on this Connection.\n  <P><B>Note:</B> Subsequent warnings will be chained to this\n  SQLWarning.\n  @return the first SQLWarning or null\n}\nfunction TZAdoConnection.GetWarnings: EZSQLWarning;\nbegin\n  Result := nil;\nend;\n\n{**\n  Clears all warnings reported for this <code>Connection</code> object.\n  After a call to this method, the method <code>getWarnings</code>\n    returns null until a new warning is reported for this Connection.\n}\nprocedure TZAdoConnection.ClearWarnings;\nbegin\nend;\n\ninitialization\n  AdoDriver := TZAdoDriver.Create;\n  DriverManager.RegisterDriver(AdoDriver);\nfinalization\n  if Assigned(DriverManager) then\n    DriverManager.DeregisterDriver(AdoDriver);\n  AdoDriver := nil;\nend.\n"
  },
  {
    "path": "lib/zeosdbo/src/dbc/ZDbcAdoMetadata.pas",
    "content": "{*********************************************************}\n{                                                         }\n{                 Zeos Database Objects                   }\n{               Ado metadata information                  }\n{                                                         }\n{        Originally written by Janos Fegyverneki          }\n{                                                         }\n{*********************************************************}\n\n{@********************************************************}\n{    Copyright (c) 1999-2012 Zeos Development Group       }\n{                                                         }\n{ License Agreement:                                      }\n{                                                         }\n{ This library is distributed in the hope that it will be }\n{ useful, but WITHOUT ANY WARRANTY; without even the      }\n{ implied warranty of MERCHANTABILITY or FITNESS FOR      }\n{ A PARTICULAR PURPOSE.  See the GNU Lesser General       }\n{ Public License for more details.                        }\n{                                                         }\n{ The source code of the ZEOS Libraries and packages are  }\n{ distributed under the Library GNU General Public        }\n{ License (see the file COPYING / COPYING.ZEOS)           }\n{ with the following  modification:                       }\n{ As a special exception, the copyright holders of this   }\n{ library give you permission to link this library with   }\n{ independent modules to produce an executable,           }\n{ regardless of the license terms of these independent    }\n{ modules, and to copy and distribute the resulting       }\n{ executable under terms of your choice, provided that    }\n{ you also meet, for each linked independent module,      }\n{ the terms and conditions of the license of that module. }\n{ An independent module is a module which is not derived  }\n{ from or based on this library. If you modify this       }\n{ library, you may extend this exception to your version  }\n{ of the library, but you are not obligated to do so.     }\n{ If you do not wish to do so, delete this exception      }\n{ statement from your version.                            }\n{                                                         }\n{                                                         }\n{ The project web site is located on:                     }\n{   http://zeos.firmos.at  (FORUM)                        }\n{   http://sourceforge.net/p/zeoslib/tickets/ (BUGTRACKER)}\n{   svn://svn.code.sf.net/p/zeoslib/code-0/trunk (SVN)    }\n{                                                         }\n{   http://www.sourceforge.net/projects/zeoslib.          }\n{                                                         }\n{                                                         }\n{                                 Zeos Development Group. }\n{********************************************************@}\n\nunit ZDbcAdoMetadata;\n\ninterface\n\n{$I ZDbc.inc}\n\nuses\n  Types, Classes, SysUtils, ZSysUtils, ZClasses, ZDbcIntfs, ZDbcMetadata,\n  ZDbcResultSet, ZDbcCachedResultSet, ZDbcResultsetMetadata, ZURL,\n  ZCompatibility, ZGenericSqlAnalyser, ZPlainAdo, ZDbcConnection;\n\ntype\n  // technobot 2008-06-27 - methods moved as is from TZAdoDatabaseMetadata:\n  {** Implements Ado Database Information. }\n  TZAdoDatabaseInfo = class(TZAbstractDatabaseInfo)\n  public\n    constructor Create(const Metadata: TZAbstractDatabaseMetadata);\n\n    // database/driver/server info:\n    function GetDatabaseProductName: string; override;\n    function GetDatabaseProductVersion: string; override;\n    function GetDriverName: string; override;\n//    function GetDriverVersion: string; override; -> Same as parent\n    function GetDriverMajorVersion: Integer; override;\n    function GetDriverMinorVersion: Integer; override;\n//    function GetServerVersion: string; -> Not implemented\n\n    // capabilities (what it can/cannot do):\n//    function AllProceduresAreCallable: Boolean; override; -> Not implemented\n//    function AllTablesAreSelectable: Boolean; override; -> Not implemented\n    function SupportsMixedCaseIdentifiers: Boolean; override;\n    function SupportsMixedCaseQuotedIdentifiers: Boolean; override;\n//    function SupportsAlterTableWithAddColumn: Boolean; override; -> Not implemented\n//    function SupportsAlterTableWithDropColumn: Boolean; override; -> Not implemented\n//    function SupportsColumnAliasing: Boolean; override; -> Not implemented\n//    function SupportsConvert: Boolean; override; -> Not implemented\n//    function SupportsConvertForTypes(FromType: TZSQLType; ToType: TZSQLType):\n//      Boolean; override; -> Not implemented\n//    function SupportsTableCorrelationNames: Boolean; override; -> Not implemented\n//    function SupportsDifferentTableCorrelationNames: Boolean; override; -> Not implemented\n    function SupportsExpressionsInOrderBy: Boolean; override;\n    function SupportsOrderByUnrelated: Boolean; override;\n    function SupportsGroupBy: Boolean; override;\n    function SupportsGroupByUnrelated: Boolean; override;\n    function SupportsGroupByBeyondSelect: Boolean; override;\n//    function SupportsLikeEscapeClause: Boolean; override; -> Not implemented\n//    function SupportsMultipleResultSets: Boolean; override; -> Not implemented\n//    function SupportsMultipleTransactions: Boolean; override; -> Not implemented\n//    function SupportsNonNullableColumns: Boolean; override; -> Not implemented\n//    function SupportsMinimumSQLGrammar: Boolean; override; -> Not implemented\n//    function SupportsCoreSQLGrammar: Boolean; override; -> Not implemented\n//    function SupportsExtendedSQLGrammar: Boolean; override; -> Not implemented\n//    function SupportsANSI92EntryLevelSQL: Boolean; override; -> Not implemented\n//    function SupportsANSI92IntermediateSQL: Boolean; override; -> Not implemented\n//    function SupportsANSI92FullSQL: Boolean; override; -> Not implemented\n    function SupportsIntegrityEnhancementFacility: Boolean; override;\n//    function SupportsOuterJoins: Boolean; override; -> Not implemented\n//    function SupportsFullOuterJoins: Boolean; override; -> Not implemented\n//    function SupportsLimitedOuterJoins: Boolean; override; -> Not implemented\n    function SupportsSchemasInDataManipulation: Boolean; override;\n    function SupportsSchemasInProcedureCalls: Boolean; override;\n    function SupportsSchemasInTableDefinitions: Boolean; override;\n    function SupportsSchemasInIndexDefinitions: Boolean; override;\n    function SupportsSchemasInPrivilegeDefinitions: Boolean; override;\n    function SupportsCatalogsInDataManipulation: Boolean; override;\n    function SupportsCatalogsInProcedureCalls: Boolean; override;\n    function SupportsCatalogsInTableDefinitions: Boolean; override;\n    function SupportsCatalogsInIndexDefinitions: Boolean; override;\n    function SupportsCatalogsInPrivilegeDefinitions: Boolean; override;\n    function SupportsOverloadPrefixInStoredProcedureName: Boolean; override;\n    function SupportsPositionedDelete: Boolean; override;\n    function SupportsPositionedUpdate: Boolean; override;\n    function SupportsSelectForUpdate: Boolean; override;\n    function SupportsStoredProcedures: Boolean; override;\n    function SupportsSubqueriesInComparisons: Boolean; override;\n    function SupportsSubqueriesInExists: Boolean; override;\n    function SupportsSubqueriesInIns: Boolean; override;\n    function SupportsSubqueriesInQuantifieds: Boolean; override;\n    function SupportsCorrelatedSubqueries: Boolean; override;\n    function SupportsUnion: Boolean; override;\n    function SupportsUnionAll: Boolean; override;\n    function SupportsOpenCursorsAcrossCommit: Boolean; override;\n    function SupportsOpenCursorsAcrossRollback: Boolean; override;\n    function SupportsOpenStatementsAcrossCommit: Boolean; override;\n    function SupportsOpenStatementsAcrossRollback: Boolean; override;\n    function SupportsTransactions: Boolean; override;\n    function SupportsTransactionIsolationLevel(Level: TZTransactIsolationLevel):\n      Boolean; override;\n    function SupportsDataDefinitionAndDataManipulationTransactions: Boolean; override;\n    function SupportsDataManipulationTransactionsOnly: Boolean; override;\n    function SupportsResultSetType(_Type: TZResultSetType): Boolean; override;\n    function SupportsResultSetConcurrency(_Type: TZResultSetType;\n      Concurrency: TZResultSetConcurrency): Boolean; override;\n//    function SupportsBatchUpdates: Boolean; override; -> Not implemented\n    function SupportsNonEscapedSearchStrings: Boolean; override;\n    function SupportsUpdateAutoIncrementFields: Boolean; override;\n\n    // maxima:\n    function GetMaxBinaryLiteralLength: Integer; override;\n    function GetMaxCharLiteralLength: Integer; override;\n    function GetMaxColumnNameLength: Integer; override;\n    function GetMaxColumnsInGroupBy: Integer; override;\n    function GetMaxColumnsInIndex: Integer; override;\n    function GetMaxColumnsInOrderBy: Integer; override;\n    function GetMaxColumnsInSelect: Integer; override;\n    function GetMaxColumnsInTable: Integer; override;\n    function GetMaxConnections: Integer; override;\n    function GetMaxCursorNameLength: Integer; override;\n    function GetMaxIndexLength: Integer; override;\n    function GetMaxSchemaNameLength: Integer; override;\n    function GetMaxProcedureNameLength: Integer; override;\n    function GetMaxCatalogNameLength: Integer; override;\n    function GetMaxRowSize: Integer; override;\n    function GetMaxStatementLength: Integer; override;\n    function GetMaxStatements: Integer; override;\n    function GetMaxTableNameLength: Integer; override;\n    function GetMaxTablesInSelect: Integer; override;\n    function GetMaxUserNameLength: Integer; override;\n\n    // policies (how are various data and operations handled):\n//    function IsReadOnly: Boolean; override; -> Not implemented\n//    function IsCatalogAtStart: Boolean; override; -> Not implemented\n    function DoesMaxRowSizeIncludeBlobs: Boolean; override;\n//    function NullsAreSortedHigh: Boolean; override; -> Not implemented\n//    function NullsAreSortedLow: Boolean; override; -> Not implemented\n//    function NullsAreSortedAtStart: Boolean; override; -> Not implemented\n//    function NullsAreSortedAtEnd: Boolean; override; -> Not implemented\n//    function NullPlusNonNullIsNull: Boolean; override; -> Not implemented\n//    function UsesLocalFiles: Boolean; override; -> Not implemented\n    function UsesLocalFilePerTable: Boolean; override;\n    function StoresUpperCaseIdentifiers: Boolean; override;\n    function StoresLowerCaseIdentifiers: Boolean; override;\n    function StoresMixedCaseIdentifiers: Boolean; override;\n    function StoresUpperCaseQuotedIdentifiers: Boolean; override;\n    function StoresLowerCaseQuotedIdentifiers: Boolean; override;\n    function StoresMixedCaseQuotedIdentifiers: Boolean; override;\n    function GetDefaultTransactionIsolation: TZTransactIsolationLevel; override;\n    function DataDefinitionCausesTransactionCommit: Boolean; override;\n    function DataDefinitionIgnoredInTransactions: Boolean; override;\n\n    // interface details (terms, keywords, etc):\n    function GetSchemaTerm: string; override;\n    function GetProcedureTerm: string; override;\n    function GetCatalogTerm: string; override;\n    function GetCatalogSeparator: string; override;\n    function GetSQLKeywords: string; override;\n    function GetNumericFunctions: string; override;\n    function GetStringFunctions: string; override;\n    function GetSystemFunctions: string; override;\n    function GetTimeDateFunctions: string; override;\n    function GetSearchStringEscape: string; override;\n    function GetExtraNameCharacters: string; override;\n  end;\n\n  {** Implements Ado Metadata. }\n  TZAdoDatabaseMetadata = class(TZAbstractDatabaseMetadata)\n  private\n    FAdoConnection: ZPlainAdo.Connection;\n    FSupportedSchemasInitialized: Boolean;\n    function AdoOpenSchema(Schema: Integer; const Args: array of const): ZPlainAdo.RecordSet;\n    procedure InitializeSchemas;\n    function SchemaSupported(SchemaId: Integer): Boolean; // (technobot) should be moved to TZAdoDatabaseInfo?\n    function FindSchema(SchemaId: Integer): Integer;\n    function BuildRestrictions(SchemaId: Integer; const Args: array of const): Variant;\n  protected\n    function CreateDatabaseInfo: IZDatabaseInfo; override; // technobot 2008-06-27\n    function DecomposeObjectString(const S: String): String; override;\n\n    function UncachedGetTables(const Catalog: string; const SchemaPattern: string;\n      const TableNamePattern: string; const Types: TStringDynArray): IZResultSet; override;\n    function UncachedGetSchemas: IZResultSet; override;\n    function UncachedGetCatalogs: IZResultSet; override;\n    function UncachedGetTableTypes: IZResultSet; override;\n    function UncachedGetColumns(const Catalog: string; const SchemaPattern: string;\n      const TableNamePattern: string; const ColumnNamePattern: string): IZResultSet; override;\n    function UncachedGetTablePrivileges(const Catalog: string; const SchemaPattern: string;\n      const TableNamePattern: string): IZResultSet; override;\n    function UncachedGetColumnPrivileges(const Catalog: string; const Schema: string;\n      const Table: string; const ColumnNamePattern: string): IZResultSet; override;\n    function UncachedGetPrimaryKeys(const Catalog: string; const Schema: string;\n      const Table: string): IZResultSet; override;\n    function UncachedGetImportedKeys(const Catalog: string; const Schema: string;\n      const Table: string): IZResultSet; override;\n    function UncachedGetExportedKeys(const Catalog: string; const Schema: string;\n      const Table: string): IZResultSet; override;\n    function UncachedGetCrossReference(const PrimaryCatalog: string; const PrimarySchema: string;\n      const PrimaryTable: string; const ForeignCatalog: string; const ForeignSchema: string;\n      const ForeignTable: string): IZResultSet; override;\n    function UncachedGetIndexInfo(const Catalog: string; const Schema: string; const Table: string;\n      Unique: Boolean; Approximate: Boolean): IZResultSet; override;\n//     function UncachedGetSequences(const Catalog: string; const SchemaPattern: string;\n//      const SequenceNamePattern: string): IZResultSet; virtual; -> Not implemented\n    function UncachedGetProcedures(const Catalog: string; const SchemaPattern: string;\n      const ProcedureNamePattern: string): IZResultSet; override;\n    function UncachedGetProcedureColumns(const Catalog: string; const SchemaPattern: string;\n      const ProcedureNamePattern: string; const ColumnNamePattern: string):\n      IZResultSet; override;\n    function UncachedGetVersionColumns(const Catalog: string; const Schema: string;\n      const Table: string): IZResultSet; override;\n    function UncachedGetTypeInfo: IZResultSet; override;\n    function UncachedGetUDTs(const Catalog: string; const SchemaPattern: string;\n      const TypeNamePattern: string; const Types: TIntegerDynArray): IZResultSet; override;\n  public\n    constructor Create(Connection: TZAbstractConnection; const Url: TZURL); override;\n    destructor Destroy; override;\n\n//    function GetTokenizer: IZTokenizer; override;\n  end;\n\nimplementation\n\nuses\n{$IFNDEF FPC}\n  Variants,\n{$ENDIF}\n  Math, ZDbcUtils, ZCollections, ZGenericSqlToken, ZDbcAdoUtils, ZDbcAdo,\n  OleDB, ZDbcAdoResultSet;\n\ntype\n  TSuppSchemaRec = record\n    SchemaGuid: TGuid;\n    SupportedRestrictions: Integer;\n    AdoSchemaId: Integer;\n  end;\n\n  IDBSchemaRowset = interface(IUnknown)\n    ['{0c733a7b-2a1c-11ce-ade5-00aa0044773d}']\n    function GetRowset(\n            pUnkOuter : IUnknown;\n            const rguidSchema : TGUID;\n            cRestrictions : Integer;\n            var rgRestrictions : PVariant;{!!was: const VARIANT __RPC_FAR rgRestrictions[  ],}\n            const riid : IUnknown;\n            cPropertySets : Integer;\n            var rgPropertySets : TDBPROPSET;\n            var ppRowset : IUnknown) : HResult; stdcall;\n      function GetSchemas(\n            var pcSchemas : Integer;\n            var prgSchemas : PGUID;\n            var prgRestrictionSupport : PInteger) : HResult; stdcall;\n    end;\n\nvar\n  SupportedSchemas: array of TSuppSchemaRec;\n\n{ TZAdoDatabaseInfo }\n\n{**\n  Constructs this object.\n  @param Metadata the interface of the correpsonding database metadata object\n  @param IdentifierQuotes the default Quotes for Identifiers used by the driver\n}\nconstructor TZAdoDatabaseInfo.Create(const Metadata: TZAbstractDatabaseMetadata);\nbegin\n  inherited Create(MetaData, '[]');\nend;\n\n//----------------------------------------------------------------------\n// First, a variety of minor information about the target database.\n\n{**\n  What's the name of this database product?\n  @return database product name\n}\nfunction TZAdoDatabaseInfo.GetDatabaseProductName: string;\nbegin\n  Result := 'ado';\nend;\n\n{**\n  What's the version of this database product?\n  @return database version\n}\nfunction TZAdoDatabaseInfo.GetDatabaseProductVersion: string;\nbegin\n  Result := (Metadata.GetConnection as IZAdoConnection).GetAdoConnection.Version;\nend;\n\n{**\n  What's the name of this JDBC driver?\n  @return JDBC driver name\n}\nfunction TZAdoDatabaseInfo.GetDriverName: string;\nbegin\n  Result := 'Zeos Database Connectivity Driver for Microsoft ADO';\nend;\n\n{**\n  What's this JDBC driver's major version number?\n  @return JDBC driver major version\n}\nfunction TZAdoDatabaseInfo.GetDriverMajorVersion: Integer;\nbegin\n  Result := 1;\nend;\n\n{**\n  What's this JDBC driver's minor version number?\n  @return JDBC driver minor version number\n}\nfunction TZAdoDatabaseInfo.GetDriverMinorVersion: Integer;\nbegin\n  Result := 0;\nend;\n\n{**\n  Does the database use a file for each table?\n  @return true if the database uses a local file for each table\n}\nfunction TZAdoDatabaseInfo.UsesLocalFilePerTable: Boolean;\nbegin\n  Result := False;\nend;\n\n{**\n  Does the database treat mixed case unquoted SQL identifiers as\n  case sensitive and as a result store them in mixed case?\n  A JDBC Compliant<sup><font size=-2>TM</font></sup> driver will\n  always return false.\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZAdoDatabaseInfo.SupportsMixedCaseIdentifiers: Boolean;\nbegin\n  Result := False;\nend;\n\n{**\n  Does the database treat mixed case unquoted SQL identifiers as\n  case insensitive and store them in upper case?\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZAdoDatabaseInfo.StoresUpperCaseIdentifiers: Boolean;\nbegin\n  Result := True;\nend;\n\n{**\n  Does the database treat mixed case unquoted SQL identifiers as\n  case insensitive and store them in lower case?\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZAdoDatabaseInfo.StoresLowerCaseIdentifiers: Boolean;\nbegin\n  Result := True;\nend;\n\n{**\n  Does the database treat mixed case unquoted SQL identifiers as\n  case insensitive and store them in mixed case?\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZAdoDatabaseInfo.StoresMixedCaseIdentifiers: Boolean;\nbegin\n  Result := True;\nend;\n\n{**\n  Does the database treat mixed case quoted SQL identifiers as\n  case sensitive and as a result store them in mixed case?\n  A JDBC Compliant<sup><font size=-2>TM</font></sup> driver will always return true.\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZAdoDatabaseInfo.SupportsMixedCaseQuotedIdentifiers: Boolean;\nbegin\n  Result := True;\nend;\n\n{**\n  Does the database treat mixed case quoted SQL identifiers as\n  case insensitive and store them in upper case?\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZAdoDatabaseInfo.StoresUpperCaseQuotedIdentifiers: Boolean;\nbegin\n  Result := True;\nend;\n\n{**\n  Does the database treat mixed case quoted SQL identifiers as\n  case insensitive and store them in lower case?\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZAdoDatabaseInfo.StoresLowerCaseQuotedIdentifiers: Boolean;\nbegin\n  Result := True;\nend;\n\n{**\n  Does the database treat mixed case quoted SQL identifiers as\n  case insensitive and store them in mixed case?\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZAdoDatabaseInfo.StoresMixedCaseQuotedIdentifiers: Boolean;\nbegin\n  Result := True;\nend;\n\n{**\n  Gets a comma-separated list of all a database's SQL keywords\n  that are NOT also SQL92 keywords.\n  @return the list\n}\nfunction TZAdoDatabaseInfo.GetSQLKeywords: string;\nbegin\n  { TODO -ofjanos -cAPI : SQL Keywords that are not SQL92 compliant }\n  Result := '';\nend;\n\n{**\n  Gets a comma-separated list of math functions.  These are the\n  X/Open CLI math function names used in the JDBC function escape\n  clause.\n  @return the list\n}\nfunction TZAdoDatabaseInfo.GetNumericFunctions: string;\nbegin\n  Result := 'ABS,ACOS,ASIN,ATAN,ATN2,CEILING,COS,COT,DEGREES,EXP,FLOOR,LOG,LOG10,'+\n            'PI,POWER,RADIANS,RAND,ROUND,SIGN,SIN,SQUARE,SQRT,TAN';\nend;\n\n{**\n  Gets a comma-separated list of string functions.  These are the\n  X/Open CLI string function names used in the JDBC function escape\n  clause.\n  @return the list\n}\nfunction TZAdoDatabaseInfo.GetStringFunctions: string;\nbegin\n  Result := 'ASCII,CHAR,CHARINDEX,DIFFERENCE,LEFT,LEN,LOWER,LTRIM,NCHAR,PATINDEX,'+\n            'REPLACE,QUOTENAME,REPLICATE,REVERSE,RIGHT,RTRIM,SOUNDEX,SPACE,STR,'+\n            'STUFF,SUBSTRING,UNICODE,UPPER';\nend;\n\n{**\n  Gets a comma-separated list of system functions.  These are the\n  X/Open CLI system function names used in the JDBC function escape\n  clause.\n  @return the list\n}\nfunction TZAdoDatabaseInfo.GetSystemFunctions: string;\nbegin\n  Result := 'APP_NAME,CASE,CAST,CONVERT,COALESCE,CURRENT_TIMESTAMP,CURRENT_USER,'+\n            'DATALENGTH,@@ERROR,FORMATMESSAGE,GETANSINULL,HOST_ID,HOST_NAME,'+\n            'IDENT_INCR,IDENT_SEED,@@IDENTITY,IDENTITY,ISDATE,ISNULL,ISNUMERIC,'+\n            'NEWID,NULLIF,PARSENAME,PERMISSIONS,@@ROWCOUNT,SESSION_USER,STATS_DATE,'+\n            'SYSTEM_USER,@@TRANCOUNT,USER_NAME';\nend;\n\n{**\n  Gets a comma-separated list of time and date functions.\n  @return the list\n}\nfunction TZAdoDatabaseInfo.GetTimeDateFunctions: string;\nbegin\n  Result := 'DATEADD,DATEDIFF,DATENAME,DATEPART,DAY,GETDATE,MONTH,YEAR';\nend;\n\n{**\n  Gets the string that can be used to escape wildcard characters.\n  This is the string that can be used to escape '_' or '%' in\n  the string pattern style catalog search parameters.\n\n  <P>The '_' character represents any single character.\n  <P>The '%' character represents any sequence of zero or\n  more characters.\n\n  @return the string used to escape wildcard characters\n}\nfunction TZAdoDatabaseInfo.GetSearchStringEscape: string;\nbegin\n{ TODO -ofjanos -cgeneral : \nIn sql server this must be specified as the parameter of like.\nexample: WHERE ColumnA LIKE '%5/%%' ESCAPE '/' }\n  Result := '/';\nend;\n\n{**\n  Gets all the \"extra\" characters that can be used in unquoted\n  identifier names (those beyond a-z, A-Z, 0-9 and _).\n  @return the string containing the extra characters\n}\nfunction TZAdoDatabaseInfo.GetExtraNameCharacters: string;\nbegin\n  Result := '@$#';\nend;\n\n//--------------------------------------------------------------------\n// Functions describing which features are supported.\n\n{**\n  Are expressions in \"ORDER BY\" lists supported?\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZAdoDatabaseInfo.SupportsExpressionsInOrderBy: Boolean;\nbegin\n  Result := True;\nend;\n\n{**\n  Can an \"ORDER BY\" clause use columns not in the SELECT statement?\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZAdoDatabaseInfo.SupportsOrderByUnrelated: Boolean;\nbegin\n  Result := True;\nend;\n\n{**\n  Is some form of \"GROUP BY\" clause supported?\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZAdoDatabaseInfo.SupportsGroupBy: Boolean;\nbegin\n  Result := True;\nend;\n\n{**\n  Can a \"GROUP BY\" clause use columns not in the SELECT?\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZAdoDatabaseInfo.SupportsGroupByUnrelated: Boolean;\nbegin\n  Result := True;\nend;\n\n{**\n  Can a \"GROUP BY\" clause add columns not in the SELECT\n  provided it specifies all the columns in the SELECT?\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZAdoDatabaseInfo.SupportsGroupByBeyondSelect: Boolean;\nbegin\n  Result := True;\nend;\n\n{**\n  Is the SQL Integrity Enhancement Facility supported?\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZAdoDatabaseInfo.SupportsIntegrityEnhancementFacility: Boolean;\nbegin\n  Result := False;\nend;\n\n{**\n  What's the database vendor's preferred term for \"schema\"?\n  @return the vendor term\n}\nfunction TZAdoDatabaseInfo.GetSchemaTerm: string;\nbegin\n  Result := 'owner';\nend;\n\n{**\n  What's the database vendor's preferred term for \"procedure\"?\n  @return the vendor term\n}\nfunction TZAdoDatabaseInfo.GetProcedureTerm: string;\nbegin\n  Result := 'procedure';\nend;\n\n{**\n  What's the database vendor's preferred term for \"catalog\"?\n  @return the vendor term\n}\nfunction TZAdoDatabaseInfo.GetCatalogTerm: string;\nbegin\n  Result := 'database';\nend;\n\n{**\n  What's the separator between catalog and table name?\n  @return the separator string\n}\nfunction TZAdoDatabaseInfo.GetCatalogSeparator: string;\nbegin\n  Result := '.';\nend;\n\n{**\n  Can a schema name be used in a data manipulation statement?\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZAdoDatabaseInfo.SupportsSchemasInDataManipulation: Boolean;\nbegin\n  Result := True;\nend;\n\n{**\n  Can a schema name be used in a procedure call statement?\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZAdoDatabaseInfo.SupportsSchemasInProcedureCalls: Boolean;\nbegin\n  Result := True;\nend;\n\n{**\n  Can a schema name be used in a table definition statement?\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZAdoDatabaseInfo.SupportsSchemasInTableDefinitions: Boolean;\nbegin\n  Result := True;\nend;\n\n{**\n  Can a schema name be used in an index definition statement?\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZAdoDatabaseInfo.SupportsSchemasInIndexDefinitions: Boolean;\nbegin\n  Result := True;\nend;\n\n{**\n  Can a schema name be used in a privilege definition statement?\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZAdoDatabaseInfo.SupportsSchemasInPrivilegeDefinitions: Boolean;\nbegin\n  Result := True;\nend;\n\n{**\n  Can a catalog name be used in a data manipulation statement?\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZAdoDatabaseInfo.SupportsCatalogsInDataManipulation: Boolean;\nbegin\n  Result := True;\nend;\n\n{**\n  Can a catalog name be used in a procedure call statement?\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZAdoDatabaseInfo.SupportsCatalogsInProcedureCalls: Boolean;\nbegin\n  Result := True;\nend;\n\n{**\n  Can a catalog name be used in a table definition statement?\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZAdoDatabaseInfo.SupportsCatalogsInTableDefinitions: Boolean;\nbegin\n  Result := True;\nend;\n\n{**\n  Can a catalog name be used in an index definition statement?\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZAdoDatabaseInfo.SupportsCatalogsInIndexDefinitions: Boolean;\nbegin\n  Result := True;\nend;\n\n{**\n  Can a catalog name be used in a privilege definition statement?\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZAdoDatabaseInfo.SupportsCatalogsInPrivilegeDefinitions: Boolean;\nbegin\n  Result := True;\nend;\n\n{**\n  Can a stored procedure have an additional overload suffix?\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZAdoDatabaseInfo.SupportsOverloadPrefixInStoredProcedureName: Boolean;\nbegin\n  Result := True;\nend;\n\n{**\n  Is positioned DELETE supported?\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZAdoDatabaseInfo.SupportsPositionedDelete: Boolean;\nbegin\n//CURRENT OF\n//Specifies that the DELETE is done at the current position of the specified cursor.\n  Result := True;\nend;\n\n{**\n  Is positioned UPDATE supported?\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZAdoDatabaseInfo.SupportsPositionedUpdate: Boolean;\nbegin\n  Result := True;\nend;\n\n{**\n  Is SELECT for UPDATE supported?\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZAdoDatabaseInfo.SupportsSelectForUpdate: Boolean;\nbegin\n  Result := True;\nend;\n\n{**\n  Are stored procedure calls using the stored procedure escape\n  syntax supported?\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZAdoDatabaseInfo.SupportsStoredProcedures: Boolean;\nbegin\n  Result := True;\nend;\n\n{**\n  Are subqueries in comparison expressions supported?\n  A JDBC Compliant<sup><font size=-2>TM</font></sup> driver always returns true.\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZAdoDatabaseInfo.SupportsSubqueriesInComparisons: Boolean;\nbegin\n  Result := True;\nend;\n\n{**\n  Are subqueries in 'exists' expressions supported?\n  A JDBC Compliant<sup><font size=-2>TM</font></sup> driver always returns true.\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZAdoDatabaseInfo.SupportsSubqueriesInExists: Boolean;\nbegin\n  Result := True;\nend;\n\n{**\n  Are subqueries in 'in' statements supported?\n  A JDBC Compliant<sup><font size=-2>TM</font></sup> driver always returns true.\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZAdoDatabaseInfo.SupportsSubqueriesInIns: Boolean;\nbegin\n  Result := True;\nend;\n\n{**\n  Are subqueries in quantified expressions supported?\n  A JDBC Compliant<sup><font size=-2>TM</font></sup> driver always returns true.\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZAdoDatabaseInfo.SupportsSubqueriesInQuantifieds: Boolean;\nbegin\n  Result := True;\nend;\n\n{**\n  Are correlated subqueries supported?\n  A JDBC Compliant<sup><font size=-2>TM</font></sup> driver always returns true.\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZAdoDatabaseInfo.SupportsCorrelatedSubqueries: Boolean;\nbegin\n  Result := True;\nend;\n\n{**\n  Is SQL UNION supported?\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZAdoDatabaseInfo.SupportsUnion: Boolean;\nbegin\n  Result := True;\nend;\n\n{**\n  Is SQL UNION ALL supported?\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZAdoDatabaseInfo.SupportsUnionAll: Boolean;\nbegin\n  Result := True;\nend;\n\n{**\n  Can cursors remain open across commits?\n  @return <code>true</code> if cursors always remain open;\n        <code>false</code> if they might not remain open\n}\nfunction TZAdoDatabaseInfo.SupportsOpenCursorsAcrossCommit: Boolean;\nbegin\n  Result := True;\nend;\n\n{**\n  Can cursors remain open across rollbacks?\n  @return <code>true</code> if cursors always remain open;\n        <code>false</code> if they might not remain open\n}\nfunction TZAdoDatabaseInfo.SupportsOpenCursorsAcrossRollback: Boolean;\nbegin\n  Result := True;\nend;\n\n{**\n  Can statements remain open across commits?\n  @return <code>true</code> if statements always remain open;\n        <code>false</code> if they might not remain open\n}\nfunction TZAdoDatabaseInfo.SupportsOpenStatementsAcrossCommit: Boolean;\nbegin\n  Result := False;\nend;\n\n{**\n  Can statements remain open across rollbacks?\n  @return <code>true</code> if statements always remain open;\n        <code>false</code> if they might not remain open\n}\nfunction TZAdoDatabaseInfo.SupportsOpenStatementsAcrossRollback: Boolean;\nbegin\n  Result := False;\nend;\n\n//----------------------------------------------------------------------\n// The following group of methods exposes various limitations\n// based on the target database with the current driver.\n// Unless otherwise specified, a result of zero means there is no\n// limit, or the limit is not known.\n\n{**\n  How many hex characters can you have in an inline binary literal?\n  @return max binary literal length in hex characters;\n       a result of zero means that there is no limit or the limit is not known\n}\nfunction TZAdoDatabaseInfo.GetMaxBinaryLiteralLength: Integer;\nbegin\n  Result := 16000;\nend;\n\n{**\n  What's the max length for a character literal?\n  @return max literal length;\n       a result of zero means that there is no limit or the limit is not known\n}\nfunction TZAdoDatabaseInfo.GetMaxCharLiteralLength: Integer;\nbegin\n  Result := 8000;\nend;\n\n{**\n  What's the limit on column name length?\n  @return max column name length;\n       a result of zero means that there is no limit or the limit is not known\n}\nfunction TZAdoDatabaseInfo.GetMaxColumnNameLength: Integer;\nbegin\n  Result := 128;\nend;\n\n{**\n  What's the maximum number of columns in a \"GROUP BY\" clause?\n  @return max number of columns;\n       a result of zero means that there is no limit or the limit is not known\n}\nfunction TZAdoDatabaseInfo.GetMaxColumnsInGroupBy: Integer;\nbegin\n  Result := 0;\nend;\n\n{**\n  What's the maximum number of columns allowed in an index?\n  @return max number of columns;\n       a result of zero means that there is no limit or the limit is not known\n}\nfunction TZAdoDatabaseInfo.GetMaxColumnsInIndex: Integer;\nbegin\n  Result := 16;\nend;\n\n{**\n  What's the maximum number of columns in an \"ORDER BY\" clause?\n  @return max number of columns;\n       a result of zero means that there is no limit or the limit is not known\n}\nfunction TZAdoDatabaseInfo.GetMaxColumnsInOrderBy: Integer;\nbegin\n  Result := 0;\nend;\n\n{**\n  What's the maximum number of columns in a \"SELECT\" list?\n  @return max number of columns;\n       a result of zero means that there is no limit or the limit is not known\n}\nfunction TZAdoDatabaseInfo.GetMaxColumnsInSelect: Integer;\nbegin\n  Result := 4096;\nend;\n\n{**\n  What's the maximum number of columns in a table?\n  @return max number of columns;\n       a result of zero means that there is no limit or the limit is not known\n}\nfunction TZAdoDatabaseInfo.GetMaxColumnsInTable: Integer;\nbegin\n  Result := 1024;\nend;\n\n{**\n  How many active connections can we have at a time to this database?\n  @return max number of active connections;\n       a result of zero means that there is no limit or the limit is not known\n}\nfunction TZAdoDatabaseInfo.GetMaxConnections: Integer;\nbegin\n  Result := 0;\nend;\n\n{**\n  What's the maximum cursor name length?\n  @return max cursor name length in bytes;\n       a result of zero means that there is no limit or the limit is not known\n}\nfunction TZAdoDatabaseInfo.GetMaxCursorNameLength: Integer;\nbegin\n  Result := 128;\nend;\n\n{**\n  Retrieves the maximum number of bytes for an index, including all\n  of the parts of the index.\n  @return max index length in bytes, which includes the composite of all\n   the constituent parts of the index;\n   a result of zero means that there is no limit or the limit is not known\n}\nfunction TZAdoDatabaseInfo.GetMaxIndexLength: Integer;\nbegin\n  Result := 900;\nend;\n\n{**\n  What's the maximum length allowed for a schema name?\n  @return max name length in bytes;\n       a result of zero means that there is no limit or the limit is not known\n}\nfunction TZAdoDatabaseInfo.GetMaxSchemaNameLength: Integer;\nbegin\n  Result := 128;\nend;\n\n{**\n  What's the maximum length of a procedure name?\n  @return max name length in bytes;\n       a result of zero means that there is no limit or the limit is not known\n}\nfunction TZAdoDatabaseInfo.GetMaxProcedureNameLength: Integer;\nbegin\n  Result := 128;\nend;\n\n{**\n  What's the maximum length of a catalog name?\n  @return max name length in bytes;\n       a result of zero means that there is no limit or the limit is not known\n}\nfunction TZAdoDatabaseInfo.GetMaxCatalogNameLength: Integer;\nbegin\n  Result := 128;\nend;\n\n{**\n  What's the maximum length of a single row?\n  @return max row size in bytes;\n       a result of zero means that there is no limit or the limit is not known\n}\nfunction TZAdoDatabaseInfo.GetMaxRowSize: Integer;\nbegin\n  Result := 8060;\nend;\n\n{**\n  Did getMaxRowSize() include LONGVARCHAR and LONGVARBINARY\n  blobs?\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZAdoDatabaseInfo.DoesMaxRowSizeIncludeBlobs: Boolean;\nbegin\n  Result := False;\nend;\n\n{**\n  What's the maximum length of an SQL statement?\n  @return max length in bytes;\n       a result of zero means that there is no limit or the limit is not known\n}\nfunction TZAdoDatabaseInfo.GetMaxStatementLength: Integer;\nbegin\n  Result := 0;\nend;\n\n{**\n  How many active statements can we have open at one time to this\n  database?\n  @return the maximum number of statements that can be open at one time;\n       a result of zero means that there is no limit or the limit is not known\n}\nfunction TZAdoDatabaseInfo.GetMaxStatements: Integer;\nbegin\n  Result := 0;\nend;\n\n{**\n  What's the maximum length of a table name?\n  @return max name length in bytes;\n       a result of zero means that there is no limit or the limit is not known\n}\nfunction TZAdoDatabaseInfo.GetMaxTableNameLength: Integer;\nbegin\n  Result := 128;\nend;\n\n{**\n  What's the maximum number of tables in a SELECT statement?\n  @return the maximum number of tables allowed in a SELECT statement;\n       a result of zero means that there is no limit or the limit is not known\n}\nfunction TZAdoDatabaseInfo.GetMaxTablesInSelect: Integer;\nbegin\n  Result := 256;\nend;\n\n{**\n  What's the maximum length of a user name?\n  @return max user name length  in bytes;\n       a result of zero means that there is no limit or the limit is not known\n}\nfunction TZAdoDatabaseInfo.GetMaxUserNameLength: Integer;\nbegin\n  Result := 128;\nend;\n\n//----------------------------------------------------------------------\n\n{**\n  What's the database's default transaction isolation level?  The\n  values are defined in <code>java.sql.Connection</code>.\n  @return the default isolation level\n  @see Connection\n}\nfunction TZAdoDatabaseInfo.GetDefaultTransactionIsolation:\n  TZTransactIsolationLevel;\nbegin\n  Result := tiReadCommitted;\nend;\n\n{**\n  Are transactions supported? If not, invoking the method\n  <code>commit</code> is a noop and the isolation level is TRANSACTION_NONE.\n  @return <code>true</code> if transactions are supported; <code>false</code> otherwise\n}\nfunction TZAdoDatabaseInfo.SupportsTransactions: Boolean;\nbegin\n  Result := True;\nend;\n\n{**\n  Does this database support the given transaction isolation level?\n  @param level the values are defined in <code>java.sql.Connection</code>\n  @return <code>true</code> if so; <code>false</code> otherwise\n  @see Connection\n}\nfunction TZAdoDatabaseInfo.SupportsTransactionIsolationLevel(\n  Level: TZTransactIsolationLevel): Boolean;\nbegin\n  Result := True;\nend;\n\n{**\n  Are both data definition and data manipulation statements\n  within a transaction supported?\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZAdoDatabaseInfo.\n  SupportsDataDefinitionAndDataManipulationTransactions: Boolean;\nbegin\n  Result := True;\nend;\n\n{**\n  Are only data manipulation statements within a transaction\n  supported?\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZAdoDatabaseInfo.\n  SupportsDataManipulationTransactionsOnly: Boolean;\nbegin\n  Result := False;\nend;\n\n{**\n  Does a data definition statement within a transaction force the\n  transaction to commit?\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZAdoDatabaseInfo.DataDefinitionCausesTransactionCommit: Boolean;\nbegin\n  Result := False;\nend;\n\n{**\n  Is a data definition statement within a transaction ignored?\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZAdoDatabaseInfo.DataDefinitionIgnoredInTransactions: Boolean;\nbegin\n  Result := False;\nend;\n\n{**\n  Does the database support the given result set type?\n  @param type defined in <code>java.sql.ResultSet</code>\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZAdoDatabaseInfo.SupportsResultSetType(\n  _Type: TZResultSetType): Boolean;\nbegin\n  Result := True;\nend;\n\n{**\n  Does the database support the concurrency type in combination\n  with the given result set type?\n\n  @param type defined in <code>java.sql.ResultSet</code>\n  @param concurrency type defined in <code>java.sql.ResultSet</code>\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZAdoDatabaseInfo.SupportsResultSetConcurrency(\n  _Type: TZResultSetType; Concurrency: TZResultSetConcurrency): Boolean;\nbegin\n  Result := True;\nend;\n\n{**\n  Does the Database or Actual Version understand non escaped search strings?\n  @return <code>true</code> if the DataBase does understand non escaped\n  search strings\n}\nfunction TZAdoDatabaseInfo.SupportsNonEscapedSearchStrings: Boolean;\nbegin\n  Result := True;\nend;\n\n{**\n  Does the Database support updating auto incremental fields?\n  @return <code>true</code> if the DataBase allows it.\n}\nfunction TZAdoDatabaseInfo.SupportsUpdateAutoIncrementFields: Boolean;\nbegin\n  Result := False;\nend;\n\n{ TZAdoDatabaseMetadata }\n\n\n{**\n  Constructs this object and assignes the main properties.\n  @param Connection a database connection object.\n  @param Url a database connection url string.\n  @param Info an extra connection properties.\n}\nconstructor TZAdoDatabaseMetadata.Create(Connection: TZAbstractConnection;\n  const Url: TZURL);\nbegin\n  inherited Create(Connection, Url);\n  FAdoConnection := nil;\nend;\n\n{**\n  Destroys this object and cleanups the memory.\n}\ndestructor TZAdoDatabaseMetadata.Destroy;\nbegin\n  inherited Destroy;\nend;\n\n{**\n  Constructs a database information object and returns the interface to it. Used\n  internally by the constructor.\n  @return the database information object interface\n}\nfunction TZAdoDatabaseMetadata.CreateDatabaseInfo: IZDatabaseInfo;\nbegin\n  Result := TZAdoDatabaseInfo.Create(Self);\nend;\n\nfunction TZAdoDatabaseMetadata.DecomposeObjectString(const S: String): String;\nbegin\n  if S = '' then\n    Result := S\n  else\n    if IC.IsQuoted(S) then\n       Result := IC.ExtractQuote(S)\n    else\n      Result := s;\nend;\n{**\n  Gets a description of the stored procedures available in a\n  catalog.\n\n  <P>Only procedure descriptions matching the schema and\n  procedure name criteria are returned.  They are ordered by\n  PROCEDURE_SCHEM, and PROCEDURE_NAME.\n\n  <P>Each procedure description has the the following columns:\n   <OL>\n \t<LI><B>PROCEDURE_CAT</B> String => procedure catalog (may be null)\n \t<LI><B>PROCEDURE_SCHEM</B> String => procedure schema (may be null)\n \t<LI><B>PROCEDURE_NAME</B> String => procedure name\n   <LI> reserved for future use\n   <LI> reserved for future use\n   <LI> reserved for future use\n \t<LI><B>REMARKS</B> String => explanatory comment on the procedure\n \t<LI><B>PROCEDURE_TYPE</B> short => kind of procedure:\n       <UL>\n       <LI> procedureResultUnknown - May return a result\n       <LI> procedureNoResult - Does not return a result\n       <LI> procedureReturnsResult - Returns a result\n       </UL>\n   </OL>\n\n  @param catalog a catalog name; \"\" retrieves those without a\n  catalog; null means drop catalog name from the selection criteria\n  @param schemaPattern a schema name pattern; \"\" retrieves those\n  without a schema\n  @param procedureNamePattern a procedure name pattern\n  @return <code>ResultSet</code> - each row is a procedure description\n  @see #getSearchStringEscape\n}\nfunction TZAdoDatabaseMetadata.UncachedGetProcedures(const Catalog: string;\n  const SchemaPattern: string; const ProcedureNamePattern: string): IZResultSet;\nvar\n  AdoRecordSet: ZPlainAdo.RecordSet;\nbegin\n    Result:=inherited UncachedGetProcedures(Catalog, SchemaPattern, ProcedureNamePattern);\n\n    AdoRecordSet := AdoOpenSchema(adSchemaProcedures,\n      [Catalog, SchemaPattern, ProcedureNamePattern, '']);\n    if Assigned(AdoRecordSet) then\n    begin\n      with TZAdoResultSet.Create(GetStatement, '', AdoRecordSet) do\n      begin\n        while Next do\n        begin\n          Result.MoveToInsertRow;\n          Result.UpdateStringByName('PROCEDURE_CAT',\n            GetStringByName('PROCEDURE_CATALOG'));\n          Result.UpdateStringByName('PROCEDURE_SCHEM',\n            GetStringByName('PROCEDURE_SCHEMA'));\n          Result.UpdateStringByName('PROCEDURE_NAME',\n            GetStringByName('PROCEDURE_NAME'));\n          Result.UpdateStringByName('REMARKS',\n            GetStringByName('DESCRIPTION'));\n          Result.UpdateShortByName('PROCEDURE_TYPE',\n            GetShortByName('PROCEDURE_TYPE') - 1);\n          Result.InsertRow;\n        end;\n        Close;\n        Free;\n      end;\n    end;\nend;\n\n{**\n  Gets a description of a catalog's stored procedure parameters\n  and result columns.\n\n  <P>Only descriptions matching the schema, procedure and\n  parameter name criteria are returned.  They are ordered by\n  PROCEDURE_SCHEM and PROCEDURE_NAME. Within this, the return value,\n  if any, is first. Next are the parameter descriptions in call\n  order. The column descriptions follow in column number order.\n\n  <P>Each row in the <code>ResultSet</code> is a parameter description or\n  column description with the following fields:\n   <OL>\n \t<LI><B>PROCEDURE_CAT</B> String => procedure catalog (may be null)\n \t<LI><B>PROCEDURE_SCHEM</B> String => procedure schema (may be null)\n \t<LI><B>PROCEDURE_NAME</B> String => procedure name\n \t<LI><B>COLUMN_NAME</B> String => column/parameter name\n \t<LI><B>COLUMN_TYPE</B> Short => kind of column/parameter:\n       <UL>\n       <LI> procedureColumnUnknown - nobody knows\n       <LI> procedureColumnIn - IN parameter\n       <LI> procedureColumnInOut - INOUT parameter\n       <LI> procedureColumnOut - OUT parameter\n       <LI> procedureColumnReturn - procedure return value\n       <LI> procedureColumnResult - result column in <code>ResultSet</code>\n       </UL>\n   <LI><B>DATA_TYPE</B> short => SQL type from java.sql.Types\n \t<LI><B>TYPE_NAME</B> String => SQL type name, for a UDT type the\n   type name is fully qualified\n \t<LI><B>PRECISION</B> int => precision\n \t<LI><B>LENGTH</B> int => length in bytes of data\n \t<LI><B>SCALE</B> short => scale\n \t<LI><B>RADIX</B> short => radix\n \t<LI><B>NULLABLE</B> short => can it contain NULL?\n       <UL>\n       <LI> procedureNoNulls - does not allow NULL values\n       <LI> procedureNullable - allows NULL values\n       <LI> procedureNullableUnknown - nullability unknown\n       </UL>\n \t<LI><B>REMARKS</B> String => comment describing parameter/column\n   </OL>\n\n  <P><B>Note:</B> Some databases may not return the column\n  descriptions for a procedure. Additional columns beyond\n  REMARKS can be defined by the database.\n\n  @param catalog a catalog name; \"\" retrieves those without a\n  catalog; null means drop catalog name from the selection criteria\n  @param schemaPattern a schema name pattern; \"\" retrieves those\n  without a schema\n  @param procedureNamePattern a procedure name pattern\n  @param columnNamePattern a column name pattern\n  @return <code>ResultSet</code> - each row describes a stored procedure parameter or\n       column\n  @see #getSearchStringEscape\n}\nfunction TZAdoDatabaseMetadata.UncachedGetProcedureColumns(const Catalog: string;\n  const SchemaPattern: string; const ProcedureNamePattern: string;\n  const ColumnNamePattern: string): IZResultSet;\nvar\n  AdoRecordSet: ZPlainAdo.RecordSet;\nbegin\n    Result:=inherited UncachedGetProcedureColumns(Catalog, SchemaPattern, ProcedureNamePattern, ColumnNamePattern);\n\n    AdoRecordSet := AdoOpenSchema(adSchemaProcedureParameters,\n      [Catalog, SchemaPattern, ProcedureNamePattern]);\n    if Assigned(AdoRecordSet) then\n    begin\n      with TZAdoResultSet.Create(GetStatement, '', AdoRecordSet) do\n      begin\n        while Next do\n        begin\n          Result.MoveToInsertRow;\n          Result.UpdateStringByName('PROCEDURE_CAT',\n            GetStringByName('PROCEDURE_CATALOG'));\n          Result.UpdateStringByName('PROCEDURE_SCHEM',\n            GetStringByName('PROCEDURE_SCHEMA'));\n          Result.UpdateStringByName('PROCEDURE_NAME',\n            GetStringByName('PROCEDURE_NAME'));\n          Result.UpdateStringByName('COLUMN_NAME',\n            GetStringByName('PARAMETER_NAME'));\n          case GetShortByName('PARAMETER_TYPE') of\n            1: Result.UpdateShortByName('COLUMN_TYPE', Ord(pctIn));\n            2: Result.UpdateShortByName('COLUMN_TYPE', Ord(pctInOut));\n            3: Result.UpdateShortByName('COLUMN_TYPE', Ord(pctOut));\n            4: Result.UpdateShortByName('COLUMN_TYPE', Ord(pctReturn));\n          else\n            Result.UpdateShortByName('COLUMN_TYPE', Ord(pctUnknown));\n          end;\n          Result.UpdateShortByName('DATA_TYPE',\n            Ord(ConvertAdoToSqlType(GetShortByName('DATA_TYPE'),\n              ConSettings.CPType)));\n          Result.UpdateStringByName('TYPE_NAME',\n            GetStringByName('TYPE_NAME'));\n          Result.UpdateIntByName('PRECISION',\n            GetIntByName('NUMERIC_PRECISION'));\n          Result.UpdateIntByName('LENGTH',\n            GetIntByName('CHARACTER_OCTET_LENGTH'));\n          Result.UpdateShortByName('SCALE',\n            GetShortByName('NUMERIC_SCALE'));\n    //      Result.UpdateShortByName('RADIX', GetShortByName('RADIX'));\n          Result.UpdateShortByName('NULLABLE', 2);\n          if GetStringByName('IS_NULLABLE') = 'NO' then\n            Result.UpdateShortByName('NULLABLE', 0);\n          if GetStringByName('IS_NULLABLE') = 'YES' then\n            Result.UpdateShortByName('NULLABLE', 1);\n          Result.UpdateStringByName('REMARKS',\n            GetStringByName('DESCRIPTION'));\n          Result.InsertRow;\n        end;\n        Close;\n        Free;\n      end;\n    end;\nend;\n\n{**\n  Gets a description of tables available in a catalog.\n\n  <P>Only table descriptions matching the catalog, schema, table\n  name and type criteria are returned.  They are ordered by\n  TABLE_TYPE, TABLE_SCHEM and TABLE_NAME.\n\n  <P>Each table description has the following columns:\n   <OL>\n \t<LI><B>TABLE_CAT</B> String => table catalog (may be null)\n \t<LI><B>TABLE_SCHEM</B> String => table schema (may be null)\n \t<LI><B>TABLE_NAME</B> String => table name\n \t<LI><B>TABLE_TYPE</B> String => table type.  Typical types are \"TABLE\",\n \t\t\t\"VIEW\",\t\"SYSTEM TABLE\", \"GLOBAL TEMPORARY\",\n \t\t\t\"LOCAL TEMPORARY\", \"ALIAS\", \"SYNONYM\".\n \t<LI><B>REMARKS</B> String => explanatory comment on the table\n   </OL>\n\n  <P><B>Note:</B> Some databases may not return information for\n  all tables.\n\n  @param catalog a catalog name; \"\" retrieves those without a\n  catalog; null means drop catalog name from the selection criteria\n  @param schemaPattern a schema name pattern; \"\" retrieves those\n  without a schema\n  @param tableNamePattern a table name pattern\n  @param types a list of table types to include; null returns all types\n  @return <code>ResultSet</code> - each row is a table description\n  @see #getSearchStringEscape\n}\nfunction TZAdoDatabaseMetadata.UncachedGetTables(const Catalog: string;\n  const SchemaPattern: string; const TableNamePattern: string;\n  const Types: TStringDynArray): IZResultSet;\nvar\n  I: Integer;\n  TableTypes: string;\n  AdoRecordSet: ZPlainAdo.RecordSet;\nbegin\n    Result:=inherited UncachedGetTables(Catalog, SchemaPattern, TableNamePattern, Types);\n\n    for I := Low(Types) to High(Types) do\n    begin\n      if Length(TableTypes) > 0 then\n        TableTypes := TableTypes + ',';\n      TableTypes := TableTypes + Types[I];\n    end;\n\n    AdoRecordSet := AdoOpenSchema(adSchemaTables,\n      [Catalog, SchemaPattern, TableNamePattern, TableTypes]);\n    if Assigned(AdoRecordSet) then\n    begin\n      with TZAdoResultSet.Create(GetStatement, '', AdoRecordset) do\n      begin\n        while Next do\n        begin\n          Result.MoveToInsertRow;\n          Result.UpdateStringByName('TABLE_CAT',\n            GetStringByName('TABLE_CATALOG'));\n          Result.UpdateStringByName('TABLE_SCHEM',\n            GetStringByName('TABLE_SCHEMA'));\n          Result.UpdateStringByName('TABLE_NAME',\n            GetStringByName('TABLE_NAME'));\n          Result.UpdateStringByName('TABLE_TYPE',\n            GetStringByName('TABLE_TYPE'));\n          Result.UpdateStringByName('REMARKS',\n            GetStringByName('DESCRIPTION'));\n          Result.InsertRow;\n        end;\n        Close;\n        Free;\n      end;\n    end;\nend;\n\n{**\n  Gets the schema names available in this database.  The results\n  are ordered by schema name.\n\n  <P>The schema column is:\n   <OL>\n \t<LI><B>TABLE_SCHEM</B> String => schema name\n   </OL>\n\n  @return <code>ResultSet</code> - each row has a single String column that is a\n  schema name\n}\nfunction TZAdoDatabaseMetadata.UncachedGetSchemas: IZResultSet;\nvar\n  AdoRecordSet: ZPlainAdo.RecordSet;\nbegin\n    Result:=inherited UncachedGetSchemas;\n\n    AdoRecordSet := AdoOpenSchema(adSchemaSchemata, []);\n    if Assigned(AdoRecordSet) then\n    begin\n      with TZAdoResultSet.Create(GetStatement, '', AdoRecordSet) do\n      begin\n        while Next do\n        begin\n          Result.MoveToInsertRow;\n          Result.UpdateStringByName('TABLE_SCHEM',\n            GetStringByName('SCHEMA_NAME'));\n          Result.InsertRow;\n        end;\n        Close;\n        Free;\n      end;\n    end;\nend;\n\n{**\n  Gets the catalog names available in this database.  The results\n  are ordered by catalog name.\n\n  <P>The catalog column is:\n   <OL>\n \t<LI><B>TABLE_CAT</B> String => catalog name\n   </OL>\n\n  @return <code>ResultSet</code> - each row has a single String column that is a\n  catalog name\n}\nfunction TZAdoDatabaseMetadata.UncachedGetCatalogs: IZResultSet;\nvar\n  AdoRecordSet: ZPlainAdo.RecordSet;\nbegin\n    Result:=inherited UncachedGetCatalogs;\n\n    AdoRecordSet := AdoOpenSchema(adSchemaCatalogs, []);\n    if Assigned(AdoRecordSet) then\n    begin\n      with TZAdoResultSet.Create(GetStatement, '', AdoRecordSet) do\n      begin\n        while Next do\n        begin\n          Result.MoveToInsertRow;\n          Result.UpdateStringByName('TABLE_CAT',\n            GetStringByName('CATALOG_NAME'));\n          Result.InsertRow;\n        end;\n        Close;\n        Free;\n      end;\n    end;\nend;\n\n{**\n  Gets the table types available in this database.  The results\n  are ordered by table type.\n\n  <P>The table type is:\n   <OL>\n \t<LI><B>TABLE_TYPE</B> String => table type.  Typical types are \"TABLE\",\n \t\t\t\"VIEW\",\t\"SYSTEM TABLE\", \"GLOBAL TEMPORARY\",\n \t\t\t\"LOCAL TEMPORARY\", \"ALIAS\", \"SYNONYM\".\n   </OL>\n\n  @return <code>ResultSet</code> - each row has a single String column that is a\n  table type\n}\nfunction TZAdoDatabaseMetadata.UncachedGetTableTypes: IZResultSet;\nconst\n  TableTypes: array[0..7] of string = (\n    'ALIAS', 'TABLE', 'SYNONYM', 'SYSTEM TABLE', 'VIEW',\n    'GLOBAL TEMPORARY', 'LOCAL TEMPORARY', 'SYSTEM VIEW'\n  );\nvar\n  I: Integer;\nbegin\n    Result:=inherited UncachedGetTableTypes;\n\n    for I := 0 to 7 do\n    begin\n      Result.MoveToInsertRow;\n      Result.UpdateStringByName('TABLE_TYPE', TableTypes[I]);\n      Result.InsertRow;\n    end;\nend;\n\n{**\n  Gets a description of table columns available in\n  the specified catalog.\n\n  <P>Only column descriptions matching the catalog, schema, table\n  and column name criteria are returned.  They are ordered by\n  TABLE_SCHEM, TABLE_NAME and ORDINAL_POSITION.\n\n  <P>Each column description has the following columns:\n   <OL>\n \t<LI><B>TABLE_CAT</B> String => table catalog (may be null)\n \t<LI><B>TABLE_SCHEM</B> String => table schema (may be null)\n \t<LI><B>TABLE_NAME</B> String => table name\n \t<LI><B>COLUMN_NAME</B> String => column name\n \t<LI><B>DATA_TYPE</B> short => SQL type from java.sql.Types\n \t<LI><B>TYPE_NAME</B> String => Data source dependent type name,\n   for a UDT the type name is fully qualified\n \t<LI><B>COLUMN_SIZE</B> int => column size.  For char or date\n \t    types this is the maximum number of characters, for numeric or\n \t    decimal types this is precision.\n \t<LI><B>BUFFER_LENGTH</B> is not used.\n \t<LI><B>DECIMAL_DIGITS</B> int => the number of fractional digits\n \t<LI><B>NUM_PREC_RADIX</B> int => Radix (typically either 10 or 2)\n \t<LI><B>NULLABLE</B> int => is NULL allowed?\n       <UL>\n       <LI> columnNoNulls - might not allow NULL values\n       <LI> columnNullable - definitely allows NULL values\n       <LI> columnNullableUnknown - nullability unknown\n       </UL>\n \t<LI><B>REMARKS</B> String => comment describing column (may be null)\n  \t<LI><B>COLUMN_DEF</B> String => default value (may be null)\n \t<LI><B>SQL_DATA_TYPE</B> int => unused\n \t<LI><B>SQL_DATETIME_SUB</B> int => unused\n \t<LI><B>CHAR_OCTET_LENGTH</B> int => for char types the\n        maximum number of bytes in the column\n \t<LI><B>ORDINAL_POSITION</B> int\t=> index of column in table\n       (starting at 1)\n \t<LI><B>IS_NULLABLE</B> String => \"NO\" means column definitely\n       does not allow NULL values; \"YES\" means the column might\n       allow NULL values.  An empty string means nobody knows.\n   </OL>\n\n  @param catalog a catalog name; \"\" retrieves those without a\n  catalog; null means drop catalog name from the selection criteria\n  @param schemaPattern a schema name pattern; \"\" retrieves those\n  without a schema\n  @param tableNamePattern a table name pattern\n  @param columnNamePattern a column name pattern\n  @return <code>ResultSet</code> - each row is a column description\n  @see #getSearchStringEscape\n}\nfunction TZAdoDatabaseMetadata.UncachedGetColumns(const Catalog: string;\n  const SchemaPattern: string; const TableNamePattern: string;\n  const ColumnNamePattern: string): IZResultSet;\nvar\n  AdoRecordSet: ZPlainAdo.RecordSet;\n  Flags: Integer;\n  SQLType: TZSQLType;\nbegin\n  Result:=inherited UncachedGetColumns(Catalog, SchemaPattern,\n      TableNamePattern, ColumnNamePattern);\n\n    AdoRecordSet := AdoOpenSchema(adSchemaColumns,\n      [DecomposeObjectString(Catalog), DecomposeObjectString(SchemaPattern),\n      DecomposeObjectString(TableNamePattern), DecomposeObjectString(ColumnNamePattern)]);\n    if Assigned(AdoRecordSet) then\n    begin\n      AdoRecordSet.Sort := 'ORDINAL_POSITION';\n      with TZAdoResultSet.Create(GetStatement, '', AdoRecordSet) do\n      begin\n        while Next do\n        begin\n          Result.MoveToInsertRow;\n          Result.UpdateStringByName('TABLE_CAT',\n            GetStringByName('TABLE_CATALOG'));\n          Result.UpdateStringByName('TABLE_SCHEM',\n            GetStringByName('TABLE_SCHEMA'));\n          Result.UpdateStringByName('TABLE_NAME',\n            GetStringByName('TABLE_NAME'));\n          Result.UpdateStringByName('COLUMN_NAME',\n            GetStringByName('COLUMN_NAME'));\n\n          SQLType := ConvertAdoToSqlType(GetShortByName('DATA_TYPE'),\n            ConSettings.CPType);\n          Flags := GetIntByName('COLUMN_FLAGS');\n  //!!!If the field type is long then this is the only way to know it because it just returns string type\n          if ((Flags and DBCOLUMNFLAGS_ISLONG) <> 0 ) and (SQLType in [stBytes, stString, stUnicodeString]) then\n            case SQLType of\n              stBytes: SQLType := stBinaryStream;\n              stString: SQLType := stAsciiStream;\n              stUnicodeString: SQLType := stUnicodeStream;\n            end;\n          Result.UpdateShortByName('DATA_TYPE', Ord(SQLType));\n          Result.UpdateIntByName('COLUMN_SIZE',\n            GetIntByName('CHARACTER_MAXIMUM_LENGTH'));\n          Result.UpdateIntByName('BUFFER_LENGTH',\n            GetIntByName('CHARACTER_MAXIMUM_LENGTH'));\n          Result.UpdateIntByName('DECIMAL_DIGITS',\n            GetIntByName('NUMERIC_SCALE'));\n          Result.UpdateIntByName('NUM_PREC_RADIX',\n            GetShortByName('NUMERIC_PRECISION'));\n          if GetBooleanByName('IS_NULLABLE') then\n            Result.UpdateShortByName('NULLABLE', 1)\n          else\n            Result.UpdateShortByName('NULLABLE', 0);\n          Result.UpdateStringByName('REMARKS',\n            GetStringByName('DESCRIPTION'));\n          Result.UpdateStringByName('COLUMN_DEF',\n            GetStringByName('COLUMN_DEFAULT'));\n          Result.UpdateShortByName('SQL_DATETIME_SUB',\n            GetShortByName('DATETIME_PRECISION'));\n          Result.UpdateIntByName('CHAR_OCTET_LENGTH',\n            GetIntByName('CHARACTER_OCTET_LENGTH'));\n          Result.UpdateIntByName('ORDINAL_POSITION',\n            GetIntByName('ORDINAL_POSITION'));\n          if UpperCase(GetStringByName('IS_NULLABLE')) = 'FALSE' then\n            Result.UpdateStringByName('IS_NULLABLE', 'NO')\n          else\n            Result.UpdateStringByName('IS_NULLABLE', 'YES');\n\n          Result.UpdateBooleanByName('WRITABLE',\n            (Flags and (DBCOLUMNFLAGS_WRITE or DBCOLUMNFLAGS_WRITEUNKNOWN) <> 0));\n\n          Result.UpdateBooleanByName('DEFINITELYWRITABLE',\n            (Flags and (DBCOLUMNFLAGS_WRITE) <> 0));\n          Result.UpdateBooleanByName('READONLY',\n            (Flags and (DBCOLUMNFLAGS_WRITE or DBCOLUMNFLAGS_WRITEUNKNOWN) = 0));\n          Result.UpdateBooleanByName('SEARCHABLE',\n            (Flags and (DBCOLUMNFLAGS_ISLONG) = 0));\n          Result.UpdateNullByName('AUTO_INCREMENT');\n          Result.InsertRow;\n        end;\n        Close;\n        Free;\n      end;\n    end;\nend;\n\n{**\n  Gets a description of the access rights for a table's columns.\n\n  <P>Only privileges matching the column name criteria are\n  returned.  They are ordered by COLUMN_NAME and PRIVILEGE.\n\n  <P>Each privilige description has the following columns:\n   <OL>\n \t<LI><B>TABLE_CAT</B> String => table catalog (may be null)\n \t<LI><B>TABLE_SCHEM</B> String => table schema (may be null)\n \t<LI><B>TABLE_NAME</B> String => table name\n \t<LI><B>COLUMN_NAME</B> String => column name\n \t<LI><B>GRANTOR</B> => grantor of access (may be null)\n \t<LI><B>GRANTEE</B> String => grantee of access\n \t<LI><B>PRIVILEGE</B> String => name of access (SELECT,\n       INSERT, UPDATE, REFRENCES, ...)\n \t<LI><B>IS_GRANTABLE</B> String => \"YES\" if grantee is permitted\n       to grant to others; \"NO\" if not; null if unknown\n   </OL>\n\n  @param catalog a catalog name; \"\" retrieves those without a\n  catalog; null means drop catalog name from the selection criteria\n  @param schema a schema name; \"\" retrieves those without a schema\n  @param table a table name\n  @param columnNamePattern a column name pattern\n  @return <code>ResultSet</code> - each row is a column privilege description\n  @see #getSearchStringEscape\n}\nfunction TZAdoDatabaseMetadata.UncachedGetColumnPrivileges(const Catalog: string;\n  const Schema: string; const Table: string; const ColumnNamePattern: string): IZResultSet;\nvar\n  AdoRecordSet: ZPlainAdo.RecordSet;\nbegin\n  Result:=inherited UncachedGetColumnPrivileges(Catalog, Schema, Table, ColumnNamePattern);\n\n    AdoRecordSet := AdoOpenSchema(adSchemaColumnPrivileges,\n      [Catalog, Schema, Table, ColumnNamePattern]);\n    if Assigned(AdoRecordSet) then\n    begin\n      with TZAdoResultSet.Create(GetStatement, '', AdoRecordSet) do\n      begin\n        while Next do\n        begin\n          Result.MoveToInsertRow;\n          Result.UpdateStringByName('TABLE_CAT',\n            GetStringByName('TABLE_CATALOG'));\n          Result.UpdateStringByName('TABLE_SCHEM',\n            GetStringByName('TABLE_SCHEMA'));\n          Result.UpdateStringByName('TABLE_NAME',\n            GetStringByName('TABLE_NAME'));\n          Result.UpdateStringByName('COLUMN_NAME',\n            GetStringByName('COLUMN_NAME'));\n          Result.UpdateStringByName('GRANTOR',\n            GetStringByName('GRANTOR'));\n          Result.UpdateStringByName('GRANTEE',\n            GetStringByName('GRANTEE'));\n          Result.UpdateStringByName('PRIVILEGE',\n            GetStringByName('PRIVILEGE_TYPE'));\n          if GetBooleanByName('IS_GRANTABLE') then\n            Result.UpdateStringByName('IS_GRANTABLE', 'YES')\n          else\n            Result.UpdateStringByName('IS_GRANTABLE', 'NO');\n          Result.InsertRow;\n        end;\n        Close;\n        Free;\n      end;\n    end;\nend;\n\n{**\n  Gets a description of the access rights for each table available\n  in a catalog. Note that a table privilege applies to one or\n  more columns in the table. It would be wrong to assume that\n  this priviledge applies to all columns (this may be true for\n  some systems but is not true for all.)\n\n  <P>Only privileges matching the schema and table name\n  criteria are returned.  They are ordered by TABLE_SCHEM,\n  TABLE_NAME, and PRIVILEGE.\n\n  <P>Each privilige description has the following columns:\n   <OL>\n \t<LI><B>TABLE_CAT</B> String => table catalog (may be null)\n \t<LI><B>TABLE_SCHEM</B> String => table schema (may be null)\n \t<LI><B>TABLE_NAME</B> String => table name\n \t<LI><B>GRANTOR</B> => grantor of access (may be null)\n \t<LI><B>GRANTEE</B> String => grantee of access\n \t<LI><B>PRIVILEGE</B> String => name of access (SELECT,\n       INSERT, UPDATE, REFRENCES, ...)\n \t<LI><B>IS_GRANTABLE</B> String => \"YES\" if grantee is permitted\n       to grant to others; \"NO\" if not; null if unknown\n   </OL>\n\n  @param catalog a catalog name; \"\" retrieves those without a\n  catalog; null means drop catalog name from the selection criteria\n  @param schemaPattern a schema name pattern; \"\" retrieves those\n  without a schema\n  @param tableNamePattern a table name pattern\n  @return <code>ResultSet</code> - each row is a table privilege description\n  @see #getSearchStringEscape\n}\nfunction TZAdoDatabaseMetadata.UncachedGetTablePrivileges(const Catalog: string;\n  const SchemaPattern: string; const TableNamePattern: string): IZResultSet;\nvar\n  AdoRecordSet: ZPlainAdo.RecordSet;\nbegin\n  Result:=inherited UncachedGetTablePrivileges(Catalog, SchemaPattern, TableNamePattern);\n\n    AdoRecordSet := AdoOpenSchema(adSchemaTablePrivileges,\n      [Catalog, SchemaPattern, TableNamePattern]);\n    if Assigned(AdoRecordSet) then\n    begin\n      with TZAdoResultSet.Create(GetStatement, '', AdoRecordSet) do\n      begin\n        while Next do\n        begin\n          Result.MoveToInsertRow;\n          Result.UpdateStringByName('TABLE_CAT',\n            GetStringByName('TABLE_CATALOG'));\n          Result.UpdateStringByName('TABLE_SCHEM',\n            GetStringByName('TABLE_SCHEMA'));\n          Result.UpdateStringByName('TABLE_NAME',\n            GetStringByName('TABLE_NAME'));\n          Result.UpdateStringByName('GRANTOR',\n            GetStringByName('GRANTOR'));\n          Result.UpdateStringByName('GRANTEE',\n            GetStringByName('GRANTEE'));\n          Result.UpdateStringByName('PRIVILEGE',\n            GetStringByName('PRIVILEGE_TYPE'));\n          if GetBooleanByName('IS_GRANTABLE') then\n            Result.UpdateStringByName('IS_GRANTABLE', 'YES')\n          else Result.UpdateStringByName('IS_GRANTABLE', 'NO');\n          Result.InsertRow;\n        end;\n        Close;\n        Free;\n      end;\n    end;\nend;\n\n{**\n  Gets a description of a table's columns that are automatically\n  updated when any value in a row is updated.  They are\n  unordered.\n\n  <P>Each column description has the following columns:\n   <OL>\n \t<LI><B>SCOPE</B> short => is not used\n \t<LI><B>COLUMN_NAME</B> String => column name\n \t<LI><B>DATA_TYPE</B> short => SQL data type from java.sql.Types\n \t<LI><B>TYPE_NAME</B> String => Data source dependent type name\n \t<LI><B>COLUMN_SIZE</B> int => precision\n \t<LI><B>BUFFER_LENGTH</B> int => length of column value in bytes\n \t<LI><B>DECIMAL_DIGITS</B> short\t => scale\n \t<LI><B>PSEUDO_COLUMN</B> short => is this a pseudo column\n       like an Oracle ROWID\n       <UL>\n       <LI> versionColumnUnknown - may or may not be pseudo column\n       <LI> versionColumnNotPseudo - is NOT a pseudo column\n       <LI> versionColumnPseudo - is a pseudo column\n       </UL>\n   </OL>\n\n  @param catalog a catalog name; \"\" retrieves those without a\n  catalog; null means drop catalog name from the selection criteria\n  @param schema a schema name; \"\" retrieves those without a schema\n  @param table a table name\n  @return <code>ResultSet</code> - each row is a column description\n  @exception SQLException if a database access error occurs\n}\nfunction TZAdoDatabaseMetadata.UncachedGetVersionColumns(const Catalog: string;\n  const Schema: string; const Table: string): IZResultSet;\nconst\n  DBCOLUMNFLAGS_ISROWVER = $00000200;\nvar\n  AdoRecordSet: ZPlainAdo.RecordSet;\nbegin\n    Result:=inherited UncachedGetVersionColumns(Catalog, Schema, Table);\n\n    AdoRecordSet := AdoOpenSchema(adSchemaColumns, [Catalog, Schema, Table]);\n    if Assigned(AdoRecordSet) then\n    begin\n      with TZAdoResultSet.Create(GetStatement, '', AdoRecordSet) do\n      begin\n        while Next do\n        begin\n          if (GetIntByName('COLUMN_FLAGS')\n            and DBCOLUMNFLAGS_ISROWVER) = 0 then\n            Continue;\n          Result.MoveToInsertRow;\n          Result.UpdateShortByName('SCOPE', 0);\n          Result.UpdateStringByName('COLUMN_NAME',\n            GetStringByName('COLUMN_NAME'));\n          Result.UpdateShortByName('DATA_TYPE',\n            Ord(ConvertAdoToSqlType(GetShortByName('DATA_TYPE'),\n              ConSettings.CPType)));\n          Result.UpdateStringByName('TYPE_NAME',\n            GetStringByName('TYPE_NAME'));\n          Result.UpdateIntByName('COLUMN_SIZE',\n            GetIntByName('CHARACTER_OCTET_LENGTH'));\n          Result.UpdateIntByName('BUFFER_LENGTH',\n            GetIntByName('CHARACTER_OCTET_LENGTH'));\n          Result.UpdateIntByName('DECIMAL_DIGITS',\n            GetIntByName('NUMERIC_SCALE'));\n          Result.UpdateShortByName('PSEUDO_COLUMN', 0);\n          Result.InsertRow;\n        end;\n        Close;\n        Free;\n      end;\n    end;\nend;\n\n{**\n  Gets a description of a table's primary key columns.  They\n  are ordered by COLUMN_NAME.\n\n  <P>Each primary key column description has the following columns:\n   <OL>\n \t<LI><B>TABLE_CAT</B> String => table catalog (may be null)\n \t<LI><B>TABLE_SCHEM</B> String => table schema (may be null)\n \t<LI><B>TABLE_NAME</B> String => table name\n \t<LI><B>COLUMN_NAME</B> String => column name\n \t<LI><B>KEY_SEQ</B> short => sequence number within primary key\n \t<LI><B>PK_NAME</B> String => primary key name (may be null)\n   </OL>\n\n  @param catalog a catalog name; \"\" retrieves those without a\n  catalog; null means drop catalog name from the selection criteria\n  @param schema a schema name; \"\" retrieves those\n  without a schema\n  @param table a table name\n  @return <code>ResultSet</code> - each row is a primary key column description\n  @exception SQLException if a database access error occurs\n}\nfunction TZAdoDatabaseMetadata.UncachedGetPrimaryKeys(const Catalog: string;\n  const Schema: string; const Table: string): IZResultSet;\nvar\n  AdoRecordSet: ZPlainAdo.RecordSet;\nbegin\n    Result:=inherited UncachedGetPrimaryKeys(Catalog, Schema, Table);\n\n    AdoRecordSet := AdoOpenSchema(adSchemaPrimaryKeys,\n      [Catalog, Schema, Table]);\n    if Assigned(AdoRecordSet) then\n    begin\n      with TZAdoResultSet.Create(GetStatement, '', AdoRecordSet) do\n      begin\n        while Next do\n        begin\n          Result.MoveToInsertRow;\n          Result.UpdateStringByName('TABLE_CAT',\n            GetStringByName('TABLE_CATALOG'));\n          Result.UpdateStringByName('TABLE_SCHEM',\n            GetStringByName('TABLE_SCHEMA'));\n          Result.UpdateStringByName('TABLE_NAME',\n            GetStringByName('TABLE_NAME'));\n          Result.UpdateStringByName('COLUMN_NAME',\n            GetStringByName('COLUMN_NAME'));\n          Result.UpdateShortByName('KEY_SEQ',\n            GetShortByName('ORDINAL'));\n          if FindColumn('PK_NAME') >= 1 then\n          begin\n            Result.UpdateStringByName('PK_NAME',\n              GetStringByName('PK_NAME'));\n          end;\n          Result.InsertRow;\n        end;\n        Close;\n        Free;\n      end;\n    end;\nend;\n\n{**\n  Gets a description of the primary key columns that are\n  referenced by a table's foreign key columns (the primary keys\n  imported by a table).  They are ordered by PKTABLE_CAT,\n  PKTABLE_SCHEM, PKTABLE_NAME, and KEY_SEQ.\n\n  <P>Each primary key column description has the following columns:\n   <OL>\n \t<LI><B>PKTABLE_CAT</B> String => primary key table catalog\n       being imported (may be null)\n \t<LI><B>PKTABLE_SCHEM</B> String => primary key table schema\n       being imported (may be null)\n \t<LI><B>PKTABLE_NAME</B> String => primary key table name\n       being imported\n \t<LI><B>PKCOLUMN_NAME</B> String => primary key column name\n       being imported\n \t<LI><B>FKTABLE_CAT</B> String => foreign key table catalog (may be null)\n \t<LI><B>FKTABLE_SCHEM</B> String => foreign key table schema (may be null)\n \t<LI><B>FKTABLE_NAME</B> String => foreign key table name\n \t<LI><B>FKCOLUMN_NAME</B> String => foreign key column name\n \t<LI><B>KEY_SEQ</B> short => sequence number within foreign key\n \t<LI><B>UPDATE_RULE</B> short => What happens to\n        foreign key when primary is updated:\n       <UL>\n       <LI> importedNoAction - do not allow update of primary\n                key if it has been imported\n       <LI> importedKeyCascade - change imported key to agree\n                with primary key update\n       <LI> importedKeySetNull - change imported key to NULL if\n                its primary key has been updated\n       <LI> importedKeySetDefault - change imported key to default values\n                if its primary key has been updated\n       <LI> importedKeyRestrict - same as importedKeyNoAction\n                                  (for ODBC 2.x compatibility)\n       </UL>\n \t<LI><B>DELETE_RULE</B> short => What happens to\n       the foreign key when primary is deleted.\n       <UL>\n       <LI> importedKeyNoAction - do not allow delete of primary\n                key if it has been imported\n       <LI> importedKeyCascade - delete rows that import a deleted key\n       <LI> importedKeySetNull - change imported key to NULL if\n                its primary key has been deleted\n       <LI> importedKeyRestrict - same as importedKeyNoAction\n                                  (for ODBC 2.x compatibility)\n       <LI> importedKeySetDefault - change imported key to default if\n                its primary key has been deleted\n       </UL>\n \t<LI><B>FK_NAME</B> String => foreign key name (may be null)\n \t<LI><B>PK_NAME</B> String => primary key name (may be null)\n \t<LI><B>DEFERRABILITY</B> short => can the evaluation of foreign key\n       constraints be deferred until commit\n       <UL>\n       <LI> importedKeyInitiallyDeferred - see SQL92 for definition\n       <LI> importedKeyInitiallyImmediate - see SQL92 for definition\n       <LI> importedKeyNotDeferrable - see SQL92 for definition\n       </UL>\n   </OL>\n\n  @param catalog a catalog name; \"\" retrieves those without a\n  catalog; null means drop catalog name from the selection criteria\n  @param schema a schema name; \"\" retrieves those\n  without a schema\n  @param table a table name\n  @return <code>ResultSet</code> - each row is a primary key column description\n  @see #getExportedKeys\n}\nfunction TZAdoDatabaseMetadata.UncachedGetImportedKeys(const Catalog: string;\n  const Schema: string; const Table: string): IZResultSet;\nbegin\n  Result := UncachedGetCrossReference('', '', '', Catalog, Schema, Table);\nend;\n\n{**\n  Gets a description of the foreign key columns that reference a\n  table's primary key columns (the foreign keys exported by a\n  table).  They are ordered by FKTABLE_CAT, FKTABLE_SCHEM,\n  FKTABLE_NAME, and KEY_SEQ.\n\n  <P>Each foreign key column description has the following columns:\n   <OL>\n \t<LI><B>PKTABLE_CAT</B> String => primary key table catalog (may be null)\n \t<LI><B>PKTABLE_SCHEM</B> String => primary key table schema (may be null)\n \t<LI><B>PKTABLE_NAME</B> String => primary key table name\n \t<LI><B>PKCOLUMN_NAME</B> String => primary key column name\n \t<LI><B>FKTABLE_CAT</B> String => foreign key table catalog (may be null)\n       being exported (may be null)\n \t<LI><B>FKTABLE_SCHEM</B> String => foreign key table schema (may be null)\n       being exported (may be null)\n \t<LI><B>FKTABLE_NAME</B> String => foreign key table name\n       being exported\n \t<LI><B>FKCOLUMN_NAME</B> String => foreign key column name\n       being exported\n \t<LI><B>KEY_SEQ</B> short => sequence number within foreign key\n \t<LI><B>UPDATE_RULE</B> short => What happens to\n        foreign key when primary is updated:\n       <UL>\n       <LI> importedNoAction - do not allow update of primary\n                key if it has been imported\n       <LI> importedKeyCascade - change imported key to agree\n                with primary key update\n       <LI> importedKeySetNull - change imported key to NULL if\n                its primary key has been updated\n       <LI> importedKeySetDefault - change imported key to default values\n                if its primary key has been updated\n       <LI> importedKeyRestrict - same as importedKeyNoAction\n                                  (for ODBC 2.x compatibility)\n       </UL>\n \t<LI><B>DELETE_RULE</B> short => What happens to\n       the foreign key when primary is deleted.\n       <UL>\n       <LI> importedKeyNoAction - do not allow delete of primary\n                key if it has been imported\n       <LI> importedKeyCascade - delete rows that import a deleted key\n       <LI> importedKeySetNull - change imported key to NULL if\n                its primary key has been deleted\n       <LI> importedKeyRestrict - same as importedKeyNoAction\n                                  (for ODBC 2.x compatibility)\n       <LI> importedKeySetDefault - change imported key to default if\n                its primary key has been deleted\n       </UL>\n \t<LI><B>FK_NAME</B> String => foreign key name (may be null)\n \t<LI><B>PK_NAME</B> String => primary key name (may be null)\n \t<LI><B>DEFERRABILITY</B> short => can the evaluation of foreign key\n       constraints be deferred until commit\n       <UL>\n       <LI> importedKeyInitiallyDeferred - see SQL92 for definition\n       <LI> importedKeyInitiallyImmediate - see SQL92 for definition\n       <LI> importedKeyNotDeferrable - see SQL92 for definition\n       </UL>\n   </OL>\n\n  @param catalog a catalog name; \"\" retrieves those without a\n  catalog; null means drop catalog name from the selection criteria\n  @param schema a schema name; \"\" retrieves those\n  without a schema\n  @param table a table name\n  @return <code>ResultSet</code> - each row is a foreign key column description\n  @see #getImportedKeys\n}\nfunction TZAdoDatabaseMetadata.UncachedGetExportedKeys(const Catalog: string;\n  const Schema: string; const Table: string): IZResultSet;\nbegin\n  Result := UncachedGetCrossReference(Catalog, Schema, Table, '', '', '');\nend;\n\n{**\n  Gets a description of the foreign key columns in the foreign key\n  table that reference the primary key columns of the primary key\n  table (describe how one table imports another's key.) This\n  should normally return a single foreign key/primary key pair\n  (most tables only import a foreign key from a table once.)  They\n  are ordered by FKTABLE_CAT, FKTABLE_SCHEM, FKTABLE_NAME, and\n  KEY_SEQ.\n\n  <P>Each foreign key column description has the following columns:\n   <OL>\n \t<LI><B>PKTABLE_CAT</B> String => primary key table catalog (may be null)\n \t<LI><B>PKTABLE_SCHEM</B> String => primary key table schema (may be null)\n \t<LI><B>PKTABLE_NAME</B> String => primary key table name\n \t<LI><B>PKCOLUMN_NAME</B> String => primary key column name\n \t<LI><B>FKTABLE_CAT</B> String => foreign key table catalog (may be null)\n       being exported (may be null)\n \t<LI><B>FKTABLE_SCHEM</B> String => foreign key table schema (may be null)\n       being exported (may be null)\n \t<LI><B>FKTABLE_NAME</B> String => foreign key table name\n       being exported\n \t<LI><B>FKCOLUMN_NAME</B> String => foreign key column name\n       being exported\n \t<LI><B>KEY_SEQ</B> short => sequence number within foreign key\n \t<LI><B>UPDATE_RULE</B> short => What happens to\n        foreign key when primary is updated:\n       <UL>\n       <LI> importedNoAction - do not allow update of primary\n                key if it has been imported\n       <LI> importedKeyCascade - change imported key to agree\n                with primary key update\n       <LI> importedKeySetNull - change imported key to NULL if\n                its primary key has been updated\n       <LI> importedKeySetDefault - change imported key to default values\n                if its primary key has been updated\n       <LI> importedKeyRestrict - same as importedKeyNoAction\n                                  (for ODBC 2.x compatibility)\n       </UL>\n \t<LI><B>DELETE_RULE</B> short => What happens to\n       the foreign key when primary is deleted.\n       <UL>\n       <LI> importedKeyNoAction - do not allow delete of primary\n                key if it has been imported\n       <LI> importedKeyCascade - delete rows that import a deleted key\n       <LI> importedKeySetNull - change imported key to NULL if\n                its primary key has been deleted\n       <LI> importedKeyRestrict - same as importedKeyNoAction\n                                  (for ODBC 2.x compatibility)\n       <LI> importedKeySetDefault - change imported key to default if\n                its primary key has been deleted\n       </UL>\n \t<LI><B>FK_NAME</B> String => foreign key name (may be null)\n \t<LI><B>PK_NAME</B> String => primary key name (may be null)\n \t<LI><B>DEFERRABILITY</B> short => can the evaluation of foreign key\n       constraints be deferred until commit\n       <UL>\n       <LI> importedKeyInitiallyDeferred - see SQL92 for definition\n       <LI> importedKeyInitiallyImmediate - see SQL92 for definition\n       <LI> importedKeyNotDeferrable - see SQL92 for definition\n       </UL>\n   </OL>\n\n  @param primaryCatalog a catalog name; \"\" retrieves those without a\n  catalog; null means drop catalog name from the selection criteria\n  @param primarySchema a schema name; \"\" retrieves those\n  without a schema\n  @param primaryTable the table name that exports the key\n  @param foreignCatalog a catalog name; \"\" retrieves those without a\n  catalog; null means drop catalog name from the selection criteria\n  @param foreignSchema a schema name; \"\" retrieves those\n  without a schema\n  @param foreignTable the table name that imports the key\n  @return <code>ResultSet</code> - each row is a foreign key column description\n  @see #getImportedKeys\n}\nfunction TZAdoDatabaseMetadata.UncachedGetCrossReference(const PrimaryCatalog: string;\n  const PrimarySchema: string; const PrimaryTable: string; const ForeignCatalog: string;\n  const ForeignSchema: string; const ForeignTable: string): IZResultSet;\nvar\n  AdoRecordSet: ZPlainAdo.RecordSet;\n\n  function GetRuleType(const Rule: String): TZImportedKey;\n  begin\n    if Rule = 'RESTRICT' then\n      Result := ikRestrict\n    else if Rule = 'NO ACTION' then\n      Result := ikNoAction\n    else if Rule = 'CASCADE' then\n      Result := ikCascade\n    else if Rule = 'SET DEFAULT' then\n      Result := ikSetDefault\n    else if Rule = 'SET NULL' then\n      Result := ikSetNull\n    else\n      Result := ikNotDeferrable; //impossible!\n  end;\nbegin\n    Result:=inherited UncachedGetCrossReference(PrimaryCatalog, PrimarySchema, PrimaryTable,\n                                                ForeignCatalog, ForeignSchema, ForeignTable);\n\n    AdoRecordSet := AdoOpenSchema(adSchemaForeignKeys,\n      [PrimaryCatalog, PrimarySchema, PrimaryTable,\n      ForeignCatalog, ForeignSchema, ForeignTable]);\n    if Assigned(AdoRecordSet) then\n    begin\n      with TZAdoResultSet.Create(GetStatement, '', AdoRecordSet) do\n      begin\n        while Next do\n        begin\n          Result.MoveToInsertRow;\n          Result.UpdateStringByName('PKTABLE_CAT',\n            GetStringByName('PK_TABLE_CATALOG'));\n          Result.UpdateStringByName('PKTABLE_SCHEM',\n            GetStringByName('PK_TABLE_SCHEMA'));\n          Result.UpdateStringByName('PKTABLE_NAME',\n            GetStringByName('PK_TABLE_NAME'));\n          Result.UpdateStringByName('PKCOLUMN_NAME',\n            GetStringByName('PK_COLUMN_NAME'));\n          Result.UpdateStringByName('FKTABLE_CAT',\n            GetStringByName('FK_TABLE_CATALOG'));\n          Result.UpdateStringByName('FKTABLE_SCHEM',\n            GetStringByName('FK_TABLE_SCHEMA'));\n          Result.UpdateStringByName('FKTABLE_NAME',\n            GetStringByName('FK_TABLE_NAME'));\n          Result.UpdateStringByName('FKCOLUMN_NAME',\n            GetStringByName('FK_COLUMN_NAME'));\n          Result.UpdateShortByName('KEY_SEQ',\n            GetShortByName('ORDINAL'));\n          Result.UpdateShortByName('UPDATE_RULE',\n            Ord(GetRuleType(GetStringByName('UPDATE_RULE'))));\n          Result.UpdateShortByName('DELETE_RULE',\n            Ord(GetRuleType(GetStringByName('DELETE_RULE'))));\n          Result.UpdateStringByName('FK_NAME',\n            GetStringByName('FK_NAME'));\n          Result.UpdateStringByName('PK_NAME',\n            GetStringByName('PK_NAME'));\n          Result.UpdateIntByName('DEFERRABILITY',\n            GetShortByName('DEFERRABILITY'));\n          Result.InsertRow;\n        end;\n        Close;\n        Free;\n      end;\n    end;\nend;\n\n{**\n  Gets a description of all the standard SQL types supported by\n  this database. They are ordered by DATA_TYPE and then by how\n  closely the data type maps to the corresponding JDBC SQL type.\n\n  <P>Each type description has the following columns:\n   <OL>\n \t<LI><B>TYPE_NAME</B> String => Type name\n \t<LI><B>DATA_TYPE</B> short => SQL data type from java.sql.Types\n \t<LI><B>PRECISION</B> int => maximum precision\n \t<LI><B>LITERAL_PREFIX</B> String => prefix used to quote a literal\n       (may be null)\n \t<LI><B>LITERAL_SUFFIX</B> String => suffix used to quote a literal\n        (may be null)\n \t<LI><B>CREATE_PARAMS</B> String => parameters used in creating\n       the type (may be null)\n \t<LI><B>NULLABLE</B> short => can you use NULL for this type?\n       <UL>\n       <LI> typeNoNulls - does not allow NULL values\n       <LI> typeNullable - allows NULL values\n       <LI> typeNullableUnknown - nullability unknown\n       </UL>\n \t<LI><B>CASE_SENSITIVE</B> boolean=> is it case sensitive?\n \t<LI><B>SEARCHABLE</B> short => can you use \"WHERE\" based on this type:\n       <UL>\n       <LI> typePredNone - No support\n       <LI> typePredChar - Only supported with WHERE .. LIKE\n       <LI> typePredBasic - Supported except for WHERE .. LIKE\n       <LI> typeSearchable - Supported for all WHERE ..\n       </UL>\n \t<LI><B>UNSIGNED_ATTRIBUTE</B> boolean => is it unsigned?\n \t<LI><B>FIXED_PREC_SCALE</B> boolean => can it be a money value?\n \t<LI><B>AUTO_INCREMENT</B> boolean => can it be used for an\n       auto-increment value?\n \t<LI><B>LOCAL_TYPE_NAME</B> String => localized version of type name\n       (may be null)\n \t<LI><B>MINIMUM_SCALE</B> short => minimum scale supported\n \t<LI><B>MAXIMUM_SCALE</B> short => maximum scale supported\n \t<LI><B>SQL_DATA_TYPE</B> int => unused\n \t<LI><B>SQL_DATETIME_SUB</B> int => unused\n \t<LI><B>NUM_PREC_RADIX</B> int => usually 2 or 10\n   </OL>\n\n  @return <code>ResultSet</code> - each row is an SQL type description\n}\nfunction TZAdoDatabaseMetadata.UncachedGetTypeInfo: IZResultSet;\nvar\n  AdoRecordSet: ZPlainAdo.RecordSet;\nbegin\n    Result:=inherited UncachedGetTypeInfo;\n\n    AdoRecordSet := AdoOpenSchema(adSchemaProviderTypes, []);\n    if Assigned(AdoRecordSet) then\n    begin\n      with TZAdoResultSet.Create(GetStatement, '', AdoRecordSet) do\n      begin\n        while Next do\n        begin\n          Result.MoveToInsertRow;\n          Result.UpdateStringByName('TYPE_NAME',\n            GetStringByName('TYPE_NAME'));\n          Result.UpdateShortByName('DATA_TYPE',\n            Ord(ConvertAdoToSqlType(GetShortByName('DATA_TYPE'),\n              ConSettings.CPType)));\n          Result.UpdateIntByName('PRECISION',\n            0);//GetIntByName('PRECISION'));\n          Result.UpdateStringByName('LITERAL_PREFIX',\n            GetStringByName('LITERAL_PREFIX'));\n          Result.UpdateStringByName('LITERAL_SUFFIX',\n            GetStringByName('LITERAL_SUFFIX'));\n          Result.UpdateStringByName('CREATE_PARAMS',\n            GetStringByName('CREATE_PARAMS'));\n          if GetBooleanByName('IS_NULLABLE') then\n            Result.UpdateShortByName('NULLABLE', 1)\n          else\n            Result.UpdateShortByName('NULLABLE', 0);\n          Result.UpdateBooleanByName('CASE_SENSITIVE',\n            GetBooleanByName('CASE_SENSITIVE'));\n          Result.UpdateShortByName('SEARCHABLE',\n            GetShortByName('SEARCHABLE'));\n          Result.UpdateBooleanByName('UNSIGNED_ATTRIBUTE',\n            GetBooleanByName('UNSIGNED_ATTRIBUTE'));\n          Result.UpdateBooleanByName('FIXED_PREC_SCALE',\n            GetBooleanByName('FIXED_PREC_SCALE'));\n          Result.UpdateBooleanByName('AUTO_INCREMENT', False);\n          Result.UpdateStringByName('LOCAL_TYPE_NAME',\n            GetStringByName('LOCAL_TYPE_NAME'));\n          Result.UpdateShortByName('MINIMUM_SCALE',\n            GetShortByName('MINIMUM_SCALE'));\n          Result.UpdateShortByName('MAXIMUM_SCALE',\n            GetShortByName('MAXIMUM_SCALE'));\n    //      Result.UpdateShortByName('SQL_DATA_TYPE',\n    //        GetShortByName('SQL_DATA_TYPE'));\n    //      Result.UpdateShortByName('SQL_DATETIME_SUB',\n    //        GetShortByName('SQL_DATETIME_SUB'));\n    //      Result.UpdateShortByName('NUM_PREC_RADIX',\n    //        GetShortByName('NUM_PREC_RADIX'));\n          Result.InsertRow;\n        end;\n        Close;\n        Free;\n      end;\n    end;\nend;\n\n{**\n  Gets a description of a table's indices and statistics. They are\n  ordered by NON_UNIQUE, TYPE, INDEX_NAME, and ORDINAL_POSITION.\n\n  <P>Each index column description has the following columns:\n   <OL>\n \t<LI><B>TABLE_CAT</B> String => table catalog (may be null)\n \t<LI><B>TABLE_SCHEM</B> String => table schema (may be null)\n \t<LI><B>TABLE_NAME</B> String => table name\n \t<LI><B>NON_UNIQUE</B> boolean => Can index values be non-unique?\n       false when TYPE is tableIndexStatistic\n \t<LI><B>INDEX_QUALIFIER</B> String => index catalog (may be null);\n       null when TYPE is tableIndexStatistic\n \t<LI><B>INDEX_NAME</B> String => index name; null when TYPE is\n       tableIndexStatistic\n \t<LI><B>TYPE</B> short => index type:\n       <UL>\n       <LI> tableIndexStatistic - this identifies table statistics that are\n            returned in conjuction with a table's index descriptions\n       <LI> tableIndexClustered - this is a clustered index\n       <LI> tableIndexHashed - this is a hashed index\n       <LI> tableIndexOther - this is some other style of index\n       </UL>\n \t<LI><B>ORDINAL_POSITION</B> short => column sequence number\n       within index; zero when TYPE is tableIndexStatistic\n \t<LI><B>COLUMN_NAME</B> String => column name; null when TYPE is\n       tableIndexStatistic\n \t<LI><B>ASC_OR_DESC</B> String => column sort sequence, \"A\" => ascending,\n       \"D\" => descending, may be null if sort sequence is not supported;\n       null when TYPE is tableIndexStatistic\n \t<LI><B>CARDINALITY</B> int => When TYPE is tableIndexStatistic, then\n       this is the number of rows in the table; otherwise, it is the\n       number of unique values in the index.\n \t<LI><B>PAGES</B> int => When TYPE is  tableIndexStatisic then\n       this is the number of pages used for the table, otherwise it\n       is the number of pages used for the current index.\n \t<LI><B>FILTER_CONDITION</B> String => Filter condition, if any.\n       (may be null)\n   </OL>\n\n  @param catalog a catalog name; \"\" retrieves those without a\n  catalog; null means drop catalog name from the selection criteria\n  @param schema a schema name; \"\" retrieves those without a schema\n  @param table a table name\n  @param unique when true, return only indices for unique values;\n      when false, return indices regardless of whether unique or not\n  @param approximate when true, result is allowed to reflect approximate\n      or out of data values; when false, results are requested to be\n      accurate\n  @return <code>ResultSet</code> - each row is an index column description\n}\nfunction TZAdoDatabaseMetadata.UncachedGetIndexInfo(const Catalog: string;\n  const Schema: string; const Table: string; Unique: Boolean;\n  Approximate: Boolean): IZResultSet;\nvar\n  AdoRecordSet: ZPlainAdo.RecordSet;\nbegin\n    Result:=inherited UncachedGetIndexInfo(Catalog, Schema, Table, Unique, Approximate);\n\n    AdoRecordSet := AdoOpenSchema(adSchemaIndexes,\n      [Catalog, Schema, '', '', Table]);\n    if Assigned(AdoRecordSet) then\n    begin\n      with TZAdoResultSet.Create(GetStatement, '', AdoRecordSet) do\n      begin\n        while Next do\n        begin\n          Result.MoveToInsertRow;\n          Result.UpdateStringByName('TABLE_CAT',\n            GetStringByName('TABLE_CATALOG'));\n          Result.UpdateStringByName('TABLE_SCHEM',\n            GetStringByName('TABLE_SCHEMA'));\n          Result.UpdateStringByName('TABLE_NAME',\n            GetStringByName('TABLE_NAME'));\n          Result.UpdateBooleanByName('NON_UNIQUE',\n            not GetBooleanByName('UNIQUE'));\n          Result.UpdateStringByName('INDEX_QUALIFIER',\n            GetStringByName('INDEX_CATALOG'));\n          Result.UpdateStringByName('INDEX_NAME',\n            GetStringByName('INDEX_NAME'));\n          Result.UpdateShortByName('TYPE',\n            GetShortByName('TYPE'));\n          Result.UpdateShortByName('ORDINAL_POSITION',\n            GetShortByName('ORDINAL_POSITION'));\n          Result.UpdateStringByName('COLUMN_NAME',\n            GetStringByName('COLUMN_NAME'));\n    //!!!      Result.UpdateStringByName('ASC_OR_DESC',\n    //        GetStringByName('COLLATION'));\n          Result.UpdateIntByName('CARDINALITY',\n            GetIntByName('CARDINALITY'));\n          Result.UpdateIntByName('PAGES',\n            GetIntByName('PAGES'));\n          Result.UpdateStringByName('FILTER_CONDITION',\n            GetStringByName('FILTER_CONDITION'));\n          Result.InsertRow;\n        end;\n        Close;\n        Free;\n      end;\n    end;\nend;\n\n{**\n\n  Gets a description of the user-defined types defined in a particular\n  schema.  Schema-specific UDTs may have type JAVA_OBJECT, STRUCT,\n  or DISTINCT.\n\n  <P>Only types matching the catalog, schema, type name and type\n  criteria are returned.  They are ordered by DATA_TYPE, TYPE_SCHEM\n  and TYPE_NAME.  The type name parameter may be a fully-qualified\n  name.  In this case, the catalog and schemaPattern parameters are\n  ignored.\n\n  <P>Each type description has the following columns:\n   <OL>\n \t<LI><B>TYPE_CAT</B> String => the type's catalog (may be null)\n \t<LI><B>TYPE_SCHEM</B> String => type's schema (may be null)\n \t<LI><B>TYPE_NAME</B> String => type name\n   <LI><B>CLASS_NAME</B> String => Java class name\n \t<LI><B>DATA_TYPE</B> String => type value defined in java.sql.Types.\n   One of JAVA_OBJECT, STRUCT, or DISTINCT\n \t<LI><B>REMARKS</B> String => explanatory comment on the type\n   </OL>\n\n  <P><B>Note:</B> If the driver does not support UDTs, an empty\n  result set is returned.\n\n  @param catalog a catalog name; \"\" retrieves those without a\n  catalog; null means drop catalog name from the selection criteria\n  @param schemaPattern a schema name pattern; \"\" retrieves those\n  without a schema\n  @param typeNamePattern a type name pattern; may be a fully-qualified name\n  @param types a list of user-named types to include (JAVA_OBJECT,\n  STRUCT, or DISTINCT); null returns all types\n  @return <code>ResultSet</code> - each row is a type description\n}\nfunction TZAdoDatabaseMetadata.UncachedGetUDTs(const Catalog: string; const SchemaPattern: string;\n  const TypeNamePattern: string; const Types: TIntegerDynArray): IZResultSet;\nbegin\n\n  Result:=inherited UncachedGetUDTs(Catalog, SchemaPattern, TypeNamePattern, Types);\n\n//  AdoRecordSet := AdoOpenSchema(adSchemaIndexes, Restrictions);\n//  if Assigned(AdoRecordSet) then\n//  with GetStatement.ExecuteQuery(\n//    Format('select TYPE_CAT = db_name(), TYPE_SCHEM = user_name(uid),'\n//      + ' TYPE_NAME = st.name, DATA_TYPE from master.dbo.spt_datatype_info'\n//      + ' sti left outer join systypes st on (sti.ss_dtype = st.xtype)'\n//      + ' where st.xusertype > 255 and user_name(uid) like %s and st.name'\n//      + ' like %s', [SchemaPattern, TypeNamePattern])) do\n//    while Next do\n//    begin\n//      Result.MoveToInsertRow;\n//      Result.UpdateString('TYPE_CAT', GetString('TYPE_CAT'));\n//      Result.UpdateString('TYPE_SCHEM', GetString('TYPE_SCHEM'));\n//      Result.UpdateString('TYPE_NAME', GetString('TYPE_NAME'));\n//      Result.UpdateNull('JAVA_CLASS');\n//      Result.UpdateShort('DATA_TYPE', GetShort('DATA_TYPE'));\n//      Result.UpdateNull('REMARKS');\n//      Result.InsertRow;\n//    end;\n\nend;\n\n{**\n  Open a schema rowset from ado\n\n  @Schema Ado identifier\n  @Args Variant array with restrictions\n  @return ADO recordset with the schemas; nil if the schema is not supported\n}\nfunction TZAdoDatabaseMetadata.AdoOpenSchema(Schema: Integer; const Args: array of const): ZPlainAdo.RecordSet;\nvar\n  Restrictions: Variant;\nbegin\n  Result := nil;\n  if not FSupportedSchemasInitialized then\n    InitializeSchemas;\n  if not SchemaSupported(Schema) then\n    Exit;\n  try\n    Restrictions := BuildRestrictions(Schema, Args);\n    Result := (GetConnection as IZAdoConnection).GetAdoConnection.\n      OpenSchema(Schema, Restrictions, EmptyParam);\n  except\n    Result := nil;\n  end;\nend;\n\n{**\n  Initialize supported schemas and restrictions from the OleDB provider\n}\nprocedure TZAdoDatabaseMetadata.InitializeSchemas;\nvar\n  AdoConnection: IZAdoConnection;\n  OleDBSession: IUnknown;\n  SchemaRS: IDBSchemaRowset;\n  PG, OriginalPG: PGUID;\n  IA: PIntegerArray;\n  Nr: Integer;\n  I: Integer;\nbegin\n  if not FSupportedSchemasInitialized then\n  begin\n    if not Assigned(FAdoConnection) then\n    begin\n      GetConnection.QueryInterface(IZAdoConnection, AdoConnection);\n      FAdoConnection := AdoConnection.GetAdoConnection;\n    end;\n    (FAdoConnection as ADOConnectionConstruction).Get_Session(OleDBSession);\n    if Assigned(OleDBSession) then\n    begin\n      OleDBSession.QueryInterface(IDBSchemaRowset, SchemaRS);\n      if Assigned(SchemaRS) then\n      begin\n        SchemaRS.GetSchemas(Nr, PG, PInteger(IA));\n        OriginalPG := PG;\n        SetLength(SupportedSchemas, Nr);\n        for I := 0 to Nr - 1 do\n        begin\n          SupportedSchemas[I].SchemaGuid := PG^;\n          SupportedSchemas[I].SupportedRestrictions := IA^[I];\n          SupportedSchemas[I].AdoSchemaId := ConvertOleDBToAdoSchema(PG^);\n          Inc({$IFDEF DELPHI16_UP}NativeInt{$ELSE}Integer{$ENDIF}(PG), SizeOf(TGuid));  //M.A. Inc(Integer(PG), SizeOf(TGuid));\n        end;\n        FSupportedSchemasInitialized := True;\n        if Assigned(OriginalPG) then ZAdoMalloc.Free(OriginalPG);\n        if Assigned(IA) then ZAdoMalloc.Free(IA);\n      end;\n    end;\n  end;\nend;\n\n{**\n  Find the Schema Id in the supported schemas\n\n  @SchemaId Ado identifier\n  @return Index of the schema in the supported schemas array\n}\nfunction TZAdoDatabaseMetadata.FindSchema(SchemaId: Integer): Integer;\nvar\n  I: Integer;\nbegin\n  Result := -1;\n  for I := 0 to Length(SupportedSchemas) - 1 do\n    if SupportedSchemas[I].AdoSchemaId = SchemaId then\n    begin\n      Result := I;\n      Break;\n    end;\nend;\n\n{**\n  Is the schema supported by the OleDB provider?\n\n  @SchemaId Ado identifier\n  @return True if the schema is supported\n}\nfunction TZAdoDatabaseMetadata.SchemaSupported(SchemaId: Integer): Boolean;\nbegin\n  Result := FindSchema(SchemaId) > -1;\nend;\n\n{**\n  Build a variant array from the provided parameters based on the supported restrictions\n\n  @SchemaId Ado identifier\n  @Args Restrictions\n  @return Variant array of restrictions\n}\nfunction TZAdoDatabaseMetadata.BuildRestrictions(SchemaId: Integer;\n  const Args: array of const): Variant;\nvar\n  SchemaIndex: Integer;\n  I: Integer;\nbegin\n  Result := Null;\n  if High(Args) = -1 then\n    Exit; \n  SchemaIndex := FindSchema(SchemaId);\n  if SchemaIndex = -1 then\n    Exit;\n\n  Result := VarArrayCreate([0, High(Args)], varVariant);\n  for I := 0 to High(Args) do\n  begin\n    if (SupportedSchemas[SchemaIndex].SupportedRestrictions\n      and (1 shl I)) <> 0 then\n    begin\n      {$IFDEF UNICODE}\n      Result[I] := string(Args[I].VPWideChar);\n      if (Args[I].VType = VtUnicodeString) then\n        if string(Args[I].VPWideChar) = '' then\n      {$ELSE}\n      Result[I] := string(Args[I].VAnsiString);\n      if (Args[I].VType = vtAnsiString) then\n        if string(Args[I].VAnsiString) = '' then\n      {$ENDIF}\n          Result[I] := UnAssigned;\n    end else\n      Result[I] := UnAssigned;\n  end;\nend;\n\nend.\n\n\n"
  },
  {
    "path": "lib/zeosdbo/src/dbc/ZDbcAdoResultSet.pas",
    "content": "{*********************************************************}\n{                                                         }\n{                 Zeos Database Objects                   }\n{         Ado Resultset common functionality              }\n{                                                         }\n{        Originally written by Janos Fegyverneki          }\n{                                                         }\n{*********************************************************}\n\n{@********************************************************}\n{    Copyright (c) 1999-2012 Zeos Development Group       }\n{                                                         }\n{ License Agreement:                                      }\n{                                                         }\n{ This library is distributed in the hope that it will be }\n{ useful, but WITHOUT ANY WARRANTY; without even the      }\n{ implied warranty of MERCHANTABILITY or FITNESS FOR      }\n{ A PARTICULAR PURPOSE.  See the GNU Lesser General       }\n{ Public License for more details.                        }\n{                                                         }\n{ The source code of the ZEOS Libraries and packages are  }\n{ distributed under the Library GNU General Public        }\n{ License (see the file COPYING / COPYING.ZEOS)           }\n{ with the following  modification:                       }\n{ As a special exception, the copyright holders of this   }\n{ library give you permission to link this library with   }\n{ independent modules to produce an executable,           }\n{ regardless of the license terms of these independent    }\n{ modules, and to copy and distribute the resulting       }\n{ executable under terms of your choice, provided that    }\n{ you also meet, for each linked independent module,      }\n{ the terms and conditions of the license of that module. }\n{ An independent module is a module which is not derived  }\n{ from or based on this library. If you modify this       }\n{ library, you may extend this exception to your version  }\n{ of the library, but you are not obligated to do so.     }\n{ If you do not wish to do so, delete this exception      }\n{ statement from your version.                            }\n{                                                         }\n{                                                         }\n{ The project web site is located on:                     }\n{   http://zeos.firmos.at  (FORUM)                        }\n{   http://sourceforge.net/p/zeoslib/tickets/ (BUGTRACKER)}\n{   svn://svn.code.sf.net/p/zeoslib/code-0/trunk (SVN)    }\n{                                                         }\n{   http://www.sourceforge.net/projects/zeoslib.          }\n{                                                         }\n{                                                         }\n{                                 Zeos Development Group. }\n{********************************************************@}\n\nunit ZDbcAdoResultSet;\n\ninterface\n\n{$I ZDbc.inc}\n\nuses\n{$IFNDEF FPC}\n  DateUtils,\n{$ENDIF}\n  {$IFDEF WITH_TOBJECTLIST_INLINE}System.Types, System.Contnrs{$ELSE}Types{$ENDIF},\n  Classes, SysUtils,\n  ZClasses, ZSysUtils, ZCollections, ZDbcIntfs,\n  ZDbcGenericResolver, ZDbcCachedResultSet, ZDbcCache, ZDbcResultSet,\n  ZDbcResultsetMetadata, ZCompatibility, ZDbcAdo, ZPlainAdoDriver, ZPlainAdo;\n\ntype\n  {** Implements Ado ResultSet. }\n  TZAdoResultSet = class(TZAbstractResultSet)\n  private\n    AdoColTypeCache: TIntegerDynArray;\n    AdoColumnCount: Integer;\n    FFirstFetch: Boolean;\n  protected\n    FAdoRecordSet: ZPlainAdo.RecordSet;\n    procedure Open; override;\n  public\n    constructor Create(Statement: IZStatement; SQL: string;\n      AdoRecordSet: ZPlainAdo.RecordSet);\n    destructor Destroy; override;\n\n    procedure Close; override;\n    function Next: Boolean; override;\n    function MoveAbsolute(Row: Integer): Boolean; override;\n    function GetRow: Integer; override;\n    function IsNull(ColumnIndex: Integer): Boolean; override;\n    function GetString(ColumnIndex: Integer): String; override;\n    function GetUnicodeString(ColumnIndex: Integer): WideString; override;\n    function GetBoolean(ColumnIndex: Integer): Boolean; override;\n    function GetByte(ColumnIndex: Integer): Byte; override;\n    function GetShort(ColumnIndex: Integer): SmallInt; override;\n    function GetInt(ColumnIndex: Integer): Integer; override;\n    function GetLong(ColumnIndex: Integer): Int64; override;\n    function GetFloat(ColumnIndex: Integer): Single; override;\n    function GetDouble(ColumnIndex: Integer): Double; override;\n    function GetBigDecimal(ColumnIndex: Integer): Extended; override;\n    function GetBytes(ColumnIndex: Integer): TByteDynArray; override;\n    function GetDate(ColumnIndex: Integer): TDateTime; override;\n    function GetTime(ColumnIndex: Integer): TDateTime; override;\n    function GetTimestamp(ColumnIndex: Integer): TDateTime; override;\n    function GetBlob(ColumnIndex: Integer): IZBlob; override;\n  end;\n\n  {** Implements a cached resolver with Ado specific functionality. }\n  TZAdoCachedResolver = class (TZGenericCachedResolver, IZCachedResolver)\n  private\n    FHandle: ZPlainAdo.Command;\n    FAutoColumnIndex: Integer;\n  public\n    constructor Create(Handle: ZPlainAdo.Connection;\n      Statement: IZStatement; Metadata: IZResultSetMetadata);\n\n    procedure PostUpdates(Sender: IZCachedResultSet; UpdateType: TZRowUpdateType;\n      OldRowAccessor, NewRowAccessor: TZRowAccessor); override;\n  end;\n\nimplementation\n\nuses\n  Variants, Math, OleDB,\n  ZMessages, ZDbcUtils, ZDbcAdoUtils, ZEncoding;\n\n{**\n  Creates this object and assignes the main properties.\n  @param Statement an SQL statement object.\n  @param SQL an SQL query string.\n  @param AdoRecordSet a ADO recordset object, the source of the ResultSet.\n}\nconstructor TZAdoResultSet.Create(Statement: IZStatement; SQL: string; AdoRecordSet: ZPlainAdo.RecordSet);\nbegin\n  inherited Create(Statement, SQL, nil, Statement.GetConnection.GetConSettings);\n  FAdoRecordSet := AdoRecordSet;\n  Open;\nend;\n\n{**\n  Destroys this object and cleanups the memory.\n}\ndestructor TZAdoResultSet.Destroy;\nbegin\n  Close;\n  inherited;\nend;\n\n{**\n  Opens this recordset and initializes the Column information.\n}\nprocedure TZAdoResultSet.Open;\nvar\n  OleDBRowset: IUnknown;\n  OleDBColumnsInfo: IColumnsInfo;\n  pcColumns: NativeUInt;\n  prgInfo, OriginalprgInfo: PDBColumnInfo;\n  ppStringsBuffer: PWideChar;\n  I: Integer;\n  FieldSize: Integer;\n  ColumnInfo: TZColumnInfo;\n  ColName: string;\n  ColType: Integer;\n  HasAutoIncProp: Boolean;\n  F: ZPlainAdo.Field20;\n  S: string;\n  J: Integer;\nbegin\n//Check if the current statement can return rows\n  if not Assigned(FAdoRecordSet) or (FAdoRecordSet.State = adStateClosed) then\n    raise EZSQLException.Create(SCanNotRetrieveResultSetData);\n\n  (FAdoRecordSet as ADORecordsetConstruction).Get_Rowset(OleDBRowset);\n  OleDBRowset.QueryInterface(IColumnsInfo, OleDBColumnsInfo);\n\n  OleDBColumnsInfo.GetColumnInfo(pcColumns, prgInfo, ppStringsBuffer);\n  OriginalprgInfo := prgInfo;\n\n  { Fills the column info }\n  ColumnsInfo.Clear;\n  AdoColumnCount := FAdoRecordSet.Fields.Count;\n  SetLength(AdoColTypeCache, AdoColumnCount);\n\n  HasAutoIncProp := False;\n  if AdoColumnCount > 0 then\n    for I := 0 to FAdoRecordSet.Fields.Item[0].Properties.Count - 1 do\n      if FAdoRecordSet.Fields.Item[0].Properties.Item[I].Name = 'ISAUTOINCREMENT' then\n      begin\n        HasAutoIncProp := True;\n        Break;\n      end;\n\n  if Assigned(prgInfo) then\n    if prgInfo.iOrdinal = 0 then\n      Inc(NativeInt(prgInfo), SizeOf(TDBColumnInfo));\n\n  for I := 0 to AdoColumnCount - 1 do\n  begin\n    ColumnInfo := TZColumnInfo.Create;\n\n    F := FAdoRecordSet.Fields.Item[I];\n    ColName := F.Name;\n    ColType := F.Type_;\n    ColumnInfo.ColumnLabel := ColName;\n    ColumnInfo.ColumnName := ColName;\n    ColumnInfo.ColumnType := ConvertAdoToSqlType(ColType, ConSettings.CPType);\n    FieldSize := F.DefinedSize;\n    if FieldSize < 0 then\n      FieldSize := 0;\n    if F.Type_ = adGuid then\n      ColumnInfo.ColumnDisplaySize := 38\n    else\n      ColumnInfo.ColumnDisplaySize := FieldSize;\n    ColumnInfo.Precision := FieldSize;\n    ColumnInfo.Currency := ColType = adCurrency;\n    ColumnInfo.Signed := False;\n    S := '';\n    for J := 0 to F.Properties.Count - 1 do\n      S := S+F.Properties.Item[J].Name + '=' + VarToStr(F.Properties.Item[J].Value) + ', ';\n    if HasAutoIncProp then\n      ColumnInfo.AutoIncrement := F.Properties.Item['ISAUTOINCREMENT'].Value;\n    if ColType in [adTinyInt, adSmallInt, adInteger, adBigInt, adCurrency, adDecimal, adDouble, adNumeric, adSingle] then\n      ColumnInfo.Signed := True;\n\n    ColumnInfo.Writable := (prgInfo.dwFlags and (DBCOLUMNFLAGS_WRITE or DBCOLUMNFLAGS_WRITEUNKNOWN) <> 0) and (F.Properties.Item['BASECOLUMNNAME'].Value <> null) and not ColumnInfo.AutoIncrement;\n    ColumnInfo.ReadOnly := (prgInfo.dwFlags and (DBCOLUMNFLAGS_WRITE or DBCOLUMNFLAGS_WRITEUNKNOWN) = 0) or ColumnInfo.AutoIncrement;\n    ColumnInfo.Searchable := (prgInfo.dwFlags and DBCOLUMNFLAGS_ISLONG) = 0;\n    if (prgInfo.dwFlags and DBCOLUMNFLAGS_ISLONG) <> 0 then\n    case ColumnInfo.ColumnType of\n      stString: ColumnInfo.ColumnType := stAsciiStream;\n      stUnicodeString: ColumnInfo.ColumnType := stUnicodeStream;\n    end;\n\n    ColumnsInfo.Add(ColumnInfo);\n\n    AdoColTypeCache[I] := ColType;\n    Inc(NativeInt(prgInfo), SizeOf(TDBColumnInfo));  //M.A. Inc(Integer(prgInfo), SizeOf(TDBColumnInfo));\n  end;\n  if Assigned(ppStringsBuffer) then ZAdoMalloc.Free(ppStringsBuffer);\n  if Assigned(OriginalprgInfo) then ZAdoMalloc.Free(OriginalprgInfo);\n  FFirstFetch := True;\n  inherited;\nend;\n\n{**\n  Releases this <code>ResultSet</code> object's database and\n  ADO resources immediately instead of waiting for\n  this to happen when it is automatically closed.\n\n  <P><B>Note:</B> A <code>ResultSet</code> object\n  is automatically closed by the\n  <code>Statement</code> object that generated it when\n  that <code>Statement</code> object is closed,\n  re-executed, or is used to retrieve the next result from a\n  sequence of multiple results. A <code>ResultSet</code> object\n  is also automatically closed when it is garbage collected.\n}\nprocedure TZAdoResultSet.Close;\nbegin\n  FAdoRecordSet := nil;\n  inherited;\nend;\n\n{**\n  Moves the cursor down one row from its current position.\n  A <code>ResultSet</code> cursor is initially positioned\n  before the first row; the first call to the method\n  <code>next</code> makes the first row the current row; the\n  second call makes the second row the current row, and so on.\n\n  <P>If an input stream is open for the current row, a call\n  to the method <code>next</code> will\n  implicitly close it. A <code>ResultSet</code> object's\n  warning chain is cleared when a new row is read.\n\n  @return <code>true</code> if the new current row is valid;\n    <code>false</code> if there are no more rows\n}\nfunction TZAdoResultSet.Next: Boolean;\nbegin\n  Result := False;\n  if FAdoRecordSet.BOF and FAdoRecordSet.EOF then\n    Exit;\n  if FAdoRecordSet.BOF then\n    FAdoRecordSet.MoveFirst\n  else\n    if not FAdoRecordSet.EOF and not FFirstFetch then\n      FAdoRecordSet.MoveNext;\n  FFirstFetch := False;\n  Result := not FAdoRecordSet.EOF;\nend;\n\n{**\n  Moves the cursor to the given row number in\n  this <code>ResultSet</code> object.\n\n  <p>If the row number is positive, the cursor moves to\n  the given row number with respect to the\n  beginning of the result set.  The first row is row 1, the second\n  is row 2, and so on.\n\n  <p>If the given row number is negative, the cursor moves to\n  an absolute row position with respect to\n  the end of the result set.  For example, calling the method\n  <code>absolute(-1)</code> positions the\n  cursor on the last row; calling the method <code>absolute(-2)</code>\n  moves the cursor to the next-to-last row, and so on.\n\n  <p>An attempt to position the cursor beyond the first/last row in\n  the result set leaves the cursor before the first row or after\n  the last row.\n\n  <p><B>Note:</B> Calling <code>absolute(1)</code> is the same\n  as calling <code>first()</code>. Calling <code>absolute(-1)</code>\n  is the same as calling <code>last()</code>.\n\n  @return <code>true</code> if the cursor is on the result set;\n    <code>false</code> otherwise\n}\nfunction TZAdoResultSet.MoveAbsolute(Row: Integer): Boolean;\nbegin\n  if FAdoRecordSet.EOF or FAdoRecordSet.BOF then\n     FAdoRecordSet.MoveFirst;\n  if Row > 0 then\n    FAdoRecordSet.Move(Row - 1, adBookmarkFirst)\n  else\n    FAdoRecordSet.Move(Abs(Row) - 1, adBookmarkLast);\n  Result := not (FAdoRecordSet.EOF or FAdoRecordSet.BOF);\nend;\n\n{**\n  Retrieves the current row number.  The first row is number 1, the\n  second number 2, and so on.\n  @return the current row number; <code>0</code> if there is no current row\n}\nfunction TZAdoResultSet.GetRow: Integer;\nbegin\n  if FAdoRecordSet.EOF or FAdoRecordSet.BOF then\n    Result := -1\n  else\n    Result := FAdoRecordSet.AbsolutePosition;\nend;\n\n{**\n  Indicates if the value of the designated column in the current row\n  of this <code>ResultSet</code> object is Null.\n\n  @param columnIndex the first column is 1, the second is 2, ...\n  @return if the value is SQL <code>NULL</code>, the\n    value returned is <code>true</code>. <code>false</code> otherwise.\n}\nfunction TZAdoResultSet.IsNull(ColumnIndex: Integer): Boolean;\nbegin\n  Result := VarIsNull(FAdoRecordSet.Fields.Item[ColumnIndex - 1].Value) or\n            VarIsEmpty(FAdoRecordSet.Fields.Item[ColumnIndex - 1].Value);\nend;\n\n{**\n  Gets the value of the designated column in the current row\n  of this <code>ResultSet</code> object as\n  a <code>String</code> in the Java programming language.\n\n  @param columnIndex the first column is 1, the second is 2, ...\n  @return the column value; if the value is SQL <code>NULL</code>, the\n    value returned is <code>null</code>\n}\nfunction TZAdoResultSet.GetString(ColumnIndex: Integer): String;\n{var\n  NL: Integer;}\nbegin\n  Result := '';\n  LastWasNull := IsNull(ColumnIndex);\n  if LastWasNull then\n     Exit;\n  if (VarType(FAdoRecordSet.Fields.Item[ColumnIndex - 1].Value) = varOleStr)\n    {$IFDEF UNICODE} or ( VarType(FAdoRecordSet.Fields.Item[ColumnIndex - 1].Value) = varUString){$ENDIF} then\n    Result := ZDbcString(ZWideString(FAdoRecordSet.Fields.Item[ColumnIndex - 1].Value))\n  else\n    Result := ZDbcString(AnsiString(FAdoRecordSet.Fields.Item[ColumnIndex - 1].Value))\n  {Why this? It cuts wanted trailing spaces!\n  NL := Length(Result);\n  while (NL > 0) and (Result[NL] = ' ') do Dec(NL);\n  SetLength(Result, NL);}\nend;\n\n{**\n  Gets the value of the designated column in the current row\n  of this <code>ResultSet</code> object as\n  a <code>WideString</code> in the Delphi programming language.\n\n  @param columnIndex the first column is 1, the second is 2, ...\n  @return the column value; if the value is SQL <code>NULL</code>, the\n    value returned is <code>null</code>\n}\nfunction TZAdoResultSet.GetUnicodeString(ColumnIndex: Integer): WideString;\n{var\n  NL: Integer;}\nbegin\n  Result := '';\n  LastWasNull := IsNull(ColumnIndex);\n  if LastWasNull then\n     Exit;\n  Result := FAdoRecordSet.Fields.Item[ColumnIndex - 1].Value;\n  {Why this? It cuts wanted trailing spaces!\n  NL := Length(Result);\n  while (NL > 0) and (Result[NL] = ' ') do\n     Dec(NL);\n  SetLength(Result, NL);}\nend;\n\n{**\n  Gets the value of the designated column in the current row\n  of this <code>ResultSet</code> object as\n  a <code>boolean</code> in the Java programming language.\n\n  @param columnIndex the first column is 1, the second is 2, ...\n  @return the column value; if the value is SQL <code>NULL</code>, the\n    value returned is <code>false</code>\n}\nfunction TZAdoResultSet.GetBoolean(ColumnIndex: Integer): Boolean;\nbegin\n  Result := False;\n  LastWasNull := IsNull(ColumnIndex);\n  if LastWasNull then\n     Exit;\n  try\n    Result := FAdoRecordSet.Fields.Item[ColumnIndex - 1].Value;\n  except\n    Result := False;\n  end;\nend;\n\n{**\n  Gets the value of the designated column in the current row\n  of this <code>ResultSet</code> object as\n  a <code>byte</code> in the Java programming language.\n\n  @param columnIndex the first column is 1, the second is 2, ...\n  @return the column value; if the value is SQL <code>NULL</code>, the\n    value returned is <code>0</code>\n}\nfunction TZAdoResultSet.GetByte(ColumnIndex: Integer): Byte;\nbegin\n  Result := 0;\n  LastWasNull := IsNull(ColumnIndex);\n  if LastWasNull then\n     Exit;\n  try\n    Result := FAdoRecordSet.Fields.Item[ColumnIndex - 1].Value;\n  except\n    Result := 0;\n  end;\nend;\n\n{**\n  Gets the value of the designated column in the current row\n  of this <code>ResultSet</code> object as\n  a <code>short</code> in the Java programming language.\n\n  @param columnIndex the first column is 1, the second is 2, ...\n  @return the column value; if the value is SQL <code>NULL</code>, the\n    value returned is <code>0</code>\n}\nfunction TZAdoResultSet.GetShort(ColumnIndex: Integer): SmallInt;\nbegin\n  Result := 0;\n  LastWasNull := IsNull(ColumnIndex);\n  if LastWasNull then\n     Exit;\n  try\n    Result := FAdoRecordSet.Fields.Item[ColumnIndex - 1].Value;\n  except\n    Result := 0;\n  end;\nend;\n\n{**\n  Gets the value of the designated column in the current row\n  of this <code>ResultSet</code> object as\n  an <code>int</code> in the Java programming language.\n\n  @param columnIndex the first column is 1, the second is 2, ...\n  @return the column value; if the value is SQL <code>NULL</code>, the\n    value returned is <code>0</code>\n}\nfunction TZAdoResultSet.GetInt(ColumnIndex: Integer): Integer;\nbegin\n  Result := 0;\n  LastWasNull := IsNull(ColumnIndex);\n  if LastWasNull then\n     Exit;\n  try\n    Result := FAdoRecordSet.Fields.Item[ColumnIndex - 1].Value;\n  except\n    Result := 0;\n  end;\nend;\n\n{**\n  Gets the value of the designated column in the current row\n  of this <code>ResultSet</code> object as\n  a <code>long</code> in the Java programming language.\n\n  @param columnIndex the first column is 1, the second is 2, ...\n  @return the column value; if the value is SQL <code>NULL</code>, the\n    value returned is <code>0</code>\n}\nfunction TZAdoResultSet.GetLong(ColumnIndex: Integer): Int64;\nbegin\n  Result := 0;\n  LastWasNull := IsNull(ColumnIndex);\n  if LastWasNull then\n     Exit;\n  try\n    Result := FAdoRecordSet.Fields.Item[ColumnIndex - 1].Value;\n  except\n    Result := 0;\n  end;\nend;\n\n{**\n  Gets the value of the designated column in the current row\n  of this <code>ResultSet</code> object as\n  a <code>float</code> in the Java programming language.\n\n  @param columnIndex the first column is 1, the second is 2, ...\n  @return the column value; if the value is SQL <code>NULL</code>, the\n    value returned is <code>0</code>\n}\nfunction TZAdoResultSet.GetFloat(ColumnIndex: Integer): Single;\nbegin\n  Result := 0;\n  LastWasNull := IsNull(ColumnIndex);\n  if LastWasNull then\n     Exit;\n  try\n    Result := FAdoRecordSet.Fields.Item[ColumnIndex - 1].Value;\n  except\n    Result := 0;\n  end;\nend;\n\n{**\n  Gets the value of the designated column in the current row\n  of this <code>ResultSet</code> object as\n  a <code>double</code> in the Java programming language.\n\n  @param columnIndex the first column is 1, the second is 2, ...\n  @return the column value; if the value is SQL <code>NULL</code>, the\n    value returned is <code>0</code>\n}\nfunction TZAdoResultSet.GetDouble(ColumnIndex: Integer): Double;\nbegin\n  Result := 0;\n  LastWasNull := IsNull(ColumnIndex);\n  if LastWasNull then\n     Exit;\n  try\n    Result := FAdoRecordSet.Fields.Item[ColumnIndex - 1].Value;\n  except\n    Result := 0;\n  end;\nend;\n\n{**\n  Gets the value of the designated column in the current row\n  of this <code>ResultSet</code> object as\n  a <code>java.sql.BigDecimal</code> in the Java programming language.\n\n  @param columnIndex the first column is 1, the second is 2, ...\n  @param scale the number of digits to the right of the decimal point\n  @return the column value; if the value is SQL <code>NULL</code>, the\n    value returned is <code>null</code>\n}\nfunction TZAdoResultSet.GetBigDecimal(ColumnIndex: Integer): Extended;\nbegin\n  Result := 0;\n  LastWasNull := IsNull(ColumnIndex);\n  if LastWasNull then\n     Exit;\n  try\n    Result := FAdoRecordSet.Fields.Item[ColumnIndex - 1].Value;\n  except\n    Result := 0;\n  end;\nend;\n\n{**\n  Gets the value of the designated column in the current row\n  of this <code>ResultSet</code> object as\n  a <code>byte</code> array in the Java programming language.\n  The bytes represent the raw values returned by the driver.\n\n  @param columnIndex the first column is 1, the second is 2, ...\n  @return the column value; if the value is SQL <code>NULL</code>, the\n    value returned is <code>null</code>\n}\nfunction TZAdoResultSet.GetBytes(ColumnIndex: Integer): TByteDynArray;\nvar\n  V: Variant;\n  GUID: TGUID;\nbegin\n  SetLength(Result, 0);\n  LastWasNull := IsNull(ColumnIndex);\n  if LastWasNull then\n     Exit;\n  V := FAdoRecordSet.Fields.Item[ColumnIndex - 1].Value;\n  if VarType(V) = varByte then\n    Result := V\n  else\n    if TZColumnInfo(ColumnsInfo[ColumnIndex-1]).ColumnType = stGUID then\n    begin\n      SetLength(Result, 16);\n      GUID := StringToGUID(V);\n      System.Move(Pointer(@GUID)^, Pointer(Result)^, 16);\n    end\n    else\n      Result := V\nend;\n\n{**\n  Gets the value of the designated column in the current row\n  of this <code>ResultSet</code> object as\n  a <code>java.sql.Date</code> object in the Java programming language.\n\n  @param columnIndex the first column is 1, the second is 2, ...\n  @return the column value; if the value is SQL <code>NULL</code>, the\n    value returned is <code>null</code>\n}\nfunction TZAdoResultSet.GetDate(ColumnIndex: Integer): TDateTime;\nbegin\n  Result := 0;\n  LastWasNull := IsNull(ColumnIndex);\n  if LastWasNull then\n     Exit;\n  try\n    Result := FAdoRecordSet.Fields.Item[ColumnIndex - 1].Value;\n  except\n    Result := 0;\n  end;\nend;\n\n{**\n  Gets the value of the designated column in the current row\n  of this <code>ResultSet</code> object as\n  a <code>java.sql.Time</code> object in the Java programming language.\n\n  @param columnIndex the first column is 1, the second is 2, ...\n  @return the column value; if the value is SQL <code>NULL</code>, the\n    value returned is <code>null</code>\n}\nfunction TZAdoResultSet.GetTime(ColumnIndex: Integer): TDateTime;\nbegin\n  Result := 0;\n  LastWasNull := IsNull(ColumnIndex);\n  if LastWasNull then\n     Exit;\n  try\n    Result := FAdoRecordSet.Fields.Item[ColumnIndex - 1].Value;\n  except\n    Result := 0;\n  end;\nend;\n\n{**\n  Gets the value of the designated column in the current row\n  of this <code>ResultSet</code> object as\n  a <code>java.sql.Timestamp</code> object in the Java programming language.\n\n  @param columnIndex the first column is 1, the second is 2, ...\n  @return the column value; if the value is SQL <code>NULL</code>, the\n  value returned is <code>null</code>\n  @exception SQLException if a database access error occurs\n}\nfunction TZAdoResultSet.GetTimestamp(ColumnIndex: Integer): TDateTime;\nbegin\n  Result := 0;\n  LastWasNull := IsNull(ColumnIndex);\n  if LastWasNull then\n     Exit;\n  try\n    Result := FAdoRecordSet.Fields.Item[ColumnIndex - 1].Value;\n  except\n    Result := 0;\n  end;\nend;\n\n{**\n  Returns the value of the designated column in the current row\n  of this <code>ResultSet</code> object as a <code>Blob</code> object\n  in the Java programming language.\n\n  @param ColumnIndex the first column is 1, the second is 2, ...\n  @return a <code>Blob</code> object representing the SQL <code>BLOB</code> value in\n    the specified column\n}\nfunction TZAdoResultSet.GetBlob(ColumnIndex: Integer): IZBlob;\nvar\n  V: Variant;\n  P: Pointer;\nbegin\n  Result := nil;\n  LastWasNull := IsNull(ColumnIndex);\n  if LastWasNull then\n     Exit;\n\n  V := FAdoRecordSet.Fields.Item[ColumnIndex - 1].Value;\n  if VarIsStr(V) {$IFDEF UNICODE} or ( VarType(V) = varUString){$ENDIF} then\n  begin\n    Result := TZAbstractBlob.CreateWithStream(nil, GetStatement.GetConnection);\n    case GetMetadata.GetColumnType(ColumnIndex) of\n      stAsciiStream:\n        if (VarType(V) = varOleStr) {$IFDEF UNICODE} or ( VarType(V) = varUString){$ENDIF} then\n          if ConSettings^.AutoEncode then\n            if ConSettings^.CPType = cCP_UTF8 then\n              Result.SetString(UTF8Encode(V))\n            else\n              Result.SetString(AnsiString(V))\n          else\n            Result.SetString(AnsiString(V))\n        else\n          Result.SetString(GetValidatedAnsiString(V, ConSettings, True));\n      stUnicodeStream:\n        Result.SetUnicodeString(WideString(V));\n      else\n        Result.SetString(RawByteString(V));\n    end;\n  end;\n  if VarIsArray(V) then\n  begin\n    P := VarArrayLock(V);\n    try\n      Result := TZAbstractBlob.CreateWithData(P, VarArrayHighBound(V, 1)+1, GetStatement.GetConnection);\n    finally\n      VarArrayUnLock(V);\n    end;\n  end;\nend;\n\n\n{ TZAdoCachedResolver }\n\n{**\n  Creates a Ado specific cached resolver object.\n  @param PlainDriver a native Ado plain driver.\n  @param Handle a Ado specific query handle.\n  @param Statement a related SQL statement object.\n  @param Metadata a resultset metadata reference.\n}\nconstructor TZAdoCachedResolver.Create(Handle: ZPlainAdo.Connection;\n  Statement: IZStatement; Metadata: IZResultSetMetadata);\nvar\n  I: Integer;\nbegin\n  inherited Create(Statement, Metadata);\n  FHandle := ZPlainAdo.CoCommand.Create;\n  FHandle._Set_ActiveConnection(Handle);\n  FHandle.CommandText := 'SELECT @@IDENTITY';\n  FHandle.CommandType := adCmdText;\n\n  { Defines an index of autoincrement field. }\n  FAutoColumnIndex := 0;\n  for I := 1 to Metadata.GetColumnCount do\n  begin\n    if Metadata.IsAutoIncrement(I) and\n      (Metadata.GetColumnType(I) in [stByte, stShort, stInteger, stLong]) then\n    begin\n      FAutoColumnIndex := I;\n      Break;\n    end;\n  end;\nend;\n\n{**\n  Posts updates to database.\n  @param Sender a cached result set object.\n  @param UpdateType a type of updates.\n  @param OldRowAccessor an accessor object to old column values.\n  @param NewRowAccessor an accessor object to new column values.\n}\nprocedure TZAdoCachedResolver.PostUpdates(Sender: IZCachedResultSet;\n  UpdateType: TZRowUpdateType; OldRowAccessor, NewRowAccessor: TZRowAccessor);\nvar\n  Recordset: ZPlainAdo.Recordset;\n  RA: OleVariant;\nbegin\n  inherited PostUpdates(Sender, UpdateType, OldRowAccessor, NewRowAccessor);\n\n  if (UpdateType = utInserted) and (FAutoColumnIndex > 0)\n    and OldRowAccessor.IsNull(FAutoColumnIndex) then\n  begin\n    Recordset := FHandle.Execute(RA, null, 0);\n    if Recordset.RecordCount > 0 then\n      NewRowAccessor.SetLong(FAutoColumnIndex, Recordset.Fields.Item[0].Value);\n  end;\nend;\n\nend.\n\n\n"
  },
  {
    "path": "lib/zeosdbo/src/dbc/ZDbcAdoStatement.pas",
    "content": "{*********************************************************}\n{                                                         }\n{                 Zeos Database Objects                   }\n{                 ADO Statement Classes                   }\n{                                                         }\n{        Originally written by Janos Fegyverneki          }\n{                                                         }\n{*********************************************************}\n\n{@********************************************************}\n{    Copyright (c) 1999-2012 Zeos Development Group       }\n{                                                         }\n{ License Agreement:                                      }\n{                                                         }\n{ This library is distributed in the hope that it will be }\n{ useful, but WITHOUT ANY WARRANTY; without even the      }\n{ implied warranty of MERCHANTABILITY or FITNESS FOR      }\n{ A PARTICULAR PURPOSE.  See the GNU Lesser General       }\n{ Public License for more details.                        }\n{                                                         }\n{ The source code of the ZEOS Libraries and packages are  }\n{ distributed under the Library GNU General Public        }\n{ License (see the file COPYING / COPYING.ZEOS)           }\n{ with the following  modification:                       }\n{ As a special exception, the copyright holders of this   }\n{ library give you permission to link this library with   }\n{ independent modules to produce an executable,           }\n{ regardless of the license terms of these independent    }\n{ modules, and to copy and distribute the resulting       }\n{ executable under terms of your choice, provided that    }\n{ you also meet, for each linked independent module,      }\n{ the terms and conditions of the license of that module. }\n{ An independent module is a module which is not derived  }\n{ from or based on this library. If you modify this       }\n{ library, you may extend this exception to your version  }\n{ of the library, but you are not obligated to do so.     }\n{ If you do not wish to do so, delete this exception      }\n{ statement from your version.                            }\n{                                                         }\n{                                                         }\n{ The project web site is located on:                     }\n{   http://zeos.firmos.at  (FORUM)                        }\n{   http://sourceforge.net/p/zeoslib/tickets/ (BUGTRACKER)}\n{   svn://svn.code.sf.net/p/zeoslib/code-0/trunk (SVN)    }\n{                                                         }\n{   http://www.sourceforge.net/projects/zeoslib.          }\n{                                                         }\n{                                                         }\n{                                 Zeos Development Group. }\n{********************************************************@}\n\nunit ZDbcAdoStatement;\n\ninterface\n\n{$I ZDbc.inc}\n\nuses\n  Types, Classes, SysUtils, ZCompatibility, ZClasses, ZSysUtils, ZCollections,\n  ZDbcIntfs, ZPlainDriver, ZDbcStatement, ZDbcAdo, ZPlainAdoDriver, ZPlainAdo,\n  ZVariant, ZDbcAdoUtils;\n\ntype\n  {** Implements Generic ADO Statement. }\n  TZAdoStatement = class(TZAbstractStatement)\n  protected\n    AdoRecordSet: ZPlainAdo.RecordSet;\n    FPlainDriver: IZPlainDriver;\n    FAdoConnection: IZAdoConnection;\n    SQL: String;\n    function IsSelect(const SQL: string): Boolean;\n  public\n    constructor Create(PlainDriver: IZPlainDriver; Connection: IZConnection; SQL: string; Info: TStrings);\n    destructor Destroy; override;\n    procedure Close; override;\n\n    function ExecuteQuery(const SQL: ZWideString): IZResultSet; override;\n    function ExecuteUpdate(const SQL: ZWideString): Integer; override;\n    function Execute(const SQL: ZWideString): Boolean; override;\n\n    function ExecuteQuery(const SQL: RawByteString): IZResultSet; override;\n    function ExecuteUpdate(const SQL: RawByteString): Integer; override;\n    function Execute(const SQL: RawByteString): Boolean; override;\n\n    function GetMoreResults: Boolean; override;\n  end;\n\n  {** Implements Prepared ADO Statement. }\n  TZAdoPreparedStatement = class(TZAbstractPreparedStatement)\n  private\n    FPlainDriver: IZPlainDriver;\n    AdoRecordSet: ZPlainAdo.RecordSet;\n    FAdoCommand: ZPlainAdo.Command;\n    FAdoConnection: IZAdoConnection;\n  protected\n    procedure PrepareInParameters; override;\n    procedure BindInParameters; override;\n  public\n    constructor Create(PlainDriver: IZPlainDriver; Connection: IZConnection; SQL: string; Info: TStrings);\n    destructor Destroy; override;\n\n    function ExecuteQueryPrepared: IZResultSet; override;\n    function ExecuteUpdatePrepared: Integer; override;\n    function ExecutePrepared: Boolean; override;\n\n    function GetMoreResults: Boolean; override;\n    procedure Unprepare; override;\n  end;\n\n  {** Implements Callable ADO Statement. }\n  TZAdoCallableStatement = class(TZAbstractCallableStatement)\n  private\n    FPlainDriver: IZPlainDriver;\n    AdoRecordSet: ZPlainAdo.RecordSet;\n    FAdoCommand: ZPlainAdo.Command;\n    FAdoConnection: IZAdoConnection;\n    FDirectionTypes: TDirectionTypes;\n  protected\n    function GetOutParam(ParameterIndex: Integer): TZVariant; override;\n    procedure PrepareInParameters; override;\n    procedure BindInParameters; override;\n  public\n    constructor Create(PlainDriver: IZPlainDriver; Connection: IZConnection;\n      SQL: string; Info: TStrings);\n    function ExecuteQueryPrepared: IZResultSet; override;\n    function ExecuteUpdatePrepared: Integer; override;\n    function ExecutePrepared: Boolean; override;\n\n    procedure RegisterParamType(ParameterIndex: Integer; ParamType: Integer); override;\n    function GetMoreResults: Boolean; override;\n    procedure Unprepare; override;\n  end;\n\nimplementation\n\nuses\n{$IFNDEF FPC}\n  Variants,\n{$ENDIF}\n  OleDB, ComObj,\n  {$IFDEF WITH_TOBJECTLIST_INLINE} System.Contnrs{$ELSE} Contnrs{$ENDIF},\n  {$IFNDEF UNICODE}ZEncoding,{$ENDIF}\n  ZDbcLogging, ZDbcCachedResultSet, ZDbcResultSet, ZDbcAdoResultSet,\n  ZDbcMetadata, ZDbcResultSetMetadata, ZDbcUtils;\n\nconstructor TZAdoStatement.Create(PlainDriver: IZPlainDriver; Connection: IZConnection; SQL: string;\n  Info: TStrings);\nbegin\n  inherited Create(Connection, Info);\n  FPlainDriver := PlainDriver;\n  FAdoConnection := Connection as IZAdoConnection;\nend;\n\ndestructor TZAdoStatement.Destroy;\nbegin\n  FAdoConnection := nil;\n  inherited;\nend;\n\nprocedure TZAdoStatement.Close;\nbegin\n  inherited;\n  AdoRecordSet := nil;\nend;\n\nfunction TZAdoStatement.IsSelect(const SQL: string): Boolean;\nbegin\n  Result := Uppercase(Copy(TrimLeft(Sql), 1, 6)) = 'SELECT';\nend;\n\nfunction TZAdoStatement.ExecuteQuery(const SQL: ZWideString): IZResultSet;\nbegin\n  {$IFDEF UNICODE}\n  WSQL := SQL;\n  {$ENDIF}\n  Result := nil;\n  LastResultSet := nil;\n  LastUpdateCount := -1;\n  if not Execute(LogSql) then\n    while (not GetMoreResults) and (LastUpdateCount > -1) do ;\n  Result := LastResultSet\nend;\n\nfunction TZAdoStatement.ExecuteUpdate(const SQL: ZWideString): Integer;\nvar\n  RC: OleVariant;\nbegin\n  try\n    LastResultSet := nil;\n    LastUpdateCount := -1;\n    {$IFDEF UNICODE}\n    WSQL := SQL;\n    {$ENDIF}\n    if IsSelect(LogSQL) then\n    begin\n      AdoRecordSet := CoRecordSet.Create;\n      AdoRecordSet.MaxRecords := MaxRows;\n      AdoRecordSet.Open(SQL, FAdoConnection.GetAdoConnection,\n        adOpenStatic, adLockOptimistic, adAsyncFetch);\n      LastResultSet := GetCurrentResultSet(AdoRecordSet, FAdoConnection, Self,\n        LogSQL, ConSettings, ResultSetConcurrency);\n      LastUpdateCount := RC;\n      AdoRecordSet.Close;\n      AdoRecordSet := nil;\n    end\n    else\n      AdoRecordSet := FAdoConnection.GetAdoConnection.Execute(WSQL, RC, adExecuteNoRecords);\n    Result := RC;\n    LastUpdateCount := Result;\n    DriverManager.LogMessage(lcExecute, FPlainDriver.GetProtocol, LogSQL);\n  except\n    on E: Exception do\n    begin\n      DriverManager.LogError(lcExecute, FPlainDriver.GetProtocol, LogSQL, 0, E.Message);\n      raise;\n    end;\n  end\nend;\n\nfunction TZAdoStatement.Execute(const SQL: ZWideString): Boolean;\nvar\n  RC: OleVariant;\nbegin\n  try\n    {$IFDEF UNICODE}\n    WSQL := SQL;\n    {$ENDIF}\n    LastResultSet := nil;\n    LastUpdateCount := -1;\n    Self.SQL := sql;\n    if IsSelect(SSQL) then\n    begin\n      AdoRecordSet := CoRecordSet.Create;\n      AdoRecordSet.MaxRecords := MaxRows;\n      AdoRecordSet.Open(SQL, FAdoConnection.GetAdoConnection,\n        adOpenStatic, adLockOptimistic, adAsyncFetch);\n    end\n    else\n      AdoRecordSet := FAdoConnection.GetAdoConnection.Execute(WSQL, RC, adExecuteNoRecords);\n    LastResultSet := GetCurrentResultSet(AdoRecordSet, FAdoConnection, Self,\n      LogSQL, ConSettings, ResultSetConcurrency);\n    Result := Assigned(LastResultSet);\n    LastUpdateCount := RC;\n    DriverManager.LogMessage(lcExecute, FPlainDriver.GetProtocol, LogSQL);\n  except\n    on E: Exception do\n    begin\n      DriverManager.LogError(lcExecute, FPlainDriver.GetProtocol, LogSQL, 0, E.Message);\n      raise;\n    end;\n  end\nend;\n\nfunction TZAdoStatement.ExecuteQuery(const SQL: RawByteString): IZResultSet;\nbegin\n  if ASQL <> SQL then\n    ASQL := SQL;\n  Result := ExecuteQuery(WSQL);\nend;\n\nfunction TZAdoStatement.ExecuteUpdate(const SQL: RawByteString): Integer;\nbegin\n  if ASQL <> SQL then\n    ASQL := SQL;\n  Result := ExecuteUpdate(WSQL);\nend;\n\nfunction TZAdoStatement.Execute(const SQL: RawByteString): Boolean;\nbegin\n  if ASQL <> SQL then\n    ASQL := SQL;\n  Result := Execute(WSQL);\nend;\n\nfunction TZAdoStatement.GetMoreResults: Boolean;\nvar\n  RC: OleVariant;\nbegin\n  Result := False;\n  LastResultSet := nil;\n  LastUpdateCount := -1;\n  if Assigned(AdoRecordSet) then\n  begin\n    AdoRecordSet := AdoRecordSet.NextRecordset(RC);\n    LastResultSet := GetCurrentResultSet(AdoRecordSet, FAdoConnection, Self,\n      SQL, ConSettings, ResultSetConcurrency);\n    Result := Assigned(LastResultSet);\n    LastUpdateCount := RC;\n  end;\nend;\n\nconstructor TZAdoPreparedStatement.Create(PlainDriver: IZPlainDriver;\n  Connection: IZConnection; SQL: string; Info: TStrings);\nbegin\n  FAdoCommand := CoCommand.Create;\n  inherited Create(Connection, SQL, Info);\n  FAdoCommand.CommandText := WSQL;\n  FAdoConnection := Connection as IZAdoConnection;\n  FPlainDriver := PlainDriver;\n  FAdoCommand._Set_ActiveConnection(FAdoConnection.GetAdoConnection);\nend;\n\ndestructor TZAdoPreparedStatement.Destroy;\nbegin\n  AdoRecordSet := nil;\n  FAdoConnection := nil;\n  inherited;\n  FAdoCommand := nil;\nend;\n\nprocedure TZAdoPreparedStatement.PrepareInParameters;\nbegin\n  if InParamCount > 0 then\n    RefreshParameters(FAdoCommand);\n  FAdoCommand.Prepared := True;\nend;\n\nprocedure TZAdoPreparedStatement.BindInParameters;\nvar I: Integer;\nbegin\n  if InParamCount = 0 then\n    Exit\n  else\n    for i := 0 to InParamCount-1 do\n      if DefVarManager.IsNull(InParamValues[i]) then\n        if (InParamDefaultValues[i] <> '') and (UpperCase(InParamDefaultValues[i]) <> 'NULL') and\n          StrToBoolEx(DefineStatementParameter(Self, 'defaults', 'true')) then\n        begin\n          DefVarManager.SetAsString(InParamValues[i], InParamDefaultValues[i]);\n          ADOSetInParam(FAdoCommand, FAdoConnection, InParamCount, I+1, InParamTypes[i], InParamValues[i], adParamInput)\n        end\n        else\n          ADOSetInParam(FAdoCommand, FAdoConnection, InParamCount, I+1, InParamTypes[i], NullVariant, adParamInput)\n      else\n        ADOSetInParam(FAdoCommand, FAdoConnection, InParamCount, I+1, InParamTypes[i], InParamValues[i], adParamInput);\nend;\n\n{**\n  Executes the SQL query in this <code>PreparedStatement</code> object\n  and returns the result set generated by the query.\n\n  @return a <code>ResultSet</code> object that contains the data produced by the\n    query; never <code>null</code>\n}\nfunction TZAdoPreparedStatement.ExecuteQueryPrepared: IZResultSet;\nbegin\n  if not ExecutePrepared then\n    while (not GetMoreResults) and (LastUpdateCount > -1) do ;\n  Result := LastResultSet;\nend;\n\n{**\n  Executes the SQL INSERT, UPDATE or DELETE statement\n  in this <code>PreparedStatement</code> object.\n  In addition,\n  SQL statements that return nothing, such as SQL DDL statements,\n  can be executed.\n\n  @return either the row count for INSERT, UPDATE or DELETE statements;\n  or 0 for SQL statements that return nothing\n}\nfunction TZAdoPreparedStatement.ExecuteUpdatePrepared: Integer;\nbegin\n  ExecutePrepared;\n  Result := LastUpdateCount;\nend;\n\n{**\n  Executes any kind of SQL statement.\n  Some prepared statements return multiple results; the <code>execute</code>\n  method handles these complex statements as well as the simpler\n  form of statements handled by the methods <code>executeQuery</code>\n  and <code>executeUpdate</code>.\n  @see Statement#execute\n}\nfunction TZAdoPreparedStatement.ExecutePrepared: Boolean;\nvar\n  RC: OleVariant;\nbegin\n  LastResultSet := nil;\n  LastUpdateCount := -1;\n\n  Prepare;\n  BindInParameters;\n  try\n    if IsSelect(SQL) then\n    begin\n      AdoRecordSet := CoRecordSet.Create;\n      AdoRecordSet.MaxRecords := MaxRows;\n      AdoRecordSet._Set_ActiveConnection(FAdoCommand.Get_ActiveConnection);\n      AdoRecordSet.Open(FAdoCommand, EmptyParam, adOpenForwardOnly, adLockOptimistic, adAsyncFetch);\n    end\n    else\n      AdoRecordSet := FAdoCommand.Execute(RC, EmptyParam, -1{, adExecuteNoRecords});\n    LastResultSet := GetCurrentResultSet(AdoRecordSet, FAdoConnection, Self,\n      SQL, ConSettings, ResultSetConcurrency);\n    LastUpdateCount := RC;\n    Result := Assigned(LastResultSet);\n    DriverManager.LogMessage(lcExecute, FPlainDriver.GetProtocol, SQL);\n  except\n    on E: Exception do\n    begin\n      DriverManager.LogError(lcExecute, FPlainDriver.GetProtocol, SQL, 0, E.Message);\n      raise;\n    end;\n  end\nend;\n\nfunction TZAdoPreparedStatement.GetMoreResults: Boolean;\nvar\n  RC: OleVariant;\nbegin\n  Result := False;\n  LastResultSet := nil;\n  LastUpdateCount := -1;\n  if Assigned(AdoRecordSet) then\n  begin\n    AdoRecordSet := AdoRecordSet.NextRecordset(RC);\n    LastResultSet := GetCurrentResultSet(AdoRecordSet, FAdoConnection, Self,\n      SQL, ConSettings, ResultSetConcurrency);\n    Result := Assigned(LastResultSet);\n    LastUpdateCount := RC;\n  end;\nend;\n\nprocedure TZAdoPreparedStatement.Unprepare;\nbegin\n  if FAdoCommand.Prepared then\n    FAdoCommand.Prepared := False;\n  inherited;\nend;\n\n{ TZAdoCallableStatement }\n\nconstructor TZAdoCallableStatement.Create(PlainDriver: IZPlainDriver;\n  Connection: IZConnection; SQL: string; Info: TStrings);\nbegin\n  inherited Create(Connection, SQL, Info);\n  FAdoCommand := CoCommand.Create;\n  FAdoCommand.CommandText := WSQL;\n  FAdoConnection := Connection as IZAdoConnection;\n  FPlainDriver := PlainDriver;\n  FAdoCommand._Set_ActiveConnection(FAdoConnection.GetAdoConnection);\n  FAdoCommand.CommandType := adCmdStoredProc;\nend;\n\nfunction TZAdoCallableStatement.ExecuteQueryPrepared: IZResultSet;\nvar\n  I: Integer;\n  ColumnInfo: TZColumnInfo;\n  ColumnsInfo: TObjectList;\n  RS: TZVirtualResultSet;\n  IndexAlign: TIntegerDynArray;\n  P: Pointer;\n  Stream: TStream;\nbegin\n  ExecutePrepared;\n  SetLength(IndexAlign, 0);\n  ColumnsInfo := TObjectList.Create(True);\n  Stream := nil;\n  try\n    for I := 0 to FAdoCommand.Parameters.Count -1 do\n      if FAdoCommand.Parameters.Item[i].Direction in [adParamOutput,\n        adParamInputOutput, adParamReturnValue] then\n    begin\n      SetLength(IndexAlign, Length(IndexAlign)+1);\n      ColumnInfo := TZColumnInfo.Create;\n      with ColumnInfo do\n      begin\n        ColumnLabel := FAdoCommand.Parameters.Item[i].Name;\n        ColumnType := ConvertAdoToSqlType(FAdoCommand.Parameters.Item[I].Type_, ConSettings.CPType);\n        ColumnDisplaySize := FAdoCommand.Parameters.Item[I].Precision;\n        Precision := FAdoCommand.Parameters.Item[I].Precision;\n        IndexAlign[High(IndexAlign)] := I;\n      end;\n      ColumnsInfo.Add(ColumnInfo);\n    end;\n\n    RS := TZVirtualResultSet.CreateWithColumns(ColumnsInfo, '', ConSettings);\n    with RS do\n    begin\n      SetType(rtScrollInsensitive);\n      SetConcurrency(rcReadOnly);\n      RS.MoveToInsertRow;\n      for i := 1 to ColumnsInfo.Count do\n        case TZColumnInfo(ColumnsInfo[i-1]).ColumnType of\n          stBoolean:\n            RS.UpdateBoolean(i, FAdoCommand.Parameters.Item[IndexAlign[i-1]].Value);\n          stByte, stShort, stInteger, stLong:\n            RS.UpdateInt(i, FAdoCommand.Parameters.Item[IndexAlign[i-1]].Value);\n          stFloat, stDouble, stBigDecimal:\n            RS.UpdateFloat(i, FAdoCommand.Parameters.Item[IndexAlign[i-1]].Value);\n          stString:\n            RS.UpdateString(i, FAdoCommand.Parameters.Item[IndexAlign[i-1]].Value);\n          stAsciiStream:\n            begin\n              Stream := TStringStream.Create(AnsiString(FAdoCommand.Parameters.Item[IndexAlign[i-1]].Value));\n              RS.UpdateAsciiStream(I, Stream);\n              Stream.Free;\n            end;\n          stUnicodeString:\n            RS.UpdateUnicodeString(i, FAdoCommand.Parameters.Item[IndexAlign[i-1]].Value);\n          stUnicodeStream:\n            begin\n              Stream := WideStringStream(WideString(FAdoCommand.Parameters.Item[IndexAlign[i-1]].Value));\n              RS.UpdateUnicodeStream(I, Stream);\n              FreeAndNil(Stream);\n            end;\n          stBytes:\n            RS.UpdateBytes(i, FAdoCommand.Parameters.Item[IndexAlign[i-1]].Value);\n          stDate:\n            RS.UpdateDate(i, FAdoCommand.Parameters.Item[IndexAlign[i-1]].Value);\n          stTime:\n            RS.UpdateTime(i, FAdoCommand.Parameters.Item[IndexAlign[i-1]].Value);\n          stTimestamp:\n            RS.UpdateTimestamp(i, FAdoCommand.Parameters.Item[IndexAlign[i-1]].Value);\n          stBinaryStream:\n            begin\n              if VarIsStr(FAdoCommand.Parameters.Item[IndexAlign[i-1]].Value) then\n              begin\n                Stream := TStringStream.Create(AnsiString(FAdoCommand.Parameters.Item[IndexAlign[i-1]].Value));\n                RS.UpdateBinaryStream(I, Stream);\n                FreeAndNil(Stream);\n              end\n              else\n                if VarIsArray(FAdoCommand.Parameters.Item[IndexAlign[i-1]].Value) then\n                begin\n                  P := VarArrayLock(FAdoCommand.Parameters.Item[IndexAlign[i-1]].Value);\n                  try\n                    Stream := TMemoryStream.Create;\n                    Stream.Size := VarArrayHighBound(FAdoCommand.Parameters.Item[IndexAlign[i-1]].Value, 1)+1;\n                    System.Move(P^, TMemoryStream(Stream).Memory^, Stream.Size);\n                    RS.UpdateBinaryStream(I, Stream);\n                    FreeAndNil(Stream);\n                  finally\n                    VarArrayUnLock(FAdoCommand.Parameters.Item[IndexAlign[i-1]].Value);\n                  end;\n                end;\n            end\n          else\n            RS.UpdateNull(i);\n        end;\n      RS.InsertRow;\n    end;\n    Result := RS;\n  finally\n    ColumnsInfo.Free;\n    if Assigned(Stream) then Stream.Free;\n\n  end;\nend;\n\n{**\n  Executes the SQL INSERT, UPDATE or DELETE statement\n  in this <code>PreparedStatement</code> object.\n  In addition,\n  SQL statements that return nothing, such as SQL DDL statements,\n  can be executed.\n\n  @return either the row count for INSERT, UPDATE or DELETE statements;\n  or 0 for SQL statements that return nothing\n}\nfunction TZAdoCallableStatement.ExecuteUpdatePrepared: Integer;\nbegin\n  ExecutePrepared;\n  Result := LastUpdateCount;\nend;\n\n{**\n  Executes any kind of SQL statement.\n  Some prepared statements return multiple results; the <code>execute</code>\n  method handles these complex statements as well as the simpler\n  form of statements handled by the methods <code>executeQuery</code>\n  and <code>executeUpdate</code>.\n  @see Statement#execute\n}\nfunction TZAdoCallableStatement.ExecutePrepared: Boolean;\nvar\n  RC: OleVariant;\nbegin\n  LastResultSet := nil;\n  LastUpdateCount := -1;\n  if Not Prepared then Prepare;\n\n  BindInParameters;\n  try\n    if IsSelect(SQL) then\n    begin\n      AdoRecordSet := CoRecordSet.Create;\n      AdoRecordSet.MaxRecords := MaxRows;\n      AdoRecordSet._Set_ActiveConnection(FAdoCommand.Get_ActiveConnection);\n      AdoRecordSet.Open(FAdoCommand, EmptyParam, adOpenForwardOnly, adLockOptimistic, adAsyncFetch);\n    end\n    else\n      AdoRecordSet := FAdoCommand.Execute(RC, EmptyParam, -1{, adExecuteNoRecords});\n    LastResultSet := GetCurrentResultSet(AdoRecordSet, FAdoConnection, Self,\n      SQL, ConSettings, ResultSetConcurrency);\n    LastUpdateCount := RC;\n    Result := Assigned(LastResultSet);\n    DriverManager.LogMessage(lcExecute, FPlainDriver.GetProtocol, SQL);\n  except\n    on E: Exception do\n    begin\n      DriverManager.LogError(lcExecute, FPlainDriver.GetProtocol, SQL, 0, E.Message);\n      raise;\n    end;\n  end\nend;\n\nprocedure TZAdoCallableStatement.RegisterParamType(ParameterIndex: Integer;\n  ParamType: Integer);\nbegin\n  inherited RegisterParamType(ParameterIndex, ParamType);\n  if Length(FDirectionTypes) < ParameterIndex then\n    SetLength(FDirectionTypes, ParameterIndex);\n\n  case Self.FDBParamTypes[ParameterIndex-1] of\n    1: //ptInput\n      FDirectionTypes[ParameterIndex-1] := adParamInput;\n    2: //ptOut\n      FDirectionTypes[ParameterIndex-1] := adParamOutput;\n    3: //ptInputOutput\n      FDirectionTypes[ParameterIndex-1] := adParamInputOutput;\n    4: //ptResult\n      FDirectionTypes[ParameterIndex-1] := adParamReturnValue;\n    else\n      //ptUnknown\n      FDirectionTypes[ParameterIndex-1] := adParamUnknown;\n  end;\nend;\n\nfunction TZAdoCallableStatement.GetMoreResults: Boolean;\nvar\n  RC: OleVariant;\nbegin\n  Result := False;\n  LastResultSet := nil;\n  LastUpdateCount := -1;\n  if Assigned(AdoRecordSet) then\n  begin\n    AdoRecordSet := AdoRecordSet.NextRecordset(RC);\n    LastResultSet := GetCurrentResultSet(AdoRecordSet, FAdoConnection, Self,\n      SQL, ConSettings, ResultSetConcurrency);\n    Result := Assigned(LastResultSet);\n    LastUpdateCount := RC;\n  end;\nend;\n\nprocedure TZAdoCallableStatement.Unprepare;\nbegin\n  if FAdoCommand.Prepared then\n    FAdoCommand.Prepared := False;\n  inherited;\nend;\n\nfunction TZAdoCallableStatement.GetOutParam(ParameterIndex: Integer): TZVariant;\nvar\n  Temp: Variant;\n  V: Variant;\n  P: Pointer;\n  TempBlob: IZBLob;\nbegin\n\n  if ParameterIndex > OutParamCount then\n    Result := NullVariant\n  else\n  begin\n    Temp := FAdoCommand.Parameters.Item[ParameterIndex - 1].Value;\n\n    case ConvertAdoToSqlType(FAdoCommand.Parameters.Item[ParameterIndex - 1].Type_,\n      ConSettings.CPType) of\n      stBoolean:\n        DefVarManager.SetAsBoolean(Result, Temp);\n      stByte, stShort, stInteger, stLong:\n        DefVarManager.SetAsInteger(Result, Temp);\n      stFloat, stDouble, stBigDecimal:\n        DefVarManager.SetAsFloat(Result, Temp);\n      stString, stAsciiStream:\n        DefVarManager.SetAsString(Result, Temp);\n      stUnicodeString, stUnicodeStream:\n        DefVarManager.SetAsUnicodeString(Result, Temp);\n      stBytes:\n        DefVarManager.SetAsBytes(Result, VarToBytes(Temp));\n      stDate, stTime, stTimestamp:\n        DefVarManager.SetAsDateTime(Result, Temp);\n      stBinaryStream:\n        begin\n          if VarIsStr(V) then\n          begin\n            TempBlob := TZAbstractBlob.CreateWithStream(nil, GetConnection);\n            TempBlob.SetString(AnsiString(V));\n          end\n          else\n            if VarIsArray(V) then\n            begin\n              P := VarArrayLock(V);\n              try\n                TempBlob := TZAbstractBlob.CreateWithData(P, VarArrayHighBound(V, 1)+1, GetConnection);\n              finally\n                VarArrayUnLock(V);\n              end;\n            end;\n          DefVarManager.SetAsInterface(Result, TempBlob);\n          TempBlob := nil;\n        end\n      else\n        DefVarManager.SetNull(Result);\n    end;\n  end;\n\n  LastWasNull := DefVarManager.IsNull(Result) or VarIsNull(Temp) or VarIsClear(Temp);\nend;\n\nprocedure TZAdoCallableStatement.PrepareInParameters;\nbegin\n  if InParamCount > 0 then\n    RefreshParameters(FAdoCommand, @FDirectionTypes);\n  FAdoCommand.Prepared := True;\nend;\n\nprocedure TZAdoCallableStatement.BindInParameters;\nvar\n  I: Integer;\nbegin\n  if InParamCount = 0 then\n    Exit\n  else\n    for i := 0 to InParamCount-1 do\n      if FDBParamTypes[i] in [1,3] then //ptInput, ptInputOutput\n        if DefVarManager.IsNull(InParamValues[i]) then\n          if (InParamDefaultValues[i] <> '') and (UpperCase(InParamDefaultValues[i]) <> 'NULL') and\n            StrToBoolEx(DefineStatementParameter(Self, 'defaults', 'true')) then\n          begin\n            DefVarManager.SetAsString(InParamValues[i], InParamDefaultValues[i]);\n            ADOSetInParam(FAdoCommand, FAdoConnection, InParamCount, I+1, InParamTypes[i], InParamValues[i], adParamInput)\n          end\n          else\n            ADOSetInParam(FAdoCommand, FAdoConnection, InParamCount, I+1, InParamTypes[i], NullVariant, FDirectionTypes[i])\n        else\n          ADOSetInParam(FAdoCommand, FAdoConnection, InParamCount, I+1, InParamTypes[i], InParamValues[i], FDirectionTypes[i])\n      else\n        ADOSetInParam(FAdoCommand, FAdoConnection, InParamCount, I+1, InParamTypes[i], NullVariant, FDirectionTypes[i]);\nend;\n\nend.\n\n"
  },
  {
    "path": "lib/zeosdbo/src/dbc/ZDbcAdoUtils.pas",
    "content": "{*********************************************************}\n{                                                         }\n{                 Zeos Database Objects                   }\n{                 ADO Specific Utilities                  }\n{                                                         }\n{        Originally written by Janos Fegyverneki          }\n{                                                         }\n{*********************************************************}\n\n{@********************************************************}\n{    Copyright (c) 1999-2012 Zeos Development Group       }\n{                                                         }\n{ License Agreement:                                      }\n{                                                         }\n{ This library is distributed in the hope that it will be }\n{ useful, but WITHOUT ANY WARRANTY; without even the      }\n{ implied warranty of MERCHANTABILITY or FITNESS FOR      }\n{ A PARTICULAR PURPOSE.  See the GNU Lesser General       }\n{ Public License for more details.                        }\n{                                                         }\n{ The source code of the ZEOS Libraries and packages are  }\n{ distributed under the Library GNU General Public        }\n{ License (see the file COPYING / COPYING.ZEOS)           }\n{ with the following  modification:                       }\n{ As a special exception, the copyright holders of this   }\n{ library give you permission to link this library with   }\n{ independent modules to produce an executable,           }\n{ regardless of the license terms of these independent    }\n{ modules, and to copy and distribute the resulting       }\n{ executable under terms of your choice, provided that    }\n{ you also meet, for each linked independent module,      }\n{ the terms and conditions of the license of that module. }\n{ An independent module is a module which is not derived  }\n{ from or based on this library. If you modify this       }\n{ library, you may extend this exception to your version  }\n{ of the library, but you are not obligated to do so.     }\n{ If you do not wish to do so, delete this exception      }\n{ statement from your version.                            }\n{                                                         }\n{                                                         }\n{ The project web site is located on:                     }\n{   http://zeos.firmos.at  (FORUM)                        }\n{   http://sourceforge.net/p/zeoslib/tickets/ (BUGTRACKER)}\n{   svn://svn.code.sf.net/p/zeoslib/code-0/trunk (SVN)    }\n{                                                         }\n{   http://www.sourceforge.net/projects/zeoslib.          }\n{                                                         }\n{                                                         }\n{                                 Zeos Development Group. }\n{********************************************************@}\n\nunit ZDbcAdoUtils;\n\ninterface\n\n{$I ZDbc.inc}\n\nuses Windows, Classes, SysUtils, ActiveX,\n  ZDbcIntfs, ZCompatibility, ZPlainAdo, ZDbcAdo, ZVariant, ZDbcStatement;\n\ntype\n  PDirectionTypes = ^TDirectionTypes;\n  TDirectionTypes = array of TOleEnum;\n\n{**\n  Converts an ADO native types into string related.\n  @param FieldType dblibc native field type.\n  @return a string data type name.\n}\nfunction ConvertAdoToTypeName(FieldType: SmallInt): string;\n\n{**\n  Converts a Ado native types into ZDBC SQL types.\n  @param FieldType dblibc native field type.\n  @return a SQL undepended type.\n}\nfunction ConvertAdoToSqlType(const FieldType: SmallInt;\n  const CtrlsCPType: TZControlsCodePage; UseCtrsCPType: Boolean = True): TZSQLType;\n\n{**\n  Converts a Zeos type into ADO types.\n  @param FieldType zeos field type.\n  @return a ADO datatype.\n}\nfunction ConvertSqlTypeToAdo(FieldType: TZSQLType): Integer;\n\n{**\n  Converts a Variant type into ADO types.\n  @param VT Variant datatype.\n  @return a ADO datatype.\n}\n{$IFDEF FPC}\nfunction ConvertVariantToAdo(VT: Integer): Integer;\n{$ELSE}\nfunction ConvertVariantToAdo(VT: TVarType): Integer;\n{$ENDIF}\n\n{**\n  Converts a TZResultSetType type into ADO cursor type.\n  @param ResultSetType.\n  @return a ADO cursor type.\n}\nfunction ConvertResultSetTypeToAdo(ResultSetType: TZResultSetType): Integer;\n\n{**\n  Converts a TZResultSetConcurrency type into ADO lock type.\n  @param ResultSetConcurrency.\n  @return a ADO lock type.\n}\nfunction ConvertResultSetConcurrencyToAdo(ResultSetConcurrency: TZResultSetConcurrency): Integer;\n\n{**\n  Converts a OLEDB schema guid into ADO schema ID usable with OpenSchema.\n  @param OleDBSchema schema guid.\n  @return a ADO schema id.\n}\nfunction ConvertOleDBToAdoSchema(OleDBSchema: TGUID): Integer;\n\n{**\n  Brings up the ADO connection string builder dialog.\n}\nfunction PromptDataSource(Handle: THandle; InitialString: WideString): WideString;\n\nfunction GetCurrentResultSet(AdoRecordSet: ZPlainAdo.RecordSet;\n  Connection: IZAdoConnection; Statement: IZStatement; Const SQL: String;\n  ConSettings: PZConSettings;\n  const ResultSetConcurrency: TZResultSetConcurrency): IZResultSet;\n\nfunction IsSelect(const SQL: string): Boolean;\n\n{**\n  Sets a variant value into specified parameter.\n  @param AdoCommand the ole command\n  @param Connection the Connection interface\n  @param ParameterIndex a index of the parameter.\n  @param SqlType a parameter SQL type.\n  @paran Value a new parameter value.\n}\nprocedure ADOSetInParam(AdoCommand: ZPlainAdo.Command; Connection: IZConnection;\n  ParamCount: Integer; const ParameterIndex: Integer;\n  const SQLType: TZSQLType; const Value: TZVariant;\n  const ParamDirection: ParameterDirectionEnum);\n\nprocedure RefreshParameters(AdoCommand: ZPlainAdo.Command; DirectionTypes: PDirectionTypes = nil);\n\nvar\n{**\n  Required to free memory allocated by oledb\n}\n  ZAdoMalloc: IMalloc;\n\nimplementation\n\nuses\n  ComObj, OleDB, Variants,\n  ZSysUtils, ZDbcAdoResultSet, ZDbcCachedResultSet, ZDbcResultSet, ZEncoding;\n\n{**\n  Converts an ADO native types into string related.\n  @param FieldType dblibc native field type.\n  @return a string data type name.\n}\nfunction ConvertAdoToTypeName(FieldType: SmallInt): string;\nbegin\n  case FieldType of\n    adChar             : Result := 'Char';\n    adVarChar          : Result := 'VarChar';\n    adBSTR             : Result := 'BSTR';\n    adWChar            : Result := 'WChar';\n    adVarWChar         : Result := 'VarWChar';\n    adBoolean          : Result := 'Boolean';\n    adTinyInt          : Result := 'TinyInt';\n    adUnsignedTinyInt  : Result := 'UnsignedTinyInt';\n    adSmallInt         : Result := 'SmallInt';\n    adUnsignedSmallInt : Result := 'UnsignedSmallInt';\n    adInteger          : Result := 'Integer';\n    adUnsignedInt      : Result := 'UnsignedInt';\n    adBigInt           : Result := 'BigInt';\n    adUnsignedBigInt   : Result := 'UnsignedBigInt';\n    adSingle           : Result := 'Single';\n    adDouble           : Result := 'Double';\n    adDecimal          : Result := 'Decimal';\n    adNumeric          : Result := 'Numeric';\n    adVarNumeric       : Result := 'VarNumeric';\n    adCurrency         : Result := 'Currency';\n    adDBDate           : Result := 'DBDate';\n    adDBTime           : Result := 'DBTime';\n    adDate             : Result := 'Date';\n    adDBTimeStamp      : Result := 'DBTimeStamp';\n    adFileTime         : Result := 'FileTime';\n    adLongVarChar      : Result := 'LongVarChar';\n    adLongVarWChar     : Result := 'LongVarWChar';\n    adBinary           : Result := 'Binary';\n    adVarBinary        : Result := 'VarBinary';\n    adLongVarBinary    : Result := 'LongVarBinary';\n    adGUID             : Result := 'GUID';\n    adEmpty            : Result := 'Empty';\n    adError            : Result := 'Error';\n    adArray            : Result := 'Array';\n    adChapter          : Result := 'Chapter';\n    adIDispatch        : Result := 'IDispatch';\n    adIUnknown         : Result := 'IUnknown';\n    adPropVariant      : Result := 'PropVariant';\n    adUserDefined      : Result := 'UserDefined';\n    adVariant          : Result := 'Variant';\n  else\n    Result := 'Unknown';\n  end;\nend;\n\n{**\n  Converts a Ado native types into ZDBC SQL types.\n  @param FieldType dblibc native field type.\n  @return a SQL undepended type.\n}\nfunction ConvertAdoToSqlType(const FieldType: SmallInt;\n  const CtrlsCPType: TZControlsCodePage; UseCtrsCPType: Boolean = True): TZSQLType;\nbegin\n  case FieldType of\n    adChar, adVarChar, adBSTR: Result := stString;\n    adWChar, adVarWChar: Result := stUnicodeString;\n    adBoolean: Result := stBoolean;\n//Bug #889223, bug with tinyint on mssql\n//    adTinyInt, adUnsignedTinyInt: Result := stByte;\n    adTinyInt, adUnsignedTinyInt: Result := stShort;\n    adSmallInt, adUnsignedSmallInt: Result := stShort;\n    adInteger, adUnsignedInt: Result := stInteger;\n    adBigInt, adUnsignedBigInt: Result := stLong;\n    adSingle: Result := stFloat;\n    adDouble: Result := stDouble;\n    adDecimal: Result := stBigDecimal;\n    adNumeric, adVarNumeric: Result := stBigDecimal;\n    adCurrency: Result := stBigDecimal;\n    adDBDate: Result := stDate;\n    adDBTime: Result := stTime;\n    adDate : Result := stDate;\n    adDBTimeStamp, adFileTime: Result := stTimestamp;\n    adLongVarChar: Result := stAsciiStream;\n    adLongVarWChar: Result := stUnicodeStream;\n    adBinary, adVarBinary: Result := stBytes;\n    adLongVarBinary: Result := stBinaryStream;\n    adGUID: Result := stGUID;\n\n    adEmpty, adError, AdArray, adChapter, adIDispatch, adIUnknown,\n    adPropVariant, adUserDefined, adVariant: Result := stString;\n  else\n    Result := stString;\n  end;\n  if UseCtrsCPType then\n    case CtrlsCPType of\n      cCP_UTF16:\n        case Result of\n          stString: Result := stUnicodeString;\n          stAsciiStream: Result := stUnicodeStream;\n        end;\n      else\n        case Result of\n          stUnicodeString: Result := stString;\n          stUnicodeStream: Result := stAsciiStream;\n        end;\n    end;\nend;\n\n{**\n  Converts a Zeos type into ADO types.\n  @param FieldType zeos field type.\n  @return a ADO datatype.\n}\nfunction ConvertSqlTypeToAdo(FieldType: TZSQLType): Integer;\nbegin\n  case FieldType of\n    stString: Result := adVarChar;\n    stUnicodeString: Result := adVarWChar;\n    stBoolean: Result := adBoolean;\n    stByte: Result := adTinyInt;\n    stShort: Result := adSmallInt;\n    stInteger: Result := adInteger;\n    stLong: Result := adBigInt;\n    stBigDecimal: Result := adDecimal;\n    stFloat: Result := adSingle;\n    stDouble: Result := adDouble;\n    stDate: Result := adDBDate;\n    stTime: Result := adDBTime;\n    stTimestamp: Result := adDBTimeStamp;\n    stBytes: Result := adVarBinary;\n    stGUID: Result := adGUID;\n    stAsciiStream: Result := adLongVarChar;\n    stUnicodeStream: Result := adLongVarWChar;\n    stBinaryStream: Result := adLongVarBinary;\n  else\n    Result := adEmpty;\n  end;\nend;\n\n{**\n  Converts a Variant type into ADO types.\n  @param VT Variant datatype.\n  @return a ADO datatype.\n}\n{$IFDEF FPC}\nfunction ConvertVariantToAdo(VT: Integer): Integer;\n{$ELSE}\nfunction ConvertVariantToAdo(VT: TVarType): Integer;\n{$ENDIF}\nbegin\n  case VT and varTypeMask of\n    varEmpty: Result := adEmpty;\n    varNull: Result := adVarChar;\n    varSmallint: Result := adSmallInt;\n    varInteger: Result := adInteger;\n    varSingle: Result := adSingle;\n    varDouble: Result := adDouble;\n    varCurrency: Result := adCurrency;\n    varDate: Result := adDate;\n    varOleStr: Result := adVarWChar;\n    varDispatch: Result := adIDispatch;\n    varError: Result := adError;\n    varBoolean: Result := adBoolean;\n    varVariant: Result := adVariant;\n    varUnknown: Result := adIUnknown;\n{$IFNDEF FPC}\n    varShortInt: Result := adTinyInt;\n{$ENDIF}\n    varByte: if (VT and varArray) <> 0 then Result := adLongVarBinary else Result := adUnsignedTinyInt;\n{$IFNDEF FPC}\n    varWord: Result := adUnsignedSmallInt;\n    varLongWord: Result := adUnsignedInt;\n    varInt64: Result := adBigInt;\n{$ENDIF}\n    varStrArg: Result := adWChar;\n    varString: Result := adVarChar;\n{$IFDEF UNICODE}\n    varUString: Result := adVarChar;\n{$ENDIF}\n    varAny: Result := adEmpty;\n  else\n    Result := adEmpty;\n  end;\nend;\n\n\n{**\n  Converts a TZResultSetType type into ADO cursor type.\n  @param ResultSetType.\n  @return a ADO cursor type.\n}\nfunction ConvertResultSetTypeToAdo(ResultSetType: TZResultSetType): Integer;\nbegin\n  case ResultSetType of\n    rtForwardOnly: Result := adOpenForwardOnly;\n    rtScrollInsensitive: Result := adOpenStatic;\n    rtScrollSensitive: Result := adOpenDynamic;\n  else\n    Result := -1;//adOpenUnspecified;\n  end\nend;\n\n{**\n  Converts a TZResultSetConcurrency type into ADO lock type.\n  @param ResultSetConcurrency.\n  @return a ADO lock type.\n}\nfunction ConvertResultSetConcurrencyToAdo(ResultSetConcurrency: TZResultSetConcurrency): Integer;\nbegin\n  case ResultSetConcurrency of\n    rcReadOnly: Result := adLockReadOnly;\n    rcUpdatable: Result := adLockOptimistic;\n  else\n    Result := -1;//adLockUnspecified;\n  end\nend;\n\n{**\n  Converts a OLEDB schema guid into ADO schema ID usable with OpenSchema.\n  @param OleDBSchema schema guid.\n  @return a ADO schema id.\n}\nfunction ConvertOleDBToAdoSchema(OleDBSchema: TGUID): Integer;\nbegin\n  Result := -1;\n  if IsEqualGuid(OleDBSchema, DBSCHEMA_ASSERTIONS) then Result := 0;\n  if IsEqualGuid(OleDBSchema, DBSCHEMA_CATALOGS) then Result := 1;\n  if IsEqualGuid(OleDBSchema, DBSCHEMA_CHARACTER_SETS) then Result := 2;\n  if IsEqualGuid(OleDBSchema, DBSCHEMA_COLLATIONS) then Result := 3;\n  if IsEqualGuid(OleDBSchema, DBSCHEMA_COLUMNS) then Result := 4;\n  if IsEqualGuid(OleDBSchema, DBSCHEMA_CHECK_CONSTRAINTS) then Result := 5;\n  if IsEqualGuid(OleDBSchema, DBSCHEMA_CONSTRAINT_COLUMN_USAGE) then Result := 6;\n  if IsEqualGuid(OleDBSchema, DBSCHEMA_CONSTRAINT_TABLE_USAGE) then Result := 7;\n  if IsEqualGuid(OleDBSchema, DBSCHEMA_KEY_COLUMN_USAGE) then Result := 8;\n  if IsEqualGuid(OleDBSchema, DBSCHEMA_REFERENTIAL_CONSTRAINTS) then Result := 9;\n  if IsEqualGuid(OleDBSchema, DBSCHEMA_TABLE_CONSTRAINTS) then Result := 10;\n  if IsEqualGuid(OleDBSchema, DBSCHEMA_COLUMN_DOMAIN_USAGE) then Result := 11;\n  if IsEqualGuid(OleDBSchema, DBSCHEMA_INDEXES) then Result := 12;\n  if IsEqualGuid(OleDBSchema, DBSCHEMA_COLUMN_PRIVILEGES) then Result := 13;\n  if IsEqualGuid(OleDBSchema, DBSCHEMA_TABLE_PRIVILEGES) then Result := 14;\n  if IsEqualGuid(OleDBSchema, DBSCHEMA_USAGE_PRIVILEGES) then Result := 15;\n  if IsEqualGuid(OleDBSchema, DBSCHEMA_PROCEDURES) then Result := 16;\n  if IsEqualGuid(OleDBSchema, DBSCHEMA_SCHEMATA) then Result := 17;\n  if IsEqualGuid(OleDBSchema, DBSCHEMA_SQL_LANGUAGES) then Result := 18;\n  if IsEqualGuid(OleDBSchema, DBSCHEMA_STATISTICS) then Result := 19;\n  if IsEqualGuid(OleDBSchema, DBSCHEMA_TABLES) then Result := 20;\n  if IsEqualGuid(OleDBSchema, DBSCHEMA_TRANSLATIONS) then Result := 21;\n  if IsEqualGuid(OleDBSchema, DBSCHEMA_PROVIDER_TYPES) then Result := 22;\n  if IsEqualGuid(OleDBSchema, DBSCHEMA_VIEWS) then Result := 23;\n  if IsEqualGuid(OleDBSchema, DBSCHEMA_VIEW_COLUMN_USAGE) then Result := 24;\n  if IsEqualGuid(OleDBSchema, DBSCHEMA_VIEW_TABLE_USAGE) then Result := 25;\n  if IsEqualGuid(OleDBSchema, DBSCHEMA_PROCEDURE_PARAMETERS) then Result := 26;\n  if IsEqualGuid(OleDBSchema, DBSCHEMA_FOREIGN_KEYS) then Result := 27;\n  if IsEqualGuid(OleDBSchema, DBSCHEMA_PRIMARY_KEYS) then Result := 28;\n  if IsEqualGuid(OleDBSchema, DBSCHEMA_PROCEDURE_COLUMNS) then Result := 29;\n  if IsEqualGuid(OleDBSchema, MDSCHEMA_CUBES) then Result := 32;\n  if IsEqualGuid(OleDBSchema, MDSCHEMA_DIMENSIONS) then Result := 33;\n  if IsEqualGuid(OleDBSchema, MDSCHEMA_HIERARCHIES) then Result := 34;\n  if IsEqualGuid(OleDBSchema, MDSCHEMA_LEVELS) then Result := 35;\n  if IsEqualGuid(OleDBSchema, MDSCHEMA_MEASURES) then Result := 36;\n  if IsEqualGuid(OleDBSchema, MDSCHEMA_PROPERTIES) then Result := 37;\n  if IsEqualGuid(OleDBSchema, MDSCHEMA_MEMBERS) then Result := 38;\n  if IsEqualGuid(OleDBSchema, DBPROPSET_TRUSTEE) then Result := 39;\nend;\n\n{**\n  Brings up the ADO connection string builder dialog.\n}\nfunction PromptDataSource(Handle: THandle; InitialString: WideString): WideString;\nvar\n  DataInit: IDataInitialize;\n  DBPrompt: IDBPromptInitialize;\n  DataSource: IUnknown;\n  InitStr: PWideChar;\nbegin\n  Result := InitialString;\n  DataInit := CreateComObject(CLSID_DataLinks) as IDataInitialize;\n  if InitialString <> '' then\n    DataInit.GetDataSource(nil, CLSCTX_INPROC_SERVER,\n      PWideChar(InitialString), IUnknown, DataSource);\n  DBPrompt := CreateComObject(CLSID_DataLinks) as IDBPromptInitialize;\n  if Succeeded(DBPrompt.PromptDataSource(nil, Handle,\n    DBPROMPTOPTIONS_PROPERTYSHEET, 0, nil, nil, IUnknown, DataSource)) then\n  begin\n    InitStr := nil;\n    DataInit.GetInitializationString(DataSource, True, InitStr);\n    Result := InitStr;\n  end;\nend;\n\nfunction GetCurrentResultSet(AdoRecordSet: ZPlainAdo.RecordSet;\n  Connection: IZAdoConnection; Statement: IZStatement; Const SQL: String; ConSettings: PZConSettings;\n  const ResultSetConcurrency: TZResultSetConcurrency): IZResultSet;\nvar\n  NativeResultSet: IZResultSet;\nbegin\n  Result := nil;\n  if Assigned(AdoRecordset) then\n    if (AdoRecordSet.State and adStateOpen) = adStateOpen then\n    begin\n      NativeResultSet := TZAdoResultSet.Create(Statement, SQL, AdoRecordSet);\n      if ResultSetConcurrency = rcUpdatable then\n        Result := TZCachedResultSet.Create(NativeResultSet, SQL,\n          TZAdoCachedResolver.Create(Connection.GetAdoConnection,\n          Statement, NativeResultSet.GetMetaData), ConSettings)\n      else\n        Result := NativeResultSet;\n    end;\nend;\n\nfunction IsSelect(const SQL: string): Boolean;\nbegin\n  Result := Uppercase(Copy(TrimLeft(Sql), 1, 6)) = 'SELECT';\nend;\n\n{**\n  Sets a variant value into specified parameter.\n  @param AdoCommand the ole command\n  @param Connection the Connection interface\n  @param ParameterIndex a index of the parameter.\n  @param SqlType a parameter SQL type.\n  @paran Value a new parameter value.\n}\nprocedure ADOSetInParam(AdoCommand: ZPlainAdo.Command; Connection: IZConnection;\n  ParamCount: Integer; const ParameterIndex: Integer;\n  const SQLType: TZSQLType; const Value: TZVariant;\n  const ParamDirection: ParameterDirectionEnum);\nvar\n  S: Integer;\n  B: IZBlob;\n  V: Variant;\n  T: Integer;\n  P: ZPlainAdo.Parameter;\n  RetValue: TZVariant;\n  TmpSQLType: TZSQLType;\nbegin\n  RetValue:= Value;\n  TmpSQLType := SQLType;\n  if not (RetValue.VType = vtNull) and (RetValue.VType = vtInterface) and\n    (SQLType in [stAsciiStream, stUnicodeStream, stBinaryStream]) then\n  begin\n    B := DefVarManager.GetAsInterface(Value) as IZBlob;\n    if B.IsEmpty then\n      RetValue := NullVariant\n    else\n      case SQLType of\n        stAsciiStream:\n          begin\n            {$IFDEF UNICODE}\n            DefVarManager.SetAsString(RetValue, String(B.GetString));\n            {$ELSE}\n            DefVarManager.SetAsString(RetValue, GetValidatedAnsiStringFromBuffer(B.GetBuffer, B.Length, Connection.GetConSettings));\n            {$ENDIF}\n            TmpSQLType := stString;\n          end;\n        stUnicodeStream:\n          begin\n            if B.Connection = nil then\n              B := TZAbstractBlob.CreateWithData(B.GetBuffer, B.Length, Connection, B.WasDecoded);\n            DefVarManager.SetAsUnicodeString(RetValue, B.GetUnicodeString);\n            TmpSQLType := stUnicodeString;\n          end;\n        stBinaryStream:\n          begin\n            if Assigned(B) then\n              DefVarManager.SetAsBytes(RetValue, B.GetBytes);\n            TmpSQLType := stBytes;\n          end;\n      end;\n  end;\n\n  case RetValue.VType of\n    vtNull: V := Null;\n    vtBoolean: V := SoftVarManager.GetAsBoolean(RetValue);\n    vtBytes: V := SoftVarManager.GetAsBytes(RetValue);\n    vtInteger: V := Integer(SoftVarManager.GetAsInteger(RetValue));\n    vtFloat: V := SoftVarManager.GetAsFloat(RetValue);\n    vtString:\n      {$IFDEF UNICODE}\n      V := SoftVarManager.GetAsString(RetValue);\n      {$ELSE}\n      if ParamDirection = adParamInputOutput then //can't say why but bidirectional params need to be converted first.\n        //On the other hand they where not refreshed after second call! Is there a problem with Variant vs. OleVariant and strings?\n      begin\n        V := WideString(SoftVarManager.GetAsString(RetValue));\n        TmpSQLType := stUnicodeString;\n      end\n      else\n        if SQLType = stAsciiStream then\n          V := SoftVarManager.GetAsString(RetValue)\n        else\n          V := Connection.GetIZPlainDriver.ZPlainString(SoftVarManager.GetAsString(RetValue), Connection.GetConSettings);\n      {$ENDIF}\n    vtUnicodeString: V := WideString(SoftVarManager.GetAsUnicodeString(RetValue));\n    vtDateTime: V := TDateTime(SoftVarManager.GetAsDateTime(RetValue));\n  end;\n\n  S := 0; //init val\n  case TmpSQLType of\n    stString:\n      begin\n        S := Length(VarToStr(V));\n        if S = 0 then S := 1;\n        //V := Null; patch by zx - see http://zeos.firmos.at/viewtopic.php?t=1255\n      end;\n    stUnicodeString:\n      begin\n        S := Length(VarToWideStr(V))*2; //strange! Need size in bytes!!\n        if S = 0 then S := 1;\n        //V := Null; patch by zx - see http://zeos.firmos.at/viewtopic.php?t=1255\n      end;\n    stBytes:\n      begin\n        //V := StrToBytes(VarToStr(V));\n        if (VarType(V) and varArray) <> 0 then\n          S := VarArrayHighBound(V, 1) + 1;\n        if S = 0 then V := Null;\n      end;\n  end;\n\n  if VarIsNull(V) or (SQLType = stBytes) then\n    T := ConvertSqlTypeToAdo(TmpSQLType)\n  else\n    T := ConvertVariantToAdo(VarType(V));\n\n  if ParameterIndex <= ParamCount then\n  begin\n    P := AdoCommand.Parameters.Item[ParameterIndex - 1];\n    P.Direction := ParamDirection; //set ParamDirection! Bidirection is requires for callables f.e.\n    if not VarIsNull(V) then //align new size and type\n    begin\n      P.Type_ := T;\n      P.Size := S;\n    end;\n    if VarIsClear(P.Value) or (P.Value <> V) or (TmpSQLType = stBytes) then //Check if Param is cleared, unasigned or different\n      P.Value := V;\n  end\n  else\n    AdoCommand.Parameters.Append(AdoCommand.CreateParameter(\n      'P' + IntToStr(ParameterIndex), T, ParamDirection, S, V));\nend;\n\nprocedure RefreshParameters(AdoCommand: ZPlainAdo.Command;\n  DirectionTypes: PDirectionTypes = nil);\n  procedure RefreshFromOleDB;\n  var\n    I: Integer;\n    ParamCount: NativeUInt;\n    ParamInfo: PDBParamInfoArray;\n    NamesBuffer: POleStr;\n    Name: WideString;\n    Parameter: _Parameter;\n    Direction: ParameterDirectionEnum;\n    OLEDBCommand: ICommand;\n    OLEDBParameters: ICommandWithParameters;\n    CommandPrepare: ICommandPrepare;\n  begin\n    OLEDBCommand := (AdoCommand as ADOCommandConstruction).OLEDBCommand as ICommand;\n    OLEDBCommand.QueryInterface(ICommandWithParameters, OLEDBParameters);\n    OLEDBParameters.SetParameterInfo(0, nil, nil);\n    if Assigned(OLEDBParameters) then\n    begin\n      ParamInfo := nil;\n      NamesBuffer := nil;\n      try\n        OLEDBCommand.QueryInterface(ICommandPrepare, CommandPrepare);\n        if Assigned(CommandPrepare) then CommandPrepare.Prepare(0);\n        if OLEDBParameters.GetParameterInfo(ParamCount, PDBPARAMINFO(ParamInfo), @NamesBuffer) = S_OK then\n          for I := 0 to ParamCount - 1 do\n            with ParamInfo[I] do\n            begin\n              { When no default name, fabricate one like ADO does }\n              if pwszName = nil then\n                Name := 'Param' + IntToStr(I+1) else { Do not localize }\n                Name := pwszName;\n              { ADO maps DBTYPE_BYTES to adVarBinary }\n              if wType = DBTYPE_BYTES then wType := adVarBinary;\n              { ADO maps DBTYPE_STR to adVarChar }\n              if wType = DBTYPE_STR then wType := adVarChar;\n              { ADO maps DBTYPE_WSTR to adVarWChar }\n              if wType = DBTYPE_WSTR then wType := adVarWChar;\n              Direction := dwFlags and $F;\n              { Verify that the Direction is initialized }\n              if Assigned(DirectionTypes) then\n                Parameter := AdoCommand.CreateParameter(Name, wType, DirectionTypes^[i], ulParamSize, EmptyParam)\n              else\n              begin\n                if Direction = adParamUnknown then Direction := adParamInput;\n                Parameter := AdoCommand.CreateParameter(Name, wType, Direction, ulParamSize, EmptyParam);\n              end;\n              Parameter.Precision := bPrecision;\n              Parameter.NumericScale := ParamInfo[I].bScale;\n              Parameter.Attributes := dwFlags and $FFFFFFF0; { Mask out Input/Output flags }\n            end;\n      finally\n        if Assigned(CommandPrepare) then CommandPrepare.Unprepare;\n        if (ParamInfo <> nil) then ZAdoMalloc.Free(ParamInfo);\n        if (NamesBuffer <> nil) then ZAdoMalloc.Free(NamesBuffer);\n      end;\n    end;\n  end;\n\n  procedure RefreshFromADO;\n  var\n    I: Integer;\n    Parameter: _Parameter;\n  begin\n    with AdoCommand do\n    try\n      Parameters.Refresh;\n      for I := 0 to Parameters.Count - 1 do\n        with Parameters[I] do\n        begin\n        { We can't use the instance of the parameter in the ADO collection because\n          it will be freed when the connection is closed even though we have a\n          reference to it.  So instead we create our own and copy the settings }\n          if Assigned(DirectionTypes) then\n            Parameter := CreateParameter(Name, Type_, DirectionTypes^[i], Size, EmptyParam)\n          else\n            Parameter := CreateParameter(Name, Type_, Direction, Size, EmptyParam);\n          Parameter.Precision := Precision;\n          Parameter.NumericScale := NumericScale;\n          Parameter.Attributes := Attributes;\n        end;\n    except\n      { do nothing }\n    end;\n  end;\nbegin\n  if ( AdoCommand.CommandType = adCmdText ) then\n    RefreshFromOLEDB else\n    RefreshFromADO;\nend;\n\ninitialization\n  OleCheck(CoGetMalloc(1, ZAdoMalloc));\nfinalization\n  ZAdoMalloc := nil;\nend.\n\n\n"
  },
  {
    "path": "lib/zeosdbo/src/dbc/ZDbcCache.pas",
    "content": "{*********************************************************}\n{                                                         }\n{                 Zeos Database Objects                   }\n{            Caching Classes and Interfaces               }\n{                                                         }\n{        Originally written by Sergey Seroukhov           }\n{                                                         }\n{*********************************************************}\n\n{@********************************************************}\n{    Copyright (c) 1999-2012 Zeos Development Group       }\n{                                                         }\n{ License Agreement:                                      }\n{                                                         }\n{ This library is distributed in the hope that it will be }\n{ useful, but WITHOUT ANY WARRANTY; without even the      }\n{ implied warranty of MERCHANTABILITY or FITNESS FOR      }\n{ A PARTICULAR PURPOSE.  See the GNU Lesser General       }\n{ Public License for more details.                        }\n{                                                         }\n{ The source code of the ZEOS Libraries and packages are  }\n{ distributed under the Library GNU General Public        }\n{ License (see the file COPYING / COPYING.ZEOS)           }\n{ with the following  modification:                       }\n{ As a special exception, the copyright holders of this   }\n{ library give you permission to link this library with   }\n{ independent modules to produce an executable,           }\n{ regardless of the license terms of these independent    }\n{ modules, and to copy and distribute the resulting       }\n{ executable under terms of your choice, provided that    }\n{ you also meet, for each linked independent module,      }\n{ the terms and conditions of the license of that module. }\n{ An independent module is a module which is not derived  }\n{ from or based on this library. If you modify this       }\n{ library, you may extend this exception to your version  }\n{ of the library, but you are not obligated to do so.     }\n{ If you do not wish to do so, delete this exception      }\n{ statement from your version.                            }\n{                                                         }\n{                                                         }\n{ The project web site is located on:                     }\n{   http://zeos.firmos.at  (FORUM)                        }\n{   http://sourceforge.net/p/zeoslib/tickets/ (BUGTRACKER)}\n{   svn://svn.code.sf.net/p/zeoslib/code-0/trunk (SVN)    }\n{                                                         }\n{   http://www.sourceforge.net/projects/zeoslib.          }\n{                                                         }\n{                                                         }\n{                                 Zeos Development Group. }\n{********************************************************@}\n\nunit ZDbcCache;\n\ninterface\n\n{$I ZDbc.inc}\n\n\nuses\n{$IFDEF MSWINDOWS}\n  Windows,\n{$ENDIF}\n  Types, Classes, {$IFDEF MSEgui}mclasses,{$ENDIF} SysUtils, Contnrs,\n  ZClasses, ZDbcIntfs, ZDbcResultSet, ZDbcResultSetMetadata, ZVariant,\n  ZCompatibility;\n\ntype\n\n  {** Defines a row status type. }\n  TZRowUpdateType = (utUnmodified, utModified, utInserted, utDeleted);\n  TZRowUpdateTypes = set of TZRowUpdateType;\n\n  TZByteArray = array[0..4096 * SizeOf(Pointer)] of Byte;\n  {** Defines a header for row buffer. }\n  {ludob. Notes on alignment:\n  Columns contains a record per field with the structure\n    null:byte;\n    fielddata:anything;\n  field records are addressed through offsets in Columns stored in FColumnOffsets.\n  Since anything can be stored as fielddata including pointers, fielddata needs\n  to be aligned to pointer. To do this Columns is aligned to pointer and\n  FColumnOffsets is aligned to pointer - 1 (the null:byte). The latter is\n  done in TZRowAccessor.Create where FColumnOffsets is filled in.\n  FPC_REQUIRES_PROPER_ALIGNMENT is a fpc build in define}\n  TZRowBuffer = {$ifndef FPC_REQUIRES_PROPER_ALIGNMENT}packed{$endif} record\n    Index: Integer;\n    UpdateType: TZRowUpdateType;\n    BookmarkFlag: Byte;\n    {$ifdef FPC_REQUIRES_PROPER_ALIGNMENT}\n    dummyalign:pointer;\n    {$endif}\n    Columns: TZByteArray;\n  end;\n  PZRowBuffer = ^TZRowBuffer;\n\n  {** Implements a column buffer accessor. }\n  TZRowAccessor = class(TZCodePagedObject)\n  private\n    FRowSize: Integer;\n    FColumnsSize: Integer;\n    FColumnCount: Integer;\n    FColumnNames: array of string;\n    FColumnCases: array of Boolean;\n    FColumnTypes: array of TZSQLType;\n    FColumnLengths: array of Integer;\n    FColumnOffsets: array of Integer;\n    FColumnDefaultExpressions: array of string;\n    FBuffer: PZRowBuffer;\n    FHasBlobs: Boolean;\n    FTemp: String;\n\n    function GetColumnSize(ColumnInfo: TZColumnInfo): Integer;\n    function GetBlobObject(Buffer: PZRowBuffer; ColumnIndex: Integer): IZBlob;\n    procedure SetBlobObject(Buffer: PZRowBuffer; ColumnIndex: Integer;\n      Value: IZBlob);\n    function InternalGetBytes(Buffer: PZRowBuffer; ColumnIndex: Integer): TByteDynArray;\n    procedure InternalSetBytes(Buffer: PZRowBuffer; ColumnIndex: Integer;\n      Value: TByteDynArray; NewPointer: Boolean = False);\n    procedure InternalSetString(Buffer: PZRowBuffer; ColumnIndex: Integer;\n      Value: String; NewPointer: Boolean = False);\n    procedure InternalSetUnicodeString(Buffer: PZRowBuffer; ColumnIndex: Integer;\n      Value: ZWideString; NewPointer: Boolean = False);\n  protected\n    procedure CheckColumnIndex(ColumnIndex: Integer);\n    procedure CheckColumnConvertion(ColumnIndex: Integer; ResultType: TZSQLType);\n\n  public\n    constructor Create(ColumnsInfo: TObjectList; ConSettings: PZConSettings);\n    destructor Destroy; override;\n\n    function AllocBuffer(var Buffer: PZRowBuffer): PZRowBuffer;\n    procedure InitBuffer(Buffer: PZRowBuffer);\n    procedure CopyBuffer(SrcBuffer: PZRowBuffer; DestBuffer: PZRowBuffer);\n    procedure MoveBuffer(SrcBuffer: PZRowBuffer; DestBuffer: PZRowBuffer);\n    procedure CloneBuffer(SrcBuffer: PZRowBuffer; DestBuffer: PZRowBuffer);\n    procedure ClearBuffer(Buffer: PZRowBuffer);\n    procedure DisposeBuffer(Buffer: PZRowBuffer);\n\n    function CompareBuffers(Buffer1, Buffer2: PZRowBuffer;\n      ColumnIndices: TIntegerDynArray; ColumnDirs: TBooleanDynArray): Integer;\n\n    function Alloc: PZRowBuffer;\n    procedure Init;\n    procedure CopyTo(DestBuffer: PZRowBuffer);\n    procedure CopyFrom(SrcBuffer: PZRowBuffer);\n    procedure MoveTo(DestBuffer: PZRowBuffer);\n    procedure MoveFrom(SrcBuffer: PZRowBuffer);\n    procedure CloneTo(DestBuffer: PZRowBuffer);\n    procedure CloneFrom(SrcBuffer: PZRowBuffer);\n    procedure Clear;\n    procedure Dispose;\n\n    function GetColumnData(ColumnIndex: Integer; var IsNull: Boolean): Pointer;\n    function GetColumnDataSize(ColumnIndex: Integer): Integer;\n\n    function GetColumnName(ColumnIndex: Integer): string;\n    function GetColumnCase(ColumnIndex: Integer): Boolean;\n    function GetColumnType(ColumnIndex: Integer): TZSQLType;\n    function GetColumnLength(ColumnIndex: Integer): Integer;\n    function GetColumnOffSet(ColumnIndex: Integer): Integer;\n    function GetColumnDefaultExpression(ColumnIndex: Integer): string;\n    procedure SetColumnDefaultExpression(ColumnIndex: Integer; Value: string);\n\n    //======================================================================\n    // Methods for accessing results by column index\n    //======================================================================\n\n    function IsNull(ColumnIndex: Integer): Boolean;\n    function GetPChar(ColumnIndex: Integer; var IsNull: Boolean): PChar;\n    function GetString(ColumnIndex: Integer; var IsNull: Boolean): String;\n    function GetUnicodeString(ColumnIndex: Integer; var IsNull: Boolean): WideString;\n    function GetBoolean(ColumnIndex: Integer; var IsNull: Boolean): Boolean;\n    function GetByte(ColumnIndex: Integer; var IsNull: Boolean): ShortInt;\n    function GetShort(ColumnIndex: Integer; var IsNull: Boolean): SmallInt;\n    function GetInt(ColumnIndex: Integer; var IsNull: Boolean): Integer;\n    function GetLong(ColumnIndex: Integer; var IsNull: Boolean): Int64;\n    function GetFloat(ColumnIndex: Integer; var IsNull: Boolean): Single;\n    function GetDouble(ColumnIndex: Integer; var IsNull: Boolean): Double;\n    function GetBigDecimal(ColumnIndex: Integer; var IsNull: Boolean): Extended;\n    function GetBytes(ColumnIndex: Integer; var IsNull: Boolean): TByteDynArray;\n    function GetDate(ColumnIndex: Integer; var IsNull: Boolean): TDateTime;\n    function GetTime(ColumnIndex: Integer; var IsNull: Boolean): TDateTime;\n    function GetTimestamp(ColumnIndex: Integer; var IsNull: Boolean): TDateTime;\n    function GetAsciiStream(ColumnIndex: Integer; var IsNull: Boolean): TStream;\n    function GetUnicodeStream(ColumnIndex: Integer; var IsNull: Boolean): TStream;\n    function GetBinaryStream(ColumnIndex: Integer; var IsNull: Boolean): TStream;\n    function GetBlob(ColumnIndex: Integer; var IsNull: Boolean): IZBlob;\n    function GetDataSet(ColumnIndex: Integer; var IsNull: Boolean): IZDataSet;\n    function GetValue(ColumnIndex: Integer): TZVariant;\n\n    //---------------------------------------------------------------------\n    // Updates\n    //---------------------------------------------------------------------\n\n    procedure SetNotNull(ColumnIndex: Integer);\n    procedure SetNull(ColumnIndex: Integer);\n    procedure SetBoolean(ColumnIndex: Integer; Value: Boolean);\n    procedure SetByte(ColumnIndex: Integer; Value: ShortInt);\n    procedure SetShort(ColumnIndex: Integer; Value: SmallInt);\n    procedure SetInt(ColumnIndex: Integer; Value: Integer);\n    procedure SetLong(ColumnIndex: Integer; Value: Int64);\n    procedure SetFloat(ColumnIndex: Integer; Value: Single);\n    procedure SetDouble(ColumnIndex: Integer; Value: Double);\n    procedure SetBigDecimal(ColumnIndex: Integer; Value: Extended);\n    procedure SetPChar(ColumnIndex: Integer; Value: PChar);\n    procedure SetString(ColumnIndex: Integer; Value: String);\n    procedure SetUnicodeString(ColumnIndex: Integer; Value: WideString);\n    procedure SetBytes(ColumnIndex: Integer; Value: TByteDynArray);\n    procedure SetDate(ColumnIndex: Integer; Value: TDateTime);\n    procedure SetTime(ColumnIndex: Integer; Value: TDateTime);\n    procedure SetTimestamp(ColumnIndex: Integer; Value: TDateTime);\n    procedure SetAsciiStream(ColumnIndex: Integer; Value: TStream);\n    procedure SetUnicodeStream(ColumnIndex: Integer; Value: TStream);\n    procedure SetBinaryStream(ColumnIndex: Integer; Value: TStream);\n    procedure SetBlob(ColumnIndex: Integer; Value: IZBlob);\n    procedure SetDataSet(ColumnIndex: Integer; Value: IZDataSet);\n    procedure SetValue(ColumnIndex: Integer; Value: TZVariant);\n\n    property ColumnsSize: Integer read FColumnsSize;\n    property RowSize: Integer read FRowSize;\n    property RowBuffer: PZRowBuffer read FBuffer write FBuffer;\n  end;\n\nconst\n  RowHeaderSize = SizeOf(TZRowBuffer) - SizeOf(TZByteArray);\n\nimplementation\n\nuses Math, ZMessages, ZSysUtils, ZDbcUtils\n  {$IFDEF WITH_UNITANSISTRINGS}, AnsiStrings{$ENDIF};\n\n{ TZRowAccessor }\n\n{**\n  Creates this object and assignes the main properties.\n  @param ColumnsInfo a collection with column information.\n}\nconstructor TZRowAccessor.Create(ColumnsInfo: TObjectList; ConSettings: PZConSettings);\nvar\n  I: Integer;\n  Current: TZColumnInfo;\nbegin\n  Self.ConSettings := ConSettings;\n  FBuffer := nil;\n  FColumnCount := ColumnsInfo.Count;\n  FColumnsSize := 0;\n  {$ifdef FPC_REQUIRES_PROPER_ALIGNMENT}\n  FColumnsSize:=align(FColumnsSize+1,sizeof(pointer))-1;\n  {$endif}\n  SetLength(FColumnNames, FColumnCount);\n  SetLength(FColumnCases, FColumnCount);\n  SetLength(FColumnTypes, FColumnCount);\n  SetLength(FColumnLengths, FColumnCount);\n  SetLength(FColumnOffsets, FColumnCount);\n  SetLength(FColumnDefaultExpressions, FColumnCount);\n  FHasBlobs := False;\n\n  for I := 0 to FColumnCount - 1 do\n  begin\n    Current := TZColumnInfo(ColumnsInfo[I]);\n    FColumnNames[I] := Current.ColumnName;\n    FColumnCases[I] := Current.CaseSensitive;\n    FColumnTypes[I] := Current.ColumnType;\n    FColumnLengths[I] := GetColumnSize(Current);\n    FColumnOffsets[I] := FColumnsSize;\n    FColumnDefaultExpressions[I] := Current.DefaultExpression;\n    Inc(FColumnsSize, FColumnLengths[I] + 1);\n    {$ifdef FPC_REQUIRES_PROPER_ALIGNMENT}\n    FColumnsSize:=align(FColumnsSize+1,sizeof(pointer))-1;\n    {$endif}\n    if Current.ColumnType in [stBytes, stString, stUnicodeString] then\n      FColumnLengths[I] := Current.Precision;\n    if Current.ColumnType = stGUID then\n      FColumnLengths[I] := 16;\n    if FColumnsSize > SizeOf(TZByteArray)-1 then\n      raise EZSQLException.Create(SRowBufferWidthExceeded);\n    FHasBlobs := FHasBlobs\n      or (FColumnTypes[I] in [stAsciiStream, stUnicodeStream, stBinaryStream]);\n  end;\n  FRowSize := FColumnsSize + RowHeaderSize;\nend;\n\n{**\n  Destroys this object and cleanups the memory.\n}\ndestructor TZRowAccessor.Destroy;\nbegin\n  inherited Destroy;\nend;\n\n{**\n  Checks is the column index correct and row buffer is available.\n  @param ColumnIndex an index of column.\n}\nprocedure TZRowAccessor.CheckColumnIndex(ColumnIndex: Integer);\nbegin\n  if not Assigned(FBuffer) then\n    raise EZSQLException.Create(SRowBufferIsNotAssigned);\n\n  if (ColumnIndex <= 0) or (ColumnIndex > FColumnCount) then\n  begin\n    raise EZSQLException.Create(\n      Format(SColumnIsNotAccessable, [ColumnIndex]));\n  end;\nend;\n\n{**\n  Checks is the column convertion from one type to another type allowed.\n  @param ColumnIndex an index of column.\n  @param ResultType a requested data type.\n  @return <code>true</code> if convertion is allowed or throw exception\n    otherwise.\n}\nprocedure TZRowAccessor.CheckColumnConvertion(ColumnIndex: Integer;\n  ResultType: TZSQLType);\nbegin\n  if not Assigned(FBuffer) then\n    raise EZSQLException.Create(SRowBufferIsNotAssigned);\n\n  if (ColumnIndex <= 0) or (ColumnIndex > FColumnCount) then\n  begin\n    raise EZSQLException.Create(\n      Format(SColumnIsNotAccessable, [ColumnIndex]));\n  end;\n\n  if not CheckConvertion(FColumnTypes[ColumnIndex - 1], ResultType) then\n  begin\n    raise EZSQLException.Create(\n      Format(SConvertionIsNotPossible, [ColumnIndex,\n      DefineColumnTypeName(FColumnTypes[ColumnIndex - 1]),\n      DefineColumnTypeName(ResultType)]));\n  end;\nend;\n\n{**\n  Gets a size of column with the specified type.\n  @param ColumnInfo a column information struct.\n  @return a size for the column with the specified type.\n}\nfunction TZRowAccessor.GetColumnSize(ColumnInfo: TZColumnInfo): Integer;\nbegin\n  case ColumnInfo.ColumnType of\n    stBoolean:\n      Result := SizeOf(WordBool);\n    stByte:\n      Result := SizeOf(Byte);\n    stShort:\n      Result := SizeOf(SmallInt);\n    stInteger:\n      Result := SizeOf(Integer);\n    stLong:\n      Result := SizeOf(Int64);\n    stFloat:\n      Result := SizeOf(Single);\n    stDouble:\n      Result := SizeOf(Double);\n    stBigDecimal:\n      Result := SizeOf(Extended);\n    stString:\n      Result := SizeOf(Pointer);\n    stUnicodeString:\n      Result := SizeOf(Pointer);\n    stBytes, stGUID:\n      Result := SizeOf(Pointer) + SizeOf(SmallInt);\n    stDate, stTime, stTimestamp:\n      Result := SizeOf(TDateTime);\n    stAsciiStream, stUnicodeStream, stBinaryStream, stDataSet:\n      Result := SizeOf(Pointer);\n    else\n      Result := 0;\n  end;\nend;\n\n{**\n  Gets a stream from the specified columns.\n  @param Buffer a row buffer.\n  @param ColumnIndex an index of the column.\n}\nfunction TZRowAccessor.GetBlobObject(Buffer: PZRowBuffer;\n  ColumnIndex: Integer): IZBlob;\nvar\n  BlobPtr: PPointer;\n  NullPtr: {$IFDEF WIN64}PBoolean{$ELSE}PByte{$ENDIF};\nbegin\n  BlobPtr := PPointer(@Buffer.Columns[FColumnOffsets[ColumnIndex - 1] + 1]);\n  NullPtr := {$IFDEF WIN64}PBoolean{$ELSE}PByte{$ENDIF}(@Buffer.Columns[FColumnOffsets[ColumnIndex - 1]]);\n\n  {$IFNDEF FPC}\n  if NullPtr^ = {$IFDEF WIN64}false{$ELSE}0{$ENDIF} then  //M.A. if NullPtr^ = 0 then\n  {$ELSE}\n  if NullPtr^ = 0 then\n  {$ENDIF}\n    Result := IZBlob(BlobPtr^)\n  else\n    Result := nil;\nend;\n\n{**\n  Sets a blob into the specified columns.\n  @param Buffer a row buffer.\n  @param ColumnIndex an index of the column.\n  @param Value a stream object to be set.\n}\nprocedure TZRowAccessor.SetBlobObject(Buffer: PZRowBuffer; ColumnIndex: Integer;\n  Value: IZBlob);\nvar\n  BlobPtr: PPointer;\n  NullPtr: {$IFDEF WIN64}PBoolean{$ELSE}PByte{$ENDIF};\nbegin\n  BlobPtr := PPointer(@Buffer.Columns[FColumnOffsets[ColumnIndex - 1] + 1]);\n  NullPtr := {$IFDEF WIN64}PBoolean{$ELSE}PByte{$ENDIF}(@Buffer.Columns[FColumnOffsets[ColumnIndex - 1]]);\n\n  {$IFNDEF FPC}\n  if NullPtr^ = {$IFDEF WIN64}false{$ELSE}0{$ENDIF} then  //M.A. if NullPtr^ = 0 then\n  {$ELSE}\n  if NullPtr^ = 0 then\n  {$ENDIF}\n    IZBlob(BlobPtr^) := nil\n  else\n    BlobPtr^ := nil;\n\n  IZBlob(BlobPtr^) := Value;\n\n  if Value <> nil then\n  {$IFNDEF FPC}\n    NullPtr^ := {$IFDEF WIN64}false{$ELSE}0{$ENDIF}  //M.A. NullPtr^ := 0\n  else\n    NullPtr^ := {$IFDEF WIN64}true{$ELSE}1{$ENDIF};  //M.A. NullPtr^ := 1;\n  {$ELSE}\n    NullPtr^ := 0\n  else\n    NullPtr^ := 1;\n  {$ENDIF}\nend;\n\nfunction TZRowAccessor.InternalGetBytes(Buffer: PZRowBuffer;\n  ColumnIndex: Integer): TByteDynArray;\nvar\n  P: PPointer;\n  L: SmallInt;\nbegin\n  Result := nil;\n  if ( Buffer.Columns[FColumnOffsets[ColumnIndex - 1]] = 0 )then\n  begin\n    L := PSmallInt(@Buffer.Columns[FColumnOffsets[ColumnIndex - 1] + 1 + SizeOf(Pointer)])^;\n    SetLength(Result, L);\n    if L > 0 then\n    begin\n      P := PPointer(@Buffer.Columns[FColumnOffsets[ColumnIndex - 1] + 1]);\n      Move(P^^, Pointer(Result)^, L);\n    end;\n  end;\nend;\n\nprocedure TZRowAccessor.InternalSetBytes(Buffer: PZRowBuffer; ColumnIndex: Integer;\n  Value: TByteDynArray; NewPointer: Boolean = False);\nvar\n  P: PPointer;\n  L: SmallInt;\nbegin\n  if Assigned(Buffer) then\n  begin\n    if NewPointer then\n      PNativeUInt(@Buffer.Columns[FColumnOffsets[ColumnIndex - 1] + 1])^ := 0;\n    P := PPointer(@Buffer.Columns[FColumnOffsets[ColumnIndex - 1] + 1]);\n    L := Min(Length(Value), FColumnLengths[ColumnIndex - 1]);\n    PSmallInt(@FBuffer.Columns[FColumnOffsets[ColumnIndex - 1] + 1 + SizeOf(Pointer)])^ := L;\n    if L > 0 then\n    begin\n      ReallocMem(P^, L);\n      System.Move(Pointer(Value)^, P^^, L);\n    end\n    else\n      if PNativeUInt(@Buffer.Columns[FColumnOffsets[ColumnIndex - 1] + 1])^ > 0 then\n      begin\n        System.Dispose(P^);\n        PNativeUInt(@Buffer.Columns[FColumnOffsets[ColumnIndex - 1] + 1])^ := 0;\n      end;\n  end;\nend;\n\nprocedure TZRowAccessor.InternalSetString(Buffer: PZRowBuffer;\n  ColumnIndex: Integer; Value: String; NewPointer: Boolean = False);\nvar\n  C: PPChar;\n  L: SmallInt;\nbegin\n  if Assigned(Buffer) then\n  begin\n    if NewPointer then\n      PNativeUInt(@Buffer.Columns[FColumnOffsets[ColumnIndex - 1] + 1])^ := 0;\n    C := PPChar(@Buffer.Columns[FColumnOffsets[ColumnIndex - 1] + 1]);\n    L := Min(FColumnLengths[ColumnIndex - 1], Length(Value));\n    ReallocMem(C^, L * SizeOf(Char) + SizeOf(Char));\n    System.Move(PChar(Value)^, C^^, L * SizeOf(Char));\n    (C^+L)^ := #0; //set #0 terminator if a truncation is required\n  end;\nend;\n\nprocedure TZRowAccessor.InternalSetUnicodeString(Buffer: PZRowBuffer;\n  ColumnIndex: Integer; Value: ZWideString; NewPointer: Boolean = False);\nvar\n  W: ZPPWideChar;\n  L: SmallInt;\nbegin\n  if Assigned(Buffer) then\n  begin\n    if NewPointer then\n      PNativeUInt(@Buffer.Columns[FColumnOffsets[ColumnIndex - 1] + 1])^ := 0;\n    W := ZPPWideChar(@Buffer.Columns[FColumnOffsets[ColumnIndex - 1] + 1]);\n    L := Min(Length(Value), FColumnLengths[ColumnIndex - 1]);\n    Value := System.Copy(Value, 1, L);\n    L := L * 2 + 2;\n    ReallocMem(W^, L);\n    System.Move(PWideChar(Value)^, W^^, L);\n  end;\nend;\n\n{**\n  Allocates a new row buffer and sets it into the variable.\n  @param Buffer a pointer to row buffer.\n  @return a pointer to the allocated buffer.\n}\nfunction TZRowAccessor.AllocBuffer(var Buffer: PZRowBuffer): PZRowBuffer;\nbegin\n  GetMem(Buffer, FRowSize);\n  InitBuffer(Buffer);\n  Result := Buffer;\nend;\n\n{**\n  Disposes the specified row buffer.\n  @param Buffer a pointer to row buffer.\n}\nprocedure TZRowAccessor.DisposeBuffer(Buffer: PZRowBuffer);\nbegin\n  if Assigned(Buffer) then\n  begin\n    ClearBuffer(Buffer);\n    FreeMem(Buffer);\n  end;\nend;\n\n{**\n  Initializes the row buffer.\n  @param Buffer a pointer to row buffer.\n}\nprocedure TZRowAccessor.InitBuffer(Buffer: PZRowBuffer);\nvar\n  I : Integer;\nbegin\n  if Assigned(Buffer) then\n    with Buffer^ do\n    begin\n      Index := 0;\n      BookmarkFlag := 0;//bfCurrent;\n      UpdateType := utUnmodified;\n      FillChar(Columns, FColumnsSize, 0);\n      for I := 0 to FColumnCount - 1 do Columns[FColumnOffsets[I]] := 1;\n    end;\nend;\n\n{**\n  Copies the row buffer from source to destination row.\n  @param SrcBuffer a pointer to source row buffer.\n  @param DestBuffer a pointer to destination row buffer.\n}\nprocedure TZRowAccessor.CopyBuffer(SrcBuffer: PZRowBuffer; DestBuffer: PZRowBuffer);\nvar\n  I: Integer;\nbegin\n  ClearBuffer(DestBuffer);\n  with DestBuffer^ do\n  begin\n    Index := SrcBuffer^.Index;\n    UpdateType := SrcBuffer^.UpdateType;\n    BookmarkFlag := SrcBuffer^.BookmarkFlag;\n    System.Move(SrcBuffer^.Columns, Columns, FColumnsSize);\n    for I := 0 to FColumnCount - 1 do\n      case FColumnTypes[I] of\n        stAsciiStream, stUnicodeStream, stBinaryStream:\n          if (Columns[FColumnOffsets[I]] = 0) then\n          begin\n            Columns[FColumnOffsets[I]] := 1;\n            SetBlobObject(DestBuffer, I + 1, GetBlobObject(SrcBuffer, I + 1));\n          end;\n      stString: InternalSetString(DestBuffer, I +1,\n        PPChar(@SrcBuffer.Columns[FColumnOffsets[I] + 1])^, True);\n      stUnicodeString: InternalSetUnicodeString(DestBuffer, I +1,\n        ZPPWideChar(@SrcBuffer.Columns[FColumnOffsets[I] + 1])^, True);\n      stBytes,stGUID: InternalSetBytes(DestBuffer, I +1, InternalGetBytes(SrcBuffer, I +1), True);\n    end;\n  end;\nend;\n\n{**\n  Moves the row buffer from source to destination row.\n  Source buffer is cleaned up after the operation.\n  @param SrcBuffer a pointer to source row buffer.\n  @param DestBuffer a pointer to destination row buffer.\n}\nprocedure TZRowAccessor.MoveBuffer(SrcBuffer: PZRowBuffer; DestBuffer: PZRowBuffer);\nbegin\n  CopyBuffer(SrcBuffer, DestBuffer);\n  ClearBuffer(SrcBuffer);\nend;\n\n{**\n  Clones the row buffer from source to destination row.\n  @param SrcBuffer a pointer to source row buffer.\n  @param DestBuffer a pointer to destination row buffer.\n}\nprocedure TZRowAccessor.CloneBuffer(SrcBuffer: PZRowBuffer; DestBuffer: PZRowBuffer);\nvar\n  I: Integer;\n  Blob: IZBlob;\nbegin\n  ClearBuffer(DestBuffer);\n  with DestBuffer^ do\n  begin\n    Index := SrcBuffer^.Index;\n    UpdateType := SrcBuffer^.UpdateType;\n    BookmarkFlag := SrcBuffer^.BookmarkFlag;\n    System.Move(SrcBuffer^.Columns, Columns, FColumnsSize);\n    for I := 0 to FColumnCount - 1 do\n      case FColumnTypes[I] of\n        stAsciiStream, stUnicodeStream, stBinaryStream:\n          if (Columns[FColumnOffsets[I]] = 0) then\n          begin\n            Columns[FColumnOffsets[I]] := 1;\n            Blob := GetBlobObject(SrcBuffer, I + 1);\n            if Blob <> nil then\n              Blob := Blob.Clone;\n            SetBlobObject(DestBuffer, I + 1, Blob);\n          end;\n        stString: InternalSetString(DestBuffer, I +1,\n          PPChar(@SrcBuffer.Columns[FColumnOffsets[I] + 1])^, True);\n        stUnicodeString: InternalSetUnicodeString(DestBuffer, I +1,\n          ZPPWideChar(@SrcBuffer.Columns[FColumnOffsets[I] + 1])^, True);\n        stBytes,stGUID: InternalSetBytes(DestBuffer, I +1, InternalGetBytes(SrcBuffer, I +1), True);\n      end;\n  end;\nend;\n\n{**\n  Compares fields from two row buffers.\n  @param Buffer1 the first row buffer to compare.\n  @param Buffer2 the second row buffer to compare.\n  @param ColumnIndices column indices to compare.\n  @param ColumnDirs compare direction for each columns.\n}\nfunction TZRowAccessor.CompareBuffers(Buffer1, Buffer2: PZRowBuffer;\n  ColumnIndices: TIntegerDynArray; ColumnDirs: TBooleanDynArray): Integer;\nvar\n  I: Integer;\n  ColumnIndex: Integer;\n  Length1, Length2: SmallInt;\n  ValuePtr1, ValuePtr2: Pointer;\n  Blob1, Blob2: IZBlob;\n  BlobEmpty1, BlobEmpty2: Boolean;\n  Bts1, Bts2: TByteDynArray;\nbegin\n  Result := 0;\n  for I := Low(ColumnIndices) to High(ColumnIndices) do\n  begin\n    ColumnIndex := ColumnIndices[I] - 1;\n    { Checks for both Null columns. }\n    if (Buffer1.Columns[FColumnOffsets[ColumnIndex]] = 1) and\n      (Buffer2.Columns[FColumnOffsets[ColumnIndex]] = 1) then\n      Continue;\n    { Checks for not-Null and Null columns. }\n    if Buffer1.Columns[FColumnOffsets[ColumnIndex]] <>\n      Buffer2.Columns[FColumnOffsets[ColumnIndex]] then\n    begin\n      if not (FColumnTypes[ColumnIndex]\n        in [stAsciiStream, stUnicodeStream, stBinaryStream]) then\n      begin\n        Result := Buffer2.Columns[FColumnOffsets[ColumnIndex]] -\n          Buffer1.Columns[FColumnOffsets[ColumnIndex]];\n        if not ColumnDirs[I] then\n          Result := -Result;\n        Break;\n      end;\n    end;\n    { Compares column values. }\n    ValuePtr1 := @Buffer1.Columns[FColumnOffsets[ColumnIndex] + 1];\n    ValuePtr2 := @Buffer2.Columns[FColumnOffsets[ColumnIndex] + 1];\n    case FColumnTypes[ColumnIndex] of\n      stByte:\n        Result := Ord((PByte(ValuePtr1)^ > PByte(ValuePtr2)^))-Ord((PByte(ValuePtr1)^ < PByte(ValuePtr2)^));\n      stShort:\n        Result := Ord((PShortInt(ValuePtr1)^ > PShortInt(ValuePtr2)^))-Ord((PShortInt(ValuePtr1)^ < PShortInt(ValuePtr2)^));\n      stInteger:\n        Result := Ord((PLongInt(ValuePtr1)^ > PLongInt(ValuePtr2)^))-Ord((PLongInt(ValuePtr1)^ < PLongInt(ValuePtr2)^));\n      stLong:\n        Result := Ord((PInt64(ValuePtr1)^ > PInt64(ValuePtr2)^))-Ord((PInt64(ValuePtr1)^ < PInt64(ValuePtr2)^));\n      stFloat:\n        Result := Ord((PSingle(ValuePtr1)^ > PSingle(ValuePtr2)^))-Ord((PSingle(ValuePtr1)^ < PSingle(ValuePtr2)^));\n      stDouble:\n        Result := Ord((PDouble(ValuePtr1)^ > PDouble(ValuePtr2)^))-Ord((PDouble(ValuePtr1)^ < PDouble(ValuePtr2)^));\n      stBigDecimal:\n        Result := Ord((PExtended(ValuePtr1)^ > PExtended(ValuePtr2)^))-Ord((PExtended(ValuePtr1)^ < PExtended(ValuePtr2)^));\n      stBoolean:\n        Result := Ord((PWordBool(ValuePtr1)^ > PWordBool(ValuePtr2)^))-Ord((PWordBool(ValuePtr1)^ < PWordBool(ValuePtr2)^));\n      stDate, stTime, stTimestamp:\n        Result := Ord((PDateTime(ValuePtr1)^ > PDateTime(ValuePtr2)^))-Ord((PDateTime(ValuePtr1)^ < PDateTime(ValuePtr2)^));\n      {$IFDEF UNICODE}\n      stUnicodeString,stString:\n        Result := WideCompareStr(PWideChar(ValuePtr1^), PWideChar(ValuePtr2^));\n      {$ELSE}\n      stString:\n        {$IFDEF MSWINDOWS} //Windows can handle nil pointers Linux not FPC-Bug?\n        Result := AnsiStrComp(PAnsiChar(ValuePtr1^), PAnsiChar(ValuePtr2^));\n        {$ELSE}\n        if Assigned(PPAnsichar(ValuePtr1)^) and Assigned(PPAnsiChar(ValuePtr2)^) then\n          Result := AnsiStrComp(PAnsiChar(ValuePtr1^), PAnsiChar(ValuePtr2^))\n        else\n          if not Assigned(PPAnsichar(ValuePtr1)^) and not Assigned(PPAnsiChar(ValuePtr2)^) then\n            Result := 0\n          else\n            Result := -1;\n        {$ENDIF}\n      stUnicodeString:\n        Result := WideCompareStr(PWideChar(ValuePtr1^), PWideChar(ValuePtr2^));\n      {$ENDIF}\n      stBytes,stGUID:\n        begin\n          Length1 := PSmallInt(@Buffer1.Columns[FColumnOffsets[ColumnIndex] + 1 + SizeOf(Pointer)])^;\n          Length2 := PSmallInt(@Buffer2.Columns[FColumnOffsets[ColumnIndex] + 1 + SizeOf(Pointer)])^;\n          Result := Length1 - Length2;\n          if Result = 0 then\n          begin\n            Bts1 := InternalGetBytes(Buffer1, ColumnIndex+1);\n            Bts2 := InternalGetBytes(Buffer2, ColumnIndex+1);\n            if (Assigned(Bts1) and Assigned(Bts2)) then\n              if MemLCompAnsi(PAnsiChar(Bts1), PAnsiChar(Bts2), Length1) then\n                Result := 0\n              else\n                Result := 1\n            else if not Assigned(Bts1) and not Assigned(Bts2) then\n              Result := 0\n            else if Assigned(Bts1) then\n              Result := 1\n            else\n              Result := -1;\n          end;\n        end;\n      stAsciiStream, stBinaryStream, stUnicodeStream:\n        begin\n          Blob1 := GetBlobObject(Buffer1, ColumnIndex + 1);\n          BlobEmpty1 := (Blob1 = nil) or (Blob1.IsEmpty);\n          Blob2 := GetBlobObject(Buffer2, ColumnIndex + 1);\n          BlobEmpty2 := (Blob2 = nil) or (Blob2.IsEmpty);\n          if (BlobEmpty1 = True) and (BlobEmpty2 = True) then\n            Continue\n          else if (BlobEmpty1 <> BlobEmpty2) then\n          begin\n            if BlobEmpty1 then\n              Result := -1\n            else\n              Result := 1;\n          end\n          else if FColumnTypes[ColumnIndex] = stAsciiStream then\n            {$IFDEF WITH_UNITANSISTRINGS}\n            Result := AnsiStrings.AnsiCompareStr(Blob1.GetString, Blob2.GetString)\n            {$ELSE}\n            Result := AnsiCompareStr(Blob1.GetString, Blob2.GetString)\n            {$ENDIF}\n          else if FColumnTypes[ColumnIndex] = stBinaryStream then\n            Result := CompareStr(Blob1.GetString, Blob2.GetString)\n          else if FColumnTypes[ColumnIndex] = stUnicodeStream then\n            Result := WideCompareStr(Blob1.GetUnicodeString, Blob2.GetUnicodeString);\n        end;\n    end;\n    if Result <> 0 then\n    begin\n      if not ColumnDirs[I] then\n        Result := -Result;\n      Break;\n    end;\n  end;\nend;\n\n{**\n  Cleans the specified row buffer.\n  @param Buffer a pointer to row buffer.\n}\nprocedure TZRowAccessor.ClearBuffer(Buffer: PZRowBuffer);\nvar\n  I: Integer;\n  P: PPointer;\nbegin\n  with Buffer^ do\n  begin\n    Index := -1;\n    UpdateType := utUnmodified;\n    BookmarkFlag := 0;\n    for I := 0 to FColumnCount - 1 do\n      case FColumnTypes[I] of\n        stAsciiStream, stUnicodeStream, stBinaryStream:\n          if (Columns[FColumnOffsets[I]] = 0) then\n            SetBlobObject(Buffer, I + 1, nil);\n        stBytes,stGUID,stString, stUnicodeString:\n          if PNativeUInt(@Columns[FColumnOffsets[I] +1])^ > 0 then\n          begin\n            P := PPointer(@Columns[FColumnOffsets[I] +1]);\n            System.Dispose(P^);\n          end;\n      end;\n    FillChar(Columns, FColumnsSize, 0);\n    for I := 0 to FColumnCount - 1 do Columns[FColumnOffsets[I]] := 1;\n  end;\nend;\n\n{**\n  Allocates a new row buffer.\n  @return a pointer to the allocated buffer.\n}\nfunction TZRowAccessor.Alloc: PZRowBuffer;\nbegin\n  Result := AllocBuffer(FBuffer);\nend;\n\n{**\n  Disposes an associated row buffer.\n}\nprocedure TZRowAccessor.Dispose;\nbegin\n  DisposeBuffer(FBuffer);\n  FBuffer := nil;\nend;\n\n{**\n  Initializes the associated row buffer.\n}\nprocedure TZRowAccessor.Init;\nbegin\n  InitBuffer(FBuffer);\nend;\n\n{**\n  Copies the associated row buffer into a specified one.\n  @param DestBuffer a destination row buffer.\n}\nprocedure TZRowAccessor.CopyTo(DestBuffer: PZRowBuffer);\nbegin\n  CopyBuffer(FBuffer, DestBuffer);\nend;\n\n{**\n  Copies the associated row buffer from a specified one.\n  @param SrcBuffer a source row buffer.\n}\nprocedure TZRowAccessor.CopyFrom(SrcBuffer: PZRowBuffer);\nbegin\n  CopyBuffer(SrcBuffer, FBuffer);\nend;\n\n{**\n  Moves the associated row buffer into a specified one.\n  @param DestBuffer a destination row buffer.\n}\nprocedure TZRowAccessor.MoveTo(DestBuffer: PZRowBuffer);\nbegin\n  MoveBuffer(FBuffer, DestBuffer);\nend;\n\n{**\n  Moves the associated row buffer from a specified one.\n  @param SrcBuffer a source row buffer.\n}\nprocedure TZRowAccessor.MoveFrom(SrcBuffer: PZRowBuffer);\nbegin\n  MoveBuffer(SrcBuffer, FBuffer);\nend;\n\n{**\n  Clones the associated row buffer into a specified one.\n  @param DestBuffer a destination row buffer.\n}\nprocedure TZRowAccessor.CloneTo(DestBuffer: PZRowBuffer);\nbegin\n  CloneBuffer(FBuffer, DestBuffer);\nend;\n\n{**\n  Clones the associated row buffer from a specified one.\n  @param SrcBuffer a source row buffer.\n}\nprocedure TZRowAccessor.CloneFrom(SrcBuffer: PZRowBuffer);\nbegin\n  CloneBuffer(SrcBuffer, FBuffer);\nend;\n\n{**\n  Cleans the associated row buffer.\n}\nprocedure TZRowAccessor.Clear;\nbegin\n  ClearBuffer(FBuffer);\nend;\n\n{**\n  Gets the case sensitive flag of a column data buffer.\n\n  @param ColumnIndex the first column is 1, the second is 2, ...\n  @return the case sensitive flag of the column data buffer.\n}\nfunction TZRowAccessor.GetColumnCase(ColumnIndex: Integer): Boolean;\nbegin\n CheckColumnIndex(ColumnIndex);\n Result := FColumnCases[ColumnIndex-1];\nend;\n\n{**\n  Gets a pointer to the column data buffer.\n\n  @param ColumnIndex the first column is 1, the second is 2, ...\n  @return a pointer to the column data buffer.\n}\nfunction TZRowAccessor.GetColumnData(ColumnIndex: Integer;\n  var IsNull: Boolean): Pointer;\nbegin\n  CheckColumnConvertion(ColumnIndex, stString);\n  Result := @FBuffer.Columns[FColumnOffsets[ColumnIndex - 1] + 1];\n  IsNull := FBuffer.Columns[FColumnOffsets[ColumnIndex - 1]] = 1;\nend;\n\n{**\n  Gets a size of the column data buffer.\n\n  @param ColumnIndex the first column is 1, the second is 2, ...\n  @return a size of the column data buffer.\n}\nfunction TZRowAccessor.GetColumnDataSize(ColumnIndex: Integer): Integer;\nbegin\n  CheckColumnConvertion(ColumnIndex, stString);\n  Result := FColumnLengths[ColumnIndex - 1];\nend;\n\n{**\n  Gets then length of a column data buffer.\n\n  @param ColumnIndex the first column is 1, the second is 2, ...\n  @return the length of the column data buffer.\n}\nfunction TZRowAccessor.GetColumnLength(ColumnIndex: Integer): Integer;\nbegin\n CheckColumnIndex(ColumnIndex);\n Result := FColumnLengths[ColumnIndex-1];\nend;\n\n{**\n  Gets then name of a column data buffer.\n\n  @param ColumnIndex the first column is 1, the second is 2, ...\n  @return the name of the column data buffer.\n}\nfunction TZRowAccessor.GetColumnName(ColumnIndex: Integer): string;\nbegin\n CheckColumnIndex(ColumnIndex);\n Result := FColumnNames[ColumnIndex-1];\nend;\n\n{**\n  Gets then offset of a column data buffer.\n\n  @param ColumnIndex the first column is 1, the second is 2, ...\n  @return then offset of the column data buffer.\n}\nfunction TZRowAccessor.GetColumnOffSet(ColumnIndex: Integer): Integer;\nbegin\n CheckColumnIndex(ColumnIndex);\n Result := FColumnOffSets[ColumnIndex-1];\nend;\n\n{**\n  Gets then SQLType of a column data buffer.\n\n  @param ColumnIndex the first column is 1, the second is 2, ...\n  @return the SQLType of the column data buffer.\n}\nfunction TZRowAccessor.GetColumnType(ColumnIndex: Integer): TZSQLType;\nbegin\n CheckColumnIndex(ColumnIndex);\n Result := FColumnTypes[ColumnIndex-1];\nend;\n\nfunction TZRowAccessor.GetColumnDefaultExpression(ColumnIndex: Integer): string;\nbegin\n CheckColumnIndex(ColumnIndex);\n Result := FColumnDefaultExpressions[ColumnIndex-1];\nend;\n\nprocedure TZRowAccessor.SetColumnDefaultExpression(ColumnIndex: Integer; Value: string);\nbegin\n FColumnDefaultExpressions[ColumnIndex-1] := Value;\nend;\n\n//\n//======================================================================\n// Methods for accessing results by column index\n//======================================================================\n\n{**\n  Indicates if the value of the designated column in the current row\n  of this <code>ResultSet</code> object is Null.\n\n  @param ColumnIndex the first column is 1, the second is 2, ...\n  @return if the value is SQL <code>NULL</code>, the\n    value returned is <code>true</code>. <code>false</code> otherwise.\n}\nfunction TZRowAccessor.IsNull(ColumnIndex: Integer): Boolean;\nvar\n  TempBlob: IZBlob;\nbegin\n  CheckColumnConvertion(ColumnIndex, stString);\n  Result := FBuffer.Columns[FColumnOffsets[ColumnIndex - 1]] = 1;\n  if not Result and (FColumnTypes[ColumnIndex - 1] in [stAsciiStream,\n    stBinaryStream, stUnicodeStream]) then\n  begin\n    TempBlob := GetBlobObject(FBuffer, ColumnIndex);\n    Result := (TempBlob = nil) or TempBlob.IsEmpty;\n  end;\nend;\n\n{**\n  Gets the value of the designated column in the current row\n  of this <code>ResultSet</code> object as\n  a <code>PChar</code> in the Delphi programming language.\n\n  @param columnIndex the first column is 1, the second is 2, ...\n  @return the column value; if the value is SQL <code>NULL</code>, the\n    value returned is <code>null</code>\n}\nfunction TZRowAccessor.GetPChar(ColumnIndex: Integer; var IsNull: Boolean): PChar;\nbegin\n{$IFNDEF DISABLE_CHECKING}\n  CheckColumnConvertion(ColumnIndex, stString);\n{$ENDIF}\n  Result := nil;\n  if FBuffer.Columns[FColumnOffsets[ColumnIndex - 1]] = 0 then\n  begin\n    case FColumnTypes[ColumnIndex - 1] of\n      stString{$IFDEF UNICODE}, stUnicodeString{$ENDIF}:\n        Result := PPChar(FBuffer.Columns[FColumnOffsets[ColumnIndex - 1] + 1])^;\n      else\n      begin\n        FTemp := GetString(ColumnIndex, IsNull);\n        Result := PChar(FTemp);\n      end;\n    end;\n    IsNull := False;\n  end\n  else\n    IsNull := True;\nend;\n\n{**\n  Gets the value of the designated column in the current row\n  of this <code>ResultSet</code> object as\n  a <code>String</code> in the Java programming language.\n\n  @param columnIndex the first column is 1, the second is 2, ...\n  @return the column value; if the value is SQL <code>NULL</code>, the\n    value returned is <code>null</code>\n}\nfunction TZRowAccessor.GetString(ColumnIndex: Integer; var IsNull: Boolean): String;\nvar\n  TempBlob: IZBlob;\n  GUID: TGUID;\nbegin\n{$IFNDEF DISABLE_CHECKING}\n  CheckColumnConvertion(ColumnIndex, stString);\n{$ENDIF}\n  Result := '';\n  if FBuffer.Columns[FColumnOffsets[ColumnIndex - 1]] = 0 then\n  begin\n    case FColumnTypes[ColumnIndex - 1] of\n      stBoolean:\n        if GetBoolean(ColumnIndex, IsNull) then\n          Result := 'True'\n        else\n          Result := 'False';\n      stByte: Result := IntToStr(GetByte(ColumnIndex, IsNull));\n      stShort: Result := IntToStr(GetShort(ColumnIndex, IsNull));\n      stInteger: Result := IntToStr(GetInt(ColumnIndex, IsNull));\n      stLong: Result := IntToStr(GetLong(ColumnIndex, IsNull));\n      stFloat: Result := FloatToSQLStr(GetFloat(ColumnIndex, IsNull));\n      stDouble: Result := FloatToSQLStr(GetDouble(ColumnIndex, IsNull));\n      stBigDecimal: Result := FloatToSQLStr(GetBigDecimal(ColumnIndex, IsNull));\n      stString: Result := PPChar(@FBuffer.Columns[FColumnOffsets[ColumnIndex - 1] + 1])^;\n      stUnicodeString, stUnicodeStream: Result := ZDbcString(GetUnicodeString(ColumnIndex, IsNull)); //wide down to expect codpage Ansi\n      stBytes: Result := String(BytesToStr(GetBytes(ColumnIndex, IsNull)));\n      stGUID:\n        begin\n          System.Move(Pointer(GetBytes(ColumnIndex, IsNull))^, GUID, 16);\n          Result := GUIDToString(GUID);\n        end;\n      stDate: Result := FormatDateTime('yyyy-mm-dd', GetDate(ColumnIndex, IsNull));\n      stTime: Result := FormatDateTime('hh:mm:ss', GetTime(ColumnIndex, IsNull));\n      stTimestamp: Result := FormatDateTime('yyyy-mm-dd hh:mm:ss',\n          GetTimestamp(ColumnIndex, IsNull));\n      stAsciiStream, stBinaryStream:\n        begin\n          TempBlob := GetBlobObject(FBuffer, ColumnIndex);\n          if (TempBlob <> nil) and not TempBlob.IsEmpty then\n            Result := String(TempBlob.GetString);\n        end;\n    end;\n    IsNull := False;\n  end\n  else\n    IsNull := True;\nend;\n\n{**\n  Gets the value of the designated column in the current row\n  of this <code>ResultSet</code> object as\n  a <code>WideString</code> in the ObjectPascal programming language.\n\n  @param columnIndex the first column is 1, the second is 2, ...\n  @return the column value; if the value is SQL <code>NULL</code>, the\n    value returned is <code>null</code>\n}\nfunction TZRowAccessor.GetUnicodeString(ColumnIndex: Integer; var IsNull: Boolean):\n   WideString;\nvar\n  TempBlob: IZBlob;\nbegin\n{$IFNDEF DISABLE_CHECKING}\n  CheckColumnConvertion(ColumnIndex, stUnicodeString);\n{$ENDIF}\n  Result := '';\n  if FBuffer.Columns[FColumnOffsets[ColumnIndex - 1]] = 0 then\n  begin\n    case FColumnTypes[ColumnIndex - 1] of\n      stUnicodeString{$IFDEF UNICODE}, stString{$ENDIF}:\n        Result := ZPPWideChar(@FBuffer.Columns[FColumnOffsets[ColumnIndex - 1] + 1])^;\n      stUnicodeStream:\n        begin\n          TempBlob := GetBlobObject(FBuffer, ColumnIndex);\n          if (TempBlob <> nil) and not TempBlob.IsEmpty then\n            Result := TempBlob.GetUnicodeString;\n        end;\n      {$IFNDEF UNICODE}\n      stString: Result := ZDbcUnicodeString(GetString(ColumnIndex, IsNull), ConSettings.CTRL_CP);\n      {$ENDIF}\n      else\n        Result := WideString(GetString(ColumnIndex, IsNull));\n    end;\n    IsNull := False;\n  end\n  else\n    IsNull := True;\nend;\n\n{**\n  Gets the value of the designated column in the current row\n  of this <code>ResultSet</code> object as\n  a <code>boolean</code> in the Java programming language.\n\n  @param columnIndex the first column is 1, the second is 2, ...\n  @return the column value; if the value is SQL <code>NULL</code>, the\n    value returned is <code>false</code>\n}\nfunction TZRowAccessor.GetBoolean(ColumnIndex: Integer; var IsNull: Boolean): Boolean;\nvar\n  TempStr: string;\nbegin\n{$IFNDEF DISABLE_CHECKING}\n  CheckColumnConvertion(ColumnIndex, stBoolean);\n{$ENDIF}\n  Result := False;\n  if FBuffer.Columns[FColumnOffsets[ColumnIndex - 1]] = 0 then\n  begin\n    case FColumnTypes[ColumnIndex - 1] of\n      stBoolean:\n        Result := PWordBool(@FBuffer.Columns[FColumnOffsets[ColumnIndex - 1] + 1])^;\n      stByte: Result := GetByte(ColumnIndex, IsNull) <> 0;\n      stShort: Result := GetShort(ColumnIndex, IsNull) <> 0;\n      stInteger: Result := GetInt(ColumnIndex, IsNull) <> 0;\n      stLong: Result := GetLong(ColumnIndex, IsNull) <> 0;\n      stFloat: Result := GetFloat(ColumnIndex, IsNull) <> 0;\n      stDouble: Result := GetDouble(ColumnIndex, IsNull) <> 0;\n      stBigDecimal: Result := GetBigDecimal(ColumnIndex, IsNull) <> 0;\n      stString, stUnicodeString:\n        begin\n          TempStr := UpperCase(GetString(ColumnIndex, IsNull));\n          Result := (TempStr = 'T') or (TempStr = 'Y') or (TempStr = 'TRUE')\n            or (TempStr = 'YES');\n        end;\n    end;\n    IsNull := False;\n  end\n  else\n    IsNull := True;\nend;\n\n{**\n  Gets the value of the designated column in the current row\n  of this <code>ResultSet</code> object as\n  a <code>byte</code> in the Java programming language.\n\n  @param columnIndex the first column is 1, the second is 2, ...\n  @return the column value; if the value is SQL <code>NULL</code>, the\n    value returned is <code>0</code>\n}\nfunction TZRowAccessor.GetByte(ColumnIndex: Integer; var IsNull: Boolean): ShortInt;\nbegin\n{$IFNDEF DISABLE_CHECKING}\n  CheckColumnConvertion(ColumnIndex, stByte);\n{$ENDIF}\n  Result := 0;\n  if FBuffer.Columns[FColumnOffsets[ColumnIndex - 1]] = 0 then\n  begin\n    case FColumnTypes[ColumnIndex - 1] of\n      stBoolean:\n        if GetBoolean(ColumnIndex, IsNull) then\n          Result := 1\n        else\n          Result := 0;\n      stByte: Result := PShortInt(@FBuffer.Columns[FColumnOffsets[ColumnIndex - 1] + 1])^;\n      stShort: Result := GetShort(ColumnIndex, IsNull);\n      stInteger: Result := GetInt(ColumnIndex, IsNull);\n      stLong: Result := GetLong(ColumnIndex, IsNull);\n      stFloat: Result := Trunc(GetFloat(ColumnIndex, IsNull));\n      stDouble: Result := Trunc(GetDouble(ColumnIndex, IsNull));\n      stBigDecimal: Result := Trunc(GetBigDecimal(ColumnIndex, IsNull));\n      stString, stUnicodeString: Result := StrToIntDef(GetString(ColumnIndex, IsNull), 0);\n    end;\n    IsNull := False;\n  end\n  else\n    IsNull := True;\nend;\n\n{**\n  Gets the value of the designated column in the current row\n  of this <code>ResultSet</code> object as\n  a <code>short</code> in the Java programming language.\n\n  @param columnIndex the first column is 1, the second is 2, ...\n  @return the column value; if the value is SQL <code>NULL</code>, the\n    value returned is <code>0</code>\n}\nfunction TZRowAccessor.GetShort(ColumnIndex: Integer; var IsNull: Boolean): SmallInt;\nbegin\n{$IFNDEF DISABLE_CHECKING}\n  CheckColumnConvertion(ColumnIndex, stShort);\n{$ENDIF}\n  Result := 0;\n  if FBuffer.Columns[FColumnOffsets[ColumnIndex - 1]] = 0 then\n  begin\n    case FColumnTypes[ColumnIndex - 1] of\n      stBoolean:\n        if GetBoolean(ColumnIndex, IsNull) then\n          Result := 1\n        else\n          Result := 0;\n      stByte: Result := GetByte(ColumnIndex, IsNull);\n      stShort: Result := PSmallInt(@FBuffer.Columns[FColumnOffsets[ColumnIndex - 1] + 1])^;\n      stInteger: Result := GetInt(ColumnIndex, IsNull);\n      stLong: Result := GetLong(ColumnIndex, IsNull);\n      stFloat: Result := Trunc(GetFloat(ColumnIndex, IsNull));\n      stDouble: Result := Trunc(GetDouble(ColumnIndex, IsNull));\n      stBigDecimal: Result := Trunc(GetBigDecimal(ColumnIndex, IsNull));\n      stString, stUnicodeString: Result := StrToIntDef(GetString(ColumnIndex, IsNull), 0);\n    end;\n    IsNull := False;\n  end\n  else\n    IsNull := True;\nend;\n\n{**\n  Gets the value of the designated column in the current row\n  of this <code>ResultSet</code> object as\n  an <code>int</code> in the Java programming language.\n\n  @param columnIndex the first column is 1, the second is 2, ...\n  @return the column value; if the value is SQL <code>NULL</code>, the\n    value returned is <code>0</code>\n}\nfunction TZRowAccessor.GetInt(ColumnIndex: Integer; var IsNull: Boolean): Integer;\nbegin\n{$IFNDEF DISABLE_CHECKING}\n  CheckColumnConvertion(ColumnIndex, stInteger);\n{$ENDIF}\n  Result := 0;\n  if FBuffer.Columns[FColumnOffsets[ColumnIndex - 1]] = 0 then\n  begin\n    case FColumnTypes[ColumnIndex - 1] of\n      stBoolean:\n        if GetBoolean(ColumnIndex, IsNull) then\n          Result := 1\n        else\n          Result := 0;\n      stByte: Result := GetByte(ColumnIndex, IsNull);\n      stShort: Result := GetShort(ColumnIndex, IsNull);\n      stInteger:\n        Result := PInteger(@FBuffer.Columns[FColumnOffsets[ColumnIndex - 1] + 1])^;\n      stLong: Result := GetLong(ColumnIndex, IsNull);\n      stFloat: Result := Trunc(GetFloat(ColumnIndex, IsNull));\n      stDouble: Result := Trunc(GetDouble(ColumnIndex, IsNull));\n      stBigDecimal: Result := Trunc(GetBigDecimal(ColumnIndex, IsNull));\n      stString, stUnicodeString:\n        Result := StrToIntDef(GetString(ColumnIndex, IsNull), 0);\n    end;\n    IsNull := False;\n  end\n  else\n    IsNull := True;\nend;\n\n{**\n  Gets the value of the designated column in the current row\n  of this <code>ResultSet</code> object as\n  a <code>long</code> in the Java programming language.\n\n  @param columnIndex the first column is 1, the second is 2, ...\n  @return the column value; if the value is SQL <code>NULL</code>, the\n    value returned is <code>0</code>\n}\nfunction TZRowAccessor.GetLong(ColumnIndex: Integer; var IsNull: Boolean): Int64;\nbegin\n{$IFNDEF DISABLE_CHECKING}\n  CheckColumnConvertion(ColumnIndex, stLong);\n{$ENDIF}\n  Result := 0;\n  if FBuffer.Columns[FColumnOffsets[ColumnIndex - 1]] = 0 then\n  begin\n    case FColumnTypes[ColumnIndex - 1] of\n      stBoolean:\n        if GetBoolean(ColumnIndex, IsNull) then\n          Result := 1\n        else\n          Result := 0;\n      stByte: Result := GetByte(ColumnIndex, IsNull);\n      stShort: Result := GetShort(ColumnIndex, IsNull);\n      stInteger: Result := GetInt(ColumnIndex, IsNull);\n      stLong:\n        Result := PInt64(@FBuffer.Columns[FColumnOffsets[ColumnIndex - 1] + 1])^;\n      stFloat: Result := Trunc(GetFloat(ColumnIndex, IsNull));\n      stDouble: Result := Trunc(GetDouble(ColumnIndex, IsNull));\n      stBigDecimal: Result := Trunc(GetBigDecimal(ColumnIndex, IsNull));\n      stString, stUnicodeString:\n        Result := StrToIntDef(GetString(ColumnIndex, IsNull), 0);\n    end;\n    IsNull := False;\n  end\n  else\n    IsNull := True;\nend;\n\n{**\n  Gets the value of the designated column in the current row\n  of this <code>ResultSet</code> object as\n  a <code>float</code> in the Java programming language.\n\n  @param columnIndex the first column is 1, the second is 2, ...\n  @return the column value; if the value is SQL <code>NULL</code>, the\n    value returned is <code>0</code>\n}\nfunction TZRowAccessor.GetFloat(ColumnIndex: Integer; var IsNull: Boolean): Single;\nbegin\n{$IFNDEF DISABLE_CHECKING}\n  CheckColumnConvertion(ColumnIndex, stFloat);\n{$ENDIF}\n  Result := 0;\n  if FBuffer.Columns[FColumnOffsets[ColumnIndex - 1]] = 0 then\n  begin\n    case FColumnTypes[ColumnIndex - 1] of\n      stBoolean:\n        if GetBoolean(ColumnIndex, IsNull) then\n          Result := 1\n        else\n          Result := 0;\n      stByte: Result := GetByte(ColumnIndex, IsNull);\n      stShort: Result := GetShort(ColumnIndex, IsNull);\n      stInteger: Result := GetInt(ColumnIndex, IsNull);\n      stLong: Result := GetLong(ColumnIndex, IsNull);\n      stFloat:\n        Result := PSingle(@FBuffer.Columns[FColumnOffsets[ColumnIndex - 1] + 1])^;\n      stDouble: Result := GetDouble(ColumnIndex, IsNull);\n      stBigDecimal: Result := GetBigDecimal(ColumnIndex, IsNull);\n      stString, stUnicodeString:\n        Result := SQLStrToFloatDef(AnsiString(GetString(ColumnIndex, IsNull)), 0);\n    end;\n    IsNull := False;\n  end\n  else\n    IsNull := True;\nend;\n\n{**\n  Gets the value of the designated column in the current row\n  of this <code>ResultSet</code> object as\n  a <code>double</code> in the Java programming language.\n\n  @param columnIndex the first column is 1, the second is 2, ...\n  @return the column value; if the value is SQL <code>NULL</code>, the\n    value returned is <code>0</code>\n}\nfunction TZRowAccessor.GetDouble(ColumnIndex: Integer; var IsNull: Boolean): Double;\nbegin\n{$IFNDEF DISABLE_CHECKING}\n  CheckColumnConvertion(ColumnIndex, stDouble);\n{$ENDIF}\n  Result := 0;\n  if FBuffer.Columns[FColumnOffsets[ColumnIndex - 1]] = 0 then\n  begin\n    case FColumnTypes[ColumnIndex - 1] of\n      stBoolean:\n        if GetBoolean(ColumnIndex, IsNull) then\n          Result := 1\n        else\n          Result := 0;\n      stByte: Result := GetByte(ColumnIndex, IsNull);\n      stShort: Result := GetShort(ColumnIndex, IsNull);\n      stInteger: Result := GetInt(ColumnIndex, IsNull);\n      stLong: Result := GetLong(ColumnIndex, IsNull);\n      stFloat: Result := GetFloat(ColumnIndex, IsNull);\n      stDouble:\n        Result := PDouble(@FBuffer.Columns[FColumnOffsets[ColumnIndex - 1] + 1])^;\n      stBigDecimal: Result := GetBigDecimal(ColumnIndex, IsNull);\n      stString, stUnicodeString:\n        Result := SQLStrToFloatDef(AnsiString(GetString(ColumnIndex, IsNull)), 0);\n    end;\n    IsNull := False;\n  end\n  else\n    IsNull := True;\nend;\n\n{**\n  Gets the value of the designated column in the current row\n  of this <code>ResultSet</code> object as\n  a <code>java.sql.BigDecimal</code> in the Java programming language.\n\n  @param columnIndex the first column is 1, the second is 2, ...\n  @param scale the number of digits to the right of the decimal point\n  @return the column value; if the value is SQL <code>NULL</code>, the\n    value returned is <code>null</code>\n}\nfunction TZRowAccessor.GetBigDecimal(ColumnIndex: Integer; var IsNull: Boolean): Extended;\nbegin\n{$IFNDEF DISABLE_CHECKING}\n  CheckColumnConvertion(ColumnIndex, stBigDecimal);\n{$ENDIF}\n  Result := 0;\n  if FBuffer.Columns[FColumnOffsets[ColumnIndex - 1]] = 0 then\n  begin\n    case FColumnTypes[ColumnIndex - 1] of\n      stBoolean:\n        if GetBoolean(ColumnIndex, IsNull) then\n          Result := 1\n        else\n          Result := 0;\n      stByte: Result := GetByte(ColumnIndex, IsNull);\n      stShort: Result := GetShort(ColumnIndex, IsNull);\n      stInteger: Result := GetInt(ColumnIndex, IsNull);\n      stLong: Result := GetLong(ColumnIndex, IsNull);\n      stFloat: Result := GetFloat(ColumnIndex, IsNull);\n      stDouble: Result := GetDouble(ColumnIndex, IsNull);\n      stBigDecimal:\n        Result := PExtended(@FBuffer.Columns[FColumnOffsets[ColumnIndex - 1] + 1])^;\n      stString, stUnicodeString:\n        Result := SQLStrToFloatDef(AnsiString(GetString(ColumnIndex, IsNull)), 0);\n    end;\n    IsNull := False;\n  end\n  else\n    IsNull := True;\nend;\n\n{**\n  Gets the value of the designated column in the current row\n  of this <code>ResultSet</code> object as\n  a <code>byte</code> array in the Java programming language.\n  The bytes represent the raw values returned by the driver.\n\n  @param columnIndex the first column is 1, the second is 2, ...\n  @return the column value; if the value is SQL <code>NULL</code>, the\n    value returned is <code>null</code>\n}\nfunction TZRowAccessor.GetBytes(ColumnIndex: Integer; var IsNull: Boolean): TByteDynArray;\nbegin\n{$IFNDEF DISABLE_CHECKING}\n  CheckColumnConvertion(ColumnIndex, stBytes);\n{$ENDIF}\n  Result := nil;\n  if FBuffer.Columns[FColumnOffsets[ColumnIndex - 1]] = 0 then\n  begin\n    case FColumnTypes[ColumnIndex - 1] of\n      stBytes,stGUID:\n        Result := InternalGetBytes(FBuffer, ColumnIndex);\n      stBinaryStream:\n        Result := GetBlob(ColumnIndex, IsNull).GetBytes;\n      else\n        Result := StrToBytes(AnsiString(GetString(ColumnIndex, IsNull)));\n    end;\n    IsNull := False;\n  end\n  else\n    IsNull := True;\nend;\n\n{**\n  Gets the value of the designated column in the current row\n  of this <code>ResultSet</code> object as\n  a <code>java.sql.Date</code> object in the Java programming language.\n\n  @param columnIndex the first column is 1, the second is 2, ...\n  @return the column value; if the value is SQL <code>NULL</code>, the\n    value returned is <code>null</code>\n}\nfunction TZRowAccessor.GetDate(ColumnIndex: Integer; var IsNull: Boolean): TDateTime;\nbegin\n{$IFNDEF DISABLE_CHECKING}\n  CheckColumnConvertion(ColumnIndex, stDate);\n{$ENDIF}\n  Result := 0;\n  if FBuffer.Columns[FColumnOffsets[ColumnIndex - 1]] = 0 then\n  begin\n    case FColumnTypes[ColumnIndex - 1] of\n      stDate, stTime, stTimestamp:\n        Result := Int(PDateTime(@FBuffer.Columns[FColumnOffsets[ColumnIndex - 1] + 1])^);\n      stString, stUnicodeString:\n        Result := Trunc(AnsiSQLDateToDateTime(GetString(ColumnIndex, IsNull)));\n    end;\n    IsNull := False;\n  end\n  else\n    IsNull := True;\nend;\n\n{**\n  Gets the value of the designated column in the current row\n  of this <code>ResultSet</code> object as\n  a <code>java.sql.Time</code> object in the Java programming language.\n\n  @param columnIndex the first column is 1, the second is 2, ...\n  @return the column value; if the value is SQL <code>NULL</code>, the\n    value returned is <code>null</code>\n}\nfunction TZRowAccessor.GetTime(ColumnIndex: Integer; var IsNull: Boolean): TDateTime;\nbegin\n{$IFNDEF DISABLE_CHECKING}\n  CheckColumnConvertion(ColumnIndex, stTime);\n{$ENDIF}\n  Result := 0;\n  if FBuffer.Columns[FColumnOffsets[ColumnIndex - 1]] = 0 then\n  begin\n    case FColumnTypes[ColumnIndex - 1] of\n      stDate, stTime, stTimestamp:\n        Result := Frac(PDateTime(@FBuffer.Columns[FColumnOffsets[ColumnIndex - 1] + 1])^);\n      stString, stUnicodeString:\n        Result := Frac(AnsiSQLDateToDateTime(GetString(ColumnIndex, IsNull)));\n    end;\n    IsNull := False;\n  end\n  else\n    IsNull := True;\nend;\n\n{**\n  Gets the value of the designated column in the current row\n  of this <code>ResultSet</code> object as\n  a <code>java.sql.Timestamp</code> object in the Java programming language.\n\n  @param columnIndex the first column is 1, the second is 2, ...\n  @return the column value; if the value is SQL <code>NULL</code>, the\n  value returned is <code>null</code>\n  @exception SQLException if a database access error occurs\n}\nfunction TZRowAccessor.GetTimestamp(ColumnIndex: Integer; var IsNull: Boolean): TDateTime;\nbegin\n{$IFNDEF DISABLE_CHECKING}\n  CheckColumnConvertion(ColumnIndex, stTimestamp);\n{$ENDIF}\n  Result := 0;\n  if FBuffer.Columns[FColumnOffsets[ColumnIndex - 1]] = 0 then\n  begin\n    case FColumnTypes[ColumnIndex - 1] of\n      stDate, stTime, stTimestamp:\n        Result := PDateTime(@FBuffer.Columns[FColumnOffsets[ColumnIndex - 1] + 1])^;\n      stString, stUnicodeString:\n        Result := AnsiSQLDateToDateTime(GetString(ColumnIndex, IsNull));\n    end;\n    IsNull := False;\n  end\n  else\n    IsNull := True;\nend;\n\n{**\n  Gets the value of the designated column in the current row\n  of this <code>ResultSet</code> object as\n  a stream of ASCII characters. The value can then be read in chunks from the\n  stream. This method is particularly\n  suitable for retrieving large <char>LONGVARCHAR</char> values.\n  The JDBC driver will\n  do any necessary conversion from the database format into ASCII.\n\n  <P><B>Note:</B> All the data in the returned stream must be\n  read prior to getting the value of any other column. The next\n  call to a <code>getXXX</code> method implicitly closes the stream.  Also, a\n  stream may return <code>0</code> when the method\n  <code>InputStream.available</code>\n  is called whether there is data available or not.\n\n  @param columnIndex the first column is 1, the second is 2, ...\n  @return a Java input stream that delivers the database column value\n    as a stream of one-byte ASCII characters; if the value is SQL\n    <code>NULL</code>, the value returned is <code>null</code>\n}\nfunction TZRowAccessor.GetAsciiStream(ColumnIndex: Integer; var IsNull: Boolean): TStream;\nvar\n  TempBlob: IZBlob;\nbegin\n{$IFNDEF DISABLE_CHECKING}\n  CheckColumnConvertion(ColumnIndex, stAsciiStream);\n{$ENDIF}\n  TempBlob := GetBlobObject(FBuffer, ColumnIndex);\n  if (TempBlob <> nil) and not TempBlob.IsEmpty then\n    Result := TempBlob.GetStream\n  else\n    Result := nil;\n  IsNull := Result = nil;\nend;\n\n{**\n  Gets the value of a column in the current row as a stream of\n  Gets the value of the designated column in the current row\n  of this <code>ResultSet</code> object as\n  as a stream of Unicode characters.\n  The value can then be read in chunks from the\n  stream. This method is particularly\n  suitable for retrieving large<code>LONGVARCHAR</code>values.  The JDBC driver will\n  do any necessary conversion from the database format into Unicode.\n  The byte format of the Unicode stream must be Java UTF-8,\n  as specified in the Java virtual machine specification.\n\n  <P><B>Note:</B> All the data in the returned stream must be\n  read prior to getting the value of any other column. The next\n  call to a <code>getXXX</code> method implicitly closes the stream.  Also, a\n  stream may return <code>0</code> when the method\n  <code>InputStream.available</code>\n  is called whether there is data available or not.\n\n  @param columnIndex the first column is 1, the second is 2, ...\n  @return a Java input stream that delivers the database column value\n    as a stream in Java UTF-8 byte format; if the value is SQL\n    <code>NULL</code>, the value returned is <code>null</code>\n}\nfunction TZRowAccessor.GetUnicodeStream(ColumnIndex: Integer; var IsNull: Boolean): TStream;\nvar\n  TempBlob: IZBlob;\nbegin\n{$IFNDEF DISABLE_CHECKING}\n  CheckColumnConvertion(ColumnIndex, stUnicodeStream);\n{$ENDIF}\n  TempBlob := GetBlobObject(FBuffer, ColumnIndex);\n  if (TempBlob <> nil) and not TempBlob.IsEmpty then\n    Result := TempBlob.GetUnicodeStream\n  else\n    Result := nil;\n  IsNull := Result = nil;\nend;\n\n{**\n  Gets the value of a column in the current row as a stream of\n  Gets the value of the designated column in the current row\n  of this <code>ResultSet</code> object as a binary stream of\n  uninterpreted bytes. The value can then be read in chunks from the\n  stream. This method is particularly\n  suitable for retrieving large <code>LONGVARBINARY</code> values.\n\n  <P><B>Note:</B> All the data in the returned stream must be\n  read prior to getting the value of any other column. The next\n  call to a <code>getXXX</code> method implicitly closes the stream.  Also, a\n  stream may return <code>0</code> when the method\n  <code>InputStream.available</code>\n  is called whether there is data available or not.\n\n  @param columnIndex the first column is 1, the second is 2, ...\n  @return a Java input stream that delivers the database column value\n    as a stream of uninterpreted bytes;\n    if the value is SQL <code>NULL</code>, the value returned is <code>null</code>\n}\nfunction TZRowAccessor.GetBinaryStream(ColumnIndex: Integer; var IsNull: Boolean): TStream;\nvar\n  TempBlob: IZBlob;\nbegin\n{$IFNDEF DISABLE_CHECKING}\n  CheckColumnConvertion(ColumnIndex, stBinaryStream);\n{$ENDIF}\n  TempBlob := GetBlobObject(FBuffer, ColumnIndex);\n  if (TempBlob <> nil) and not TempBlob.IsEmpty then\n    Result := TempBlob.GetStream\n  else\n    Result := nil;\n  IsNull := Result = nil;\nend;\n\n{**\n  Returns the value of the designated column in the current row\n  of this <code>ResultSet</code> object as a <code>Blob</code> object\n  in the Java programming language.\n\n  @param ColumnIndex the first column is 1, the second is 2, ...\n  @return a <code>Blob</code> object representing the SQL <code>BLOB</code> value in\n    the specified column\n}\nfunction TZRowAccessor.GetBlob(ColumnIndex: Integer; var IsNull: Boolean): IZBlob;\nbegin\n{$IFNDEF DISABLE_CHECKING}\n  CheckColumnIndex(ColumnIndex);\n  if not (FColumnTypes[ColumnIndex - 1] in [stAsciiStream, stBinaryStream,\n    stUnicodeStream]) then\n  begin\n    raise EZSQLException.Create(\n      Format(SCanNotAccessBlobRecord,\n      [ColumnIndex, DefineColumnTypeName(FColumnTypes[ColumnIndex - 1])]));\n  end;\n{$ENDIF}\n\n  Result := GetBlobObject(FBuffer, ColumnIndex);\n  IsNull := Result = nil;\n  if Result = nil then\n  begin\n    Result := TZAbstractBlob.CreateWithStream(nil, nil);\n    SetBlobObject(FBuffer, ColumnIndex, Result);\n  end;\nend;\n\n{**\n  Returns the value of the designated column in the current row\n  of this <code>ResultSet</code> object as a <code>ResultSet</code> object\n  in the Java programming language.\n\n  @param ColumnIndex the first column is 1, the second is 2, ...\n  @return a <code>ResultSet</code> object representing the SQL\n    <code>ResultSet</code> value in the specified column\n}\nfunction TZRowAccessor.GetDataSet(ColumnIndex: Integer; var IsNull: Boolean): IZDataSet;\nvar\n  Ptr: PPointer;\n  NullPtr: {$IFDEF WIN64}PBoolean{$ELSE}PByte{$ENDIF};\nbegin\n{$IFNDEF DISABLE_CHECKING}\n  CheckColumnIndex(ColumnIndex);\n  if not (FColumnTypes[ColumnIndex - 1] = stDataSet) then\n  begin\n    raise EZSQLException.Create(\n      Format(SCanNotAccessBlobRecord,\n      [ColumnIndex, DefineColumnTypeName(FColumnTypes[ColumnIndex - 1])]));\n  end;\n{$ENDIF}\n\n  Ptr := PPointer(@FBuffer.Columns[FColumnOffsets[ColumnIndex - 1] + 1]);\n  NullPtr := {$IFDEF WIN64}PBoolean{$ELSE}PByte{$ENDIF}(@FBuffer.Columns[FColumnOffsets[ColumnIndex - 1]]);\n\n  {$IFNDEF FPC}\n  if NullPtr^ = {$IFDEF WIN64}false{$ELSE}0{$ENDIF} then\n  {$ELSE}\n  if NullPtr^ = 0 then\n  {$ENDIF}\n    Result := IZDataSet(Ptr^)\n  else\n    Result := nil;\nend;\n\n{**\n  Gets the value of the designated column in the current row\n  of this <code>ResultSet</code> object as a <code>Variant</code> value.\n\n  @param columnIndex the first column is 1, the second is 2, ...\n  @return the column value; if the value is SQL <code>NULL</code>, the\n  value returned is <code>null</code>\n}\nfunction TZRowAccessor.GetValue(ColumnIndex: Integer): TZVariant;\nvar\n  ValuePtr: Pointer;\n  IsNull: Boolean;\nbegin\n  IsNull := False;\n  if FBuffer.Columns[FColumnOffsets[ColumnIndex - 1]] = 0 then\n  begin\n    ValuePtr := @FBuffer.Columns[FColumnOffsets[ColumnIndex - 1] + 1];\n    case FColumnTypes[ColumnIndex - 1] of\n      stByte:\n        begin\n          Result.VType := vtInteger;\n          Result.VInteger := PShortInt(ValuePtr)^;\n        end;\n      stShort:\n        begin\n          Result.VType := vtInteger;\n          Result.VInteger := PSmallInt(ValuePtr)^;\n        end;\n      stInteger:\n        begin\n          Result.VType := vtInteger;\n          Result.VInteger := PInteger(ValuePtr)^;\n        end;\n      stLong:\n        begin\n          Result.VType := vtInteger;\n          Result.VInteger := PInt64(ValuePtr)^;\n        end;\n      stFloat:\n        begin\n          Result.VType := vtFloat;\n          Result.VFloat := PSingle(ValuePtr)^;\n        end;\n      stDouble:\n        begin\n          Result.VType := vtFloat;\n          Result.VFloat := PDouble(ValuePtr)^;\n        end;\n      stBigDecimal:\n        begin\n          Result.VType := vtFloat;\n          Result.VFloat := PExtended(ValuePtr)^;\n        end;\n      stBoolean:\n        begin\n          Result.VType := vtBoolean;\n          Result.VBoolean := PWordBool(ValuePtr)^;\n        end;\n      stDate, stTime, stTimestamp:\n        begin\n          Result.VType := vtDateTime;\n          Result.VDateTime := PDateTime(ValuePtr)^;\n        end;\n      stString:\n        begin\n          Result.VType := vtString;\n          Result.VString := PChar(ValuePtr);\n        end;\n      stUnicodeString:\n        begin\n          Result.VType := vtUnicodeString;\n          Result.VUnicodeString := GetUnicodeString(ColumnIndex, IsNull);\n        end;\n      stBytes,stGUID,stAsciiStream, stBinaryStream:\n        begin\n          Result.VType := vtString;\n          Result.VString := GetString(ColumnIndex, IsNull);\n        end;\n      stUnicodeStream:\n        begin\n          Result.VType := vtUnicodeString;\n          Result.VUnicodeString := GetUnicodeString(ColumnIndex, IsNull);\n        end;\n      stDataSet:\n        begin\n          Result.VType := vtInterface;\n          Result.VInterface := GetDataSet(ColumnIndex, IsNull);\n        end;\n      else\n        Result.VType := vtNull;\n    end;\n  end\n  else\n    Result.VType := vtNull;\nend;\n\n//---------------------------------------------------------------------\n// Updates\n//---------------------------------------------------------------------\n\n{**\n  Gives a not nullable column a null value.\n\n  The <code>SetXXX</code> methods are used to Set column values in the\n  current row or the insert row.  The <code>SetXXX</code> methods do not\n  Set the underlying database; instead the <code>SetRow</code>\n  or <code>insertRow</code> methods are called to Set the database.\n\n  @param columnIndex the first column is 1, the second is 2, ...\n}\nprocedure TZRowAccessor.SetNotNull(ColumnIndex: Integer);\nbegin\n{$IFNDEF DISABLE_CHECKING}\n  CheckColumnConvertion(ColumnIndex, stString);\n{$ENDIF}\n  if (FBuffer.Columns[FColumnOffsets[ColumnIndex - 1]] = 1)\n    and (FColumnTypes[ColumnIndex - 1] in [stAsciiStream, stBinaryStream,\n    stUnicodeStream]) then\n  begin\n    SetBlobObject(FBuffer, ColumnIndex, nil);\n  end;\n  FBuffer.Columns[FColumnOffsets[ColumnIndex - 1]] := 0;\nend;\n\n{**\n  Gives a nullable column a null value.\n\n  The <code>SetXXX</code> methods are used to Set column values in the\n  current row or the insert row.  The <code>SetXXX</code> methods do not\n  Set the underlying database; instead the <code>SetRow</code>\n  or <code>insertRow</code> methods are called to Set the database.\n\n  @param columnIndex the first column is 1, the second is 2, ...\n}\nprocedure TZRowAccessor.SetNull(ColumnIndex: Integer);\nbegin\n{$IFNDEF DISABLE_CHECKING}\n  CheckColumnConvertion(ColumnIndex, stString);\n{$ENDIF}\n  if (FBuffer.Columns[FColumnOffsets[ColumnIndex - 1]] = 0) then\n    case FColumnTypes[ColumnIndex - 1] of\n      stAsciiStream, stBinaryStream, stUnicodeStream:\n        SetBlobObject(FBuffer, ColumnIndex, nil);\n      stBytes,stGUID, stString, stUnicodeString:\n        if PNativeUInt(@FBuffer.Columns[FColumnOffsets[ColumnIndex - 1] + 1])^ > 0 then\n        begin\n          System.Dispose(PPointer(@FBuffer.Columns[FColumnOffsets[ColumnIndex - 1] + 1])^);\n          PNativeUInt(@FBuffer.Columns[FColumnOffsets[ColumnIndex - 1] + 1])^ := 0;\n        end;\n    end;\n  FBuffer.Columns[FColumnOffsets[ColumnIndex - 1]] := 1;\nend;\n\n{**\n  Sets the designated column with a <code>boolean</code> value.\n  The <code>SetXXX</code> methods are used to Set column values in the\n  current row or the insert row.  The <code>SetXXX</code> methods do not\n  Set the underlying database; instead the <code>SetRow</code> or\n  <code>insertRow</code> methods are called to Set the database.\n\n  @param columnIndex the first column is 1, the second is 2, ...\n  @param x the new column value\n}\nprocedure TZRowAccessor.SetBoolean(ColumnIndex: Integer; Value: Boolean);\nvar\n  TempInt: Integer;\nbegin\n{$IFNDEF DISABLE_CHECKING}\n  CheckColumnConvertion(ColumnIndex, stBoolean);\n{$ENDIF}\n  if Value then\n     TempInt := 1\n  else\n     TempInt := 0;\n\n  case FColumnTypes[ColumnIndex - 1] of\n    stBoolean:\n      begin\n        FBuffer.Columns[FColumnOffsets[ColumnIndex - 1]] := 0;\n        PWordBool(@FBuffer.Columns[FColumnOffsets[ColumnIndex - 1] + 1])^ := Value;\n      end;\n    stByte: SetByte(ColumnIndex, TempInt);\n    stShort: SetShort(ColumnIndex, TempInt);\n    stInteger: SetInt(ColumnIndex, TempInt);\n    stLong: SetLong(ColumnIndex, TempInt);\n    stFloat: SetFloat(ColumnIndex, TempInt);\n    stDouble: SetDouble(ColumnIndex, TempInt);\n    stBigDecimal: SetBigDecimal(ColumnIndex, TempInt);\n    stString, stUnicodeString:\n         if Value then\n            SetString(ColumnIndex, 'True')\n         else\n            SetString(ColumnIndex, 'False');\n  end;\nend;\n\n{**\n  Sets the designated column with a <code>byte</code> value.\n  The <code>SetXXX</code> methods are used to Set column values in the\n  current row or the insert row.  The <code>SetXXX</code> methods do not\n  Set the underlying database; instead the <code>SetRow</code> or\n  <code>insertRow</code> methods are called to Set the database.\n\n\n  @param columnIndex the first column is 1, the second is 2, ...\n  @param x the new column value\n}\nprocedure TZRowAccessor.SetByte(ColumnIndex: Integer;\n  Value: ShortInt);\nbegin\n{$IFNDEF DISABLE_CHECKING}\n  CheckColumnConvertion(ColumnIndex, stByte);\n{$ENDIF}\n  case FColumnTypes[ColumnIndex - 1] of\n    stBoolean: SetBoolean(ColumnIndex, Value <> 0);\n    stByte:\n      begin\n        FBuffer.Columns[FColumnOffsets[ColumnIndex - 1]] := 0;\n        PShortInt(@FBuffer.Columns[FColumnOffsets[ColumnIndex - 1] + 1])^ := Value;\n      end;\n    stShort: SetShort(ColumnIndex, Value);\n    stInteger: SetInt(ColumnIndex, Value);\n    stLong: SetLong(ColumnIndex, Value);\n    stFloat: SetFloat(ColumnIndex, Value);\n    stDouble: SetDouble(ColumnIndex, Value);\n    stBigDecimal: SetBigDecimal(ColumnIndex, Value);\n    stString, stUnicodeString: SetString(ColumnIndex, IntToStr(Value));\n  end;\nend;\n\n{**\n  Sets the designated column with a <code>short</code> value.\n  The <code>SetXXX</code> methods are used to Set column values in the\n  current row or the insert row.  The <code>SetXXX</code> methods do not\n  Set the underlying database; instead the <code>SetRow</code> or\n  <code>insertRow</code> methods are called to Set the database.\n\n  @param columnIndex the first column is 1, the second is 2, ...\n  @param x the new column value\n}\nprocedure TZRowAccessor.SetShort(ColumnIndex: Integer; Value: SmallInt);\nbegin\n{$IFNDEF DISABLE_CHECKING}\n  CheckColumnConvertion(ColumnIndex, stShort);\n{$ENDIF}\n  case FColumnTypes[ColumnIndex - 1] of\n    stBoolean: SetBoolean(ColumnIndex, Value <> 0);\n    stByte: SetByte(ColumnIndex, Value);\n    stShort:\n      begin\n        FBuffer.Columns[FColumnOffsets[ColumnIndex - 1]] := 0;\n        PSmallInt(@FBuffer.Columns[FColumnOffsets[ColumnIndex - 1] + 1])^ := Value;\n      end;\n    stInteger: SetInt(ColumnIndex, Value);\n    stLong: SetLong(ColumnIndex, Value);\n    stFloat: SetFloat(ColumnIndex, Value);\n    stDouble: SetDouble(ColumnIndex, Value);\n    stBigDecimal: SetBigDecimal(ColumnIndex, Value);\n    stString, stUnicodeString: SetString(ColumnIndex, IntToStr(Value));\n  end;\nend;\n\n{**\n  Sets the designated column with an <code>int</code> value.\n  The <code>SetXXX</code> methods are used to Set column values in the\n  current row or the insert row.  The <code>SetXXX</code> methods do not\n  Set the underlying database; instead the <code>SetRow</code> or\n  <code>insertRow</code> methods are called to Set the database.\n\n  @param columnIndex the first column is 1, the second is 2, ...\n  @param x the new column value\n}\nprocedure TZRowAccessor.SetInt(ColumnIndex: Integer; Value: Integer);\nbegin\n{$IFNDEF DISABLE_CHECKING}\n  CheckColumnConvertion(ColumnIndex, stInteger);\n{$ENDIF}\n  case FColumnTypes[ColumnIndex - 1] of\n    stBoolean: SetBoolean(ColumnIndex, Value <> 0);\n    stByte: SetByte(ColumnIndex, Value);\n    stShort: SetShort(ColumnIndex, Value);\n    stInteger:\n      begin\n        FBuffer.Columns[FColumnOffsets[ColumnIndex - 1]] := 0;\n        PInteger(@FBuffer.Columns[FColumnOffsets[ColumnIndex - 1] + 1])^ := Value;\n      end;\n    stLong: SetLong(ColumnIndex, Value);\n    stFloat: SetFloat(ColumnIndex, Value);\n    stDouble: SetDouble(ColumnIndex, Value);\n    stBigDecimal: SetBigDecimal(ColumnIndex, Value);\n    stString, stUnicodeString: SetString(ColumnIndex, IntToStr(Value));\n  end;\nend;\n\n{**\n  Sets the designated column with a <code>long</code> value.\n  The <code>SetXXX</code> methods are used to Set column values in the\n  current row or the insert row.  The <code>SetXXX</code> methods do not\n  Set the underlying database; instead the <code>SetRow</code> or\n  <code>insertRow</code> methods are called to Set the database.\n\n  @param columnIndex the first column is 1, the second is 2, ...\n  @param x the new column value\n}\nprocedure TZRowAccessor.SetLong(ColumnIndex: Integer; Value: Int64);\nbegin\n{$IFNDEF DISABLE_CHECKING}\n  CheckColumnConvertion(ColumnIndex, stLong);\n{$ENDIF}\n  case FColumnTypes[ColumnIndex - 1] of\n    stBoolean: SetBoolean(ColumnIndex, Value <> 0);\n    stByte: SetByte(ColumnIndex, Value);\n    stShort: SetShort(ColumnIndex, Value);\n    stInteger: SetInt(ColumnIndex, Value);\n    stLong:\n      begin\n        FBuffer.Columns[FColumnOffsets[ColumnIndex - 1]] := 0;\n        PInt64(@FBuffer.Columns[FColumnOffsets[ColumnIndex - 1] + 1])^ := Value;\n      end;\n    stFloat: SetFloat(ColumnIndex, Value);\n    stDouble: SetDouble(ColumnIndex, Value);\n    stBigDecimal: SetBigDecimal(ColumnIndex, Value);\n    stString, stUnicodeString: SetString(ColumnIndex, IntToStr(Value));\n  end;\nend;\n\n{**\n  Sets the designated column with a <code>float</code> value.\n  The <code>SetXXX</code> methods are used to Set column values in the\n  current row or the insert row.  The <code>SetXXX</code> methods do not\n  Set the underlying database; instead the <code>SetRow</code> or\n  <code>insertRow</code> methods are called to Set the database.\n\n  @param columnIndex the first column is 1, the second is 2, ...\n  @param x the new column value\n}\nprocedure TZRowAccessor.SetFloat(ColumnIndex: Integer; Value: Single);\nbegin\n{$IFNDEF DISABLE_CHECKING}\n  CheckColumnConvertion(ColumnIndex, stFloat);\n{$ENDIF}\n  case FColumnTypes[ColumnIndex - 1] of\n    stBoolean: SetBoolean(ColumnIndex, Value <> 0);\n    stByte: SetByte(ColumnIndex, Trunc(Value));\n    stShort: SetShort(ColumnIndex, Trunc(Value));\n    stInteger: SetInt(ColumnIndex, Trunc(Value));\n    stLong: SetLong(ColumnIndex, Trunc(Value));\n    stFloat:\n      begin\n        FBuffer.Columns[FColumnOffsets[ColumnIndex - 1]] := 0;\n        PSingle(@FBuffer.Columns[FColumnOffsets[ColumnIndex - 1] + 1])^ := Value;\n      end;\n    stDouble: SetDouble(ColumnIndex, Value);\n    stBigDecimal: SetBigDecimal(ColumnIndex, Value);\n    stString, stUnicodeString: SetString(ColumnIndex, FloatToSQLStr(Value));\n  end;\nend;\n\n{**\n  Sets the designated column with a <code>double</code> value.\n  The <code>SetXXX</code> methods are used to Set column values in the\n  current row or the insert row.  The <code>SetXXX</code> methods do not\n  Set the underlying database; instead the <code>SetRow</code> or\n  <code>insertRow</code> methods are called to Set the database.\n\n  @param columnIndex the first column is 1, the second is 2, ...\n  @param x the new column value\n}\nprocedure TZRowAccessor.SetDouble(ColumnIndex: Integer; Value: Double);\nbegin\n{$IFNDEF DISABLE_CHECKING}\n  CheckColumnConvertion(ColumnIndex, stDouble);\n{$ENDIF}\n  case FColumnTypes[ColumnIndex - 1] of\n    stBoolean: SetBoolean(ColumnIndex, Value <> 0);\n    stByte: SetByte(ColumnIndex, Trunc(Value));\n    stShort: SetShort(ColumnIndex, Trunc(Value));\n    stInteger: SetInt(ColumnIndex, Trunc(Value));\n    stLong: SetLong(ColumnIndex, Trunc(Value));\n    stFloat: SetFloat(ColumnIndex, Value);\n    stDouble:\n      begin\n        FBuffer.Columns[FColumnOffsets[ColumnIndex - 1]] := 0;\n        PDouble(@FBuffer.Columns[FColumnOffsets[ColumnIndex - 1] + 1])^ := Value;\n      end;\n    stBigDecimal: SetBigDecimal(ColumnIndex, Value);\n    stString, stUnicodeString: SetString(ColumnIndex, FloatToSQLStr(Value));\n  end;\nend;\n\n{**\n  Sets the designated column with a <code>java.math.BigDecimal</code>\n  value.\n  The <code>SetXXX</code> methods are used to Set column values in the\n  current row or the insert row.  The <code>SetXXX</code> methods do not\n  Set the underlying database; instead the <code>SetRow</code> or\n  <code>insertRow</code> methods are called to Set the database.\n\n  @param columnIndex the first column is 1, the second is 2, ...\n  @param x the new column value\n}\nprocedure TZRowAccessor.SetBigDecimal(ColumnIndex: Integer; Value: Extended);\nbegin\n{$IFNDEF DISABLE_CHECKING}\n  CheckColumnConvertion(ColumnIndex, stBigDecimal);\n{$ENDIF}\n  case FColumnTypes[ColumnIndex - 1] of\n    stBoolean: SetBoolean(ColumnIndex, Value <> 0);\n    stByte: SetByte(ColumnIndex, Trunc(Value));\n    stShort: SetShort(ColumnIndex, Trunc(Value));\n    stInteger: SetInt(ColumnIndex, Trunc(Value));\n    stLong: SetLong(ColumnIndex, Trunc(Value));\n    stFloat: SetFloat(ColumnIndex, Value);\n    stDouble: SetDouble(ColumnIndex, Value);\n    stBigDecimal:\n      begin\n        FBuffer.Columns[FColumnOffsets[ColumnIndex - 1]] := 0;\n        PExtended(@FBuffer.Columns[FColumnOffsets[ColumnIndex - 1] + 1])^ := Value;\n      end;\n    stString, stUnicodeString: SetString(ColumnIndex, FloatToSQLStr(Value));\n  end;\nend;\n\n{**\n  Sets the designated column with a <code>String</code> value.\n  The <code>SetXXX</code> methods are used to Set column values in the\n  current row or the insert row.  The <code>SetXXX</code> methods do not\n  Set the underlying database; instead the <code>SetRow</code> or\n  <code>insertRow</code> methods are called to Set the database.\n\n  @param columnIndex the first column is 1, the second is 2, ...\n  @param x the new column value\n}\nprocedure TZRowAccessor.SetPChar(ColumnIndex: Integer; Value: PChar);\nbegin\n{$IFNDEF DISABLE_CHECKING}\n  CheckColumnConvertion(ColumnIndex, stString);\n{$ENDIF}\n  case FColumnTypes[ColumnIndex - 1] of\n    stString{$IFDEF UNICODE}, stUnicodeString{$ENDIF}:\n      begin\n        if Value <> nil then\n        begin\n          FBuffer.Columns[FColumnOffsets[ColumnIndex - 1]] := 0;\n          SetString(ColumnIndex, Value);\n        end\n        else\n          FBuffer.Columns[FColumnOffsets[ColumnIndex - 1]] := 1;\n      end;\n    else\n      SetString(ColumnIndex, Value);\n  end;\nend;\n\n{**\n  Sets the designated column with a <code>String</code> value.\n  The <code>SetXXX</code> methods are used to Set column values in the\n  current row or the insert row.  The <code>SetXXX</code> methods do not\n  Set the underlying database; instead the <code>SetRow</code> or\n  <code>insertRow</code> methods are called to Set the database.\n\n  @param columnIndex the first column is 1, the second is 2, ...\n  @param x the new column value\n}\nprocedure TZRowAccessor.SetString(ColumnIndex: Integer; Value: String);\nvar\n  TempStr: string;\n  IsNull: Boolean;\n  GUID: TGUID;\n  Bts: TByteDynArray;\nbegin\n{$IFNDEF DISABLE_CHECKING}\n  CheckColumnConvertion(ColumnIndex, stString);\n{$ENDIF}\n  IsNull := False;\n  case FColumnTypes[ColumnIndex - 1] of\n    stBoolean:\n      begin\n        TempStr := UpperCase(Value);\n        SetBoolean(ColumnIndex, (TempStr = 'Y') or (TempStr = 'T')\n          or (TempStr = 'YES') or (TempStr = 'TRUE'));\n      end;\n    stByte: SetByte(ColumnIndex, StrToIntDef(Value, 0));\n    stShort: SetShort(ColumnIndex, StrToIntDef(Value, 0));\n    stInteger: SetInt(ColumnIndex, StrToIntDef(Value, 0));\n    stLong: SetLong(ColumnIndex, StrToIntDef(Value, 0));\n    stFloat: SetFloat(ColumnIndex, SQLStrToFloatDef(AnsiString(Value), 0));\n    stDouble: SetDouble(ColumnIndex, SQLStrToFloatDef(AnsiString(Value), 0));\n    stBigDecimal: SetBigDecimal(ColumnIndex, SQLStrToFloatDef(AnsiString(Value), 0));\n    stString:\n      begin\n        InternalSetString(FBuffer, ColumnIndex, Value);\n        FBuffer.Columns[FColumnOffsets[ColumnIndex - 1]] := 0;\n      end;\n    stUnicodeString:\n      {$IFDEF UNICODE}\n      SetUnicodeString(ColumnIndex, Value);\n      {$ELSE}\n      SetUnicodeString(ColumnIndex, ZDbcUnicodeString(Value, ConSettings.CTRL_CP));\n      {$ENDIF}\n    stBytes: SetBytes(ColumnIndex, StrToBytes(AnsiString(Value)));\n    stGUID:\n      begin\n        GUID := StringToGUID(Value);\n        SetLength(Bts, 16);\n        System.Move(Pointer(@GUID)^, Pointer(Bts)^, 16);\n        SetBytes(ColumnIndex, Bts);\n      end;\n    stDate: SetDate(ColumnIndex, AnsiSQLDateToDateTime(Value));\n    stTime: SetTime(ColumnIndex, AnsiSQLDateToDateTime(Value));\n    stTimestamp: SetTimestamp(ColumnIndex, AnsiSQLDateToDateTime(Value));\n    stUnicodeStream:\n    {$IFDEF UNICODE}\n      GetBlob(ColumnIndex, IsNull).SetUnicodeString(Value);\n    {$ELSE}\n      GetBlob(ColumnIndex, IsNull).SetString(ZDbcUnicodeString(Value, ConSettings.CTRL_CP));\n    {$ENDIF}\n    stAsciiStream:\n      GetBlob(ColumnIndex, IsNull).SetString(ZPlainString(Value, ConSettings, ConSettings.CTRL_CP));\n    stBinaryStream:\n      GetBlob(ColumnIndex, IsNull).SetString(RawByteString(Value));\n  end;\nend;\n\n{**\n  Sets the designated column with a <code>WideString</code> value.\n  The <code>SetXXX</code> methods are used to Set column values in the\n  current row or the insert row.  The <code>SetXXX</code> methods do not\n  Set the underlying database; instead the <code>SetRow</code> or\n  <code>insertRow</code> methods are called to Set the database.\n\n  @param columnIndex the first column is 1, the second is 2, ...\n  @param x the new column value\n}\nprocedure TZRowAccessor.SetUnicodeString(ColumnIndex: Integer; Value: WideString);\nvar IsNull: Boolean;\nbegin\n{$IFNDEF DISABLE_CHECKING}\n  CheckColumnConvertion(ColumnIndex, stString);\n{$ENDIF}\n  case FColumnTypes[ColumnIndex - 1] of\n    stUnicodeString{$IFDEF UNICODE},stString{$ENDIF}:\n      begin\n        FBuffer.Columns[FColumnOffsets[ColumnIndex - 1]] := 0;\n        InternalSetUnicodeString(FBuffer, ColumnIndex, Value);\n      end;\n    stUnicodeStream:\n      GetBlob(ColumnIndex, IsNull).SetUnicodeString(Value);\n    else\n      SetString(ColumnIndex, ZDbcString(Value));\n  end;\nend;\n\n{**\n  Sets the designated column with a <code>byte</code> array value.\n  The <code>SetXXX</code> methods are used to Set column values in the\n  current row or the insert row.  The <code>SetXXX</code> methods do not\n  Set the underlying database; instead the <code>SetRow</code> or\n  <code>insertRow</code> methods are called to Set the database.\n\n  @param columnIndex the first column is 1, the second is 2, ...\n  @param x the new column value\n}\nprocedure TZRowAccessor.SetBytes(ColumnIndex: Integer; Value: TByteDynArray);\nvar\n  IsNull: Boolean;\nbegin\n{$IFNDEF DISABLE_CHECKING}\n  CheckColumnConvertion(ColumnIndex, stBytes);\n{$ENDIF}\n  if Value <> nil then\n  begin\n    FBuffer.Columns[FColumnOffsets[ColumnIndex - 1]] := 0;\n    case FColumnTypes[ColumnIndex - 1] of\n      stBytes,stGUID: InternalSetBytes(FBuffer, ColumnIndex, Value);\n      stBinaryStream: GetBlob(ColumnIndex, IsNull).SetBytes(Value);\n      else\n        SetString(ColumnIndex, String(BytesToStr(Value)));\n    end;\n  end\n  else\n    SetNull(ColumnIndex);\nend;\n\n{**\n  Sets the designated column with a <code>java.sql.Date</code> value.\n  The <code>SetXXX</code> methods are used to Set column values in the\n  current row or the insert row.  The <code>SetXXX</code> methods do not\n  Set the underlying database; instead the <code>SetRow</code> or\n  <code>insertRow</code> methods are called to Set the database.\n\n  @param columnIndex the first column is 1, the second is 2, ...\n  @param x the new column value\n}\nprocedure TZRowAccessor.SetDate(ColumnIndex: Integer; Value: TDateTime);\nbegin\n{$IFNDEF DISABLE_CHECKING}\n  CheckColumnConvertion(ColumnIndex, stTimestamp);\n{$ENDIF}\n  case FColumnTypes[ColumnIndex - 1] of\n    stDate:\n      begin\n        FBuffer.Columns[FColumnOffsets[ColumnIndex - 1]] := 0;\n        PDateTime(@FBuffer.Columns[FColumnOffsets[ColumnIndex - 1] + 1])^ :=\n          Trunc(Value);\n      end;\n    stTimestamp: SetTimestamp(ColumnIndex, Trunc(Value));\n    stString, stUnicodeString: SetString(ColumnIndex, FormatDateTime('yyyy-mm-dd', Value));\n  end;\nend;\n\n{**\n  Sets the designated column with a <code>java.sql.Time</code> value.\n  The <code>SetXXX</code> methods are used to Set column values in the\n  current row or the insert row.  The <code>SetXXX</code> methods do not\n  Set the underlying database; instead the <code>SetRow</code> or\n  <code>insertRow</code> methods are called to Set the database.\n\n  @param columnIndex the first column is 1, the second is 2, ...\n  @param x the new column value\n}\nprocedure TZRowAccessor.SetTime(ColumnIndex: Integer; Value: TDateTime);\nbegin\n{$IFNDEF DISABLE_CHECKING}\n  CheckColumnConvertion(ColumnIndex, stTime);\n{$ENDIF}\n  case FColumnTypes[ColumnIndex - 1] of\n    stTime:\n      begin\n        FBuffer.Columns[FColumnOffsets[ColumnIndex - 1]] := 0;\n        PDateTime(@FBuffer.Columns[FColumnOffsets[ColumnIndex - 1] + 1])^ :=\n          Frac(Value);\n      end;\n    stTimestamp: SetTimestamp(ColumnIndex, Frac(Value));\n    stString, stUnicodeString:\n      SetString(ColumnIndex, FormatDateTime('hh:nn:ss', Value));\n  end;\nend;\n\n{**\n  Sets the designated column with a <code>java.sql.Timestamp</code>\n  value.\n  The <code>SetXXX</code> methods are used to Set column values in the\n  current row or the insert row.  The <code>SetXXX</code> methods do not\n  Set the underlying database; instead the <code>SetRow</code> or\n  <code>insertRow</code> methods are called to Set the database.\n\n  @param columnIndex the first column is 1, the second is 2, ...\n  @param x the new column value\n}\nprocedure TZRowAccessor.SetTimestamp(ColumnIndex: Integer; Value: TDateTime);\nbegin\n{$IFNDEF DISABLE_CHECKING}\n  CheckColumnConvertion(ColumnIndex, stTimestamp);\n{$ENDIF}\n  case FColumnTypes[ColumnIndex - 1] of\n    stDate: SetDate(ColumnIndex, Value);\n    stTime: SetTime(ColumnIndex, Value);\n    stTimestamp:\n      begin\n        FBuffer.Columns[FColumnOffsets[ColumnIndex - 1]] := 0;\n        PDateTime(@FBuffer.Columns[FColumnOffsets[ColumnIndex - 1] + 1])^ := Value;\n      end;\n    stString, stUnicodeString:\n      SetString(ColumnIndex, FormatDateTime('yyyy-mm-dd hh:nn:ss', Value));\n  end;\nend;\n\n{**\n  Sets the designated column with an ascii stream value.\n  The <code>SetXXX</code> methods are used to Set column values in the\n  current row or the insert row.  The <code>SetXXX</code> methods do not\n  Set the underlying database; instead the <code>SetRow</code> or\n  <code>insertRow</code> methods are called to Set the database.\n\n  @param columnIndex the first column is 1, the second is 2, ...\n  @param x the new column value\n}\nprocedure TZRowAccessor.SetAsciiStream(ColumnIndex: Integer; Value: TStream);\nvar\n  IsNull: Boolean;\nbegin\n{$IFNDEF DISABLE_CHECKING}\n  CheckColumnConvertion(ColumnIndex, stAsciiStream);\n{$ENDIF}\n  IsNull := False;\n  GetBlob(ColumnIndex, IsNull).SetStream(Value);\nend;\n\n{**\n  Sets the designated column with a binary stream value.\n  The <code>SetXXX</code> methods are used to Set column values in the\n  current row or the insert row.  The <code>SetXXX</code> methods do not\n  Set the underlying database; instead the <code>SetRow</code> or\n  <code>insertRow</code> methods are called to Set the database.\n\n  @param columnIndex the first column is 1, the second is 2, ...\n  @param x the new column value\n  @param length the length of the stream\n}\nprocedure TZRowAccessor.SetBinaryStream(ColumnIndex: Integer; Value: TStream);\nvar\n  IsNull: Boolean;\nbegin\n{$IFNDEF DISABLE_CHECKING}\n  CheckColumnConvertion(ColumnIndex, stBinaryStream);\n{$ENDIF}\n  IsNull := False;\n  GetBlob(ColumnIndex, IsNull).SetStream(Value);\nend;\n\n{**\n  Sets the designated column with a character stream value.\n  The <code>SetXXX</code> methods are used to Set column values in the\n  current row or the insert row.  The <code>SetXXX</code> methods do not\n  Set the underlying database; instead the <code>SetRow</code> or\n  <code>insertRow</code> methods are called to Set the database.\n\n  @param columnIndex the first column is 1, the second is 2, ...\n  @param x the new column value\n}\nprocedure TZRowAccessor.SetUnicodeStream(ColumnIndex: Integer;\n  Value: TStream);\nvar\n  IsNull: Boolean;\nbegin\n  IsNull := False;\n{$IFNDEF DISABLE_CHECKING}\n  CheckColumnConvertion(ColumnIndex, stUnicodeStream);\n{$ENDIF}\n  GetBlob(ColumnIndex, IsNull).SetStream(Value, True);\nend;\n\n{**\n  Sets the blob wrapper object to the specified column.\n  @param ColumnIndex the first column is 1, the second is 2, ...\n  @param Value a blob wrapper object to be set.\n}\nprocedure TZRowAccessor.SetBlob(ColumnIndex: Integer; Value: IZBlob);\nbegin\n{$IFNDEF DISABLE_CHECKING}\n  CheckColumnIndex(ColumnIndex);\n  if not (FColumnTypes[ColumnIndex - 1] in [stAsciiStream, stBinaryStream,\n    stUnicodeStream]) then\n  begin\n    raise EZSQLException.Create(\n      Format(SCanNotAccessBlobRecord,\n      [ColumnIndex, DefineColumnTypeName(FColumnTypes[ColumnIndex - 1])]));\n  end;\n{$ENDIF}\n\n  SetBlobObject(FBuffer, ColumnIndex, Value);\nend;\n\n{**\n  Sets the blob wrapper object to the specified column.\n  @param ColumnIndex the first column is 1, the second is 2, ...\n  @param Value a ResultSet wrapper object to be set.\n}\nprocedure TZRowAccessor.SetDataSet(ColumnIndex: Integer; Value: IZDataSet);\nvar\n  Ptr: PPointer;\n  NullPtr: {$IFDEF WIN64}PBoolean{$ELSE}PByte{$ENDIF};\nbegin\n{$IFNDEF DISABLE_CHECKING}\n  CheckColumnIndex(ColumnIndex);\n  if not (FColumnTypes[ColumnIndex - 1] = stDataSet) then\n  begin\n    raise EZSQLException.Create(\n      Format(SCanNotAccessBlobRecord,\n      [ColumnIndex, DefineColumnTypeName(FColumnTypes[ColumnIndex - 1])]));\n  end;\n{$ENDIF}\n\n  Ptr := PPointer(@FBuffer.Columns[FColumnOffsets[ColumnIndex - 1] + 1]);\n  NullPtr := {$IFDEF WIN64}PBoolean{$ELSE}PByte{$ENDIF}(@FBuffer.Columns[FColumnOffsets[ColumnIndex - 1]]);\n\n  {$IFNDEF FPC}\n  if NullPtr^ = {$IFDEF WIN64}false{$ELSE}0{$ENDIF} then  //M.A. if NullPtr^ = 0 then\n  {$ELSE}\n  if NullPtr^ = 0 then\n  {$ENDIF}\n    IZDataSet(Ptr^) := nil\n  else\n    Ptr^ := nil;\n\n  IZDataSet(Ptr^) := Value;\n\n  if Value <> nil then\n  {$IFNDEF FPC}\n    NullPtr^ := {$IFDEF WIN64}false{$ELSE}0{$ENDIF}  //M.A. NullPtr^ := 0\n  else\n    NullPtr^ := {$IFDEF WIN64}true{$ELSE}1{$ENDIF};  //M.A. NullPtr^ := 1;\n  {$ELSE}\n    NullPtr^ := 0\n  else\n    NullPtr^ := 1;\n  {$ENDIF}\nend;\n{**\n  Sets the designated column with a <code>Variant</code> value.\n  The <code>SetXXX</code> methods are used to Set column values in the\n  current row or the insert row.  The <code>SetXXX</code> methods do not\n  Set the underlying database; instead the <code>SetRow</code> or\n  <code>insertRow</code> methods are called to Set the database.\n\n  @param columnIndex the first column is 1, the second is 2, ...\n  @param x the new column value\n}\nprocedure TZRowAccessor.SetValue(ColumnIndex: Integer; Value: TZVariant);\nbegin\n  case Value.VType of\n    vtNull: SetNull(ColumnIndex);\n    vtBoolean: SetBoolean(ColumnIndex, Value.VBoolean);\n    vtInteger: SetLong(ColumnIndex, Value.VInteger);\n    vtFloat: SetBigDecimal(ColumnIndex, Value.VFloat);\n    vtBytes: SetBytes(ColumnIndex, Value.VBytes);\n    vtString: SetString(ColumnIndex, Value.VString);\n    vtUnicodeString: SetUnicodeString(ColumnIndex, Value.VUnicodeString);\n    vtDateTime: SetTimestamp(ColumnIndex, Value.VDateTime);\n  end;\nend;\n\nend.\n\n"
  },
  {
    "path": "lib/zeosdbo/src/dbc/ZDbcCachedResultSet.pas",
    "content": "{*********************************************************}\n{                                                         }\n{                 Zeos Database Objects                   }\n{            Caching Classes and Interfaces               }\n{                                                         }\n{        Originally written by Sergey Seroukhov           }\n{                                                         }\n{*********************************************************}\n\n{@********************************************************}\n{    Copyright (c) 1999-2012 Zeos Development Group       }\n{                                                         }\n{ License Agreement:                                      }\n{                                                         }\n{ This library is distributed in the hope that it will be }\n{ useful, but WITHOUT ANY WARRANTY; without even the      }\n{ implied warranty of MERCHANTABILITY or FITNESS FOR      }\n{ A PARTICULAR PURPOSE.  See the GNU Lesser General       }\n{ Public License for more details.                        }\n{                                                         }\n{ The source code of the ZEOS Libraries and packages are  }\n{ distributed under the Library GNU General Public        }\n{ License (see the file COPYING / COPYING.ZEOS)           }\n{ with the following  modification:                       }\n{ As a special exception, the copyright holders of this   }\n{ library give you permission to link this library with   }\n{ independent modules to produce an executable,           }\n{ regardless of the license terms of these independent    }\n{ modules, and to copy and distribute the resulting       }\n{ executable under terms of your choice, provided that    }\n{ you also meet, for each linked independent module,      }\n{ the terms and conditions of the license of that module. }\n{ An independent module is a module which is not derived  }\n{ from or based on this library. If you modify this       }\n{ library, you may extend this exception to your version  }\n{ of the library, but you are not obligated to do so.     }\n{ If you do not wish to do so, delete this exception      }\n{ statement from your version.                            }\n{                                                         }\n{                                                         }\n{ The project web site is located on:                     }\n{   http://zeos.firmos.at  (FORUM)                        }\n{   http://sourceforge.net/p/zeoslib/tickets/ (BUGTRACKER)}\n{   svn://svn.code.sf.net/p/zeoslib/code-0/trunk (SVN)    }\n{                                                         }\n{   http://www.sourceforge.net/projects/zeoslib.          }\n{                                                         }\n{                                                         }\n{                                 Zeos Development Group. }\n{********************************************************@}\n\nunit ZDbcCachedResultSet;\n\ninterface\n\n{$I ZDbc.inc}\n\nuses\n  Types, Classes, {$IFDEF MSEgui}mclasses,{$ENDIF} SysUtils, Contnrs,\n  ZClasses, ZDbcIntfs, ZDbcResultSet, ZDbcCache, ZCompatibility;\n\ntype\n  // Forward declarations.\n  IZCachedResultSet = interface;\n\n  {** Resolver to post updates. }\n  IZCachedResolver = interface (IZInterface)\n    ['{546ED716-BB88-468C-8CCE-D7111CF5E1EF}']\n\n    procedure CalculateDefaults(Sender: IZCachedResultSet;\n      RowAccessor: TZRowAccessor);\n    procedure PostUpdates(Sender: IZCachedResultSet; UpdateType: TZRowUpdateType;\n      OldRowAccessor, NewRowAccessor: TZRowAccessor);\n    {BEGIN of PATCH [1185969]: Do tasks after posting updates. ie: Updating AutoInc fields in MySQL }\n    procedure UpdateAutoIncrementFields(Sender: IZCachedResultSet; UpdateType: TZRowUpdateType;\n      OldRowAccessor, NewRowAccessor: TZRowAccessor; Resolver: IZCachedResolver);\n    {END of PATCH [1185969]: Do tasks after posting updates. ie: Updating AutoInc fields in MySQL }\n    procedure RefreshCurrentRow(Sender: IZCachedResultSet;RowAccessor: TZRowAccessor); //FOS+ 07112006\n  end;\n\n  {** Represents a cached result set. }\n  IZCachedResultSet = interface (IZResultSet)\n    ['{BAF24A92-C8CE-4AB4-AEBC-3D4A9BCB0946}']\n\n    function GetResolver: IZCachedResolver;\n    procedure SetResolver(Resolver: IZCachedResolver);\n\n    {BEGIN PATCH [1214009] Calc Defaults in TZUpdateSQL and Added Methods to GET and SET the database Native Resolver\n      will help to implemented feature to Calculate default values in TZUpdateSQL\n      comment: add this properties to get the original Resolver\n      this will be useful whn using TZUpdateSQL //added by fduenas\n    }\n    function GetNativeResolver: IZCachedResolver;\n   {END PATCH [1214009] CalcDefaults in TZUpdateSQL and Added Methods to GET the DB NativeResolver}\n\n    function IsCachedUpdates: Boolean;\n    procedure SetCachedUpdates(Value: Boolean);\n    function IsPendingUpdates: Boolean;\n\n    procedure PostUpdates;\n    procedure CancelUpdates;\n    procedure PostUpdatesCached;\n    procedure DisposeCachedUpdates;\n    procedure RevertRecord;\n    procedure MoveToInitialRow;\n    procedure RefreshRow; // FOS+ 071106\n  end;\n\n  {** Implements cached ResultSet. }\n  TZAbstractCachedResultSet = class (TZAbstractResultSet, IZCachedResultSet)\n  private\n    FCachedUpdates: Boolean;\n    FRowsList: TList;\n    FInitialRowsList: TList;\n    FCurrentRowsList: TList;\n    FSelectedRow: PZRowBuffer;\n    FUpdatedRow: PZRowBuffer;\n    FInsertedRow: PZRowBuffer;\n    FRowAccessor: TZRowAccessor;\n    FNewRowAccessor: TZRowAccessor;\n    FOldRowAccessor: TZRowAccessor;\n    FNextRowIndex: Integer;\n    FResolver: IZCachedResolver;\n    {BEGIN PATCH [1214009] CalcDefaults in TZUpdateSQL and Added Methods to GET the DB NativeResolver}\n    FNativeResolver: IZCachedResolver;\n    {END PATCH [1214009] CalcDefaults in TZUpdateSQL and Added Methods to GET the DB NativeResolver}\n  protected\n    procedure CheckAvailable;\n    procedure CheckUpdatable;\n    procedure Open; override;\n    function GetNextRowIndex: Integer;\n\n    procedure CalculateRowDefaults(RowAccessor: TZRowAccessor); virtual;\n    procedure PostRowUpdates(OldRowAccessor,\n      NewRowAccessor: TZRowAccessor); virtual;\n    function LocateRow(RowsList: TList; RowIndex: Integer): Integer;\n    function AppendRow(Row: PZRowBuffer): PZRowBuffer;\n    procedure PrepareRowForUpdates;\n\n    property CachedUpdates: Boolean read FCachedUpdates write FCachedUpdates;\n    property RowsList: TList read FRowsList write FRowsList;\n    property InitialRowsList: TList read FInitialRowsList\n      write FInitialRowsList;\n    property CurrentRowsList: TList read FCurrentRowsList\n      write FCurrentRowsList;\n    property SelectedRow: PZRowBuffer read FSelectedRow write FSelectedRow;\n    property UpdatedRow: PZRowBuffer read FUpdatedRow write FUpdatedRow;\n    property InsertedRow: PZRowBuffer read FInsertedRow write FInsertedRow;\n    property RowAccessor: TZRowAccessor read FRowAccessor write FRowAccessor;\n    property OldRowAccessor: TZRowAccessor read FOldRowAccessor\n      write FOldRowAccessor;\n    property NewRowAccessor: TZRowAccessor read FNewRowAccessor\n      write FNewRowAccessor;\n    property NextRowIndex: Integer read FNextRowIndex write FNextRowIndex;\n    property Resolver: IZCachedResolver read FResolver write FResolver;\n    {BEGIN PATCH [1214009] CalcDefaults in TZUpdateSQL and Added Methods to GET the DB NativeResolver}\n    property NativeResolver: IZCachedResolver read FNativeResolver;\n    {END PATCH [1214009] CalcDefaults in TZUpdateSQL and Added Methods to GET the DB NativeResolver}\n  public\n    constructor CreateWithStatement(SQL: string; Statement: IZStatement;\n      ConSettings: PZConSettings);\n    constructor CreateWithColumns(ColumnsInfo: TObjectList; SQL: string;\n      ConSettings: PZConSettings);\n    destructor Destroy; override;\n\n    procedure Close; override;\n\n    //======================================================================\n    // Methods for accessing results by column index\n    //======================================================================\n\n    function IsNull(ColumnIndex: Integer): Boolean; override;\n    function GetPChar(ColumnIndex: Integer): PChar; override;\n    function GetString(ColumnIndex: Integer): String; override;\n    function GetUnicodeString(ColumnIndex: Integer): Widestring; override;\n    function GetBoolean(ColumnIndex: Integer): Boolean; override;\n    function GetByte(ColumnIndex: Integer): Byte; override;\n    function GetShort(ColumnIndex: Integer): SmallInt; override;\n    function GetInt(ColumnIndex: Integer): Integer; override;\n    function GetLong(ColumnIndex: Integer): Int64; override;\n    function GetFloat(ColumnIndex: Integer): Single; override;\n    function GetDouble(ColumnIndex: Integer): Double; override;\n    function GetBigDecimal(ColumnIndex: Integer): Extended; override;\n    function GetBytes(ColumnIndex: Integer): TByteDynArray; override;\n    function GetDate(ColumnIndex: Integer): TDateTime; override;\n    function GetTime(ColumnIndex: Integer): TDateTime; override;\n    function GetTimestamp(ColumnIndex: Integer): TDateTime; override;\n    function GetBlob(ColumnIndex: Integer): IZBlob; override;\n    function GetDefaultExpression(ColumnIndex: Integer): string; override;\n\n    //---------------------------------------------------------------------\n    // Traversal/Positioning\n    //---------------------------------------------------------------------\n\n    function MoveAbsolute(Row: Integer): Boolean; override;\n\n    //---------------------------------------------------------------------\n    // Updates\n    //---------------------------------------------------------------------\n\n    function RowUpdated: Boolean; override;\n    function RowInserted: Boolean; override;\n    function RowDeleted: Boolean; override;\n\n    procedure UpdateNull(ColumnIndex: Integer); override;\n    procedure UpdateBoolean(ColumnIndex: Integer; Value: Boolean); override;\n    procedure UpdateByte(ColumnIndex: Integer; Value: ShortInt); override;\n    procedure UpdateShort(ColumnIndex: Integer; Value: SmallInt); override;\n    procedure UpdateInt(ColumnIndex: Integer; Value: Integer); override;\n    procedure UpdateLong(ColumnIndex: Integer; Value: Int64); override;\n    procedure UpdateFloat(ColumnIndex: Integer; Value: Single); override;\n    procedure UpdateDouble(ColumnIndex: Integer; Value: Double); override;\n    procedure UpdateBigDecimal(ColumnIndex: Integer; Value: Extended); override;\n    procedure UpdatePChar(ColumnIndex: Integer; Value: PChar); override;\n    procedure UpdateString(ColumnIndex: Integer; const Value: String); override;\n    procedure UpdateUnicodeString(ColumnIndex: Integer; const Value: WideString); override;\n    procedure UpdateBytes(ColumnIndex: Integer; const Value: TByteDynArray); override;\n    procedure UpdateDate(ColumnIndex: Integer; Value: TDateTime); override;\n    procedure UpdateTime(ColumnIndex: Integer; Value: TDateTime); override;\n    procedure UpdateTimestamp(ColumnIndex: Integer; Value: TDateTime); override;\n    procedure UpdateAsciiStream(ColumnIndex: Integer; Value: TStream); override;\n    procedure UpdateUnicodeStream(ColumnIndex: Integer; Value: TStream); override;\n    procedure UpdateBinaryStream(ColumnIndex: Integer; Value: TStream); override;\n    procedure UpdateDefaultExpression(ColumnIndex: Integer; const Value: string); override;\n\n    procedure InsertRow; override;\n    procedure UpdateRow; override;\n    procedure DeleteRow; override;\n    procedure CancelRowUpdates; override;\n    procedure RefreshRow;override;// FOS+ 071106\n\n\n    procedure MoveToInsertRow; override;\n    procedure MoveToCurrentRow; override;\n\n    function CompareRows(Row1, Row2: Integer; const ColumnIndices: TIntegerDynArray;\n      const ColumnDirs: TBooleanDynArray): Integer; override;\n\n    //---------------------------------------------------------------------\n    // Cached Updates\n    //---------------------------------------------------------------------\n\n    function GetResolver: IZCachedResolver;\n    procedure SetResolver(Resolver: IZCachedResolver);\n    {BEGIN PATCH [1214009] CalcDefaults in TZUpdateSQL and Added Methods to GET the DB NativeResolver}\n    function GetNativeResolver: IZCachedResolver;\n    {END PATCH [1214009] CalcDefaults in TZUpdateSQL and Added Methods to GET the DB NativeResolver}\n    function IsCachedUpdates: Boolean;\n    procedure SetCachedUpdates(Value: Boolean);\n    function IsPendingUpdates: Boolean; virtual;\n\n    procedure PostUpdates; virtual;\n    procedure CancelUpdates; virtual;\n    procedure RevertRecord; virtual;\n    procedure MoveToInitialRow; virtual;\n    procedure PostUpdatesCached; virtual;\n    procedure DisposeCachedUpdates; virtual;\n  end;\n\n  {**\n    Implements Abstract cached ResultSet. This class should be extended\n    with database specific logic to form SQL data manipulation statements.\n  }\n  TZCachedResultSet = class(TZAbstractCachedResultSet)\n  private\n    FResultSet: IZResultSet;\n  protected\n    procedure Open; override;\n    function Fetch: Boolean; virtual;\n    procedure FetchAll; virtual;\n\n    property ResultSet: IZResultSet read FResultSet write FResultSet;\n  public\n    constructor Create(ResultSet: IZResultSet; SQL: string;\n      Resolver: IZCachedResolver; ConSettings: PZConSettings);\n    destructor Destroy; override;\n\n    procedure Close; override;\n    function GetMetaData: IZResultSetMetaData; override;\n\n    function IsAfterLast: Boolean; override;\n    function IsLast: Boolean; override;\n    procedure AfterLast; override;\n    function Last: Boolean; override;\n    function MoveAbsolute(Row: Integer): Boolean; override;\n  end;\n\nimplementation\n\nuses ZMessages, ZDbcResultSetMetadata, ZDbcGenericResolver, ZDbcUtils, ZEncoding;\n\n{ TZAbstractCachedResultSet }\n\n{**\n  Creates this object and assignes the main properties.\n  @param Statement an SQL statement object.\n  @param SQL an SQL query.\n}\nconstructor TZAbstractCachedResultSet.CreateWithStatement(SQL: string;\n  Statement: IZStatement; ConSettings: PZConSettings);\nbegin\n  inherited Create(Statement, SQL, nil, ConSettings);\n  FCachedUpdates := False;\nend;\n\n{**\n  Creates this object and assignes the main properties.\n  @param SQL an SQL query.\n  @param ColumnsInfo a columns info for cached rows.\n}\nconstructor TZAbstractCachedResultSet.CreateWithColumns(\n  ColumnsInfo: TObjectList; SQL: string; ConSettings: PZConSettings);\nbegin\n  inherited Create(nil, SQL, nil, ConSettings);\n\n  CopyColumnsInfo(ColumnsInfo, Self.ColumnsInfo);\n  FCachedUpdates := False;\n  Open;\nend;\n\n{**\n  Destroys this object and cleanups the memory.\n}\ndestructor TZAbstractCachedResultSet.Destroy;\nbegin\n  FResolver := nil;\n  {BEGIN PATCH [1214009] CalcDefaults in TZUpdateSQL and Added Methods to GET the DB NativeResolver}\n  FNativeResolver := nil;\n  {END PATCH [1214009] CalcDefaults in TZUpdateSQL and Added Methods to GET the DB NativeResolver}\n  inherited Destroy;\nend;\n\n{**\n  Checks for availability of the cached buffer.\n}\nprocedure TZAbstractCachedResultSet.CheckAvailable;\nbegin\n  CheckClosed;\n  if (FRowAccessor = nil) or (FRowAccessor.RowBuffer = nil) then\n    raise EZSQLException.Create(SRowDataIsNotAvailable);\nend;\n\n{**\n  Checks is the cached buffer updatable.\n}\nprocedure TZAbstractCachedResultSet.CheckUpdatable;\nbegin\n  CheckAvailable;\n  if ResultSetConcurrency <> rcUpdatable then\n    RaiseReadOnlyException;\nend;\n\n{**\n  Generates the next row index value.\n  @return the new generated row index.\n}\nfunction TZAbstractCachedResultSet.GetNextRowIndex: Integer;\nbegin\n  Result := FNextRowIndex;\n  Inc(FNextRowIndex);\nend;\n\n{**\n  Finds a row with specified index among list of rows.\n  @param RowsList a list of rows.\n  @param Index a row index.\n  @return a found row buffer of <code>null</code> otherwise.\n}\nfunction TZAbstractCachedResultSet.LocateRow(RowsList: TList;\n  RowIndex: Integer): Integer;\nvar\n  I: Integer;\nbegin\n  Result := -1;\n  for I := 0 to RowsList.Count - 1 do\n  begin\n    if PZRowBuffer(RowsList[I]).Index = RowIndex then\n    begin\n      Result := I;\n      Break;\n    end;\n  end;\nend;\n\n{**\n  Appends a row to the list of rows if such row is not exist.\n  @param Row a row buffer.\n  @return an appended row buffer.\n}\nfunction TZAbstractCachedResultSet.AppendRow(Row: PZRowBuffer): PZRowBuffer;\nbegin\n  if LocateRow(FInitialRowsList, Row.Index) < 0 then\n  begin\n    FRowAccessor.AllocBuffer(Result);\n    FRowAccessor.CopyBuffer(Row, Result);\n    FInitialRowsList.Add(Result);\n    FCurrentRowsList.Add(Row);\n  end\n  else\n    Result := nil;\nend;\n\n{**\n  Prepares the current selected row for updates.\n}\nprocedure TZAbstractCachedResultSet.PrepareRowForUpdates;\nbegin\n  if (RowAccessor.RowBuffer = FSelectedRow) and (FSelectedRow <> FUpdatedRow) then\n  begin\n    FSelectedRow := FUpdatedRow;\n    RowAccessor.RowBuffer := FSelectedRow;\n    RowAccessor.CloneFrom(PZRowBuffer(FRowsList[RowNo - 1]));\n  end;\nend;\n\n{**\n  Calculates column default values..\n  @param RowAccessor a row accessor which contains new column values.\n}\nprocedure TZAbstractCachedResultSet.CalculateRowDefaults(\n  RowAccessor: TZRowAccessor);\nbegin\n{$IFNDEF DISABLE_CHECKING}\n  if Resolver = nil then\n    raise EZSQLException.Create(SResolverIsNotSpecified);\n{$ENDIF}\n  Resolver.CalculateDefaults(Self, RowAccessor);\nend;\n\n{**\n  Post changes to database server.\n  @param OldRowAccessor a row accessor which contains old column values.\n  @param NewRowAccessor a row accessor which contains new or updated\n    column values.\n}\nprocedure TZAbstractCachedResultSet.PostRowUpdates(OldRowAccessor,\n  NewRowAccessor: TZRowAccessor);\nbegin\n{$IFNDEF DISABLE_CHECKING}\n  if Resolver = nil then\n    raise EZSQLException.Create(SResolverIsNotSpecified);\n{$ENDIF}\n  Resolver.PostUpdates(Self, NewRowAccessor.RowBuffer.UpdateType,\n    OldRowAccessor, NewRowAccessor);\nend;\n\n{**\n  Gets a cached updates resolver object.\n  @return a cached updates resolver object.\n}\nfunction TZAbstractCachedResultSet.GetResolver: IZCachedResolver;\nbegin\n  Result := FResolver;\nend;\n\n{**\n  Sets a new cached updates resolver object.\n  @param Resolver a cached updates resolver object.\n}\nprocedure TZAbstractCachedResultSet.SetResolver(Resolver: IZCachedResolver);\nbegin\n  FResolver := Resolver;\n{BEGIN PATCH [1214009] CalcDefaults in TZUpdateSQL and Added Methods to GET the DB NativeResolver}\n  if FNativeResolver = nil then\n     FNativeResolver := Resolver;\n{END PATCH [1214009] CalcDefaults in TZUpdateSQL and Added Methods to GET the DB NativeResolver}\nend;\n{BEGIN PATCH [1214009] CalcDefaults in TZUpdateSQL and Added Methods to GET the DB NativeResolver}\n{**\n  Gets a Native cached updates resolver object.\n  @return a Native cached updates resolver object.\n}\nfunction TZAbstractCachedResultSet.GetNativeResolver: IZCachedResolver;\nbegin\n  Result := FNativeResolver;\nend;\n{END PATCH [1214009] CalcDefaults in TZUpdateSQL and Added Methods to GET the DB NativeResolver}\n\n{**\n  Checks is the cached updates mode turned on.\n  @return <code>True</code> if the cached updates mode turned on.\n}\nfunction TZAbstractCachedResultSet.IsCachedUpdates: Boolean;\nbegin\n  Result := FCachedUpdates;\nend;\n\n{**\n  Switched the cached updates mode.\n  @param Value boolean flag which turns on/off the cached updates mode.\n}\nprocedure TZAbstractCachedResultSet.SetCachedUpdates(Value: Boolean);\nbegin\n  if FCachedUpdates <> Value then\n  begin\n    FCachedUpdates := Value;\n    if not FCachedUpdates then\n      PostUpdates;\n  end;\nend;\n\n{**\n  Checks is cached updates pending.\n  @return <code>True</code> if the cached updates pending.\n}\nfunction TZAbstractCachedResultSet.IsPendingUpdates: Boolean;\nbegin\n  Result := FInitialRowsList.Count > 0;\nend;\n\n{**\n  Moves to the current row with initial column values.\n}\nprocedure TZAbstractCachedResultSet.MoveToInitialRow;\nvar\n  Index: Integer;\nbegin\n  CheckClosed;\n  if (RowNo >= 1) and (RowNo <= LastRowNo) and (FSelectedRow <> nil) then\n  begin\n    Index := LocateRow(FInitialRowsList, FSelectedRow.Index);\n    if Index >= 0 then\n    begin\n      FSelectedRow := FInitialRowsList[Index];\n      FRowAccessor.RowBuffer := FSelectedRow;\n    end;\n  end\n  else\n    FRowAccessor.RowBuffer := nil;\nend;\n\n{**\n  Posts all saved updates to the server.\n}\nprocedure TZAbstractCachedResultSet.PostUpdates;\nbegin\n  CheckClosed;\n  if FInitialRowsList.Count > 0 then\n  begin\n    while FInitialRowsList.Count > 0 do\n    begin\n      OldRowAccessor.RowBuffer := PZRowBuffer(FInitialRowsList[0]);\n      NewRowAccessor.RowBuffer := PZRowBuffer(FCurrentRowsList[0]);\n\n      { Updates default field values. }\n      if NewRowAccessor.RowBuffer.UpdateType = utInserted then\n        CalculateRowDefaults(NewRowAccessor);\n\n      { Posts row updates and processes the exceptions. }\n      PostRowUpdates(OldRowAccessor, NewRowAccessor);\n\n      { If post was Ok - update the row update type. }\n      if NewRowAccessor.RowBuffer.UpdateType <> utDeleted then\n      begin\n        NewRowAccessor.RowBuffer.UpdateType := utUnmodified;\n        if (FSelectedRow <> nil)\n          and (FSelectedRow.Index = NewRowAccessor.RowBuffer.Index) then\n          FSelectedRow.UpdateType := utUnmodified;\n      end;\n\n      { Removes cached rows. }\n      OldRowAccessor.Dispose;\n      FInitialRowsList.Delete(0);\n      FCurrentRowsList.Delete(0);\n    end;\n  end;\nend;\n\n{**\n  Posts all saved updates to the server but keeps them cached.\n}\nprocedure TZAbstractCachedResultSet.PostUpdatesCached;\nvar\n  i: Integer;\nbegin\n  CheckClosed;\n  if FInitialRowsList.Count > 0 then\n  begin\n    i := 0;\n    while i < FInitialRowsList.Count do\n    begin\n      OldRowAccessor.RowBuffer := PZRowBuffer(FInitialRowsList[i]);\n      NewRowAccessor.RowBuffer := PZRowBuffer(FCurrentRowsList[i]);\n      Inc(i);\n\n      { Updates default field values. }\n      if NewRowAccessor.RowBuffer.UpdateType = utInserted then\n        CalculateRowDefaults(NewRowAccessor);\n\n      { Posts row updates. }\n      PostRowUpdates(OldRowAccessor, NewRowAccessor);\n    end;\n  end;\nend;\n\n{**\n  Frees the updates and marks records as unmodified. Complements\n  PostUpdatesCached.\n}\nprocedure TZAbstractCachedResultSet.DisposeCachedUpdates;\nbegin\n  while FInitialRowsList.Count > 0 do\n  begin\n    OldRowAccessor.RowBuffer := PZRowBuffer(FInitialRowsList[0]);\n    NewRowAccessor.RowBuffer := PZRowBuffer(FCurrentRowsList[0]);\n\n    if NewRowAccessor.RowBuffer.UpdateType <> utDeleted then\n    begin\n      NewRowAccessor.RowBuffer.UpdateType := utUnmodified;\n      if (FSelectedRow <> nil)\n        and (FSelectedRow.Index = NewRowAccessor.RowBuffer.Index) then\n          FSelectedRow.UpdateType := utUnmodified;\n    end;\n\n    { Remove cached rows. }\n    OldRowAccessor.Dispose;\n    FInitialRowsList.Delete(0);\n    FCurrentRowsList.Delete(0);\n  end;\nend;\n\n{**\n  Cancels updates for all rows.\n}\nprocedure TZAbstractCachedResultSet.CancelUpdates;\nvar\n  InitialRow, CurrentRow: PZRowBuffer;\nbegin\n  CheckClosed;\n  while FInitialRowsList.Count > 0 do\n  begin\n    InitialRow := PZRowBuffer(FInitialRowsList[0]);\n    CurrentRow := PZRowBuffer(FCurrentRowsList[0]);\n\n    if CurrentRow.UpdateType = utInserted then\n      InitialRow.UpdateType := utDeleted;\n\n    FRowAccessor.CopyBuffer(InitialRow, CurrentRow);\n    if (FSelectedRow = FUpdatedRow)\n      and (FSelectedRow.Index = InitialRow.Index) then\n      FRowAccessor.CopyBuffer(InitialRow, FSelectedRow);\n\n    FRowAccessor.DisposeBuffer(InitialRow);\n    FInitialRowsList.Delete(0);\n    FCurrentRowsList.Delete(0);\n  end;\nend;\n\n{**\n  Cancels updates for the current row.\n}\nprocedure TZAbstractCachedResultSet.RefreshRow;\nbegin\n  if Resolver = nil then\n    raise EZSQLException.Create(SResolverIsNotSpecified);\n  Resolver.RefreshCurrentRow(Self,RowAccessor);\nend;\n\nprocedure TZAbstractCachedResultSet.RevertRecord;\nvar\n  Index: Integer;\n  InitialRow, CurrentRow: PZRowBuffer;\nbegin\n  CheckClosed;\n  if (RowNo >= 1) and (RowNo <= LastRowNo) then\n  begin\n    Index := LocateRow(FInitialRowsList, FSelectedRow.Index);\n    if Index >= 0 then\n    begin\n      InitialRow := PZRowBuffer(FInitialRowsList[Index]);\n      CurrentRow := PZRowBuffer(FRowsList[RowNo - 1]);\n\n      if CurrentRow.UpdateType = utInserted then\n        InitialRow.UpdateType := utDeleted;\n      FRowAccessor.CopyBuffer(InitialRow, CurrentRow);\n      if (FSelectedRow = FUpdatedRow) then\n        FRowAccessor.CopyBuffer(InitialRow, FSelectedRow);\n\n      FRowAccessor.DisposeBuffer(InitialRow);\n      FInitialRowsList.Delete(Index);\n      FCurrentRowsList.Delete(Index);\n    end;\n  end;\nend;\n\n{**\n  Opens this recordset.\n}\nprocedure TZAbstractCachedResultSet.Open;\nbegin\n  if not Closed then\n    raise EZSQLException.Create(SResultsetIsAlreadyOpened);\n\n  FRowsList := TList.Create;\n  FInitialRowsList := TList.Create;\n  FCurrentRowsList := TList.Create;\n\n  FRowAccessor := TZRowAccessor.Create(ColumnsInfo, ConSettings);\n  FOldRowAccessor := TZRowAccessor.Create(ColumnsInfo, ConSettings);\n  FNewRowAccessor := TZRowAccessor.Create(ColumnsInfo, ConSettings);\n\n  FRowAccessor.AllocBuffer(FUpdatedRow);\n  FRowAccessor.AllocBuffer(FInsertedRow);\n  FSelectedRow := nil;\n\n  FNextRowIndex := 0;\n\n  if (Resolver = nil) and (GetConcurrency = rcUpdatable) then\n    Resolver := TZGenericCachedResolver.Create(GetStatement, GetMetadata);\n\n  inherited Open;\nend;\n\n{**\n  Releases this <code>ResultSet</code> object's database and\n  JDBC resources immediately instead of waiting for\n  this to happen when it is automatically closed.\n\n  <P><B>Note:</B> A <code>ResultSet</code> object\n  is automatically closed by the\n  <code>Statement</code> object that generated it when\n  that <code>Statement</code> object is closed,\n  re-executed, or is used to retrieve the next result from a\n  sequence of multiple results. A <code>ResultSet</code> object\n  is also automatically closed when it is garbage collected.\n}\nprocedure TZAbstractCachedResultSet.Close;\nvar\n  I: Integer;\nbegin\n  inherited Close;\n\n  if Assigned(FRowAccessor) then\n  begin\n    for I := 0 to FRowsList.Count - 1 do\n      FRowAccessor.DisposeBuffer(PZRowBuffer(FRowsList[I]));\n    for I := 0 to FInitialRowsList.Count - 1 do\n      FRowAccessor.DisposeBuffer(PZRowBuffer(FInitialRowsList[I]));\n\n    FRowAccessor.DisposeBuffer(FUpdatedRow);\n    FUpdatedRow := nil;\n    FRowAccessor.DisposeBuffer(FInsertedRow);\n    FInsertedRow := nil;\n    FSelectedRow := nil;\n\n    FreeAndNil(FRowsList);\n    FreeAndNil(FInitialRowsList);\n    FreeAndNil(FCurrentRowsList);\n\n    FreeAndNil(FRowAccessor);\n    FreeAndNil(FOldRowAccessor);\n    FreeAndNil(FNewRowAccessor);\n  end;\nend;\n\n//======================================================================\n// Methods for accessing results by column index\n//======================================================================\n\n{**\n  Indicates if the value of the designated column in the current row\n  of this <code>ResultSet</code> object is Null.\n\n  @param columnIndex the first column is 1, the second is 2, ...\n  @return if the value is SQL <code>NULL</code>, the\n    value returned is <code>true</code>. <code>false</code> otherwise.\n}\nfunction TZAbstractCachedResultSet.IsNull(ColumnIndex: Integer): Boolean;\nbegin\n{$IFNDEF DISABLE_CHECKING}\n  CheckAvailable;\n{$ENDIF}\n  Result := FRowAccessor.IsNull(ColumnIndex);\nend;\n\n{**\n  Gets the value of the designated column in the current row\n  of this <code>ResultSet</code> object as\n  a <code>PAnsiChar</code> in the Delphi programming language.\n\n  @param columnIndex the first column is 1, the second is 2, ...\n  @return the column value; if the value is SQL <code>NULL</code>, the\n    value returned is <code>null</code>\n}\nfunction TZAbstractCachedResultSet.GetPChar(ColumnIndex: Integer): PChar;\nbegin\n{$IFNDEF DISABLE_CHECKING}\n  CheckAvailable;\n{$ENDIF}\n  Result := FRowAccessor.GetPChar(ColumnIndex, LastWasNull);\nend;\n\n{**\n  Gets the value of the designated column in the current row\n  of this <code>ResultSet</code> object as\n  a <code>String</code> in the Java programming language.\n\n  @param columnIndex the first column is 1, the second is 2, ...\n  @return the column value; if the value is SQL <code>NULL</code>, the\n    value returned is <code>null</code>\n}\nfunction TZAbstractCachedResultSet.GetString(ColumnIndex: Integer): String;\nbegin\n{$IFNDEF DISABLE_CHECKING}\n  CheckAvailable;\n{$ENDIF}\n  Result := FRowAccessor.GetString(ColumnIndex, LastWasNull);\nend;\n\n{**\n  Gets the value of the designated column in the current row\n  of this <code>ResultSet</code> object as\n  a <code>Widestring</code> in the Java programming language.\n\n  @param columnIndex the first column is 1, the second is 2, ...\n  @return the column value; if the value is SQL <code>NULL</code>, the\n    value returned is <code>null</code>\n}\nfunction TZAbstractCachedResultSet.GetUnicodeString(ColumnIndex: Integer): Widestring;\nbegin\n{$IFNDEF DISABLE_CHECKING}\n  CheckAvailable;\n{$ENDIF}\n  Result := FRowAccessor.GetUnicodeString(ColumnIndex, LastWasNull);\nend;\n\n{**\n  Gets the value of the designated column in the current row\n  of this <code>ResultSet</code> object as\n  a <code>boolean</code> in the Java programming language.\n\n  @param columnIndex the first column is 1, the second is 2, ...\n  @return the column value; if the value is SQL <code>NULL</code>, the\n    value returned is <code>false</code>\n}\nfunction TZAbstractCachedResultSet.GetBoolean(ColumnIndex: Integer): Boolean;\nbegin\n{$IFNDEF DISABLE_CHECKING}\n  CheckAvailable;\n{$ENDIF}\n  Result := FRowAccessor.GetBoolean(ColumnIndex, LastWasNull);\nend;\n\n{**\n  Gets the value of the designated column in the current row\n  of this <code>ResultSet</code> object as\n  a <code>byte</code> in the Java programming language.\n\n  @param columnIndex the first column is 1, the second is 2, ...\n  @return the column value; if the value is SQL <code>NULL</code>, the\n    value returned is <code>0</code>\n}\nfunction TZAbstractCachedResultSet.GetByte(ColumnIndex: Integer): Byte;\nbegin\n{$IFNDEF DISABLE_CHECKING}\n  CheckAvailable;\n{$ENDIF}\n  Result := FRowAccessor.GetByte(ColumnIndex, LastWasNull);\nend;\n\n{**\n  Gets the value of the designated column in the current row\n  of this <code>ResultSet</code> object as\n  a <code>short</code> in the Java programming language.\n\n  @param columnIndex the first column is 1, the second is 2, ...\n  @return the column value; if the value is SQL <code>NULL</code>, the\n    value returned is <code>0</code>\n}\nfunction TZAbstractCachedResultSet.GetShort(ColumnIndex: Integer): SmallInt;\nbegin\n{$IFNDEF DISABLE_CHECKING}\n  CheckAvailable;\n{$ENDIF}\n  Result := FRowAccessor.GetShort(ColumnIndex, LastWasNull);\nend;\n\n{**\n  Gets the value of the designated column in the current row\n  of this <code>ResultSet</code> object as\n  an <code>int</code> in the Java programming language.\n\n  @param columnIndex the first column is 1, the second is 2, ...\n  @return the column value; if the value is SQL <code>NULL</code>, the\n    value returned is <code>0</code>\n}\nfunction TZAbstractCachedResultSet.GetInt(ColumnIndex: Integer): Integer;\nbegin\n{$IFNDEF DISABLE_CHECKING}\n  CheckAvailable;\n{$ENDIF}\n  Result := FRowAccessor.GetInt(ColumnIndex, LastWasNull);\nend;\n\n{**\n  Gets the value of the designated column in the current row\n  of this <code>ResultSet</code> object as\n  a <code>long</code> in the Java programming language.\n\n  @param columnIndex the first column is 1, the second is 2, ...\n  @return the column value; if the value is SQL <code>NULL</code>, the\n    value returned is <code>0</code>\n}\nfunction TZAbstractCachedResultSet.GetLong(ColumnIndex: Integer): Int64;\nbegin\n{$IFNDEF DISABLE_CHECKING}\n  CheckAvailable;\n{$ENDIF}\n  Result := FRowAccessor.GetLong(ColumnIndex, LastWasNull);\nend;\n\n{**\n  Gets the value of the designated column in the current row\n  of this <code>ResultSet</code> object as\n  a <code>float</code> in the Java programming language.\n\n  @param columnIndex the first column is 1, the second is 2, ...\n  @return the column value; if the value is SQL <code>NULL</code>, the\n    value returned is <code>0</code>\n}\nfunction TZAbstractCachedResultSet.GetFloat(ColumnIndex: Integer): Single;\nbegin\n{$IFNDEF DISABLE_CHECKING}\n  CheckAvailable;\n{$ENDIF}\n  Result := FRowAccessor.GetFloat(ColumnIndex, LastWasNull);\nend;\n\n{**\n  Gets the value of the designated column in the current row\n  of this <code>ResultSet</code> object as\n  a <code>double</code> in the Java programming language.\n\n  @param columnIndex the first column is 1, the second is 2, ...\n  @return the column value; if the value is SQL <code>NULL</code>, the\n    value returned is <code>0</code>\n}\nfunction TZAbstractCachedResultSet.GetDouble(ColumnIndex: Integer): Double;\nbegin\n{$IFNDEF DISABLE_CHECKING}\n  CheckAvailable;\n{$ENDIF}\n  Result := FRowAccessor.GetDouble(ColumnIndex, LastWasNull);\nend;\n\n{**\n  Gets the value of the designated column in the current row\n  of this <code>ResultSet</code> object as\n  a <code>java.sql.BigDecimal</code> in the Java programming language.\n\n  @param columnIndex the first column is 1, the second is 2, ...\n  @param scale the number of digits to the right of the decimal point\n  @return the column value; if the value is SQL <code>NULL</code>, the\n    value returned is <code>null</code>\n}\nfunction TZAbstractCachedResultSet.GetBigDecimal(ColumnIndex: Integer): Extended;\nbegin\n{$IFNDEF DISABLE_CHECKING}\n  CheckAvailable;\n{$ENDIF}\n  Result := FRowAccessor.GetBigDecimal(ColumnIndex, LastWasNull);\nend;\n\n{**\n  Gets the value of the designated column in the current row\n  of this <code>ResultSet</code> object as\n  a <code>byte</code> array in the Java programming language.\n  The bytes represent the raw values returned by the driver.\n\n  @param columnIndex the first column is 1, the second is 2, ...\n  @return the column value; if the value is SQL <code>NULL</code>, the\n    value returned is <code>null</code>\n}\nfunction TZAbstractCachedResultSet.GetBytes(ColumnIndex: Integer): TByteDynArray;\nbegin\n{$IFNDEF DISABLE_CHECKING}\n  CheckAvailable;\n{$ENDIF}\n  Result := FRowAccessor.GetBytes(ColumnIndex, LastWasNull);\nend;\n\n{**\n  Gets the value of the designated column in the current row\n  of this <code>ResultSet</code> object as\n  a <code>java.sql.Date</code> object in the Java programming language.\n\n  @param columnIndex the first column is 1, the second is 2, ...\n  @return the column value; if the value is SQL <code>NULL</code>, the\n    value returned is <code>null</code>\n}\nfunction TZAbstractCachedResultSet.GetDate(ColumnIndex: Integer): TDateTime;\nbegin\n{$IFNDEF DISABLE_CHECKING}\n  CheckAvailable;\n{$ENDIF}\n  Result := FRowAccessor.GetDate(ColumnIndex, LastWasNull);\nend;\n\n{**\n  Gets the value of the designated column in the current row\n  of this <code>ResultSet</code> object as\n  a <code>java.sql.Time</code> object in the Java programming language.\n\n  @param columnIndex the first column is 1, the second is 2, ...\n  @return the column value; if the value is SQL <code>NULL</code>, the\n    value returned is <code>null</code>\n}\nfunction TZAbstractCachedResultSet.GetTime(ColumnIndex: Integer): TDateTime;\nbegin\n{$IFNDEF DISABLE_CHECKING}\n  CheckAvailable;\n{$ENDIF}\n  Result := FRowAccessor.GetTime(ColumnIndex, LastWasNull);\nend;\n\n{**\n  Gets the value of the designated column in the current row\n  of this <code>ResultSet</code> object as\n  a <code>java.sql.Timestamp</code> object in the Java programming language.\n\n  @param columnIndex the first column is 1, the second is 2, ...\n  @return the column value; if the value is SQL <code>NULL</code>, the\n  value returned is <code>null</code>\n  @exception SQLException if a database access error occurs\n}\nfunction TZAbstractCachedResultSet.GetTimestamp(ColumnIndex: Integer): TDateTime;\nbegin\n{$IFNDEF DISABLE_CHECKING}\n  CheckAvailable;\n{$ENDIF}\n  Result := FRowAccessor.GetTimestamp(ColumnIndex, LastWasNull);\nend;\n\n{**\n  Returns the value of the designated column in the current row\n  of this <code>ResultSet</code> object as a <code>Blob</code> object\n  in the Java programming language.\n\n  @param ColumnIndex the first column is 1, the second is 2, ...\n  @return a <code>Blob</code> object representing the SQL <code>BLOB</code> value in\n    the specified column\n}\nfunction TZAbstractCachedResultSet.GetBlob(ColumnIndex: Integer): IZBlob;\nbegin\n{$IFNDEF DISABLE_CHECKING}\n  CheckAvailable;\n{$ENDIF}\n  Result := FRowAccessor.GetBlob(ColumnIndex, LastWasNull);\nend;\n\n{**\n  Gets the DefaultExpression value of the designated column in the current row\n  of this <code>ResultSet</code> object as\n  a <code>String</code>.\n\n  @param columnIndex the first column is 1, the second is 2, ...\n  @return the DefaultExpression value\n}\nfunction TZAbstractCachedResultSet.GetDefaultExpression(ColumnIndex: Integer): string;\nbegin\n{$IFNDEF DISABLE_CHECKING}\n  CheckAvailable;\n{$ENDIF}\n  Result := FRowAccessor.GetColumnDefaultExpression(ColumnIndex);\nend;\n\n//---------------------------------------------------------------------\n// Updates\n//---------------------------------------------------------------------\n\n{**\n  Gives a nullable column a null value.\n\n  The <code>updateXXX</code> methods are used to update column values in the\n  current row or the insert row.  The <code>updateXXX</code> methods do not\n  update the underlying database; instead the <code>updateRow</code>\n  or <code>insertRow</code> methods are called to update the database.\n\n  @param columnIndex the first column is 1, the second is 2, ...\n}\nprocedure TZAbstractCachedResultSet.UpdateNull(ColumnIndex: Integer);\nbegin\n{$IFNDEF DISABLE_CHECKING}\n  CheckUpdatable;\n{$ENDIF}\n  PrepareRowForUpdates;\n  FRowAccessor.SetNull(ColumnIndex);\nend;\n\n{**\n  Updates the designated column with a <code>boolean</code> value.\n  The <code>updateXXX</code> methods are used to update column values in the\n  current row or the insert row.  The <code>updateXXX</code> methods do not\n  update the underlying database; instead the <code>updateRow</code> or\n  <code>insertRow</code> methods are called to update the database.\n\n  @param columnIndex the first column is 1, the second is 2, ...\n  @param x the new column value\n}\nprocedure TZAbstractCachedResultSet.UpdateBoolean(ColumnIndex: Integer;\n  Value: Boolean);\nbegin\n{$IFNDEF DISABLE_CHECKING}\n  CheckUpdatable;\n{$ENDIF}\n  PrepareRowForUpdates;\n  FRowAccessor.SetBoolean(ColumnIndex, Value);\nend;\n\n{**\n  Updates the designated column with a <code>byte</code> value.\n  The <code>updateXXX</code> methods are used to update column values in the\n  current row or the insert row.  The <code>updateXXX</code> methods do not\n  update the underlying database; instead the <code>updateRow</code> or\n  <code>insertRow</code> methods are called to update the database.\n\n  @param columnIndex the first column is 1, the second is 2, ...\n  @param x the new column value\n}\nprocedure TZAbstractCachedResultSet.UpdateByte(ColumnIndex: Integer;\n  Value: ShortInt);\nbegin\n{$IFNDEF DISABLE_CHECKING}\n  CheckUpdatable;\n{$ENDIF}\n  PrepareRowForUpdates;\n  FRowAccessor.SetByte(ColumnIndex, Value);\nend;\n\n{**\n  Updates the designated column with a <code>short</code> value.\n  The <code>updateXXX</code> methods are used to update column values in the\n  current row or the insert row.  The <code>updateXXX</code> methods do not\n  update the underlying database; instead the <code>updateRow</code> or\n  <code>insertRow</code> methods are called to update the database.\n\n  @param columnIndex the first column is 1, the second is 2, ...\n  @param x the new column value\n}\nprocedure TZAbstractCachedResultSet.UpdateShort(ColumnIndex: Integer;\n  Value: SmallInt);\nbegin\n{$IFNDEF DISABLE_CHECKING}\n  CheckUpdatable;\n{$ENDIF}\n  PrepareRowForUpdates;\n  FRowAccessor.SetShort(ColumnIndex, Value);\nend;\n\n{**\n  Updates the designated column with an <code>int</code> value.\n  The <code>updateXXX</code> methods are used to update column values in the\n  current row or the insert row.  The <code>updateXXX</code> methods do not\n  update the underlying database; instead the <code>updateRow</code> or\n  <code>insertRow</code> methods are called to update the database.\n\n  @param columnIndex the first column is 1, the second is 2, ...\n  @param x the new column value\n}\nprocedure TZAbstractCachedResultSet.UpdateInt(ColumnIndex, Value: Integer);\nbegin\n{$IFNDEF DISABLE_CHECKING}\n  CheckUpdatable;\n{$ENDIF}\n  PrepareRowForUpdates;\n  FRowAccessor.SetInt(ColumnIndex, Value);\nend;\n\n{**\n  Updates the designated column with a <code>long</code> value.\n  The <code>updateXXX</code> methods are used to update column values in the\n  current row or the insert row.  The <code>updateXXX</code> methods do not\n  update the underlying database; instead the <code>updateRow</code> or\n  <code>insertRow</code> methods are called to update the database.\n\n  @param columnIndex the first column is 1, the second is 2, ...\n  @param x the new column value\n}\nprocedure TZAbstractCachedResultSet.UpdateLong(ColumnIndex: Integer;\n  Value: Int64);\nbegin\n{$IFNDEF DISABLE_CHECKING}\n  CheckUpdatable;\n{$ENDIF}\n  PrepareRowForUpdates;\n  FRowAccessor.SetLong(ColumnIndex, Value);\nend;\n\n{**\n  Updates the designated column with a <code>float</code> value.\n  The <code>updateXXX</code> methods are used to update column values in the\n  current row or the insert row.  The <code>updateXXX</code> methods do not\n  update the underlying database; instead the <code>updateRow</code> or\n  <code>insertRow</code> methods are called to update the database.\n\n  @param columnIndex the first column is 1, the second is 2, ...\n  @param x the new column value\n}\nprocedure TZAbstractCachedResultSet.UpdateFloat(ColumnIndex: Integer;\n  Value: Single);\nbegin\n{$IFNDEF DISABLE_CHECKING}\n  CheckUpdatable;\n{$ENDIF}\n  PrepareRowForUpdates;\n  FRowAccessor.SetFloat(ColumnIndex, Value);\nend;\n\n{**\n  Updates the designated column with a <code>double</code> value.\n  The <code>updateXXX</code> methods are used to update column values in the\n  current row or the insert row.  The <code>updateXXX</code> methods do not\n  update the underlying database; instead the <code>updateRow</code> or\n  <code>insertRow</code> methods are called to update the database.\n\n  @param columnIndex the first column is 1, the second is 2, ...\n  @param x the new column value\n}\nprocedure TZAbstractCachedResultSet.UpdateDouble(ColumnIndex: Integer;\n  Value: Double);\nbegin\n{$IFNDEF DISABLE_CHECKING}\n  CheckUpdatable;\n{$ENDIF}\n  PrepareRowForUpdates;\n  FRowAccessor.SetDouble(ColumnIndex, Value);\nend;\n\n{**\n  Updates the designated column with a <code>java.math.BigDecimal</code>\n  value.\n  The <code>updateXXX</code> methods are used to update column values in the\n  current row or the insert row.  The <code>updateXXX</code> methods do not\n  update the underlying database; instead the <code>updateRow</code> or\n  <code>insertRow</code> methods are called to update the database.\n\n  @param columnIndex the first column is 1, the second is 2, ...\n  @param x the new column value\n}\nprocedure TZAbstractCachedResultSet.UpdateBigDecimal(ColumnIndex: Integer;\n  Value: Extended);\nbegin\n{$IFNDEF DISABLE_CHECKING}\n  CheckUpdatable;\n{$ENDIF}\n  PrepareRowForUpdates;\n  FRowAccessor.SetBigDecimal(ColumnIndex, Value);\nend;\n\n{**\n  Updates the designated column with a <code>String</code> value.\n  The <code>updateXXX</code> methods are used to update column values in the\n  current row or the insert row.  The <code>updateXXX</code> methods do not\n  update the underlying database; instead the <code>updateRow</code> or\n  <code>insertRow</code> methods are called to update the database.\n\n  @param columnIndex the first column is 1, the second is 2, ...\n  @param x the new column value\n}\nprocedure TZAbstractCachedResultSet.UpdatePChar(ColumnIndex: Integer;\n  Value: PChar);\nbegin\n{$IFNDEF DISABLE_CHECKING}\n  CheckUpdatable;\n{$ENDIF}\n  PrepareRowForUpdates;\n  FRowAccessor.SetPChar(ColumnIndex, Value);\nend;\n\n{**\n  Updates the designated column with a <code>String</code> value.\n  The <code>updateXXX</code> methods are used to update column values in the\n  current row or the insert row.  The <code>updateXXX</code> methods do not\n  update the underlying database; instead the <code>updateRow</code> or\n  <code>insertRow</code> methods are called to update the database.\n\n  @param columnIndex the first column is 1, the second is 2, ...\n  @param x the new column value\n}\nprocedure TZAbstractCachedResultSet.UpdateString(ColumnIndex: Integer;\n  const Value: String);\nbegin\n{$IFNDEF DISABLE_CHECKING}\n  CheckUpdatable;\n{$ENDIF}\n  PrepareRowForUpdates;\n  FRowAccessor.SetString(ColumnIndex, Value);\nend;\n\n{**\n  Updates the designated column with a <code>Widestring</code> value.\n  The <code>updateXXX</code> methods are used to update column values in the\n  current row or the insert row.  The <code>updateXXX</code> methods do not\n  update the underlying database; instead the <code>updateRow</code> or\n  <code>insertRow</code> methods are called to update the database.\n\n  @param columnIndex the first column is 1, the second is 2, ...\n  @param x the new column value\n}\nprocedure TZAbstractCachedResultSet.UpdateUnicodeString(ColumnIndex: Integer;\n  const Value: WideString);\nbegin\n{$IFNDEF DISABLE_CHECKING}\n  CheckUpdatable;\n{$ENDIF}\n  PrepareRowForUpdates;\n  FRowAccessor.SetUnicodeString(ColumnIndex, Value);\nend;\n\n{**\n  Updates the designated column with a <code>byte</code> array value.\n  The <code>updateXXX</code> methods are used to update column values in the\n  current row or the insert row.  The <code>updateXXX</code> methods do not\n  update the underlying database; instead the <code>updateRow</code> or\n  <code>insertRow</code> methods are called to update the database.\n\n  @param columnIndex the first column is 1, the second is 2, ...\n  @param x the new column value\n}\nprocedure TZAbstractCachedResultSet.UpdateBytes(ColumnIndex: Integer;\n  const Value: TByteDynArray);\nbegin\n{$IFNDEF DISABLE_CHECKING}\n  CheckUpdatable;\n{$ENDIF}\n  PrepareRowForUpdates;\n  FRowAccessor.SetBytes(ColumnIndex, Value);\nend;\n\n{**\n  Updates the designated column with a <code>java.sql.Date</code> value.\n  The <code>updateXXX</code> methods are used to update column values in the\n  current row or the insert row.  The <code>updateXXX</code> methods do not\n  update the underlying database; instead the <code>updateRow</code> or\n  <code>insertRow</code> methods are called to update the database.\n\n  @param columnIndex the first column is 1, the second is 2, ...\n  @param x the new column value\n}\nprocedure TZAbstractCachedResultSet.UpdateDate(ColumnIndex: Integer;\n  Value: TDateTime);\nbegin\n{$IFNDEF DISABLE_CHECKING}\n  CheckUpdatable;\n{$ENDIF}\n  PrepareRowForUpdates;\n  FRowAccessor.SetDate(ColumnIndex, Value);\nend;\n\n{**\n  Updates the designated column with a <code>java.sql.Time</code> value.\n  The <code>updateXXX</code> methods are used to update column values in the\n  current row or the insert row.  The <code>updateXXX</code> methods do not\n  update the underlying database; instead the <code>updateRow</code> or\n  <code>insertRow</code> methods are called to update the database.\n\n  @param columnIndex the first column is 1, the second is 2, ...\n  @param x the new column value\n}\nprocedure TZAbstractCachedResultSet.UpdateTime(ColumnIndex: Integer;\n  Value: TDateTime);\nbegin\n{$IFNDEF DISABLE_CHECKING}\n  CheckUpdatable;\n{$ENDIF}\n  PrepareRowForUpdates;\n  FRowAccessor.SetTime(ColumnIndex, Value);\nend;\n\n{**\n  Updates the designated column with a <code>java.sql.Timestamp</code>\n  value.\n  The <code>updateXXX</code> methods are used to update column values in the\n  current row or the insert row.  The <code>updateXXX</code> methods do not\n  update the underlying database; instead the <code>updateRow</code> or\n  <code>insertRow</code> methods are called to update the database.\n\n  @param columnIndex the first column is 1, the second is 2, ...\n  @param x the new column value\n}\nprocedure TZAbstractCachedResultSet.UpdateTimestamp(ColumnIndex: Integer;\n  Value: TDateTime);\nbegin\n{$IFNDEF DISABLE_CHECKING}\n  CheckUpdatable;\n{$ENDIF}\n  PrepareRowForUpdates;\n  FRowAccessor.SetTimestamp(ColumnIndex, Value);\nend;\n\n{**\n  Updates the designated column with an ascii stream value.\n  The <code>updateXXX</code> methods are used to update column values in the\n  current row or the insert row.  The <code>updateXXX</code> methods do not\n  update the underlying database; instead the <code>updateRow</code> or\n  <code>insertRow</code> methods are called to update the database.\n\n  @param columnIndex the first column is 1, the second is 2, ...\n  @param x the new column value\n}\nprocedure TZAbstractCachedResultSet.UpdateAsciiStream(ColumnIndex: Integer;\n  Value: TStream);\nbegin\n{$IFNDEF DISABLE_CHECKING}\n  CheckUpdatable;\n{$ENDIF}\n  PrepareRowForUpdates;\n  FRowAccessor.SetAsciiStream(ColumnIndex, Value);\nend;\n\n{**\n  Updates the designated column with a binary stream value.\n  The <code>updateXXX</code> methods are used to update column values in the\n  current row or the insert row.  The <code>updateXXX</code> methods do not\n  update the underlying database; instead the <code>updateRow</code> or\n  <code>insertRow</code> methods are called to update the database.\n\n  @param columnIndex the first column is 1, the second is 2, ...\n  @param x the new column value\n  @param length the length of the stream\n}\nprocedure TZAbstractCachedResultSet.UpdateBinaryStream(\n  ColumnIndex: Integer; Value: TStream);\nbegin\n{$IFNDEF DISABLE_CHECKING}\n  CheckUpdatable;\n{$ENDIF}\n  PrepareRowForUpdates;\n  FRowAccessor.SetBinaryStream(ColumnIndex, Value);\nend;\n\n{**\n  Updates the designated column with a character stream value.\n  The <code>updateXXX</code> methods are used to update column values in the\n  current row or the insert row.  The <code>updateXXX</code> methods do not\n  update the underlying database; instead the <code>updateRow</code> or\n  <code>insertRow</code> methods are called to update the database.\n\n  @param columnIndex the first column is 1, the second is 2, ...\n  @param x the new column value\n}\nprocedure TZAbstractCachedResultSet.UpdateUnicodeStream(\n  ColumnIndex: Integer; Value: TStream);\nvar\n  TempStream: TStream;\nbegin\n{$IFNDEF DISABLE_CHECKING}\n  CheckUpdatable;\n{$ENDIF}\n  PrepareRowForUpdates;\n  {EgonHugeist:\n    Findout, wat's comming in! To avoid User-Bugs\n    it is possible that a PAnsiChar OR a PWideChar was written into\n    the Stream!!!  And these chars could be trunced with changing the\n    Stream.Size.}\n  if Assigned(Value) then\n  begin\n    TempStream := GetValidatedUnicodeStream(TMemoryStream(Value).Memory, Value.Size, ConSettings, False);\n    FRowAccessor.SetUnicodeStream(ColumnIndex, TempStream);\n    TempStream.Free;\n  end\n  else\n    FRowAccessor.SetUnicodeStream(ColumnIndex, nil);\nend;\n\n{**\n  Updates the DefaultExpression of the designated column with a <code>String</code> value.\n  This changes the behaviour of the RowAccessor used by the Resultset\n  @param columnIndex the first column is 1, the second is 2, ...\n  @param x the new DefaultExpression value for the column\n}\nprocedure TZAbstractCachedResultSet.UpdateDefaultExpression(ColumnIndex: Integer;\n  const Value: string);\nbegin\n  FNewRowAccessor.SetColumnDefaultExpression(ColumnIndex, Value);\nend;\n\n//---------------------------------------------------------------------\n// Processing methods\n//---------------------------------------------------------------------\n\n{**\n  Moves the cursor to the given row number in\n  this <code>ResultSet</code> object.\n\n  <p>If the row number is positive, the cursor moves to\n  the given row number with respect to the\n  beginning of the result set.  The first row is row 1, the second\n  is row 2, and so on.\n\n  <p>If the given row number is negative, the cursor moves to\n  an absolute row position with respect to\n  the end of the result set.  For example, calling the method\n  <code>absolute(-1)</code> positions the\n  cursor on the last row; calling the method <code>absolute(-2)</code>\n  moves the cursor to the next-to-last row, and so on.\n\n  <p>An attempt to position the cursor beyond the first/last row in\n  the result set leaves the cursor before the first row or after\n  the last row.\n\n  <p><B>Note:</B> Calling <code>absolute(1)</code> is the same\n  as calling <code>first()</code>. Calling <code>absolute(-1)</code>\n  is the same as calling <code>last()</code>.\n\n  @return <code>true</code> if the cursor is on the result set;\n    <code>false</code> otherwise\n}\nfunction TZAbstractCachedResultSet.MoveAbsolute(Row: Integer): Boolean;\nbegin\n{$IFNDEF DISABLE_CHECKING}\n  CheckClosed;\n  if (ResultSetType = rtForwardOnly) and (Row < RowNo) then\n    RaiseForwardOnlyException;\n{$ENDIF}\n\n  if (Row >= 0) and (Row <= LastRowNo + 1) then\n  begin\n    RowNo := Row;\n    if (Row >= 1) and (Row <= LastRowNo) then\n    begin\n      Result := True;\n      FSelectedRow := PZRowBuffer(FRowsList[Row - 1]);\n      RowAccessor.RowBuffer := FSelectedRow;\n    end\n    else\n    begin\n      Result := False;\n      FSelectedRow := nil;\n      RowAccessor.RowBuffer := FSelectedRow;\n    end;\n  end\n  else\n    Result := False;\nend;\n\n{**\n  Indicates whether the current row has been updated.  The value returned\n  depends on whether or not the result set can detect updates.\n\n  @return <code>true</code> if the row has been visibly updated\n    by the owner or another, and updates are detected\n}\nfunction TZAbstractCachedResultSet.RowUpdated: Boolean;\nvar\n  CurrentRow: PZRowBuffer;\nbegin\n  if (RowNo >= 1) and (RowNo <= LastRowNo) then\n  begin\n    CurrentRow := PZRowBuffer(FRowsList[RowNo - 1]);\n    Result := CurrentRow^.UpdateType = utModified;\n  end\n  else\n    Result := False;\nend;\n\n{**\n  Indicates whether the current row has had an insertion.\n  The value returned depends on whether or not this\n  <code>ResultSet</code> object can detect visible inserts.\n\n  @return <code>true</code> if a row has had an insertion\n    and insertions are detected; <code>false</code> otherwise\n}\nfunction TZAbstractCachedResultSet.RowInserted: Boolean;\nvar\n  CurrentRow: PZRowBuffer;\nbegin\n  if (RowNo >= 1) and (RowNo <= LastRowNo) then\n  begin\n    CurrentRow := PZRowBuffer(FRowsList[RowNo - 1]);\n    Result := CurrentRow^.UpdateType = utInserted;\n  end\n  else\n    Result := False;\nend;\n\n{**\n  Indicates whether a row has been deleted.  A deleted row may leave\n  a visible \"hole\" in a result set.  This method can be used to\n  detect holes in a result set.  The value returned depends on whether\n  or not this <code>ResultSet</code> object can detect deletions.\n\n  @return <code>true</code> if a row was deleted and deletions are detected;\n    <code>false</code> otherwise\n}\nfunction TZAbstractCachedResultSet.RowDeleted: Boolean;\nvar\n  UpdateType: TZRowUpdateType;\nbegin\n  if (RowNo >= 1) and (RowNo <= LastRowNo) then\n  begin\n    UpdateType := PZRowBuffer(FRowsList[RowNo - 1])^.UpdateType;\n    Result := UpdateType = utDeleted;\n  end\n  else\n    Result := False;\nend;\n\n{**\n  Inserts the contents of the insert row into this\n  <code>ResultSet</code> object and into the database.\n  The cursor must be on the insert row when this method is called.\n}\nprocedure TZAbstractCachedResultSet.InsertRow;\nvar\n  TempRow: PZRowBuffer;\nbegin\n  CheckClosed;\n\n  { Creates a new row. }\n  TempRow := FRowAccessor.RowBuffer;\n  FRowAccessor.Alloc;\n  FRowAccessor.MoveFrom(FInsertedRow);\n  FRowAccessor.RowBuffer^.UpdateType := utInserted;\n  FRowAccessor.RowBuffer^.Index := GetNextRowIndex;\n\n  AppendRow(FRowAccessor.RowBuffer);\n\n  { Posts non-cached updates. }\n  if not FCachedUpdates then\n  begin\n    try\n      PostUpdates;\n    except\n      on E: Exception do\n      begin\n        { Restore the previous state. }\n        FRowAccessor.DisposeBuffer(FInitialRowsList[FInitialRowsList.Count - 1]);\n        FInitialRowsList.Delete(FInitialRowsList.Count - 1);\n        FRowAccessor.DisposeBuffer(FCurrentRowsList[FCurrentRowsList.Count - 1]);\n        FCurrentRowsList.Delete(FCurrentRowsList.Count - 1);\n        FRowAccessor.RowBuffer := TempRow;\n\n        { Reraises the exception. }\n        RaiseSQLException(E);\n      end;\n    end;\n  end;\n\n  FRowsList.Add(FRowAccessor.RowBuffer);\n  LastRowNo := FRowsList.Count;\n  MoveAbsolute(LastRowNo);\nend;\n\n{**\n  Updates the underlying database with the new contents of the\n  current row of this <code>ResultSet</code> object.\n  This method cannot be called when the cursor is on the insert row.\n}\nprocedure TZAbstractCachedResultSet.UpdateRow;\nbegin\n  CheckUpdatable;\n  if (RowNo < 1) or (RowNo > LastRowNo) then\n    raise EZSQLException.Create(SCanNotUpdateEmptyRow);\n\n  if PZRowBuffer(FRowsList[RowNo - 1]).UpdateType = utDeleted then\n    raise EZSQLException.Create(SCanNotUpdateDeletedRow);\n\n  if FSelectedRow <> FUpdatedRow then\n      Exit;\n\n  AppendRow(FRowsList[RowNo - 1]);\n\n  FSelectedRow := PZRowBuffer(FRowsList[RowNo - 1]);\n  FRowAccessor.CopyBuffer(FUpdatedRow, FSelectedRow);\n  FRowAccessor.RowBuffer := FSelectedRow;\n  if FSelectedRow.UpdateType = utUnmodified then\n    FSelectedRow.UpdateType := utModified;\n\n  { Posts non-cached updates. }\n  if not FCachedUpdates then\n  begin\n    try\n      PostUpdates;\n    except\n      on E: Exception do\n      begin\n        { Restore the previous state. }\n        FRowAccessor.DisposeBuffer(FRowsList[RowNo - 1]);\n        FRowsList[RowNo - 1] := FInitialRowsList[FInitialRowsList.Count - 1];\n        FInitialRowsList.Delete(FInitialRowsList.Count - 1);\n        FCurrentRowsList.Delete(FCurrentRowsList.Count - 1);\n\n        FSelectedRow := PZRowBuffer(FRowsList[RowNo - 1]);\n        FRowAccessor.RowBuffer := FSelectedRow;\n\n        { Reraises the exception. }\n        RaiseSQLException(E);\n      end;\n    end;\n  end;\nend;\n\n{**\n  Deletes the current row from this <code>ResultSet</code> object\n  and from the underlying database.  This method cannot be called when\n  the cursor is on the insert row.\n}\nprocedure TZAbstractCachedResultSet.DeleteRow;\nbegin\n  CheckUpdatable;\n  if (RowNo < 1) or (RowNo > LastRowNo) or (FSelectedRow = nil) then\n    raise EZSQLException.Create(SCanNotDeleteEmptyRow);\n\n  if FSelectedRow^.UpdateType = utInserted then\n    RevertRecord\n  else\n  begin\n    AppendRow(FRowsList[RowNo - 1]);\n\n    FSelectedRow^.UpdateType := utDeleted;\n    if FSelectedRow = FUpdatedRow then\n      FRowAccessor.CopyBuffer(FUpdatedRow, FRowsList[RowNo - 1]);\n\n    { Posts non-cached updates. }\n    if not FCachedUpdates then\n    begin\n      try\n        PostUpdates;\n      except\n        on E: Exception do\n        begin\n          { Restores the previous state. }\n          FRowAccessor.DisposeBuffer(FRowsList[RowNo - 1]);\n          FRowsList[RowNo - 1] := FInitialRowsList[FInitialRowsList.Count - 1];\n          FSelectedRow := FRowsList[RowNo - 1];\n          FInitialRowsList.Delete(FInitialRowsList.Count - 1);\n          FCurrentRowsList.Delete(FCurrentRowsList.Count - 1);\n\n          { Rethrows the exception. }\n          RaiseSQLException(E);\n        end;\n      end;\n    end;\n  end;\nend;\n\n{**\n  Cancels the updates made to the current row in this\n  <code>ResultSet</code> object.\n  This method may be called after calling an\n  <code>updateXXX</code> method(s) and before calling\n  the method <code>updateRow</code> to roll back\n  the updates made to a row.  If no updates have been made or\n  <code>updateRow</code> has already been called, this method has no\n  effect.\n}\nprocedure TZAbstractCachedResultSet.CancelRowUpdates;\nbegin\n  MoveAbsolute(RowNo);\nend;\n\n{**\n  Moves the cursor to the insert row.  The current cursor position is\n  remembered while the cursor is positioned on the insert row.\n\n  The insert row is a special row associated with an updatable\n  result set.  It is essentially a buffer where a new row may\n  be constructed by calling the <code>updateXXX</code> methods prior to\n  inserting the row into the result set.\n\n  Only the <code>updateXXX</code>, <code>getXXX</code>,\n  and <code>insertRow</code> methods may be\n  called when the cursor is on the insert row.  All of the columns in\n  a result set must be given a value each time this method is\n  called before calling <code>insertRow</code>.\n  An <code>updateXXX</code> method must be called before a\n  <code>getXXX</code> method can be called on a column value.\n}\nprocedure TZAbstractCachedResultSet.MoveToInsertRow;\nbegin\n  CheckClosed;\n  FRowAccessor.RowBuffer := FInsertedRow;\nend;\n\n{**\n  Moves the cursor to the remembered cursor position, usually the\n  current row.  This method has no effect if the cursor is not on\n  the insert row.\n}\nprocedure TZAbstractCachedResultSet.MoveToCurrentRow;\nbegin\n  CheckClosed;\n  if (RowNo >= 1) and (RowNo <= LastRowNo) then\n    FRowAccessor.RowBuffer := FSelectedRow\n  else\n    FRowAccessor.RowBuffer := nil;\nend;\n\n{**\n  Compares fields from two row buffers.\n  @param Row1 the first row buffer to compare.\n  @param Row2 the second row buffer to compare.\n  @param ColumnIndices column indices to compare.\n  @param ColumnDirs compare direction for each columns.\n}\nfunction TZAbstractCachedResultSet.CompareRows(Row1, Row2: Integer;\n  const ColumnIndices: TIntegerDynArray; const ColumnDirs: TBooleanDynArray): Integer;\nvar\n  RowBuffer1, RowBuffer2: PZRowBuffer;\nbegin\n{$IFNDEF DISABLE_CHECKING}\n  if ResultSetType = rtForwardOnly then\n    RaiseForwardOnlyException;\n{$ENDIF}\n  RowBuffer1 := PZRowBuffer(FRowsList[Row1 - 1]);\n  RowBuffer2 := PZRowBuffer(FRowsList[Row2 - 1]);\n  Result := FRowAccessor.CompareBuffers(RowBuffer1, RowBuffer2,\n    ColumnIndices, ColumnDirs);\nend;\n\n{ TZCachedResultSet }\n\n{**\n  Creates this object and assignes the main properties.\n  @param ResultSet a wrapped resultset object.\n  @param Resolver a cached updates resolver object.\n}\nconstructor TZCachedResultSet.Create(ResultSet: IZResultSet; SQL: string;\n  Resolver: IZCachedResolver; ConSettings: PZConSettings);\nbegin\n  inherited Create(ResultSet.GetStatement, SQL, nil, ConSettings);\n  FResultSet := ResultSet;\n  FResolver := Resolver;\n  {BEGIN PATCH [1214009] CalcDefaults in TZUpdateSQL and Added Methods to GET the DB NativeResolver}\n  FNativeResolver := Resolver;\n  {END PATCH [1214009] CalcDefaults in TZUpdateSQL and Added Methods to GET the DB NativeResolver}\n  Open;\nend;\n\n{**\n  Destroys this object and cleanups the memory.\n}\ndestructor TZCachedResultSet.Destroy;\nbegin\n  inherited Destroy;\nend;\n\n{**\n  Fetches one row from the wrapped result set object.\n  @return <code>True</code> if row was successfuly fetched\n    or <code>False</code> otherwise.\n}\nfunction TZCachedResultSet.Fetch: Boolean;\nvar\n  I: Integer;\n  TempRow: PZRowBuffer;\nbegin\n  Result := FResultSet.Next;\n  if not Result or ((MaxRows > 0) and (LastRowNo >= MaxRows)) then\n    Exit;\n\n  TempRow := RowAccessor.RowBuffer;\n  try\n    RowAccessor.Alloc;\n    RowAccessor.RowBuffer.Index := GetNextRowIndex;\n    RowAccessor.RowBuffer.UpdateType := utUnmodified;\n\n    for I := 1 to ColumnsInfo.Count do\n    begin\n      case TZColumnInfo(ColumnsInfo[I - 1]).ColumnType of\n        stBoolean: RowAccessor.SetBoolean(I, ResultSet.GetBoolean(I));\n        stByte: RowAccessor.SetByte(I, ResultSet.GetByte(I));\n        stShort: RowAccessor.SetShort(I, ResultSet.GetShort(I));\n        stInteger: RowAccessor.SetInt(I, ResultSet.GetInt(I));\n        stLong: RowAccessor.SetLong(I, ResultSet.GetLong(I));\n        stFloat: RowAccessor.SetFloat(I, ResultSet.GetFloat(I));\n        stDouble: RowAccessor.SetDouble(I, ResultSet.GetDouble(I));\n        stBigDecimal: RowAccessor.SetBigDecimal(I, ResultSet.GetBigDecimal(I));\n        stString: RowAccessor.SetString(I, ResultSet.GetString(I));\n        stUnicodeString: RowAccessor.SetUnicodeString(I,\n                  ResultSet.GetUnicodeString(I));\n        stBytes,stGUID: RowAccessor.SetBytes(I, ResultSet.GetBytes(I));\n        stDate: RowAccessor.SetDate(I, ResultSet.GetDate(I));\n        stTime: RowAccessor.SetTime(I, ResultSet.GetTime(I));\n        stTimestamp: RowAccessor.SetTimestamp(I, ResultSet.GetTimestamp(I));\n        stAsciiStream, stBinaryStream, stUnicodeStream:\n          RowAccessor.SetBlob(I, ResultSet.GetBlob(I));\n        stDataSet: RowAccessor.SetDataSet(i, ResultSet.GetDataSet(I));\n\n      end;\n      if ResultSet.WasNull then\n        RowAccessor.SetNull(I);\n    end;\n\n    RowsList.Add(RowAccessor.RowBuffer);\n    LastRowNo := RowsList.Count;\n  finally\n    RowAccessor.RowBuffer := TempRow;\n  end;\nend;\n\n{**\n  Fetches all of the rest rows from the wrapped result set.\n}\nprocedure TZCachedResultSet.FetchAll;\nbegin\n  while Fetch do;\nend;\n\n{**\n  Opens this recordset.\n}\nprocedure TZCachedResultSet.Open;\nvar\n  I: Integer;\n  ColumnInfo: TZColumnInfo;\n  MetaData : IZResultSetMetaData;\nbegin\n  ColumnsInfo.Clear;\n  MetaData := FResultSet.GetMetadata;\n  for I := 1 to Metadata.GetColumnCount do\n  begin\n    ColumnInfo := TZColumnInfo.Create;\n    with ColumnInfo do\n    begin\n      Currency := Metadata.IsCurrency(I);\n      Signed := Metadata.IsSigned(I);\n      ColumnDisplaySize := Metadata.GetColumnDisplaySize(I);\n      ColumnLabel := Metadata.GetColumnLabel(I);\n      Precision := Metadata.GetPrecision(I);\n      Scale := Metadata.GetScale(I);\n      ColumnType := Metadata.GetColumnType(I);\n    end;\n    ColumnsInfo.Add(ColumnInfo);\n  end;\n\n  inherited Open;\nend;\n\n{**\n  Releases this <code>ResultSet</code> object's database and\n  JDBC resources immediately instead of waiting for\n  this to happen when it is automatically closed.\n\n  <P><B>Note:</B> A <code>ResultSet</code> object\n  is automatically closed by the\n  <code>Statement</code> object that generated it when\n  that <code>Statement</code> object is closed,\n  re-executed, or is used to retrieve the next result from a\n  sequence of multiple results. A <code>ResultSet</code> object\n  is also automatically closed when it is garbage collected.\n}\nprocedure TZCachedResultSet.Close;\nbegin\n  inherited Close;\n  ColumnsInfo.Clear;\n  If Assigned(FResultset) then\n    FResultset.Close;\n  FResultSet := nil;\nend;\n\n{**\n  Retrieves the  number, types and properties of\n  this <code>ResultSet</code> object's columns.\n  @return the description of this <code>ResultSet</code> object's columns\n}\nfunction TZCachedResultSet.GetMetadata: IZResultSetMetadata;\nbegin\n  Result := ResultSet.GetMetadata;\nend;\n\n{**\n  Indicates whether the cursor is after the last row in\n  this <code>ResultSet</code> object.\n\n  @return <code>true</code> if the cursor is after the last row;\n    <code>false</code> if the cursor is at any other position or the\n    result set contains no rows\n}\nfunction TZCachedResultSet.IsAfterLast: Boolean;\nbegin\n  FetchAll;\n  Result := inherited IsAfterLast;\nend;\n\n{**\n  Moves the cursor to the end of\n  this <code>ResultSet</code> object, just after the\n  last row. This method has no effect if the result set contains no rows.\n}\nprocedure TZCachedResultSet.AfterLast;\nbegin\n  FetchAll;\n  inherited AfterLast;\nend;\n\n{**\n  Indicates whether the cursor is on the last row of\n  this <code>ResultSet</code> object.\n  Note: Calling the method <code>isLast</code> may be expensive\n  because the JDBC driver\n  might need to fetch ahead one row in order to determine\n  whether the current row is the last row in the result set.\n\n  @return <code>true</code> if the cursor is on the last row;\n    <code>false</code> otherwise\n}\nfunction TZCachedResultSet.IsLast: Boolean;\nbegin\n  FetchAll;\n  Result := inherited IsLast;\nend;\n\n{**\n  Moves the cursor to the last row in\n  this <code>ResultSet</code> object.\n\n  @return <code>true</code> if the cursor is on a valid row;\n    <code>false</code> if there are no rows in the result set\n}\nfunction TZCachedResultSet.Last: Boolean;\nbegin\n  FetchAll;\n  Result := inherited Last;\nend;\n\n{**\n  Moves the cursor to the given row number in\n  this <code>ResultSet</code> object.\n\n  <p>If the row number is positive, the cursor moves to\n  the given row number with respect to the\n  beginning of the result set.  The first row is row 1, the second\n  is row 2, and so on.\n\n  <p>If the given row number is negative, the cursor moves to\n  an absolute row position with respect to\n  the end of the result set.  For example, calling the method\n  <code>absolute(-1)</code> positions the\n  cursor on the last row; calling the method <code>absolute(-2)</code>\n  moves the cursor to the next-to-last row, and so on.\n\n  <p>An attempt to position the cursor beyond the first/last row in\n  the result set leaves the cursor before the first row or after\n  the last row.\n\n  <p><B>Note:</B> Calling <code>absolute(1)</code> is the same\n  as calling <code>first()</code>. Calling <code>absolute(-1)</code>\n  is the same as calling <code>last()</code>.\n\n  @return <code>true</code> if the cursor is on the result set;\n    <code>false</code> otherwise\n}\nfunction TZCachedResultSet.MoveAbsolute(Row: Integer): Boolean;\nbegin\n  { Checks for maximum row. }\n  Result := False;\n  if (MaxRows > 0) and (Row > MaxRows) then\n    Exit;\n\n  { Processes negative rows }\n  if Row < 0 then\n  begin\n    FetchAll;\n    Row := LastRowNo - Row + 1;\n    if Row < 0 then\n       Row := 0;\n  end\n  else\n  { Processes moving after last row }\n    while (LastRowNo < Row) and Fetch do;\n\n  Result := inherited MoveAbsolute(Row);\nend;\n\nend.\n\n"
  },
  {
    "path": "lib/zeosdbo/src/dbc/ZDbcConnection.pas",
    "content": "{*********************************************************}\n{                                                         }\n{                 Zeos Database Objects                   }\n{         Abstract Database Connectivity Classes          }\n{                                                         }\n{        Originally written by Sergey Seroukhov           }\n{                                                         }\n{*********************************************************}\n\n{@********************************************************}\n{    Copyright (c) 1999-2012 Zeos Development Group       }\n{                                                         }\n{ License Agreement:                                      }\n{                                                         }\n{ This library is distributed in the hope that it will be }\n{ useful, but WITHOUT ANY WARRANTY; without even the      }\n{ implied warranty of MERCHANTABILITY or FITNESS FOR      }\n{ A PARTICULAR PURPOSE.  See the GNU Lesser General       }\n{ Public License for more details.                        }\n{                                                         }\n{ The source code of the ZEOS Libraries and packages are  }\n{ distributed under the Library GNU General Public        }\n{ License (see the file COPYING / COPYING.ZEOS)           }\n{ with the following  modification:                       }\n{ As a special exception, the copyright holders of this   }\n{ library give you permission to link this library with   }\n{ independent modules to produce an executable,           }\n{ regardless of the license terms of these independent    }\n{ modules, and to copy and distribute the resulting       }\n{ executable under terms of your choice, provided that    }\n{ you also meet, for each linked independent module,      }\n{ the terms and conditions of the license of that module. }\n{ An independent module is a module which is not derived  }\n{ from or based on this library. If you modify this       }\n{ library, you may extend this exception to your version  }\n{ of the library, but you are not obligated to do so.     }\n{ If you do not wish to do so, delete this exception      }\n{ statement from your version.                            }\n{                                                         }\n{                                                         }\n{ The project web site is located on:                     }\n{   http://zeos.firmos.at  (FORUM)                        }\n{   http://sourceforge.net/p/zeoslib/tickets/ (BUGTRACKER)}\n{   svn://svn.code.sf.net/p/zeoslib/code-0/trunk (SVN)    }\n{                                                         }\n{   http://www.sourceforge.net/projects/zeoslib.          }\n{                                                         }\n{                                                         }\n{                                 Zeos Development Group. }\n{********************************************************@}\n\nunit ZDbcConnection;\n\ninterface\n\n{$I ZDbc.inc}\n\nuses\n{$IFDEF FPC}\n  {$IFDEF WIN32}\n    Comobj,\n  {$ENDIF}\n{$ENDIF}\n{$IFDEF WITH_LCONVENCODING}\n  LConvEncoding,\n{$ENDIF}\n  Types, Classes, {$IFDEF MSEgui}mclasses,{$ENDIF} SysUtils,\n  ZClasses, ZDbcIntfs, ZTokenizer, ZCompatibility, ZGenericSqlToken,\n  ZGenericSqlAnalyser, ZPlainDriver, ZURL, ZCollections, ZVariant;\n\ntype\n\n  {** Implements Abstract Database Driver. }\n  {$WARNINGS OFF} //to supress the deprecated Warning of connect\n  TZAbstractDriver = class(TInterfacedObject, IZDriver)\n  private\n    FTokenizer: IZTokenizer;\n    FAnalyser: IZStatementAnalyser;\n  protected\n    FCachedPlainDrivers: IZHashMap;\n    FSupportedProtocols: TStringDynArray;\n    procedure AddSupportedProtocol(AProtocol: String);\n    function AddPlainDriverToCache(PlainDriver: IZPlainDriver; const Protocol: string = ''; LibLocation: string = ''): String;\n    function GetPlainDriverFromCache(const Protocol, LibLocation: string): IZPlainDriver;\n    function GetPlainDriver(const Url: TZURL; const InitDriver: Boolean = True): IZPlainDriver; virtual;\n    property Tokenizer: IZTokenizer read FTokenizer write FTokenizer;\n    property Analyser: IZStatementAnalyser read FAnalyser write FAnalyser;\n  public\n    constructor Create; virtual;\n    destructor Destroy; override;\n\n    function GetSupportedProtocols: TStringDynArray;\n    function GetSupportedClientCodePages(const Url: TZURL;\n      Const {$IFNDEF UNICODE}AutoEncode, {$ENDIF} SupportedsOnly: Boolean;\n      CtrlsCPType: TZControlsCodePage = cCP_UTF16): TStringDynArray;\n    function Connect(const Url: string; Info: TStrings = nil): IZConnection; overload; deprecated;\n    function Connect(const Url: TZURL): IZConnection; overload; virtual;\n    function AcceptsURL(const Url: string): Boolean; virtual;\n\n    function GetPropertyInfo(const Url: string; Info: TStrings): TStrings; virtual;\n    function GetMajorVersion: Integer; virtual;\n    function GetMinorVersion: Integer; virtual;\n    function GetSubVersion: Integer; virtual;\n    function GetTokenizer: IZTokenizer; virtual;\n    function GetStatementAnalyser: IZStatementAnalyser; virtual;\n    function GetClientVersion(const Url: string): Integer; virtual;\n  end;\n  {$WARNINGS OFF}\n\n  {** Implements Abstract Database Connection. }\n\n  { TZAbstractConnection }\n\n  TZAbstractConnection = class(TZCodePagedObject, IZConnection)\n  private\n    FDriver: IZDriver;\n    FIZPlainDriver: IZPlainDriver;\n    FAutoCommit: Boolean;\n    FReadOnly: Boolean;\n    FTransactIsolationLevel: TZTransactIsolationLevel;\n    FClosed: Boolean;\n    FURL: TZURL;\n    FUseMetadata: Boolean;\n    function GetHostName: string;\n    procedure SetHostName(const Value: String);\n    function GetPort: Integer;\n    procedure SetConnPort(const Value: Integer);\n    function GetDatabase: string;\n    procedure SetDatabase(const Value: String);\n    function GetUser: string;\n    procedure SetUser(const Value: String);\n    function GetPassword: string;\n    procedure SetPassword(const Value: String);\n    function GetInfo: TStrings;\n  protected\n    FDisposeCodePage: Boolean;\n    FUndefinedVarcharAsStringLength: Integer; //used for PostgreSQL and SQLite\n    FClientCodePage: String;\n    FMetadata: TContainedObject;\n    {$IFDEF ZEOS_TEST_ONLY}\n    FTestMode: Byte;\n    {$ENDIF}\n    procedure InternalCreate; virtual; abstract;\n    function GetEncoding: TZCharEncoding;\n    function GetConSettings: PZConSettings;\n    procedure CheckCharEncoding(const CharSet: String; const DoArrange: Boolean = False);\n    function GetClientCodePageInformations: PZCodePage; //EgonHugeist\n    function GetAutoEncodeStrings: Boolean; //EgonHugeist\n    procedure SetAutoEncodeStrings(const Value: Boolean);\n    procedure OnPropertiesChange(Sender: TObject); virtual;\n    procedure RaiseUnsupportedException;\n\n    function CreateRegularStatement(Info: TStrings): IZStatement;\n      virtual;\n    function CreatePreparedStatement(const SQL: string; Info: TStrings):\n      IZPreparedStatement; virtual;\n    function CreateCallableStatement(const SQL: string; Info: TStrings):\n      IZCallableStatement; virtual;\n\n    property Driver: IZDriver read FDriver write FDriver;\n    property PlainDriver: IZPlainDriver read FIZPlainDriver write FIZPlainDriver;\n    property HostName: string read GetHostName write SetHostName;\n    property Port: Integer read GetPort write SetConnPort;\n    property Database: string read GetDatabase write SetDatabase;\n    property User: string read GetUser write SetUser;\n    property Password: string read GetPassword write SetPassword;\n    property Info: TStrings read GetInfo;\n    property AutoCommit: Boolean read FAutoCommit write FAutoCommit;\n    property ReadOnly: Boolean read FReadOnly write FReadOnly;\n    property URL: TZURL read FURL;\n    property TransactIsolationLevel: TZTransactIsolationLevel\n      read FTransactIsolationLevel write FTransactIsolationLevel;\n    property Closed: Boolean read FClosed write FClosed;\n  public\n    constructor Create(Driver: IZDriver; const Url: string;\n      PlainDriver: IZPlainDriver; const HostName: string; Port: Integer;\n      const Database: string; const User: string; const Password: string;\n      Info: TStrings); overload; deprecated;\n    constructor Create(const ZUrl: TZURL); overload;\n    destructor Destroy; override;\n\n    function CreateStatement: IZStatement;\n    function PrepareStatement(const SQL: string): IZPreparedStatement;\n    function PrepareCall(const SQL: string): IZCallableStatement;\n\n    function CreateStatementWithParams(Info: TStrings): IZStatement;\n    function PrepareStatementWithParams(const SQL: string; Info: TStrings):\n      IZPreparedStatement;\n    function PrepareCallWithParams(const SQL: string; Info: TStrings):\n      IZCallableStatement;\n\n    function CreateNotification(const Event: string): IZNotification; virtual;\n    function CreateSequence(const Sequence: string; BlockSize: Integer):\n      IZSequence; virtual;\n\n    function NativeSQL(const SQL: string): string; virtual;\n\n    procedure SetAutoCommit(AutoCommit: Boolean); virtual;\n    function GetAutoCommit: Boolean; virtual;\n\n    procedure Commit; virtual;\n    procedure Rollback; virtual;\n\n    //2Phase Commit Support initially for PostgresSQL (firmos) 21022006\n    procedure PrepareTransaction(const transactionid: string);virtual;\n    procedure CommitPrepared(const transactionid: string);virtual;\n    procedure RollbackPrepared(const transactionid: string);virtual;\n\n    //Ping Support initially for MySQL 27032006 (firmos)\n    function PingServer: Integer; virtual;\n    function EscapeString(Value: RawByteString): RawByteString; virtual;\n\n    procedure Open; virtual;\n    procedure Close; virtual;\n    function IsClosed: Boolean; virtual;\n\n    function GetDriver: IZDriver;\n    function GetIZPlainDriver: IZPlainDriver;\n    function GetMetadata: IZDatabaseMetadata;\n    function GetParameters: TStrings;\n    {ADDED by fduenas 15-06-2006}\n    function GetClientVersion: Integer; virtual;\n    function GetHostVersion: Integer; virtual;\n    {END ADDED by fduenas 15-06-2006}\n    function GetDescription: AnsiString;\n    procedure SetReadOnly(ReadOnly: Boolean); virtual;\n    function IsReadOnly: Boolean; virtual;\n\n    procedure SetCatalog(const Catalog: string); virtual;\n    function GetCatalog: string; virtual;\n\n    procedure SetTransactionIsolation(Level: TZTransactIsolationLevel); virtual;\n    function GetTransactionIsolation: TZTransactIsolationLevel; virtual;\n\n    function GetWarnings: EZSQLWarning; virtual;\n    procedure ClearWarnings; virtual;\n    function GetBinaryEscapeString(const Value: RawByteString): String; overload; virtual;\n    function GetBinaryEscapeString(const Value: TByteDynArray): String; overload; virtual;\n    function GetEscapeString(const Value: ZWideString): ZWideString; overload; virtual;\n    function GetEscapeString(const Value: RawByteString): RawByteString; overload; virtual;\n    function UseMetadata: boolean;\n    procedure SetUseMetadata(Value: Boolean);\n    {$IFDEF ZEOS_TEST_ONLY}\n    function GetTestMode : Byte;\n    procedure SetTestMode(Mode: Byte);\n    {$ENDIF}\nend;\n\n  {** Implements Abstract Database notification. }\n  TZAbstractNotification = class(TInterfacedObject, IZNotification)\n  private\n    FEventName: string;\n    FConnection: IZConnection;\n  protected\n    property EventName: string read FEventName write FEventName;\n    property Connection: IZConnection read FConnection write FConnection;\n  public\n    constructor Create(Connection: IZConnection; EventName: string);\n    function GetEvent: string;\n    procedure Listen; virtual;\n    procedure Unlisten; virtual;\n    procedure DoNotify; virtual;\n    function CheckEvents: string; virtual;\n\n    function GetConnection: IZConnection; virtual;\n  end;\n\n  {** Implements Abstract Sequence generator. }\n  TZAbstractSequence = class(TInterfacedObject, IZSequence)\n  private\n    FName: string;\n    FBlockSize: Integer;\n    FConnection: IZConnection;\n  protected\n    function GetName: string; virtual;\n    function GetBlockSize: Integer; virtual;\n    procedure SetName(const Value: string); virtual;\n    procedure SetBlockSize(const Value: Integer); virtual;\n    property Connection: IZConnection read FConnection write FConnection;\n  public\n    constructor Create(Connection: IZConnection; Name: string;\n      BlockSize: Integer);\n\n    function GetCurrentValue: Int64; virtual;\n    function GetNextValue: Int64; virtual;\n\n    function GetCurrentValueSQL: string; virtual; abstract;\n    function GetNextValueSQL: string; virtual; abstract;\n\n    function GetConnection: IZConnection; virtual;\n\n    property Name: string read GetName write SetName;\n    property BlockSize: Integer read GetBlockSize write SetBlockSize;\n  end;\n\nimplementation\n\nuses ZMessages, ZSysUtils, ZDbcMetadata, ZDbcUtils, ZEncoding\n  {$IFDEF WITH_UNITANSISTRINGS},AnsiStrings{$ENDIF};\n\n{ TZAbstractDriver }\n\n{**\n  Constructs this object with default properties.\n}\nconstructor TZAbstractDriver.Create;\nbegin\n  FCachedPlainDrivers := TZHashMap.Create;\nend;\n\n{**\n  Destroys this object and cleanups the memory.\n}\ndestructor TZAbstractDriver.Destroy;\nbegin\n  FTokenizer := nil;\n  FAnalyser := nil;\n  FCachedPlainDrivers.Clear;\n  FCachedPlainDrivers := nil;\n  inherited Destroy;\nend;\n\nfunction TZAbstractDriver.GetSupportedProtocols: TStringDynArray;\nbegin\n  Result := FSupportedProtocols;\nend;\n\n{**\n  EgonHugeist:\n  Get names of the supported CharacterSets.\n  For example: ASCII, UTF8...\n}\nfunction TZAbstractDriver.GetSupportedClientCodePages(const Url: TZURL;\n  Const {$IFNDEF UNICODE}AutoEncode,{$ENDIF} SupportedsOnly: Boolean;\n  CtrlsCPType: TZControlsCodePage = cCP_UTF16): TStringDynArray;\nvar\n  Plain: IZPlainDriver;\nbegin\n  Plain := GetPlainDriverFromCache(Url.Protocol, '');\n  if Assigned(Plain) then\n  Result := Plain.GetSupportedClientCodePages({$IFNDEF UNICODE}AutoEncode,{$ENDIF}\n    not SupportedsOnly, CtrlsCPType);\nend;\n\n{**\n  Attempts to make a database connection to the given URL.\n  The driver should return \"null\" if it realizes it is the wrong kind\n  of driver to connect to the given URL.  This will be common, as when\n  the JDBC driver manager is asked to connect to a given URL it passes\n  the URL to each loaded driver in turn.\n\n  <P>The driver should raise a SQLException if it is the right\n  driver to connect to the given URL, but has trouble connecting to\n  the database.\n\n  <P>The java.util.Properties argument can be used to passed arbitrary\n  string tag/value pairs as connection arguments.\n  Normally at least \"user\" and \"password\" properties should be\n  included in the Properties.\n\n  @param url the URL of the database to which to connect\n  @param info a list of arbitrary string tag/value pairs as\n    connection arguments. Normally at least a \"user\" and\n    \"password\" property should be included.\n  @return a <code>Connection</code> object that represents a\n    connection to the URL\n}\n{$WARNINGS OFF}\nfunction TZAbstractDriver.Connect(const Url: string; Info: TStrings): IZConnection;\nvar\n  TempURL:  TZURL;\nbegin\n  TempURL := TZURL.Create(Url, Info);\n  try\n    Result := Connect(TempURL);\n  finally\n    TempUrl.Free;\n  end;\nend;\n\nfunction TZAbstractDriver.Connect(const Url: TZURL): IZConnection;\nbegin\n  Result := nil;\nend;\n{$WARNINGS ON}\n\n{**\n  Returns true if the driver thinks that it can open a connection\n  to the given URL.  Typically drivers will return true if they\n  understand the subprotocol specified in the URL and false if\n  they don't.\n  @param url the URL of the database\n  @return true if this driver can connect to the given URL\n}\nfunction TZAbstractDriver.AcceptsURL(const Url: string): Boolean;\nvar\n  I: Integer;\n  Protocols: TStringDynArray;\nbegin\n  Result := False;\n  Protocols := GetSupportedProtocols;\n  for I := Low(Protocols) to High(Protocols) do\n  begin\n    Result := StartsWith(LowerCase(Url), Format('zdbc:%s:', [LowerCase(Protocols[I])]));\n    if Result then\n      Break;\n  end;\nend;\n\nprocedure TZAbstractDriver.AddSupportedProtocol(AProtocol: String);\nbegin\n  SetLength(FSupportedProtocols, Length(FSupportedProtocols)+1);\n  FSupportedProtocols[High(FSupportedProtocols)] := AProtocol;\nend;\n\nfunction TZAbstractDriver.AddPlainDriverToCache(PlainDriver: IZPlainDriver;\n  const Protocol: string = ''; LibLocation: string = ''): String;\nvar\n  TempKey: IZAnyValue;\nbegin\n  if Protocol = '' then\n  begin\n    Result := PlainDriver.GetProtocol;\n    TempKey := TZAnyValue.CreateWithString(PlainDriver.GetProtocol)\n  end\n  else\n  begin\n    Result := Protocol;\n    TempKey := TZAnyValue.CreateWithString(Protocol+LibLocation);\n  end;\n  FCachedPlainDrivers.Put(TempKey, PlainDriver);\nend;\n\nfunction TZAbstractDriver.GetPlainDriverFromCache(const Protocol, LibLocation: string): IZPlainDriver;\nvar\n  TempKey: IZAnyValue;\n  TempPlain: IZPlainDriver;\nbegin\n  TempKey := TZAnyValue.CreateWithString(Protocol+LibLocation);\n  Result := FCachedPlainDrivers.Get(TempKey) as IZPlainDriver;\n  if Result = nil then\n  begin\n    TempKey := nil;\n    TempKey := TZAnyValue.CreateWithString(Protocol);\n    TempPlain := FCachedPlainDrivers.Get(TempKey) as IZPlainDriver;\n    if Assigned(TempPlain) then\n      Result := TempPlain.Clone;\n  end;\nend;\n\n{**\n  Gets plain driver for selected protocol.\n  @param Url a database connection URL.\n  @return a selected plaindriver.\n}\nfunction TZAbstractDriver.GetPlainDriver(const Url: TZURL;\n  const InitDriver: Boolean): IZPlainDriver;\nbegin\n  Result := GetPlainDriverFromCache(Url.Protocol, Url.LibLocation);\n  if Assigned(Result) and InitDriver then\n    Result.Initialize(Url.LibLocation);\nend;\n\n{**\n  Gets information about the possible properties for this driver.\n  <p>The getPropertyInfo method is intended to allow a generic GUI tool to\n  discover what properties it should prompt a human for in order to get\n  enough information to connect to a database.  Note that depending on\n  the values the human has supplied so far, additional values may become\n  necessary, so it may be necessary to iterate though several calls\n  to getPropertyInfo.\n\n  @param url the URL of the database to which to connect\n  @param info a proposed list of tag/value pairs that will be sent on\n    connect open\n  @return an array of DriverPropertyInfo objects describing possible\n    properties.  This array may be an empty array if no properties\n    are required.\n}\nfunction TZAbstractDriver.GetPropertyInfo(const Url: string; Info: TStrings): TStrings;\nbegin\n  Result := nil;\nend;\n\n{**\n  Gets the driver's major version number. Initially this should be 1.\n  @return this driver's major version number\n}\nfunction TZAbstractDriver.GetMajorVersion: Integer;\nbegin\n  Result := 1;\nend;\n\n{**\n  Gets the driver's minor version number. Initially this should be 0.\n  @return this driver's minor version number\n}\nfunction TZAbstractDriver.GetMinorVersion: Integer;\nbegin\n  Result := 0;\nend;\n\n{**\n  Gets the driver's sub version (revision) number. Initially this should be 0.\n  @return this driver's sub version number\n}\nfunction TZAbstractDriver.GetSubVersion: Integer;\nbegin\n Result := 0;\nend;\n{**\n  Creates a generic statement analyser object.\n  @returns a generic statement analyser object.\n}\nfunction TZAbstractDriver.GetStatementAnalyser: IZStatementAnalyser;\nbegin\n  if Analyser = nil then\n    Analyser := TZGenericStatementAnalyser.Create;\n  Result := Analyser;\nend;\n\n{**\n  Creates a generic tokenizer object.\n  @returns a created generic tokenizer object.\n}\nfunction TZAbstractDriver.GetTokenizer: IZTokenizer;\nbegin\n  if Tokenizer = nil then\n    Tokenizer := TZGenericSQLTokenizer.Create;\n  Result := Tokenizer;\nend;\n\n{**\n  Returns the version of the plain driver library that will be used to open a connection\n  to the given URL.\n  @param url the URL of the database\n  @return the version number of the plain driver library for the give URL\n}\nfunction TZAbstractDriver.GetClientVersion(const Url: string): Integer;\nbegin\n  Result := 0;\nend;\n\n{ TZAbstractConnection }\n\nfunction TZAbstractConnection.GetHostName: string;\nbegin\n  Result := FURL.HostName;\nend;\n\nprocedure TZAbstractConnection.SetHostName(const Value: String);\nbegin\n  FURL.HostName := Value;\nend;\n\nfunction TZAbstractConnection.GetPort: Integer;\nbegin\n  Result := FURL.Port;\nend;\n\nprocedure TZAbstractConnection.SetConnPort(const Value: Integer);\nbegin\n  FURL.Port := Value;\nend;\n\nfunction TZAbstractConnection.GetDatabase: string;\nbegin\n  Result := FURL.Database;\nend;\n\nprocedure TZAbstractConnection.SetDatabase(const Value: String);\nbegin\n  FURL.Database := Value;\nend;\n\nfunction TZAbstractConnection.GetUser: string;\nbegin\n  Result := FURL.UserName;\nend;\n\nprocedure TZAbstractConnection.SetUser(const Value: String);\nbegin\n  FURL.UserName := Value;\nend;\n\nfunction TZAbstractConnection.GetPassword: string;\nbegin\n  Result := FURL.Password;\nend;\n\nprocedure TZAbstractConnection.SetPassword(const Value: String);\nbegin\n  FURL.Password := Value;\nend;\n\nfunction TZAbstractConnection.GetInfo: TStrings;\nbegin\n  Result := FURL.Properties;\nend;\n\nfunction TZAbstractConnection.GetEncoding: TZCharEncoding;\nbegin\n  Result := ConSettings.ClientCodePage^.Encoding;\nend;\n\nfunction TZAbstractConnection.GetConSettings: PZConSettings;\nbegin\n  Result := ConSettings;\nend;\n\n{**\n  EgonHugeist: Check if the given Charset for Compiler/Database-Support!!\n    Not supported means if there is a pissible String-DataLoss.\n    So it raises an Exception if case of settings. This handling\n    is an improofment to inform Zeos-Users about the troubles the given\n    CharacterSet may have.\n  @param CharSet the CharacterSet which has to be proofed\n  @param DoArrange represents a switch to check and set a aternative ZAlias as\n    default. This means it ignores the choosen Client-CharacterSet and sets a\n    \"more\" Zeos-Compatible Client-CharacterSet if known.\n}\nprocedure TZAbstractConnection.CheckCharEncoding(const CharSet: String;\n  const DoArrange: Boolean = False);\nbegin\n  ConSettings.ClientCodePage := GetIZPlainDriver.ValidateCharEncoding(CharSet, DoArrange);\n  FClientCodePage := ConSettings.ClientCodePage^.Name; //resets the developer choosen ClientCodePage\n  {$IFDEF WITH_LCONVENCODING}\n  SetConvertFunctions(ConSettings.CTRL_CP, ConSettings.ClientCodePage.CP,\n    ConSettings.PlainConvertFunc, ConSettings.DbcConvertFunc);\n  {$ENDIF}\n  ZEncoding.SetConvertFunctions(ConSettings);\nend;\n\n\n{**\n  EgonHugeist: this is a compatibility-Option for exiting Applictions.\n    Zeos is now able to preprepare direct insered SQL-Statements.\n    Means do the UTF8-preparation if the CharacterSet was choosen.\n    So we do not need to do the SQLString + UTF8Encode(Edit1.Test) for example.\n  @result True if coPreprepareSQL was choosen in the TZAbstractConnection\n}\nfunction TZAbstractConnection.GetAutoEncodeStrings: Boolean;\nbegin\n  {$IFDEF UNICODE}\n  Result := True;\n  {$ELSE}\n  Result := ConSettings.AutoEncode;\n  {$ENDIF}\nend;\n\nprocedure TZAbstractConnection.SetAutoEncodeStrings(const Value: Boolean);\nbegin\n  {$IFNDEF UNICODE}\n  ConSettings.AutoEncode := Value;\n  {$ENDIF}\nend;\n\n{**\n  EgonHugeist and MDeams: The old deprecadet constructor which was used\n  from the descendant classes. We left him here for compatibility reasons to\n  exesting projects which using the DbcConnections directly\n\n  Constructs this object and assignes the main properties.\n  @param Driver the parent ZDBC driver.\n  @param Url a connection URL.\n  @param PlainDriver a versioned ZPlainDriver object interface.\n  @param HostName a name of the host.\n  @param Port a port number (0 for default port).\n  @param Database a name pof the database.\n  @param User a user name.\n  @param Password a user password.\n  @param Info a string list with extra connection parameters.\n}\n{$WARNINGS OFF} //suppress the deprecatad warning of calling create from internal\nconstructor TZAbstractConnection.Create(Driver: IZDriver; const Url: string;\n  PlainDriver: IZPlainDriver;\n  const HostName: string; Port: Integer; const Database: string;\n  const User: string; const Password: string; Info: TStrings);\nvar\n  TempURL: TZURL;\nbegin\n  TempURL := TZURL.Create(Url, HostName, Port, Database, User, Password, Info);\n  Create(TempURL);\n  TempURL.Free;\nend;\n{$WARNINGS OFF}\n\n{**\n  Constructs this object and assignes the main properties.\n  @param Url a connection ZURL-class which exports all connection parameters.\n}\nconstructor TZAbstractConnection.Create(const ZUrl: TZURL);\nbegin\n  FClosed := True;\n  if not assigned(ZUrl) then\n    raise Exception.Create('ZUrl is not assigned!')\n  else\n    FURL := TZURL.Create();\n  FDriver := DriverManager.GetDriver(ZURL.URL);\n  FIZPlainDriver := FDriver.GetPlainDriver(ZUrl);\n\n  FURL.OnPropertiesChange := OnPropertiesChange;\n  FURL.URL := ZUrl.URL;\n\n  FClientCodePage := Info.Values['codepage'];\n  {CheckCharEncoding}\n  ConSettings := New(PZConSettings);\n\n  SetConSettingsFromInfo(Info);\n  CheckCharEncoding(FClientCodePage, True);\n\n  FAutoCommit := True;\n  FReadOnly := True;\n  FTransactIsolationLevel := tiNone;\n  FUseMetadata := True;\n  InternalCreate;\n  {$IFDEF ZEOS_TEST_ONLY}\n  FTestMode := 0;\n  {$ENDIF}\nend;\n\n{**\n  Destroys this object and cleanups the memory.\n}\ndestructor TZAbstractConnection.Destroy;\nbegin\n  if not FClosed then\n    Close;\n  FreeAndNil(FMetadata);\n  FURL.Free;\n  FIZPlainDriver := nil;\n  FDriver := nil;\n  if Assigned(ConSettings) then\n    Dispose(ConSettings);\n  inherited Destroy;\nend;\n\n{**\n  Opens a connection to database server with specified parameters.\n}\nprocedure TZAbstractConnection.Open;\nbegin\n  FClosed := False;\nend;\n\n{**\n  Raises unsupported operation exception.\n}\nprocedure TZAbstractConnection.RaiseUnsupportedException;\nbegin\n  raise EZSQLException.Create(SUnsupportedOperation);\nend;\n\n{**\n  Creates a <code>Statement</code> object for sending\n  SQL statements to the database.\n  SQL statements without parameters are normally\n  executed using Statement objects. If the same SQL statement\n  is executed many times, it is more efficient to use a\n  <code>PreparedStatement</code> object.\n  <P>\n  Result sets created using the returned <code>Statement</code>\n  object will by default have forward-only type and read-only concurrency.\n\n  @return a new Statement object\n}\nfunction TZAbstractConnection.CreateStatement: IZStatement;\nbegin\n  Result := CreateStatementWithParams(nil);\nend;\n\n{**\n  Creates a <code>Statement</code> object for sending\n  SQL statements to the database.\n  SQL statements without parameters are normally\n  executed using Statement objects. If the same SQL statement\n  is executed many times, it is more efficient to use a\n  <code>PreparedStatement</code> object.\n  <P>\n  Result sets created using the returned <code>Statement</code>\n  object will by default have forward-only type and read-only concurrency.\n\n  @param Info a statement parameters.\n  @return a new Statement object\n}\nfunction TZAbstractConnection.CreateStatementWithParams(Info: TStrings):\n  IZStatement;\nvar UsedInfo: TStrings;\nbegin\n  UsedInfo := Info;\n  If StrToBoolEx(GetInfo.Values['preferprepared']) then\n  begin\n    If UsedInfo = nil then\n        UsedInfo := TSTringList.Create;\n      UsedInfo.Append('preferprepared=TRUE');\n  end;\n  Result := CreateRegularStatement(UsedInfo);\n  if UsedInfo <> Info then UsedInfo.Free;\nend;\n\n{**\n  Creates a regular statement object.\n  @param SQL a SQL query string.\n  @param Info a statement parameters.\n  @returns a created statement.\n}\nfunction TZAbstractConnection.CreateRegularStatement(\n  Info: TStrings): IZStatement;\nbegin\n  Result := nil;\n  RaiseUnsupportedException;\nend;\n\n{**\n  Creates a <code>PreparedStatement</code> object for sending\n  parameterized SQL statements to the database.\n\n  A SQL statement with or without IN parameters can be\n  pre-compiled and stored in a PreparedStatement object. This\n  object can then be used to efficiently execute this statement\n  multiple times.\n\n  <P><B>Note:</B> This method is optimized for handling\n  parametric SQL statements that benefit from precompilation. If\n  the driver supports precompilation,\n  the method <code>prepareStatement</code> will send\n  the statement to the database for precompilation. Some drivers\n  may not support precompilation. In this case, the statement may\n  not be sent to the database until the <code>PreparedStatement</code> is\n  executed.  This has no direct effect on users; however, it does\n  affect which method throws certain SQLExceptions.\n\n  Result sets created using the returned PreparedStatement will have\n  forward-only type and read-only concurrency, by default.\n\n  @param sql a SQL statement that may contain one or more '?' IN\n    parameter placeholders\n  @return a new PreparedStatement object containing the\n    pre-compiled statement\n}\nfunction TZAbstractConnection.PrepareStatement(const SQL: string): IZPreparedStatement;\nbegin\n  Result := CreatePreparedStatement(SQL, nil);\nend;\n\n{**\n  Creates a <code>PreparedStatement</code> object for sending\n  parameterized SQL statements to the database.\n\n  @param SQL a SQL statement that may contain one or more '?' IN\n    parameter placeholders\n  @param Info a statement parameters.\n  @return a new PreparedStatement object containing the\n    pre-compiled statement\n}\nfunction TZAbstractConnection.PrepareStatementWithParams(const SQL: string;\n  Info: TStrings): IZPreparedStatement;\nvar UsedInfo: TStrings;\nbegin\n  UsedInfo := Info;\n  If StrToBoolEx(GetInfo.Values['preferprepared']) then\n  begin\n    If UsedInfo = nil then\n      UsedInfo := TSTringList.Create;\n    UsedInfo.Append('preferprepared=TRUE');\n  end;\n  Result := CreatePreparedStatement(SQL, UsedInfo);\n  if UsedInfo <> Info then UsedInfo.Free;\nend;\n\nprocedure TZAbstractConnection.PrepareTransaction(const transactionid: string);\nbegin\n  RaiseUnsupportedException;\nend;\n\n{**\n  Creates a prepared statement object.\n  @param SQL a SQL query string.\n  @param Info a statement parameters.\n  @returns a created statement.\n}\nfunction TZAbstractConnection.CreatePreparedStatement(const SQL: string;\n  Info: TStrings): IZPreparedStatement;\nbegin\n  Result := nil;\n  RaiseUnsupportedException;\nend;\n\n{**\n  Creates a <code>CallableStatement</code> object for calling\n  database stored procedures.\n  The <code>CallableStatement</code> object provides\n  methods for setting up its IN and OUT parameters, and\n  methods for executing the call to a stored procedure.\n\n  <P><B>Note:</B> This method is optimized for handling stored\n  procedure call statements. Some drivers may send the call\n  statement to the database when the method <code>prepareCall</code>\n  is done; others\n  may wait until the <code>CallableStatement</code> object\n  is executed. This has no\n  direct effect on users; however, it does affect which method\n  throws certain SQLExceptions.\n\n  Result sets created using the returned CallableStatement will have\n  forward-only type and read-only concurrency, by default.\n\n  @param sql a SQL statement that may contain one or more '?'\n    parameter placeholders. Typically this  statement is a JDBC\n    function call escape string.\n  @return a new CallableStatement object containing the\n    pre-compiled SQL statement\n}\n\nfunction TZAbstractConnection.PrepareCall(\n  const SQL: string): IZCallableStatement;\nbegin\n  Result := CreateCallableStatement(SQL, nil);\nend;\n\n{**\n  Creates a <code>CallableStatement</code> object for calling\n  database stored procedures.\n  The <code>CallableStatement</code> object provides\n  methods for setting up its IN and OUT parameters, and\n  methods for executing the call to a stored procedure.\n\n  @param SQL a SQL statement that may contain one or more '?'\n    parameter placeholders. Typically this  statement is a JDBC\n    function call escape string.\n  @param Info a statement parameters.\n  @return a new CallableStatement object containing the\n    pre-compiled SQL statement\n}\nfunction TZAbstractConnection.PrepareCallWithParams(const SQL: string;\n  Info: TStrings): IZCallableStatement;\nvar UsedInfo: TStrings;\nbegin\n  UsedInfo := Info;\n  If StrToBoolEx(GetInfo.Values['preferprepared']) then\n  begin\n    If UsedInfo = nil then\n      UsedInfo := TSTringList.Create;\n    UsedInfo.Append('preferprepared=TRUE');\n  end;\n  Result := CreateCallableStatement(SQL, UsedInfo);\n  if UsedInfo <> Info then UsedInfo.Free;\nend;\n\n{**\n  Creates a callable statement object.\n  @param SQL a SQL query string.\n  @param Info a statement parameters.\n  @returns a created statement.\n}\nfunction TZAbstractConnection.CreateCallableStatement(const SQL: string;\n  Info: TStrings): IZCallableStatement;\nbegin\n  Result := nil;\n  RaiseUnsupportedException;\nend;\n\n{**\n  Creates an object to send/recieve notifications from SQL server.\n  @param Event an event name.\n  @returns a created notification object.\n}\nfunction TZAbstractConnection.CreateNotification(const Event: string): IZNotification;\nbegin\n  Result := nil;\n  RaiseUnsupportedException;\nend;\n\n{**\n  Creates a sequence generator object.\n  @param Sequence a name of the sequence generator.\n  @param BlockSize a number of unique keys requested in one trip to SQL server.\n  @returns a created sequence object.\n}\nfunction TZAbstractConnection.CreateSequence(const Sequence: string;\n  BlockSize: Integer): IZSequence;\nbegin\n  Result := nil;\n  RaiseUnsupportedException;\nend;\n\n{**\n  Converts the given SQL statement into the system's native SQL grammar.\n  A driver may convert the JDBC sql grammar into its system's\n  native SQL grammar prior to sending it; this method returns the\n  native form of the statement that the driver would have sent.\n\n  @param sql a SQL statement that may contain one or more '?'\n    parameter placeholders\n  @return the native form of this statement\n}\nfunction TZAbstractConnection.NativeSQL(const SQL: string): string;\nbegin\n  Result := SQL;\nend;\n\n{**\n  Sets this connection's auto-commit mode.\n  If a connection is in auto-commit mode, then all its SQL\n  statements will be executed and committed as individual\n  transactions.  Otherwise, its SQL statements are grouped into\n  transactions that are terminated by a call to either\n  the method <code>commit</code> or the method <code>rollback</code>.\n  By default, new connections are in auto-commit mode.\n\n  The commit occurs when the statement completes or the next\n  execute occurs, whichever comes first. In the case of\n  statements returning a ResultSet, the statement completes when\n  the last row of the ResultSet has been retrieved or the\n  ResultSet has been closed. In advanced cases, a single\n  statement may return multiple results as well as output\n  parameter values. In these cases the commit occurs when all results and\n  output parameter values have been retrieved.\n\n  @param autoCommit true enables auto-commit; false disables auto-commit.\n}\nprocedure TZAbstractConnection.SetAutoCommit(AutoCommit: Boolean);\nbegin\n  FAutoCommit := AutoCommit;\nend;\n\n{**\n  Gets the current auto-commit state.\n  @return the current state of auto-commit mode\n  @see #setAutoCommit\n}\nfunction TZAbstractConnection.GetAutoCommit: Boolean;\nbegin\n  Result := FAutoCommit;\nend;\n\n{**\n  Makes all changes made since the previous\n  commit/rollback permanent and releases any database locks\n  currently held by the Connection. This method should be\n  used only when auto-commit mode has been disabled.\n  @see #setAutoCommit\n}\nprocedure TZAbstractConnection.Commit;\nbegin\n  RaiseUnsupportedException;\nend;\n\nprocedure TZAbstractConnection.CommitPrepared(const transactionid: string);\nbegin\n  RaiseUnsupportedException;\nend;\n\n{**\n  Drops all changes made since the previous\n  commit/rollback and releases any database locks currently held\n  by this Connection. This method should be used only when auto-\n  commit has been disabled.\n  @see #setAutoCommit\n}\nprocedure TZAbstractConnection.Rollback;\nbegin\n  RaiseUnsupportedException;\nend;\n\nprocedure TZAbstractConnection.RollbackPrepared(const transactionid: string);\nbegin\n  RaiseUnsupportedException;\nend;\n\n{**\n  Ping Current Connection's server, if client was disconnected,\n  the connection is resumed.\n  @return 0 if succesfull or error code if any error occurs\n}\nfunction TZAbstractConnection.PingServer: Integer;\nbegin\n  Result := 1;\n  RaiseUnsupportedException;\nend;\n\n{**\n  Escape a string so it's acceptable for the Connection's server.\n  @param value string that should be escaped\n  @return Escaped string\n}\nfunction TZAbstractConnection.EscapeString(Value : RawByteString) : RawByteString;\nbegin\n  Result := AnsiString(EncodeCString(String(Value)));\nend;\n\n{**\n  Releases a Connection's database and JDBC resources\n  immediately instead of waiting for\n  them to be automatically released.\n\n  <P><B>Note:</B> A Connection is automatically closed when it is\n  garbage collected. Certain fatal errors also result in a closed\n  Connection.\n}\n\nprocedure TZAbstractConnection.Close;\nbegin\n  if FDisposeCodePage then\n  begin\n    Dispose(ConSettings^.ClientCodePage);\n    ConSettings^.ClientCodePage := nil;\n    FDisposeCodePage := False;\n  end;\n  FClosed := True;\nend;\n\n{**\n  Tests to see if a Connection is closed.\n  @return true if the connection is closed; false if it's still open\n}\nfunction TZAbstractConnection.IsClosed: Boolean;\nbegin\n  Result := FClosed;\nend;\n\n{**\n  Gets the parent ZDBC driver.\n  @returns the parent ZDBC driver interface.\n}\nfunction TZAbstractConnection.GetDriver: IZDriver;\nbegin\n  Result := FDriver;\nend;\n\n{**\n  Gets the plain driver.\n  @returns the plain driver interface.\n}\nfunction TZAbstractConnection.GetIZPlainDriver: IZPlainDriver;\nbegin\n  result := FIZPlainDriver;\nend;\n\n{**\n  Gets the metadata regarding this connection's database.\n  A Connection's database is able to provide information\n  describing its tables, its supported SQL grammar, its stored\n  procedures, the capabilities of this connection, and so on. This\n  information is made available through a DatabaseMetaData\n  object.\n\n  @return a DatabaseMetaData object for this Connection\n}\nfunction TZAbstractConnection.GetMetadata: IZDatabaseMetadata;\nbegin\n  Result := FMetadata as IZDatabaseMetadata;\nend;\n\n{**\n  Gets a connection parameters.\n  @returns a list with connection parameters.\n}\nfunction TZAbstractConnection.GetParameters: TStrings;\nbegin\n  Result := Info;\nend;\n\n{**\n  Gets the client's full version number. Initially this should be 0.\n  The format of the version resturned must be XYYYZZZ where\n   X   = Major version\n   YYY = Minor version\n   ZZZ = Sub version\n  @return this clients's full version number\n}\nfunction TZAbstractConnection.GetClientVersion: Integer;\nbegin\n Result := 0;\nend;\n\n{**\n  Gets the host's full version number. Initially this should be 0.\n  The format of the version returned must be XYYYZZZ where\n   X   = Major version\n   YYY = Minor version\n   ZZZ = Sub version\n  @return this server's full version number\n}\nfunction TZAbstractConnection.GetHostVersion: Integer;\nbegin\n Result := 0;\nend;\n\nfunction TZAbstractConnection.GetDescription: AnsiString;\nbegin\n  PlainDriver.GetDescription;\nend;\n\n{END ADDED by fduenas 15-06-2006}\n\n{**\n  Puts this connection in read-only mode as a hint to enable\n  database optimizations.\n\n  <P><B>Note:</B> This method cannot be called while in the\n  middle of a transaction.\n\n  @param readOnly true enables read-only mode; false disables\n    read-only mode.\n}\nprocedure TZAbstractConnection.SetReadOnly(ReadOnly: Boolean);\nbegin\n  FReadOnly := ReadOnly;\nend;\n\n{**\n  Tests to see if the connection is in read-only mode.\n  @return true if connection is read-only and false otherwise\n}\nfunction TZAbstractConnection.IsReadOnly: Boolean;\nbegin\n  Result := FReadOnly;\nend;\n\n{**\n  Sets a catalog name in order to select\n  a subspace of this Connection's database in which to work.\n  If the driver does not support catalogs, it will\n  silently ignore this request.\n}\nprocedure TZAbstractConnection.SetCatalog(const Catalog: string);\nbegin\nend;\n\n{**\n  Returns the Connection's current catalog name.\n  @return the current catalog name or null\n}\nfunction TZAbstractConnection.GetCatalog: string;\nbegin\n  Result := '';\nend;\n\n{**\n  Attempts to change the transaction isolation level to the one given.\n  The constants defined in the interface <code>Connection</code>\n  are the possible transaction isolation levels.\n\n  <P><B>Note:</B> This method cannot be called while\n  in the middle of a transaction.\n\n  @param level one of the TRANSACTION_* isolation values with the\n    exception of TRANSACTION_NONE; some databases may not support other values\n  @see DatabaseMetaData#supportsTransactionIsolationLevel\n}\nprocedure TZAbstractConnection.SetTransactionIsolation(\n  Level: TZTransactIsolationLevel);\nbegin\n  FTransactIsolationLevel := Level;\nend;\n\n{**\n  Gets this Connection's current transaction isolation level.\n  @return the current TRANSACTION_* mode value\n}\nfunction TZAbstractConnection.GetTransactionIsolation: TZTransactIsolationLevel;\nbegin\n  Result := FTransactIsolationLevel;\nend;\n\n{**\n  Returns the first warning reported by calls on this Connection.\n  <P><B>Note:</B> Subsequent warnings will be chained to this\n  SQLWarning.\n  @return the first SQLWarning or null\n}\nfunction TZAbstractConnection.GetWarnings: EZSQLWarning;\nbegin\n  Result := nil;\nend;\n\n{**\n  Clears all warnings reported for this <code>Connection</code> object.\n  After a call to this method, the method <code>getWarnings</code>\n    returns null until a new warning is reported for this Connection.\n}\nprocedure TZAbstractConnection.ClearWarnings;\nbegin\nend;\n\nfunction TZAbstractConnection.UseMetadata: boolean;\nbegin\n  result := FUseMetadata;\nend;\n\nprocedure TZAbstractConnection.SetUseMetadata(Value: Boolean);\nbegin\n  FUseMetadata := Value;\nend;\n\n{$IFDEF ZEOS_TEST_ONLY}\nfunction TZAbstractConnection.GetTestMode: Byte;\nbegin\n  Result := FTestMode;\nend;\n\nprocedure TZAbstractConnection.SetTestMode(Mode: Byte);\nbegin\n  FTestMode := Mode;\nend;\n{$ENDIF}\n\n{**\n  EgonHugeist:\n  Returns the BinaryString in a Tokenizer-detectable kind\n  If the Tokenizer don't need to predetect it Result = BinaryString\n  @param Value represents the Binary-String\n  @param EscapeMarkSequence represents a Tokenizer detectable EscapeSequence (Len >= 3)\n  @result the detectable Binary String\n}\nfunction TZAbstractConnection.GetBinaryEscapeString(const Value: RawByteString): String;\nbegin\n  if GetAutoEncodeStrings then //Set detect-sequence only if Prepreparing should be done else it's not server-understandable.\n    Result := Self.GetDriver.GetTokenizer.AnsiGetEscapeString(GetSQLHexString(PAnsiChar(Value), Length(Value)))\n  else\n    Result := GetSQLHexString(PAnsiChar(Value), Length(Value));\nend;\n\nfunction TZAbstractConnection.GetBinaryEscapeString(const Value: TByteDynArray): String;\nbegin\n  if GetAutoEncodeStrings then //Set detect-sequence only if Prepreparing should be done else it's not server-understandable.\n    Result := Self.GetDriver.GetTokenizer.AnsiGetEscapeString(GetSQLHexString(PAnsiChar(Value), Length(Value)))\n  else\n    Result := GetSQLHexString(PAnsiChar(Value), Length(Value));\nend;\n\nfunction TZAbstractConnection.GetEscapeString(const Value: ZWideString): ZWideString;\nbegin\n  if GetAutoEncodeStrings then\n    if StartsWith(Value, '''') and EndsWith(Value, '''') then\n      Result := GetDriver.GetTokenizer.GetEscapeString(Value)\n    else\n      {$IFDEF UNICODE}\n      Result := AnsiQuotedStr(Value, #39)\n      {$ELSE}\n      Result := ZDbcUnicodeString(GetDriver.GetTokenizer.GetEscapeString(AnsiQuotedStr(ZPlainString(Value), #39)))\n      {$ENDIF}\n  else\n    if StartsWith(Value, '''') and EndsWith(Value, '''') then\n      Result := Value\n    else\n      {$IFDEF UNICODE}\n      Result := AnsiQuotedStr(Value, #39);\n      {$ELSE}\n      Result := ZDbcUnicodeString(AnsiQuotedStr(ZPlainString(Value), #39));\n      {$ENDIF}\nend;\n\nfunction TZAbstractConnection.GetEscapeString(const Value: RawByteString): RawByteString;\nbegin\n  if GetAutoEncodeStrings then\n    if StartsWith(Value, '''') and EndsWith(Value, '''') then\n      Result := {$IFNDEF UNICODE}GetDriver.GetTokenizer.GetEscapeString{$ENDIF}(Value)\n    else\n      {$IFDEF WITH_UNITANSISTRINGS}\n      AnsiStrings.AnsiQuotedStr(Value, #39)\n      {$ELSE}\n      Result := GetDriver.GetTokenizer.GetEscapeString(AnsiQuotedStr(ZDbcString(Value), #39))\n      {$ENDIF}\n  else\n    if StartsWith(Value, '''') and EndsWith(Value, '''') then\n      Result := Value\n    else\n      Result := {$IFDEF WITH_UNITANSISTRINGS}AnsiStrings.{$ENDIF}AnsiQuotedStr(Value, #39);\nend;\n\n{**\n  Result 100% Compiler-Compatible\n  And sets it Result to ClientCodePage by calling the\n    PlainDriver.GetClientCodePageInformations function\n\n  @param ClientCharacterSet the CharacterSet which has to be checked\n  @result PZCodePage see ZCompatible.pas\n}\nfunction TZAbstractConnection.GetClientCodePageInformations: PZCodePage; //EgonHugeist\nbegin\n  Result := ConSettings.ClientCodePage\nend;\n\nprocedure TZAbstractConnection.OnPropertiesChange(Sender: TObject);\nbegin\n  // do nothing in base class\nend;\n\n{ TZAbstractNotification }\n\n{**\n  Creates this object and assignes the main properties.\n  @param Connection a database connection object.\n  @param EventName a name of the SQL event.\n}\nconstructor TZAbstractNotification.Create(Connection: IZConnection;\n  EventName: string);\nbegin\n  FConnection := Connection;\n  FEventName := EventName;\nend;\n\n{**\n  Gets an event name.\n  @return an event name for this notification.\n}\nfunction TZAbstractNotification.GetEvent: string;\nbegin\n  Result := FEventName;\nend;\n\n{**\n  Sets a listener to the specified event.\n}\nprocedure TZAbstractNotification.Listen;\nbegin\nend;\n\n{**\n  Removes a listener to the specified event.\n}\nprocedure TZAbstractNotification.Unlisten;\nbegin\nend;\n\n{**\n  Checks for any pending events.\n  @return a string with incoming events??\n}\nfunction TZAbstractNotification.CheckEvents: string;\nbegin\n  Result := '';\nend;\n\n{**\n  Sends a notification string.\n}\nprocedure TZAbstractNotification.DoNotify;\nbegin\nend;\n\n{**\n  Returns the <code>Connection</code> object\n  that produced this <code>Statement</code> object.\n  @return the connection that produced this statement\n}\nfunction TZAbstractNotification.GetConnection: IZConnection;\nbegin\n  Result := FConnection;\nend;\n\n{ TZAbstractSequence }\n\n{**\n  Creates this sequence object.\n  @param Connection an SQL connection interface.\n  @param Name a name of the sequence generator.\n  @param BlockSize a number of unique keys requested in one trip to server.\n}\nconstructor TZAbstractSequence.Create(Connection: IZConnection;\n  Name: string; BlockSize: Integer);\nbegin\n  FConnection := Connection;\n  FName := Name;\n  FBlockSize := BlockSize;\nend;\n\n{**\n  Returns the <code>Connection</code> object\n  that produced this <code>Statement</code> object.\n  @return the connection that produced this statement\n}\nfunction TZAbstractSequence.GetConnection: IZConnection;\nbegin\n  Result := FConnection;\nend;\n\n{**\n  Returns a name of the sequence generator.\n  @return a name of this sequence generator.\n}\nfunction TZAbstractSequence.GetName: string;\nbegin\n  Result := FName;\nend;\n\n{**\n  Returns the assigned block size for this sequence.\n  @return the assigned block size.\n}\nfunction TZAbstractSequence.GetBlockSize: Integer;\nbegin\n  Result := FBlockSize;\nend;\n\n{**\n  Gets the current unique key generated by this sequence.\n  @param the last generated unique key.\n}\nfunction TZAbstractSequence.GetCurrentValue: Int64;\nbegin\n  Result := 0;\nend;\n\n{\nfunction TZAbstractSequence.GetCurrentValueSQL: String;\nbegin\n result:='IMPLEMENT';\nend;\n}\n\n{**\n  Gets the next unique key generated by this sequence.\n  @param the next generated unique key.\n}\nfunction TZAbstractSequence.GetNextValue: Int64;\nbegin\n  Result := 0;\nend;\n\n{\nfunction TZAbstractSequence.GetNextValueSQL: String;\nbegin\n result:='IMPLEMENT';\nend;\n}\n\n{**\n  Sets the block size for this sequence.\n  @param Value the block size.\n}\nprocedure TZAbstractSequence.SetBlockSize(const Value: Integer);\nbegin\n  FBlockSize := Value;\nend;\n\n{**\n  Sets a name of the sequence generator.\n  @param Value a name of this sequence generator.\n}\nprocedure TZAbstractSequence.SetName(const Value: string);\nbegin\n  FName := Value;\nend;\n\nend.\n"
  },
  {
    "path": "lib/zeosdbo/src/dbc/ZDbcDbLib.pas",
    "content": "{*********************************************************}\n{                                                         }\n{                 Zeos Database Objects                   }\n{               DBLib Connectivity Classes                }\n{                                                         }\n{        Originally written by Janos Fegyverneki          }\n{                                                         }\n{*********************************************************}\n\n{@********************************************************}\n{    Copyright (c) 1999-2012 Zeos Development Group       }\n{                                                         }\n{ License Agreement:                                      }\n{                                                         }\n{ This library is distributed in the hope that it will be }\n{ useful, but WITHOUT ANY WARRANTY; without even the      }\n{ implied warranty of MERCHANTABILITY or FITNESS FOR      }\n{ A PARTICULAR PURPOSE.  See the GNU Lesser General       }\n{ Public License for more details.                        }\n{                                                         }\n{ The source code of the ZEOS Libraries and packages are  }\n{ distributed under the Library GNU General Public        }\n{ License (see the file COPYING / COPYING.ZEOS)           }\n{ with the following  modification:                       }\n{ As a special exception, the copyright holders of this   }\n{ library give you permission to link this library with   }\n{ independent modules to produce an executable,           }\n{ regardless of the license terms of these independent    }\n{ modules, and to copy and distribute the resulting       }\n{ executable under terms of your choice, provided that    }\n{ you also meet, for each linked independent module,      }\n{ the terms and conditions of the license of that module. }\n{ An independent module is a module which is not derived  }\n{ from or based on this library. If you modify this       }\n{ library, you may extend this exception to your version  }\n{ of the library, but you are not obligated to do so.     }\n{ If you do not wish to do so, delete this exception      }\n{ statement from your version.                            }\n{                                                         }\n{                                                         }\n{ The project web site is located on:                     }\n{   http://zeos.firmos.at  (FORUM)                        }\n{   http://sourceforge.net/p/zeoslib/tickets/ (BUGTRACKER)}\n{   svn://svn.code.sf.net/p/zeoslib/code-0/trunk (SVN)    }\n{                                                         }\n{   http://www.sourceforge.net/projects/zeoslib.          }\n{                                                         }\n{                                                         }\n{                                 Zeos Development Group. }\n{********************************************************@}\n\nunit ZDbcDbLib;\n\ninterface\n\n{$I ZDbc.inc}\n\nuses\n{$IFDEF FPC}\n  {$IFDEF WIN32}\n    Comobj,\n  {$ENDIF}\n{$ENDIF}\n  Types, Classes, {$IFDEF MSEgui}mclasses,{$ENDIF}\n  ZDbcConnection, ZDbcIntfs, ZCompatibility, ZDbcLogging, ZPlainDbLibDriver,\n  ZPlainDbLibConstants, ZTokenizer, ZGenericSqlAnalyser, ZURL, ZPlainDriver;\n\ntype\n  TDBLibProvider = (dpMsSQL, dpSybase);\n\n  {** Implements DBLib Database Driver. }\n  {$WARNINGS OFF}\n  TZDBLibDriver = class(TZAbstractDriver)\n  public\n    constructor Create; override;\n    function Connect(const Url: TZURL): IZConnection; override;\n    function GetMajorVersion: Integer; override;\n    function GetMinorVersion: Integer; override;\n\n    function GetTokenizer: IZTokenizer; override;\n    function GetStatementAnalyser: IZStatementAnalyser; override;\n  end;\n  {$WARNINGS ON}\n\n  {** Represents a DBLib specific connection interface. }\n  IZDBLibConnection = interface (IZConnection)\n    ['{6B0662A2-FF2A-4415-B6B0-AAC047EA0671}']\n\n    function FreeTDS: Boolean;\n    function GetProvider: TDBLibProvider;\n    function GetPlainDriver: IZDBLibPlainDriver;\n    function GetConnectionHandle: PDBPROCESS;\n    procedure InternalExecuteStatement(const SQL: string);\n    procedure CheckDBLibError(LogCategory: TZLoggingCategory; const LogMessage: string);\n  end;\n\n  {** Implements a generic DBLib Connection. }\n  TZDBLibConnection = class(TZAbstractConnection, IZDBLibConnection)\n  private\n    FProvider: TDBLibProvider;\n    FFreeTDS: Boolean;\n    function FreeTDS: Boolean;\n    function GetProvider: TDBLibProvider;\n    procedure ReStartTransactionSupport;\n    procedure InternalSetTransactionIsolation(Level: TZTransactIsolationLevel);\n    procedure DetermineMSDateFormat;\n    function DetermineMSServerCollation: String;\n    function DetermineMSServerCodePage(const Collation: String): Word;\n  protected\n    FHandle: PDBPROCESS;\n    procedure InternalCreate; override;\n    procedure InternalExecuteStatement(const SQL: string); virtual;\n    procedure InternalLogin; virtual;\n    function GetPlainDriver: IZDBLibPlainDriver;\n    function GetConnectionHandle: PDBPROCESS;\n    procedure CheckDBLibError(LogCategory: TZLoggingCategory; const LogMessage: string); virtual;\n    procedure StartTransaction; virtual;\n  public\n    function CreateRegularStatement(Info: TStrings): IZStatement; override;\n    function CreatePreparedStatement(const SQL: string; Info: TStrings):\n      IZPreparedStatement; override;\n    function CreateCallableStatement(const SQL: string; Info: TStrings):\n      IZCallableStatement; override;\n\n    function NativeSQL(const SQL: string): string; override;\n\n    procedure SetAutoCommit(AutoCommit: Boolean); override;\n    procedure SetTransactionIsolation(Level: TZTransactIsolationLevel); override;\n\n    procedure Commit; override;\n    procedure Rollback; override;\n\n    procedure Open; override;\n    procedure Close; override;\n\n    procedure SetReadOnly(ReadOnly: Boolean); override;\n\n    procedure SetCatalog(const Catalog: string); override;\n    function GetCatalog: string; override;\n\n    function GetWarnings: EZSQLWarning; override;\n    procedure ClearWarnings; override;\n    function GetBinaryEscapeString(const Value: TByteDynArray): String; overload; override;\n    function GetBinaryEscapeString(const Value: RawByteString): String; overload; override;\n  end;\n\nvar\n  {** The common driver manager object. }\n  DBLibDriver: IZDriver;\n\nimplementation\n\nuses\n  {$IFDEF WITH_UNITANSISTRINGS}AnsiStrings,{$ENDIF}\n  SysUtils, ZSysUtils, ZMessages, ZDbcUtils, ZDbcDbLibStatement, ZEncoding,\n  ZDbcDbLibMetadata, ZSybaseToken, ZSybaseAnalyser{$IFDEF FPC}, ZClasses{$ENDIF};\n\n{ TZDBLibDriver }\n\n{**\n  Constructs this object with default properties.\n}\nconstructor TZDBLibDriver.Create;\nbegin\n  inherited Create;\n  AddSupportedProtocol(AddPlainDriverToCache(TZDBLibMSSQL7PlainDriver.Create));\n  AddSupportedProtocol(AddPlainDriverToCache(TZDBLibSybaseASE125PlainDriver.Create));\n  AddSupportedProtocol(AddPlainDriverToCache(TZFreeTDS42MsSQLPlainDriver.Create));\n  AddSupportedProtocol(AddPlainDriverToCache(TZFreeTDS42SybasePlainDriver.Create));\n  AddSupportedProtocol(AddPlainDriverToCache(TZFreeTDS50PlainDriver.Create));\n  AddSupportedProtocol(AddPlainDriverToCache(TZFreeTDS70PlainDriver.Create));\n  AddSupportedProtocol(AddPlainDriverToCache(TZFreeTDS71PlainDriver.Create));\n  AddSupportedProtocol(AddPlainDriverToCache(TZFreeTDS72PlainDriver.Create));\nend;\n\n{**\n  Attempts to make a database connection to the given URL.\n}\n{$WARNINGS OFF}\nfunction TZDBLibDriver.Connect(const Url: TZURL): IZConnection;\nbegin\n  Result := TZDBLibConnection.Create(Url);\nend;\n{$WARNINGS ON}\n\n{**\n  Gets the driver's major version number. Initially this should be 1.\n  @return this driver's major version number\n}\nfunction TZDBLibDriver.GetMajorVersion: Integer;\nbegin\n  Result := 1;\nend;\n\n{**\n  Gets the driver's minor version number. Initially this should be 0.\n  @return this driver's minor version number\n}\nfunction TZDBLibDriver.GetMinorVersion: Integer;\nbegin\n  Result := 0;\nend;\n\n{**\n  Gets a SQL syntax tokenizer.\n  @returns a SQL syntax tokenizer object.\n}\nfunction TZDBLibDriver.GetTokenizer: IZTokenizer;\nbegin\n  if Tokenizer = nil then\n    Tokenizer := TZSybaseTokenizer.Create;\n  Result := Tokenizer;\nend;\n\n{**\n  Creates a statement analyser object.\n  @returns a statement analyser object.\n}\nfunction TZDBLibDriver.GetStatementAnalyser: IZStatementAnalyser;\nbegin\n  if Analyser = nil then\n    Analyser := TZSybaseStatementAnalyser.Create;\n  Result := Analyser;\nend;\n\n{ TZDBLibConnection }\n\n{**\n  Constructs this object and assignes the main properties.\n}\nprocedure TZDBLibConnection.InternalCreate;\nbegin\n  FDisposeCodePage := False;\n  if Pos('mssql', LowerCase(Url.Protocol)) > 0  then\n  begin\n    FMetadata := TZMsSqlDatabaseMetadata.Create(Self, Url);\n    FProvider := dpMsSQL;\n  end\n  else\n    if Pos('sybase', LowerCase(Url.Protocol)) > 0 then\n    begin\n      FMetadata := TZSybaseDatabaseMetadata.Create(Self, Url);\n      FProvider := dpSybase;\n    end\n    else\n      FMetadata := nil;\n  FFreeTDS := Pos('FreeTDS', Url.Protocol) > 0;\n\n  FHandle := nil;\nend;\n\n{**\n  Destroys this object and cleanups the memory.\n}\nfunction TZDBLibConnection.FreeTDS: Boolean;\nbegin\n  Result := FFreeTDS;\nend;\n\nfunction TZDBLibConnection.GetProvider: TDBLibProvider;\nbegin\n  Result := FProvider;\nend;\n\n{**\n  Executes simple statements internally.\n}\nprocedure TZDBLibConnection.InternalExecuteStatement(const SQL: string);\nvar\n  LSQL: string;\n  ASQL: RawByteString;\nbegin\n  FHandle := GetConnectionHandle;\n  if GetPlainDriver.dbCancel(FHandle) <> DBSUCCEED then\n    CheckDBLibError(lcExecute, SQL);\n  if FProvider = dpMsSQL then\n    LSQL := StringReplace(Sql, '\\'#13, '\\\\'#13, [rfReplaceAll])\n  else\n    LSQL := SQL;\n\n  ASQL := AnsiString(LSQL);\n    if GetPlainDriver.dbcmd(FHandle, PAnsiChar(ASQL)) <> DBSUCCEED then\n      CheckDBLibError(lcExecute, LSQL);\n  if GetPlainDriver.dbsqlexec(FHandle) <> DBSUCCEED then\n    CheckDBLibError(lcExecute, LSQL);\n  repeat\n    GetPlainDriver.dbresults(FHandle);\n    GetPlainDriver.dbcanquery(FHandle);\n  until GetPlainDriver.dbmorecmds(FHandle) = DBFAIL;\n  CheckDBLibError(lcExecute, LSQL);\n  DriverManager.LogMessage(lcExecute, PlainDriver.GetProtocol, LSQL);\nend;\n\n{**\n  Login procedure can be overriden for special settings.\n}\nprocedure TZDBLibConnection.InternalLogin;\nvar\n  Loginrec: PLOGINREC;\n  LogMessage: string;\n  S: string;\n  lLogFile  : String;\nbegin\n  LogMessage := Format('CONNECT TO \"%s\"', [HostName]);\n  LoginRec := GetPLainDriver.dbLogin;\n  try\n//Common parameters\n    S := Info.Values['workstation'];\n    if S <> '' then\n      GetPlainDriver.dbSetLHost(LoginRec, PAnsiChar(AnsiString(S)));\n\n    S := Info.Values['appname'];\n    if S <> '' then\n      GetPlainDriver.dbSetLApp(LoginRec, PAnsiChar(AnsiString(S)));\n\n    S := Info.Values['language'];\n    if S <> '' then\n      GetPlainDriver.dbSetLNatLang(LoginRec, PAnsiChar(AnsiString(S)));\n\n    S := Info.Values['timeout'];\n    if S <> '' then\n      GetPlainDriver.dbSetLoginTime(StrToIntDef(S, 60));\n\n    if FFreeTDS then\n    begin\n      if StrToBoolEx(Info.Values['log']) or StrToBoolEx(Info.Values['logging']) or\n         StrToBoolEx(Info.Values['tds_dump']) then begin\n           lLogFile := Info.Values['logfile'];\n           if lLogFile = '' then\n            lLogFile := Info.Values['log_file'];\n           if lLogFile = '' then\n            lLogFile := Info.Values['tds_dump_file'];\n           if lLogFile = '' then\n            lLogFile := ChangeFileExt(ParamStr(0), '.tdslog');\n           (GetPlainDriver as IZFreeTDSPlainDriver).tdsDump_Open(lLogFile);\n         end;\n    end;\n\n\n    //mssql specific parameters\n    if ( FProvider = dpMsSQL ) then\n    begin\n      if ( StrToBoolEx(Info.Values['NTAuth']) or StrToBoolEx(Info.Values['trusted'])\n        or StrToBoolEx(Info.Values['secure']) ) and ( not FFreeTDS ) then\n      begin\n        GetPlainDriver.dbsetlsecure(LoginRec);\n        LogMessage := LogMessage + ' USING WINDOWS AUTHENTICATION';\n      end\n      else\n      begin\n        GetPlainDriver.dbsetluser(LoginRec, PAnsiChar(AnsiString(User)));\n        GetPlainDriver.dbsetlpwd(LoginRec, PAnsiChar(AnsiString(Password)));\n        LogMessage := LogMessage + Format(' AS USER \"%s\"', [User]);\n      end;\n    end;\n\n    //sybase specific parameters\n    if FProvider = dpSybase then\n    begin\n      S := Info.Values['codepage'];\n      if S <> '' then\n        GetPlainDriver.dbSetLCharSet(LoginRec, PAnsiChar(ZPlainString(S)));\n      GetPlainDriver.dbsetluser(LoginRec, PAnsiChar(ZPlainString(User)));\n      GetPlainDriver.dbsetlpwd(LoginRec, PAnsiChar(ZPlainString(Password)));\n      LogMessage := LogMessage + Format(' AS USER \"%s\"', [User]);\n    end;\n\n    CheckDBLibError(lcConnect, LogMessage);\n    FHandle := GetPlainDriver.dbOpen(LoginRec, PAnsiChar(AnsiString(HostName)));\n    CheckDBLibError(lcConnect, LogMessage);\n    DriverManager.LogMessage(lcConnect, PlainDriver.GetProtocol, LogMessage);\n  finally\n    GetPLainDriver.dbLoginFree(LoginRec);\n  end;\nend;\n\nfunction TZDBLibConnection.GetPlainDriver: IZDBLibPlainDriver;\nbegin\n  Result := PlainDriver as IZDBLibPlainDriver;\nend;\n\nfunction TZDBLibConnection.GetConnectionHandle: PDBPROCESS;\nbegin\n  if FProvider = dpMsSQL then\n    if GetPlainDriver.dbDead(FHandle) then\n    begin\n      Closed := True;\n      Open;\n    end;\n  Result := FHandle;\nend;\n\nprocedure TZDBLibConnection.CheckDBLibError(LogCategory: TZLoggingCategory; const LogMessage: string);\nbegin\n  try\n    GetPlainDriver.CheckError(FHandle);\n  except\n    on E: Exception do\n    begin\n      DriverManager.LogError(LogCategory, PlainDriver.GetProtocol, LogMessage, 0, E.Message);\n      raise;\n    end;\n  end;\nend;\n\n{**\n  Starts a transaction support.\n}\nprocedure TZDBLibConnection.ReStartTransactionSupport;\nbegin\n  if Closed then\n    Exit;\n\n  if not (AutoCommit or (GetTransactionIsolation = tiNone)) then\n    StartTransaction;\nend;\n\n{**\n  Opens a connection to database server with specified parameters.\n}\nprocedure TZDBLibConnection.Open;\nvar\n  LogMessage: string;\nbegin\n   if not Closed then\n      Exit;\n\n  InternalLogin;\n\n  LogMessage := Format('USE %s', [Database]);\n  if FProvider = dpMsSQL then\n  begin\n    if GetPlainDriver.dbUse(FHandle, PAnsiChar(AnsiString(Database))) <> DBSUCCEED then\n      CheckDBLibError(lcConnect, LogMessage);\n  end\n  else\n    if GetPlainDriver.dbUse(FHandle, PAnsiChar(ZPlainString(Database))) <> DBSUCCEED then\n      CheckDBLibError(lcConnect, LogMessage);\n  DriverManager.LogMessage(lcConnect, PlainDriver.GetProtocol, LogMessage);\n\n  LogMessage := 'set textlimit=2147483647';\n  if GetPlainDriver.dbsetopt(FHandle, GetPlainDriver.GetVariables.dboptions[Z_TEXTLIMIT] , '2147483647') <> DBSUCCEED then\n    CheckDBLibError(lcConnect, LogMessage);\n  DriverManager.LogMessage(lcConnect, PlainDriver.GetProtocol, LogMessage);\n\n  InternalExecuteStatement('set textsize 2147483647 set quoted_identifier on');\n\n  inherited Open;\n\n  if FProvider = dpMsSQL then\n  begin\n    if FClientCodePage = '' then\n    begin\n      FDisposeCodePage := True;\n      ConSettings^.ClientCodePage := New(PZCodePage);\n      ConSettings^.ClientCodePage^.CP := ZDefaultSystemCodePage; //need a tempory CP for the SQL preparation\n      ConSettings^.ClientCodePage^.Encoding := ceAnsi;\n      ConSettings^.ClientCodePage^.Name := DetermineMSServerCollation;\n      ConSettings^.ClientCodePage^.IsStringFieldCPConsistent := True;\n      ConSettings^.ClientCodePage^.CP := DetermineMSServerCodePage(ConSettings^.ClientCodePage^.Name);\n      SetConvertFunctions(ConSettings);\n    end;\n    DetermineMSDateFormat;\n  end\n  else\n    ConSettings.DateFormat := 'yyyy/mm/dd';\n\n  InternalSetTransactionIsolation(GetTransactionIsolation);\n  ReStartTransactionSupport;\nend;\n\n{**\n  Creates a <code>Statement</code> object for sending\n  SQL statements to the database.\n  SQL statements without parameters are normally\n  executed using Statement objects. If the same SQL statement\n  is executed many times, it is more efficient to use a\n  <code>PreparedStatement</code> object.\n  <P>\n  Result sets created using the returned <code>Statement</code>\n  object will by default have forward-only type and read-only concurrency.\n\n  @return a new Statement object\n}\nfunction TZDBLibConnection.CreateRegularStatement(Info: TStrings):\n  IZStatement;\nbegin\n  if IsClosed then\n     Open;\n  Result := TZDBLibStatement.Create(Self, Info);\nend;\n\n{**\n  Creates a <code>PreparedStatement</code> object for sending\n  parameterized SQL statements to the database.\n\n  A SQL statement with or without IN parameters can be\n  pre-compiled and stored in a PreparedStatement object. This\n  object can then be used to efficiently execute this statement\n  multiple times.\n\n  <P><B>Note:</B> This method is optimized for handling\n  parametric SQL statements that benefit from precompilation. If\n  the driver supports precompilation,\n  the method <code>prepareStatement</code> will send\n  the statement to the database for precompilation. Some drivers\n  may not support precompilation. In this case, the statement may\n  not be sent to the database until the <code>PreparedStatement</code> is\n  executed.  This has no direct effect on users; however, it does\n  affect which method throws certain SQLExceptions.\n\n  Result sets created using the returned PreparedStatement will have\n  forward-only type and read-only concurrency, by default.\n\n  @param sql a SQL statement that may contain one or more '?' IN\n    parameter placeholders\n  @param Info a statement parameters.\n  @return a new PreparedStatement object containing the\n    pre-compiled statement\n}\nfunction TZDBLibConnection.CreatePreparedStatement(\n  const SQL: string; Info: TStrings): IZPreparedStatement;\nbegin\n  if IsClosed then\n     Open;\n  Result := TZDBLibPreparedStatementEmulated.Create(Self, SQL, Info);\nend;\n\n{**\n  Creates a <code>CallableStatement</code> object for calling\n  database stored procedures.\n  The <code>CallableStatement</code> object provides\n  methods for setting up its IN and OUT parameters, and\n  methods for executing the call to a stored procedure.\n\n  <P><B>Note:</B> This method is optimized for handling stored\n  procedure call statements. Some drivers may send the call\n  statement to the database when the method <code>prepareCall</code>\n  is done; others\n  may wait until the <code>CallableStatement</code> object\n  is executed. This has no\n  direct effect on users; however, it does affect which method\n  throws certain SQLExceptions.\n\n  Result sets created using the returned CallableStatement will have\n  forward-only type and read-only concurrency, by default.\n\n  @param sql a SQL statement that may contain one or more '?'\n    parameter placeholders. Typically this  statement is a JDBC\n    function call escape string.\n  @param Info a statement parameters.\n  @return a new CallableStatement object containing the\n    pre-compiled SQL statement\n}\nfunction TZDBLibConnection.CreateCallableStatement(\n  const SQL: string; Info: TStrings): IZCallableStatement;\nbegin\n  if IsClosed then\n     Open;\n  Result := TZDBLibCallableStatement.Create(Self, SQL, Info);\nend;\n\n{**\n  Converts the given SQL statement into the system's native SQL grammar.\n  A driver may convert the JDBC sql grammar into its system's\n  native SQL grammar prior to sending it; this method returns the\n  native form of the statement that the driver would have sent.\n\n  @param sql a SQL statement that may contain one or more '?'\n    parameter placeholders\n  @return the native form of this statement\n}\nfunction TZDBLibConnection.NativeSQL(const SQL: string): string;\nbegin\n  Result := SQL;\nend;\n\n{**\n  Sets this connection's auto-commit mode.\n  If a connection is in auto-commit mode, then all its SQL\n  statements will be executed and committed as individual\n  transactions.  Otherwise, its SQL statements are grouped into\n  transactions that are terminated by a call to either\n  the method <code>commit</code> or the method <code>rollback</code>.\n  By default, new connections are in auto-commit mode.\n\n  The commit occurs when the statement completes or the next\n  execute occurs, whichever comes first. In the case of\n  statements returning a ResultSet, the statement completes when\n  the last row of the ResultSet has been retrieved or the\n  ResultSet has been closed. In advanced cases, a single\n  statement may return multiple results as well as output\n  parameter values. In these cases the commit occurs when all results and\n  output parameter values have been retrieved.\n\n  @param autoCommit true enables auto-commit; false disables auto-commit.\n}\nprocedure TZDBLibConnection.SetAutoCommit(AutoCommit: Boolean);\nbegin\n  if GetAutoCommit = AutoCommit then  Exit;\n  if not Closed and AutoCommit then InternalExecuteStatement('commit');\n  inherited;\n  ReStartTransactionSupport;\nend;\n\nprocedure TZDBLibConnection.InternalSetTransactionIsolation(Level: TZTransactIsolationLevel);\nconst\n  IL: array[TZTransactIsolationLevel, 0..1] of string = (('READ COMMITTED', '1'), ('READ UNCOMMITTED', '0'), ('READ COMMITTED', '1'), ('REPEATABLE READ', '2'), ('SERIALIZABLE', '3'));\nvar\n  Index: Integer;\n  S: string;\nbegin\n  Index := -1;\n  if FProvider = dpMsSQL then Index := 0;\n  if FProvider = dpSybase then Index := 1;\n\n  S := 'SET TRANSACTION ISOLATION LEVEL ' + IL[GetTransactionIsolation, Index];\n  InternalExecuteStatement(S);\n  if not (AutoCommit) then\n    InternalExecuteStatement('BEGIN TRANSACTION');\nend;\n\nprocedure TZDBLibConnection.DetermineMSDateFormat;\nvar\n  Tmp: AnsiString;\nbegin\n  Tmp := 'SELECT dateformat FROM master.dbo.syslanguages WHERE name = @@LANGUAGE';\n  if (GetPlainDriver.dbcmd(FHandle, Pointer(Tmp)) <> DBSUCCEED) or\n     (GetPlainDriver.dbsqlexec(FHandle) <> DBSUCCEED) or\n     (GetPlainDriver.dbresults(FHandle) <> DBSUCCEED) or\n     (GetPlainDriver.dbcmdrow(FHandle) <> DBSUCCEED) or\n     (GetPlainDriver.dbnextrow(FHandle) <> REG_ROW) then\n    CheckDBLibError(lcOther, String(Tmp))\n  else\n    SetString(Tmp, PAnsiChar(GetPlainDriver.dbdata(FHandle, 1)),\n      GetPlainDriver.dbDatLen(FHandle, 1));\n  GetPlainDriver.dbCancel(FHandle);\n  ConSettings.DateFormat := String(Tmp);\n  if ConSettings.DateFormat = 'dmy' then\n    ConSettings.DateFormat := 'dd/mm/yyyy'\n  else if ConSettings.DateFormat = 'mdy' then\n    ConSettings.DateFormat := 'mm/dd/yyyy'\n  else\n    ConSettings.DateFormat := 'yyyy/mm/dd'\nend;\n\nfunction TZDBLibConnection.DetermineMSServerCollation: String;\nvar\n  Tmp: AnsiString;\nbegin\n  Tmp := 'SELECT DATABASEPROPERTYEX('+\n    {$IFDEF WITH_UNITANSISTRINGS}AnsiStrings.{$ENDIF}AnsiQuotedStr(AnsiString(DataBase), #39)+\n    ', ''Collation'') as DatabaseCollation';\n  if (GetPlainDriver.dbcmd(FHandle, Pointer(Tmp)) <> DBSUCCEED) or\n     (GetPlainDriver.dbsqlexec(FHandle) <> DBSUCCEED) or\n     (GetPlainDriver.dbresults(FHandle) <> DBSUCCEED) or\n     (GetPlainDriver.dbcmdrow(FHandle) <> DBSUCCEED) or\n     (GetPlainDriver.dbnextrow(FHandle) <> REG_ROW) then\n    CheckDBLibError(lcOther, String(Tmp))\n  else\n    ZSetString(PAnsiChar(GetPlainDriver.dbdata(FHandle, 1)), GetPlainDriver.dbDatLen(FHandle, 1), Tmp);\n  GetPlainDriver.dbCancel(FHandle);\n  Result := String(Tmp);\nend;\n\nfunction TZDBLibConnection.DetermineMSServerCodePage(const Collation: String): Word;\nvar\n  Tmp: AnsiString;\nbegin\n  Result := High(Word);\n  Tmp := 'SELECT COLLATIONPROPERTY('+\n    {$IFDEF WITH_UNITANSISTRINGS}AnsiStrings.{$ENDIF}AnsiQuotedStr(\n      AnsiString(Collation), #39)+\n    ', ''Codepage'') as Codepage';\n  if (GetPlainDriver.dbcmd(FHandle, Pointer(Tmp)) <> DBSUCCEED) or\n     (GetPlainDriver.dbsqlexec(FHandle) <> DBSUCCEED) or\n     (GetPlainDriver.dbresults(FHandle) <> DBSUCCEED) or\n     (GetPlainDriver.dbcmdrow(FHandle) <> DBSUCCEED) or\n     (GetPlainDriver.dbnextrow(FHandle) <> REG_ROW) then\n    CheckDBLibError(lcOther, String(Tmp))\n  else\n  begin\n    ZSetString(PAnsiChar(GetPlainDriver.dbdata(FHandle, 1)), GetPlainDriver.dbDatLen(FHandle, 1), Tmp);\n    Result := StrToInt(String(Tmp));\n  end;\n  GetPlainDriver.dbCancel(FHandle);\nend;\n\n{**\n  Attempts to change the transaction isolation level to the one given.\n  The constants defined in the interface <code>Connection</code>\n  are the possible transaction isolation levels.\n\n  <P><B>Note:</B> This method cannot be called while\n  in the middle of a transaction.\n\n  @param level one of the TRANSACTION_* isolation values with the\n    exception of TRANSACTION_NONE; some databases may not support other values\n  @see DatabaseMetaData#supportsTransactionIsolationLevel\n}\nprocedure TZDBLibConnection.SetTransactionIsolation(\n  Level: TZTransactIsolationLevel);\nbegin\n  if GetTransactionIsolation = Level then\n    Exit;\n\n  if not Closed and not AutoCommit and (GetTransactionIsolation <> tiNone) then\n    InternalExecuteStatement('commit');\n\n  inherited;\n\n  if not Closed then\n    InternalSetTransactionIsolation(Level);\n\n  RestartTransactionSupport;\nend;\n\n{**\n  Starts a new transaction. Used internally.\n}\nprocedure TZDBLibConnection.StartTransaction;\nbegin\n  InternalExecuteStatement('begin transaction');\nend;\n\n{**\n  Makes all changes made since the previous\n  commit/rollback permanent and releases any database locks\n  currently held by the Connection. This method should be\n  used only when auto-commit mode has been disabled.\n  @see #setAutoCommit\n}\nprocedure TZDBLibConnection.Commit;\nbegin\n  if AutoCommit then\n    raise Exception.Create(SCannotUseCommit);\n  InternalExecuteStatement('commit');\n  StartTransaction;\nend;\n\n{**\n  Drops all changes made since the previous\n  commit/rollback and releases any database locks currently held\n  by this Connection. This method should be used only when auto-\n  commit has been disabled.\n  @see #setAutoCommit\n}\nprocedure TZDBLibConnection.Rollback;\nbegin\n  if AutoCommit then\n    raise Exception.Create(SCannotUseRollBack);\n  InternalExecuteStatement('rollback');\n  StartTransaction;\nend;\n\n{**\n  Releases a Connection's database and JDBC resources\n  immediately instead of waiting for\n  them to be automatically released.\n\n  <P><B>Note:</B> A Connection is automatically closed when it is\n  garbage collected. Certain fatal errors also result in a closed\n  Connection.\n}\nprocedure TZDBLibConnection.Close;\nvar\n  LogMessage: string;\nbegin\n  if Closed then\n    Exit;\n  if  Assigned(PlainDriver) then\n  begin\n  if not GetPlainDriver.dbDead(FHandle) then\n    InternalExecuteStatement('if @@trancount > 0 rollback');\n\n  LogMessage := Format('CLOSE CONNECTION TO \"%s\" DATABASE \"%s\"', [HostName, Database]);\n\n  if GetPlainDriver.dbclose(FHandle) <> DBSUCCEED then\n    CheckDBLibError(lcDisConnect, LogMessage);\n  DriverManager.LogMessage(lcDisconnect, PlainDriver.GetProtocol, LogMessage);\n  end;\n  FHandle := nil;\n  inherited;\nend;\n\n{**\n  Puts this connection in read-only mode as a hint to enable\n  database optimizations.\n\n  <P><B>Note:</B> This method cannot be called while in the\n  middle of a transaction.\n\n  @param readOnly true enables read-only mode; false disables\n    read-only mode.\n}\nprocedure TZDBLibConnection.SetReadOnly(ReadOnly: Boolean);\nbegin\n{ TODO -ofjanos -cAPI : I think it is not supported in this way }\n  inherited;\nend;\n\n{**\n  Sets a catalog name in order to select\n  a subspace of this Connection's database in which to work.\n  If the driver does not support catalogs, it will\n  silently ignore this request.\n}\nprocedure TZDBLibConnection.SetCatalog(const Catalog: string);\nvar\n  LogMessage: string;\nbegin\n  if (Catalog <> '') and not Closed then\n  begin\n    LogMessage := Format('SET CATALOG %s', [Catalog]);\n    if FProvider = dpMsSQL then\n    begin\n      if GetPLainDriver.dbUse(FHandle, PAnsiChar(AnsiString(Catalog))) <> DBSUCCEED then\n        CheckDBLibError(lcOther, LogMessage);\n    end\n    else\n      if GetPLainDriver.dbUse(FHandle, PAnsiChar(ZPlainString(Catalog))) <> DBSUCCEED then\n        CheckDBLibError(lcOther, LogMessage);\n    DriverManager.LogMessage(lcOther, PLainDriver.GetProtocol, LogMessage);\n  end;\nend;\n\n{**\n  Returns the Connection's current catalog name.\n  @return the current catalog name or null\n}\nfunction TZDBLibConnection.GetCatalog: string;\nbegin\n  Result := String(GetPlainDriver.dbName(FHandle));\n  CheckDBLibError(lcOther, 'GETCATALOG');\nend;\n\n{**\n  Returns the first warning reported by calls on this Connection.\n  <P><B>Note:</B> Subsequent warnings will be chained to this\n  SQLWarning.\n  @return the first SQLWarning or null\n}\nfunction TZDBLibConnection.GetWarnings: EZSQLWarning;\nbegin\n  Result := nil;\nend;\n\n{**\n  Clears all warnings reported for this <code>Connection</code> object.\n  After a call to this method, the method <code>getWarnings</code>\n    returns null until a new warning is reported for this Connection.\n}\nprocedure TZDBLibConnection.ClearWarnings;\nvar\n  LogMessage: string;\nbegin\n  if Closed then\n    Exit;\n\n  if not GetPlainDriver.dbDead(FHandle) then\n    InternalExecuteStatement('if @@trancount > 0 rollback');\n\n  LogMessage := Format('CLOSE CONNECTION TO \"%s\" DATABASE \"%s\"', [HostName, Database]);\n  if GetPlainDriver.dbclose(FHandle) <> DBSUCCEED then\n    CheckDBLibError(lcDisConnect, LogMessage);\n  DriverManager.LogMessage(lcDisconnect, GetPlainDriver.GetProtocol, LogMessage);\n\n  FHandle := nil;\n  inherited;\nend;\n\nfunction TZDBLibConnection.GetBinaryEscapeString(const Value: TByteDynArray): String;\nbegin\n  Result := GetSQLHexString(PAnsiChar(Value), Length(Value), True);\n  if GetAutoEncodeStrings then\n    Result := GetDriver.GetTokenizer.GetEscapeString(Result)\nend;\n\nfunction TZDBLibConnection.GetBinaryEscapeString(const Value: RawByteString): String;\nbegin\n  Result := GetSQLHexString(PAnsiChar(Value), Length(Value), True);\n  if GetAutoEncodeStrings then\n    Result := GetDriver.GetTokenizer.GetEscapeString(Result)\nend;\n\n\ninitialization\n  DBLibDriver := TZDBLibDriver.Create;\n  DriverManager.RegisterDriver(DBLibDriver);\nfinalization\n  if Assigned(DriverManager) then\n    DriverManager.DeregisterDriver(DBLibDriver);\n  DBLibDriver := nil;\nend.\n"
  },
  {
    "path": "lib/zeosdbo/src/dbc/ZDbcDbLibMetadata.pas",
    "content": "{*********************************************************}\n{                                                         }\n{                 Zeos Database Objects                   }\n{           MsSql Database metadata information           }\n{                                                         }\n{        Originally written by Janos Fegyverneki          }\n{                                                         }\n{*********************************************************}\n\n{@********************************************************}\n{    Copyright (c) 1999-2012 Zeos Development Group       }\n{                                                         }\n{ License Agreement:                                      }\n{                                                         }\n{ This library is distributed in the hope that it will be }\n{ useful, but WITHOUT ANY WARRANTY; without even the      }\n{ implied warranty of MERCHANTABILITY or FITNESS FOR      }\n{ A PARTICULAR PURPOSE.  See the GNU Lesser General       }\n{ Public License for more details.                        }\n{                                                         }\n{ The source code of the ZEOS Libraries and packages are  }\n{ distributed under the Library GNU General Public        }\n{ License (see the file COPYING / COPYING.ZEOS)           }\n{ with the following  modification:                       }\n{ As a special exception, the copyright holders of this   }\n{ library give you permission to link this library with   }\n{ independent modules to produce an executable,           }\n{ regardless of the license terms of these independent    }\n{ modules, and to copy and distribute the resulting       }\n{ executable under terms of your choice, provided that    }\n{ you also meet, for each linked independent module,      }\n{ the terms and conditions of the license of that module. }\n{ An independent module is a module which is not derived  }\n{ from or based on this library. If you modify this       }\n{ library, you may extend this exception to your version  }\n{ of the library, but you are not obligated to do so.     }\n{ If you do not wish to do so, delete this exception      }\n{ statement from your version.                            }\n{                                                         }\n{                                                         }\n{ The project web site is located on:                     }\n{   http://zeos.firmos.at  (FORUM)                        }\n{   http://sourceforge.net/p/zeoslib/tickets/ (BUGTRACKER)}\n{   svn://svn.code.sf.net/p/zeoslib/code-0/trunk (SVN)    }\n{                                                         }\n{   http://www.sourceforge.net/projects/zeoslib.          }\n{                                                         }\n{                                                         }\n{                                 Zeos Development Group. }\n{********************************************************@}\n\nunit ZDbcDbLibMetadata;\n\ninterface\n\n{$I ZDbc.inc}\n\nuses\n  Types, Classes, SysUtils, ZSysUtils, ZDbcIntfs, ZDbcMetadata, ZURL,\n  ZCompatibility, ZDbcConnection, ZSelectSchema;\n\ntype\n\n  // technobot 2008-06-25 - methods moved as is from TZDbLibBaseDatabaseMetadata:\n  {** Implements MsSql Database Information. }\n  TZDbLibDatabaseInfo = class(TZAbstractDatabaseInfo)\n  public\n\n    // database/driver/server info:\n    function GetDatabaseProductName: string; override;\n    function GetDatabaseProductVersion: string; override;\n    function GetDriverName: string; override;\n//    function GetDriverVersion: string; override; -> Same as parent\n    function GetDriverMajorVersion: Integer; override;\n    function GetDriverMinorVersion: Integer; override;\n//    function GetServerVersion: string; -> Not implemented\n\n    // capabilities (what it can/cannot do):\n//    function AllProceduresAreCallable: Boolean; override; -> Not implemented\n//    function AllTablesAreSelectable: Boolean; override; -> Not implemented\n    function SupportsMixedCaseIdentifiers: Boolean; override;\n    function SupportsMixedCaseQuotedIdentifiers: Boolean; override;\n//    function SupportsAlterTableWithAddColumn: Boolean; override; -> Not implemented\n//    function SupportsAlterTableWithDropColumn: Boolean; override; -> Not implemented\n//    function SupportsColumnAliasing: Boolean; override; -> Not implemented\n//    function SupportsConvert: Boolean; override; -> Not implemented\n//    function SupportsConvertForTypes(FromType: TZSQLType; ToType: TZSQLType):\n//      Boolean; override; -> Not implemented\n//    function SupportsTableCorrelationNames: Boolean; override; -> Not implemented\n//    function SupportsDifferentTableCorrelationNames: Boolean; override; -> Not implemented\n    function SupportsExpressionsInOrderBy: Boolean; override;\n    function SupportsOrderByUnrelated: Boolean; override;\n    function SupportsGroupBy: Boolean; override;\n    function SupportsGroupByUnrelated: Boolean; override;\n    function SupportsGroupByBeyondSelect: Boolean; override;\n//    function SupportsLikeEscapeClause: Boolean; override; -> Not implemented\n//    function SupportsMultipleResultSets: Boolean; override; -> Not implemented\n//    function SupportsMultipleTransactions: Boolean; override; -> Not implemented\n//    function SupportsNonNullableColumns: Boolean; override; -> Not implemented\n//    function SupportsMinimumSQLGrammar: Boolean; override; -> Not implemented\n//    function SupportsCoreSQLGrammar: Boolean; override; -> Not implemented\n//    function SupportsExtendedSQLGrammar: Boolean; override; -> Not implemented\n//    function SupportsANSI92EntryLevelSQL: Boolean; override; -> Not implemented\n//    function SupportsANSI92IntermediateSQL: Boolean; override; -> Not implemented\n//    function SupportsANSI92FullSQL: Boolean; override; -> Not implemented\n    function SupportsIntegrityEnhancementFacility: Boolean; override;\n//    function SupportsOuterJoins: Boolean; override; -> Not implemented\n//    function SupportsFullOuterJoins: Boolean; override; -> Not implemented\n//    function SupportsLimitedOuterJoins: Boolean; override; -> Not implemented\n    function SupportsSchemasInDataManipulation: Boolean; override;\n    function SupportsSchemasInProcedureCalls: Boolean; override;\n    function SupportsSchemasInTableDefinitions: Boolean; override;\n    function SupportsSchemasInIndexDefinitions: Boolean; override;\n    function SupportsSchemasInPrivilegeDefinitions: Boolean; override;\n    function SupportsCatalogsInDataManipulation: Boolean; override;\n    function SupportsCatalogsInProcedureCalls: Boolean; override;\n    function SupportsCatalogsInTableDefinitions: Boolean; override;\n    function SupportsCatalogsInIndexDefinitions: Boolean; override;\n    function SupportsCatalogsInPrivilegeDefinitions: Boolean; override;\n    function SupportsPositionedDelete: Boolean; override;\n    function SupportsPositionedUpdate: Boolean; override;\n    function SupportsSelectForUpdate: Boolean; override;\n    function SupportsStoredProcedures: Boolean; override;\n    function SupportsSubqueriesInComparisons: Boolean; override;\n    function SupportsSubqueriesInExists: Boolean; override;\n    function SupportsSubqueriesInIns: Boolean; override;\n    function SupportsSubqueriesInQuantifieds: Boolean; override;\n    function SupportsCorrelatedSubqueries: Boolean; override;\n    function SupportsUnion: Boolean; override;\n    function SupportsUnionAll: Boolean; override;\n    function SupportsOpenCursorsAcrossCommit: Boolean; override;\n    function SupportsOpenCursorsAcrossRollback: Boolean; override;\n    function SupportsOpenStatementsAcrossCommit: Boolean; override;\n    function SupportsOpenStatementsAcrossRollback: Boolean; override;\n    function SupportsTransactions: Boolean; override;\n    function SupportsTransactionIsolationLevel(Level: TZTransactIsolationLevel):\n      Boolean; override;\n    function SupportsDataDefinitionAndDataManipulationTransactions: Boolean; override;\n    function SupportsDataManipulationTransactionsOnly: Boolean; override;\n    function SupportsResultSetType(_Type: TZResultSetType): Boolean; override;\n    function SupportsResultSetConcurrency(_Type: TZResultSetType;\n      Concurrency: TZResultSetConcurrency): Boolean; override;\n//    function SupportsBatchUpdates: Boolean; override; -> Not implemented\n\n    // maxima:\n    function GetMaxBinaryLiteralLength: Integer; override;\n    function GetMaxCharLiteralLength: Integer; override;\n    function GetMaxColumnNameLength: Integer; override;\n    function GetMaxColumnsInGroupBy: Integer; override;\n    function GetMaxColumnsInIndex: Integer; override;\n    function GetMaxColumnsInOrderBy: Integer; override;\n    function GetMaxColumnsInSelect: Integer; override;\n    function GetMaxColumnsInTable: Integer; override;\n    function GetMaxConnections: Integer; override;\n    function GetMaxCursorNameLength: Integer; override;\n    function GetMaxIndexLength: Integer; override;\n    function GetMaxSchemaNameLength: Integer; override;\n    function GetMaxProcedureNameLength: Integer; override;\n    function GetMaxCatalogNameLength: Integer; override;\n    function GetMaxRowSize: Integer; override;\n    function GetMaxStatementLength: Integer; override;\n    function GetMaxStatements: Integer; override;\n    function GetMaxTableNameLength: Integer; override;\n    function GetMaxTablesInSelect: Integer; override;\n    function GetMaxUserNameLength: Integer; override;\n\n    // policies (how are various data and operations handled):\n//    function IsReadOnly: Boolean; override; -> Not implemented\n//    function IsCatalogAtStart: Boolean; override; -> Not implemented\n    function DoesMaxRowSizeIncludeBlobs: Boolean; override;\n//    function NullsAreSortedHigh: Boolean; override; -> Not implemented\n//    function NullsAreSortedLow: Boolean; override; -> Not implemented\n//    function NullsAreSortedAtStart: Boolean; override; -> Not implemented\n//    function NullsAreSortedAtEnd: Boolean; override; -> Not implemented\n//    function NullPlusNonNullIsNull: Boolean; override; -> Not implemented\n//    function UsesLocalFiles: Boolean; override; -> Not implemented\n    function UsesLocalFilePerTable: Boolean; override;\n    function StoresUpperCaseIdentifiers: Boolean; override;\n    function StoresLowerCaseIdentifiers: Boolean; override;\n    function StoresMixedCaseIdentifiers: Boolean; override;\n    function StoresUpperCaseQuotedIdentifiers: Boolean; override;\n    function StoresLowerCaseQuotedIdentifiers: Boolean; override;\n    function StoresMixedCaseQuotedIdentifiers: Boolean; override;\n    function GetDefaultTransactionIsolation: TZTransactIsolationLevel; override;\n    function DataDefinitionCausesTransactionCommit: Boolean; override;\n    function DataDefinitionIgnoredInTransactions: Boolean; override;\n\n    // interface details (terms, keywords, etc):\n    function GetSchemaTerm: string; override;\n    function GetProcedureTerm: string; override;\n    function GetCatalogTerm: string; override;\n    function GetCatalogSeparator: string; override;\n    function GetSQLKeywords: string; override;\n    function GetNumericFunctions: string; override;\n    function GetStringFunctions: string; override;\n    function GetSystemFunctions: string; override;\n    function GetTimeDateFunctions: string; override;\n    function GetSearchStringEscape: string; override;\n    function GetExtraNameCharacters: string; override;\n  end;\n\n  TZMsSqlDatabaseInfo = class(TZDbLibDatabaseInfo)\n    // database/driver/server info:\n    function GetDatabaseProductName: string; override;\n    function GetDatabaseProductVersion: string; override;\n    function GetDriverName: string; override;\n  end;\n\n  TZSybaseDatabaseInfo = class(TZDbLibDatabaseInfo)\n    // database/driver/server info:\n    function GetDatabaseProductName: string; override;\n    function GetDatabaseProductVersion: string; override;\n    function GetDriverName: string; override;\n  end;\n\n  {** Implements DbLib Database Metadata. }\n  TZDbLibBaseDatabaseMetadata = class(TZAbstractDatabaseMetadata)\n  protected\n    function ComposeObjectString(const S: String; Const NullText: String = 'null';\n      QuoteChar: Char = #39): String;\n    function DecomposeObjectString(const S: String): String; override;\n    function CreateDatabaseInfo: IZDatabaseInfo; override; // technobot 2008-06-25\n\n    function UncachedGetImportedKeys(const Catalog: string; const Schema: string;\n      const Table: string): IZResultSet; override;\n    function UncachedGetExportedKeys(const Catalog: string; const Schema: string;\n      const Table: string): IZResultSet; override;\n  end;\n\n  {** Implements MsSql Database Metadata. }\n  TZMsSqlDatabaseMetadata = class(TZDbLibBaseDatabaseMetadata)\n  protected\n    function CreateDatabaseInfo: IZDatabaseInfo; override; // technobot 2008-06-25\n\n    function UncachedGetTables(const Catalog: string; const SchemaPattern: string;\n      const TableNamePattern: string; const Types: TStringDynArray): IZResultSet; override;\n    function UncachedGetSchemas: IZResultSet; override;\n    function UncachedGetCatalogs: IZResultSet; override;\n    function UncachedGetTableTypes: IZResultSet; override;\n    function UncachedGetColumns(const Catalog: string; const SchemaPattern: string;\n      const TableNamePattern: string; const ColumnNamePattern: string): IZResultSet; override;\n    function UncachedGetTablePrivileges(const Catalog: string; const SchemaPattern: string;\n      const TableNamePattern: string): IZResultSet; override;\n    function UncachedGetColumnPrivileges(const Catalog: string; const Schema: string;\n      const Table: string; const ColumnNamePattern: string): IZResultSet; override;\n    function UncachedGetPrimaryKeys(const Catalog: string; const Schema: string;\n      const Table: string): IZResultSet; override;\n    function UncachedGetCrossReference(const PrimaryCatalog: string; const PrimarySchema: string;\n      const PrimaryTable: string; const ForeignCatalog: string; const ForeignSchema: string;\n      const ForeignTable: string): IZResultSet; override;\n    function UncachedGetIndexInfo(const Catalog: string; const Schema: string; const Table: string;\n      Unique: Boolean; Approximate: Boolean): IZResultSet; override;\n    function UncachedGetProcedures(const Catalog: string; const SchemaPattern: string;\n      const ProcedureNamePattern: string): IZResultSet; override;\n    function UncachedGetProcedureColumns(const Catalog: string; const SchemaPattern: string;\n      const ProcedureNamePattern: string; const ColumnNamePattern: string):\n      IZResultSet; override;\n    function UncachedGetVersionColumns(const Catalog: string; const Schema: string;\n      const Table: string): IZResultSet; override;\n    function UncachedGetTypeInfo: IZResultSet; override;\n  end;\n\n  {** Implements Sybase Database Metadata. }\n  TZSybaseDatabaseMetadata = class(TZDbLibBaseDatabaseMetadata)\n  protected\n    function CreateDatabaseInfo: IZDatabaseInfo; override; // technobot 2008-06-25\n\n    function UncachedGetTables(const Catalog: string; const SchemaPattern: string;\n      const TableNamePattern: string; const Types: TStringDynArray): IZResultSet; override;\n    function UncachedGetSchemas: IZResultSet; override;\n    function UncachedGetCatalogs: IZResultSet; override;\n    function UncachedGetTableTypes: IZResultSet; override;\n    function UncachedGetColumns(const Catalog: string; const SchemaPattern: string;\n      const TableNamePattern: string; const ColumnNamePattern: string): IZResultSet; override;\n    function UncachedGetTablePrivileges(const Catalog: string; const SchemaPattern: string;\n      const TableNamePattern: string): IZResultSet; override;\n    function UncachedGetColumnPrivileges(const Catalog: string; const Schema: string;\n      const Table: string; const ColumnNamePattern: string): IZResultSet; override;\n    function UncachedGetPrimaryKeys(const Catalog: string; const Schema: string;\n      const Table: string): IZResultSet; override;\n    function UncachedGetImportedKeys(const Catalog: string; const Schema: string;\n      const Table: string): IZResultSet; override;\n    function UncachedGetExportedKeys(const Catalog: string; const Schema: string;\n      const Table: string): IZResultSet; override;\n    function UncachedGetCrossReference(const PrimaryCatalog: string; const PrimarySchema: string;\n      const PrimaryTable: string; const ForeignCatalog: string; const ForeignSchema: string;\n      const ForeignTable: string): IZResultSet; override;\n    function UncachedGetIndexInfo(const Catalog: string; const Schema: string; const Table: string;\n      Unique: Boolean; Approximate: Boolean): IZResultSet; override;\n    function UncachedGetProcedures(const Catalog: string; const SchemaPattern: string;\n      const ProcedureNamePattern: string): IZResultSet; override;\n    function UncachedGetProcedureColumns(const Catalog: string; const SchemaPattern: string;\n      const ProcedureNamePattern: string; const ColumnNamePattern: string):\n      IZResultSet; override;\n    function UncachedGetVersionColumns(const Catalog: string; const Schema: string;\n      const Table: string): IZResultSet; override;\n    function UncachedGetTypeInfo: IZResultSet; override;\n    function UncachedGetUDTs(const Catalog: string; const SchemaPattern: string;\n      const TypeNamePattern: string; const Types: TIntegerDynArray): IZResultSet; override;\n  end;\n\nimplementation\n\nuses ZDbcUtils, ZDbcDbLibUtils;\n\n{ TZDbLibDatabaseInfo }\n\n{**\n//----------------------------------------------------------------------\n// First, a variety of minor information about the target database.\n\n{**\n  What's the name of this database product?\n  @return database product name\n}\nfunction TZDbLibDatabaseInfo.GetDatabaseProductName: string;\nbegin\n  Result := '';\nend;\n\n{**\n  What's the version of this database product?\n  @return database version\n}\nfunction TZDbLibDatabaseInfo.GetDatabaseProductVersion: string;\nbegin\n  Result := '';\nend;\n\n{**\n  What's the name of this JDBC driver?\n  @return JDBC driver name\n}\nfunction TZDbLibDatabaseInfo.GetDriverName: string;\nbegin\n  Result := 'Zeos Abstract Database Connectivity Driver for DbLib Server';\nend;\n\n{**\n  What's this JDBC driver's major version number?\n  @return JDBC driver major version\n}\nfunction TZDbLibDatabaseInfo.GetDriverMajorVersion: Integer;\nbegin\n  Result := 1;\nend;\n\n{**\n  What's this JDBC driver's minor version number?\n  @return JDBC driver minor version number\n}\nfunction TZDbLibDatabaseInfo.GetDriverMinorVersion: Integer;\nbegin\n  Result := 0;\nend;\n\n{**\n  Does the database use a file for each table?\n  @return true if the database uses a local file for each table\n}\nfunction TZDbLibDatabaseInfo.UsesLocalFilePerTable: Boolean;\nbegin\n  Result := False;\nend;\n\n{**\n  Does the database treat mixed case unquoted SQL identifiers as\n  case sensitive and as a result store them in mixed case?\n  A JDBC Compliant<sup><font size=-2>TM</font></sup> driver will\n  always return false.\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZDbLibDatabaseInfo.SupportsMixedCaseIdentifiers: Boolean;\nbegin\n  Result := False;\nend;\n\n{**\n  Does the database treat mixed case unquoted SQL identifiers as\n  case insensitive and store them in upper case?\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZDbLibDatabaseInfo.StoresUpperCaseIdentifiers: Boolean;\nbegin\n  Result := True;\nend;\n\n{**\n  Does the database treat mixed case unquoted SQL identifiers as\n  case insensitive and store them in lower case?\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZDbLibDatabaseInfo.StoresLowerCaseIdentifiers: Boolean;\nbegin\n  Result := True;\nend;\n\n{**\n  Does the database treat mixed case unquoted SQL identifiers as\n  case insensitive and store them in mixed case?\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZDbLibDatabaseInfo.StoresMixedCaseIdentifiers: Boolean;\nbegin\n  Result := True;\nend;\n\n{**\n  Does the database treat mixed case quoted SQL identifiers as\n  case sensitive and as a result store them in mixed case?\n  A JDBC Compliant<sup><font size=-2>TM</font></sup> driver will always return true.\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZDbLibDatabaseInfo.SupportsMixedCaseQuotedIdentifiers: Boolean;\nbegin\n  Result := True;\nend;\n\n{**\n  Does the database treat mixed case quoted SQL identifiers as\n  case insensitive and store them in upper case?\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZDbLibDatabaseInfo.StoresUpperCaseQuotedIdentifiers: Boolean;\nbegin\n  Result := True;\nend;\n\n{**\n  Does the database treat mixed case quoted SQL identifiers as\n  case insensitive and store them in lower case?\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZDbLibDatabaseInfo.StoresLowerCaseQuotedIdentifiers: Boolean;\nbegin\n  Result := True;\nend;\n\n{**\n  Does the database treat mixed case quoted SQL identifiers as\n  case insensitive and store them in mixed case?\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZDbLibDatabaseInfo.StoresMixedCaseQuotedIdentifiers: Boolean;\nbegin\n  Result := True;\nend;\n\n{**\n  Gets a comma-separated list of all a database's SQL keywords\n  that are NOT also SQL92 keywords.\n  @return the list\n}\nfunction TZDbLibDatabaseInfo.GetSQLKeywords: string;\nbegin\n  { TODO -ofjanos -cAPI : SQL Keywords that are not SQL92 compliant }\n  Result := '';\nend;\n\n{**\n  Gets a comma-separated list of math functions.  These are the\n  X/Open CLI math function names used in the JDBC function escape\n  clause.\n  @return the list\n}\nfunction TZDbLibDatabaseInfo.GetNumericFunctions: string;\nbegin\n  Result := 'ABS,ACOS,ASIN,ATAN,ATN2,CEILING,COS,COT,DEGREES,EXP,FLOOR,LOG,LOG10,'+\n            'PI,POWER,RADIANS,RAND,ROUND,SIGN,SIN,SQUARE,SQRT,TAN';\nend;\n\n{**\n  Gets a comma-separated list of string functions.  These are the\n  X/Open CLI string function names used in the JDBC function escape\n  clause.\n  @return the list\n}\nfunction TZDbLibDatabaseInfo.GetStringFunctions: string;\nbegin\n  Result := 'ASCII,CHAR,CHARINDEX,DIFFERENCE,LEFT,LEN,LOWER,LTRIM,NCHAR,PATINDEX,'+\n            'REPLACE,QUOTENAME,REPLICATE,REVERSE,RIGHT,RTRIM,SOUNDEX,SPACE,STR,'+\n            'STUFF,SUBSTRING,UNICODE,UPPER';\nend;\n\n{**\n  Gets a comma-separated list of system functions.  These are the\n  X/Open CLI system function names used in the JDBC function escape\n  clause.\n  @return the list\n}\nfunction TZDbLibDatabaseInfo.GetSystemFunctions: string;\nbegin\n  Result := 'APP_NAME,CASE,CAST,CONVERT,COALESCE,CURRENT_TIMESTAMP,CURRENT_USER,'+\n            'DATALENGTH,@@ERROR,FORMATMESSAGE,GETANSINULL,HOST_ID,HOST_NAME,'+\n            'IDENT_INCR,IDENT_SEED,@@IDENTITY,IDENTITY,ISDATE,ISNULL,ISNUMERIC,'+\n            'NEWID,NULLIF,PARSENAME,PERMISSIONS,@@ROWCOUNT,SESSION_USER,STATS_DATE,'+\n            'SYSTEM_USER,@@TRANCOUNT,USER_NAME';\nend;\n\n{**\n  Gets a comma-separated list of time and date functions.\n  @return the list\n}\nfunction TZDbLibDatabaseInfo.GetTimeDateFunctions: string;\nbegin\n  Result := 'DATEADD,DATEDIFF,DATENAME,DATEPART,DAY,GETDATE,MONTH,YEAR';\nend;\n\n{**\n  Gets the string that can be used to escape wildcard characters.\n  This is the string that can be used to escape '_' or '%' in\n  the string pattern style catalog search parameters.\n\n  <P>The '_' character represents any single character.\n  <P>The '%' character represents any sequence of zero or\n  more characters.\n\n  @return the string used to escape wildcard characters\n}\nfunction TZDbLibDatabaseInfo.GetSearchStringEscape: string;\nbegin\n{ TODO -ofjanos -cgeneral :\nIn sql server this must be specified as the parameter of like.\nexample: WHERE ColumnA LIKE '%5/%%' ESCAPE '/' }\n  Result := '/';\nend;\n\n{**\n  Gets all the \"extra\" characters that can be used in unquoted\n  identifier names (those beyond a-z, A-Z, 0-9 and _).\n  @return the string containing the extra characters\n}\nfunction TZDbLibDatabaseInfo.GetExtraNameCharacters: string;\nbegin\n  Result := '@$#';\nend;\n\n//--------------------------------------------------------------------\n// Functions describing which features are supported.\n\n{**\n  Are expressions in \"ORDER BY\" lists supported?\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZDbLibDatabaseInfo.SupportsExpressionsInOrderBy: Boolean;\nbegin\n  Result := True;\nend;\n\n{**\n  Can an \"ORDER BY\" clause use columns not in the SELECT statement?\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZDbLibDatabaseInfo.SupportsOrderByUnrelated: Boolean;\nbegin\n  Result := True;\nend;\n\n{**\n  Is some form of \"GROUP BY\" clause supported?\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZDbLibDatabaseInfo.SupportsGroupBy: Boolean;\nbegin\n  Result := True;\nend;\n\n{**\n  Can a \"GROUP BY\" clause use columns not in the SELECT?\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZDbLibDatabaseInfo.SupportsGroupByUnrelated: Boolean;\nbegin\n  Result := True;\nend;\n\n{**\n  Can a \"GROUP BY\" clause add columns not in the SELECT\n  provided it specifies all the columns in the SELECT?\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZDbLibDatabaseInfo.SupportsGroupByBeyondSelect: Boolean;\nbegin\n  Result := True;\nend;\n\n{**\n  Is the SQL Integrity Enhancement Facility supported?\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZDbLibDatabaseInfo.SupportsIntegrityEnhancementFacility: Boolean;\nbegin\n  Result := False;\nend;\n\n{**\n  What's the database vendor's preferred term for \"schema\"?\n  @return the vendor term\n}\nfunction TZDbLibDatabaseInfo.GetSchemaTerm: string;\nbegin\n  Result := 'owner';\nend;\n\n{**\n  What's the database vendor's preferred term for \"procedure\"?\n  @return the vendor term\n}\nfunction TZDbLibDatabaseInfo.GetProcedureTerm: string;\nbegin\n  Result := 'procedure';\nend;\n\n{**\n  What's the database vendor's preferred term for \"catalog\"?\n  @return the vendor term\n}\nfunction TZDbLibDatabaseInfo.GetCatalogTerm: string;\nbegin\n  Result := 'database';\nend;\n\n{**\n  What's the separator between catalog and table name?\n  @return the separator string\n}\nfunction TZDbLibDatabaseInfo.GetCatalogSeparator: string;\nbegin\n  Result := '.';\nend;\n\n{**\n  Can a schema name be used in a data manipulation statement?\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZDbLibDatabaseInfo.SupportsSchemasInDataManipulation: Boolean;\nbegin\n  Result := True;\nend;\n\n{**\n  Can a schema name be used in a procedure call statement?\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZDbLibDatabaseInfo.SupportsSchemasInProcedureCalls: Boolean;\nbegin\n  Result := True;\nend;\n\n{**\n  Can a schema name be used in a table definition statement?\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZDbLibDatabaseInfo.SupportsSchemasInTableDefinitions: Boolean;\nbegin\n  Result := True;\nend;\n\n{**\n  Can a schema name be used in an index definition statement?\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZDbLibDatabaseInfo.SupportsSchemasInIndexDefinitions: Boolean;\nbegin\n  Result := True;\nend;\n\n{**\n  Can a schema name be used in a privilege definition statement?\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZDbLibDatabaseInfo.SupportsSchemasInPrivilegeDefinitions: Boolean;\nbegin\n  Result := True;\nend;\n\n{**\n  Can a catalog name be used in a data manipulation statement?\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZDbLibDatabaseInfo.SupportsCatalogsInDataManipulation: Boolean;\nbegin\n  Result := True;\nend;\n\n{**\n  Can a catalog name be used in a procedure call statement?\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZDbLibDatabaseInfo.SupportsCatalogsInProcedureCalls: Boolean;\nbegin\n  Result := True;\nend;\n\n{**\n  Can a catalog name be used in a table definition statement?\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZDbLibDatabaseInfo.SupportsCatalogsInTableDefinitions: Boolean;\nbegin\n  Result := True;\nend;\n\n{**\n  Can a catalog name be used in an index definition statement?\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZDbLibDatabaseInfo.SupportsCatalogsInIndexDefinitions: Boolean;\nbegin\n  Result := True;\nend;\n\n{**\n  Can a catalog name be used in a privilege definition statement?\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZDbLibDatabaseInfo.SupportsCatalogsInPrivilegeDefinitions: Boolean;\nbegin\n  Result := True;\nend;\n\n{**\n  Is positioned DELETE supported?\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZDbLibDatabaseInfo.SupportsPositionedDelete: Boolean;\nbegin\n//CURRENT OF\n//Specifies that the DELETE is done at the current position of the specified cursor.\n  Result := True;\nend;\n\n{**\n  Is positioned UPDATE supported?\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZDbLibDatabaseInfo.SupportsPositionedUpdate: Boolean;\nbegin\n  Result := True;\nend;\n\n{**\n  Is SELECT for UPDATE supported?\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZDbLibDatabaseInfo.SupportsSelectForUpdate: Boolean;\nbegin\n  Result := True;\nend;\n\n{**\n  Are stored procedure calls using the stored procedure escape\n  syntax supported?\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZDbLibDatabaseInfo.SupportsStoredProcedures: Boolean;\nbegin\n  Result := True;\nend;\n\n{**\n  Are subqueries in comparison expressions supported?\n  A JDBC Compliant<sup><font size=-2>TM</font></sup> driver always returns true.\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZDbLibDatabaseInfo.SupportsSubqueriesInComparisons: Boolean;\nbegin\n  Result := True;\nend;\n\n{**\n  Are subqueries in 'exists' expressions supported?\n  A JDBC Compliant<sup><font size=-2>TM</font></sup> driver always returns true.\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZDbLibDatabaseInfo.SupportsSubqueriesInExists: Boolean;\nbegin\n  Result := True;\nend;\n\n{**\n  Are subqueries in 'in' statements supported?\n  A JDBC Compliant<sup><font size=-2>TM</font></sup> driver always returns true.\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZDbLibDatabaseInfo.SupportsSubqueriesInIns: Boolean;\nbegin\n  Result := True;\nend;\n\n{**\n  Are subqueries in quantified expressions supported?\n  A JDBC Compliant<sup><font size=-2>TM</font></sup> driver always returns true.\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZDbLibDatabaseInfo.SupportsSubqueriesInQuantifieds: Boolean;\nbegin\n  Result := True;\nend;\n\n{**\n  Are correlated subqueries supported?\n  A JDBC Compliant<sup><font size=-2>TM</font></sup> driver always returns true.\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZDbLibDatabaseInfo.SupportsCorrelatedSubqueries: Boolean;\nbegin\n  Result := True;\nend;\n\n{**\n  Is SQL UNION supported?\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZDbLibDatabaseInfo.SupportsUnion: Boolean;\nbegin\n  Result := True;\nend;\n\n{**\n  Is SQL UNION ALL supported?\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZDbLibDatabaseInfo.SupportsUnionAll: Boolean;\nbegin\n  Result := True;\nend;\n\n{**\n  Can cursors remain open across commits?\n  @return <code>true</code> if cursors always remain open;\n        <code>false</code> if they might not remain open\n}\nfunction TZDbLibDatabaseInfo.SupportsOpenCursorsAcrossCommit: Boolean;\nbegin\n  Result := True;\nend;\n\n{**\n  Can cursors remain open across rollbacks?\n  @return <code>true</code> if cursors always remain open;\n        <code>false</code> if they might not remain open\n}\nfunction TZDbLibDatabaseInfo.SupportsOpenCursorsAcrossRollback: Boolean;\nbegin\n  Result := True;\nend;\n\n{**\n  Can statements remain open across commits?\n  @return <code>true</code> if statements always remain open;\n        <code>false</code> if they might not remain open\n}\nfunction TZDbLibDatabaseInfo.SupportsOpenStatementsAcrossCommit: Boolean;\nbegin\n  Result := False;\nend;\n\n{**\n  Can statements remain open across rollbacks?\n  @return <code>true</code> if statements always remain open;\n        <code>false</code> if they might not remain open\n}\nfunction TZDbLibDatabaseInfo.SupportsOpenStatementsAcrossRollback: Boolean;\nbegin\n  Result := False;\nend;\n\n//----------------------------------------------------------------------\n// The following group of methods exposes various limitations\n// based on the target database with the current driver.\n// Unless otherwise specified, a result of zero means there is no\n// limit, or the limit is not known.\n\n{**\n  How many hex characters can you have in an inline binary literal?\n  @return max binary literal length in hex characters;\n       a result of zero means that there is no limit or the limit is not known\n}\nfunction TZDbLibDatabaseInfo.GetMaxBinaryLiteralLength: Integer;\nbegin\n  Result := 16000;\nend;\n\n{**\n  What's the max length for a character literal?\n  @return max literal length;\n       a result of zero means that there is no limit or the limit is not known\n}\nfunction TZDbLibDatabaseInfo.GetMaxCharLiteralLength: Integer;\nbegin\n  Result := 8000;\nend;\n\n{**\n  What's the limit on column name length?\n  @return max column name length;\n       a result of zero means that there is no limit or the limit is not known\n}\nfunction TZDbLibDatabaseInfo.GetMaxColumnNameLength: Integer;\nbegin\n  Result := 128;\nend;\n\n{**\n  What's the maximum number of columns in a \"GROUP BY\" clause?\n  @return max number of columns;\n       a result of zero means that there is no limit or the limit is not known\n}\nfunction TZDbLibDatabaseInfo.GetMaxColumnsInGroupBy: Integer;\nbegin\n  Result := 0;\nend;\n\n{**\n  What's the maximum number of columns allowed in an index?\n  @return max number of columns;\n       a result of zero means that there is no limit or the limit is not known\n}\nfunction TZDbLibDatabaseInfo.GetMaxColumnsInIndex: Integer;\nbegin\n  Result := 16;\nend;\n\n{**\n  What's the maximum number of columns in an \"ORDER BY\" clause?\n  @return max number of columns;\n       a result of zero means that there is no limit or the limit is not known\n}\nfunction TZDbLibDatabaseInfo.GetMaxColumnsInOrderBy: Integer;\nbegin\n  Result := 0;\nend;\n\n{**\n  What's the maximum number of columns in a \"SELECT\" list?\n  @return max number of columns;\n       a result of zero means that there is no limit or the limit is not known\n}\nfunction TZDbLibDatabaseInfo.GetMaxColumnsInSelect: Integer;\nbegin\n  Result := 4096;\nend;\n\n{**\n  What's the maximum number of columns in a table?\n  @return max number of columns;\n       a result of zero means that there is no limit or the limit is not known\n}\nfunction TZDbLibDatabaseInfo.GetMaxColumnsInTable: Integer;\nbegin\n  Result := 1024;\nend;\n\n{**\n  How many active connections can we have at a time to this database?\n  @return max number of active connections;\n       a result of zero means that there is no limit or the limit is not known\n}\nfunction TZDbLibDatabaseInfo.GetMaxConnections: Integer;\nbegin\n  Result := 0;\nend;\n\n{**\n  What's the maximum cursor name length?\n  @return max cursor name length in bytes;\n       a result of zero means that there is no limit or the limit is not known\n}\nfunction TZDbLibDatabaseInfo.GetMaxCursorNameLength: Integer;\nbegin\n  Result := 128;\nend;\n\n{**\n  Retrieves the maximum number of bytes for an index, including all\n  of the parts of the index.\n  @return max index length in bytes, which includes the composite of all\n   the constituent parts of the index;\n   a result of zero means that there is no limit or the limit is not known\n}\nfunction TZDbLibDatabaseInfo.GetMaxIndexLength: Integer;\nbegin\n  Result := 900;\nend;\n\n{**\n  What's the maximum length allowed for a schema name?\n  @return max name length in bytes;\n       a result of zero means that there is no limit or the limit is not known\n}\nfunction TZDbLibDatabaseInfo.GetMaxSchemaNameLength: Integer;\nbegin\n  Result := 128;\nend;\n\n{**\n  What's the maximum length of a procedure name?\n  @return max name length in bytes;\n       a result of zero means that there is no limit or the limit is not known\n}\nfunction TZDbLibDatabaseInfo.GetMaxProcedureNameLength: Integer;\nbegin\n  Result := 128;\nend;\n\n{**\n  What's the maximum length of a catalog name?\n  @return max name length in bytes;\n       a result of zero means that there is no limit or the limit is not known\n}\nfunction TZDbLibDatabaseInfo.GetMaxCatalogNameLength: Integer;\nbegin\n  Result := 128;\nend;\n\n{**\n  What's the maximum length of a single row?\n  @return max row size in bytes;\n       a result of zero means that there is no limit or the limit is not known\n}\nfunction TZDbLibDatabaseInfo.GetMaxRowSize: Integer;\nbegin\n  Result := 8060;\nend;\n\n{**\n  Did getMaxRowSize() include LONGVARCHAR and LONGVARBINARY\n  blobs?\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZDbLibDatabaseInfo.DoesMaxRowSizeIncludeBlobs: Boolean;\nbegin\n  Result := False;\nend;\n\n{**\n  What's the maximum length of an SQL statement?\n  @return max length in bytes;\n       a result of zero means that there is no limit or the limit is not known\n}\nfunction TZDbLibDatabaseInfo.GetMaxStatementLength: Integer;\nbegin\n  Result := 0;\nend;\n\n{**\n  How many active statements can we have open at one time to this\n  database?\n  @return the maximum number of statements that can be open at one time;\n       a result of zero means that there is no limit or the limit is not known\n}\nfunction TZDbLibDatabaseInfo.GetMaxStatements: Integer;\nbegin\n  Result := 0;\nend;\n\n{**\n  What's the maximum length of a table name?\n  @return max name length in bytes;\n       a result of zero means that there is no limit or the limit is not known\n}\nfunction TZDbLibDatabaseInfo.GetMaxTableNameLength: Integer;\nbegin\n  Result := 128;\nend;\n\n{**\n  What's the maximum number of tables in a SELECT statement?\n  @return the maximum number of tables allowed in a SELECT statement;\n       a result of zero means that there is no limit or the limit is not known\n}\nfunction TZDbLibDatabaseInfo.GetMaxTablesInSelect: Integer;\nbegin\n  Result := 256;\nend;\n\n{**\n  What's the maximum length of a user name?\n  @return max user name length  in bytes;\n       a result of zero means that there is no limit or the limit is not known\n}\nfunction TZDbLibDatabaseInfo.GetMaxUserNameLength: Integer;\nbegin\n  Result := 128;\nend;\n\n//----------------------------------------------------------------------\n\n{**\n  What's the database's default transaction isolation level?  The\n  values are defined in <code>java.sql.Connection</code>.\n  @return the default isolation level\n  @see Connection\n}\nfunction TZDbLibDatabaseInfo.GetDefaultTransactionIsolation:\n  TZTransactIsolationLevel;\nbegin\n  Result := tiReadCommitted;\nend;\n\n{**\n  Are transactions supported? If not, invoking the method\n  <code>commit</code> is a noop and the isolation level is TRANSACTION_NONE.\n  @return <code>true</code> if transactions are supported; <code>false</code> otherwise\n}\nfunction TZDbLibDatabaseInfo.SupportsTransactions: Boolean;\nbegin\n  Result := True;\nend;\n\n{**\n  Does this database support the given transaction isolation level?\n  @param level the values are defined in <code>java.sql.Connection</code>\n  @return <code>true</code> if so; <code>false</code> otherwise\n  @see Connection\n}\nfunction TZDbLibDatabaseInfo.SupportsTransactionIsolationLevel(\n  Level: TZTransactIsolationLevel): Boolean;\nbegin\n  Result := True;\nend;\n\n{**\n  Are both data definition and data manipulation statements\n  within a transaction supported?\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZDbLibDatabaseInfo.\n  SupportsDataDefinitionAndDataManipulationTransactions: Boolean;\nbegin\n  Result := True;\nend;\n\n{**\n  Are only data manipulation statements within a transaction\n  supported?\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZDbLibDatabaseInfo.\n  SupportsDataManipulationTransactionsOnly: Boolean;\nbegin\n  Result := False;\nend;\n\n{**\n  Does a data definition statement within a transaction force the\n  transaction to commit?\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZDbLibDatabaseInfo.DataDefinitionCausesTransactionCommit: Boolean;\nbegin\n  Result := False;\nend;\n\n{**\n  Is a data definition statement within a transaction ignored?\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZDbLibDatabaseInfo.DataDefinitionIgnoredInTransactions: Boolean;\nbegin\n  Result := False;\nend;\n\n{**\n  Does the database support the given result set type?\n  @param type defined in <code>java.sql.ResultSet</code>\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZDbLibDatabaseInfo.SupportsResultSetType(\n  _Type: TZResultSetType): Boolean;\nbegin\n  Result := True;\nend;\n\n{**\n  Does the database support the concurrency type in combination\n  with the given result set type?\n\n  @param type defined in <code>java.sql.ResultSet</code>\n  @param concurrency type defined in <code>java.sql.ResultSet</code>\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZDbLibDatabaseInfo.SupportsResultSetConcurrency(\n  _Type: TZResultSetType; Concurrency: TZResultSetConcurrency): Boolean;\nbegin\n  Result := True;\nend;\n\n\n{ TZDbLibBaseDatabaseMetadata }\n\n{**\n  Composes a object name, AnsiQuotedStr or NullText\n  @param S the object string\n  @param NullText the \"NULL\"-Text default: 'null'\n  @param QuoteChar the QuoteChar default: '\n  @return 'null' if S is '' or S if s is already Quoted or AnsiQuotedStr(S, #39)\n}\nfunction TZDbLibBaseDatabaseMetadata.ComposeObjectString(const S: String;\n  Const NullText: String = 'null'; QuoteChar: Char = #39): String;\nbegin\n  if S = '' then\n    Result := NullText\n  else\n    if IC.IsQuoted(s) then\n      Result := S\n    else\n      Result := AnsiQuotedStr(S, QuoteChar);\nend;\n\n{**\n  Decomposes a object name, AnsiQuotedStr or NullText\n  @param S the object string\n  @return 'null' if S is '' or S if s is already Quoted or AnsiQuotedStr(S, #39)\n}\nfunction TZDbLibBaseDatabaseMetadata.DecomposeObjectString(const S: String): String;\nbegin\n  if S = '' then\n    Result := 'null'\n  else\n  begin\n    if IC.IsQuoted(s) then\n      Result := IC.ExtractQuote(s)\n    else\n      Result := S;\n    Result := AnsiQuotedStr(Result, #39);\n  end;\nend;\n{**\n  Constructs a database information object and returns the interface to it. Used\n  internally by the constructor.\n  @return the database information object interface\n}\nfunction TZDbLibBaseDatabaseMetadata.CreateDatabaseInfo: IZDatabaseInfo;\nbegin\n  Result := TZDbLibDatabaseInfo.Create(Self);\nend;\n\n{**\n  Gets a description of the primary key columns that are\n  referenced by a table's foreign key columns (the primary keys\n  imported by a table).  They are ordered by PKTABLE_CAT,\n  PKTABLE_SCHEM, PKTABLE_NAME, and KEY_SEQ.\n\n  <P>Each primary key column description has the following columns:\n   <OL>\n        <LI><B>PKTABLE_CAT</B> String => primary key table catalog\n       being imported (may be null)\n        <LI><B>PKTABLE_SCHEM</B> String => primary key table schema\n       being imported (may be null)\n        <LI><B>PKTABLE_NAME</B> String => primary key table name\n       being imported\n        <LI><B>PKCOLUMN_NAME</B> String => primary key column name\n       being imported\n        <LI><B>FKTABLE_CAT</B> String => foreign key table catalog (may be null)\n        <LI><B>FKTABLE_SCHEM</B> String => foreign key table schema (may be null)\n        <LI><B>FKTABLE_NAME</B> String => foreign key table name\n        <LI><B>FKCOLUMN_NAME</B> String => foreign key column name\n        <LI><B>KEY_SEQ</B> short => sequence number within foreign key\n        <LI><B>UPDATE_RULE</B> short => What happens to\n        foreign key when primary is updated:\n       <UL>\n       <LI> importedNoAction - do not allow update of primary\n                key if it has been imported\n       <LI> importedKeyCascade - change imported key to agree\n                with primary key update\n       <LI> importedKeySetNull - change imported key to NULL if\n                its primary key has been updated\n       <LI> importedKeySetDefault - change imported key to default values\n                if its primary key has been updated\n       <LI> importedKeyRestrict - same as importedKeyNoAction\n                                  (for ODBC 2.x compatibility)\n       </UL>\n        <LI><B>DELETE_RULE</B> short => What happens to\n       the foreign key when primary is deleted.\n       <UL>\n       <LI> importedKeyNoAction - do not allow delete of primary\n                key if it has been imported\n       <LI> importedKeyCascade - delete rows that import a deleted key\n       <LI> importedKeySetNull - change imported key to NULL if\n                its primary key has been deleted\n       <LI> importedKeyRestrict - same as importedKeyNoAction\n                                  (for ODBC 2.x compatibility)\n       <LI> importedKeySetDefault - change imported key to default if\n                its primary key has been deleted\n       </UL>\n        <LI><B>FK_NAME</B> String => foreign key name (may be null)\n        <LI><B>PK_NAME</B> String => primary key name (may be null)\n        <LI><B>DEFERRABILITY</B> short => can the evaluation of foreign key\n       constraints be deferred until commit\n       <UL>\n       <LI> importedKeyInitiallyDeferred - see SQL92 for definition\n       <LI> importedKeyInitiallyImmediate - see SQL92 for definition\n       <LI> importedKeyNotDeferrable - see SQL92 for definition\n       </UL>\n   </OL>\n\n  @param catalog a catalog name; \"\" retrieves those without a\n  catalog; null means drop catalog name from the selection criteria\n  @param schema a schema name; \"\" retrieves those\n  without a schema\n  @param table a table name\n  @return <code>ResultSet</code> - each row is a primary key column description\n  @see #getExportedKeys\n}\nfunction TZDbLibBaseDatabaseMetadata.UncachedGetImportedKeys(const Catalog: string;\n  const Schema: string; const Table: string): IZResultSet;\nbegin\n  Result := UncachedGetCrossReference('', '', '', Catalog, Schema, Table);\nend;\n\n{**\n  Gets a description of the foreign key columns that reference a\n  table's primary key columns (the foreign keys exported by a\n  table).  They are ordered by FKTABLE_CAT, FKTABLE_SCHEM,\n  FKTABLE_NAME, and KEY_SEQ.\n\n  <P>Each foreign key column description has the following columns:\n   <OL>\n        <LI><B>PKTABLE_CAT</B> String => primary key table catalog (may be null)\n        <LI><B>PKTABLE_SCHEM</B> String => primary key table schema (may be null)\n        <LI><B>PKTABLE_NAME</B> String => primary key table name\n        <LI><B>PKCOLUMN_NAME</B> String => primary key column name\n        <LI><B>FKTABLE_CAT</B> String => foreign key table catalog (may be null)\n       being exported (may be null)\n        <LI><B>FKTABLE_SCHEM</B> String => foreign key table schema (may be null)\n       being exported (may be null)\n        <LI><B>FKTABLE_NAME</B> String => foreign key table name\n       being exported\n        <LI><B>FKCOLUMN_NAME</B> String => foreign key column name\n       being exported\n        <LI><B>KEY_SEQ</B> short => sequence number within foreign key\n        <LI><B>UPDATE_RULE</B> short => What happens to\n        foreign key when primary is updated:\n       <UL>\n       <LI> importedNoAction - do not allow update of primary\n                key if it has been imported\n       <LI> importedKeyCascade - change imported key to agree\n                with primary key update\n       <LI> importedKeySetNull - change imported key to NULL if\n                its primary key has been updated\n       <LI> importedKeySetDefault - change imported key to default values\n                if its primary key has been updated\n       <LI> importedKeyRestrict - same as importedKeyNoAction\n                                  (for ODBC 2.x compatibility)\n       </UL>\n        <LI><B>DELETE_RULE</B> short => What happens to\n       the foreign key when primary is deleted.\n       <UL>\n       <LI> importedKeyNoAction - do not allow delete of primary\n                key if it has been imported\n       <LI> importedKeyCascade - delete rows that import a deleted key\n       <LI> importedKeySetNull - change imported key to NULL if\n                its primary key has been deleted\n       <LI> importedKeyRestrict - same as importedKeyNoAction\n                                  (for ODBC 2.x compatibility)\n       <LI> importedKeySetDefault - change imported key to default if\n                its primary key has been deleted\n       </UL>\n        <LI><B>FK_NAME</B> String => foreign key name (may be null)\n        <LI><B>PK_NAME</B> String => primary key name (may be null)\n        <LI><B>DEFERRABILITY</B> short => can the evaluation of foreign key\n       constraints be deferred until commit\n       <UL>\n       <LI> importedKeyInitiallyDeferred - see SQL92 for definition\n       <LI> importedKeyInitiallyImmediate - see SQL92 for definition\n       <LI> importedKeyNotDeferrable - see SQL92 for definition\n       </UL>\n   </OL>\n\n  @param catalog a catalog name; \"\" retrieves those without a\n  catalog; null means drop catalog name from the selection criteria\n  @param schema a schema name; \"\" retrieves those\n  without a schema\n  @param table a table name\n  @return <code>ResultSet</code> - each row is a foreign key column description\n  @see #getImportedKeys\n}\nfunction TZDbLibBaseDatabaseMetadata.UncachedGetExportedKeys(const Catalog: string;\n  const Schema: string; const Table: string): IZResultSet;\nbegin\n  Result := UncachedGetCrossReference(Catalog, Schema, Table, '', '', '');\nend;\n\n{**\n  What's the name of this database product?\n  @return database product name\n}\nfunction TZMsSqlDatabaseInfo.GetDatabaseProductName: string;\nbegin\n  Result := 'MS SQL';\nend;\n\n{**\n  What's the version of this database product?\n  @return database version\n}\nfunction TZMsSqlDatabaseInfo.GetDatabaseProductVersion: string;\nbegin\n  Result := '7+';\nend;\n\n{**\n  What's the name of this JDBC driver?\n  @return JDBC driver name\n}\nfunction TZMsSqlDatabaseInfo.GetDriverName: string;\nbegin\n  Result := 'Zeos Database Connectivity Driver for Microsoft SQL Server';\nend;\n\n{**\n  What's the name of this database product?\n  @return database product name\n}\nfunction TZSybaseDatabaseInfo.GetDatabaseProductName: string;\nbegin\n  Result := 'Sybase';\nend;\n\n{**\n  What's the version of this database product?\n  @return database version\n}\nfunction TZSybaseDatabaseInfo.GetDatabaseProductVersion: string;\nbegin\n  Result := '12+';\nend;\n\n{**\n  What's the name of this JDBC driver?\n  @return JDBC driver name\n}\nfunction TZSybaseDatabaseInfo.GetDriverName: string;\nbegin\n  Result := 'Zeos Database Connectivity Driver for Sybase ASE Server';\nend;\n\n{ TZMsSqlDatabaseMetadata }\n\n{**\n  Constructs a database information object and returns the interface to it. Used\n  internally by the constructor.\n  @return the database information object interface\n}\nfunction TZMsSqlDatabaseMetadata.CreateDatabaseInfo: IZDatabaseInfo;\nbegin\n  Result := TZMsSqlDatabaseInfo.Create(Self);\nend;\n\n{**\n  Gets a description of the stored procedures available in a\n  catalog.\n\n  <P>Only procedure descriptions matching the schema and\n  procedure name criteria are returned.  They are ordered by\n  PROCEDURE_SCHEM, and PROCEDURE_NAME.\n\n  <P>Each procedure description has the the following columns:\n   <OL>\n        <LI><B>PROCEDURE_CAT</B> String => procedure catalog (may be null)\n        <LI><B>PROCEDURE_SCHEM</B> String => procedure schema (may be null)\n        <LI><B>PROCEDURE_NAME</B> String => procedure name\n   <LI> reserved for future use\n   <LI> reserved for future use\n   <LI> reserved for future use\n        <LI><B>REMARKS</B> String => explanatory comment on the procedure\n        <LI><B>PROCEDURE_TYPE</B> short => kind of procedure:\n       <UL>\n       <LI> procedureResultUnknown - May return a result\n       <LI> procedureNoResult - Does not return a result\n       <LI> procedureReturnsResult - Returns a result\n       </UL>\n   </OL>\n\n  @param catalog a catalog name; \"\" retrieves those without a\n  catalog; null means drop catalog name from the selection criteria\n  @param schemaPattern a schema name pattern; \"\" retrieves those\n  without a schema\n  @param procedureNamePattern a procedure name pattern\n  @return <code>ResultSet</code> - each row is a procedure description\n  @see #getSearchStringEscape\n}\nfunction TZMsSqlDatabaseMetadata.UncachedGetProcedures(const Catalog: string;\n  const SchemaPattern: string; const ProcedureNamePattern: string): IZResultSet;\nbegin\n    Result:=inherited UncachedGetProcedures(Catalog, SchemaPattern, ProcedureNamePattern);\n\n    with GetStatement.ExecuteQuery(\n      Format('exec sp_stored_procedures %s, %s, %s',\n      [ComposeObjectString(ProcedureNamePattern), ComposeObjectString(SchemaPattern), ComposeObjectString(Catalog)])) do\n    begin\n      while Next do\n      begin\n        Result.MoveToInsertRow;\n        Result.UpdateStringByName('PROCEDURE_CAT',\n          GetStringByName('PROCEDURE_QUALIFIER'));\n        Result.UpdateStringByName('PROCEDURE_SCHEM',\n          GetStringByName('PROCEDURE_OWNER'));\n        Result.UpdateStringByName('PROCEDURE_NAME',\n          GetStringByName('PROCEDURE_NAME'));\n        Result.UpdateStringByName('REMARKS',\n          GetStringByName('REMARKS'));\n        Result.UpdateShortByName('PROCEDURE_TYPE', 0);\n        Result.InsertRow;\n      end;\n      Close;\n    end;\n    Result.BeforeFirst;\nend;\n\n{**\n  Gets a description of a catalog's stored procedure parameters\n  and result columns.\n\n  <P>Only descriptions matching the schema, procedure and\n  parameter name criteria are returned.  They are ordered by\n  PROCEDURE_SCHEM and PROCEDURE_NAME. Within this, the return value,\n  if any, is first. Next are the parameter descriptions in call\n  order. The column descriptions follow in column number order.\n\n  <P>Each row in the <code>ResultSet</code> is a parameter description or\n  column description with the following fields:\n   <OL>\n        <LI><B>PROCEDURE_CAT</B> String => procedure catalog (may be null)\n        <LI><B>PROCEDURE_SCHEM</B> String => procedure schema (may be null)\n        <LI><B>PROCEDURE_NAME</B> String => procedure name\n        <LI><B>COLUMN_NAME</B> String => column/parameter name\n        <LI><B>COLUMN_TYPE</B> Short => kind of column/parameter:\n       <UL>\n       <LI> procedureColumnUnknown - nobody knows\n       <LI> procedureColumnIn - IN parameter\n       <LI> procedureColumnInOut - INOUT parameter\n       <LI> procedureColumnOut - OUT parameter\n       <LI> procedureColumnReturn - procedure return value\n       <LI> procedureColumnResult - result column in <code>ResultSet</code>\n       </UL>\n   <LI><B>DATA_TYPE</B> short => SQL type from java.sql.Types\n        <LI><B>TYPE_NAME</B> String => SQL type name, for a UDT type the\n   type name is fully qualified\n        <LI><B>PRECISION</B> int => precision\n        <LI><B>LENGTH</B> int => length in bytes of data\n        <LI><B>SCALE</B> short => scale\n        <LI><B>RADIX</B> short => radix\n        <LI><B>NULLABLE</B> short => can it contain NULL?\n       <UL>\n       <LI> procedureNoNulls - does not allow NULL values\n       <LI> procedureNullable - allows NULL values\n       <LI> procedureNullableUnknown - nullability unknown\n       </UL>\n        <LI><B>REMARKS</B> String => comment describing parameter/column\n   </OL>\n\n  <P><B>Note:</B> Some databases may not return the column\n  descriptions for a procedure. Additional columns beyond\n  REMARKS can be defined by the database.\n\n  @param catalog a catalog name; \"\" retrieves those without a\n  catalog; null means drop catalog name from the selection criteria\n  @param schemaPattern a schema name pattern; \"\" retrieves those\n  without a schema\n  @param procedureNamePattern a procedure name pattern\n  @param columnNamePattern a column name pattern\n  @return <code>ResultSet</code> - each row describes a stored procedure parameter or\n       column\n  @see #getSearchStringEscape\n}\nfunction TZMsSqlDatabaseMetadata.UncachedGetProcedureColumns(const Catalog: string;\n  const SchemaPattern: string; const ProcedureNamePattern: string;\n  const ColumnNamePattern: string): IZResultSet;\nbegin\n    Result:=inherited UncachedGetProcedureColumns(Catalog, SchemaPattern, ProcedureNamePattern, ColumnNamePattern);\n\n    with GetStatement.ExecuteQuery(\n      Format('exec sp_sproc_columns %s, %s, %s, %s',\n      [ComposeObjectString(ProcedureNamePattern), ComposeObjectString(SchemaPattern), ComposeObjectString(Catalog), ComposeObjectString(ColumnNamePattern)])) do\n    begin\n      while Next do\n      begin\n        Result.MoveToInsertRow;\n        Result.UpdateStringByName('PROCEDURE_CAT',\n          GetStringByName('PROCEDURE_QUALIFIER'));\n        Result.UpdateStringByName('PROCEDURE_SCHEM',\n          GetStringByName('PROCEDURE_OWNER'));\n        Result.UpdateStringByName('PROCEDURE_NAME',\n          GetStringByName('PROCEDURE_NAME'));\n        Result.UpdateStringByName('COLUMN_NAME',\n          GetStringByName('COLUMN_NAME'));\n        case GetShortByName('COLUMN_TYPE') of\n          1: Result.UpdateShortByName('COLUMN_TYPE', Ord(pctIn));\n          2: Result.UpdateShortByName('COLUMN_TYPE', Ord(pctInOut));\n          3: Result.UpdateShortByName('COLUMN_TYPE', Ord(pctUnknown));\n          4: Result.UpdateShortByName('COLUMN_TYPE', Ord(pctInOut));\n          5: Result.UpdateShortByName('COLUMN_TYPE', Ord(pctReturn));\n        else\n          Result.UpdateShortByName('COLUMN_TYPE', Ord(pctUnknown));\n        end;\n        Result.UpdateShortByName('DATA_TYPE',\n          Ord(ConvertODBCToSqlType(GetShortByName('DATA_TYPE'), ConSettings.CPType)));\n        Result.UpdateStringByName('TYPE_NAME', GetStringByName('TYPE_NAME'));\n        Result.UpdateIntByName('PRECISION', GetIntByName('PRECISION'));\n        Result.UpdateIntByName('LENGTH', GetIntByName('LENGTH'));\n        Result.UpdateShortByName('SCALE', GetShortByName('SCALE'));\n        Result.UpdateShortByName('RADIX', GetShortByName('RADIX'));\n        Result.UpdateShortByName('NULLABLE', 2);\n        if GetStringByName('IS_NULLABLE') = 'NO' then\n          Result.UpdateShortByName('NULLABLE', 0);\n        if GetStringByName('IS_NULLABLE') = 'YES' then\n          Result.UpdateShortByName('NULLABLE', 1);\n        Result.UpdateStringByName('REMARKS', GetStringByName('REMARKS'));\n        Result.InsertRow;\n      end;\n      Close;\n    end;\n    Result.BeforeFirst;\nend;\n\n{**\n  Gets a description of tables available in a catalog.\n\n  <P>Only table descriptions matching the catalog, schema, table\n  name and type criteria are returned.  They are ordered by\n  TABLE_TYPE, TABLE_SCHEM and TABLE_NAME.\n\n  <P>Each table description has the following columns:\n   <OL>\n        <LI><B>TABLE_CAT</B> String => table catalog (may be null)\n        <LI><B>TABLE_SCHEM</B> String => table schema (may be null)\n        <LI><B>TABLE_NAME</B> String => table name\n        <LI><B>TABLE_TYPE</B> String => table type.  Typical types are \"TABLE\",\n                        \"VIEW\", \"SYSTEM TABLE\", \"GLOBAL TEMPORARY\",\n                        \"LOCAL TEMPORARY\", \"ALIAS\", \"SYNONYM\".\n        <LI><B>REMARKS</B> String => explanatory comment on the table\n   </OL>\n\n  <P><B>Note:</B> Some databases may not return information for\n  all tables.\n\n  @param catalog a catalog name; \"\" retrieves those without a\n  catalog; null means drop catalog name from the selection criteria\n  @param schemaPattern a schema name pattern; \"\" retrieves those\n  without a schema\n  @param tableNamePattern a table name pattern\n  @param types a list of table types to include; null returns all types\n  @return <code>ResultSet</code> - each row is a table description\n  @see #getSearchStringEscape\n}\nfunction TZMsSqlDatabaseMetadata.UncachedGetTables(const Catalog: string;\n  const SchemaPattern: string; const TableNamePattern: string;\n  const Types: TStringDynArray): IZResultSet;\nvar\n  I: Integer;\n  TableTypes: string;\nbegin\n    Result:=inherited UncachedGetTables(Catalog, SchemaPattern, TableNamePattern, Types);\n\n    TableTypes := '';\n    for I := 0 to Length(Types) - 1 do\n    begin\n      if Length(TableTypes) > 0 then\n        TableTypes := TableTypes + ',';\n      TableTypes := TableTypes + AnsiQuotedStr(Types[I], '''');\n    end;\n    if TableTypes = '' then\n      TableTypes := 'null'\n    else TableTypes := AnsiQuotedStr(TableTypes, '\"');\n\n    with GetStatement.ExecuteQuery(\n      Format('exec sp_tables %s, %s, %s, %s',\n      [ComposeObjectString(TableNamePattern), ComposeObjectString(SchemaPattern), ComposeObjectString(Catalog), TableTypes])) do\n    begin\n      while Next do\n      begin\n        Result.MoveToInsertRow;\n        Result.UpdateStringByName('TABLE_CAT',\n          GetStringByName('TABLE_QUALIFIER'));\n        Result.UpdateStringByName('TABLE_SCHEM', GetStringByName('TABLE_OWNER'));\n        Result.UpdateStringByName('TABLE_NAME', GetStringByName('TABLE_NAME'));\n        Result.UpdateStringByName('TABLE_TYPE', GetStringByName('TABLE_TYPE'));\n        Result.UpdateStringByName('REMARKS', GetStringByName('REMARKS'));\n        Result.InsertRow;\n      end;\n      Close;\n    end;\n    Result.BeforeFirst;\nend;\n\n{**\n  Gets the schema names available in this database.  The results\n  are ordered by schema name.\n\n  <P>The schema column is:\n   <OL>\n        <LI><B>TABLE_SCHEM</B> String => schema name\n   </OL>\n\n  @return <code>ResultSet</code> - each row has a single String column that is a\n  schema name\n}\nfunction TZMsSqlDatabaseMetadata.UncachedGetSchemas: IZResultSet;\nbegin\n    Result:=inherited UncachedGetSchemas;\n\n    with GetStatement.ExecuteQuery(\n      'select name as TABLE_OWNER from sysusers where islogin = 1') do\n    begin\n      while Next do\n      begin\n        Result.MoveToInsertRow;\n        Result.UpdateStringByName('TABLE_SCHEM',\n          GetStringByName('TABLE_OWNER'));\n        Result.InsertRow;\n      end;\n      Close;\n    end;\n    Result.BeforeFirst;\nend;\n\n{**\n  Gets the catalog names available in this database.  The results\n  are ordered by catalog name.\n\n  <P>The catalog column is:\n   <OL>\n        <LI><B>TABLE_CAT</B> String => catalog name\n   </OL>\n\n  @return <code>ResultSet</code> - each row has a single String column that is a\n  catalog name\n}\nfunction TZMsSqlDatabaseMetadata.UncachedGetCatalogs: IZResultSet;\nbegin\n    Result:=inherited UncachedGetCatalogs;\n\n    with GetStatement.ExecuteQuery('exec sp_databases') do\n    begin\n      while Next do\n      begin\n        Result.MoveToInsertRow;\n        Result.UpdateStringByName('TABLE_CAT',\n          GetStringByName('DATABASE_NAME'));\n        Result.InsertRow;\n      end;\n      Close;\n    end;\n    Result.BeforeFirst;\nend;\n\n{**\n  Gets the table types available in this database.  The results\n  are ordered by table type.\n\n  <P>The table type is:\n   <OL>\n        <LI><B>TABLE_TYPE</B> String => table type.  Typical types are \"TABLE\",\n                        \"VIEW\", \"SYSTEM TABLE\", \"GLOBAL TEMPORARY\",\n                        \"LOCAL TEMPORARY\", \"ALIAS\", \"SYNONYM\".\n   </OL>\n\n  @return <code>ResultSet</code> - each row has a single String column that is a\n  table type\n}\nfunction TZMsSqlDatabaseMetadata.UncachedGetTableTypes: IZResultSet;\nconst\n  TableTypes: array[0..2] of string = ('SYSTEM TABLE', 'TABLE', 'VIEW');\nvar\n  I: Integer;\nbegin\n    Result:=inherited UncachedGetTableTypes;\n\n    for I := 0 to 2 do\n    begin\n      Result.MoveToInsertRow;\n      Result.UpdateStringByName('TABLE_TYPE', TableTypes[I]);\n      Result.InsertRow;\n    end;\n    Result.BeforeFirst;\nend;\n\n{**\n  Gets a description of table columns available in\n  the specified catalog.\n\n  <P>Only column descriptions matching the catalog, schema, table\n  and column name criteria are returned.  They are ordered by\n  TABLE_SCHEM, TABLE_NAME and ORDINAL_POSITION.\n\n  <P>Each column description has the following columns:\n   <OL>\n        <LI><B>TABLE_CAT</B> String => table catalog (may be null)\n        <LI><B>TABLE_SCHEM</B> String => table schema (may be null)\n        <LI><B>TABLE_NAME</B> String => table name\n        <LI><B>COLUMN_NAME</B> String => column name\n        <LI><B>DATA_TYPE</B> short => SQL type from java.sql.Types\n        <LI><B>TYPE_NAME</B> String => Data source dependent type name,\n   for a UDT the type name is fully qualified\n        <LI><B>COLUMN_SIZE</B> int => column size.  For char or date\n            types this is the maximum number of characters, for numeric or\n            decimal types this is precision.\n        <LI><B>BUFFER_LENGTH</B> is not used.\n        <LI><B>DECIMAL_DIGITS</B> int => the number of fractional digits\n        <LI><B>NUM_PREC_RADIX</B> int => Radix (typically either 10 or 2)\n        <LI><B>NULLABLE</B> int => is NULL allowed?\n       <UL>\n       <LI> columnNoNulls - might not allow NULL values\n       <LI> columnNullable - definitely allows NULL values\n       <LI> columnNullableUnknown - nullability unknown\n       </UL>\n        <LI><B>REMARKS</B> String => comment describing column (may be null)\n        <LI><B>COLUMN_DEF</B> String => default value (may be null)\n        <LI><B>SQL_DATA_TYPE</B> int => unused\n        <LI><B>SQL_DATETIME_SUB</B> int => unused\n        <LI><B>CHAR_OCTET_LENGTH</B> int => for char types the\n        maximum number of bytes in the column\n        <LI><B>ORDINAL_POSITION</B> int => index of column in table\n       (starting at 1)\n        <LI><B>IS_NULLABLE</B> String => \"NO\" means column definitely\n       does not allow NULL values; \"YES\" means the column might\n       allow NULL values.  An empty string means nobody knows.\n   </OL>\n\n  @param catalog a catalog name; \"\" retrieves those without a\n  catalog; null means drop catalog name from the selection criteria\n  @param schemaPattern a schema name pattern; \"\" retrieves those\n  without a schema\n  @param tableNamePattern a table name pattern\n  @param columnNamePattern a column name pattern\n  @return <code>ResultSet</code> - each row is a column description\n  @see #getSearchStringEscape\n}\nfunction TZMsSqlDatabaseMetadata.UncachedGetColumns(const Catalog: string;\n  const SchemaPattern: string; const TableNamePattern: string;\n  const ColumnNamePattern: string): IZResultSet;\nvar\n  SQLType: TZSQLType;\nbegin\n    Result:=inherited UncachedGetColumns(Catalog, SchemaPattern, TableNamePattern, ColumnNamePattern);\n\n    with GetStatement.ExecuteQuery(\n      Format('exec sp_columns %s, %s, %s, %s',\n        [ComposeObjectString(TableNamePattern),\n         ComposeObjectString(SchemaPattern),\n         ComposeObjectString(Catalog),\n         ComposeObjectString(ColumnNamePattern)])) do\n    begin\n      while Next do\n      begin\n        Result.MoveToInsertRow;\n        Result.UpdateStringByName('TABLE_CAT', GetStringByName('TABLE_QUALIFIER'));\n        Result.UpdateStringByName('TABLE_SCHEM', GetStringByName('TABLE_OWNER'));\n        Result.UpdateStringByName('TABLE_NAME',\n          GetStringByName('TABLE_NAME'));\n        Result.UpdateStringByName('COLUMN_NAME',\n          GetStringByName('COLUMN_NAME'));\n        //The value in the resultset will be used\n        SQLType := ConvertODBCToSqlType(GetShortByName('DATA_TYPE'), ConSettings.CPType);\n        if SQLType = stUnknown then\n          Result.UpdateNullByName('DATA_TYPE')\n        else\n          Result.UpdateShortByName('DATA_TYPE', Ord(SQLType));\n        if ( SQLType = stBytes) and (UpperCase(GetStringByName('TYPE_NAME')) = 'UNIQUEIDENTIFIER') then\n          Result.UpdateShortByName('DATA_TYPE', Ord(stGUID));\n        Result.UpdateStringByName('TYPE_NAME', GetStringByName('TYPE_NAME'));\n        Result.UpdateIntByName('COLUMN_SIZE', GetIntByName('LENGTH'));\n        Result.UpdateIntByName('BUFFER_LENGTH', GetIntByName('LENGTH'));\n        Result.UpdateIntByName('DECIMAL_DIGITS', GetIntByName('SCALE'));\n        Result.UpdateIntByName('NUM_PREC_RADIX', GetShortByName('RADIX'));\n        Result.UpdateIntByName('NULLABLE', 2);\n        if GetStringByName('IS_NULLABLE') = 'NO' then\n          Result.UpdateShortByName('NULLABLE', 0);\n        if GetStringByName('IS_NULLABLE') = 'YES' then\n          Result.UpdateShortByName('NULLABLE', 1);\n        Result.UpdateStringByName('REMARKS', GetStringByName('REMARKS'));\n        Result.UpdateStringByName('COLUMN_DEF', GetStringByName('COLUMN_DEF'));\n        Result.UpdateShortByName('SQL_DATA_TYPE', GetShortByName('SQL_DATA_TYPE'));\n        Result.UpdateShortByName('SQL_DATETIME_SUB', GetShortByName('SQL_DATETIME_SUB'));\n        Result.UpdateIntByName('CHAR_OCTET_LENGTH', GetIntByName('CHAR_OCTET_LENGTH'));\n        Result.UpdateIntByName('ORDINAL_POSITION', GetIntByName('ORDINAL_POSITION'));\n        Result.UpdateStringByName('IS_NULLABLE',\n          GetStringByName('IS_NULLABLE'));\n\n        Result.UpdateBooleanByName('SEARCHABLE',\n          not (GetShortByName('SS_DATA_TYPE') in [34, 35]));\n\n        Result.InsertRow;\n      end;\n      Close;\n    end;\n\n    Result.BeforeFirst;\n    with GetStatement.ExecuteQuery(\n      Format('select c.colid, c.name, c.type, c.prec, c.scale, c.colstat,'\n      + ' c.status, c.iscomputed from syscolumns c inner join'\n      + ' sysobjects o on (o.id = c.id) where o.name COLLATE Latin1_General_CS_AS = %s and c.number=0 order by colid',\n      [DeComposeObjectString(TableNamePattern)])) do\n      // hint http://blog.sqlauthority.com/2007/04/30/case-sensitive-sql-query-search/ for the collation setting to get a case sensitive behavior\n    begin\n      while Next do\n      begin\n        Result.Next;\n        Result.UpdateBooleanByName('AUTO_INCREMENT',\n          (GetShortByName('status') and $80) <> 0);\n        Result.UpdateNullByName('CASE_SENSITIVE');\n        Result.UpdateBooleanByName('SEARCHABLE',\n          Result.GetBooleanByName('SEARCHABLE')\n          and (GetIntByName('iscomputed') = 0));\n        Result.UpdateBooleanByName('WRITABLE',\n          ((GetShortByName('status') and $80) = 0)\n          (*and (GetShortByName('type') <> 37)*)   // <<<< *DEBUG WARUM?\n          and (GetIntByName('iscomputed') = 0));\n        Result.UpdateBooleanByName('DEFINITELYWRITABLE',\n          Result.GetBooleanByName('WRITABLE'));\n        Result.UpdateBooleanByName('READONLY',\n          not Result.GetBooleanByName('WRITABLE'));\n        if Result.GetBooleanByName('AUTO_INCREMENT') then\n        begin\n          Result.UpdateShortByName('NULLABLE', 1);\n          Result.UpdateStringByName('IS_NULLABLE', 'YES');\n        end;\n        Result.UpdateRow;\n      end;\n      Close;\n    end;\n    Result.BeforeFirst;\nend;\n\n{**\n  Gets a description of the access rights for a table's columns.\n\n  <P>Only privileges matching the column name criteria are\n  returned.  They are ordered by COLUMN_NAME and PRIVILEGE.\n\n  <P>Each privilige description has the following columns:\n   <OL>\n        <LI><B>TABLE_CAT</B> String => table catalog (may be null)\n        <LI><B>TABLE_SCHEM</B> String => table schema (may be null)\n        <LI><B>TABLE_NAME</B> String => table name\n        <LI><B>COLUMN_NAME</B> String => column name\n        <LI><B>GRANTOR</B> => grantor of access (may be null)\n        <LI><B>GRANTEE</B> String => grantee of access\n        <LI><B>PRIVILEGE</B> String => name of access (SELECT,\n       INSERT, UPDATE, REFRENCES, ...)\n        <LI><B>IS_GRANTABLE</B> String => \"YES\" if grantee is permitted\n       to grant to others; \"NO\" if not; null if unknown\n   </OL>\n\n  @param catalog a catalog name; \"\" retrieves those without a\n  catalog; null means drop catalog name from the selection criteria\n  @param schema a schema name; \"\" retrieves those without a schema\n  @param table a table name\n  @param columnNamePattern a column name pattern\n  @return <code>ResultSet</code> - each row is a column privilege description\n  @see #getSearchStringEscape\n}\nfunction TZMsSqlDatabaseMetadata.UncachedGetColumnPrivileges(const Catalog: string;\n  const Schema: string; const Table: string; const ColumnNamePattern: string): IZResultSet;\nbegin\n    Result:=inherited UncachedGetColumnPrivileges(Catalog, Schema, Table, ColumnNamePattern);\n\n    with GetStatement.ExecuteQuery(\n      Format('exec sp_column_privileges %s, %s, %s, %s',\n      [ComposeObjectString(Table), ComposeObjectString(Schema), ComposeObjectString(Catalog), ComposeObjectString(ColumnNamePattern)])) do\n    begin\n      while Next do\n      begin\n        Result.MoveToInsertRow;\n        Result.UpdateStringByName('TABLE_CAT',\n          GetStringByName('TABLE_QUALIFIER'));\n        Result.UpdateStringByName('TABLE_SCHEM',\n          GetStringByName('TABLE_OWNER'));\n        Result.UpdateStringByName('TABLE_NAME',\n          GetStringByName('TABLE_NAME'));\n        Result.UpdateStringByName('COLUMN_NAME',\n          GetStringByName('COLUMN_NAME'));\n        Result.UpdateStringByName('GRANTOR',\n          GetStringByName('GRANTOR'));\n        Result.UpdateStringByName('GRANTEE',\n          GetStringByName('GRANTEE'));\n        Result.UpdateStringByName('PRIVILEGE',\n          GetStringByName('PRIVILEGE'));\n        Result.UpdateStringByName('IS_GRANTABLE',\n          GetStringByName('IS_GRANTABLE'));\n        Result.InsertRow;\n      end;\n      Close;\n    end;\n    Result.BeforeFirst;\nend;\n\n{**\n  Gets a description of the access rights for each table available\n  in a catalog. Note that a table privilege applies to one or\n  more columns in the table. It would be wrong to assume that\n  this priviledge applies to all columns (this may be true for\n  some systems but is not true for all.)\n\n  <P>Only privileges matching the schema and table name\n  criteria are returned.  They are ordered by TABLE_SCHEM,\n  TABLE_NAME, and PRIVILEGE.\n\n  <P>Each privilige description has the following columns:\n   <OL>\n        <LI><B>TABLE_CAT</B> String => table catalog (may be null)\n        <LI><B>TABLE_SCHEM</B> String => table schema (may be null)\n        <LI><B>TABLE_NAME</B> String => table name\n        <LI><B>GRANTOR</B> => grantor of access (may be null)\n        <LI><B>GRANTEE</B> String => grantee of access\n        <LI><B>PRIVILEGE</B> String => name of access (SELECT,\n       INSERT, UPDATE, REFRENCES, ...)\n        <LI><B>IS_GRANTABLE</B> String => \"YES\" if grantee is permitted\n       to grant to others; \"NO\" if not; null if unknown\n   </OL>\n\n  @param catalog a catalog name; \"\" retrieves those without a\n  catalog; null means drop catalog name from the selection criteria\n  @param schemaPattern a schema name pattern; \"\" retrieves those\n  without a schema\n  @param tableNamePattern a table name pattern\n  @return <code>ResultSet</code> - each row is a table privilege description\n  @see #getSearchStringEscape\n}\nfunction TZMsSqlDatabaseMetadata.UncachedGetTablePrivileges(const Catalog: string;\n  const SchemaPattern: string; const TableNamePattern: string): IZResultSet;\nbegin\n    Result:=inherited UncachedGetTablePrivileges(Catalog, SchemaPattern, TableNamePattern);\n\n    with GetStatement.ExecuteQuery(\n      Format('exec sp_table_privileges %s, %s, %s',\n      [ComposeObjectString(TableNamePattern), ComposeObjectString(SchemaPattern), ComposeObjectString(Catalog)])) do\n    begin\n      while Next do\n      begin\n        Result.MoveToInsertRow;\n        Result.UpdateStringByName('TABLE_CAT',\n          GetStringByName('TABLE_QUALIFIER'));\n        Result.UpdateStringByName('TABLE_SCHEM',\n          GetStringByName('TABLE_OWNER'));\n        Result.UpdateStringByName('TABLE_NAME',\n          GetStringByName('TABLE_NAME'));\n        Result.UpdateStringByName('GRANTOR',\n          GetStringByName('GRANTOR'));\n        Result.UpdateStringByName('GRANTEE',\n          GetStringByName('GRANTEE'));\n        Result.UpdateStringByName('PRIVILEGE',\n          GetStringByName('PRIVILEGE'));\n        Result.UpdateStringByName('IS_GRANTABLE',\n          GetStringByName('IS_GRANTABLE'));\n        Result.InsertRow;\n      end;\n      Close;\n    end;\n    Result.BeforeFirst;\nend;\n\n{**\n  Gets a description of a table's columns that are automatically\n  updated when any value in a row is updated.  They are\n  unordered.\n\n  <P>Each column description has the following columns:\n   <OL>\n        <LI><B>SCOPE</B> short => is not used\n        <LI><B>COLUMN_NAME</B> String => column name\n        <LI><B>DATA_TYPE</B> short => SQL data type from java.sql.Types\n        <LI><B>TYPE_NAME</B> String => Data source dependent type name\n        <LI><B>COLUMN_SIZE</B> int => precision\n        <LI><B>BUFFER_LENGTH</B> int => length of column value in bytes\n        <LI><B>DECIMAL_DIGITS</B> short  => scale\n        <LI><B>PSEUDO_COLUMN</B> short => is this a pseudo column\n       like an Oracle ROWID\n       <UL>\n       <LI> versionColumnUnknown - may or may not be pseudo column\n       <LI> versionColumnNotPseudo - is NOT a pseudo column\n       <LI> versionColumnPseudo - is a pseudo column\n       </UL>\n   </OL>\n\n  @param catalog a catalog name; \"\" retrieves those without a\n  catalog; null means drop catalog name from the selection criteria\n  @param schema a schema name; \"\" retrieves those without a schema\n  @param table a table name\n  @return <code>ResultSet</code> - each row is a column description\n  @exception SQLException if a database access error occurs\n}\nfunction TZMsSqlDatabaseMetadata.UncachedGetVersionColumns(const Catalog: string;\n  const Schema: string; const Table: string): IZResultSet;\nvar\n  MSCol_Type: string;\nbegin\n    Result:=inherited UncachedGetVersionColumns(Catalog, Schema, Table);\n\n    MSCol_Type := '''V''';\n\n    with GetStatement.ExecuteQuery(\n      Format('exec sp_special_columns %s, %s, %s, %s',\n      [ComposeObjectString(Table), ComposeObjectString(Schema), ComposeObjectString(Catalog), MSCol_Type])) do\n    begin\n      while Next do\n      begin\n        Result.MoveToInsertRow;\n        Result.UpdateShortByName('SCOPE',\n          GetShortByName('SCOPE'));\n        Result.UpdateStringByName('COLUMN_NAME',\n          GetStringByName('COLUMN_NAME'));\n        Result.UpdateShortByName('DATA_TYPE',\n          Ord(ConvertODBCToSqlType(GetShortByName('DATA_TYPE'), ConSettings.CPType)));\n        Result.UpdateStringByName('TYPE_NAME',\n          GetStringByName('TYPE_NAME'));\n        Result.UpdateIntByName('COLUMN_SIZE',\n          GetIntByName('LENGTH'));\n        Result.UpdateIntByName('BUFFER_LENGTH',\n          GetIntByName('LENGTH'));\n        Result.UpdateIntByName('DECIMAL_DIGITS',\n          GetIntByName('SCALE'));\n        Result.UpdateShortByName('PSEUDO_COLUMN',\n          GetShortByName('PSEUDO_COLUMN'));\n        Result.InsertRow;\n      end;\n      Close;\n    end;\n    Result.BeforeFirst;\nend;\n\n{**\n  Gets a description of a table's primary key columns.  They\n  are ordered by COLUMN_NAME.\n\n  <P>Each primary key column description has the following columns:\n   <OL>\n        <LI><B>TABLE_CAT</B> String => table catalog (may be null)\n        <LI><B>TABLE_SCHEM</B> String => table schema (may be null)\n        <LI><B>TABLE_NAME</B> String => table name\n        <LI><B>COLUMN_NAME</B> String => column name\n        <LI><B>KEY_SEQ</B> short => sequence number within primary key\n        <LI><B>PK_NAME</B> String => primary key name (may be null)\n   </OL>\n\n  @param catalog a catalog name; \"\" retrieves those without a\n  catalog; null means drop catalog name from the selection criteria\n  @param schema a schema name; \"\" retrieves those\n  without a schema\n  @param table a table name\n  @return <code>ResultSet</code> - each row is a primary key column description\n  @exception SQLException if a database access error occurs\n}\nfunction TZMsSqlDatabaseMetadata.UncachedGetPrimaryKeys(const Catalog: string;\n  const Schema: string; const Table: string): IZResultSet;\nbegin\n    Result:=inherited UncachedGetPrimaryKeys(Catalog, Schema, Table);\n\n    with GetStatement.ExecuteQuery(\n      Format('exec sp_pkeys %s, %s, %s',\n      [ComposeObjectString(Table), ComposeObjectString(Schema), ComposeObjectString(Catalog)])) do\n    begin\n      while Next do\n      begin\n        Result.MoveToInsertRow;\n        Result.UpdateStringByName('TABLE_CAT',\n          GetStringByName('TABLE_QUALIFIER'));\n        Result.UpdateStringByName('TABLE_SCHEM',\n          GetStringByName('TABLE_OWNER'));\n        Result.UpdateStringByName('TABLE_NAME',\n          GetStringByName('TABLE_NAME'));\n        Result.UpdateStringByName('COLUMN_NAME',\n          GetStringByName('COLUMN_NAME'));\n        Result.UpdateShortByName('KEY_SEQ',\n          GetShortByName('KEY_SEQ'));\n        Result.UpdateStringByName('PK_NAME',\n          GetStringByName('PK_NAME'));\n        Result.InsertRow;\n      end;\n      Close;\n    end;\n    Result.BeforeFirst;\nend;\n\n{**\n  Gets a description of the foreign key columns in the foreign key\n  table that reference the primary key columns of the primary key\n  table (describe how one table imports another's key.) This\n  should normally return a single foreign key/primary key pair\n  (most tables only import a foreign key from a table once.)  They\n  are ordered by FKTABLE_CAT, FKTABLE_SCHEM, FKTABLE_NAME, and\n  KEY_SEQ.\n\n  <P>Each foreign key column description has the following columns:\n   <OL>\n        <LI><B>PKTABLE_CAT</B> String => primary key table catalog (may be null)\n        <LI><B>PKTABLE_SCHEM</B> String => primary key table schema (may be null)\n        <LI><B>PKTABLE_NAME</B> String => primary key table name\n        <LI><B>PKCOLUMN_NAME</B> String => primary key column name\n        <LI><B>FKTABLE_CAT</B> String => foreign key table catalog (may be null)\n       being exported (may be null)\n        <LI><B>FKTABLE_SCHEM</B> String => foreign key table schema (may be null)\n       being exported (may be null)\n        <LI><B>FKTABLE_NAME</B> String => foreign key table name\n       being exported\n        <LI><B>FKCOLUMN_NAME</B> String => foreign key column name\n       being exported\n        <LI><B>KEY_SEQ</B> short => sequence number within foreign key\n        <LI><B>UPDATE_RULE</B> short => What happens to\n        foreign key when primary is updated:\n       <UL>\n       <LI> importedNoAction - do not allow update of primary\n                key if it has been imported\n       <LI> importedKeyCascade - change imported key to agree\n                with primary key update\n       <LI> importedKeySetNull - change imported key to NULL if\n                its primary key has been updated\n       <LI> importedKeySetDefault - change imported key to default values\n                if its primary key has been updated\n       <LI> importedKeyRestrict - same as importedKeyNoAction\n                                  (for ODBC 2.x compatibility)\n       </UL>\n        <LI><B>DELETE_RULE</B> short => What happens to\n       the foreign key when primary is deleted.\n       <UL>\n       <LI> importedKeyNoAction - do not allow delete of primary\n                key if it has been imported\n       <LI> importedKeyCascade - delete rows that import a deleted key\n       <LI> importedKeySetNull - change imported key to NULL if\n                its primary key has been deleted\n       <LI> importedKeyRestrict - same as importedKeyNoAction\n                                  (for ODBC 2.x compatibility)\n       <LI> importedKeySetDefault - change imported key to default if\n                its primary key has been deleted\n       </UL>\n        <LI><B>FK_NAME</B> String => foreign key name (may be null)\n        <LI><B>PK_NAME</B> String => primary key name (may be null)\n        <LI><B>DEFERRABILITY</B> short => can the evaluation of foreign key\n       constraints be deferred until commit\n       <UL>\n       <LI> importedKeyInitiallyDeferred - see SQL92 for definition\n       <LI> importedKeyInitiallyImmediate - see SQL92 for definition\n       <LI> importedKeyNotDeferrable - see SQL92 for definition\n       </UL>\n   </OL>\n\n  @param primaryCatalog a catalog name; \"\" retrieves those without a\n  catalog; null means drop catalog name from the selection criteria\n  @param primarySchema a schema name; \"\" retrieves those\n  without a schema\n  @param primaryTable the table name that exports the key\n  @param foreignCatalog a catalog name; \"\" retrieves those without a\n  catalog; null means drop catalog name from the selection criteria\n  @param foreignSchema a schema name; \"\" retrieves those\n  without a schema\n  @param foreignTable the table name that imports the key\n  @return <code>ResultSet</code> - each row is a foreign key column description\n  @see #getImportedKeys\n}\nfunction TZMsSqlDatabaseMetadata.UncachedGetCrossReference(const PrimaryCatalog: string;\n  const PrimarySchema: string; const PrimaryTable: string; const ForeignCatalog: string;\n  const ForeignSchema: string; const ForeignTable: string): IZResultSet;\nvar KeySeq: Integer;\nbegin\n  Result:=inherited UncachedGetCrossReference(PrimaryCatalog, PrimarySchema, PrimaryTable,\n                                              ForeignCatalog, ForeignSchema, ForeignTable);\n  KeySeq := 0;\n  with GetStatement.ExecuteQuery(\n    Format('exec sp_fkeys %s, %s, %s, %s, %s, %s',\n    [ComposeObjectString(PrimaryTable), ComposeObjectString(PrimarySchema), ComposeObjectString(PrimaryCatalog),\n     ComposeObjectString(ForeignTable), ComposeObjectString(ForeignSchema), ComposeObjectString(ForeignCatalog)])) do\n  begin\n    while Next do\n    begin\n      Inc(KeySeq);\n      Result.MoveToInsertRow;\n      Result.UpdateStringByName('PKTABLE_CAT',\n        GetStringByName('PKTABLE_QUALIFIER'));\n      Result.UpdateStringByName('PKTABLE_SCHEM',\n        GetStringByName('PKTABLE_OWNER'));\n      Result.UpdateStringByName('PKTABLE_NAME',\n        GetStringByName('PKTABLE_NAME'));\n      Result.UpdateStringByName('PKCOLUMN_NAME',\n        GetStringByName('PKCOLUMN_NAME'));\n      Result.UpdateStringByName('FKTABLE_CAT',\n        GetStringByName('FKTABLE_QUALIFIER'));\n      Result.UpdateStringByName('FKTABLE_SCHEM',\n        GetStringByName('FKTABLE_OWNER'));\n      Result.UpdateStringByName('FKTABLE_NAME',\n        GetStringByName('FKTABLE_NAME'));\n      Result.UpdateStringByName('FKCOLUMN_NAME',\n        GetStringByName('FKCOLUMN_NAME'));\n      Result.UpdateShortByName('KEY_SEQ', KeySeq);\n      Result.UpdateShortByName('UPDATE_RULE',\n        GetShortByName('UPDATE_RULE'));\n      Result.UpdateShortByName('DELETE_RULE',\n        GetShortByName('DELETE_RULE'));\n      Result.UpdateStringByName('FK_NAME',\n        GetStringByName('FK_NAME'));\n      Result.UpdateStringByName('PK_NAME',\n        GetStringByName('PK_NAME'));\n      Result.UpdateIntByName('DEFERRABILITY', 0);\n      Result.InsertRow;\n    end;\n    Close;\n  end;\n  Result.BeforeFirst;\nend;\n\n{**\n  Gets a description of all the standard SQL types supported by\n  this database. They are ordered by DATA_TYPE and then by how\n  closely the data type maps to the corresponding JDBC SQL type.\n\n  <P>Each type description has the following columns:\n   <OL>\n        <LI><B>TYPE_NAME</B> String => Type name\n        <LI><B>DATA_TYPE</B> short => SQL data type from java.sql.Types\n        <LI><B>PRECISION</B> int => maximum precision\n        <LI><B>LITERAL_PREFIX</B> String => prefix used to quote a literal\n       (may be null)\n        <LI><B>LITERAL_SUFFIX</B> String => suffix used to quote a literal\n        (may be null)\n        <LI><B>CREATE_PARAMS</B> String => parameters used in creating\n       the type (may be null)\n        <LI><B>NULLABLE</B> short => can you use NULL for this type?\n       <UL>\n       <LI> typeNoNulls - does not allow NULL values\n       <LI> typeNullable - allows NULL values\n       <LI> typeNullableUnknown - nullability unknown\n       </UL>\n        <LI><B>CASE_SENSITIVE</B> boolean=> is it case sensitive?\n        <LI><B>SEARCHABLE</B> short => can you use \"WHERE\" based on this type:\n       <UL>\n       <LI> typePredNone - No support\n       <LI> typePredChar - Only supported with WHERE .. LIKE\n       <LI> typePredBasic - Supported except for WHERE .. LIKE\n       <LI> typeSearchable - Supported for all WHERE ..\n       </UL>\n        <LI><B>UNSIGNED_ATTRIBUTE</B> boolean => is it unsigned?\n        <LI><B>FIXED_PREC_SCALE</B> boolean => can it be a money value?\n        <LI><B>AUTO_INCREMENT</B> boolean => can it be used for an\n       auto-increment value?\n        <LI><B>LOCAL_TYPE_NAME</B> String => localized version of type name\n       (may be null)\n        <LI><B>MINIMUM_SCALE</B> short => minimum scale supported\n        <LI><B>MAXIMUM_SCALE</B> short => maximum scale supported\n        <LI><B>SQL_DATA_TYPE</B> int => unused\n        <LI><B>SQL_DATETIME_SUB</B> int => unused\n        <LI><B>NUM_PREC_RADIX</B> int => usually 2 or 10\n   </OL>\n\n  @return <code>ResultSet</code> - each row is an SQL type description\n}\nfunction TZMsSqlDatabaseMetadata.UncachedGetTypeInfo: IZResultSet;\nbegin\n    Result:=inherited UncachedGetTypeInfo;\n\n    with GetStatement.ExecuteQuery('exec sp_datatype_info') do\n    begin\n      while Next do\n      begin\n        Result.MoveToInsertRow;\n        Result.UpdateStringByName('TYPE_NAME',\n          GetStringByName('TYPE_NAME'));\n        Result.UpdateShortByName('DATA_TYPE',\n          Ord(ConvertODBCToSqlType(GetShortByName('DATA_TYPE'), ConSettings.CPType)));\n        Result.UpdateIntByName('PRECISION',\n          GetIntByName('PRECISION'));\n        Result.UpdateStringByName('LITERAL_PREFIX',\n          GetStringByName('LITERAL_PREFIX'));\n        Result.UpdateStringByName('LITERAL_SUFFIX',\n          GetStringByName('LITERAL_SUFFIX'));\n        Result.UpdateStringByName('CREATE_PARAMS',\n          GetStringByName('CREATE_PARAMS'));\n        Result.UpdateShortByName('NULLABLE',\n          GetShortByName('NULLABLE'));\n        Result.UpdateBooleanByName('CASE_SENSITIVE',\n          GetShortByName('CASE_SENSITIVE') = 1);\n        Result.UpdateShortByName('SEARCHABLE',\n          GetShortByName('SEARCHABLE'));\n        Result.UpdateBooleanByName('UNSIGNED_ATTRIBUTE',\n          GetShortByName('UNSIGNED_ATTRIBUTE') = 1);\n        Result.UpdateBooleanByName('FIXED_PREC_SCALE',\n          GetShortByName('MONEY') = 1);\n        Result.UpdateBooleanByName('AUTO_INCREMENT',\n          GetShortByName('AUTO_INCREMENT') = 1);\n        Result.UpdateStringByName('LOCAL_TYPE_NAME',\n          GetStringByName('LOCAL_TYPE_NAME'));\n        Result.UpdateShortByName('MINIMUM_SCALE',\n          GetShortByName('MINIMUM_SCALE'));\n        Result.UpdateShortByName('MAXIMUM_SCALE',\n          GetShortByName('MAXIMUM_SCALE'));\n        Result.UpdateShortByName('SQL_DATA_TYPE',\n          GetShortByName('SQL_DATA_TYPE'));\n        Result.UpdateShortByName('SQL_DATETIME_SUB',\n          GetShortByName('SQL_DATETIME_SUB'));\n        Result.UpdateShortByName('NUM_PREC_RADIX',\n          GetShortByName('NUM_PREC_RADIX'));\n        Result.InsertRow;\n      end;\n      Close;\n    end;\n    Result.BeforeFirst;\nend;\n\n{**\n  Gets a description of a table's indices and statistics. They are\n  ordered by NON_UNIQUE, TYPE, INDEX_NAME, and ORDINAL_POSITION.\n\n  <P>Each index column description has the following columns:\n   <OL>\n        <LI><B>TABLE_CAT</B> String => table catalog (may be null)\n        <LI><B>TABLE_SCHEM</B> String => table schema (may be null)\n        <LI><B>TABLE_NAME</B> String => table name\n        <LI><B>NON_UNIQUE</B> boolean => Can index values be non-unique?\n       false when TYPE is tableIndexStatistic\n        <LI><B>INDEX_QUALIFIER</B> String => index catalog (may be null);\n       null when TYPE is tableIndexStatistic\n        <LI><B>INDEX_NAME</B> String => index name; null when TYPE is\n       tableIndexStatistic\n        <LI><B>TYPE</B> short => index type:\n       <UL>\n       <LI> tableIndexStatistic - this identifies table statistics that are\n            returned in conjuction with a table's index descriptions\n       <LI> tableIndexClustered - this is a clustered index\n       <LI> tableIndexHashed - this is a hashed index\n       <LI> tableIndexOther - this is some other style of index\n       </UL>\n        <LI><B>ORDINAL_POSITION</B> short => column sequence number\n       within index; zero when TYPE is tableIndexStatistic\n        <LI><B>COLUMN_NAME</B> String => column name; null when TYPE is\n       tableIndexStatistic\n        <LI><B>ASC_OR_DESC</B> String => column sort sequence, \"A\" => ascending,\n       \"D\" => descending, may be null if sort sequence is not supported;\n       null when TYPE is tableIndexStatistic\n        <LI><B>CARDINALITY</B> int => When TYPE is tableIndexStatistic, then\n       this is the number of rows in the table; otherwise, it is the\n       number of unique values in the index.\n        <LI><B>PAGES</B> int => When TYPE is  tableIndexStatisic then\n       this is the number of pages used for the table, otherwise it\n       is the number of pages used for the current index.\n        <LI><B>FILTER_CONDITION</B> String => Filter condition, if any.\n       (may be null)\n   </OL>\n\n  @param catalog a catalog name; \"\" retrieves those without a\n  catalog; null means drop catalog name from the selection criteria\n  @param schema a schema name; \"\" retrieves those without a schema\n  @param table a table name\n  @param unique when true, return only indices for unique values;\n      when false, return indices regardless of whether unique or not\n  @param approximate when true, result is allowed to reflect approximate\n      or out of data values; when false, results are requested to be\n      accurate\n  @return <code>ResultSet</code> - each row is an index column description\n}\nfunction TZMsSqlDatabaseMetadata.UncachedGetIndexInfo(const Catalog: string;\n  const Schema: string; const Table: string; Unique: Boolean;\n  Approximate: Boolean): IZResultSet;\nvar\n  Is_Unique, Accuracy: string;\nbegin\n    Result:=inherited UncachedGetIndexInfo(Catalog, Schema, Table, Unique, Approximate);\n\n    if Unique then\n      Is_Unique := '''Y'''\n    else Is_Unique := '''N''';\n    if Approximate then\n      Accuracy := '''Q'''\n    else Accuracy := '''E''';\n\n    with GetStatement.ExecuteQuery(\n      Format('exec sp_statistics %s, %s, %s, ''%%'', %s, %s',\n      [ComposeObjectString(Table), ComposeObjectString(Schema), ComposeObjectString(Catalog), Is_Unique, Accuracy])) do\n    begin\n      while Next do\n      begin\n        Result.MoveToInsertRow;\n        Result.UpdateStringByName('TABLE_CAT',\n          GetStringByName('TABLE_QUALIFIER'));\n        Result.UpdateStringByName('TABLE_SCHEM',\n          GetStringByName('TABLE_OWNER'));\n        Result.UpdateStringByName('TABLE_NAME',\n          GetStringByName('TABLE_NAME'));\n        Result.UpdateBooleanByName('NON_UNIQUE',\n          GetShortByName('NON_UNIQUE') = 1);\n        Result.UpdateStringByName('INDEX_QUALIFIER',\n          GetStringByName('INDEX_QUALIFIER'));\n        Result.UpdateStringByName('INDEX_NAME',\n          GetStringByName('INDEX_NAME'));\n        Result.UpdateShortByName('TYPE',\n          GetShortByName('TYPE'));\n        Result.UpdateShortByName('ORDINAL_POSITION',\n          GetShortByName('SEQ_IN_INDEX'));\n        Result.UpdateStringByName('COLUMN_NAME',\n          GetStringByName('COLUMN_NAME'));\n        Result.UpdateStringByName('ASC_OR_DESC',\n          GetStringByName('COLLATION'));\n        Result.UpdateIntByName('CARDINALITY',\n          GetIntByName('CARDINALITY'));\n        Result.UpdateIntByName('PAGES',\n          GetIntByName('PAGES'));\n        Result.UpdateStringByName('FILTER_CONDITION',\n          GetStringByName('FILTER_CONDITION'));\n        Result.InsertRow;\n      end;\n      Close;\n    end;\n    Result.BeforeFirst;\nend;\n\n{ TZSybaseDatabaseMetadata }\n\n{**\n  Constructs a database information object and returns the interface to it. Used\n  internally by the constructor.\n  @return the database information object interface\n}\nfunction TZSybaseDatabaseMetadata.CreateDatabaseInfo: IZDatabaseInfo;\nbegin\n  Result := TZSybaseDatabaseInfo.Create(Self);\nend;\n\n{**\n  Gets a description of the stored procedures available in a\n  catalog.\n\n  <P>Only procedure descriptions matching the schema and\n  procedure name criteria are returned.  They are ordered by\n  PROCEDURE_SCHEM, and PROCEDURE_NAME.\n\n  <P>Each procedure description has the the following columns:\n   <OL>\n        <LI><B>PROCEDURE_CAT</B> String => procedure catalog (may be null)\n        <LI><B>PROCEDURE_SCHEM</B> String => procedure schema (may be null)\n        <LI><B>PROCEDURE_NAME</B> String => procedure name\n   <LI> reserved for future use\n   <LI> reserved for future use\n   <LI> reserved for future use\n        <LI><B>REMARKS</B> String => explanatory comment on the procedure\n        <LI><B>PROCEDURE_TYPE</B> short => kind of procedure:\n       <UL>\n       <LI> procedureResultUnknown - May return a result\n       <LI> procedureNoResult - Does not return a result\n       <LI> procedureReturnsResult - Returns a result\n       </UL>\n   </OL>\n\n  @param catalog a catalog name; \"\" retrieves those without a\n  catalog; null means drop catalog name from the selection criteria\n  @param schemaPattern a schema name pattern; \"\" retrieves those\n  without a schema\n  @param procedureNamePattern a procedure name pattern\n  @return <code>ResultSet</code> - each row is a procedure description\n  @see #getSearchStringEscape\n}\nfunction TZSybaseDatabaseMetadata.UncachedGetProcedures(const Catalog: string;\n  const SchemaPattern: string; const ProcedureNamePattern: string): IZResultSet;\nbegin\n    Result:=inherited UncachedGetProcedures(Catalog, SchemaPattern, ProcedureNamePattern);\n\n    with GetStatement.ExecuteQuery(\n      Format('exec sp_jdbc_stored_procedures %s, %s, %s',\n      [ComposeObjectString(Catalog), ComposeObjectString(SchemaPattern), ComposeObjectString(ProcedureNamePattern)])) do\n    begin\n      while Next do\n      begin\n        Result.MoveToInsertRow;\n        Result.UpdateStringByName('PROCEDURE_CAT',\n          GetStringByName('PROCEDURE_CAT'));\n        Result.UpdateStringByName('PROCEDURE_SCHEM',\n          GetStringByName('PROCEDURE_SCHEM'));\n        Result.UpdateStringByName('PROCEDURE_NAME',\n          GetStringByName('PROCEDURE_NAME'));\n        Result.UpdateStringByName('REMARKS',\n          GetStringByName('REMARKS'));\n        Result.UpdateShortByName('PROCEDURE_TYPE',\n          GetShortByName('PROCEDURE_TYPE'));\n        Result.InsertRow;\n      end;\n      Close;\n    end;\nend;\n\n{**\n  Gets a description of a catalog's stored procedure parameters\n  and result columns.\n\n  <P>Only descriptions matching the schema, procedure and\n  parameter name criteria are returned.  They are ordered by\n  PROCEDURE_SCHEM and PROCEDURE_NAME. Within this, the return value,\n  if any, is first. Next are the parameter descriptions in call\n  order. The column descriptions follow in column number order.\n\n  <P>Each row in the <code>ResultSet</code> is a parameter description or\n  column description with the following fields:\n   <OL>\n        <LI><B>PROCEDURE_CAT</B> String => procedure catalog (may be null)\n        <LI><B>PROCEDURE_SCHEM</B> String => procedure schema (may be null)\n        <LI><B>PROCEDURE_NAME</B> String => procedure name\n        <LI><B>COLUMN_NAME</B> String => column/parameter name\n        <LI><B>COLUMN_TYPE</B> Short => kind of column/parameter:\n       <UL>\n       <LI> procedureColumnUnknown - nobody knows\n       <LI> procedureColumnIn - IN parameter\n       <LI> procedureColumnInOut - INOUT parameter\n       <LI> procedureColumnOut - OUT parameter\n       <LI> procedureColumnReturn - procedure return value\n       <LI> procedureColumnResult - result column in <code>ResultSet</code>\n       </UL>\n   <LI><B>DATA_TYPE</B> short => SQL type from java.sql.Types\n        <LI><B>TYPE_NAME</B> String => SQL type name, for a UDT type the\n   type name is fully qualified\n        <LI><B>PRECISION</B> int => precision\n        <LI><B>LENGTH</B> int => length in bytes of data\n        <LI><B>SCALE</B> short => scale\n        <LI><B>RADIX</B> short => radix\n        <LI><B>NULLABLE</B> short => can it contain NULL?\n       <UL>\n       <LI> procedureNoNulls - does not allow NULL values\n       <LI> procedureNullable - allows NULL values\n       <LI> procedureNullableUnknown - nullability unknown\n       </UL>\n        <LI><B>REMARKS</B> String => comment describing parameter/column\n   </OL>\n\n  <P><B>Note:</B> Some databases may not return the column\n  descriptions for a procedure. Additional columns beyond\n  REMARKS can be defined by the database.\n\n  @param catalog a catalog name; \"\" retrieves those without a\n  catalog; null means drop catalog name from the selection criteria\n  @param schemaPattern a schema name pattern; \"\" retrieves those\n  without a schema\n  @param procedureNamePattern a procedure name pattern\n  @param columnNamePattern a column name pattern\n  @return <code>ResultSet</code> - each row describes a stored procedure parameter or\n       column\n  @see #getSearchStringEscape\n}\nfunction TZSybaseDatabaseMetadata.UncachedGetProcedureColumns(const Catalog: string;\n  const SchemaPattern: string; const ProcedureNamePattern: string;\n  const ColumnNamePattern: string): IZResultSet;\nvar\n  ProcNamePart: string;\n  NumberPart: string;\n  status2: Integer;\nbegin\n    Result:=inherited UncachedGetProcedureColumns(Catalog, SchemaPattern, ProcedureNamePattern, ColumnNamePattern);\n\n    with GetStatement.ExecuteQuery(\n      Format('exec sp_jdbc_getprocedurecolumns %s, %s, %s, %s',\n      [ComposeObjectString(Catalog), ComposeObjectString(SchemaPattern), ComposeObjectString(ProcedureNamePattern), ComposeObjectString(ColumnNamePattern)])) do\n    begin\n      while Next do\n      begin\n        Result.MoveToInsertRow;\n        Result.UpdateStringByName('PROCEDURE_CAT',\n          GetStringByName('PROCEDURE_CAT'));\n        Result.UpdateStringByName('PROCEDURE_SCHEM',\n          GetStringByName('PROCEDURE_SCHEM'));\n        Result.UpdateStringByName('PROCEDURE_NAME',\n          GetStringByName('PROCEDURE_NAME'));\n        Result.UpdateStringByName('COLUMN_NAME',\n          GetStringByName('COLUMN_NAME'));\n        case GetShortByName('COLUMN_TYPE') of\n          0, 1: Result.UpdateShortByName('COLUMN_TYPE', Ord(pctIn));\n          2: Result.UpdateShortByName('COLUMN_TYPE', Ord(pctInOut));\n          3: Result.UpdateShortByName('COLUMN_TYPE', Ord(pctUnknown));\n          4: Result.UpdateShortByName('COLUMN_TYPE', Ord(pctInOut));\n          5: Result.UpdateShortByName('COLUMN_TYPE', Ord(pctReturn));\n        else\n          Result.UpdateShortByName('COLUMN_TYPE', Ord(pctUnknown));\n        end;\n        Result.UpdateShortByName('DATA_TYPE',\n          Ord(ConvertODBCToSqlType(GetShortByName('DATA_TYPE'), ConSettings.CPType)));\n        Result.UpdateStringByName('TYPE_NAME',\n          GetStringByName('TYPE_NAME'));\n        Result.UpdateIntByName('PRECISION',\n          GetIntByName('PRECISION'));\n        Result.UpdateIntByName('LENGTH',\n          GetIntByName('LENGTH'));\n        Result.UpdateShortByName('SCALE',\n          GetShortByName('SCALE'));\n        Result.UpdateShortByName('RADIX',\n          GetShortByName('RADIX'));\n        Result.UpdateShortByName('NULLABLE',\n          GetShortByName('NULLABLE'));\n        Result.UpdateStringByName('REMARKS',\n          GetStringByName('REMARKS'));\n        Result.InsertRow;\n      end;\n      Close;\n    end;\n    Result.BeforeFirst;\n\n    NumberPart := '1';\n    ProcNamePart := '';\n    if AnsiPos(';', ProcNamePart) > 0 then\n    begin\n      NumberPart := Copy(ProcNamePart, LastDelimiter(';', ProcNamePart) + 1,\n        Length(ProcNamePart));\n      if NumberPart = '' then\n        NumberPart := '1';\n\n      ProcNamePart := Copy(ProcNamePart, 1, LastDelimiter(';', ProcNamePart));\n      if ProcNamePart[Length(ProcNamePart)] = ';' then\n        Delete(ProcNamePart, Length(ProcNamePart), 1);\n    end;\n  //status2 is added in sybase ASE 12.5 to store the storedprocedure parameters\n  // input/output type this column does not exists in prior versions.\n  // In prior versions there is no way to determine between input or output type.\n    with GetStatement.ExecuteQuery(\n      Format('select c.* from syscolumns c inner join sysobjects o on'\n      + ' (o.id = c.id) where o.name = %s and c.number = %s order by colid',\n      [AnsiQuotedStr(ProcNamePart, ''''), NumberPart])) do\n    begin\n      Result.Next;//Skip return parameter\n      while Next do\n      begin\n        Result.Next;\n        if FindColumn('status2') >= 1 then\n          status2 := GetShortByName('status2')\n        else\n          status2 := 0;\n        case status2 of\n          0, 1: Result.UpdateShortByName('COLUMN_TYPE', Ord(pctIn));\n          2: Result.UpdateShortByName('COLUMN_TYPE', Ord(pctInOut));\n          3: Result.UpdateShortByName('COLUMN_TYPE', Ord(pctUnknown));\n          4: Result.UpdateShortByName('COLUMN_TYPE', Ord(pctInOut));\n          5: Result.UpdateShortByName('COLUMN_TYPE', Ord(pctReturn));\n        else\n          Result.UpdateShortByName('COLUMN_TYPE', Ord(pctUnknown));\n        end;\n        Result.UpdateRow;\n      end;\n      Close;\n    end;\nend;\n\n{**\n  Gets a description of tables available in a catalog.\n\n  <P>Only table descriptions matching the catalog, schema, table\n  name and type criteria are returned.  They are ordered by\n  TABLE_TYPE, TABLE_SCHEM and TABLE_NAME.\n\n  <P>Each table description has the following columns:\n   <OL>\n        <LI><B>TABLE_CAT</B> String => table catalog (may be null)\n        <LI><B>TABLE_SCHEM</B> String => table schema (may be null)\n        <LI><B>TABLE_NAME</B> String => table name\n        <LI><B>TABLE_TYPE</B> String => table type.  Typical types are \"TABLE\",\n                        \"VIEW\", \"SYSTEM TABLE\", \"GLOBAL TEMPORARY\",\n                        \"LOCAL TEMPORARY\", \"ALIAS\", \"SYNONYM\".\n        <LI><B>REMARKS</B> String => explanatory comment on the table\n   </OL>\n\n  <P><B>Note:</B> Some databases may not return information for\n  all tables.\n\n  @param catalog a catalog name; \"\" retrieves those without a\n  catalog; null means drop catalog name from the selection criteria\n  @param schemaPattern a schema name pattern; \"\" retrieves those\n  without a schema\n  @param tableNamePattern a table name pattern\n  @param types a list of table types to include; null returns all types\n  @return <code>ResultSet</code> - each row is a table description\n  @see #getSearchStringEscape\n}\nfunction TZSybaseDatabaseMetadata.UncachedGetTables(const Catalog: string;\n  const SchemaPattern: string; const TableNamePattern: string;\n  const Types: TStringDynArray): IZResultSet;\nvar\n  I: Integer;\n  TableTypes: string;\nbegin\n    Result:=inherited UncachedGetTables(Catalog, SchemaPattern, TableNamePattern, Types);\n\n    TableTypes := '';\n    for I := 0 to Length(Types) - 1 do\n    begin\n      if TableTypes <> '' then\n        TableTypes := TableTypes + ',';\n      TableTypes := TableTypes + AnsiQuotedStr(Types[I], '''');\n    end;\n\n  with GetStatement.ExecuteQuery(\n    Format('exec sp_jdbc_tables %s, %s, %s, %s',\n    [ComposeObjectString(TableNamePattern), ComposeObjectString(SchemaPattern), ComposeObjectString(Catalog), ComposeObjectString(TableTypes)])) do\n  begin\n    while Next do\n      while Next do\n      begin\n        Result.MoveToInsertRow;\n        Result.UpdateStringByName('TABLE_CAT',\n          GetStringByName('TABLE_CAT'));\n        Result.UpdateStringByName('TABLE_SCHEM',\n          GetStringByName('TABLE_SCHEM'));\n        Result.UpdateStringByName('TABLE_NAME',\n          GetStringByName('TABLE_NAME'));\n        Result.UpdateStringByName('TABLE_TYPE',\n          GetStringByName('TABLE_TYPE'));\n        Result.UpdateStringByName('REMARKS',\n          GetStringByName('REMARKS'));\n        Result.InsertRow;\n      end;\n      Close;\n    end;\nend;\n\n{**\n  Gets the schema names available in this database.  The results\n  are ordered by schema name.\n\n  <P>The schema column is:\n   <OL>\n        <LI><B>TABLE_SCHEM</B> String => schema name\n   </OL>\n\n  @return <code>ResultSet</code> - each row has a single String column that is a\n  schema name\n}\nfunction TZSybaseDatabaseMetadata.UncachedGetSchemas: IZResultSet;\nbegin\n    Result:=inherited UncachedGetSchemas;\n\n    with GetStatement.ExecuteQuery('exec sp_jdbc_getschemas') do\n    begin\n      while Next do\n      begin\n        Result.MoveToInsertRow;\n        Result.UpdateStringByName('TABLE_SCHEM',\n          GetStringByName('TABLE_SCHEM'));\n        Result.InsertRow;\n      end;\n      Close;\n    end;\nend;\n\n{**\n  Gets the catalog names available in this database.  The results\n  are ordered by catalog name.\n\n  <P>The catalog column is:\n   <OL>\n        <LI><B>TABLE_CAT</B> String => catalog name\n   </OL>\n\n  @return <code>ResultSet</code> - each row has a single String column that is a\n  catalog name\n}\nfunction TZSybaseDatabaseMetadata.UncachedGetCatalogs: IZResultSet;\nbegin\n    Result:=inherited UncachedGetCatalogs;\n\n    with GetStatement.ExecuteQuery('exec sp_jdbc_getcatalogs') do\n    begin\n      while Next do\n      begin\n        Result.MoveToInsertRow;\n        Result.UpdateStringByName('TABLE_CAT',\n          GetStringByName('TABLE_CAT'));\n        Result.InsertRow;\n      end;\n      Close;\n    end;\nend;\n\n{**\n  Gets the table types available in this database.  The results\n  are ordered by table type.\n\n  <P>The table type is:\n   <OL>\n        <LI><B>TABLE_TYPE</B> String => table type.  Typical types are \"TABLE\",\n                        \"VIEW\", \"SYSTEM TABLE\", \"GLOBAL TEMPORARY\",\n                        \"LOCAL TEMPORARY\", \"ALIAS\", \"SYNONYM\".\n   </OL>\n\n  @return <code>ResultSet</code> - each row has a single String column that is a\n  table type\n}\nfunction TZSybaseDatabaseMetadata.UncachedGetTableTypes: IZResultSet;\nconst\n  TableTypes: array[0..2] of string = ('SYSTEM TABLE', 'TABLE', 'VIEW');\nvar\n  I: Integer;\nbegin\n    Result:=inherited UncachedGetTableTypes;\n\n    for I := 0 to 2 do\n    begin\n      Result.MoveToInsertRow;\n      Result.UpdateStringByName('TABLE_TYPE', TableTypes[I]);\n      Result.InsertRow;\n    end;\nend;\n\n{**\n  Gets a description of table columns available in\n  the specified catalog.\n\n  <P>Only column descriptions matching the catalog, schema, table\n  and column name criteria are returned.  They are ordered by\n  TABLE_SCHEM, TABLE_NAME and ORDINAL_POSITION.\n\n  <P>Each column description has the following columns:\n   <OL>\n        <LI><B>TABLE_CAT</B> String => table catalog (may be null)\n        <LI><B>TABLE_SCHEM</B> String => table schema (may be null)\n        <LI><B>TABLE_NAME</B> String => table name\n        <LI><B>COLUMN_NAME</B> String => column name\n        <LI><B>DATA_TYPE</B> short => SQL type from java.sql.Types\n        <LI><B>TYPE_NAME</B> String => Data source dependent type name,\n   for a UDT the type name is fully qualified\n        <LI><B>COLUMN_SIZE</B> int => column size.  For char or date\n            types this is the maximum number of characters, for numeric or\n            decimal types this is precision.\n        <LI><B>BUFFER_LENGTH</B> is not used.\n        <LI><B>DECIMAL_DIGITS</B> int => the number of fractional digits\n        <LI><B>NUM_PREC_RADIX</B> int => Radix (typically either 10 or 2)\n        <LI><B>NULLABLE</B> int => is NULL allowed?\n       <UL>\n       <LI> columnNoNulls - might not allow NULL values\n       <LI> columnNullable - definitely allows NULL values\n       <LI> columnNullableUnknown - nullability unknown\n       </UL>\n        <LI><B>REMARKS</B> String => comment describing column (may be null)\n        <LI><B>COLUMN_DEF</B> String => default value (may be null)\n        <LI><B>SQL_DATA_TYPE</B> int => unused\n        <LI><B>SQL_DATETIME_SUB</B> int => unused\n        <LI><B>CHAR_OCTET_LENGTH</B> int => for char types the\n        maximum number of bytes in the column\n        <LI><B>ORDINAL_POSITION</B> int => index of column in table\n       (starting at 1)\n        <LI><B>IS_NULLABLE</B> String => \"NO\" means column definitely\n       does not allow NULL values; \"YES\" means the column might\n       allow NULL values.  An empty string means nobody knows.\n   </OL>\n\n  @param catalog a catalog name; \"\" retrieves those without a\n  catalog; null means drop catalog name from the selection criteria\n  @param schemaPattern a schema name pattern; \"\" retrieves those\n  without a schema\n  @param tableNamePattern a table name pattern\n  @param columnNamePattern a column name pattern\n  @return <code>ResultSet</code> - each row is a column description\n  @see #getSearchStringEscape\n}\nfunction TZSybaseDatabaseMetadata.UncachedGetColumns(const Catalog: string;\n  const SchemaPattern: string; const TableNamePattern: string;\n  const ColumnNamePattern: string): IZResultSet;\nbegin\n    Result:=inherited UncachedGetColumns(Catalog, SchemaPattern, TableNamePattern, ColumnNamePattern);\n\n    with GetStatement.ExecuteQuery(\n      Format('exec sp_jdbc_columns %s, %s, %s, %s',\n      [ComposeObjectString(TableNamePattern), ComposeObjectString(SchemaPattern), ComposeObjectString(Catalog), ComposeObjectString(ColumnNamePattern)])) do\n    begin\n      while Next do\n      begin\n        Result.MoveToInsertRow;\n        Result.UpdateStringByName('TABLE_CAT',\n          ''{GetStringByName('TABLE_CAT')});\n        Result.UpdateStringByName('TABLE_SCHEM',\n          ''{GetStringByName('TABLE_SCHEM')});\n        Result.UpdateStringByName('TABLE_NAME',\n          GetStringByName('TABLE_NAME'));\n        Result.UpdateStringByName('COLUMN_NAME',\n          GetStringByName('COLUMN_NAME'));\n  //The value in the resultset will be used\n  //      Result.UpdateShortByName('DATA_TYPE',\n  //        Ord(ConvertODBCToSqlType(GetShortByName('DATA_TYPE'))));\n        Result.UpdateStringByName('TYPE_NAME',\n          GetStringByName('TYPE_NAME'));\n        Result.UpdateIntByName('COLUMN_SIZE',\n          GetIntByName('COLUMN_SIZE'));\n        Result.UpdateIntByName('BUFFER_LENGTH',\n          GetIntByName('BUFFER_LENGTH'));\n        Result.UpdateIntByName('DECIMAL_DIGITS',\n          GetIntByName('DECIMAL_DIGITS'));\n        Result.UpdateIntByName('NUM_PREC_RADIX',\n          GetShortByName('NUM_PREC_RADIX'));\n        Result.UpdateShortByName('NULLABLE',\n          GetShortByName('NULLABLE'));\n        Result.UpdateStringByName('REMARKS',\n          GetStringByName('REMARKS'));\n        Result.UpdateStringByName('COLUMN_DEF',\n          GetStringByName('COLUMN_DEF'));\n        Result.UpdateShortByName('SQL_DATA_TYPE',\n          GetShortByName('SQL_DATA_TYPE'));\n        Result.UpdateShortByName('SQL_DATETIME_SUB',\n          GetShortByName('SQL_DATETIME_SUB'));\n        Result.UpdateIntByName('CHAR_OCTET_LENGTH',\n          GetIntByName('CHAR_OCTET_LENGTH'));\n        Result.UpdateIntByName('ORDINAL_POSITION',\n          GetIntByName('ORDINAL_POSITION'));\n        Result.UpdateStringByName('IS_NULLABLE',\n          GetStringByName('IS_NULLABLE'));\n        Result.InsertRow;\n      end;\n      Close;\n    end;\n    Result.BeforeFirst;\n    with GetStatement.ExecuteQuery(\n      Format('select c.colid, c.name, c.type, c.prec, c.scale, c.status'\n      + ' from syscolumns c inner join sysobjects o on (o.id = c.id)'\n      + ' where o.name = %s order by colid', [AnsiQuotedStr(TableNamePattern, '''')])) do\n    begin\n      while Next do\n      begin\n        Result.Next;\n        Result.UpdateBooleanByName('AUTO_INCREMENT',\n          (GetShortByName('status') and $80) <> 0);\n        Result.UpdateNullByName('CASE_SENSITIVE');\n        Result.UpdateBooleanByName('SEARCHABLE',\n          not (GetShortByName('type') in [34, 35]));\n        Result.UpdateBooleanByName('WRITABLE',\n          ((GetShortByName('status') and $80) = 0)\n          (*and (GetShortByName('type') <> 37)*));   // <<<< *DEBUG WARUM?\n        Result.UpdateBooleanByName('DEFINITELYWRITABLE',\n          Result.GetBooleanByName('WRITABLE'));\n        Result.UpdateBooleanByName('READONLY',\n          not Result.GetBooleanByName('WRITABLE'));\n        if Result.GetBooleanByName('AUTO_INCREMENT') then\n        begin\n          Result.UpdateShortByName('NULLABLE', 1);\n          Result.UpdateStringByName('IS_NULLABLE', 'YES');\n        end;\n        Result.UpdateRow;\n      end;\n      Close;\n    end;\nend;\n\n{**\n  Gets a description of the access rights for a table's columns.\n\n  <P>Only privileges matching the column name criteria are\n  returned.  They are ordered by COLUMN_NAME and PRIVILEGE.\n\n  <P>Each privilige description has the following columns:\n   <OL>\n        <LI><B>TABLE_CAT</B> String => table catalog (may be null)\n        <LI><B>TABLE_SCHEM</B> String => table schema (may be null)\n        <LI><B>TABLE_NAME</B> String => table name\n        <LI><B>COLUMN_NAME</B> String => column name\n        <LI><B>GRANTOR</B> => grantor of access (may be null)\n        <LI><B>GRANTEE</B> String => grantee of access\n        <LI><B>PRIVILEGE</B> String => name of access (SELECT,\n       INSERT, UPDATE, REFRENCES, ...)\n        <LI><B>IS_GRANTABLE</B> String => \"YES\" if grantee is permitted\n       to grant to others; \"NO\" if not; null if unknown\n   </OL>\n\n  @param catalog a catalog name; \"\" retrieves those without a\n  catalog; null means drop catalog name from the selection criteria\n  @param schema a schema name; \"\" retrieves those without a schema\n  @param table a table name\n  @param columnNamePattern a column name pattern\n  @return <code>ResultSet</code> - each row is a column privilege description\n  @see #getSearchStringEscape\n}\nfunction TZSybaseDatabaseMetadata.UncachedGetColumnPrivileges(const Catalog: string;\n  const Schema: string; const Table: string; const ColumnNamePattern: string): IZResultSet;\nbegin\n    Result:=inherited UncachedGetColumnPrivileges(Catalog, Schema, Table, ColumnNamePattern);\n\n    with GetStatement.ExecuteQuery(\n      Format('exec sp_jdbc_getcolumnprivileges %s, %s, %s, %s',\n      [ComposeObjectString(Catalog), ComposeObjectString(Schema), ComposeObjectString(Table),\n       ComposeObjectString(ColumnNamePattern, '''%''')])) do\n    begin\n      while Next do\n      begin\n        Result.MoveToInsertRow;\n        Result.UpdateStringByName('TABLE_CAT',\n          GetStringByName('TABLE_CAT'));\n        Result.UpdateStringByName('TABLE_SCHEM',\n          GetStringByName('TABLE_SCHEM'));\n        Result.UpdateStringByName('TABLE_NAME',\n          GetStringByName('TABLE_NAME'));\n        Result.UpdateStringByName('COLUMN_NAME',\n          GetStringByName('COLUMN_NAME'));\n        Result.UpdateStringByName('GRANTOR',\n          GetStringByName('GRANTOR'));\n        Result.UpdateStringByName('GRANTEE',\n          GetStringByName('GRANTEE'));\n        Result.UpdateStringByName('PRIVILEGE',\n          GetStringByName('PRIVILEGE'));\n        Result.UpdateStringByName('IS_GRANTABLE',\n          GetStringByName('IS_GRANTABLE'));\n        Result.InsertRow;\n      end;\n      Close;\n    end;\nend;\n\n{**\n  Gets a description of the access rights for each table available\n  in a catalog. Note that a table privilege applies to one or\n  more columns in the table. It would be wrong to assume that\n  this priviledge applies to all columns (this may be true for\n  some systems but is not true for all.)\n\n  <P>Only privileges matching the schema and table name\n  criteria are returned.  They are ordered by TABLE_SCHEM,\n  TABLE_NAME, and PRIVILEGE.\n\n  <P>Each privilige description has the following columns:\n   <OL>\n        <LI><B>TABLE_CAT</B> String => table catalog (may be null)\n        <LI><B>TABLE_SCHEM</B> String => table schema (may be null)\n        <LI><B>TABLE_NAME</B> String => table name\n        <LI><B>GRANTOR</B> => grantor of access (may be null)\n        <LI><B>GRANTEE</B> String => grantee of access\n        <LI><B>PRIVILEGE</B> String => name of access (SELECT,\n       INSERT, UPDATE, REFRENCES, ...)\n        <LI><B>IS_GRANTABLE</B> String => \"YES\" if grantee is permitted\n       to grant to others; \"NO\" if not; null if unknown\n   </OL>\n\n  @param catalog a catalog name; \"\" retrieves those without a\n  catalog; null means drop catalog name from the selection criteria\n  @param schemaPattern a schema name pattern; \"\" retrieves those\n  without a schema\n  @param tableNamePattern a table name pattern\n  @return <code>ResultSet</code> - each row is a table privilege description\n  @see #getSearchStringEscape\n}\nfunction TZSybaseDatabaseMetadata.UncachedGetTablePrivileges(const Catalog: string;\n  const SchemaPattern: string; const TableNamePattern: string): IZResultSet;\nbegin\n    Result:=inherited UncachedGetTablePrivileges(Catalog, SchemaPattern, TableNamePattern);\n\n    with GetStatement.ExecuteQuery(\n      Format('exec sp_jdbc_gettableprivileges %s, %s, %s',\n      [ComposeObjectString(Catalog), ComposeObjectString(SchemaPattern), ComposeObjectString(TableNamePattern)])) do\n    begin\n      while Next do\n      begin\n        Result.MoveToInsertRow;\n        Result.UpdateStringByName('TABLE_CAT',\n          GetStringByName('TABLE_CAT'));\n        Result.UpdateStringByName('TABLE_SCHEM',\n          GetStringByName('TABLE_SCHEM'));\n        Result.UpdateStringByName('TABLE_NAME',\n          GetStringByName('TABLE_NAME'));\n        Result.UpdateStringByName('GRANTOR',\n          GetStringByName('GRANTOR'));\n        Result.UpdateStringByName('GRANTEE',\n          GetStringByName('GRANTEE'));\n        Result.UpdateStringByName('PRIVILEGE',\n          GetStringByName('PRIVILEGE'));\n        Result.UpdateStringByName('IS_GRANTABLE',\n          GetStringByName('IS_GRANTABLE'));\n        Result.InsertRow;\n      end;\n      Close;\n    end;\nend;\n\n{**\n  Gets a description of a table's columns that are automatically\n  updated when any value in a row is updated.  They are\n  unordered.\n\n  <P>Each column description has the following columns:\n   <OL>\n        <LI><B>SCOPE</B> short => is not used\n        <LI><B>COLUMN_NAME</B> String => column name\n        <LI><B>DATA_TYPE</B> short => SQL data type from java.sql.Types\n        <LI><B>TYPE_NAME</B> String => Data source dependent type name\n        <LI><B>COLUMN_SIZE</B> int => precision\n        <LI><B>BUFFER_LENGTH</B> int => length of column value in bytes\n        <LI><B>DECIMAL_DIGITS</B> short  => scale\n        <LI><B>PSEUDO_COLUMN</B> short => is this a pseudo column\n       like an Oracle ROWID\n       <UL>\n       <LI> versionColumnUnknown - may or may not be pseudo column\n       <LI> versionColumnNotPseudo - is NOT a pseudo column\n       <LI> versionColumnPseudo - is a pseudo column\n       </UL>\n   </OL>\n\n  @param catalog a catalog name; \"\" retrieves those without a\n  catalog; null means drop catalog name from the selection criteria\n  @param schema a schema name; \"\" retrieves those without a schema\n  @param table a table name\n  @return <code>ResultSet</code> - each row is a column description\n  @exception SQLException if a database access error occurs\n}\nfunction TZSybaseDatabaseMetadata.UncachedGetVersionColumns(const Catalog: string;\n  const Schema: string; const Table: string): IZResultSet;\nbegin\n    Result:=inherited UncachedGetVersionColumns(Catalog, Schema, Table);\n\n    with GetStatement.ExecuteQuery(\n      Format('exec sp_jdbc_getversioncolumns %s, %s, %s',\n      [ComposeObjectString(Catalog), ComposeObjectString(Schema), ComposeObjectString(Table)])) do\n    begin\n      while Next do\n      begin\n        Result.MoveToInsertRow;\n        Result.UpdateShortByName('SCOPE',\n          GetShortByName('SCOPE'));\n        Result.UpdateStringByName('COLUMN_NAME',\n          GetStringByName('COLUMN_NAME'));\n        Result.UpdateShortByName('DATA_TYPE',\n          Ord(ConvertODBCToSqlType(GetShortByName('DATA_TYPE'), ConSettings.CPType)));\n        Result.UpdateStringByName('TYPE_NAME',\n          GetStringByName('TYPE_NAME'));\n        Result.UpdateIntByName('COLUMN_SIZE',\n          GetIntByName('COLUMN_SIZE'));\n        Result.UpdateIntByName('BUFFER_LENGTH',\n          GetIntByName('BUFFER_LENGTH'));\n        Result.UpdateIntByName('DECIMAL_DIGITS',\n          GetIntByName('DECIMAL_DIGITS'));\n        Result.UpdateShortByName('PSEUDO_COLUMN',\n          GetShortByName('PSEUDO_COLUMN'));\n        Result.InsertRow;\n      end;\n      Close;\n    end;\nend;\n\n{**\n  Gets a description of a table's primary key columns.  They\n  are ordered by COLUMN_NAME.\n\n  <P>Each primary key column description has the following columns:\n   <OL>\n        <LI><B>TABLE_CAT</B> String => table catalog (may be null)\n        <LI><B>TABLE_SCHEM</B> String => table schema (may be null)\n        <LI><B>TABLE_NAME</B> String => table name\n        <LI><B>COLUMN_NAME</B> String => column name\n        <LI><B>KEY_SEQ</B> short => sequence number within primary key\n        <LI><B>PK_NAME</B> String => primary key name (may be null)\n   </OL>\n\n  @param catalog a catalog name; \"\" retrieves those without a\n  catalog; null means drop catalog name from the selection criteria\n  @param schema a schema name; \"\" retrieves those\n  without a schema\n  @param table a table name\n  @return <code>ResultSet</code> - each row is a primary key column description\n  @exception SQLException if a database access error occurs\n}\nfunction TZSybaseDatabaseMetadata.UncachedGetPrimaryKeys(const Catalog: string;\n  const Schema: string; const Table: string): IZResultSet;\nbegin\n    Result:=inherited UncachedGetPrimaryKeys(Catalog, Schema, Table);\n\n    with GetStatement.ExecuteQuery(\n      Format('exec sp_jdbc_primarykey %s, %s, %s',\n      [ComposeObjectString(Catalog), ComposeObjectString(Schema), ComposeObjectString(Table)])) do\n    begin\n      while Next do\n      begin\n        Result.MoveToInsertRow;\n        Result.UpdateStringByName('TABLE_CAT',\n          GetStringByName('TABLE_CAT'));\n        Result.UpdateStringByName('TABLE_SCHEM',\n          GetStringByName('TABLE_SCHEM'));\n        Result.UpdateStringByName('TABLE_NAME',\n          GetStringByName('TABLE_NAME'));\n        Result.UpdateStringByName('COLUMN_NAME',\n          GetStringByName('COLUMN_NAME'));\n        Result.UpdateShortByName('KEY_SEQ',\n          GetShortByName('KEY_SEQ'));\n        Result.UpdateStringByName('PK_NAME',\n          GetStringByName('PK_NAME'));\n        Result.InsertRow;\n      end;\n      Close;\n    end;\nend;\n\n{**\n  Gets a description of the primary key columns that are\n  referenced by a table's foreign key columns (the primary keys\n  imported by a table).  They are ordered by PKTABLE_CAT,\n  PKTABLE_SCHEM, PKTABLE_NAME, and KEY_SEQ.\n\n  <P>Each primary key column description has the following columns:\n   <OL>\n        <LI><B>PKTABLE_CAT</B> String => primary key table catalog\n       being imported (may be null)\n        <LI><B>PKTABLE_SCHEM</B> String => primary key table schema\n       being imported (may be null)\n        <LI><B>PKTABLE_NAME</B> String => primary key table name\n       being imported\n        <LI><B>PKCOLUMN_NAME</B> String => primary key column name\n       being imported\n        <LI><B>FKTABLE_CAT</B> String => foreign key table catalog (may be null)\n        <LI><B>FKTABLE_SCHEM</B> String => foreign key table schema (may be null)\n        <LI><B>FKTABLE_NAME</B> String => foreign key table name\n        <LI><B>FKCOLUMN_NAME</B> String => foreign key column name\n        <LI><B>KEY_SEQ</B> short => sequence number within foreign key\n        <LI><B>UPDATE_RULE</B> short => What happens to\n        foreign key when primary is updated:\n       <UL>\n       <LI> importedNoAction - do not allow update of primary\n                key if it has been imported\n       <LI> importedKeyCascade - change imported key to agree\n                with primary key update\n       <LI> importedKeySetNull - change imported key to NULL if\n                its primary key has been updated\n       <LI> importedKeySetDefault - change imported key to default values\n                if its primary key has been updated\n       <LI> importedKeyRestrict - same as importedKeyNoAction\n                                  (for ODBC 2.x compatibility)\n       </UL>\n        <LI><B>DELETE_RULE</B> short => What happens to\n       the foreign key when primary is deleted.\n       <UL>\n       <LI> importedKeyNoAction - do not allow delete of primary\n                key if it has been imported\n       <LI> importedKeyCascade - delete rows that import a deleted key\n       <LI> importedKeySetNull - change imported key to NULL if\n                its primary key has been deleted\n       <LI> importedKeyRestrict - same as importedKeyNoAction\n                                  (for ODBC 2.x compatibility)\n       <LI> importedKeySetDefault - change imported key to default if\n                its primary key has been deleted\n       </UL>\n        <LI><B>FK_NAME</B> String => foreign key name (may be null)\n        <LI><B>PK_NAME</B> String => primary key name (may be null)\n        <LI><B>DEFERRABILITY</B> short => can the evaluation of foreign key\n       constraints be deferred until commit\n       <UL>\n       <LI> importedKeyInitiallyDeferred - see SQL92 for definition\n       <LI> importedKeyInitiallyImmediate - see SQL92 for definition\n       <LI> importedKeyNotDeferrable - see SQL92 for definition\n       </UL>\n   </OL>\n\n  @param catalog a catalog name; \"\" retrieves those without a\n  catalog; null means drop catalog name from the selection criteria\n  @param schema a schema name; \"\" retrieves those\n  without a schema\n  @param table a table name\n  @return <code>ResultSet</code> - each row is a primary key column description\n  @see #getExportedKeys\n}\nfunction TZSybaseDatabaseMetadata.UncachedGetImportedKeys(const Catalog: string;\n  const Schema: string; const Table: string): IZResultSet;\nbegin\n    Result:=inherited UncachedGetImportedKeys(Catalog, Schema, Table);\n\n    with GetStatement.ExecuteQuery(\n      Format('exec sp_jdbc_importkey %s, %s, %s',\n      [ComposeObjectString(Catalog), ComposeObjectString(Schema), ComposeObjectString(Table)])) do\n    begin\n      while Next do\n      begin\n        Result.MoveToInsertRow;\n        Result.UpdateStringByName('PKTABLE_CAT',\n          GetStringByName('PKTABLE_CAT'));\n        Result.UpdateStringByName('PKTABLE_SCHEM',\n          GetStringByName('PKTABLE_SCHEM'));\n        Result.UpdateStringByName('PKTABLE_NAME',\n          GetStringByName('PKTABLE_NAME'));\n        Result.UpdateStringByName('PKCOLUMN_NAME',\n          GetStringByName('PKCOLUMN_NAME'));\n        Result.UpdateStringByName('FKTABLE_CAT',\n          GetStringByName('FKTABLE_CAT'));\n        Result.UpdateStringByName('FKTABLE_SCHEM',\n          GetStringByName('FKTABLE_SCHEM'));\n        Result.UpdateStringByName('FKTABLE_NAME',\n          GetStringByName('FKTABLE_NAME'));\n        Result.UpdateStringByName('FKCOLUMN_NAME',\n          GetStringByName('FKCOLUMN_NAME'));\n        Result.UpdateShortByName('KEY_SEQ',\n          GetShortByName('KEY_SEQ'));\n        Result.UpdateShortByName('UPDATE_RULE',\n          GetShortByName('UPDATE_RULE'));\n        Result.UpdateShortByName('DELETE_RULE',\n          GetShortByName('DELETE_RULE'));\n        Result.UpdateStringByName('FK_NAME',\n          GetStringByName('FK_NAME'));\n        Result.UpdateStringByName('PK_NAME',\n          GetStringByName('PK_NAME'));\n        Result.UpdateIntByName('DEFERRABILITY',\n          GetIntByName('DEFERRABILITY'));\n        Result.InsertRow;\n      end;\n      Close;\n    end;\nend;\n\n{**\n  Gets a description of the foreign key columns that reference a\n  table's primary key columns (the foreign keys exported by a\n  table).  They are ordered by FKTABLE_CAT, FKTABLE_SCHEM,\n  FKTABLE_NAME, and KEY_SEQ.\n\n  <P>Each foreign key column description has the following columns:\n   <OL>\n        <LI><B>PKTABLE_CAT</B> String => primary key table catalog (may be null)\n        <LI><B>PKTABLE_SCHEM</B> String => primary key table schema (may be null)\n        <LI><B>PKTABLE_NAME</B> String => primary key table name\n        <LI><B>PKCOLUMN_NAME</B> String => primary key column name\n        <LI><B>FKTABLE_CAT</B> String => foreign key table catalog (may be null)\n       being exported (may be null)\n        <LI><B>FKTABLE_SCHEM</B> String => foreign key table schema (may be null)\n       being exported (may be null)\n        <LI><B>FKTABLE_NAME</B> String => foreign key table name\n       being exported\n        <LI><B>FKCOLUMN_NAME</B> String => foreign key column name\n       being exported\n        <LI><B>KEY_SEQ</B> short => sequence number within foreign key\n        <LI><B>UPDATE_RULE</B> short => What happens to\n        foreign key when primary is updated:\n       <UL>\n       <LI> importedNoAction - do not allow update of primary\n                key if it has been imported\n       <LI> importedKeyCascade - change imported key to agree\n                with primary key update\n       <LI> importedKeySetNull - change imported key to NULL if\n                its primary key has been updated\n       <LI> importedKeySetDefault - change imported key to default values\n                if its primary key has been updated\n       <LI> importedKeyRestrict - same as importedKeyNoAction\n                                  (for ODBC 2.x compatibility)\n       </UL>\n        <LI><B>DELETE_RULE</B> short => What happens to\n       the foreign key when primary is deleted.\n       <UL>\n       <LI> importedKeyNoAction - do not allow delete of primary\n                key if it has been imported\n       <LI> importedKeyCascade - delete rows that import a deleted key\n       <LI> importedKeySetNull - change imported key to NULL if\n                its primary key has been deleted\n       <LI> importedKeyRestrict - same as importedKeyNoAction\n                                  (for ODBC 2.x compatibility)\n       <LI> importedKeySetDefault - change imported key to default if\n                its primary key has been deleted\n       </UL>\n        <LI><B>FK_NAME</B> String => foreign key name (may be null)\n        <LI><B>PK_NAME</B> String => primary key name (may be null)\n        <LI><B>DEFERRABILITY</B> short => can the evaluation of foreign key\n       constraints be deferred until commit\n       <UL>\n       <LI> importedKeyInitiallyDeferred - see SQL92 for definition\n       <LI> importedKeyInitiallyImmediate - see SQL92 for definition\n       <LI> importedKeyNotDeferrable - see SQL92 for definition\n       </UL>\n   </OL>\n\n  @param catalog a catalog name; \"\" retrieves those without a\n  catalog; null means drop catalog name from the selection criteria\n  @param schema a schema name; \"\" retrieves those\n  without a schema\n  @param table a table name\n  @return <code>ResultSet</code> - each row is a foreign key column description\n  @see #getImportedKeys\n}\nfunction TZSybaseDatabaseMetadata.UncachedGetExportedKeys(const Catalog: string;\n  const Schema: string; const Table: string): IZResultSet;\nbegin\n    Result:=inherited UncachedGetExportedKeys(Catalog, Schema, Table);\n\n    with GetStatement.ExecuteQuery(\n      Format('exec sp_jdbc_exportkey %s, %s, %s',\n      [ComposeObjectString(Catalog), ComposeObjectString(Schema), ComposeObjectString(Table)])) do\n    begin\n      while Next do\n      begin\n        Result.MoveToInsertRow;\n        Result.UpdateStringByName('PKTABLE_CAT',\n          GetStringByName('PKTABLE_CAT'));\n        Result.UpdateStringByName('PKTABLE_SCHEM',\n          GetStringByName('PKTABLE_SCHEM'));\n        Result.UpdateStringByName('PKTABLE_NAME',\n          GetStringByName('PKTABLE_NAME'));\n        Result.UpdateStringByName('PKCOLUMN_NAME',\n          GetStringByName('PKCOLUMN_NAME'));\n        Result.UpdateStringByName('FKTABLE_CAT',\n          GetStringByName('FKTABLE_CAT'));\n        Result.UpdateStringByName('FKTABLE_SCHEM',\n          GetStringByName('FKTABLE_SCHEM'));\n        Result.UpdateStringByName('FKTABLE_NAME',\n          GetStringByName('FKTABLE_NAME'));\n        Result.UpdateStringByName('FKCOLUMN_NAME',\n          GetStringByName('FKCOLUMN_NAME'));\n        Result.UpdateShortByName('KEY_SEQ',\n          GetShortByName('KEY_SEQ'));\n        Result.UpdateShortByName('UPDATE_RULE',\n          GetShortByName('UPDATE_RULE'));\n        Result.UpdateShortByName('DELETE_RULE',\n          GetShortByName('DELETE_RULE'));\n        Result.UpdateStringByName('FK_NAME',\n          GetStringByName('FK_NAME'));\n        Result.UpdateStringByName('PK_NAME',\n          GetStringByName('PK_NAME'));\n        Result.UpdateIntByName('DEFERRABILITY',\n          GetIntByName('DEFERRABILITY'));\n        Result.InsertRow;\n      end;\n      Close;\n    end;\nend;\n\n{**\n  Gets a description of the foreign key columns in the foreign key\n  table that reference the primary key columns of the primary key\n  table (describe how one table imports another's key.) This\n  should normally return a single foreign key/primary key pair\n  (most tables only import a foreign key from a table once.)  They\n  are ordered by FKTABLE_CAT, FKTABLE_SCHEM, FKTABLE_NAME, and\n  KEY_SEQ.\n\n  <P>Each foreign key column description has the following columns:\n   <OL>\n        <LI><B>PKTABLE_CAT</B> String => primary key table catalog (may be null)\n        <LI><B>PKTABLE_SCHEM</B> String => primary key table schema (may be null)\n        <LI><B>PKTABLE_NAME</B> String => primary key table name\n        <LI><B>PKCOLUMN_NAME</B> String => primary key column name\n        <LI><B>FKTABLE_CAT</B> String => foreign key table catalog (may be null)\n       being exported (may be null)\n        <LI><B>FKTABLE_SCHEM</B> String => foreign key table schema (may be null)\n       being exported (may be null)\n        <LI><B>FKTABLE_NAME</B> String => foreign key table name\n       being exported\n        <LI><B>FKCOLUMN_NAME</B> String => foreign key column name\n       being exported\n        <LI><B>KEY_SEQ</B> short => sequence number within foreign key\n        <LI><B>UPDATE_RULE</B> short => What happens to\n        foreign key when primary is updated:\n       <UL>\n       <LI> importedNoAction - do not allow update of primary\n                key if it has been imported\n       <LI> importedKeyCascade - change imported key to agree\n                with primary key update\n       <LI> importedKeySetNull - change imported key to NULL if\n                its primary key has been updated\n       <LI> importedKeySetDefault - change imported key to default values\n                if its primary key has been updated\n       <LI> importedKeyRestrict - same as importedKeyNoAction\n                                  (for ODBC 2.x compatibility)\n       </UL>\n        <LI><B>DELETE_RULE</B> short => What happens to\n       the foreign key when primary is deleted.\n       <UL>\n       <LI> importedKeyNoAction - do not allow delete of primary\n                key if it has been imported\n       <LI> importedKeyCascade - delete rows that import a deleted key\n       <LI> importedKeySetNull - change imported key to NULL if\n                its primary key has been deleted\n       <LI> importedKeyRestrict - same as importedKeyNoAction\n                                  (for ODBC 2.x compatibility)\n       <LI> importedKeySetDefault - change imported key to default if\n                its primary key has been deleted\n       </UL>\n        <LI><B>FK_NAME</B> String => foreign key name (may be null)\n        <LI><B>PK_NAME</B> String => primary key name (may be null)\n        <LI><B>DEFERRABILITY</B> short => can the evaluation of foreign key\n       constraints be deferred until commit\n       <UL>\n       <LI> importedKeyInitiallyDeferred - see SQL92 for definition\n       <LI> importedKeyInitiallyImmediate - see SQL92 for definition\n       <LI> importedKeyNotDeferrable - see SQL92 for definition\n       </UL>\n   </OL>\n\n  @param primaryCatalog a catalog name; \"\" retrieves those without a\n  catalog; null means drop catalog name from the selection criteria\n  @param primarySchema a schema name; \"\" retrieves those\n  without a schema\n  @param primaryTable the table name that exports the key\n  @param foreignCatalog a catalog name; \"\" retrieves those without a\n  catalog; null means drop catalog name from the selection criteria\n  @param foreignSchema a schema name; \"\" retrieves those\n  without a schema\n  @param foreignTable the table name that imports the key\n  @return <code>ResultSet</code> - each row is a foreign key column description\n  @see #getImportedKeys\n}\nfunction TZSybaseDatabaseMetadata.UncachedGetCrossReference(const PrimaryCatalog: string;\n  const PrimarySchema: string; const PrimaryTable: string; const ForeignCatalog: string;\n  const ForeignSchema: string; const ForeignTable: string): IZResultSet;\nbegin\n    Result:=inherited UncachedGetCrossReference(PrimaryCatalog, PrimarySchema, PrimaryTable,\n                                        ForeignCatalog, ForeignSchema, ForeignTable);\n\n    with GetStatement.ExecuteQuery(\n      Format('exec sp_jdbc_getcrossreferences %s, %s, %s, %s, %s, %s',\n      [ComposeObjectString(PrimaryCatalog), ComposeObjectString(PrimarySchema), ComposeObjectString(PrimaryTable),\n       ComposeObjectString(ForeignCatalog), ComposeObjectString(ForeignSchema), ComposeObjectString(ForeignTable)])) do\n    begin\n      while Next do\n      begin\n        Result.MoveToInsertRow;\n        Result.UpdateStringByName('PKTABLE_CAT',\n          GetStringByName('PKTABLE_CAT'));\n        Result.UpdateStringByName('PKTABLE_SCHEM',\n          GetStringByName('PKTABLE_SCHEM'));\n        Result.UpdateStringByName('PKTABLE_NAME',\n          GetStringByName('PKTABLE_NAME'));\n        Result.UpdateStringByName('PKCOLUMN_NAME',\n          GetStringByName('PKCOLUMN_NAME'));\n        Result.UpdateStringByName('FKTABLE_CAT',\n          GetStringByName('FKTABLE_CAT'));\n        Result.UpdateStringByName('FKTABLE_SCHEM',\n          GetStringByName('FKTABLE_SCHEM'));\n        Result.UpdateStringByName('FKTABLE_NAME',\n          GetStringByName('FKTABLE_NAME'));\n        Result.UpdateStringByName('FKCOLUMN_NAME',\n          GetStringByName('FKCOLUMN_NAME'));\n        Result.UpdateShortByName('KEY_SEQ',\n          GetShortByName('KEY_SEQ'));\n        Result.UpdateShortByName('UPDATE_RULE',\n          GetShortByName('UPDATE_RULE'));\n        Result.UpdateShortByName('DELETE_RULE',\n          GetShortByName('DELETE_RULE'));\n        Result.UpdateStringByName('FK_NAME',\n          GetStringByName('FK_NAME'));\n        Result.UpdateStringByName('PK_NAME',\n          GetStringByName('PK_NAME'));\n        Result.UpdateIntByName('DEFERRABILITY',\n          GetIntByName('DEFERRABILITY'));\n        Result.InsertRow;\n      end;\n      Close;\n    end;\nend;\n\n{**\n  Gets a description of all the standard SQL types supported by\n  this database. They are ordered by DATA_TYPE and then by how\n  closely the data type maps to the corresponding JDBC SQL type.\n\n  <P>Each type description has the following columns:\n   <OL>\n        <LI><B>TYPE_NAME</B> String => Type name\n        <LI><B>DATA_TYPE</B> short => SQL data type from java.sql.Types\n        <LI><B>PRECISION</B> int => maximum precision\n        <LI><B>LITERAL_PREFIX</B> String => prefix used to quote a literal\n       (may be null)\n        <LI><B>LITERAL_SUFFIX</B> String => suffix used to quote a literal\n        (may be null)\n        <LI><B>CREATE_PARAMS</B> String => parameters used in creating\n       the type (may be null)\n        <LI><B>NULLABLE</B> short => can you use NULL for this type?\n       <UL>\n       <LI> typeNoNulls - does not allow NULL values\n       <LI> typeNullable - allows NULL values\n       <LI> typeNullableUnknown - nullability unknown\n       </UL>\n        <LI><B>CASE_SENSITIVE</B> boolean=> is it case sensitive?\n        <LI><B>SEARCHABLE</B> short => can you use \"WHERE\" based on this type:\n       <UL>\n       <LI> typePredNone - No support\n       <LI> typePredChar - Only supported with WHERE .. LIKE\n       <LI> typePredBasic - Supported except for WHERE .. LIKE\n       <LI> typeSearchable - Supported for all WHERE ..\n       </UL>\n        <LI><B>UNSIGNED_ATTRIBUTE</B> boolean => is it unsigned?\n        <LI><B>FIXED_PREC_SCALE</B> boolean => can it be a money value?\n        <LI><B>AUTO_INCREMENT</B> boolean => can it be used for an\n       auto-increment value?\n        <LI><B>LOCAL_TYPE_NAME</B> String => localized version of type name\n       (may be null)\n        <LI><B>MINIMUM_SCALE</B> short => minimum scale supported\n        <LI><B>MAXIMUM_SCALE</B> short => maximum scale supported\n        <LI><B>SQL_DATA_TYPE</B> int => unused\n        <LI><B>SQL_DATETIME_SUB</B> int => unused\n        <LI><B>NUM_PREC_RADIX</B> int => usually 2 or 10\n   </OL>\n\n  @return <code>ResultSet</code> - each row is an SQL type description\n}\nfunction TZSybaseDatabaseMetadata.UncachedGetTypeInfo: IZResultSet;\nbegin\n    Result:=inherited UncachedGetTypeInfo;\n\n    with GetStatement.ExecuteQuery('exec sp_jdbc_datatype_info') do\n    begin\n      while Next do\n      begin\n        Result.MoveToInsertRow;\n        Result.UpdateStringByName('TYPE_NAME',\n          GetStringByName('TYPE_NAME'));\n        Result.UpdateShortByName('DATA_TYPE',\n          Ord(ConvertODBCToSqlType(GetShortByName('DATA_TYPE'), ConSettings.CPType)));\n        Result.UpdateIntByName('PRECISION',\n          GetIntByName('PRECISION'));\n        Result.UpdateStringByName('LITERAL_PREFIX',\n          GetStringByName('LITERAL_PREFIX'));\n        Result.UpdateStringByName('LITERAL_SUFFIX',\n          GetStringByName('LITERAL_SUFFIX'));\n        Result.UpdateStringByName('CREATE_PARAMS',\n          GetStringByName('CREATE_PARAMS'));\n        Result.UpdateShortByName('NULLABLE',\n          GetShortByName('NULLABLE'));\n        Result.UpdateBooleanByName('CASE_SENSITIVE',\n          GetShortByName('CASE_SENSITIVE') = 1);\n        Result.UpdateShortByName('SEARCHABLE',\n          GetShortByName('SEARCHABLE'));\n        Result.UpdateBooleanByName('UNSIGNED_ATTRIBUTE',\n          GetShortByName('UNSIGNED_ATTRIBUTE') = 1);\n        Result.UpdateBooleanByName('FIXED_PREC_SCALE',\n          GetShortByName('FIXED_PREC_SCALE') = 1);\n        Result.UpdateBooleanByName('AUTO_INCREMENT',\n          GetShortByName('AUTO_INCREMENT') = 1);\n        Result.UpdateStringByName('LOCAL_TYPE_NAME',\n          GetStringByName('LOCAL_TYPE_NAME'));\n        Result.UpdateShortByName('MINIMUM_SCALE',\n          GetShortByName('MINIMUM_SCALE'));\n        Result.UpdateShortByName('MAXIMUM_SCALE',\n          GetShortByName('MAXIMUM_SCALE'));\n        Result.UpdateShortByName('SQL_DATA_TYPE',\n          GetShortByName('SQL_DATA_TYPE'));\n        Result.UpdateShortByName('SQL_DATETIME_SUB',\n          GetShortByName('SQL_DATETIME_SUB'));\n        Result.UpdateShortByName('NUM_PREC_RADIX',\n          GetShortByName('NUM_PREC_RADIX'));\n        Result.InsertRow;\n      end;\n      Close;\n    end;\nend;\n\n{**\n  Gets a description of a table's indices and statistics. They are\n  ordered by NON_UNIQUE, TYPE, INDEX_NAME, and ORDINAL_POSITION.\n\n  <P>Each index column description has the following columns:\n   <OL>\n        <LI><B>TABLE_CAT</B> String => table catalog (may be null)\n        <LI><B>TABLE_SCHEM</B> String => table schema (may be null)\n        <LI><B>TABLE_NAME</B> String => table name\n        <LI><B>NON_UNIQUE</B> boolean => Can index values be non-unique?\n       false when TYPE is tableIndexStatistic\n        <LI><B>INDEX_QUALIFIER</B> String => index catalog (may be null);\n       null when TYPE is tableIndexStatistic\n        <LI><B>INDEX_NAME</B> String => index name; null when TYPE is\n       tableIndexStatistic\n        <LI><B>TYPE</B> short => index type:\n       <UL>\n       <LI> tableIndexStatistic - this identifies table statistics that are\n            returned in conjuction with a table's index descriptions\n       <LI> tableIndexClustered - this is a clustered index\n       <LI> tableIndexHashed - this is a hashed index\n       <LI> tableIndexOther - this is some other style of index\n       </UL>\n        <LI><B>ORDINAL_POSITION</B> short => column sequence number\n       within index; zero when TYPE is tableIndexStatistic\n        <LI><B>COLUMN_NAME</B> String => column name; null when TYPE is\n       tableIndexStatistic\n        <LI><B>ASC_OR_DESC</B> String => column sort sequence, \"A\" => ascending,\n       \"D\" => descending, may be null if sort sequence is not supported;\n       null when TYPE is tableIndexStatistic\n        <LI><B>CARDINALITY</B> int => When TYPE is tableIndexStatistic, then\n       this is the number of rows in the table; otherwise, it is the\n       number of unique values in the index.\n        <LI><B>PAGES</B> int => When TYPE is  tableIndexStatisic then\n       this is the number of pages used for the table, otherwise it\n       is the number of pages used for the current index.\n        <LI><B>FILTER_CONDITION</B> String => Filter condition, if any.\n       (may be null)\n   </OL>\n\n  @param catalog a catalog name; \"\" retrieves those without a\n  catalog; null means drop catalog name from the selection criteria\n  @param schema a schema name; \"\" retrieves those without a schema\n  @param table a table name\n  @param unique when true, return only indices for unique values;\n      when false, return indices regardless of whether unique or not\n  @param approximate when true, result is allowed to reflect approximate\n      or out of data values; when false, results are requested to be\n      accurate\n  @return <code>ResultSet</code> - each row is an index column description\n}\nfunction TZSybaseDatabaseMetadata.UncachedGetIndexInfo(const Catalog: string;\n  const Schema: string; const Table: string; Unique: Boolean;\n  Approximate: Boolean): IZResultSet;\nvar\n  Is_Unique, Accuracy: string;\nbegin\n    Result:=inherited UncachedGetIndexInfo(Catalog, Schema, Table, Unique, Approximate);\n\n    if Unique then\n      Is_Unique := '''1'''\n    else Is_Unique := '''0''';\n    if Approximate then\n      Accuracy := '''1'''\n    else Accuracy := '''0''';\n\n    with GetStatement.ExecuteQuery(\n      Format('exec sp_jdbc_getindexinfo %s, %s, %s, %s, %s',\n      [ComposeObjectString(Catalog), ComposeObjectString(Schema), ComposeObjectString(Table), Is_Unique, Accuracy])) do\n    begin\n      while Next do\n      begin\n        Result.MoveToInsertRow;\n        Result.UpdateStringByName('TABLE_CAT',\n          GetStringByName('TABLE_CAT'));\n        Result.UpdateStringByName('TABLE_SCHEM',\n          GetStringByName('TABLE_SCHEM'));\n        Result.UpdateStringByName('TABLE_NAME',\n          GetStringByName('TABLE_NAME'));\n        Result.UpdateBooleanByName('NON_UNIQUE',\n          GetShortByName('NON_UNIQUE') = 1);\n        Result.UpdateStringByName('INDEX_QUALIFIER',\n          GetStringByName('INDEX_QUALIFIER'));\n        Result.UpdateStringByName('INDEX_NAME',\n          GetStringByName('INDEX_NAME'));\n        Result.UpdateShortByName('TYPE',\n          GetShortByName('TYPE'));\n        Result.UpdateShortByName('ORDINAL_POSITION',\n          GetShortByName('ORDINAL_POSITION'));\n        Result.UpdateStringByName('COLUMN_NAME',\n          GetStringByName('COLUMN_NAME'));\n        Result.UpdateStringByName('ASC_OR_DESC',\n          GetStringByName('ASC_OR_DESC'));\n        Result.UpdateIntByName('CARDINALITY',\n          GetIntByName('CARDINALITY'));\n        Result.UpdateIntByName('PAGES',\n          GetIntByName('PAGES'));\n        Result.UpdateStringByName('FILTER_CONDITION',\n          GetStringByName('FILTER_CONDITION'));\n        Result.InsertRow;\n      end;\n      Close;\n    end;\nend;\n\n{**\n\n  Gets a description of the user-defined types defined in a particular\n  schema.  Schema-specific UDTs may have type JAVA_OBJECT, STRUCT,\n  or DISTINCT.\n\n  <P>Only types matching the catalog, schema, type name and type\n  criteria are returned.  They are ordered by DATA_TYPE, TYPE_SCHEM\n  and TYPE_NAME.  The type name parameter may be a fully-qualified\n  name.  In this case, the catalog and schemaPattern parameters are\n  ignored.\n\n  <P>Each type description has the following columns:\n   <OL>\n        <LI><B>TYPE_CAT</B> String => the type's catalog (may be null)\n        <LI><B>TYPE_SCHEM</B> String => type's schema (may be null)\n        <LI><B>TYPE_NAME</B> String => type name\n   <LI><B>CLASS_NAME</B> String => Java class name\n        <LI><B>DATA_TYPE</B> String => type value defined in java.sql.Types.\n   One of JAVA_OBJECT, STRUCT, or DISTINCT\n        <LI><B>REMARKS</B> String => explanatory comment on the type\n   </OL>\n\n  <P><B>Note:</B> If the driver does not support UDTs, an empty\n  result set is returned.\n\n  @param catalog a catalog name; \"\" retrieves those without a\n  catalog; null means drop catalog name from the selection criteria\n  @param schemaPattern a schema name pattern; \"\" retrieves those\n  without a schema\n  @param typeNamePattern a type name pattern; may be a fully-qualified name\n  @param types a list of user-named types to include (JAVA_OBJECT,\n  STRUCT, or DISTINCT); null returns all types\n  @return <code>ResultSet</code> - each row is a type description\n}\nfunction TZSybaseDatabaseMetadata.UncachedGetUDTs(const Catalog: string;\n  const SchemaPattern: string; const TypeNamePattern: string;\n  const Types: TIntegerDynArray): IZResultSet;\nvar\n  I: Integer;\n  UDTypes: string;\nbegin\n    Result:=inherited UncachedGetUDTs(Catalog, SchemaPattern, TypeNamePattern, Types);\n\n    UDTypes := '';\n    for I := 0 to Length(Types) - 1 do\n    begin\n      if Length(UDTypes) > 0 then\n        UDTypes := UDTypes + ',';\n      UDTypes := UDTypes + AnsiQuotedStr(IntToStr(Types[I]), '''');\n    end;\n\n  with GetStatement.ExecuteQuery(\n    Format('exec sp_jdbc_getudts %s, %s, %s, %s',\n    [ComposeObjectString(Catalog), ComposeObjectString(SchemaPattern, '''%'''),\n     ComposeObjectString(TypeNamePattern, '''%'''), ComposeObjectString(UDTypes)])) do\n  begin\n    while Next do\n      while Next do\n      begin\n        Result.MoveToInsertRow;\n        Result.UpdateStringByName('TYPE_CAT',\n          GetStringByName('TYPE_CAT'));\n        Result.UpdateStringByName('TYPE_SCHEM',\n          GetStringByName('TYPE_SCHEM'));\n        Result.UpdateStringByName('TYPE_NAME',\n          GetStringByName('TYPE_NAME'));\n        Result.UpdateStringByName('JAVA_CLASS',\n          GetStringByName('JAVA_CLASS'));\n        Result.UpdateShortByName('DATA_TYPE',\n          Ord(ConvertODBCToSqlType(GetShortByName('DATA_TYPE'), ConSettings.CPType)));\n        Result.UpdateStringByName('REMARKS',\n          GetStringByName('REMARKS'));\n        Result.InsertRow;\n      end;\n      Close;\n    end;\nend;\n\nend.\n\n\n\n"
  },
  {
    "path": "lib/zeosdbo/src/dbc/ZDbcDbLibResultSet.pas",
    "content": "{*********************************************************}\n{                                                         }\n{                 Zeos Database Objects                   }\n{         DBLib Resultset common functionality            }\n{                                                         }\n{        Originally written by Janos Fegyverneki          }\n{                                                         }\n{*********************************************************}\n\n{@********************************************************}\n{    Copyright (c) 1999-2012 Zeos Development Group       }\n{                                                         }\n{ License Agreement:                                      }\n{                                                         }\n{ This library is distributed in the hope that it will be }\n{ useful, but WITHOUT ANY WARRANTY; without even the      }\n{ implied warranty of MERCHANTABILITY or FITNESS FOR      }\n{ A PARTICULAR PURPOSE.  See the GNU Lesser General       }\n{ Public License for more details.                        }\n{                                                         }\n{ The source code of the ZEOS Libraries and packages are  }\n{ distributed under the Library GNU General Public        }\n{ License (see the file COPYING / COPYING.ZEOS)           }\n{ with the following  modification:                       }\n{ As a special exception, the copyright holders of this   }\n{ library give you permission to link this library with   }\n{ independent modules to produce an executable,           }\n{ regardless of the license terms of these independent    }\n{ modules, and to copy and distribute the resulting       }\n{ executable under terms of your choice, provided that    }\n{ you also meet, for each linked independent module,      }\n{ the terms and conditions of the license of that module. }\n{ An independent module is a module which is not derived  }\n{ from or based on this library. If you modify this       }\n{ library, you may extend this exception to your version  }\n{ of the library, but you are not obligated to do so.     }\n{ If you do not wish to do so, delete this exception      }\n{ statement from your version.                            }\n{                                                         }\n{                                                         }\n{ The project web site is located on:                     }\n{   http://zeos.firmos.at  (FORUM)                        }\n{   http://sourceforge.net/p/zeoslib/tickets/ (BUGTRACKER)}\n{   svn://svn.code.sf.net/p/zeoslib/code-0/trunk (SVN)    }\n{                                                         }\n{   http://www.sourceforge.net/projects/zeoslib.          }\n{                                                         }\n{                                                         }\n{                                 Zeos Development Group. }\n{********************************************************@}\n\nunit ZDbcDbLibResultSet;\n\ninterface\n\n{$I ZDbc.inc}\n\nuses\n{$IFNDEF FPC}\n  DateUtils,\n{$ENDIF}\n  {$IFDEF WITH_TOBJECTLIST_INLINE}System.Types, System.Contnrs{$ELSE}Types{$ENDIF},\n  Classes, {$IFDEF MSEgui}mclasses,{$ENDIF} SysUtils,\n  ZDbcIntfs, ZDbcResultSet, ZCompatibility, ZDbcResultsetMetadata,\n  ZDbcGenericResolver, ZDbcCachedResultSet, ZDbcCache, ZDbcDBLib,\n  ZPlainDbLibConstants, ZPlainDBLibDriver;\n\ntype\n  {** Implements DBLib ResultSet. }\n  TZDBLibResultSet = class(TZAbstractResultSet)\n  private\n    FSQL: string;\n    FHandle: PDBPROCESS;\n    DBLibColTypeCache: TSmallIntDynArray;\n    DBLibColumnCount: Integer;\n    procedure CheckColumnIndex(ColumnIndex: Integer);\n  protected\n    FDBLibConnection: IZDBLibConnection;\n    FPlainDriver: IZDBLibPlainDriver;\n    procedure Open; override;\n    function InternalGetString(ColumnIndex: Integer): RawByteString; override;\n  public\n    constructor Create(Statement: IZStatement; SQL: string);\n    destructor Destroy; override;\n\n    procedure Close; override;\n\n    function IsNull(ColumnIndex: Integer): Boolean; override;\n    function GetString(ColumnIndex: Integer): String; override;\n    function GetUnicodeString(ColumnIndex: Integer): WideString; override;\n    function GetBoolean(ColumnIndex: Integer): Boolean; override;\n    function GetByte(ColumnIndex: Integer): Byte; override;\n    function GetShort(ColumnIndex: Integer): SmallInt; override;\n    function GetInt(ColumnIndex: Integer): Integer; override;\n    function GetLong(ColumnIndex: Integer): Int64; override;\n    function GetFloat(ColumnIndex: Integer): Single; override;\n    function GetDouble(ColumnIndex: Integer): Double; override;\n    function GetBigDecimal(ColumnIndex: Integer): Extended; override;\n    function GetBytes(ColumnIndex: Integer): TByteDynArray; override;\n    function GetDate(ColumnIndex: Integer): TDateTime; override;\n    function GetTime(ColumnIndex: Integer): TDateTime; override;\n    function GetTimestamp(ColumnIndex: Integer): TDateTime; override;\n    function GetBlob(ColumnIndex: Integer): IZBlob; override;\n\n    function MoveAbsolute(Row: Integer): Boolean; override;\n    function Next: Boolean; override;\n  end;\n\n  {** Implements a cached resolver with mssql and sybase specific functionality. }\n  TZDBLibCachedResolver = class (TZGenericCachedResolver, IZCachedResolver)\n  private\n    FAutoColumnIndex: Integer;\n  public\n    constructor Create(Statement: IZStatement; Metadata: IZResultSetMetadata);\n\n    procedure PostUpdates(Sender: IZCachedResultSet; UpdateType: TZRowUpdateType;\n      OldRowAccessor, NewRowAccessor: TZRowAccessor); override;\n  end;\n\nimplementation\n\nuses ZMessages, ZDbcLogging, ZDbcDBLibUtils, ZEncoding\n  {$IFDEF WITH_UNITANSISTRINGS}, AnsiStrings{$ENDIF}\n  {$IFDEF WITH_WIDESTRUTILS}, WideStrUtils {$ENDIF}\n;\n\n{ TZDBLibResultSet }\n\n{**\n  Constructs this object, assignes main properties and\n  opens the record set.\n  @param Statement a related SQL statement object.\n  @param Handle a DBLib specific query handle.\n}\nconstructor TZDBLibResultSet.Create(Statement: IZStatement; SQL: string);\nbegin\n  inherited Create(Statement, SQL, nil, Statement.GetConnection.GetConSettings);\n  Statement.GetConnection.QueryInterface(IZDBLibConnection, FDBLibConnection);\n  FPlainDriver := FDBLibConnection.GetPlainDriver;\n  FHandle := FDBLibConnection.GetConnectionHandle;\n  FSQL := SQL;\n\n  Open;\nend;\n\n{**\n  Destroys this object and cleanups the memory.\n}\ndestructor TZDBLibResultSet.Destroy;\nbegin\n{ TODO -ofjanos -cGeneral : Does it need close here? }\n  Close;\n  inherited Destroy;\nend;\n\n{**\n  Opens this recordset.\n}\nprocedure TZDBLibResultSet.Open;\nvar\n  I: Integer;\n  ColumnInfo: TZColumnInfo;\n  ColName: string;\n  ColType: Integer;\nbegin\n//Check if the current statement can return rows\n  if FPlainDriver.dbCmdRow(FHandle) <> DBSUCCEED then\n    raise EZSQLException.Create(SCanNotRetrieveResultSetData);\n\n  { Fills the column info }\n  ColumnsInfo.Clear;\n  DBLibColumnCount := FPlainDriver.dbnumcols(FHandle);\n  SetLength(DBLibColTypeCache, DBLibColumnCount + 1);\n  for I := 1 to DBLibColumnCount do\n  begin\n    ColName := FPlainDriver.ZDbcString(FPlainDriver.dbColName(FHandle, I),\n      FDBLibConnection.GetConSettings);\n    ColType := FPlainDriver.dbColtype(FHandle, I);\n    ColumnInfo := TZColumnInfo.Create;\n\n    ColumnInfo.ColumnLabel := ColName;\n    ColumnInfo.ColumnName := ColName;\n    if Self.FDBLibConnection.FreeTDS then\n      ColumnInfo.ColumnType := ConvertFreeTDSToSqlType(ColType, ConSettings.CPType)\n    else\n      ColumnInfo.ColumnType := ConvertDBLibToSqlType(ColType, ConSettings.CPType);\n    ColumnInfo.Currency := (ColType = FPlainDriver.GetVariables.datatypes[Z_SQLMONEY]) or\n      (ColType = FPlainDriver.GetVariables.datatypes[Z_SQLMONEY4]) or\n      (ColType = FPlainDriver.GetVariables.datatypes[Z_SQLMONEYN]);;\n    ColumnInfo.Precision := FPlainDriver.dbCollen(FHandle, I);\n    ColumnInfo.Scale := 0;\n    if ColType = FPlainDriver.GetVariables.datatypes[Z_SQLINT1] then\n      ColumnInfo.Signed := False\n    else\n      ColumnInfo.Signed := True;\n\n    ColumnsInfo.Add(ColumnInfo);\n\n    DBLibColTypeCache[I] := ColType;\n  end;\n  inherited Open;\nend;\n\n{**\n  Releases this <code>ResultSet</code> object's database and\n  JDBC resources immediately instead of waiting for\n  this to happen when it is automatically closed.\n\n  <P><B>Note:</B> A <code>ResultSet</code> object\n  is automatically closed by the\n  <code>Statement</code> object that generated it when\n  that <code>Statement</code> object is closed,\n  re-executed, or is used to retrieve the next result from a\n  sequence of multiple results. A <code>ResultSet</code> object\n  is also automatically closed when it is garbage collected.\n}\nprocedure TZDBLibResultSet.Close;\nbegin\n{ TODO -ofjanos -cGeneral : Maybe it needs a dbcanquery here. }\n//  if Assigned(FHandle) then\n//    if not FPlainDriver.dbDead(FHandle) then\n//      if FPlainDriver.dbCanQuery(FHandle) <> DBSUCCEED then\n//        FDBLibConnection.CheckDBLibError(lcDisconnect, 'CLOSE QUERY');\n  FHandle := nil;\n  SetLength(DBLibColTypeCache, 0);\n  inherited Close;\nend;\n\n{**\n  Checks if the columnindex is in the proper range.\n  An exception is generated if somthing is not ok.\n\n  @param columnIndex the first column is 1, the second is 2, ...\n}\nprocedure TZDBLibResultSet.CheckColumnIndex(ColumnIndex: Integer);\nbegin\n  if (ColumnIndex > DBLibColumnCount) or (ColumnIndex < 1) then\n  begin\n    raise EZSQLException.Create(\n      Format(SColumnIsNotAccessable, [ColumnIndex]));\n  end;\nend;\n\n{**\n  Indicates if the value of the designated column in the current row\n  of this <code>ResultSet</code> object is Null.\n\n  @param columnIndex the first column is 1, the second is 2, ...\n  @return if the value is SQL <code>NULL</code>, the\n    value returned is <code>true</code>. <code>false</code> otherwise.\n}\nfunction TZDBLibResultSet.IsNull(ColumnIndex: Integer): Boolean;\nbegin\n  CheckClosed;\n  CheckColumnIndex(ColumnIndex);\n  Result := FPlainDriver.dbData(FHandle, ColumnIndex) = nil;\nend;\n\n{**\n  Gets the value of the designated column in the current row\n  of this <code>ResultSet</code> object as\n  a <code>String</code> in the Java programming language.\n\n  @param columnIndex the first column is 1, the second is 2, ...\n  @return the column value; if the value is SQL <code>NULL</code>, the\n    value returned is <code>null</code>\n}\nfunction TZDBLibResultSet.GetString(ColumnIndex: Integer): String;\nvar Tmp: RawByteString;\nbegin\n  if TZColumnInfo(ColumnsInfo[ColumnIndex-1]).ColumnType in [stString, stUnicodeString, stAsciiStream, stUnicodeStream]  then\n    if TZColumnInfo(ColumnsInfo[ColumnIndex-1]).InternalColumnType = stUnknown then\n    begin\n      Tmp := InternalGetString(ColumnIndex);\n      case DetectUTF8Encoding(Tmp) of\n        etUTF8:\n          begin\n            if TZColumnInfo(ColumnsInfo[ColumnIndex-1]).ColumnType in [stString, stUnicodeString] then\n              TZColumnInfo(ColumnsInfo[ColumnIndex-1]).InternalColumnType := stUnicodeString\n            else\n              TZColumnInfo(ColumnsInfo[ColumnIndex-1]).InternalColumnType := stUnicodeStream;\n            Result := ZDbcString(Tmp, zCP_UTF8)\n          end;\n        etAnsi:\n          begin\n            if TZColumnInfo(ColumnsInfo[ColumnIndex-1]).ColumnType in [stString, stUnicodeString] then\n              TZColumnInfo(ColumnsInfo[ColumnIndex-1]).InternalColumnType := stString\n            else\n              TZColumnInfo(ColumnsInfo[ColumnIndex-1]).InternalColumnType := stAsciiStream;\n            Result := ZDbcString(tmp, ConSettings^.ClientCodePage^.CP)\n          end;\n        else\n          Result := ZDbcString(tmp);\n      end;\n    end\n    else\n      if TZColumnInfo(ColumnsInfo[ColumnIndex-1]).InternalColumnType in [stUnicodeString, stUnicodeStream] then\n        Result := ZDbcString(InternalGetString(ColumnIndex), zCP_UTF8)\n      else\n        Result := ZDbcString(InternalGetString(ColumnIndex), ConSettings^.ClientCodePage^.CP)\n  else\n    Result := String(InternalGetString(ColumnIndex));\nend;\n\n{**\n  Gets the value of the designated column in the current row\n  of this <code>ResultSet</code> object as\n  a <code>WideString</code> in the Delphi programming language.\n\n  @param columnIndex the first column is 1, the second is 2, ...\n  @return the column value; if the value is SQL <code>NULL</code>, the\n    value returned is <code>null</code>\n}\nfunction TZDBLibResultSet.GetUnicodeString(ColumnIndex: Integer): WideString;\nvar Tmp: RawByteString;\nbegin\n  if TZColumnInfo(ColumnsInfo[ColumnIndex-1]).ColumnType in [stString, stUnicodeString, stAsciiStream, stUnicodeStream]  then\n    if TZColumnInfo(ColumnsInfo[ColumnIndex-1]).InternalColumnType = stUnknown then\n    begin\n      Tmp := InternalGetString(ColumnIndex);\n      case DetectUTF8Encoding(Tmp) of\n        etUTF8:\n          begin\n            if TZColumnInfo(ColumnsInfo[ColumnIndex-1]).ColumnType in [stString, stUnicodeString] then\n              TZColumnInfo(ColumnsInfo[ColumnIndex-1]).InternalColumnType := stUnicodeString\n            else\n              TZColumnInfo(ColumnsInfo[ColumnIndex-1]).InternalColumnType := stUnicodeStream;\n            Result := ZDbcUnicodeString(Tmp, zCP_UTF8)\n          end;\n        etAnsi:\n          begin\n            if TZColumnInfo(ColumnsInfo[ColumnIndex-1]).ColumnType in [stString, stUnicodeString] then\n              TZColumnInfo(ColumnsInfo[ColumnIndex-1]).InternalColumnType := stString\n            else\n              TZColumnInfo(ColumnsInfo[ColumnIndex-1]).InternalColumnType := stAsciiStream;\n            Result := ZDbcUnicodeString(tmp, ConSettings^.ClientCodePage^.CP)\n          end;\n        else\n          Result := ZDbcUnicodeString(tmp);\n      end;\n    end\n    else\n      if TZColumnInfo(ColumnsInfo[ColumnIndex-1]).InternalColumnType in [stUnicodeString, stUnicodeStream] then\n        Result := ZDbcUnicodeString(InternalGetString(ColumnIndex), zCP_UTF8)\n      else\n        Result := ZDbcUnicodeString(InternalGetString(ColumnIndex), ConSettings^.ClientCodePage^.CP)\n  else\n    Result := WideString(InternalGetString(ColumnIndex));\nend;\n\n{**\n  Gets the value of the designated column in the current row\n  of this <code>ResultSet</code> object as\n  a <code>String</code> in the Java programming language.\n\n  @param columnIndex the first column is 1, the second is 2, ...\n  @return the column value; if the value is SQL <code>NULL</code>, the\n    value returned is <code>null</code>\n}\nfunction TZDBLibResultSet.InternalGetString(ColumnIndex: Integer): RawByteString;\nvar\n  DL: Integer;\n  Data: Pointer;\n  DT: Integer;\nbegin\n  CheckClosed;\n  CheckColumnIndex(ColumnIndex);\n\n  DL := FPlainDriver.dbDatLen(FHandle, ColumnIndex);\n  Data := FPlainDriver.dbdata(FHandle, ColumnIndex);\n  DT := DBLibColTypeCache[ColumnIndex];\n  LastWasNull := Data = nil;\n\n  Result := '';\n  if Assigned(Data) then\n  begin\n    if (DT = FPlainDriver.GetVariables.datatypes[Z_SQLCHAR]) or\n      (DT = FPlainDriver.GetVariables.datatypes[Z_SQLTEXT]) then\n    begin\n      while (DL > 0) and (PAnsiChar(NativeUint(Data) + NativeUint(DL - 1))^ = ' ') do\n              Dec(DL);\n      if DL > 0 then\n      begin\n        SetLength(Result, DL);\n        Move(Data^, PAnsiChar(Result)^, DL);\n      end;\n    end else\n    if (DT = FPlainDriver.GetVariables.datatypes[Z_SQLIMAGE]) then\n    begin\n      SetLength(Result, DL);\n      Move(Data^, PAnsiChar(Result)^, DL);\n    end else\n    begin\n      SetLength(Result, 4001);\n      DL := FPlainDriver.dbconvert(FHandle, DT, Data, DL,\n        FPlainDriver.GetVariables.datatypes[Z_SQLCHAR], Pointer(PAnsiChar(Result)), Length(Result));\n      while (DL > 0) and (Result[DL] = ' ') do\n          Dec(DL);\n      SetLength(Result, DL);\n    end;\n  end;\n  //else\n\n  FDBLibConnection.CheckDBLibError(lcOther, 'GETSTRING');\nend;\n\n{**\n  Gets the value of the designated column in the current row\n  of this <code>ResultSet</code> object as\n  a <code>boolean</code> in the Java programming language.\n\n  @param columnIndex the first column is 1, the second is 2, ...\n  @return the column value; if the value is SQL <code>NULL</code>, the\n    value returned is <code>false</code>\n}\nfunction TZDBLibResultSet.GetBoolean(ColumnIndex: Integer): Boolean;\nvar\n  DL: Integer;\n  Data: Pointer;\n  DT: Integer;\nbegin\n  CheckClosed;\n  CheckColumnIndex(ColumnIndex);\n\n  DL := FPlainDriver.dbdatlen(FHandle, ColumnIndex);\n  Data := FPlainDriver.dbdata(FHandle, ColumnIndex);\n  DT := DBLibColTypeCache[ColumnIndex];\n  LastWasNull := Data = nil;\n\n  Result := False;\n  if Assigned(Data) then\n  begin\n    if DT = FPlainDriver.GetVariables.datatypes[Z_SQLBIT] then\n      Result := PBoolean(Data)^\n    else\n    begin\n      FPlainDriver.dbconvert(FHandle, DT, Data, DL, FPlainDriver.GetVariables.datatypes[Z_SQLBIT],\n        @Result, SizeOf(Result));\n    end;\n  end;\n  FDBLibConnection.CheckDBLibError(lcOther, 'GETBOOLEAN');\nend;\n\n{**\n  Gets the value of the designated column in the current row\n  of this <code>ResultSet</code> object as\n  a <code>byte</code> in the Java programming language.\n\n  @param columnIndex the first column is 1, the second is 2, ...\n  @return the column value; if the value is SQL <code>NULL</code>, the\n    value returned is <code>0</code>\n}\nfunction TZDBLibResultSet.GetByte(ColumnIndex: Integer): Byte;\nvar\n  DL: Integer;\n  Data: Pointer;\n  DT: Integer;\nbegin\n  CheckClosed;\n  CheckColumnIndex(ColumnIndex);\n\n  DL := FPlainDriver.dbdatlen(FHandle, ColumnIndex);\n  Data := FPlainDriver.dbdata(FHandle, ColumnIndex);\n  DT := DBLibColTypeCache[ColumnIndex];\n  LastWasNull := Data = nil;\n\n  Result := 0;\n  if Assigned(Data) then\n  begin\n    if DT = FPlainDriver.GetVariables.datatypes[Z_SQLINT1] then\n      Result := PByte(Data)^\n    else\n    begin\n      FPlainDriver.dbconvert(FHandle, DT, Data, DL, FPlainDriver.GetVariables.datatypes[Z_SQLINT1],\n        @Result, SizeOf(Result));\n    end;\n  end;\n  FDBLibConnection.CheckDBLibError(lcOther, 'GETBYTE');\nend;\n\n{**\n  Gets the value of the designated column in the current row\n  of this <code>ResultSet</code> object as\n  a <code>short</code> in the Java programming language.\n\n  @param columnIndex the first column is 1, the second is 2, ...\n  @return the column value; if the value is SQL <code>NULL</code>, the\n    value returned is <code>0</code>\n}\nfunction TZDBLibResultSet.GetShort(ColumnIndex: Integer): SmallInt;\nvar\n  DL: Integer;\n  Data: Pointer;\n  DT: Integer;\nbegin\n  CheckClosed;\n  CheckColumnIndex(ColumnIndex);\n\n  DL := FPlainDriver.dbdatlen(FHandle, ColumnIndex);\n  Data := FPlainDriver.dbdata(FHandle, ColumnIndex);\n  DT := DBLibColTypeCache[ColumnIndex];\n  LastWasNull := Data = nil;\n\n  Result := 0;\n  if Assigned(Data) then\n  begin\n    if DT = FPlainDriver.GetVariables.datatypes[Z_SQLINT2] then\n      Result := PSmallInt(Data)^\n    else\n    begin\n      FPlainDriver.dbconvert(FHandle, DT, Data, DL, FPlainDriver.GetVariables.datatypes[Z_SQLINT2],\n        @Result, SizeOf(Result));\n    end;\n  end;\n  FDBLibConnection.CheckDBLibError(lcOther, 'GETSHORT');\nend;\n\n{**\n  Gets the value of the designated column in the current row\n  of this <code>ResultSet</code> object as\n  an <code>int</code> in the Java programming language.\n\n  @param columnIndex the first column is 1, the second is 2, ...\n  @return the column value; if the value is SQL <code>NULL</code>, the\n    value returned is <code>0</code>\n}\nfunction TZDBLibResultSet.GetInt(ColumnIndex: Integer): Integer;\nvar\n  DL: Integer;\n  Data: Pointer;\n  DT: Integer;\nbegin\n  CheckClosed;\n  CheckColumnIndex(ColumnIndex);\n\n  DL := FPlainDriver.dbdatlen(FHandle, ColumnIndex);\n  Data := FPlainDriver.dbdata(FHandle, ColumnIndex);\n  DT := DBLibColTypeCache[ColumnIndex];\n  LastWasNull := Data = nil;\n\n  Result := 0;\n  if Assigned(Data) then\n  begin\n    if DT = FPlainDriver.GetVariables.datatypes[Z_SQLINT4] then\n      Result := PLongint(Data)^\n    else\n    begin\n      FPlainDriver.dbconvert(FHandle, DT, Data, DL, FPlainDriver.GetVariables.datatypes[Z_SQLINT4],\n        @Result, SizeOf(Result));\n    end;\n  end;\n  FDBLibConnection.CheckDBLibError(lcOther, 'GETINT');\nend;\n\n{**\n  Gets the value of the designated column in the current row\n  of this <code>ResultSet</code> object as\n  a <code>long</code> in the Java programming language.\n\n  @param columnIndex the first column is 1, the second is 2, ...\n  @return the column value; if the value is SQL <code>NULL</code>, the\n    value returned is <code>0</code>\n}\nfunction TZDBLibResultSet.GetLong(ColumnIndex: Integer): Int64;\nbegin\n  Result := GetInt(ColumnIndex);\nend;\n\n{**\n  Gets the value of the designated column in the current row\n  of this <code>ResultSet</code> object as\n  a <code>float</code> in the Java programming language.\n\n  @param columnIndex the first column is 1, the second is 2, ...\n  @return the column value; if the value is SQL <code>NULL</code>, the\n    value returned is <code>0</code>\n}\nfunction TZDBLibResultSet.GetFloat(ColumnIndex: Integer): Single;\nvar\n  DL: Integer;\n  Data: Pointer;\n  DT: Integer;\nbegin\n  CheckClosed;\n  CheckColumnIndex(ColumnIndex);\n\n  DL := FPlainDriver.dbdatlen(FHandle, ColumnIndex);\n  Data := FPlainDriver.dbdata(FHandle, ColumnIndex);\n  DT := DBLibColTypeCache[ColumnIndex];\n  LastWasNull := Data = nil;\n\n  Result := 0;\n  if Assigned(Data) then\n  begin\n    if DT = FPlainDriver.GetVariables.datatypes[Z_SQLFLT4] then\n      Result := PSingle(Data)^\n    else\n    begin\n      FPlainDriver.dbconvert(FHandle, DT, Data, DL, FPlainDriver.GetVariables.datatypes[Z_SQLFLT4],\n        @Result, SizeOf(Result));\n    end;\n  end;\n  FDBLibConnection.CheckDBLibError(lcOther, 'GETFLOAT');\nend;\n\n{**\n  Gets the value of the designated column in the current row\n  of this <code>ResultSet</code> object as\n  a <code>double</code> in the Java programming language.\n\n  @param columnIndex the first column is 1, the second is 2, ...\n  @return the column value; if the value is SQL <code>NULL</code>, the\n    value returned is <code>0</code>\n}\nfunction TZDBLibResultSet.GetDouble(ColumnIndex: Integer): Double;\nvar\n  DL: Integer;\n  Data: Pointer;\n  DT: Integer;\nbegin\n  CheckClosed;\n  CheckColumnIndex(ColumnIndex);\n\n  DL := FPlainDriver.dbdatlen(FHandle, ColumnIndex);\n  Data := FPlainDriver.dbdata(FHandle, ColumnIndex);\n  DT := DBLibColTypeCache[ColumnIndex];\n  LastWasNull := Data = nil;\n\n  Result := 0;\n  if Assigned(Data) then\n  begin\n    if DT = FPlainDriver.GetVariables.datatypes[Z_SQLFLT8] then\n      Result := PDouble(Data)^\n    else\n    begin\n      FPlainDriver.dbconvert(FHandle, DT, Data, DL, FPlainDriver.GetVariables.datatypes[Z_SQLFLT8],\n        @Result, SizeOf(Result));\n    end;\n  end;\n  FDBLibConnection.CheckDBLibError(lcOther, 'GETDOUBLE');\nend;\n\n{**\n  Gets the value of the designated column in the current row\n  of this <code>ResultSet</code> object as\n  a <code>java.sql.BigDecimal</code> in the Java programming language.\n\n  @param columnIndex the first column is 1, the second is 2, ...\n  @param scale the number of digits to the right of the decimal point\n  @return the column value; if the value is SQL <code>NULL</code>, the\n    value returned is <code>null</code>\n}\nfunction TZDBLibResultSet.GetBigDecimal(ColumnIndex: Integer): Extended;\nbegin\n  Result := GetDouble(ColumnIndex);\nend;\n\n{**\n  Gets the value of the designated column in the current row\n  of this <code>ResultSet</code> object as\n  a <code>byte</code> array in the Java programming language.\n  The bytes represent the raw values returned by the driver.\n\n  @param columnIndex the first column is 1, the second is 2, ...\n  @return the column value; if the value is SQL <code>NULL</code>, the\n    value returned is <code>null</code>\n}\nfunction TZDBLibResultSet.GetBytes(ColumnIndex: Integer): TByteDynArray;\nvar\n  DL: Integer;\n  Data: Pointer;\nbegin\n  CheckClosed;\n  CheckColumnIndex(ColumnIndex);\n\n  DL := FPlainDriver.dbdatlen(FHandle, ColumnIndex);\n  Data := FPlainDriver.dbdata(FHandle, ColumnIndex);\n  FDBLibConnection.CheckDBLibError(lcOther, 'GETBYTES');\n  LastWasNull := Data = nil;\n\n  SetLength(Result, DL);\n  if Assigned(Data) then\n      Move(PAnsiChar(Data)^, Result[0], DL);\nend;\n\n{**\n  Gets the value of the designated column in the current row\n  of this <code>ResultSet</code> object as\n  a <code>java.sql.Date</code> object in the Java programming language.\n\n  @param columnIndex the first column is 1, the second is 2, ...\n  @return the column value; if the value is SQL <code>NULL</code>, the\n    value returned is <code>null</code>\n}\nfunction TZDBLibResultSet.GetDate(ColumnIndex: Integer): TDateTime;\nbegin\n  Result := System.Int(GetTimestamp(ColumnIndex));\nend;\n\n{**\n  Gets the value of the designated column in the current row\n  of this <code>ResultSet</code> object as\n  a <code>java.sql.Time</code> object in the Java programming language.\n\n  @param columnIndex the first column is 1, the second is 2, ...\n  @return the column value; if the value is SQL <code>NULL</code>, the\n    value returned is <code>null</code>\n}\nfunction TZDBLibResultSet.GetTime(ColumnIndex: Integer): TDateTime;\nbegin\n  Result := Frac(GetTimestamp(ColumnIndex));\nend;\n\n{**\n  Gets the value of the designated column in the current row\n  of this <code>ResultSet</code> object as\n  a <code>java.sql.Timestamp</code> object in the Java programming language.\n\n  @param columnIndex the first column is 1, the second is 2, ...\n  @return the column value; if the value is SQL <code>NULL</code>, the\n  value returned is <code>null</code>\n  @exception SQLException if a database access error occurs\n}\nfunction TZDBLibResultSet.GetTimestamp(ColumnIndex: Integer): TDateTime;\nvar\n  DL: Integer;\n  Data: Pointer;\n  DT: Integer;\n  TempDate: DBDATETIME;\n  tdsTempDate: TTDSDBDATETIME;\nbegin\n  CheckClosed;\n  CheckColumnIndex(ColumnIndex);\n\n  DL := FPlainDriver.dbdatlen(FHandle, ColumnIndex);\n  Data := FPlainDriver.dbdata(FHandle, ColumnIndex);\n  DT := DBLibColTypeCache[ColumnIndex];\n  LastWasNull := Data = nil;\n\n  Result := 0;\n  if Assigned(Data) then\n  begin\n    if DT = FPlainDriver.GetVariables.datatypes[Z_SQLDATETIME] then\n      if FDBLibConnection.FreeTDS then //type diff\n        Result := PTDSDBDATETIME(Data)^.dtdays + 2 + (PTDSDBDATETIME(Data)^.dttime / 25920000)\n      else\n        Result := PDBDATETIME(Data)^.dtdays + 2 + (PDBDATETIME(Data)^.dttime / 25920000)\n    else\n      if FDBLibConnection.FreeTDS then //type diff\n      begin\n        FPlainDriver.dbconvert(FHandle, DT, Data, DL, FPlainDriver.GetVariables.datatypes[Z_SQLDATETIME],\n          @tdsTempDate, SizeOf(tdsTempDate));\n        Result := tdsTempDate.dtdays + 2 + (tdsTempDate.dttime / 25920000);\n      end\n      else\n      begin\n        FPlainDriver.dbconvert(FHandle, DT, Data, DL, FPlainDriver.GetVariables.datatypes[Z_SQLDATETIME],\n          @TempDate, SizeOf(TempDate));\n        Result := TempDate.dtdays + 2 + (TempDate.dttime / 25920000);\n      end;\n  end;\n  FDBLibConnection.CheckDBLibError(lcOther, 'GETTIMESTAMP');\nend;\n\n{**\n  Returns the value of the designated column in the current row\n  of this <code>ResultSet</code> object as a <code>Blob</code> object\n  in the Java programming language.\n\n  @param ColumnIndex the first column is 1, the second is 2, ...\n  @return a <code>Blob</code> object representing the SQL <code>BLOB</code> value in\n    the specified column\n}\nfunction TZDBLibResultSet.GetBlob(ColumnIndex: Integer): IZBlob;\nvar\n  DL: Integer;\n  Data: Pointer;\n  TempStream: TStream;\n  TempAnsi: RawByteString;\nbegin\n  CheckClosed;\n  CheckColumnIndex(ColumnIndex);\n  CheckBlobColumn(ColumnIndex);\n\n  DL := FPlainDriver.dbdatlen(FHandle, ColumnIndex);\n  Data := FPlainDriver.dbdata(FHandle, ColumnIndex);\n  LastWasNull := Data = nil;\n  Result := TZAbstractBlob.CreateWithData(Data, DL, FDBLibConnection);\n  if (GetMetaData.GetColumnType(ColumnIndex) in [stAsciiStream, stUnicodeStream]) then\n  begin\n    TempAnsi := Result.GetString;\n    if ( Length(TempAnsi) = 1) and (TempAnsi[1] = ' ') then\n      TempAnsi := ''\n    else\n      TempAnsi := {$IFDEF WITH_UNITANSISTRINGS}AnsiStrings.{$ENDIF}StringReplace(TempAnsi, #0, '', [rfReplaceAll]);\n    if (GetMetaData.GetColumnType(ColumnIndex) = stAsciiStream ) then\n      Result.SetString(ZEncoding.GetValidatedAnsiString(TempAnsi, ConSettings, True))\n    else\n    begin\n      if TempAnsi = '' then\n        TempStream := TMemoryStream.Create\n      else\n        TempStream := ZEncoding.GetValidatedUnicodeStream(TempAnsi, ConSettings, True);\n      Result.SetStream(TempStream, True);\n      TempStream.Free;\n    end;\n  end;\nend;\n\n{**\n  Moves the cursor to the given row number in\n  this <code>ResultSet</code> object.\n\n  <p>If the row number is positive, the cursor moves to\n  the given row number with respect to the\n  beginning of the result set.  The first row is row 1, the second\n  is row 2, and so on.\n\n  <p>If the given row number is negative, the cursor moves to\n  an absolute row position with respect to\n  the end of the result set.  For example, calling the method\n  <code>absolute(-1)</code> positions the\n  cursor on the last row; calling the method <code>absolute(-2)</code>\n  moves the cursor to the next-to-last row, and so on.\n\n  <p>An attempt to position the cursor beyond the first/last row in\n  the result set leaves the cursor before the first row or after\n  the last row.\n\n  <p><B>Note:</B> Calling <code>absolute(1)</code> is the same\n  as calling <code>first()</code>. Calling <code>absolute(-1)</code>\n  is the same as calling <code>last()</code>.\n\n  @return <code>true</code> if the cursor is on the result set;\n    <code>false</code> otherwise\n}\nfunction TZDBLibResultSet.MoveAbsolute(Row: Integer): Boolean;\nbegin\n  Result := False;\n  RaiseUnsupportedException;\nend;\n\n{**\n  Moves the cursor down one row from its current position.\n  A <code>ResultSet</code> cursor is initially positioned\n  before the first row; the first call to the method\n  <code>next</code> makes the first row the current row; the\n  second call makes the second row the current row, and so on.\n\n  <P>If an input stream is open for the current row, a call\n  to the method <code>next</code> will\n  implicitly close it. A <code>ResultSet</code> object's\n  warning chain is cleared when a new row is read.\n\n  @return <code>true</code> if the new current row is valid;\n    <code>false</code> if there are no more rows\n}\nfunction TZDBLibResultSet.Next: Boolean;\nbegin\n  Result := False;\n  if FPlainDriver.GetProtocol = 'mssql' then\n    if FPlainDriver.dbDead(FHandle) then\n      Exit;\n//!!! maybe an error message other than dbconnection is dead should be raised\n  case FPlainDriver.dbnextrow(FHandle) of\n    REG_ROW: Result := True;\n    NO_MORE_ROWS: ;\n    DBFAIL: FDBLibConnection.CheckDBLibError(lcOther, 'NEXT');\n    BUF_FULL: ;//should not happen because we are not using dblibc buffering.\n  else\n   // If a compute row is read, the computeid of the row is returned\n    Result := False;\n  end;\nend;\n\n\n{ TZDBLibCachedResolver }\n\n{**\n  Creates a DBLib specific cached resolver object.\n  @param PlainDriver a native DBLib plain driver.\n  @param Handle a DBLib specific query handle.\n  @param Statement a related SQL statement object.\n  @param Metadata a resultset metadata reference.\n}\nconstructor TZDBLibCachedResolver.Create(Statement: IZStatement;\n  Metadata: IZResultSetMetadata);\nbegin\n  inherited Create(Statement, Metadata);\n\n  { Defines an index of autoincrement field. }\n  FAutoColumnIndex := -1;\nend;\n\n{**\n  Posts updates to database.\n  @param Sender a cached result set object.\n  @param UpdateType a type of updates.\n  @param OldRowAccessor an accessor object to old column values.\n  @param NewRowAccessor an accessor object to new column values.\n}\nprocedure TZDBLibCachedResolver.PostUpdates(Sender: IZCachedResultSet;\n  UpdateType: TZRowUpdateType; OldRowAccessor, NewRowAccessor: TZRowAccessor);\nvar\n  Statement: IZStatement;\n  ResultSet: IZResultSet;\n  I: Integer;\nbegin\n  inherited PostUpdates(Sender, UpdateType, OldRowAccessor, NewRowAccessor);\n\n  { Defines an index of autoincrement field. }\n  if FAutoColumnIndex = -1 then\n  begin\n    FAutoColumnIndex := 0;\n    for I := 1 to Metadata.GetColumnCount do\n    begin\n      if Metadata.IsAutoIncrement(I) then\n      begin\n        FAutoColumnIndex := I;\n        Break;\n      end;\n    end;\n  end;\n\n  if (UpdateType = utInserted) and (FAutoColumnIndex > 0)\n    and OldRowAccessor.IsNull(FAutoColumnIndex) then\n  begin\n    Statement := Connection.CreateStatement;\n    ResultSet := Statement.ExecuteQuery('SELECT @@IDENTITY');\n    try\n      if ResultSet.Next then\n        NewRowAccessor.SetLong(FAutoColumnIndex, ResultSet.GetLong(1));\n    finally\n      ResultSet.Close;\n      Statement.Close;\n    end;\n  end;\nend;\n\nend.\n\n"
  },
  {
    "path": "lib/zeosdbo/src/dbc/ZDbcDbLibStatement.pas",
    "content": "{*********************************************************}\n{                                                         }\n{                 Zeos Database Objects                   }\n{          DBLib Statement common functionality           }\n{                                                         }\n{        Originally written by Janos Fegyverneki          }\n{                                                         }\n{*********************************************************}\n\n{@********************************************************}\n{    Copyright (c) 1999-2012 Zeos Development Group       }\n{                                                         }\n{ License Agreement:                                      }\n{                                                         }\n{ This library is distributed in the hope that it will be }\n{ useful, but WITHOUT ANY WARRANTY; without even the      }\n{ implied warranty of MERCHANTABILITY or FITNESS FOR      }\n{ A PARTICULAR PURPOSE.  See the GNU Lesser General       }\n{ Public License for more details.                        }\n{                                                         }\n{ The source code of the ZEOS Libraries and packages are  }\n{ distributed under the Library GNU General Public        }\n{ License (see the file COPYING / COPYING.ZEOS)           }\n{ with the following  modification:                       }\n{ As a special exception, the copyright holders of this   }\n{ library give you permission to link this library with   }\n{ independent modules to produce an executable,           }\n{ regardless of the license terms of these independent    }\n{ modules, and to copy and distribute the resulting       }\n{ executable under terms of your choice, provided that    }\n{ you also meet, for each linked independent module,      }\n{ the terms and conditions of the license of that module. }\n{ An independent module is a module which is not derived  }\n{ from or based on this library. If you modify this       }\n{ library, you may extend this exception to your version  }\n{ of the library, but you are not obligated to do so.     }\n{ If you do not wish to do so, delete this exception      }\n{ statement from your version.                            }\n{                                                         }\n{                                                         }\n{ The project web site is located on:                     }\n{   http://zeos.firmos.at  (FORUM)                        }\n{   http://sourceforge.net/p/zeoslib/tickets/ (BUGTRACKER)}\n{   svn://svn.code.sf.net/p/zeoslib/code-0/trunk (SVN)    }\n{                                                         }\n{   http://www.sourceforge.net/projects/zeoslib.          }\n{                                                         }\n{                                                         }\n{                                 Zeos Development Group. }\n{********************************************************@}\n\nunit ZDbcDbLibStatement;\n\ninterface\n\n{$I ZDbc.inc}\n\nuses Classes, {$IFDEF MSEgui}mclasses,{$ENDIF} SysUtils,\n  ZCompatibility, ZClasses, ZSysUtils, ZCollections, ZDbcIntfs, ZDbcStatement,\n  ZDbcDbLib, ZPlainDbLibConstants, ZPlainDbLibDriver;\n\ntype\n  {** Implements Generic DBLib Statement. }\n  TZDBLibStatement = class(TZAbstractStatement)\n  protected\n    FDBLibConnection: IZDBLibConnection;\n    FPlainDriver: IZDBLibPlainDriver;\n    FHandle: PDBPROCESS;\n    FResults: IZCollection;\n    FRetrievedResultSet: IZResultSet;\n    FRetrievedUpdateCount: Integer;\n\n    procedure InternalExecuteStatement(SQL: RawByteString);\n    procedure FetchResults; virtual;\n\n  public\n    constructor Create(Connection: IZConnection; Info: TStrings);\n    procedure Close; override;\n\n    function GetMoreResults: Boolean; override;\n\n    function ExecuteQuery(const SQL: RawByteString): IZResultSet; override;\n    function ExecuteUpdate(const SQL: RawByteString): Integer; override;\n    function Execute(const SQL: RawByteString): Boolean; override;\n  end;\n\n  {** Implements Prepared SQL Statement. With emulation}\n  TZDBLibPreparedStatementEmulated = class(TZEmulatedPreparedStatement)\n  private\n    FPlainDriver: IZDBLibPlainDriver;\n  protected\n    function GetEscapeString(Value: string): string;\n    function PrepareAnsiSQLQuery: RawByteString; override;\n    function PrepareAnsiSQLParam(ParamIndex: Integer;\n      const NChar: Boolean): RawByteString; reintroduce;\n    function CreateExecStatement: IZStatement; override;\n  public\n    constructor Create(Connection: IZConnection; SQL: string; Info: TStrings);\n    function GetMetaData: IZResultSetMetaData; override;\n\n    function ExecuteQueryPrepared: IZResultSet; override;\n    function ExecuteUpdatePrepared: Integer; override;\n    function ExecutePrepared: Boolean; override;\n  end;\n\n  TZDBLibCallableStatement = class(TZAbstractCallableStatement)\n  private\n    FSQL: string;\n    FDBLibConnection: IZDBLibConnection;\n    FPlainDriver: IZDBLibPlainDriver;\n    FHandle: PDBPROCESS;\n    FLastRowsAffected: Integer;//Workaround for sybase\n    FRetrievedResultSet: IZResultSet;\n    FRetrievedUpdateCount: Integer;\n\n    procedure FetchResults; virtual;\n    procedure FetchRowCount; virtual;\n\n  protected\n    procedure SetInParamCount(NewParamCount: Integer); override;\n\n  public\n    constructor Create(Connection: IZConnection; ProcName: string; Info: TStrings);\n    procedure Close; override;\n\n    procedure RegisterOutParameter(ParameterIndex: Integer;\n      SqlType: Integer); override;\n    function GetMoreResults: Boolean; override;\n    function ExecuteQueryPrepared: IZResultSet; override;\n    function ExecuteUpdatePrepared: Integer; override;\n    function ExecutePrepared: Boolean; override;\n\n  end;\n\ntype\n  {** Interface for storing counter. }\n  IZUpdateCount = interface(IZInterface)\n    ['{03219BB4-E07F-4A50-80CD-291FEA629697}']\n    procedure SetCount(Value: Integer);\n    function GetCount: Integer;\n  end;\n\n  TZUpdateCount = class(TInterfacedObject, IZUpdateCount)\n  private\n    FCount: Integer;\n  public\n    constructor Create(ACount: Integer);\n    procedure SetCount(Value: Integer); virtual;\n    function GetCount: Integer; virtual;\n    property Count: Integer read GetCount write SetCount;\n  end;\n\nimplementation\n\nuses\n  Types, ZDbcLogging, ZDbcCachedResultSet, ZDbcDbLibUtils, ZDbcDbLibResultSet,\n  ZVariant{$IFDEF WITH_UNITANSISTRINGS}, AnsiStrings{$ENDIF};\n\nconstructor TZUpdateCount.Create(ACount: Integer);\nbegin\n  inherited Create;\n  FCount := ACount;\nend;\n\nprocedure TZUpdateCount.SetCount(Value: Integer);\nbegin\n  FCount := Value;\nend;\n\nfunction TZUpdateCount.GetCount: Integer;\nbegin\n  Result := FCount;\nend;\n\n{ TZDBLibStatement }\n\n{**\n  Constructs this object and assignes the main properties.\n  @param Connection a database connection object.\n  @param Info a statement parameters.\n}\nconstructor TZDBLibStatement.Create(Connection: IZConnection; Info: TStrings);\nbegin\n  inherited Create(Connection, Info);\n  Connection.QueryInterface(IZDBLibConnection, FDBLibConnection);\n  if Assigned(FDBLibConnection) then\n    FPLainDriver := FDBLibConnection.GetPlainDriver;\n  FHandle := FDBLibConnection.GetConnectionHandle;\n  ResultSetType := rtScrollInsensitive;\n  FResults := TZCollection.Create;\nend;\n\nprocedure TZDBLibStatement.Close;\nvar\n  I: Integer;\n  RS: IZResultSet;\nbegin\n  for i := 0 to FResults.Count -1 do\n    if supports(FResults[i], IZResultSet, RS) then    //possible IZUpdateCount\n      RS.Close;\n  FResults.Clear;\n  FRetrievedResultSet := nil;\n  inherited Close;\nend;\n\n{**\n  Executes a Statement.\n  Used internally to execute statements.\n\n  @param Handle a DBLib connection handle.\n  @sql string containing the statements to execute\n}\nprocedure TZDBLibStatement.InternalExecuteStatement(SQL: RawByteString);\nvar Ansi: RawByteString;\nbegin\n  if FDBLibConnection.GetProvider = dpMsSQL then\n    //This one is to avoid a bug in dblib interface as it drops a single backslash before line end\n    Ansi := {$IFDEF WITH_UNITANSISTRINGS}AnsiStrings.{$ENDIF}StringReplace(SQL, '\\'#13, '\\\\'#13, [rfReplaceAll])\n  else\n    //This one is to avoid sybase error: Invalid operator for datatype op: is null type: VOID TYPE\n    Ansi := {$IFDEF WITH_UNITANSISTRINGS}AnsiStrings.{$ENDIF}StringReplace(SQL, ' AND NULL IS NULL', '', [rfReplaceAll]);\n\n  FHandle := FDBLibConnection.GetConnectionHandle;\n  FPlainDriver := FDBLibConnection.GetPlainDriver;\n  if FPlainDriver.dbcancel(FHandle) <> DBSUCCEED then\n    FDBLibConnection.CheckDBLibError(lcExecute, LogSQL);\n\n  if FPlainDriver.dbcmd(FHandle, PAnsiChar(Ansi)) <> DBSUCCEED then\n    FDBLibConnection.CheckDBLibError(lcExecute, LogSQL);\n\n  if FPlainDriver.dbsqlexec(FHandle) <> DBSUCCEED then\n    FDBLibConnection.CheckDBLibError(lcExecute, LogSQL);\n  DriverManager.LogMessage(lcExecute, FPlainDriver.GetProtocol, LogSQL);\nend;\n\n{**\n  Moves to a <code>Statement</code> object's next result.  It returns\n  <code>true</code> if this result is a <code>ResultSet</code> object.\n  This method also implicitly closes any current <code>ResultSet</code>\n  object obtained with the method <code>getResultSet</code>.\n\n  <P>There are no more results when the following is true:\n  <PRE>\n        <code>(!getMoreResults() && (getUpdateCount() == -1)</code>\n  </PRE>\n\n @return <code>true</code> if the next result is a <code>ResultSet</code> object;\n   <code>false</code> if it is an update count or there are no more results\n @see #execute\n}\nfunction TZDBLibStatement.GetMoreResults: Boolean;\nvar\n  ResultSet: IZResultSet;\n  UpdateCount: IZUpdateCount;\nbegin\n  Result := False;\n  FRetrievedResultSet := nil;\n  FRetrievedUpdateCount := -1;\n  if FResults.Count > 0 then\n  begin\n    try\n      Result := FResults.Items[0].QueryInterface(IZResultSet, ResultSet) = 0;\n      if Result then\n      begin\n        FRetrievedResultSet := ResultSet;\n        FRetrievedUpdateCount := 0;\n      end\n      else\n      begin\n        if FResults.Items[0].QueryInterface(IZUpdateCount, UpdateCount) = 0 then\n          FRetrievedUpdateCount := UpdateCount.GetCount;\n      end;\n      FResults.Delete(0);\n    finally\n      ResultSet := nil;\n      UpdateCount := nil;\n    end;\n  end;\nend;\n\n{**\n  Fetches all results and creates a cachedresultset object for each resultset\n  and a ZUpdateCount object for each count value.\n}\nprocedure TZDBLibStatement.FetchResults;\nvar\n  NativeResultSet: TZDBLibResultSet;\n  CachedResultSet: TZCachedResultSet;\n  RS: IZResultSet;\n  RowsAffected: Integer;\nbegin\n  for RowsAffected := 0 to FResults.Count -1 do\n    if Supports(FResults[RowsAffected], IZResultSet, RS) then\n      RS.Close;\n  FResults.Clear;\n//Sybase does not seem to return dbCount at all, so a workaround is made\n  RowsAffected := -2;\n  while FPlainDriver.dbresults(FHandle) = DBSUCCEED do\n  begin\n    if FPlainDriver.dbcmdrow(FHandle) = DBSUCCEED then\n    begin\n      NativeResultSet := TZDBLibResultSet.Create(Self, LogSQL);\n      NativeResultSet.SetConcurrency(rcReadOnly);\n      CachedResultSet := TZCachedResultSet.Create(NativeResultSet,\n        LogSQL, TZDBLibCachedResolver.Create(Self, NativeResultSet.GetMetaData), ConSettings);\n      CachedResultSet.SetType(rtScrollInsensitive);//!!!Cached resultsets are allways this\n      CachedResultSet.Last;\n      CachedResultSet.BeforeFirst; //!!!Just to invoke fetchall\n      CachedResultSet.SetConcurrency(GetResultSetConcurrency);\n      FResults.Add(CachedResultSet);\n    end\n    else\n    begin\n      RowsAffected := FPlainDriver.dbCount(FHandle);\n      if RowsAffected > -1 then\n        FResults.Add(TZUpdateCount.Create(RowsAffected));\n    end;\n    FPlainDriver.dbCanQuery(FHandle);\n  end;\n  FDBLibConnection.CheckDBLibError(lcOther, 'FETCHRESULTS');\n\n  if not FDBLibConnection.FreeTDS then\n    if RowsAffected = -1 then\n    begin\n      FDBLibConnection.InternalExecuteStatement('select @@rowcount');\n      try\n        FPlainDriver.dbresults(FHandle);\n        NativeResultSet := TZDBLibResultSet.Create(Self, 'select @@rowcount');\n        try\n          if NativeResultset.Next then\n            RowsAffected := NativeResultSet.GetInt(1);\n        finally\n          NativeResultSet.Close;\n        end;\n        FResults.Add(TZUpdateCount.Create(RowsAffected));\n      finally\n        FPlainDriver.dbCancel(FHandle);\n      end;\n      FDBLibConnection.CheckDBLibError(lcOther, 'FETCHRESULTS');\n    end;\nend;\n\n{**\n  Executes an SQL statement that returns a single <code>ResultSet</code> object.\n  @param sql typically this is a static SQL <code>SELECT</code> statement\n  @return a <code>ResultSet</code> object that contains the data produced by the\n    given query; never <code>null</code>\n}\nfunction TZDBLibStatement.ExecuteQuery(const SQL: RawByteString): IZResultSet;\nbegin\n  Result := nil;\n  if ASQL <> SQL then\n    ASQL := SQL;\n  try\n    InternalExecuteStatement(ASQL);\n    FetchResults;\n    repeat\n      if GetMoreResults then\n        Result := FRetrievedResultSet\n      else if FRetrievedUpdateCount = -1 then\n        Break;\n    until False;\n  finally\n    FRetrievedResultSet := nil;\n  end;\nend;\n\n{**\n  Executes an SQL <code>INSERT</code>, <code>UPDATE</code> or\n  <code>DELETE</code> statement. In addition,\n  SQL statements that return nothing, such as SQL DDL statements,\n  can be executed.\n\n  @param sql an SQL <code>INSERT</code>, <code>UPDATE</code> or\n    <code>DELETE</code> statement or an SQL statement that returns nothing\n  @return either the row count for <code>INSERT</code>, <code>UPDATE</code>\n    or <code>DELETE</code> statements, or 0 for SQL statements that return nothing\n}\nfunction TZDBLibStatement.ExecuteUpdate(const SQL: RawByteString): Integer;\nbegin\n  if ASQL <> SQL then\n    ASQL := SQL;\n  InternalExecuteStatement(ASQL);\n  FetchResults;\n  GetMoreResults;\n  Result := FRetrievedUpdateCount;\n  FRetrievedResultSet := nil;\nend;\n\n{**\n  Executes an SQL statement that may return multiple results.\n  Under some (uncommon) situations a single SQL statement may return\n  multiple result sets and/or update counts.  Normally you can ignore\n  this unless you are (1) executing a stored procedure that you know may\n  return multiple results or (2) you are dynamically executing an\n  unknown SQL string.  The  methods <code>execute</code>,\n  <code>getMoreResults</code>, <code>getResultSet</code>,\n  and <code>getUpdateCount</code> let you navigate through multiple results.\n\n  The <code>execute</code> method executes an SQL statement and indicates the\n  form of the first result.  You can then use the methods\n  <code>getResultSet</code> or <code>getUpdateCount</code>\n  to retrieve the result, and <code>getMoreResults</code> to\n  move to any subsequent result(s).\n\n  @param sql any SQL statement\n  @return <code>true</code> if the next result is a <code>ResultSet</code> object;\n  <code>false</code> if it is an update count or there are no more results\n}\nfunction TZDBLibStatement.Execute(const SQL: RawByteString): Boolean;\nbegin\n  if ASQL <> SQL then\n    ASQL := SQL;\n  InternalExecuteStatement(ASQL);\n  FetchResults;\n  Result := GetMoreResults;\n  LastResultSet := FRetrievedResultSet;\n  LastUpdateCount := FRetrievedUpdateCount;\n  FRetrievedResultSet := nil;\nend;\n\n{ TZDBLibPreparedStatementEmulated }\n\n{**\n  Constructs this object and assignes the main properties.\n  @param Connection a database connection object.\n  @param Info a statement parameters.\n  @param Handle a connection handle pointer.\n}\nconstructor TZDBLibPreparedStatementEmulated.Create(Connection: IZConnection;\n  SQL: string; Info: TStrings);\nbegin\n  inherited Create(Connection, SQL, Info);\n  FPlainDriver := (Connection as IZDBLibConnection).GetPlainDriver;\n  ResultSetType := rtScrollInsensitive;\n  FNeedNCharDetection := True;\nend;\n\n{**\n  Converts an string into escape DBLib format.\n  @param Value a regular string.\n  @return a string in DBLib escape format.\n}\nfunction TZDBLibPreparedStatementEmulated.GetEscapeString(Value: string): string;\nbegin\n  Result := AnsiQuotedStr(Value, '''');\nend;\n\nfunction TZDBLibPreparedStatementEmulated.PrepareAnsiSQLQuery: RawByteString;\nvar\n  I: Integer;\n  ParamIndex: Integer;\n  Tokens: TStrings;\nbegin\n  ParamIndex := 0;\n  Result := '';\n  Tokens := TokenizeSQLQuery;\n\n  for I := 0 to Tokens.Count - 1 do\n  begin\n    if Tokens[I] = '?' then\n    begin\n      Result := Result + PrepareAnsiSQLParam(ParamIndex, ((i > 0) and (Tokens[i-1] = 'N')));\n      Inc(ParamIndex);\n    end\n    else\n      Result := Result + ZPlainString(Tokens[I]);\n  end;\n  {$IFNDEF UNICODE}\n  if GetConnection.AutoEncodeStrings then\n     Result := GetConnection.GetDriver.GetTokenizer.GetEscapeString(Result);\n  {$ENDIF}\nend;\n{**\n  Prepares an SQL parameter for the query.\n  @param ParameterIndex the first parameter is 1, the second is 2, ...\n  @return a string representation of the parameter.\n}\nfunction TZDBLibPreparedStatementEmulated.PrepareAnsiSQLParam(ParamIndex: Integer;\n  const NChar: Boolean): RawByteString;\nbegin\n  if InParamCount <= ParamIndex then\n    Result := 'NULL'\n  else\n  begin\n    Result := PrepareSQLParameter(InParamValues[ParamIndex],\n      InParamTypes[ParamIndex], ConSettings, FPlainDriver, NChar);\n  end;\nend;\n\n{**\n  Gets the number, types and properties of a <code>ResultSet</code>\n  object's columns.\n  @return the description of a <code>ResultSet</code> object's columns\n}\nfunction TZDBLibPreparedStatementEmulated.GetMetaData: IZResultSetMetaData;\nbegin\n  Result := nil;\nend;\n\n{**\n  Executes the SQL query in this <code>PreparedStatement</code> object\n  and returns the result set generated by the query.\n\n  @return a <code>ResultSet</code> object that contains the data produced by the\n    query; never <code>null</code>\n}\nfunction TZDBLibPreparedStatementEmulated.ExecutePrepared: Boolean;\nbegin\n  Result := inherited Execute(PrepareAnsiSQLQuery);\nend;\n\n{**\n  Executes the SQL query in this <code>PreparedStatement</code> object\n  and returns the result set generated by the query.\n\n  @return a <code>ResultSet</code> object that contains the data produced by the\n    query; never <code>null</code>\n}\nfunction TZDBLibPreparedStatementEmulated.ExecuteQueryPrepared: IZResultSet;\nbegin\n  Result := inherited ExecuteQuery(PrepareAnsiSQLQuery);\nend;\n\n{**\n  Executes the SQL INSERT, UPDATE or DELETE statement\n  in this <code>PreparedStatement</code> object.\n  In addition,\n  SQL statements that return nothing, such as SQL DDL statements,\n  can be executed.\n\n  @return either the row count for INSERT, UPDATE or DELETE statements;\n  or 0 for SQL statements that return nothing\n}\nfunction TZDBLibPreparedStatementEmulated.ExecuteUpdatePrepared: Integer;\nbegin\n  Result := inherited ExecuteUpdate(PrepareAnsiSQLQuery);\nend;\n\n{**\n  Creates a temporary statement which executes queries.\n  @param Info a statement parameters.\n  @return a created statement object.\n}\nfunction TZDBLibPreparedStatementEmulated.CreateExecStatement: IZStatement;\nbegin\n  Result := TZDBLibStatement.Create(Connection, Info);\nend;\n\nconstructor TZDBLibCallableStatement.Create(Connection: IZConnection;\n  ProcName: string; Info: TStrings);\nbegin\n  inherited Create(Connection, ProcName, Info);\n  Connection.QueryInterface(IZDBLibConnection, FDBLibConnection);\n  if Assigned(FDBLibConnection) then\n    FPLainDriver := FDBLibConnection.GetPlainDriver;\n  FHandle := FDBLibConnection.GetConnectionHandle;\n  ResultSetType := rtScrollInsensitive;\nend;\n\nprocedure TZDBLibCallableStatement.Close;\nbegin\n  FRetrievedResultSet := nil;\n  inherited Close;\nend;\n\nprocedure TZDBLibCallableStatement.FetchResults;\nvar\n  NativeResultSet: TZDBLibResultSet;\n  CachedResultSet: TZCachedResultSet;\nbegin\n//Sybase does not seem to return dbCount at all, so a workaround is made\n  FLastRowsAffected := -2;\n  while FPlainDriver.dbresults(FHandle) = DBSUCCEED do\n  begin\n    if FPlainDriver.dbcmdrow(FHandle) = DBSUCCEED then\n    begin\n      NativeResultSet := TZDBLibResultSet.Create(Self, FSQL);\n      NativeResultSet.SetConcurrency(rcReadOnly);\n      CachedResultSet := TZCachedResultSet.Create(NativeResultSet, FSQL,\n        TZDBLibCachedResolver.Create(Self, NativeResultSet.GetMetaData), ConSettings);\n      CachedResultSet.SetType(rtScrollInsensitive);//!!!Cached resultsets are allways this\n      CachedResultSet.Last;\n      CachedResultSet.BeforeFirst; //!!!Just to invoke fetchall\n      CachedResultSet.SetConcurrency(GetResultSetConcurrency);\n      FResultSets.Add(CachedResultSet);\n    end\n    else\n    begin\n      FLastRowsAffected := FPlainDriver.dbCount(FHandle);\n      if FLastRowsAffected > -1 then\n        FResultSets.Add(TZUpdateCount.Create(FLastRowsAffected));\n    end;\n  end;\n  FDBLibConnection.CheckDBLibError(lcOther, 'FETCHRESULTS');\nend;\n\nprocedure TZDBLibCallableStatement.FetchRowCount;\nvar\n  NativeResultSet: TZDBLibResultSet;\nbegin\n//Sybase does not seem to return dbCount at all, so a workaround is made\n  if FLastRowsAffected = -1 then\n  begin\n    FDBLibConnection.InternalExecuteStatement('select @@rowcount');\n    try\n      FPlainDriver.dbresults(FHandle);\n      NativeResultSet := TZDBLibResultSet.Create(Self, 'select @@rowcount');\n      try\n        if NativeResultset.Next then\n          FLastRowsAffected := NativeResultSet.GetInt(1);\n      finally\n        NativeResultset.Close;\n      end;\n      FResultSets.Add(TZUpdateCount.Create(FLastRowsAffected));\n    finally\n      FPlainDriver.dbCancel(FHandle);\n    end;\n    FDBLibConnection.CheckDBLibError(lcOther, 'FETCHRESULTS');\n  end;\nend;\n\n{**\n  Moves to a <code>Statement</code> object's next result.  It returns\n  <code>true</code> if this result is a <code>ResultSet</code> object.\n  This method also implicitly closes any current <code>ResultSet</code>\n  object obtained with the method <code>getResultSet</code>.\n\n  <P>There are no more results when the following is true:\n  <PRE>\n        <code>(!getMoreResults() && (getUpdateCount() == -1)</code>\n  </PRE>\n\n @return <code>true</code> if the next result is a <code>ResultSet</code> object;\n   <code>false</code> if it is an update count or there are no more results\n @see #execute\n}\nfunction TZDBLibCallableStatement.GetMoreResults: Boolean;\nvar\n  ResultSet: IZResultSet;\n  UpdateCount: IZUpdateCount;\nbegin\n  Result := False;\n  FRetrievedResultSet := nil;\n  FRetrievedUpdateCount := -1;\n  if FResultSets.Count > 0 then\n  begin\n    try\n      Result := Supports(FResultSets[0], IZResultSet, ResultSet);\n      if Result then\n      begin\n        FRetrievedResultSet := ResultSet;\n        FRetrievedUpdateCount := 0;\n      end\n      else\n        if Supports(FResultSets[0], IZUpdateCount, UpdateCount) then\n          FRetrievedUpdateCount := UpdateCount.GetCount;\n      FResultSets.Delete(0);\n    finally\n      ResultSet := nil;\n      UpdateCount := nil;\n    end;\n  end;\nend;\n\nfunction TZDBLibCallableStatement.ExecuteQueryPrepared: IZResultSet;\nbegin\n  if not ExecutePrepared then\n    while not GetMoreResults and (FRetrievedUpdateCount <> -1) do;\n  Result := FRetrievedResultSet;\n  FRetrievedResultSet := nil;\nend;\n\nfunction TZDBLibCallableStatement.ExecuteUpdatePrepared: Integer;\nbegin\n  if ExecutePrepared then\n    while GetMoreResults and (FRetrievedUpdateCount = -1) do;\n  Result := FRetrievedUpdateCount;\n  FRetrievedResultSet := nil;\nend;\n\nprocedure TZDBLibCallableStatement.RegisterOutParameter(ParameterIndex: Integer;\n  SqlType: Integer);\nbegin\n  SetOutParamCount(ParameterIndex);\n  OutParamTypes[ParameterIndex - 1] := TZSqlType(SqlType);\n\n  //Count inparams must equal count outparams to correct set paramters\n  if InParamCount < ParameterIndex then\n    SetInParamCount(ParameterIndex);\nend;\n\nfunction TZDBLibCallableStatement.ExecutePrepared: Boolean;\nvar\n  S: RawByteString;\n  I, ParamIndex, DatLen: Integer;\n  RetParam: Byte;\n  DatBoolean: Boolean;\n  DatByte: Byte;\n  DatShort: SmallInt;\n  DatInteger: Integer;\n  DatFloat: Single;\n  DatDouble: Double;\n  DatString: RawByteString;\n  DatMoney: Currency;\n  DatDBDATETIME: DBDATETIME;\n  DatBytes: TByteDynArray;\n  Temp: TZVariant;\n  ParamType: TZSQLType;\n  TempBlob: IZBlob;\nbegin\n  S := {$IFDEF WITH_UNITANSISTRINGS}AnsiStrings.{$ENDIF}Trim(ASql);\n  if FPLainDriver.dbRPCInit(FHandle, Pointer(S), 0) <> DBSUCCEED then\n    FDBLibConnection.CheckDBLibError(lcOther, 'EXECUTEPREPARED:dbRPCInit');\n\n  for I := 1 to InParamCount - 1 do//The 0 parameter is the return value\n  begin\n    RetParam := 0;\n    if OutParamTypes[I] <> stUnknown then\n      RetParam := DBRPCRETURN;\n\n    ParamType := InParamTypes[I];\n    if ParamType = stUnknown then\n      ParamType := OutParamTypes[I];\n\n    if DefVarManager.IsNull(InParamValues[I]) and (InParamTypes[I] <> stUnknown) then\n    begin\n      if FDBLibConnection.FreeTDS then\n        FPlainDriver.dbRpcParam(FHandle, nil, RetParam,\n        ConvertSqlTypeToFreeTDSType(InParamTypes[I]), -1, 0, nil)\n      else\n        FPlainDriver.dbRpcParam(FHandle, nil, RetParam,\n        ConvertSqlTypeToDBLibType(InParamTypes[I]), -1, 0, nil)\n    end\n    else\n    begin\n      case ParamType of\n        stBoolean:\n          begin\n            DatBoolean := SoftVarManager.GetAsBoolean(InParamValues[I]);\n            FPlainDriver.dbRpcParam(FHandle, nil, RetParam,\n              FPlainDriver.GetVariables.datatypes[Z_SQLINT1], -1, -1, @DatBoolean);\n          end;\n        stByte:\n          begin\n            DatByte := Byte(SoftVarManager.GetAsInteger(InParamValues[I]));\n            FPlainDriver.dbRpcParam(FHandle, nil, RetParam,\n              FPlainDriver.GetVariables.datatypes[Z_SQLINT1], -1, -1, @DatByte);\n          end;\n        stShort:\n          begin\n            DatShort := SmallInt(SoftVarManager.GetAsInteger(InParamValues[I]));\n            FPlainDriver.dbRpcParam(FHandle, nil, RetParam,\n              FPlainDriver.GetVariables.datatypes[Z_SQLINT2], -1, -1, @DatShort);\n          end;\n        stInteger, stLong:\n          begin\n            DatInteger := Integer(SoftVarManager.GetAsInteger(InParamValues[I]));\n            FPlainDriver.dbRpcParam(FHandle, nil, RetParam,\n              FPlainDriver.GetVariables.datatypes[Z_SQLINT4], -1, -1, @DatInteger);\n          end;\n        stFloat:\n          begin\n            DatFloat := SoftVarManager.GetAsFloat(InParamValues[I]);\n            FPlainDriver.dbRpcParam(FHandle, nil, RetParam,\n              FPlainDriver.GetVariables.datatypes[Z_SQLFLT4], -1, -1, @DatFloat);\n          end;\n        stDouble, stBigDecimal:\n          begin\n            DatDouble := SoftVarManager.GetAsFloat(InParamValues[I]);\n            FPlainDriver.dbRpcParam(FHandle, nil, RetParam,\n              FPlainDriver.GetVariables.datatypes[Z_SQLFLT8], -1, -1, @DatDouble);\n          end;\n        stString:\n          begin\n            DatString := ZPlainString(SoftVarManager.GetAsString(InParamValues[I]));\n            if DatString = ''then\n              DatLen := 1\n            else\n              DatLen := Length(DatString);\n            FPlainDriver.dbRpcParam(FHandle, nil, RetParam,\n              FPlainDriver.GetVariables.datatypes[Z_SQLCHAR], MaxInt, DatLen, PAnsiChar(DatString));\n          end;\n        stUnicodeString:\n          begin\n            DatString := UTF8Encode(SoftVarManager.GetAsUnicodeString(InParamValues[I]));\n            if DatString = '' then\n              DatLen := 1\n            else\n              DatLen := Length(DatString);\n            FPlainDriver.dbRpcParam(FHandle, nil, RetParam,\n              FPlainDriver.GetVariables.datatypes[Z_SQLCHAR], MaxInt, DatLen, PAnsiChar(DatString));\n          end;\n        stDate:\n          begin\n            DatString := AnsiString(FormatDateTime('yyyymmdd',\n              SoftVarManager.GetAsDateTime(InParamValues[I])));\n            FPlainDriver.dbRpcParam(FHandle, nil, RetParam,\n              FPlainDriver.GetVariables.datatypes[Z_SQLCHAR], MaxInt, Length(DatString), PAnsiChar(DatString));\n          end;\n        stTime:\n          begin\n            DatString := AnsiString(FormatDateTime('hh\":\"mm\":\"ss\":\"zzz',\n              SoftVarManager.GetAsDateTime(InParamValues[I])));\n            FPlainDriver.dbRpcParam(FHandle, nil, RetParam,\n              FPlainDriver.GetVariables.datatypes[Z_SQLCHAR], MaxInt, Length(DatString), PAnsiChar(DatString));\n          end;\n        stTimeStamp:\n          begin\n            DatString := AnsiString(FormatDateTime('yyyymmdd hh\":\"mm\":\"ss\":\"zzz',\n              SoftVarManager.GetAsDateTime(InParamValues[I])));\n            FPlainDriver.dbRpcParam(FHandle, nil, RetParam,\n              FPlainDriver.GetVariables.datatypes[Z_SQLCHAR], MaxInt, Length(DatString), PAnsiChar(DatString));\n          end;\n        stAsciiStream, stUnicodeStream, stBinaryStream:\n          begin\n            TempBlob := SoftVarManager.GetAsInterface(InParamValues[I]) as IZBlob;\n            DatString := TempBlob.GetString;\n            if DatString = '' then\n              DatLen := 1\n            else\n              DatLen := Length(DatString);\n            if ParamType = stBinaryStream then\n              FPlainDriver.dbRpcParam(FHandle, nil, RetParam,\n                FPlainDriver.GetVariables.datatypes[Z_SQLBINARY], MaxInt, Length(DatString), PAnsiChar(DatString))\n            else\n              FPlainDriver.dbRpcParam(FHandle, nil, RetParam,\n                FPlainDriver.GetVariables.datatypes[Z_SQLTEXT], FPlainDriver.GetVariables.dboptions[Z_TEXTSIZE], DatLen, PAnsiChar(DatString));\n          end;\n        stBytes:\n          begin\n            DatString := AnsiString(SoftVarManager.GetAsString(InParamValues[I]));\n            FPlainDriver.dbRpcParam(FHandle, nil, RetParam,\n              FPlainDriver.GetVariables.datatypes[Z_SQLBINARY], MaxInt, Length(DatString), PAnsiChar(DatString));\n          end;\n      else\n        FPlainDriver.dbRpcParam(FHandle, nil, 0, FPlainDriver.GetVariables.datatypes[Z_SQLCHAR], 0, 0, nil);\n    end;\n  end;\n  end;\n\n  if FPLainDriver.dbRpcExec(FHandle) <> DBSUCCEED then\n    FDBLibConnection.CheckDBLibError(lcOther, 'EXECUTEPREPARED:dbRPCExec');\n  FetchResults;\n  Result := GetMoreResults;\n\n  if FPLainDriver.dbHasRetStat(FHandle) then\n    DefVarManager.SetAsInteger(Temp, FPlainDriver.dbRetStatus(FHandle))\n  else\n    Temp := NullVariant;\n  OutParamValues[0] := Temp; //set function RETURN_VALUE\n\n  ParamIndex := 1;\n  for I := 1 to OutParamCount - 1 do\n  begin\n    if OutParamTypes[I] = stUnknown then\n      Continue;\n    if FPlainDriver.dbRetData(FHandle, ParamIndex) = nil then\n      Temp := NullVariant\n    else\n    begin\n      if FDBLibConnection.FreeTDS then\n        case FPLainDriver.dbRetType(FHandle, ParamIndex) of\n          TDSSQLCHAR, TDSSQLBINARY:\n            begin\n              DatLen := FPLainDriver.dbRetLen(FHandle, ParamIndex);\n              SetLength(DatBytes, DatLen);\n              Move(PAnsiChar(FPLainDriver.dbRetData(FHandle, ParamIndex))^,\n                DatBytes[0], Length(DatBytes));\n              DefVarManager.SetAsString(Temp, String(BytesToStr(DatBytes)));\n            end;\n          TDSSQLINT1:\n            DefVarManager.SetAsInteger(Temp,\n              PByte(FPlainDriver.dbRetData(FHandle, ParamIndex))^);\n          TDSSQLINT2:\n            DefVarManager.SetAsInteger(Temp,\n              PSmallInt(FPLainDriver.dbRetData(FHandle, ParamIndex))^);\n          TDSSQLINT4:\n            DefVarManager.SetAsInteger(Temp,\n              PInteger(FPLainDriver.dbRetData(FHandle, ParamIndex))^);\n          TDSSQLFLT4:\n            DefVarManager.SetAsFloat(Temp,\n              PSingle(FPLainDriver.dbRetData(FHandle, ParamIndex))^);\n          TDSSQLFLT8:\n            DefVarManager.SetAsFloat(Temp,\n              PDouble(FPLainDriver.dbRetData(FHandle, ParamIndex))^);\n          TDSSQLMONEY4:\n            begin\n              FPlainDriver.dbConvert(FHandle, TDSSQLMONEY4,\n                FPlainDriver.dbRetData(FHandle, ParamIndex), 4, TDSSQLMONEY,\n                @DatMoney, 8);\n              DefVarManager.SetAsFloat(Temp, DatMoney);\n            end;\n          TDSSQLMONEY:\n            DefVarManager.SetAsFloat(Temp,\n              PCurrency(FPLainDriver.dbRetData(FHandle, ParamIndex))^);\n          TDSSQLDECIMAL:\n            begin\n              FPLainDriver.dbConvert(FHandle, TDSSQLDECIMAL,\n                FPLainDriver.dbRetData(FHandle, ParamIndex),\n                FPLainDriver.dbRetLen(FHandle, ParamIndex),\n                TDSSQLFLT8, @DatDouble, 8);\n              DefVarManager.SetAsFloat(Temp, DatDouble);\n            end;\n          TDSSQLNUMERIC:\n            begin\n              FPLainDriver.dbConvert(FHandle, TDSSQLNUMERIC,\n                FPLainDriver.dbRetData(FHandle, ParamIndex),\n                FPLainDriver.dbRetLen(FHandle, ParamIndex),\n                TDSSQLFLT8, @DatDouble, 8);\n              DefVarManager.SetAsFloat(Temp, DatDouble);\n            end;\n          TDSSQLDATETIM4:\n            begin\n              FPLainDriver.dbConvert(FHandle, TDSSQLDATETIM4,\n                FPLainDriver.dbRetData(FHandle, ParamIndex), 4,\n                TDSSQLDATETIME, @DatDBDATETIME, 8);\n              DefVarManager.SetAsDateTime(Temp,\n                DatDBDATETIME.dtdays + 2 + (DatDBDATETIME.dttime / 25920000));\n            end;\n          TDSSQLDATETIME:\n            begin\n              DatDBDATETIME := PDBDATETIME(\n                FPLainDriver.dbRetData(FHandle, ParamIndex))^;\n              DefVarManager.SetAsDateTime(Temp,\n                DatDBDATETIME.dtdays + 2 + (DatDBDATETIME.dttime / 25920000));\n            end;\n          else\n            Temp := NullVariant;\n        end\n      else\n        case FPLainDriver.dbRetType(FHandle, ParamIndex) of\n          DBLIBSQLCHAR, DBLIBSQLBINARY:\n            begin\n              DatLen := FPLainDriver.dbRetLen(FHandle, ParamIndex);\n              SetLength(DatBytes, DatLen);\n              Move(PAnsiChar(FPLainDriver.dbRetData(FHandle, ParamIndex))^,\n                DatBytes[0], Length(DatBytes));\n              DefVarManager.SetAsString(Temp, String(BytesToStr(DatBytes)));\n            end;\n          DBLIBSQLINT1:\n            DefVarManager.SetAsInteger(Temp,\n              PByte(FPlainDriver.dbRetData(FHandle, ParamIndex))^);\n          DBLIBSQLINT2:\n            DefVarManager.SetAsInteger(Temp,\n              PSmallInt(FPLainDriver.dbRetData(FHandle, ParamIndex))^);\n          DBLIBSQLINT4:\n            DefVarManager.SetAsInteger(Temp,\n              PInteger(FPLainDriver.dbRetData(FHandle, ParamIndex))^);\n          DBLIBSQLFLT4:\n            DefVarManager.SetAsFloat(Temp,\n              PSingle(FPLainDriver.dbRetData(FHandle, ParamIndex))^);\n          DBLIBSQLFLT8:\n            DefVarManager.SetAsFloat(Temp,\n              PDouble(FPLainDriver.dbRetData(FHandle, ParamIndex))^);\n          DBLIBSQLMONEY4:\n            begin\n              FPlainDriver.dbConvert(FHandle, DBLIBSQLMONEY4,\n                FPlainDriver.dbRetData(FHandle, ParamIndex), 4, DBLIBSQLMONEY,\n                @DatMoney, 8);\n              DefVarManager.SetAsFloat(Temp, DatMoney);\n            end;\n          DBLIBSQLMONEY:\n            DefVarManager.SetAsFloat(Temp,\n              PCurrency(FPLainDriver.dbRetData(FHandle, ParamIndex))^);\n          DBLIBSQLDECIMAL:\n            begin\n              FPLainDriver.dbConvert(FHandle, DBLIBSQLDECIMAL,\n                FPLainDriver.dbRetData(FHandle, ParamIndex),\n                FPLainDriver.dbRetLen(FHandle, ParamIndex),\n                DBLIBSQLFLT8, @DatDouble, 8);\n              DefVarManager.SetAsFloat(Temp, DatDouble);\n            end;\n          DBLIBSQLNUMERIC:\n            begin\n              FPLainDriver.dbConvert(FHandle, DBLIBSQLNUMERIC,\n                FPLainDriver.dbRetData(FHandle, ParamIndex),\n                FPLainDriver.dbRetLen(FHandle, ParamIndex),\n                DBLIBSQLFLT8, @DatDouble, 8);\n              DefVarManager.SetAsFloat(Temp, DatDouble);\n            end;\n          DBLIBSQLDATETIM4:\n            begin\n              FPLainDriver.dbConvert(FHandle, DBLIBSQLDATETIM4,\n                FPLainDriver.dbRetData(FHandle, ParamIndex), 4,\n                DBLIBSQLDATETIME, @DatDBDATETIME, 8);\n              DefVarManager.SetAsDateTime(Temp,\n                DatDBDATETIME.dtdays + 2 + (DatDBDATETIME.dttime / 25920000));\n            end;\n          DBLIBSQLDATETIME:\n            begin\n              DatDBDATETIME := PDBDATETIME(\n                FPLainDriver.dbRetData(FHandle, ParamIndex))^;\n              DefVarManager.SetAsDateTime(Temp,\n                DatDBDATETIME.dtdays + 2 + (DatDBDATETIME.dttime / 25920000));\n            end;\n          else\n            Temp := NullVariant;\n        end;\n    end;\n    OutParamValues[I] := Temp;\n    Inc(ParamIndex);\n  end;\n\n//Workaround for sybase. the dbCount does not work, so a select @@rowcount is\n//made but this cleared the returned output parameters, so this is moved here\n//after reading the output parameters\n  FetchRowCount;\n\n  DriverManager.LogMessage(lcExecute, FPlainDriver.GetProtocol,\n    Format('EXEC %s', [SQL]));\nend;\n\nprocedure TZDBLibCallableStatement.SetInParamCount(NewParamCount: Integer);\nbegin\n  inherited SetInParamCount(NewParamCount);\n\n  if OutParamCount < NewParamCount then\n    SetOutParamCount(NewParamCount);\nend;\n\nend.\n\n\n"
  },
  {
    "path": "lib/zeosdbo/src/dbc/ZDbcDbLibUtils.pas",
    "content": "{*********************************************************}\n{                                                         }\n{                 Zeos Database Objects                   }\n{                DBLib Utility Functions                  }\n{                                                         }\n{        Originally written by Janos Fegyverneki          }\n{                                                         }\n{*********************************************************}\n\n{@********************************************************}\n{    Copyright (c) 1999-2012 Zeos Development Group       }\n{                                                         }\n{ License Agreement:                                      }\n{                                                         }\n{ This library is distributed in the hope that it will be }\n{ useful, but WITHOUT ANY WARRANTY; without even the      }\n{ implied warranty of MERCHANTABILITY or FITNESS FOR      }\n{ A PARTICULAR PURPOSE.  See the GNU Lesser General       }\n{ Public License for more details.                        }\n{                                                         }\n{ The source code of the ZEOS Libraries and packages are  }\n{ distributed under the Library GNU General Public        }\n{ License (see the file COPYING / COPYING.ZEOS)           }\n{ with the following  modification:                       }\n{ As a special exception, the copyright holders of this   }\n{ library give you permission to link this library with   }\n{ independent modules to produce an executable,           }\n{ regardless of the license terms of these independent    }\n{ modules, and to copy and distribute the resulting       }\n{ executable under terms of your choice, provided that    }\n{ you also meet, for each linked independent module,      }\n{ the terms and conditions of the license of that module. }\n{ An independent module is a module which is not derived  }\n{ from or based on this library. If you modify this       }\n{ library, you may extend this exception to your version  }\n{ of the library, but you are not obligated to do so.     }\n{ If you do not wish to do so, delete this exception      }\n{ statement from your version.                            }\n{                                                         }\n{                                                         }\n{ The project web site is located on:                     }\n{   http://zeos.firmos.at  (FORUM)                        }\n{   http://sourceforge.net/p/zeoslib/tickets/ (BUGTRACKER)}\n{   svn://svn.code.sf.net/p/zeoslib/code-0/trunk (SVN)    }\n{                                                         }\n{   http://www.sourceforge.net/projects/zeoslib.          }\n{                                                         }\n{                                                         }\n{                                 Zeos Development Group. }\n{********************************************************@}\n\nunit ZDbcDbLibUtils;\n\ninterface\n\n{$I ZDbc.inc}\n\nuses Classes, SysUtils, ZVariant, ZDbcIntfs, ZPlainDBLibDriver, ZCompatibility;\n\n{**\n  Converts an ODBC native types into ZDBC SQL types.\n  @param FieldType dblibc native field type.\n  @return a SQL undepended type.\n}\nfunction ConvertODBCToSqlType(FieldType: SmallInt; CtrlsCPType: TZControlsCodePage): TZSQLType;\n\n{**\n  Converts a DBLib native types into ZDBC SQL types.\n  @param FieldType dblibc native field type.\n  @return a SQL undepended type.\n}\nfunction ConvertDBLibToSqlType(FieldType: SmallInt; CtrlsCPType: TZControlsCodePage): TZSQLType;\nfunction ConvertFreeTDSToSqlType(const FieldType: SmallInt;\n  const CtrlsCPType: TZControlsCodePage): TZSQLType;\n\n{**\n  Convert string DBLib field type to SqlType\n  @param string field type value\n  @result the SqlType field type value\n}\nfunction ConvertDBLibTypeToSqlType(Value: string): TZSQLType;\n\n{**\n  Converts ZDBC SQL types into MS SQL native types.\n  @param FieldType dblibc native field type.\n  @return a SQL undepended type.\n}\nfunction ConvertSqlTypeToDBLibType(FieldType: TZSQLType): Integer;\nfunction ConvertSqlTypeToFreeTDSType(FieldType: TZSQLType): Integer;\n\n{**\n  Converts ZDBC SQL types into MS SQL native types.\n  @param FieldType dblibc native field type.\n  @return a SQL undepended type.\n}\nfunction ConvertSqlTypeToDBLibTypeName(FieldType: TZSQLType): string;\nfunction ConvertSqlTypeToFreeTDSTypeName(FieldType: TZSQLType): string;\n\n{**\n  Converts a DBLib nullability value into ZDBC TZColumnNullableType.\n  @param DBLibNullability dblibc native nullability.\n  @return a SQL TZColumnNullableType.\n}\nfunction ConvertDBLibNullability(DBLibNullability: Byte): TZColumnNullableType;\n\n{**\n  Prepares an SQL parameter for the query.\n  @param ParameterIndex the first parameter is 1, the second is 2, ...\n  @return a string representation of the parameter.\n}\nfunction PrepareSQLParameter(Value: TZVariant; ParamType: TZSQLType;\n  ConSettings: PZConSettings; PlainDriver: IZDBLibPlainDriver;\n  const NChar: Boolean = False): RawByteString;\n\nimplementation\n\nuses Types, ZSysUtils, ZPlainDbLibConstants, ZEncoding, ZDbcUtils\n  {$IFDEF WITH_UNITANSISTRINGS}, AnsiStrings{$ENDIF};\n\n{**\n  Converts an ODBC native types into ZDBC SQL types.\n  @param FieldType dblibc native field type.\n  @return a SQL undepended type.\n}\nfunction ConvertODBCToSqlType(FieldType: SmallInt;\n  CtrlsCPType: TZControlsCodePage): TZSQLType;\nbegin\n  case FieldType of\n    1, 12, -8, -9: Result := stString;\n    -7{bit}: Result := stBoolean;\n//Bug #889223, bug with tinyint on mssql\n//    -6: Result := stByte;\n    -5: Result := stLong;\n    -6: Result := stShort;\n    5: Result := stShort;\n    4: Result := stInteger;\n    2, 3, 6, 7, 8: Result := stDouble;\n    11, 93: Result := stTimestamp;\n    -1, -10: Result := stAsciiStream;\n    -4{image}: Result := stBinaryStream;\n    -2{binary},-3{varbinary},-11{uniqueidentifier}: Result := stBytes;\n  else\n    Result := stUnknown;\n  end;\n  if CtrlsCPType = cCP_UTF16 then\n  case Result of\n    stString: Result := stUnicodeString;\n    stAsciiStream: Result := stUnicodeStream;\n  end;\nend;\n\n{**\n  Converts a DBLib native types into ZDBC SQL types.\n  @param FieldType dblibc native field type.\n  @return a SQL undepended type.\n}\nfunction ConvertDBLibToSqlType(FieldType: SmallInt;\n  CtrlsCPType: TZControlsCodePage): TZSQLType;\nbegin\n  case FieldType of\n    DBLIBSQLCHAR: Result := stString;\n    DBLIBSQLBIT: Result := stBoolean;\n//Bug #889223, bug with tinyint on mssql\n//    DBLIBSQLINT1: Result := stByte;\n    DBLIBSQLINT1: Result := stShort;\n    DBLIBSQLINT2: Result := stShort;\n    DBLIBSQLINT4: Result := stInteger;\n    DBLIBSQLFLT4: Result := stDouble;\n    DBLIBSQLFLT8: Result := stDouble;\n    DBLIBSQLMONEY4: Result := stDouble;\n    DBLIBSQLMONEY: Result := stDouble;\n    DBLIBSQLDATETIM4: Result := stTimestamp;\n    DBLIBSQLDATETIME: Result := stTimestamp;\n    DBLIBSQLTEXT: Result := stAsciiStream;\n    DBLIBSQLIMAGE: Result := stBinaryStream;\n    DBLIBSQLBINARY: Result := stBinaryStream;\n  else\n    Result := stUnknown;\n  end;\n  if CtrlsCPType = cCP_UTF16 then\n  case Result of\n    stString: Result := stUnicodeString;\n    stAsciiStream: Result := stUnicodeStream;\n  end;\nend;\n\n{**\n  Converts a FreeTDS native types into ZDBC SQL types.\n  @param FieldType dblibc native field type.\n  @return a SQL undepended type.\n}\nfunction ConvertFreeTDSToSqlType(const FieldType: SmallInt;\n  const CtrlsCPType: TZControlsCodePage): TZSQLType;\nbegin\n  case FieldType of\n    SYBCHAR, SYBVARCHAR, XSYBCHAR, XSYBVARCHAR: Result := stString;\n    SYBINTN, SYBINT4:                           Result := stInteger;\n    SYBINT8:                                    Result := stLong;\n    SYBNUMERIC:                                 Result := stBigDecimal;\n    SYBINT1, SYBINT2:                           Result := stShort;\n    SYBFLT8, SYBFLTN, SYBREAL, SYBDECIMAL:      Result := stDouble;\n    SYBDATETIME, SYBDATETIME4, SYBDATETIMN:     Result := stTimestamp;\n    SYBBIT, SYBBITN:                            Result := stBoolean;\n    SYBTEXT:                                    Result := stAsciiStream;\n    SYBNTEXT:                                   Result := stUnicodeStream;\n    SYBIMAGE:                                   Result := stBinaryStream;\n    SYBBINARY, SYBVARBINARY,\n    XSYBBINARY, XSYBVARBINARY:                  Result := stBytes;\n    SYBMONEY4, SYBMONEY, SYBMONEYN:             Result := stDouble;\n    SYBVOID:                                    Result := stUnknown;\n    SYBNVARCHAR, XSYBNCHAR, XSYBNVARCHAR:       Result := stUnicodeString;\n    SYBMSXML:                                   Result := stBinaryStream;\n    SYBUNIQUE:                                  Result := stString;\n    SYBVARIANT:                                 Result := stString;\n    SYBMSUDT:                                   Result := stString;\n    else\n      Result := stUnknown;\n  end;\n  if CtrlsCPType = cCP_UTF16 then\n  case Result of\n    stString: Result := stUnicodeString;\n    stAsciiStream: Result := stUnicodeStream;\n  end;\nend;\n\n{**\n  Convert string DBLib field type to SqlType\n  @param string field type value\n  @result the SqlType field type value\n}\nfunction ConvertDBLibTypeToSqlType(Value: string): TZSQLType;\nbegin\n  Result := stUnknown;\nend;\n\n{**\n  Converts ZDBC SQL types into DBLib native types.\n  @param FieldType dblibc native field type.\n  @return a SQL undepended type.\n}\nfunction ConvertSqlTypeToDBLibType(FieldType: TZSQLType): Integer;\nbegin\n  Result := -1;\n  case FieldType of\n    stBoolean: Result := DBLIBSQLBIT;\n    stByte: Result := DBLIBSQLINT1;\n    stShort: Result := DBLIBSQLINT2;\n    stInteger: Result := DBLIBSQLINT4;\n    stLong: Result := DBLIBSQLFLT8;\n    stFloat: Result := DBLIBSQLFLT8;\n    stDouble: Result := DBLIBSQLFLT8;\n    stBigDecimal: Result := DBLIBSQLFLT8;\n    stString: Result := DBLIBSQLCHAR;\n    stBytes: Result := DBLIBSQLBINARY;\n    stDate: Result := DBLIBSQLDATETIME;\n    stTime: Result := DBLIBSQLDATETIME;\n    stTimestamp: Result := DBLIBSQLDATETIME;\n    stAsciiStream: Result := DBLIBSQLTEXT;\n    stUnicodeStream: Result := DBLIBSQLIMAGE;\n    stBinaryStream: Result := DBLIBSQLIMAGE;\n  end;\nend;\n\n{**\n  Converts ZDBC SQL types into DBLib native types.\n  @param FieldType dblibc native field type.\n  @return a SQL undepended type.\n}\nfunction ConvertSqlTypeToDBLibTypeName(FieldType: TZSQLType): string;\nbegin\n  Result := '';\n  case FieldType of\n    stBoolean: Result := 'bit';\n    stByte: Result := 'tinyint';\n    stShort: Result := 'smallint';\n    stInteger: Result := 'int';\n    stLong: Result := 'bigint';\n    stFloat: Result := 'float(24)';\n    stDouble: Result := 'float(53)';\n    stBigDecimal: Result := 'float(53)';\n    stString: Result := 'varchar(8000)';\n    stBytes: Result := 'varbinary(8000)';\n    stDate: Result := 'datetime';\n    stTime: Result := 'datetime';\n    stTimestamp: Result := 'datetime';\n    stAsciiStream: Result := 'text';\n    stUnicodeStream: Result := 'ntext';\n    stBinaryStream: Result := 'image';\n  end;\nend;\n\n{**\n  Converts ZDBC SQL types into FreeTDS native types.\n  @param FieldType dblibc native field type.\n  @return a SQL undepended type.\n}\nfunction ConvertSqlTypeToFreeTDSType(FieldType: TZSQLType): Integer;\nbegin\n  Result := -1;\n  case FieldType of\n    stBoolean: Result := SYBBIT;\n    stByte: Result := SYBINT1;\n    stShort: Result := SYBINT2;\n    stInteger: Result := SYBINT4;\n    stLong: Result := SYBFLT8;\n    stFloat: Result := SYBFLT8;\n    stDouble: Result := SYBFLT8;\n    stBigDecimal: Result := SYBFLT8;\n    stString: Result := SYBCHAR;\n    stUnicodeString: Result := SYBNVARCHAR;\n    stBytes: Result := SYBBINARY;\n    stDate: Result := SYBDATETIME;\n    stTime: Result := SYBDATETIME;\n    stTimestamp: Result := SYBDATETIME;\n    stAsciiStream: Result := SYBTEXT;\n    stUnicodeStream: Result := SYBNTEXT;\n    stBinaryStream: Result := SYBIMAGE;\n  end;\nend;\n\n{**\n  Converts ZDBC SQL types into FreeTDS native types.\n  @param FieldType dblibc native field type.\n  @return a SQL undepended type.\n}\nfunction ConvertSqlTypeToFreeTDSTypeName(FieldType: TZSQLType): string;\nbegin\n  Result := '';\n  case FieldType of\n    stBoolean: Result := 'bit';\n    stByte: Result := 'tinyint';\n    stShort: Result := 'smallint';\n    stInteger: Result := 'int';\n    stLong: Result := 'bigint';\n    stFloat: Result := 'float(24)';\n    stDouble: Result := 'float(53)';\n    stBigDecimal: Result := 'float(53)';\n    stString: Result := 'varchar(8000)';\n    stUnicodeString: Result := 'nvarchar(4000)';\n    stBytes: Result := 'varbinary(8000)';\n    stDate: Result := 'datetime';\n    stTime: Result := 'datetime';\n    stTimestamp: Result := 'datetime';\n    stAsciiStream: Result := 'text';\n    stUnicodeStream: Result := 'ntext';\n    stBinaryStream: Result := 'image';\n  end;\nend;\n\n\n{**\n  Converts a DBLib nullability value into ZDBC TZColumnNullableType.\n  @param DBLibNullability dblibc native nullability.\n  @return a SQL TZColumnNullableType.\n}\nfunction ConvertDBLibNullability(DBLibNullability: Byte): TZColumnNullableType;\nconst\n  Nullability: array[0..2] of TZColumnNullableType =\n    (ntNoNulls, ntNullable, ntNullableUnknown);\nbegin\n  Result := Nullability[DBLibNullability];\nend;\n\n{**\n  Prepares an SQL parameter for the query.\n  @param ParameterIndex the first parameter is 1, the second is 2, ...\n  @return a string representation of the parameter.\n}\nfunction PrepareSQLParameter(Value: TZVariant; ParamType: TZSQLType;\n  ConSettings: PZConSettings; PlainDriver: IZDBLibPlainDriver;\n    const NChar: Boolean = False): RawByteString;\nvar\n  TempBytes: TByteDynArray;\n  TempBlob: IZBlob;\nbegin\n  TempBytes := nil;\n\n  if DefVarManager.IsNull(Value) then\n    Result := 'NULL'\n  else\n  begin\n    case ParamType of\n      stBoolean:\n        if SoftVarManager.GetAsBoolean(Value) then\n          Result := '1'\n        else\n          Result := '0';\n      stByte, stShort, stInteger, stLong, stFloat, stDouble, stBigDecimal:\n        Result := RawByteString(SoftVarManager.GetAsString(Value));\n      stString:\n        if NChar then\n          Result := {$IFDEF WITH_UNITANSISTRINGS}AnsiStrings.{$ENDIF}AnsiQuotedStr(PlainDriver.ZPlainString(SoftVarManager.GetAsString(Value), ConSettings, zCP_UTF8), '''')\n        else\n          Result := {$IFDEF WITH_UNITANSISTRINGS}AnsiStrings.{$ENDIF}AnsiQuotedStr(PlainDriver.ZPlainString(SoftVarManager.GetAsString(Value), ConSettings), '''');\n      stUnicodeString:\n        if NChar then\n          Result := {$IFDEF WITH_UNITANSISTRINGS}AnsiStrings.{$ENDIF}AnsiQuotedStr(UTF8Encode(SoftVarManager.GetAsUnicodeString(Value)),'''')\n        else\n          Result := {$IFDEF WITH_UNITANSISTRINGS}AnsiStrings.{$ENDIF}AnsiQuotedStr(PlainDriver.ZPlainString(SoftVarManager.GetAsUnicodeString(Value), ConSettings),'''');\n      stBytes:\n        begin\n          TempBytes := SoftVarManager.GetAsBytes(Value);\n          if Length(TempBytes) = 0 then\n            Result := 'NULL'\n          else\n            Result := GetSQLHexAnsiString(PAnsiChar(TempBytes), Length(TempBytes), True);\n        end;\n      stDate:\n        Result := RawByteString('''' + FormatDateTime(ConSettings^.DateFormat,\n          SoftVarManager.GetAsDateTime(Value)) + '''');\n      stTime:\n        Result := RawByteString('''' + FormatDateTime('hh\":\"mm\":\"ss\":\"zzz',\n          SoftVarManager.GetAsDateTime(Value)) + '''');\n      stTimestamp:\n        Result := RawByteString('''' + FormatDateTime(ConSettings^.DateFormat+' hh\":\"mm\":\"ss\":\"zzz',\n          SoftVarManager.GetAsDateTime(Value)) + '''');\n      stAsciiStream, stUnicodeStream, stBinaryStream:\n        begin\n          TempBlob := DefVarManager.GetAsInterface(Value) as IZBlob;\n          if not TempBlob.IsEmpty then\n          begin\n            if ParamType = stBinaryStream then\n              Result := GetSQLHexAnsiString(PAnsiChar(TempBlob.GetBuffer), TempBlob.Length, True)\n            else\n              if NChar then\n              {$IFDEF WITH_UNITANSISTRINGS}\n                Result := AnsiStrings.AnsiQuotedStr(AnsiStrings.StringReplace(\n                  GetValidatedAnsiStringFromBuffer(TempBlob.GetBuffer,\n                    TempBlob.Length, ConSettings, zCP_UTF8), #0, '', [rfReplaceAll]), '''')\n              else\n                Result := AnsiStrings.AnsiQuotedStr(AnsiStrings.StringReplace(\n                  GetValidatedAnsiStringFromBuffer(TempBlob.GetBuffer,\n                    TempBlob.Length, TempBlob.WasDecoded, ConSettings), #0, '', [rfReplaceAll]), '''')\n              {$ELSE}\n                Result := AnsiQuotedStr(StringReplace(\n                  GetValidatedAnsiStringFromBuffer(TempBlob.GetBuffer,\n                    TempBlob.Length, ConSettings, zCP_UTF8), #0, '', [rfReplaceAll]), '''')\n              else\n                Result := AnsiQuotedStr(StringReplace(\n                  GetValidatedAnsiStringFromBuffer(TempBlob.GetBuffer,\n                    TempBlob.Length, TempBlob.WasDecoded, ConSettings), #0, '', [rfReplaceAll]), '''')\n              {$ENDIF}\n          end\n          else\n            Result := 'NULL';\n          TempBlob := nil;\n        end;\n      else\n        Result := 'NULL';\n    end;\n  end;\nend;\n\nend.\n"
  },
  {
    "path": "lib/zeosdbo/src/dbc/ZDbcGenericResolver.pas",
    "content": "{*********************************************************}\n{                                                         }\n{                 Zeos Database Objects                   }\n{                Generic Cached Resolver                  }\n{                                                         }\n{        Originally written by Sergey Seroukhov           }\n{                                                         }\n{*********************************************************}\n\n{@********************************************************}\n{    Copyright (c) 1999-2012 Zeos Development Group       }\n{                                                         }\n{ License Agreement:                                      }\n{                                                         }\n{ This library is distributed in the hope that it will be }\n{ useful, but WITHOUT ANY WARRANTY; without even the      }\n{ implied warranty of MERCHANTABILITY or FITNESS FOR      }\n{ A PARTICULAR PURPOSE.  See the GNU Lesser General       }\n{ Public License for more details.                        }\n{                                                         }\n{ The source code of the ZEOS Libraries and packages are  }\n{ distributed under the Library GNU General Public        }\n{ License (see the file COPYING / COPYING.ZEOS)           }\n{ with the following  modification:                       }\n{ As a special exception, the copyright holders of this   }\n{ library give you permission to link this library with   }\n{ independent modules to produce an executable,           }\n{ regardless of the license terms of these independent    }\n{ modules, and to copy and distribute the resulting       }\n{ executable under terms of your choice, provided that    }\n{ you also meet, for each linked independent module,      }\n{ the terms and conditions of the license of that module. }\n{ An independent module is a module which is not derived  }\n{ from or based on this library. If you modify this       }\n{ library, you may extend this exception to your version  }\n{ of the library, but you are not obligated to do so.     }\n{ If you do not wish to do so, delete this exception      }\n{ statement from your version.                            }\n{                                                         }\n{                                                         }\n{ The project web site is located on:                     }\n{   http://zeos.firmos.at  (FORUM)                        }\n{   http://sourceforge.net/p/zeoslib/tickets/ (BUGTRACKER)}\n{   svn://svn.code.sf.net/p/zeoslib/code-0/trunk (SVN)    }\n{                                                         }\n{   http://www.sourceforge.net/projects/zeoslib.          }\n{                                                         }\n{                                                         }\n{                                 Zeos Development Group. }\n{********************************************************@}\n\nunit ZDbcGenericResolver;\n\ninterface\n\n{$I ZDbc.inc}\n\nuses\n  Types, Classes, {$IFDEF MSEgui}mclasses,{$ENDIF} SysUtils, Contnrs,\n  ZVariant, ZDbcIntfs, ZDbcCache, ZDbcCachedResultSet, ZCompatibility,\n  ZSelectSchema;\n\ntype\n\n  {** Implements a resolver parameter object. }\n  TZResolverParameter = class (TObject)\n  private\n    FColumnIndex: Integer;\n    FColumnName: string;\n    FColumnType: TZSQLType;\n    FNewValue: Boolean;\n    FDefaultValue: string;\n  public\n    constructor Create(ColumnIndex: Integer; ColumnName: string;\n      ColumnType: TZSQLType; NewValue: Boolean; DefaultValue: string);\n\n    property ColumnIndex: Integer read FColumnIndex write FColumnIndex;\n    property ColumnName: string read FColumnName write FColumnName;\n    property ColumnType: TZSQLType read FColumnType write FColumnType;\n    property NewValue: Boolean read FNewValue write FNewValue;\n    property DefaultValue: string read FDefaultValue write FDefaultValue;\n  end;\n\n  {**\n    Implements a generic cached resolver object which generates\n    DML SQL statements and posts resultset updates to database.\n  }\n\n  { TZGenericCachedResolver }\n\n  TZGenericCachedResolver = class (TInterfacedObject, IZCachedResolver)\n  private\n    FConnection: IZConnection;\n    FStatement : IZStatement;\n    FMetadata: IZResultSetMetadata;\n    FDatabaseMetadata: IZDatabaseMetadata;\n    FIdentifierConvertor: IZIdentifierConvertor;\n\n    FInsertColumns: TObjectList;\n    FUpdateColumns: TObjectList;\n    FWhereColumns: TObjectList;\n\n    FCalcDefaults: Boolean;\n    FWhereAll: Boolean;\n    FUpdateAll: Boolean;\n\n    InsertStatement            : IZPreparedStatement;\n    UpdateStatement            : IZPreparedStatement;\n    DeleteStatement            : IZPreparedStatement;\n\n  protected\n    procedure CopyResolveParameters(FromList, ToList: TObjectList);\n    function ComposeFullTableName(Catalog, Schema, Table: string): string;\n    function DefineTableName: string;\n\n    function CreateResolverStatement(SQL : String):IZPreparedStatement;\n\n    procedure DefineCalcColumns(Columns: TObjectList;\n      RowAccessor: TZRowAccessor);\n    procedure DefineInsertColumns(Columns: TObjectList);\n    procedure DefineUpdateColumns(Columns: TObjectList;\n      OldRowAccessor, NewRowAccessor: TZRowAccessor);\n    procedure DefineWhereKeyColumns(Columns: TObjectList);\n    procedure DefineWhereAllColumns(Columns: TObjectList; IgnoreKeyColumn: Boolean = False);\n    function CheckKeyColumn(ColumnIndex: Integer): Boolean; virtual;\n\n    procedure FillStatement(Statement: IZPreparedStatement;\n      Params: TObjectList; OldRowAccessor, NewRowAccessor: TZRowAccessor);\n\n    property Connection: IZConnection read FConnection write FConnection;\n    property Metadata: IZResultSetMetadata read FMetadata write FMetadata;\n    property DatabaseMetadata: IZDatabaseMetadata read FDatabaseMetadata\n      write FDatabaseMetadata;\n    property IdentifierConvertor: IZIdentifierConvertor\n      read FIdentifierConvertor write FIdentifierConvertor;\n\n    property InsertColumns: TObjectList read FInsertColumns;\n    property UpdateColumns: TObjectList read FUpdateColumns;\n    property WhereColumns: TObjectList read FWhereColumns;\n\n    property CalcDefaults: Boolean read FCalcDefaults write FCalcDefaults;\n    property WhereAll: Boolean read FWhereAll write FWhereAll;\n    property UpdateAll: Boolean read FUpdateAll write FUpdateAll;\n\n  public\n    constructor Create(Statement: IZStatement; Metadata: IZResultSetMetadata);\n    destructor Destroy; override;\n\n    function FormWhereClause(Columns: TObjectList;\n      OldRowAccessor: TZRowAccessor): string; virtual;\n    function FormInsertStatement(Columns: TObjectList;\n      NewRowAccessor: TZRowAccessor): string;\n    function FormUpdateStatement(Columns: TObjectList;\n      OldRowAccessor, NewRowAccessor: TZRowAccessor): string;\n    function FormDeleteStatement(Columns: TObjectList;\n      OldRowAccessor: TZRowAccessor): string;\n    function FormCalculateStatement(Columns: TObjectList): string; virtual;\n\n    procedure CalculateDefaults(Sender: IZCachedResultSet;\n      RowAccessor: TZRowAccessor);\n    procedure PostUpdates(Sender: IZCachedResultSet;\n      UpdateType: TZRowUpdateType;\n      OldRowAccessor, NewRowAccessor: TZRowAccessor); virtual;\n    {BEGIN of PATCH [1185969]: Do tasks after posting updates. ie: Updating AutoInc fields in MySQL }\n    procedure UpdateAutoIncrementFields(Sender: IZCachedResultSet;\n      UpdateType: TZRowUpdateType;\n      OldRowAccessor, NewRowAccessor: TZRowAccessor; Resolver: IZCachedResolver); virtual;\n    {END of PATCH [1185969]: Do tasks after posting updates. ie: Updating AutoInc fields in MySQL }\n    procedure RefreshCurrentRow(Sender: IZCachedResultSet;RowAccessor: TZRowAccessor); //FOS+ 07112006\n\n  end;\n\nimplementation\n\nuses ZMessages, ZSysUtils, ZDbcMetadata, ZDbcUtils;\n\n{ TZResolverParameter }\n\n{**\n  Constructs this resolver parameter and assignes the main properties.\n  @param ColumnIndex a result set column index.\n  @param ColumnName a result set column name.\n  @param NewValue <code>True</code> for new value and <code>False</code>\n    for an old one.\n  @param DefaultValue a default column value to evalute on server.\n}\nconstructor TZResolverParameter.Create(ColumnIndex: Integer;\n  ColumnName: string; ColumnType: TZSQLType; NewValue: Boolean; DefaultValue: string);\nbegin\n  FColumnType := ColumnType;\n  FColumnIndex := ColumnIndex;\n  FColumnName := ColumnName;\n  FNewValue := NewValue;\n  FDefaultValue := DefaultValue;\nend;\n\n{ TZGenericCachedResolver }\n\n{**\n  Creates a cached resolver and assignes the main properties.\n  @param ResultSet a related ResultSet object.\n}\nconstructor TZGenericCachedResolver.Create(Statement: IZStatement;\n  Metadata: IZResultSetMetadata);\nbegin\n  FStatement := Statement;\n  FConnection := Statement.GetConnection;\n  FMetadata := Metadata;\n  FDatabaseMetadata := Statement.GetConnection.GetMetadata;\n  FIdentifierConvertor := FDatabaseMetadata.GetIdentifierConvertor;\n\n  FInsertColumns := TObjectList.Create(True);\n  FWhereColumns := TObjectList.Create(True);\n  FUpdateColumns := TObjectList.Create(True);\n\n  FCalcDefaults := StrToBoolEx(DefineStatementParameter(Statement,\n    'defaults', 'true'));\n  FUpdateAll := UpperCase(DefineStatementParameter(Statement,\n    'update', 'changed')) = 'ALL';\n  FWhereAll := UpperCase(DefineStatementParameter(Statement,\n    'where', 'keyonly')) = 'ALL';\n\n  InsertStatement := nil;\n  UpdateStatement := nil;\n  DeleteStatement := nil;\n\nend;\n\n{**\n  Destroys this object and cleanups the memory.\n}\ndestructor TZGenericCachedResolver.Destroy;\nbegin\n  FMetadata := nil;\n  FDatabaseMetadata := nil;\n\n  FreeAndNil(FInsertColumns);\n  FreeAndNil(FUpdateColumns);\n  FreeAndNil(FWhereColumns);\n\n  inherited Destroy;\nend;\n\n{**\n  Copies resolver parameters from source list to destination list.\n  @param FromList the source object list.\n  @param ToList the destination object list.\n}\nprocedure TZGenericCachedResolver.CopyResolveParameters(\n  FromList: TObjectList; ToList: TObjectList);\nvar\n  I: Integer;\n  Current: TZResolverParameter;\nbegin\n  for I := 0 to FromList.Count - 1 do\n  begin\n    Current := TZResolverParameter(FromList[I]);\n    if Current.ColumnName <> '' then\n      ToList.Add(TZResolverParameter.Create(Current.ColumnIndex,\n        Current.ColumnName, Current.ColumnType, Current.NewValue, ''));\n  end;\nend;\n\n{**\n  Composes a fully quilified table name.\n  @param Catalog a table catalog name.\n  @param Schema a table schema name.\n  @param Table a table name.\n  @return a fully qualified table name.\n}\nfunction TZGenericCachedResolver.ComposeFullTableName(Catalog, Schema,\n  Table: string): string;\nbegin\n  if Table <> '' then\n  begin\n    Result := IdentifierConvertor.Quote(Table);\n    if Schema <> '' then\n      Result := IdentifierConvertor.Quote(Schema) + '.' + Result;\n    if Catalog <> '' then\n      Result := IdentifierConvertor.Quote(Catalog) + '.' + Result;\n  end\n  else\n    Result := '';\nend;\n\n{**\n  Defines a table name from the select statement.\n}\nfunction TZGenericCachedResolver.DefineTableName: string;\nvar\n  I: Integer;\n  Temp: string;\nbegin\n  Result := '';\n  for I := 1 to Metadata.GetColumnCount do\n  begin\n    Temp := ComposeFullTableName(Metadata.GetCatalogName(I),\n      Metadata.GetSchemaName(I), Metadata.GetTableName(I));\n    if (Result = '') and (Temp <> '') then\n      Result := Temp\n    else if (Result <> '') and (Temp <> '') and (Temp <> Result) then\n      raise EZSQLException.Create(SCanNotUpdateComplexQuery);\n  end;\n  if Result = '' then\n    raise EZSQLException.Create(SCanNotUpdateThisQueryType);\nend;\n\nfunction TZGenericCachedResolver.CreateResolverStatement(SQL: String): IZPreparedStatement;\nvar\n  Temp : TStrings;\nbegin\n  if StrToBoolEx(FStatement.GetParameters.Values['preferprepared']) then\n    begin\n      Temp := TStringList.Create;\n      Temp.Values['preferprepared'] := 'true';\n      if not ( Connection.GetParameters.Values['chunk_size'] = '' ) then //ordered by precedence\n        Temp.Values['chunk_size'] := Connection.GetParameters.Values['chunk_size']\n      else\n        Temp.Values['chunk_size'] := FStatement.GetParameters.Values['chunk_size'];\n      Result := Connection.PrepareStatementWithParams(SQL, Temp);\n      Temp.Free;\n    end\n  else\n    Result := Connection.PrepareStatement(SQL);\n\nend;\n\n{**\n  Gets a collection of data columns for INSERT statements.\n  @param Columns a collection of columns.\n}\nprocedure TZGenericCachedResolver.DefineInsertColumns(Columns: TObjectList);\nvar\n  I: Integer;\nbegin\n  { Precache insert parameters. }\n  if InsertColumns.Count = 0 then\n  begin\n    for I := 1 to Metadata.GetColumnCount do\n    begin\n      if (Metadata.GetTableName(I) <> '') and (Metadata.GetColumnName(I) <> '')\n        and Metadata.IsWritable(I) then\n      begin\n        InsertColumns.Add(TZResolverParameter.Create(I,\n          Metadata.GetColumnName(I), Metadata.GetColumnType(I), True, ''));\n      end;\n    end;\n  end;\n  { Use cached insert parameters }\n  CopyResolveParameters(InsertColumns, Columns);\nend;\n\n{**\n  Gets a collection of data columns for UPDATE statements.\n  @param Columns a collection of columns.\n  @param OldRowAccessor an accessor object to old column values.\n  @param NewRowAccessor an accessor object to new column values.\n}\nprocedure TZGenericCachedResolver.DefineUpdateColumns(\n  Columns: TObjectList; OldRowAccessor, NewRowAccessor: TZRowAccessor);\nvar\n  I: Integer;\n  ColumnIndices: TIntegerDynArray;\n  ColumnDirs: TBooleanDynArray;\nbegin\n  { Use precached parameters. }\n  if UpdateAll and (UpdateColumns.Count > 0) then\n  begin\n    CopyResolveParameters(UpdateColumns, Columns);\n    Exit;\n  end;\n\n  { Defines parameters for UpdateAll mode. }\n  if UpdateAll then\n  begin\n    for I := 1 to Metadata.GetColumnCount do\n    begin\n      if (Metadata.GetTableName(I) <> '') and (Metadata.GetColumnName(I) <> '')\n        and Metadata.IsWritable(I) then\n      begin\n        UpdateColumns.Add(TZResolverParameter.Create(I,\n          Metadata.GetColumnName(I), Metadata.GetColumnType(I), True, ''));\n      end;\n    end;\n    CopyResolveParameters(UpdateColumns, Columns);\n  end\n  { Defines parameters for UpdateChanged mode. }\n  else\n  begin\n    SetLength(ColumnIndices, 1);\n    SetLength(ColumnDirs, 1);\n    ColumnDirs[0] := True;\n    for I := 1 to Metadata.GetColumnCount do\n    begin\n      ColumnIndices[0] := I;\n      if (Metadata.GetTableName(I) <> '') and (Metadata.GetColumnName(I) <> '')\n        and Metadata.IsWritable(I) and (OldRowAccessor.CompareBuffers(\n        OldRowAccessor.RowBuffer, NewRowAccessor.RowBuffer, ColumnIndices,\n        ColumnDirs) <> 0)then\n      begin\n        Columns.Add(TZResolverParameter.Create(I,\n          Metadata.GetColumnName(I), Metadata.GetColumnType(I), True, ''));\n      end;\n    end;\n  end;\nend;\n\n{**\n  Gets a collection of where key columns for DELETE or UPDATE DML statements.\n  @param Columns a collection of key columns.\n}\nprocedure TZGenericCachedResolver.DefineWhereKeyColumns(Columns: TObjectList);\nvar\n  I: Integer;\n  Found: Boolean;\n  ColumnName: string;\n  Catalog, Schema, Table: string;\n  PrimaryKeys: IZResultSet;\nbegin\n  { Use precached values. }\n  if WhereColumns.Count > 0 then\n  begin\n    CopyResolveParameters(WhereColumns, Columns);\n    Exit;\n  end;\n\n  { Defines catalog, schema and a table. }\n  Table := DefineTableName;\n  for I := 1 to Metadata.GetColumnCount do\n  begin\n    Table := Metadata.GetTableName(I);\n    if Table <> '' then\n    begin\n      Schema := Metadata.GetSchemaName(I);\n      Catalog := Metadata.GetCatalogName(I);\n      Break;\n    end;\n  end;\n\n  { Tryes to define primary keys. }\n  if not WhereAll then\n  begin\n    {For exact results: quote all identifiers SEE: http://sourceforge.net/p/zeoslib/tickets/81/\n    If table names have mixed case ConstructNameCondition will return wrong results\n    and we fall back to WhereAll}\n    PrimaryKeys := DatabaseMetadata.GetPrimaryKeys(IdentifierConvertor.Quote(Catalog),\n      IdentifierConvertor.Quote(Schema), IdentifierConvertor.Quote(Table));\n    while PrimaryKeys.Next do\n    begin\n      ColumnName := PrimaryKeys.GetString(4);\n      Found := False;\n      for I := 1 to Metadata.GetColumnCount do\n      begin\n        if (ColumnName = Metadata.GetColumnName(I))\n          and (Table = Metadata.GetTableName(I)) then\n        begin\n          Found := True;\n          Break;\n        end;\n      end;\n      if not Found then\n      begin\n        WhereColumns.Clear;\n        Break;\n      end;\n      WhereColumns.Add(TZResolverParameter.Create(I, ColumnName,\n        stUnknown, False, ''));\n    end;\n  end;\n\n  if WhereColumns.Count > 0 then\n    CopyResolveParameters(WhereColumns, Columns)\n  else\n    DefineWhereAllColumns(Columns);\nend;\n\n{**\n  Gets a collection of where all columns for DELETE or UPDATE DML statements.\n  @param Columns a collection of key columns.\n}\nprocedure TZGenericCachedResolver.DefineWhereAllColumns(Columns: TObjectList;\n  IgnoreKeyColumn: Boolean = False);\nvar\n  I: Integer;\nbegin\n  { Use precached values. }\n  if WhereColumns.Count > 0 then\n  begin\n    CopyResolveParameters(WhereColumns, Columns);\n    Exit;\n  end;\n\n  { Takes a a key all non-blob fields. }\n  for I := 1 to Metadata.GetColumnCount do\n  begin\n    if CheckKeyColumn(I) then\n      WhereColumns.Add(TZResolverParameter.Create(I,\n        Metadata.GetColumnName(I), Metadata.GetColumnType(I), False, ''))\n    else\n      if IgnoreKeyColumn then\n        WhereColumns.Add(TZResolverParameter.Create(I,\n          Metadata.GetColumnName(I), Metadata.GetColumnType(I), False, ''));\n  end;\n  if ( WhereColumns.Count = 0 ) and ( not IgnoreKeyColumn ) then\n    DefineWhereAllColumns(Columns, True)\n  else\n    { Copy defined parameters to target columns }\n    CopyResolveParameters(WhereColumns, Columns);\nend;\n\n{**\n  Checks is the specified column can be used in where clause.\n  @param ColumnIndex an index of the column.\n  @returns <code>true</code> if column can be included into where clause.\n}\nfunction TZGenericCachedResolver.CheckKeyColumn(ColumnIndex: Integer): Boolean;\nbegin\n  Result := (Metadata.GetTableName(ColumnIndex) <> '')\n    and (Metadata.GetColumnName(ColumnIndex) <> '')\n    and Metadata.IsSearchable(ColumnIndex)\n    and not (Metadata.GetColumnType(ColumnIndex)\n    in [stUnknown, stAsciiStream, stBinaryStream, stUnicodeStream]);\nend;\n\n{**\n  Gets a collection of data columns to initialize before INSERT statements.\n  @param Columns a collection of columns.\n  @param RowAccessor an accessor object to column values.\n}\nprocedure TZGenericCachedResolver.DefineCalcColumns(Columns: TObjectList;\n  RowAccessor: TZRowAccessor);\nvar\n  I: Integer;\nbegin\n  for I := 1 to Metadata.GetColumnCount do\n  begin\n    if RowAccessor.IsNull(I) and (Metadata.GetTableName(I) <> '')\n      and ((Metadata.GetDefaultValue(I) <> '') or (RowAccessor.GetColumnDefaultExpression(I) <> '')) then\n    begin\n      // DefaultExpression takes takes precedence on database default value\n      if RowAccessor.GetColumnDefaultExpression(I) <> '' then\n        Columns.Add(TZResolverParameter.Create(I,\n          Metadata.GetColumnName(I), Metadata.GetColumnType(I),\n          True, RowAccessor.GetColumnDefaultExpression(I)))\n      else\n        Columns.Add(TZResolverParameter.Create(I,\n          Metadata.GetColumnName(I), Metadata.GetColumnType(I),\n          True, Metadata.GetDefaultValue(I)));\n    end;\n  end;\nend;\n\n{**\n  Fills the specified statement with stored or given parameters.\n  @param ResultSet a source result set object.\n  @param Statement a DBC statement object.\n  @param Config an UpdateStatement configuration.\n  @param OldRowAccessor an accessor object to old column values.\n  @param NewRowAccessor an accessor object to new column values.\n}\nprocedure TZGenericCachedResolver.FillStatement(Statement: IZPreparedStatement;\n  Params: TObjectList; OldRowAccessor, NewRowAccessor: TZRowAccessor);\nvar\n  I: Integer;\n  ColumnIndex: Integer;\n  Current: TZResolverParameter;\n  RowAccessor: TZRowAccessor;\n  WasNull: Boolean;\nbegin\n  WasNull := False;\n  for I := 0 to Params.Count - 1 do\n  begin\n    Current := TZResolverParameter(Params[I]);\n    if Current.NewValue then\n      RowAccessor := NewRowAccessor\n    else\n      RowAccessor := OldRowAccessor;\n    ColumnIndex := Current.ColumnIndex;\n\n    if FCalcDefaults then\n      Statement.SetDefaultValue(I + 1, Metadata.GetDefaultValue(ColumnIndex));\n\n    case Metadata.GetColumnType(ColumnIndex) of\n      stBoolean:\n        Statement.SetBoolean(I + 1,\n          RowAccessor.GetBoolean(ColumnIndex, WasNull));\n      stByte:\n        Statement.SetByte(I + 1, RowAccessor.GetByte(ColumnIndex, WasNull));\n      stShort:\n        Statement.SetShort(I + 1, RowAccessor.GetShort(ColumnIndex, WasNull));\n      stInteger:\n        Statement.SetInt(I + 1, RowAccessor.GetInt(ColumnIndex, WasNull));\n      stLong:\n        Statement.SetLong(I + 1, RowAccessor.GetLong(ColumnIndex, WasNull));\n      stFloat:\n        Statement.SetFloat(I + 1, RowAccessor.GetFloat(ColumnIndex, WasNull));\n      stDouble:\n        Statement.SetDouble(I + 1, RowAccessor.GetDouble(ColumnIndex, WasNull));\n      stBigDecimal:\n        Statement.SetBigDecimal(I + 1,\n          RowAccessor.GetBigDecimal(ColumnIndex, WasNull));\n      stString:\n        Statement.SetString(I + 1, RowAccessor.GetString(ColumnIndex, WasNull));\n      stUnicodeString:\n        Statement.SetUnicodeString(I + 1,\n          RowAccessor.GetUnicodeString(ColumnIndex, WasNull));\n      stBytes, stGUID:\n        Statement.SetBytes(I + 1, RowAccessor.GetBytes(ColumnIndex, WasNull));\n      stDate:\n        Statement.SetDate(I + 1, RowAccessor.GetDate(ColumnIndex, WasNull));\n      stTime:\n        Statement.SetTime(I + 1, RowAccessor.GetTime(ColumnIndex, WasNull));\n      stTimestamp:\n        Statement.SetTimestamp(I + 1,\n          RowAccessor.GetTimestamp(ColumnIndex, WasNull));\n      stAsciiStream:\n         Statement.SetBlob(I + 1, stAsciiStream,\n           RowAccessor.GetBlob(ColumnIndex, WasNull));\n      stUnicodeStream:\n         Statement.SetBlob(I + 1, stUnicodeStream,\n           RowAccessor.GetBlob(ColumnIndex, WasNull));\n      stBinaryStream:\n         Statement.SetBlob(I + 1, stBinaryStream,\n           RowAccessor.GetBlob(ColumnIndex, WasNull));\n    end;\n    if WasNull then\n      Statement.SetNull(I + 1, Metadata.GetColumnType(ColumnIndex))\n  end;\nend;\n\n{**\n  Forms a where clause for UPDATE or DELETE DML statements.\n  @param Columns a collection of key columns.\n  @param OldRowAccessor an accessor object to old column values.\n}\nfunction TZGenericCachedResolver.FormWhereClause(Columns: TObjectList;\n  OldRowAccessor: TZRowAccessor): string;\nvar\n  I, N: Integer;\n  Current: TZResolverParameter;\nbegin\n  Result := '';\n  N := Columns.Count - WhereColumns.Count;\n\n  for I := 0 to WhereColumns.Count - 1 do\n  begin\n    Current := TZResolverParameter(WhereColumns[I]);\n    if Result <> '' then\n      Result := Result + ' AND ';\n\n    Result := Result + IdentifierConvertor.Quote(Current.ColumnName);\n    if OldRowAccessor.IsNull(Current.ColumnIndex) then\n    begin\n      Result := Result + ' IS NULL ';\n      Columns.Delete(N);\n    end\n    else\n    begin\n      Result := Result + '=?';\n      Inc(N);\n    end;\n  end;\n\n  if Result <> '' then\n    Result := ' WHERE ' + Result;\nend;\n\n{**\n  Forms a where clause for INSERT statements.\n  @param Columns a collection of key columns.\n  @param NewRowAccessor an accessor object to new column values.\n}\nfunction TZGenericCachedResolver.FormInsertStatement(Columns: TObjectList;\n  NewRowAccessor: TZRowAccessor): string;\nvar\n  I: Integer;\n  Current: TZResolverParameter;\n  TableName: string;\n  Temp1, Temp2: string;\n  l1: Integer; \n\n  procedure Append(const app: String); \n  begin \n    if Length(Temp1) < l1 + length(app) then \n      SetLength(Temp1, 2 * (length(app) + l1)); \n    Move(app[1], Temp1[l1+1], length(app)*SizeOf(Char)); \n    Inc(l1, length(app)); \n  end; \n\nbegin\n  TableName := DefineTableName;\n  DefineInsertColumns(Columns);\n  if Columns.Count = 0 then\n  begin\n    Result := '';\n    Exit;\n  end;\n\n  Temp1 := '';    l1 := 0; \n  SetLength(Temp2, 2 * Columns.Count - 1); \n  for I := 0 to Columns.Count - 1 do \n  begin \n    Current := TZResolverParameter(Columns[I]); \n    if Temp1 <> '' then \n      Append(','); \n    Append(IdentifierConvertor.Quote(Current.ColumnName)); \n    if I > 0 then \n      Temp2[I*2] := ','; \n    Temp2[I*2+1] := '?'; \n  end; \n  SetLength(Temp1, l1); \n  Result := Format('INSERT INTO %s (%s) VALUES (%s)', [TableName, Temp1, Temp2]);\nend;\n\n{**\n  Forms a where clause for UPDATE statements.\n  @param Columns a collection of key columns.\n  @param OldRowAccessor an accessor object to old column values.\n  @param NewRowAccessor an accessor object to new column values.\n}\nfunction TZGenericCachedResolver.FormUpdateStatement(Columns: TObjectList;\n  OldRowAccessor, NewRowAccessor: TZRowAccessor): string;\nvar\n  I: Integer;\n  Current: TZResolverParameter;\n  TableName: string;\n  Temp: string;\nbegin\n  TableName := DefineTableName;\n  DefineUpdateColumns(Columns, OldRowAccessor, NewRowAccessor);\n  if Columns.Count = 0 then\n  begin\n    Result := '';\n    Exit;\n  end;\n\n  Temp := '';\n  for I := 0 to Columns.Count - 1 do\n  begin\n    Current := TZResolverParameter(Columns[I]);\n    if Temp <> '' then\n      Temp := Temp + ',';\n    Temp := Temp + IdentifierConvertor.Quote(Current.ColumnName) + '=?';\n  end;\n\n  Result := Format('UPDATE %s SET %s', [TableName, Temp]);\n  DefineWhereKeyColumns(Columns);\n  Result := Result + FormWhereClause(Columns, OldRowAccessor);\nend;\n\n{**\n  Forms a where clause for DELETE statements.\n  @param Columns a collection of key columns.\n  @param OldRowAccessor an accessor object to old column values.\n}\nfunction TZGenericCachedResolver.FormDeleteStatement(Columns: TObjectList;\n  OldRowAccessor: TZRowAccessor): string;\nvar\n  TableName: string;\nbegin\n  TableName := DefineTableName;\n  Result := Format('DELETE FROM %s', [TableName]);\n  DefineWhereKeyColumns(Columns);\n  Result := Result + FormWhereClause(Columns, OldRowAccessor);\nend;\n\n{**\n  Forms a where clause for SELECT statements to calculate default values.\n  @param Columns a collection of key columns.\n  @param OldRowAccessor an accessor object to old column values.\n}\nfunction TZGenericCachedResolver.FormCalculateStatement(\n  Columns: TObjectList): string;\nvar\n  I: Integer;\n  Current: TZResolverParameter;\nbegin\n  Result := '';\n  if Columns.Count = 0 then\n     Exit;\n\n  for I := 0 to Columns.Count - 1 do\n  begin\n    Current := TZResolverParameter(Columns[I]);\n    if Result <> '' then\n      Result := Result + ',';\n    if Current.DefaultValue <> '' then\n      Result := Result + Current.DefaultValue\n    else\n      Result := Result + 'NULL';\n  end;\n  Result := 'SELECT ' + Result;\nend;\n\n{**\n  Posts updates to database.\n  @param Sender a cached result set object.\n  @param UpdateType a type of updates.\n  @param OldRowAccessor an accessor object to old column values.\n  @param NewRowAccessor an accessor object to new column values.\n}\nprocedure TZGenericCachedResolver.PostUpdates(Sender: IZCachedResultSet;\n  UpdateType: TZRowUpdateType; OldRowAccessor, NewRowAccessor: TZRowAccessor);\nvar\n  Statement            : IZPreparedStatement;\n  SQL                  : string;\n  SQLParams            : TObjectList;\n  lUpdateCount         : Integer;\n  lValidateUpdateCount : Boolean;\n\nbegin\n  if (UpdateType = utDeleted)\n    and (OldRowAccessor.RowBuffer.UpdateType = utInserted) then\n    Exit;\n\n  SQLParams := TObjectList.Create(True);\n  try\n    case UpdateType of\n      utInserted:\n          begin\n        SQL := FormInsertStatement(SQLParams, NewRowAccessor);\n            If Assigned(InsertStatement) and (SQL <> InsertStatement.GetSQL) then\n              InsertStatement := nil;\n            If not Assigned(InsertStatement) then\n              InsertStatement := CreateResolverStatement(SQL);\n            Statement := InsertStatement;\n          end;\n      utDeleted:\n          begin\n        SQL := FormDeleteStatement(SQLParams, OldRowAccessor);\n            If Assigned(DeleteStatement) and (SQL <> DeleteStatement.GetSQL) then\n              DeleteStatement := nil;\n            If not Assigned(DeleteStatement) then\n              DeleteStatement := CreateResolverStatement(SQL);\n            Statement := DeleteStatement;\n          end;\n      utModified:\n          begin\n        SQL := FormUpdateStatement(SQLParams, OldRowAccessor, NewRowAccessor);\n            If SQL =''then // no fields have been changed\n               exit;\n            If Assigned(UpdateStatement) and (SQL <> UpdateStatement.GetSQL) then\n              UpdateStatement := nil;\n            If not Assigned(UpdateStatement) then\n              UpdateStatement := CreateResolverStatement(SQL);\n            Statement := UpdateStatement;\n          end;\n      else\n        Exit;\n    end;\n\n    if SQL <> '' then\n    begin\n\n      FillStatement(Statement, SQLParams, OldRowAccessor, NewRowAccessor);\n      // if Property ValidateUpdateCount isn't set : assume it's true\n      lValidateUpdateCount := (Sender.GetStatement.GetParameters.IndexOfName('ValidateUpdateCount') = -1)\n                            or StrToBoolEx(Sender.GetStatement.GetParameters.Values['ValidateUpdateCount']);\n\n      lUpdateCount := Statement.ExecuteUpdatePrepared;\n      {$IFDEF WITH_VALIDATE_UPDATE_COUNT}\n      if  (lValidateUpdateCount) and (lUpdateCount <> 1   ) then\n        raise EZSQLException.Create(Format(SInvalidUpdateCount, [lUpdateCount]));\n      {$ENDIF}\n    end;\n  finally\n    FreeAndNil(SQLParams);\n  end;\nend;\n\nprocedure TZGenericCachedResolver.RefreshCurrentRow(Sender: IZCachedResultSet;  RowAccessor: TZRowAccessor);\nbegin\n raise EZSQLException.Create(SRefreshRowOnlySupportedWithUpdateObject);\nend;\n\n{**\n  Calculate default values for the fields.\n  @param Sender a cached result set object.\n  @param RowAccessor an accessor object to column values.\n}\nprocedure TZGenericCachedResolver.CalculateDefaults(\n  Sender: IZCachedResultSet; RowAccessor: TZRowAccessor);\nvar\n  I: Integer;\n  SQL: string;\n  SQLParams: TObjectList;\n  Statement: IZStatement;\n  ResultSet: IZResultSet;\n  Metadata: IZResultSetMetadata;\n  Current: TZResolverParameter;\nbegin\n  if not FCalcDefaults then\n     Exit;\n\n  SQLParams := TObjectList.Create(True);\n  try\n    DefineCalcColumns(SQLParams, RowAccessor);\n    SQL := FormCalculateStatement(SQLParams);\n    if SQL = '' then\n       Exit;\n\n    { Executes statement and fills default fields. }\n    Statement := Connection.CreateStatement;\n    try\n      ResultSet := Statement.ExecuteQuery(SQL);\n      if ResultSet.Next then\n      begin\n        Metadata := ResultSet.GetMetadata;\n        for I := 1 to Metadata.GetColumnCount do\n        begin\n          Current := TZResolverParameter(SQLParams[I - 1]);\n          try\n            case Current.ColumnType of\n              stBoolean:\n                RowAccessor.SetBoolean(Current.ColumnIndex,\n                  ResultSet.GetBoolean(I));\n              stByte:\n                RowAccessor.SetByte(Current.ColumnIndex, ResultSet.GetByte(I));\n              stShort:\n                RowAccessor.SetShort(Current.ColumnIndex, ResultSet.GetShort(I));\n              stInteger:\n                RowAccessor.SetInt(Current.ColumnIndex, ResultSet.GetInt(I));\n              stLong:\n                RowAccessor.SetLong(Current.ColumnIndex, ResultSet.GetLong(I));\n              stFloat:\n                RowAccessor.SetFloat(Current.ColumnIndex, ResultSet.GetFloat(I));\n              stDouble:\n                RowAccessor.SetDouble(Current.ColumnIndex, ResultSet.GetDouble(I));\n              stBigDecimal:\n                RowAccessor.SetBigDecimal(Current.ColumnIndex, ResultSet.GetBigDecimal(I));\n              stString, stAsciiStream:\n                RowAccessor.SetString(Current.ColumnIndex, ResultSet.GetString(I));\n              stUnicodeString, stUnicodeStream:\n                RowAccessor.SetUnicodeString(Current.ColumnIndex, ResultSet.GetUnicodeString(I));\n              stBytes, stGUID:\n                RowAccessor.SetBytes(Current.ColumnIndex, ResultSet.GetBytes(I));\n              stDate:\n                RowAccessor.SetDate(Current.ColumnIndex, ResultSet.GetDate(I));\n              stTime:\n                RowAccessor.SetTime(Current.ColumnIndex, ResultSet.GetTime(I));\n              stTimestamp:\n                RowAccessor.SetTimestamp(Current.ColumnIndex,\n                  ResultSet.GetTimestamp(I));\n            end;\n\n            if ResultSet.WasNull then\n              RowAccessor.SetNull(Current.ColumnIndex);\n          except\n            { Supress any errors in default fields. }\n          end;\n        end;\n      end;\n      ResultSet.Close;\n    finally\n      Statement.Close;\n    end;\n  finally\n    FreeAndNil(SQLParams);\n  end;\nend;\n\n{BEGIN of PATCH [1185969]: Do tasks after posting updates. ie: Updating AutoInc fields in MySQL }\nprocedure TZGenericCachedResolver.UpdateAutoIncrementFields(\n  Sender: IZCachedResultSet; UpdateType: TZRowUpdateType; OldRowAccessor,\n  NewRowAccessor: TZRowAccessor; Resolver: IZCachedResolver);\nbegin\n //Should be implemented at Specific database Level Cached resolver\nend;\n{END of PATCH [1185969]: Do tasks after posting updates. ie: Updating AutoInc fields in MySQL }\n\nend.\n\n"
  },
  {
    "path": "lib/zeosdbo/src/dbc/ZDbcInterbase6.pas",
    "content": "{*********************************************************}\n{                                                         }\n{                 Zeos Database Objects                   }\n{         Interbase Database Connectivity Classes         }\n{                                                         }\n{        Originally written by Sergey Merkuriev           }\n{                                                         }\n{*********************************************************}\n\n{@********************************************************}\n{    Copyright (c) 1999-2012 Zeos Development Group       }\n{                                                         }\n{ License Agreement:                                      }\n{                                                         }\n{ This library is distributed in the hope that it will be }\n{ useful, but WITHOUT ANY WARRANTY; without even the      }\n{ implied warranty of MERCHANTABILITY or FITNESS FOR      }\n{ A PARTICULAR PURPOSE.  See the GNU Lesser General       }\n{ Public License for more details.                        }\n{                                                         }\n{ The source code of the ZEOS Libraries and packages are  }\n{ distributed under the Library GNU General Public        }\n{ License (see the file COPYING / COPYING.ZEOS)           }\n{ with the following  modification:                       }\n{ As a special exception, the copyright holders of this   }\n{ library give you permission to link this library with   }\n{ independent modules to produce an executable,           }\n{ regardless of the license terms of these independent    }\n{ modules, and to copy and distribute the resulting       }\n{ executable under terms of your choice, provided that    }\n{ you also meet, for each linked independent module,      }\n{ the terms and conditions of the license of that module. }\n{ An independent module is a module which is not derived  }\n{ from or based on this library. If you modify this       }\n{ library, you may extend this exception to your version  }\n{ of the library, but you are not obligated to do so.     }\n{ If you do not wish to do so, delete this exception      }\n{ statement from your version.                            }\n{                                                         }\n{                                                         }\n{ The project web site is located on:                     }\n{   http://zeos.firmos.at  (FORUM)                        }\n{   http://sourceforge.net/p/zeoslib/tickets/ (BUGTRACKER)}\n{   svn://svn.code.sf.net/p/zeoslib/code-0/trunk (SVN)    }\n{                                                         }\n{   http://www.sourceforge.net/projects/zeoslib.          }\n{                                                         }\n{                                                         }\n{                                 Zeos Development Group. }\n{********************************************************@}\n\nunit ZDbcInterbase6;\n\ninterface\n\n{$I ZDbc.inc}\n\nuses\n  Types, Classes, {$IFDEF MSEgui}mclasses,{$ENDIF} SysUtils, Contnrs,\n  ZPlainFirebirdDriver, ZPlainDriver, ZCompatibility, ZDbcUtils, ZDbcIntfs,\n  ZDbcConnection, ZPlainFirebirdInterbaseConstants, ZSysUtils, ZDbcLogging,\n  ZDbcInterbase6Utils, ZDbcGenericResolver, ZTokenizer, ZGenericSqlAnalyser,\n  ZURL;\n\ntype\n\n  {** Implements Interbase6 Database Driver. }\n  {$WARNINGS OFF}\n  TZInterbase6Driver = class(TZAbstractDriver)\n  public\n    constructor Create; override;\n    function Connect(const Url: TZURL): IZConnection; override;\n    function GetMajorVersion: Integer; override;\n    function GetMinorVersion: Integer; override;\n\n    function GetTokenizer: IZTokenizer; override;\n    function GetStatementAnalyser: IZStatementAnalyser; override;\n  end;\n  {$WARNINGS ON}\n\n  {** Represents a Interbase specific connection interface. }\n  IZInterbase6Connection = interface (IZConnection)\n    ['{E870E4FE-21EB-4725-B5D8-38B8A2B12D0B}']\n    function GetDBHandle: PISC_DB_HANDLE;\n    function GetTrHandle: PISC_TR_HANDLE;\n    function GetDialect: Word;\n    function GetPlainDriver: IZInterbasePlainDriver;\n    procedure CreateNewDatabase(const SQL: String);\n  end;\n\n  {** Implements Interbase6 Database Connection. }\n\n  { TZInterbase6Connection }\n\n  TZInterbase6Connection = class(TZAbstractConnection, IZInterbase6Connection)\n  private\n    FDialect: Word;\n    FHandle: TISC_DB_HANDLE;\n    FTrHandle: TISC_TR_HANDLE;\n    FStatusVector: TARRAY_ISC_STATUS;\n    FHardCommit: boolean;\n    FDisposeClientCodePage: Boolean;\n  private\n    procedure StartTransaction; virtual;\n  protected\n    procedure InternalCreate; override;\n  public\n    destructor Destroy; override;\n\n    function GetDBHandle: PISC_DB_HANDLE;\n    function GetTrHandle: PISC_TR_HANDLE;\n    function GetDialect: Word;\n    function GetPlainDriver: IZInterbasePlainDriver;\n    procedure CreateNewDatabase(const SQL: String);\n\n    function CreateRegularStatement(Info: TStrings): IZStatement; override;\n    function CreatePreparedStatement(const SQL: string; Info: TStrings):\n      IZPreparedStatement; override;\n    function CreateCallableStatement(const SQL: string; Info: TStrings):\n      IZCallableStatement; override;\n\n    function CreateSequence(const Sequence: string; BlockSize: Integer):\n      IZSequence; override;\n\n    procedure Commit; override;\n    procedure Rollback; override;\n\n    function PingServer: Integer; override;\n\n    procedure Open; override;\n    procedure Close; override;\n\n    function GetBinaryEscapeString(const Value: RawByteString): String; override;\n    function GetBinaryEscapeString(const Value: TByteDynArray): String; override;\n    function GetEscapeString(const Value: RawByteString): RawByteString; override;\n    function GetEscapeString(const Value: ZWideString): ZWideString; override;\n  end;\n\n  {** Implements a specialized cached resolver for Interbase/Firebird. }\n  TZInterbase6CachedResolver = class(TZGenericCachedResolver)\n  public\n    function FormCalculateStatement(Columns: TObjectList): string; override;\n  end;\n\n  {** Implements a Interbase 6 sequence. }\n  TZInterbase6Sequence = class(TZAbstractSequence)\n  public\n    function GetCurrentValue: Int64; override;\n    function GetNextValue: Int64; override;\n    function GetCurrentValueSQL: string; override;\n    function GetNextValueSQL: string; override;\n  end;\n\n\nvar\n  {** The common driver manager object. }\n  Interbase6Driver: IZDriver;\n\nimplementation\n\nuses ZDbcInterbase6Statement, ZDbcInterbase6Metadata, ZEncoding,\n  ZInterbaseToken, ZInterbaseAnalyser\n  {$IFDEF WITH_UNITANSISTRINGS}, AnsiStrings{$ENDIF};\n\n{ TZInterbase6Driver }\n\n{**\n  Attempts to make a database connection to the given URL.\n  The driver should return \"null\" if it realizes it is the wrong kind\n  of driver to connect to the given URL.  This will be common, as when\n  the JDBC driver manager is asked to connect to a given URL it passes\n  the URL to each loaded driver in turn.\n\n  <P>The driver should raise a SQLException if it is the right\n  driver to connect to the given URL, but has trouble connecting to\n  the database.\n\n  <P>The java.util.Properties argument can be used to passed arbitrary\n  string tag/value pairs as connection arguments.\n  Normally at least \"user\" and \"password\" properties should be\n  included in the Properties.\n\n  @param url the URL of the database to which to connect\n  @param info a list of arbitrary string tag/value pairs as\n    connection arguments. Normally at least a \"user\" and\n    \"password\" property should be included.\n  @return a <code>Connection</code> object that represents a\n    connection to the URL\n}\n{$WARNINGS OFF}\nfunction TZInterbase6Driver.Connect(const Url: TZURL): IZConnection;\nbegin\n  Result := TZInterbase6Connection.Create(Url);\nend;\n{$WARNINGS ON}\n\n{**\n  Constructs this object with default properties.\n}\nconstructor TZInterbase6Driver.Create;\nbegin\n  inherited Create;\n  AddSupportedProtocol(AddPlainDriverToCache(TZInterbase6PlainDriver.Create));\n  AddSupportedProtocol(AddPlainDriverToCache(TZFirebird10PlainDriver.Create));\n  AddSupportedProtocol(AddPlainDriverToCache(TZFirebird15PlainDriver.Create));\n  AddSupportedProtocol(AddPlainDriverToCache(TZFirebird20PlainDriver.Create));\n  AddSupportedProtocol(AddPlainDriverToCache(TZFirebird21PlainDriver.Create));\n  AddSupportedProtocol(AddPlainDriverToCache(TZFirebird25PlainDriver.Create));\n  // embedded drivers\n  AddSupportedProtocol(AddPlainDriverToCache(TZFirebirdD15PlainDriver.Create));\n  AddSupportedProtocol(AddPlainDriverToCache(TZFirebirdD20PlainDriver.Create));\n  AddSupportedProtocol(AddPlainDriverToCache(TZFirebirdD21PlainDriver.Create));\n  AddSupportedProtocol(AddPlainDriverToCache(TZFirebirdD25PlainDriver.Create));\nend;\n\n{**\n  Gets the driver's major version number. Initially this should be 1.\n  @return this driver's major version number\n}\nfunction TZInterbase6Driver.GetMajorVersion: Integer;\nbegin\n Result := 1;\nend;\n\n{**\n  Gets the driver's minor version number. Initially this should be 0.\n  @return this driver's minor version number\n}\nfunction TZInterbase6Driver.GetMinorVersion: Integer;\nbegin\n  Result := 0;\nend;\n\n{**\n  Gets a SQL syntax tokenizer.\n  @returns a SQL syntax tokenizer object.\n}\nfunction TZInterbase6Driver.GetTokenizer: IZTokenizer;\nbegin\n  if Tokenizer = nil then\n    Tokenizer := TZInterbaseTokenizer.Create;\n  Result := Tokenizer;\nend;\n\n{**\n  Creates a statement analyser object.\n  @returns a statement analyser object.\n}\nfunction TZInterbase6Driver.GetStatementAnalyser: IZStatementAnalyser;\nbegin\n  if Analyser = nil then\n    Analyser := TZInterbaseStatementAnalyser.Create;\n  Result := Analyser;\nend;\n\n{ TZInterbase6Connection }\n\n{**\n  Releases a Connection's database and JDBC resources\n  immediately instead of waiting for\n  them to be automatically released.\n\n  <P><B>Note:</B> A Connection is automatically closed when it is\n  garbage collected. Certain fatal errors also result in a closed\n  Connection.\n}\nprocedure TZInterbase6Connection.Close;\nbegin\n  if Closed or (not Assigned(PlainDriver)) then\n     Exit;\n\n  if FTrHandle <> 0 then\n  begin\n    if AutoCommit then\n    begin\n      GetPlainDriver.isc_commit_transaction(@FStatusVector, @FTrHandle);\n      DriverManager.LogMessage(lcTransaction, PlainDriver.GetProtocol,\n        Format('COMMIT TRANSACTION \"%s\"', [Database]));\n    end\n    else\n    begin\n      GetPlainDriver.isc_rollback_transaction(@FStatusVector, @FTrHandle);\n      DriverManager.LogMessage(lcTransaction, PlainDriver.GetProtocol,\n        Format('ROLLBACK TRANSACTION \"%s\"', [Database]));\n    end;\n    FTrHandle := 0;\n    CheckInterbase6Error(GetPlainDriver, FStatusVector, lcDisconnect);\n  end;\n\n  if FHandle <> 0 then\n  begin\n    GetPlainDriver.isc_detach_database(@FStatusVector, @FHandle);\n    FHandle := 0;\n    CheckInterbase6Error(GetPlainDriver, FStatusVector, lcDisconnect);\n  end;\n\n  DriverManager.LogMessage(lcConnect, PlainDriver.GetProtocol,\n      Format('DISCONNECT FROM \"%s\"', [Database]));\n\n  inherited Close;\nend;\n\n{**\n   Commit current transaction\n}\nprocedure TZInterbase6Connection.Commit;\nbegin\n  if Closed then\n     Exit;\n\n  if FTrHandle <> 0 then\n  begin\n    if FHardCommit then\n    begin\n      GetPlainDriver.isc_commit_transaction(@FStatusVector, @FTrHandle);\n      FTrHandle := 0;\n    end\n    else\n      GetPlainDriver.isc_commit_retaining(@FStatusVector, @FTrHandle);\n\n    CheckInterbase6Error(GetPlainDriver, FStatusVector, lcTransaction);\n    DriverManager.LogMessage(lcTransaction,\n      PlainDriver.GetProtocol, 'TRANSACTION COMMIT');\n  end;\nend;\n\n{**\n  Constructs this object and assignes the main properties.\n}\nprocedure TZInterbase6Connection.InternalCreate;\nvar\n  RoleName: string;\n  UserSetDialect: string;\n  ConnectTimeout : integer;\nbegin\n  FDisposeClientCodePage := False;\n  Self.FMetadata := TZInterbase6DatabaseMetadata.Create(Self, Url);\n\n  FHardCommit := StrToBoolEx(URL.Properties.Values['hard_commit']);\n  { Sets a default Interbase port }\n\n  if Self.Port = 0 then\n    Self.Port := 3050;\n\n  { set default sql dialect it can be overriden }\n  FDialect := 3;\n\n  UserSetDialect := Trim(URL.Properties.Values['dialect']);\n  if UserSetDialect <> '' then\n    FDialect := StrToIntDef(UserSetDialect, FDialect);\n\n  { Processes connection properties. }\n  self.Info.Values['isc_dpb_username'] := Url.UserName;\n  self.Info.Values['isc_dpb_password'] := Url.Password;\n\n  if FClientCodePage = '' then //was set on inherited Create(...)\n    if URL.Properties.Values['isc_dpb_lc_ctype'] <> '' then //Check if Dev set's it manually\n    begin\n      FClientCodePage := URL.Properties.Values['isc_dpb_lc_ctype'];\n      CheckCharEncoding(FClientCodePage, True);\n    end;\n  URL.Properties.Values['isc_dpb_lc_ctype'] := FClientCodePage;\n\n  RoleName := Trim(URL.Properties.Values['rolename']);\n  if RoleName <> '' then\n    URL.Properties.Values['isc_dpb_sql_role_name'] := UpperCase(RoleName);\n\n  ConnectTimeout := StrToIntDef(URL.Properties.Values['timeout'], -1);\n  if ConnectTimeout >= 0 then\n    URL.Properties.Values['isc_dpb_connect_timeout'] := IntToStr(ConnectTimeout);\n\nend;\n\n{**\n  Creates a <code>Statement</code> object for sending\n  SQL statements to the database.\n  SQL statements without parameters are normally\n  executed using Statement objects. If the same SQL statement\n  is executed many times, it is more efficient to use a\n  <code>PreparedStatement</code> object.\n  <P>\n  Result sets created using the returned <code>Statement</code>\n  object will by default have forward-only type and read-only concurrency.\n\n  @param Info a statement parameters.\n  @return a new Statement object\n}\nfunction TZInterbase6Connection.CreateRegularStatement(Info: TStrings):\n  IZStatement;\nbegin\n  if IsClosed then\n     Open;\n  Result := TZInterbase6Statement.Create(Self, Info);\nend;\n\n{**\n  Destroys this object and cleanups the memory.\n}\ndestructor TZInterbase6Connection.Destroy;\nbegin\n  if not Closed then\n    Close;\n  if FDisposeClientCodePage then Dispose(ConSettings^.ClientCodePage); //FreeMem for own created ClientCodePage rec\n  inherited Destroy;\nend;\n\n{**\n   Get database connection handle.\n   @return database handle\n}\nfunction TZInterbase6Connection.GetDBHandle: PISC_DB_HANDLE;\nbegin\n  Result := @FHandle;\nend;\n\n{**\n   Return Interbase dialect number. Dialect a dialect Interbase SQL\n   must be 1 or 2 or 3.\n   @return dialect number\n}\nfunction TZInterbase6Connection.GetDialect: Word;\nbegin\n  Result := FDialect;\nend;\n\n{**\n   Return native interbase plain driver\n   @return plain driver\n}\nfunction TZInterbase6Connection.GetPlainDriver: IZInterbasePlainDriver;\nbegin\n  Result := PlainDriver as IZInterbasePlainDriver;\nend;\n\n{**\n   Get Interbase transaction handle\n   @return transaction handle\n}\nfunction TZInterbase6Connection.GetTrHandle: PISC_TR_HANDLE;\nbegin\n  if (FHardCommit and (FTrHandle = 0)) then\n    StartTransaction;\n  Result := @FTrHandle;\nend;\n\n{**\n  Opens a connection to database server with specified parameters.\n}\nprocedure TZInterbase6Connection.Open;\nconst sCS_NONE = 'NONE';\nvar\n  DPB: PAnsiChar;\n  FDPBLength: Word;\n  DBName: array[0..512] of AnsiChar;\n  TmpClientCodePageOld, TmpClientCodePageNew: PZCodePage;\nbegin\n  if not Closed then\n     Exit;\n\n  if TransactIsolationLevel = tiReadUncommitted then\n    raise EZSQLException.Create('Isolation level do not capable');\n  if ConSettings^.ClientCodePage = nil then\n    CheckCharEncoding(FClientCodePage, True);\n\n  DPB := GenerateDPB(Info, FDPBLength, FDialect);\n\n  if HostName <> '' then\n  begin\n    if Port <> 3050 then\n      {$IFDEF WITH_STRPCOPY_DEPRECATED}AnsiStrings.{$ENDIF}StrPCopy(DBName, ZPlainString(HostName + '/' + IntToStr(Port) + ':' + Database))\n    else\n      {$IFDEF WITH_STRPCOPY_DEPRECATED}AnsiStrings.{$ENDIF}StrPCopy(DBName, ZPlainString(HostName + ':' + Database))\n  end\n  else\n    {$IFDEF WITH_STRPCOPY_DEPRECATED}AnsiStrings.{$ENDIF}StrPCopy(DBName, ZPlainString(Database));\n\n  try\n    { Create new db if needed }\n    if Info.Values['createNewDatabase'] <> '' then\n    begin\n      CreateNewDatabase(Info.Values['createNewDatabase']);\n      { Logging connection action }\n      DriverManager.LogMessage(lcConnect, PlainDriver.GetProtocol,\n        Format('CREATE DATABASE \"%s\" AS USER \"%s\"', [Info.Values['createNewDatabase'], User]));\n      URL.Properties.Values['createNewDatabase'] := '';\n      //Allready Connected now if successfully created\n    end\n    else\n    begin\n      FHandle := 0;\n      { Connect to Interbase6 database. }\n      GetPlainDriver.isc_attach_database(@FStatusVector,\n        {$IFDEF WITH_STRLEN_DEPRECATED}AnsiStrings.{$ENDIF}StrLen(DBName), DBName,\n          @FHandle, FDPBLength, DPB);\n\n      { Check connection error }\n      CheckInterbase6Error(GetPlainDriver, FStatusVector, lcConnect);\n    end;\n\n    { Logging connection action }\n    DriverManager.LogMessage(lcConnect, PlainDriver.GetProtocol,\n      Format('CONNECT TO \"%s\" AS USER \"%s\"', [Database, User]));\n\n    { Start transaction }\n    if not FHardCommit then\n      StartTransaction;\n\n    inherited Open;\n\n    {Check for ClientCodePage: if empty switch to database-defaults\n      and/or check for charset 'NONE' which has a different byte-width\n      and no conversations where done except the collumns using collations}\n    with GetMetadata.GetCollationAndCharSet('', '', '', '') do\n    begin\n      if Next then\n        if FCLientCodePage = '' then\n        begin\n          FCLientCodePage := GetString(6);\n          CheckCharEncoding(FClientCodePage);\n        end\n        else\n          if GetString(6) = sCS_NONE then\n            if not ( FClientCodePage = sCS_NONE ) then\n            begin\n              URL.Properties.Values['isc_dpb_lc_ctype'] := sCS_NONE;\n              FClientCodePage := sCS_NONE;\n              {save the user wanted CodePage-Informations}\n              TmpClientCodePageOld := ConSettings.ClientCodePage;\n              { charset 'NONE' can't converty anything and write 'Data as is'!\n                If another charset was set on attaching the Server then all\n                column collations are retrieved with newly choosen collation.\n                BUT NO string convertations where done! So we need a\n                reopen (since we can set the Client-CharacterSet only on\n                connecting) to determine charset 'NONE' corectly. Then the column\n                collations have there proper CharsetID's to encode all strings\n                correctly. }\n              Self.Close;\n              Self.Open;\n              { Create a new PZCodePage for the new environment-variables }\n              TmpClientCodePageNew := New(PZCodePage);\n              TmpClientCodePageNew.Name := sCS_NONE;\n              TmpClientCodePageNew.ID := CS_NONE;\n              TmpClientCodePageNew.CharWidth := 1;\n              TmpClientCodePageNew.Encoding := TmpClientCodePageOld.Encoding;\n              TmpClientCodePageNew.CP := TmpClientCodePageOld.CP;\n              TmpClientCodePageNew.ZAlias := '';\n              TmpClientCodePageNew.IsStringFieldCPConsistent := False;\n              ConSettings.ClientCodePage := TmpClientCodePageNew;\n              SetConvertFunctions(ConSettings); //now let's the converters again\n              FDisposeClientCodePage := True;\n              {Also reset the MetaData ConSettings}\n              (FMetadata as TZInterbase6DatabaseMetadata).ConSettings := ConSettings;\n              { now we're able to read and write strings for columns without a\n                spezial declared collation for charset 'NONE' with the user\n                choosen CodePage and Encoding }\n            end;\n      Close;\n    end;\n    if FClientCodePage = sCS_NONE then\n      ConSettings.AutoEncode := True; //Must be set!\n  finally\n    {$IFDEF WITH_STRDISPOSE_DEPRECATED}AnsiStrings.{$ENDIF}StrDispose(DPB);\n  end;\nend;\n\n{**\n  Creates a <code>PreparedStatement</code> object for sending\n  parameterized SQL statements to the database.\n\n  A SQL statement with or without IN parameters can be\n  pre-compiled and stored in a PreparedStatement object. This\n  object can then be used to efficiently execute this statement\n  multiple times.\n\n  <P><B>Note:</B> This method is optimized for handling\n  parametric SQL statements that benefit from precompilation. If\n  the driver supports precompilation,\n  the method <code>prepareStatement</code> will send\n  the statement to the database for precompilation. Some drivers\n  may not support precompilation. In this case, the statement may\n  not be sent to the database until the <code>PreparedStatement</code> is\n  executed.  This has no direct effect on users; however, it does\n  affect which method throws certain SQLExceptions.\n\n  Result sets created using the returned PreparedStatement will have\n  forward-only type and read-only concurrency, by default.\n\n  @param sql a SQL statement that may contain one or more '?' IN\n    parameter placeholders\n  @return a new PreparedStatement object containing the\n    pre-compiled statement\n}\nfunction TZInterbase6Connection.CreatePreparedStatement(\n  const SQL: string; Info: TStrings): IZPreparedStatement;\nbegin\n  if IsClosed then\n     Open;\n  Result := TZInterbase6PreparedStatement.Create(Self, SQL, Info);\nend;\n\n{**\n  Creates a <code>CallableStatement</code> object for calling\n  database stored procedures.\n  The <code>CallableStatement</code> object provides\n  methods for setting up its IN and OUT parameters, and\n  methods for executing the call to a stored procedure.\n\n  <P><B>Note:</B> This method is optimized for handling stored\n  procedure call statements. Some drivers may send the call\n  statement to the database when the method <code>prepareCall</code>\n  is done; others\n  may wait until the <code>CallableStatement</code> object\n  is executed. This has no\n  direct effect on users; however, it does affect which method\n  throws certain SQLExceptions.\n\n  Result sets created using the returned CallableStatement will have\n  forward-only type and read-only concurrency, by default.\n\n  @param sql a SQL statement that may contain one or more '?'\n    parameter placeholders. Typically this  statement is a JDBC\n    function call escape string.\n  @param Info a statement parameters.\n  @return a new CallableStatement object containing the\n    pre-compiled SQL statement\n}\nfunction TZInterbase6Connection.CreateCallableStatement(const SQL: string;\n  Info: TStrings): IZCallableStatement;\nbegin\n  if IsClosed then\n     Open;\n  Result := TZInterbase6CallableStatement.Create(Self, SQL, Info);\nend;\n\n{**\n  Drops all changes made since the previous\n  commit/rollback and releases any database locks currently held\n  by this Connection. This method should be used only when auto-\n  commit has been disabled.\n  @see #setAutoCommit\n}\nprocedure TZInterbase6Connection.Rollback;\nbegin\n  if FTrHandle <> 0 then\n  begin\n    if FHardCommit then\n    begin\n      GetPlainDriver.isc_rollback_transaction(@FStatusVector, @FTrHandle);\n      FTrHandle := 0;\n    end\n    else\n      GetPlainDriver.isc_rollback_retaining(@FStatusVector, @FTrHandle);\n    CheckInterbase6Error(GetPlainDriver, FStatusVector);\n    DriverManager.LogMessage(lcTransaction, PlainDriver.GetProtocol, 'TRANSACTION ROLLBACK');\n  end;\nend;\n\n{**\n  Checks if a connection is still alive by doing a call to isc_database_info\n  It does not matter what info we request, we are not looking at it, as long\n  as it is something which should _always_ work if the connection is there.\n  We check if the error returned is one of the net_* errors described in the\n  firebird client documentation (335544721 .. 335544727).\n  Returns 0 if the connection is OK\n  Returns non zeor if the connection is not OK\n}\nfunction TZInterbase6Connection.PingServer: integer;\nvar\n  DatabaseInfoCommand: Char;\n  Buffer: array[0..IBBigLocalBufferLength - 1] of AnsiChar;\n  ErrorCode: ISC_STATUS;\nbegin\n  DatabaseInfoCommand := Char(isc_info_reads);\n\n  ErrorCode := GetPlainDriver.isc_database_info(@FStatusVector, @FHandle, 1, @DatabaseInfoCommand,\n                           IBLocalBufferLength, Buffer);\n\n  if (ErrorCode >= 335544721) and (ErrorCode <= 335544727) then\n   result := -1\n  else\n   result := 0;\nend;\n\n{**\n   Start Interbase transaction\n}\nprocedure TZInterbase6Connection.StartTransaction;\nvar\n  Params: TStrings;\n  PTEB: PISC_TEB;\nbegin\n  PTEB := nil;\n  Params := TStringList.Create;\n\n  { Set transaction parameters by TransactIsolationLevel }\n  //Params.Values['isc_dpb_lc_ctype'] := FClientCodePage; //Set CharacterSet allways if option is set\n  Params.Add('isc_tpb_version3');\n  case TransactIsolationLevel of\n    tiReadCommitted:\n      begin\n        Params.Add('isc_tpb_read_committed');\n        Params.Add('isc_tpb_rec_version');\n        Params.Add('isc_tpb_nowait');\n      end;\n    tiRepeatableRead:\n      begin\n        Params.Add('isc_tpb_concurrency');\n        Params.Add('isc_tpb_nowait');\n      end;\n    tiSerializable:\n      begin\n        Params.Add('isc_tpb_consistency');\n      end;\n  else\n    begin\n      { Add user defined parameters for transaction }\n      Params.Clear;\n      Params.AddStrings(Info);\n    end;\n  end;\n\n  try\n    { GenerateTPB return PTEB with null pointer tpb_address from default\n      transaction }\n    PTEB := GenerateTPB(Params, FHandle);\n    GetPlainDriver.isc_start_multiple(@FStatusVector, @FTrHandle, 1, PTEB);\n    CheckInterbase6Error(GetPlainDriver, FStatusVector, lcTransaction);\n    DriverManager.LogMessage(lcTransaction, PlainDriver.GetProtocol,\n      'TRANSACTION STARTED.');\n  finally\n    FreeAndNil(Params);\n    {$IFDEF WITH_STRDISPOSE_DEPRECATED}AnsiStrings.{$ENDIF}StrDispose(PTEB.tpb_address);\n    FreeMem(PTEB);\n  end\nend;\n\n{**\n  Creates new database\n  @param SQL a sql strinf for creation database\n}\nprocedure TZInterbase6Connection.CreateNewDatabase(const SQL: String);\nvar\n  TrHandle: TISC_TR_HANDLE;\nbegin\n  TrHandle := 0;\n  GetPlainDriver.isc_dsql_execute_immediate(@FStatusVector, @FHandle, @TrHandle,\n    0, PAnsiChar({$IFDEF UNICODE}AnsiString{$ENDIF}(sql)), FDialect, nil);\n  CheckInterbase6Error(GetPlainDriver, FStatusVector, lcExecute, SQL);\nend;\n\nfunction TZInterbase6Connection.GetBinaryEscapeString(const Value: RawByteString): String;\nbegin\n  //http://tracker.firebirdsql.org/browse/CORE-2789\n  if EndsWith(GetPlainDriver.GetProtocol, '2.5') then\n    if (Length(Value)*2+3) < 32*1024 then\n      Result := GetSQLHexString(PAnsiChar(Value), Length(Value))\n    else\n      raise Exception.Create('Binary data out of range! Use parameters!')\n  else\n    raise Exception.Create('Your Firebird-Version does''t support Binary-Data in SQL-Statements! Use parameters!');\nend;\n\nfunction TZInterbase6Connection.GetBinaryEscapeString(const Value: TByteDynArray): String;\nbegin\n  //http://tracker.firebirdsql.org/browse/CORE-2789\n  if EndsWith(GetPlainDriver.GetProtocol, '2.5') then\n    if (Length(Value)*2+3) < 32*1024 then\n      Result := GetSQLHexString(PAnsiChar(Value), Length(Value))\n    else\n      raise Exception.Create('Binary data out of range! Use parameters!')\n  else\n    raise Exception.Create('Your Firebird-Version does''t support Binary-Data in SQL-Statements! Use parameters!');\nend;\n\nfunction TZInterbase6Connection.GetEscapeString(const Value: RawByteString): RawByteString;\nbegin\n  //http://www.firebirdsql.org/manual/qsg10-firebird-sql.html\n  if GetAutoEncodeStrings then\n    if StartsWith(Value, RawByteString('''')) and EndsWith(Value, RawByteString('''')) then\n      {$IFDEF UNICODE}\n      Result := Value\n      {$ELSE}\n      Result := GetDriver.GetTokenizer.GetEscapeString(Value)\n      {$ENDIF}\n    else\n      {$IFDEF UNICODE}\n      Result := #39+{$IFDEF WITH_UNITANSISTRINGS}AnsiStrings.{$ENDIF}StringReplace(Value, #39, #39#39, [rfReplaceAll])+#39\n      {$ELSE}\n      Result := GetDriver.GetTokenizer.GetEscapeString(#39+StringReplace(Value, #39, #39#39, [rfReplaceAll])+#39)\n      {$ENDIF}\n  else\n    if StartsWith(Value, RawByteString('''')) and EndsWith(Value, RawByteString('''')) then\n      Result := Value\n    else\n      Result := #39+{$IFDEF WITH_UNITANSISTRINGS}AnsiStrings.{$ENDIF}StringReplace(Value, #39, #39#39, [rfReplaceAll])+#39;\nend;\n\nfunction TZInterbase6Connection.GetEscapeString(const Value: ZWideString): ZWideString;\nbegin\n  //http://www.firebirdsql.org/manual/qsg10-firebird-sql.html\n  if GetAutoEncodeStrings then\n    if StartsWith(Value, ZWideString('''')) and EndsWith(Value, ZWideString('''')) then\n      {$IFDEF UNICODE}\n      Result := GetDriver.GetTokenizer.GetEscapeString(Value)\n      {$ELSE}\n      Result := Value\n      {$ENDIF}\n    else\n      {$IFDEF UNICODE}\n      Result := GetDriver.GetTokenizer.GetEscapeString(#39+StringReplace(Value, #39, #39#39, [rfReplaceAll])+#39)\n      {$ELSE}\n      Result := ZDbcUnicodeString(GetDriver.GetTokenizer.GetEscapeString(#39+StringReplace(ZPlainString(Value), #39, #39#39, [rfReplaceAll])+#39))\n      {$ENDIF}\n  else\n    if StartsWith(Value, ZWideString('''')) and EndsWith(Value, ZWideString('''')) then\n      Result := Value\n    else\n      {$IFDEF UNICODE}\n      Result := #39+StringReplace(Value, #39, #39#39, [rfReplaceAll])+#39;\n      {$ELSE}\n      Result := ZDbcUnicodeString(#39+StringReplace(ZPlainString(Value), #39, #39#39, [rfReplaceAll])+#39);\n      {$ENDIF}\nend;\n{**\n  Creates a sequence generator object.\n  @param Sequence a name of the sequence generator.\n  @param BlockSize a number of unique keys requested in one trip to SQL server.\n  @returns a created sequence object.\n}\nfunction TZInterbase6Connection.CreateSequence(const Sequence: string;\n  BlockSize: Integer): IZSequence;\nbegin\n  Result := TZInterbase6Sequence.Create(Self, Sequence, BlockSize);\nend;\n\n{ TZInterbase6CachedResolver }\n\n{**\n  Forms a where clause for SELECT statements to calculate default values.\n  @param Columns a collection of key columns.\n  @param OldRowAccessor an accessor object to old column values.\n}\nfunction TZInterbase6CachedResolver.FormCalculateStatement(\n  Columns: TObjectList): string;\n// --> ms, 30/10/2005\nvar\n   iPos: Integer;\nbegin\n  Result := inherited FormCalculateStatement(Columns);\n  if Result <> '' then\n  begin\n    iPos := pos('FROM', uppercase(Result));\n    if iPos > 0 then\n    begin\n      Result := copy(Result, 1, iPos+3) + ' RDB$DATABASE';\n    end\n    else\n    begin\n      Result := Result + ' FROM RDB$DATABASE';\n    end;\n  end;\n// <-- ms\nend;\n\n{ TZInterbase6Sequence }\n\n{**\n  Gets the current unique key generated by this sequence.\n  @param the next generated unique key.\n}\nfunction TZInterbase6Sequence.GetCurrentValue: Int64;\nvar\n  Statement: IZStatement;\n  ResultSet: IZResultSet;\nbegin\n  Statement := Connection.CreateStatement;\n  ResultSet := Statement.ExecuteQuery(Format(\n    'SELECT GEN_ID(\"%s\", 0) FROM rdb$generators ' +\n    'WHERE rdb$generators.rdb$generator_name = ''%s''', [Name, Name]));\n  if ResultSet.Next then\n    Result := ResultSet.GetLong(1)\n  else\n    Result := inherited GetCurrentValue;\n  ResultSet.Close;\n  Statement.Close;\nend;\n\n{**\n  Gets the next unique key generated by this sequence.\n  @param the next generated unique key.\n}\nfunction TZInterbase6Sequence.GetCurrentValueSQL: string;\nbegin\n  Result := Format(' GEN_ID(\"%s\", 0) ', [Name]);\nend;\n\nfunction TZInterbase6Sequence.GetNextValue: Int64;\nvar\n  Statement: IZStatement;\n  ResultSet: IZResultSet;\nbegin\n  Statement := Connection.CreateStatement;\n  ResultSet := Statement.ExecuteQuery(Format(\n    'SELECT GEN_ID(\"%s\", %d) FROM rdb$generators ' +\n    'WHERE rdb$generators.rdb$generator_name = ''%s''', [Name, BlockSize, Name]));\n  if ResultSet.Next then\n    Result := ResultSet.GetLong(1)\n  else\n    Result := inherited GetNextValue;\n  ResultSet.Close;\n  Statement.Close;\nend;\n\nfunction TZInterbase6Sequence.GetNextValueSQL: string;\nbegin\n  Result := Format(' GEN_ID(\"%s\", %d) ', [Name, BlockSize]);\nend;\n\ninitialization\n  Interbase6Driver := TZInterbase6Driver.Create;\n  DriverManager.RegisterDriver(Interbase6Driver);\n\nfinalization\n  if Assigned(DriverManager) then\n    DriverManager.DeregisterDriver(Interbase6Driver);\n  Interbase6Driver := nil;\nend.\n"
  },
  {
    "path": "lib/zeosdbo/src/dbc/ZDbcInterbase6Metadata.pas",
    "content": "{*********************************************************}\n{                                                         }\n{                 Zeos Database Objects                   }\n{         Interbase Database Connectivity Classes         }\n{                                                         }\n{        Originally written by Sergey Merkuriev           }\n{                                                         }\n{*********************************************************}\n\n{@********************************************************}\n{    Copyright (c) 1999-2012 Zeos Development Group       }\n{                                                         }\n{ License Agreement:                                      }\n{                                                         }\n{ This library is distributed in the hope that it will be }\n{ useful, but WITHOUT ANY WARRANTY; without even the      }\n{ implied warranty of MERCHANTABILITY or FITNESS FOR      }\n{ A PARTICULAR PURPOSE.  See the GNU Lesser General       }\n{ Public License for more details.                        }\n{                                                         }\n{ The source code of the ZEOS Libraries and packages are  }\n{ distributed under the Library GNU General Public        }\n{ License (see the file COPYING / COPYING.ZEOS)           }\n{ with the following  modification:                       }\n{ As a special exception, the copyright holders of this   }\n{ library give you permission to link this library with   }\n{ independent modules to produce an executable,           }\n{ regardless of the license terms of these independent    }\n{ modules, and to copy and distribute the resulting       }\n{ executable under terms of your choice, provided that    }\n{ you also meet, for each linked independent module,      }\n{ the terms and conditions of the license of that module. }\n{ An independent module is a module which is not derived  }\n{ from or based on this library. If you modify this       }\n{ library, you may extend this exception to your version  }\n{ of the library, but you are not obligated to do so.     }\n{ If you do not wish to do so, delete this exception      }\n{ statement from your version.                            }\n{                                                         }\n{                                                         }\n{ The project web site is located on:                     }\n{   http://zeos.firmos.at  (FORUM)                        }\n{   http://sourceforge.net/p/zeoslib/tickets/ (BUGTRACKER)}\n{   svn://svn.code.sf.net/p/zeoslib/code-0/trunk (SVN)    }\n{                                                         }\n{   http://www.sourceforge.net/projects/zeoslib.          }\n{                                                         }\n{                                                         }\n{                                 Zeos Development Group. }\n{********************************************************@}\n\nunit ZDbcInterbase6Metadata;\n\ninterface\n\n{$I ZDbc.inc}\n\nuses\n  Types, Classes, SysUtils, ZSysUtils, ZDbcIntfs, ZDbcMetadata, ZCompatibility,\n  ZDbcConnection, ZDbcInterbase6, ZURL;\n\ntype\n\n  // technobot 2008-06-25 - methods moved as is from TZInterbase6DatabaseMetadata:\n  {** Implements Interbase6 Database Information. }\n  TZInterbase6DatabaseInfo = class(TZAbstractDatabaseInfo)\n  private\n    FServerVersion: string;\n//    function UncachedGetUDTs(const Catalog: string; const SchemaPattern: string;\n//      const TypeNamePattern: string; const Types: TIntegerDynArray): IZResultSet; override;\n  public\n    // database/driver/server info:\n    function GetDatabaseProductName: string; override;\n    function GetDatabaseProductVersion: string; override;\n    function GetDriverName: string; override;\n//    function GetDriverVersion: string; override; -> Same as parent\n    function GetDriverMajorVersion: Integer; override;\n    function GetDriverMinorVersion: Integer; override;\n    function GetServerVersion: string;\n\n    // capabilities (what it can/cannot do):\n//    function AllProceduresAreCallable: Boolean; override; -> Not implemented\n//    function AllTablesAreSelectable: Boolean; override; -> Not implemented\n    function SupportsMixedCaseIdentifiers: Boolean; override;\n    function SupportsMixedCaseQuotedIdentifiers: Boolean; override;\n//    function SupportsAlterTableWithAddColumn: Boolean; override; -> Not implemented\n//    function SupportsAlterTableWithDropColumn: Boolean; override; -> Not implemented\n//    function SupportsColumnAliasing: Boolean; override; -> Not implemented\n//    function SupportsConvert: Boolean; override; -> Not implemented\n//    function SupportsConvertForTypes(FromType: TZSQLType; ToType: TZSQLType):\n//      Boolean; override; -> Not implemented\n//    function SupportsTableCorrelationNames: Boolean; override; -> Not implemented\n//    function SupportsDifferentTableCorrelationNames: Boolean; override; -> Not implemented\n    function SupportsExpressionsInOrderBy: Boolean; override;\n    function SupportsOrderByUnrelated: Boolean; override;\n    function SupportsGroupBy: Boolean; override;\n    function SupportsGroupByUnrelated: Boolean; override;\n    function SupportsGroupByBeyondSelect: Boolean; override;\n//    function SupportsLikeEscapeClause: Boolean; override; -> Not implemented\n//    function SupportsMultipleResultSets: Boolean; override; -> Not implemented\n//    function SupportsMultipleTransactions: Boolean; override; -> Not implemented\n//    function SupportsNonNullableColumns: Boolean; override; -> Not implemented\n//    function SupportsMinimumSQLGrammar: Boolean; override; -> Not implemented\n//    function SupportsCoreSQLGrammar: Boolean; override; -> Not implemented\n//    function SupportsExtendedSQLGrammar: Boolean; override; -> Not implemented\n//    function SupportsANSI92EntryLevelSQL: Boolean; override; -> Not implemented\n//    function SupportsANSI92IntermediateSQL: Boolean; override; -> Not implemented\n//    function SupportsANSI92FullSQL: Boolean; override; -> Not implemented\n    function SupportsIntegrityEnhancementFacility: Boolean; override;\n//    function SupportsOuterJoins: Boolean; override; -> Not implemented\n//    function SupportsFullOuterJoins: Boolean; override; -> Not implemented\n//    function SupportsLimitedOuterJoins: Boolean; override; -> Not implemented\n    function SupportsSchemasInDataManipulation: Boolean; override;\n    function SupportsSchemasInProcedureCalls: Boolean; override;\n    function SupportsSchemasInTableDefinitions: Boolean; override;\n    function SupportsSchemasInIndexDefinitions: Boolean; override;\n    function SupportsSchemasInPrivilegeDefinitions: Boolean; override;\n    function SupportsCatalogsInDataManipulation: Boolean; override;\n    function SupportsCatalogsInProcedureCalls: Boolean; override;\n    function SupportsCatalogsInTableDefinitions: Boolean; override;\n    function SupportsCatalogsInIndexDefinitions: Boolean; override;\n    function SupportsCatalogsInPrivilegeDefinitions: Boolean; override;\n    function SupportsPositionedDelete: Boolean; override;\n    function SupportsPositionedUpdate: Boolean; override;\n    function SupportsSelectForUpdate: Boolean; override;\n    function SupportsStoredProcedures: Boolean; override;\n    function SupportsSubqueriesInComparisons: Boolean; override;\n    function SupportsSubqueriesInExists: Boolean; override;\n    function SupportsSubqueriesInIns: Boolean; override;\n    function SupportsSubqueriesInQuantifieds: Boolean; override;\n    function SupportsCorrelatedSubqueries: Boolean; override;\n    function SupportsUnion: Boolean; override;\n    function SupportsUnionAll: Boolean; override;\n    function SupportsOpenCursorsAcrossCommit: Boolean; override;\n    function SupportsOpenCursorsAcrossRollback: Boolean; override;\n    function SupportsOpenStatementsAcrossCommit: Boolean; override;\n    function SupportsOpenStatementsAcrossRollback: Boolean; override;\n    function SupportsTransactions: Boolean; override;\n    function SupportsTransactionIsolationLevel(Level: TZTransactIsolationLevel):\n      Boolean; override;\n    function SupportsDataDefinitionAndDataManipulationTransactions: Boolean; override;\n    function SupportsDataManipulationTransactionsOnly: Boolean; override;\n    function SupportsResultSetType(_Type: TZResultSetType): Boolean; override;\n    function SupportsResultSetConcurrency(_Type: TZResultSetType;\n      Concurrency: TZResultSetConcurrency): Boolean; override;\n//    function SupportsBatchUpdates: Boolean; override; -> Not implemented\n\n    // maxima:\n    function GetMaxBinaryLiteralLength: Integer; override;\n    function GetMaxCharLiteralLength: Integer; override;\n    function GetMaxColumnNameLength: Integer; override;\n    function GetMaxColumnsInGroupBy: Integer; override;\n    function GetMaxColumnsInIndex: Integer; override;\n    function GetMaxColumnsInOrderBy: Integer; override;\n    function GetMaxColumnsInSelect: Integer; override;\n    function GetMaxColumnsInTable: Integer; override;\n    function GetMaxConnections: Integer; override;\n    function GetMaxCursorNameLength: Integer; override;\n    function GetMaxIndexLength: Integer; override;\n    function GetMaxSchemaNameLength: Integer; override;\n    function GetMaxProcedureNameLength: Integer; override;\n    function GetMaxCatalogNameLength: Integer; override;\n    function GetMaxRowSize: Integer; override;\n    function GetMaxStatementLength: Integer; override;\n    function GetMaxStatements: Integer; override;\n    function GetMaxTableNameLength: Integer; override;\n    function GetMaxTablesInSelect: Integer; override;\n    function GetMaxUserNameLength: Integer; override;\n\n    // policies (how are various data and operations handled):\n//    function IsReadOnly: Boolean; override; -> Not implemented\n//    function IsCatalogAtStart: Boolean; override; -> Not implemented\n    function DoesMaxRowSizeIncludeBlobs: Boolean; override;\n//    function NullsAreSortedHigh: Boolean; override; -> Not implemented\n//    function NullsAreSortedLow: Boolean; override; -> Not implemented\n//    function NullsAreSortedAtStart: Boolean; override; -> Not implemented\n//    function NullsAreSortedAtEnd: Boolean; override; -> Not implemented\n//    function NullPlusNonNullIsNull: Boolean; override; -> Not implemented\n//    function UsesLocalFiles: Boolean; override; -> Not implemented\n    function UsesLocalFilePerTable: Boolean; override;\n    function StoresUpperCaseIdentifiers: Boolean; override;\n    function StoresLowerCaseIdentifiers: Boolean; override;\n    function StoresMixedCaseIdentifiers: Boolean; override;\n    function StoresUpperCaseQuotedIdentifiers: Boolean; override;\n    function StoresLowerCaseQuotedIdentifiers: Boolean; override;\n    function StoresMixedCaseQuotedIdentifiers: Boolean; override;\n    function GetDefaultTransactionIsolation: TZTransactIsolationLevel; override;\n    function DataDefinitionCausesTransactionCommit: Boolean; override;\n    function DataDefinitionIgnoredInTransactions: Boolean; override;\n\n    // interface details (terms, keywords, etc):\n    function GetSchemaTerm: string; override;\n    function GetProcedureTerm: string; override;\n    function GetCatalogTerm: string; override;\n    function GetCatalogSeparator: string; override;\n    function GetSQLKeywords: string; override;\n    function GetNumericFunctions: string; override;\n    function GetStringFunctions: string; override;\n    function GetSystemFunctions: string; override;\n    function GetTimeDateFunctions: string; override;\n    function GetSearchStringEscape: string; override;\n    function GetExtraNameCharacters: string; override;\n  end;\n\n  {** Implements Interbase6 Database Metadata. }\n  TZInterbase6DatabaseMetadata = class(TZAbstractDatabaseMetadata)\n  private\n    function GetPrivilege(Privilege: string): string;\n  protected\n    function CreateDatabaseInfo: IZDatabaseInfo; override; // technobot 2008-06-25\n    function ConstructNameCondition(Pattern: string; Column: string): string; override;\n\n    function UncachedGetTables(const Catalog: string; const SchemaPattern: string;\n      const TableNamePattern: string; const Types: TStringDynArray): IZResultSet; override;\n//    function UncachedGetSchemas: IZResultSet; override; -> Not implemented\n//    function UncachedGetCatalogs: IZResultSet; override; -> Not Implemented\n    function UncachedGetTableTypes: IZResultSet; override;\n    function UncachedGetColumns(const Catalog: string; const SchemaPattern: string;\n      const TableNamePattern: string; const ColumnNamePattern: string): IZResultSet; override;\n    function UncachedGetTablePrivileges(const Catalog: string; const SchemaPattern: string;\n      const TableNamePattern: string): IZResultSet; override;\n    function UncachedGetColumnPrivileges(const Catalog: string; const Schema: string;\n      const Table: string; const ColumnNamePattern: string): IZResultSet; override;\n    function UncachedGetPrimaryKeys(const Catalog: string; const Schema: string;\n      const Table: string): IZResultSet; override;\n    function UncachedGetImportedKeys(const Catalog: string; const Schema: string;\n      const Table: string): IZResultSet; override;\n    function UncachedGetExportedKeys(const Catalog: string; const Schema: string;\n      const Table: string): IZResultSet; override;\n    function UncachedGetCrossReference(const PrimaryCatalog: string; const PrimarySchema: string;\n      const PrimaryTable: string; const ForeignCatalog: string; const ForeignSchema: string;\n      const ForeignTable: string): IZResultSet; override;\n    function UncachedGetIndexInfo(const Catalog: string; const Schema: string; const Table: string;\n      Unique: Boolean; Approximate: Boolean): IZResultSet; override;\n    function UncachedGetSequences(const Catalog: string; const SchemaPattern: string;\n      const SequenceNamePattern: string): IZResultSet; override;\n    function UncachedGetProcedures(const Catalog: string; const SchemaPattern: string;\n      const ProcedureNamePattern: string): IZResultSet; override;\n    function UncachedGetProcedureColumns(const Catalog: string; const SchemaPattern: string;\n      const ProcedureNamePattern: string; const ColumnNamePattern: string):\n      IZResultSet; override;\n    function UncachedGetVersionColumns(const Catalog: string; const Schema: string;\n      const Table: string): IZResultSet; override;\n    function UncachedGetTypeInfo: IZResultSet; override;\n    function UncachedGetTriggers(const Catalog: string;\n      const SchemaPattern: string; const TableNamePattern: string;\n      const TriggerNamePattern: string): IZResultSet; override; //EgonHugesit\n    function UncachedGetCollationAndCharSet(const Catalog, SchemaPattern,\n      TableNamePattern, ColumnNamePattern: string): IZResultSet; override; //EgonHugeist\n    function UncachedGetCharacterSets: IZResultSet; override; //EgonHugeist\n  public\n    property ConSettings;\n  end;\n\nimplementation\n\nuses ZMessages, ZDbcInterbase6Utils, ZDbcUtils;\n\n{ TZInterbase6DatabaseInfo }\n\n//----------------------------------------------------------------------\n// First, a variety of minor information about the target database.\n\n{**\n  What's the name of this database product?\n  @return database product name\n}\nfunction TZInterbase6DatabaseInfo.GetDatabaseProductName: string;\nbegin\n  Result := 'Interbase/Firebird';\nend;\n\n{**\n  What's the version of this database product?\n  @return database version\n}\nfunction TZInterbase6DatabaseInfo.GetDatabaseProductVersion: string;\nbegin\n  Result := '6.0+';\nend;\n\n{**\n  What's the name of this JDBC driver?\n  @return JDBC driver name\n}\nfunction TZInterbase6DatabaseInfo.GetDriverName: string;\nbegin\n  Result := 'Zeos Database Connectivity Driver for Interbase and Firebird';\nend;\n\n{**\n  What's this JDBC driver's major version number?\n  @return JDBC driver major version\n}\nfunction TZInterbase6DatabaseInfo.GetDriverMajorVersion: Integer;\nbegin\n  Result := 1;\nend;\n\n{**\n  What's this JDBC driver's minor version number?\n  @return JDBC driver minor version number\n}\nfunction TZInterbase6DatabaseInfo.GetDriverMinorVersion: Integer;\nbegin\n  Result := 0;\nend;\n\n{**\n  Gets the version of the server.\n  @returns the version of the server.\n}\nfunction TZInterbase6DatabaseInfo.GetServerVersion: string;\nvar\n  FIBConnection: IZInterbase6Connection;\nbegin\n  if FServerVersion = '' then\n  begin\n    FIBConnection := Metadata.GetConnection as IZInterbase6Connection;\n    FServerVersion := String(GetVersion(FIBConnection.GetPlainDriver,\n      FIBConnection.GetDBHandle));\n  end;\n  Result := FServerVersion;\nend;\n\n{**\n  Does the database use a file for each table?\n  @return true if the database uses a local file for each table\n}\nfunction TZInterbase6DatabaseInfo.UsesLocalFilePerTable: Boolean;\nbegin\n  Result := False;\nend;\n\n{**\n  Does the database treat mixed case unquoted SQL identifiers as\n  case sensitive and as a result store them in mixed case?\n  A JDBC Compliant<sup><font size=-2>TM</font></sup> driver will always return false.\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZInterbase6DatabaseInfo.SupportsMixedCaseIdentifiers: Boolean;\nbegin\n  Result := True;\nend;\n\n{**\n  Does the database treat mixed case unquoted SQL identifiers as\n  case insensitive and store them in upper case?\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZInterbase6DatabaseInfo.StoresUpperCaseIdentifiers: Boolean;\nbegin\n  Result := True;\nend;\n\n{**\n  Does the database treat mixed case unquoted SQL identifiers as\n  case insensitive and store them in lower case?\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZInterbase6DatabaseInfo.StoresLowerCaseIdentifiers: Boolean;\nbegin\n  Result := False;\nend;\n\n{**\n  Does the database treat mixed case unquoted SQL identifiers as\n  case insensitive and store them in mixed case?\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZInterbase6DatabaseInfo.StoresMixedCaseIdentifiers: Boolean;\nbegin\n  Result := False;\nend;\n\n{**\n  Does the database treat mixed case quoted SQL identifiers as\n  case sensitive and as a result store them in mixed case?\n  A JDBC Compliant<sup><font size=-2>TM</font></sup> driver will always return true.\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZInterbase6DatabaseInfo.SupportsMixedCaseQuotedIdentifiers: Boolean;\nbegin\n  Result := True;\nend;\n\n{**\n  Does the database treat mixed case quoted SQL identifiers as\n  case insensitive and store them in upper case?\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZInterbase6DatabaseInfo.StoresUpperCaseQuotedIdentifiers: Boolean;\nbegin\n  Result := False;\nend;\n\n{**\n  Does the database treat mixed case quoted SQL identifiers as\n  case insensitive and store them in lower case?\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZInterbase6DatabaseInfo.StoresLowerCaseQuotedIdentifiers: Boolean;\nbegin\n  Result := False;\nend;\n\n{**\n  Does the database treat mixed case quoted SQL identifiers as\n  case insensitive and store them in mixed case?\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZInterbase6DatabaseInfo.StoresMixedCaseQuotedIdentifiers: Boolean;\nbegin\n  Result := True;\nend;\n\n{**\n  Gets a comma-separated list of all a database's SQL keywords\n  that are NOT also SQL92 keywords.\n  @return the list\n}\nfunction TZInterbase6DatabaseInfo.GetSQLKeywords: string;\nbegin\n  Result := 'ACTIVE,AFTER,ASCENDING,BASE_NAME,BEFORE,BLOB,' +\n    'CACHE,CHECK_POINT_LENGTH,COMPUTED,CONDITIONAL,CONTAINING,' +\n    'CSTRING,DATABASE,RDB$DB_KEY,DEBUG,DESCENDING,DO,ENTRY_POINT,' +\n    'EXIT,FILE,FILTER,FUNCTION,GDSCODE,GENERATOR,GEN_ID,' +\n    'GROUP_COMMIT_WAIT_TIME,IF,INACTIVE,INPUT_TYPE,INDEX,' +\n    'LOGFILE,LOG_BUFFER_SIZE,MANUAL,MAXIMUM_SEGMENT,MERGE, MESSAGE,' +\n    'MODULE_NAME,NCHAR,NUM_LOG_BUFFERS,OUTPUT_TYPE,OVERFLOW,PAGE,' +\n    'PAGES,PAGE_SIZE,PARAMETER,PASSWORD,PLAN,POST_EVENT,PROTECTED,' +\n    'RAW_PARTITIONS,RESERV,RESERVING,RETAIN,RETURNING_VALUES,RETURNS,' +\n    'SEGMENT,SHADOW,SHARED,SINGULAR,SNAPSHOT,SORT,STABILITY,STARTS,' +\n    'STARTING,STATISTICS,SUB_TYPE,SUSPEND,TRIGGER,VARIABLE,RECORD_VERSION,' +\n    'WAIT,WHILE,WORK,VALUE,POSITION,USER,CURRENCY,OPTION,DATE,START,END,USER,' +\n    'READ,PARENT,TYPE'+\n    {Ticket #63: http://sourceforge.net/p/zeoslib/tickets/62/}\n    ',DEC,TIME,MIN,MAX'+\n    {FireBird 3.0}\n    ',DETERMINISTIC,OVER,RETURN,SCROLL,SQLSTATE';\nend;\n\n{**\n  Gets a comma-separated list of math functions.  These are the\n  X/Open CLI math function names used in the JDBC function escape\n  clause.\n  @return the list\n}\nfunction TZInterbase6DatabaseInfo.GetNumericFunctions: string;\nbegin\n  Result := '';\nend;\n\n{**\n  Gets a comma-separated list of string functions.  These are the\n  X/Open CLI string function names used in the JDBC function escape\n  clause.\n  @return the list\n}\nfunction TZInterbase6DatabaseInfo.GetStringFunctions: string;\nbegin\n  Result := '';\nend;\n\n{**\n  Gets a comma-separated list of system functions.  These are the\n  X/Open CLI system function names used in the JDBC function escape\n  clause.\n  @return the list\n}\nfunction TZInterbase6DatabaseInfo.GetSystemFunctions: string;\nbegin\n  Result := '';\nend;\n\n{**\n  Gets a comma-separated list of time and date functions.\n  @return the list\n}\nfunction TZInterbase6DatabaseInfo.GetTimeDateFunctions: string;\nbegin\n  Result := '';\nend;\n\n{**\n  Gets the string that can be used to escape wildcard characters.\n  This is the string that can be used to escape '_' or '%' in\n  the string pattern style catalog search parameters.\n\n  <P>The '_' character represents any single character.\n  <P>The '%' character represents any sequence of zero or\n  more characters.\n\n  @return the string used to escape wildcard characters\n}\nfunction TZInterbase6DatabaseInfo.GetSearchStringEscape: string;\nbegin\n  Result := '\\';\nend;\n\n{**\n  Gets all the \"extra\" characters that can be used in unquoted\n  identifier names (those beyond a-z, A-Z, 0-9 and _).\n  @return the string containing the extra characters\n}\nfunction TZInterbase6DatabaseInfo.GetExtraNameCharacters: string;\nbegin\n  Result := '$';\nend;\n\n//--------------------------------------------------------------------\n// Functions describing which features are supported.\n\n{**\n  Are expressions in \"ORDER BY\" lists supported?\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZInterbase6DatabaseInfo.SupportsExpressionsInOrderBy: Boolean;\nbegin\n  Result := False;\nend;\n\n{**\n  Can an \"ORDER BY\" clause use columns not in the SELECT statement?\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZInterbase6DatabaseInfo.SupportsOrderByUnrelated: Boolean;\nbegin\n  Result := True;\nend;\n\n{**\n  Is some form of \"GROUP BY\" clause supported?\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZInterbase6DatabaseInfo.SupportsGroupBy: Boolean;\nbegin\n  Result := True;\nend;\n\n{**\n  Can a \"GROUP BY\" clause use columns not in the SELECT?\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZInterbase6DatabaseInfo.SupportsGroupByUnrelated: Boolean;\nbegin\n  Result := True;\nend;\n\n{**\n  Can a \"GROUP BY\" clause add columns not in the SELECT\n  provided it specifies all the columns in the SELECT?\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZInterbase6DatabaseInfo.SupportsGroupByBeyondSelect: Boolean;\nbegin\n  Result := True;\nend;\n\n{**\n  Is the SQL Integrity Enhancement Facility supported?\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZInterbase6DatabaseInfo.SupportsIntegrityEnhancementFacility: Boolean;\nbegin\n  Result := False;\nend;\n\n{**\n  What's the database vendor's preferred term for \"schema\"?\n  @return the vendor term\n}\nfunction TZInterbase6DatabaseInfo.GetSchemaTerm: string;\nbegin\n  Result := '';\nend;\n\n{**\n  What's the database vendor's preferred term for \"procedure\"?\n  @return the vendor term\n}\nfunction TZInterbase6DatabaseInfo.GetProcedureTerm: string;\nbegin\n  Result := 'PROCEDURE';\nend;\n\n{**\n  What's the database vendor's preferred term for \"catalog\"?\n  @return the vendor term\n}\nfunction TZInterbase6DatabaseInfo.GetCatalogTerm: string;\nbegin\n  Result := '';\nend;\n\n{**\n  What's the separator between catalog and table name?\n  @return the separator string\n}\nfunction TZInterbase6DatabaseInfo.GetCatalogSeparator: string;\nbegin\n  Result := '';\nend;\n\n{**\n  Can a schema name be used in a data manipulation statement?\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZInterbase6DatabaseInfo.SupportsSchemasInDataManipulation: Boolean;\nbegin\n  Result := False;\nend;\n\n{**\n  Can a schema name be used in a procedure call statement?\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZInterbase6DatabaseInfo.SupportsSchemasInProcedureCalls: Boolean;\nbegin\n  Result := False;\nend;\n\n{**\n  Can a schema name be used in a table definition statement?\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZInterbase6DatabaseInfo.SupportsSchemasInTableDefinitions: Boolean;\nbegin\n  Result := False;\nend;\n\n{**\n  Can a schema name be used in an index definition statement?\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZInterbase6DatabaseInfo.SupportsSchemasInIndexDefinitions: Boolean;\nbegin\n  Result := False;\nend;\n\n{**\n  Can a schema name be used in a privilege definition statement?\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZInterbase6DatabaseInfo.SupportsSchemasInPrivilegeDefinitions: Boolean;\nbegin\n  Result := False;\nend;\n\n{**\n  Can a catalog name be used in a data manipulation statement?\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZInterbase6DatabaseInfo.SupportsCatalogsInDataManipulation: Boolean;\nbegin\n  Result := False;\nend;\n\n{**\n  Can a catalog name be used in a procedure call statement?\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZInterbase6DatabaseInfo.SupportsCatalogsInProcedureCalls: Boolean;\nbegin\n  Result := False;\nend;\n\n{**\n  Can a catalog name be used in a table definition statement?\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZInterbase6DatabaseInfo.SupportsCatalogsInTableDefinitions: Boolean;\nbegin\n  Result := False;\nend;\n\n{**\n  Can a catalog name be used in an index definition statement?\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZInterbase6DatabaseInfo.SupportsCatalogsInIndexDefinitions: Boolean;\nbegin\n  Result := False;\nend;\n\n{**\n  Can a catalog name be used in a privilege definition statement?\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZInterbase6DatabaseInfo.SupportsCatalogsInPrivilegeDefinitions: Boolean;\nbegin\n  Result := False;\nend;\n\n{**\n  Is positioned DELETE supported?\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZInterbase6DatabaseInfo.SupportsPositionedDelete: Boolean;\nbegin\n  Result := True;\nend;\n\n{**\n  Is positioned UPDATE supported?\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZInterbase6DatabaseInfo.SupportsPositionedUpdate: Boolean;\nbegin\n  Result := True;\nend;\n\n{**\n  Is SELECT for UPDATE supported?\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZInterbase6DatabaseInfo.SupportsSelectForUpdate: Boolean;\nbegin\n  Result := True;\nend;\n\n{**\n  Are stored procedure calls using the stored procedure escape\n  syntax supported?\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZInterbase6DatabaseInfo.SupportsStoredProcedures: Boolean;\nbegin\n  Result := True;\nend;\n\n{**\n  Are subqueries in comparison expressions supported?\n  A JDBC Compliant<sup><font size=-2>TM</font></sup> driver always returns true.\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZInterbase6DatabaseInfo.SupportsSubqueriesInComparisons: Boolean;\nbegin\n  Result := True;\nend;\n\n{**\n  Are subqueries in 'exists' expressions supported?\n  A JDBC Compliant<sup><font size=-2>TM</font></sup> driver always returns true.\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZInterbase6DatabaseInfo.SupportsSubqueriesInExists: Boolean;\nbegin\n  Result := True;\nend;\n\n{**\n  Are subqueries in 'in' statements supported?\n  A JDBC Compliant<sup><font size=-2>TM</font></sup> driver always returns true.\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZInterbase6DatabaseInfo.SupportsSubqueriesInIns: Boolean;\nbegin\n  Result := False;\nend;\n\n{**\n  Are subqueries in quantified expressions supported?\n  A JDBC Compliant<sup><font size=-2>TM</font></sup> driver always returns true.\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZInterbase6DatabaseInfo.SupportsSubqueriesInQuantifieds: Boolean;\nbegin\n  Result := True;\nend;\n\n{**\n  Are correlated subqueries supported?\n  A JDBC Compliant<sup><font size=-2>TM</font></sup> driver always returns true.\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZInterbase6DatabaseInfo.SupportsCorrelatedSubqueries: Boolean;\nbegin\n  Result := True;\nend;\n\n{**\n  Is SQL UNION supported?\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZInterbase6DatabaseInfo.SupportsUnion: Boolean;\nbegin\n  Result := True;\nend;\n\n{**\n  Is SQL UNION ALL supported?\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZInterbase6DatabaseInfo.SupportsUnionAll: Boolean;\nbegin\n  Result := True;\nend;\n\n{**\n  Can cursors remain open across commits?\n  @return <code>true</code> if cursors always remain open;\n        <code>false</code> if they might not remain open\n}\nfunction TZInterbase6DatabaseInfo.SupportsOpenCursorsAcrossCommit: Boolean;\nbegin\n  Result := False;\nend;\n\n{**\n  Can cursors remain open across rollbacks?\n  @return <code>true</code> if cursors always remain open;\n        <code>false</code> if they might not remain open\n}\nfunction TZInterbase6DatabaseInfo.SupportsOpenCursorsAcrossRollback: Boolean;\nbegin\n  Result := False;\nend;\n\n{**\n  Can statements remain open across commits?\n  @return <code>true</code> if statements always remain open;\n        <code>false</code> if they might not remain open\n}\nfunction TZInterbase6DatabaseInfo.SupportsOpenStatementsAcrossCommit: Boolean;\nbegin\n  Result := True;\nend;\n\n{**\n  Can statements remain open across rollbacks?\n  @return <code>true</code> if statements always remain open;\n        <code>false</code> if they might not remain open\n}\nfunction TZInterbase6DatabaseInfo.SupportsOpenStatementsAcrossRollback: Boolean;\nbegin\n  Result := True;\nend;\n\n//----------------------------------------------------------------------\n// The following group of methods exposes various limitations\n// based on the target database with the current driver.\n// Unless otherwise specified, a result of zero means there is no\n// limit, or the limit is not known.\n\n{**\n  How many hex characters can you have in an inline binary literal?\n  @return max binary literal length in hex characters;\n       a result of zero means that there is no limit or the limit is not known\n}\nfunction TZInterbase6DatabaseInfo.GetMaxBinaryLiteralLength: Integer;\nbegin\n  Result := 0;\nend;\n\n{**\n  What's the max length for a character literal?\n  @return max literal length;\n       a result of zero means that there is no limit or the limit is not known\n}\nfunction TZInterbase6DatabaseInfo.GetMaxCharLiteralLength: Integer;\nbegin\n  Result := 1024;\nend;\n\n{**\n  What's the limit on column name length?\n  @return max column name length;\n       a result of zero means that there is no limit or the limit is not known\n}\nfunction TZInterbase6DatabaseInfo.GetMaxColumnNameLength: Integer;\nbegin\n  Result := 31;\nend;\n\n{**\n  What's the maximum number of columns in a \"GROUP BY\" clause?\n  @return max number of columns;\n       a result of zero means that there is no limit or the limit is not known\n}\nfunction TZInterbase6DatabaseInfo.GetMaxColumnsInGroupBy: Integer;\nbegin\n  Result := 16;\nend;\n\n{**\n  What's the maximum number of columns allowed in an index?\n  @return max number of columns;\n       a result of zero means that there is no limit or the limit is not known\n}\nfunction TZInterbase6DatabaseInfo.GetMaxColumnsInIndex: Integer;\nbegin\n  Result := 16;\nend;\n\n{**\n  What's the maximum number of columns in an \"ORDER BY\" clause?\n  @return max number of columns;\n       a result of zero means that there is no limit or the limit is not known\n}\nfunction TZInterbase6DatabaseInfo.GetMaxColumnsInOrderBy: Integer;\nbegin\n  Result := 16;\nend;\n\n{**\n  What's the maximum number of columns in a \"SELECT\" list?\n  @return max number of columns;\n       a result of zero means that there is no limit or the limit is not known\n}\nfunction TZInterbase6DatabaseInfo.GetMaxColumnsInSelect: Integer;\nbegin\n  Result := 32767;\nend;\n\n{**\n  What's the maximum number of columns in a table?\n  @return max number of columns;\n       a result of zero means that there is no limit or the limit is not known\n}\nfunction TZInterbase6DatabaseInfo.GetMaxColumnsInTable: Integer;\nbegin\n  Result := 32767;\nend;\n\n{**\n  How many active connections can we have at a time to this database?\n  @return max number of active connections;\n       a result of zero means that there is no limit or the limit is not known\n}\nfunction TZInterbase6DatabaseInfo.GetMaxConnections: Integer;\nbegin\n  Result := 0;\nend;\n\n{**\n  What's the maximum cursor name length?\n  @return max cursor name length in bytes;\n       a result of zero means that there is no limit or the limit is not known\n}\nfunction TZInterbase6DatabaseInfo.GetMaxCursorNameLength: Integer;\nbegin\n  Result := 31;\nend;\n\n{**\n  Retrieves the maximum number of bytes for an index, including all\n  of the parts of the index.\n  @return max index length in bytes, which includes the composite of all\n   the constituent parts of the index;\n   a result of zero means that there is no limit or the limit is not known\n}\nfunction TZInterbase6DatabaseInfo.GetMaxIndexLength: Integer;\nbegin\n  Result := 198;\nend;\n\n{**\n  What's the maximum length allowed for a schema name?\n  @return max name length in bytes;\n       a result of zero means that there is no limit or the limit is not known\n}\nfunction TZInterbase6DatabaseInfo.GetMaxSchemaNameLength: Integer;\nbegin\n  Result := 0;\nend;\n\n{**\n  What's the maximum length of a procedure name?\n  @return max name length in bytes;\n       a result of zero means that there is no limit or the limit is not known\n}\nfunction TZInterbase6DatabaseInfo.GetMaxProcedureNameLength: Integer;\nbegin\n  Result := 0;\nend;\n\n{**\n  What's the maximum length of a catalog name?\n  @return max name length in bytes;\n       a result of zero means that there is no limit or the limit is not known\n}\nfunction TZInterbase6DatabaseInfo.GetMaxCatalogNameLength: Integer;\nbegin\n  Result := 27;\nend;\n\n{**\n  What's the maximum length of a single row?\n  @return max row size in bytes;\n       a result of zero means that there is no limit or the limit is not known\n}\nfunction TZInterbase6DatabaseInfo.GetMaxRowSize: Integer;\nbegin\n  Result := 32664;\nend;\n\n{**\n  Did getMaxRowSize() include LONGVARCHAR and LONGVARBINARY\n  blobs?\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZInterbase6DatabaseInfo.DoesMaxRowSizeIncludeBlobs: Boolean;\nbegin\n  Result := False;\nend;\n\n{**\n  What's the maximum length of an SQL statement?\n  @return max length in bytes;\n       a result of zero means that there is no limit or the limit is not known\n}\nfunction TZInterbase6DatabaseInfo.GetMaxStatementLength: Integer;\nbegin\n  Result := 640;\nend;\n\n{**\n  How many active statements can we have open at one time to this\n  database?\n  @return the maximum number of statements that can be open at one time;\n       a result of zero means that there is no limit or the limit is not known\n}\nfunction TZInterbase6DatabaseInfo.GetMaxStatements: Integer;\nbegin\n  Result := 0;\nend;\n\n{**\n  What's the maximum length of a table name?\n  @return max name length in bytes;\n       a result of zero means that there is no limit or the limit is not known\n}\nfunction TZInterbase6DatabaseInfo.GetMaxTableNameLength: Integer;\nbegin\n  Result := 31;\nend;\n\n{**\n  What's the maximum number of tables in a SELECT statement?\n  @return the maximum number of tables allowed in a SELECT statement;\n       a result of zero means that there is no limit or the limit is not known\n}\nfunction TZInterbase6DatabaseInfo.GetMaxTablesInSelect: Integer;\nbegin\n  Result := 16;\nend;\n\n{**\n  What's the maximum length of a user name?\n  @return max user name length  in bytes;\n       a result of zero means that there is no limit or the limit is not known\n}\nfunction TZInterbase6DatabaseInfo.GetMaxUserNameLength: Integer;\nbegin\n  Result := 31;\nend;\n\n//----------------------------------------------------------------------\n\n{**\n  What's the database's default transaction isolation level?  The\n  values are defined in <code>java.sql.Connection</code>.\n  @return the default isolation level\n  @see Connection\n}\nfunction TZInterbase6DatabaseInfo.GetDefaultTransactionIsolation:\n  TZTransactIsolationLevel;\nbegin\n  Result := tiSerializable;\nend;\n\n{**\n  Are transactions supported? If not, invoking the method\n  <code>commit</code> is a noop and the isolation level is TRANSACTION_NONE.\n  @return <code>true</code> if transactions are supported; <code>false</code> otherwise\n}\nfunction TZInterbase6DatabaseInfo.SupportsTransactions: Boolean;\nbegin\n  Result := True;\nend;\n\n{**\n  Does this database support the given transaction isolation level?\n  @param level the values are defined in <code>java.sql.Connection</code>\n  @return <code>true</code> if so; <code>false</code> otherwise\n  @see Connection\n}\nfunction TZInterbase6DatabaseInfo.SupportsTransactionIsolationLevel(\n  Level: TZTransactIsolationLevel): Boolean;\nbegin\n  case Level of\n    tiRepeatableRead, tiReadCommitted, tiSerializable: Result := True;\n    tiReadUncommitted: Result := False;\n    tiNone: Result := False; //MAY BE FIX IT\n    else\n      Result := False;\n  end;    \nend;\n\n{**\n  Are both data definition and data manipulation statements\n  within a transaction supported?\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZInterbase6DatabaseInfo.\n  SupportsDataDefinitionAndDataManipulationTransactions: Boolean;\nbegin\n  Result := True;\nend;\n\n{**\n  Are only data manipulation statements within a transaction\n  supported?\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZInterbase6DatabaseInfo.\n  SupportsDataManipulationTransactionsOnly: Boolean;\nbegin\n  Result := False;\nend;\n\n{**\n  Does a data definition statement within a transaction force the\n  transaction to commit?\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZInterbase6DatabaseInfo.DataDefinitionCausesTransactionCommit: Boolean;\nbegin\n  Result := True;\nend;\n\n{**\n  Is a data definition statement within a transaction ignored?\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZInterbase6DatabaseInfo.DataDefinitionIgnoredInTransactions: Boolean;\nbegin\n  Result := False;\nend;\n\n{**\n  Does the database support the given result set type?\n  @param type defined in <code>java.sql.ResultSet</code>\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZInterbase6DatabaseInfo.SupportsResultSetType(\n  _Type: TZResultSetType): Boolean;\nbegin\n  Result := _Type = rtScrollInsensitive;\nend;\n\n{**\n  Does the database support the concurrency type in combination\n  with the given result set type?\n\n  @param type defined in <code>java.sql.ResultSet</code>\n  @param concurrency type defined in <code>java.sql.ResultSet</code>\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZInterbase6DatabaseInfo.SupportsResultSetConcurrency(\n  _Type: TZResultSetType; Concurrency: TZResultSetConcurrency): Boolean;\nbegin\n  Result := (_Type = rtScrollInsensitive) and (Concurrency = rcReadOnly);\nend;\n\n\n{ TZInterbase6DatabaseMetadata }\n\n{**\n  Constructs a database information object and returns the interface to it. Used\n  internally by the constructor.\n  @return the database information object interface\n}\nfunction TZInterbase6DatabaseMetadata.CreateDatabaseInfo: IZDatabaseInfo;\nbegin\n  Result := TZInterbase6DatabaseInfo.Create(Self);\nend;\n\nfunction TZInterbase6DatabaseMetadata.ConstructNameCondition(Pattern: string;\n  Column: string): string;\nbegin\n  Result := Inherited ConstructnameCondition(Pattern,'trim('+Column+')');\nend;\n\nfunction TZInterbase6DatabaseMetadata.UncachedGetTriggers(const Catalog: string;\n  const SchemaPattern: string; const TableNamePattern: string;\n  const TriggerNamePattern: string): IZResultSet;\nvar\n  SQL: string;\n  LTriggerNamePattern: string;\n  LTableNamePattern: string;\nbegin\n  Result:=inherited UncachedGetTriggers(Catalog, SchemaPattern, TableNamePattern, TriggerNamePattern);\n\n  LTriggerNamePattern := ConstructNameCondition(TriggerNamePattern,\n    'RDB$TRIGGER_NAME');\n  LTableNamePattern := ConstructNameCondition(TableNamePattern,\n    'RDB$RELATION_NAME');\n  If LTriggerNamePattern <> '' then\n    LTriggerNamePattern := ' and ' + LTriggerNamePattern;\n  If LTableNamePattern <> '' then\n    LTableNamePattern := ' and ' + LTableNamePattern;\n\n  SQL := 'SELECT RDB$TRIGGER_NAME, RDB$RELATION_NAME,'\n    + ' RDB$TRIGGER_TYPE, RDB$TRIGGER_INACTIVE,'\n    + ' RDB$TRIGGER_SOURCE, RDB$DESCRIPTION FROM RDB$TRIGGERS'\n    + ' WHERE 1=1' + LTriggerNamePattern + LTableNamePattern;\n\n  with GetConnection.CreateStatement.ExecuteQuery(SQL) do\n  begin\n    while Next do\n    begin\n      Result.MoveToInsertRow;\n      Result.UpdateNull(1);\n      Result.UpdateNull(2);\n      Result.UpdateString(3, GetString(1)); //RDB$TRIGGER_NAME\n      Result.UpdateString(4, GetString(2)); //RDB$RELATION_NAME\n      Result.UpdateShort(5, GetShort(3)); //RDB$TRIGGER_TYPE\n      Result.UpdateShort(6, GetShort(4)); //RDB$TRIGGER_INACTIVE\n      Result.UpdateString(7, GetString(5)); //RDB$TRIGGER_SOURCE\n      Result.UpdateString(8, GetString(6)); //RDB$DESCRIPTION\n      Result.InsertRow;\n    end;\n    Close;\n  end;\nend;\n\n\n{**\n  Gets a description of the stored procedures available in a\n  catalog.\n\n  <P>Only procedure descriptions matching the schema and\n  procedure name criteria are returned.  They are ordered by\n  PROCEDURE_SCHEM, and PROCEDURE_NAME.\n\n  <P>Each procedure description has the the following columns:\n   <OL>\n \t<LI><B>PROCEDURE_CAT</B> String => procedure catalog (may be null)\n \t<LI><B>PROCEDURE_SCHEM</B> String => procedure schema (may be null)\n \t<LI><B>PROCEDURE_NAME</B> String => procedure name\n   <LI> reserved for future use\n   <LI> reserved for future use\n   <LI> reserved for future use\n \t<LI><B>REMARKS</B> String => explanatory comment on the procedure\n \t<LI><B>PROCEDURE_TYPE</B> short => kind of procedure:\n       <UL>\n       <LI> procedureResultUnknown - May return a result\n       <LI> procedureNoResult - Does not return a result\n       <LI> procedureReturnsResult - Returns a result\n       </UL>\n   </OL>\n\n  @param catalog a catalog name; \"\" retrieves those without a\n  catalog; null means drop catalog name from the selection criteria\n  @param schemaPattern a schema name pattern; \"\" retrieves those\n  without a schema\n  @param procedureNamePattern a procedure name pattern\n  @return <code>ResultSet</code> - each row is a procedure description\n  @see #getSearchStringEscape\n}\nfunction TZInterbase6DatabaseMetadata.UncachedGetProcedures(const Catalog: string;\n  const SchemaPattern: string; const ProcedureNamePattern: string): IZResultSet;\nvar\n  SQL: string;\n  LProcedureNamePattern: string;\nbegin\n    Result:=inherited UncachedGetProcedures(Catalog, SchemaPattern, ProcedureNamePattern);\n\n    LProcedureNamePattern := ConstructNameCondition(ProcedureNamePattern,\n      'RDB$PROCEDURE_NAME');\n    If LProcedureNamePattern <> '' then\n      LProcedureNamePattern := ' and ' + LProcedureNamePattern;\n\n    SQL := 'SELECT RDB$PROCEDURE_NAME, RDB$PROCEDURE_OUTPUTS,'\n      + ' RDB$DESCRIPTION FROM RDB$PROCEDURES'\n      + ' WHERE 1=1' + LProcedureNamePattern;\n\n    with GetConnection.CreateStatement.ExecuteQuery(SQL) do\n    begin\n      while Next do\n      begin\n        Result.MoveToInsertRow;\n        Result.UpdateNull(1);\n        Result.UpdateNull(2);\n        Result.UpdateString(3, GetString(1)); //RDB$PROCEDURE_NAME\n        Result.UpdateNull(4);\n        Result.UpdateNull(5);\n        Result.UpdateNull(6);\n        Result.UpdateString(7, GetString(3)); //RDB$DESCRIPTION\n        if IsNull(2) then //RDB$PROCEDURE_OUTPUTS\n          Result.UpdateInt(8, Ord(prtNoResult))\n        else Result.UpdateInt(8, Ord(prtReturnsResult));\n        Result.InsertRow;\n      end;\n      Close;\n    end;\nend;\n\n{**\n  Gets a description of a catalog's stored procedure parameters\n  and result columns.\n\n  <P>Only descriptions matching the schema, procedure and\n  parameter name criteria are returned.  They are ordered by\n  PROCEDURE_SCHEM and PROCEDURE_NAME. Within this, the return value,\n  if any, is first. Next are the parameter descriptions in call\n  order. The column descriptions follow in column number order.\n\n  <P>Each row in the <code>ResultSet</code> is a parameter description or\n  column description with the following fields:\n   <OL>\n \t<LI><B>PROCEDURE_CAT</B> String => procedure catalog (may be null)\n \t<LI><B>PROCEDURE_SCHEM</B> String => procedure schema (may be null)\n \t<LI><B>PROCEDURE_NAME</B> String => procedure name\n \t<LI><B>COLUMN_NAME</B> String => column/parameter name\n \t<LI><B>COLUMN_TYPE</B> Short => kind of column/parameter:\n       <UL>\n       <LI> procedureColumnUnknown - nobody knows\n       <LI> procedureColumnIn - IN parameter\n       <LI> procedureColumnInOut - INOUT parameter\n       <LI> procedureColumnOut - OUT parameter\n       <LI> procedureColumnReturn - procedure return value\n       <LI> procedureColumnResult - result column in <code>ResultSet</code>\n       </UL>\n   <LI><B>DATA_TYPE</B> short => SQL type from java.sql.Types\n \t<LI><B>TYPE_NAME</B> String => SQL type name, for a UDT type the\n   type name is fully qualified\n \t<LI><B>PRECISION</B> int => precision\n \t<LI><B>LENGTH</B> int => length in bytes of data\n \t<LI><B>SCALE</B> short => scale\n \t<LI><B>RADIX</B> short => radix\n \t<LI><B>NULLABLE</B> short => can it contain NULL?\n       <UL>\n       <LI> procedureNoNulls - does not allow NULL values\n       <LI> procedureNullable - allows NULL values\n       <LI> procedureNullableUnknown - nullability unknown\n       </UL>\n \t<LI><B>REMARKS</B> String => comment describing parameter/column\n   </OL>\n\n  <P><B>Note:</B> Some databases may not return the column\n  descriptions for a procedure. Additional columns beyond\n  REMARKS can be defined by the database.\n\n  @param catalog a catalog name; \"\" retrieves those without a\n  catalog; null means drop catalog name from the selection criteria\n  @param schemaPattern a schema name pattern; \"\" retrieves those\n  without a schema\n  @param procedureNamePattern a procedure name pattern\n  @param columnNamePattern a column name pattern\n  @return <code>ResultSet</code> - each row describes a stored procedure parameter or\n       column\n  @see #getSearchStringEscape\n}\nfunction TZInterbase6DatabaseMetadata.UncachedGetProcedureColumns(const Catalog: string;\n  const SchemaPattern: string; const ProcedureNamePattern: string;\n  const ColumnNamePattern: string): IZResultSet;\nvar\n  SQL: string;\n  LProcedureNamePattern, LColumnNamePattern: string;\n  TypeName, SubTypeName: Integer;\n  ColumnIndexes : Array[1..8] of integer;\nbegin\n    Result:=inherited UncachedGetProcedureColumns(Catalog, SchemaPattern, ProcedureNamePattern, ColumnNamePattern);\n\n    LProcedureNamePattern := ConstructNameCondition(ProcedureNamePattern, \n      'P.RDB$PROCEDURE_NAME');\n    LColumnNamePattern := ConstructNameCondition(ColumnNamePattern,\n      'PP.RDB$PARAMETER_NAME');\n    If LProcedureNamePattern <> '' then\n      LProcedureNamePattern := ' and ' + LProcedureNamePattern;\n    If LColumnNamePattern <> '' then\n      LColumnNamePattern := ' and ' + LColumnNamePattern;\n\n  if (StrPos(PChar(GetDatabaseInfo.GetServerVersion), 'Interbase 5') <> nil)\n     or (StrPos(PChar(GetDatabaseInfo.GetServerVersion), 'V5.') <> nil) then\n    begin\n      SQL := ' SELECT P.RDB$PROCEDURE_NAME, PP.RDB$PARAMETER_NAME,'\n        + ' PP.RDB$PARAMETER_TYPE, F.RDB$FIELD_TYPE, F.RDB$FIELD_SUB_TYPE,'\n        + ' F.RDB$FIELD_SCALE, F.RDB$FIELD_LENGTH, F.RDB$NULL_FLAG,'\n        + ' PP.RDB$DESCRIPTION, F.RDB$FIELD_SCALE as RDB$FIELD_PRECISION,'\n        + ' F.RDB$NULL_FLAG FROM RDB$PROCEDURES P'\n        + ' JOIN RDB$PROCEDURE_PARAMETERS PP ON P.RDB$PROCEDURE_NAME'\n        + '=PP.RDB$PROCEDURE_NAME JOIN RDB$FIELDS F ON PP.RDB$FIELD_SOURCE'\n        + '=F.RDB$FIELD_NAME '\n        + ' WHERE 1=1' + LProcedureNamePattern + LColumnNamePattern\n        + ' ORDER BY  P.RDB$PROCEDURE_NAME,'\n        + ' PP.RDB$PARAMETER_TYPE, PP.RDB$PARAMETER_NUMBER';\n    end\n    else\n    begin\n      SQL := ' SELECT P.RDB$PROCEDURE_NAME, PP.RDB$PARAMETER_NAME,'\n        + ' PP.RDB$PARAMETER_TYPE, F.RDB$FIELD_TYPE, F.RDB$FIELD_SUB_TYPE,'\n        + ' F.RDB$FIELD_SCALE, F.RDB$FIELD_LENGTH, F.RDB$NULL_FLAG,'\n        + ' PP.RDB$DESCRIPTION, F.RDB$FIELD_PRECISION, F.RDB$NULL_FLAG '\n        + ' FROM RDB$PROCEDURES P JOIN RDB$PROCEDURE_PARAMETERS PP ON'\n        + ' P.RDB$PROCEDURE_NAME = PP.RDB$PROCEDURE_NAME '\n        + ' JOIN RDB$FIELDS F ON PP.RDB$FIELD_SOURCE = F.RDB$FIELD_NAME '\n        + ' WHERE 1=1' + LProcedureNamePattern + LColumnNamePattern\n        + ' ORDER BY  P.RDB$PROCEDURE_NAME,'\n        + ' PP.RDB$PARAMETER_TYPE, PP.RDB$PARAMETER_NUMBER';\n    end;\n\n    with GetConnection.CreateStatement.ExecuteQuery(SQL) do\n    begin\n      ColumnIndexes[1] := FindColumn('RDB$PROCEDURE_NAME');\n      ColumnIndexes[2] := FindColumn('RDB$PARAMETER_NAME');\n      ColumnIndexes[3] := FindColumn('RDB$PARAMETER_TYPE');\n      ColumnIndexes[4] := FindColumn('RDB$FIELD_TYPE');\n      ColumnIndexes[5] := FindColumn('RDB$FIELD_SUB_TYPE');\n      ColumnIndexes[6] := FindColumn('RDB$FIELD_PRECISION');\n      ColumnIndexes[7] := FindColumn('RDB$FIELD_SCALE');\n      ColumnIndexes[8] := FindColumn('RDB$NULL_FLAG');\n      while Next do\n      begin\n        TypeName := GetInt(ColumnIndexes[4]);\n        SubTypeName := GetInt(ColumnIndexes[5]);\n\n        Result.MoveToInsertRow;\n        Result.UpdateNull(1);    //PROCEDURE_CAT\n        Result.UpdateNull(2);    //PROCEDURE_SCHEM\n        Result.UpdateString(3, GetString(ColumnIndexes[1]));    //TABLE_NAME\n        Result.UpdateString(4, GetString(ColumnIndexes[2]));    //COLUMN_NAME\n        case GetInt(ColumnIndexes[3]) of\n          0: Result.UpdateInt(5, Ord(pctIn));\n          1: Result.UpdateInt(5, Ord(pctOut));\n        else\n            Result.UpdateInt(5, Ord(pctUnknown));\n        end;\n\n        Result.UpdateInt(6,\n          Ord(ConvertInterbase6ToSqlType(TypeName, SubTypeName,\n            ConSettings.CPType))); //DATA_TYPE\n        Result.UpdateString(7,GetString(ColumnIndexes[4]));    //TYPE_NAME\n        Result.UpdateInt(10, GetInt(ColumnIndexes[6]));\n        Result.UpdateNull(9);    //BUFFER_LENGTH\n        Result.UpdateInt(10, GetInt(ColumnIndexes[7]));\n        Result.UpdateInt(11, 10);\n        Result.UpdateInt(12, GetInt(ColumnIndexes[8]));\n        Result.UpdateString(12, GetString(ColumnIndexes[6]));\n        Result.InsertRow;\n      end;\n      Close;\n    end;\nend;\n\n{**\n  Gets a description of tables available in a catalog.\n\n  <P>Only table descriptions matching the catalog, schema, table\n  name and type criteria are returned.  They are ordered by\n  TABLE_TYPE, TABLE_SCHEM and TABLE_NAME.\n\n  <P>Each table description has the following columns:\n   <OL>\n \t<LI><B>TABLE_CAT</B> String => table catalog (may be null)\n \t<LI><B>TABLE_SCHEM</B> String => table schema (may be null)\n \t<LI><B>TABLE_NAME</B> String => table name\n \t<LI><B>TABLE_TYPE</B> String => table type.  Typical types are \"TABLE\",\n \t\t\t\"VIEW\",\t\"SYSTEM TABLE\", \"GLOBAL TEMPORARY\",\n \t\t\t\"LOCAL TEMPORARY\", \"ALIAS\", \"SYNONYM\".\n \t<LI><B>REMARKS</B> String => explanatory comment on the table\n   </OL>\n\n  <P><B>Note:</B> Some databases may not return information for\n  all tables.\n\n  @param catalog a catalog name; \"\" retrieves those without a\n  catalog; null means drop catalog name from the selection criteria\n  @param schemaPattern a schema name pattern; \"\" retrieves those\n  without a schema\n  @param tableNamePattern a table name pattern\n  @param types a list of table types to include; null returns all types\n  @return <code>ResultSet</code> - each row is a table description\n  @see #getSearchStringEscape\n}\n\nfunction TZInterbase6DatabaseMetadata.UncachedGetTables(const Catalog: string; \n  const SchemaPattern: string; const TableNamePattern: string; \n  const Types: TStringDynArray): IZResultSet; \nvar \n  SQL, TableType: string;\n  I, SystemFlag: Integer;\n  TableNameCondition: string;\n\nbegin \n    Result:=inherited UncachedGetTables(Catalog, SchemaPattern, TableNamePattern, Types);\n\n    TableNameCondition := ConstructNameCondition(TableNamePattern,\n      'a.RDB$RELATION_NAME');\n    If TableNameCondition <> '' then\n      TableNameCondition := ' and ' + TableNameCondition;\n\n    SQL := 'SELECT DISTINCT a.RDB$RELATION_NAME, a.RDB$SYSTEM_FLAG, ' \n      + ' a.RDB$VIEW_SOURCE, a.RDB$DESCRIPTION FROM RDB$RELATIONS a'\n      + ' WHERE 1=1' + TableNameCondition;\n\n    with GetConnection.CreateStatement.ExecuteQuery(SQL) do \n    begin    \n       while Next do \n      begin \n        SystemFlag := GetInt(2); //RDB$SYSTEM_FLAG\n\n        if SystemFlag = 0 then \n        begin \n          if IsNull(3) then //RDB$VIEW_SOURCE\n            TableType := 'TABLE' \n          else \n            TableType := 'VIEW'; \n        end\n        else\n          TableType := 'SYSTEM TABLE'; \n\n        if Length(Types) = 0 then \n        begin \n          Result.MoveToInsertRow; \n          Result.UpdateNull(1); \n          Result.UpdateNull(2); \n          Result.UpdateString(3, GetString(1)); //RDB$RELATION_NAME\n          Result.UpdateString(4, TableType);\n          Result.UpdateString(5, Copy(GetString(4),1,255)); //RDB$DESCRIPTION\n          Result.InsertRow;\n        end\n        else\n        begin\n          for I := 0 to High(Types) do\n          begin\n            if Types[I] = TableType then\n            begin\n              Result.MoveToInsertRow;\n              Result.UpdateNull(1);\n              Result.UpdateNull(2);\n              Result.UpdateString(3, GetString(1)); //RDB$RELATION_NAME\n              Result.UpdateString(4, TableType);\n              Result.UpdateString(5, Copy(GetString(4),1,255)); //RDB$DESCRIPTION \n              Result.InsertRow; \n            end; \n          end; \n        end; \n            \n      end; \n      Close; \n    end; \nend; \n\n{**\n  Gets the table types available in this database.  The results\n  are ordered by table type.\n\n  <P>The table type is:\n   <OL>\n \t<LI><B>TABLE_TYPE</B> String => table type.  Typical types are \"TABLE\",\n \t\t\t\"VIEW\",\t\"SYSTEM TABLE\", \"GLOBAL TEMPORARY\",\n \t\t\t\"LOCAL TEMPORARY\", \"ALIAS\", \"SYNONYM\".\n   </OL>\n\n  @return <code>ResultSet</code> - each row has a single String column that is a\n  table type\n}\nfunction TZInterbase6DatabaseMetadata.UncachedGetTableTypes: IZResultSet;\nconst\n  TablesTypes: array [0..2] of String = ('TABLE', 'VIEW', 'SYSTEM TABLE');\nvar\n  I: Integer;\nbegin\n  Result:=inherited UncachedGetTableTypes;\n\n  for I := 0 to 2 do\n    begin\n      Result.MoveToInsertRow;\n      Result.UpdateString(1, TablesTypes[I]);\n      Result.InsertRow;\n    end;\nend;\n\n{**\n  Gets a description of table columns available in\n  the specified catalog.\n\n  <P>Only column descriptions matching the catalog, schema, table\n  and column name criteria are returned.  They are ordered by\n  TABLE_SCHEM, TABLE_NAME and ORDINAL_POSITION.\n\n  <P>Each column description has the following columns:\n   <OL>\n \t<LI><B>TABLE_CAT</B> String => table catalog (may be null)\n \t<LI><B>TABLE_SCHEM</B> String => table schema (may be null)\n \t<LI><B>TABLE_NAME</B> String => table name\n \t<LI><B>COLUMN_NAME</B> String => column name\n \t<LI><B>DATA_TYPE</B> short => SQL type from java.sql.Types\n \t<LI><B>TYPE_NAME</B> String => Data source dependent type name,\n   for a UDT the type name is fully qualified\n \t<LI><B>COLUMN_SIZE</B> int => column size.  For char or date\n \t    types this is the maximum number of characters, for numeric or\n \t    decimal types this is precision.\n \t<LI><B>BUFFER_LENGTH</B> is not used.\n \t<LI><B>DECIMAL_DIGITS</B> int => the number of fractional digits\n \t<LI><B>NUM_PREC_RADIX</B> int => Radix (typically either 10 or 2)\n \t<LI><B>NULLABLE</B> int => is NULL allowed?\n       <UL>\n       <LI> columnNoNulls - might not allow NULL values\n       <LI> columnNullable - definitely allows NULL values\n       <LI> columnNullableUnknown - nullability unknown\n       </UL>\n \t<LI><B>REMARKS</B> String => comment describing column (may be null)\n \t<LI><B>COLUMN_DEF</B> String => default value (may be null)\n \t<LI><B>SQL_DATA_TYPE</B> int => unused\n \t<LI><B>SQL_DATETIME_SUB</B> int => unused\n \t<LI><B>CHAR_OCTET_LENGTH</B> int => for char types the\n        maximum number of bytes in the column\n \t<LI><B>ORDINAL_POSITION</B> int\t=> index of column in table\n       (starting at 1)\n \t<LI><B>IS_NULLABLE</B> String => \"NO\" means column definitely\n       does not allow NULL values; \"YES\" means the column might\n       allow NULL values.  An empty string means nobody knows.\n   </OL>\n\n  @param catalog a catalog name; \"\" retrieves those without a\n  catalog; null means drop catalog name from the selection criteria\n  @param schemaPattern a schema name pattern; \"\" retrieves those\n  without a schema\n  @param tableNamePattern a table name pattern\n  @param columnNamePattern a column name pattern\n  @return <code>ResultSet</code> - each row is a column description\n  @see #getSearchStringEscape\n}\n\nfunction TZInterbase6DatabaseMetadata.UncachedGetColumns(const Catalog: string;\n  const SchemaPattern: string; const TableNamePattern: string;\n  const ColumnNamePattern: string): IZResultSet;\nvar\n  SQL, ColumnName, DefaultValue: String;\n  TypeName, SubTypeName, FieldScale: integer;\n  LTableNamePattern, LColumnNamePattern: string;\n  ColumnIndexes : Array[1..15] of integer;\n  SQLType: TZSQLType;\nbegin\n    Result:=inherited UncachedGetColumns(Catalog, SchemaPattern, TableNamePattern, ColumnNamePattern);\n\n    LTableNamePattern := ConstructNameCondition(TableNamePattern,\n      'a.RDB$RELATION_NAME');\n    LColumnNamePattern := ConstructNameCondition(ColumnNamePattern,\n      'a.RDB$FIELD_NAME');\n    If LTableNamePattern <> '' then\n      LTableNamePattern := ' and ' + LTableNamePattern;\n    If LColumnNamePattern <> '' then\n      LColumnNamePattern := ' and ' + LColumnNamePattern;\n\n  if (StrPos(PChar(GetDatabaseInfo.GetServerVersion), 'Interbase 5') <> nil)\n     or (StrPos(PChar(GetDatabaseInfo.GetServerVersion), 'V5.') <> nil) then\n    begin\n      SQL := 'SELECT a.RDB$RELATION_NAME, a.RDB$FIELD_NAME, a.RDB$FIELD_POSITION,'\n        + ' a.RDB$NULL_FLAG, b. RDB$FIELD_LENGTH, b.RDB$FIELD_SCALE,'\n        + ' c.RDB$TYPE_NAME, b.RDB$FIELD_TYPE, b.RDB$FIELD_SUB_TYPE,'\n        + ' b.RDB$DESCRIPTION, b.RDB$CHARACTER_LENGTH, b.RDB$FIELD_SCALE'\n        + ' as RDB$FIELD_PRECISION, a.RDB$DEFAULT_SOURCE, b.RDB$DEFAULT_SOURCE'\n        + ' as RDB$DEFAULT_SOURCE_DOMAIN, b.RDB$COMPUTED_SOURCE as RDB$COMPUTED_SOURCE'\n        + ' , b.RDB$CHARACTER_SET_ID FROM RDB$RELATION_FIELDS a'\n        + ' JOIN RDB$FIELDS b ON (b.RDB$FIELD_NAME = a.RDB$FIELD_SOURCE)'\n        + ' LEFT JOIN RDB$TYPES c ON b.RDB$FIELD_TYPE = c.RDB$TYPE'\n        + ' and c.RDB$FIELD_NAME = ''RDB$FIELD_TYPE'''\n        + ' WHERE 1=1' + LTableNamePattern + LColumnNamePattern\n        + ' ORDER BY a.RDB$RELATION_NAME, a.RDB$FIELD_POSITION';\n    end\n    else\n    begin\n      SQL := ' SELECT a.RDB$RELATION_NAME, a.RDB$FIELD_NAME, a.RDB$FIELD_POSITION,'\n        + ' a.RDB$NULL_FLAG, a.RDB$DEFAULT_VALUE, b. RDB$FIELD_LENGTH,'\n        + ' b.RDB$FIELD_SCALE, c.RDB$TYPE_NAME, b.RDB$FIELD_TYPE,'\n        + ' b.RDB$FIELD_SUB_TYPE, b.RDB$DESCRIPTION, b.RDB$CHARACTER_LENGTH,'\n        + ' b.RDB$FIELD_PRECISION, a.RDB$DEFAULT_SOURCE, b.RDB$DEFAULT_SOURCE'\n        + ' as RDB$DEFAULT_SOURCE_DOMAIN,b.RDB$COMPUTED_SOURCE as RDB$COMPUTED_SOURCE'\n        + ' , b.RDB$CHARACTER_SET_ID FROM RDB$RELATION_FIELDS a'\n        + ' JOIN RDB$FIELDS b ON (b.RDB$FIELD_NAME = a.RDB$FIELD_SOURCE)'\n        + ' LEFT JOIN RDB$TYPES c ON (b.RDB$FIELD_TYPE = c.RDB$TYPE'\n        + ' and c.RDB$FIELD_NAME = ''RDB$FIELD_TYPE'')'\n        + ' WHERE 1=1' + LTableNamePattern + LColumnNamePattern\n        + ' ORDER BY a.RDB$RELATION_NAME, a.RDB$FIELD_POSITION';\n    end;\n\n    with GetConnection.CreateStatement.ExecuteQuery(SQL) do\n    begin\n      ColumnIndexes[1] := FindColumn('RDB$FIELD_TYPE');\n      ColumnIndexes[2] := FindColumn('RDB$FIELD_SUB_TYPE');\n      ColumnIndexes[3] := FindColumn('RDB$FIELD_SCALE');\n      ColumnIndexes[4] := FindColumn('RDB$FIELD_NAME');\n      ColumnIndexes[5] := FindColumn('RDB$DEFAULT_SOURCE');\n      ColumnIndexes[6] := FindColumn('RDB$DEFAULT_SOURCE_DOMAIN');\n      ColumnIndexes[7] := FindColumn('RDB$RELATION_NAME');\n      ColumnIndexes[8] := FindColumn('RDB$TYPE_NAME');\n      ColumnIndexes[9] := FindColumn('RDB$FIELD_PRECISION');\n      ColumnIndexes[10] := FindColumn('RDB$FIELD_LENGTH');\n      ColumnIndexes[11] := FindColumn('RDB$NULL_FLAG');\n      ColumnIndexes[12] := FindColumn('RDB$DESCRIPTION');\n      ColumnIndexes[13] := FindColumn('RDB$FIELD_POSITION');\n      ColumnIndexes[14] := FindColumn('RDB$COMPUTED_SOURCE');\n      ColumnIndexes[15] := FindColumn('RDB$CHARACTER_SET_ID');\n      while Next do\n      begin\n        TypeName := GetInt(ColumnIndexes[1]);\n        if TypeName = 14 then //'TEXT'\n          SubTypeName := GetInt(ColumnIndexes[15]) //need a way to determine CS_Binary (octets) for stBytes on the other hand the subtype is useless here\n        else\n          SubTypeName := GetInt(ColumnIndexes[2]);\n        FieldScale := GetInt(ColumnIndexes[3]);\n        ColumnName := GetString(ColumnIndexes[4]);\n\n        if (GetString(ColumnIndexes[14]) <> '') then  //AVZ -- not isNull(14) was not working correcly here could be ' ' - subselect\n        begin //Computed by Source  & Sub Selects  //AVZ\n          if ((TypeName = 16) and (FieldScale < 0)) then SubTypeName := 1; // Fix for 0 subtype which removes decimals\n        end;\n\n        DefaultValue := GetString(ColumnIndexes[5]);\n        if DefaultValue = '' then\n          DefaultValue := GetString(ColumnIndexes[6]);\n        if StartsWith(Trim(UpperCase(DefaultValue)), 'DEFAULT') then\n        begin\n          DefaultValue := Trim(StringReplace(DefaultValue, 'DEFAULT ', '',\n            [rfIgnoreCase]));\n        end;\n\n        IF (UpperCase(DefaultValue)= '''NOW''') or (UpperCase(DefaultValue)= '\"NOW\"')then\n          case TypeName of\n          12: DefaultValue := 'CURRENT_DATE';\n          13: DefaultValue := 'CURRENT_TIME';\n          35: DefaultValue := 'CURRENT_TIMESTAMP';\n          else begin end;\n          end;\n\n        Result.MoveToInsertRow;\n        Result.UpdateNull(1);    //TABLE_CAT\n        Result.UpdateNull(2);    //TABLE_SCHEM\n        Result.UpdateString(3, GetString(ColumnIndexes[7]));    //TABLE_NAME\n        Result.UpdateString(4, ColumnName);    //COLUMN_NAME\n        SQLType := ConvertInterbase6ToSqlType(TypeName, SubTypeName\n          , ConSettings.CPType);\n        Result.UpdateInt(5, Ord(SQLType));\n        // TYPE_NAME\n        case TypeName of\n          7  : Result.UpdateString(6, 'SMALLINT');\n          8  : Result.UpdateString(6, 'INTEGER' );\n          16 :\n            begin\n              if (SubTypeName = 0) then\n                Result.UpdateString(6, GetString(ColumnIndexes[8]));\n              if (SubTypeName = 1) then\n                Result.UpdateString(6, 'NUMERIC');\n              if (SubTypeName = 2) then\n                Result.UpdateString(6, 'DECIMAL');\n            end;\n          37 : Result.UpdateString(6, 'VARCHAR'); // Instead of VARYING\n        else\n            Result.UpdateString(6, GetString(ColumnIndexes[8]));\n        end;\n        // COLUMN_SIZE.\n        case TypeName of\n          7, 8 : Result.UpdateInt(7, 0);\n          16   : Result.UpdateInt(7, GetInt(ColumnIndexes[9]));\n          37, 38: Result.UpdateNull(7);  //the defaults of the resultsets will be used if null\n            {if ( ConSettings.ClientCodePage.ID = 0 ) then //CharcterSet 'NONE'\n              Result.UpdateInt(7, GetFieldSize(SQLType, ConSettings,\n                GetInt(ColumnIndexes[10]), GetConnection.GetIZPlainDriver.ValidateCharEncoding(SubTypeName).CharWidth, nil, True)) //FireBird return Char*Bytes for Varchar\n            else\n              Result.UpdateInt(7, GetFieldSize(SQLType, ConSettings,\n                GetInt(ColumnIndexes[10]), ConSettings.ClientCodePage.CharWidth, nil, True)); //FireBird return Char*Bytes for Varchar}\n        else\n          Result.UpdateInt(7, GetInt(ColumnIndexes[10]));\n        end;\n\n        Result.UpdateNull(8);    //BUFFER_LENGTH\n\n        if FieldScale < 0 then\n          Result.UpdateInt(9, -1 * FieldScale)    //DECIMAL_DIGITS\n        else\n          Result.UpdateInt(9, 0); //DECIMAL_DIGITS\n\n        Result.UpdateInt(10, 10);   //NUM_PREC_RADIX\n\n        if GetInt(ColumnIndexes[11]) <> 0 then\n          Result.UpdateInt(11, Ord(ntNoNulls))   //NULLABLE\n        else\n          Result.UpdateInt(11, Ord(ntNullable));\n\n        Result.UpdateString(12, Copy(GetString(ColumnIndexes[12]),1,255));   //REMARKS\n        Result.UpdateString(13, DefaultValue);   //COLUMN_DEF\n        Result.UpdateNull(14);   //SQL_DATA_TYPE\n        Result.UpdateNull(15);   //SQL_DATETIME_SUB\n        Result.UpdateInt(16,\n          GetInt(7));   //CHAR_OCTET_LENGTH\n        Result.UpdateInt(17, GetInt(ColumnIndexes[13]) + 1);   //ORDINAL_POSITION\n\n        if IsNull(ColumnIndexes[11]) then\n          Result.UpdateString(18, 'YES')   //IS_NULLABLE\n        else\n          Result.UpdateString(18, 'NO'); //IS_NULLABLE\n\n        Result.UpdateNull(19); //AUTO_INCREMENT\n\n        if CompareStr(ColumnName, UpperCase(ColumnName)) = 0 then\n          Result.UpdateBoolean(20, False) //CASE_SENSITIVE\n        else\n          Result.UpdateBoolean(20, True); //CASE_SENSITIVE\n\n        Result.UpdateBoolean(21, True); //SEARCHABLE\n        if isNull(ColumnIndexes[14]) then\n          begin\n            Result.UpdateBoolean(22, True); //WRITABLE\n            Result.UpdateBoolean(23, True); //DEFINITELYWRITABLE\n            Result.UpdateBoolean(24, False); //READONLY\n          end\n        else\n          begin\n            Result.UpdateBoolean(22, False); //WRITABLE\n            Result.UpdateBoolean(23, False); //DEFINITELYWRITABLE\n            Result.UpdateBoolean(24, True); //READONLY\n          end;\n        Result.InsertRow;\n      end;\n      Close;\n    end;\nend;\n\n{**\n  Gets a description of the access rights for a table's columns.\n\n  <P>Only privileges matching the column name criteria are\n  returned.  They are ordered by COLUMN_NAME and PRIVILEGE.\n\n  <P>Each privilige description has the following columns:\n   <OL>\n \t<LI><B>TABLE_CAT</B> String => table catalog (may be null)\n \t<LI><B>TABLE_SCHEM</B> String => table schema (may be null)\n \t<LI><B>TABLE_NAME</B> String => table name\n \t<LI><B>COLUMN_NAME</B> String => column name\n \t<LI><B>GRANTOR</B> => grantor of access (may be null)\n \t<LI><B>GRANTEE</B> String => grantee of access\n \t<LI><B>PRIVILEGE</B> String => name of access (SELECT,\n       INSERT, UPDATE, REFRENCES, ...)\n \t<LI><B>IS_GRANTABLE</B> String => \"YES\" if grantee is permitted\n       to grant to others; \"NO\" if not; null if unknown\n   </OL>\n\n  @param catalog a catalog name; \"\" retrieves those without a\n  catalog; null means drop catalog name from the selection criteria\n  @param schema a schema name; \"\" retrieves those without a schema\n  @param table a table name\n  @param columnNamePattern a column name pattern\n  @return <code>ResultSet</code> - each row is a column privilege description\n  @see #getSearchStringEscape\n}\nfunction TZInterbase6DatabaseMetadata.UncachedGetColumnPrivileges(const Catalog: string;\n  const Schema: string; const Table: string; const ColumnNamePattern: string): IZResultSet;\nvar\n  SQL: string;\n  TableName, FieldName, Privilege: String;\n  Grantor, Grantee, Grantable: String;\n  LColumnNamePattern, LTable: String;\nbegin\n    Result:=inherited UncachedGetColumnPrivileges(Catalog, Schema, Table, ColumnNamePattern);\n\n    LTable := ConstructNameCondition(AddEscapeCharToWildcards(Table), 'a.RDB$RELATION_NAME');\n    LColumnNamePattern := ConstructNameCondition(ColumnNamePattern, 'a.RDB$FIELD_NAME');\n    if LTable <> '' then\n      LTable := ' and ' + LTable;\n    if LColumnNamePattern <> '' then\n      LColumnNamePattern := ' and ' + LColumnNamePattern;\n\n    SQL := 'SELECT a.RDB$USER, a.RDB$GRANTOR, a.RDB$PRIVILEGE,'\n      + ' a.RDB$GRANT_OPTION, a.RDB$RELATION_NAME, a.RDB$FIELD_NAME '\n      + ' FROM RDB$USER_PRIVILEGES a, RDB$TYPES b '\n      + ' WHERE a.RDB$OBJECT_TYPE = b.RDB$TYPE '\n      + LTable + LColumnNamePattern\n      + ' and b.RDB$TYPE_NAME IN (''RELATION'', ''VIEW'','\n      + ' ''COMPUTED_FIELD'', ''FIELD'' ) AND b.RDB$FIELD_NAME'\n      + '=''RDB$OBJECT_TYPE'' ORDER BY a.RDB$FIELD_NAME, a.RDB$PRIVILEGE  ' ;\n\n    with GetConnection.CreateStatement.ExecuteQuery(SQL) do\n    begin\n      while Next do\n      begin\n\n        TableName := GetString(5); //RDB$RELATION_NAME\n        FieldName := GetString(6); //RDB$FIELD_NAME\n        Privilege := GetPrivilege(GetString(3)); //RDB$PRIVILEGE\n        Grantor := GetString(2); //RDB$GRANTOR\n        Grantee := GetString(1); //RDB$USER\n        if Grantor = Grantee then\n          Grantable := 'YES'\n        else\n          Grantable := 'NO';\n        if FieldName = '' then\n        begin\n          LTable := ConstructNameCondition(TableName, 'a.RDB$RELATION_NAME');\n          SQL := 'SELECT RDB$FIELD_NAME FROM RDB$RELATION_FIELDS A'\n            + ' WHERE ' + LTable + LColumnNamePattern;\n          with GetConnection.CreateStatement.ExecuteQuery(SQL) do\n          begin\n            while Next do\n            begin\n              Result.MoveToInsertRow;\n              Result.UpdateNull(1);\n              Result.UpdateNull(2);\n              Result.UpdateString(3, TableName);\n              Result.UpdateString(4, GetString(1));\n              Result.UpdateString(5, Grantor);\n              Result.UpdateString(6, Grantee);\n              Result.UpdateString(7, Privilege);\n              Result.UpdateString(8, Grantable);\n              Result.InsertRow;\n            end;\n            Close;\n          end;\n        end\n        else\n        begin\n          Result.MoveToInsertRow;\n          Result.UpdateNull(1);\n          Result.UpdateNull(2);\n          Result.UpdateString(3, TableName);\n          Result.UpdateString(4, FieldName);\n          Result.UpdateString(5, Grantor);\n          Result.UpdateString(6, Grantee);\n          Result.UpdateString(7, Privilege);\n          Result.UpdateString(8, Grantable);\n          Result.InsertRow;\n        end;\n      end;\n      Close;\n    end;\nend;\n\n{**\n  Gets a description of the access rights for each table available\n  in a catalog. Note that a table privilege applies to one or\n  more columns in the table. It would be wrong to assume that\n  this priviledge applies to all columns (this may be true for\n  some systems but is not true for all.)\n\n  <P>Only privileges matching the schema and table name\n  criteria are returned.  They are ordered by TABLE_SCHEM,\n  TABLE_NAME, and PRIVILEGE.\n\n  <P>Each privilige description has the following columns:\n   <OL>\n \t<LI><B>TABLE_CAT</B> String => table catalog (may be null)\n \t<LI><B>TABLE_SCHEM</B> String => table schema (may be null)\n \t<LI><B>TABLE_NAME</B> String => table name\n \t<LI><B>GRANTOR</B> => grantor of access (may be null)\n \t<LI><B>GRANTEE</B> String => grantee of access\n \t<LI><B>PRIVILEGE</B> String => name of access (SELECT,\n       INSERT, UPDATE, REFRENCES, ...)\n \t<LI><B>IS_GRANTABLE</B> String => \"YES\" if grantee is permitted\n       to grant to others; \"NO\" if not; null if unknown\n   </OL>\n\n  @param catalog a catalog name; \"\" retrieves those without a\n  catalog; null means drop catalog name from the selection criteria\n  @param schemaPattern a schema name pattern; \"\" retrieves those\n  without a schema\n  @param tableNamePattern a table name pattern\n  @return <code>ResultSet</code> - each row is a table privilege description\n  @see #getSearchStringEscape\n}\nfunction TZInterbase6DatabaseMetadata.UncachedGetTablePrivileges(const Catalog: string;\n  const SchemaPattern: string; const TableNamePattern: string): IZResultSet;\nvar\n  SQL: string;\n  TableName, Privilege, Grantor: String;\n  Grantee, Grantable: String;\n  LTableNamePattern: String;\nbegin\n    Result:=inherited UncachedGetTablePrivileges(Catalog, SchemaPattern, TableNamePattern);\n\n    LTableNamePattern := ConstructNameCondition(TableNamePattern, 'a.RDB$RELATION_NAME');\n    if LTableNamePattern <> '' then\n      LTableNamePattern := ' and ' + LTableNamePattern;\n\n    SQL := 'SELECT a.RDB$USER, a.RDB$GRANTOR, a.RDB$PRIVILEGE,'\n      + ' a.RDB$GRANT_OPTION, a.RDB$RELATION_NAME FROM RDB$USER_PRIVILEGES a,'\n      + ' RDB$TYPES b WHERE a.RDB$OBJECT_TYPE = b.RDB$TYPE AND '\n      + ' b.RDB$TYPE_NAME IN (''RELATION'', ''VIEW'', ''COMPUTED_FIELD'','\n      + ' ''FIELD'' ) AND a.RDB$FIELD_NAME IS NULL '+ LTableNamePattern\n      + ' ORDER BY a.RDB$RELATION_NAME, a.RDB$PRIVILEGE';\n\n    with GetConnection.CreateStatement.ExecuteQuery(SQL) do\n    begin\n      while Next do\n      begin\n        TableName := GetString(5); //RDB$RELATION_NAME\n        Privilege := GetPrivilege(GetString(3)); //RDB$PRIVILEGE\n        Grantor := GetString(2); //RDB$GRANTOR\n        Grantee := GetString(1); //RDB$USER\n\n        if Grantor = Grantee then\n          Grantable := 'YES'\n        else\n          Grantable := 'NO';\n\n        Result.MoveToInsertRow;\n        Result.UpdateNull(1);\n        Result.UpdateNull(2);\n        Result.UpdateString(3, TableName);\n        Result.UpdateString(4, Grantor);\n        Result.UpdateString(5, Grantee);\n        Result.UpdateString(6, Privilege);\n        Result.UpdateString(7, Grantable);\n        Result.InsertRow;\n      end;\n      Close;\n    end;\nend;\n\n{**\n  Gets a description of a table's columns that are automatically\n  updated when any value in a row is updated.  They are\n  unordered.\n\n  <P>Each column description has the following columns:\n   <OL>\n \t<LI><B>SCOPE</B> short => is not used\n \t<LI><B>COLUMN_NAME</B> String => column name\n \t<LI><B>DATA_TYPE</B> short => SQL data type from java.sql.Types\n \t<LI><B>TYPE_NAME</B> String => Data source dependent type name\n \t<LI><B>COLUMN_SIZE</B> int => precision\n \t<LI><B>BUFFER_LENGTH</B> int => length of column value in bytes\n \t<LI><B>DECIMAL_DIGITS</B> short\t => scale\n \t<LI><B>PSEUDO_COLUMN</B> short => is this a pseudo column\n       like an Oracle ROWID\n       <UL>\n       <LI> versionColumnUnknown - may or may not be pseudo column\n       <LI> versionColumnNotPseudo - is NOT a pseudo column\n       <LI> versionColumnPseudo - is a pseudo column\n       </UL>\n   </OL>\n\n  @param catalog a catalog name; \"\" retrieves those without a\n  catalog; null means drop catalog name from the selection criteria\n  @param schema a schema name; \"\" retrieves those without a schema\n  @param table a table name\n  @return <code>ResultSet</code> - each row is a column description\n  @exception SQLException if a database access error occurs\n}\nfunction TZInterbase6DatabaseMetadata.UncachedGetVersionColumns(const Catalog: string;\n  const Schema: string; const Table: string): IZResultSet;\nbegin\n    Result:=inherited UncachedGetVersionColumns(Catalog, Schema, Table);\n\n    Result.MoveToInsertRow;\n    Result.UpdateNull(1);\n    Result.UpdateString(2, 'ctid');\n    //  Result.UpdateInt(3, GetSQLType('tid')); //FIX IT\n    Result.UpdateString(4, 'tid');\n    Result.UpdateNull(5);\n    Result.UpdateNull(6);\n    Result.UpdateNull(7);\n    Result.UpdateInt(4, Ord(vcPseudo));\n    Result.InsertRow;\nend;\n\n{**\n  Gets a description of a table's primary key columns.  They\n  are ordered by COLUMN_NAME.\n\n  <P>Each primary key column description has the following columns:\n   <OL>\n \t<LI><B>TABLE_CAT</B> String => table catalog (may be null)\n \t<LI><B>TABLE_SCHEM</B> String => table schema (may be null)\n \t<LI><B>TABLE_NAME</B> String => table name\n \t<LI><B>COLUMN_NAME</B> String => column name\n \t<LI><B>KEY_SEQ</B> short => sequence number within primary key\n \t<LI><B>PK_NAME</B> String => primary key name (may be null)\n   </OL>\n\n  @param catalog a catalog name; \"\" retrieves those without a\n  catalog; null means drop catalog name from the selection criteria\n  @param schema a schema name; \"\" retrieves those\n  without a schema\n  @param table a table name\n  @return <code>ResultSet</code> - each row is a primary key column description\n  @exception SQLException if a database access error occurs\n}\nfunction TZInterbase6DatabaseMetadata.UncachedGetPrimaryKeys(const Catalog: string;\n  const Schema: string; const Table: string): IZResultSet;\nvar\n  SQL: string;\n  LTable: string;\nbegin\n    LTable := ConstructNameCondition(AddEscapeCharToWildcards(Table), 'a.RDB$RELATION_NAME');\n    if LTable <> '' then\n      LTable := ' AND ' + LTable;\n\n    SQL := ' SELECT null as TABLE_CAT, null as TABLE_SCHEM,'\n      + ' a.RDB$RELATION_NAME as TABLE_NAME, b.RDB$FIELD_NAME as COLUMN_NAME,'\n      + ' b.RDB$FIELD_POSITION+1 as KEY_SEQ, a.RDB$INDEX_NAME as PK_NAME'\n      + ' FROM RDB$RELATION_CONSTRAINTS a JOIN RDB$INDEX_SEGMENTS b ON'\n      + ' (a.RDB$INDEX_NAME = b.RDB$INDEX_NAME)'\n      + ' WHERE  RDB$CONSTRAINT_TYPE = ''PRIMARY KEY''' + LTable\n      + ' ORDER BY a.RDB$RELATION_NAME, b.RDB$FIELD_NAME';\n\n    Result := CopyToVirtualResultSet(\n      GetConnection.CreateStatement.ExecuteQuery(SQL),\n      ConstructVirtualResultSet(PrimaryKeyColumnsDynArray));\nend;\n\n{**\n  Gets a description of the primary key columns that are\n  referenced by a table's foreign key columns (the primary keys\n  imported by a table).  They are ordered by PKTABLE_CAT,\n  PKTABLE_SCHEM, PKTABLE_NAME, and KEY_SEQ.\n\n  <P>Each primary key column description has the following columns:\n   <OL>\n \t<LI><B>PKTABLE_CAT</B> String => primary key table catalog\n       being imported (may be null)\n \t<LI><B>PKTABLE_SCHEM</B> String => primary key table schema\n       being imported (may be null)\n \t<LI><B>PKTABLE_NAME</B> String => primary key table name\n       being imported\n \t<LI><B>PKCOLUMN_NAME</B> String => primary key column name\n       being imported\n \t<LI><B>FKTABLE_CAT</B> String => foreign key table catalog (may be null)\n \t<LI><B>FKTABLE_SCHEM</B> String => foreign key table schema (may be null)\n \t<LI><B>FKTABLE_NAME</B> String => foreign key table name\n \t<LI><B>FKCOLUMN_NAME</B> String => foreign key column name\n \t<LI><B>KEY_SEQ</B> short => sequence number within foreign key\n \t<LI><B>UPDATE_RULE</B> short => What happens to\n        foreign key when primary is updated:\n       <UL>\n       <LI> importedNoAction - do not allow update of primary\n                key if it has been imported\n       <LI> importedKeyCascade - change imported key to agree\n                with primary key update\n       <LI> importedKeySetNull - change imported key to NULL if\n                its primary key has been updated\n       <LI> importedKeySetDefault - change imported key to default values\n                if its primary key has been updated\n       <LI> importedKeyRestrict - same as importedKeyNoAction\n                                  (for ODBC 2.x compatibility)\n       </UL>\n \t<LI><B>DELETE_RULE</B> short => What happens to\n       the foreign key when primary is deleted.\n       <UL>\n       <LI> importedKeyNoAction - do not allow delete of primary\n                key if it has been imported\n       <LI> importedKeyCascade - delete rows that import a deleted key\n       <LI> importedKeySetNull - change imported key to NULL if\n                its primary key has been deleted\n       <LI> importedKeyRestrict - same as importedKeyNoAction\n                                  (for ODBC 2.x compatibility)\n       <LI> importedKeySetDefault - change imported key to default if\n                its primary key has been deleted\n       </UL>\n \t<LI><B>FK_NAME</B> String => foreign key name (may be null)\n \t<LI><B>PK_NAME</B> String => primary key name (may be null)\n \t<LI><B>DEFERRABILITY</B> short => can the evaluation of foreign key\n       constraints be deferred until commit\n       <UL>\n       <LI> importedKeyInitiallyDeferred - see SQL92 for definition\n       <LI> importedKeyInitiallyImmediate - see SQL92 for definition\n       <LI> importedKeyNotDeferrable - see SQL92 for definition\n       </UL>\n   </OL>\n\n  @param catalog a catalog name; \"\" retrieves those without a\n  catalog; null means drop catalog name from the selection criteria\n  @param schema a schema name; \"\" retrieves those\n  without a schema\n  @param table a table name\n  @return <code>ResultSet</code> - each row is a primary key column description\n  @see #getExportedKeys\n}\nfunction TZInterbase6DatabaseMetadata.UncachedGetImportedKeys(const Catalog: string;\n  const Schema: string; const Table: string): IZResultSet;\nvar\n  SQL: string;\n  LTable: string;\nbegin\n    Result:=inherited UncachedGetImportedKeys(Catalog, Schema, Table);\n\n    LTable := ConstructNameCondition(AddEscapeCharToWildcards(Table), 'RELC_FOR.RDB$RELATION_NAME'); // Modified by cipto 6/11/2007 4:53:02 PM \n    if LTable <> '' then\n      LTable := ' AND ' + LTable;\n\n    SQL := 'SELECT RELC_PRIM.RDB$RELATION_NAME, '    // 1 prim.RDB$ key table name\n      + ' IS_PRIM.RDB$FIELD_NAME, '         // 2 prim.RDB$ key column name\n      + ' RELC_FOR.RDB$RELATION_NAME, '     // 3 foreign key table name\n      + ' IS_FOR.RDB$FIELD_NAME, '          // 4 foreign key column name\n      + ' IS_FOR.RDB$FIELD_POSITION, '      // 5 key sequence\n      + ' REFC_PRIM.RDB$UPDATE_RULE, '      // 6\n      + ' REFC_PRIM.RDB$DELETE_RULE, '      // 7\n      + ' RELC_FOR.RDB$CONSTRAINT_NAME, '   // 8 foreign key constraint name\n      + ' RELC_PRIM.RDB$CONSTRAINT_NAME '   // 9 primary key constraint name\n      + ' FROM RDB$RELATION_CONSTRAINTS RELC_FOR, RDB$REF_CONSTRAINTS REFC_FOR, '\n      + ' RDB$RELATION_CONSTRAINTS RELC_PRIM, RDB$REF_CONSTRAINTS REFC_PRIM, '\n      + ' RDB$INDEX_SEGMENTS IS_PRIM,  RDB$INDEX_SEGMENTS IS_FOR '\n      + ' WHERE RELC_FOR.RDB$CONSTRAINT_TYPE = ''FOREIGN KEY'' ' + LTable\n      + ' AND RELC_FOR.RDB$CONSTRAINT_NAME=REFC_FOR.RDB$CONSTRAINT_NAME'\n      + ' and REFC_FOR.RDB$CONST_NAME_UQ = RELC_PRIM.RDB$CONSTRAINT_NAME and '\n      + ' RELC_PRIM.RDB$CONSTRAINT_TYPE = ''PRIMARY KEY'' and ' // useful check, anyay\n      + ' RELC_PRIM.RDB$INDEX_NAME = IS_PRIM.RDB$INDEX_NAME and '\n      + ' IS_FOR.RDB$INDEX_NAME = RELC_FOR.RDB$INDEX_NAME   and '\n      + ' IS_PRIM.RDB$FIELD_POSITION = IS_FOR.RDB$FIELD_POSITION  and '\n      + ' REFC_PRIM.RDB$CONSTRAINT_NAME = RELC_FOR.RDB$CONSTRAINT_NAME '\n      + ' ORDER BY RELC_PRIM.RDB$RELATION_NAME, IS_FOR.RDB$FIELD_POSITION ';\n\n    with GetConnection.CreateStatement.ExecuteQuery(SQL) do\n    begin\n      while Next do\n      begin\n        Result.MoveToInsertRow;\n        Result.UpdateNull(1); //PKTABLE_CAT\n        Result.UpdateNull(2); //PKTABLE_SCHEM\n        Result.UpdateString(3, GetString(1)); //PKTABLE_NAME\n        Result.UpdateString(4, GetString(2)); //PKCOLUMN_NAME\n        Result.UpdateNull(5); //FKTABLE_CAT\n        Result.UpdateNull(6); //FKTABLE_SCHEM\n        Result.UpdateString(7, GetString(3)); //FKTABLE_NAME\n        Result.UpdateString(8, GetString(4)); //FKCOLUMN_NAME\n        Result.UpdateInt(9, GetInt(5) + 1); //KEY_SEQ\n\n        if GetString(6) = 'RESTRICT' then  //UPDATE_RULE\n          Result.UpdateInt(10, Ord(ikRestrict))\n        else if GetString(6) = 'NO ACTION' then\n          Result.UpdateInt(10, Ord(ikNoAction))\n        else if GetString(6) = 'SET DEFAULT' then\n          Result.UpdateInt(10, Ord(ikSetDefault))\n        else if GetString(6) = 'CASCADE' then\n          Result.UpdateInt(10, Ord(ikCascade))\n        else if GetString(6) = 'SET NULL' then\n          Result.UpdateInt(10, Ord(ikSetNull));\n\n        if GetString(7) = 'RESTRICT' then //DELETE_RULE\n          Result.UpdateInt(11, Ord(ikRestrict))\n        else if GetString(7) = 'NO ACTION' then\n          Result.UpdateInt(11, Ord(ikNoAction))\n        else if GetString(7) = 'SET DEFAULT' then\n          Result.UpdateInt(11, Ord(ikSetDefault))\n        else if GetString(7) = 'CASCADE' then\n          Result.UpdateInt(11, Ord(ikCascade))\n        else if GetString(7) = 'SET NULL' then\n          Result.UpdateInt(11, Ord(ikSetNull));\n\n        Result.UpdateString(12, GetString(8)); //FK_NAME\n        Result.UpdateString(13, GetString(9)); //PK_NAME\n        Result.UpdateNull(14); //DEFERABILITY\n        Result.InsertRow;\n      end;\n      Close;\n    end;\nend;\n\n{**\n  Gets a description of the foreign key columns that reference a\n  table's primary key columns (the foreign keys exported by a\n  table).  They are ordered by FKTABLE_CAT, FKTABLE_SCHEM,\n  FKTABLE_NAME, and KEY_SEQ.\n\n  <P>Each foreign key column description has the following columns:\n   <OL>\n \t<LI><B>PKTABLE_CAT</B> String => primary key table catalog (may be null)\n \t<LI><B>PKTABLE_SCHEM</B> String => primary key table schema (may be null)\n \t<LI><B>PKTABLE_NAME</B> String => primary key table name\n \t<LI><B>PKCOLUMN_NAME</B> String => primary key column name\n \t<LI><B>FKTABLE_CAT</B> String => foreign key table catalog (may be null)\n       being exported (may be null)\n \t<LI><B>FKTABLE_SCHEM</B> String => foreign key table schema (may be null)\n       being exported (may be null)\n \t<LI><B>FKTABLE_NAME</B> String => foreign key table name\n       being exported\n \t<LI><B>FKCOLUMN_NAME</B> String => foreign key column name\n       being exported\n \t<LI><B>KEY_SEQ</B> short => sequence number within foreign key\n \t<LI><B>UPDATE_RULE</B> short => What happens to\n        foreign key when primary is updated:\n       <UL>\n       <LI> importedNoAction - do not allow update of primary\n                key if it has been imported\n       <LI> importedKeyCascade - change imported key to agree\n                with primary key update\n       <LI> importedKeySetNull - change imported key to NULL if\n                its primary key has been updated\n       <LI> importedKeySetDefault - change imported key to default values\n                if its primary key has been updated\n       <LI> importedKeyRestrict - same as importedKeyNoAction\n                                  (for ODBC 2.x compatibility)\n       </UL>\n \t<LI><B>DELETE_RULE</B> short => What happens to\n       the foreign key when primary is deleted.\n       <UL>\n       <LI> importedKeyNoAction - do not allow delete of primary\n                key if it has been imported\n       <LI> importedKeyCascade - delete rows that import a deleted key\n       <LI> importedKeySetNull - change imported key to NULL if\n                its primary key has been deleted\n       <LI> importedKeyRestrict - same as importedKeyNoAction\n                                  (for ODBC 2.x compatibility)\n       <LI> importedKeySetDefault - change imported key to default if\n                its primary key has been deleted\n       </UL>\n \t<LI><B>FK_NAME</B> String => foreign key name (may be null)\n \t<LI><B>PK_NAME</B> String => primary key name (may be null)\n \t<LI><B>DEFERRABILITY</B> short => can the evaluation of foreign key\n       constraints be deferred until commit\n       <UL>\n       <LI> importedKeyInitiallyDeferred - see SQL92 for definition\n       <LI> importedKeyInitiallyImmediate - see SQL92 for definition\n       <LI> importedKeyNotDeferrable - see SQL92 for definition\n       </UL>\n   </OL>\n\n  @param catalog a catalog name; \"\" retrieves those without a\n  catalog; null means drop catalog name from the selection criteria\n  @param schema a schema name; \"\" retrieves those\n  without a schema\n  @param table a table name\n  @return <code>ResultSet</code> - each row is a foreign key column description\n  @see #getImportedKeys\n}\nfunction TZInterbase6DatabaseMetadata.UncachedGetExportedKeys(const Catalog: string;\n  const Schema: string; const Table: string): IZResultSet;\nvar\n  SQL: string;\n  LTable: string;\nbegin\n    Result:=inherited UncachedGetExportedKeys(Catalog, Schema, Table);\n\n    LTable := ConstructNameCondition(AddEscapeCharToWildcards(Table), 'RC_PRIM.RDB$RELATION_NAME'); // Modified by cipto 6/11/2007 4:54:02 PM\n    if LTable <> '' then\n      LTable := ' AND ' + LTable;\n\n    SQL := ' SELECT RC_PRIM.RDB$RELATION_NAME, ' // prim.RDB$ key Table name\n      + ' IS_PRIM.RDB$FIELD_NAME, '       // prim.RDB$ key column name\n      + ' RC_FOR.RDB$RELATION_NAME, '     // foreign key Table name\n      + ' IS_FOR.RDB$FIELD_NAME, '        // foreign key column name\n      + ' IS_FOR.RDB$FIELD_POSITION, '    // key sequence\n      + ' REFC_PRIM.RDB$UPDATE_RULE, '    // if update or delete rule is null, interpret as RESTRICT\n      + ' REFC_PRIM.RDB$DELETE_RULE, '\n      + ' RC_FOR.RDB$CONSTRAINT_NAME, '   // foreign key constraint name\n      + ' RC_PRIM.RDB$CONSTRAINT_NAME '  // primary key constraint name\n      + ' FROM RDB$RELATION_CONSTRAINTS RC_FOR, RDB$REF_CONSTRAINTS REFC_FOR, '\n      + ' RDB$RELATION_CONSTRAINTS RC_PRIM, RDB$REF_CONSTRAINTS REFC_PRIM, '\n      + ' RDB$INDEX_SEGMENTS IS_PRIM, RDB$INDEX_SEGMENTS IS_FOR '\n      + ' WHERE RC_PRIM.RDB$CONSTRAINT_TYPE = ''PRIMARY KEY'' '+ LTable\n      + ' and REFC_FOR.RDB$CONST_NAME_UQ = RC_PRIM.RDB$CONSTRAINT_NAME'\n      + ' and RC_FOR.RDB$CONSTRAINT_NAME = REFC_FOR.RDB$CONSTRAINT_NAME and '\n      + ' RC_FOR.RDB$CONSTRAINT_TYPE = ''FOREIGN KEY'' and '// useful check, anyay\n      + ' RC_PRIM.RDB$INDEX_NAME = IS_PRIM.RDB$INDEX_NAME and '\n      + ' IS_FOR.RDB$INDEX_NAME = RC_FOR.RDB$INDEX_NAME   and '\n      + ' IS_PRIM.RDB$FIELD_POSITION = IS_FOR.RDB$FIELD_POSITION  and '\n      + ' REFC_PRIM.RDB$CONSTRAINT_NAME = RC_FOR.RDB$CONSTRAINT_NAME '\n      + ' ORDER BY RC_FOR.RDB$RELATION_NAME, IS_FOR.RDB$FIELD_POSITION ';\n\n    with GetConnection.CreateStatement.ExecuteQuery(SQL) do\n    begin\n      while Next do\n      begin\n        Result.MoveToInsertRow;\n        Result.UpdateNull(1); //PKTABLE_CAT\n        Result.UpdateNull(2); //PKTABLE_SCHEM\n        Result.UpdateString(3, GetString(1)); //PKTABLE_NAME\n        Result.UpdateString(4, GetString(2)); //PKCOLUMN_NAME\n        Result.UpdateNull(5); //FKTABLE_CAT\n        Result.UpdateNull(6); //FKTABLE_SCHEM'\n        Result.UpdateString(7, GetString(3)); //FKTABLE_NAME\n        Result.UpdateString(8, GetString(4)); //FKCOLUMN_NAME\n        Result.UpdateInt(9, GetInt(5) + 1); //KEY_SEQ\n\n        if GetString(6) = 'RESTRICT' then //UPDATE_RULE\n          Result.UpdateInt(10, Ord(ikRestrict))\n        else if GetString(6) = 'NO ACTION' then\n          Result.UpdateInt(10, Ord(ikNoAction))\n        else if GetString(6) = 'SET DEFAULT' then\n          Result.UpdateInt(10, Ord(ikSetDefault))\n        else if GetString(6) = 'CASCADE' then\n          Result.UpdateInt(10, Ord(ikCascade))\n        else if GetString(6) = 'SET NULL' then\n          Result.UpdateInt(10, Ord(ikSetNull));\n\n        if GetString(7) = 'RESTRICT' then //DELETE_RULE\n          Result.UpdateInt(11, Ord(ikRestrict))\n        else if GetString(7) = 'NO ACTION' then\n          Result.UpdateInt(11, Ord(ikNoAction))\n        else if GetString(7) = 'SET DEFAULT' then\n          Result.UpdateInt(11, Ord(ikSetDefault))\n        else if GetString(7) = 'CASCADE' then\n          Result.UpdateInt(11, Ord(ikCascade))\n        else if GetString(7) = 'SET NULL' then\n          Result.UpdateInt(11, Ord(ikSetNull));\n\n        Result.UpdateString(12, GetString(8)); //FK_NAME\n        Result.UpdateString(13, GetString(9)); //PK_NAME\n        Result.UpdateNull(14); //DEFERABILITY\n        Result.InsertRow;\n      end;\n      Close;\n    end;\nend;\n\n{**\n  EgonHugeist:\n  Gets a description of the foreign key columns in the foreign key\n  table that reference the primary key columns of the primary key\n  table (describe how one table imports another's key.) This\n  should normally return a single foreign key/primary key pair\n  (most tables only import a foreign key from a table once.)  They\n  are ordered by FKTABLE_CAT, FKTABLE_SCHEM, FKTABLE_NAME, and\n  KEY_SEQ.\n\n  <P>Each foreign key column description has the following columns:\n   <OL>\n \t<LI><B>PKTABLE_CAT</B> String => primary key table catalog (may be null)\n \t<LI><B>PKTABLE_SCHEM</B> String => primary key table schema (may be null)\n \t<LI><B>PKTABLE_NAME</B> String => primary key table name\n \t<LI><B>PKCOLUMN_NAME</B> String => primary key column name\n \t<LI><B>FKTABLE_CAT</B> String => foreign key table catalog (may be null)\n       being exported (may be null)\n \t<LI><B>FKTABLE_SCHEM</B> String => foreign key table schema (may be null)\n       being exported (may be null)\n \t<LI><B>FKTABLE_NAME</B> String => foreign key table name\n       being exported\n \t<LI><B>FKCOLUMN_NAME</B> String => foreign key column name\n       being exported\n \t<LI><B>KEY_SEQ</B> short => sequence number within foreign key\n \t<LI><B>UPDATE_RULE</B> short => What happens to\n        foreign key when primary is updated:\n       <UL>\n       <LI> importedNoAction - do not allow update of primary\n                key if it has been imported\n       <LI> importedKeyCascade - change imported key to agree\n                with primary key update\n       <LI> importedKeySetNull - change imported key to NULL if\n                its primary key has been updated\n       <LI> importedKeySetDefault - change imported key to default values\n                if its primary key has been updated\n       <LI> importedKeyRestrict - same as importedKeyNoAction\n                                  (for ODBC 2.x compatibility)\n       </UL>\n \t<LI><B>DELETE_RULE</B> short => What happens to\n       the foreign key when primary is deleted.\n       <UL>\n       <LI> importedKeyNoAction - do not allow delete of primary\n                key if it has been imported\n       <LI> importedKeyCascade - delete rows that import a deleted key\n       <LI> importedKeySetNull - change imported key to NULL if\n                its primary key has been deleted\n       <LI> importedKeyRestrict - same as importedKeyNoAction\n                                  (for ODBC 2.x compatibility)\n       <LI> importedKeySetDefault - change imported key to default if\n                its primary key has been deleted\n       </UL>\n \t<LI><B>FK_NAME</B> String => foreign key name (may be null)\n \t<LI><B>PK_NAME</B> String => primary key name (may be null)\n \t<LI><B>DEFERRABILITY</B> short => can the evaluation of foreign key\n       constraints be deferred until commit\n       <UL>\n       <LI> importedKeyInitiallyDeferred - see SQL92 for definition\n       <LI> importedKeyInitiallyImmediate - see SQL92 for definition\n       <LI> importedKeyNotDeferrable - see SQL92 for definition\n       </UL>\n   </OL>\n\n  @param primaryCatalog a catalog name; \"\" retrieves those without a\n  catalog; null means drop catalog name from the selection criteria\n  @param primarySchema a schema name; \"\" retrieves those\n  without a schema\n  @param primaryTable the table name that exports the key\n  @param foreignCatalog a catalog name; \"\" retrieves those without a\n  catalog; null means drop catalog name from the selection criteria\n  @param foreignSchema a schema name; \"\" retrieves those\n  without a schema\n  @param foreignTable the table name that imports the key\n  @return <code>ResultSet</code> - each row is a foreign key column description\n  @see #getImportedKeys\n}\nfunction TZInterbase6DatabaseMetadata.UncachedGetCrossReference(\n  const PrimaryCatalog: string; const PrimarySchema: string;\n  const PrimaryTable: string; const ForeignCatalog: string; const ForeignSchema: string;\n  const ForeignTable: string): IZResultSet;\nvar\n  KeySeq: Integer;\n  LCatalog, SQLString, LPTable, LFTable: String;\n\n  function GetRuleType(const Rule: String): TZImportedKey;\n  begin\n    if Rule = 'RESTRICT' then\n      Result := ikRestrict\n    else if Rule = 'NO ACTION' then\n      Result := ikNoAction\n    else if Rule = 'CASCADE' then\n      Result := ikCascade\n    else if Rule = 'SET DEFAULT' then\n      Result := ikSetDefault\n    else if Rule = 'SET NULL' then\n      Result := ikSetNull\n    else\n      Result := ikNotDeferrable; //impossible!\n  end;\nbegin\n  if PrimaryCatalog = '' then\n    LCatalog := GetConnection.GetCatalog\n  else\n    LCatalog := PrimaryCatalog;\n\n  LPTable := ConstructNameCondition(AddEscapeCharToWildcards(PrimaryTable), 'i2.RDB$RELATION_NAME');\n  LFTable := ConstructNameCondition(AddEscapeCharToWildcards(ForeignTable), 'rc.RDB$RELATION_NAME');\n  if LPTable <> '' then\n    LPTable := ' AND ' + LPTable;\n  if LFTable <> '' then\n    LFTable := ' AND ' + LFTable;\n\n  Result:=inherited UncachedGetCrossReference(PrimaryCatalog, PrimarySchema, PrimaryTable,\n                                              ForeignCatalog, ForeignSchema, ForeignTable);\n\n  SQLString :=\n      'SELECT '+\n      'i2.RDB$RELATION_NAME AS PKTABLE_NAME, '+\n      's2.RDB$FIELD_NAME AS PKCOLUMN_NAME, '+\n      'rc.RDB$RELATION_NAME as FKTABLE_NAME, '+\n      's.RDB$FIELD_NAME AS FKCOLUMN_NAME, '+\n      'refc.RDB$UPDATE_RULE AS UPDATE_RULE, '+\n      'refc.RDB$DELETE_RULE AS DELETE_RULE, '+\n      'i.RDB$INDEX_NAME AS FK_NAME, '+\n      's2.RDB$INDEX_NAME as PK_NAME, '+\n      'rc.RDB$DEFERRABLE AS DEFERRABILITY '+\n      'FROM RDB$INDEX_SEGMENTS s '+\n      'LEFT JOIN RDB$INDICES i ON i.RDB$INDEX_NAME = s.RDB$INDEX_NAME '+\n      'LEFT JOIN RDB$RELATION_CONSTRAINTS rc ON rc.RDB$INDEX_NAME = s.RDB$INDEX_NAME '+\n      'LEFT JOIN RDB$REF_CONSTRAINTS refc ON rc.RDB$CONSTRAINT_NAME = refc.RDB$CONSTRAINT_NAME '+\n      'LEFT JOIN RDB$RELATION_CONSTRAINTS rc2 ON rc2.RDB$CONSTRAINT_NAME = refc.RDB$CONST_NAME_UQ '+\n      'LEFT JOIN RDB$INDICES i2 ON i2.RDB$INDEX_NAME = rc2.RDB$INDEX_NAME '+\n      'LEFT JOIN RDB$INDEX_SEGMENTS s2 ON i2.RDB$INDEX_NAME = s2.RDB$INDEX_NAME '+\n      'WHERE rc.RDB$CONSTRAINT_TYPE = ''FOREIGN KEY'' '+\n      'AND rc.RDB$CONSTRAINT_TYPE IS NOT NULL '+LPTable+LFTable;\n\n  KeySeq := 0;\n  with GetConnection.CreateStatement.ExecuteQuery(SQLString) do\n  begin\n    while Next do\n    begin\n      Inc(KeySeq);\n      Result.MoveToInsertRow;\n      Result.UpdateString(1, LCatalog); //PKTABLE_CAT\n      Result.UpdateNull(2); //PKTABLE_SCHEM\n      Result.UpdateString(3, GetString(1)); //PKTABLE_NAME\n      Result.UpdateString(4, GetString(2)); //PKCOLUMN_NAME\n      Result.UpdateString(5, LCatalog); //PKTABLE_CAT\n      Result.UpdateNull(6); //FKTABLE_SCHEM\n      Result.UpdateString(7, GetString(3)); //FKTABLE_NAME\n      Result.UpdateString(8, GetString(4)); //FKCOLUMN_NAME\n      Result.UpdateShort(9, KeySeq); //KEY_SEQ\n      Result.UpdateShort(10, Ord(GetRuleType(GetString(5)))); //UPDATE_RULE\n      Result.UpdateShort(11, Ord(GetRuleType(GetString(6)))); //DELETE_RULE\n      Result.UpdateString(12, GetString(7)); //FK_NAME\n      Result.UpdateString(13, GetString(8)); //PK_NAME\n      if GetString(9) = 'NO' then\n        Result.UpdateShort(14, Ord(ikNotDeferrable)) //DEFERRABILITY\n      else\n        Result.UpdateShort(14, Ord(ikInitiallyDeferred)); //DEFERRABILITY\n      Result.InsertRow;\n    end;\n    Close;\n  end;\nend;\n\n{**\n  Gets a description of all the standard SQL types supported by\n  this database. They are ordered by DATA_TYPE and then by how\n  closely the data type maps to the corresponding JDBC SQL type.\n\n  <P>Each type description has the following columns:\n   <OL>\n \t<LI><B>TYPE_NAME</B> String => Type name\n \t<LI><B>DATA_TYPE</B> short => SQL data type from java.sql.Types\n \t<LI><B>PRECISION</B> int => maximum precision\n \t<LI><B>LITERAL_PREFIX</B> String => prefix used to quote a literal\n       (may be null)\n \t<LI><B>LITERAL_SUFFIX</B> String => suffix used to quote a literal\n        (may be null)\n \t<LI><B>CREATE_PARAMS</B> String => parameters used in creating\n       the type (may be null)\n \t<LI><B>NULLABLE</B> short => can you use NULL for this type?\n       <UL>\n       <LI> typeNoNulls - does not allow NULL values\n       <LI> typeNullable - allows NULL values\n       <LI> typeNullableUnknown - nullability unknown\n       </UL>\n \t<LI><B>CASE_SENSITIVE</B> boolean=> is it case sensitive?\n \t<LI><B>SEARCHABLE</B> short => can you use \"WHERE\" based on this type:\n       <UL>\n       <LI> typePredNone - No support\n       <LI> typePredChar - Only supported with WHERE .. LIKE\n       <LI> typePredBasic - Supported except for WHERE .. LIKE\n       <LI> typeSearchable - Supported for all WHERE ..\n       </UL>\n \t<LI><B>UNSIGNED_ATTRIBUTE</B> boolean => is it unsigned?\n \t<LI><B>FIXED_PREC_SCALE</B> boolean => can it be a money value?\n \t<LI><B>AUTO_INCREMENT</B> boolean => can it be used for an\n       auto-increment value?\n \t<LI><B>LOCAL_TYPE_NAME</B> String => localized version of type name\n       (may be null)\n \t<LI><B>MINIMUM_SCALE</B> short => minimum scale supported\n \t<LI><B>MAXIMUM_SCALE</B> short => maximum scale supported\n \t<LI><B>SQL_DATA_TYPE</B> int => unused\n \t<LI><B>SQL_DATETIME_SUB</B> int => unused\n \t<LI><B>NUM_PREC_RADIX</B> int => usually 2 or 10\n   </OL>\n\n  @return <code>ResultSet</code> - each row is an SQL type description\n}\nfunction TZInterbase6DatabaseMetadata.UncachedGetTypeInfo: IZResultSet;\nvar\n  SQL: string;\nbegin\n    Result:=inherited UncachedGetTypeInfo;\n\n    SQL := ' SELECT RDB$TYPE, RDB$TYPE_NAME FROM RDB$TYPES ' +\n      ' WHERE RDB$FIELD_NAME = ''RDB$FIELD_TYPE'' ';\n    with GetConnection.CreateStatement.ExecuteQuery(SQL) do\n    begin\n      while Next do\n      begin\n        Result.MoveToInsertRow;\n        Result.UpdateString(1, GetString(2));\n        Result.UpdateInt(2, Ord(ConvertInterbase6ToSqlType(GetInt(1), 0,\n          ConSettings.CPType)));\n        Result.UpdateInt(3, 9);\n        Result.UpdateInt(7, Ord(ntNoNulls));\n        Result.UpdateBoolean(8, false);\n        Result.UpdateBoolean(9, false);\n        Result.UpdateBoolean(11, false);\n        Result.UpdateBoolean(12, false);\n        Result.UpdateInt(18, 10);\n        Result.InsertRow;\n      end;\n      Close;\n    end;\nend;\n\n{**\n  Gets a description of a table's indices and statistics. They are\n  ordered by NON_UNIQUE, TYPE, INDEX_NAME, and ORDINAL_POSITION.\n\n  <P>Each index column description has the following columns:\n   <OL>\n \t<LI><B>TABLE_CAT</B> String => table catalog (may be null)\n \t<LI><B>TABLE_SCHEM</B> String => table schema (may be null)\n \t<LI><B>TABLE_NAME</B> String => table name\n \t<LI><B>NON_UNIQUE</B> boolean => Can index values be non-unique?\n       false when TYPE is tableIndexStatistic\n \t<LI><B>INDEX_QUALIFIER</B> String => index catalog (may be null);\n       null when TYPE is tableIndexStatistic\n \t<LI><B>INDEX_NAME</B> String => index name; null when TYPE is\n       tableIndexStatistic\n \t<LI><B>TYPE</B> short => index type:\n       <UL>\n       <LI> tableIndexStatistic - this identifies table statistics that are\n            returned in conjuction with a table's index descriptions\n       <LI> tableIndexClustered - this is a clustered index\n       <LI> tableIndexHashed - this is a hashed index\n       <LI> tableIndexOther - this is some other style of index\n       </UL>\n \t<LI><B>ORDINAL_POSITION</B> short => column sequence number\n       within index; zero when TYPE is tableIndexStatistic\n \t<LI><B>COLUMN_NAME</B> String => column name; null when TYPE is\n       tableIndexStatistic\n \t<LI><B>ASC_OR_DESC</B> String => column sort sequence, \"A\" => ascending,\n       \"D\" => descending, may be null if sort sequence is not supported;\n       null when TYPE is tableIndexStatistic\n \t<LI><B>CARDINALITY</B> int => When TYPE is tableIndexStatistic, then\n       this is the number of rows in the table; otherwise, it is the\n       number of unique values in the index.\n \t<LI><B>PAGES</B> int => When TYPE is  tableIndexStatisic then\n       this is the number of pages used for the table, otherwise it\n       is the number of pages used for the current index.\n \t<LI><B>FILTER_CONDITION</B> String => Filter condition, if any.\n       (may be null)\n   </OL>\n\n  @param catalog a catalog name; \"\" retrieves those without a\n  catalog; null means drop catalog name from the selection criteria\n  @param schema a schema name; \"\" retrieves those without a schema\n  @param table a table name\n  @param unique when true, return only indices for unique values;\n      when false, return indices regardless of whether unique or not\n  @param approximate when true, result is allowed to reflect approximate\n      or out of data values; when false, results are requested to be\n      accurate\n  @return <code>ResultSet</code> - each row is an index column description\n}\nfunction TZInterbase6DatabaseMetadata.UncachedGetIndexInfo(const Catalog: string;\n  const Schema: string; const Table: string; Unique: Boolean;\n  Approximate: Boolean): IZResultSet;\nvar\n  SQL : string;\n  LTable: String;\nbegin\n  LTable := ConstructNameCondition(Table, 'I.RDB$RELATION_NAME');\n  if LTable <> '' then\n    LTable := ' AND ' + LTable;\n\n  Result:=inherited UncachedGetIndexInfo(Catalog, Schema, Table, Unique, Approximate);\n\n    SQL :=  ' SELECT I.RDB$RELATION_NAME, I.RDB$UNIQUE_FLAG, I.RDB$INDEX_NAME,'\n      + ' ISGMT.RDB$FIELD_POSITION,\tISGMT.RDB$FIELD_NAME, I.RDB$INDEX_TYPE,'\n      + ' I.RDB$SEGMENT_COUNT, COUNT (DISTINCT P.RDB$PAGE_NUMBER) '\n      + ' FROM RDB$INDICES I JOIN RDB$INDEX_SEGMENTS ISGMT ON'\n      + ' I.RDB$INDEX_NAME = ISGMT.RDB$INDEX_NAME JOIN RDB$RELATIONS R ON'\n      + ' (R.RDB$RELATION_NAME = I.RDB$RELATION_NAME) JOIN RDB$PAGES P ON'\n      + ' (P.RDB$RELATION_ID = R.RDB$RELATION_ID AND P.RDB$PAGE_TYPE = 7'\n      + ' OR P.RDB$PAGE_TYPE = 6) WHERE ';\n    if Unique then\n      SQL := SQL + ' I.RDB$UNIQUE_FLAG = 1 AND ';\n\n    SQL := SQL + 'I.RDB$RELATION_NAME != '''' ' + LTable\n      + ' GROUP BY '\n      + ' I.RDB$INDEX_NAME, I.RDB$RELATION_NAME, I.RDB$UNIQUE_FLAG, '\n      + ' ISGMT.RDB$FIELD_POSITION, ISGMT.RDB$FIELD_NAME, I.RDB$INDEX_TYPE, '\n      + ' I.RDB$SEGMENT_COUNT ORDER BY 1,2,3,4';\n\n\n    with GetConnection.CreateStatement.ExecuteQuery(SQL) do\n    begin\n      while Next do\n      begin\n        Result.MoveToInsertRow;\n        Result.UpdateNull(1); //TABLE_CAT\n        Result.UpdateNull(2); //TABLE_SCHEM\n        Result.UpdateString(3, GetString(1)); //TABLE_NAME, RDB$RELATION_NAME\n        Result.UpdateBoolean(4, not GetBoolean(2)); //NON_UNIQUE, RDB$UNIQUE_FLAG\n        Result.UpdateNull(5); //INDEX_QUALIFIER\n        Result.UpdateString(6, GetString(3)); //INDEX_NAME, RDB$INDEX_NAME\n        Result.UpdateInt(7, Ord(ntNoNulls)); //TYPE\n        Result.UpdateInt(8, GetInt(4) + 1); //ORDINAL_POSITION, RDB$FIELD_POSITION\n        Result.UpdateString(9, GetString(5)); //COLUMN_NAME, RDB$FIELD_NAME\n        Result.UpdateNull(10); //ASC_OR_DESC\n        Result.UpdateNull(11); //CARDINALITY\n        Result.UpdateInt(12, GetInt(7)); //PAGES, RDB$SEGMENT_COUNT\n        Result.UpdateNull(13); //FILTER_CONDITION\n        Result.InsertRow;\n      end;\n      Close;\n    end;\nend;\n\nfunction TZInterbase6DatabaseMetadata.UncachedGetSequences(const Catalog, SchemaPattern,\n  SequenceNamePattern: string): IZResultSet;\nvar\n  SQL: string;\n  LSequenceNamePattern: string;\nbegin\n    Result:=inherited UncachedGetSequences(Catalog, SchemaPattern, SequenceNamePattern);\n\n    LSequenceNamePattern := ConstructNameCondition(SequenceNamePattern, \n      'RDB$GENERATOR_NAME');\n    if LSequenceNamePattern <> '' then\n      LSequenceNamePattern := ' and '+LSequenceNamePattern;\n\n    SQL := ' SELECT RDB$GENERATOR_NAME FROM RDB$GENERATORS ' + \n      'WHERE (RDB$SYSTEM_FLAG IS NULL OR RDB$SYSTEM_FLAG = 0)'+ LSequenceNamePattern;\n\n    with GetConnection.CreateStatement.ExecuteQuery(SQL) do\n    begin\n      while Next do\n      begin\n        Result.MoveToInsertRow;\n        Result.UpdateNull(1);\n        Result.UpdateNull(2);\n        Result.UpdateString(3, GetString(1)); //RDB$GENERATOR_NAME\n        Result.InsertRow;\n      end;\n      Close;\n    end;\nend;\n\n{**\n  Gets a privilege name.\n  @param  Interbase privilege name\n  @returns a JDBC privilege name.\n}\nfunction TZInterbase6DatabaseMetadata.GetPrivilege(Privilege: string): string;\nbegin\n  if Privilege = 'S' then\n    Result := 'SELECT'\n  else if Privilege = 'I' then\n    Result := 'INSERT'\n  else if Privilege = 'U' then\n    Result := 'UPDATE'\n  else if Privilege = 'D' then\n    Result := 'DELETE'\n  else if Privilege = 'R' then\n    Result := 'REFERENCE'\n  else\n    Result := '';\nend;\n\n{**\n  Gets the used Collation and CharacterSet of spezified Object.\n\n  @param catalog a catalog name; \"\" retrieves those without a\n  catalog; null means drop catalog name from the selection criteria\n  @param schema a schema name; \"\" and Catolog \"\" retrieves nothing\n  @param table a table name; \"\" retrieves the Schema Colloation and CharacterSet\n  @param ColumnNamePattern ColumnPattern;\"\" retrieves the\n    Table(if @param TablePattern is set) or\n    Schema(if @param TablePattern is NULL)\n      Colloation and CharacterSet\n  @return <code>ResultSet</code> - each row is a Collation, CharacterSet, ID,\n    and ByteLength per Char of speziefied Object\n}\nfunction TZInterbase6DatabaseMetadata.UncachedGetCollationAndCharSet(const Catalog, SchemaPattern,\n  TableNamePattern, ColumnNamePattern: string): IZResultSet; //EgonHugeist\nvar\n  SQL, LCatalog: string;\n  ColumnNameCondition, TableNameCondition: string;\nbegin\n  if Catalog = '' then\n  begin\n    if SchemaPattern <> '' then\n      LCatalog := SchemaPattern\n    else\n      LCatalog := FDatabase;\n  end\n  else\n    LCatalog := Catalog;\n  TableNameCondition := ConstructNameCondition(TableNamePattern,'R.RDB$RELATION_NAME');\n  ColumnNameCondition := ConstructNameCondition(ColumnNamePattern,'R.RDB$FIELD_NAME');\n  If TableNameCondition <> '' then\n    TableNameCondition := ' and ' + TableNameCondition;\n  If ColumnNameCondition <> '' then\n    ColumnNameCondition := ' and ' + ColumnNameCondition;\n\n  Result:=inherited UncachedGetCollationAndCharSet(Catalog, SchemaPattern, TableNamePattern, ColumnNamePattern);\n\n  if LCatalog <> '' then\n  begin\n    if TableNamePattern <> '' then\n    begin\n      if ColumnNamePattern <> '' then\n      begin\n        SQL :=  'SELECT C.RDB$CHARACTER_SET_NAME, C.RDB$DEFAULT_COLLATE_NAME, '+\n                'C.RDB$CHARACTER_SET_ID, C.RDB$BYTES_PER_CHARACTER '+\n                'FROM RDB$RELATION_FIELDS R '+\n                'right join RDB$FIELDS F on R.RDB$FIELD_SOURCE = F.RDB$FIELD_NAME '+\n                'left join RDB$CHARACTER_SETS C on C.RDB$CHARACTER_SET_ID = F.RDB$CHARACTER_SET_ID '+\n                'left join RDB$TYPES T on F.RDB$FIELD_TYPE = T.RDB$TYPE'+\n                'where T.RDB$FIELD_NAME=''RDB$FIELD_TYPE'' '+\n                ColumnNameCondition+TableNameCondition+\n                'order by R.RDB$FIELD_POSITION;';\n        with GetConnection.CreateStatement.ExecuteQuery(SQL) do\n        begin\n          if Next then\n          begin\n            if not ( GetString(FindColumn('RDB$CHARACTER_SET_NAME')) = 'NONE' ) then\n            begin\n              Result.MoveToInsertRow;\n              Result.UpdateString(1, LCatalog);   //COLLATION_CATALOG\n              Result.UpdateString(2, LCatalog);   //COLLATION_SCHEMA\n              Result.UpdateString(3, TableNamePattern); //COLLATION_TABLE\n              Result.UpdateString(4, ColumnNamePattern);//COLLATION_COLUMN\n              Result.UpdateString(5, GetString(FindColumn('RDB$DEFAULT_COLLATE_NAME'))); //COLLATION_NAME\n              Result.UpdateString(6, GetString(FindColumn('RDB$CHARACTER_SET_NAME'))); //CHARACTER_SET_NAME\n              Result.UpdateShort(7, GetShort(FindColumn('RDB$CHARACTER_SET_ID'))); //CHARACTER_SET_ID\n              Result.UpdateShort(8, GetShort(FindColumn('RDB$BYTES_PER_CHARACTER'))); //CHARACTER_SET_SIZE\n              Result.InsertRow;\n              Close;\n              Exit;\n            end;\n          end;\n          Close;\n        end;\n      end;\n    end;\n  end;\n  {Brings Defaults for Table or Database up}\n  SQL :=  'SELECT D.RDB$CHARACTER_SET_NAME, CS.RDB$DEFAULT_COLLATE_NAME, '+\n          'CS.RDB$CHARACTER_SET_ID, CS.RDB$BYTES_PER_CHARACTER '+\n          'FROM RDB$DATABASE D '+\n          'LEFT JOIN RDB$CHARACTER_SETS CS on '+\n          'D.RDB$CHARACTER_SET_NAME = CS.RDB$CHARACTER_SET_NAME; ';\n  with GetConnection.CreateStatement.ExecuteQuery(SQL) do\n  begin\n    if Next then\n    begin\n      Result.MoveToInsertRow;\n      Result.UpdateString(1, LCatalog);   //COLLATION_CATALOG\n      Result.UpdateString(2, LCatalog);   //COLLATION_SCHEMA\n      Result.UpdateString(3, TableNamePattern); //COLLATION_TABLE\n      Result.UpdateNull(4);//COLLATION_COLUMN\n      Result.UpdateString(5, GetString(FindColumn('RDB$DEFAULT_COLLATE_NAME'))); //COLLATION_NAME\n      Result.UpdateString(6, GetString(FindColumn('RDB$CHARACTER_SET_NAME'))); //CHARACTER_SET_NAME\n      Result.UpdateShort(7, GetShort(FindColumn('RDB$CHARACTER_SET_ID'))); //CHARACTER_SET_ID\n      Result.UpdateShort(8, GetShort(FindColumn('RDB$BYTES_PER_CHARACTER'))); //CHARACTER_SET_SIZE\n      Result.InsertRow;\n    end;\n    Close;\n  end;\nend;\n\n{**\n  Gets the supported CharacterSets:\n  @return <code>ResultSet</code> - each row is a CharacterSetName and it's ID\n}\nfunction TZInterbase6DatabaseMetadata.UncachedGetCharacterSets: IZResultSet; //EgonHugeist\nbegin\n  Result:=inherited UncachedGetCharacterSets;\n\n  with GetConnection.CreateStatement.ExecuteQuery(\n  'SELECT RDB$CHARACTER_SET_NAME, RDB$CHARACTER_SET_ID '+\n  'FROM RDB$CHARACTER_SETS') do\n  begin\n    while Next do\n    begin\n      Result.MoveToInsertRow;\n      Result.UpdateString(1, GetString(FindColumn('RDB$CHARACTER_SET_NAME'))); //CHARACTER_SET_NAME\n      Result.UpdateString(2, GetString(FindColumn('RDB$CHARACTER_SET_ID'))); //CHARACTER_SET_ID\n      Result.InsertRow;\n    end;\n    Close;\n  end;\nend;\n\nend.\n"
  },
  {
    "path": "lib/zeosdbo/src/dbc/ZDbcInterbase6ResultSet.pas",
    "content": "{*********************************************************}\n{                                                         }\n{                 Zeos Database Objects                   }\n{         Interbase Database Connectivity Classes         }\n{                                                         }\n{        Originally written by Sergey Merkuriev           }\n{                                                         }\n{*********************************************************}\n\n{@********************************************************}\n{    Copyright (c) 1999-2012 Zeos Development Group       }\n{                                                         }\n{ License Agreement:                                      }\n{                                                         }\n{ This library is distributed in the hope that it will be }\n{ useful, but WITHOUT ANY WARRANTY; without even the      }\n{ implied warranty of MERCHANTABILITY or FITNESS FOR      }\n{ A PARTICULAR PURPOSE.  See the GNU Lesser General       }\n{ Public License for more details.                        }\n{                                                         }\n{ The source code of the ZEOS Libraries and packages are  }\n{ distributed under the Library GNU General Public        }\n{ License (see the file COPYING / COPYING.ZEOS)           }\n{ with the following  modification:                       }\n{ As a special exception, the copyright holders of this   }\n{ library give you permission to link this library with   }\n{ independent modules to produce an executable,           }\n{ regardless of the license terms of these independent    }\n{ modules, and to copy and distribute the resulting       }\n{ executable under terms of your choice, provided that    }\n{ you also meet, for each linked independent module,      }\n{ the terms and conditions of the license of that module. }\n{ An independent module is a module which is not derived  }\n{ from or based on this library. If you modify this       }\n{ library, you may extend this exception to your version  }\n{ of the library, but you are not obligated to do so.     }\n{ If you do not wish to do so, delete this exception      }\n{ statement from your version.                            }\n{                                                         }\n{                                                         }\n{ The project web site is located on:                     }\n{   http://zeos.firmos.at  (FORUM)                        }\n{   http://sourceforge.net/p/zeoslib/tickets/ (BUGTRACKER)}\n{   svn://svn.code.sf.net/p/zeoslib/code-0/trunk (SVN)    }\n{                                                         }\n{   http://www.sourceforge.net/projects/zeoslib.          }\n{                                                         }\n{                                                         }\n{                                 Zeos Development Group. }\n{********************************************************@}\n\nunit ZDbcInterbase6ResultSet;\n\ninterface\n\n{$I ZDbc.inc}\n\nuses\n  {$IFDEF WITH_TOBJECTLIST_INLINE}System.Types, System.Contnrs{$ELSE}Types{$ENDIF},\n  Classes, {$IFDEF MSEgui}mclasses,{$ENDIF}\n  ZDbcIntfs, ZDbcResultSet, ZDbcInterbase6, ZPlainFirebirdInterbaseConstants,\n  ZPlainFirebirdDriver, ZCompatibility, ZDbcResultSetMetadata, ZMessages,\n  ZDbcInterbase6Utils;\n\ntype\n\n  {** Implements Interbase ResultSet. }\n  TZInterbase6ResultSet = class(TZAbstractResultSet)\n  private\n    FCachedBlob: boolean;\n    FFetchStat: Integer;\n    FCursorName: AnsiString;\n    FStmtHandle: TISC_STMT_HANDLE;\n    FSqlData: IZResultSQLDA;\n    FIBConnection: IZInterbase6Connection;\n  protected\n    procedure Open; override;\n    function GetFieldValue(ColumnIndex: Integer): Variant;\n    function InternalGetString(ColumnIndex: Integer): RawByteString; override;\n  public\n    constructor Create(Statement: IZStatement; SQL: string;\n      var StatementHandle: TISC_STMT_HANDLE; CursorName: AnsiString;\n      SqlData: IZResultSQLDA; CachedBlob: boolean);\n    destructor Destroy; override;\n\n    procedure Close; override;\n\n    function GetCursorName: AnsiString; override;\n\n    function IsNull(ColumnIndex: Integer): Boolean; override;\n    function GetString(ColumnIndex: Integer): String; override;\n    function GetUnicodeString(ColumnIndex: Integer): WideString; override;\n    function GetBoolean(ColumnIndex: Integer): Boolean; override;\n    function GetByte(ColumnIndex: Integer): Byte; override;\n    function GetShort(ColumnIndex: Integer): SmallInt; override;\n    function GetInt(ColumnIndex: Integer): Integer; override;\n    function GetLong(ColumnIndex: Integer): Int64; override;\n    function GetFloat(ColumnIndex: Integer): Single; override;\n    function GetDouble(ColumnIndex: Integer): Double; override;\n    function GetBigDecimal(ColumnIndex: Integer): Extended; override;\n    function GetBytes(ColumnIndex: Integer): TByteDynArray; override;\n    function GetDate(ColumnIndex: Integer): TDateTime; override;\n    function GetTime(ColumnIndex: Integer): TDateTime; override;\n    function GetTimestamp(ColumnIndex: Integer): TDateTime; override;\n    function GetBlob(ColumnIndex: Integer): IZBlob; override;\n\n    function MoveAbsolute(Row: Integer): Boolean; override;\n    function Next: Boolean; override;\n  end;\n\n  {** Implements external blob wrapper object for Intebase/Firbird. }\n  TZInterbase6Blob = class(TZAbstractBlob)\n  private\n    FBlobId: TISC_QUAD;\n    FBlobRead: Boolean;\n    FIBConnection: IZInterbase6Connection;\n  protected\n    procedure ReadBlob;\n  public\n    constructor Create(IBConnection: IZInterbase6Connection;\n      var BlobId: TISC_QUAD);\n\n    function IsEmpty: Boolean; override;\n    function Clone: IZBlob; override;\n    function GetStream: TStream; override;\n    function GetString: RawByteString; override;\n    function GetUnicodeString: WideString; override;\n    function GetBytes: TByteDynArray; override;\n  end;\n\nimplementation\n\nuses\n{$IFNDEF FPC}\n  Variants,\n{$ENDIF}\n  SysUtils, ZDbcUtils, ZEncoding, ZDbcLogging;\n\n{ TZInterbase6ResultSet }\n\n{**\n  Releases this <code>ResultSet</code> object's database and\n  JDBC resources immediately instead of waiting for\n  this to happen when it is automatically closed.\n\n  <P><B>Note:</B> A <code>ResultSet</code> object\n  is automatically closed by the\n  <code>Statement</code> object that generated it when\n  that <code>Statement</code> object is closed,\n  re-executed, or is used to retrieve the next result from a\n  sequence of multiple results. A <code>ResultSet</code> object\n  is also automatically closed when it is garbage collected.\n}\nprocedure TZInterbase6ResultSet.Close;\nbegin\n  if FStmtHandle <> 0 then\n  begin\n    { Free output allocated memory }\n    FSqlData := nil;\n    { Free allocate sql statement }\n    FreeStatement(FIBConnection.GetPlainDriver, FStmtHandle, DSQL_CLOSE); //AVZ\n  end;\n  inherited Close;\nend;\n\n{**\n  Constructs this object, assignes main properties and\n  opens the record set.\n  @param Statement a related SQL statement object.\n  @param handle a Interbase6 database connect handle.\n  @param the statement previously prepared\n  @param the sql out data previously allocated\n  @param the Interbase sql dialect\n}\nconstructor TZInterbase6ResultSet.Create(Statement: IZStatement; SQL: string;\n  var StatementHandle: TISC_STMT_HANDLE; CursorName: AnsiString;\n  SqlData: IZResultSQLDA; CachedBlob: boolean);\nbegin\n  inherited Create(Statement, SQL, nil,\n    Statement.GetConnection.GetConSettings);\n  \n  FFetchStat := 0;\n  FSqlData := SqlData;\n  FCursorName := CursorName;\n  FCachedBlob := CachedBlob;\n  FIBConnection := Statement.GetConnection as IZInterbase6Connection;\n\n  FStmtHandle := StatementHandle;\n  ResultSetType := rtForwardOnly;\n  ResultSetConcurrency := rcReadOnly;\n\n  Open;\nend;\n\n{**\n   Free memory and destriy component\n}\ndestructor TZInterbase6ResultSet.Destroy;\nbegin\n  if not Closed then\n    Close;\n  inherited Destroy;\nend;\n\n{**\n   Return field value by it index\n   @param the index column 0 first, 1 second ...\n   @return the field value as variant type\n}\nfunction TZInterbase6ResultSet.GetFieldValue(ColumnIndex: Integer): Variant;\nbegin\n  CheckClosed;\n  Result := FSqlData.GetValue(ColumnIndex);\nend;\n\n{**\n  Gets the value of the designated column in the current row\n  of this <code>ResultSet</code> object as\n  a <code>java.sql.BigDecimal</code> in the Java programming language.\n\n  @param columnIndex the first column is 1, the second is 2, ...\n  @param scale the number of digits to the right of the decimal point\n  @return the column value; if the value is SQL <code>NULL</code>, the\n    value returned is <code>null</code>\n}\nfunction TZInterbase6ResultSet.GetBigDecimal(ColumnIndex: Integer): Extended;\nbegin\n  CheckClosed;\n{$IFNDEF DISABLE_CHECKING}\n  CheckColumnConvertion(ColumnIndex, stBigDecimal);\n{$ENDIF}\n  Result := FSqlData.GetBigDecimal(ColumnIndex - 1);\n  LastWasNull := IsNull(ColumnIndex);\nend;\n\n{**\n  Returns the value of the designated column in the current row\n  of this <code>ResultSet</code> object as a <code>Blob</code> object\n  in the Java programming language.\n\n  @param ColumnIndex the first column is 1, the second is 2, ...\n  @return a <code>Blob</code> object representing the SQL <code>BLOB</code> value in\n    the specified column\n}\n{$IFDEF FPC}\n  {$HINTS OFF}\n{$ENDIF}\nfunction TZInterbase6ResultSet.GetBlob(ColumnIndex: Integer): IZBlob;\nvar\n  Size: Integer;\n  Buffer: Pointer;\n  BlobId: TISC_QUAD;\n  TempStream: TStream;\nbegin\n  Result := nil;\n  CheckClosed;\n  CheckBlobColumn(ColumnIndex);\n\n  LastWasNull := IsNull(ColumnIndex);\n  if LastWasNull then\n      Exit;\n  TempStream := nil;\n  if FCachedBlob then\n  begin\n    try\n      BlobId := FSqlData.GetQuad(ColumnIndex - 1);\n      with FIBConnection do\n        ReadBlobBufer(GetPlainDriver, GetDBHandle, GetTrHandle,\n          BlobId, Size, Buffer);\n\n      if Size = 0 then\n      begin\n        TempStream := TMemoryStream.Create;\n        Result := TZAbstractBlob.CreateWithStream(TempStream, FIBConnection, GetMetaData.GetColumnType(ColumnIndex) = stUnicodeStream);\n      end\n      else\n      case GetMetaData.GetColumnType(ColumnIndex) of\n        stBinaryStream:\n          Result := TZAbstractBlob.CreateWithData(Buffer, Size, FIBConnection);\n        stAsciiStream:\n          begin\n            Result := TZAbstractBlob.CreateWithData(Buffer, Size, FIBConnection);\n            TempStream := TStringStream.Create(GetValidatedAnsiString(Result.GetString, Consettings, True));\n            Result.SetStream(TempStream);\n          end;\n        else\n          begin\n            TempStream := GetValidatedUnicodeStream(Buffer, Size, ConSettings, True);\n            Result := TZAbstractBlob.CreateWithStream(TempStream, FIBConnection, True);\n          end;\n      end;\n    finally\n      if Assigned(TempStream) then FreeAndNil(TempStream);\n      FreeMem(Buffer, Size);\n    end;\n  end\n  else\n  begin\n    BlobId := FSqlData.GetQuad(ColumnIndex - 1);\n    Result := TZInterbase6Blob.Create(FIBConnection, BlobId);\n  end;\nend;\n{$IFDEF FPC}\n  {$HINTS ON}\n{$ENDIF}\n\n{**\n  Gets the value of the designated column in the current row\n  of this <code>ResultSet</code> object as\n  a <code>boolean</code> in the Java programming language.\n\n  @param columnIndex the first column is 1, the second is 2, ...\n  @return the column value; if the value is SQL <code>NULL</code>, the\n    value returned is <code>false</code>\n}\nfunction TZInterbase6ResultSet.GetBoolean(ColumnIndex: Integer): Boolean;\nbegin\n  CheckClosed;\n{$IFNDEF DISABLE_CHECKING}\n  CheckColumnConvertion(ColumnIndex, stBoolean);\n{$ENDIF}\n  Result := FSqlData.GetBoolean(ColumnIndex - 1);\n  LastWasNull := IsNull(ColumnIndex);\nend;\n\n{**\n  Gets the value of the designated column in the current row\n  of this <code>ResultSet</code> object as\n  a <code>byte</code> in the Java programming language.\n\n  @param columnIndex the first column is 1, the second is 2, ...\n  @return the column value; if the value is SQL <code>NULL</code>, the\n    value returned is <code>0</code>\n}\nfunction TZInterbase6ResultSet.GetByte(ColumnIndex: Integer): Byte;\nbegin\n  CheckClosed;\n{$IFNDEF DISABLE_CHECKING}\n  CheckColumnConvertion(ColumnIndex, stByte);\n{$ENDIF}\n  Result := FSqlData.GetByte(ColumnIndex - 1);\n  LastWasNull := IsNull(ColumnIndex);\nend;\n\n{**\n  Gets the value of the designated column in the current row\n  of this <code>ResultSet</code> object as\n  a <code>byte</code> array in the Java programming language.\n  The bytes represent the raw values returned by the driver.\n\n  @param columnIndex the first column is 1, the second is 2, ...\n  @return the column value; if the value is SQL <code>NULL</code>, the\n    value returned is <code>null</code>\n}\nfunction TZInterbase6ResultSet.GetBytes(ColumnIndex: Integer): TByteDynArray;\nbegin\n  CheckClosed;\n{$IFNDEF DISABLE_CHECKING}\n  CheckColumnConvertion(ColumnIndex, stBytes);\n{$ENDIF}\n  Result := FSqlData.GetBytes(ColumnIndex - 1);\n  LastWasNull := IsNull(ColumnIndex);\nend;\n\n{**\n  Gets the value of the designated column in the current row\n  of this <code>ResultSet</code> object as\n  a <code>java.sql.Date</code> object in the Java programming language.\n\n  @param columnIndex the first column is 1, the second is 2, ...\n  @return the column value; if the value is SQL <code>NULL</code>, the\n    value returned is <code>null</code>\n}\nfunction TZInterbase6ResultSet.GetDate(ColumnIndex: Integer): TDateTime;\nbegin\n  CheckClosed;\n{$IFNDEF DISABLE_CHECKING}\n  CheckColumnConvertion(ColumnIndex, stDate);\n{$ENDIF}\n  Result := FSqlData.GetDate(ColumnIndex - 1);\n  LastWasNull := IsNull(ColumnIndex);\nend;\n\n{**\n  Gets the value of the designated column in the current row\n  of this <code>ResultSet</code> object as\n  a <code>double</code> in the Java programming language.\n\n  @param columnIndex the first column is 1, the second is 2, ...\n  @return the column value; if the value is SQL <code>NULL</code>, the\n    value returned is <code>0</code>\n}\nfunction TZInterbase6ResultSet.GetDouble(ColumnIndex: Integer): Double;\nbegin\n  CheckClosed;\n{$IFNDEF DISABLE_CHECKING}\n  CheckColumnConvertion(ColumnIndex, stDouble);\n{$ENDIF}\n  Result := FSqlData.GetDouble(ColumnIndex - 1);\n  LastWasNull := IsNull(ColumnIndex);\nend;\n\n{**\n  Gets the value of the designated column in the current row\n  of this <code>ResultSet</code> object as\n  a <code>float</code> in the Java programming language.\n\n  @param columnIndex the first column is 1, the second is 2, ...\n  @return the column value; if the value is SQL <code>NULL</code>, the\n    value returned is <code>0</code>\n}\nfunction TZInterbase6ResultSet.GetFloat(ColumnIndex: Integer): Single;\nbegin\n  CheckClosed;\n{$IFNDEF DISABLE_CHECKING}\n  CheckColumnConvertion(ColumnIndex, stFloat);\n{$ENDIF}\n  Result := FSqlData.GetFloat(ColumnIndex - 1);\n  LastWasNull := IsNull(ColumnIndex);\nend;\n\n{**\n  Gets the value of the designated column in the current row\n  of this <code>ResultSet</code> object as\n  an <code>int</code> in the Java programming language.\n\n  @param columnIndex the first column is 1, the second is 2, ...\n  @return the column value; if the value is SQL <code>NULL</code>, the\n    value returned is <code>0</code>\n}\nfunction TZInterbase6ResultSet.GetInt(ColumnIndex: Integer): Integer;\nbegin\n  CheckClosed;\n{$IFNDEF DISABLE_CHECKING}\n  CheckColumnConvertion(ColumnIndex, stInteger);\n{$ENDIF}\n  Result := FSqlData.GetInt(ColumnIndex - 1);\n  LastWasNull := IsNull(ColumnIndex);\nend;\n\n{**\n  Gets the value of the designated column in the current row\n  of this <code>ResultSet</code> object as\n  a <code>long</code> in the Java programming language.\n\n  @param columnIndex the first column is 1, the second is 2, ...\n  @return the column value; if the value is SQL <code>NULL</code>, the\n    value returned is <code>0</code>\n}\nfunction TZInterbase6ResultSet.GetLong(ColumnIndex: Integer): Int64;\nbegin\n  CheckClosed;\n{$IFNDEF DISABLE_CHECKING}\n  CheckColumnConvertion(ColumnIndex, stLong);\n{$ENDIF}\n  Result := FSqlData.GetLong(ColumnIndex - 1);\n  LastWasNull := IsNull(ColumnIndex);\nend;\n\n{**\n  Gets the value of the designated column in the current row\n  of this <code>ResultSet</code> object as\n  a <code>short</code> in the Java programming language.\n\n  @param columnIndex the first column is 1, the second is 2, ...\n  @return the column value; if the value is SQL <code>NULL</code>, the\n    value returned is <code>0</code>\n}\nfunction TZInterbase6ResultSet.GetShort(ColumnIndex: Integer): SmallInt;\nbegin\n  CheckClosed;\n{$IFNDEF DISABLE_CHECKING}\n  CheckColumnConvertion(ColumnIndex, stShort);\n{$ENDIF}\n  Result := FSqlData.GetShort(ColumnIndex - 1);\n  LastWasNull := IsNull(ColumnIndex);\nend;\n\n{**\n  Gets the value of the designated column in the current row\n  of this <code>ResultSet</code> object as\n  a <code>String</code> in the Java programming language.\n\n  @param columnIndex the first column is 1, the second is 2, ...\n  @return the column value; if the value is SQL <code>NULL</code>, the\n    value returned is <code>null</code>\n}\nfunction TZInterbase6ResultSet.InternalGetString(ColumnIndex: Integer): RawByteString;\nbegin\n  CheckClosed;\n{$IFNDEF DISABLE_CHECKING}\n  CheckColumnConvertion(ColumnIndex, stString);\n{$ENDIF}\n  LastWasNull := IsNull(ColumnIndex);\n  Result := FSqlData.GetString(ColumnIndex - 1);\nend;\n\n{**\n  Gets the value of the designated column in the current row\n  of this <code>ResultSet</code> object as\n  a <code>java.sql.Time</code> object in the Java programming language.\n\n  @param columnIndex the first column is 1, the second is 2, ...\n  @return the column value; if the value is SQL <code>NULL</code>, the\n    value returned is <code>null</code>\n}\nfunction TZInterbase6ResultSet.GetTime(ColumnIndex: Integer): TDateTime;\nbegin\n  CheckClosed;\n{$IFNDEF DISABLE_CHECKING}\n  CheckColumnConvertion(ColumnIndex, stTime);\n{$ENDIF}\n  Result := FSqlData.GetTime(ColumnIndex - 1);\n  LastWasNull := IsNull(ColumnIndex);\nend;\n\n{**\n  Gets the value of the designated column in the current row\n  of this <code>ResultSet</code> object as\n  a <code>java.sql.Timestamp</code> object in the Java programming language.\n\n  @param columnIndex the first column is 1, the second is 2, ...\n  @return the column value; if the value is SQL <code>NULL</code>, the\n  value returned is <code>null</code>\n  @exception SQLException if a database access error occurs\n}\nfunction TZInterbase6ResultSet.GetTimestamp(ColumnIndex: Integer): TDateTime;\nbegin\n  CheckClosed;\n{$IFNDEF DISABLE_CHECKING}\n  CheckColumnConvertion(ColumnIndex, stTimestamp);\n{$ENDIF}\n  Result := FSqlData.GetTimestamp(ColumnIndex - 1);\n  LastWasNull := IsNull(ColumnIndex);\nend;\n\n{**\n  Indicates if the value of the designated column in the current row\n  of this <code>ResultSet</code> object is Null.\n\n  @param columnIndex the first column is 1, the second is 2, ...\n  @return if the value is SQL <code>NULL</code>, the\n    value returned is <code>true</code>. <code>false</code> otherwise.\n}\nfunction TZInterbase6ResultSet.IsNull(ColumnIndex: Integer): Boolean;\nbegin\n  CheckClosed;\n  Result := FSqlData.IsNull(ColumnIndex - 1);\nend;\n\n{**\n  Gets the value of the designated column in the current row\n  of this <code>ResultSet</code> object as\n  a <code>String</code> in the Java programming language.\n\n  @param columnIndex the first column is 1, the second is 2, ...\n  @return the column value; if the value is SQL <code>NULL</code>, the\n    value returned is <code>null</code>\n}\nfunction TZInterbase6ResultSet.GetString(ColumnIndex: Integer): String;\nbegin\n  CheckClosed;\n{$IFNDEF DISABLE_CHECKING}\n  CheckColumnConvertion(ColumnIndex, stString);\n{$ENDIF}\n  LastWasNull := IsNull(ColumnIndex);\n  if ( ConSettings.ClientCodePage.ID = CS_NONE ) then //CharacterSet 'NONE' doesn't convert anything! Data as is!\n    case FSqlData.GetIbSqlType(ColumnIndex -1) of\n      SQL_VARYING, SQL_TEXT:\n        if FSqlData.GetIbSqlSubType(ColumnIndex -1) = CS_NONE then\n          Result := ZDbcString(FSqlData.GetString(ColumnIndex - 1))\n        else\n          Result := ZDbcString(FSqlData.GetString(ColumnIndex - 1),\n            FIBConnection.GetPlainDriver.ValidateCharEncoding(FSqlData.GetIbSqlSubType(ColumnIndex -1)).CP);\n      else\n        Result := ZDbcString(FSqlData.GetString(ColumnIndex - 1));\n    end\n  else\n    Result := ZDbcString(FSqlData.GetString(ColumnIndex - 1));\nend;\n\n{**\n  Gets the value of the designated column in the current row\n  of this <code>ResultSet</code> object as\n  a <code>WideString</code> in the Delphi programming language.\n\n  @param columnIndex the first column is 1, the second is 2, ...\n  @return the column value; if the value is SQL <code>NULL</code>, the\n    value returned is <code>null</code>\n}\nfunction TZInterbase6ResultSet.GetUnicodeString(ColumnIndex: Integer): WideString;\nbegin\n  CheckClosed;\n{$IFNDEF DISABLE_CHECKING}\n  CheckColumnConvertion(ColumnIndex, stString);\n{$ENDIF}\n  LastWasNull := IsNull(ColumnIndex);\n  if ( ConSettings.ClientCodePage.ID = CS_NONE ) then //CharacterSet 'NONE' doesn't convert anything! Data as is!\n    case FSqlData.GetIbSqlType(ColumnIndex -1) of\n      SQL_VARYING, SQL_TEXT:\n        if FSqlData.GetIbSqlSubType(ColumnIndex -1) = CS_NONE then\n          Result := ZDbcUnicodeString(FSqlData.GetString(ColumnIndex - 1))\n        else\n          Result := ZDbcUnicodeString(FSqlData.GetString(ColumnIndex - 1),\n            FIBConnection.GetPlainDriver.ValidateCharEncoding(FSqlData.GetIbSqlSubType(ColumnIndex -1)).CP);\n      else\n        Result := ZDbcUnicodeString(FSqlData.GetString(ColumnIndex - 1));\n    end\n  else\n    Result := ZDbcUnicodeString(FSqlData.GetString(ColumnIndex - 1));\nend;\n\n{**\n  Moves the cursor to the given row number in\n  this <code>ResultSet</code> object.\n\n  <p>If the row number is positive, the cursor moves to\n  the given row number with respect to the\n  beginning of the result set.  The first row is row 1, the second\n  is row 2, and so on.\n\n  <p>If the given row number is negative, the cursor moves to\n  an absolute row position with respect to\n  the end of the result set.  For example, calling the method\n  <code>absolute(-1)</code> positions the\n  cursor on the last row; calling the method <code>absolute(-2)</code>\n  moves the cursor to the next-to-last row, and so on.\n\n  <p>An attempt to position the cursor beyond the first/last row in\n  the result set leaves the cursor before the first row or after\n  the last row.\n\n  <p><B>Note:</B> Calling <code>absolute(1)</code> is the same\n  as calling <code>first()</code>. Calling <code>absolute(-1)</code>\n  is the same as calling <code>last()</code>.\n\n  @return <code>true</code> if the cursor is on the result set;\n    <code>false</code> otherwise\n}\nfunction TZInterbase6ResultSet.MoveAbsolute(Row: Integer): Boolean;\nbegin\n  Result := False;\n  RaiseForwardOnlyException;\nend;\n\n{**\n  Moves the cursor down one row from its current position.\n  A <code>ResultSet</code> cursor is initially positioned\n  before the first row; the first call to the method\n  <code>next</code> makes the first row the current row; the\n  second call makes the second row the current row, and so on.\n\n  <P>If an input stream is open for the current row, a call\n  to the method <code>next</code> will\n  implicitly close it. A <code>ResultSet</code> object's\n  warning chain is cleared when a new row is read.\n\n  @return <code>true</code> if the new current row is valid;\n    <code>false</code> if there are no more rows\n}\nfunction TZInterbase6ResultSet.Next: Boolean;\nvar\n  StatusVector: TARRAY_ISC_STATUS;\nbegin\n  { Checks for maximum row. }\n  Result := False;\n  if (MaxRows > 0) and (LastRowNo >= MaxRows) then\n    Exit;\n\n  { Fetch row. }\n  if (ResultSetType = rtForwardOnly) and (FFetchStat = 0) then\n  begin\n    with FIBConnection do\n    begin\n      if (FCursorName = '') then  //AVZ - Test for ExecProc - this is for multiple rows\n      begin\n        FFetchStat := GetPlainDriver.isc_dsql_fetch(@StatusVector,\n          @FStmtHandle, GetDialect, FSqlData.GetData);\n      end\n      else\n      begin\n        FFetchStat := 1;\n        Result := True;\n      end;\n    end;\n\n    if FFetchStat = 0 then\n    begin\n      RowNo := RowNo + 1;\n      LastRowNo := RowNo;\n      Result := True;\n    end\n    else\n      if not Result then\n        CheckInterbase6Error(FIBConnection.GetPlainDriver, StatusVector, lcOther);\n  end;\nend;\n\n{**\n  Opens this recordset.\n}\nprocedure TZInterbase6ResultSet.Open;\nvar\n  I: Integer;\n  FieldSqlType: TZSQLType;\n  ColumnInfo: TZColumnInfo;\n  ZCodePageInfo: PZCodePage;\nbegin\n  if FStmtHandle=0 then\n    raise EZSQLException.Create(SCanNotRetrieveResultSetData);\n\n  ColumnsInfo.Clear;\n  for I := 0 to FSqlData.GetFieldCount - 1 do\n  begin\n    ColumnInfo := TZColumnInfo.Create;\n    with ColumnInfo, FSqlData  do\n    begin\n      ColumnName := GetFieldSqlName(I);\n      TableName := GetFieldRelationName(I);\n      ColumnLabel := GetFieldAliasName(I);\n      FieldSqlType := GetFieldSqlType(I);\n      ColumnType := FieldSqlType;\n\n        if FieldSqlType in [stString, stUnicodeString] then\n        begin\n          ZCodePageInfo := FIBConnection.GetPlainDriver.ValidateCharEncoding(GetIbSqlSubType(I)); //get column CodePage info\n          Precision := GetFieldSize(ColumnType, ConSettings, GetIbSqlLen(I),\n            ZCodePageInfo^.CharWidth, @ColumnDisplaySize, True);\n        end;\n        if FieldSQLType = stBytes then\n          Precision := GetIbSqlLen(I);\n\n        ReadOnly := (TableName = '') or (ColumnName = '') or\n          (ColumnName = 'RDB$DB_KEY') or (FieldSqlType = ZDbcIntfs.stUnknown);\n\n      if IsNullable(I) then\n        Nullable := ntNullable\n      else\n        Nullable := ntNoNulls;\n\n      Scale := GetFieldScale(I);\n        CaseSensitive := UpperCase(ColumnName) <> ColumnName; //non quoted fields are uppercased by default\n    end;\n    ColumnsInfo.Add(ColumnInfo);\n  end;\n  inherited Open;\nend;\n\nfunction TZInterbase6ResultSet.GetCursorName: AnsiString;\nbegin\n  Result := FCursorName;\nend;\n\n{ TZInterbase6Blob }\n\nfunction TZInterbase6Blob.Clone: IZBlob;\nbegin\n  Result := TZInterbase6Blob.Create(FIBConnection, FBlobId);\nend;\n\n{**\n  Reads the blob information by blob handle.\n  @param handle a Interbase6 database connect handle.\n  @param the statement previously prepared\n}\nconstructor TZInterbase6Blob.Create(IBConnection: IZInterbase6Connection;\n  var BlobId: TISC_QUAD);\nbegin\n  FBlobId := BlobId;\n  FBlobRead := False;\n  FIBConnection := IBConnection;\nend;\n\nfunction TZInterbase6Blob.GetBytes: TByteDynArray;\nbegin\n  ReadBlob;\n  Result := inherited GetBytes;\nend;\n\nfunction TZInterbase6Blob.GetStream: TStream;\nbegin\n  ReadBlob;\n  Result := inherited GetStream;\nend;\n\nfunction TZInterbase6Blob.GetString: RawByteString;\nbegin\n  ReadBlob;\n  Result := inherited GetString;\nend;\n\nfunction TZInterbase6Blob.GetUnicodeString: WideString;\nbegin\n  ReadBlob;\n  Result := inherited GetUnicodeString;\nend;\n\nfunction TZInterbase6Blob.IsEmpty: Boolean;\nbegin\n  ReadBlob;\n  Result := inherited IsEmpty;\nend;\n\n{$IFDEF FPC}\n  {$HINTS OFF}\n{$ENDIF}\nprocedure TZInterbase6Blob.ReadBlob;\nvar\n  Size: Integer;\n  Buffer: Pointer;\nbegin\n  if FBlobRead then\n   Exit;\n   \n  with FIBConnection do\n    ReadBlobBufer(GetPlainDriver, GetDBHandle, GetTrHandle, FBlobId, Size, Buffer);\n  BlobSize := Size;\n  BlobData := Buffer;\n  FBlobRead := True;\nend;\n{$IFDEF FPC}\n  {$HINTS ON}\n{$ENDIF}\n\nend."
  },
  {
    "path": "lib/zeosdbo/src/dbc/ZDbcInterbase6Statement.pas",
    "content": "{*********************************************************}\n{                                                         }\n{                 Zeos Database Objects                   }\n{         Interbase Database Connectivity Classes         }\n{                                                         }\n{        Originally written by Sergey Merkuriev           }\n{                                                         }\n{*********************************************************}\n\n{@********************************************************}\n{    Copyright (c) 1999-2012 Zeos Development Group       }\n{                                                         }\n{ License Agreement:                                      }\n{                                                         }\n{ This library is distributed in the hope that it will be }\n{ useful, but WITHOUT ANY WARRANTY; without even the      }\n{ implied warranty of MERCHANTABILITY or FITNESS FOR      }\n{ A PARTICULAR PURPOSE.  See the GNU Lesser General       }\n{ Public License for more details.                        }\n{                                                         }\n{ The source code of the ZEOS Libraries and packages are  }\n{ distributed under the Library GNU General Public        }\n{ License (see the file COPYING / COPYING.ZEOS)           }\n{ with the following  modification:                       }\n{ As a special exception, the copyright holders of this   }\n{ library give you permission to link this library with   }\n{ independent modules to produce an executable,           }\n{ regardless of the license terms of these independent    }\n{ modules, and to copy and distribute the resulting       }\n{ executable under terms of your choice, provided that    }\n{ you also meet, for each linked independent module,      }\n{ the terms and conditions of the license of that module. }\n{ An independent module is a module which is not derived  }\n{ from or based on this library. If you modify this       }\n{ library, you may extend this exception to your version  }\n{ of the library, but you are not obligated to do so.     }\n{ If you do not wish to do so, delete this exception      }\n{ statement from your version.                            }\n{                                                         }\n{                                                         }\n{ The project web site is located on:                     }\n{   http://zeos.firmos.at  (FORUM)                        }\n{   http://sourceforge.net/p/zeoslib/tickets/ (BUGTRACKER)}\n{   svn://svn.code.sf.net/p/zeoslib/code-0/trunk (SVN)    }\n{                                                         }\n{   http://www.sourceforge.net/projects/zeoslib.          }\n{                                                         }\n{                                                         }\n{                                 Zeos Development Group. }\n{********************************************************@}\n\nunit ZDbcInterbase6Statement;\n\ninterface\n\n{$I ZDbc.inc}\n\nuses Classes, {$IFDEF MSEgui}mclasses,{$ENDIF} SysUtils, Types,\n  ZDbcIntfs, ZDbcStatement, ZDbcInterbase6, ZDbcInterbase6Utils,\n  ZDbcInterbase6ResultSet, ZPlainFirebirdInterbaseConstants, ZCompatibility,\n  ZDbcLogging, ZVariant, ZMessages;\n\ntype\n\n  {** Implements Generic Interbase6 Statement. }\n  TZInterbase6Statement = class(TZAbstractStatement)\n  private\n    FCachedBlob: boolean;\n    FStatusVector: TARRAY_ISC_STATUS;\n    FIBConnection: IZInterbase6Connection;\n  protected\n    function CheckInterbase6Error(const Sql: string = '') : Integer;\n  public\n    constructor Create(Connection: IZConnection; Info: TStrings);\n\n    function ExecuteQuery(const SQL: RawByteString): IZResultSet; override;\n    function ExecuteUpdate(const SQL: RawByteString): Integer; override;\n    function Execute(const SQL: RawByteString): Boolean; override;\n  end;\n\n  {** Implements Prepared SQL Statement. }\n\n  { TZInterbase6PreparedStatement }\n\n  TZInterbase6PreparedStatement = class(TZAbstractPreparedStatement)\n  private\n    FCachedBlob: boolean;\n    FParamSQLData: IZParamsSQLDA;\n    FStatusVector: TARRAY_ISC_STATUS;\n    FIBConnection: IZInterbase6Connection;\n\n    Cursor: AnsiString;\n    SQLData: IZResultSQLDA;\n    StmtHandle: TISC_STMT_HANDLE;\n    StatementType: TZIbSqlStatementType;\n  protected\n    procedure PrepareInParameters; override;\n    procedure SetASQL(const Value: RawByteString); override;\n    procedure SetWSQL(const Value: ZWideString); override;\n    procedure BindInParameters; override;\n    procedure UnPrepareInParameters; override;\n    function CheckInterbase6Error(const Sql: string = '') : Integer;\n  public\n    constructor Create(Connection: IZConnection; const SQL: string; Info: TStrings);\n    destructor Destroy; override;\n\n    procedure Prepare; override;\n    procedure Unprepare; override;\n\n    function ExecuteQueryPrepared: IZResultSet; override;\n    function ExecuteUpdatePrepared: Integer; override;\n    function ExecutePrepared: Boolean; override;\n  end;\n\n  TZInterbase6CallableStatement = class(TZAbstractPreparedCallableStatement)\n  private\n    FCachedBlob: boolean;\n    FParamSQLData: IZParamsSQLDA;\n    FResultSQLData: IZResultSQLDA;\n    FStmtHandle: TISC_STMT_HANDLE;\n    FStatementType: TZIbSqlStatementType;\n    FStatusVector: TARRAY_ISC_STATUS;\n    FIBConnection: IZInterbase6Connection;\n  protected\n    procedure CheckInterbase6Error(const Sql: string = '');\n    procedure FetchOutParams(Value: IZResultSQLDA);\n    function GetProcedureSql(SelectProc: boolean): string;\n\n    procedure PrepareInParameters; override;\n    procedure BindInParameters; override;\n    procedure UnPrepareInParameters; override;\n  public\n    constructor Create(Connection: IZConnection; const SQL: string; Info: TStrings);\n    destructor Destroy; override;\n    procedure Unprepare; override;\n\n    function ExecuteQueryPrepared: IZResultSet; override;\n    function ExecuteUpdatePrepared: Integer; override;\n    function ExecutePrepared: Boolean; override;\n  end;\n\nimplementation\n\nuses ZSysUtils, ZDbcUtils;\n\n{ TZInterbase6Statement }\n\n{**\n   Check interbase error status\n   @param Sql the used sql tring\n\n   @return ErrorCode for possible Database Disconnect \n}\nfunction TZInterbase6Statement.CheckInterbase6Error(const Sql: string = '') : Integer;\nbegin\n  Result := ZDbcInterbase6Utils.CheckInterbase6Error(FIBConnection.GetPlainDriver,\n    FStatusVector, lcExecute, SQL);\nend;\n\n\n{**\n  Constructs this object and assignes the main properties.\n  @param Connection a database connection object.\n  @param Handle a connection handle pointer.\n  @param Dialect a dialect Interbase SQL must be 1 or 2 or 3.\n  @param Info a statement parameters.\n}\nconstructor TZInterbase6Statement.Create(Connection: IZConnection;\n  Info: TStrings);\nbegin\n  inherited Create(Connection, Info);\n\n  FIBConnection := Connection as IZInterbase6Connection;\n  ResultSetType := rtScrollInsensitive;\n  FCachedBlob := StrToBoolEx(DefineStatementParameter(Self, 'cashedblob', 'true'));\nend;\n\n{**\n  Destroys this object and cleanups the memory.\n}\n{**\n  Executes an SQL statement that returns a single <code>ResultSet</code> object.\n  @param sql typically this is a static SQL <code>SELECT</code> statement\n  @return a <code>ResultSet</code> object that contains the data produced by the\n    given query; never <code>null</code>\n}\n{$HINTS OFF}\nfunction TZInterbase6Statement.ExecuteQuery(const SQL: RawByteString): IZResultSet;\nvar\n  Cursor: AnsiString;\n  SQLData: IZResultSQLDA;\n  StmtHandle: TISC_STMT_HANDLE;\n  StatementType: TZIbSqlStatementType;\n  iError : Integer; //For closing the database //AVZ\nbegin\n  StmtHandle := 0;\n  iError := 0;\n  {$IFNDEF UNICODE}ASQL := SQL;{$ENDIF} //preprepares SQL and sets AnsiSQL(ASQL)\n  with FIBConnection do\n  begin\n    SQLData := TZResultSQLDA.Create(GetPlainDriver, GetDBHandle, GetTrHandle, ConSettings);\n    try\n      StatementType := ZDbcInterbase6Utils.PrepareStatement(GetPlainDriver,\n        GetDBHandle, GetTrHandle, GetDialect, ASQL, SSQL, StmtHandle);\n\n      PrepareResultSqlData(GetPlainDriver, GetDBHandle, GetDialect,\n          SSQL, StmtHandle, SQLData);\n\n      DriverManager.LogMessage(lcExecute, GetPlainDriver.GetProtocol, SSQL);\n\n      GetPlainDriver.isc_dsql_execute(@FStatusVector, GetTrHandle,\n        @StmtHandle, GetDialect, SQLData.GetData);\n      iError := CheckInterbase6Error(SSQL);\n\n      if (StatementType in [stSelect, stExecProc])\n        and (SQLData.GetFieldCount <> 0) then\n      begin\n        if CursorName <> '' then\n        begin\n          Cursor := CursorName;\n          GetPlainDriver.isc_dsql_set_cursor_name(@FStatusVector,\n                  @StmtHandle, PAnsiChar(Cursor), 0);\n          CheckInterbase6Error(SSQL);\n        end;\n\n        Result := CreateIBResultSet(SSQL, Self,\n               TZInterbase6ResultSet.Create(Self, LogSQL, StmtHandle, Cursor, SQLData, FCachedBlob));\n      end\n      else\n        if (iError <> DISCONNECT_ERROR) then\n          raise EZSQLException.Create(SCanNotRetrieveResultSetData);\n    except\n      on E: Exception do\n      begin\n        FreeStatement(GetPlainDriver, StmtHandle, DSQL_drop); //Free Stmt handle only if Execution fails. Otherwise the ResultSet will do this\n        raise;\n      end;\n    end;\n  end;\nend;\n{$HINTS OFF}\n\n{**\n  Executes an SQL <code>INSERT</code>, <code>UPDATE</code> or\n  <code>DELETE</code> statement. In addition,\n  SQL statements that return nothing, such as SQL DDL statements,\n  can be executed.\n\n  @param sql an SQL <code>INSERT</code>, <code>UPDATE</code> or\n    <code>DELETE</code> statement or an SQL statement that returns nothing\n  @return either the row count for <code>INSERT</code>, <code>UPDATE</code>\n    or <code>DELETE</code> statements, or 0 for SQL statements that return nothing\n}\n{$HINTS OFF}\nfunction TZInterbase6Statement.ExecuteUpdate(const SQL: RawByteString): Integer;\nvar\n  StmtHandle: TISC_STMT_HANDLE;\n  StatementType: TZIbSqlStatementType;\nbegin\n  Result := -1;\n  StmtHandle := 0;\n  with FIBConnection do\n  begin\n    try\n      {$IFNDEF UNICODE}ASQL := SQL;{$ENDIF} //preprepares SQL and sets AnsiSQL(ASQL)\n      StatementType := ZDbcInterbase6Utils.PrepareStatement(GetPlainDriver,\n        GetDBHandle, GetTrHandle, GetDialect, ASQL, SSQL, StmtHandle);\n\n      DriverManager.LogMessage(lcExecute, GetPlainDriver.GetProtocol, SSQL);\n\n      GetPlainDriver.isc_dsql_execute2(@FStatusVector, GetTrHandle,\n        @StmtHandle, GetDialect, nil, nil);\n      CheckInterbase6Error(SSQL);\n\n      case StatementType of\n        stCommit, stRollback, stUnknown: Result := -1;\n      else\n        begin\n          Result := GetAffectedRows(GetPlainDriver, StmtHandle, StatementType);\n          LastUpdateCount := Result;\n        end;\n      end;\n\n      { Autocommit statement. }\n      if Connection.GetAutoCommit then\n        Connection.Commit;\n      { Logging SQL Command }\n    finally\n      FreeStatement(GetPlainDriver, StmtHandle, DSQL_drop); //Free Stmt handle because of single executions without a prepared state\n    end;\n  end;\nend;\n{$HINTS ON}\n\n{**\n  Executes an SQL statement that may return multiple results.\n  Under some (uncommon) situations a single SQL statement may return\n  multiple result sets and/or update counts.  Normally you can ignore\n  this unless you are (1) executing a stored procedure that you know may\n  return multiple results or (2) you are dynamically executing an\n  unknown SQL string.  The  methods <code>execute</code>,\n  <code>getMoreResults</code>, <code>getResultSet</code>,\n  and <code>getUpdateCount</code> let you navigate through multiple results.\n\n  The <code>execute</code> method executes an SQL statement and indicates the\n  form of the first result.  You can then use the methods\n  <code>getResultSet</code> or <code>getUpdateCount</code>\n  to retrieve the result, and <code>getMoreResults</code> to\n  move to any subsequent result(s).\n\n  @param sql any SQL statement\n  @return <code>true</code> if the next result is a <code>ResultSet</code> object;\n  <code>false</code> if it is an update count or there are no more results\n  @see #getResultSet\n  @see #getUpdateCount\n  @see #getMoreResults\n}\n{$HINTS OFF}\nfunction TZInterbase6Statement.Execute(const SQL: RawByteString): Boolean;\nvar\n  Cursor: AnsiString;\n  SQLData: IZResultSQLDA;\n  StmtHandle: TISC_STMT_HANDLE;\n  StatementType: TZIbSqlStatementType;\nbegin\n  StmtHandle := 0;\n  with FIBConnection do\n  begin\n    try\n      Result := False;\n      {$IFNDEF UNICODE}ASQL := SQL;{$ENDIF} //preprepares SQL and sets AnsiSQL(ASQL)\n      StatementType := ZDbcInterbase6Utils.PrepareStatement(GetPlainDriver,\n        GetDBHandle, GetTrHandle, GetDialect, ASQL, LogSQL, StmtHandle);\n\n      { Check statement type }\n//      if not (StatementType in [stExecProc]) then\n//        raise EZSQLException.Create(SStatementIsNotAllowed);\n\n      { Create Result SQLData if statement returns result }\n      if StatementType in [stSelect, stExecProc] then\n      begin\n        SQLData := TZResultSQLDA.Create(GetPlainDriver, GetDBHandle, GetTrHandle, ConSettings);\n        PrepareResultSqlData(GetPlainDriver, GetDBHandle, GetDialect, LogSQL,\n          StmtHandle, SQLData);\n      end;\n\n      DriverManager.LogMessage(lcExecute, GetPlainDriver.GetProtocol, SSQL);\n      { Execute prepared statement }\n      GetPlainDriver.isc_dsql_execute(@FStatusVector, GetTrHandle,\n              @StmtHandle, GetDialect, nil);\n      CheckInterbase6Error(LogSQL);\n      { Set updated rows count }\n      LastUpdateCount := GetAffectedRows(GetPlainDriver, StmtHandle, StatementType);\n\n      case StatementType of\n        stInsert, stDelete, stUpdate, stSelectForUpdate: Result := False;\n      else\n        Result := True;\n      end;\n\n      { Create ResultSet if possible else free Stateent Handle }\n      if (StatementType in [stSelect, stExecProc])\n        and (SQLData.GetFieldCount <> 0) then\n      begin\n        if CursorName <> '' then\n        begin\n          Cursor := CursorName;\n\n          GetPlainDriver.isc_dsql_set_cursor_name(@FStatusVector,\n                  @StmtHandle, PAnsiChar(Cursor), 0);\n          CheckInterbase6Error(sSQL);\n        end;\n\n        LastResultSet := CreateIBResultSet(SSQL, Self,\n          TZInterbase6ResultSet.Create(Self, SSQL, StmtHandle, Cursor,\n            SQLData, FCachedBlob));\n      end\n      else\n      begin\n        LastResultSet := nil;\n        FreeStatement(GetPlainDriver, StmtHandle, DSQL_drop);\n      end;\n\n      { Autocommit statement. }\n      if Connection.GetAutoCommit then\n        Connection.Commit;\n    except\n      on E: Exception do\n      begin\n       FreeStatement(GetPlainDriver, StmtHandle, DSQL_drop); //Free Stmt handle because of single executions without a prepared state\n       raise;\n      end;\n    end;\n  end;\nend;\n{$HINTS ON}\n\n{ TZInterbase6PreparedStatement }\n\nprocedure TZInterbase6PreparedStatement.PrepareInParameters;\nvar\n  StatusVector: TARRAY_ISC_STATUS;\nbegin\n  With FIBConnection do\n    begin\n      {create the parameter bind structure}\n      FParamSQLData := TZParamsSQLDA.Create(GetPlainDriver, GetDBHandle, GetTrHandle, ConSettings);\n      {check dynamic sql}\n      GetPlainDriver.isc_dsql_describe_bind(@StatusVector, @StmtHandle, GetDialect,\n        FParamSQLData.GetData);\n      ZDbcInterbase6Utils.CheckInterbase6Error(GetPlainDriver, StatusVector, lcExecute, SSQL);\n\n      { Resize XSQLDA structure if needed }\n      if FParamSQLData.GetData^.sqld > FParamSQLData.GetData^.sqln then\n      begin\n        FParamSQLData.AllocateSQLDA;\n        GetPlainDriver.isc_dsql_describe_bind(@StatusVector, @StmtHandle, GetDialect,FParamSQLData.GetData);\n        ZDbcInterbase6Utils.CheckInterbase6Error(GetPlainDriver, StatusVector, lcExecute, SSQL);\n      end;\n\n      FParamSQLData.InitFields(True);\n    end;\n  inherited PrepareInParameters;\nend;\n\nprocedure TZInterbase6PreparedStatement.SetASQL(const Value: RawByteString);\nbegin\n  if ( ASQL <> Value ) and Prepared then\n    Unprepare;\n  inherited SetASQL(Value);\nend;\n\nprocedure TZInterbase6PreparedStatement.SetWSQL(const Value: ZWideString);\nbegin\n  if ( WSQL <> Value ) and Prepared then\n    Unprepare;\n  inherited SetWSQL(Value);\nend;\n\nprocedure TZInterbase6PreparedStatement.BindInParameters;\nbegin\n  BindSQLDAInParameters(FIBConnection.GetPlainDriver, InParamValues,\n    InParamTypes, InParamCount, FParamSQLData, GetConnection.GetConSettings);\n  inherited BindInParameters;\nend;\n\nprocedure TZInterbase6PreparedStatement.UnPrepareInParameters;\nbegin\n  if assigned(FParamSQLData) then\n    FParamSQLData.FreeParamtersValues;\nend;\n\n{**\n   Check interbase error status\n   @param Sql the used sql tring\n\n   @return Integer - Error Code to test for graceful database disconnection\n}\nfunction  TZInterbase6PreparedStatement.CheckInterbase6Error(const Sql: string) : Integer;\nbegin\n  Result := ZDbcInterbase6Utils.CheckInterbase6Error(FIBConnection.GetPlainDriver,\n    FStatusVector, lcExecute, SQL);\nend;\n\n{**\n  Constructs this object and assignes the main properties.\n  @param Connection a database connection object.\n  @param Handle a connection handle pointer.\n  @param Dialect a dialect Interbase SQL must be 1 or 2 or 3.\n  @param Info a statement parameters.\n}\nconstructor TZInterbase6PreparedStatement.Create(Connection: IZConnection;\n  const SQL: string; Info: TStrings);\nbegin\n  inherited Create(Connection, SQL, Info);\n\n  FIBConnection := Connection as IZInterbase6Connection;\n  ResultSetType := rtScrollInsensitive;\n  FCachedBlob := StrToBoolEx(DefineStatementParameter(Self, 'cashedblob', 'true'));\n  StmtHandle := 0;\n\n  Prepare;\nend;\n\ndestructor TZInterbase6PreparedStatement.Destroy;\nbegin\n  inherited Destroy;\n  FreeStatement(FIBConnection.GetPlainDriver, StmtHandle, DSQL_drop);\nend;\n\nprocedure TZInterbase6PreparedStatement.Prepare;\nbegin\n  with FIBConnection do\n  begin\n    StatementType := ZDbcInterbase6Utils.PrepareStatement(GetPlainDriver,\n      GetDBHandle, GetTrHandle, GetDialect, ASQL, LogSQL, StmtHandle); //allocate handle if required or reuse it\n\n    if StatementType in [stSelect, stExecProc] then\n    begin\n      SQLData := TZResultSQLDA.Create(GetPlainDriver, GetDBHandle,\n        GetTrHandle , ConSettings);\n      PrepareResultSqlData(GetPlainDriver, GetDBHandle, GetDialect,\n        SQL, StmtHandle, SQLData);\n    end;\n  end;\n  CheckInterbase6Error(SQL);\n  LogPrepStmtMessage(lcPrepStmt, SQL);\n  inherited Prepare;\nend;\n\nprocedure TZInterbase6PreparedStatement.Unprepare;\nbegin\n  if StmtHandle <> 0 then //check if prepare did fail. otherwise we unprepare the handle\n    FreeStatement(FIBConnection.GetPlainDriver, StmtHandle, DSQL_UNPREPARE); //unprepare avoids new allocation for the stmt handle\n  inherited Unprepare;\nend;\n\n{**\n  Executes any kind of SQL statement.\n  Some prepared statements return multiple results; the <code>execute</code>\n  method handles these complex statements as well as the simpler\n  form of statements handled by the methods <code>executeQuery</code>\n  and <code>executeUpdate</code>.\n  @see Statement#execute\n}\n{$HINTS OFF}\nfunction TZInterbase6PreparedStatement.ExecutePrepared: Boolean;\nbegin\n  Result := False;\n  if not Prepared then\n    Prepare;\n\n  with FIBConnection do\n  begin\n    try\n      BindInParameters;\n\n      if (StatementType = stSelect) then     //AVZ Get many rows - only need to use execute not execute2\n        GetPlainDriver.isc_dsql_execute(@FStatusVector, GetTrHandle, @StmtHandle,\n          GetDialect, FParamSQLData.GetData)\n      else\n      begin\n        CursorName := 'ExecProc'+RandomString(12); //AVZ - Need a way to return one row so we give the cursor a name\n        if (SQLData = nil) then\n          GetPlainDriver.isc_dsql_execute2(@FStatusVector, GetTrHandle, @StmtHandle,\n            GetDialect, FParamSQLData.GetData, nil) //not expecting a result\n        else\n          GetPlainDriver.isc_dsql_execute2(@FStatusVector, GetTrHandle, @StmtHandle,\n            GetDialect, FParamSQLData.GetData, SQLData.GetData); //expecting a result\n      end;\n\n      CheckInterbase6Error(SQL);\n\n      LastUpdateCount := GetAffectedRows(GetPlainDriver, StmtHandle, StatementType);\n\n      case StatementType of\n        stInsert,\n        stDelete,\n        stUpdate,\n        stSelectForUpdate:\n          Result := False;\n        else\n          Result := True;\n      end;\n\n      { Create ResultSet if possible else free Statement Handle }\n      if (StatementType in [stSelect, stExecProc])\n        and (SQLData.GetFieldCount <> 0) then\n      begin\n        LastResultSet := CreateIBResultSet(SQL, Self,\n        TZInterbase6ResultSet.Create(Self, SQL, StmtHandle, Cursor,\n        SQLData, FCachedBlob));\n      end\n        else\n      begin\n        LastResultSet := nil;\n      end;\n\n      { Autocommit statement. }\n      if Connection.GetAutoCommit then\n        Connection.Commit;\n    except\n      on E: Exception do\n      begin\n        {EH: do not Close the Stmt if execution fails !!}\n        //FreeStatement(GetPlainDriver, StmtHandle, DSQL_CLOSE); //AVZ\n       raise;\n      end;\n    end;\n  end;\n  inherited ExecutePrepared;\nend;\n{$HINTS ON}\n\n{**\n  Executes the SQL query in this <code>PreparedStatement</code> object\n  and returns the result set generated by the query.\n\n  @return a <code>ResultSet</code> object that contains the data produced by the\n    query; never <code>null</code>\n}\n{$HINTS OFF}\nfunction TZInterbase6PreparedStatement.ExecuteQueryPrepared: IZResultSet;\nvar\n  iError : Integer; //Check for database disconnect AVZ\nbegin\n  if not Prepared then\n    Prepare;\n\n  with FIBConnection do\n  begin\n    try\n      BindInParameters;\n\n      if (StatementType = stSelect) then     //AVZ Get many rows - only need to use execute not execute2\n        GetPlainDriver.isc_dsql_execute(@FStatusVector, GetTrHandle, @StmtHandle,\n          GetDialect, FParamSQLData.GetData)\n      else\n      begin\n        CursorName := 'ExecProc'+RandomString(12); //AVZ - Need a way to return one row so we give the cursor a name\n        if (SQLData = nil) then\n          GetPlainDriver.isc_dsql_execute2(@FStatusVector, GetTrHandle, @StmtHandle,\n            GetDialect, FParamSQLData.GetData, nil) //not expecting a result\n        else\n          GetPlainDriver.isc_dsql_execute2(@FStatusVector, GetTrHandle, @StmtHandle,\n            GetDialect, FParamSQLData.GetData, SQLData.GetData); //expecting a result\n      end;\n\n      iError := CheckInterbase6Error(SQL);\n\n      if (StatementType in [stSelect, stExecProc]) and (SQLData.GetFieldCount <> 0) then\n      begin\n        if CursorName <> '' then\n        begin\n          Cursor := CursorName;\n          GetPlainDriver.isc_dsql_set_cursor_name(@FStatusVector,\n                  @StmtHandle, PAnsiChar(Cursor), 0);\n          iError := CheckInterbase6Error(SQL);\n        end;\n\n        if (iError <> DISCONNECT_ERROR) then\n          Result := CreateIBResultSet(LogSQL, Self, TZInterbase6ResultSet.Create(Self, LogSQL, StmtHandle, Cursor, SQLData, FCachedBlob));\n      end\n      else\n        if (iError <> DISCONNECT_ERROR) then    //AVZ\n          raise EZSQLException.Create(SCanNotRetrieveResultSetData)\n        else\n          Result := nil;\n    except\n      on E: Exception do\n      begin\n        //The cursor will be already closed for exec2\n        if (Pos('ExecProc', String(CursorName)) <> 0) then\n          StmtHandle := 0;\n\n        {EH: do not Close the Stmt if execution fails !! This will be done on unprepare}\n        //FreeStatement(GetPlainDriver, StmtHandle, DSQL_CLOSE); //AVZ\n        raise;\n      end;\n    end;\n  end;\n  inherited ExecuteQueryPrepared;\nend;\n{$HINTS ON}\n\n{**\n  Executes the SQL INSERT, UPDATE or DELETE statement\n  in this <code>PreparedStatement</code> object.\n  In addition,\n  SQL statements that return nothing, such as SQL DDL statements,\n  can be executed.\n\n  @return either the row count for INSERT, UPDATE or DELETE statements;\n  or 0 for SQL statements that return nothing\n}\n{$HINTS OFF}\nfunction TZInterbase6PreparedStatement.ExecuteUpdatePrepared: Integer;\nvar\n  iError : Integer; //Implementation for graceful disconnect AVZ\nbegin\n  Result := -1;\n\n  if not Prepared then\n    Prepare;\n\n  with FIBConnection do\n  begin\n    BindInParameters;\n\n    GetPlainDriver.isc_dsql_execute(@FStatusVector, GetTrHandle,\n      @StmtHandle, GetDialect, FParamSQLData.GetData);\n    iError := CheckInterbase6Error(SQL);\n\n    Result := GetAffectedRows(GetPlainDriver, StmtHandle, StatementType);\n    LastUpdateCount := Result;\n\n    case StatementType of\n      stCommit, stRollback, stUnknown: Result := -1;\n      stSelect: FreeStatement(GetPlainDriver, StmtHandle, DSQL_CLOSE);  //AVZ\n    end;\n\n    { Autocommit statement. }\n    if Connection.GetAutoCommit and ( StatementType <> stSelect ) then\n      Connection.Commit;\n  end;\n  inherited ExecuteUpdatePrepared;\n\n  //Trail for the disconnection of the database gracefully - AVZ\n  if (iError = DISCONNECT_ERROR) then\n  begin\n    Result := DISCONNECT_ERROR;\n  end;\n\nend;\n{$HINTS ON}\n\n\n{ TZInterbase6CallableStatement }\n\n{**\n   Check interbase error status\n   @param Sql the used sql tring\n}\nprocedure TZInterbase6CallableStatement.CheckInterbase6Error(const Sql: string);\nbegin\n  ZDbcInterbase6Utils.CheckInterbase6Error(FIBConnection.GetPlainDriver,\n    FStatusVector, lcExecute, SQL);\nend;\n\n{**\n  Constructs this object and assignes the main properties.\n  @param Connection a database connection object.\n  @param Handle a connection handle pointer.\n  @param Dialect a dialect Interbase SQL must be 1 or 2 or 3.\n  @param Info a statement parameters.\n}\nconstructor TZInterbase6CallableStatement.Create(Connection: IZConnection;\n  const SQL: string; Info: TStrings);\nbegin\n  inherited Create(Connection, SQL, Info);\n\n  FIBConnection := Connection as IZInterbase6Connection;\n  ResultSetType := rtScrollInsensitive;\n  FCachedBlob := StrToBoolEx(DefineStatementParameter(Self, 'cashedblob', 'true'));\n  with FIBConnection do\n  begin\n    FParamSQLData := TZParamsSQLDA.Create(GetPlainDriver, GetDBHandle,\n      GetTrHandle, ConSettings);\n    FResultSQLData := TZResultSQLDA.Create(GetPlainDriver, GetDBHandle,\n      GetTrHandle, ConSettings);\n  end;\nend;\n\nprocedure TZInterbase6CallableStatement.PrepareInParameters;\nbegin\n  with FIBConnection do\n  begin\n    { Prepare statement }\n    FStatementType := ZDbcInterbase6Utils.PrepareStatement(GetPlainDriver,\n      GetDBHandle, GetTrHandle, GetDialect, ZPlainString(ProcSql), ProcSQL, FStmtHandle);\n    PrepareResultSqlData(GetPlainDriver, GetDBHandle, GetDialect,\n      SQL, FStmtHandle, FResultSQLData);\n    PrepareParameters(GetPlainDriver, ProcSql, GetDialect, FStmtHandle, FParamSQLData);\n  end;\nend;\n\nprocedure TZInterbase6CallableStatement.BindInParameters;\nbegin\n  BindSQLDAInParameters(FIBConnection.GetPlainDriver, InParamValues,\n    InParamTypes, InParamCount, FParamSQLData, ConSettings);\n  inherited BindInParameters;\nend;\n\nprocedure TZInterbase6CallableStatement.UnPrepareInParameters;\nbegin\n  if assigned(FParamSQLData) then\n    FParamSQLData.FreeParamtersValues;\nend;\n\nprocedure TZInterbase6CallableStatement.Unprepare;\nbegin\n  inherited Unprepare;\n  FreeStatement(FIBConnection.GetPlainDriver, FStmtHandle, DSQL_unprepare);\n  if FStmtHandle <> 0 then // Free statement-hande! On the other hand: Exception!\n  begin\n    FreeStatement(FIBConnection.GetPlainDriver, FStmtHandle, DSQL_drop);\n    FStmtHandle := 0;\n  end;\nend;\n\ndestructor TZInterbase6CallableStatement.Destroy;\nbegin\n  inherited Destroy;\n  if FStmtHandle <> 0 then\n    FreeStatement(FIBConnection.GetPlainDriver, FStmtHandle, DSQL_drop);\n  FResultSQLData := nil;\n  FParamSQLData := nil;\nend;\n\n{**\n  Executes any kind of SQL statement.\n  Some prepared statements return multiple results; the <code>execute</code>\n  method handles these complex statements as well as the simpler\n  form of statements handled by the methods <code>executeQuery</code>\n  and <code>executeUpdate</code>.\n  @see Statement#execute\n}\n{$HINTS OFF}\nfunction TZInterbase6CallableStatement.ExecutePrepared: Boolean;\nvar\n  Cursor: AnsiString;\nbegin\n  Result := False;\n  with FIBConnection do\n  begin\n    ProcSql := GetProcedureSql(False);\n    BindInParameters;\n    DriverManager.LogMessage(lcExecute, GetPlainDriver.GetProtocol, SQL);\n    try\n      GetPlainDriver.isc_dsql_execute2(@FStatusVector, GetTrHandle, @FStmtHandle,\n            GetDialect, FParamSQLData.GetData, Self.FResultSQLData.GetData);\n      CheckInterbase6Error(SQL);\n\n      LastUpdateCount := GetAffectedRows(GetPlainDriver, FStmtHandle, FStatementType);\n\n      case FStatementType of\n        stInsert, stDelete, stUpdate, stSelectForUpdate: Result := False;\n      else\n        Result := True;\n      end;\n\n      { Create ResultSet if possible else free Stateent Handle, ResultSQlData and\n        ParamSqlData }\n      if (FStatementType in [stSelect, stExecProc])\n        and (FResultSQLData.GetFieldCount <> 0) then\n      begin\n        Cursor := RandomString(12);\n        LastResultSet := CreateIBResultSet(SQL, Self,\n           TZInterbase6ResultSet.Create(Self, SQL, FStmtHandle, Cursor, FResultSQLData, FCachedBlob));\n      end\n      else\n      begin\n        { Fetch data and fill Output params }\n        FetchOutParams(FResultSQLData);\n        FreeStatement(GetPlainDriver, FStmtHandle, DSQL_CLOSE); //AVZ\n        LastResultSet := nil;\n      end;\n\n      { Autocommit statement. }\n      if Connection.GetAutoCommit then\n        Connection.Commit;\n\n    except\n      on E: Exception do\n      begin\n       //FreeStatement(GetPlainDriver, FStmtHandle, DSQL_CLOSE); //AVZ\n       raise;\n      end;\n    end;\n  end;\nend;\n{$HINTS ON}\n\n{**\n  Executes the SQL query in this <code>PreparedStatement</code> object\n  and returns the result set generated by the query.\n\n  @return a <code>ResultSet</code> object that contains the data produced by the\n    query; never <code>null</code>\n}\n{$HINTS OFF}\nfunction TZInterbase6CallableStatement.ExecuteQueryPrepared: IZResultSet;\nvar\n  Cursor: AnsiString;\nbegin\n  with FIBConnection do\n  begin\n    ProcSql := GetProcedureSql(True); //Prepares the Statement\n    BindInParameters;\n    try\n      DriverManager.LogMessage(lcExecute, GetPlainDriver.GetProtocol, ProcSql);\n\n      if (FStatementType = stSelect) then     //AVZ Get many rows - only need to use execute not execute2\n        GetPlainDriver.isc_dsql_execute(@FStatusVector, GetTrHandle, @FStmtHandle,\n          GetDialect, FParamSQLData.GetData)\n      else\n      begin\n        CursorName := 'ExecProc'+RandomString(12); //AVZ - Need a way to return one row so we give the cursor a name\n        GetPlainDriver.isc_dsql_execute2(@FStatusVector, GetTrHandle, @FStmtHandle,\n          GetDialect, FParamSQLData.GetData, FResultSQLData.GetData);\n      end;\n\n      CheckInterbase6Error(ProcSql);\n\n      if (FStatementType in [stSelect, stExecProc]) and (FResultSQLData.GetFieldCount <> 0) then\n      begin\n        if CursorName <> '' then\n        begin\n          Cursor := CursorName;\n          GetPlainDriver.isc_dsql_set_cursor_name(@FStatusVector, @FStmtHandle, PAnsiChar(Cursor), 0);\n          CheckInterbase6Error(ProcSql);\n        end;\n\n        Result := CreateIBResultSet(ProcSql, Self,\n          TZInterbase6ResultSet.Create(Self, ProcSql, FStmtHandle, Cursor,\n          FResultSQLData, FCachedBlob));\n      end;\n\n    except\n      on E: Exception do\n      begin\n        //FreeStatement(GetPlainDriver, FStmtHandle, DSQL_unprepare); //AVZ\n        raise;\n      end;\n    end;\n  end;\nend;\n{$HINTS ON}\n\n{**\n  Executes the SQL INSERT, UPDATE or DELETE statement\n  in this <code>PreparedStatement</code> object.\n  In addition,\n  SQL statements that return nothing, such as SQL DDL statements,\n  can be executed.\n\n  @return either the row count for INSERT, UPDATE or DELETE statements;\n  or 0 for SQL statements that return nothing\n}\nfunction TZInterbase6CallableStatement.ExecuteUpdatePrepared: Integer;\nbegin\n  with FIBConnection do\n  begin\n    try\n      ProcSQL := Self.GetProcedureSql(False);\n      BindInParameters;\n\n      DriverManager.LogMessage(lcExecute, GetPlainDriver.GetProtocol, ProcSQL);\n\n      GetPlainDriver.isc_dsql_execute2(@FStatusVector, GetTrHandle, @FStmtHandle,\n        GetDialect, FParamSQLData.GetData, FResultSQLData.GetData);\n      CheckInterbase6Error(ProcSql);\n\n      Result := GetAffectedRows(GetPlainDriver, FStmtHandle, FStatementType);\n      LastUpdateCount := Result;\n      { Fetch data and fill Output params }\n      FetchOutParams(FResultSQLData);\n      { Autocommit statement. }\n      if Connection.GetAutoCommit then\n        Connection.Commit;\n\n    finally\n      //FreeStatement(GetPlainDriver, FStmtHandle, DSQL_unprepare); //AVZ -- unprepare the statement - not close it\n\n    end;\n  end;\nend;\n\n{**\n  Set output parameters values from TZResultSQLDA.\n  @param Value a TZResultSQLDA object.\n}\nprocedure TZInterbase6CallableStatement.FetchOutParams(\n  Value: IZResultSQLDA);\nvar\n  ParamIndex, I: Integer;\n  Temp: TZVariant;\nbegin\n  I := 0;\n  for ParamIndex := 0 to OutParamCount - 1 do\n  begin\n    if not (FDBParamTypes[ParamIndex] in [2, 3, 4]) then // ptOutput, ptInputOutput, ptResult\n      Continue;\n\n    if I >= Value.GetFieldCount then\n      Break;\n\n    if Value.IsNull(I) then\n      DefVarManager.SetNull(Temp)\n    else\n      case Value.GetFieldSqlType(I) of\n      stBoolean:\n        DefVarManager.SetAsBoolean(Temp, Value.GetBoolean(I));\n      stByte:\n        DefVarManager.SetAsInteger(Temp, Value.GetByte(I));\n      stBytes:\n        DefVarManager.SetAsBytes(Temp, Value.GetBytes(I));\n      stShort:\n        DefVarManager.SetAsInteger(Temp, Value.GetShort(I));\n      stInteger:\n        DefVarManager.SetAsInteger(Temp, Value.GetInt(I));\n      stLong:\n        DefVarManager.SetAsInteger(Temp, Value.GetLong(I));\n      stFloat:\n        DefVarManager.SetAsFloat(Temp, Value.GetFloat(I));\n      stDouble:\n        DefVarManager.SetAsFloat(Temp, Value.GetDouble(I));\n      stBigDecimal:\n        DefVarManager.SetAsFloat(Temp, Value.GetBigDecimal(I));\n      stString:\n        DefVarManager.SetAsString(Temp, ZDbcString(Value.GetString(I)));\n      stUnicodeString:\n        DefVarManager.SetAsUnicodeString(Temp, ZDbcUnicodeString(Value.GetString(I)));\n      stDate:\n        DefVarManager.SetAsDateTime(Temp, Value.GetDate(I));\n      stTime:\n        DefVarManager.SetAsDateTime(Temp, Value.GetTime(I));\n      stTimestamp:\n        DefVarManager.SetAsDateTime(Temp, Value.GetTimestamp(I));\n    end;\n    OutParamValues[ParamIndex] := Temp;\n    Inc(I);\n  end;\nend;\n\n{**\n   Create sql string for calling stored procedure.\n   @param SelectProc indicate use <b>EXECUTE PROCEDURE</b> or\n    <b>SELECT</b> staement\n   @return a Stored Procedure SQL string \n}\nfunction TZInterbase6CallableStatement.GetProcedureSql(SelectProc: boolean): string;\n\n  function GenerateParamsStr(Count: integer): string;\n  var\n    I: integer;\n  begin\n    Result := ''; //init Result -> FPC\n    for I := 0 to Count - 1 do\n    begin\n      if I > 0 then\n        Result := Result + ',';\n      Result := Result + '?';\n    end;\n  end;\n\nvar\n  InParams: string;\nbegin\n  TrimInParameters;\n  InParams := GenerateParamsStr(High(InParamValues) + 1);\n  if InParams <> '' then\n    InParams := '(' + InParams + ')';\n\n  if SelectProc then\n    Result := 'SELECT * FROM ' + SQL + InParams\n  else\n    Result := 'EXECUTE PROCEDURE ' + SQL + InParams;\nend;\n\nend.\n"
  },
  {
    "path": "lib/zeosdbo/src/dbc/ZDbcInterbase6Utils.pas",
    "content": "{*********************************************************}\n{                                                         }\n{                 Zeos Database Objects                   }\n{         Interbase Database Connectivity Classes         }\n{                                                         }\n{        Originally written by Sergey Merkuriev           }\n{                                                         }\n{*********************************************************}\n\n{@********************************************************}\n{    Copyright (c) 1999-2012 Zeos Development Group       }\n{                                                         }\n{ License Agreement:                                      }\n{                                                         }\n{ This library is distributed in the hope that it will be }\n{ useful, but WITHOUT ANY WARRANTY; without even the      }\n{ implied warranty of MERCHANTABILITY or FITNESS FOR      }\n{ A PARTICULAR PURPOSE.  See the GNU Lesser General       }\n{ Public License for more details.                        }\n{                                                         }\n{ The source code of the ZEOS Libraries and packages are  }\n{ distributed under the Library GNU General Public        }\n{ License (see the file COPYING / COPYING.ZEOS)           }\n{ with the following  modification:                       }\n{ As a special exception, the copyright holders of this   }\n{ library give you permission to link this library with   }\n{ independent modules to produce an executable,           }\n{ regardless of the license terms of these independent    }\n{ modules, and to copy and distribute the resulting       }\n{ executable under terms of your choice, provided that    }\n{ you also meet, for each linked independent module,      }\n{ the terms and conditions of the license of that module. }\n{ An independent module is a module which is not derived  }\n{ from or based on this library. If you modify this       }\n{ library, you may extend this exception to your version  }\n{ of the library, but you are not obligated to do so.     }\n{ If you do not wish to do so, delete this exception      }\n{ statement from your version.                            }\n{                                                         }\n{                                                         }\n{ The project web site is located on:                     }\n{   http://zeos.firmos.at  (FORUM)                        }\n{   http://sourceforge.net/p/zeoslib/tickets/ (BUGTRACKER)}\n{   svn://svn.code.sf.net/p/zeoslib/code-0/trunk (SVN)    }\n{                                                         }\n{   http://www.sourceforge.net/projects/zeoslib.          }\n{                                                         }\n{                                                         }\n{                                 Zeos Development Group. }\n{********************************************************@}\n\nunit ZDbcInterbase6Utils;\n\ninterface\n\n{$I ZDbc.inc}\n\nuses\n  SysUtils, Classes, {$IFDEF MSEgui}mclasses,{$ENDIF} Types,\n  ZDbcIntfs, ZDbcStatement, ZPlainFirebirdDriver, ZCompatibility,\n  ZPlainFirebirdInterbaseConstants, ZDbcCachedResultSet, ZDbcLogging, ZMessages,\n  ZVariant, ZTokenizer;\n\ntype\n  { Interbase Statement Type }\n  TZIbSqlStatementType = (stUnknown, stSelect, stInsert, stUpdate, stDelete,\n    stDDL, stGetSegment, stPutSegment, stExecProc, stStartTrans, stCommit,\n    stRollback, stSelectForUpdate, stSetGenerator, stDisconnect);\n\n  { Interbase Error Class}\n  EZIBConvertError = class(Exception);\n\n  { Paparameter string name and it value}\n  TZIbParam = record\n    Name: AnsiString;\n    Number: word;\n  end;\n  PZIbParam = ^TZIbParam;\n\n  { Interbase blob Information structure\n    contain iformation about blob size in bytes,\n    segments count, segment size in bytes and blob type\n    Note: blob type can be text an binary }\n  TIbBlobInfo = record\n    NumSegments: Word;\n    MaxSegmentSize: Word;\n    BlobType: SmallInt;\n    TotalSize: LongInt;\n  end;\n\n  { Base interface for sqlda }\n  IZSQLDA = interface\n    ['{2D0D6029-B31C-4E39-89DC-D86D20437C35}']\n    procedure InitFields(Parameters: boolean);\n    procedure AllocateSQLDA;\n    procedure FreeParamtersValues;\n\n    function GetData: PXSQLDA;\n    function IsBlob(const Index: Word): boolean;\n    function IsNullable(const Index: Word): boolean;\n\n    function GetFieldCount: Integer;\n    function GetFieldSqlName(const Index: Word): String;\n    function GetFieldRelationName(const Index: Word): String;\n    function GetFieldOwnerName(const Index: Word): String;\n    function GetFieldAliasName(const Index: Word): String;\n    function GetFieldIndex(const Name: AnsiString): Word;\n    function GetFieldScale(const Index: Word): integer;\n    function GetFieldSqlType(const Index: Word): TZSQLType;\n    function GetFieldLength(const Index: Word): SmallInt;\n    function GetIbSqlType(const Index: Word): Smallint;\n    function GetIbSqlSubType(const Index: Word): Smallint;\n    function GetIbSqlLen(const Index: Word): Smallint;\n  end;\n\n  { parameters interface sqlda}\n  IZParamsSQLDA = interface(IZSQLDA)\n    ['{D2C3D5E1-F3A6-4223-9A6E-3048B99A06C4}']\n    procedure WriteBlob(const Index: Integer; Stream: TStream);\n    procedure UpdateNull(const Index: Integer; Value: boolean);\n    procedure UpdateBoolean(const Index: Integer; Value: boolean);\n    procedure UpdateByte(const Index: Integer; Value: ShortInt);\n    procedure UpdateShort(const Index: Integer; Value: SmallInt);\n    procedure UpdateInt(const Index: Integer; Value: Integer);\n    procedure UpdateLong(const Index: Integer; Value: Int64);\n    procedure UpdateFloat(const Index: Integer; Value: Single);\n    procedure UpdateDouble(const Index: Integer; Value: Double);\n    procedure UpdateBigDecimal(const Index: Integer; Value: Extended);\n    procedure UpdatePChar(const Index: Integer; Value: PAnsiChar);\n    procedure UpdateString(const Index: Integer; Value: RawByteString);\n    procedure UpdateBytes(const Index: Integer; Value: TByteDynArray);\n    procedure UpdateDate(const Index: Integer; Value: TDateTime);\n    procedure UpdateTime(const Index: Integer; Value: TDateTime);\n    procedure UpdateTimestamp(const Index: Integer; Value: TDateTime);\n    procedure UpdateQuad(const Index: Word; const Value: TISC_QUAD);\n  end;\n\n  { Result interface for sqlda}\n  IZResultSQLDA = interface(IZSQLDA)\n    ['{D2C3D5E1-F3A6-4223-9A6E-3048B99A06C4}']\n    procedure ReadBlobFromStream(const Index: Word; Stream: TStream);\n    procedure ReadBlobFromString(const Index: Word; var str: AnsiString);\n    procedure ReadBlobFromVariant(const Index: Word; var Value: Variant);\n\n    function IsNull(const Index: Integer): Boolean;\n    function GetPChar(const Index: Integer): PChar;\n    function GetString(const Index: Integer): RawByteString;\n    function GetBoolean(const Index: Integer): Boolean;\n    function GetByte(const Index: Integer): Byte;\n    function GetShort(const Index: Integer): SmallInt;\n    function GetInt(const Index: Integer): Integer;\n    function GetLong(const Index: Integer): Int64;\n    function GetFloat(const Index: Integer): Single;\n    function GetDouble(const Index: Integer): Double;\n    function GetBigDecimal(const Index: Integer): Extended;\n    function GetBytes(const Index: Integer): TByteDynArray;\n    function GetDate(const Index: Integer): TDateTime;\n    function GetTime(const Index: Integer): TDateTime;\n    function GetTimestamp(const Index: Integer): TDateTime;\n    function GetValue(const Index: Word): Variant;\n    function GetQuad(const Index: Integer): TISC_QUAD;\n  end;\n\n  { Base class contain core functions to work with sqlda structure\n    Can allocate memory for sqlda structure get basic information }\n  TZSQLDA = class (TZCodePagedObject, IZSQLDA)\n  private\n    FHandle: PISC_DB_HANDLE;\n    FTransactionHandle: PISC_TR_HANDLE;\n    FXSQLDA: PXSQLDA;\n    FPlainDriver: IZInterbasePlainDriver;\n    Temp: AnsiString;\n    procedure CheckRange(const Index: Word);\n    procedure IbReAlloc(var P; OldSize, NewSize: Integer);\n    procedure SetFieldType(const Index: Word; Size: Integer; Code: Smallint;\n      Scale: Smallint);\n  public\n    constructor Create(PlainDriver: IZInterbasePlainDriver;\n      Handle: PISC_DB_HANDLE; TransactionHandle: PISC_TR_HANDLE;\n      ConSettings: PZConSettings); virtual;\n    procedure InitFields(Parameters: boolean);\n    procedure AllocateSQLDA; virtual;\n    procedure FreeParamtersValues;\n\n    function IsBlob(const Index: Word): boolean;\n    function IsNullable(const Index: Word): boolean;\n\n    function GetFieldCount: Integer;\n    function GetFieldSqlName(const Index: Word): String;\n    function GetFieldOwnerName(const Index: Word): String;\n    function GetFieldRelationName(const Index: Word): String;\n    function GetFieldAliasName(const Index: Word): String;\n    function GetFieldIndex(const Name: AnsiString): Word;\n    function GetFieldScale(const Index: Word): integer;\n    function GetFieldSqlType(const Index: Word): TZSQLType;\n    function GetFieldLength(const Index: Word): SmallInt;\n    function GetData: PXSQLDA;\n\n    function GetIbSqlType(const Index: Word): Smallint;\n    function GetIbSqlSubType(const Index: Word): Smallint;\n    function GetIbSqlLen(const Index: Word): Smallint;\n  end;\n\n  { Parameters class for sqlda structure.\n    It clas can only write data to parameters/fields }\n  TZParamsSQLDA = class (TZSQLDA, IZParamsSQLDA)\n  private\n    procedure EncodeString(Code: Smallint; const Index: Word; const Str: RawByteString);\n    procedure EncodeBytes(Code: Smallint; const Index: Word; const Value: TByteDynArray);\n    procedure UpdateDateTime(const Index: Integer; Value: TDateTime);\n  public\n    destructor Destroy; override;\n\n    procedure WriteBlob(const Index: Integer; Stream: TStream);\n\n    procedure UpdateNull(const Index: Integer; Value: boolean);\n    procedure UpdateBoolean(const Index: Integer; Value: boolean);\n    procedure UpdateByte(const Index: Integer; Value: ShortInt);\n    procedure UpdateShort(const Index: Integer; Value: SmallInt);\n    procedure UpdateInt(const Index: Integer; Value: Integer);\n    procedure UpdateLong(const Index: Integer; Value: Int64);\n    procedure UpdateFloat(const Index: Integer; Value: Single);\n    procedure UpdateDouble(const Index: Integer; Value: Double);\n    procedure UpdateBigDecimal(const Index: Integer; Value: Extended);\n    procedure UpdatePChar(const Index: Integer; Value: PAnsiChar);\n    procedure UpdateString(const Index: Integer; Value: RawByteString);\n    procedure UpdateBytes(const Index: Integer; Value: TByteDynArray);\n    procedure UpdateDate(const Index: Integer; Value: TDateTime);\n    procedure UpdateTime(const Index: Integer; Value: TDateTime);\n    procedure UpdateTimestamp(const Index: Integer; Value: TDateTime);\n    procedure UpdateQuad(const Index: Word; const Value: TISC_QUAD);\n  end;\n\n  { Resultset class for sqlda structure.\n    It class read data from sqlda fields }\n  TZResultSQLDA = class (TZSQLDA, IZResultSQLDA)\n  private\n    function DecodeString(const Code: Smallint; const Index: Word): RawByteString;\n    procedure DecodeString2(const Code: Smallint; const Index: Word; out Str: RawByteString);\n  protected\n    FDefaults: array of Variant;\n  public\n    destructor Destroy; override;\n\n    procedure AllocateSQLDA; override;\n\n    procedure ReadBlobFromStream(const Index: Word; Stream: TStream);\n    procedure ReadBlobFromString(const Index: Word; var str: AnsiString);\n    procedure ReadBlobFromVariant(const Index: Word; var Value: Variant);\n\n    function IsNull(const Index: Integer): Boolean;\n    function GetPChar(const Index: Integer): PChar;\n    function GetString(const Index: Integer): RawByteString;\n    function GetBoolean(const Index: Integer): Boolean;\n    function GetByte(const Index: Integer): Byte;\n    function GetShort(const Index: Integer): SmallInt;\n    function GetInt(const Index: Integer): Integer;\n    function GetLong(const Index: Integer): Int64;\n    function GetFloat(const Index: Integer): Single;\n    function GetDouble(const Index: Integer): Double;\n    function GetBigDecimal(const Index: Integer): Extended;\n    function GetBytes(const Index: Integer): TByteDynArray;\n    function GetDate(const Index: Integer): TDateTime;\n    function GetTime(const Index: Integer): TDateTime;\n    function GetTimestamp(const Index: Integer): TDateTime;\n    function GetValue(const Index: Word): Variant;\n    function GetQuad(const Index: Integer): TISC_QUAD;\n  end;\n\n  function RandomString(Len: integer): AnsiString;\n  function CreateIBResultSet(SQL: string; Statement: IZStatement;\n    NativeResultSet: IZResultSet): IZResultSet;\n\n  {Interbase6 Connection Functions}\n  function GenerateDPB(Info: TStrings; var FDPBLength, Dialect: Word): PAnsiChar;\n  function GenerateTPB(Params: TStrings; var Handle: TISC_DB_HANDLE): PISC_TEB;\n  function GetInterbase6DatabaseParamNumber(const Value: AnsiString): word;\n  function GetInterbase6TransactionParamNumber(const Value: AnsiString): word;\n\n  { Interbase6 errors functions }\n  function GetNameSqlType(Value: Word): AnsiString;\n  function CheckInterbase6Error(PlainDriver: IZInterbasePlainDriver;\n    StatusVector: TARRAY_ISC_STATUS; LoggingCategory: TZLoggingCategory = lcOther;\n    SQL: string = '') : Integer;\n\n  { Interbase information functions}\n  function GetVersion(PlainDriver: IZInterbasePlainDriver;\n    Handle: PISC_DB_HANDLE): AnsiString;\n  function GetDBImplementationNo(PlainDriver: IZInterbasePlainDriver;\n    Handle: PISC_DB_HANDLE): LongInt;\n  function GetDBImplementationClass(PlainDriver: IZInterbasePlainDriver;\n    Handle: PISC_DB_HANDLE): LongInt;\n  function GetLongDbInfo(PlainDriver: IZInterbasePlainDriver;\n    Handle: PISC_DB_HANDLE; DatabaseInfoCommand: Integer): LongInt;\n  function GetStringDbInfo(PlainDriver: IZInterbasePlainDriver;\n    Handle: PISC_DB_HANDLE; DatabaseInfoCommand: Integer): AnsiString;\n  function GetDBSQLDialect(PlainDriver: IZInterbasePlainDriver;\n    Handle: PISC_DB_HANDLE): Integer;\n\n  { Interbase statement functions}\n  function PrepareStatement(PlainDriver: IZInterbasePlainDriver;\n    Handle: PISC_DB_HANDLE; TrHandle: PISC_TR_HANDLE; Dialect: Word;\n    SQL: RawByteString; LogSQL: String;\n    var StmtHandle: TISC_STMT_HANDLE): TZIbSqlStatementType;\n  procedure PrepareResultSqlData(PlainDriver: IZInterbasePlainDriver;\n    Handle: PISC_DB_HANDLE; Dialect: Word; LogSQL: string;\n    var StmtHandle: TISC_STMT_HANDLE; SqlData: IZResultSQLDA);\n  procedure PrepareParameters(PlainDriver: IZInterbasePlainDriver; LogSQL: string;\n    Dialect: Word; var StmtHandle: TISC_STMT_HANDLE; ParamSqlData: IZParamsSQLDA);\n  procedure BindSQLDAInParameters(PlainDriver: IZInterbasePlainDriver;\n    InParamValues: TZVariantDynArray; InParamTypes: TZSQLTypeArray;\n    InParamCount: Integer; ParamSqlData: IZParamsSQLDA; ConSettings: PZConSettings);\n  procedure FreeStatement(PlainDriver: IZInterbasePlainDriver;\n    StatementHandle: TISC_STMT_HANDLE; Options : Word);\n  function GetStatementType(PlainDriver: IZInterbasePlainDriver;\n    StmtHandle: TISC_STMT_HANDLE): TZIbSqlStatementType;\n  function GetAffectedRows(PlainDriver: IZInterbasePlainDriver;\n    StmtHandle: TISC_STMT_HANDLE; StatementType: TZIbSqlStatementType): integer;\n\n  function ConvertInterbase6ToSqlType(SqlType, SqlSubType: Integer;\n    const CtrlsCPType: TZControlsCodePage): TZSqlType;\n\n  { interbase blob routines }\n  procedure GetBlobInfo(PlainDriver: IZInterbasePlainDriver;\n    BlobHandle: TISC_BLOB_HANDLE; var BlobInfo: TIbBlobInfo);\n  procedure ReadBlobBufer(PlainDriver: IZInterbasePlainDriver;\n    Handle: PISC_DB_HANDLE; TransactionHandle: PISC_TR_HANDLE;\n    BlobId: TISC_QUAD; var Size: Integer; var Buffer: Pointer);\n  function GetIBScaleDivisor(Scale: SmallInt): Int64;\n\n\nconst\n  { Default Interbase blob size for readig }\n  DefaultBlobSegmentSize = 16 * 1024;\n\n  IBScaleDivisor: array[-15..-1] of Int64 = (1000000000000000,100000000000000,\n    10000000000000,1000000000000,100000000000,10000000000,1000000000,100000000,\n    10000000,1000000,100000,10000,1000,100,10);\n\n  { count database parameters }\n  MAX_DPB_PARAMS = 67;\n  { prefix database parameters names it used in paramters scann procedure }\n  BPBPrefix = 'isc_dpb_';\n  { list database parameters and their apropriate numbers }\n  DatabaseParams: array [0..MAX_DPB_PARAMS]of TZIbParam = (\n    (Name:'isc_dpb_version1';         Number: isc_dpb_version1),\n    (Name:'isc_dpb_cdd_pathname';     Number: isc_dpb_cdd_pathname),\n    (Name:'isc_dpb_allocation';       Number: isc_dpb_allocation),\n    (Name:'isc_dpb_journal';          Number: isc_dpb_journal),\n    (Name:'isc_dpb_page_size';        Number: isc_dpb_page_size),\n    (Name:'isc_dpb_num_buffers';      Number: isc_dpb_num_buffers),\n    (Name:'isc_dpb_buffer_length';    Number: isc_dpb_buffer_length),\n    (Name:'isc_dpb_debug';            Number: isc_dpb_debug),\n    (Name:'isc_dpb_garbage_collect';  Number: isc_dpb_garbage_collect),\n    (Name:'isc_dpb_verify';           Number: isc_dpb_verify),\n    (Name:'isc_dpb_sweep';            Number: isc_dpb_sweep),\n    (Name:'isc_dpb_enable_journal';   Number: isc_dpb_enable_journal),\n    (Name:'isc_dpb_disable_journal';  Number: isc_dpb_disable_journal),\n    (Name:'isc_dpb_dbkey_scope';      Number: isc_dpb_dbkey_scope),\n    (Name:'isc_dpb_number_of_users';  Number: isc_dpb_number_of_users),\n    (Name:'isc_dpb_trace';            Number: isc_dpb_trace),\n    (Name:'isc_dpb_no_garbage_collect'; Number: isc_dpb_no_garbage_collect),\n    (Name:'isc_dpb_damaged';          Number: isc_dpb_damaged),\n    (Name:'isc_dpb_license';          Number: isc_dpb_license),\n    (Name:'isc_dpb_sys_user_name';    Number: isc_dpb_sys_user_name),\n    (Name:'isc_dpb_encrypt_key';      Number: isc_dpb_encrypt_key),\n    (Name:'isc_dpb_activate_shadow';  Number: isc_dpb_activate_shadow),\n    (Name:'isc_dpb_sweep_interval';   Number: isc_dpb_sweep_interval),\n    (Name:'isc_dpb_delete_shadow';    Number: isc_dpb_delete_shadow),\n    (Name:'isc_dpb_force_write';      Number: isc_dpb_force_write),\n    (Name:'isc_dpb_begin_log';        Number: isc_dpb_begin_log),\n    (Name:'isc_dpb_quit_log';         Number: isc_dpb_quit_log),\n    (Name:'isc_dpb_no_reserve';       Number: isc_dpb_no_reserve),\n    (Name:'isc_dpb_username';         Number: isc_dpb_user_name),\n    (Name:'isc_dpb_password';         Number: isc_dpb_password),\n    (Name:'isc_dpb_password_enc';     Number: isc_dpb_password_enc),\n    (Name:'isc_dpb_sys_user_name_enc';  Number: isc_dpb_sys_user_name_enc),\n    (Name:'isc_dpb_interp';           Number: isc_dpb_interp),\n    (Name:'isc_dpb_online_dump';      Number: isc_dpb_online_dump),\n    (Name:'isc_dpb_old_file_size';    Number: isc_dpb_old_file_size),\n    (Name:'isc_dpb_old_num_files';    Number: isc_dpb_old_num_files),\n    (Name:'isc_dpb_old_file';         Number: isc_dpb_old_file),\n    (Name:'isc_dpb_old_start_page';   Number: isc_dpb_old_start_page),\n    (Name:'isc_dpb_old_start_seqno';  Number: isc_dpb_old_start_seqno),\n    (Name:'isc_dpb_old_start_file';   Number: isc_dpb_old_start_file),\n    (Name:'isc_dpb_drop_walfile';     Number: isc_dpb_drop_walfile),\n    (Name:'isc_dpb_old_dump_id';      Number: isc_dpb_old_dump_id),\n    (Name:'isc_dpb_wal_backup_dir';   Number: isc_dpb_wal_backup_dir),\n    (Name:'isc_dpb_wal_chkptlen';     Number: isc_dpb_wal_chkptlen),\n    (Name:'isc_dpb_wal_numbufs';      Number: isc_dpb_wal_numbufs),\n    (Name:'isc_dpb_wal_bufsize';      Number: isc_dpb_wal_bufsize),\n    (Name:'isc_dpb_wal_grp_cmt_wait'; Number: isc_dpb_wal_grp_cmt_wait),\n    (Name:'isc_dpb_lc_messages';      Number: isc_dpb_lc_messages),\n    (Name:'isc_dpb_lc_ctype';         Number: isc_dpb_lc_ctype),\n    (Name:'isc_dpb_cache_manager';    Number: isc_dpb_cache_manager),\n    (Name:'isc_dpb_shutdown';         Number: isc_dpb_shutdown),\n    (Name:'isc_dpb_online';           Number: isc_dpb_online),\n    (Name:'isc_dpb_shutdown_delay';   Number: isc_dpb_shutdown_delay),\n    (Name:'isc_dpb_reserved';         Number: isc_dpb_reserved),\n    (Name:'isc_dpb_overwrite';        Number: isc_dpb_overwrite),\n    (Name:'isc_dpb_sec_attach';       Number: isc_dpb_sec_attach),\n    (Name:'isc_dpb_disable_wal';      Number: isc_dpb_disable_wal),\n    (Name:'isc_dpb_connect_timeout';  Number: isc_dpb_connect_timeout),\n    (Name:'isc_dpb_dummy_packet_interval'; Number: isc_dpb_dummy_packet_interval),\n    (Name:'isc_dpb_gbak_attach';      Number: isc_dpb_gbak_attach),\n    (Name:'isc_dpb_sql_role_name';    Number: isc_dpb_sql_role_name),\n    (Name:'isc_dpb_set_page_buffers'; Number: isc_dpb_set_page_buffers),\n    (Name:'isc_dpb_working_directory';  Number: isc_dpb_working_directory),\n    (Name:'isc_dpb_sql_dialect';      Number: isc_dpb_SQL_dialect),\n    (Name:'isc_dpb_set_db_readonly';  Number: isc_dpb_set_db_readonly),\n    (Name:'isc_dpb_set_db_sql_dialect'; Number: isc_dpb_set_db_SQL_dialect),\n    (Name:'isc_dpb_gfix_attach';      Number: isc_dpb_gfix_attach),\n    (Name:'isc_dpb_gstat_attach';     Number: isc_dpb_gstat_attach)\n  );\n\n  { count transaction parameters }\n  MAX_TPB_PARAMS = 16;\n  { prefix transaction parameters names it used in paramters scann procedure }\n  TPBPrefix = 'isc_tpb_';\n  { list transaction parameters and their apropriate numbers }\n  TransactionParams: array [0..MAX_TPB_PARAMS]of TZIbParam = (\n    (Name:'isc_tpb_version1';         Number: isc_tpb_version1),\n    (Name:'isc_tpb_version3';         Number: isc_tpb_version3),\n    (Name:'isc_tpb_consistency';      Number: isc_tpb_consistency),\n    (Name:'isc_tpb_concurrency';      Number: isc_tpb_concurrency),\n    (Name:'isc_tpb_exclusive';        Number: isc_tpb_exclusive),\n    (Name:'isc_tpb_shared';           Number: isc_tpb_shared),\n    (Name:'isc_tpb_protected';        Number: isc_tpb_protected),\n    (Name:'isc_tpb_wait';             Number: isc_tpb_wait),\n    (Name:'isc_tpb_nowait';           Number: isc_tpb_nowait),\n    (Name:'isc_tpb_read';             Number: isc_tpb_read),\n    (Name:'isc_tpb_write';            Number: isc_tpb_write),\n    (Name:'isc_tpb_ignore_limbo';     Number: isc_tpb_ignore_limbo),\n    (Name:'isc_tpb_read_committed';   Number: isc_tpb_read_committed),\n    (Name:'isc_tpb_rec_version';      Number: isc_tpb_rec_version),\n    (Name:'isc_tpb_no_rec_version';   Number: isc_tpb_no_rec_version),\n    (Name:'isc_tpb_lock_read';        Number: isc_tpb_lock_read),\n    (Name:'isc_tpb_lock_write';       Number: isc_tpb_lock_write)\n    );\n\nimplementation\n\nuses\n  Variants, ZSysUtils, Math, ZDbcInterbase6, ZEncoding\n  {$IFDEF WITH_UNITANSISTRINGS}, AnsiStrings{$ENDIF};\n\n{**\n   Generate specific length random string and return it\n   @param Len a length result string\n   @return random string\n}\nfunction RandomString(Len: integer): AnsiString;\nbegin\n  Result := '';\n  while Length(Result) < Len do\n    Result := Result + AnsiString(IntToStr(Trunc(Random(High(Integer)))));\n  if Length(Result) > Len then\n    Result := Copy(Result, 1, Len);\nend;\n\n{**\n  Create CachedResultSet with using TZCachedResultSet and return it.\n  @param SQL a sql query command\n  @param Statement a zeos statement object\n  @param NativeResultSet a native result set\n  @return cached ResultSet\n}\nfunction CreateIBResultSet(SQL: string; Statement: IZStatement; NativeResultSet: IZResultSet): IZResultSet;\nvar\n  CachedResolver: TZInterbase6CachedResolver;\n  CachedResultSet: TZCachedResultSet;\nbegin\n  if (Statement.GetResultSetConcurrency <> rcReadOnly)\n     or (Statement.GetResultSetType <> rtForwardOnly) then\n  begin\n    CachedResolver  := TZInterbase6CachedResolver.Create(Statement,  NativeResultSet.GetMetadata);\n    CachedResultSet := TZCachedResultSet.Create(NativeResultSet, SQL,\n      CachedResolver, Statement.GetConnection.GetConSettings);\n    CachedResultSet.SetConcurrency(Statement.GetResultSetConcurrency);\n    Result := CachedResultSet;\n  end\n  else\n    Result := NativeResultSet;\nend;\n\n{**\n  Generate database connection string by connection information\n  @param DPB - a database connection string\n  @param Dialect - a sql dialect number\n  @param Info - a list connection interbase parameters\n  @return a generated string length\n}\nfunction GenerateDPB(Info: TStrings; var FDPBLength, Dialect: Word): PAnsiChar;\nvar\n  I, Pos, PValue: Integer;\n  ParamNo: Word;\n  Buffer: String;\n  DPB, ParamName, ParamValue: AnsiString;\nbegin\n  FDPBLength := 1;\n  DPB := AnsiChar(isc_dpb_version1);\n\n  for I := 0 to Info.Count - 1 do\n  begin\n    Buffer := Info.Strings[I];\n    Pos := FirstDelimiter(' ='#9#10#13, Buffer);\n    ParamName := AnsiString(Copy(Buffer, 1, Pos - 1));\n    Delete(Buffer, 1, Pos);\n    ParamValue := AnsiString(Buffer);\n    ParamNo := GetInterbase6DatabaseParamNumber(ParamName);\n\n    case ParamNo of\n      0: Continue;\n      isc_dpb_set_db_SQL_dialect:\n        Dialect := StrToIntDef(String(ParamValue), 0);\n      isc_dpb_user_name, isc_dpb_password, isc_dpb_password_enc,\n      isc_dpb_sys_user_name, isc_dpb_license, isc_dpb_encrypt_key,\n      isc_dpb_lc_messages, isc_dpb_lc_ctype, isc_dpb_sql_role_name,\n\t  isc_dpb_connect_timeout:\n        begin\n          DPB := DPB + AnsiChar(ParamNo) + AnsiChar(Length(ParamValue)) + ParamValue;\n          Inc(FDPBLength, 2 + Length(ParamValue));\n        end;\n      isc_dpb_num_buffers, isc_dpb_dbkey_scope, isc_dpb_force_write,\n      isc_dpb_no_reserve, isc_dpb_damaged, isc_dpb_verify:\n        begin\n          DPB := DPB + AnsiChar(ParamNo) + #1 + AnsiChar(StrToInt(String(ParamValue)));\n          Inc(FDPBLength, 3);\n        end;\n      isc_dpb_sweep:\n        begin\n          DPB := DPB + AnsiChar(ParamNo) + #1 + AnsiChar(isc_dpb_records);\n          Inc(FDPBLength, 3);\n        end;\n      isc_dpb_sweep_interval:\n        begin\n          PValue := StrToInt(String(ParamValue));\n          DPB := DPB + AnsiChar(ParamNo) + #4 + PAnsiChar(@PValue)[0] +\n                 PAnsiChar(@PValue)[1] + PAnsiChar(@PValue)[2] + PAnsiChar(@PValue)[3];\n          Inc(FDPBLength, 6);\n        end;\n      isc_dpb_activate_shadow, isc_dpb_delete_shadow, isc_dpb_begin_log,\n      isc_dpb_quit_log:\n        begin\n          DPB := DPB + AnsiChar(ParamNo) + #1 + #0;\n          Inc(FDPBLength, 3);\n        end;\n    end;\n  end;\n\n  {$IFDEF UNICODE}\n  Result := AnsiStrAlloc(FDPBLength + 1);\n  {$ELSE}\n  Result := StrAlloc(FDPBLength + 1);\n  {$ENDIF}\n\n\n  {$IFDEF WITH_STRPCOPY_DEPRECATED}AnsiStrings.{$ENDIF}StrPCopy(Result, DPB);\nend;\n\n{**\n   Generate transaction structuer by connection information\n   @param Params - a transaction parameters list\n   @param Dialect - a database connection handle\n   @return a transaction ISC structure\n}\nfunction GenerateTPB(Params: TStrings; var Handle: TISC_DB_HANDLE): PISC_TEB;\nvar\n  I: Integer;\n  TPBLength,ParamNo: Word;\n  TempStr, ParamValue: AnsiString;\n  TPB: PAnsiChar;\n  IsolationLevel: Boolean;\nbegin\n  TPBLength := 0;\n  TempStr := '';\n  IsolationLevel := False;\n\n  { Prepare transaction parameters string }\n  for I := 0 to Params.Count - 1 do\n  begin\n    ParamValue := AnsiString(Params.Strings[I]);\n    ParamNo := GetInterbase6TransactionParamNumber(ParamValue);\n\n    case ParamNo of\n      0: Continue;\n      isc_tpb_lock_read, isc_tpb_lock_write:\n        begin\n          TempStr := TempStr + AnsiChar(ParamNo) + AnsiChar(Length(ParamValue)) + ParamValue;\n          Inc(TPBLength, Length(ParamValue) + 2);\n        end;\n      else\n        begin\n          TempStr := TempStr + AnsiChar(ParamNo);\n          Inc(TPBLength, 1);\n        end;\n    end;\n\n    { Check what was set use transaction isolation level }\n    if not IsolationLevel then\n      case ParamNo of\n        isc_tpb_concurrency, isc_tpb_consistency,\n        isc_tpb_read_committed:\n          IsolationLevel := True\n        else\n          IsolationLevel := False;\n      end;\n\n  end;\n\n   { Allocate transaction parameters PAnsiChar buffer\n    if temporally parameters string is empty the set null pointer for\n    default database transaction}\n  if (TPBLength > 0) and (IsolationLevel) then\n  begin\n    {$IFDEF UNICODE}\n    TPB := AnsiStrAlloc(TPBLength + 1);\n    {$ELSE}\n    TPB := StrAlloc(TPBLength + 1);\n    {$ENDIF}\n    TPB := {$IFDEF WITH_STRPCOPY_DEPRECATED}AnsiStrings.{$ENDIF}StrPCopy(TPB, TempStr);\n\n  end\n  else\n    TPB := nil;\n\n  { Allocate transaction structure }\n  Result := AllocMem(SizeOf(TISC_TEB));\n  with Result^ do\n  begin\n    db_handle := @Handle;\n    tpb_length := TPBLength;\n    tpb_address := TPB;\n  end;\nend;\n\n{**\n  Return interbase connection parameter number by it name\n  @param Value - a connection parameter name\n  @return - connection parameter number\n}\nfunction GetInterbase6DatabaseParamNumber(const Value: AnsiString): Word;\nvar\n I: Integer;\n ParamName: AnsiString;\nbegin\n  ParamName := {$IFDEF WITH_UNITANSISTRINGS}AnsiStrings.{$ENDIF}AnsiLowerCase(Value);\n  Result := 0;\n  if System.Pos(BPBPrefix, String(ParamName)) = 1 then\n    for I := 1 to MAX_DPB_PARAMS do\n    begin\n      if ParamName = DatabaseParams[I].Name then\n      begin\n        Result := DatabaseParams[I].Number;\n        Break;\n      end;\n    end;\nend;\n\n{**\n  Return interbase transaction parameter number by it name\n  @param Value - a transaction parameter name\n  @return - transaction parameter number\n}\nfunction GetInterbase6TransactionParamNumber(const Value: AnsiString): Word;\nvar\n I: Integer;\n ParamName: AnsiString;\nbegin\n  ParamName := {$IFDEF WITH_UNITANSISTRINGS}AnsiStrings.{$ENDIF}AnsiLowerCase(Value);\n  Result := 0;\n  if System.Pos(TPBPrefix, String(ParamName)) = 1 then\n    for I := 1 to MAX_TPB_PARAMS do\n    begin\n      if ParamName = TransactionParams[I].Name then\n      begin\n        Result := TransactionParams[I].Number;\n        Break;\n      end;\n    end;\nend;\n\n{**\n  Converts a Interbase6 native types into ZDBC SQL types.\n  @param the interbase type\n  @param the interbase subtype\n  @return a SQL undepended type.\n\n  <b>Note:</b> The interbase type and subtype get from RDB$TYPES table\n}\nfunction ConvertInterbase6ToSqlType(SqlType, SqlSubType: Integer;\n  const CtrlsCPType: TZControlsCodePage): TZSQLType;\nbegin\n  Result := ZDbcIntfs.stUnknown;\n\n  case SqlType of\n    blr_bool, blr_not_nullable: Result := stBoolean;\n    blr_varying2, blr_varying, blr_cstring, blr_cstring2, blr_domain_name,\n    blr_domain_name2, blr_column_name, blr_column_name2:\n      Result := stString;\n    blr_text, blr_text2:\n      case SqlSubType of\n        CS_BINARY: Result := stBytes;\n      else\n        Result := stString;\n      end;\n    blr_d_float: Result := stDouble;\n    blr_float: Result := stFloat;\n    blr_double: Result := stDouble;\n    blr_blob_id, blr_quad: Result := stLong;\n    blr_int64:\n      case SqlSubType of\n        RDB_NUMBERS_NONE: Result := stLong;\n        RDB_NUMBERS_NUMERIC: Result := stDouble;\n        RDB_NUMBERS_DECIMAL: Result := stBigDecimal;\n      end;\n    blr_long:\n      begin\n        case SqlSubType of\n          RDB_NUMBERS_NONE: Result := stInteger;\n          RDB_NUMBERS_NUMERIC: Result := stDouble;\n          RDB_NUMBERS_DECIMAL: Result := stBigDecimal;\n        end;\n      end;\n    blr_short:\n      begin\n        case SqlSubType of\n          RDB_NUMBERS_NONE: Result := stShort;\n          RDB_NUMBERS_NUMERIC: Result := stDouble;\n          RDB_NUMBERS_DECIMAL: Result := stDouble;\n        end;\n      end;\n    blr_sql_date: Result := stDate;\n    blr_sql_time: Result := stTime;\n    blr_timestamp: Result := stTimestamp;\n    blr_blob, blr_blob2:\n      begin\n        case SqlSubType of\n          { Blob Subtypes }\n          { types less than zero are reserved for customer use }\n          isc_blob_untyped: Result := stBinaryStream;\n\n          { internal subtypes }\n          isc_blob_text: Result := stAsciiStream;\n          isc_blob_blr: Result := stBinaryStream;\n          isc_blob_acl: Result := stAsciiStream;\n          isc_blob_ranges: Result := stBinaryStream;\n          isc_blob_summary: Result := stBinaryStream;\n          isc_blob_format: Result := stAsciiStream;\n          isc_blob_tra: Result := stAsciiStream;\n          isc_blob_extfile: Result := stAsciiStream;\n          isc_blob_debug_info: Result := stBinaryStream;\n        end;\n      end;\n    else\n      Result := ZDbcIntfs.stUnknown;\n  end;\n  if ( CtrlsCPType = cCP_UTF16) then\n    case result of\n      stString: Result := stUnicodeString;\n      stAsciiStream: Result := stUnicodeStream;\n    end;\nend;\n\n{**\n   Return Interbase SqlType by it number\n   @param Value the SqlType number\n}\nfunction GetNameSqlType(Value: Word): AnsiString;\nbegin\n  case Value of\n    SQL_VARYING: Result := 'SQL_VARYING';\n    SQL_TEXT: Result := 'SQL_TEXT';\n    SQL_DOUBLE: Result := 'SQL_DOUBLE';\n    SQL_FLOAT: Result := 'SQL_FLOAT';\n    SQL_LONG: Result := 'SQL_LONG';\n    SQL_SHORT: Result := 'SQL_SHORT';\n    SQL_TIMESTAMP: Result := 'SQL_TIMESTAMP';\n    SQL_BLOB: Result := 'SQL_BLOB';\n    SQL_D_FLOAT: Result := 'SQL_D_FLOAT';\n    SQL_ARRAY: Result := 'SQL_ARRAY';\n    SQL_QUAD: Result := 'SQL_QUAD';\n    SQL_TYPE_TIME: Result := 'SQL_TYPE_TIME';\n    SQL_TYPE_DATE: Result := 'SQL_TYPE_DATE';\n    SQL_INT64: Result := 'SQL_INT64';\n    SQL_BOOLEAN: Result := 'SQL_BOOLEAN';\n  else\n    Result := 'Unknown';\n  end\nend;\n\n{**\n  Checks for possible sql errors.\n  @param PlainDriver a Interbase Plain drver\n  @param StatusVector a status vector. It contain information about error\n  @param Sql a sql query commend\n\n  @Param Integer Return is the ErrorCode that happened - for disconnecting the database\n}\nfunction CheckInterbase6Error(PlainDriver: IZInterbasePlainDriver;\n  StatusVector: TARRAY_ISC_STATUS; LoggingCategory: TZLoggingCategory = lcOther;\n  SQL: string = '') : Integer;\nvar\n  Msg: array[0..1024] of AnsiChar;\n  PStatusVector: PISC_STATUS;\n  ErrorMessage, ErrorSqlMessage: string;\n  ErrorCode: LongInt;\nbegin\n  Result := 0;\n  if (StatusVector[0] = 1) and (StatusVector[1] > 0) then\n  begin\n    ErrorMessage := '';\n    PStatusVector := @StatusVector;\n    while PlainDriver.isc_interprete(Msg, @PStatusVector) > 0 do\n      ErrorMessage := ErrorMessage + ' ' + String(Msg);\n\n    ErrorCode := PlainDriver.isc_sqlcode(@StatusVector);\n    PlainDriver.isc_sql_interprete(ErrorCode, Msg, 1024);\n    ErrorSqlMessage := String(Msg);\n\n{$IFDEF INTERBASE_EXTENDED_MESSAGES}\n    if SQL <> '' then\n      SQL := Format(' The SQL: %s; ', [SQL]);\n{$ENDIF}\n\n    if ErrorMessage <> '' then\n    begin\n      DriverManager.LogError(LoggingCategory, PlainDriver.GetProtocol,\n        ErrorMessage, ErrorCode, ErrorSqlMessage + SQL);\n\n      //AVZ Ignore error codes for disconnected database -901, -902\n      if ((ErrorCode <> -901) and (ErrorCode <> -902)) then\n      begin\n{$IFDEF INTERBASE_EXTENDED_MESSAGES}\n        raise EZSQLException.CreateWithCode(ErrorCode,\n          Format('SQL Error: %s. Error Code: %d. %s',\n          [ErrorMessage, ErrorCode, ErrorSqlMessage]) + SQL);\n{$ELSE}\n        raise EZSQLException.CreateWithCode(ErrorCode,\n          Format('SQL Error: %s. Error Code: %d. %s',\n          [ErrorMessage, ErrorCode, ErrorSqlMessage]));\n{$ENDIF}\n      end\n        else\n      begin      //AVZ -- Added exception back in to help error trapping\n        raise EZSQLException.CreateWithCode(ErrorCode,\n          Format('SQL Error: %s. Error Code: %d. %s',\n          [ErrorMessage, ErrorCode, ErrorSqlMessage]));\n\n        Result := DISCONNECT_ERROR;\n      end;\n    end;\n  end;\nend;\n\n{**\n   Prepare statement and create statement handle.\n   @param PlainDriver a interbase plain driver\n   @param Handle a interbase connection handle\n   @param TrHandle a transaction handle\n   @param Dialect a interbase sql dialect number\n   @param Sql a sql query\n   @param StmtHandle a statement handle\n   @param SqlData a interbase sql result data\n   @return sql statement type\n}\nfunction PrepareStatement(PlainDriver: IZInterbasePlainDriver;\n  Handle: PISC_DB_HANDLE; TrHandle: PISC_TR_HANDLE; Dialect: Word;\n  SQL: RawByteString; LogSQL: String; var StmtHandle: TISC_STMT_HANDLE):\n  TZIbSqlStatementType;\nvar\n  StatusVector: TARRAY_ISC_STATUS;\n  iError : Integer; //Error for disconnect\nbegin\n  { Allocate an sql statement }\n  if StmtHandle = 0 then\n  begin\n    PlainDriver.isc_dsql_allocate_statement(@StatusVector, Handle, @StmtHandle);\n    CheckInterbase6Error(PlainDriver, StatusVector, lcOther, LogSQL);\n  end;\n  { Prepare an sql statement }\n  PlainDriver.isc_dsql_prepare(@StatusVector, TrHandle, @StmtHandle,\n    0, PAnsiChar(SQL), Dialect, nil);\n\n  iError := CheckInterbase6Error(PlainDriver, StatusVector, lcPrepStmt, LogSQL); //Check for disconnect AVZ\n\n  { Set Statement Type }\n  if (iError <> DISCONNECT_ERROR) then //AVZ\n    Result := GetStatementType(PlainDriver, StmtHandle)\n  else\n    Result := stDisconnect;\n\n  if Result in [stUnknown, stGetSegment, stPutSegment, stStartTrans] then\n  begin\n    FreeStatement(PlainDriver, StmtHandle, DSQL_CLOSE);  //AVZ\n    raise EZSQLException.Create(SStatementIsNotAllowed);\n  end;\nend;\n\n{**\n   Describe SQLDA and allocate memory for result values.\n   @param PlainDriver a interbase plain driver\n   @param Handle a interbase connection handle\n   @param Dialect a interbase sql dialect number\n   @param Sql a sql query\n   @param StmtHandle a statement handle\n   @param SqlData a interbase sql result data\n}\nprocedure PrepareResultSqlData(PlainDriver: IZInterbasePlainDriver;\n    Handle: PISC_DB_HANDLE; Dialect: Word; LogSQL: string;\n    var StmtHandle: TISC_STMT_HANDLE; SqlData: IZResultSQLDA);\nvar\n  StatusVector: TARRAY_ISC_STATUS;\nbegin\n  { Initialise ouput param and fields }\n  PlainDriver.isc_dsql_describe(@StatusVector, @StmtHandle, Dialect,\n    SqlData.GetData);\n  CheckInterbase6Error(PlainDriver, StatusVector, lcExecute, LogSQL);\n\n  if SqlData.GetData^.sqld > SqlData.GetData^.sqln then\n  begin\n    SqlData.AllocateSQLDA;\n    PlainDriver.isc_dsql_describe(@StatusVector, @StmtHandle,\n      Dialect, SqlData.GetData);\n    CheckInterbase6Error(PlainDriver, StatusVector, lcExecute, LogSql);\n  end;\n  SqlData.InitFields(False);\nend;\n\n{**\n   Return interbase statement type by statement handle\n   @param PlainDriver a interbase plain driver\n   @param StmtHandle a statement handle\n   @return interbase statement type\n}\nfunction GetStatementType(PlainDriver: IZInterbasePlainDriver;\n  StmtHandle: TISC_STMT_HANDLE): TZIbSqlStatementType;\nvar\n  TypeItem: AnsiChar;\n  StatusVector: TARRAY_ISC_STATUS;\n  StatementLength: integer;\n  StatementBuffer: array[0..7] of AnsiChar;\nbegin\n  Result := stUnknown;\n  TypeItem := AnsiChar(isc_info_sql_stmt_type);\n\n  { Get information about a prepared DSQL statement. }\n  PlainDriver.isc_dsql_sql_info(@StatusVector, @StmtHandle, 1,\n    @TypeItem, SizeOf(StatementBuffer), StatementBuffer);\n  CheckInterbase6Error(PlainDriver, StatusVector);\n\n  if StatementBuffer[0] = AnsiChar(isc_info_sql_stmt_type) then\n  begin\n    StatementLength := PlainDriver.isc_vax_integer(\n      @StatementBuffer[1], 2);\n    Result := TZIbSqlStatementType(PlainDriver.isc_vax_integer(\n      @StatementBuffer[3], StatementLength));\n  end;\nend;\n\n{**\n   Free interbse allocated statement and SQLDA for input and utput parameters\n   @param  the interbase plain driver\n   @param  the interbse statement handle\n}\nprocedure FreeStatement(PlainDriver: IZInterbasePlainDriver; StatementHandle: TISC_STMT_HANDLE; Options: Word);\nvar\n  StatusVector: TARRAY_ISC_STATUS;\nbegin\n  if StatementHandle <> 0  then\n    PlainDriver.isc_dsql_free_statement(@StatusVector, @StatementHandle, Options);\n  //CheckInterbase6Error(PlainDriver, StatusVector); //raises an unwanted exception if Connection was reopened  See: http://sourceforge.net/p/zeoslib/tickets/40/\nend;\n\n{**\n   Get affected rows.\n   <i>Note:<i> it function may call after statement execution\n   @param PlainDriver a interbase plain driver\n   @param StmtHandle a statement handle\n   @param StatementType a statement type\n   @return affected rows\n}\nfunction GetAffectedRows(PlainDriver: IZInterbasePlainDriver;\n  StmtHandle: TISC_STMT_HANDLE; StatementType: TZIbSqlStatementType): Integer;\nvar\n  ReqInfo: AnsiChar;\n  OutBuffer: array[0..255] of AnsiChar;\n  StatusVector: TARRAY_ISC_STATUS;\nbegin\n  Result := -1;\n  ReqInfo := AnsiChar(isc_info_sql_records);\n\n  if PlainDriver.isc_dsql_sql_info(@StatusVector, @StmtHandle, 1,\n    @ReqInfo, SizeOf(OutBuffer), OutBuffer) > 0 then\n    Exit;\n  CheckInterbase6Error(PlainDriver, StatusVector);\n  if OutBuffer[0] = AnsiChar(isc_info_sql_records) then\n  begin\n    case StatementType of\n      stUpdate: Result := PlainDriver.isc_vax_integer(@OutBuffer[6], 4);\n      stDelete: Result := PlainDriver.isc_vax_integer(@OutBuffer[13], 4);\n      stSelect: Result := PlainDriver.isc_vax_integer(@OutBuffer[20], 4);\n      stInsert: Result := PlainDriver.isc_vax_integer(@OutBuffer[27], 4);\n    else\n       Result := -1;\n    end;\n  end;\nend;\n\n{**\n   Prepare sql statement parameters and fill parameters by values\n   @param PlainDriver a interbase plain driver\n   @param Dialect a interbase sql dialect number\n   @param StmtHandle a statement handle\n   @param SqlData a interbase sql result data\n}\nprocedure PrepareParameters(PlainDriver: IZInterbasePlainDriver; LogSQL: string;\n   Dialect: Word; var StmtHandle: TISC_STMT_HANDLE; ParamSqlData: IZParamsSQLDA);\nvar\n  StatusVector: TARRAY_ISC_STATUS;\nbegin\n  {check dynamic sql}\n  PlainDriver.isc_dsql_describe_bind(@StatusVector, @StmtHandle, Dialect,\n    ParamSqlData.GetData);\n  CheckInterbase6Error(PlainDriver, StatusVector, lcExecute, LogSQL);\n\n  { Resize XSQLDA structure if needed }\n  if ParamSqlData.GetData^.sqld > ParamSqlData.GetData^.sqln then\n  begin\n    ParamSqlData.AllocateSQLDA;\n    PlainDriver.isc_dsql_describe_bind(@StatusVector, @StmtHandle, Dialect,\n      ParamSqlData.GetData);\n    CheckInterbase6Error(PlainDriver, StatusVector, lcExecute, LogSQL);\n  end;\n\n  ParamSqlData.InitFields(True);\nend;\n\nprocedure BindSQLDAInParameters(PlainDriver: IZInterbasePlainDriver;\n  InParamValues: TZVariantDynArray; InParamTypes: TZSQLTypeArray;\n  InParamCount: Integer; ParamSqlData: IZParamsSQLDA; ConSettings: PZConSettings);\nvar\n  I: Integer;\n  TempBlob: IZBlob;\n  TempStream: TStream;\nbegin\n  if InParamCount <> ParamSqlData.GetFieldCount then\n    raise EZSQLException.Create(SInvalidInputParameterCount);\n\n  {$R-}\n  for I := 0 to ParamSqlData.GetFieldCount - 1 do\n  begin\n    ParamSqlData.UpdateNull(I, DefVarManager.IsNull(InParamValues[I]));\n    if DefVarManager.IsNull(InParamValues[I])then\n      Continue\n    else\n    case InParamTypes[I] of\n      stBoolean:\n        ParamSqlData.UpdateBoolean(I,\n          SoftVarManager.GetAsBoolean(InParamValues[I]));\n      stByte:\n        ParamSqlData.UpdateByte(I,\n          SoftVarManager.GetAsInteger(InParamValues[I]));\n      stShort:\n        ParamSqlData.UpdateShort(I,\n          SoftVarManager.GetAsInteger(InParamValues[I]));\n      stInteger:\n        ParamSqlData.UpdateInt(I,\n          SoftVarManager.GetAsInteger(InParamValues[I]));\n      stLong:\n        ParamSqlData.UpdateLong(I,\n          SoftVarManager.GetAsInteger(InParamValues[I]));\n      stFloat:\n        ParamSqlData.UpdateFloat(I,\n          SoftVarManager.GetAsFloat(InParamValues[I]));\n      stDouble:\n        ParamSqlData.UpdateDouble(I,\n          SoftVarManager.GetAsFloat(InParamValues[I]));\n      stBigDecimal:\n        ParamSqlData.UpdateBigDecimal(I,\n          SoftVarManager.GetAsFloat(InParamValues[I]));\n      stString:\n         if ( ConSettings.ClientCodePage.ID = CS_NONE ) and not\n            (ParamSqlData.GetIbSqlSubType(I) = CS_NONE) then //CharSet 'NONE' writes data 'as is'!\n          ParamSqlData.UpdateString(I,\n            PlainDriver.ZPlainString(SoftVarManager.GetAsString(InParamValues[I]),\n            ConSettings, PlainDriver.ValidateCharEncoding(ParamSqlData.GetIbSqlSubType(I)).CP))\n        else\n          ParamSqlData.UpdateString(I,\n            PlainDriver.ZPlainString(SoftVarManager.GetAsString(InParamValues[I]), ConSettings));\n      stUnicodeString:\n         if ( ConSettings.ClientCodePage.ID = CS_NONE ) and not\n            (ParamSqlData.GetIbSqlSubType(I) = CS_NONE) then //CharSet 'NONE' writes data 'as is'!\n          ParamSqlData.UpdateString(I,\n            PlainDriver.ZPlainString(SoftVarManager.GetAsUnicodeString(InParamValues[I]),\n            ConSettings, PlainDriver.ValidateCharEncoding(ParamSqlData.GetIbSqlSubType(I)).CP))\n        else\n          ParamSqlData.UpdateString(I,\n            PlainDriver.ZPlainString(SoftVarManager.GetAsUnicodeString(InParamValues[I]), ConSettings));\n      stBytes:\n        ParamSqlData.UpdateBytes(I, SoftVarManager.GetAsBytes(InParamValues[I]));\n      stDate:\n        ParamSqlData.UpdateDate(I,\n          SoftVarManager.GetAsDateTime(InParamValues[I]));\n      stTime:\n        ParamSqlData.UpdateTime(I,\n          SoftVarManager.GetAsDateTime(InParamValues[I]));\n      stTimestamp:\n        ParamSqlData.UpdateTimestamp(I,\n          SoftVarManager.GetAsDateTime(InParamValues[I]));\n      stAsciiStream,\n      stUnicodeStream,\n      stBinaryStream:\n        begin\n          TempBlob := DefVarManager.GetAsInterface(InParamValues[I]) as IZBlob;\n          if not TempBlob.IsEmpty then\n          begin\n            if (ParamSqlData.GetFieldSqlType(i) in [stUnicodeStream, stAsciiStream] ) then\n              TempStream := TStringStream.Create(GetValidatedAnsiStringFromBuffer(TempBlob.GetBuffer, TempBlob.Length,\n                TempBlob.WasDecoded, ConSettings))\n            else\n              TempStream := TempBlob.GetStream;\n            if Assigned(TempStream) then\n            begin\n              ParamSqlData.WriteBlob(I, TempStream);\n              TempStream.Free;\n            end;\n          end;\n        end\n      else\n        raise EZIBConvertError.Create(SUnsupportedParameterType);\n    end;\n  end;\n {$IFOPT D+}\n{$ENDIF}\nend;\n\n{**\n   Read blob information by it handle such as blob segment size, segments count,\n   blob size and type.\n   @param PlainDriver\n   @param BlobInfo the blob information structure\n}\nprocedure GetBlobInfo(PlainDriver: IZInterbasePlainDriver;\n  BlobHandle: TISC_BLOB_HANDLE; var BlobInfo: TIbBlobInfo);\nvar\n  Items: array[0..3] of AnsiChar;\n  Results: array[0..99] of AnsiChar;\n  I, ItemLength: Integer;\n  Item: Integer;\n  StatusVector: TARRAY_ISC_STATUS;\nbegin\n  I := 0;\n  Items[0] := AnsiChar(isc_info_blob_num_segments);\n  Items[1] := AnsiChar(isc_info_blob_max_segment);\n  Items[2] := AnsiChar(isc_info_blob_total_length);\n  Items[3] := AnsiChar(isc_info_blob_type);\n\n  if PlainDriver.isc_blob_info(@StatusVector, @BlobHandle, 4, @items[0],\n    SizeOf(Results), @Results[0]) > 0 then\n  CheckInterbase6Error(PlainDriver, StatusVector);\n\n  while (I < SizeOf(Results)) and (Results[I] <> AnsiChar(isc_info_end)) do\n  begin\n    Item := Integer(Results[I]);\n    Inc(I);\n    ItemLength := PlainDriver.isc_vax_integer(@results[I], 2);\n    Inc(I, 2);\n    case Item of\n      isc_info_blob_num_segments:\n        BlobInfo.NumSegments := PlainDriver.isc_vax_integer(@Results[I], ItemLength);\n      isc_info_blob_max_segment:\n        BlobInfo.MaxSegmentSize := PlainDriver.isc_vax_integer(@Results[I], ItemLength);\n      isc_info_blob_total_length:\n        BlobInfo.TotalSize := PlainDriver.isc_vax_integer(@Results[I], ItemLength);\n      isc_info_blob_type:\n        BlobInfo.BlobType := PlainDriver.isc_vax_integer(@Results[I], ItemLength);\n    end;\n    Inc(i, ItemLength);\n  end;\nend;\n\n{**\n   Read blob field data to stream by it ISC_QUAD value\n   Note: DefaultBlobSegmentSize constant used for limit segment size reading\n   @param Handle the database connection handle\n   @param TransactionHandle the transaction handle\n   @param BlobId the ISC_QUAD structure\n   @param Size the result buffer size\n   @param Buffer the pointer to result buffer\n\n   Note: Buffer must be nill. Function self allocate memory for data\n    and return it size\n}\nprocedure ReadBlobBufer(PlainDriver: IZInterbasePlainDriver;\n  Handle: PISC_DB_HANDLE; TransactionHandle: PISC_TR_HANDLE;\n  BlobId: TISC_QUAD; var Size: Integer; var Buffer: Pointer);\nvar\n  TempBuffer: PAnsiChar;\n  BlobInfo: TIbBlobInfo;\n  BlobSize, CurPos: LongInt;\n  BytesRead, SegmentLenght: UShort;\n  BlobHandle: TISC_BLOB_HANDLE;\n  StatusVector: TARRAY_ISC_STATUS;\nbegin\n  BlobHandle := 0;\n  CurPos := 0;\n//  SegmentLenght := UShort(DefaultBlobSegmentSize);\n\n  { open blob }\n  PlainDriver.isc_open_blob2(@StatusVector, Handle,\n         TransactionHandle, @BlobHandle, @BlobId, 0 , nil);\n  CheckInterbase6Error(PlainDriver, StatusVector);\n\n  { get blob info }\n  GetBlobInfo(PlainDriver, BlobHandle, BlobInfo);\n  BlobSize := BlobInfo.TotalSize;\n  Size := BlobSize;\n\n  SegmentLenght := BlobInfo.MaxSegmentSize;\n\n  { Allocates a blob buffer }\n  Buffer := AllocMem(BlobSize);\n  TempBuffer := Buffer;\n\n  { Copies data to blob buffer }\n  while CurPos < BlobSize do\n  begin\n    if (CurPos + SegmentLenght > BlobSize) then\n      SegmentLenght := BlobSize - CurPos;\n    if not(PlainDriver.isc_get_segment(@StatusVector, @BlobHandle,\n           @BytesRead, SegmentLenght, TempBuffer) = 0) or\n          (StatusVector[1] <> isc_segment) then\n      CheckInterbase6Error(PlainDriver, StatusVector);\n    Inc(CurPos, BytesRead);\n    Inc(TempBuffer, BytesRead);\n    BytesRead := 0;\n  end;\n\n  { close blob handle }\n  PlainDriver.isc_close_blob(@StatusVector, @BlobHandle);\n  CheckInterbase6Error(PlainDriver, StatusVector);\nend;\n\nfunction GetIBScaleDivisor(Scale: SmallInt): Int64;\nvar\n  i: Integer;\nbegin\n  Result := 1;\n  if Scale > 0 then\n    for i := 1 to Scale do\n      Result := Result * 10\n  else\n    if Scale < 0 then\n      for i := -1 downto Scale do\n        Result := Result * 10;\nend;\n{**\n   Return interbase server version string\n   @param PlainDriver a interbase plain driver\n   @param Handle the database connection handle\n   @return interbase version string\n}\nfunction GetVersion(PlainDriver: IZInterbasePlainDriver;\n  Handle: PISC_DB_HANDLE): AnsiString;\nvar\n  DatabaseInfoCommand: AnsiChar;\n  StatusVector: TARRAY_ISC_STATUS;\n  Buffer: array[0..IBBigLocalBufferLength - 1] of AnsiChar;\nbegin\n  DatabaseInfoCommand := AnsiChar(isc_info_version);\n  PlainDriver.isc_database_info(@StatusVector, Handle, 1, @DatabaseInfoCommand,\n    IBBigLocalBufferLength, Buffer);\n  CheckInterbase6Error(PlainDriver, StatusVector);\n  Buffer[5 + Integer(Buffer[4])] := #0;\n  result := AnsiString(PAnsiChar(@Buffer[5]));\nend;\n\n{**\n   Return interbase database implementation\n   @param PlainDriver a interbase plain driver\n   @param Handle the database connection handle\n   @return interbase database implementation\n}\nfunction GetDBImplementationNo(PlainDriver: IZInterbasePlainDriver;\n    Handle: PISC_DB_HANDLE): LongInt;\nvar\n  DatabaseInfoCommand: AnsiChar;\n  StatusVector: TARRAY_ISC_STATUS;\n  Buffer: array[0..IBBigLocalBufferLength - 1] of AnsiChar;\nbegin\n  DatabaseInfoCommand := AnsiChar(isc_info_implementation);\n  PlainDriver.isc_database_info(@StatusVector, Handle, 1, @DatabaseInfoCommand,\n    IBLocalBufferLength, Buffer);\n  CheckInterbase6Error(PlainDriver, StatusVector);\n  result := PlainDriver.isc_vax_integer(@Buffer[3], 1);\nend;\n\n{**\n   Return interbase database implementation class\n   @param PlainDriver a interbase plain driver\n   @param Handle the database connection handle\n   @return interbase database implementation class\n}\nfunction GetDBImplementationClass(PlainDriver: IZInterbasePlainDriver;\n    Handle: PISC_DB_HANDLE): LongInt;\nvar\n  DatabaseInfoCommand: AnsiChar;\n  StatusVector: TARRAY_ISC_STATUS;\n  Buffer: array[0..IBBigLocalBufferLength - 1] of AnsiChar;\nbegin\n  DatabaseInfoCommand := AnsiChar(isc_info_implementation);\n  PlainDriver.isc_database_info(@StatusVector, Handle, 1, @DatabaseInfoCommand,\n    IBLocalBufferLength, Buffer);\n  CheckInterbase6Error(PlainDriver, StatusVector);\n  result := PlainDriver.isc_vax_integer(@Buffer[4], 1);\nend;\n\n{**\n   Return interbase database info\n   @param PlainDriver a interbase plain driver\n   @param Handle the database connection handle\n   @param DatabaseInfoCommand a database information command\n   @return interbase database info\n}\nfunction GetLongDbInfo(PlainDriver: IZInterbasePlainDriver;\n  Handle: PISC_DB_HANDLE; DatabaseInfoCommand: Integer): LongInt;\nvar\n  Length: Integer;\n  DatabaseInfoCommand1: AnsiChar;\n  StatusVector: TARRAY_ISC_STATUS;\n  Buffer: array[0..IBBigLocalBufferLength - 1] of AnsiChar;\nbegin\n  DatabaseInfoCommand1 := AnsiChar(DatabaseInfoCommand);\n  PlainDriver.isc_database_info(@StatusVector, Handle, 1, @DatabaseInfoCommand1,\n    IBLocalBufferLength, Buffer);\n  CheckInterbase6Error(PlainDriver, StatusVector);\n  Length := PlainDriver.isc_vax_integer(@Buffer[1], 2);\n  Result := PlainDriver.isc_vax_integer(@Buffer[4], Length);\nend;\n\n{**\n   Return interbase database info string\n   @param PlainDriver a interbase plain driver\n   @param Handle a database connection handle\n   @param DatabaseInfoCommand a database information command\n   @return interbase database info string\n}\nfunction GetStringDbInfo(PlainDriver: IZInterbasePlainDriver;\n  Handle: PISC_DB_HANDLE; DatabaseInfoCommand: Integer): AnsiString;\nvar\n  DatabaseInfoCommand1: AnsiChar;\n  StatusVector: TARRAY_ISC_STATUS;\n  Buffer: array[0..IBBigLocalBufferLength - 1] of AnsiChar;\nbegin\n   DatabaseInfoCommand1 := AnsiChar(DatabaseInfoCommand);\n   PlainDriver.isc_database_info(@StatusVector, Handle, 1, @DatabaseInfoCommand1,\n     IBLocalBufferLength, Buffer);\n   CheckInterbase6Error(PlainDriver, StatusVector);\n   Buffer[4 + Integer(Buffer[3])] := #0;\n   Result := AnsiString(PAnsiChar(@Buffer[4]));\nend;\n\n{**\n   Return interbase database dialect\n   @param PlainDriver a interbase plain driver\n   @param Handle the database connection handle\n   @return interbase database dialect\n}\nfunction GetDBSQLDialect(PlainDriver: IZInterbasePlainDriver;\n    Handle: PISC_DB_HANDLE): Integer;\nvar\n  Length: Integer;\n  DatabaseInfoCommand1: AnsiChar;\n  StatusVector: TARRAY_ISC_STATUS;\n  Buffer: array[0..IBBigLocalBufferLength - 1] of AnsiChar;\nbegin\n   DatabaseInfoCommand1 := AnsiChar(isc_info_db_SQL_Dialect);\n   PlainDriver.isc_database_info(@StatusVector, Handle, 1, @DatabaseInfoCommand1,\n     IBLocalBufferLength, Buffer);\n   CheckInterbase6Error(PlainDriver, StatusVector);\n   if (Buffer[0] <> AnsiChar(isc_info_db_SQL_dialect)) then\n     Result := 1\n   else\n   begin\n     Length := PlainDriver.isc_vax_integer(@Buffer[1], 2);\n     Result := PlainDriver.isc_vax_integer(@Buffer[3], Length);\n   end;\nend;\n\n{ TSQLDA }\nconstructor TZSQLDA.Create(PlainDriver: IZInterbasePlainDriver;\n  Handle: PISC_DB_HANDLE; TransactionHandle: PISC_TR_HANDLE;\n  ConSettings: PZConSettings);\nbegin\n  Self.ConSettings := ConSettings;\n  FPlainDriver := PlainDriver;\n  FHandle := Handle;\n  FTransactionHandle := TransactionHandle;\n\n  GetMem(FXSQLDA, XSQLDA_LENGTH(0));\n  FillChar(FXSQLDA^, XSQLDA_LENGTH(0), 0);\n  FXSQLDA.sqln := 0;\n  FXSQLDA.sqld := 0;\n\n  FXSQLDA.version := SQLDA_VERSION1;\nend;\n{**\n   Allocate memory for SQLVar in SQLDA structure for every\n   fields by it length.\n}\nprocedure TZSQLDA.InitFields(Parameters: boolean);\nvar\n  I: Integer;\n  SqlVar: PXSQLVAR;\nbegin\n  {$R-}\n  for I := 0 to FXSQLDA.sqld - 1 do\n  begin\n    SqlVar := @FXSQLDA.SqlVar[I];\n    case SqlVar.sqltype and (not 1) of\n      SQL_BOOLEAN, SQL_TEXT, SQL_TYPE_DATE, SQL_TYPE_TIME, SQL_DATE,\n      SQL_BLOB, SQL_ARRAY, SQL_QUAD, SQL_SHORT,\n      SQL_LONG, SQL_INT64, SQL_DOUBLE, SQL_FLOAT, SQL_D_FLOAT:\n        begin\n          if SqlVar.sqllen = 0 then\n            IbReAlloc(SqlVar.sqldata, 0, 1)\n          else\n            IbReAlloc(SqlVar.sqldata, 0, SqlVar.sqllen)\n        end;\n      SQL_VARYING:\n          IbReAlloc(SqlVar.sqldata, 0, SqlVar.sqllen + 2)\n    end;\n\n    if Parameters = True then\n    begin\n      //This code used when allocated sqlind parameter for Param SQLDA\n      SqlVar.sqltype := SqlVar.sqltype or 1;\n      IbReAlloc(SqlVar.sqlind, 0, SizeOf(Short))\n    end\n    else\n    begin\n      //This code used when allocated sqlind parameter for Result SQLDA\n      if (SqlVar.sqltype and 1) <> 0 then\n        ReallocMem(SqlVar.sqlind, SizeOf(Short))\n      else\n        SqlVar.sqlind := nil;\n    end;\n  end;\n  {$IFOPT D+}\n{$R+}\n{$ENDIF}\nend;\n\n{**\n   Clear allocated data for SQLDA paramters\n}\nprocedure TZSQLDA.FreeParamtersValues;\nvar\n  I: Integer;\n  SqlVar: PXSQLVAR;\nbegin\n  {$R-}\n  for I := 0 to FXSQLDA.sqln - 1 do\n  begin\n    SqlVar := @FXSQLDA.SqlVar[I];\n    FreeMem(SqlVar.sqldata);\n    FreeMem(SqlVar.sqlind);\n    SqlVar.sqldata := nil;\n    SqlVar.sqlind := nil;\n  end;\n  {$IFOPT D+}\n{$R+}\n{$ENDIF}\nend;\n\n{**\n   Chech reange count fields. If index out of range raised exception.\n   @param Index the index field\n}\nprocedure TZSQLDA.CheckRange(const Index: Word);\nbegin\n  Assert(Index < Word(FXSQLDA.sqln), 'Out of Range.');\nend;\n\n{**\n   Return alias name for field\n   @param Index the index fields\n   @return the alias name\n}\nfunction TZSQLDA.GetFieldAliasName(const Index: Word): String;\nbegin\n  CheckRange(Index);\n  {$R-}\n  SetString(Temp, FXSQLDA.sqlvar[Index].aliasname, FXSQLDA.sqlvar[Index].aliasname_length);\n  Result := ZDbcString(Temp);\n  {$IFOPT D+}\n{$R+}\n{$ENDIF}\nend;\n\n{**\n   Return pointer to SQLDA structure\n}\nfunction TZSQLDA.GetData: PXSQLDA;\nbegin\n  result := FXSQLDA;\nend;\n\n{**\n   Get fields count not allocated.\n   @return fields count\n}\nfunction TZSQLDA.GetFieldCount: Integer;\nbegin\n  Result := FXSQLDA.sqld;\nend;\n\n{**\n   Return field index by it name\n   @param Index the index fields\n   @return the index field\n}\nfunction TZSQLDA.GetFieldIndex(const Name: AnsiString): Word;\nbegin\n  {$R-}\n  for Result := 0 to GetFieldCount - 1 do\n    if FXSQLDA.sqlvar[Result].aliasname_length = Length(name) then\n      if {$IFDEF WITH_STRLICOPY_DEPRECATED}AnsiStrings.{$ENDIF}StrLIComp(@FXSQLDA.sqlvar[Result].aliasname, PAnsiChar(Name), FXSQLDA.sqlvar[Result].aliasname_length) = 0 then\n        Exit;\n  raise Exception.Create(Format(SFieldNotFound1, [name]));\n  {$IFOPT D+}\n{$R+}\n{$ENDIF}\nend;\n\n{**\n   Return field length\n   @param Index the index fields\n   @return the field lenth\n}\nfunction TZSQLDA.GetFieldLength(const Index: Word): SmallInt;\nbegin\n  {$R-}\n  case GetIbSqlType(Index) of\n    SQL_TEXT: Result := GetIbSqlLen(Index);\n    SQL_VARYING: Result := GetIbSqlLen(Index);\n    //SQL_VARYING: Result := FPlainDriver.isc_vax_integer(GetData.sqlvar[Index].sqldata, 2);  //AVZ\n    else\n      Result := GetIbSqlLen(Index);\n  end;\n  {$IFOPT D+}\n{$R+}\n{$ENDIF}\nend;\n\n{**\n   Return field scale\n   @param Index the index fields\n   @return the field scale\n}\nfunction TZSQLDA.GetFieldScale(const Index: Word): integer;\nbegin\n  CheckRange(Index);\n  {$R-}\n  Result := Abs(FXSQLDA.sqlvar[Index].sqlscale);\n  {$IFOPT D+}\n{$R+}\n{$ENDIF}\nend;\n\n{**\n   Convert Interbase sql type to SQLType\n   @param Index the index fields\n   @return the SQLType\n}\nfunction TZSQLDA.GetFieldSqlType(const Index: Word): TZSQLType;\nvar\n  SqlScale: Integer;\n  SqlSubType: Integer;\nbegin\n  SqlScale := GetFieldScale(Index);\n  SqlSubType := GetIbSqlSubType(Index);\n\n  case GetIbSqlType(Index) of\n    SQL_VARYING, SQL_TEXT:\n      case SqlSubType of\n        1: {Octets} Result := stBytes;\n        else\n          Result := stString;\n      end;\n    SQL_LONG:\n      begin\n        if SqlScale = 0 then\n          Result := stInteger\n        else\n          Result := stDouble;\n      end;\n    SQL_SHORT:\n      begin\n        if SqlScale = 0 then\n          Result := stShort\n        else\n          Result := stFloat; //Numeric with low precision\n       end;\n    SQL_FLOAT: Result := stFloat;\n    SQL_DOUBLE: Result := stDouble;\n    SQL_DATE: Result := stTimestamp;\n    SQL_TYPE_TIME: Result := stTime;\n    SQL_TYPE_DATE: Result := stDate;\n    SQL_INT64:\n      begin\n        if SqlScale = 0 then\n          Result := stLong\n        else if Abs(SqlScale) <= 4 then\n          Result := stDouble\n        else\n          Result := stBigDecimal;\n      end;\n    SQL_QUAD, SQL_ARRAY, SQL_BLOB:\n      begin\n        if SqlSubType = isc_blob_text then\n          Result := stAsciiStream\n        else\n          Result := stBinaryStream;\n      end;\n    //SQL_ARRAY: Result := stBytes;\n  else\n      Result := stString;\n  end;\n  if ( ConSettings.CPType = cCP_UTF16 ) then\n    case result of\n      stString: Result := stUnicodeString;\n      stAsciiStream: Result := stUnicodeStream;\n    end;\nend;\n\n{**\n   Return own name for field\n   @param Index the index fields\n   @return the own name\n}\nfunction TZSQLDA.GetFieldOwnerName(const Index: Word): String;\nbegin\n  CheckRange(Index);\n  {$R-}\n  {$IFDEF WITH_RAWBYTESTRING}\n  SetLength(Temp, FXSQLDA.sqlvar[Index].OwnName_length);\n  System.Move(FXSQLDA.sqlvar[Index].OwnName, PAnsiChar(Temp)^, FXSQLDA.sqlvar[Index].OwnName_length);\n  {$ELSE}\n  SetString(Temp, FXSQLDA.sqlvar[Index].OwnName, FXSQLDA.sqlvar[Index].OwnName_length);\n  {$ENDIF}\n  Result := ZDbcString(Temp);\n  {$IFOPT D+}\n{$R+}\n{$ENDIF}\nend;\n\n{**\n   Return real name for field\n   @param Index the index fields\n   @return the real name\n}\nfunction TZSQLDA.GetFieldRelationName(const Index: Word): String;\nbegin\n  CheckRange(Index);\n  {$R-}\n    {$IFDEF WITH_RAWBYTESTRING}\n    SetLength(Temp, FXSQLDA.sqlvar[Index].RelName_length);\n    System.Move(FXSQLDA.sqlvar[Index].RelName, PAnsiChar(Temp)^, FXSQLDA.sqlvar[Index].RelName_length);\n    {$ELSE}\n    SetString(Temp, FXSQLDA.sqlvar[Index].RelName, FXSQLDA.sqlvar[Index].RelName_length);\n    {$ENDIF}\n    Result := ZDbcString(Temp);\n  {$IFOPT D+}\n{$R+}\n{$ENDIF}\nend;\n\n{**\n   Get Interbase sql fields lenth\n   @param Index the index fields\n   @return Interbase sql fields lenth\n}\nfunction TZSQLDA.GetIbSqlLen(const Index: Word): Smallint;\nbegin\n  CheckRange(Index);\n  {$R-}\n  result := FXSQLDA.sqlvar[Index].sqllen;\n  {$IFOPT D+}\n{$R+}\n{$ENDIF}\nend;\n\n{**\n   Return sql name for field\n   @param Index the index fields\n   @return the sql name\n}\nfunction TZSQLDA.GetFieldSqlName(const Index: Word): String;\nbegin\n  CheckRange(Index);\n  {$R-}\n    {$IFDEF WITH_RAWBYTESTRING}\n    SetLength(Temp, FXSQLDA.sqlvar[Index].sqlname_length);\n    System.Move(FXSQLDA.sqlvar[Index].sqlname, PAnsiChar(Temp)^, FXSQLDA.sqlvar[Index].sqlname_length);\n    {$ELSE}\n    SetString(Temp, FXSQLDA.sqlvar[Index].sqlname, FXSQLDA.sqlvar[Index].sqlname_length);\n    {$ENDIF}\n    Result := ZDbcString(Temp);\n  {$IFOPT D+}\n{$R+}\n{$ENDIF}\nend;\n\n{**\n   Get Interbase subsql type\n   @param Index the index fields\n   @return the Interbase subsql\n}\nfunction TZSQLDA.GetIbSqlSubType(const Index: Word): Smallint;\nbegin\n  CheckRange(Index);\n  {$R-}\n  result := FXSQLDA.sqlvar[Index].sqlsubtype;\n  {$IFOPT D+}\n{$R+}\n{$ENDIF}\nend;\n\n{**\n   Get Interbase sql type\n   @param Index the index fields\n   @return the interbase sql type\n}\nfunction TZSQLDA.GetIbSqlType(const Index: Word): Smallint;\nbegin\n  CheckRange(Index);\n  {$R-}\n  result := FXSQLDA.sqlvar[Index].sqltype and not (1);\n  {$IFOPT D+}\n{$R+}\n{$ENDIF}\nend;\n\n{**\n   Reallocate memory and fill memory by #0\n   @param pointer to memory block\n   @param old size of memory block\n   @param new size of memory block\n}\nprocedure TZSQLDA.IbReAlloc(var P; OldSize, NewSize: Integer);\nbegin\n  ReallocMem(Pointer(P), NewSize);\n  if NewSize > OldSize then\n      Fillchar((PAnsiChar(P) + OldSize)^, NewSize - OldSize, #0);\nend;\n\nprocedure TZSQLDA.SetFieldType(const Index: Word; Size: Integer; Code: Smallint;\n  Scale: Smallint);\nbegin\n  CheckRange(Index);\n  {$R-}\n  with FXSQLDA.sqlvar[Index] do\n  begin\n    sqltype := Code;\n    if Scale <= 0 then\n      sqlscale := Scale;\n    sqllen := Size;\n    if (Size > 0) then\n      IbReAlloc(sqldata, 0, Size)\n    else\n    begin\n      FreeMem(sqldata);\n      sqldata := nil;\n    end;\n  end;\n  {$IFOPT D+}\n{$R+}\n{$ENDIF}\nend;\n\n{**\n   Indicate blob field\n   @param Index the index fields\n   @return true if blob field overwise false\n}\nfunction TZSQLDA.IsBlob(const Index: Word): boolean;\nbegin\n  CheckRange(Index);\n  {$R-}\n  result := ((FXSQLDA.sqlvar[Index].sqltype and not(1)) = SQL_BLOB);\n  {$IFOPT D+}\n{$R+}\n{$ENDIF}\nend;\n\n{**\n   Indicate blob field\n   @param Index the index fields\n   @return true if field nullable overwise false\n}\nfunction TZSQLDA.IsNullable(const Index: Word): boolean;\nbegin\n  CheckRange(Index);\n  {$R-}\n  Result := FXSQLDA.sqlvar[Index].sqltype and 1 = 1\n  {$IFOPT D+}\n{$R+}\n{$ENDIF}\nend;\n\n{**\n   Reallocate SQLDA to fields count length\n   @param Value the count fields\n}\nprocedure TZSQLDA.AllocateSQLDA;\nbegin\n  IbReAlloc(FXSQLDA, XSQLDA_LENGTH(FXSQLDA.sqln), XSQLDA_LENGTH(FXSQLDA.sqld));\n  FXSQLDA.sqln := FXSQLDA.sqld;\nend;\n\n{ TParamsSQLDA }\n\n{**\n   Free allocated memory and free object\n}\ndestructor TZParamsSQLDA.Destroy;\nbegin\n  FreeParamtersValues;\n  FreeMem(FXSQLDA);\n  inherited Destroy;\nend;\n\n{**\n   Encode pascal string to Interbase paramter buffer\n   @param Code the Interbase data type\n   @param Index the index target filed\n   @param Str the source string\n}\n\nprocedure TZParamsSQLDA.EncodeString(Code: Smallint; const Index: Word;\n  const Str: RawByteString);\nvar\n  Len: Cardinal;\nbegin\n  Len := Length(Str);\n  {$R-}\n   with FXSQLDA.sqlvar[Index] do\n    case Code of\n      SQL_TEXT :\n        begin\n          if (sqllen = 0) and (Str <> '') then //Manits: #0000249/pktfag\n            GetMem(sqldata, Len)\n          else\n            IbReAlloc(sqldata, 0, Len + 1);\n          sqllen := Len;\n          Move(PAnsiChar(Str)^, sqldata^, sqllen);\n        end;\n      SQL_VARYING :\n        begin\n          sqllen := Len + 2;\n          if sqllen = 0 then   //Egonhugeist: Todo: Need test case. Can't believe this line is correct! sqllen is min 2\n            GetMem(sqldata, Len + 2)\n          else\n            IbReAlloc(sqldata, 0, Len + 2);\n          PISC_VARYING(sqldata).strlen :=  Len;\n          Move(PAnsiChar(Str)^, PISC_VARYING(sqldata).str, PISC_VARYING(sqldata).strlen);\n        end;\n    end;\n  {$IFOPT D+}\n{$R+}\n{$ENDIF}\nend;\n\n{**\n   Encode Bytes dynamic array to Interbase paramter buffer\n   @param Code the Interbase data type\n   @param Index the index target filed\n   @param Value the source array\n}\n\nprocedure TZParamsSQLDA.EncodeBytes(Code: Smallint; const Index: Word;\n  const Value: TByteDynArray);\nvar\n  Len: Cardinal;\nbegin\n  Len := Length(Value);\n  {$R-}\n   with FXSQLDA.sqlvar[Index] do\n    case Code of\n      SQL_TEXT :\n        begin\n          if (sqllen = 0) and ( Len <> 0 ) then //Manits: #0000249/pktfag\n            GetMem(sqldata, Len)\n          else\n            IbReAlloc(sqldata, 0, Len + 1);\n          sqllen := Len;\n          Move(Pointer(Value)^, sqldata^, sqllen);\n        end;\n      SQL_VARYING :\n        begin\n          sqllen := Len + 2;\n          if sqllen = 0 then   //Egonhugeist: Todo: Need test case. Can't believe this line is correct! sqllen is min 2\n            GetMem(sqldata, Len + 2)\n          else\n            IbReAlloc(sqldata, 0, Len + 2);\n          PISC_VARYING(sqldata).strlen :=  Len;\n          Move(Pointer(Value)^, PISC_VARYING(sqldata).str, PISC_VARYING(sqldata).strlen);\n        end;\n    end;\n  {$IFOPT D+}\n{$R+}\n{$ENDIF}\nend;\n\n{**\n   Set up parameter BigDecimal value\n   @param Index the target parameter index\n   @param Value the source value\n}\nprocedure TZParamsSQLDA.UpdateBigDecimal(const Index: Integer; Value: Extended);\nvar\n  SQLCode: SmallInt;\nbegin\n  CheckRange(Index);\n\n  {$R-}\n  with FXSQLDA.sqlvar[Index] do\n  begin\n    if (sqlind <> nil) and (sqlind^ = -1) then\n       Exit;\n\n    SQLCode := (sqltype and not(1));\n\n    if (sqlscale < 0)  then\n    begin //http://code.google.com/p/fbclient/wiki/DatatypeMapping\n      case SQLCode of\n        SQL_SHORT  : PSmallInt(sqldata)^ := Trunc(Value * IBScaleDivisor[sqlscale]);\n        SQL_LONG   : PInteger(sqldata)^  := Trunc(Value * IBScaleDivisor[sqlscale]);\n        SQL_INT64,\n        SQL_QUAD   : //PInt64(sqldata)^    := Trunc(Value * GetIBScaleDivisor(sqlscale)); EgonHugeist: Trunc seems to have rounding issues!\n            //remain issues if decimal digits > scale than we've school learned rounding success randomly only\n            //each aproach did fail: RoundTo(Value, sqlscale*-1), Round etc.\n            //so the developer has to take\n            PInt64(sqldata)^    := StrToInt64(FloatToStrF(RoundTo(Value, sqlscale) * GetIBScaleDivisor(sqlscale), ffFixed, 18, 0));\n        SQL_DOUBLE : PDouble(sqldata)^   := Value;                                        //I have tested with Query.ParamByName ().AsCurrency to check this, problem does not lie with straight SQL\n      else\n        raise EZIBConvertError.Create(SUnsupportedDataType);\n      end;\n    end\n    else\n      case SQLCode of\n        SQL_DOUBLE    : PDouble(sqldata)^   := Value;\n        SQL_LONG      : PInteger(sqldata)^ := Trunc(Value);\n        SQL_D_FLOAT,\n        SQL_FLOAT     : PSingle(sqldata)^ := Value;\n        SQL_BOOLEAN   : PSmallint(sqldata)^ := Trunc(Value);\n        SQL_SHORT     : PSmallint(sqldata)^ := Trunc(Value);\n        SQL_INT64     : PInt64(sqldata)^ := Trunc(Value);\n        SQL_TEXT      : EncodeString(SQL_TEXT, Index, AnsiString(FloatToStr(Value)));\n        SQL_VARYING   : EncodeString(SQL_VARYING, Index, AnsiString(FloatToStr(Value)));\n      else\n        raise EZIBConvertError.Create(SUnsupportedDataType);\n      end;\n    if (sqlind <> nil) then\n       sqlind^ := 0; // not null\n  end;\n  {$IFOPT D+}\n{$R+}\n{$ENDIF}\nend;\n\n{**\n   Set up parameter Boolean value\n   @param Index the target parameter index\n   @param Value the source value\n}\nprocedure TZParamsSQLDA.UpdateBoolean(const Index: Integer; Value: boolean);\nvar\n  SQLCode: SmallInt;\nbegin\n  CheckRange(Index);\n  {$R-}\n  with FXSQLDA.sqlvar[Index] do\n  begin\n    if (sqlind <> nil) and (sqlind^ = -1) then\n       Exit;\n    SQLCode := (sqltype and not(1));\n\n    if (sqlscale < 0)  then\n    begin\n      case SQLCode of\n        SQL_SHORT  : PSmallInt(sqldata)^ := ord(Value) * IBScaleDivisor[sqlscale];\n        SQL_LONG   : PInteger(sqldata)^  := ord(Value) * IBScaleDivisor[sqlscale];\n        SQL_INT64,\n        SQL_QUAD   : PInt64(sqldata)^    := ord(Value) * IBScaleDivisor[sqlscale];\n        SQL_DOUBLE : PDouble(sqldata)^   := ord(Value);\n      else\n        raise EZIBConvertError.Create(SUnsupportedParameterType);\n      end;\n    end\n    else\n      case SQLCode of\n        SQL_DOUBLE    : PDouble(sqldata)^   := ord(Value);\n        SQL_LONG      : PInteger(sqldata)^ := ord(Value);\n        SQL_D_FLOAT,\n        SQL_FLOAT     : PSingle(sqldata)^ := ord(Value);\n        SQL_BOOLEAN   : PSmallint(sqldata)^ := ord(Value);\n        SQL_SHORT     : PSmallint(sqldata)^ := ord(Value);\n        SQL_INT64     : PInt64(sqldata)^ := ord(Value);\n        SQL_TEXT      : EncodeString(SQL_TEXT, Index, AnsiString(IntToStr(ord(Value))));\n        SQL_VARYING   : EncodeString(SQL_VARYING, Index, AnsiString(IntToStr(ord(Value))));\n      else\n        raise EZIBConvertError.Create(SUnsupportedParameterType);\n      end;\n    if (sqlind <> nil) then\n       sqlind^ := 0; // not null\n  end;\n  {$IFOPT D+}\n{$R+}\n{$ENDIF}\nend;\n\n{**\n   Set up parameter Byte value\n   @param Index the target parameter index\n   @param Value the source value\n}\nprocedure TZParamsSQLDA.UpdateByte(const Index: Integer; Value: ShortInt);\nvar\n  SQLCode: SmallInt;\nbegin\n  CheckRange(Index);\n  SetFieldType(Index, sizeof(Smallint), SQL_SHORT + 1, 0);\n  {$R-}\n  with FXSQLDA.sqlvar[Index] do\n  begin\n    if (sqlind <> nil) and (sqlind^ = -1) then\n       Exit;\n    SQLCode := (sqltype and not(1));\n\n    if (sqlscale < 0)  then\n    begin\n      case SQLCode of\n        SQL_SHORT  : PSmallInt(sqldata)^ := Value * IBScaleDivisor[sqlscale];\n        SQL_LONG   : PInteger(sqldata)^  := Value * IBScaleDivisor[sqlscale];\n        SQL_INT64,\n        SQL_QUAD   : PInt64(sqldata)^    := Value * IBScaleDivisor[sqlscale];\n        SQL_DOUBLE : PDouble(sqldata)^   := Value;\n      else\n        raise EZIBConvertError.Create(SUnsupportedParameterType);\n      end;\n    end\n    else\n      case SQLCode of\n        SQL_DOUBLE    : PDouble(sqldata)^   := Value;\n        SQL_LONG      : PInteger(sqldata)^ := Value;\n        SQL_D_FLOAT,\n        SQL_FLOAT     : PSingle(sqldata)^ := Value;\n        SQL_BOOLEAN:\n                     begin\n                       if FPlainDriver.GetProtocol <> 'interbase-7' then\n                         raise EZIBConvertError.Create(SUnsupportedDataType);\n                       PSmallint(sqldata)^ := Value;\n                     end;\n        SQL_SHORT     : PSmallint(sqldata)^ := Value;\n        SQL_INT64     : PInt64(sqldata)^ := Value;\n        SQL_TEXT      : EncodeString(SQL_TEXT, Index, AnsiString(IntToStr(Value)));\n        SQL_VARYING   : EncodeString(SQL_VARYING, Index, AnsiString(IntToStr(Value)));\n      else\n        raise EZIBConvertError.Create(SUnsupportedParameterType);\n      end;\n    if (sqlind <> nil) then\n       sqlind^ := 0; // not null\n  end;\n  {$IFOPT D+}\n{$R+}\n{$ENDIF}\nend;\n\n{**\n   Set up parameter byte value\n   @param Index the target parameter index\n   @param Value the source value\n}\nprocedure TZParamsSQLDA.UpdateBytes(const Index: Integer; Value: TByteDynArray);\nvar\n SQLCode: SmallInt;\n Stream: TStream;\n Len: Integer;\nbegin\n  CheckRange(Index);\n//  SetFieldType(Index, Length(Value) + 1, SQL_TEXT + 1, 0);\n  {$R-}\n  with FXSQLDA.sqlvar[Index] do\n  begin\n    if (sqlind <> nil) and (sqlind^ = -1) then\n         Exit;\n    SQLCode := (sqltype and not(1));\n    case SQLCode of\n      SQL_TEXT      : EncodeBytes(SQL_TEXT, Index, Value);\n      SQL_VARYING   : EncodeBytes(SQL_VARYING, Index, Value);\n      SQL_LONG      : PInteger (sqldata)^ := Round(ZStrToFloat(BytesToStr(Value)) * IBScaleDivisor[sqlscale]); //AVZ\n      SQL_SHORT     : PInteger (sqldata)^ := StrToInt(String(BytesToStr(Value)));\n      SQL_TYPE_DATE : EncodeString(SQL_DATE, Index, BytesToStr(Value));\n      SQL_DOUBLE    : PDouble (sqldata)^ := ZStrToFloat(BytesToStr(Value)) * IBScaleDivisor[sqlscale]; //AVZ\n      SQL_D_FLOAT,\n      SQL_FLOAT     : PSingle (sqldata)^ := ZStrToFloat(BytesToStr(Value)) * IBScaleDivisor[sqlscale];  //AVZ\n      SQL_INT64     : PInt64(sqldata)^ := Trunc(ZStrToFloat(BytesToStr(Value)) * IBScaleDivisor[sqlscale]); //AVZ - INT64 value was not recognized\n      SQL_BLOB, SQL_QUAD:\n        begin\n          Stream := TMemoryStream.Create;\n          try\n            Len := Length(Value);\n            Stream.Size := Len;\n            System.Move(Pointer(Value)^, TMemoryStream(Stream).Memory^, Len);\n            WriteBlob(index, Stream);\n          finally\n            Stream.Free;\n          end;\n        end;\n    else\n      raise EZIBConvertError.Create(SErrorConvertion);\n    end;\n    if (sqlind <> nil) then\n         sqlind^ := 0; // not null\n  end;\n  {$IFOPT D+}\n{$R+}\n{$ENDIF}\nend;\n\n{**\n   Set up parameter Date value\n   @param Index the target parameter index\n   @param Value the source value\n}\nprocedure TZParamsSQLDA.UpdateDate(const Index: Integer; Value: TDateTime);\nbegin\n  SetFieldType(Index, sizeof(Integer), SQL_TYPE_DATE + 1, 0);\n  UpdateDateTime(Index, Value);\nend;\n\n{**\n   Set up parameter DateTime value\n   @param Index the target parameter index\n   @param Value the source value\n}\nprocedure TZParamsSQLDA.UpdateDateTime(const Index: Integer;\n  Value: TDateTime);\nvar\n  y, m, d: word;\n  hr, min, sec, msec: word;\n  SQLCode: SmallInt;\n  TmpDate: TCTimeStructure;\nbegin\n  CheckRange(Index);\n  {$R-}\n  with FXSQLDA.sqlvar[Index] do\n  begin\n    DecodeDate(Value, y, m, d);\n    DecodeTime(Value, hr, min, sec, msec);\n    TmpDate.tm_year := y - 1900;\n    TmpDate.tm_mon := m - 1;\n    TmpDate.tm_mday := d;\n    TmpDate.tm_hour := hr;\n    TmpDate.tm_min := min;\n    TmpDate.tm_sec := sec;\n    TmpDate.tm_wday := 0;\n    TmpDate.tm_yday := 0;\n    TmpDate.tm_isdst := 0;\n\n    if (sqlind <> nil) and (sqlind^ = -1) then\n       Exit;\n    SQLCode := (sqltype and not(1));\n\n    case SQLCode of\n      SQL_TYPE_DATE : FPlainDriver.isc_encode_sql_date(@TmpDate, PISC_DATE(sqldata));\n      SQL_TYPE_TIME : begin\n                        FPlainDriver.isc_encode_sql_time(@TmpDate, PISC_TIME(sqldata));\n                        PISC_TIME(sqldata)^ := PISC_TIME(sqldata)^ + msec*10;\n                      end;\n      SQL_TIMESTAMP : begin\n                        FPlainDriver.isc_encode_timestamp(@TmpDate,PISC_TIMESTAMP(sqldata));\n                        PISC_TIMESTAMP(sqldata).timestamp_time :=PISC_TIMESTAMP(sqldata).timestamp_time + msec*10;\n                      end;\n      else\n        raise EZIBConvertError.Create(SInvalidState);\n    end;\n    if (sqlind <> nil) then\n         sqlind^ := 0; // not null\n  end;\n  {$IFOPT D+}\n{$R+}\n{$ENDIF}\nend;\n\n{**\n   Set up parameter Double value\n   @param Index the target parameter index\n   @param Value the source value\n}\nprocedure TZParamsSQLDA.UpdateDouble(const Index: Integer; Value: Double);\nvar\n  SQLCode: SmallInt;\nbegin\n  CheckRange(Index);\n  SetFieldType(Index, sizeof(double), SQL_DOUBLE + 1, 0);\n  {$R-}\n  with FXSQLDA.sqlvar[Index] do\n  begin\n    if (sqlind <> nil) and (sqlind^ = -1) then\n         Exit;\n    SQLCode := (sqltype and not(1));\n\n    if (sqlscale < 0)  then\n    begin\n      case SQLCode of\n        SQL_SHORT  : PSmallInt(sqldata)^ := Trunc(Value * IBScaleDivisor[sqlscale]);\n        SQL_LONG   : PInteger(sqldata)^  := Trunc(Value * IBScaleDivisor[sqlscale]);\n        SQL_INT64,\n        SQL_QUAD   : PInt64(sqldata)^    := Trunc(Value * IBScaleDivisor[sqlscale]);\n        SQL_DOUBLE : PDouble(sqldata)^   := Value;\n      else\n        raise EZIBConvertError.Create(SUnsupportedDataType);\n      end;\n    end\n    else\n      case SQLCode of\n        SQL_DOUBLE    : PDouble(sqldata)^   := Value;\n        SQL_LONG      : PInteger(sqldata)^ := Trunc(Value);\n        SQL_D_FLOAT,\n        SQL_FLOAT     : PSingle(sqldata)^ := Value;\n        SQL_BOOLEAN   : PSmallint(sqldata)^ := Trunc(Value);\n        SQL_SHORT     : PSmallint(sqldata)^ := Trunc(Value);\n        SQL_INT64     : PInt64(sqldata)^ := Trunc(Value);\n        SQL_TEXT      : EncodeString(SQL_TEXT, Index, AnsiString(FloatToStr(Value)));\n        SQL_VARYING   : EncodeString(SQL_VARYING, Index, AnsiString(FloatToStr(Value)));\n      else\n        raise EZIBConvertError.Create(SUnsupportedDataType);\n      end;\n      if (sqlind <> nil) then\n         sqlind^ := 0; // not null\n  end;\n  {$IFOPT D+}\n{$R+}\n{$ENDIF}\nend;\n\n{**\n   Set up parameter Float value\n   @param Index the target parameter index\n   @param Value the source value\n}\nprocedure TZParamsSQLDA.UpdateFloat(const Index: Integer; Value: Single);\nvar\n  SQLCode: SmallInt;\nbegin\n  CheckRange(Index);\n  SetFieldType(Index, sizeof(Single), SQL_FLOAT + 1, 1);\n  {$R-}\n  with FXSQLDA.sqlvar[Index] do\n  begin\n    if (sqlind <> nil) and (sqlind^ = -1) then\n       Exit;\n    SQLCode := (sqltype and not(1));\n\n    if (sqlscale < 0)  then\n    begin\n      case SQLCode of\n        SQL_SHORT  : PSmallInt(sqldata)^ := Trunc(Value * IBScaleDivisor[sqlscale]);\n        SQL_LONG   : PInteger(sqldata)^  := Trunc(Value * IBScaleDivisor[sqlscale]);\n        SQL_INT64,\n        SQL_QUAD   : PInt64(sqldata)^    := Trunc(Value * IBScaleDivisor[sqlscale]);\n        SQL_DOUBLE : PDouble(sqldata)^   := Value;\n        SQL_D_FLOAT,\n        SQL_FLOAT  : PSingle(sqldata)^   := Value;\n      else\n        raise EZIBConvertError.Create(SUnsupportedDataType);\n      end;\n    end\n    else\n      case SQLCode of\n        SQL_DOUBLE    : PDouble(sqldata)^   := Value;\n        SQL_LONG      : PInteger(sqldata)^ := Trunc(Value);\n        SQL_D_FLOAT,\n        SQL_FLOAT     : PSingle(sqldata)^ := Value;\n        SQL_BOOLEAN   : PSmallint(sqldata)^ := Trunc(Value);\n        SQL_SHORT     : PSmallint(sqldata)^ := Trunc(Value);\n        SQL_INT64     : PInt64(sqldata)^ := Trunc(Value);\n        SQL_TEXT      : EncodeString(SQL_TEXT, Index, AnsiString(FloatToStr(Value)));\n        SQL_VARYING   : EncodeString(SQL_VARYING, Index, AnsiString(FloatToStr(Value)));\n      else\n        raise EZIBConvertError.Create(SUnsupportedDataType);\n      end;\n      if (sqlind <> nil) then\n         sqlind^ := 0; // not null\n  end;\n  {$IFOPT D+}\n{$R+}\n{$ENDIF}\nend;\n\n{**\n   Set up parameter integer value\n   @param Index the target parameter index\n   @param Value the source value\n}\nprocedure TZParamsSQLDA.UpdateInt(const Index: Integer; Value: Integer);\nvar\n  SQLCode: SmallInt;\nbegin\n  CheckRange(Index);\n  SetFieldType(Index, sizeof(Integer), SQL_LONG + 1, 0);\n  {$R-}\n  with FXSQLDA.sqlvar[Index] do\n  begin\n    if (sqlind <> nil) and (sqlind^ = -1) then\n       Exit;\n    SQLCode := (sqltype and not(1));\n\n    if (sqlscale < 0)  then\n    begin\n      case SQLCode of\n        SQL_SHORT  : PSmallInt(sqldata)^ := Value * IBScaleDivisor[sqlscale];\n        SQL_LONG   : PInteger(sqldata)^  := Value * IBScaleDivisor[sqlscale];\n        SQL_INT64,\n        SQL_QUAD   : PInt64(sqldata)^    := Value * IBScaleDivisor[sqlscale];\n        SQL_DOUBLE : PDouble(sqldata)^   := Value;\n      else\n        raise EZIBConvertError.Create(SUnsupportedDataType);\n      end;\n    end\n    else\n      case SQLCode of\n        SQL_DOUBLE    : PDouble(sqldata)^   := Value;\n        SQL_LONG      : PInteger(sqldata)^ := Value;\n        SQL_D_FLOAT,\n        SQL_FLOAT     : PSingle(sqldata)^ := Value;\n        SQL_BOOLEAN   : PSmallint(sqldata)^ := Value;\n        SQL_SHORT     : PSmallint(sqldata)^ := Value;\n        SQL_INT64     : PInt64(sqldata)^ := Value;\n        SQL_TEXT      : EncodeString(SQL_TEXT, Index, AnsiString(IntToStr(Value)));\n        SQL_VARYING   : EncodeString(SQL_VARYING, Index, AnsiString(IntToStr(Value)));\n      else\n        raise EZIBConvertError.Create(SUnsupportedDataType);\n      end;\n      if (sqlind <> nil) then\n         sqlind^ := 0; // not null\n  end;\n  {$IFOPT D+}\n{$R+}\n{$ENDIF}\nend;\n\n{**\n   Set up parameter Long value\n   @param Index the target parameter index\n   @param Value the source value\n}\nprocedure TZParamsSQLDA.UpdateLong(const Index: integer; Value: Int64);\nvar\n  SQLCode: SmallInt;\nbegin\n  CheckRange(Index);\n  SetFieldType(Index, sizeof(Int64), SQL_INT64 + 1, 0);\n  {$R-}\n  with FXSQLDA.sqlvar[Index] do\n  begin\n    if (sqlind <> nil) and (sqlind^ = -1) then\n         Exit;\n    SQLCode := (sqltype and not(1));\n\n    if (sqlscale < 0)  then\n    begin\n      case SQLCode of\n        SQL_SHORT  : PSmallInt(sqldata)^ := Value * IBScaleDivisor[sqlscale];\n        SQL_LONG   : PInteger(sqldata)^  := Value * IBScaleDivisor[sqlscale];\n        SQL_INT64,\n        SQL_QUAD   : PInt64(sqldata)^    := Value * IBScaleDivisor[sqlscale];\n        SQL_DOUBLE : PDouble(sqldata)^   := Value;\n      else\n        raise EZIBConvertError.Create(SUnsupportedDataType);\n      end;\n    end\n    else\n      case SQLCode of\n        SQL_DOUBLE    : PDouble(sqldata)^   := Value;\n        SQL_LONG      : PInteger(sqldata)^ := Value;\n        SQL_D_FLOAT,\n        SQL_FLOAT     : PSingle(sqldata)^ := Value;\n        SQL_BOOLEAN   : PSmallint(sqldata)^ := Value;\n        SQL_SHORT     : PSmallint(sqldata)^ := Value;\n        SQL_INT64     : PInt64(sqldata)^ := Value;\n        SQL_TEXT      : EncodeString(SQL_TEXT, Index, AnsiString(IntToStr(Value)));\n        SQL_VARYING   : EncodeString(SQL_VARYING, Index, AnsiString(IntToStr(Value)));\n      else\n        raise EZIBConvertError.Create(SUnsupportedDataType);\n      end;\n      if (sqlind <> nil) then\n         sqlind^ := 0; // not null\n  end;\n  {$IFOPT D+}\n{$R+}\n{$ENDIF}\nend;\n\n{**\n   Set up parameter null value\n   @param Index the target parameter index\n   @param Value the source value\n}\nprocedure TZParamsSQLDA.UpdateNull(const Index: Integer; Value: boolean);\nbegin\n  CheckRange(Index);\n  {$R-}\n  with FXSQLDA.sqlvar[Index] do\n    if (sqlind <> nil) then\n      case Value of\n        True  : sqlind^ := -1; //NULL\n        False : sqlind^ :=  0; //NOT NULL\n      end;\n  {$IFOPT D+}\n{$R+}\n{$ENDIF}\nend;\n\n{**\n   Set up parameter PAnsiChar value\n   @param Index the target parameter index\n   @param Value the source value\n}\nprocedure TZParamsSQLDA.UpdatePChar(const Index: Integer; Value: PAnsiChar);\nvar\n  TempString: AnsiString;\nbegin\n  TempString := Value;\n  UpdateString(Index, TempString);\nend;\n\n{**\n   Set up parameter Interbase QUAD value\n   @param Index the target parameter index\n   @param Value the source value\n}\nprocedure TZParamsSQLDA.UpdateQuad(const Index: Word; const Value: TISC_QUAD);\nbegin\n  CheckRange(Index);\n  SetFieldType(Index, sizeof(TISC_QUAD), SQL_QUAD + 1, 0);\n  {$R-}\n  with FXSQLDA.sqlvar[Index] do\n    if not ((sqlind <> nil) and (sqlind^ = -1)) then\n    begin\n      case (sqltype and not(1)) of\n        SQL_QUAD, SQL_DOUBLE, SQL_INT64, SQL_BLOB, SQL_ARRAY: PISC_QUAD(sqldata)^ := Value;\n      else\n        raise EZIBConvertError.Create(SUnsupportedDataType);\n      end;\n      if (sqlind <> nil) then\n          sqlind^ := 0; // not null\n    end\n    else\n      raise EZIBConvertError.Create(SUnsupportedDataType);\n  {$IFOPT D+}\n{$R+}\n{$ENDIF}\nend;\n\n{**\n   Set up parameter short value\n   @param Index the target parameter index\n   @param Value the source value\n}\nprocedure TZParamsSQLDA.UpdateShort(const Index: Integer; Value: SmallInt);\nvar\n  SQLCode: SmallInt;\nbegin\n  CheckRange(Index);\n  SetFieldType(Index, sizeof(Smallint), SQL_SHORT + 1, 0);\n  {$R-}\n  with FXSQLDA.sqlvar[Index] do\n  begin\n    if (sqlind <> nil) and (sqlind^ = -1) then\n         Exit;\n    SQLCode := (sqltype and not(1));\n\n    if (sqlscale < 0)  then\n    begin\n      case SQLCode of\n        SQL_SHORT  : PSmallInt(sqldata)^ := Value * IBScaleDivisor[sqlscale];\n        SQL_LONG   : PInteger(sqldata)^  := Value * IBScaleDivisor[sqlscale];\n        SQL_INT64,\n        SQL_QUAD   : PInt64(sqldata)^    := Value * IBScaleDivisor[sqlscale];\n        SQL_DOUBLE : PDouble(sqldata)^   := Value;\n      else\n        raise EZIBConvertError.Create(SUnsupportedDataType);\n      end;\n    end\n    else\n      case SQLCode of\n        SQL_DOUBLE    : PDouble(sqldata)^   := Value;\n        SQL_LONG      : PInteger(sqldata)^ := Value;\n        SQL_D_FLOAT,\n        SQL_FLOAT     : PSingle(sqldata)^ := Value;\n        SQL_BOOLEAN   : PSmallint(sqldata)^ := Value;\n        SQL_SHORT     : PSmallint(sqldata)^ := Value;\n        SQL_INT64     : PInt64(sqldata)^ := Value;\n        SQL_TEXT      : EncodeString(SQL_TEXT, Index, AnsiString(IntToStr(Value)));\n        SQL_VARYING   : EncodeString(SQL_VARYING, Index, AnsiString(IntToStr(Value)));\n      else\n        raise EZIBConvertError.Create(SUnsupportedDataType);\n      end;\n      if (sqlind <> nil) then\n         sqlind^ := 0; // not null\n  end;\n  {$IFOPT D+}\n{$R+}\n{$ENDIF}\nend;\n\n{**\n   Set up parameter String value\n   @param Index the target parameter index\n   @param Value the source value\n}\n\nprocedure TZParamsSQLDA.UpdateString(const Index: Integer; Value: RawByteString);\nvar\n SQLCode: SmallInt;\n Stream: TStream;\nbegin\n  CheckRange(Index);\n//  SetFieldType(Index, Length(Value) + 1, SQL_TEXT + 1, 0);\n  {$R-}\n  with FXSQLDA.sqlvar[Index] do\n  begin\n    if (sqlind <> nil) and (sqlind^ = -1) then\n         Exit;\n    SQLCode := (sqltype and not(1));\n    case SQLCode of\n      SQL_TEXT      : EncodeString(SQL_TEXT, Index, Value);\n      SQL_VARYING   : EncodeString(SQL_VARYING, Index, Value);\n      SQL_LONG      : PInteger (sqldata)^ := StrToInt(String(Value)); //AVZ\n      SQL_SHORT     : PSmallInt (sqldata)^ := StrToInt(String(Value));\n      SQL_TYPE_DATE : EncodeString(SQL_DATE, Index, Value);\n      SQL_DOUBLE    : PDouble (sqldata)^ := ZStrToFloat(Value) * IBScaleDivisor[sqlscale]; //AVZ\n      SQL_D_FLOAT,\n      SQL_FLOAT     : PSingle (sqldata)^ := ZStrToFloat(Value) * IBScaleDivisor[sqlscale];  //AVZ\n      SQL_INT64     : PInt64(sqldata)^ := Trunc(ZStrToFloat(Value) * IBScaleDivisor[sqlscale]); //AVZ - INT64 value was not recognized\n      SQL_BLOB, SQL_QUAD:\n        begin\n          Stream := TStringStream.Create(Value);\n          try\n            WriteBlob(index, Stream);\n          finally\n            Stream.Free;\n          end;\n        end;\n    else\n      raise EZIBConvertError.Create(SErrorConvertion);\n    end;\n    if (sqlind <> nil) then\n         sqlind^ := 0; // not null\n  end;\n  {$IFOPT D+}\n{$R+}\n{$ENDIF}\nend;\n\n{**\n   Set up parameter Time value\n   @param Index the target parameter index\n   @param Value the source value\n}\nprocedure TZParamsSQLDA.UpdateTime(const Index: Integer; Value: TDateTime);\nbegin\n  SetFieldType(Index, sizeof(Cardinal), SQL_TYPE_TIME + 1, 0);\n  UpdateDateTime(Index, Value);\nend;\n\n{**\n   Set up parameter Timestamp value\n   @param Index the target parameter index\n   @param Value the source value\n}\nprocedure TZParamsSQLDA.UpdateTimestamp(const Index: Integer; Value: TDateTime);\nbegin\n  SetFieldType(Index, sizeof(TISC_QUAD), SQL_TIMESTAMP + 1, 0);\n  UpdateDateTime(Index, Value);\nend;\n\n{**\n   Write stream to blob field\n   @param Index an index field number\n   @param Stream the souse data stream\n}\nprocedure TZParamsSQLDA.WriteBlob(const Index: Integer; Stream: TStream);\nvar\n  Buffer: PAnsiChar;\n  BlobId: TISC_QUAD;\n  BlobHandle: TISC_BLOB_HANDLE;\n  StatusVector: TARRAY_ISC_STATUS;\n  BlobSize, CurPos, SegLen: Integer;\nbegin\n  BlobHandle := 0;\n  Stream.Seek(0, 0);\n\n  { create blob handle }\n  FPlainDriver.isc_create_blob2(@StatusVector, FHandle, FTransactionHandle,\n    @BlobHandle, @BlobId, 0, nil);\n  CheckInterbase6Error(FPlainDriver, StatusVector);\n\n  Stream.Position := 0;\n  BlobSize := Stream.Size;\n  Buffer := AllocMem(BlobSize);\n  Try\n    Stream.ReadBuffer(Buffer^, BlobSize);\n\n    { put data to blob }\n    CurPos := 0;\n    SegLen := DefaultBlobSegmentSize;\n    while (CurPos < BlobSize) do\n    begin\n      if (CurPos + SegLen > BlobSize) then\n        SegLen := BlobSize - CurPos;\n      if FPlainDriver.isc_put_segment(@StatusVector, @BlobHandle, SegLen,\n            PAnsiChar(@Buffer[CurPos])) > 0 then\n        CheckInterbase6Error(FPlainDriver, StatusVector);\n      Inc(CurPos, SegLen);\n    end;\n\n    { close blob handle }\n    FPlainDriver.isc_close_blob(@StatusVector, @BlobHandle);\n    CheckInterbase6Error(FPlainDriver, StatusVector);\n\n    Stream.Seek(0, 0);\n    UpdateQuad(Index, BlobId);\n  Finally\n    Freemem(Buffer);\n  End;\nend;\n\n{ TResultSQLDA }\n\n{**\n   Decode Interbase field value to pascal string\n   @param Code the Interbase data type\n   @param Index field index\n   @result the field string\n}\nfunction TZResultSQLDA.DecodeString(const Code: Smallint;\n   const Index: Word): RawByteString;\nvar\n   l: integer;\n  procedure SetAnsi(Ansi: PAnsiChar; Len: Longint);\n  begin\n    SetLength(Result, Len);\n    System.Move(Ansi^, PAnsiChar(Result)^, Len);\n  end;\nbegin\n  {$R-}\n  with FXSQLDA.sqlvar[Index] do\n  case Code of\n    SQL_TEXT:\n      begin\n        SetAnsi(sqldata, sqllen);\n        // Trim only spaces. TrimRight also removes other characters)\n        l := sqllen;\n        while (l > 0) and (Result[l] = ' ') do\n           dec(l);\n        if l < sqllen then\n           result := copy(result, 1, l);\n      end;\n    SQL_VARYING : SetAnsi(PISC_VARYING(sqldata).str, PISC_VARYING(sqldata).strlen);\n  end;\n  {$IFOPT D+}\n{$R+}\n{$ENDIF}\nend;\n\n{**\n   Decode Interbase field value to pascal string\n   @param Code the Interbase data type\n   @param Index field index\n   @param Str the field string\n}\nprocedure TZResultSQLDA.DecodeString2(const Code: Smallint; const Index: Word;\n  out Str: RawByteString);\nbegin\n  Str := DecodeString(Code, Index);\nend;\n\n{**\n   Return BigDecimal field value\n   @param Index the field index\n   @return the field BigDecimal value\n}\nfunction TZResultSQLDA.GetBigDecimal(const Index: Integer): Extended;\nvar\n  SQLCode: SmallInt;\nbegin\n  CheckRange(Index);\n  {$R-}\n  with FXSQLDA.sqlvar[Index] do\n  begin\n    Result := 0;\n    if (sqlind <> nil) and (sqlind^ = -1) then\n         Exit;\n    SQLCode := (sqltype and not(1));\n\n    if (sqlscale < 0)  then\n    begin\n      case SQLCode of\n        SQL_SHORT  : Result := PSmallInt(sqldata)^ / IBScaleDivisor[sqlscale];\n        SQL_LONG   : Result := PInteger(sqldata)^  / IBScaleDivisor[sqlscale];\n        SQL_INT64,\n        SQL_QUAD   : Result := PInt64(sqldata)^    / IBScaleDivisor[sqlscale];\n        SQL_DOUBLE : Result := PDouble(sqldata)^;\n      else\n        raise EZIBConvertError.Create(Format(SErrorConvertionField,\n          [GetFieldAliasName(Index), GetNameSqlType(SQLCode)]));\n      end;\n    end\n    else\n      case SQLCode of\n        SQL_DOUBLE    : Result := PDouble(sqldata)^;\n        SQL_LONG      : Result := PInteger(sqldata)^;\n        SQL_D_FLOAT,\n        SQL_FLOAT     : Result := PSingle(sqldata)^;\n        SQL_BOOLEAN   : Result := PSmallint(sqldata)^;\n        SQL_SHORT     : Result := PSmallint(sqldata)^;\n        SQL_INT64     : Result := PInt64(sqldata)^;\n        SQL_TEXT      : Result := StrToFloat(String(DecodeString(SQL_TEXT, Index)));\n        SQL_VARYING   : Result := StrToFloat(String(DecodeString(SQL_VARYING, Index)));\n      else\n        raise EZIBConvertError.Create(Format(SErrorConvertionField,\n          [GetFieldAliasName(Index), GetNameSqlType(SQLCode)]));\n      end;\n   end;\n  {$IFOPT D+}\n{$R+}\n{$ENDIF}\nend;\n\n{**\n   Return Boolean field value\n   @param Index the field index\n   @return the field boolean value\n}\nfunction TZResultSQLDA.GetBoolean(const Index: Integer): Boolean;\nvar\n  SQLCode: SmallInt;\nbegin\n  CheckRange(Index);\n  {$R-}\n  with FXSQLDA.sqlvar[Index] do\n  begin\n    Result := False;\n    if (sqlind <> nil) and (sqlind^ = -1) then\n         Exit;\n    SQLCode := (sqltype and not(1));\n\n    if (sqlscale < 0)  then\n    begin\n      case SQLCode of\n        SQL_SHORT  : Result := PSmallInt(sqldata)^ div IBScaleDivisor[sqlscale] <> 0;\n        SQL_LONG   : Result := PInteger(sqldata)^  div IBScaleDivisor[sqlscale] <> 0;\n        SQL_INT64,\n        SQL_QUAD   : Result := PInt64(sqldata)^    div IBScaleDivisor[sqlscale] <> 0;\n        SQL_DOUBLE : Result := Trunc(PDouble(sqldata)^) > 0;\n      else\n        raise EZIBConvertError.Create(Format(SErrorConvertionField,\n          [GetFieldAliasName(Index), GetNameSqlType(SQLCode)]));\n      end;\n    end\n    else\n      case SQLCode of\n        SQL_DOUBLE    : Result := Trunc(PDouble(sqldata)^) <> 0;\n        SQL_LONG      : Result := PInteger(sqldata)^ <> 0;\n        SQL_D_FLOAT,\n        SQL_FLOAT     : Result := Trunc(PSingle(sqldata)^) <> 0;\n        SQL_BOOLEAN   : Result := PSmallint(sqldata)^ <> 0;\n        SQL_SHORT     : Result := PSmallint(sqldata)^ <> 0;\n        SQL_INT64     : Result := PInt64(sqldata)^ <> 0;\n        SQL_TEXT      : Result := StrToInt(String(DecodeString(SQL_TEXT, Index))) <> 0;\n        SQL_VARYING   : Result := StrToInt(String(DecodeString(SQL_VARYING, Index))) <> 0;\n      else\n        raise EZIBConvertError.Create(Format(SErrorConvertionField,\n          [GetFieldAliasName(Index), GetNameSqlType(SQLCode)]));\n      end;\n  end;\n  {$IFOPT D+}\n{$R+}\n{$ENDIF}\nend;\n\n{**\n   Return Byte field value\n   @param Index the field index\n   @return the field Byte value\n}\nfunction TZResultSQLDA.GetByte(const Index: Integer): Byte;\nbegin\n  Result := Byte(GetShort(Index));\nend;\n\n{**\n   Return Bytes field value\n   @param Index the field index\n   @return the field Bytes value\n}\nfunction TZResultSQLDA.GetBytes(const Index: Integer): TByteDynArray;\nvar\n  SQLCode: SmallInt;\nbegin\n  CheckRange(Index);\n  Result := nil;\n  {$R-}\n  with FXSQLDA.sqlvar[Index] do\n  begin\n    if (sqlind <> nil) and (sqlind^ = -1) then\n         Exit;\n    SQLCode := (sqltype and not(1));\n\n      case SQLCode of\n        SQL_TEXT, SQL_VARYING:\n          begin\n            SetLength(Result, sqllen);\n            System.Move(PAnsiChar(sqldata)^, Pointer(Result)^, sqllen);\n          end;\n        else\n          raise EZIBConvertError.Create(Format(SErrorConvertionField,\n            [GetFieldAliasName(Index), GetNameSqlType(SQLCode)]));\n      end;\n  end;\n  {$IFOPT D+}\n{$R+}\n{$ENDIF}\nend;\n\n{**\n   Return Date field value\n   @param Index the field index\n   @return the field Date value\n}\nfunction TZResultSQLDA.GetDate(const Index: Integer): TDateTime;\nbegin\n  Result := Trunc(GetTimestamp(Index));\nend;\n\n{**\n   Return Double field value\n   @param Index the field index\n   @return the field Double value\n}\nfunction TZResultSQLDA.GetDouble(const Index: Integer): Double;\nvar\n  SQLCode: SmallInt;\nbegin\n  CheckRange(Index);\n  {$R-}\n  with FXSQLDA.sqlvar[Index] do\n  begin\n    Result := 0;\n    if (sqlind <> nil) and (sqlind^ = -1) then\n         Exit;\n    SQLCode := (sqltype and not(1));\n\n    if (sqlscale < 0)  then\n    begin\n      case SQLCode of\n        SQL_SHORT  : Result := PSmallInt(sqldata)^ / IBScaleDivisor[sqlscale];\n        SQL_LONG   : Result := PInteger(sqldata)^  / IBScaleDivisor[sqlscale];\n        SQL_INT64,\n        SQL_QUAD   : Result := PInt64(sqldata)^    / IBScaleDivisor[sqlscale];\n        SQL_DOUBLE : Result := PDouble(sqldata)^;\n      else\n        raise EZIBConvertError.Create(Format(SErrorConvertionField,\n          [GetFieldAliasName(Index), GetNameSqlType(SQLCode)]));\n      end;\n    end\n    else\n      case SQLCode of\n        SQL_DOUBLE    : Result := PDouble(sqldata)^;\n        SQL_LONG      : Result := PInteger(sqldata)^;\n        SQL_D_FLOAT,\n        SQL_FLOAT     : Result := PSingle(sqldata)^;\n        SQL_BOOLEAN   : Result := PSmallint(sqldata)^;\n        SQL_SHORT     : Result := PSmallint(sqldata)^;\n        SQL_INT64     : Result := PInt64(sqldata)^;\n        SQL_TEXT      : Result := StrToFloat(String(DecodeString(SQL_TEXT, Index)));\n        SQL_VARYING   : Result := StrToFloat(String(DecodeString(SQL_VARYING, Index)));\n      else\n        raise EZIBConvertError.Create(Format(SErrorConvertionField,\n          [GetFieldAliasName(Index), GetNameSqlType(SQLCode)]));\n      end;\n  end;\n  {$IFOPT D+}\n{$R+}\n{$ENDIF}\nend;\n\n{**\n   Return Float field value\n   @param Index the field index\n   @return the field Float value\n}\nfunction TZResultSQLDA.GetFloat(const Index: Integer): Single;\nvar\n  SQLCode: SmallInt;\nbegin\n  CheckRange(Index);\n  {$R-}\n  with FXSQLDA.sqlvar[Index] do\n  begin\n    Result := 0;\n    if (sqlind <> nil) and (sqlind^ = -1) then\n         Exit;\n    SQLCode := (sqltype and not(1));\n\n    if (sqlscale < 0)  then\n    begin\n      case SQLCode of\n        SQL_SHORT  : Result := PSmallInt(sqldata)^ / IBScaleDivisor[sqlscale];\n        SQL_LONG   : Result := PInteger(sqldata)^  / IBScaleDivisor[sqlscale];\n        SQL_INT64,\n        SQL_QUAD   : Result := PInt64(sqldata)^    / IBScaleDivisor[sqlscale];\n        SQL_DOUBLE : Result := PDouble(sqldata)^;\n      else\n        raise EZIBConvertError.Create(Format(SErrorConvertionField,\n          [GetFieldAliasName(Index), GetNameSqlType(SQLCode)]));\n      end;\n    end\n    else\n      case SQLCode of\n        SQL_DOUBLE    : Result := PDouble(sqldata)^;\n        SQL_LONG      : Result := PInteger(sqldata)^;\n        SQL_D_FLOAT,\n        SQL_FLOAT     : Result := PSingle(sqldata)^;\n        SQL_BOOLEAN   : Result := PSmallint(sqldata)^;\n        SQL_SHORT     : Result := PSmallint(sqldata)^;\n        SQL_INT64     : Result := PInt64(sqldata)^;\n        SQL_TEXT      : Result := StrToFloat(String(DecodeString(SQL_TEXT, Index)));\n        SQL_VARYING   : Result := StrToFloat(String(DecodeString(SQL_VARYING, Index)));\n      else\n        raise EZIBConvertError.Create(Format(SErrorConvertionField,\n          [GetFieldAliasName(Index), GetNameSqlType(SQLCode)]));\n      end;\n  end;\n  {$IFOPT D+}\n{$R+}\n{$ENDIF}\nend;\n\n{**\n   Return Integer field value\n   @param Index the field index\n   @return the field Integer value\n}\nfunction TZResultSQLDA.GetInt(const Index: Integer): Integer;\nbegin\n  Result := Integer(GetLong(Index));\nend;\n\n{**\n   Return Long field value\n   @param Index the field index\n   @return the field Long value\n}\nfunction TZResultSQLDA.GetLong(const Index: Integer): Int64;\nvar\n  SQLCode: SmallInt;\nbegin\n  CheckRange(Index);\n  {$R-}\n  with FXSQLDA.sqlvar[Index] do\n  begin\n    Result := 0;\n    if (sqlind <> nil) and (sqlind^ = -1) then\n         Exit;\n    SQLCode := (sqltype and not(1));\n\n    if (sqlscale < 0)  then\n    begin\n      case SQLCode of\n        SQL_SHORT  : Result := PSmallInt(sqldata)^ div IBScaleDivisor[sqlscale];\n        SQL_LONG   : Result := PInteger(sqldata)^  div IBScaleDivisor[sqlscale];\n        SQL_INT64,\n        SQL_QUAD   : Result := PInt64(sqldata)^    div IBScaleDivisor[sqlscale];\n        SQL_DOUBLE : Result := Trunc(PDouble(sqldata)^);\n      else\n        raise EZIBConvertError.Create(Format(SErrorConvertionField,\n          [GetFieldAliasName(Index), GetNameSqlType(SQLCode)]));\n      end;\n    end\n    else\n      case SQLCode of\n        SQL_DOUBLE    : Result := Trunc(PDouble(sqldata)^);\n        SQL_LONG      : Result := PInteger(sqldata)^;\n        SQL_D_FLOAT,\n        SQL_FLOAT     : Result := Trunc(PSingle(sqldata)^);\n        SQL_BOOLEAN   : Result := PSmallint(sqldata)^;\n        SQL_SHORT     : Result := PSmallint(sqldata)^;\n        SQL_INT64     : Result := PInt64(sqldata)^;\n        SQL_TEXT      : Result := StrToInt(String(DecodeString(SQL_TEXT, Index)));\n        SQL_VARYING   : Result := StrToInt(String(DecodeString(SQL_VARYING, Index)));\n      else\n        raise EZIBConvertError.Create(Format(SErrorConvertionField,\n          [GetFieldAliasName(Index), GetNameSqlType(SQLCode)]));\n      end;\n  end;\n  {$IFOPT D+}\n{$R+}\n{$ENDIF}\nend;\n\n{**\n   Return PAnsiChar field value\n   @param Index the field index\n   @return the field PAnsiChar value\n}\nfunction TZResultSQLDA.GetPChar(const Index: Integer): PChar;\nvar\n  TempStr: String;\nbegin\n  TempStr := ZDbcString(GetString(Index));\n  Result := PChar(TempStr);\nend;\n\n{**\n   Return Short field value\n   @param Index the field index\n   @return the field Short value\n}\nfunction TZResultSQLDA.GetShort(const Index: Integer): SmallInt;\nvar\n  SQLCode: SmallInt;\nbegin\n  CheckRange(Index);\n  {$R-}\n  with FXSQLDA.sqlvar[Index] do\n  begin\n    Result := 0;\n    if (sqlind <> nil) and (sqlind^ = -1) then\n         Exit;\n    SQLCode := (sqltype and not(1));\n\n    if (sqlscale < 0)  then\n    begin\n      case SQLCode of\n        SQL_SHORT  : Result := PSmallInt(sqldata)^ div IBScaleDivisor[sqlscale];\n        SQL_LONG   : Result := PInteger(sqldata)^  div IBScaleDivisor[sqlscale];\n        SQL_INT64,\n        SQL_QUAD   : Result := PInt64(sqldata)^    div IBScaleDivisor[sqlscale];\n        SQL_DOUBLE : Result := Trunc(PDouble(sqldata)^);\n      else\n        raise EZIBConvertError.Create(Format(SErrorConvertionField,\n          [GetFieldAliasName(Index), GetNameSqlType(SQLCode)]));\n      end;\n    end\n    else\n      case SQLCode of\n        SQL_DOUBLE    : Result := Trunc(PDouble(sqldata)^);\n        SQL_LONG      : Result := PInteger(sqldata)^;\n        SQL_D_FLOAT,\n        SQL_FLOAT     : Result := Trunc(PSingle(sqldata)^);\n        SQL_BOOLEAN   : Result := PSmallint(sqldata)^;\n        SQL_SHORT     : Result := PSmallint(sqldata)^;\n        SQL_INT64     : Result := PInt64(sqldata)^;\n        SQL_TEXT      : Result := StrToInt(String(DecodeString(SQL_TEXT, Index)));\n        SQL_VARYING   : Result := StrToInt(String(DecodeString(SQL_VARYING, Index)));\n      else\n        raise EZIBConvertError.Create(Format(SErrorConvertionField,\n          [GetFieldAliasName(Index), GetNameSqlType(SQLCode)]));\n      end;\n  end;\n  {$IFOPT D+}\n{$R+}\n{$ENDIF}\nend;\n\n{**\n   Return String field value\n   @param Index the field index\n   @return the field String value\n}\nfunction TZResultSQLDA.GetString(const Index: Integer): RawByteString;\nvar\n  SQLCode: SmallInt;\n  TempAnsi: AnsiString;\nbegin\n  CheckRange(Index);\n  Result := '';\n  {$R-}\n  with FXSQLDA.sqlvar[Index] do\n  begin\n    if (sqlind <> nil) and (sqlind^ = -1) then\n         Exit;\n    SQLCode := (sqltype and not(1));\n\n    if (sqlscale < 0)  then\n    begin\n      case SQLCode of\n        SQL_SHORT  : Result := RawByteString(FloatToStr(PSmallInt(sqldata)^ / IBScaleDivisor[sqlscale]));\n        SQL_LONG   : Result := RawByteString(FloatToStr(PInteger(sqldata)^  / IBScaleDivisor[sqlscale]));\n        SQL_INT64,\n        SQL_QUAD   : Result := RawByteString(FloatToStr(PInt64(sqldata)^    / IBScaleDivisor[sqlscale]));\n        SQL_DOUBLE : Result := RawByteString(FloatToStr(PDouble(sqldata)^));\n      else\n        raise EZIBConvertError.Create(Format(SErrorConvertionField,\n          [GetFieldAliasName(Index), GetNameSqlType(SQLCode)]));\n      end;\n    end\n    else\n      case SQLCode of\n        SQL_DOUBLE    : Result := RawByteString(FloatToStr(PDouble(sqldata)^));\n        SQL_LONG      : Result := RawByteString(IntToStr(PInteger(sqldata)^));\n        SQL_D_FLOAT,\n        SQL_FLOAT     : Result := RawByteString(FloatToStr(PSingle(sqldata)^));\n        SQL_BOOLEAN   :\n          if Boolean(PSmallint(sqldata)^) = True then\n            Result := 'YES'\n          else\n            Result := 'NO';\n        SQL_SHORT     : Result := RawByteString(IntToStr(PSmallint(sqldata)^));\n        SQL_INT64     : Result := RawByteString(IntToStr(PInt64(sqldata)^));\n        SQL_TEXT      : DecodeString2(SQL_TEXT, Index, Result);\n        SQL_VARYING   : DecodeString2(SQL_VARYING, Index, Result);\n        SQL_BLOB      : if VarIsEmpty(FDefaults[Index]) then\n                        begin\n                          ReadBlobFromString(Index, TempAnsi);\n                          FDefaults[Index] := TempAnsi;\n                        end\n                        else\n                          Result := {$IFDEF WITH_FPC_STRING_CONVERSATION}AnsiString{$ELSE}RawByteString{$ENDIF}(FDefaults[Index]);\n\n      else\n        raise EZIBConvertError.Create(Format(SErrorConvertionField,\n          [GetFieldAliasName(Index), GetNameSqlType(SQLCode)]));\n      end;\n  end;\n  {$IFOPT D+}\n{$R+}\n{$ENDIF}\nend;\n\n{**\n   Return Time field value\n   @param Index the field index\n   @return the field Time value\n}\nfunction TZResultSQLDA.GetTime(const Index: Integer): TDateTime;\nbegin\n  Result := Frac(GetTimestamp(Index));\nend;\n\n{**\n   Return Timestamp field value\n   @param Index the field index\n   @return the field Timestamp value\n}\nfunction TZResultSQLDA.GetTimestamp(const Index: Integer): TDateTime;\nvar\n  TempDate: TCTimeStructure;\nbegin\n  CheckRange(Index);\n  {$R-}\n  with FXSQLDA.sqlvar[Index] do\n  begin\n    Result := 0;\n    if (sqlind <> nil) and (sqlind^ = -1) then\n         Exit;\n\n    case (sqltype and not(1)) of\n        SQL_TIMESTAMP : begin\n                          FPlainDriver.isc_decode_timestamp(PISC_TIMESTAMP(sqldata), @TempDate);\n                          Result := SysUtils.EncodeDate(TempDate.tm_year + 1900,\n                            TempDate.tm_mon + 1, TempDate.tm_mday) + EncodeTime(TempDate.tm_hour,\n                          TempDate.tm_min, TempDate.tm_sec, Word((PISC_TIMESTAMP(sqldata).timestamp_time mod 10000) div 10));\n                        end;\n        SQL_TYPE_DATE : begin\n                          FPlainDriver.isc_decode_sql_date(PISC_DATE(sqldata), @TempDate);\n                          Result := SysUtils.EncodeDate(Word(TempDate.tm_year + 1900),\n                            Word(TempDate.tm_mon + 1), Word(TempDate.tm_mday));\n                        end;\n        SQL_TYPE_TIME : begin\n                          FPlainDriver.isc_decode_sql_time(PISC_TIME(sqldata), @TempDate);\n                          Result := SysUtils.EncodeTime(Word(TempDate.tm_hour), Word(TempDate.tm_min),\n                            Word(TempDate.tm_sec),  Word((PISC_TIME(sqldata)^ mod 10000) div 10));\n                        end;\n        else\n          Result := Trunc(GetDouble(Index));\n        end;\n  end;\n {$IFOPT D+}\n{$R+}\n{$ENDIF}\nend;\n\n{**\n   Indicate field null\n   @param Index the field index\n   @return true if fied value NULL overwise false\n}\nfunction TZResultSQLDA.IsNull(const Index: Integer): Boolean;\nbegin\n  CheckRange(Index);\n  {$R-}\n  with FXSQLDA.sqlvar[Index] do\n    Result := (sqlind <> nil) and (sqlind^ = ISC_NULL);\n  {$IFOPT D+}\n{$R+}\n{$ENDIF}\nend;\n\n{**\n   Return Interbase QUAD field value\n   @param Index the field index\n   @return the field Interbase QUAD value\n}\nfunction TZResultSQLDA.GetQuad(const Index: Integer): TISC_QUAD;\nbegin\n  CheckRange(Index);\n  {$R-}\n  with FXSQLDA.sqlvar[Index] do\n  if not ((sqlind <> nil) and (sqlind^ = -1)) then\n    case (sqltype and not(1)) of\n      SQL_QUAD, SQL_DOUBLE, SQL_INT64, SQL_BLOB, SQL_ARRAY: result := PISC_QUAD(sqldata)^;\n    else\n      raise EZIBConvertError.Create(SUnsupportedDataType + ' ' + inttostr((sqltype and not(1))));\n    end\n  else\n    raise EZIBConvertError.Create('Invalid State.');\n  {$IFOPT D+}\n{$R+}\n{$ENDIF}\nend;\n\n{**\n   Return Variant field value\n   @param Index the field index\n   @return the field Variant value\n}\nfunction TZResultSQLDA.GetValue(const Index: Word): Variant;\nvar\n  SQLCode: SmallInt;\nbegin\n  CheckRange(Index);\n  with FXSQLDA.sqlvar[Index] do\n  begin\n    VarClear(Result);\n    if (sqlind <> nil) and (sqlind^ = -1) then\n         Exit;\n    SQLCode := (sqltype and not(1));\n\n    if (sqlscale < 0)  then\n    begin\n      case SQLCode of\n        SQL_SHORT  : Result := PSmallInt(sqldata)^ / IBScaleDivisor[sqlscale];\n        SQL_LONG   : Result := PInteger(sqldata)^  / IBScaleDivisor[sqlscale];\n        SQL_INT64,\n        SQL_QUAD   : Result := PInt64(sqldata)^    / IBScaleDivisor[sqlscale];\n        SQL_DOUBLE : Result := PDouble(sqldata)^;\n      else\n        raise EZIBConvertError.Create(Format(SErrorConvertionField,\n          [GetFieldAliasName(Index), GetNameSqlType(SQLCode)]));\n      end;\n    end\n    else\n      case SQLCode of\n        SQL_DOUBLE    : Result := PDouble(sqldata)^;\n        SQL_TIMESTAMP : Result := GetTimestamp(Index);\n        SQL_TYPE_DATE : Result := GetDate(Index);\n        SQL_TYPE_TIME : Result := GetTime(Index);\n        SQL_LONG      : Result := PInteger(sqldata)^;\n        SQL_D_FLOAT,\n        SQL_FLOAT     : Result := PSingle(sqldata)^;\n        SQL_BOOLEAN:\n                     begin\n                       if FPlainDriver.GetProtocol <> 'interbase-7' then\n                         raise EZIBConvertError.Create(SUnsupportedDataType);\n                       Result := IntToStr(PSmallint(sqldata)^);\n                     end;\n        SQL_SHORT     : Result := PSmallint(sqldata)^;\n        SQL_INT64     : Result := PInt64(sqldata)^;\n        SQL_TEXT      : Result := DecodeString(SQL_TEXT, Index);\n        SQL_VARYING   : Result := DecodeString(SQL_VARYING, Index);\n        SQL_BLOB      : if VarIsEmpty(FDefaults[Index]) then\n                        begin\n                          ReadBlobFromVariant(Index, FDefaults[Index]);\n                          Result := FDefaults[Index];\n                        end\n                        else\n                          Result := Double(FDefaults[Index]);\n      else\n        raise EZIBConvertError.Create(Format(SErrorConvertionField,\n          [GetFieldAliasName(Index), GetNameSqlType(SQLCode)]));\n      end;\n  end;\nend;\n\ndestructor TZResultSQLDA.Destroy;\nbegin\n  FreeParamtersValues;\n  FreeMem(FXSQLDA);\n  inherited Destroy;\nend;\n\n{**\n   Read blob data to string\n   @param Index an filed index\n   @param Str destination string\n}\nprocedure TZResultSQLDA.ReadBlobFromString(const Index: Word; var Str: AnsiString);\nvar\n  Size: LongInt;\n  Buffer: Pointer;\nbegin\n  ReadBlobBufer(FPlainDriver, FHandle, FTransactionHandle, GetQuad(Index),\n    Size, Buffer);\n  try\n    SetLength(Str, Size);\n    SetString(Str, PAnsiChar(Buffer), Size);\n  finally\n    FreeMem(Buffer, Size);\n  end;\nend;\n\n{**\n   Read blob data to stream\n   @param Index an filed index\n   @param Stream destination stream object\n}\nprocedure TZResultSQLDA.ReadBlobFromStream(const Index: Word; Stream: TStream);\nvar\n  Size: LongInt;\n  Buffer: Pointer;\nbegin\n  ReadBlobBufer(FPlainDriver, FHandle, FTransactionHandle, GetQuad(Index),\n    Size, Buffer);\n  try\n    Stream.Seek(0, 0);\n    Stream.Write(Buffer^, Size);\n    Stream.Seek(0, 0);\n  finally\n    FreeMem(Buffer, Size);\n  end;\nend;\n\n{**\n   Read blob data to variant value\n   @param Index an filed index\n   @param Value destination variant value\n}\nprocedure TZResultSQLDA.ReadBlobFromVariant(const Index: Word;\n  var Value: Variant);\nvar\n  Size: LongInt;\n  Buffer: Pointer;\n  PData: Pointer;\nbegin\n  ReadBlobBufer(FPlainDriver, FHandle, FTransactionHandle, GetQuad(Index),\n    Size, Buffer);\n  Value := VarArrayCreate([0, Size-1], varByte);\n  PData := VarArrayLock(Value);\n  try\n    move(Buffer^, PData^, Size);\n  finally\n    VarArrayUnlock(Value);\n    FreeMem(Buffer, Size);\n  end;\nend;\n\nprocedure TZResultSQLDA.AllocateSQLDA;\nbegin\n  inherited AllocateSQLDA;\n  SetLength(FDefaults, GetFieldCount);\nend;\n\n\nend.\n\n"
  },
  {
    "path": "lib/zeosdbo/src/dbc/ZDbcIntfs.pas",
    "content": "{*********************************************************}\n{                                                         }\n{                 Zeos Database Objects                   }\n{           Database Connectivity Interfaces              }\n{                                                         }\n{        Originally written by Sergey Seroukhov           }\n{                                                         }\n{*********************************************************}\n\n{@********************************************************}\n{    Copyright (c) 1999-2012 Zeos Development Group       }\n{                                                         }\n{ License Agreement:                                      }\n{                                                         }\n{ This library is distributed in the hope that it will be }\n{ useful, but WITHOUT ANY WARRANTY; without even the      }\n{ implied warranty of MERCHANTABILITY or FITNESS FOR      }\n{ A PARTICULAR PURPOSE.  See the GNU Lesser General       }\n{ Public License for more details.                        }\n{                                                         }\n{ The source code of the ZEOS Libraries and packages are  }\n{ distributed under the Library GNU General Public        }\n{ License (see the file COPYING / COPYING.ZEOS)           }\n{ with the following  modification:                       }\n{ As a special exception, the copyright holders of this   }\n{ library give you permission to link this library with   }\n{ independent modules to produce an executable,           }\n{ regardless of the license terms of these independent    }\n{ modules, and to copy and distribute the resulting       }\n{ executable under terms of your choice, provided that    }\n{ you also meet, for each linked independent module,      }\n{ the terms and conditions of the license of that module. }\n{ An independent module is a module which is not derived  }\n{ from or based on this library. If you modify this       }\n{ library, you may extend this exception to your version  }\n{ of the library, but you are not obligated to do so.     }\n{ If you do not wish to do so, delete this exception      }\n{ statement from your version.                            }\n{                                                         }\n{                                                         }\n{ The project web site is located on:                     }\n{   http://zeos.firmos.at  (FORUM)                        }\n{   http://sourceforge.net/p/zeoslib/tickets/ (BUGTRACKER)}\n{   svn://svn.code.sf.net/p/zeoslib/code-0/trunk (SVN)    }\n{                                                         }\n{   http://www.sourceforge.net/projects/zeoslib.          }\n{                                                         }\n{                                                         }\n{                                 Zeos Development Group. }\n{********************************************************@}\n\nunit ZDbcIntfs;\n\ninterface\n\n{$I ZDbc.inc}\n\nuses\n  Types, Classes, {$IFDEF MSEgui}mclasses, mdb{$ELSE}DB{$ENDIF}, SysUtils,\n  ZClasses, ZCollections, ZCompatibility, ZTokenizer, ZSelectSchema,\n  ZGenericSqlAnalyser, ZDbcLogging, ZVariant, ZPlainDriver, ZURL;\n\nconst\n  { Constants from JDBC DatabaseMetadata }\n  TypeSearchable           = 3;\n  ProcedureReturnsResult   = 2;\n\n// Exceptions\ntype\n\n  {** Abstract SQL exception. }\n  EZSQLThrowable = class(Exception)\n  private\n    FErrorCode: Integer;\n    FStatusCode: String;\n  public\n    constructor Create(const Msg: string);\n    constructor CreateWithCode(const ErrorCode: Integer; const Msg: string);\n    constructor CreateWithStatus(const StatusCode: String; const Msg: string);\n    constructor CreateClone(const E:EZSQLThrowable);\n\n    property ErrorCode: Integer read FErrorCode;\n    property StatusCode: string read FStatuscode; // The \"String\" Errocode // FirmOS\n  end;\n\n  {** Generic SQL exception. }\n  EZSQLException = class(EZSQLThrowable);\n\n  {** Generic SQL warning. }\n  EZSQLWarning = class(EZSQLThrowable);\n\n// Data types\ntype\n  {** Defines supported SQL types. }\n  TZSQLType = (stUnknown, stBoolean, stByte, stShort, stInteger, stLong,\n    stFloat, stDouble, stBigDecimal, stString, stUnicodeString, stBytes,\n    stDate, stTime, stTimestamp, stDataSet, stGUID,\n    stAsciiStream, stUnicodeStream, stBinaryStream);\n\n  {** Defines a transaction isolation level. }\n  TZTransactIsolationLevel = (tiNone, tiReadUncommitted, tiReadCommitted,\n    tiRepeatableRead, tiSerializable);\n\n  {** Defines a resultset fetch direction. }\n  TZFetchDirection = (fdForward, fdReverse, fdUnknown);\n\n  {** Defines a type of result set. }\n  TZResultSetType = (rtForwardOnly, rtScrollInsensitive, rtScrollSensitive);\n\n  {** Defines a result set concurrency type. }\n  TZResultSetConcurrency = (rcReadOnly, rcUpdatable);\n\n  {** Defines a nullable type for the column. }\n  TZColumnNullableType = (ntNoNulls, ntNullable, ntNullableUnknown);\n\n  {** Defines a result type for the procedures. }\n  TZProcedureResultType = (prtUnknown, prtNoResult, prtReturnsResult);\n\n  {** Defines a column type for the procedures. }\n  TZProcedureColumnType = (pctUnknown, pctIn, pctInOut, pctOut, pctReturn,\n    pctResultSet);\n\n  {** Defines a best row identifier. }\n  TZBestRowIdentifier = (brUnknown, brNotPseudo, brPseudo);\n\n  {** Defines a scope best row identifier. }\n  TZScopeBestRowIdentifier = (sbrTemporary, sbrTransaction, sbrSession);\n\n  {** Defines a version column. }\n  TZVersionColumn = (vcUnknown, vcNotPseudo, vcPseudo);\n\n  {**  }\n  TZImportedKey = (ikCascade, ikRestrict, ikSetNull, ikNoAction, ikSetDefault,\n    ikInitiallyDeferred, ikInitiallyImmediate, ikNotDeferrable);\n\n  TZTableIndex = (tiStatistic, tiClustered, tiHashed, tiOther);\n\n  {** Defines a post update mode. }\n  TZPostUpdatesMode = (poColumnsAll, poColumnsChanged);\n\n  {** Defines a locate mode. }\n  TZLocateUpdatesMode = (loWhereAll, loWhereChanged, loWhereKeyOnly);\n\n// Interfaces\ntype\n\n  // Forward declarations\n  IZDriverManager = interface;\n  IZDriver = interface;\n  IZConnection = interface;\n  IZDatabaseMetadata = interface;\n  IZDatabaseInfo = interface;\n  IZStatement = interface;\n  IZPreparedStatement = interface;\n  IZCallableStatement = interface;\n  IZResultSet = interface;\n  IZResultSetMetadata = interface;\n  IZBlob = interface;\n  IZNotification = interface;\n  IZSequence = interface;\n  IZDataSet = interface;\n\n  {** Driver Manager interface. }\n  IZDriverManager = interface(IZInterface)\n    ['{8874B9AA-068A-4C0C-AE75-9DB1EA9E3720}']\n\n    function GetConnection(const Url: string): IZConnection;\n    function GetConnectionWithParams(const Url: string; Info: TStrings): IZConnection;\n    function GetConnectionWithLogin(const Url: string; const User: string;\n      const Password: string): IZConnection;\n\n    function GetDriver(const Url: string): IZDriver;\n    function GetClientVersion(const Url: string): Integer;\n    procedure RegisterDriver(Driver: IZDriver);\n    procedure DeregisterDriver(Driver: IZDriver);\n\n    function GetDrivers: IZCollection;\n\n    function GetLoginTimeout: Integer;\n    procedure SetLoginTimeout(Seconds: Integer);\n\n    procedure AddLoggingListener(Listener: IZLoggingListener);\n    procedure RemoveLoggingListener(Listener: IZLoggingListener);\n\n    procedure LogMessage(Category: TZLoggingCategory; const Protocol: string;\n      const Msg: string);\n    procedure LogError(Category: TZLoggingCategory; const Protocol: string;\n      const Msg: string; ErrorCode: Integer; const Error: string);\n    function ConstructURL(const Protocol, HostName, Database,\n      UserName, Password: String; const Port: Integer;\n      const Properties: TStrings = nil; const LibLocation: String = ''): String;\n    procedure ResolveDatabaseUrl(const Url: string; out HostName: string;\n      out Port: Integer; out Database: string; out UserName: string;\n      out Password: string; ResultInfo: TStrings = nil); overload;\n    procedure ResolveDatabaseUrl(const Url: string; out Database: string); overload;\n  end;\n\n  {** Database Driver interface. }\n  IZDriver = interface(IZInterface)\n    ['{2157710E-FBD8-417C-8541-753B585332E2}']\n\n    function GetSupportedProtocols: TStringDynArray;\n    function GetSupportedClientCodePages(const Url: TZURL;\n      Const {$IFNDEF UNICODE}AutoEncode,{$ENDIF} SupportedsOnly: Boolean;\n      CtrlsCPType: TZControlsCodePage = cCP_UTF16): TStringDynArray;\n    function Connect(const Url: string; Info: TStrings): IZConnection; overload;\n    function Connect(const Url: TZURL): IZConnection; overload;\n    function GetClientVersion(const Url: string): Integer;\n    function AcceptsURL(const Url: string): Boolean;\n    function GetPlainDriver(const Url: TZURL; const InitDriver: Boolean = True): IZPlainDriver;\n\n    function GetPropertyInfo(const Url: string; Info: TStrings): TStrings;\n    function GetMajorVersion: Integer;\n    function GetMinorVersion: Integer;\n    function GetSubVersion: Integer;\n    function GetTokenizer: IZTokenizer;\n    function GetStatementAnalyser: IZStatementAnalyser;\n  end;\n\n  {** Database Connection interface. }\n  IZConnection = interface(IZInterface)\n    ['{8EEBBD1A-56D1-4EC0-B3BD-42B60591457F}']\n\n    function CreateStatement: IZStatement;\n    function PrepareStatement(const SQL: string): IZPreparedStatement;\n    function PrepareCall(const SQL: string): IZCallableStatement;\n\n    function CreateStatementWithParams(Info: TStrings): IZStatement;\n    function PrepareStatementWithParams(const SQL: string; Info: TStrings):\n      IZPreparedStatement;\n    function PrepareCallWithParams(const SQL: string; Info: TStrings):\n      IZCallableStatement;\n\n    function CreateNotification(const Event: string): IZNotification;\n    function CreateSequence(const Sequence: string; BlockSize: Integer): IZSequence;\n\n    function NativeSQL(const SQL: string): string;\n\n    procedure SetAutoCommit(Value: Boolean);\n    function GetAutoCommit: Boolean;\n\n    procedure Commit;\n    procedure Rollback;\n\n    //2Phase Commit Support initially for PostgresSQL (firmos) 21022006\n    procedure PrepareTransaction(const transactionid: string);\n    procedure CommitPrepared(const transactionid: string);\n    procedure RollbackPrepared(const transactionid: string);\n\n\n    //Ping Server Support (firmos) 27032006\n\n    function PingServer: Integer;\n    function EscapeString(Value: RawByteString): RawByteString;\n\n    procedure Open;\n    procedure Close;\n    function IsClosed: Boolean;\n\n    function GetDriver: IZDriver;\n    function GetIZPlainDriver: IZPlainDriver;\n    function GetMetadata: IZDatabaseMetadata;\n    function GetParameters: TStrings;\n    function GetClientVersion: Integer;\n    function GetHostVersion: Integer;\n\n    procedure SetReadOnly(Value: Boolean);\n    function IsReadOnly: Boolean;\n\n    procedure SetCatalog(const Value: string);\n    function GetCatalog: string;\n\n    procedure SetTransactionIsolation(Value: TZTransactIsolationLevel);\n    function GetTransactionIsolation: TZTransactIsolationLevel;\n\n    function GetWarnings: EZSQLWarning;\n    procedure ClearWarnings;\n\n    function UseMetadata: boolean;\n    procedure SetUseMetadata(Value: Boolean);\n    //EgonHugeist\n    function GetBinaryEscapeString(const Value: RawByteString): String; overload;\n    function GetBinaryEscapeString(const Value: TByteDynArray): String; overload;\n    function GetEscapeString(const Value: ZWideString): ZWideString; overload;\n    function GetEscapeString(const Value: RawByteString): RawByteString; overload;\n    function GetClientCodePageInformations: PZCodePage;\n    function GetAutoEncodeStrings: Boolean;\n    procedure SetAutoEncodeStrings(const Value: Boolean);\n    property AutoEncodeStrings: Boolean read GetAutoEncodeStrings write SetAutoEncodeStrings;\n    function GetEncoding: TZCharEncoding;\n    function GetConSettings: PZConSettings;\n\n    {$IFDEF ZEOS_TEST_ONLY}\n    function GetTestMode : Byte;\n    procedure SetTestMode(Mode: Byte);\n    {$ENDIF}\n  end;\n\n  {** Database metadata interface. }\n  IZDatabaseMetadata = interface(IZInterface)\n    ['{FE331C2D-0664-464E-A981-B4F65B85D1A8}']\n\n    function GetURL: string;\n    function GetUserName: string;\n\n    function GetDatabaseInfo: IZDatabaseInfo;\n    function GetTriggers(const Catalog: string; const SchemaPattern: string;\n      const TableNamePattern: string; const TriggerNamePattern: string): IZResultSet; //EgonHugeist 30.03.2011\n    function GetCollationAndCharSet(const Catalog, Schema, TableName, ColumnName: String): IZResultSet; //EgonHugeist 10.01.2012\n    function GetCharacterSets: IZResultSet; //EgonHugeist 19.01.2012\n    function GetProcedures(const Catalog: string; const SchemaPattern: string;\n      const ProcedureNamePattern: string): IZResultSet;\n    function GetProcedureColumns(const Catalog: string; const SchemaPattern: string;\n      const ProcedureNamePattern: string; const ColumnNamePattern: string): IZResultSet;\n\n    function GetTables(const Catalog: string; const SchemaPattern: string;\n      const TableNamePattern: string; const Types: TStringDynArray): IZResultSet;\n    function GetSchemas: IZResultSet;\n    function GetCatalogs: IZResultSet;\n    function GetTableTypes: IZResultSet;\n    function GetColumns(const Catalog: string; const SchemaPattern: string;\n      const TableNamePattern: string; const ColumnNamePattern: string): IZResultSet;\n    function GetColumnPrivileges(const Catalog: string; const Schema: string;\n      const Table: string; const ColumnNamePattern: string): IZResultSet;\n\n    function GetTablePrivileges(const Catalog: string; const SchemaPattern: string;\n      const TableNamePattern: string): IZResultSet;\n    function GetBestRowIdentifier(const Catalog: string; const Schema: string;\n      const Table: string; Scope: Integer; Nullable: Boolean): IZResultSet;\n    function GetVersionColumns(const Catalog: string; const Schema: string;\n      const Table: string): IZResultSet;\n\n    function GetPrimaryKeys(const Catalog: string; const Schema: string;\n      const Table: string): IZResultSet;\n    function GetImportedKeys(const Catalog: string; const Schema: string;\n      const Table: string): IZResultSet;\n    function GetExportedKeys(const Catalog: string; const Schema: string;\n      const Table: string): IZResultSet;\n    function GetCrossReference(const PrimaryCatalog: string; const PrimarySchema: string;\n      const PrimaryTable: string; const ForeignCatalog: string; const ForeignSchema: string;\n      const ForeignTable: string): IZResultSet;\n\n    function GetTypeInfo: IZResultSet;\n\n    function GetIndexInfo(const Catalog: string; const Schema: string; const Table: string;\n      Unique: Boolean; Approximate: Boolean): IZResultSet;\n\n    function GetSequences(const Catalog: string; const SchemaPattern: string;\n      const SequenceNamePattern: string): IZResultSet;\n\n    function GetUDTs(const Catalog: string; const SchemaPattern: string;\n      const TypeNamePattern: string; const Types: TIntegerDynArray): IZResultSet;\n\n    function GetConnection: IZConnection;\n    function GetIdentifierConvertor: IZIdentifierConvertor;\n\n    procedure ClearCache;overload;\n\t\tprocedure ClearCache(const Key: string);overload;\n\n    function AddEscapeCharToWildcards(const Pattern:string): string;\n    function NormalizePatternCase(Pattern:String): string;\n  end;\n\n  {**\n    Database information interface. Used to describe the database as a whole\n    (version, capabilities, policies, etc).\n  } // technobot 2008-06-24\n  IZDatabaseInfo = interface(IZInterface)\n    ['{107CA354-F594-48F9-8E08-CD797F151EA0}']\n\n    // database/driver/server info:\n    function GetDatabaseProductName: string;\n    function GetDatabaseProductVersion: string;\n    function GetDriverName: string;\n    function GetDriverVersion: string;\n    function GetDriverMajorVersion: Integer;\n    function GetDriverMinorVersion: Integer;\n    function GetServerVersion: string;\n\n    // capabilities (what it can/cannot do):\n    function AllProceduresAreCallable: Boolean;\n    function AllTablesAreSelectable: Boolean;\n    function SupportsMixedCaseIdentifiers: Boolean;\n    function SupportsMixedCaseQuotedIdentifiers: Boolean;\n    function SupportsAlterTableWithAddColumn: Boolean;\n    function SupportsAlterTableWithDropColumn: Boolean;\n    function SupportsColumnAliasing: Boolean;\n    function SupportsConvert: Boolean;\n    function SupportsConvertForTypes(FromType: TZSQLType; ToType: TZSQLType):\n      Boolean;\n    function SupportsTableCorrelationNames: Boolean;\n    function SupportsDifferentTableCorrelationNames: Boolean;\n    function SupportsExpressionsInOrderBy: Boolean;\n    function SupportsOrderByUnrelated: Boolean;\n    function SupportsGroupBy: Boolean;\n    function SupportsGroupByUnrelated: Boolean;\n    function SupportsGroupByBeyondSelect: Boolean;\n    function SupportsLikeEscapeClause: Boolean;\n    function SupportsMultipleResultSets: Boolean;\n    function SupportsMultipleTransactions: Boolean;\n    function SupportsNonNullableColumns: Boolean;\n    function SupportsMinimumSQLGrammar: Boolean;\n    function SupportsCoreSQLGrammar: Boolean;\n    function SupportsExtendedSQLGrammar: Boolean;\n    function SupportsANSI92EntryLevelSQL: Boolean;\n    function SupportsANSI92IntermediateSQL: Boolean;\n    function SupportsANSI92FullSQL: Boolean;\n    function SupportsIntegrityEnhancementFacility: Boolean;\n    function SupportsOuterJoins: Boolean;\n    function SupportsFullOuterJoins: Boolean;\n    function SupportsLimitedOuterJoins: Boolean;\n    function SupportsSchemasInDataManipulation: Boolean;\n    function SupportsSchemasInProcedureCalls: Boolean;\n    function SupportsSchemasInTableDefinitions: Boolean;\n    function SupportsSchemasInIndexDefinitions: Boolean;\n    function SupportsSchemasInPrivilegeDefinitions: Boolean;\n    function SupportsCatalogsInDataManipulation: Boolean;\n    function SupportsCatalogsInProcedureCalls: Boolean;\n    function SupportsCatalogsInTableDefinitions: Boolean;\n    function SupportsCatalogsInIndexDefinitions: Boolean;\n    function SupportsCatalogsInPrivilegeDefinitions: Boolean;\n    function SupportsOverloadPrefixInStoredProcedureName: Boolean;\n    function SupportsPositionedDelete: Boolean;\n    function SupportsPositionedUpdate: Boolean;\n    function SupportsSelectForUpdate: Boolean;\n    function SupportsStoredProcedures: Boolean;\n    function SupportsSubqueriesInComparisons: Boolean;\n    function SupportsSubqueriesInExists: Boolean;\n    function SupportsSubqueriesInIns: Boolean;\n    function SupportsSubqueriesInQuantifieds: Boolean;\n    function SupportsCorrelatedSubqueries: Boolean;\n    function SupportsUnion: Boolean;\n    function SupportsUnionAll: Boolean;\n    function SupportsOpenCursorsAcrossCommit: Boolean;\n    function SupportsOpenCursorsAcrossRollback: Boolean;\n    function SupportsOpenStatementsAcrossCommit: Boolean;\n    function SupportsOpenStatementsAcrossRollback: Boolean;\n    function SupportsTransactions: Boolean;\n    function SupportsTransactionIsolationLevel(Level: TZTransactIsolationLevel):\n      Boolean;\n    function SupportsDataDefinitionAndDataManipulationTransactions: Boolean;\n    function SupportsDataManipulationTransactionsOnly: Boolean;\n    function SupportsResultSetType(_Type: TZResultSetType): Boolean;\n    function SupportsResultSetConcurrency(_Type: TZResultSetType;\n      Concurrency: TZResultSetConcurrency): Boolean;\n    function SupportsBatchUpdates: Boolean;\n    function SupportsNonEscapedSearchStrings: Boolean;\n    function SupportsUpdateAutoIncrementFields: Boolean;\n\n    // maxima:\n    function GetMaxBinaryLiteralLength: Integer;\n    function GetMaxCharLiteralLength: Integer;\n    function GetMaxColumnNameLength: Integer;\n    function GetMaxColumnsInGroupBy: Integer;\n    function GetMaxColumnsInIndex: Integer;\n    function GetMaxColumnsInOrderBy: Integer;\n    function GetMaxColumnsInSelect: Integer;\n    function GetMaxColumnsInTable: Integer;\n    function GetMaxConnections: Integer;\n    function GetMaxCursorNameLength: Integer;\n    function GetMaxIndexLength: Integer;\n    function GetMaxSchemaNameLength: Integer;\n    function GetMaxProcedureNameLength: Integer;\n    function GetMaxCatalogNameLength: Integer;\n    function GetMaxRowSize: Integer;\n    function GetMaxStatementLength: Integer;\n    function GetMaxStatements: Integer;\n    function GetMaxTableNameLength: Integer;\n    function GetMaxTablesInSelect: Integer;\n    function GetMaxUserNameLength: Integer;\n\n    // policies (how are various data and operations handled):\n    function IsReadOnly: Boolean;\n    function IsCatalogAtStart: Boolean;\n    function DoesMaxRowSizeIncludeBlobs: Boolean;\n    function NullsAreSortedHigh: Boolean;\n    function NullsAreSortedLow: Boolean;\n    function NullsAreSortedAtStart: Boolean;\n    function NullsAreSortedAtEnd: Boolean;\n    function NullPlusNonNullIsNull: Boolean;\n    function UsesLocalFiles: Boolean;\n    function UsesLocalFilePerTable: Boolean;\n    function StoresUpperCaseIdentifiers: Boolean;\n    function StoresLowerCaseIdentifiers: Boolean;\n    function StoresMixedCaseIdentifiers: Boolean;\n    function StoresUpperCaseQuotedIdentifiers: Boolean;\n    function StoresLowerCaseQuotedIdentifiers: Boolean;\n    function StoresMixedCaseQuotedIdentifiers: Boolean;\n    function GetDefaultTransactionIsolation: TZTransactIsolationLevel;\n    function DataDefinitionCausesTransactionCommit: Boolean;\n    function DataDefinitionIgnoredInTransactions: Boolean;\n\n    // interface details (terms, keywords, etc):\n    function GetIdentifierQuoteString: string;\n    function GetSchemaTerm: string;\n    function GetProcedureTerm: string;\n    function GetCatalogTerm: string;\n    function GetCatalogSeparator: string;\n    function GetSQLKeywords: string;\n    function GetNumericFunctions: string;\n    function GetStringFunctions: string;\n    function GetSystemFunctions: string;\n    function GetTimeDateFunctions: string;\n    function GetSearchStringEscape: string;\n    function GetExtraNameCharacters: string;\n  end;\n\n  {** Generic SQL statement interface. }\n  IZStatement = interface(IZInterface)\n    ['{22CEFA7E-6A6D-48EC-BB9B-EE66056E90F1}']\n\n    function ExecuteQuery(const SQL: ZWideString): IZResultSet; overload;\n    function ExecuteUpdate(const SQL: ZWideString): Integer; overload;\n    function Execute(const SQL: ZWideString): Boolean; overload;\n    function ExecuteQuery(const SQL: RawByteString): IZResultSet; overload;\n    function ExecuteUpdate(const SQL: RawByteString): Integer; overload;\n    function Execute(const SQL: RawByteString): Boolean; overload;\n    procedure Close;\n\n    function GetMaxFieldSize: Integer;\n    procedure SetMaxFieldSize(Value: Integer);\n    function GetMaxRows: Integer;\n    procedure SetMaxRows(Value: Integer);\n    procedure SetEscapeProcessing(Value: Boolean);\n    function GetQueryTimeout: Integer;\n    procedure SetQueryTimeout(Value: Integer);\n    procedure Cancel;\n    procedure SetCursorName(const Value: AnsiString);\n\n    function GetResultSet: IZResultSet;\n    function GetUpdateCount: Integer;\n    function GetMoreResults: Boolean;\n\n    procedure SetFetchDirection(Value: TZFetchDirection);\n    function GetFetchDirection: TZFetchDirection;\n    procedure SetFetchSize(Value: Integer);\n    function GetFetchSize: Integer;\n\n    procedure SetResultSetConcurrency(Value: TZResultSetConcurrency);\n    function GetResultSetConcurrency: TZResultSetConcurrency;\n    procedure SetResultSetType(Value: TZResultSetType);\n    function GetResultSetType: TZResultSetType;\n\n    procedure SetPostUpdates(Value: TZPostUpdatesMode);\n    function GetPostUpdates: TZPostUpdatesMode;\n    procedure SetLocateUpdates(Value: TZLocateUpdatesMode);\n    function GetLocateUpdates: TZLocateUpdatesMode;\n\n    procedure AddBatch(const SQL: string);\n    procedure ClearBatch;\n    function ExecuteBatch: TIntegerDynArray;\n\n    function GetConnection: IZConnection;\n    function GetParameters: TStrings;\n    function GetChunkSize: Integer;\n\n    function GetWarnings: EZSQLWarning;\n    procedure ClearWarnings;\n\n    function GetEncodedSQL(const SQL: {$IF defined(FPC) and defined(WITH_RAWBYTESTRING)}RawByteString{$ELSE}String{$IFEND}): RawByteString;\n  end;\n\n  {** Prepared SQL statement interface. }\n  IZPreparedStatement = interface(IZStatement)\n    ['{990B8477-AF11-4090-8821-5B7AFEA9DD70}']\n\n    function ExecuteQueryPrepared: IZResultSet;\n    function ExecuteUpdatePrepared: Integer;\n    function ExecutePrepared: Boolean;\n\n    function GetSQL : String;\n//    procedure Prepare;\n//    procedure Unprepare;\n//    function IsPrepared: Boolean;\n\n    procedure SetDefaultValue(ParameterIndex: Integer; const Value: string);\n\n    procedure SetNull(ParameterIndex: Integer; SQLType: TZSQLType);\n    procedure SetBoolean(ParameterIndex: Integer; Value: Boolean);\n    procedure SetByte(ParameterIndex: Integer; Value: Byte);\n    procedure SetShort(ParameterIndex: Integer; Value: SmallInt);\n    procedure SetInt(ParameterIndex: Integer; Value: Integer);\n    procedure SetLong(ParameterIndex: Integer; Value: Int64);\n    procedure SetFloat(ParameterIndex: Integer; Value: Single);\n    procedure SetDouble(ParameterIndex: Integer; Value: Double);\n    procedure SetBigDecimal(ParameterIndex: Integer; Value: Extended);\n    procedure SetPChar(ParameterIndex: Integer; Value: PChar);\n    procedure SetString(ParameterIndex: Integer; const Value: String);\n    procedure SetUnicodeString(ParameterIndex: Integer; const Value: ZWideString); //AVZ\n    procedure SetBytes(ParameterIndex: Integer; const Value: TByteDynArray);\n    procedure SetDate(ParameterIndex: Integer; Value: TDateTime);\n    procedure SetTime(ParameterIndex: Integer; Value: TDateTime);\n    procedure SetTimestamp(ParameterIndex: Integer; Value: TDateTime);\n    procedure SetAsciiStream(ParameterIndex: Integer; Value: TStream);\n    procedure SetUnicodeStream(ParameterIndex: Integer; Value: TStream);\n    procedure SetBinaryStream(ParameterIndex: Integer; Value: TStream);\n    procedure SetBlob(ParameterIndex: Integer; SQLType: TZSQLType;\n      Value: IZBlob);\n    procedure SetValue(ParameterIndex: Integer; const Value: TZVariant);\n\n    procedure ClearParameters;\n\n    procedure AddBatchPrepared;\n    function GetMetadata: IZResultSetMetadata;\n  end;\n\n  {** Callable SQL statement interface. }\n  IZCallableStatement = interface(IZPreparedStatement)\n    ['{E6FA6C18-C764-4C05-8FCB-0582BDD1EF40}']\n    function IsFunction: Boolean;\n    { Multiple ResultSet support API }\n    function HasMoreResultSets: Boolean;\n    function GetFirstResultSet: IZResultSet;\n    function GetPreviousResultSet: IZResultSet;\n    function GetNextResultSet: IZResultSet;\n    function GetLastResultSet: IZResultSet;\n    function BOR: Boolean;\n    function EOR: Boolean;\n    function GetResultSetByIndex(const Index: Integer): IZResultSet;\n    function GetResultSetCount: Integer;\n\n    procedure RegisterOutParameter(ParameterIndex: Integer; SQLType: Integer);\n    procedure RegisterParamType(ParameterIndex:integer;ParamType:Integer);\n    function WasNull: Boolean;\n\n    function IsNull(ParameterIndex: Integer): Boolean;\n    function GetPChar(ParameterIndex: Integer): PChar;\n    function GetString(ParameterIndex: Integer): String;\n    function GetUnicodeString(ParameterIndex: Integer): WideString;\n    function GetBoolean(ParameterIndex: Integer): Boolean;\n    function GetByte(ParameterIndex: Integer): Byte;\n    function GetShort(ParameterIndex: Integer): SmallInt;\n    function GetInt(ParameterIndex: Integer): Integer;\n    function GetLong(ParameterIndex: Integer): Int64;\n    function GetFloat(ParameterIndex: Integer): Single;\n    function GetDouble(ParameterIndex: Integer): Double;\n    function GetBigDecimal(ParameterIndex: Integer): Extended;\n    function GetBytes(ParameterIndex: Integer): TByteDynArray;\n    function GetDate(ParameterIndex: Integer): TDateTime;\n    function GetTime(ParameterIndex: Integer): TDateTime;\n    function GetTimestamp(ParameterIndex: Integer): TDateTime;\n    function GetValue(ParameterIndex: Integer): TZVariant;\n  end;\n\n  IZParamNamedCallableStatement = interface(IZCallableStatement)\n    ['{99882891-81B2-4F3E-A3D7-35B6DCAA7136}']\n    procedure RegisterParamTypeAndName(const ParameterIndex:integer;\n      const ParamTypeName, ParamName: String; Const ColumnSize, Precision: Integer);\n  end;\n\n  {** Rows returned by SQL query. }\n  IZResultSet = interface(IZInterface)\n    ['{8F4C4D10-2425-409E-96A9-7142007CC1B2}']\n\n    function Next: Boolean;\n    procedure Close;\n    function WasNull: Boolean;\n\n    //======================================================================\n    // Methods for accessing results by column index\n    //======================================================================\n\n    function IsNull(ColumnIndex: Integer): Boolean;\n    function GetPChar(ColumnIndex: Integer): PChar;\n    function GetString(ColumnIndex: Integer): String;\n    function GetBinaryString(ColumnIndex: Integer): RawByteString;\n    function GetUnicodeString(ColumnIndex: Integer): WideString;\n    function GetBoolean(ColumnIndex: Integer): Boolean;\n    function GetByte(ColumnIndex: Integer): Byte;\n    function GetShort(ColumnIndex: Integer): SmallInt;\n    function GetInt(ColumnIndex: Integer): Integer;\n    function GetLong(ColumnIndex: Integer): Int64;\n    function GetFloat(ColumnIndex: Integer): Single;\n    function GetDouble(ColumnIndex: Integer): Double;\n    function GetBigDecimal(ColumnIndex: Integer): Extended;\n    function GetBytes(ColumnIndex: Integer): TByteDynArray;\n    function GetDate(ColumnIndex: Integer): TDateTime;\n    function GetTime(ColumnIndex: Integer): TDateTime;\n    function GetTimestamp(ColumnIndex: Integer): TDateTime;\n    function GetAsciiStream(ColumnIndex: Integer): TStream;\n    function GetUnicodeStream(ColumnIndex: Integer): TStream;\n    function GetBinaryStream(ColumnIndex: Integer): TStream;\n    function GetBlob(ColumnIndex: Integer): IZBlob;\n    function GetDataSet(ColumnIndex: Integer): IZDataSet;\n    function GetValue(ColumnIndex: Integer): TZVariant;\n    function GetDefaultExpression(ColumnIndex: Integer): string;\n\n    //======================================================================\n    // Methods for accessing results by column name\n    //======================================================================\n\n    function IsNullByName(const ColumnName: string): Boolean;\n    function GetPCharByName(const ColumnName: string): PChar;\n    function GetStringByName(const ColumnName: string): String;\n    function GetBinaryStringByName(const ColumnName: string): RawByteString;\n    function GetUnicodeStringByName(const ColumnName: string): WideString;\n    function GetBooleanByName(const ColumnName: string): Boolean;\n    function GetByteByName(const ColumnName: string): Byte;\n    function GetShortByName(const ColumnName: string): SmallInt;\n    function GetIntByName(const ColumnName: string): Integer;\n    function GetLongByName(const ColumnName: string): Int64;\n    function GetFloatByName(const ColumnName: string): Single;\n    function GetDoubleByName(const ColumnName: string): Double;\n    function GetBigDecimalByName(const ColumnName: string): Extended;\n    function GetBytesByName(const ColumnName: string): TByteDynArray;\n    function GetDateByName(const ColumnName: string): TDateTime;\n    function GetTimeByName(const ColumnName: string): TDateTime;\n    function GetTimestampByName(const ColumnName: string): TDateTime;\n    function GetAsciiStreamByName(const ColumnName: string): TStream;\n    function GetUnicodeStreamByName(const ColumnName: string): TStream;\n    function GetBinaryStreamByName(const ColumnName: string): TStream;\n    function GetBlobByName(const ColumnName: string): IZBlob;\n    function GetDataSetByName(const ColumnName: String): IZDataSet;\n    function GetValueByName(const ColumnName: string): TZVariant;\n\n    //=====================================================================\n    // Advanced features:\n    //=====================================================================\n\n    function GetWarnings: EZSQLWarning;\n    procedure ClearWarnings;\n\n    function GetCursorName: AnsiString;\n    function GetMetadata: IZResultSetMetadata;\n    function FindColumn(const ColumnName: string): Integer;\n\n    //---------------------------------------------------------------------\n    // Traversal/Positioning\n    //---------------------------------------------------------------------\n\n    function IsBeforeFirst: Boolean;\n    function IsAfterLast: Boolean;\n    function IsFirst: Boolean;\n    function IsLast: Boolean;\n    procedure BeforeFirst;\n    procedure AfterLast;\n    function First: Boolean;\n    function Last: Boolean;\n    function GetRow: Integer;\n    function MoveAbsolute(Row: Integer): Boolean;\n    function MoveRelative(Rows: Integer): Boolean;\n    function Previous: Boolean;\n\n    //---------------------------------------------------------------------\n    // Properties\n    //---------------------------------------------------------------------\n\n    procedure SetFetchDirection(Value: TZFetchDirection);\n    function GetFetchDirection: TZFetchDirection;\n\n    procedure SetFetchSize(Value: Integer);\n    function GetFetchSize: Integer;\n\n    function GetType: TZResultSetType;\n    function GetConcurrency: TZResultSetConcurrency;\n\n    function GetPostUpdates: TZPostUpdatesMode;\n    function GetLocateUpdates: TZLocateUpdatesMode;\n\n    //---------------------------------------------------------------------\n    // Updates\n    //---------------------------------------------------------------------\n\n    function RowUpdated: Boolean;\n    function RowInserted: Boolean;\n    function RowDeleted: Boolean;\n\n    procedure UpdateNull(ColumnIndex: Integer);\n    procedure UpdateBoolean(ColumnIndex: Integer; Value: Boolean);\n    procedure UpdateByte(ColumnIndex: Integer; Value: ShortInt);\n    procedure UpdateShort(ColumnIndex: Integer; Value: SmallInt);\n    procedure UpdateInt(ColumnIndex: Integer; Value: Integer);\n    procedure UpdateLong(ColumnIndex: Integer; Value: Int64);\n    procedure UpdateFloat(ColumnIndex: Integer; Value: Single);\n    procedure UpdateDouble(ColumnIndex: Integer; Value: Double);\n    procedure UpdateBigDecimal(ColumnIndex: Integer; Value: Extended);\n    procedure UpdatePChar(ColumnIndex: Integer; Value: PChar);\n    procedure UpdateString(ColumnIndex: Integer; const Value: String);\n    procedure UpdateBinaryString(ColumnIndex: Integer; const Value: RawByteString);\n    procedure UpdateUnicodeString(ColumnIndex: Integer; const Value: WideString);\n    procedure UpdateBytes(ColumnIndex: Integer; const Value: TByteDynArray);\n    procedure UpdateDate(ColumnIndex: Integer; Value: TDateTime);\n    procedure UpdateTime(ColumnIndex: Integer; Value: TDateTime);\n    procedure UpdateTimestamp(ColumnIndex: Integer; Value: TDateTime);\n    procedure UpdateAsciiStream(ColumnIndex: Integer; Value: TStream);\n    procedure UpdateUnicodeStream(ColumnIndex: Integer; Value: TStream);\n    procedure UpdateBinaryStream(ColumnIndex: Integer; Value: TStream);\n    procedure UpdateDataSet(ColumnIndex: Integer; Value: IZDataSet);\n    procedure UpdateValue(ColumnIndex: Integer; const Value: TZVariant);\n    procedure UpdateDefaultExpression(ColumnIndex: Integer; const Value: string);\n\n    //======================================================================\n    // Methods for accessing results by column name\n    //======================================================================\n\n    procedure UpdateNullByName(const ColumnName: string);\n    procedure UpdateBooleanByName(const ColumnName: string; Value: Boolean);\n    procedure UpdateByteByName(const ColumnName: string; Value: ShortInt);\n    procedure UpdateShortByName(const ColumnName: string; Value: SmallInt);\n    procedure UpdateIntByName(const ColumnName: string; Value: Integer);\n    procedure UpdateLongByName(const ColumnName: string; Value: Int64);\n    procedure UpdateFloatByName(const ColumnName: string; Value: Single);\n    procedure UpdateDoubleByName(const ColumnName: string; Value: Double);\n    procedure UpdateBigDecimalByName(const ColumnName: string; Value: Extended);\n    procedure UpdatePCharByName(const ColumnName: string; Value: PChar);\n    procedure UpdateStringByName(const ColumnName: string; const Value: String);\n    procedure UpdateBinaryStringByName(const ColumnName: string; const Value: RawByteString);\n    procedure UpdateUnicodeStringByName(const ColumnName: string; const Value: WideString);\n    procedure UpdateBytesByName(const ColumnName: string; const Value: TByteDynArray);\n    procedure UpdateDateByName(const ColumnName: string; Value: TDateTime);\n    procedure UpdateTimeByName(const ColumnName: string; Value: TDateTime);\n    procedure UpdateTimestampByName(const ColumnName: string; Value: TDateTime);\n    procedure UpdateAsciiStreamByName(const ColumnName: string; Value: TStream);\n    procedure UpdateUnicodeStreamByName(const ColumnName: string; Value: TStream);\n    procedure UpdateBinaryStreamByName(const ColumnName: string; Value: TStream);\n    procedure UpdateDataSetByName(const ColumnName: string; Value: IZDataSet);\n    procedure UpdateValueByName(const ColumnName: string; const Value: TZVariant);\n\n    procedure InsertRow;\n    procedure UpdateRow;\n    procedure DeleteRow;\n    procedure RefreshRow;\n    procedure CancelRowUpdates;\n    procedure MoveToInsertRow;\n    procedure MoveToCurrentRow;\n//    procedure MoveToSearchRow;\n\n//    function Search(CaseInsensitive, PartialKey: Boolean): Boolean;\n//    function Compare(Row: Integer; CaseInsensitive, PartialKey: Boolean):\n//      Boolean;\n\n    function CompareRows(Row1, Row2: Integer; const ColumnIndices: TIntegerDynArray;\n      const ColumnDirs: TBooleanDynArray): Integer;\n\n    function GetStatement: IZStatement;\n    function GetConSettings: PZConsettings;\n  end;\n\n  {** TDataSet interface}\n  IZDataSet = interface(IZInterface)\n    ['{DBC24011-EF26-4FD8-AC8B-C3E01619494A}']\n    function GetDataSet: TDataSet;\n    function IsEmpty: Boolean;\n  end;\n\n  {** ResultSet metadata interface. }\n  IZResultSetMetadata = interface(IZInterface)\n    ['{47CA2144-2EA7-42C4-8444-F5154369B2D7}']\n\n    function GetColumnCount: Integer;\n    function IsAutoIncrement(Column: Integer): Boolean;\n    function IsCaseSensitive(Column: Integer): Boolean;\n    function IsSearchable(Column: Integer): Boolean;\n    function IsCurrency(Column: Integer): Boolean;\n    function IsNullable(Column: Integer): TZColumnNullableType;\n\n    function IsSigned(Column: Integer): Boolean;\n    function GetColumnDisplaySize(Column: Integer): Integer;\n    function GetColumnLabel(Column: Integer): string;\n    function GetColumnName(Column: Integer): string;\n    function GetSchemaName(Column: Integer): string;\n    function GetPrecision(Column: Integer): Integer;\n    function GetScale(Column: Integer): Integer;\n    function GetTableName(Column: Integer): string;\n    function GetCatalogName(Column: Integer): string;\n    function GetColumnType(Column: Integer): TZSQLType;\n    function GetColumnTypeName(Column: Integer): string;\n    function IsReadOnly(Column: Integer): Boolean;\n    function IsWritable(Column: Integer): Boolean;\n    function IsDefinitelyWritable(Column: Integer): Boolean;\n    function GetDefaultValue(Column: Integer): string;\n    function HasDefaultValue(Column: Integer): Boolean;\n  end;\n\n  {** External or internal blob wrapper object. }\n  IZBlob = interface(IZInterface)\n    ['{47D209F1-D065-49DD-A156-EFD1E523F6BF}']\n\n    function IsEmpty: Boolean;\n    function IsUpdated: Boolean;\n    function Length: LongInt;\n    function WasDecoded: Boolean;\n    function Connection: IZConnection;\n\n    function GetString: RawByteString;\n    procedure SetString(const Value: RawByteString);\n    function GetUnicodeString: WideString;\n    procedure SetUnicodeString(const Value: WideString);\n    function GetBytes: TByteDynArray;\n    procedure SetBytes(const Value: TByteDynArray);\n    function GetUnicodeStream: TStream;\n    function GetStream: TStream;\n    procedure SetStream(Value: TStream; Encoded: Boolean = False);\n    function GetBuffer: Pointer;\n    procedure SetBuffer(Buffer: Pointer; Length: Integer);\n\n    procedure Clear;\n    function Clone: IZBlob;\n  end;\n\n  {** Database notification interface. }\n  IZNotification = interface(IZInterface)\n    ['{BF785C71-EBE9-4145-8DAE-40674E45EF6F}']\n\n    function GetEvent: string;\n    procedure Listen;\n    procedure Unlisten;\n    procedure DoNotify;\n    function CheckEvents: string;\n\n    function GetConnection: IZConnection;\n  end;\n\n  {** Database sequence generator interface. }\n  IZSequence = interface(IZInterface)\n    ['{A9A54FE5-0DBE-492F-8DA6-04AC5FCE779C}']\n    function  GetName: string;\n    function  GetBlockSize: Integer;\n    procedure SetName(const Value: string);\n    procedure SetBlockSize(const Value: Integer);\n    function  GetCurrentValue: Int64;\n    function  GetNextValue: Int64;\n    function  GetCurrentValueSQL: string;\n    function  GetNextValueSQL: string;\n    function  GetConnection: IZConnection;\n  end;\n\nvar\n  {** The common driver manager object. }\n  DriverManager: IZDriverManager;\n\nimplementation\n\nuses ZMessages;\n\ntype\n  {** Driver Manager interface. }\n  TZDriverManager = class(TInterfacedObject, IZDriverManager)\n  private\n    FDrivers: IZCollection;\n    FLoginTimeout: Integer;\n    FLoggingListeners: IZCollection;\n    FURL: TZURL;\n  public\n    constructor Create;\n    destructor Destroy; override;\n\n    function GetConnection(const Url: string): IZConnection;\n    function GetConnectionWithParams(const Url: string; Info: TStrings): IZConnection;\n    function GetConnectionWithLogin(const Url: string; const User: string;\n      const Password: string): IZConnection;\n\n    function GetDriver(const Url: string): IZDriver;\n    procedure RegisterDriver(Driver: IZDriver);\n    procedure DeregisterDriver(Driver: IZDriver);\n\n    function GetDrivers: IZCollection;\n\n    function GetClientVersion(const Url: string): Integer;\n\n    function GetLoginTimeout: Integer;\n    procedure SetLoginTimeout(Value: Integer);\n\n    procedure AddLoggingListener(Listener: IZLoggingListener);\n    procedure RemoveLoggingListener(Listener: IZLoggingListener);\n\n    procedure LogMessage(Category: TZLoggingCategory; const Protocol: string;\n      const Msg: string);\n    procedure LogError(Category: TZLoggingCategory; const Protocol: string;\n      const Msg: string; ErrorCode: Integer; const Error: string);\n\n    function ConstructURL(const Protocol, HostName, Database,\n      UserName, Password: String; const Port: Integer;\n      const Properties: TStrings = nil; const LibLocation: String = ''): String;\n    procedure ResolveDatabaseUrl(const Url: string; out HostName: string;\n      out Port: Integer; out Database: string; out UserName: string;\n      out Password: string; ResultInfo: TStrings = nil); overload;\n    procedure ResolveDatabaseUrl(const Url: string; out Database: string); overload;\n  end;\n\n{ TZDriverManager }\n\n{**\n  Constructs this object with default properties.\n}\nconstructor TZDriverManager.Create;\nbegin\n  FDrivers := TZCollection.Create;\n  FLoginTimeout := 0;\n  FLoggingListeners := TZCollection.Create;\n  FURL := TZURL.Create;\nend;\n\n{**\n  Destroys this object and cleanups the memory.\n}\ndestructor TZDriverManager.Destroy;\nbegin\n  FURL.Free;\n  FDrivers := nil;\n  FLoggingListeners := nil;\n  inherited Destroy;\nend;\n\n{**\n  Gets a collection of registered drivers.\n  @return an unmodifiable collection with registered drivers.\n}\nfunction TZDriverManager.GetDrivers: IZCollection;\nbegin\n  Result := TZUnmodifiableCollection.Create(FDrivers);\nend;\n\n{**\n  Gets a login timeout value.\n  @return a login timeout.\n}\nfunction TZDriverManager.GetLoginTimeout: Integer;\nbegin\n  Result := FLoginTimeout;\nend;\n\n{**\n  Sets a new login timeout value.\n  @param Seconds a new login timeout in seconds.\n}\nprocedure TZDriverManager.SetLoginTimeout(Value: Integer);\nbegin\n  FLoginTimeout := Value;\nend;\n\n{**\n  Registers a driver for specific database.\n  @param Driver a driver to be registered.\n}\nprocedure TZDriverManager.RegisterDriver(Driver: IZDriver);\nbegin\n  if not FDrivers.Contains(Driver) then\n    FDrivers.Add(Driver);\nend;\n\n{**\n  Unregisters a driver for specific database.\n  @param Driver a driver to be unregistered.\n}\nprocedure TZDriverManager.DeregisterDriver(Driver: IZDriver);\nbegin\n  FDrivers.Remove(Driver);\nend;\n\n{**\n  Gets a driver which accepts the specified url.\n  @param Url a database connection url.\n  @return a found driver or <code>null</code> otherwise.\n}\nfunction TZDriverManager.GetDriver(const Url: string): IZDriver;\nvar\n  I: Integer;\n  Current: IZDriver;\nbegin\n  Result := nil;\n  for I := 0 to FDrivers.Count - 1 do\n  begin\n    Current := FDrivers[I] as IZDriver;\n    if Current.AcceptsURL(Url) then\n    begin\n      Result := Current;\n      Break;\n    end;\n  end;\nend;\n\n{**\n  Locates a required driver and opens a connection to the specified database.\n  @param Url a database connection Url.\n  @param Info an extra connection parameters.\n  @return an opened connection.\n}\nfunction TZDriverManager.GetConnectionWithParams(const Url: string; Info: TStrings):\n  IZConnection;\nvar\n  Driver: IZDriver;\nbegin\n  Driver := GetDriver(Url);\n  if Driver = nil then\n    raise EZSQLException.Create(SDriverWasNotFound);\n  Result := Driver.Connect(Url, Info);\nend;\n\n{**\n  Locates a required driver and returns the client library version number.\n  @param Url a database connection Url.\n  @return client library version number.\n}\nfunction TZDriverManager.GetClientVersion(const Url: string): Integer;\nvar\n  Driver: IZDriver;\nbegin\n  Driver := GetDriver(Url);\n  if Driver = nil then\n    raise EZSQLException.Create(SDriverWasNotFound);\n  Result := Driver.GetClientVersion(Url);\nend;\n\n{**\n  Locates a required driver and opens a connection to the specified database.\n  @param Url a database connection Url.\n  @param User a user's name.\n  @param Password a user's password.\n  @return an opened connection.\n}\nfunction TZDriverManager.GetConnectionWithLogin(const Url: string; const User: string;\n  const Password: string): IZConnection;\nvar\n  Info: TStrings;\nbegin\n  Info := TStringList.Create;\n  try\n    Info.Add('username=' + User);\n    Info.Add('password=' + Password);\n    Result := GetConnectionWithParams(Url, Info);\n  finally\n    Info.Free;\n  end;\nend;\n\n{**\n  Locates a required driver and opens a connection to the specified database.\n  @param Url a database connection Url.\n  @return an opened connection.\n}\nfunction TZDriverManager.GetConnection(const Url: string): IZConnection;\nbegin\n  Result := GetConnectionWithParams(Url, nil);\nend;\n\n{**\n  Adds a logging listener to log SQL events.\n  @param Listener a logging interface to be added.\n}\nprocedure TZDriverManager.AddLoggingListener(Listener: IZLoggingListener);\nbegin\n  FLoggingListeners.Add(Listener);\nend;\n\n{**\n  Removes a logging listener from the list.\n  @param Listener a logging interface to be removed.\n}\nprocedure TZDriverManager.RemoveLoggingListener(Listener: IZLoggingListener);\nbegin\n  FLoggingListeners.Remove(Listener);\nend;\n\n{**\n  Logs a message about event with error result code.\n  @param Category a category of the message.\n  @param Protocol a name of the protocol.\n  @param Msg a description message.\n  @param ErrorCode an error code.\n  @param Error an error message.\n}\nprocedure TZDriverManager.LogError(Category: TZLoggingCategory;\n  const Protocol: string; const Msg: string; ErrorCode: Integer; const Error: string);\nvar\n  I: Integer;\n  Listener: IZLoggingListener;\n  Event: TZLoggingEvent;\nbegin\n  if FLoggingListeners.Count = 0 then\n    Exit;\n  Event := TZLoggingEvent.Create(Category, Protocol, Msg, ErrorCode, Error);\n  try\n    for I := 0 to FLoggingListeners.Count - 1 do\n    begin\n      Listener := FLoggingListeners[I] as IZLoggingListener;\n      try\n        Listener.LogEvent(Event);\n      except\n      end;\n    end;\n  finally\n    Event.Destroy;\n  end;\nend;\n\n{**\n  Logs a message about event with normal result code.\n  @param Category a category of the message.\n  @param Protocol a name of the protocol.\n  @param Msg a description message.\n}\nprocedure TZDriverManager.LogMessage(Category: TZLoggingCategory;\n  const Protocol: string; const Msg: string);\nbegin\n  if FLoggingListeners.Count = 0 then\n      Exit;\n  LogError(Category, Protocol, Msg, 0, '');\nend;\n\n{**\n  Constructs a valid URL\n  @param Protocol the Driver-protocol (must be assigned).\n  @param HostName the hostname (could be empty).\n  @param Database the connection-database (could be empty).\n  @param UserName the username (could be empty).\n  @param Password the password(could be empty).\n  @param Port the Server-Port (could be 0).\n  @param Properties the Database-Properties (could be empty).\n}\nfunction TZDriverManager.ConstructURL(const Protocol, HostName, Database,\n  UserName, Password: String; const Port: Integer;\n  const Properties: TStrings = nil; const LibLocation: String = ''): String;\nbegin\n  FURL.Protocol := Protocol;\n  FURL.HostName := HostName;\n  FURL.Database := DataBase;\n  FURL.UserName := UserName;\n  FURL.Password := Password;\n  FURL.Port := Port;\n  if Assigned(Properties) then\n    FURL.Properties.Text := Properties.Text;\n  FURL.LibLocation := LibLocation;\n  Result := FURL.URL;\nend;\n\n{**\n  Resolves a database URL and fills the database connection parameters.\n  @param Url an initial database URL.\n  @param HostName a name of the database host.\n  @param Port a port number.\n  @param Database a database name.\n  @param UserName a name of the database user.\n  @param Password a user's password.\n  @param ResutlInfo a result info parameters.\n}\nprocedure TZDriverManager.ResolveDatabaseUrl(const Url: string; out HostName: string;\n  out Port: Integer; out Database: string; out UserName: string;\n  out Password: string; ResultInfo: TStrings = nil);\nbegin\n  FURL.URL := Url;\n  HostName := FURL.HostName;\n  Port := FURL.Port;\n  DataBase := FURL.Database;\n  UserName := FURL.UserName;\n  PassWord := FURL.Password;\n  if Assigned(ResultInfo) then\n    ResultInfo.Text := FURL.Properties.Text;\nend;\n\n{**\n  Resolves a database URL and fills the database parameter for MetaData.\n  @param Url an initial database URL.\n  @param Database a database name.\n}\nprocedure TZDriverManager.ResolveDatabaseUrl(const Url: string; out Database: string);\nbegin\n  FURL.URL := Url;\n  DataBase := FURL.Database;\nend;\n\n{ EZSQLThrowable }\n\n{**\n  Creates an exception with message string.\n  @param Msg a error description.\n}\nconstructor EZSQLThrowable.CreateClone(const E: EZSQLThrowable);\nbegin\n  inherited Create(E.Message);\n  FErrorCode:=E.ErrorCode;\n  FStatusCode:=E.Statuscode;\nend;\n\nconstructor EZSQLThrowable.Create(const Msg: string);\nbegin\n  inherited Create(Msg);\n  FErrorCode := -1;\nend;\n\n{**\n  Creates an exception with message string.\n  @param Msg a error description.\n  @param ErrorCode a native server error code.\n}\nconstructor EZSQLThrowable.CreateWithCode(const ErrorCode: Integer;\n  const Msg: string);\nbegin\n  inherited Create(Msg);\n  FErrorCode := ErrorCode;\nend;\n\nconstructor EZSQLThrowable.CreateWithStatus(const StatusCode, Msg: string);\nbegin\n  inherited Create(Msg);\n  FStatusCode := StatusCode;\nend;\n\ninitialization\n  DriverManager := TZDriverManager.Create;\nfinalization\n  DriverManager := nil;\nend.\n\n"
  },
  {
    "path": "lib/zeosdbo/src/dbc/ZDbcLogging.pas",
    "content": "{*********************************************************}\n{                                                         }\n{                 Zeos Database Objects                   }\n{         Database Logging Classes and Interfaces         }\n{                                                         }\n{        Originally written by Sergey Seroukhov           }\n{                                                         }\n{*********************************************************}\n\n{@********************************************************}\n{    Copyright (c) 1999-2012 Zeos Development Group       }\n{                                                         }\n{ License Agreement:                                      }\n{                                                         }\n{ This library is distributed in the hope that it will be }\n{ useful, but WITHOUT ANY WARRANTY; without even the      }\n{ implied warranty of MERCHANTABILITY or FITNESS FOR      }\n{ A PARTICULAR PURPOSE.  See the GNU Lesser General       }\n{ Public License for more details.                        }\n{                                                         }\n{ The source code of the ZEOS Libraries and packages are  }\n{ distributed under the Library GNU General Public        }\n{ License (see the file COPYING / COPYING.ZEOS)           }\n{ with the following  modification:                       }\n{ As a special exception, the copyright holders of this   }\n{ library give you permission to link this library with   }\n{ independent modules to produce an executable,           }\n{ regardless of the license terms of these independent    }\n{ modules, and to copy and distribute the resulting       }\n{ executable under terms of your choice, provided that    }\n{ you also meet, for each linked independent module,      }\n{ the terms and conditions of the license of that module. }\n{ An independent module is a module which is not derived  }\n{ from or based on this library. If you modify this       }\n{ library, you may extend this exception to your version  }\n{ of the library, but you are not obligated to do so.     }\n{ If you do not wish to do so, delete this exception      }\n{ statement from your version.                            }\n{                                                         }\n{                                                         }\n{ The project web site is located on:                     }\n{   http://zeos.firmos.at  (FORUM)                        }\n{   http://sourceforge.net/p/zeoslib/tickets/ (BUGTRACKER)}\n{   svn://svn.code.sf.net/p/zeoslib/code-0/trunk (SVN)    }\n{                                                         }\n{   http://www.sourceforge.net/projects/zeoslib.          }\n{                                                         }\n{                                                         }\n{                                 Zeos Development Group. }\n{********************************************************@}\n\nunit ZDbcLogging;\n\ninterface\n\n{$I ZDbc.inc}\n\nuses SysUtils, ZClasses;\n\ntype\n\n  {** Defines a time or the message. }\n  TZLoggingCategory = (lcConnect, lcDisconnect, lcTransaction, lcExecute, lcOther,\n    lcPrepStmt, lcBindPrepStmt, lcExecPrepStmt, lcUnprepStmt);\n\n  {** Defines a object for logging event. }\n  TZLoggingEvent = class;\n\n  {** Defines an interface to format logging events. }\n  IZLoggingFormatter = interface (IZInterface)\n//    ['{53559F5F-AC22-4DDC-B2EA-45D21ADDD2D5}']\n    function Format(LoggingEvent: TZLoggingEvent) : string;\n  end;\n\n  { TZLoggingFormatter }\n  {** Defines a object for logging event. }\n  TZLoggingFormatter = class (TInterfacedObject, IZLoggingFormatter)\n  private\n  public\n    function Format(LoggingEvent: TZLoggingEvent) : string; virtual;\n  end;\n\n  {** Defines a object for logging event. }\n  TZLoggingEvent = class (TObject)\n  private\n    FCategory: TZLoggingCategory;\n    FProtocol: string;\n    FMessage: string;\n    FErrorCode: Integer;\n    FError: string;\n    FTimestamp: TDateTime;\n  public\n    constructor Create(Category: TZLoggingCategory; Protocol: string;\n      Msg: string; ErrorCode: Integer; Error: string);\n\n    function AsString(LoggingFormatter:IZLoggingFormatter = nil): string;\n\n    property Category: TZLoggingCategory read FCategory;\n    property Protocol: string read FProtocol;\n    property Message: string read FMessage;\n    property ErrorCode: Integer read FErrorCode;\n    property Error: string read FError;\n    property Timestamp: TDateTime read FTimestamp;\n  end;\n\n  {** Defines an interface to accept logging events. }\n  IZLoggingListener = interface (IZInterface)\n    ['{53559F5F-AC22-4DDC-B2EA-45D21ADDD2D4}']\n\n    procedure LogEvent(Event: TZLoggingEvent);\n  end;\n\nimplementation\nvar DefaultLoggingFormatter: TZLoggingFormatter;\n\n{ TZLoggingFormatter }\n\nfunction TZLoggingFormatter.Format(LoggingEvent: TZLoggingEvent): string;\nbegin\n  Result := FormatDateTime('yyyy-mm-dd hh:mm:ss', LoggingEvent.Timestamp) + ' cat: ';\n  case LoggingEvent.Category of\n    lcConnect: Result := Result + 'Connect';\n    lcDisconnect: Result := Result + 'Disconnect';\n    lcTransaction: Result := Result + 'Transaction';\n    lcExecute: Result := Result + 'Execute';\n    lcPrepStmt: Result := Result + 'Prepare';\n    lcBindPrepStmt: Result := Result + 'Bind prepared';\n    lcExecPrepStmt: Result := Result + 'Execute prepared';\n    lcUnprepStmt: Result := Result + 'Unprepare prepared';\n  else\n    Result := Result + 'Other';\n  end;\n  if LoggingEvent.Protocol <> '' then\n    Result := Result + ', proto: ' + LoggingEvent.Protocol;\n  Result := Result + ', msg: ' + LoggingEvent.Message;\n  if (LoggingEvent.ErrorCode <> 0) or (LoggingEvent.Error <> '') then\n  begin\n    Result := Result + ', errcode: ' + IntToStr(LoggingEvent.ErrorCode)\n      + ', error: ' + LoggingEvent.Error;\n  end;\nend;\n\n{ TZLoggingEvent }\n\n{**\n  Constructs this logging event.\n  @param Protocol a DBC protocol.\n  @param Msg a description message.\n  @param ErrorCode an error code.\n  @param Error an error message.\n}\nconstructor TZLoggingEvent.Create(Category: TZLoggingCategory;\n  Protocol: string; Msg: string; ErrorCode: Integer; Error: string);\nbegin\n  FCategory := Category;\n  FProtocol := Protocol;\n  FMessage := Msg;\n  FErrorCode := ErrorCode;\n  FError := Error;\n  FTimestamp := Now;\nend;\n\n{**\n  Gets a string representation for this event.\n  @returns a string representation.\n}\nfunction TZLoggingEvent.AsString(LoggingFormatter:IZLoggingFormatter = nil): string;\nbegin\n  If Assigned(LoggingFormatter) then\n    Result := LoggingFormatter.Format(Self)\n  else\n    Result := DefaultLoggingFormatter.Format(Self);\nend;\n\ninitialization\n  DefaultLoggingFormatter := TZLoggingFormatter.Create;\n\nfinalization\n  DefaultLoggingFormatter.Free;\nend.\n\n"
  },
  {
    "path": "lib/zeosdbo/src/dbc/ZDbcMetadata.pas",
    "content": "{*********************************************************}\n{                                                         }\n{                 Zeos Database Objects                   }\n{           Abstract Database Connectivity Classes        }\n{                                                         }\n{        Originally written by Sergey Seroukhov           }\n{                                                         }\n{*********************************************************}\n\n{@********************************************************}\n{    Copyright (c) 1999-2012 Zeos Development Group       }\n{                                                         }\n{ License Agreement:                                      }\n{                                                         }\n{ This library is distributed in the hope that it will be }\n{ useful, but WITHOUT ANY WARRANTY; without even the      }\n{ implied warranty of MERCHANTABILITY or FITNESS FOR      }\n{ A PARTICULAR PURPOSE.  See the GNU Lesser General       }\n{ Public License for more details.                        }\n{                                                         }\n{ The source code of the ZEOS Libraries and packages are  }\n{ distributed under the Library GNU General Public        }\n{ License (see the file COPYING / COPYING.ZEOS)           }\n{ with the following  modification:                       }\n{ As a special exception, the copyright holders of this   }\n{ library give you permission to link this library with   }\n{ independent modules to produce an executable,           }\n{ regardless of the license terms of these independent    }\n{ modules, and to copy and distribute the resulting       }\n{ executable under terms of your choice, provided that    }\n{ you also meet, for each linked independent module,      }\n{ the terms and conditions of the license of that module. }\n{ An independent module is a module which is not derived  }\n{ from or based on this library. If you modify this       }\n{ library, you may extend this exception to your version  }\n{ of the library, but you are not obligated to do so.     }\n{ If you do not wish to do so, delete this exception      }\n{ statement from your version.                            }\n{                                                         }\n{                                                         }\n{ The project web site is located on:                     }\n{   http://zeos.firmos.at  (FORUM)                        }\n{   http://sourceforge.net/p/zeoslib/tickets/ (BUGTRACKER)}\n{   svn://svn.code.sf.net/p/zeoslib/code-0/trunk (SVN)    }\n{                                                         }\n{   http://www.sourceforge.net/projects/zeoslib.          }\n{                                                         }\n{                                                         }\n{                                 Zeos Development Group. }\n{********************************************************@}\n\nunit ZDbcMetadata;\n\ninterface\n\n{$I ZDbc.inc}\n\nuses\n{$IFDEF FPC}\n  {$IFDEF WIN32}\n    Comobj,\n  {$ENDIF}\n{$ENDIF}\n  Types, Classes, {$IFDEF MSEgui}mclasses,{$ENDIF} SysUtils, Contnrs,\n  ZSysUtils, ZClasses, ZDbcIntfs, ZDbcResultSetMetadata, ZDbcCachedResultSet,\n  ZDbcCache, ZCompatibility, ZSelectSchema, ZURL, ZDbcConnection;\n\nconst\n  procedureColumnUnknown = 0;\n  procedureColumnIn = 1;\n  procedureColumnInOut = 2;\n  procedureColumnOut = 4;\n  procedureColumnReturn = 5;\n  procedureColumnResult = 3;\n  procedureNoNulls = 0;\n  procedureNullable = 1;\n  procedureNullableUnknown = 2;\n\ntype\n  TZWildcardsSet= {$IFDEF UNICODE}TSysCharSet{$ELSE}set of Char{$ENDIF};\n\n  {** Defines a metadata resultset column definition. }\n  TZMetadataColumnDef = {$ifndef FPC_REQUIRES_PROPER_ALIGNMENT}packed{$endif} record\n    Name: string;\n    SQLType: TZSQLType;\n    Length: Integer\n  end;\n\n  {** Defines a dynamic array of metadata column definitions. }\n  TZMetadataColumnDefs = array of TZMetadataColumnDef;\n\n  {** Represents a Virtual ResultSet interface. }\n  IZVirtualResultSet = interface(IZCachedResultSet)\n    ['{D84055AC-BCD5-40CD-B408-6F11AF000C96}']\n    procedure SetType(Value: TZResultSetType);\n    procedure SetConcurrency(Value: TZResultSetConcurrency);\n  end;\n\n  {** Implements Virtual ResultSet. }\n  TZVirtualResultSet = class(TZAbstractCachedResultSet, IZVirtualResultSet)\n  protected\n    procedure CalculateRowDefaults(RowAccessor: TZRowAccessor); override;\n    procedure PostRowUpdates(OldRowAccessor, NewRowAccessor: TZRowAccessor);\n      override;\n  public\n    constructor CreateWithStatement(const SQL: string; Statement: IZStatement;\n      ConSettings: PZConSettings);\n    constructor CreateWithColumns(ColumnsInfo: TObjectList; const SQL: string;\n      ConSettings: PZConSettings);\n    destructor Destroy; override;\n  end;\n\n  {** Implements Abstract Database Metadata. }\n\n  { TZAbstractDatabaseMetadata }\n\n  TZAbstractDatabaseMetadata = class(TContainedObject, IZDatabaseMetadata)\n  private\n    FConnection: Pointer;\n    FUrl: TZURL;\n    FCachedResultSets: IZHashMap;\n    FDatabaseInfo: IZDatabaseInfo;\n    FConSettings: PZConSettings;\n    FIC: IZIdentifierConvertor;\n    function GetInfo: TStrings;\n    function GetURLString: String;\n    function StripEscape(const Pattern: string): string;\n    function HasNoWildcards(const Pattern: string): boolean;\n  protected\n    FDatabase: String;\n    WildcardsArray: array of char; //Added by Cipto\n    function EscapeString(const S: string): string; virtual;\n    function DecomposeObjectString(const S: String): String; virtual;\n    function CreateDatabaseInfo: IZDatabaseInfo; virtual; // technobot 2008-06-24\n    function GetStatement: IZSTatement; // technobot 2008-06-28 - moved from descendants\n\n    { Metadata ResultSets Caching. }\n    procedure AddResultSetToCache(const Key: string; ResultSet: IZResultSet);\n    function GetResultSetFromCache(const Key: string): IZResultSet;\n    function ConstructVirtualResultSet(ColumnsDefs: TZMetadataColumnDefs):\n      IZVirtualResultSet;\n    function CopyToVirtualResultSet(SrcResultSet: IZResultSet;\n      DestResultSet: IZVirtualResultSet): IZVirtualResultSet;\n    function CloneCachedResultSet(ResultSet: IZResultSet): IZResultSet;\n    function ConstructNameCondition(Pattern: string; Column: string): string; virtual;\n    function AddEscapeCharToWildcards(const Pattern:string): string;\n    function GetWildcardsSet:TZWildcardsSet;\n    procedure FillWildcards; virtual;\n    function NormalizePatternCase(Pattern:String): string;\n    property Url: string read GetURLString;\n    property Info: TStrings read GetInfo;\n    property CachedResultSets: IZHashMap read FCachedResultSets\n      write FCachedResultSets;\n    property ConSettings: PZConSettings read FConSettings write FConSettings;\n    property IC: IZIdentifierConvertor read FIC;\n  protected\n    function UncachedGetTables(const Catalog: string; const SchemaPattern: string;\n      const TableNamePattern: string; const Types: TStringDynArray): IZResultSet; virtual;\n    function UncachedGetSchemas: IZResultSet; virtual;\n    function UncachedGetCatalogs: IZResultSet; virtual;\n    function UncachedGetTableTypes: IZResultSet; virtual;\n    function UncachedGetColumns(const Catalog: string; const SchemaPattern: string;\n      const TableNamePattern: string; const ColumnNamePattern: string): IZResultSet; virtual;\n    function UncachedGetTablePrivileges(const Catalog: string; const SchemaPattern: string;\n      const TableNamePattern: string): IZResultSet; virtual;\n    function UncachedGetColumnPrivileges(const Catalog: string; const Schema: string;\n      const Table: string; const ColumnNamePattern: string): IZResultSet; virtual;\n\n    function UncachedGetPrimaryKeys(const Catalog: string; const Schema: string;\n      const Table: string): IZResultSet; virtual;\n    function UncachedGetImportedKeys(const Catalog: string; const Schema: string;\n      const Table: string): IZResultSet; virtual;\n    function UncachedGetExportedKeys(const Catalog: string; const Schema: string;\n      const Table: string): IZResultSet; virtual;\n    function UncachedGetCrossReference(const PrimaryCatalog: string; const PrimarySchema: string;\n      const PrimaryTable: string; const ForeignCatalog: string; const ForeignSchema: string;\n      const ForeignTable: string): IZResultSet; virtual;\n    function UncachedGetIndexInfo(const Catalog: string; const Schema: string; const Table: string;\n      Unique: Boolean; Approximate: Boolean): IZResultSet; virtual;\n    function UncachedGetSequences(const Catalog: string; const SchemaPattern: string;\n      const SequenceNamePattern: string): IZResultSet; virtual;\n    function UncachedGetTriggers(const Catalog: string; const SchemaPattern: string;\n      const TableNamePattern: string; const TriggerNamePattern: string): IZResultSet; virtual; //EgonHugeist\n    function UncachedGetCollationAndCharSet(const Catalog, SchemaPattern,\n      TableNamePattern, ColumnNamePattern: string): IZResultSet; virtual; //EgonHugeist\n    function UncachedGetCharacterSets: IZResultSet; virtual; //EgonHugeist\n    function UncachedGetProcedures(const Catalog: string; const SchemaPattern: string;\n      const ProcedureNamePattern: string): IZResultSet; virtual;\n    function UncachedGetProcedureColumns(const Catalog: string; const SchemaPattern: string;\n      const ProcedureNamePattern: string; const ColumnNamePattern: string):\n      IZResultSet; virtual;\n    function UncachedGetBestRowIdentifier(const Catalog: string; const Schema: string;\n      const Table: string; Scope: Integer; Nullable: Boolean): IZResultSet; virtual;\n    function UncachedGetVersionColumns(const Catalog: string; const Schema: string;\n      const Table: string): IZResultSet; virtual;\n    function UncachedGetTypeInfo: IZResultSet; virtual;\n    function UncachedGetUDTs(const Catalog: string; const SchemaPattern: string;\n      const TypeNamePattern: string; const Types: TIntegerDynArray): IZResultSet; virtual;\n  public\n    constructor Create(Connection: TZAbstractConnection; const Url: TZURL); virtual;\n    destructor Destroy; override;\n\n    function GetURL: string; virtual;\n    function GetUserName: string; virtual;\n\n    function GetDatabaseInfo: IZDatabaseInfo; // technobot 2008-06-24 - see also CreateDatabaseInfo method.\n\n    function GetTables(const Catalog: string; const SchemaPattern: string;\n      const TableNamePattern: string; const Types: TStringDynArray): IZResultSet;\n    function GetSchemas: IZResultSet;\n    function GetCatalogs: IZResultSet;\n    function GetTableTypes: IZResultSet;\n    function GetColumns(const Catalog: string; const SchemaPattern: string;\n      const TableNamePattern: string; const ColumnNamePattern: string): IZResultSet;\n    function GetTablePrivileges(const Catalog: string; const SchemaPattern: string;\n      const TableNamePattern: string): IZResultSet;\n    function GetColumnPrivileges(const Catalog: string; const Schema: string;\n      const Table: string; const ColumnNamePattern: string): IZResultSet;\n    function GetPrimaryKeys(const Catalog: string; const Schema: string;\n      const Table: string): IZResultSet;\n    function GetImportedKeys(const Catalog: string; const Schema: string;\n      const Table: string): IZResultSet;\n    function GetExportedKeys(const Catalog: string; const Schema: string;\n      const Table: string): IZResultSet;\n    function GetCrossReference(const PrimaryCatalog: string; const PrimarySchema: string;\n      const PrimaryTable: string; const ForeignCatalog: string; const ForeignSchema: string;\n      const ForeignTable: string): IZResultSet;\n    function GetIndexInfo(const Catalog: string; const Schema: string; const Table: string;\n      Unique: Boolean; Approximate: Boolean): IZResultSet;\n    function GetCollationAndCharSet(const Catalog, Schema, TableName, ColumnName: String): IZResultSet; //EgonHugeist\n    function GetCharacterSets: IZResultSet; //EgonHugeist\n    function GetTriggers(const Catalog: string; const SchemaPattern: string;\n      const TableNamePattern: string; const TriggerNamePattern: string): IZResultSet; //EgonHugesit\n    function GetSequences(const Catalog: string; const SchemaPattern: string;\n      const SequenceNamePattern: string): IZResultSet;\n    function GetProcedures(const Catalog: string; const SchemaPattern: string;\n      const ProcedureNamePattern: string): IZResultSet;\n    function GetProcedureColumns(const Catalog: string; const SchemaPattern: string;\n      const ProcedureNamePattern: string; const ColumnNamePattern: string):\n      IZResultSet;\n    function GetBestRowIdentifier(const Catalog: string; const Schema: string;\n      const Table: string; Scope: Integer; Nullable: Boolean): IZResultSet;\n    function GetVersionColumns(const Catalog: string; const Schema: string;\n      const Table: string): IZResultSet;\n    function GetTypeInfo: IZResultSet;\n    function GetUDTs(const Catalog: string; const SchemaPattern: string;\n      const TypeNamePattern: string; const Types: TIntegerDynArray): IZResultSet;\n\n\n    function GetConnection: IZConnection; virtual;\n\n    function GetIdentifierConvertor: IZIdentifierConvertor; virtual;\n    procedure ClearCache; overload;virtual;\n    procedure ClearCache(const Key: string);overload;virtual;\n\n    // --> technobot 2008-06-14:  metadata cache key retrieval API:\n    function GetTablesCacheKey(const Catalog: string; const SchemaPattern: string;\n      const TableNamePattern: string; const Types: TStringDynArray): string;\n    function GetSchemasCacheKey: string;\n    function GetCatalogsCacheKey: string;\n    function GetTableTypesCacheKey: string;\n    function GetColumnsCacheKey(const Catalog: string; const SchemaPattern: string;\n      const TableNamePattern: string; const ColumnNamePattern: string): string;\n    function GetColumnPrivilegesCacheKey(const Catalog: string; const Schema: string;\n      const Table: string; const ColumnNamePattern: string): string;\n    function GetTablePrivilegesCacheKey(const Catalog: string; const SchemaPattern: string;\n      const TableNamePattern: string): string;\n    function GetPrimaryKeysCacheKey(const Catalog: string; const Schema: string;\n      const Table: string): string;\n    function GetImportedKeysCacheKey(const Catalog: string; const Schema: string;\n      const Table: string): string;\n    function GetExportedKeysCacheKey(const Catalog: string; const Schema: string;\n      const Table: string): string;\n    function GetCrossReferenceCacheKey(const PrimaryCatalog: string; const PrimarySchema: string;\n      const PrimaryTable: string; const ForeignCatalog: string; const ForeignSchema: string;\n      const ForeignTable: string): string;\n    function GetIndexInfoCacheKey(const Catalog: string; const Schema: string; const Table: string;\n      const Unique: Boolean; const Approximate: Boolean): string;\n    function GetSequencesCacheKey(const Catalog: string; const SchemaPattern: string;\n      const SequenceNamePattern: string): string;\n    function GetCollationAndCharSetCacheKey(const Catalog, SchemaPattern,\n      TableNamePattern, ColumnPattern: String): string; //EgonHugeist\n    function GetCharacterSetsCacheKey: String; //EgonHugeist\n    function GetTriggersCacheKey(const Catalog: string;\n      const SchemaPattern: string; const TableNamePattern: string;\n      const TriggerNamePattern: string): string; //EgonHugeist\n    function GetProceduresCacheKey(const Catalog: string; const SchemaPattern: string;\n      const ProcedureNamePattern: string): string;\n    function GetProcedureColumnsCacheKey(const Catalog: string; const SchemaPattern: string;\n      const ProcedureNamePattern: string; const ColumnNamePattern: string): string;\n    function GetBestRowIdentifierCacheKey(const Catalog: string; const Schema: string;\n      const Table: string; const Scope: Integer; const Nullable: Boolean): string;\n    function GetVersionColumnsCacheKey(const Catalog: string; const Schema: string;\n      const Table: string): string;\n    function GetTypeInfoCacheKey: string;\n    function GetUDTsCacheKey(const Catalog: string; const SchemaPattern: string;\n      const TypeNamePattern: string; const Types: TIntegerDynArray): string;\n\n    procedure GetCacheKeys(List: TStrings);\n    // <-- technobot 2008-06-14\n  end;\n\n  // technobot 2008-06-24 - methods moved as is from TZAbstractDatabaseMetadata:\n  {** Implements Abstract Database Information. }\n  TZAbstractDatabaseInfo = class(TInterfacedObject, IZDatabaseInfo)\n  private\n    FMetadata: TZAbstractDatabaseMetadata;\n  protected\n    FIdentifierQuotes: String;\n    property Metadata: TZAbstractDatabaseMetadata read FMetadata;\n  public\n    constructor Create(const Metadata: TZAbstractDatabaseMetadata); overload;\n    constructor Create(const Metadata: TZAbstractDatabaseMetadata;\n      const IdentifierQuotes: String); overload;\n    destructor Destroy; override;\n\n    // database/driver/server info:\n    function GetDatabaseProductName: string; virtual;\n    function GetDatabaseProductVersion: string; virtual;\n    function GetDriverName: string; virtual;\n    function GetDriverVersion: string; virtual;\n    function GetDriverMajorVersion: Integer; virtual;\n    function GetDriverMinorVersion: Integer; virtual;\n    function GetServerVersion: string;\n\n    // capabilities (what it can/cannot do):\n    function AllProceduresAreCallable: Boolean; virtual;\n    function AllTablesAreSelectable: Boolean; virtual;\n    function SupportsMixedCaseIdentifiers: Boolean; virtual;\n    function SupportsMixedCaseQuotedIdentifiers: Boolean; virtual;\n    function SupportsAlterTableWithAddColumn: Boolean; virtual;\n    function SupportsAlterTableWithDropColumn: Boolean; virtual;\n    function SupportsColumnAliasing: Boolean; virtual;\n    function SupportsConvert: Boolean; virtual;\n    function SupportsConvertForTypes(FromType: TZSQLType; ToType: TZSQLType):\n      Boolean; virtual;\n    function SupportsTableCorrelationNames: Boolean; virtual;\n    function SupportsDifferentTableCorrelationNames: Boolean; virtual;\n    function SupportsExpressionsInOrderBy: Boolean; virtual;\n    function SupportsOrderByUnrelated: Boolean; virtual;\n    function SupportsGroupBy: Boolean; virtual;\n    function SupportsGroupByUnrelated: Boolean; virtual;\n    function SupportsGroupByBeyondSelect: Boolean; virtual;\n    function SupportsLikeEscapeClause: Boolean; virtual;\n    function SupportsMultipleResultSets: Boolean; virtual;\n    function SupportsMultipleTransactions: Boolean; virtual;\n    function SupportsNonNullableColumns: Boolean; virtual;\n    function SupportsMinimumSQLGrammar: Boolean; virtual;\n    function SupportsCoreSQLGrammar: Boolean; virtual;\n    function SupportsExtendedSQLGrammar: Boolean; virtual;\n    function SupportsANSI92EntryLevelSQL: Boolean; virtual;\n    function SupportsANSI92IntermediateSQL: Boolean; virtual;\n    function SupportsANSI92FullSQL: Boolean; virtual;\n    function SupportsIntegrityEnhancementFacility: Boolean; virtual;\n    function SupportsOuterJoins: Boolean; virtual;\n    function SupportsFullOuterJoins: Boolean; virtual;\n    function SupportsLimitedOuterJoins: Boolean; virtual;\n    function SupportsSchemasInDataManipulation: Boolean; virtual;\n    function SupportsSchemasInProcedureCalls: Boolean; virtual;\n    function SupportsSchemasInTableDefinitions: Boolean; virtual;\n    function SupportsSchemasInIndexDefinitions: Boolean; virtual;\n    function SupportsSchemasInPrivilegeDefinitions: Boolean; virtual;\n    function SupportsCatalogsInDataManipulation: Boolean; virtual;\n    function SupportsCatalogsInProcedureCalls: Boolean; virtual;\n    function SupportsCatalogsInTableDefinitions: Boolean; virtual;\n    function SupportsCatalogsInIndexDefinitions: Boolean; virtual;\n    function SupportsCatalogsInPrivilegeDefinitions: Boolean; virtual;\n    function SupportsOverloadPrefixInStoredProcedureName: Boolean; virtual;\n    function SupportsPositionedDelete: Boolean; virtual;\n    function SupportsPositionedUpdate: Boolean; virtual;\n    function SupportsSelectForUpdate: Boolean; virtual;\n    function SupportsStoredProcedures: Boolean; virtual;\n    function SupportsSubqueriesInComparisons: Boolean; virtual;\n    function SupportsSubqueriesInExists: Boolean; virtual;\n    function SupportsSubqueriesInIns: Boolean; virtual;\n    function SupportsSubqueriesInQuantifieds: Boolean; virtual;\n    function SupportsCorrelatedSubqueries: Boolean; virtual;\n    function SupportsUnion: Boolean; virtual;\n    function SupportsUnionAll: Boolean; virtual;\n    function SupportsOpenCursorsAcrossCommit: Boolean; virtual;\n    function SupportsOpenCursorsAcrossRollback: Boolean; virtual;\n    function SupportsOpenStatementsAcrossCommit: Boolean; virtual;\n    function SupportsOpenStatementsAcrossRollback: Boolean; virtual;\n    function SupportsTransactions: Boolean; virtual;\n    function SupportsTransactionIsolationLevel(Level: TZTransactIsolationLevel):\n      Boolean; virtual;\n    function SupportsDataDefinitionAndDataManipulationTransactions: Boolean; virtual;\n    function SupportsDataManipulationTransactionsOnly: Boolean; virtual;\n    function SupportsResultSetType(_Type: TZResultSetType): Boolean; virtual;\n    function SupportsResultSetConcurrency(_Type: TZResultSetType;\n      Concurrency: TZResultSetConcurrency): Boolean; virtual;\n    function SupportsBatchUpdates: Boolean; virtual;\n    function SupportsNonEscapedSearchStrings: Boolean; virtual;\n    function SupportsUpdateAutoIncrementFields: Boolean; virtual;\n\n    // maxima:\n    function GetMaxBinaryLiteralLength: Integer; virtual;\n    function GetMaxCharLiteralLength: Integer; virtual;\n    function GetMaxColumnNameLength: Integer; virtual;\n    function GetMaxColumnsInGroupBy: Integer; virtual;\n    function GetMaxColumnsInIndex: Integer; virtual;\n    function GetMaxColumnsInOrderBy: Integer; virtual;\n    function GetMaxColumnsInSelect: Integer; virtual;\n    function GetMaxColumnsInTable: Integer; virtual;\n    function GetMaxConnections: Integer; virtual;\n    function GetMaxCursorNameLength: Integer; virtual;\n    function GetMaxIndexLength: Integer; virtual;\n    function GetMaxSchemaNameLength: Integer; virtual;\n    function GetMaxProcedureNameLength: Integer; virtual;\n    function GetMaxCatalogNameLength: Integer; virtual;\n    function GetMaxRowSize: Integer; virtual;\n    function GetMaxStatementLength: Integer; virtual;\n    function GetMaxStatements: Integer; virtual;\n    function GetMaxTableNameLength: Integer; virtual;\n    function GetMaxTablesInSelect: Integer; virtual;\n    function GetMaxUserNameLength: Integer; virtual;\n\n    // policies (how are various data and operations handled):\n    function IsReadOnly: Boolean; virtual;\n    function IsCatalogAtStart: Boolean; virtual;\n    function DoesMaxRowSizeIncludeBlobs: Boolean; virtual;\n    function NullsAreSortedHigh: Boolean; virtual;\n    function NullsAreSortedLow: Boolean; virtual;\n    function NullsAreSortedAtStart: Boolean; virtual;\n    function NullsAreSortedAtEnd: Boolean; virtual;\n    function NullPlusNonNullIsNull: Boolean; virtual;\n    function UsesLocalFiles: Boolean; virtual;\n    function UsesLocalFilePerTable: Boolean; virtual;\n    function StoresUpperCaseIdentifiers: Boolean; virtual;\n    function StoresLowerCaseIdentifiers: Boolean; virtual;\n    function StoresMixedCaseIdentifiers: Boolean; virtual;\n    function StoresUpperCaseQuotedIdentifiers: Boolean; virtual;\n    function StoresLowerCaseQuotedIdentifiers: Boolean; virtual;\n    function StoresMixedCaseQuotedIdentifiers: Boolean; virtual;\n    function GetDefaultTransactionIsolation: TZTransactIsolationLevel; virtual;\n    function DataDefinitionCausesTransactionCommit: Boolean; virtual;\n    function DataDefinitionIgnoredInTransactions: Boolean; virtual;\n\n    // interface details (terms, keywords, etc):\n    function GetIdentifierQuoteString: string;\n    function GetSchemaTerm: string; virtual;\n    function GetProcedureTerm: string; virtual;\n    function GetCatalogTerm: string; virtual;\n    function GetCatalogSeparator: string; virtual;\n    function GetSQLKeywords: string; virtual;\n    function GetNumericFunctions: string; virtual;\n    function GetStringFunctions: string; virtual;\n    function GetSystemFunctions: string; virtual;\n    function GetTimeDateFunctions: string; virtual;\n    function GetSearchStringEscape: string; virtual;\n    function GetExtraNameCharacters: string; virtual;\n  end;\n\n  {** Implements a default Case Sensitive/Unsensitive identifier convertor. }\n  TZDefaultIdentifierConvertor = class (TZAbstractObject,\n    IZIdentifierConvertor)\n  private\n    FMetadata: Pointer;\n    function GetMetaData: IZDatabaseMetadata;\n  protected\n    property Metadata: IZDatabaseMetadata read GetMetaData;\n\n    function IsLowerCase(const Value: string): Boolean;\n    function IsUpperCase(const Value: string): Boolean;\n    function IsSpecialCase(const Value: string): Boolean; virtual;\n  public\n    constructor Create(Metadata: IZDatabaseMetadata);\n\n    function IsCaseSensitive(const Value: string): Boolean;\n    function IsQuoted(const Value: string): Boolean; virtual;\n    function Quote(const Value: string): string; virtual;\n    function ExtractQuote(const Value: string): string; virtual;\n  end;\n\n  function GetTablesMetaDataCacheKey(Const Catalog:String;\n      Const SchemaPattern:String;Const TableNamePattern:String;const Types: TStringDynArray):String;\n      deprecated; // (technobot) use TZAbstractDatabaseMetadata.GetTablesCacheKey instead\n\n\nvar\n  CharacterSetsColumnsDynArray: TZMetadataColumnDefs; //EgonHugeist\n  CollationCharSetColumnsDynArray: TZMetadataColumnDefs; //EgonHugeist\n  TriggersColumnsDynArray: TZMetadataColumnDefs; //EgonHugeist\n  TriggersColColumnsDynArray: TZMetadataColumnDefs;\n  ProceduresColumnsDynArray: TZMetadataColumnDefs;\n  ProceduresColColumnsDynArray: TZMetadataColumnDefs;\n  TableColumnsDynArray: TZMetadataColumnDefs;\n  SchemaColumnsDynArray: TZMetadataColumnDefs;\n  CatalogColumnsDynArray: TZMetadataColumnDefs;\n  TableTypeColumnsDynArray: TZMetadataColumnDefs;\n  TableColColumnsDynArray: TZMetadataColumnDefs;\n  TableColPrivColumnsDynArray: TZMetadataColumnDefs;\n  TablePrivColumnsDynArray: TZMetadataColumnDefs;\n  BestRowIdentColumnsDynArray: TZMetadataColumnDefs;\n  TableColVerColumnsDynArray: TZMetadataColumnDefs;\n  PrimaryKeyColumnsDynArray: TZMetadataColumnDefs;\n  ImportedKeyColumnsDynArray: TZMetadataColumnDefs;\n  ExportedKeyColumnsDynArray: TZMetadataColumnDefs;\n  CrossRefColumnsDynArray: TZMetadataColumnDefs;\n  TypeInfoColumnsDynArray: TZMetadataColumnDefs;\n  IndexInfoColumnsDynArray: TZMetadataColumnDefs;\n  SequenceColumnsDynArray: TZMetadataColumnDefs;\n  UDTColumnsDynArray: TZMetadataColumnDefs;\n\nimplementation\n\nuses ZVariant, ZCollections, ZMessages;\n\n{ TZAbstractDatabaseInfo }\n\n{**\n  Constructs this object.\n  @param Metadata the interface of the correpsonding database metadata object\n}\nconstructor TZAbstractDatabaseInfo.Create(const Metadata: TZAbstractDatabaseMetadata);\nbegin\n  Create(MetaData, '\"');\nend;\n\n{**\n  Constructs this object.\n  @param Metadata the interface of the correpsonding database metadata object\n  @param IdentifierQuotes\n    What's the string used to quote SQL identifiers?\n    This returns a space \" \" if identifier quoting isn't supported.\n    A JDBC Compliant<sup><font size=-2>TM</font></sup>\n    driver always uses a double quote character.\n}\nconstructor TZAbstractDatabaseInfo.Create(const Metadata: TZAbstractDatabaseMetadata;\n  const IdentifierQuotes: String);\nbegin\n  inherited Create;\n  FMetadata := Metadata;\n  if FMetaData.FUrl.Properties.IndexOfName('identifier_quotes') > -1 then //prevent to loose emty quotes '' !!!\n    FIdentifierQuotes := FMetaData.FUrl.Properties.Values['identifier_quotes']\n  else\n    if IdentifierQuotes = '' then\n      FIdentifierQuotes := '\"'\n    else\n      FIdentifierQuotes := IdentifierQuotes;\nend;\n\n{**\n  Destroys this object and cleanups the memory.\n}\ndestructor TZAbstractDatabaseInfo.Destroy;\nbegin\n  FMetadata := nil;\n  inherited;\nend;\n\n//----------------------------------------------------------------------\n// First, a variety of minor information about the target database.\n\n{**\n  Can all the procedures returned by getProcedures be called by the\n  current user?\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZAbstractDatabaseInfo.AllProceduresAreCallable: Boolean;\nbegin\n  Result := True;\nend;\n\n{**\n  Can all the tables returned by getTable be SELECTed by the\n  current user?\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZAbstractDatabaseInfo.AllTablesAreSelectable: Boolean;\nbegin\n  Result := True;\nend;\n\n{**\n  Is the database in read-only mode?\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZAbstractDatabaseInfo.IsReadOnly: Boolean;\nbegin\n  Result := False;\nend;\n\n{**\n  Are NULL values sorted high?\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZAbstractDatabaseInfo.NullsAreSortedHigh: Boolean;\nbegin\n  Result := False;\nend;\n\n{**\n  Are NULL values sorted low?\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZAbstractDatabaseInfo.NullsAreSortedLow: Boolean;\nbegin\n  Result := False;\nend;\n\n{**\n  Are NULL values sorted at the start regardless of sort order?\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZAbstractDatabaseInfo.NullsAreSortedAtStart: Boolean;\nbegin\n  Result := False;\nend;\n\n{**\n  Are NULL values sorted at the end regardless of sort order?\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZAbstractDatabaseInfo.NullsAreSortedAtEnd: Boolean;\nbegin\n  Result := False;\nend;\n\n{**\n  What's the name of this database product?\n  @return database product name\n}\nfunction TZAbstractDatabaseInfo.GetDatabaseProductName: string;\nbegin\n  Result := '';\nend;\n\n{**\n  What's the version of this database product?\n  @return database version\n}\nfunction TZAbstractDatabaseInfo.GetDatabaseProductVersion: string;\nbegin\n  Result := '';\nend;\n\n{**\n  What's the name of this JDBC driver?\n  @return JDBC driver name\n}\nfunction TZAbstractDatabaseInfo.GetDriverName: string;\nbegin\n  Result := 'Zeos Database Connectivity Driver';\nend;\n\n{**\n  What's the version of this JDBC driver?\n  @return JDBC driver version\n}\nfunction TZAbstractDatabaseInfo.GetDriverVersion: string;\nbegin\n  Result := Format('%d.%d', [GetDriverMajorVersion, GetDriverMinorVersion]);\nend;\n\n{**\n  What's this JDBC driver's major version number?\n  @return JDBC driver major version\n}\nfunction TZAbstractDatabaseInfo.GetDriverMajorVersion: Integer;\nbegin\n  Result := 1;\nend;\n\n{**\n  What's this JDBC driver's minor version number?\n  @return JDBC driver minor version number\n}\nfunction TZAbstractDatabaseInfo.GetDriverMinorVersion: Integer;\nbegin\n  Result := 0;\nend;\n\n{**\n  Returns the server version\n  @return the server version string\n}\nfunction TZAbstractDatabaseInfo.GetServerVersion: string;\nbegin\n  Result := '';\nend;\n\n{**\n  Does the database store tables in a local file?\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZAbstractDatabaseInfo.UsesLocalFiles: Boolean;\nbegin\n  Result := True;\nend;\n\n{**\n  Does the database use a file for each table?\n  @return true if the database uses a local file for each table\n}\nfunction TZAbstractDatabaseInfo.UsesLocalFilePerTable: Boolean;\nbegin\n  Result := False;\nend;\n\n{**\n  Does the database treat mixed case unquoted SQL identifiers as\n  case sensitive and as a result store them in mixed case?\n  A JDBC Compliant<sup><font size=-2>TM</font></sup> driver will always return false.\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZAbstractDatabaseInfo.SupportsMixedCaseIdentifiers: Boolean;\nbegin\n  Result := False;\nend;\n\n{**\n  Does the database treat mixed case unquoted SQL identifiers as\n  case insensitive and store them in upper case?\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZAbstractDatabaseInfo.StoresUpperCaseIdentifiers: Boolean;\nbegin\n  Result := False;\nend;\n\n{**\n  Does the database treat mixed case unquoted SQL identifiers as\n  case insensitive and store them in lower case?\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZAbstractDatabaseInfo.StoresLowerCaseIdentifiers: Boolean;\nbegin\n  Result := False;\nend;\n\n{**\n  Does the database treat mixed case unquoted SQL identifiers as\n  case insensitive and store them in mixed case?\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZAbstractDatabaseInfo.StoresMixedCaseIdentifiers: Boolean;\nbegin\n  Result := True;\nend;\n\n{**\n  Does the database treat mixed case quoted SQL identifiers as\n  case sensitive and as a result store them in mixed case?\n  A JDBC Compliant<sup><font size=-2>TM</font></sup> driver will always return true.\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZAbstractDatabaseInfo.SupportsMixedCaseQuotedIdentifiers: Boolean;\nbegin\n  Result := True;\nend;\n\n{**\n  Does the database treat mixed case quoted SQL identifiers as\n  case insensitive and store them in upper case?\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZAbstractDatabaseInfo.StoresUpperCaseQuotedIdentifiers: Boolean;\nbegin\n  Result := False;\nend;\n\n{**\n  Does the database treat mixed case quoted SQL identifiers as\n  case insensitive and store them in lower case?\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZAbstractDatabaseInfo.StoresLowerCaseQuotedIdentifiers: Boolean;\nbegin\n  Result := False;\nend;\n\n{**\n  Does the database treat mixed case quoted SQL identifiers as\n  case insensitive and store them in mixed case?\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZAbstractDatabaseInfo.StoresMixedCaseQuotedIdentifiers: Boolean;\nbegin\n  Result := False;\nend;\n\n{**\n  What's the string used to quote SQL identifiers?\n  This returns a space \" \" if identifier quoting isn't supported.\n  A JDBC Compliant<sup><font size=-2>TM</font></sup>\n  driver always uses a double quote character.\n  @return the quoting string\n}\nfunction TZAbstractDatabaseInfo.GetIdentifierQuoteString: string;\nbegin\n  Result := FIdentifierQuotes;\nend;\n\n{**\n  Gets a comma-separated list of all a database's SQL keywords\n  that are NOT also SQL92 keywords.\n  @return the list\n}\nfunction TZAbstractDatabaseInfo.GetSQLKeywords: string;\nbegin\n  Result := '';\nend;\n\n{**\n  Gets a comma-separated list of math functions.  These are the\n  X/Open CLI math function names used in the JDBC function escape\n  clause.\n  @return the list\n}\nfunction TZAbstractDatabaseInfo.GetNumericFunctions: string;\nbegin\n  Result := '';\nend;\n\n{**\n  Gets a comma-separated list of string functions.  These are the\n  X/Open CLI string function names used in the JDBC function escape\n  clause.\n  @return the list\n}\nfunction TZAbstractDatabaseInfo.GetStringFunctions: string;\nbegin\n  Result := '';\nend;\n\n{**\n  Gets a comma-separated list of system functions.  These are the\n  X/Open CLI system function names used in the JDBC function escape\n  clause.\n  @return the list\n}\nfunction TZAbstractDatabaseInfo.GetSystemFunctions: string;\nbegin\n  Result := '';\nend;\n\n{**\n  Gets a comma-separated list of time and date functions.\n  @return the list\n}\nfunction TZAbstractDatabaseInfo.GetTimeDateFunctions: string;\nbegin\n  Result := '';\nend;\n\n{**\n  Gets the string that can be used to escape wildcard characters.\n  This is the string that can be used to escape '_' or '%' in\n  the string pattern style catalog search parameters.\n\n  <P>The '_' character represents any single character.\n  <P>The '%' character represents any sequence of zero or\n  more characters.\n\n  @return the string used to escape wildcard characters\n}\nfunction TZAbstractDatabaseInfo.GetSearchStringEscape: string;\nbegin\n  Result := '%';\nend;\n\n{**\n  Gets all the \"extra\" characters that can be used in unquoted\n  identifier names (those beyond a-z, A-Z, 0-9 and _).\n  @return the string containing the extra characters\n}\nfunction TZAbstractDatabaseInfo.GetExtraNameCharacters: string;\nbegin\n  Result := '';\nend;\n\n//--------------------------------------------------------------------\n// Functions describing which features are supported.\n\n{**\n  Is \"ALTER TABLE\" with add column supported?\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZAbstractDatabaseInfo.SupportsAlterTableWithAddColumn: Boolean;\nbegin\n  Result := True;\nend;\n\n{**\n  Is \"ALTER TABLE\" with drop column supported?\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZAbstractDatabaseInfo.SupportsAlterTableWithDropColumn: Boolean;\nbegin\n  Result := True;\nend;\n\n{**\n  Is column aliasing supported?\n\n  <P>If so, the SQL AS clause can be used to provide names for\n  computed columns or to provide alias names for columns as\n  required.\n  A JDBC Compliant<sup><font size=-2>TM</font></sup> driver always returns true.\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZAbstractDatabaseInfo.SupportsColumnAliasing: Boolean;\nbegin\n  Result := True;\nend;\n\n{**\n  Are concatenations between NULL and non-NULL values NULL?\n  For SQL-92 compliance, a JDBC technology-enabled driver will\n  return <code>true</code>.\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZAbstractDatabaseInfo.NullPlusNonNullIsNull: Boolean;\nbegin\n  Result := True;\nend;\n\n{**\n  Is the CONVERT function between SQL types supported?\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZAbstractDatabaseInfo.SupportsConvert: Boolean;\nbegin\n  Result := False;\nend;\n\n{**\n  Is CONVERT between the given SQL types supported?\n  @param fromType the type to convert from\n  @param toType the type to convert to\n  @return <code>true</code> if so; <code>false</code> otherwise\n  @see Types\n}\nfunction TZAbstractDatabaseInfo.SupportsConvertForTypes(\n  FromType: TZSQLType; ToType: TZSQLType): Boolean;\nbegin\n  Result := False;\nend;\n\n{**\n  Are table correlation names supported?\n  A JDBC Compliant<sup><font size=-2>TM</font></sup> driver always returns true.\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZAbstractDatabaseInfo.SupportsTableCorrelationNames: Boolean;\nbegin\n  Result := True;\nend;\n\n{**\n  If table correlation names are supported, are they restricted\n  to be different from the names of the tables?\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZAbstractDatabaseInfo.SupportsDifferentTableCorrelationNames: Boolean;\nbegin\n  Result := False;\nend;\n\n{**\n  Are expressions in \"ORDER BY\" lists supported?\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZAbstractDatabaseInfo.SupportsExpressionsInOrderBy: Boolean;\nbegin\n  Result := True;\nend;\n\n{**\n  Can an \"ORDER BY\" clause use columns not in the SELECT statement?\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZAbstractDatabaseInfo.SupportsOrderByUnrelated: Boolean;\nbegin\n  Result := True;\nend;\n\n{**\n  Is some form of \"GROUP BY\" clause supported?\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZAbstractDatabaseInfo.SupportsGroupBy: Boolean;\nbegin\n  Result := True;\nend;\n\n{**\n  Can a \"GROUP BY\" clause use columns not in the SELECT?\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZAbstractDatabaseInfo.SupportsGroupByUnrelated: Boolean;\nbegin\n  Result := True;\nend;\n\n{**\n  Can a \"GROUP BY\" clause add columns not in the SELECT\n  provided it specifies all the columns in the SELECT?\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZAbstractDatabaseInfo.SupportsGroupByBeyondSelect: Boolean;\nbegin\n  Result := False;\nend;\n\n{**\n  Is the escape character in \"LIKE\" clauses supported?\n  A JDBC Compliant<sup><font size=-2>TM</font></sup> driver always returns true.\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZAbstractDatabaseInfo.SupportsLikeEscapeClause: Boolean;\nbegin\n  Result := True;\nend;\n\n{**\n  Are multiple <code>ResultSet</code> from a single execute supported?\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZAbstractDatabaseInfo.SupportsMultipleResultSets: Boolean;\nbegin\n  Result := True;\nend;\n\n{**\n  Can we have multiple transactions open at once (on different\n  connections)?\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZAbstractDatabaseInfo.SupportsMultipleTransactions: Boolean;\nbegin\n  Result := True;\nend;\n\n{**\n  Can columns be defined as non-nullable?\n  A JDBC Compliant<sup><font size=-2>TM</font></sup> driver always returns true.\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZAbstractDatabaseInfo.SupportsNonNullableColumns: Boolean;\nbegin\n  Result := True;\nend;\n\n{**\n  Is the ODBC Minimum SQL grammar supported?\n  All JDBC Compliant<sup><font size=-2>TM</font></sup> drivers must return true.\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZAbstractDatabaseInfo.SupportsMinimumSQLGrammar: Boolean;\nbegin\n  Result := True;\nend;\n\n{**\n  Is the ODBC Core SQL grammar supported?\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZAbstractDatabaseInfo.SupportsCoreSQLGrammar: Boolean;\nbegin\n  Result := True;\nend;\n\n{**\n  Is the ODBC Extended SQL grammar supported?\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZAbstractDatabaseInfo.SupportsExtendedSQLGrammar: Boolean;\nbegin\n  Result := True;\nend;\n\n{**\n  Is the ANSI92 entry level SQL grammar supported?\n  All JDBC Compliant<sup><font size=-2>TM</font></sup> drivers must return true.\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZAbstractDatabaseInfo.SupportsANSI92EntryLevelSQL: Boolean;\nbegin\n  Result := True;\nend;\n\n{**\n  Is the ANSI92 intermediate SQL grammar supported?\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZAbstractDatabaseInfo.SupportsANSI92IntermediateSQL: Boolean;\nbegin\n  Result := True;\nend;\n\n{**\n  Is the ANSI92 full SQL grammar supported?\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZAbstractDatabaseInfo.SupportsANSI92FullSQL: Boolean;\nbegin\n  Result := True;\nend;\n\n{**\n  Is the SQL Integrity Enhancement Facility supported?\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZAbstractDatabaseInfo.SupportsIntegrityEnhancementFacility: Boolean;\nbegin\n  Result := False;\nend;\n\n{**\n  Is some form of outer join supported?\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZAbstractDatabaseInfo.SupportsOuterJoins: Boolean;\nbegin\n  Result := True;\nend;\n\n{**\n  Are full nested outer joins supported?\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZAbstractDatabaseInfo.SupportsFullOuterJoins: Boolean;\nbegin\n  Result := True;\nend;\n\n{**\n  Is there limited support for outer joins?  (This will be true\n  if supportFullOuterJoins is true.)\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZAbstractDatabaseInfo.SupportsLimitedOuterJoins: Boolean;\nbegin\n  Result := True;\nend;\n\n{**\n  What's the database vendor's preferred term for \"schema\"?\n  @return the vendor term\n}\nfunction TZAbstractDatabaseInfo.GetSchemaTerm: string;\nbegin\n  Result := 'Schema';\nend;\n\n{**\n  What's the database vendor's preferred term for \"procedure\"?\n  @return the vendor term\n}\nfunction TZAbstractDatabaseInfo.GetProcedureTerm: string;\nbegin\n  Result := 'Procedure';\nend;\n\n{**\n  What's the database vendor's preferred term for \"catalog\"?\n  @return the vendor term\n}\nfunction TZAbstractDatabaseInfo.GetCatalogTerm: string;\nbegin\n  Result := 'Catalog';\nend;\n\n{**\n  Does a catalog appear at the start of a qualified table name?\n  (Otherwise it appears at the end)\n  @return true if it appears at the start\n}\nfunction TZAbstractDatabaseInfo.IsCatalogAtStart: Boolean;\nbegin\n  Result := False;\nend;\n\n{**\n  What's the separator between catalog and table name?\n  @return the separator string\n}\nfunction TZAbstractDatabaseInfo.GetCatalogSeparator: string;\nbegin\n  Result := '.';\nend;\n\n{**\n  Can a schema name be used in a data manipulation statement?\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZAbstractDatabaseInfo.SupportsSchemasInDataManipulation: Boolean;\nbegin\n  Result := False;\nend;\n\n{**\n  Can a schema name be used in a procedure call statement?\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZAbstractDatabaseInfo.SupportsSchemasInProcedureCalls: Boolean;\nbegin\n  Result := False;\nend;\n\n{**\n  Can a schema name be used in a table definition statement?\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZAbstractDatabaseInfo.SupportsSchemasInTableDefinitions: Boolean;\nbegin\n  Result := False;\nend;\n\n{**\n  Can a schema name be used in an index definition statement?\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZAbstractDatabaseInfo.SupportsSchemasInIndexDefinitions: Boolean;\nbegin\n  Result := False;\nend;\n\n{**\n  Can a schema name be used in a privilege definition statement?\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZAbstractDatabaseInfo.SupportsSchemasInPrivilegeDefinitions: Boolean;\nbegin\n  Result := False;\nend;\n\n{**\n  Can a catalog name be used in a data manipulation statement?\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZAbstractDatabaseInfo.SupportsCatalogsInDataManipulation: Boolean;\nbegin\n  Result := False;\nend;\n\n{**\n  Can a catalog name be used in a procedure call statement?\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZAbstractDatabaseInfo.SupportsCatalogsInProcedureCalls: Boolean;\nbegin\n  Result := False;\nend;\n\n{**\n  Can a catalog name be used in a table definition statement?\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZAbstractDatabaseInfo.SupportsCatalogsInTableDefinitions: Boolean;\nbegin\n  Result := False;\nend;\n\n{**\n  Can a catalog name be used in an index definition statement?\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZAbstractDatabaseInfo.SupportsCatalogsInIndexDefinitions: Boolean;\nbegin\n  Result := False;\nend;\n\n{**\n  Can a catalog name be used in a privilege definition statement?\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZAbstractDatabaseInfo.SupportsCatalogsInPrivilegeDefinitions: Boolean;\nbegin\n  Result := False;\nend;\n\n{**\n  Can a stored procedure have an additional overload suffix?\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZAbstractDatabaseInfo.SupportsOverloadPrefixInStoredProcedureName: Boolean;\nbegin\n  Result := False;\nend;\n\n{**\n  Is positioned DELETE supported?\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZAbstractDatabaseInfo.SupportsPositionedDelete: Boolean;\nbegin\n  Result := False;\nend;\n\n{**\n  Is positioned UPDATE supported?\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZAbstractDatabaseInfo.SupportsPositionedUpdate: Boolean;\nbegin\n  Result := False;\nend;\n\n{**\n  Is SELECT for UPDATE supported?\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZAbstractDatabaseInfo.SupportsSelectForUpdate: Boolean;\nbegin\n  Result := False;\nend;\n\n{**\n  Are stored procedure calls using the stored procedure escape\n  syntax supported?\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZAbstractDatabaseInfo.SupportsStoredProcedures: Boolean;\nbegin\n  Result := False;\nend;\n\n{**\n  Are subqueries in comparison expressions supported?\n  A JDBC Compliant<sup><font size=-2>TM</font></sup> driver always returns true.\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZAbstractDatabaseInfo.SupportsSubqueriesInComparisons: Boolean;\nbegin\n  Result := False;\nend;\n\n{**\n  Are subqueries in 'exists' expressions supported?\n  A JDBC Compliant<sup><font size=-2>TM</font></sup> driver always returns true.\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZAbstractDatabaseInfo.SupportsSubqueriesInExists: Boolean;\nbegin\n  Result := False;\nend;\n\n{**\n  Are subqueries in 'in' statements supported?\n  A JDBC Compliant<sup><font size=-2>TM</font></sup> driver always returns true.\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZAbstractDatabaseInfo.SupportsSubqueriesInIns: Boolean;\nbegin\n  Result := False;\nend;\n\n{**\n  Are subqueries in quantified expressions supported?\n  A JDBC Compliant<sup><font size=-2>TM</font></sup> driver always returns true.\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZAbstractDatabaseInfo.SupportsSubqueriesInQuantifieds: Boolean;\nbegin\n  Result := False;\nend;\n\n{**\n  Are correlated subqueries supported?\n  A JDBC Compliant<sup><font size=-2>TM</font></sup> driver always returns true.\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZAbstractDatabaseInfo.SupportsCorrelatedSubqueries: Boolean;\nbegin\n  Result := False;\nend;\n\n{**\n  Is SQL UNION supported?\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZAbstractDatabaseInfo.SupportsUnion: Boolean;\nbegin\n  Result := False;\nend;\n\n{**\n  Is SQL UNION ALL supported?\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZAbstractDatabaseInfo.SupportsUnionAll: Boolean;\nbegin\n  Result := False;\nend;\n\n{**\n  Can cursors remain open across commits?\n  @return <code>true</code> if cursors always remain open;\n        <code>false</code> if they might not remain open\n}\nfunction TZAbstractDatabaseInfo.SupportsOpenCursorsAcrossCommit: Boolean;\nbegin\n  Result := False;\nend;\n\n{**\n  Can cursors remain open across rollbacks?\n  @return <code>true</code> if cursors always remain open;\n        <code>false</code> if they might not remain open\n}\nfunction TZAbstractDatabaseInfo.SupportsOpenCursorsAcrossRollback: Boolean;\nbegin\n  Result := False;\nend;\n\n{**\n  Can statements remain open across commits?\n  @return <code>true</code> if statements always remain open;\n        <code>false</code> if they might not remain open\n}\nfunction TZAbstractDatabaseInfo.SupportsOpenStatementsAcrossCommit: Boolean;\nbegin\n  Result := True;\nend;\n\n{**\n  Can statements remain open across rollbacks?\n  @return <code>true</code> if statements always remain open;\n        <code>false</code> if they might not remain open\n}\nfunction TZAbstractDatabaseInfo.SupportsOpenStatementsAcrossRollback: Boolean;\nbegin\n  Result := True;\nend;\n\n//----------------------------------------------------------------------\n// The following group of methods exposes various limitations\n// based on the target database with the current driver.\n// Unless otherwise specified, a result of zero means there is no\n// limit, or the limit is not known.\n\n{**\n  How many hex characters can you have in an inline binary literal?\n  @return max binary literal length in hex characters;\n       a result of zero means that there is no limit or the limit is not known\n}\nfunction TZAbstractDatabaseInfo.GetMaxBinaryLiteralLength: Integer;\nbegin\n  Result := 0;\nend;\n\n{**\n  What's the max length for a character literal?\n  @return max literal length;\n       a result of zero means that there is no limit or the limit is not known\n}\nfunction TZAbstractDatabaseInfo.GetMaxCharLiteralLength: Integer;\nbegin\n  Result := 0;\nend;\n\n{**\n  What's the limit on column name length?\n  @return max column name length;\n       a result of zero means that there is no limit or the limit is not known\n}\nfunction TZAbstractDatabaseInfo.GetMaxColumnNameLength: Integer;\nbegin\n  Result := 0;\nend;\n\n{**\n  What's the maximum number of columns in a \"GROUP BY\" clause?\n  @return max number of columns;\n       a result of zero means that there is no limit or the limit is not known\n}\nfunction TZAbstractDatabaseInfo.GetMaxColumnsInGroupBy: Integer;\nbegin\n  Result := 0;\nend;\n\n{**\n  What's the maximum number of columns allowed in an index?\n  @return max number of columns;\n       a result of zero means that there is no limit or the limit is not known\n}\nfunction TZAbstractDatabaseInfo.GetMaxColumnsInIndex: Integer;\nbegin\n  Result := 0;\nend;\n\n{**\n  What's the maximum number of columns in an \"ORDER BY\" clause?\n  @return max number of columns;\n       a result of zero means that there is no limit or the limit is not known\n}\nfunction TZAbstractDatabaseInfo.GetMaxColumnsInOrderBy: Integer;\nbegin\n  Result := 0;\nend;\n\n{**\n  What's the maximum number of columns in a \"SELECT\" list?\n  @return max number of columns;\n       a result of zero means that there is no limit or the limit is not known\n}\nfunction TZAbstractDatabaseInfo.GetMaxColumnsInSelect: Integer;\nbegin\n  Result := 0;\nend;\n\n{**\n  What's the maximum number of columns in a table?\n  @return max number of columns;\n       a result of zero means that there is no limit or the limit is not known\n}\nfunction TZAbstractDatabaseInfo.GetMaxColumnsInTable: Integer;\nbegin\n  Result := 0;\nend;\n\n{**\n  How many active connections can we have at a time to this database?\n  @return max number of active connections;\n       a result of zero means that there is no limit or the limit is not known\n}\nfunction TZAbstractDatabaseInfo.GetMaxConnections: Integer;\nbegin\n  Result := 0;\nend;\n\n{**\n  What's the maximum cursor name length?\n  @return max cursor name length in bytes;\n       a result of zero means that there is no limit or the limit is not known\n}\nfunction TZAbstractDatabaseInfo.GetMaxCursorNameLength: Integer;\nbegin\n  Result := 0;\nend;\n\n{**\n  Retrieves the maximum number of bytes for an index, including all\n  of the parts of the index.\n  @return max index length in bytes, which includes the composite of all\n   the constituent parts of the index;\n   a result of zero means that there is no limit or the limit is not known\n}\nfunction TZAbstractDatabaseInfo.GetMaxIndexLength: Integer;\nbegin\n  Result := 0;\nend;\n\n{**\n  What's the maximum length allowed for a schema name?\n  @return max name length in bytes;\n       a result of zero means that there is no limit or the limit is not known\n}\nfunction TZAbstractDatabaseInfo.GetMaxSchemaNameLength: Integer;\nbegin\n  Result := 0;\nend;\n\n{**\n  What's the maximum length of a procedure name?\n  @return max name length in bytes;\n       a result of zero means that there is no limit or the limit is not known\n}\nfunction TZAbstractDatabaseInfo.GetMaxProcedureNameLength: Integer;\nbegin\n  Result := 0;\nend;\n\n{**\n  What's the maximum length of a catalog name?\n  @return max name length in bytes;\n       a result of zero means that there is no limit or the limit is not known\n}\nfunction TZAbstractDatabaseInfo.GetMaxCatalogNameLength: Integer;\nbegin\n  Result := 0;\nend;\n\n{**\n  What's the maximum length of a single row?\n  @return max row size in bytes;\n       a result of zero means that there is no limit or the limit is not known\n}\nfunction TZAbstractDatabaseInfo.GetMaxRowSize: Integer;\nbegin\n  Result := 0;\nend;\n\n{**\n  Did getMaxRowSize() include LONGVARCHAR and LONGVARBINARY\n  blobs?\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZAbstractDatabaseInfo.DoesMaxRowSizeIncludeBlobs: Boolean;\nbegin\n  Result := True;\nend;\n\n{**\n  What's the maximum length of an SQL statement?\n  @return max length in bytes;\n       a result of zero means that there is no limit or the limit is not known\n}\nfunction TZAbstractDatabaseInfo.GetMaxStatementLength: Integer;\nbegin\n  Result := 0;\nend;\n\n{**\n  How many active statements can we have open at one time to this\n  database?\n  @return the maximum number of statements that can be open at one time;\n       a result of zero means that there is no limit or the limit is not known\n}\nfunction TZAbstractDatabaseInfo.GetMaxStatements: Integer;\nbegin\n  Result := 0;\nend;\n\n{**\n  What's the maximum length of a table name?\n  @return max name length in bytes;\n       a result of zero means that there is no limit or the limit is not known\n}\nfunction TZAbstractDatabaseInfo.GetMaxTableNameLength: Integer;\nbegin\n  Result := 0;\nend;\n\n{**\n  What's the maximum number of tables in a SELECT statement?\n  @return the maximum number of tables allowed in a SELECT statement;\n       a result of zero means that there is no limit or the limit is not known\n}\nfunction TZAbstractDatabaseInfo.GetMaxTablesInSelect: Integer;\nbegin\n  Result := 0;\nend;\n\n{**\n  What's the maximum length of a user name?\n  @return max user name length  in bytes;\n       a result of zero means that there is no limit or the limit is not known\n}\nfunction TZAbstractDatabaseInfo.GetMaxUserNameLength: Integer;\nbegin\n  Result := 0;\nend;\n\n//----------------------------------------------------------------------\n\n{**\n  What's the database's default transaction isolation level?  The\n  values are defined in <code>java.sql.Connection</code>.\n  @return the default isolation level\n  @see Connection\n}\nfunction TZAbstractDatabaseInfo.GetDefaultTransactionIsolation:\n  TZTransactIsolationLevel;\nbegin\n  Result := tiReadCommitted;\nend;\n\n{**\n  Are transactions supported? If not, invoking the method\n  <code>commit</code> is a noop and the isolation level is TRANSACTION_NONE.\n  @return <code>true</code> if transactions are supported; <code>false</code> otherwise\n}\nfunction TZAbstractDatabaseInfo.SupportsTransactions: Boolean;\nbegin\n  Result := True;\nend;\n\n{**\n  Does this database support the given transaction isolation level?\n  @param level the values are defined in <code>java.sql.Connection</code>\n  @return <code>true</code> if so; <code>false</code> otherwise\n  @see Connection\n}\nfunction TZAbstractDatabaseInfo.SupportsTransactionIsolationLevel(\n  Level: TZTransactIsolationLevel): Boolean;\nbegin\n  Result := True;\nend;\n\n{**\n  Are both data definition and data manipulation statements\n  within a transaction supported?\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZAbstractDatabaseInfo.\n  SupportsDataDefinitionAndDataManipulationTransactions: Boolean;\nbegin\n  Result := True;\nend;\n\n{**\n  Are only data manipulation statements within a transaction\n  supported?\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZAbstractDatabaseInfo.\n  SupportsDataManipulationTransactionsOnly: Boolean;\nbegin\n  Result := False;\nend;\n\n{**\n  Does a data definition statement within a transaction force the\n  transaction to commit?\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZAbstractDatabaseInfo.DataDefinitionCausesTransactionCommit: Boolean;\nbegin\n  Result := True;\nend;\n\n{**\n  Is a data definition statement within a transaction ignored?\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZAbstractDatabaseInfo.DataDefinitionIgnoredInTransactions: Boolean;\nbegin\n  Result := False;\nend;\n\n{**\n  Does the database support the given result set type?\n  @param type defined in <code>java.sql.ResultSet</code>\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZAbstractDatabaseInfo.SupportsResultSetType(\n  _Type: TZResultSetType): Boolean;\nbegin\n  Result := True;\nend;\n\n{**\n  Does the database support the concurrency type in combination\n  with the given result set type?\n\n  @param type defined in <code>java.sql.ResultSet</code>\n  @param concurrency type defined in <code>java.sql.ResultSet</code>\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZAbstractDatabaseInfo.SupportsResultSetConcurrency(\n  _Type: TZResultSetType; Concurrency: TZResultSetConcurrency): Boolean;\nbegin\n  Result := True;\nend;\n\n{**\n  Indicates whether the driver supports batch updates.\n  @return true if the driver supports batch updates; false otherwise\n}\nfunction TZAbstractDatabaseInfo.SupportsBatchUpdates: Boolean;\nbegin\n  Result := True;\nend;\n\n{**\n  Does the Database or Actual Version understand non escaped search strings?\n  @return <code>true</code> if the DataBase does understand non escaped\n  search strings\n}\nfunction TZAbstractDatabaseInfo.SupportsNonEscapedSearchStrings: Boolean;\nbegin\n  Result := False;\nend;\n\n{**\n  Does the Database support updating auto incremental fields?\n  @return <code>true</code> if the DataBase allows it.\n}\nfunction TZAbstractDatabaseInfo.SupportsUpdateAutoIncrementFields: Boolean;\nbegin\n  Result := True;\nend;\n\n{ TZAbstractDatabaseMetadata }\n\n{**\n  Constructs this object and assignes the main properties.\n  @param Connection a database connection object.\n  @param Url a database connection url string.\n}\nconstructor TZAbstractDatabaseMetadata.Create(Connection: TZAbstractConnection;\n  const Url: TZURL);\nbegin\n  inherited Create(Connection as IZConnection);\n  FIC := Self.GetIdentifierConvertor;\n  FConnection := Pointer(Connection as IZConnection);\n  FUrl := Url;\n  FCachedResultSets := TZHashMap.Create;\n  FDatabaseInfo := CreateDatabaseInfo;\n  FDatabase := Url.Database;\n  FConSettings := IZConnection(FConnection).GetConSettings;\n  FillWildcards;\nend;\n\nfunction TZAbstractDatabaseMetadata.GetInfo: TStrings;\nbegin\n  Result := FURL.Properties;\nend;\n\nfunction TZAbstractDatabaseMetadata.GetURLString: String;\nbegin\n  Result := FURL.URL;\nend;\n\n{**\n   Remove escapes from pattren string\n   @param Pattern a sql pattern\n   @return string without escapes\n}\nfunction TZAbstractDatabaseMetadata.StripEscape(const Pattern: string): string;\nvar\n  I: Integer;\n  PreviousChar: Char;\n  EscapeChar: string;\nbegin\n  PreviousChar := #0;\n  Result := '';\n  EscapeChar := GetDatabaseInfo.GetSearchStringEscape;\n  for I := 1 to Length(Pattern) do\n  begin\n    if (Pattern[i] <> EscapeChar) then\n    begin\n      Result := Result + Pattern[I];\n      PreviousChar := Pattern[I];\n    end\n    else\n    begin\n      if (PreviousChar = EscapeChar) then\n      begin\n        Result := Result + Pattern[I];\n        PreviousChar := #0;\n      end\n      else\n        PreviousChar := Pattern[i];\n    end;\n  end;\nend;\n\n{**\n   Check if pattern does not contain wildcards\n   @param Pattern a sql pattern\n   @return if pattern contain wildcards return true otherwise false\n}\nfunction TZAbstractDatabaseMetadata.HasNoWildcards(const Pattern: string\n  ): boolean;\nvar\n  I: Integer;\n  PreviousCharWasEscape: Boolean;\n  EscapeChar,PreviousChar: Char;\n  WildcardsSet: TZWildcardsSet;\nbegin\n  Result := False;\n  PreviousChar := #0;\n  PreviousCharWasEscape := False;\n  EscapeChar := Char(GetDatabaseInfo.GetSearchStringEscape[1]);\n  WildcardsSet := GetWildcardsSet;\n  for I := 1 to Length(Pattern) do\n  begin\n    if (not PreviousCharWasEscape) and CharInset(Pattern[I], WildcardsSet) then\n     Exit;\n\n    PreviousCharWasEscape := (Pattern[I] = EscapeChar) and (PreviousChar <> EscapeChar);\n    if (PreviousCharWasEscape) and (Pattern[I] = EscapeChar) then\n      PreviousChar := #0\n    else\n      PreviousChar := Pattern[I];\n  end;\n  Result := True;\nend;\n\nfunction TZAbstractDatabaseMetadata.EscapeString(const S: string): string;\nbegin\n  Result := '''' + S + '''';\nend;\n\nfunction TZAbstractDatabaseMetadata.DecomposeObjectString(const S: String): String;\nbegin\n  if IC.IsQuoted(s) then\n    Result := IC.ExtractQuote(s)\n  else\n    Result := s;\nend;\n\n{**  Destroys this object and cleanups the memory.}\ndestructor TZAbstractDatabaseMetadata.Destroy;\nbegin\n  FIC := nil;\n  FUrl := nil;\n  FCachedResultSets.Clear;\n  FCachedResultSets := nil;\n  FDatabaseInfo := nil;\n\n  inherited Destroy;\nend;\n\n{**\n  Constructs a database information object and returns the interface to it. Used\n  internally by the constructor.\n  @return the database information object interface\n}\nfunction TZAbstractDatabaseMetadata.CreateDatabaseInfo: IZDatabaseInfo;\nbegin\n  Result := TZAbstractDatabaseInfo.Create(Self);\nend;\n\n{**\n  Creates and returns a statement object.\n  @return the statement object\n}\nfunction TZAbstractDatabaseMetadata.GetStatement: IZSTatement;\nbegin\n  Result := GetConnection.CreateStatement;\nend;\n\n{**\n  Retrieves the connection that produced this metadata object.\n  @return the connection that produced this metadata object\n}\nfunction TZAbstractDatabaseMetadata.GetConnection: IZConnection;\nbegin\n  Result := IZConnection(FConnection);\nend;\n\n{**\n  Constructs a virtual result set object.\n  @param ColumnsDefs an array of column definition objects.\n  @return a created result set.\n}\nfunction TZAbstractDatabaseMetadata.ConstructVirtualResultSet(\n  ColumnsDefs: TZMetadataColumnDefs): IZVirtualResultSet;\nvar\n  I: Integer;\n  ColumnInfo: TZColumnInfo;\n  ColumnsInfo: TObjectList;\nbegin\n  ColumnsInfo := TObjectList.Create(True);\n  try\n    for I := 0 to High(ColumnsDefs) do\n    begin\n      ColumnInfo := TZColumnInfo.Create;\n      with ColumnInfo do\n      begin\n        ColumnLabel := ColumnsDefs[I].Name;\n        ColumnType := ColumnsDefs[I].SQLType;\n        ColumnDisplaySize := ColumnsDefs[I].Length;\n        Precision := ColumnsDefs[I].Length;\n      end;\n      ColumnsInfo.Add(ColumnInfo);\n    end;\n\n    Result := TZVirtualResultSet.CreateWithColumns(ColumnsInfo, '',\n      IZConnection(FConnection).GetConSettings);\n    with Result do\n    begin\n      SetType(rtScrollInsensitive);\n      SetConcurrency(rcUpdatable);\n    end;\n  finally\n    ColumnsInfo.Free;\n  end;\nend;\n\n{**\n  Clears all cached metadata.\n}\nprocedure TZAbstractDatabaseMetadata.ClearCache;\nbegin\n  FCachedResultSets.Clear;\nend;\n\n{**\n  Clears specific cached metadata.\n}\nprocedure TZAbstractDatabaseMetadata.ClearCache(const Key: string);\nvar\n  TempKey: IZAnyValue;\nbegin\n  TempKey := TZAnyValue.CreateWithString(Key);\n  FCachedResultSets.Remove(TempKey);\nend;\n\n{**\n  Adds resultset to the internal cache.\n  @param Key a resultset unique key value.\n  @param ResultSet a resultset interface.\n}\nprocedure TZAbstractDatabaseMetadata.AddResultSetToCache(const Key: string;\n  ResultSet: IZResultSet);\nvar\n  TempKey: IZAnyValue;\nbegin\n  TempKey := TZAnyValue.CreateWithString(Key);\n  FCachedResultSets.Put(TempKey, CloneCachedResultSet(ResultSet));\nend;\n\n{**\n  Gets a resultset interface from the internal cache by key.\n  @param Key a resultset unique key value.\n  @returns a cached resultset interface or <code>nil</code> otherwise.\n}\nfunction TZAbstractDatabaseMetadata.GetResultSetFromCache(\n  const Key: string): IZResultSet;\nvar\n  TempKey: IZAnyValue;\nbegin\n  TempKey := TZAnyValue.CreateWithString(Key);\n  Result := FCachedResultSets.Get(TempKey) as IZResultSet;\n  if Result <> nil then\n    Result := CloneCachedResultSet(Result);\nend;\n\n{**\n  Copies on result set to another one from the current position.\n  @param SrcResultSet a source result set.\n  @param DestResultSet a destination result set.\n  @returns a destination result set.\n}\nfunction TZAbstractDatabaseMetadata.CopyToVirtualResultSet(\n  SrcResultSet: IZResultSet; DestResultSet: IZVirtualResultSet):\n  IZVirtualResultSet;\nvar\n  I: Integer;\n  Metadata: IZResultSetMetadata;\nbegin\n  DestResultSet.SetType(rtScrollInsensitive);\n  DestResultSet.SetConcurrency(rcUpdatable);\n\n  Metadata := SrcResultSet.GetMetadata;\n  while SrcResultSet.Next do\n  begin\n    DestResultSet.MoveToInsertRow;\n    for I := 1 to Metadata.GetColumnCount do\n    begin\n      case Metadata.GetColumnType(I) of\n        stBoolean:\n          DestResultSet.UpdateBoolean(I, SrcResultSet.GetBoolean(I));\n        stByte:\n          DestResultSet.UpdateByte(I, SrcResultSet.GetByte(I));\n        stShort:\n          DestResultSet.UpdateShort(I, SrcResultSet.GetShort(I));\n        stInteger:\n          DestResultSet.UpdateInt(I, SrcResultSet.GetInt(I));\n        stLong:\n          DestResultSet.UpdateLong(I, SrcResultSet.GetLong(I));\n        stFloat:\n          DestResultSet.UpdateFloat(I, SrcResultSet.GetFloat(I));\n        stDouble:\n          DestResultSet.UpdateDouble(I, SrcResultSet.GetDouble(I));\n        stBigDecimal:\n          DestResultSet.UpdateBigDecimal(I, SrcResultSet.GetBigDecimal(I));\n        stString:\n          DestResultSet.UpdateString(I, SrcResultSet.GetString(I));\n        stUnicodeString:\n          DestResultSet.UpdateUnicodeString(I, SrcResultSet.GetUnicodeString(I));\n        stBytes:\n          DestResultSet.UpdateBytes(I, SrcResultSet.GetBytes(I));\n        stDate:\n          DestResultSet.UpdateDate(I, SrcResultSet.GetDate(I));\n        stTime:\n          DestResultSet.UpdateTime(I, SrcResultSet.GetTime(I));\n        stTimestamp:\n          DestResultSet.UpdateTimestamp(I, SrcResultSet.GetTimestamp(I));\n        stAsciiStream,\n        stUnicodeStream,\n        stBinaryStream:\n          DestResultSet.UpdateString(I, SrcResultSet.GetString(I));\n      end;\n      if SrcResultSet.WasNull then\n        DestResultSet.UpdateNull(I);\n    end;\n    DestResultSet.InsertRow;\n  end;\n\n  DestResultSet.BeforeFirst;\n  DestResultSet.SetConcurrency(rcReadOnly);\n  Result := DestResultSet;\nend;\n\n{**\n  Clones the cached resultset.\n  @param ResultSet the resultset to be cloned.\n  @returns the clone of the specified resultset.\n}\nfunction TZAbstractDatabaseMetadata.CloneCachedResultSet(\n  ResultSet: IZResultSet): IZResultSet;\nvar\n  I: Integer;\n  Metadata: IZResultSetMetadata;\n  ColumnInfo: TZColumnInfo;\n  ColumnsInfo: TObjectList;\nbegin\n  Result := nil;\n  Metadata := ResultSet.GetMetadata;\n  ColumnsInfo := TObjectList.Create(True);\n  try\n    for I := 1 to Metadata.GetColumnCount do\n    begin\n      ColumnInfo := TZColumnInfo.Create;\n      with ColumnInfo do\n      begin\n        ColumnLabel := Metadata.GetColumnLabel(I);\n        ColumnType := Metadata.GetColumnType(I);\n        ColumnDisplaySize := Metadata.GetPrecision(I);\n        Precision := Metadata.GetPrecision(I);\n      end;\n      ColumnsInfo.Add(ColumnInfo);\n    end;\n\n    ResultSet.BeforeFirst;\n    Result := CopyToVirtualResultSet(ResultSet,\n      TZVirtualResultSet.CreateWithColumns(ColumnsInfo, '',\n        IZConnection(Self.FConnection).GetConSettings));\n    ResultSet.BeforeFirst;\n  finally\n    ColumnsInfo.Free;\n  end;\nend;\n\n{**\n   Takes a name patternand column name and retuen an appropriate SQL clause\n    @param Pattern a sql pattren\n    @parma Column a sql column name\n    @return processed string for query\n}\nfunction TZAbstractDatabaseMetadata.ConstructNameCondition(Pattern: string;\n  Column: string): string;\nconst\n  Spaces = '';\nvar\n  WorkPattern: string;\nbegin\n  Result := '';\n  if (Length(Pattern) > 2 * 31) then\n    raise EZSQLException.Create(SPattern2Long);\n\n  if (Pattern = '%') or (Pattern = '') then\n     Exit;\n  WorkPattern:=NormalizePatternCase(Pattern);\n  if HasNoWildcards(WorkPattern) then\n  begin\n    WorkPattern := StripEscape(WorkPattern);\n    Result := Format('%s = %s', [Column, EscapeString(WorkPattern)]);\n  end\n  else\n  begin\n    Result := Format('%s like %s',\n      [Column, EscapeString(WorkPattern+'%')]);\n  end;\nend;\n\n{**\n  What's the url for this database?\n  @return the url or null if it cannot be generated\n}\nfunction TZAbstractDatabaseMetadata.GetURL: string;\nbegin\n  Result := GetURLString;\nend;\n\n{**\n  What's our user name as known to the database?\n  @return our database user name\n}\nfunction TZAbstractDatabaseMetadata.GetUserName: string;\nbegin\n  Result := FURL.UserName;\nend;\n\n{**\n  Returns general information about the database (version, capabilities,\n  policies, etc).\n  @return the database information object interface.\n}\nfunction TZAbstractDatabaseMetadata.GetDatabaseInfo: IZDatabaseInfo;\nbegin\n  Result := FDatabaseInfo;\nend;\n\n{**\n  Gets a description of the stored procedures available in a\n  catalog.\n\n  <P>Only procedure descriptions matching the schema and\n  procedure name criteria are returned.  They are ordered by\n  PROCEDURE_SCHEM, and PROCEDURE_NAME.\n\n  <P>Each procedure description has the the following columns:\n   <OL>\n \t<LI><B>PROCEDURE_CAT</B> String => procedure catalog (may be null)\n \t<LI><B>PROCEDURE_SCHEM</B> String => procedure schema (may be null)\n \t<LI><B>PROCEDURE_NAME</B> String => procedure name\n   <LI> reserved for future use\n   <LI> reserved for future use\n   <LI> reserved for future use\n \t<LI><B>REMARKS</B> String => explanatory comment on the procedure\n \t<LI><B>PROCEDURE_TYPE</B> short => kind of procedure:\n       <UL>\n       <LI> procedureResultUnknown - May return a result\n       <LI> procedureNoResult - Does not return a result\n       <LI> procedureReturnsResult - Returns a result\n       </UL>\n   </OL>\n\n  @param catalog a catalog name; \"\" retrieves those without a\n  catalog; null means drop catalog name from the selection criteria\n  @param schemaPattern a schema name pattern; \"\" retrieves those\n  without a schema\n  @param procedureNamePattern a procedure name pattern\n  @return <code>ResultSet</code> - each row is a procedure description\n  @see #getSearchStringEscape\n}\nfunction TZAbstractDatabaseMetadata.GetProcedures(const Catalog: string;\n  const SchemaPattern: string; const ProcedureNamePattern: string): IZResultSet;\nvar\n  Key: string;\nbegin\n  if not GetConnection.UseMetadata then\n  begin\n    Result := ConstructVirtualResultSet(ProceduresColumnsDynArray);\n    exit;\n  end;\n\n  Key := GetProceduresCacheKey(Catalog, SchemaPattern, ProcedureNamePattern);\n\n  Result := GetResultSetFromCache(Key);\n  if Result = nil then\n  begin\n    Result := UncachedGetProcedures(Catalog, SchemaPattern, ProcedureNamePattern);\n    AddResultSetToCache(Key, Result);\n  end;\nend;\n\n{**\n  Gets a description of the stored procedures available in a\n  catalog.\n\n  <P>Only procedure descriptions matching the schema and\n  procedure name criteria are returned.  They are ordered by\n  PROCEDURE_SCHEM, and PROCEDURE_NAME.\n\n  <P>Each procedure description has the the following columns:\n   <OL>\n \t<LI><B>PROCEDURE_CAT</B> String => procedure catalog (may be null)\n \t<LI><B>PROCEDURE_SCHEM</B> String => procedure schema (may be null)\n \t<LI><B>PROCEDURE_NAME</B> String => procedure name\n   <LI> reserved for future use\n   <LI> reserved for future use\n   <LI> reserved for future use\n \t<LI><B>REMARKS</B> String => explanatory comment on the procedure\n \t<LI><B>PROCEDURE_TYPE</B> short => kind of procedure:\n       <UL>\n       <LI> procedureResultUnknown - May return a result\n       <LI> procedureNoResult - Does not return a result\n       <LI> procedureReturnsResult - Returns a result\n       </UL>\n   </OL>\n\n  @param catalog a catalog name; \"\" retrieves those without a\n  catalog; null means drop catalog name from the selection criteria\n  @param schemaPattern a schema name pattern; \"\" retrieves those\n  without a schema\n  @param procedureNamePattern a procedure name pattern\n  @return <code>ResultSet</code> - each row is a procedure description\n  @see #getSearchStringEscape\n}\nfunction TZAbstractDatabaseMetadata.UncachedGetProcedures(const Catalog: string;\n  const SchemaPattern: string; const ProcedureNamePattern: string): IZResultSet;\nbegin\n    Result := ConstructVirtualResultSet(ProceduresColumnsDynArray);\nend;\n\n{**\n  Gets a description of a catalog's stored procedure parameters\n  and result columns.\n\n  <P>Only descriptions matching the schema, procedure and\n  parameter name criteria are returned.  They are ordered by\n  PROCEDURE_SCHEM and PROCEDURE_NAME. Within this, the return value,\n  if any, is first. Next are the parameter descriptions in call\n  order. The column descriptions follow in column number order.\n\n  <P>Each row in the <code>ResultSet</code> is a parameter description or\n  column description with the following fields:\n   <OL>\n \t<LI><B>PROCEDURE_CAT</B> String => procedure catalog (may be null)\n \t<LI><B>PROCEDURE_SCHEM</B> String => procedure schema (may be null)\n \t<LI><B>PROCEDURE_NAME</B> String => procedure name\n \t<LI><B>COLUMN_NAME</B> String => column/parameter name\n \t<LI><B>COLUMN_TYPE</B> Short => kind of column/parameter:\n       <UL>\n       <LI> procedureColumnUnknown - nobody knows\n       <LI> procedureColumnIn - IN parameter\n       <LI> procedureColumnInOut - INOUT parameter\n       <LI> procedureColumnOut - OUT parameter\n       <LI> procedureColumnReturn - procedure return value\n       <LI> procedureColumnResult - result column in <code>ResultSet</code>\n       </UL>\n   <LI><B>DATA_TYPE</B> short => SQL type from java.sql.Types\n \t<LI><B>TYPE_NAME</B> String => SQL type name, for a UDT type the\n   type name is fully qualified\n \t<LI><B>PRECISION</B> int => precision\n \t<LI><B>LENGTH</B> int => length in bytes of data\n \t<LI><B>SCALE</B> short => scale\n \t<LI><B>RADIX</B> short => radix\n \t<LI><B>NULLABLE</B> short => can it contain NULL?\n       <UL>\n       <LI> procedureNoNulls - does not allow NULL values\n       <LI> procedureNullable - allows NULL values\n       <LI> procedureNullableUnknown - nullability unknown\n       </UL>\n \t<LI><B>REMARKS</B> String => comment describing parameter/column\n   </OL>\n\n  <P><B>Note:</B> Some databases may not return the column\n  descriptions for a procedure. Additional columns beyond\n  REMARKS can be defined by the database.\n\n  @param catalog a catalog name; \"\" retrieves those without a\n  catalog; null means drop catalog name from the selection criteria\n  @param schemaPattern a schema name pattern; \"\" retrieves those\n  without a schema\n  @param procedureNamePattern a procedure name pattern\n  @param columnNamePattern a column name pattern\n  @return <code>ResultSet</code> - each row describes a stored procedure parameter or\n       column\n  @see #getSearchStringEscape\n}\nfunction TZAbstractDatabaseMetadata.GetProcedureColumns(const Catalog: string;\n  const SchemaPattern: string; const ProcedureNamePattern: string;\n  const ColumnNamePattern: string): IZResultSet;\nvar\n  Key: string;\nbegin\n  if not GetConnection.UseMetadata then\n  begin\n    Result := ConstructVirtualResultSet(ProceduresColColumnsDynArray);\n    exit;\n  end;\n\n  Key := GetProcedureColumnsCacheKey(Catalog, SchemaPattern, ProcedureNamePattern,\n    ColumnNamePattern);\n  Result := GetResultSetFromCache(Key);\n  if Result = nil then\n  begin\n    Result := UncachedGetProcedureColumns(Catalog, SchemaPattern, ProcedureNamePattern, ColumnNamePattern);\n    AddResultSetToCache(Key, Result);\n  end;\nend;\n\n{**\n  Gets a description of a catalog's stored procedure parameters\n  and result columns.\n\n  <P>Only descriptions matching the schema, procedure and\n  parameter name criteria are returned.  They are ordered by\n  PROCEDURE_SCHEM and PROCEDURE_NAME. Within this, the return value,\n  if any, is first. Next are the parameter descriptions in call\n  order. The column descriptions follow in column number order.\n\n  <P>Each row in the <code>ResultSet</code> is a parameter description or\n  column description with the following fields:\n   <OL>\n \t<LI><B>PROCEDURE_CAT</B> String => procedure catalog (may be null)\n \t<LI><B>PROCEDURE_SCHEM</B> String => procedure schema (may be null)\n \t<LI><B>PROCEDURE_NAME</B> String => procedure name\n \t<LI><B>COLUMN_NAME</B> String => column/parameter name\n \t<LI><B>COLUMN_TYPE</B> Short => kind of column/parameter:\n       <UL>\n       <LI> procedureColumnUnknown - nobody knows\n       <LI> procedureColumnIn - IN parameter\n       <LI> procedureColumnInOut - INOUT parameter\n       <LI> procedureColumnOut - OUT parameter\n       <LI> procedureColumnReturn - procedure return value\n       <LI> procedureColumnResult - result column in <code>ResultSet</code>\n       </UL>\n   <LI><B>DATA_TYPE</B> short => SQL type from java.sql.Types\n \t<LI><B>TYPE_NAME</B> String => SQL type name, for a UDT type the\n   type name is fully qualified\n \t<LI><B>PRECISION</B> int => precision\n \t<LI><B>LENGTH</B> int => length in bytes of data\n \t<LI><B>SCALE</B> short => scale\n \t<LI><B>RADIX</B> short => radix\n \t<LI><B>NULLABLE</B> short => can it contain NULL?\n       <UL>\n       <LI> procedureNoNulls - does not allow NULL values\n       <LI> procedureNullable - allows NULL values\n       <LI> procedureNullableUnknown - nullability unknown\n       </UL>\n \t<LI><B>REMARKS</B> String => comment describing parameter/column\n   </OL>\n\n  <P><B>Note:</B> Some databases may not return the column\n  descriptions for a procedure. Additional columns beyond\n  REMARKS can be defined by the database.\n\n  @param catalog a catalog name; \"\" retrieves those without a\n  catalog; null means drop catalog name from the selection criteria\n  @param schemaPattern a schema name pattern; \"\" retrieves those\n  without a schema\n  @param procedureNamePattern a procedure name pattern\n  @param columnNamePattern a column name pattern\n  @return <code>ResultSet</code> - each row describes a stored procedure parameter or\n       column\n  @see #getSearchStringEscape\n}\nfunction TZAbstractDatabaseMetadata.UncachedGetProcedureColumns(const Catalog: string;\n  const SchemaPattern: string; const ProcedureNamePattern: string;\n  const ColumnNamePattern: string): IZResultSet;\nbegin\n    Result := ConstructVirtualResultSet(ProceduresColColumnsDynArray);\nend;\n\nfunction TZAbstractDatabaseMetadata.GetTriggers(const Catalog: string; const SchemaPattern: string;\n  const TableNamePattern: string; const TriggerNamePattern: string): IZResultSet;\nvar\n  Key: string;\nbegin\n  if not GetConnection.UseMetadata then\n  begin\n    Result := ConstructVirtualResultSet(TriggersColumnsDynArray);\n    exit;\n  end;\n\n  Key := GetTriggersCacheKey(Catalog, SchemaPattern, TableNamePattern, TriggerNamePattern);\n  Result := GetResultSetFromCache(Key);\n  if Result = nil then\n  begin\n    Result := UncachedGetTriggers(Catalog, SchemaPattern, TableNamePattern, TriggerNamePattern);\n    AddResultSetToCache(Key, Result);\n  end;\nend;\n\nfunction TZAbstractDatabaseMetadata.UncachedGetTriggers(const Catalog: string; const SchemaPattern: string;\n  const TableNamePattern: string; const TriggerNamePattern: string): IZResultSet;\nbegin\n  Result := ConstructVirtualResultSet(TriggersColumnsDynArray);\nend;\n\nfunction TZAbstractDatabaseMetadata.GetCollationAndCharSet(const Catalog, Schema,\n  TableName, ColumnName: String): IZResultSet;\nvar\n  Key: string;\nbegin\n  if not GetConnection.UseMetadata then\n  begin\n    Result := ConstructVirtualResultSet(CollationCharSetColumnsDynArray);\n    exit;\n  end;\n\n  Key := GetCollationAndCharSetCacheKey(Catalog, Schema, TableName, ColumnName);\n  Result := GetResultSetFromCache(Key);\n  if Result = nil then\n  begin\n    Result := UncachedGetCollationAndCharSet(Catalog, Schema, TableName, ColumnName);\n    AddResultSetToCache(Key, Result);\n  end;\nend;\n\nfunction TZAbstractDatabaseMetadata.GetCharacterSets: IZResultSet; //EgonHugeist\nvar\n  Key: string;\nbegin\n  if not GetConnection.UseMetadata then\n  begin\n    Result := ConstructVirtualResultSet(CharacterSetsColumnsDynArray);\n    exit;\n  end;\n\n  Key := GetCharacterSetsCacheKey;\n  Result := GetResultSetFromCache(Key);\n  if Result = nil then\n  begin\n    Result := UncachedGetCharacterSets;\n    AddResultSetToCache(Key, Result);\n  end;\nend;\n\nfunction TZAbstractDatabaseMetadata.UncachedGetCollationAndCharSet(const Catalog, SchemaPattern,\n  TableNamePattern, ColumnNamePattern: string): IZResultSet;\nbegin\n  Result := ConstructVirtualResultSet(CollationCharSetColumnsDynArray);\nend;\n\nfunction TZAbstractDatabaseMetadata.UncachedGetCharacterSets: IZResultSet; //EgonHugeist\nbegin\n  Result := ConstructVirtualResultSet(CharacterSetsColumnsDynArray);\nend;\n\nfunction TZAbstractDatabaseMetadata.GetCollationAndCharSetCacheKey(const Catalog, SchemaPattern,\n  TableNamePattern, ColumnPattern: String): string;\nbegin\n  Result := Format('get-CollationAndCharSet:%s:%s:%s:%s',\n    [Catalog, SchemaPattern, TableNamePattern, ColumnPattern]);\nend;\n\nfunction TZAbstractDatabaseMetadata.GetCharacterSetsCacheKey: String; //EgonHugeist\nbegin\n  Result := 'get-charactersets';\nend;\n\nfunction TZAbstractDatabaseMetadata.GetTriggersCacheKey(const Catalog: string;\n  const SchemaPattern: string; const TableNamePattern: string;\n  const TriggerNamePattern: string): string;\nbegin\n  Result := Format('get-trigger:%s:%s:%s:%s',\n    [Catalog, SchemaPattern, TableNamePattern, TriggerNamePattern]);\nend;\n\n{**\n  Gets a description of tables available in a catalog.\n\n  <P>Only table descriptions matching the catalog, schema, table\n  name and type criteria are returned.  They are ordered by\n  TABLE_TYPE, TABLE_SCHEM and TABLE_NAME.\n\n  <P>Each table description has the following columns:\n   <OL>\n \t<LI><B>TABLE_CAT</B> String => table catalog (may be null)\n \t<LI><B>TABLE_SCHEM</B> String => table schema (may be null)\n \t<LI><B>TABLE_NAME</B> String => table name\n \t<LI><B>TABLE_TYPE</B> String => table type.  Typical types are \"TABLE\",\n \t\t\t\"VIEW\",\t\"SYSTEM TABLE\", \"GLOBAL TEMPORARY\",\n \t\t\t\"LOCAL TEMPORARY\", \"ALIAS\", \"SYNONYM\".\n \t<LI><B>REMARKS</B> String => explanatory comment on the table\n   </OL>\n\n  <P><B>Note:</B> Some databases may not return information for\n  all tables.\n\n  @param catalog a catalog name; \"\" retrieves those without a\n  catalog; null means drop catalog name from the selection criteria\n  @param schemaPattern a schema name pattern; \"\" retrieves those\n  without a schema\n  @param tableNamePattern a table name pattern\n  @param types a list of table types to include; null returns all types\n  @return <code>ResultSet</code> - each row is a table description\n  @see #getSearchStringEscape\n}\nfunction TZAbstractDatabaseMetadata.GetTables(const Catalog: string;\n  const SchemaPattern: string; const TableNamePattern: string;\n  const Types: TStringDynArray): IZResultSet;\nvar\n  Key: string;\nbegin\n  if not GetConnection.UseMetadata then\n  begin\n    Result := ConstructVirtualResultSet(TableColumnsDynArray);\n    exit;\n  end;\n\n  Key := GetTablesCacheKey(Catalog, SchemaPattern, TableNamePattern, Types);\n  Result := GetResultSetFromCache(Key);\n  if Result = nil then\n  begin\n    Result := UncachedGetTables(Catalog, SchemaPattern, TableNamePattern, Types);\n    AddResultSetToCache(Key, Result);\n  end;\nend;\n\n{**\n  Gets a description of tables available in a catalog.\n\n  <P>Only table descriptions matching the catalog, schema, table\n  name and type criteria are returned.  They are ordered by\n  TABLE_TYPE, TABLE_SCHEM and TABLE_NAME.\n\n  <P>Each table description has the following columns:\n   <OL>\n \t<LI><B>TABLE_CAT</B> String => table catalog (may be null)\n \t<LI><B>TABLE_SCHEM</B> String => table schema (may be null)\n \t<LI><B>TABLE_NAME</B> String => table name\n \t<LI><B>TABLE_TYPE</B> String => table type.  Typical types are \"TABLE\",\n \t\t\t\"VIEW\",\t\"SYSTEM TABLE\", \"GLOBAL TEMPORARY\",\n \t\t\t\"LOCAL TEMPORARY\", \"ALIAS\", \"SYNONYM\".\n \t<LI><B>REMARKS</B> String => explanatory comment on the table\n   </OL>\n\n  <P><B>Note:</B> Some databases may not return information for\n  all tables.\n\n  @param catalog a catalog name; \"\" retrieves those without a\n  catalog; null means drop catalog name from the selection criteria\n  @param schemaPattern a schema name pattern; \"\" retrieves those\n  without a schema\n  @param tableNamePattern a table name pattern\n  @param types a list of table types to include; null returns all types\n  @return <code>ResultSet</code> - each row is a table description\n  @see #getSearchStringEscape\n}\nfunction TZAbstractDatabaseMetadata.UncachedGetTables(const Catalog: string;\n  const SchemaPattern: string; const TableNamePattern: string;\n  const Types: TStringDynArray): IZResultSet;\nbegin\n  Result := ConstructVirtualResultSet(TableColumnsDynArray);\nend;\n\n{**\n  Gets the schema names available in this database.  The results\n  are ordered by schema name.\n\n  <P>The schema column is:\n   <OL>\n \t<LI><B>TABLE_SCHEM</B> String => schema name\n   </OL>\n\n  @return <code>ResultSet</code> - each row has a single String column that is a\n  schema name\n}\nfunction TZAbstractDatabaseMetadata.GetSchemas: IZResultSet;\nvar\n  Key: string;\nbegin\n  if not GetConnection.UseMetadata then\n  begin\n    Result := ConstructVirtualResultSet(SchemaColumnsDynArray);\n    exit;\n  end;\n\n  Key := GetSchemasCacheKey;\n  Result := GetResultSetFromCache(Key);\n  if Result = nil then\n  begin\n    Result := UncachedGetSchemas;\n    AddResultSetToCache(Key, Result);\n  end;\nend;\n\n{**\n  Gets the schema names available in this database.  The results\n  are ordered by schema name.\n\n  <P>The schema column is:\n   <OL>\n \t<LI><B>TABLE_SCHEM</B> String => schema name\n   </OL>\n\n  @return <code>ResultSet</code> - each row has a single String column that is a\n  schema name\n}\nfunction TZAbstractDatabaseMetadata.UncachedGetSchemas: IZResultSet;\nbegin\n    Result := ConstructVirtualResultSet(SchemaColumnsDynArray);\nend;\n\n{**\n  Gets the catalog names available in this database.  The results\n  are ordered by catalog name.\n\n  <P>The catalog column is:\n   <OL>\n \t<LI><B>TABLE_CAT</B> String => catalog name\n   </OL>\n\n  @return <code>ResultSet</code> - each row has a single String column that is a\n  catalog name\n}\nfunction TZAbstractDatabaseMetadata.GetCatalogs: IZResultSet;\nvar\n  Key: string;\nbegin\n  if not GetConnection.UseMetadata then\n  begin\n    Result := ConstructVirtualResultSet(CatalogColumnsDynArray);\n    exit;\n  end;\n\n  Key := GetCatalogsCacheKey;\n  Result := GetResultSetFromCache(Key);\n  if Result = nil then\n  begin\n    Result := UncachedGetCatalogs;\n    AddResultSetToCache(Key, Result);\n  end;\nend;\n\n{**\n  Gets the catalog names available in this database.  The results\n  are ordered by catalog name.\n\n  <P>The catalog column is:\n   <OL>\n \t<LI><B>TABLE_CAT</B> String => catalog name\n   </OL>\n\n  @return <code>ResultSet</code> - each row has a single String column that is a\n  catalog name\n}\nfunction TZAbstractDatabaseMetadata.UncachedGetCatalogs: IZResultSet;\nbegin\n    Result := ConstructVirtualResultSet(CatalogColumnsDynArray);\nend;\n\n{**\n  Gets the table types available in this database.  The results\n  are ordered by table type.\n\n  <P>The table type is:\n   <OL>\n \t<LI><B>TABLE_TYPE</B> String => table type.  Typical types are \"TABLE\",\n \t\t\t\"VIEW\",\t\"SYSTEM TABLE\", \"GLOBAL TEMPORARY\",\n \t\t\t\"LOCAL TEMPORARY\", \"ALIAS\", \"SYNONYM\".\n   </OL>\n\n  @return <code>ResultSet</code> - each row has a single String column that is a\n  table type\n}\nfunction TZAbstractDatabaseMetadata.GetTableTypes: IZResultSet;\nvar\n  Key: string;\nbegin\n  if not GetConnection.UseMetadata then\n  begin\n    Result := ConstructVirtualResultSet(TableTypeColumnsDynArray);\n    exit;\n  end;\n\n  Key := GetTableTypesCacheKey;\n  Result := GetResultSetFromCache(Key);\n  if Result = nil then\n  begin\n    Result := UncachedGetTableTypes;\n    AddResultSetToCache(Key, Result);\n  end;\nend;\n\n{**\n  Gets the table types available in this database.  The results\n  are ordered by table type.\n\n  <P>The table type is:\n   <OL>\n \t<LI><B>TABLE_TYPE</B> String => table type.  Typical types are \"TABLE\",\n \t\t\t\"VIEW\",\t\"SYSTEM TABLE\", \"GLOBAL TEMPORARY\",\n \t\t\t\"LOCAL TEMPORARY\", \"ALIAS\", \"SYNONYM\".\n   </OL>\n\n  @return <code>ResultSet</code> - each row has a single String column that is a\n  table type\n}\nfunction TZAbstractDatabaseMetadata.UncachedGetTableTypes: IZResultSet;\nbegin\n    Result := ConstructVirtualResultSet(TableTypeColumnsDynArray);\nend;\n\n{**\n  Gets a description of table columns available in\n  the specified catalog.\n\n  <P>Only column descriptions matching the catalog, schema, table\n  and column name criteria are returned.  They are ordered by\n  TABLE_SCHEM, TABLE_NAME and ORDINAL_POSITION.\n\n  <P>Each column description has the following columns:\n   <OL>\n \t<LI><B>TABLE_CAT</B> String => table catalog (may be null)\n \t<LI><B>TABLE_SCHEM</B> String => table schema (may be null)\n \t<LI><B>TABLE_NAME</B> String => table name\n \t<LI><B>COLUMN_NAME</B> String => column name\n \t<LI><B>DATA_TYPE</B> short => SQL type from java.sql.Types\n \t<LI><B>TYPE_NAME</B> String => Data source dependent type name,\n   for a UDT the type name is fully qualified\n \t<LI><B>COLUMN_SIZE</B> int => column size.  For char or date\n \t    types this is the maximum number of characters, for numeric or\n \t    decimal types this is precision.\n \t<LI><B>BUFFER_LENGTH</B> is not used.\n \t<LI><B>DECIMAL_DIGITS</B> int => the number of fractional digits\n \t<LI><B>NUM_PREC_RADIX</B> int => Radix (typically either 10 or 2)\n \t<LI><B>NULLABLE</B> int => is NULL allowed?\n       <UL>\n       <LI> columnNoNulls - might not allow NULL values\n       <LI> columnNullable - definitely allows NULL values\n       <LI> columnNullableUnknown - nullability unknown\n       </UL>\n \t<LI><B>REMARKS</B> String => comment describing column (may be null)\n  \t<LI><B>COLUMN_DEF</B> String => default value (may be null)\n \t<LI><B>SQL_DATA_TYPE</B> int => unused\n \t<LI><B>SQL_DATETIME_SUB</B> int => unused\n \t<LI><B>CHAR_OCTET_LENGTH</B> int => for char types the\n        maximum number of bytes in the column\n \t<LI><B>ORDINAL_POSITION</B> int\t=> index of column in table\n       (starting at 1)\n \t<LI><B>IS_NULLABLE</B> String => \"NO\" means column definitely\n       does not allow NULL values; \"YES\" means the column might\n       allow NULL values.  An empty string means nobody knows.\n   </OL>\n\n  @param catalog a catalog name; \"\" retrieves those without a\n  catalog; null means drop catalog name from the selection criteria\n  @param schemaPattern a schema name pattern; \"\" retrieves those\n  without a schema\n  @param tableNamePattern a table name pattern\n  @param columnNamePattern a column name pattern\n  @return <code>ResultSet</code> - each row is a column description\n  @see #getSearchStringEscape\n}\nfunction TZAbstractDatabaseMetadata.GetColumns(const Catalog: string;\n  const SchemaPattern: string; const TableNamePattern: string;\n  const ColumnNamePattern: string): IZResultSet;\nvar\n  Key: string;\nbegin\n  if not GetConnection.UseMetadata then\n  begin\n    Result := ConstructVirtualResultSet(TableColColumnsDynArray);\n    exit;\n  end;\n\n  Key := GetColumnsCacheKey(Catalog, SchemaPattern, TableNamePattern,\n    ColumnNamePattern);\n  Result := GetResultSetFromCache(Key);\n  if Result = nil then\n  begin\n    Result := UncachedGetColumns(Catalog, SchemaPattern, TableNamePattern, ColumnNamePattern);\n    AddResultSetToCache(Key, Result);\n  end;\nend;\n\n{**\n  Gets a description of table columns available in\n  the specified catalog.\n\n  <P>Only column descriptions matching the catalog, schema, table\n  and column name criteria are returned.  They are ordered by\n  TABLE_SCHEM, TABLE_NAME and ORDINAL_POSITION.\n\n  <P>Each column description has the following columns:\n   <OL>\n \t<LI><B>TABLE_CAT</B> String => table catalog (may be null)\n \t<LI><B>TABLE_SCHEM</B> String => table schema (may be null)\n \t<LI><B>TABLE_NAME</B> String => table name\n \t<LI><B>COLUMN_NAME</B> String => column name\n \t<LI><B>DATA_TYPE</B> short => SQL type from java.sql.Types\n \t<LI><B>TYPE_NAME</B> String => Data source dependent type name,\n   for a UDT the type name is fully qualified\n \t<LI><B>COLUMN_SIZE</B> int => column size.  For char or date\n \t    types this is the maximum number of characters, for numeric or\n \t    decimal types this is precision.\n \t<LI><B>BUFFER_LENGTH</B> is not used.\n \t<LI><B>DECIMAL_DIGITS</B> int => the number of fractional digits\n \t<LI><B>NUM_PREC_RADIX</B> int => Radix (typically either 10 or 2)\n \t<LI><B>NULLABLE</B> int => is NULL allowed?\n       <UL>\n       <LI> columnNoNulls - might not allow NULL values\n       <LI> columnNullable - definitely allows NULL values\n       <LI> columnNullableUnknown - nullability unknown\n       </UL>\n \t<LI><B>REMARKS</B> String => comment describing column (may be null)\n  \t<LI><B>COLUMN_DEF</B> String => default value (may be null)\n \t<LI><B>SQL_DATA_TYPE</B> int => unused\n \t<LI><B>SQL_DATETIME_SUB</B> int => unused\n \t<LI><B>CHAR_OCTET_LENGTH</B> int => for char types the\n        maximum number of bytes in the column\n \t<LI><B>ORDINAL_POSITION</B> int\t=> index of column in table\n       (starting at 1)\n \t<LI><B>IS_NULLABLE</B> String => \"NO\" means column definitely\n       does not allow NULL values; \"YES\" means the column might\n       allow NULL values.  An empty string means nobody knows.\n   </OL>\n\n  @param catalog a catalog name; \"\" retrieves those without a\n  catalog; null means drop catalog name from the selection criteria\n  @param schemaPattern a schema name pattern; \"\" retrieves those\n  without a schema\n  @param tableNamePattern a table name pattern\n  @param columnNamePattern a column name pattern\n  @return <code>ResultSet</code> - each row is a column description\n  @see #getSearchStringEscape\n}\nfunction TZAbstractDatabaseMetadata.UncachedGetColumns(const Catalog: string;\n  const SchemaPattern: string; const TableNamePattern: string;\n  const ColumnNamePattern: string): IZResultSet;\nbegin\n    Result := ConstructVirtualResultSet(TableColColumnsDynArray);\nend;\n\n{**\n  Gets a description of the access rights for a table's columns.\n\n  <P>Only privileges matching the column name criteria are\n  returned.  They are ordered by COLUMN_NAME and PRIVILEGE.\n\n  <P>Each privilige description has the following columns:\n   <OL>\n \t<LI><B>TABLE_CAT</B> String => table catalog (may be null)\n \t<LI><B>TABLE_SCHEM</B> String => table schema (may be null)\n \t<LI><B>TABLE_NAME</B> String => table name\n \t<LI><B>COLUMN_NAME</B> String => column name\n \t<LI><B>GRANTOR</B> => grantor of access (may be null)\n \t<LI><B>GRANTEE</B> String => grantee of access\n \t<LI><B>PRIVILEGE</B> String => name of access (SELECT,\n       INSERT, UPDATE, REFRENCES, ...)\n \t<LI><B>IS_GRANTABLE</B> String => \"YES\" if grantee is permitted\n       to grant to others; \"NO\" if not; null if unknown\n   </OL>\n\n  @param catalog a catalog name; \"\" retrieves those without a\n  catalog; null means drop catalog name from the selection criteria\n  @param schema a schema name; \"\" retrieves those without a schema\n  @param table a table name\n  @param columnNamePattern a column name pattern\n  @return <code>ResultSet</code> - each row is a column privilege description\n  @see #getSearchStringEscape\n}\nfunction TZAbstractDatabaseMetadata.GetColumnPrivileges(const Catalog: string;\n  const Schema: string; const Table: string; const ColumnNamePattern: string): IZResultSet;\nvar\n  Key: string;\nbegin\n  if not GetConnection.UseMetadata then\n  begin\n    Result := ConstructVirtualResultSet(TableColPrivColumnsDynArray);\n    exit;\n  end;\n\n  Key := GetColumnPrivilegesCacheKey(Catalog, Schema, Table,\n    ColumnNamePattern);\n  Result := GetResultSetFromCache(Key);\n  if Result = nil then\n  begin\n    Result := UncachedGetColumnPrivileges(Catalog, Schema, Table, ColumnNamePattern);\n    AddResultSetToCache(Key, Result);\n  end;\nend;\n\n{**\n  Gets a description of the access rights for a table's columns.\n\n  <P>Only privileges matching the column name criteria are\n  returned.  They are ordered by COLUMN_NAME and PRIVILEGE.\n\n  <P>Each privilige description has the following columns:\n   <OL>\n \t<LI><B>TABLE_CAT</B> String => table catalog (may be null)\n \t<LI><B>TABLE_SCHEM</B> String => table schema (may be null)\n \t<LI><B>TABLE_NAME</B> String => table name\n \t<LI><B>COLUMN_NAME</B> String => column name\n \t<LI><B>GRANTOR</B> => grantor of access (may be null)\n \t<LI><B>GRANTEE</B> String => grantee of access\n \t<LI><B>PRIVILEGE</B> String => name of access (SELECT,\n       INSERT, UPDATE, REFRENCES, ...)\n \t<LI><B>IS_GRANTABLE</B> String => \"YES\" if grantee is permitted\n       to grant to others; \"NO\" if not; null if unknown\n   </OL>\n\n  @param catalog a catalog name; \"\" retrieves those without a\n  catalog; null means drop catalog name from the selection criteria\n  @param schema a schema name; \"\" retrieves those without a schema\n  @param table a table name\n  @param columnNamePattern a column name pattern\n  @return <code>ResultSet</code> - each row is a column privilege description\n  @see #getSearchStringEscape\n}\nfunction TZAbstractDatabaseMetadata.UncachedGetColumnPrivileges(const Catalog: string;\n  const Schema: string; const Table: string; const ColumnNamePattern: string): IZResultSet;\nbegin\n    Result := ConstructVirtualResultSet(TableColPrivColumnsDynArray);\nend;\n\n{**\n  Gets a description of the access rights for each table available\n  in a catalog. Note that a table privilege applies to one or\n  more columns in the table. It would be wrong to assume that\n  this priviledge applies to all columns (this may be true for\n  some systems but is not true for all.)\n\n  <P>Only privileges matching the schema and table name\n  criteria are returned.  They are ordered by TABLE_SCHEM,\n  TABLE_NAME, and PRIVILEGE.\n\n  <P>Each privilige description has the following columns:\n   <OL>\n \t<LI><B>TABLE_CAT</B> String => table catalog (may be null)\n \t<LI><B>TABLE_SCHEM</B> String => table schema (may be null)\n \t<LI><B>TABLE_NAME</B> String => table name\n \t<LI><B>GRANTOR</B> => grantor of access (may be null)\n \t<LI><B>GRANTEE</B> String => grantee of access\n \t<LI><B>PRIVILEGE</B> String => name of access (SELECT,\n       INSERT, UPDATE, REFRENCES, ...)\n \t<LI><B>IS_GRANTABLE</B> String => \"YES\" if grantee is permitted\n       to grant to others; \"NO\" if not; null if unknown\n   </OL>\n\n  @param catalog a catalog name; \"\" retrieves those without a\n  catalog; null means drop catalog name from the selection criteria\n  @param schemaPattern a schema name pattern; \"\" retrieves those\n  without a schema\n  @param tableNamePattern a table name pattern\n  @return <code>ResultSet</code> - each row is a table privilege description\n  @see #getSearchStringEscape\n}\nfunction TZAbstractDatabaseMetadata.GetTablePrivileges(const Catalog: string;\n  const SchemaPattern: string; const TableNamePattern: string): IZResultSet;\nvar\n  Key: string;\nbegin\n  if not GetConnection.UseMetadata then\n  begin\n    Result := ConstructVirtualResultSet(TablePrivColumnsDynArray);\n    exit;\n  end;\n\n  Key := GetTablePrivilegesCacheKey(Catalog, SchemaPattern,\n    TableNamePattern);\n  Result := GetResultSetFromCache(Key);\n  if Result = nil then\n  begin\n    Result := UncachedGetTablePrivileges(Catalog, SchemaPattern, TableNamePattern);\n    AddResultSetToCache(Key, Result);\n  end;\nend;\n\n{**\n  Gets a description of the access rights for each table available\n  in a catalog. Note that a table privilege applies to one or\n  more columns in the table. It would be wrong to assume that\n  this priviledge applies to all columns (this may be true for\n  some systems but is not true for all.)\n\n  <P>Only privileges matching the schema and table name\n  criteria are returned.  They are ordered by TABLE_SCHEM,\n  TABLE_NAME, and PRIVILEGE.\n\n  <P>Each privilige description has the following columns:\n   <OL>\n \t<LI><B>TABLE_CAT</B> String => table catalog (may be null)\n \t<LI><B>TABLE_SCHEM</B> String => table schema (may be null)\n \t<LI><B>TABLE_NAME</B> String => table name\n \t<LI><B>GRANTOR</B> => grantor of access (may be null)\n \t<LI><B>GRANTEE</B> String => grantee of access\n \t<LI><B>PRIVILEGE</B> String => name of access (SELECT,\n       INSERT, UPDATE, REFRENCES, ...)\n \t<LI><B>IS_GRANTABLE</B> String => \"YES\" if grantee is permitted\n       to grant to others; \"NO\" if not; null if unknown\n   </OL>\n\n  @param catalog a catalog name; \"\" retrieves those without a\n  catalog; null means drop catalog name from the selection criteria\n  @param schemaPattern a schema name pattern; \"\" retrieves those\n  without a schema\n  @param tableNamePattern a table name pattern\n  @return <code>ResultSet</code> - each row is a table privilege description\n  @see #getSearchStringEscape\n}\nfunction TZAbstractDatabaseMetadata.UncachedGetTablePrivileges(const Catalog: string;\n  const SchemaPattern: string; const TableNamePattern: string): IZResultSet;\nbegin\n    Result := ConstructVirtualResultSet(TablePrivColumnsDynArray);\nend;\n\n{**\n  Gets a description of a table's optimal set of columns that\n  uniquely identifies a row. They are ordered by SCOPE.\n\n  <P>Each column description has the following columns:\n   <OL>\n \t<LI><B>SCOPE</B> short => actual scope of result\n       <UL>\n       <LI> bestRowTemporary - very temporary, while using row\n       <LI> bestRowTransaction - valid for remainder of current transaction\n       <LI> bestRowSession - valid for remainder of current session\n       </UL>\n \t<LI><B>COLUMN_NAME</B> String => column name\n \t<LI><B>DATA_TYPE</B> short => SQL data type from java.sql.Types\n \t<LI><B>TYPE_NAME</B> String => Data source dependent type name,\n   for a UDT the type name is fully qualified\n \t<LI><B>COLUMN_SIZE</B> int => precision\n \t<LI><B>BUFFER_LENGTH</B> int => not used\n \t<LI><B>DECIMAL_DIGITS</B> short\t => scale\n \t<LI><B>PSEUDO_COLUMN</B> short => is this a pseudo column\n       like an Oracle ROWID\n       <UL>\n       <LI> bestRowUnknown - may or may not be pseudo column\n       <LI> bestRowNotPseudo - is NOT a pseudo column\n       <LI> bestRowPseudo - is a pseudo column\n       </UL>\n   </OL>\n\n  @param catalog a catalog name; \"\" retrieves those without a\n  catalog; null means drop catalog name from the selection criteria\n  @param schema a schema name; \"\" retrieves those without a schema\n  @param table a table name\n  @param scope the scope of interest; use same values as SCOPE\n  @param nullable include columns that are nullable?\n  @return <code>ResultSet</code> - each row is a column description\n}\nfunction TZAbstractDatabaseMetadata.GetBestRowIdentifier(const Catalog: string;\n  const Schema: string; const Table: string; Scope: Integer; Nullable: Boolean): IZResultSet;\nvar\n  Key: string;\nbegin\n  if not GetConnection.UseMetadata then\n  begin\n    Result := ConstructVirtualResultSet(BestRowIdentColumnsDynArray);\n    exit;\n  end;\n\n  Key := GetBestRowIdentifierCacheKey(Catalog, Schema, Table, Scope,\n    Nullable);\n  Result := GetResultSetFromCache(Key);\n  if Result = nil then\n  begin\n    Result := UncachedGetBestRowIdentifier(Catalog, Schema, Table, Scope, Nullable);\n    AddResultSetToCache(Key, Result);\n  end;\nend;\n\n{**\n  Gets a description of a table's optimal set of columns that\n  uniquely identifies a row. They are ordered by SCOPE.\n\n  <P>Each column description has the following columns:\n   <OL>\n \t<LI><B>SCOPE</B> short => actual scope of result\n       <UL>\n       <LI> bestRowTemporary - very temporary, while using row\n       <LI> bestRowTransaction - valid for remainder of current transaction\n       <LI> bestRowSession - valid for remainder of current session\n       </UL>\n \t<LI><B>COLUMN_NAME</B> String => column name\n \t<LI><B>DATA_TYPE</B> short => SQL data type from java.sql.Types\n \t<LI><B>TYPE_NAME</B> String => Data source dependent type name,\n   for a UDT the type name is fully qualified\n \t<LI><B>COLUMN_SIZE</B> int => precision\n \t<LI><B>BUFFER_LENGTH</B> int => not used\n \t<LI><B>DECIMAL_DIGITS</B> short\t => scale\n \t<LI><B>PSEUDO_COLUMN</B> short => is this a pseudo column\n       like an Oracle ROWID\n       <UL>\n       <LI> bestRowUnknown - may or may not be pseudo column\n       <LI> bestRowNotPseudo - is NOT a pseudo column\n       <LI> bestRowPseudo - is a pseudo column\n       </UL>\n   </OL>\n\n  @param catalog a catalog name; \"\" retrieves those without a\n  catalog; null means drop catalog name from the selection criteria\n  @param schema a schema name; \"\" retrieves those without a schema\n  @param table a table name\n  @param scope the scope of interest; use same values as SCOPE\n  @param nullable include columns that are nullable?\n  @return <code>ResultSet</code> - each row is a column description\n}\nfunction TZAbstractDatabaseMetadata.UncachedGetBestRowIdentifier(const Catalog: string;\n  const Schema: string; const Table: string; Scope: Integer; Nullable: Boolean): IZResultSet;\nvar\n  IndexName: string;\n  ColumnNames: TStrings;\nbegin\n    Result := ConstructVirtualResultSet(BestRowIdentColumnsDynArray);\n    ColumnNames := TStringList.Create;\n    try\n      { Tries primary keys. }\n      with GetPrimaryKeys(Catalog, Schema, Table) do\n      begin\n        while Next do\n          ColumnNames.Add(GetStringByName('COLUMN_NAME'));\n        Close;\n      end;\n\n      { Tries unique indices. }\n      if ColumnNames.Count = 0 then\n      begin\n        with GetIndexInfo(Catalog, Schema, Table, True, False) do\n        begin\n          IndexName := '';\n          while Next do\n          begin\n            if IndexName = '' then\n              IndexName := GetStringByName('INDEX_NAME');\n            if GetStringByName('INDEX_NAME') = IndexName then\n              ColumnNames.Add(GetStringByName('COLUMN_NAME'));\n          end;\n          Close;\n        end;\n      end;\n\n      with GetColumns(Catalog, Schema, Table, '') do\n      begin\n        while Next do\n        begin\n          if (ColumnNames.Count <> 0) and (ColumnNames.IndexOf(\n            GetStringByName('COLUMN_NAME')) < 0) then\n            Continue;\n          if (ColumnNames.Count = 0)\n            and (TZSQLType(GetIntByName('DATA_TYPE')) in\n            [stBytes, stBinaryStream, stAsciiStream, stUnicodeStream]) then\n            Continue;\n\n          Result.MoveToInsertRow;\n          Result.UpdateInt(1, Ord(sbrSession));\n          Result.UpdateString(2, GetStringByName('COLUMN_NAME'));\n          Result.UpdateInt(3, GetIntByName('DATA_TYPE'));\n          Result.UpdateString(4, GetStringByName('TYPE_NAME'));\n          Result.UpdateInt(5, GetIntByName('COLUMN_SIZE'));\n          Result.UpdateInt(6, GetIntByName('BUFFER_LENGTH'));\n          Result.UpdateInt(7, GetIntByName('DECIMAL_DIGITS'));\n          Result.UpdateInt(8, Ord(brNotPseudo));\n          Result.InsertRow;\n        end;\n        Close;\n      end;\n    finally\n      ColumnNames.Free;\n    end;\nend;\n\n{**\n  Gets a description of a table's columns that are automatically\n  updated when any value in a row is updated.  They are\n  unordered.\n\n  <P>Each column description has the following columns:\n   <OL>\n \t<LI><B>SCOPE</B> short => is not used\n \t<LI><B>COLUMN_NAME</B> String => column name\n \t<LI><B>DATA_TYPE</B> short => SQL data type from java.sql.Types\n \t<LI><B>TYPE_NAME</B> String => Data source dependent type name\n \t<LI><B>COLUMN_SIZE</B> int => precision\n \t<LI><B>BUFFER_LENGTH</B> int => length of column value in bytes\n \t<LI><B>DECIMAL_DIGITS</B> short\t => scale\n \t<LI><B>PSEUDO_COLUMN</B> short => is this a pseudo column\n       like an Oracle ROWID\n       <UL>\n       <LI> versionColumnUnknown - may or may not be pseudo column\n       <LI> versionColumnNotPseudo - is NOT a pseudo column\n       <LI> versionColumnPseudo - is a pseudo column\n       </UL>\n   </OL>\n\n  @param catalog a catalog name; \"\" retrieves those without a\n  catalog; null means drop catalog name from the selection criteria\n  @param schema a schema name; \"\" retrieves those without a schema\n  @param table a table name\n  @return <code>ResultSet</code> - each row is a column description\n  @exception SQLException if a database access error occurs\n}\n\nfunction TZAbstractDatabaseMetadata.GetVersionColumns(const Catalog: string;\n  const Schema: string; const Table: string): IZResultSet;\nvar\n  Key: string;\nbegin\n  if not GetConnection.UseMetadata then\n  begin\n    Result := ConstructVirtualResultSet(TableColVerColumnsDynArray);\n    exit;\n  end;\n\n  Key := GetVersionColumnsCacheKey(Catalog, Schema, Table);\n  Result := GetResultSetFromCache(Key);\n  if Result = nil then\n  begin\n    Result := UncachedGetVersionColumns(Catalog, Schema, Table);\n    AddResultSetToCache(Key, Result);\n  end;\nend;\n\n{**\n  Gets a description of a table's columns that are automatically\n  updated when any value in a row is updated.  They are\n  unordered.\n\n  <P>Each column description has the following columns:\n   <OL>\n \t<LI><B>SCOPE</B> short => is not used\n \t<LI><B>COLUMN_NAME</B> String => column name\n \t<LI><B>DATA_TYPE</B> short => SQL data type from java.sql.Types\n \t<LI><B>TYPE_NAME</B> String => Data source dependent type name\n \t<LI><B>COLUMN_SIZE</B> int => precision\n \t<LI><B>BUFFER_LENGTH</B> int => length of column value in bytes\n \t<LI><B>DECIMAL_DIGITS</B> short\t => scale\n \t<LI><B>PSEUDO_COLUMN</B> short => is this a pseudo column\n       like an Oracle ROWID\n       <UL>\n       <LI> versionColumnUnknown - may or may not be pseudo column\n       <LI> versionColumnNotPseudo - is NOT a pseudo column\n       <LI> versionColumnPseudo - is a pseudo column\n       </UL>\n   </OL>\n\n  @param catalog a catalog name; \"\" retrieves those without a\n  catalog; null means drop catalog name from the selection criteria\n  @param schema a schema name; \"\" retrieves those without a schema\n  @param table a table name\n  @return <code>ResultSet</code> - each row is a column description\n  @exception SQLException if a database access error occurs\n}\nfunction TZAbstractDatabaseMetadata.UncachedGetVersionColumns(const Catalog: string;\n  const Schema: string; const Table: string): IZResultSet;\nbegin\n    Result := ConstructVirtualResultSet(TableColVerColumnsDynArray);\nend;\n\n{**\n  Gets a description of a table's primary key columns.  They\n  are ordered by COLUMN_NAME.\n\n  <P>Each primary key column description has the following columns:\n   <OL>\n \t<LI><B>TABLE_CAT</B> String => table catalog (may be null)\n \t<LI><B>TABLE_SCHEM</B> String => table schema (may be null)\n \t<LI><B>TABLE_NAME</B> String => table name\n \t<LI><B>COLUMN_NAME</B> String => column name\n \t<LI><B>KEY_SEQ</B> short => sequence number within primary key\n \t<LI><B>PK_NAME</B> String => primary key name (may be null)\n   </OL>\n\n  @param catalog a catalog name; \"\" retrieves those without a\n  catalog; null means drop catalog name from the selection criteria\n  @param schema a schema name; \"\" retrieves those\n  without a schema\n  @param table a table name\n  @return <code>ResultSet</code> - each row is a primary key column description\n  @exception SQLException if a database access error occurs\n}\nfunction TZAbstractDatabaseMetadata.GetPrimaryKeys(const Catalog: string;\n  const Schema: string; const Table: string): IZResultSet;\nvar\n  Key: string;\nbegin\n  if not GetConnection.UseMetadata then\n  begin\n    Result := ConstructVirtualResultSet(PrimaryKeyColumnsDynArray);\n    exit;\n  end;\n\n  Key := GetPrimaryKeysCacheKey(Catalog, Schema, Table);\n  Result := GetResultSetFromCache(Key);\n  if Result = nil then\n  begin\n    Result := UncachedGetPrimaryKeys(Catalog, Schema, Table);\n    AddResultSetToCache(Key, Result);\n  end;\nend;\n\n{**\n  Gets a description of a table's primary key columns.  They\n  are ordered by COLUMN_NAME.\n\n  <P>Each primary key column description has the following columns:\n   <OL>\n \t<LI><B>TABLE_CAT</B> String => table catalog (may be null)\n \t<LI><B>TABLE_SCHEM</B> String => table schema (may be null)\n \t<LI><B>TABLE_NAME</B> String => table name\n \t<LI><B>COLUMN_NAME</B> String => column name\n \t<LI><B>KEY_SEQ</B> short => sequence number within primary key\n \t<LI><B>PK_NAME</B> String => primary key name (may be null)\n   </OL>\n\n  @param catalog a catalog name; \"\" retrieves those without a\n  catalog; null means drop catalog name from the selection criteria\n  @param schema a schema name; \"\" retrieves those\n  without a schema\n  @param table a table name\n  @return <code>ResultSet</code> - each row is a primary key column description\n  @exception SQLException if a database access error occurs\n}\nfunction TZAbstractDatabaseMetadata.UncachedGetPrimaryKeys(const Catalog: string;\n  const Schema: string; const Table: string): IZResultSet;\nbegin\n    Result := ConstructVirtualResultSet(PrimaryKeyColumnsDynArray);\nend;\n\n{**\n  Gets a description of the primary key columns that are\n  referenced by a table's foreign key columns (the primary keys\n  imported by a table).  They are ordered by PKTABLE_CAT,\n  PKTABLE_SCHEM, PKTABLE_NAME, and KEY_SEQ.\n\n  <P>Each primary key column description has the following columns:\n   <OL>\n \t<LI><B>PKTABLE_CAT</B> String => primary key table catalog\n       being imported (may be null)\n \t<LI><B>PKTABLE_SCHEM</B> String => primary key table schema\n       being imported (may be null)\n \t<LI><B>PKTABLE_NAME</B> String => primary key table name\n       being imported\n \t<LI><B>PKCOLUMN_NAME</B> String => primary key column name\n       being imported\n \t<LI><B>FKTABLE_CAT</B> String => foreign key table catalog (may be null)\n \t<LI><B>FKTABLE_SCHEM</B> String => foreign key table schema (may be null)\n \t<LI><B>FKTABLE_NAME</B> String => foreign key table name\n \t<LI><B>FKCOLUMN_NAME</B> String => foreign key column name\n \t<LI><B>KEY_SEQ</B> short => sequence number within foreign key\n \t<LI><B>UPDATE_RULE</B> short => What happens to\n        foreign key when primary is updated:\n       <UL>\n       <LI> importedNoAction - do not allow update of primary\n                key if it has been imported\n       <LI> importedKeyCascade - change imported key to agree\n                with primary key update\n       <LI> importedKeySetNull - change imported key to NULL if\n                its primary key has been updated\n       <LI> importedKeySetDefault - change imported key to default values\n                if its primary key has been updated\n       <LI> importedKeyRestrict - same as importedKeyNoAction\n                                  (for ODBC 2.x compatibility)\n       </UL>\n \t<LI><B>DELETE_RULE</B> short => What happens to\n       the foreign key when primary is deleted.\n       <UL>\n       <LI> importedKeyNoAction - do not allow delete of primary\n                key if it has been imported\n       <LI> importedKeyCascade - delete rows that import a deleted key\n       <LI> importedKeySetNull - change imported key to NULL if\n                its primary key has been deleted\n       <LI> importedKeyRestrict - same as importedKeyNoAction\n                                  (for ODBC 2.x compatibility)\n       <LI> importedKeySetDefault - change imported key to default if\n                its primary key has been deleted\n       </UL>\n \t<LI><B>FK_NAME</B> String => foreign key name (may be null)\n \t<LI><B>PK_NAME</B> String => primary key name (may be null)\n \t<LI><B>DEFERRABILITY</B> short => can the evaluation of foreign key\n       constraints be deferred until commit\n       <UL>\n       <LI> importedKeyInitiallyDeferred - see SQL92 for definition\n       <LI> importedKeyInitiallyImmediate - see SQL92 for definition\n       <LI> importedKeyNotDeferrable - see SQL92 for definition\n       </UL>\n   </OL>\n\n  @param catalog a catalog name; \"\" retrieves those without a\n  catalog; null means drop catalog name from the selection criteria\n  @param schema a schema name; \"\" retrieves those\n  without a schema\n  @param table a table name\n  @return <code>ResultSet</code> - each row is a primary key column description\n  @see #getExportedKeys\n}\nfunction TZAbstractDatabaseMetadata.GetImportedKeys(const Catalog: string;\n  const Schema: string; const Table: string): IZResultSet;\nvar\n  Key: string;\nbegin\n  if not GetConnection.UseMetadata then\n  begin\n    Result := ConstructVirtualResultSet(ImportedKeyColumnsDynArray);\n    exit;\n  end;\n\n  Key := GetImportedKeysCacheKey(Catalog, Schema, Table);\n  Result := GetResultSetFromCache(Key);\n  if Result = nil then\n  begin\n    Result := UncachedGetImportedKeys(Catalog, Schema, Table);\n    AddResultSetToCache(Key, Result);\n  end;\nend;\n\n{**\n  Gets a description of the primary key columns that are\n  referenced by a table's foreign key columns (the primary keys\n  imported by a table).  They are ordered by PKTABLE_CAT,\n  PKTABLE_SCHEM, PKTABLE_NAME, and KEY_SEQ.\n\n  <P>Each primary key column description has the following columns:\n   <OL>\n \t<LI><B>PKTABLE_CAT</B> String => primary key table catalog\n       being imported (may be null)\n \t<LI><B>PKTABLE_SCHEM</B> String => primary key table schema\n       being imported (may be null)\n \t<LI><B>PKTABLE_NAME</B> String => primary key table name\n       being imported\n \t<LI><B>PKCOLUMN_NAME</B> String => primary key column name\n       being imported\n \t<LI><B>FKTABLE_CAT</B> String => foreign key table catalog (may be null)\n \t<LI><B>FKTABLE_SCHEM</B> String => foreign key table schema (may be null)\n \t<LI><B>FKTABLE_NAME</B> String => foreign key table name\n \t<LI><B>FKCOLUMN_NAME</B> String => foreign key column name\n \t<LI><B>KEY_SEQ</B> short => sequence number within foreign key\n \t<LI><B>UPDATE_RULE</B> short => What happens to\n        foreign key when primary is updated:\n       <UL>\n       <LI> importedNoAction - do not allow update of primary\n                key if it has been imported\n       <LI> importedKeyCascade - change imported key to agree\n                with primary key update\n       <LI> importedKeySetNull - change imported key to NULL if\n                its primary key has been updated\n       <LI> importedKeySetDefault - change imported key to default values\n                if its primary key has been updated\n       <LI> importedKeyRestrict - same as importedKeyNoAction\n                                  (for ODBC 2.x compatibility)\n       </UL>\n \t<LI><B>DELETE_RULE</B> short => What happens to\n       the foreign key when primary is deleted.\n       <UL>\n       <LI> importedKeyNoAction - do not allow delete of primary\n                key if it has been imported\n       <LI> importedKeyCascade - delete rows that import a deleted key\n       <LI> importedKeySetNull - change imported key to NULL if\n                its primary key has been deleted\n       <LI> importedKeyRestrict - same as importedKeyNoAction\n                                  (for ODBC 2.x compatibility)\n       <LI> importedKeySetDefault - change imported key to default if\n                its primary key has been deleted\n       </UL>\n \t<LI><B>FK_NAME</B> String => foreign key name (may be null)\n \t<LI><B>PK_NAME</B> String => primary key name (may be null)\n \t<LI><B>DEFERRABILITY</B> short => can the evaluation of foreign key\n       constraints be deferred until commit\n       <UL>\n       <LI> importedKeyInitiallyDeferred - see SQL92 for definition\n       <LI> importedKeyInitiallyImmediate - see SQL92 for definition\n       <LI> importedKeyNotDeferrable - see SQL92 for definition\n       </UL>\n   </OL>\n\n  @param catalog a catalog name; \"\" retrieves those without a\n  catalog; null means drop catalog name from the selection criteria\n  @param schema a schema name; \"\" retrieves those\n  without a schema\n  @param table a table name\n  @return <code>ResultSet</code> - each row is a primary key column description\n  @see #getExportedKeys\n}\nfunction TZAbstractDatabaseMetadata.UncachedGetImportedKeys(const Catalog: string;\n  const Schema: string; const Table: string): IZResultSet;\nbegin\n    Result := ConstructVirtualResultSet(ImportedKeyColumnsDynArray);\nend;\n\n{**\n  Gets a description of the foreign key columns that reference a\n  table's primary key columns (the foreign keys exported by a\n  table).  They are ordered by FKTABLE_CAT, FKTABLE_SCHEM,\n  FKTABLE_NAME, and KEY_SEQ.\n\n  <P>Each foreign key column description has the following columns:\n   <OL>\n \t<LI><B>PKTABLE_CAT</B> String => primary key table catalog (may be null)\n \t<LI><B>PKTABLE_SCHEM</B> String => primary key table schema (may be null)\n \t<LI><B>PKTABLE_NAME</B> String => primary key table name\n \t<LI><B>PKCOLUMN_NAME</B> String => primary key column name\n \t<LI><B>FKTABLE_CAT</B> String => foreign key table catalog (may be null)\n       being exported (may be null)\n \t<LI><B>FKTABLE_SCHEM</B> String => foreign key table schema (may be null)\n       being exported (may be null)\n \t<LI><B>FKTABLE_NAME</B> String => foreign key table name\n       being exported\n \t<LI><B>FKCOLUMN_NAME</B> String => foreign key column name\n       being exported\n \t<LI><B>KEY_SEQ</B> short => sequence number within foreign key\n \t<LI><B>UPDATE_RULE</B> short => What happens to\n        foreign key when primary is updated:\n       <UL>\n       <LI> importedNoAction - do not allow update of primary\n                key if it has been imported\n       <LI> importedKeyCascade - change imported key to agree\n                with primary key update\n       <LI> importedKeySetNull - change imported key to NULL if\n                its primary key has been updated\n       <LI> importedKeySetDefault - change imported key to default values\n                if its primary key has been updated\n       <LI> importedKeyRestrict - same as importedKeyNoAction\n                                  (for ODBC 2.x compatibility)\n       </UL>\n \t<LI><B>DELETE_RULE</B> short => What happens to\n       the foreign key when primary is deleted.\n       <UL>\n       <LI> importedKeyNoAction - do not allow delete of primary\n                key if it has been imported\n       <LI> importedKeyCascade - delete rows that import a deleted key\n       <LI> importedKeySetNull - change imported key to NULL if\n                its primary key has been deleted\n       <LI> importedKeyRestrict - same as importedKeyNoAction\n                                  (for ODBC 2.x compatibility)\n       <LI> importedKeySetDefault - change imported key to default if\n                its primary key has been deleted\n       </UL>\n \t<LI><B>FK_NAME</B> String => foreign key name (may be null)\n \t<LI><B>PK_NAME</B> String => primary key name (may be null)\n \t<LI><B>DEFERRABILITY</B> short => can the evaluation of foreign key\n       constraints be deferred until commit\n       <UL>\n       <LI> importedKeyInitiallyDeferred - see SQL92 for definition\n       <LI> importedKeyInitiallyImmediate - see SQL92 for definition\n       <LI> importedKeyNotDeferrable - see SQL92 for definition\n       </UL>\n   </OL>\n\n  @param catalog a catalog name; \"\" retrieves those without a\n  catalog; null means drop catalog name from the selection criteria\n  @param schema a schema name; \"\" retrieves those\n  without a schema\n  @param table a table name\n  @return <code>ResultSet</code> - each row is a foreign key column description\n  @see #getImportedKeys\n}\nfunction TZAbstractDatabaseMetadata.GetExportedKeys(const Catalog: string;\n  const Schema: string; const Table: string): IZResultSet;\nvar\n  Key: string;\nbegin\n  if not GetConnection.UseMetadata then\n  begin\n    Result := ConstructVirtualResultSet(ExportedKeyColumnsDynArray);\n    exit;\n  end;\n\n  Key := GetExportedKeysCacheKey(Catalog, Schema, Table);\n  Result := GetResultSetFromCache(Key);\n  if Result = nil then\n  begin\n    Result := UncachedGetExportedKeys(Catalog, Schema, Table);\n    AddResultSetToCache(Key, Result);\n  end;\nend;\n\n{**\n  Gets a description of the foreign key columns that reference a\n  table's primary key columns (the foreign keys exported by a\n  table).  They are ordered by FKTABLE_CAT, FKTABLE_SCHEM,\n  FKTABLE_NAME, and KEY_SEQ.\n\n  <P>Each foreign key column description has the following columns:\n   <OL>\n \t<LI><B>PKTABLE_CAT</B> String => primary key table catalog (may be null)\n \t<LI><B>PKTABLE_SCHEM</B> String => primary key table schema (may be null)\n \t<LI><B>PKTABLE_NAME</B> String => primary key table name\n \t<LI><B>PKCOLUMN_NAME</B> String => primary key column name\n \t<LI><B>FKTABLE_CAT</B> String => foreign key table catalog (may be null)\n       being exported (may be null)\n \t<LI><B>FKTABLE_SCHEM</B> String => foreign key table schema (may be null)\n       being exported (may be null)\n \t<LI><B>FKTABLE_NAME</B> String => foreign key table name\n       being exported\n \t<LI><B>FKCOLUMN_NAME</B> String => foreign key column name\n       being exported\n \t<LI><B>KEY_SEQ</B> short => sequence number within foreign key\n \t<LI><B>UPDATE_RULE</B> short => What happens to\n        foreign key when primary is updated:\n       <UL>\n       <LI> importedNoAction - do not allow update of primary\n                key if it has been imported\n       <LI> importedKeyCascade - change imported key to agree\n                with primary key update\n       <LI> importedKeySetNull - change imported key to NULL if\n                its primary key has been updated\n       <LI> importedKeySetDefault - change imported key to default values\n                if its primary key has been updated\n       <LI> importedKeyRestrict - same as importedKeyNoAction\n                                  (for ODBC 2.x compatibility)\n       </UL>\n \t<LI><B>DELETE_RULE</B> short => What happens to\n       the foreign key when primary is deleted.\n       <UL>\n       <LI> importedKeyNoAction - do not allow delete of primary\n                key if it has been imported\n       <LI> importedKeyCascade - delete rows that import a deleted key\n       <LI> importedKeySetNull - change imported key to NULL if\n                its primary key has been deleted\n       <LI> importedKeyRestrict - same as importedKeyNoAction\n                                  (for ODBC 2.x compatibility)\n       <LI> importedKeySetDefault - change imported key to default if\n                its primary key has been deleted\n       </UL>\n \t<LI><B>FK_NAME</B> String => foreign key name (may be null)\n \t<LI><B>PK_NAME</B> String => primary key name (may be null)\n \t<LI><B>DEFERRABILITY</B> short => can the evaluation of foreign key\n       constraints be deferred until commit\n       <UL>\n       <LI> importedKeyInitiallyDeferred - see SQL92 for definition\n       <LI> importedKeyInitiallyImmediate - see SQL92 for definition\n       <LI> importedKeyNotDeferrable - see SQL92 for definition\n       </UL>\n   </OL>\n\n  @param catalog a catalog name; \"\" retrieves those without a\n  catalog; null means drop catalog name from the selection criteria\n  @param schema a schema name; \"\" retrieves those\n  without a schema\n  @param table a table name\n  @return <code>ResultSet</code> - each row is a foreign key column description\n  @see #getImportedKeys\n}\nfunction TZAbstractDatabaseMetadata.UncachedGetExportedKeys(const Catalog: string;\n  const Schema: string; const Table: string): IZResultSet;\nbegin\n    Result := ConstructVirtualResultSet(ExportedKeyColumnsDynArray);\nend;\n\n{**\n  Gets a description of the foreign key columns in the foreign key\n  table that reference the primary key columns of the primary key\n  table (describe how one table imports another's key.) This\n  should normally return a single foreign key/primary key pair\n  (most tables only import a foreign key from a table once.)  They\n  are ordered by FKTABLE_CAT, FKTABLE_SCHEM, FKTABLE_NAME, and\n  KEY_SEQ.\n\n  <P>Each foreign key column description has the following columns:\n   <OL>\n \t<LI><B>PKTABLE_CAT</B> String => primary key table catalog (may be null)\n \t<LI><B>PKTABLE_SCHEM</B> String => primary key table schema (may be null)\n \t<LI><B>PKTABLE_NAME</B> String => primary key table name\n \t<LI><B>PKCOLUMN_NAME</B> String => primary key column name\n \t<LI><B>FKTABLE_CAT</B> String => foreign key table catalog (may be null)\n       being exported (may be null)\n \t<LI><B>FKTABLE_SCHEM</B> String => foreign key table schema (may be null)\n       being exported (may be null)\n \t<LI><B>FKTABLE_NAME</B> String => foreign key table name\n       being exported\n \t<LI><B>FKCOLUMN_NAME</B> String => foreign key column name\n       being exported\n \t<LI><B>KEY_SEQ</B> short => sequence number within foreign key\n \t<LI><B>UPDATE_RULE</B> short => What happens to\n        foreign key when primary is updated:\n       <UL>\n       <LI> importedNoAction - do not allow update of primary\n                key if it has been imported\n       <LI> importedKeyCascade - change imported key to agree\n                with primary key update\n       <LI> importedKeySetNull - change imported key to NULL if\n                its primary key has been updated\n       <LI> importedKeySetDefault - change imported key to default values\n                if its primary key has been updated\n       <LI> importedKeyRestrict - same as importedKeyNoAction\n                                  (for ODBC 2.x compatibility)\n       </UL>\n \t<LI><B>DELETE_RULE</B> short => What happens to\n       the foreign key when primary is deleted.\n       <UL>\n       <LI> importedKeyNoAction - do not allow delete of primary\n                key if it has been imported\n       <LI> importedKeyCascade - delete rows that import a deleted key\n       <LI> importedKeySetNull - change imported key to NULL if\n                its primary key has been deleted\n       <LI> importedKeyRestrict - same as importedKeyNoAction\n                                  (for ODBC 2.x compatibility)\n       <LI> importedKeySetDefault - change imported key to default if\n                its primary key has been deleted\n       </UL>\n \t<LI><B>FK_NAME</B> String => foreign key name (may be null)\n \t<LI><B>PK_NAME</B> String => primary key name (may be null)\n \t<LI><B>DEFERRABILITY</B> short => can the evaluation of foreign key\n       constraints be deferred until commit\n       <UL>\n       <LI> importedKeyInitiallyDeferred - see SQL92 for definition\n       <LI> importedKeyInitiallyImmediate - see SQL92 for definition\n       <LI> importedKeyNotDeferrable - see SQL92 for definition\n       </UL>\n   </OL>\n\n  @param primaryCatalog a catalog name; \"\" retrieves those without a\n  catalog; null means drop catalog name from the selection criteria\n  @param primarySchema a schema name; \"\" retrieves those\n  without a schema\n  @param primaryTable the table name that exports the key\n  @param foreignCatalog a catalog name; \"\" retrieves those without a\n  catalog; null means drop catalog name from the selection criteria\n  @param foreignSchema a schema name; \"\" retrieves those\n  without a schema\n  @param foreignTable the table name that imports the key\n  @return <code>ResultSet</code> - each row is a foreign key column description\n  @see #getImportedKeys\n}\nfunction TZAbstractDatabaseMetadata.GetCrossReference(const PrimaryCatalog: string;\n  const PrimarySchema: string; const PrimaryTable: string; const ForeignCatalog: string;\n  const ForeignSchema: string; const ForeignTable: string): IZResultSet;\nvar\n  Key: string;\nbegin\n  if not GetConnection.UseMetadata then\n  begin\n    Result := ConstructVirtualResultSet(CrossRefColumnsDynArray);\n    exit;\n  end;\n\n  Key := GetCrossReferenceCacheKey(PrimaryCatalog, PrimarySchema, PrimaryTable,\n    ForeignCatalog, ForeignSchema, ForeignTable);\n\n  Result := GetResultSetFromCache(Key);\n  if Result = nil then\n  begin\n    Result := UncachedGetCrossReference(PrimaryCatalog, PrimarySchema, PrimaryTable,\n    ForeignCatalog, ForeignSchema, ForeignTable);\n    AddResultSetToCache(Key, Result);\n  end;\nend;\n\n{**\n  Gets a description of the foreign key columns in the foreign key\n  table that reference the primary key columns of the primary key\n  table (describe how one table imports another's key.) This\n  should normally return a single foreign key/primary key pair\n  (most tables only import a foreign key from a table once.)  They\n  are ordered by FKTABLE_CAT, FKTABLE_SCHEM, FKTABLE_NAME, and\n  KEY_SEQ.\n\n  <P>Each foreign key column description has the following columns:\n   <OL>\n \t<LI><B>PKTABLE_CAT</B> String => primary key table catalog (may be null)\n \t<LI><B>PKTABLE_SCHEM</B> String => primary key table schema (may be null)\n \t<LI><B>PKTABLE_NAME</B> String => primary key table name\n \t<LI><B>PKCOLUMN_NAME</B> String => primary key column name\n \t<LI><B>FKTABLE_CAT</B> String => foreign key table catalog (may be null)\n       being exported (may be null)\n \t<LI><B>FKTABLE_SCHEM</B> String => foreign key table schema (may be null)\n       being exported (may be null)\n \t<LI><B>FKTABLE_NAME</B> String => foreign key table name\n       being exported\n \t<LI><B>FKCOLUMN_NAME</B> String => foreign key column name\n       being exported\n \t<LI><B>KEY_SEQ</B> short => sequence number within foreign key\n \t<LI><B>UPDATE_RULE</B> short => What happens to\n        foreign key when primary is updated:\n       <UL>\n       <LI> importedNoAction - do not allow update of primary\n                key if it has been imported\n       <LI> importedKeyCascade - change imported key to agree\n                with primary key update\n       <LI> importedKeySetNull - change imported key to NULL if\n                its primary key has been updated\n       <LI> importedKeySetDefault - change imported key to default values\n                if its primary key has been updated\n       <LI> importedKeyRestrict - same as importedKeyNoAction\n                                  (for ODBC 2.x compatibility)\n       </UL>\n \t<LI><B>DELETE_RULE</B> short => What happens to\n       the foreign key when primary is deleted.\n       <UL>\n       <LI> importedKeyNoAction - do not allow delete of primary\n                key if it has been imported\n       <LI> importedKeyCascade - delete rows that import a deleted key\n       <LI> importedKeySetNull - change imported key to NULL if\n                its primary key has been deleted\n       <LI> importedKeyRestrict - same as importedKeyNoAction\n                                  (for ODBC 2.x compatibility)\n       <LI> importedKeySetDefault - change imported key to default if\n                its primary key has been deleted\n       </UL>\n \t<LI><B>FK_NAME</B> String => foreign key name (may be null)\n \t<LI><B>PK_NAME</B> String => primary key name (may be null)\n \t<LI><B>DEFERRABILITY</B> short => can the evaluation of foreign key\n       constraints be deferred until commit\n       <UL>\n       <LI> importedKeyInitiallyDeferred - see SQL92 for definition\n       <LI> importedKeyInitiallyImmediate - see SQL92 for definition\n       <LI> importedKeyNotDeferrable - see SQL92 for definition\n       </UL>\n   </OL>\n\n  @param primaryCatalog a catalog name; \"\" retrieves those without a\n  catalog; null means drop catalog name from the selection criteria\n  @param primarySchema a schema name; \"\" retrieves those\n  without a schema\n  @param primaryTable the table name that exports the key\n  @param foreignCatalog a catalog name; \"\" retrieves those without a\n  catalog; null means drop catalog name from the selection criteria\n  @param foreignSchema a schema name; \"\" retrieves those\n  without a schema\n  @param foreignTable the table name that imports the key\n  @return <code>ResultSet</code> - each row is a foreign key column description\n  @see #getImportedKeys\n}\nfunction TZAbstractDatabaseMetadata.UncachedGetCrossReference(const PrimaryCatalog: string;\n  const PrimarySchema: string; const PrimaryTable: string; const ForeignCatalog: string;\n  const ForeignSchema: string; const ForeignTable: string): IZResultSet;\nbegin\n    Result := ConstructVirtualResultSet(CrossRefColumnsDynArray);\nend;\n\n{**\n  Gets a description of all the standard SQL types supported by\n  this database. They are ordered by DATA_TYPE and then by how\n  closely the data type maps to the corresponding JDBC SQL type.\n\n  <P>Each type description has the following columns:\n   <OL>\n \t<LI><B>TYPE_NAME</B> String => Type name\n \t<LI><B>DATA_TYPE</B> short => SQL data type from java.sql.Types\n \t<LI><B>PRECISION</B> int => maximum precision\n \t<LI><B>LITERAL_PREFIX</B> String => prefix used to quote a literal\n       (may be null)\n \t<LI><B>LITERAL_SUFFIX</B> String => suffix used to quote a literal\n        (may be null)\n \t<LI><B>CREATE_PARAMS</B> String => parameters used in creating\n       the type (may be null)\n \t<LI><B>NULLABLE</B> short => can you use NULL for this type?\n       <UL>\n       <LI> typeNoNulls - does not allow NULL values\n       <LI> typeNullable - allows NULL values\n       <LI> typeNullableUnknown - nullability unknown\n       </UL>\n \t<LI><B>CASE_SENSITIVE</B> boolean=> is it case sensitive?\n \t<LI><B>SEARCHABLE</B> short => can you use \"WHERE\" based on this type:\n       <UL>\n       <LI> typePredNone - No support\n       <LI> typePredChar - Only supported with WHERE .. LIKE\n       <LI> typePredBasic - Supported except for WHERE .. LIKE\n       <LI> typeSearchable - Supported for all WHERE ..\n       </UL>\n \t<LI><B>UNSIGNED_ATTRIBUTE</B> boolean => is it unsigned?\n \t<LI><B>FIXED_PREC_SCALE</B> boolean => can it be a money value?\n \t<LI><B>AUTO_INCREMENT</B> boolean => can it be used for an\n       auto-increment value?\n \t<LI><B>LOCAL_TYPE_NAME</B> String => localized version of type name\n       (may be null)\n \t<LI><B>MINIMUM_SCALE</B> short => minimum scale supported\n \t<LI><B>MAXIMUM_SCALE</B> short => maximum scale supported\n \t<LI><B>SQL_DATA_TYPE</B> int => unused\n \t<LI><B>SQL_DATETIME_SUB</B> int => unused\n \t<LI><B>NUM_PREC_RADIX</B> int => usually 2 or 10\n   </OL>\n\n  @return <code>ResultSet</code> - each row is an SQL type description\n}\nfunction TZAbstractDatabaseMetadata.GetTypeInfo: IZResultSet;\nvar\n  Key: string;\nbegin\n  if not GetConnection.UseMetadata then\n  begin\n    Result := ConstructVirtualResultSet(TypeInfoColumnsDynArray);\n    exit;\n  end;\n\n  Key := GetTypeInfoCacheKey;\n  Result := GetResultSetFromCache(Key);\n  if Result = nil then\n  begin\n    Result := UncachedGetTypeInfo;\n    AddResultSetToCache(Key, Result);\n  end;\nend;\n\n{**\n  Gets a description of all the standard SQL types supported by\n  this database. They are ordered by DATA_TYPE and then by how\n  closely the data type maps to the corresponding JDBC SQL type.\n\n  <P>Each type description has the following columns:\n   <OL>\n \t<LI><B>TYPE_NAME</B> String => Type name\n \t<LI><B>DATA_TYPE</B> short => SQL data type from java.sql.Types\n \t<LI><B>PRECISION</B> int => maximum precision\n \t<LI><B>LITERAL_PREFIX</B> String => prefix used to quote a literal\n       (may be null)\n \t<LI><B>LITERAL_SUFFIX</B> String => suffix used to quote a literal\n        (may be null)\n \t<LI><B>CREATE_PARAMS</B> String => parameters used in creating\n       the type (may be null)\n \t<LI><B>NULLABLE</B> short => can you use NULL for this type?\n       <UL>\n       <LI> typeNoNulls - does not allow NULL values\n       <LI> typeNullable - allows NULL values\n       <LI> typeNullableUnknown - nullability unknown\n       </UL>\n \t<LI><B>CASE_SENSITIVE</B> boolean=> is it case sensitive?\n \t<LI><B>SEARCHABLE</B> short => can you use \"WHERE\" based on this type:\n       <UL>\n       <LI> typePredNone - No support\n       <LI> typePredChar - Only supported with WHERE .. LIKE\n       <LI> typePredBasic - Supported except for WHERE .. LIKE\n       <LI> typeSearchable - Supported for all WHERE ..\n       </UL>\n \t<LI><B>UNSIGNED_ATTRIBUTE</B> boolean => is it unsigned?\n \t<LI><B>FIXED_PREC_SCALE</B> boolean => can it be a money value?\n \t<LI><B>AUTO_INCREMENT</B> boolean => can it be used for an\n       auto-increment value?\n \t<LI><B>LOCAL_TYPE_NAME</B> String => localized version of type name\n       (may be null)\n \t<LI><B>MINIMUM_SCALE</B> short => minimum scale supported\n \t<LI><B>MAXIMUM_SCALE</B> short => maximum scale supported\n \t<LI><B>SQL_DATA_TYPE</B> int => unused\n \t<LI><B>SQL_DATETIME_SUB</B> int => unused\n \t<LI><B>NUM_PREC_RADIX</B> int => usually 2 or 10\n   </OL>\n\n  @return <code>ResultSet</code> - each row is an SQL type description\n}\nfunction TZAbstractDatabaseMetadata.UncachedGetTypeInfo: IZResultSet;\nbegin\n    Result := ConstructVirtualResultSet(TypeInfoColumnsDynArray);\nend;\n\n{**\n  Gets a description of a table's indices and statistics. They are\n  ordered by NON_UNIQUE, TYPE, INDEX_NAME, and ORDINAL_POSITION.\n\n  <P>Each index column description has the following columns:\n   <OL>\n \t<LI><B>TABLE_CAT</B> String => table catalog (may be null)\n \t<LI><B>TABLE_SCHEM</B> String => table schema (may be null)\n \t<LI><B>TABLE_NAME</B> String => table name\n \t<LI><B>NON_UNIQUE</B> boolean => Can index values be non-unique?\n       false when TYPE is tableIndexStatistic\n \t<LI><B>INDEX_QUALIFIER</B> String => index catalog (may be null);\n       null when TYPE is tableIndexStatistic\n \t<LI><B>INDEX_NAME</B> String => index name; null when TYPE is\n       tableIndexStatistic\n \t<LI><B>TYPE</B> short => index type:\n       <UL>\n       <LI> tableIndexStatistic - this identifies table statistics that are\n            returned in conjuction with a table's index descriptions\n       <LI> tableIndexClustered - this is a clustered index\n       <LI> tableIndexHashed - this is a hashed index\n       <LI> tableIndexOther - this is some other style of index\n       </UL>\n \t<LI><B>ORDINAL_POSITION</B> short => column sequence number\n       within index; zero when TYPE is tableIndexStatistic\n \t<LI><B>COLUMN_NAME</B> String => column name; null when TYPE is\n       tableIndexStatistic\n \t<LI><B>ASC_OR_DESC</B> String => column sort sequence, \"A\" => ascending,\n       \"D\" => descending, may be null if sort sequence is not supported;\n       null when TYPE is tableIndexStatistic\n \t<LI><B>CARDINALITY</B> int => When TYPE is tableIndexStatistic, then\n       this is the number of rows in the table; otherwise, it is the\n       number of unique values in the index.\n \t<LI><B>PAGES</B> int => When TYPE is  tableIndexStatisic then\n       this is the number of pages used for the table, otherwise it\n       is the number of pages used for the current index.\n \t<LI><B>FILTER_CONDITION</B> String => Filter condition, if any.\n       (may be null)\n   </OL>\n\n  @param catalog a catalog name; \"\" retrieves those without a\n  catalog; null means drop catalog name from the selection criteria\n  @param schema a schema name; \"\" retrieves those without a schema\n  @param table a table name\n  @param unique when true, return only indices for unique values;\n      when false, return indices regardless of whether unique or not\n  @param approximate when true, result is allowed to reflect approximate\n      or out of data values; when false, results are requested to be\n      accurate\n  @return <code>ResultSet</code> - each row is an index column description\n}\nfunction TZAbstractDatabaseMetadata.GetIndexInfo(const Catalog: string;\n  const Schema: string; const Table: string; Unique: Boolean;\n  Approximate: Boolean): IZResultSet;\nvar\n  Key: string;\nbegin\n  if not GetConnection.UseMetadata then\n  begin\n    Result := ConstructVirtualResultSet(IndexInfoColumnsDynArray);\n    exit;\n  end;\n\n  Key := GetIndexInfoCacheKey(Catalog, Schema, Table, Unique, Approximate);\n\n  Result := GetResultSetFromCache(Key);\n  if Result = nil then\n  begin\n    Result := UncachedGetIndexInfo(Catalog, Schema, Table, Unique, Approximate);\n    AddResultSetToCache(Key, Result);\n  end;\nend;\n\n{**\n  Gets a description of a table's indices and statistics. They are\n  ordered by NON_UNIQUE, TYPE, INDEX_NAME, and ORDINAL_POSITION.\n\n  <P>Each index column description has the following columns:\n   <OL>\n \t<LI><B>TABLE_CAT</B> String => table catalog (may be null)\n \t<LI><B>TABLE_SCHEM</B> String => table schema (may be null)\n \t<LI><B>TABLE_NAME</B> String => table name\n \t<LI><B>NON_UNIQUE</B> boolean => Can index values be non-unique?\n       false when TYPE is tableIndexStatistic\n \t<LI><B>INDEX_QUALIFIER</B> String => index catalog (may be null);\n       null when TYPE is tableIndexStatistic\n \t<LI><B>INDEX_NAME</B> String => index name; null when TYPE is\n       tableIndexStatistic\n \t<LI><B>TYPE</B> short => index type:\n       <UL>\n       <LI> tableIndexStatistic - this identifies table statistics that are\n            returned in conjuction with a table's index descriptions\n       <LI> tableIndexClustered - this is a clustered index\n       <LI> tableIndexHashed - this is a hashed index\n       <LI> tableIndexOther - this is some other style of index\n       </UL>\n \t<LI><B>ORDINAL_POSITION</B> short => column sequence number\n       within index; zero when TYPE is tableIndexStatistic\n \t<LI><B>COLUMN_NAME</B> String => column name; null when TYPE is\n       tableIndexStatistic\n \t<LI><B>ASC_OR_DESC</B> String => column sort sequence, \"A\" => ascending,\n       \"D\" => descending, may be null if sort sequence is not supported;\n       null when TYPE is tableIndexStatistic\n \t<LI><B>CARDINALITY</B> int => When TYPE is tableIndexStatistic, then\n       this is the number of rows in the table; otherwise, it is the\n       number of unique values in the index.\n \t<LI><B>PAGES</B> int => When TYPE is  tableIndexStatisic then\n       this is the number of pages used for the table, otherwise it\n       is the number of pages used for the current index.\n \t<LI><B>FILTER_CONDITION</B> String => Filter condition, if any.\n       (may be null)\n   </OL>\n\n  @param catalog a catalog name; \"\" retrieves those without a\n  catalog; null means drop catalog name from the selection criteria\n  @param schema a schema name; \"\" retrieves those without a schema\n  @param table a table name\n  @param unique when true, return only indices for unique values;\n      when false, return indices regardless of whether unique or not\n  @param approximate when true, result is allowed to reflect approximate\n      or out of data values; when false, results are requested to be\n      accurate\n  @return <code>ResultSet</code> - each row is an index column description\n}\nfunction TZAbstractDatabaseMetadata.UncachedGetIndexInfo(const Catalog: string;\n  const Schema: string; const Table: string; Unique: Boolean;\n  Approximate: Boolean): IZResultSet;\nbegin\n    Result := ConstructVirtualResultSet(IndexInfoColumnsDynArray);\nend;\n\nfunction TZAbstractDatabaseMetadata.GetSequences(const Catalog: string;\n  const SchemaPattern: string; const SequenceNamePattern: string): IZResultSet;\nvar\n  Key: string;\nbegin\n  if not GetConnection.UseMetadata then\n  begin\n    Result := ConstructVirtualResultSet(SequenceColumnsDynArray);\n    exit;\n  end;\n\n  Key := GetSequencesCacheKey(Catalog, SchemaPattern, SequenceNamePattern);\n  Result := GetResultSetFromCache(Key);\n  if Result = nil then\n  begin\n    Result := UncachedGetSequences(Catalog, SchemaPattern, SequenceNamePattern);\n    AddResultSetToCache(Key, Result);\n  end;\nend;\n\nfunction TZAbstractDatabaseMetadata.UncachedGetSequences(const Catalog: string;\n  const SchemaPattern: string; const SequenceNamePattern: string): IZResultSet;\nbegin\n    Result := ConstructVirtualResultSet(SequenceColumnsDynArray);\nend;\n\n{**\n\n  Gets a description of the user-defined types defined in a particular\n  schema.  Schema-specific UDTs may have type JAVA_OBJECT, STRUCT,\n  or DISTINCT.\n\n  <P>Only types matching the catalog, schema, type name and type\n  criteria are returned.  They are ordered by DATA_TYPE, TYPE_SCHEM\n  and TYPE_NAME.  The type name parameter may be a fully-qualified\n  name.  In this case, the catalog and schemaPattern parameters are\n  ignored.\n\n  <P>Each type description has the following columns:\n   <OL>\n \t<LI><B>TYPE_CAT</B> String => the type's catalog (may be null)\n \t<LI><B>TYPE_SCHEM</B> String => type's schema (may be null)\n \t<LI><B>TYPE_NAME</B> String => type name\n   <LI><B>CLASS_NAME</B> String => Java class name\n \t<LI><B>DATA_TYPE</B> String => type value defined in java.sql.Types.\n   One of JAVA_OBJECT, STRUCT, or DISTINCT\n \t<LI><B>REMARKS</B> String => explanatory comment on the type\n   </OL>\n\n  <P><B>Note:</B> If the driver does not support UDTs, an empty\n  result set is returned.\n\n  @param catalog a catalog name; \"\" retrieves those without a\n  catalog; null means drop catalog name from the selection criteria\n  @param schemaPattern a schema name pattern; \"\" retrieves those\n  without a schema\n  @param typeNamePattern a type name pattern; may be a fully-qualified name\n  @param types a list of user-named types to include (JAVA_OBJECT,\n  STRUCT, or DISTINCT); null returns all types\n  @return <code>ResultSet</code> - each row is a type description\n}\nfunction TZAbstractDatabaseMetadata.GetUDTs(const Catalog: string;\n  const SchemaPattern: string; const TypeNamePattern: string;\n  const Types: TIntegerDynArray): IZResultSet;\nvar\n  Key: string;\nbegin\n  if not GetConnection.UseMetadata then\n  begin\n    Result := ConstructVirtualResultSet(UDTColumnsDynArray);\n    exit;\n  end;\n\n  Key := GetUDTsCacheKey(Catalog, SchemaPattern, TypeNamePattern,\n    Types);\n\n  Result := GetResultSetFromCache(Key);\n  if Result = nil then\n  begin\n    Result := UncachedGetUDTs(Catalog, SchemaPattern, TypeNamePattern, Types);\n    AddResultSetToCache(Key, Result);\n  end;\nend;\n\n{**\n\n  Gets a description of the user-defined types defined in a particular\n  schema.  Schema-specific UDTs may have type JAVA_OBJECT, STRUCT,\n  or DISTINCT.\n\n  <P>Only types matching the catalog, schema, type name and type\n  criteria are returned.  They are ordered by DATA_TYPE, TYPE_SCHEM\n  and TYPE_NAME.  The type name parameter may be a fully-qualified\n  name.  In this case, the catalog and schemaPattern parameters are\n  ignored.\n\n  <P>Each type description has the following columns:\n   <OL>\n \t<LI><B>TYPE_CAT</B> String => the type's catalog (may be null)\n \t<LI><B>TYPE_SCHEM</B> String => type's schema (may be null)\n \t<LI><B>TYPE_NAME</B> String => type name\n   <LI><B>CLASS_NAME</B> String => Java class name\n \t<LI><B>DATA_TYPE</B> String => type value defined in java.sql.Types.\n   One of JAVA_OBJECT, STRUCT, or DISTINCT\n \t<LI><B>REMARKS</B> String => explanatory comment on the type\n   </OL>\n\n  <P><B>Note:</B> If the driver does not support UDTs, an empty\n  result set is returned.\n\n  @param catalog a catalog name; \"\" retrieves those without a\n  catalog; null means drop catalog name from the selection criteria\n  @param schemaPattern a schema name pattern; \"\" retrieves those\n  without a schema\n  @param typeNamePattern a type name pattern; may be a fully-qualified name\n  @param types a list of user-named types to include (JAVA_OBJECT,\n  STRUCT, or DISTINCT); null returns all types\n  @return <code>ResultSet</code> - each row is a type description\n}\nfunction TZAbstractDatabaseMetadata.UncachedGetUDTs(const Catalog: string;\n  const SchemaPattern: string; const TypeNamePattern: string;\n  const Types: TIntegerDynArray): IZResultSet;\nbegin\n    Result := ConstructVirtualResultSet(UDTColumnsDynArray);\nend;\n\n{**\n  Creates ab identifier convertor object.\n  @returns an identifier convertor object.\n}\nfunction TZAbstractDatabaseMetadata.GetIdentifierConvertor:\n  IZIdentifierConvertor;\nbegin\n  Result := TZDefaultIdentifierConvertor.Create(Self);\nend;\n\n{**\n  Add escape character in the pattern that has wildcards character\n  @param Pattern The pattern that would be escaped\n  @return Escaped Pattern\n}\nfunction TZAbstractDatabaseMetadata.AddEscapeCharToWildcards(\n  const Pattern: string): string;\nvar\n  i:Integer;\n  EscapeChar : string;\nbegin\n  if GetDatabaseInfo.SupportsNonEscapedSearchStrings then\n    Result := Pattern\n  else\n  begin\n    EscapeChar := GetDatabaseInfo.GetSearchStringEscape;\n    if WildcardsArray<>nil then\n    begin\n      Result:=StringReplace(Pattern,EscapeChar,EscapeChar+EscapeChar,[rfReplaceAll]);\n      for i:=0 to High(WildcardsArray) do\n        Result:=StringReplace(Result,WildcardsArray[i],EscapeChar+WildcardsArray[i],[rfReplaceAll]);\n    end;\n  end;\nend;\n\n{**\n  Set the Wildcards character for WildcardsArray variable.\n  Overrride this method if the wildcards character is different in other database\n}\nprocedure TZAbstractDatabaseMetadata.FillWildcards;\nbegin\n  SetLength(WildcardsArray,1);\n  WildcardsArray[0]:='%';\n  {SetLength(WildcardsArray,2);\n  WildcardsArray[0]:='_';  <---- seems to be a trublemaker, no idea how to test it with our tests. See http://zeoslib.sourceforge.net/viewtopic.php?f=40&t=13184\n  WildcardsArray[1]:='%';}\nend;\n\nfunction TZAbstractDatabaseMetadata.NormalizePatternCase(Pattern:String): string;\nbegin\n  if not GetIdentifierConvertor.IsQuoted(Pattern) then\n    if FDatabaseInfo.StoresUpperCaseIdentifiers then\n      Result := UpperCase(Pattern)\n    else if FDatabaseInfo.StoresLowerCaseIdentifiers then\n      Result := LowerCase(Pattern)\n    else Result := Pattern\n  else\n    Result := GetIdentifierConvertor.ExtractQuote(Pattern);\nend;\n\n{**\n  Get the Wildscards in set of char type\n  @return TZWildcardsSet type\n}\nfunction TZAbstractDatabaseMetadata.GetWildcardsSet:TZWildcardsSet;\nvar i:Integer;\nbegin\n  Result:=[];\n  for i:=0 to High(WildcardsArray) do\n    Result:=Result+[WildcardsArray[i]];\nend;\n\n//----------------------------------------------------------------------\n// Metadata cache key retrieval API (technobot 2008-06-14):\n\n{**\n  returns cache key for GetProcedures metadata entry\n  @param Catalog a catalog name\n  @param SchemaPattern a schema name pattern\n  @param ProcedureNamePattern a procedure name pattern\n  @return the cache key string\n}\nfunction TZAbstractDatabaseMetadata.GetProceduresCacheKey(const Catalog: string;\n  const SchemaPattern: string; const ProcedureNamePattern: string): string;\nbegin\n  Result := Format('get-procedures:%s:%s:%s',\n    [Catalog, SchemaPattern, ProcedureNamePattern]);\nend;\n\n{**\n  returns cache key for GetProcedureColumns metadata entry\n  @param Catalog a catalog name\n  @param SchemaPattern a schema name pattern\n  @param ProcedureNamePattern a procedure name pattern\n  @param ColumnNamePattern a column name pattern\n  @return the cache key string\n}\nfunction TZAbstractDatabaseMetadata.GetProcedureColumnsCacheKey(const Catalog: string;\n  const SchemaPattern: string; const ProcedureNamePattern: string;\n  const ColumnNamePattern: string): string;\nbegin\n  Result := Format('get-procedure-columns:%s:%s:%s:%s',\n    [Catalog, SchemaPattern, ProcedureNamePattern, ColumnNamePattern]);\nend;\n\n{**\n  returns cache key for GetTables metadata entry\n  @param Catalog a catalog name\n  @param SchemaPattern a schema name pattern\n  @param TableNamePattern a table name pattern\n  @param Types table types list\n  @return the cache key string\n}\nfunction TZAbstractDatabaseMetadata.GetTablesCacheKey(const Catalog: string;\n  const SchemaPattern: string; const TableNamePattern: string;\n  const Types: TStringDynArray): string;\nvar\n  I: Integer;\n  Key: string;\nbegin\n  Key := '';\n  for I := Low(Types) to High(Types) do\n    Key := Key + ':' + Types[I];\n\n  Result := Format('get-tables:%s:%s:%s:%s',\n    [Catalog, SchemaPattern, TableNamePattern, Key]);\nend;\n\n{**\n  returns cache key for GetSchemas metadata entry\n  @return the cache key string\n}\nfunction TZAbstractDatabaseMetadata.GetSchemasCacheKey: string;\nbegin\n  Result := 'get-schemas';\nend;\n\n{**\n  returns cache key for GetCatalogs metadata entry\n  @return the cache key string\n}\nfunction TZAbstractDatabaseMetadata.GetCatalogsCacheKey: string;\nbegin\n  Result := 'get-catalogs';\nend;\n\n{**\n  returns cache key for GetTableTypes metadata entry\n  @return the cache key string\n}\nfunction TZAbstractDatabaseMetadata.GetTableTypesCacheKey: string;\nbegin\n  Result := 'get-table-types';\nend;\n\n{**\n  returns cache key for GetColumns metadata entry\n  @param Catalog a catalog name\n  @param SchemaPattern a schema name pattern\n  @param TableNamePattern a table name pattern\n  @param ColumnNamePattern a column name pattern\n  @return the cache key string\n}\nfunction TZAbstractDatabaseMetadata.GetColumnsCacheKey(const Catalog: string;\n  const SchemaPattern: string; const TableNamePattern: string;\n  const ColumnNamePattern: string): string;\nbegin\n  Result := Format('get-columns:%s:%s:%s:%s',\n    [Catalog, SchemaPattern, TableNamePattern, ColumnNamePattern]);\nend;\n\n{**\n  returns cache key for GetColumnPrivileges metadata entry\n  @param Catalog a catalog name\n  @param Schema a schema name\n  @param Table a table name\n  @param ColumnNamePattern a column name pattern\n  @return the cache key string\n}\nfunction TZAbstractDatabaseMetadata.GetColumnPrivilegesCacheKey(\n  const Catalog: string; const Schema: string; const Table: string;\n  const ColumnNamePattern: string): string;\nbegin\n  Result := Format('get-column-privileges:%s:%s:%s:%s',\n    [Catalog, Schema, Table, ColumnNamePattern]);\nend;\n\n{**\n  returns cache key for GetTablePrivileges metadata entry\n  @param Catalog a catalog name\n  @param SchemaPattern a schema name pattern\n  @param TableNamePattern a table name pattern\n  @return the cache key string\n}\nfunction TZAbstractDatabaseMetadata.GetTablePrivilegesCacheKey(\n  const Catalog: string; const SchemaPattern: string;\n  const TableNamePattern: string): string;\nbegin\n  Result := Format('get-table-privileges:%s:%s:%s',\n    [Catalog, SchemaPattern, TableNamePattern]);\nend;\n\n{**\n  returns cache key for GetBestRowIdentifier metadata entry\n  @param Catalog a catalog name\n  @param Schema a schema name\n  @param Table a table name\n  @param Scope the scope of interest\n  @param Nullable include columns that are nullable?\n  @return the cache key string\n}\nfunction TZAbstractDatabaseMetadata.GetBestRowIdentifierCacheKey(\n  const Catalog: string; const Schema: string; const Table: string;\n  const Scope: Integer; const Nullable: Boolean): string;\nbegin\n  Result := Format('get-best-row-identifier:%s:%s:%s:%d:%s',\n    [Catalog, Schema, Table, Scope, BoolToStr(Nullable)]);\nend;\n\n{**\n  returns cache key for GetVersionColumns metadata entry\n  @param Catalog a catalog name\n  @param Schema a schema name\n  @param Table a table name\n  @return the cache key string\n}\nfunction TZAbstractDatabaseMetadata.GetVersionColumnsCacheKey(\n  const Catalog: string; const Schema: string; const Table: string): string;\nbegin\n  Result := Format('get-version-columns:%s:%s:%s', [Catalog, Schema, Table]);\nend;\n\n{**\n  returns cache key for GetPrimaryKeys metadata entry\n  @param Catalog a catalog name\n  @param Schema a schema name\n  @param Table a table name\n  @return the cache key string\n}\nfunction TZAbstractDatabaseMetadata.GetPrimaryKeysCacheKey(const Catalog: string;\n  const Schema: string; const Table: string): string;\nbegin\n  Result := Format('get-primary-keys:%s:%s:%s', [Catalog, Schema, Table]);\nend;\n\n{**\n  returns cache key for GetImportedKeys metadata entry\n  @param Catalog a catalog name\n  @param Schema a schema name\n  @param Table a table name\n  @return the cache key string\n}\nfunction TZAbstractDatabaseMetadata.GetImportedKeysCacheKey(const Catalog: string;\n  const Schema: string; const Table: string): string;\nbegin\n  Result := Format('get-imported-keys:%s:%s:%s', [Catalog, Schema, Table]);\nend;\n\n{**\n  returns cache key for GetExportedKeys metadata entry\n  @param Catalog a catalog name\n  @param Schema a schema name\n  @param Table a table name\n  @return the cache key string\n}\nfunction TZAbstractDatabaseMetadata.GetExportedKeysCacheKey(const Catalog: string;\n  const Schema: string; const Table: string): string;\nbegin\n  Result := Format('get-exported-keys:%s:%s:%s', [Catalog, Schema, Table]);\nend;\n\n{**\n  returns cache key for GetCrossReference metadata entry\n  @param PrimaryCatalog a catalog name for the primary table\n  @param PrimarySchema a schema name for the primary table\n  @param PrimaryTable the table name that exports the key\n  @param ForeignCatalog a catalog name for the foreign table\n  @param ForeignSchema a schema name for the foreign table\n  @param ForeignTable the table name that imports the key\n  @return the cache key string\n}\nfunction TZAbstractDatabaseMetadata.GetCrossReferenceCacheKey(\n  const PrimaryCatalog: string; const PrimarySchema: string;\n  const PrimaryTable: string; const ForeignCatalog: string;\n  const ForeignSchema: string; const ForeignTable: string): string;\nbegin\n  Result := Format('get-cross-reference:%s:%s:%s:%s:%s:%s',\n    [PrimaryCatalog, PrimarySchema, PrimaryTable, ForeignCatalog,\n    ForeignSchema, ForeignTable]);\nend;\n\n{**\n  returns cache key for GetTypeInfo metadata entry\n  @return the cache key string\n}\nfunction TZAbstractDatabaseMetadata.GetTypeInfoCacheKey: string;\nbegin\n  Result := 'get-type-info';\nend;\n\n{**\n  returns cache key for GetIndexInfo metadata entry\n  @param Catalog a catalog name\n  @param Schema a schema name\n  @param Table a table name\n  @param Unique when true, return key for a metadata entry that should contain\n      only indices for unique values; when false, return key for a metadata\n      entry that may contain indices to non-unique values\n  @param Approximate when true, return key for a metadata entry that may include\n      approximate or out of data values; when false, return key for a metadata\n      entry that should contain only accurate results\n  @return the cache key string\n}\nfunction TZAbstractDatabaseMetadata.GetIndexInfoCacheKey(const Catalog: string;\n  const Schema: string; const Table: string; const Unique: Boolean;\n  const Approximate: Boolean): string;\nbegin\n  Result := Format('get-index-info:%s:%s:%s:%s:%s',\n    [Catalog, Schema, Table, BoolToStr(Unique), BoolToStr(Approximate)]);\nend;\n\n{**\n  returns cache key for GetSequences metadata entry\n  @param Catalog a catalog name\n  @param SchemaPattern a schema name pattern\n  @param SequenceNamePattern a sequence name pattern\n  @return the cache key string\n}\nfunction TZAbstractDatabaseMetadata.GetSequencesCacheKey(const Catalog: string;\n  const SchemaPattern: string; const SequenceNamePattern: string): string;\nbegin\n  Result := Format('get-sequences:%s:%s:%s',\n    [Catalog, SchemaPattern, SequenceNamePattern]);\nend;\n\n{**\n  returns cache key for GetUDTs metadata entry\n  @param Catalog a catalog name\n  @param SchemaPattern a schema name pattern\n  @param TypeNamePattern a type name pattern\n  @param Types a list of user-named types to include\n  @return the cache key string\n}\nfunction TZAbstractDatabaseMetadata.GetUDTsCacheKey(const Catalog: string;\n  const SchemaPattern: string; const TypeNamePattern: string;\n  const Types: TIntegerDynArray): string;\nvar\n  I: Integer;\nbegin\n  Result := '';\n  for I := Low(Types) to High(Types) do\n    Result := Result + ':' + IntToStr(Types[I]);\n  Result := Format('get-udts:%s:%s:%s%s',\n    [Catalog, SchemaPattern, TypeNamePattern, Result]);\nend;\n\n{**\n  fills string list with the keys for the currently cached metadata entries\n  @param List a string list to fill out\n}\nprocedure TZAbstractDatabaseMetadata.GetCacheKeys(List: TStrings);\nvar\n  I: Integer;\nbegin\n  List.Clear;\n  with CachedResultSets.Keys do\n    for I := 0 to Count-1 do\n      List.Add((Items[I] as IZAnyValue).GetString);\nend;\n\n// End of metadata cache key retrieval API (technobot 2008-06-14)\n//----------------------------------------------------------------------\n\n\n{ TZVirtualResultSet }\n\n{**\n  Creates this object and assignes the main properties.\n  @param Statement an SQL statement object.\n  @param SQL an SQL query string.\n}\nconstructor TZVirtualResultSet.CreateWithStatement(const SQL: string;\n   Statement: IZStatement; ConSettings: PZConSettings);\nbegin\n  inherited CreateWithStatement(SQL, Statement, ConSettings);\nend;\n\n{**\n  Creates this object and assignes the main properties.\n  @param ColumnsInfo a columns info for cached rows.\n  @param SQL an SQL query string.\n}\nconstructor TZVirtualResultSet.CreateWithColumns(ColumnsInfo: TObjectList;\n  const SQL: string; ConSettings: PZConSettings);\nbegin\n  inherited CreateWithColumns(ColumnsInfo, SQL, ConSettings);\nend;\n\n{**\n  Destroys this object and cleanups the memory.\n}\ndestructor TZVirtualResultSet.Destroy;\nbegin\n  inherited Destroy;\nend;\n\n{**\n  Calculates column default values..\n  @param RowAccessor a row accessor which contains new column values.\n}\nprocedure TZVirtualResultSet.CalculateRowDefaults(RowAccessor: TZRowAccessor);\nbegin\nend;\n\n{**\n  Post changes to database server.\n  @param OldRowAccessor a row accessor which contains old column values.\n  @param NewRowAccessor a row accessor which contains new or updated\n    column values.\n}\nprocedure TZVirtualResultSet.PostRowUpdates(OldRowAccessor,\n  NewRowAccessor: TZRowAccessor);\nbegin\nend;\n\n{ TZDefaultIdentifierConvertor }\n\n{**\n  Constructs this default identifier convertor object.\n  @param Metadata a database metadata interface.\n}\nconstructor TZDefaultIdentifierConvertor.Create(\n  Metadata: IZDatabaseMetadata);\nbegin\n  inherited Create;\n  FMetadata := Pointer(Metadata);\nend;\n\nfunction TZDefaultIdentifierConvertor.GetMetaData;\nbegin\n  if Assigned(FMetadata) then\n    Result := IZDatabaseMetadata(FMetadata)\n  else\n    Result := nil;\nend;\n\n{**\n  Checks is the specified string in lower case.\n  @param an identifier string.\n  @return <code>True</code> is the identifier string in lower case.\n}\nfunction TZDefaultIdentifierConvertor.IsLowerCase(const Value: string): Boolean;\nvar\n  I: Integer;\nbegin\n  Result := True;\n  for I := 1 to Length(Value) do\n  begin\n    if not CharInSet(Value[I], ['a'..'z','0'..'9','_']) then\n    begin\n      Result := False;\n      Break;\n    end;\n  end;\nend;\n\n{**\n  Checks is the specified string in upper case.\n  @param an identifier string.\n  @return <code>True</code> is the identifier string in upper case.\n}\nfunction TZDefaultIdentifierConvertor.IsUpperCase(const Value: string): Boolean;\nvar\n  I: Integer;\nbegin\n  Result := True;\n  for I := 1 to Length(Value) do\n  begin\n    if not CharInSet(Value[I], ['A'..'Z','0'..'9','_']) then\n    begin\n      Result := False;\n      Break;\n    end;\n  end;\nend;\n\n{**\n  Checks is the specified string in special case.\n  @param an identifier string.\n  @return <code>True</code> is the identifier string in mixed case.\n}\nfunction TZDefaultIdentifierConvertor.IsSpecialCase(const Value: string): Boolean;\nvar\n  I: Integer;\nbegin\n  Result := False;\n  if CharInSet(Value[1], ['0'..'9']) then\n  begin\n    Result := True;\n    exit;\n  end;\n  for I := 1 to Length(Value) do\n  begin\n    if not CharInSet(Value[I], ['A'..'Z','a'..'z','0'..'9','_']) then\n    begin\n      Result := True;\n      Break;\n    end;\n  end;\nend;\n\n{**\n  Checks is the string case sensitive.\n  @return <code>True</code> if the string case sensitive.\n}\nfunction TZDefaultIdentifierConvertor.IsCaseSensitive(const Value: string): Boolean;\nconst\n  AnsiSQLKeywords = 'insert,update,delete,select,drop,create,from,set,values,'\n    + 'where,order,group,by,having,into,as,table,index,primary,key,on,is,null,'\n    + 'char,varchar,integer,number,alter,column,value,'\n    + 'current,top,login,status,version';\nvar\n  Keywords: string;\nbegin\n  if Value = '' then\n    Result := False\n  else if IsSpecialCase(Value) then\n    Result := True\n  else if IsLowerCase(Value) then\n    Result := Metadata.GetDatabaseInfo.StoresUpperCaseIdentifiers\n  else if IsUpperCase(Value) then\n    Result := Metadata.GetDatabaseInfo.StoresLowerCaseIdentifiers\n  else\n    Result := not Metadata.GetDatabaseInfo.StoresMixedCaseIdentifiers;\n\n  { Checks for reserved keywords. }\n  if not Result then\n  begin\n    Keywords := ',' + AnsiSQLKeywords + ','\n      + LowerCase(Metadata.GetDatabaseInfo.GetSQLKeywords) + ',';\n    Result := Pos(',' + LowerCase(Value) + ',', Keywords) > 0;\n  end;\nend;\n\n{**\n  Checks is the string quoted.\n  @return <code>True</code> is the string quoted.\n}\nfunction TZDefaultIdentifierConvertor.IsQuoted(const Value: string): Boolean;\nvar\n  QuoteDelim: string;\nbegin\n  QuoteDelim := Metadata.GetDatabaseInfo.GetIdentifierQuoteString;\n  Result := (QuoteDelim <> '') and (Value <> '') and (QuoteDelim[1] = Value[1]);\nend;\n\n{**\n  Extracts the quote from the idenfitier string.\n  @param an identifier string.\n  @return a extracted and processed string.\n}\nfunction TZDefaultIdentifierConvertor.ExtractQuote(const Value: string): string;\nbegin\n  if IsQuoted(Value) then\n  begin\n    Result := Copy(Value, 2, Length(Value) - 2);\n    if not Metadata.GetDatabaseInfo.StoresMixedCaseQuotedIdentifiers then\n    begin\n      if Metadata.GetDatabaseInfo.StoresLowerCaseQuotedIdentifiers then\n        Result := LowerCase(Result)\n      else if Metadata.GetDatabaseInfo.StoresUpperCaseQuotedIdentifiers then\n        Result := UpperCase(Result);\n    end;\n  end\n  else\n  begin\n    Result := Value;\n    if not Metadata.GetDatabaseInfo.StoresMixedCaseIdentifiers then\n    begin\n      if Metadata.GetDatabaseInfo.StoresLowerCaseIdentifiers then\n        Result := LowerCase(Result)\n      else if Metadata.GetDatabaseInfo.StoresUpperCaseIdentifiers then\n        Result := UpperCase(Result);\n    end;\n  end;\nend;\n\n{**\n  Quotes the identifier string.\n  @param an identifier string.\n  @return a quoted string.\n}\nfunction TZDefaultIdentifierConvertor.Quote(const Value: string): string;\nvar\n  QuoteDelim: string;\nbegin\n  Result := Value;\n  if IsCaseSensitive(Value) then\n  begin\n    QuoteDelim := Metadata.GetDatabaseInfo.GetIdentifierQuoteString;\n    if Length(QuoteDelim) > 1 then\n      Result := QuoteDelim[1] + Result + QuoteDelim[2]\n    else if Length(QuoteDelim) = 1 then\n      Result := QuoteDelim[1] + Result + QuoteDelim[1];\n  end;\nend;\n\n{**\n  rerurns cache key for get tables metadata entry\n  @param Catalog catalog name\n  @param SchemaPattern schema pattern\n  @param TableNamePattern table name pattern\n  @param Types table types\n  @return the cache key string\n  @deprecated use TZAbstractDatabaseMetadata.GetTablesCacheKey instead\n}\nfunction GetTablesMetaDataCacheKey(Const Catalog:String;\n      Const SchemaPattern:String;\tConst TableNamePattern:String;const Types: TStringDynArray):String;\nVar I : Integer;\n    Key :  String;\nbegin\n  Key := '';\n  for I := Low(Types) to High(Types) do\n    Key := Key + ':' + Types[I];\n\n  Result:= Format('get-tables:%s:%s:%s:%s',\n    [Catalog, SchemaPattern, TableNamePattern, Key]);\nend;\n\n\nconst\n  CharacterSetsColumnsCount = 2;\n  CharacterSetsColumns: array[1..CharacterSetsColumnsCount]\n    of TZMetadataColumnDef =(\n    (Name: 'CHARACTER_SET_NAME'; SQLType: stString; Length: 35),\n    (Name: 'CHARACTER_SET_ID'; SQLType: stShort; Length: 0)\n  );\n\n  CollationCharSetColumnsCount = 8; //EgonHugeist\n  CollationCharSetColumns: array[1..CollationCharSetColumnsCount]\n    of TZMetadataColumnDef =(\n    (Name: 'COLLATION_CATALOG'; SQLType: stString; Length: 35),\n    (Name: 'COLLATION_SCHEMA'; SQLType: stString; Length: 35),\n    (Name: 'COLLATION_TABLE'; SQLType: stString; Length: 35),\n    (Name: 'COLLATION_COLUMN'; SQLType: stString; Length: 35),\n    (Name: 'COLLATION_NAME'; SQLType: stString; Length: 35),\n    (Name: 'CHARACTER_SET_NAME'; SQLType: stString; Length: 35),\n    (Name: 'CHARACTER_SET_ID'; SQLType: stShort; Length: 0),\n    (Name: 'CHARACTER_SET_SIZE'; SQLType: stShort; Length: 0)\n  );\n\n  TriggersColumnCount = 8;  //EgonHugeist\n  TriggersColumns: array[1..TriggersColumnCount]\n    of TZMetadataColumnDef =(\n    (Name: 'TRIGGER_CAT'; SQLType: stString; Length: 255),\n    (Name: 'TRIGGER_SCHEM'; SQLType: stString; Length: 255),\n    (Name: 'TRIGGER_NAME'; SQLType: stString; Length: 255), //RDB$TRIGGER_NAME\n    (Name: 'TRIGGER_RELATION'; SQLType: stString; Length: 255), //RDB$RELATION_NAME\n    (Name: 'TRIGGER_TYPE'; SQLType: stShort; Length: 0),     //RDB$TRIGGER_TYPE\n    (Name: 'TRIGGER_INACTIVE'; SQLType: stShort; Length: 0),     //RDB$TRIGGER_INACTIVE\n    (Name: 'TRIGGER_SOURCE'; SQLType: stString; Length: 3000),     //RDB$TRIGGER_SOURCE\n    (Name: 'TRIGGER_DESCRIPTION'; SQLType: stString; Length: 255)     //RDB$DESCRIPTION\n  );\n\n  ProceduresColumnCount = 8;\n  ProceduresColumns: array[1..ProceduresColumnCount]\n    of TZMetadataColumnDef =(\n    (Name: 'PROCEDURE_CAT'; SQLType: stString; Length: 255),\n    (Name: 'PROCEDURE_SCHEM'; SQLType: stString; Length: 255),\n    (Name: 'PROCEDURE_NAME'; SQLType: stString; Length: 255),\n    (Name: 'PROCEDURE_OVERLOAD'; SQLType: stString; Length: 255),\n    (Name: 'RESERVED1'; SQLType: stString; Length: 255),\n    (Name: 'RESERVED2'; SQLType: stString; Length: 255),\n    (Name: 'REMARKS'; SQLType: stString; Length: 255),\n    (Name: 'PROCEDURE_TYPE'; SQLType: stShort; Length: 0)\n  );\n\n  ProceduresColColumnCount = 13;\n  ProceduresColColumns: array[1..ProceduresColColumnCount]\n    of TZMetadataColumnDef =(\n    (Name: 'PROCEDURE_CAT'; SQLType: stString; Length: 255),\n    (Name: 'PROCEDURE_SCHEM'; SQLType: stString; Length: 255),\n    (Name: 'PROCEDURE_NAME'; SQLType: stString; Length: 255),\n    (Name: 'COLUMN_NAME'; SQLType: stString; Length: 255),\n    (Name: 'COLUMN_TYPE'; SQLType: stShort; Length: 0),\n    (Name: 'DATA_TYPE'; SQLType: stShort; Length: 0),\n    (Name: 'TYPE_NAME'; SQLType: stString; Length: 255),\n    (Name: 'PRECISION'; SQLType: stInteger; Length: 0),\n    (Name: 'LENGTH'; SQLType: stInteger; Length: 0),\n    (Name: 'SCALE'; SQLType: stShort; Length: 0),\n    (Name: 'RADIX'; SQLType: stShort; Length: 0),\n    (Name: 'NULLABLE'; SQLType: stShort; Length: 0),\n    (Name: 'REMARKS'; SQLType: stString; Length: 255)\n  );\n\n  TableColumnCount = 5;\n  TableColumns: array[1..TableColumnCount]\n    of TZMetadataColumnDef =(\n    (Name: 'TABLE_CAT'; SQLType: stString; Length: 255),\n    (Name: 'TABLE_SCHEM'; SQLType: stString; Length: 255),\n    (Name: 'TABLE_NAME'; SQLType: stString; Length: 255),\n    (Name: 'TABLE_TYPE'; SQLType: stString; Length: 255),\n    (Name: 'REMARKS'; SQLType: stString; Length: 255)\n  );\n\n  SchemaColumnCount = 1;\n  SchemaColumns: array[1..SchemaColumnCount]\n    of TZMetadataColumnDef =(\n    (Name: 'TABLE_SCHEM'; SQLType: stString; Length: 255)\n  );\n\n  CatalogColumnCount = 1;\n  CatalogColumns: array[1..CatalogColumnCount]\n    of TZMetadataColumnDef =(\n    (Name: 'TABLE_CAT'; SQLType: stString; Length: 255)\n  );\n\n  TableTypeColumnCount = 1;\n  TableTypeColumns: array[1..TableTypeColumnCount]\n    of TZMetadataColumnDef =(\n    (Name: 'TABLE_TYPE'; SQLType: stString; Length: 255)\n  );\n\n  TableColColumnCount = 24;\n  TableColColumns: array[1..TableColColumnCount]\n    of TZMetadataColumnDef =(\n    (Name: 'TABLE_CAT'; SQLType: stString; Length: 255),\n    (Name: 'TABLE_SCHEM'; SQLType: stString; Length: 255),\n    (Name: 'TABLE_NAME'; SQLType: stString; Length: 255),\n    (Name: 'COLUMN_NAME'; SQLType: stString; Length: 255),\n    (Name: 'DATA_TYPE'; SQLType: stShort; Length: 0),\n    (Name: 'TYPE_NAME'; SQLType: stString; Length: 255),\n    (Name: 'COLUMN_SIZE'; SQLType: stInteger; Length: 0),\n    (Name: 'BUFFER_LENGTH'; SQLType: stInteger; Length: 0),\n    (Name: 'DECIMAL_DIGITS'; SQLType: stInteger; Length: 0),\n    (Name: 'NUM_PREC_RADIX'; SQLType: stInteger; Length: 0),\n    (Name: 'NULLABLE'; SQLType: stInteger; Length: 0),\n    (Name: 'REMARKS'; SQLType: stString; Length: 255),\n    (Name: 'COLUMN_DEF'; SQLType: stString; Length: 255),\n    (Name: 'SQL_DATA_TYPE'; SQLType: stInteger; Length: 0),\n    (Name: 'SQL_DATETIME_SUB'; SQLType: stInteger; Length: 0),\n    (Name: 'CHAR_OCTET_LENGTH'; SQLType: stInteger; Length: 0),\n    (Name: 'ORDINAL_POSITION'; SQLType: stInteger; Length: 0),\n    (Name: 'IS_NULLABLE'; SQLType: stString; Length: 255),\n    (Name: 'AUTO_INCREMENT'; SQLType: stBoolean; Length: 0),\n    (Name: 'CASE_SENSITIVE'; SQLType: stBoolean; Length: 0),\n    (Name: 'SEARCHABLE'; SQLType: stBoolean; Length: 0),\n    (Name: 'WRITABLE'; SQLType: stBoolean; Length: 0),\n    (Name: 'DEFINITELYWRITABLE'; SQLType: stBoolean; Length: 0),\n    (Name: 'READONLY'; SQLType: stBoolean; Length: 0)\n  );\n\n  TableColPrivColumnCount = 8;\n  TableColPrivColumns: array[1..TableColPrivColumnCount]\n    of TZMetadataColumnDef =(\n    (Name: 'TABLE_CAT'; SQLType: stString; Length: 255),\n    (Name: 'TABLE_SCHEM'; SQLType: stString; Length: 255),\n    (Name: 'TABLE_NAME'; SQLType: stString; Length: 255),\n    (Name: 'COLUMN_NAME'; SQLType: stString; Length: 255),\n    (Name: 'GRANTOR'; SQLType: stString; Length: 255),\n    (Name: 'GRANTEE'; SQLType: stString; Length: 255),\n    (Name: 'PRIVILEGE'; SQLType: stString; Length: 255),\n    (Name: 'IS_GRANTABLE'; SQLType: stString; Length: 255)\n  );\n\n  TablePrivColumnCount = 7;\n  TablePrivColumns: array[1..TablePrivColumnCount]\n    of TZMetadataColumnDef =(\n    (Name: 'TABLE_CAT'; SQLType: stString; Length: 255),\n    (Name: 'TABLE_SCHEM'; SQLType: stString; Length: 255),\n    (Name: 'TABLE_NAME'; SQLType: stString; Length: 255),\n    (Name: 'GRANTOR'; SQLType: stString; Length: 255),\n    (Name: 'GRANTEE'; SQLType: stString; Length: 255),\n    (Name: 'PRIVILEGE'; SQLType: stString; Length: 255),\n    (Name: 'IS_GRANTABLE'; SQLType: stString; Length: 255)\n  );\n\n  BestRowIdentColumnCount = 8;\n  BestRowIdentColumns: array[1..BestRowIdentColumnCount]\n    of TZMetadataColumnDef =(\n    (Name: 'SCOPE'; SQLType: stShort; Length: 0),\n    (Name: 'COLUMN_NAME'; SQLType: stString; Length: 255),\n    (Name: 'DATA_TYPE'; SQLType: stShort; Length: 0),\n    (Name: 'TYPE_NAME'; SQLType: stString; Length: 255),\n    (Name: 'COLUMN_SIZE'; SQLType: stInteger; Length: 0),\n    (Name: 'BUFFER_LENGTH'; SQLType: stInteger; Length: 0),\n    (Name: 'DECIMAL_DIGITS'; SQLType: stShort; Length: 0),\n    (Name: 'PSEUDO_COLUMN'; SQLType: stShort; Length: 0)\n  );\n\n  TableColVerColumnCount = 8;\n  TableColVerColumns: array[1..TableColVerColumnCount]\n    of TZMetadataColumnDef =(\n    (Name: 'SCOPE'; SQLType: stShort; Length: 0),\n    (Name: 'COLUMN_NAME'; SQLType: stString; Length: 255),\n    (Name: 'DATA_TYPE'; SQLType: stShort; Length: 0),\n    (Name: 'TYPE_NAME'; SQLType: stString; Length: 255),\n    (Name: 'COLUMN_SIZE'; SQLType: stInteger; Length: 0),\n    (Name: 'BUFFER_LENGTH'; SQLType: stInteger; Length: 0),\n    (Name: 'DECIMAL_DIGITS'; SQLType: stShort; Length: 0),\n    (Name: 'PSEUDO_COLUMN'; SQLType: stShort; Length: 0)\n  );\n\n  PrimaryKeyColumnCount = 6;\n  PrimaryKeyColumns: array[1..PrimaryKeyColumnCount]\n    of TZMetadataColumnDef =(\n    (Name: 'TABLE_CAT'; SQLType: stString; Length: 255),\n    (Name: 'TABLE_SCHEM'; SQLType: stString; Length: 255),\n    (Name: 'TABLE_NAME'; SQLType: stString; Length: 255),\n    (Name: 'COLUMN_NAME'; SQLType: stString; Length: 255),\n    (Name: 'KEY_SEQ'; SQLType: stShort; Length: 0),\n    (Name: 'PK_NAME'; SQLType: stString; Length: 255)\n  );\n\n  ImportedKeyColumnCount = 14;\n  ImportedKeyColumns: array[1..ImportedKeyColumnCount]\n    of TZMetadataColumnDef =(\n    (Name: 'PKTABLE_CAT'; SQLType: stString; Length: 255),\n    (Name: 'PKTABLE_SCHEM'; SQLType: stString; Length: 255),\n    (Name: 'PKTABLE_NAME'; SQLType: stString; Length: 255),\n    (Name: 'PKCOLUMN_NAME'; SQLType: stString; Length: 255),\n    (Name: 'FKTABLE_CAT'; SQLType: stString; Length: 255),\n    (Name: 'FKTABLE_SCHEM'; SQLType: stString; Length: 255),\n    (Name: 'FKTABLE_NAME'; SQLType: stString; Length: 255),\n    (Name: 'FKCOLUMN_NAME'; SQLType: stString; Length: 255),\n    (Name: 'KEY_SEQ'; SQLType: stShort; Length: 0),\n    (Name: 'UPDATE_RULE'; SQLType: stShort; Length: 0),\n    (Name: 'DELETE_RULE'; SQLType: stShort; Length: 0),\n    (Name: 'FK_NAME'; SQLType: stString; Length: 255),\n    (Name: 'PK_NAME'; SQLType: stString; Length: 255),\n    (Name: 'DEFERRABILITY'; SQLType: stShort; Length: 0)\n  );\n\n  ExportedKeyColumnCount = 14;\n  ExportedKeyColumns: array[1..ExportedKeyColumnCount]\n    of TZMetadataColumnDef =(\n    (Name: 'PKTABLE_CAT'; SQLType: stString; Length: 255),\n    (Name: 'PKTABLE_SCHEM'; SQLType: stString; Length: 255),\n    (Name: 'PKTABLE_NAME'; SQLType: stString; Length: 255),\n    (Name: 'PKCOLUMN_NAME'; SQLType: stString; Length: 255),\n    (Name: 'FKTABLE_CAT'; SQLType: stString; Length: 255),\n    (Name: 'FKTABLE_SCHEM'; SQLType: stString; Length: 255),\n    (Name: 'FKTABLE_NAME'; SQLType: stString; Length: 255),\n    (Name: 'FKCOLUMN_NAME'; SQLType: stString; Length: 255),\n    (Name: 'KEY_SEQ'; SQLType: stShort; Length: 0),\n    (Name: 'UPDATE_RULE'; SQLType: stShort; Length: 0),\n    (Name: 'DELETE_RULE'; SQLType: stShort; Length: 0),\n    (Name: 'FK_NAME'; SQLType: stString; Length: 255),\n    (Name: 'PK_NAME'; SQLType: stString; Length: 255),\n    (Name: 'DEFERRABILITY'; SQLType: stShort; Length: 0)\n  );\n\n  CrossRefColumnCount = 14;\n  CrossRefColumns: array[1..CrossRefColumnCount]\n    of TZMetadataColumnDef =(\n    (Name: 'PKTABLE_CAT'; SQLType: stString; Length: 255),\n    (Name: 'PKTABLE_SCHEM'; SQLType: stString; Length: 255),\n    (Name: 'PKTABLE_NAME'; SQLType: stString; Length: 255),\n    (Name: 'PKCOLUMN_NAME'; SQLType: stString; Length: 255),\n    (Name: 'FKTABLE_CAT'; SQLType: stString; Length: 255),\n    (Name: 'FKTABLE_SCHEM'; SQLType: stString; Length: 255),\n    (Name: 'FKTABLE_NAME'; SQLType: stString; Length: 255),\n    (Name: 'FKCOLUMN_NAME'; SQLType: stString; Length: 255),\n    (Name: 'KEY_SEQ'; SQLType: stShort; Length: 0),\n    (Name: 'UPDATE_RULE'; SQLType: stShort; Length: 0),\n    (Name: 'DELETE_RULE'; SQLType: stShort; Length: 0),\n    (Name: 'FK_NAME'; SQLType: stString; Length: 255),\n    (Name: 'PK_NAME'; SQLType: stString; Length: 255),\n    (Name: 'DEFERRABILITY'; SQLType: stShort; Length: 0)\n  );\n\n  TypeInfoColumnCount = 18;\n  TypeInfoColumns: array[1..TypeInfoColumnCount]\n    of TZMetadataColumnDef =(\n    (Name: 'TYPE_NAME'; SQLType: stString; Length: 255),\n    (Name: 'DATA_TYPE'; SQLType: stShort; Length: 0),\n    (Name: 'PRECISION'; SQLType: stInteger; Length: 0),\n    (Name: 'LITERAL_PREFIX'; SQLType: stString; Length: 255),\n    (Name: 'LITERAL_SUFFIX'; SQLType: stString; Length: 255),\n    (Name: 'CREATE_PARAMS'; SQLType: stString; Length: 255),\n    (Name: 'NULLABLE'; SQLType: stShort; Length: 0),\n    (Name: 'CASE_SENSITIVE'; SQLType: stBoolean; Length: 0),\n    (Name: 'SEARCHABLE'; SQLType: stShort; Length: 0),\n    (Name: 'UNSIGNED_ATTRIBUTE'; SQLType: stBoolean; Length: 0),\n    (Name: 'FIXED_PREC_SCALE'; SQLType: stBoolean; Length: 0),\n    (Name: 'AUTO_INCREMENT'; SQLType: stBoolean; Length: 0),\n    (Name: 'LOCAL_TYPE_NAME'; SQLType: stString; Length: 255),\n    (Name: 'MINIMUM_SCALE'; SQLType: stShort; Length: 0),\n    (Name: 'MAXIMUM_SCALE'; SQLType: stShort; Length: 0),\n    (Name: 'SQL_DATA_TYPE'; SQLType: stInteger; Length: 0),\n    (Name: 'SQL_DATETIME_SUB'; SQLType: stInteger; Length: 0),\n    (Name: 'NUM_PREC_RADIX'; SQLType: stInteger; Length: 0)\n  );\n\n  IndexInfoColumnCount = 13;\n  IndexInfoColumns: array[1..IndexInfoColumnCount]\n    of TZMetadataColumnDef =(\n    (Name: 'TABLE_CAT'; SQLType: stString; Length: 255),\n    (Name: 'TABLE_SCHEM'; SQLType: stString; Length: 255),\n    (Name: 'TABLE_NAME'; SQLType: stString; Length: 255),\n    (Name: 'NON_UNIQUE'; SQLType: stBoolean; Length: 0),\n    (Name: 'INDEX_QUALIFIER'; SQLType: stString; Length: 255),\n    (Name: 'INDEX_NAME'; SQLType: stString; Length: 255),\n    (Name: 'TYPE'; SQLType: stShort; Length: 0),\n    (Name: 'ORDINAL_POSITION'; SQLType: stShort; Length: 0),\n    (Name: 'COLUMN_NAME'; SQLType: stString; Length: 255),\n    (Name: 'ASC_OR_DESC'; SQLType: stString; Length: 255),\n    (Name: 'CARDINALITY'; SQLType: stInteger; Length: 0),\n    (Name: 'PAGES'; SQLType: stInteger; Length: 0),\n    (Name: 'FILTER_CONDITION'; SQLType: stString; Length: 255)\n  );\n\n  SequenceColumnCount = 3;\n  SequenceColumns: array[1..SequenceColumnCount]\n    of TZMetadataColumnDef = (\n    (Name: 'SEQUENCE_CAT'; SQLType: stString; Length: 255),\n    (Name: 'SEQUENCE_SCHEM'; SQLType: stString; Length: 255),\n    (Name: 'SEQUENCE_NAME'; SQLType: stString; Length: 255)\n  );\n\n  UDTColumnCount = 6;\n  UDTColumns: array[1..UDTColumnCount]\n    of TZMetadataColumnDef =(\n    (Name: 'TYPE_CAT'; SQLType: stString; Length: 255),\n    (Name: 'TYPE_SCHEM'; SQLType: stString; Length: 255),\n    (Name: 'TYPE_NAME'; SQLType: stString; Length: 255),\n    (Name: 'CLASS_NAME'; SQLType: stString; Length: 255),\n    (Name: 'DATA_TYPE'; SQLType: stShort; Length: 0),\n    (Name: 'REMARKS'; SQLType: stString; Length: 255)\n  );\n\nvar\n  I: Integer;\n\ninitialization\n  SetLength(CharacterSetsColumnsDynArray, CharacterSetsColumnsCount);\n  for I := 1 to CharacterSetsColumnsCount do\n    CharacterSetsColumnsDynArray[I - 1] := CharacterSetsColumns[I];\n\n  SetLength(CollationCharSetColumnsDynArray, CollationCharSetColumnsCount);\n  for I := 1 to CollationCharSetColumnsCount do\n    CollationCharSetColumnsDynArray[I - 1] := CollationCharSetColumns[I];\n\n  SetLength(TriggersColumnsDynArray, TriggersColumnCount);\n  for I := 1 to TriggersColumnCount do\n    TriggersColumnsDynArray[I - 1] := TriggersColumns[I];\n\n  SetLength(ProceduresColumnsDynArray, ProceduresColumnCount);\n  for I := 1 to ProceduresColumnCount do\n    ProceduresColumnsDynArray[I - 1] := ProceduresColumns[I];\n\n  SetLength(ProceduresColColumnsDynArray, ProceduresColColumnCount);\n  for I := 1 to ProceduresColColumnCount do\n    ProceduresColColumnsDynArray[I - 1] := ProceduresColColumns[I];\n\n  SetLength(TableColumnsDynArray, TableColumnCount);\n  for I := 1 to TableColumnCount do\n    TableColumnsDynArray[I - 1] := TableColumns[I];\n\n  SetLength(SchemaColumnsDynArray, SchemaColumnCount);\n  for I := 1 to SchemaColumnCount do\n    SchemaColumnsDynArray[I - 1] := SchemaColumns[I];\n\n  SetLength(CatalogColumnsDynArray, CatalogColumnCount);\n  for I := 1 to CatalogColumnCount do\n    CatalogColumnsDynArray[I - 1] := CatalogColumns[I];\n\n  SetLength(TableTypeColumnsDynArray, TableTypeColumnCount);\n  for I := 1 to TableTypeColumnCount do\n    TableTypeColumnsDynArray[I - 1] := TableTypeColumns[I];\n\n  SetLength(TableColColumnsDynArray, TableColColumnCount);\n  for I := 1 to TableColColumnCount do\n    TableColColumnsDynArray[I - 1] := TableColColumns[I];\n\n  SetLength(TableColPrivColumnsDynArray, TableColPrivColumnCount);\n  for I := 1 to TableColPrivColumnCount do\n    TableColPrivColumnsDynArray[I - 1] := TableColPrivColumns[I];\n\n  SetLength(TablePrivColumnsDynArray, TablePrivColumnCount);\n  for I := 1 to TablePrivColumnCount do\n    TablePrivColumnsDynArray[I - 1] := TablePrivColumns[I];\n\n  SetLength(BestRowIdentColumnsDynArray, BestRowIdentColumnCount);\n  for I := 1 to BestRowIdentColumnCount do\n    BestRowIdentColumnsDynArray[I - 1] := BestRowIdentColumns[I];\n\n  SetLength(TableColVerColumnsDynArray, TableColVerColumnCount);\n  for I := 1 to TableColVerColumnCount do\n    TableColVerColumnsDynArray[I - 1] := TableColVerColumns[I];\n\n  SetLength(PrimaryKeyColumnsDynArray, PrimaryKeyColumnCount);\n  for I := 1 to PrimaryKeyColumnCount do\n    PrimaryKeyColumnsDynArray[I - 1] := PrimaryKeyColumns[I];\n\n  SetLength(ImportedKeyColumnsDynArray, ImportedKeyColumnCount);\n  for I := 1 to ImportedKeyColumnCount do\n    ImportedKeyColumnsDynArray[I - 1] := ImportedKeyColumns[I];\n\n  SetLength(ExportedKeyColumnsDynArray, ExportedKeyColumnCount);\n  for I := 1 to ExportedKeyColumnCount do\n    ExportedKeyColumnsDynArray[I - 1] := ExportedKeyColumns[I];\n\n  SetLength(CrossRefColumnsDynArray, CrossRefColumnCount);\n  for I := 1 to CrossRefColumnCount do\n    CrossRefColumnsDynArray[I - 1] := CrossRefColumns[I];\n\n  SetLength(TypeInfoColumnsDynArray, TypeInfoColumnCount);\n  for I := 1 to TypeInfoColumnCount do\n    TypeInfoColumnsDynArray[I - 1] := TypeInfoColumns[I];\n\n  SetLength(IndexInfoColumnsDynArray, IndexInfoColumnCount);\n  for I := 1 to IndexInfoColumnCount do\n    IndexInfoColumnsDynArray[I - 1] := IndexInfoColumns[I];\n\n  SetLength(SequenceColumnsDynArray, SequenceColumnCount);\n  for I := 1 to SequenceColumnCount do\n    SequenceColumnsDynArray[I - 1] := SequenceColumns[I];\n\n  SetLength(UDTColumnsDynArray, UDTColumnCount);\n  for I := 1 to UDTColumnCount do\n    UDTColumnsDynArray[I - 1] := UDTColumns[I];\nend.\n"
  },
  {
    "path": "lib/zeosdbo/src/dbc/ZDbcMySql.pas",
    "content": "{*********************************************************}\n{                                                         }\n{                 Zeos Database Objects                   }\n{           MySQL Database Connectivity Classes           }\n{                                                         }\n{        Originally written by Sergey Seroukhov           }\n{                                                         }\n{*********************************************************}\n\n{@********************************************************}\n{    Copyright (c) 1999-2012 Zeos Development Group       }\n{                                                         }\n{ License Agreement:                                      }\n{                                                         }\n{ This library is distributed in the hope that it will be }\n{ useful, but WITHOUT ANY WARRANTY; without even the      }\n{ implied warranty of MERCHANTABILITY or FITNESS FOR      }\n{ A PARTICULAR PURPOSE.  See the GNU Lesser General       }\n{ Public License for more details.                        }\n{                                                         }\n{ The source code of the ZEOS Libraries and packages are  }\n{ distributed under the Library GNU General Public        }\n{ License (see the file COPYING / COPYING.ZEOS)           }\n{ with the following  modification:                       }\n{ As a special exception, the copyright holders of this   }\n{ library give you permission to link this library with   }\n{ independent modules to produce an executable,           }\n{ regardless of the license terms of these independent    }\n{ modules, and to copy and distribute the resulting       }\n{ executable under terms of your choice, provided that    }\n{ you also meet, for each linked independent module,      }\n{ the terms and conditions of the license of that module. }\n{ An independent module is a module which is not derived  }\n{ from or based on this library. If you modify this       }\n{ library, you may extend this exception to your version  }\n{ of the library, but you are not obligated to do so.     }\n{ If you do not wish to do so, delete this exception      }\n{ statement from your version.                            }\n{                                                         }\n{                                                         }\n{ The project web site is located on:                     }\n{   http://zeos.firmos.at  (FORUM)                        }\n{   http://sourceforge.net/p/zeoslib/tickets/ (BUGTRACKER)}\n{   svn://svn.code.sf.net/p/zeoslib/code-0/trunk (SVN)    }\n{                                                         }\n{   http://www.sourceforge.net/projects/zeoslib.          }\n{                                                         }\n{                                                         }\n{                                 Zeos Development Group. }\n{********************************************************@}\n\nunit ZDbcMySql;\n\ninterface\n\n{$I ZDbc.inc}\n\nuses\n  Types, Classes, {$IFDEF MSEgui}mclasses,{$ENDIF} SysUtils,\n  ZCompatibility, ZDbcIntfs, ZDbcConnection, ZPlainMySqlDriver, ZPlainDriver,\n  ZURL, ZDbcLogging, ZTokenizer, ZGenericSqlAnalyser, ZPlainMySqlConstants;\n\ntype\n\n  {** Implements MySQL Database Driver. }\n\n  { TZMySQLDriver }\n  {$WARNINGS OFF}\n  TZMySQLDriver = class(TZAbstractDriver)\n  protected\n    function GetPlainDriver(const Url: TZURL; const InitDriver: Boolean = True): IZPlainDriver; override;\n  public\n    constructor Create; override;\n    function Connect(const Url: TZURL): IZConnection; override;\n    function GetMajorVersion: Integer; override;\n    function GetMinorVersion: Integer; override;\n\n    function GetTokenizer: IZTokenizer; override;\n    function GetStatementAnalyser: IZStatementAnalyser; override;\n    function GetClientVersion(const Url: string): Integer; override;\n  end;\n  {$WARNINGS ON}\n\n  {** Represents a MYSQL specific connection interface. }\n  IZMySQLConnection = interface (IZConnection)\n    ['{68E33DD3-4CDC-4BFC-8A28-E9F2EE94E457}']\n\n    function GetPlainDriver: IZMySQLPlainDriver;\n    function GetConnectionHandle: PZMySQLConnect;\n  end;\n\n  {** Implements MySQL Database Connection. }\n  TZMySQLConnection = class(TZAbstractConnection, IZMySQLConnection)\n  private\n    FCatalog: string;\n    FHandle: PZMySQLConnect;\n  protected\n    procedure InternalCreate; override;\n  public\n    destructor Destroy; override;\n\n    function CreateRegularStatement(Info: TStrings): IZStatement; override;\n    function CreatePreparedStatement(const SQL: string; Info: TStrings):\n      IZPreparedStatement; override;\n    function CreateCallableStatement(const SQL: string; Info: TStrings):\n      IZCallableStatement; override;\n\n    procedure Commit; override;\n    procedure Rollback; override;\n\n    function PingServer: Integer; override;\n    function EscapeString(Value: RawByteString): RawByteString; override;\n\n    procedure Open; override;\n    procedure Close; override;\n\n    procedure SetCatalog(const Catalog: string); override;\n    function GetCatalog: string; override;\n\n    procedure SetTransactionIsolation(Level: TZTransactIsolationLevel); override;\n    procedure SetAutoCommit(AutoCommit: Boolean); override;\n    {ADDED by fduenas 15-06-2006}\n    function GetClientVersion: Integer; override;\n    function GetHostVersion: Integer; override;\n    {END ADDED by fduenas 15-06-2006}\n    function GetPlainDriver: IZMySQLPlainDriver;\n    function GetConnectionHandle: PZMySQLConnect;\n    function GetEscapeString(const Value: ZWideString): ZWideString; override;\n    function GetEscapeString(const Value: RawByteString): RawByteString; override;\n  end;\n\n\nvar\n  {** The common driver manager object. }\n  MySQLDriver: IZDriver;\n\nimplementation\n\nuses\n  ZMessages, ZSysUtils, ZDbcUtils, ZDbcMySqlStatement, ZMySqlToken,\n  ZDbcMySqlUtils, ZDbcMySqlMetadata, ZMySqlAnalyser, TypInfo, Math,\n  ZEncoding;\n\n{ TZMySQLDriver }\n\n{**\n  Constructs this object with default properties.\n}\nconstructor TZMySQLDriver.Create;\nbegin\n  inherited Create;\n  AddSupportedProtocol(AddPlainDriverToCache(TZMySQL5PlainDriver.Create(GetTokenizer), 'mysql'));\n  AddSupportedProtocol(AddPlainDriverToCache(TZMySQL41PlainDriver.Create(GetTokenizer)));\n  AddSupportedProtocol(AddPlainDriverToCache(TZMySQL5PlainDriver.Create(GetTokenizer)));\n  AddSupportedProtocol(AddPlainDriverToCache(TZMySQLD41PlainDriver.Create(GetTokenizer)));\n  AddSupportedProtocol(AddPlainDriverToCache(TZMySQLD5PlainDriver.Create(GetTokenizer)));\n  AddSupportedProtocol(AddPlainDriverToCache(TZMariaDB5PlainDriver.Create(GetTokenizer)));\nend;\n\n{**\n  Attempts to make a database connection to the given URL.\n  The driver should return \"null\" if it realizes it is the wrong kind\n  of driver to connect to the given URL.  This will be common, as when\n  the JDBC driver manager is asked to connect to a given URL it passes\n  the URL to each loaded driver in turn.\n\n  <P>The driver should raise a SQLException if it is the right\n  driver to connect to the given URL, but has trouble connecting to\n  the database.\n\n  <P>The java.util.Properties argument can be used to passed arbitrary\n  string tag/value pairs as connection arguments.\n  Normally at least \"user\" and \"password\" properties should be\n  included in the Properties.\n\n  @param url the URL of the database to which to connect\n  @param info a list of arbitrary string tag/value pairs as\n    connection arguments. Normally at least a \"user\" and\n    \"password\" property should be included.\n  @return a <code>Connection</code> object that represents a\n    connection to the URL\n}\n{$WARNINGS OFF}\nfunction TZMySQLDriver.Connect(const Url: TZURL): IZConnection;\nbegin\n  Result := TZMySQLConnection.Create(Url);\nend;\n{$WARNINGS ON}\n\n{**\n  Gets the driver's major version number. Initially this should be 1.\n  @return this driver's major version number\n}\nfunction TZMySQLDriver.GetMajorVersion: Integer;\nbegin\n  Result := 1;\nend;\n\n{**\n  Gets the driver's minor version number. Initially this should be 0.\n  @return this driver's minor version number\n}\nfunction TZMySQLDriver.GetMinorVersion: Integer;\nbegin\n  Result := 1;\nend;\n\n{**\n  Gets a SQL syntax tokenizer.\n  @returns a SQL syntax tokenizer object.\n}\nfunction TZMySQLDriver.GetTokenizer: IZTokenizer;\nbegin\n  if Tokenizer = nil then\n    Tokenizer := TZMySQLTokenizer.Create;\n  Result := Tokenizer;\nend;\n\n{**\n  Creates a statement analyser object.\n  @returns a statement analyser object.\n}\nfunction TZMySQLDriver.GetStatementAnalyser: IZStatementAnalyser;\nbegin\n  if Analyser = nil then\n    Analyser := TZMySQLStatementAnalyser.Create;\n  Result := Analyser;\nend;\n\n{**\n  Gets plain driver for selected protocol.\n  @param Url a database connection URL.\n  @return a selected plaindriver.\n}\nfunction TZMySQLDriver.GetPlainDriver(const Url: TZURL;\n  const InitDriver: Boolean = True): IZPlainDriver;\nbegin\n  // added by tohenk, 2009-10-11\n  // before PlainDriver is initialized, we can perform pre-library loading\n  // requirement check here, e.g. Embedded server argument params\n  Result := inherited GetPlainDriver(URL, False);\n  if Assigned(Result) then\n  begin\n    if Url.Properties.Count >0  then\n      (Result as IZMySQLPlainDriver).SetDriverOptions(Url.Properties);\n    // end added by tohenk, 2009-10-11\n    if InitDriver then Result.Initialize(Url.LibLocation);\n  end\n  else\n    raise Exception.Create('Can''t receive Plaindriver!');\nend;\n\n{**\n  Returns the version of the plain driver library that will be used to open a connection\n  to the given URL.\n  @param url the URL of the database\n  @return the version number of the plain driver library for the give URL\n}\nfunction TZMySQLDriver.GetClientVersion(const Url: string): Integer;\nvar\n  TempURL: TZURL;\nbegin\n  TempURL := TZURL.Create(Url);\n  Result := ConvertMySQLVersionToSQLVersion((GetPlainDriver(TempUrl) as IZMySQLPlainDriver).GetClientVersion);\n  TempUrl.Free\nend;\n\n{ TZMySQLConnection }\n\n{**\n  Constructs this object and assignes the main properties.\n}\nprocedure TZMySQLConnection.InternalCreate;\nbegin\n  FMetaData := TZMySQLDatabaseMetadata.Create(Self, Url);\n  if Self.Port = 0 then\n     Self.Port := MYSQL_PORT;\n  AutoCommit := True;\n  TransactIsolationLevel := tiNone;\n  FHandle := nil;\n\n  { Processes connection properties. }\n  Open;\nend;\n\n{**\n  Destroys this object and cleanups the memory.\n}\ndestructor TZMySQLConnection.Destroy;\nbegin\n  inherited Destroy;\nend;\n\n{**\n  Opens a connection to database server with specified parameters.\n}\nprocedure TZMySQLConnection.Open;\nvar\n  LogMessage: string;\n  OldLevel: TZTransactIsolationLevel;\n  OldAutoCommit: Boolean;\n  UIntOpt: UInt;\n  MyBoolOpt: Byte;\n  ClientFlag : Cardinal;\n  SslCa, SslCaPath, SslKey, SslCert, SslCypher: PAnsiChar;\n  myopt: TMySQLOption;\n  sMyOpt: string;\n  my_client_Opt:TMYSQL_CLIENT_OPTIONS;\n  sMy_client_Opt, sMy_client_Char_Set:String;\n  ClientVersion: Integer;\n  SQL: PAnsiChar;\nlabel setuint;\nbegin\n   if not Closed then\n      Exit;\n\n  LogMessage := Format('CONNECT TO \"%s\" AS USER \"%s\"', [Database, User]);\n  FHandle := GetPlainDriver.Init(FHandle);\n  {EgonHugeist: Arrange Client-CodePage/CharacterSet first\n    Now we know if UTFEncoding is neccessary or not}\n  sMy_client_Char_Set := String(GetPlainDriver.GetConnectionCharacterSet(FHandle));\n  ConSettings^.ClientCodePage := GetPlainDriver.ValidateCharEncoding(sMy_client_Char_Set);\n  ZEncoding.SetConvertFunctions(ConSettings);\n  {EgonHugeist:\n    Now we know in which kind of CharacterSet we have to send the next Connection-Properties\n    before we can change to the CharacterSet we want to have here..\n    This sets also all environment-variables to the Codepaged Object.\n    Now the compatibility-functions ZString/ZPlainString working like\n    Database-expected Data has to be!!. }\n\n  try\n    { Sets a default port number. }\n    if Port = 0 then\n       Port := MYSQL_PORT;\n\n    { Turn on compression protocol. }\n    if StrToBoolEx(Info.Values['compress']) and\n      (Info.Values['MYSQL_OPT_COMPRESS'] = '') and\n       (Info.IndexOf('MYSQL_OPT_COMPRESS') = -1) then\n      Info.Values['MYSQL_OPT_COMPRESS'] := Info.Values['compress']; //check if user allready did set the value!\n    { Sets connection timeout. }\n    if (StrToIntDef(Info.Values['timeout'], 0) >= 0) and\n       (Info.Values['MYSQL_OPT_CONNECT_TIMEOUT'] = '') then //check if user allready did set the value!\n      Info.Values['MYSQL_OPT_CONNECT_TIMEOUT'] := Info.Values['timeout'];\n\n   (*Added lines to handle option parameters 21 november 2007 marco cotroneo*)\n    ClientVersion := GetPlainDriver.GetClientVersion;\n    for myopt := low(TMySQLOption) to high(TMySQLOption) do\n    begin\n      sMyOpt:= GetEnumName(typeInfo(TMySQLOption), integer(myOpt));\n      if ClientVersion >= TMySqlOptionMinimumVersion[myopt] then //version checked (:\n        case myopt of\n          {unsigned int options ...}\n          MYSQL_OPT_CONNECT_TIMEOUT,\n          MYSQL_OPT_PROTOCOL,\n          MYSQL_OPT_READ_TIMEOUT,\n          MYSQL_OPT_WRITE_TIMEOUT:\n      if Info.Values[sMyOpt] <> '' then\n            begin\nsetuint:      UIntOpt := StrToIntDef(Info.Values[sMyOpt], 0);\n              GetPlainDriver.SetOptions(FHandle, myopt, @UIntOpt);\n    end;\n          MYSQL_OPT_LOCAL_INFILE: {optional empty or unsigned int}\n            if Info.Values[sMyOpt] <> '' then\n              goto setuint\n            else\n              if Info.IndexOf(sMyOpt) > -1 then\n                GetPlainDriver.SetOptions(FHandle, myopt, nil);\n          { no value options }\n          MYSQL_OPT_COMPRESS,\n          MYSQL_OPT_GUESS_CONNECTION,\n          MYSQL_OPT_NAMED_PIPE,\n          MYSQL_OPT_USE_REMOTE_CONNECTION,\n          MYSQL_OPT_USE_EMBEDDED_CONNECTION,\n          MYSQL_OPT_USE_RESULT,\n          MYSQL_OPT_CONNECT_ATTR_RESET:\n            if (Info.Values[sMyOpt] <> '') or (Info.IndexOf(sMyOpt) > -1) then\n              GetPlainDriver.SetOptions(FHandle, myopt, nil);\n          { my_bool * options}\n          MYSQL_REPORT_DATA_TRUNCATION,\n          MYSQL_SECURE_AUTH,\n          MYSQL_OPT_RECONNECT,\n          MYSQL_OPT_SSL_VERIFY_SERVER_CERT,\n          MYSQL_ENABLE_CLEARTEXT_PLUGIN,\n          MYSQL_OPT_CAN_HANDLE_EXPIRED_PASSWORDS,\n          MYSQL_OPT_SSL_ENFORCE:\n            if Info.Values[sMyOpt] <> '' then\n            begin\n              MyBoolOpt := Ord(StrToBoolEx(Info.Values[sMyOpt]));\n              GetPlainDriver.SetOptions(FHandle, myopt, @MyBoolOpt);\n            end;\n          { unsigned char * options }\n          MYSQL_OPT_SSL_KEY, MYSQL_OPT_SSL_CERT,\n          MYSQL_OPT_SSL_CA, MYSQL_OPT_SSL_CAPATH, MYSQL_OPT_SSL_CIPHER: ;//skip, processed down below\n          else\n            if Info.Values[sMyOpt] <> '' then\n              GetPlainDriver.SetOptions(FHandle, myopt, PAnsiChar(\n                ConSettings^.ConvFuncs.ZStringToRaw(Info.Values[sMyOpt],\n                  ConSettings^.CTRL_CP, ConSettings^.ClientCodePage^.CP)));\n        end;\n    end;\n\n    { Set ClientFlag }\n    ClientFlag := 0;\n    if Not StrToBoolEx(Info.Values['dbless'])\n       then ClientFlag := trunc(power(2, GetEnumValue(   TypeInfo(TMYSQL_CLIENT_OPTIONS),'_CLIENT_CONNECT_WITH_DB')));\n\n    for my_client_Opt := low(TMYSQL_CLIENT_OPTIONS) to high(TMYSQL_CLIENT_OPTIONS) do\n    begin\n      sMy_client_Opt:= GetEnumName(typeInfo(TMYSQL_CLIENT_OPTIONS), integer(my_client_Opt));\n      if StrToBoolEx(Info.Values[sMy_client_Opt]) then\n          ClientFlag:= ClientFlag or trunc(power(2, GetEnumValue(TypeInfo(TMYSQL_CLIENT_OPTIONS),sMy_client_Opt)));\n    end;\n\n  { Set SSL properties before connect}\n  SslKey := nil; SslCert := nil; SslCa := nil; SslCaPath := nil; SslCypher := nil;\n  {EgonHugeist: If these Paramters MUST BE UTF8 then leave Param ceUTF8 in the\n    ZPlainString-function like else remove it and it adapts to default codepage}\n  if StrToBoolEx(Info.Values['MYSQL_SSL']) then\n    begin\n       if Info.Values['MYSQL_SSL_KEY'] <> '' then\n          SslKey := PAnsiChar(ZPlainString(Info.Values['MYSQL_SSL_KEY'], ceUTF8));\n       if Info.Values['MYSQL_SSL_CERT'] <> '' then\n          SslCert := PAnsiChar(ZPlainString(Info.Values['MYSQL_SSL_CERT'], ceUTF8));\n       if Info.Values['MYSQL_SSL_CA'] <> '' then\n          SslCa := PAnsiChar(ZPlainString(Info.Values['MYSQL_SSL_CA'], ceUTF8));\n       if Info.Values['MYSQL_SSL_CAPATH'] <> '' then\n          SslCaPath := PAnsiChar(ZPlainString(Info.Values['MYSQL_SSL_CAPATH'], ceUTF8));\n       if Info.Values['MYSQL_SSL_CYPHER'] <> '' then\n          SslCypher := PAnsiChar(ZPlainString(Info.Values['MYSQL_SSL_CYPHER'], ceUTF8));\n       GetPlainDriver.SslSet(FHandle, SslKey, SslCert, SslCa, SslCaPath,\n          SslCypher);\n       DriverManager.LogMessage(lcConnect, PlainDriver.GetProtocol,\n          'SSL options set');\n    end;\n\n    { Connect to MySQL database. }\n    if GetPlainDriver.RealConnect(FHandle, PAnsiChar(ZPlainString(HostName)),\n                              PAnsiChar(ZPlainString(User)), PAnsiChar(ZPlainString(Password)),\n                              PAnsiChar(ZPlainString(Database)), Port, nil,\n                              ClientFlag) = nil then\n\n    begin\n      CheckMySQLError(GetPlainDriver, FHandle, lcConnect, LogMessage);\n      DriverManager.LogError(lcConnect, PlainDriver.GetProtocol, LogMessage,\n        0, SUnknownError);\n      raise EZSQLException.Create(SCanNotConnectToServer);\n    end;\n    DriverManager.LogMessage(lcConnect, PlainDriver.GetProtocol, LogMessage);\n\n    { Fix Bugs in certain Versions where real_conncet resets the Reconnect flag }\n    if (Info.Values['MYSQL_OPT_RECONNECT'] <> '') and\n      ((ClientVersion>=50013) and (ClientVersion<50019)) or\n      ((ClientVersion>=50100) and (ClientVersion<50106)) then\n    begin\n      MyBoolOpt := Ord(StrToBoolEx(Info.Values['MYSQL_OPT_RECONNECT']));\n      GetPlainDriver.SetOptions(FHandle, MYSQL_OPT_RECONNECT, @MyBoolOpt);\n    end;\n    if (FClientCodePage = '') and (sMy_client_Char_Set <> '') then\n      FClientCodePage := sMy_client_Char_Set;\n\n    if (FClientCodePage <> sMy_client_Char_Set) then\n    begin\n      SQL := PAnsiChar(ZPlainString(Format('SET NAMES %s', [FClientCodePage])));\n      GetPlainDriver.ExecQuery(FHandle, SQL);\n      CheckMySQLError(GetPlainDriver, FHandle, lcExecute, String(SQL));\n      DriverManager.LogMessage(lcExecute, PlainDriver.GetProtocol, String(SQL));\n    end;\n    Self.CheckCharEncoding(FClientCodePage);\n\n    { Sets transaction isolation level. }\n    OldLevel := TransactIsolationLevel;\n    TransactIsolationLevel := tiNone;\n    SetTransactionIsolation(OldLevel);\n\n    { Sets an auto commit mode. }\n    OldAutoCommit := AutoCommit;\n    AutoCommit := True;\n    SetAutoCommit(OldAutoCommit);\n  except\n    GetPlainDriver.Close(FHandle);\n    GetPlainDriver.Despose(FHandle);\n    FHandle := nil;\n    raise;\n  end;\n\n  inherited Open;\n\n  if FClientCodePage = '' then //workaround for MySQL 4 down\n  begin\n    with CreateStatement.ExecuteQuery('show variables like \"character_set_database\"') do\n    begin\n      if Next then\n        FClientCodePage := GetString(2);\n      Close;\n    end;\n    ConSettings^.ClientCodePage := GetPlainDriver.ValidateCharEncoding(FClientCodePage);\n    ZEncoding.SetConvertFunctions(ConSettings);\n  end\nend;\n\n{**\n  Ping Current Connection's server, if client was disconnected,\n  the connection is resumed.\n  @return 0 if succesfull or error code if any error occurs\n}\nfunction TZMySQLConnection.PingServer: Integer;\nconst\n   PING_ERROR_ZEOSCONNCLOSED = -1;\nvar\n   Closing: boolean;\nbegin\n   Closing := FHandle = nil;\n   if Closed or Closing then\n      Result := PING_ERROR_ZEOSCONNCLOSED\n   else\n      Result := GetPlainDriver.Ping(FHandle);\nend;\n\n{**\n  Escape a string so it's acceptable for the Connection's server.\n  @param value string that should be escaped\n  @return Escaped string\n}\nfunction TZMySQLConnection.EscapeString(Value: RawByteString): RawByteString;\nbegin\n  Result := PlainDriver.EscapeString(Self.FHandle,  Value, ConSettings);\nend;\n\n{**\n  Creates a <code>Statement</code> object for sending\n  SQL statements to the database.\n  SQL statements without parameters are normally\n  executed using Statement objects. If the same SQL statement\n  is executed many times, it is more efficient to use a\n  <code>PreparedStatement</code> object.\n  <P>\n  Result sets created using the returned <code>Statement</code>\n  object will by default have forward-only type and read-only concurrency.\n\n  @param Info a statement parameters.\n  @return a new Statement object\n}\nfunction TZMySQLConnection.CreateRegularStatement(Info: TStrings):\n  IZStatement;\nbegin\n  if IsClosed then\n     Open;\n  Result := TZMySQLStatement.Create(GetPlainDriver, Self, Info, FHandle);\nend;\n\n{**\n  Creates a <code>PreparedStatement</code> object for sending\n  parameterized SQL statements to the database.\n\n  A SQL statement with or without IN parameters can be\n  pre-compiled and stored in a PreparedStatement object. This\n  object can then be used to efficiently execute this statement\n  multiple times.\n\n  <P><B>Note:</B> This method is optimized for handling\n  parametric SQL statements that benefit from precompilation. If\n  the driver supports precompilation,\n  the method <code>prepareStatement</code> will send\n  the statement to the database for precompilation. Some drivers\n  may not support precompilation. In this case, the statement may\n  not be sent to the database until the <code>PreparedStatement</code> is\n  executed.  This has no direct effect on users; however, it does\n  affect which method throws certain SQLExceptions.\n\n  Result sets created using the returned PreparedStatement will have\n  forward-only type and read-only concurrency, by default.\n\n  @param sql a SQL statement that may contain one or more '?' IN\n    parameter placeholders\n  @param Info a statement parameters.\n  @return a new PreparedStatement object containing the\n    pre-compiled statement\n}\nfunction TZMySQLConnection.CreatePreparedStatement(const SQL: string;\n  Info: TStrings): IZPreparedStatement;\nbegin\n  if IsClosed then\n     Open;\n  if Assigned(Info) then\n    if StrToBoolEx(Info.Values['preferprepared']) then\n      Result := TZMySQLPreparedStatement.Create(GetPlainDriver, Self, SQL, Info)\n    else\n      Result := TZMySQLEmulatedPreparedStatement.Create(GetPlainDriver, Self, SQL, Info, FHandle)\n  else\n    Result := TZMySQLEmulatedPreparedStatement.Create(GetPlainDriver, Self, SQL, Info, FHandle);\nend;\n\n{**\n  Creates a <code>CallableStatement</code> object for calling\n  database stored procedures.\n  The <code>CallableStatement</code> object provides\n  methods for setting up its IN and OUT parameters, and\n  methods for executing the call to a stored procedure.\n\n  <P><B>Note:</B> This method is optimized for handling stored\n  procedure call statements. Some drivers may send the call\n  statement to the database when the method <code>prepareCall</code>\n  is done; others\n  may wait until the <code>CallableStatement</code> object\n  is executed. This has no\n  direct effect on users; however, it does affect which method\n  throws certain SQLExceptions.\n\n  Result sets created using the returned CallableStatement will have\n  forward-only type and read-only concurrency, by default.\n\n  @param sql a SQL statement that may contain one or more '?'\n    parameter placeholders. Typically this  statement is a JDBC\n    function call escape string.\n  @param Info a statement parameters.\n  @return a new CallableStatement object containing the\n    pre-compiled SQL statement\n}\nfunction TZMySQLConnection.CreateCallableStatement(const SQL: string; Info: TStrings):\n  IZCallableStatement;\nbegin\n  Result := TZMySQLCallableStatement.Create(GetPlainDriver, Self, SQL, Info, FHandle);\nend;\n\n{**\n  Makes all changes made since the previous\n  commit/rollback permanent and releases any database locks\n  currently held by the Connection. This method should be\n  used only when auto-commit mode has been disabled.\n  @see #setAutoCommit\n}\nprocedure TZMySQLConnection.Commit;\nbegin\n  if (TransactIsolationLevel <> tiNone) and (AutoCommit <> True)\n    and not Closed then\n  begin\n    If not GEtPlaindriver.Commit(FHandle) then\n      CheckMySQLError(GetPlainDriver, FHandle, lcExecute, 'Native Commit call');\n    DriverManager.LogMessage(lcExecute, PlainDriver.GetProtocol, 'Native Commit call');\n  end;\nend;\n\n{**\n  Drops all changes made since the previous\n  commit/rollback and releases any database locks currently held\n  by this Connection. This method should be used only when auto-\n  commit has been disabled.\n  @see #setAutoCommit\n}\nprocedure TZMySQLConnection.Rollback;\nbegin\n  if (TransactIsolationLevel <> tiNone) and (AutoCommit <> True)\n    and not Closed then\n  begin\n    If not GetPlaindriver.Rollback(FHandle) then\n      CheckMySQLError(GetPlainDriver, FHandle, lcExecute, 'Native Rollback call');\n    DriverManager.LogMessage(lcExecute, PlainDriver.GetProtocol, 'Native Rollback call');\n  end;\nend;\n\n{**\n  Releases a Connection's database and JDBC resources\n  immediately instead of waiting for\n  them to be automatically released.\n\n  <P><B>Note:</B> A Connection is automatically closed when it is\n  garbage collected. Certain fatal errors also result in a closed\n  Connection.\n}\nprocedure TZMySQLConnection.Close;\nvar\n  LogMessage: string;\nbegin\n  if ( Closed ) or (not Assigned(PlainDriver)) then\n    Exit;\n\n  GetPlainDriver.Close(FHandle);\n  GetPlainDriver.Despose(FHandle);\n  FHandle := nil;\n  LogMessage := Format('DISCONNECT FROM \"%s\"', [Database]);\n  DriverManager.LogMessage(lcDisconnect, GetPlainDriver.GetProtocol, LogMessage);\n  inherited Close;\nend;\n\n{**\n  Gets a selected catalog name.\n  @return a selected catalog name.\n}\nfunction TZMySQLConnection.GetCatalog: string;\nbegin\n  Result := FCatalog;\nend;\n\n{**\n  Sets a new selected catalog name.\n  @param Catalog a selected catalog name.\n}\nprocedure TZMySQLConnection.SetCatalog(const Catalog: string);\nbegin\n  FCatalog := Catalog;\nend;\n\n{**\n  Sets a new transact isolation level.\n  @param Level a new transact isolation level.\n}\nprocedure TZMySQLConnection.SetTransactionIsolation(\n  Level: TZTransactIsolationLevel);\nvar\n  SQL: PAnsiChar;\n  testResult: Integer;\nbegin\n  if TransactIsolationLevel <> Level then\n  begin\n    inherited SetTransactionIsolation(Level);\n    testResult := 1;\n    if not Closed then\n    begin\n      case TransactIsolationLevel of\n        tiNone, tiReadUncommitted:\n          begin\n            SQL := 'SET SESSION TRANSACTION ISOLATION LEVEL READ UNCOMMITTED';\n            testResult := GetPlainDriver.ExecQuery(FHandle, SQL);\n          end;\n        tiReadCommitted:\n          begin\n            SQL := 'SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED';\n            testResult := GetPlainDriver.ExecQuery(FHandle, SQL);\n          end;\n        tiRepeatableRead:\n          begin\n            SQL := 'SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ';\n            testResult := GetPlainDriver.ExecQuery(FHandle, SQL);\n          end;\n        tiSerializable:\n          begin\n            SQL := 'SET SESSION TRANSACTION ISOLATION LEVEL SERIALIZABLE';\n            testResult := GetPlainDriver.ExecQuery(FHandle, SQL);\n          end;\n        else\n          SQL := '';\n      end;\n      if (testResult <> 0) then\n          CheckMySQLError(GetPlainDriver, FHandle, lcExecute, String(SQL));\n      if SQL <> '' then\n        DriverManager.LogMessage(lcExecute, PlainDriver.GetProtocol, String(SQL));\n    end;\n  end;\nend;\n\n{**\n  Sets this connection's auto-commit mode.\n  If a connection is in auto-commit mode, then all its SQL\n  statements will be executed and committed as individual\n  transactions.  Otherwise, its SQL statements are grouped into\n  transactions that are terminated by a call to either\n  the method <code>commit</code> or the method <code>rollback</code>.\n  By default, new connections are in auto-commit mode.\n\n  The commit occurs when the statement completes or the next\n  execute occurs, whichever comes first. In the case of\n  statements returning a ResultSet, the statement completes when\n  the last row of the ResultSet has been retrieved or the\n  ResultSet has been closed. In advanced cases, a single\n  statement may return multiple results as well as output\n  parameter values. In these cases the commit occurs when all results and\n  output parameter values have been retrieved.\n\n  @param autoCommit true enables auto-commit; false disables auto-commit.\n}\nprocedure TZMySQLConnection.SetAutoCommit(AutoCommit: Boolean);\nbegin\n  if AutoCommit <> Self.AutoCommit then\n  begin\n    inherited SetAutoCommit(AutoCommit);\n\n    if not Closed then\n    begin\n      if not GetPlaindriver.SetAutocommit(FHandle, AutoCommit) then\n        CheckMySQLError(GetPlainDriver, FHandle, lcExecute, 'Native SetAutoCommit '+BoolToStrEx(AutoCommit)+'call');\n      DriverManager.LogMessage(lcExecute, PlainDriver.GetProtocol, 'Native SetAutoCommit '+BoolToStrEx(AutoCommit)+'call');\n    end;\n  end;\nend;\n\n{**\n  Gets client's full version number.\n  The format of the version returned must be XYYYZZZ where\n   X   = Major version\n   YYY = Minor version\n   ZZZ = Sub version\n  @return this clients's full version number\n}\nfunction TZMySQLConnection.GetClientVersion: Integer;\nbegin\n Result := ConvertMySQLVersionToSQLVersion( GetPlainDriver.GetClientVersion );\nend;\n\n{**\n  Gets server's full version number.\n  The format of the returned version must be XYYYZZZ where\n   X   = Major version\n   YYY = Minor version\n   ZZZ = Sub version\n  @return this clients's full version number\n}\nfunction TZMySQLConnection.GetHostVersion: Integer;\nbegin\n Result := ConvertMySQLVersionToSQLVersion( GetPlainDriver.GetServerVersion(FHandle) );\n CheckMySQLError(GetPlainDriver, FHandle, lcExecute, 'mysql_get_server_version()');\nend;\n\n{**\n  Gets a reference to MySQL connection handle.\n  @return a reference to MySQL connection handle.\n}\nfunction TZMySQLConnection.GetConnectionHandle: PZMySQLConnect;\nbegin\n  Result := FHandle;\nend;\n\n{**\n  Gets a MySQL plain driver interface.\n  @return a MySQL plain driver interface.\n}\nfunction TZMySQLConnection.GetPlainDriver: IZMySQLPlainDriver;\nbegin\n  Result := Self.PlainDriver as IZMySQLPlainDriver;\nend;\n\n{**\n  EgonHugeist:\n  Returns the BinaryString in a Tokenizer-detectable kind\n  If the Tokenizer don't need to predetect it Result := BinaryString\n  @param Value represents the Binary-String\n  @param EscapeMarkSequence represents a Tokenizer detectable EscapeSequence (Len >= 3)\n  @result the detectable Binary String\n}\nfunction TZMySQLConnection.GetEscapeString(const Value: ZWideString): ZWideString;\nbegin\n  Result := inherited GetEscapeString(GetPlainDriver.EscapeString(FHandle, Value, ConSettings));\nend;\n\nfunction TZMySQLConnection.GetEscapeString(const Value: RawByteString): RawByteString;\nbegin\n  Result := inherited GetEscapeString(GetPlainDriver.EscapeString(FHandle, Value, ConSettings));\nend;\n\ninitialization\n  MySQLDriver := TZMySQLDriver.Create;\n  DriverManager.RegisterDriver(MySQLDriver);\nfinalization\n  if DriverManager <> nil then\n    DriverManager.DeregisterDriver(MySQLDriver);\n  MySQLDriver := nil;\nend.\n\n"
  },
  {
    "path": "lib/zeosdbo/src/dbc/ZDbcMySqlMetadata.pas",
    "content": "{*********************************************************}\n{                                                         }\n{                 Zeos Database Objects                   }\n{           MySQL Database Connectivity Classes           }\n{                                                         }\n{         Originally written by Sergey Seroukhov          }\n{                           and Sergey Merkuriev          }\n{                                                         }\n{*********************************************************}\n\n{@********************************************************}\n{    Copyright (c) 1999-2012 Zeos Development Group       }\n{                                                         }\n{ License Agreement:                                      }\n{                                                         }\n{ This library is distributed in the hope that it will be }\n{ useful, but WITHOUT ANY WARRANTY; without even the      }\n{ implied warranty of MERCHANTABILITY or FITNESS FOR      }\n{ A PARTICULAR PURPOSE.  See the GNU Lesser General       }\n{ Public License for more details.                        }\n{                                                         }\n{ The source code of the ZEOS Libraries and packages are  }\n{ distributed under the Library GNU General Public        }\n{ License (see the file COPYING / COPYING.ZEOS)           }\n{ with the following  modification:                       }\n{ As a special exception, the copyright holders of this   }\n{ library give you permission to link this library with   }\n{ independent modules to produce an executable,           }\n{ regardless of the license terms of these independent    }\n{ modules, and to copy and distribute the resulting       }\n{ executable under terms of your choice, provided that    }\n{ you also meet, for each linked independent module,      }\n{ the terms and conditions of the license of that module. }\n{ An independent module is a module which is not derived  }\n{ from or based on this library. If you modify this       }\n{ library, you may extend this exception to your version  }\n{ of the library, but you are not obligated to do so.     }\n{ If you do not wish to do so, delete this exception      }\n{ statement from your version.                            }\n{                                                         }\n{                                                         }\n{ The project web site is located on:                     }\n{   http://zeos.firmos.at  (FORUM)                        }\n{   http://sourceforge.net/p/zeoslib/tickets/ (BUGTRACKER)}\n{   svn://svn.code.sf.net/p/zeoslib/code-0/trunk (SVN)    }\n{                                                         }\n{   http://www.sourceforge.net/projects/zeoslib.          }\n{                                                         }\n{                                                         }\n{                                 Zeos Development Group. }\n{********************************************************@}\n\nunit ZDbcMySqlMetadata;\n\ninterface\n\n{$I ZDbc.inc}\n\nuses\n  Types, Classes, {$IFDEF MSEgui}mclasses,{$ENDIF} SysUtils,\n  ZClasses, ZSysUtils, ZDbcIntfs, ZDbcMetadata, ZDbcResultSet, ZDbcConnection,\n  ZDbcCachedResultSet, ZDbcResultSetMetadata, ZURL, ZCompatibility;\n\ntype\n\n  // technobot 2008-06-26 - methods moved as is from TZMySQLDatabaseMetadata:\n  {** Implements MySQL Database Information. }\n  TZMySQLDatabaseInfo = class(TZAbstractDatabaseInfo)\n  protected\n    procedure GetVersion(var MajorVersion, MinorVersion: integer);\n  public\n    constructor Create(const Metadata: TZAbstractDatabaseMetadata);\n\n    // database/driver/server info:\n    function GetDatabaseProductName: string; override;\n    function GetDatabaseProductVersion: string; override;\n    function GetDriverName: string; override;\n//    function GetDriverVersion: string; override; -> Same as parent\n    function GetDriverMajorVersion: Integer; override;\n    function GetDriverMinorVersion: Integer; override;\n//    function GetServerVersion: string; -> Not implemented\n\n    // capabilities (what it can/cannot do):\n//    function AllProceduresAreCallable: Boolean; override; -> Not implemented\n//    function AllTablesAreSelectable: Boolean; override; -> Not implemented\n//    function SupportsMixedCaseIdentifiers: Boolean; override; -> Not implemented\n//    function SupportsMixedCaseQuotedIdentifiers: Boolean; override; -> Not implemented\n//    function SupportsAlterTableWithAddColumn: Boolean; override; -> Not implemented\n//    function SupportsAlterTableWithDropColumn: Boolean; override; -> Not implemented\n//    function SupportsColumnAliasing: Boolean; override; -> Not implemented\n//    function SupportsConvert: Boolean; override; -> Not implemented\n//    function SupportsConvertForTypes(FromType: TZSQLType; ToType: TZSQLType):\n//      Boolean; override; -> Not implemented\n//    function SupportsTableCorrelationNames: Boolean; override; -> Not implemented\n//    function SupportsDifferentTableCorrelationNames: Boolean; override; -> Not implemented\n//    function SupportsExpressionsInOrderBy: Boolean; override; -> Not implemented\n    function SupportsOrderByUnrelated: Boolean; override;\n//    function SupportsGroupBy: Boolean; override; -> Not implemented\n    function SupportsGroupByUnrelated: Boolean; override;\n    function SupportsGroupByBeyondSelect: Boolean; override;\n//    function SupportsLikeEscapeClause: Boolean; override; -> Not implemented\n//    function SupportsMultipleResultSets: Boolean; override; -> Not implemented\n//    function SupportsMultipleTransactions: Boolean; override; -> Not implemented\n//    function SupportsNonNullableColumns: Boolean; override; -> Not implemented\n//    function SupportsMinimumSQLGrammar: Boolean; override; -> Not implemented\n//    function SupportsCoreSQLGrammar: Boolean; override; -> Not implemented\n//    function SupportsExtendedSQLGrammar: Boolean; override; -> Not implemented\n//    function SupportsANSI92EntryLevelSQL: Boolean; override; -> Not implemented\n//    function SupportsANSI92IntermediateSQL: Boolean; override; -> Not implemented\n//    function SupportsANSI92FullSQL: Boolean; override; -> Not implemented\n    function SupportsIntegrityEnhancementFacility: Boolean; override;\n//    function SupportsOuterJoins: Boolean; override; -> Not implemented\n//    function SupportsFullOuterJoins: Boolean; override; -> Not implemented\n//    function SupportsLimitedOuterJoins: Boolean; override; -> Not implemented\n//    function SupportsSchemasInDataManipulation: Boolean; override; -> Not implemented\n//    function SupportsSchemasInProcedureCalls: Boolean; override; -> Not implemented\n//    function SupportsSchemasInTableDefinitions: Boolean; override; -> Not implemented\n//    function SupportsSchemasInIndexDefinitions: Boolean; override; -> Not implemented\n//    function SupportsSchemasInPrivilegeDefinitions: Boolean; override; -> Not implemented\n    function SupportsCatalogsInDataManipulation: Boolean; override;\n//    function SupportsCatalogsInProcedureCalls: Boolean; override; -> Not implemented\n    function SupportsCatalogsInTableDefinitions: Boolean; override;\n//    function SupportsCatalogsInIndexDefinitions: Boolean; override; -> Not implemented\n//    function SupportsCatalogsInPrivilegeDefinitions: Boolean; override; -> Not implemented\n//    function SupportsPositionedDelete: Boolean; override; -> Not implemented\n//    function SupportsPositionedUpdate: Boolean; override; -> Not implemented\n//    function SupportsSelectForUpdate: Boolean; override; -> Not implemented\n//    function SupportsStoredProcedures: Boolean; override; -> Not implemented\n    function SupportsSubqueriesInComparisons: Boolean; override;\n//    function SupportsSubqueriesInExists: Boolean; override; -> Not implemented\n//    function SupportsSubqueriesInIns: Boolean; override; -> Not implemented\n//    function SupportsSubqueriesInQuantifieds: Boolean; override; -> Not implemented\n//    function SupportsCorrelatedSubqueries: Boolean; override; -> Not implemented\n//    function SupportsUnion: Boolean; override; -> Not implemented\n    function SupportsUnionAll: Boolean; override;\n//    function SupportsOpenCursorsAcrossCommit: Boolean; override; -> Not implemented\n//    function SupportsOpenCursorsAcrossRollback: Boolean; override; -> Not implemented\n    function SupportsOpenStatementsAcrossCommit: Boolean; override;\n    function SupportsOpenStatementsAcrossRollback: Boolean; override;\n//    function SupportsTransactions: Boolean; override; -> Not implemented\n//    function SupportsTransactionIsolationLevel(Level: TZTransactIsolationLevel):\n//      Boolean; override; -> Not implemented\n    function SupportsDataDefinitionAndDataManipulationTransactions: Boolean; override;\n    function SupportsDataManipulationTransactionsOnly: Boolean; override;\n//    function SupportsResultSetType(_Type: TZResultSetType): Boolean; override; -> Not implemented\n//    function SupportsResultSetConcurrency(_Type: TZResultSetType;\n//      Concurrency: TZResultSetConcurrency): Boolean; override; -> Not implemented\n//    function SupportsBatchUpdates: Boolean; override; -> Not implemented\n\n    // maxima:\n    function GetMaxBinaryLiteralLength: Integer; override;\n    function GetMaxCharLiteralLength: Integer; override;\n    function GetMaxColumnNameLength: Integer; override;\n    function GetMaxColumnsInGroupBy: Integer; override;\n    function GetMaxColumnsInIndex: Integer; override;\n    function GetMaxColumnsInOrderBy: Integer; override;\n    function GetMaxColumnsInSelect: Integer; override;\n    function GetMaxColumnsInTable: Integer; override;\n    function GetMaxConnections: Integer; override;\n    function GetMaxCursorNameLength: Integer; override;\n    function GetMaxIndexLength: Integer; override;\n//    function GetMaxSchemaNameLength: Integer; override; -> Not implemented\n//    function GetMaxProcedureNameLength: Integer; override; -> Not implemented\n    function GetMaxCatalogNameLength: Integer; override;\n    function GetMaxRowSize: Integer; override;\n    function GetMaxStatementLength: Integer; override;\n    function GetMaxStatements: Integer; override;\n    function GetMaxTableNameLength: Integer; override;\n    function GetMaxTablesInSelect: Integer; override;\n    function GetMaxUserNameLength: Integer; override;\n\n    // policies (how are various data and operations handled):\n//    function IsReadOnly: Boolean; override; -> Not implemented\n//    function IsCatalogAtStart: Boolean; override; -> Not implemented\n    function DoesMaxRowSizeIncludeBlobs: Boolean; override;\n//    function NullsAreSortedHigh: Boolean; override; -> Not implemented\n//    function NullsAreSortedLow: Boolean; override; -> Not implemented\n//    function NullsAreSortedAtStart: Boolean; override; -> Not implemented\n//    function NullsAreSortedAtEnd: Boolean; override; -> Not implemented\n//    function NullPlusNonNullIsNull: Boolean; override; -> Not implemented\n//    function UsesLocalFiles: Boolean; override; -> Not implemented\n    function UsesLocalFilePerTable: Boolean; override;\n//    function StoresUpperCaseIdentifiers: Boolean; override; -> Not implemented\n//    function StoresLowerCaseIdentifiers: Boolean; override; -> Not implemented\n    function StoresMixedCaseIdentifiers: Boolean; override;\n//    function StoresUpperCaseQuotedIdentifiers: Boolean; override; -> Not implemented\n//    function StoresLowerCaseQuotedIdentifiers: Boolean; override; -> Not implemented\n//    function StoresMixedCaseQuotedIdentifiers: Boolean; override; -> Not implemented\n    function GetDefaultTransactionIsolation: TZTransactIsolationLevel; override;\n//    function DataDefinitionCausesTransactionCommit: Boolean; override; -> Not implemented\n//    function DataDefinitionIgnoredInTransactions: Boolean; override; -> Not implemented\n\n    // interface details (terms, keywords, etc):\n    function GetSchemaTerm: string; override;\n    function GetProcedureTerm: string; override;\n    function GetCatalogTerm: string; override;\n//    function GetCatalogSeparator: string; override; -> Not implemented\n    function GetSQLKeywords: string; override;\n    function GetNumericFunctions: string; override;\n    function GetStringFunctions: string; override;\n    function GetSystemFunctions: string; override;\n    function GetTimeDateFunctions: string; override;\n    function GetSearchStringEscape: string; override;\n    function GetExtraNameCharacters: string; override;\n  end;\n\n  {** Implements MySQL Database Metadata. }\n  TZMySQLDatabaseMetadata = class(TZAbstractDatabaseMetadata)\n  protected\n    function CreateDatabaseInfo: IZDatabaseInfo; override; // technobot 2008-06-26\n\n    procedure GetCatalogAndNamePattern(const Catalog, SchemaPattern,\n      NamePattern: string; out OutCatalog, OutNamePattern: string);\n    function UncachedGetTables(const Catalog: string; const SchemaPattern: string;\n      const TableNamePattern: string; const Types: TStringDynArray): IZResultSet; override;\n//    function UncachedGetSchemas: IZResultSet; override; -> Not implemented\n    function UncachedGetCatalogs: IZResultSet; override;\n    function UncachedGetTableTypes: IZResultSet; override;\n    function UncachedGetColumns(const Catalog: string; const SchemaPattern: string;\n      const TableNamePattern: string; const ColumnNamePattern: string): IZResultSet; override;\n    function UncachedGetTablePrivileges(const Catalog: string; const SchemaPattern: string;\n      const TableNamePattern: string): IZResultSet; override;\n    function UncachedGetColumnPrivileges(const Catalog: string; const Schema: string;\n      const Table: string; const ColumnNamePattern: string): IZResultSet; override;\n    function UncachedGetPrimaryKeys(const Catalog: string; const Schema: string;\n      const Table: string): IZResultSet; override;\n    function UncachedGetImportedKeys(const Catalog: string; const Schema: string;\n      const Table: string): IZResultSet; override;\n    function UncachedGetExportedKeys(const Catalog: string; const Schema: string;\n      const Table: string): IZResultSet; override;\n    function UncachedGetCrossReference(const PrimaryCatalog: string; const PrimarySchema: string;\n      const PrimaryTable: string; const ForeignCatalog: string; const ForeignSchema: string;\n      const ForeignTable: string): IZResultSet; override;\n    function UncachedGetIndexInfo(const Catalog: string; const Schema: string; const Table: string;\n      Unique: Boolean; Approximate: Boolean): IZResultSet; override;\n//     function UncachedGetSequences(const Catalog: string; const SchemaPattern: string;\n//      const SequenceNamePattern: string): IZResultSet; override; -> Not implemented\n    function UncachedGetProcedures(const Catalog: string; const SchemaPattern: string;\n      const ProcedureNamePattern: string): IZResultSet; override;\n    function UncachedGetProcedureColumns(const Catalog: string; const SchemaPattern: string;\n      const ProcedureNamePattern: string; const ColumnNamePattern: string):\n      IZResultSet; override;\n    function UncachedGetVersionColumns(const Catalog: string; const Schema: string;\n      const Table: string): IZResultSet; override;\n    function UncachedGetTypeInfo: IZResultSet; override;\n//    function UncachedGetUDTs(const Catalog: string; const SchemaPattern: string;\n//      const TypeNamePattern: string; const Types: TIntegerDynArray): IZResultSet; override;\n    function UncachedGetCollationAndCharSet(const Catalog, SchemaPattern,\n      TableNamePattern, ColumnNamePattern: string): IZResultSet; override; //EgonHugeist\n    function UncachedGetCharacterSets: IZResultSet; override; //EgonHugeist\n  public\n    destructor Destroy; override;\n  end;\n\nimplementation\n\nuses\n  Math, ZMessages, ZDbcUtils, ZCollections, ZDbcMySqlUtils;\n\n{ TZMySQLDatabaseInfo }\n\n{**\n  Constructs this object.\n  @param Metadata the interface of the correpsonding database metadata object\n}\nconstructor TZMySQLDatabaseInfo.Create(const Metadata: TZAbstractDatabaseMetadata);\nbegin\n  inherited Create(MetaData, '`');\nend;\n\n//----------------------------------------------------------------------\n// First, a variety of minor information about the target database.\n\n{**\n  What's the name of this database product?\n  @return database product name\n}\nfunction TZMySQLDatabaseInfo.GetDatabaseProductName: string;\nbegin\n  Result := 'MySQL';\nend;\n\n{**\n  What's the version of this database product?\n  @return database version\n}\nfunction TZMySQLDatabaseInfo.GetDatabaseProductVersion: string;\nbegin\n  Result := '3+';\nend;\n\n{**\n  What's the name of this JDBC driver?\n  @return JDBC driver name\n}\nfunction TZMySQLDatabaseInfo.GetDriverName: string;\nbegin\n  Result := 'Zeos Database Connectivity Driver for MySQL';\nend;\n\n{**\n  What's this JDBC driver's major version number?\n  @return JDBC driver major version\n}\nfunction TZMySQLDatabaseInfo.GetDriverMajorVersion: Integer;\nbegin\n  Result := 1;\nend;\n\n{**\n  What's this JDBC driver's minor version number?\n  @return JDBC driver minor version number\n}\nfunction TZMySQLDatabaseInfo.GetDriverMinorVersion: Integer;\nbegin\n  Result := 1;\nend;\n\n{**\n  Does the database use a file for each table?\n  @return true if the database uses a local file for each table\n}\nfunction TZMySQLDatabaseInfo.UsesLocalFilePerTable: Boolean;\nbegin\n  Result := True;\nend;\n\n{**\n  Does the database treat mixed case unquoted SQL identifiers as\n  case insensitive and store them in mixed case?\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZMySQLDatabaseInfo.StoresMixedCaseIdentifiers: Boolean;\nbegin\n  Result := True;\nend;\n\n{**\n  Gets a comma-separated list of all a database's SQL keywords\n  that are NOT also SQL92 keywords.\n  @return the list\n}\nfunction TZMySQLDatabaseInfo.GetSQLKeywords: string;\nbegin\n  Result := 'AUTO_INCREMENT,BINARY,BLOB,ENUM,INFILE,LOAD,MEDIUMINT,OPTION,'\n    + 'OUTFILE,REPLACE,SET,TEXT,UNSIGNED,ZEROFILL';\n  { mdaems : added all reserved words indicated by mysql documentation (up to mysql 5.1)}\n  Result := Result + 'ACCESSIBLE,ADD,ALL,ALTER,ANALYZE,AND,ASC,ASENSITIVE,'\n    + ' BEFORE,BETWEEN,BIGINT,BOTH,CALL,CASCADE,CASE,CHANGE,CHARACTER,CHECK,'\n    + 'COLLATE,COLUMN,CONDITION,CONSTRAINT,CONTINUE,CONVERT,CROSS,'\n    + 'CURRENT_DATE,CURRENT_TIME,CURRENT_TIMESTAMP,CURRENT_USER,CURSOR,'\n    + 'DATABASE,DATABASES,DAY_HOUR,DAY_MICROSECOND,DAY_MINUTE,DAY_SECOND,'\n    + 'DEC,DECIMAL,DECLARE,DEFAULT,DELAYED,DESC,DESCRIBE,DETERMINISTIC,'\n    + 'DISTINCT,DISTINCTROW,DIV,DOUBLE,DUAL,EACH,ELSE,ELSEIF,ENCLOSED,'\n    + 'ESCAPED,EXISTS,EXIT,EXPLAIN,FALSE,FETCH,FLOAT,FLOAT4,FLOAT8,FOR,'\n    + 'FORCE,FOREIGN,FULLTEXT,GENERAL,GRANT,HIGH_PRIORITY,HOUR_MICROSECOND,'\n    + 'HOUR_MINUTE,HOUR_SECOND,IF,IGNORE,IGNORE_SERVER_IDS,IN,INNER,INOUT,INSENSITIVE,INT,'\n    + 'INT1,INT2,INT3,INT4,INT8,INTERVAL,ITERATE,JOIN,KEYS,KILL,LEADING,'\n    + 'LEAVE,LEFT,LIKE,LIMIT,LINEAR,LINES,LOCALTIME,LOCALTIMESTAMP,LOCK,'\n    + 'LONG,LONGBLOB,LONGTEXT,LOOP,LOW_PRIORITY,MASTER_HEARTBEAT_PERIOD,MASTER_SSL_VERIFY_SERVER_CERT,'\n    + 'MATCH,MAXVALUE,MEDIUMBLOB,MEDIUMTEXT,MIDDLEINT,MINUTE_MICROSECOND,MINUTE_SECOND,'\n    + 'MOD,MODIFIES,NATURAL,NOT,NO_WRITE_TO_BINLOG,NUMERIC,OPTIMIZE,'\n    + 'OPTIONALLY,OR,OUT,OUTER,PRECISION,PROCEDURE,PURGE,RANGE,READ,READS,'\n    + 'READ_ONLY,READ_WRITE,REAL,REFERENCES,REGEXP,RELEASE,RENAME,REPEAT,'\n    + 'REQUIRE,RESIGNAL SIGNAL,RESTRICT,RETURN,REVOKE,RIGHT,RLIKE,SCHEMA,SCHEMAS,'\n    + 'SECOND_MICROSECOND,SENSITIVE,SEPARATOR,SHOW,SLOW,SMALLINT,SPATIAL,'\n    + 'SPECIFIC,SQL,SQLEXCEPTION,SQLSTATE,SQLWARNING,SQL_BIG_RESULT,'\n    + 'SQL_CALC_FOUND_ROWS,SQL_SMALL_RESULT,SSL,STARTING,STRAIGHT_JOIN,'\n    + 'TERMINATED,THEN,TINYBLOB,TINYINT,TINYTEXT,TO,TRAILING,TRIGGER,'\n    + 'TRUE,UNDO,UNION,UNIQUE,UNLOCK,USAGE,USE,USING,UTC_DATE,UTC_TIME,'\n    + 'UTC_TIMESTAMP,VARBINARY,VARCHARACTER,VARYING,WHEN,WHILE,WITH,'\n    + 'WRITE,X509,XOR,YEAR_MONTH,ACCESSIBLE,LINEAR,'\n    + 'MASTER_SSL_VERIFY_SERVER_CERT,RANGE,READ_ONLY,READ_WRITE';\nend;\n\n{**\n  Gets a comma-separated list of math functions.  These are the\n  X/Open CLI math function names used in the JDBC function escape\n  clause.\n  @return the list\n}\nfunction TZMySQLDatabaseInfo.GetNumericFunctions: string;\nbegin\n  Result := 'ABS,ACOS,ASIN,ATAN,ATAN2,BIT_COUNT,CEILING,COS,COT,DEGREES,EXP,'\n    + 'FLOOR,LOG,LOG10,MAX,MIN,MOD,PI,POW,POWER,RADIANS,RAND,ROUND,SIN,SQRT,'\n    + 'TAN,TRUNCATE';\n  { mdaems : added all numeric functions indicated by mysql documentation (up to mysql 5.1)}\n  Result := Result + 'BIT_COUNT,CEIL,CRC32,LN,LOG2,SIGN,UUID';\nend;\n\n{**\n  Gets a comma-separated list of string functions.  These are the\n  X/Open CLI string function names used in the JDBC function escape\n  clause.\n  @return the list\n}\nfunction TZMySQLDatabaseInfo.GetStringFunctions: string;\nbegin\n  Result := 'ASCII,CHAR,CHAR_LENGTH,CHARACTER_LENGTH,CONCAT,ELT,FIELD,'\n    + 'FIND_IN_SET,INSERT,INSTR,INTERVAL,LCASE,LEFT,LENGTH,LOCATE,LOWER,LTRIM,'\n    + 'MID,POSITION,OCTET_LENGTH,REPEAT,REPLACE,REVERSE,RIGHT,RTRIM,SPACE,'\n    + 'SOUNDEX,SUBSTRING,SUBSTRING_INDEX,TRIM,UCASE,UPPER';\n  { mdaems : added all string functions indicated by mysql documentation (up to mysql 5.1)}\n  Result := Result + 'AES_DECRYPT,AES_ENCRYPT,BIN,BIT_LENGTH,CHARSET,'\n    + 'COERCIBILITY,COLLATION,COMPRESS,CONCAT_WS,DECODE,DES_DECRYPT,DES_ENCRYPT,'\n    + 'ENCODE,ENCRYPT,EXPORT_SET,FORMAT,HEX,LOAD_FILE,LPAD,MAKE_SET,MD5,OCT,ORD,'\n    + 'QUOTE,RPAD,STRCMP,SHA,SHA1,SUBSTR,UNHEX,EXTRACTVALUE,UPDATEXML,'\n    + 'UNCOMPRESS,UNCOMPRESSED_LENGTH';\nend;\n\n{**\n  Gets a comma-separated list of system functions.  These are the\n  X/Open CLI system function names used in the JDBC function escape\n  clause.\n  @return the list\n}\nfunction TZMySQLDatabaseInfo.GetSystemFunctions: string;\nbegin\n  Result := 'DATABASE,USER,SYSTEM_USER,SESSION_USER,PASSWORD,ENCRYPT,'\n    + 'LAST_INSERT_ID,VERSION';\n  { mdaems : added all system functions indicated by mysql documentation (up to mysql 5.1)}\n  Result := Result + 'BENCHMARK,CONNECTION_ID,CURRENT_USER,DEFAULT,FOUND_ROWS,'\n    + 'GET_LOCK,INET_ATON,INET_NTOA,IS_FREE_LOCK,IS_USED_LOCK,MASTER_POS_WAIT,'\n    + 'NAME_CONST,OLD_PASSWORD,RELEASE_LOCK,ROW_COUNT,SCHEMA,SLEEP';\nend;\n\n{**\n  Gets a comma-separated list of time and date functions.\n  @return the list\n}\nfunction TZMySQLDatabaseInfo.GetTimeDateFunctions: string;\nbegin\n  Result := 'DAYOFWEEK,WEEKDAY,DAYOFMONTH,DAYOFYEAR,MONTH,DAYNAME,MONTHNAME,'\n    + 'QUARTER,WEEK,YEAR,HOUR,MINUTE,SECOND,PERIOD_ADD,PERIOD_DIFF,TO_DAYS,'\n    + 'FROM_DAYS,DATE_FORMAT,TIME_FORMAT,CURDATE,CURRENT_DATE,CURTIME,'\n    + 'CURRENT_TIME,NOW,SYSDATE,CURRENT_TIMESTAMP,UNIX_TIMESTAMP,FROM_UNIXTIME,'\n    + 'SEC_TO_TIME,TIME_TO_SEC';\n  { mdaems : added all time and date functions indicated by mysql documentation (up to mysql 5.1)}\n  Result := Result + 'ADDDATE,ADDTIME,CONVERT_TZ,CURRENT_TIMESTAMP,DATE_ADD,'\n    + 'DATE_SUB,DATE,DATEDIFF,DAYOFWEEK,GET_FORMAT,LAST_DAY,LOCALTIME,'\n    + 'LOCALTIMESTAMP,MAKEDATE,MAKETIME,MICROSECOND,STR_TO_DATE,SUBDATE,SUBTIME,'\n    + 'TIMEDIFF,TIMESTAMP,TIMESTAMPADD,TIMESTAMPDIFF,UTC_DATE,UTC_TIME,'\n    + 'UTC_TIMESTAMP,WEEKOFYEAR,YEARWEEK';\nend;\n\n{**\n  Gets the string that can be used to escape wildcard characters.\n  This is the string that can be used to escape '_' or '%' in\n  the string pattern style catalog search parameters.\n\n  <P>The '_' character represents any single character.\n  <P>The '%' character represents any sequence of zero or\n  more characters.\n\n  @return the string used to escape wildcard characters\n}\nfunction TZMySQLDatabaseInfo.GetSearchStringEscape: string;\nbegin\n  Result := '\\';\nend;\n\n{**\n  Gets all the \"extra\" characters that can be used in unquoted\n  identifier names (those beyond a-z, A-Z, 0-9 and _).\n  @return the string containing the extra characters\n}\nfunction TZMySQLDatabaseInfo.GetExtraNameCharacters: string;\nbegin\n  Result := '';\nend;\n\n//--------------------------------------------------------------------\n// Functions describing which features are supported.\n\n{**\n  Can an \"ORDER BY\" clause use columns not in the SELECT statement?\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZMySQLDatabaseInfo.SupportsOrderByUnrelated: Boolean;\nvar\n  MajorVersion: Integer;\n  MinorVersion: Integer;\nbegin\n  GetVersion(MajorVersion, MinorVersion);\n  // changed from False by mdaems. After testing with lower versions, please correct.\n  Result := MajorVersion >= 5;\nend;\n\n{**\n  Can a \"GROUP BY\" clause use columns not in the SELECT?\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZMySQLDatabaseInfo.SupportsGroupByUnrelated: Boolean;\nbegin\n  Result := False;\nend;\n\n{**\n  Can a \"GROUP BY\" clause add columns not in the SELECT\n  provided it specifies all the columns in the SELECT?\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZMySQLDatabaseInfo.SupportsGroupByBeyondSelect: Boolean;\nbegin\n  Result := True;\nend;\n\n{**\n  Is the SQL Integrity Enhancement Facility supported?\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZMySQLDatabaseInfo.SupportsIntegrityEnhancementFacility: Boolean;\nbegin\n  Result := False;\nend;\n\n{**\n  What's the database vendor's preferred term for \"schema\"?\n  @return the vendor term\n}\nfunction TZMySQLDatabaseInfo.GetSchemaTerm: string;\nbegin\n  Result := '';\nend;\n\n{**\n  What's the database vendor's preferred term for \"procedure\"?\n  @return the vendor term\n}\nfunction TZMySQLDatabaseInfo.GetProcedureTerm: string;\nbegin\n  Result := '';\nend;\n\n{**\n  What's the database vendor's preferred term for \"catalog\"?\n  @return the vendor term\n}\nfunction TZMySQLDatabaseInfo.GetCatalogTerm: string;\nbegin\n  Result := 'Database';\nend;\n\n{**\n  Can a catalog name be used in a data manipulation statement?\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZMySQLDatabaseInfo.SupportsCatalogsInDataManipulation: Boolean;\nvar\n  MajorVersion: Integer;\n  MinorVersion: Integer;\nbegin\n  GetVersion(MajorVersion, MinorVersion);\n  Result := ((MajorVersion = 3) and (MinorVersion >= 22)) or (MajorVersion > 3);\nend;\n\n{**\n  Can a catalog name be used in a table definition statement?\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZMySQLDatabaseInfo.SupportsCatalogsInTableDefinitions: Boolean;\nbegin\n  Result := False;\nend;\n\n{**\n  Are subqueries in comparison expressions supported?\n  A JDBC Compliant<sup><font size=-2>TM</font></sup> driver always returns true.\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZMySQLDatabaseInfo.SupportsSubqueriesInComparisons: Boolean;\nbegin\n  Result := True;\nend;\n\n{**\n  Is SQL UNION ALL supported?\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZMySQLDatabaseInfo.SupportsUnionAll: Boolean;\nvar\n  MajorVersion: Integer;\n  MinorVersion: Integer;\nbegin\n  GetVersion(MajorVersion, MinorVersion);\n  Result := MajorVersion >= 4;\nend;\n\n{**\n  Can statements remain open across commits?\n  @return <code>true</code> if statements always remain open;\n        <code>false</code> if they might not remain open\n}\nfunction TZMySQLDatabaseInfo.SupportsOpenStatementsAcrossCommit: Boolean;\nbegin\n  Result := False;\nend;\n\n{**\n  Can statements remain open across rollbacks?\n  @return <code>true</code> if statements always remain open;\n        <code>false</code> if they might not remain open\n}\nfunction TZMySQLDatabaseInfo.SupportsOpenStatementsAcrossRollback: Boolean;\nbegin\n  Result := False;\nend;\n\n//----------------------------------------------------------------------\n// The following group of methods exposes various limitations\n// based on the target database with the current driver.\n// Unless otherwise specified, a result of zero means there is no\n// limit, or the limit is not known.\n\n{**\n  How many hex characters can you have in an inline binary literal?\n  @return max binary literal length in hex characters;\n       a result of zero means that there is no limit or the limit is not known\n}\nfunction TZMySQLDatabaseInfo.GetMaxBinaryLiteralLength: Integer;\nbegin\n  Result := 16777208;\nend;\n\n{**\n  What's the max length for a character literal?\n  @return max literal length;\n       a result of zero means that there is no limit or the limit is not known\n}\nfunction TZMySQLDatabaseInfo.GetMaxCharLiteralLength: Integer;\nbegin\n  Result := 16777208;\nend;\n\n{**\n  What's the limit on column name length?\n  @return max column name length;\n       a result of zero means that there is no limit or the limit is not known\n}\nfunction TZMySQLDatabaseInfo.GetMaxColumnNameLength: Integer;\nbegin\n  Result := 64;\nend;\n\n{**\n  What's the maximum number of columns in a \"GROUP BY\" clause?\n  @return max number of columns;\n       a result of zero means that there is no limit or the limit is not known\n}\nfunction TZMySQLDatabaseInfo.GetMaxColumnsInGroupBy: Integer;\nbegin\n  Result := 16;\nend;\n\n{**\n  What's the maximum number of columns allowed in an index?\n  @return max number of columns;\n       a result of zero means that there is no limit or the limit is not known\n}\nfunction TZMySQLDatabaseInfo.GetMaxColumnsInIndex: Integer;\nbegin\n  Result := 16;\nend;\n\n{**\n  What's the maximum number of columns in an \"ORDER BY\" clause?\n  @return max number of columns;\n       a result of zero means that there is no limit or the limit is not known\n}\nfunction TZMySQLDatabaseInfo.GetMaxColumnsInOrderBy: Integer;\nbegin\n  Result := 16;\nend;\n\n{**\n  What's the maximum number of columns in a \"SELECT\" list?\n  @return max number of columns;\n       a result of zero means that there is no limit or the limit is not known\n}\nfunction TZMySQLDatabaseInfo.GetMaxColumnsInSelect: Integer;\nbegin\n  Result := 256;\nend;\n\n{**\n  What's the maximum number of columns in a table?\n  @return max number of columns;\n       a result of zero means that there is no limit or the limit is not known\n}\nfunction TZMySQLDatabaseInfo.GetMaxColumnsInTable: Integer;\nbegin\n  Result := 512;\nend;\n\n{**\n  How many active connections can we have at a time to this database?\n  @return max number of active connections;\n       a result of zero means that there is no limit or the limit is not known\n}\nfunction TZMySQLDatabaseInfo.GetMaxConnections: Integer;\nbegin\n  Result := 0;\nend;\n\n{**\n  What's the maximum cursor name length?\n  @return max cursor name length in bytes;\n       a result of zero means that there is no limit or the limit is not known\n}\nfunction TZMySQLDatabaseInfo.GetMaxCursorNameLength: Integer;\nbegin\n  Result := 64;\nend;\n\n{**\n  Retrieves the maximum number of bytes for an index, including all\n  of the parts of the index.\n  @return max index length in bytes, which includes the composite of all\n   the constituent parts of the index;\n   a result of zero means that there is no limit or the limit is not known\n}\nfunction TZMySQLDatabaseInfo.GetMaxIndexLength: Integer;\nbegin\n  Result := 128;\nend;\n\n{**\n  What's the maximum length of a catalog name?\n  @return max name length in bytes;\n       a result of zero means that there is no limit or the limit is not known\n}\nfunction TZMySQLDatabaseInfo.GetMaxCatalogNameLength: Integer;\nbegin\n  Result := 32;\nend;\n\n{**\n  What's the maximum length of a single row?\n  @return max row size in bytes;\n       a result of zero means that there is no limit or the limit is not known\n}\nfunction TZMySQLDatabaseInfo.GetMaxRowSize: Integer;\nbegin\n  Result := 2147483639;\nend;\n\n{**\n  Did getMaxRowSize() include LONGVARCHAR and LONGVARBINARY\n  blobs?\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZMySQLDatabaseInfo.DoesMaxRowSizeIncludeBlobs: Boolean;\nbegin\n  Result := True;\nend;\n\n{**\n  What's the maximum length of an SQL statement?\n  @return max length in bytes;\n       a result of zero means that there is no limit or the limit is not known\n}\nfunction TZMySQLDatabaseInfo.GetMaxStatementLength: Integer;\nbegin\n  Result := 65531;\nend;\n\n{**\n  How many active statements can we have open at one time to this\n  database?\n  @return the maximum number of statements that can be open at one time;\n    a result of zero means that there is no limit or the limit is not known\n}\nfunction TZMySQLDatabaseInfo.GetMaxStatements: Integer;\nbegin\n  Result := 0;\nend;\n\n{**\n  What's the maximum length of a table name?\n  @return max name length in bytes;\n    a result of zero means that there is no limit or the limit is not known\n}\nfunction TZMySQLDatabaseInfo.GetMaxTableNameLength: Integer;\nbegin\n  Result := 64;\nend;\n\n{**\n  What's the maximum number of tables in a SELECT statement?\n  @return the maximum number of tables allowed in a SELECT statement;\n       a result of zero means that there is no limit or the limit is not known\n}\nfunction TZMySQLDatabaseInfo.GetMaxTablesInSelect: Integer;\nbegin\n  Result := 256;\nend;\n\n{**\n  What's the maximum length of a user name?\n  @return max user name length  in bytes;\n    a result of zero means that there is no limit or the limit is not known\n}\nfunction TZMySQLDatabaseInfo.GetMaxUserNameLength: Integer;\nbegin\n  Result := 16;\nend;\n\n//----------------------------------------------------------------------\n\n{**\n  What's the database's default transaction isolation level?  The\n  values are defined in <code>java.sql.Connection</code>.\n  @return the default isolation level\n  @see Connection\n}\nfunction TZMySQLDatabaseInfo.GetDefaultTransactionIsolation:\n  TZTransactIsolationLevel;\nbegin\n  Result := tiNone;\nend;\n\n{**\n  Are both data definition and data manipulation statements\n  within a transaction supported?\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZMySQLDatabaseInfo.\n  SupportsDataDefinitionAndDataManipulationTransactions: Boolean;\nbegin\n  Result := True;\nend;\n\n{**\n  Are only data manipulation statements within a transaction\n  supported?\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZMySQLDatabaseInfo.SupportsDataManipulationTransactionsOnly: Boolean;\nbegin\n  case Metadata.GetConnection.GetTransactionIsolation of\n    tiReadUncommitted: Result := True;\n    tiReadCommitted: Result := True;\n    tiRepeatableRead: Result := True;\n    tiSerializable: Result := True;\n  else\n    Result := False;\n  end;\nend;\n\n{**\n  Gets the MySQL version info.\n  @param MajorVesion the major version of MySQL server.\n  @param MinorVersion the minor version of MySQL server.\n}\nprocedure TZMySQLDatabaseInfo.GetVersion(var MajorVersion,\n  MinorVersion: Integer);\nvar\n  VersionList: TStrings;\n  Subversion : integer;\nbegin\n  DecodeSqlVersioning(Metadata.GetConnection.GetHostVersion,\n    MajorVersion,MinorVersion, Subversion);\n  if (Majorversion < 4) or ((majorversion=4) and (Minorversion = 0)) then\n   with Metadata.GetConnection.CreateStatement.ExecuteQuery('SELECT VERSION()') do\n    begin\n      VersionList := SplitString(String(GetString(1)), '.-');\n      try\n        if VersionList.Count >= 2 then\n        begin\n          MajorVersion := StrToIntDef(VersionList.Strings[0], 0);\n          MinorVersion := StrToIntDef(VersionList.Strings[1], 0);\n        end;\n      finally\n        VersionList.Free;\n      end;\n      Close;\n    end;\nend;\n\n{ TZMySQLDatabaseMetadata }\n\n{**\n  Destroys this object and cleanups the memory.\n}\ndestructor TZMySQLDatabaseMetadata.Destroy;\nbegin\n  inherited Destroy;\nend;\n\n{**\n  Constructs a database information object and returns the interface to it. Used\n  internally by the constructor.\n  @return the database information object interface\n}\nfunction TZMySQLDatabaseMetadata.CreateDatabaseInfo: IZDatabaseInfo;\nbegin\n  Result := TZMySQLDatabaseInfo.Create(Self);\nend;\n\nprocedure TZMySQLDatabaseMetadata.GetCatalogAndNamePattern(const Catalog,\n  SchemaPattern, NamePattern: string; out OutCatalog, OutNamePattern: string);\nbegin\n  if Catalog = '' then\n  begin\n    if SchemaPattern <> '' then\n      OutCatalog := NormalizePatternCase(SchemaPattern)\n    else\n      OutCatalog := NormalizePatternCase(FDatabase);\n  end\n  else\n    OutCatalog := NormalizePatternCase(Catalog);\n\n  if NamePattern = '' then\n    OutNamePattern := '%'\n  else\n    OutNamePattern := NormalizePatternCase(NamePattern);\nend;\n\n{**\n  Gets a description of tables available in a catalog.\n\n  <P>Only table descriptions matching the catalog, schema, table\n  name and type criteria are returned.  They are ordered by\n  TABLE_TYPE, TABLE_SCHEM and TABLE_NAME.\n\n  <P>Each table description has the following columns:\n   <OL>\n \t<LI><B>TABLE_CAT</B> String => table catalog (may be null)\n \t<LI><B>TABLE_SCHEM</B> String => table schema (may be null)\n \t<LI><B>TABLE_NAME</B> String => table name\n \t<LI><B>TABLE_TYPE</B> String => table type.  Typical types are \"TABLE\",\n \t\t\t\"VIEW\",\t\"SYSTEM TABLE\", \"GLOBAL TEMPORARY\",\n \t\t\t\"LOCAL TEMPORARY\", \"ALIAS\", \"SYNONYM\".\n \t<LI><B>REMARKS</B> String => explanatory comment on the table\n   </OL>\n\n  <P><B>Note:</B> Some databases may not return information for\n  all tables.\n\n  @param catalog a catalog name; \"\" retrieves those without a\n  catalog; null means drop catalog name from the selection criteria\n  @param schemaPattern a schema name pattern; \"\" retrieves those\n  without a schema\n  @param tableNamePattern a table name pattern\n  @param types a list of table types to include; null returns all types\n  @return <code>ResultSet</code> - each row is a table description\n  @see #getSearchStringEscape\n}\nfunction TZMySQLDatabaseMetadata.UncachedGetTables(const Catalog: string;\n  const SchemaPattern: string; const TableNamePattern: string;\n  const Types: TStringDynArray): IZResultSet;\nvar\n  LCatalog, LTableNamePattern: string;\nbegin\n    Result := inherited UncachedGetTables(Catalog, SchemaPattern, TableNamePattern, Types);\n\n    GetCatalogAndNamePattern(Catalog, SchemaPattern, TableNamePattern,\n      LCatalog, LTableNamePattern);\n\n    with GetConnection.CreateStatement.ExecuteQuery(\n      Format('SHOW TABLES FROM %s LIKE ''%s''',\n      [IC.Quote(LCatalog), LTableNamePattern])) do\n    begin\n      while Next do\n      begin\n        Result.MoveToInsertRow;\n        Result.UpdateString(1, LCatalog);\n        Result.UpdateString(3, GetString(1));\n        Result.UpdateString(4, 'TABLE');\n        Result.InsertRow;\n      end;\n      Close;\n    end;\n\n    // If a table was specified but not found, check if it could be a temporary table\n    if not Result.First and (LTableNamePattern <> '%') then\n    begin\n      try\n        EnterSilentMySQLError;\n        try\n          if GetConnection.CreateStatement.ExecuteQuery(\n            Format('SHOW COLUMNS FROM %s.%s',\n            [IC.Quote(LCatalog),\n             IC.Quote(LTableNamePattern)])).Next then\n          begin\n            Result.MoveToInsertRow;\n            Result.UpdateString(1, LCatalog);\n            Result.UpdateString(3, LTableNamePattern);\n            Result.UpdateString(4, 'TABLE');\n            Result.InsertRow;\n          end;\n        finally\n          LeaveSilentMySQLError;\n        end;\n      except\n        on EZMySQLSilentException do ;\n        on EZSQLException do ;\n      end;\n    end;\nend;\n\n{**\n  Gets the catalog names available in this database.  The results\n  are ordered by catalog name.\n\n  <P>The catalog column is:\n   <OL>\n \t<LI><B>TABLE_CAT</B> String => catalog name\n   </OL>\n\n  @return <code>ResultSet</code> - each row has a single String column that is a\n  catalog name\n}\nfunction TZMySQLDatabaseMetadata.UncachedGetCatalogs: IZResultSet;\nbegin\n    Result:=inherited UncachedGetCatalogs;\n\n    with GetConnection.CreateStatement.ExecuteQuery('SHOW DATABASES') do\n    begin\n      while Next do\n      begin\n        Result.MoveToInsertRow;\n        Result.UpdateString(1, GetString(1));\n        Result.InsertRow;\n      end;\n      Close;\n    end;\nend;\n\n{**\n  Gets the table types available in this database.  The results\n  are ordered by table type.\n\n  <P>The table type is:\n   <OL>\n \t<LI><B>TABLE_TYPE</B> String => table type.  Typical types are \"TABLE\",\n \t\t\t\"VIEW\",\t\"SYSTEM TABLE\", \"GLOBAL TEMPORARY\",\n \t\t\t\"LOCAL TEMPORARY\", \"ALIAS\", \"SYNONYM\".\n   </OL>\n\n  @return <code>ResultSet</code> - each row has a single String column that is a\n  table type\n}\nfunction TZMySQLDatabaseMetadata.UncachedGetTableTypes: IZResultSet;\nbegin\n    Result:=inherited UncachedGetTableTypes;\n\n    Result.MoveToInsertRow;\n    Result.UpdateString(1, 'TABLE');\n    Result.InsertRow;\nend;\n\n{**\n  Gets a description of table columns available in\n  the specified catalog.\n\n  <P>Only column descriptions matching the catalog, schema, table\n  and column name criteria are returned.  They are ordered by\n  TABLE_SCHEM, TABLE_NAME and ORDINAL_POSITION.\n\n  <P>Each column description has the following columns:\n   <OL>\n \t<LI><B>TABLE_CAT</B> String => table catalog (may be null)\n \t<LI><B>TABLE_SCHEM</B> String => table schema (may be null)\n \t<LI><B>TABLE_NAME</B> String => table name\n \t<LI><B>COLUMN_NAME</B> String => column name\n \t<LI><B>DATA_TYPE</B> short => SQL type from java.sql.Types\n \t<LI><B>TYPE_NAME</B> String => Data source dependent type name,\n   for a UDT the type name is fully qualified\n \t<LI><B>COLUMN_SIZE</B> int => column size.  For char or date\n \t    types this is the maximum number of characters, for numeric or\n \t    decimal types this is precision.\n \t<LI><B>BUFFER_LENGTH</B> is not used.\n \t<LI><B>DECIMAL_DIGITS</B> int => the number of fractional digits\n \t<LI><B>NUM_PREC_RADIX</B> int => Radix (typically either 10 or 2)\n \t<LI><B>NULLABLE</B> int => is NULL allowed?\n       <UL>\n       <LI> columnNoNulls - might not allow NULL values\n       <LI> columnNullable - definitely allows NULL values\n       <LI> columnNullableUnknown - nullability unknown\n       </UL>\n \t<LI><B>REMARKS</B> String => comment describing column (may be null)\n  \t<LI><B>COLUMN_DEF</B> String => default value (may be null)\n \t<LI><B>SQL_DATA_TYPE</B> int => unused\n \t<LI><B>SQL_DATETIME_SUB</B> int => unused\n \t<LI><B>CHAR_OCTET_LENGTH</B> int => for char types the\n        maximum number of bytes in the column\n \t<LI><B>ORDINAL_POSITION</B> int\t=> index of column in table\n       (starting at 1)\n \t<LI><B>IS_NULLABLE</B> String => \"NO\" means column definitely\n       does not allow NULL values; \"YES\" means the column might\n       allow NULL values.  An empty string means nobody knows.\n   </OL>\n\n  @param catalog a catalog name; \"\" retrieves those without a\n  catalog; null means drop catalog name from the selection criteria\n  @param schemaPattern a schema name pattern; \"\" retrieves those\n  without a schema\n  @param tableNamePattern a table name pattern\n  @param columnNamePattern a column name pattern\n  @return <code>ResultSet</code> - each row is a column description\n  @see #getSearchStringEscape\n}\nfunction TZMySQLDatabaseMetadata.UncachedGetColumns(const Catalog: string;\n  const SchemaPattern: string; const TableNamePattern: string;\n  const ColumnNamePattern: string): IZResultSet;\nvar\n  I: Integer;\n  MySQLType: TZSQLType;\n  TempCatalog, TempColumnNamePattern, TempTableNamePattern: string;\n\n  TypeName, TypeInfoSecond: String;\n  Nullable, DefaultValue: String;\n  HasDefaultValue: Boolean;\n  ColumnSize, ColumnDecimals: Integer;\n  OrdPosition: Integer;\n\n  TableNameList: TStrings;\n  TableNameLength: Integer;\n  ColumnIndexes : Array[1..6] of integer;\n  Res : IZResultset;\n\nbegin\n    Res:=inherited UncachedGetColumns(Catalog, SchemaPattern, TableNamePattern, ColumnNamePattern);\n\n    GetCatalogAndNamePattern(Catalog, SchemaPattern, ColumnNamePattern,\n      TempCatalog, TempColumnNamePattern);\n\n    TableNameLength := 0;\n    TableNameList := TStringList.Create;\n    try\n      with GetTables(Catalog, SchemaPattern, TableNamePattern, nil) do\n      begin\n        while Next do\n        begin\n          TableNameList.Add(GetString(3)); //TABLE_NAME\n          TableNameLength := Max(TableNameLength, Length(TableNameList[TableNameList.Count - 1]));\n        end;\n        Close;\n      end;\n\n      for I := 0 to TableNameList.Count - 1 do\n      begin\n        OrdPosition := 1;\n        TempTableNamePattern := TableNameList.Strings[I];\n\n        with GetConnection.CreateStatement.ExecuteQuery(\n          Format('SHOW FULL COLUMNS FROM %s.%s LIKE ''%s''',\n          [IC.Quote(TempCatalog),\n          IC.Quote(TempTableNamePattern),\n          TempColumnNamePattern])) do\n        begin\n          ColumnIndexes[1] := FindColumn('Field');\n          ColumnIndexes[2] := FindColumn('Type');\n          ColumnIndexes[3] := FindColumn('Null');\n          ColumnIndexes[4] := FindColumn('Extra');\n          ColumnIndexes[5] := FindColumn('Default');\n          ColumnIndexes[6] := FindColumn('Collation');\n          while Next do\n          begin\n            {initialise some variables}\n            Res.MoveToInsertRow;\n            Res.UpdateString(1, TempCatalog);\n            Res.UpdateString(2, '');\n            Res.UpdateString(3, TempTableNamePattern) ;\n            Res.UpdateString(4, GetString(ColumnIndexes[1]));\n\n            ConvertMySQLColumnInfoFromString(GetString(ColumnIndexes[2]),\n              ConSettings, TypeName,\n              TypeInfoSecond, MySQLType, ColumnSize, ColumnDecimals);\n            Res.UpdateInt(5, Ord(MySQLType));\n            Res.UpdateString(6, TypeName);\n            Res.UpdateInt(7, ColumnSize);\n            Res.UpdateInt(8, MAXBUF);\n            Res.UpdateInt(9, ColumnDecimals);\n            Res.UpdateNull(10);\n\n            { Sets nullable fields. }\n            Nullable := GetString(ColumnIndexes[3]);\n            if Nullable <> '' then\n              if Nullable = 'YES' then\n              begin\n                Res.UpdateInt(11, Ord(ntNullable));\n                Res.UpdateString(18, 'YES');\n              end\n              else\n              begin\n                Res.UpdateInt(11, Ord(ntNoNulls));\n                Res.UpdateString(18, 'NO');\n              end\n            else\n            begin\n              Res.UpdateInt(11, 0);\n              Res.UpdateString(18, 'NO');\n            end;\n            Res.UpdateString(12, GetString(ColumnIndexes[4]));\n            // MySQL is a bit bizarre.\n            if IsNull(ColumnIndexes[5]) then\n            begin\n              // MySQL bizarity 1:\n              // NULL actually means that the default is NULL.\n              // Superfluous, since there's a NULL / NOT NULL flag to control whether the field may have no value.\n              // So we just ignore this, the field gets set to NULL if nothing was specified...\n              HasDefaultValue := false;\n              DefaultValue := '';\n            end\n            else\n            begin\n              DefaultValue := GetString(ColumnIndexes[5]);\n              if not (DefaultValue = '') then\n                 HasDefaultValue := true\n              else\n              begin\n                // MySQL bizarity 2:\n                // For CHAR, BLOB, TEXT and SET types, '' either means: default value is '' or: no default value\n                // There's absolutely no way of telling when using SHOW COLUMNS FROM,\n                // the correct information can /only/ be discerned by using information_schema.\n                // TODO: For now, just use '' as default value for these types, but this should really be fixed to use information_schema.\n                // For ENUM types, '' means: default value is first value in enum set\n                // For other types, '' means: no default value\n                HasDefaultValue := false;\n                if Pos('blob', TypeName) > 0 then HasDefaultValue := true;\n                if Pos('text', TypeName) > 0 then HasDefaultValue := true;\n                if Pos('char', TypeName) > 0 then HasDefaultValue := true;\n                if 'set' = TypeName then HasDefaultValue := true;\n                if 'enum' =  TypeName then\n                  begin\n                    HasDefaultValue := true;\n                    DefaultValue := Copy(TypeInfoSecond, 2,length(TypeInfoSecond)-1);\n                    DefaultValue := Copy(DefaultValue, 1, Pos('''', DefaultValue) - 1);\n                  end;\n              end;\n            end;\n            if HasDefaultValue then\n            begin\n              // String values in the 'Default value' field are not escaped with apostrophes.\n              // Guess this makes it impossible to specify a function call or similar via default values.\n              if (MySQLType in [stString, stUnicodeString, stBinaryStream, stAsciiStream]) then\n              begin\n                // Since we changed date/time-related columntypes to be presented\n                // as strings, we need to move the CURRENT_TIMESTAMP-check to here.\n                // Also left the other line in order to minimize the changes in ZeosLib\n                if DefaultValue <> 'CURRENT_TIMESTAMP' then\n                DefaultValue := '''' + DefaultValue + ''''\n              end\n              else if (MySQLType in [stDate, stTime, stTimestamp]) then\n              begin\n                if DefaultValue <> 'CURRENT_TIMESTAMP' then\n                  DefaultValue := '''' + DefaultValue + ''''\n              end\n              else if (MySQLType = stBoolean) and (TypeName = 'enum') then\n              begin\n                if (DefaultValue = 'y') or (DefaultValue = 'Y') then\n                  DefaultValue := '1'\n                else\n                  DefaultValue := '0';\n              end;\n            end;\n            Res.UpdateString(13, DefaultValue);\n            Res.UpdateNull(14);\n            Res.UpdateNull(15);\n            Res.UpdateInt(17, OrdPosition);\n\n            Res.UpdateBoolean(19, //AUTO_INCREMENT\n              Trim(LowerCase(GetString(ColumnIndexes[4]))) = 'auto_increment'); //Extra\n            Res.UpdateBoolean(20, //CASE_SENSITIVE\n              IC.IsCaseSensitive(GetString(ColumnIndexes[1]))); //Field\n            Res.UpdateBoolean(21, True);  //SEARCHABLE\n            Res.UpdateBoolean(22, True);  //WRITABLE\n            Res.UpdateBoolean(23, True);  //DEFINITELYWRITABLE\n            Res.UpdateBoolean(24, False); //READONLY\n\n            Inc(OrdPosition);\n            Res.InsertRow;\n          end;\n          Close;\n        end;\n      end;\n    finally\n      TableNameList.Free;\n    end;\n    Result := Res;\nend;\n\n{**\n  Gets a description of the access rights for a table's columns.\n\n  <P>Only privileges matching the column name criteria are\n  returned.  They are ordered by COLUMN_NAME and PRIVILEGE.\n\n  <P>Each privilige description has the following columns:\n   <OL>\n \t<LI><B>TABLE_CAT</B> String => table catalog (may be null)\n \t<LI><B>TABLE_SCHEM</B> String => table schema (may be null)\n \t<LI><B>TABLE_NAME</B> String => table name\n \t<LI><B>COLUMN_NAME</B> String => column name\n \t<LI><B>GRANTOR</B> => grantor of access (may be null)\n \t<LI><B>GRANTEE</B> String => grantee of access\n \t<LI><B>PRIVILEGE</B> String => name of access (SELECT,\n       INSERT, UPDATE, REFRENCES, ...)\n \t<LI><B>IS_GRANTABLE</B> String => \"YES\" if grantee is permitted\n       to grant to others; \"NO\" if not; null if unknown\n   </OL>\n\n  @param catalog a catalog name; \"\" retrieves those without a\n  catalog; null means drop catalog name from the selection criteria\n  @param schema a schema name; \"\" retrieves those without a schema\n  @param table a table name\n  @param columnNamePattern a column name pattern\n  @return <code>ResultSet</code> - each row is a column privilege description\n  @see #getSearchStringEscape\n}\nfunction TZMySQLDatabaseMetadata.UncachedGetColumnPrivileges(const Catalog: string;\n  const Schema: string; const Table: string; const ColumnNamePattern: string): IZResultSet;\nvar\n  I: Integer;\n  Host, Database, Grantor, User, FullUser: String;\n  AllPrivileges, ColumnName, Privilege: String;\n  PrivilegesList: TStrings;\n  ColumnNameCondition, TableNameCondition, SchemaCondition: string;\nbegin\n  Result:=inherited UncachedGetColumnPrivileges(Catalog, Schema, Table, ColumnNamePattern);\n\n    If Catalog = '' then\n      If Schema <> '' then\n      SchemaCondition := ConstructNameCondition(Schema,'c.db')\n      else\n      SchemaCondition := ConstructNameCondition(FDatabase,'c.db')\n    else\n      SchemaCondition := ConstructNameCondition(Catalog,'c.db');\n    TableNameCondition := ConstructNameCondition(Table,'c.table_name');\n    ColumnNameCondition := ConstructNameCondition(ColumnNamePattern,'c.column_name');\n    If SchemaCondition <> '' then\n      SchemaCondition := ' and ' + SchemaCondition;\n    If TableNameCondition <> '' then\n      TableNameCondition := ' and ' + TableNameCondition;\n    If ColumnNameCondition <> '' then\n      ColumnNameCondition := ' and ' + ColumnNameCondition;\n\n    PrivilegesList := TStringList.Create;\n    try\n      with GetConnection.CreateStatement.ExecuteQuery(\n        'SELECT c.host, c.db, t.grantor, c.user, c.table_name,'\n        + ' c.column_name, c.column_priv FROM mysql.columns_priv c,'\n        + ' mysql.tables_priv t WHERE c.host=t.host AND c.db=t.db'\n        + ' AND c.table_name=t.table_name'\n        + SchemaCondition + TableNameCondition + ColumnNameCondition\n      ) do\n      begin\n        while Next do\n        begin\n          Host := GetString(1);\n          Database := GetString(2);\n          Grantor := GetString(4);\n          User := GetString(5);\n          if User = '' then\n            User := '%';\n          if Host <> '' then\n            FullUser := User + '@' + Host;\n          ColumnName := GetString(6);\n\n          AllPrivileges := GetString(7);\n          PutSplitString(PrivilegesList, AllPrivileges, ',');\n\n          for I := 0 to PrivilegesList.Count - 1 do\n          begin\n            Result.MoveToInsertRow;\n            Privilege := Trim(PrivilegesList.Strings[I]);\n            Result.UpdateString(1, Database);\n            Result.UpdateNull(2);\n            Result.UpdateString(3, Table);\n            Result.UpdateString(4, ColumnName);\n            Result.UpdateString(5, Grantor);\n            Result.UpdateString(6, FullUser);\n            Result.UpdateString(7, Privilege);\n            Result.UpdateNull(8);\n            Result.InsertRow;\n          end;\n        end;\n        Close;\n      end;\n    finally\n      PrivilegesList.Free;\n    end;\nend;\n\n{**\n  Gets a description of the access rights for each table available\n  in a catalog. Note that a table privilege applies to one or\n  more columns in the table. It would be wrong to assume that\n  this priviledge applies to all columns (this may be true for\n  some systems but is not true for all.)\n\n  <P>Only privileges matching the schema and table name\n  criteria are returned.  They are ordered by TABLE_SCHEM,\n  TABLE_NAME, and PRIVILEGE.\n\n  <P>Each privilige description has the following columns:\n   <OL>\n \t<LI><B>TABLE_CAT</B> String => table catalog (may be null)\n \t<LI><B>TABLE_SCHEM</B> String => table schema (may be null)\n \t<LI><B>TABLE_NAME</B> String => table name\n \t<LI><B>GRANTOR</B> => grantor of access (may be null)\n \t<LI><B>GRANTEE</B> String => grantee of access\n \t<LI><B>PRIVILEGE</B> String => name of access (SELECT,\n       INSERT, UPDATE, REFRENCES, ...)\n \t<LI><B>IS_GRANTABLE</B> String => \"YES\" if grantee is permitted\n       to grant to others; \"NO\" if not; null if unknown\n   </OL>\n\n  @param catalog a catalog name; \"\" retrieves those without a\n  catalog; null means drop catalog name from the selection criteria\n  @param schemaPattern a schema name pattern; \"\" retrieves those\n  without a schema\n  @param tableNamePattern a table name pattern\n  @return <code>ResultSet</code> - each row is a table privilege description\n  @see #getSearchStringEscape\n}\nfunction TZMySQLDatabaseMetadata.UncachedGetTablePrivileges(const Catalog: string;\n  const SchemaPattern: string; const TableNamePattern: string): IZResultSet;\nvar\n  I: Integer;\n  Host, Database, Table, Grantor, User, FullUser: String;\n  AllPrivileges, Privilege: String;\n  PrivilegesList: TStrings;\n  TableNameCondition, SchemaCondition: string;\nbegin\n    Result:=inherited UncachedGetTablePrivileges(Catalog, SchemaPattern, TableNamePattern);\n\n    If Catalog = '' then\n      If SchemaPattern <> '' then\n      SchemaCondition := ConstructNameCondition(SchemaPattern,'db')\n      else\n      SchemaCondition := ConstructNameCondition(FDatabase,'db')\n    else\n      SchemaCondition := ConstructNameCondition(Catalog,'db');\n    TableNameCondition := ConstructNameCondition(TableNamePattern,'table_name');\n    If SchemaCondition <> '' then\n      SchemaCondition := ' and ' + SchemaCondition;\n    If TableNameCondition <> '' then\n      TableNameCondition := ' and ' + TableNameCondition;\n\n    PrivilegesList := TStringList.Create;\n    try\n      with GetConnection.CreateStatement.ExecuteQuery(\n        'SELECT host,db,table_name,grantor,user,table_priv'\n        + ' from mysql.tables_priv WHERE 1=1'\n        + SchemaCondition + TableNameCondition\n      ) do\n      begin\n        while Next do\n        begin\n          Host := GetString(1);\n          Database := GetString(2);\n          Table := GetString(3);\n          Grantor := GetString(4);\n          User := GetString(5);\n          if User = '' then\n            User := '%';\n          if Host <> '' then\n            FullUser := User + '@' + Host;\n\n          AllPrivileges := GetString(6);\n          PutSplitString(PrivilegesList, AllPrivileges, ',');\n\n          for I := 0 to PrivilegesList.Count - 1 do\n          begin\n            Result.MoveToInsertRow;\n            Privilege := Trim(PrivilegesList.Strings[I]);\n            Result.UpdateString(1, Database);\n            Result.UpdateNull(2);\n            Result.UpdateString(3, Table);\n            Result.UpdateString(4, Grantor);\n            Result.UpdateString(5, FullUser);\n            Result.UpdateString(6, Privilege);\n            Result.UpdateNull(7);\n            Result.InsertRow;\n          end;\n        end;\n        Close;\n      end;\n    finally\n      PrivilegesList.Free;\n    end;\nend;\n\n{**\n  Gets a description of a table's primary key columns.  They\n  are ordered by COLUMN_NAME.\n\n  <P>Each primary key column description has the following columns:\n   <OL>\n \t<LI><B>TABLE_CAT</B> String => table catalog (may be null)\n \t<LI><B>TABLE_SCHEM</B> String => table schema (may be null)\n \t<LI><B>TABLE_NAME</B> String => table name\n \t<LI><B>COLUMN_NAME</B> String => column name\n \t<LI><B>KEY_SEQ</B> short => sequence number within primary key\n \t<LI><B>PK_NAME</B> String => primary key name (may be null)\n   </OL>\n\n  @param catalog a catalog name; \"\" retrieves those without a\n  catalog; null means drop catalog name from the selection criteria\n  @param schema a schema name; \"\" retrieves those\n  without a schema\n  @param table a table name\n  @return <code>ResultSet</code> - each row is a primary key column description\n  @exception SQLException if a database access error occurs\n}\nfunction TZMySQLDatabaseMetadata.UncachedGetPrimaryKeys(const Catalog: string;\n  const Schema: string; const Table: string): IZResultSet;\nvar\n  KeyType: string;\n  LCatalog, LTable: string;\n  ColumnIndexes : Array[1..3] of integer;\nbegin\n    if Table = '' then\n      raise Exception.Create(STableIsNotSpecified); //CHANGE IT!\n\n    Result:=inherited UncachedGetPrimaryKeys(Catalog, Schema, Table);\n\n    GetCatalogAndNamePattern(Catalog, Schema, Table,\n      LCatalog, LTable);\n\n    with GetConnection.CreateStatement.ExecuteQuery(\n      Format('SHOW KEYS FROM %s.%s',\n      [IC.Quote(LCatalog),\n      IC.Quote(LTable)])) do\n    begin\n      ColumnIndexes[1] := FindColumn('Key_name');\n      ColumnIndexes[2] := FindColumn('Column_name');\n      ColumnIndexes[3] := FindColumn('Seq_in_index');\n      while Next do\n      begin\n        KeyType := UpperCase(String(GetString(ColumnIndexes[1])));\n        KeyType := Copy(KeyType, 1, 3);\n        if KeyType = 'PRI' then\n        begin\n          Result.MoveToInsertRow;\n          Result.UpdateString(1, LCatalog);\n          Result.UpdateString(2, '');\n          Result.UpdateString(3, Table);\n          Result.UpdateString(4, GetString(ColumnIndexes[2]));\n          Result.UpdateString(5, GetString(ColumnIndexes[3]));\n          Result.UpdateNull(6);\n          Result.InsertRow;\n        end;\n      end;\n      Close;\n    end;\nend;\n\n{**\n  Gets a description of the primary key columns that are\n  referenced by a table's foreign key columns (the primary keys\n  imported by a table).  They are ordered by PKTABLE_CAT,\n  PKTABLE_SCHEM, PKTABLE_NAME, and KEY_SEQ.\n\n  <P>Each primary key column description has the following columns:\n   <OL>\n \t<LI><B>PKTABLE_CAT</B> String => primary key table catalog\n       being imported (may be null)\n \t<LI><B>PKTABLE_SCHEM</B> String => primary key table schema\n       being imported (may be null)\n \t<LI><B>PKTABLE_NAME</B> String => primary key table name\n       being imported\n \t<LI><B>PKCOLUMN_NAME</B> String => primary key column name\n       being imported\n \t<LI><B>FKTABLE_CAT</B> String => foreign key table catalog (may be null)\n \t<LI><B>FKTABLE_SCHEM</B> String => foreign key table schema (may be null)\n \t<LI><B>FKTABLE_NAME</B> String => foreign key table name\n \t<LI><B>FKCOLUMN_NAME</B> String => foreign key column name\n \t<LI><B>KEY_SEQ</B> short => sequence number within foreign key\n \t<LI><B>UPDATE_RULE</B> short => What happens to\n        foreign key when primary is updated:\n       <UL>\n       <LI> importedNoAction - do not allow update of primary\n                key if it has been imported\n       <LI> importedKeyCascade - change imported key to agree\n                with primary key update\n       <LI> importedKeySetNull - change imported key to NULL if\n                its primary key has been updated\n       <LI> importedKeySetDefault - change imported key to default values\n                if its primary key has been updated\n       <LI> importedKeyRestrict - same as importedKeyNoAction\n                                  (for ODBC 2.x compatibility)\n       </UL>\n \t<LI><B>DELETE_RULE</B> short => What happens to\n       the foreign key when primary is deleted.\n       <UL>\n       <LI> importedKeyNoAction - do not allow delete of primary\n                key if it has been imported\n       <LI> importedKeyCascade - delete rows that import a deleted key\n       <LI> importedKeySetNull - change imported key to NULL if\n                its primary key has been deleted\n       <LI> importedKeyRestrict - same as importedKeyNoAction\n                                  (for ODBC 2.x compatibility)\n       <LI> importedKeySetDefault - change imported key to default if\n                its primary key has been deleted\n       </UL>\n \t<LI><B>FK_NAME</B> String => foreign key name (may be null)\n \t<LI><B>PK_NAME</B> String => primary key name (may be null)\n \t<LI><B>DEFERRABILITY</B> short => can the evaluation of foreign key\n       constraints be deferred until commit\n       <UL>\n       <LI> importedKeyInitiallyDeferred - see SQL92 for definition\n       <LI> importedKeyInitiallyImmediate - see SQL92 for definition\n       <LI> importedKeyNotDeferrable - see SQL92 for definition\n       </UL>\n   </OL>\n\n  @param catalog a catalog name; \"\" retrieves those without a\n  catalog; null means drop catalog name from the selection criteria\n  @param schema a schema name; \"\" retrieves those\n  without a schema\n  @param table a table name\n  @return <code>ResultSet</code> - each row is a primary key column description\n  @see #getExportedKeys\n}\nfunction TZMySQLDatabaseMetadata.UncachedGetImportedKeys(const Catalog: string;\n  const Schema: string; const Table: string): IZResultSet;\nvar\n  I: Integer;\n  KeySeq: Integer;\n  LCatalog, LTable: string;\n  TableType, Comment, Keys: String;\n  CommentList, KeyList: TStrings;\n  ColumnIndexes : Array[1..2] of integer;\nbegin\n    if Table = '' then\n      raise Exception.Create(STableIsNotSpecified); //CHANGE IT!\n\n    Result := inherited UncachedGetImportedKeys(Catalog, Schema, Table);\n\n    GetCatalogAndNamePattern(Catalog, Schema, Table,\n      LCatalog, LTable);\n\n    KeyList := TStringList.Create;\n    CommentList := TStringList.Create;\n    try\n      with GetConnection.CreateStatement.ExecuteQuery(\n        Format('SHOW TABLE STATUS FROM %s LIKE ''%s''',\n        [IC.Quote(LCatalog), LTable])) do\n      begin\n        ColumnIndexes[1] := FindColumn('Type');\n        ColumnIndexes[2] := FindColumn('Comment');\n        while Next do\n        begin\n          TableType := GetString(ColumnIndexes[1]);\n          if (TableType <> '') and (LowerCase(TableType) = 'innodb') then\n          begin\n            Comment := GetString(ColumnIndexes[2]);\n            if Comment <> '' then\n            begin\n              PutSplitString(CommentList, Comment, ';');\n              KeySeq := 0;\n\n              if CommentList.Count > 4 then\n              begin\n                for I := 0 to CommentList.Count - 1 do\n                begin\n                  Keys := CommentList.Strings[1];\n                  Result.MoveToInsertRow;\n                  PutSplitString(KeyList, Keys, '() /');\n\n                  Result.UpdateString(1, KeyList.Strings[2]); // PKTABLE_CAT\n                  Result.UpdateNull(2); // PKTABLE_SCHEM\n                  Result.UpdateString(3, KeyList.Strings[3]); // PKTABLE_NAME\n                  Result.UpdateString(4, KeyList.Strings[4]); // PKCOLUMN_NAME\n                  Result.UpdateString(5, LCatalog);\n                  Result.UpdateNull(6);// FKTABLE_SCHEM\n                  Result.UpdateString(7, Table); // FKTABLE_NAME\n                  Result.UpdateString(8, KeyList.Strings[0]); // FKCOLUMN_NAME\n\n                  Result.UpdateInt(9, KeySeq); // KEY_SEQ\n                  Result.UpdateInt(10, Ord(ikSetDefault)); // UPDATE_RULE\n                  Result.UpdateInt(11, Ord(ikSetDefault)); // DELETE_RULE\n                  Result.UpdateNull(12); // FK_NAME\n                  Result.UpdateNull(13); // PK_NAME\n                  Result.UpdateInt(14, Ord(ikSetDefault)); // DEFERRABILITY\n                  Inc(KeySeq);\n                  Result.InsertRow;\n                end;\n              end;\n            end;\n          end;\n        end;\n        Close;\n      end;\n    finally\n      KeyList.Free;\n      CommentList.Free;\n    end;\nend;\n\n{**\n  Gets a description of the foreign key columns that reference a\n  table's primary key columns (the foreign keys exported by a\n  table).  They are ordered by FKTABLE_CAT, FKTABLE_SCHEM,\n  FKTABLE_NAME, and KEY_SEQ.\n\n  <P>Each foreign key column description has the following columns:\n   <OL>\n \t<LI><B>PKTABLE_CAT</B> String => primary key table catalog (may be null)\n \t<LI><B>PKTABLE_SCHEM</B> String => primary key table schema (may be null)\n \t<LI><B>PKTABLE_NAME</B> String => primary key table name\n \t<LI><B>PKCOLUMN_NAME</B> String => primary key column name\n \t<LI><B>FKTABLE_CAT</B> String => foreign key table catalog (may be null)\n       being exported (may be null)\n \t<LI><B>FKTABLE_SCHEM</B> String => foreign key table schema (may be null)\n       being exported (may be null)\n \t<LI><B>FKTABLE_NAME</B> String => foreign key table name\n       being exported\n \t<LI><B>FKCOLUMN_NAME</B> String => foreign key column name\n       being exported\n \t<LI><B>KEY_SEQ</B> short => sequence number within foreign key\n \t<LI><B>UPDATE_RULE</B> short => What happens to\n        foreign key when primary is updated:\n       <UL>\n       <LI> importedNoAction - do not allow update of primary\n                key if it has been imported\n       <LI> importedKeyCascade - change imported key to agree\n                with primary key update\n       <LI> importedKeySetNull - change imported key to NULL if\n                its primary key has been updated\n       <LI> importedKeySetDefault - change imported key to default values\n                if its primary key has been updated\n       <LI> importedKeyRestrict - same as importedKeyNoAction\n                                  (for ODBC 2.x compatibility)\n       </UL>\n \t<LI><B>DELETE_RULE</B> short => What happens to\n       the foreign key when primary is deleted.\n       <UL>\n       <LI> importedKeyNoAction - do not allow delete of primary\n                key if it has been imported\n       <LI> importedKeyCascade - delete rows that import a deleted key\n       <LI> importedKeySetNull - change imported key to NULL if\n                its primary key has been deleted\n       <LI> importedKeyRestrict - same as importedKeyNoAction\n                                  (for ODBC 2.x compatibility)\n       <LI> importedKeySetDefault - change imported key to default if\n                its primary key has been deleted\n       </UL>\n \t<LI><B>FK_NAME</B> String => foreign key name (may be null)\n \t<LI><B>PK_NAME</B> String => primary key name (may be null)\n \t<LI><B>DEFERRABILITY</B> short => can the evaluation of foreign key\n       constraints be deferred until commit\n       <UL>\n       <LI> importedKeyInitiallyDeferred - see SQL92 for definition\n       <LI> importedKeyInitiallyImmediate - see SQL92 for definition\n       <LI> importedKeyNotDeferrable - see SQL92 for definition\n       </UL>\n   </OL>\n\n  @param catalog a catalog name; \"\" retrieves those without a\n  catalog; null means drop catalog name from the selection criteria\n  @param schema a schema name; \"\" retrieves those\n  without a schema\n  @param table a table name\n  @return <code>ResultSet</code> - each row is a foreign key column description\n  @see #getImportedKeys\n}\nfunction TZMySQLDatabaseMetadata.UncachedGetExportedKeys(const Catalog: string;\n  const Schema: string; const Table: string): IZResultSet;\nvar\n  I: Integer;\n  KeySeq: Integer;\n  LCatalog, LTable: string;\n  TableType, Comment, Keys: String;\n  CommentList, KeyList: TStrings;\n  ColumnIndexes : Array[1..3] of integer;\nbegin\n    if Table = '' then\n      raise Exception.Create(STableIsNotSpecified); //CHANGE IT!\n\n    Result:=inherited UncachedGetExportedKeys(Catalog, Schema, Table);\n\n    GetCatalogAndNamePattern(Catalog, Schema, Table,\n      LCatalog, LTable);\n\n    KeyList := TStringList.Create;\n    CommentList := TStringList.Create;\n    try\n      with GetConnection.CreateStatement.ExecuteQuery(\n        Format('SHOW TABLE STATUS FROM %s',\n        [IC.Quote(LCatalog)])) do\n      begin\n        ColumnIndexes[1] := FindColumn('Type');\n        ColumnIndexes[2] := FindColumn('Comment');\n        ColumnIndexes[3] := FindColumn('Name');\n        while Next do\n        begin\n          TableType := GetString(ColumnIndexes[1]);\n          if (TableType <> '') and (LowerCase(TableType) = 'innodb') then\n          begin\n            Comment := GetString(ColumnIndexes[2]);\n            if Comment <> '' then\n            begin\n              PutSplitString(CommentList, Comment, ';');\n              KeySeq := 0;\n              if CommentList.Count > 4 then\n              begin\n                for I := 0 to CommentList.Count-1 do\n                begin\n                  Keys := CommentList.Strings[1];\n                  Result.MoveToInsertRow;\n                  PutSplitString(KeyList, Keys, '() /');\n\n                  Result.UpdateString(5, LCatalog);\n                  Result.UpdateNull(6);// FKTABLE_SCHEM\n                  Result.UpdateString(7, GetString(ColumnIndexes[3])); // FKTABLE_NAME\n                  Result.UpdateString(8, KeyList.Strings[0]); // PKTABLE_CAT\n\n                  Result.UpdateString(1, KeyList.Strings[2]); // PKTABLE_CAT\n                  Result.UpdateNull(2); // PKTABLE_SCHEM\n                  Result.UpdateString(3, Table); // PKTABLE_NAME\n                  Result.UpdateInt(9, KeySeq); // KEY_SEQ\n\n                  Result.UpdateInt(10, Ord(ikSetDefault)); // UPDATE_RULE\n                  Result.UpdateInt(11, Ord(ikSetDefault)); // DELETE_RULE\n                  Result.UpdateNull(12); // FK_NAME\n                  Result.UpdateNull(13); // PK_NAME\n                  Result.UpdateInt(14, Ord(ikSetDefault)); // DEFERRABILITY\n                  Inc(KeySeq);\n                  Result.InsertRow;\n                end;\n              end;\n            end;\n          end;\n        end;\n        Close;\n      end;\n    finally\n      KeyList.Free;\n      CommentList.Free;\n    end;\nend;\n\n{**\n  Gets a description of the foreign key columns in the foreign key\n  table that reference the primary key columns of the primary key\n  table (describe how one table imports another's key.) This\n  should normally return a single foreign key/primary key pair\n  (most tables only import a foreign key from a table once.)  They\n  are ordered by FKTABLE_CAT, FKTABLE_SCHEM, FKTABLE_NAME, and\n  KEY_SEQ.\n\n  <P>Each foreign key column description has the following columns:\n   <OL>\n \t<LI><B>PKTABLE_CAT</B> String => primary key table catalog (may be null)\n \t<LI><B>PKTABLE_SCHEM</B> String => primary key table schema (may be null)\n \t<LI><B>PKTABLE_NAME</B> String => primary key table name\n \t<LI><B>PKCOLUMN_NAME</B> String => primary key column name\n \t<LI><B>FKTABLE_CAT</B> String => foreign key table catalog (may be null)\n       being exported (may be null)\n \t<LI><B>FKTABLE_SCHEM</B> String => foreign key table schema (may be null)\n       being exported (may be null)\n \t<LI><B>FKTABLE_NAME</B> String => foreign key table name\n       being exported\n \t<LI><B>FKCOLUMN_NAME</B> String => foreign key column name\n       being exported\n \t<LI><B>KEY_SEQ</B> short => sequence number within foreign key\n \t<LI><B>UPDATE_RULE</B> short => What happens to\n        foreign key when primary is updated:\n       <UL>\n       <LI> importedNoAction - do not allow update of primary\n                key if it has been imported\n       <LI> importedKeyCascade - change imported key to agree\n                with primary key update\n       <LI> importedKeySetNull - change imported key to NULL if\n                its primary key has been updated\n       <LI> importedKeySetDefault - change imported key to default values\n                if its primary key has been updated\n       <LI> importedKeyRestrict - same as importedKeyNoAction\n                                  (for ODBC 2.x compatibility)\n       </UL>\n \t<LI><B>DELETE_RULE</B> short => What happens to\n       the foreign key when primary is deleted.\n       <UL>\n       <LI> importedKeyNoAction - do not allow delete of primary\n                key if it has been imported\n       <LI> importedKeyCascade - delete rows that import a deleted key\n       <LI> importedKeySetNull - change imported key to NULL if\n                its primary key has been deleted\n       <LI> importedKeyRestrict - same as importedKeyNoAction\n                                  (for ODBC 2.x compatibility)\n       <LI> importedKeySetDefault - change imported key to default if\n                its primary key has been deleted\n       </UL>\n \t<LI><B>FK_NAME</B> String => foreign key name (may be null)\n \t<LI><B>PK_NAME</B> String => primary key name (may be null)\n \t<LI><B>DEFERRABILITY</B> short => can the evaluation of foreign key\n       constraints be deferred until commit\n       <UL>\n       <LI> importedKeyInitiallyDeferred - see SQL92 for definition\n       <LI> importedKeyInitiallyImmediate - see SQL92 for definition\n       <LI> importedKeyNotDeferrable - see SQL92 for definition\n       </UL>\n   </OL>\n\n  @param primaryCatalog a catalog name; \"\" retrieves those without a\n  catalog; null means drop catalog name from the selection criteria\n  @param primarySchema a schema name; \"\" retrieves those\n  without a schema\n  @param primaryTable the table name that exports the key\n  @param foreignCatalog a catalog name; \"\" retrieves those without a\n  catalog; null means drop catalog name from the selection criteria\n  @param foreignSchema a schema name; \"\" retrieves those\n  without a schema\n  @param foreignTable the table name that imports the key\n  @return <code>ResultSet</code> - each row is a foreign key column description\n  @see #getImportedKeys\n}\nfunction TZMySQLDatabaseMetadata.UncachedGetCrossReference(const PrimaryCatalog: string;\n  const PrimarySchema: string; const PrimaryTable: string; const ForeignCatalog: string;\n  const ForeignSchema: string; const ForeignTable: string): IZResultSet;\nvar\n  I: Integer;\n  KeySeq: Integer;\n  LForeignCatalog: string;\n  TableType, Comment, Keys: string;\n  CommentList, KeyList: TStrings;\n  ColumnIndexes : Array[1..3] of integer;\nbegin\n    if PrimaryTable = '' then\n      raise Exception.Create(STableIsNotSpecified); //CHANGE IT!\n\n    Result:=inherited UncachedGetCrossReference(PrimaryCatalog, PrimarySchema, PrimaryTable,\n                                                ForeignCatalog, ForeignSchema, ForeignTable);\n\n    if ForeignCatalog = '' then\n      LForeignCatalog := FDatabase\n    else\n      LForeignCatalog := ForeignCatalog;\n\n    KeyList := TStringList.Create;\n    CommentList := TStringList.Create;\n    try\n      with GetConnection.CreateStatement.ExecuteQuery(\n        Format('SHOW TABLE STATUS FROM %s',\n        [IC.Quote(LForeignCatalog)])) do\n      begin\n        ColumnIndexes[1] := FindColumn('Type');\n        ColumnIndexes[2] := FindColumn('Comment');\n        ColumnIndexes[3] := FindColumn('Name');\n        while Next do\n        begin\n          TableType := GetString(ColumnIndexes[1]);\n          if (TableType <> '') and (LowerCase(TableType) = 'innodb') then\n          begin\n            Comment := GetString(ColumnIndexes[2]);\n            if Comment = '' then\n            begin\n              PutSplitString(CommentList, Comment, ';');\n              KeySeq := 0;\n              if CommentList.Count > 4 then\n              begin\n                for I := 0 to CommentList.Count-1 do\n                begin\n                  Keys := CommentList.Strings[1];\n                  Result.MoveToInsertRow;\n                  PutSplitString(KeyList, Keys, '() /');\n\n                  Result.UpdateString(5, LForeignCatalog);\n                  if ForeignSchema = '' then\n                    Result.UpdateNull(6) // FKTABLE_SCHEM\n                  else\n                    Result.UpdateString(6, ForeignSchema);\n                  if ForeignTable <> GetString(ColumnIndexes[3]) then\n                    Continue\n                  else\n                    Result.UpdateString(7, GetString(ColumnIndexes[3])); // FKTABLE_NAME\n\n                  Result.UpdateString(8, KeyList.Strings[0]); // PKTABLE_CAT\n\n                  Result.UpdateString(1, KeyList.Strings[2]); // PKTABLE_CAT\n                  if PrimarySchema = '' then\n                    Result.UpdateNull(2) // PKTABLE_SCHEM\n                  else\n                    Result.UpdateString(2, PrimarySchema); // PKTABLE_SCHEM\n\n                  if PrimaryTable = KeyList.Strings[3] then\n                    Continue;\n\n                  Result.UpdateString(3, PrimaryTable); // PKTABLE_NAME\n                  Result.UpdateString(4, KeyList.Strings[4]); // PKCOLUMN_NAME\n                  Result.UpdateInt(9, KeySeq); // KEY_SEQ\n                  Result.UpdateInt(10, Ord(ikSetDefault)); // UPDATE_RULE\n                  Result.UpdateInt(11, Ord(ikSetDefault)); // DELETE_RULE\n                  Result.UpdateNull(12); // FK_NAME\n                  Result.UpdateNull(13); // PK_NAME\n                  Result.UpdateInt(14, Ord(ikSetDefault)); // DEFERRABILITY\n                  Inc(KeySeq);\n                  Result.InsertRow;\n                end;\n              end;\n            end;\n          end;\n        end;\n        Close;\n      end;\n    finally\n      KeyList.Free;\n      CommentList.Free;\n    end;\nend;\n\n{**\n  Gets a description of all the standard SQL types supported by\n  this database. They are ordered by DATA_TYPE and then by how\n  closely the data type maps to the corresponding JDBC SQL type.\n\n  <P>Each type description has the following columns:\n   <OL>\n \t<LI><B>TYPE_NAME</B> String => Type name\n \t<LI><B>DATA_TYPE</B> short => SQL data type from java.sql.Types\n \t<LI><B>PRECISION</B> int => maximum precision\n \t<LI><B>LITERAL_PREFIX</B> String => prefix used to quote a literal\n       (may be null)\n \t<LI><B>LITERAL_SUFFIX</B> String => suffix used to quote a literal\n        (may be null)\n \t<LI><B>CREATE_PARAMS</B> String => parameters used in creating\n       the type (may be null)\n \t<LI><B>NULLABLE</B> short => can you use NULL for this type?\n       <UL>\n       <LI> typeNoNulls - does not allow NULL values\n       <LI> typeNullable - allows NULL values\n       <LI> typeNullableUnknown - nullability unknown\n       </UL>\n \t<LI><B>CASE_SENSITIVE</B> boolean=> is it case sensitive?\n \t<LI><B>SEARCHABLE</B> short => can you use \"WHERE\" based on this type:\n       <UL>\n       <LI> typePredNone - No support\n       <LI> typePredChar - Only supported with WHERE .. LIKE\n       <LI> typePredBasic - Supported except for WHERE .. LIKE\n       <LI> typeSearchable - Supported for all WHERE ..\n       </UL>\n \t<LI><B>UNSIGNED_ATTRIBUTE</B> boolean => is it unsigned?\n \t<LI><B>FIXED_PREC_SCALE</B> boolean => can it be a money value?\n \t<LI><B>AUTO_INCREMENT</B> boolean => can it be used for an\n       auto-increment value?\n \t<LI><B>LOCAL_TYPE_NAME</B> String => localized version of type name\n       (may be null)\n \t<LI><B>MINIMUM_SCALE</B> short => minimum scale supported\n \t<LI><B>MAXIMUM_SCALE</B> short => maximum scale supported\n \t<LI><B>SQL_DATA_TYPE</B> int => unused\n \t<LI><B>SQL_DATETIME_SUB</B> int => unused\n \t<LI><B>NUM_PREC_RADIX</B> int => usually 2 or 10\n   </OL>\n\n  @return <code>ResultSet</code> - each row is an SQL type description\n}\nfunction TZMySQLDatabaseMetadata.UncachedGetTypeInfo: IZResultSet;\nconst\n  MaxTypeCount = 33;\n  TypeNames: array[1..MaxTypeCount] of string = (\n    'BIT', 'BOOL', 'TINYINT', 'BIGINT', 'MEDIUMBLOB', 'LONG VARBINARY',\n    'LONGBLOB', 'BLOB', 'TINYBLOB', 'VARBINARY', 'BINARY',\n    'LONG VARCHAR', 'MEDIUMTEXT', 'LONGTEXT', 'TEXT', 'TINYTEXT',\n    'CHAR', 'VARCHAR', 'NUMERIC', 'DECIMAL', 'INTEGER', 'INT',\n    'MEDIUMINT', 'SMALLINT', 'DOUBLE', 'FLOAT', 'REAL', 'ENUM', 'SET',\n    'DATE', 'TIME', 'DATETIME', 'TIMESTAMP');\n  TypeCodes: array[1..MaxTypeCount] of TZSQLType = (\n    stByte, stBoolean, stShort, stLong, stBinaryStream, stBinaryStream,\n    stBinaryStream, stBinaryStream, stBinaryStream, stBytes, stBytes,\n    stString, stAsciiStream, stAsciiStream, stAsciiStream, stAsciiStream,\n    stString, stString, stBigDecimal, stBigDecimal, stInteger, stInteger,\n    stInteger, stShort, stDouble, stFloat, stFloat, stString, stString,\n    stDate, stTime, stTimestamp, stTimestamp);\n  TypePrecision: array[1..MaxTypeCount] of Integer = (\n    1, -1, 4, 16, 16777215, 16777215, MAXBUF, 65535, 255, 255, 255,\n    16777215, 16777215, 2147483647, 65535, 255, 255, 255, 17, 17, 10, 10,\n    7, 4, 17, 10, 10, 65535, 64, -1, -1, -1, -1);\nvar\n  I: Integer;\nbegin\n    Result:=inherited UncachedGetTypeInfo;\n\n    for I := 1 to MaxTypeCount do\n    begin\n      Result.MoveToInsertRow;\n\n      Result.UpdateString(1, TypeNames[I]);\n      Result.UpdateInt(2, Ord(TypeCodes[I]));\n      if TypePrecision[I] >= 0 then\n        Result.UpdateInt(3, TypePrecision[I])\n      else\n        Result.UpdateNull(3);\n      if TypeCodes[I] in [stString, stBytes, stDate, stTime,\n        stTimeStamp, stBinaryStream, stAsciiStream] then\n      begin\n        Result.UpdateString(4, '''');\n        Result.UpdateString(5, '''');\n      end\n      else\n      begin\n        Result.UpdateNull(4);\n        Result.UpdateNull(5);\n      end;\n      Result.UpdateNull(6);\n      Result.UpdateInt(7, Ord(ntNullable));\n      Result.UpdateBoolean(8, False);\n      Result.UpdateBoolean(9, False);\n      Result.UpdateBoolean(11, False);\n      Result.UpdateBoolean(12, False);\n      Result.UpdateBoolean(12, TypeNames[I] = 'INTEGER');\n      Result.UpdateNull(13);\n      Result.UpdateNull(14);\n      Result.UpdateNull(15);\n      Result.UpdateNull(16);\n      Result.UpdateNull(17);\n      Result.UpdateInt(18, 10);\n\n      Result.InsertRow;\n    end;\nend;\n\n{**\n  Gets a description of a table's indices and statistics. They are\n  ordered by NON_UNIQUE, TYPE, INDEX_NAME, and ORDINAL_POSITION.\n\n  <P>Each index column description has the following columns:\n   <OL>\n \t<LI><B>TABLE_CAT</B> String => table catalog (may be null)\n \t<LI><B>TABLE_SCHEM</B> String => table schema (may be null)\n \t<LI><B>TABLE_NAME</B> String => table name\n \t<LI><B>NON_UNIQUE</B> boolean => Can index values be non-unique?\n       false when TYPE is tableIndexStatistic\n \t<LI><B>INDEX_QUALIFIER</B> String => index catalog (may be null);\n       null when TYPE is tableIndexStatistic\n \t<LI><B>INDEX_NAME</B> String => index name; null when TYPE is\n       tableIndexStatistic\n \t<LI><B>TYPE</B> short => index type:\n       <UL>\n       <LI> tableIndexStatistic - this identifies table statistics that are\n            returned in conjuction with a table's index descriptions\n       <LI> tableIndexClustered - this is a clustered index\n       <LI> tableIndexHashed - this is a hashed index\n       <LI> tableIndexOther - this is some other style of index\n       </UL>\n \t<LI><B>ORDINAL_POSITION</B> short => column sequence number\n       within index; zero when TYPE is tableIndexStatistic\n \t<LI><B>COLUMN_NAME</B> String => column name; null when TYPE is\n       tableIndexStatistic\n \t<LI><B>ASC_OR_DESC</B> String => column sort sequence, \"A\" => ascending,\n       \"D\" => descending, may be null if sort sequence is not supported;\n       null when TYPE is tableIndexStatistic\n \t<LI><B>CARDINALITY</B> int => When TYPE is tableIndexStatistic, then\n       this is the number of rows in the table; otherwise, it is the\n       number of unique values in the index.\n \t<LI><B>PAGES</B> int => When TYPE is  tableIndexStatisic then\n       this is the number of pages used for the table, otherwise it\n       is the number of pages used for the current index.\n \t<LI><B>FILTER_CONDITION</B> String => Filter condition, if any.\n       (may be null)\n   </OL>\n\n  @param catalog a catalog name; \"\" retrieves those without a\n  catalog; null means drop catalog name from the selection criteria\n  @param schema a schema name; \"\" retrieves those without a schema\n  @param table a table name\n  @param unique when true, return only indices for unique values;\n      when false, return indices regardless of whether unique or not\n  @param approximate when true, result is allowed to reflect approximate\n      or out of data values; when false, results are requested to be\n      accurate\n  @return <code>ResultSet</code> - each row is an index column description\n}\nfunction TZMySQLDatabaseMetadata.UncachedGetIndexInfo(const Catalog: string;\n  const Schema: string; const Table: string; Unique: Boolean;\n  Approximate: Boolean): IZResultSet;\nvar\n  LCatalog, LTable: string;\n  ColumnIndexes : Array[1..7] of integer;\nbegin\n    if Table = '' then\n      raise Exception.Create(STableIsNotSpecified); //CHANGE IT!\n\n    Result:=inherited UncachedGetIndexInfo(Catalog, Schema, Table, Unique, Approximate);\n\n    GetCatalogAndNamePattern(Catalog, Schema, Table,\n      LCatalog, LTable);\n\n    with GetConnection.CreateStatement.ExecuteQuery(\n      Format('SHOW INDEX FROM %s.%s',\n      [IC.Quote(LCatalog),\n      IC.Quote(LTable)])) do\n    begin\n      ColumnIndexes[1] := FindColumn('Table');\n      ColumnIndexes[2] := FindColumn('Non_unique');\n      ColumnIndexes[3] := FindColumn('Key_name');\n      ColumnIndexes[4] := FindColumn('Seq_in_index');\n      ColumnIndexes[5] := FindColumn('Column_name');\n      ColumnIndexes[6] := FindColumn('Collation');\n      ColumnIndexes[7] := FindColumn('Cardinality');\n      while Next do\n      begin\n        Result.MoveToInsertRow;\n        Result.UpdateString(1, LCatalog);\n        Result.UpdateNull(2);\n        Result.UpdateString(3, GetString(ColumnIndexes[1]));\n        if GetInt(ColumnIndexes[2]) = 0 then\n          Result.UpdateString(4, 'true')\n        else\n          Result.UpdateString(4, 'false');\n        Result.UpdateNull(5);\n        Result.UpdateString(6, GetString(ColumnIndexes[3]));\n        Result.UpdateInt(7, Ord(tiOther));\n        Result.UpdateInt(8, GetInt(ColumnIndexes[4]));\n        Result.UpdateString(9, GetString(ColumnIndexes[5]));\n        Result.UpdateString(10, GetString(ColumnIndexes[6]));\n        Result.UpdateString(11, GetString(ColumnIndexes[7]));\n        Result.UpdateInt(12, 0);\n        Result.UpdateNull(13);\n        Result.InsertRow;\n      end;\n      Close;\n    end;\nend;\n\n{**\n  Gets a description of the stored procedures available in a\n  catalog.\n\n  <P>Only procedure descriptions matching the schema and\n  procedure name criteria are returned.  They are ordered by\n  PROCEDURE_SCHEM, and PROCEDURE_NAME.\n\n  <P>Each procedure description has the the following columns:\n   <OL>\n \t<LI><B>PROCEDURE_CAT</B> String => procedure catalog (may be null)\n \t<LI><B>PROCEDURE_SCHEM</B> String => procedure schema (may be null)\n \t<LI><B>PROCEDURE_NAME</B> String => procedure name\n   <LI> reserved for future use\n   <LI> reserved for future use\n   <LI> reserved for future use\n \t<LI><B>REMARKS</B> String => explanatory comment on the procedure\n \t<LI><B>PROCEDURE_TYPE</B> short => kind of procedure:\n       <UL>\n       <LI> procedureResultUnknown - May return a result\n       <LI> procedureNoResult - Does not return a result\n       <LI> procedureReturnsResult - Returns a result\n       </UL>\n   </OL>\n\n  @param catalog a catalog name; \"\" retrieves those without a\n  catalog; null means drop catalog name from the selection criteria\n  @param schemaPattern a schema name pattern; \"\" retrieves those\n  without a schema\n  @param procedureNamePattern a procedure name pattern\n  @return <code>ResultSet</code> - each row is a procedure description\n  @see #getSearchStringEscape\n}\nfunction TZMySQLDatabaseMetadata.UncachedGetProcedures(const Catalog: string;\n  const SchemaPattern: string; const ProcedureNamePattern: string): IZResultSet;\nvar\n  SQL: string;\n  ProcedureNameCondition, SchemaCondition: string;\nbegin\n  If Catalog = '' then\n    If SchemaPattern <> '' then\n    SchemaCondition := ConstructNameCondition(SchemaPattern,'p.db')\n    else\n    SchemaCondition := ConstructNameCondition(FDatabase,'p.db')\n  else\n    SchemaCondition := ConstructNameCondition(Catalog,'p.db');\n  ProcedureNameCondition := ConstructNameCondition(ProcedureNamePattern,'p.name');\n  If SchemaCondition <> '' then\n    SchemaCondition := ' and ' + SchemaCondition;\n  If ProcedureNameCondition <> '' then\n    ProcedureNameCondition := ' and ' + ProcedureNameCondition;\n\n  SQL := 'SELECT NULL AS PROCEDURE_CAT, p.db AS PROCEDURE_SCHEM, '+\n      'p.name AS PROCEDURE_NAME, NULL AS RESERVED1, NULL AS RESERVED2, '+\n      'NULL AS RESERVED3, p.comment AS REMARKS, '+\n      IntToStr(ProcedureReturnsResult)+' AS PROCEDURE_TYPE  from  mysql.proc p '+\n      'WHERE 1=1' + SchemaCondition + ProcedureNameCondition+\n      ' ORDER BY p.db, p.name';\n    Result := CopyToVirtualResultSet(\n    GetConnection.CreateStatement.ExecuteQuery(SQL),\n    ConstructVirtualResultSet(ProceduresColumnsDynArray));\nend;\n\n{**\n  Gets a description of a catalog's stored procedure parameters\n  and result columns.\n\n  <P>Only descriptions matching the schema, procedure and\n  parameter name criteria are returned.  They are ordered by\n  PROCEDURE_SCHEM and PROCEDURE_NAME. Within this, the return value,\n  if any, is first. Next are the parameter descriptions in call\n  order. The column descriptions follow in column number order.\n\n  <P>Each row in the <code>ResultSet</code> is a parameter description or\n  column description with the following fields:\n   <OL>\n \t<LI><B>PROCEDURE_CAT</B> String => procedure catalog (may be null)\n \t<LI><B>PROCEDURE_SCHEM</B> String => procedure schema (may be null)\n \t<LI><B>PROCEDURE_NAME</B> String => procedure name\n \t<LI><B>COLUMN_NAME</B> String => column/parameter name\n \t<LI><B>COLUMN_TYPE</B> Short => kind of column/parameter:\n       <UL>\n       <LI> procedureColumnUnknown - nobody knows\n       <LI> procedureColumnIn - IN parameter\n       <LI> procedureColumnInOut - INOUT parameter\n       <LI> procedureColumnOut - OUT parameter\n       <LI> procedureColumnReturn - procedure return value\n       <LI> procedureColumnResult - result column in <code>ResultSet</code>\n       </UL>\n   <LI><B>DATA_TYPE</B> short => SQL type from java.sql.Types\n \t<LI><B>TYPE_NAME</B> String => SQL type name, for a UDT type the\n   type name is fully qualified\n \t<LI><B>PRECISION</B> int => precision\n \t<LI><B>LENGTH</B> int => length in bytes of data\n \t<LI><B>SCALE</B> short => scale\n \t<LI><B>RADIX</B> short => radix\n \t<LI><B>NULLABLE</B> short => can it contain NULL?\n       <UL>\n       <LI> procedureNoNulls - does not allow NULL values\n       <LI> procedureNullable - allows NULL values\n       <LI> procedureNullableUnknown - nullability unknown\n       </UL>\n \t<LI><B>REMARKS</B> String => comment describing parameter/column\n   </OL>\n\n  <P><B>Note:</B> Some databases may not return the column\n  descriptions for a procedure. Additional columns beyond\n  REMARKS can be defined by the database.\n\n  @param catalog a catalog name; \"\" retrieves those without a\n  catalog; null means drop catalog name from the selection criteria\n  @param schemaPattern a schema name pattern; \"\" retrieves those\n  without a schema\n  @param procedureNamePattern a procedure name pattern\n  @param columnNamePattern a column name pattern\n  @return <code>ResultSet</code> - each row describes a stored procedure parameter or\n       column\n  @see #getSearchStringEscape\n}\nfunction TZMySQLDatabaseMetadata.UncachedGetProcedureColumns(const Catalog: string;\n  const SchemaPattern: string; const ProcedureNamePattern: string;\n  const ColumnNamePattern: string): IZResultSet;\nvar\n  SQL, TypeName, Temp: string;\n  ParamList, Params, Names, Returns: TStrings;\n  I, ColumnSize, Precision: Integer;\n  FieldType: TZSQLType;\n  ProcedureNameCondition, SchemaCondition: string;\n\n  function GetNextName(const AName: String; NameEmpty: Boolean = False): String;\n  var N: Integer;\n  begin\n    if (Names.IndexOf(AName) = -1) and not NameEmpty then\n    begin\n      Names.Add(AName);\n      Result := AName;\n    end\n    else\n      for N := 1 to MaxInt do\n        if Names.IndexOf(AName+IntToStr(N)) = -1 then\n        begin\n          Names.Add(AName+IntToStr(N));\n          Result := AName+IntToStr(N);\n          Break;\n        end;\n  end;\n\n  function DecomposeParamFromList(AList: TStrings): String;\n  var\n    J, I, N: Integer;\n    Temp: String;\n    procedure AddTempString(Const Value: String);\n    begin\n      if Temp = '' then\n        Temp := Trim(Value)\n      else\n        Temp := Temp + LineEnding+ Trim(Value);\n    end;\n\n  begin\n    J := 0;\n    Temp := '';\n    for I := 0 to AList.Count -1 do\n      if J < AList.Count then\n      begin\n        if (Pos('(', (AList[J])) > 0) and (Pos(')', (AList[J])) = 0) then\n          if ( Pos('real', LowerCase(AList[J])) > 0 ) or\n             ( Pos('float', LowerCase(AList[J])) > 0 ) or\n             ( Pos('decimal', LowerCase(AList[J])) > 0 ) or\n             ( Pos('numeric', LowerCase(AList[J])) > 0 ) or\n             ( Pos('double', LowerCase(AList[J])) > 0 ) then\n          begin\n            AddTempString(AList[j]+','+AList[j+1]);\n            Inc(j);\n          end\n          else\n            if ( Pos('set', LowerCase(AList[J])) > 0 ) and\n              ( Pos(')', LowerCase(AList[J])) = 0 ) then\n            begin\n              TypeName := AList[J];\n              for N := J+1 to AList.Count-1 do\n              begin\n                TypeName := TypeName +','+AList[N];\n                if Pos(')', AList[N]) > 0 then\n                  Break;\n              end;\n              AddTempString(TypeName);\n              J := N;\n            end\n            else\n              AddTempString(AList[j])\n        else\n          if not (AList[j] = '') then\n            AddTempString(AList[j]);\n        Inc(J);\n      end;\n    Result := Temp;\n  end;\nbegin\n  If Catalog = '' then\n    If SchemaPattern <> '' then\n    SchemaCondition := ConstructNameCondition(SchemaPattern,'p.db')\n    else\n    SchemaCondition := ConstructNameCondition(FDatabase,'p.db')\n  else\n    SchemaCondition := ConstructNameCondition(Catalog,'p.db');\n  ProcedureNameCondition := ConstructNameCondition(ProcedureNamePattern,'p.name');\n  If SchemaCondition <> '' then\n    SchemaCondition := ' and ' + SchemaCondition;\n  If ProcedureNameCondition <> '' then\n    ProcedureNameCondition := ' and ' + ProcedureNameCondition;\n\n  Result := inherited UncachedGetProcedureColumns(Catalog, SchemaPattern, ProcedureNamePattern, ColumnNamePattern);\n\n  SQL := 'SELECT p.db AS PROCEDURE_CAT, NULL AS PROCEDURE_SCHEM, '+\n      'p.name AS PROCEDURE_NAME, p.param_list AS PARAMS, p.comment AS REMARKS, '+\n    IntToStr(ProcedureReturnsResult)+' AS PROCEDURE_TYPE, p.returns AS RETURN_VALUES '+\n    ' from  mysql.proc p where 1 = 1'+SchemaCondition+ProcedureNameCondition+\n    ' ORDER BY p.db, p.name';\n\n    try\n      with GetConnection.CreateStatement.ExecuteQuery(SQL) do\n      begin\n        ParamList := TStringList.Create;\n        Params := TStringList.Create;\n        Names := TStringList.Create;\n        Returns := TStringList.Create;\n        while Next do\n        begin\n          PutSplitString(ParamList, Trim(GetString(4)), ',');\n          PutSplitString(ParamList, DecomposeParamFromList(ParamList), LineEnding);\n\n          PutSplitString(Returns, Trim(GetString(7)), ',');\n          PutSplitString(Returns, DecomposeParamFromList(Returns), LineEnding);\n\n          for I := 0 to Returns.Count-1 do\n          begin\n            Returns[i] := 'RETURNS '+Returns[i];\n            ParamList.Add(Returns[i]);\n          end;\n\n          for i := 0 to ParamList.Count -1 do\n          begin\n            PutSplitString(Params, ParamList[i], ' ');\n            if Params.Count = 2 then {no name available}\n              if Params[0] = 'RETURNS' then\n                Params.Insert(1,'')\n              else\n                if (UpperCase(Params[1]) = 'IN') or\n                    (UpperCase(Params[1]) = 'INOUT') or\n                    (UpperCase(Params[1]) = 'OUT') then\n                  Params.Insert(1,'')\n                else\n                  Params.Insert(0,'IN'); //Function in value\n\n            Result.MoveToInsertRow;\n            Result.UpdateString(1, GetString(1)); //PROCEDURE_CAT\n            Result.UpdateString(2, GetString(2)); //PROCEDURE_SCHEM\n            Result.UpdateString(3, GetString(3)); //PROCEDURE_NAME\n            ConvertMySQLColumnInfoFromString(Params[2],\n              ConSettings, TypeName, Temp,\n              FieldType, ColumnSize, Precision);\n            { process COLUMN_NAME }\n            if Params[1] = '' then\n              if Params[0] = 'RETURNS' then\n                Result.UpdateString(4, 'ReturnValue')\n              else\n                Result.UpdateString(4, GetNextName('$', True))\n            else\n              if IC.IsQuoted(Params[1]) then\n                Result.UpdateString(4, GetNextName(Copy(Params[1], 2, Length(Params[1])-2), (Length(Params[1])=2)))\n              else\n                Result.UpdateString(4, GetNextName(Params[1]));\n            { COLUMN_TYPE }\n            if UpperCase(Params[0]) = 'OUT' then\n              Result.UpdateInt(5, Ord(pctOut))\n            else\n              if UpperCase(Params[0]) = 'INOUT' then\n                Result.UpdateInt(5, Ord(pctInOut))\n              else\n                if UpperCase(Params[0]) = 'IN' then\n                  Result.UpdateInt(5, Ord(pctIn))\n                else\n                  if UpperCase(Params[0]) = 'RETURNS' then\n                    Result.UpdateInt(5, Ord(pctReturn))\n                  else\n                    Result.UpdateInt(5, Ord(pctUnknown));\n\n            { DATA_TYPE }\n            Result.UpdateInt(6, Ord(FieldType));\n            { TYPE_NAME }\n            Result.UpdateString(7, TypeName);\n            { PRECISION }\n            Result.UpdateInt(8, ColumnSize);\n            { LENGTH }\n            Result.UpdateInt(9, Precision);\n\n            Result.UpdateNull(10);\n            Result.UpdateNull(11);\n            Result.UpdateInt(12, Ord(ntNullableUnknown));\n            Result.UpdateNull(13);\n            Result.InsertRow;\n          end;\n        end;\n        Close;\n      end;\n    finally\n      FreeAndNil(Names);\n      FreeAndNil(Params);\n      FreeAndNil(ParamList);\n      FreeAndNil(Returns);\n    end;\nend;\n\n{**\n  Gets a description of a table's columns that are automatically\n  updated when any value in a row is updated.  They are\n  unordered.\n\n  <P>Each column description has the following columns:\n   <OL>\n \t<LI><B>SCOPE</B> short => is not used\n \t<LI><B>COLUMN_NAME</B> String => column name\n \t<LI><B>DATA_TYPE</B> short => SQL data type from java.sql.Types\n \t<LI><B>TYPE_NAME</B> String => Data source dependent type name\n \t<LI><B>COLUMN_SIZE</B> int => precision\n \t<LI><B>BUFFER_LENGTH</B> int => length of column value in bytes\n \t<LI><B>DECIMAL_DIGITS</B> short\t => scale\n \t<LI><B>PSEUDO_COLUMN</B> short => is this a pseudo column\n       like an Oracle ROWID\n       <UL>\n       <LI> versionColumnUnknown - may or may not be pseudo column\n       <LI> versionColumnNotPseudo - is NOT a pseudo column\n       <LI> versionColumnPseudo - is a pseudo column\n       </UL>\n   </OL>\n\n  @param catalog a catalog name; \"\" retrieves those without a\n  catalog; null means drop catalog name from the selection criteria\n  @param schema a schema name; \"\" retrieves those without a schema\n  @param table a table name\n  @return <code>ResultSet</code> - each row is a column description\n  @exception SQLException if a database access error occurs\n}\nfunction TZMySQLDatabaseMetadata.UncachedGetVersionColumns(const Catalog, Schema,\n  Table: string): IZResultSet;\nbegin\n    Result:=inherited UncachedGetVersionColumns(Catalog, Schema, Table);\n\n    Result.MoveToInsertRow;\n    Result.UpdateNull(1);\n    Result.UpdateString(2, 'ctid');\n  //  Result.UpdateInt(3, GetSQLType('tid')); //FIX IT\n    Result.UpdateString(4, 'tid');\n    Result.UpdateNull(5);\n    Result.UpdateNull(6);\n    Result.UpdateNull(7);\n    Result.UpdateInt(4, Ord(vcPseudo));\n    Result.InsertRow;\nend;\n\n{**\n  Gets the used Collation and CharacterSet of spezified Object.\n\n  @param catalog a catalog name; \"\" retrieves those without a\n  catalog; null means drop catalog name from the selection criteria\n  @param schema a schema name; \"\" and Catolog \"\" retrieves nothing\n  @param table a table name; \"\" retrieves the Schema Colloation and CharacterSet\n  @param ColumnNamePattern ColumnPattern;\"\" retrieves the\n    Table(if @param TablePattern is set) or\n    Schema(if @param TablePattern is NULL)\n      Colloation and CharacterSet\n  @return <code>ResultSet</code> - each row is a Collation, CharacterSet, ID,\n    and ByteLength per Char of speziefied Object\n}\nfunction TZMySQLDatabaseMetadata.UncachedGetCollationAndCharSet(const Catalog, SchemaPattern,\n  TableNamePattern, ColumnNamePattern: string): IZResultSet; //EgonHugeist\nvar\n  SQL, LCatalog: string;\n  ColumnNameCondition, TableNameCondition, SchemaCondition: string;\nbegin\n    if Catalog = '' then\n    begin\n      if SchemaPattern <> '' then\n        LCatalog := SchemaPattern\n      else\n        LCatalog := FDatabase;\n    end\n    else\n      LCatalog := Catalog;\n  If Catalog = '' then\n    If SchemaPattern <> '' then\n      SchemaCondition := ConstructNameCondition(SchemaPattern,'TABLE_SCHEMA')\n    else\n      SchemaCondition := ConstructNameCondition(FDatabase,'TABLE_SCHEMA')\n  else\n    SchemaCondition := ConstructNameCondition(Catalog,'TABLE_SCHEMA');\n  TableNameCondition := ConstructNameCondition(TableNamePattern,'TABLE_NAME');\n  ColumnNameCondition := ConstructNameCondition(ColumnNamePattern,'COLUMN_NAME');\n  If SchemaCondition <> '' then\n    SchemaCondition := ' and ' + SchemaCondition;\n  If TableNameCondition <> '' then\n    TableNameCondition := ' and ' + TableNameCondition;\n  If ColumnNameCondition <> '' then\n    ColumnNameCondition := ' and ' + ColumnNameCondition;\n\n  Result:=inherited UncachedGetCollationAndCharSet(Catalog, SchemaPattern, TableNamePattern, ColumnNamePattern);\n\n  if SchemaCondition <> '' then\n  begin\n    if TableNamePattern <> '' then\n    begin\n      if ColumnNamePattern <> '' then\n      begin\n        SQL := 'SELECT CLMS.COLLATION_NAME, CLMS.CHARACTER_SET_NAME, CS.MAXLEN '+\n          'FROM INFORMATION_SCHEMA.COLUMNS CLMS '+\n          'LEFT JOIN INFORMATION_SCHEMA.CHARACTER_SETS CS '+\n          'ON CS.DEFAULT_COLLATE_NAME = CLMS.COLLATION_NAME '+\n          'WHERE 1=1'+ SchemaCondition + TableNameCondition + ColumnNameCondition;\n        with GetConnection.CreateStatement.ExecuteQuery(SQL) do\n        begin\n          if Next then\n          begin\n            Result.MoveToInsertRow;\n            Result.UpdateString(1, LCatalog);   //COLLATION_CATALOG\n            Result.UpdateString(2, LCatalog);   //COLLATION_SCHEMA\n            Result.UpdateString(3, TableNamePattern); //COLLATION_TABLE\n            Result.UpdateString(4, ColumnNamePattern);//COLLATION_COLUMN\n            Result.UpdateString(5, GetString(FindColumn('COLLATION_NAME'))); //COLLATION_NAME\n            Result.UpdateString(6, GetString(FindColumn('CHARACTER_SET_NAME'))); //CHARACTER_SET_NAME\n            Result.UpdateNull(7); //CHARACTER_SET_ID\n            Result.UpdateShort(8, GetShort(FindColumn('MAXLEN'))); //CHARACTER_SET_SIZE\n            Result.InsertRow;\n          end;\n          Close;\n        end;\n      end\n      else\n      begin\n        SQL := 'SELECT TBLS.TABLE_COLLATION, CS.CHARACTER_SET_NAME, CS.MAXLEN '+\n          'FROM INFORMATION_SCHEMA.TABLES TBLS LEFT JOIN '+\n          'INFORMATION_SCHEMA.CHARACTER_SETS CS ON '+\n          'TBLS.TABLE_COLLATION = CS.DEFAULT_COLLATE_NAME '+\n          'WHERE 1=1'+ SchemaCondition + TableNameCondition;\n        with GetConnection.CreateStatement.ExecuteQuery(SQL) do\n        begin\n          if Next then\n          begin\n            Result.MoveToInsertRow;\n            Result.UpdateString(1, LCatalog);   //COLLATION_CATALOG\n            Result.UpdateString(2, LCatalog);   //COLLATION_SCHEMA\n            Result.UpdateString(3, TableNamePattern); //COLLATION_TABLE\n            Result.UpdateString(5, GetString(FindColumn('TABLE_COLLATION'))); //COLLATION_NAME\n            Result.UpdateString(6, GetString(FindColumn('CHARACTER_SET_NAME'))); //CHARACTER_SET_NAME\n            Result.UpdateNull(7); //CHARACTER_SET_ID\n            Result.UpdateShort(8, GetShort(FindColumn('MAXLEN'))); //CHARACTER_SET_SIZE\n            Result.InsertRow;\n          end;\n          Close;\n        end;\n      end;\n    end\n    else\n    begin\n      SchemaCondition := ConstructNameCondition(LCatalog, 'and SCHEMA_NAME');\n      SQL := 'SELECT S.DEFAULT_COLLATION_NAME, S.DEFAULT_CHARACTER_SET_NAME, '+\n        'CS.MAXLEN FROM INFORMATION_SCHEMA.SCHEMATA S '+\n        'LEFT JOIN INFORMATION_SCHEMA.CHARACTER_SETS CS '+\n        'ON CS.DEFAULT_COLLATE_NAME = S.DEFAULT_COLLATION_NAME '+\n        'WHERE 1=1 '+ SchemaCondition;\n      with GetConnection.CreateStatement.ExecuteQuery(SQL) do\n      begin\n        if Next then\n        begin\n          Result.MoveToInsertRow;\n          Result.UpdateString(1, LCatalog);   //COLLATION_CATALOG\n          Result.UpdateString(2, LCatalog);   //COLLATION_SCHEMA\n          Result.UpdateNull(3); //COLLATION_TABLE\n          Result.UpdateNull(4);//COLLATION_COLUMN\n          Result.UpdateString(5, GetString(FindColumn('DEFAULT_COLLATION_NAME'))); //COLLATION_NAME\n          Result.UpdateString(6, GetString(FindColumn('DEFAULT_CHARACTER_SET_NAME'))); //CHARACTER_SET_NAME\n          Result.UpdateNull(7); //CHARACTER_SET_ID\n          Result.UpdateShort(8, GetShort(FindColumn('MAXLEN'))); //CHARACTER_SET_SIZE\n          Result.InsertRow;\n        end;\n        Close;\n      end;\n    end;\n  end;\nend;\n\n{**\n  Gets the supported CharacterSets:\n  @return <code>ResultSet</code> - each row is a CharacterSetName and it's ID\n}\nfunction TZMySQLDatabaseMetadata.UncachedGetCharacterSets: IZResultSet; //EgonHugeist\nbegin\n  Result:=inherited UncachedGetCharacterSets;\n\n  with GetConnection.CreateStatement.ExecuteQuery(\n    'SELECT CHARACTER_SET_NAME '+\n    'FROM INFORMATION_SCHEMA.CHARACTER_SETS') do\n  begin\n    while Next do\n    begin\n      Result.MoveToInsertRow;\n      Result.UpdateString(1, GetString(FindColumn('CHARACTER_SET_NAME'))); //CHARACTER_SET_NAME\n      Result.UpdateNull(2); //CHARACTER_SET_ID\n      Result.InsertRow;\n    end;\n    Close;\n  end;\nend;\n\n\n\nend.\n\n\n"
  },
  {
    "path": "lib/zeosdbo/src/dbc/ZDbcMySqlResultSet.pas",
    "content": "{*********************************************************}\n{                                                         }\n{                 Zeos Database Objects                   }\n{           MySQL Database Connectivity Classes           }\n{                                                         }\n{        Originally written by Sergey Seroukhov           }\n{                                                         }\n{*********************************************************}\n\n{@********************************************************}\n{    Copyright (c) 1999-2012 Zeos Development Group       }\n{                                                         }\n{ License Agreement:                                      }\n{                                                         }\n{ This library is distributed in the hope that it will be }\n{ useful, but WITHOUT ANY WARRANTY; without even the      }\n{ implied warranty of MERCHANTABILITY or FITNESS FOR      }\n{ A PARTICULAR PURPOSE.  See the GNU Lesser General       }\n{ Public License for more details.                        }\n{                                                         }\n{ The source code of the ZEOS Libraries and packages are  }\n{ distributed under the Library GNU General Public        }\n{ License (see the file COPYING / COPYING.ZEOS)           }\n{ with the following  modification:                       }\n{ As a special exception, the copyright holders of this   }\n{ library give you permission to link this library with   }\n{ independent modules to produce an executable,           }\n{ regardless of the license terms of these independent    }\n{ modules, and to copy and distribute the resulting       }\n{ executable under terms of your choice, provided that    }\n{ you also meet, for each linked independent module,      }\n{ the terms and conditions of the license of that module. }\n{ An independent module is a module which is not derived  }\n{ from or based on this library. If you modify this       }\n{ library, you may extend this exception to your version  }\n{ of the library, but you are not obligated to do so.     }\n{ If you do not wish to do so, delete this exception      }\n{ statement from your version.                            }\n{                                                         }\n{                                                         }\n{ The project web site is located on:                     }\n{   http://zeos.firmos.at  (FORUM)                        }\n{   http://sourceforge.net/p/zeoslib/tickets/ (BUGTRACKER)}\n{   svn://svn.code.sf.net/p/zeoslib/code-0/trunk (SVN)    }\n{                                                         }\n{   http://www.sourceforge.net/projects/zeoslib.          }\n{                                                         }\n{                                                         }\n{                                 Zeos Development Group. }\n{********************************************************@}\n\nunit ZDbcMySqlResultSet;\n\ninterface\n\n{$I ZDbc.inc}\n\nuses\n  Classes, {$IFDEF MSEgui}mclasses,{$ENDIF} SysUtils, Types, Contnrs,\n  ZDbcIntfs, ZDbcResultSet, ZDbcResultSetMetadata, ZCompatibility, ZDbcCache,\n  ZDbcCachedResultSet, ZDbcGenericResolver, ZDbcMySqlStatement,\n  ZPlainMySqlDriver, ZPlainMySqlConstants;\n\ntype\n  {** Implements MySQL ResultSet Metadata. }\n  TZMySQLResultSetMetadata = class(TZAbstractResultSetMetadata)\n  public\n    function GetColumnType(Column: Integer): TZSQLType; override;\n  end;\n\n  {** Implements MySQL ResultSet. }\n  TZMySQLResultSet = class(TZAbstractResultSet)\n  private\n    FHandle: PZMySQLConnect;\n    FQueryHandle: PZMySQLResult;\n    FRowHandle: PZMySQLRow;\n    FPlainDriver: IZMySQLPlainDriver;\n    FUseResult: Boolean;\n    FIgnoreUseResult: Boolean;\n    TempStr: String;\n  protected\n    procedure Open; override;\n    function InternalGetString(ColumnIndex: Integer): RawByteString; override;\n  public\n    constructor Create(PlainDriver: IZMySQLPlainDriver; Statement: IZStatement;\n      SQL: string; Handle: PZMySQLConnect; UseResult: Boolean;\n      AffectedRows: PInteger; IgnoreUseResult: Boolean = False);\n    destructor Destroy; override;\n\n    procedure Close; override;\n\n    function IsNull(ColumnIndex: Integer): Boolean; override;\n    function GetPChar(ColumnIndex: Integer): PChar; override;\n    function GetBoolean(ColumnIndex: Integer): Boolean; override;\n    function GetByte(ColumnIndex: Integer): Byte; override;\n    function GetShort(ColumnIndex: Integer): SmallInt; override;\n    function GetInt(ColumnIndex: Integer): Integer; override;\n    function GetLong(ColumnIndex: Integer): Int64; override;\n    function GetFloat(ColumnIndex: Integer): Single; override;\n    function GetDouble(ColumnIndex: Integer): Double; override;\n    function GetBigDecimal(ColumnIndex: Integer): Extended; override;\n    function GetBytes(ColumnIndex: Integer): TByteDynArray; override;\n    function GetDate(ColumnIndex: Integer): TDateTime; override;\n    function GetTime(ColumnIndex: Integer): TDateTime; override;\n    function GetTimestamp(ColumnIndex: Integer): TDateTime; override;\n    function GetBlob(ColumnIndex: Integer): IZBlob; override;\n\n    function MoveAbsolute(Row: Integer): Boolean; override;\n    function Next: Boolean; override;\n    procedure ReleaseHandle;\n  end;\n\n  {** Implements Prepared MySQL ResultSet. }\n  TZMySQLPreparedResultSet = class(TZAbstractResultSet)\n  private\n    FHandle: PZMySQLConnect;\n    FPrepStmt: PZMySqlPrepStmt;\n    FResultMetaData : PZMySQLResult;\n    FPlainDriver: IZMySQLPlainDriver;\n    FUseResult: Boolean;\n    FColumnArray: TZMysqlColumnBuffer;\n    FBindBuffer: TZMySqlResultSetBindBuffer;\n    function bufferasint64(ColumnIndex: Integer): Int64;\n    function bufferasextended(ColumnIndex: Integer): Extended;\n\n  protected\n    function InternalGetString(ColumnIndex: Integer): RawByteString; override;\n    procedure Open; override;\n  public\n    constructor Create(PlainDriver: IZMySQLPlainDriver; Statement: IZStatement;\n      SQL: string; Handle: PZMySQLConnect; UseResult: Boolean);\n    destructor Destroy; override;\n\n    procedure Close; override;\n\n    function IsNull(ColumnIndex: Integer): Boolean; override;\n    function GetBoolean(ColumnIndex: Integer): Boolean; override;\n    function GetByte(ColumnIndex: Integer): Byte; override;\n    function GetShort(ColumnIndex: Integer): SmallInt; override;\n    function GetInt(ColumnIndex: Integer): Integer; override;\n    function GetLong(ColumnIndex: Integer): Int64; override;\n    function GetFloat(ColumnIndex: Integer): Single; override;\n    function GetDouble(ColumnIndex: Integer): Double; override;\n    function GetBigDecimal(ColumnIndex: Integer): Extended; override;\n    function GetBytes(ColumnIndex: Integer): TByteDynArray; override;\n    function GetDate(ColumnIndex: Integer): TDateTime; override;\n    function GetTime(ColumnIndex: Integer): TDateTime; override;\n    function GetTimestamp(ColumnIndex: Integer): TDateTime; override;\n    function GetAsciiStream(ColumnIndex: Integer): TStream; override;\n    function GetUnicodeStream(ColumnIndex: Integer): TStream; override;\n    function GetBinaryStream(ColumnIndex: Integer): TStream; override;\n    function GetBlob(ColumnIndex: Integer): IZBlob; override;\n\n    function MoveAbsolute(Row: Integer): Boolean; override;\n    function Next: Boolean; override;\n  end;\n\n  {** Implements a cached resolver with MySQL specific functionality. }\n  TZMySQLCachedResolver = class (TZGenericCachedResolver, IZCachedResolver)\n  private\n    FHandle: PZMySQLConnect;\n    FPlainDriver: IZMySQLPlainDriver;\n    FAutoColumnIndex: Integer;\n    FStatement: IZMysqlStatement;\n  public\n    constructor Create(PlainDriver: IZMySQLPlainDriver; Handle: PZMySQLConnect;\n      Statement: IZMysqlStatement; Metadata: IZResultSetMetadata);\n\n    function FormWhereClause(Columns: TObjectList;\n      OldRowAccessor: TZRowAccessor): string; override;\n    procedure PostUpdates(Sender: IZCachedResultSet; UpdateType: TZRowUpdateType;\n      OldRowAccessor, NewRowAccessor: TZRowAccessor); override;\n\n    // --> ms, 31/10/2005\n    function FormCalculateStatement(Columns: TObjectList): string; override;\n    // <-- ms\n    {BEGIN of PATCH [1185969]: Do tasks after posting updates. ie: Updating AutoInc fields in MySQL }\n    procedure UpdateAutoIncrementFields(Sender: IZCachedResultSet; UpdateType: TZRowUpdateType;\n      OldRowAccessor, NewRowAccessor: TZRowAccessor; Resolver: IZCachedResolver); override;\n    {END of PATCH [1185969]: Do tasks after posting updates. ie: Updating AutoInc fields in MySQL }\n  end;\n\nimplementation\n\nuses\n  Math, ZMessages, ZDbcMySqlUtils, ZMatchPattern, ZDbcMysql, ZEncoding, ZSysUtils;\n\n{ TZMySQLResultSetMetadata }\n\n{**\n  Retrieves the designated column's SQL type.\n  @param column the first column is 1, the second is 2, ...\n  @return SQL type from java.sql.Types\n}\nfunction TZMySQLResultSetMetadata.GetColumnType(Column: Integer): TZSQLType;\nbegin\n  if not Loaded then\n     LoadColumns;\n  Result := TZColumnInfo(ResultSet.ColumnsInfo[Column - 1]).ColumnType;\nend;\n\n{ TZMySQLResultSet }\n\n{**\n  Constructs this object, assignes main properties and\n  opens the record set.\n  @param PlainDriver a native MySQL plain driver.\n  @param Statement a related SQL statement object.\n  @param Handle a MySQL specific query handle.\n  @param UseResult <code>True</code> to use results,\n    <code>False</code> to store result.\n}\nconstructor TZMySQLResultSet.Create(PlainDriver: IZMySQLPlainDriver;\n  Statement: IZStatement; SQL: string; Handle: PZMySQLConnect;\n  UseResult: Boolean; AffectedRows: PInteger; IgnoreUseResult: Boolean = False);\nbegin\n  inherited Create(Statement, SQL, TZMySQLResultSetMetadata.Create(\n    Statement.GetConnection.GetMetadata, SQL, Self),\n      Statement.GetConnection.GetConSettings);\n\n  FHandle := Handle;\n  FQueryHandle := nil;\n  FRowHandle := nil;\n  FPlainDriver := PlainDriver;\n  ResultSetConcurrency := rcReadOnly;\n  FUseResult := UseResult;\n  FIgnoreUseResult := IgnoreUseResult;\n\n  Open;\n  if Assigned(AffectedRows) then\n    AffectedRows^ := LastRowNo;\nend;\n\n{**\n  Destroys this object and cleanups the memory.\n}\ndestructor TZMySQLResultSet.Destroy;\nbegin\n  inherited Destroy;\nend;\n\n{**\n  Opens this recordset.\n}\nprocedure TZMySQLResultSet.Open;\nvar\n  I: Integer;\n  FieldHandle: PZMySQLField;\nbegin\n  if ResultSetConcurrency = rcUpdatable then\n    raise EZSQLException.Create(SLiveResultSetsAreNotSupported);\n\n  if FUseResult and (not FIgnoreUseResult) then\n  begin\n    FQueryHandle := FPlainDriver.UseResult(FHandle);\n    LastRowNo := 0;\n  end\n  else\n  begin\n    FQueryHandle := FPlainDriver.StoreResult(FHandle);\n    if Assigned(FQueryHandle) then\n      LastRowNo := FPlainDriver.GetRowCount(FQueryHandle)\n    else\n      LastRowNo := 0;\n  end;\n\n  if not Assigned(FQueryHandle) then\n    raise EZSQLException.Create(SCanNotRetrieveResultSetData);\n\n  { Fills the column info. }\n  ColumnsInfo.Clear;\n  for I := 0 to FPlainDriver.GetFieldCount(FQueryHandle) - 1 do\n  begin\n    FPlainDriver.SeekField(FQueryHandle, I);\n    FieldHandle := FPlainDriver.FetchField(FQueryHandle);\n    if FieldHandle = nil then\n      Break;\n\n    ColumnsInfo.Add(GetMySQLColumnInfoFromFieldHandle(FPlainDriver,\n     FieldHandle, ConSettings, FUseResult));\n  end;\n\n  inherited Open;\nend;\n\n{**\n  Releases this <code>ResultSet</code> object's database and\n  JDBC resources immediately instead of waiting for\n  this to happen when it is automatically closed.\n\n  <P><B>Note:</B> A <code>ResultSet</code> object\n  is automatically closed by the\n  <code>Statement</code> object that generated it when\n  that <code>Statement</code> object is closed,\n  re-executed, or is used to retrieve the next result from a\n  sequence of multiple results. A <code>ResultSet</code> object\n  is also automatically closed when it is garbage collected.\n}\nprocedure TZMySQLResultSet.Close;\nbegin\n  if FQueryHandle <> nil then\n  begin\n    FPlainDriver.FreeResult(FQueryHandle);\n    while(FPlainDriver.RetrieveNextRowset(FHandle) = 0) do\n    begin\n      FQueryHandle := FPlainDriver.StoreResult(FHandle);\n      if FQueryHandle <> nil then\n      begin\n        FPlainDriver.FreeResult(FQueryHandle);\n      end;\n    end;\n  end;\n  FQueryHandle := nil;\n  FRowHandle := nil;\n  inherited Close;\nend;\n\n{**\n  Indicates if the value of the designated column in the current row\n  of this <code>ResultSet</code> object is Null.\n\n  @param columnIndex the first column is 1, the second is 2, ...\n  @return if the value is SQL <code>NULL</code>, the\n    value returned is <code>true</code>. <code>false</code> otherwise.\n}\nfunction TZMySQLResultSet.IsNull(ColumnIndex: Integer): Boolean;\nvar\n   Temp: PAnsiChar;\nbegin\n{$IFNDEF DISABLE_CHECKING}\n  CheckClosed;\n  if FRowHandle = nil then\n    raise EZSQLException.Create(SRowDataIsNotAvailable);\n{$ENDIF}\n\n  Temp := FPlainDriver.GetFieldData(FRowHandle, ColumnIndex - 1);\n  Result := (Temp = nil);\n  if not Result and (TZAbstractResultSetMetadata(Metadata).\n    GetColumnType(ColumnIndex) in [stDate, stTimestamp]) then\n  begin\n    Result := (AnsiSQLDateToDateTime(String(Temp)) = 0)\n      and (TimestampStrToDateTime(String(Temp)) = 0);\n  end;\nend;\n\n{**\n  Gets the value of the designated column in the current row\n  of this <code>ResultSet</code> object as\n  a <code>PAnsiChar</code> in the Delphi programming language.\n\n  @param columnIndex the first column is 1, the second is 2, ...\n  @return the column value; if the value is SQL <code>NULL</code>, the\n    value returned is <code>null</code>\n}\nfunction TZMySQLResultSet.GetPChar(ColumnIndex: Integer): PChar;\nbegin\n{$IFNDEF DISABLE_CHECKING}\n  CheckClosed;\n  if FRowHandle = nil then\n    raise EZSQLException.Create(SRowDataIsNotAvailable);\n{$ENDIF}\n\n  TempStr := ZDbcString(FPlainDriver.GetFieldData(FRowHandle, ColumnIndex - 1));\n  Result := PChar(TempStr);\n  LastWasNull := Result = nil;\nend;\n\n{**\n  Gets the value of the designated column in the current row\n  of this <code>ResultSet</code> object as\n  a <code>String</code>.\n\n  @param columnIndex the first column is 1, the second is 2, ...\n  @return the column value; if the value is SQL <code>NULL</code>, the\n    value returned is <code>null</code>\n}\nfunction TZMySQLResultSet.InternalGetString(ColumnIndex: Integer): RawByteString;\nvar\n  LengthPointer: PULong;\n  Length: ULong;\n  Buffer: PAnsiChar;\nbegin\n{$IFNDEF DISABLE_CHECKING}\n  CheckClosed;\n  if FRowHandle = nil then\n    raise EZSQLException.Create(SRowDataIsNotAvailable);\n{$ENDIF}\n\n  ColumnIndex := ColumnIndex - 1;\n  LengthPointer := FPlainDriver.FetchLengths(FQueryHandle);\n  if LengthPointer <> nil then\n    Length  := PULong(NativeUint(LengthPointer) + NativeUInt(ColumnIndex) * SizeOf(ULOng))^\n  else\n    Length := 0;\n  Buffer := FPlainDriver.GetFieldData(FRowHandle, ColumnIndex);\n  LastWasNull := Buffer = nil;\n  Result := '';\n  if not LastWasNull then\n  {$IFDEF WITH_RAWBYTESTRING}\n  begin\n    SetLength(Result, Length);\n    Move(Buffer^, PAnsiChar(Result)^, Length);\n  end;\n  {$ELSE}\n    SetString(Result, Buffer, Length);\n  {$ENDIF}\nend;\n\n{**\n  Gets the value of the designated column in the current row\n  of this <code>ResultSet</code> object as\n  a <code>boolean</code> in the Java programming language.\n\n  @param columnIndex the first column is 1, the second is 2, ...\n  @return the column value; if the value is SQL <code>NULL</code>, the\n    value returned is <code>false</code>\n}\nfunction TZMySQLResultSet.GetBoolean(ColumnIndex: Integer): Boolean;\nvar\n  Temp: string;\nbegin\n{$IFNDEF DISABLE_CHECKING}\n  CheckColumnConvertion(ColumnIndex, stBoolean);\n{$ENDIF}\n  Temp := UpperCase(String(InternalGetString(ColumnIndex)));\n  Result := (Temp = 'Y') or (Temp = 'YES') or (Temp = 'T') or\n    (Temp = 'TRUE') or (StrToIntDef(Temp, 0) <> 0);\nend;\n\n{**\n  Gets the value of the designated column in the current row\n  of this <code>ResultSet</code> object as\n  a <code>byte</code> in the Java programming language.\n\n  @param columnIndex the first column is 1, the second is 2, ...\n  @return the column value; if the value is SQL <code>NULL</code>, the\n    value returned is <code>0</code>\n}\nfunction TZMySQLResultSet.GetByte(ColumnIndex: Integer): Byte;\nbegin\n{$IFNDEF DISABLE_CHECKING}\n  CheckColumnConvertion(ColumnIndex, stByte);\n{$ENDIF}\n  Result := Byte(StrToIntDef(String(InternalGetString(ColumnIndex)), 0));\nend;\n\n{**\n  Gets the value of the designated column in the current row\n  of this <code>ResultSet</code> object as\n  a <code>short</code> in the Java programming language.\n\n  @param columnIndex the first column is 1, the second is 2, ...\n  @return the column value; if the value is SQL <code>NULL</code>, the\n    value returned is <code>0</code>\n}\nfunction TZMySQLResultSet.GetShort(ColumnIndex: Integer): SmallInt;\nbegin\n{$IFNDEF DISABLE_CHECKING}\n  CheckColumnConvertion(ColumnIndex, stShort);\n{$ENDIF}\n  Result := SmallInt(StrToIntDef(String(InternalGetString(ColumnIndex)), 0));\nend;\n\n{**\n  Gets the value of the designated column in the current row\n  of this <code>ResultSet</code> object as\n  an <code>int</code> in the Java programming language.\n\n  @param columnIndex the first column is 1, the second is 2, ...\n  @return the column value; if the value is SQL <code>NULL</code>, the\n    value returned is <code>0</code>\n}\nfunction TZMySQLResultSet.GetInt(ColumnIndex: Integer): Integer;\nbegin\n{$IFNDEF DISABLE_CHECKING}\n  CheckColumnConvertion(ColumnIndex, stInteger);\n{$ENDIF}\n  Result := StrToIntDef(String(InternalGetString(ColumnIndex)), 0);\nend;\n\n{**\n  Gets the value of the designated column in the current row\n  of this <code>ResultSet</code> object as\n  a <code>long</code> in the Java programming language.\n\n  @param columnIndex the first column is 1, the second is 2, ...\n  @return the column value; if the value is SQL <code>NULL</code>, the\n    value returned is <code>0</code>\n}\nfunction TZMySQLResultSet.GetLong(ColumnIndex: Integer): Int64;\nbegin\n{$IFNDEF DISABLE_CHECKING}\n  CheckColumnConvertion(ColumnIndex, stLong);\n{$ENDIF}\n  Result := StrToInt64Def(String(InternalGetString(ColumnIndex)), 0);\nend;\n\n{**\n  Gets the value of the designated column in the current row\n  of this <code>ResultSet</code> object as\n  a <code>float</code> in the Java programming language.\n\n  @param columnIndex the first column is 1, the second is 2, ...\n  @return the column value; if the value is SQL <code>NULL</code>, the\n    value returned is <code>0</code>\n}\nfunction TZMySQLResultSet.GetFloat(ColumnIndex: Integer): Single;\nbegin\n{$IFNDEF DISABLE_CHECKING}\n  CheckColumnConvertion(ColumnIndex, stFloat);\n{$ENDIF}\n  Result := SQLStrToFloatDef(InternalGetString(ColumnIndex), 0);\nend;\n\n{**\n  Gets the value of the designated column in the current row\n  of this <code>ResultSet</code> object as\n  a <code>double</code> in the Java programming language.\n\n  @param columnIndex the first column is 1, the second is 2, ...\n  @return the column value; if the value is SQL <code>NULL</code>, the\n    value returned is <code>0</code>\n}\nfunction TZMySQLResultSet.GetDouble(ColumnIndex: Integer): Double;\nbegin\n{$IFNDEF DISABLE_CHECKING}\n  CheckColumnConvertion(ColumnIndex, stDouble);\n{$ENDIF}\n  Result := SQLStrToFloatDef(InternalGetString(ColumnIndex), 0);\nend;\n\n{**\n  Gets the value of the designated column in the current row\n  of this <code>ResultSet</code> object as\n  a <code>java.sql.BigDecimal</code> in the Java programming language.\n\n  @param columnIndex the first column is 1, the second is 2, ...\n  @param scale the number of digits to the right of the decimal point\n  @return the column value; if the value is SQL <code>NULL</code>, the\n    value returned is <code>null</code>\n}\nfunction TZMySQLResultSet.GetBigDecimal(ColumnIndex: Integer): Extended;\nbegin\n{$IFNDEF DISABLE_CHECKING}\n  CheckColumnConvertion(ColumnIndex, stBigDecimal);\n{$ENDIF}\n  Result := SQLStrToFloatDef(InternalGetString(ColumnIndex), 0);\nend;\n\n{**\n  Gets the value of the designated column in the current row\n  of this <code>ResultSet</code> object as\n  a <code>byte</code> array in the Java programming language.\n  The bytes represent the raw values returned by the driver.\n\n  @param columnIndex the first column is 1, the second is 2, ...\n  @return the column value; if the value is SQL <code>NULL</code>, the\n    value returned is <code>null</code>\n}\nfunction TZMySQLResultSet.GetBytes(ColumnIndex: Integer): TByteDynArray;\nbegin\n{$IFNDEF DISABLE_CHECKING}\n  CheckColumnConvertion(ColumnIndex, stBytes);\n{$ENDIF}\n  Result := StrToBytes(InternalGetString(ColumnIndex));\nend;\n\n{**\n  Gets the value of the designated column in the current row\n  of this <code>ResultSet</code> object as\n  a <code>java.sql.Date</code> object in the Java programming language.\n\n  @param columnIndex the first column is 1, the second is 2, ...\n  @return the column value; if the value is SQL <code>NULL</code>, the\n    value returned is <code>null</code>\n}\nfunction TZMySQLResultSet.GetDate(ColumnIndex: Integer): TDateTime;\nvar\n  Value: string;\nbegin\n{$IFNDEF DISABLE_CHECKING}\n  CheckColumnConvertion(ColumnIndex, stDate);\n{$ENDIF}\n  Value := String(InternalGetString(ColumnIndex));\n\n  LastWasNull := (LastWasNull or (Copy(Value, 1, 10)='0000-00-00'));\n  if LastWasNull then\n  begin\n    Result := 0;\n    Exit;\n  end;\n\n  if IsMatch('????-??-??*', Value) then\n    Result := Trunc(AnsiSQLDateToDateTime(Value))\n  else\n    Result := Trunc(TimestampStrToDateTime(Value));\n  LastWasNull := Result = 0;\nend;\n\n{**\n  Gets the value of the designated column in the current row\n  of this <code>ResultSet</code> object as\n  a <code>java.sql.Time</code> object in the Java programming language.\n\n  @param columnIndex the first column is 1, the second is 2, ...\n  @return the column value; if the value is SQL <code>NULL</code>, the\n    value returned is <code>null</code>\n}\nfunction TZMySQLResultSet.GetTime(ColumnIndex: Integer): TDateTime;\nvar\n  Value: string;\nbegin\n{$IFNDEF DISABLE_CHECKING}\n  CheckColumnConvertion(ColumnIndex, stTime);\n{$ENDIF}\n  Value := String(InternalGetString(ColumnIndex));\n\n  if LastWasNull then\n  begin\n    Result := 0;\n    Exit;\n  end;\n\n  if IsMatch('*??:??:??*', Value) then\n    Result := Frac(AnsiSQLDateToDateTime(Value))\n  else\n    Result := Frac(TimestampStrToDateTime(Value));\nend;\n\n{**\n  Gets the value of the designated column in the current row\n  of this <code>ResultSet</code> object as\n  a <code>java.sql.Timestamp</code> object in the Java programming language.\n\n  @param columnIndex the first column is 1, the second is 2, ...\n  @return the column value; if the value is SQL <code>NULL</code>, the\n  value returned is <code>null</code>\n  @exception SQLException if a database access error occurs\n}\nfunction TZMySQLResultSet.GetTimestamp(ColumnIndex: Integer): TDateTime;\nvar\n  Temp: string;\nbegin\n{$IFNDEF DISABLE_CHECKING}\n  CheckColumnConvertion(ColumnIndex, stTimestamp);\n{$ENDIF}\n  Temp := String(GetPChar(ColumnIndex));\n\n  if LastWasNull then\n  begin\n    Result := 0;\n    Exit;\n  end;\n\n  if IsMatch('????-??-??*', Temp) or IsMatch('??:??:??*', Temp) then\n    Result := AnsiSQLDateToDateTime(Temp)\n  else\n    Result := TimestampStrToDateTime(Temp);\n  LastWasNull := Result = 0;\nend;\n\n{**\n  Returns the value of the designated column in the current row\n  of this <code>ResultSet</code> object as a <code>Blob</code> object\n  in the Java programming language.\n\n  @param ColumnIndex the first column is 1, the second is 2, ...\n  @return a <code>Blob</code> object representing the SQL <code>BLOB</code> value in\n    the specified column\n}\nfunction TZMySQLResultSet.GetBlob(ColumnIndex: Integer): IZBlob;\nvar\n  Stream: TStream;\nbegin\n{$IFNDEF DISABLE_CHECKING}\n  CheckBlobColumn(ColumnIndex);\n{$ENDIF}\n  Stream := nil;\n  try\n    if not IsNull(ColumnIndex) then\n    begin\n      case GetMetaData.GetColumnType(ColumnIndex) of\n        stAsciiStream: Stream := TStringStream.Create(GetValidatedAnsiString(InternalGetString(ColumnIndex), ConSettings, True));\n        stUnicodeStream: Stream := GetValidatedUnicodeStream(InternalGetString(ColumnIndex), ConSettings, True);\n        else\n          Stream := TStringStream.Create(InternalGetString(ColumnIndex));\n      end;\n      if not Assigned(Stream) then //improve TZTestCompMySQLBugReport.Test1045286\n        Stream := TMemoryStream.Create;\n      Result := TZAbstractBlob.CreateWithStream(Stream, GetStatement.GetConnection,\n        GetMetaData.GetColumnType(ColumnIndex) = stUnicodeStream);\n    end\n    else\n      Result := TZAbstractBlob.CreateWithStream(nil, GetStatement.GetConnection);\n  finally\n    if Assigned(Stream) then\n      Stream.Free;\n  end;\nend;\n\n{**\n  Moves the cursor to the given row number in\n  this <code>ResultSet</code> object.\n\n  <p>If the row number is positive, the cursor moves to\n  the given row number with respect to the\n  beginning of the result set.  The first row is row 1, the second\n  is row 2, and so on.\n\n  <p>If the given row number is negative, the cursor moves to\n  an absolute row position with respect to\n  the end of the result set.  For example, calling the method\n  <code>absolute(-1)</code> positions the\n  cursor on the last row; calling the method <code>absolute(-2)</code>\n  moves the cursor to the next-to-last row, and so on.\n\n  <p>An attempt to position the cursor beyond the first/last row in\n  the result set leaves the cursor before the first row or after\n  the last row.\n\n  <p><B>Note:</B> Calling <code>absolute(1)</code> is the same\n  as calling <code>first()</code>. Calling <code>absolute(-1)</code>\n  is the same as calling <code>last()</code>.\n\n  @return <code>true</code> if the cursor is on the result set;\n    <code>false</code> otherwise\n}\nfunction TZMySQLResultSet.MoveAbsolute(Row: Integer): Boolean;\nbegin\n  CheckClosed;\n\n  { Checks for maximum row. }\n  Result := False;\n  if (MaxRows > 0) and (Row > MaxRows) then\n    Exit;\n\n  if not FUseResult then\n  begin\n    { Process negative rows. }\n    if Row < 0 then\n    begin\n      Row := LastRowNo - Row + 1;\n      if Row < 0 then\n         Row := 0;\n    end;\n\n    if (Row >= 0) and (Row <= LastRowNo + 1) then\n    begin\n      RowNo := Row;\n      if (Row >= 1) and (Row <= LastRowNo) then\n      begin\n        FPlainDriver.SeekData(FQueryHandle, RowNo - 1);\n        FRowHandle := FPlainDriver.FetchRow(FQueryHandle);\n      end\n      else\n        FRowHandle := nil;\n    end;\n    Result := FRowHandle <> nil;\n  end\n  else\n    RaiseForwardOnlyException;\nend;\n\n{**\n  Moves the cursor down one row from its current position.\n  A <code>ResultSet</code> cursor is initially positioned\n  before the first row; the first call to the method\n  <code>next</code> makes the first row the current row; the\n  second call makes the second row the current row, and so on.\n\n  <P>If an input stream is open for the current row, a call\n  to the method <code>next</code> will\n  implicitly close it. A <code>ResultSet</code> object's\n  warning chain is cleared when a new row is read.\n\n  @return <code>true</code> if the new current row is valid;\n    <code>false</code> if there are no more rows\n}\nfunction TZMySQLResultSet.Next: Boolean;\nbegin\n  { Checks for maximum row. }\n  Result := False;\n  if (MaxRows > 0) and (RowNo >= MaxRows) then\n    Exit;\n  if Assigned(FQueryHandle) then\n    FRowHandle := FPlainDriver.FetchRow(FQueryHandle);\n  if FRowHandle <> nil then\n  begin\n    RowNo := RowNo + 1;\n    if LastRowNo < RowNo then\n      LastRowNo := RowNo;\n    Result := True;\n  end\n  else\n  begin\n    if RowNo <= LastRowNo then\n      RowNo := LastRowNo + 1;\n    Result := False;\n  end;\nend;\n\nprocedure TZMySQLResultSet.ReleaseHandle;\nbegin\n  if FQueryHandle <> nil then\n    FPlainDriver.FreeResult(FQueryHandle);\n  FQueryHandle := nil;\nend;\n{ TZMySQLPreparedResultSet }\n\n{**\n  Constructs this object, assignes main properties and\n  opens the record set.\n  @param PlainDriver a native MySQL plain driver.\n  @param Statement a related SQL statement object.\n  @param Handle a MySQL specific query handle.\n  @param UseResult <code>True</code> to use results,\n    <code>False</code> to store result.\n}\nconstructor TZMySQLPreparedResultSet.Create(PlainDriver: IZMySQLPlainDriver;\n  Statement: IZStatement; SQL: string; Handle: PZMySQLConnect;\n  UseResult: Boolean);\nvar\n  tempPrepStmt : IZMysqlPreparedStatement;\nbegin\n  inherited Create(Statement, SQL, TZMySQLResultSetMetadata.Create(\n    Statement.GetConnection.GetMetadata, SQL, Self),\n    Statement.GetConnection.GetConSettings);\n\n  FHandle := Handle;\n  tempPrepStmt := Statement as IZMysqlPreparedStatement;\n  FPrepStmt:= tempPrepStmt.GetStmtHandle;\n  FResultMetaData := nil;\n  FPlainDriver := PlainDriver;\n  ResultSetConcurrency := rcReadOnly;\n  FUseResult := UseResult;\n\n  Open;\nend;\n\n{**\n  Destroys this object and cleanups the memory.\n}\ndestructor TZMySQLPreparedResultSet.Destroy;\nbegin\n  inherited Destroy;\nend;\n\n{**\n  Opens this recordset.\n}\nprocedure TZMySQLPreparedResultSet.Open;\nconst one = AnsiString('1');\nvar\n  I: Integer;\n  ColumnInfo: TZColumnInfo;\n  FieldHandle: PZMySQLField;\n  FieldCount: Integer;\nbegin\n  if ResultSetConcurrency = rcUpdatable then\n    raise EZSQLException.Create(SLiveResultSetsAreNotSupported);\n\n  FieldCount := FPlainDriver.GetPreparedFieldCount(FPrepStmt);\n  if FieldCount = 0 then\n    raise EZSQLException.Create(SCanNotRetrieveResultSetData);\n\n  FResultMetaData := FPlainDriver.GetPreparedMetaData(FPrepStmt);\n  if not Assigned(FResultMetaData) then\n    raise EZSQLException.Create(SCanNotRetrieveResultSetData);\n\n  if FUseResult then\n    LastRowNo := 0\n  else\n  begin\n    FPlainDriver.StmtAttrSet(FPrepStmt,STMT_ATTR_UPDATE_MAX_LENGTH,PAnsiChar(one));\n    if (FPlainDriver.StorePreparedResult(FPrepStmt)=0) then\n      LastRowNo := FPlainDriver.GetPreparedNumRows(FPrepStmt)\n    else\n      LastRowNo := 0;\n  end;\n\n    { Initialize Bind Array and Column Array }\n  FBindBuffer := TZMySqlResultSetBindBuffer.Create(FPlainDriver,FieldCount,FColumnArray);\n\n  { Fills the column info. }\n  ColumnsInfo.Clear;\n  for I := 0 to FPlainDriver.GetFieldCount(FResultMetaData) - 1 do\n  begin\n    FPlainDriver.SeekField(FResultMetaData, I);\n    FieldHandle := FPlainDriver.FetchField(FResultMetaData);\n    if FieldHandle = nil then\n      Break;\n\n    ColumnInfo := GetMySQLColumnInfoFromFieldHandle(FPlainDriver,\n     FieldHandle, GetStatement.GetConnection.GetConSettings, FUseResult);\n\n    ColumnsInfo.Add(ColumnInfo);\n\n    FBindBuffer.AddColumn(FPlainDriver, FieldHandle);\n  end;\n  FPlainDriver.FreeResult(FResultMetaData);\n  FResultMetaData := nil;\n\n  if (FPlainDriver.BindResult(FPrepStmt,FBindBuffer.GetBufferAddress)<>0) then\n    raise EZSQLException.Create(SFailedToBindResults);\n\n  inherited Open;\nend;\n\n{**\n  Releases this <code>ResultSet</code> object's database and\n  JDBC resources immediately instead of waiting for\n  this to happen when it is automatically closed.\n\n  <P><B>Note:</B> A <code>ResultSet</code> object\n  is automatically closed by the\n  <code>Statement</code> object that generated it when\n  that <code>Statement</code> object is closed,\n  re-executed, or is used to retrieve the next result from a\n  sequence of multiple results. A <code>ResultSet</code> object\n  is also automatically closed when it is garbage collected.\n}\nprocedure TZMySQLPreparedResultSet.Close;\nbegin\n  if Assigned(FResultMetaData) then\n    FPlainDriver.FreeResult(FResultMetaData);\n  FResultMetaData := nil;\n  if Assigned(FBindBuffer) then\n    FreeAndNil(FBindBuffer);\n  if Assigned(FPrepStmt) then\n    begin\n      FPlainDriver.FreePreparedResult(FPrepStmt);\n      while(FPlainDriver.GetPreparedNextResult(FPrepStmt) = 0) do\n        FPlainDriver.FreePreparedResult(FPrepStmt);\n    end;\n  inherited Close;\n\nend;\n\n{**\n  Indicates if the value of the designated column in the current row\n  of this <code>ResultSet</code> object is Null.\n\n  @param columnIndex the first column is 1, the second is 2, ...\n  @return if the value is SQL <code>NULL</code>, the\n    value returned is <code>true</code>. <code>false</code> otherwise.\n}\nfunction TZMySQLPreparedResultSet.IsNull(ColumnIndex: Integer): Boolean;\nbegin\n{$IFNDEF DISABLE_CHECKING}\n  CheckClosed;\n{$ENDIF}\n\n  Result := FColumnArray[ColumnIndex-1].is_null =1;\nend;\n\n{**\n  Gets the value of the designated column in the current row\n  of this <code>ResultSet</code> object as\n  a <code>String</code> in the Java programming language.\n\n  @param columnIndex the first column is 1, the second is 2, ...\n  @return the column value; if the value is SQL <code>NULL</code>, the\n    value returned is <code>null</code>\n}\nfunction TZMySQLPreparedResultSet.InternalGetString(ColumnIndex: Integer): RawByteString;\nbegin\n{$IFNDEF DISABLE_CHECKING}\n  CheckClosed;\n{$ENDIF}\n  Result := PAnsiChar(FColumnArray[ColumnIndex - 1].buffer);\n  LastWasNull := FColumnArray[ColumnIndex-1].is_null =1;\nend;\n\n{**\n  Gets the value of the designated column in the current row\n  of this <code>ResultSet</code> object as\n  a <code>boolean</code> in the Java programming language.\n\n  @param columnIndex the first column is 1, the second is 2, ...\n  @return the column value; if the value is SQL <code>NULL</code>, the\n    value returned is <code>false</code>\n}\nfunction TZMySQLPreparedResultSet.GetBoolean(ColumnIndex: Integer): Boolean;\nvar\n  Temp: string;\nbegin\n{$IFNDEF DISABLE_CHECKING}\n  CheckColumnConvertion(ColumnIndex, stBoolean);\n{$ENDIF}\n   Temp := UpperCase(String(InternalGetString(ColumnIndex)));\n  Result := (Temp = 'Y') or (Temp = 'YES') or (Temp = 'T') or\n    (Temp = 'TRUE') or (StrToIntDef(Temp, 0) <> 0);\nend;\n\n{**\n  Gets the value of the designated column in the current row\n  of this <code>ResultSet</code> object as\n  a <code>byte</code> in the Java programming language.\n\n  @param columnIndex the first column is 1, the second is 2, ...\n  @return the column value; if the value is SQL <code>NULL</code>, the\n    value returned is <code>0</code>\n}\nfunction TZMySQLPreparedResultSet.GetByte(ColumnIndex: Integer): Byte;\nbegin\n{$IFNDEF DISABLE_CHECKING}\n  CheckColumnConvertion(ColumnIndex, stByte);\n{$ENDIF}\n  Result := Byte(bufferasInt64(ColumnIndex));\n  LastWasNull := FColumnArray[ColumnIndex-1].is_null =1;\nend;\n\n{**\n  Gets the value of the designated column in the current row\n  of this <code>ResultSet</code> object as\n  a <code>short</code> in the Java programming language.\n\n  @param columnIndex the first column is 1, the second is 2, ...\n  @return the column value; if the value is SQL <code>NULL</code>, the\n    value returned is <code>0</code>\n}\nfunction TZMySQLPreparedResultSet.GetShort(ColumnIndex: Integer): SmallInt;\nBegin\n{$IFNDEF DISABLE_CHECKING}\n  CheckColumnConvertion(ColumnIndex, stShort);\n{$ENDIF}\n Result := Integer(bufferasInt64(ColumnIndex));\n LastWasNull := FColumnArray[ColumnIndex-1].is_null =1;\nend;\n\n{**\n  Gets the value of the designated column in the current row\n  of this <code>ResultSet</code> object as\n  an <code>int</code> in the Java programming language.\n\n  @param columnIndex the first column is 1, the second is 2, ...\n  @return the column value; if the value is SQL <code>NULL</code>, the\n    value returned is <code>0</code>\n}\nfunction TZMySQLPreparedResultSet.GetInt(ColumnIndex: Integer): Integer;\nbegin\n{$IFNDEF DISABLE_CHECKING}\n  CheckColumnConvertion(ColumnIndex, stInteger);\n{$ENDIF}\n  Result := bufferasInt64(ColumnIndex);\n  LastWasNull := FColumnArray[ColumnIndex-1].is_null =1;\nend;\n\n{**\n  Gets the value of the designated column in the current row\n  of this <code>ResultSet</code> object as\n  a <code>long</code> in the Java programming language.\n\n  @param columnIndex the first column is 1, the second is 2, ...\n  @return the column value; if the value is SQL <code>NULL</code>, the\n    value returned is <code>0</code>\n}\nfunction TZMySQLPreparedResultSet.GetLong(ColumnIndex: Integer): Int64;\nBegin\n{$IFNDEF DISABLE_CHECKING}\n  CheckColumnConvertion(ColumnIndex, stLong);\n{$ENDIF}\n  Result := bufferasInt64(ColumnIndex);\n  LastWasNull := FColumnArray[ColumnIndex-1].is_null =1;\nend;\n\n{**\n  Gets the value of the designated column in the current row\n  of this <code>ResultSet</code> object as\n  a <code>float</code> in the Java programming language.\n\n  @param columnIndex the first column is 1, the second is 2, ...\n  @return the column value; if the value is SQL <code>NULL</code>, the\n    value returned is <code>0</code>\n}\nfunction TZMySQLPreparedResultSet.GetFloat(ColumnIndex: Integer): Single;\nbegin\n{$IFNDEF DISABLE_CHECKING}\n  CheckColumnConvertion(ColumnIndex, stFloat);\n{$ENDIF}\n  Result := BufferAsExtended(ColumnIndex);\n  LastWasNull := FColumnArray[ColumnIndex-1].is_null =1;\nend;\n\n{**\n  Gets the value of the designated column in the current row\n  of this <code>ResultSet</code> object as\n  a <code>double</code> in the Java programming language.\n\n  @param columnIndex the first column is 1, the second is 2, ...\n  @return the column value; if the value is SQL <code>NULL</code>, the\n    value returned is <code>0</code>\n}\nfunction TZMySQLPreparedResultSet.GetDouble(ColumnIndex: Integer): Double;\nbegin\n{$IFNDEF DISABLE_CHECKING}\n  CheckColumnConvertion(ColumnIndex, stDouble);\n{$ENDIF}\n  Result := BufferAsExtended(ColumnIndex);\n  LastWasNull := FColumnArray[ColumnIndex-1].is_null =1;\nend;\n\n{**\n  Gets the value of the designated column in the current row\n  of this <code>ResultSet</code> object as\n  a <code>java.sql.BigDecimal</code> in the Java programming language.\n\n  @param columnIndex the first column is 1, the second is 2, ...\n  @param scale the number of digits to the right of the decimal point\n  @return the column value; if the value is SQL <code>NULL</code>, the\n    value returned is <code>null</code>\n}\nfunction TZMySQLPreparedResultSet.GetBigDecimal(ColumnIndex: Integer): Extended;\nbegin\n{$IFNDEF DISABLE_CHECKING}\n  CheckColumnConvertion(ColumnIndex, stBigDecimal);\n{$ENDIF}\n  Result := BufferAsExtended(ColumnIndex);\n  LastWasNull := FColumnArray[ColumnIndex-1].is_null =1;\nend;\n\n{**\n  Gets the value of the designated column in the current row\n  of this <code>ResultSet</code> object as\n  a <code>byte</code> array in the Java programming language.\n  The bytes represent the raw values returned by the driver.\n\n  @param columnIndex the first column is 1, the second is 2, ...\n  @return the column value; if the value is SQL <code>NULL</code>, the\n    value returned is <code>null</code>\n}\nfunction TZMySQLPreparedResultSet.GetBytes(ColumnIndex: Integer): TByteDynArray;\nbegin\n{$IFNDEF DISABLE_CHECKING}\n  CheckColumnConvertion(ColumnIndex, stBytes);\n{$ENDIF}\n  Result := StrToBytes(InternalGetString(ColumnIndex));\n  LastWasNull := FColumnArray[ColumnIndex-1].is_null =1;\nend;\n\n{**\n  Gets the value of the designated column in the current row\n  of this <code>ResultSet</code> object as\n  a <code>java.sql.Date</code> object in the Java programming language.\n\n  @param columnIndex the first column is 1, the second is 2, ...\n  @return the column value; if the value is SQL <code>NULL</code>, the\n    value returned is <code>null</code>\n}\nfunction TZMySQLPreparedResultSet.GetDate(ColumnIndex: Integer): TDateTime;\nbegin\n{$IFNDEF DISABLE_CHECKING}\n  CheckColumnConvertion(ColumnIndex, stDate);\n{$ENDIF}\n  if not sysUtils.TryEncodeDate(PMYSQL_TIME(FColumnArray[ColumnIndex - 1].buffer)^.Year,\n                                PMYSQL_TIME(FColumnArray[ColumnIndex - 1].buffer)^.Month,\n                                PMYSQL_TIME(FColumnArray[ColumnIndex - 1].buffer)^.Day,\n                                Result) then\n            Result := encodeDate(1900, 1, 1);\n  LastWasNull := FColumnArray[ColumnIndex-1].is_null =1;\nend;\n\n{**\n  Gets the value of the designated column in the current row\n  of this <code>ResultSet</code> object as\n  a <code>java.sql.Time</code> object in the Java programming language.\n\n  @param columnIndex the first column is 1, the second is 2, ...\n  @return the column value; if the value is SQL <code>NULL</code>, the\n    value returned is <code>null</code>\n}\nfunction TZMySQLPreparedResultSet.GetTime(ColumnIndex: Integer): TDateTime;\nbegin\n{$IFNDEF DISABLE_CHECKING}\n  CheckColumnConvertion(ColumnIndex, stTime);\n{$ENDIF}\n  if not sysUtils.TryEncodeTime(PMYSQL_TIME(FColumnArray[ColumnIndex - 1].buffer)^.Hour,\n                                PMYSQL_TIME(FColumnArray[ColumnIndex - 1].buffer)^.Minute,\n                                PMYSQL_TIME(FColumnArray[ColumnIndex - 1].buffer)^.Second,\n                                0,\n                                Result) then\n      Result :=  encodeTime(0,0,0,0);\n  LastWasNull := FColumnArray[ColumnIndex-1].is_null =1;\nend;\n\n{**\n  Gets the value of the designated column in the current row\n  of this <code>ResultSet</code> object as\n  a <code>java.sql.Timestamp</code> object in the Java programming language.\n\n  @param columnIndex the first column is 1, the second is 2, ...\n  @return the column value; if the value is SQL <code>NULL</code>, the\n  value returned is <code>null</code>\n  @exception SQLException if a database access error occurs\n}\nfunction TZMySQLPreparedResultSet.GetTimestamp(ColumnIndex: Integer): TDateTime;\nbegin\n{$IFNDEF DISABLE_CHECKING}\n  CheckColumnConvertion(ColumnIndex, stTimestamp);\n{$ENDIF}\n  Result := GetDate(ColumnIndex) + GetTime(ColumnIndex);\n  LastWasNull := FColumnArray[ColumnIndex-1].is_null =1;\nend;\n\n{**\n  Gets the value of the designated column in the current row\n  of this <code>ResultSet</code> object as\n  a stream of ASCII characters. The value can then be read in chunks from the\n  stream. This method is particularly\n  suitable for retrieving large <char>LONGVARCHAR</char> values.\n  The JDBC driver will\n  do any necessary conversion from the database format into ASCII.\n\n  <P><B>Note:</B> All the data in the returned stream must be\n  read prior to getting the value of any other column. The next\n  call to a <code>getXXX</code> method implicitly closes the stream.  Also, a\n  stream may return <code>0</code> when the method\n  <code>InputStream.available</code>\n  is called whether there is data available or not.\n\n  @param columnIndex the first column is 1, the second is 2, ...\n  @return a Java input stream that delivers the database column value\n    as a stream of one-byte ASCII characters; if the value is SQL\n    <code>NULL</code>, the value returned is <code>null</code>\n}\nfunction TZMySQLPreparedResultSet.GetAsciiStream(ColumnIndex: Integer): TStream;\nbegin\n{$IFNDEF DISABLE_CHECKING}\n  CheckColumnConvertion(ColumnIndex, stAsciiStream);\n{$ENDIF}\n  Result := TStringStream.Create(InternalGetString(ColumnIndex));\n  LastWasNull := FColumnArray[ColumnIndex-1].is_null =1;\nend;\n\n{**\n  Gets the value of a column in the current row as a stream of\n  Gets the value of the designated column in the current row\n  of this <code>ResultSet</code> object as\n  as a stream of Unicode characters.\n  The value can then be read in chunks from the\n  stream. This method is particularly\n  suitable for retrieving large<code>LONGVARCHAR</code>values.  The JDBC driver will\n  do any necessary conversion from the database format into Unicode.\n  The byte format of the Unicode stream must be Java UTF-8,\n  as specified in the Java virtual machine specification.\n\n  <P><B>Note:</B> All the data in the returned stream must be\n  read prior to getting the value of any other column. The next\n  call to a <code>getXXX</code> method implicitly closes the stream.  Also, a\n  stream may return <code>0</code> when the method\n  <code>InputStream.available</code>\n  is called whether there is data available or not.\n\n  @param columnIndex the first column is 1, the second is 2, ...\n  @return a Java input stream that delivers the database column value\n    as a stream in Java UTF-8 byte format; if the value is SQL\n    <code>NULL</code>, the value returned is <code>null</code>\n}\nfunction TZMySQLPreparedResultSet.GetUnicodeStream(ColumnIndex: Integer): TStream;\nvar\n  WS: ZWideString;\nbegin\n{$IFNDEF DISABLE_CHECKING}\n  CheckColumnConvertion(ColumnIndex, stUnicodeStream);\n{$ENDIF}\n  WS := ZDbcUnicodeString(InternalGetString(ColumnIndex));\n  Result := TMemoryStream.Create;\n  Result.Write(PWideChar(WS)^, Length(WS) *2);\n  Result.Position := 0;\n  LastWasNull := FColumnArray[ColumnIndex-1].is_null =1;\nend;\n\n{**\n  Gets the value of a column in the current row as a stream of\n  Gets the value of the designated column in the current row\n  of this <code>ResultSet</code> object as a binary stream of\n  uninterpreted bytes. The value can then be read in chunks from the\n  stream. This method is particularly\n  suitable for retrieving large <code>LONGVARBINARY</code> values.\n\n  <P><B>Note:</B> All the data in the returned stream must be\n  read prior to getting the value of any other column. The next\n  call to a <code>getXXX</code> method implicitly closes the stream.  Also, a\n  stream may return <code>0</code> when the method\n  <code>InputStream.available</code>\n  is called whether there is data available or not.\n\n  @param columnIndex the first column is 1, the second is 2, ...\n  @return a Java input stream that delivers the database column value\n    as a stream of uninterpreted bytes;\n    if the value is SQL <code>NULL</code>, the value returned is <code>null</code>\n}\nfunction TZMySQLPreparedResultSet.GetBinaryStream(ColumnIndex: Integer): TStream;\nbegin\n{$IFNDEF DISABLE_CHECKING}\n  CheckColumnConvertion(ColumnIndex, stBinaryStream);\n{$ENDIF}\n  Result := TMemoryStream.Create;\n  Result.Write(FColumnArray[ColumnIndex - 1].buffer[0], FColumnArray[ColumnIndex - 1].length);\n  Result.Position := 0;\n  LastWasNull := FColumnArray[ColumnIndex-1].is_null =1;\nend;\n\n{**\n  Returns the value of the designated column in the current row\n  of this <code>ResultSet</code> object as a <code>Blob</code> object\n  in the Java programming language.\n\n  @param ColumnIndex the first column is 1, the second is 2, ...\n  @return a <code>Blob</code> object representing the SQL <code>BLOB</code> value in\n    the specified column\n}\nfunction TZMySQLPreparedResultSet.GetBlob(ColumnIndex: Integer): IZBlob;\nvar\n  Stream: TStream;\nbegin\n  Result := nil;\n{$IFNDEF DISABLE_CHECKING}\n  CheckBlobColumn(ColumnIndex);\n{$ENDIF}\n\n  LastWasNull := IsNull(ColumnIndex);\n  if LastWasNull then\n      Exit;\n\n  Stream := nil;\n  try\n    if not LastWasNull then\n    begin\n      case GetMetadata.GetColumnType(ColumnIndex) of\n        stBinaryStream: Stream := GetBinaryStream(ColumnIndex);\n        stUnicodeStream: Stream := GetUnicodeStream(ColumnIndex);\n      else\n        Stream := TStringStream.Create(GetValidatedAnsiString(InternalGetString(ColumnIndex), ConSettings, True));\n      end;\n      Result := TZAbstractBlob.CreateWithStream(Stream, GetStatement.GetConnection,\n        GetMetadata.GetColumnType(ColumnIndex) = stUnicodeStream)\n    end\n    else\n      Result := TZAbstractBlob.CreateWithStream(nil, GetStatement.GetConnection);\n  finally\n    if Assigned(Stream) then\n      Stream.Free;\n  end;\nend;\n\nfunction TZMySQLPreparedResultSet.bufferasint64(ColumnIndex: Integer): Int64;\nbegin\n  //http://dev.mysql.com/doc/refman/5.1/de/numeric-types.html\n  if FBindBuffer.GetBufferIsSigned(ColumnIndex) then\n    Case FBindBuffer.GetBufferType(ColumnIndex) of\n      FIELD_TYPE_DECIMAL:   Result := 0;\n      FIELD_TYPE_TINY:      Result := PByte(FColumnArray[ColumnIndex-1].buffer)^;\n      FIELD_TYPE_SHORT:     Result := PWord(FColumnArray[ColumnIndex-1].buffer)^;\n      FIELD_TYPE_LONG:      Result := PCardinal(FColumnArray[ColumnIndex-1].buffer)^;\n      FIELD_TYPE_FLOAT:     Result := 0;\n      FIELD_TYPE_DOUBLE:    Result := 0;\n      FIELD_TYPE_NULL:      Result := 0;\n      FIELD_TYPE_TIMESTAMP: Result := 0;\n      FIELD_TYPE_LONGLONG:  Result := PULongLong(FColumnArray[ColumnIndex-1].buffer)^;\n      FIELD_TYPE_INT24:     Result := PCardinal(FColumnArray[ColumnIndex-1].buffer)^;\n      (*FIELD_TYPE_DATE      = 10,\n      FIELD_TYPE_TIME      = 11,\n      FIELD_TYPE_DATETIME  = 12,*)\n      FIELD_TYPE_YEAR:      Result := PWord(FColumnArray[ColumnIndex-1].buffer)^;\n      (*FIELD_TYPE_NEWDATE   = 14,\n      FIELD_TYPE_VARCHAR   = 15, //<--ADDED by fduenas 20-06-2006\n      FIELD_TYPE_BIT: ;\n      FIELD_TYPE_NEWDECIMAL = 246, //<--ADDED by fduenas 20-06-2006\n      FIELD_TYPE_ENUM      = 247,\n      FIELD_TYPE_SET       = 248,\n      FIELD_TYPE_TINY_BLOB,\n      FIELD_TYPE_MEDIUM_BLOB,\n      FIELD_TYPE_LONG_BLOB,\n      FIELD_TYPE_BLOB:      Result := 0;\n      FIELD_TYPE_VAR_STRING = 253,\n      FIELD_TYPE_STRING:    = 254,\n      FIELD_TYPE_GEOMETRY:  = 255*)\n      else Result := 0;\n    end\n  else\n    Case FBindBuffer.GetBufferType(ColumnIndex) of\n      FIELD_TYPE_DECIMAL:   Result := 0;\n      FIELD_TYPE_TINY:      Result := PShortInt(FColumnArray[ColumnIndex-1].buffer)^;\n      FIELD_TYPE_SHORT:     Result := PSmallInt(FColumnArray[ColumnIndex-1].buffer)^;\n      FIELD_TYPE_LONG:      Result := PInteger(FColumnArray[ColumnIndex-1].buffer)^;\n      FIELD_TYPE_FLOAT:     Result := 0;\n      FIELD_TYPE_DOUBLE:    Result := 0;\n      FIELD_TYPE_NULL:      Result := 0;\n      FIELD_TYPE_TIMESTAMP: Result := 0;\n      FIELD_TYPE_LONGLONG:  Result := PInt64(FColumnArray[ColumnIndex-1].buffer)^;\n      FIELD_TYPE_INT24:     Result := PInteger(FColumnArray[ColumnIndex-1].buffer)^;\n      (*FIELD_TYPE_DATE      = 10,\n      FIELD_TYPE_TIME      = 11,\n      FIELD_TYPE_DATETIME  = 12, *)\n      FIELD_TYPE_YEAR:      Result := PSmallInt(FColumnArray[ColumnIndex-1].buffer)^;\n      (*FIELD_TYPE_NEWDATE   = 14,\n      FIELD_TYPE_VARCHAR   = 15, //<--ADDED by fduenas 20-06-2006\n      FIELD_TYPE_BIT: ;\n      FIELD_TYPE_NEWDECIMAL = 246, //<--ADDED by fduenas 20-06-2006\n      FIELD_TYPE_ENUM      = 247,\n      FIELD_TYPE_SET       = 248,\n      FIELD_TYPE_TINY_BLOB,\n      FIELD_TYPE_MEDIUM_BLOB,\n      FIELD_TYPE_LONG_BLOB,\n      FIELD_TYPE_BLOB:      Result := 0;\n      FIELD_TYPE_VAR_STRING = 253,\n      FIELD_TYPE_STRING:    = 254,\n      FIELD_TYPE_GEOMETRY:  = 255*)\n      else Result := 0;\n    end;\nend;\n\nfunction TZMySQLPreparedResultSet.bufferasextended(ColumnIndex: Integer): Extended;\nbegin\n   Case FBindBuffer.GetBufferType(ColumnIndex) of\n     FIELD_TYPE_FLOAT: Result := psingle(FColumnArray[ColumnIndex-1].buffer)^;\n     FIELD_TYPE_DOUBLE: Result := pdouble(FColumnArray[ColumnIndex-1].buffer)^;\n   else\n      Result := SQLStrToFloatDef(InternalGetString(ColumnIndex), 0);\n   End\nend;\n\n{**\n  Moves the cursor to the given row number in\n  this <code>ResultSet</code> object.\n\n  <p>If the row number is positive, the cursor moves to\n  the given row number with respect to the\n  beginning of the result set.  The first row is row 1, the second\n  is row 2, and so on.\n\n  <p>If the given row number is negative, the cursor moves to\n  an absolute row position with respect to\n  the end of the result set.  For example, calling the method\n  <code>absolute(-1)</code> positions the\n  cursor on the last row; calling the method <code>absolute(-2)</code>\n  moves the cursor to the next-to-last row, and so on.\n\n  <p>An attempt to position the cursor beyond the first/last row in\n  the result set leaves the cursor before the first row or after\n  the last row.\n\n  <p><B>Note:</B> Calling <code>absolute(1)</code> is the same\n  as calling <code>first()</code>. Calling <code>absolute(-1)</code>\n  is the same as calling <code>last()</code>.\n\n  @return <code>true</code> if the cursor is on the result set;\n    <code>false</code> otherwise\n}\nfunction TZMySQLPreparedResultSet.MoveAbsolute(Row: Integer): Boolean;\nbegin\n  CheckClosed;\n\n  { Checks for maximum row. }\n  Result := False;\n  if (MaxRows > 0) and (Row > MaxRows) then\n    Exit;\n\n  if not FUseResult then\n  begin\n    { Process negative rows. }\n    if Row < 0 then\n    begin\n      Row := LastRowNo - Row + 1;\n      if Row < 0 then\n         Row := 0;\n    end;\n\n    if (Row >= 0) and (Row <= LastRowNo + 1) then\n    begin\n      RowNo := Row;\n      if (Row >= 1) and (Row <= LastRowNo) then\n      begin\n        FPlainDriver.SeekPreparedData(FPrepStmt, RowNo - 1);\n        Result := (FPlainDriver.FetchBoundResults(FPrepStmt) =0);\n      end;\n    end;\n  end\n  else\n    RaiseForwardOnlyException;\nend;\n\n{**\n  Moves the cursor down one row from its current position.\n  A <code>ResultSet</code> cursor is initially positioned\n  before the first row; the first call to the method\n  <code>next</code> makes the first row the current row; the\n  second call makes the second row the current row, and so on.\n\n  <P>If an input stream is open for the current row, a call\n  to the method <code>next</code> will\n  implicitly close it. A <code>ResultSet</code> object's\n  warning chain is cleared when a new row is read.\n\n  @return <code>true</code> if the new current row is valid;\n    <code>false</code> if there are no more rows\n}\nfunction TZMySQLPreparedResultSet.Next: Boolean;\nbegin\n  { Checks for maximum row. }\n  Result := False;\n  if (MaxRows > 0) and (RowNo >= MaxRows) then\n    Exit;\n\n  if FPlainDriver.FetchBoundResults(FPrepStmt) in [0, MYSQL_DATA_TRUNCATED] then\n  begin\n    RowNo := RowNo + 1;\n    if LastRowNo < RowNo then\n      LastRowNo := RowNo;\n    Result := True;\n  end\n  else\n  begin\n    if RowNo <= LastRowNo then\n      RowNo := LastRowNo + 1;\n    Result := False;\n  end;\nend;\n\n{ TZMySQLCachedResolver }\n\n{**\n  Creates a MySQL specific cached resolver object.\n  @param PlainDriver a native MySQL plain driver.\n  @param Handle a MySQL specific query handle.\n  @param Statement a related SQL statement object.\n  @param Metadata a resultset metadata reference.\n}\nconstructor TZMySQLCachedResolver.Create(PlainDriver: IZMySQLPlainDriver;\n  Handle: PZMySQLConnect; Statement: IZMysqlStatement; Metadata: IZResultSetMetadata);\nvar\n  I: Integer;\nbegin\n  inherited Create(Statement, Metadata);\n  FPlainDriver := PlainDriver;\n  FHandle := Handle;\n  FStatement := Statement as IZMysqlStatement;\n\n  { Defines an index of autoincrement field. }\n  FAutoColumnIndex := 0;\n  for I := 1 to Metadata.GetColumnCount do\n  begin\n    if Metadata.IsAutoIncrement(I) and\n      (Metadata.GetColumnType(I) in [stByte, stShort, stInteger, stLong]) then\n    begin\n      FAutoColumnIndex := I;\n      Break;\n    end;\n  end;\nend;\n\n{**\n  Forms a where clause for UPDATE or DELETE DML statements.\n  @param Columns a collection of key columns.\n  @param OldRowAccessor an accessor object to old column values.\n}\nfunction TZMySQLCachedResolver.FormWhereClause(Columns: TObjectList;\n  OldRowAccessor: TZRowAccessor): string;\nvar\n  I, N: Integer;\n  Current: TZResolverParameter;\nbegin\n  Result := '';\n  N := Columns.Count - WhereColumns.Count;\n\n  for I := 0 to WhereColumns.Count - 1 do\n  begin\n    Current := TZResolverParameter(WhereColumns[I]);\n    if Result <> '' then\n      Result := Result + ' AND ';\n\n    Result := Result + IdentifierConvertor.Quote(Current.ColumnName);\n    if OldRowAccessor.IsNull(Current.ColumnIndex) then\n    begin\n      if not (Metadata.IsNullable(Current.ColumnIndex) = ntNullable) then\n        case OldRowAccessor.GetColumnType(Current.ColumnIndex) of\n          stDate:\n            if I > 0 then\n            begin\n              Current := TZResolverParameter(WhereColumns[I-1]);\n              Result := Result+ '=''0000-00-00'' OR '+Result + ' IS NULL';\n              Columns.Add(TZResolverParameter.Create(Current.ColumnIndex,\n              Current.ColumnName, Current.ColumnType, Current.NewValue, ''));\n            end;\n          stTime:\n            if I > 0 then\n            begin\n              Current := TZResolverParameter(WhereColumns[I-1]);\n              Result := Result+ '=''00:00:00'' OR '+Result + ' IS NULL';\n              Columns.Add(TZResolverParameter.Create(Current.ColumnIndex,\n              Current.ColumnName, Current.ColumnType, Current.NewValue, ''));\n            end;\n          stTimeStamp:\n            if I > 0 then\n            begin\n              Current := TZResolverParameter(WhereColumns[I-1]);\n              Result := Result+ '=''0000-00-00 00:00:00'' OR '+Result + ' IS NULL';\n              Columns.Add(TZResolverParameter.Create(Current.ColumnIndex,\n              Current.ColumnName, Current.ColumnType, Current.NewValue, ''));\n            end;\n          else\n            Result := Result + ' IS NULL';\n        end\n      else\n        Result := Result + ' IS NULL ';\n      Columns.Delete(N);\n    end\n    else\n    begin\n      Result := Result + '=?';\n      Inc(N);\n    end;\n  end;\n\n  if Result <> '' then\n    Result := ' WHERE ' + Result;\nend;\n{**\n  Posts updates to database.\n  @param Sender a cached result set object.\n  @param UpdateType a type of updates.\n  @param OldRowAccessor an accessor object to old column values.\n  @param NewRowAccessor an accessor object to new column values.\n}\nprocedure TZMySQLCachedResolver.PostUpdates(Sender: IZCachedResultSet;\n  UpdateType: TZRowUpdateType; OldRowAccessor, NewRowAccessor: TZRowAccessor);\nbegin\n  inherited PostUpdates(Sender, UpdateType, OldRowAccessor, NewRowAccessor);\n  if (UpdateType = utInserted) then\n  begin\n   UpdateAutoIncrementFields(Sender, UpdateType, OldRowAccessor, NewRowAccessor, Self);\n  end;\nend;\n\n{**\n Do Tasks after Post updates to database.\n  @param Sender a cached result set object.\n  @param UpdateType a type of updates.\n  @param OldRowAccessor an accessor object to old column values.\n  @param NewRowAccessor an accessor object to new column values.\n}\nprocedure TZMySQLCachedResolver.UpdateAutoIncrementFields(\n  Sender: IZCachedResultSet; UpdateType: TZRowUpdateType; OldRowAccessor,\n  NewRowAccessor: TZRowAccessor; Resolver: IZCachedResolver);\nvar\n  Plaindriver : IZMysqlPlainDriver;\nbegin\n  inherited UpdateAutoIncrementFields(Sender, UpdateType, OldRowAccessor, NewRowAccessor, Resolver);\n  if not ((FAutoColumnIndex > 0) and\n          (OldRowAccessor.IsNull(FAutoColumnIndex) or (OldRowAccessor.GetValue(FAutoColumnIndex).VInteger=0))) then\n     exit;\n  Plaindriver := (Connection as IZMysqlConnection).GetPlainDriver;\n  // THIS IS WRONG, I KNOW (MDAEMS) : which function to use depends on the insert statement, not the resultset statement\n  {  IF FStatement.IsPreparedStatement  then\n    NewRowAccessor.SetLong(FAutoColumnIndex, PlainDriver.GetPreparedInsertID(FStatement.GetStmtHandle))\n  else}\n    NewRowAccessor.SetLong(FAutoColumnIndex, PlainDriver.GetLastInsertID(FHandle));\n\nend;\n\n{**\n  Forms a where clause for SELECT statements to calculate default values.\n  @param Columns a collection of key columns.\n  @param OldRowAccessor an accessor object to old column values.\n}\nfunction TZMySQLCachedResolver.FormCalculateStatement(\n  Columns: TObjectList): string;\nvar\n  I: Integer;\n  Current: TZResolverParameter;\nbegin\n  Result := '';\n  if Columns.Count = 0 then\n     Exit;\n\n  for I := 0 to Columns.Count - 1 do\n  begin\n    Current := TZResolverParameter(Columns[I]);\n    if Result <> '' then\n      Result := Result + ',';\n    if Current.DefaultValue <> '' then\n      Result := Result + Current.DefaultValue\n    else\n      Result := Result + 'NULL';\n  end;\n  Result := 'SELECT ' + Result;\nend;\n\nend.\n"
  },
  {
    "path": "lib/zeosdbo/src/dbc/ZDbcMySqlStatement.pas",
    "content": "{*********************************************************}\n{                                                         }\n{                 Zeos Database Objects                   }\n{           MySQL Database Connectivity Classes           }\n{                                                         }\n{        Originally written by Sergey Seroukhov           }\n{                                                         }\n{*********************************************************}\n\n{@********************************************************}\n{    Copyright (c) 1999-2012 Zeos Development Group       }\n{                                                         }\n{ License Agreement:                                      }\n{                                                         }\n{ This library is distributed in the hope that it will be }\n{ useful, but WITHOUT ANY WARRANTY; without even the      }\n{ implied warranty of MERCHANTABILITY or FITNESS FOR      }\n{ A PARTICULAR PURPOSE.  See the GNU Lesser General       }\n{ Public License for more details.                        }\n{                                                         }\n{ The source code of the ZEOS Libraries and packages are  }\n{ distributed under the Library GNU General Public        }\n{ License (see the file COPYING / COPYING.ZEOS)           }\n{ with the following  modification:                       }\n{ As a special exception, the copyright holders of this   }\n{ library give you permission to link this library with   }\n{ independent modules to produce an executable,           }\n{ regardless of the license terms of these independent    }\n{ modules, and to copy and distribute the resulting       }\n{ executable under terms of your choice, provided that    }\n{ you also meet, for each linked independent module,      }\n{ the terms and conditions of the license of that module. }\n{ An independent module is a module which is not derived  }\n{ from or based on this library. If you modify this       }\n{ library, you may extend this exception to your version  }\n{ of the library, but you are not obligated to do so.     }\n{ If you do not wish to do so, delete this exception      }\n{ statement from your version.                            }\n{                                                         }\n{                                                         }\n{ The project web site is located on:                     }\n{   http://zeos.firmos.at  (FORUM)                        }\n{   http://sourceforge.net/p/zeoslib/tickets/ (BUGTRACKER)}\n{   svn://svn.code.sf.net/p/zeoslib/code-0/trunk (SVN)    }\n{                                                         }\n{   http://www.sourceforge.net/projects/zeoslib.          }\n{                                                         }\n{                                                         }\n{                                 Zeos Development Group. }\n{********************************************************@}\n\nunit ZDbcMySqlStatement;\n\ninterface\n\n{$I ZDbc.inc}\n\nuses\n  Classes, {$IFDEF MSEgui}mclasses,{$ENDIF} SysUtils,\n  ZClasses, ZDbcIntfs, ZDbcStatement, ZDbcMySql, ZVariant, ZPlainMySqlDriver,\n  ZPlainMySqlConstants, ZCompatibility, ZDbcLogging;\n\ntype\n\n  {** Represents a MYSQL specific connection interface. }\n  IZMySQLStatement = interface (IZStatement)\n    ['{A05DB91F-1E40-46C7-BF2E-25D74978AC83}']\n\n    function IsUseResult: Boolean;\n    function IsPreparedStatement: Boolean;\n    function GetStmtHandle: PZMySqlPrepStmt;\n  end;\n\n  {** Represents a MYSQL prepared Statement specific connection interface. }\n  IZMySQLPreparedStatement = interface (IZMySQLStatement)\n    ['{A05DB91F-1E40-46C7-BF2E-25D74978AC83}']\n  end;\n\n  {** Implements Generic MySQL Statement. }\n  TZMySQLStatement = class(TZAbstractStatement, IZMySQLStatement)\n  private\n    FHandle: PZMySQLConnect;\n    FPlainDriver: IZMySQLPlainDriver;\n    FUseResult: Boolean;\n\n    function CreateResultSet(const SQL: string): IZResultSet;\n    function GetStmtHandle : PZMySqlPrepStmt;\n  public\n    constructor Create(PlainDriver: IZMySQLPlainDriver;\n      Connection: IZConnection; Info: TStrings; Handle: PZMySQLConnect);\n\n    function ExecuteQuery(const SQL: RawByteString): IZResultSet; override;\n    function ExecuteUpdate(const SQL: RawByteString): Integer; override;\n    function Execute(const SQL: RawByteString): Boolean; override;\n\n    function GetMoreResults: Boolean; override;\n\n    function IsUseResult: Boolean;\n    function IsPreparedStatement: Boolean;\n  end;\n\n  {** Implements Prepared SQL Statement. }\n  TZMySQLEmulatedPreparedStatement = class(TZEmulatedPreparedStatement)\n  private\n    FHandle: PZMySQLConnect;\n    FPlainDriver: IZMySQLPlainDriver;\n    FUseDefaults: Boolean;\n  protected\n    function CreateExecStatement: IZStatement; override;\n    function PrepareAnsiSQLParam(ParamIndex: Integer): RawByteString; override;\n  public\n    constructor Create(PlainDriver: IZMySQLPlainDriver;\n      Connection: IZConnection; const SQL: string; Info: TStrings;\n      Handle: PZMySQLConnect);\n  end;\n\n  TZMysqlColumnBuffer = Array of PDOBindRecord2;\n  { TZMySQLBindBuffer }\n  {** Encapsulates a MySQL bind buffer. }\n  TZMySQLAbstractBindBuffer = class(TZAbstractObject)\n  protected\n    FAddedColumnCount : Integer;\n    FBindOffsets: MYSQL_BINDOFFSETS;\n    FBindArray: Array of byte;\n    FPColumnArray: ^TZMysqlColumnBuffer;\n  public\n    constructor Create(PlainDriver:IZMysqlPlainDriver;\n      const BindCount : Integer; var ColumnArray:TZMysqlColumnBuffer);\n    function GetColumnArray : TZMysqlColumnBuffer;\n    function GetBufferAddress : Pointer;\n    function GetBufferType(ColumnIndex: Integer): TMysqlFieldTypes;\n    function GetBufferIsSigned(ColumnIndex: Integer): Boolean;\n  end;\n\n  {** Encapsulates a MySQL bind buffer for ResultSets. }\n  TZMySQLResultSetBindBuffer = class(TZMySQLAbstractBindBuffer)\n  public\n    procedure AddColumn(PlainDriver: IZMysqlPlainDriver; const FieldHandle: PZMySQLField);\n  end;\n\n  {** Encapsulates a MySQL bind buffer for updates. }\n  TZMySQLParamBindBuffer = class(TZMySQLAbstractBindBuffer)\n  public\n    procedure AddColumn(buffertype: TMysqlFieldTypes; const field_length: integer;\n      const largeblobparameter: boolean);\n  end;\n  {** Implements Prepared SQL Statement. }\n\n  { TZMySQLPreparedStatement }\n\n  TZMySQLPreparedStatement = class(TZAbstractPreparedStatement,IZMySQLPreparedStatement)\n  private\n    FHandle: PZMySQLConnect;\n    FMySQLConnection: IZMySQLConnection;\n    FStmtHandle: PZMySqlPrepStmt;\n    FPlainDriver: IZMySQLPlainDriver;\n    FUseResult: Boolean;\n    FUseDefaults: Boolean;\n\n    FColumnArray: TZMysqlColumnBuffer;\n    FParamBindBuffer: TZMySQLParamBindBuffer;\n\n    function CreateResultSet(const SQL: string): IZResultSet;\n\n    function getFieldType (testVariant: TZVariant): TMysqlFieldTypes;\n  protected\n    function GetStmtHandle : PZMySqlPrepStmt;\n    procedure BindInParameters; override;\n    procedure UnPrepareInParameters; override;\n  public\n    property StmtHandle: PZMySqlPrepStmt read GetStmtHandle;\n    constructor Create(PlainDriver: IZMysqlPlainDriver; Connection: IZConnection;\n      const SQL: string; Info: TStrings);\n    procedure Prepare; override;\n    destructor Destroy; override;\n\n    function ExecuteQueryPrepared: IZResultSet; override;\n    function ExecuteUpdatePrepared: Integer; override;\n    function ExecutePrepared: Boolean; override;\n\n    function IsUseResult: Boolean;\n    function IsPreparedStatement: Boolean;\n  end;\n\n  {** Implements callable Postgresql Statement. }\n  TZMySQLCallableStatement = class(TZAbstractCallableStatement, IZMySQLStatement,\n    IZParamNamedCallableStatement)\n  private\n    FPlainDriver: IZMysqlPlainDriver;\n    FHandle: PZMySQLConnect;\n    FQueryHandle: PZMySQLResult;\n    FUseResult: Boolean;\n    FParamNames: array [0..1024] of String;\n    FParamTypeNames: array [0..1024] of String;\n    FUseDefaults: Boolean;\n    function GetCallSQL: RawByteString;\n    function GetOutParamSQL: String;\n    function GetSelectFunctionSQL: RawByteString;\n    function PrepareAnsiSQLParam(ParamIndex: Integer): RawByteString;\n    function GetStmtHandle : PZMySqlPrepStmt;\n  protected\n    procedure ClearResultSets; override;\n    procedure BindInParameters; override;\n    function CreateResultSet(const SQL: string): IZResultSet;\n    procedure FetchOutParams(ResultSet: IZResultSet);\n    procedure RegisterParamTypeAndName(const ParameterIndex:integer;\n      const ParamTypeName, ParamName: String; Const ColumnSize, Precision: Integer);\n  public\n    constructor Create(PlainDriver: IZMySQLPlainDriver;\n      Connection: IZConnection; const SQL: string; Info: TStrings;\n      Handle: PZMySQLConnect);\n\n    function Execute(const SQL: RawByteString): Boolean; override;\n    function ExecuteQuery(const SQL: RawByteString): IZResultSet; override;\n    function ExecuteUpdate(const SQL: RawByteString): Integer; override;\n\n    function ExecuteQueryPrepared: IZResultSet; override;\n    function ExecuteUpdatePrepared: Integer; override;\n\n    function IsUseResult: Boolean;\n    function IsPreparedStatement: Boolean;\n\n    function HasMoreResultSets: Boolean; override;\n    function GetFirstResultSet: IZResultSet; override;\n    function GetPreviousResultSet: IZResultSet; override;\n    function GetNextResultSet: IZResultSet; override;\n    function GetLastResultSet: IZResultSet; override;\n    function BOR: Boolean; override;\n    function EOR: Boolean; override;\n    function GetResultSetByIndex(const Index: Integer): IZResultSet; override;\n    function GetResultSetCount: Integer; override;\n  end;\n\nimplementation\n\nuses\n  Types, Math, DateUtils, ZDbcMySqlUtils, ZDbcMySqlResultSet, ZSysUtils,\n  ZDbcResultSetMetadata, ZMessages, ZDbcCachedResultSet, ZDbcUtils, ZEncoding,\n  ZDbcResultSet{$IFDEF WITH_UNITANSISTRINGS}, AnsiStrings{$ENDIF};\n\n{ TZMySQLStatement }\n\n{**\n  Constructs this object and assignes the main properties.\n  @param PlainDriver a native MySQL plain driver.\n  @param Connection a database connection object.\n  @param Handle a connection handle pointer.\n  @param Info a statement parameters.\n}\nconstructor TZMySQLStatement.Create(PlainDriver: IZMySQLPlainDriver;\n  Connection: IZConnection; Info: TStrings; Handle: PZMySQLConnect);\nbegin\n  inherited Create(Connection, Info);\n  FHandle := Handle;\n  FPlainDriver := PlainDriver;\n  ResultSetType := rtScrollInsensitive;\n\n  FUseResult := StrToBoolEx(DefineStatementParameter(Self, 'useresult', 'false'));\nend;\n\n{**\n  Checks is use result should be used in result sets.\n  @return <code>True</code> use result in result sets,\n    <code>False</code> store result in result sets.\n}\nfunction TZMySQLStatement.IsUseResult: Boolean;\nbegin\n  Result := FUseResult;\nend;\n\n{**\n  Checks if this is a prepared mysql statement.\n  @return <code>False</code> This is not a prepared mysql statement.\n}\nfunction TZMySQLStatement.IsPreparedStatement: Boolean;\nbegin\n  Result := False;\nend;\n\nfunction TZMySQLStatement.GetStmtHandle: PZMySqlPrepStmt;\nbegin\n  Result := nil;\nend;\n\n{**\n  Creates a result set based on the current settings.\n  @return a created result set object.\n}\nfunction TZMySQLStatement.CreateResultSet(const SQL: string): IZResultSet;\nvar\n  CachedResolver: TZMySQLCachedResolver;\n  NativeResultSet: TZMySQLResultSet;\n  CachedResultSet: TZCachedResultSet;\nbegin\n  NativeResultSet := TZMySQLResultSet.Create(FPlainDriver, Self, SQL, FHandle,\n    FUseResult, nil);\n  NativeResultSet.SetConcurrency(rcReadOnly);\n  if (GetResultSetConcurrency <> rcReadOnly) or (FUseResult\n    and (GetResultSetType <> rtForwardOnly)) then\n  begin\n    CachedResolver := TZMySQLCachedResolver.Create(FPlainDriver, FHandle, Self,\n      NativeResultSet.GetMetaData);\n    CachedResultSet := TZCachedResultSet.Create(NativeResultSet, SQL,\n      CachedResolver, ConSettings);\n    CachedResultSet.SetConcurrency(GetResultSetConcurrency);\n    Result := CachedResultSet;\n  end\n  else\n    Result := NativeResultSet;\nend;\n\n\n{**\n  Executes an SQL statement that returns a single <code>ResultSet</code> object.\n  @param sql typically this is a static SQL <code>SELECT</code> statement\n  @return a <code>ResultSet</code> object that contains the data produced by the\n    given query; never <code>null</code>\n}\nfunction TZMySQLStatement.ExecuteQuery(const SQL: RawByteString): IZResultSet;\nbegin\n  ASQL := SQL;\n  Result := nil;\n  if FPlainDriver.ExecQuery(FHandle, PAnsiChar(ASQL)) = 0 then\n  begin\n    DriverManager.LogMessage(lcExecute, FPlainDriver.GetProtocol, LogSQL);\n    if not FPlainDriver.ResultSetExists(FHandle) then\n      raise EZSQLException.Create(SCanNotOpenResultSet);\n    Result := CreateResultSet(LogSQL);\n  end\n  else\n    CheckMySQLError(FPlainDriver, FHandle, lcExecute, LogSQL);\nend;\n\n{**\n  Executes an SQL <code>INSERT</code>, <code>UPDATE</code> or\n  <code>DELETE</code> statement. In addition,\n  SQL statements that return nothing, such as SQL DDL statements,\n  can be executed.\n\n  @param sql an SQL <code>INSERT</code>, <code>UPDATE</code> or\n    <code>DELETE</code> statement or an SQL statement that returns nothing\n  @return either the row count for <code>INSERT</code>, <code>UPDATE</code>\n    or <code>DELETE</code> statements, or 0 for SQL statements that return nothing\n}\nfunction TZMySQLStatement.ExecuteUpdate(const SQL: RawByteString): Integer;\nvar\n  QueryHandle: PZMySQLResult;\n  HasResultset : Boolean;\nbegin\n  ASQL := SQL;\n  Result := -1;\n  if FPlainDriver.ExecQuery(FHandle, PAnsichar(ASQL)) = 0 then\n  begin\n    DriverManager.LogMessage(lcExecute, FPlainDriver.GetProtocol, LogSQL);\n    HasResultSet := FPlainDriver.ResultSetExists(FHandle);\n    { Process queries with result sets }\n    if HasResultSet then\n      begin\n        QueryHandle := FPlainDriver.StoreResult(FHandle);\n        if QueryHandle <> nil then\n        begin\n          Result := FPlainDriver.GetRowCount(QueryHandle);\n          FPlainDriver.FreeResult(QueryHandle);\n        end\n        else\n          Result := FPlainDriver.GetAffectedRows(FHandle);\n        while(FPlainDriver.RetrieveNextRowset(FHandle) = 0) do\n          begin\n           QueryHandle := FPlainDriver.StoreResult(FHandle);\n           if QueryHandle <> nil then\n             begin\n               FPlainDriver.FreeResult(QueryHandle);\n             end;\n           end;\n      end\n  { Process regular query }\n    else\n      Result := FPlainDriver.GetAffectedRows(FHandle);\n  end\n  else\n    CheckMySQLError(FPlainDriver, FHandle, lcExecute, LogSQL);\n  LastUpdateCount := Result;\nend;\n\n{**\n  Executes an SQL statement that may return multiple results.\n  Under some (uncommon) situations a single SQL statement may return\n  multiple result sets and/or update counts.  Normally you can ignore\n  this unless you are (1) executing a stored procedure that you know may\n  return multiple results or (2) you are dynamically executing an\n  unknown SQL string.  The  methods <code>execute</code>,\n  <code>getMoreResults</code>, <code>getResultSet</code>,\n  and <code>getUpdateCount</code> let you navigate through multiple results.\n\n  The <code>execute</code> method executes an SQL statement and indicates the\n  form of the first result.  You can then use the methods\n  <code>getResultSet</code> or <code>getUpdateCount</code>\n  to retrieve the result, and <code>getMoreResults</code> to\n  move to any subsequent result(s).\n\n  @param sql any SQL statement\n  @return <code>true</code> if the next result is a <code>ResultSet</code> object;\n  <code>false</code> if it is an update count or there are no more results\n}\nfunction TZMySQLStatement.Execute(const SQL: RawByteString): Boolean;\nvar\n  HasResultset : Boolean;\nbegin\n  ASQL := SQL;\n  Result := False;\n  if FPlainDriver.ExecQuery(FHandle, PAnsiChar(ASQL)) = 0 then\n  begin\n    DriverManager.LogMessage(lcExecute, FPlainDriver.GetProtocol, LogSQL);\n    HasResultSet := FPlainDriver.ResultSetExists(FHandle);\n    { Process queries with result sets }\n    if HasResultSet then\n    begin\n      Result := True;\n      LastResultSet := CreateResultSet(LogSQL);\n    end\n    { Processes regular query. }\n    else\n    begin\n      Result := False;\n      LastUpdateCount := FPlainDriver.GetAffectedRows(FHandle);\n    end;\n  end\n  else\n    CheckMySQLError(FPlainDriver, FHandle, lcExecute, LogSQL);\nend;\n\n{**\n  Moves to a <code>Statement</code> object's next result.  It returns\n  <code>true</code> if this result is a <code>ResultSet</code> object.\n  This method also implicitly closes any current <code>ResultSet</code>\n  object obtained with the method <code>getResultSet</code>.\n\n  <P>There are no more results when the following is true:\n  <PRE>\n        <code>(!getMoreResults() && (getUpdateCount() == -1)</code>\n  </PRE>\n\n @return <code>true</code> if the next result is a <code>ResultSet</code> object;\n   <code>false</code> if it is an update count or there are no more results\n @see #execute\n}\nfunction TZMySQLStatement.GetMoreResults: Boolean;\nvar\n  AStatus: integer;\nbegin\n  Result := inherited GetMoreResults;\n  if FPlainDriver.GetClientVersion >= 40100 then\n  begin\n    AStatus := FPlainDriver.RetrieveNextRowset(FHandle);\n    if AStatus > 0 then\n      CheckMySQLError(FPlainDriver, FHandle, lcExecute, SSQL)\n    else\n      Result := (AStatus = 0);\n\n    if LastResultSet <> nil then\n      LastResultSet.Close;\n    LastResultSet := nil;\n    LastUpdateCount := -1;\n    if FPlainDriver.ResultSetExists(FHandle) then\n      LastResultSet := CreateResultSet(SSQL)\n    else\n      LastUpdateCount := FPlainDriver.GetAffectedRows(FHandle);\n  end;\nend;\n\n{ TZMySQLEmulatedPreparedStatement }\n\n{**\n  Constructs this object and assignes the main properties.\n  @param PlainDriver a native MySQL Plain driver.\n  @param Connection a database connection object.\n  @param Info a statement parameters.\n  @param Handle a connection handle pointer.\n}\nconstructor TZMySQLEmulatedPreparedStatement.Create(PlainDriver: IZMySQLPlainDriver;\n  Connection: IZConnection; const SQL: string; Info: TStrings; Handle: PZMySQLConnect);\nbegin\n  inherited Create(Connection, SQL, Info);\n  FHandle := Handle;\n  FPlainDriver := PlainDriver;\n  ResultSetType := rtScrollInsensitive;\n  FUseDefaults := StrToBoolEx(DefineStatementParameter(Self, 'defaults', 'true'));\nend;\n\n{**\n  Creates a temporary statement which executes queries.\n  @param Info a statement parameters.\n  @return a created statement object.\n}\nfunction TZMySQLEmulatedPreparedStatement.CreateExecStatement: IZStatement;\nbegin\n  Result := TZMySQLStatement.Create(FPlainDriver, Connection, Info,FHandle);\nend;\n\n{**\n  Prepares an SQL parameter for the query.\n  @param ParameterIndex the first parameter is 1, the second is 2, ...\n  @return a string representation of the parameter.\n}\nfunction TZMySQLEmulatedPreparedStatement.PrepareAnsiSQLParam(ParamIndex: Integer): RawByteString;\nvar\n  Value: TZVariant;\n  TempBytes: TByteDynArray;\n  TempBlob: IZBlob;\n  AYear, AMonth, ADay, AHour, AMinute, ASecond, AMilliSecond: Word;\nbegin\n  TempBytes := nil;\n  if InParamCount <= ParamIndex then\n    raise EZSQLException.Create(SInvalidInputParameterCount);\n\n  Value := InParamValues[ParamIndex];\n  if DefVarManager.IsNull(Value) then\n    if FUseDefaults and (InParamDefaultValues[ParamIndex] <> '') then\n      Result := ConSettings^.ConvFuncs.ZStringToRaw(InParamDefaultValues[ParamIndex],\n        ConSettings^.CTRL_CP, ConSettings^.ClientCodePage^.CP)\n    else\n      Result := 'NULL'\n  else\n  begin\n    case InParamTypes[ParamIndex] of\n      stBoolean:\n        if SoftVarManager.GetAsBoolean(Value) then\n           Result := '''Y'''\n        else\n           Result := '''N''';\n      stByte, stShort, stInteger, stLong, stBigDecimal, stFloat, stDouble:\n        Result := RawByteString(SoftVarManager.GetAsString(Value));\n      stBytes:\n        begin\n          TempBytes := SoftVarManager.GetAsBytes(Value);\n          Result := GetSQLHexAnsiString(PAnsiChar(TempBytes), Length(TempBytes));\n        end;\n      stString:\n        Result := FPlainDriver.EscapeString(FHandle, ZPlainString(SoftVarManager.GetAsString(Value)), ConSettings, True);\n      stUnicodeString:\n        Result := FPlainDriver.EscapeString(FHandle, ZPlainString(SoftVarManager.GetAsUnicodeString(Value)), ConSettings, True);\n      stDate:\n        begin\n          DecodeDateTime(SoftVarManager.GetAsDateTime(Value),\n            AYear, AMonth, ADay, AHour, AMinute, ASecond, AMilliSecond);\n          Result := RawByteString('''' + Format('%0.4d-%0.2d-%0.2d',\n            [AYear, AMonth, ADay]) + '''');\n        end;\n      stTime:\n        begin\n          DecodeDateTime(SoftVarManager.GetAsDateTime(Value),\n            AYear, AMonth, ADay, AHour, AMinute, ASecond, AMilliSecond);\n          Result := RawByteString('''' + Format('%0.2d:%0.2d:%0.2d',\n            [AHour, AMinute, ASecond]) + '''');\n        end;\n      stTimestamp:\n        begin\n          DecodeDateTime(SoftVarManager.GetAsDateTime(Value),\n            AYear, AMonth, ADay, AHour, AMinute, ASecond, AMilliSecond);\n          Result := RawByteString('''' + Format('%0.4d-%0.2d-%0.2d %0.2d:%0.2d:%0.2d',\n            [AYear, AMonth, ADay, AHour, AMinute, ASecond]) + '''');\n        end;\n      stAsciiStream, stUnicodeStream, stBinaryStream:\n        begin\n          TempBlob := DefVarManager.GetAsInterface(Value) as IZBlob;\n          if not TempBlob.IsEmpty then\n          begin\n            case InParamTypes[ParamIndex] of\n              stBinaryStream:\n                Result := GetSQLHexAnsiString(PAnsichar(TempBlob.GetBuffer), TempBlob.Length);\n              else\n                Result := FPlainDriver.EscapeString(FHandle,\n                  GetValidatedAnsiStringFromBuffer(TempBlob.GetBuffer,\n                    TempBlob.Length, TempBlob.WasDecoded, ConSettings),\n                    ConSettings, True);\n            end;\n          end\n          else\n            Result := 'NULL';\n        end;\n    end;\n  end;\nend;\n\n{ TZMySQLPreparedStatement }\n\n{**\n  Constructs this object and assignes the main properties.\n  @param PlainDriver a Oracle plain driver.\n  @param Connection a database connection object.\n  @param Info a statement parameters.\n  @param Handle a connection handle pointer.\n}\nconstructor TZMySQLPreparedStatement.Create(\n  PlainDriver: IZMySQLPlainDriver; Connection: IZConnection;\n  const SQL: string; Info: TStrings);\nbegin\n  inherited Create(Connection, SQL, Info);\n  FMySQLConnection := Connection as IZMySQLConnection;\n  FHandle := FMysqlConnection.GetConnectionHandle;\n  FPlainDriver := PlainDriver;\n  ResultSetType := rtScrollInsensitive;\n\n  FUseResult := StrToBoolEx(DefineStatementParameter(Self, 'useresult', 'false'));\n  FUseDefaults := StrToBoolEx(DefineStatementParameter(Self, 'defaults', 'true'));\n\n  Prepare;\nend;\n\n{**\n  Destroys this object and cleanups the memory.\n}\ndestructor TZMySQLPreparedStatement.Destroy;\nbegin\n  FStmtHandle := FPlainDriver.ClosePrepStmt(FStmtHandle);\n  inherited Destroy;\nend;\n\nprocedure TZMySQLPreparedStatement.Prepare;\nbegin\n  FStmtHandle := FPlainDriver.InitializePrepStmt(FHandle);\n  if (FStmtHandle = nil) then\n    begin\n      CheckMySQLPrepStmtError(FPlainDriver, FStmtHandle, lcPrepStmt, SFailedtoInitPrepStmt);\n      exit;\n    end;\n  if (FPlainDriver.PrepareStmt(FStmtHandle, PAnsiChar(ASQL), length(ASQL)) <> 0) then\n    begin\n      CheckMySQLPrepStmtError(FPlainDriver, FStmtHandle, lcPrepStmt, SFailedtoPrepareStmt);\n      exit;\n    end;\n  LogPrepStmtMessage(lcPrepStmt, SQL);\n  inherited Prepare;\nend;\n\n{**\n  Checks is use result should be used in result sets.\n  @return <code>True</code> use result in result sets,\n    <code>False</code> store result in result sets.\n}\nfunction TZMySQLPreparedStatement.IsUseResult: Boolean;\nbegin\n  Result := FUseResult;\nend;\n\n{**\n  Checks if this is a prepared mysql statement.\n  @return <code>True</code> This is a prepared mysql statement.\n}\nfunction TZMySQLPreparedStatement.IsPreparedStatement: Boolean;\nbegin\n  Result := True;\nend;\n\n{**\n  Creates a result set based on the current settings.\n  @return a created result set object.\n}\nfunction TZMySQLPreparedStatement.CreateResultSet(const SQL: string): IZResultSet;\nvar\n  CachedResolver: TZMySQLCachedResolver;\n  NativeResultSet: TZMySQLPreparedResultSet;\n  CachedResultSet: TZCachedResultSet;\nbegin\n  NativeResultSet := TZMySQLPreparedResultSet.Create(FPlainDriver, Self, SQL, FHandle,\n    FUseResult);\n  NativeResultSet.SetConcurrency(rcReadOnly);\n  if (GetResultSetConcurrency <> rcReadOnly) or (FUseResult\n    and (GetResultSetType <> rtForwardOnly)) then\n  begin\n    CachedResolver := TZMySQLCachedResolver.Create(FPlainDriver, FHandle, (Self as IZMysqlStatement),\n      NativeResultSet.GetMetaData);\n    CachedResultSet := TZCachedResultSet.Create(NativeResultSet, SQL,\n      CachedResolver, ConSettings);\n    CachedResultSet.SetConcurrency(GetResultSetConcurrency);\n    Result := CachedResultSet;\n  end\n  else\n    Result := NativeResultSet;\nend;\n\nprocedure TZMysqlPreparedStatement.BindInParameters;\nvar\n  PBuffer: Pointer;\n  year, month, day, hour, minute, second, millisecond: word;\n  MyType: TMysqlFieldTypes;\n  I, OffSet, PieceSize: integer;\n  TempBlob: IZBlob;\n  TempAnsi: RawByteString;\nbegin\n  //http://dev.mysql.com/doc/refman/5.0/en/storage-requirements.html\n  if InParamCount = 0 then\n     exit;\n  { Initialize Bind Array and Column Array }\n  FParamBindBuffer := TZMySqlParamBindBuffer.Create(FPlainDriver,InParamCount,FColumnArray);\n\n  For I := 0 to InParamCount - 1 do\n  begin\n    if (InParamValues[I].VType = vtNull) and (InParamDefaultValues[I] <> '') and\n      StrToBoolEx(DefineStatementParameter(Self, 'defaults', 'true')) then\n        SoftVarManager.SetAsString(InParamValues[I], Copy(InParamDefaultValues[I], 2, Length(InParamDefaultValues[I])-2));\n    MyType := GetFieldType(InParamValues[I]);\n    case MyType of\n      FIELD_TYPE_VARCHAR:\n        begin\n          TempAnsi := ZPlainString(InParamValues[I].VUnicodeString);\n          FParamBindBuffer.AddColumn(FIELD_TYPE_STRING, Length(TempAnsi),false);\n        end;\n      FIELD_TYPE_STRING:\n        begin\n          TempAnsi := ZPlainString(InParamValues[I].VString);\n          FParamBindBuffer.AddColumn(FIELD_TYPE_STRING, Length(TempAnsi),false);\n        end;\n      FIELD_TYPE_BLOB:\n        begin\n          TempBlob := (InParamValues[I].VInterface as IZBlob);\n          if TempBlob.IsEmpty then\n            DefVarManager.SetNull(InParamValues[I])\n          else\n            if InParamTypes[I] = stBinaryStream then\n              FParamBindBuffer.AddColumn(FIELD_TYPE_BLOB, TempBlob.Length, TempBlob.Length > ChunkSize)\n            else\n            begin\n              TempAnsi := GetValidatedAnsiStringFromBuffer(TempBlob.GetBuffer,\n                        TempBlob.Length, TempBlob.WasDecoded, ConSettings);\n              TempBlob := TZAbstractBlob.CreateWithData(PAnsiChar(TempAnsi), Length(TempAnsi));\n              TempBlob.SetString(TempAnsi);\n              InParamValues[I].VInterface  := TempBlob;\n              FParamBindBuffer.AddColumn(FIELD_TYPE_STRING, TempBlob.Length, TempBlob.Length > ChunkSize);\n            end;\n        end;\n      FIELD_TYPE_TINY:\n        FParamBindBuffer.AddColumn(FIELD_TYPE_STRING,1,false);\n      FIELD_TYPE_TINY_BLOB:\n        FParamBindBuffer.AddColumn(MyType,Length(InParamValues[i].VBytes),false);\n      else\n        FParamBindBuffer.AddColumn(MyType,getMySQLFieldSize(MyType, 0),false);\n    end;\n    PBuffer := @FColumnArray[I].buffer[0];\n\n    if InParamValues[I].VType=vtNull then\n      FColumnArray[I].is_null := 1\n    else\n      FColumnArray[I].is_null := 0;\n      case FParamBindBuffer.GetBufferType(I+1) of\n\n        FIELD_TYPE_FLOAT:    Single(PBuffer^)     := InParamValues[I].VFloat;\n        FIELD_TYPE_DOUBLE:   Double(PBuffer^)     := InParamValues[I].VFloat;\n        FIELD_TYPE_STRING:\n          case MyType of\n            FIELD_TYPE_TINY:\n              if InParamValues[I].VBoolean then\n                PAnsiChar(PBuffer)^ := 'Y'\n              else\n                PAnsiChar(PBuffer)^ := 'N';\n            FIELD_TYPE_VARCHAR:\n              System.Move(PAnsiChar(TempAnsi)^, PBuffer^, Length(TempAnsi));\n            FIELD_TYPE_BLOB:\n              if not (Length(TempAnsi) > ChunkSize ) then\n                System.Move(PAnsiChar(TempAnsi)^, PBuffer^, Length(TempAnsi));\n            else\n              System.Move(PAnsiChar(TempAnsi)^, PBuffer^, Length(TempAnsi));\n          end;\n        FIELD_TYPE_LONGLONG: Int64(PBuffer^) := InParamValues[I].VInteger;\n        FIELD_TYPE_DATETIME:\n          begin\n            DecodeDateTime(InParamValues[I].VDateTime, Year, Month, Day, hour, minute, second, millisecond);\n            PMYSQL_TIME(PBuffer)^.year := year;\n            PMYSQL_TIME(PBuffer)^.month := month;\n            PMYSQL_TIME(PBuffer)^.day := day;\n            PMYSQL_TIME(PBuffer)^.hour := hour;\n            PMYSQL_TIME(PBuffer)^.minute := minute;\n            PMYSQL_TIME(PBuffer)^.second := second;\n            PMYSQL_TIME(PBuffer)^.second_part := millisecond;\n          end;\n          FIELD_TYPE_TINY_BLOB:\n            System.Move(PAnsiChar(InParamValues[i].VBytes)^, PBuffer^, Length(InParamValues[i].VBytes));\n          FIELD_TYPE_MEDIUM_BLOB, FIELD_TYPE_LONG_BLOB,\n          FIELD_TYPE_BLOB:\n            begin\n              if TempBlob.Length<=ChunkSize then\n                System.Move(TempBlob.GetBuffer^, PBuffer^, TempBlob.Length);\n              TempBlob := nil;\n            end;\n          FIELD_TYPE_NULL:;\n      end;\n  end;\n\n  if (FPlainDriver.BindParameters(FStmtHandle, FParamBindBuffer.GetBufferAddress) <> 0) then\n  begin\n    checkMySQLPrepStmtError (FPlainDriver, FStmtHandle, lcPrepStmt, SBindingFailure);\n    exit;\n  end;\n  inherited BindInParameters;\n\n  // Send large blobs in chuncks\n  For I := 0 to InParamCount - 1 do\n  begin\n    if FParamBindBuffer.GetBufferType(I+1) in [FIELD_TYPE_STRING,FIELD_TYPE_BLOB] then\n      begin\n        MyType := GetFieldType(InParamValues[I]);\n        if MyType = FIELD_TYPE_BLOB then\n          begin\n            TempBlob := (InParamValues[I].VInterface as IZBlob);\n            if TempBlob.Length>ChunkSize then\n            begin\n              OffSet := 0;\n              PieceSize := ChunkSize;\n              while OffSet < TempBlob.Length do\n              begin\n                if OffSet+PieceSize > TempBlob.Length then\n                  PieceSize := TempBlob.Length - OffSet;\n                if (FPlainDriver.SendPreparedLongData(FStmtHandle, I, PAnsiChar(TempBlob.GetBuffer)+OffSet, PieceSize) <> 0) then\n                begin\n                  checkMySQLPrepStmtError (FPlainDriver, FStmtHandle, lcPrepStmt, SBindingFailure);\n                  exit;\n                end;\n                Inc(OffSet, PieceSize);\n              end;\n            end;\n            TempBlob:=nil;\n          end;\n      end;\n  end;\nend;\n\nprocedure TZMySQLPreparedStatement.UnPrepareInParameters;\nbegin\n  // Empty : Mysql can't prepare datastructures before the actual parameters are known, because the\n  // number/datatype of parameters isn't returned by the server.\n  inherited UnPrepareInParameters;\nend;\n\nfunction TZMysqlPreparedStatement.getFieldType (testVariant: TZVariant): TMysqlFieldTypes;\nbegin\n  case testVariant.vType of\n    vtNull:      Result := FIELD_TYPE_TINY;\n    vtBoolean:   Result := FIELD_TYPE_TINY;\n    vtBytes:     Result := FIELD_TYPE_TINY_BLOB;\n    vtInteger:   Result := FIELD_TYPE_LONGLONG;\n    vtFloat:     Result := FIELD_TYPE_DOUBLE;\n    vtString:    Result := FIELD_TYPE_STRING;\n    vtDateTime:  Result := FIELD_TYPE_DATETIME;\n    vtUnicodeString: Result := FIELD_TYPE_VARCHAR;\n    vtInterface: Result := FIELD_TYPE_BLOB;\n  else\n    raise EZSQLException.Create(SUnsupportedDataType);\n  end;\nend;\n\n{**\n  Executes the SQL query in this <code>PreparedStatement</code> object\n  and returns the result set generated by the query.\n\n  @return a <code>ResultSet</code> object that contains the data produced by the\n    query; never <code>null</code>\n}\nfunction TZMySQLPreparedStatement.ExecuteQueryPrepared: IZResultSet;\nbegin\n  Result := nil;\n  BindInParameters;\n  if (self.FPlainDriver.ExecuteStmt(FStmtHandle) <> 0) then\n    try\n      checkMySQLPrepStmtError(FPlainDriver,FStmtHandle, lcExecPrepStmt, SPreparedStmtExecFailure);\n    except\n      if Assigned(FParamBindBuffer) then\n        FreeAndNil(FParamBindBuffer);\n      raise;\n    end;\n\n  if Assigned(FParamBindBuffer) then\n     FreeAndNil(FParamBindBuffer);\n\n  if FPlainDriver.GetPreparedFieldCount(FStmtHandle) = 0 then\n    raise EZSQLException.Create(SCanNotOpenResultSet);\n  Result := CreateResultSet(SQL);\n  inherited ExecuteQueryPrepared;\nend;\n\n{**\n  Executes the SQL INSERT, UPDATE or DELETE statement\n  in this <code>PreparedStatement</code> object.\n  In addition,\n  SQL statements that return nothing, such as SQL DDL statements,\n  can be executed.\n\n  @return either the row count for INSERT, UPDATE or DELETE statements;\n  or 0 for SQL statements that return nothing\n}\nfunction TZMySQLPreparedStatement.ExecuteUpdatePrepared: Integer;\nbegin\n  BindInParameters;\n  if (self.FPlainDriver.ExecuteStmt(FStmtHandle) <> 0) then\n    try\n      checkMySQLPrepStmtError(FPlainDriver,FStmtHandle, lcExecPrepStmt, SPreparedStmtExecFailure);\n    except\n      if Assigned(FParamBindBuffer) then\n        FreeAndNil(FParamBindBuffer); //MemLeak closed\n      raise;\n    end;\n\n  if Assigned(FParamBindBuffer) then\n    FreeAndNil(FParamBindBuffer); //MemLeak closed\n\n    { Process queries with result sets }\n  if FPlainDriver.GetPreparedFieldCount(FStmtHandle) > 0 then\n    begin\n      FPlainDriver.StorePreparedResult(FStmtHandle);\n      Result := FPlainDriver.GetPreparedAffectedRows(FStmtHandle);\n      if Assigned(FStmtHandle) then\n        begin\n          FPlainDriver.FreePreparedResult(FStmtHandle);\n          while(FPlainDriver.GetPreparedNextResult(FStmtHandle) = 0) do\n            FPlainDriver.FreePreparedResult(FStmtHandle);\n        end;\n\n    end\n    { Process regular query }\n  else\n    Result := FPlainDriver.GetPreparedAffectedRows(FStmtHandle);\n  LastUpdateCount := Result;\n  Inherited ExecuteUpdatePrepared;\nend;\n\n{**\n  Executes any kind of SQL statement.\n  Some prepared statements return multiple results; the <code>execute</code>\n  method handles these complex statements as well as the simpler\n  form of statements handled by the methods <code>executeQuery</code>\n  and <code>executeUpdate</code>.\n  @see Statement#execute\n}\nfunction TZMySQLPreparedStatement.ExecutePrepared: Boolean;\nbegin\n  BindInParameters;\n  if (FPlainDriver.ExecuteStmt(FStmtHandle) <> 0) then\n    try\n      checkMySQLPrepStmtError(FPlainDriver,FStmtHandle, lcExecPrepStmt, SPreparedStmtExecFailure);\n    except\n      if Assigned(FParamBindBuffer) then\n        FreeAndNil(FParamBindBuffer); //MemLeak closed\n      raise;\n    end;\n\n  if Assigned(FParamBindBuffer) then\n    FreeAndNil(FParamBindBuffer); //MemLeak closed\n\n  if FPlainDriver.GetPreparedFieldCount(FStmtHandle) > 0 then\n  begin\n    Result := True;\n    LastResultSet := CreateResultSet(SQL);\n  end\n  { Processes regular query. }\n  else\n  begin\n    Result := False;\n    LastUpdateCount := FPlainDriver.GetPreparedAffectedRows(FStmtHandle);\n  end;\n\n  inherited ExecutePrepared;\nend;\n\nfunction TZMySQLPreparedStatement.GetStmtHandle: PZMySqlPrepStmt;\nbegin\n  Result := FStmtHandle;\nend;\n\n{ TZMySQLCallableStatement }\n\n{**\n   Create sql string for calling stored procedure.\n   @return a Stored Procedure SQL string\n}\nfunction TZMySQLCallableStatement.GetCallSQL: RawByteString;\n  function GenerateParamsStr(Count: integer): RawByteString;\n  var\n    I: integer;\n  begin\n    Result := '';\n    for I := 0 to Count-1 do\n    begin\n      if I > 0 then\n        Result := Result + ', ';\n      if FDBParamTypes[i] in [1, 2, 3, 4] then\n        Result := Result + '@'+ZPlainString(FParamNames[I])\n    end;\n  end;\n\nvar\n  InParams: RawByteString;\nbegin\n  if HasOutParameter then\n    InParams := GenerateParamsStr(OutParamCount)\n  else\n    InParams := GenerateParamsStr(InParamCount);\n  Result := 'CALL '+ZPlainString(SQL)+'('+InParams+')';\nend;\n\nfunction TZMySQLCallableStatement.GetOutParamSQL: String;\n  function GenerateParamsStr(Count: integer): string;\n  var\n    I: integer;\n  begin\n    Result := '';\n    I := 0;\n    while True do\n      if (FDBParamTypes[i] = 0) or ( I = Length(FDBParamTypes)) then\n        break\n      else\n      begin\n        if FDBParamTypes[i] in [2, 3, 4] then\n        begin\n          if Result <> '' then\n            Result := Result + ',';\n          if FParamTypeNames[i] = '' then\n            Result := Result + ' @'+FParamNames[I]+' AS '+FParamNames[I]\n          else\n            Result := Result + ' CAST(@'+FParamNames[I]+ ' AS '+FParamTypeNames[i]+') AS '+FParamNames[I];\n        end;\n        Inc(i);\n      end;\n  end;\n\nvar\n  OutParams: String;\nbegin\n  OutParams := GenerateParamsStr(Self.OutParamCount-Length(InParamValues));\n  Result := 'SELECT '+ OutParams;\nend;\n\nfunction TZMySQLCallableStatement.GetSelectFunctionSQL: RawByteString;\n  function GenerateInParamsStr: RawByteString;\n  var\n    I: Integer;\n  begin\n    Result := '';\n    for i := 0 to Length(InParamValues) -1 do\n      if Result = '' then\n        Result := PrepareAnsiSQLParam(I)\n      else\n        Result := Result+', '+ PrepareAnsiSQLParam(I);\n  end;\nvar\n  InParams: RawByteString;\nbegin\n  InParams := GenerateInParamsStr;\n  Result := 'SELECT '+ZPlainString(SQL)+'('+InParams+')';\n  Result := Result + ' AS ReturnValue';\nend;\n\n{**\n  Executes an SQL <code>INSERT</code>, <code>UPDATE</code> or\n  <code>DELETE</code> statement. In addition,\n  SQL statements that return nothing, such as SQL DDL statements,\n  can be executed.\n\n  @param sql an SQL <code>INSERT</code>, <code>UPDATE</code> or\n    <code>DELETE</code> statement or an SQL statement that returns nothing\n  @return either the row count for <code>INSERT</code>, <code>UPDATE</code>\n    or <code>DELETE</code> statements, or 0 for SQL statements that return nothing\n}\nfunction TZMySQLCallableStatement.PrepareAnsiSQLParam(ParamIndex: Integer): RawByteString;\nvar\n  Value: TZVariant;\n  TempBytes: TByteDynArray;\n  TempBlob: IZBlob;\n  AYear, AMonth, ADay, AHour, AMinute, ASecond, AMilliSecond: Word;\nbegin\n  TempBytes := nil;\n  if InParamCount <= ParamIndex then\n    raise EZSQLException.Create(SInvalidInputParameterCount);\n\n  Value := InParamValues[ParamIndex];\n  if DefVarManager.IsNull(Value) then\n    if FUseDefaults and (InParamDefaultValues[ParamIndex] <> '') then\n      Result := ConSettings^.ConvFuncs.ZStringToRaw(InParamDefaultValues[ParamIndex],\n        ConSettings^.CTRL_CP, ConSettings^.ClientCodePage^.CP)\n    else\n      Result := 'NULL'\n  else\n  begin\n    case InParamTypes[ParamIndex] of\n      stBoolean:\n        if SoftVarManager.GetAsBoolean(Value) then\n          Result := '''Y'''\n        else\n          Result := '''N''';\n      stByte, stShort, stInteger, stLong, stBigDecimal, stFloat, stDouble:\n        Result := RawByteString(SoftVarManager.GetAsString(Value));\n      stBytes:\n        begin\n          TempBytes := SoftVarManager.GetAsBytes(Value);\n          Result := GetSQLHexAnsiString(PAnsiChar(TempBytes), Length(TempBytes));\n        end;\n      stString:\n        Result := FPlainDriver.EscapeString(FHandle, ZPlainString(SoftVarManager.GetAsString(Value), ConSettings), ConSettings, True);\n      stUnicodeString:\n        Result := FPlainDriver.EscapeString(FHandle, ZPlainString(SoftVarManager.GetAsUnicodeString(Value)), ConSettings, True);\n      stDate:\n      begin\n        DecodeDateTime(SoftVarManager.GetAsDateTime(Value),\n          AYear, AMonth, ADay, AHour, AMinute, ASecond, AMilliSecond);\n        Result := '''' + RawByteString(Format('%0.4d-%0.2d-%0.2d',\n          [AYear, AMonth, ADay])) + '''';\n      end;\n      stTime:\n      begin\n        DecodeDateTime(SoftVarManager.GetAsDateTime(Value),\n          AYear, AMonth, ADay, AHour, AMinute, ASecond, AMilliSecond);\n        Result := '''' + RawByteString(Format('%0.2d:%0.2d:%0.2d',\n          [AHour, AMinute, ASecond])) + '''';\n      end;\n      stTimestamp:\n      begin\n        DecodeDateTime(SoftVarManager.GetAsDateTime(Value),\n          AYear, AMonth, ADay, AHour, AMinute, ASecond, AMilliSecond);\n        Result := '''' + RawByteString(Format('%0.4d-%0.2d-%0.2d %0.2d:%0.2d:%0.2d',\n          [AYear, AMonth, ADay, AHour, AMinute, ASecond])) + '''';\n      end;\n      stAsciiStream, stUnicodeStream, stBinaryStream:\n        begin\n          TempBlob := DefVarManager.GetAsInterface(Value) as IZBlob;\n          if not TempBlob.IsEmpty then\n            case InParamTypes[ParamIndex] of\n              stBinaryStream:\n                Result := GetSQLHexAnsiString(PAnsichar(TempBlob.GetBuffer), TempBlob.Length);\n              else\n                Result := FPlainDriver.EscapeString(FHandle,\n                  GetValidatedAnsiStringFromBuffer(TempBlob.GetBuffer,\n                  TempBlob.Length, TempBlob.WasDecoded, ConSettings),\n                  ConSettings, True);\n            end\n          else\n            Result := 'NULL';\n        end;\n    end;\n  end;\nend;\n\nfunction TZMySQLCallableStatement.GetStmtHandle: PZMySqlPrepStmt;\nbegin\n  Result := nil;\nend;\n\nprocedure TZMySQLCallableStatement.ClearResultSets;\nbegin\n  inherited;\n  FPlainDriver.FreeResult(FQueryHandle);\n  FQueryHandle := nil;\nend;\n\nprocedure TZMySQLCallableStatement.BindInParameters;\nvar\n  I: integer;\n  ExecQuery: RawByteString;\nbegin\n  I := 0;\n  ExecQuery := '';\n  while True do\n    if (i = Length(FDBParamTypes)) then\n      break\n    else\n    begin\n      if FDBParamTypes[i] in [1, 3] then //ptInputOutput\n        if ExecQuery = '' then\n          ExecQuery := 'SET @'+ZPlainString(FParamNames[i])+' = '+PrepareAnsiSQLParam(I)\n        else\n          ExecQuery := ExecQuery + ', @'+ZPlainString(FParamNames[i])+' = '+PrepareAnsiSQLParam(I);\n      Inc(i);\n    end;\n  if not (ExecQuery = '') then\n    if FPlainDriver.ExecQuery(Self.FHandle, PAnsiChar(ExecQuery)) = 0 then\n      DriverManager.LogMessage(lcBindPrepStmt, FPlainDriver.GetProtocol, String(ExecQuery))\n    else\n      CheckMySQLError(FPlainDriver, FHandle, lcExecute, String(ExecQuery));\nend;\n\n{**\n  Creates a result set based on the current settings.\n  @return a created result set object.\n}\nfunction TZMySQLCallableStatement.CreateResultSet(const SQL: string): IZResultSet;\nvar\n  CachedResolver: TZMySQLCachedResolver;\n  NativeResultSet: TZMySQLResultSet;\n  CachedResultSet: TZCachedResultSet;\nbegin\n  NativeResultSet := TZMySQLResultSet.Create(FPlainDriver, Self, SQL, FHandle,\n    FUseResult, @LastUpdateCount, not IsFunction);\n  NativeResultSet.SetConcurrency(rcReadOnly);\n  if (GetResultSetConcurrency <> rcReadOnly) or (FUseResult\n    and (GetResultSetType <> rtForwardOnly)) or (not IsFunction) then\n  begin\n    CachedResolver := TZMySQLCachedResolver.Create(FPlainDriver, FHandle, Self,\n      NativeResultSet.GetMetaData);\n    CachedResultSet := TZCachedResultSet.Create(NativeResultSet, SQL,\n      CachedResolver, ConSettings);\n    CachedResultSet.SetConcurrency(rcReadOnly);\n    {Need to fetch all data. The handles must be released for mutiple\n      Resultsets}\n    CachedResultSet.AfterLast;//Fetch all\n    CachedResultSet.BeforeFirst;//Move to first pos\n    NativeResultSet.ReleaseHandle; //Release the handles\n    Result := CachedResultSet;\n  end\n  else\n    Result := NativeResultSet;\nend;\n\n{**\n  Sets output parameters from a ResultSet\n  @param Value a IZResultSet object.\n}\nprocedure TZMySQLCallableStatement.FetchOutParams(ResultSet: IZResultSet);\nvar\n  ParamIndex, I: Integer;\n  Temp: TZVariant;\n  HasRows: Boolean;\nbegin\n  ResultSet.BeforeFirst;\n  HasRows := ResultSet.Next;\n\n  I := 1;\n  for ParamIndex := 0 to OutParamCount - 1 do\n  begin\n    if not (FDBParamTypes[ParamIndex] in [2, 3, 4]) then // ptOutput, ptInputOutput, ptResult\n      Continue;\n    if I > ResultSet.GetMetadata.GetColumnCount then\n      Break;\n\n    if (not HasRows) or (ResultSet.IsNull(I)) then\n      DefVarManager.SetNull(Temp)\n    else\n      case ResultSet.GetMetadata.GetColumnType(I) of\n      stBoolean:\n        DefVarManager.SetAsBoolean(Temp, ResultSet.GetBoolean(I));\n      stByte:\n        DefVarManager.SetAsInteger(Temp, ResultSet.GetByte(I));\n      stBytes:\n        DefVarManager.SetAsBytes(Temp, ResultSet.GetBytes(I));\n      stShort:\n        DefVarManager.SetAsInteger(Temp, ResultSet.GetShort(I));\n      stInteger:\n        DefVarManager.SetAsInteger(Temp, ResultSet.GetInt(I));\n      stLong:\n        DefVarManager.SetAsInteger(Temp, ResultSet.GetLong(I));\n      stFloat:\n        DefVarManager.SetAsFloat(Temp, ResultSet.GetFloat(I));\n      stDouble:\n        DefVarManager.SetAsFloat(Temp, ResultSet.GetDouble(I));\n      stBigDecimal:\n        DefVarManager.SetAsFloat(Temp, ResultSet.GetBigDecimal(I));\n      stString, stAsciiStream:\n        DefVarManager.SetAsString(Temp, ResultSet.GetString(I));\n      stUnicodeString, stUnicodeStream:\n        DefVarManager.SetAsUnicodeString(Temp, ResultSet.GetUnicodeString(I));\n      stDate:\n        DefVarManager.SetAsDateTime(Temp, ResultSet.GetDate(I));\n      stTime:\n        DefVarManager.SetAsDateTime(Temp, ResultSet.GetTime(I));\n      stTimestamp:\n        DefVarManager.SetAsDateTime(Temp, ResultSet.GetTimestamp(I));\n      stBinaryStream:\n        DefVarManager.SetAsInterface(Temp, ResultSet.GetBlob(I));\n      else\n        DefVarManager.SetAsString(Temp, ResultSet.GetString(I));\n      end;\n    OutParamValues[ParamIndex] := Temp;\n    Inc(I);\n  end;\n  ResultSet.BeforeFirst;\nend;\n\nprocedure TZMySQLCallableStatement.RegisterParamTypeAndName(const ParameterIndex:integer;\n      const ParamTypeName, ParamName: String; Const ColumnSize, Precision: Integer);\nbegin\n  FParamNames[ParameterIndex] := ParamName;\n  if ( Pos('char', LowerCase(ParamTypeName)) > 0 ) or\n     ( Pos('set', LowerCase(ParamTypeName)) > 0 ) then\n    FParamTypeNames[ParameterIndex] := 'CHAR('+IntToStr(ColumnSize)+')'\n  else\n    if ( Pos('set', LowerCase(ParamTypeName)) > 0 ) then\n      FParamTypeNames[ParameterIndex] := 'CHAR('+IntToStr(ColumnSize)+')'\n    else\n      if ( Pos('datetime', LowerCase(ParamTypeName)) > 0 ) or\n         ( Pos('timestamp', LowerCase(ParamTypeName)) > 0 ) then\n        FParamTypeNames[ParameterIndex] := 'DATETIME'\n      else\n        if ( Pos('date', LowerCase(ParamTypeName)) > 0 ) then\n          FParamTypeNames[ParameterIndex] := 'DATE'\n        else\n          if ( Pos('time', LowerCase(ParamTypeName)) > 0 ) then\n            FParamTypeNames[ParameterIndex] := 'TIME'\n          else\n            if ( Pos('int', LowerCase(ParamTypeName)) > 0 ) or\n               ( Pos('year', LowerCase(ParamTypeName)) > 0 ) then\n              FParamTypeNames[ParameterIndex] := 'SIGNED'\n            else\n              if ( Pos('binary', LowerCase(ParamTypeName)) > 0 ) then\n                FParamTypeNames[ParameterIndex] := 'BINARY('+IntToStr(ColumnSize)+')'\n              else\n                FParamTypeNames[ParameterIndex] := '';\nend;\n\nconstructor TZMySQLCallableStatement.Create(PlainDriver: IZMySQLPlainDriver;\n  Connection: IZConnection; const SQL: string; Info: TStrings;\n  Handle: PZMySQLConnect);\nbegin\n  inherited Create(Connection, SQL, Info);\n  FHandle := Handle;\n  FPlainDriver := PlainDriver;\n  ResultSetType := rtScrollInsensitive;\n  FUseResult := StrToBoolEx(DefineStatementParameter(Self, 'useresult', 'false'));\n  FUseDefaults := StrToBoolEx(DefineStatementParameter(Self, 'defaults', 'true'))\nend;\n\n{**\n  Executes an SQL statement that returns a single <code>ResultSet</code> object.\n  @param sql typically this is a static SQL <code>SELECT</code> statement\n  @return a <code>ResultSet</code> object that contains the data produced by the\n    given query; never <code>null</code>\n}\nfunction TZMySQLCallableStatement.ExecuteQuery(const SQL: RawByteString): IZResultSet;\nbegin\n  Result := nil;\n  ASQL := SQL;\n  if FPlainDriver.ExecQuery(FHandle, PAnsiChar(SQL)) = 0 then\n  begin\n    DriverManager.LogMessage(lcExecute, FPlainDriver.GetProtocol, SSQL);\n    if not FPlainDriver.ResultSetExists(FHandle) then\n      raise EZSQLException.Create(SCanNotOpenResultSet);\n    if IsFunction then\n      ClearResultSets;\n    FResultSets.Add(CreateResultSet(SSQL));\n    if FPlainDriver.CheckAnotherRowset(FHandle) then\n    begin\n      while FPlainDriver.RetrieveNextRowset(FHandle) = 0 do\n        if FPlainDriver.CheckAnotherRowset(FHandle) then\n          FResultSets.Add(CreateResultSet(SSQL))\n        else break;\n      CheckMySQLError(FPlainDriver, FHandle, lcExecute, SSQL);\n    end;\n    FActiveResultset := FResultSets.Count-1;\n    Result := IZResultSet(FResultSets[FActiveResultset]);\n  end\n  else\n    CheckMySQLError(FPlainDriver, FHandle, lcExecute, SSQL);\nend;\n\n{**\n  Executes an SQL <code>INSERT</code>, <code>UPDATE</code> or\n  <code>DELETE</code> statement. In addition,\n  SQL statements that return nothing, such as SQL DDL statements,\n  can be executed.\n\n  @param sql an SQL <code>INSERT</code>, <code>UPDATE</code> or\n    <code>DELETE</code> statement or an SQL statement that returns nothing\n  @return either the row count for <code>INSERT</code>, <code>UPDATE</code>\n    or <code>DELETE</code> statements, or 0 for SQL statements that return nothing\n}\nfunction TZMySQLCallableStatement.ExecuteUpdate(const SQL: RawByteString): Integer;\nbegin\n  Result := -1;\n  ASQL := SQL;\n  if FPlainDriver.ExecQuery(FHandle, PAnsiChar(ASQL)) = 0 then\n  begin\n    { Process queries with result sets }\n    if FPlainDriver.ResultSetExists(FHandle) then\n    begin\n      ClearResultSets;\n      FActiveResultset := 0;\n      FResultSets.Add(CreateResultSet(LogSQL));\n      if FPlainDriver.CheckAnotherRowset(FHandle) then\n      begin\n        Result := LastUpdateCount;\n        while FPlainDriver.RetrieveNextRowset(FHandle) = 0 do\n          if FPlainDriver.CheckAnotherRowset(FHandle) then\n          begin\n            FResultSets.Add(CreateResultSet(SSQL));\n            inc(Result, LastUpdateCount); //LastUpdateCount will be returned from ResultSet.Open\n          end\n          else break;\n        CheckMySQLError(FPlainDriver, FHandle, lcExecute, SSQL);\n      end\n      else\n        Result := LastUpdateCount;\n      FActiveResultset := FResultSets.Count-1;\n      LastResultSet := IZResultSet(FResultSets[FActiveResultset]);\n    end\n    else { Process regular query }\n      Result := FPlainDriver.GetAffectedRows(FHandle);\n  end\n  else\n    CheckMySQLError(FPlainDriver, FHandle, lcExecute, SSQL);\n  LastUpdateCount := Result;\nend;\n\n{**\n  Executes an SQL statement that may return multiple results.\n  Under some (uncommon) situations a single SQL statement may return\n  multiple result sets and/or update counts.  Normally you can ignore\n  this unless you are (1) executing a stored procedure that you know may\n  return multiple results or (2) you are dynamically executing an\n  unknown SQL string.  The  methods <code>execute</code>,\n  <code>getMoreResults</code>, <code>getResultSet</code>,\n  and <code>getUpdateCount</code> let you navigate through multiple results.\n\n  The <code>execute</code> method executes an SQL statement and indicates the\n  form of the first result.  You can then use the methods\n  <code>getResultSet</code> or <code>getUpdateCount</code>\n  to retrieve the result, and <code>getMoreResults</code> to\n  move to any subsequent result(s).\n\n  @param sql any SQL statement\n  @return <code>true</code> if the next result is a <code>ResultSet</code> object;\n  <code>false</code> if it is an update count or there are no more results\n}\nfunction TZMySQLCallableStatement.Execute(const SQL: RawByteString): Boolean;\nvar\n  HasResultset : Boolean;\nbegin\n  Result := False;\n  {$IFNDEF UNICODE}ASQL := SQL;{$ENDIF}\n  if FPlainDriver.ExecQuery(FHandle, PAnsiChar(ASQL)) = 0 then\n  begin\n    DriverManager.LogMessage(lcExecute, FPlainDriver.GetProtocol, LogSQL);\n    HasResultSet := FPlainDriver.ResultSetExists(FHandle);\n    { Process queries with result sets }\n    if HasResultSet then\n    begin\n      Result := True;\n      LastResultSet := CreateResultSet(LogSQL);\n    end\n    { Processes regular query. }\n    else\n    begin\n      Result := False;\n      LastUpdateCount := FPlainDriver.GetAffectedRows(FHandle);\n    end;\n  end\n  else\n    CheckMySQLError(FPlainDriver, FHandle, lcExecute, LogSQL);\nend;\n\n{**\n  Executes the SQL query in this <code>PreparedStatement</code> object\n  and returns the result set generated by the query.\n\n  @return a <code>ResultSet</code> object that contains the data produced by the\n    query; never <code>null</code>\n}\nfunction TZMySQLCallableStatement.ExecuteQueryPrepared: IZResultSet;\nbegin\n  if IsFunction then\n  begin\n    TrimInParameters;\n    Result := ExecuteQuery(GetSelectFunctionSQL);\n  end\n  else\n  begin\n    BindInParameters;\n    ExecuteUpdate(GetCallSQL);\n    if OutParamCount > 0 then\n      Result := ExecuteQuery(ZPlainString(GetOutParamSQL)) //Get the Last Resultset\n    else\n      Result := GetLastResultSet;\n  end;\n  if Assigned(Result) then\n    FetchOutParams(Result);\nend;\n\n{**\n  Executes the SQL INSERT, UPDATE or DELETE statement\n  in this <code>PreparedStatement</code> object.\n  In addition,\n  SQL statements that return nothing, such as SQL DDL statements,\n  can be executed.\n\n  @return either the row count for INSERT, UPDATE or DELETE statements;\n  or 0 for SQL statements that return nothing\n}\nfunction TZMySQLCallableStatement.ExecuteUpdatePrepared: Integer;\nbegin\n  if IsFunction then\n  begin\n    TrimInParameters;\n    Result := ExecuteUpdate(GetSelectFunctionSQL);\n    FetchOutParams(LastResultSet);\n  end\n  else\n  begin\n    BindInParameters;\n    Result := ExecuteUpdate(GetCallSQL);\n    if OutParamCount > 0 then\n      FetchOutParams(ExecuteQuery(ZPlainString(GetOutParamSQL))); //Get the Last Resultset\n    Inc(Result, LastUpdateCount);\n  end;\nend;\n\n{**\n  Checks is use result should be used in result sets.\n  @return <code>True</code> use result in result sets,\n    <code>False</code> store result in result sets.\n}\nfunction TZMySQLCallableStatement.IsUseResult: Boolean;\nbegin\n  Result := FUseResult;\nend;\n\n{**\n  Checks if this is a prepared mysql statement.\n  @return <code>False</code> This is not a prepared mysql statement.\n}\nfunction TZMySQLCallableStatement.IsPreparedStatement: Boolean;\nbegin\n  Result := False;\nend;\n\n{**\n  Are more resultsets retrieved?\n  @result Returns <code>True</code> if more resultsets are retrieved\n}\nfunction TZMySQLCallableStatement.HasMoreResultSets: Boolean;\nbegin\n  Result := FResultSets.Count > 1;\nend;\n\n{**\n  Get the first resultset..\n  @result <code>IZResultSet</code> if supported\n}\nfunction TZMySQLCallableStatement.GetNextResultSet: IZResultSet;\nbegin\n  if ( FActiveResultset < FResultSets.Count-1) and ( FResultSets.Count > 1) then\n  begin\n    Inc(FActiveResultset);\n    Result := IZResultSet(FResultSets[FActiveResultset]);\n  end\n  else\n    if FResultSets.Count = 0 then\n      Result := nil\n    else\n      Result := IZResultSet(FResultSets[FActiveResultset]);\nend;\n\n{**\n  Get the previous resultset..\n  @result <code>IZResultSet</code> if supported\n}\nfunction TZMySQLCallableStatement.GetPreviousResultSet: IZResultSet;\nbegin\n  if ( FActiveResultset > 0) and ( FResultSets.Count > 0) then\n  begin\n    Dec(FActiveResultset);\n    Result := IZResultSet(FResultSets[FActiveResultset]);\n  end\n  else\n    if FResultSets.Count = 0 then\n      Result := nil\n    else\n      Result := IZResultSet(FResultSets[FActiveResultset]);\nend;\n\n{**\n  Get the next resultset..\n  @result <code>IZResultSet</code> if supported\n}\nfunction TZMySQLCallableStatement.GetFirstResultSet: IZResultSet;\nbegin\n  if FResultSets.Count = 0 then\n    Result := nil\n  else\n  begin\n    FActiveResultset := 0;\n    Result := IZResultSet(FResultSets[0]);\n  end;\nend;\n\n{**\n  Get the last resultset..\n  @result <code>IZResultSet</code> if supported\n}\nfunction TZMySQLCallableStatement.GetLastResultSet: IZResultSet;\nbegin\n  if FResultSets.Count = 0 then\n    Result := nil\n  else\n  begin\n    FActiveResultset := FResultSets.Count -1;\n    Result := IZResultSet(FResultSets[FResultSets.Count -1]);\n  end;\nend;\n\n{**\n  First ResultSet?\n  @result <code>True</code> if first ResultSet\n}\nfunction TZMySQLCallableStatement.BOR: Boolean;\nbegin\n  Result := FActiveResultset = 0;\nend;\n\n{**\n  Last ResultSet?\n  @result <code>True</code> if Last ResultSet\n}\nfunction TZMySQLCallableStatement.EOR: Boolean;\nbegin\n  Result := FActiveResultset = FResultSets.Count -1;\nend;\n\n{**\n  Retrieves a ResultSet by his index.\n  @param Integer the index of the Resultset\n  @result <code>IZResultSet</code> of the Index or nil.\n}\nfunction TZMySQLCallableStatement.GetResultSetByIndex(const Index: Integer): IZResultSet;\nbegin\n  Result := nil;\n  if ( Index < 0 ) or ( Index > FResultSets.Count -1 ) then\n    raise Exception.Create(Format(SListIndexError, [Index]))\n  else\n    Result := IZResultSet(FResultSets[Index]);\nend;\n\n{**\n  Returns the Count of retrived ResultSets.\n  @result <code>Integer</code> Count\n}\nfunction TZMySQLCallableStatement.GetResultSetCount: Integer;\nbegin\n  Result := FResultSets.Count;\nend;\n\n{ TZMySQLAbstractBindBuffer }\n\nconstructor TZMySQLAbstractBindBuffer.Create(PlainDriver: IZMysqlPlainDriver;\n  const BindCount: Integer; var ColumnArray: TZMysqlColumnBuffer);\nbegin\n  inherited Create;\n  FBindOffsets := PlainDriver.GetBindOffsets;\n  if FBindOffsets.buffer_type=0 then\n    raise EZSQLException.Create('Unknown dll version : '+IntToStr(PlainDriver.GetClientVersion));\n  FPColumnArray := @ColumnArray;\n  setlength(FBindArray,0);\n  setlength(ColumnArray,BindCount);\n  setlength(FBindArray,BindCount*FBindOffsets.size);\nend;\n\nfunction TZMySQLAbstractBindBuffer.GetColumnArray: TZMysqlColumnBuffer;\nbegin\n  result := FPColumnArray^;\nend;\n\nfunction TZMySQLAbstractBindBuffer.GetBufferAddress: Pointer;\nbegin\n  result := @FBindArray[0];\nend;\n\nfunction TZMySQLAbstractBindBuffer.GetBufferType(ColumnIndex: Integer): TMysqlFieldTypes;\nbegin\n  result := PTMysqlFieldTypes(@FbindArray[NativeUInt((ColumnIndex-1)*FBindOffsets.size)+FBindOffsets.buffer_type])^;\nend;\n\nfunction TZMySQLAbstractBindBuffer.GetBufferIsSigned(ColumnIndex: Integer): Boolean;\nbegin\n  result := PByte(@FbindArray[NativeUInt((ColumnIndex-1)*FBindOffsets.size)+FBindOffsets.is_unsigned])^ <> 0;\nend;\n\n{ TZMySQLResultSetBindBuffer }\n\nprocedure TZMySQLResultSetBindBuffer.AddColumn(PlainDriver: IZMysqlPlainDriver;\n  const FieldHandle: PZMySQLField);\nvar\n  buffertype: TMysqlFieldTypes;\n  ColOffset: NativeUInt;\nbegin\n  buffertype := PlainDriver.GetFieldType(FieldHandle);\n  Inc(FAddedColumnCount);\n  With FPColumnArray^[FAddedColumnCount-1] do\n  begin\n      case buffertype of\n        FIELD_TYPE_DATE:        Length := sizeOf(MYSQL_TIME);\n        FIELD_TYPE_TIME:        Length := sizeOf(MYSQL_TIME);\n        FIELD_TYPE_DATETIME:    Length := sizeOf(MYSQL_TIME);\n        FIELD_TYPE_TIMESTAMP:   Length := sizeOf(MYSQL_TIME);\n        FIELD_TYPE_TINY:        Length := 1;\n        FIELD_TYPE_SHORT:       Length := 2;\n        FIELD_TYPE_LONG:        Length := 4;\n        FIELD_TYPE_LONGLONG:    Length := 8;\n        FIELD_TYPE_FLOAT:       Length := 4;\n        FIELD_TYPE_DOUBLE:      Length := 8;\n        FIELD_TYPE_NEWDECIMAL:  Length := 11;\n        FIELD_TYPE_BLOB,\n        FIELD_TYPE_MEDIUM_BLOB,\n        FIELD_TYPE_LONG_BLOB,\n        FIELD_TYPE_GEOMETRY:\n          Length := PlainDriver.GetFieldMaxLength(FieldHandle)+1;\n        FIELD_TYPE_VARCHAR,\n        FIELD_TYPE_VAR_STRING,\n        FIELD_TYPE_STRING:\n            Length := Min(MaxBlobSize, Max(PlainDriver.GetFieldLength(FieldHandle), PlainDriver.GetFieldMaxLength(FieldHandle)))+1;\n      else\n        Length := PlainDriver.GetFieldLength(FieldHandle);\n      end;\n    SetLength(Buffer, Length);\n  end;\n  ColOffset := NativeUInt((FAddedColumnCount-1)*FBindOffsets.size);\n  PTMysqlFieldTypes(@FbindArray[ColOffset+FBindOffsets.buffer_type])^ := buffertype;\n  PULong(@FbindArray[ColOffset+FBindOffsets.buffer_length])^ := FPColumnArray^[FAddedColumnCount-1].length;\n  PByte(@FbindArray[ColOffset+FBindOffsets.is_unsigned])^:= PlainDriver.GetFieldFlags(FieldHandle) and UNSIGNED_FLAG;\n  PPointer(@FbindArray[ColOffset+FBindOffsets.buffer])^:= @FPColumnArray^[FAddedColumnCount-1].buffer[0];\n  PPointer(@FbindArray[ColOffset+FBindOffsets.length])^:= @FPColumnArray^[FAddedColumnCount-1].length;\n  PPointer(@FbindArray[ColOffset+FBindOffsets.is_null])^:= @FPColumnArray^[FAddedColumnCount-1].is_null;\nend;\n\n{ TZMySQLParamBindBuffer }\n\n// largeblobparameter: true to indicate that parameter is a blob that will be\n// sent chunked. Set to false for result set columns.\n\nprocedure TZMySQLParamBindBuffer.AddColumn(buffertype: TMysqlFieldTypes;\n  const field_length: integer; const largeblobparameter: boolean);\nvar\n  tempbuffertype: TMysqlFieldTypes;\n  ColOffset:NativeUInt;\nbegin\n  Case buffertype of\n    FIELD_TYPE_DECIMAL,\n    FIELD_TYPE_NEWDECIMAL: tempbuffertype := FIELD_TYPE_DOUBLE;\n  Else\n    tempbuffertype := buffertype;\n  End;\n  Inc(FAddedColumnCount);\n  With FPColumnArray^[FAddedColumnCount-1] do\n  begin\n    length := getMySQLFieldSize(tempbuffertype,field_length);\n    if largeblobparameter then\n    begin\n      is_Null := 0;\n      buffer := nil;\n    end\n    else if field_length = 0 then\n    begin\n      is_Null := 1;\n      buffer := nil;\n    end\n    else\n    begin\n      if tempbuffertype in [FIELD_TYPE_TINY_BLOB, FIELD_TYPE_MEDIUM_BLOB,\n           FIELD_TYPE_LONG_BLOB, FIELD_TYPE_BLOB, FIELD_TYPE_VAR_STRING, FIELD_TYPE_STRING] then\n      //ludob: mysql adds terminating #0 on top of data. Avoid buffer overrun.\n        SetLength(buffer,length+1)\n      else\n        SetLength(buffer,length);\n      is_null := 0;\n    end;\n  end;\n  ColOffset:=NativeUInt((FAddedColumnCount-1)*FBindOffsets.size);\n  PTMysqlFieldTypes(@FbindArray[ColOffset+FBindOffsets.buffer_type])^:=tempbuffertype;\n  PULong(@FbindArray[ColOffset+FBindOffsets.buffer_length])^ := FPColumnArray^[FAddedColumnCount-1].length;\n  PByte(@FbindArray[ColOffset+FBindOffsets.is_unsigned])^:= 0;\n  PPointer(@FbindArray[ColOffset+FBindOffsets.buffer])^:= @FPColumnArray^[FAddedColumnCount-1].buffer[0];\n  PPointer(@FbindArray[ColOffset+FBindOffsets.length])^:= @FPColumnArray^[FAddedColumnCount-1].length;\n  PPointer(@FbindArray[ColOffset+FBindOffsets.is_null])^:= @FPColumnArray^[FAddedColumnCount-1].is_null;\nend;\n\nend.\n"
  },
  {
    "path": "lib/zeosdbo/src/dbc/ZDbcMySqlUtils.pas",
    "content": "{*********************************************************}\n{                                                         }\n{                 Zeos Database Objects                   }\n{           MySQL Database Connectivity Classes           }\n{                                                         }\n{         Originally written by Sergey Seroukhov          }\n{                           and Sergey Merkuriev          }\n{                                                         }\n{*********************************************************}\n\n{@********************************************************}\n{    Copyright (c) 1999-2012 Zeos Development Group       }\n{                                                         }\n{ License Agreement:                                      }\n{                                                         }\n{ This library is distributed in the hope that it will be }\n{ useful, but WITHOUT ANY WARRANTY; without even the      }\n{ implied warranty of MERCHANTABILITY or FITNESS FOR      }\n{ A PARTICULAR PURPOSE.  See the GNU Lesser General       }\n{ Public License for more details.                        }\n{                                                         }\n{ The source code of the ZEOS Libraries and packages are  }\n{ distributed under the Library GNU General Public        }\n{ License (see the file COPYING / COPYING.ZEOS)           }\n{ with the following  modification:                       }\n{ As a special exception, the copyright holders of this   }\n{ library give you permission to link this library with   }\n{ independent modules to produce an executable,           }\n{ regardless of the license terms of these independent    }\n{ modules, and to copy and distribute the resulting       }\n{ executable under terms of your choice, provided that    }\n{ you also meet, for each linked independent module,      }\n{ the terms and conditions of the license of that module. }\n{ An independent module is a module which is not derived  }\n{ from or based on this library. If you modify this       }\n{ library, you may extend this exception to your version  }\n{ of the library, but you are not obligated to do so.     }\n{ If you do not wish to do so, delete this exception      }\n{ statement from your version.                            }\n{                                                         }\n{                                                         }\n{ The project web site is located on:                     }\n{   http://zeos.firmos.at  (FORUM)                        }\n{   http://sourceforge.net/p/zeoslib/tickets/ (BUGTRACKER)}\n{   svn://svn.code.sf.net/p/zeoslib/code-0/trunk (SVN)    }\n{                                                         }\n{   http://www.sourceforge.net/projects/zeoslib.          }\n{                                                         }\n{                                                         }\n{                                 Zeos Development Group. }\n{********************************************************@}\n\nunit ZDbcMySqlUtils;\n\ninterface\n\n{$I ZDbc.inc}\n\nuses\n  Classes, {$IFDEF MSEgui}mclasses,{$ENDIF} SysUtils, StrUtils,\n  ZSysUtils, ZDbcIntfs, ZPlainMySqlDriver, ZPlainMySqlConstants, ZDbcLogging,\n  ZCompatibility, ZDbcResultSetMetadata;\n\nconst\n  MAXBUF = 65535;\n\ntype\n  {** Silent exception }\n  EZMySQLSilentException = class(EAbort);\n\n{**\n  Converts a MySQL native types into ZDBC SQL types.\n  @param PlainDriver a native MySQL plain driver.\n  @param FieldHandle a handler to field description structure.\n  @param FieldFlags field flags.\n  @return a SQL undepended type.\n}\nfunction ConvertMySQLHandleToSQLType(PlainDriver: IZMySQLPlainDriver;\n  FieldHandle: PZMySQLField; FieldFlags: Integer;\n  const CtrlsCPType: TZControlsCodePage): TZSQLType;\n\n{**\n  Convert string mysql field type to SQLType\n  @param string field type value\n  @result the SQLType field type value\n}\nfunction ConvertMySQLTypeToSQLType(TypeName, TypeNameFull: string;\n  const CtrlsCPType: TZControlsCodePage): TZSQLType;\n\n{**\n  Checks for possible sql errors.\n  @param PlainDriver a MySQL plain driver.\n  @param Handle a MySQL connection handle.\n  @param LogCategory a logging category.\n  @param LogMessage a logging message.\n}\nprocedure CheckMySQLError(PlainDriver: IZMySQLPlainDriver;\n  Handle: PZMySQLConnect; LogCategory: TZLoggingCategory; const LogMessage: string);\nprocedure CheckMySQLPrepStmtError(PlainDriver: IZMySQLPlainDriver;\n  Handle: PZMySQLConnect; LogCategory: TZLoggingCategory; const LogMessage: string);\nprocedure EnterSilentMySQLError;\nprocedure LeaveSilentMySQLError;\n\n{**\n  Decodes a MySQL Version Value encoded with format:\n   (major_version * 10,000) + (minor_version * 100) + sub_version\n  into separated major, minor and subversion values\n  @param MySQLVersion an integer containing the MySQL Full Version to decode.\n  @param MajorVersion an integer containing the Major Version decoded.\n  @param MinorVersion an integer containing the Minor Version decoded.\n  @param SubVersion an integer contaning the Sub Version (revision) decoded.\n}\nprocedure DecodeMySQLVersioning(const MySQLVersion: Integer;\n out MajorVersion: Integer; out MinorVersion: Integer;\n out SubVersion: Integer);\n\n{**\n  Encodes major, minor and subversion (revision) values in MySQL format:\n   (major_version * 10,000) + (minor_version * 100) + sub_version\n  For example, 4.1.12 is returned as 40112.\n  @param MajorVersion an integer containing the Major Version.\n  @param MinorVersion an integer containing the Minor Version.\n  @param SubVersion an integer containing the Sub Version (revision).\n  @return an integer containing the full version.\n}\nfunction EncodeMySQLVersioning(const MajorVersion: Integer;\n const MinorVersion: Integer; const SubVersion: Integer): Integer;\n\n{**\n  Decodes a MySQL Version Value and Encodes it to a Zeos SQL Version format:\n   (major_version * 1,000,000) + (minor_version * 1,000) + sub_version\n  into separated major, minor and subversion values\n  @param MySQLVersion an integer containing the Full Version to decode.\n  @return Encoded Zeos SQL Version Value.\n}\nfunction ConvertMySQLVersionToSQLVersion( const MySQLVersion: Integer ): Integer;\n\nfunction getMySQLFieldSize (field_type: TMysqlFieldTypes; field_size: LongWord): LongWord;\n\n{**\n  Returns a valid TZColumnInfo from a FieldHandle\n  @param PlainDriver the MySQL PlainDriver interface\n  @param FieldHandle the handle of the fetched field\n  @returns a new TZColumnInfo\n}\nfunction GetMySQLColumnInfoFromFieldHandle(PlainDriver: IZMySQLPlainDriver;\n  const FieldHandle: PZMySQLField; ConSettings: PZConSettings;\n  const bUseResult:boolean): TZColumnInfo;\n\nprocedure ConvertMySQLColumnInfoFromString(const TypeInfo: String;\n  ConSettings: PZConSettings; out TypeName, TypeInfoSecond: String;\n  out FieldType: TZSQLType; out ColumnSize: Integer; out Precision: Integer);\n\nimplementation\n\nuses ZMessages, Math, ZDbcUtils;\n\nthreadvar\n  SilentMySQLError: Integer;\n\nprocedure EnterSilentMySQLError;\nbegin\n  Inc(SilentMySQLError);\nend;\n\nprocedure LeaveSilentMySQLError;\nbegin\n  Dec(SilentMySQLError);\nend;\n\n{**\n  Converts a MySQL native types into ZDBC SQL types.\n  @param PlainDriver a native MySQL plain driver.\n  @param FieldHandle a handler to field description structure.\n  @param FieldFlags a field flags.\n  @return a SQL undepended type.\n}\nfunction ConvertMySQLHandleToSQLType(PlainDriver: IZMySQLPlainDriver;\n  FieldHandle: PZMySQLField; FieldFlags: Integer;\n  const CtrlsCPType: TZControlsCodePage): TZSQLType;\n\n  function Signed: Boolean;\n  begin\n    Result := (UNSIGNED_FLAG and FieldFlags) = 0;\n  end;\n\nbegin\n    case PlainDriver.GetFieldType(FieldHandle) of\n    FIELD_TYPE_TINY:\n      if not Signed and (PlainDriver.GetFieldLength(FieldHandle)=1) then\n         Result := stByte\n      else\n         Result := stShort;\n    FIELD_TYPE_YEAR, FIELD_TYPE_SHORT:\n      if Signed then\n         Result := stShort\n      else\n         Result := stInteger;\n    FIELD_TYPE_INT24, FIELD_TYPE_LONG:\n      if Signed then\n         Result := stInteger\n      else\n         Result := stLong;\n    FIELD_TYPE_LONGLONG:\n      if Signed then\n         Result := stLong\n      else\n         Result := stBigDecimal;\n    FIELD_TYPE_FLOAT:\n      Result := stDouble;\n    FIELD_TYPE_DECIMAL, FIELD_TYPE_NEWDECIMAL: {ADDED FIELD_TYPE_NEWDECIMAL by fduenas 20-06-2006}\n      if PlainDriver.GetFieldDecimals(FieldHandle) = 0 then\n        if PlainDriver.GetFieldLength(FieldHandle) < 11 then\n          Result := stInteger\n        else\n          Result := stLong\n      else\n        Result := stDouble;\n    FIELD_TYPE_DOUBLE:\n      Result := stDouble;\n    FIELD_TYPE_DATE, FIELD_TYPE_NEWDATE:\n      Result := stDate;\n    FIELD_TYPE_TIME:\n      Result := stTime;\n    FIELD_TYPE_DATETIME, FIELD_TYPE_TIMESTAMP:\n      Result := stTimestamp;\n    FIELD_TYPE_TINY_BLOB, FIELD_TYPE_MEDIUM_BLOB,\n    FIELD_TYPE_LONG_BLOB, FIELD_TYPE_BLOB:\n      if (FieldFlags and BINARY_FLAG) = 0 then\n        If ( CtrlsCPType = cCP_UTF16) then\n          Result := stUnicodeStream\n        else\n          Result := stAsciiStream\n      else\n        Result := stBinaryStream;\n    FIELD_TYPE_BIT:\n      Result := stShort;\n    FIELD_TYPE_VARCHAR,\n    FIELD_TYPE_VAR_STRING,\n    FIELD_TYPE_STRING:\n      if (FieldFlags and BINARY_FLAG) = 0 then\n        if ( CtrlsCPType = cCP_UTF16) then\n          Result := stUnicodeString\n        else\n          Result := stString\n      else\n        Result := stBytes;\n    FIELD_TYPE_ENUM:\n      Result := stString;\n    FIELD_TYPE_SET:\n      Result := stString;\n    FIELD_TYPE_NULL:\n      // Example: SELECT NULL FROM DUAL\n      Result := stString;\n   FIELD_TYPE_GEOMETRY:\n      // Todo: Would be nice to show as WKT.\n      Result := stBinaryStream;\n   else\n      raise Exception.Create('Unknown MySQL data type!');\n   end;\nend;\n\n{**\n  Convert string mysql field type to SQLType\n  @param string field type value\n  @result the SQLType field type value\n}\nfunction ConvertMySQLTypeToSQLType(TypeName, TypeNameFull: string;\n  const CtrlsCPType: TZControlsCodePage): TZSQLType;\nconst\n  GeoTypes: array[0..7] of string = (\n   'POINT','LINESTRING','POLYGON','GEOMETRY',\n   'MULTIPOINT','MULTILINESTRING','MULTIPOLYGON','GEOMETRYCOLLECTION'\n  );\nvar\n  IsUnsigned: Boolean;\n  Posi, Len, i: Integer;\n  Spec: string;\nbegin\n  TypeName := UpperCase(TypeName);\n  TypeNameFull := UpperCase(TypeNameFull);\n  Result := stUnknown;\n\n  Posi := FirstDelimiter(' ', TypeName);\n  if Posi > 0 then\n    TypeName := Copy(TypeName, 1, Posi - 1);\n\n  Spec := '';\n  Posi := FirstDelimiter(' ', TypeNameFull);\n  if Posi > 0 then\n    Spec := Copy(TypeNameFull, Posi + 1, Length(TypeNameFull)-Posi);\n\n  IsUnsigned := Pos('UNSIGNED', Spec) > 0;\n\n  if TypeName = 'TINYINT' then\n  begin\n    if not IsUnsigned then\n      Result := stShort\n    else\n      Result := stByte;\n  end\n  else if TypeName = 'YEAR' then\n    Result := stShort\n  else if TypeName = 'SMALLINT' then\n  begin\n    if IsUnsigned then\n      Result := stInteger\n    else\n      Result := stShort;\n  end\n  else if TypeName = 'MEDIUMINT' then\n    Result := stInteger\n  else if (TypeName = 'INT') or (TypeName = 'INTEGER') then\n  begin\n      if IsUnsigned then\n         Result := stLong\n      else\n         Result := stInteger\n  end\n  else if TypeName = 'BIGINT' then\n    Result := stLong\n  else if TypeName = 'INT24' then\n    Result := stLong\n  else if TypeName = 'REAL' then\n  begin\n    if IsUnsigned then\n      Result := stDouble\n    else\n      Result := stFloat;\n  end\n  else if TypeName = 'FLOAT' then\n  begin\n//    if IsUnsigned then\n      Result := stDouble\n//    else Result := stFloat;\n  end\n  else if TypeName = 'DECIMAL' then\n  begin\n    if EndsWith(TypeNameFull, ',0)') then\n    begin\n      Len := StrToInt(Copy(TypeNameFull, 9, Length(TypeNameFull) - 11));\n      if Len < 10 then\n        Result := stInteger\n      else\n        Result := stLong;\n    end\n    else\n      Result := stDouble;\n  end\n  else if TypeName = 'DOUBLE' then\n    Result := stDouble\n  else if TypeName = 'CHAR' then\n    Result := stString\n  else if TypeName = 'VARCHAR' then\n    Result := stString\n  else if TypeName = 'VARBINARY' then\n    Result := stBytes\n  else if TypeName = 'BINARY' then\n    Result := stBytes\n  else if TypeName = 'DATE' then\n    Result := stDate\n  else if TypeName = 'TIME' then\n    Result := stTime\n  else if TypeName = 'TIMESTAMP' then\n    Result := stTimestamp\n  else if TypeName = 'DATETIME' then\n    Result := stTimestamp\n  else if TypeName = 'TINYBLOB' then\n    Result := stBinaryStream\n  else if TypeName = 'BLOB' then\n    Result := stBinaryStream\n  else if TypeName = 'MEDIUMBLOB' then\n    Result := stBinaryStream\n  else if TypeName = 'LONGBLOB' then\n    Result := stBinaryStream\n  else if TypeName = 'TINYTEXT' then\n    Result := stAsciiStream\n  else if TypeName = 'TEXT' then\n    Result := stAsciiStream\n  else if TypeName = 'MEDIUMTEXT' then\n    Result := stAsciiStream\n  else if TypeName = 'LONGTEXT' then\n    Result := stAsciiStream\n  else if TypeName = 'ENUM' then\n  begin\n    if (TypeNameFull = 'ENUM(''Y'',''N'')')\n      or (TypeNameFull = 'ENUM(''N'',''Y'')') then\n      Result := stBoolean\n    else\n      Result := stString;\n  end\n  else if TypeName = 'SET' then\n    Result := stString\n  else if TypeName = 'BIT' then\n    Result := stShort\n  else\n      for i := 0 to Length(GeoTypes) - 1 do\n         if GeoTypes[i] = TypeName then\n            Result := stBinaryStream;\n\n  if ( CtrlsCPType = cCP_UTF16) then\n  case result of\n    stString: Result := stUnicodeString;\n    stAsciiStream: Result := stUnicodeStream;\n  end;\n\n  if Result = stUnknown then\n     raise Exception.Create('Unknown MySQL data type!');\nend;\n\n{**\n  Checks for possible sql errors.\n  @param PlainDriver a MySQL plain driver.\n  @param Handle a MySQL connection handle.\n  @param LogCategory a logging category.\n  @param LogMessage a logging message.\n}\nprocedure CheckMySQLError(PlainDriver: IZMySQLPlainDriver;\n  Handle: PZMySQLConnect; LogCategory: TZLoggingCategory; const LogMessage: string);\nvar\n  ErrorMessage: string;\n  ErrorCode: Integer;\nbegin\n  ErrorMessage := Trim(String(PlainDriver.GetLastError(Handle)));\n  ErrorCode := PlainDriver.GetLastErrorCode(Handle);\n  if (ErrorCode <> 0) and (ErrorMessage <> '') then\n  begin\n    if SilentMySQLError > 0 then\n      raise EZMySQLSilentException.CreateFmt(SSQLError1, [ErrorMessage]);\n\n    DriverManager.LogError(LogCategory, PlainDriver.GetProtocol, LogMessage,\n      ErrorCode, ErrorMessage);\n    raise EZSQLException.CreateWithCode(ErrorCode,\n      Format(SSQLError1, [ErrorMessage]));\n  end;\nend;\n\nprocedure CheckMySQLPrepStmtError(PlainDriver: IZMySQLPlainDriver;\n  Handle: PZMySQLConnect; LogCategory: TZLoggingCategory; const LogMessage: string);\nvar\n  ErrorMessage: string;\n  ErrorCode: Integer;\nbegin\n  ErrorMessage := Trim(String(PlainDriver.GetLastPreparedError(Handle)));\n  ErrorCode := PlainDriver.GetLastPreparedErrorCode(Handle);\n  if (ErrorCode <> 0) and (ErrorMessage <> '') then\n  begin\n    if SilentMySQLError > 0 then\n      raise EZMySQLSilentException.CreateFmt(SSQLError1, [ErrorMessage]);\n\n    DriverManager.LogError(LogCategory,PlainDriver.GetProtocol,LogMessage,ErrorCode, ErrorMessage);\n    raise EZSQLException.CreateWithCode(ErrorCode,\n      Format(SSQLError1, [ErrorMessage]));\n  end;\nend;\n\n{**\n  Decodes a MySQL Version Value encoded with format:\n   (major_version * 10,000) + (minor_version * 100) + sub_version\n  into separated major, minor and subversion values\n  @param MySQLVersion an integer containing the MySQL Full Version to decode.\n  @param MajorVersion an integer containing the Major Version decoded.\n  @param MinorVersion an integer containing the Minor Version decoded.\n  @param SubVersion an integer contaning the Sub Version (revision) decoded.\n}\nprocedure DecodeMySQLVersioning(const MySQLVersion: Integer;\n out MajorVersion: Integer; out MinorVersion: Integer;\n out SubVersion: Integer);\nbegin\n  MajorVersion := MySQLVersion div 10000;\n  MinorVersion := (MySQLVersion - (MajorVersion * 10000)) div 100;\n  SubVersion   := MySQLVersion-(MajorVersion*10000)-(MinorVersion*100);\nend;\n\n{**\n  Encodes major, minor and subversion (revision) values in MySQL format:\n   (major_version * 10,000) + (minor_version * 100) + sub_version\n  For example, 4.1.12 is returned as 40112.\n  @param MajorVersion an integer containing the Major Version.\n  @param MinorVersion an integer containing the Minor Version.\n  @param SubVersion an integer containing the Sub Version (revision).\n  @return an integer containing the full version.\n}\nfunction EncodeMySQLVersioning(const MajorVersion: Integer;\n const MinorVersion: Integer; const SubVersion: Integer): Integer;\nbegin\n Result := (MajorVersion * 10000) + (MinorVersion * 100) + SubVersion;\nend;\n\n{**\n  Decodes a MySQL Version Value and Encodes it to a Zeos SQL Version format:\n   (major_version * 1,000,000) + (minor_version * 1,000) + sub_version\n  into separated major, minor and subversion values\n  So it transforms a version in format XYYZZ to XYYYZZZ where:\n   X = major_version\n   Y = minor_version\n   Z = sub version\n  @param MySQLVersion an integer containing the Full MySQL Version to decode.\n  @return Encoded Zeos SQL Version Value.\n}\nfunction ConvertMySQLVersionToSQLVersion( const MySQLVersion: Integer ): integer;\nvar\n   MajorVersion, MinorVersion, SubVersion: Integer;\nbegin\n DecodeMySQLVersioning(MySQLVersion,MajorVersion,MinorVersion,SubVersion);\n Result := EncodeSQLVersioning(MajorVersion,MinorVersion,SubVersion);\nend;\n\nfunction getMySQLFieldSize (field_type: TMysqlFieldTypes; field_size: LongWord): LongWord;\nvar\n    FieldSize: LongWord;\nBegin\n    FieldSize := field_size;\n\n    case field_type of\n        FIELD_TYPE_TINY:        Result := 1;\n        FIELD_TYPE_SHORT:       Result := 2;\n        FIELD_TYPE_LONG:        Result := 4;\n        FIELD_TYPE_LONGLONG:    Result := 8;\n        FIELD_TYPE_FLOAT:       Result := 4;\n        FIELD_TYPE_DOUBLE:      Result := 8;\n        FIELD_TYPE_DATE:        Result := sizeOf(MYSQL_TIME);\n        FIELD_TYPE_TIME:        Result := sizeOf(MYSQL_TIME);\n        FIELD_TYPE_DATETIME:    Result := sizeOf(MYSQL_TIME);\n        FIELD_TYPE_TINY_BLOB:   Result := FieldSize; //stBytes\n        FIELD_TYPE_BLOB:        Result := FieldSize;\n        FIELD_TYPE_STRING:      Result := FieldSize;\n    else\n        Result := 255;  {unknown ??}\n    end;\nend;\n\n{**\n  Returns a valid TZColumnInfo from a FieldHandle\n  @param PlainDriver the MySQL PlainDriver interface\n  @param FieldHandle the handle of the fetched field\n  @returns a new TZColumnInfo\n}\nfunction GetMySQLColumnInfoFromFieldHandle(PlainDriver: IZMySQLPlainDriver;\n  const FieldHandle: PZMySQLField; ConSettings: PZConSettings;\n  const bUseResult:boolean): TZColumnInfo;\nvar\n  FieldFlags: Integer;\n  FieldLength: ULong;\nbegin\n  if Assigned(FieldHandle) then\n  begin\n    Result := TZColumnInfo.Create;\n    FieldFlags := PlainDriver.GetFieldFlags(FieldHandle);\n\n    Result.ColumnLabel := PlainDriver.ZDbcString(PlainDriver.GetFieldName(FieldHandle), ConSettings);\n    Result.ColumnName := PlainDriver.ZDbcString(PlainDriver.GetFieldOrigName(FieldHandle), ConSettings);\n    Result.TableName := PlainDriver.ZDbcString(PlainDriver.GetFieldTable(FieldHandle), ConSettings);\n    Result.ReadOnly := (PlainDriver.GetFieldTable(FieldHandle) = '');\n    Result.Writable := not Result.ReadOnly;\n    Result.ColumnType := ConvertMySQLHandleToSQLType(PlainDriver,\n        FieldHandle, FieldFlags, ConSettings.CPType);\n    FieldLength:=PlainDriver.GetFieldLength(FieldHandle);\n    //EgonHugeist: arrange the MBCS field DisplayWidth to a proper count of Chars\n    if Result.ColumnType in [stString, stUnicodeString] then\n       case PlainDriver.GetFieldCharsetNr(FieldHandle) of\n        1, 84, {Big5}\n        95, 96, {cp932 japanese}\n        19, 85, {euckr}\n        24, 86, {gb2312}\n        38, 87, {gbk}\n        13, 88, {sjis}\n        35, 90, 128..151:  {ucs2}\n          begin\n            Result.ColumnDisplaySize := (FieldLength div 4);\n            Result.Precision := GetFieldSize(Result.ColumnType, ConSettings,\n              Result.ColumnDisplaySize, 2, nil);\n          end;\n        33, 83, 192..215, { utf8 }\n        97, 98, { eucjpms}\n        12, 91: {ujis}\n          begin\n            Result.ColumnDisplaySize := (FieldLength div 3);\n            Result.Precision := GetFieldSize(Result.ColumnType,\n              ConSettings, Result.ColumnDisplaySize, 3, nil);\n          end;\n        54, 55, 101..124, {utf16}\n        56, 62, {utf16le}\n        60, 61, 160..183, {utf32}\n        45, 46, 224..247: {utf8mb4}\n          begin\n            Result.ColumnDisplaySize := (FieldLength div 4);\n            Result.Precision := GetFieldSize(Result.ColumnType,\n              ConSettings, Result.ColumnDisplaySize, 4, nil);\n          end;\n        else //1-Byte charsets\n        begin\n          Result.ColumnDisplaySize := FieldLength;\n          Result.Precision := GetFieldSize(Result.ColumnType,\n            ConSettings, Result.ColumnDisplaySize, 1, nil);\n        end;\n      end\n    else\n      Result.Precision := min(MaxBlobSize,FieldLength);\n\n    if PlainDriver.GetFieldType(FieldHandle) in [FIELD_TYPE_BLOB,FIELD_TYPE_MEDIUM_BLOB,FIELD_TYPE_LONG_BLOB,FIELD_TYPE_STRING,\n      FIELD_TYPE_VAR_STRING] then\n      begin\n      if bUseResult then  //PMYSQL_FIELD(Field)^.max_length not valid\n        Result.MaxLenghtBytes:=Result.Precision\n      else\n        Result.MaxLenghtBytes:=PlainDriver.GetFieldMaxLength(FieldHandle);\n      end\n    else\n      Result.MaxLenghtBytes:=FieldLength;\n    Result.Scale := PlainDriver.GetFieldDecimals(FieldHandle);\n    if (AUTO_INCREMENT_FLAG and FieldFlags <> 0)\n      or (TIMESTAMP_FLAG and FieldFlags <> 0) then\n      Result.AutoIncrement := True;\n    if UNSIGNED_FLAG and FieldFlags <> 0 then\n      Result.Signed := False\n    else\n      Result.Signed := True;\n    if NOT_NULL_FLAG and FieldFlags <> 0 then\n      Result.Nullable := ntNoNulls\n    else\n      Result.Nullable := ntNullable;\n    // Properties not set via query results here will be fetched from table metadata.\n  end\n  else\n    Result := nil;\nend;\n\nprocedure ConvertMySQLColumnInfoFromString(const TypeInfo: String;\n  ConSettings: PZConSettings; out TypeName, TypeInfoSecond:\n  String; out FieldType: TZSQLType; out ColumnSize: Integer; out Precision: Integer);\nvar\n  TypeInfoList: TStrings;\n  TypeInfoFirst: String;\n  J, TempPos: Integer;\nbegin\n  TypeInfoList := TStringList.Create;\n  TypeInfoFirst := '';\n  TypeInfoSecond := '';\n  Precision := 0;\n  ColumnSize := 0;\n\n  if StrPos(PChar(TypeInfo), '(') <> nil then\n  begin\n    PutSplitString(TypeInfoList, TypeInfo, '()');\n    TypeInfoFirst := TypeInfoList.Strings[0];\n    TypeInfoSecond := TypeInfoList.Strings[1];\n  end\n  else\n    TypeInfoFirst := TypeInfo;\n\n  TypeInfoFirst := LowerCase(TypeInfoFirst);\n  TypeName := TypeInfoFirst;\n\n  FieldType := ConvertMySQLTypeToSQLType(TypeInfoFirst, TypeInfo, Consettings.CPType);\n  { the column type is ENUM}\n  if TypeInfoFirst = 'enum' then\n  begin\n    PutSplitString(TypeInfoList, TypeInfoSecond, ',');\n    for J := 0 to TypeInfoList.Count-1 do\n      ColumnSize := Max(ColumnSize, Length(TypeInfoList.Strings[J]));\n  end\n  else\n    { the column type is decimal }\n    if ( Pos(',', TypeInfoSecond) > 0 ) and not ( TypeInfoFirst = 'set' ) then\n    begin\n      TempPos := FirstDelimiter(',', TypeInfoSecond);\n      ColumnSize := StrToIntDef(Copy(TypeInfoSecond, 1, TempPos - 1), 0);\n      Precision := StrToIntDef(Copy(TypeInfoSecond, TempPos + 1,\n        Length(TypeInfoSecond) - TempPos), 0);\n    end\n    else\n    begin\n      { the column type is other }\n       if (TypeInfoSecond <> '') and not (TypeInfoFirst = 'set') then\n          ColumnSize := StrToIntDef(TypeInfoSecond, 0)\n       else if TypeInfoFirst = 'tinyint' then\n          ColumnSize := 1\n       else if TypeInfoFirst = 'smallint' then\n          ColumnSize := 6\n       else if TypeInfoFirst = 'mediumint' then\n          ColumnSize := 6\n       else if TypeInfoFirst = 'int' then\n          ColumnSize := 11\n       else if TypeInfoFirst = 'integer' then\n          ColumnSize := 11\n       else if TypeInfoFirst = 'bigint' then\n          ColumnSize := 25\n       else if TypeInfoFirst = 'int24' then\n          ColumnSize := 25\n       else if TypeInfoFirst = 'real' then\n          ColumnSize := 12\n       else if TypeInfoFirst = 'float' then\n          ColumnSize := 12\n       else if TypeInfoFirst = 'decimal' then\n          ColumnSize := 12\n       else if TypeInfoFirst = 'numeric' then\n          ColumnSize := 12\n       else if TypeInfoFirst = 'double' then\n          ColumnSize := 22\n       else if TypeInfoFirst = 'char' then\n          ColumnSize := 1\n       else if TypeInfoFirst = 'varchar' then\n          ColumnSize := 255\n       else if TypeInfoFirst = 'date' then\n          ColumnSize := 10\n       else if TypeInfoFirst = 'time' then\n          ColumnSize := 8\n       else if TypeInfoFirst = 'timestamp' then\n          ColumnSize := 19\n       else if TypeInfoFirst = 'datetime' then\n          ColumnSize := 19\n       else if TypeInfoFirst = 'tinyblob' then\n          ColumnSize := 255\n       else if TypeInfoFirst = 'blob' then\n          ColumnSize := MAXBUF\n       else if TypeInfoFirst = 'mediumblob' then\n          ColumnSize := 16277215//may be 65535\n       else if TypeInfoFirst = 'longblob' then\n          ColumnSize := High(Integer)//2147483657//may be 65535\n       else if TypeInfoFirst = 'tinytext' then\n          ColumnSize := 255\n       else if TypeInfoFirst = 'text' then\n          ColumnSize := 65535\n       else if TypeInfoFirst = 'mediumtext' then\n          ColumnSize := 16277215 //may be 65535\n       else if TypeInfoFirst = 'enum' then\n          ColumnSize := 255\n       else if TypeInfoFirst = 'set' then\n          ColumnSize := 255;\n    end;\n    if FieldType in [stString, stUnicodeString] then\n      ColumnSize := GetFieldSize(FieldType, consettings, ColumnSize,\n        ConSettings.ClientCodePage.CharWidth, nil);\n\n  FreeAndNil(TypeInfoList);\nend;\n\nend.\n"
  },
  {
    "path": "lib/zeosdbo/src/dbc/ZDbcOracle.pas",
    "content": "{*********************************************************}\n{                                                         }\n{                 Zeos Database Objects                   }\n{           Oracle Database Connectivity Classes          }\n{                                                         }\n{        Originally written by Sergey Seroukhov           }\n{                                                         }\n{*********************************************************}\n\n{@********************************************************}\n{    Copyright (c) 1999-2012 Zeos Development Group       }\n{                                                         }\n{ License Agreement:                                      }\n{                                                         }\n{ This library is distributed in the hope that it will be }\n{ useful, but WITHOUT ANY WARRANTY; without even the      }\n{ implied warranty of MERCHANTABILITY or FITNESS FOR      }\n{ A PARTICULAR PURPOSE.  See the GNU Lesser General       }\n{ Public License for more details.                        }\n{                                                         }\n{ The source code of the ZEOS Libraries and packages are  }\n{ distributed under the Library GNU General Public        }\n{ License (see the file COPYING / COPYING.ZEOS)           }\n{ with the following  modification:                       }\n{ As a special exception, the copyright holders of this   }\n{ library give you permission to link this library with   }\n{ independent modules to produce an executable,           }\n{ regardless of the license terms of these independent    }\n{ modules, and to copy and distribute the resulting       }\n{ executable under terms of your choice, provided that    }\n{ you also meet, for each linked independent module,      }\n{ the terms and conditions of the license of that module. }\n{ An independent module is a module which is not derived  }\n{ from or based on this library. If you modify this       }\n{ library, you may extend this exception to your version  }\n{ of the library, but you are not obligated to do so.     }\n{ If you do not wish to do so, delete this exception      }\n{ statement from your version.                            }\n{                                                         }\n{                                                         }\n{ The project web site is located on:                     }\n{   http://zeos.firmos.at  (FORUM)                        }\n{   http://sourceforge.net/p/zeoslib/tickets/ (BUGTRACKER)}\n{   svn://svn.code.sf.net/p/zeoslib/code-0/trunk (SVN)    }\n{                                                         }\n{   http://www.sourceforge.net/projects/zeoslib.          }\n{                                                         }\n{                                                         }\n{                                 Zeos Development Group. }\n{********************************************************@}\n\nunit ZDbcOracle;\n\ninterface\n\n{$I ZDbc.inc}\n\nuses\n  Types, Classes, {$IFDEF MSEgui}mclasses,{$ENDIF} SysUtils, Contnrs,\n  ZCompatibility, ZDbcIntfs, ZDbcConnection, ZPlainOracleDriver, ZDbcLogging,\n  ZTokenizer, ZDbcGenericResolver, ZURL, ZGenericSqlAnalyser,\n  ZPlainOracleConstants;\n\ntype\n\n  {** Implements Oracle Database Driver. }\n  {$WARNINGS OFF}\n  TZOracleDriver = class(TZAbstractDriver)\n  public\n    constructor Create; override;\n    function Connect(const Url: TZURL): IZConnection; override;\n    function GetMajorVersion: Integer; override;\n    function GetMinorVersion: Integer; override;\n\n    function GetTokenizer: IZTokenizer; override;\n    function GetStatementAnalyser: IZStatementAnalyser; override;\n  end;\n  {$WARNINGS ON}\n\n  {** Represents a Oracle specific connection interface. }\n  IZOracleConnection = interface (IZConnection)\n    ['{C7F36FDF-8A64-477B-A0EB-3E8AB7C09F8D}']\n\n    function GetPlainDriver: IZOraclePlainDriver;\n    function GetConnectionHandle: POCIEnv;\n    function GetContextHandle: POCISvcCtx;\n    function GetErrorHandle: POCIError;\n    function GetServerHandle: POCIServer;\n    function GetSessionHandle: POCISession;\n    function GetTransactionHandle: POCITrans;\n    function GetDescribeHandle: POCIDescribe;\n  end;\n\n  {** Implements Oracle Database Connection. }\n  TZOracleConnection = class(TZAbstractConnection, IZOracleConnection)\n  private\n    FCatalog: string;\n    FHandle: POCIEnv;\n    FContextHandle: POCISvcCtx;\n    FErrorHandle: POCIError;\n    FServerHandle: POCIServer;\n    FSessionHandle: POCISession;\n    FTransHandle: POCITrans;\n    FDescibeHandle: POCIDescribe;\n  protected\n    procedure InternalCreate; override;\n    procedure StartTransactionSupport;\n\n  public\n    destructor Destroy; override;\n\n    function CreateRegularStatement(Info: TStrings): IZStatement; override;\n    function CreatePreparedStatement(const SQL: string; Info: TStrings):\n      IZPreparedStatement; override;\n\n    function CreateCallableStatement(const SQL: string; Info: TStrings):\n      IZCallableStatement; override;\n\n    procedure Commit; override;\n    procedure Rollback; override;\n\n    function PingServer: Integer; override;\n\n    procedure Open; override;\n    procedure Close; override;\n\n    procedure SetCatalog(const Catalog: string); override;\n    function GetCatalog: string; override;\n\n    procedure SetTransactionIsolation(Level: TZTransactIsolationLevel); override;\n    function CreateSequence(const Sequence: string; BlockSize: Integer): IZSequence; override;\n\n    function GetPlainDriver: IZOraclePlainDriver;\n    function GetConnectionHandle: POCIEnv;\n    function GetContextHandle: POCISvcCtx;\n    function GetErrorHandle: POCIError;\n    function GetServerHandle: POCIServer;\n    function GetSessionHandle: POCISession;\n    function GetTransactionHandle: POCITrans;\n    function GetDescribeHandle: POCIDescribe;\n    function GetClientVersion: Integer; override;\n    function GetHostVersion: Integer; override;\n    function GetBinaryEscapeString(const Value: TByteDynArray): String; overload; override;\n    function GetBinaryEscapeString(const Value: RawByteString): String; overload; override;\n  end;\n\n  TZOracleSequence = class(TZAbstractSequence)\n  public\n    function GetCurrentValue: Int64; override;\n    function GetCurrentValueSQL: String; override;\n    function GetNextValue: Int64; override;\n    function GetNextValueSQL: String; override;\n  end;\n\n  {** Implements a specialized cached resolver for Oracle. }\n  TZOracleCachedResolver = class(TZGenericCachedResolver)\n  public\n    function FormCalculateStatement(Columns: TObjectList): string; override;\n  end;\n\nvar\n  {** The common driver manager object. }\n  OracleDriver: IZDriver;\n\nimplementation\n\nuses\n  ZMessages, ZGenericSqlToken, ZDbcOracleStatement, ZSysUtils, ZDbcUtils,\n  ZDbcOracleUtils, ZDbcOracleMetadata, ZOracleToken, ZOracleAnalyser;\n\n{ TZOracleDriver }\n\n{**\n  Constructs this object with default properties.\n}\nconstructor TZOracleDriver.Create;\nbegin\n  inherited Create;\n  AddSupportedProtocol(AddPlainDriverToCache(TZOracle9iPlainDriver.Create, 'oracle'));\n  AddSupportedProtocol(AddPlainDriverToCache(TZOracle9iPlainDriver.Create));\nend;\n\n{**\n  Attempts to make a database connection to the given URL.\n  The driver should return \"null\" if it realizes it is the wrong kind\n  of driver to connect to the given URL.  This will be common, as when\n  the JDBC driver manager is asked to connect to a given URL it passes\n  the URL to each loaded driver in turn.\n\n  <P>The driver should raise a SQLException if it is the right\n  driver to connect to the given URL, but has trouble connecting to\n  the database.\n\n  <P>The java.util.Properties argument can be used to passed arbitrary\n  string tag/value pairs as connection arguments.\n  Normally at least \"user\" and \"password\" properties should be\n  included in the Properties.\n\n  @param url the URL of the database to which to connect\n  @param info a list of arbitrary string tag/value pairs as\n    connection arguments. Normally at least a \"user\" and\n    \"password\" property should be included.\n  @return a <code>Connection</code> object that represents a\n    connection to the URL\n}\n{$WARNINGS OFF}\nfunction TZOracleDriver.Connect(const Url: TZURL): IZConnection;\nbegin\n  Result := TZOracleConnection.Create(Url);\nend;\n{$WARNINGS ON}\n\n{**\n  Gets the driver's major version number. Initially this should be 1.\n  @return this driver's major version number\n}\nfunction TZOracleDriver.GetMajorVersion: Integer;\nbegin\n  Result := 1;\nend;\n\n{**\n  Gets the driver's minor version number. Initially this should be 0.\n  @return this driver's minor version number\n}\nfunction TZOracleDriver.GetMinorVersion: Integer;\nbegin\n  Result := 0;\nend;\n\n{**\n  Gets a SQL syntax tokenizer.\n  @returns a SQL syntax tokenizer object.\n}\nfunction TZOracleDriver.GetTokenizer: IZTokenizer;\nbegin\n  if Tokenizer = nil then\n    Tokenizer := TZOracleTokenizer.Create;\n  Result := Tokenizer;\nend;\n\n{**\n  Creates a statement analyser object.\n  @returns a statement analyser object.\n}\nfunction TZOracleDriver.GetStatementAnalyser: IZStatementAnalyser;\nbegin\n  if Analyser = nil then\n    Analyser := TZOracleStatementAnalyser.Create;\n  Result := Analyser;\nend;\n\n{ TZOracleConnection }\n\n{**\n  Constructs this object and assignes the main properties.\n}\nprocedure TZOracleConnection.InternalCreate;\nbegin\n  FMetaData := TZOracleDatabaseMetadata.Create(Self, URL);\n  FHandle := nil;\n\n  { Sets a default properties }\n  if Self.Port = 0 then\n      Self.Port := 1521;\n  AutoCommit := True;\n  TransactIsolationLevel := tiNone;\n  Open;\nend;\n\nfunction TZOracleConnection.CreateCallableStatement(const SQL: string;\n  Info: TStrings): IZCallableStatement;\nbegin\n  if IsClosed then\n     Open;\n  Result := TZOracleCallableStatement.Create(Self, SQL, Info);\n  Result.ClearParameters;\nend;\n\n{**\n  Destroys this object and cleanups the memory.\n}\ndestructor TZOracleConnection.Destroy;\nbegin\n  if not IsClosed then\n     Close;\n\n  if FHandle <> nil then\n  begin\n    GetPlainDriver.HandleFree(FHandle, OCI_HTYPE_ENV);\n    FHandle := nil;\n  end;\n\n  inherited Destroy;\nend;\n\n{**\n  Opens a connection to database server with specified parameters.\n}\nprocedure TZOracleConnection.Open;\nvar\n  Status: Integer;\n  LogMessage: string;\n  OCI_CLIENT_CHARSET_ID,  OCI_CLIENT_NCHARSET_ID: ub2;\n\n  procedure CleanupOnFail;\n  begin\n    GetPlainDriver.HandleFree(FDescibeHandle, OCI_HTYPE_DESCRIBE);\n    FDescibeHandle := nil;\n    GetPlainDriver.HandleFree(FContextHandle, OCI_HTYPE_SVCCTX);\n    FContextHandle := nil;\n    GetPlainDriver.HandleFree(FErrorHandle, OCI_HTYPE_ERROR);\n    FErrorHandle := nil;\n    GetPlainDriver.HandleFree(FServerHandle, OCI_HTYPE_SERVER);\n    FServerHandle := nil;\n  end;\n\nbegin\n  if not Closed then\n     Exit;\n\n  LogMessage := Format('CONNECT TO \"%s\" AS USER \"%s\"', [Database, User]);\n\n  { Sets a default port number. }\n  if Port = 0 then\n     Port := 1521;\n\n  { Sets a client codepage. }\n  OCI_CLIENT_CHARSET_ID := ConSettings.ClientCodePage^.ID;\n  { Connect to Oracle database. }\n  if ( FHandle = nil ) then\n    try\n      FErrorHandle := nil;\n      Status := GetPlainDriver.EnvNlsCreate(FHandle, OCI_OBJECT, nil, nil, nil, nil, 0, nil,\n        OCI_CLIENT_CHARSET_ID, OCI_CLIENT_CHARSET_ID);\n      CheckOracleError(GetPlainDriver, FErrorHandle, Status, lcOther, 'EnvNlsCreate failed.');\n    except\n      raise;\n    end;\n  FErrorHandle := nil;\n  GetPlainDriver.HandleAlloc(FHandle, FErrorHandle, OCI_HTYPE_ERROR, 0, nil);\n  FServerHandle := nil;\n  GetPlainDriver.HandleAlloc(FHandle, FServerHandle, OCI_HTYPE_SERVER, 0, nil);\n  FContextHandle := nil;\n  GetPlainDriver.HandleAlloc(FHandle, FContextHandle, OCI_HTYPE_SVCCTX, 0, nil);\n  FDescibeHandle := nil;\n  GetPlainDriver.HandleAlloc(FHandle, FDescibeHandle, OCI_HTYPE_DESCRIBE, 0, nil);\n\n  Status := GetPlainDriver.ServerAttach(FServerHandle, FErrorHandle,\n      PAnsiChar(ansistring(Database)), Length(AnsiString(Database)), 0);\n  try\n    CheckOracleError(GetPlainDriver, FErrorHandle, Status, lcConnect, LogMessage);\n  except\n    CleanupOnFail;\n    raise;\n  end;\n\n  if OCI_CLIENT_CHARSET_ID = 0 then\n  begin\n    OCI_CLIENT_NCHARSET_ID := High(ub2);\n    GetPlainDriver.AttrGet(FHandle, OCI_HTYPE_ENV, @OCI_CLIENT_CHARSET_ID,\n      nil, OCI_ATTR_ENV_CHARSET_ID, FErrorHandle); //Get Server default CodePage\n    CheckCharEncoding(GetPlainDriver.ValidateCharEncoding(OCI_CLIENT_CHARSET_ID)^.Name);\n    if OCI_CLIENT_CHARSET_ID <> OCI_CLIENT_NCHARSET_ID then\n    begin\n      CleanupOnFail;\n      Open;\n      Exit;\n    end;\n  end;\n  if GetPlainDriver.GetEnvCharsetByteWidth(FHandle, FErrorHandle, ConSettings.ClientCodePage^.CharWidth) <> OCI_SUCCESS then\n    CheckOracleError(GetPlainDriver, FErrorHandle, Status, lcConnect, LogMessage);\n\n  GetPlainDriver.AttrSet(FContextHandle, OCI_HTYPE_SVCCTX, FServerHandle, 0,\n    OCI_ATTR_SERVER, FErrorHandle);\n  GetPlainDriver.HandleAlloc(FHandle, FSessionHandle, OCI_HTYPE_SESSION, 0, nil);\n  GetPlainDriver.AttrSet(FSessionHandle, OCI_HTYPE_SESSION, PAnsiChar(AnsiString(User)),\n    Length(User), OCI_ATTR_USERNAME, FErrorHandle);\n  GetPlainDriver.AttrSet(FSessionHandle, OCI_HTYPE_SESSION, PAnsiChar(AnsiString(Password)),\n    Length(Password), OCI_ATTR_PASSWORD, FErrorHandle);\n  Status := GetPlainDriver.SessionBegin(FContextHandle, FErrorHandle,\n    FSessionHandle, OCI_CRED_RDBMS, OCI_DEFAULT);\n  try\n    CheckOracleError(GetPlainDriver, FErrorHandle, Status, lcConnect, LogMessage);\n  except\n    CleanupOnFail;\n    raise;\n  end;\n  GetPlainDriver.AttrSet(FContextHandle, OCI_HTYPE_SVCCTX, FSessionHandle, 0,\n    OCI_ATTR_SESSION, FErrorHandle);\n  DriverManager.LogMessage(lcConnect, PlainDriver.GetProtocol, LogMessage);\n\n  StartTransactionSupport;\n\n  inherited Open;\nend;\n\n{**\n  Starts a transaction support.\n}\nprocedure TZOracleConnection.StartTransactionSupport;\nvar\n  SQL: PChar;\n  Status: Integer;\n  Isolation: Integer;\nbegin\n  if TransactIsolationLevel = tiNone then\n  begin\n    SQL := 'SET TRANSACTION ISOLATION LEVEL DEFAULT';\n    Isolation := OCI_DEFAULT;\n  end\n  else if TransactIsolationLevel = tiReadCommitted then\n  begin\n// Behaviour changed by mdaems 31/05/2006 : Read Committed is the default\n// isolation level used by oracle. This property should not be abused to add\n// the non-standard isolation level 'read only' thats invented by oracle.\n//    SQL := 'SET TRANSACTION ISOLATION LEVEL READONLY';\n//    Isolation := OCI_TRANS_READONLY;\n    SQL := 'SET TRANSACTION ISOLATION LEVEL DEFAULT';\n    Isolation := OCI_DEFAULT;\n  end\n  else if TransactIsolationLevel = tiRepeatableRead then\n  begin\n    SQL := 'SET TRANSACTION ISOLATION LEVEL READWRITE';\n    Isolation := OCI_TRANS_READWRITE;\n  end\n  else if TransactIsolationLevel = tiSerializable then\n  begin\n    SQL := 'SET TRANSACTION ISOLATION LEVEL SERIALIZABLE';\n    Isolation := OCI_TRANS_SERIALIZABLE;\n  end\n  else\n    raise EZSQLException.Create(SIsolationIsNotSupported);\n\n  FTransHandle := nil;\n  GetPlainDriver.HandleAlloc(FHandle, FTransHandle, OCI_HTYPE_TRANS, 0, nil);\n  GetPlainDriver.AttrSet(FContextHandle, OCI_HTYPE_SVCCTX, FTransHandle, 0,\n    OCI_ATTR_TRANS, FErrorHandle);\n\n  Status := GetPlainDriver.TransStart(FContextHandle, FErrorHandle, 0, Isolation);\n  CheckOracleError(GetPlainDriver, FErrorHandle, Status, lcExecute, SQL);\n\n  DriverManager.LogMessage(lcExecute, PlainDriver.GetProtocol, SQL);\nend;\n\n{**\n  Creates a <code>Statement</code> object for sending\n  SQL statements to the database.\n  SQL statements without parameters are normally\n  executed using Statement objects. If the same SQL statement\n  is executed many times, it is more efficient to use a\n  <code>PreparedStatement</code> object.\n  <P>\n  Result sets created using the returned <code>Statement</code>\n  object will by default have forward-only type and read-only concurrency.\n\n  @param Info a statement parameters.\n  @return a new Statement object\n}\nfunction TZOracleConnection.CreateRegularStatement(Info: TStrings):\n  IZStatement;\nbegin\n  if IsClosed then\n     Open;\n  Result := TZOracleStatement.Create(GetPlainDriver, Self, Info);\nend;\n\n{**\n  Creates a <code>PreparedStatement</code> object for sending\n  parameterized SQL statements to the database.\n\n  A SQL statement with or without IN parameters can be\n  pre-compiled and stored in a PreparedStatement object. This\n  object can then be used to efficiently execute this statement\n  multiple times.\n\n  <P><B>Note:</B> This method is optimized for handling\n  parametric SQL statements that benefit from precompilation. If\n  the driver supports precompilation,\n  the method <code>prepareStatement</code> will send\n  the statement to the database for precompilation. Some drivers\n  may not support precompilation. In this case, the statement may\n  not be sent to the database until the <code>PreparedStatement</code> is\n  executed.  This has no direct effect on users; however, it does\n  affect which method throws certain SQLExceptions.\n\n  Result sets created using the returned PreparedStatement will have\n  forward-only type and read-only concurrency, by default.\n\n  @param sql a SQL statement that may contain one or more '?' IN\n    parameter placeholders\n  @param Info a statement parameters.\n  @return a new PreparedStatement object containing the\n    pre-compiled statement\n}\nfunction TZOracleConnection.CreatePreparedStatement(const SQL: string;\n  Info: TStrings): IZPreparedStatement;\nbegin\n  if IsClosed then\n     Open;\n  Result := TZOraclePreparedStatement.Create(GetPlainDriver, Self, SQL, Info);\nend;\n\n{**\n  Makes all changes made since the previous\n  commit/rollback permanent and releases any database locks\n  currently held by the Connection. This method should be\n  used only when auto-commit mode has been disabled.\n  @see #setAutoCommit\n}\nprocedure TZOracleConnection.Commit;\nvar\n  Status: Integer;\n  SQL: PChar;\nbegin\n  if not Closed then\n  begin\n    SQL := 'COMMIT';\n\n    Status := GetPlainDriver.TransCommit(FContextHandle, FErrorHandle,\n      OCI_DEFAULT);\n    CheckOracleError(GetPlainDriver, FErrorHandle, Status, lcExecute, SQL);\n\n    DriverManager.LogMessage(lcExecute, PlainDriver.GetProtocol, SQL);\n  end;\nend;\n\n{**\n  Drops all changes made since the previous\n  commit/rollback and releases any database locks currently held\n  by this Connection. This method should be used only when auto-\n  commit has been disabled.\n  @see #setAutoCommit\n}\nprocedure TZOracleConnection.Rollback;\nvar\n  Status: Integer;\n  SQL: PChar;\nbegin\n  if not Closed then\n  begin\n    SQL := 'ROLLBACK';\n\n    Status := GetPlainDriver.TransRollback(FContextHandle, FErrorHandle,\n      OCI_DEFAULT);\n    CheckOracleError(GetPlainDriver, FErrorHandle, Status, lcExecute, SQL);\n\n    DriverManager.LogMessage(lcExecute, PlainDriver.GetProtocol, SQL);\n  end;\nend;\n\n{**\n  Ping Current Connection's server, if client was disconnected,\n  the connection is resumed.\n  @return 0 if succesfull or error code if any error occurs\n}\nfunction TZOracleConnection.PingServer: Integer;\nbegin\n  Result := GetPlainDriver.Ping(FContextHandle, FErrorHandle);\n  CheckOracleError(GetPlainDriver, FErrorHandle, Result, lcExecute, 'Ping Server');\n  Result := 0; //only possible if CheckOracleError dosn't raise an exception\nend;\n\n{**\n  Releases a Connection's database and JDBC resources\n  immediately instead of waiting for\n  them to be automatically released.\n\n  <P><B>Note:</B> A Connection is automatically closed when it is\n  garbage collected. Certain fatal errors also result in a closed\n  Connection.\n}\nprocedure TZOracleConnection.Close;\nvar\n  Status: Integer;\n  LogMessage: string;\nbegin\n  if not Closed then\n  begin\n    LogMessage := Format('DISCONNECT FROM \"%s\"', [Database]);\n\n    { Closes started transaction }\n    Status := GetPlainDriver.TransRollback(FContextHandle, FErrorHandle,\n      OCI_DEFAULT);\n    CheckOracleError(GetPlainDriver, FErrorHandle, Status, lcDisconnect,\n      LogMessage);\n    GetPlainDriver.HandleFree(FTransHandle, OCI_HTYPE_TRANS);\n    FTransHandle := nil;\n\n    { Closes the session }\n    Status := GetPlainDriver.SessionEnd(FContextHandle, FErrorHandle,\n      FSessionHandle, OCI_DEFAULT);\n    CheckOracleError(GetPlainDriver, FErrorHandle, Status, lcDisconnect,\n      LogMessage);\n\n    { Detaches from the server }\n    Status := GetPlainDriver.ServerDetach(FServerHandle, FErrorHandle,\n      OCI_DEFAULT);\n    CheckOracleError(GetPlainDriver, FErrorHandle, Status, lcDisconnect,\n      LogMessage);\n\n    { Frees all handlers }\n    GetPlainDriver.HandleFree(FDescibeHandle, OCI_HTYPE_DESCRIBE);\n    FDescibeHandle := nil;\n    GetPlainDriver.HandleFree(FSessionHandle, OCI_HTYPE_SESSION);\n    FSessionHandle := nil;\n    GetPlainDriver.HandleFree(FContextHandle, OCI_HTYPE_SVCCTX);\n    FContextHandle := nil;\n    GetPlainDriver.HandleFree(FServerHandle, OCI_HTYPE_SERVER);\n    FServerHandle := nil;\n    GetPlainDriver.HandleFree(FErrorHandle, OCI_HTYPE_ERROR);\n    FErrorHandle := nil;\n\n    DriverManager.LogMessage(lcDisconnect, PlainDriver.GetProtocol, LogMessage);\n  end;\n  inherited Close;\nend;\n\n{**\n  Gets a selected catalog name.\n  @return a selected catalog name.\n}\nfunction TZOracleConnection.GetCatalog: string;\nbegin\n  Result := FCatalog;\nend;\n\n{**\n  Sets a new selected catalog name.\n  @param Catalog a selected catalog name.\n}\nprocedure TZOracleConnection.SetCatalog(const Catalog: string);\nbegin\n  FCatalog := Catalog;\nend;\n\n{**\n  Sets a new transact isolation level.\n  @param Level a new transact isolation level.\n}\nprocedure TZOracleConnection.SetTransactionIsolation(\n  Level: TZTransactIsolationLevel);\nvar\n  Status: Integer;\n  SQL: PChar;\nbegin\n  if TransactIsolationLevel <> Level then\n  begin\n    inherited SetTransactionIsolation(Level);\n\n    if not Closed then\n    begin\n      SQL := 'END TRANSACTION';\n      Status := GetPlainDriver.TransRollback(FContextHandle, FErrorHandle,\n        OCI_DEFAULT);\n      CheckOracleError(GetPlainDriver, FErrorHandle, Status, lcExecute, SQL);\n      GetPlainDriver.HandleFree(FTransHandle, OCI_HTYPE_TRANS);\n      FTransHandle := nil;\n      DriverManager.LogMessage(lcExecute, PlainDriver.GetProtocol, SQL);\n\n      StartTransactionSupport;\n    end;\n  end;\nend;\n\n{**\n  Creates a sequence generator object.\n  @param Sequence a name of the sequence generator.\n  @param BlockSize a number of unique keys requested in one trip to SQL server.\n  @returns a created sequence object.\n}\nfunction TZOracleConnection.CreateSequence(const Sequence: string; BlockSize: Integer): IZSequence; \nbegin\n  Result := TZOracleSequence.Create(Self, Sequence, BlockSize);\nend;\n{**\n  Gets a Oracle plain driver interface.\n  @return a Oracle plain driver interface.\n}\nfunction TZOracleConnection.GetPlainDriver: IZOraclePlainDriver;\nbegin\n  Result := PlainDriver as IZOraclePlainDriver;\nend;\n\n{**\n  Gets a reference to Oracle connection handle.\n  @return a reference to Oracle connection handle.\n}\nfunction TZOracleConnection.GetConnectionHandle: POCIEnv;\nbegin\n  Result := FHandle;\nend;\n\n{**\n  Gets a reference to Oracle context handle.\n  @return a reference to Oracle context handle.\n}\nfunction TZOracleConnection.GetContextHandle: POCISvcCtx;\nbegin\n  Result := FContextHandle;\nend;\n\n{**\n  Gets a reference to Oracle error handle.\n  @return a reference to Oracle error handle.\n}\nfunction TZOracleConnection.GetErrorHandle: POCIError;\nbegin\n  Result := FErrorHandle;\nend;\n\n{**\n  Gets a reference to Oracle server handle.\n  @return a reference to Oracle server handle.\n}\nfunction TZOracleConnection.GetServerHandle: POCIServer;\nbegin\n  Result := FServerHandle;\nend;\n\n{**\n  Gets a reference to Oracle session handle.\n  @return a reference to Oracle session handle.\n}\nfunction TZOracleConnection.GetSessionHandle: POCISession;\nbegin\n  Result := FSessionHandle;\nend;\n\n{**\n  Gets a reference to Oracle transaction handle.\n  @return a reference to Oracle transacton handle.\n}\nfunction TZOracleConnection.GetTransactionHandle: POCITrans;\nbegin\n  Result := FTransHandle;\nend;\n\n{**\n  Gets a reference to Oracle describe handle.\n  @return a reference to Oracle describe handle.\n}\nfunction TZOracleConnection.GetDescribeHandle: POCIDescribe;\nbegin\n  Result := FDescibeHandle;\nend;\n\nfunction TZOracleConnection.GetClientVersion: Integer;\nvar\n  major_version, minor_version, update_num,\n      patch_num, port_update_num: sword;\nbegin\n  GetPlainDriver.ClientVersion(@major_version, @minor_version, @update_num,\n      @patch_num, @port_update_num);\n  Result := EncodeSQLVersioning(major_version,minor_version,update_num);\nend;\n\nfunction TZOracleConnection.GetHostVersion: Integer;\nvar\n  buf:text;\n  version:ub4;\nbegin\n  result:=0;\n  getmem(buf,1024);\n  if GetPlainDriver.ServerRelease(FServerHandle,FErrorHandle,buf,1024,OCI_HTYPE_SERVER,@version)=OCI_SUCCESS then\n    Result := EncodeSQLVersioning((version shr 24) and $ff,(version shr 20) and $f,(version shr 12) and $ff);\n  freemem(buf);\nend;\n\nfunction TZOracleConnection.GetBinaryEscapeString(const Value: TByteDynArray): String;\nvar\n  tmp: RawByteString;\n  L: Integer;\nbegin\n  L := Length(Value);\n  SetLength(tmp, L*2);\n  BinToHex(PAnsiChar(Value), PAnsiChar(tmp), L);\n  Result := #39+String(tmp)+#39;\n  if GetAutoEncodeStrings then\n    Result := GetDriver.GetTokenizer.GetEscapeString(Result)\nend;\n\nfunction TZOracleConnection.GetBinaryEscapeString(const Value: RawByteString): String;\nvar\n  tmp: RawByteString;\n  L: Integer;\nbegin\n  L := Length(Value);\n  SetLength(tmp, L*2);\n  BinToHex(PAnsiChar(Value), PAnsiChar(tmp), L);\n  if GetAutoEncodeStrings then\n    Result := GetDriver.GetTokenizer.GetEscapeString(Result)\nend;\n\n{ TZOracleSequence }\n\n{**\n  Gets the current unique key generated by this sequence.\n  @param the last generated unique key.\n}\nfunction TZOracleSequence.GetCurrentValue: Int64;\nvar\n  Statement: IZStatement;\n  ResultSet: IZResultSet;\nbegin\n  Statement := Connection.CreateStatement;\n  ResultSet := Statement.ExecuteQuery(\n    Format('SELECT %s.CURRVAL FROM DUAL', [Name]));\n  if ResultSet.Next then\n    Result := ResultSet.GetLong(1)\n  else\n    Result := inherited GetCurrentValue;\n  ResultSet.Close;\n  Statement.Close;\nend;\n\nfunction TZOracleSequence.GetCurrentValueSQL: String;\nbegin\n result:=Format('SELECT %s.CURRVAL FROM DUAL', [Name]);\nend;\n\n{**\n  Gets the next unique key generated by this sequence.\n  @param the next generated unique key.\n}\nfunction TZOracleSequence.GetNextValue: Int64;\nvar\n  Statement: IZStatement;\n  ResultSet: IZResultSet;\nbegin\n  Statement := Connection.CreateStatement;\n  ResultSet := Statement.ExecuteQuery(\n    Format('SELECT %s.NEXTVAL FROM DUAL', [Name]));\n  if ResultSet.Next then\n    Result := ResultSet.GetLong(1)\n  else\n    Result := inherited GetNextValue;\n  ResultSet.Close;\n  Statement.Close;\nend;\n\n\nfunction TZOracleSequence.GetNextValueSQL: String;\nbegin\n result:=Format('SELECT %s.NEXTVAL FROM DUAL', [Name]);\nend;\n\n{ TZOracleCachedResolver }\n\n{**\n  Forms a where clause for SELECT statements to calculate default values.\n  @param Columns a collection of key columns.\n  @param OldRowAccessor an accessor object to old column values.\n}\nfunction TZOracleCachedResolver.FormCalculateStatement(\n  Columns: TObjectList): string;\nvar\n   iPos: Integer;\nbegin\n  Result := inherited FormCalculateStatement(Columns);\n  if Result <> '' then\n  begin\n    iPos := pos('FROM', uppercase(Result));\n    if iPos > 0 then\n    begin\n      Result := copy(Result, 1, iPos+3) + ' DUAL';\n    end\n    else\n    begin\n      Result := Result + ' FROM DUAL';\n    end;\n  end;\nend;\n\ninitialization\n  OracleDriver := TZOracleDriver.Create;\n  DriverManager.RegisterDriver(OracleDriver);\nfinalization\n  if DriverManager <> nil then\n    DriverManager.DeregisterDriver(OracleDriver);\n  OracleDriver := nil;\nend.\n\n"
  },
  {
    "path": "lib/zeosdbo/src/dbc/ZDbcOracleMetadata.pas",
    "content": "{*********************************************************}\n{                                                         }\n{                 Zeos Database Objects                   }\n{          Oracle Database Connectivity Classes           }\n{                                                         }\n{        Originally written by Sergey Seroukhov           }\n{                                                         }\n{*********************************************************}\n\n{@********************************************************}\n{    Copyright (c) 1999-2012 Zeos Development Group       }\n{                                                         }\n{ License Agreement:                                      }\n{                                                         }\n{ This library is distributed in the hope that it will be }\n{ useful, but WITHOUT ANY WARRANTY; without even the      }\n{ implied warranty of MERCHANTABILITY or FITNESS FOR      }\n{ A PARTICULAR PURPOSE.  See the GNU Lesser General       }\n{ Public License for more details.                        }\n{                                                         }\n{ The source code of the ZEOS Libraries and packages are  }\n{ distributed under the Library GNU General Public        }\n{ License (see the file COPYING / COPYING.ZEOS)           }\n{ with the following  modification:                       }\n{ As a special exception, the copyright holders of this   }\n{ library give you permission to link this library with   }\n{ independent modules to produce an executable,           }\n{ regardless of the license terms of these independent    }\n{ modules, and to copy and distribute the resulting       }\n{ executable under terms of your choice, provided that    }\n{ you also meet, for each linked independent module,      }\n{ the terms and conditions of the license of that module. }\n{ An independent module is a module which is not derived  }\n{ from or based on this library. If you modify this       }\n{ library, you may extend this exception to your version  }\n{ of the library, but you are not obligated to do so.     }\n{ If you do not wish to do so, delete this exception      }\n{ statement from your version.                            }\n{                                                         }\n{                                                         }\n{ The project web site is located on:                     }\n{   http://zeos.firmos.at  (FORUM)                        }\n{   http://sourceforge.net/p/zeoslib/tickets/ (BUGTRACKER)}\n{   svn://svn.code.sf.net/p/zeoslib/code-0/trunk (SVN)    }\n{                                                         }\n{   http://www.sourceforge.net/projects/zeoslib.          }\n{                                                         }\n{                                                         }\n{                                 Zeos Development Group. }\n{********************************************************@}\n\nunit ZDbcOracleMetadata;\n\ninterface\n\n{$I ZDbc.inc}\n\nuses\n  Types, Classes, SysUtils, ZSysUtils, ZDbcIntfs, ZDbcMetadata,\n  ZCompatibility, ZDbcOracleUtils, ZDbcConnection, ZURL,\n  ZDbcCachedResultSet, ZDbcCache;\n\ntype\n\n  // technobot 2008-06-28 - methods moved as is from TZOracleDatabaseMetadata:\n  {** Implements Oracle Database Information. }\n  TZOracleDatabaseInfo = class(TZAbstractDatabaseInfo)\n//    function UncachedGetUDTs(const Catalog: string; const SchemaPattern: string;\n//      const TypeNamePattern: string; const Types: TIntegerDynArray): IZResultSet; override;\n  public\n    // database/driver/server info:\n    function GetDatabaseProductName: string; override;\n    function GetDatabaseProductVersion: string; override;\n    function GetDriverName: string; override;\n//    function GetDriverVersion: string; override; -> Same as parent\n    function GetDriverMajorVersion: Integer; override;\n    function GetDriverMinorVersion: Integer; override;\n//    function GetServerVersion: string; -> Not implemented\n\n    // capabilities (what it can/cannot do):\n//    function AllProceduresAreCallable: Boolean; override; -> Not implemented\n//    function AllTablesAreSelectable: Boolean; override; -> Not implemented\n    function SupportsMixedCaseIdentifiers: Boolean; override;\n    function SupportsMixedCaseQuotedIdentifiers: Boolean; override;\n//    function SupportsAlterTableWithAddColumn: Boolean; override; -> Not implemented\n//    function SupportsAlterTableWithDropColumn: Boolean; override; -> Not implemented\n//    function SupportsColumnAliasing: Boolean; override; -> Not implemented\n//    function SupportsConvert: Boolean; override; -> Not implemented\n//    function SupportsConvertForTypes(FromType: TZSQLType; ToType: TZSQLType):\n//      Boolean; override; -> Not implemented\n//    function SupportsTableCorrelationNames: Boolean; override; -> Not implemented\n//    function SupportsDifferentTableCorrelationNames: Boolean; override; -> Not implemented\n    function SupportsExpressionsInOrderBy: Boolean; override;\n    function SupportsOrderByUnrelated: Boolean; override;\n    function SupportsGroupBy: Boolean; override;\n    function SupportsGroupByUnrelated: Boolean; override;\n    function SupportsGroupByBeyondSelect: Boolean; override;\n//    function SupportsLikeEscapeClause: Boolean; override; -> Not implemented\n//    function SupportsMultipleResultSets: Boolean; override; -> Not implemented\n//    function SupportsMultipleTransactions: Boolean; override; -> Not implemented\n//    function SupportsNonNullableColumns: Boolean; override; -> Not implemented\n//    function SupportsMinimumSQLGrammar: Boolean; override; -> Not implemented\n//    function SupportsCoreSQLGrammar: Boolean; override; -> Not implemented\n//    function SupportsExtendedSQLGrammar: Boolean; override; -> Not implemented\n//    function SupportsANSI92EntryLevelSQL: Boolean; override; -> Not implemented\n//    function SupportsANSI92IntermediateSQL: Boolean; override; -> Not implemented\n//    function SupportsANSI92FullSQL: Boolean; override; -> Not implemented\n    function SupportsIntegrityEnhancementFacility: Boolean; override;\n//    function SupportsOuterJoins: Boolean; override; -> Not implemented\n//    function SupportsFullOuterJoins: Boolean; override; -> Not implemented\n//    function SupportsLimitedOuterJoins: Boolean; override; -> Not implemented\n    function SupportsSchemasInDataManipulation: Boolean; override;\n    function SupportsSchemasInProcedureCalls: Boolean; override;\n    function SupportsSchemasInTableDefinitions: Boolean; override;\n    function SupportsSchemasInIndexDefinitions: Boolean; override;\n    function SupportsSchemasInPrivilegeDefinitions: Boolean; override;\n    function SupportsCatalogsInDataManipulation: Boolean; override;\n    function SupportsCatalogsInProcedureCalls: Boolean; override;\n    function SupportsCatalogsInTableDefinitions: Boolean; override;\n    function SupportsCatalogsInIndexDefinitions: Boolean; override;\n    function SupportsCatalogsInPrivilegeDefinitions: Boolean; override;\n    function SupportsPositionedDelete: Boolean; override;\n    function SupportsPositionedUpdate: Boolean; override;\n    function SupportsSelectForUpdate: Boolean; override;\n    function SupportsStoredProcedures: Boolean; override;\n    function SupportsSubqueriesInComparisons: Boolean; override;\n    function SupportsSubqueriesInExists: Boolean; override;\n    function SupportsSubqueriesInIns: Boolean; override;\n    function SupportsSubqueriesInQuantifieds: Boolean; override;\n    function SupportsCorrelatedSubqueries: Boolean; override;\n    function SupportsUnion: Boolean; override;\n    function SupportsUnionAll: Boolean; override;\n    function SupportsOpenCursorsAcrossCommit: Boolean; override;\n    function SupportsOpenCursorsAcrossRollback: Boolean; override;\n    function SupportsOpenStatementsAcrossCommit: Boolean; override;\n    function SupportsOpenStatementsAcrossRollback: Boolean; override;\n    function SupportsTransactions: Boolean; override;\n    function SupportsTransactionIsolationLevel(Level: TZTransactIsolationLevel):\n      Boolean; override;\n    function SupportsDataDefinitionAndDataManipulationTransactions: Boolean; override;\n    function SupportsDataManipulationTransactionsOnly: Boolean; override;\n    function SupportsResultSetType(_Type: TZResultSetType): Boolean; override;\n    function SupportsResultSetConcurrency(_Type: TZResultSetType;\n      Concurrency: TZResultSetConcurrency): Boolean; override;\n//    function SupportsBatchUpdates: Boolean; override; -> Not implemented\n    function SupportsNonEscapedSearchStrings: Boolean; override;\n\n    // maxima:\n    function GetMaxBinaryLiteralLength: Integer; override;\n    function GetMaxCharLiteralLength: Integer; override;\n    function GetMaxColumnNameLength: Integer; override;\n    function GetMaxColumnsInGroupBy: Integer; override;\n    function GetMaxColumnsInIndex: Integer; override;\n    function GetMaxColumnsInOrderBy: Integer; override;\n    function GetMaxColumnsInSelect: Integer; override;\n    function GetMaxColumnsInTable: Integer; override;\n    function GetMaxConnections: Integer; override;\n    function GetMaxCursorNameLength: Integer; override;\n    function GetMaxIndexLength: Integer; override;\n    function GetMaxSchemaNameLength: Integer; override;\n    function GetMaxProcedureNameLength: Integer; override;\n    function GetMaxCatalogNameLength: Integer; override;\n    function GetMaxRowSize: Integer; override;\n    function GetMaxStatementLength: Integer; override;\n    function GetMaxStatements: Integer; override;\n    function GetMaxTableNameLength: Integer; override;\n    function GetMaxTablesInSelect: Integer; override;\n    function GetMaxUserNameLength: Integer; override;\n\n    // policies (how are various data and operations handled):\n//    function IsReadOnly: Boolean; override; -> Not implemented\n//    function IsCatalogAtStart: Boolean; override; -> Not implemented\n    function DoesMaxRowSizeIncludeBlobs: Boolean; override;\n//    function NullsAreSortedHigh: Boolean; override; -> Not implemented\n//    function NullsAreSortedLow: Boolean; override; -> Not implemented\n//    function NullsAreSortedAtStart: Boolean; override; -> Not implemented\n//    function NullsAreSortedAtEnd: Boolean; override; -> Not implemented\n//    function NullPlusNonNullIsNull: Boolean; override; -> Not implemented\n//    function UsesLocalFiles: Boolean; override; -> Not implemented\n    function UsesLocalFilePerTable: Boolean; override;\n    function StoresUpperCaseIdentifiers: Boolean; override;\n    function StoresLowerCaseIdentifiers: Boolean; override;\n    function StoresMixedCaseIdentifiers: Boolean; override;\n    function StoresUpperCaseQuotedIdentifiers: Boolean; override;\n    function StoresLowerCaseQuotedIdentifiers: Boolean; override;\n    function StoresMixedCaseQuotedIdentifiers: Boolean; override;\n    function GetDefaultTransactionIsolation: TZTransactIsolationLevel; override;\n    function DataDefinitionCausesTransactionCommit: Boolean; override;\n    function DataDefinitionIgnoredInTransactions: Boolean; override;\n\n    // interface details (terms, keywords, etc):\n    function GetSchemaTerm: string; override;\n    function GetProcedureTerm: string; override;\n    function GetCatalogTerm: string; override;\n    function GetCatalogSeparator: string; override;\n    function GetSQLKeywords: string; override;\n    function GetNumericFunctions: string; override;\n    function GetStringFunctions: string; override;\n    function GetSystemFunctions: string; override;\n    function GetTimeDateFunctions: string; override;\n    function GetSearchStringEscape: string; override;\n    function GetExtraNameCharacters: string; override;\n  end;\n\n  {** Implements Oracle Database Metadata. }\n  TZOracleDatabaseMetadata = class(TZAbstractDatabaseMetadata)\n  protected\n    function CreateDatabaseInfo: IZDatabaseInfo; override; // technobot 2008-06-28\n\n    function UncachedGetTables(const Catalog: string; const SchemaPattern: string;\n      const TableNamePattern: string; const Types: TStringDynArray): IZResultSet; override;\n    function UncachedGetSchemas: IZResultSet; override;\n//    function UncachedGetCatalogs: IZResultSet; override; -> Not implemented\n    function UncachedGetTableTypes: IZResultSet; override;\n    function UncachedGetColumns(const Catalog: string; const SchemaPattern: string;\n      const TableNamePattern: string; const ColumnNamePattern: string): IZResultSet; override;\n    function UncachedGetTablePrivileges(const Catalog: string; const SchemaPattern: string;\n      const TableNamePattern: string): IZResultSet; override;\n    function UncachedGetColumnPrivileges(const Catalog: string; const Schema: string;\n      const Table: string; const ColumnNamePattern: string): IZResultSet; override;\n    function UncachedGetPrimaryKeys(const Catalog: string; const Schema: string;\n      const Table: string): IZResultSet; override;\n//    function UncachedGetImportedKeys(const Catalog: string; const Schema: string;\n//      const Table: string): IZResultSet; override;\n//    function UncachedGetExportedKeys(const Catalog: string; const Schema: string;\n//      const Table: string): IZResultSet; override;\n//    function UncachedGetCrossReference(const PrimaryCatalog: string; const PrimarySchema: string;\n//      const PrimaryTable: string; const ForeignCatalog: string; const ForeignSchema: string;\n//      const ForeignTable: string): IZResultSet; override;\n    function UncachedGetIndexInfo(const Catalog: string; const Schema: string; const Table: string;\n      Unique: Boolean; Approximate: Boolean): IZResultSet; override;\n//     function UncachedGetSequences(const Catalog: string; const SchemaPattern: string;\n//      const SequenceNamePattern: string): IZResultSet; virtual; -> Not implemented\n    function UncachedGetProcedures(const Catalog, SchemaPattern,\n      ProcedureNamePattern: string): IZResultSet;override;\n    function UncachedGetProcedureColumns(const Catalog: string; const SchemaPattern: string;\n      const ProcedureNamePattern: string; const ColumnNamePattern: string):\n      IZResultSet; override;\n//    function UncachedGetVersionColumns(const Catalog: string; const Schema: string;\n//      const Table: string): IZResultSet; override;\n//    function UncachedGetTypeInfo: IZResultSet; override;\n  public\n    destructor Destroy; override;\n  end;\n\nimplementation\n\nuses\n  ZDbcUtils;\n\n{ TZOracleDatabaseInfo }\n\n//----------------------------------------------------------------------\n// First, a variety of minor information about the target database.\n\n{**\n  What's the name of this database product?\n  @return database product name\n}\nfunction TZOracleDatabaseInfo.GetDatabaseProductName: string;\nbegin\n  Result := 'Oracle';\nend;\n\n{**\n  What's the version of this database product?\n  @return database version\n}\nfunction TZOracleDatabaseInfo.GetDatabaseProductVersion: string;\nbegin\n  Result := '';\nend;\n\n{**\n  What's the name of this JDBC driver?\n  @return JDBC driver name\n}\nfunction TZOracleDatabaseInfo.GetDriverName: string;\nbegin\n  Result := 'Zeos Database Connectivity Driver for Oracle';\nend;\n\n{**\n  What's this JDBC driver's major version number?\n  @return JDBC driver major version\n}\nfunction TZOracleDatabaseInfo.GetDriverMajorVersion: Integer;\nbegin\n  Result := 1;\nend;\n\n{**\n  What's this JDBC driver's minor version number?\n  @return JDBC driver minor version number\n}\nfunction TZOracleDatabaseInfo.GetDriverMinorVersion: Integer;\nbegin\n  Result := 0;\nend;\n\n{**\n  Does the database use a file for each table?\n  @return true if the database uses a local file for each table\n}\nfunction TZOracleDatabaseInfo.UsesLocalFilePerTable: Boolean;\nbegin\n  Result := False;\nend;\n\n{**\n  Does the database treat mixed case unquoted SQL identifiers as\n  case sensitive and as a result store them in mixed case?\n  A JDBC Compliant<sup><font size=-2>TM</font></sup> driver will always return false.\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZOracleDatabaseInfo.SupportsMixedCaseIdentifiers: Boolean;\nbegin\n  Result := False;\nend;\n\n{**\n  Does the database treat mixed case unquoted SQL identifiers as\n  case insensitive and store them in upper case?\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZOracleDatabaseInfo.StoresUpperCaseIdentifiers: Boolean;\nbegin\n  Result := True;\nend;\n\n{**\n  Does the database treat mixed case unquoted SQL identifiers as\n  case insensitive and store them in lower case?\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZOracleDatabaseInfo.StoresLowerCaseIdentifiers: Boolean;\nbegin\n  Result := False;\nend;\n\n{**\n  Does the database treat mixed case unquoted SQL identifiers as\n  case insensitive and store them in mixed case?\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZOracleDatabaseInfo.StoresMixedCaseIdentifiers: Boolean;\nbegin\n  Result := False;\nend;\n\n{**\n  Does the database treat mixed case quoted SQL identifiers as\n  case sensitive and as a result store them in mixed case?\n  A JDBC Compliant<sup><font size=-2>TM</font></sup> driver will always return true.\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZOracleDatabaseInfo.SupportsMixedCaseQuotedIdentifiers: Boolean;\nbegin\n  Result := True;\nend;\n\n{**\n  Does the database treat mixed case quoted SQL identifiers as\n  case insensitive and store them in upper case?\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZOracleDatabaseInfo.StoresUpperCaseQuotedIdentifiers: Boolean;\nbegin\n  Result := False;\nend;\n\n{**\n  Does the database treat mixed case quoted SQL identifiers as\n  case insensitive and store them in lower case?\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZOracleDatabaseInfo.StoresLowerCaseQuotedIdentifiers: Boolean;\nbegin\n  Result := False;\nend;\n\n{**\n  Does the database treat mixed case quoted SQL identifiers as\n  case insensitive and store them in mixed case?\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZOracleDatabaseInfo.StoresMixedCaseQuotedIdentifiers: Boolean;\nbegin\n  Result := True;\nend;\n\n{**\n  Gets a comma-separated list of all a database's SQL keywords\n  that are NOT also SQL92 keywords.\n  @return the list\n}\nfunction TZOracleDatabaseInfo.GetSQLKeywords: string;\nbegin\n  Result := 'ACCESS,ADD,ALTER,AUDIT,CLUSTER,COLUMN,COMMENT,COMPRESS,CONNECT,'\n    + 'DATE,DROP,EXCLUSIVE,FILE,IDENTIFIED,IMMEDIATE,INCREMENT,INDEX,INITIAL,'\n    + 'INTERSECT,LEVEL,LOCK,LONG,MAXEXTENTS,MINUS,MODE,NOAUDIT,NOCOMPRESS,'\n    + 'NOWAIT,NUMBER,OFFLINE,ONLINE,PCTFREE,PRIOR';\nend;\n\n{**\n  Gets a comma-separated list of math functions.  These are the\n  X/Open CLI math function names used in the JDBC function escape\n  clause.\n  @return the list\n}\nfunction TZOracleDatabaseInfo.GetNumericFunctions: string;\nbegin\n  Result := 'ABS,ACOS,ASIN,ATAN,ATAN2,CEILING,COS,EXP,FLOOR,LOG,LOG10,MOD,PI,'\n    + 'POWER,ROUND,SIGN,SIN,SQRT,TAN,TRUNCATE';\nend;\n\n{**\n  Gets a comma-separated list of string functions.  These are the\n  X/Open CLI string function names used in the JDBC function escape\n  clause.\n  @return the list\n}\nfunction TZOracleDatabaseInfo.GetStringFunctions: string;\nbegin\n  Result := 'ASCII,CHAR,CONCAT,LCASE,LENGTH,LTRIM,REPLACE,RTRIM,SOUNDEX,'\n    + 'SUBSTRING,UCASE';\nend;\n\n{**\n  Gets a comma-separated list of system functions.  These are the\n  X/Open CLI system function names used in the JDBC function escape\n  clause.\n  @return the list\n}\nfunction TZOracleDatabaseInfo.GetSystemFunctions: string;\nbegin\n  Result := 'USER';\nend;\n\n{**\n  Gets a comma-separated list of time and date functions.\n  @return the list\n}\nfunction TZOracleDatabaseInfo.GetTimeDateFunctions: string;\nbegin\n  Result := 'CURDATE,CURTIME,DAYOFMONTH,HOUR,MINUTE,MONTH,NOW,SECOND,YEAR';\nend;\n\n{**\n  Gets the string that can be used to escape wildcard characters.\n  This is the string that can be used to escape '_' or '%' in\n  the string pattern style catalog search parameters.\n\n  <P>The '_' character represents any single character.\n  <P>The '%' character represents any sequence of zero or\n  more characters.\n\n  @return the string used to escape wildcard characters\n}\nfunction TZOracleDatabaseInfo.GetSearchStringEscape: string;\nbegin\n  Result := '//';\nend;\n\n{**\n  Gets all the \"extra\" characters that can be used in unquoted\n  identifier names (those beyond a-z, A-Z, 0-9 and _).\n  @return the string containing the extra characters\n}\nfunction TZOracleDatabaseInfo.GetExtraNameCharacters: string;\nbegin\n  Result := '$#';\nend;\n\n//--------------------------------------------------------------------\n// Functions describing which features are supported.\n\n{**\n  Are expressions in \"ORDER BY\" lists supported?\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZOracleDatabaseInfo.SupportsExpressionsInOrderBy: Boolean;\nbegin\n  Result := True;\nend;\n\n{**\n  Can an \"ORDER BY\" clause use columns not in the SELECT statement?\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZOracleDatabaseInfo.SupportsOrderByUnrelated: Boolean;\nbegin\n  Result := True;\nend;\n\n{**\n  Is some form of \"GROUP BY\" clause supported?\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZOracleDatabaseInfo.SupportsGroupBy: Boolean;\nbegin\n  Result := True;\nend;\n\n{**\n  Can a \"GROUP BY\" clause use columns not in the SELECT?\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZOracleDatabaseInfo.SupportsGroupByUnrelated: Boolean;\nbegin\n  Result := True;\nend;\n\n{**\n  Can a \"GROUP BY\" clause add columns not in the SELECT\n  provided it specifies all the columns in the SELECT?\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZOracleDatabaseInfo.SupportsGroupByBeyondSelect: Boolean;\nbegin\n  Result := True;\nend;\n\n{**\n  Is the SQL Integrity Enhancement Facility supported?\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZOracleDatabaseInfo.SupportsIntegrityEnhancementFacility: Boolean;\nbegin\n  Result := True;\nend;\n\n{**\n  What's the database vendor's preferred term for \"schema\"?\n  @return the vendor term\n}\nfunction TZOracleDatabaseInfo.GetSchemaTerm: string;\nbegin\n  Result := 'schema';\nend;\n\n{**\n  What's the database vendor's preferred term for \"procedure\"?\n  @return the vendor term\n}\nfunction TZOracleDatabaseInfo.GetProcedureTerm: string;\nbegin\n  Result := 'procedure';\nend;\n\n{**\n  What's the database vendor's preferred term for \"catalog\"?\n  @return the vendor term\n}\nfunction TZOracleDatabaseInfo.GetCatalogTerm: string;\nbegin\n  Result := '';\nend;\n\n{**\n  What's the separator between catalog and table name?\n  @return the separator string\n}\nfunction TZOracleDatabaseInfo.GetCatalogSeparator: string;\nbegin\n  Result := '';\nend;\n\n{**\n  Can a schema name be used in a data manipulation statement?\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZOracleDatabaseInfo.SupportsSchemasInDataManipulation: Boolean;\nbegin\n  Result := True;\nend;\n\n{**\n  Can a schema name be used in a procedure call statement?\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZOracleDatabaseInfo.SupportsSchemasInProcedureCalls: Boolean;\nbegin\n  Result := True;\nend;\n\n{**\n  Can a schema name be used in a table definition statement?\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZOracleDatabaseInfo.SupportsSchemasInTableDefinitions: Boolean;\nbegin\n  Result := True;\nend;\n\n{**\n  Can a schema name be used in an index definition statement?\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZOracleDatabaseInfo.SupportsSchemasInIndexDefinitions: Boolean;\nbegin\n  Result := True;\nend;\n\n{**\n  Can a schema name be used in a privilege definition statement?\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZOracleDatabaseInfo.SupportsSchemasInPrivilegeDefinitions: Boolean;\nbegin\n  Result := True;\nend;\n\n{**\n  Can a catalog name be used in a data manipulation statement?\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZOracleDatabaseInfo.SupportsCatalogsInDataManipulation: Boolean;\nbegin\n  Result := False;\nend;\n\n{**\n  Can a catalog name be used in a procedure call statement?\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZOracleDatabaseInfo.SupportsCatalogsInProcedureCalls: Boolean;\nbegin\n  Result := False;\nend;\n\n{**\n  Can a catalog name be used in a table definition statement?\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZOracleDatabaseInfo.SupportsCatalogsInTableDefinitions: Boolean;\nbegin\n  Result := False;\nend;\n\n{**\n  Can a catalog name be used in an index definition statement?\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZOracleDatabaseInfo.SupportsCatalogsInIndexDefinitions: Boolean;\nbegin\n  Result := False;\nend;\n\n{**\n  Can a catalog name be used in a privilege definition statement?\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZOracleDatabaseInfo.SupportsCatalogsInPrivilegeDefinitions: Boolean;\nbegin\n  Result := False;\nend;\n\n{**\n  Is positioned DELETE supported?\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZOracleDatabaseInfo.SupportsPositionedDelete: Boolean;\nbegin\n  Result := False;\nend;\n\n{**\n  Is positioned UPDATE supported?\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZOracleDatabaseInfo.SupportsPositionedUpdate: Boolean;\nbegin\n  Result := False;\nend;\n\n{**\n  Is SELECT for UPDATE supported?\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZOracleDatabaseInfo.SupportsSelectForUpdate: Boolean;\nbegin\n  Result := True;\nend;\n\n{**\n  Are stored procedure calls using the stored procedure escape\n  syntax supported?\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZOracleDatabaseInfo.SupportsStoredProcedures: Boolean;\nbegin\n  Result := True;\nend;\n\n{**\n  Are subqueries in comparison expressions supported?\n  A JDBC Compliant<sup><font size=-2>TM</font></sup> driver always returns true.\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZOracleDatabaseInfo.SupportsSubqueriesInComparisons: Boolean;\nbegin\n  Result := True;\nend;\n\n{**\n  Are subqueries in 'exists' expressions supported?\n  A JDBC Compliant<sup><font size=-2>TM</font></sup> driver always returns true.\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZOracleDatabaseInfo.SupportsSubqueriesInExists: Boolean;\nbegin\n  Result := True;\nend;\n\n{**\n  Are subqueries in 'in' statements supported?\n  A JDBC Compliant<sup><font size=-2>TM</font></sup> driver always returns true.\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZOracleDatabaseInfo.SupportsSubqueriesInIns: Boolean;\nbegin\n  Result := True;\nend;\n\n{**\n  Are subqueries in quantified expressions supported?\n  A JDBC Compliant<sup><font size=-2>TM</font></sup> driver always returns true.\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZOracleDatabaseInfo.SupportsSubqueriesInQuantifieds: Boolean;\nbegin\n  Result := True;\nend;\n\n{**\n  Are correlated subqueries supported?\n  A JDBC Compliant<sup><font size=-2>TM</font></sup> driver always returns true.\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZOracleDatabaseInfo.SupportsCorrelatedSubqueries: Boolean;\nbegin\n  Result := True;\nend;\n\n{**\n  Is SQL UNION supported?\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZOracleDatabaseInfo.SupportsUnion: Boolean;\nbegin\n  Result := True;\nend;\n\n{**\n  Is SQL UNION ALL supported?\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZOracleDatabaseInfo.SupportsUnionAll: Boolean;\nbegin\n  Result := True;\nend;\n\n{**\n  Can cursors remain open across commits?\n  @return <code>true</code> if cursors always remain open;\n        <code>false</code> if they might not remain open\n}\nfunction TZOracleDatabaseInfo.SupportsOpenCursorsAcrossCommit: Boolean;\nbegin\n  Result := False;\nend;\n\n{**\n  Can cursors remain open across rollbacks?\n  @return <code>true</code> if cursors always remain open;\n        <code>false</code> if they might not remain open\n}\nfunction TZOracleDatabaseInfo.SupportsOpenCursorsAcrossRollback: Boolean;\nbegin\n  Result := False;\nend;\n\n{**\n  Can statements remain open across commits?\n  @return <code>true</code> if statements always remain open;\n        <code>false</code> if they might not remain open\n}\nfunction TZOracleDatabaseInfo.SupportsOpenStatementsAcrossCommit: Boolean;\nbegin\n  Result := False;\nend;\n\n{**\n  Can statements remain open across rollbacks?\n  @return <code>true</code> if statements always remain open;\n        <code>false</code> if they might not remain open\n}\nfunction TZOracleDatabaseInfo.SupportsOpenStatementsAcrossRollback: Boolean;\nbegin\n  Result := False;\nend;\n\n//----------------------------------------------------------------------\n// The following group of methods exposes various limitations\n// based on the target database with the current driver.\n// Unless otherwise specified, a result of zero means there is no\n// limit, or the limit is not known.\n\n{**\n  How many hex characters can you have in an inline binary literal?\n  @return max binary literal length in hex characters;\n       a result of zero means that there is no limit or the limit is not known\n}\nfunction TZOracleDatabaseInfo.GetMaxBinaryLiteralLength: Integer;\nbegin\n  Result := 1000;\nend;\n\n{**\n  What's the max length for a character literal?\n  @return max literal length;\n       a result of zero means that there is no limit or the limit is not known\n}\nfunction TZOracleDatabaseInfo.GetMaxCharLiteralLength: Integer;\nbegin\n  Result := 2000;\nend;\n\n{**\n  What's the limit on column name length?\n  @return max column name length;\n       a result of zero means that there is no limit or the limit is not known\n}\nfunction TZOracleDatabaseInfo.GetMaxColumnNameLength: Integer;\nbegin\n  Result := 30;\nend;\n\n{**\n  What's the maximum number of columns in a \"GROUP BY\" clause?\n  @return max number of columns;\n       a result of zero means that there is no limit or the limit is not known\n}\nfunction TZOracleDatabaseInfo.GetMaxColumnsInGroupBy: Integer;\nbegin\n  Result := 0;\nend;\n\n{**\n  What's the maximum number of columns allowed in an index?\n  @return max number of columns;\n       a result of zero means that there is no limit or the limit is not known\n}\nfunction TZOracleDatabaseInfo.GetMaxColumnsInIndex: Integer;\nbegin\n  Result := 32;\nend;\n\n{**\n  What's the maximum number of columns in an \"ORDER BY\" clause?\n  @return max number of columns;\n       a result of zero means that there is no limit or the limit is not known\n}\nfunction TZOracleDatabaseInfo.GetMaxColumnsInOrderBy: Integer;\nbegin\n  Result := 0;\nend;\n\n{**\n  What's the maximum number of columns in a \"SELECT\" list?\n  @return max number of columns;\n       a result of zero means that there is no limit or the limit is not known\n}\nfunction TZOracleDatabaseInfo.GetMaxColumnsInSelect: Integer;\nbegin\n  Result := 0;\nend;\n\n{**\n  What's the maximum number of columns in a table?\n  @return max number of columns;\n       a result of zero means that there is no limit or the limit is not known\n}\nfunction TZOracleDatabaseInfo.GetMaxColumnsInTable: Integer;\nbegin\n  Result := 1000;\nend;\n\n{**\n  How many active connections can we have at a time to this database?\n  @return max number of active connections;\n       a result of zero means that there is no limit or the limit is not known\n}\nfunction TZOracleDatabaseInfo.GetMaxConnections: Integer;\nbegin\n  Result := 0;\nend;\n\n{**\n  What's the maximum cursor name length?\n  @return max cursor name length in bytes;\n       a result of zero means that there is no limit or the limit is not known\n}\nfunction TZOracleDatabaseInfo.GetMaxCursorNameLength: Integer;\nbegin\n  Result := 0;\nend;\n\n{**\n  Retrieves the maximum number of bytes for an index, including all\n  of the parts of the index.\n  @return max index length in bytes, which includes the composite of all\n   the constituent parts of the index;\n   a result of zero means that there is no limit or the limit is not known\n}\nfunction TZOracleDatabaseInfo.GetMaxIndexLength: Integer;\nbegin\n  Result := 0;\nend;\n\n{**\n  What's the maximum length allowed for a schema name?\n  @return max name length in bytes;\n       a result of zero means that there is no limit or the limit is not known\n}\nfunction TZOracleDatabaseInfo.GetMaxSchemaNameLength: Integer;\nbegin\n  Result := 30;\nend;\n\n{**\n  What's the maximum length of a procedure name?\n  @return max name length in bytes;\n       a result of zero means that there is no limit or the limit is not known\n}\nfunction TZOracleDatabaseInfo.GetMaxProcedureNameLength: Integer;\nbegin\n  Result := 30;\nend;\n\n{**\n  What's the maximum length of a catalog name?\n  @return max name length in bytes;\n       a result of zero means that there is no limit or the limit is not known\n}\nfunction TZOracleDatabaseInfo.GetMaxCatalogNameLength: Integer;\nbegin\n  Result := 0;\nend;\n\n{**\n  What's the maximum length of a single row?\n  @return max row size in bytes;\n       a result of zero means that there is no limit or the limit is not known\n}\nfunction TZOracleDatabaseInfo.GetMaxRowSize: Integer;\nbegin\n  Result := 2000;\nend;\n\n{**\n  Did getMaxRowSize() include LONGVARCHAR and LONGVARBINARY\n  blobs?\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZOracleDatabaseInfo.DoesMaxRowSizeIncludeBlobs: Boolean;\nbegin\n  Result := True;\nend;\n\n{**\n  What's the maximum length of an SQL statement?\n  @return max length in bytes;\n       a result of zero means that there is no limit or the limit is not known\n}\nfunction TZOracleDatabaseInfo.GetMaxStatementLength: Integer;\nbegin\n  Result := 65535;\nend;\n\n{**\n  How many active statements can we have open at one time to this\n  database?\n  @return the maximum number of statements that can be open at one time;\n       a result of zero means that there is no limit or the limit is not known\n}\nfunction TZOracleDatabaseInfo.GetMaxStatements: Integer;\nbegin\n  Result := 0;\nend;\n\n{**\n  What's the maximum length of a table name?\n  @return max name length in bytes;\n       a result of zero means that there is no limit or the limit is not known\n}\nfunction TZOracleDatabaseInfo.GetMaxTableNameLength: Integer;\nbegin\n  Result := 30;\nend;\n\n{**\n  What's the maximum number of tables in a SELECT statement?\n  @return the maximum number of tables allowed in a SELECT statement;\n       a result of zero means that there is no limit or the limit is not known\n}\nfunction TZOracleDatabaseInfo.GetMaxTablesInSelect: Integer;\nbegin\n  Result := 0;\nend;\n\n{**\n  What's the maximum length of a user name?\n  @return max user name length  in bytes;\n       a result of zero means that there is no limit or the limit is not known\n}\nfunction TZOracleDatabaseInfo.GetMaxUserNameLength: Integer;\nbegin\n  Result := 30;\nend;\n\n//----------------------------------------------------------------------\n\n{**\n  What's the database's default transaction isolation level?  The\n  values are defined in <code>java.sql.Connection</code>.\n  @return the default isolation level\n  @see Connection\n}\nfunction TZOracleDatabaseInfo.GetDefaultTransactionIsolation:\n  TZTransactIsolationLevel;\nbegin\n  Result := tiReadCommitted;\nend;\n\n{**\n  Are transactions supported? If not, invoking the method\n  <code>commit</code> is a noop and the isolation level is TRANSACTION_NONE.\n  @return <code>true</code> if transactions are supported; <code>false</code> otherwise\n}\nfunction TZOracleDatabaseInfo.SupportsTransactions: Boolean;\nbegin\n  Result := True;\nend;\n\n{**\n  Does this database support the given transaction isolation level?\n  @param level the values are defined in <code>java.sql.Connection</code>\n  @return <code>true</code> if so; <code>false</code> otherwise\n  @see Connection\n}\nfunction TZOracleDatabaseInfo.SupportsTransactionIsolationLevel(\n  Level: TZTransactIsolationLevel): Boolean;\nbegin\n  Result := True;\nend;\n\n{**\n  Are both data definition and data manipulation statements\n  within a transaction supported?\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZOracleDatabaseInfo.\n  SupportsDataDefinitionAndDataManipulationTransactions: Boolean;\nbegin\n  Result := True;\nend;\n\n{**\n  Are only data manipulation statements within a transaction\n  supported?\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZOracleDatabaseInfo.\n  SupportsDataManipulationTransactionsOnly: Boolean;\nbegin\n  Result := True;\nend;\n\n{**\n  Does a data definition statement within a transaction force the\n  transaction to commit?\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZOracleDatabaseInfo.DataDefinitionCausesTransactionCommit: Boolean;\nbegin\n  Result := True;\nend;\n\n{**\n  Is a data definition statement within a transaction ignored?\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZOracleDatabaseInfo.DataDefinitionIgnoredInTransactions: Boolean;\nbegin\n  Result := False;\nend;\n\n{**\n  Does the database support the given result set type?\n  @param type defined in <code>java.sql.ResultSet</code>\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZOracleDatabaseInfo.SupportsResultSetType(\n  _Type: TZResultSetType): Boolean;\nbegin\n  Result := _Type = rtForwardOnly;\nend;\n\n{**\n  Does the database support the concurrency type in combination\n  with the given result set type?\n\n  @param type defined in <code>java.sql.ResultSet</code>\n  @param concurrency type defined in <code>java.sql.ResultSet</code>\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZOracleDatabaseInfo.SupportsResultSetConcurrency(\n  _Type: TZResultSetType; Concurrency: TZResultSetConcurrency): Boolean;\nbegin\n  Result := (_Type = rtForwardOnly) and (Concurrency = rcReadOnly);\nend;\n\n{**\n  Does the Database or Actual Version understand non escaped search strings?\n  @return <code>true</code> if the DataBase does understand non escaped\n  search strings\n}\nfunction TZOracleDatabaseInfo.SupportsNonEscapedSearchStrings: Boolean;\nbegin\n  Result := MetaData.GetConnection.GetClientVersion > 10000000;\nend;\n\n{ TZOracleDatabaseMetadata }\n\n{**\n  Destroys this object and cleanups the memory.\n}\ndestructor TZOracleDatabaseMetadata.Destroy;\nbegin\n  inherited Destroy;\nend;\n\n{**\n  Constructs a database information object and returns the interface to it. Used\n  internally by the constructor.\n  @return the database information object interface\n}\nfunction TZOracleDatabaseMetadata.CreateDatabaseInfo: IZDatabaseInfo;\nbegin\n  Result := TZOracleDatabaseInfo.Create(Self);\nend;\n\n{**\n  Gets a description of tables available in a catalog.\n\n  <P>Only table descriptions matching the catalog, schema, table\n  name and type criteria are returned.  They are ordered by\n  TABLE_TYPE, TABLE_SCHEM and TABLE_NAME.\n\n  <P>Each table description has the following columns:\n   <OL>\n \t<LI><B>TABLE_CAT</B> String => table catalog (may be null)\n \t<LI><B>TABLE_SCHEM</B> String => table schema (may be null)\n \t<LI><B>TABLE_NAME</B> String => table name\n \t<LI><B>TABLE_TYPE</B> String => table type.  Typical types are \"TABLE\",\n \t\t\t\"VIEW\",\t\"SYSTEM TABLE\", \"GLOBAL TEMPORARY\",\n \t\t\t\"LOCAL TEMPORARY\", \"ALIAS\", \"SYNONYM\".\n \t<LI><B>REMARKS</B> String => explanatory comment on the table\n   </OL>\n\n  <P><B>Note:</B> Some databases may not return information for\n  all tables.\n\n  @param catalog a catalog name; \"\" retrieves those without a\n  catalog; null means drop catalog name from the selection criteria\n  @param schemaPattern a schema name pattern; \"\" retrieves those\n  without a schema\n  @param tableNamePattern a table name pattern\n  @param types a list of table types to include; null returns all types\n  @return <code>ResultSet</code> - each row is a table description\n  @see #getSearchStringEscape\n}\nfunction TZOracleDatabaseMetadata.UncachedGetTables(const Catalog: string;\n  const SchemaPattern: string; const TableNamePattern: string;\n  const Types: TStringDynArray): IZResultSet;\nvar\n  NameCondition, OwnerCondition, PartSQL, SQL: string;\n\n  function IncludedType(const TypeName: string): Boolean;\n  var I: Integer;\n  begin\n    Result := False;\n    for I := Low(Types) to High(Types) do\n      Result := Result or (UpperCase(Types[I]) = TypeName);\n    Result := Result or (Length(Types) = 0);\n  end;\n\n  function CreateWhere: String;\n  begin\n    Result := '';\n    If OwnerCondition <> '' then\n      Result := OwnerCondition;\n    If NameCondition <> '' then\n      If Result <> '' then\n        Result := Result + ' AND ' + NameCondition\n      Else\n        Result := NameCondition;\n    If Result <> '' then\n      Result := ' Where ' + Result;\n  end;\n\nbegin\n  OwnerCondition := ConstructNameCondition(SchemaPattern,'OWNER');\n\n  if IncludedType('TABLE') then\n  begin\n    NameCondition := ConstructNameCondition(TableNamePattern,'TABLE_NAME');\n    SQL := 'SELECT NULL AS TABLE_CAT, OWNER AS TABLE_SCHEM, TABLE_NAME,'\n      + ' ''TABLE'' AS TABLE_TYPE, NULL AS REMARKS FROM SYS.ALL_TABLES'\n      + CreateWhere;\n  end else\n    SQL := '';\n\n  if IncludedType('SYNONYM') then\n  begin\n    NameCondition := ConstructNameCondition(TableNamePattern,'SYNONYM_NAME');\n    PartSQL := 'SELECT NULL AS TABLE_CAT, OWNER AS TABLE_SCHEM,'\n      + ' SYNONYM_NAME AS TABLE_NAME, ''SYNONYM'' AS TABLE_TYPE,'\n      + ' NULL AS REMARKS FROM SYS.ALL_SYNONYMS'\n      + CreateWhere;\n    if SQL <> '' then\n      SQL := SQL + ' UNION ';\n    SQL := SQL + PartSQL;\n  end;\n\n  if IncludedType('VIEW') then\n  begin\n    NameCondition := ConstructNameCondition(TableNamePattern,'VIEW_NAME');\n    PartSQL := 'SELECT NULL AS TABLE_CAT, OWNER AS TABLE_SCHEM,'\n      + ' VIEW_NAME AS TABLE_NAME, ''VIEW'' AS TABLE_TYPE,'\n      + ' NULL AS REMARKS FROM SYS.ALL_VIEWS'\n      + CreateWhere;\n    if SQL <> '' then\n      SQL := SQL + ' UNION ';\n    SQL := SQL + PartSQL;\n  end;\n\n  if IncludedType('SEQUENCE') then\n  begin\n    OwnerCondition := ConstructNameCondition(SchemaPattern,'SEQUENCE_OWNER');\n    NameCondition := ConstructNameCondition(TableNamePattern,'SEQUENCE_NAME');\n    PartSQL := 'SELECT NULL AS TABLE_CAT, SEQUENCE_OWNER AS TABLE_SCHEM,'\n      + ' SEQUENCE_NAME AS TABLE_NAME, ''SEQUENCE'' AS TABLE_TYPE,'\n      + ' NULL AS REMARKS FROM SYS.ALL_SEQUENCES'\n      + CreateWhere;\n    if SQL <> '' then\n      SQL := SQL + ' UNION ';\n    SQL := SQL + PartSQL;\n  end;\n\n  Result := CopyToVirtualResultSet(\n    GetConnection.CreateStatement.ExecuteQuery(SQL),\n    ConstructVirtualResultSet(TableColumnsDynArray));\nend;\n\n\nfunction TZOracleDatabaseMetadata.UncachedGetProcedureColumns(const Catalog,\n  SchemaPattern, ProcedureNamePattern, ColumnNamePattern: string): IZResultSet;\nvar\n  ColumnIndexes : Array[1..9] of integer;\n  colName: string;\n  IZStmt: IZStatement;\n  TempSet: IZResultSet;\n  Names, Procs: TStrings;\n  PackageName, ProcName, TempProcedureNamePattern, TmpSchemaPattern: String;\n\n  function GetNextName(const AName: String; NameEmpty: Boolean = False): String;\n  var\n    N: Integer;\n    NewName: String;\n  begin\n    if ( PackageName = '' ) or ( not ( PackageName = ProcedureNamePattern ) ) then\n      NewName := AName\n    else\n      NewName := ProcName+'.'+AName;\n    if (Names.IndexOf(NewName) = -1) and not NameEmpty then\n    begin\n      Names.Add(NewName);\n      Result := NewName;\n    end\n    else\n      for N := 1 to MaxInt do\n        if Names.IndexOf(NewName+IntToStr(N)) = -1 then\n        begin\n          Result := NewName+IntToStr(N);\n          Names.Add(Result);\n          Break;\n        end;\n  end;\n\n  procedure InsertProcedureColumnValues(Source: IZResultSet; IsResultParam: Boolean = False);\n  var\n    TypeName, SubTypeName: string;\n  begin\n    TypeName := Source.GetString(ColumnIndexes[4]);\n    SubTypeName := Source.GetString(ColumnIndexes[5]);\n    PackageName := Source.GetString(ColumnIndexes[8]);\n    ProcName := Source.GetString(ColumnIndexes[9]);\n\n    Result.MoveToInsertRow;\n    Result.UpdateNull(1);    //PROCEDURE_CAT\n    Result.UpdateNull(2);    //PROCEDURE_SCHEM\n    Result.UpdateString(3, Source.GetString(ColumnIndexes[1]));    //TABLE_NAME\n    if IsResultParam then\n      Result.UpdateInt(5, Ord(pctReturn))\n    else\n      if Source.GetString(ColumnIndexes[3]) = 'IN' then\n        Result.UpdateInt(5, Ord(pctIn))\n      else\n        if Source.GetString(ColumnIndexes[3]) = 'OUT' then\n          Result.UpdateInt(5, Ord(pctOut))\n        else\n          if ( Source.GetString(ColumnIndexes[3]) = 'IN/OUT') then\n            Result.UpdateInt(5, Ord(pctInOut))\n          else\n            Result.UpdateInt(5, Ord(pctUnknown));\n\n    ColName := Source.GetString(ColumnIndexes[2]);\n    if IsResultParam then\n      Result.UpdateString(4, GetNextName('ReturnValue', False))    //COLUMN_NAME\n    else\n      Result.UpdateString(4, GetNextName(ColName, Length(ColName) = 0));    //COLUMN_NAME\n\n    Result.UpdateInt(6, Ord(ConvertOracleTypeToSQLType(TypeName,\n      Source.GetInt(ColumnIndexes[6]),Source.GetInt(ColumnIndexes[7]),\n      ConSettings.CPType))); //DATA_TYPE\n    Result.UpdateString(7,TypeName);    //TYPE_NAME\n    Result.UpdateInt(10, Source.GetInt(ColumnIndexes[6])); //PRECISION\n    Result.UpdateNull(9);    //BUFFER_LENGTH\n    Result.UpdateInt(10, Source.GetInt(ColumnIndexes[7]));\n    Result.UpdateInt(11, 10);\n    //Result.UpdateInt(12, GetInt(ColumnIndexes[8]));\n    Result.UpdateNull(12);\n    Result.UpdateString(12, Source.GetString(ColumnIndexes[6]));\n    Result.InsertRow;\n  end;\n\n  function GetColumnSQL(PosChar: String; Package: String = ''): String;\n  var\n    OwnerCondition, PackageNameCondition, PackageAsProcCondition, PackageProcNameCondition: string;\n\n    procedure SplitPackageAndProc(Value: String);\n    var\n      iPos: Integer;\n    begin\n      PackageName := '';\n      ProcName := 'Value';\n      iPos := Pos('.', Value);\n        if (iPos > 0) then\n        begin\n          PackageNameCondition := ConstructNameCondition(Copy(Value, 1, iPos-1),'package_name');\n          PackageProcNameCondition := ConstructNameCondition(Copy(Value, iPos+1,Length(Value)-iPos),'object_name');\n          PackageAsProcCondition := ConstructNameCondition(Copy(Value, iPos+1,Length(Value)-iPos),'package_name');\n          PackageName := '= '+#39+IC.ExtractQuote(Copy(Value, 1, iPos-1))+#39;\n          ProcName := IC.ExtractQuote(Copy(Value, iPos+1,Length(Value)-iPos));\n        end\n        else\n        begin\n          PackageNameCondition := 'package_name IS NULL';\n          PackageProcNameCondition := ConstructNameCondition(Value,'object_name');\n          PackageAsProcCondition := ConstructNameCondition(Value,'package_name');\n          PackageName := 'IS NULL';\n          ProcName := IC.ExtractQuote(Value);\n        end;\n    end;\n  begin\n    OwnerCondition := ConstructNameCondition(TmpSchemaPattern,'OWNER');\n    SplitPackageAndProc(TempProcedureNamePattern);\n    Result := 'select * from all_arguments where ('+PackageNameCondition+\n      ' AND '+PackageProcNameCondition+\n      ' OR '+ PackageAsProcCondition+')'+\n        'AND POSITION '+PosChar+' 0';\n    If OwnerCondition <> '' then\n      Result := Result + ' AND ' + OwnerCondition;\n    Result := Result + ' ORDER BY POSITION';\n  end;\n\n  procedure AddColumns(WasNext: Boolean; WasFunc: Boolean);\n  begin\n    if WasNext then InsertProcedureColumnValues(TempSet, WasFunc);\n    while TempSet.Next do\n      InsertProcedureColumnValues(TempSet, WasFunc);\n    TempSet.Close;\n\n    if not WasFunc then\n    begin\n      TempSet := IZStmt.ExecuteQuery(GetColumnSQL('=')); //ReturnValue has allways Position = 0\n      with TempSet do\n      begin\n        while Next do\n          InsertProcedureColumnValues(TempSet, True);\n        Close;\n      end;\n    end;\n  end;\n\n  procedure GetMoreProcedures;\n  var\n    i: Integer;\n    PackageNameCondition: String;\n  begin\n    PackageNameCondition := ConstructNameCondition(ProcedureNamePattern,'package_name');\n    If PackageNameCondition <> '' then\n      PackageNameCondition := ' WHERE ' + PackageNameCondition;\n    TempSet.Close;\n    TempSet := IZStmt.ExecuteQuery('select object_name from user_arguments '\n               + PackageNameCondition + ' GROUP BY object_name order by object_name');\n    while TempSet.Next do\n      Procs.Add(TempSet.GetString(1));\n    TempSet.Close;\n    for i := 0 to Procs.Count -1 do\n    begin\n      TempProcedureNamePattern := ProcedureNamePattern+'.'+IC.Quote(Procs[i]);\n      TempSet := IZStmt.ExecuteQuery(GetColumnSQL('>')); //ParameterValues have allways Position > 0\n      AddColumns(False, False);\n    end;\n  end;\n\n  function CheckSchema: Boolean;\n  begin\n    if TmpSchemaPattern = '' then\n      Result := False\n    else\n      with GetConnection.CreateStatement.ExecuteQuery('SELECT COUNT(*) FROM ALL_USERS WHERE '+ConstructNameCondition(TmpSchemaPattern,'username')) do\n      begin\n        Next;\n        Result := GetInt(1) > 0;\n        Close;\n      end;\n  end;\nbegin\n  Result:=inherited UncachedGetProcedureColumns(Catalog, SchemaPattern, ProcedureNamePattern, ColumnNamePattern);\n\n  {improve SplitQualifiedObjectName: Oracle does'nt support catalogs}\n  if Catalog = '' then\n    TmpSchemaPattern := SchemaPattern\n  else\n    TmpSchemaPattern := Catalog;\n\n    if ( TmpSchemaPattern = '' ) then\n      TempProcedureNamePattern := ProcedureNamePattern //just a procedurename or package or both\n    else\n      if CheckSchema then\n        TempProcedureNamePattern := ProcedureNamePattern //Schema exists not a package\n      else\n        begin\n          TempProcedureNamePattern := TmpSchemaPattern+'.'+ProcedureNamePattern; //no Schema so it's a PackageName\n          TmpSchemaPattern := '';\n        end;\n  if TempProcedureNamePattern <> '' then\n  begin\n    Names := TStringList.Create;\n    Procs := TStringList.Create;\n\n    IZStmt := GetConnection.CreateStatement;\n    TempSet := IZStmt.ExecuteQuery(GetColumnSQL('>')); //ParameterValues have allways Position > 0\n\n    with TempSet  do\n    begin\n      ColumnIndexes[1] := FindColumn('object_name');\n      ColumnIndexes[2] := FindColumn('argument_name');\n      ColumnIndexes[3] := FindColumn('IN_OUT'); //'RDB$PARAMETER_TYPE');\n      ColumnIndexes[4] := FindColumn('DATA_TYPE');//'RDB$FIELD_TYPE');\n      ColumnIndexes[5] := FindColumn('TYPE_SUBNAME');//RDB$FIELD_SUB_TYPE');\n      ColumnIndexes[6] := FindColumn('DATA_PRECISION');//RDB$FIELD_PRECISION');\n      ColumnIndexes[7] := FindColumn('DATA_SCALE');//RDB$FIELD_SCALE');\n      ColumnIndexes[8] := FindColumn('package_name');\n      ColumnIndexes[9] := FindColumn('object_name');\n    end;\n      if ( PackageName <> 'IS NULL' ) and ( ProcName <> '' ) then\n        AddColumns(False, False)\n      else\n        if TempSet.Next then\n          if ( TempSet.GetString(ColumnIndexes[8]) = ProcName ) then\n          {Package without proc found}\n            GetMoreProcedures\n          else\n            AddColumns(True, False)\n        else\n        begin\n          TempSet.Close;\n          TempSet := IZStmt.ExecuteQuery(GetColumnSQL('=')); //ParameterValues have allways Position > 0\n          if TempSet.Next then\n            if ( TempSet.GetString(ColumnIndexes[8]) = ProcName ) then\n            {Package without proc found}\n              GetMoreProcedures\n            else\n              AddColumns(True, True)\n        end;\n    TempSet := nil;\n    IZStmt.Close;\n    FreeAndNil(Names);\n    FreeAndNil(Procs);\n  end;\nend;\n\nfunction TZOracleDatabaseMetadata.UncachedGetProcedures(const Catalog: string;\n  const SchemaPattern: string; const ProcedureNamePattern: string): IZResultSet;\nvar\n  SQL: string;\n  LProcedureNamePattern, LSchemaNamePattern: string;\n  sName:string;\nbegin\n  Result:=inherited UncachedGetProcedures(Catalog, SchemaPattern, ProcedureNamePattern);\n\n  LProcedureNamePattern := ConstructNameCondition(ProcedureNamePattern,'decode(procedure_name,null,object_name,object_name||''.''||procedure_name)');\n  LSchemaNamePattern := ConstructNameCondition(SchemaPattern,'owner');\n  SQL := 'select NULL AS PROCEDURE_CAT, OWNER AS PROCEDURE_SCHEM, '+\n    'OBJECT_NAME, PROCEDURE_NAME AS PROCEDURE_NAME, '+\n    'OVERLOAD AS PROCEDURE_OVERLOAD, OBJECT_TYPE AS PROCEDURE_TYPE FROM '+\n    'ALL_PROCEDURES WHERE 1=1';\n  if LProcedureNamePattern <> '' then\n    SQL := SQL + ' AND ' + LProcedureNamePattern;\n  if LSchemaNamePattern <> '' then\n    SQL := SQL + ' AND ' + LSchemaNamePattern;\n  SQL := SQL + ' ORDER BY decode(owner,user,0,1),owner,object_name,procedure_name,overload';\n\n  with GetConnection.CreateStatement.ExecuteQuery(SQL) do\n  begin\n    while Next do\n    begin\n      sName := IC.Quote(GetString(3));\n      if GetString(4) <> '' then\n        sName :=  sName+'.'+IC.Quote(GetString(4));\n      Result.MoveToInsertRow;\n      Result.UpdateNull(1);\n      Result.UpdateString(2, GetString(2));\n      Result.UpdateString(3, sName); //PROCEDURE_NAME\n      Result.UpdateString(4, GetString(5)); //PROCEDURE_OVERLOAD\n      Result.UpdateNull(5);\n      Result.UpdateNull(6);\n      Result.UpdateNull(7);\n      if GetString(6) = 'FUNCTION' then\n          Result.UpdateInt(8, Ord(prtReturnsResult))\n        else if GetString(6) = 'PROCDEURE' then\n          Result.UpdateInt(8, Ord(prtNoResult))\n        else\n          Result.UpdateInt(8, Ord(prtUnknown)); //Package\n      Result.InsertRow;\n    end;\n    Close;\n  end;\nend;\n\n\n{**\n  Gets the schema names available in this database.  The results\n  are ordered by schema name.\n\n  <P>The schema column is:\n   <OL>\n \t<LI><B>TABLE_SCHEM</B> String => schema name\n   </OL>\n\n  @return <code>ResultSet</code> - each row has a single String column that is a\n  schema name\n}\nfunction TZOracleDatabaseMetadata.UncachedGetSchemas: IZResultSet;\nbegin\n    Result := CopyToVirtualResultSet(\n      GetConnection.CreateStatement.ExecuteQuery(\n        'SELECT USERNAME AS TABLE_SCHEM FROM SYS.ALL_USERS'),\n      ConstructVirtualResultSet(SchemaColumnsDynArray));\nend;\n\n{**\n  Gets the table types available in this database.  The results\n  are ordered by table type.\n\n  <P>The table type is:\n   <OL>\n \t<LI><B>TABLE_TYPE</B> String => table type.  Typical types are \"TABLE\",\n \t\t\t\"VIEW\",\t\"SYSTEM TABLE\", \"GLOBAL TEMPORARY\",\n \t\t\t\"LOCAL TEMPORARY\", \"ALIAS\", \"SYNONYM\".\n   </OL>\n\n  @return <code>ResultSet</code> - each row has a single String column that is a\n  table type\n}\nfunction TZOracleDatabaseMetadata.UncachedGetTableTypes: IZResultSet;\nconst\n  TableTypeCount = 4;\n  Types: array [1..TableTypeCount] of String = (\n    'TABLE', 'SYNONYM', 'VIEW', 'SEQUENCE'\n  );\nvar\n  I: Integer;\nbegin\n  Result:=inherited UncachedGetTableTypes;\n\n  for I := 1 to TableTypeCount do\n    begin\n      Result.MoveToInsertRow;\n      Result.UpdateString(1, Types[I]);\n      Result.InsertRow;\n    end;\nend;\n\n{**\n  Gets a description of table columns available in\n  the specified catalog.\n\n  <P>Only column descriptions matching the catalog, schema, table\n  and column name criteria are returned.  They are ordered by\n  TABLE_SCHEM, TABLE_NAME and ORDINAL_POSITION.\n\n  <P>Each column description has the following columns:\n   <OL>\n \t<LI><B>TABLE_CAT</B> String => table catalog (may be null)\n \t<LI><B>TABLE_SCHEM</B> String => table schema (may be null)\n \t<LI><B>TABLE_NAME</B> String => table name\n \t<LI><B>COLUMN_NAME</B> String => column name\n \t<LI><B>DATA_TYPE</B> short => SQL type from java.sql.Types\n \t<LI><B>TYPE_NAME</B> String => Data source dependent type name,\n   for a UDT the type name is fully qualified\n \t<LI><B>COLUMN_SIZE</B> int => column size.  For char or date\n \t    types this is the maximum number of characters, for numeric or\n \t    decimal types this is precision.\n \t<LI><B>BUFFER_LENGTH</B> is not used.\n \t<LI><B>DECIMAL_DIGITS</B> int => the number of fractional digits\n \t<LI><B>NUM_PREC_RADIX</B> int => Radix (typically either 10 or 2)\n \t<LI><B>NULLABLE</B> int => is NULL allowed?\n       <UL>\n       <LI> columnNoNulls - might not allow NULL values\n       <LI> columnNullable - definitely allows NULL values\n       <LI> columnNullableUnknown - nullability unknown\n       </UL>\n \t<LI><B>REMARKS</B> String => comment describing column (may be null)\n  \t<LI><B>COLUMN_DEF</B> String => default value (may be null)\n \t<LI><B>SQL_DATA_TYPE</B> int => unused\n \t<LI><B>SQL_DATETIME_SUB</B> int => unused\n \t<LI><B>CHAR_OCTET_LENGTH</B> int => for char types the\n        maximum number of bytes in the column\n \t<LI><B>ORDINAL_POSITION</B> int\t=> index of column in table\n       (starting at 1)\n \t<LI><B>IS_NULLABLE</B> String => \"NO\" means column definitely\n       does not allow NULL values; \"YES\" means the column might\n       allow NULL values.  An empty string means nobody knows.\n   </OL>\n\n  @param catalog a catalog name; \"\" retrieves those without a\n  catalog; null means drop catalog name from the selection criteria\n  @param schemaPattern a schema name pattern; \"\" retrieves those\n  without a schema\n  @param tableNamePattern a table name pattern\n  @param columnNamePattern a column name pattern\n  @return <code>ResultSet</code> - each row is a column description\n  @see #getSearchStringEscape\n}\nfunction TZOracleDatabaseMetadata.UncachedGetColumns(const Catalog: string;\n  const SchemaPattern: string; const TableNamePattern: string;\n  const ColumnNamePattern: string): IZResultSet;\nvar\n  SQL: string;\n  SQLType: TZSQLType;\n  OwnerCondition,TableCondition,ColumnCondition: String;\n\n  function CreateWhere: String;\n  begin\n    Result := '';\n    If OwnerCondition <> '' then\n      Result := OwnerCondition;\n    If TableCondition <> '' then\n      If Result <> '' then\n        Result := Result + ' AND ' + TableCondition\n      Else\n        Result := TableCondition;\n    If ColumnCondition <> '' then\n      If Result <> '' then\n        Result := Result + ' AND ' + ColumnCondition\n      Else\n        Result := ColumnCondition;\n    If Result <> '' then\n      Result := ' Where ' + Result;\n  end;\n\nbegin\n  OwnerCondition := ConstructNameCondition(SchemaPattern,'OWNER');\n  TableCondition := ConstructNameCondition(TableNamePattern,'TABLE_NAME');\n  ColumnCondition := ConstructNameCondition(ColumnNamePattern,'COLUMN_NAME');\n  Result:=inherited UncachedGetColumns(Catalog, SchemaPattern, TableNamePattern, ColumnNamePattern);\n\n  SQL := 'SELECT NULL, OWNER, TABLE_NAME, COLUMN_NAME, NULL, DATA_TYPE,'\n    + ' DATA_LENGTH, NULL, DATA_PRECISION, DATA_SCALE, NULLABLE, NULL,'\n    + ' DATA_DEFAULT, NULL, NULL, NULL, COLUMN_ID, NULLABLE'\n    + ' FROM SYS.ALL_TAB_COLUMNS'\n    + CreateWhere;\n\n  with GetConnection.CreateStatement.ExecuteQuery(SQL) do\n  begin\n    while Next do\n    begin\n      Result.MoveToInsertRow;\n      Result.UpdateNull(1);\n      Result.UpdateString(2, GetString(2));\n      Result.UpdateString(3, GetString(3));\n      Result.UpdateString(4, GetString(4));\n      SQLType := ConvertOracleTypeToSQLType(GetString(6), GetInt(9),\n        GetInt(10), ConSettings.CPType);\n      Result.UpdateInt(5, Ord(SQLType));\n      Result.UpdateString(6, GetString(6));\n      Result.UpdateInt(7, GetFieldSize(SQLType, ConSettings, GetInt(7), ConSettings.ClientCodePage.CharWidth)); //FIELD_SIZE\n      Result.UpdateNull(8);\n      Result.UpdateInt(9, GetInt(9));\n      Result.UpdateInt(10, GetInt(10));\n\n      if UpperCase(GetString(11)) = 'N' then\n      begin\n        Result.UpdateInt(11, Ord(ntNoNulls));\n        Result.UpdateString(18, 'NO');\n      end\n      else\n      begin\n        Result.UpdateInt(11, Ord(ntNullable));\n        Result.UpdateString(18, 'YES');\n      end;\n\n      Result.UpdateNull(12);\n      Result.UpdateString(13, GetString(13));\n      Result.UpdateNull(14);\n      Result.UpdateNull(15);\n      Result.UpdateNull(16);\n      Result.UpdateInt(17, GetInt(17));\n\n      Result.UpdateNull(19);   //AUTO_INCREMENT\n      Result.UpdateBoolean(20, //CASE_SENSITIVE\n        IC.IsCaseSensitive(GetString(4)));\n      Result.UpdateBoolean(21, True);  //SEARCHABLE\n      Result.UpdateBoolean(22, not (GetString(6) = 'BFILE'));  //WRITABLE\n      Result.UpdateBoolean(23, True);  //DEFINITELYWRITABLE\n      Result.UpdateBoolean(24, (GetString(6) = 'BFILE')); //READONLY\n\n      Result.InsertRow;\n    end;\n    Close;\n  end;\nend;\n\n{**\n  Gets a description of the access rights for a table's columns.\n\n  <P>Only privileges matching the column name criteria are\n  returned.  They are ordered by COLUMN_NAME and PRIVILEGE.\n\n  <P>Each privilige description has the following columns:\n   <OL>\n \t<LI><B>TABLE_CAT</B> String => table catalog (may be null)\n \t<LI><B>TABLE_SCHEM</B> String => table schema (may be null)\n \t<LI><B>TABLE_NAME</B> String => table name\n \t<LI><B>COLUMN_NAME</B> String => column name\n \t<LI><B>GRANTOR</B> => grantor of access (may be null)\n \t<LI><B>GRANTEE</B> String => grantee of access\n \t<LI><B>PRIVILEGE</B> String => name of access (SELECT,\n       INSERT, UPDATE, REFRENCES, ...)\n \t<LI><B>IS_GRANTABLE</B> String => \"YES\" if grantee is permitted\n       to grant to others; \"NO\" if not; null if unknown\n   </OL>\n\n  @param catalog a catalog name; \"\" retrieves those without a\n  catalog; null means drop catalog name from the selection criteria\n  @param schema a schema name; \"\" retrieves those without a schema\n  @param table a table name\n  @param columnNamePattern a column name pattern\n  @return <code>ResultSet</code> - each row is a column privilege description\n  @see #getSearchStringEscape\n}\nfunction TZOracleDatabaseMetadata.UncachedGetColumnPrivileges(const Catalog: string;\n  const Schema: string; const Table: string; const ColumnNamePattern: string): IZResultSet;\nvar\n  SQL: string;\n  OwnerCondition,TableCondition,ColumnCondition: String;\n\n  function CreateWhere: String;\n  begin\n    Result := '';\n    If OwnerCondition <> '' then\n      Result := OwnerCondition;\n    If TableCondition <> '' then\n      If Result <> '' then\n        Result := Result + ' AND ' + TableCondition\n      Else\n        Result := TableCondition;\n    If ColumnCondition <> '' then\n      If Result <> '' then\n        Result := Result + ' AND ' + ColumnCondition\n      Else\n        Result := ColumnCondition;\n    If Result <> '' then\n      Result := ' Where ' + Result;\n  end;\n\nbegin\n  OwnerCondition := ConstructNameCondition(Schema,'TABLE_SCHEMA');\n  TableCondition := ConstructNameCondition(Table,'TABLE_NAME');\n  ColumnCondition := ConstructNameCondition(ColumnNamePattern,'COLUMN_NAME');\n  SQL := 'SELECT NULL AS TABLE_CAT, TABLE_SCHEMA AS TABLE_SCHEM, TABLE_NAME,'\n    + ' COLUMN_NAME, GRANTOR, GRANTEE, PRIVILEGE, GRANTABLE AS IS_GRANTABLE'\n    + ' FROM SYS.ALL_COL_PRIVS'\n    + CreateWhere;\n\n  Result := CopyToVirtualResultSet(\n    GetConnection.CreateStatement.ExecuteQuery(SQL),\n    ConstructVirtualResultSet(TableColPrivColumnsDynArray));\nend;\n\n{**\n  Gets a description of the access rights for each table available\n  in a catalog. Note that a table privilege applies to one or\n  more columns in the table. It would be wrong to assume that\n  this priviledge applies to all columns (this may be true for\n  some systems but is not true for all.)\n\n  <P>Only privileges matching the schema and table name\n  criteria are returned.  They are ordered by TABLE_SCHEM,\n  TABLE_NAME, and PRIVILEGE.\n\n  <P>Each privilige description has the following columns:\n   <OL>\n \t<LI><B>TABLE_CAT</B> String => table catalog (may be null)\n \t<LI><B>TABLE_SCHEM</B> String => table schema (may be null)\n \t<LI><B>TABLE_NAME</B> String => table name\n \t<LI><B>GRANTOR</B> => grantor of access (may be null)\n \t<LI><B>GRANTEE</B> String => grantee of access\n \t<LI><B>PRIVILEGE</B> String => name of access (SELECT,\n       INSERT, UPDATE, REFRENCES, ...)\n \t<LI><B>IS_GRANTABLE</B> String => \"YES\" if grantee is permitted\n       to grant to others; \"NO\" if not; null if unknown\n   </OL>\n\n  @param catalog a catalog name; \"\" retrieves those without a\n  catalog; null means drop catalog name from the selection criteria\n  @param schemaPattern a schema name pattern; \"\" retrieves those\n  without a schema\n  @param tableNamePattern a table name pattern\n  @return <code>ResultSet</code> - each row is a table privilege description\n  @see #getSearchStringEscape\n}\nfunction TZOracleDatabaseMetadata.UncachedGetTablePrivileges(const Catalog: string;\n  const SchemaPattern: string; const TableNamePattern: string): IZResultSet;\nvar\n  SQL: string;\n  OwnerCondition,TableCondition: String;\n\n  function CreateWhere: String;\n  begin\n    Result := '';\n    If OwnerCondition <> '' then\n      Result := OwnerCondition;\n    If TableCondition <> '' then\n      If Result <> '' then\n        Result := Result + ' AND ' + TableCondition\n      Else\n        Result := TableCondition;\n    If Result <> '' then\n      Result := ' Where ' + Result;\n  end;\n\nbegin\n  OwnerCondition := ConstructNameCondition(SchemaPattern,'TABLE_SCHEMA');\n  TableCondition := ConstructNameCondition(TableNamePattern,'TABLE_NAME');\n  SQL := 'SELECT NULL AS TABLE_CAT, TABLE_SCHEMA AS TABLE_SCHEM, TABLE_NAME,'\n    + ' GRANTOR, GRANTEE, PRIVILEGE, GRANTABLE AS IS_GRANTABLE'\n    + ' FROM SYS.ALL_TAB_PRIVS '\n    + CreateWhere;\n\n  Result := CopyToVirtualResultSet(\n    GetConnection.CreateStatement.ExecuteQuery(SQL),\n    ConstructVirtualResultSet(TablePrivColumnsDynArray));\nend;\n\n{**\n  Gets a description of a table's primary key columns.  They\n  are ordered by COLUMN_NAME.\n\n  <P>Each primary key column description has the following columns:\n   <OL>\n \t<LI><B>TABLE_CAT</B> String => table catalog (may be null)\n \t<LI><B>TABLE_SCHEM</B> String => table schema (may be null)\n \t<LI><B>TABLE_NAME</B> String => table name\n \t<LI><B>COLUMN_NAME</B> String => column name\n \t<LI><B>KEY_SEQ</B> short => sequence number within primary key\n \t<LI><B>PK_NAME</B> String => primary key name (may be null)\n   </OL>\n\n  @param catalog a catalog name; \"\" retrieves those without a\n  catalog; null means drop catalog name from the selection criteria\n  @param schema a schema name; \"\" retrieves those\n  without a schema\n  @param table a table name\n  @return <code>ResultSet</code> - each row is a primary key column description\n  @exception SQLException if a database access error occurs\n}\nfunction TZOracleDatabaseMetadata.UncachedGetPrimaryKeys(const Catalog: string;\n  const Schema: string; const Table: string): IZResultSet;\nvar\n  SQL: string;\n  OwnerCondition,TableCondition: String;\n\n  function CreateExtraWhere: String;\n  begin\n    Result := '';\n    If OwnerCondition <> '' then\n      Result := OwnerCondition;\n    If TableCondition <> '' then\n      If Result <> '' then\n        Result := Result + ' AND ' + TableCondition\n      Else\n        Result := TableCondition;\n    If Result <> '' then\n      Result := ' AND ' + Result;\n  end;\n\nbegin\n  OwnerCondition := ConstructNameCondition(Schema,'A.OWNER');\n  TableCondition := ConstructNameCondition(Table,'A.TABLE_NAME');\n  SQL := 'SELECT NULL AS TABLE_CAT, A.OWNER AS TABLE_SCHEM, A.TABLE_NAME,'\n    + ' B.COLUMN_NAME, B.COLUMN_POSITION AS KEY_SEQ, A.INDEX_NAME AS PK_NAME'\n    + ' FROM ALL_INDEXES A, ALL_IND_COLUMNS B'\n    + ' WHERE A.OWNER=B.INDEX_OWNER AND A.INDEX_NAME=B.INDEX_NAME'\n    + ' AND A.TABLE_OWNER=B.TABLE_OWNER AND A.TABLE_NAME=B.TABLE_NAME'\n    + ' AND A.UNIQUENESS=''UNIQUE'' AND A.GENERATED=''Y'''\n    + ' AND A.INDEX_NAME LIKE ''SYS_%'''\n    + CreateExtraWhere\n    + ' ORDER BY A.INDEX_NAME, B.COLUMN_POSITION';\n\n  Result := CopyToVirtualResultSet(\n    GetConnection.CreateStatement.ExecuteQuery(SQL),\n    ConstructVirtualResultSet(PrimaryKeyColumnsDynArray));\nend;\n\n{**\n  Gets a description of a table's indices and statistics. They are\n  ordered by NON_UNIQUE, TYPE, INDEX_NAME, and ORDINAL_POSITION.\n\n  <P>Each index column description has the following columns:\n   <OL>\n \t<LI><B>TABLE_CAT</B> String => table catalog (may be null)\n \t<LI><B>TABLE_SCHEM</B> String => table schema (may be null)\n \t<LI><B>TABLE_NAME</B> String => table name\n \t<LI><B>NON_UNIQUE</B> Boolean => Can index values be non-unique?\n       false when TYPE is tableIndexStatistic\n \t<LI><B>INDEX_QUALIFIER</B> String => index catalog (may be null);\n       null when TYPE is tableIndexStatistic\n \t<LI><B>INDEX_NAME</B> String => index name; null when TYPE is\n       tableIndexStatistic\n \t<LI><B>TYPE</B> short => index type:\n       <UL>\n       <LI> tableIndexStatistic - this identifies table statistics that are\n            returned in conjuction with a table's index descriptions\n       <LI> tableIndexClustered - this is a clustered index\n       <LI> tableIndexHashed - this is a hashed index\n       <LI> tableIndexOther - this is some other style of index\n       </UL>\n \t<LI><B>ORDINAL_POSITION</B> short => column sequence number\n       within index; zero when TYPE is tableIndexStatistic\n \t<LI><B>COLUMN_NAME</B> String => column name; null when TYPE is\n       tableIndexStatistic\n \t<LI><B>ASC_OR_DESC</B> String => column sort sequence, \"A\" => ascending,\n       \"D\" => descending, may be null if sort sequence is not supported;\n       null when TYPE is tableIndexStatistic\n \t<LI><B>CARDINALITY</B> int => When TYPE is tableIndexStatistic, then\n       this is the number of rows in the table; otherwise, it is the\n       number of unique values in the index.\n \t<LI><B>PAGES</B> int => When TYPE is  tableIndexStatisic then\n       this is the number of pages used for the table, otherwise it\n       is the number of pages used for the current index.\n \t<LI><B>FILTER_CONDITION</B> String => Filter condition, if any.\n       (may be null)\n   </OL>\n\n  @param catalog a catalog name; \"\" retrieves those without a\n  catalog; null means drop catalog name from the selection criteria\n  @param schema a schema name; \"\" retrieves those without a schema\n  @param table a table name\n  @param unique when true, return only indices for unique values;\n      when false, return indices regardless of whether unique or not\n  @param approximate when true, result is allowed to reflect approximate\n      or out of data values; when false, results are requested to be\n      accurate\n  @return <code>ResultSet</code> - each row is an index column description\n}\nfunction TZOracleDatabaseMetadata.UncachedGetIndexInfo(const Catalog: string;\n  const Schema: string; const Table: string; Unique: Boolean;\n  Approximate: Boolean): IZResultSet;\nvar\n  SQL: string;\n  OwnerCondition,TableCondition: String;\n\n  function CreateExtraWhere: String;\n  begin\n    Result := '';\n    If OwnerCondition <> '' then\n      Result := OwnerCondition;\n    If TableCondition <> '' then\n      If Result <> '' then\n        Result := Result + ' AND ' + TableCondition\n      Else\n        Result := TableCondition;\n    If Result <> '' then\n      Result := ' AND ' + Result;\n  end;\n\nbegin\n  OwnerCondition := ConstructNameCondition(Schema,'A.TABLE_OWNER');\n  TableCondition := ConstructNameCondition(Table,'A.TABLE_NAME');\n  Result:=inherited UncachedGetIndexInfo(Catalog, Schema, Table, Unique, Approximate);\n\n  SQL := 'SELECT NULL, A.OWNER, A.TABLE_NAME, A.UNIQUENESS, NULL,'\n    + ' A.INDEX_NAME, 3, B.COLUMN_POSITION, B.COLUMN_NAME, B.DESCEND,'\n    + ' 0, 0, NULL FROM ALL_INDEXES A, ALL_IND_COLUMNS B'\n    + ' WHERE A.OWNER=B.INDEX_OWNER AND A.INDEX_NAME=B.INDEX_NAME'\n    + ' AND A.TABLE_OWNER=B.TABLE_OWNER AND A.TABLE_NAME=B.TABLE_NAME'\n    + CreateExtraWhere;\n  if Unique then\n    SQL := SQL + ' AND A.UNIQUENESS=''UNIQUE''';\n  SQL := SQL + ' ORDER BY A.UNIQUENESS DESC, A.INDEX_NAME, B.COLUMN_POSITION';\n\n  with GetConnection.CreateStatement.ExecuteQuery(SQL) do\n  begin\n    while Next do\n    begin\n      Result.MoveToInsertRow;\n\n      Result.UpdateNull(1);\n      Result.UpdateString(2, GetString(2));\n      Result.UpdateString(3, GetString(3));\n      Result.UpdateBoolean(4,\n        UpperCase(GetString(4)) <> 'UNIQUE');\n      Result.UpdateNull(5);\n      Result.UpdateString(6, GetString(6));\n      Result.UpdateInt(7, GetInt(7));\n      Result.UpdateInt(8, GetInt(8));\n      Result.UpdateString(9, GetString(9));\n      if GetString(10) = 'ASC' then\n        Result.UpdateString(10, 'A')\n      else Result.UpdateString(10, 'D');\n      Result.UpdateInt(11, GetInt(11));\n      Result.UpdateInt(12, GetInt(12));\n      Result.UpdateNull(13);\n\n      Result.InsertRow;\n    end;\n    Close;\n  end;\nend;\n\nend.\n"
  },
  {
    "path": "lib/zeosdbo/src/dbc/ZDbcOracleResultSet.pas",
    "content": "{*********************************************************}\n{                                                         }\n{                 Zeos Database Objects                   }\n{         Oracle Database Connectivity Classes        }\n{                                                         }\n{        Originally written by Sergey Seroukhov           }\n{                                                         }\n{*********************************************************}\n\n{@********************************************************}\n{    Copyright (c) 1999-2012 Zeos Development Group       }\n{                                                         }\n{ License Agreement:                                      }\n{                                                         }\n{ This library is distributed in the hope that it will be }\n{ useful, but WITHOUT ANY WARRANTY; without even the      }\n{ implied warranty of MERCHANTABILITY or FITNESS FOR      }\n{ A PARTICULAR PURPOSE.  See the GNU Lesser General       }\n{ Public License for more details.                        }\n{                                                         }\n{ The source code of the ZEOS Libraries and packages are  }\n{ distributed under the Library GNU General Public        }\n{ License (see the file COPYING / COPYING.ZEOS)           }\n{ with the following  modification:                       }\n{ As a special exception, the copyright holders of this   }\n{ library give you permission to link this library with   }\n{ independent modules to produce an executable,           }\n{ regardless of the license terms of these independent    }\n{ modules, and to copy and distribute the resulting       }\n{ executable under terms of your choice, provided that    }\n{ you also meet, for each linked independent module,      }\n{ the terms and conditions of the license of that module. }\n{ An independent module is a module which is not derived  }\n{ from or based on this library. If you modify this       }\n{ library, you may extend this exception to your version  }\n{ of the library, but you are not obligated to do so.     }\n{ If you do not wish to do so, delete this exception      }\n{ statement from your version.                            }\n{                                                         }\n{                                                         }\n{ The project web site is located on:                     }\n{   http://zeos.firmos.at  (FORUM)                        }\n{   http://sourceforge.net/p/zeoslib/tickets/ (BUGTRACKER)}\n{   svn://svn.code.sf.net/p/zeoslib/code-0/trunk (SVN)    }\n{                                                         }\n{   http://www.sourceforge.net/projects/zeoslib.          }\n{                                                         }\n{                                                         }\n{                                 Zeos Development Group. }\n{********************************************************@}\n\nunit ZDbcOracleResultSet;\n\ninterface\n\n{$I ZDbc.inc}\n\nuses\n  {$IFDEF WITH_TOBJECTLIST_INLINE}System.Types, System.Contnrs{$ELSE}Types{$ENDIF},\n  Classes, {$IFDEF MSEgui}mclasses,{$ENDIF} SysUtils,\n  ZSysUtils, ZDbcIntfs, ZDbcOracle, ZDbcResultSet, ZPlainOracleDriver,\n  ZDbcResultSetMetadata, ZDbcLogging, ZCompatibility, ZDbcOracleUtils,\n  ZPlainOracleConstants;\n\ntype\n\n  {** Implements Oracle ResultSet. }\n  TZOracleAbstractResultSet = class(TZAbstractResultSet)\n  private\n    FSQL: string;\n    FStmtHandle: POCIStmt;\n    FErrorHandle: POCIError;\n    FPlainDriver: IZOraclePlainDriver;\n    FConnection: IZOracleConnection;\n    FOutVars: PZSQLVars;\n  protected\n    function GetSQLVarHolder(ColumnIndex: Integer): PZSQLVar;\n    function GetAsStringValue(ColumnIndex: Integer;\n      SQLVarHolder: PZSQLVar): RawByteString;\n    function GetAsLongIntValue(ColumnIndex: Integer;\n      SQLVarHolder: PZSQLVar): LongInt;\n    function GetAsDoubleValue(ColumnIndex: Integer;\n      SQLVarHolder: PZSQLVar): Double;\n    function GetAsDateTimeValue(ColumnIndex: Integer;\n      SQLVarHolder: PZSQLVar): TDateTime;\n    function InternalGetString(ColumnIndex: Integer): RawByteString; override;\n    function GetFinalObject(Obj: POCIObject): POCIObject;\n  public\n    constructor Create(PlainDriver: IZOraclePlainDriver;\n      Statement: IZStatement; SQL: string; StmtHandle: POCIStmt;\n      ErrorHandle: POCIError);\n\n    function IsNull(ColumnIndex: Integer): Boolean; override;\n    function GetBoolean(ColumnIndex: Integer): Boolean; override;\n    function GetByte(ColumnIndex: Integer): Byte; override;\n    function GetShort(ColumnIndex: Integer): SmallInt; override;\n    function GetInt(ColumnIndex: Integer): Integer; override;\n    function GetLong(ColumnIndex: Integer): Int64; override;\n    function GetFloat(ColumnIndex: Integer): Single; override;\n    function GetDouble(ColumnIndex: Integer): Double; override;\n    function GetBigDecimal(ColumnIndex: Integer): Extended; override;\n    function GetBytes(ColumnIndex: Integer): TByteDynArray; override;\n    function GetDate(ColumnIndex: Integer): TDateTime; override;\n    function GetTime(ColumnIndex: Integer): TDateTime; override;\n    function GetTimestamp(ColumnIndex: Integer): TDateTime; override;\n    function GetDataSet(ColumnIndex: Integer): IZDataSet; override;\n    function GetBlob(ColumnIndex: Integer): IZBlob; override;\n  end;\n\n  TZOracleResultSet = class(TZOracleAbstractResultSet)\n  protected\n    procedure Open; override;\n  public\n    procedure Close; override;\n    function Next: Boolean; override;\n  end;\n\n  TZOracleCallableResultSet = Class(TZOracleAbstractResultSet)\n  private\n    FFieldNames: TStringDynArray;\n    function PrepareOracleOutVars(Statement: IZStatement; InVars: PZSQLVars;\n      const OracleParams: TZOracleParams): PZSQLVars;\n  protected\n    procedure Open; override;\n  public\n    constructor Create(PlainDriver: IZOraclePlainDriver;\n      Statement: IZStatement; SQL: string; StmtHandle: POCIStmt;\n      ErrorHandle: POCIError; OutVars: PZSQLVars; const OracleParams: TZOracleParams);\n    procedure Close; override;\n    function Next: Boolean; override;\n  End;\n\n  {** Represents an interface, specific for Oracle blobs. }\n  IZOracleBlob = interface(IZBlob)\n    ['{3D861AAC-B263-42F1-B359-2A188D1D986A}']\n    function GetLobLocator: POCILobLocator;\n    procedure CreateBlob;\n    procedure ReadBlob;\n    procedure WriteBlob;\n  end;\n\n  {** Implements external blob wrapper object for Oracle. }\n  TZOracleBlob = class(TZAbstractBlob, IZOracleBlob)\n  private\n    FHandle: IZConnection;\n    FLobLocator: POCILobLocator;\n    FPlainDriver: IZOraclePlainDriver;\n    FBlobType: TZSQLType;\n    FTemporary: Boolean;\n    FChunkSize: Integer;\n  protected\n    procedure InternalSetData(AData: Pointer; ASize: Integer);\n  public\n    constructor Create(PlainDriver: IZOraclePlainDriver; Data: Pointer;\n      Size: Integer; Handle: IZConnection; LobLocator: POCILobLocator;\n      BlobType: TZSQLType; ChunkSize: Integer);\n    destructor Destroy; override;\n\n    function GetLobLocator: POCILobLocator;\n    procedure CreateBlob;\n    procedure ReadBlob;\n    procedure WriteBlob;\n\n    function Length: LongInt; override;\n    function IsEmpty: Boolean; override;\n    function Clone: IZBlob; override;\n\n    function GetString: RawByteString; override;\n    function GetBytes: TByteDynArray; override;\n    function GetStream: TStream; override;\n  end;\n\nimplementation\n\nuses\n  Math, ZMessages, ZDbcUtils, ZEncoding;\n\n{ TZOracleAbstractResultSet }\n\n{**\n  Constructs this object, assignes main properties and\n  opens the record set.\n  @param PlainDriver a Oracle plain driver.\n  @param Statement a related SQL statement object.\n  @param SQL a SQL statement.\n  @param Handle a Oracle specific query handle.\n}\nconstructor TZOracleAbstractResultSet.Create(PlainDriver: IZOraclePlainDriver;\n  Statement: IZStatement; SQL: string; StmtHandle: POCIStmt;\n  ErrorHandle: POCIError);\nbegin\n  inherited Create(Statement, SQL, nil, Statement.GetConnection.GetConSettings);\n\n  FSQL := SQL;\n  FStmtHandle := StmtHandle;\n  FErrorHandle := ErrorHandle;\n  FPlainDriver := PlainDriver;\n  ResultSetConcurrency := rcReadOnly;\n  FConnection := Statement.GetConnection as IZOracleConnection;\n\n  Open;\nend;\n\n{**\n  Indicates if the value of the designated column in the current row\n  of this <code>ResultSet</code> object is Null.\n\n  @param columnIndex the first column is 1, the second is 2, ...\n  @return if the value is SQL <code>NULL</code>, the\n    value returned is <code>true</code>. <code>false</code> otherwise.\n}\nfunction TZOracleAbstractResultSet.IsNull(ColumnIndex: Integer): Boolean;\nvar\n  CurrentVar: PZSQLVar;\nbegin\n{$IFNDEF DISABLE_CHECKING}\n  CheckClosed;\n  if (RowNo < 1) or (RowNo > LastRowNo) then\n    raise EZSQLException.Create(SRowDataIsNotAvailable);\n  if (ColumnIndex <=0) or (ColumnIndex > FOutVars.ActualNum) then\n  begin\n    raise EZSQLException.Create(\n      Format(SColumnIsNotAccessable, [ColumnIndex]));\n  end;\n{$ENDIF}\n\n  CurrentVar := @FOutVars.Variables[ColumnIndex];\n  Result := (CurrentVar.Indicator < 0);\nend;\n\n{**\n  Gets a holder for SQL output variable.\n  @param ColumnIndex an index of the column to read.\n  @returns an output variable holder or <code>nil</code> if column is empty.\n}\nfunction TZOracleAbstractResultSet.GetSQLVarHolder(ColumnIndex: Integer): PZSQLVar;\nbegin\n{$IFNDEF DISABLE_CHECKING}\n  CheckClosed;\n  if (RowNo < 1) or (RowNo > LastRowNo) then\n    raise EZSQLException.Create(SRowDataIsNotAvailable);\n{$ENDIF}\n\n  Result := @FOutVars.Variables[ColumnIndex];\n  LastWasNull := (Result.Indicator < 0) or (Result.Data = nil);\n  if LastWasNull then\n    Result := nil;\nend;\n\n{**\n  Gets the value of the designated column in the current row\n  of this <code>ResultSet</code> object as a <code>String</code>.\n\n  @param ColumnIndex the first column is 1, the second is 2, ...\n  @param SQLVarHolder a reference to SQL variable holder or <code>nil</code>\n    to force retrieving the variable.\n  @return the column value; if the value is SQL <code>NULL</code>, the\n    value returned is <code>null</code>\n}\nfunction TZOracleAbstractResultSet.GetAsStringValue(ColumnIndex: Integer;\n  SQLVarHolder: PZSQLVar): RawByteString;\nvar\n  OldSeparator: Char;\n  Blob: IZBlob;\nbegin\n  if SQLVarHolder = nil then\n    SQLVarHolder := GetSQLVarHolder(ColumnIndex);\n  if SQLVarHolder <> nil then\n  begin\n    case SQLVarHolder.TypeCode of\n      SQLT_INT:\n        Result := AnsiString(IntToStr(PLongInt(SQLVarHolder.Data)^));\n      SQLT_FLT:\n        begin\n          OldSeparator := {$IFDEF WITH_FORMATSETTINGS}FormatSettings.{$ENDIF}DecimalSeparator;\n          {$IFDEF WITH_FORMATSETTINGS}FormatSettings.{$ENDIF}DecimalSeparator := '.';\n          Result := AnsiString(FloatToSqlStr(PDouble(SQLVarHolder.Data)^));\n          {$IFDEF WITH_FORMATSETTINGS}FormatSettings.{$ENDIF}DecimalSeparator := OldSeparator;\n        end;\n      SQLT_STR:\n        Result := PAnsiChar(SQLVarHolder.Data);\n      SQLT_LVB, SQLT_LVC, SQLT_BIN:\n        begin\n          Result := AnsiString(BufferToStr(PAnsiChar(SQLVarHolder.Data) + SizeOf(Integer),\n            PInteger(SQLVarHolder.Data)^));\n        end;\n      SQLT_DAT, SQLT_TIMESTAMP:\n        begin\n          Result := AnsiString(DateTimeToAnsiSQLDate(\n            GetAsDateTimeValue(ColumnIndex, SQLVarHolder)));\n        end;\n      SQLT_BLOB, SQLT_CLOB:\n        begin\n          Blob := GetBlob(ColumnIndex);\n          Result := Blob.GetString;\n        end;\n    end;\n  end\n  else\n    Result := '';\nend;\n\n{**\n  Gets the value of the designated column in the current row\n  of this <code>ResultSet</code> object as a <code>LongInt</code>.\n\n  @param ColumnIndex the first column is 1, the second is 2, ...\n  @param SQLVarHolder a reference to SQL variable holder or <code>nil</code>\n    to force retrieving the variable.\n  @return the column value; if the value is SQL <code>NULL</code>, the\n    value returned is <code>0</code>\n}\nfunction TZOracleAbstractResultSet.GetAsLongIntValue(ColumnIndex: Integer;\n  SQLVarHolder: PZSQLVar): LongInt;\nbegin\n  if SQLVarHolder = nil then\n    SQLVarHolder := GetSQLVarHolder(ColumnIndex);\n  if SQLVarHolder <> nil then\n  begin\n    case SQLVarHolder.TypeCode of\n      SQLT_INT:\n        Result := PLongInt(SQLVarHolder.Data)^;\n      SQLT_FLT:\n        Result := Trunc(PDouble(SQLVarHolder.Data)^);\n      else\n      begin\n        Result := Trunc(SqlStrToFloatDef(\n          GetAsStringValue(ColumnIndex, SQLVarHolder), 0));\n      end;\n    end;\n  end\n  else\n    Result := 0;\nend;\n\n{**\n  Gets the value of the designated column in the current row\n  of this <code>ResultSet</code> object as a <code>Double</code>.\n\n  @param ColumnIndex the first column is 1, the second is 2, ...\n  @param SQLVarHolder a reference to SQL variable holder or <code>nil</code>\n    to force retrieving the variable.\n  @return the column value; if the value is SQL <code>NULL</code>, the\n    value returned is <code>0.0</code>\n}\nfunction TZOracleAbstractResultSet.GetAsDoubleValue(ColumnIndex: Integer;\n  SQLVarHolder: PZSQLVar): Double;\nbegin\n  if SQLVarHolder = nil then\n    SQLVarHolder := GetSQLVarHolder(ColumnIndex);\n  if SQLVarHolder <> nil then\n  begin\n    case SQLVarHolder.TypeCode of\n      SQLT_INT:\n        Result := PLongInt(SQLVarHolder.Data)^;\n      SQLT_FLT:\n        Result := PDouble(SQLVarHolder.Data)^;\n      else\n      begin\n        Result := SqlStrToFloatDef(\n          GetAsStringValue(ColumnIndex, SQLVarHolder), 0);\n      end;\n    end;\n  end\n  else\n    Result := 0;\nend;\n\n{**\n  Gets the value of the designated column in the current row\n  of this <code>ResultSet</code> object as a <code>DateTime</code>.\n\n  @param ColumnIndex the first column is 1, the second is 2, ...\n  @param SQLVarHolder a reference to SQL variable holder or <code>nil</code>\n    to force retrieving the variable.\n  @return the column value; if the value is SQL <code>NULL</code>, the\n    value returned is <code>0</code>\n}\nfunction TZOracleAbstractResultSet.GetAsDateTimeValue(ColumnIndex: Integer;\n  SQLVarHolder: PZSQLVar): TDateTime;\nvar\n  Status: Integer;\n  Year: SmallInt;\n  Month, Day: Byte;\n  Hour, Minute, Second: Byte;\n  Millis: Integer;\n  Connection: IZOracleConnection;\nbegin\n  if SQLVarHolder = nil then\n    SQLVarHolder := GetSQLVarHolder(ColumnIndex);\n  if SQLVarHolder <> nil then\n  begin\n    case SQLVarHolder.TypeCode of\n      SQLT_DAT:\n        Result := OraDateToDateTime(SQLVarHolder.Data);\n      SQLT_TIMESTAMP:\n        begin\n          Connection := GetStatement.GetConnection as IZOracleConnection;\n          if SQLVarHolder.ColType in [stDate, stTimestamp] then\n          begin\n            Status := FPlainDriver.DateTimeGetDate(\n              Connection.GetConnectionHandle,\n              FErrorHandle, PPOCIDescriptor(SQLVarHolder.Data)^,\n              Year, Month, Day);\n            // attention : this code handles all timestamps on 01/01/0001 as a pure time value\n            // reason : oracle doesn't have a pure time datatype so all time comparisons compare\n            //          TDateTime values on 30 Dec 1899 against oracle timestamps on 01 januari 0001 (negative TDateTime)\n            if (Status = OCI_SUCCESS) and\n               ((Year <> 1) or (Month <> 1) or (Day <> 1)) then\n              Result := EncodeDate(Year, Month, Day)\n            else\n              Result := 0;\n          end\n          else\n            Result := 0;\n          if SQLVarHolder.ColType in [stTime, stTimestamp] then\n          begin\n            Status := FPlainDriver.DateTimeGetTime(\n              Connection.GetConnectionHandle,\n              FErrorHandle, PPOCIDescriptor(SQLVarHolder.Data)^,\n              Hour, Minute, Second, Millis);\n            if Status = OCI_SUCCESS then\n            begin\n              Millis := Round(Millis / 1000000);\n              if Millis >= 1000 then Millis := 999;\n                Result := Result + EncodeTime(\n                  Hour, Minute, Second, Millis);\n            end;\n          end;\n        end;\n      else\n      begin\n        Result := AnsiSQLDateToDateTime(\n          String(GetAsStringValue(ColumnIndex, SQLVarHolder)));\n      end;\n    end;\n  end\n  else\n    Result := 0;\nend;\n\n{**\n  Gets the value of the designated column in the current row\n  of this <code>ResultSet</code> object as\n  a <code>String</code> in the Java programming language.\n\n  @param columnIndex the first column is 1, the second is 2, ...\n  @return the column value; if the value is SQL <code>NULL</code>, the\n    value returned is <code>null</code>\n}\nfunction TZOracleAbstractResultSet.InternalGetString(ColumnIndex: Integer): RawByteString;\nbegin\n{$IFNDEF DISABLE_CHECKING}\n  CheckColumnConvertion(ColumnIndex, stString);\n{$ENDIF}\n  Result := GetAsStringValue(ColumnIndex, nil);\nend;\n\n{**\n  Gets the final object of a type/named-collection/nested-table,array\n\n  @param obj the parent-object\n  @return the Object which contains the final object descriptor\n}\nfunction TZOracleAbstractResultSet.GetFinalObject(Obj: POCIObject): POCIObject;\nbegin\n  if Obj.is_final_type = 1 then\n    Result := Obj\n  else\n    Result := GetFinalObject(Obj.next_subtype); //recursive call\nend;\n\n{**\n  Gets the value of the designated column in the current row\n  of this <code>ResultSet</code> object as\n  a <code>boolean</code> in the Java programming language.\n\n  @param columnIndex the first column is 1, the second is 2, ...\n  @return the column value; if the value is SQL <code>NULL</code>, the\n    value returned is <code>false</code>\n}\nfunction TZOracleAbstractResultSet.GetBoolean(ColumnIndex: Integer): Boolean;\nvar\n  Temp: string;\nbegin\n{$IFNDEF DISABLE_CHECKING}\n  CheckColumnConvertion(ColumnIndex, stBoolean);\n{$ENDIF}\n  Temp := String(GetAsStringValue(ColumnIndex, nil));\n  Result := (StrToIntDef(Temp, 0) <> 0) or StrToBoolEx(Temp);\nend;\n\n{**\n  Gets the value of the designated column in the current row\n  of this <code>ResultSet</code> object as\n  a <code>byte</code> in the Java programming language.\n\n  @param columnIndex the first column is 1, the second is 2, ...\n  @return the column value; if the value is SQL <code>NULL</code>, the\n    value returned is <code>0</code>\n}\nfunction TZOracleAbstractResultSet.GetByte(ColumnIndex: Integer): Byte;\nbegin\n{$IFNDEF DISABLE_CHECKING}\n  CheckColumnConvertion(ColumnIndex, stByte);\n{$ENDIF}\n  Result := Byte(GetAsLongIntValue(ColumnIndex, nil));\nend;\n\n{**\n  Gets the value of the designated column in the current row\n  of this <code>ResultSet</code> object as\n  a <code>short</code> in the Java programming language.\n\n  @param columnIndex the first column is 1, the second is 2, ...\n  @return the column value; if the value is SQL <code>NULL</code>, the\n    value returned is <code>0</code>\n}\nfunction TZOracleAbstractResultSet.GetShort(ColumnIndex: Integer): SmallInt;\nbegin\n{$IFNDEF DISABLE_CHECKING}\n  CheckColumnConvertion(ColumnIndex, stShort);\n{$ENDIF}\n  Result := SmallInt(GetAsLongIntValue(ColumnIndex, nil));\nend;\n\n{**\n  Gets the value of the designated column in the current row\n  of this <code>ResultSet</code> object as\n  an <code>int</code> in the Java programming language.\n\n  @param columnIndex the first column is 1, the second is 2, ...\n  @return the column value; if the value is SQL <code>NULL</code>, the\n    value returned is <code>0</code>\n}\nfunction TZOracleAbstractResultSet.GetInt(ColumnIndex: Integer): Integer;\nbegin\n{$IFNDEF DISABLE_CHECKING}\n  CheckColumnConvertion(ColumnIndex, stInteger);\n{$ENDIF}\n  Result := Integer(GetAsLongIntValue(ColumnIndex, nil));\nend;\n\n{**\n  Gets the value of the designated column in the current row\n  of this <code>ResultSet</code> object as\n  a <code>long</code> in the Java programming language.\n\n  @param columnIndex the first column is 1, the second is 2, ...\n  @return the column value; if the value is SQL <code>NULL</code>, the\n    value returned is <code>0</code>\n}\nfunction TZOracleAbstractResultSet.GetLong(ColumnIndex: Integer): Int64;\nbegin\n{$IFNDEF DISABLE_CHECKING}\n  CheckColumnConvertion(ColumnIndex, stLong);\n{$ENDIF}\n  Result := Trunc(GetAsDoubleValue(ColumnIndex, nil));\nend;\n\n{**\n  Gets the value of the designated column in the current row\n  of this <code>ResultSet</code> object as\n  a <code>float</code> in the Java programming language.\n\n  @param columnIndex the first column is 1, the second is 2, ...\n  @return the column value; if the value is SQL <code>NULL</code>, the\n    value returned is <code>0</code>\n}\nfunction TZOracleAbstractResultSet.GetFloat(ColumnIndex: Integer): Single;\nbegin\n{$IFNDEF DISABLE_CHECKING}\n  CheckColumnConvertion(ColumnIndex, stFloat);\n{$ENDIF}\n  Result := GetAsDoubleValue(ColumnIndex, nil);\nend;\n\n{**\n  Gets the value of the designated column in the current row\n  of this <code>ResultSet</code> object as\n  a <code>double</code> in the Java programming language.\n\n  @param columnIndex the first column is 1, the second is 2, ...\n  @return the column value; if the value is SQL <code>NULL</code>, the\n    value returned is <code>0</code>\n}\nfunction TZOracleAbstractResultSet.GetDouble(ColumnIndex: Integer): Double;\nbegin\n{$IFNDEF DISABLE_CHECKING}\n  CheckColumnConvertion(ColumnIndex, stDouble);\n{$ENDIF}\n  Result := GetAsDoubleValue(ColumnIndex, nil);\nend;\n\n{**\n  Gets the value of the designated column in the current row\n  of this <code>ResultSet</code> object as\n  a <code>java.sql.BigDecimal</code> in the Java programming language.\n\n  @param columnIndex the first column is 1, the second is 2, ...\n  @param scale the number of digits to the right of the decimal point\n  @return the column value; if the value is SQL <code>NULL</code>, the\n    value returned is <code>null</code>\n}\nfunction TZOracleAbstractResultSet.GetBigDecimal(ColumnIndex: Integer): Extended;\nbegin\n{$IFNDEF DISABLE_CHECKING}\n  CheckColumnConvertion(ColumnIndex, stBigDecimal);\n{$ENDIF}\n  Result := GetAsDoubleValue(ColumnIndex, nil);\nend;\n\n{**\n  Gets the value of the designated column in the current row\n  of this <code>ResultSet</code> object as\n  a <code>byte</code> array in the Java programming language.\n  The bytes represent the raw values returned by the driver.\n\n  @param columnIndex the first column is 1, the second is 2, ...\n  @return the column value; if the value is SQL <code>NULL</code>, the\n    value returned is <code>null</code>\n}\nfunction TZOracleAbstractResultSet.GetBytes(ColumnIndex: Integer): TByteDynArray;\nbegin\n{$IFNDEF DISABLE_CHECKING}\n  CheckColumnConvertion(ColumnIndex, stBytes);\n{$ENDIF}\n  Result := StrToBytes(GetAsStringValue(ColumnIndex, nil));\nend;\n\n{**\n  Gets the value of the designated column in the current row\n  of this <code>ResultSet</code> object as\n  a <code>java.sql.Date</code> object in the Java programming language.\n\n  @param columnIndex the first column is 1, the second is 2, ...\n  @return the column value; if the value is SQL <code>NULL</code>, the\n    value returned is <code>null</code>\n}\nfunction TZOracleAbstractResultSet.GetDate(ColumnIndex: Integer): TDateTime;\nbegin\n{$IFNDEF DISABLE_CHECKING}\n  CheckColumnConvertion(ColumnIndex, stDate);\n{$ENDIF}\n  Result := Trunc(GetAsDateTimeValue(ColumnIndex, nil));\nend;\n\n{**\n  Gets the value of the designated column in the current row\n  of this <code>ResultSet</code> object as\n  a <code>java.sql.Time</code> object in the Java programming language.\n\n  @param columnIndex the first column is 1, the second is 2, ...\n  @return the column value; if the value is SQL <code>NULL</code>, the\n    value returned is <code>null</code>\n}\nfunction TZOracleAbstractResultSet.GetTime(ColumnIndex: Integer): TDateTime;\nbegin\n{$IFNDEF DISABLE_CHECKING}\n  CheckColumnConvertion(ColumnIndex, stTime);\n{$ENDIF}\n  Result := Frac(GetAsDateTimeValue(ColumnIndex, nil));\nend;\n\n{**\n  Gets the value of the designated column in the current row\n  of this <code>ResultSet</code> object as\n  a <code>java.sql.Timestamp</code> object in the Java programming language.\n\n  @param columnIndex the first column is 1, the second is 2, ...\n  @return the column value; if the value is SQL <code>NULL</code>, the\n  value returned is <code>null</code>\n  @exception SQLException if a database access error occurs\n}\nfunction TZOracleAbstractResultSet.GetTimestamp(ColumnIndex: Integer): TDateTime;\nbegin\n{$IFNDEF DISABLE_CHECKING}\n  CheckColumnConvertion(ColumnIndex, stTimestamp);\n{$ENDIF}\n  Result := GetAsDateTimeValue(ColumnIndex, nil);\nend;\n\n{**\n  Returns the value of the designated column in the current row\n  of this <code>ResultSet</code> object as a <code>IZResultSet</code> object\n  in the Java programming language.\n\n  @param ColumnIndex the first column is 1, the second is 2, ...\n  @return a <code>IZResultSet</code> object representing the SQL\n    <code>IZResultSet</code> value in the specified column\n}\nfunction TZOracleAbstractResultSet.GetDataSet(ColumnIndex: Integer): IZDataSet;\nvar\n  CurrentVar: PZSQLVar;\n  type_Ref: POCIRef;\n  //tdo: POCIType;\nbegin\n  Result := nil ;\n{$IFNDEF DISABLE_CHECKING}\n  CheckBlobColumn(ColumnIndex);\n{$ENDIF}\n\n  LastWasNull := IsNull(ColumnIndex);\n  if LastWasNull then\n      Exit;\n\n  GetSQLVarHolder(ColumnIndex);\n  CurrentVar := @FOutVars.Variables[ColumnIndex];\n  Result := nil;\n  if CurrentVar.TypeCode = SQLT_NTY then\n    if CurrentVar.Indicator >= 0 then\n    begin\n      if CurrentVar._Obj.is_final_type = 1 then\n        // here we've the final object lets's read it to test it\n        // later we only need the reference-pointers to create a new dataset\n      else\n      begin\n        //create a temporary object\n        type_ref := nil;\n        CheckOracleError(FPlainDriver, FErrorHandle,\n          FPlainDriver.ObjectNew(FConnection.GetConnectionHandle,\n            FConnection.GetErrorHandle, FConnection.GetContextHandle,\n            OCI_TYPECODE_REF, nil, nil, OCI_DURATION_DEFAULT, TRUE, @type_ref),\n          lcOther, 'OCITypeByRef from OCI_ATTR_REF_TDO');\n        //Get the type reference\n        CheckOracleError(FPlainDriver, FErrorHandle,\n          FPlainDriver.ObjectGetTypeRef(FConnection.GetConnectionHandle,\n            FConnection.GetErrorHandle, CurrentVar._Obj.obj_value, type_Ref),\n          lcOther, 'OCIObjectGetTypeRef(obj_value)');\n\n        //Now let's get the new tdo\n        //Excptions????????\n        {CheckOracleError(FPlainDriver, FErrorHandle,\n          FPlainDriver.TypeByRef(FConnection.GetConnectionHandle,\n            FConnection.GetErrorHandle, type_ref, OCI_DURATION_DEFAULT,\n            OCI_TYPEGET_ALL, @tdo),\n          lcOther, 'OCITypeByRef from OCI_ATTR_REF_TDO');}\n        //free the temporary object\n        CheckOracleError(FPlainDriver, FErrorHandle,\n          FPlainDriver.ObjectFree(FConnection.GetConnectionHandle,\n            FConnection.GetErrorHandle, type_ref, ub2(0)),\n          lcOther, 'ObjectFree()');\n      end;\n\n\n      {CheckOracleError(FPlainDriver, FErrorHandle,\n        FPlainDriver.ResultSetToStmt(CurrentVar._Object,\n          FErrorHandle), lcOther, 'Nested Table to Stmt handle');\n      Result := CreateOracleResultSet(FPlainDriver, GetStatement,\n        'Fetch Nested Table', CurrentVar._Object, FErrorHandle);}\n    end;\nend;\n\n{**\n  Returns the value of the designated column in the current row\n  of this <code>ResultSet</code> object as a <code>Blob</code> object\n  in the Java programming language.\n\n  @param ColumnIndex the first column is 1, the second is 2, ...\n  @return a <code>Blob</code> object representing the SQL <code>BLOB</code> value in\n    the specified column\n}\nfunction TZOracleAbstractResultSet.GetBlob(ColumnIndex: Integer): IZBlob;\nvar\n  Connection: IZOracleConnection;\n  CurrentVar: PZSQLVar;\n  LobLocator: POCILobLocator;\n  Stream: TStream;\nbegin\n  Result := nil ;\n{$IFNDEF DISABLE_CHECKING}\n  CheckBlobColumn(ColumnIndex);\n{$ENDIF}\n\n  LastWasNull := IsNull(ColumnIndex);\n  if LastWasNull then\n      Exit;\n\n  GetSQLVarHolder(ColumnIndex);\n  CurrentVar := @FOutVars.Variables[ColumnIndex];\n  if CurrentVar.TypeCode in [SQLT_BLOB, SQLT_CLOB, SQLT_BFILEE, SQLT_CFILEE] then\n  begin\n    if CurrentVar.Indicator >= 0 then\n      LobLocator := PPOCIDescriptor(CurrentVar.Data)^\n    else\n      LobLocator := nil;\n\n    Connection := GetStatement.GetConnection as IZOracleConnection;\n    Result := TZOracleBlob.Create(FPlainDriver, nil, 0, Connection, LobLocator,\n      CurrentVar.ColType, GetStatement.GetChunkSize);\n    (Result as IZOracleBlob).ReadBlob;\n\n  end\n  else\n    if CurrentVar.TypeCode=SQLT_NTY then\n      Result := TZAbstractBlob.CreateWithStream(nil, GetStatement.GetConnection)\n    else\n    begin\n      if CurrentVar.Indicator >= 0 then\n      begin\n        Stream := nil;\n        try\n          Stream := TStringStream.Create(\n            GetAsStringValue(ColumnIndex, CurrentVar));\n          Result := TZAbstractBlob.CreateWithStream(Stream, GetStatement.GetConnection);\n        finally\n          if Assigned(Stream) then\n            Stream.Free;\n        end;\n      end\n      else\n        Result := TZAbstractBlob.CreateWithStream(nil, GetStatement.GetConnection);\n    end;\nend;\n\n{ TZOracleResultSet }\n\n{**\n  Opens this recordset.\n}\nprocedure TZOracleResultSet.Open;\nvar\n  I: Integer;\n  ColumnInfo: TZColumnInfo;\n  Connection: IZOracleConnection;\n  CurrentVar: PZSQLVar;\n  ColumnCount: ub4;\n  TempColumnName: PAnsiChar;\n  TempColumnNameLen, CSForm: Integer;\nbegin\n  if ResultSetConcurrency = rcUpdatable then\n    raise EZSQLException.Create(SLiveResultSetsAreNotSupported);\n\n  if not Assigned(FStmtHandle) or not Assigned(FErrorHandle) then\n    raise EZSQLException.Create(SCanNotRetrieveResultSetData);\n\n  Connection := GetStatement.GetConnection as IZOracleConnection;\n\n  CheckOracleError(FPlainDriver, FErrorHandle,\n    FPlainDriver.StmtExecute(Connection.GetContextHandle, FStmtHandle,\n    FErrorHandle, 1, 0, nil, nil, OCI_DESCRIBE_ONLY), lcExecute, FSQL);\n\n  { Resize SQLVERS structure if needed }\n  FPlainDriver.AttrGet(FStmtHandle, OCI_HTYPE_STMT, @ColumnCount, nil,\n    OCI_ATTR_PARAM_COUNT, FErrorHandle);\n  AllocateOracleSQLVars(FOutVars, ColumnCount);\n  FOutVars.ActualNum := ColumnCount;\n\n  { Allocates memory for result set }\n  for I := 1 to FOutVars.ActualNum do\n  begin\n    CurrentVar := @FOutVars.Variables[I];\n    CurrentVar.Handle := nil;\n\n    FPlainDriver.ParamGet(FStmtHandle, OCI_HTYPE_STMT, FErrorHandle,\n      CurrentVar.Handle, I);\n    FPlainDriver.AttrGet(CurrentVar.Handle, OCI_DTYPE_PARAM,\n      @CurrentVar.DataSize, nil, OCI_ATTR_DATA_SIZE, FErrorHandle);\n    FPlainDriver.AttrGet(CurrentVar.Handle, OCI_DTYPE_PARAM,\n      @CurrentVar.DataType, nil, OCI_ATTR_DATA_TYPE, FErrorHandle);\n    CurrentVar.Scale := 0;\n    CurrentVar.Precision := 0;\n\n    case CurrentVar.DataType of\n      SQLT_CHR, SQLT_VCS, SQLT_AFC, SQLT_AVC, SQLT_STR, SQLT_VST:\n        CurrentVar.ColType := stString;\n      SQLT_NUM:\n        begin\n          FPlainDriver.AttrGet(CurrentVar.Handle, OCI_DTYPE_PARAM,\n            @CurrentVar.Precision, nil, OCI_ATTR_PRECISION, FErrorHandle);\n          FPlainDriver.AttrGet(CurrentVar.Handle, OCI_DTYPE_PARAM,\n            @CurrentVar.Scale, nil, OCI_ATTR_SCALE, FErrorHandle);\n\n          {by default convert number to double}\n          CurrentVar.ColType := stDouble;\n          if (CurrentVar.Scale = 0) and (CurrentVar.Precision <> 0) then\n          begin\n            if CurrentVar.Precision <= 2 then\n              CurrentVar.ColType := stByte\n            else if CurrentVar.Precision <= 4 then\n              CurrentVar.ColType := stShort\n            else if CurrentVar.Precision <= 9 then\n              CurrentVar.ColType := stInteger\n            else if CurrentVar.Precision <= 19 then\n              CurrentVar.ColType := stLong;\n          end\n        end;\n      SQLT_BFLOAT, SQLT_BDOUBLE, SQLT_IBFLOAT, SQLT_IBDOUBLE:\n        CurrentVar.ColType := stDouble;\n      SQLT_INT, _SQLT_PLI:\n        CurrentVar.ColType := stInteger;\n      SQLT_LNG, SQLT_LVC:\n        CurrentVar.ColType := stAsciiStream;\n      SQLT_RID, SQLT_RDD:\n        begin\n          CurrentVar.ColType := stString;\n          CurrentVar.DataSize := 20;\n        end;\n      SQLT_DAT, SQLT_DATE:\n        { oracle DATE precission - 1 second}\n        CurrentVar.ColType := stTimestamp;\n      SQLT_TIME, SQLT_TIME_TZ:\n        CurrentVar.ColType := stTime;\n      SQLT_TIMESTAMP, SQLT_TIMESTAMP_TZ, SQLT_TIMESTAMP_LTZ:\n        CurrentVar.ColType := stTimestamp;\n      SQLT_BIN, SQLT_LBI:\n        begin\n          if CurrentVar.DataSize = 0 then\n            CurrentVar.ColType := stBinaryStream\n          else\n            CurrentVar.ColType := stBytes;\n        end;\n      SQLT_CLOB:\n        begin\n          CurrentVar.ColType := stAsciiStream;\n          CurrentVar.TypeCode := CurrentVar.DataType;\n        end;\n      SQLT_BLOB, SQLT_BFILEE, SQLT_CFILEE:\n        begin\n          CurrentVar.ColType := stBinaryStream;\n          CurrentVar.TypeCode := CurrentVar.DataType;\n        end;\n      SQLT_NTY:\n        begin\n          CurrentVar.ColType := stDataSet;\n          CurrentVar.TypeCode := CurrentVar.DataType;\n\n          CurrentVar._Obj := DescribeObject(FplainDriver, FConnection,\n            CurrentVar.Handle, FStmtHandle, 0);\n\n          if FPlainDriver.TypeTypeCode(Connection.GetConnectionHandle,\n              FerrorHandle, CurrentVar._Obj.tdo) = SQLT_NCO then\n            CurrentVar.ColType := stDataSet\n          else\n            CurrentVar.ColType := stBinaryStream;\n        end;\n      else\n        CurrentVar.ColType := stUnknown;\n    end;\n\n    if (ConSettings.CPType = cCP_UTF16) then\n      case CurrentVar.ColType of\n        stString: CurrentVar.ColType := stUnicodeString;\n        stAsciiStream: if not ( CurrentVar.DataType in [SQLT_LNG]) then\n          CurrentVar.ColType := stUnicodeStream;\n      end;\n\n\n    InitializeOracleVar(FPlainDriver, Connection, CurrentVar,\n      CurrentVar.ColType, CurrentVar.TypeCode, CurrentVar.DataSize);\n\n    if CurrentVar.ColType <> stUnknown then\n      CheckOracleError(FPlainDriver, FErrorHandle,\n        FPlainDriver.DefineByPos(FStmtHandle, CurrentVar.Define,\n        FErrorHandle, I, CurrentVar.Data, CurrentVar.Length, CurrentVar.TypeCode,\n        @CurrentVar.Indicator, nil, nil, OCI_DEFAULT), lcExecute, FSQL);\n    if CurrentVar.DataType=SQLT_NTY then\n    begin\n      //second step: http://www.csee.umbc.edu/portal/help/oracle8/server.815/a67846/obj_bind.htm\n      CheckOracleError(FPlainDriver, FErrorHandle,\n        FPlainDriver.DefineObject(CurrentVar.Define, FErrorHandle, CurrentVar._Obj.tdo,\n           @CurrentVar._Obj.obj_value, nil, nil, nil), lcExecute, FSQL);\n    end;\n  end;\n\n  { Fills the column info. }\n  ColumnsInfo.Clear;\n  for I := 1 to FOutVars.ActualNum do\n  begin\n    CurrentVar := @FOutVars.Variables[I];\n    ColumnInfo := TZColumnInfo.Create;\n\n    with ColumnInfo do\n    begin\n      ColumnName := '';\n      TableName := '';\n\n      TempColumnName := nil;\n      FPlainDriver.AttrGet(CurrentVar.Handle, OCI_DTYPE_PARAM,\n        @TempColumnName, @TempColumnNameLen, OCI_ATTR_NAME, FErrorHandle);\n      if TempColumnName <> nil then\n        ColumnLabel := BufferToStr(TempColumnName, TempColumnNameLen);\n\n      ColumnDisplaySize := 0;\n      AutoIncrement := False;\n      Signed := True;\n      Nullable := ntNullable;\n\n      ColumnType := CurrentVar.ColType;\n      Scale := CurrentVar.Scale;\n      if (ColumnType in [stString, stUnicodeString]) then\n      begin\n        FPlainDriver.AttrGet(CurrentVar.Handle, OCI_DTYPE_PARAM,\n          @ColumnDisplaySize, nil, OCI_ATTR_DISP_SIZE, FErrorHandle);\n        FPlainDriver.AttrGet(CurrentVar.Handle, OCI_DTYPE_PARAM,\n          @CSForm, nil, OCI_ATTR_CHARSET_FORM, FErrorHandle);\n        if CSForm = SQLCS_NCHAR then //AL16UTF16 or AL16UTF16LE?? We should determine the NCHAR set on connect\n          ColumnDisplaySize := ColumnDisplaySize div 2;\n        Precision := GetFieldSize(ColumnType, ConSettings, ColumnDisplaySize,\n          ConSettings.ClientCodePage^.CharWidth);\n      end\n      else\n        if (ColumnType = stBytes ) then\n          Precision := CurrentVar.DataSize\n        else\n          Precision := CurrentVar.Precision;\n    end;\n\n    ColumnsInfo.Add(ColumnInfo);\n  end;\n\n  inherited Open;\nend;\n\n{**\n  Releases this <code>ResultSet</code> object's database and\n  JDBC resources immediately instead of waiting for\n  this to happen when it is automatically closed.\n\n  <P><B>Note:</B> A <code>ResultSet</code> object\n  is automatically closed by the\n  <code>Statement</code> object that generated it when\n  that <code>Statement</code> object is closed,\n  re-executed, or is used to retrieve the next result from a\n  sequence of multiple results. A <code>ResultSet</code> object\n  is also automatically closed when it is garbage collected.\n}\nprocedure TZOracleResultSet.Close;\nvar\n  ps: IZPreparedStatement;\nbegin\n  if assigned(FOutVars) then // else no statement anyways\n    FreeOracleSQLVars(FPlainDriver, FOutVars, FConnection.GetConnectionHandle, FErrorHandle, ConSettings);\n  { prepared statement own handles, so dont free them }\n  if not Supports(GetStatement, IZPreparedStatement, ps) then\n     FreeOracleStatementHandles(FPlainDriver, FStmtHandle, FErrorHandle);\n  inherited Close;\nend;\n\n{**\n  Moves the cursor down one row from its current position.\n  A <code>ResultSet</code> cursor is initially positioned\n  before the first row; the first call to the method\n  <code>next</code> makes the first row the current row; the\n  second call makes the second row the current row, and so on.\n\n  <P>If an input stream is open for the current row, a call\n  to the method <code>next</code> will\n  implicitly close it. A <code>ResultSet</code> object's\n  warning chain is cleared when a new row is read.\n\n  @return <code>true</code> if the new current row is valid;\n    <code>false</code> if there are no more rows\n}\nfunction TZOracleResultSet.Next: Boolean;\nvar\n  Status: Integer;\nbegin\n  { Checks for maximum row. }\n  Result := False;\n  if (RowNo > LastRowNo) or ((MaxRows > 0) and (RowNo >= MaxRows)) then\n    Exit;\n\n  if RowNo = 0 then\n    Status := FPlainDriver.StmtExecute(FConnection.GetContextHandle, FStmtHandle,\n      FErrorHandle, 1, 0, nil, nil, OCI_DEFAULT)\n  else\n    Status := FPlainDriver.StmtFetch(FStmtHandle, FErrorHandle,\n      1, OCI_FETCH_NEXT, OCI_DEFAULT);\n  if not (Status in [OCI_SUCCESS, OCI_NO_DATA]) then\n    CheckOracleError(FPlainDriver, FErrorHandle, Status, lcOther, 'FETCH ROW');\n\n  if Status in [OCI_SUCCESS, OCI_SUCCESS_WITH_INFO] then\n  begin\n    RowNo := RowNo + 1;\n    if LastRowNo < RowNo then\n      LastRowNo := RowNo;\n    Result := True;\n  end\n  else\n  begin\n    if RowNo <= LastRowNo then\n      RowNo := LastRowNo + 1;\n    Result := False;\n  end;\nend;\n\n{ TZOracleCallableResultSet }\nfunction TZOracleCallableResultSet.PrepareOracleOutVars(Statement: IZStatement;\n  InVars: PZSQLVars; const OracleParams: TZOracleParams): PZSQLVars;\nvar\n  I, J: Integer;\nbegin\n  J := 0;\n  for i := 0 to High(OracleParams) do\n    if OracleParams[I].pType in [2,3,4] then\n      Inc(J);\n\n  Result := nil;\n  AllocateOracleSQLVars(Result, J);\n  Result.ActualNum := J;\n  SetLength(FFieldNames, J);\n\n  for I := 1 to Length(OracleParams) do\n  begin\n    J := OracleParams[I-1].pOutIndex;\n    if OracleParams[I-1].pType in [2,3,4] then //ptInOut, ptOut, ptResult\n    begin\n      Result.Variables[J].ColType := InVars.Variables[I].ColType;\n      Result.Variables[J].TypeCode := InVars.Variables[I].TypeCode;\n      Result.Variables[J].DataSize := InVars.Variables[I].DataSize;\n      Result.Variables[J].Length := InVars.Variables[I].Length;\n      GetMem(Result.Variables[J].Data, InVars.Variables[I].Length);\n      Move(InVars.Variables[I].Data^, Result.Variables[J].Data^, InVars.Variables[I].Length);\n      FFieldNames[J-1] := OracleParams[I-1].pName;\n    end;\n  end;\nend;\n\nprocedure TZOracleCallableResultSet.Open;\nvar\n  I: Integer;\n  ColumnInfo: TZColumnInfo;\n  CurrentVar: PZSQLVar;\n  Connection: IZConnection;\nbegin\n  Connection := GetStatement.GetConnection;\n  { Fills the column info. }\n  ColumnsInfo.Clear;\n  for I := 1 to FOutVars.ActualNum do\n  begin\n    CurrentVar := @FOutVars.Variables[I];\n    ColumnInfo := TZColumnInfo.Create;\n\n    with ColumnInfo do\n    begin\n      ColumnName := '';\n      TableName := '';\n\n      ColumnLabel := FFieldNames[i-1];\n      ColumnDisplaySize := 0;\n      AutoIncrement := False;\n      Signed := True;\n      Nullable := ntNullable;\n\n      ColumnType := CurrentVar.ColType;\n      Scale := CurrentVar.Scale;\n\n      {Reset the column type which can be changed by user before}\n      if (ColumnType = stUnicodeStream) and not ( Connection.GetConSettings.CPType = cCP_UTF16) then\n        ColumnType := stAsciiStream;\n      if (ColumnType = stAsciiStream) and ( Connection.GetConSettings.CPType = cCP_UTF16) then\n        ColumnType := stUnicodeStream;\n      if (ColumnType = stUnicodeString) and not ( Connection.GetConSettings.CPType = cCP_UTF16) then\n        ColumnType := stString;\n      if (ColumnType = stString) and ( Connection.GetConSettings.CPType = cCP_UTF16) then\n        ColumnType := stUnicodeString;\n\n      if ( ColumnType in [stString, stUnicodeString] ) then\n      begin\n        ColumnDisplaySize := CurrentVar.DataSize;\n        Precision := GetFieldSize(ColumnType, ConSettings, CurrentVar.DataSize,\n          ConSettings.ClientCodePage^.CharWidth);\n      end\n      else\n        Precision := CurrentVar.Precision;\n    end;\n\n    ColumnsInfo.Add(ColumnInfo);\n  end;\n\n  inherited Open;\nend;\n\n{**\n  Constructs this object, assignes main properties and\n  opens the record set.\n  @param PlainDriver a Oracle plain driver.\n  @param Statement a related SQL statement object.\n  @param SQL a SQL statement.\n  @param Handle a Oracle specific query handle.\n}\nconstructor TZOracleCallableResultSet.Create(PlainDriver: IZOraclePlainDriver;\n  Statement: IZStatement; SQL: string; StmtHandle: POCIStmt;\n  ErrorHandle: POCIError; OutVars: PZSQLVars; const OracleParams: TZOracleParams);\nbegin\n  FOutVars := PrepareOracleOutVars(Statement, OutVars, OracleParams);\n  inherited Create(PlainDriver, Statement, SQL, StmtHandle, ErrorHandle);\n  FConnection := Statement.GetConnection as IZOracleConnection;\n  MaxRows := 1;\nend;\n\n{**\n  Releases this <code>ResultSet</code> object's database and\n  JDBC resources immediately instead of waiting for\n  this to happen when it is automatically closed.\n\n  <P><B>Note:</B> A <code>ResultSet</code> object\n  is automatically closed by the\n  <code>Statement</code> object that generated it when\n  that <code>Statement</code> object is closed,\n  re-executed, or is used to retrieve the next result from a\n  sequence of multiple results. A <code>ResultSet</code> object\n  is also automatically closed when it is garbage collected.\n}\nprocedure TZOracleCallableResultSet.Close;\nvar\n  I: Integer;\n  CurrentVar: PZSQLVar;\nbegin\n  if FOutVars <> nil then\n  begin\n    { Frees allocated memory for output variables }\n    for I := 1 to FOutVars.ActualNum do\n    begin\n      CurrentVar := @FOutVars.Variables[I];\n      if CurrentVar.Data <> nil then\n      begin\n        CurrentVar.DupData := nil;\n        FreeMem(CurrentVar.Data);\n        CurrentVar.Data := nil;\n      end;\n    end;\n    FreeMem(FOutVars);\n  end;\n  FOutVars := nil;\n  inherited Close;\nend;\n\nfunction TZOracleCallableResultSet.Next: Boolean;\nbegin\n  { Checks for maximum row. }\n  Result := False;\n  if (RowNo >= MaxRows) then\n    Exit;\n  RowNo := LastRowNo + 1;\n  Result := True;\nend;\n\n{ TZOracleBlob }\n\n{**\n  Constructs this class and assignes the main properties.\n  @param PlainDriver a Oracle plain driver.\n  @param Data a pointer to the blobdata.\n  @param Size the size of the blobdata.\n  @param Handle a Oracle connection reference.\n  @param LobLocator an Oracle lob locator reference.\n  @param BlobType a blob type.\n}\nconstructor TZOracleBlob.Create(PlainDriver: IZOraclePlainDriver;\n  Data: Pointer; Size: Integer; Handle: IZConnection;\n  LobLocator: POCILobLocator; BlobType: TZSQLType; ChunkSize: Integer);\nbegin\n  inherited CreateWithData(Data, Size, Handle);\n  FHandle := Handle;\n  FLobLocator := LobLocator;\n  FPlainDriver := PlainDriver;\n  FTemporary := False;\n  FBlobType := BlobType;\n  FChunkSize := ChunkSize;\nend;\n\n{**\n  Destroys this object and cleanups the memory.\n}\ndestructor TZOracleBlob.Destroy;\nvar\n  Connection: IZOracleConnection;\nbegin\n  if FTemporary then\n  begin\n    Connection := FHandle as IZOracleConnection;\n    FPlainDriver.LobFreeTemporary(Connection.GetContextHandle,\n      Connection.GetErrorHandle, FLobLocator);\n  end;\n\n  inherited Destroy;\nend;\n\n{**\n  Gets the lob locator reference.\n  @return the lob locator reference.\n}\nfunction TZOracleBlob.GetLobLocator: POCILobLocator;\nbegin\n  Result := FLobLocator;\nend;\n\n{**\n  Creates a temporary blob.\n}\nprocedure TZOracleBlob.CreateBlob;\nvar\n  Status: Integer;\n  Connection: IZOracleConnection;\n  TempBlobType: ub1;\nbegin\n  Connection := FHandle as IZOracleConnection;\n\n  if FBlobType in [stBytes, stBinaryStream] then\n    TempBlobType := OCI_TEMP_BLOB\n  else\n    TempBlobType := OCI_TEMP_CLOB;\n\n  Status := FPlainDriver.LobCreateTemporary(Connection.GetContextHandle,\n    Connection.GetErrorHandle, FLobLocator, OCI_DEFAULT, OCI_DEFAULT,\n    TempBlobType, False, OCI_DURATION_DEFAULT);\n  CheckOracleError(FPlainDriver, Connection.GetErrorHandle,\n    Status, lcOther, 'Create Large Object');\n\n  FTemporary := True;\nend;\n\n{**\n  Reads the blob by the blob handle.\n}\nprocedure TZOracleBlob.ReadBlob;\nconst\n  MemDelta = 1 shl 12;  // read page (2^...)\nvar\n  Status: Integer;\n  Buf: PByteArray;\n  ReadNumBytes, ReadNumChars, Offset, Cap: ub4;\n  Connection: IZOracleConnection;\n  AnsiTemp: RawByteString;\n  Stream: TStream;\n  csid: ub2;\n  csfrm: ub1;\n\n  procedure DoRead(const csid: ub2; const csfrm: ub1);\n  begin\n    FillChar(Buf^, FChunkSize+1, #0);\n    ReadNumChars := 0;\n    Status := FPlainDriver.LobRead(Connection.GetContextHandle,\n      Connection.GetErrorHandle, FLobLocator, ReadNumChars, Offset + 1,\n      Buf, FChunkSize, nil, nil, Connection.GetClientCodePageInformations^.ID, csfrm);\n    if ReadNumChars > 0 then\n    begin\n      Inc(Offset, ReadNumChars);\n      AnsiTemp := AnsiTemp+PAnsiChar(Buf);\n    end;\n  end;\nbegin\n  if not Updated and (FLobLocator <> nil)\n    and (BlobData = nil) and (not FTemporary) then\n  begin\n    Connection := FHandle as IZOracleConnection;\n\n    { Opens a large object or file for read. }\n    Status := FPlainDriver.LobOpen(Connection.GetContextHandle,\n      Connection.GetErrorHandle, FLobLocator, OCI_LOB_READONLY);\n    CheckOracleError(FPlainDriver, Connection.GetErrorHandle,\n      Status, lcOther, 'Open Large Object');\n    try\n      { Reads data in chunks by MemDelta or more }\n      Offset := 0;\n      Buf := nil;\n      try\n        case FBlobType of\n          stBinaryStream:\n            repeat //BLOB\n              {Calc new progressive by 1/8 and aligned by MemDelta capacity for buffer}\n              Cap := (Offset + (Offset shr 3) + 2 * MemDelta - 1) and not (MemDelta - 1);\n              ReallocMem(Buf, Cap);\n              ReadNumBytes := Cap - Offset;\n\n              Status := FPlainDriver.LobRead(Connection.GetContextHandle,\n                Connection.GetErrorHandle, FLobLocator, ReadNumBytes, Offset + 1,\n                @Buf[Offset], ReadNumBytes, nil, nil, 0, SQLCS_IMPLICIT);\n              CheckOracleError(FPlainDriver, Connection.GetErrorHandle,\n                Status, lcOther, 'Read Large Object');\n              if ReadNumBytes > 0 then\n                Inc(Offset, ReadNumBytes);\n            until Offset < Cap;\n          else //CLob\n          begin\n            GetMem(Buf, FChunkSize+1);\n            AnsiTemp := '';\n            Offset := 0;\n            csid := Connection.GetClientCodePageInformations^.ID;\n            CheckOracleError(FPlainDriver, Connection.GetErrorHandle,\n              FPlainDriver.LobCharSetForm(Connection.GetConnectionHandle,\n                Connection.GetErrorHandle, FLobLocator, @csfrm), lcOther, 'Determine LOB SCFORM'); //need to determine proper CharSet-Form\n            DoRead(csid, csfrm);\n            if Status = OCI_NEED_DATA then\n              while Status = OCI_NEED_DATA do\n                DoRead(csid, csfrm);\n            CheckOracleError(FPlainDriver, Connection.GetErrorHandle,\n              Status, lcOther, 'Read Large Object');\n            if FBlobType = stUnicodeStream then\n              if OffSet = 0 then\n                Stream := TMemoryStream.Create\n              else\n                Stream := ZEncoding.GetValidatedUnicodeStream(AnsiTemp, Connection.GetConSettings, True)\n            else\n              Stream := TStringStream.Create(GetValidatedAnsiString(AnsiTemp, Connection.GetConSettings, True));\n            ReallocMem(Buf, Stream.Size);\n            Move(TMemoryStream(Stream).Memory^, PAnsichar(Buf)^, Stream.Size);\n            OffSet := Stream.Size;\n            Stream.Free;\n            FDecoded := FBlobType = stUnicodeStream;\n          end;\n        end;\n      except\n        FreeMem(Buf);\n        raise;\n      end;\n    finally\n      { Closes large object or file. }\n      Status := FPlainDriver.LobClose(Connection.GetContextHandle,\n        Connection.GetErrorHandle, FLobLocator);\n      CheckOracleError(FPlainDriver, Connection.GetErrorHandle,\n        Status, lcOther, 'Close Large Object');\n    end;\n    { Assigns data }\n    InternalSetData(Buf, Offset);\n  end;\nend;\n\n{**\n  Writes the blob by the blob handle.\n}\nprocedure TZOracleBlob.WriteBlob;\nvar\n  Status: sword;\n  Connection: IZOracleConnection;\n  ContentSize, OffSet: ub4;\n\n  function DoWrite(AOffSet: ub4; AChunkSize: ub4; APiece: ub1): sword;\n  var\n    AContentSize: ub4;\n  begin\n    if Self.FBlobType = stBinaryStream then\n    begin\n      AContentSize := ContentSize;\n      Result := FPlainDriver.LobWrite(Connection.GetContextHandle,\n        Connection.GetErrorHandle, FLobLocator, AContentSize, AOffSet,\n        (PAnsiChar(BlobData)+OffSet), AChunkSize, APiece, nil, nil, 0, SQLCS_IMPLICIT);\n    end\n    else\n    begin\n      if ContentSize > 0 then\n        AContentSize := AChunkSize div Connection.GetClientCodePageInformations^.CharWidth\n      else\n      begin\n        AContentSize := ContentSize;\n        AChunkSize := Connection.GetClientCodePageInformations^.CharWidth;\n      end;\n\n      Result := FPlainDriver.LobWrite(Connection.GetContextHandle,\n        Connection.GetErrorHandle, FLobLocator, AContentSize, AOffSet,\n        (PAnsiChar(BlobData)+OffSet), AChunkSize, APiece, nil, nil, Connection.GetClientCodePageInformations^.ID, SQLCS_IMPLICIT);\n    end;\n    ContentSize := AContentSize;\n    inc(OffSet, AChunkSize);\n  end;\nbegin\n  Connection := FHandle as IZOracleConnection;\n\n  { Opens a large object or file for read. }\n  Status := FPlainDriver.LobOpen(Connection.GetContextHandle,\n    Connection.GetErrorHandle, FLobLocator, OCI_LOB_READWRITE);\n  CheckOracleError(FPlainDriver, Connection.GetErrorHandle,\n    Status, lcOther, 'Open Large Object');\n\n  { Checks for empty blob.}\n  { This test doesn't use IsEmpty because that function does allow for zero length blobs}\n  if (BlobSize > 0) then\n  begin\n    if BlobSize > FChunkSize then\n    begin\n      OffSet := 0;\n      ContentSize := 0;\n\n      Status := DoWrite(1, FChunkSize, OCI_FIRST_PIECE);\n      if Status <> OCI_NEED_DATA then\n        CheckOracleError(FPlainDriver, Connection.GetErrorHandle,\n          Status, lcOther, 'Write Large Object');\n\n      if (BlobSize - OffSet) > FChunkSize then\n        while (BlobSize - OffSet) > FChunkSize do //take care there is room left for LastPiece\n        begin\n          Status := DoWrite(offset, FChunkSize, OCI_NEXT_PIECE);\n          if Status <> OCI_NEED_DATA then\n            CheckOracleError(FPlainDriver, Connection.GetErrorHandle,\n              Status, lcOther, 'Write Large Object');\n\n        end;\n      Status := DoWrite(offset, BlobSize - OffSet, OCI_LAST_PIECE);\n    end\n    else\n    begin\n      ContentSize := BlobSize;\n      Status := FPlainDriver.LobWrite(Connection.GetContextHandle,\n        Connection.GetErrorHandle, FLobLocator, ContentSize, 1,\n        BlobData, BlobSize, OCI_ONE_PIECE, nil, nil, 0, SQLCS_IMPLICIT);\n    end;\n  end\n  else\n  begin\n    Status := FPlainDriver.LobTrim(Connection.GetContextHandle,\n      Connection.GetErrorHandle, FLobLocator, 0);\n  end;\n  CheckOracleError(FPlainDriver, Connection.GetErrorHandle,\n    Status, lcOther, 'Write Large Object');\n\n  { Closes large object or file. }\n  Status := FPlainDriver.LobClose(Connection.GetContextHandle,\n    Connection.GetErrorHandle, FLobLocator);\n  CheckOracleError(FPlainDriver, Connection.GetErrorHandle,\n    Status, lcOther, 'Close Large Object');\nend;\n\n{**\n  Replace data in blob by AData without copy (keep ref of AData)\n}\nprocedure TZOracleBlob.InternalSetData(AData: Pointer; ASize: Integer);\nbegin\n  Clear;\n  BlobData := AData;\n  BlobSize := ASize;\nend;\n\n{**\n  Checks if this blob has an empty content.\n  @return <code>True</code> if this blob is empty.\n}\nfunction TZOracleBlob.IsEmpty: Boolean;\nbegin\n  ReadBlob;\n  Result := inherited IsEmpty;\nend;\n\nfunction TZOracleBlob.Length: LongInt;\nbegin\n  ReadBlob;\n  Result := inherited Length;\nend;\n\n{**\n  Clones this blob object.\n  @return a clonned blob object.\n}\nfunction TZOracleBlob.Clone: IZBlob;\nbegin\n  Result := TZOracleBlob.Create(FPlainDriver, BlobData, BlobSize,\n    FHandle, FLobLocator, FBlobType, FChunkSize);\nend;\n\n{**\n  Gets the associated stream object.\n  @return an associated or newly created stream object.\n}\nfunction TZOracleBlob.GetStream: TStream;\nbegin\n  ReadBlob;\n  Result := inherited GetStream;\nend;\n\n{**\n  Gets the string from the stored data.\n  @return a string which contains the stored data.\n}\nfunction TZOracleBlob.GetString: RawByteString;\nbegin\n  ReadBlob;\n  Result := inherited GetString;\nend;\n\n{**\n  Gets the byte buffer from the stored data.\n  @return a byte buffer which contains the stored data.\n}\nfunction TZOracleBlob.GetBytes: TByteDynArray;\nbegin\n  ReadBlob;\n  Result := inherited GetBytes;\nend;\n\nend.\n"
  },
  {
    "path": "lib/zeosdbo/src/dbc/ZDbcOracleStatement.pas",
    "content": "{*********************************************************}\n{                                                         }\n{                 Zeos Database Objects                   }\n{           Oracle Database Connectivity Classes          }\n{                                                         }\n{        Originally written by Sergey Seroukhov           }\n{                                                         }\n{*********************************************************}\n\n{@********************************************************}\n{    Copyright (c) 1999-2012 Zeos Development Group       }\n{                                                         }\n{ License Agreement:                                      }\n{                                                         }\n{ This library is distributed in the hope that it will be }\n{ useful, but WITHOUT ANY WARRANTY; without even the      }\n{ implied warranty of MERCHANTABILITY or FITNESS FOR      }\n{ A PARTICULAR PURPOSE.  See the GNU Lesser General       }\n{ Public License for more details.                        }\n{                                                         }\n{ The source code of the ZEOS Libraries and packages are  }\n{ distributed under the Library GNU General Public        }\n{ License (see the file COPYING / COPYING.ZEOS)           }\n{ with the following  modification:                       }\n{ As a special exception, the copyright holders of this   }\n{ library give you permission to link this library with   }\n{ independent modules to produce an executable,           }\n{ regardless of the license terms of these independent    }\n{ modules, and to copy and distribute the resulting       }\n{ executable under terms of your choice, provided that    }\n{ you also meet, for each linked independent module,      }\n{ the terms and conditions of the license of that module. }\n{ An independent module is a module which is not derived  }\n{ from or based on this library. If you modify this       }\n{ library, you may extend this exception to your version  }\n{ of the library, but you are not obligated to do so.     }\n{ If you do not wish to do so, delete this exception      }\n{ statement from your version.                            }\n{                                                         }\n{                                                         }\n{ The project web site is located on:                     }\n{   http://zeos.firmos.at  (FORUM)                        }\n{   http://sourceforge.net/p/zeoslib/tickets/ (BUGTRACKER)}\n{   svn://svn.code.sf.net/p/zeoslib/code-0/trunk (SVN)    }\n{                                                         }\n{   http://www.sourceforge.net/projects/zeoslib.          }\n{                                                         }\n{                                                         }\n{                                 Zeos Development Group. }\n{********************************************************@}\n\nunit ZDbcOracleStatement;\n\ninterface\n\n{$I ZDbc.inc}\n\nuses\n  Classes, {$IFDEF MSEgui}mclasses,{$ENDIF} SysUtils, Types,\n  ZSysUtils, ZDbcIntfs, ZDbcStatement, ZDbcLogging, ZPlainOracleDriver,\n  ZCompatibility, ZVariant, ZDbcOracleUtils, ZPlainOracleConstants;\n\ntype\n\n  {** Defines a Oracle specific statement. }\n  IZOracleStatement = interface(IZStatement)\n    ['{8644E5B6-1E0F-493F-B6AC-40D70CCEA13A}']\n\n    function GetStatementHandle: POCIStmt;\n  end;\n\n  {** Implements Generic Oracle Statement. }\n  TZOracleStatement = class(TZAbstractStatement, IZOracleStatement)\n  private\n    FPlainDriver: IZOraclePlainDriver;\n\n  public\n    constructor Create(PlainDriver: IZOraclePlainDriver;\n      Connection: IZConnection; Info: TStrings);\n    destructor Destroy; override;\n\n    function ExecuteQuery(const SQL: RawByteString): IZResultSet; override;\n    function ExecuteUpdate(const SQL: RawByteString): Integer; override;\n    function Execute(const SQL: RawByteString): Boolean; override;\n\n    function GetStatementHandle: POCIStmt;\n  end;\n\n  {** Implements Prepared SQL Statement. }\n  TZOraclePreparedStatement = class(TZAbstractPreparedStatement)\n  private\n    FPrepared: Boolean;\n    FHandle: POCIStmt;\n    FErrorHandle: POCIError;\n    FPlainDriver: IZOraclePlainDriver;\n    FExecStatement: IZStatement;\n    FLastStatement: IZStatement;\n    FInVars: PZSQLVars;\n\n    procedure SetLastStatement(LastStatement: IZStatement);\n    function GetExecStatement: IZStatement;\n    function ConvertToOracleSQLQuery(SQL: string): RawByteString;\n\n  protected\n    property Prepared: Boolean read FPrepared write FPrepared;\n    property Handle: POCIStmt read FHandle write FHandle;\n    property ErrorHandle: POCIError read FErrorHandle write FErrorHandle;\n    property ExecStatement: IZStatement read FExecStatement write FExecStatement;\n    property LastStatement: IZStatement read FLastStatement write SetLastStatement;\n    property InVars: PZSQLVars read FInVars write FInVars;\n  public\n    constructor Create(PlainDriver: IZOraclePlainDriver;\n      Connection: IZConnection; const SQL: string; Info: TStrings);\n    destructor Destroy; override;\n\n    procedure Close; override;\n    procedure Prepare; override;\n    function ExecuteQuery(const SQL: RawByteString): IZResultSet; override;\n    function ExecuteUpdate(const SQL: RawByteString): Integer; override;\n    function Execute(const SQL: RawByteString): Boolean; override;\n\n    function ExecuteQueryPrepared: IZResultSet; override;\n    function ExecuteUpdatePrepared: Integer; override;\n    function ExecutePrepared: Boolean; override;\n\n    function GetStatementHandle: POCIStmt;\n  end;\n\n  TZOracleCallableStatement = class(TZAbstractCallableStatement,\n    IZParamNamedCallableStatement)\n  private\n    FOutParamCount: Integer;\n    FErrorHandle: POCIError;\n    FInVars: PZSQLVars;\n    FPlainDriver:IZOraclePlainDriver;\n    FPrepared:boolean;\n    FHandle: POCIStmt;\n    FOracleParams: TZOracleParams;\n    FOracleParamsCount: Integer;\n    FParamNames: TStringDynArray;\n    PackageIncludedList: TStrings;\n    procedure ArrangeInParams;\n    procedure FetchOutParamsFromOracleVars;\n  protected\n    function GetProcedureSql(SelectProc: boolean): RawByteString;\n    procedure SetInParam(ParameterIndex: Integer; SQLType: TZSQLType;\n      const Value: TZVariant); override;\n    procedure RegisterParamTypeAndName(const ParameterIndex:integer;\n      const ParamTypeName, ParamName: String; Const ColumnSize, Precision: Integer);\n  public\n    procedure RegisterOutParameter(ParameterIndex: Integer; SQLType: Integer); override;\n    procedure RegisterParamType(ParameterIndex: integer; ParamType: Integer); override;\n    procedure Prepare; override;\n    function IsNull(ParameterIndex: Integer): Boolean;override;\n\n    Function ExecuteUpdatePrepared: Integer; override;\n    function ExecuteQueryPrepared: IZResultSet; override;\n    constructor Create(Connection: IZConnection; const pProcName: string; Info: TStrings);\n    destructor Destroy; override;\n    procedure ClearParameters; override;\n  end;\n\nimplementation\n\nuses\n  ZTokenizer, ZDbcOracle, ZDbcOracleResultSet\n  {$IFDEF WITH_UNITANSISTRINGS}, AnsiStrings{$ENDIF};\n\n{ TZOracleStatement }\n\n{**\n  Constructs this object and assignes the main properties.\n  @param PlainDriver a Oracle plain driver.\n  @param Connection a database connection object.\n  @param Info a statement parameters.\n  @param Handle a connection handle pointer.\n}\nconstructor TZOracleStatement.Create(PlainDriver: IZOraclePlainDriver;\n  Connection: IZConnection; Info: TStrings);\nbegin\n  inherited Create(Connection, Info);\n  FPlainDriver := PlainDriver;\n  ResultSetType := rtForwardOnly;\nend;\n\n{**\n  Destroys this object and cleanups the memory.\n}\ndestructor TZOracleStatement.Destroy;\nbegin\n  inherited Destroy;\nend;\n\n{**\n  Executes an SQL statement that returns a single <code>ResultSet</code> object.\n  @param sql typically this is a static SQL <code>SELECT</code> statement\n  @return a <code>ResultSet</code> object that contains the data produced by the\n    given query; never <code>null</code>\n}\nfunction TZOracleStatement.ExecuteQuery(const SQL: RawByteString): IZResultSet;\nvar\n  Handle: POCIStmt;\n  ErrorHandle: POCIError;\nbegin\n  AllocateOracleStatementHandles(FPlainDriver, Connection, Handle, ErrorHandle);\n  ASQL := SQL;\n  try\n    PrepareOracleStatement(FPlainDriver, ASQL, LogSQL, Handle, ErrorHandle,\n      StrToIntDef(Info.Values['prefetch_count'], 100), ConSettings);\n    Result := CreateOracleResultSet(FPlainDriver, Self, LogSQL,\n      Handle, ErrorHandle);\n  except\n    FreeOracleStatementHandles(FPlainDriver, Handle, ErrorHandle);\n    raise;\n  end;\n\n  DriverManager.LogMessage(lcExecute, FPlainDriver.GetProtocol, LogSQL);\nend;\n\n{**\n  Executes an SQL <code>INSERT</code>, <code>UPDATE</code> or\n  <code>DELETE</code> statement. In addition,\n  SQL statements that return nothing, such as SQL DDL statements,\n  can be executed.\n\n  @param sql an SQL <code>INSERT</code>, <code>UPDATE</code> or\n    <code>DELETE</code> statement or an SQL statement that returns nothing\n  @return either the row count for <code>INSERT</code>, <code>UPDATE</code>\n    or <code>DELETE</code> statements, or 0 for SQL statements that return nothing\n}\nfunction TZOracleStatement.ExecuteUpdate(const SQL: RawByteString): Integer;\nvar\n  Handle: POCIStmt;\n  ErrorHandle: POCIError;\nbegin\n  AllocateOracleStatementHandles(FPlainDriver, Connection, Handle, ErrorHandle);\n  ASQL := SQL;\n  try\n    PrepareOracleStatement(FPlainDriver, ASQL, LogSQL, Handle, ErrorHandle,\n      StrToIntDef(Info.Values['prefetch_count'], 100), ConSettings);\n    ExecuteOracleStatement(FPlainDriver, Connection, LogSQL, Handle, ErrorHandle);\n    Result := GetOracleUpdateCount(FPlainDriver, Handle, ErrorHandle);\n  finally\n    FreeOracleStatementHandles(FPlainDriver, Handle, ErrorHandle);\n  end;\n\n  DriverManager.LogMessage(lcExecute, FPlainDriver.GetProtocol, LogSQL);\n\n  { Autocommit statement. }\n  if Connection.GetAutoCommit then\n    Connection.Commit;\nend;\n\n{**\n  Executes an SQL statement that may return multiple results.\n  Under some (uncommon) situations a single SQL statement may return\n  multiple result sets and/or update counts.  Normally you can ignore\n  this unless you are (1) executing a stored procedure that you know may\n  return multiple results or (2) you are dynamically executing an\n  unknown SQL string.  The  methods <code>execute</code>,\n  <code>getMoreResults</code>, <code>getResultSet</code>,\n  and <code>getUpdateCount</code> let you navigate through multiple results.\n\n  The <code>execute</code> method executes an SQL statement and indicates the\n  form of the first result.  You can then use the methods\n  <code>getResultSet</code> or <code>getUpdateCount</code>\n  to retrieve the result, and <code>getMoreResults</code> to\n  move to any subsequent result(s).\n\n  @param sql any SQL statement\n  @return <code>true</code> if the next result is a <code>ResultSet</code> object;\n  <code>false</code> if it is an update count or there are no more results\n}\nfunction TZOracleStatement.Execute(const SQL: RawByteString): Boolean;\nvar\n  Handle: POCIStmt;\n  ErrorHandle: POCIError;\n  StatementType: ub2;\nbegin\n  Result := False;\n  AllocateOracleStatementHandles(FPlainDriver, Connection, Handle, ErrorHandle);\n  ASQL := SQL;\n  try\n    PrepareOracleStatement(FPlainDriver, ASQL, LogSQL, Handle, ErrorHandle,\n      StrToIntDef(Info.Values['prefetch_count'], 100), ConSettings);\n\n    StatementType := 0;\n    FPlainDriver.AttrGet(Handle, OCI_HTYPE_STMT, @StatementType, nil,\n      OCI_ATTR_STMT_TYPE, ErrorHandle);\n\n    if StatementType = OCI_STMT_SELECT then\n    begin\n      LastResultSet := CreateOracleResultSet(FPlainDriver, Self,\n        LogSQL, Handle, ErrorHandle);\n      Result := LastResultSet <> nil;\n    end\n    else\n    begin\n      ExecuteOracleStatement(FPlainDriver, Connection, LogSQL,\n        Handle, ErrorHandle);\n      LastUpdateCount := GetOracleUpdateCount(FPlainDriver, Handle, ErrorHandle);\n    end;\n  finally\n    if not Result then\n      FreeOracleStatementHandles(FPlainDriver, Handle, ErrorHandle);\n  end;\n\n  DriverManager.LogMessage(lcExecute, FPlainDriver.GetProtocol, LogSQL);\n\n  { Autocommit statement. }\n  if not Result and Connection.GetAutoCommit then\n    Connection.Commit;\nend;\n\n{**\n  Gets statement handle.\n  @return statement handle.\n}\nfunction TZOracleStatement.GetStatementHandle: POCIStmt;\nbegin\n  Result := nil;\nend;\n\n{ TZOraclePreparedStatement }\n\n{**\n  Constructs this object and assignes the main properties.\n  @param PlainDriver a Oracle plain driver.\n  @param Connection a database connection object.\n  @param Info a statement parameters.\n  @param Handle a connection handle pointer.\n}\nconstructor TZOraclePreparedStatement.Create(\n  PlainDriver: IZOraclePlainDriver; Connection: IZConnection;\n  const SQL: string; Info: TStrings);\nbegin\n  inherited Create(Connection, SQL, Info);\n  FPlainDriver := PlainDriver;\n  ResultSetType := rtForwardOnly;\n  ASQL := ConvertToOracleSQLQuery(SQL);\n  FPrepared := False;\nend;\n\n{**\n  Destroys this object and cleanups the memory.\n}\ndestructor TZOraclePreparedStatement.Destroy;\nbegin\n  inherited Destroy;\nend;\n\n{**\n  Sets a reference to the last statement.\n  @param LastStatement the last statement interface.\n}\nprocedure TZOraclePreparedStatement.SetLastStatement(\n  LastStatement: IZStatement);\nbegin\n  if FLastStatement <> nil then\n    FLastStatement.Close;\n  FLastStatement := LastStatement;\nend;\n\n{**\n  Creates a temporary statement which executes queries.\n  @param Info a statement parameters.\n  @return a created statement object.\n}\nfunction TZOraclePreparedStatement.GetExecStatement: IZStatement;\nbegin\n  if ExecStatement = nil then\n  begin\n    ExecStatement := TZOracleStatement.Create(FPlainDriver, Connection, Info);\n\n    ExecStatement.SetMaxFieldSize(GetMaxFieldSize);\n    ExecStatement.SetMaxRows(GetMaxRows);\n    ExecStatement.SetEscapeProcessing(EscapeProcessing);\n    ExecStatement.SetQueryTimeout(GetQueryTimeout);\n    ExecStatement.SetCursorName(CursorName);\n\n    ExecStatement.SetFetchDirection(GetFetchDirection);\n    ExecStatement.SetFetchSize(GetFetchSize);\n    ExecStatement.SetResultSetConcurrency(GetResultSetConcurrency);\n    ExecStatement.SetResultSetType(GetResultSetType);\n  end;\n  Result := ExecStatement;\nend;\n\n{**\n  Converts an SQL query into Oracle format.\n  @param SQL a query with parameters defined with '?'\n  @returns a query with parameters in Oracle format ':pN'.\n}\nfunction TZOraclePreparedStatement.ConvertToOracleSQLQuery(SQL: string): RawByteString;\nvar\n  I, N: Integer;\n  Tokens: TStrings;\nbegin\n  if Pos('?', SQL) > 0 then\n  begin\n    Tokens := Connection.GetDriver.GetTokenizer.\n      TokenizeBufferToList(SQL, [toUnifyWhitespaces]);\n    try\n      Result := '';\n      N := 0;\n      for I := 0 to Tokens.Count - 1 do\n        if Tokens[I] = '?' then\n        begin\n          Inc(N);\n          Result := Result + ':P' + RawByteString(IntToStr(N));\n        end else\n          Result := Result + ZPlainString(Tokens[I]);\n    finally\n      Tokens.Free;\n    end;\n  end else\n    Result := GetEncodedSQL(SQL);\nend;\n\n{**\n  Closes this statement and frees all resources.\n}\nprocedure TZOraclePreparedStatement.Close;\nbegin\n  inherited Close;\n  if LastStatement <> nil then\n  begin\n    FLastStatement.Close;\n    FLastStatement := nil;\n  end;\n  FreeOracleStatementHandles(FPlainDriver, FHandle, FErrorHandle);\n  FreeOracleSQLVars(FPlainDriver, FInVars, (Connection as IZOracleConnection).GetConnectionHandle, FErrorHandle, ConSettings);\nend;\n\n{**\n  Executes an SQL statement that may return multiple results.\n  Under some (uncommon) situations a single SQL statement may return\n  multiple result sets and/or update counts.  Normally you can ignore\n  this unless you are (1) executing a stored procedure that you know may\n  return multiple results or (2) you are dynamically executing an\n  unknown SQL string.  The  methods <code>execute</code>,\n  <code>getMoreResults</code>, <code>getResultSet</code>,\n  and <code>getUpdateCount</code> let you navigate through multiple results.\n\n  The <code>execute</code> method executes an SQL statement and indicates the\n  form of the first result.  You can then use the methods\n  <code>getResultSet</code> or <code>getUpdateCount</code>\n  to retrieve the result, and <code>getMoreResults</code> to\n  move to any subsequent result(s).\n\n  @param sql any SQL statement\n  @return <code>true</code> if the next result is a <code>ResultSet</code> object;\n  <code>false</code> if it is an update count or there are no more results\n}\nfunction TZOraclePreparedStatement.Execute(const SQL: RawByteString): Boolean;\nbegin\n  LastStatement := GetExecStatement;\n  Result := LastStatement.Execute(SQL);\n  if Result then\n    LastResultSet := LastStatement.GetResultSet\n  else\n    LastUpdateCount := LastStatement.GetUpdateCount;\nend;\n\n{**\n  Executes an SQL statement that returns a single <code>ResultSet</code> object.\n  @param sql typically this is a static SQL <code>SELECT</code> statement\n  @return a <code>ResultSet</code> object that contains the data produced by the\n    given query; never <code>null</code>\n}\nfunction TZOraclePreparedStatement.ExecuteQuery(const SQL: RawByteString): IZResultSet;\nbegin\n  Result := GetExecStatement.ExecuteQuery(SQL);\nend;\n\n{**\n  Executes an SQL <code>INSERT</code>, <code>UPDATE</code> or\n  <code>DELETE</code> statement. In addition,\n  SQL statements that return nothing, such as SQL DDL statements,\n  can be executed.\n\n  @param sql an SQL <code>INSERT</code>, <code>UPDATE</code> or\n    <code>DELETE</code> statement or an SQL statement that returns nothing\n  @return either the row count for <code>INSERT</code>, <code>UPDATE</code>\n    or <code>DELETE</code> statements, or 0 for SQL statements that return nothing\n}\nfunction TZOraclePreparedStatement.ExecuteUpdate(const SQL: RawByteString): Integer;\nbegin\n  Result := GetExecStatement.ExecuteUpdate(SQL);\n  LastUpdateCount := Result;\nend;\n\n{**\n  Prepares an SQL statement\n}\nprocedure TZOraclePreparedStatement.Prepare;\nvar\n  I: Integer;\n  Status: Integer;\n  TypeCode: ub2;\n  CurrentVar: PZSQLVar;\nbegin\n  if not Prepared then\n  begin\n    { Allocates statement handles. }\n    if (FHandle = nil) or (FErrorHandle = nil) then\n    begin\n      AllocateOracleStatementHandles(FPlainDriver, Connection,\n        FHandle, FErrorHandle);\n    end;\n\n    PrepareOracleStatement(FPlainDriver, ASQL, LogSQL, Handle, ErrorHandle,\n      StrToIntDef(Info.Values['prefetch_count'], 100), ConSettings);\n\n    AllocateOracleSQLVars(FInVars, InParamCount);\n    InVars^.ActualNum := InParamCount;\n\n    for I := 0 to InParamCount - 1 do\n    begin\n      CurrentVar := @FInVars.Variables[I + 1];\n      CurrentVar.Handle := nil;\n\n      { Artificially define Oracle internal type. }\n      if InParamTypes[I] in [stBytes, stBinaryStream] then\n        TypeCode := SQLT_BLOB\n      else if InParamTypes[I] = stAsciiStream then\n        TypeCode := SQLT_CLOB\n      else if InParamTypes[I] = stUnicodeStream then\n        TypeCode := SQLT_CLOB\n      else TypeCode := SQLT_STR;\n\n      InitializeOracleVar(FPlainDriver, Connection, CurrentVar,\n        InParamTypes[I], TypeCode, 1024);\n\n      Status := FPlainDriver.BindByPos(FHandle, CurrentVar.BindHandle,\n        FErrorHandle, I + 1, CurrentVar.Data, CurrentVar.Length,\n        CurrentVar.TypeCode, @CurrentVar.Indicator, nil, nil, 0, nil,\n        OCI_DEFAULT);\n      CheckOracleError(FPlainDriver, FErrorHandle, Status, lcExecute, LogSQL);\n    end;\n\n    DriverManager.LogMessage(lcExecute, FPlainDriver.GetProtocol, LogSQL);\n    Prepared := True;\n  end;\nend;\n\n{**\n  Executes the SQL query in this <code>PreparedStatement</code> object\n  and returns the result set generated by the query.\n\n  @return a <code>ResultSet</code> object that contains the data produced by the\n    query; never <code>null</code>\n}\nfunction TZOraclePreparedStatement.ExecutePrepared: Boolean;\nvar\n  StatementType: ub2;\nbegin\n  Result := False;\n\n  { Prepares a statement. }\n  if not Prepared then\n    Prepare;\n\n  { Loads binded variables with values. }\n  LoadOracleVars(FPlainDriver, Connection, ErrorHandle,\n    FInVars, InParamValues, ChunkSize);\n\n  StatementType := 0;\n  FPlainDriver.AttrGet(Handle, OCI_HTYPE_STMT, @StatementType, nil,\n    OCI_ATTR_STMT_TYPE, ErrorHandle);\n\n  if StatementType = OCI_STMT_SELECT then\n  begin\n    { Executes the statement and gets a resultset. }\n    LastResultSet := CreateOracleResultSet(FPlainDriver, Self,\n      SQL, Handle, ErrorHandle);\n    Result := LastResultSet <> nil;\n  end\n  else\n  begin\n    { Executes the statement and gets a result. }\n    ExecuteOracleStatement(FPlainDriver, Connection, LogSQL,\n      Handle, ErrorHandle);\n    LastUpdateCount := GetOracleUpdateCount(FPlainDriver, Handle, ErrorHandle);\n  end;\n\n  DriverManager.LogMessage(lcExecute, FPlainDriver.GetProtocol, LogSQL);\n\n  { Unloads binded variables with values. }\n  UnloadOracleVars(FInVars);\n\n  { Autocommit statement. }\n  if not Result and Connection.GetAutoCommit then\n    Connection.Commit;\nend;\n\n{**\n  Executes the SQL query in this <code>PreparedStatement</code> object\n  and returns the result set generated by the query.\n\n  @return a <code>ResultSet</code> object that contains the data produced by the\n    query; never <code>null</code>\n}\nfunction TZOraclePreparedStatement.ExecuteQueryPrepared: IZResultSet;\nbegin\n  { Prepares a statement. }\n  if not Prepared then\n    Prepare;\n\n  { Loads binded variables with values. }\n  LoadOracleVars(FPlainDriver, Connection, ErrorHandle,\n    FInVars, InParamValues,ChunkSize);\n\n  { Executes the statement and gets a resultset. }\n  Result := CreateOracleResultSet(FPlainDriver, Self, SQL,\n    Handle, ErrorHandle);\n\n  DriverManager.LogMessage(lcExecute, FPlainDriver.GetProtocol, SQL);\n\n  { Unloads binded variables with values. }\n  UnloadOracleVars(FInVars);\nend;\n\n{**\n  Executes the SQL INSERT, UPDATE or DELETE statement\n  in this <code>PreparedStatement</code> object.\n  In addition,\n  SQL statements that return nothing, such as SQL DDL statements,\n  can be executed.\n\n  @return either the row count for INSERT, UPDATE or DELETE statements;\n  or 0 for SQL statements that return nothing\n}\nfunction TZOraclePreparedStatement.ExecuteUpdatePrepared: Integer;\nvar\n  StatementType: ub2;\n  ResultSet: IZResultSet;\nbegin\n  { Prepares a statement. }\n  if not Prepared then\n    Prepare;\n\n  { Loads binded variables with values. }\n  LoadOracleVars(FPlainDriver, Connection, ErrorHandle,\n    FInVars, InParamValues, ChunkSize);\n\n  try\n    StatementType := 0;\n    FPlainDriver.AttrGet(Handle, OCI_HTYPE_STMT, @StatementType, nil,\n      OCI_ATTR_STMT_TYPE, ErrorHandle);\n\n    if StatementType = OCI_STMT_SELECT then\n    begin\n      { Executes the statement and gets a resultset. }\n      ResultSet := CreateOracleResultSet(FPlainDriver, Self,\n        SQL, Handle, ErrorHandle);\n      try\n        while ResultSet.Next do;\n        LastUpdateCount := ResultSet.GetRow;\n      finally\n        ResultSet.Close;\n      end;\n    end\n    else\n    begin\n      { Executes the statement and gets a result. }\n      ExecuteOracleStatement(FPlainDriver, Connection, LogSQL,\n        Handle, ErrorHandle);\n      LastUpdateCount := GetOracleUpdateCount(FPlainDriver, Handle, ErrorHandle);\n    end;\n    Result := LastUpdateCount;\n\n    DriverManager.LogMessage(lcExecute, FPlainDriver.GetProtocol, LogSQL);\n  finally\n    { Unloads binded variables with values. }\n    UnloadOracleVars(FInVars);\n  end;\n\n  { Autocommit statement. }\n  if Connection.GetAutoCommit then\n    Connection.Commit;\nend;\n\n{**\n  Gets statement handle.\n  @return statement handle.\n}\nfunction TZOraclePreparedStatement.GetStatementHandle: POCIStmt;\nbegin\n  Result := FHandle;\nend;\n\nprocedure TZOracleCallableStatement.Prepare;\nvar\n  I: Integer;\n  Status: Integer;\n  TypeCode: ub2;\n  CurrentVar: PZSQLVar;\n  SQLType:TZSQLType;\nbegin\n  if not FPrepared then\n  begin\n    ArrangeInParams; //need to sort ReturnValues for functions\n    ASQL := GetProcedureSql(False);\n    SetLength(FParamNames, FOracleParamsCount);\n    for i := 0 to FOracleParamsCount -1 do\n      FParamNames[I] := Self.FOracleParams[I].pName;\n\n    { Allocates statement handles. }\n    if (FHandle = nil) or (FErrorHandle = nil) then\n    begin\n      AllocateOracleStatementHandles(FPlainDriver, Connection,\n        FHandle, FErrorHandle);\n    end;\n\n    PrepareOracleStatement(FPlainDriver, ASQL, LogSQL, FHandle, FErrorHandle,\n      StrToIntDef(Info.Values['prefetch_count'], 100), ConSettings);\n    //make sure eventual old buffers are cleaned\n    FreeOracleSQLVars(FPlainDriver, FInVars, (Connection as IZOracleConnection).GetConnectionHandle, FErrorHandle, ConSettings);\n    AllocateOracleSQLVars(FInVars, FOracleParamsCount);\n    FInVars^.ActualNum := FOracleParamsCount;\n\n    for I := 0 to FOracleParamsCount - 1 do\n    begin\n      CurrentVar := @FInVars.Variables[I + 1];\n      CurrentVar.Handle := nil;\n      SQLType := TZSQLType(FOracleParams[I].pSQLType);\n\n    { Artificially define Oracle internal type. }\n      if SQLType = stBinaryStream then\n        TypeCode := SQLT_BLOB\n      else if SQLType in [stAsciiStream, stUnicodeStream] then\n        TypeCode := SQLT_CLOB\n      else TypeCode := SQLT_STR;\n\n      InitializeOracleVar(FPlainDriver, Connection, CurrentVar,\n        SQLType, TypeCode, 1024);\n\n      Status := FPlainDriver.BindByPos(FHandle, CurrentVar.BindHandle,\n        FErrorHandle, I + 1, CurrentVar.Data, CurrentVar.Length,\n        CurrentVar.TypeCode, @CurrentVar.Indicator, nil, nil, 0, nil,\n        OCI_DEFAULT);\n      CheckOracleError(FPlainDriver, FErrorHandle, Status, lcExecute, LogSQL);\n    end;\n    DriverManager.LogMessage(lcExecute, FPlainDriver.GetProtocol, LogSQL);\n  end;\nend;\n\n\nprocedure TZOracleCallableStatement.RegisterOutParameter(ParameterIndex,\n  SQLType: Integer);\nbegin\n  inherited RegisterOutParameter(ParameterIndex,SQLType);\n  with FOracleParams[ParameterIndex-1] do\n  begin\n    if not GetConnection.UseMetadata then\n      pName := 'pOut'+IntToStr(ParameterIndex);\n    pSQLType := SQLType;\n  end;\nend;\n\nprocedure TZOracleCallableStatement.RegisterParamType(ParameterIndex: integer;\n  ParamType: Integer);\nbegin\n  inherited RegisterParamType(ParameterIndex, ParamType);\n  if ParameterIndex > High(FOracleParams) then\n    SetLength(FOracleParams, ParameterIndex);\n  if ParameterIndex > FOracleParamsCount then\n    FOracleParamsCount := ParameterIndex;\n  FOracleParams[ParameterIndex-1].pType := ParamType;\n  FOracleParams[ParameterIndex-1].pParamIndex := ParameterIndex;\n  if ParamType in [2,3,4] then //ptInOut, ptOut, ptResult\n  begin\n    Inc(FOutParamCount);\n    FOracleParams[ParameterIndex-1].pOutIndex := FOutParamCount;\n  end;\nend;\n\nprocedure TZOracleCallableStatement.SetInParam(ParameterIndex: Integer;\n  SQLType: TZSQLType; const Value: TZVariant);\nvar \n  AConnection: IZConnection;\n\n  function GetOracleParamIndexOfParameterIndex: Integer;\n  var I: Integer;\n  begin\n    Result := 0;\n    for i := 0 to high(FOracleParams) do\n      if ParameterIndex = FOracleParams[i].pParamIndex then\n      begin\n        Result := I;\n        Break;\n      end;\n  end;\n\nbegin\n  inherited SetInParam(ParameterIndex, SQLType, Value);\n  with FOracleParams[GetOracleParamIndexOfParameterIndex] do\n  begin\n    AConnection := GetConnection;\n    if Assigned(AConnection) and ( not AConnection.UseMetadata ) then\n      pName := 'p'+IntToStr(ParameterIndex);\n    pSQLType := ord(SQLType);\n    pValue := Value;\n  end;\nend;\n\nprocedure TZOracleCallableStatement.RegisterParamTypeAndName(const ParameterIndex: integer;\n  const ParamTypeName, ParamName: String; Const ColumnSize, Precision: Integer);\nvar\n  iPos: Integer;\n  ProcName: String;\nbegin\n  FOracleParams[ParameterIndex].pName := ParamName;\n  FOracleParams[ParameterIndex].pTypeName := ParamTypeName;\n  iPos := Pos('.', ParamName);\n  if iPos > 0 then\n  begin\n    ProcName := Copy(ParamName, 1, iPos-1); //extract function or Procedure names\n    FOracleParams[ParameterIndex].pProcIndex := PackageIncludedList.IndexOf(ProcName); //check index\n    if FOracleParams[ParameterIndex].pProcIndex = -1 then //if not exists\n      FOracleParams[ParameterIndex].pProcIndex := PackageIncludedList.Add(ProcName); //Add to List\n  end\n  else //No package\n    FOracleParams[ParameterIndex].pProcIndex := 0;\nend;\n\nprocedure TZOracleCallableStatement.ArrangeInParams;\nvar\n  I, J, NewProcIndex, StartProcIndex: Integer;\n  TempVars: TZVariantDynArray;\n  TempOraVar: TZOracleParam;\nbegin\n  NewProcIndex := -1;\n  StartProcIndex := 0;\n  if IsFunction then\n  begin\n    for i := 0 to high(FOracleParams) do\n    begin\n      if not ( FOracleParams[i].pProcIndex = NewProcIndex ) then\n      begin\n        NewProcIndex := FOracleParams[i].pProcIndex;\n        StartProcIndex := I;\n      end;\n      if ( FOracleParams[i].pType = 4 ) then\n      begin\n        DefVarManager.SetNull(FOracleParams[i].pValue);\n        if not (i = StartProcIndex) then\n        begin\n          TempOraVar := FOracleParams[I];\n          for J := I downto StartProcIndex+1 do\n            FOracleParams[j] := FOracleParams[j-1];\n          FOracleParams[StartProcIndex] := TempOraVar;\n        end;\n      end;\n    end;\n    SetLength(TempVars, Length(FOracleParams));\n    for i := 0 to high(FOracleParams) do\n      TempVars[i] := FOracleParams[i].pValue;\n    InParamValues := TempVars;  \n  end;\nend;\n\nprocedure TZOracleCallableStatement.FetchOutParamsFromOracleVars;\nvar\n  CurrentVar: PZSQLVar;\n  LobLocator: POCILobLocator;\n  I: integer;\n  TempBlob: IZBlob;\n\n  procedure SetOutParam(CurrentVar: PZSQLVar; Index: Integer);\n  var\n    OracleConnection :IZOracleConnection;\n    Year:SmallInt;\n    Month, Day:Byte; Hour, Min, Sec:ub1; MSec: ub4;\n    dTmp:TDateTime;\n    ps: PAnsiChar;\n  begin\n    case CurrentVar.TypeCode of\n      SQLT_INT: DefVarManager.SetAsInteger( outParamValues[Index], PLongInt(CurrentVar.Data)^ );\n      SQLT_FLT:  DefVarManager.SetAsFloat( outParamValues[Index], PDouble(CurrentVar.Data)^ );\n      SQLT_STR:\n        begin\n          GetMem(ps,1025);\n          try\n            {$IFDEF WITH_STRLCOPY_DEPRECATED}AnsiStrings.{$ENDIF}StrLCopy( ps, (CurrentVar.Data), 1024);\n            DefVarManager.SetAsString( OutParamValues[Index], ZDbcString(ps) );\n          finally\n            FreeMem(ps);\n          end;\n        end;\n      SQLT_TIMESTAMP:\n        begin\n          OracleConnection := Connection as IZOracleConnection;\n          FPlainDriver.DateTimeGetDate(\n            OracleConnection.GetConnectionHandle ,\n            FErrorHandle, PPOCIDescriptor(CurrentVar.Data)^,\n            Year, Month, Day);\n          FPlainDriver.DateTimeGetTime(\n            OracleConnection.GetConnectionHandle ,\n            FErrorHandle, PPOCIDescriptor(CurrentVar.Data)^,\n            Hour, Min, Sec,MSec);\n          dTmp := EncodeDate(year,month,day )+EncodeTime(Hour,min,sec,msec) ;\n          DefVarManager.SetAsDateTime( outParamValues[Index], dTmp );\n        end;\n      SQLT_BLOB, SQLT_CLOB, SQLT_BFILEE, SQLT_CFILEE:\n        begin\n          if CurrentVar.Indicator >= 0 then\n            LobLocator := PPOCIDescriptor(CurrentVar.Data)^\n          else\n            LobLocator := nil;\n\n          OracleConnection := Connection as IZOracleConnection;\n          TempBlob := TZOracleBlob.Create(FPlainDriver, nil, 0, OracleConnection,\n            LobLocator, CurrentVar.ColType, GetChunkSize);\n          (TempBlob as IZOracleBlob).ReadBlob;\n          DefVarManager.SetAsInterface(outParamValues[Index], TempBlob);\n          TempBlob := nil;\n        end;\n      SQLT_NTY:\n        DefVarManager.SetAsInterface(outParamValues[Index],\n          TZOracleBlob.CreateWithStream(nil, GetConnection));\n      end;\n  end;\nbegin\n  for I := 0 to FOracleParamsCount -1 do\n    if FOracleParams[i].pType in [2,3,4] then\n    begin\n      CurrentVar:= @FInVars.Variables[I+1];\n      CurrentVar.Data := CurrentVar.DupData;\n      SetOutParam(CurrentVar, FOracleParams[i].pParamIndex-1);\n    end;\nend;\n\nfunction TZOracleCallableStatement.GetProcedureSql(SelectProc: boolean): RawByteString;\nvar\n  sFunc: string;\n  I, IncludeCount, LastIndex: Integer;\n  PackageBody: TStrings;\n  TempResult: String;\n\n  function GenerateParamsStr(Count: integer): string;\n  var\n    I: integer;\n  begin\n    for I := 0 to Count - 1 do\n    begin\n      if ( FDBParamTypes[I] = 4 ) then //ptResult\n      begin\n        sFunc := ' :'+FOracleParams[0].pName+' := ';\n        continue;\n      end;\n      if Result <> '' then\n        Result := Result + ',';\n      if IsFunction then\n        Result := Result + ':'+FOracleParams[I+1].pName\n      else\n        Result := Result + ':'+FOracleParams[I].pName;\n    end;\n    Result := '('+Result+')'\n  end;\n\nvar\n  InParams: string;\nbegin\n  sFunc := '';\n  if PackageIncludedList.Count > 0 then\n  begin\n    PackageBody := TStringList.Create;\n    PackageBody.Add('BEGIN');\n    LastIndex := 0;\n    for IncludeCount := 0 to PackageIncludedList.Count -1 do\n    begin\n      InParams := '';\n      sFunc := '';\n      for i := LastIndex to high(FOracleParams) do\n        if IncludeCount = FOracleParams[i].pProcIndex then\n          if ( FOracleParams[I].pType = 4 ) then //ptResult\n            sFunc := ' :'+StringReplace(FOracleParams[I].pName, '.', '', [rfReplaceAll])+' := '\n          else\n            if InParams <> '' then\n              InParams := InParams +', :'+StringReplace(FOracleParams[I].pName, '.', '', [rfReplaceAll])\n            else\n              InParams := InParams +':'+StringReplace(FOracleParams[I].pName, '.', '', [rfReplaceAll])\n        else\n        begin\n          LastIndex := I;\n          break;\n        end;\n      PackageBody.Add('BEGIN '+sFunc+SQL+\n        '.'+GetConnection.GetMetadata.GetIdentifierConvertor.Quote(PackageIncludedList[IncludeCount])+'('+InParams+'); END;');\n    end;\n    PackageBody.Add('END;');\n    TempResult := TrimRight(PackageBody.Text);\n    FreeAndNil(PackageBody);\n  end\n  else\n  begin\n    InParams := GenerateParamsStr( FOracleParamsCount );\n    TempResult := 'BEGIN ' + sFunc +SQL + InParams+'; END;';\n  end;\n  Result := ZPlainString(TempResult);\nend;\n\nfunction TZOracleCallableStatement.IsNull(ParameterIndex: Integer): Boolean;\nbegin\n  result := inherited IsNull(ParameterIndex);\nend;\n\nprocedure TZOracleCallableStatement.ClearParameters;\nbegin\n  inherited;\n  FOracleParamsCount := 0;\n  SetLength(FOracleParams, 0);\nend;\n\nconstructor TZOracleCallableStatement.Create(Connection: IZConnection;\n  const pProcName: string; Info: TStrings);\nbegin\n\n  inherited Create(Connection, pProcName, Info);\n\n  FOracleParamsCount := 0;\n  FPlainDriver := Connection.GetIZPlainDriver as IZOraclePlainDriver;\n  ResultSetType := rtForwardOnly;\n  FPrepared := False;\n  PackageIncludedList := TStringList.Create;\n  FOutParamCount := 0;\nend;\n\ndestructor TZOracleCallableStatement.Destroy;\nbegin\n  FreeOracleSQLVars(FPlainDriver, FInVars, (Connection as IZOracleConnection).GetConnectionHandle, FErrorHandle, ConSettings);\n  PackageIncludedList.Free;\n  inherited;\nend;\n\nfunction TZOracleCallableStatement.ExecuteUpdatePrepared: Integer;\nbegin\n  { Prepares a statement. }\n  if not Prepared then\n    Prepare;\n\n  { Loads binded variables with values. }\n  LoadOracleVars(FPlainDriver , Connection, FErrorHandle,\n    FInVars, InParamValues, ChunkSize);\n\n  try\n    ExecuteOracleStatement(FPlainDriver, Connection, LogSQL,\n      FHandle, FErrorHandle);\n    LastUpdateCount := GetOracleUpdateCount(FPlainDriver, FHandle, FErrorHandle);\n    FetchOutParamsFromOracleVars;\n    DriverManager.LogMessage(lcExecute, FPlainDriver.GetProtocol, LogSQL);\n  finally\n    { Unloads binded variables with values. }\n    UnloadOracleVars(FInVars);\n  end;\n\n  { Autocommit statement. }\n  if Connection.GetAutoCommit then\n    Connection.Commit;\n\n  Result := LastUpdateCount;\nend;\n\nfunction TZOracleCallableStatement.ExecuteQueryPrepared: IZResultSet;\nbegin\n  { Prepares a statement. }\n  if not Prepared then\n    Prepare;\n\n  { Loads binded variables with values. }\n  LoadOracleVars(FPlainDriver , Connection, FErrorHandle,\n    FInVars, InParamValues, ChunkSize);\n\n  try\n    ExecuteOracleStatement(FPlainDriver, Connection, LogSQL,\n      FHandle, FErrorHandle);\n    FetchOutParamsFromOracleVars;\n    LastResultSet := CreateOracleResultSet(FPlainDriver, Self, LogSQL,\n      FHandle, FErrorHandle, FInVars, FOracleParams);\n    Result := LastResultSet;\n    DriverManager.LogMessage(lcExecute, FPlainDriver.GetProtocol, LogSQL);\n  finally\n    { Unloads binded variables with values. }\n    UnloadOracleVars(FInVars);\n  end;\nend;\n\nend.\n"
  },
  {
    "path": "lib/zeosdbo/src/dbc/ZDbcOracleUtils.pas",
    "content": "{*********************************************************}\n{                                                         }\n{                 Zeos Database Objects                   }\n{           Oracle Database Connectivity Classes          }\n{                                                         }\n{          Originally written by Sergey Seroukhov         }\n{                                                         }\n{*********************************************************}\n\n{@********************************************************}\n{    Copyright (c) 1999-2012 Zeos Development Group       }\n{                                                         }\n{ License Agreement:                                      }\n{                                                         }\n{ This library is distributed in the hope that it will be }\n{ useful, but WITHOUT ANY WARRANTY; without even the      }\n{ implied warranty of MERCHANTABILITY or FITNESS FOR      }\n{ A PARTICULAR PURPOSE.  See the GNU Lesser General       }\n{ Public License for more details.                        }\n{                                                         }\n{ The source code of the ZEOS Libraries and packages are  }\n{ distributed under the Library GNU General Public        }\n{ License (see the file COPYING / COPYING.ZEOS)           }\n{ with the following  modification:                       }\n{ As a special exception, the copyright holders of this   }\n{ library give you permission to link this library with   }\n{ independent modules to produce an executable,           }\n{ regardless of the license terms of these independent    }\n{ modules, and to copy and distribute the resulting       }\n{ executable under terms of your choice, provided that    }\n{ you also meet, for each linked independent module,      }\n{ the terms and conditions of the license of that module. }\n{ An independent module is a module which is not derived  }\n{ from or based on this library. If you modify this       }\n{ library, you may extend this exception to your version  }\n{ of the library, but you are not obligated to do so.     }\n{ If you do not wish to do so, delete this exception      }\n{ statement from your version.                            }\n{                                                         }\n{                                                         }\n{ The project web site is located on:                     }\n{   http://zeos.firmos.at  (FORUM)                        }\n{   http://sourceforge.net/p/zeoslib/tickets/ (BUGTRACKER)}\n{   svn://svn.code.sf.net/p/zeoslib/code-0/trunk (SVN)    }\n{                                                         }\n{   http://www.sourceforge.net/projects/zeoslib.          }\n{                                                         }\n{                                                         }\n{                                 Zeos Development Group. }\n{********************************************************@}\n\nunit ZDbcOracleUtils;\n\ninterface\n\n{$I ZDbc.inc}\n\nuses\n  Types, Classes, {$IFDEF MSEgui}mclasses,{$ENDIF} SysUtils,\n  ZSysUtils, ZDbcIntfs, ZVariant, ZPlainOracleDriver, ZDbcLogging,\n  ZCompatibility, ZPlainOracleConstants;\n\nconst\n  MAX_SQLVAR_LIMIT = 1024;\n\ntype\n  {** Declares SQL Object }\n\n  POCIObject = ^TOCIObject;\n  TObjFields = array of POCIObject;\n  TOCIObject = Record                 // embedded object or table will work recursively\n    type_name:      String;           //object's name (TDO)\n    type_schema:    String;           //object's schema name (TDO)\n    parmdp:         POCIParam;        //Describe attributes of the object OCI_DTYPE_PARAM\n    parmap:         POCIParam;        //Describe attributes of the object OCI_ATTR_COLLECTION_ELEMENT OCI_ATTR_PARAM\n    tdo:            POCIType;         //object's TDO handle\n    typecode:       OCITypeCode;      //object's OCI_ATTR_TYPECODE\n    col_typecode:   OCITypeCode;      //if collection this is its OCI_ATTR_COLLECTION_TYPECODE\n    elem_typecode:  OCITypeCode;      //if collection this is its element's OCI_ATTR_TYPECODE\n    obj_ref:        POCIRef;          //if an embeded object this is ref handle to its TDO\n    obj_ind:        POCIInd;          //Null indictator for object\n    obj_value:      POCIComplexObject;//the actual value from the DB\n    obj_type:       POCIType;         //if an embeded object this is the  OCIType returned by a OCIObjectPin\n    is_final_type:  ub1;              //object's OCI_ATTR_IS_FINAL_TYPE\n    fields:         TObjFields;       //one object for each field/property\n    field_count:    ub2;              //The number of fields Not really needed but nice to have\n    next_subtype:   POCIObject;       //There is strored information about subtypes for inteherited objects\n    stmt_handle:    POCIStmt;         //the Statement-Handle\n    Level:          Integer;          //the instance level\n    Pinned:         Boolean;          //did we pin the obj on decribe?\n  end;\n\n  PZSQLVar = ^TZSQLVar;\n  TZSQLVar = {$ifndef FPC_REQUIRES_PROPER_ALIGNMENT}packed{$endif} record\n    Handle:    POCIHandle;\n    Define:    POCIHandle;\n    BindHandle: POCIBind;\n    Data:      Pointer;\n    DupData:   Pointer;\n    DataType:  ub2;\n    DataSize:  ub2;\n    Length:    Integer;\n    Precision: Integer;\n    Scale:     Integer;\n    ColType:   TZSQLType;\n    TypeCode:  ub2;\n    Indicator: sb2;\n    Blob:      IZBlob;\n    _Obj:      POCIObject;\n  end;\n\n  TZSQLVars = {$ifndef FPC_REQUIRES_PROPER_ALIGNMENT}packed{$endif} record\n    AllocNum:  ub4;\n    ActualNum: ub4;\n    Variables: array[1..MAX_SQLVAR_LIMIT] of TZSQLVar;\n  end;\n  PZSQLVars = ^TZSQLVars;\n\n  TZOracleParam = Record\n    pName:string;\n    pSQLType:Integer;\n    pValue: TZVariant;\n    pTypeName: String;\n    pType: ShortInt;\n    pProcIndex: Integer;\n    pParamIndex: Integer;\n    pOutIndex: Integer;\n  End;\n  TZOracleParams = array of TZOracleParam;\n\n{**\n  Allocates memory for Oracle SQL Variables.\n  @param Variables a pointer to array of variables.\n  @param Count a number of SQL variables.\n}\nprocedure AllocateOracleSQLVars(var Variables: PZSQLVars; Count: Integer);\n\n{**\n  Frees memory Oracle SQL Variables from the memory.\n  @param PlainDriver an Oracle plain driver.\n  @param Variables a pointer to array of variables.\n}\nprocedure FreeOracleSQLVars(const PlainDriver: IZOraclePlainDriver;\n  var Variables: PZSQLVars; const Handle: POCIEnv; const ErrorHandle: POCIError;\n  const ConSettings: PZConSettings);\n\n{**\n  Allocates in memory and initializes the Oracle variable.\n  @param PlainDriver an Oracle plain driver.\n  @param Connection an Oracle connection Object.\n  @param Variable an Oracle variable holder.\n  @param DataType a DBC data type.\n  @param OracleType a correspondent Oracle type.\n  @param DataSize a length for string variables.\n}\nprocedure InitializeOracleVar(PlainDriver: IZOraclePlainDriver;\n  Connection: IZConnection; var Variable: PZSQLVar;\n  DataType: TZSQLType; OracleType: ub2; DataSize: Integer);\n\n{**\n  Loads Oracle variables binded to SQL statement with data.\n  @param PlainDriver an Oracle plain driver.\n  @param Connection an Oracle connection Object.\n  @param Variables Oracle variable holders.\n  @param Values a values to be loaded.\n}\nprocedure LoadOracleVars(PlainDriver: IZOraclePlainDriver;\n  Connection: IZConnection; ErrorHandle: POCIError; Variables: PZSQLVars;\n  Values: TZVariantDynArray; ChunkSize: Integer);\n\n{**\n  Unloads Oracle variables binded to SQL statement with data.\n  @param Variables Oracle variable holders.\n}\nprocedure UnloadOracleVars(Variables: PZSQLVars);\n\n{**\n  Convert string Oracle field type to SQLType\n  @param string field type value\n  @result the SQLType field type value\n}\nfunction ConvertOracleTypeToSQLType(TypeName: string;\n  Precision, Scale: Integer; const CtrlsCPType: TZControlsCodePage): TZSQLType;\n\n{**\n  Converts Oracle internal date into TDateTime\n  @param Value a pointer to Oracle internal date.\n  @return a decoded TDateTime value.\n}\nfunction OraDateToDateTime(Value: PAnsiChar): TDateTime;\n\n{**\n  Checks for possible SQL errors.\n  @param PlainDriver an Oracle plain driver.\n  @param Handle an Oracle error handle.\n  @param Status a command return status.\n  @param LogCategory a logging category.\n  @param LogMessage a logging message.\n}\nprocedure CheckOracleError(PlainDriver: IZOraclePlainDriver;\n  ErrorHandle: POCIError; Status: Integer; LogCategory: TZLoggingCategory;\n  LogMessage: string);\n\n{**\n  Creates an Oracle result set based on the current settings.\n  @return a created result set object.\n}\nfunction CreateOracleResultSet(PlainDriver: IZOraclePlainDriver;\n  Statement: IZStatement; LogSQL: string; Handle: POCIStmt;\n  ErrorHandle: POCIError): IZResultSet; overload;\n\n{**\n  Creates an Oracle result set based on the current settings.\n  @return a created result set object.\n}\nfunction CreateOracleResultSet(PlainDriver: IZOraclePlainDriver;\n  Statement: IZStatement; LogSQL: string; StmtHandle: POCIStmt;\n  ErrorHandle: POCIError; OutVars: PZSQLVars;\n  Const OracleParams: TZOracleParams): IZResultSet; overload;\n\n{**\n  Allocates in memory Oracle handlers for Statement object.\n  @param PlainDriver an Oracle plain driver.\n  @param Connection an Oracle connection object.\n  @param Handle a holder for Statement handle.\n  @param ErrorHandle a holder for Error handle.\n}\nprocedure AllocateOracleStatementHandles(PlainDriver: IZOraclePlainDriver;\n  Connection: IZConnection; var Handle: POCIStmt; var ErrorHandle: POCIError);\n\n{**\n  Frees from memory Oracle handlers for Statement object.\n  @param PlainDriver an Oracle plain driver.\n  @param Handle a holder for Statement handle.\n  @param ErrorHandle a holder for Error handle.\n}\nprocedure FreeOracleStatementHandles(PlainDriver: IZOraclePlainDriver;\n  var Handle: POCIStmt; var ErrorHandle: POCIError);\n\n{**\n  Prepares an Oracle statement.\n  @param PlainDriver an Oracle plain driver.\n  @param SQL an SQL query to be prepared.\n  @param Handle a holder for Statement handle.\n  @param ErrorHandle a holder for Error handle.\n}\nprocedure PrepareOracleStatement(PlainDriver: IZOraclePlainDriver;\n  SQL: RawByteString; LogSQL: String; Handle: POCIStmt; ErrorHandle: POCIError;\n  PrefetchCount: ub4; ConSettings: PZConSettings);\n\n{**\n  Executes an Oracle statement.\n  @param PlainDriver an Oracle plain driver.\n  @param Connection an Oracle connection Object.\n  @param SQL an SQL query to be prepared.\n  @param Handle a holder for Statement handle.\n  @param ErrorHandle a holder for Error handle.\n}\nprocedure ExecuteOracleStatement(PlainDriver: IZOraclePlainDriver;\n  Connection: IZConnection; LogSQL: string; Handle: POCIStmt;\n  ErrorHandle: POCIError);\n\n{**\n  Gets a number of updates made by executed Oracle statement.\n  @param PlainDriver an Oracle plain driver.\n  @param Handle a holder for Statement handle.\n  @param ErrorHandle a holder for Error handle.\n  @returns a number of updates.\n}\nfunction GetOracleUpdateCount(PlainDriver: IZOraclePlainDriver;\n  Handle: POCIStmt; ErrorHandle: POCIError): ub4;\n\nfunction DescribeObject(PlainDriver: IZOraclePlainDriver; Connection: IZConnection;\n  ParamHandle: POCIParam; stmt_handle: POCIHandle; Level: ub2): POCIObject;\n\nimplementation\n\nuses ZMessages, ZDbcOracle, ZDbcOracleResultSet, ZDbcCachedResultSet,\n  ZDbcGenericResolver, ZDbcUtils, ZEncoding\n  {$IFDEF WITH_UNITANSISTRINGS}, AnsiStrings{$ENDIF};\n\n{**\n  Calculates size of SQLVars record.\n  @param Count a number of variable.\n  @returns a record size.\n}\nfunction CalculateSQLVarsSize(Count: Integer): Integer;\nbegin\n  Result := SizeOf(TZSQLVars) + Count * SizeOf(TZSQLVar);\nend;\n\n{**\n  Allocates memory for Oracle SQL Variables.\n  @param Variables a pointer to array of variables.\n  @param Count a number of SQL variables.\n}\nprocedure AllocateOracleSQLVars(var Variables: PZSQLVars; Count: Integer);\nvar\n  Size: Integer;\nbegin\n  if Variables <> nil then\n    FreeMem(Variables);\n\n  Size := CalculateSQLVarsSize(Count);\n  GetMem(Variables, Size);\n  FillChar(Variables^, Size, 0);\n  Variables^.AllocNum := Count;\n  Variables^.ActualNum := 0;\nend;\n\n{**\n  Frees memory Oracle SQL Variables from the memory.\n  @param PlainDriver an Oracle plain driver.\n  @param Variables a pointer to array of variables.\n}\nprocedure FreeOracleSQLVars(const PlainDriver: IZOraclePlainDriver;\n  var Variables: PZSQLVars; const Handle: POCIEnv; const ErrorHandle: POCIError;\n  const ConSettings: PZConSettings);\nvar\n  I: Integer;\n  CurrentVar: PZSQLVar;\n\n  procedure DisposeObject(var Obj: POCIObject);\n  var\n    I: Integer;\n  begin\n    for i := 0 to High(Obj.fields) do\n      DisposeObject(Obj.fields[i]);\n    SetLength(Obj.fields, 0);\n    if Assigned(Obj.next_subtype) then\n    begin\n      DisposeObject(Obj.next_subtype);\n      Obj.next_subtype := nil;\n    end;\n    if Obj.Pinned then\n      {Unpin tdo}\n      //CheckOracleError(PlainDriver, ErrorHandle, //debug\n        PlainDriver.ObjectUnpin(Handle,ErrorHandle, CurrentVar^._Obj.tdo)\n        ;//debug, lcOther, 'OCIObjectUnpin', ConSettings);\n    if (Obj.Level = 0) and assigned(Obj.tdo) then\n      {Free Object}\n      //debugCheckOracleError(PlainDriver, ErrorHandle,\n      PlainDriver.ObjectFree(Handle,ErrorHandle, CurrentVar^._Obj.tdo, 0)\n      ;//debug, lcOther, 'OCIObjectFree', ConSettings);\n    Dispose(Obj);\n    Obj := nil;\n  end;\n\nbegin\n  if Variables <> nil then\n  begin\n    { Frees allocated memory for output variables }\n    for I := 1 to Variables.ActualNum do\n    begin\n      CurrentVar := @Variables.Variables[I];\n      if Assigned(CurrentVar._Obj) then\n        DisposeObject(CurrentVar^._Obj);\n      if CurrentVar.Data <> nil then\n      begin\n        if CurrentVar.TypeCode in [SQLT_BLOB, SQLT_CLOB, SQLT_BFILEE, SQLT_CFILEE] then\n        begin\n          PlainDriver.DescriptorFree(PPOCIDescriptor(CurrentVar.Data)^,\n            OCI_DTYPE_LOB);\n        end\n        else if CurrentVar.TypeCode = SQLT_TIMESTAMP then\n        begin\n          PlainDriver.DescriptorFree(PPOCIDescriptor(CurrentVar.Data)^,\n            OCI_DTYPE_TIMESTAMP);\n        end;\n        FreeMem(CurrentVar.Data);\n        CurrentVar.Data := nil;\n      end;\n    end;\n\n    FreeMem(Variables);\n  end;\n  Variables := nil;\nend;\n\n{**\n  Allocates in memory and initializes the Oracle variable.\n  @param PlainDriver an Oracle plain driver.\n  @param Connection an Oracle connection Object.\n  @param Variable an Oracle variable holder.\n  @param DataType a DBC data type.\n  @param OracleType a correspondent Oracle type.\n  @param DataSize a length for string variables.\n}\n\nprocedure InitializeOracleVar(PlainDriver: IZOraclePlainDriver;\n  Connection: IZConnection; var Variable: PZSQLVar;\n  DataType: TZSQLType; OracleType: ub2; DataSize: Integer);\nvar\n  Length: Integer;\n  OracleConnection: IZOracleConnection;\nbegin\n  OracleConnection := Connection as IZOracleConnection;\n  Variable.ColType := DataType;\n  Variable.TypeCode := OracleType;\n  Variable.DataSize := DataSize;\n  Length := 0;\n  case Variable.ColType of\n    stByte, stShort, stInteger:\n      begin\n        Variable.TypeCode := SQLT_INT;\n        Length := SizeOf(LongInt);\n      end;\n    stFloat, stDouble, stLong:\n      begin\n        Variable.TypeCode := SQLT_FLT;\n        Length := SizeOf(Double);\n      end;\n    stDate, stTime, stTimestamp:\n      begin\n        Variable.TypeCode := SQLT_TIMESTAMP;\n        Length := SizeOf(POCIDateTime);\n      end;\n    stString, stUnicodeString:\n      begin\n        Variable.TypeCode := SQLT_STR;\n        Length := Variable.DataSize + 1;\n      end;\n    stAsciiStream, stUnicodeStream, stBinaryStream, stBytes:\n      begin\n        if not (Variable.TypeCode in [SQLT_CLOB, SQLT_BLOB, SQLT_BFILEE, SQLT_CFILEE,SQLT_NTY]) then\n        begin\n          if Variable.ColType = stAsciiStream then\n            Variable.TypeCode := SQLT_LVC\n          else\n            Variable.TypeCode := SQLT_LVB;\n          if Variable.DataSize = 0 then\n            Length := 128 * 1024 + SizeOf(Integer)\n          else\n            Length := Variable.DataSize + SizeOf(Integer);\n        end\n        else\n          Length := SizeOf(POCILobLocator);\n      end;\n    stDataSet: ; //Do nothing here!\n    stUnknown:\n      Exit;\n  end;\n\n  Variable.Length := Length;\n  GetMem(Variable.Data, Variable.Length);\n  if Variable.TypeCode in [SQLT_BIN, SQLT_BLOB, SQLT_CLOB, SQLT_BFILEE, SQLT_CFILEE] then\n  begin\n    PlainDriver.DescriptorAlloc(OracleConnection.GetConnectionHandle,\n      PPOCIDescriptor(Variable.Data)^, OCI_DTYPE_LOB, 0, nil);\n  end\n  else\n    if Variable.TypeCode = SQLT_TIMESTAMP then\n    begin\n      PlainDriver.DescriptorAlloc(OracleConnection.GetConnectionHandle,\n        PPOCIDescriptor(Variable.Data)^, OCI_DTYPE_TIMESTAMP, 0, nil);\n    end;\nend;\n\n{**\n  Loads Oracle variables binded to SQL statement with data.\n  @param PlainDriver an Oracle plain driver.\n  @param Connection an Oracle connection Object.\n  @param Variables Oracle variable holders.\n  @param Values a values to be loaded.\n}\nprocedure LoadOracleVars(PlainDriver: IZOraclePlainDriver;\n  Connection: IZConnection; ErrorHandle: POCIError; Variables: PZSQLVars;\n  Values: TZVariantDynArray; ChunkSize: Integer);\nvar\n  I, Len: Integer;\n  Status: Integer;\n  CurrentVar: PZSQLVar;\n  TempDate: TDateTime;\n  TempBytes: TByteDynArray;\n  TempBlob: IZBlob;\n  WriteTempBlob: IZOracleBlob;\n  TempStream: TStream;\n  Year, Month, Day, Hour, Min, Sec, MSec: Word;\n  OracleConnection: IZOracleConnection;\nbegin\n  OracleConnection := Connection as IZOracleConnection;\n  for I := 0 to Variables.ActualNum - 1 do\n  begin\n    CurrentVar := @Variables.Variables[I + 1];\n    CurrentVar.DupData := CurrentVar.Data;\n    if (high(Values)<I) or DefVarManager.IsNull(Values[I]) then\n    begin\n      CurrentVar.Indicator := -1;\n      //CurrentVar.Data := nil;\n    end\n    else\n    begin\n      CurrentVar.Indicator := 0;\n      case CurrentVar.TypeCode of\n        SQLT_INT:\n          begin\n            PLongInt(CurrentVar.Data)^ :=\n              DefVarManager.GetAsInteger(Values[I]);\n          end;\n        SQLT_FLT:\n          begin\n            PDouble(CurrentVar.Data)^ :=\n              DefVarManager.GetAsFloat(Values[I]);\n          end;\n        SQLT_STR:\n          begin\n            case Values[i].VType of\n              vtUnicodeString:\n                {$IFDEF WITH_STRLCOPY_DEPRECATED}AnsiStrings.{$ENDIF}StrLCopy(PAnsiChar(CurrentVar.Data),\n                  PAnsiChar(PlainDriver.ZPlainString(SoftVarManager.GetAsUnicodeString(Values[I]), Connection.GetConSettings)), 1024);\n              else\n                {$IFDEF WITH_STRLCOPY_DEPRECATED}AnsiStrings.{$ENDIF}StrLCopy(PAnsiChar(CurrentVar.Data),\n                  PAnsiChar(PlainDriver.ZPlainString(SoftVarManager.GetAsString(Values[I]), Connection.GetConSettings)), 1024);\n            end;\n          end;\n        SQLT_VST:\n          begin\n            {$IFDEF WITH_STRLCOPY_DEPRECATED}AnsiStrings.{$ENDIF}StrLCopy(PAnsiChar(CurrentVar.Data), PAnsiChar(UTF8Encode(DefVarManager.GetAsUnicodeString(Values[I]))), 1024);\n          end;\n        SQLT_TIMESTAMP:\n          begin\n            TempDate := DefVarManager.GetAsDateTime(Values[I]);\n            DecodeDate(TempDate, Year, Month, Day);\n            DecodeTime(TempDate, Hour, Min, Sec, MSec);\n            Status := PlainDriver.DateTimeConstruct(\n              OracleConnection.GetConnectionHandle,\n              ErrorHandle, PPOCIDescriptor(CurrentVar.Data)^,\n              Year, Month, Day, Hour, Min, Sec, MSec * 1000000, nil, 0);\n            CheckOracleError(PlainDriver, ErrorHandle, Status, lcOther, '');\n          end;\n        SQLT_BLOB, SQLT_CLOB:\n          begin\n            if Values[I].VType = vtBytes then\n            begin\n              TempBytes := DefVarManager.GetAsBytes(Values[I]);\n              Len := Length(TempBytes);\n              TempStream := TMemoryStream.Create;\n              TempStream.Size := Len;\n              System.Move(Pointer(TempBytes)^, TMemoryStream(TempStream).Memory^, Len);\n            end\n            else\n            begin\n              TempBlob := DefVarManager.GetAsInterface(Values[I]) as IZBlob;\n              if not TempBlob.IsEmpty then\n              begin\n                if (CurrentVar.TypeCode = SQLT_CLOB) then\n                  TempStream := TStringStream.Create(GetValidatedAnsiStringFromBuffer(TempBlob.GetBuffer,\n                      TempBlob.Length, TempBlob.WasDecoded, Connection.GetConSettings))\n                else\n                  TempStream := TempBlob.GetStream;\n              end\n              else TempStream := TMemoryStream.Create;\n            end;\n            try\n              WriteTempBlob := TZOracleBlob.Create(PlainDriver,\n                TMemoryStream(TempStream).Memory, TempStream.Size, Connection, PPOCIDescriptor(CurrentVar.Data)^,\n                CurrentVar.ColType, ChunkSize);\n              WriteTempBlob.CreateBlob;\n              WriteTempBlob.WriteBlob;\n              CurrentVar.Blob := WriteTempBlob;\n            finally\n              WriteTempBlob := nil;\n              TempStream.Free;\n            end;\n          end;\n      end;\n    end;\n  end;\nend;\n\n{**\n  Unloads Oracle variables binded to SQL statement with data.\n  @param Variables Oracle variable holders.\n}\nprocedure UnloadOracleVars(Variables: PZSQLVars);\nvar\n  I: Integer;\n  CurrentVar: PZSQLVar;\nbegin\n  for I := 1 to Variables.ActualNum do\n  begin\n    CurrentVar := @Variables.Variables[I];\n    CurrentVar.Blob := nil;\n    CurrentVar.Data := CurrentVar.DupData;\n  end;\nend;\n\n{**\n  Convert string Oracle field type to SQLType\n  @param string field type value\n  @result the SQLType field type value\n}\nfunction ConvertOracleTypeToSQLType(TypeName: string;\n  Precision, Scale: Integer; const CtrlsCPType: TZControlsCodePage): TZSQLType;\nbegin\n  TypeName := UpperCase(TypeName);\n  Result := stUnknown;\n\n  if (TypeName = 'CHAR') or (TypeName = 'VARCHAR2') then\n    Result := stString\n  else if (TypeName = 'NCHAR') or (TypeName = 'NVARCHAR2') then\n    Result := stString\n  else if (TypeName = 'FLOAT') or (TypeName = 'BINARY_FLOAT') or (TypeName = 'BINARY_DOUBLE') then\n    Result := stDouble\n  else if TypeName = 'DATE' then  {precission - 1 sec, so Timestamp}\n    Result := stTimestamp\n  else if TypeName = 'BLOB' then\n    Result := stBinaryStream\n  else if (TypeName = 'RAW') then\n    Result := stBytes\n  else if (TypeName = 'LONG RAW') then\n    Result := stBinaryStream\n  else if TypeName = 'CLOB' then\n    Result := stAsciiStream\n  else if TypeName = 'NCLOB' then\n    Result := stAsciiStream\n  else if TypeName = 'LONG' then\n    Result := stAsciiStream\n  else if StartsWith(TypeName, 'TIMESTAMP') then\n    Result := stTimestamp\n  else if TypeName = 'BFILE' then\n    Result := stBinaryStream else\n  if TypeName = 'NUMBER' then\n  begin\n    Result := stDouble;  { default for number types}\n    if (Scale = 0) and (Precision <> 0) then\n    begin\n      if Precision <= 2 then\n        Result := stByte\n      else if Precision <= 4 then\n        Result := stShort\n      else if Precision <= 9 then\n        Result := stInteger\n      else if Precision <= 19 then\n        Result := stLong  {!!in fact, unusable}\n    end;\n  end;\n  if ( CtrlsCPType = cCP_UTF16 ) then\n    case result of\n      stString: Result := stUnicodeString;\n      stAsciiStream: if not (TypeName = 'LONG') then Result := stUnicodeStream; //fix: http://zeos.firmos.at/viewtopic.php?t=3530\n    end;\nend;\n\n{**\n  Converts Oracle internal date into TDateTime\n  @param Value a pointer to Oracle internal date.\n  @return a decoded TDateTime value.\n}\nfunction OraDateToDateTime(Value: PAnsiChar): TDateTime;\ntype\n  TOraDate = array[1..7] of Byte;\n  POraDate = ^TOraDate;\nvar\n  Ptr: POraDate;\nbegin\n  Ptr := POraDate(Value);\n  Result := EncodeDate((Ptr[1] - 100) * 100 + Ptr[2] - 100, Ptr[3], Ptr[4]) +\n    EncodeTime(Ptr[5]-1, Ptr[6]-1, Ptr[7]-1, 0);\nend;\n\n{**\n  Checks for possible SQL errors.\n  @param PlainDriver an Oracle plain driver.\n  @param Handle an Oracle error handle.\n  @param Status a command return status.\n  @param LogCategory a logging category.\n  @param LogMessage a logging message.\n}\nprocedure CheckOracleError(PlainDriver: IZOraclePlainDriver;\n  ErrorHandle: POCIError; Status: Integer; LogCategory: TZLoggingCategory;\n  LogMessage: string);\nvar\n  ErrorMessage: string;\n  ErrorBuffer: array[0..255] of AnsiChar;\n  ErrorCode: SB4;\nbegin\n  ErrorMessage := '';\n  ErrorCode := Status;\n\n  case Status of\n    OCI_SUCCESS:\n      Exit;\n    OCI_SUCCESS_WITH_INFO:\n      begin\n        PlainDriver.ErrorGet(ErrorHandle, 1, nil, ErrorCode, ErrorBuffer, 255,\n          OCI_HTYPE_ERROR);\n        ErrorMessage := 'OCI_SUCCESS_WITH_INFO: ' + String(ErrorBuffer);\n      end;\n    OCI_NEED_DATA:\n      ErrorMessage := 'OCI_NEED_DATA';\n    OCI_NO_DATA:\n      ErrorMessage := 'OCI_NO_DATA';\n    OCI_ERROR:\n      begin\n        PlainDriver.ErrorGet(ErrorHandle, 1, nil, ErrorCode, ErrorBuffer, 255,\n          OCI_HTYPE_ERROR);\n        ErrorMessage := 'OCI_ERROR: ' + String(ErrorBuffer);\n      end;\n    OCI_INVALID_HANDLE:\n      ErrorMessage := 'OCI_INVALID_HANDLE';\n    OCI_STILL_EXECUTING:\n      ErrorMessage := 'OCI_STILL_EXECUTING';\n    OCI_CONTINUE:\n      ErrorMessage := 'OCI_CONTINUE';\n  end;\n\n  if (Status <> OCI_SUCCESS) and (Status <> OCI_SUCCESS_WITH_INFO) and (ErrorMessage <> '') then\n  begin\n    if Assigned(DriverManager) then //Thread-Safe patch\n      DriverManager.LogError(LogCategory, PlainDriver.GetProtocol, LogMessage,\n        ErrorCode, ErrorMessage);\n    if not ( ( LogCategory = lcDisconnect ) and ( ErrorCode = 3314 ) ) then //patch for disconnected Server\n      //on the other hand we can't close the connction  MantisBT: #0000227\n      raise EZSQLException.CreateWithCode(ErrorCode,\n        Format(SSQLError1, [ErrorMessage]));\n  end;\n  if (Status = OCI_SUCCESS_WITH_INFO) and (ErrorMessage <> '') then\n    if Assigned(DriverManager) then //Thread-Safe patch\n      DriverManager.LogMessage(LogCategory, PlainDriver.GetProtocol, ErrorMessage);\nend;\n\n{**\n  Creates an Oracle result set based on the current settings.\n  @return a created result set object.\n}\nfunction CreateOracleResultSet(PlainDriver: IZOraclePlainDriver;\n  Statement: IZStatement; LogSQL: string; Handle: POCIStmt;\n  ErrorHandle: POCIError): IZResultSet;\nvar\n  NativeResultSet: TZOracleResultSet;\n  CachedResultSet: TZCachedResultSet;\nbegin\n  NativeResultSet := TZOracleResultSet.Create(PlainDriver, Statement,\n    LogSQL, Handle, ErrorHandle);\n  NativeResultSet.SetConcurrency(rcReadOnly);\n  if (Statement.GetResultSetConcurrency = rcUpdatable)\n    or (Statement.GetResultSetType <> rtForwardOnly) then\n  begin\n    CachedResultSet := TZCachedResultSet.Create(NativeResultSet, LogSQL, nil,\n      Statement.GetConnection.GetConSettings);\n    CachedResultSet.SetConcurrency(rcUpdatable);\n    CachedResultSet.SetResolver(TZOracleCachedResolver.Create(\n      Statement, NativeResultSet.GetMetadata));\n    Result := CachedResultSet;\n  end\n  else\n    Result := NativeResultSet;\nend;\n\n{**\n  Creates an Oracle result set based on the current settings.\n  @return a created result set object.\n}\nfunction CreateOracleResultSet(PlainDriver: IZOraclePlainDriver;\n      Statement: IZStatement; LogSQL: string; StmtHandle: POCIStmt;\n      ErrorHandle: POCIError; OutVars: PZSQLVars;\n      Const OracleParams: TZOracleParams): IZResultSet;\nvar\n  NativeResultSet: TZOracleCallableResultSet;\n  CachedResultSet: TZCachedResultSet;\nbegin\n  NativeResultSet := TZOracleCallableResultSet.Create(PlainDriver, Statement,\n    LogSQL, StmtHandle, ErrorHandle, OutVars, OracleParams);\n  NativeResultSet.SetConcurrency(rcReadOnly);\n  CachedResultSet := TZCachedResultSet.Create(NativeResultSet, LogSQL, nil,\n    Statement.GetConnection.GetConSettings);\n  CachedResultSet.SetConcurrency(rcReadOnly);\n  CachedResultSet.SetResolver(TZOracleCachedResolver.Create(\n    Statement, NativeResultSet.GetMetadata));\n  CachedResultSet.Last;\n  CachedResultSet.BeforeFirst;\n  Result := CachedResultSet;\nend;\n\n{**\n  Allocates in memory Oracle handlers for Statement object.\n  @param PlainDriver an Oracle plain driver.\n  @param Connection an Oracle connection object.\n  @param Handle a holder for Statement handle.\n  @param ErrorHandle a holder for Error handle.\n}\nprocedure AllocateOracleStatementHandles(PlainDriver: IZOraclePlainDriver;\n  Connection: IZConnection; var Handle: POCIStmt; var ErrorHandle: POCIError);\nvar\n  OracleConnection: IZOracleConnection;\nbegin\n  OracleConnection := Connection as IZOracleConnection;\n  ErrorHandle := nil;\n  PlainDriver.HandleAlloc(OracleConnection.GetConnectionHandle,\n    ErrorHandle, OCI_HTYPE_ERROR, 0, nil);\n  Handle := nil;\n  PlainDriver.HandleAlloc(OracleConnection.GetConnectionHandle,\n    Handle, OCI_HTYPE_STMT, 0, nil);\nend;\n\n{**\n  Frees from memory Oracle handlers for Statement object.\n  @param PlainDriver an Oracle plain driver.\n  @param Handle a holder for Statement handle.\n  @param ErrorHandle a holder for Error handle.\n}\nprocedure FreeOracleStatementHandles(PlainDriver: IZOraclePlainDriver;\n  var Handle: POCIStmt; var ErrorHandle: POCIError);\nbegin\n  if ErrorHandle <> nil then\n  begin\n    PlainDriver.HandleFree(ErrorHandle, OCI_HTYPE_ERROR);\n    ErrorHandle := nil;\n  end;\n  if Handle <> nil then\n  begin\n    PlainDriver.HandleFree(Handle, OCI_HTYPE_STMT);\n    Handle := nil;\n  end;\nend;\n\n{**\n  Prepares an Oracle statement.\n  @param PlainDriver an Oracle plain driver.\n  @param SQL an SQL query to be prepared.\n  @param Handle a holder for Statement handle.\n  @param ErrorHandle a holder for Error handle.\n}\nprocedure PrepareOracleStatement(PlainDriver: IZOraclePlainDriver;\n  SQL: RawByteString; LogSQL: String; Handle: POCIStmt;\n  ErrorHandle: POCIError; PrefetchCount: ub4; ConSettings: PZConSettings);\nvar\n  Status: Integer;\nbegin\n  PlainDriver.AttrSet(Handle, OCI_HTYPE_STMT, @PrefetchCount, SizeOf(ub4),\n    OCI_ATTR_PREFETCH_ROWS, ErrorHandle);\n  Status := PlainDriver.StmtPrepare(Handle, ErrorHandle, PAnsiChar(SQL),\n    Length(SQL)+1, OCI_NTV_SYNTAX, OCI_DEFAULT);\n  CheckOracleError(PlainDriver, ErrorHandle, Status, lcExecute, LogSQL);\nend;\n\n{**\n  Executes an Oracle statement.\n  @param PlainDriver an Oracle plain driver.\n  @param Connection an Oracle connection Object.\n  @param SQL an SQL query to be prepared.\n  @param Handle a holder for Statement handle.\n  @param ErrorHandle a holder for Error handle.\n}\nprocedure ExecuteOracleStatement(PlainDriver: IZOraclePlainDriver;\n  Connection: IZConnection; LogSQL: string; Handle: POCIStmt; ErrorHandle: POCIError);\nvar\n  Status: Integer;\n  OracleConnection: IZOracleConnection;\nbegin\n  OracleConnection := Connection as IZOracleConnection;\n  Status := PlainDriver.StmtExecute(OracleConnection.GetContextHandle,\n    Handle, ErrorHandle, 1, 0, nil, nil, OCI_DEFAULT);\n  CheckOracleError(PlainDriver, ErrorHandle, Status, lcExecute, LogSQL);\nend;\n\n{**\n  Gets a number of updates made by executed Oracle statement.\n  @param PlainDriver an Oracle plain driver.\n  @param Handle a holder for Statement handle.\n  @param ErrorHandle a holder for Error handle.\n  @returns a number of updates.\n}\nfunction GetOracleUpdateCount(PlainDriver: IZOraclePlainDriver;\n  Handle: POCIStmt; ErrorHandle: POCIError): ub4;\nbegin\n  Result := 0;\n  PlainDriver.AttrGet(Handle, OCI_HTYPE_STMT, @Result, nil,\n    OCI_ATTR_ROW_COUNT, ErrorHandle);\nend;\n\n{**\n  recurses down the field's TDOs and saves the little bits it need for later\n  use on a fetch SQLVar._obj\n}\nfunction DescribeObject(PlainDriver: IZOraclePlainDriver; Connection: IZConnection;\n  ParamHandle: POCIParam; stmt_handle: POCIHandle; Level: ub2): POCIObject;\nvar\n  type_ref: POCIRef;\n\n  function AllocateObject: POCIObject;\n  begin\n    Result := New(POCIObject);\n    FillChar(Result^, SizeOf(TOCIObject), 0);\n  end;\n\n  procedure DescribeObjectByTDO(PlainDriver: IZOraclePlainDriver;\n    Connection: IZConnection; var obj: POCIObject);\n  var\n    FConnection: IZOracleConnection;\n    list_attibutes: POCIParam;\n    name: PAnsiChar;\n    temp: RawByteString;\n    len: ub4;\n    I: ub2;\n    Fld: POCIObject;\n  begin\n    FConnection := Connection as IZOracleConnection;\n\n    CheckOracleError(PlainDriver, FConnection.GetErrorHandle,\n      PlainDriver.DescribeAny(FConnection.GetContextHandle,\n        FConnection.GetErrorHandle, obj.tdo, 0, OCI_OTYPE_PTR, OCI_DEFAULT,\n        OCI_PTYPE_TYPE, FConnection.GetDescribeHandle),\n      lcOther, 'OCIDescribeAny(OCI_PTYPE_TYPE) of OCI_OTYPE_PTR');\n\n    //we have the Actual TDO  so lets see what it is made up of by a describe\n    Len := 0;  //and we store it in the object's paramdp for now\n    CheckOracleError(PlainDriver, FConnection.GetErrorHandle,\n      PlainDriver.AttrGet(FConnection.GetDescribeHandle, OCI_HTYPE_DESCRIBE,\n        @obj.parmdp, @Len, OCI_ATTR_PARAM, FConnection.GetErrorHandle),\n      lcOther, 'OCIAttrGet(OCI_HTYPE_DESCRIBE) of OCI_ATTR_PARAM');\n\n    //Get the SchemaName of the Object\n    CheckOracleError(PlainDriver, FConnection.GetErrorHandle,\n      PlainDriver.AttrGet(obj.parmdp, OCI_DTYPE_PARAM,\n        @name, @len, OCI_ATTR_SCHEMA_NAME, FConnection.GetErrorHandle),\n      lcOther, 'OCIAttrGet(OCI_ATTR_SCHEMA_NAME) of OCI_DTYPE_PARAM');\n\n    SetLength(temp, len+1);\n    temp := {$IFDEF WITH_STRPLCOPY_DEPRECATED}AnsiStrings.{$ENDIF}StrPLCopy(PAnsiChar(temp), name, len);\n    Obj.type_schema := PlainDriver.ZDbcString(temp, Connection.GetConSettings);\n\n    //Get the TypeName of the Object\n    CheckOracleError(PlainDriver, FConnection.GetErrorHandle,\n      PlainDriver.AttrGet(obj.parmdp, OCI_DTYPE_PARAM,\n        @name, @len, OCI_ATTR_NAME, FConnection.GetErrorHandle),\n      lcOther, 'OCIAttrGet(OCI_ATTR_NAME) of OCI_DTYPE_PARAM');\n\n    SetLength(temp, len+1);\n    temp := {$IFDEF WITH_STRPLCOPY_DEPRECATED}AnsiStrings.{$ENDIF}StrPLCopy(PAnsiChar(temp), name, len);\n    Obj.type_name := PlainDriver.ZDbcString(temp, Connection.GetConSettings);\n\n    //Get the TypeCode of the Object\n    CheckOracleError(PlainDriver, FConnection.GetErrorHandle,\n      PlainDriver.AttrGet(obj.parmdp, OCI_DTYPE_PARAM,\n        @Obj.typecode, nil, OCI_ATTR_TYPECODE, FConnection.GetErrorHandle),\n      lcOther, 'OCIAttrGet(OCI_ATTR_TYPECODE) of OCI_DTYPE_PARAM');\n\n    if (obj.typecode = OCI_TYPECODE_OBJECT ) or ( obj.typecode = OCI_TYPECODE_OPAQUE) then\n    begin\n      //we will need a reff to the TDO for the pin operation\n      CheckOracleError(PlainDriver, FConnection.GetErrorHandle,\n        PlainDriver.AttrGet(obj.parmdp, OCI_DTYPE_PARAM,\n          @Obj.obj_ref, nil, OCI_ATTR_REF_TDO, FConnection.GetErrorHandle),\n        lcOther, 'OCIAttrGet(OCI_ATTR_REF_TDO) of OCI_DTYPE_PARAM');\n\n      //now we'll pin the object\n      CheckOracleError(PlainDriver, FConnection.GetErrorHandle,\n        PlainDriver.ObjectPin(FConnection.GetConnectionHandle, FConnection.GetErrorHandle,\n          Obj.obj_ref, nil, OCI_PIN_LATEST, OCI_DURATION_SESSION, pub2(OCI_LOCK_NONE),\n          @obj.obj_type),\n        lcOther, 'OCIObjectPin(OCI_PIN_LATEST, OCI_DURATION_SESSION, OCI_LOCK_NONE)');\n      Obj.Pinned := True;\n\n      //is the object the final type or an type-descriptor?\n      CheckOracleError(PlainDriver, FConnection.GetErrorHandle,\n        PlainDriver.AttrGet(obj.parmdp, OCI_DTYPE_PARAM,\n          @Obj.is_final_type, nil, OCI_ATTR_IS_FINAL_TYPE, FConnection.GetErrorHandle),\n        lcOther, 'OCIAttrGet(OCI_ATTR_IS_FINAL_TYPE) of OCI_DTYPE_PARAM(SubType)');\n\n      //Get the FieldCount\n      CheckOracleError(PlainDriver, FConnection.GetErrorHandle,\n        PlainDriver.AttrGet(obj.parmdp, OCI_DTYPE_PARAM,\n          @Obj.field_count, nil, OCI_ATTR_NUM_TYPE_ATTRS, FConnection.GetErrorHandle),\n        lcOther, 'OCIAttrGet(OCI_ATTR_NUM_TYPE_ATTRS) of OCI_DTYPE_PARAM(SubType)');\n\n      //now get the differnt fields of this object add one field object for property\n      SetLength(Obj.fields, Obj.field_count);\n\n      //a field is just another instance of an obj not a new struct\n      CheckOracleError(PlainDriver, FConnection.GetErrorHandle,\n        PlainDriver.AttrGet(obj.parmdp, OCI_DTYPE_PARAM,\n          @list_attibutes, nil, OCI_ATTR_LIST_TYPE_ATTRS, FConnection.GetErrorHandle),\n        lcOther, 'OCIAttrGet(OCI_ATTR_LIST_TYPE_ATTRS) of OCI_DTYPE_PARAM(SubType)');\n\n      if obj.field_count > 0 then\n      for I := 0 to obj.field_count-1 do\n      begin\n        Fld := AllocateObject;  //allocate a new object\n          Obj.fields[i] := Fld;  //assign the object to the field-list\n\n        CheckOracleError(PlainDriver, FConnection.GetErrorHandle,\n          PlainDriver.ParamGet(list_attibutes, OCI_DTYPE_PARAM,\n            FConnection.GetErrorHandle, Fld.parmdp, I+1),\n          lcOther, 'OCIParamGet(OCI_DTYPE_PARAM) of OCI_DTYPE_PARAM(Element)');\n\n        // get the name of the attribute\n        len := 0;\n        CheckOracleError(PlainDriver, FConnection.GetErrorHandle,\n          PlainDriver.AttrGet(Fld.parmdp, OCI_DTYPE_PARAM,\n            @name, @len, OCI_ATTR_NAME, FConnection.GetErrorHandle),\n          lcOther, 'OCIAttrGet(OCI_ATTR_NAME) of OCI_DTYPE_PARAM(Element)');\n\n        SetLength(temp, len+1);\n        temp := {$IFDEF WITH_STRPLCOPY_DEPRECATED}AnsiStrings.{$ENDIF}StrPLCopy(PAnsiChar(temp), name, len);\n        Fld.type_name := PlainDriver.ZDbcString(temp, Connection.GetConSettings);\n\n        // get the typeCode of the attribute\n        CheckOracleError(PlainDriver, FConnection.GetErrorHandle,\n          PlainDriver.AttrGet(Fld.parmdp, OCI_DTYPE_PARAM,\n            @Fld.typecode, nil, OCI_ATTR_TYPECODE, FConnection.GetErrorHandle),\n          lcOther, 'OCIAttrGet(OCI_ATTR_TYPECODE) of OCI_DTYPE_PARAM(Element)');\n\n        if (fld.typecode = OCI_TYPECODE_OBJECT) or\n           (fld.typecode = OCI_TYPECODE_VARRAY) or\n           (fld.typecode = OCI_TYPECODE_TABLE) or\n           (fld.typecode = OCI_TYPECODE_NAMEDCOLLECTION) then\n          //this is some sort of object or collection so lets drill down some more\n          fld.next_subtype := DescribeObject(PlainDriver, Connection, fld.parmdp,\n              obj.stmt_handle, obj.Level+1);\n      end;\n    end\n    else\n    begin\n      //this is an embedded table or varray of some form so find out what is in it*/\n\n      CheckOracleError(PlainDriver, FConnection.GetErrorHandle,\n        PlainDriver.AttrGet(obj.parmdp, OCI_DTYPE_PARAM,\n          @obj.col_typecode, nil, OCI_ATTR_COLLECTION_TYPECODE, FConnection.GetErrorHandle),\n        lcOther, 'OCIAttrGet(OCI_ATTR_COLLECTION_TYPECODE) of OCI_DTYPE_PARAM');\n\n      //first get what sort of collection it is by coll typecode\n      CheckOracleError(PlainDriver, FConnection.GetErrorHandle,\n        PlainDriver.AttrGet(obj.parmdp, OCI_DTYPE_PARAM,\n          @obj.parmap, nil, OCI_ATTR_COLLECTION_ELEMENT, FConnection.GetErrorHandle),\n        lcOther, 'OCIAttrGet(OCI_ATTR_COLLECTION_ELEMENT) of OCI_DTYPE_PARAM');\n\n      CheckOracleError(PlainDriver, FConnection.GetErrorHandle,\n        PlainDriver.AttrGet(obj.parmdp, OCI_DTYPE_PARAM,\n          @obj.elem_typecode, nil, OCI_ATTR_TYPECODE, FConnection.GetErrorHandle),\n        lcOther, 'OCIAttrGet(OCI_ATTR_TYPECODE of Element) of OCI_DTYPE_PARAM');\n\n      if (obj.elem_typecode = OCI_TYPECODE_OBJECT) or\n         (obj.elem_typecode = OCI_TYPECODE_VARRAY) or\n         (obj.elem_typecode = OCI_TYPECODE_TABLE) or\n         (obj.elem_typecode = OCI_TYPECODE_NAMEDCOLLECTION) then\n        //this is some sort of object or collection so lets drill down some more\n        obj.next_subtype := DescribeObject(PlainDriver, Connection, obj.parmap,\n            obj.stmt_handle, obj.Level+1);\n    end;\n  end;\nbegin\n    Result := AllocateObject;\n\n  //Describe the field (OCIParm) we know it is a object or a collection\n\n  //Get the Actual TDO\n  CheckOracleError(PlainDriver, (Connection as IZOracleConnection).GetErrorHandle,\n    PlainDriver.AttrGet(ParamHandle, OCI_DTYPE_PARAM, @type_ref, nil,\n      OCI_ATTR_REF_TDO, (Connection as IZOracleConnection).GetErrorHandle),\n    lcOther, 'OCIAttrGet OCI_ATTR_REF_TDO of OCI_DTYPE_PARAM');\n\n  CheckOracleError(PlainDriver, (Connection as IZOracleConnection).GetErrorHandle,\n    PlainDriver.TypeByRef((Connection as IZOracleConnection).GetConnectionHandle,\n      (Connection as IZOracleConnection).GetErrorHandle, type_ref,\n      OCI_DURATION_TRANS, OCI_TYPEGET_ALL, @Result.tdo),\n    lcOther, 'OCITypeByRef from OCI_ATTR_REF_TDO');\n  Result^.Level := Level;\n  DescribeObjectByTDO(PlainDriver, Connection, Result);\nend;\n\nend.\n\n"
  },
  {
    "path": "lib/zeosdbo/src/dbc/ZDbcPooled.pas",
    "content": "{*********************************************************}\n{                                                         }\n{                 Zeos Database Objects                   }\n{                                                         }\n{*********************************************************}\n\n{@********************************************************}\n{    Copyright (c) 1999-2012 Zeos Development Group       }\n{                                                         }\n{ License Agreement:                                      }\n{                                                         }\n{ This library is distributed in the hope that it will be }\n{ useful, but WITHOUT ANY WARRANTY; without even the      }\n{ implied warranty of MERCHANTABILITY or FITNESS FOR      }\n{ A PARTICULAR PURPOSE.  See the GNU Lesser General       }\n{ Public License for more details.                        }\n{                                                         }\n{ The source code of the ZEOS Libraries and packages are  }\n{ distributed under the Library GNU General Public        }\n{ License (see the file COPYING / COPYING.ZEOS)           }\n{ with the following  modification:                       }\n{ As a special exception, the copyright holders of this   }\n{ library give you permission to link this library with   }\n{ independent modules to produce an executable,           }\n{ regardless of the license terms of these independent    }\n{ modules, and to copy and distribute the resulting       }\n{ executable under terms of your choice, provided that    }\n{ you also meet, for each linked independent module,      }\n{ the terms and conditions of the license of that module. }\n{ An independent module is a module which is not derived  }\n{ from or based on this library. If you modify this       }\n{ library, you may extend this exception to your version  }\n{ of the library, but you are not obligated to do so.     }\n{ If you do not wish to do so, delete this exception      }\n{ statement from your version.                            }\n{                                                         }\n{                                                         }\n{ The project web site is located on:                     }\n{   http://zeos.firmos.at  (FORUM)                        }\n{   http://sourceforge.net/p/zeoslib/tickets/ (BUGTRACKER)}\n{   svn://svn.code.sf.net/p/zeoslib/code-0/trunk (SVN)    }\n{                                                         }\n{   http://www.sourceforge.net/projects/zeoslib.          }\n{                                                         }\n{                                                         }\n{                                 Zeos Development Group. }\n{********************************************************@}\n\nunit ZDbcPooled;\n\ninterface\n\n{$I ZDbc.inc}\n\nimplementation\n\nuses\n  Classes, {$IFDEF MSEgui}mclasses,{$ENDIF} Contnrs, DateUtils, SysUtils, Types,\n  SyncObjs,\n  ZCompatibility, ZClasses, ZURL, ZDbcConnection, ZDbcIntfs, ZPlainDriver,\n  ZMessages, ZVariant;\n\ntype\n  TConnectionPool = class;\n\n  { This class searchs for timed out connections in a pool and destroy them.\n    Maybe it would be nice to have a global instance to check all pools. This\n    way, we could avoid creating many threads. }\n  TConnectionTimeoutThread = class(TThread)\n  private\n    FConnectionPool: TConnectionPool;\n  protected\n    procedure Execute; override;\n  public\n    constructor Create(const ConnectionPool: TConnectionPool);\n  end;\n\n  { This class keeps a pool of connections which shares the same URL.\n    When a new connection is needed, it looks first if there is an available\n    connection in the pool, and returns it. If there is no connection available,\n    it creates a new one. Each created connection will be returned automatically\n    to the pool when it is not used anymore. }\n  TConnectionPool = class\n  private\n    FConnections: array of IZConnection;\n    FConnectionsReturnTimes: array of TDateTime;\n    FSlotsInUse: TBits;\n    FConnectionTimeout: Integer;\n    FConnectionTimeoutThread: TConnectionTimeoutThread;\n    FCriticalSection: TCriticalSection;\n    FCriticalSectionDriverManager: TCriticalSection;\n    FDefaultAutoCommit: Boolean;\n    FDefaultTransactIsolationLevel: TZTransactIsolationLevel;\n    FMaxConnections: Integer;\n    FURL: string;\n    FWait: Boolean;\n  public\n    { URL\n        The connection URL\n      ConnectionTimeout\n        How many time a pooled connection will be kept in the pool. Zero = infinite\n      MaxConnections\n        The maximum numbers of connections this pool will hold. Zero = infinite\n      Wait\n        True - When a pool reach its maximum number of connections and someone\n               tries to acquire a new one, it waits until a connection is\n               returned to the pool\n        False - Raises an exception instead of wait }\n    constructor Create(const URL: string; const ConnectionTimeout: Integer = 0; const MaxConnections: Integer = 0; const Wait: Boolean = True);\n    destructor Destroy; override;\n    function Acquire: IZConnection;\n    procedure ReturnToPool(const Connection: IZConnection);\n  end;\n\n  { This class embedds a real connection and redirects all methods to it.\n    When it is droped or closed, it returns the real connection to the pool. }\n\n  { TZDbcPooledConnection }\n\n  TZDbcPooledConnection = class(TZCodePagedObject, IZConnection)\n  private\n    FConnection: IZConnection;\n    FConnectionPool: TConnectionPool;\n    FAutoEncodeStrings: Boolean;\n    FUseMetadata: Boolean;\n    {$IFDEF ZEOS_TEST_ONLY}\n    FTestMode: Byte;\n    {$ENDIF}\n    function GetConnection: IZConnection;\n  protected // IZConnection\n    FClientCodePage: String;\n    procedure CheckCharEncoding(CharSet: String;\n      const DoArrange: Boolean = False);\n    function GetClientCodePageInformations: PZCodePage; //EgonHugeist\n    function GetAutoEncodeStrings: Boolean; //EgonHugeist\n    procedure SetAutoEncodeStrings(const Value: Boolean);\n    function CreateStatement: IZStatement;\n    function PrepareStatement(const SQL: string): IZPreparedStatement;\n    function PrepareCall(const SQL: string): IZCallableStatement;\n    function CreateStatementWithParams(Info: TStrings): IZStatement;\n    function PrepareStatementWithParams(const SQL: string; Info: TStrings): IZPreparedStatement;\n    function PrepareCallWithParams(const SQL: string; Info: TStrings): IZCallableStatement;\n    function CreateNotification(const Event: string): IZNotification;\n    function CreateSequence(const Sequence: string; BlockSize: Integer): IZSequence;\n    function NativeSQL(const SQL: string): string;\n    procedure SetAutoCommit(Value: Boolean);\n    function GetAutoCommit: Boolean;\n    procedure Commit;\n    procedure Rollback;\n    procedure PrepareTransaction(const transactionid: string);\n    procedure CommitPrepared(const transactionid: string);\n    procedure RollbackPrepared(const transactionid: string);\n    function PingServer: Integer;\n    function EscapeString(Value : RawByteString) : RawByteString;\n    procedure Open;\n    procedure Close;\n    function IsClosed: Boolean;\n    function GetDriver: IZDriver;\n    function GetIZPlainDriver: IZPlainDriver;\n    function GetMetadata: IZDatabaseMetadata;\n    function GetParameters: TStrings;\n    function GetClientVersion: Integer;\n    function GetHostVersion: Integer;\n    procedure SetReadOnly(Value: Boolean);\n    function IsReadOnly: Boolean;\n    procedure SetCatalog(const Value: string);\n    function GetCatalog: string;\n    procedure SetTransactionIsolation(Value: TZTransactIsolationLevel);\n    function GetTransactionIsolation: TZTransactIsolationLevel;\n    function GetWarnings: EZSQLWarning;\n    procedure ClearWarnings;\n    function UseMetadata: boolean;\n    procedure SetUseMetadata(Value: Boolean);\n  public\n    constructor Create(const ConnectionPool: TConnectionPool);\n    destructor Destroy; override;\n    function GetBinaryEscapeString(const Value: RawByteString): String; overload;\n    function GetBinaryEscapeString(const Value: TByteDynArray): String; overload;\n    function GetEscapeString(const Value: ZWideString): ZWideString; overload; virtual;\n    function GetEscapeString(const Value: RawByteString): RawByteString; overload; virtual;\n    function GetEncoding: TZCharEncoding;\n    function GetConSettings: PZConSettings;\n    {$IFDEF ZEOS_TEST_ONLY}\n    function GetTestMode : Byte;\n    procedure SetTestMode(Mode: Byte);\n    {$ENDIF}\n  end;\n\n  {$WARNINGS OFF}\n  TZDbcPooledConnectionDriver = class(TZAbstractDriver)\n  private\n    PoolList: TObjectList;\n    URLList: TStringList;\n    function GetEmbeddedURL(const URL: String): String;\n  public\n    //function GetSupportedProtocols: TStringDynArray; override;\n    function Connect(const URL: TZURL): IZConnection; override;\n    function GetClientVersion(const URL: string): Integer; override;\n    function AcceptsURL(const URL: string): Boolean; override;\n    function GetPropertyInfo(const URL: string; Info: TStrings): TStrings; override;\n    function GetMajorVersion: Integer; override;\n    function GetMinorVersion: Integer; override;\n    function GetSubVersion: Integer; override;\n  public\n    constructor Create; override;\n    destructor Destroy; override;\n  end;\n  {$WARNINGS ON}\n\n{ TConnectionPool }\n\nconstructor TConnectionPool.Create(const URL: string; const ConnectionTimeout: Integer = 0; const MaxConnections: Integer = 0; const Wait: Boolean = True);\nbegin\n  FURL := URL;\n  FWait := Wait;\n\n  FSlotsInUse := TBits.Create;\n  FCriticalSection := TCriticalSection.Create;\n  FCriticalSectionDriverManager := TCriticalSection.Create;\n\n  FMaxConnections := MaxConnections;\n  if FMaxConnections = 0 then\n  begin\n    SetLength(FConnections, 10);\n    SetLength(FConnectionsReturnTimes, 10);\n    FSlotsInUse.Size := 10;\n  end\n  else\n  begin\n    SetLength(FConnections, FMaxConnections);\n    SetLength(FConnectionsReturnTimes, FMaxConnections);\n    FSlotsInUse.Size := FMaxConnections;\n  end;\n\n  //\n  // If there is a connection timeout, an instance of TConnectionTimeoutThread\n  // will monitor all unused connections and drop them when they timeout.\n  //\n  FConnectionTimeout := ConnectionTimeout;\n  if FConnectionTimeout <> 0 then\n    FConnectionTimeoutThread := TConnectionTimeoutThread.Create(Self);\nend;\n\ndestructor TConnectionPool.Destroy;\nbegin\n  if FConnectionTimeoutThread <> nil then\n  begin\n    FConnectionTimeoutThread.Terminate;\n    FConnectionTimeoutThread.WaitFor;\n    FConnectionTimeoutThread.Free;\n  end;\n\n  SetLength(FConnections, 0);\n  FSlotsInUse.Free;\n  FCriticalSection.Free;\n  FCriticalSectionDriverManager.Free;\n\n  inherited;\nend;\n\nfunction TConnectionPool.Acquire: IZConnection;\nvar\n  I: Integer;\nbegin\n  Result := nil;\n  I := 0;\n\n  while True do\n  begin\n    FCriticalSection.Enter;\n    try\n      // Try to get an existing connection\n      I := 0;\n      while I < FSlotsInUse.Size do\n      begin\n        if (FConnections[I] <> nil) and (not FSlotsInUse[I]) then\n        begin\n          try\n            // Test for dead connections\n            FConnections[I].Rollback; // PingServer did not work (tested with FB)\n            FSlotsInUse[I] := True;\n            Break;\n          except\n            // An exception can be raised when the dead connection is dropped\n            try\n              FConnections[I] := nil;\n            except\n            end;\n            Inc(I);\n          end;\n    end\n    else\n          Inc(I);\n      end;\n\n      // Try to get a free slot if there is no existing connection available\n      if I = FSlotsInUse.Size then\n      begin\n        I := 0;\n        while I < FSlotsInUse.Size do\n        begin\n          if (FConnections[I] = nil) and (not FSlotsInUse[I]) then\n          begin\n            FSlotsInUse[I] := True;\n            Break;\n          end;\n          Inc(I);\n        end;\n      end;\n\n      // Increase the pool if there is no free slot in the pool\n      if I = FSlotsInUse.Size then\n    begin\n      if FMaxConnections = 0 then\n      begin\n        SetLength(FConnections, Length(FConnections) + 10);\n        SetLength(FConnectionsReturnTimes, Length(FConnectionsReturnTimes) + 10);\n          FSlotsInUse.Size := FSlotsInUse.Size + 10;\n          FSlotsInUse[I] := True;\n        end;\n    end;\n  finally\n      FCriticalSection.Leave;\n    end;\n\n    if I < FSlotsInUse.Size then\n      Break;\n\n    // No connection available. Wait and try again later\n    if FWait then\n      Sleep(100)\n    else\n      raise Exception.Create(ClassName + '.Acquire'+LineEnding+'O pool de conexatingiu o limite maximo');\n            //2013-10-13 mse: please replace non ASCII characters (>127) by the \n            //#nnn notation in order to have encoding independent sources\n  end;\n\n  //\n  // If there is no connection in the pool, create a new one.\n  // This block is separated from the block above because there could be some\n  // delay to create a connection, and it would not be nice to keep the critical\n  // section locked during this delay.\n  //\n  if FConnections[I] = nil then\n  begin\n    try\n      // I had a strong feeling that DriverManager is not thread-safe, because i\n      // had random access violations on high load operations at this point.\n      // For now, i will serialize DriverManager access, until further\n      // investigation (maybe the problem is in the pool driver, as\n      // DriverManager should be thread-safe in essence.\n      FCriticalSectionDriverManager.Enter;\n      try\n        FConnections[I] := DriverManager.GetConnection(FURL);\n      finally\n        FCriticalSectionDriverManager.Leave;\n      end;\n      FConnections[I].Open;\n    except\n      on E: Exception do\n      begin\n        FCriticalSection.Enter;\n        try\n          FSlotsInUse[I] := False;\n          FConnections[I] := nil;\n        finally\n          FCriticalSection.Leave;\n          raise Exception.Create(ClassName + '.Acquire'+LineEnding+'Error while trying to acquire a new connection'+LineEnding+LineEnding+E.Message);\n        end;\n      end;\n    end;\n    FDefaultAutoCommit := FConnections[I].GetAutoCommit;\n    FDefaultTransactIsolationLevel := FConnections[I].GetTransactionIsolation;\n  end;\n\n  Result := IZConnection(FConnections[I]);\n  Result.SetAutoCommit(True);\n  Result.SetTransactionIsolation(tiReadCommitted);\nend;\n\nprocedure TConnectionPool.ReturnToPool(const Connection: IZConnection);\nvar\n  I: Integer;\nbegin\n  //\n  // Return the connection to the pool.\n  //\n  FCriticalSection.Enter;\n  try\n    for I := 0 to Length(FConnections) - 1 do\n    begin\n      if FConnections[I] = Connection then\n      begin\n        //\n        // If there is some problem with the connection, a RollBack will raise\n        // an exception, and the connection will be dropped.\n        //\n        try\n          FSlotsInUse[I] := False;\n        FConnectionsReturnTimes[I] := Now;\n          FConnections[I].Rollback;\n        except\n          try\n            FConnections[I] := nil;\n          except\n          end;\n        end;\n        Break;\n      end;\n    end;\n  finally\n    FCriticalSection.Leave;\n  end;\nend;\n\n{ TZDbcPooledConnection }\n\nconstructor TZDbcPooledConnection.Create(const ConnectionPool: TConnectionPool);\nbegin\n  FConnectionPool := ConnectionPool;\n  {$IFDEF ZEOS_TEST_ONLY}\n  FTestMode := 0;\n  {$ENDIF}\nend;\n\ndestructor TZDbcPooledConnection.Destroy;\nbegin\n  if FConnection <> nil then\n  begin\n    FConnectionPool.ReturnToPool(FConnection);\n    FConnection := nil;\n  end;\n\n  FConnectionPool := nil;\n\n  inherited;\nend;\n\nfunction TZDbcPooledConnection.GetConnection: IZConnection;\nbegin\n  if FConnection = nil then\n    FConnection := FConnectionPool.Acquire;\n  Result := FConnection;\nend;\n\nprocedure TZDbcPooledConnection.ClearWarnings;\nbegin\n  GetConnection.ClearWarnings;\nend;\n\nfunction TZDbcPooledConnection.UseMetadata: boolean;\nbegin\n  result := FUseMetadata;\nend;\n\nprocedure TZDbcPooledConnection.SetUseMetadata(Value: Boolean);\nbegin\n  FUseMetadata := Value;\nend;\n\nprocedure TZDbcPooledConnection.Close;\nbegin\n  if FConnection <> nil then\n  begin\n    FConnectionPool.ReturnToPool(FConnection);\n    FConnection := nil;\n  end;\nend;\n\nprocedure TZDbcPooledConnection.Commit;\nbegin\n  GetConnection.Commit;\nend;\n\nprocedure TZDbcPooledConnection.CommitPrepared(const transactionid: string);\nbegin\n  GetConnection.CommitPrepared(transactionid);\nend;\n\nfunction TZDbcPooledConnection.CreateNotification(const Event: string): IZNotification;\nbegin\n  Result := GetConnection.CreateNotification(Event);\nend;\n\nfunction TZDbcPooledConnection.CreateSequence(const Sequence: string; BlockSize: Integer): IZSequence;\nbegin\n  Result := GetConnection.CreateSequence(Sequence, BlockSize);\nend;\n\nfunction TZDbcPooledConnection.CreateStatement: IZStatement;\nbegin\n  Result := GetConnection.CreateStatement;\nend;\n\n\nfunction TZDbcPooledConnection.CreateStatementWithParams(Info: TStrings): IZStatement;\nbegin\n  Result := GetConnection.CreateStatementWithParams(Info);\nend;\n\nfunction TZDbcPooledConnection.EscapeString(Value: RawByteString): RawByteString;\nbegin\n  Result := GetConnection.EscapeString(Value);\nend;\n\nfunction TZDbcPooledConnection.GetAutoCommit: Boolean;\nbegin\n  Result := GetConnection.GetAutoCommit;  \nend;\n\nfunction TZDbcPooledConnection.GetCatalog: string;\nbegin\n  Result := GetConnection.GetCatalog;\nend;\n\nfunction TZDbcPooledConnection.GetClientVersion: Integer;\nbegin\n  Result := GetConnection.GetClientVersion;\nend;\n\nfunction TZDbcPooledConnection.GetDriver: IZDriver;\nbegin\n  Result := GetConnection.GetDriver;\nend;\n\nfunction TZDbcPooledConnection.GetIZPlainDriver: IZPlainDriver;\nbegin\n  Result := GetConnection.GetIZPlainDriver;\nend;\n\nfunction TZDbcPooledConnection.GetHostVersion: Integer;\nbegin\n  Result := GetConnection.GetHostVersion;\nend;\n\nfunction TZDbcPooledConnection.GetMetadata: IZDatabaseMetadata;\nbegin\n  Result := GetConnection.GetMetadata;\nend;\n\nfunction TZDbcPooledConnection.GetParameters: TStrings;\nbegin\n  Result := GetConnection.GetParameters;\nend;\n\nfunction TZDbcPooledConnection.GetTransactionIsolation: TZTransactIsolationLevel;\nbegin\n  Result := GetConnection.GetTransactionIsolation;  \nend;\n\nfunction TZDbcPooledConnection.GetWarnings: EZSQLWarning;\nbegin\n  Result := GetConnection.GetWarnings;\nend;\n\nfunction TZDbcPooledConnection.IsClosed: Boolean;\nbegin\n  Result := (FConnection = nil) or FConnection.IsClosed;\nend;\n\nfunction TZDbcPooledConnection.IsReadOnly: Boolean;\nbegin\n  Result := GetConnection.IsReadOnly;\nend;\n\nfunction TZDbcPooledConnection.NativeSQL(const SQL: string): string;\nbegin\n  Result := GetConnection.NativeSQL(SQL);\nend;\n\nprocedure TZDbcPooledConnection.Open;\nbegin\n  GetConnection.Open;\nend;\n\nfunction TZDbcPooledConnection.PingServer: Integer;\nbegin\n  Result := GetConnection.PingServer;\nend;\n\nfunction TZDbcPooledConnection.PrepareCall(const SQL: string): IZCallableStatement;\nbegin\n  Result := GetConnection.PrepareCall(SQL);\nend;\n\nfunction TZDbcPooledConnection.PrepareCallWithParams(const SQL: string; Info: TStrings): IZCallableStatement;\nbegin\n  Result := GetConnection.PrepareCallWithParams(SQL, Info);\nend;\n\nfunction TZDbcPooledConnection.PrepareStatement(const SQL: string): IZPreparedStatement;\nbegin\n  Result := GetConnection.PrepareStatement(SQL);\nend;\n\nfunction TZDbcPooledConnection.PrepareStatementWithParams(const SQL: string; Info: TStrings): IZPreparedStatement;\nbegin\n  Result := GetConnection.PrepareStatementWithParams(SQL, Info);\nend;\n\nprocedure TZDbcPooledConnection.PrepareTransaction(const transactionid: string);\nbegin\n  GetConnection.PrepareTransaction(transactionid);\nend;\n\nprocedure TZDbcPooledConnection.Rollback;\nbegin\n  GetConnection.Rollback;\nend;\n\nprocedure TZDbcPooledConnection.RollbackPrepared(const transactionid: string);\nbegin\n  GetConnection.RollbackPrepared(transactionid);\nend;\n\nprocedure TZDbcPooledConnection.SetAutoCommit(Value: Boolean);\nbegin\n  GetConnection.SetAutoCommit(Value);  \nend;\n\nprocedure TZDbcPooledConnection.SetCatalog(const Value: string);\nbegin\n  GetConnection.SetCatalog(Value);\nend;\n\nprocedure TZDbcPooledConnection.SetReadOnly(Value: Boolean);\nbegin\n  GetConnection.SetReadOnly(Value);\nend;\n\nprocedure TZDbcPooledConnection.SetTransactionIsolation(Value: TZTransactIsolationLevel);\nbegin\n  GetConnection.SetTransactionIsolation(Value);\nend;\n\n{**\n  EgonHugeist: Check if the given Charset for Compiler/Database-Support!!\n    Not supported means if there is a pissible String-DataLoss.\n    So it raises an Exception if case of settings. This handling\n    is an improofment to inform Zeos-Users about the troubles the given\n    CharacterSet may have.\n  @param CharSet the CharacterSet which has to be proofed\n  @param DoArrange represents a switch to check and set a aternative ZAlias as\n    default. This means it ignores the choosen Client-CharacterSet and sets a\n    \"more\" Zeos-Compatible Client-CharacterSet if known.\n}\nprocedure TZDbcPooledConnection.CheckCharEncoding(CharSet: String;\n  const DoArrange: Boolean = False);\nbegin\n  Self.GetConSettings.ClientCodePage := GetIZPlainDriver.ValidateCharEncoding(CharSet, DoArrange);\n  FClientCodePage := ConSettings.ClientCodePage^.Name; //resets the developer choosen ClientCodePage\nend;\n\n\n{**\n  EgonHugeist: this is a compatibility-Option for exiting Applictions.\n    Zeos is now able to preprepare direct insered SQL-Statements.\n    Means do the UTF8-preparation if the CharacterSet was choosen.\n    So we do not need to do the SQLString + UTF8Encode(Edit1.Test) for example.\n  @result True if coAutoEncodeStrings was choosen in the TZAbstractConnection\n}\nfunction TZDbcPooledConnection.GetAutoEncodeStrings: Boolean;\nbegin\n  Result := FAutoEncodeStrings;\nend;\n\nprocedure TZDbcPooledConnection.SetAutoEncodeStrings(const Value: Boolean);\nbegin\n  FAutoEncodeStrings := Value;\nend;\n\n{**\n  EgonHugeist:\n  Returns the BinaryString in a Tokenizer-detectable kind\n  If the Tokenizer don't need to predetect it Result = BinaryString\n  @param Value represents the Binary-String\n  @param EscapeMarkSequence represents a Tokenizer detectable EscapeSequence (Len >= 3)\n  @result the detectable Binary String\n}\nfunction TZDbcPooledConnection.GetBinaryEscapeString(const Value: RawByteString): String;\nbegin\n  Result := GetConnection.GetBinaryEscapeString(Value);\nend;\n\nfunction TZDbcPooledConnection.GetBinaryEscapeString(const Value: TByteDynArray): String;\nbegin\n  Result := GetConnection.GetBinaryEscapeString(Value);\nend;\n\nfunction TZDbcPooledConnection.GetEscapeString(const Value: ZWideString): ZWideString;\nbegin\n  Result := GetConnection.GetEscapeString(Value);\nend;\n\nfunction TZDbcPooledConnection.GetEscapeString(const Value: RawByteString): RawByteString;\nbegin\n  Result := GetConnection.GetEscapeString(Value);\nend;\n\nfunction TZDbcPooledConnection.GetEncoding: TZCharEncoding;\nbegin\n  Result := ConSettings.ClientCodePage^.Encoding;\nend;\n\nfunction TZDbcPooledConnection.GetConSettings: PZConSettings;\nbegin\n  Result := @ConSettings;\nend;\n\n{$IFDEF ZEOS_TEST_ONLY}\nfunction TZDbcPooledConnection.GetTestMode: Byte;\nbegin\n  Result := FTestMode;\nend;\n\nprocedure TZDbcPooledConnection.SetTestMode(Mode: Byte);\nbegin\n  FTestMode := Mode;\nend;\n{$ENDIF}\n\n{**\n  Result 100% Compiler-Compatible\n  And sets it Result to ClientCodePage by calling the\n    PlainDriver.GetClientCodePageInformations function\n\n  @param ClientCharacterSet the CharacterSet which has to be checked\n  @result PZCodePage see ZCompatible.pas\n}\nfunction TZDbcPooledConnection.GetClientCodePageInformations: PZCodePage; //EgonHugeist\nbegin\n  Result := ConSettings.ClientCodePage\nend;\n\n{ TZDbcPooledConnectionDriver }\n\nconstructor TZDbcPooledConnectionDriver.Create;\nbegin\n  inherited Create;\n\n  PoolList := TObjectList.Create(True);\n  URLList := TStringList.Create;\n  AddSupportedProtocol(PooledPrefix + '*');\nend;\n\ndestructor TZDbcPooledConnectionDriver.Destroy;\nbegin\n  PoolList.Free;\n  URLList.Free;\n\n  inherited;\nend;\n\nfunction TZDbcPooledConnectionDriver.AcceptsURL(const URL: string): Boolean;\nbegin\n  Result := Copy(URL, 1, 5 + Length(PooledPrefix)) = 'zdbc:' + PooledPrefix;\nend;\n\nfunction TZDbcPooledConnectionDriver.Connect(const URL: TZURL): IZConnection;\nvar\n  TempURL: TZURL;\n  I: Integer;\n  ConnectionPool: TConnectionPool;\n  ConnetionTimeout: Integer;\n  MaxConnections: Integer;\n  Wait: Boolean;\nbegin\n  Result := nil;\n\n  TempURL := TZURL.Create;\n  try\n    TempURL.URL := GetEmbeddedURL(URL.URL);\n    TempURL.Properties.Text := URL.Properties.Text;\n\n    ConnectionPool := nil;\n\n{ TODO\n  - Read and process connection properties 'timeout', 'poolsize' and 'wait' }\n\n    //\n    // Search for an existing pool for the URL.\n    // There is room to improve the algorithm used to decide when a pool is\n    // compatible with a given URL. For now, i am just comparing the URL strings.\n    //\n    for I := 0 to PoolList.Count - 1 do\n      if URLList[I] = TempURL.URL then\n      begin\n        ConnectionPool := TConnectionPool(PoolList[I]);\n        Break;\n      end;\n\n    //\n    // Create a new pool if needed.\n    //\n    if ConnectionPool = nil then\n    begin\n      ConnetionTimeout := StrToIntDef(TempURL.Properties.Values['ConnectionTimeout'], 0);\n      MaxConnections := StrToIntDef(TempURL.Properties.Values['MaxConnections'], 0);\n      Wait := StrToBoolDef(TempURL.Properties.Values['Wait'], True);\n      ConnectionPool := TConnectionPool.Create(TempURL.URL, ConnetionTimeout, MaxConnections, Wait);\n      PoolList.Add(ConnectionPool);\n      URLList.Add(TempURL.URL);\n    end;\n\n    Result := TZDbcPooledConnection.Create(ConnectionPool);\n  finally\n    TempURL.Free;\n  end;\nend;\n\nfunction TZDbcPooledConnectionDriver.GetClientVersion(const URL: string): Integer;\nbegin\n  Result := DriverManager.GetDriver(GetEmbeddedURL(URL)).GetClientVersion(GetEmbeddedURL(URL));\nend;\n\nfunction TZDbcPooledConnectionDriver.GetMajorVersion: Integer;\nbegin\n  Result := 1;\nend;\n\nfunction TZDbcPooledConnectionDriver.GetMinorVersion: Integer;\nbegin\n  Result := 0;\nend;\n\nfunction TZDbcPooledConnectionDriver.GetPropertyInfo(const URL: string; Info: TStrings): TStrings;\nbegin\n  Result := DriverManager.GetDriver(GetEmbeddedURL(URL)).GetPropertyInfo(GetEmbeddedURL(URL), Info);\n  if Result = nil then\n    Result := TStringList.Create;\n  Result.Values['ConnectionTimeout'] := '0';\n  Result.Values['MaxConnections'] := '0';\n  Result.Values['Wait'] := 'True';\nend;\n\nfunction TZDbcPooledConnectionDriver.GetSubVersion: Integer;\nbegin\n  Result := 0;\nend;\n\n{function TZDbcPooledConnectionDriver.GetSupportedProtocols: TStringDynArray;\nbegin\n  SetLength(Result, 1);\n  Result[0] := PooledPrefix + '*';\nend;}\n\nfunction TZDbcPooledConnectionDriver.GetEmbeddedURL(const URL: String): String;\nbegin\n  if Copy(URL, 1, 5 + Length(PooledPrefix)) = 'zdbc:' + PooledPrefix then\n    Result := 'zdbc:' + Copy(URL, 5 + Length(PooledPrefix) + 1, Length(URL))\n  else\n    raise Exception.Create('TZDbcPooledConnectionDriver.GetRealURL - URL must start with ''zdbc:' + PooledPrefix+ '''');\nend;\n\nvar\n  _Driver: IZDriver;\n\n{ TConnectionTimeoutThread }\n\nconstructor TConnectionTimeoutThread.Create(const ConnectionPool: TConnectionPool);\nbegin\n  inherited Create(False);\n\n  FConnectionPool := ConnectionPool;\n  FreeOnTerminate := False;\nend;\n\nprocedure TConnectionTimeoutThread.Execute;\nvar\n  I: Integer;\nbegin\n  while not Terminated  do\n  begin\n    Sleep(1000);\n\n    //\n    // Check if there are timed out connections and releases them\n    //\n    FConnectionPool.FCriticalSection.Enter;\n    try\n      for I := 0 to Length(FConnectionPool.FConnections) - 1 do\n        if (FConnectionPool.FConnections[I] <> nil) and\n           (not FConnectionPool.FSlotsInUse[I]) and\n           (FConnectionPool.FConnectionsReturnTimes[I] <> 0) and\n           (MilliSecondsBetween(FConnectionPool.FConnectionsReturnTimes[I], Now) > FConnectionPool.FConnectionTimeout * 1000) then\n             FConnectionPool.FConnections[I] := nil;\n    finally\n      FConnectionPool.FCriticalSection.Leave;\n    end;\n  end;\nend;\n\ninitialization\n  _Driver := TZDbcPooledConnectionDriver.Create;\n  DriverManager.RegisterDriver(_Driver);\n\nfinalization\n  DriverManager.DeregisterDriver(_Driver);\n\nend.\n\n"
  },
  {
    "path": "lib/zeosdbo/src/dbc/ZDbcPostgreSql.pas",
    "content": "{*********************************************************}\n{                                                         }\n{                 Zeos Database Objects                   }\n{         PostgreSQL Database Connectivity Classes        }\n{                                                         }\n{        Originally written by Sergey Seroukhov           }\n{                                                         }\n{*********************************************************}\n\n{@********************************************************}\n{    Copyright (c) 1999-2012 Zeos Development Group       }\n{                                                         }\n{ License Agreement:                                      }\n{                                                         }\n{ This library is distributed in the hope that it will be }\n{ useful, but WITHOUT ANY WARRANTY; without even the      }\n{ implied warranty of MERCHANTABILITY or FITNESS FOR      }\n{ A PARTICULAR PURPOSE.  See the GNU Lesser General       }\n{ Public License for more details.                        }\n{                                                         }\n{ The source code of the ZEOS Libraries and packages are  }\n{ distributed under the Library GNU General Public        }\n{ License (see the file COPYING / COPYING.ZEOS)           }\n{ with the following  modification:                       }\n{ As a special exception, the copyright holders of this   }\n{ library give you permission to link this library with   }\n{ independent modules to produce an executable,           }\n{ regardless of the license terms of these independent    }\n{ modules, and to copy and distribute the resulting       }\n{ executable under terms of your choice, provided that    }\n{ you also meet, for each linked independent module,      }\n{ the terms and conditions of the license of that module. }\n{ An independent module is a module which is not derived  }\n{ from or based on this library. If you modify this       }\n{ library, you may extend this exception to your version  }\n{ of the library, but you are not obligated to do so.     }\n{ If you do not wish to do so, delete this exception      }\n{ statement from your version.                            }\n{                                                         }\n{                                                         }\n{ The project web site is located on:                     }\n{   http://zeos.firmos.at  (FORUM)                        }\n{   http://sourceforge.net/p/zeoslib/tickets/ (BUGTRACKER)}\n{   svn://svn.code.sf.net/p/zeoslib/code-0/trunk (SVN)    }\n{                                                         }\n{   http://www.sourceforge.net/projects/zeoslib.          }\n{                                                         }\n{                                                         }\n{                                 Zeos Development Group. }\n{********************************************************@}\n\nunit ZDbcPostgreSql;\n\ninterface\n\n{$I ZDbc.inc}\n\nuses\n  Types, Classes, {$IFDEF MSEgui}mclasses,{$ENDIF} SysUtils,\n  {$IF defined(DELPHI) and defined(MSWINDOWS)}Windows,{$IFEND}\n  ZDbcIntfs, ZDbcConnection, ZPlainPostgreSqlDriver, ZDbcLogging, ZTokenizer,\n  ZGenericSqlAnalyser, ZURL, ZCompatibility;\n\ntype\n\n  {** Implements PostgreSQL Database Driver. }\n  {$WARNINGS OFF}\n  TZPostgreSQLDriver = class(TZAbstractDriver)\n  public\n    constructor Create; override;\n    function Connect(const Url: TZURL): IZConnection; override;\n    function GetMajorVersion: Integer; override;\n    function GetMinorVersion: Integer; override;\n\n    function GetTokenizer: IZTokenizer; override;\n    function GetStatementAnalyser: IZStatementAnalyser; override;\n  end;\n  {$WARNINGS ON}\n\ntype\n  PZPGTableInfo = ^TZPGTableInfo;\n  TZPGTableInfo = record\n    OID: Oid;\n    Name: String;\n    Schema: String;\n    ColNames: Array of String;\n    ColCount: Integer;\n  end;\n\n  { TZPGTableInfoCache }\n\n  TZPGTableInfoCache = class(TZCodePagedObject)\n    protected\n      FTblInfo: Array of TZPGTableInfo;\n      FPlainDriver: Pointer;\n      FHandle: PZPostgreSQLConnect;\n      function LoadTblInfo(const TblOid: Oid; out Index: Integer; ZPGTableInfo: PZPGTableInfo): Boolean;\n      function GetTblPos(const TblOid: Oid): Integer;\n    public\n      constructor Create(const ConSettings: PZConSettings;\n        const Handle: PZPostgreSQLConnect; const PlainDriver: IZPostgreSQLPlainDriver);\n      function GetTableInfo(const TblOid: Oid; CurrentFieldCount: Integer): PZPGTableInfo;\n      procedure Clear;\n  end;\n\n  {** Defines a PostgreSQL specific connection. }\n  IZPostgreSQLConnection = interface(IZConnection)\n    ['{8E62EA93-5A49-4F20-928A-0EA44ABCE5DB}']\n\n    function IsOidAsBlob: Boolean;\n    function Is_bytea_output_hex: Boolean;\n\n    function GetTypeNameByOid(Id: Oid): string;\n    function GetPlainDriver: IZPostgreSQLPlainDriver;\n    function GetConnectionHandle: PZPostgreSQLConnect;\n    function GetServerMajorVersion: Integer;\n    function GetServerMinorVersion: Integer;\n    function EncodeBinary(const Value: RawByteString): RawByteString; overload;\n    function EncodeBinary(const Value: TByteDynArray): RawByteString; overload;\n    procedure RegisterPreparedStmtName(const value: String);\n    procedure UnregisterPreparedStmtName(const value: String);\n    function ClientSettingsChanged: Boolean;\n    function GetUndefinedVarcharAsStringLength: Integer;\n    function GetTableInfo(const TblOid: Oid; CurrentFieldCount: Integer): PZPGTableInfo;\n    function CheckFieldVisibility: Boolean;\n  end;\n\n  {** Implements PostgreSQL Database Connection. }\n\n  { TZPostgreSQLConnection }\n\n  TZPostgreSQLConnection = class(TZAbstractConnection, IZPostgreSQLConnection)\n  private\n    FStandardConformingStrings: Boolean;\n    FHandle: PZPostgreSQLConnect;\n    FBeginRequired: Boolean;\n    FTypeList: TStrings;\n    FOidAsBlob: Boolean;\n    FServerMajorVersion: Integer;\n    FServerMinorVersion: Integer;\n    FServerSubVersion: Integer;\n    FNoticeProcessor: TZPostgreSQLNoticeProcessor;\n    FPreparedStmts: TStrings;\n    FClientSettingsChanged: Boolean;\n    FTableInfoCache: TZPGTableInfoCache;\n    FIs_bytea_output_hex: Boolean;\n    FCheckFieldVisibility: Boolean;\n  protected\n    procedure InternalCreate; override;\n    function GetUndefinedVarcharAsStringLength: Integer;\n    function GetTableInfo(const TblOid: Oid; CurrentFieldCount: Integer): PZPGTableInfo;\n    function BuildConnectStr: AnsiString;\n    procedure StartTransactionSupport;\n    procedure LoadServerVersion;\n    procedure OnPropertiesChange(Sender: TObject); override;\n    procedure SetStandardConformingStrings(const Value: Boolean);\n    function EncodeBinary(const Value: RawByteString): RawByteString; overload;\n    function EncodeBinary(const Value: TByteDynArray): RawByteString; overload;\n    procedure RegisterPreparedStmtName(const value: String);\n    procedure UnregisterPreparedStmtName(const value: String);\n    function ClientSettingsChanged: Boolean;\n  public\n    destructor Destroy; override;\n\n    function CreateRegularStatement(Info: TStrings): IZStatement; override;\n    function CreatePreparedStatement(const SQL: string; Info: TStrings):\n      IZPreparedStatement; override;\n    function CreateCallableStatement(const SQL: string; Info: TStrings):\n      IZCallableStatement; override;\n\n    function CreateSequence(const Sequence: string; BlockSize: Integer): IZSequence; override;\n\n    procedure Commit; override;\n    procedure Rollback; override;\n    //2Phase Commit Support initially for PostgresSQL (firmos) 21022006\n    procedure PrepareTransaction(const transactionid: string);override;\n    procedure CommitPrepared(const transactionid:string);override;\n    procedure RollbackPrepared(const transactionid:string);override;\n\n    procedure Open; override;\n    procedure Close; override;\n\n    procedure SetTransactionIsolation(Level: TZTransactIsolationLevel); override;\n\n    function IsOidAsBlob: Boolean;\n    function Is_bytea_output_hex: Boolean;\n    function CheckFieldVisibility: Boolean;\n\n    function GetTypeNameByOid(Id: Oid): string;\n    function GetPlainDriver: IZPostgreSQLPlainDriver;\n    function GetConnectionHandle: PZPostgreSQLConnect;\n\n    function GetHostVersion: Integer; override;\n    function GetServerMajorVersion: Integer;\n    function GetServerMinorVersion: Integer;\n    function GetServerSubVersion: Integer;\n\n    function PingServer: Integer; override;\n    function EscapeString(Value: RawByteString): RawByteString; override;\n    function GetBinaryEscapeString(const Value: RawByteString): String; overload; override;\n    function GetBinaryEscapeString(const Value: TByteDynArray): String; overload; override;\n    function GetEscapeString(const Value: ZWideString): ZWideString; overload; override;\n    function GetEscapeString(const Value: RawByteString): RawByteString; overload; override;\n    function GetServerSetting(const AName: string): string;\n    procedure SetServerSetting(const AName, AValue: string);\n    {$IFDEF ZEOS_TEST_ONLY}\n    constructor Create(const ZUrl: TZURL);\n    {$ENDIF}\n  end;\n\n  {** Implements a Postgres sequence. }\n  TZPostgreSQLSequence = class(TZAbstractSequence)\n  public\n    function GetCurrentValue: Int64; override;\n    function GetNextValue: Int64; override;\n    function  GetCurrentValueSQL:String;override;\n    function  GetNextValueSQL:String;override;\n  end;\n\n\nvar\n  {** The common driver manager object. }\n  PostgreSQLDriver: IZDriver;\n\nimplementation\n\nuses\n  ZMessages, ZSysUtils, ZDbcUtils, ZDbcPostgreSqlStatement,\n  ZDbcPostgreSqlUtils, ZDbcPostgreSqlMetadata, ZPostgreSqlToken,\n  ZPostgreSqlAnalyser, ZEncoding;\n\nconst\n  FON = String('ON');\n  standard_conforming_strings = String('standard_conforming_strings');\n\nprocedure DefaultNoticeProcessor(arg: Pointer; message: PAnsiChar); cdecl;\nbegin\nDriverManager.LogMessage(lcOther,'Postgres NOTICE',String(message));\nend;\n\n{ TZPGTableInfoCache }\nfunction TZPGTableInfoCache.LoadTblInfo(const TblOid: Oid; \n  out Index: Integer; ZPGTableInfo: PZPGTableInfo): Boolean;\nvar\n  SQL: String;\n  TblInfo: PZPGTableInfo;\n  RawOid: String;\n  QueryHandle: PZPostgreSQLResult;\n  I: Integer;\n  function GetInt(const Row, Col: Integer): Integer;\n  begin\n    Result := StrToInt(String(IZPostgreSQLPlainDriver(FPlainDriver).GetValue(QueryHandle, Row, Col)));\n  end;\n\n  function GetString(const Row, Col: Integer): String;\n {$IFDEF UNICODE}\n  var\n    RawTemp: RawByteString;\n {$ENDIF}\n  begin\n    {$IFDEF UNICODE}\n    ZSetString(IZPostgreSQLPlainDriver(FPlainDriver).GetValue(QueryHandle, Row, Col),\n      IZPostgreSQLPlainDriver(FPlainDriver).GetLength(QueryHandle, Row, Col), RawTemp);\n    Result := ZDbcUnicodeString(RawTemp);\n    {$ELSE}\n    SetString(Result, IZPostgreSQLPlainDriver(FPlainDriver).GetValue(QueryHandle, Row, Col),\n      IZPostgreSQLPlainDriver(FPlainDriver).GetLength(QueryHandle, Row, Col));\n    {$ENDIF}\n  end;\nbegin\n  RawOID := IntToStr(TblOid);\n\n  SQL := 'select pc.relname, pns.nspname, pa.attnum, pa.attname from ' +\n    'pg_catalog.pg_class pc ' +\n    'join pg_catalog.pg_namespace pns on pc.relnamespace = pns.oid ' +\n    'join pg_catalog.pg_attribute pa on pa.attrelid = pc.oid ' +\n    'where pc.oid = ' + RawOID + ' and pa.attnum > 0';\n\n  QueryHandle := IZPostgreSQLPlainDriver(FPlainDriver).ExecuteQuery(FHandle, PAnsichar(ZPlainString(SQL)));\n  CheckPostgreSQLError(nil, IZPostgreSQLPlainDriver(FPlainDriver), FHandle, lcExecute, SQL, QueryHandle);\n  DriverManager.LogMessage(lcExecute, IZPostgreSQLPlainDriver(FPlainDriver).GetProtocol, SQL);\n\n  Result := IZPostgreSQLPlainDriver(FPlainDriver).GetRowCount(QueryHandle) > 0;\n  if Result then\n  begin\n    if ZPGTableInfo <> nil then //just overwrite all values\n      tblInfo := ZPGTableInfo\n    else\n    begin //we need a new cache\n      SetLength(FTblInfo, Length(FTblInfo) +1);\n      Index := High(FTblInfo);\n      TblInfo := @FTblInfo[Index];\n    end;\n    TblInfo^.OID := TblOid;\n    TblInfo^.Name := GetString(0, 0);\n    TblInfo^.Schema := GetString(0, 1);\n    TblInfo^.ColCount := IZPostgreSQLPlainDriver(FPlainDriver).GetRowCount(QueryHandle);\n    SetLength(TblInfo^.ColNames, TblInfo^.ColCount);\n\n    for I := 0 to TblInfo^.ColCount - 1 do\n      TblInfo^.ColNames[GetInt(I, 2)-1] := GetString(i, 3);\n    IZPostgreSQLPlainDriver(FPlainDriver).Clear(QueryHandle);\n  end\n  else\n    Index := -1;\nend;\n\nfunction TZPGTableInfoCache.GetTblPos(const TblOid: Oid): Integer;\nvar\n  x: Integer;\nbegin\n  Result := -1;\n  if TblOid <> InvalidOid then\n    for x := 0 to Length(FTblInfo) - 1 do\n      if FTblInfo[x].OID = TblOid then\n      begin\n        Result := x;\n        Break;\n      end;\nend;\n\nconstructor TZPGTableInfoCache.Create(const ConSettings: PZConSettings;\n  const Handle: PZPostgreSQLConnect; const PlainDriver: IZPostgreSQLPlainDriver);\nbegin\n  Self.ConSettings := ConSettings;\n  FPlainDriver := Pointer(PlainDriver);\n  FHandle := Handle;\n\n  Clear;\nend;\n\nfunction TZPGTableInfoCache.GetTableInfo(const TblOid: Oid;\n  CurrentFieldCount: Integer): PZPGTableInfo;\nvar Idx: Integer;\nbegin\n  Idx := GetTblPos(TblOid);\n  if (Idx = -1) then\n    if (TblOid <> InvalidOid) and (LoadTblInfo(TblOid, Idx, nil)) then\n      Result := @FTblInfo[Idx]\n    else\n      Result := nil\n  else\n  begin\n    Result := @FTblInfo[Idx];\n    if Result^.ColCount <> CurrentFieldCount then //something changed ?\n      LoadTblInfo(TblOid, Idx, Result); //refresh all data\n  end;\nend;\n\nprocedure TZPGTableInfoCache.Clear;\nbegin\n  SetLength(FTblInfo, 0);\nend;\n\n{ TZPostgreSQLDriver }\n\n{**\n  Constructs this object with default properties.\n}\nconstructor TZPostgreSQLDriver.Create;\nbegin\n  inherited Create;\n  AddSupportedProtocol(AddPlainDriverToCache(TZPostgreSQL9PlainDriver.Create, 'postgresql'));\n  AddSupportedProtocol(AddPlainDriverToCache(TZPostgreSQL7PlainDriver.Create));\n  AddSupportedProtocol(AddPlainDriverToCache(TZPostgreSQL8PlainDriver.Create));\n  AddSupportedProtocol(AddPlainDriverToCache(TZPostgreSQL9PlainDriver.Create));\nend;\n\n{**\n  Attempts to make a database connection to the given URL.\n  The driver should return \"null\" if it realizes it is the wrong kind\n  of driver to connect to the given URL.  This will be common, as when\n  the JDBC driver manager is asked to connect to a given URL it passes\n  the URL to each loaded driver in turn.\n\n  <P>The driver should raise a SQLException if it is the right\n  driver to connect to the given URL, but has trouble connecting to\n  the database.\n\n  <P>The java.util.Properties argument can be used to passed arbitrary\n  string tag/value pairs as connection arguments.\n  Normally at least \"user\" and \"password\" properties should be\n  included in the Properties.\n\n  @param url the URL of the database to which to connect\n  @param info a list of arbitrary string tag/value pairs as\n    connection arguments. Normally at least a \"user\" and\n    \"password\" property should be included.\n  @return a <code>Connection</code> object that represents a\n    connection to the URL\n}\n{$WARNINGS OFF}\nfunction TZPostgreSQLDriver.Connect(const Url: TZURL): IZConnection;\nbegin\n  Result := TZPostgreSQLConnection.Create(Url);\nend;\n{$WARNINGS ON}\n\n{**\n  Gets the driver's major version number. Initially this should be 1.\n  @return this driver's major version number\n}\nfunction TZPostgreSQLDriver.GetMajorVersion: Integer;\nbegin\n  Result := 1;\nend;\n\n{**\n  Gets the driver's minor version number. Initially this should be 0.\n  @return this driver's minor version number\n}\nfunction TZPostgreSQLDriver.GetMinorVersion: Integer;\nbegin\n  Result := 3;\nend;\n\n{**\n  Gets a SQL syntax tokenizer.\n  @returns a SQL syntax tokenizer object.\n}\nfunction TZPostgreSQLDriver.GetTokenizer: IZTokenizer;\nbegin\n  if Tokenizer = nil then\n    Tokenizer := TZPostgreSQLTokenizer.Create;\n  Result := Tokenizer;\nend;\n\n{**\n  Creates a statement analyser object.\n  @returns a statement analyser object.\n}\nfunction TZPostgreSQLDriver.GetStatementAnalyser: IZStatementAnalyser;\nbegin\n  if Analyser = nil then\n    Analyser := TZPostgreSQLStatementAnalyser.Create;\n  Result := Analyser;\nend;\n\n{ TZPostgreSQLConnection }\n\n{**\n  Constructs this object and assignes the main properties.\n}\nprocedure TZPostgreSQLConnection.InternalCreate;\nbegin\n  FMetaData := TZPostgreSQLDatabaseMetadata.Create(Self, Url);\n  FPreparedStmts := nil;\n  FTableInfoCache := nil;\n\n  { Sets a default PostgreSQL port }\n  if Self.Port = 0 then\n     Self.Port := 5432;\n\n  { Define connect options. }\n  if Info.Values['beginreq'] <> '' then\n    FBeginRequired := StrToBoolEx(Info.Values['beginreq'])\n  else\n    FBeginRequired := True;\n\n  TransactIsolationLevel := tiNone;\n\n  { Processes connection properties. }\n  if Info.Values['oidasblob'] <> '' then\n    FOidAsBlob := StrToBoolEx(Info.Values['oidasblob'])\n  else\n    FOidAsBlob := False;\n\n  FUndefinedVarcharAsStringLength := StrToIntDef(Info.Values['Undefined_Varchar_AsString_Length'], 0);\n  FCheckFieldVisibility := StrToBoolEx(Info.Values['CheckFieldVisibility']);\n\n  OnPropertiesChange(nil);\n\n  FNoticeProcessor := DefaultNoticeProcessor;\nend;\n\n\nfunction TZPostgreSQLConnection.GetUndefinedVarcharAsStringLength: Integer;\nbegin\n  Result := FUndefinedVarcharAsStringLength;\nend;\n\nfunction TZPostgreSQLConnection.GetTableInfo(const TblOid: Oid; CurrentFieldCount: Integer): PZPGTableInfo;\nbegin\n  Result := FTableInfoCache.GetTableInfo(TblOid, CurrentFieldCount);\nend;\n\n{**\n  Destroys this object and cleanups the memory.\n}\ndestructor TZPostgreSQLConnection.Destroy;\nbegin\n  if FTypeList <> nil then FreeAndNil(FTypeList);\n  inherited Destroy;\n  if FTableInfoCache <> nil then FreeAndNil(FTableInfoCache);\n  if FPreparedStmts <> nil then FreeAndNil(FPreparedStmts);\nend;\n\n{**\n  Builds a connection string for PostgreSQL.\n  @return a built connection string.\n}\nfunction TZPostgreSQLConnection.BuildConnectStr: AnsiString;\nvar\n  ConnectTimeout: Integer;\n  // backslashes and single quotes must be escaped with backslashes\n  function EscapeValue(AValue: String): String;\n  begin\n    Result := StringReplace(AValue, '\\', '\\\\', [rfReplaceAll]);\n    Result := StringReplace(Result, '''', '\\''', [rfReplaceAll]);\n  end;\n\n  //parameters should be separated by whitespace\n  procedure AddParamToResult(AParam, AValue: String);\n  begin\n    if Result <> '' then\n      Result := Result + ' ';\n\n    Result := Result + AnsiString(AParam+'='+QuotedStr(EscapeValue(AValue)));\n  end;\nbegin\n  //Init the result to empty string.\n  Result := '';\n  //Entering parameters from the ZConnection\n  If IsIpAddr(HostName) then\n    AddParamToResult('hostaddr', HostName)\n  else\n    AddParamToResult('host', HostName);\n\n  AddParamToResult('port', IntToStr(Port));\n  AddParamToResult('dbname', Database);\n  AddParamToResult('user', User);\n  AddParamToResult('password', Password);\n\n  If Info.Values['sslmode'] <> '' then\n  begin\n    // the client (>= 7.3) sets the ssl mode for this connection\n    // (possible values are: require, prefer, allow, disable)\n    AddParamToResult('sslmode', Info.Values['sslmode']);\n  end\n  else if Info.Values['requiressl'] <> '' then\n  begin\n    // the client (< 7.3) sets the ssl encription for this connection\n    // (possible values are: 0,1)\n    AddParamToResult('requiressl', Info.Values['requiressl']);\n  end;\n\n  if Info.Values['sslcompression'] <> '' then AddParamToResult('sslcompression', Info.Values['sslcompression']);\n  if Info.Values['sslcert'] <> '' then AddParamToResult('sslcert', Info.Values['sslcert']);\n  if Info.Values['sslkey'] <> '' then AddParamToResult('sslkey', Info.Values['sslkey']);\n  if Info.Values['sslrootcert'] <> '' then AddParamToResult('sslrootcert', Info.Values['sslrootcert']);\n  if Info.Values['sslcrl'] <> '' then AddParamToResult('sslcrl', Info.Values['sslcrl']);\n\n  { Sets a connection timeout. }\n  ConnectTimeout := StrToIntDef(Info.Values['timeout'], -1);\n  if ConnectTimeout >= 0 then\n    AddParamToResult('connect_timeout', IntToStr(ConnectTimeout));\n\n  { Sets the application name }\n  if Info.Values['application_name'] <> '' then\n    AddParamToResult('application_name', Info.Values['application_name']);\n\nend;\n\n{**\n  Checks is oid should be treated as Large Object.\n  @return <code>True</code> if oid should represent a Large Object.\n}\nfunction TZPostgreSQLConnection.IsOidAsBlob: Boolean;\nbegin\n  Result := FOidAsBlob;\nend;\n\n{**\n  Checks is bytea_output hex.\n  @return <code>True</code> if hex is set.\n}\nfunction TZPostgreSQLConnection.Is_bytea_output_hex: Boolean;\nbegin\n  Result := FIs_bytea_output_hex;\nend;\n\n{**\n  Checks if DataBaseMetaData should check FieldVisibility too.\n  @return <code>True</code> if user did set it.\n}\nfunction TZPostgreSQLConnection.CheckFieldVisibility: Boolean;\nbegin\n  Result := FCheckFieldVisibility;\nend;\n\n{**\n  Starts a transaction support.\n}\nprocedure TZPostgreSQLConnection.StartTransactionSupport;\nvar\n  QueryHandle: PZPostgreSQLResult;\n  SQL: String;\nbegin\n  if TransactIsolationLevel <> tiNone then\n  begin\n    if FBeginRequired then\n    begin\n      SQL := 'BEGIN';\n      QueryHandle := GetPlainDriver.ExecuteQuery(FHandle, PAnsiChar(AnsiString(SQL)));\n      CheckPostgreSQLError(nil, GetPlainDriver, FHandle, lcExecute, SQL,QueryHandle);\n      GetPlainDriver.Clear(QueryHandle);\n      DriverManager.LogMessage(lcExecute, PlainDriver.GetProtocol, SQL);\n    end;\n\n    if TransactIsolationLevel = tiReadCommitted then\n    begin\n      SQL := 'SET TRANSACTION ISOLATION LEVEL READ COMMITTED';\n      QueryHandle := GetPlainDriver.ExecuteQuery(FHandle, PAnsiChar(AnsiString(SQL)));\n      CheckPostgreSQLError(nil, GetPlainDriver, FHandle, lcExecute, SQL,QueryHandle);\n      GetPlainDriver.Clear(QueryHandle);\n      DriverManager.LogMessage(lcExecute, PlainDriver.GetProtocol, SQL);\n    end\n    else if TransactIsolationLevel = tiSerializable then\n    begin\n      SQL := 'SET TRANSACTION ISOLATION LEVEL SERIALIZABLE';\n      QueryHandle := GetPlainDriver.ExecuteQuery(FHandle, PAnsiChar(AnsiString(SQL)));\n      CheckPostgreSQLError(nil, GetPlainDriver, FHandle, lcExecute, SQL,QueryHandle);\n      GetPlainDriver.Clear(QueryHandle);\n      DriverManager.LogMessage(lcExecute, PlainDriver.GetProtocol, SQL);\n    end\n    else\n      raise EZSQLException.Create(SIsolationIsNotSupported);\n  end;\nend;\n\n{**\n  Encodes a Binary-AnsiString to a PostgreSQL format\n  @param Value the Binary String\n  @result the encoded String\n}\nfunction TZPostgreSQLConnection.EncodeBinary(const Value: TByteDynArray): RawByteString;\nvar Temp: RawByteString;\nbegin\n  ZSetString(PAnsiChar(Value), Length(Value), Temp);\n  Result := EncodeBinary(Temp);\nend;\n{**\n  Encodes a Binary-AnsiString to a PostgreSQL format\n  @param Value the Binary String\n  @result the encoded String\n}\nfunction TZPostgreSQLConnection.EncodeBinary(const Value: RawByteString): RawByteString;\nbegin\n  if ( Self.GetServerMajorVersion > 7 ) or\n    ((GetServerMajorVersion = 7) and (GetServerMinorVersion >= 3)) then\n    Result := GetPlainDriver.EncodeBYTEA(Value, GetConnectionHandle)\n  else\n    Result := ZDbcPostgreSqlUtils.EncodeBinaryString(Value);\nend;\n\nprocedure TZPostgreSQLConnection.RegisterPreparedStmtName(const value: String);\nbegin\n  FPreparedStmts.Add(Value);\nend;\n\nprocedure TZPostgreSQLConnection.UnregisterPreparedStmtName(const value: String);\nvar Index: Integer;\nbegin\n  Index := FPreparedStmts.IndexOf(Value);\n  if Index > -1 then\n    FPreparedStmts.Delete(Index);\nend;\n\nfunction TZPostgreSQLConnection.ClientSettingsChanged: Boolean;\nbegin\n  Result := FClientSettingsChanged;\nend;\n{**\n  Opens a connection to database server with specified parameters.\n}\nprocedure TZPostgreSQLConnection.Open;\n\nvar\n  SCS, LogMessage, TempClientCodePage: string;\nbegin\n  if not Closed then\n    Exit;\n\n  LogMessage := Format('CONNECT TO \"%s\" AS USER \"%s\"', [Database, User]);\n\n  { Connect to PostgreSQL database. }\n  FHandle := GetPlainDriver.ConnectDatabase(PAnsiChar(BuildConnectStr));\n  try\n    if GetPlainDriver.GetStatus(FHandle) = CONNECTION_BAD then\n    begin\n      CheckPostgreSQLError(nil, GetPlainDriver, FHandle,\n                            lcConnect, LogMessage,nil)\n    end\n    else\n      DriverManager.LogMessage(lcConnect, PlainDriver.GetProtocol, LogMessage);\n\n    { Set the notice processor (default = nil)}\n    GetPlainDriver.SetNoticeProcessor(FHandle,FNoticeProcessor,nil);\n\n    { Gets the current codepage }\n    TempClientCodePage := GetPlainDriver.ValidateCharEncoding(GetPlainDriver.GetClientEncoding(FHandle)).Name;\n\n    { Sets a client codepage if necessary }\n    if ( FClientCodePage <> '' ) and (TempClientCodePage <> FClientCodePage) then\n      SetServerSetting('CLIENT_ENCODING', FClientCodePage);\n\n    { Turn on transaction mode }\n    StartTransactionSupport;\n    inherited Open;\n\n    { Gets the current codepage if it wasn't set..}\n    if ( FClientCodePage = '') then\n      CheckCharEncoding(TempClientCodePage)\n    else\n    begin\n      CheckCharEncoding(FClientCodePage);\n      FClientSettingsChanged := True;\n    end;\n\n    if FPreparedStmts = nil then\n      FPreparedStmts := TStringList.Create;\n    if FTableInfoCache = nil then\n      FTableInfoCache := TZPGTableInfoCache.Create(ConSettings, FHandle, GetPlainDriver);\n\n    { sets standard_conforming_strings according to Properties if available }\n    SCS := Info.Values[standard_conforming_strings];\n    if SCS <> '' then\n    begin\n      SetServerSetting(standard_conforming_strings, SCS);\n      FClientSettingsChanged := True;\n    end;\n    FIs_bytea_output_hex := UpperCase(GetServerSetting('''bytea_output''')) = 'HEX';\n\n  finally\n    if self.IsClosed and (Self.FHandle <> nil) then\n    begin\n      GetPlainDriver.Finish(Self.FHandle);\n      Self.FHandle := nil;\n    end;\n  end;\nend;\n\nprocedure TZPostgreSQLConnection.PrepareTransaction(const transactionid: string);\nvar\n   QueryHandle: PZPostgreSQLResult;\n   SQL: String;\nbegin\n  if (TransactIsolationLevel <> tiNone) and not Closed then\n  begin\n    SQL:='PREPARE TRANSACTION '''+copy(transactionid,1,200)+'''';\n    QueryHandle := GetPlainDriver.ExecuteQuery(FHandle, PAnsiChar(ZPlainString(SQL)));\n    CheckPostgreSQLError(nil, GetPlainDriver, FHandle, lcExecute, SQL,QueryHandle);\n    GetPlainDriver.Clear(QueryHandle);\n    DriverManager.LogMessage(lcExecute, PlainDriver.GetProtocol, SQL);\n    StartTransactionSupport;\n  end;\nend;\n\n{**\n  Creates a <code>Statement</code> object for sending\n  SQL statements to the database.\n  SQL statements without parameters are normally\n  executed using Statement objects. If the same SQL statement\n  is executed many times, it is more efficient to use a\n  <code>PreparedStatement</code> object.\n  <P>\n  Result sets created using the returned <code>Statement</code>\n  object will by default have forward-only type and read-only concurrency.\n\n  @param Info a statement parameters.\n  @return a new Statement object\n}\nfunction TZPostgreSQLConnection.CreateRegularStatement(Info: TStrings):\n  IZStatement;\nbegin\n  if IsClosed then\n    Open;\n  Result := TZPostgreSQLStatement.Create(GetPlainDriver, Self, Info);\nend;\n\n{**\n  Creates a <code>PreparedStatement</code> object for sending\n  parameterized SQL statements to the database.\n\n  A SQL statement with or without IN parameters can be\n  pre-compiled and stored in a PreparedStatement object. This\n  object can then be used to efficiently execute this statement\n  multiple times.\n\n  <P><B>Note:</B> This method is optimized for handling\n  parametric SQL statements that benefit from precompilation. If\n  the driver supports precompilation,\n  the method <code>prepareStatement</code> will send\n  the statement to the database for precompilation. Some drivers\n  may not support precompilation. In this case, the statement may\n  not be sent to the database until the <code>PreparedStatement</code> is\n  executed.  This has no direct effect on users; however, it does\n  affect which method throws certain SQLExceptions.\n\n  Result sets created using the returned PreparedStatement will have\n  forward-only type and read-only concurrency, by default.\n\n  @param sql a SQL statement that may contain one or more '?' IN\n    parameter placeholders\n  @param Info a statement parameters.\n  @return a new PreparedStatement object containing the\n    pre-compiled statement\n}\nfunction TZPostgreSQLConnection.CreatePreparedStatement(\n  const SQL: string; Info: TStrings): IZPreparedStatement;\nbegin\n  if IsClosed then\n     Open;\n\n  {$IFDEF ZEOS_TEST_ONLY}\n  Case GetTestMode of\n    0:\n  {$ENDIF}\n      if GetServerMajorVersion >= 8 then\n        Result := TZPostgreSQLCAPIPreparedStatement.Create(GetPlainDriver, Self, SQL, Info)\n      else\n        Result := TZPostgreSQLClassicPreparedStatement.Create(GetPlainDriver, Self, SQL, Info);\n  {$IFDEF ZEOS_TEST_ONLY}\n    1: Result := TZPostgreSQLClassicPreparedStatement.Create(GetPlainDriver, Self, SQL, Info);\n    2: Result := TZPostgreSQLEmulatedPreparedStatement.Create(GetPlainDriver, Self, SQL, Info);\n  end;\n  {$ENDIF}\nend;\n\n\n{**\n  Creates a <code>CallableStatement</code> object for calling\n  database stored procedures (functions in PostgreSql).\n  The <code>CallableStatement</code> object provides\n  methods for setting up its IN and OUT parameters, and\n  methods for executing the call to a stored procedure.\n\n  <P><B>Note:</B> This method is optimized for handling stored\n  procedure call statements. Some drivers may send the call\n  statement to the database when the method <code>prepareCall</code>\n  is done; others\n  may wait until the <code>CallableStatement</code> object\n  is executed. This has no\n  direct effect on users; however, it does affect which method\n  throws certain SQLExceptions.\n\n  Result sets created using the returned CallableStatement will have\n  forward-only type and read-only concurrency, by default.\n\n  @param sql a SQL statement that may contain one or more '?'\n    parameter placeholders. Typically this  statement is a JDBC\n    function call escape string.\n  @param Info a statement parameters.\n  @return a new CallableStatement object containing the\n    pre-compiled SQL statement\n}\nfunction TZPostgreSQLConnection.CreateCallableStatement(\n  const SQL: string; Info: TStrings): IZCallableStatement;\nbegin\n  if IsClosed then\n     Open;\n  Result := TZPostgreSQLCallableStatement.Create(Self, SQL, Info);\nend;\n\n{**\n  Makes all changes made since the previous\n  commit/rollback permanent and releases any database locks\n  currently held by the Connection. This method should be\n  used only when auto-commit mode has been disabled.\n  @see #setAutoCommit\n}\nprocedure TZPostgreSQLConnection.Commit;\nvar\n  QueryHandle: PZPostgreSQLResult;\n  SQL: String;\nbegin\n  if (TransactIsolationLevel <> tiNone) and not Closed then\n  begin\n    SQL := 'COMMIT';\n    QueryHandle := GetPlainDriver.ExecuteQuery(FHandle, PAnsiChar(AnsiString(SQL)));\n    CheckPostgreSQLError(nil, GetPlainDriver, FHandle, lcExecute, SQL,QueryHandle);\n    GetPlainDriver.Clear(QueryHandle);\n    DriverManager.LogMessage(lcExecute, PlainDriver.GetProtocol, SQL);\n\n    StartTransactionSupport;\n  end;\nend;\n\nprocedure TZPostgreSQLConnection.CommitPrepared(const transactionid: string);\nvar\n  QueryHandle: PZPostgreSQLResult;\n  SQL: String;\nbegin\n  if (TransactIsolationLevel = tiNone) and not Closed then\n  begin\n    SQL := 'COMMIT PREPARED '''+copy(transactionid,1,200)+'''';\n    QueryHandle := GetPlainDriver.ExecuteQuery(FHandle, PAnsiChar(AnsiString(SQL)));\n    CheckPostgreSQLError(nil, GetPlainDriver, FHandle, lcExecute, SQL,QueryHandle);\n    GetPlainDriver.Clear(QueryHandle);\n    DriverManager.LogMessage(lcExecute, PlainDriver.GetProtocol, SQL);\n    StartTransactionSupport;\n  end;\nend;\n\n{**\n  Drops all changes made since the previous\n  commit/rollback and releases any database locks currently held\n  by this Connection. This method should be used only when auto-\n  commit has been disabled.\n  @see #setAutoCommit\n}\nprocedure TZPostgreSQLConnection.Rollback;\nvar\n  QueryHandle: PZPostgreSQLResult;\n  SQL: String;\nbegin\n  if (TransactIsolationLevel <> tiNone) and not Closed then\n  begin\n    SQL := 'ROLLBACK';\n    QueryHandle := GetPlainDriver.ExecuteQuery(FHandle, PAnsiChar(AnsiString(SQL)));\n    CheckPostgreSQLError(nil, GetPlainDriver, FHandle, lcExecute, SQL,QueryHandle);\n    GetPlainDriver.Clear(QueryHandle);\n    DriverManager.LogMessage(lcExecute, PlainDriver.GetProtocol, SQL);\n\n    StartTransactionSupport;\n  end;\nend;\n\nprocedure TZPostgreSQLConnection.RollbackPrepared(const transactionid: string);\nvar\n   QueryHandle: PZPostgreSQLResult;\n   SQL: string;\nbegin\n  if (TransactIsolationLevel = tiNone) and not Closed then\n  begin\n    SQL := 'ROLLBACK PREPARED '''+copy(transactionid,1,200)+'''';\n    QueryHandle := GetPlainDriver.ExecuteQuery(FHandle, PAnsiChar(AnsiString(SQL)));\n    CheckPostgreSQLError(nil, GetPlainDriver, FHandle, lcExecute, SQL,QueryHandle);\n    GetPlainDriver.Clear(QueryHandle);\n    DriverManager.LogMessage(lcExecute, PlainDriver.GetProtocol, SQL);\n    StartTransactionSupport;\n  end;\nend;\n\n{**\n  Releases a Connection's database and JDBC resources\n  immediately instead of waiting for\n  them to be automatically released.\n\n  <P><B>Note:</B> A Connection is automatically closed when it is\n  garbage collected. Certain fatal errors also result in a closed\n  Connection.\n}\nprocedure TZPostgreSQLConnection.Close;\nvar\n  LogMessage: string;\n  I: Integer;\nbegin\n  if ( Closed ) or (not Assigned(PlainDriver)) then\n    Exit;\n\n  for i := 0 to FPreparedStmts.Count -1 do\n  begin\n    LogMessage := 'DEALLOCATE \"'+FPreparedStmts[i]+'\";';\n    GetPlainDriver.ExecuteQuery(FHandle, Pointer(LogMessage));\n  end;\n  FPreparedStmts.Clear;\n  FTableInfoCache.Clear;\n\n  GetPlainDriver.Finish(FHandle);\n  FHandle := nil;\n  LogMessage := Format('DISCONNECT FROM \"%s\"', [Database]);\n  DriverManager.LogMessage(lcDisconnect, PlainDriver.GetProtocol, LogMessage);\n  inherited Close;\nend;\n\n{**\n  Sets a new transact isolation level.\n  @param Level a new transact isolation level.\n}\nprocedure TZPostgreSQLConnection.SetTransactionIsolation(\n  Level: TZTransactIsolationLevel);\nvar\n  QueryHandle: PZPostgreSQLResult;\n  SQL: String;\nbegin\n  if not (Level in [tiNone, tiReadCommitted, tiSerializable]) then\n    raise EZSQLException.Create(SIsolationIsNotSupported);\n\n  if (TransactIsolationLevel <> tiNone) and not Closed then\n  begin\n    SQL := 'END';\n    QueryHandle := GetPlainDriver.ExecuteQuery(FHandle, PAnsiChar(AnsiString(SQL)));\n    CheckPostgreSQLError(nil, GetPlainDriver, FHandle, lcExecute, SQL,QueryHandle);\n    GetPlainDriver.Clear(QueryHandle);\n    DriverManager.LogMessage(lcExecute, PlainDriver.GetProtocol, SQL);\n  end;\n\n  inherited SetTransactionIsolation(Level);\n\n  if not Closed then\n    StartTransactionSupport;\nend;\n\n{**\n  Gets a reference to PostgreSQL connection handle.\n  @return a reference to PostgreSQL connection handle.\n}\nfunction TZPostgreSQLConnection.GetConnectionHandle: PZPostgreSQLConnect;\nbegin\n  Result := FHandle;\nend;\n\n{**\n  Gets a PostgreSQL plain driver interface.\n  @return a PostgreSQL plain driver interface.\n}\nfunction TZPostgreSQLConnection.GetPlainDriver: IZPostgreSQLPlainDriver;\nbegin\n  Result := PlainDriver as IZPostgreSQLPlainDriver;\nend;\n\n{**\n  Gets a type name by it's oid number.\n  @param Id a type oid number.\n  @return a type name or empty string if there was no such type found.\n}\nfunction TZPostgreSQLConnection.GetTypeNameByOid(Id: Oid): string;\nvar\n  I, Index: Integer;\n  QueryHandle: PZPostgreSQLResult;\n  SQL: PAnsiChar;\n  TypeCode, BaseTypeCode: Integer;\n  TypeName: string;\n  LastVersion, IsEnum: boolean;\nbegin\n  if Closed then\n     Open;\n\n  if (GetServerMajorVersion < 7 ) or\n    ((GetServerMajorVersion = 7) and (GetServerMinorVersion < 3)) then\n    LastVersion := True\n  else\n    LastVersion := False;\n\n  { Fill the list with existed types }\n  if not Assigned(FTypeList) then\n  begin\n    if LastVersion then\n      SQL := 'SELECT oid, typname FROM pg_type WHERE oid<10000'\n    else\n      SQL := 'SELECT oid, typname, typbasetype,typtype FROM pg_type' +\n             ' WHERE (typtype = ''b'' and oid < 10000) OR typtype = ''p'' OR typtype = ''e'' OR typbasetype<>0 ORDER BY oid';\n\n    QueryHandle := GetPlainDriver.ExecuteQuery(FHandle, SQL);\n    CheckPostgreSQLError(Self, GetPlainDriver, FHandle, lcExecute, String(SQL),QueryHandle);\n    DriverManager.LogMessage(lcExecute, PlainDriver.GetProtocol, String(SQL));\n\n    FTypeList := TStringList.Create;\n    for I := 0 to GetPlainDriver.GetRowCount(QueryHandle)-1 do\n    begin\n      TypeCode := StrToIntDef(String(\n        GetPlainDriver.GetValue(QueryHandle, I, 0)), 0);\n      isEnum := LowerCase(String(GetPlainDriver.GetValue(QueryHandle, I, 3))) = 'e';\n      if isEnum then\n        TypeName := 'enum'\n      else\n        TypeName := String(GetPlainDriver.GetValue(QueryHandle, I, 1));\n\n      if LastVersion then\n        BaseTypeCode := 0\n      else\n        BaseTypeCode := StrToIntDef(String(\n          GetPlainDriver.GetValue(QueryHandle, I, 2)), 0);\n\n      if BaseTypeCode <> 0 then\n      begin\n        Index := FTypeList.IndexOfObject(TObject(BaseTypeCode));\n        if Index >= 0 then\n          TypeName := FTypeList[Index]\n        else\n          TypeName := '';\n      end;\n      FTypeList.AddObject(TypeName, TObject(TypeCode));\n    end;\n    GetPlainDriver.Clear(QueryHandle);\n  end;\n\n  I := FTypeList.IndexOfObject(TObject(Id));\n  if I >= 0 then\n    Result := FTypeList[I]\n  else\n    Result := '';\nend;\n\n{**\n  Gets the host's full version number. Initially this should be 0.\n  The format of the version returned must be XYYYZZZ where\n   X   = Major version\n   YYY = Minor version\n   ZZZ = Sub version\n  @return this server's full version number\n}\nfunction TZPostgreSQLConnection.GetHostVersion: Integer;\nbegin\n Result := GetServerMajorVersion*1000000+GetServerMinorversion*1000+GetServerSubversion;\nend;\n\n{**\n  Gets a server major version.\n  @return a server major version number.\n}\nfunction TZPostgreSQLConnection.GetServerMajorVersion: Integer;\nbegin\n  if (FServerMajorVersion = 0) and (FServerMinorVersion = 0) then\n    LoadServerVersion;\n  Result := FServerMajorVersion;\nend;\n\n{**\n  Gets a server minor version.\n  @return a server minor version number.\n}\nfunction TZPostgreSQLConnection.GetServerMinorVersion: Integer;\nbegin\n  if (FServerMajorVersion = 0) and (FServerMinorVersion = 0) then\n    LoadServerVersion;\n  Result := FServerMinorVersion;\nend;\n\n{**\n  Gets a server sub version.\n  @return a server sub version number.\n}\nfunction TZPostgreSQLConnection.GetServerSubVersion: Integer;\nbegin\n  if (FServerMajorVersion = 0) and (FServerMinorVersion = 0) then\n    LoadServerVersion;\n  Result := FServerSubVersion;\nend;\n\n{**\n  Loads a server major and minor version numbers.\n}\nprocedure TZPostgreSQLConnection.LoadServerVersion;\nvar\n  Temp: string;\n  List: TStrings;\n  QueryHandle: PZPostgreSQLResult;\n  SQL: PAnsiChar;\nbegin\n  if Closed then\n    Open;\n  SQL := 'SELECT version()';\n  QueryHandle := GetPlainDriver.ExecuteQuery(FHandle, SQL);\n  CheckPostgreSQLError(Self, GetPlainDriver, FHandle, lcExecute, String(SQL),QueryHandle);\n  DriverManager.LogMessage(lcExecute, PlainDriver.GetProtocol, String(SQL));\n\n  Temp := String(GetPlainDriver.GetValue(QueryHandle, 0, 0));\n  GetPlainDriver.Clear(QueryHandle);\n\n  List := TStringList.Create;\n  try\n    { Splits string by space }\n    PutSplitString(List, Temp, ' ');\n    { first - PostgreSQL, second X.Y.Z}\n    Temp := List.Strings[1];\n    { Splits string by dot }\n    PutSplitString(List, Temp, '.');\n\n    FServerMajorVersion := StrToIntDef(List.Strings[0], 0);\n    if List.Count > 1 then\n      FServerMinorVersion := GetMinorVersion(List.Strings[1])\n    else\n      FServerMinorVersion := 0;\n    if List.Count > 2 then\n      FServerSubVersion := GetMinorVersion(List.Strings[2])\n    else\n      FServerSubVersion := 0;\n  finally\n    List.Free;\n  end;\nend;\n\n{** \nPing Current Connection's server, if client was disconnected, \nthe connection is resumed. \n@return 0 if succesfull or error code if any error occurs \n} \nfunction TZPostgreSQLConnection.PingServer: Integer; \nconst \n  PING_ERROR_ZEOSCONNCLOSED = -1; \nvar \n  Closing: boolean;\n  res: PZPostgreSQLResult;\n  isset: boolean;\nbegin\n  Result := PING_ERROR_ZEOSCONNCLOSED;\n  Closing := FHandle = nil;\n  if Not(Closed or Closing) then\n  begin\n    res := GetPlainDriver.ExecuteQuery(FHandle,'');\n    isset := assigned(res);\n    GetPlainDriver.Clear(res);\n    if isset and (GetPlainDriver.GetStatus(FHandle) = CONNECTION_OK) then\n      Result := 0\n    else\n      try\n        GetPlainDriver.Reset(FHandle);\n        res := GetPlainDriver.ExecuteQuery(FHandle,'');\n        isset := assigned(res);\n        GetPlainDriver.Clear(res);\n        if isset and (GetPlainDriver.GetStatus(FHandle) = CONNECTION_OK) then\n          Result := 0;\n      except\n        Result := 1;\n      end;\n  end;\nend;\n\nfunction TZPostgreSQLConnection.EscapeString(Value: RawByteString): RawByteString;\nbegin\n  Result := PlainDriver.EscapeString(Self.FHandle, Value, ConSettings)\nend;\n{**\n  Creates a sequence generator object.\n  @param Sequence a name of the sequence generator.\n  @param BlockSize a number of unique keys requested in one trip to SQL server.\n  @returns a created sequence object.\n}\nfunction TZPostgreSQLConnection.CreateSequence(const Sequence: string;\n  BlockSize: Integer): IZSequence;\nbegin\n  Result := TZPostgreSQLSequence.Create(Self, Sequence, BlockSize);\nend;\n\n{**\n  EgonHugeist:\n  Returns the BinaryString in a Tokenizer-detectable kind\n  If the Tokenizer don't need to predetect it Result = BinaryString\n  @param Value represents the Binary-String\n  @param EscapeMarkSequence represents a Tokenizer detectable EscapeSequence (Len >= 3)\n  @result the detectable Binary String\n}\nfunction TZPostgreSQLConnection.GetBinaryEscapeString(const Value: RawByteString): String;\nbegin\n  Result := String(EncodeBinary(Value));\n  if GetAutoEncodeStrings then\n    Result := GetDriver.GetTokenizer.GetEscapeString(Result);\nend;\n\n{**\n  EgonHugeist:\n  Returns the BinaryString in a Tokenizer-detectable kind\n  If the Tokenizer don't need to predetect it Result = BinaryString\n  @param Value represents the Binary-String\n  @param EscapeMarkSequence represents a Tokenizer detectable EscapeSequence (Len >= 3)\n  @result the detectable Binary String\n}\nfunction TZPostgreSQLConnection.GetBinaryEscapeString(const Value: TByteDynArray): String;\nvar Tmp: RawByteString;\nbegin\n  ZSetString(PAnsiChar(Value), Length(Value), Tmp);\n  Result := String(EncodeBinary(Tmp));\n  if GetAutoEncodeStrings then\n    Result := GetDriver.GetTokenizer.GetEscapeString(Result);\nend;\n\n{**\n  EgonHugeist:\n  Returns a String in a Tokenizer-detectable kind\n  If the Tokenizer don't need to predetect it Result = BinaryString\n  @param Value represents the String\n  @param EscapeMarkSequence represents a Tokenizer detectable EscapeSequence (Len >= 3)\n  @result the detectable Postrgres-compatible String\n}\nfunction TZPostgreSQLConnection.GetEscapeString(const Value: ZWideString): ZWideString;\nbegin\n  Result := GetPlainDriver.EscapeString(FHandle, Value, ConSettings);\n  if GetAutoEncodeStrings then\n    Result := GetDriver.GetTokenizer.GetEscapeString(Result);\nend;\n\nfunction TZPostgreSQLConnection.GetEscapeString(const Value: RawByteString): RawByteString;\nbegin\n  Result := GetPlainDriver.EscapeString(FHandle, Value, ConSettings);\n  {$IFNDEF UNICODE}\n  if GetAutoEncodeStrings then\n    Result := GetDriver.GetTokenizer.GetEscapeString(Result);\n  {$ENDIF}\nend;\n\n{**\n  Gets a current setting of run-time parameter.\n  @param AName a parameter name.\n  @result a parmeter value retrieved from server.\n}\nfunction TZPostgreSQLConnection.GetServerSetting(const AName: string): string;\nvar\n  SQL: string;\n  QueryHandle: PZPostgreSQLResult;\nbegin\n  SQL := Format('select setting from pg_settings where name = %s', [AName]);\n  QueryHandle := GetPlainDriver.ExecuteQuery(FHandle, PAnsiChar({$IFDEF UNICODE}AnsiString{$ENDIF}(SQL)));\n  CheckPostgreSQLError(Self, GetPlainDriver, FHandle, lcExecute, SQL, QueryHandle);\n  DriverManager.LogMessage(lcExecute, PlainDriver.GetProtocol, SQL);\n\n  Result := String(GetPlainDriver.GetValue(QueryHandle, 0, 0));\n  GetPlainDriver.Clear(QueryHandle);\nend;\n\nprocedure TZPostgreSQLConnection.OnPropertiesChange(Sender: TObject);\nvar\n  SCS: string;\nbegin\n  inherited OnPropertiesChange(Sender);\n\n  { Define standard_conforming_strings setting}\n  SCS := Trim(Info.Values[standard_conforming_strings]);\n  if SCS <> '' then\n    SetStandardConformingStrings(UpperCase(SCS) = FON)\n  else\n    SetStandardConformingStrings(GetPlainDriver.GetStandardConformingStrings);\nend;\n\n{**\n  Sets current setting of run-time parameter.\n  String values should be already quoted.\n  @param AName a parameter name.\n  @param AValue a new parameter value.\n}\nprocedure TZPostgreSQLConnection.SetServerSetting(const AName, AValue: string);\nvar\n  SQL: string;\n  QueryHandle: PZPostgreSQLResult;\nbegin\n  SQL := Format('SET %s = %s', [AName, AValue]);\n  QueryHandle := GetPlainDriver.ExecuteQuery(FHandle, PAnsiChar(AnsiString(SQL)));\n  CheckPostgreSQLError(Self, GetPlainDriver, FHandle, lcExecute, SQL, QueryHandle);\n  DriverManager.LogMessage(lcExecute, PlainDriver.GetProtocol, SQL);\n\n  GetPlainDriver.Clear(QueryHandle);\nend;\n\n{$IFDEF ZEOS_TEST_ONLY}\nconstructor TZPostgreSQLConnection.Create(const ZUrl: TZURL);\nbegin\n inherited Create(ZUrl);\nend;\n{$ENDIF}\n\nprocedure TZPostgreSQLConnection.SetStandardConformingStrings(const Value: Boolean);\nbegin\n  FStandardConformingStrings := Value;\n  ( Self.GetDriver.GetTokenizer as IZPostgreSQLTokenizer ).SetStandardConformingStrings(FStandardConformingStrings);\nend;\n\n\n{ TZPostgreSQLSequence }\n{**\n  Gets the current unique key generated by this sequence.\n  @param the last generated unique key.\n}\nfunction TZPostgreSQLSequence.GetCurrentValue: Int64;\nvar\n  Statement: IZStatement;\n  ResultSet: IZResultSet;\nbegin\n  Statement := Connection.CreateStatement;\n  ResultSet := Statement.ExecuteQuery(\n    Format('SELECT CURRVAL(''%s'')', [Name]));\n  if ResultSet.Next then\n    Result := ResultSet.GetLong(1)\n  else\n    Result := inherited GetCurrentValue;\n  ResultSet.Close;\n  Statement.Close;\nend;\n\n{**\n  Gets the next unique key generated by this sequence.\n  @param the next generated unique key.\n}\nfunction TZPostgreSQLSequence.GetCurrentValueSQL: String;\nbegin\n  result:=Format(' CURRVAL(''%s'') ', [Name]);\nend;\n\nfunction TZPostgreSQLSequence.GetNextValue: Int64;\nvar\n  Statement: IZStatement;\n  ResultSet: IZResultSet;\nbegin\n  Statement := Connection.CreateStatement;\n  ResultSet := Statement.ExecuteQuery(\n    Format('SELECT NEXTVAL(''%s'')', [Name]));\n  if ResultSet.Next then\n    Result := ResultSet.GetLong(1)\n  else\n    Result := inherited GetNextValue;\n  ResultSet.Close;\n  Statement.Close;\nend;\n\nfunction TZPostgreSQLSequence.GetNextValueSQL: String;\nbegin\n result:=Format(' NEXTVAL(''%s'') ', [Name]);\nend;\n\ninitialization\n  PostgreSQLDriver := TZPostgreSQLDriver.Create;\n  DriverManager.RegisterDriver(PostgreSQLDriver);\nfinalization\n  if DriverManager <> nil then\n    DriverManager.DeregisterDriver(PostgreSQLDriver);\n  PostgreSQLDriver := nil;\nend.\n\n"
  },
  {
    "path": "lib/zeosdbo/src/dbc/ZDbcPostgreSqlMetadata.pas",
    "content": "{*********************************************************}\n{                                                         }\n{                 Zeos Database Objects                   }\n{         PostgreSQL Database Connectivity Classes        }\n{                                                         }\n{         Originally written by Sergey Seroukhov          }\n{                           and Sergey Merkuriev          }\n{                                                         }\n{*********************************************************}\n\n{@********************************************************}\n{    Copyright (c) 1999-2012 Zeos Development Group       }\n{                                                         }\n{ License Agreement:                                      }\n{                                                         }\n{ This library is distributed in the hope that it will be }\n{ useful, but WITHOUT ANY WARRANTY; without even the      }\n{ implied warranty of MERCHANTABILITY or FITNESS FOR      }\n{ A PARTICULAR PURPOSE.  See the GNU Lesser General       }\n{ Public License for more details.                        }\n{                                                         }\n{ The source code of the ZEOS Libraries and packages are  }\n{ distributed under the Library GNU General Public        }\n{ License (see the file COPYING / COPYING.ZEOS)           }\n{ with the following  modification:                       }\n{ As a special exception, the copyright holders of this   }\n{ library give you permission to link this library with   }\n{ independent modules to produce an executable,           }\n{ regardless of the license terms of these independent    }\n{ modules, and to copy and distribute the resulting       }\n{ executable under terms of your choice, provided that    }\n{ you also meet, for each linked independent module,      }\n{ the terms and conditions of the license of that module. }\n{ An independent module is a module which is not derived  }\n{ from or based on this library. If you modify this       }\n{ library, you may extend this exception to your version  }\n{ of the library, but you are not obligated to do so.     }\n{ If you do not wish to do so, delete this exception      }\n{ statement from your version.                            }\n{                                                         }\n{                                                         }\n{ The project web site is located on:                     }\n{   http://zeos.firmos.at  (FORUM)                        }\n{   http://sourceforge.net/p/zeoslib/tickets/ (BUGTRACKER)}\n{   svn://svn.code.sf.net/p/zeoslib/code-0/trunk (SVN)    }\n{                                                         }\n{   http://www.sourceforge.net/projects/zeoslib.          }\n{                                                         }\n{                                                         }\n{                                 Zeos Development Group. }\n{********************************************************@}\n\nunit ZDbcPostgreSqlMetadata;\n\ninterface\n\n{$I ZDbc.inc}\n\nuses\n  Types, Classes, {$IFDEF MSEgui}mclasses,{$ENDIF} SysUtils,\n  ZSysUtils, ZDbcIntfs, ZDbcMetadata, ZCompatibility, ZDbcPostgreSqlUtils,\n  ZDbcConnection, ZSelectSchema;\n\ntype\n  {** Implements a PostgreSQL Case Sensitive/Unsensitive identifier convertor. }\n  TZPostgreSQLIdentifierConvertor = class (TZDefaultIdentifierConvertor)\n  protected\n    function IsSpecialCase(const Value: string): Boolean; override;\n  public\n    function IsQuoted(const Value: string): Boolean; override;\n    function Quote(const Value: string): string; override;\n    function ExtractQuote(const Value: string): string; override; \n  end; \n \n  {**\n    Database information interface for PostgreSQL. Adds some PostgreSQL-specific\n     methods to IZDatabaseInfo.\n  } // technobot 2008-06-27\n  IZPostgreSQLDatabaseInfo = interface(IZDatabaseInfo)\n    ['{7D48BBAA-FAE2-48EA-8B9E-663CCA5690EC}']\n    // database and driver info:\n    function HasMinimumServerVersion(MajorVersion: Integer;\n      MinorVersion: Integer): Boolean;\n  end;\n  IZPostgreDBInfo = IZPostgreSQLDatabaseInfo; // shorthand alias\n\n  // technobot 2008-06-27 - methods moved as is from TZPostgreSQLDatabaseMetadata:\n  {** Implements PostgreSQL Database Information. }\n  TZPostgreSQLDatabaseInfo = class(TZAbstractDatabaseInfo, IZPostgreSQLDatabaseInfo)\n  protected\n    function GetMaxIndexKeys: Integer;\n    function GetMaxNameLength: Integer;\n//    function UncachedGetUDTs(const Catalog: string; const SchemaPattern: string;\n//      const TypeNamePattern: string; const Types: TIntegerDynArray): IZResultSet; override;\n  public\n    constructor Create(const Metadata: TZAbstractDatabaseMetadata);\n    destructor Destroy; override;\n\n    // database/driver/server info:\n    function GetDatabaseProductName: string; override;\n    function GetDatabaseProductVersion: string; override;\n    function GetDriverName: string; override;\n//    function GetDriverVersion: string; override; -> Same as parent\n    function GetDriverMajorVersion: Integer; override;\n    function GetDriverMinorVersion: Integer; override;\n    function GetServerVersion: string;\n    function HasMinimumServerVersion(MajorVersion: Integer;\n      MinorVersion: Integer): Boolean; // was TZPostgreSQLDatabaseMetadata.HaveMinimumServerVersion\n\n    // capabilities (what it can/cannot do):\n//    function AllProceduresAreCallable: Boolean; override; -> Not implemented\n//    function AllTablesAreSelectable: Boolean; override; -> Not implemented\n    function SupportsMixedCaseIdentifiers: Boolean; override;\n    function SupportsMixedCaseQuotedIdentifiers: Boolean; override;\n//    function SupportsAlterTableWithAddColumn: Boolean; override; -> Not implemented\n//    function SupportsAlterTableWithDropColumn: Boolean; override; -> Not implemented\n//    function SupportsColumnAliasing: Boolean; override; -> Not implemented\n//    function SupportsConvert: Boolean; override; -> Not implemented\n//    function SupportsConvertForTypes(FromType: TZSQLType; ToType: TZSQLType):\n//      Boolean; override; -> Not implemented\n//    function SupportsTableCorrelationNames: Boolean; override; -> Not implemented\n//    function SupportsDifferentTableCorrelationNames: Boolean; override; -> Not implemented\n    function SupportsExpressionsInOrderBy: Boolean; override;\n    function SupportsOrderByUnrelated: Boolean; override;\n    function SupportsGroupBy: Boolean; override;\n    function SupportsGroupByUnrelated: Boolean; override;\n    function SupportsGroupByBeyondSelect: Boolean; override;\n//    function SupportsLikeEscapeClause: Boolean; override; -> Not implemented\n//    function SupportsMultipleResultSets: Boolean; override; -> Not implemented\n//    function SupportsMultipleTransactions: Boolean; override; -> Not implemented\n//    function SupportsNonNullableColumns: Boolean; override; -> Not implemented\n//    function SupportsMinimumSQLGrammar: Boolean; override; -> Not implemented\n//    function SupportsCoreSQLGrammar: Boolean; override; -> Not implemented\n//    function SupportsExtendedSQLGrammar: Boolean; override; -> Not implemented\n//    function SupportsANSI92EntryLevelSQL: Boolean; override; -> Not implemented\n//    function SupportsANSI92IntermediateSQL: Boolean; override; -> Not implemented\n//    function SupportsANSI92FullSQL: Boolean; override; -> Not implemented\n    function SupportsIntegrityEnhancementFacility: Boolean; override;\n//    function SupportsOuterJoins: Boolean; override; -> Not implemented\n//    function SupportsFullOuterJoins: Boolean; override; -> Not implemented\n//    function SupportsLimitedOuterJoins: Boolean; override; -> Not implemented\n    function SupportsSchemasInDataManipulation: Boolean; override;\n    function SupportsSchemasInProcedureCalls: Boolean; override;\n    function SupportsSchemasInTableDefinitions: Boolean; override;\n    function SupportsSchemasInIndexDefinitions: Boolean; override;\n    function SupportsSchemasInPrivilegeDefinitions: Boolean; override;\n    function SupportsCatalogsInDataManipulation: Boolean; override;\n    function SupportsCatalogsInProcedureCalls: Boolean; override;\n    function SupportsCatalogsInTableDefinitions: Boolean; override;\n    function SupportsCatalogsInIndexDefinitions: Boolean; override;\n    function SupportsCatalogsInPrivilegeDefinitions: Boolean; override;\n    function SupportsPositionedDelete: Boolean; override;\n    function SupportsPositionedUpdate: Boolean; override;\n    function SupportsSelectForUpdate: Boolean; override;\n    function SupportsStoredProcedures: Boolean; override;\n    function SupportsSubqueriesInComparisons: Boolean; override;\n    function SupportsSubqueriesInExists: Boolean; override;\n    function SupportsSubqueriesInIns: Boolean; override;\n    function SupportsSubqueriesInQuantifieds: Boolean; override;\n    function SupportsCorrelatedSubqueries: Boolean; override;\n    function SupportsUnion: Boolean; override;\n    function SupportsUnionAll: Boolean; override;\n    function SupportsOpenCursorsAcrossCommit: Boolean; override;\n    function SupportsOpenCursorsAcrossRollback: Boolean; override;\n    function SupportsOpenStatementsAcrossCommit: Boolean; override;\n    function SupportsOpenStatementsAcrossRollback: Boolean; override;\n    function SupportsTransactions: Boolean; override;\n    function SupportsTransactionIsolationLevel(Level: TZTransactIsolationLevel):\n      Boolean; override;\n    function SupportsDataDefinitionAndDataManipulationTransactions: Boolean; override;\n    function SupportsDataManipulationTransactionsOnly: Boolean; override;\n    function SupportsResultSetType(_Type: TZResultSetType): Boolean; override;\n    function SupportsResultSetConcurrency(_Type: TZResultSetType;\n      Concurrency: TZResultSetConcurrency): Boolean; override;\n//    function SupportsBatchUpdates: Boolean; override; -> Not implemented\n\n    // maxima:\n    function GetMaxBinaryLiteralLength: Integer; override;\n    function GetMaxCharLiteralLength: Integer; override;\n    function GetMaxColumnNameLength: Integer; override;\n    function GetMaxColumnsInGroupBy: Integer; override;\n    function GetMaxColumnsInIndex: Integer; override;\n    function GetMaxColumnsInOrderBy: Integer; override;\n    function GetMaxColumnsInSelect: Integer; override;\n    function GetMaxColumnsInTable: Integer; override;\n    function GetMaxConnections: Integer; override;\n    function GetMaxCursorNameLength: Integer; override;\n    function GetMaxIndexLength: Integer; override;\n    function GetMaxSchemaNameLength: Integer; override;\n    function GetMaxProcedureNameLength: Integer; override;\n    function GetMaxCatalogNameLength: Integer; override;\n    function GetMaxRowSize: Integer; override;\n    function GetMaxStatementLength: Integer; override;\n    function GetMaxStatements: Integer; override;\n    function GetMaxTableNameLength: Integer; override;\n    function GetMaxTablesInSelect: Integer; override;\n    function GetMaxUserNameLength: Integer; override;\n\n    // policies (how are various data and operations handled):\n//    function IsReadOnly: Boolean; override; -> Not implemented\n//    function IsCatalogAtStart: Boolean; override; -> Not implemented\n    function DoesMaxRowSizeIncludeBlobs: Boolean; override;\n//    function NullsAreSortedHigh: Boolean; override; -> Not implemented\n//    function NullsAreSortedLow: Boolean; override; -> Not implemented\n//    function NullsAreSortedAtStart: Boolean; override; -> Not implemented\n//    function NullsAreSortedAtEnd: Boolean; override; -> Not implemented\n//    function NullPlusNonNullIsNull: Boolean; override; -> Not implemented\n//    function UsesLocalFiles: Boolean; override; -> Not implemented\n    function UsesLocalFilePerTable: Boolean; override;\n    function StoresUpperCaseIdentifiers: Boolean; override;\n    function StoresLowerCaseIdentifiers: Boolean; override;\n    function StoresMixedCaseIdentifiers: Boolean; override;\n    function StoresUpperCaseQuotedIdentifiers: Boolean; override;\n    function StoresLowerCaseQuotedIdentifiers: Boolean; override;\n    function StoresMixedCaseQuotedIdentifiers: Boolean; override;\n    function GetDefaultTransactionIsolation: TZTransactIsolationLevel; override;\n    function DataDefinitionCausesTransactionCommit: Boolean; override;\n    function DataDefinitionIgnoredInTransactions: Boolean; override;\n\n    // interface details (terms, keywords, etc):\n    function GetSchemaTerm: string; override;\n    function GetProcedureTerm: string; override;\n    function GetCatalogTerm: string; override;\n    function GetCatalogSeparator: string; override;\n    function GetSQLKeywords: string; override;\n    function GetNumericFunctions: string; override;\n    function GetStringFunctions: string; override;\n    function GetSystemFunctions: string; override;\n    function GetTimeDateFunctions: string; override;\n    function GetSearchStringEscape: string; override;\n    function GetExtraNameCharacters: string; override;\n  end;\n\n  {** Implements PostgreSQL Database Metadata. }\n  TZPostgreSQLDatabaseMetadata = class(TZAbstractDatabaseMetadata)\n  private\n    function GetRuleType(const Rule: String): TZImportedKey;\n  protected\n    function CreateDatabaseInfo: IZDatabaseInfo; override; // technobot 2008-06-27\n\n    // (technobot) should any of these be moved to TZPostgreSQLDatabaseInfo?:\n    function GetPostgreSQLType(Oid: Integer): string;\n    function GetSQLTypeByOid(Oid: Integer): TZSQLType;\n    function GetSQLTypeByName(TypeName: string): TZSQLType;\n    function TableTypeSQLExpression(TableType: string; UseSchemas: Boolean):\n      string;\n    procedure ParseACLArray(List: TStrings; AclString: string);\n    function GetPrivilegeName(Permission: char): string;\n    // (technobot) end of questioned section\n\n    function EscapeString(const S: string): string; override;\n    function UncachedGetTables(const Catalog: string; const SchemaPattern: string;\n      const TableNamePattern: string; const Types: TStringDynArray): IZResultSet; override;\n    function UncachedGetSchemas: IZResultSet; override;\n    function UncachedGetCatalogs: IZResultSet; override;\n    function UncachedGetTableTypes: IZResultSet; override;\n    function UncachedGetColumns(const Catalog: string; const SchemaPattern: string;\n      const TableNamePattern: string; const ColumnNamePattern: string): IZResultSet; override;\n    function UncachedGetTablePrivileges(const Catalog: string; const SchemaPattern: string;\n      const TableNamePattern: string): IZResultSet; override;\n    function UncachedGetColumnPrivileges(const Catalog: string; const Schema: string;\n      const Table: string; const ColumnNamePattern: string): IZResultSet; override;\n    function UncachedGetPrimaryKeys(const Catalog: string; const Schema: string;\n      const Table: string): IZResultSet; override;\n    function UncachedGetImportedKeys(const Catalog: string; const Schema: string;\n      const Table: string): IZResultSet; override;\n    function UncachedGetExportedKeys(const Catalog: string; const Schema: string;\n      const Table: string): IZResultSet; override;\n    function UncachedGetCrossReference(const PrimaryCatalog: string; const PrimarySchema: string;\n      const PrimaryTable: string; const ForeignCatalog: string; const ForeignSchema: string;\n      const ForeignTable: string): IZResultSet; override;\n    function UncachedGetIndexInfo(const Catalog: string; const Schema: string; const Table: string;\n      Unique: Boolean; Approximate: Boolean): IZResultSet; override;\n     function UncachedGetSequences(const Catalog: string; const SchemaPattern: string;\n      const SequenceNamePattern: string): IZResultSet; override;\n    function UncachedGetProcedures(const Catalog: string; const SchemaPattern: string;\n      const ProcedureNamePattern: string): IZResultSet; override;\n    function UncachedGetProcedureColumns(const Catalog: string; const SchemaPattern: string;\n      const ProcedureNamePattern: string; const ColumnNamePattern: string):\n      IZResultSet; override;\n    function UncachedGetVersionColumns(const Catalog: string; const Schema: string;\n      const Table: string): IZResultSet; override;\n    function UncachedGetTypeInfo: IZResultSet; override;\n    function UncachedGetCharacterSets: IZResultSet; override; //EgonHugeist\n\n  public\n    destructor Destroy; override;\n    function GetIdentifierConvertor: IZIdentifierConvertor; override; \n end;\n\nimplementation\n\nuses\n  ZMessages, ZDbcUtils, ZDbcPostgreSql;\n\n{ TZPostgreSQLDatabaseInfo }\n\n{**\n  Constructs this object.\n  @param Metadata the interface of the correpsonding database metadata object\n}\nconstructor TZPostgreSQLDatabaseInfo.Create(const Metadata: TZAbstractDatabaseMetadata);\nbegin\n  inherited;\nend;\n\n{**\n  Destroys this object and cleanups the memory.\n}\ndestructor TZPostgreSQLDatabaseInfo.Destroy;\nbegin\n  inherited;\nend;\n\n//----------------------------------------------------------------------\n// First, a variety of minor information about the target database.\n\n{**\n  What's the name of this database product?\n  @return database product name\n}\nfunction TZPostgreSQLDatabaseInfo.GetDatabaseProductName: string;\nbegin\n  Result := 'PostgreSQL';\nend;\n\n{**\n  What's the version of this database product?\n  @return database version\n}\nfunction TZPostgreSQLDatabaseInfo.GetDatabaseProductVersion: string;\nbegin\n  Result := '';\nend;\n\n{**\n  What's the name of this JDBC driver?\n  @return JDBC driver name\n}\nfunction TZPostgreSQLDatabaseInfo.GetDriverName: string;\nbegin\n  Result := 'Zeos Database Connectivity Driver for PostgreSQL';\nend;\n\n{**\n  What's this JDBC driver's major version number?\n  @return JDBC driver major version\n}\nfunction TZPostgreSQLDatabaseInfo.GetDriverMajorVersion: Integer;\nbegin\n  Result := 1;\nend;\n\n{**\n  What's this JDBC driver's minor version number?\n  @return JDBC driver minor version number\n}\nfunction TZPostgreSQLDatabaseInfo.GetDriverMinorVersion: Integer;\nbegin\n  Result := 1;\nend;\n\n{**\n  Returns the server version\n  @return the server version string\n}\nfunction TZPostgreSQLDatabaseInfo.GetServerVersion: string;\nbegin\n  with Metadata.GetConnection as IZPostgreSQLConnection do\n    Result := Format('%s.%s', [GetServerMajorVersion, GetServerMinorVersion]);\nend;\n\n{**\n  Does the database use a file for each table?\n  @return true if the database uses a local file for each table\n}\nfunction TZPostgreSQLDatabaseInfo.UsesLocalFilePerTable: Boolean;\nbegin\n  Result := False;\nend;\n\n{**\n  Does the database treat mixed case unquoted SQL identifiers as\n  case sensitive and as a result store them in mixed case?\n  A JDBC Compliant<sup><font size=-2>TM</font></sup> driver will always return false.\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZPostgreSQLDatabaseInfo.SupportsMixedCaseIdentifiers: Boolean;\nbegin\n  Result := False;\nend;\n\n{**\n  Does the database treat mixed case unquoted SQL identifiers as\n  case insensitive and store them in upper case?\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZPostgreSQLDatabaseInfo.StoresUpperCaseIdentifiers: Boolean;\nbegin\n  Result := False;\nend;\n\n{**\n  Does the database treat mixed case unquoted SQL identifiers as\n  case insensitive and store them in lower case?\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZPostgreSQLDatabaseInfo.StoresLowerCaseIdentifiers: Boolean;\nbegin\n  Result := True;\nend;\n\n{**\n  Does the database treat mixed case unquoted SQL identifiers as\n  case insensitive and store them in mixed case?\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZPostgreSQLDatabaseInfo.StoresMixedCaseIdentifiers: Boolean;\nbegin\n  Result := False;\nend;\n\n{**\n  Does the database treat mixed case quoted SQL identifiers as\n  case sensitive and as a result store them in mixed case?\n  A JDBC Compliant<sup><font size=-2>TM</font></sup> driver will always return true.\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZPostgreSQLDatabaseInfo.SupportsMixedCaseQuotedIdentifiers: Boolean;\nbegin\n  Result := True;\nend;\n\n{**\n  Does the database treat mixed case quoted SQL identifiers as\n  case insensitive and store them in upper case?\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZPostgreSQLDatabaseInfo.StoresUpperCaseQuotedIdentifiers: Boolean;\nbegin\n  Result := False;\nend;\n\n{**\n  Does the database treat mixed case quoted SQL identifiers as\n  case insensitive and store them in lower case?\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZPostgreSQLDatabaseInfo.StoresLowerCaseQuotedIdentifiers: Boolean;\nbegin\n  Result := False;\nend;\n\n{**\n  Does the database treat mixed case quoted SQL identifiers as\n  case insensitive and store them in mixed case?\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZPostgreSQLDatabaseInfo.StoresMixedCaseQuotedIdentifiers: Boolean;\nbegin\n  Result := True;\nend;\n\n{**\n  Gets a comma-separated list of all a database's SQL keywords\n  that are NOT also SQL92 keywords.\n  @return the list\n}\nfunction TZPostgreSQLDatabaseInfo.GetSQLKeywords: string;\nbegin\n  Result := 'abort,absolute,access,action,add,admin,after,aggregate,all,also,'+\n            'alter,always,analyse,analyze,and,any,array,asc,assertion,assignment,'+\n            'asymmetric,at,authorization,'+\n            'backward,before,begin,between,bigint,binary,bit,boolean,both,'+\n            'cache,called,cascade,cascaded,case,cast,catalog,chain,character,'+\n            'characteristics,check,checkpoint,class,close,cluster,coalesce,'+\n            'collate,column,comment,commit,committed,concurrently,configuration,'+\n            'connect,connection,constraint,constraints,content,continue,'+\n            'conversion,convert,copy,cost,createdb,createrole,createuser,cross,'+\n            'csv,current,current_catalog,current_date,current_role,current_schema,'+\n            'current_time,current_timestamp,current_user,cursor,cycle,'+\n            'data,database,day,deallocate,dec,decimal,declare,default,defaults,'+\n            'deferrable,deferred,definer,delimiter,delimiters,desc,dictionary,'+\n            'disable,discard,distinct,do,document,domain,double,'+\n            'each,else,enable,encoding,encrypted,end,end-exec,enum,escape,except,'+\n            'excluding,exclusive,exec,execute,exists,explain,external,extract,'+\n            'false,family,fetch,first,float,following,for,force,foreign,forward,'+\n            'freeze,full,function,'+\n            'global,grant,granted,greatest,'+\n            'handler,header,hold,hour,'+\n            'identity,if,ilike,immediate,immutable,implicit,in,including,'+\n            'increment,indexes,inherit,inherits,initially,inner,inout,input,'+\n            'insensitive,instead,int,intersect,interval,invoker,isnull,isolation,'+\n            'join,'+\n            'lancompiler,language,large,last,lc_collate,lc_ctype,leading,least,'+\n            'left,level,like,limit,listen,load,local,localtime,localtimestamp,'+\n            'location,lock,login,'+\n            'mapping,match,maxvalue,minute,minvalue,mode,month,move,'+\n            'name,names,national,natural,nchar,new,next,no,nocreatedb,nocreaterole,'+\n            'nocreateuser,noinherit,nologin,none,nosuperuser,not,nothing,notify,'+\n            'notnull,nowait,nullif,nulls,numeric,'+\n            'object,of,off,offset,oids,old,only,operator,option,options,or,out,'+\n            'outer,over,overlaps,overlay,owned,owner,'+\n            'parser,partial,partition,password,placing,plans,position,preceding,'+\n            'precision,prepare,prepared,preserve,prior,privileges,procedural,'+\n            'procedure,'+\n            'quote,'+\n            'range,read,real,reassign,recheck,recursive,references,reindex,'+\n            'relative,release,rename,repeatable,replace,replica,reset,restart,'+\n            'restrict,return,returning,returns,revoke,right,role,rollback,row,'+\n            'rows,rule,'+\n            'savepoint,schema,scroll,search,second,security,sequence,serializable,'+\n            'server,session,session_user,setof,share,show,similar,simple,smallint,'+\n            'some,stable,standalone,start,statement,statistics,stdin,stdout,'+\n            'storage,strict,strip,substring,superuser,symmetric,sysid,system,'+\n            'tablespace,temp,template,temporary,text,then,time,timestamp,to,'+\n            'trailing,transaction,treat,trigger,trim,true,truncate,trusted,type,'+\n            'unbounded,uncommitted,unencrypted,union,unique,unknown,unlisten,'+\n            'until,user,using,'+\n            'vacuum,valid,validator,value,variadic,varying,verbose,version,view,'+\n            'volatile,'+\n            'when,whitespace,window,with,without,work,wrapper,write,'+\n            'xml,xmlattributes,xmlconcat,xmlelement,xmlforest,xmlparse,xmlpi,'+\n            'xmlroot,xmlserialize,'+\n            'year,yes,'+\n            'zone';\nend;\n\n{**\n  Gets a comma-separated list of math functions.  These are the\n  X/Open CLI math function names used in the JDBC function escape\n  clause.\n  @return the list\n}\nfunction TZPostgreSQLDatabaseInfo.GetNumericFunctions: string;\nbegin\n  Result := '';\nend;\n\n{**\n  Gets a comma-separated list of string functions.  These are the\n  X/Open CLI string function names used in the JDBC function escape\n  clause.\n  @return the list\n}\nfunction TZPostgreSQLDatabaseInfo.GetStringFunctions: string;\nbegin\n  Result := '';\nend;\n\n{**\n  Gets a comma-separated list of system functions.  These are the\n  X/Open CLI system function names used in the JDBC function escape\n  clause.\n  @return the list\n}\nfunction TZPostgreSQLDatabaseInfo.GetSystemFunctions: string;\nbegin\n  Result := '';\nend;\n\n{**\n  Gets a comma-separated list of time and date functions.\n  @return the list\n}\nfunction TZPostgreSQLDatabaseInfo.GetTimeDateFunctions: string;\nbegin\n  Result := '';\nend;\n\n{**\n  Gets the string that can be used to escape wildcard characters.\n  This is the string that can be used to escape '_' or '%' in\n  the string pattern style catalog search parameters.\n\n  <P>The '_' character represents any single character.\n  <P>The '%' character represents any sequence of zero or\n  more characters.\n\n  @return the string used to escape wildcard characters\n}\nfunction TZPostgreSQLDatabaseInfo.GetSearchStringEscape: string;\nbegin\n  Result := '\\';\nend;\n\n{**\n  Gets all the \"extra\" characters that can be used in unquoted\n  identifier names (those beyond a-z, A-Z, 0-9 and _).\n  @return the string containing the extra characters\n}\nfunction TZPostgreSQLDatabaseInfo.GetExtraNameCharacters: string;\nbegin\n  Result := '';\nend;\n\n//--------------------------------------------------------------------\n// Functions describing which features are supported.\n\n{**\n  Are expressions in \"ORDER BY\" lists supported?\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZPostgreSQLDatabaseInfo.SupportsExpressionsInOrderBy: Boolean;\nbegin\n  Result := True;\nend;\n\n{**\n  Can an \"ORDER BY\" clause use columns not in the SELECT statement?\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZPostgreSQLDatabaseInfo.SupportsOrderByUnrelated: Boolean;\nbegin\n  Result := HasMinimumServerVersion(6, 4);\nend;\n\n{**\n  Is some form of \"GROUP BY\" clause supported?\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZPostgreSQLDatabaseInfo.SupportsGroupBy: Boolean;\nbegin\n  Result := True;\nend;\n\n{**\n  Can a \"GROUP BY\" clause use columns not in the SELECT?\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZPostgreSQLDatabaseInfo.SupportsGroupByUnrelated: Boolean;\nbegin\n  Result := HasMinimumServerVersion(6, 4);\nend;\n\n{**\n  Can a \"GROUP BY\" clause add columns not in the SELECT\n  provided it specifies all the columns in the SELECT?\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZPostgreSQLDatabaseInfo.SupportsGroupByBeyondSelect: Boolean;\nbegin\n  Result := HasMinimumServerVersion(6, 4);\nend;\n\n{**\n  Is the SQL Integrity Enhancement Facility supported?\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZPostgreSQLDatabaseInfo.SupportsIntegrityEnhancementFacility: Boolean;\nbegin\n  Result := False;\nend;\n\n{**\n  What's the database vendor's preferred term for \"schema\"?\n  @return the vendor term\n}\nfunction TZPostgreSQLDatabaseInfo.GetSchemaTerm: string;\nbegin\n  Result := 'schema';\nend;\n\n{**\n  What's the database vendor's preferred term for \"procedure\"?\n  @return the vendor term\n}\nfunction TZPostgreSQLDatabaseInfo.GetProcedureTerm: string;\nbegin\n  Result := 'function';\nend;\n\n{**\n  What's the database vendor's preferred term for \"catalog\"?\n  @return the vendor term\n}\nfunction TZPostgreSQLDatabaseInfo.GetCatalogTerm: string;\nbegin\n  Result := 'database';\nend;\n\n{**\n  What's the separator between catalog and table name?\n  @return the separator string\n}\nfunction TZPostgreSQLDatabaseInfo.GetCatalogSeparator: string;\nbegin\n  Result := '.';\nend;\n\n{**\n  Can a schema name be used in a data manipulation statement?\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZPostgreSQLDatabaseInfo.SupportsSchemasInDataManipulation: Boolean;\nbegin\n  Result := HasMinimumServerVersion(7, 3);\nend;\n\n{**\n  Can a schema name be used in a procedure call statement?\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZPostgreSQLDatabaseInfo.SupportsSchemasInProcedureCalls: Boolean;\nbegin\n  Result := HasMinimumServerVersion(7, 3);\nend;\n\n{**\n  Can a schema name be used in a table definition statement?\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZPostgreSQLDatabaseInfo.SupportsSchemasInTableDefinitions: Boolean;\nbegin\n  Result := HasMinimumServerVersion(7, 3);\nend;\n\n{**\n  Can a schema name be used in an index definition statement?\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZPostgreSQLDatabaseInfo.SupportsSchemasInIndexDefinitions: Boolean;\nbegin\n  Result := HasMinimumServerVersion(7, 3);\nend;\n\n{**\n  Can a schema name be used in a privilege definition statement?\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZPostgreSQLDatabaseInfo.SupportsSchemasInPrivilegeDefinitions: Boolean;\nbegin\n  Result := HasMinimumServerVersion(7, 3);\nend;\n\n{**\n  Can a catalog name be used in a data manipulation statement?\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZPostgreSQLDatabaseInfo.SupportsCatalogsInDataManipulation: Boolean;\nbegin\n  Result := False;\nend;\n\n{**\n  Can a catalog name be used in a procedure call statement?\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZPostgreSQLDatabaseInfo.SupportsCatalogsInProcedureCalls: Boolean;\nbegin\n  Result := HasMinimumServerVersion(7, 3);\nend;\n\n{**\n  Can a catalog name be used in a table definition statement?\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZPostgreSQLDatabaseInfo.SupportsCatalogsInTableDefinitions: Boolean;\nbegin\n  Result := HasMinimumServerVersion(7, 3);\nend;\n\n{**\n  Can a catalog name be used in an index definition statement?\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZPostgreSQLDatabaseInfo.SupportsCatalogsInIndexDefinitions: Boolean;\nbegin\n  Result := False;\nend;\n\n{**\n  Can a catalog name be used in a privilege definition statement?\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZPostgreSQLDatabaseInfo.SupportsCatalogsInPrivilegeDefinitions: Boolean;\nbegin\n  Result := False;\nend;\n\n{**\n  Is positioned DELETE supported?\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZPostgreSQLDatabaseInfo.SupportsPositionedDelete: Boolean;\nbegin\n  Result := False;\nend;\n\n{**\n  Is positioned UPDATE supported?\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZPostgreSQLDatabaseInfo.SupportsPositionedUpdate: Boolean;\nbegin\n  Result := False;\nend;\n\n{**\n  Is SELECT for UPDATE supported?\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZPostgreSQLDatabaseInfo.SupportsSelectForUpdate: Boolean;\nbegin\n  Result := HasMinimumServerVersion(6, 5);\nend;\n\n{**\n  Are stored procedure calls using the stored procedure escape\n  syntax supported?\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZPostgreSQLDatabaseInfo.SupportsStoredProcedures: Boolean;\nbegin\n  Result := False;\nend;\n\n{**\n  Are subqueries in comparison expressions supported?\n  A JDBC Compliant<sup><font size=-2>TM</font></sup> driver always returns true.\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZPostgreSQLDatabaseInfo.SupportsSubqueriesInComparisons: Boolean;\nbegin\n  Result := True;\nend;\n\n{**\n  Are subqueries in 'exists' expressions supported?\n  A JDBC Compliant<sup><font size=-2>TM</font></sup> driver always returns true.\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZPostgreSQLDatabaseInfo.SupportsSubqueriesInExists: Boolean;\nbegin\n  Result := True;\nend;\n\n{**\n  Are subqueries in 'in' statements supported?\n  A JDBC Compliant<sup><font size=-2>TM</font></sup> driver always returns true.\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZPostgreSQLDatabaseInfo.SupportsSubqueriesInIns: Boolean;\nbegin\n  Result := True;\nend;\n\n{**\n  Are subqueries in quantified expressions supported?\n  A JDBC Compliant<sup><font size=-2>TM</font></sup> driver always returns true.\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZPostgreSQLDatabaseInfo.SupportsSubqueriesInQuantifieds: Boolean;\nbegin\n  Result := True;\nend;\n\n{**\n  Are correlated subqueries supported?\n  A JDBC Compliant<sup><font size=-2>TM</font></sup> driver always returns true.\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZPostgreSQLDatabaseInfo.SupportsCorrelatedSubqueries: Boolean;\nbegin\n  Result := HasMinimumServerVersion(7, 1);\nend;\n\n{**\n  Is SQL UNION supported?\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZPostgreSQLDatabaseInfo.SupportsUnion: Boolean;\nbegin\n  Result := True;\nend;\n\n{**\n  Is SQL UNION ALL supported?\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZPostgreSQLDatabaseInfo.SupportsUnionAll: Boolean;\nbegin\n  Result := HasMinimumServerVersion(7, 1);\nend;\n\n{**\n  Can cursors remain open across commits?\n  @return <code>true</code> if cursors always remain open;\n        <code>false</code> if they might not remain open\n}\nfunction TZPostgreSQLDatabaseInfo.SupportsOpenCursorsAcrossCommit: Boolean;\nbegin\n  Result := False;\nend;\n\n{**\n  Can cursors remain open across rollbacks?\n  @return <code>true</code> if cursors always remain open;\n        <code>false</code> if they might not remain open\n}\nfunction TZPostgreSQLDatabaseInfo.SupportsOpenCursorsAcrossRollback: Boolean;\nbegin\n  Result := False;\nend;\n\n{**\n  Can statements remain open across commits?\n  @return <code>true</code> if statements always remain open;\n        <code>false</code> if they might not remain open\n}\nfunction TZPostgreSQLDatabaseInfo.SupportsOpenStatementsAcrossCommit: Boolean;\nbegin\n  Result := True;\nend;\n\n{**\n  Can statements remain open across rollbacks?\n  @return <code>true</code> if statements always remain open;\n        <code>false</code> if they might not remain open\n}\nfunction TZPostgreSQLDatabaseInfo.SupportsOpenStatementsAcrossRollback: Boolean;\nbegin\n  Result := True;\nend;\n\n//----------------------------------------------------------------------\n// The following group of methods exposes various limitations\n// based on the target database with the current driver.\n// Unless otherwise specified, a result of zero means there is no\n// limit, or the limit is not known.\n\n{**\n  How many hex characters can you have in an inline binary literal?\n  @return max binary literal length in hex characters;\n       a result of zero means that there is no limit or the limit is not known\n}\nfunction TZPostgreSQLDatabaseInfo.GetMaxBinaryLiteralLength: Integer;\nbegin\n  Result := 0;\nend;\n\n{**\n  What's the max length for a character literal?\n  @return max literal length;\n       a result of zero means that there is no limit or the limit is not known\n}\nfunction TZPostgreSQLDatabaseInfo.GetMaxCharLiteralLength: Integer;\nbegin\n  Result := 0;\nend;\n\n{**\n  What's the limit on column name length?\n  @return max column name length;\n       a result of zero means that there is no limit or the limit is not known\n}\nfunction TZPostgreSQLDatabaseInfo.GetMaxColumnNameLength: Integer;\nbegin\n  Result := GetMaxNameLength;\nend;\n\n{**\n  What's the maximum number of columns in a \"GROUP BY\" clause?\n  @return max number of columns;\n       a result of zero means that there is no limit or the limit is not known\n}\nfunction TZPostgreSQLDatabaseInfo.GetMaxColumnsInGroupBy: Integer;\nbegin\n  Result := 0;\nend;\n\n{**\n  What's the maximum number of columns allowed in an index?\n  @return max number of columns;\n       a result of zero means that there is no limit or the limit is not known\n}\nfunction TZPostgreSQLDatabaseInfo.GetMaxColumnsInIndex: Integer;\nbegin\n  Result := GetMaxIndexKeys;\nend;\n\n{**\n  What's the maximum number of columns in an \"ORDER BY\" clause?\n  @return max number of columns;\n       a result of zero means that there is no limit or the limit is not known\n}\nfunction TZPostgreSQLDatabaseInfo.GetMaxColumnsInOrderBy: Integer;\nbegin\n  Result := 0;\nend;\n\n{**\n  What's the maximum number of columns in a \"SELECT\" list?\n  @return max number of columns;\n       a result of zero means that there is no limit or the limit is not known\n}\nfunction TZPostgreSQLDatabaseInfo.GetMaxColumnsInSelect: Integer;\nbegin\n  Result := 0;\nend;\n\n{**\n  What's the maximum number of columns in a table?\n  @return max number of columns;\n       a result of zero means that there is no limit or the limit is not known\n}\nfunction TZPostgreSQLDatabaseInfo.GetMaxColumnsInTable: Integer;\nbegin\n  Result := 1600;\nend;\n\n{**\n  How many active connections can we have at a time to this database?\n  @return max number of active connections;\n       a result of zero means that there is no limit or the limit is not known\n}\nfunction TZPostgreSQLDatabaseInfo.GetMaxConnections: Integer;\nbegin\n  Result := 8192;\nend;\n\n{**\n  What's the maximum cursor name length?\n  @return max cursor name length in bytes;\n       a result of zero means that there is no limit or the limit is not known\n}\nfunction TZPostgreSQLDatabaseInfo.GetMaxCursorNameLength: Integer;\nbegin\n  Result := GetMaxNameLength;\nend;\n\n{**\n  Retrieves the maximum number of bytes for an index, including all\n  of the parts of the index.\n  @return max index length in bytes, which includes the composite of all\n   the constituent parts of the index;\n   a result of zero means that there is no limit or the limit is not known\n}\nfunction TZPostgreSQLDatabaseInfo.GetMaxIndexLength: Integer;\nbegin\n  Result := 0;\nend;\n\n{**\n  What's the maximum length allowed for a schema name?\n  @return max name length in bytes;\n       a result of zero means that there is no limit or the limit is not known\n}\nfunction TZPostgreSQLDatabaseInfo.GetMaxSchemaNameLength: Integer;\nbegin\n  Result := GetMaxNameLength;\nend;\n\n{**\n  What's the maximum length of a procedure name?\n  @return max name length in bytes;\n       a result of zero means that there is no limit or the limit is not known\n}\nfunction TZPostgreSQLDatabaseInfo.GetMaxProcedureNameLength: Integer;\nbegin\n  Result := GetMaxNameLength;\nend;\n\n{**\n  What's the maximum length of a catalog name?\n  @return max name length in bytes;\n       a result of zero means that there is no limit or the limit is not known\n}\nfunction TZPostgreSQLDatabaseInfo.GetMaxCatalogNameLength: Integer;\nbegin\n  Result := GetMaxNameLength;\nend;\n\n{**\n  What's the maximum length of a single row?\n  @return max row size in bytes;\n       a result of zero means that there is no limit or the limit is not known\n}\nfunction TZPostgreSQLDatabaseInfo.GetMaxRowSize: Integer;\nbegin\n  if HasMinimumServerVersion(7, 1) then\n    Result := 1073741824\n  else Result := 8192;\nend;\n\n{**\n  Did getMaxRowSize() include LONGVARCHAR and LONGVARBINARY\n  blobs?\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZPostgreSQLDatabaseInfo.DoesMaxRowSizeIncludeBlobs: Boolean;\nbegin\n  Result := True;\nend;\n\n{**\n  What's the maximum length of an SQL statement?\n  @return max length in bytes;\n       a result of zero means that there is no limit or the limit is not known\n}\nfunction TZPostgreSQLDatabaseInfo.GetMaxStatementLength: Integer;\nbegin\n  if HasMinimumServerVersion(7, 0) then\n    Result := 0\n  else Result := 16348\nend;\n\n{**\n  How many active statements can we have open at one time to this\n  database?\n  @return the maximum number of statements that can be open at one time;\n       a result of zero means that there is no limit or the limit is not known\n}\nfunction TZPostgreSQLDatabaseInfo.GetMaxStatements: Integer;\nbegin\n  Result := 1;\nend;\n\n{**\n  What's the maximum length of a table name?\n  @return max name length in bytes;\n       a result of zero means that there is no limit or the limit is not known\n}\nfunction TZPostgreSQLDatabaseInfo.GetMaxTableNameLength: Integer;\nbegin\n  Result := GetMaxNameLength;\nend;\n\n{**\n  What's the maximum number of tables in a SELECT statement?\n  @return the maximum number of tables allowed in a SELECT statement;\n       a result of zero means that there is no limit or the limit is not known\n}\nfunction TZPostgreSQLDatabaseInfo.GetMaxTablesInSelect: Integer;\nbegin\n  Result := 0;\nend;\n\n{**\n  What's the maximum length of a user name?\n  @return max user name length  in bytes;\n       a result of zero means that there is no limit or the limit is not known\n}\nfunction TZPostgreSQLDatabaseInfo.GetMaxUserNameLength: Integer;\nbegin\n  Result := GetMaxNameLength;\nend;\n\n//----------------------------------------------------------------------\n\n{**\n  What's the database's default transaction isolation level?  The\n  values are defined in <code>java.sql.Connection</code>.\n  @return the default isolation level\n  @see Connection\n}\nfunction TZPostgreSQLDatabaseInfo.GetDefaultTransactionIsolation:\n  TZTransactIsolationLevel;\nbegin\n  Result := tiReadCommitted;\nend;\n\n{**\n  Are transactions supported? If not, invoking the method\n  <code>commit</code> is a noop and the isolation level is TRANSACTION_NONE.\n  @return <code>true</code> if transactions are supported; <code>false</code> otherwise\n}\nfunction TZPostgreSQLDatabaseInfo.SupportsTransactions: Boolean;\nbegin\n  Result := True;\nend;\n\n{**\n  Does this database support the given transaction isolation level?\n  @param level the values are defined in <code>java.sql.Connection</code>\n  @return <code>true</code> if so; <code>false</code> otherwise\n  @see Connection\n}\nfunction TZPostgreSQLDatabaseInfo.SupportsTransactionIsolationLevel(\n  Level: TZTransactIsolationLevel): Boolean;\nbegin\n  Result := (Level = tiSerializable) or (Level = tiReadCommitted);\nend;\n\n{**\n  Are both data definition and data manipulation statements\n  within a transaction supported?\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZPostgreSQLDatabaseInfo.\n  SupportsDataDefinitionAndDataManipulationTransactions: Boolean;\nbegin\n  Result := True;\nend;\n\n{**\n  Are only data manipulation statements within a transaction\n  supported?\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZPostgreSQLDatabaseInfo.\n  SupportsDataManipulationTransactionsOnly: Boolean;\nbegin\n  Result := False;\nend;\n\n{**\n  Does a data definition statement within a transaction force the\n  transaction to commit?\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZPostgreSQLDatabaseInfo.DataDefinitionCausesTransactionCommit: Boolean;\nbegin\n  Result := False;\nend;\n\n{**\n  Is a data definition statement within a transaction ignored?\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZPostgreSQLDatabaseInfo.DataDefinitionIgnoredInTransactions: Boolean;\nbegin\n  Result := False;\nend;\n\n{**\n  Does the database support the given result set type?\n  @param type defined in <code>java.sql.ResultSet</code>\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZPostgreSQLDatabaseInfo.SupportsResultSetType(\n  _Type: TZResultSetType): Boolean;\nbegin\n  Result := _Type = rtScrollInsensitive;\nend;\n\n{**\n  Does the database support the concurrency type in combination\n  with the given result set type?\n\n  @param type defined in <code>java.sql.ResultSet</code>\n  @param concurrency type defined in <code>java.sql.ResultSet</code>\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZPostgreSQLDatabaseInfo.SupportsResultSetConcurrency(\n  _Type: TZResultSetType; Concurrency: TZResultSetConcurrency): Boolean;\nbegin\n  Result := (_Type = rtScrollInsensitive) and (Concurrency = rcReadOnly);\nend;\n\n//----------------------------------------------------------------------\n// Additional functions.\n\nfunction TZPostgreSQLDatabaseInfo.HasMinimumServerVersion(\n  MajorVersion: Integer; MinorVersion: Integer): Boolean;\nvar\n  PostgreSQLConnection: IZPostgreSQLConnection;\nbegin\n  PostgreSQLConnection := Metadata.GetConnection as IZPostgreSQLConnection;\n  Result := (MajorVersion < PostgreSQLConnection.GetServerMajorVersion)\n    or ((MajorVersion = PostgreSQLConnection.GetServerMajorVersion)\n    and (MinorVersion <= PostgreSQLConnection.GetServerMinorVersion));\nend;\n\nfunction TZPostgreSQLDatabaseInfo.GetMaxIndexKeys: Integer;\nvar\n  SQL, From: string;\nbegin\n  if HasMinimumServerVersion(7, 3) then\n  begin\n    From := ' pg_catalog.pg_namespace n, pg_catalog.pg_type t1,'\n      + ' pg_catalog.pg_type t2 WHERE t1.typnamespace=n.oid'\n      + ' AND n.nspname=''pg_catalog'' AND ';\n  end else\n    From := ' pg_type t1, pg_type t2 WHERE ';\n  SQL := ' SELECT t1.typlen/t2.typlen FROM ' + From\n    + ' t1.typelem=t2.oid AND t1.typname=''oidvector'' ';\n\n  with Metadata.GetConnection.CreateStatement.ExecuteQuery(SQL) do\n  begin\n    if not Next then\n      raise Exception.Create(SUnknownError); //CHANGE IT!\n    Result := GetInt(1);\n    Close;\n  end;\nend;\n\nfunction TZPostgreSQLDatabaseInfo.GetMaxNameLength: Integer;\nvar\n  SQL: string;\nbegin\n  if HasMinimumServerVersion(7, 3) then\n  begin\n    SQL := ' SELECT t.typlen FROM pg_catalog.pg_type t,'\n      + ' pg_catalog.pg_namespace n WHERE t.typnamespace=n.oid'\n      + ' AND t.typname=''name'' AND n.nspname=''pg_catalog'' ';\n  end else\n    SQL := ' SELECT typlen FROM pg_type WHERE typname=''name'' ';\n\n  with Metadata.GetConnection.CreateStatement.ExecuteQuery(SQL) do\n  begin\n    if not Next then\n      raise Exception.Create(SUnknownError); //CHANGE IT!\n    Result := GetIntByName('typlen');\n    Close;\n  end;\nend;\n\n\n{ TZPostgreSQLDatabaseMetadata }\n\n\n{**\n  Destroys this object and cleanups the memory.\n}\ndestructor TZPostgreSQLDatabaseMetadata.Destroy;\nbegin\n  inherited Destroy;\nend;\n\n{**\n  Constructs a database information object and returns the interface to it. Used\n  internally by the constructor.\n  @return the database information object interface\n}\nfunction TZPostgreSQLDatabaseMetadata.CreateDatabaseInfo: IZDatabaseInfo;\nbegin\n  Result := TZPostgreSQLDatabaseInfo.Create(Self);\nend;\n\n{**\n  @param S a string.\n  @return escaped string\n}\nfunction TZPostgreSQLDatabaseMetadata.EscapeString(const S: string): string;\nvar\n  I: Integer;\nbegin\n  Result := S;\n  for I := Length(Result) downto 1 do\n    if (Result[I] = '''') or (Result[I] = '\\') then\n      Insert('\\', Result, I);\n  Result := '''' + Result + '''';\n  if (GetDatabaseInfo as IZPostgreDBInfo).HasMinimumServerVersion(8, 1) then\n    Result := 'E' + Result;\nend;\n\nfunction TZPostgreSQLDatabaseMetadata.GetRuleType(const Rule: String): TZImportedKey;\nbegin\n  if Rule = 'RESTRICT' then\n    Result := ikRestrict\n  else if Rule = 'NO ACTION' then\n    Result := ikNoAction\n  else if Rule = 'CASCADE' then\n    Result := ikCascade\n  else if Rule = 'SET DEFAULT' then\n    Result := ikSetDefault\n  else if Rule = 'SET NULL' then\n    Result := ikSetNull\n  else\n    Result := ikNotDeferrable; //impossible!\nend;\n\n{**\n  Gets a description of the stored procedures available in a\n  catalog.\n\n  <P>Only procedure descriptions matching the schema and\n  procedure name criteria are returned.  They are ordered by\n  PROCEDURE_SCHEM, and PROCEDURE_NAME.\n\n  <P>Each procedure description has the the following columns:\n   <OL>\n \t<LI><B>PROCEDURE_CAT</B> String => procedure catalog (may be null)\n \t<LI><B>PROCEDURE_SCHEM</B> String => procedure schema (may be null)\n \t<LI><B>PROCEDURE_NAME</B> String => procedure name\n   <LI> reserved for future use\n   <LI> reserved for future use\n   <LI> reserved for future use\n \t<LI><B>REMARKS</B> String => explanatory comment on the procedure\n \t<LI><B>PROCEDURE_TYPE</B> short => kind of procedure:\n       <UL>\n       <LI> procedureResultUnknown - May return a result\n       <LI> procedureNoResult - Does not return a result\n       <LI> procedureReturnsResult - Returns a result\n       </UL>\n   </OL>\n\n  @param catalog a catalog name; \"\" retrieves those without a\n  catalog; null means drop catalog name from the selection criteria\n  @param schemaPattern a schema name pattern; \"\" retrieves those\n  without a schema\n  @param procedureNamePattern a procedure name pattern\n  @return <code>ResultSet</code> - each row is a procedure description\n  @see #getSearchStringEscape\n}\nfunction TZPostgreSQLDatabaseMetadata.UncachedGetProcedures(const Catalog: string;\n  const SchemaPattern: string; const ProcedureNamePattern: string): IZResultSet;\nvar\n  SQL, ProcedureCondition, SchemaCondition: string;\nbegin\n  SchemaCondition := ConstructNameCondition(SchemaPattern,'n.nspname');\n  ProcedureCondition := ConstructNameCondition(ProcedureNamePattern,'p.proname');\n  if (GetDatabaseInfo as IZPostgreDBInfo).HasMinimumServerVersion(7, 3) then\n  begin\n    SQL := 'SELECT NULL AS PROCEDURE_CAT, n.nspname AS PROCEDURE_SCHEM,'\n      + ' p.proname AS PROCEDURE_NAME, NULL AS RESERVED1, NULL AS RESERVED2,'\n      + ' NULL AS RESERVED3, d.description AS REMARKS, '\n      + IntToStr(ProcedureReturnsResult) + ' AS PROCEDURE_TYPE '\n      + ' FROM pg_catalog.pg_namespace n, pg_catalog.pg_proc p  '\n      + ' LEFT JOIN pg_catalog.pg_description d ON (p.oid=d.objoid) '\n      + ' LEFT JOIN pg_catalog.pg_class c ON (d.classoid=c.oid AND'\n      + ' c.relname=''pg_proc'') LEFT JOIN pg_catalog.pg_namespace pn ON'\n      + ' (c.relnamespace=pn.oid AND pn.nspname=''pg_catalog'') '\n      + ' WHERE p.pronamespace=n.oid';\n    if SchemaCondition <> '' then\n      SQL := SQL + ' AND ' + Schemacondition;\n    if ProcedureCondition <> '' then\n      SQL := SQL + ' AND ' + ProcedureCondition;\n    SQL := SQL + ' ORDER BY PROCEDURE_SCHEM, PROCEDURE_NAME';\n  end\n  else\n  begin\n    SQL := 'SELECT NULL AS PROCEDURE_CAT, NULL AS PROCEDURE_SCHEM,'\n      + ' p.proname AS PROCEDURE_NAME, NULL AS RESERVED1, NULL AS RESERVED2,'\n      + ' NULL AS RESERVED3, NULL AS REMARKS, '\n      + IntToStr(ProcedureReturnsResult) + ' AS PROCEDURE_TYPE'\n      + ' FROM pg_proc p';\n    if ProcedureCondition <> '' then\n      SQL := SQL + ' WHERE ' + ProcedureCondition;\n    SQL := SQL + ' ORDER BY PROCEDURE_NAME';\n  end;\n\n  Result := CopyToVirtualResultSet(\n    GetConnection.CreateStatement.ExecuteQuery(SQL),\n    ConstructVirtualResultSet(ProceduresColumnsDynArray));\nend;\n\n{**\n  Gets a description of a catalog's stored procedure parameters\n  and result columns.\n\n  <P>Only descriptions matching the schema, procedure and\n  parameter name criteria are returned.  They are ordered by\n  PROCEDURE_SCHEM and PROCEDURE_NAME. Within this, the return value,\n  if any, is first. Next are the parameter descriptions in call\n  order. The column descriptions follow in column number order.\n\n  <P>Each row in the <code>ResultSet</code> is a parameter description or\n  column description with the following fields:\n   <OL>\n \t<LI><B>PROCEDURE_CAT</B> String => procedure catalog (may be null)\n \t<LI><B>PROCEDURE_SCHEM</B> String => procedure schema (may be null)\n \t<LI><B>PROCEDURE_NAME</B> String => procedure name\n \t<LI><B>COLUMN_NAME</B> String => column/parameter name\n \t<LI><B>COLUMN_TYPE</B> Short => kind of column/parameter:\n       <UL>\n       <LI> procedureColumnUnknown - nobody knows\n       <LI> procedureColumnIn - IN parameter\n       <LI> procedureColumnInOut - INOUT parameter\n       <LI> procedureColumnOut - OUT parameter\n       <LI> procedureColumnReturn - procedure return value\n       <LI> procedureColumnResult - result column in <code>ResultSet</code>\n       </UL>\n   <LI><B>DATA_TYPE</B> short => SQL type from java.sql.Types\n \t<LI><B>TYPE_NAME</B> String => SQL type name, for a UDT type the\n   type name is fully qualified\n \t<LI><B>PRECISION</B> int => precision\n \t<LI><B>LENGTH</B> int => length in bytes of data\n \t<LI><B>SCALE</B> short => scale\n \t<LI><B>RADIX</B> short => radix\n \t<LI><B>NULLABLE</B> short => can it contain NULL?\n       <UL>\n       <LI> procedureNoNulls - does not allow NULL values\n       <LI> procedureNullable - allows NULL values\n       <LI> procedureNullableUnknown - nullability unknown\n       </UL>\n \t<LI><B>REMARKS</B> String => comment describing parameter/column\n   </OL>\n\n  <P><B>Note:</B> Some databases may not return the column\n  descriptions for a procedure. Additional columns beyond\n  REMARKS can be defined by the database.\n\n  @param catalog a catalog name; \"\" retrieves those without a\n  catalog; null means drop catalog name from the selection criteria\n  @param schemaPattern a schema name pattern; \"\" retrieves those\n  without a schema\n  @param procedureNamePattern a procedure name pattern\n  @param columnNamePattern a column name pattern\n  @return <code>ResultSet</code> - each row describes a stored procedure parameter or\n       column\n  @see #getSearchStringEscape\n}\nfunction TZPostgreSQLDatabaseMetadata.UncachedGetProcedureColumns(const Catalog: string;\n  const SchemaPattern: string; const ProcedureNamePattern: string;\n  const ColumnNamePattern: string): IZResultSet;\n\n  procedure InsertProcedureColumnRow(AResultSet: IZResultSet;\n    const ASchema, AProcedureName, AColumnName: string;\n    const AColumnType, ADataType: integer; const ATypeName: string;\n    const ANullable: integer);\n  begin\n    AResultSet.MoveToInsertRow;\n    AResultSet.UpdateNullByName('PROCEDURE_CAT');\n    AResultSet.UpdateStringByName('PROCEDURE_SCHEM', ASchema);\n    AResultSet.UpdateStringByName('PROCEDURE_NAME', AProcedureName);\n    AResultSet.UpdateStringByName('COLUMN_NAME', AColumnName);\n    AResultSet.UpdateIntByName('COLUMN_TYPE', AColumnType);\n    AResultSet.UpdateIntByName('DATA_TYPE', ADataType);\n    AResultSet.UpdateStringByName('TYPE_NAME', ATypeName);\n    AResultSet.UpdateNullByName('PRECISION');\n    AResultSet.UpdateNullByName('LENGTH');\n    AResultSet.UpdateNullByName('SCALE');\n    AResultSet.UpdateNullByName('RADIX');\n    AResultSet.UpdateIntByName('NULLABLE', ANullable);\n    AResultSet.UpdateNullByName('REMARKS');\n    AResultSet.InsertRow;\n  end;\n\nvar\n  I, ReturnType, ColumnTypeOid, ArgOid: Integer;\n  SQL, ReturnTypeType: string;\n  IsInParam, IsOutParam: Boolean;\n  ArgTypes, ArgNames, ArgModes: TStrings;\n  Ver73Up, Ver80Up: Boolean;\n  ResultSet: IZResultSet;\n  ColumnsRS: IZResultSet;\n  ArgMode: Char;\n  OutParamCount: Integer;\n  ColumnName: string;\n  ColumnType: Integer;\n  ProcedureCondition, SchemaCondition: string;\nbegin\n  SchemaCondition := ConstructNameCondition(SchemaPattern,'n.nspname');\n  ProcedureCondition := ConstructNameCondition(ProcedureNamePattern,'p.proname');\n  Result := inherited UncachedGetProcedureColumns(Catalog, SchemaPattern, ProcedureNamePattern, ColumnNamePattern);\n\n  Ver80Up := (GetDatabaseInfo as IZPostgreDBInfo).HasMinimumServerVersion(8, 0);\n  Ver73Up := Ver80Up or (GetDatabaseInfo as IZPostgreDBInfo).HasMinimumServerVersion(7, 3);\n  if Ver80Up then\n  begin\n    SQL := 'SELECT n.nspname,p.proname,p.prorettype,p.proargtypes,t.typtype,'\n      + 'p.proallargtypes,p.proargnames,p.proargmodes,t.typrelid '\n      + 'FROM pg_catalog.pg_proc p, pg_catalog.pg_namespace n, pg_catalog.pg_type t '\n      + 'WHERE p.pronamespace=n.oid AND p.prorettype=t.oid';\n    if SchemaPattern <> '' then\n      SQL := SQL + ' AND ' + SchemaCondition;\n    if ProcedureNamePattern <> '' then\n      SQL := SQL + ' AND ' + ProcedureCondition;\n    SQL := SQL + ' ORDER BY n.nspname, p.proname';\n  end\n  else\n  if Ver73Up then\n  begin\n    SQL := 'SELECT n.nspname,p.proname,p.prorettype,p.proargtypes,t.typtype,'\n      + 'NULL AS proallargtypes,NULL AS proargnames,NULL AS proargnames,t.typrelid '\n      + 'FROM pg_catalog.pg_proc p, pg_catalog.pg_namespace n,'\n      + ' pg_catalog.pg_type t WHERE p.pronamespace=n.oid AND p.prorettype=t.oid';\n    if SchemaPattern <> '' then\n        SQL := SQL + ' AND ' + SchemaCondition;\n    if ProcedureNamePattern <> '' then\n        SQL := SQL + ' AND ' + ProcedureCondition;\n    SQL := SQL + ' ORDER BY n.nspname, p.proname';\n  end\n  else\n  begin\n    SQL := 'SELECT NULL AS nspname,p.proname,p.prorettype,p.proargtypes,'\n      + ' NULL AS proallargtypes,NULL AS proargnames,NULL AS proargnames,t.typtype,t.typrelid'\n      + ' FROM pg_proc p, pg_type t'\n      + ' WHERE p.prorettype=t.oid';\n    if ProcedureNamePattern <> '' then\n      SQL := SQL + ' AND ' + ProcedureCondition;\n    SQL := SQL + ' ORDER BY p.proname';\n  end;\n\n  ArgTypes := TStringList.Create;\n  ArgNames := TStringList.Create;\n  ArgModes := TStringList.Create;\n  try\n    ResultSet := GetConnection.CreateStatement.ExecuteQuery(SQL); //FirmOS Patch\n    with ResultSet do\n    begin\n      while Next do\n      begin\n        ReturnType := StrToInt(GetStringByName('prorettype'));\n        ReturnTypeType := GetStringByName('typtype');\n\n        ArgTypes.Clear;\n        ArgNames.Clear;\n        ArgModes.Clear;\n\n        if (IsNullByName('proallargtypes')) then\n          PutSplitString(ArgTypes, GetStringByName('proargtypes'), #10#13#9' ')\n        else\n          ParseACLArray(ArgTypes, GetStringByName('proallargtypes'));\n        ParseACLArray(ArgNames, GetStringByName('proargnames'));\n        ParseACLArray(ArgModes, GetStringByName('proargmodes'));\n\n        OutParamCount := 0;\n        for I := 0 to ArgTypes.Count - 1 do\n        begin\n          IsInParam := True;\n          IsOutParam := False;\n          if ArgModes.Count > I then\n          begin\n            ArgMode := ArgModes[I][1];\n            IsInParam := CharInSet(ArgMode, ['i', 'b', 'v']);\n            IsOutParam := CharInSet(ArgMode, ['o', 'b', 't']);\n          end;\n\n          if IsOutParam then\n            Inc(OutParamCount);\n\n          // column name\n          ArgOid := StrToInt(ArgTypes.Strings[i]);\n          if ArgNames.Count > I then\n            ColumnName := ArgNames.Strings[I]\n          else\n            ColumnName := '$' + IntToStr(I + 1);\n\n          // column type\n          if IsInParam then\n          begin\n            if IsOutParam then\n              ColumnType := Ord(pctInOut)\n            else\n              ColumnType := Ord(pctIn);\n          end\n          else\n          begin\n           if IsOutParam then\n             ColumnType := Ord(pctOut)\n           else\n             ColumnType := Ord(pctUnknown);\n          end;\n\n          InsertProcedureColumnRow(Result, GetStringByName('nspname'),\n            GetStringByName('proname'), ColumnName, ColumnType,\n            Ord(GetSQLTypeByOid(ArgOid)), GetPostgreSQLType(ArgOid),\n            Ord(ntNullableUnknown));\n        end;\n\n        if (OutParamCount > 0) then\n          Continue;\n\n        if (ReturnTypeType = 'c') then // Extract composit type columns\n        begin\n          ColumnsRS := GetConnection.CreateStatement.ExecuteQuery(\n            Format('SELECT a.attname,a.atttypid'\n              + ' FROM pg_catalog.pg_attribute a WHERE a.attrelid=%s'\n              + ' ORDER BY a.attnum',\n              [ResultSet.GetStringByName('typrelid')]));\n          while ColumnsRS.Next do\n          begin\n            ColumnTypeOid := ColumnsRS.GetIntByName('atttypid');\n            InsertProcedureColumnRow(Result, GetStringByName('nspname'),\n              GetStringByName('proname'), ColumnsRS.GetStringByName('attname'),\n              Ord(pctResultSet), Ord(GetSQLTypeByOid(ColumnTypeOid)),\n              GetPostgreSQLType(ColumnTypeOid), Ord(ntNullableUnknown));\n          end;\n          ColumnsRS.Close;\n        end\n        else\n        begin\n          if (ReturnTypeType <> 'p') then // Single non-pseudotype return value\n          begin\n            InsertProcedureColumnRow(Result, GetStringByName('nspname'),\n              GetStringByName('proname'), 'returnValue', Ord(pctReturn),\n              Ord(GetSQLTypeByOid(ReturnType)), GetPostgreSQLType(ReturnType),\n              Ord(ntNullableUnknown));\n          end;\n        end;\n      end;\n      Close;\n    end;\n  finally\n    ArgTypes.Free;\n    ArgNames.Free;\n    ArgModes.Free;\n  end;\nend;\n\n{**\n  Gets a description of tables available in a catalog.\n\n  <P>Only table descriptions matching the catalog, schema, table\n  name and type criteria are returned.  They are ordered by\n  TABLE_TYPE, TABLE_SCHEM and TABLE_NAME.\n\n  <P>Each table description has the following columns:\n   <OL>\n \t<LI><B>TABLE_CAT</B> String => table catalog (may be null)\n \t<LI><B>TABLE_SCHEM</B> String => table schema (may be null)\n \t<LI><B>TABLE_NAME</B> String => table name\n \t<LI><B>TABLE_TYPE</B> String => table type.  Typical types are \"TABLE\",\n \t\t\t\"VIEW\",\t\"SYSTEM TABLE\", \"GLOBAL TEMPORARY\",\n \t\t\t\"LOCAL TEMPORARY\", \"ALIAS\", \"SYNONYM\".\n \t<LI><B>REMARKS</B> String => explanatory comment on the table\n   </OL>\n\n  <P><B>Note:</B> Some databases may not return information for\n  all tables.\n\n  @param catalog a catalog name; \"\" retrieves those without a\n  catalog; null means drop catalog name from the selection criteria\n  @param schemaPattern a schema name pattern; \"\" retrieves those\n  without a schema\n  @param tableNamePattern a table name pattern\n  @param types a list of table types to include; null returns all types\n  @return <code>ResultSet</code> - each row is a table description\n  @see #getSearchStringEscape\n}\nfunction TZPostgreSQLDatabaseMetadata.UncachedGetTables(const Catalog: string;\n  const SchemaPattern: string; const TableNamePattern: string;\n  const Types: TStringDynArray): IZResultSet;\nvar\n  I: Integer;\n  TableType, OrderBy, SQL: string;\n  UseSchemas: Boolean;\n  LTypes: TStringDynArray;\n  TableNameCondition, SchemaCondition: string;\nbegin\n  SchemaCondition := ConstructNameCondition(SchemaPattern,'n.nspname');\n  TableNameCondition := ConstructNameCondition(TableNamePattern,'c.relname');\n  UseSchemas := True;\n\n  if (GetDatabaseInfo as IZPostgreDBInfo).HasMinimumServerVersion(7, 3) then\n  begin\n    SQL := ' SELECT NULL AS TABLE_CAT, n.nspname AS TABLE_SCHEM,'\n      + ' c.relname AS TABLE_NAME,  '\n      + ' CASE (n.nspname LIKE ''pg\\\\_%'')'\n      + '   OR (n.nspname=''information_schema'')'\n      + ' WHEN true THEN CASE n.nspname '\n      + '   WHEN ''pg_catalog'' THEN CASE c.relkind '\n      + '     WHEN ''r'' THEN ''SYSTEM TABLE'''\n      + '     WHEN ''v'' THEN ''SYSTEM VIEW'' '\n      + '     WHEN ''i'' THEN ''SYSTEM INDEX'' '\n      + '     ELSE NULL '\n      + '   END '\n      + '   WHEN ''information_schema'' THEN CASE c.relkind '\n      + '     WHEN ''r'' THEN ''SYSTEM TABLE'''\n      + '     WHEN ''v'' THEN ''SYSTEM VIEW'' '\n      + '     WHEN ''i'' THEN ''SYSTEM INDEX'' '\n      + '     ELSE NULL '\n      + '   END '\n      + '   WHEN ''pg_toast'' THEN CASE c.relkind '\n      + '     WHEN ''r'' THEN ''SYSTEM TOAST TABLE'' '\n      + '     WHEN ''i'' THEN ''SYSTEM TOAST INDEX'' '\n      + '     ELSE NULL '\n      + '   END '\n      + '   ELSE CASE c.relkind '\n      + '\tWHEN ''r'' THEN ''TEMPORARY TABLE'' '\n      + '\tWHEN ''i'' THEN ''TEMPORARY INDEX'' '\n      + '\tELSE NULL '\n      + '   END '\n      + ' END '\n      + ' WHEN false THEN CASE c.relkind '\n      + '   WHEN ''r'' THEN ''TABLE'' '\n      + '   WHEN ''i'' THEN ''INDEX'' '\n      + '   WHEN ''S'' THEN ''SEQUENCE'' '\n      + '   WHEN ''v'' THEN ''VIEW'' '\n      + '   ELSE NULL '\n      + ' END '\n      + ' ELSE NULL '\n      + ' END '\n      + ' AS TABLE_TYPE, d.description AS REMARKS '\n      + ' FROM pg_catalog.pg_namespace n, pg_catalog.pg_class c '\n      + ' LEFT JOIN pg_catalog.pg_description d'\n      + ' ON (c.oid = d.objoid AND d.objsubid = 0) '\n      + ' LEFT JOIN pg_catalog.pg_class dc ON (d.classoid=dc.oid'\n      + ' AND dc.relname=''pg_class'') LEFT JOIN pg_catalog.pg_namespace dn'\n      + ' ON (dn.oid=dc.relnamespace AND dn.nspname=''pg_catalog'') '\n      + ' WHERE c.relnamespace = n.oid ';\n    if SchemaPattern <> '' then\n    begin\n      SQL := SQL + ' AND ' + SchemaCondition;\n    end;\n    OrderBy := ' ORDER BY TABLE_TYPE,TABLE_SCHEM,TABLE_NAME';\n  end\n  else\n  begin\n    UseSchemas := False;\n    TableType := ' CASE c.relname LIKE ''pg\\\\_%'' '\n      + 'WHEN true THEN CASE c.relname LIKE ''pg\\\\_toast\\\\_%'' '\n      + 'WHEN true THEN CASE c.relkind '\n      + '  WHEN ''r'' THEN ''SYSTEM TOAST TABLE'' '\n      + '  WHEN ''i'' THEN ''SYSTEM TOAST INDEX'' '\n      + '  ELSE NULL '\n      + 'END '\n      + 'WHEN false THEN CASE c.relname LIKE ''pg\\\\_temp\\\\_%'' '\n      + '  WHEN true THEN CASE c.relkind '\n      + '    WHEN ''r'' THEN ''TEMPORARY TABLE'' '\n      + '    WHEN ''i'' THEN ''TEMPORARY INDEX'' '\n      + '    ELSE NULL '\n      + '  END '\n      + '  WHEN false THEN CASE c.relkind '\n      + '    WHEN ''r'' THEN ''SYSTEM TABLE'' '\n      + '    WHEN ''v'' THEN ''SYSTEM VIEW'' '\n      + '    WHEN ''i'' THEN ''SYSTEM INDEX'' '\n      + '    ELSE NULL '\n      + '  END '\n      + '  ELSE NULL '\n      + 'END '\n      + 'ELSE NULL '\n      + 'END '\n      + 'WHEN false THEN CASE c.relkind '\n      + '  WHEN ''r'' THEN ''TABLE'' '\n      + '  WHEN ''i'' THEN ''INDEX'' '\n      + '  WHEN ''S'' THEN ''SEQUENCE'' '\n      + '  WHEN ''v'' THEN ''VIEW'' '\n      + '  ELSE NULL '\n      + 'END '\n      + 'ELSE NULL '\n      + ' END ';\n    OrderBy := ' ORDER BY TABLE_TYPE,TABLE_NAME ';\n    SQL := 'SELECT NULL AS TABLE_CAT, NULL AS TABLE_SCHEM,'\n      + ' c.relname AS TABLE_NAME, ' + TableType + ' AS TABLE_TYPE,'\n      + ' NULL AS REMARKS FROM pg_class c WHERE true ';\n  end;\n\n  if (Types = nil) or (Length(Types) = 0) then\n  begin\n    SetLength(LTypes, 3);\n    // SetLength(LTypes, 6);\n    LTypes[0] := 'TABLE';\n    LTypes[1] := 'VIEW';\n    LTypes[2] := 'TEMPORARY TABLE';\n    // LTypes[3] := 'SYSTEM TABLE';\n    // LTypes[4] := 'SYSTEM TOAST TABLE';\n    // LTypes[5] := 'SYSTEM VIEW';\n  end\n  else\n    LTypes := Types;\n\n  If TableNameCondition <> '' then\n    SQL := SQL + ' AND ' + TableNameCondition;\n\n  SQL := SQL + ' AND (false';\n  for I := 0 to High(LTypes) do\n    SQL := SQL + ' OR (' + TableTypeSQLExpression(LTypes[i], UseSchemas) + ')';\n  SQL := SQL + ')' + OrderBy;\n\n  Result := CopyToVirtualResultSet(\n    GetConnection.CreateStatement.ExecuteQuery(SQL),\n    ConstructVirtualResultSet(TableColumnsDynArray));\nend;\n\n{**\n  Gets the schema names available in this database.  The results\n  are ordered by schema name.\n\n  <P>The schema column is:\n   <OL>\n \t<LI><B>TABLE_SCHEM</B> String => schema name\n   </OL>\n\n  @return <code>ResultSet</code> - each row has a single String column that is a\n  schema name\n}\nfunction TZPostgreSQLDatabaseMetadata.UncachedGetSchemas: IZResultSet;\nvar\n  SQL: string;\nbegin\n    if (GetDatabaseInfo as IZPostgreDBInfo).HasMinimumServerVersion(7, 3) then\n    begin\n      SQL := 'SELECT nspname AS TABLE_SCHEM FROM pg_catalog.pg_namespace'\n        + ' WHERE nspname <> ''pg_toast'' AND nspname NOT'\n        + ' LIKE ''pg\\\\_temp\\\\_%'' ORDER BY TABLE_SCHEM';\n    end else\n      SQL := 'SELECT ''''::text AS TABLE_SCHEM ORDER BY TABLE_SCHEM';\n\n    Result := CopyToVirtualResultSet(\n      GetConnection.CreateStatement.ExecuteQuery(SQL),\n      ConstructVirtualResultSet(SchemaColumnsDynArray));\nend;\n\n{**\n  Gets the catalog names available in this database.  The results\n  are ordered by catalog name.\n\n  <P>The catalog column is:\n   <OL>\n \t<LI><B>TABLE_CAT</B> String => catalog name\n   </OL>\n\n  @return <code>ResultSet</code> - each row has a single String column that is a\n  catalog name\n}\nfunction TZPostgreSQLDatabaseMetadata.UncachedGetCatalogs: IZResultSet;\nvar\n  SQL: string;\nbegin\n    if (GetDatabaseInfo as IZPostgreDBInfo).HasMinimumServerVersion(7, 3) then\n    begin\n      SQL := 'SELECT datname AS TABLE_CAT FROM pg_catalog.pg_database'\n        + ' ORDER BY TABLE_CAT';\n    end else\n      SQL := 'SELECT datname AS TABLE_CAT FROM pg_database ORDER BY TABLE_CAT';\n\n    Result := CopyToVirtualResultSet(\n      GetConnection.CreateStatement.ExecuteQuery(SQL),\n      ConstructVirtualResultSet(CatalogColumnsDynArray));\nend;\n\n{**\n  Gets the table types available in this database.  The results\n  are ordered by table type.\n\n  <P>The table type is:\n   <OL>\n \t<LI><B>TABLE_TYPE</B> String => table type.  Typical types are \"TABLE\",\n \t\t\t\"VIEW\",\t\"SYSTEM TABLE\", \"GLOBAL TEMPORARY\",\n \t\t\t\"LOCAL TEMPORARY\", \"ALIAS\", \"SYNONYM\".\n   </OL>\n\n  @return <code>ResultSet</code> - each row has a single String column that is a\n  table type\n}\nfunction TZPostgreSQLDatabaseMetadata.UncachedGetTableTypes: IZResultSet;\nconst\n  Types: array [0..10] of string = ('TABLE', 'VIEW', 'INDEX',\n    'SEQUENCE', 'SYSTEM TABLE', 'SYSTEM TOAST TABLE',\n    'SYSTEM TOAST INDEX', 'SYSTEM VIEW', 'SYSTEM INDEX',\n    'TEMPORARY TABLE', 'TEMPORARY INDEX');\nvar\n  I: Integer;\nbegin\n Result:=inherited UncachedGetTableTypes;\n\n for I := 0 to 10 do\n    begin\n      Result.MoveToInsertRow;\n      Result.UpdateString(1, Types[I]);\n      Result.InsertRow;\n    end;\nend;\n\n{**\n  Gets a description of table columns available in\n  the specified catalog.\n\n  <P>Only column descriptions matching the catalog, schema, table\n  and column name criteria are returned.  They are ordered by\n  TABLE_SCHEM, TABLE_NAME and ORDINAL_POSITION.\n\n  <P>Each column description has the following columns:\n   <OL>\n \t<LI><B>TABLE_CAT</B> String => table catalog (may be null)\n \t<LI><B>TABLE_SCHEM</B> String => table schema (may be null)\n \t<LI><B>TABLE_NAME</B> String => table name\n \t<LI><B>COLUMN_NAME</B> String => column name\n \t<LI><B>DATA_TYPE</B> short => SQL type from java.sql.Types\n \t<LI><B>TYPE_NAME</B> String => Data source dependent type name,\n   for a UDT the type name is fully qualified\n \t<LI><B>COLUMN_SIZE</B> int => column size.  For char or date\n \t    types this is the maximum number of characters, for numeric or\n \t    decimal types this is precision.\n \t<LI><B>BUFFER_LENGTH</B> is not used.\n \t<LI><B>DECIMAL_DIGITS</B> int => the number of fractional digits\n \t<LI><B>NUM_PREC_RADIX</B> int => Radix (typically either 10 or 2)\n \t<LI><B>NULLABLE</B> int => is NULL allowed?\n       <UL>\n       <LI> columnNoNulls - might not allow NULL values\n       <LI> columnNullable - definitely allows NULL values\n       <LI> columnNullableUnknown - nullability unknown\n       </UL>\n \t<LI><B>REMARKS</B> String => comment describing column (may be null)\n  \t<LI><B>COLUMN_DEF</B> String => default value (may be null)\n \t<LI><B>SQL_DATA_TYPE</B> int => unused\n \t<LI><B>SQL_DATETIME_SUB</B> int => unused\n \t<LI><B>CHAR_OCTET_LENGTH</B> int => for char types the\n        maximum number of bytes in the column\n \t<LI><B>ORDINAL_POSITION</B> int\t=> index of column in table\n       (starting at 1)\n \t<LI><B>IS_NULLABLE</B> String => \"NO\" means column definitely\n       does not allow NULL values; \"YES\" means the column might\n       allow NULL values.  An empty string means nobody knows.\n   </OL>\n\n  @param catalog a catalog name; \"\" retrieves those without a\n  catalog; null means drop catalog name from the selection criteria\n  @param schemaPattern a schema name pattern; \"\" retrieves those\n  without a schema\n  @param tableNamePattern a table name pattern\n  @param columnNamePattern a column name pattern\n  @return <code>ResultSet</code> - each row is a column description\n  @see #getSearchStringEscape\n}\nfunction TZPostgreSQLDatabaseMetadata.UncachedGetColumns(const Catalog: string;\n  const SchemaPattern: string; const TableNamePattern: string;\n  const ColumnNamePattern: string): IZResultSet;\nvar\n  TypeOid, AttTypMod: Integer;\n  SQL, PgType: string;\n  SQLType: TZSQLType;\n  CheckVisibility: Boolean;\n  ColumnNameCondition, TableNameCondition, SchemaCondition: string;\nbegin\n  CheckVisibility := (GetConnection as IZPostgreSQLConnection).CheckFieldVisibility; //http://zeoslib.sourceforge.net/viewtopic.php?f=40&t=11174\n  SchemaCondition := ConstructNameCondition(SchemaPattern,'n.nspname');\n  TableNameCondition := ConstructNameCondition(TableNamePattern,'c.relname');\n  ColumnNameCondition := ConstructNameCondition(ColumnNamePattern,'a.attname');\n  Result:=inherited UncachedGetColumns(Catalog, SchemaPattern, TableNamePattern, ColumnNamePattern);\n\n  if (GetDatabaseInfo as IZPostgreDBInfo).HasMinimumServerVersion(7, 3) then\n  begin\n    SQL := 'SELECT n.nspname,' {nspname_index}\n      + 'c.relname,' {relname_index}\n      + 'a.attname,' {attname_index}\n      + 'a.atttypid,' {atttypid_index}\n      + 'a.attnotnull,' {attnotnull_index}\n      + 'a.atttypmod,' {atttypmod_index}\n      + 'a.attlen,' {attlen_index}\n      + 'a.attnum,' {attnum_index}\n      + 'pg_get_expr(def.adbin, def.adrelid) as adsrc,' {adsrc_index}\n      + 'dsc.description ' {description_index}\n      + ' FROM pg_catalog.pg_namespace n '\n      + ' JOIN pg_catalog.pg_class c ON (c.relnamespace = n.oid) '\n      + ' JOIN pg_catalog.pg_attribute a ON (a.attrelid=c.oid) '\n      + ' LEFT JOIN pg_catalog.pg_attrdef def ON (a.attrelid=def.adrelid'\n      + ' AND a.attnum = def.adnum) LEFT JOIN pg_catalog.pg_description dsc'\n      + ' ON (c.oid=dsc.objoid AND a.attnum = dsc.objsubid) '\n      + ' LEFT JOIN pg_catalog.pg_class dc ON (dc.oid=dsc.classoid'\n      + ' AND dc.relname=''pg_class'') LEFT JOIN pg_catalog.pg_namespace dn'\n      + ' ON (dc.relnamespace=dn.oid AND dn.nspname=''pg_catalog'') '\n      + ' WHERE a.attnum > 0 AND NOT a.attisdropped';\n    if SchemaPattern <> '' then\n      SQL := SQL + ' AND ' + SchemaCondition\n    else\n      //not by default: because of Speed decrease: http://http://zeoslib.sourceforge.net/viewtopic.php?p=16646&sid=130\n      if CheckVisibility then\n        SQL := SQL + ' AND pg_table_is_visible (c.oid) ';\n  end\n  else\n  begin\n    SQL := 'SELECT NULL::text AS nspname,' {1}\n      + 'c.relname,' {2}\n      + 'a.attname,' {3}\n      + 'a.atttypid,' {4}\n      + 'a.attnotnull,' {5}\n      + 'a.atttypmod,' {6}\n      + 'a.attlen,' {7}\n      + 'a.attnum,' {8}\n      + 'NULL AS adsrc,' {9}\n      + 'NULL AS description' {10}\n      + 'FROM pg_class c, pg_attribute a '\n      + ' WHERE a.attrelid=c.oid AND a.attnum > 0 ';\n  end;\n\n  If TableNameCondition <> '' then\n    SQL := SQL + ' AND ' + TableNameCondition;\n  If ColumnNameCondition <> '' then\n    SQL := SQL+ ' AND ' + ColumnNameCondition;\n  SQL := SQL+ ' ORDER BY nspname,relname,attnum';\n\n  with GetConnection.CreateStatement.ExecuteQuery(SQL) do\n  begin\n    while Next do\n    begin\n      AttTypMod := GetInt(6 {atttypmod});\n\n      TypeOid := GetInt(4 {atttypid});\n      PgType := GetPostgreSQLType(TypeOid);\n\n      Result.MoveToInsertRow;\n      Result.UpdateNull(1);\n      Result.UpdateString(2, GetString(1 {nspname}));\n      Result.UpdateString(3, GetString(2 {relname}));\n      Result.UpdateString(4, GetString(3 {attname}));\n      SQLType := GetSQLTypeByOid(TypeOid);\n      Result.UpdateInt(5, Ord(SQLType));\n      Result.UpdateString(6, PgType);\n      Result.UpdateInt(8, 0);\n\n      if (PgType = 'bpchar') or (PgType = 'varchar') or (PgType = 'enum') then\n      begin\n        if AttTypMod <> -1 then\n          Result.UpdateInt(7, GetFieldSize(SQLType, ConSettings, (AttTypMod - 4),\n            ConSettings.ClientCodePage.CharWidth))\n        else\n          if (PgType = 'varchar') then\n            if ( (GetConnection as IZPostgreSQLConnection).GetUndefinedVarcharAsStringLength = 0 ) then\n            begin\n              Result.UpdateInt(5, Ord(GetSQLTypeByOid(25))); //Assume text-lob instead\n              Result.UpdateInt(7, 0); // need no size for streams\n            end\n            else //keep the string type but with user defined count of chars\n              Result.UpdateInt(7, (GetConnection as IZPostgreSQLConnection).GetUndefinedVarcharAsStringLength )\n          else\n            Result.UpdateInt(7, 0);\n      end\n      else if (PgType = 'numeric') or (PgType = 'decimal') then\n      begin\n        Result.UpdateInt(7, ((AttTypMod - 4) div 65536)); //precision\n        Result.UpdateInt(9, ((AttTypMod -4) mod 65536)); //scale\n        Result.UpdateInt(10, 10); //base? ten as default\n      end\n      else if (PgType = 'bit') or (PgType = 'varbit') then\n      begin\n        Result.UpdateInt(7, AttTypMod);\n        Result.UpdateInt(10, 2);\n      end\n      else\n      begin\n        Result.UpdateInt(7, GetInt(7 {attlen}));\n        Result.UpdateInt(10, 2);\n      end;\n\n      Result.UpdateNull(8);\n      if GetBoolean(5 {attnotnull}) then\n      begin\n        Result.UpdateString(18, 'NO');\n        Result.UpdateInt(11, Ord(ntNoNulls));\n      end\n      else\n      begin\n        Result.UpdateString(18, 'YES');\n        Result.UpdateInt(11, Ord(ntNullable));\n      end;\n\n      Result.UpdateString(12, GetString(10 {description}));\n      Result.UpdateString(13, GetString(9 {adsrc}));\n      Result.UpdateNull(14);\n      Result.UpdateNull(15);\n      Result.UpdateInt(16, Result.GetInt(7));\n      Result.UpdateInt(17, GetInt(8 {attnum}));\n\n      Result.UpdateNullByName('AUTO_INCREMENT');\n      Result.UpdateBooleanByName('CASE_SENSITIVE',\n        IC.IsCaseSensitive(GetString(3 {attname})));\n      Result.UpdateBooleanByName('SEARCHABLE', True);\n      Result.UpdateBooleanByName('WRITABLE', True);\n      Result.UpdateBooleanByName('DEFINITELYWRITABLE', True);\n      Result.UpdateBooleanByName('READONLY', False);\n\n      Result.InsertRow;\n    end;\n    Close;\n  end;\nend;\n\n{**\n  Gets a description of the access rights for a table's columns.\n\n  <P>Only privileges matching the column name criteria are\n  returned.  They are ordered by COLUMN_NAME and PRIVILEGE.\n\n  <P>Each privilige description has the following columns:\n   <OL>\n \t<LI><B>TABLE_CAT</B> String => table catalog (may be null)\n \t<LI><B>TABLE_SCHEM</B> String => table schema (may be null)\n \t<LI><B>TABLE_NAME</B> String => table name\n \t<LI><B>COLUMN_NAME</B> String => column name\n \t<LI><B>GRANTOR</B> => grantor of access (may be null)\n \t<LI><B>GRANTEE</B> String => grantee of access\n \t<LI><B>PRIVILEGE</B> String => name of access (SELECT,\n       INSERT, UPDATE, REFRENCES, ...)\n \t<LI><B>IS_GRANTABLE</B> String => \"YES\" if grantee is permitted\n       to grant to others; \"NO\" if not; null if unknown\n   </OL>\n\n  @param catalog a catalog name; \"\" retrieves those without a\n  catalog; null means drop catalog name from the selection criteria\n  @param schema a schema name; \"\" retrieves those without a schema\n  @param table a table name\n  @param columnNamePattern a column name pattern\n  @return <code>ResultSet</code> - each row is a column privilege description\n  @see #getSearchStringEscape\n}\nfunction TZPostgreSQLDatabaseMetadata.UncachedGetColumnPrivileges(const Catalog: string;\n  const Schema: string; const Table: string; const ColumnNamePattern: string): IZResultSet;\nvar\n  I, J: Integer;\n  SQL, Column, Owner: string;\n  Privileges, Grantable, Grantee: string;\n  Permissions, PermissionsExp: TStrings;\n  ColumnNameCondition, TableNameCondition, SchemaCondition: string;\nbegin\n  SchemaCondition := ConstructNameCondition(Schema,'n.nspname');\n  TableNameCondition := ConstructNameCondition(Table,'c.relname');\n  ColumnNameCondition := ConstructNameCondition(ColumnNamePattern,'a.attname');\n  Result:=inherited UncachedGetColumnPrivileges(Catalog, Schema, Table, ColumnNamePattern);\n\n  if (GetDatabaseInfo as IZPostgreDBInfo).HasMinimumServerVersion(7, 3) then\n  begin\n    SQL := 'SELECT n.nspname,c.relname,u.usename,c.relacl,a.attname '\n      + ' FROM pg_catalog.pg_namespace n, pg_catalog.pg_class c,'\n      + ' pg_catalog.pg_user u, pg_catalog.pg_attribute a '\n      + ' WHERE c.relnamespace = n.oid AND u.usesysid = c.relowner '\n      + ' AND c.oid = a.attrelid AND c.relkind = ''r'''\n      + ' AND a.attnum > 0 AND NOT a.attisdropped';\n    if Schema <> '' then\n      SQL := SQL + ' AND ' + SchemaCondition;\n  end\n  else\n  begin\n    SQL := 'SELECT NULL::text AS nspname,c.relname,u.usename,c.relacl,'\n      + 'a.attname FROM pg_class c, pg_user u,pg_attribute a '\n      + ' WHERE u.usesysid = c.relowner AND c.oid = a.attrelid '\n      + ' AND a.attnum > 0 AND c.relkind = ''r''';\n  end;\n\n  If TableNameCondition <> '' then\n    SQL := SQL + ' AND ' + TableNameCondition;\n  If ColumnNameCondition <> '' then\n    SQL := SQL + ' AND '+ ColumnNameCondition;\n  SQL := SQL + ' ORDER BY attname';\n\n  Permissions := TStringList.Create;\n  PermissionsExp := TStringList.Create;\n  try\n    with GetConnection.CreateStatement.ExecuteQuery(SQL) do\n    begin\n      while Next do\n      begin\n        //SchemaName := GetStringByName('nspname');\n        //TableName := GetStringByName('relname');\n        Column := GetStringByName('attname');\n        Owner := GetStringByName('usename');\n        Permissions.Clear;\n        ParseACLArray(Permissions, GetStringByName('relacl'));\n        for I := 0 to Permissions.Count-1 do\n        begin\n          PutSplitString(PermissionsExp, Permissions.Strings[I], '=');\n          if PermissionsExp.Count < 2 then\n            Continue;\n          Grantee := PermissionsExp.Strings[0];\n          if Grantee = '' then\n            Grantee := 'PUBLIC';\n          Privileges := PermissionsExp.Strings[1];\n          for J := 1 to Length(Privileges) do\n          begin\n            if Owner = Grantee then\n              Grantable := 'YES'\n            else Grantable := 'NO';\n            Result.MoveToInsertRow;\n            Result.UpdateNull(1);\n            Result.UpdateString(2, Schema);\n            Result.UpdateString(3, Table);\n            Result.UpdateString(4, Column);\n            Result.UpdateString(5, Owner);\n            Result.UpdateString(6, Grantee);\n            Result.UpdateString(7, GetPrivilegeName(Privileges[J]));\n            Result.UpdateString(8, grantable);\n            Result.InsertRow;\n          end;\n        end;\n      end;\n      Close;\n    end;\n  finally\n    Permissions.Free;\n    PermissionsExp.Free;\n  end;\nend;\n\n{**\n  Gets a description of the access rights for each table available\n  in a catalog. Note that a table privilege applies to one or\n  more columns in the table. It would be wrong to assume that\n  this priviledge applies to all columns (this may be true for\n  some systems but is not true for all.)\n\n  <P>Only privileges matching the schema and table name\n  criteria are returned.  They are ordered by TABLE_SCHEM,\n  TABLE_NAME, and PRIVILEGE.\n\n  <P>Each privilige description has the following columns:\n   <OL>\n \t<LI><B>TABLE_CAT</B> String => table catalog (may be null)\n \t<LI><B>TABLE_SCHEM</B> String => table schema (may be null)\n \t<LI><B>TABLE_NAME</B> String => table name\n \t<LI><B>GRANTOR</B> => grantor of access (may be null)\n \t<LI><B>GRANTEE</B> String => grantee of access\n \t<LI><B>PRIVILEGE</B> String => name of access (SELECT,\n       INSERT, UPDATE, REFRENCES, ...)\n \t<LI><B>IS_GRANTABLE</B> String => \"YES\" if grantee is permitted\n       to grant to others; \"NO\" if not; null if unknown\n   </OL>\n\n  @param catalog a catalog name; \"\" retrieves those without a\n  catalog; null means drop catalog name from the selection criteria\n  @param schemaPattern a schema name pattern; \"\" retrieves those\n  without a schema\n  @param tableNamePattern a table name pattern\n  @return <code>ResultSet</code> - each row is a table privilege description\n  @see #getSearchStringEscape\n}\nfunction TZPostgreSQLDatabaseMetadata.UncachedGetTablePrivileges(const Catalog: string;\n  const SchemaPattern: string; const TableNamePattern: string): IZResultSet;\nvar\n  I, J: Integer;\n  SQL, SchemaName, TableName, Owner: string;\n  Privileges, Grantable, Grantee: string;\n  Permissions, PermissionsExp: TStringList;\n  TableNameCondition, SchemaCondition: string;\nbegin\n  SchemaCondition := ConstructNameCondition(SchemaPattern,'n.nspname');\n  TableNameCondition := ConstructNameCondition(TableNamePattern,'c.relname');\n  Result:=inherited UncachedGetTablePrivileges(Catalog, SchemaPattern, TableNamePattern);\n\n  if (GetDatabaseInfo as IZPostgreDBInfo).HasMinimumServerVersion(7, 3) then\n  begin\n    SQL := 'SELECT n.nspname,c.relname,u.usename,c.relacl '\n      + ' FROM pg_catalog.pg_namespace n, pg_catalog.pg_class c,'\n      + ' pg_catalog.pg_user u WHERE c.relnamespace = n.oid '\n      + ' AND u.usesysid = c.relowner AND c.relkind = ''r'' ';\n    if SchemaPattern <> '' then\n      SQL := SQL + ' AND ' + SchemaCondition;\n  end\n  else\n  begin\n    SQL := 'SELECT NULL::text AS nspname,c.relname,u.usename,c.relacl '\n      + ' FROM pg_class c, pg_user u WHERE u.usesysid = c.relowner '\n      + ' AND c.relkind = ''r'' ';\n  end;\n\n  SQL := SQL + ' AND ' + TableNameCondition\n    + ' ORDER BY nspname, relname';\n\n  Permissions := TStringList.Create;\n  PermissionsExp := TStringList.Create;\n  try\n    with GetConnection.CreateStatement.ExecuteQuery(SQL) do\n    begin\n      while Next do\n      begin\n        SchemaName := GetStringByName('nspname');\n        TableName := GetStringByName('relname');\n        Owner := GetStringByName('usename');\n        SchemaName := GetStringByName('nspname');\n        Permissions.Clear;\n        ParseACLArray(Permissions, GetStringByName('relacl'));\n        Permissions.Sort;\n        for I := 0 to Permissions.Count-1 do\n        begin\n          PutSplitString(PermissionsExp, Permissions.Strings[I], '=');\n          if PermissionsExp.Count < 2 then\n            Continue;\n          Grantee := PermissionsExp.Strings[0];\n          if Grantee = '' then\n          Grantee := 'PUBLIC';\n          Privileges := PermissionsExp.Strings[1];\n          for J := 1 to Length(Privileges) do\n          begin\n            if Owner = Grantee then\n              Grantable := 'YES'\n            else Grantable := 'NO';\n            Result.MoveToInsertRow;\n            Result.UpdateNull(1);\n            Result.UpdateString(2, SchemaName);\n            Result.UpdateString(3, TableName);\n            Result.UpdateString(4, Owner);\n            Result.UpdateString(5, Grantee);\n            Result.UpdateString(6, GetPrivilegeName(Privileges[J]));\n            Result.UpdateString(7, grantable);\n            Result.InsertRow;\n          end;\n        end;\n      end;\n      Close;\n    end;\n  finally\n    Permissions.Free;\n    PermissionsExp.Free;\n  end;\nend;\n\n{**\n  Gets a description of a table's columns that are automatically\n  updated when any value in a row is updated.  They are\n  unordered.\n\n  <P>Each column description has the following columns:\n   <OL>\n \t<LI><B>SCOPE</B> short => is not used\n \t<LI><B>COLUMN_NAME</B> String => column name\n \t<LI><B>DATA_TYPE</B> short => SQL data type from java.sql.Types\n \t<LI><B>TYPE_NAME</B> String => Data source dependent type name\n \t<LI><B>COLUMN_SIZE</B> int => precision\n \t<LI><B>BUFFER_LENGTH</B> int => length of column value in bytes\n \t<LI><B>DECIMAL_DIGITS</B> short\t => scale\n \t<LI><B>PSEUDO_COLUMN</B> short => is this a pseudo column\n       like an Oracle ROWID\n       <UL>\n       <LI> versionColumnUnknown - may or may not be pseudo column\n       <LI> versionColumnNotPseudo - is NOT a pseudo column\n       <LI> versionColumnPseudo - is a pseudo column\n       </UL>\n   </OL>\n\n  @param catalog a catalog name; \"\" retrieves those without a\n  catalog; null means drop catalog name from the selection criteria\n  @param schema a schema name; \"\" retrieves those without a schema\n  @param table a table name\n  @return <code>ResultSet</code> - each row is a column description\n  @exception SQLException if a database access error occurs\n}\nfunction TZPostgreSQLDatabaseMetadata.UncachedGetVersionColumns(const Catalog: string;\n  const Schema: string; const Table: string): IZResultSet;\nbegin\n    Result:=inherited UncachedGetVersionColumns(Catalog, Schema, Table);\n\n    Result.MoveToInsertRow;\n    Result.UpdateNull(1);\n    Result.UpdateString(2, 'ctid');\n    Result.UpdateInt(3, Ord(GetSQLTypeByName('tid')));\n    Result.UpdateString(4, 'tid');\n    Result.UpdateNull(5);\n    Result.UpdateNull(6);\n    Result.UpdateNull(7);\n    Result.UpdateInt(4, Ord(vcPseudo));\n    Result.InsertRow;\nend;\n\n{**\n  Gets a description of a table's primary key columns.  They\n  are ordered by COLUMN_NAME.\n\n  <P>Each primary key column description has the following columns:\n   <OL>\n \t<LI><B>TABLE_CAT</B> String => table catalog (may be null)\n \t<LI><B>TABLE_SCHEM</B> String => table schema (may be null)\n \t<LI><B>TABLE_NAME</B> String => table name\n \t<LI><B>COLUMN_NAME</B> String => column name\n \t<LI><B>KEY_SEQ</B> short => sequence number within primary key\n \t<LI><B>PK_NAME</B> String => primary key name (may be null)\n   </OL>\n\n  @param catalog a catalog name; \"\" retrieves those without a\n  catalog; null means drop catalog name from the selection criteria\n  @param schema a schema name; \"\" retrieves those\n  without a schema\n  @param table a table name\n  @return <code>ResultSet</code> - each row is a primary key column description\n  @exception SQLException if a database access error occurs\n}\nfunction TZPostgreSQLDatabaseMetadata.UncachedGetPrimaryKeys(const Catalog: string;\n  const Schema: string; const Table: string): IZResultSet;\nvar\n  SQL, Select, From, Where: string;\n  TableNameCondition, SchemaCondition: string;\nbegin\n  SchemaCondition := ConstructNameCondition(Schema,'n.nspname');\n  TableNameCondition := ConstructNameCondition(Table,'ct.relname');\n  if (GetDatabaseInfo as IZPostgreDBInfo).HasMinimumServerVersion(7, 3) then\n  begin\n    Select := 'SELECT NULL AS TABLE_CAT, n.nspname AS TABLE_SCHEM,';\n    From := ' FROM pg_catalog.pg_namespace n, pg_catalog.pg_class ct,'\n      + ' pg_catalog.pg_class ci, pg_catalog.pg_attribute a,'\n      + ' pg_catalog.pg_index i';\n    Where := ' AND ct.relnamespace = n.oid';\n    if Schema <> '' then\n      Where := Where + ' AND ' + SchemaCondition;\n  end\n  else\n  begin\n    Select := 'SELECT NULL AS TABLE_CAT, NULL AS TABLE_SCHEM,';\n    From := ' FROM pg_class ct, pg_class ci, pg_attribute a, pg_index i';\n  end;\n  SQL := Select + ' ct.relname AS TABLE_NAME, a.attname AS COLUMN_NAME,'\n    + ' a.attnum AS KEY_SEQ, ci.relname AS PK_NAME'\n    + From\n    + ' WHERE ct.oid=i.indrelid AND ci.oid=i.indexrelid'\n    + ' AND a.attrelid=ci.oid AND i.indisprimary';\n  if Table <> '' then\n     SQL := SQL + ' AND ' + TableNameCondition;\n  SQL := SQL + Where + ' ORDER BY table_name, pk_name, key_seq';\n\n  Result := CopyToVirtualResultSet(\n    GetConnection.CreateStatement.ExecuteQuery(SQL),\n    ConstructVirtualResultSet(PrimaryKeyColumnsDynArray));\nend;\n\n{**\n  Gets a description of the primary key columns that are\n  referenced by a table's foreign key columns (the primary keys\n  imported by a table).  They are ordered by PKTABLE_CAT,\n  PKTABLE_SCHEM, PKTABLE_NAME, and KEY_SEQ.\n\n  <P>Each primary key column description has the following columns:\n   <OL>\n \t<LI><B>PKTABLE_CAT</B> String => primary key table catalog\n       being imported (may be null)\n \t<LI><B>PKTABLE_SCHEM</B> String => primary key table schema\n       being imported (may be null)\n \t<LI><B>PKTABLE_NAME</B> String => primary key table name\n       being imported\n \t<LI><B>PKCOLUMN_NAME</B> String => primary key column name\n       being imported\n \t<LI><B>FKTABLE_CAT</B> String => foreign key table catalog (may be null)\n \t<LI><B>FKTABLE_SCHEM</B> String => foreign key table schema (may be null)\n \t<LI><B>FKTABLE_NAME</B> String => foreign key table name\n \t<LI><B>FKCOLUMN_NAME</B> String => foreign key column name\n \t<LI><B>KEY_SEQ</B> short => sequence number within foreign key\n \t<LI><B>UPDATE_RULE</B> short => What happens to\n        foreign key when primary is updated:\n       <UL>\n       <LI> importedNoAction - do not allow update of primary\n                key if it has been imported\n       <LI> importedKeyCascade - change imported key to agree\n                with primary key update\n       <LI> importedKeySetNull - change imported key to NULL if\n                its primary key has been updated\n       <LI> importedKeySetDefault - change imported key to default values\n                if its primary key has been updated\n       <LI> importedKeyRestrict - same as importedKeyNoAction\n                                  (for ODBC 2.x compatibility)\n       </UL>\n \t<LI><B>DELETE_RULE</B> short => What happens to\n       the foreign key when primary is deleted.\n       <UL>\n       <LI> importedKeyNoAction - do not allow delete of primary\n                key if it has been imported\n       <LI> importedKeyCascade - delete rows that import a deleted key\n       <LI> importedKeySetNull - change imported key to NULL if\n                its primary key has been deleted\n       <LI> importedKeyRestrict - same as importedKeyNoAction\n                                  (for ODBC 2.x compatibility)\n       <LI> importedKeySetDefault - change imported key to default if\n                its primary key has been deleted\n       </UL>\n \t<LI><B>FK_NAME</B> String => foreign key name (may be null)\n \t<LI><B>PK_NAME</B> String => primary key name (may be null)\n \t<LI><B>DEFERRABILITY</B> short => can the evaluation of foreign key\n       constraints be deferred until commit\n       <UL>\n       <LI> importedKeyInitiallyDeferred - see SQL92 for definition\n       <LI> importedKeyInitiallyImmediate - see SQL92 for definition\n       <LI> importedKeyNotDeferrable - see SQL92 for definition\n       </UL>\n   </OL>\n\n  @param catalog a catalog name; \"\" retrieves those without a\n  catalog; null means drop catalog name from the selection criteria\n  @param schema a schema name; \"\" retrieves those\n  without a schema\n  @param table a table name\n  @return <code>ResultSet</code> - each row is a primary key column description\n  @see #getExportedKeys\n}\nfunction TZPostgreSQLDatabaseMetadata.UncachedGetImportedKeys(const Catalog: string;\n  const Schema: string; const Table: string): IZResultSet;\nvar\n  SQL: string;\n  KeySequence: Integer;\n  TableNameCondition, SchemaCondition, CatalogCondition: string;\nbegin\n  CatalogCondition := ConstructNameCondition(Catalog,'kcu.table_catalog');\n  SchemaCondition := ConstructNameCondition(Schema,'kcu.constraint_schema');\n  TableNameCondition := ConstructNameCondition(Table,'kcu.table_name');\n  if (GetDatabaseInfo as IZPostgreDBInfo).HasMinimumServerVersion(7, 4) then\n  begin\n    Result:=inherited UncachedGetImportedKeys(Catalog, Schema, Table);\n    SQL := 'SELECT '+\n      'tc.constraint_catalog as PKTABLE_CAT, '+\n      'tc.constraint_schema as PKTABLE_SCHEM, '+\n      'ccu.table_name as PKTABLE_NAME, '+\n      'ccu.column_name as PKCOLUMN_NAME, '+\n      'kcu.table_catalog as FKTABLE_CAT, '+\n      'kcu.constraint_schema as FKTABLE_SCHEM, '+\n      'kcu.table_name as PKTABLE_NAME, '+\n      'kcu.column_name as FKCOLUMN_NAME, '+\n      'rf.update_rule as UPDATE_RULE, '+\n      'rf.delete_rule as DELETE_RULE, '+\n      'kcu.constraint_name as FK_NAME, '+\n      'kcu.ordinal_position as PK_NAME, '+\n      'tc.is_deferrable as DEFERRABILITY '+\n      'FROM information_schema.table_constraints AS tc '+\n      'JOIN information_schema.key_column_usage AS kcu ON tc.constraint_name = kcu.constraint_name '+\n      'JOIN information_schema.constraint_column_usage AS ccu ON ccu.constraint_name = tc.constraint_name '+\n      'join information_schema.referential_constraints as rf on rf.constraint_name = tc.constraint_name '+\n      'WHERE constraint_type = ''FOREIGN KEY''';\n    if Catalog <> '' then\n      SQL := SQL + ' and ' + CatalogCondition;\n    if Schema <> '' then\n      SQL := SQL + ' and ' + SchemaCondition;\n    if Table <> '' then\n      SQL := SQL + ' and ' + TableNameCondition;\n\n    KeySequence := 0;\n    with GetConnection.CreateStatement.ExecuteQuery(SQL) do\n    begin\n      while Next do\n      begin\n        Inc(KeySequence);\n        Result.MoveToInsertRow;\n        Result.UpdateNull(1); //PKTABLE_CAT\n        Result.UpdateString(2, GetString(2)); //PKTABLE_SCHEM\n        Result.UpdateString(3, GetString(3)); //PKTABLE_NAME\n        Result.UpdateString(4, GetString(4)); //PKCOLUMN_NAME\n        //Result.UpdateString(5, GetString(5)); //PKTABLE_CAT\n        Result.UpdateString(5, Catalog); //PKTABLE_CAT\n        Result.UpdateString(6, GetString(6)); //FKTABLE_SCHEM\n        Result.UpdateString(7, GetString(7)); //FKTABLE_NAME\n        Result.UpdateString(8, GetString(8)); //FKCOLUMN_NAME\n        Result.UpdateShort(9, KeySequence); //KEY_SEQ\n        Result.UpdateShort(10, Ord(GetRuleType(GetString(9)))); //UPDATE_RULE\n        Result.UpdateShort(11, Ord(GetRuleType(GetString(10)))); //DELETE_RULE\n        Result.UpdateString(12, GetString(11)); //FK_NAME\n        Result.UpdateString(13, GetString(12)); //PK_NAME\n        if GetString(13) = 'NO' then\n          Result.UpdateShort(14, Ord(ikNotDeferrable)) //DEFERRABILITY\n        else\n          Result.UpdateShort(14, Ord(ikInitiallyDeferred)); //DEFERRABILITY\n        Result.InsertRow;\n      end;\n      Close;\n    end;\n  end\n  else\n    Result := UncachedGetCrossReference('', '', '', Catalog, Schema, Table);\nend;\n\n{**\n  Gets a description of the foreign key columns that reference a\n  table's primary key columns (the foreign keys exported by a\n  table).  They are ordered by FKTABLE_CAT, FKTABLE_SCHEM,\n  FKTABLE_NAME, and KEY_SEQ.\n\n  <P>Each foreign key column description has the following columns:\n   <OL>\n \t<LI><B>PKTABLE_CAT</B> String => primary key table catalog (may be null)\n \t<LI><B>PKTABLE_SCHEM</B> String => primary key table schema (may be null)\n \t<LI><B>PKTABLE_NAME</B> String => primary key table name\n \t<LI><B>PKCOLUMN_NAME</B> String => primary key column name\n \t<LI><B>FKTABLE_CAT</B> String => foreign key table catalog (may be null)\n       being exported (may be null)\n \t<LI><B>FKTABLE_SCHEM</B> String => foreign key table schema (may be null)\n       being exported (may be null)\n \t<LI><B>FKTABLE_NAME</B> String => foreign key table name\n       being exported\n \t<LI><B>FKCOLUMN_NAME</B> String => foreign key column name\n       being exported\n \t<LI><B>KEY_SEQ</B> short => sequence number within foreign key\n \t<LI><B>UPDATE_RULE</B> short => What happens to\n        foreign key when primary is updated:\n       <UL>\n       <LI> importedNoAction - do not allow update of primary\n                key if it has been imported\n       <LI> importedKeyCascade - change imported key to agree\n                with primary key update\n       <LI> importedKeySetNull - change imported key to NULL if\n                its primary key has been updated\n       <LI> importedKeySetDefault - change imported key to default values\n                if its primary key has been updated\n       <LI> importedKeyRestrict - same as importedKeyNoAction\n                                  (for ODBC 2.x compatibility)\n       </UL>\n \t<LI><B>DELETE_RULE</B> short => What happens to\n       the foreign key when primary is deleted.\n       <UL>\n       <LI> importedKeyNoAction - do not allow delete of primary\n                key if it has been imported\n       <LI> importedKeyCascade - delete rows that import a deleted key\n       <LI> importedKeySetNull - change imported key to NULL if\n                its primary key has been deleted\n       <LI> importedKeyRestrict - same as importedKeyNoAction\n                                  (for ODBC 2.x compatibility)\n       <LI> importedKeySetDefault - change imported key to default if\n                its primary key has been deleted\n       </UL>\n \t<LI><B>FK_NAME</B> String => foreign key name (may be null)\n \t<LI><B>PK_NAME</B> String => primary key name (may be null)\n \t<LI><B>DEFERRABILITY</B> short => can the evaluation of foreign key\n       constraints be deferred until commit\n       <UL>\n       <LI> importedKeyInitiallyDeferred - see SQL92 for definition\n       <LI> importedKeyInitiallyImmediate - see SQL92 for definition\n       <LI> importedKeyNotDeferrable - see SQL92 for definition\n       </UL>\n   </OL>\n\n  @param catalog a catalog name; \"\" retrieves those without a\n  catalog; null means drop catalog name from the selection criteria\n  @param schema a schema name; \"\" retrieves those\n  without a schema\n  @param table a table name\n  @return <code>ResultSet</code> - each row is a foreign key column description\n  @see #getImportedKeys\n}\nfunction TZPostgreSQLDatabaseMetadata.UncachedGetExportedKeys(const Catalog: string;\n  const Schema: string; const Table: string): IZResultSet;\nvar\n  SQL: string;\n  KeySequence: Integer;\n  TableNameCondition, SchemaCondition, CatalogCondition: string;\nbegin\n  CatalogCondition := ConstructNameCondition(Catalog,'tc.constraint_catalog');\n  SchemaCondition := ConstructNameCondition(Schema,'tc.constraint_schema');\n  TableNameCondition := ConstructNameCondition(Table,'ccu.table_name');\n  if (GetDatabaseInfo as IZPostgreDBInfo).HasMinimumServerVersion(7, 4) then\n  begin\n    Result:=inherited UncachedGetImportedKeys(Catalog, Schema, Table);\n    SQL := 'SELECT '+\n      'tc.constraint_catalog as PKTABLE_CAT, '+\n      'tc.constraint_schema as PKTABLE_SCHEM, '+\n      'ccu.table_name as PKTABLE_NAME, '+\n      'ccu.column_name as PKCOLUMN_NAME, '+\n      'kcu.table_catalog as FKTABLE_CAT, '+\n      'kcu.constraint_schema as FKTABLE_SCHEM, '+\n      'kcu.table_name as PKTABLE_NAME, '+\n      'kcu.column_name as FKCOLUMN_NAME, '+\n      'rf.update_rule as UPDATE_RULE, '+\n      'rf.delete_rule as DELETE_RULE, '+\n      'kcu.constraint_name as FK_NAME, '+\n      'kcu.ordinal_position as PK_NAME, '+\n      'tc.is_deferrable as DEFERRABILITY '+\n      'FROM information_schema.table_constraints AS tc '+\n      'JOIN information_schema.key_column_usage AS kcu ON tc.constraint_name = kcu.constraint_name '+\n      'JOIN information_schema.constraint_column_usage AS ccu ON ccu.constraint_name = tc.constraint_name '+\n      'join information_schema.referential_constraints as rf on rf.constraint_name = tc.constraint_name '+\n      'WHERE constraint_type = ''FOREIGN KEY''';\n    if Catalog <> '' then\n      SQL := SQL + ' and ' + CatalogCondition;\n    if Schema <> '' then\n      SQL := SQL + ' and ' + SchemaCondition;\n    if Table <> '' then\n      SQL := SQL + ' and ' + TableNameCondition;\n    SQL := SQL + ' order by kcu.table_name;';\n\n    KeySequence := 0;\n    with GetConnection.CreateStatement.ExecuteQuery(SQL) do\n    begin\n      while Next do\n      begin\n        Inc(KeySequence);\n        Result.MoveToInsertRow;\n        Result.UpdateNull(1); //PKTABLE_CAT\n        Result.UpdateString(2, GetString(2)); //PKTABLE_SCHEM\n        Result.UpdateString(3, GetString(3)); //PKTABLE_NAME\n        Result.UpdateString(4, GetString(4)); //PKCOLUMN_NAME\n        //Result.UpdateString(5, GetString(5)); //PKTABLE_CAT\n        Result.UpdateString(5, Catalog); //PKTABLE_CAT\n        Result.UpdateString(6, GetString(6)); //FKTABLE_SCHEM\n        Result.UpdateString(7, GetString(7)); //FKTABLE_NAME\n        Result.UpdateString(8, GetString(8)); //FKCOLUMN_NAME\n        Result.UpdateShort(9, KeySequence); //KEY_SEQ\n        Result.UpdateShort(10, Ord(GetRuleType(GetString(9)))); //UPDATE_RULE\n        Result.UpdateShort(11, Ord(GetRuleType(GetString(10)))); //DELETE_RULE\n        Result.UpdateString(12, GetString(11)); //FK_NAME\n        Result.UpdateString(13, GetString(12)); //PK_NAME\n        if GetString(13) = 'NO' then\n          Result.UpdateShort(14, Ord(ikNotDeferrable)) //DEFERRABILITY\n        else\n          Result.UpdateShort(14, Ord(ikInitiallyDeferred)); //DEFERRABILITY\n        Result.InsertRow;\n      end;\n      Close;\n    end;\n  end\n  else\n    Result := UncachedGetCrossReference('', '', '', Catalog, Schema, Table);\nend;\n\n{**\n  Gets a description of the foreign key columns in the foreign key\n  table that reference the primary key columns of the primary key\n  table (describe how one table imports another's key.) This\n  should normally return a single foreign key/primary key pair\n  (most tables only import a foreign key from a table once.)  They\n  are ordered by FKTABLE_CAT, FKTABLE_SCHEM, FKTABLE_NAME, and\n  KEY_SEQ.\n\n  <P>Each foreign key column description has the following columns:\n   <OL>\n \t<LI><B>PKTABLE_CAT</B> String => primary key table catalog (may be null)\n \t<LI><B>PKTABLE_SCHEM</B> String => primary key table schema (may be null)\n \t<LI><B>PKTABLE_NAME</B> String => primary key table name\n \t<LI><B>PKCOLUMN_NAME</B> String => primary key column name\n \t<LI><B>FKTABLE_CAT</B> String => foreign key table catalog (may be null)\n       being exported (may be null)\n \t<LI><B>FKTABLE_SCHEM</B> String => foreign key table schema (may be null)\n       being exported (may be null)\n \t<LI><B>FKTABLE_NAME</B> String => foreign key table name\n       being exported\n \t<LI><B>FKCOLUMN_NAME</B> String => foreign key column name\n       being exported\n \t<LI><B>KEY_SEQ</B> short => sequence number within foreign key\n \t<LI><B>UPDATE_RULE</B> short => What happens to\n        foreign key when primary is updated:\n       <UL>\n       <LI> importedNoAction - do not allow update of primary\n                key if it has been imported\n       <LI> importedKeyCascade - change imported key to agree\n                with primary key update\n       <LI> importedKeySetNull - change imported key to NULL if\n                its primary key has been updated\n       <LI> importedKeySetDefault - change imported key to default values\n                if its primary key has been updated\n       <LI> importedKeyRestrict - same as importedKeyNoAction\n                                  (for ODBC 2.x compatibility)\n       </UL>\n \t<LI><B>DELETE_RULE</B> short => What happens to\n       the foreign key when primary is deleted.\n       <UL>\n       <LI> importedKeyNoAction - do not allow delete of primary\n                key if it has been imported\n       <LI> importedKeyCascade - delete rows that import a deleted key\n       <LI> importedKeySetNull - change imported key to NULL if\n                its primary key has been deleted\n       <LI> importedKeyRestrict - same as importedKeyNoAction\n                                  (for ODBC 2.x compatibility)\n       <LI> importedKeySetDefault - change imported key to default if\n                its primary key has been deleted\n       </UL>\n \t<LI><B>FK_NAME</B> String => foreign key name (may be null)\n \t<LI><B>PK_NAME</B> String => primary key name (may be null)\n \t<LI><B>DEFERRABILITY</B> short => can the evaluation of foreign key\n       constraints be deferred until commit\n       <UL>\n       <LI> importedKeyInitiallyDeferred - see SQL92 for definition\n       <LI> importedKeyInitiallyImmediate - see SQL92 for definition\n       <LI> importedKeyNotDeferrable - see SQL92 for definition\n       </UL>\n   </OL>\n\n  @param primaryCatalog a catalog name; \"\" retrieves those without a\n  catalog; null means drop catalog name from the selection criteria\n  @param primarySchema a schema name; \"\" retrieves those\n  without a schema\n  @param primaryTable the table name that exports the key\n  @param foreignCatalog a catalog name; \"\" retrieves those without a\n  catalog; null means drop catalog name from the selection criteria\n  @param foreignSchema a schema name; \"\" retrieves those\n  without a schema\n  @param foreignTable the table name that imports the key\n  @return <code>ResultSet</code> - each row is a foreign key column description\n  @see #getImportedKeys\n}\nfunction TZPostgreSQLDatabaseMetadata.UncachedGetCrossReference(const PrimaryCatalog: string;\n  const PrimarySchema: string; const PrimaryTable: string; const ForeignCatalog: string;\n  const ForeignSchema: string; const ForeignTable: string): IZResultSet;\nvar\n  SQL, Select, From, Where: string;\n  DeleteRule, UpdateRule, Rule: string;\n  {FKeyName, }FKeyColumn, PKeyColumn, Targs: string;\n  Action, KeySequence, Advance: Integer;\n  List: TStrings;\n  Deferrability: Integer;\n  Deferrable, InitiallyDeferred: Boolean;\nbegin\n  Result:=inherited UncachedGetCrossReference(PrimaryCatalog, PrimarySchema, PrimaryTable,\n                                              ForeignCatalog, ForeignSchema, ForeignTable);\n\n  if (GetDatabaseInfo as IZPostgreDBInfo).HasMinimumServerVersion(7, 4) then\n  begin\n    SQL := 'SELECT '+\n      'tc.constraint_catalog as PKTABLE_CAT, '+\n      'tc.constraint_schema as PKTABLE_SCHEM, '+\n      'ccu.table_name as PKTABLE_NAME, '+\n      'ccu.column_name as PKCOLUMN_NAME, '+\n      'kcu.table_catalog as FKTABLE_CAT, '+\n      'kcu.constraint_schema as FKTABLE_SCHEM, '+\n      'kcu.table_name as PKTABLE_NAME, '+\n      'kcu.column_name as FKCOLUMN_NAME, '+\n      'rf.update_rule as UPDATE_RULE, '+\n      'rf.delete_rule as DELETE_RULE, '+\n      'kcu.constraint_name as FK_NAME, '+\n      'kcu.ordinal_position as PK_NAME, '+\n      'tc.is_deferrable as DEFERRABILITY '+\n      'FROM information_schema.table_constraints AS tc '+\n      'JOIN information_schema.key_column_usage AS kcu ON tc.constraint_name = kcu.constraint_name '+\n      'JOIN information_schema.constraint_column_usage AS ccu ON ccu.constraint_name = tc.constraint_name '+\n      'join information_schema.referential_constraints as rf on rf.constraint_name = tc.constraint_name '+\n      'WHERE constraint_type = ''FOREIGN KEY''';\n    if PrimaryCatalog <> '' then\n      SQL := SQL + ' and tc.constraint_catalog = '''+PrimaryCatalog+'''';\n    if PrimarySchema <> '' then\n      SQL := SQL + ' and tc.constraint_schema = '''+PrimarySchema+'''';\n    if PrimaryTable <> '' then\n      SQL := SQL + ' and ccu.table_name = '''+PrimaryTable+'''';\n    if ForeignCatalog <> '' then\n      SQL := SQL + ' and kcu.table_catalog = '''+ForeignCatalog+'''';\n    if ForeignSchema <> '' then\n      SQL := SQL + ' and kcu.constraint_schema = '''+ForeignSchema+'''';\n    if ForeignTable <> '' then\n      SQL := SQL + ' and kcu.table_name = '''+ForeignTable+'''';\n\n    KeySequence := 0;\n    with GetConnection.CreateStatement.ExecuteQuery(SQL) do\n    begin\n      while Next do\n      begin\n        Inc(KeySequence);\n        Result.MoveToInsertRow;\n        //Result.UpdateString(1, GetString(1)); //PKTABLE_CAT\n        Result.UpdateString(1, PrimaryCatalog); //PKTABLE_CAT\n        Result.UpdateString(2, GetString(2)); //PKTABLE_SCHEM\n        Result.UpdateString(3, GetString(3)); //PKTABLE_NAME\n        Result.UpdateString(4, GetString(4)); //PKCOLUMN_NAME\n        //Result.UpdateString(5, GetString(5)); //PKTABLE_CAT\n        Result.UpdateString(5, ForeignCatalog); //PKTABLE_CAT\n        Result.UpdateString(6, GetString(6)); //FKTABLE_SCHEM\n        Result.UpdateString(7, GetString(7)); //FKTABLE_NAME\n        Result.UpdateString(8, GetString(8)); //FKCOLUMN_NAME\n        Result.UpdateShort(9, KeySequence); //KEY_SEQ\n        Result.UpdateShort(10, Ord(GetRuleType(GetString(9)))); //UPDATE_RULE\n        Result.UpdateShort(11, Ord(GetRuleType(GetString(10)))); //DELETE_RULE\n        Result.UpdateString(12, GetString(11)); //FK_NAME\n        Result.UpdateString(13, GetString(12)); //PK_NAME\n        if GetString(13) = 'NO' then\n          Result.UpdateShort(14, Ord(ikNotDeferrable)) //DEFERRABILITY\n        else\n          Result.UpdateShort(14, Ord(ikInitiallyDeferred)); //DEFERRABILITY\n        Result.InsertRow;\n      end;\n      Close;\n    end;\n  end\n  else\n  begin\n    if (GetDatabaseInfo as IZPostgreDBInfo).HasMinimumServerVersion(7, 3) then\n    begin\n      Select := 'SELECT DISTINCT n1.nspname as pnspname,n2.nspname as fnspname,';\n      From := ' FROM pg_catalog.pg_namespace n1 JOIN pg_catalog.pg_class c1'\n        + ' ON (c1.relnamespace = n1.oid) JOIN pg_catalog.pg_index i'\n        + ' ON (c1.oid=i.indrelid) JOIN pg_catalog.pg_class ic'\n        + ' ON (i.indexrelid=ic.oid) JOIN pg_catalog.pg_attribute a'\n        + ' ON (ic.oid=a.attrelid), pg_catalog.pg_namespace n2'\n        + ' JOIN pg_catalog.pg_class c2 ON (c2.relnamespace=n2.oid),'\n        + ' pg_catalog.pg_trigger t1 JOIN pg_catalog.pg_proc p1'\n        + ' ON (t1.tgfoid=p1.oid), pg_catalog.pg_trigger t2'\n        + ' JOIN pg_catalog.pg_proc p2 ON (t2.tgfoid=p2.oid)';\n      Where := '';\n      if PrimarySchema <> ''then\n      begin\n        Where := Where + ' AND n1.nspname = '\n          + EscapeString(PrimarySchema);\n      end;\n      if ForeignSchema <> '' then\n      begin\n        Where := Where + ' AND n2.nspname = '\n          + EscapeString(ForeignSchema);\n      end;\n    end\n    else\n    begin\n      Select := 'SELECT DISTINCT NULL::text as pnspname, NULL::text as fnspname,';\n      From := ' FROM pg_class c1 JOIN pg_index i ON (c1.oid=i.indrelid)'\n        + ' JOIN pg_class ic ON (i.indexrelid=ic.oid) JOIN pg_attribute a'\n        + ' ON (ic.oid=a.attrelid), pg_class c2, pg_trigger t1'\n        + ' JOIN pg_proc p1 ON (t1.tgfoid=p1.oid), pg_trigger t2'\n        + ' JOIN pg_proc p2 ON (t2.tgfoid=p2.oid)';\n    end;\n\n    SQL := Select + ' c1.relname as prelname, c2.relname as frelname,'\n      + ' t1.tgconstrname, a.attnum as keyseq, ic.relname as fkeyname,'\n      + ' t1.tgdeferrable, t1.tginitdeferred, t1.tgnargs,t1.tgargs,'\n      + ' p1.proname as updaterule, p2.proname as deleterule'\n      + From\n      + ' WHERE (t1.tgrelid=c1.oid AND t1.tgisconstraint'\n      + ' AND t1.tgconstrrelid=c2.oid AND p1.proname'\n      + ' LIKE ' + EscapeString('RI\\_FKey\\_%\\_upd')\n      + ') AND (t2.tgrelid=c1.oid'\n      + ' AND t2.tgisconstraint AND t2.tgconstrrelid=c2.oid '\n      + ' AND p2.proname LIKE ' + EscapeString('RI\\_FKey\\_%\\_del')\n      + ') AND i.indisprimary'\n      + Where;\n    if PrimaryTable <> '' then\n      SQL := SQL + ' AND c1.relname=' + EscapeString(PrimaryTable);\n    if ForeignTable <> '' then\n      SQL := SQL + ' AND c2.relname=' + EscapeString(ForeignTable);\n    SQL := SQL + ' ORDER BY ';\n\n    if PrimaryTable <> '' then\n    begin\n      if (GetDatabaseInfo as IZPostgreDBInfo).HasMinimumServerVersion(7, 3) then\n        SQL := SQL + 'fnspname, ';\n      SQL := SQL + 'frelname';\n    end\n    else\n    begin\n      if (GetDatabaseInfo as IZPostgreDBInfo).HasMinimumServerVersion(7, 3) then\n        SQL := SQL + 'pnspname, ';\n      SQL := SQL + 'prelname';\n    end;\n\n    SQL := SQL + ', keyseq';\n\n    List := TStringList.Create;\n    try\n      with GetConnection.CreateStatement.ExecuteQuery(SQL) do\n      begin\n        while Next do\n        begin\n          Result.MoveToInsertRow;\n          Result.UpdateString(2, GetString(1));\n          Result.UpdateString(6, GetString(2));\n          Result.UpdateString(3, GetString(3));\n          Result.UpdateString(7, GetString(4));\n\n          //FKeyName := GetString(5);\n          UpdateRule := GetString(12);\n          if UpdateRule <> '' then\n          begin\n            Rule := Copy(UpdateRule, 9, Length(UpdateRule) - 12);\n            Action := Ord(ikNoAction);\n            if (Rule = '') or (Rule = 'noaction') then\n              Action := Ord(ikNoAction);\n            if Rule = 'cascade' then\n              Action := Ord(ikCascade);\n            if Rule = 'setnull' then\n              Action := Ord(ikSetNull);\n            if Rule = 'setdefault' then\n              Action := Ord(ikSetDefault);\n            if Rule = 'restrict' then\n             Action := Ord(ikRestrict);\n            Result.UpdateInt(10, Action);\n          end;\n\n          DeleteRule := GetString(13);\n          if DeleteRule <> '' then\n          begin\n            Rule := Copy(DeleteRule, 9, Length(DeleteRule) - 12);\n            Action := Ord(ikNoAction);\n            if Rule = 'cascade' then\n              Action := Ord(ikCascade);\n            if Rule = 'setnull' then\n              Action := Ord(ikSetNull);\n            if Rule = 'setdefault' then\n              Action := Ord(ikSetDefault);\n            if Rule = 'restrict' then\n              Action := Ord(ikRestrict);\n            Result.UpdateInt(11, Action);\n          end;\n\n          KeySequence := GetInt(6);\n          Targs := GetString(11);\n\n          //<unnamed>\\000ww\\000vv\\000UNSPECIFIED\\000m\\000a\\000n\\000b\\000\n          //for Postgresql 7.3\n          //$1\\000ww\\000vv\\000UNSPECIFIED\\000m\\000a\\000n\\000b\\000\n          //$2\\000ww\\000vv\\000UNSPECIFIED\\000m\\000a\\000n\\000b\\000\n\n          Advance := 4 + (KeySequence - 1) * 2;\n          PutSplitStringEx(List, Targs, '\\000');\n\n          if Advance <= List.Count-1 then\n            FKeyColumn := List.Strings[Advance];\n          if Advance + 1 <= List.Count-1 then\n            PKeyColumn := List.Strings[Advance+1];\n          Result.UpdateString(4, PKeyColumn);\n          Result.UpdateString(8, FKeyColumn);\n          Result.UpdateString(9, GetString(6)); //KEY_SEQ\n\n          if List.Strings[0] = '<unnamed>' then\n            Result.UpdateString(12, Targs) //FK_NAME\n          else Result.UpdateString(12, List.Strings[0]); //FK_NAME\n\n          Result.UpdateString(13, GetString(6)); //PK_ NAME\n\n          Deferrability := Ord(ikNotDeferrable);\n          Deferrable := GetBoolean(8);\n          InitiallyDeferred := GetBoolean(9);\n          if Deferrable then\n          begin\n            if InitiallyDeferred then\n              Deferrability := Ord(ikInitiallyDeferred)\n            else Deferrability := Ord(ikInitiallyImmediate);\n          end;\n          Result.UpdateInt(14, Deferrability);\n          Result.InsertRow;\n        end;\n        Close;\n      end;\n    finally\n      List.Free;\n    end;\n  end;\nend;\n\n{**\n  Gets a description of all the standard SQL types supported by\n  this database. They are ordered by DATA_TYPE and then by how\n  closely the data type maps to the corresponding JDBC SQL type.\n\n  <P>Each type description has the following columns:\n   <OL>\n \t<LI><B>TYPE_NAME</B> String => Type name\n \t<LI><B>DATA_TYPE</B> short => SQL data type from java.sql.Types\n \t<LI><B>PRECISION</B> int => maximum precision\n \t<LI><B>LITERAL_PREFIX</B> String => prefix used to quote a literal\n       (may be null)\n \t<LI><B>LITERAL_SUFFIX</B> String => suffix used to quote a literal\n        (may be null)\n \t<LI><B>CREATE_PARAMS</B> String => parameters used in creating\n       the type (may be null)\n \t<LI><B>NULLABLE</B> short => can you use NULL for this type?\n       <UL>\n       <LI> typeNoNulls - does not allow NULL values\n       <LI> typeNullable - allows NULL values\n       <LI> typeNullableUnknown - nullability unknown\n       </UL>\n \t<LI><B>CASE_SENSITIVE</B> Boolean=> is it case sensitive?\n \t<LI><B>SEARCHABLE</B> short => can you use \"WHERE\" based on this type:\n       <UL>\n       <LI> typePredNone - No support\n       <LI> typePredChar - Only supported with WHERE .. LIKE\n       <LI> typePredBasic - Supported except for WHERE .. LIKE\n       <LI> typeSearchable - Supported for all WHERE ..\n       </UL>\n \t<LI><B>UNSIGNED_ATTRIBUTE</B> Boolean => is it unsigned?\n \t<LI><B>FIXED_PREC_SCALE</B> Boolean => can it be a money value?\n \t<LI><B>AUTO_INCREMENT</B> Boolean => can it be used for an\n       auto-increment value?\n \t<LI><B>LOCAL_TYPE_NAME</B> String => localized version of type name\n       (may be null)\n \t<LI><B>MINIMUM_SCALE</B> short => minimum scale supported\n \t<LI><B>MAXIMUM_SCALE</B> short => maximum scale supported\n \t<LI><B>SQL_DATA_TYPE</B> int => unused\n \t<LI><B>SQL_DATETIME_SUB</B> int => unused\n \t<LI><B>NUM_PREC_RADIX</B> int => usually 2 or 10\n   </OL>\n\n  @return <code>ResultSet</code> - each row is an SQL type description\n}\nfunction TZPostgreSQLDatabaseMetadata.UncachedGetTypeInfo: IZResultSet;\nvar\n  SQL: string;\nbegin\n    Result:=inherited UncachedGetTypeInfo;\n\n    if (GetDatabaseInfo as IZPostgreDBInfo).HasMinimumServerVersion(7, 3) then\n      SQL := ' SELECT typname FROM pg_catalog.pg_type '\n    else SQL := ' SELECT typname FROM pg_type ';\n\n    with GetConnection.CreateStatement.ExecuteQuery(SQL) do\n    begin\n      while Next do\n      begin\n        Result.MoveToInsertRow;\n        Result.UpdateString(1, GetString(1));\n        Result.UpdateInt(2, Ord(GetSQLTypeByName(GetString(1))));\n        Result.UpdateInt(3, 9);\n        Result.UpdateInt(7, Ord(ntNoNulls));\n        Result.UpdateBoolean(8, False);\n        Result.UpdateBoolean(9, False);\n        Result.UpdateBoolean(11, False);\n        Result.UpdateBoolean(12, False);\n        Result.UpdateInt(18, 10);\n        Result.InsertRow;\n      end;\n      Close;\n    end;\nend;\n\n{**\n  Gets a description of a table's indices and statistics. They are\n  ordered by NON_UNIQUE, TYPE, INDEX_NAME, and ORDINAL_POSITION.\n\n  <P>Each index column description has the following columns:\n   <OL>\n \t<LI><B>TABLE_CAT</B> String => table catalog (may be null)\n \t<LI><B>TABLE_SCHEM</B> String => table schema (may be null)\n \t<LI><B>TABLE_NAME</B> String => table name\n \t<LI><B>NON_UNIQUE</B> Boolean => Can index values be non-unique?\n       false when TYPE is tableIndexStatistic\n \t<LI><B>INDEX_QUALIFIER</B> String => index catalog (may be null);\n       null when TYPE is tableIndexStatistic\n \t<LI><B>INDEX_NAME</B> String => index name; null when TYPE is\n       tableIndexStatistic\n \t<LI><B>TYPE</B> short => index type:\n       <UL>\n       <LI> tableIndexStatistic - this identifies table statistics that are\n            returned in conjuction with a table's index descriptions\n       <LI> tableIndexClustered - this is a clustered index\n       <LI> tableIndexHashed - this is a hashed index\n       <LI> tableIndexOther - this is some other style of index\n       </UL>\n \t<LI><B>ORDINAL_POSITION</B> short => column sequence number\n       within index; zero when TYPE is tableIndexStatistic\n \t<LI><B>COLUMN_NAME</B> String => column name; null when TYPE is\n       tableIndexStatistic\n \t<LI><B>ASC_OR_DESC</B> String => column sort sequence, \"A\" => ascending,\n       \"D\" => descending, may be null if sort sequence is not supported;\n       null when TYPE is tableIndexStatistic\n \t<LI><B>CARDINALITY</B> int => When TYPE is tableIndexStatistic, then\n       this is the number of rows in the table; otherwise, it is the\n       number of unique values in the index.\n \t<LI><B>PAGES</B> int => When TYPE is  tableIndexStatisic then\n       this is the number of pages used for the table, otherwise it\n       is the number of pages used for the current index.\n \t<LI><B>FILTER_CONDITION</B> String => Filter condition, if any.\n       (may be null)\n   </OL>\n\n  @param catalog a catalog name; \"\" retrieves those without a\n  catalog; null means drop catalog name from the selection criteria\n  @param schema a schema name; \"\" retrieves those without a schema\n  @param table a table name\n  @param unique when true, return only indices for unique values;\n      when false, return indices regardless of whether unique or not\n  @param approximate when true, result is allowed to reflect approximate\n      or out of data values; when false, results are requested to be\n      accurate\n  @return <code>ResultSet</code> - each row is an index column description\n}\nfunction TZPostgreSQLDatabaseMetadata.UncachedGetIndexInfo(const Catalog: string;\n  const Schema: string; const Table: string; Unique: Boolean;\n  Approximate: Boolean): IZResultSet;\nvar\n  SQL, Select, From, Where: string;\nbegin\n    if (GetDatabaseInfo as IZPostgreDBInfo).HasMinimumServerVersion(7, 3) then\n    begin\n      Select := 'SELECT NULL AS TABLE_CAT, n.nspname AS TABLE_SCHEM,';\n      From := ' FROM pg_catalog.pg_namespace n, pg_catalog.pg_class ct,'\n        + ' pg_catalog.pg_class ci, pg_catalog.pg_index i,'\n        + ' pg_catalog.pg_attribute a, pg_catalog.pg_am am';\n      Where := ' AND n.oid = ct.relnamespace';\n      if Schema <> '' then\n        Where := Where + ' AND n.nspname = ' + EscapeString(Schema);\n    end\n    else\n    begin\n      Select := 'SELECT NULL AS TABLE_CAT, NULL AS TABLE_SCHEM,';\n      From := ' FROM pg_class ct, pg_class ci, pg_index i, pg_attribute a,'\n        + ' pg_am am';\n    end;\n\n    SQL := Select + ' ct.relname AS TABLE_NAME, NOT i.indisunique'\n      + ' AS NON_UNIQUE, NULL AS INDEX_QUALIFIER, ci.relname AS INDEX_NAME,'\n      + ' CASE i.indisclustered WHEN true THEN ' + IntToStr(Ord(tiClustered))\n      + ' ELSE CASE am.amname WHEN ''hash'' THEN ' + IntToStr(Ord(tiHashed))\n      + ' ELSE ' + IntToStr(Ord(tiOther)) + ' END END AS TYPE,'\n      + ' a.attnum AS ORDINAL_POSITION, a.attname AS COLUMN_NAME,'\n      + ' NULL AS ASC_OR_DESC, ci.reltuples AS CARDINALITY,'\n      + ' ci.relpages AS PAGES, NULL AS FILTER_CONDITION'\n      + From\n      + ' WHERE ct.oid=i.indrelid AND ci.oid=i.indexrelid'\n      + ' AND a.attrelid=ci.oid AND ci.relam=am.oid' + Where\n      + ' AND ct.relname = ' + EscapeString(Table);\n\n    if Unique then\n      SQL := SQL + ' AND i.indisunique';\n    SQL := SQL + ' ORDER BY NON_UNIQUE, TYPE, INDEX_NAME, ORDINAL_POSITION';\n\n    Result := CopyToVirtualResultSet(\n      GetConnection.CreateStatement.ExecuteQuery(SQL),\n      ConstructVirtualResultSet(IndexInfoColumnsDynArray));\nend;\n\nfunction TZPostgreSQLDatabaseMetadata.UncachedGetSequences(const Catalog, SchemaPattern,\n  SequenceNamePattern: string): IZResultSet;\nvar\n  SQL: string;\nbegin\n    Result:=inherited UncachedGetSequences(Catalog, SchemaPattern, SequenceNamePattern);\n\n    SQL := ' SELECT nspname, relname ' +\n      'FROM pg_catalog.pg_namespace n, pg_catalog.pg_class ct ' +\n      'WHERE relkind = ''S'' ' +\n      'AND n.oid = ct.relnamespace';\n\n    if SequenceNamePattern <> '' then\n      SQL := SQL + ' AND ' + Format('relname = ''%s''', [SequenceNamePattern]);\n    if SchemaPattern <> '' then\n      SQL := SQL + ' AND ' + Format('nspname = ''%s''', [SchemaPattern]);\n\n    with GetConnection.CreateStatement.ExecuteQuery(SQL) do\n    begin\n      while Next do\n      begin\n        Result.MoveToInsertRow;\n        Result.UpdateNull(1);\n        Result.UpdateString(2, GetStringByName('nspname'));\n        Result.UpdateString(3, GetStringByName('relname'));\n        Result.InsertRow;\n      end;\n      Close;\n    end;\nend;\n\nfunction TZPostgreSQLDatabaseMetadata.GetPostgreSQLType(Oid: Integer): string;\nbegin\n  Result := (GetConnection as IZPostgreSQLConnection).GetTypeNameByOid(Oid);\nend;\n\nfunction TZPostgreSQLDatabaseMetadata.GetSQLTypeByOid(Oid: Integer): TZSQLType;\nvar\n  PostgreSQLConnection: IZPostgreSQLConnection;\nbegin\n  PostgreSQLConnection := GetConnection as IZPostgreSQLConnection;\n  Result := PostgreSQLToSQLType(PostgreSQLConnection,\n    PostgreSQLConnection.GetTypeNameByOid(Oid));\nend;\n\nfunction TZPostgreSQLDatabaseMetadata.GetSQLTypeByName(\n  TypeName: string): TZSQLType;\nbegin\n  Result := PostgreSQLToSQLType(\n    GetConnection as IZPostgreSQLConnection, TypeName);\nend;\n\nfunction TZPostgreSQLDatabaseMetadata.TableTypeSQLExpression(\n  TableType: string; UseSchemas: Boolean): string;\nbegin\n  if UseSchemas then\n  begin\n    if TableType = 'TABLE' then\n      Result := ' c.relkind = ''r'' AND n.nspname NOT LIKE ''pg\\\\_%'' '\n    else if TableType = 'VIEW' then\n      Result := ' c.relkind = ''v'' AND n.nspname <> ''pg_catalog'' '\n    else if TableType = 'INDEX' then\n      Result := ' c.relkind = ''i'' AND n.nspname NOT LIKE ''pg\\\\_%'' '\n    else if TableType = 'SEQUENCE' then\n      Result := ' c.relkind = ''S'' '\n    else if TableType = 'SYSTEM TABLE' then\n      Result := ' c.relkind = ''r'' AND n.nspname = ''pg_catalog'' '\n    else if TableType = 'SYSTEM TOAST TABLE' then\n      Result := ' c.relkind = ''r'' AND n.nspname = ''pg_toast'' '\n    else if TableType = 'SYSTEM TOAST INDEX' then\n      Result := ' c.relkind = ''i'' AND n.nspname = ''pg_toast'' '\n    else if TableType = 'SYSTEM VIEW' then\n      Result := ' c.relkind = ''v'' AND n.nspname = ''pg_catalog'' '\n    else if TableType = 'SYSTEM INDEX' then\n      Result := ' c.relkind = ''i'' AND n.nspname = ''pg_catalog'' '\n    else if TableType = 'TEMPORARY TABLE' then\n      Result := ' c.relkind = ''r'' AND n.nspname LIKE ''pg\\\\_temp\\\\_%'' '\n    else if TableType = 'TEMPORARY INDEX' then\n      Result := 'c.relkind = ''i'' AND n.nspname LIKE ''pg\\\\_temp\\\\_%'' ';\n  end\n  else\n  begin\n    if TableType = 'TABLE' then\n      Result := ' c.relkind = ''r'' AND c.relname NOT LIKE ''pg\\\\_%'' '\n    else if TableType = 'VIEW' then\n      Result := ' c.relkind = ''v'' AND c.relname NOT LIKE ''pg\\\\_%'' '\n    else if TableType = 'INDEX' then\n      Result := ' c.relkind = ''i'' AND c.relname NOT LIKE ''pg\\\\_%'' '\n    else if TableType = 'SEQUENCE' then\n      Result := ' c.relkind = ''S'' '\n    else if TableType = 'SYSTEM TABLE' then\n      Result := ' c.relkind = ''r'' AND c.relname LIKE ''pg\\\\_%'' AND c.relname '+\n        'NOT LIKE ''pg\\\\_toast\\\\_%'' AND c.relname NOT LIKE ''pg\\\\_temp\\\\_%'' '\n    else if TableType = 'SYSTEM TOAST TABLE' then\n      Result := ' c.relkind = ''r'' AND c.relname LIKE ''pg\\\\_toast\\\\_%'' '\n    else if TableType = 'SYSTEM TOAST INDEX' then\n      Result := ' c.relkind = ''i'' AND c.relname LIKE ''pg\\\\_toast\\\\_%'' '\n    else if TableType = 'SYSTEM VIEW' then\n      Result := 'c.relkind = ''v'' AND c.relname LIKE ''pg\\\\_%'''\n    else if TableType = 'SYSTEM INDEX' then\n    begin\n      Result := ' c.relkind = ''v'' AND c.relname LIKE ''pg\\\\_%'' AND '+\n        'c.relname NOT LIKE ''pg\\\\_toast\\\\_%'' AND c.relname '+\n        'NOT LIKE ''pg\\\\_temp\\\\_%'' '\n    end\n    else if TableType = 'TEMPORARY TABLE' then\n      Result := ' c.relkind = ''r'' AND c.relname LIKE ''pg\\\\_temp\\\\_%'' '\n    else if TableType = 'TEMPORARY INDEX' then\n      Result := ' c.relkind = ''i'' AND c.relname LIKE ''pg\\\\_temp\\\\_%'' '\n  end;\nend;\n\nprocedure TZPostgreSQLDatabaseMetadata.ParseACLArray(\n  List: TStrings; AclString: string);\nvar\n  PrevChar: Char;\n  InQuotes: Boolean;\n  I, BeginIndex: Integer;\nbegin\n  if AclString = '' then Exit;\n  InQuotes := False;\n  PrevChar := ' ';\n  BeginIndex := 2;\n  for I := BeginIndex to Length(AclString) do\n  begin\n    if (AclString[I] = '\"') and (PrevChar <> '\\' ) then\n      InQuotes := not InQuotes\n    else if (AclString[I] = ',') and not InQuotes then\n    begin\n      List.Add(Copy(AclString, BeginIndex, I - BeginIndex));\n      BeginIndex := I+1;\n    end;\n    PrevChar := AclString[I];\n  end;\n\n  // add last element removing the trailing \"}\"\n  List.Add(Copy(AclString, BeginIndex, Length(AclString) - BeginIndex));\n\n  // Strip out enclosing quotes, if any.\n  for I := 0 to List.Count-1 do\n  begin\n    if (List.Strings[i][1] = '\"')\n      and (List.Strings[i][Length(List.Strings[i])] = '\"') then\n      List.Strings[i] := Copy(List.Strings[i], 2, Length(List.Strings[i])-2);\n  end;\nend;\n\nfunction TZPostgreSQLDatabaseMetadata.GetPrivilegeName(Permission: Char): string;\nbegin\n case Permission of\n   'a': Result := 'INSERT';\n   'r': Result := 'SELECT';\n   'w': Result := 'UPDATE';\n   'd': Result := 'DELETE';\n   'R': Result := 'RULE';\n   'x': Result := 'REFERENCES';\n   't': Result := 'TRIGGER';\n   'X': Result := 'EXECUTE';\n   'U': Result := 'USAGE';\n   'C': Result := 'CREATE';\n   'T': Result := 'CREATE TEMP';\n   else Result := 'UNKNOWN';\n end;\nend;\n\nfunction TZPostgreSQLDatabaseMetadata.GetIdentifierConvertor: IZIdentifierConvertor;\nbegin\n  Result:=TZPostgreSQLIdentifierConvertor.Create(Self);\nend;\n\n{**\n  Gets the all supported CharacterSets:\n  @return <code>ResultSet</code> - each row is a CharacterSetName and it's ID\n}\nfunction TZPostgreSQLDatabaseMetadata.UncachedGetCharacterSets: IZResultSet; //EgonHugeist\nbegin\n  Self.GetConnection.CreateStatement.Execute(\n  ' CREATE OR REPLACE FUNCTION get_encodings() RETURNS INTEGER AS '''+\n  ' DECLARE '+\n  '   enc     INTEGER := 0; '+\n  '   name    VARCHAR; '+\n  ' BEGIN '+\n  '   CREATE TEMP TABLE encodings ( enc_code int, enc_name text ); '+\n  '   LOOP '+\n  '       SELECT INTO name pg_encoding_to_char( enc ); '+\n  '       IF( name = '''''''' ) THEN '+\n  '           EXIT; '+\n  '       ELSE '+\n  '           INSERT INTO encodings VALUES( enc, name ); '+\n  '        END IF; '+\n  '       enc := enc + 1; '+\n  '   END LOOP; '+\n  '   RETURN enc; '+\n  ' END; '+\n  ''' LANGUAGE ''plpgsql'';');\n  Self.GetConnection.CreateStatement.ExecuteQuery('select get_encodings();').Close;\n\n  Result:=inherited UncachedGetCharacterSets;\n\n  with Self.GetConnection.CreateStatement.ExecuteQuery(\n   'select * from encodings;') do\n  begin\n    while Next do\n    begin\n      Result.MoveToInsertRow;\n      Result.UpdateString(1, GetString(2)); //CHARACTER_SET_NAME\n      Result.UpdateShort(2, GetShort(1)); //CHARACTER_SET_ID\n      Result.InsertRow;\n    end;\n    CLose;\n  end;\nend;\n\n{ TZPostgresIdentifierConvertor }\n\nfunction TZPostgreSQLIdentifierConvertor.ExtractQuote(\n  const Value: string): string;\nvar\n  QuoteDelim: string;\nbegin\n  QuoteDelim := Metadata.GetDatabaseInfo.GetIdentifierQuoteString;\n  Result := Value;\n  if (QuoteDelim <> '') and (Value <> '') then\n    if (Value[1]=QuoteDelim[1]) and\n      (Value[PLongInt(NativeUInt(Value) - 4)^{fast Length()}]=QuoteDelim[1]) then\n    begin\n      Result:=copy(Value,2,length(Value)-2);\n      Result:=StringReplace(Result,QuoteDelim+QuoteDelim,QuoteDelim,[rfReplaceAll]);\n    end\n    else\n      Result := AnsiLowerCase(Value);\n\nend;\n\nfunction TZPostgreSQLIdentifierConvertor.IsQuoted(const Value: string): Boolean;\nvar\n  QuoteDelim: string;\nbegin\n  QuoteDelim := Metadata.GetDatabaseInfo.GetIdentifierQuoteString;\n  Result := (QuoteDelim <> '') and (Value <> '') and\n            (Value[1]=QuoteDelim[1]) and\n            (Value[PLongInt(NativeUInt(Value) - 4)^{fast Length()}]=QuoteDelim[1]);\nend;\n\nfunction TZPostgreSQLIdentifierConvertor.IsSpecialCase(\n  const Value: string): Boolean;\nvar\n  I: Integer;\nbegin\n  Result := False;\n  if not CharInSet(Value[1], ['a'..'z','_']) then\n  begin\n    Result := True;\n    Exit;\n  end;\n  for I := 1 to Length(Value) do\n  begin\n    if not CharInSet(Value[I], ['A'..'Z','a'..'z','0'..'9','_']) then\n    begin\n      Result := True;\n      Break;\n    end;\n  end;\nend;\n\nfunction TZPostgreSQLIdentifierConvertor.Quote(const Value: string): string;\nvar\n  QuoteDelim: string;\nbegin\n  Result := Value;\n  if IsCaseSensitive(Value) then\n  begin\n    QuoteDelim := Metadata.GetDatabaseInfo.GetIdentifierQuoteString;\n    Result := QuoteDelim +\n              StringReplace(Result,QuoteDelim,QuoteDelim+QuoteDelim,[rfReplaceAll]) +\n              QuoteDelim;\n  end;\nend;\n\nend.\n"
  },
  {
    "path": "lib/zeosdbo/src/dbc/ZDbcPostgreSqlResultSet.pas",
    "content": "{*********************************************************}\n{                                                         }\n{                 Zeos Database Objects                   }\n{         PostgreSQL Database Connectivity Classes        }\n{                                                         }\n{        Originally written by Sergey Seroukhov           }\n{                                                         }\n{*********************************************************}\n\n{@********************************************************}\n{    Copyright (c) 1999-2012 Zeos Development Group       }\n{                                                         }\n{ License Agreement:                                      }\n{                                                         }\n{ This library is distributed in the hope that it will be }\n{ useful, but WITHOUT ANY WARRANTY; without even the      }\n{ implied warranty of MERCHANTABILITY or FITNESS FOR      }\n{ A PARTICULAR PURPOSE.  See the GNU Lesser General       }\n{ Public License for more details.                        }\n{                                                         }\n{ The source code of the ZEOS Libraries and packages are  }\n{ distributed under the Library GNU General Public        }\n{ License (see the file COPYING / COPYING.ZEOS)           }\n{ with the following  modification:                       }\n{ As a special exception, the copyright holders of this   }\n{ library give you permission to link this library with   }\n{ independent modules to produce an executable,           }\n{ regardless of the license terms of these independent    }\n{ modules, and to copy and distribute the resulting       }\n{ executable under terms of your choice, provided that    }\n{ you also meet, for each linked independent module,      }\n{ the terms and conditions of the license of that module. }\n{ An independent module is a module which is not derived  }\n{ from or based on this library. If you modify this       }\n{ library, you may extend this exception to your version  }\n{ of the library, but you are not obligated to do so.     }\n{ If you do not wish to do so, delete this exception      }\n{ statement from your version.                            }\n{                                                         }\n{                                                         }\n{ The project web site is located on:                     }\n{   http://zeos.firmos.at  (FORUM)                        }\n{   http://sourceforge.net/p/zeoslib/tickets/ (BUGTRACKER)}\n{   svn://svn.code.sf.net/p/zeoslib/code-0/trunk (SVN)    }\n{                                                         }\n{   http://www.sourceforge.net/projects/zeoslib.          }\n{                                                         }\n{                                                         }\n{                                 Zeos Development Group. }\n{********************************************************@}\n\nunit ZDbcPostgreSqlResultSet;\n\ninterface\n\n{$I ZDbc.inc}\n\nuses\n  {$IFDEF WITH_TOBJECTLIST_INLINE}System.Types, System.Contnrs{$ELSE}Types{$ENDIF},\n  Classes, {$IFDEF MSEgui}mclasses,{$ENDIF} SysUtils,\n  ZSysUtils, ZDbcIntfs, ZDbcResultSet, ZPlainPostgreSqlDriver, ZDbcLogging,\n  ZDbcResultSetMetadata, ZCompatibility;\n\ntype\n  {** Implements PostgreSQL ResultSet. }\n  TZPostgreSQLResultSet = class(TZAbstractResultSet)\n  private\n    FHandle: PZPostgreSQLConnect;\n    FQueryHandle: PZPostgreSQLResult;\n    FPlainDriver: IZPostgreSQLPlainDriver;\n    FChunk_Size: Integer;\n    FUndefinedVarcharAsStringLength: Integer;\n  protected\n    function InternalGetString(ColumnIndex: Integer): RawByteString; override;\n    procedure Open; override;\n    procedure DefinePostgreSQLToSQLType(ColumnInfo: TZColumnInfo; const TypeOid: Oid);\n  public\n    constructor Create(PlainDriver: IZPostgreSQLPlainDriver;\n      Statement: IZStatement; SQL: string; Handle: PZPostgreSQLConnect;\n      QueryHandle: PZPostgreSQLResult; Chunk_Size: Integer);\n\n    procedure Close; override;\n\n    function IsNull(ColumnIndex: Integer): Boolean; override;\n    function GetUnicodeStream(ColumnIndex: Integer): TStream; override;\n    function GetBoolean(ColumnIndex: Integer): Boolean; override;\n    function GetByte(ColumnIndex: Integer): Byte; override;\n    function GetShort(ColumnIndex: Integer): SmallInt; override;\n    function GetInt(ColumnIndex: Integer): Integer; override;\n    function GetLong(ColumnIndex: Integer): Int64; override;\n    function GetFloat(ColumnIndex: Integer): Single; override;\n    function GetDouble(ColumnIndex: Integer): Double; override;\n    function GetBigDecimal(ColumnIndex: Integer): Extended; override;\n    function GetBytes(ColumnIndex: Integer): TByteDynArray; override;\n    function GetDate(ColumnIndex: Integer): TDateTime; override;\n    function GetTime(ColumnIndex: Integer): TDateTime; override;\n    function GetTimestamp(ColumnIndex: Integer): TDateTime; override;\n    function GetBlob(ColumnIndex: Integer): IZBlob; override;\n\n    function MoveAbsolute(Row: Integer): Boolean; override;\n  end;\n\n  {** Represents an interface, specific for PostgreSQL blobs. }\n  IZPostgreSQLBlob = interface(IZBlob)\n    ['{BDFB6B80-477D-4CB1-9508-9541FEA6CD72}']\n    function GetBlobOid: Oid;\n    procedure ReadBlob;\n    procedure WriteBlob;\n  end;\n\n  {** Implements external blob wrapper object for PostgreSQL. }\n  TZPostgreSQLBlob = class(TZAbstractBlob, IZPostgreSQLBlob)\n  private\n    FHandle: PZPostgreSQLConnect;\n    FBlobOid: Oid;\n    FPlainDriver: IZPostgreSQLPlainDriver;\n    FChunk_Size: Integer;\n  public\n    constructor Create(PlainDriver: IZPostgreSQLPlainDriver; Data: Pointer;\n      Size: Integer; Handle: PZPostgreSQLConnect; BlobOid: Oid; Chunk_Size: Integer);\n\n    destructor Destroy; override;\n\n    function GetBlobOid: Oid;\n    procedure ReadBlob;\n    procedure WriteBlob;\n\n    function IsEmpty: Boolean; override;\n    function Clone: IZBlob; override;\n\n    function GetStream: TStream; override;\n  end;\n\nimplementation\n\nuses\n  Math, ZMessages, ZMatchPattern, ZDbcPostgreSql, ZDbcUtils, ZEncoding,\n  ZDbcPostgreSqlUtils{$IFDEF WITH_UNITANSISTRINGS}, AnsiStrings{$ENDIF};\n\n{ TZPostgreSQLResultSet }\n\n{**\n  Constructs this object, assignes main properties and\n  opens the record set.\n  @param PlainDriver a PostgreSQL plain driver.\n  @param Statement a related SQL statement object.\n  @param SQL a SQL statement.\n  @param Handle a PostgreSQL specific query handle.\n}\nconstructor TZPostgreSQLResultSet.Create(PlainDriver: IZPostgreSQLPlainDriver;\n  Statement: IZStatement; SQL: string; Handle: PZPostgreSQLConnect;\n  QueryHandle: PZPostgreSQLResult; Chunk_Size: Integer);\nbegin\n  inherited Create(Statement, SQL, nil, Statement.GetConnection.GetConSettings);\n\n  FHandle := Handle;\n  FQueryHandle := QueryHandle;\n  FPlainDriver := PlainDriver;\n  ResultSetConcurrency := rcReadOnly;\n  FChunk_Size := Chunk_Size; //size of red/write lob chunks\n  FUndefinedVarcharAsStringLength := (Statement.GetConnection as IZPostgreSQLConnection).GetUndefinedVarcharAsStringLength;\n\n  Open;\nend;\n\n{**\n  Converts a PostgreSQL native types into ZDBC SQL types.\n  @param ColumnIndex a column index.\n  @param ColumnInfo a column description object.\n  @param TypeOid a type oid.\n  @return a SQL undepended type.\n}\nprocedure TZPostgreSQLResultSet.DefinePostgreSQLToSQLType(\n  ColumnInfo: TZColumnInfo; const TypeOid: Oid);\nvar\n  SQLType: TZSQLType;\n  Connection: IZPostgreSQLConnection;\nbegin\n  Connection := Statement.GetConnection as IZPostgreSQLConnection;\n\n  case TypeOid of\n    790: ColumnInfo.Currency := True; { money }\n    19: if (Connection.GetServerMajorVersion < 7) or\n           ((Connection.GetServerMajorVersion = 7) and (Connection.GetServerMinorVersion < 3)) then\n          ColumnInfo.Precision := 32\n        else\n          ColumnInfo.Precision := 64; { name }\n    650: ColumnInfo.Precision := 100; { cidr }\n    869: ColumnInfo.Precision := 100; { inet }\n    829: ColumnInfo.Precision := 17; { macaddr }\n    1186: ColumnInfo.Precision := 32; { interval }\n    24: ColumnInfo.Precision := 64; { regproc } // M.A. was 10\n    17:{ bytea }\n      if Connection.IsOidAsBlob then\n        ColumnInfo.Precision := 256;\n  end;\n\n  SQLType := PostgreSQLToSQLType(ConSettings, Connection.IsOidAsBlob, TypeOid);\n\n  if SQLType <> stUnknown then\n    ColumnInfo.ColumnType := SQLType\n  else\n  begin\n    ColumnInfo.ColumnType := stString;\n    ColumnInfo.Precision := 255;\n    ColumnInfo.ReadOnly := True;\n  end;\nend;\n\n{**\n  Opens this recordset.\n}\nprocedure TZPostgreSQLResultSet.Open;\nvar\n  I, FieldCount: Integer;\n  ColumnInfo: TZColumnInfo;\n  FieldMode, FieldSize, FieldType: Integer;\n  TableInfo: PZPGTableInfo;\n  Connection: IZPostgreSQLConnection;\nbegin\n  if ResultSetConcurrency = rcUpdatable then\n    raise EZSQLException.Create(SLiveResultSetsAreNotSupported);\n\n  if not Assigned(FQueryHandle) then\n    raise EZSQLException.Create(SCanNotRetrieveResultSetData);\n\n  Connection := Statement.GetConnection as IZPostgreSQLConnection;\n\n  LastRowNo := FPlainDriver.GetRowCount(FQueryHandle);\n\n  { Fills the column info. }\n  ColumnsInfo.Clear;\n  FieldCount := FPlainDriver.GetFieldCount(FQueryHandle);\n  for I := 0 to FieldCount - 1 do\n  begin\n    ColumnInfo := TZColumnInfo.Create;\n    with ColumnInfo do\n    begin\n      if Statement.GetResultSetConcurrency = rcUpdatable then //exclude system-tables and if no updates happen -> useless\n        TableInfo := Connection.GetTableInfo(FPlainDriver.GetFieldTableOID(FQueryHandle, I),FieldCount)\n      else\n        TableInfo := nil;\n      if TableInfo = nil then\n      begin\n        SchemaName := '';\n        ColumnName := '';\n        TableName := '';\n      end\n      else\n      begin\n        SchemaName := TableInfo^.Schema;\n        TableName := TableInfo^.Name;\n        ColumnName := TableInfo^.ColNames[FplainDriver.GetFieldTableColIdx(FQueryHandle, I) - 1];\n      end;\n      ColumnLabel := ZDbcString(FPlainDriver.GetFieldName(FQueryHandle, I));\n      ColumnDisplaySize := 0;\n      Scale := 0;\n      Precision := 0;\n\n      AutoIncrement := False;\n      Signed := False;\n      Nullable := ntNullable;\n\n      FieldType := FPlainDriver.GetFieldType(FQueryHandle, I);\n      DefinePostgreSQLToSQLType(ColumnInfo, FieldType);\n\n      if Precision = 0 then\n      begin\n        FieldMode := FPlainDriver.GetFieldMode(FQueryHandle, I);\n        FieldSize := FPlainDriver.GetFieldSize(FQueryHandle, I);\n        Precision := Max(Max(FieldMode - 4, FieldSize), 0);\n\n        if ColumnType in [stString, stUnicodeString] then\n          {begin patch: varchar() is equal to text!}\n          if ( FieldMode = -1 ) and ( FieldSize = -1 ) and ( FieldType = 1043) then\n            if FUndefinedVarcharAsStringLength > 0 then\n              Precision := GetFieldSize(ColumnType, ConSettings,\n                FUndefinedVarcharAsStringLength,\n                ConSettings.ClientCodePage^.CharWidth, nil, False)\n            else\n              DefinePostgreSQLToSQLType(ColumnInfo, 25) //assume text instead!\n          else\n            if ( (ColumnLabel = 'expr') or ( Precision = 0 ) ) then\n              Precision := GetFieldSize(ColumnType, ConSettings, 255,\n                ConSettings.ClientCodePage^.CharWidth, nil, True)\n            else\n              Precision := GetFieldSize(ColumnType, ConSettings, Precision,\n                ConSettings.ClientCodePage^.CharWidth, @ColumnDisplaySize);\n      end;\n    end;\n\n    ColumnsInfo.Add(ColumnInfo);\n  end;\n\n  inherited Open;\nend;\n\n{**\n  Releases this <code>ResultSet</code> object's database and\n  JDBC resources immediately instead of waiting for\n  this to happen when it is automatically closed.\n\n  <P><B>Note:</B> A <code>ResultSet</code> object\n  is automatically closed by the\n  <code>Statement</code> object that generated it when\n  that <code>Statement</code> object is closed,\n  re-executed, or is used to retrieve the next result from a\n  sequence of multiple results. A <code>ResultSet</code> object\n  is also automatically closed when it is garbage collected.\n}\nprocedure TZPostgreSQLResultSet.Close;\nbegin\n  if FQueryHandle <> nil then\n    FPlainDriver.Clear(FQueryHandle);\n  FHandle := nil;\n  FQueryHandle := nil;\n  inherited Close;\nend;\n\n{**\n  Indicates if the value of the designated column in the current row\n  of this <code>ResultSet</code> object is Null.\n\n  @param columnIndex the first column is 1, the second is 2, ...\n  @return if the value is SQL <code>NULL</code>, the\n    value returned is <code>true</code>. <code>false</code> otherwise.\n}\nfunction TZPostgreSQLResultSet.IsNull(ColumnIndex: Integer): Boolean;\nbegin\n{$IFNDEF DISABLE_CHECKING}\n  CheckClosed;\n  if (RowNo < 1) or (RowNo > LastRowNo) then\n    raise EZSQLException.Create(SRowDataIsNotAvailable);\n{$ENDIF}\n\n  Result := FPlainDriver.GetIsNull(FQueryHandle, RowNo - 1,\n    ColumnIndex - 1) <> 0;\nend;\n\n{**\n  Gets the value of the designated column in the current row\n  of this <code>ResultSet</code> object as\n  a <code>String</code> in the Java programming language.\n\n  @param columnIndex the first column is 1, the second is 2, ...\n  @return the column value; if the value is SQL <code>NULL</code>, the\n    value returned is <code>null</code>\n}\nfunction TZPostgreSQLResultSet.InternalGetString(ColumnIndex: Integer): RawByteString;\n{$IFDEF WITH_RAWBYTESTRING}\nvar Len: Integer;\n{$ENDIF}\nbegin\n  ColumnIndex := ColumnIndex - 1;\n  LastWasNull := FPlainDriver.GetIsNull(FQueryHandle, RowNo - 1,\n    ColumnIndex) <> 0;\n  {$IFDEF WITH_RAWBYTESTRING}\n  Len := FPlainDriver.GetLength(FQueryHandle, RowNo - 1, ColumnIndex);\n  SetLength(Result, Len);\n  Move(FPlainDriver.GetValue(FQueryHandle, RowNo - 1, ColumnIndex)^, PAnsiChar(Result)^, Len);\n  {$ELSE}\n  SetString(Result, FPlainDriver.GetValue(FQueryHandle, RowNo - 1, ColumnIndex),\n    FPlainDriver.GetLength(FQueryHandle, RowNo - 1, ColumnIndex));\n  {$ENDIF}\n  if FPlainDriver.GetFieldType(FQueryHandle, ColumnIndex) = 1042 then\n    Result := {$IFDEF WITH_UNITANSISTRINGS}AnsiStrings.{$ENDIF}TrimRight(Result);\nend;\n\n{**\n  Gets the value of the designated column in the current row\n  of this <code>ResultSet</code> object as\n  a <code>boolean</code> in the Java programming language.\n\n  @param columnIndex the first column is 1, the second is 2, ...\n  @return the column value; if the value is SQL <code>NULL</code>, the\n    value returned is <code>false</code>\n}\nfunction TZPostgreSQLResultSet.GetBoolean(ColumnIndex: Integer): Boolean;\nvar\n  Temp: string;\nbegin\n{$IFNDEF DISABLE_CHECKING}\n  CheckColumnConvertion(ColumnIndex, stBoolean);\n{$ENDIF}\n  Temp := UpperCase(String(InternalGetString(ColumnIndex)));\n  Result := (Temp = 'Y') or (Temp = 'YES') or (Temp = 'T') or\n    (Temp = 'TRUE') or (StrToIntDef(String(Temp), 0) <> 0);\nend;\n\n{**\n  Gets the value of the designated column in the current row\n  of this <code>ResultSet</code> object as\n  a <code>byte</code> in the Java programming language.\n\n  @param columnIndex the first column is 1, the second is 2, ...\n  @return the column value; if the value is SQL <code>NULL</code>, the\n    value returned is <code>0</code>\n}\nfunction TZPostgreSQLResultSet.GetByte(ColumnIndex: Integer): Byte;\nbegin\n{$IFNDEF DISABLE_CHECKING}\n  CheckColumnConvertion(ColumnIndex, stByte);\n{$ENDIF}\n  Result := Byte(StrToIntDef(String(InternalGetString(ColumnIndex)), 0));\nend;\n\n{**\n  Gets the value of the designated column in the current row\n  of this <code>ResultSet</code> object as\n  a <code>short</code> in the Java programming language.\n\n  @param columnIndex the first column is 1, the second is 2, ...\n  @return the column value; if the value is SQL <code>NULL</code>, the\n    value returned is <code>0</code>\n}\nfunction TZPostgreSQLResultSet.GetShort(ColumnIndex: Integer): SmallInt;\nbegin\n{$IFNDEF DISABLE_CHECKING}\n  CheckColumnConvertion(ColumnIndex, stShort);\n{$ENDIF}\n  Result := SmallInt(StrToIntDef(String(InternalGetString(ColumnIndex)), 0));\nend;\n\n{**\n  Gets the value of the designated column in the current row\n  of this <code>ResultSet</code> object as\n  an <code>int</code> in the Java programming language.\n\n  @param columnIndex the first column is 1, the second is 2, ...\n  @return the column value; if the value is SQL <code>NULL</code>, the\n    value returned is <code>0</code>\n}\nfunction TZPostgreSQLResultSet.GetInt(ColumnIndex: Integer): Integer;\nbegin\n{$IFNDEF DISABLE_CHECKING}\n  CheckColumnConvertion(ColumnIndex, stInteger);\n{$ENDIF}\n  Result := StrToIntDef(String(InternalGetString(ColumnIndex)), 0);\nend;\n\n{**\n  Gets the value of the designated column in the current row\n  of this <code>ResultSet</code> object as\n  a <code>long</code> in the Java programming language.\n\n  @param columnIndex the first column is 1, the second is 2, ...\n  @return the column value; if the value is SQL <code>NULL</code>, the\n    value returned is <code>0</code>\n}\nfunction TZPostgreSQLResultSet.GetLong(ColumnIndex: Integer): Int64;\nbegin\n{$IFNDEF DISABLE_CHECKING}\n  CheckColumnConvertion(ColumnIndex, stLong);\n{$ENDIF}\n  Result := StrToInt64Def(String(InternalGetString(ColumnIndex)), 0);\nend;\n\n{**\n  Gets the value of the designated column in the current row\n  of this <code>ResultSet</code> object as\n  a <code>float</code> in the Java programming language.\n\n  @param columnIndex the first column is 1, the second is 2, ...\n  @return the column value; if the value is SQL <code>NULL</code>, the\n    value returned is <code>0</code>\n}\nfunction TZPostgreSQLResultSet.GetFloat(ColumnIndex: Integer): Single;\nbegin\n{$IFNDEF DISABLE_CHECKING}\n  CheckColumnConvertion(ColumnIndex, stFloat);\n{$ENDIF}\n  Result := SQLStrToFloatDef(InternalGetString(ColumnIndex), 0);\nend;\n\n{**\n  Gets the value of the designated column in the current row\n  of this <code>ResultSet</code> object as\n  a <code>double</code> in the Java programming language.\n\n  @param columnIndex the first column is 1, the second is 2, ...\n  @return the column value; if the value is SQL <code>NULL</code>, the\n    value returned is <code>0</code>\n}\nfunction TZPostgreSQLResultSet.GetDouble(ColumnIndex: Integer): Double;\nbegin\n{$IFNDEF DISABLE_CHECKING}\n  CheckColumnConvertion(ColumnIndex, stDouble);\n{$ENDIF}\n  Result := SQLStrToFloatDef(InternalGetString(ColumnIndex), 0);\nend;\n\n{**\n  Gets the value of the designated column in the current row\n  of this <code>ResultSet</code> object as\n  a <code>java.sql.BigDecimal</code> in the Java programming language.\n\n  @param columnIndex the first column is 1, the second is 2, ...\n  @param scale the number of digits to the right of the decimal point\n  @return the column value; if the value is SQL <code>NULL</code>, the\n    value returned is <code>null</code>\n}\nfunction TZPostgreSQLResultSet.GetBigDecimal(ColumnIndex: Integer): Extended;\nbegin\n{$IFNDEF DISABLE_CHECKING}\n  CheckColumnConvertion(ColumnIndex, stBigDecimal);\n{$ENDIF}\n  Result := SQLStrToFloatDef(InternalGetString(ColumnIndex), 0);\nend;\n\n{**\n  Gets the value of the designated column in the current row\n  of this <code>ResultSet</code> object as\n  a <code>byte</code> array in the Java programming language.\n  The bytes represent the raw values returned by the driver.\n\n  @param columnIndex the first column is 1, the second is 2, ...\n  @return the column value; if the value is SQL <code>NULL</code>, the\n    value returned is <code>null</code>\n}\nfunction TZPostgreSQLResultSet.GetBytes(ColumnIndex: Integer): TByteDynArray;\nbegin\n{$IFNDEF DISABLE_CHECKING}\n  CheckColumnConvertion(ColumnIndex, stBytes);\n{$ENDIF}\n  Result := StrToBytes(DecodeString(InternalGetString(ColumnIndex)));\nend;\n\n{**\n  Gets the value of the designated column in the current row\n  of this <code>ResultSet</code> object as\n  a <code>java.sql.Date</code> object in the Java programming language.\n\n  @param columnIndex the first column is 1, the second is 2, ...\n  @return the column value; if the value is SQL <code>NULL</code>, the\n    value returned is <code>null</code>\n}\nfunction TZPostgreSQLResultSet.GetDate(ColumnIndex: Integer): TDateTime;\nvar\n  Value: string;\nbegin\n{$IFNDEF DISABLE_CHECKING}\n  CheckColumnConvertion(ColumnIndex, stDate);\n{$ENDIF}\n  Value := String(InternalGetString(ColumnIndex));\n  if IsMatch('????-??-??*', Value) then\n    Result := Trunc(AnsiSQLDateToDateTime(Value))\n  else\n    Result := Trunc(TimestampStrToDateTime(Value));\nend;\n\n{**\n  Gets the value of the designated column in the current row\n  of this <code>ResultSet</code> object as\n  a <code>java.sql.Time</code> object in the Java programming language.\n\n  @param columnIndex the first column is 1, the second is 2, ...\n  @return the column value; if the value is SQL <code>NULL</code>, the\n    value returned is <code>null</code>\n}\nfunction TZPostgreSQLResultSet.GetTime(ColumnIndex: Integer): TDateTime;\nvar\n  Value: string;\nbegin\n{$IFNDEF DISABLE_CHECKING}\n  CheckColumnConvertion(ColumnIndex, stTime);\n{$ENDIF}\n  Value := String(InternalGetString(ColumnIndex));\n  if IsMatch('*??:??:??*', Value) then\n    Result := Frac(AnsiSQLDateToDateTime(Value))\n  else\n    Result := Frac(TimestampStrToDateTime(Value));\nend;\n\n{**\n  Gets the value of the designated column in the current row\n  of this <code>ResultSet</code> object as\n  a <code>java.sql.Timestamp</code> object in the Java programming language.\n\n  @param columnIndex the first column is 1, the second is 2, ...\n  @return the column value; if the value is SQL <code>NULL</code>, the\n  value returned is <code>null</code>\n  @exception SQLException if a database access error occurs\n}\nfunction TZPostgreSQLResultSet.GetTimestamp(ColumnIndex: Integer): TDateTime;\nvar\n  Value: string;\nbegin\n{$IFNDEF DISABLE_CHECKING}\n  CheckColumnConvertion(ColumnIndex, stTimestamp);\n{$ENDIF}\n  Value := String(InternalGetString(ColumnIndex));\n  if IsMatch('????-??-??*', Value) then\n    Result := AnsiSQLDateToDateTime(Value)\n  else\n    Result := TimestampStrToDateTime(Value);\nend;\n\nfunction TZPostgreSQLResultSet.GetUnicodeStream(ColumnIndex: Integer): TStream;\nbegin\n{$IFNDEF DISABLE_CHECKING}\n  CheckColumnConvertion(ColumnIndex, stUnicodeStream);\n{$ENDIF}\n  Result := TStringStream.Create(InternalGetString(ColumnIndex));\nend;\n\n{**\n  Returns the value of the designated column in the current row\n  of this <code>ResultSet</code> object as a <code>Blob</code> object\n  in the Java programming language.\n\n  @param ColumnIndex the first column is 1, the second is 2, ...\n  @return a <code>Blob</code> object representing the SQL <code>BLOB</code> value in\n    the specified column\n}\nfunction TZPostgreSQLResultSet.GetBlob(ColumnIndex: Integer): IZBlob;\nvar\n  BlobOid: Oid;\n  Stream: TStream;\n  Connection: IZConnection;\n  WS: ZWideString;\nbegin\n{$IFNDEF DISABLE_CHECKING}\n  CheckBlobColumn(ColumnIndex);\n  CheckClosed;\n  if (RowNo < 1) or (RowNo > LastRowNo) then\n    raise EZSQLException.Create(SRowDataIsNotAvailable);\n{$ENDIF}\n\n  Connection := Statement.GetConnection;\n  if (GetMetadata.GetColumnType(ColumnIndex) = stBinaryStream)\n    and (Connection as IZPostgreSQLConnection).IsOidAsBlob then\n  begin\n    if FPlainDriver.GetIsNull(FQueryHandle, RowNo - 1, ColumnIndex - 1) = 0 then\n      BlobOid := StrToIntDef(String(InternalGetString(ColumnIndex)), 0)\n    else\n      BlobOid := 0;\n\n    Result := TZPostgreSQLBlob.Create(FPlainDriver, nil, 0, FHandle, BlobOid, FChunk_Size);\n  end\n  else\n  begin\n    if FPlainDriver.GetIsNull(FQueryHandle, RowNo - 1, ColumnIndex - 1) = 0 then\n    begin\n      Stream := nil;\n      try\n        case GetMetadata.GetColumnType(ColumnIndex) of\n          stBinaryStream:\n            Stream := TStringStream.Create(FPlainDriver.DecodeBYTEA(InternalGetString(ColumnIndex),\n              (Connection as IZPostgreSQLConnection).Is_bytea_output_hex, Self.FHandle));\n          stAsciiStream:\n            Stream := TStringStream.Create(GetValidatedAnsiString(InternalGetString(ColumnIndex), ConSettings, True));\n          stUnicodeStream:\n            begin\n              WS := ZDbcUnicodeString(InternalGetString(ColumnIndex));\n              Stream := WideStringStream(Ws);\n            end;\n        end;\n        Result := TZAbstractBlob.CreateWithStream(Stream, GetStatement.GetConnection,\n          GetMetadata.GetColumnType(ColumnIndex) = stUnicodeStream);\n      finally\n        if Assigned(Stream) then\n          Stream.Free;\n      end;\n    end\n    else\n      Result := TZAbstractBlob.CreateWithStream(nil, GetStatement.GetConnection);\n  end;\nend;\n\n{**\n  Moves the cursor to the given row number in\n  this <code>ResultSet</code> object.\n\n  <p>If the row number is positive, the cursor moves to\n  the given row number with respect to the\n  beginning of the result set.  The first row is row 1, the second\n  is row 2, and so on.\n\n  <p>If the given row number is negative, the cursor moves to\n  an absolute row position with respect to\n  the end of the result set.  For example, calling the method\n  <code>absolute(-1)</code> positions the\n  cursor on the last row; calling the method <code>absolute(-2)</code>\n  moves the cursor to the next-to-last row, and so on.\n\n  <p>An attempt to position the cursor beyond the first/last row in\n  the result set leaves the cursor before the first row or after\n  the last row.\n\n  <p><B>Note:</B> Calling <code>absolute(1)</code> is the same\n  as calling <code>first()</code>. Calling <code>absolute(-1)</code>\n  is the same as calling <code>last()</code>.\n\n  @return <code>true</code> if the cursor is on the result set;\n    <code>false</code> otherwise\n}\nfunction TZPostgreSQLResultSet.MoveAbsolute(Row: Integer): Boolean;\nbegin\n{$IFNDEF DISABLE_CHECKING}\n  CheckClosed;\n{$ENDIF}\n\n  { Checks for maximum row. }\n  Result := False;\n  if (MaxRows > 0) and (Row > MaxRows) then\n    Exit;\n\n  { Processes negative rows. }\n  if Row < 0 then\n  begin\n    Row := LastRowNo - Row + 1;\n    if Row < 0 then\n       Row := 0;\n  end;\n\n  if (ResultSetType <> rtForwardOnly) or (Row >= RowNo) then\n  begin\n    if (Row >= 0) and (Row <= LastRowNo + 1) then\n    begin\n      RowNo := Row;\n      Result := (Row >= 1) and (Row <= LastRowNo);\n    end\n    else\n      Result := False;\n  end\n  else\n    RaiseForwardOnlyException;\nend;\n\n{ TZPostgreSQLBlob }\n\n{**\n  Constructs this class and assignes the main properties.\n  @param PlainDriver a PostgreSQL plain driver.\n  @param Data a pointer to the blobdata.\n  @param Size the size of the blobdata.\n  @param Handle a PostgreSQL connection reference.\n}\nconstructor TZPostgreSQLBlob.Create(PlainDriver: IZPostgreSQLPlainDriver;\n  Data: Pointer; Size: Integer; Handle: PZPostgreSQLConnect; BlobOid: Oid;\n  Chunk_Size: Integer);\nbegin\n  inherited CreateWithData(Data, Size, nil);\n  FHandle := Handle;\n  FBlobOid := BlobOid;\n  FPlainDriver := PlainDriver;\n  FChunk_Size := Chunk_Size;\nend;\n\n{**\n  Destroys this object and cleanups the memory.\n}\ndestructor TZPostgreSQLBlob.Destroy;\nbegin\n  inherited Destroy;\nend;\n\n{**\n  Gets the blob handle oid.\n  @return the blob handle oid.\n}\nfunction TZPostgreSQLBlob.GetBlobOid: Oid;\nbegin\n  Result := FBlobOid;\nend;\n\n{**\n  Reads the blob by the blob handle.\n}\nprocedure TZPostgreSQLBlob.ReadBlob;\nvar\n  BlobHandle: Integer;\n  Buffer: array[0..1024] of AnsiChar;\n  ReadNum: Integer;\n  ReadStream: TMemoryStream;\nbegin\n  if not Updated and (FBlobOid > 0) then\n  begin\n    BlobHandle := FPlainDriver.OpenLargeObject(FHandle, FBlobOid, INV_READ);\n    CheckPostgreSQLError(nil, FPlainDriver, FHandle, lcOther, 'Read Large Object',nil);\n    ReadStream := nil;\n    if BlobHandle >= 0 then\n    begin\n      ReadStream := TMemoryStream.Create;\n      repeat\n        ReadNum := FPlainDriver.ReadLargeObject(FHandle, BlobHandle,\n          Buffer, 1024);\n        if ReadNum > 0 then\n        begin\n          ReadStream.SetSize(ReadStream.Size + ReadNum);\n          ReadStream.Write(Buffer, ReadNum);\n        end;\n      until ReadNum < 1024;\n      FPlainDriver.CloseLargeObject(FHandle, BlobHandle);\n      ReadStream.Position := 0;\n    end;\n    SetStream(ReadStream);\n    if ReadStream <> nil then\n      ReadStream.free;\n  end;\nend;\n\n{**\n  Writes the blob by the blob handle.\n}\nprocedure TZPostgreSQLBlob.WriteBlob;\nvar\n  BlobHandle: Integer;\n  Position: Integer;\n  Size: Integer;\nbegin\n  { Checks for empty blob. }\n  if IsEmpty then\n  begin\n    FBlobOid := 0;\n    Exit;\n  end;\n\n  { Creates a new large object. }\n  if FBlobOid = 0 then\n  begin\n    FBlobOid := FPlainDriver.CreateLargeObject(FHandle, INV_WRITE);\n    CheckPostgreSQLError(nil, FPlainDriver, FHandle, lcOther, 'Create Large Object',nil);\n  end;\n\n  { Opens and writes a large object. }\n  BlobHandle := FPlainDriver.OpenLargeObject(FHandle, FBlobOid, INV_WRITE);\n  CheckPostgreSQLError(nil, FPlainDriver, FHandle, lcOther, 'Open Large Object',nil);\n\n  Position := 0;\n  while Position < BlobSize do\n  begin\n    if (BlobSize - Position) < FChunk_Size then\n      Size := BlobSize - Position\n    else\n      Size := FChunk_Size;\n    FPlainDriver.WriteLargeObject(FHandle, BlobHandle,\n      Pointer(NativeUInt(BlobData) + NativeUInt(Position)), Size);\n    CheckPostgreSQLError(nil, FPlainDriver, FHandle, lcOther, 'Write Large Object',nil);\n    Inc(Position, Size);\n  end;\n\n  FPlainDriver.CloseLargeObject(FHandle, BlobHandle);\n  CheckPostgreSQLError(nil, FPlainDriver, FHandle, lcOther, 'Close Large Object',nil);\nend;\n\n{**\n  Checks if this blob has an empty content.\n  @return <code>True</code> if this blob is empty.\n}\nfunction TZPostgreSQLBlob.IsEmpty: Boolean;\nbegin\n  ReadBlob;\n  Result := inherited IsEmpty;\nend;\n\n{**\n  Clones this blob object.\n  @return a clonned blob object.\n}\nfunction TZPostgreSQLBlob.Clone: IZBlob;\nbegin\n  Result := TZPostgreSQLBlob.Create(FPlainDriver, BlobData, BlobSize,\n    FHandle, FBlobOid, FChunk_Size);\nend;\n\n{**\n  Gets the associated stream object.\n  @return an associated or newly created stream object.\n}\nfunction TZPostgreSQLBlob.GetStream: TStream;\nbegin\n  ReadBlob;\n  Result := inherited GetStream;\nend;\n\nend.\n"
  },
  {
    "path": "lib/zeosdbo/src/dbc/ZDbcPostgreSqlStatement.pas",
    "content": "{*********************************************************}\n{                                                         }\n{                 Zeos Database Objects                   }\n{         PostgreSQL Database Connectivity Classes        }\n{                                                         }\n{        Originally written by Sergey Seroukhov           }\n{                                                         }\n{*********************************************************}\n\n{@********************************************************}\n{    Copyright (c) 1999-2012 Zeos Development Group       }\n{                                                         }\n{ License Agreement:                                      }\n{                                                         }\n{ This library is distributed in the hope that it will be }\n{ useful, but WITHOUT ANY WARRANTY; without even the      }\n{ implied warranty of MERCHANTABILITY or FITNESS FOR      }\n{ A PARTICULAR PURPOSE.  See the GNU Lesser General       }\n{ Public License for more details.                        }\n{                                                         }\n{ The source code of the ZEOS Libraries and packages are  }\n{ distributed under the Library GNU General Public        }\n{ License (see the file COPYING / COPYING.ZEOS)           }\n{ with the following  modification:                       }\n{ As a special exception, the copyright holders of this   }\n{ library give you permission to link this library with   }\n{ independent modules to produce an executable,           }\n{ regardless of the license terms of these independent    }\n{ modules, and to copy and distribute the resulting       }\n{ executable under terms of your choice, provided that    }\n{ you also meet, for each linked independent module,      }\n{ the terms and conditions of the license of that module. }\n{ An independent module is a module which is not derived  }\n{ from or based on this library. If you modify this       }\n{ library, you may extend this exception to your version  }\n{ of the library, but you are not obligated to do so.     }\n{ If you do not wish to do so, delete this exception      }\n{ statement from your version.                            }\n{                                                         }\n{                                                         }\n{ The project web site is located on:                     }\n{   http://zeos.firmos.at  (FORUM)                        }\n{   http://sourceforge.net/p/zeoslib/tickets/ (BUGTRACKER)}\n{   svn://svn.code.sf.net/p/zeoslib/code-0/trunk (SVN)    }\n{                                                         }\n{   http://www.sourceforge.net/projects/zeoslib.          }\n{                                                         }\n{                                                         }\n{                                 Zeos Development Group. }\n{********************************************************@}\n\nunit ZDbcPostgreSqlStatement;\n\ninterface\n\n{$I ZDbc.inc}\n\nuses\n  Classes, {$IFDEF MSEgui}mclasses,{$ENDIF} SysUtils, Types,\n  ZSysUtils, ZDbcIntfs, ZDbcStatement, ZDbcLogging, ZPlainPostgreSqlDriver,\n  ZCompatibility, ZVariant, ZDbcGenericResolver, ZDbcCachedResultSet,\n  ZDbcPostgreSql;\n\ntype\n\n  {** Defines a PostgreSQL specific statement. }\n  IZPostgreSQLStatement = interface(IZStatement)\n    ['{E4FAFD96-97CC-4247-8ECC-6E0A168FAFE6}']\n\n    function IsOidAsBlob: Boolean;\n  end;\n\n  {** Implements Generic PostgreSQL Statement. }\n  TZPostgreSQLStatement = class(TZAbstractStatement, IZPostgreSQLStatement)\n  private\n    FPlainDriver: IZPostgreSQLPlainDriver;\n    FOidAsBlob: Boolean;\n  protected\n    function CreateResultSet(const SQL: string;\n      QueryHandle: PZPostgreSQLResult): IZResultSet;\n    function GetConnectionHandle():PZPostgreSQLConnect;\n  public\n    constructor Create(PlainDriver: IZPostgreSQLPlainDriver;\n      Connection: IZConnection; Info: TStrings);\n    destructor Destroy; override;\n\n    function ExecuteQuery(const SQL: RawByteString): IZResultSet; override;\n    function ExecuteUpdate(const SQL: RawByteString): Integer; override;\n    function Execute(const SQL: RawByteString): Boolean; override;\n\n    function IsOidAsBlob: Boolean;\n  end;\n\n  {$IFDEF ZEOS_TEST_ONLY}\n  {** Implements Emulated Prepared SQL Statement. }\n  TZPostgreSQLEmulatedPreparedStatement = class(TZEmulatedPreparedStatement)\n  private\n    FPlainDriver: IZPostgreSQLPlainDriver;\n    Foidasblob: Boolean;\n  protected\n    function CreateExecStatement: IZStatement; override;\n    function PrepareAnsiSQLParam(ParamIndex: Integer): RawByteString; override;\n    function GetConnectionHandle: PZPostgreSQLConnect;\n  public\n    constructor Create(PlainDriver: IZPostgreSQLPlainDriver;\n      Connection: IZConnection; const SQL: string; Info: TStrings);\n  end;\n  {$ENDIF}\n\n  TZPostgreSQLPreparedStatement = class(TZAbstractPreparedStatement)\n  private\n    FPlanName: String;\n    FRawPlanName: RawByteString;\n    FPostgreSQLConnection: IZPostgreSQLConnection;\n    FPlainDriver: IZPostgreSQLPlainDriver;\n    QueryHandle: PZPostgreSQLResult;\n    Foidasblob: Boolean;\n    FConnectionHandle: PZPostgreSQLConnect;\n    Findeterminate_datatype: Boolean;\n    FCachedQuery: TStrings;\n    function CreateResultSet(QueryHandle: PZPostgreSQLResult): IZResultSet;\n  protected\n    procedure SetPlanNames; virtual; abstract;\n  public\n    constructor Create(PlainDriver: IZPostgreSQLPlainDriver;\n      Connection: IZPostgreSQLConnection; const SQL: string; Info: TStrings);\n    destructor Destroy; override;\n  end;\n\n  {** EgonHugeist: Implements Prepared SQL Statement with AnsiString usage }\n  TZPostgreSQLClassicPreparedStatement = class(TZPostgreSQLPreparedStatement)\n  private\n    FExecSQL: RawByteString;\n    function GetAnsiSQLQuery: RawByteString;\n  protected\n    procedure SetPlanNames; override;\n    function PrepareAnsiSQLParam(ParamIndex: Integer; Escaped: Boolean): RawByteString;\n    procedure PrepareInParameters; override;\n    procedure BindInParameters; override;\n    procedure UnPrepareInParameters; override;\n  public\n    procedure Prepare; override;\n\n    function ExecuteQuery(const SQL: RawByteString): IZResultSet; override;\n    function ExecuteUpdate(const SQL: RawByteString): Integer; override;\n    function Execute(const SQL: RawByteString): Boolean; override;\n\n    function ExecuteQueryPrepared: IZResultSet; override;\n    function ExecuteUpdatePrepared: Integer; override;\n    function ExecutePrepared: Boolean; override;\n  end;\n\n  {** EgonHugeist: Implements Prepared SQL Statement based on Protocol3\n    ServerVersion 7.4Up and ClientVersion 8.0Up. with C++API usage}\n  TZPostgreSQLCAPIPreparedStatement = class(TZPostgreSQLPreparedStatement)\n  private\n    FPQparamValues: TPQparamValues;\n    FPQparamLengths: TPQparamLengths;\n    FPQparamFormats: TPQparamFormats;\n    function ExectuteInternal(const SQL: RawByteString; const LogSQL: String;\n      const LoggingCategory: TZLoggingCategory): PZPostgreSQLResult;\n  protected\n    procedure SetPlanNames; override;\n    procedure SetASQL(const Value: RawByteString); override;\n    procedure SetWSQL(const Value: ZWideString); override;\n    procedure PrepareInParameters; override;\n    procedure BindInParameters; override;\n    procedure UnPrepareInParameters; override;\n    function PrepareAnsiSQLQuery: RawByteString;\n\n  public\n    procedure Prepare; override;\n    procedure Unprepare; override;\n\n    function ExecuteQueryPrepared: IZResultSet; override;\n    function ExecuteUpdatePrepared: Integer; override;\n    function ExecutePrepared: Boolean; override;\n  end;\n\n  {** Implements callable Postgresql Statement. }\n  TZPostgreSQLCallableStatement = class(TZAbstractCallableStatement)\n  private\n    Foidasblob: Boolean;\n    FPlainDriver: IZPostgreSQLPlainDriver;\n    function GetProcedureSql: string;\n    function FillParams(const ASql: String): RawByteString;\n    function PrepareAnsiSQLParam(ParamIndex: Integer): RawByteString;\n  protected\n    function GetConnectionHandle:PZPostgreSQLConnect;\n    function GetPlainDriver:IZPostgreSQLPlainDriver;\n    function CreateResultSet(const SQL: string;\n      QueryHandle: PZPostgreSQLResult): IZResultSet;\n    procedure FetchOutParams(ResultSet: IZResultSet);\n    procedure TrimInParameters; override;\n  public\n    constructor Create(Connection: IZConnection; const SQL: string; Info: TStrings);\n\n    function ExecuteQuery(const SQL: RawByteString): IZResultSet; override;\n    function ExecuteUpdate(const SQL: RawByteString): Integer; override;\n\n    function ExecuteQueryPrepared: IZResultSet; override;\n    function ExecuteUpdatePrepared: Integer; override;\n  end;\n\n  {** Implements a specialized cached resolver for PostgreSQL. }\n  TZPostgreSQLCachedResolver = class(TZGenericCachedResolver, IZCachedResolver)\n  protected\n    function CheckKeyColumn(ColumnIndex: Integer): Boolean; override;\n  end;\n\nimplementation\n\nuses\n  ZMessages, ZDbcPostgreSqlResultSet, ZDbcPostgreSqlUtils, ZTokenizer,\n  ZEncoding{$IFDEF WITH_UNITANSISTRINGS}, AnsiStrings{$ENDIF};\n\n{ TZPostgreSQLStatement }\n\n{**\n  Constructs this object and assignes the main properties.\n  @param PlainDriver a PostgreSQL plain driver.\n  @param Connection a database connection object.\n  @param Info a statement parameters.\n  @param Handle a connection handle pointer.\n}\nconstructor TZPostgreSQLStatement.Create(PlainDriver: IZPostgreSQLPlainDriver;\n  Connection: IZConnection; Info: TStrings);\nbegin\n  inherited Create(Connection, Info);\n  FPlainDriver := PlainDriver;\n  ResultSetType := rtScrollInsensitive;\n  { Processes connection properties. }\n  FOidAsBlob := StrToBoolEx(Self.Info.Values['oidasblob'])\n    or (Connection as IZPostgreSQLConnection).IsOidAsBlob;\nend;\n{**\n  Destroys this object and cleanups the memory.\n}\ndestructor TZPostgreSQLStatement.Destroy;\nbegin\n  inherited Destroy;\nend;\n\n{**\n  Checks is oid should be treated as Large Object.\n  @return <code>True</code> if oid should represent a Large Object.\n}\nfunction TZPostgreSQLStatement.IsOidAsBlob: Boolean;\nbegin\n  Result := FOidAsBlob;\nend;\n\n{**\n  Creates a result set based on the current settings.\n  @return a created result set object.\n}\nfunction TZPostgreSQLStatement.CreateResultSet(const SQL: string;\n  QueryHandle: PZPostgreSQLResult): IZResultSet;\nvar\n  NativeResultSet: TZPostgreSQLResultSet;\n  CachedResultSet: TZCachedResultSet;\n  ConnectionHandle: PZPostgreSQLConnect;\nbegin\n  ConnectionHandle := GetConnectionHandle();\n  NativeResultSet := TZPostgreSQLResultSet.Create(FPlainDriver, Self, SQL,\n  ConnectionHandle, QueryHandle, ChunkSize);\n\n  NativeResultSet.SetConcurrency(rcReadOnly);\n  if GetResultSetConcurrency = rcUpdatable then\n  begin\n    CachedResultSet := TZCachedResultSet.Create(NativeResultSet, SQL, nil, ConSettings);\n    CachedResultSet.SetConcurrency(rcUpdatable);\n    CachedResultSet.SetResolver(TZPostgreSQLCachedResolver.Create(\n      Self,  NativeResultSet.GetMetadata));\n    Result := CachedResultSet;\n  end\n  else\n    Result := NativeResultSet;\nend;\n\n{**\n  Executes an SQL statement that returns a single <code>ResultSet</code> object.\n  @param sql typically this is a static SQL <code>SELECT</code> statement\n  @return a <code>ResultSet</code> object that contains the data produced by the\n    given query; never <code>null</code>\n}\nfunction TZPostgreSQLStatement.ExecuteQuery(const SQL: RawByteString): IZResultSet;\nvar\n  QueryHandle: PZPostgreSQLResult;\n  ConnectionHandle: PZPostgreSQLConnect;\nbegin\n  Result := nil;\n  ConnectionHandle := GetConnectionHandle();\n  ASQL := SQL; //Preprepares the SQL and Sets the AnsiSQL\n  QueryHandle := FPlainDriver.ExecuteQuery(ConnectionHandle, PAnsiChar(ASQL));\n  CheckPostgreSQLError(Connection, FPlainDriver, ConnectionHandle, lcExecute,\n    SSQL, QueryHandle);\n  DriverManager.LogMessage(lcExecute, FPlainDriver.GetProtocol, LogSQL);\n  if QueryHandle <> nil then\n    Result := CreateResultSet(LogSQL, QueryHandle)\n  else\n    Result := nil;\nend;\n\n{**\n  Executes an SQL <code>INSERT</code>, <code>UPDATE</code> or\n  <code>DELETE</code> statement. In addition,\n  SQL statements that return nothing, such as SQL DDL statements,\n  can be executed.\n\n  @param sql an SQL <code>INSERT</code>, <code>UPDATE</code> or\n    <code>DELETE</code> statement or an SQL statement that returns nothing\n  @return either the row count for <code>INSERT</code>, <code>UPDATE</code>\n    or <code>DELETE</code> statements, or 0 for SQL statements that return nothing\n}\nfunction TZPostgreSQLStatement.ExecuteUpdate(const SQL: RawByteString): Integer;\nvar\n  QueryHandle: PZPostgreSQLResult;\n  ConnectionHandle: PZPostgreSQLConnect;\nbegin\n  Result := -1;\n  ConnectionHandle := GetConnectionHandle();\n\n  ASQL := SQL; //Prepares SQL if needed\n  QueryHandle := FPlainDriver.ExecuteQuery(ConnectionHandle, PAnsiChar(ASQL));\n  CheckPostgreSQLError(Connection, FPlainDriver, ConnectionHandle, lcExecute,\n    LogSQL, QueryHandle);\n  DriverManager.LogMessage(lcExecute, FPlainDriver.GetProtocol, LogSQL);\n\n  if QueryHandle <> nil then\n  begin\n    Result := StrToIntDef(String(FPlainDriver.GetCommandTuples(QueryHandle)), 0);\n    FPlainDriver.Clear(QueryHandle);\n  end;\n\n  { Autocommit statement. }\n  if Connection.GetAutoCommit then\n    Connection.Commit;\nend;\n\n{**\n  Executes an SQL statement that may return multiple results.\n  Under some (uncommon) situations a single SQL statement may return\n  multiple result sets and/or update counts.  Normally you can ignore\n  this unless you are (1) executing a stored procedure that you know may\n  return multiple results or (2) you are dynamically executing an\n  unknown SQL string.  The  methods <code>execute</code>,\n  <code>getMoreResults</code>, <code>getResultSet</code>,\n  and <code>getUpdateCount</code> let you navigate through multiple results.\n\n  The <code>execute</code> method executes an SQL statement and indicates the\n  form of the first result.  You can then use the methods\n  <code>getResultSet</code> or <code>getUpdateCount</code>\n  to retrieve the result, and <code>getMoreResults</code> to\n  move to any subsequent result(s).\n\n  @param sql any SQL statement\n  @return <code>true</code> if the next result is a <code>ResultSet</code> object;\n  <code>false</code> if it is an update count or there are no more results\n}\nfunction TZPostgreSQLStatement.Execute(const SQL: RawByteString): Boolean;\nvar\n  QueryHandle: PZPostgreSQLResult;\n  ResultStatus: TZPostgreSQLExecStatusType;\n  ConnectionHandle: PZPostgreSQLConnect;\nbegin\n  ASQL := SQL;\n  ConnectionHandle := GetConnectionHandle();\n  QueryHandle := FPlainDriver.ExecuteQuery(ConnectionHandle, PAnsiChar(ASQL));\n  CheckPostgreSQLError(Connection, FPlainDriver, ConnectionHandle, lcExecute,\n    LogSQL, QueryHandle);\n  DriverManager.LogMessage(lcExecute, FPlainDriver.GetProtocol, LogSQL);\n\n  { Process queries with result sets }\n  ResultStatus := FPlainDriver.GetResultStatus(QueryHandle);\n  case ResultStatus of\n    PGRES_TUPLES_OK:\n      begin\n        Result := True;\n        LastResultSet := CreateResultSet(LogSQL, QueryHandle);\n      end;\n    PGRES_COMMAND_OK:\n      begin\n        Result := False;\n        LastUpdateCount := StrToIntDef(String(\n          FPlainDriver.GetCommandTuples(QueryHandle)), 0);\n        FPlainDriver.Clear(QueryHandle);\n      end;\n    else\n      begin\n        Result := False;\n        LastUpdateCount := StrToIntDef(String(\n          FPlainDriver.GetCommandTuples(QueryHandle)), 0);\n        FPlainDriver.Clear(QueryHandle);\n      end;\n  end;\n\n  { Autocommit statement. }\n  if not Result and Connection.GetAutoCommit then\n    Connection.Commit;\nend;\n\n{**\n  Provides connection handle from the associated IConnection\n}\nfunction TZPostgreSQLStatement.GetConnectionHandle():PZPostgreSQLConnect;\nbegin\n  if Self.Connection = nil then\n    Result := nil\n  else\n    Result := (Connection as IZPostgreSQLConnection).GetConnectionHandle;\nend;\n\n{$IFDEF ZEOS_TEST_ONLY}\n{ TZPostgreSQLEmulatedPreparedStatement }\n\n{**\n  Constructs this object and assignes the main properties.\n  @param PlainDriver a PostgreSQL plain driver.\n  @param Connection a database connection object.\n  @param Info a statement parameters.\n  @param Handle a connection handle pointer.\n}\nconstructor TZPostgreSQLEmulatedPreparedStatement.Create(\n  PlainDriver: IZPostgreSQLPlainDriver; Connection: IZConnection;\n  const SQL: string; Info: TStrings);\nbegin\n  inherited Create(Connection, SQL, Info);\n  FPlainDriver := PlainDriver;\n  ResultSetType := rtScrollInsensitive;\n  Foidasblob := StrToBoolDef(Self.Info.Values['oidasblob'], False) or\n    (Connection as IZPostgreSQLConnection).IsOidAsBlob;\nend;\n\n{**\n  Creates a temporary statement which executes queries.\n  @return a created statement object.\n}\nfunction TZPostgreSQLEmulatedPreparedStatement.CreateExecStatement: IZStatement;\nbegin\n  Result := TZPostgreSQLStatement.Create(FPlainDriver, Connection, Info);\nend;\n\n{**\n  Prepares an SQL parameter for the query.\n  @param ParameterIndex the first parameter is 1, the second is 2, ...\n  @return a string representation of the parameter.\n}\nfunction TZPostgreSQLEmulatedPreparedStatement.PrepareAnsiSQLParam(\n  ParamIndex: Integer): RawByteString;\nbegin\n  if InParamCount <= ParamIndex then\n    raise EZSQLException.Create(SInvalidInputParameterCount);\n\n  Result := PGPrepareAnsiSQLParam(InParamValues[ParamIndex],\n    (Connection as IZPostgreSQLConnection), FPlainDriver, ChunkSize,\n    InParamTypes[ParamIndex], Foidasblob, True, False, ConSettings);\nend;\n\n{**\n  Provides connection handle from the associated IConnection\n}\nfunction TZPostgreSQLEmulatedPreparedStatement.GetConnectionHandle:PZPostgreSQLConnect;\nbegin\n  if Self.Connection = nil then\n    Result := nil\n  else\n    Result := (self.Connection as IZPostgreSQLConnection).GetConnectionHandle;\nend;\n{$ENDIF}\n\n{ TZPostgreSQLPreparedStatement }\n\n{**\n  Creates a result set based on the current settings.\n  @param QueryHandle the Postgres query handle\n  @return a created result set object.\n}\nconstructor TZPostgreSQLPreparedStatement.Create(PlainDriver: IZPostgreSQLPlainDriver;\n  Connection: IZPostgreSQLConnection; const SQL: string; Info: TStrings);\nbegin\n  inherited Create(Connection, SQL, Info);\n  Foidasblob := StrToBoolDef(Self.Info.Values['oidasblob'], False) or\n    (Connection as IZPostgreSQLConnection).IsOidAsBlob;\n  FPostgreSQLConnection := Connection;\n  FPlainDriver := PlainDriver;\n  ResultSetType := rtScrollInsensitive;\n  FConnectionHandle := Connection.GetConnectionHandle;\n  Findeterminate_datatype := False;\n  SetPlanNames;\nend;\n\ndestructor TZPostgreSQLPreparedStatement.Destroy;\nbegin\n  if Assigned(FCachedQuery) then\n    FReeAndNil(FCachedQuery);\n  inherited Destroy;\nend;\n\nfunction TZPostgreSQLPreparedStatement.CreateResultSet(QueryHandle: Pointer): IZResultSet;\nvar\n  NativeResultSet: TZPostgreSQLResultSet;\n  CachedResultSet: TZCachedResultSet;\nbegin\n  NativeResultSet := TZPostgreSQLResultSet.Create(FPlainDriver, Self, Self.SQL,\n  FConnectionHandle, QueryHandle, ChunkSize);\n\n  NativeResultSet.SetConcurrency(rcReadOnly);\n  if GetResultSetConcurrency = rcUpdatable then\n  begin\n    CachedResultSet := TZCachedResultSet.Create(NativeResultSet, Self.SQL, nil,\n      ConSettings);\n    CachedResultSet.SetConcurrency(rcUpdatable);\n    CachedResultSet.SetResolver(TZPostgreSQLCachedResolver.Create(\n      Self,  NativeResultSet.GetMetadata));\n    Result := CachedResultSet;\n  end\n  else\n    Result := NativeResultSet;\nend;\n\n{ TZPostgreSQLClassicPreparedStatement }\n\nfunction TZPostgreSQLClassicPreparedStatement.GetAnsiSQLQuery;\nvar\n  I: Integer;\n  ParamIndex: Integer;\n  Tokens: TStrings;\n\n  function TokenizeSQLQuery: TStrings;\n  var\n    I: Integer;\n    Tokens: TStrings;\n    Temp: string;\n  begin\n    if FCachedQuery = nil then\n    begin\n      FCachedQuery := TStringList.Create;\n      if Pos('?', SQL) > 0 then\n      begin\n        Tokens := Connection.GetDriver.GetTokenizer.TokenizeBufferToList(SQL, [toUnifyWhitespaces]);\n        try\n          Temp := '';\n          for I := 0 to Tokens.Count - 1 do\n          begin\n            if Tokens[I] = '?' then\n            begin\n              FCachedQuery.Add(Temp);\n              FCachedQuery.AddObject('?', Self);\n              Temp := '';\n            end\n            else\n              Temp := Temp + Tokens[I];\n          end;\n          if Temp <> '' then\n            FCachedQuery.Add(Temp);\n        finally\n          Tokens.Free;\n        end;\n      end\n      else\n        FCachedQuery.Add(SQL);\n    end;\n    Result := FCachedQuery;\n  end;\nbegin\n  ParamIndex := 0;\n  Result := '';\n  Tokens := TokenizeSQLQuery;\n\n  for I := 0 to Tokens.Count - 1 do\n  begin\n    if Tokens[I] = '?' then\n    begin\n      Result := Result + PrepareAnsiSQLParam(ParamIndex, True);\n      Inc(ParamIndex);\n    end\n    else\n      Result := Result + ZPlainString(Tokens[I]);\n  end;\nend;\n\nprocedure TZPostgreSQLClassicPreparedStatement.SetPlanNames;\nbegin\n  FPlanName := '\"'+IntToStr(Hash(ASQL)+Cardinal(FStatementId)+NativeUInt(FConnectionHandle))+'\"';\n  FRawPlanName := {$IFDEF UNICODE}RawByteString{$ENDIF}(FPlanName);\nend;\n\nfunction TZPostgreSQLClassicPreparedStatement.PrepareAnsiSQLParam(ParamIndex: Integer;\n  Escaped: Boolean): RawByteString;\nbegin\n  if InParamCount <= ParamIndex then\n    raise EZSQLException.Create(SInvalidInputParameterCount);\n\n  Result := PGPrepareAnsiSQLParam(InParamValues[ParamIndex],\n    (Connection as IZPostgreSQLConnection), FPlainDriver, ChunkSize,\n    InParamTypes[ParamIndex], Foidasblob, Escaped, True, ConSettings);\nend;\n\nprocedure TZPostgreSQLClassicPreparedStatement.PrepareInParameters;\nvar\n  I, N: Integer;\n  Tokens: TStrings;\n  TempSQL: String;\n  QueryHandle: PZPostgreSQLResult;\nbegin\n  if Pos('?', SQL) > 0 then\n  begin\n    Tokens := Connection.GetDriver.GetTokenizer.\n      TokenizeBufferToList(SQL, [toUnifyWhitespaces]);\n    try\n      TempSQL := 'PREPARE '+FPlanName+' AS ';\n      N := 0;\n      for I := 0 to Tokens.Count - 1 do\n      begin\n        if Tokens[I] = '?' then\n        begin\n          Inc(N);\n          TempSQL := TempSQL + '$' + IntToStr(N);\n        end else\n          TempSQL := TempSQL + Tokens[I];\n      end;\n    finally\n      Tokens.Free;\n    end;\n  end\n  else Exit;\n\n  {$IFDEF UNICODE}WSQL{$ELSE}ASQL{$ENDIF} := TempSQL;\n  QueryHandle := FPlainDriver.ExecuteQuery(FConnectionHandle,\n    PAnsiChar(ASQL));\n  CheckPostgreSQLError(Connection, FPlainDriver, FConnectionHandle, lcPrepStmt,\n    SSQL, QueryHandle);\n  DriverManager.LogMessage(lcPrepStmt, FPlainDriver.GetProtocol, SSQL);\n  FPlainDriver.Clear(QueryHandle);\nend;\n\nprocedure TZPostgreSQLClassicPreparedStatement.BindInParameters;\nvar\n  I: Integer;\nbegin\n  if Self.InParamCount > 0 then\n  begin\n    if Prepared then\n    begin\n      FExecSQL := 'EXECUTE '+FRawPlanName+'(';\n      for i := 0 to InParamCount -1 do\n        if I = 0 then\n          FExecSQL := FExecSQL+PrepareAnsiSQLParam(i, False)\n        else\n          FExecSQL := FExecSQL+','+PrepareAnsiSQLParam(i, False);\n      FExecSQL := FExecSQL+');';\n    end\n    else\n      FExecSQL := GetAnsiSQLQuery;\n  end\n  else\n    FExecSQL := ASQL;\nend;\n\nprocedure TZPostgreSQLClassicPreparedStatement.UnPrepareInParameters;\nbegin\n  if Prepared and Assigned(FPostgreSQLConnection.GetConnectionHandle) then\n  begin\n    ASQL := 'DEALLOCATE '+FRawPlanName+';';\n    Execute(ASQL);\n  end;\nend;\n\nprocedure TZPostgreSQLClassicPreparedStatement.Prepare;\nbegin\n  { EgonHugeist: assume automated Prepare after third execution. That's the way\n    the JDBC Drivers go too... }\n  if (not Prepared ) and ( InParamCount > 0 ) and ( ExecCount > 2 ) then\n    inherited Prepare;\n  BindInParameters;\nend;\n\n{**\n  Executes an SQL statement that returns a single <code>ResultSet</code> object.\n  @param sql typically this is a static SQL <code>SELECT</code> statement\n  @return a <code>ResultSet</code> object that contains the data produced by the\n    given query; never <code>null</code>\n}\nfunction TZPostgreSQLClassicPreparedStatement.ExecuteQuery(const SQL: RawByteString): IZResultSet;\nbegin\n  Result := nil;\n  ASQL := SQL; //Preprepares the SQL and Sets the AnsiSQL\n  QueryHandle := FPlainDriver.ExecuteQuery(FConnectionHandle, PAnsiChar(ASQL));\n  CheckPostgreSQLError(Connection, FPlainDriver,\n    FConnectionHandle, lcExecute, SSQL, QueryHandle);\n  DriverManager.LogMessage(lcExecute, FPlainDriver.GetProtocol, Self.SSQL);\n  if QueryHandle <> nil then\n    Result := CreateResultSet(QueryHandle)\n  else\n    Result := nil;\nend;\n\n{**\n  Executes an SQL <code>INSERT</code>, <code>UPDATE</code> or\n  <code>DELETE</code> statement. In addition,\n  SQL statements that return nothing, such as SQL DDL statements,\n  can be executed.\n\n  @param sql an SQL <code>INSERT</code>, <code>UPDATE</code> or\n    <code>DELETE</code> statement or an SQL statement that returns nothing\n  @return either the row count for <code>INSERT</code>, <code>UPDATE</code>\n    or <code>DELETE</code> statements, or 0 for SQL statements that return nothing\n}\nfunction TZPostgreSQLClassicPreparedStatement.ExecuteUpdate(const SQL: RawByteString): Integer;\nvar\n  QueryHandle: PZPostgreSQLResult;\nbegin\n  Result := -1;\n  ASQL := SQL; //Preprepares the SQL and Sets the AnsiSQL\n  QueryHandle := FPlainDriver.ExecuteQuery(FConnectionHandle, PAnsiChar(ASQL));\n  CheckPostgreSQLError(Connection, FPlainDriver, FConnectionHandle, lcExecute,\n    SSQL, QueryHandle);\n  DriverManager.LogMessage(lcExecute, FPlainDriver.GetProtocol, SSQL);\n\n  if QueryHandle <> nil then\n  begin\n    Result := StrToIntDef(String(FPlainDriver.GetCommandTuples(QueryHandle)), 0);\n    FPlainDriver.Clear(QueryHandle);\n  end;\n\n  { Autocommit statement. }\n  if Connection.GetAutoCommit then\n    Connection.Commit;\nend;\n\n{**\n  Executes an SQL statement that may return multiple results.\n  Under some (uncommon) situations a single SQL statement may return\n  multiple result sets and/or update counts.  Normally you can ignore\n  this unless you are (1) executing a stored procedure that you know may\n  return multiple results or (2) you are dynamically executing an\n  unknown SQL string.  The  methods <code>execute</code>,\n  <code>getMoreResults</code>, <code>getResultSet</code>,\n  and <code>getUpdateCount</code> let you navigate through multiple results.\n\n  The <code>execute</code> method executes an SQL statement and indicates the\n  form of the first result.  You can then use the methods\n  <code>getResultSet</code> or <code>getUpdateCount</code>\n  to retrieve the result, and <code>getMoreResults</code> to\n  move to any subsequent result(s).\n\n  @param sql any SQL statement\n  @return <code>true</code> if the next result is a <code>ResultSet</code> object;\n  <code>false</code> if it is an update count or there are no more results\n}\nfunction TZPostgreSQLClassicPreparedStatement.Execute(const SQL: RawByteString): Boolean;\nvar\n  QueryHandle: PZPostgreSQLResult;\n  ResultStatus: TZPostgreSQLExecStatusType;\nbegin\n  ASQL := SQL; //Preprepares the SQL and Sets the AnsiSQL\n  QueryHandle := FPlainDriver.ExecuteQuery(FConnectionHandle,\n    PAnsiChar(ASQL));\n  CheckPostgreSQLError(Connection, FPlainDriver, FConnectionHandle, lcExecute,\n    SSQL, QueryHandle);\n  DriverManager.LogMessage(lcExecute, FPlainDriver.GetProtocol, SSQL);\n\n  { Process queries with result sets }\n  ResultStatus := FPlainDriver.GetResultStatus(QueryHandle);\n  case ResultStatus of\n    PGRES_TUPLES_OK:\n      begin\n        Result := True;\n        LastResultSet := CreateResultSet(QueryHandle);\n      end;\n    PGRES_COMMAND_OK:\n      begin\n        Result := False;\n        LastUpdateCount := StrToIntDef(String(\n          FPlainDriver.GetCommandTuples(QueryHandle)), 0);\n        FPlainDriver.Clear(QueryHandle);\n      end;\n    else\n      begin\n        Result := False;\n        LastUpdateCount := StrToIntDef(String(\n          FPlainDriver.GetCommandTuples(QueryHandle)), 0);\n        FPlainDriver.Clear(QueryHandle);\n      end;\n  end;\n\n  { Autocommit statement. }\n  if not Result and Connection.GetAutoCommit then\n    Connection.Commit;\nend;\n\n{**\n  Executes the SQL query in this <code>PreparedStatement</code> object\n  and returns the result set generated by the query.\n\n  @return a <code>ResultSet</code> object that contains the data produced by the\n    query; never <code>null</code>\n}\nfunction TZPostgreSQLClassicPreparedStatement.ExecuteQueryPrepared: IZResultSet;\nbegin\n  Prepare;\n  Result := ExecuteQuery(FExecSQL);\n  inherited ExecuteQueryPrepared;\nend;\n\n{**\n  Executes the SQL INSERT, UPDATE or DELETE statement\n  in this <code>PreparedStatement</code> object.\n  In addition,\n  SQL statements that return nothing, such as SQL DDL statements,\n  can be executed.\n\n  @return either the row count for INSERT, UPDATE or DELETE statements;\n  or 0 for SQL statements that return nothing\n}\nfunction TZPostgreSQLClassicPreparedStatement.ExecuteUpdatePrepared: Integer;\nbegin\n  Prepare;\n  Result := ExecuteUpdate(FExecSQL);\n  inherited ExecuteUpdatePrepared;\nend;\n\n{**\n  Executes any kind of SQL statement.\n  Some prepared statements return multiple results; the <code>execute</code>\n  method handles these complex statements as well as the simpler\n  form of statements handled by the methods <code>executeQuery</code>\n  and <code>executeUpdate</code>.\n  @see Statement#execute\n}\nfunction TZPostgreSQLClassicPreparedStatement.ExecutePrepared: Boolean;\nbegin\n  Prepare;\n  Result := Execute(FExecSQL);\n  inherited ExecutePrepared;\nend;\n\n{ TZPostgreSQLCAPIPreparedStatement }\n\nfunction TZPostgreSQLCAPIPreparedStatement.ExectuteInternal(const SQL: RawByteString;\n  const LogSQL: String; const LoggingCategory: TZLoggingCategory): PZPostgreSQLResult;\nbegin\n  case LoggingCategory of\n    lcPrepStmt:\n      begin\n        Result := FPlainDriver.Prepare(FConnectionHandle, PAnsiChar(RawByteString(FPlanName)),\n          PAnsiChar(SQL), InParamCount, nil);\n        Findeterminate_datatype := (CheckPostgreSQLError(Connection, FPlainDriver,\n          FConnectionHandle, LoggingCategory, LogSQL, Result) = '42P18');\n        DriverManager.LogMessage(LoggingCategory, FPlainDriver.GetProtocol, LogSQL);\n        if not Findeterminate_datatype then\n          FPostgreSQLConnection.RegisterPreparedStmtName(FPlanName);\n        Exit;\n      end;\n    lcExecPrepStmt:\n      Result := FPlainDriver.ExecPrepared(FConnectionHandle,\n        PAnsiChar(RawByteString(FPlanName)), InParamCount, FPQparamValues,\n        FPQparamLengths, FPQparamFormats, 0);\n    lcUnprepStmt:\n      if Assigned(FConnectionHandle) then\n        Result := FPlainDriver.ExecuteQuery(FConnectionHandle, PAnsiChar(SQL))\n      else Result := nil;\n    else\n      Result := FPlainDriver.ExecuteQuery(FConnectionHandle, PAnsiChar(SQL));\n  end;\n  if Assigned(FConnectionHandle) then\n    CheckPostgreSQLError(Connection, FPlainDriver, FConnectionHandle,\n      LoggingCategory, LogSQL, Result);\n  DriverManager.LogMessage(LoggingCategory, FPlainDriver.GetProtocol, LogSQL);\nend;\nprocedure TZPostgreSQLCAPIPreparedStatement.SetPlanNames;\nbegin\n  FPlanName := IntToStr(Hash(ASQL)+Cardinal(FStatementId)+NativeUInt(FConnectionHandle));\n  FRawPlanName := {$IFDEF UNICODE}RawByteString{$ENDIF}(FPlanName);\nend;\n\nprocedure TZPostgreSQLCAPIPreparedStatement.SetASQL(const Value: RawByteString);\nbegin\n  if ( ASQL <> Value ) and Prepared then\n    Unprepare;\n  inherited SetASQL(Value);\nend;\n\nprocedure TZPostgreSQLCAPIPreparedStatement.SetWSQL(const Value: ZWideString);\nbegin\n  if ( WSQL <> Value ) and Prepared then\n    Unprepare;\n  inherited SetWSQL(Value);\nend;\n\nprocedure TZPostgreSQLCAPIPreparedStatement.PrepareInParameters;\nbegin\n  if not (Findeterminate_datatype) then\n  begin\n    SetLength(FPQparamValues, InParamCount);\n    SetLength(FPQparamLengths, InParamCount);\n    SetLength(FPQparamFormats, InParamCount);\n  end;\nend;\n\nprocedure TZPostgreSQLCAPIPreparedStatement.BindInParameters;\nvar\n  Value: TZVariant;\n  TempBlob: IZBlob;\n  TempStream: TStream;\n  WriteTempBlob: IZPostgreSQLBlob;\n  ParamIndex: Integer;\n  TempBytes: TByteDynArray;\n\n  procedure UpdateNull(const Index: Integer);\n  begin\n    FreeMem(FPQparamValues[Index]);\n\n    FPQparamValues[Index] := nil;\n    FPQparamLengths[Index] := 0;\n    FPQparamFormats[Index] := 0;\n  end;\n\n  procedure UpdateString(Value: RawByteString; const Index: Integer);\n  begin\n    UpdateNull(Index);\n\n    FPQparamValues[ParamIndex] := AllocMem(Length(Value) + 1);\n    {$IFDEF WITH_STRPCOPY_DEPRECATED}AnsiStrings.{$ENDIF}StrCopy(FPQparamValues[Index], PAnsiChar(Value));\n  end;\n\n  procedure UpdateBinary(Value: Pointer; const Len, Index: Integer);\n  begin\n    UpdateNull(Index);\n\n    FPQparamValues[Index] := AllocMem(Len);\n    System.Move(Value^, FPQparamValues[Index]^, Len);\n    FPQparamLengths[Index] := Len;\n    FPQparamFormats[Index] := 1;\n  end;\n\nbegin\n  if InParamCount <> High(FPQparamValues)+1 then\n    raise EZSQLException.Create(SInvalidInputParameterCount);\n\n  for ParamIndex := 0 to InParamCount -1 do\n  begin\n    Value := InParamValues[ParamIndex];\n    if DefVarManager.IsNull(Value)  then\n      UpdateNull(ParamIndex)\n    else\n      case InParamTypes[ParamIndex] of\n        stBoolean:\n          UpdateString(RawByteString(UpperCase(BoolToStrEx(SoftVarManager.GetAsBoolean(Value)))), ParamIndex);\n        stByte, stShort, stInteger, stLong, stBigDecimal, stFloat, stDouble:\n          UpdateString(RawByteString(SoftVarManager.GetAsString(Value)), ParamIndex);\n        stBytes:\n          begin\n            TempBytes := SoftVarManager.GetAsBytes(Value);\n            UpdateBinary(PAnsiChar(TempBytes), Length(TempBytes), ParamIndex);\n          end;\n        stString:\n          UpdateString(ZPlainString(SoftVarManager.GetAsString(Value), GetConnection.GetEncoding), ParamIndex);\n        stUnicodeString:\n          UpdateString(ZPlainString(SoftVarManager.GetAsUnicodeString(Value)), ParamIndex);\n        stDate:\n          UpdateString(RawByteString(FormatDateTime('yyyy-mm-dd', SoftVarManager.GetAsDateTime(Value))), ParamIndex);\n        stTime:\n          UpdateString(RawByteString(FormatDateTime('hh\":\"mm\":\"ss\".\"zzz', SoftVarManager.GetAsDateTime(Value))), ParamIndex);\n        stTimestamp:\n          UpdateString(RawByteString(FormatDateTime('yyyy-mm-dd hh\":\"mm\":\"ss\".\"zzz', SoftVarManager.GetAsDateTime(Value))), ParamIndex);\n        stAsciiStream, stUnicodeStream, stBinaryStream:\n          begin\n            TempBlob := DefVarManager.GetAsInterface(Value) as IZBlob;\n            if not TempBlob.IsEmpty then\n            begin\n              case InParamTypes[ParamIndex] of\n                stBinaryStream:\n                  if ((GetConnection as IZPostgreSQLConnection).IsOidAsBlob) or\n                    StrToBoolDef(Info.Values['oidasblob'], False) then\n                  begin\n                    TempStream := TempBlob.GetStream;\n                    try\n                      WriteTempBlob := TZPostgreSQLBlob.Create(FPlainDriver, nil, 0,\n                        FConnectionHandle, 0, ChunkSize);\n                      WriteTempBlob.SetStream(TempStream);\n                      WriteTempBlob.WriteBlob;\n                      UpdateString(RawByteString(IntToStr(WriteTempBlob.GetBlobOid)), ParamIndex);\n                    finally\n                      WriteTempBlob := nil;\n                      TempStream.Free;\n                    end;\n                  end\n                  else\n                    UpdateBinary(TempBlob.GetBuffer, TempBlob.Length, ParamIndex);\n                stAsciiStream, stUnicodeStream:\n                  begin\n                    UpdateString(GetValidatedAnsiStringFromBuffer(TempBlob.GetBuffer,\n                    TempBlob.Length, TempBlob.WasDecoded, ConSettings), ParamIndex);\n                  end;\n              end; {case..}\n              TempBlob := nil;\n            end\n            else\n              UpdateNull(ParamIndex);\n          end; {if not TempBlob.IsEmpty then}\n      end;\n  end;\n  inherited BindInParameters;\nend;\n\n{**\n  Removes eventual structures for binding input parameters.\n}\nprocedure TZPostgreSQLCAPIPreparedStatement.UnPrepareInParameters;\nvar\n  I: Integer;\nbegin\n  { release allocated memory }\n  if not (Findeterminate_datatype) then\n  begin\n    for i := 0 to InParamCount-1 do\n    begin\n      FreeMem(FPQparamValues[i]);\n      FPQparamValues[i] := nil;\n    end;\n    SetLength(FPQparamValues, 0);\n    SetLength(FPQparamLengths, 0);\n    SetLength(FPQparamFormats, 0);\n  end;\nend;\n\n{**\n  Prepares an SQL statement and inserts all data values.\n  @return a prepared SQL statement.\n}\nfunction TZPostgreSQLCAPIPreparedStatement.PrepareAnsiSQLQuery: RawByteString;\nvar\n  I: Integer;\n  ParamIndex: Integer;\n  Tokens: TStrings;\nbegin\n  ParamIndex := 0;\n  Result := '';\n  Tokens := Connection.GetDriver.GetTokenizer.TokenizeBufferToList(SQL, [toUnifyWhitespaces]);\n\n  for I := 0 to Tokens.Count - 1 do\n  begin\n    if Tokens[I] = '?' then\n    begin\n      if InParamCount <= ParamIndex then\n        raise EZSQLException.Create(SInvalidInputParameterCount);\n      Result := Result + PGPrepareAnsiSQLParam(InParamValues[ParamIndex],\n        (Connection as IZPostgreSQLConnection), FPlainDriver, ChunkSize,\n        InParamTypes[ParamIndex], Foidasblob, True, False, ConSettings);\n      Inc(ParamIndex);\n    end\n    else\n      Result := Result + ZPlainString(Tokens[I]);\n  end;\n  Tokens.Free;\nend;\n\nprocedure TZPostgreSQLCAPIPreparedStatement.Prepare;\nvar\n  Tokens: TStrings;\n  TempSQL: String;\n  N, I: Integer;\nbegin\n  if not Prepared then\n  begin\n    N := 0;\n    if Pos('?', SSQL) > 0 then\n    begin\n      TempSQL := ''; //init\n      Tokens := Connection.GetDriver.GetTokenizer.\n        TokenizeBufferToList(SSQL, [toUnifyWhitespaces]);\n      try\n        for I := 0 to Tokens.Count - 1 do\n        begin\n          if Tokens[I] = '?' then\n          begin\n            Inc(N);\n            TempSQL := TempSQL + '$' + IntToStr(N);\n          end else\n            TempSQL := TempSQL + Tokens[I];\n        end;\n      finally\n        Tokens.Free;\n      end;\n    end\n    else TempSQL := SSQL;\n\n    if ( N > 0 ) or ( ExecCount > 2 ) then //prepare only if Params are available or certain executions expected\n    begin\n      QueryHandle := ExectuteInternal(GetEncodedSQL(TempSQL), 'PREPARE '#39+TempSQL+#39, lcPrepStmt);\n      if not (Findeterminate_datatype) then\n        FPlainDriver.Clear(QueryHandle);\n      inherited Prepare;\n    end;\n  end;\nend;\n\nprocedure TZPostgreSQLCAPIPreparedStatement.Unprepare;\nvar\n  TempSQL: String;\nbegin\n  if Prepared then\n  begin\n    inherited Unprepare;\n    if Assigned(FPostgreSQLConnection.GetConnectionHandle) and (not Findeterminate_datatype)  then\n    begin\n      TempSQL := 'DEALLOCATE \"'+FPlanName+'\";';\n      QueryHandle := ExectuteInternal(RawByteString(TempSQL), TempSQL, lcUnprepStmt);\n      FPlainDriver.Clear(QueryHandle);\n      FPostgreSQLConnection.UnregisterPreparedStmtName(FPlanName);\n    end;\n  end;\nend;\n\nfunction TZPostgreSQLCAPIPreparedStatement.ExecuteQueryPrepared: IZResultSet;\nbegin\n  Result := nil;\n\n  Prepare;\n  if Prepared  then\n    if Findeterminate_datatype then\n      QueryHandle := ExectuteInternal(PrepareAnsiSQLQuery, SSQL, lcExecute)\n    else\n    begin\n      BindInParameters;\n      QueryHandle := ExectuteInternal(ASQL, SSQL, lcExecPrepStmt);\n    end\n  else\n    QueryHandle := ExectuteInternal(ASQL, SSQL, lcExecute);\n  if QueryHandle <> nil then\n    Result := CreateResultSet(QueryHandle)\n  else\n    Result := nil;\n  inherited ExecuteQueryPrepared;\nend;\n\nfunction TZPostgreSQLCAPIPreparedStatement.ExecuteUpdatePrepared: Integer;\nbegin\n  Result := -1;\n  Prepare;\n\n  if Prepared  then\n    if Findeterminate_datatype then\n      QueryHandle := ExectuteInternal(PrepareAnsiSQLQuery, SSQL, lcExecute)\n    else\n    begin\n      BindInParameters;\n      QueryHandle := ExectuteInternal(ASQL, SSQL, lcExecPrepStmt);\n    end\n  else\n    QueryHandle := ExectuteInternal(ASQL, SSQL, lcExecute);\n\n  if QueryHandle <> nil then\n  begin\n    Result := StrToIntDef(String(FPlainDriver.GetCommandTuples(QueryHandle)), 0);\n    FPlainDriver.Clear(QueryHandle);\n  end;\n\n  { Autocommit statement. }\n  if Connection.GetAutoCommit then\n    Connection.Commit;\n\n  inherited ExecuteUpdatePrepared;\nend;\n\nfunction TZPostgreSQLCAPIPreparedStatement.ExecutePrepared: Boolean;\nvar\n  ResultStatus: TZPostgreSQLExecStatusType;\nbegin\n  Prepare;\n\n  if Prepared  then\n    if Findeterminate_datatype then\n      QueryHandle := ExectuteInternal(PrepareAnsiSQLQuery, SSQL, lcExecPrepStmt)\n    else\n    begin\n      BindInParameters;\n      QueryHandle := ExectuteInternal(ASQL, SSQL, lcExecPrepStmt);\n    end\n  else\n    QueryHandle := ExectuteInternal(ASQL, SSQL, lcExecute);\n\n  { Process queries with result sets }\n  ResultStatus := FPlainDriver.GetResultStatus(QueryHandle);\n  case ResultStatus of\n    PGRES_TUPLES_OK:\n      begin\n        Result := True;\n        LastResultSet := CreateResultSet(QueryHandle);\n      end;\n    PGRES_COMMAND_OK:\n      begin\n        Result := False;\n        LastUpdateCount := StrToIntDef(String(\n          FPlainDriver.GetCommandTuples(QueryHandle)), 0);\n        FPlainDriver.Clear(QueryHandle);\n      end;\n    else\n      begin\n        Result := False;\n        LastUpdateCount := StrToIntDef(String(\n          FPlainDriver.GetCommandTuples(QueryHandle)), 0);\n        FPlainDriver.Clear(QueryHandle);\n      end;\n  end;\n\n  { Autocommit statement. }\n  if not Result and Connection.GetAutoCommit then\n    Connection.Commit;\n\n  inherited ExecutePrepared;\nend;\n\n\n{ TZPostgreSQLCallableStatement }\n\n{**\n  Constructs this object and assignes the main properties.\n  @param Connection a database connection object.\n  @param Info a statement parameters.\n  @param Handle a connection handle pointer.\n}\nconstructor TZPostgreSQLCallableStatement.Create(\n  Connection: IZConnection; const SQL: string; Info: TStrings);\nbegin\n  inherited Create(Connection, SQL, Info);\n  ResultSetType := rtScrollInsensitive;\n  FPlainDriver := (Connection as IZPostgreSQLConnection).GetPlainDriver;\n  Foidasblob := StrToBoolDef(Self.Info.Values['oidasblob'], False) or\n    (Connection as IZPostgreSQLConnection).IsOidAsBlob;\nend;\n\n{**\n  Provides connection handle from the associated IConnection\n  @return a PostgreSQL connection handle.\n}\nfunction TZPostgreSQLCallableStatement.GetConnectionHandle:PZPostgreSQLConnect;\nbegin\n  if Self.Connection = nil then\n    Result := nil\n  else\n    Result := (self.Connection as IZPostgreSQLConnection).GetConnectionHandle;\nend;\n\n{**\n  Creates a result set based on the current settings.\n  @return a created result set object.\n}\nfunction TZPostgreSQLCallableStatement.CreateResultSet(const SQL: string;\n      QueryHandle: PZPostgreSQLResult): IZResultSet;\nvar\n  NativeResultSet: TZPostgreSQLResultSet;\n  CachedResultSet: TZCachedResultSet;\n  ConnectionHandle: PZPostgreSQLConnect;\nbegin\n  ConnectionHandle := GetConnectionHandle();\n  NativeResultSet := TZPostgreSQLResultSet.Create(GetPlainDriver, Self, SQL,\n    ConnectionHandle, QueryHandle, ChunkSize);\n  NativeResultSet.SetConcurrency(rcReadOnly);\n  if GetResultSetConcurrency = rcUpdatable then\n  begin\n    CachedResultSet := TZCachedResultSet.Create(NativeResultSet, SQL, nil,\n      ConSettings);\n    CachedResultSet.SetConcurrency(rcUpdatable);\n    CachedResultSet.SetResolver(TZPostgreSQLCachedResolver.Create(\n      Self,  NativeResultSet.GetMetadata));\n    Result := CachedResultSet;\n  end\n  else\n    Result := NativeResultSet;\nend;\n\n{**\n   Returns plain draiver from connection object\n   @return a PlainDriver object\n}\nfunction TZPostgreSQLCallableStatement.GetPlainDriver():IZPostgreSQLPlainDriver;\nbegin\n  if self.Connection <> nil then\n    Result := (self.Connection as IZPostgreSQLConnection).GetPlainDriver\n  else\n    Result := nil;\nend;\n\n{**\n  Prepares an SQL parameter for the query.\n  @param ParameterIndex the first parameter is 1, the second is 2, ...\n  @return a string representation of the parameter.\n}\nfunction TZPostgreSQLCallableStatement.PrepareAnsiSQLParam(\n  ParamIndex: Integer): RawByteString;\nbegin\n  if InParamCount <= ParamIndex then\n    raise EZSQLException.Create(SInvalidInputParameterCount);\n\n  Result := PGPrepareAnsiSQLParam(InParamValues[ParamIndex],\n    (Connection as IZPostgreSQLConnection), FPlainDriver, ChunkSize,\n    InParamTypes[ParamIndex], Foidasblob, True, False, ConSettings);\nend;\n\n{**\n  Executes an SQL statement that returns a single <code>ResultSet</code> object.\n  @param sql typically this is a static SQL <code>SELECT</code> statement\n  @return a <code>ResultSet</code> object that contains the data produced by the\n    given query; never <code>null</code>\n}\nfunction TZPostgreSQLCallableStatement.ExecuteQuery(\n  const SQL: RawByteString): IZResultSet;\nvar\n  QueryHandle: PZPostgreSQLResult;\n  ConnectionHandle: PZPostgreSQLConnect;\nbegin\n  Result := nil;\n  ConnectionHandle := GetConnectionHandle();\n  ASQL := SQL; //Preprepares the SQL and Sets the AnsiSQL\n  QueryHandle := GetPlainDriver.ExecuteQuery(ConnectionHandle,\n    PAnsiChar(ASQL));\n  CheckPostgreSQLError(Connection, GetPlainDriver, ConnectionHandle, lcExecute,\n    LogSQL, QueryHandle);\n  DriverManager.LogMessage(lcExecute, GetPlainDriver.GetProtocol, LogSQL);\n  if QueryHandle <> nil then\n  begin\n    Result := CreateResultSet(SSQL, QueryHandle);\n    FetchOutParams(Result);\n  end\n  else\n    Result := nil;\nend;\n\n{**\n  Prepares and executes an SQL statement that returns a single <code>ResultSet</code> object.\n  @return a <code>ResultSet</code> object that contains the data produced by the\n    given query; never <code>null</code>\n}\nfunction TZPostgreSQLCallableStatement.ExecuteQueryPrepared: IZResultSet;\nbegin\n  TrimInParameters;\n  Result := ExecuteQuery(FillParams(GetProcedureSql));\nend;\n\n{**\n   Create sql string for calling stored procedure.\n   @return a Stored Procedure SQL string\n}\nfunction TZPostgreSQLCallableStatement.GetProcedureSql: string;\n\n  function GenerateParamsStr(Count: integer): string;\n  var\n    I: integer;\n  begin\n    Result := '';\n    for I := 0 to Count - 1 do\n    begin\n      if Result <> '' then\n        Result := Result + ',';\n      Result := Result + '?';\n    end;\n  end;\n\nvar\n  InParams: string;\nbegin\n  InParams := GenerateParamsStr(Length(InParamValues));\n  Result := Format('SELECT * FROM %s(%s)', [SQL, InParams]);\nend;\n\n{**\n   Fills the parameter (?) tokens with corresponding parameter value\n   @return a prepared SQL query for execution\n}\nfunction TZPostgreSQLCallableStatement.FillParams(const ASql: String): RawByteString;\nvar I: Integer;\n  Tokens: TStrings;\n  ParamIndex: Integer;\nbegin\n  if Pos('?', ASql) > 0 then\n  begin\n    Tokens := Connection.GetDriver.GetTokenizer.TokenizeBufferToList(ASql, [toUnifyWhitespaces]);\n    try\n      ParamIndex := 0;\n      for I := 0 to Tokens.Count - 1 do\n        if Tokens[I] = '?' then\n        begin\n          Result := Result + PrepareAnsiSQLParam(ParamIndex);\n          Inc(ParamIndex);\n        end\n        else\n          Result := Result + ZPlainString(Tokens[i]);\n    finally\n      Tokens.Free;\n    end;\n  end\n  else\n    Result := GetEncodedSQL(ASql);\nend;\n\n{**\n  Executes an SQL <code>INSERT</code>, <code>UPDATE</code> or\n  <code>DELETE</code> statement. In addition,\n  SQL statements that return nothing, such as SQL DDL statements,\n  can be executed.\n\n  @param sql an SQL <code>INSERT</code>, <code>UPDATE</code> or\n    <code>DELETE</code> statement or an SQL statement that returns nothing\n  @return either the row count for <code>INSERT</code>, <code>UPDATE</code>\n    or <code>DELETE</code> statements, or 0 for SQL statements that return nothing\n}\nfunction TZPostgreSQLCallableStatement.ExecuteUpdate(const SQL: RawByteString): Integer;\nvar\n  QueryHandle: PZPostgreSQLResult;\n  ConnectionHandle: PZPostgreSQLConnect;\nbegin\n  Result := -1;\n  ConnectionHandle := GetConnectionHandle();\n  ASQL := SQL; //Preprepares the SQL and Sets the AnsiSQL\n  QueryHandle := GetPlainDriver.ExecuteQuery(ConnectionHandle,\n    PAnsiChar(ASQL));\n  CheckPostgreSQLError(Connection, GetPlainDriver, ConnectionHandle, lcExecute,\n    SSQL, QueryHandle);\n  DriverManager.LogMessage(lcExecute, GetPlainDriver.GetProtocol, SSQL);\n\n  if QueryHandle <> nil then\n  begin\n    Result := StrToIntDef(String(GetPlainDriver.GetCommandTuples(QueryHandle)), 0);\n    FetchOutParams(CreateResultSet(SSQL, QueryHandle));\n  end;\n\n  { Autocommit statement. }\n  if Connection.GetAutoCommit then\n    Connection.Commit;\nend;\n\n\nfunction TZPostgreSQLCallableStatement.ExecuteUpdatePrepared: Integer;\nbegin\n  TrimInParameters;\n  Result := Self.ExecuteUpdate(FillParams(GetProcedureSql));\nend;\n\n{**\n  Sets output parameters from a ResultSet\n  @param Value a IZResultSet object.\n}\nprocedure TZPostgreSQLCallableStatement.FetchOutParams(ResultSet: IZResultSet);\nvar\n  ParamIndex, I: Integer;\n  Temp: TZVariant;\n  HasRows: Boolean;\nbegin\n  ResultSet.BeforeFirst;\n  HasRows := ResultSet.Next;\n\n  I := 1;\n  for ParamIndex := 0 to OutParamCount - 1 do\n  begin\n    if not (FDBParamTypes[ParamIndex] in [2, 3, 4]) then // ptOutput, ptInputOutput, ptResult\n      Continue;\n\n    if I > ResultSet.GetMetadata.GetColumnCount then\n      Break;\n\n    if (not HasRows) or (ResultSet.IsNull(I)) then\n      DefVarManager.SetNull(Temp)\n    else\n      case ResultSet.GetMetadata.GetColumnType(I) of\n      stBoolean:\n        DefVarManager.SetAsBoolean(Temp, ResultSet.GetBoolean(I));\n      stByte:\n        DefVarManager.SetAsInteger(Temp, ResultSet.GetByte(I));\n      stShort:\n        DefVarManager.SetAsInteger(Temp, ResultSet.GetShort(I));\n      stInteger:\n        DefVarManager.SetAsInteger(Temp, ResultSet.GetInt(I));\n      stLong:\n        DefVarManager.SetAsInteger(Temp, ResultSet.GetLong(I));\n      stFloat:\n        DefVarManager.SetAsFloat(Temp, ResultSet.GetFloat(I));\n      stDouble:\n        DefVarManager.SetAsFloat(Temp, ResultSet.GetDouble(I));\n      stBigDecimal:\n        DefVarManager.SetAsFloat(Temp, ResultSet.GetBigDecimal(I));\n      stString:\n        DefVarManager.SetAsString(Temp, ResultSet.GetString(I));\n      stUnicodeString:\n        DefVarManager.SetAsUnicodeString(Temp, ResultSet.GetUnicodeString(I));\n      stDate:\n        DefVarManager.SetAsDateTime(Temp, ResultSet.GetDate(I));\n      stTime:\n        DefVarManager.SetAsDateTime(Temp, ResultSet.GetTime(I));\n      stTimestamp:\n        DefVarManager.SetAsDateTime(Temp, ResultSet.GetTimestamp(I));\n      else\n        DefVarManager.SetAsString(Temp, ResultSet.GetString(I));\n      end;\n    OutParamValues[ParamIndex] := Temp;\n    Inc(I);\n  end;\n  ResultSet.BeforeFirst;\nend;\n\n{**\n   Function removes ptResult, ptOutput parameters from\n   InParamTypes and InParamValues\n}\nprocedure TZPostgreSQLCallableStatement.TrimInParameters;\nvar\n  I: integer;\n  ParamValues: TZVariantDynArray;\n  ParamTypes: TZSQLTypeArray;\n  ParamCount: Integer;\nbegin\n  ParamCount := 0;\n  SetLength(ParamValues, InParamCount);\n  SetLength(ParamTypes, InParamCount);\n\n  for I := 0 to High(InParamTypes) do\n  begin\n    if (Self.FDBParamTypes[i] in [2, 4]) then //[ptResult, ptOutput]\n      Continue;\n    ParamTypes[ParamCount] := InParamTypes[I];\n    ParamValues[ParamCount] := InParamValues[I];\n    Inc(ParamCount);\n  end;\n\n  if ParamCount = InParamCount then\n    Exit;\n\n  InParamTypes := ParamTypes;\n  InParamValues := ParamValues;\n  SetInParamCount(ParamCount);\nend;\n\n{ TZPostgreSQLCachedResolver }\n\n{**\n  Checks is the specified column can be used in where clause.\n  @param ColumnIndex an index of the column.\n  @returns <code>true</code> if column can be included into where clause.\n}\nfunction TZPostgreSQLCachedResolver.CheckKeyColumn(ColumnIndex: Integer): Boolean;\nbegin\n  Result := (Metadata.GetTableName(ColumnIndex) <> '')\n    and (Metadata.GetColumnName(ColumnIndex) <> '')\n    and Metadata.IsSearchable(ColumnIndex)\n    and not (Metadata.GetColumnType(ColumnIndex)\n    in [stUnknown, stBinaryStream, stUnicodeStream]);\nend;\n\n\n\nend.\n\n"
  },
  {
    "path": "lib/zeosdbo/src/dbc/ZDbcPostgreSqlUtils.pas",
    "content": "{*********************************************************}\n{                                                         }\n{                 Zeos Database Objects                   }\n{         PostgreSQL Database Connectivity Classes        }\n{                                                         }\n{         Originally written by Sergey Seroukhov          }\n{                           and Sergey Merkuriev          }\n{                                                         }\n{*********************************************************}\n\n{@********************************************************}\n{    Copyright (c) 1999-2012 Zeos Development Group       }\n{                                                         }\n{ License Agreement:                                      }\n{                                                         }\n{ This library is distributed in the hope that it will be }\n{ useful, but WITHOUT ANY WARRANTY; without even the      }\n{ implied warranty of MERCHANTABILITY or FITNESS FOR      }\n{ A PARTICULAR PURPOSE.  See the GNU Lesser General       }\n{ Public License for more details.                        }\n{                                                         }\n{ The source code of the ZEOS Libraries and packages are  }\n{ distributed under the Library GNU General Public        }\n{ License (see the file COPYING / COPYING.ZEOS)           }\n{ with the following  modification:                       }\n{ As a special exception, the copyright holders of this   }\n{ library give you permission to link this library with   }\n{ independent modules to produce an executable,           }\n{ regardless of the license terms of these independent    }\n{ modules, and to copy and distribute the resulting       }\n{ executable under terms of your choice, provided that    }\n{ you also meet, for each linked independent module,      }\n{ the terms and conditions of the license of that module. }\n{ An independent module is a module which is not derived  }\n{ from or based on this library. If you modify this       }\n{ library, you may extend this exception to your version  }\n{ of the library, but you are not obligated to do so.     }\n{ If you do not wish to do so, delete this exception      }\n{ statement from your version.                            }\n{                                                         }\n{                                                         }\n{ The project web site is located on:                     }\n{   http://zeos.firmos.at  (FORUM)                        }\n{   http://sourceforge.net/p/zeoslib/tickets/ (BUGTRACKER)}\n{   svn://svn.code.sf.net/p/zeoslib/code-0/trunk (SVN)    }\n{                                                         }\n{   http://www.sourceforge.net/projects/zeoslib.          }\n{                                                         }\n{                                                         }\n{                                 Zeos Development Group. }\n{********************************************************@}\n\nunit ZDbcPostgreSqlUtils;\n\ninterface\n\n{$I ZDbc.inc}\n\nuses\n  Classes, {$IFDEF MSEgui}mclasses,{$ENDIF} SysUtils,\n  ZDbcIntfs, ZPlainPostgreSqlDriver, ZDbcPostgreSql, ZDbcLogging,\n  ZCompatibility, ZVariant;\n\n{**\n  Indicate what field type is a number (integer, float and etc.)\n  @param  the SQLType field type value\n  @result true if field type number\n}\nfunction IsNumber(Value: TZSQLType): Boolean;\n\n{**\n   Return ZSQLType from PostgreSQL type name\n   @param Connection a connection to PostgreSQL\n   @param The TypeName is PostgreSQL type name\n   @return The ZSQLType type\n}\nfunction PostgreSQLToSQLType(Connection: IZPostgreSQLConnection;\n  TypeName: string): TZSQLType; overload;\n\n{**\n    Another version of PostgreSQLToSQLType()\n      - comparing integer should be faster than AnsiString?\n   Return ZSQLType from PostgreSQL type name\n   @param Connection a connection to PostgreSQL\n   @param TypeOid is PostgreSQL type OID\n   @return The ZSQLType type\n}\nfunction PostgreSQLToSQLType(const ConSettings: PZConSettings;\n  const OIDAsBlob: Boolean; const TypeOid: Integer): TZSQLType; overload;\n\n{**\n   Return PostgreSQL type name from ZSQLType\n   @param The ZSQLType type\n   @return The Postgre TypeName\n}\nfunction SQLTypeToPostgreSQL(SQLType: TZSQLType; IsOidAsBlob: Boolean): string;\n\n{**\n  add by Perger -> based on SourceForge:\n  [ 1520587 ] Fix for 1484704: bytea corrupted on post when not using utf8,\n  file: 1484704.patch\n\n  Converts a binary string into escape PostgreSQL format.\n  @param Value a binary stream.\n  @return a string in PostgreSQL binary string escape format.\n}\nfunction EncodeBinaryString(const Value: AnsiString): AnsiString;\n\n{**\n  Encode string which probably consists of multi-byte characters.\n  Characters ' (apostraphy), low value (value zero), and \\ (back slash) are encoded. Since we have noticed that back slash is the second byte of some BIG5 characters (each of them is two bytes in length), we need a characterset aware encoding function.\n  @param CharactersetCode the characterset in terms of enumerate code.\n  @param Value the regular string.\n  @return the encoded string.\n}\nfunction PGEscapeString(Handle: Pointer; const Value: RawByteString;\n    ConSettings: PZConSettings; WasEncoded: Boolean = False): RawByteString;\n\n{**\n  Converts an string from escape PostgreSQL format.\n  @param Value a string in PostgreSQL escape format.\n  @return a regular string.\n}\nfunction DecodeString(const Value: AnsiString): AnsiString;\n\n{**\n  Checks for possible sql errors.\n  @param Connection a reference to database connection to execute Rollback.\n  @param PlainDriver a PostgreSQL plain driver.\n  @param Handle a PostgreSQL connection reference.\n  @param LogCategory a logging category.\n  @param LogMessage a logging message.\n  @param ResultHandle the Handle to the Result\n}\n\nfunction CheckPostgreSQLError(Connection: IZConnection;\n  PlainDriver: IZPostgreSQLPlainDriver;\n  Handle: PZPostgreSQLConnect; LogCategory: TZLoggingCategory;\n  const LogMessage: string;\n  ResultHandle: PZPostgreSQLResult): String;\n\n\n{**\n   Resolve problem with minor version in PostgreSql bettas\n   @param Value a minor version string like \"4betta2\"\n   @return a miror version number\n}\nfunction GetMinorVersion(const Value: string): Word;\n\n{**\n  Prepares an SQL parameter for the query.\n  @param ParameterIndex the first parameter is 1, the second is 2, ...\n  @return a string representation of the parameter.\n}\nfunction PGPrepareAnsiSQLParam(Value: TZVariant; Connection: IZPostgreSQLConnection;\n  PlainDriver: IZPostgreSQLPlainDriver; const ChunkSize: Cardinal;\n  const InParamType: TZSQLType; const oidasblob, DateTimePrefix, QuotedNumbers: Boolean;\n  ConSettings: PZConSettings): RawByteString;\n\nimplementation\n\nuses ZMessages, ZDbcPostgreSqlResultSet, ZEncoding, ZDbcPostgreSqlStatement;\n\n{**\n   Return ZSQLType from PostgreSQL type name\n   @param Connection a connection to PostgreSQL\n   @param The TypeName is PostgreSQL type name\n   @return The ZSQLType type\n}\nfunction PostgreSQLToSQLType(Connection: IZPostgreSQLConnection;\n  TypeName: string): TZSQLType;\nbegin\n  TypeName := LowerCase(TypeName);\n  if (TypeName = 'interval') or (TypeName = 'char') or (TypeName = 'bpchar')\n    or (TypeName = 'varchar') or (TypeName = 'bit') or (TypeName = 'varbit')\n  then//EgonHugeist: Highest Priority Client_Character_set!!!!\n    if (Connection.GetConSettings.CPType = cCP_UTF16) then\n      Result := stUnicodeString\n    else\n      Result := stString\n  else if TypeName = 'text' then\n    Result := stAsciiStream\n  else if TypeName = 'oid' then\n  begin\n    if Connection.IsOidAsBlob() then\n      Result := stBinaryStream\n    else\n      Result := stInteger;\n  end\n  else if TypeName = 'name' then\n    Result := stString\n  else if TypeName = 'enum' then\n    Result := stString\n  else if TypeName = 'cidr' then\n    Result := stString\n  else if TypeName = 'inet' then\n    Result := stString\n  else if TypeName = 'macaddr' then\n    Result := stString\n  else if TypeName = 'int2' then\n    Result := stShort\n  else if TypeName = 'int4' then\n    Result := stInteger\n  else if TypeName = 'int8' then\n    Result := stLong\n  else if TypeName = 'float4' then\n    Result := stFloat\n  else if (TypeName = 'float8') or (TypeName = 'decimal')\n    or (TypeName = 'numeric') then\n    Result := stDouble\n  else if TypeName = 'money' then\n    Result := stDouble\n  else if TypeName = 'bool' then\n    Result := stBoolean\n  else if TypeName = 'date' then\n    Result := stDate\n  else if TypeName = 'time' then\n    Result := stTime\n  else if (TypeName = 'datetime') or (TypeName = 'timestamp')\n    or (TypeName = 'timestamptz') or (TypeName = 'abstime') then\n    Result := stTimestamp\n  else if TypeName = 'regproc' then\n    Result := stString\n  else if TypeName = 'bytea' then\n  begin\n    if Connection.IsOidAsBlob then\n      Result := stBytes\n    else\n      Result := stBinaryStream;\n  end\n  else if (TypeName = 'int2vector') or (TypeName = 'oidvector') then\n    Result := stAsciiStream\n  else if (TypeName <> '') and (TypeName[1] = '_') then // ARRAY TYPES\n    Result := stAsciiStream\n  else\n    Result := stUnknown;\n\n  if (Connection.GetConSettings.CPType = cCP_UTF16) then\n    if Result = stAsciiStream then\n      Result := stUnicodeStream;\nend;\n\n{**\n   Another version of PostgreSQLToSQLType()\n     - comparing integer should be faster than AnsiString.\n   Return ZSQLType from PostgreSQL type name\n   @param Connection a connection to PostgreSQL\n   @param TypeOid is PostgreSQL type OID\n   @return The ZSQLType type\n}\nfunction PostgreSQLToSQLType(const ConSettings: PZConSettings;\n  const OIDAsBlob: Boolean; const TypeOid: Integer): TZSQLType; overload;\nbegin\n  case TypeOid of\n    1186,18,1042,1043:  { interval/char/bpchar/varchar }\n      if (ConSettings.CPType = cCP_UTF16) then\n          Result := stUnicodeString\n        else\n          Result := stString;\n    25: Result := stAsciiStream; { text }\n    26: { oid }\n      begin\n        if OidAsBlob then\n          Result := stBinaryStream\n        else\n          Result := stInteger;\n      end;\n    19: Result := stString; { name }\n    21: Result := stShort; { int2 }\n    23: Result := stInteger; { int4 }\n    20: Result := stLong; { int8 }\n    650: Result := stString; { cidr }\n    869: Result := stString; { inet }\n    829: Result := stString; { macaddr }\n    700: Result := stFloat; { float4 }\n    701,1700: Result := stDouble; { float8/numeric. no 'decimal' any more }\n    790: Result := stDouble; { money }\n    16: Result := stBoolean; { bool }\n    1082: Result := stDate; { date }\n    1083: Result := stTime; { time }\n    1114,1184,702: Result := stTimestamp; { timestamp,timestamptz/abstime. no 'datetime' any more}\n    1560,1562: Result := stString; {bit/ bit varying string}\n    24: Result := stString; { regproc }\n    1034: Result := stAsciiStream; {aclitem[]}\n    17: { bytea }\n      begin\n        if OidAsBlob then\n          Result := stBytes\n        else\n          Result := stBinaryStream;\n      end;\n    22,30: Result := stAsciiStream; { int2vector/oidvector. no '_aclitem' }\n    143,629,651,719,791,1000..1028,1040,1041,1115,1182,1183,1185,1187,1231,1263,\n    1270,1561,1563,2201,2207..2211,2949,2951,3643,3644,3645,3735,3770 : { other array types }\n      Result := stAsciiStream;\n    else\n      Result := stUnknown;\n  end;\n\n  if (ConSettings.CPType = cCP_UTF16) then\n    if Result = stAsciiStream then\n      Result := stUnicodeStream;\nend;\n\nfunction SQLTypeToPostgreSQL(SQLType: TZSQLType; IsOidAsBlob: boolean): string;\nbegin\n  case SQLType of\n    stBoolean: Result := 'bool';\n    stByte, stShort, stInteger, stLong: Result := 'int';\n    stFloat, stDouble, stBigDecimal: Result := 'numeric';\n    stString, stUnicodeString, stAsciiStream, stUnicodeStream: Result := 'text';\n    stDate: Result := 'date';\n    stTime: Result := 'time';\n    stTimestamp: Result := 'timestamp';\n    stBinaryStream, stBytes:\n      if IsOidAsBlob then\n        Result := 'oid'\n      else\n        Result := 'bytea';\n  end;\nend;\n\n{**\n  Indicate what field type is a number (integer, float and etc.)\n  @param  the SQLType field type value\n  @result true if field type number\n}\nfunction IsNumber(Value: TZSQLType): Boolean;\nbegin\n  Result := Value in [stByte, stShort, stInteger, stLong,\n    stFloat, stDouble, stBigDecimal];\nend;\n\n{**\n  Encode string which probably consists of multi-byte characters.\n  Characters ' (apostraphy), low value (value zero), and \\ (back slash) are encoded.\n  Since we have noticed that back slash is the second byte of some BIG5 characters\n    (each of them is two bytes in length), we need a characterset aware encoding function.\n  @param CharactersetCode the characterset in terms of enumerate code.\n  @param Value the regular string.\n  @return the encoded string.\n}\nfunction PGEscapeString(Handle: Pointer; const Value: RawByteString;\n    ConSettings: PZConSettings; WasEncoded: Boolean = False): RawByteString;\nvar\n  I, LastState: Integer;\n  SrcLength, DestLength: Integer;\n  SrcBuffer, DestBuffer: PAnsiChar;\n\n  function pg_CS_stat(stat: integer; character: integer;\n          CharactersetCode: TZPgCharactersetType): integer;\n  begin\n    if character = 0 then\n      stat := 0;\n\n    case CharactersetCode of\n      csUTF8, csUNICODE_PODBC:\n        begin\n          if (stat < 2) and (character >= $80) then\n          begin\n            if character >= $fc then\n              stat := 6\n            else if character >= $f8 then\n              stat := 5\n            else if character >= $f0 then\n              stat := 4\n            else if character >= $e0 then\n              stat := 3\n            else if character >= $c0 then\n              stat := 2;\n          end\n          else\n            if (stat > 2) and (character > $7f) then\n              Dec(stat)\n            else\n              stat := 0;\n        end;\n  { Shift-JIS Support. }\n      csSJIS:\n        begin\n      if (stat < 2)\n        and (character > $80)\n        and not ((character > $9f) and (character < $e0)) then\n        stat := 2\n      else if stat = 2 then\n        stat := 1\n      else\n        stat := 0;\n        end;\n  { Chinese Big5 Support. }\n      csBIG5:\n        begin\n      if (stat < 2) and (character > $A0) then\n        stat := 2\n      else if stat = 2 then\n        stat := 1\n      else\n        stat := 0;\n        end;\n  { Chinese GBK Support. }\n      csGBK:\n        begin\n      if (stat < 2) and (character > $7F) then\n        stat := 2\n      else if stat = 2 then\n        stat := 1\n      else\n        stat := 0;\n        end;\n\n  { Korian UHC Support. }\n      csUHC:\n        begin\n      if (stat < 2) and (character > $7F) then\n        stat := 2\n      else if stat = 2 then\n        stat := 1\n      else\n        stat := 0;\n        end;\n\n  { EUC_JP Support }\n      csEUC_JP:\n        begin\n      if (stat < 3) and (character = $8f) then { JIS X 0212 }\n        stat := 3\n      else\n      if (stat <> 2)\n        and ((character = $8e) or\n        (character > $a0)) then { Half Katakana HighByte & Kanji HighByte }\n        stat := 2\n      else if stat = 2 then\n        stat := 1\n      else\n        stat := 0;\n        end;\n\n  { EUC_CN, EUC_KR, JOHAB Support }\n      csEUC_CN, csEUC_KR, csJOHAB:\n        begin\n      if (stat < 2) and (character > $a0) then\n        stat := 2\n      else if stat = 2 then\n        stat := 1\n      else\n        stat := 0;\n        end;\n      csEUC_TW:\n        begin\n      if (stat < 4) and (character = $8e) then\n        stat := 4\n      else if (stat = 4) and (character > $a0) then\n        stat := 3\n      else if ((stat = 3) or (stat < 2)) and (character > $a0) then\n        stat := 2\n      else if stat = 2 then\n        stat := 1\n      else\n        stat := 0;\n        end;\n        { Chinese GB18030 support.Added by Bill Huang <bhuang@redhat.com> <bill_huanghb@ybb.ne.jp> }\n      csGB18030:\n        begin\n      if (stat < 2) and (character > $80) then\n        stat := 2\n      else if stat = 2 then\n      begin\n        if (character >= $30) and (character <= $39) then\n          stat := 3\n        else\n          stat := 1;\n      end\n      else if stat = 3 then\n      begin\n        if (character >= $30) and (character <= $39) then\n          stat := 1\n        else\n          stat := 3;\n      end\n      else\n        stat := 0;\n        end;\n      else\n      stat := 0;\n    end;\n    Result := stat;\n  end;\n\nbegin\n  SrcLength := Length(Value);\n  SrcBuffer := PAnsiChar(Value);\n  DestLength := 2;\n  LastState := 0;\n  for I := 1 to SrcLength do\n  begin\n    LastState := pg_CS_stat(LastState,integer(SrcBuffer^),\n      TZPgCharactersetType(ConSettings.ClientCodePage.ID));\n    if CharInSet(SrcBuffer^, [#0, '''']) or ((SrcBuffer^ = '\\') and (LastState = 0)) then\n      Inc(DestLength, 4)\n    else\n      Inc(DestLength);\n    Inc(SrcBuffer);\n  end;\n\n  SrcBuffer := PAnsiChar(Value);\n  SetLength(Result, DestLength);\n  DestBuffer := PAnsiChar(Result);\n  DestBuffer^ := '''';\n  Inc(DestBuffer);\n\n  LastState := 0;\n  for I := 1 to SrcLength do\n  begin\n    LastState := pg_CS_stat(LastState,integer(SrcBuffer^),\n      TZPgCharactersetType(ConSettings.ClientCodePage.ID));\n    if CharInSet(SrcBuffer^, [#0, '''']) or ((SrcBuffer^ = '\\') and (LastState = 0)) then\n    begin\n      DestBuffer[0] := '\\';\n      DestBuffer[1] := AnsiChar(Ord('0') + (Byte(SrcBuffer^) shr 6));\n      DestBuffer[2] := AnsiChar(Ord('0') + ((Byte(SrcBuffer^) shr 3) and $07));\n      DestBuffer[3] := AnsiChar(Ord('0') + (Byte(SrcBuffer^) and $07));\n      Inc(DestBuffer, 4);\n    end\n    else\n    begin\n      DestBuffer^ := SrcBuffer^;\n      Inc(DestBuffer);\n    end;\n    Inc(SrcBuffer);\n  end;\n  DestBuffer^ := '''';\nend;\n\n\n{**\n  add by Perger -> based on SourceForge:\n  [ 1520587 ] Fix for 1484704: bytea corrupted on post when not using utf8,\n  file: 1484704.patch\n\n  Converts a binary string into escape PostgreSQL format.\n  @param Value a binary stream.\n  @return a string in PostgreSQL binary string escape format.\n}\nfunction EncodeBinaryString(const Value: AnsiString): AnsiString;\nvar\n  I: Integer;\n  SrcLength, DestLength: Integer;\n  SrcBuffer, DestBuffer: PAnsiChar;\nbegin\n  SrcLength := Length(Value);\n  SrcBuffer := PAnsiChar(Value);\n  DestLength := 2;\n  for I := 1 to SrcLength do\n  begin\n    if (Byte(SrcBuffer^) < 32) or (Byte(SrcBuffer^) > 126)\n    or CharInSet(SrcBuffer^, ['''', '\\']) then\n      Inc(DestLength, 5)\n    else\n      Inc(DestLength);\n    Inc(SrcBuffer);\n  end;\n\n  SrcBuffer := PAnsiChar(Value);\n  SetLength(Result, DestLength);\n  DestBuffer := PAnsiChar(Result);\n  DestBuffer^ := '''';\n  Inc(DestBuffer);\n\n  for I := 1 to SrcLength do\n  begin\n    if (Byte(SrcBuffer^) < 32) or (Byte(SrcBuffer^) > 126)\n    or CharInSet(SrcBuffer^, ['''', '\\']) then\n    begin\n      DestBuffer[0] := '\\';\n      DestBuffer[1] := '\\';\n      DestBuffer[2] := AnsiChar(Ord('0') + (Byte(SrcBuffer^) shr 6));\n      DestBuffer[3] := AnsiChar(Ord('0') + ((Byte(SrcBuffer^) shr 3) and $07));\n      DestBuffer[4] := AnsiChar(Ord('0') + (Byte(SrcBuffer^) and $07));\n      Inc(DestBuffer, 5);\n    end\n    else\n    begin\n      DestBuffer^ := SrcBuffer^;\n      Inc(DestBuffer);\n    end;\n    Inc(SrcBuffer);\n  end;\n  DestBuffer^ := '''';\nend;\n\n{**\n  Converts an string from escape PostgreSQL format.\n  @param Value a string in PostgreSQL escape format.\n  @return a regular string.\n}\nfunction DecodeString(const Value: AnsiString): AnsiString;\nvar\n  SrcLength, DestLength: Integer;\n  SrcBuffer, DestBuffer: PAnsiChar;\nbegin\n  SrcLength := Length(Value);\n  SrcBuffer := PAnsiChar(Value);\n  SetLength(Result, SrcLength);\n  DestLength := 0;\n  DestBuffer := PAnsiChar(Result);\n\n  while SrcLength > 0 do\n  begin\n    if SrcBuffer^ = '\\' then\n    begin\n      Inc(SrcBuffer);\n      if CharInSet(SrcBuffer^, ['\\', '''']) then\n      begin\n        DestBuffer^ := SrcBuffer^;\n        Inc(SrcBuffer);\n        Dec(SrcLength, 2);\n      end\n      else\n      begin\n        DestBuffer^ := AnsiChar(((Byte(SrcBuffer[0]) - Ord('0')) shl 6)\n          or ((Byte(SrcBuffer[1]) - Ord('0')) shl 3)\n          or ((Byte(SrcBuffer[2]) - Ord('0'))));\n        Inc(SrcBuffer, 3);\n        Dec(SrcLength, 4);\n      end;\n    end\n    else\n    begin\n      DestBuffer^ := SrcBuffer^;\n      Inc(SrcBuffer);\n      Dec(SrcLength);\n    end;\n    Inc(DestBuffer);\n    Inc(DestLength);\n  end;\n  SetLength(Result, DestLength);\nend;\n\n{**\n  Checks for possible sql errors.\n  @param Connection a reference to database connection to execute Rollback.\n  @param PlainDriver a PostgreSQL plain driver.\n  @param Handle a PostgreSQL connection reference.\n  @param LogCategory a logging category.\n  @param LogMessage a logging message.\n  //FirmOS 22.02.06\n  @param ResultHandle the Handle to the Result\n}\nfunction CheckPostgreSQLError(Connection: IZConnection;\n  PlainDriver: IZPostgreSQLPlainDriver;\n  Handle: PZPostgreSQLConnect; LogCategory: TZLoggingCategory;\n  const LogMessage: string;\n  ResultHandle: PZPostgreSQLResult): String;\nvar\n   ErrorMessage: string;\n//FirmOS\n   ConnectionLost: boolean;\n\n   function GetMessage(AMessage: PAnsiChar): String;\n   begin\n    if Assigned(Connection) then\n      Result := Trim(PlainDriver.ZDbcString(AMessage, Connection.GetConSettings))\n    else\n      {$IFDEF UNICODE}\n      Result := Trim(UTF8ToString(AMessage));\n      {$ELSE}\n        {$IFDEF DELPHI}\n        Result := Trim(Utf8ToAnsi(AMessage));\n        {$ELSE}\n        Result := Trim(AMessage);\n        {$ENDIF}\n     {$ENDIF}\n   end;\nbegin\n  if Assigned(Handle) then\n    ErrorMessage := GetMessage(PlainDriver.GetErrorMessage(Handle))\n  else\n    ErrorMessage := '';\n\n  if ErrorMessage <> '' then\n  begin\n    if Assigned(ResultHandle) then\n{     StatusCode := Trim(StrPas(PlainDriver.GetResultErrorField(ResultHandle,PG_DIAG_SEVERITY)));\n     StatusCode := Trim(StrPas(PlainDriver.GetResultErrorField(ResultHandle,PG_DIAG_MESSAGE_PRIMARY)));\n     StatusCode := Trim(StrPas(PlainDriver.GetResultErrorField(ResultHandle,PG_DIAG_MESSAGE_DETAIL)));\n     StatusCode := Trim(StrPas(PlainDriver.GetResultErrorField(ResultHandle,PG_DIAG_MESSAGE_HINT)));\n     StatusCode := Trim(StrPas(PlainDriver.GetResultErrorField(ResultHandle,PG_DIAG_STATEMENT_POSITION)));\n     StatusCode := Trim(StrPas(PlainDriver.GetResultErrorField(ResultHandle,PG_DIAG_INTERNAL_POSITION)));\n     StatusCode := Trim(StrPas(PlainDriver.GetResultErrorField(ResultHandle,PG_DIAG_INTERNAL_QUERY)));\n     StatusCode := Trim(StrPas(PlainDriver.GetResultErrorField(ResultHandle,PG_DIAG_CONTEXT)));\n     StatusCode := Trim(StrPas(PlainDriver.GetResultErrorField(ResultHandle,PG_DIAG_SOURCE_FILE)));\n     StatusCode := Trim(StrPas(PlainDriver.GetResultErrorField(ResultHandle,PG_DIAG_SOURCE_LINE)));\n     StatusCode := Trim(StrPas(PlainDriver.GetResultErrorField(ResultHandle,PG_DIAG_SOURCE_FUNCTION)));\n}\n     Result := GetMessage(PlainDriver.GetResultErrorField(ResultHandle,PG_DIAG_SQLSTATE))\n    else\n      Result := '';\n  end;\n\n\n\n  if ErrorMessage <> '' then\n  begin\n    ConnectionLost := (PlainDriver.GetStatus(Handle) = CONNECTION_BAD);\n\n    if Assigned(Connection) then begin\n      if Connection.GetAutoCommit and not ConnectionLost then Connection.Rollback;\n    DriverManager.LogError(LogCategory, PlainDriver.GetProtocol, LogMessage,\n      0, ErrorMessage);\n    end else begin\n      DriverManager.LogError(LogCategory, 'some PostgreSQL protocol', LogMessage,\n        0, ErrorMessage);\n    end;\n\n    if ResultHandle <> nil then PlainDriver.Clear(ResultHandle);\n\n    if not ( ConnectionLost and ( LogCategory = lcUnprepStmt ) ) then\n      if not (Result = '42P18') then\n        raise EZSQLException.CreateWithStatus(Result,Format(SSQLError1, [ErrorMessage]));\n  end;\nend;\n\n{**\n   Resolve problem with minor version in PostgreSql bettas\n   @param Value a minor version string like \"4betta2\"\n   @return a miror version number\n}\nfunction GetMinorVersion(const Value: string): Word;\nvar\n  I: integer;\n  Temp: string;\nbegin\n  Temp := '';\n  for I := 1 to Length(Value) do\n    if CharInSet(Value[I], ['0'..'9']) then\n      Temp := Temp + Value[I]\n    else\n      Break;\n  Result := StrToIntDef(Temp, 0);\nend;\n\n{**\n  Prepares an SQL parameter for the query.\n  @param ParameterIndex the first parameter is 1, the second is 2, ...\n  @return a string representation of the parameter.\n}\nfunction PGPrepareAnsiSQLParam(Value: TZVariant; Connection: IZPostgreSQLConnection;\n  PlainDriver: IZPostgreSQLPlainDriver; const ChunkSize: Cardinal;\n  const InParamType: TZSQLType; const oidasblob, DateTimePrefix, QuotedNumbers: Boolean;\n  ConSettings: PZConSettings): RawByteString;\nvar\n  TempBlob: IZBlob;\n  TempStream: TStream;\n  WriteTempBlob: IZPostgreSQLBlob;\nbegin\n  if DefVarManager.IsNull(Value)  then\n    Result := 'NULL'\n  else\n  begin\n    case InParamType of\n      stBoolean:\n        if SoftVarManager.GetAsBoolean(Value) then\n          Result := 'TRUE'\n        else\n          Result := 'FALSE';\n      stByte, stShort, stInteger, stLong, stBigDecimal, stFloat, stDouble:\n        begin\n          Result := RawByteString(SoftVarManager.GetAsString(Value));\n          if QuotedNumbers then Result := #39+Result+#39;\n        end;\n      stBytes:\n        Result := Connection.EncodeBinary(SoftVarManager.GetAsBytes(Value));\n      stString:\n        if PlainDriver.SupportsStringEscaping(Connection.ClientSettingsChanged) then\n          Result :=  PlainDriver.EscapeString(Connection.GetConnectionHandle,\n            PlainDriver.ZPlainString(SoftVarManager.GetAsString(Value), ConSettings), ConSettings, True)\n        else\n          Result := ZDbcPostgreSqlUtils.PGEscapeString(Connection.GetConnectionHandle,\n            PlainDriver.ZPlainString(SoftVarManager.GetAsString(Value), ConSettings), ConSettings, True);\n      stUnicodeString:\n        if PlainDriver.SupportsStringEscaping(Connection.ClientSettingsChanged) then\n          Result := PlainDriver.EscapeString(Connection.GetConnectionHandle,\n            PlainDriver.ZPlainString(SoftVarManager.GetAsUnicodeString(Value), ConSettings), ConSettings, True)\n        else\n          Result := ZDbcPostgreSqlUtils.PGEscapeString(Connection.GetConnectionHandle,\n            PlainDriver.ZPlainString(SoftVarManager.GetAsUnicodeString(Value), ConSettings), ConSettings, True);\n      stDate:\n        begin\n          Result := RawByteString(#39+FormatDateTime('yyyy-mm-dd',\n            SoftVarManager.GetAsDateTime(Value))+#39);\n          if DateTimePrefix then Result := Result + '::date';\n        end;\n      stTime:\n        begin\n          Result := RawByteString(#39+FormatDateTime('hh\":\"mm\":\"ss\".\"zzz',\n            SoftVarManager.GetAsDateTime(Value))+#39);\n          if DateTimePrefix then Result := Result + '::time';\n        end;\n      stTimestamp:\n        begin\n          Result := RawByteString(#39+FormatDateTime('yyyy-mm-dd hh\":\"mm\":\"ss\".\"zzz',\n              SoftVarManager.GetAsDateTime(Value))+#39);\n        if DateTimePrefix then Result := Result + '::timestamp';\n        end;\n      stAsciiStream, stUnicodeStream, stBinaryStream:\n        begin\n          TempBlob := DefVarManager.GetAsInterface(Value) as IZBlob;\n          if not TempBlob.IsEmpty then\n          begin\n            case InParamType of\n              stBinaryStream:\n                if (Connection.IsOidAsBlob) or oidasblob then\n                begin\n                  TempStream := TempBlob.GetStream;\n                  try\n                    WriteTempBlob := TZPostgreSQLBlob.Create(PlainDriver, nil, 0,\n                      Connection.GetConnectionHandle, 0, ChunkSize);\n                    WriteTempBlob.SetStream(TempStream);\n                    WriteTempBlob.WriteBlob;\n                    Result := RawByteString(IntToStr(WriteTempBlob.GetBlobOid));\n                  finally\n                    WriteTempBlob := nil;\n                    TempStream.Free;\n                  end;\n                end\n                else\n                  Result := Connection.EncodeBinary(TempBlob.GetString);\n              stAsciiStream, stUnicodeStream:\n                if PlainDriver.SupportsStringEscaping(Connection.ClientSettingsChanged) then\n                  Result := PlainDriver.EscapeString(\n                    Connection.GetConnectionHandle,\n                    GetValidatedAnsiStringFromBuffer(TempBlob.GetBuffer,\n                      TempBlob.Length, TempBlob.WasDecoded, ConSettings),\n                      ConSettings, True)\n                else\n                  Result := ZDbcPostgreSqlUtils.PGEscapeString(\n                    Connection.GetConnectionHandle,\n                    GetValidatedAnsiStringFromBuffer(TempBlob.GetBuffer,\n                      TempBlob.Length, TempBlob.WasDecoded, ConSettings),\n                      ConSettings, True);\n            end; {case..}\n          end\n          else\n            Result := 'NULL';\n          TempBlob := nil;\n        end; {if not TempBlob.IsEmpty then}\n    end;\n  end;\nend;\n\n\nend.\n"
  },
  {
    "path": "lib/zeosdbo/src/dbc/ZDbcResultSet.pas",
    "content": "{*********************************************************}\n{                                                         }\n{                 Zeos Database Objects                   }\n{         Abstract Database Connectivity Classes          }\n{                                                         }\n{        Originally written by Sergey Seroukhov           }\n{                                                         }\n{*********************************************************}\n\n{@********************************************************}\n{    Copyright (c) 1999-2012 Zeos Development Group       }\n{                                                         }\n{ License Agreement:                                      }\n{                                                         }\n{ This library is distributed in the hope that it will be }\n{ useful, but WITHOUT ANY WARRANTY; without even the      }\n{ implied warranty of MERCHANTABILITY or FITNESS FOR      }\n{ A PARTICULAR PURPOSE.  See the GNU Lesser General       }\n{ Public License for more details.                        }\n{                                                         }\n{ The source code of the ZEOS Libraries and packages are  }\n{ distributed under the Library GNU General Public        }\n{ License (see the file COPYING / COPYING.ZEOS)           }\n{ with the following  modification:                       }\n{ As a special exception, the copyright holders of this   }\n{ library give you permission to link this library with   }\n{ independent modules to produce an executable,           }\n{ regardless of the license terms of these independent    }\n{ modules, and to copy and distribute the resulting       }\n{ executable under terms of your choice, provided that    }\n{ you also meet, for each linked independent module,      }\n{ the terms and conditions of the license of that module. }\n{ An independent module is a module which is not derived  }\n{ from or based on this library. If you modify this       }\n{ library, you may extend this exception to your version  }\n{ of the library, but you are not obligated to do so.     }\n{ If you do not wish to do so, delete this exception      }\n{ statement from your version.                            }\n{                                                         }\n{                                                         }\n{ The project web site is located on:                     }\n{   http://zeos.firmos.at  (FORUM)                        }\n{   http://sourceforge.net/p/zeoslib/tickets/ (BUGTRACKER)}\n{   svn://svn.code.sf.net/p/zeoslib/code-0/trunk (SVN)    }\n{                                                         }\n{   http://www.sourceforge.net/projects/zeoslib.          }\n{                                                         }\n{                                                         }\n{                                 Zeos Development Group. }\n{********************************************************@}\n\nunit ZDbcResultSet;\n\ninterface\n\n{$I ZDbc.inc}\n\nuses\n{$IFDEF MSWINDOWS}\n  Windows,\n{$ENDIF}\n{$IFDEF FPC}\n  {$IFDEF WIN32}\n    Comobj,\n  {$ENDIF}\n{$ENDIF}\n  Types, Classes, {$IFDEF MSEgui}mclasses,{$ENDIF} SysUtils, Contnrs,\n  ZDbcIntfs, ZClasses, ZCollections, ZSysUtils, ZCompatibility, ZVariant;\n\n{$IFDEF FPC}\n  {$HINTS OFF} //suppress not used params\n{$ENDIF}\ntype\n  {** Implements Abstract ResultSet. }\n  TZAbstractResultSet = class(TZCodePagedObject, IZResultSet)\n  private\n    FTemp: String;\n    FRowNo: Integer;\n    FLastRowNo: Integer;\n    FMaxRows: Integer;\n    FClosed: Boolean;\n    FFetchDirection: TZFetchDirection;\n    FFetchSize: Integer;\n    FResultSetType: TZResultSetType;\n    FResultSetConcurrency: TZResultSetConcurrency;\n    FPostUpdates: TZPostUpdatesMode;\n    FLocateUpdates: TZLocateUpdatesMode;\n    FColumnsInfo: TObjectList;\n    FMetadata: TContainedObject;\n    FStatement: IZStatement;\n  protected\n    LastWasNull: Boolean;\n\n    function InternalGetString(ColumnIndex: Integer): RawByteString; virtual;\n\n    procedure RaiseUnsupportedException;\n    procedure RaiseForwardOnlyException;\n    procedure RaiseReadOnlyException;\n    procedure CheckClosed;\n    procedure CheckColumnConvertion(ColumnIndex: Integer; ResultType: TZSQLType);\n    procedure CheckBlobColumn(ColumnIndex: Integer);\n    procedure Open; virtual;\n    function GetColumnIndex(const ColumnName: string): Integer;\n    property RowNo: Integer read FRowNo write FRowNo;\n    property LastRowNo: Integer read FLastRowNo write FLastRowNo;\n    property MaxRows: Integer read FMaxRows write FMaxRows;\n    property Closed: Boolean read FClosed write FClosed;\n    property FetchDirection: TZFetchDirection\n      read FFetchDirection write FFetchDirection;\n    property FetchSize: Integer read FFetchSize write FFetchSize;\n    property ResultSetType: TZResultSetType\n      read FResultSetType write FResultSetType;\n    property ResultSetConcurrency: TZResultSetConcurrency\n      read FResultSetConcurrency write FResultSetConcurrency;\n    property Statement: IZStatement read FStatement;\n    property Metadata: TContainedObject read FMetadata write FMetadata;\n\n  public\n    constructor Create(Statement: IZStatement; SQL: string;\n      Metadata: TContainedObject; ConSettings: PZConSettings);\n    destructor Destroy; override;\n\n    procedure SetType(Value: TZResultSetType);\n    procedure SetConcurrency(Value: TZResultSetConcurrency);\n\n    function Next: Boolean; virtual;\n    procedure Close; virtual;\n    function WasNull: Boolean; virtual;\n\n    //======================================================================\n    // Methods for accessing results by column index\n    //======================================================================\n\n    function IsNull(ColumnIndex: Integer): Boolean; virtual;\n    function GetPChar(ColumnIndex: Integer): PChar; virtual;\n    function GetString(ColumnIndex: Integer): String; virtual;\n    function GetBinaryString(ColumnIndex: Integer): RawByteString;\n    function GetUnicodeString(ColumnIndex: Integer): WideString; virtual;\n    function GetBoolean(ColumnIndex: Integer): Boolean; virtual;\n    function GetByte(ColumnIndex: Integer): Byte; virtual;\n    function GetShort(ColumnIndex: Integer): SmallInt; virtual;\n    function GetInt(ColumnIndex: Integer): Integer; virtual;\n    function GetLong(ColumnIndex: Integer): Int64; virtual;\n    function GetFloat(ColumnIndex: Integer): Single; virtual;\n    function GetDouble(ColumnIndex: Integer): Double; virtual;\n    function GetBigDecimal(ColumnIndex: Integer): Extended; virtual;\n    function GetBytes(ColumnIndex: Integer): TByteDynArray; virtual;\n    function GetDate(ColumnIndex: Integer): TDateTime; virtual;\n    function GetTime(ColumnIndex: Integer): TDateTime; virtual;\n    function GetTimestamp(ColumnIndex: Integer): TDateTime; virtual;\n    function GetAsciiStream(ColumnIndex: Integer): TStream; virtual;\n    function GetUnicodeStream(ColumnIndex: Integer): TStream; virtual;\n    function GetBinaryStream(ColumnIndex: Integer): TStream; virtual;\n    function GetBlob(ColumnIndex: Integer): IZBlob; virtual;\n    function GetDataSet(ColumnIndex: Integer): IZDataSet; virtual;\n    function GetValue(ColumnIndex: Integer): TZVariant; virtual;\n    function GetDefaultExpression(ColumnIndex: Integer): String; virtual;\n\n    //======================================================================\n    // Methods for accessing results by column name\n    //======================================================================\n\n    function IsNullByName(const ColumnName: string): Boolean; virtual;\n    function GetPCharByName(const ColumnName: string): PChar; virtual;\n    function GetStringByName(const ColumnName: string): String; virtual;\n    function GetBinaryStringByName(const ColumnName: string): RawByteString;\n    function GetUnicodeStringByName(const ColumnName: string): WideString; virtual;\n    function GetBooleanByName(const ColumnName: string): Boolean; virtual;\n    function GetByteByName(const ColumnName: string): Byte; virtual;\n    function GetShortByName(const ColumnName: string): SmallInt; virtual;\n    function GetIntByName(const ColumnName: string): Integer; virtual;\n    function GetLongByName(const ColumnName: string): Int64; virtual;\n    function GetFloatByName(const ColumnName: string): Single; virtual;\n    function GetDoubleByName(const ColumnName: string): Double; virtual;\n    function GetBigDecimalByName(const ColumnName: string): Extended; virtual;\n    function GetBytesByName(const ColumnName: string): TByteDynArray; virtual;\n    function GetDateByName(const ColumnName: string): TDateTime; virtual;\n    function GetTimeByName(const ColumnName: string): TDateTime; virtual;\n    function GetTimestampByName(const ColumnName: string): TDateTime; virtual;\n    function GetAsciiStreamByName(const ColumnName: string): TStream; virtual;\n    function GetUnicodeStreamByName(const ColumnName: string): TStream; virtual;\n    function GetBinaryStreamByName(const ColumnName: string): TStream; virtual;\n    function GetBlobByName(const ColumnName: string): IZBlob; virtual;\n    function GetDataSetByName(const ColumnName: String): IZDataSet; virtual;\n    function GetValueByName(const ColumnName: string): TZVariant; virtual;\n\n    //=====================================================================\n    // Advanced features:\n    //=====================================================================\n\n    function GetWarnings: EZSQLWarning; virtual;\n    procedure ClearWarnings; virtual;\n\n    function GetCursorName: AnsiString; virtual;\n    function GetMetaData: IZResultSetMetaData; virtual;\n    function FindColumn(const ColumnName: string): Integer; virtual;\n\n    //---------------------------------------------------------------------\n    // Traversal/Positioning\n    //---------------------------------------------------------------------\n\n    function IsBeforeFirst: Boolean; virtual;\n    function IsAfterLast: Boolean; virtual;\n    function IsFirst: Boolean; virtual;\n    function IsLast: Boolean; virtual;\n    procedure BeforeFirst; virtual;\n    procedure AfterLast; virtual;\n    function First: Boolean; virtual;\n    function Last: Boolean; virtual;\n    function GetRow: Integer; virtual;\n    function MoveAbsolute(Row: Integer): Boolean; virtual;\n    function MoveRelative(Rows: Integer): Boolean; virtual;\n    function Previous: Boolean; virtual;\n\n    //---------------------------------------------------------------------\n    // Properties\n    //---------------------------------------------------------------------\n\n    procedure SetFetchDirection(Direction: TZFetchDirection); virtual;\n    function GetFetchDirection: TZFetchDirection; virtual;\n\n    procedure SetFetchSize(Rows: Integer); virtual;\n    function GetFetchSize: Integer; virtual;\n\n    function GetType: TZResultSetType; virtual;\n    function GetConcurrency: TZResultSetConcurrency; virtual;\n\n    function GetPostUpdates: TZPostUpdatesMode;\n    function GetLocateUpdates: TZLocateUpdatesMode;\n\n    //---------------------------------------------------------------------\n    // Updates\n    //---------------------------------------------------------------------\n\n    function RowUpdated: Boolean; virtual;\n    function RowInserted: Boolean; virtual;\n    function RowDeleted: Boolean; virtual;\n\n    procedure UpdateNull(ColumnIndex: Integer); virtual;\n    procedure UpdateBoolean(ColumnIndex: Integer; Value: Boolean); virtual;\n    procedure UpdateByte(ColumnIndex: Integer; Value: ShortInt); virtual;\n    procedure UpdateShort(ColumnIndex: Integer; Value: SmallInt); virtual;\n    procedure UpdateInt(ColumnIndex: Integer; Value: Integer); virtual;\n    procedure UpdateLong(ColumnIndex: Integer; Value: Int64); virtual;\n    procedure UpdateFloat(ColumnIndex: Integer; Value: Single); virtual;\n    procedure UpdateDouble(ColumnIndex: Integer; Value: Double); virtual;\n    procedure UpdateBigDecimal(ColumnIndex: Integer; Value: Extended); virtual;\n    procedure UpdatePChar(ColumnIndex: Integer; Value: PChar); virtual;\n    procedure UpdateString(ColumnIndex: Integer; const Value: String); virtual;\n    procedure UpdateBinaryString(ColumnIndex: Integer; const Value: RawByteString);\n    procedure UpdateUnicodeString(ColumnIndex: Integer; const Value: WideString); virtual;\n    procedure UpdateBytes(ColumnIndex: Integer; const Value: TByteDynArray); virtual;\n    procedure UpdateDate(ColumnIndex: Integer; Value: TDateTime); virtual;\n    procedure UpdateTime(ColumnIndex: Integer; Value: TDateTime); virtual;\n    procedure UpdateTimestamp(ColumnIndex: Integer; Value: TDateTime); virtual;\n    procedure UpdateAsciiStream(ColumnIndex: Integer; Value: TStream); virtual;\n    procedure UpdateUnicodeStream(ColumnIndex: Integer; Value: TStream); virtual;\n    procedure UpdateBinaryStream(ColumnIndex: Integer; Value: TStream); virtual;\n    procedure UpdateDataSet(ColumnIndex: Integer; Value: IZDataSet); virtual;\n    procedure UpdateValue(ColumnIndex: Integer; const Value: TZVariant); virtual;\n    procedure UpdateDefaultExpression(ColumnIndex: Integer; const Value: string); virtual;\n\n    //======================================================================\n    // Methods for accessing results by column name\n    //======================================================================\n\n    procedure UpdateNullByName(const ColumnName: string); virtual;\n    procedure UpdateBooleanByName(const ColumnName: string; Value: Boolean); virtual;\n    procedure UpdateByteByName(const ColumnName: string; Value: ShortInt); virtual;\n    procedure UpdateShortByName(const ColumnName: string; Value: SmallInt); virtual;\n    procedure UpdateIntByName(const ColumnName: string; Value: Integer); virtual;\n    procedure UpdateLongByName(const ColumnName: string; Value: Int64); virtual;\n    procedure UpdateFloatByName(const ColumnName: string; Value: Single); virtual;\n    procedure UpdateDoubleByName(const ColumnName: string; Value: Double); virtual;\n    procedure UpdateBigDecimalByName(const ColumnName: string; Value: Extended); virtual;\n    procedure UpdatePCharByName(const ColumnName: string; Value: PChar); virtual;\n    procedure UpdateStringByName(const ColumnName: string; const Value: String); virtual;\n    procedure UpdateBinaryStringByName(const ColumnName: string; const Value: RawByteString);\n    procedure UpdateUnicodeStringByName(const ColumnName: string; const Value: WideString); virtual;\n    procedure UpdateBytesByName(const ColumnName: string; const Value: TByteDynArray); virtual;\n    procedure UpdateDateByName(const ColumnName: string; Value: TDateTime); virtual;\n    procedure UpdateTimeByName(const ColumnName: string; Value: TDateTime); virtual;\n    procedure UpdateTimestampByName(const ColumnName: string; Value: TDateTime); virtual;\n    procedure UpdateAsciiStreamByName(const ColumnName: string; Value: TStream); virtual;\n    procedure UpdateUnicodeStreamByName(const ColumnName: string; Value: TStream); virtual;\n    procedure UpdateBinaryStreamByName(const ColumnName: string; Value: TStream); virtual;\n    procedure UpdateDataSetByName(const ColumnName: string; Value: IZDataSet); virtual;\n    procedure UpdateValueByName(const ColumnName: string; const Value: TZVariant); virtual;\n\n    procedure InsertRow; virtual;\n    procedure UpdateRow; virtual;\n    procedure DeleteRow; virtual;\n    procedure RefreshRow; virtual;\n    procedure CancelRowUpdates; virtual;\n    procedure MoveToInsertRow; virtual;\n    procedure MoveToCurrentRow; virtual;\n\n    function CompareRows(Row1, Row2: Integer; const ColumnIndices: TIntegerDynArray;\n      const ColumnDirs: TBooleanDynArray): Integer; virtual;\n\n    function GetStatement: IZStatement; virtual;\n\n    function GetConSettings: PZConsettings;\n    property ColumnsInfo: TObjectList read FColumnsInfo write FColumnsInfo;\n  end;\n\n  {** Implements external or internal blob wrapper object. }\n  TZAbstractBlob = class(TInterfacedObject, IZBlob)\n  private\n    FBlobData: Pointer;\n    FBlobSize: Integer;\n    FUpdated: Boolean;\n  protected\n    FConnection: IZConnection;\n    FDecoded: Boolean;\n    property BlobData: Pointer read FBlobData write FBlobData;\n    property BlobSize: Integer read FBlobSize write FBlobSize;\n    property Updated: Boolean read FUpdated write FUpdated;\n  public\n    constructor CreateWithStream(Stream: TStream; Connection: IZConnection = nil;\n      Decoded: Boolean = False);\n    constructor CreateWithData(Data: Pointer; Size: Integer;\n      Connection: IZConnection = nil; Decoded: Boolean = False);\n    destructor Destroy; override;\n\n    function WasDecoded: Boolean;\n    function Connection: IZConnection;\n    function IsEmpty: Boolean; virtual;\n    function IsUpdated: Boolean; virtual;\n    function Length: LongInt; virtual;\n\n    function GetString: RawByteString; virtual;\n    procedure SetString(const Value: RawByteString); virtual;\n    function GetUnicodeString: WideString; virtual;\n    procedure SetUnicodeString(const Value: WideString); virtual;\n    function GetBytes: TByteDynArray; virtual;\n    procedure SetBytes(const Value: TByteDynArray); virtual;\n    function GetUnicodeStream: TStream; virtual;\n    function GetStream: TStream; virtual;\n    procedure SetStream(Value: TStream; Decoded: Boolean = False); virtual;\n    function GetBuffer: Pointer;\n    procedure SetBuffer(Buffer: Pointer; Length: Integer);\n\n    procedure Clear; virtual;\n    function Clone: IZBlob; virtual;\n  end;\n\nimplementation\n\nuses ZMessages, ZDbcUtils, ZDbcResultSetMetadata, ZEncoding\n  {$IFDEF WITH_ANSISTRCOMP_DEPRECATED}, AnsiStrings{$ENDIF};\n\n{ TZAbstractResultSet }\n\n{**\n  Creates this object and assignes the main properties.\n  @param Statement an SQL statement object.\n  @param SQL an SQL query string.\n  @param Metadata a resultset metadata object.\n}\nconstructor TZAbstractResultSet.Create(Statement: IZStatement; SQL: string;\n  Metadata: TContainedObject; ConSettings: PZConSettings);\nvar\n  DatabaseMetadata: IZDatabaseMetadata;\nbegin\n  Self.ConSettings := ConSettings;\n  LastWasNull := True;\n  FRowNo := 0;\n  FLastRowNo := 0;\n  FClosed := True;\n\n  if Statement = nil then\n  begin\n    FResultSetType := rtForwardOnly;\n    FResultSetConcurrency := rcReadOnly;\n    FPostUpdates := poColumnsAll;\n    FLocateUpdates := loWhereAll;\n    FMaxRows := 0;\n  end\n  else\n  begin\n    FFetchDirection := Statement.GetFetchDirection;\n    FFetchSize := Statement.GetFetchSize;\n    FResultSetType := Statement.GetResultSetType;\n    FResultSetConcurrency := Statement.GetResultSetConcurrency;\n    FPostUpdates := Statement.GetPostUpdates;\n    FLocateUpdates := Statement.GetLocateUpdates;\n    FStatement := Statement;\n    FMaxRows := Statement.GetMaxRows;\n  end;\n\n  if Metadata = nil then\n  begin\n    if Statement <> nil then\n      DatabaseMetadata := GetStatement.GetConnection.GetMetadata\n    else\n      DatabaseMetadata := nil;\n    FMetadata := TZAbstractResultSetMetadata.Create(DatabaseMetadata, SQL, Self);\n   end\n   else\n    FMetadata := Metadata;\n\n  FColumnsInfo := TObjectList.Create(True); //Free the MemoryLeaks of TZColumnInfo\nend;\n\n{**\n  Destroys this object and cleanups the memory.\n}\ndestructor TZAbstractResultSet.Destroy;\nbegin\n  if not FClosed then\n      Close;\n\n  if FMetadata <> nil then\n    FMetadata.Free;\n  FMetadata := nil;\n  FStatement := nil;\n\n  FColumnsInfo.Free;\n  inherited Destroy;\nend;\n\nfunction TZAbstractResultSet.InternalGetString(ColumnIndex: Integer): RawByteString;\nbegin\n{$IFNDEF DISABLE_CHECKING}\n  CheckColumnConvertion(ColumnIndex, stString);\n{$ENDIF}\n  Result := '';\nend;\n\n{**\n  Raises unsupported operation exception.\n}\nprocedure TZAbstractResultSet.RaiseUnsupportedException;\nbegin\n  raise EZSQLException.Create(SUnsupportedOperation);\nend;\n\n{**\n  Raises operation is not allowed in FORWARD ONLY mode exception.\n}\nprocedure TZAbstractResultSet.RaiseForwardOnlyException;\nbegin\n  raise EZSQLException.Create(SOperationIsNotAllowed1);\nend;\n\n{**\n  Raises operation is not allowed in READ ONLY mode exception.\n}\nprocedure TZAbstractResultSet.RaiseReadOnlyException;\nbegin\n  raise EZSQLException.Create(SOperationIsNotAllowed2);\nend;\n\n{**\n  Checks if result set is open and operation is allowed.\n}\nprocedure TZAbstractResultSet.CheckClosed;\nbegin\n  if FClosed then\n    raise EZSQLException.Create(SOperationIsNotAllowed4);\nend;\n\n{**\n  Checks is the column convertion from one type to another type allowed.\n  @param ColumnIndex an index of column.\n  @param ResultType a requested data type.\n}\nprocedure TZAbstractResultSet.CheckColumnConvertion(ColumnIndex: Integer;\n  ResultType: TZSQLType);\nvar\n  InitialType: TZSQLType;\n  Metadata: TZAbstractResultSetMetadata;\nbegin\n  CheckClosed;\n  Metadata := TZAbstractResultSetMetadata(FMetadata);\n  if (Metadata = nil) or (ColumnIndex <= 0)\n    or (ColumnIndex > Metadata.GetColumnCount) then\n  begin\n    raise EZSQLException.Create(\n      Format(SColumnIsNotAccessable, [ColumnIndex]));\n  end;\n\n  InitialType := Metadata.GetColumnType(ColumnIndex);\n  if not CheckConvertion(InitialType, ResultType) then\n  begin\n      raise EZSQLException.Create(Format(SConvertionIsNotPossible, [ColumnIndex,\n         DefineColumnTypeName(InitialType), DefineColumnTypeName(ResultType)]));\n  end;\nend;\n\n{**\n  Checks for blob expected column.\n  @param ColumnIndex an index of column.\n}\nprocedure TZAbstractResultSet.CheckBlobColumn(ColumnIndex: Integer);\nvar\n  InitialType: TZSQLType;\n  Metadata: TZAbstractResultSetMetadata;\nbegin\n  CheckClosed;\n  Metadata := TZAbstractResultSetMetadata(FMetadata);\n  if (Metadata = nil) or (ColumnIndex <= 0)\n    or (ColumnIndex > Metadata.GetColumnCount) then\n  begin\n    raise EZSQLException.Create(\n      Format(SColumnIsNotAccessable, [ColumnIndex]));\n  end;\n\n  InitialType := Metadata.GetColumnType(ColumnIndex);\n  if not (InitialType in [stAsciiStream, stBinaryStream, stUnicodeStream]) then\n  begin\n    raise EZSQLException.Create(\n      Format(SCanNotAccessBlobRecord,\n      [ColumnIndex, DefineColumnTypeName(InitialType)]));\n  end;\nend;\n\n{**\n  Set the concurrency mode of this <code>ResultSet</code> object.\n  The concurrency used is determined by the\n  <code>Statement</code> object that created the result set.\n\n  @param the concurrency type, either <code>CONCUR_READ_ONLY</code>\n    or <code>CONCUR_UPDATABLE</code>\n}\nprocedure TZAbstractResultSet.SetConcurrency(Value: TZResultSetConcurrency);\nbegin\n  ResultSetConcurrency := Value;\nend;\n\n{**\n  Set the type of this <code>ResultSet</code> object.\n  The type is determined by the <code>Statement</code> object\n  that created the result set.\n\n  @param <code>TYPE_FORWARD_ONLY</code>,\n    <code>TYPE_SCROLL_INSENSITIVE</code>,\n    or <code>TYPE_SCROLL_SENSITIVE</code>\n}\nprocedure TZAbstractResultSet.SetType(Value: TZResultSetType);\nbegin\n  ResultSetType := Value;\nend;\n\n{**\n  Opens this recordset.\n}\nprocedure TZAbstractResultSet.Open;\nbegin\n  FClosed := False;\nend;\n\n{**\n  Releases this <code>ResultSet</code> object's database and\n  JDBC resources immediately instead of waiting for\n  this to happen when it is automatically closed.\n\n  <P><B>Note:</B> A <code>ResultSet</code> object\n  is automatically closed by the\n  <code>Statement</code> object that generated it when\n  that <code>Statement</code> object is closed,\n  re-executed, or is used to retrieve the next result from a\n  sequence of multiple results. A <code>ResultSet</code> object\n  is also automatically closed when it is garbage collected.\n}\nprocedure TZAbstractResultSet.Close;\nvar\n   I: integer;\n   FColumnInfo: TZColumnInfo;\nbegin\n  LastWasNull := True;\n  FRowNo := 0;\n  FLastRowNo := 0;\n  FClosed := True;\n  for I := FColumnsInfo.Count - 1 downto 0 do\n  begin\n    FColumnInfo:=TZColumnInfo(FColumnsInfo.Extract(FColumnsInfo.Items[I]));\n    FColumnInfo.Free;\n  end;\n  FColumnsInfo.Clear;\n  FStatement := nil;\nend;\n\n{**\n  Reports whether\n  the last column read had a value of SQL <code>NULL</code>.\n  Note that you must first call one of the <code>getXXX</code> methods\n  on a column to try to read its value and then call\n  the method <code>wasNull</code> to see if the value read was\n  SQL <code>NULL</code>.\n\n  @return <code>true</code> if the last column value read was SQL\n    <code>NULL</code> and <code>false</code> otherwise\n}\nfunction TZAbstractResultSet.WasNull: Boolean;\nbegin\n  Result := LastWasNull;\nend;\n\n//======================================================================\n// Methods for accessing results by column index\n//======================================================================\n\n{**\n  Indicates if the value of the designated column in the current row\n  of this <code>ResultSet</code> object is Null.\n\n  @param columnIndex the first column is 1, the second is 2, ...\n  @return if the value is SQL <code>NULL</code>, the\n    value returned is <code>true</code>. <code>false</code> otherwise.\n}\nfunction TZAbstractResultSet.IsNull(ColumnIndex: Integer): Boolean;\nbegin\n  Result := True;\nend;\n\n{**\n  Gets the value of the designated column in the current row\n  of this <code>ResultSet</code> object as\n  a <code>PAnsiChar</code> in the Delphi programming language.\n\n  @param columnIndex the first column is 1, the second is 2, ...\n  @return the column value; if the value is SQL <code>NULL</code>, the\n    value returned is <code>null</code>\n}\n\nfunction TZAbstractResultSet.GetPChar(ColumnIndex: Integer): PChar;\nbegin\n  FTemp := GetString(ColumnIndex);\n  Result := PChar(FTemp);\nend;\n\n{**\n  Gets the value of the designated column in the current row\n  of this <code>ResultSet</code> object as\n  a <code>String</code> in the Java programming language.\n\n  @param columnIndex the first column is 1, the second is 2, ...\n  @return the column value; if the value is SQL <code>NULL</code>, the\n    value returned is <code>null</code>\n}\nfunction TZAbstractResultSet.GetString(ColumnIndex: Integer): String;\nbegin\n  Result := ZDbcString(InternalGetString(ColumnIndex));\nend;\n\n{**\n  Gets the value of the designated column in the current row\n  of this <code>ResultSet</code> object as\n  a <code>String</code> in the Java programming language.\n\n  @param columnIndex the first column is 1, the second is 2, ...\n  @return the column value; if the value is SQL <code>NULL</code>, the\n    value returned is <code>null</code>\n}\nfunction TZAbstractResultSet.GetBinaryString(ColumnIndex: Integer): RawByteString;\nbegin\n  Result := InternalGetString(ColumnIndex);\nend;\n\n{**\n  Gets the value of the designated column in the current row\n  of this <code>ResultSet</code> object as\n  a <code>WideString</code> in the Delphi programming language.\n\n  @param columnIndex the first column is 1, the second is 2, ...\n  @return the column value; if the value is SQL <code>NULL</code>, the\n    value returned is <code>null</code>\n}\nfunction TZAbstractResultSet.GetUnicodeString(ColumnIndex: Integer): WideString;\nbegin\n{$IFNDEF DISABLE_CHECKING}\n  CheckColumnConvertion(ColumnIndex, stUnicodeString);\n{$ENDIF}\n  Result := ZDbcUnicodeString(InternalGetString(ColumnIndex));\nend;\n\n{**\n  Gets the value of the designated column in the current row\n  of this <code>ResultSet</code> object as\n  a <code>boolean</code> in the Java programming language.\n\n  @param columnIndex the first column is 1, the second is 2, ...\n  @return the column value; if the value is SQL <code>NULL</code>, the\n    value returned is <code>false</code>\n}\nfunction TZAbstractResultSet.GetBoolean(ColumnIndex: Integer): Boolean;\nbegin\n{$IFNDEF DISABLE_CHECKING}\n  CheckColumnConvertion(ColumnIndex, stBoolean);\n{$ENDIF}\n  Result := False;\nend;\n\n{**\n  Gets the value of the designated column in the current row\n  of this <code>ResultSet</code> object as\n  a <code>byte</code> in the Java programming language.\n\n  @param columnIndex the first column is 1, the second is 2, ...\n  @return the column value; if the value is SQL <code>NULL</code>, the\n    value returned is <code>0</code>\n}\nfunction TZAbstractResultSet.GetByte(ColumnIndex: Integer): Byte;\nbegin\n{$IFNDEF DISABLE_CHECKING}\n  CheckColumnConvertion(ColumnIndex, stByte);\n{$ENDIF}\n  Result := 0;\nend;\n\n{**\n  Gets the value of the designated column in the current row\n  of this <code>ResultSet</code> object as\n  a <code>short</code> in the Java programming language.\n\n  @param columnIndex the first column is 1, the second is 2, ...\n  @return the column value; if the value is SQL <code>NULL</code>, the\n    value returned is <code>0</code>\n}\nfunction TZAbstractResultSet.GetShort(ColumnIndex: Integer): SmallInt;\nbegin\n{$IFNDEF DISABLE_CHECKING}\n  CheckColumnConvertion(ColumnIndex, stShort);\n{$ENDIF}\n  Result := 0;\nend;\n\n{**\n  Gets the value of the designated column in the current row\n  of this <code>ResultSet</code> object as\n  an <code>int</code> in the Java programming language.\n\n  @param columnIndex the first column is 1, the second is 2, ...\n  @return the column value; if the value is SQL <code>NULL</code>, the\n    value returned is <code>0</code>\n}\nfunction TZAbstractResultSet.GetInt(ColumnIndex: Integer): Integer;\nbegin\n{$IFNDEF DISABLE_CHECKING}\n  CheckColumnConvertion(ColumnIndex, stInteger);\n{$ENDIF}\n  Result := 0;\nend;\n\n{**\n  Gets the value of the designated column in the current row\n  of this <code>ResultSet</code> object as\n  a <code>long</code> in the Java programming language.\n\n  @param columnIndex the first column is 1, the second is 2, ...\n  @return the column value; if the value is SQL <code>NULL</code>, the\n    value returned is <code>0</code>\n}\nfunction TZAbstractResultSet.GetLong(ColumnIndex: Integer): Int64;\nbegin\n{$IFNDEF DISABLE_CHECKING}\n  CheckColumnConvertion(ColumnIndex, stLong);\n{$ENDIF}\n  Result := 0;\nend;\n\n{**\n  Gets the value of the designated column in the current row\n  of this <code>ResultSet</code> object as\n  a <code>float</code> in the Java programming language.\n\n  @param columnIndex the first column is 1, the second is 2, ...\n  @return the column value; if the value is SQL <code>NULL</code>, the\n    value returned is <code>0</code>\n}\nfunction TZAbstractResultSet.GetFloat(ColumnIndex: Integer): Single;\nbegin\n{$IFNDEF DISABLE_CHECKING}\n  CheckColumnConvertion(ColumnIndex, stFloat);\n{$ENDIF}\n  Result := 0;\nend;\n\n{**\n  Gets the value of the designated column in the current row\n  of this <code>ResultSet</code> object as\n  a <code>double</code> in the Java programming language.\n\n  @param columnIndex the first column is 1, the second is 2, ...\n  @return the column value; if the value is SQL <code>NULL</code>, the\n    value returned is <code>0</code>\n}\nfunction TZAbstractResultSet.GetDouble(ColumnIndex: Integer): Double;\nbegin\n{$IFNDEF DISABLE_CHECKING}\n  CheckColumnConvertion(ColumnIndex, stDouble);\n{$ENDIF}\n  Result := 0;\nend;\n\n{**\n  Gets the value of the designated column in the current row\n  of this <code>ResultSet</code> object as\n  a <code>java.sql.BigDecimal</code> in the Java programming language.\n\n  @param columnIndex the first column is 1, the second is 2, ...\n  @param scale the number of digits to the right of the decimal point\n  @return the column value; if the value is SQL <code>NULL</code>, the\n    value returned is <code>null</code>\n}\nfunction TZAbstractResultSet.GetBigDecimal(ColumnIndex: Integer): Extended;\nbegin\n{$IFNDEF DISABLE_CHECKING}\n  CheckColumnConvertion(ColumnIndex, stBigDecimal);\n{$ENDIF}\n  Result := 0;\nend;\n\n{**\n  Gets the value of the designated column in the current row\n  of this <code>ResultSet</code> object as\n  a <code>byte</code> array in the Java programming language.\n  The bytes represent the raw values returned by the driver.\n\n  @param columnIndex the first column is 1, the second is 2, ...\n  @return the column value; if the value is SQL <code>NULL</code>, the\n    value returned is <code>null</code>\n}\nfunction TZAbstractResultSet.GetBytes(ColumnIndex: Integer): TByteDynArray;\nbegin\n{$IFNDEF DISABLE_CHECKING}\n  CheckColumnConvertion(ColumnIndex, stBytes);\n{$ENDIF}\n  Result := nil;\nend;\n\n{**\n  Gets the value of the designated column in the current row\n  of this <code>ResultSet</code> object as\n  a <code>java.sql.Date</code> object in the Java programming language.\n\n  @param columnIndex the first column is 1, the second is 2, ...\n  @return the column value; if the value is SQL <code>NULL</code>, the\n    value returned is <code>null</code>\n}\nfunction TZAbstractResultSet.GetDate(ColumnIndex: Integer): TDateTime;\nbegin\n{$IFNDEF DISABLE_CHECKING}\n  CheckColumnConvertion(ColumnIndex, stDate);\n{$ENDIF}\n  Result := 0;\nend;\n\n{**\n  Gets the value of the designated column in the current row\n  of this <code>ResultSet</code> object as\n  a <code>java.sql.Time</code> object in the Java programming language.\n\n  @param columnIndex the first column is 1, the second is 2, ...\n  @return the column value; if the value is SQL <code>NULL</code>, the\n    value returned is <code>null</code>\n}\nfunction TZAbstractResultSet.GetTime(ColumnIndex: Integer): TDateTime;\nbegin\n{$IFNDEF DISABLE_CHECKING}\n  CheckColumnConvertion(ColumnIndex, stTime);\n{$ENDIF}\n  Result := 0;\nend;\n\n{**\n  Gets the value of the designated column in the current row\n  of this <code>ResultSet</code> object as\n  a <code>java.sql.Timestamp</code> object in the Java programming language.\n\n  @param columnIndex the first column is 1, the second is 2, ...\n  @return the column value; if the value is SQL <code>NULL</code>, the\n  value returned is <code>null</code>\n  @exception SQLException if a database access error occurs\n}\nfunction TZAbstractResultSet.GetTimestamp(ColumnIndex: Integer): TDateTime;\nbegin\n{$IFNDEF DISABLE_CHECKING}\n  CheckColumnConvertion(ColumnIndex, stTimestamp);\n{$ENDIF}\n  Result := 0;\nend;\n\n{**\n  Gets the value of the designated column in the current row\n  of this <code>ResultSet</code> object as\n  a stream of ASCII characters. The value can then be read in chunks from the\n  stream. This method is particularly\n  suitable for retrieving large <char>LONGVARCHAR</char> values.\n  The JDBC driver will\n  do any necessary conversion from the database format into ASCII.\n\n  <P><B>Note:</B> All the data in the returned stream must be\n  read prior to getting the value of any other column. The next\n  call to a <code>getXXX</code> method implicitly closes the stream.  Also, a\n  stream may return <code>0</code> when the method\n  <code>InputStream.available</code>\n  is called whether there is data available or not.\n\n  @param columnIndex the first column is 1, the second is 2, ...\n  @return a Java input stream that delivers the database column value\n    as a stream of one-byte ASCII characters; if the value is SQL\n    <code>NULL</code>, the value returned is <code>null</code>\n}\nfunction TZAbstractResultSet.GetAsciiStream(ColumnIndex: Integer): TStream;\nvar\n  Blob: IZBlob;\nbegin\n{$IFNDEF DISABLE_CHECKING}\n  CheckColumnConvertion(ColumnIndex, stAsciiStream);\n{$ENDIF}\n  Result := nil;\n  if not IsNull(ColumnIndex) then\n  begin\n    Blob := GetBlob(ColumnIndex);\n    if Blob <> nil then\n      if Self.GetMetaData.GetColumnType(ColumnIndex) = stUnicodeStream then\n        Result := TStringStream.Create(GetValidatedAnsiStringFromBuffer(Blob.GetBuffer,\n          Blob.Length, ConSettings, ConSettings.CTRL_CP))\n      else\n        Result := Blob.GetStream;\n  end;\n  LastWasNull := (Result = nil);\nend;\n\n{**\n  Gets the value of a column in the current row as a stream of\n  Gets the value of the designated column in the current row\n  of this <code>ResultSet</code> object as\n  as a stream of Unicode characters.\n  The value can then be read in chunks from the\n  stream. This method is particularly\n  suitable for retrieving large<code>LONGVARCHAR</code>values.  The JDBC driver will\n  do any necessary conversion from the database format into Unicode.\n  The byte format of the Unicode stream must be Java UTF-8,\n  as specified in the Java virtual machine specification.\n\n  <P><B>Note:</B> All the data in the returned stream must be\n  read prior to getting the value of any other column. The next\n  call to a <code>getXXX</code> method implicitly closes the stream.  Also, a\n  stream may return <code>0</code> when the method\n  <code>InputStream.available</code>\n  is called whether there is data available or not.\n\n  @param columnIndex the first column is 1, the second is 2, ...\n  @return a Java input stream that delivers the database column value\n    as a stream in Java UTF-8 byte format; if the value is SQL\n    <code>NULL</code>, the value returned is <code>null</code>\n}\nfunction TZAbstractResultSet.GetUnicodeStream(ColumnIndex: Integer): TStream;\nvar\n  Blob: IZBlob;\nbegin\n{$IFNDEF DISABLE_CHECKING}\n  CheckColumnConvertion(ColumnIndex, stUnicodeStream);\n{$ENDIF}\n  Result := nil;\n  if not IsNull(ColumnIndex) then\n  begin\n    Blob := GetBlob(ColumnIndex);\n    if Blob <> nil then\n      Result := Blob.GetUnicodeStream;\n  end;\n  LastWasNull := (Result = nil);\nend;\n\n{**\n  Gets the value of a column in the current row as a stream of\n  Gets the value of the designated column in the current row\n  of this <code>ResultSet</code> object as a binary stream of\n  uninterpreted bytes. The value can then be read in chunks from the\n  stream. This method is particularly\n  suitable for retrieving large <code>LONGVARBINARY</code> values.\n\n  <P><B>Note:</B> All the data in the returned stream must be\n  read prior to getting the value of any other column. The next\n  call to a <code>getXXX</code> method implicitly closes the stream.  Also, a\n  stream may return <code>0</code> when the method\n  <code>InputStream.available</code>\n  is called whether there is data available or not.\n\n  @param columnIndex the first column is 1, the second is 2, ...\n  @return a Java input stream that delivers the database column value\n    as a stream of uninterpreted bytes;\n    if the value is SQL <code>NULL</code>, the value returned is <code>null</code>\n}\nfunction TZAbstractResultSet.GetBinaryStream(ColumnIndex: Integer): TStream;\nvar\n  Blob: IZBlob;\nbegin\n{$IFNDEF DISABLE_CHECKING}\n  CheckColumnConvertion(ColumnIndex, stBinaryStream);\n{$ENDIF}\n  Result := nil;\n  if not IsNull(ColumnIndex) then\n  begin\n    Blob := GetBlob(ColumnIndex);\n    if Blob <> nil then\n      Result := Blob.GetStream;\n  end;\n  LastWasNull := (Result = nil);\nend;\n\n{**\n  Returns the value of the designated column in the current row\n  of this <code>ResultSet</code> object as a <code>Blob</code> object\n  in the Java programming language.\n\n  @param ColumnIndex the first column is 1, the second is 2, ...\n  @return a <code>Blob</code> object representing the SQL <code>BLOB</code> value in\n    the specified column\n}\nfunction TZAbstractResultSet.GetBlob(ColumnIndex: Integer): IZBlob;\nbegin\n{$IFNDEF DISABLE_CHECKING}\n  CheckBlobColumn(ColumnIndex);\n{$ENDIF}\n\n  Result := TZAbstractBlob.CreateWithStream(nil, GetStatement.GetConnection);\nend;\n\n{**\n  Returns the value of the designated column in the current row\n  of this <code>ResultSet</code> object as a <code>IZResultSet</code> object\n  in the Java programming language.\n\n  @param ColumnIndex the first column is 1, the second is 2, ...\n  @return a <code>IZResultSet</code> object representing the SQL\n    <code>IZResultSet</code> value in the specified column\n}\nfunction TZAbstractResultSet.GetDataSet(ColumnIndex: Integer): IZDataSet;\nbegin\n  Result := nil;\nend;\n\n{**\n  Returns the value of the designated column in the current row\n  of this <code>ResultSet</code> object as a <code>Variant</code> object.\n\n  @param ColumnIndex the first column is 1, the second is 2, ...\n  @return a <code>Variant</code> object representing the SQL\n    any value in the specified column\n}\nfunction TZAbstractResultSet.GetValue(ColumnIndex: Integer): TZVariant;\nvar\n  Metadata: TZAbstractResultSetMetadata;\nbegin\n{$IFNDEF DISABLE_CHECKING}\n  CheckClosed;\n{$ENDIF}\n  Metadata := TZAbstractResultSetMetadata(FMetadata);\n{$IFNDEF DISABLE_CHECKING}\n  if (Metadata = nil) or (ColumnIndex <= 0)\n    or (ColumnIndex > Metadata.GetColumnCount) then\n  begin\n    raise EZSQLException.Create(\n      Format(SColumnIsNotAccessable, [ColumnIndex]));\n  end;\n{$ENDIF}\n\n  case Metadata.GetColumnType(ColumnIndex) of\n    stBoolean:\n      begin\n        Result.VType := vtBoolean;\n        Result.VBoolean := GetBoolean(ColumnIndex);\n      end;\n    stByte, stShort, stInteger, stLong:\n      begin\n        Result.VType := vtInteger;\n        Result.VInteger := GetLong(ColumnIndex);\n      end;\n    stFloat, stDouble, stBigDecimal:\n      begin\n        Result.VType := vtFloat;\n        Result.VFloat := GetBigDecimal(ColumnIndex);\n      end;\n    stDate, stTime, stTimestamp:\n      begin\n        Result.VType := vtDateTime;\n        Result.VDateTime := GetTimestamp(ColumnIndex);\n      end;\n    stString, stBytes, stAsciiStream, stBinaryStream:\n      begin\n        Result.VType := vtString;\n        Result.VString := String(GetString(ColumnIndex));\n      end;\n    stUnicodeString, stUnicodeStream:\n      begin\n        Result.VType := vtUnicodeString;\n        Result.VUnicodeString := GetUnicodeString(ColumnIndex);\n      end;\n    else\n      Result.VType := vtNull;\n  end;\n\n  if WasNull then\n    Result.VType := vtNull;\nend;\n\n{**\n  Gets the DefaultExpression value of the designated column in the current row\n  of this <code>ResultSet</code> object as\n  a <code>String</code>.\n\n  @param columnIndex the first column is 1, the second is 2, ...\n  @return the DefaultExpression value\n}\nfunction TZAbstractResultSet.GetDefaultExpression(ColumnIndex: Integer): string;\nbegin\n{$IFNDEF DISABLE_CHECKING}\n  CheckColumnConvertion(ColumnIndex, stString);\n{$ENDIF}\n  Result := '';\nend;\n\n//======================================================================\n// Methods for accessing results by column name\n//======================================================================\n\n{**\n  Indicates if the value of the designated column in the current row\n  of this <code>ResultSet</code> object is Null.\n\n  @param columnName the SQL name of the column\n  @return if the value is SQL <code>NULL</code>, the\n    value returned is <code>true</code>. <code>false</code> otherwise.\n}\nfunction TZAbstractResultSet.IsNullByName(const ColumnName: string): Boolean;\nbegin\n  Result := IsNull(GetColumnIndex(ColumnName));\nend;\n\n{**\n  Gets the value of the designated column in the current row\n  of this <code>ResultSet</code> object as\n  a <code>PAnsiChar</code> in the Delphi programming language.\n\n  @param columnName the SQL name of the column\n  @return the column value; if the value is SQL <code>NULL</code>, the\n    value returned is <code>null</code>\n}\nfunction TZAbstractResultSet.GetPCharByName(const ColumnName: string): PChar;\nbegin\n  Result := GetPChar(GetColumnIndex(ColumnName));\nend;\n\n{**\n  Gets the value of the designated column in the current row\n  of this <code>ResultSet</code> object as\n  a <code>String</code> in the Java programming language.\n\n  @param columnName the SQL name of the column\n  @return the column value; if the value is SQL <code>NULL</code>, the\n    value returned is <code>null</code>\n}\nfunction TZAbstractResultSet.GetStringByName(const ColumnName: string): String;\nbegin\n  Result := GetString(GetColumnIndex(ColumnName));\nend;\n\n{**\n  Gets the value of the designated column in the current row\n  of this <code>ResultSet</code> object as\n  a <code>String</code> in the Java programming language.\n\n  @param columnName the SQL name of the column\n  @return the column value; if the value is SQL <code>NULL</code>, the\n    value returned is <code>null</code>\n}\nfunction TZAbstractResultSet.GetBinaryStringByName(const ColumnName: string): RawByteString;\nbegin\n  Result := GetBinaryString(GetColumnIndex(ColumnName));\nend;\n\n{**\n  Gets the value of the designated column in the current row\n  of this <code>ResultSet</code> object as\n  a <code>WideString</code> in the Object Pascal programming language.\n\n  @param columnName the SQL name of the column\n  @return the column value; if the value is SQL <code>NULL</code>, the\n    value returned is <code>null</code>\n}\nfunction TZAbstractResultSet.GetUnicodeStringByName(const ColumnName: string):\n  WideString;\nbegin\n  Result := GetUnicodeString(GetColumnIndex(ColumnName));\nend;\n\n{**\n  Gets the value of the designated column in the current row\n  of this <code>ResultSet</code> object as\n  a <code>boolean</code> in the Java programming language.\n\n  @param columnName the SQL name of the column\n  @return the column value; if the value is SQL <code>NULL</code>, the\n    value returned is <code>false</code>\n}\nfunction TZAbstractResultSet.GetBooleanByName(const ColumnName: string): Boolean;\nbegin\n  Result := GetBoolean(GetColumnIndex(ColumnName));\nend;\n\n{**\n  Gets the value of the designated column in the current row\n  of this <code>ResultSet</code> object as\n  a <code>byte</code> in the Java programming language.\n\n  @param columnName the SQL name of the column\n  @return the column value; if the value is SQL <code>NULL</code>, the\n    value returned is <code>0</code>\n}\nfunction TZAbstractResultSet.GetByteByName(const ColumnName: string): Byte;\nbegin\n  Result := GetByte(GetColumnIndex(ColumnName));\nend;\n\n{**\n  Gets the value of the designated column in the current row\n  of this <code>ResultSet</code> object as\n  a <code>short</code> in the Java programming language.\n\n  @param columnName the SQL name of the column\n  @return the column value; if the value is SQL <code>NULL</code>, the\n    value returned is <code>0</code>\n}\nfunction TZAbstractResultSet.GetShortByName(const ColumnName: string): SmallInt;\nbegin\n  Result := GetShort(GetColumnIndex(ColumnName));\nend;\n\n{**\n  Gets the value of the designated column in the current row\n  of this <code>ResultSet</code> object as\n  an <code>int</code> in the Java programming language.\n\n  @param columnName the SQL name of the column\n  @return the column value; if the value is SQL <code>NULL</code>, the\n    value returned is <code>0</code>\n}\nfunction TZAbstractResultSet.GetIntByName(const ColumnName: string): Integer;\nbegin\n  Result := GetInt(GetColumnIndex(ColumnName));\nend;\n\n{**\n  Gets the value of the designated column in the current row\n  of this <code>ResultSet</code> object as\n  a <code>long</code> in the Java programming language.\n\n  @param columnName the SQL name of the column\n  @return the column value; if the value is SQL <code>NULL</code>, the\n    value returned is <code>0</code>\n}\nfunction TZAbstractResultSet.GetLongByName(const ColumnName: string): Int64;\nbegin\n  Result := GetLong(GetColumnIndex(ColumnName));\nend;\n\n{**\n  Gets the value of the designated column in the current row\n  of this <code>ResultSet</code> object as\n  a <code>float</code> in the Java programming language.\n\n  @param columnName the SQL name of the column\n  @return the column value; if the value is SQL <code>NULL</code>, the\n    value returned is <code>0</code>\n}\nfunction TZAbstractResultSet.GetFloatByName(const ColumnName: string): Single;\nbegin\n  Result := GetFloat(GetColumnIndex(ColumnName));\nend;\n\n{**\n  Gets the value of the designated column in the current row\n  of this <code>ResultSet</code> object as\n  a <code>double</code> in the Java programming language.\n\n  @param columnName the SQL name of the column\n  @return the column value; if the value is SQL <code>NULL</code>, the\n    value returned is <code>0</code>\n}\nfunction TZAbstractResultSet.GetDoubleByName(const ColumnName: string): Double;\nbegin\n  Result := GetDouble(GetColumnIndex(ColumnName));\nend;\n\n{**\n  Gets the value of the designated column in the current row\n  of this <code>ResultSet</code> object as\n  a <code>java.math.BigDecimal</code> in the Java programming language.\n\n  @param columnName the SQL name of the column\n  @return the column value; if the value is SQL <code>NULL</code>, the\n    value returned is <code>null</code>\n}\nfunction TZAbstractResultSet.GetBigDecimalByName(const ColumnName: string): Extended;\nbegin\n  Result := GetBigDecimal(GetColumnIndex(ColumnName));\nend;\n\n{**\n  Gets the value of the designated column in the current row\n  of this <code>ResultSet</code> object as\n  a <code>byte</code> array in the Java programming language.\n  The bytes represent the raw values returned by the driver.\n\n  @param columnName the SQL name of the column\n  @return the column value; if the value is SQL <code>NULL</code>, the\n    value returned is <code>null</code>\n}\nfunction TZAbstractResultSet.GetBytesByName(const ColumnName: string): TByteDynArray;\nbegin\n  Result := GetBytes(GetColumnIndex(ColumnName));\nend;\n\n{**\n  Gets the value of the designated column in the current row\n  of this <code>ResultSet</code> object as\n  a <code>java.sql.Date</code> object in the Java programming language.\n\n  @param columnName the SQL name of the column\n  @return the column value; if the value is SQL <code>NULL</code>, the\n    value returned is <code>null</code>\n}\nfunction TZAbstractResultSet.GetDateByName(const ColumnName: string): TDateTime;\nbegin\n  Result := GetDate(GetColumnIndex(ColumnName));\nend;\n\n{**\n  Gets the value of the designated column in the current row\n  of this <code>ResultSet</code> object as\n  a <code>java.sql.Time</code> object in the Java programming language.\n\n  @param columnName the SQL name of the column\n  @return the column value; if the value is SQL <code>NULL</code>,\n    the value returned is <code>null</code>\n}\nfunction TZAbstractResultSet.GetTimeByName(const ColumnName: string): TDateTime;\nbegin\n  Result := GetTime(GetColumnIndex(ColumnName));\nend;\n\n{**\n  Gets the value of the designated column in the current row\n  of this <code>ResultSet</code> object as\n  a <code>java.sql.Timestamp</code> object.\n\n  @param columnName the SQL name of the column\n  @return the column value; if the value is SQL <code>NULL</code>, the\n    value returned is <code>null</code>\n}\nfunction TZAbstractResultSet.GetTimestampByName(const ColumnName: string): TDateTime;\nbegin\n  Result := GetTimestamp(GetColumnIndex(ColumnName));\nend;\n\n{**\n  Gets the value of the designated column in the current row\n  of this <code>ResultSet</code> object as a stream of\n  ASCII characters. The value can then be read in chunks from the\n  stream. This method is particularly\n  suitable for retrieving large <code>LONGVARCHAR</code> values.\n  The JDBC driver will\n  do any necessary conversion from the database format into ASCII.\n\n  <P><B>Note:</B> All the data in the returned stream must be\n  read prior to getting the value of any other column. The next\n  call to a <code>getXXX</code> method implicitly closes the stream. Also, a\n  stream may return <code>0</code> when the method <code>available</code>\n  is called whether there is data available or not.\n\n  @param columnName the SQL name of the column\n  @return a Java input stream that delivers the database column value\n    as a stream of one-byte ASCII characters.\n    If the value is SQL <code>NULL</code>,\n    the value returned is <code>null</code>.\n}\nfunction TZAbstractResultSet.GetAsciiStreamByName(const ColumnName: string): TStream;\nbegin\n  Result := GetAsciiStream(GetColumnIndex(ColumnName));\nend;\n\n{**\n  Gets the value of the designated column in the current row\n  of this <code>ResultSet</code> object as a stream of\n  Unicode characters. The value can then be read in chunks from the\n  stream. This method is particularly\n  suitable for retrieving large <code>LONGVARCHAR</code> values.\n  The JDBC driver will\n  do any necessary conversion from the database format into Unicode.\n  The byte format of the Unicode stream must be Java UTF-8,\n  as defined in the Java virtual machine specification.\n\n  <P><B>Note:</B> All the data in the returned stream must be\n  read prior to getting the value of any other column. The next\n  call to a <code>getXXX</code> method implicitly closes the stream. Also, a\n  stream may return <code>0</code> when the method <code>available</code>\n  is called whether there is data available or not.\n\n  @param columnName the SQL name of the column\n  @return a Java input stream that delivers the database column value\n    as a stream of two-byte Unicode characters.\n    If the value is SQL <code>NULL</code>, the value returned is <code>null</code>.\n}\nfunction TZAbstractResultSet.GetUnicodeStreamByName(const ColumnName: string): TStream;\nbegin\n  Result := GetUnicodeStream(GetColumnIndex(ColumnName));\nend;\n\n{**\n  Gets the value of the designated column in the current row\n  of this <code>ResultSet</code> object as a stream of uninterpreted\n  <code>byte</code>s.\n  The value can then be read in chunks from the\n  stream. This method is particularly\n  suitable for retrieving large <code>LONGVARBINARY</code>\n  values.\n\n  <P><B>Note:</B> All the data in the returned stream must be\n  read prior to getting the value of any other column. The next\n  call to a <code>getXXX</code> method implicitly closes the stream. Also, a\n  stream may return <code>0</code> when the method <code>available</code>\n  is called whether there is data available or not.\n\n  @param columnName the SQL name of the column\n  @return a Java input stream that delivers the database column value\n    as a stream of uninterpreted bytes;\n    if the value is SQL <code>NULL</code>, the result is <code>null</code>\n}\nfunction TZAbstractResultSet.GetBinaryStreamByName(const ColumnName: string): TStream;\nbegin\n  Result := GetBinaryStream(GetColumnIndex(ColumnName));\nend;\n\n{**\n  Returns the value of the designated column in the current row\n  of this <code>ResultSet</code> object as a <code>Blob</code> object\n  in the Java programming language.\n\n  @param colName the name of the column from which to retrieve the value\n  @return a <code>Blob</code> object representing the SQL <code>BLOB</code> value in\n    the specified column\n}\nfunction TZAbstractResultSet.GetBlobByName(const ColumnName: string): IZBlob;\nbegin\n  Result := GetBlob(GetColumnIndex(ColumnName));\nend;\n\nfunction TZAbstractResultSet.GetDataSetByName(const ColumnName: string): IZDataSet;\nbegin\n  Result := GetDataSet(GetColumnIndex(ColumnName));\nend;\n\n{**\n  Returns the value of the designated column in the current row\n  of this <code>ResultSet</code> object as a <code>Variant</code> object.\n\n  @param colName the name of the column from which to retrieve the value\n  @return a <code>Blob</code> object representing the SQL <code>Any</code>\n    value in the specified column\n}\nfunction TZAbstractResultSet.GetValueByName(const ColumnName: string): TZVariant;\nbegin\n  Result := GetValue(GetColumnIndex(ColumnName));\nend;\n\n//=====================================================================\n// Advanced features:\n//=====================================================================\n\n{**\n  Returns the first warning reported by calls on this\n  <code>ResultSet</code> object.\n  Subsequent warnings on this <code>ResultSet</code> object\n  will be chained to the <code>SQLWarning</code> object that\n  this method returns.\n\n  <P>The warning chain is automatically cleared each time a new\n  row is read.\n\n  <P><B>Note:</B> This warning chain only covers warnings caused\n  by <code>ResultSet</code> methods.  Any warning caused by\n  <code>Statement</code> methods\n  (such as reading OUT parameters) will be chained on the\n  <code>Statement</code> object.\n\n  @return the first <code>SQLWarning</code> object reported or <code>null</code>\n}\nfunction TZAbstractResultSet.GetWarnings: EZSQLWarning;\nbegin\n  Result := nil;\nend;\n\n{**\n  Clears all warnings reported on this <code>ResultSet</code> object.\n  After this method is called, the method <code>getWarnings</code>\n  returns <code>null</code> until a new warning is\n  reported for this <code>ResultSet</code> object.\n}\nprocedure TZAbstractResultSet.ClearWarnings;\nbegin\nend;\n\n{**\n  Gets the name of the SQL cursor used by this <code>ResultSet</code>\n  object.\n\n  <P>In SQL, a result table is retrieved through a cursor that is\n  named. The current row of a result set can be updated or deleted\n  using a positioned update/delete statement that references the\n  cursor name. To insure that the cursor has the proper isolation\n  level to support update, the cursor's <code>select</code> statement should be\n  of the form 'select for update'. If the 'for update' clause is\n  omitted, the positioned updates may fail.\n\n  <P>The JDBC API supports this SQL feature by providing the name of the\n  SQL cursor used by a <code>ResultSet</code> object.\n  The current row of a <code>ResultSet</code> object\n  is also the current row of this SQL cursor.\n\n  <P><B>Note:</B> If positioned update is not supported, a\n  <code>SQLException</code> is thrown.\n\n  @return the SQL name for this <code>ResultSet</code> object's cursor\n}\nfunction TZAbstractResultSet.GetCursorName: AnsiString;\nbegin\n  Result := '';\nend;\n\n{**\n  Retrieves the  number, types and properties of\n  this <code>ResultSet</code> object's columns.\n  @return the description of this <code>ResultSet</code> object's columns\n}\nfunction TZAbstractResultSet.GetMetaData: IZResultSetMetaData;\nbegin\n  Result := TZAbstractResultSetMetadata(FMetadata);\nend;\n\n{**\n  Maps the given <code>ResultSet</code> column name to its\n  <code>ResultSet</code> column index.\n\n  @param columnName the name of the column\n  @return the column index of the given column name\n}\nfunction TZAbstractResultSet.GetColumnIndex(const ColumnName: string): Integer;\nbegin\n  Result := FindColumn(ColumnName);\n\n  if Result < 1 then\n    raise EZSQLException.Create(Format(SColumnWasNotFound, [ColumnName]));\nend;\n\n{**\n  Maps the given <code>ResultSet</code> column name to its\n  <code>ResultSet</code> column index.\n\n  @param columnName the name of the column\n  @return the column index of the given column name\n}\nfunction TZAbstractResultSet.FindColumn(const ColumnName: string): Integer;\nvar\n  I: Integer;\n  Metadata: TZAbstractResultSetMetadata;\nbegin\n  CheckClosed;\n  Metadata := TZAbstractResultSetMetadata(FMetadata);\n  Result := 0;\n\n  { Search for case sensitive columns. }\n  for I := 1 to Metadata.GetColumnCount do\n  begin\n    if Metadata.GetColumnLabel(I) = ColumnName then\n    begin\n      Result := I;\n      Exit;\n    end;\n  end;\n\n  { Search for case insensitive columns. }\n  for I := 1 to Metadata.GetColumnCount do\n  begin\n    if AnsiUpperCase(Metadata.GetColumnLabel(I)) = AnsiUpperCase(ColumnName) then\n    begin\n      Result := I;\n      Exit;\n    end;\n  end;\nend;\n\n//---------------------------------------------------------------------\n// Traversal/Positioning\n//---------------------------------------------------------------------\n\n{**\n  Indicates whether the cursor is before the first row in\n  this <code>ResultSet</code> object.\n\n  @return <code>true</code> if the cursor is before the first row;\n    <code>false</code> if the cursor is at any other position or the\n    result set contains no rows\n}\nfunction TZAbstractResultSet.IsBeforeFirst: Boolean;\nbegin\n  Result := (FRowNo = 0);\nend;\n\n{**\n  Indicates whether the cursor is after the last row in\n  this <code>ResultSet</code> object.\n\n  @return <code>true</code> if the cursor is after the last row;\n    <code>false</code> if the cursor is at any other position or the\n    result set contains no rows\n}\nfunction TZAbstractResultSet.IsAfterLast: Boolean;\nbegin\n  Result := {(FLastRowNo > 0) and} (FRowNo > FLastRowNo);\nend;\n\n{**\n  Indicates whether the cursor is on the first row of\n  this <code>ResultSet</code> object.\n\n  @return <code>true</code> if the cursor is on the first row;\n    <code>false</code> otherwise\n}\nfunction TZAbstractResultSet.IsFirst: Boolean;\nbegin\n  Result := (FRowNo = 1);\nend;\n\n{**\n  Indicates whether the cursor is on the last row of\n  this <code>ResultSet</code> object.\n  Note: Calling the method <code>isLast</code> may be expensive\n  because the JDBC driver\n  might need to fetch ahead one row in order to determine\n  whether the current row is the last row in the result set.\n\n  @return <code>true</code> if the cursor is on the last row;\n    <code>false</code> otherwise\n}\nfunction TZAbstractResultSet.IsLast: Boolean;\nbegin\n  Result := {(FLastRowNo > 0) and} (FRowNo = FLastRowNo);\nend;\n\n{**\n  Moves the cursor to the front of\n  this <code>ResultSet</code> object, just before the\n  first row. This method has no effect if the result set contains no rows.\n}\nprocedure TZAbstractResultSet.BeforeFirst;\nbegin\n  MoveAbsolute(0);\nend;\n\n{**\n  Moves the cursor to the end of\n  this <code>ResultSet</code> object, just after the\n  last row. This method has no effect if the result set contains no rows.\n}\nprocedure TZAbstractResultSet.AfterLast;\nbegin\n  Last;\n  Next;\nend;\n\n{**\n  Moves the cursor to the first row in\n  this <code>ResultSet</code> object.\n\n  @return <code>true</code> if the cursor is on a valid row;\n  <code>false</code> if there are no rows in the result set\n}\nfunction TZAbstractResultSet.First: Boolean;\nbegin\n  Result := MoveAbsolute(1);\nend;\n\n{**\n  Moves the cursor to the last row in\n  this <code>ResultSet</code> object.\n\n  @return <code>true</code> if the cursor is on a valid row;\n    <code>false</code> if there are no rows in the result set\n}\nfunction TZAbstractResultSet.Last: Boolean;\nbegin\n  Result := MoveAbsolute(FLastRowNo);\nend;\n\n{**\n  Retrieves the current row number.  The first row is number 1, the\n  second number 2, and so on.\n  @return the current row number; <code>0</code> if there is no current row\n}\nfunction TZAbstractResultSet.GetRow: Integer;\nbegin\n  Result := FRowNo;\nend;\n\n{**\n  Moves the cursor to the given row number in\n  this <code>ResultSet</code> object.\n\n  <p>If the row number is positive, the cursor moves to\n  the given row number with respect to the\n  beginning of the result set.  The first row is row 1, the second\n  is row 2, and so on.\n\n  <p>If the given row number is negative, the cursor moves to\n  an absolute row position with respect to\n  the end of the result set.  For example, calling the method\n  <code>absolute(-1)</code> positions the\n  cursor on the last row; calling the method <code>absolute(-2)</code>\n  moves the cursor to the next-to-last row, and so on.\n\n  <p>An attempt to position the cursor beyond the first/last row in\n  the result set leaves the cursor before the first row or after\n  the last row.\n\n  <p><B>Note:</B> Calling <code>absolute(1)</code> is the same\n  as calling <code>first()</code>. Calling <code>absolute(-1)</code>\n  is the same as calling <code>last()</code>.\n\n  @return <code>true</code> if the cursor is on the result set;\n    <code>false</code> otherwise\n}\nfunction TZAbstractResultSet.MoveAbsolute(Row: Integer): Boolean;\nbegin\n  Result := False;\n  RaiseForwardOnlyException;\nend;\n\n{**\n  Moves the cursor a relative number of rows, either positive or negative.\n  Attempting to move beyond the first/last row in the\n  result set positions the cursor before/after the\n  the first/last row. Calling <code>relative(0)</code> is valid, but does\n  not change the cursor position.\n\n  <p>Note: Calling the method <code>relative(1)</code>\n  is different from calling the method <code>next()</code>\n  because is makes sense to call <code>next()</code> when there\n  is no current row,\n  for example, when the cursor is positioned before the first row\n  or after the last row of the result set.\n\n  @return <code>true</code> if the cursor is on a row;\n    <code>false</code> otherwise\n}\nfunction TZAbstractResultSet.MoveRelative(Rows: Integer): Boolean;\nbegin\n  Result := MoveAbsolute(FRowNo + Rows);\nend;\n\n{**\n  Moves the cursor to the previous row in this\n  <code>ResultSet</code> object.\n\n  <p><B>Note:</B> Calling the method <code>previous()</code> is not the same as\n  calling the method <code>relative(-1)</code> because it\n  makes sense to call</code>previous()</code> when there is no current row.\n\n  @return <code>true</code> if the cursor is on a valid row;\n    <code>false</code> if it is off the result set\n}\nfunction TZAbstractResultSet.Previous: Boolean;\nbegin\n  Result := MoveAbsolute(FRowNo - 1);\nend;\n\n{**\n  Moves the cursor down one row from its current position.\n  A <code>ResultSet</code> cursor is initially positioned\n  before the first row; the first call to the method\n  <code>next</code> makes the first row the current row; the\n  second call makes the second row the current row, and so on.\n\n  <P>If an input stream is open for the current row, a call\n  to the method <code>next</code> will\n  implicitly close it. A <code>ResultSet</code> object's\n  warning chain is cleared when a new row is read.\n\n  @return <code>true</code> if the new current row is valid;\n    <code>false</code> if there are no more rows\n}\nfunction TZAbstractResultSet.Next: Boolean;\nbegin\n  Result := MoveAbsolute(FRowNo + 1);\nend;\n\n//---------------------------------------------------------------------\n// Properties\n//---------------------------------------------------------------------\n\n{**\n  Returns the fetch direction for this\n  <code>ResultSet</code> object.\n  @return the current fetch direction for this <code>ResultSet</code> object\n}\nfunction TZAbstractResultSet.GetFetchDirection: TZFetchDirection;\nbegin\n  Result := FFetchDirection;\nend;\n\n{**\n  Gives a hint as to the direction in which the rows in this\n  <code>ResultSet</code> object will be processed.\n  The initial value is determined by the\n  <code>Statement</code> object\n  that produced this <code>ResultSet</code> object.\n  The fetch direction may be changed at any time.\n}\nprocedure TZAbstractResultSet.SetFetchDirection(Direction: TZFetchDirection);\nbegin\n  if Direction <> fdForward then\n    RaiseUnsupportedException;\nend;\n\n{**\n  Returns the fetch size for this\n  <code>ResultSet</code> object.\n  @return the current fetch size for this <code>ResultSet</code> object\n}\nfunction TZAbstractResultSet.GetFetchSize: Integer;\nbegin\n  Result := FFetchSize;\nend;\n\n{**\n  Gives the JDBC driver a hint as to the number of rows that should\n  be fetched from the database when more rows are needed for this\n  <code>ResultSet</code> object.\n  If the fetch size specified is zero, the JDBC driver\n  ignores the value and is free to make its own best guess as to what\n  the fetch size should be.  The default value is set by the\n  <code>Statement</code> object\n  that created the result set.  The fetch size may be changed at any time.\n\n  @param rows the number of rows to fetch\n}\nprocedure TZAbstractResultSet.SetFetchSize(Rows: Integer);\nbegin\n  FFetchSize := Rows;\nend;\n\n{**\n  Returns the type of this <code>ResultSet</code> object.\n  The type is determined by the <code>Statement</code> object\n  that created the result set.\n\n  @return <code>TYPE_FORWARD_ONLY</code>,\n    <code>TYPE_SCROLL_INSENSITIVE</code>,\n    or <code>TYPE_SCROLL_SENSITIVE</code>\n}\nfunction TZAbstractResultSet.GetType: TZResultSetType;\nbegin\n  Result := FResultSetType;\nend;\n\n{**\n  Returns the concurrency mode of this <code>ResultSet</code> object.\n  The concurrency used is determined by the\n  <code>Statement</code> object that created the result set.\n\n  @return the concurrency type, either <code>CONCUR_READ_ONLY</code>\n    or <code>CONCUR_UPDATABLE</code>\n}\nfunction TZAbstractResultSet.GetConcurrency: TZResultSetConcurrency;\nbegin\n  Result := FResultSetConcurrency;\nend;\n\n{**\n  Gets an assigned post locate mode.\n  @param the assigned post locate mode.\n}\nfunction TZAbstractResultSet.GetLocateUpdates: TZLocateUpdatesMode;\nbegin\n  Result := FLocateUpdates;\nend;\n\nfunction TZAbstractResultSet.GetPostUpdates: TZPostUpdatesMode;\nbegin\n  Result := FPostUpdates;\nend;\n\n//---------------------------------------------------------------------\n// Updates\n//---------------------------------------------------------------------\n\n{**\n  Indicates whether the current row has been updated.  The value returned\n  depends on whether or not the result set can detect updates.\n\n  @return <code>true</code> if the row has been visibly updated\n    by the owner or another, and updates are detected\n}\nfunction TZAbstractResultSet.RowUpdated: Boolean;\nbegin\n  Result := False;\nend;\n\n{**\n  Indicates whether the current row has had an insertion.\n  The value returned depends on whether or not this\n  <code>ResultSet</code> object can detect visible inserts.\n\n  @return <code>true</code> if a row has had an insertion\n    and insertions are detected; <code>false</code> otherwise\n}\nfunction TZAbstractResultSet.RowInserted: Boolean;\nbegin\n  Result := False;\nend;\n\n{**\n  Indicates whether a row has been deleted.  A deleted row may leave\n  a visible \"hole\" in a result set.  This method can be used to\n  detect holes in a result set.  The value returned depends on whether\n  or not this <code>ResultSet</code> object can detect deletions.\n\n  @return <code>true</code> if a row was deleted and deletions are detected;\n    <code>false</code> otherwise\n}\nfunction TZAbstractResultSet.RowDeleted: Boolean;\nbegin\n  Result := False;\nend;\n\n{**\n  Gives a nullable column a null value.\n\n  The <code>updateXXX</code> methods are used to update column values in the\n  current row or the insert row.  The <code>updateXXX</code> methods do not\n  update the underlying database; instead the <code>updateRow</code>\n  or <code>insertRow</code> methods are called to update the database.\n\n  @param columnIndex the first column is 1, the second is 2, ...\n}\nprocedure TZAbstractResultSet.UpdateNull(ColumnIndex: Integer);\nbegin\n  RaiseReadOnlyException;\nend;\n\n{**\n  Updates the designated column with a <code>boolean</code> value.\n  The <code>updateXXX</code> methods are used to update column values in the\n  current row or the insert row.  The <code>updateXXX</code> methods do not\n  update the underlying database; instead the <code>updateRow</code> or\n  <code>insertRow</code> methods are called to update the database.\n\n  @param columnIndex the first column is 1, the second is 2, ...\n  @param x the new column value\n}\nprocedure TZAbstractResultSet.UpdateBoolean(ColumnIndex: Integer; Value: Boolean);\nbegin\n  RaiseReadOnlyException;\nend;\n\n{**\n  Updates the designated column with a <code>byte</code> value.\n  The <code>updateXXX</code> methods are used to update column values in the\n  current row or the insert row.  The <code>updateXXX</code> methods do not\n  update the underlying database; instead the <code>updateRow</code> or\n  <code>insertRow</code> methods are called to update the database.\n\n\n  @param columnIndex the first column is 1, the second is 2, ...\n  @param x the new column value\n}\nprocedure TZAbstractResultSet.UpdateByte(ColumnIndex: Integer;\n  Value: ShortInt);\nbegin\n  RaiseReadOnlyException;\nend;\n\n{**\n  Updates the designated column with a <code>short</code> value.\n  The <code>updateXXX</code> methods are used to update column values in the\n  current row or the insert row.  The <code>updateXXX</code> methods do not\n  update the underlying database; instead the <code>updateRow</code> or\n  <code>insertRow</code> methods are called to update the database.\n\n  @param columnIndex the first column is 1, the second is 2, ...\n  @param x the new column value\n}\nprocedure TZAbstractResultSet.UpdateShort(ColumnIndex: Integer; Value: SmallInt);\nbegin\n  RaiseReadOnlyException;\nend;\n\n{**\n  Updates the designated column with an <code>int</code> value.\n  The <code>updateXXX</code> methods are used to update column values in the\n  current row or the insert row.  The <code>updateXXX</code> methods do not\n  update the underlying database; instead the <code>updateRow</code> or\n  <code>insertRow</code> methods are called to update the database.\n\n  @param columnIndex the first column is 1, the second is 2, ...\n  @param x the new column value\n}\nprocedure TZAbstractResultSet.UpdateInt(ColumnIndex: Integer; Value: Integer);\nbegin\n  RaiseReadOnlyException;\nend;\n\n{**\n  Updates the designated column with a <code>long</code> value.\n  The <code>updateXXX</code> methods are used to update column values in the\n  current row or the insert row.  The <code>updateXXX</code> methods do not\n  update the underlying database; instead the <code>updateRow</code> or\n  <code>insertRow</code> methods are called to update the database.\n\n  @param columnIndex the first column is 1, the second is 2, ...\n  @param x the new column value\n}\nprocedure TZAbstractResultSet.UpdateLong(ColumnIndex: Integer; Value: Int64);\nbegin\n  RaiseReadOnlyException;\nend;\n\n{**\n  Updates the designated column with a <code>float</code> value.\n  The <code>updateXXX</code> methods are used to update column values in the\n  current row or the insert row.  The <code>updateXXX</code> methods do not\n  update the underlying database; instead the <code>updateRow</code> or\n  <code>insertRow</code> methods are called to update the database.\n\n  @param columnIndex the first column is 1, the second is 2, ...\n  @param x the new column value\n}\nprocedure TZAbstractResultSet.UpdateFloat(ColumnIndex: Integer; Value: Single);\nbegin\n  RaiseReadOnlyException;\nend;\n\n{**\n  Updates the designated column with a <code>double</code> value.\n  The <code>updateXXX</code> methods are used to update column values in the\n  current row or the insert row.  The <code>updateXXX</code> methods do not\n  update the underlying database; instead the <code>updateRow</code> or\n  <code>insertRow</code> methods are called to update the database.\n\n  @param columnIndex the first column is 1, the second is 2, ...\n  @param x the new column value\n}\nprocedure TZAbstractResultSet.UpdateDouble(ColumnIndex: Integer; Value: Double);\nbegin\n  RaiseReadOnlyException;\nend;\n\n{**\n  Updates the designated column with a <code>java.math.BigDecimal</code>\n  value.\n  The <code>updateXXX</code> methods are used to update column values in the\n  current row or the insert row.  The <code>updateXXX</code> methods do not\n  update the underlying database; instead the <code>updateRow</code> or\n  <code>insertRow</code> methods are called to update the database.\n\n  @param columnIndex the first column is 1, the second is 2, ...\n  @param x the new column value\n}\nprocedure TZAbstractResultSet.UpdateBigDecimal(ColumnIndex: Integer;\n  Value: Extended);\nbegin\n  RaiseReadOnlyException;\nend;\n\n{**\n  Updates the designated column with a <code>String</code> value.\n  The <code>updateXXX</code> methods are used to update column values in the\n  current row or the insert row.  The <code>updateXXX</code> methods do not\n  update the underlying database; instead the <code>updateRow</code> or\n  <code>insertRow</code> methods are called to update the database.\n\n  @param columnIndex the first column is 1, the second is 2, ...\n  @param x the new column value\n}\nprocedure TZAbstractResultSet.UpdatePChar(ColumnIndex: Integer; Value: PChar);\nbegin\n  UpdateString(ColumnIndex, Value);\nend;\n\n{**\n  Updates the designated column with a <code>String</code> value.\n  The <code>updateXXX</code> methods are used to update column values in the\n  current row or the insert row.  The <code>updateXXX</code> methods do not\n  update the underlying database; instead the <code>updateRow</code> or\n  <code>insertRow</code> methods are called to update the database.\n\n  @param columnIndex the first column is 1, the second is 2, ...\n  @param x the new column value\n}\nprocedure TZAbstractResultSet.UpdateString(ColumnIndex: Integer; const Value: String);\nbegin\n  RaiseReadOnlyException;\nend;\n\n{**\n  Updates the designated column with a <code>String</code> value.\n  The <code>updateXXX</code> methods are used to update column values in the\n  current row or the insert row.  The <code>updateXXX</code> methods do not\n  update the underlying database; instead the <code>updateRow</code> or\n  <code>insertRow</code> methods are called to update the database.\n\n  @param columnIndex the first column is 1, the second is 2, ...\n  @param x the new column value\n}\nprocedure TZAbstractResultSet.UpdateBinaryString(ColumnIndex: Integer; const Value: RawByteString);\nbegin\n  case GetMetaData.GetColumnType(ColumnIndex) of\n    stBytes: UpdateBytes(ColumnIndex, StrToBytes(Value));\n    stBinaryStream: GetBlob(ColumnIndex).SetString(Value);\n    else\n      UpdateString(ColumnIndex, ZDbcString(Value));\n  end;\nend;\n\n{**\n  Updates the designated column with a <code>WideString</code> value.\n  The <code>updateXXX</code> methods are used to update column values in the\n  current row or the insert row.  The <code>updateXXX</code> methods do not\n  update the underlying database; instead the <code>updateRow</code> or\n  <code>insertRow</code> methods are called to update the database.\n\n  @param columnIndex the first column is 1, the second is 2, ...\n  @param x the new column value\n}\nprocedure TZAbstractResultSet.UpdateUnicodeString(ColumnIndex: Integer;\n  const Value: WideString);\nbegin\n  RaiseReadOnlyException;\nend;\n\n{**\n  Updates the designated column with a <code>byte</code> array value.\n  The <code>updateXXX</code> methods are used to update column values in the\n  current row or the insert row.  The <code>updateXXX</code> methods do not\n  update the underlying database; instead the <code>updateRow</code> or\n  <code>insertRow</code> methods are called to update the database.\n\n  @param columnIndex the first column is 1, the second is 2, ...\n  @param x the new column value\n}\nprocedure TZAbstractResultSet.UpdateBytes(ColumnIndex: Integer;\n  const Value: TByteDynArray);\nbegin\n  RaiseReadOnlyException;\nend;\n\n{**\n  Updates the designated column with a <code>java.sql.Date</code> value.\n  The <code>updateXXX</code> methods are used to update column values in the\n  current row or the insert row.  The <code>updateXXX</code> methods do not\n  update the underlying database; instead the <code>updateRow</code> or\n  <code>insertRow</code> methods are called to update the database.\n\n  @param columnIndex the first column is 1, the second is 2, ...\n  @param x the new column value\n}\nprocedure TZAbstractResultSet.UpdateDate(ColumnIndex: Integer; Value: TDateTime);\nbegin\n  RaiseReadOnlyException;\nend;\n\n{**\n  Updates the designated column with a <code>java.sql.Time</code> value.\n  The <code>updateXXX</code> methods are used to update column values in the\n  current row or the insert row.  The <code>updateXXX</code> methods do not\n  update the underlying database; instead the <code>updateRow</code> or\n  <code>insertRow</code> methods are called to update the database.\n\n  @param columnIndex the first column is 1, the second is 2, ...\n  @param x the new column value\n}\nprocedure TZAbstractResultSet.UpdateTime(ColumnIndex: Integer; Value: TDateTime);\nbegin\n  RaiseReadOnlyException;\nend;\n\n{**\n  Updates the designated column with a <code>java.sql.Timestamp</code>\n  value.\n  The <code>updateXXX</code> methods are used to update column values in the\n  current row or the insert row.  The <code>updateXXX</code> methods do not\n  update the underlying database; instead the <code>updateRow</code> or\n  <code>insertRow</code> methods are called to update the database.\n\n  @param columnIndex the first column is 1, the second is 2, ...\n  @param x the new column value\n}\nprocedure TZAbstractResultSet.UpdateTimestamp(ColumnIndex: Integer;\n  Value: TDateTime);\nbegin\n  RaiseReadOnlyException;\nend;\n\n{**\n  Updates the designated column with an ascii stream value.\n  The <code>updateXXX</code> methods are used to update column values in the\n  current row or the insert row.  The <code>updateXXX</code> methods do not\n  update the underlying database; instead the <code>updateRow</code> or\n  <code>insertRow</code> methods are called to update the database.\n\n  @param columnIndex the first column is 1, the second is 2, ...\n  @param x the new column value\n}\nprocedure TZAbstractResultSet.UpdateAsciiStream(ColumnIndex: Integer;\n  Value: TStream);\nbegin\n  RaiseReadOnlyException;\nend;\n\n{**\n  Updates the designated column with a binary stream value.\n  The <code>updateXXX</code> methods are used to update column values in the\n  current row or the insert row.  The <code>updateXXX</code> methods do not\n  update the underlying database; instead the <code>updateRow</code> or\n  <code>insertRow</code> methods are called to update the database.\n\n  @param columnIndex the first column is 1, the second is 2, ...\n  @param x the new column value\n  @param length the length of the stream\n}\nprocedure TZAbstractResultSet.UpdateBinaryStream(ColumnIndex: Integer;\n  Value: TStream);\nbegin\n  RaiseReadOnlyException;\nend;\n\nprocedure TZAbstractResultSet.UpdateDataSet(ColumnIndex: Integer; Value: IZDataSet);\nbegin\n  RaiseReadOnlyException;\nend;\n{**\n  Updates the designated column with a character stream value.\n  The <code>updateXXX</code> methods are used to update column values in the\n  current row or the insert row.  The <code>updateXXX</code> methods do not\n  update the underlying database; instead the <code>updateRow</code> or\n  <code>insertRow</code> methods are called to update the database.\n\n  @param columnIndex the first column is 1, the second is 2, ...\n  @param x the new column value\n}\nprocedure TZAbstractResultSet.UpdateUnicodeStream(ColumnIndex: Integer;\n  Value: TStream);\nbegin\n  RaiseReadOnlyException;\nend;\n\n{**\n  Updates the designated column with a variant value.\n  The <code>updateXXX</code> methods are used to update column values in the\n  current row or the insert row.  The <code>updateXXX</code> methods do not\n  update the underlying database; instead the <code>updateRow</code> or\n  <code>insertRow</code> methods are called to update the database.\n\n  @param columnIndex the first column is 1, the second is 2, ...\n  @param x the new column value\n}\nprocedure TZAbstractResultSet.UpdateValue(ColumnIndex: Integer;\n  const Value: TZVariant);\nbegin\n  case Value.VType of\n    vtBoolean: UpdateBoolean(ColumnIndex, Value.VBoolean);\n    vtInteger: UpdateLong(ColumnIndex, Value.VInteger);\n    vtFloat: UpdateBigDecimal(ColumnIndex, Value.VFloat);\n    vtString: UpdateString(ColumnIndex, Value.VString);\n    vtDateTime: UpdateTimestamp(ColumnIndex, Value.VDateTime);\n    vtUnicodeString: UpdateUnicodeString(ColumnIndex, Value.VUnicodeString);\n  else\n    UpdateNull(ColumnIndex);\n  end;\nend;\n\n{**\n  Updates the DefaultExpression of the designated column with a <code>String</code> value.\n  This changes the behaviour of the RowAccessor used by the Resultset\n  @param columnIndex the first column is 1, the second is 2, ...\n  @param x the new DefaultExpression value for the column\n}\nprocedure TZAbstractResultSet.UpdateDefaultExpression(ColumnIndex: Integer; const Value: string);\nbegin\n  RaiseReadOnlyException;\nend;\n\n{**\n  Updates the designated column with a <code>null</code> value.\n  The <code>updateXXX</code> methods are used to update column values in the\n  current row or the insert row.  The <code>updateXXX</code> methods do not\n  update the underlying database; instead the <code>updateRow</code> or\n  <code>insertRow</code> methods are called to update the database.\n\n  @param columnName the name of the column\n}\nprocedure TZAbstractResultSet.UpdateNullByName(const ColumnName: string);\nbegin\n  UpdateNull(GetColumnIndex(ColumnName));\nend;\n\n{**\n  Updates the designated column with a <code>boolean</code> value.\n  The <code>updateXXX</code> methods are used to update column values in the\n  current row or the insert row.  The <code>updateXXX</code> methods do not\n  update the underlying database; instead the <code>updateRow</code> or\n  <code>insertRow</code> methods are called to update the database.\n\n  @param columnName the name of the column\n  @param x the new column value\n}\nprocedure TZAbstractResultSet.UpdateBooleanByName(const ColumnName: string;\n  Value: Boolean);\nbegin\n  UpdateBoolean(GetColumnIndex(ColumnName), Value);\nend;\n\n{**\n  Updates the designated column with a <code>byte</code> value.\n  The <code>updateXXX</code> methods are used to update column values in the\n  current row or the insert row.  The <code>updateXXX</code> methods do not\n  update the underlying database; instead the <code>updateRow</code> or\n  <code>insertRow</code> methods are called to update the database.\n\n  @param columnName the name of the column\n  @param x the new column value\n}\nprocedure TZAbstractResultSet.UpdateByteByName(const ColumnName: string;\n  Value: ShortInt);\nbegin\n  UpdateByte(GetColumnIndex(ColumnName), Value);\nend;\n\n{**\n  Updates the designated column with a <code>short</code> value.\n  The <code>updateXXX</code> methods are used to update column values in the\n  current row or the insert row.  The <code>updateXXX</code> methods do not\n  update the underlying database; instead the <code>updateRow</code> or\n  <code>insertRow</code> methods are called to update the database.\n\n  @param columnName the name of the column\n  @param x the new column value\n}\nprocedure TZAbstractResultSet.UpdateShortByName(const ColumnName: string;\n  Value: SmallInt);\nbegin\n  UpdateShort(GetColumnIndex(ColumnName), Value);\nend;\n\n{**\n  Updates the designated column with an <code>int</code> value.\n  The <code>updateXXX</code> methods are used to update column values in the\n  current row or the insert row.  The <code>updateXXX</code> methods do not\n  update the underlying database; instead the <code>updateRow</code> or\n  <code>insertRow</code> methods are called to update the database.\n\n  @param columnName the name of the column\n  @param x the new column value\n}\nprocedure TZAbstractResultSet.UpdateIntByName(const ColumnName: string;\n  Value: Integer);\nbegin\n  UpdateInt(GetColumnIndex(ColumnName), Value);\nend;\n\n{**\n  Updates the designated column with a <code>long</code> value.\n  The <code>updateXXX</code> methods are used to update column values in the\n  current row or the insert row.  The <code>updateXXX</code> methods do not\n  update the underlying database; instead the <code>updateRow</code> or\n  <code>insertRow</code> methods are called to update the database.\n\n  @param columnName the name of the column\n  @param x the new column value\n}\nprocedure TZAbstractResultSet.UpdateLongByName(const ColumnName: string;\n  Value: Int64);\nbegin\n  UpdateLong(GetColumnIndex(ColumnName), Value);\nend;\n\n{**\n  Updates the designated column with a <code>float\t</code> value.\n  The <code>updateXXX</code> methods are used to update column values in the\n  current row or the insert row.  The <code>updateXXX</code> methods do not\n  update the underlying database; instead the <code>updateRow</code> or\n  <code>insertRow</code> methods are called to update the database.\n\n  @param columnName the name of the column\n  @param x the new column value\n}\nprocedure TZAbstractResultSet.UpdateFloatByName(const ColumnName: string;\n  Value: Single);\nbegin\n  UpdateFloat(GetColumnIndex(ColumnName), Value);\nend;\n\n{**\n  Updates the designated column with a <code>double</code> value.\n  The <code>updateXXX</code> methods are used to update column values in the\n  current row or the insert row.  The <code>updateXXX</code> methods do not\n  update the underlying database; instead the <code>updateRow</code> or\n  <code>insertRow</code> methods are called to update the database.\n\n  @param columnName the name of the column\n  @param x the new column value\n}\nprocedure TZAbstractResultSet.UpdateDoubleByName(const ColumnName: string;\n  Value: Double);\nbegin\n  UpdateDouble(GetColumnIndex(ColumnName), Value);\nend;\n\n{**\n  Updates the designated column with a <code>java.sql.BigDecimal</code>\n  value.\n  The <code>updateXXX</code> methods are used to update column values in the\n  current row or the insert row.  The <code>updateXXX</code> methods do not\n  update the underlying database; instead the <code>updateRow</code> or\n  <code>insertRow</code> methods are called to update the database.\n\n  @param columnName the name of the column\n  @param x the new column value\n}\nprocedure TZAbstractResultSet.UpdateBigDecimalByName(const ColumnName: string;\n  Value: Extended);\nbegin\n  UpdateBigDecimal(GetColumnIndex(ColumnName), Value);\nend;\n\n{**\n  Updates the designated column with a <code>String</code> value.\n  The <code>updateXXX</code> methods are used to update column values in the\n  current row or the insert row.  The <code>updateXXX</code> methods do not\n  update the underlying database; instead the <code>updateRow</code> or\n  <code>insertRow</code> methods are called to update the database.\n\n  @param columnName the name of the column\n  @param x the new column value\n}\nprocedure TZAbstractResultSet.UpdatePCharByName(const ColumnName: string;\n   Value: PChar);\nbegin\n  UpdatePChar(GetColumnIndex(ColumnName), Value);\nend;\n\n{**\n  Updates the designated column with a <code>String</code> value.\n  The <code>updateXXX</code> methods are used to update column values in the\n  current row or the insert row.  The <code>updateXXX</code> methods do not\n  update the underlying database; instead the <code>updateRow</code> or\n  <code>insertRow</code> methods are called to update the database.\n\n  @param columnName the name of the column\n  @param x the new column value\n}\nprocedure TZAbstractResultSet.UpdateStringByName(const ColumnName: string;\n   const Value: String);\nbegin\n  UpdateString(GetColumnIndex(ColumnName), Value);\nend;\n\n{**\n  Updates the designated column with a <code>String</code> value.\n  The <code>updateXXX</code> methods are used to update column values in the\n  current row or the insert row.  The <code>updateXXX</code> methods do not\n  update the underlying database; instead the <code>updateRow</code> or\n  <code>insertRow</code> methods are called to update the database.\n\n  @param columnName the name of the column\n  @param x the new column value\n}\nprocedure TZAbstractResultSet.UpdateBinaryStringByName(const ColumnName: string;\n   const Value: RawByteString);\nbegin\n  UpdateBinaryString(GetColumnIndex(ColumnName), Value);\nend;\n\n{**\n  Updates the designated column with a <code>WideString</code> value.\n  The <code>updateXXX</code> methods are used to update column values in the\n  current row or the insert row.  The <code>updateXXX</code> methods do not\n  update the underlying database; instead the <code>updateRow</code> or\n  <code>insertRow</code> methods are called to update the database.\n\n  @param columnName the name of the column\n  @param x the new column value\n}\nprocedure TZAbstractResultSet.UpdateUnicodeStringByName(const ColumnName: string;\n  const Value: WideString);\nbegin\n  UpdateUnicodeString(GetColumnIndex(ColumnName), Value);\nend;\n\n{**\n  Updates the designated column with a <code>boolean</code> value.\n  The <code>updateXXX</code> methods are used to update column values in the\n  current row or the insert row.  The <code>updateXXX</code> methods do not\n  update the underlying database; instead the <code>updateRow</code> or\n  <code>insertRow</code> methods are called to update the database.\n\n  JDBC 2.0\n\n  Updates a column with a byte array value.\n\n  The <code>updateXXX</code> methods are used to update column values in the\n  current row, or the insert row.  The <code>updateXXX</code> methods do not\n  update the underlying database; instead the <code>updateRow</code> or <code>insertRow</code>\n  methods are called to update the database.\n\n  @param columnName the name of the column\n  @param x the new column value\n}\nprocedure TZAbstractResultSet.UpdateBytesByName(const ColumnName: string;\n  const Value: TByteDynArray);\nbegin\n  UpdateBytes(GetColumnIndex(ColumnName), Value);\nend;\n\n{**\n  Updates the designated column with a <code>java.sql.Date</code> value.\n  The <code>updateXXX</code> methods are used to update column values in the\n  current row or the insert row.  The <code>updateXXX</code> methods do not\n  update the underlying database; instead the <code>updateRow</code> or\n  <code>insertRow</code> methods are called to update the database.\n\n  @param columnName the name of the column\n  @param x the new column value\n}\nprocedure TZAbstractResultSet.UpdateDateByName(const ColumnName: string;\n  Value: TDateTime);\nbegin\n  UpdateDate(GetColumnIndex(ColumnName), Value);\nend;\n\n{**\n  Updates the designated column with a <code>java.sql.Time</code> value.\n  The <code>updateXXX</code> methods are used to update column values in the\n  current row or the insert row.  The <code>updateXXX</code> methods do not\n  update the underlying database; instead the <code>updateRow</code> or\n  <code>insertRow</code> methods are called to update the database.\n\n  @param columnName the name of the column\n  @param x the new column value\n}\nprocedure TZAbstractResultSet.UpdateTimeByName(const ColumnName: string;\n  Value: TDateTime);\nbegin\n  UpdateTime(GetColumnIndex(ColumnName), Value);\nend;\n\n{**\n  Updates the designated column with a <code>java.sql.Timestamp</code>\n  value.\n  The <code>updateXXX</code> methods are used to update column values in the\n  current row or the insert row.  The <code>updateXXX</code> methods do not\n  update the underlying database; instead the <code>updateRow</code> or\n  <code>insertRow</code> methods are called to update the database.\n\n  @param columnName the name of the column\n  @param x the new column value\n}\nprocedure TZAbstractResultSet.UpdateTimestampByName(const ColumnName: string;\n  Value: TDateTime);\nbegin\n  UpdateTimestamp(GetColumnIndex(ColumnName), Value);\nend;\n\n{**\n  Updates the designated column with an ascii stream value.\n  The <code>updateXXX</code> methods are used to update column values in the\n  current row or the insert row.  The <code>updateXXX</code> methods do not\n  update the underlying database; instead the <code>updateRow</code> or\n  <code>insertRow</code> methods are called to update the database.\n\n  @param columnName the name of the column\n  @param x the new column value\n}\nprocedure TZAbstractResultSet.UpdateAsciiStreamByName(const ColumnName: string;\n  Value: TStream);\nbegin\n  UpdateAsciiStream(GetColumnIndex(ColumnName), Value);\nend;\n\n{**\n  Updates the designated column with a binary stream value.\n  The <code>updateXXX</code> methods are used to update column values in the\n  current row or the insert row.  The <code>updateXXX</code> methods do not\n  update the underlying database; instead the <code>updateRow</code> or\n  <code>insertRow</code> methods are called to update the database.\n\n  @param columnName the name of the column\n  @param x the new column value\n}\nprocedure TZAbstractResultSet.UpdateBinaryStreamByName(const ColumnName: string;\n  Value: TStream);\nbegin\n  UpdateBinaryStream(GetColumnIndex(ColumnName), Value);\nend;\n\nprocedure TZAbstractResultSet.UpdateDataSetByName(const ColumnName: string;\n  Value: IZDataSet);\nbegin\n  UpdateDataSet(GetColumnIndex(ColumnName), Value);\nend;\n\n{**\n  Updates the designated column with a character stream value.\n  The <code>updateXXX</code> methods are used to update column values in the\n  current row or the insert row.  The <code>updateXXX</code> methods do not\n  update the underlying database; instead the <code>updateRow</code> or\n  <code>insertRow</code> methods are called to update the database.\n\n  @param columnName the name of the column\n  @param x the new column value\n}\nprocedure TZAbstractResultSet.UpdateUnicodeStreamByName(const ColumnName: string;\n  Value: TStream);\nbegin\n  UpdateUnicodeStream(GetColumnIndex(ColumnName), Value);\nend;\n\n{**\n  Updates the designated column with a <code>Variant</code> value.\n  The <code>updateXXX</code> methods are used to update column values in the\n  current row or the insert row.  The <code>updateXXX</code> methods do not\n  update the underlying database; instead the <code>updateRow</code> or\n  <code>insertRow</code> methods are called to update the database.\n\n  @param columnName the name of the column\n  @param x the new column value\n}\nprocedure TZAbstractResultSet.UpdateValueByName(const ColumnName: string;\n  const Value: TZVariant);\nbegin\n  UpdateValue(GetColumnIndex(ColumnName), Value);\nend;\n\n{**\n  Inserts the contents of the insert row into this\n  <code>ResultSet</code> objaect and into the database.\n  The cursor must be on the insert row when this method is called.\n}\nprocedure TZAbstractResultSet.InsertRow;\nbegin\n  RaiseReadOnlyException;\nend;\n\n{**\n  Updates the underlying database with the new contents of the\n  current row of this <code>ResultSet</code> object.\n  This method cannot be called when the cursor is on the insert row.\n}\nprocedure TZAbstractResultSet.UpdateRow;\nbegin\n  RaiseReadOnlyException;\nend;\n\n{**\n  Deletes the current row from this <code>ResultSet</code> object\n  and from the underlying database.  This method cannot be called when\n  the cursor is on the insert row.\n}\nprocedure TZAbstractResultSet.DeleteRow;\nbegin\n  RaiseReadOnlyException;\nend;\n\n{**\n  Refreshes the current row with its most recent value in\n  the database.  This method cannot be called when\n  the cursor is on the insert row.\n\n  <P>The <code>refreshRow</code> method provides a way for an\n  application to\n  explicitly tell the JDBC driver to refetch a row(s) from the\n  database.  An application may want to call <code>refreshRow</code> when\n  caching or prefetching is being done by the JDBC driver to\n  fetch the latest value of a row from the database.  The JDBC driver\n  may actually refresh multiple rows at once if the fetch size is\n  greater than one.\n\n  <P> All values are refetched subject to the transaction isolation\n  level and cursor sensitivity.  If <code>refreshRow</code> is called after\n  calling an <code>updateXXX</code> method, but before calling\n  the method <code>updateRow</code>, then the\n  updates made to the row are lost.  Calling the method\n  <code>refreshRow</code> frequently will likely slow performance.\n}\nprocedure TZAbstractResultSet.RefreshRow;\nbegin\n  RaiseUnsupportedException;\nend;\n\n{**\n  Cancels the updates made to the current row in this\n  <code>ResultSet</code> object.\n  This method may be called after calling an\n  <code>updateXXX</code> method(s) and before calling\n  the method <code>updateRow</code> to roll back\n  the updates made to a row.  If no updates have been made or\n  <code>updateRow</code> has already been called, this method has no\n  effect.\n}\nprocedure TZAbstractResultSet.CancelRowUpdates;\nbegin\n  RaiseReadOnlyException;\nend;\n\n{**\n  Moves the cursor to the insert row.  The current cursor position is\n  remembered while the cursor is positioned on the insert row.\n\n  The insert row is a special row associated with an updatable\n  result set.  It is essentially a buffer where a new row may\n  be constructed by calling the <code>updateXXX</code> methods prior to\n  inserting the row into the result set.\n\n  Only the <code>updateXXX</code>, <code>getXXX</code>,\n  and <code>insertRow</code> methods may be\n  called when the cursor is on the insert row.  All of the columns in\n  a result set must be given a value each time this method is\n  called before calling <code>insertRow</code>.\n  An <code>updateXXX</code> method must be called before a\n  <code>getXXX</code> method can be called on a column value.\n}\nprocedure TZAbstractResultSet.MoveToInsertRow;\nbegin\n  RaiseReadOnlyException;\nend;\n\n{**\n  Moves the cursor to the remembered cursor position, usually the\n  current row.  This method has no effect if the cursor is not on\n  the insert row.\n}\nprocedure TZAbstractResultSet.MoveToCurrentRow;\nbegin\nend;\n\n{**\n  Compares fields from two row buffers.\n  @param Row1 the first row buffer to compare.\n  @param Row2 the second row buffer to compare.\n  @param ColumnIndices column indices to compare.\n  @param ColumnDirs compare direction for each columns.\n}\nfunction TZAbstractResultSet.CompareRows(Row1, Row2: Integer;\n  const ColumnIndices: TIntegerDynArray; const ColumnDirs: TBooleanDynArray): Integer;\nvar\n  I: Integer;\n  ColumnIndex: Integer;\n  SaveRowNo: Integer;\n  Value1, Value2: TZVariant;\n\n  function CompareFloat(Value1, Value2: Extended): Integer;\n  begin\n    Value1 := Value1 - Value2;\n    if Value1 > 0 then\n      Result := 1\n    else if Value1 < 0 then\n      Result := -1\n    else\n      Result := 0;\n  end;\n\nbegin\n  Result := 0;\n  SaveRowNo := RowNo;\n  try\n    for I := Low(ColumnIndices) to High(ColumnIndices) do\n    begin\n      ColumnIndex := ColumnIndices[I];\n\n      MoveAbsolute(Row1);\n      Value1 := GetValue(ColumnIndex);\n      MoveAbsolute(Row2);\n      Value2 := GetValue(ColumnIndex);\n\n      { Checks for both Null columns. }\n      if (Value1.VType = vtNull) and (Value2.VType = vtNull) then\n        Continue;\n      { Checks for not-Null and Null columns. }\n      if (Value1.VType = vtNull) or (Value2.VType = vtNull) then\n      begin\n        if Value1.VType <> vtNull then\n          Result := 1\n        else\n          Result := -1;\n        if not ColumnDirs[I] then\n          Result := -Result;\n        Break;\n      end;\n      case Value1.VType of\n        vtBoolean:\n          begin\n            if Value1.VBoolean = Value2.VBoolean then\n              Result := 0\n            else if Value1.VBoolean = True then\n              Result := 1\n            else\n              Result := -1;\n          end;\n        vtInteger:\n          Result := Value1.VInteger - Value2.VInteger;\n        vtFloat:\n          Result := CompareFloat(Value1.VFloat, Value2.VFloat);\n        vtDateTime:\n          Result := CompareFloat(Value1.VDateTime, Value2.VDateTime);\n        vtString:\n          Result := AnsiCompareStr(Value1.VString, Value2.VString);\n        vtUnicodeString:\n          Result := WideCompareStr(Value1.VUnicodeString, Value2.VUnicodeString);\n      end;\n      if Result <> 0 then\n      begin\n        if not ColumnDirs[I] then\n          Result := -Result;\n        Break;\n      end;\n    end;\n  finally\n    MoveAbsolute(SaveRowNo);\n  end;\nend;\n\n{**\n  Returns the <code>Statement</code> object that produced this\n  <code>ResultSet</code> object.\n  If the result set was generated some other way, such as by a\n  <code>DatabaseMetaData</code> method, this method returns\n  <code>null</code>.\n\n  @return the <code>Statment</code> object that produced\n    this <code>ResultSet</code> object or <code>null</code>\n    if the result set was produced some other way\n}\nfunction TZAbstractResultSet.GetStatement: IZStatement;\nbegin\n  Result := FStatement;\nend;\n\nfunction TZAbstractResultSet.GetConSettings: PZConsettings;\nbegin\n  Result := ConSettings;\nend;\n\n{ TZAbstractBlob }\n\n{**\n  Constructs this class and assignes the main properties.\n  @param Stream a data string object.\n}\nconstructor TZAbstractBlob.CreateWithStream(Stream: TStream;\n  Connection: IZConnection = Nil; Decoded: Boolean = False);\nbegin\n  inherited Create;\n  FUpdated := False;\n  FConnection := Connection;\n  FDecoded := Decoded;\n  if Assigned(Stream) then\n  begin\n    FBlobSize := Stream.Size;\n    if FBlobSize > 0 then\n    begin\n      GetMem(FBlobData, FBlobSize);\n      Stream.Position := 0;\n      Stream.ReadBuffer(FBlobData^, FBlobSize);\n    end;\n  end\n  else\n  begin\n    FBlobSize := -1;\n    FBlobData := nil;\n  end;\nend;\n\n{**\n  Constructs this class and assignes the main properties.\n  @param Data a pointer to the blobdata.\n  @param Size the size of the blobdata.\n}\nconstructor TZAbstractBlob.CreateWithData(Data: Pointer; Size: Integer;\n  Connection: IZConnection = nil; Decoded: Boolean = False);\nbegin\n  inherited Create;\n  FConnection := Connection;\n  FBlobData := nil;\n  FBlobSize := Size;\n  FDecoded := Decoded;\n  if FBlobSize > 0 then\n  begin\n    GetMem(FBlobData, FBlobSize);\n    System.Move(Data^, FBlobData^, FBlobSize);\n  end;\n  FUpdated := False;\nend;\n\n{**\n  Destroys this object and cleanups the memory.\n}\ndestructor TZAbstractBlob.Destroy;\nbegin\n  Clear;\n  inherited Destroy;\nend;\n\n{**\n  Clears the content of this blob.\n}\nprocedure TZAbstractBlob.Clear;\nbegin\n  if Assigned(FBlobData) then\n    FreeMem(FBlobData);\n  FBlobData := nil;\n  FBlobSize := -1;\n  FUpdated := True;\nend;\n\n{**\n  Clones this blob object.\n  @return a clonned blob object.\n}\nfunction TZAbstractBlob.Clone: IZBlob;\nbegin\n  Result := TZAbstractBlob.CreateWithData(FBlobData, FBlobSize, FConnection, FDecoded);\nend;\n\n{**\n  Checks if this Text-blob was right Decoded.\n  @return <code>True</code> if this blob is empty.\n}\nfunction TZAbstractBlob.WasDecoded: Boolean;\nbegin\n  Result := FDecoded;\nend;\n\n{**\n  Returns the IZConnection which is propable needed to handle the encoding\n  @return <code>IZConnection</code> if assigned\n}\nfunction TZAbstractBlob.Connection: IZConnection;\nbegin\n  Result := FConnection;\nend;\n\n{**\n  Checks if this blob has an empty content.\n  @return <code>True</code> if this blob is empty.\n}\nfunction TZAbstractBlob.IsEmpty: Boolean;\nbegin\n  Result := FBlobSize < 0;\nend;\n\n{**\n  Checks if the content of this blob was updated.\n  @return <code>True</code> is this blob was updated.\n}\nfunction TZAbstractBlob.IsUpdated: Boolean;\nbegin\n  Result := FUpdated;\nend;\n\n{**\n  Gets the length of the stored data.\n  @return the length of the stored data or null if the blob is empty.\n}\nfunction TZAbstractBlob.Length: LongInt;\nbegin\n  Result := FBlobSize;\nend;\n\n{**\n  Gets the string from the stored data.\n  @return a string which contains the stored data.\n}\nfunction TZAbstractBlob.GetString: RawByteString;\nbegin\n  if (FBlobSize > 0) and Assigned(FBlobData) then\n    if FDecoded then\n      Result := FConnection.GetIZPlainDriver.ZPlainString(GetUnicodeString, FConnection.GetConSettings)\n    else\n    begin\n      {$IFDEF WITH_RAWBYTESTRING}\n      SetLength(Result, FBlobSize);\n      System.Move(PAnsiChar(FBlobData)^, PAnsiChar(Result)^, FBlobSize);\n      {$ELSE}\n      System.SetString(Result, PAnsiChar(FBlobData), FBlobSize);\n      {$ENDIF}\n    end\n  else\n    Result := '';\nend;\n\n{**\n  Sets a new string data to this blob content.\n  @param Value a new string data.\n}\nprocedure TZAbstractBlob.SetString(const Value: RawByteString);\nbegin\n  Clear;\n  FBlobSize := System.Length(Value);\n  if FBlobSize > 0 then\n  begin\n    GetMem(FBlobData, FBlobSize);\n    System.Move(PAnsiChar(Value)^, FBlobData^, FBlobSize);\n  end;\n  FUpdated := True;\nend;\n\n{**\n  Gets the wide string from the stored data.\n  @return a string which contains the stored data.\n}\nfunction TZAbstractBlob.GetUnicodeString: WideString;\nvar\n  Bytes: TByteDynArray;\nbegin\n  if (FBlobSize > 0) and Assigned(FBlobData) then\n    if FDecoded then\n    begin\n      SetLength(Result, FBlobSize div 2);\n      System.Move(PWidechar(FBlobData)^, PWideChar(Result)^, FBlobSize);\n    end\n    else\n    begin\n      SetLength(Bytes, FBlobSize +2);\n      System.move(FBlobData^, Pointer(Bytes)^, FBlobSize);\n      if ( not ( {$IFDEF WITH_ANSISTRCOMP_DEPRECATED}AnsiStrings.{$ENDIF}StrLen(PAnsiChar(Bytes)) = Cardinal(FBlobSize) ) ) and\n         ( {$IFDEF DELPHI14_UP}StrLen{$ELSE}System.Length{$ENDIF}(PWideChar(Bytes)) = Cardinal(FBlobSize) div 2 ) then\n      begin\n        SetLength(Result, FBlobSize div 2);\n        System.Move(PWidechar(Bytes)^, PWideChar(Result)^, FBlobSize);\n      end\n      else\n        Result := FConnection.GetIZPlainDriver.ZDbcUnicodeString(PAnsiChar(Bytes), FConnection.GetConSettings.CTRL_CP);\n      SetLength(Bytes, 0);\n    end\n  else\n    Result := '';\nend;\n\n{**\n  Sets a new string data to this blob content.\n  @param Value a new wide string data.\n}\nprocedure TZAbstractBlob.SetUnicodeString(const Value: WideString);\nbegin\n  Clear;\n  FBlobSize := System.Length(Value) *2;\n  if FBlobSize > 0 then\n  begin\n    GetMem(FBlobData, FBlobSize);\n    System.Move(PWideChar(Value)^, FBlobData^, FBlobSize);\n  end;\n  FUpdated := True;\n  FDecoded := True;\nend;\n\n{**\n  Gets the byte buffer from the stored data.\n  @return a byte buffer which contains the stored data.\n}\nfunction TZAbstractBlob.GetBytes: TByteDynArray;\nbegin\n  if not IsEmpty then\n  begin\n    if (FBlobSize > 0) and Assigned(FBlobData) then begin\n      SetLength(Result, FBlobSize);\n      Move(FBlobData^, Result[0], FBlobSize);\n    end else\n      Result := nil;\n  end\n  else\n    Result := nil;\nend;\n\n{**\n  Sets a new byte buffer to this blob content.\n  @param Value a new byte buffer.\n}\nprocedure TZAbstractBlob.SetBytes(const Value: TByteDynArray);\nbegin\n  Clear;\n  if Value <> nil then\n  begin\n    FBlobSize := System.Length(Value);\n    if FBlobSize > 0 then\n    begin\n      GetMem(FBlobData, FBlobSize);\n      System.Move(Value[0], FBlobData^, FBlobSize);\n    end;\n  end;\n  FUpdated := True;\nend;\n\nfunction TZAbstractBlob.GetUnicodeStream: TStream;\nvar\n  ws: WideString;\nbegin\n  Result := TMemoryStream.Create;\n  if (FBlobSize > 0) and Assigned(FBlobData) then\n  begin\n    if ( not ( {$IFDEF WITH_ANSISTRCOMP_DEPRECATED}AnsiStrings.{$ENDIF}StrLen(PAnsiChar(FBlobData)) = Cardinal(FBlobSize) ) ) and\n       ( {$IFDEF DELPHI14_UP}StrLen{$ELSE}System.Length{$ENDIF}(PWideChar(FBlobData)) = Cardinal(FBlobSize) div 2 ) then\n    begin\n      Result.Size := FBlobSize;\n      System.Move(PWidechar(FBlobData)^, TMemoryStream(Result).Memory^, FBlobSize);\n    end\n    else\n    begin\n      ws:=GetUnicodeString;\n      Result.Size := System.Length(WS)*2;\n      System.Move(ws[1], TMemoryStream(Result).Memory^, Result.Size);\n    end;\n  end;\n  Result.Position := 0;\nend;\n\n{**\n  Gets the associated stream object.\n  @return an associated or newly created stream object.\n}\nfunction TZAbstractBlob.GetStream: TStream;\nbegin\n  Result := TMemoryStream.Create;\n  if (FBlobSize > 0) and Assigned(FBlobData) then\n  begin\n    Result.Size := FBlobSize;\n    System.Move(FBlobData^, TMemoryStream(Result).Memory^, FBlobSize);\n  end;\n  Result.Position := 0;\nend;\n\n{**\n  Sets a data from the specified stream into this blob.\n  @param Value a stream object to be stored into this blob.\n}\nprocedure TZAbstractBlob.SetStream(Value: TStream; Decoded: Boolean = False);\nbegin\n  Clear;\n  if Assigned(Value) then\n  begin\n    FBlobSize := Value.Size;\n    if FBlobSize > 0 then\n    begin\n      GetMem(FBlobData, FBlobSize);\n      Value.Position := 0;\n      Value.ReadBuffer(FBlobData^, FBlobSize);\n    end;\n  end\n  else\n  begin\n    FBlobSize := -1;\n    FBlobData := nil;\n  end;\n  FUpdated := True;\n  FDecoded := Decoded;\nend;\n\nfunction TZAbstractBlob.GetBuffer: Pointer;\nbegin\n  Result := FBlobData;\nend;\n\nprocedure TZAbstractBlob.SetBuffer(Buffer: Pointer; Length: Integer);\nbegin\n  FBlobSize := Length;\n  if Assigned(Buffer) and ( Length > 0 ) then\n  begin\n    FBlobData := nil;\n    GetMem(FBlobData, Length);\n    Move(FBlobData^, Buffer^, Length);\n  end\n  else\n  begin\n    FBlobSize := -1;\n    FBlobData := nil;\n  end;\n  FUpdated := True;\nend;\n\nend.\n"
  },
  {
    "path": "lib/zeosdbo/src/dbc/ZDbcResultSetMetadata.pas",
    "content": "{*********************************************************}\n{                                                         }\n{                 Zeos Database Objects                   }\n{         Abstract Database Connectivity Classes          }\n{                                                         }\n{        Originally written by Sergey Seroukhov           }\n{                                                         }\n{*********************************************************}\n\n{@********************************************************}\n{    Copyright (c) 1999-2012 Zeos Development Group       }\n{                                                         }\n{ License Agreement:                                      }\n{                                                         }\n{ This library is distributed in the hope that it will be }\n{ useful, but WITHOUT ANY WARRANTY; without even the      }\n{ implied warranty of MERCHANTABILITY or FITNESS FOR      }\n{ A PARTICULAR PURPOSE.  See the GNU Lesser General       }\n{ Public License for more details.                        }\n{                                                         }\n{ The source code of the ZEOS Libraries and packages are  }\n{ distributed under the Library GNU General Public        }\n{ License (see the file COPYING / COPYING.ZEOS)           }\n{ with the following  modification:                       }\n{ As a special exception, the copyright holders of this   }\n{ library give you permission to link this library with   }\n{ independent modules to produce an executable,           }\n{ regardless of the license terms of these independent    }\n{ modules, and to copy and distribute the resulting       }\n{ executable under terms of your choice, provided that    }\n{ you also meet, for each linked independent module,      }\n{ the terms and conditions of the license of that module. }\n{ An independent module is a module which is not derived  }\n{ from or based on this library. If you modify this       }\n{ library, you may extend this exception to your version  }\n{ of the library, but you are not obligated to do so.     }\n{ If you do not wish to do so, delete this exception      }\n{ statement from your version.                            }\n{                                                         }\n{                                                         }\n{ The project web site is located on:                     }\n{   http://zeos.firmos.at  (FORUM)                        }\n{   http://sourceforge.net/p/zeoslib/tickets/ (BUGTRACKER)}\n{   svn://svn.code.sf.net/p/zeoslib/code-0/trunk (SVN)    }\n{                                                         }\n{   http://www.sourceforge.net/projects/zeoslib.          }\n{                                                         }\n{                                                         }\n{                                 Zeos Development Group. }\n{********************************************************@}\n\nunit ZDbcResultSetMetadata;\n\ninterface\n\n{$I ZDbc.inc}\n\nuses\n  Classes, SysUtils, Contnrs, ZDbcIntfs, ZClasses, ZCollections,\n  ZGenericSqlAnalyser,\n{$IFDEF FPC}\n  {$IFDEF WIN32}\n    Comobj,\n  {$ENDIF}\n{$ENDIF}\n  ZTokenizer, ZSelectSchema, ZCompatibility, ZDbcResultSet;\n\ntype\n\n  {** Implements a column information structure. }\n  TZColumnInfo = class(TObject)\n  protected\n    FAutoIncrement: Boolean;\n    FCaseSensitive: Boolean;\n    FSearchable: Boolean;\n    FCurrency: Boolean;\n    FNullable: TZColumnNullableType;\n    FSigned: Boolean;\n    FColumnDisplaySize: Integer;\n    FMaxLenghtBytes: Integer;\n    FColumnLabel: string;\n    FColumnName: string;\n    FSchemaName: string;\n    FPrecision: Integer;\n    FScale: Integer;\n    FTableName: string;\n    FCatalogName: string;\n    FColumnType: TZSQLType;\n    FInternalColumnType: TZSQLType;\n    FReadOnly: Boolean;\n    FWritable: Boolean;\n    FDefinitelyWritable: Boolean;\n    FDefaultValue: string;\n    FDefaultExpression : string;\n  public\n    constructor Create;\n    function GetColumnTypeName: string;\n\n    property AutoIncrement: Boolean read FAutoIncrement write FAutoIncrement;\n    property CaseSensitive: Boolean read FCaseSensitive write FCaseSensitive;\n    property Searchable: Boolean read FSearchable write FSearchable;\n    property Currency: Boolean read FCurrency write FCurrency;\n    property Nullable: TZColumnNullableType read FNullable write FNullable;\n\n    property Signed: Boolean read FSigned write FSigned;\n    property ColumnDisplaySize: Integer read FColumnDisplaySize\n      write FColumnDisplaySize;\n    property MaxLenghtBytes: Integer read FMaxLenghtBytes\n      write FMaxLenghtBytes;\n    property ColumnLabel: string read FColumnLabel write FColumnLabel;\n    property ColumnName: string read FColumnName write FColumnName;\n    property SchemaName: string read FSchemaName write FSchemaName;\n    property Precision: Integer read FPrecision write FPrecision;\n    property Scale: Integer read FScale write FScale;\n    property TableName: string read FTableName write FTableName;\n    property CatalogName: string read FCatalogName write FCatalogName;\n    property ColumnType: TZSQLType read FColumnType write FColumnType;\n    property InternalColumnType: TZSQLType read FInternalColumnType write FInternalColumnType;\n    property ReadOnly: Boolean read FReadOnly write FReadOnly;\n    property Writable: Boolean read FWritable write FWritable;\n    property DefinitelyWritable: Boolean read FDefinitelyWritable\n      write FDefinitelyWritable;\n    property DefaultValue: string read FDefaultValue write FDefaultValue;\n    property DefaultExpression: string read FDefaultExpression write FDefaultExpression;\n  end;\n\n  {** Implements Abstract ResultSet Metadata. }\n  TZAbstractResultSetMetadata = class(TContainedObject, IZResultSetMetaData)\n  private\n    FLoaded: Boolean;\n    FMetadata: IZDatabaseMetadata;\n    FColumnsLabels: TStrings;\n    FSQL: string;\n    FTableColumns: TZHashMap;\n    FIdentifierConvertor: IZIdentifierConvertor;\n    FResultSet: TZAbstractResultSet;\n    procedure SetMetadata(const Value: IZDatabaseMetadata);\n  protected\n    procedure LoadColumn(ColumnIndex: Integer; ColumnInfo: TZColumnInfo;\n      SelectSchema: IZSelectSchema); virtual;\n\n    function GetTableColumns(TableRef: TZTableRef): IZResultSet;\n    function ReadColumnByRef(FieldRef: TZFieldRef;\n      ColumnInfo: TZColumnInfo): Boolean;\n    function ReadColumnByName(FieldName: string; TableRef: TZTableRef;\n      ColumnInfo: TZColumnInfo): Boolean;\n    procedure ClearColumn(ColumnInfo: TZColumnInfo);\n    procedure LoadColumns;\n    procedure ReplaceStarColumns(SelectSchema: IZSelectSchema);\n\n    property MetaData: IZDatabaseMetadata read FMetadata write SetMetadata;\n    property ColumnsLabels: TStrings read FColumnsLabels write FColumnsLabels;\n    property SQL: string read FSQL write FSQL;\n    property IdentifierConvertor: IZIdentifierConvertor\n      read FIdentifierConvertor write FIdentifierConvertor;\n    property Loaded: Boolean read FLoaded write FLoaded;\n    property ResultSet: TZAbstractResultSet read FResultSet write FResultSet;\n  public\n    constructor Create(Metadata: IZDatabaseMetadata; SQL: string;\n      ParentResultSet: TZAbstractResultSet);\n    destructor Destroy; override;\n\n    function GetColumnCount: Integer; virtual;\n    function IsAutoIncrement(Column: Integer): Boolean; virtual;\n    function IsCaseSensitive(Column: Integer): Boolean; virtual;\n    function IsSearchable(Column: Integer): Boolean; virtual;\n    function IsCurrency(Column: Integer): Boolean; virtual;\n    function IsNullable(Column: Integer): TZColumnNullableType; virtual;\n\n    function IsSigned(Column: Integer): Boolean; virtual;\n    function GetColumnDisplaySize(Column: Integer): Integer; virtual;\n    function GetColumnLabel(Column: Integer): string; virtual;\n    function GetColumnName(Column: Integer): string; virtual;\n    function GetSchemaName(Column: Integer): string; virtual;\n    function GetPrecision(Column: Integer): Integer; virtual;\n    function GetScale(Column: Integer): Integer; virtual;\n    function GetTableName(Column: Integer): string; virtual;\n    function GetCatalogName(Column: Integer): string; virtual;\n    function GetColumnType(Column: Integer): TZSQLType; virtual;\n    function GetColumnTypeName(Column: Integer): string; virtual;\n    function IsReadOnly(Column: Integer): Boolean; virtual;\n    function IsWritable(Column: Integer): Boolean; virtual;\n    function IsDefinitelyWritable(Column: Integer): Boolean; virtual;\n    function GetDefaultValue(Column: Integer): string; virtual;\n    function HasDefaultValue(Column: Integer): Boolean; virtual;\n  end;\n\nimplementation\n\nuses ZVariant, ZDbcUtils, ZDbcMetadata;\n\n{ TZColumnInfo }\n\n{**\n  Constructs this object and assigns main properties.\n}\nconstructor TZColumnInfo.Create;\nbegin\n  FAutoIncrement := False;\n  FCaseSensitive := False;\n  FSearchable := False;\n  FCurrency := False;\n  FNullable := ntNullableUnknown;\n  FSigned := False;\n  FColumnDisplaySize := 0;\n  FColumnLabel := '';\n  FColumnName := '';\n  FSchemaName := '';\n  FPrecision := 0;\n  FScale := 0;\n  FTableName := '';\n  FCatalogName := '';\n  FDefaultValue := '';\n  FColumnType := stUnknown;\n  FInternalColumnType := stUnknown;\n  FReadOnly := True;\n  FWritable := False;\n  FDefinitelyWritable := False;\nend;\n\n{**\n  Retrieves the designated column's database-specific type name.\n  @return type name used by the database. If the column type is\n    a user-defined type, then a fully-qualified type name is returned.\n}\nfunction TZColumnInfo.GetColumnTypeName: string;\nbegin\n  Result := DefineColumnTypeName(FColumnType);\nend;\n\n{ TZAbstractResultSetMetadata }\n\n{**\n  Constructs this object and assignes the main properties.\n  @param Metadata a database metadata object.\n  @param SQL an SQL query statement.\n  @param ColumnsInfo a collection of columns info.\n}\nconstructor TZAbstractResultSetMetadata.Create(Metadata: IZDatabaseMetadata;\n  SQL: string; ParentResultSet: TZAbstractResultSet);\nbegin\n  inherited Create(ParentResultSet);\n\n  SetMetadata(Metadata);\n  FSQL := SQL;\n  FLoaded := not (FMetadata <> nil);\n  FTableColumns := TZHashMap.Create;\n  FResultSet := ParentResultSet;\nend;\n\n{**\n  Destroys this object and cleanups the memory.\n}\ndestructor TZAbstractResultSetMetadata.Destroy;\nbegin\n  FIdentifierConvertor := nil;\n  FMetadata := nil;\n  if Assigned(FTableColumns) then\n  begin\n    FTableColumns.Clear;\n    FTableColumns.Free;\n  end;\n  FTableColumns := nil;\n  if FColumnsLabels <> nil then\n    FColumnsLabels.Free;\n  inherited Destroy;\nend;\n\n{**\n  Returns the number of columns in this <code>ResultSet</code> object.\n  @return the number of columns\n}\nfunction TZAbstractResultSetMetadata.GetColumnCount: Integer;\nbegin\n  Result := FResultSet.ColumnsInfo.Count;\nend;\n\n{**\n  Indicates whether the designated column is automatically numbered, thus read-only.\n  @param column the first column is 1, the second is 2, ...\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZAbstractResultSetMetadata.IsAutoIncrement(Column: Integer): Boolean;\nbegin\n  if not Loaded then\n     LoadColumns;\n  Result := TZColumnInfo(FResultSet.ColumnsInfo[Column - 1]).AutoIncrement;\nend;\n\n{**\n  Indicates whether a column's case matters.\n  @param column the first column is 1, the second is 2, ...\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZAbstractResultSetMetadata.IsCaseSensitive(Column: Integer): Boolean;\nbegin\n  if not Loaded then\n     LoadColumns;\n  Result := TZColumnInfo(FResultSet.ColumnsInfo[Column - 1]).CaseSensitive;\nend;\n\n{**\n  Indicates whether the designated column can be used in a where clause.\n  @param column the first column is 1, the second is 2, ...\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZAbstractResultSetMetadata.IsSearchable(Column: Integer): Boolean;\nbegin\n  if not Loaded then\n     LoadColumns;\n  Result := TZColumnInfo(FResultSet.ColumnsInfo[Column - 1]).Searchable;\nend;\n\n{**\n  Indicates whether the designated column is a cash value.\n  @param column the first column is 1, the second is 2, ...\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZAbstractResultSetMetadata.IsCurrency(Column: Integer): Boolean;\nbegin\n  Result := TZColumnInfo(FResultSet.ColumnsInfo[Column - 1]).Currency;\nend;\n\n{**\n  Indicates the nullability of values in the designated column.\n  @param column the first column is 1, the second is 2, ...\n  @return the nullability status of the given column; one of <code>columnNoNulls</code>,\n    <code>columnNullable</code> or <code>columnNullableUnknown</code>\n}\nfunction TZAbstractResultSetMetadata.IsNullable(\n  Column: Integer): TZColumnNullableType;\nbegin\n  if not Loaded then\n     LoadColumns;\n  Result := TZColumnInfo(FResultSet.ColumnsInfo[Column - 1]).Nullable;\nend;\n\n{**\n  Indicates whether values in the designated column are signed numbers.\n  @param column the first column is 1, the second is 2, ...\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZAbstractResultSetMetadata.IsSigned(Column: Integer): Boolean;\nbegin\n  Result := TZColumnInfo(FResultSet.ColumnsInfo[Column - 1]).Signed;\nend;\n\n{**\n  Indicates the designated column's normal maximum width in characters.\n  @param column the first column is 1, the second is 2, ...\n  @return the normal maximum number of characters allowed as the width\n    of the designated column\n}\nfunction TZAbstractResultSetMetadata.GetColumnDisplaySize(\n  Column: Integer): Integer;\nbegin\n  Result := TZColumnInfo(FResultSet.ColumnsInfo[Column - 1]).ColumnDisplaySize;\nend;\n\n{**\n  Gets the designated column's suggested title for use in printouts and\n  displays.\n  @param column the first column is 1, the second is 2, ...\n  @return the suggested column title\n}\nfunction TZAbstractResultSetMetadata.GetColumnLabel(Column: Integer): string;\nvar\n  I, J, N: Integer;\n  ColumnName: string;\n  ColumnsInfo: TObjectList;\nbegin\n  { Prepare unique column labels. }\n  if FColumnsLabels = nil then\n  begin\n    ColumnsInfo := FResultSet.ColumnsInfo;\n    FColumnsLabels := TStringList.Create;\n    for I := 0 to ColumnsInfo.Count - 1 do\n    begin\n      N := 0;\n      ColumnName := TZColumnInfo(ColumnsInfo[I]).ColumnLabel;\n      for J := 0 to I - 1 do\n      begin\n        if TZColumnInfo(ColumnsInfo[J]).ColumnLabel = ColumnName then\n          Inc(N);\n      end;\n      if ColumnName = '' then\n        ColumnName := 'Column';\n      if N > 0 then\n        ColumnName := ColumnName + '_' + IntToStr(N);\n      FColumnsLabels.Add(ColumnName);\n    end;\n  end;\n\n  Result := ColumnsLabels[Column - 1];\nend;\n\n{**\n  Get the designated column's name.\n  @param column the first column is 1, the second is 2, ...\n  @return column name\n}\nfunction TZAbstractResultSetMetadata.GetColumnName(\n  Column: Integer): string;\nbegin\n  if not Loaded then\n     LoadColumns;\n  Result := TZColumnInfo(FResultSet.ColumnsInfo[Column - 1]).ColumnName;\nend;\n\n{**\n  Get the designated column's table's schema.\n  @param column the first column is 1, the second is 2, ...\n  @return schema name or \"\" if not applicable\n}\nfunction TZAbstractResultSetMetadata.GetSchemaName(\n  Column: Integer): string;\nbegin\n  if not Loaded then\n     LoadColumns;\n  Result := TZColumnInfo(FResultSet.ColumnsInfo[Column - 1]).SchemaName;\nend;\n\n{**\n  Get the designated column's number of decimal digits.\n  @param column the first column is 1, the second is 2, ...\n  @return precision\n}\nfunction TZAbstractResultSetMetadata.GetPrecision(Column: Integer): Integer;\nbegin\n  Result := TZColumnInfo(FResultSet.ColumnsInfo[Column - 1]).Precision;\nend;\n\n{**\n  Gets the designated column's number of digits to right of the decimal point.\n  @param column the first column is 1, the second is 2, ...\n  @return scale\n}\nfunction TZAbstractResultSetMetadata.GetScale(Column: Integer): Integer;\nbegin\n  Result := TZColumnInfo(FResultSet.ColumnsInfo[Column - 1]).Scale;\nend;\n\n{**\n  Gets the designated column's table name.\n  @param column the first column is 1, the second is 2, ...\n  @return table name or \"\" if not applicable\n}\nfunction TZAbstractResultSetMetadata.GetTableName(Column: Integer): string;\nbegin\n  if not Loaded then\n     LoadColumns;\n  Result := TZColumnInfo(FResultSet.ColumnsInfo[Column - 1]).TableName;\nend;\n\n{**\n  Gets the designated column's table's catalog name.\n  @param column the first column is 1, the second is 2, ...\n  @return column name or \"\" if not applicable\n}\nfunction TZAbstractResultSetMetadata.GetCatalogName(Column: Integer): string;\nbegin\n  if not Loaded then\n     LoadColumns;\n  Result := TZColumnInfo(FResultSet.ColumnsInfo[Column - 1]).CatalogName;\nend;\n\n{**\n  Retrieves the designated column's SQL type.\n  @param column the first column is 1, the second is 2, ...\n  @return SQL type from java.sql.Types\n}\nfunction TZAbstractResultSetMetadata.GetColumnType(Column: Integer): TZSQLType;\nbegin\n  Result := TZColumnInfo(FResultSet.ColumnsInfo[Column - 1]).ColumnType;\nend;\n\n{**\n  Retrieves the designated column's database-specific type name.\n\n  @param column the first column is 1, the second is 2, ...\n  @return type name used by the database. If the column type is\n    a user-defined type, then a fully-qualified type name is returned.\n}\nfunction TZAbstractResultSetMetadata.GetColumnTypeName(Column: Integer): string;\nbegin\n  Result := TZColumnInfo(FResultSet.ColumnsInfo[Column - 1]).GetColumnTypeName;\nend;\n\n{**\n  Indicates whether the designated column is definitely not writable.\n  @param column the first column is 1, the second is 2, ...\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZAbstractResultSetMetadata.IsReadOnly(Column: Integer): Boolean;\nbegin\n  if not Loaded then\n     LoadColumns;\n  Result := TZColumnInfo(FResultSet.ColumnsInfo[Column - 1]).ReadOnly;\nend;\n\n{**\n  Indicates whether it is possible for a write on the designated column to succeed.\n  @param column the first column is 1, the second is 2, ...\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZAbstractResultSetMetadata.IsWritable(Column: Integer): Boolean;\nbegin\n  if not Loaded then\n     LoadColumns;\n  Result := TZColumnInfo(FResultSet.ColumnsInfo[Column - 1]).Writable;\nend;\n\n{**\n  Indicates whether a write on the designated column will definitely succeed.\n  @param column the first column is 1, the second is 2, ...\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZAbstractResultSetMetadata.IsDefinitelyWritable(\n  Column: Integer): Boolean;\nbegin\n  if not Loaded then\n     LoadColumns;\n  Result := TZColumnInfo(FResultSet.ColumnsInfo[Column - 1]).DefinitelyWritable;\nend;\n\n{**\n  Gets a default value for this field.\n  @param column the first column is 1, the second is 2, ...\n  @return a default value for this field.\n}\nfunction TZAbstractResultSetMetadata.GetDefaultValue(\n  Column: Integer): string;\nbegin\n  if not Loaded then\n     LoadColumns;\n  Result := TZColumnInfo(FResultSet.ColumnsInfo[Column - 1]).DefaultValue;\nend;\n\n{**\n  Finds whether this field has a default value.\n  @param column the first column is 1, the second is 2, ...\n  @return true if this field has a default value.\n}\nfunction TZAbstractResultSetMetadata.HasDefaultValue(\n  Column: Integer): Boolean;\nbegin\n  if not Loaded then\n     LoadColumns;\n  // '' = NULL / no default value, '''''' = empty string (''), etc.\n  Result := not(TZColumnInfo(FResultSet.ColumnsInfo[Column - 1]).DefaultValue = '');\nend;\n\n{**\n  Gets a table description result set.\n  @param TableRef a table reference object.\n  @return a result set with table columns from database metadata.\n}\nfunction TZAbstractResultSetMetadata.GetTableColumns(\n  TableRef: TZTableRef): IZResultSet;\nvar\n  TableKey: IZAnyValue;\nbegin\n  TableKey := TZAnyValue.CreateWithString(TableRef.FullName);\n  if FTableColumns.Get(TableKey) = nil then\n  begin\n    Result := Metadata.GetColumns(TableRef.Catalog,\n      TableRef.Schema, TableRef.Table, '');\n    FTableColumns.Put(TableKey, Result);\n  end\n  else\n    Result := FTableColumns.Get(TableKey) as IZResultSet;\nend;\n\n{**\n  Clears specified column information.\n  @param ColumnInfo a column information object.\n}\nprocedure TZAbstractResultSetMetadata.ClearColumn(ColumnInfo: TZColumnInfo);\nbegin\n  ColumnInfo.ReadOnly := True;\n  ColumnInfo.Writable := False;\n  ColumnInfo.DefinitelyWritable := False;\n  ColumnInfo.CatalogName := '';\n  ColumnInfo.SchemaName := '';\n  ColumnInfo.TableName := '';\n  ColumnInfo.ColumnName := '';\nend;\n\n{**\n  Reads a column information from table metadata.\n  @param FieldName a name of the field.\n  @param TableRef a table reference object.\n  @param ColumnInfo a column information object.\n  @return <code>True</code> is column was found and read.\n}\nfunction TZAbstractResultSetMetadata.ReadColumnByName(FieldName: string;\n  TableRef: TZTableRef; ColumnInfo: TZColumnInfo): Boolean;\nvar\n  TableColumns: IZResultSet;\n  tempColType: TZSQLType;\nbegin\n  Result := False;\n  TableColumns := GetTableColumns(TableRef);\n  { Checks for unexisted table. }\n  if not Assigned(TableColumns) then\n    Exit;\n\n  { Locates a column row. }\n  TableColumns.BeforeFirst;\n  while TableColumns.Next do\n    if TableColumns.GetString(4) = FieldName then\n      Break;\n  if TableColumns.IsAfterLast then\n  begin\n    { Locates a column row with case insensitivity. }\n    TableColumns.BeforeFirst;\n    while TableColumns.Next do\n      if AnsiUpperCase(TableColumns.GetString(4)) = AnsiUpperCase(FieldName) then\n        Break;\n    if TableColumns.IsAfterLast then\n      Exit;\n  end;\n\n  { Reads a column information. }\n  Result := True;\n  ColumnInfo.CatalogName := TableColumns.GetString(1);\n  ColumnInfo.SchemaName := TableColumns.GetString(2);\n  ColumnInfo.TableName := TableColumns.GetString(3);\n  ColumnInfo.ColumnName := FieldName;\n\n//If the returned column information is null then the value assigned during\n//the resultset.open will be kept\n  if not TableColumns.IsNull(5) then\n  begin\n    //since Pointer referencing by RowAccessor we've a pointer and GetBlob\n    //raises an exception if the pointer is a reference to PPAnsiChar or\n    //ZPPWideChar. if we execute a cast of a lob field the database meta-informtions\n    //assume a IZLob-Pointer. So let's prevent this case and check for\n    //stByte, stString, stUnicoeString first. If this type is returned from the\n    //ResultSet-Metadata we do NOT overwrite the column-type\n    //f.e. select cast( name as varchar(100)), cast(setting as varchar(100)) from pg_settings\n\n    //or the same vice versa:\n    //(CASE WHEN (Ticket51_B.\"Name\" IS NOT NULL) THEN Ticket51_B.\"Name\" ELSE 'Empty' END) As \"Name\"\n    //we've NO fixed length for a case(postgres and FB2.5up f.e.) select\n    tempColType := TZSQLType(TableColumns.GetShort(5));\n    if not (TZSQLType(TableColumns.GetShort(5)) in [stBinaryStream, stAsciiStream,\n        stUnicodeStream, stBytes, stString, stUnicodeString]) then\n    ColumnInfo.ColumnType := tempColType;\n  end;\n  if not TableColumns.IsNull(11) then\n    ColumnInfo.Nullable := TZColumnNullableType(TableColumns.GetInt(11));\n  if not TableColumns.IsNull(19) then\n    ColumnInfo.AutoIncrement := TableColumns.GetBoolean(19);\n  if not TableColumns.IsNull(20) then\n    ColumnInfo.CaseSensitive := TableColumns.GetBoolean(20);\n  if not TableColumns.IsNull(21) then\n    ColumnInfo.Searchable := TableColumns.GetBoolean(21);\n  if not TableColumns.IsNull(22) then\n    if ColumnInfo.AutoIncrement and Assigned(FMetadata) then {improve ADO where the metainformations do not bring autoincremental fields through}\n      if FMetadata.GetDatabaseInfo.SupportsUpdateAutoIncrementFields then\n        ColumnInfo.Writable := TableColumns.GetBoolean(22)\n      else\n        ColumnInfo.Writable := False\n    else\n      ColumnInfo.Writable := TableColumns.GetBoolean(22);\n  if not TableColumns.IsNull(23) then\n    if ColumnInfo.AutoIncrement and Assigned(FMetadata) then {improve ADO where the metainformations do not bring autoincremental fields through}\n      if FMetadata.GetDatabaseInfo.SupportsUpdateAutoIncrementFields then\n        ColumnInfo.DefinitelyWritable := TableColumns.GetBoolean(23)\n      else\n        ColumnInfo.DefinitelyWritable := False\n    else\n      ColumnInfo.DefinitelyWritable := TableColumns.GetBoolean(23);\n  if not TableColumns.IsNull(24) then\n    if ColumnInfo.AutoIncrement and Assigned(FMetadata) then {improve ADO where the metainformations do not bring autoincremental fields through}\n      if FMetadata.GetDatabaseInfo.SupportsUpdateAutoIncrementFields then\n        ColumnInfo.ReadOnly := TableColumns.GetBoolean(24)\n      else\n        ColumnInfo.ReadOnly := True\n    else\n      ColumnInfo.ReadOnly := TableColumns.GetBoolean(24);\n  if not TableColumns.IsNull(13) then\n    ColumnInfo.DefaultValue := TableColumns.GetString(13);\nend;\n\n{**\n  Reads a column information from table metadata.\n  @param FieldRef a field reference object.\n  @param ColumnInfo a column information object.\n  @return <code>True</code> if column was found and read.\n}\nfunction TZAbstractResultSetMetadata.ReadColumnByRef(\n  FieldRef: TZFieldRef; ColumnInfo: TZColumnInfo): Boolean;\nbegin\n  Result := False;\n  ClearColumn(ColumnInfo);\n  { Checks for uncompleted field reference. }\n  if not Assigned(FieldRef) or not Assigned(FieldRef.TableRef) then\n    Exit;\n  if not FieldRef.IsField then\n    Exit;\n\n  Result := ReadColumnByName(FieldRef.Field, FieldRef.TableRef, ColumnInfo);\nend;\n\n{**\n  Initializes on single column of the result set.\n  @param ColumnIndex a column index in the query.\n  @param ColumnInfo a column information object to be initialized.\n  @param SelectSchema a schema of the select statement.\n}\nprocedure TZAbstractResultSetMetadata.LoadColumn(ColumnIndex: Integer;\n  ColumnInfo: TZColumnInfo; SelectSchema: IZSelectSchema);\nvar\n  I: Integer;\n  FieldRef: TZFieldRef;\n  TableRef: TZTableRef;\n  Found: Boolean;\nbegin\n  { Initializes single columns with specified table. }\n  FieldRef := SelectSchema.LinkFieldByIndexAndShortName(ColumnIndex,\n    ColumnInfo.ColumnLabel, IdentifierConvertor);\n  ReadColumnByRef(FieldRef, ColumnInfo);\n  if ColumnInfo.ColumnName <> '' then\n    Exit;\n\n  { Initializes single columns without specified table. }\n  I := 0;\n  Found := False;\n  while (ColumnInfo.ColumnName = '') and (I < SelectSchema.TableCount)\n    and not Found do\n  begin\n    TableRef := SelectSchema.Tables[I];\n    if Assigned(FieldRef) then\n      Found := ReadColumnByName(IdentifierConvertor.ExtractQuote(FieldRef.Field), TableRef, ColumnInfo)\n    else\n      Found := ReadColumnByName(IdentifierConvertor.ExtractQuote(ColumnInfo.ColumnLabel), TableRef, ColumnInfo);\n    Inc(I);\n  end;\nend;\n\n{**\n  Replaces '*' columns in the select schema.\n  @param SelectSchema a query select schema.\n}\nprocedure TZAbstractResultSetMetadata.ReplaceStarColumns(\n  SelectSchema: IZSelectSchema);\nvar\n  I: Integer;\n  Current: TZFieldRef;\n  FieldRef: TZFieldRef;\n  TableRef: TZTableRef;\n  ResultSet: IZResultSet;\nbegin\n  I := 0;\n  while I < SelectSchema.FieldCount do\n  begin\n    Current := SelectSchema.Fields[I];\n    if (Current.Field = '*') and (Current.TableRef <> nil) then\n    begin\n      TableRef := Current.TableRef;\n      ResultSet := Self.GetTableColumns(TableRef);\n      if ResultSet <> nil then\n      begin\n        ResultSet.BeforeFirst;\n        while ResultSet.Next do\n        begin\n          FieldRef := TZFieldRef.Create(True, TableRef.Catalog, TableRef.Schema,\n            TableRef.Table, ResultSet.GetString(4), '', TableRef);\n          SelectSchema.InsertField(I, FieldRef);\n          Inc(I);\n        end;\n      end;\n      SelectSchema.DeleteField(Current);\n      Dec(I);\n    end;\n    Inc(I);\n  end;\nend;\n\nprocedure TZAbstractResultSetMetadata.SetMetadata(\n  const Value: IZDatabaseMetadata);\nbegin\n  FMetadata := Value;\n  if Value<>nil then\n    FIdentifierConvertor := Value.GetIdentifierConvertor\n  else\n    FIdentifierConvertor := TZDefaultIdentifierConvertor.Create(FMetadata);\nend;\n\n{**\n  Initializes columns with additional data.\n}\nprocedure TZAbstractResultSetMetadata.LoadColumns;\nvar\n  I: Integer;\n  Driver: IZDriver;\n  Tokenizer: IZTokenizer;\n  StatementAnalyser: IZStatementAnalyser;\n  SelectSchema: IZSelectSchema;\n  FillByIndices: Boolean;\nbegin\n  { Parses the Select statement and retrieves a schema object. }\n  Driver := Metadata.GetConnection.GetDriver;\n  Tokenizer := Driver.GetTokenizer;\n  StatementAnalyser := Driver.GetStatementAnalyser;\n  SelectSchema := StatementAnalyser.DefineSelectSchemaFromQuery(Tokenizer, SQL);\n  if Assigned(SelectSchema) then\n  begin\n    SelectSchema.LinkReferences(IdentifierConvertor);\n    ReplaceStarColumns(SelectSchema);\n    FillByIndices := SelectSchema.FieldCount = FResultSet.ColumnsInfo.Count;\n    for I := 0 to FResultSet.ColumnsInfo.Count - 1 do\n    begin\n      if FillByIndices then\n        LoadColumn(I + 1, TZColumnInfo(FResultSet.ColumnsInfo[I]), SelectSchema)\n      else\n        LoadColumn(-1, TZColumnInfo(FResultSet.ColumnsInfo[I]), SelectSchema);\n    end;\n  end;\n  Loaded := True;\nend;\n\nend.\n\n"
  },
  {
    "path": "lib/zeosdbo/src/dbc/ZDbcSqLite.pas",
    "content": "{*********************************************************}\n{                                                         }\n{                 Zeos Database Objects                   }\n{           SQLite Database Connectivity Classes          }\n{                                                         }\n{        Originally written by Sergey Seroukhov           }\n{                                                         }\n{*********************************************************}\n\n{@********************************************************}\n{    Copyright (c) 1999-2012 Zeos Development Group       }\n{                                                         }\n{ License Agreement:                                      }\n{                                                         }\n{ This library is distributed in the hope that it will be }\n{ useful, but WITHOUT ANY WARRANTY; without even the      }\n{ implied warranty of MERCHANTABILITY or FITNESS FOR      }\n{ A PARTICULAR PURPOSE.  See the GNU Lesser General       }\n{ Public License for more details.                        }\n{                                                         }\n{ The source code of the ZEOS Libraries and packages are  }\n{ distributed under the Library GNU General Public        }\n{ License (see the file COPYING / COPYING.ZEOS)           }\n{ with the following  modification:                       }\n{ As a special exception, the copyright holders of this   }\n{ library give you permission to link this library with   }\n{ independent modules to produce an executable,           }\n{ regardless of the license terms of these independent    }\n{ modules, and to copy and distribute the resulting       }\n{ executable under terms of your choice, provided that    }\n{ you also meet, for each linked independent module,      }\n{ the terms and conditions of the license of that module. }\n{ An independent module is a module which is not derived  }\n{ from or based on this library. If you modify this       }\n{ library, you may extend this exception to your version  }\n{ of the library, but you are not obligated to do so.     }\n{ If you do not wish to do so, delete this exception      }\n{ statement from your version.                            }\n{                                                         }\n{                                                         }\n{ The project web site is located on:                     }\n{   http://zeos.firmos.at  (FORUM)                        }\n{   http://sourceforge.net/p/zeoslib/tickets/ (BUGTRACKER)}\n{   svn://svn.code.sf.net/p/zeoslib/code-0/trunk (SVN)    }\n{                                                         }\n{   http://www.sourceforge.net/projects/zeoslib.          }\n{                                                         }\n{                                                         }\n{                                 Zeos Development Group. }\n{********************************************************@}\n\nunit ZDbcSqLite;\n\ninterface\n\n{$I ZDbc.inc}\n\nuses\n  Types, Classes, {$IFDEF MSEgui}mclasses,{$ENDIF} SysUtils,\n  ZDbcIntfs, ZDbcConnection, ZPlainSqLiteDriver, ZDbcLogging, ZTokenizer,\n  ZGenericSqlAnalyser, ZURL, ZPlainDriver, ZCompatibility;\n\ntype\n\n  {** Implements SQLite Database Driver. }\n  {$WARNINGS OFF}\n  TZSQLiteDriver = class(TZAbstractDriver)\n  public\n    constructor Create; override;\n    function Connect(const Url: TZURL): IZConnection; override;\n    function GetMajorVersion: Integer; override;\n    function GetMinorVersion: Integer; override;\n\n    function GetTokenizer: IZTokenizer; override;\n    function GetStatementAnalyser: IZStatementAnalyser; override;\n  end;\n  {$WARNINGS ON}\n\n  {** Represents a SQLite specific connection interface. }\n  IZSQLiteConnection = interface (IZConnection)\n    ['{A4B797A9-7CF7-4DE9-A5BB-693DD32D07D2}']\n    function UseOldBlobEncoding: Boolean;\n    function GetPlainDriver: IZSQLitePlainDriver;\n    function GetConnectionHandle: Psqlite;\n  end;\n\n  {** Implements SQLite Database Connection. }\n\n  { TZSQLiteConnection }\n\n  TZSQLiteConnection = class(TZAbstractConnection, IZSQLiteConnection)\n  private\n    FCatalog: string;\n    FHandle: Psqlite;\n    function UseOldBlobEncoding: Boolean;\n  protected\n    procedure InternalCreate; override;\n    procedure StartTransactionSupport;\n\n  public\n    destructor Destroy; override;\n\n    function CreateRegularStatement(Info: TStrings): IZStatement; override;\n    function CreatePreparedStatement(const SQL: string; Info: TStrings):\n      IZPreparedStatement; override;\n\n    procedure Commit; override;\n    procedure Rollback; override;\n\n    procedure Open; override;\n    procedure Close; override;\n\n    procedure SetCatalog(const Catalog: string); override;\n    function GetCatalog: string; override;\n\n    procedure SetTransactionIsolation(Level: TZTransactIsolationLevel); override;\n\n    function GetClientVersion: Integer; override;\n    function GetHostVersion: Integer; override;\n\n    function GetPlainDriver: IZSQLitePlainDriver;\n    function GetConnectionHandle: Psqlite;\n\n    function ReKey(const Key: string): Integer;\n    function Key(const Key: string): Integer;\n    function GetBinaryEscapeString(const Value: RawByteString): String; overload; override;\n    function GetBinaryEscapeString(const Value: TByteDynArray): String; overload; override;\n    {$IFDEF ZEOS_TEST_ONLY}\n    constructor Create(const ZUrl: TZURL);\n    {$ENDIF}\n  end;\n\nvar\n  {** The common driver manager object. }\n  SQLiteDriver: IZDriver;\n\nimplementation\n\nuses\n  ZSysUtils, ZDbcUtils, ZDbcSqLiteStatement, ZSqLiteToken,\n  ZDbcSqLiteUtils, ZDbcSqLiteMetadata, ZSqLiteAnalyser\n  {$IFDEF WITH_UNITANSISTRINGS}, AnsiStrings{$ENDIF};\n\n{ TZSQLiteDriver }\n\n{**\n  Constructs this object with default properties.\n}\nconstructor TZSQLiteDriver.Create;\nbegin\n  inherited Create;\n  AddSupportedProtocol(AddPlainDriverToCache(TZSQLite3PlainDriver.Create, 'sqlite'));\n  AddSupportedProtocol(AddPlainDriverToCache(TZSQLite3PlainDriver.Create));\nend;\n\n{**\n  Attempts to make a database connection to the given URL.\n  The driver should return \"null\" if it realizes it is the wrong kind\n  of driver to connect to the given URL.  This will be common, as when\n  the JDBC driver manager is asked to connect to a given URL it passes\n  the URL to each loaded driver in turn.\n\n  <P>The driver should raise a SQLException if it is the right\n  driver to connect to the given URL, but has trouble connecting to\n  the database.\n\n  <P>The java.util.Properties argument can be used to passed arbitrary\n  string tag/value pairs as connection arguments.\n  Normally at least \"user\" and \"password\" properties should be\n  included in the Properties.\n\n  @param url the URL of the database to which to connect\n  @param info a list of arbitrary string tag/value pairs as\n    connection arguments. Normally at least a \"user\" and\n    \"password\" property should be included.\n  @return a <code>Connection</code> object that represents a\n    connection to the URL\n}\n{$WARNINGS OFF}\nfunction TZSQLiteDriver.Connect(const Url: TZURL): IZConnection;\nbegin\n  Result := TZSQLiteConnection.Create(Url);\nend;\n{$WARNINGS ON}\n\n{**\n  Gets the driver's major version number. Initially this should be 1.\n  @return this driver's major version number\n}\nfunction TZSQLiteDriver.GetMajorVersion: Integer;\nbegin\n  Result := 1;\nend;\n\n{**\n  Gets the driver's minor version number. Initially this should be 0.\n  @return this driver's minor version number\n}\nfunction TZSQLiteDriver.GetMinorVersion: Integer;\nbegin\n  Result := 0;\nend;\n\n{**\n  Gets a SQL syntax tokenizer.\n  @returns a SQL syntax tokenizer object.\n}\nfunction TZSQLiteDriver.GetTokenizer: IZTokenizer;\nbegin\n  if Tokenizer = nil then\n    Tokenizer := TZSQLiteTokenizer.Create;\n  Result := Tokenizer;\nend;\n\n{**\n  Creates a statement analyser object.\n  @returns a statement analyser object.\n}\nfunction TZSQLiteDriver.GetStatementAnalyser: IZStatementAnalyser;\nbegin\n  if Analyser = nil then\n    Analyser := TZSQLiteStatementAnalyser.Create;\n  Result := Analyser;\nend;\n\n{ TZSQLiteConnection }\n\n{**\n  Constructs this object and assignes the main properties.\n}\nprocedure TZSQLiteConnection.InternalCreate;\nbegin\n  FMetadata := TZSQLiteDatabaseMetadata.Create(Self, Url);\n  AutoCommit := True;\n  TransactIsolationLevel := tiNone;\n  CheckCharEncoding('UTF-8');\n  Open;\nend;\n\n{**\n  Destroys this object and cleanups the memory.\n}\ndestructor TZSQLiteConnection.Destroy;\nbegin\n  inherited Destroy;\nend;\n\nfunction TZSQLiteConnection.UseOldBlobEncoding: Boolean;\nbegin\n  Result := Url.Properties.Values['OldBlobEncoding'] = 'True';\nend;\n\n{**\n  Set encryption key for a database\n  @param Key the key used to encrypt your database.\n  @return error code from SQLite Key function.\n}\nfunction TZSQLiteConnection.Key(const Key: string):Integer;\nvar\n  ErrorCode: Integer;\nbegin\n  {$IFDEF UNICODE}\n  ErrorCode := GetPlainDriver.Key(FHandle, PAnsiChar(UTF8String(Key)), {$IFDEF WITH_STRLEN_DEPRECATED}AnsiStrings.{$ENDIF}StrLen(PAnsiChar(UTF8String(Key))));\n  {$ELSE}\n  ErrorCode := GetPlainDriver.Key(FHandle, PAnsiChar(Key), StrLen(PAnsiChar(Key)));\n  {$ENDIF}\n  Result := ErrorCode;\nend;\n\n{**\n  Reencrypt a database with a new key. The old/current key needs to be\n  set before calling this function.\n  @param Key the new key used to encrypt your database.\n  @return error code from SQLite ReKey function.\n}\nfunction TZSQLiteConnection.ReKey(const Key: string):Integer;\nvar\n  ErrorCode: Integer;\nbegin\n  {$IFDEF UNICODE}\n  ErrorCode := GetPlainDriver.ReKey(FHandle, PAnsiChar(UTF8String(Key)), {$IFDEF WITH_STRLEN_DEPRECATED}AnsiStrings.{$ENDIF}StrLen(PAnsiChar(UTF8String(Key))));\n  {$ELSE}\n  ErrorCode := GetPlainDriver.ReKey(FHandle, PAnsiChar(Key), StrLen(PAnsiChar(Key)));\n  {$ENDIF}\n  Result := ErrorCode;\nend;\n\n{**\n  Opens a connection to database server with specified parameters.\n}\nprocedure TZSQLiteConnection.Open;\nvar\n  ErrorCode: Integer;\n  ErrorMessage: PAnsiChar;\n  LogMessage: string;\n  SQL: AnsiString;\n  Timeout_ms: Integer;\nbegin\n  if not Closed then\n    Exit;\n  ErrorMessage := '';\n\n  LogMessage := Format('CONNECT TO \"%s\" AS USER \"%s\"', [Database, User]);\n\n{$IFDEF UNICODE}\n  FHandle := GetPlainDriver.Open(PAnsiChar(AnsiString(UTF8Encode(Database))), 0, ErrorMessage);\n{$ELSE}\n  FHandle := GetPlainDriver.Open(PAnsiChar(Database), 0, ErrorMessage);\n{$ENDIF}\n\n  if FHandle = nil then\n  begin\n    CheckSQLiteError(GetPlainDriver, FHandle, SQLITE_ERROR, ErrorMessage,\n      lcConnect, LogMessage);\n  end;\n  DriverManager.LogMessage(lcConnect, PlainDriver.GetProtocol, LogMessage);\n\n  { Turn on encryption if requested }\n  if StrToBoolEx(Info.Values['encrypted']) then\n  begin\n    {$IFDEF UNICODE}\n    ErrorCode := GetPlainDriver.Key(FHandle, PAnsiChar(UTF8String(Password)), {$IFDEF WITH_STRLEN_DEPRECATED}AnsiStrings.{$ENDIF}StrLen(PAnsiChar(UTF8String(Password))));\n    {$ELSE}\n    ErrorCode := GetPlainDriver.Key(FHandle, PAnsiChar(Password), StrLen(PAnsiChar(Password)));\n    {$ENDIF}\n    CheckSQLiteError(GetPlainDriver, FHandle, ErrorCode, nil, lcConnect, 'SQLite.Key');\n  end;\n\n  { Set busy timeout if requested }\n  Timeout_ms := StrToIntDef(Info.Values['busytimeout'], -1); \n  if Timeout_ms >= 0 then \n  begin \n    GetPlainDriver.BusyTimeout(FHandle, Timeout_ms);\n  end; \n\n  try\n    if ( FClientCodePage <> '' ) then\n    begin\n        SQL := 'PRAGMA encoding = '''+AnsiString(FClientCodePage)+'''';\n        ErrorCode := GetPlainDriver.Execute(FHandle, PAnsiChar(SQL),\n          nil, nil, ErrorMessage);\n        CheckSQLiteError(GetPlainDriver, FHandle, ErrorCode, ErrorMessage, lcExecute, String(SQL));\n    end;\n\n    SQL := 'PRAGMA show_datatypes = ON';\n    ErrorCode := GetPlainDriver.Execute(FHandle, PAnsiChar(SQL),\n      nil, nil, ErrorMessage);\n    CheckSQLiteError(GetPlainDriver, FHandle, ErrorCode, ErrorMessage, lcExecute, String(SQL));\n\n    if Info.Values['foreign_keys'] <> '' then\n    begin\n      if StrToBoolEx(Info.Values['foreign_keys']) then\n        SQL := 'PRAGMA foreign_keys = 1'\n      else\n        SQL := 'PRAGMA foreign_keys = 0';\n      ErrorCode := GetPlainDriver.Execute(FHandle, PAnsiChar(SQL), nil, nil, ErrorMessage);\n      CheckSQLiteError(GetPlainDriver, FHandle, ErrorCode, ErrorMessage, lcExecute, String(SQL));\n      DriverManager.LogMessage(lcConnect, GetPlainDriver.GetProtocol, String(SQL));\n    end;\n    StartTransactionSupport;\n  except\n    GetPlainDriver.Close(FHandle);\n    FHandle := nil;\n    raise;\n  end;\n\n  inherited Open;\nend;\n\n{**\n  Creates a <code>Statement</code> object for sending\n  SQL statements to the database.\n  SQL statements without parameters are normally\n  executed using Statement objects. If the same SQL statement\n  is executed many times, it is more efficient to use a\n  <code>PreparedStatement</code> object.\n  <P>\n  Result sets created using the returned <code>Statement</code>\n  object will by default have forward-only type and read-only concurrency.\n\n  @param Info a statement parameters.\n  @return a new Statement object\n}\nfunction TZSQLiteConnection.CreateRegularStatement(Info: TStrings):\n  IZStatement;\nbegin\n  if IsClosed then\n    Open;\n  Result := TZSQLiteStatement.Create(GetPlainDriver, Self, Info, FHandle);\nend;\n\n{**\n  Creates a <code>PreparedStatement</code> object for sending\n  parameterized SQL statements to the database.\n\n  A SQL statement with or without IN parameters can be\n  pre-compiled and stored in a PreparedStatement object. This\n  object can then be used to efficiently execute this statement\n  multiple times.\n\n  <P><B>Note:</B> This method is optimized for handling\n  parametric SQL statements that benefit from precompilation. If\n  the driver supports precompilation,\n  the method <code>prepareStatement</code> will send\n  the statement to the database for precompilation. Some drivers\n  may not support precompilation. In this case, the statement may\n  not be sent to the database until the <code>PreparedStatement</code> is\n  executed.  This has no direct effect on users; however, it does\n  affect which method throws certain SQLExceptions.\n\n  Result sets created using the returned PreparedStatement will have\n  forward-only type and read-only concurrency, by default.\n\n  @param sql a SQL statement that may contain one or more '?' IN\n    parameter placeholders\n  @param Info a statement parameters.\n  @return a new PreparedStatement object containing the\n    pre-compiled statement\n}\nfunction TZSQLiteConnection.CreatePreparedStatement(const SQL: string;\n  Info: TStrings): IZPreparedStatement;\nbegin\n  if IsClosed then\n    Open;\n  {$IFDEF ZEOS_TEST_ONLY}\n  Case GetTestMode of\n    0:\n  {$ENDIF}\n      Result := TZSQLiteCAPIPreparedStatement.Create(GetPlainDriver, Self, SQL, Info, FHandle);\n  {$IFDEF ZEOS_TEST_ONLY}\n    1: Result := TZSQLitePreparedStatement.Create(GetPlainDriver, Self, SQL, Info, FHandle);\n  end;\n  {$ENDIF}\nend;\n\n{**\n  Starts a transaction support.\n}\nprocedure TZSQLiteConnection.StartTransactionSupport;\nvar\n  ErrorCode: Integer;\n  ErrorMessage: PAnsiChar;\n  SQL: String;\nbegin\n  if TransactIsolationLevel <> tiNone then\n  begin\n    ErrorMessage := '';\n    SQL := 'BEGIN TRANSACTION';\n    ErrorCode := GetPlainDriver.Execute(FHandle, PAnsiChar(AnsiString(SQL)), nil, nil,\n      ErrorMessage);\n    CheckSQLiteError(GetPlainDriver, FHandle, ErrorCode, ErrorMessage, lcExecute, SQL);\n    DriverManager.LogMessage(lcExecute, PlainDriver.GetProtocol, SQL);\n  end;\nend;\n\n{**\n  Makes all changes made since the previous\n  commit/rollback permanent and releases any database locks\n  currently held by the Connection. This method should be\n  used only when auto-commit mode has been disabled.\n  @see #setAutoCommit\n}\nprocedure TZSQLiteConnection.Commit;\nvar\n  ErrorCode: Integer;\n  ErrorMessage: PAnsiChar;\n  SQL: PAnsiChar;\nbegin\n  if (TransactIsolationLevel <> tiNone) and not Closed then\n  begin\n    ErrorMessage := '';\n    SQL := 'COMMIT TRANSACTION';\n    ErrorCode := GetPlainDriver.Execute(FHandle, PAnsiChar(SQL), nil, nil,\n      ErrorMessage);\n    CheckSQLiteError(GetPlainDriver, FHandle, ErrorCode, ErrorMessage, lcExecute, String(SQL));\n    DriverManager.LogMessage(lcExecute, PlainDriver.GetProtocol, String(SQL));\n\n    StartTransactionSupport;\n  end;\nend;\n\n{**\n  Drops all changes made since the previous\n  commit/rollback and releases any database locks currently held\n  by this Connection. This method should be used only when auto-\n  commit has been disabled.\n  @see #setAutoCommit\n}\nprocedure TZSQLiteConnection.Rollback;\nvar\n  ErrorCode: Integer;\n  ErrorMessage: PAnsiChar;\n  SQL: String;\nbegin\n  if (TransactIsolationLevel <> tiNone) and not Closed then\n  begin\n    ErrorMessage := '';\n    SQL := 'ROLLBACK TRANSACTION';\n    ErrorCode := GetPlainDriver.Execute(FHandle, PAnsiChar(AnsiString(SQL)), nil, nil,\n      ErrorMessage);\n    CheckSQLiteError(GetPlainDriver, FHandle, ErrorCode, ErrorMessage, lcExecute, SQL);\n    DriverManager.LogMessage(lcExecute, PlainDriver.GetProtocol, SQL);\n\n    StartTransactionSupport;\n  end;\nend;\n\n{**\n  Releases a Connection's database and JDBC resources\n  immediately instead of waiting for\n  them to be automatically released.\n\n  <P><B>Note:</B> A Connection is automatically closed when it is\n  garbage collected. Certain fatal errors also result in a closed\n  Connection.\n}\nprocedure TZSQLiteConnection.Close;\nvar\n  LogMessage: string;\n  ErrorCode: Integer;\nbegin\n  if ( Closed ) or (not Assigned(PlainDriver)) then\n    Exit;\n\n  LogMessage := 'DISCONNECT FROM \"'+Database+'\"';\n  if Assigned(DriverManager) then\n    DriverManager.LogMessage(lcDisconnect, PlainDriver.GetProtocol, LogMessage);\n  ErrorCode := GetPlainDriver.Close(FHandle);\n  CheckSQLiteError(GetPlainDriver, FHandle, ErrorCode, nil,\n    lcOther, LogMessage);\n  FHandle := nil;\n  inherited Close;\nend;\n\n{**\n  Gets a selected catalog name.\n  @return a selected catalog name.\n}\nfunction TZSQLiteConnection.GetCatalog: string;\nbegin\n  Result := FCatalog;\nend;\n\nfunction TZSQLiteConnection.GetClientVersion: Integer;\nbegin\n  Result := ConvertSQLiteVersionToSQLVersion(GetPlainDriver.LibVersion);\nend;\n\n{**\n  Sets a new selected catalog name.\n  @param Catalog a selected catalog name.\n}\nprocedure TZSQLiteConnection.SetCatalog(const Catalog: string);\nbegin\n  FCatalog := Catalog;\nend;\n\n{**\n  Sets a new transact isolation level.\n  @param Level a new transact isolation level.\n}\nprocedure TZSQLiteConnection.SetTransactionIsolation(\n  Level: TZTransactIsolationLevel);\nvar\n  ErrorCode: Integer;\n  ErrorMessage: PAnsiChar;\n  SQL: String;\nbegin\n  if (TransactIsolationLevel <> tiNone) and not Closed then\n  begin\n    ErrorMessage := '';\n    SQL := 'ROLLBACK TRANSACTION';\n    ErrorCode := GetPlainDriver.Execute(FHandle, PAnsiChar(AnsiString(SQL)), nil, nil,\n      ErrorMessage);\n    CheckSQLiteError(GetPlainDriver, FHandle, ErrorCode, ErrorMessage, lcExecute, SQL);\n    DriverManager.LogMessage(lcExecute, PlainDriver.GetProtocol, SQL);\n  end;\n\n  inherited SetTransactionIsolation(Level);\n\n  if not Closed then\n    StartTransactionSupport;\nend;\n\n{**\n  Gets a reference to SQLite connection handle.\n  @return a reference to SQLite connection handle.\n}\nfunction TZSQLiteConnection.GetConnectionHandle: Psqlite;\nbegin\n  Result := FHandle;\nend;\n\n{**\n  Gets a SQLite plain driver interface.\n  @return a SQLite plain driver interface.\n}\nfunction TZSQLiteConnection.GetPlainDriver: IZSQLitePlainDriver;\nbegin\n  Result := PlainDriver as IZSQLitePlainDriver;\nend;\n\n{**\n  EgonHugeist:\n  Returns the BinaryString in a Tokenizer-detectable kind\n  If the Tokenizer don't need to predetect it Result := BinaryString\n  @param Value represents the Binary-String\n  @param EscapeMarkSequence represents a Tokenizer detectable EscapeSequence (Len >= 3)\n  @result the detectable Binary String\n}\nfunction TZSQLiteConnection.GetBinaryEscapeString(const Value: RawByteString): String;\nbegin\n  if GetAutoEncodeStrings then\n    Result := GetDriver.GetTokenizer.AnsiGetEscapeString(ZDbcSqLiteUtils.EncodeString(PAnsiChar(Value), Length(Value)))\n  else\n    Result := String(ZDbcSqLiteUtils.EncodeString(PAnsiChar(Value), Length(Value)));\nend;\n\n{**\n  EgonHugeist:\n  Returns the BinaryString in a Tokenizer-detectable kind\n  If the Tokenizer don't need to predetect it Result := BinaryString\n  @param Value represents the Binary-String\n  @param EscapeMarkSequence represents a Tokenizer detectable EscapeSequence (Len >= 3)\n  @result the detectable Binary String\n}\nfunction TZSQLiteConnection.GetBinaryEscapeString(const Value: TByteDynArray): String;\nbegin\n  if GetAutoEncodeStrings then\n    Result := GetDriver.GetTokenizer.AnsiGetEscapeString(ZDbcSqLiteUtils.EncodeString(PAnsiChar(Value), Length(Value)))\n  else\n    Result := String(ZDbcSqLiteUtils.EncodeString(PAnsiChar(Value), Length(Value)));\nend;\n\n{$IFDEF ZEOS_TEST_ONLY}\nconstructor TZSQLiteConnection.Create(const ZUrl: TZURL);\nbegin\n  inherited Create(ZUrl);\n end;\n {$ENDIF}\n\nfunction TZSQLiteConnection.GetHostVersion: Integer;\nbegin\n  Result := ConvertSQLiteVersionToSQLVersion(GetPlainDriver.LibVersion);\nend;\n\ninitialization\n  SQLiteDriver := TZSQLiteDriver.Create;\n  DriverManager.RegisterDriver(SQLiteDriver);\nfinalization\n  if DriverManager <> nil then\n    DriverManager.DeregisterDriver(SQLiteDriver);\n  SQLiteDriver := nil;\nend.\n\n"
  },
  {
    "path": "lib/zeosdbo/src/dbc/ZDbcSqLiteMetadata.pas",
    "content": "{*********************************************************}\n{                                                         }\n{                 Zeos Database Objects                   }\n{          SQLite Database Connectivity Classes           }\n{                                                         }\n{        Originally written by Sergey Seroukhov           }\n{                                                         }\n{*********************************************************}\n\n{@********************************************************}\n{    Copyright (c) 1999-2012 Zeos Development Group       }\n{                                                         }\n{ License Agreement:                                      }\n{                                                         }\n{ This library is distributed in the hope that it will be }\n{ useful, but WITHOUT ANY WARRANTY; without even the      }\n{ implied warranty of MERCHANTABILITY or FITNESS FOR      }\n{ A PARTICULAR PURPOSE.  See the GNU Lesser General       }\n{ Public License for more details.                        }\n{                                                         }\n{ The source code of the ZEOS Libraries and packages are  }\n{ distributed under the Library GNU General Public        }\n{ License (see the file COPYING / COPYING.ZEOS)           }\n{ with the following  modification:                       }\n{ As a special exception, the copyright holders of this   }\n{ library give you permission to link this library with   }\n{ independent modules to produce an executable,           }\n{ regardless of the license terms of these independent    }\n{ modules, and to copy and distribute the resulting       }\n{ executable under terms of your choice, provided that    }\n{ you also meet, for each linked independent module,      }\n{ the terms and conditions of the license of that module. }\n{ An independent module is a module which is not derived  }\n{ from or based on this library. If you modify this       }\n{ library, you may extend this exception to your version  }\n{ of the library, but you are not obligated to do so.     }\n{ If you do not wish to do so, delete this exception      }\n{ statement from your version.                            }\n{                                                         }\n{                                                         }\n{ The project web site is located on:                     }\n{   http://zeos.firmos.at  (FORUM)                        }\n{   http://sourceforge.net/p/zeoslib/tickets/ (BUGTRACKER)}\n{   svn://svn.code.sf.net/p/zeoslib/code-0/trunk (SVN)    }\n{                                                         }\n{   http://www.sourceforge.net/projects/zeoslib.          }\n{                                                         }\n{                                                         }\n{                                 Zeos Development Group. }\n{********************************************************@}\n\nunit ZDbcSqLiteMetadata;\n\ninterface\n\n{$I ZDbc.inc}\n\nuses\n  Types, Classes, SysUtils, ZSysUtils, ZDbcIntfs, ZDbcMetadata,\n  ZCompatibility, ZDbcSQLiteUtils, ZDbcConnection;\n\ntype\n\n  // technobot 2008-06-28 - methods moved as is from TZSQLiteDatabaseMetadata:\n  {** Implements SQLite Database Information. }\n  TZSQLiteDatabaseInfo = class(TZAbstractDatabaseInfo)\n//    function UncachedGetUDTs(const Catalog: string; const SchemaPattern: string;\n//      const TypeNamePattern: string; const Types: TIntegerDynArray): IZResultSet; override;\n  public\n    // database/driver/server info:\n    function GetDatabaseProductName: string; override;\n    function GetDatabaseProductVersion: string; override;\n    function GetDriverName: string; override;\n//    function GetDriverVersion: string; override; -> Same as parent\n    function GetDriverMajorVersion: Integer; override;\n    function GetDriverMinorVersion: Integer; override;\n//    function GetServerVersion: string; -> Not implemented\n\n    // capabilities (what it can/cannot do):\n//    function AllProceduresAreCallable: Boolean; override; -> Not implemented\n//    function AllTablesAreSelectable: Boolean; override; -> Not implemented\n    function SupportsMixedCaseIdentifiers: Boolean; override;\n    function SupportsMixedCaseQuotedIdentifiers: Boolean; override;\n//    function SupportsAlterTableWithAddColumn: Boolean; override; -> Not implemented\n//    function SupportsAlterTableWithDropColumn: Boolean; override; -> Not implemented\n//    function SupportsColumnAliasing: Boolean; override; -> Not implemented\n//    function SupportsConvert: Boolean; override; -> Not implemented\n//    function SupportsConvertForTypes(FromType: TZSQLType; ToType: TZSQLType):\n//      Boolean; override; -> Not implemented\n//    function SupportsTableCorrelationNames: Boolean; override; -> Not implemented\n//    function SupportsDifferentTableCorrelationNames: Boolean; override; -> Not implemented\n    function SupportsExpressionsInOrderBy: Boolean; override;\n    function SupportsOrderByUnrelated: Boolean; override;\n    function SupportsGroupBy: Boolean; override;\n    function SupportsGroupByUnrelated: Boolean; override;\n    function SupportsGroupByBeyondSelect: Boolean; override;\n//    function SupportsLikeEscapeClause: Boolean; override; -> Not implemented\n//    function SupportsMultipleResultSets: Boolean; override; -> Not implemented\n//    function SupportsMultipleTransactions: Boolean; override; -> Not implemented\n//    function SupportsNonNullableColumns: Boolean; override; -> Not implemented\n//    function SupportsMinimumSQLGrammar: Boolean; override; -> Not implemented\n//    function SupportsCoreSQLGrammar: Boolean; override; -> Not implemented\n//    function SupportsExtendedSQLGrammar: Boolean; override; -> Not implemented\n//    function SupportsANSI92EntryLevelSQL: Boolean; override; -> Not implemented\n//    function SupportsANSI92IntermediateSQL: Boolean; override; -> Not implemented\n//    function SupportsANSI92FullSQL: Boolean; override; -> Not implemented\n    function SupportsIntegrityEnhancementFacility: Boolean; override;\n//    function SupportsOuterJoins: Boolean; override; -> Not implemented\n//    function SupportsFullOuterJoins: Boolean; override; -> Not implemented\n//    function SupportsLimitedOuterJoins: Boolean; override; -> Not implemented\n    function SupportsSchemasInDataManipulation: Boolean; override;\n    function SupportsSchemasInProcedureCalls: Boolean; override;\n    function SupportsSchemasInTableDefinitions: Boolean; override;\n    function SupportsSchemasInIndexDefinitions: Boolean; override;\n    function SupportsSchemasInPrivilegeDefinitions: Boolean; override;\n    function SupportsCatalogsInDataManipulation: Boolean; override;\n    function SupportsCatalogsInProcedureCalls: Boolean; override;\n    function SupportsCatalogsInTableDefinitions: Boolean; override;\n    function SupportsCatalogsInIndexDefinitions: Boolean; override;\n    function SupportsCatalogsInPrivilegeDefinitions: Boolean; override;\n    function SupportsPositionedDelete: Boolean; override;\n    function SupportsPositionedUpdate: Boolean; override;\n    function SupportsSelectForUpdate: Boolean; override;\n    function SupportsStoredProcedures: Boolean; override;\n    function SupportsSubqueriesInComparisons: Boolean; override;\n    function SupportsSubqueriesInExists: Boolean; override;\n    function SupportsSubqueriesInIns: Boolean; override;\n    function SupportsSubqueriesInQuantifieds: Boolean; override;\n    function SupportsCorrelatedSubqueries: Boolean; override;\n    function SupportsUnion: Boolean; override;\n    function SupportsUnionAll: Boolean; override;\n    function SupportsOpenCursorsAcrossCommit: Boolean; override;\n    function SupportsOpenCursorsAcrossRollback: Boolean; override;\n    function SupportsOpenStatementsAcrossCommit: Boolean; override;\n    function SupportsOpenStatementsAcrossRollback: Boolean; override;\n    function SupportsTransactions: Boolean; override;\n    function SupportsTransactionIsolationLevel(Level: TZTransactIsolationLevel):\n      Boolean; override;\n    function SupportsDataDefinitionAndDataManipulationTransactions: Boolean; override;\n    function SupportsDataManipulationTransactionsOnly: Boolean; override;\n    function SupportsResultSetType(_Type: TZResultSetType): Boolean; override;\n    function SupportsResultSetConcurrency(_Type: TZResultSetType;\n      Concurrency: TZResultSetConcurrency): Boolean; override;\n//    function SupportsBatchUpdates: Boolean; override; -> Not implemented\n\n    // maxima:\n    function GetMaxBinaryLiteralLength: Integer; override;\n    function GetMaxCharLiteralLength: Integer; override;\n    function GetMaxColumnNameLength: Integer; override;\n    function GetMaxColumnsInGroupBy: Integer; override;\n    function GetMaxColumnsInIndex: Integer; override;\n    function GetMaxColumnsInOrderBy: Integer; override;\n    function GetMaxColumnsInSelect: Integer; override;\n    function GetMaxColumnsInTable: Integer; override;\n    function GetMaxConnections: Integer; override;\n    function GetMaxCursorNameLength: Integer; override;\n    function GetMaxIndexLength: Integer; override;\n    function GetMaxSchemaNameLength: Integer; override;\n    function GetMaxProcedureNameLength: Integer; override;\n    function GetMaxCatalogNameLength: Integer; override;\n    function GetMaxRowSize: Integer; override;\n    function GetMaxStatementLength: Integer; override;\n    function GetMaxStatements: Integer; override;\n    function GetMaxTableNameLength: Integer; override;\n    function GetMaxTablesInSelect: Integer; override;\n    function GetMaxUserNameLength: Integer; override;\n\n    // policies (how are various data and operations handled):\n//    function IsReadOnly: Boolean; override; -> Not implemented\n//    function IsCatalogAtStart: Boolean; override; -> Not implemented\n    function DoesMaxRowSizeIncludeBlobs: Boolean; override;\n//    function NullsAreSortedHigh: Boolean; override; -> Not implemented\n//    function NullsAreSortedLow: Boolean; override; -> Not implemented\n//    function NullsAreSortedAtStart: Boolean; override; -> Not implemented\n//    function NullsAreSortedAtEnd: Boolean; override; -> Not implemented\n//    function NullPlusNonNullIsNull: Boolean; override; -> Not implemented\n//    function UsesLocalFiles: Boolean; override; -> Not implemented\n    function UsesLocalFilePerTable: Boolean; override;\n    function StoresUpperCaseIdentifiers: Boolean; override;\n    function StoresLowerCaseIdentifiers: Boolean; override;\n    function StoresMixedCaseIdentifiers: Boolean; override;\n    function StoresUpperCaseQuotedIdentifiers: Boolean; override;\n    function StoresLowerCaseQuotedIdentifiers: Boolean; override;\n    function StoresMixedCaseQuotedIdentifiers: Boolean; override;\n    function GetDefaultTransactionIsolation: TZTransactIsolationLevel; override;\n    function DataDefinitionCausesTransactionCommit: Boolean; override;\n    function DataDefinitionIgnoredInTransactions: Boolean; override;\n\n    // interface details (terms, keywords, etc):\n//    function GetIdentifierQuoteString: string; override; -> Not implemented\n    function GetSchemaTerm: string; override;\n    function GetProcedureTerm: string; override;\n    function GetCatalogTerm: string; override;\n    function GetCatalogSeparator: string; override;\n    function GetSQLKeywords: string; override;\n    function GetNumericFunctions: string; override;\n    function GetStringFunctions: string; override;\n    function GetSystemFunctions: string; override;\n    function GetTimeDateFunctions: string; override;\n    function GetSearchStringEscape: string; override;\n    function GetExtraNameCharacters: string; override;\n  end;\n\n  {** Implements SQLite Database Metadata. }\n  TZSQLiteDatabaseMetadata = class(TZAbstractDatabaseMetadata)\n  protected\n    function DeComposeObjectString(const S: String): String; reintroduce;\n    function CreateDatabaseInfo: IZDatabaseInfo; override; // technobot 2008-06-28\n\n    function UncachedGetTables(const Catalog: string; const SchemaPattern: string;\n      const TableNamePattern: string; const Types: TStringDynArray): IZResultSet; override;\n//    function UncachedGetSchemas: IZResultSet; override;  -> not implemented\n//    function UncachedGetCatalogs: IZResultSet; override;  -> not implemented\n    function UncachedGetTableTypes: IZResultSet; override;\n    function UncachedGetColumns(const Catalog: string; const SchemaPattern: string;\n      const TableNamePattern: string; const ColumnNamePattern: string): IZResultSet; override;\n//    function UncachedGetTablePrivileges(const Catalog: string; const SchemaPattern: string;  -> not implemented\n//      const TableNamePattern: string): IZResultSet; override;\n//    function UncachedGetColumnPrivileges(const Catalog: string; const Schema: string;  -> not implemented\n//      const Table: string; const ColumnNamePattern: string): IZResultSet; override;\n    function UncachedGetPrimaryKeys(const Catalog: string; const Schema: string;\n      const Table: string): IZResultSet; override;\n//    function UncachedGetImportedKeys(const Catalog: string; const Schema: string;\n//      const Table: string): IZResultSet; override;\n//    function UncachedGetExportedKeys(const Catalog: string; const Schema: string;\n//      const Table: string): IZResultSet; override;\n//    function UncachedGetCrossReference(const PrimaryCatalog: string; const PrimarySchema: string;\n//      const PrimaryTable: string; const ForeignCatalog: string; const ForeignSchema: string;\n//      const ForeignTable: string): IZResultSet; override;\n    function UncachedGetIndexInfo(const Catalog: string; const Schema: string; const Table: string;\n      Unique: Boolean; Approximate: Boolean): IZResultSet; override;\n//     function UncachedGetSequences(const Catalog: string; const SchemaPattern: string;\n//      const SequenceNamePattern: string): IZResultSet; virtual; -> Not implemented\n//    function UncachedGetProcedures(const Catalog: string; const SchemaPattern: string;\n//      const ProcedureNamePattern: string): IZResultSet; override;\n//    function UncachedGetProcedureColumns(const Catalog: string; const SchemaPattern: string;\n//      const ProcedureNamePattern: string; const ColumnNamePattern: string):\n//      IZResultSet; override;\n//    function UncachedGetVersionColumns(const Catalog: string; const Schema: string;\n//      const Table: string): IZResultSet; override;\n    function UncachedGetTypeInfo: IZResultSet; override;\n    function UncachedGetCharacterSets: IZResultSet; override; //EgonHugeist\n  public\n    destructor Destroy; override;\n  end;\n\nimplementation\n\nuses\n  ZDbcUtils;\n\n{ TZSQLiteDatabaseInfo }\n\n//----------------------------------------------------------------------\n// First, a variety of minor information about the target database.\n\n{**\n  What's the name of this database product?\n  @return database product name\n}\nfunction TZSQLiteDatabaseInfo.GetDatabaseProductName: string;\nbegin\n  Result := 'SQLite';\nend;\n\n{**\n  What's the version of this database product?\n  @return database version\n}\nfunction TZSQLiteDatabaseInfo.GetDatabaseProductVersion: string;\nbegin\n  Result := '';\nend;\n\n{**\n  What's the name of this JDBC driver?\n  @return JDBC driver name\n}\nfunction TZSQLiteDatabaseInfo.GetDriverName: string;\nbegin\n  Result := 'Zeos Database Connectivity Driver for SQLite';\nend;\n\n{**\n  What's this JDBC driver's major version number?\n  @return JDBC driver major version\n}\nfunction TZSQLiteDatabaseInfo.GetDriverMajorVersion: Integer;\nbegin\n  Result := 1;\nend;\n\n{**\n  What's this JDBC driver's minor version number?\n  @return JDBC driver minor version number\n}\nfunction TZSQLiteDatabaseInfo.GetDriverMinorVersion: Integer;\nbegin\n  Result := 0;\nend;\n\n{**\n  Does the database use a file for each table?\n  @return true if the database uses a local file for each table\n}\nfunction TZSQLiteDatabaseInfo.UsesLocalFilePerTable: Boolean;\nbegin\n  Result := False;\nend;\n\n{**\n  Does the database treat mixed case unquoted SQL identifiers as\n  case sensitive and as a result store them in mixed case?\n  A JDBC Compliant<sup><font size=-2>TM</font></sup> driver will always return false.\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZSQLiteDatabaseInfo.SupportsMixedCaseIdentifiers: Boolean;\nbegin\n  Result := True;\nend;\n\n{**\n  Does the database treat mixed case unquoted SQL identifiers as\n  case insensitive and store them in upper case?\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZSQLiteDatabaseInfo.StoresUpperCaseIdentifiers: Boolean;\nbegin\n  Result := False;\nend;\n\n{**\n  Does the database treat mixed case unquoted SQL identifiers as\n  case insensitive and store them in lower case?\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZSQLiteDatabaseInfo.StoresLowerCaseIdentifiers: Boolean;\nbegin\n  Result := False;\nend;\n\n{**\n  Does the database treat mixed case unquoted SQL identifiers as\n  case insensitive and store them in mixed case?\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZSQLiteDatabaseInfo.StoresMixedCaseIdentifiers: Boolean;\nbegin\n  Result := True;\nend;\n\n{**\n  Does the database treat mixed case quoted SQL identifiers as\n  case sensitive and as a result store them in mixed case?\n  A JDBC Compliant<sup><font size=-2>TM</font></sup> driver will always return true.\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZSQLiteDatabaseInfo.SupportsMixedCaseQuotedIdentifiers: Boolean;\nbegin\n  Result := True;\nend;\n\n{**\n  Does the database treat mixed case quoted SQL identifiers as\n  case insensitive and store them in upper case?\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZSQLiteDatabaseInfo.StoresUpperCaseQuotedIdentifiers: Boolean;\nbegin\n  Result := False;\nend;\n\n{**\n  Does the database treat mixed case quoted SQL identifiers as\n  case insensitive and store them in lower case?\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZSQLiteDatabaseInfo.StoresLowerCaseQuotedIdentifiers: Boolean;\nbegin\n  Result := False;\nend;\n\n{**\n  Does the database treat mixed case quoted SQL identifiers as\n  case insensitive and store them in mixed case?\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZSQLiteDatabaseInfo.StoresMixedCaseQuotedIdentifiers: Boolean;\nbegin\n  Result := True;\nend;\n\n{**\n  Gets a comma-separated list of all a database's SQL keywords\n  that are NOT also SQL92 keywords.\n  @return the list\n}\nfunction TZSQLiteDatabaseInfo.GetSQLKeywords: string;\nbegin\n  Result := 'ALL,AND,AS,BETWEEN,BY,CASE,CHECK,COLLATE,COMMIT,CONSTRAINT,CREATE,'\n    + 'DEFAULT,DEFERRABLE,DELETE,DISTINCT,DROP,ELSE,EXCEPT,FOREIGN,FROM,GLOB,'\n    + 'GROUP,HAVING,IN,INDEX,INSERT,INTERSECT,INTO,IS,ISNULL,JOIN,LIKE,LIMIT,'\n    + 'NOT,NOTNULL,NULL,ON,OR,ORDER,PRIMARY,REFERENCES,ROLLBACK,SELECT,SET,'\n    + 'TABLE,THEN,TRANSACTION,UNION,UNIQUE,UPDATE,USING,VALUES,WHEN,WHERE,'\n    + 'ABORT,AFTER,ASC,ATTACH,BEFORE,BEGIN,DEFERRED,CASCADE,CLUSTER,CONFLICT,'\n    + 'COPY,CROSS,DATABASE,DELIMITERS,DESC,DETACH,EACH,END,EXPLAIN,FAIL,FOR,'\n    + 'FULL,IGNORE,IMMEDIATE,INITIALLY,INNER,INSTEAD,KEY,LEFT,MATCH,NATURAL,'\n    + 'OF,OFFSET,OUTER,PRAGMA,RAISE,REPLACE,RESTRICT,RIGHT,ROW,STATEMENT,'\n    + 'TEMP,TEMPORARY,TRIGGER,VACUUM,VIEW';\nend;\n\n{**\n  Gets a comma-separated list of math functions.  These are the\n  X/Open CLI math function names used in the JDBC function escape\n  clause.\n  @return the list\n}\nfunction TZSQLiteDatabaseInfo.GetNumericFunctions: string;\nbegin\n  Result := 'ABS,MAX,MIN,RANDOM,ROUND';\nend;\n\n{**\n  Gets a comma-separated list of string functions.  These are the\n  X/Open CLI string function names used in the JDBC function escape\n  clause.\n  @return the list\n}\nfunction TZSQLiteDatabaseInfo.GetStringFunctions: string;\nbegin\n  Result := 'LENGTH,LIKE,LOWER,SOUNDEX,SUBSTRING,UPPER';\nend;\n\n{**\n  Gets a comma-separated list of system functions.  These are the\n  X/Open CLI system function names used in the JDBC function escape\n  clause.\n  @return the list\n}\nfunction TZSQLiteDatabaseInfo.GetSystemFunctions: string;\nbegin\n  Result := 'LAST_INSERT_ROWID,SQLITE_VERSION,TYPEOF';\nend;\n\n{**\n  Gets a comma-separated list of time and date functions.\n  @return the list\n}\nfunction TZSQLiteDatabaseInfo.GetTimeDateFunctions: string;\nbegin\n  Result := '';\nend;\n\n{**\n  Gets the string that can be used to escape wildcard characters.\n  This is the string that can be used to escape '_' or '%' in\n  the string pattern style catalog search parameters.\n\n  <P>The '_' character represents any single character.\n  <P>The '%' character represents any sequence of zero or\n  more characters.\n\n  @return the string used to escape wildcard characters\n}\nfunction TZSQLiteDatabaseInfo.GetSearchStringEscape: string;\nbegin\n  Result := '//';\nend;\n\n{**\n  Gets all the \"extra\" characters that can be used in unquoted\n  identifier names (those beyond a-z, A-Z, 0-9 and _).\n  @return the string containing the extra characters\n}\nfunction TZSQLiteDatabaseInfo.GetExtraNameCharacters: string;\nbegin\n  Result := '';\nend;\n\n//--------------------------------------------------------------------\n// Functions describing which features are supported.\n\n{**\n  Are expressions in \"ORDER BY\" lists supported?\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZSQLiteDatabaseInfo.SupportsExpressionsInOrderBy: Boolean;\nbegin\n  Result := False;\nend;\n\n{**\n  Can an \"ORDER BY\" clause use columns not in the SELECT statement?\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZSQLiteDatabaseInfo.SupportsOrderByUnrelated: Boolean;\nbegin\n  Result := False;\nend;\n\n{**\n  Is some form of \"GROUP BY\" clause supported?\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZSQLiteDatabaseInfo.SupportsGroupBy: Boolean;\nbegin\n  Result := True;\nend;\n\n{**\n  Can a \"GROUP BY\" clause use columns not in the SELECT?\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZSQLiteDatabaseInfo.SupportsGroupByUnrelated: Boolean;\nbegin\n  Result := True;\nend;\n\n{**\n  Can a \"GROUP BY\" clause add columns not in the SELECT\n  provided it specifies all the columns in the SELECT?\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZSQLiteDatabaseInfo.SupportsGroupByBeyondSelect: Boolean;\nbegin\n  Result := True;\nend;\n\n{**\n  Is the SQL Integrity Enhancement Facility supported?\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZSQLiteDatabaseInfo.SupportsIntegrityEnhancementFacility: Boolean;\nbegin\n  Result := False;\nend;\n\n{**\n  What's the database vendor's preferred term for \"schema\"?\n  @return the vendor term\n}\nfunction TZSQLiteDatabaseInfo.GetSchemaTerm: string;\nbegin\n  Result := '';\nend;\n\n{**\n  What's the database vendor's preferred term for \"procedure\"?\n  @return the vendor term\n}\nfunction TZSQLiteDatabaseInfo.GetProcedureTerm: string;\nbegin\n  Result := '';\nend;\n\n{**\n  What's the database vendor's preferred term for \"catalog\"?\n  @return the vendor term\n}\nfunction TZSQLiteDatabaseInfo.GetCatalogTerm: string;\nbegin\n  Result := 'database';\nend;\n\n{**\n  What's the separator between catalog and table name?\n  @return the separator string\n}\nfunction TZSQLiteDatabaseInfo.GetCatalogSeparator: string;\nbegin\n  Result := '.';\nend;\n\n{**\n  Can a schema name be used in a data manipulation statement?\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZSQLiteDatabaseInfo.SupportsSchemasInDataManipulation: Boolean;\nbegin\n  Result := True;\nend;\n\n{**\n  Can a schema name be used in a procedure call statement?\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZSQLiteDatabaseInfo.SupportsSchemasInProcedureCalls: Boolean;\nbegin\n  Result := False;\nend;\n\n{**\n  Can a schema name be used in a table definition statement?\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZSQLiteDatabaseInfo.SupportsSchemasInTableDefinitions: Boolean;\nbegin\n  Result := False;\nend;\n\n{**\n  Can a schema name be used in an index definition statement?\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZSQLiteDatabaseInfo.SupportsSchemasInIndexDefinitions: Boolean;\nbegin\n  Result := False;\nend;\n\n{**\n  Can a schema name be used in a privilege definition statement?\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZSQLiteDatabaseInfo.SupportsSchemasInPrivilegeDefinitions: Boolean;\nbegin\n  Result := False;\nend;\n\n{**\n  Can a catalog name be used in a data manipulation statement?\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZSQLiteDatabaseInfo.SupportsCatalogsInDataManipulation: Boolean;\nbegin\n  Result := True;\nend;\n\n{**\n  Can a catalog name be used in a procedure call statement?\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZSQLiteDatabaseInfo.SupportsCatalogsInProcedureCalls: Boolean;\nbegin\n  Result := False;\nend;\n\n{**\n  Can a catalog name be used in a table definition statement?\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZSQLiteDatabaseInfo.SupportsCatalogsInTableDefinitions: Boolean;\nbegin\n  Result := False;\nend;\n\n{**\n  Can a catalog name be used in an index definition statement?\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZSQLiteDatabaseInfo.SupportsCatalogsInIndexDefinitions: Boolean;\nbegin\n  Result := False;\nend;\n\n{**\n  Can a catalog name be used in a privilege definition statement?\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZSQLiteDatabaseInfo.SupportsCatalogsInPrivilegeDefinitions: Boolean;\nbegin\n  Result := True;\nend;\n\n{**\n  Is positioned DELETE supported?\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZSQLiteDatabaseInfo.SupportsPositionedDelete: Boolean;\nbegin\n  Result := False;\nend;\n\n{**\n  Is positioned UPDATE supported?\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZSQLiteDatabaseInfo.SupportsPositionedUpdate: Boolean;\nbegin\n  Result := False;\nend;\n\n{**\n  Is SELECT for UPDATE supported?\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZSQLiteDatabaseInfo.SupportsSelectForUpdate: Boolean;\nbegin\n  Result := False;\nend;\n\n{**\n  Are stored procedure calls using the stored procedure escape\n  syntax supported?\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZSQLiteDatabaseInfo.SupportsStoredProcedures: Boolean;\nbegin\n  Result := False;\nend;\n\n{**\n  Are subqueries in comparison expressions supported?\n  A JDBC Compliant<sup><font size=-2>TM</font></sup> driver always returns true.\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZSQLiteDatabaseInfo.SupportsSubqueriesInComparisons: Boolean;\nbegin\n  Result := True;\nend;\n\n{**\n  Are subqueries in 'exists' expressions supported?\n  A JDBC Compliant<sup><font size=-2>TM</font></sup> driver always returns true.\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZSQLiteDatabaseInfo.SupportsSubqueriesInExists: Boolean;\nbegin\n  Result := True;\nend;\n\n{**\n  Are subqueries in 'in' statements supported?\n  A JDBC Compliant<sup><font size=-2>TM</font></sup> driver always returns true.\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZSQLiteDatabaseInfo.SupportsSubqueriesInIns: Boolean;\nbegin\n  Result := True;\nend;\n\n{**\n  Are subqueries in quantified expressions supported?\n  A JDBC Compliant<sup><font size=-2>TM</font></sup> driver always returns true.\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZSQLiteDatabaseInfo.SupportsSubqueriesInQuantifieds: Boolean;\nbegin\n  Result := True;\nend;\n\n{**\n  Are correlated subqueries supported?\n  A JDBC Compliant<sup><font size=-2>TM</font></sup> driver always returns true.\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZSQLiteDatabaseInfo.SupportsCorrelatedSubqueries: Boolean;\nbegin\n  Result := True;\nend;\n\n{**\n  Is SQL UNION supported?\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZSQLiteDatabaseInfo.SupportsUnion: Boolean;\nbegin\n  Result := True;\nend;\n\n{**\n  Is SQL UNION ALL supported?\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZSQLiteDatabaseInfo.SupportsUnionAll: Boolean;\nbegin\n  Result := True;\nend;\n\n{**\n  Can cursors remain open across commits?\n  @return <code>true</code> if cursors always remain open;\n        <code>false</code> if they might not remain open\n}\nfunction TZSQLiteDatabaseInfo.SupportsOpenCursorsAcrossCommit: Boolean;\nbegin\n  Result := False;\nend;\n\n{**\n  Can cursors remain open across rollbacks?\n  @return <code>true</code> if cursors always remain open;\n        <code>false</code> if they might not remain open\n}\nfunction TZSQLiteDatabaseInfo.SupportsOpenCursorsAcrossRollback: Boolean;\nbegin\n  Result := False;\nend;\n\n{**\n  Can statements remain open across commits?\n  @return <code>true</code> if statements always remain open;\n        <code>false</code> if they might not remain open\n}\nfunction TZSQLiteDatabaseInfo.SupportsOpenStatementsAcrossCommit: Boolean;\nbegin\n  Result := False;\nend;\n\n{**\n  Can statements remain open across rollbacks?\n  @return <code>true</code> if statements always remain open;\n        <code>false</code> if they might not remain open\n}\nfunction TZSQLiteDatabaseInfo.SupportsOpenStatementsAcrossRollback: Boolean;\nbegin\n  Result := False;\nend;\n\n//----------------------------------------------------------------------\n// The following group of methods exposes various limitations\n// based on the target database with the current driver.\n// Unless otherwise specified, a result of zero means there is no\n// limit, or the limit is not known.\n\n{**\n  How many hex characters can you have in an inline binary literal?\n  @return max binary literal length in hex characters;\n       a result of zero means that there is no limit or the limit is not known\n}\nfunction TZSQLiteDatabaseInfo.GetMaxBinaryLiteralLength: Integer;\nbegin\n  Result := 0;\nend;\n\n{**\n  What's the max length for a character literal?\n  @return max literal length;\n       a result of zero means that there is no limit or the limit is not known\n}\nfunction TZSQLiteDatabaseInfo.GetMaxCharLiteralLength: Integer;\nbegin\n  Result := 0;\nend;\n\n{**\n  What's the limit on column name length?\n  @return max column name length;\n       a result of zero means that there is no limit or the limit is not known\n}\nfunction TZSQLiteDatabaseInfo.GetMaxColumnNameLength: Integer;\nbegin\n  Result := 0;\nend;\n\n{**\n  What's the maximum number of columns in a \"GROUP BY\" clause?\n  @return max number of columns;\n       a result of zero means that there is no limit or the limit is not known\n}\nfunction TZSQLiteDatabaseInfo.GetMaxColumnsInGroupBy: Integer;\nbegin\n  Result := 0;\nend;\n\n{**\n  What's the maximum number of columns allowed in an index?\n  @return max number of columns;\n       a result of zero means that there is no limit or the limit is not known\n}\nfunction TZSQLiteDatabaseInfo.GetMaxColumnsInIndex: Integer;\nbegin\n  Result := 0;\nend;\n\n{**\n  What's the maximum number of columns in an \"ORDER BY\" clause?\n  @return max number of columns;\n       a result of zero means that there is no limit or the limit is not known\n}\nfunction TZSQLiteDatabaseInfo.GetMaxColumnsInOrderBy: Integer;\nbegin\n  Result := 0;\nend;\n\n{**\n  What's the maximum number of columns in a \"SELECT\" list?\n  @return max number of columns;\n       a result of zero means that there is no limit or the limit is not known\n}\nfunction TZSQLiteDatabaseInfo.GetMaxColumnsInSelect: Integer;\nbegin\n  Result := 0;\nend;\n\n{**\n  What's the maximum number of columns in a table?\n  @return max number of columns;\n       a result of zero means that there is no limit or the limit is not known\n}\nfunction TZSQLiteDatabaseInfo.GetMaxColumnsInTable: Integer;\nbegin\n  Result := 0;\nend;\n\n{**\n  How many active connections can we have at a time to this database?\n  @return max number of active connections;\n       a result of zero means that there is no limit or the limit is not known\n}\nfunction TZSQLiteDatabaseInfo.GetMaxConnections: Integer;\nbegin\n  Result := 0;\nend;\n\n{**\n  What's the maximum cursor name length?\n  @return max cursor name length in bytes;\n       a result of zero means that there is no limit or the limit is not known\n}\nfunction TZSQLiteDatabaseInfo.GetMaxCursorNameLength: Integer;\nbegin\n  Result := 0;\nend;\n\n{**\n  Retrieves the maximum number of bytes for an index, including all\n  of the parts of the index.\n  @return max index length in bytes, which includes the composite of all\n   the constituent parts of the index;\n   a result of zero means that there is no limit or the limit is not known\n}\nfunction TZSQLiteDatabaseInfo.GetMaxIndexLength: Integer;\nbegin\n  Result := 0;\nend;\n\n{**\n  What's the maximum length allowed for a schema name?\n  @return max name length in bytes;\n       a result of zero means that there is no limit or the limit is not known\n}\nfunction TZSQLiteDatabaseInfo.GetMaxSchemaNameLength: Integer;\nbegin\n  Result := 0;\nend;\n\n{**\n  What's the maximum length of a procedure name?\n  @return max name length in bytes;\n       a result of zero means that there is no limit or the limit is not known\n}\nfunction TZSQLiteDatabaseInfo.GetMaxProcedureNameLength: Integer;\nbegin\n  Result := 0;\nend;\n\n{**\n  What's the maximum length of a catalog name?\n  @return max name length in bytes;\n       a result of zero means that there is no limit or the limit is not known\n}\nfunction TZSQLiteDatabaseInfo.GetMaxCatalogNameLength: Integer;\nbegin\n  Result := 0;\nend;\n\n{**\n  What's the maximum length of a single row?\n  @return max row size in bytes;\n       a result of zero means that there is no limit or the limit is not known\n}\nfunction TZSQLiteDatabaseInfo.GetMaxRowSize: Integer;\nbegin\n  Result := 0;\nend;\n\n{**\n  Did getMaxRowSize() include LONGVARCHAR and LONGVARBINARY\n  blobs?\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZSQLiteDatabaseInfo.DoesMaxRowSizeIncludeBlobs: Boolean;\nbegin\n  Result := True;\nend;\n\n{**\n  What's the maximum length of an SQL statement?\n  @return max length in bytes;\n       a result of zero means that there is no limit or the limit is not known\n}\nfunction TZSQLiteDatabaseInfo.GetMaxStatementLength: Integer;\nbegin\n  Result := 65535;\nend;\n\n{**\n  How many active statements can we have open at one time to this\n  database?\n  @return the maximum number of statements that can be open at one time;\n       a result of zero means that there is no limit or the limit is not known\n}\nfunction TZSQLiteDatabaseInfo.GetMaxStatements: Integer;\nbegin\n  Result := 0;\nend;\n\n{**\n  What's the maximum length of a table name?\n  @return max name length in bytes;\n       a result of zero means that there is no limit or the limit is not known\n}\nfunction TZSQLiteDatabaseInfo.GetMaxTableNameLength: Integer;\nbegin\n  Result := 0;\nend;\n\n{**\n  What's the maximum number of tables in a SELECT statement?\n  @return the maximum number of tables allowed in a SELECT statement;\n       a result of zero means that there is no limit or the limit is not known\n}\nfunction TZSQLiteDatabaseInfo.GetMaxTablesInSelect: Integer;\nbegin\n  Result := 0;\nend;\n\n{**\n  What's the maximum length of a user name?\n  @return max user name length  in bytes;\n       a result of zero means that there is no limit or the limit is not known\n}\nfunction TZSQLiteDatabaseInfo.GetMaxUserNameLength: Integer;\nbegin\n  Result := 0;\nend;\n\n//----------------------------------------------------------------------\n\n{**\n  What's the database's default transaction isolation level?  The\n  values are defined in <code>java.sql.Connection</code>.\n  @return the default isolation level\n  @see Connection\n}\nfunction TZSQLiteDatabaseInfo.GetDefaultTransactionIsolation:\n  TZTransactIsolationLevel;\nbegin\n  Result := tiNone;\nend;\n\n{**\n  Are transactions supported? If not, invoking the method\n  <code>commit</code> is a noop and the isolation level is TRANSACTION_NONE.\n  @return <code>true</code> if transactions are supported; <code>false</code> otherwise\n}\nfunction TZSQLiteDatabaseInfo.SupportsTransactions: Boolean;\nbegin\n  Result := True;\nend;\n\n{**\n  Does this database support the given transaction isolation level?\n  @param level the values are defined in <code>java.sql.Connection</code>\n  @return <code>true</code> if so; <code>false</code> otherwise\n  @see Connection\n}\nfunction TZSQLiteDatabaseInfo.SupportsTransactionIsolationLevel(\n  Level: TZTransactIsolationLevel): Boolean;\nbegin\n  Result := True;\nend;\n\n{**\n  Are both data definition and data manipulation statements\n  within a transaction supported?\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZSQLiteDatabaseInfo.\n  SupportsDataDefinitionAndDataManipulationTransactions: Boolean;\nbegin\n  Result := True;\nend;\n\n{**\n  Are only data manipulation statements within a transaction\n  supported?\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZSQLiteDatabaseInfo.\n  SupportsDataManipulationTransactionsOnly: Boolean;\nbegin\n  Result := True;\nend;\n\n{**\n  Does a data definition statement within a transaction force the\n  transaction to commit?\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZSQLiteDatabaseInfo.DataDefinitionCausesTransactionCommit: Boolean;\nbegin\n  Result := True;\nend;\n\n{**\n  Is a data definition statement within a transaction ignored?\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZSQLiteDatabaseInfo.DataDefinitionIgnoredInTransactions: Boolean;\nbegin\n  Result := False;\nend;\n\n{**\n  Does the database support the given result set type?\n  @param type defined in <code>java.sql.ResultSet</code>\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZSQLiteDatabaseInfo.SupportsResultSetType(\n  _Type: TZResultSetType): Boolean;\nbegin\n  Result := _Type = rtForwardOnly;\nend;\n\n{**\n  Does the database support the concurrency type in combination\n  with the given result set type?\n\n  @param type defined in <code>java.sql.ResultSet</code>\n  @param concurrency type defined in <code>java.sql.ResultSet</code>\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\nfunction TZSQLiteDatabaseInfo.SupportsResultSetConcurrency(\n  _Type: TZResultSetType; Concurrency: TZResultSetConcurrency): Boolean;\nbegin\n  Result := (_Type = rtForwardOnly) and (Concurrency = rcReadOnly);\nend;\n\n\n{ TZSQLiteDatabaseMetadata }\n\n{**\n  Decomposes a object name, AnsiQuotedStr or NullText\n  @param S the object string\n  @return a non-quoted string\n}\nfunction TZSQLiteDatabaseMetadata.DecomposeObjectString(const S: String): String;\nbegin\n  if S = '' then\n    Result := S\n  else\n    if IC.IsQuoted(S) then\n       Result := IC.ExtractQuote(S)\n    else\n      Result := s;\nend;\n\n{**\n  Destroys this object and cleanups the memory.\n}\ndestructor TZSQLiteDatabaseMetadata.Destroy;\nbegin\n  inherited Destroy;\nend;\n\n{**\n  Constructs a database information object and returns the interface to it. Used\n  internally by the constructor.\n  @return the database information object interface\n}\nfunction TZSQLiteDatabaseMetadata.CreateDatabaseInfo: IZDatabaseInfo;\nbegin\n  Result := TZSQLiteDatabaseInfo.Create(Self);\nend;\n\n{**\n  Gets a description of tables available in a catalog.\n\n  <P>Only table descriptions matching the catalog, schema, table\n  name and type criteria are returned.  They are ordered by\n  TABLE_TYPE, TABLE_SCHEM and TABLE_NAME.\n\n  <P>Each table description has the following columns:\n   <OL>\n \t<LI><B>TABLE_CAT</B> String => table catalog (may be null)\n \t<LI><B>TABLE_SCHEM</B> String => table schema (may be null)\n \t<LI><B>TABLE_NAME</B> String => table name\n \t<LI><B>TABLE_TYPE</B> String => table type.  Typical types are \"TABLE\",\n \t\t\t\"VIEW\",\t\"SYSTEM TABLE\", \"GLOBAL TEMPORARY\",\n \t\t\t\"LOCAL TEMPORARY\", \"ALIAS\", \"SYNONYM\".\n \t<LI><B>REMARKS</B> String => explanatory comment on the table\n   </OL>\n\n  <P><B>Note:</B> Some databases may not return information for\n  all tables.\n\n  @param catalog a catalog name; \"\" retrieves those without a\n  catalog; null means drop catalog name from the selection criteria\n  @param schemaPattern a schema name pattern; \"\" retrieves those\n  without a schema\n  @param tableNamePattern a table name pattern\n  @param types a list of table types to include; null returns all types\n  @return <code>ResultSet</code> - each row is a table description\n  @see #getSearchStringEscape\n}\nfunction TZSQLiteDatabaseMetadata.UncachedGetTables(const Catalog: string;\n  const SchemaPattern: string; const TableNamePattern: string;\n  const Types: TStringDynArray): IZResultSet;\nvar\n  WhereClause, SQL: string;\n\n  function IncludedType(TypeName: string): Boolean;\n  var I: Integer;\n  begin\n    Result := False;\n    for I := Low(Types) to High(Types) do\n      Result := Result or (UpperCase(Types[I]) = TypeName);\n    Result := Result or (Length(Types) = 0);\n  end;\n\nbegin\n    WhereClause := '';\n    if IncludedType('TABLE') then\n      WhereClause := 'TYPE=''table''';\n    if IncludedType('VIEW') then\n    begin\n      if WhereClause <> '' then\n        WhereClause := '(' + WhereClause + ' OR TYPE=''view'')'\n      else WhereClause := 'TYPE=''view''';\n    end;\n\n    SQL := 'SELECT ''' + Catalog + ''' AS TABLE_CAT, NULL AS TABLE_SCHEM,'\n      + ' TBL_NAME AS TABLE_NAME, UPPER(TYPE) AS TABLE_TYPE, NULL AS REMARKS'\n      + ' FROM ';\n    if Catalog <> '' then\n      SQL := SQL + Catalog + '.';\n    SQL := SQL + 'SQLITE_MASTER WHERE ' + WhereClause\n      + ' AND TBL_NAME LIKE ''' + ToLikeString(TableNamePattern) + '''';\n\n    Result := CopyToVirtualResultSet(\n      GetConnection.CreateStatement.ExecuteQuery(SQL),\n      ConstructVirtualResultSet(TableColumnsDynArray));\nend;\n\n{**\n  Gets the table types available in this database.  The results\n  are ordered by table type.\n\n  <P>The table type is:\n   <OL>\n \t<LI><B>TABLE_TYPE</B> String => table type.  Typical types are \"TABLE\",\n \t\t\t\"VIEW\",\t\"SYSTEM TABLE\", \"GLOBAL TEMPORARY\",\n \t\t\t\"LOCAL TEMPORARY\", \"ALIAS\", \"SYNONYM\".\n   </OL>\n\n  @return <code>ResultSet</code> - each row has a single String column that is a\n  table type\n}\nfunction TZSQLiteDatabaseMetadata.UncachedGetTableTypes: IZResultSet;\nconst\n  TableTypeCount = 2;\n  Types: array [1..TableTypeCount] of string = ('TABLE', 'VIEW');\nvar\n  I: Integer;\nbegin\n  Result:=inherited UncachedGetTableTypes;\n\n  for I := 1 to TableTypeCount do\n    begin\n      Result.MoveToInsertRow;\n      Result.UpdateString(1, Types[I]);\n      Result.InsertRow;\n    end;\nend;\n\n{**\n  Gets a description of table columns available in\n  the specified catalog.\n\n  <P>Only column descriptions matching the catalog, schema, table\n  and column name criteria are returned.  They are ordered by\n  TABLE_SCHEM, TABLE_NAME and ORDINAL_POSITION.\n\n  <P>Each column description has the following columns:\n   <OL>\n \t<LI><B>TABLE_CAT</B> String => table catalog (may be null)\n \t<LI><B>TABLE_SCHEM</B> String => table schema (may be null)\n \t<LI><B>TABLE_NAME</B> String => table name\n \t<LI><B>COLUMN_NAME</B> String => column name\n \t<LI><B>DATA_TYPE</B> short => SQL type from java.sql.Types\n \t<LI><B>TYPE_NAME</B> String => Data source dependent type name,\n   for a UDT the type name is fully qualified\n \t<LI><B>COLUMN_SIZE</B> int => column size.  For char or date\n \t    types this is the maximum number of characters, for numeric or\n \t    decimal types this is precision.\n \t<LI><B>BUFFER_LENGTH</B> is not used.\n \t<LI><B>DECIMAL_DIGITS</B> int => the number of fractional digits\n \t<LI><B>NUM_PREC_RADIX</B> int => Radix (typically either 10 or 2)\n \t<LI><B>NULLABLE</B> int => is NULL allowed?\n       <UL>\n       <LI> columnNoNulls - might not allow NULL values\n       <LI> columnNullable - definitely allows NULL values\n       <LI> columnNullableUnknown - nullability unknown\n       </UL>\n \t<LI><B>REMARKS</B> String => comment describing column (may be null)\n  \t<LI><B>COLUMN_DEF</B> String => default value (may be null)\n \t<LI><B>SQL_DATA_TYPE</B> int => unused\n \t<LI><B>SQL_DATETIME_SUB</B> int => unused\n \t<LI><B>CHAR_OCTET_LENGTH</B> int => for char types the\n        maximum number of bytes in the column\n \t<LI><B>ORDINAL_POSITION</B> int\t=> index of column in table\n       (starting at 1)\n \t<LI><B>IS_NULLABLE</B> String => \"NO\" means column definitely\n       does not allow NULL values; \"YES\" means the column might\n       allow NULL values.  An empty string means nobody knows.\n   </OL>\n\n  @param catalog a catalog name; \"\" retrieves those without a\n  catalog; null means drop catalog name from the selection criteria\n  @param schemaPattern a schema name pattern; \"\" retrieves those\n  without a schema\n  @param tableNamePattern a table name pattern\n  @param columnNamePattern a column name pattern\n  @return <code>ResultSet</code> - each row is a column description\n  @see #getSearchStringEscape\n}\nfunction TZSQLiteDatabaseMetadata.UncachedGetColumns(const Catalog: string;\n  const SchemaPattern: string; const TableNamePattern: string;\n  const ColumnNamePattern: string): IZResultSet;\nvar\n  Temp: string;\n  Precision, Decimals: Integer;\n  Temp_scheme: string;\n  ResSet: IZResultSet;\n  TempTableNamePattern: String;\nbegin\n  Result:=inherited UncachedGetColumns(Catalog, SchemaPattern, TableNamePattern, ColumnNamePattern);\n\n  if SchemaPattern = '' then\n    Temp_scheme := '' // OR  'main.'\n  else\n    Temp_scheme := SchemaPattern +'.';\n\n  TempTableNamePattern := NormalizePatternCase(TableNamePattern);\n  ResSet := GetConnection.CreateStatement.ExecuteQuery(\n    Format('PRAGMA %s table_info(''%s'')', [Temp_scheme, TempTableNamePattern]));\n  if ResSet <> nil then\n    with ResSet do\n  begin\n    while Next do\n    begin\n      Result.MoveToInsertRow;\n      if SchemaPattern <> '' then\n        Result.UpdateString(1, SchemaPattern)\n      else Result.UpdateNull(1);\n      Result.UpdateNull(2);\n      Result.UpdateString(3, TempTableNamePattern);\n      Result.UpdateString(4, GetString(2));\n      Result.UpdateInt(5, Ord(ConvertSQLiteTypeToSQLType(GetString(3),\n        Precision, Decimals, ConSettings.CPType)));\n\n      { Defines a table name. }\n      Temp := UpperCase(GetString(3));\n      if Pos('(', Temp) > 0 then\n        Temp := Copy(Temp, 1, Pos('(', Temp) - 1);\n      Result.UpdateString(6, Temp);\n\n      Result.UpdateInt(7, Precision);  //Precision will be converted higher up\n      Result.UpdateNull(8);\n      Result.UpdateInt(9, Decimals);\n      Result.UpdateInt(10, 0);\n\n      if GetInt(4) <> 0 then\n      begin\n        Result.UpdateInt(11, Ord(ntNoNulls));\n        Result.UpdateString(18, 'NO');\n      end\n      else\n      begin\n        Result.UpdateInt(11, Ord(ntNullable));\n        Result.UpdateString(18, 'YES');\n      end;\n\n      Result.UpdateNull(12);\n      if Trim(GetString(5)) <> '' then\n        Result.UpdateString(13, GetString(5))\n  //          Result.UpdateString(13, '''' + GetString(5) + '''')\n      else Result.UpdateNull(13);\n      Result.UpdateNull(14);\n      Result.UpdateNull(15);\n      Result.UpdateNull(16);\n      Result.UpdateInt(17, GetInt(1) + 1);\n\n      Result.UpdateBooleanByName('AUTO_INCREMENT',\n        (GetInt(6) = 1) and (Temp = 'INTEGER'));\n      Result.UpdateBooleanByName('CASE_SENSITIVE', False);\n      Result.UpdateBooleanByName('SEARCHABLE', True);\n      Result.UpdateBooleanByName('WRITABLE', True);\n      Result.UpdateBooleanByName('DEFINITELYWRITABLE', True);\n      Result.UpdateBooleanByName('READONLY', False);\n\n      Result.InsertRow;\n    end;\n    Close;\n  end;\nend;\n\n{**\n  Gets a description of a table's primary key columns.  They\n  are ordered by COLUMN_NAME.\n\n  <P>Each primary key column description has the following columns:\n   <OL>\n \t<LI><B>TABLE_CAT</B> String => table catalog (may be null)\n \t<LI><B>TABLE_SCHEM</B> String => table schema (may be null)\n \t<LI><B>TABLE_NAME</B> String => table name\n \t<LI><B>COLUMN_NAME</B> String => column name\n \t<LI><B>KEY_SEQ</B> short => sequence number within primary key\n \t<LI><B>PK_NAME</B> String => primary key name (may be null)\n   </OL>\n\n  @param catalog a catalog name; \"\" retrieves those without a\n  catalog; null means drop catalog name from the selection criteria\n  @param schema a schema name; \"\" retrieves those\n  without a schema\n  @param table a table name\n  @return <code>ResultSet</code> - each row is a primary key column description\n  @exception SQLException if a database access error occurs\n}\nfunction TZSQLiteDatabaseMetadata.UncachedGetPrimaryKeys(const Catalog: string;\n  const Schema: string; const Table: string): IZResultSet;\nvar\n  Index: Integer;\n  Temp_scheme: string;\nbegin\n    Result:=inherited UncachedGetPrimaryKeys(Catalog, Schema, Table);\n\n    if Schema = '' then\n      Temp_scheme := '' // OR  'main.'\n    else\n      Temp_scheme := Schema +'.';\n\n    with GetConnection.CreateStatement.ExecuteQuery(\n      Format('PRAGMA %s table_info(''%s'')', [Temp_scheme,Table])) do\n    begin\n      Index := 1;\n      while Next do\n      begin\n        if GetInt(6) = 0 then\n          Continue;\n\n        Result.MoveToInsertRow;\n        if Schema <> '' then\n          Result.UpdateString(1, Schema)\n        else Result.UpdateNull(1);\n        Result.UpdateNull(2);\n        Result.UpdateString(3, Table);\n        Result.UpdateString(4, GetString(2));\n        Result.UpdateInt(5, Index);\n        Result.UpdateNull(6);\n\n        Inc(Index);\n\n        Result.InsertRow;\n      end;\n      Close;\n    end;\nend;\n\n{**\n  Gets a description of all the standard SQL types supported by\n  this database. They are ordered by DATA_TYPE and then by how\n  closely the data type maps to the corresponding JDBC SQL type.\n\n  <P>Each type description has the following columns:\n   <OL>\n \t<LI><B>TYPE_NAME</B> String => Type name\n \t<LI><B>DATA_TYPE</B> short => SQL data type from java.sql.Types\n \t<LI><B>PRECISION</B> int => maximum precision\n \t<LI><B>LITERAL_PREFIX</B> String => prefix used to quote a literal\n       (may be null)\n \t<LI><B>LITERAL_SUFFIX</B> String => suffix used to quote a literal\n        (may be null)\n \t<LI><B>CREATE_PARAMS</B> String => parameters used in creating\n       the type (may be null)\n \t<LI><B>NULLABLE</B> short => can you use NULL for this type?\n       <UL>\n       <LI> typeNoNulls - does not allow NULL values\n       <LI> typeNullable - allows NULL values\n       <LI> typeNullableUnknown - nullability unknown\n       </UL>\n \t<LI><B>CASE_SENSITIVE</B> Boolean=> is it case sensitive?\n \t<LI><B>SEARCHABLE</B> short => can you use \"WHERE\" based on this type:\n       <UL>\n       <LI> typePredNone - No support\n       <LI> typePredChar - Only supported with WHERE .. LIKE\n       <LI> typePredBasic - Supported except for WHERE .. LIKE\n       <LI> typeSearchable - Supported for all WHERE ..\n       </UL>\n \t<LI><B>UNSIGNED_ATTRIBUTE</B> Boolean => is it unsigned?\n \t<LI><B>FIXED_PREC_SCALE</B> Boolean => can it be a money value?\n \t<LI><B>AUTO_INCREMENT</B> Boolean => can it be used for an\n       auto-increment value?\n \t<LI><B>LOCAL_TYPE_NAME</B> String => localized version of type name\n       (may be null)\n \t<LI><B>MINIMUM_SCALE</B> short => minimum scale supported\n \t<LI><B>MAXIMUM_SCALE</B> short => maximum scale supported\n \t<LI><B>SQL_DATA_TYPE</B> int => unused\n \t<LI><B>SQL_DATETIME_SUB</B> int => unused\n \t<LI><B>NUM_PREC_RADIX</B> int => usually 2 or 10\n   </OL>\n\n  @return <code>ResultSet</code> - each row is an SQL type description\n}\nfunction TZSQLiteDatabaseMetadata.UncachedGetTypeInfo: IZResultSet;\nconst\n  MaxTypeCount = 22;\n  TypeNames: array[1..MaxTypeCount] of string = (\n    'BOOLEAN', 'TINYINT', 'SMALLINT', 'MEDIUMINT', 'INTEGER',\n    'BIGINT', 'REAL', 'FLOAT', 'NUMERIC', 'DECIMAL', 'NUMBER',\n    'DOUBLE', 'CHAR', 'VARCHAR', 'BINARY', 'VARBINARY', 'DATE',\n    'TIME', 'DATETIME', 'TIMESTAMP', 'BLOB', 'TEXT');\n  TypeCodes: array[1..MaxTypeCount] of TZSQLType = (\n    stBoolean, stByte, stShort, stInteger, stInteger, stLong,\n    stFloat, stFloat, stDouble, stDouble, stDouble, stDouble,\n    stString, {$IFDEF UNICODE}stUnicodeString{$ELSE}stString{$ENDIF},\n    stBytes, stBytes, stDate, stTime, stTimestamp,\n    stTimestamp, stBinaryStream, {$IFDEF UNICODE}stUnicodeStream{$ELSE}stAsciiStream{$ENDIF});\n  TypePrecision: array[1..MaxTypeCount] of Integer = (\n    -1, 2, 4, 9, 9, 16, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\n    -1, -1, -1, -1, -1);\nvar\n  I: Integer;\nbegin\n    Result:=inherited UncachedGetTypeInfo;\n\n    for I := 1 to MaxTypeCount do\n    begin\n      Result.MoveToInsertRow;\n\n      Result.UpdateString(1, TypeNames[I]);\n      Result.UpdateInt(2, Ord(TypeCodes[I]));\n      if TypePrecision[I] >= 0 then\n        Result.UpdateInt(3, TypePrecision[I])\n      else Result.UpdateNull(3);\n      if TypeCodes[I] in [stString, stBytes, stDate, stTime,\n        stTimeStamp, stBinaryStream, stAsciiStream, stUnicodeString] then\n      begin\n        Result.UpdateString(4, '''');\n        Result.UpdateString(5, '''');\n      end\n      else\n      begin\n        Result.UpdateNull(4);\n        Result.UpdateNull(5);\n      end;\n      Result.UpdateNull(6);\n      Result.UpdateInt(7, Ord(ntNullable));\n      Result.UpdateBoolean(8, False);\n      Result.UpdateBoolean(9, False);\n      Result.UpdateBoolean(11, False);\n      Result.UpdateBoolean(12, False);\n      Result.UpdateBoolean(12, TypeNames[I] = 'INTEGER');\n      Result.UpdateNull(13);\n      Result.UpdateNull(14);\n      Result.UpdateNull(15);\n      Result.UpdateNull(16);\n      Result.UpdateNull(17);\n      Result.UpdateInt(18, 10);\n\n      Result.InsertRow;\n    end;\nend;\n\n{**\n  Gets a description of a table's indices and statistics. They are\n  ordered by NON_UNIQUE, TYPE, INDEX_NAME, and ORDINAL_POSITION.\n\n  <P>Each index column description has the following columns:\n   <OL>\n \t<LI><B>TABLE_CAT</B> String => table catalog (may be null)\n \t<LI><B>TABLE_SCHEM</B> String => table schema (may be null)\n \t<LI><B>TABLE_NAME</B> String => table name\n \t<LI><B>NON_UNIQUE</B> Boolean => Can index values be non-unique?\n       false when TYPE is tableIndexStatistic\n \t<LI><B>INDEX_QUALIFIER</B> String => index catalog (may be null);\n       null when TYPE is tableIndexStatistic\n \t<LI><B>INDEX_NAME</B> String => index name; null when TYPE is\n       tableIndexStatistic\n \t<LI><B>TYPE</B> short => index type:\n       <UL>\n       <LI> tableIndexStatistic - this identifies table statistics that are\n            returned in conjuction with a table's index descriptions\n       <LI> tableIndexClustered - this is a clustered index\n       <LI> tableIndexHashed - this is a hashed index\n       <LI> tableIndexOther - this is some other style of index\n       </UL>\n \t<LI><B>ORDINAL_POSITION</B> short => column sequence number\n       within index; zero when TYPE is tableIndexStatistic\n \t<LI><B>COLUMN_NAME</B> String => column name; null when TYPE is\n       tableIndexStatistic\n \t<LI><B>ASC_OR_DESC</B> String => column sort sequence, \"A\" => ascending,\n       \"D\" => descending, may be null if sort sequence is not supported;\n       null when TYPE is tableIndexStatistic\n \t<LI><B>CARDINALITY</B> int => When TYPE is tableIndexStatistic, then\n       this is the number of rows in the table; otherwise, it is the\n       number of unique values in the index.\n \t<LI><B>PAGES</B> int => When TYPE is  tableIndexStatisic then\n       this is the number of pages used for the table, otherwise it\n       is the number of pages used for the current index.\n \t<LI><B>FILTER_CONDITION</B> String => Filter condition, if any.\n       (may be null)\n   </OL>\n\n  @param catalog a catalog name; \"\" retrieves those without a\n  catalog; null means drop catalog name from the selection criteria\n  @param schema a schema name; \"\" retrieves those without a schema\n  @param table a table name\n  @param unique when true, return only indices for unique values;\n      when false, return indices regardless of whether unique or not\n  @param approximate when true, result is allowed to reflect approximate\n      or out of data values; when false, results are requested to be\n      accurate\n  @return <code>ResultSet</code> - each row is an index column description\n}\nfunction TZSQLiteDatabaseMetadata.UncachedGetIndexInfo(const Catalog: string;\n  const Schema: string; const Table: string; Unique: Boolean;\n  Approximate: Boolean): IZResultSet;\nvar\n  MainResultSet, ResultSet: IZResultSet;\n  Temp_scheme: string;\nbegin\n    Result:=inherited UncachedGetIndexInfo(Catalog, Schema, Table, Unique, Approximate);\n\n    if Schema = '' then\n      Temp_scheme := '' // OR  'main.'\n    else\n      Temp_scheme := Schema +'.';\n\n    MainResultSet := GetConnection.CreateStatement.ExecuteQuery(\n      Format('PRAGMA %s index_list(''%s'')', [Temp_scheme, Table]));\n    if MainResultSet<>nil then\n    begin\n      while MainResultSet.Next do\n      begin\n        if (Pos(' autoindex ', String(MainResultSet.GetString(2))) = 0)\n          and ((Unique = False) or (MainResultSet.GetInt(3) = 0)) then\n        begin\n          ResultSet := GetConnection.CreateStatement.ExecuteQuery(\n            Format('PRAGMA %s index_info(''%s'')', [Temp_scheme,MainResultSet.GetString(2)]));\n          while ResultSet.Next do\n          begin\n            Result.MoveToInsertRow;\n\n            if Schema <> '' then\n              Result.UpdateString(1, Schema)\n            else Result.UpdateNull(1);\n            Result.UpdateNull(2);\n            Result.UpdateString(3, Table);\n            Result.UpdateBoolean(4, MainResultSet.GetInt(3) = 0);\n            Result.UpdateNull(5);\n            Result.UpdateString(6, MainResultSet.GetString(2));\n            Result.UpdateNull(7);\n            Result.UpdateInt(8, ResultSet.GetInt(1) + 1);\n            Result.UpdateString(9, ResultSet.GetString(3));\n            Result.UpdateString(10, 'A');\n            Result.UpdateInt(11, 0);\n            Result.UpdateInt(12, 0);\n            Result.UpdateNull(13);\n\n            Result.InsertRow;\n          end;\n          ResultSet.Close;\n        end;\n      end;\n      MainResultSet.Close;\n    end;\nend;\n\n{**\n  Gets the supported CharacterSets:\n  @return <code>ResultSet</code> - each row is a CharacterSetName and it's ID\n}\ntype\n  CodePageRec = record\n    CP: String;\n    ID: Integer;\n  end;\n\nfunction TZSQLiteDatabaseMetadata.UncachedGetCharacterSets: IZResultSet; //EgonHugeist\nconst\n  Encodings: array[0..3] of CodePageRec =(\n    (CP: 'UTF-8'; ID: 1),\n    (CP: 'UTF-16le'; ID: 2),\n    (CP: 'UTF-16be'; ID: 3),\n    (CP: 'UTF-16'; ID: 4)\n    );\nvar\n  I: Integer;\nbegin\n { TODO -oEgonHugeist : Correct this please if i'm wrong here!!! }\n{Text Encodings\n\n    #define SQLITE_UTF8           1\n    #define SQLITE_UTF16LE        2\n    #define SQLITE_UTF16BE        3\n    #define SQLITE_UTF16          4    /* Use native byte order */\n    #define SQLITE_ANY            5    /* sqlite3_create_function only */\n    #define SQLITE_UTF16_ALIGNED  8    /* sqlite3_create_collation only */\n\nThese constant define integer codes that represent the various text encodings supported by SQLite.}\n\n  Result:=inherited UncachedGetCharacterSets;\n\n  for i := 0 to high(Encodings) do\n  begin\n    Result.MoveToInsertRow;\n    Result.UpdateString(1, Encodings[i].CP); //CHARACTER_SET_NAME\n    Result.UpdateShort(2, Encodings[i].ID); //CHARACTER_SET_ID\n    Result.InsertRow;\n  end;\nend;\n\nend.\n"
  },
  {
    "path": "lib/zeosdbo/src/dbc/ZDbcSqLiteResultSet.pas",
    "content": "{*********************************************************}\n{                                                         }\n{                 Zeos Database Objects                   }\n{           SQLite Database Connectivity Classes          }\n{                                                         }\n{        Originally written by Sergey Seroukhov           }\n{                                                         }\n{*********************************************************}\n\n{@********************************************************}\n{    Copyright (c) 1999-2012 Zeos Development Group       }\n{                                                         }\n{ License Agreement:                                      }\n{                                                         }\n{ This library is distributed in the hope that it will be }\n{ useful, but WITHOUT ANY WARRANTY; without even the      }\n{ implied warranty of MERCHANTABILITY or FITNESS FOR      }\n{ A PARTICULAR PURPOSE.  See the GNU Lesser General       }\n{ Public License for more details.                        }\n{                                                         }\n{ The source code of the ZEOS Libraries and packages are  }\n{ distributed under the Library GNU General Public        }\n{ License (see the file COPYING / COPYING.ZEOS)           }\n{ with the following  modification:                       }\n{ As a special exception, the copyright holders of this   }\n{ library give you permission to link this library with   }\n{ independent modules to produce an executable,           }\n{ regardless of the license terms of these independent    }\n{ modules, and to copy and distribute the resulting       }\n{ executable under terms of your choice, provided that    }\n{ you also meet, for each linked independent module,      }\n{ the terms and conditions of the license of that module. }\n{ An independent module is a module which is not derived  }\n{ from or based on this library. If you modify this       }\n{ library, you may extend this exception to your version  }\n{ of the library, but you are not obligated to do so.     }\n{ If you do not wish to do so, delete this exception      }\n{ statement from your version.                            }\n{                                                         }\n{                                                         }\n{ The project web site is located on:                     }\n{   http://zeos.firmos.at  (FORUM)                        }\n{   http://sourceforge.net/p/zeoslib/tickets/ (BUGTRACKER)}\n{   svn://svn.code.sf.net/p/zeoslib/code-0/trunk (SVN)    }\n{                                                         }\n{   http://www.sourceforge.net/projects/zeoslib.          }\n{                                                         }\n{                                                         }\n{                                 Zeos Development Group. }\n{********************************************************@}\n\nunit ZDbcSqLiteResultSet;\n\ninterface\n\n{$I ZDbc.inc}\n\nuses\n  {$IFDEF WITH_TOBJECTLIST_INLINE}System.Types, System.Contnrs{$ELSE}Types, Contnrs{$ENDIF},\n  Classes, {$IFDEF MSEgui}mclasses,{$ENDIF} SysUtils,\n  ZSysUtils, ZDbcIntfs, ZDbcResultSet, ZDbcResultSetMetadata, ZPlainSqLiteDriver,\n  ZCompatibility, ZDbcCache, ZDbcCachedResultSet, ZDbcGenericResolver;\n\ntype\n\n  {** Implements SQLite ResultSet Metadata. }\n  TZSQLiteResultSetMetadata = class(TZAbstractResultSetMetadata)\n  public\n//    function IsAutoIncrement(Column: Integer): Boolean; override;\n    function IsNullable(Column: Integer): TZColumnNullableType; override;\n  end;\n\n  {** Implements SQLite ResultSet. }\n  TZSQLiteResultSet = class(TZAbstractResultSet)\n  private\n    FFetchingReady: Boolean;\n    FHandle: Psqlite;\n    FStmtHandle: Psqlite_vm;\n    FColumnCount: Integer;\n    FColumnNames: PPAnsiChar;\n    FColumnValues: PPAnsiChar;\n    FPlainDriver: IZSQLitePlainDriver;\n    FFreeHandle: Boolean;\n  protected\n    procedure Open; override;\n    procedure FreeHandle;\n    function InternalGetString(ColumnIndex: Integer): RawByteString; override;\n  public\n    constructor Create(PlainDriver: IZSQLitePlainDriver; Statement: IZStatement;\n      SQL: string; Handle: Psqlite; StmtHandle: Psqlite_vm;\n      ColumnCount: Integer; ColumnNames: PPAnsiChar; ColumnValues: PPAnsiChar;\n      AllowFreeHandle: Boolean = True);\n    destructor Destroy; override;\n\n    procedure Close; override;\n\n    function IsNull(ColumnIndex: Integer): Boolean; override;\n    function GetPChar(ColumnIndex: Integer): PChar; override;\n    function GetBoolean(ColumnIndex: Integer): Boolean; override;\n    function GetByte(ColumnIndex: Integer): Byte; override;\n    function GetShort(ColumnIndex: Integer): SmallInt; override;\n    function GetInt(ColumnIndex: Integer): Integer; override;\n    function GetLong(ColumnIndex: Integer): Int64; override;\n    function GetFloat(ColumnIndex: Integer): Single; override;\n    function GetDouble(ColumnIndex: Integer): Double; override;\n    function GetBigDecimal(ColumnIndex: Integer): Extended; override;\n    function GetBytes(ColumnIndex: Integer): TByteDynArray; override;\n    function GetDate(ColumnIndex: Integer): TDateTime; override;\n    function GetTime(ColumnIndex: Integer): TDateTime; override;\n    function GetTimestamp(ColumnIndex: Integer): TDateTime; override;\n    function GetBlob(ColumnIndex: Integer): IZBlob; override;\n\n    function Next: Boolean; override;\n  end;\n\n  {** Implements a cached resolver with SQLite specific functionality. }\n  TZSQLiteCachedResolver = class (TZGenericCachedResolver, IZCachedResolver)\n  private\n    FHandle: Psqlite;\n    FPlainDriver: IZSQLitePlainDriver;\n    FAutoColumnIndex: Integer;\n  public\n    constructor Create(PlainDriver: IZSQLitePlainDriver; Handle: Psqlite;\n      Statement: IZStatement; Metadata: IZResultSetMetadata);\n\n    procedure PostUpdates(Sender: IZCachedResultSet; UpdateType: TZRowUpdateType;\n      OldRowAccessor, NewRowAccessor: TZRowAccessor); override;\n\n    function FormCalculateStatement(Columns: TObjectList): string; override;\n\n    procedure UpdateAutoIncrementFields(Sender: IZCachedResultSet; UpdateType: TZRowUpdateType;\n      OldRowAccessor, NewRowAccessor: TZRowAccessor; Resolver: IZCachedResolver); override;\n  end;\n\nimplementation\n\nuses\n  ZMessages, ZDbcSqLite, ZDbcSQLiteUtils, ZMatchPattern, ZEncoding,\n  ZDbcLogging, ZDbcSqLiteStatement;\n\n{ TZSQLiteResultSetMetadata }\n\n{**\n  Indicates whether the designated column is automatically numbered, thus read-only.\n  @param column the first column is 1, the second is 2, ...\n  @return <code>true</code> if so; <code>false</code> otherwise\n}\n{\nfunction TZSQLiteResultSetMetadata.IsAutoIncrement(Column: Integer): Boolean;\nbegin\n  Result := TZColumnInfo(ResultSet.ColumnsInfo[Column - 1]).AutoIncrement;\nend;\n}\n\n{**\n  Indicates the nullability of values in the designated column.\n  @param column the first column is 1, the second is 2, ...\n  @return the nullability status of the given column; one of <code>columnNoNulls</code>,\n    <code>columnNullable</code> or <code>columnNullableUnknown</code>\n}\nfunction TZSQLiteResultSetMetadata.IsNullable(Column: Integer):\n  TZColumnNullableType;\nbegin\n  if IsAutoIncrement(Column) then\n    Result := ntNullable\n  else\n    Result := inherited IsNullable(Column);\nend;\n\n{ TZSQLiteResultSet }\n\n{**\n  Constructs this object, assignes main properties and\n  opens the record set.\n  @param PlainDriver a native SQLite plain driver.\n  @param Statement a related SQL statement object.\n  @param Handle a SQLite specific query handle.\n  @param UseResult <code>True</code> to use results,\n    <code>False</code> to store result.\n}\nconstructor TZSQLiteResultSet.Create(PlainDriver: IZSQLitePlainDriver;\n  Statement: IZStatement; SQL: string; Handle: Psqlite;\n  StmtHandle: Psqlite_vm; ColumnCount: Integer; ColumnNames: PPAnsiChar;\n  ColumnValues: PPAnsiChar; AllowFreeHandle: Boolean = True);\nbegin\n  inherited Create(Statement, SQL, TZSQLiteResultSetMetadata.Create(\n    Statement.GetConnection.GetMetadata, SQL, Self),\n    Statement.GetConnection.GetConSettings);\n\n  FHandle := Handle;\n  FStmtHandle := StmtHandle;\n  FPlainDriver := PlainDriver;\n  ResultSetConcurrency := rcReadOnly;\n  FColumnCount := ColumnCount;\n  FColumnNames := ColumnNames;\n  FColumnValues := ColumnValues;\n  FFreeHandle := AllowFreeHandle;\n  FFetchingReady := False;\n\n  Open;\nend;\n\n{**\n  Destroys this object and cleanups the memory.\n}\ndestructor TZSQLiteResultSet.Destroy;\nbegin\n  //ZPlainSQLLiteDriver.Step : AllocMem(SizeOf(PPAnsiChar)*(pN+1)); // Leak, if not freed ! [HD, 05.10.2007]\n  if FColumnValues <> nil then\n    FreeMem(FColumnValues, Sizeof(PPAnsiChar) * (fColumnCount + 1));\n  FColumnValues := nil;\n\n   //ZPlainSQLLiteDriver.Step : AllocMem(SizeOf(PPAnsiChar)*(pN+1)*2); // Leak, if not freed ! [HD, 05.10.2007]\n  if FColumnNames <> nil then\n    FreeMem(FColumnNames, Sizeof(PPAnsiChar) * (fColumnCount + 1) * 2);\n  FColumnNames := nil;\n\n  inherited Destroy;\nend;\n\n{**\n  Opens this recordset.\n}\nprocedure TZSQLiteResultSet.Open;\nvar\n  I: Integer;\n  ColumnInfo: TZColumnInfo;\n  FieldName: PPAnsiChar;\n  FieldPrecision: Integer;\n  FieldDecimals: Integer;\n  TypeName: PPAnsiChar;\nbegin\n  if ResultSetConcurrency = rcUpdatable then\n    raise EZSQLException.Create(SLiveResultSetsAreNotSupported);\n\n  LastRowNo := 0;\n\n  { Fills the column info. }\n  ColumnsInfo.Clear;\n  FieldName := FColumnNames;\n  TypeName := FColumnNames;\n  Inc(TypeName, FColumnCount);\n  for I := 1 to FColumnCount do\n  begin\n    ColumnInfo := TZColumnInfo.Create;\n    with ColumnInfo do\n    begin\n      ColumnLabel := ZDbcString(FieldName^);\n      Inc(FieldName);\n      TableName := '';\n      ReadOnly := False;\n      if TypeName^ <> nil then\n      begin\n        ColumnType := ConvertSQLiteTypeToSQLType(ZDbcString(TypeName^),\n          FieldPrecision, FieldDecimals, ConSettings.CPType);\n        Inc(TypeName);\n      end\n      else\n      begin\n        ColumnType := ConvertSQLiteTypeToSQLType(ZDbcString(FPlainDriver.column_decltype(FStmtHandle,I-1)),\n          FieldPrecision, FieldDecimals, ConSettings.CPType);\n      end;\n      if ColumnType = stString then\n        if Zencoding.ZDefaultSystemCodePage = zCP_UTF8 then\n          ColumnDisplaySize := FieldPrecision div 4\n        else\n          ColumnDisplaySize := FieldPrecision div 2;\n\n      if ColumnType = stUnicodeString then\n        ColumnDisplaySize := FieldPrecision div 2;\n\n      AutoIncrement := False;\n      Precision := FieldPrecision;\n      Scale := FieldDecimals;\n      Signed := True;\n      Nullable := ntNullable;\n    end;\n\n    ColumnsInfo.Add(ColumnInfo);\n  end;\n\n  inherited Open;\nend;\n\n{**\n  Frees statement handle.\n}\nprocedure TZSQLiteResultSet.FreeHandle;\nvar\n  ErrorCode: Integer;\nbegin\n  if FFreeHandle then\n  begin\n    if Assigned(FStmtHandle) then\n      ErrorCode := FPlainDriver.Finalize(FStmtHandle)\n    else\n      ErrorCode := SQLITE_OK;\n    FStmtHandle := nil;\n    CheckSQLiteError(FPlainDriver, FStmtHandle, ErrorCode, nil,\n      lcOther, 'FINALIZE SQLite VM');\n  end\n  else\n    if FStmtHandle <> nil then\n    begin\n      ErrorCode := FPlainDriver.reset(FStmtHandle);\n      FStmtHandle := nil;\n      CheckSQLiteError(FPlainDriver, FStmtHandle, ErrorCode, nil, lcBindPrepStmt, 'Reset Prepared Stmt');\n      FFetchingReady := True;\n    end;\nend;\n\n{**\n  Releases this <code>ResultSet</code> object's database and\n  JDBC resources immediately instead of waiting for\n  this to happen when it is automatically closed.\n\n  <P><B>Note:</B> A <code>ResultSet</code> object\n  is automatically closed by the\n  <code>Statement</code> object that generated it when\n  that <code>Statement</code> object is closed,\n  re-executed, or is used to retrieve the next result from a\n  sequence of multiple results. A <code>ResultSet</code> object\n  is also automatically closed when it is garbage collected.\n}\nprocedure TZSQLiteResultSet.Close;\nvar stmt: IZSQLiteCAPIPreparedStatement;\nbegin\n  if Assigned(Statement) and Supports(Statement, IZSQLiteCAPIPreparedStatement, stmt) then\n    stmt.FreeReference;\n  inherited Close;\n  FreeHandle;\nend;\n\n{**\n  Indicates if the value of the designated column in the current row\n  of this <code>ResultSet</code> object is Null.\n\n  @param columnIndex the first column is 1, the second is 2, ...\n  @return if the value is SQL <code>NULL</code>, the\n    value returned is <code>true</code>. <code>false</code> otherwise.\n}\nfunction TZSQLiteResultSet.IsNull(ColumnIndex: Integer): Boolean;\nvar\n  Temp: PPAnsiChar;\nbegin\n{$IFNDEF DISABLE_CHECKING}\n  CheckClosed;\n  if (LastRowNo = 0) or (FColumnValues = nil) then\n    raise EZSQLException.Create(SRowDataIsNotAvailable);\n{$ENDIF}\n\n  Temp := FColumnValues;\n  Inc(Temp, ColumnIndex - 1);\n  Result := (Temp^ = nil);\nend;\n\n{**\n  Gets the value of the designated column in the current row\n  of this <code>ResultSet</code> object as\n  a <code>PAnsiChar</code> in the Delphi programming language.\n\n  @param columnIndex the first column is 1, the second is 2, ...\n  @return the column value; if the value is SQL <code>NULL</code>, the\n    value returned is <code>null</code>\n}\nfunction TZSQLiteResultSet.GetPChar(ColumnIndex: Integer): PChar;\nvar\n  TempStr: String;\nbegin\n{$IFNDEF DISABLE_CHECKING}\n  CheckClosed;\n  if (LastRowNo = 0) or (FColumnValues = nil) then\n    raise EZSQLException.Create(SRowDataIsNotAvailable);\n{$ENDIF}\n\n  TempStr := GetString(ColumnIndex);\n  Result := PChar(TempStr);\n  LastWasNull := Result = nil;\nend;\n\n{**\n  Gets the value of the designated column in the current row\n  of this <code>ResultSet</code> object as\n  a <code>String</code> in the Java programming language.\n\n  @param columnIndex the first column is 1, the second is 2, ...\n  @return the column value; if the value is SQL <code>NULL</code>, the\n    value returned is <code>null</code>\n}\nfunction TZSQLiteResultSet.InternalGetString(ColumnIndex: Integer): RawByteString;\nvar\n  Temp: PPAnsiChar;\nbegin\n{$IFNDEF DISABLE_CHECKING}\n  CheckClosed;\n  if (LastRowNo = 0) or (FColumnValues = nil) then\n    raise EZSQLException.Create(SRowDataIsNotAvailable);\n{$ENDIF}\n\n  Temp := FColumnValues;\n  Inc(Temp, ColumnIndex - 1);\n  Result := Temp^;\n  LastWasNull := Temp^ = nil;\nend;\n\n{**\n  Gets the value of the designated column in the current row\n  of this <code>ResultSet</code> object as\n  a <code>boolean</code> in the Java programming language.\n\n  @param columnIndex the first column is 1, the second is 2, ...\n  @return the column value; if the value is SQL <code>NULL</code>, the\n    value returned is <code>false</code>\n}\nfunction TZSQLiteResultSet.GetBoolean(ColumnIndex: Integer): Boolean;\nvar\n  Temp: string;\nbegin\n{$IFNDEF DISABLE_CHECKING}\n  CheckColumnConvertion(ColumnIndex, stBoolean);\n{$ENDIF}\n  Temp := UpperCase(String(InternalGetString(ColumnIndex)));\n  Result := (Temp = 'Y') or (Temp = 'YES') or (Temp = 'T') or\n    (Temp = 'TRUE') or (StrToIntDef(Temp, 0) <> 0);\nend;\n\n{**\n  Gets the value of the designated column in the current row\n  of this <code>ResultSet</code> object as\n  a <code>byte</code> in the Java programming language.\n\n  @param columnIndex the first column is 1, the second is 2, ...\n  @return the column value; if the value is SQL <code>NULL</code>, the\n    value returned is <code>0</code>\n}\nfunction TZSQLiteResultSet.GetByte(ColumnIndex: Integer): Byte;\nbegin\n{$IFNDEF DISABLE_CHECKING}\n  CheckColumnConvertion(ColumnIndex, stByte);\n{$ENDIF}\n  Result := Byte(StrToIntDef(String(InternalGetString(ColumnIndex)), 0));\nend;\n\n{**\n  Gets the value of the designated column in the current row\n  of this <code>ResultSet</code> object as\n  a <code>short</code> in the Java programming language.\n\n  @param columnIndex the first column is 1, the second is 2, ...\n  @return the column value; if the value is SQL <code>NULL</code>, the\n    value returned is <code>0</code>\n}\nfunction TZSQLiteResultSet.GetShort(ColumnIndex: Integer): SmallInt;\nbegin\n{$IFNDEF DISABLE_CHECKING}\n  CheckColumnConvertion(ColumnIndex, stShort);\n{$ENDIF}\n  Result := SmallInt(StrToIntDef(String(InternalGetString(ColumnIndex)), 0));\nend;\n\n{**\n  Gets the value of the designated column in the current row\n  of this <code>ResultSet</code> object as\n  an <code>int</code> in the Java programming language.\n\n  @param columnIndex the first column is 1, the second is 2, ...\n  @return the column value; if the value is SQL <code>NULL</code>, the\n    value returned is <code>0</code>\n}\nfunction TZSQLiteResultSet.GetInt(ColumnIndex: Integer): Integer;\nbegin\n{$IFNDEF DISABLE_CHECKING}\n  CheckColumnConvertion(ColumnIndex, stInteger);\n{$ENDIF}\n  Result := StrToIntDef(String(InternalGetString(ColumnIndex)), 0);\nend;\n\n{**\n  Gets the value of the designated column in the current row\n  of this <code>ResultSet</code> object as\n  a <code>long</code> in the Java programming language.\n\n  @param columnIndex the first column is 1, the second is 2, ...\n  @return the column value; if the value is SQL <code>NULL</code>, the\n    value returned is <code>0</code>\n}\nfunction TZSQLiteResultSet.GetLong(ColumnIndex: Integer): Int64;\nbegin\n{$IFNDEF DISABLE_CHECKING}\n  CheckColumnConvertion(ColumnIndex, stLong);\n{$ENDIF}\n  Result := StrToInt64Def(String(InternalGetString(ColumnIndex)), 0);\nend;\n\n{**\n  Gets the value of the designated column in the current row\n  of this <code>ResultSet</code> object as\n  a <code>float</code> in the Java programming language.\n\n  @param columnIndex the first column is 1, the second is 2, ...\n  @return the column value; if the value is SQL <code>NULL</code>, the\n    value returned is <code>0</code>\n}\nfunction TZSQLiteResultSet.GetFloat(ColumnIndex: Integer): Single;\nbegin\n{$IFNDEF DISABLE_CHECKING}\n  CheckColumnConvertion(ColumnIndex, stFloat);\n{$ENDIF}\n  Result := SQLStrToFloatDef(InternalGetString(ColumnIndex), 0);\nend;\n\n{**\n  Gets the value of the designated column in the current row\n  of this <code>ResultSet</code> object as\n  a <code>double</code> in the Java programming language.\n\n  @param columnIndex the first column is 1, the second is 2, ...\n  @return the column value; if the value is SQL <code>NULL</code>, the\n    value returned is <code>0</code>\n}\nfunction TZSQLiteResultSet.GetDouble(ColumnIndex: Integer): Double;\nbegin\n{$IFNDEF DISABLE_CHECKING}\n  CheckColumnConvertion(ColumnIndex, stDouble);\n{$ENDIF}\n  Result := SQLStrToFloatDef(InternalGetString(ColumnIndex), 0);\nend;\n\n{**\n  Gets the value of the designated column in the current row\n  of this <code>ResultSet</code> object as\n  a <code>java.sql.BigDecimal</code> in the Java programming language.\n\n  @param columnIndex the first column is 1, the second is 2, ...\n  @param scale the number of digits to the right of the decimal point\n  @return the column value; if the value is SQL <code>NULL</code>, the\n    value returned is <code>null</code>\n}\nfunction TZSQLiteResultSet.GetBigDecimal(ColumnIndex: Integer): Extended;\nbegin\n{$IFNDEF DISABLE_CHECKING}\n  CheckColumnConvertion(ColumnIndex, stBigDecimal);\n{$ENDIF}\n  Result := SQLStrToFloatDef(InternalGetString(ColumnIndex), 0);\nend;\n\n{**\n  Gets the value of the designated column in the current row\n  of this <code>ResultSet</code> object as\n  a <code>byte</code> array in the Java programming language.\n  The bytes represent the raw values returned by the driver.\n\n  @param columnIndex the first column is 1, the second is 2, ...\n  @return the column value; if the value is SQL <code>NULL</code>, the\n    value returned is <code>null</code>\n}\nfunction TZSQLiteResultSet.GetBytes(ColumnIndex: Integer): TByteDynArray;\nbegin\n{$IFNDEF DISABLE_CHECKING}\n  CheckColumnConvertion(ColumnIndex, stBytes);\n{$ENDIF}\n  Result := StrToBytes(DecodeString(InternalGetString(ColumnIndex)));\nend;\n\n{**\n  Gets the value of the designated column in the current row\n  of this <code>ResultSet</code> object as\n  a <code>java.sql.Date</code> object in the Java programming language.\n\n  @param columnIndex the first column is 1, the second is 2, ...\n  @return the column value; if the value is SQL <code>NULL</code>, the\n    value returned is <code>null</code>\n}\nfunction TZSQLiteResultSet.GetDate(ColumnIndex: Integer): TDateTime;\nvar\n  Value: string;\n  TempDate: TDateTime;\nbegin\n{$IFNDEF DISABLE_CHECKING}\n  CheckColumnConvertion(ColumnIndex, stDate);\n{$ENDIF}\n  Value := String(InternalGetString(ColumnIndex));\n  if IsMatch('????-??-??*', Value) then\n    Result := Trunc(AnsiSQLDateToDateTime(Value))\n  else\n  begin\n    TempDate := Trunc(SQLStrToFloatDef(Value, 0));\n    Result := Trunc(TimestampStrToDateTime(Value));\n    if ( Result = 0 ) and not ( TempDate = 0 ) then\n      Result := TempDate;\n  end;\n  LastWasNull := Result = 0;\nend;\n\n{**\n  Gets the value of the designated column in the current row\n  of this <code>ResultSet</code> object as\n  a <code>java.sql.Time</code> object in the Java programming language.\n\n  @param columnIndex the first column is 1, the second is 2, ...\n  @return the column value; if the value is SQL <code>NULL</code>, the\n    value returned is <code>null</code>\n}\nfunction TZSQLiteResultSet.GetTime(ColumnIndex: Integer): TDateTime;\nvar\n  Value: string;\n  TempTime: TDateTime;\nbegin\n{$IFNDEF DISABLE_CHECKING}\n  CheckColumnConvertion(ColumnIndex, stTime);\n{$ENDIF}\n  Value := String(InternalGetString(ColumnIndex));\n  if IsMatch('*??:??:??*', Value) then\n    Result := Frac(AnsiSQLDateToDateTime(Value))\n  else\n  begin\n    TempTime := Frac(SQLStrToFloatDef(Value, 0));\n    Result := Frac(TimestampStrToDateTime(Value));\n    if ( Result = 0 ) and not ( TempTime = 0 ) then\n      Result := TempTime;\n  end;\n  LastWasNull := Result = 0;\nend;\n\n{**\n  Gets the value of the designated column in the current row\n  of this <code>ResultSet</code> object as\n  a <code>java.sql.Timestamp</code> object in the Java programming language.\n\n  @param columnIndex the first column is 1, the second is 2, ...\n  @return the column value; if the value is SQL <code>NULL</code>, the\n  value returned is <code>null</code>\n  @exception SQLException if a database access error occurs\n}\nfunction TZSQLiteResultSet.GetTimestamp(ColumnIndex: Integer): TDateTime;\nvar\n  Value: string;\n  TempTimeStamp: TDateTime;\nbegin\n{$IFNDEF DISABLE_CHECKING}\n  CheckColumnConvertion(ColumnIndex, stTimestamp);\n{$ENDIF}\n  Value := String(InternalGetString(ColumnIndex));\n  if IsMatch('????-??-??*', Value) then\n    Result := AnsiSQLDateToDateTime(Value)\n  else\n  begin\n    TempTimeStamp := SQLStrToFloatDef(Value, 0);\n    Result := TimestampStrToDateTime(Value);\n    if ( Result = 0 ) and not ( TempTimeStamp = 0 ) then\n      Result := TempTimeStamp;\n  end;\n  LastWasNull := Result = 0;\nend;\n\n{**\n  Returns the value of the designated column in the current row\n  of this <code>ResultSet</code> object as a <code>Blob</code> object\n  in the Java programming language.\n\n  @param ColumnIndex the first column is 1, the second is 2, ...\n  @return a <code>Blob</code> object representing the SQL <code>BLOB</code> value in\n    the specified column\n}\nfunction TZSQLiteResultSet.GetBlob(ColumnIndex: Integer): IZBlob;\nvar\n  Stream: TStream;\n  AnsiTemp: RawByteString;\nbegin\n  Result := nil;\n{$IFNDEF DISABLE_CHECKING}\n  CheckBlobColumn(ColumnIndex);\n{$ENDIF}\n  LastWasNull := IsNull(ColumnIndex);\n  if LastWasNull then\n      Exit;\n\n  Stream := nil;\n  try\n    if not LastWasNull then\n    begin\n      case GetMetadata.GetColumnType(ColumnIndex) of\n        stAsciiStream:\n          if ConSettings.AutoEncode then\n            Stream := TStringStream.Create(GetValidatedAnsiString(InternalGetString(ColumnIndex), ConSettings, True))\n          else\n            Stream := TStringStream.Create(InternalGetString(ColumnIndex));\n        stUnicodeStream:\n          begin\n            AnsiTemp := InternalGetString(ColumnIndex);\n            if Length(AnsiTemp) = 0 then\n              Stream := TMemoryStream.Create\n            else\n              Stream := GetValidatedUnicodeStream(InternalGetString(ColumnIndex), ConSettings, True);\n          end;\n        stBinaryStream:\n          {introduced the old Zeos6 blob-encoding cause of compatibility reasons}\n          if (Statement.GetConnection as IZSQLiteConnection).UseOldBlobEncoding then\n            Stream := TStringStream.Create(DecodeString(InternalGetString(ColumnIndex)))\n          else\n            Stream := FPlaindriver.column_blob(FStmtHandle,columnIndex);\n      end;\n      Result := TZAbstractBlob.CreateWithStream(Stream, GetStatement.GetConnection, GetMetadata.GetColumnType(ColumnIndex) = stUnicodeStream);\n    end\n    else\n      Result := TZAbstractBlob.CreateWithStream(nil, GetStatement.GetConnection);\n  finally\n    if Assigned(Stream) then\n      Stream.Free;\n  end;\nend;\n\n{**\n  Moves the cursor down one row from its current position.\n  A <code>ResultSet</code> cursor is initially positioned\n  before the first row; the first call to the method\n  <code>next</code> makes the first row the current row; the\n  second call makes the second row the current row, and so on.\n\n  <P>If an input stream is open for the current row, a call\n  to the method <code>next</code> will\n  implicitly close it. A <code>ResultSet</code> object's\n  warning chain is cleared when a new row is read.\n\n  @return <code>true</code> if the new current row is valid;\n    <code>false</code> if there are no more rows\n}\nfunction TZSQLiteResultSet.Next: Boolean;\nvar\n  ErrorCode: Integer;\nbegin\n  { Checks for maximum row. }\n  Result := False;\n\n  if (MaxRows > 0) and (RowNo >= MaxRows) then\n    Exit;\n\n  if LastRowNo = 0 then\n  begin\n    Result := FColumnValues <> nil;\n    if Result then\n    begin\n      LastRowNo := LastRowNo + 1;\n      RowNo := RowNo + 1;\n    end\n    else\n    begin\n      if RowNo <= LastRowNo then\n        RowNo := LastRowNo + 1;\n    end;\n  end\n  else\n  begin\n      //ZPlainSQLLiteDriver.Step : AllocMem(SizeOf(PPAnsiChar)*(pN+1)); // Leak, if not freed ! [HD, 05.10.2007]\n    if FColumnValues <> nil then\n      FreeMem(FColumnValues, Sizeof(PPAnsiChar) * (fColumnCount + 1));\n    FColumnValues := nil;\n    if Assigned(FStmtHandle) and not FFetchingReady then\n    begin\n     //ZPlainSQLLiteDriver.Step : AllocMem(SizeOf(PPAnsiChar)*(pN+1)*2); // Leak, if not freed [HD, 05.10.2007]\n      if FColumnNames <> nil then\n        FreeMem(FColumnNames, Sizeof(PPAnsiChar) * (fColumnCount + 1) * 2);\n      FColumnNames := nil;\n      ErrorCode := FPlainDriver.Step(FStmtHandle, FColumnCount,\n        FColumnValues, FColumnNames);\n      CheckSQLiteError(FPlainDriver, FStmtHandle, ErrorCode, nil, lcOther, 'FETCH');\n    end;\n\n    if FColumnValues <> nil then\n    begin\n      RowNo := RowNo + 1;\n      if LastRowNo < RowNo then\n        LastRowNo := RowNo;\n      Result := True;\n    end\n    else\n    begin\n      if RowNo <= LastRowNo then\n        RowNo := LastRowNo + 1;\n      Result := False;\n    end;\n  end;\n\n  { Frees handle when reads to the end. }\n  if not Result and Assigned(FStmtHandle) then\n    FreeHandle;\nend;\n\n{ TZSQLiteCachedResolver }\n\n{**\n  Creates a SQLite specific cached resolver object.\n  @param PlainDriver a native SQLite plain driver.\n  @param Handle a SQLite specific query handle.\n  @param Statement a related SQL statement object.\n  @param Metadata a resultset metadata reference.\n}\nconstructor TZSQLiteCachedResolver.Create(PlainDriver: IZSQLitePlainDriver;\n  Handle: Psqlite; Statement: IZStatement; Metadata: IZResultSetMetadata);\nvar\n  I: Integer;\nbegin\n  inherited Create(Statement, Metadata);\n  FPlainDriver := PlainDriver;\n  FHandle := Handle;\n\n  { Defines an index of autoincrement field. }\n  FAutoColumnIndex := 0;\n  for I := 1 to Metadata.GetColumnCount do\n  begin\n    if Metadata.IsAutoIncrement(I) and\n      (Metadata.GetColumnType(I) in [stByte, stShort, stInteger, stLong]) then\n    begin\n      FAutoColumnIndex := I;\n      Break;\n    end;\n  end;\nend;\n\n{**\n  Posts updates to database.\n  @param Sender a cached result set object.\n  @param UpdateType a type of updates.\n  @param OldRowAccessor an accessor object to old column values.\n  @param NewRowAccessor an accessor object to new column values.\n}\nprocedure TZSQLiteCachedResolver.PostUpdates(Sender: IZCachedResultSet;\n  UpdateType: TZRowUpdateType; OldRowAccessor, NewRowAccessor: TZRowAccessor);\nbegin\n  inherited PostUpdates(Sender, UpdateType, OldRowAccessor, NewRowAccessor);\n\n  if (UpdateType = utInserted) then\n    UpdateAutoIncrementFields(Sender, UpdateType, OldRowAccessor, NewRowAccessor, Self);\nend;\n\n{**\n Do Tasks after Post updates to database.\n  @param Sender a cached result set object.\n  @param UpdateType a type of updates.\n  @param OldRowAccessor an accessor object to old column values.\n  @param NewRowAccessor an accessor object to new column values.\n}\nprocedure TZSQLiteCachedResolver.UpdateAutoIncrementFields(\n  Sender: IZCachedResultSet; UpdateType: TZRowUpdateType; OldRowAccessor,\n  NewRowAccessor: TZRowAccessor; Resolver: IZCachedResolver);\nvar\n  PlainDriver: IZSQLitePlainDriver;\nbegin\n  inherited;\n\n  if (FAutoColumnIndex > 0) and\n     (OldRowAccessor.IsNull(FAutoColumnIndex) or (OldRowAccessor.GetValue(FAutoColumnIndex).VInteger = 0)) then\n  begin\n    PlainDriver := (Connection as IZSQLiteConnection).GetPlainDriver;\n\n    NewRowAccessor.SetLong(FAutoColumnIndex, PlainDriver.LastInsertRowId(FHandle));\n  end;\nend;\n\n// --> ms, 02/11/2005\n{**\n  Forms a where clause for SELECT statements to calculate default values.\n  @param Columns a collection of key columns.\n  @param OldRowAccessor an accessor object to old column values.\n}\nfunction TZSQLiteCachedResolver.FormCalculateStatement(\n  Columns: TObjectList): string;\nvar\n  I: Integer;\n  Current: TZResolverParameter;\nbegin\n  Result := '';\n  if Columns.Count = 0 then\n     Exit;\n\n  for I := 0 to Columns.Count - 1 do\n  begin\n    Current := TZResolverParameter(Columns[I]);\n    if Result <> '' then\n      Result := Result + ',';\n    if Current.DefaultValue <> '' then\n      Result := Result + Current.DefaultValue\n    else\n      Result := Result + 'NULL';\n  end;\n  Result := 'SELECT ' + Result;\nend;\n// <-- ms\n\nend.\n"
  },
  {
    "path": "lib/zeosdbo/src/dbc/ZDbcSqLiteStatement.pas",
    "content": "{*********************************************************}\n{                                                         }\n{                 Zeos Database Objects                   }\n{           SQLite Database Connectivity Classes          }\n{                                                         }\n{        Originally written by Sergey Seroukhov           }\n{                                                         }\n{*********************************************************}\n\n{@********************************************************}\n{    Copyright (c) 1999-2012 Zeos Development Group       }\n{                                                         }\n{ License Agreement:                                      }\n{                                                         }\n{ This library is distributed in the hope that it will be }\n{ useful, but WITHOUT ANY WARRANTY; without even the      }\n{ implied warranty of MERCHANTABILITY or FITNESS FOR      }\n{ A PARTICULAR PURPOSE.  See the GNU Lesser General       }\n{ Public License for more details.                        }\n{                                                         }\n{ The source code of the ZEOS Libraries and packages are  }\n{ distributed under the Library GNU General Public        }\n{ License (see the file COPYING / COPYING.ZEOS)           }\n{ with the following  modification:                       }\n{ As a special exception, the copyright holders of this   }\n{ library give you permission to link this library with   }\n{ independent modules to produce an executable,           }\n{ regardless of the license terms of these independent    }\n{ modules, and to copy and distribute the resulting       }\n{ executable under terms of your choice, provided that    }\n{ you also meet, for each linked independent module,      }\n{ the terms and conditions of the license of that module. }\n{ An independent module is a module which is not derived  }\n{ from or based on this library. If you modify this       }\n{ library, you may extend this exception to your version  }\n{ of the library, but you are not obligated to do so.     }\n{ If you do not wish to do so, delete this exception      }\n{ statement from your version.                            }\n{                                                         }\n{                                                         }\n{ The project web site is located on:                     }\n{   http://zeos.firmos.at  (FORUM)                        }\n{   http://sourceforge.net/p/zeoslib/tickets/ (BUGTRACKER)}\n{   svn://svn.code.sf.net/p/zeoslib/code-0/trunk (SVN)    }\n{                                                         }\n{   http://www.sourceforge.net/projects/zeoslib.          }\n{                                                         }\n{                                                         }\n{                                 Zeos Development Group. }\n{********************************************************@}\n\nunit ZDbcSqLiteStatement;\n\ninterface\n\n{$I ZDbc.inc}\n\nuses\n  Classes, {$IFDEF MSEgui}mclasses,{$ENDIF} SysUtils,\n  {$IFDEF WITH_WIDESTRUTILS}WideStrUtils, {$ENDIF}\n  ZDbcIntfs, ZDbcStatement, ZPlainSqLiteDriver, ZCompatibility, ZDbcLogging,\n  ZVariant;\n\ntype\n\n  {** Implements Generic SQLite Statement. }\n  TZSQLiteStatement = class(TZAbstractStatement)\n  private\n    FHandle: Psqlite;\n    FPlainDriver: IZSQLitePlainDriver;\n\n    function CreateResultSet(const SQL: string; StmtHandle: Psqlite_vm;\n       ColumnCount: Integer; ColumnNames: PPAnsiChar;\n       ColumnValues: PPAnsiChar): IZResultSet;\n  public\n    constructor Create(PlainDriver: IZSQLitePlainDriver;\n      Connection: IZConnection; Info: TStrings; Handle: Psqlite);\n\n    function ExecuteQuery(const SQL: RawByteString): IZResultSet; override;\n    function ExecuteUpdate(const SQL: RawByteString): Integer; override;\n    function Execute(const SQL: RawByteString): Boolean; override;\n  end;\n\n  {$IFDEF ZEOS_TEST_ONLY}\n  {** Implements Prepared SQL Statement. }\n  TZSQLitePreparedStatement = class(TZEmulatedPreparedStatement)\n  private\n    FHandle: Psqlite;\n    FPlainDriver: IZSQLitePlainDriver;\n  protected\n    function CreateExecStatement: IZStatement; override;\n    function PrepareAnsiSQLParam(ParamIndex: Integer): RawByteString; override;\n  public\n    constructor Create(PlainDriver: IZSQLitePlainDriver;\n      Connection: IZConnection; const SQL: string; Info: TStrings;\n      Handle: Psqlite);\n  end;\n  {$ENDIF}\n\n  IZSQLiteCAPIPreparedStatement = Interface(IZPreparedStatement)\n    ['{CA05874D-E817-4523-B0AF-DBCDD0CF85CA}']\n    Procedure FreeReference;\n  end;\n  {** Implements CAPI Prepared SQL Statement. }\n  TZSQLiteCAPIPreparedStatement = class(TZAbstractPreparedStatement,\n    IZSQLiteCAPIPreparedStatement)\n  private\n    FErrorCode: Integer;\n    FHandle: Psqlite;\n    FStmtHandle: Psqlite3_stmt;\n    FPlainDriver: IZSQLitePlainDriver;\n    FOpenResultSet: Pointer;\n    function CreateResultSet(const SQL: string; StmtHandle: Psqlite_vm;\n       ColumnCount: Integer; ColumnNames: PPAnsiChar;\n       ColumnValues: PPAnsiChar): IZResultSet;\n  protected\n    procedure SetASQL(const Value: RawByteString); override;\n    procedure SetWSQL(const Value: ZWideString); override;\n    procedure FreeReference;\n  protected //abstaction overrides\n    procedure PrepareInParameters; override;\n    procedure BindInParameters; override;\n  public\n    constructor Create(PlainDriver: IZSQLitePlainDriver;\n      Connection: IZConnection; const SQL: string; Info: TStrings; Handle: Psqlite);\n\n    procedure Prepare; override;\n    procedure Unprepare; override;\n\n    function ExecuteQueryPrepared: IZResultSet; override;\n    function ExecuteUpdatePrepared: Integer; override;\n    function ExecutePrepared: Boolean; override;\n  end;\n\n\nimplementation\n\nuses\n  Types, ZDbcSqLiteUtils, ZDbcSqLiteResultSet, ZSysUtils, ZEncoding,\n  ZMessages, ZDbcCachedResultSet{$IFDEF WITH_UNITANSISTRINGS}, AnsiStrings{$ENDIF};\n\n{ TZSQLiteStatement }\n\n{**\n  Constructs this object and assignes the main properties.\n  @param PlainDriver a native SQLite plain driver.\n  @param Connection a database connection object.\n  @param Handle a connection handle pointer.\n  @param Info a statement parameters.\n}\nconstructor TZSQLiteStatement.Create(PlainDriver: IZSQLitePlainDriver;\n  Connection: IZConnection; Info: TStrings; Handle: Psqlite);\nbegin\n  inherited Create(Connection, Info);\n  FHandle := Handle;\n  FPlainDriver := PlainDriver;\n  ResultSetType := rtScrollInsensitive;\nend;\n\n{**\n  Creates a result set based on the current settings.\n  @return a created result set object.\n}\n\nfunction TZSQLiteStatement.CreateResultSet(const SQL: string; StmtHandle: Psqlite_vm;\n   ColumnCount: Integer; ColumnNames: PPAnsiChar; ColumnValues: PPAnsiChar): IZResultSet;\nvar\n  CachedResolver: TZSQLiteCachedResolver;\n  NativeResultSet: TZSQLiteResultSet;\n  CachedResultSet: TZCachedResultSet;\nbegin\n  { Creates a native result set. }\n  NativeResultSet := TZSQLiteResultSet.Create(FPlainDriver, Self, SQL, FHandle,\n    StmtHandle, ColumnCount, ColumnNames, ColumnValues);\n  NativeResultSet.SetConcurrency(rcReadOnly);\n\n  { Creates a cached result set. }\n  CachedResolver := TZSQLiteCachedResolver.Create(FPlainDriver, FHandle, Self,\n    NativeResultSet.GetMetaData);\n  CachedResultSet := TZCachedResultSet.Create(NativeResultSet, SQL,\n    CachedResolver,GetConnection.GetConSettings);\n\n  { Fetches all rows to prevent blocking. }\n  CachedResultSet.SetType(rtScrollInsensitive);\n  CachedResultSet.Last;\n  CachedResultSet.BeforeFirst;\n  CachedResultSet.SetConcurrency(GetResultSetConcurrency);\n\n  Result := CachedResultSet;\nend;\n\n{**\n  Executes an SQL statement that returns a single <code>ResultSet</code> object.\n  @param sql typically this is a static SQL <code>SELECT</code> statement\n  @return a <code>ResultSet</code> object that contains the data produced by the\n    given query; never <code>null</code>\n}\nfunction TZSQLiteStatement.ExecuteQuery(const SQL: RawByteString): IZResultSet;\nvar\n  ErrorCode: Integer;\n  StmtHandle: Psqlite3_stmt;\n  ColumnCount: Integer;\n  ColumnValues: PPAnsiChar;\n  ColumnNames: PPAnsiChar;\nbegin\n  ColumnCount := 0;\n  ASQL := SQL; //preprepares SQL\n  ErrorCode := FPlainDriver.Prepare(FHandle, PAnsiChar(ASQL), Length(ASQL),\n    StmtHandle, nil);\n  CheckSQLiteError(FPlainDriver, FHandle, ErrorCode, nil, lcExecute, LogSQL);\n  DriverManager.LogMessage(lcExecute, FPlainDriver.GetProtocol, LogSQL);\n\n  try\n    ErrorCode := FPlainDriver.Step(StmtHandle, ColumnCount,\n      ColumnValues, ColumnNames);\n    CheckSQLiteError(FPlainDriver, FHandle, ErrorCode, nil, lcOther, 'FETCH');\n  except\n    FPlainDriver.Finalize(StmtHandle);\n    raise;\n  end;\n\n  Result := CreateResultSet(SSQL, StmtHandle, ColumnCount, ColumnNames,\n    ColumnValues);\nend;\n\n{**\n  Executes an SQL <code>INSERT</code>, <code>UPDATE</code> or\n  <code>DELETE</code> statement. In addition,\n  SQL statements that return nothing, such as SQL DDL statements,\n  can be executed.\n\n  @param sql an SQL <code>INSERT</code>, <code>UPDATE</code> or\n    <code>DELETE</code> statement or an SQL statement that returns nothing\n  @return either the row count for <code>INSERT</code>, <code>UPDATE</code>\n    or <code>DELETE</code> statements, or 0 for SQL statements that return nothing\n}\nfunction TZSQLiteStatement.ExecuteUpdate(const SQL: RawByteString): Integer;\nvar\n  ErrorCode: Integer;\n  ErrorMessage: PAnsichar;\nbegin\n  ASQL := SQL; //preprepares SQL\n  ErrorCode := FPlainDriver.Execute(FHandle, PAnsiChar(ASQL), nil, nil,ErrorMessage);\n  CheckSQLiteError(FPlainDriver, FHandle, ErrorCode, ErrorMessage, lcExecute, SSQL);\n  DriverManager.LogMessage(lcExecute, FPlainDriver.GetProtocol, SSQL);\n  Result := FPlainDriver.Changes(FHandle);\n  LastUpdateCount := Result;\nend;\n\n{**\n  Executes an SQL statement that may return multiple results.\n  Under some (uncommon) situations a single SQL statement may return\n  multiple result sets and/or update counts.  Normally you can ignore\n  this unless you are (1) executing a stored procedure that you know may\n  return multiple results or (2) you are dynamically executing an\n  unknown SQL string.  The  methods <code>execute</code>,\n  <code>getMoreResults</code>, <code>getResultSet</code>,\n  and <code>getUpdateCount</code> let you navigate through multiple results.\n\n  The <code>execute</code> method executes an SQL statement and indicates the\n  form of the first result.  You can then use the methods\n  <code>getResultSet</code> or <code>getUpdateCount</code>\n  to retrieve the result, and <code>getMoreResults</code> to\n  move to any subsequent result(s).\n\n  @param sql any SQL statement\n  @return <code>true</code> if the next result is a <code>ResultSet</code> object;\n  <code>false</code> if it is an update count or there are no more results\n}\nfunction TZSQLiteStatement.Execute(const SQL: RawByteString): Boolean;\nvar\n  ErrorCode: Integer;\n  StmtHandle: Psqlite_vm;\n  ColumnCount: Integer;\n  ColumnValues: PPAnsiChar;\n  ColumnNames: PPAnsiChar;\nbegin\n  ColumnCount := 0;\n  ColumnValues:=nil;\n  ColumnNames:=nil;\n  ASQL := SQL; //preprapares SQL\n  ErrorCode := FPlainDriver.Prepare(FHandle, PAnsiChar(ASQL), Length(ASQL),\n    StmtHandle, nil);\n  CheckSQLiteError(FPlainDriver, FHandle, ErrorCode, nil, lcExecute, SSQL);\n  DriverManager.LogMessage(lcExecute, FPlainDriver.GetProtocol, SSQL);\n\n  try\n    ErrorCode := FPlainDriver.Step(StmtHandle, ColumnCount,\n      ColumnValues, ColumnNames);\n    CheckSQLiteError(FPlainDriver, FHandle, ErrorCode, nil, lcOther, 'FETCH');\n  except\n    FPlainDriver.Finalize(StmtHandle);\n    raise;\n  end;\n\n  { Process queries with result sets }\n  if ColumnCount <> 0 then\n  begin\n    Result := True;\n    LastResultSet := CreateResultSet(SSQL, StmtHandle, ColumnCount, ColumnNames,\n      ColumnValues);\n  end\n  { Processes regular query. }\n  else\n  begin\n    if assigned(ColumnValues) then\n      Freemem(ColumnValues);\n    if assigned(ColumnNames) then\n      Freemem(ColumnNames);\n    Result := False;\n    LastUpdateCount := FPlainDriver.Changes(FHandle);\n    ErrorCode := FPlainDriver.Finalize(StmtHandle);\n    CheckSQLiteError(FPlainDriver, FHandle, ErrorCode, nil, lcOther,\n      'Finalize SQLite VM');\n  end;\nend;\n\n{$IFDEF ZEOS_TEST_ONLY}\n{ TZSQLitePreparedStatement }\n\n{**\n  Constructs this object and assignes the main properties.\n  @param PlainDriver a native SQLite Plain driver.\n  @param Connection a database connection object.\n  @param Info a statement parameters.\n  @param Handle a connection handle pointer.\n}\nconstructor TZSQLitePreparedStatement.Create(PlainDriver: IZSQLitePlainDriver;\n  Connection: IZConnection; const SQL: string; Info: TStrings; Handle: Psqlite);\nbegin\n  inherited Create(Connection, SQL, Info);\n  FHandle := Handle;\n  FPlainDriver := PlainDriver;\n  ResultSetType := rtForwardOnly;\n  Prepare;\nend;\n\n{**\n  Creates a temporary statement which executes queries.\n  @param Info a statement parameters.\n  @return a created statement object.\n}\nfunction TZSQLitePreparedStatement.CreateExecStatement: IZStatement;\nbegin\n  Result := TZSQLiteStatement.Create(FPlainDriver, Connection, Info,FHandle);\nend;\n\n{**\n  Prepares an SQL parameter for the query.\n  @param ParameterIndex the first parameter is 1, the second is 2, ...\n  @return a string representation of the parameter.\n}\nfunction TZSQLitePreparedStatement.PrepareAnsiSQLParam(ParamIndex: Integer): RawByteString;\nvar\n  Value: TZVariant;\n  TempBlob: IZBlob;\n  TempBytes: TByteDynArray;\nbegin\n  if InParamCount <= ParamIndex then\n    raise EZSQLException.Create(SInvalidInputParameterCount);\n\n  Value := InParamValues[ParamIndex];\n  if DefVarManager.IsNull(Value)  then\n    Result := 'NULL'\n  else\n  begin\n    case InParamTypes[ParamIndex] of\n      stBoolean:\n            if SoftVarManager.GetAsBoolean(Value) then\n               Result := '''Y'''\n            else\n               Result := '''N''';\n      stByte, stShort, stInteger, stLong, stBigDecimal, stFloat, stDouble:\n        Result := RawByteString(SoftVarManager.GetAsString(Value));\n      stBytes:\n        begin\n          TempBytes := SoftVarManager.GetAsBytes(Value);\n          Result := EncodeString(@TempBytes, Length(TempBytes));\n        end;\n      stString:\n        Result := ZPlainString(AnsiQuotedStr(SoftVarManager.GetAsString(Value), #39));\n      stUnicodeString:\n        {$IFDEF UNICODE}\n        Result := ZPlainString(AnsiQuotedStr(SoftVarManager.GetAsUnicodeString(Value), #39));\n        {$ELSE}\n        Result := AnsiQuotedStr(ZPlainString(SoftVarManager.GetAsUnicodeString(Value)), #39);\n        {$ENDIF}\n      stDate:\n        Result := '''' + RawByteString(FormatDateTime('yyyy-mm-dd',\n          SoftVarManager.GetAsDateTime(Value))) + '''';\n      stTime:\n        Result := '''' + RawByteString(FormatDateTime('hh:mm:ss',\n          SoftVarManager.GetAsDateTime(Value))) + '''';\n      stTimestamp:\n        Result := '''' + RawByteString(FormatDateTime('yyyy-mm-dd hh:mm:ss',\n          SoftVarManager.GetAsDateTime(Value))) + '''';\n      stAsciiStream, stUnicodeStream, stBinaryStream:\n        begin\n          TempBlob := DefVarManager.GetAsInterface(Value) as IZBlob;\n          if not TempBlob.IsEmpty then\n            if InParamTypes[ParamIndex] = stBinaryStream then\n              Result := EncodeString(TempBlob.GetBuffer, TempBlob.Length)\n            else\n              Result := {$IFDEF WITH_UNITANSISTRINGS}AnsiStrings.{$ENDIF}AnsiQuotedStr(\n                GetValidatedAnsiStringFromBuffer(TempBlob.GetBuffer,\n                TempBlob.Length, TempBlob.WasDecoded, ConSettings), #39)\n          else\n            Result := 'NULL';\n        end;\n    end;\n  end;\nend;\n{$ENDIF}\n\n\nprocedure BindingDestructor(Value: PAnsiChar); cdecl;\nbegin\n  {$IFDEF WITH_STRDISPOSE_DEPRECATED}AnsiStrings.{$ENDIF}StrDispose(Value);\nend;\n\n{ TZSQLiteCAPIPreparedStatement }\n\nfunction TZSQLiteCAPIPreparedStatement.CreateResultSet(const SQL: string;\n  StmtHandle: Psqlite_vm; ColumnCount: Integer; ColumnNames: PPAnsiChar;\n  ColumnValues: PPAnsiChar): IZResultSet;\nvar\n  CachedResolver: TZSQLiteCachedResolver;\n  NativeResultSet: TZSQLiteResultSet;\n  CachedResultSet: TZCachedResultSet;\nbegin\n  { Creates a native result set. }\n  Self.SSQL := SQL;\n  NativeResultSet := TZSQLiteResultSet.Create(FPlainDriver, Self, SSQL, FHandle,\n    StmtHandle, ColumnCount, ColumnNames, ColumnValues, False);\n  NativeResultSet.SetConcurrency(rcReadOnly);\n\n  { Creates a cached result set. }\n  CachedResolver := TZSQLiteCachedResolver.Create(FPlainDriver, FHandle, Self,\n    NativeResultSet.GetMetaData);\n  CachedResultSet := TZCachedResultSet.Create(NativeResultSet, SSQL,\n    CachedResolver,GetConnection.GetConSettings);\n\n  { Fetches all rows to prevent blocking. }\n  CachedResultSet.SetType(rtScrollInsensitive);\n  CachedResultSet.Last;\n  CachedResultSet.BeforeFirst;\n  CachedResultSet.SetConcurrency(GetResultSetConcurrency);\n\n  Result := CachedResultSet;\n  FOpenResultSet := Pointer(Result);\nend;\n\nprocedure TZSQLiteCAPIPreparedStatement.SetASQL(const Value: RawByteString);\nbegin\n  if ( ASQL <> Value ) and Prepared then\n    Unprepare;\n  inherited SetASQL(Value);\nend;\n\nprocedure TZSQLiteCAPIPreparedStatement.SetWSQL(const Value: ZWideString);\nbegin\n  if ( WSQL <> Value ) and Prepared then\n    Unprepare;\n  inherited SetWSQL(Value);\nend;\n\nprocedure TZSQLiteCAPIPreparedStatement.FreeReference;\nbegin\n  FOpenResultSet := nil;\nend;\n\nprocedure TZSQLiteCAPIPreparedStatement.PrepareInParameters;\nbegin\n  if FPlainDriver.bind_parameter_count(FStmtHandle) <> InParamCount then\n    raise Exception.Create('Invalid InParamCount');\nend;\n\nprocedure TZSQLiteCAPIPreparedStatement.BindInParameters;\nvar\n  Value: TZVariant;\n  TempBlob: IZBlob;\n  I, L: Integer;\n  TempAnsi: RawByteString;\n  Bts: TByteDynArray;\n\n  Function AsPAnsiChar(Const S : RawByteString; Len: Integer) : PAnsiChar;\n  begin\n    Result := {$IFDEF UNICODE}AnsiStrAlloc{$ELSE}StrAlloc{$ENDIF}(Len);\n    System.Move(PAnsiChar(S)^, Result^, Len);\n  end;\n\nbegin\n  FErrorcode := FPlainDriver.clear_bindings(FStmtHandle);\n  CheckSQLiteError(FPlainDriver, FStmtHandle, FErrorCode, nil, lcBindPrepStmt, SSQL);\n  for i := 1 to InParamCount do\n  begin\n    Value := InParamValues[i-1];\n    if DefVarManager.IsNull(Value)  then\n      FErrorcode := FPlainDriver.bind_null(FStmtHandle, I)\n    else\n    begin\n      case InParamTypes[I-1] of\n        stBoolean:\n          if SoftVarManager.GetAsBoolean(Value) then\n            FErrorcode := FPlainDriver.bind_text(FStmtHandle, i,\n            {$IFDEF WITH_STRNEW_DEPRECATED}AnsiStrings.{$ENDIF}StrNew(PAnsiChar(AnsiString('Y'))), 1, @BindingDestructor)\n          else\n            FErrorcode := FPlainDriver.bind_text(FStmtHandle, i,\n              {$IFDEF WITH_STRNEW_DEPRECATED}AnsiStrings.{$ENDIF}StrNew(PAnsichar(AnsiString('N'))), 1, @BindingDestructor);\n        stByte, stShort, stInteger:\n          FErrorcode := FPlainDriver.bind_int(FStmtHandle, i,\n            SoftVarManager.GetAsInteger(Value));\n        stLong:\n          FErrorcode := FPlainDriver.bind_int64(FStmtHandle, i,\n            SoftVarManager.GetAsInteger(Value));\n        stBigDecimal, stFloat, stDouble:\n          FErrorcode := FPlainDriver.bind_double(FStmtHandle, i,\n            SoftVarManager.GetAsFloat(Value));\n        stBytes:\n          begin\n            Bts := SoftVarManager.GetAsBytes(Value);\n            L := Length(Bts);\n            ZSetString(PAnsiChar(Bts), L, TempAnsi);\n            FErrorcode := FPlainDriver.bind_blob(FStmtHandle, i,\n              AsPAnsiChar(TempAnsi, L), L, @BindingDestructor)\n          end;\n        stString:\n          {$IFDEF FPC} //FPC StrNew fails for '' strings and returns nil\n          begin\n            TempAnsi := ZPlainString(SoftVarManager.GetAsString(Value));\n            if TempAnsi = '' then\n              FErrorcode := FPlainDriver.bind_text(FStmtHandle, i,\n                AsPAnsiChar(TempAnsi, 1), 0, @BindingDestructor)\n            else\n              FErrorcode := FPlainDriver.bind_text(FStmtHandle, i,\n              StrNew(PAnsichar(TempAnsi)), -1, @BindingDestructor);\n          end;\n          {$ELSE}\n          FErrorcode := FPlainDriver.bind_text(FStmtHandle, i,\n          {$IFDEF WITH_STRNEW_DEPRECATED}AnsiStrings.{$ENDIF}StrNew(PAnsichar(ZPlainString(SoftVarManager.GetAsString(Value)))),\n              -1, @BindingDestructor);\n          {$ENDIF}\n        stUnicodeString:\n          {$IFDEF FPC} //FPC StrNew fails for '' strings and returns nil\n          begin\n            TempAnsi := ZPlainString(SoftVarManager.GetAsUnicodeString(Value));\n            if TempAnsi = '' then\n              FErrorcode := FPlainDriver.bind_text(FStmtHandle, i,\n                AsPAnsiChar(TempAnsi, 1), 0, @BindingDestructor)\n            else\n              FErrorcode := FPlainDriver.bind_text(FStmtHandle, i,\n              StrNew(PAnsichar(TempAnsi)), -1, @BindingDestructor);\n          end;\n          {$ELSE}\n          FErrorcode := FPlainDriver.bind_text(FStmtHandle, i,\n            {$IFDEF WITH_STRNEW_DEPRECATED}AnsiStrings.{$ENDIF}StrNew(PAnsichar(ZPlainString(SoftVarManager.GetAsUnicodeString(Value)))),\n               -1, @BindingDestructor);\n          {$ENDIF}\n        stDate:\n          FErrorcode := FPlainDriver.bind_text(FStmtHandle, i,\n            {$IFDEF WITH_STRNEW_DEPRECATED}AnsiStrings.{$ENDIF}StrNew(PAnsichar(RawByteString(FormatDateTime('yyyy-mm-dd',\n            SoftVarManager.GetAsDateTime(Value))))),\n                10, @BindingDestructor);\n        stTime:\n          FErrorcode := FPlainDriver.bind_text(FStmtHandle, i,\n            {$IFDEF WITH_STRNEW_DEPRECATED}AnsiStrings.{$ENDIF}StrNew(PAnsichar(RawByteString(FormatDateTime('hh:mm:ss',\n            SoftVarManager.GetAsDateTime(Value))))),\n                8, @BindingDestructor);\n        stTimestamp:\n          FErrorcode := FPlainDriver.bind_text(FStmtHandle, i,\n            {$IFDEF WITH_STRNEW_DEPRECATED}AnsiStrings.{$ENDIF}StrNew(PAnsichar(RawByteString(FormatDateTime('yyyy-mm-dd hh:mm:ss',\n            SoftVarManager.GetAsDateTime(Value))))),\n                19, @BindingDestructor);\n        { works equal but selects from data which was written in string format\n          won't match! e.G. TestQuery etc. On the other hand-> i've prepared\n          this case on the resultsets too. JULIAN_DAY_PRECISION?}\n        {stDate, stTime, stTimestamp:\n          FErrorcode := FPlainDriver.bind_double(FStmtHandle, i,\n            SoftVarManager.GetAsDateTime(Value));}\n        stAsciiStream, stUnicodeStream, stBinaryStream:\n          begin\n            TempBlob := DefVarManager.GetAsInterface(Value) as IZBlob;\n            if not TempBlob.IsEmpty then\n              if InParamTypes[I-1] = stBinaryStream then\n              begin\n                TempAnsi := TempBlob.GetString;\n                FErrorcode := FPlainDriver.bind_blob(FStmtHandle, i,\n                  AsPAnsiChar(TempAnsi, TempBlob.Length), TempBlob.Length,\n                    @BindingDestructor)\n              end\n              else\n              begin\n                TempAnsi := GetValidatedAnsiStringFromBuffer(TempBlob.GetBuffer,\n                  TempBlob.Length, TempBlob.WasDecoded, ConSettings);\n                FErrorcode := FPlainDriver.bind_text(FStmtHandle, i,\n                  {$IFDEF WITH_STRNEW_DEPRECATED}AnsiStrings.{$ENDIF}StrNew(PAnsiChar(TempAnsi)),\n                  Length(TempAnsi), @BindingDestructor);\n              end\n            else\n              FErrorcode := FPlainDriver.bind_null(FStmtHandle, I);\n          end;\n      end;\n    end;\n    CheckSQLiteError(FPlainDriver, FStmtHandle, FErrorCode, nil, lcBindPrepStmt, SSQL);\n  end;\nend;\n\nconstructor TZSQLiteCAPIPreparedStatement.Create(PlainDriver: IZSQLitePlainDriver;\n  Connection: IZConnection; const SQL: string; Info: TStrings; Handle: Psqlite);\nbegin\n  inherited Create(Connection, SQL, Info);\n  FHandle := Handle;\n  FPlainDriver := PlainDriver;\n  ResultSetType := rtForwardOnly;\nend;\n\nprocedure TZSQLiteCAPIPreparedStatement.Prepare;\nbegin\n  FErrorCode := FPlainDriver.Prepare_v2(FHandle, PAnsiChar(ASQL), Length(ASQL), FStmtHandle, nil);\n  CheckSQLiteError(FPlainDriver, FHandle, FErrorCode, nil, lcPrepStmt, SSQL);\n  inherited Prepare;\nend;\n\nprocedure TZSQLiteCAPIPreparedStatement.Unprepare;\nbegin\n  if Assigned(FStmtHandle) then\n    FErrorCode := FPlainDriver.Finalize(FStmtHandle)\n  else\n    FErrorCode := SQLITE_OK;\n  FStmtHandle := nil;\n  CheckSQLiteError(FPlainDriver, FStmtHandle, FErrorCode, nil,\n    lcUnprepStmt, 'Unprepare SQLite Statement');\n  inherited UnPrepare;\nend;\n\nfunction TZSQLiteCAPIPreparedStatement.ExecuteQueryPrepared: IZResultSet;\nvar\n  ColumnCount: Integer;\n  ColumnValues: PPAnsiChar;\n  ColumnNames: PPAnsiChar;\nbegin\n  if Not Prepared then\n     Prepare;\n  { after reading the last row we reset the statment. So we don't need this here }\n  ColumnValues := nil;\n  ColumnNames := nil;\n  ColumnCount := 0;\n  try\n    if FOpenResultSet <> nil then\n      IZResultSet(FOpenResultSet).Close; // reset stmt\n    FOpenResultSet := nil;\n\n    BindInParameters;\n    FErrorCode := FPlainDriver.Step(FStmtHandle, ColumnCount,\n      ColumnValues, ColumnNames);\n    CheckSQLiteError(FPlainDriver, FStmtHandle, FErrorCode, nil, lcOther, SCanNotRetrieveResultsetData);\n  except\n    if ColumnValues <> nil then\n      FreeMem(ColumnValues);\n    ColumnValues := nil;\n    if ColumnNames <> nil then\n      FreeMem(ColumnNames);\n    ColumnNames := nil;\n    raise;\n  end;\n\n  Result := CreateResultSet(SSQL, FStmtHandle, ColumnCount, ColumnNames,\n    ColumnValues);\nend;\n\nfunction TZSQLiteCAPIPreparedStatement.ExecuteUpdatePrepared: Integer;\nbegin\n  if Not Prepared then\n     Prepare;\n  BindInParameters;\n\n  Result := 0;\n  try\n    FErrorCode := FPlainDriver.Step(FStmtHandle);\n    CheckSQLiteError(FPlainDriver, FStmtHandle, FErrorCode, nil, lcExecPrepStmt, SSQL);\n    Result := FPlainDriver.Changes(FHandle);\n  finally\n    FErrorCode := FPlainDriver.reset(FStmtHandle); //no errorcheck!\n    LastUpdateCount := Result;\n  end;\n  { Autocommit statement. }\n  if Connection.GetAutoCommit then\n    Connection.Commit;\nend;\n\nfunction TZSQLiteCAPIPreparedStatement.ExecutePrepared: Boolean;\nvar\n  ColumnCount: Integer;\n  ColumnValues: PPAnsiChar;\n  ColumnNames: PPAnsiChar;\nbegin\n  if Not Prepared then\n     Prepare;\n\n  ColumnCount := 0;\n  ColumnValues:=nil;\n  ColumnNames:=nil;\n  try\n    BindInParameters;\n\n    FErrorCode := FPlainDriver.Step(FStmtHandle, ColumnCount,\n      ColumnValues, ColumnNames);\n    CheckSQLiteError(FPlainDriver, FStmtHandle, FErrorCode, nil, lcExecPrepStmt, 'Step');\n  except\n    raise;\n  end;\n\n  { Process queries with result sets }\n  if ColumnCount <> 0 then\n  begin\n    Result := True;\n    LastResultSet := CreateResultSet(SSQL, FStmtHandle, ColumnCount, ColumnNames,\n      ColumnValues);\n  end\n  { Processes regular query. }\n  else\n  begin\n    if assigned(ColumnValues) then\n      Freemem(ColumnValues);\n    if assigned(ColumnNames) then\n      Freemem(ColumnNames);\n    Result := False;\n    LastUpdateCount := FPlainDriver.Changes(FHandle);\n    FErrorCode := FPlainDriver.reset(FStmtHandle);\n    CheckSQLiteError(FPlainDriver, FStmtHandle, FErrorCode, nil, lcOther, 'Reset');\n  end;\n  { Autocommit statement. }\n  if not Result and Connection.GetAutoCommit then\n    Connection.Commit;\n\n  inherited ExecutePrepared;\nend;\n\nend.\n\n"
  },
  {
    "path": "lib/zeosdbo/src/dbc/ZDbcSqLiteUtils.pas",
    "content": "{*********************************************************}\n{                                                         }\n{                 Zeos Database Objects                   }\n{           SQLite Database Connectivity Classes          }\n{                                                         }\n{        Originally written by Sergey Seroukhov           }\n{                                                         }\n{*********************************************************}\n\n{@********************************************************}\n{    Copyright (c) 1999-2012 Zeos Development Group       }\n{                                                         }\n{ License Agreement:                                      }\n{                                                         }\n{ This library is distributed in the hope that it will be }\n{ useful, but WITHOUT ANY WARRANTY; without even the      }\n{ implied warranty of MERCHANTABILITY or FITNESS FOR      }\n{ A PARTICULAR PURPOSE.  See the GNU Lesser General       }\n{ Public License for more details.                        }\n{                                                         }\n{ The source code of the ZEOS Libraries and packages are  }\n{ distributed under the Library GNU General Public        }\n{ License (see the file COPYING / COPYING.ZEOS)           }\n{ with the following  modification:                       }\n{ As a special exception, the copyright holders of this   }\n{ library give you permission to link this library with   }\n{ independent modules to produce an executable,           }\n{ regardless of the license terms of these independent    }\n{ modules, and to copy and distribute the resulting       }\n{ executable under terms of your choice, provided that    }\n{ you also meet, for each linked independent module,      }\n{ the terms and conditions of the license of that module. }\n{ An independent module is a module which is not derived  }\n{ from or based on this library. If you modify this       }\n{ library, you may extend this exception to your version  }\n{ of the library, but you are not obligated to do so.     }\n{ If you do not wish to do so, delete this exception      }\n{ statement from your version.                            }\n{                                                         }\n{                                                         }\n{ The project web site is located on:                     }\n{   http://zeos.firmos.at  (FORUM)                        }\n{   http://sourceforge.net/p/zeoslib/tickets/ (BUGTRACKER)}\n{   svn://svn.code.sf.net/p/zeoslib/code-0/trunk (SVN)    }\n{                                                         }\n{   http://www.sourceforge.net/projects/zeoslib.          }\n{                                                         }\n{                                                         }\n{                                 Zeos Development Group. }\n{********************************************************@}\n\nunit ZDbcSqLiteUtils;\n\ninterface\n\n{$I ZDbc.inc}\n\nuses\n  Classes, SysUtils, ZSysUtils, ZDbcIntfs, ZPlainSqLiteDriver, ZDbcLogging, ZCompatibility;\n\n{**\n  Convert string SQLite field type to SQLType\n  @param string field type value\n  @param Precision the column precision or size\n  @param Decimals the column position after decimal point\n  @result the SQLType field type value\n}\nfunction ConvertSQLiteTypeToSQLType(TypeName: string; var Precision: Integer;\n  var Decimals: Integer; const CtrlsCPType: TZControlsCodePage): TZSQLType;\n\n{**\n  Checks for possible sql errors.\n  @param PlainDriver a SQLite plain driver.\n  @param ErrorCode an error code.\n  @param ErrorMessage an error message.\n  @param LogCategory a logging category.\n  @param LogMessage a logging message.\n}\nprocedure CheckSQLiteError(PlainDriver: IZSQLitePlainDriver;\n  Handle: PSqlite;\n  ErrorCode: Integer; ErrorMessage: PAnsiChar;\n  LogCategory: TZLoggingCategory; LogMessage: string);\n\n{**\n  Converts an string into escape PostgreSQL format.\n  @param Value a regular string.\n  @return a string in PostgreSQL escape format.\n}\nfunction EncodeString(Buffer: PAnsiChar; Len: Integer): RawByteString; overload;\nfunction EncodeString(Value: RawByteString): RawByteString; overload;\n\n{**\n  Converts an string from escape PostgreSQL format.\n  @param Value a string in PostgreSQL escape format.\n  @return a regular string.\n}\nfunction DecodeString(Value: ansistring): ansistring;\n\n{**\n  Decodes a SQLite Version Value and Encodes it to a Zeos SQL Version format:\n   (major_version * 1,000,000) + (minor_version * 1,000) + sub_version\n  into separated major, minor and subversion values\n  @param SQLiteVersion an integer containing the Full Version to decode.\n  @return Encoded Zeos SQL Version Value.\n}\nfunction ConvertSQLiteVersionToSQLVersion( const SQLiteVersion: PAnsiChar ): Integer;\n\n\nimplementation\n\nuses ZMessages{$IFDEF WITH_UNITANSISTRINGS}, AnsiStrings{$ENDIF};\n\n{**\n  Convert string SQLite field type to SQLType\n  @param string field type value\n  @param Precision the column precision or size\n  @param Decimals the column position after decimal point\n  @result the SQLType field type value\n}\nfunction ConvertSQLiteTypeToSQLType(TypeName: string; var Precision: Integer;\n  var Decimals: Integer; const CtrlsCPType: TZControlsCodePage): TZSQLType;\nvar\n  P1, P2: Integer;\n  Temp: string;\nbegin\n  TypeName := UpperCase(TypeName);\n  Result := stString;\n  Precision := 0;\n  Decimals := 0;\n\n  P1 := Pos('(', TypeName);\n  P2 := Pos(')', TypeName);\n  if (P1 > 0) and (P2 > 0) then\n  begin\n    Temp := Copy(TypeName, P1 + 1, P2 - P1 - 1);\n    TypeName := Copy(TypeName, 1, P1 - 1);\n    P1 := Pos(',', Temp);\n    if P1 > 0 then\n    begin\n      Precision := StrToIntDef(Copy(Temp, 1, P1 - 1), 0);\n      Decimals := StrToIntDef(Copy(Temp, P1 + 1, Length(Temp) - P1), 0);\n    end\n    else\n      Precision := StrToIntDef(Temp, 0);\n  end;\n\n  if StartsWith(TypeName, 'BOOL') then\n    Result := stBoolean\n  else if TypeName = 'TINYINT' then\n    Result := stShort\n  else if TypeName = 'SMALLINT' then\n    Result := stShort\n  else if TypeName = 'MEDIUMINT' then\n    Result := stInteger\n  else if TypeName = {$IFDEF UNICODE}RawByteString{$ENDIF}('INTEGER') then\n    Result := stLong //http://www.sqlite.org/autoinc.html\n  else if StartsWith(TypeName, {$IFDEF UNICODE}RawByteString{$ENDIF}('INT')) then\n    Result := stInteger\n  else if TypeName = 'BIGINT' then\n    Result := stLong\n  else if StartsWith(TypeName, 'REAL') then\n    Result := stDouble\n  else if StartsWith(TypeName, 'FLOAT') then\n    Result := stDouble\n  else if (TypeName = 'NUMERIC') or (TypeName = 'DECIMAL')\n    or (TypeName = 'NUMBER') then\n  begin\n   { if Decimals = 0 then\n      Result := stInteger\n    else} Result := stDouble;\n  end\n  else if StartsWith(TypeName, 'DOUB') then\n    Result := stDouble\n  else if TypeName = 'MONEY' then\n    Result := stBigDecimal\n  else if StartsWith(TypeName, 'CHAR') then\n    Result := stString\n  else if TypeName = 'VARCHAR' then\n    Result := stString\n  else if TypeName = 'VARBINARY' then\n    Result := stBytes\n  else if TypeName = 'BINARY' then\n    Result := stBytes\n  else if TypeName = 'DATE' then\n    Result := stDate\n  else if TypeName = 'TIME' then\n    Result := stTime\n  else if TypeName = 'TIMESTAMP' then\n    Result := stTimestamp\n  else if TypeName = 'DATETIME' then\n    Result := stTimestamp\n  else if Pos('BLOB', TypeName) > 0 then\n    Result := stBinaryStream\n  else if Pos('CLOB', TypeName) > 0 then\n    Result := stAsciiStream\n  else if Pos('TEXT', TypeName) > 0 then\n    Result := stAsciiStream;\n\n  if (Result = stInteger) and (Precision <> 0) then\n  begin\n    if Precision <= 2 then\n      Result := stByte\n    else if Precision <= 4 then\n      Result := stShort\n    else if Precision <= 9 then\n      Result := stInteger\n    else\n      Result := stLong;\n  end;\n\n  if ( CtrlsCPType = cCP_UTF16 ) then\n    case Result of\n      stString:  Result := stUnicodeString;\n      stAsciiStream: Result := stUnicodeStream;\n    end;\n\n  if (Result = stString) then\n    if (Precision = 0) then\n      Precision := 255 *{$IFDEF UNICODE}2{$ELSE}4{$ENDIF}//UTF8 assumes 4Byte/Char\n    else\n      Precision := Precision*{$IFDEF UNICODE}2{$ELSE}4{$ENDIF};//UTF8 assumes 4Byte/Char\n\n  if (Result = stUnicodeString) then\n    if (Precision = 0) then\n      Precision := 255 * 2 //UTF8 assumes 4Byte/Char -> 2 * UnicodeChar\n    else\n      Precision := Precision * 2;//UTF8 assumes 4Byte/Char\n\nend;\n\n{**\n  Checks for possible sql errors.\n  @param PlainDriver a SQLite plain driver.\n  @param ErrorCode an error code.\n  @param ErrorMessage an error message.\n  @param LogCategory a logging category.\n  @param LogMessage a logging message.\n}\nprocedure CheckSQLiteError(PlainDriver: IZSQLitePlainDriver;\n  Handle: PSqlite;\n  ErrorCode: Integer; ErrorMessage: PAnsiChar;\n  LogCategory: TZLoggingCategory; LogMessage: string);\nvar\n  Error: string;\nbegin\n  if ErrorMessage <> nil then\n  begin\n  {$IFDEF UNICODE}\n    Error := trim(UTF8ToUnicodeString(ErrorMessage));\n  {$ELSE}\n    {$IFNDEF FPC}\n    Error := Trim(UTF8ToAnsi(StrPas(ErrorMessage)));\n    {$ELSE}\n    Error := Trim(StrPas(ErrorMessage));\n    {$ENDIF}\n  {$ENDIF}\n    PlainDriver.FreeMem(ErrorMessage);\n  end\n  else\n    Error := '';\n  if not (ErrorCode in [SQLITE_OK, SQLITE_ROW, SQLITE_DONE]) then\n  begin\n    if Error = '' then\n      Error := PlainDriver.ErrorString(Handle, ErrorCode);\n    DriverManager.LogError(LogCategory, PlainDriver.GetProtocol, LogMessage,\n      ErrorCode, Error);\n    raise EZSQLException.CreateWithCode(ErrorCode, Format(SSQLError1, [Error]));\n  end;\nend;\n\n\nfunction NewEncodeString(Buffer: PAnsiChar; Len: Integer): RawByteString; overload;\nvar\n  I: Integer;\n  ihx : integer;\n  shx : ansistring;\nbegin\n  SetLength( Result,3 + Len * 2 );\n  Result[1] := 'x'; // set x\n  Result[2] := ''''; // set Open Quote\n  ihx := 3; // set 1st hex location\n  for I := 1 to Len do\n  begin\n    shx := AnsiString(IntToHex( ord(Buffer^),2 )); // eg. '3E'\n    result[ihx] := shx[1]; Inc( ihx,1 ); // copy '3'\n    result[ihx] := shx[2]; Inc( ihx,1 ); // copy 'E'\n    Inc( Buffer,1 ); // next byte source location\n  end;\n  result[ihx] := ''''; // set Close Quote\nend;\n\nfunction NewEncodeString(Value: RawByteString): RawByteString; overload;\nbegin\n  Result := NewEncodeString(PAnsiChar(Value), Length(Value));\nend;\n\nfunction NewDecodeString(Value:ansistring):ansistring;\nvar\n  i : integer;\n  srcbuffer : PAnsichar;\nbegin\n  value := copy(value,3,length(value)-4);\n  value := {$IFDEF WITH_UNITANSISTRINGS}AnsiStrings.{$ENDIF}AnsiLowercase(value);\n  i := length(value) div 2;\n  srcbuffer := PAnsiChar(value);\n  setlength(result,i);\n  HexToBin(PAnsiChar(srcbuffer),PAnsiChar(result),i);\nend;\n\n{**\n  Converts an string into escape PostgreSQL format.\n  @param Value a regular string.\n  @return a string in PostgreSQL escape format.\n}\n\nfunction EncodeString(Buffer: PAnsiChar; Len: Integer): RawByteString; overload;\nbegin\n  result := NewEncodeString(Buffer, Len);\nend;\n\nfunction EncodeString(Value: RawByteString): RawByteString; overload;\nbegin\n  result := NewEncodeString(Value);\nend;\n\n{**\n  Converts an string from escape PostgreSQL format.\n  @param Value a string in PostgreSQL escape format.\n  @return a regular string.\n}\nfunction DecodeString(Value: ansistring): ansistring;\nvar\n  SrcLength, DestLength: Integer;\n  SrcBuffer, DestBuffer: PAnsiChar;\nbegin\n  if pos('x''',String(value))= 1 then\n    result := NewDecodeString(value)\n  else\n  begin\n    SrcLength := Length(Value);\n    SrcBuffer := PAnsiChar(Value);\n    SetLength(Result, SrcLength);\n    DestLength := 0;\n    DestBuffer := PAnsiChar(Result);\n\n    while SrcLength > 0 do\n    begin\n      if SrcBuffer^ = '%' then\n      begin\n        Inc(SrcBuffer);\n        if SrcBuffer^ <> '0' then\n          DestBuffer^ := SrcBuffer^\n        else\n          DestBuffer^ := #0;\n        Inc(SrcBuffer);\n        Dec(SrcLength, 2);\n      end\n      else\n      begin\n        DestBuffer^ := SrcBuffer^;\n        Inc(SrcBuffer);\n        Dec(SrcLength);\n      end;\n      Inc(DestBuffer);\n      Inc(DestLength);\n    end;\n    SetLength(Result, DestLength);\n  end;\nend;\n\n{**\n  Decodes a SQLite Version Value and Encodes it to a Zeos SQL Version format:\n   (major_version * 1,000,000) + (minor_version * 1,000) + sub_version\n  into separated major, minor and subversion values\n  @param SQLiteVersion an integer containing the Full Version to decode.\n  @return Encoded Zeos SQL Version Value.\n}\nfunction ConvertSQLiteVersionToSQLVersion( const SQLiteVersion: PAnsiChar ): Integer;\nvar\n  MajorVersion, MinorVersion, SubVersion: Integer;\n  s:string;\nbegin\n  s:=String(SQLiteVersion);\n  MajorVersion:=StrToIntDef(copy(s,1,pos('.',s)-1),0);\n  delete(s,1,pos('.',s));\n  MinorVersion:=StrToIntDef(copy(s,1,pos('.',s)-1),0);\n  delete(s,1,pos('.',s));\n  SubVersion:=StrToIntDef(s,0);\n  Result := EncodeSQLVersioning(MajorVersion,MinorVersion,SubVersion);\nend;\n\nend.\n\n"
  },
  {
    "path": "lib/zeosdbo/src/dbc/ZDbcStatement.pas",
    "content": "{*********************************************************}\n{                                                         }\n{                 Zeos Database Objects                   }\n{         Abstract Database Connectivity Classes          }\n{                                                         }\n{        Originally written by Sergey Seroukhov           }\n{                                                         }\n{*********************************************************}\n\n{@********************************************************}\n{    Copyright (c) 1999-2012 Zeos Development Group       }\n{                                                         }\n{ License Agreement:                                      }\n{                                                         }\n{ This library is distributed in the hope that it will be }\n{ useful, but WITHOUT ANY WARRANTY; without even the      }\n{ implied warranty of MERCHANTABILITY or FITNESS FOR      }\n{ A PARTICULAR PURPOSE.  See the GNU Lesser General       }\n{ Public License for more details.                        }\n{                                                         }\n{ The source code of the ZEOS Libraries and packages are  }\n{ distributed under the Library GNU General Public        }\n{ License (see the file COPYING / COPYING.ZEOS)           }\n{ with the following  modification:                       }\n{ As a special exception, the copyright holders of this   }\n{ library give you permission to link this library with   }\n{ independent modules to produce an executable,           }\n{ regardless of the license terms of these independent    }\n{ modules, and to copy and distribute the resulting       }\n{ executable under terms of your choice, provided that    }\n{ you also meet, for each linked independent module,      }\n{ the terms and conditions of the license of that module. }\n{ An independent module is a module which is not derived  }\n{ from or based on this library. If you modify this       }\n{ library, you may extend this exception to your version  }\n{ of the library, but you are not obligated to do so.     }\n{ If you do not wish to do so, delete this exception      }\n{ statement from your version.                            }\n{                                                         }\n{                                                         }\n{ The project web site is located on:                     }\n{   http://zeos.firmos.at  (FORUM)                        }\n{   http://sourceforge.net/p/zeoslib/tickets/ (BUGTRACKER)}\n{   svn://svn.code.sf.net/p/zeoslib/code-0/trunk (SVN)    }\n{                                                         }\n{   http://www.sourceforge.net/projects/zeoslib.          }\n{                                                         }\n{                                                         }\n{                                 Zeos Development Group. }\n{********************************************************@}\n\nunit ZDbcStatement;\n\ninterface\n\n{$I ZDbc.inc}\n\nuses\n  Types, Classes, {$IFDEF MSEgui}mclasses,{$ENDIF} SysUtils,\n  ZDbcIntfs, ZTokenizer, ZCompatibility, ZVariant, ZDbcLogging, ZClasses,\n  ZPlainDriver;\n\ntype\n  TZSQLTypeArray = array of TZSQLType;\n\n  {** Implements Abstract Generic SQL Statement. }\n\n  { TZAbstractStatement }\n\n  TZAbstractStatement = class(TZCodePagedObject, IZStatement)\n  private\n    FMaxFieldSize: Integer;\n    FMaxRows: Integer;\n    FEscapeProcessing: Boolean;\n    FQueryTimeout: Integer;\n    FLastUpdateCount: Integer;\n    FLastResultSet: IZResultSet;\n    FFetchDirection: TZFetchDirection;\n    FFetchSize: Integer;\n    FResultSetConcurrency: TZResultSetConcurrency;\n    FResultSetType: TZResultSetType;\n    FPostUpdates: TZPostUpdatesMode;\n    FLocateUpdates: TZLocateUpdatesMode;\n    FCursorName: AnsiString;\n    FBatchQueries: TStrings;\n    FConnection: IZConnection;\n    FInfo: TStrings;\n    FChunkSize: Integer; //size of buffer chunks for large lob's related to network settings\n    FClosed: Boolean;\n    FWSQL: ZWideString;\n    FaSQL: RawByteString;\n    FIsAnsiDriver: Boolean;\n    procedure SetLastResultSet(ResultSet: IZResultSet); virtual;\n  protected\n    procedure SetASQL(const Value: RawByteString); virtual;\n    procedure SetWSQL(const Value: ZWideString); virtual;\n    class function GetNextStatementId : integer;\n    procedure RaiseUnsupportedException;\n\n    property MaxFieldSize: Integer read FMaxFieldSize write FMaxFieldSize;\n    property MaxRows: Integer read FMaxRows write FMaxRows;\n    property EscapeProcessing: Boolean\n      read FEscapeProcessing write FEscapeProcessing;\n    property QueryTimeout: Integer read FQueryTimeout write FQueryTimeout;\n    property LastUpdateCount: Integer\n      read FLastUpdateCount write FLastUpdateCount;\n    property LastResultSet: IZResultSet\n      read FLastResultSet write SetLastResultSet;\n    property FetchDirection: TZFetchDirection\n      read FFetchDirection write FFetchDirection;\n    property FetchSize: Integer read FFetchSize write FFetchSize;\n    property ResultSetConcurrency: TZResultSetConcurrency\n      read FResultSetConcurrency write FResultSetConcurrency;\n    property ResultSetType: TZResultSetType\n      read FResultSetType write FResultSetType;\n    property CursorName: AnsiString read FCursorName write FCursorName;\n    property BatchQueries: TStrings read FBatchQueries;\n    property Connection: IZConnection read FConnection;\n    property Info: TStrings read FInfo;\n    property Closed: Boolean read FClosed write FClosed;\n\n    {EgonHugeist SSQL only because of compatibility to the old code available}\n    property SSQL: {$IF defined(FPC) and defined(WITH_RAWBYTESTRING)}RawByteString{$ELSE}String{$IFEND} read {$IFDEF UNICODE}FWSQL{$ELSE}FaSQL{$ENDIF} write {$IFDEF UNICODE}SetWSQL{$ELSE}SetASQL{$ENDIF};\n    property WSQL: ZWideString read FWSQL write SetWSQL;\n    property ASQL: RawByteString read FaSQL write SetASQL;\n    property LogSQL: String read {$IFDEF UNICODE}FWSQL{$ELSE}FaSQL{$ENDIF};\n    property ChunkSize: Integer read FChunkSize;\n    property IsAnsiDriver: Boolean read FIsAnsiDriver;\n  public\n    constructor Create(Connection: IZConnection; Info: TStrings);\n    destructor Destroy; override;\n\n    function ExecuteQuery(const SQL: ZWideString): IZResultSet; overload; virtual;\n    function ExecuteUpdate(const SQL: ZWideString): Integer; overload; virtual;\n    function Execute(const SQL: ZWideString): Boolean; overload; virtual;\n\n    function ExecuteQuery(const SQL: RawByteString): IZResultSet; overload; virtual;\n    function ExecuteUpdate(const SQL: RawByteString): Integer; overload; virtual;\n    function Execute(const SQL: RawByteString): Boolean; overload; virtual;\n\n    procedure Close; virtual;\n\n    function GetMaxFieldSize: Integer; virtual;\n    procedure SetMaxFieldSize(Value: Integer); virtual;\n    function GetMaxRows: Integer; virtual;\n    procedure SetMaxRows(Value: Integer); virtual;\n    procedure SetEscapeProcessing(Value: Boolean); virtual;\n    function GetQueryTimeout: Integer; virtual;\n    procedure SetQueryTimeout(Value: Integer); virtual;\n    procedure Cancel; virtual;\n    procedure SetCursorName(const Value: AnsiString); virtual;\n\n    function GetResultSet: IZResultSet; virtual;\n    function GetUpdateCount: Integer; virtual;\n    function GetMoreResults: Boolean; virtual;\n\n    procedure SetFetchDirection(Value: TZFetchDirection); virtual;\n    function GetFetchDirection: TZFetchDirection; virtual;\n    procedure SetFetchSize(Value: Integer); virtual;\n    function GetFetchSize: Integer; virtual;\n\n    procedure SetResultSetConcurrency(Value: TZResultSetConcurrency); virtual;\n    function GetResultSetConcurrency: TZResultSetConcurrency; virtual;\n    procedure SetResultSetType(Value: TZResultSetType); virtual;\n    function GetResultSetType: TZResultSetType; virtual;\n\n    procedure SetPostUpdates(Value: TZPostUpdatesMode);\n    function GetPostUpdates: TZPostUpdatesMode;\n    procedure SetLocateUpdates(Value: TZLocateUpdatesMode);\n    function GetLocateUpdates: TZLocateUpdatesMode;\n\n    procedure AddBatch(const SQL: string); virtual;\n    procedure ClearBatch; virtual;\n    function ExecuteBatch: TIntegerDynArray; virtual;\n\n    function GetConnection: IZConnection;\n    function GetParameters: TStrings;\n    function GetChunkSize: Integer;\n\n    function GetWarnings: EZSQLWarning; virtual;\n    procedure ClearWarnings; virtual;\n    function GetEncodedSQL(const SQL: {$IF defined(FPC) and defined(WITH_RAWBYTESTRING)}RawByteString{$ELSE}String{$IFEND}): RawByteString; virtual;\n  end;\n\n  {** Implements Abstract Prepared SQL Statement. }\n\n  { TZAbstractPreparedStatement }\n\n  TZAbstractPreparedStatement = class(TZAbstractStatement, IZPreparedStatement)\n  private\n    FSQL: string;\n    FInParamValues: TZVariantDynArray;\n    FInParamTypes: TZSQLTypeArray;\n    FInParamDefaultValues: TStringDynArray;\n    FInParamCount: Integer;\n    FPrepared : Boolean;\n    FExecCount: Integer;\n  protected\n    FStatementId : Integer;\n    procedure PrepareInParameters; virtual;\n    procedure BindInParameters; virtual;\n    procedure UnPrepareInParameters; virtual;\n\n    procedure SetInParamCount(NewParamCount: Integer); virtual;\n    procedure SetInParam(ParameterIndex: Integer; SQLType: TZSQLType;\n      const Value: TZVariant); virtual;\n    procedure LogPrepStmtMessage(Category: TZLoggingCategory; const Msg: string = '');\n    function GetInParamLogValue(Value: TZVariant): String;\n\n    property ExecCount: Integer read FExecCount;\n    property SQL: string read FSQL write FSQL;\n    property InParamValues: TZVariantDynArray\n      read FInParamValues write FInParamValues;\n    property InParamTypes: TZSQLTypeArray\n      read FInParamTypes write FInParamTypes;\n    property InParamDefaultValues: TStringDynArray\n      read FInParamDefaultValues write FInParamDefaultValues;\n    property InParamCount: Integer read FInParamCount write FInParamCount;\n  public\n    constructor Create(Connection: IZConnection; const SQL: string; Info: TStrings);\n    destructor Destroy; override;\n\n    function ExecuteQuery(const SQL: ZWideString): IZResultSet; override;\n    function ExecuteUpdate(const SQL: ZWideString): Integer; override;\n    function Execute(const SQL: ZWideString): Boolean; override;\n\n    function ExecuteQuery(const SQL: RawByteString): IZResultSet; override;\n    function ExecuteUpdate(const SQL: RawByteString): Integer; override;\n    function Execute(const SQL: RawByteString): Boolean; override;\n\n    function ExecuteQueryPrepared: IZResultSet; virtual;\n    function ExecuteUpdatePrepared: Integer; virtual;\n    function ExecutePrepared: Boolean; virtual;\n\n    function GetSQL : String;\n    procedure Prepare; virtual;\n    procedure Unprepare; virtual;\n    function IsPrepared: Boolean; virtual;\n    property Prepared: Boolean read IsPrepared;\n\n    procedure SetDefaultValue(ParameterIndex: Integer; const Value: string);\n\n    procedure SetNull(ParameterIndex: Integer; SQLType: TZSQLType); virtual;\n    procedure SetBoolean(ParameterIndex: Integer; Value: Boolean); virtual;\n    procedure SetByte(ParameterIndex: Integer; Value: Byte); virtual;\n    procedure SetShort(ParameterIndex: Integer; Value: SmallInt); virtual;\n    procedure SetInt(ParameterIndex: Integer; Value: Integer); virtual;\n    procedure SetLong(ParameterIndex: Integer; Value: Int64); virtual;\n    procedure SetFloat(ParameterIndex: Integer; Value: Single); virtual;\n    procedure SetDouble(ParameterIndex: Integer; Value: Double); virtual;\n    procedure SetBigDecimal(ParameterIndex: Integer; Value: Extended); virtual;\n    procedure SetPChar(ParameterIndex: Integer; Value: PChar); virtual;\n    procedure SetString(ParameterIndex: Integer; const Value: String); virtual;\n    procedure SetUnicodeString(ParameterIndex: Integer; const Value: ZWideString);  virtual; //AVZ\n    procedure SetBytes(ParameterIndex: Integer; const Value: TByteDynArray); virtual;\n    procedure SetDate(ParameterIndex: Integer; Value: TDateTime); virtual;\n    procedure SetTime(ParameterIndex: Integer; Value: TDateTime); virtual;\n    procedure SetTimestamp(ParameterIndex: Integer; Value: TDateTime); virtual;\n    procedure SetAsciiStream(ParameterIndex: Integer; Value: TStream); virtual;\n    procedure SetUnicodeStream(ParameterIndex: Integer; Value: TStream); virtual;\n    procedure SetBinaryStream(ParameterIndex: Integer; Value: TStream); virtual;\n    procedure SetBlob(ParameterIndex: Integer; SQLType: TZSQLType; Value: IZBlob); virtual;\n    procedure SetValue(ParameterIndex: Integer; const Value: TZVariant); virtual;\n\n    procedure ClearParameters; virtual;\n\n    procedure AddBatchPrepared; virtual;\n    function GetMetaData: IZResultSetMetaData; virtual;\n  end;\n\n  {** Implements Abstract Callable SQL statement. }\n  TZAbstractCallableStatement = class(TZAbstractPreparedStatement,\n    IZCallableStatement)\n  private\n    FOutParamValues: TZVariantDynArray;\n    FOutParamTypes: TZSQLTypeArray;\n    FOutParamCount: Integer;\n    FLastWasNull: Boolean;\n    FTemp: String;\n    FProcSql: String;\n    FIsFunction: Boolean;\n    FHasOutParameter: Boolean;\n  protected\n    FResultSets: IZCollection;\n    FActiveResultset: Integer;\n    FDBParamTypes: array of ShortInt;\n    procedure ClearResultSets; virtual;\n    procedure TrimInParameters; virtual;\n    procedure SetOutParamCount(NewParamCount: Integer); virtual;\n    function GetOutParam(ParameterIndex: Integer): TZVariant; virtual;\n    procedure SetProcSQL(const Value: String); virtual;\n\n    property OutParamValues: TZVariantDynArray\n      read FOutParamValues write FOutParamValues;\n    property OutParamTypes: TZSQLTypeArray\n      read FOutParamTypes write FOutParamTypes;\n    property OutParamCount: Integer read FOutParamCount write FOutParamCount;\n    property LastWasNull: Boolean read FLastWasNull write FLastWasNull;\n    property ProcSql: String read FProcSQL write SetProcSQL;\n  public\n    constructor Create(Connection: IZConnection; SQL: string; Info: TStrings);\n    procedure ClearParameters; override;\n    procedure Close; override;\n\n    function IsFunction: Boolean;\n    function HasOutParameter: Boolean;\n    function HasMoreResultSets: Boolean; virtual;\n    function GetFirstResultSet: IZResultSet; virtual;\n    function GetPreviousResultSet: IZResultSet; virtual;\n    function GetNextResultSet: IZResultSet; virtual;\n    function GetLastResultSet: IZResultSet; virtual;\n    function BOR: Boolean; virtual;\n    function EOR: Boolean; virtual;\n    function GetResultSetByIndex(const Index: Integer): IZResultSet; virtual;\n    function GetResultSetCount: Integer; virtual;\n\n    procedure RegisterOutParameter(ParameterIndex: Integer;\n      SQLType: Integer); virtual;\n    procedure RegisterParamType(ParameterIndex:integer;ParamType:Integer);virtual;\n    function WasNull: Boolean; virtual;\n\n    function IsNull(ParameterIndex: Integer): Boolean; virtual;\n    function GetPChar(ParameterIndex: Integer): PChar; virtual;\n    function GetString(ParameterIndex: Integer): String; virtual;\n    function GetUnicodeString(ParameterIndex: Integer): WideString; virtual;\n    function GetBoolean(ParameterIndex: Integer): Boolean; virtual;\n    function GetByte(ParameterIndex: Integer): Byte; virtual;\n    function GetShort(ParameterIndex: Integer): SmallInt; virtual;\n    function GetInt(ParameterIndex: Integer): Integer; virtual;\n    function GetLong(ParameterIndex: Integer): Int64; virtual;\n    function GetFloat(ParameterIndex: Integer): Single; virtual;\n    function GetDouble(ParameterIndex: Integer): Double; virtual;\n    function GetBigDecimal(ParameterIndex: Integer): Extended; virtual;\n    function GetBytes(ParameterIndex: Integer): TByteDynArray; virtual;\n    function GetDate(ParameterIndex: Integer): TDateTime; virtual;\n    function GetTime(ParameterIndex: Integer): TDateTime; virtual;\n    function GetTimestamp(ParameterIndex: Integer): TDateTime; virtual;\n    function GetValue(ParameterIndex: Integer): TZVariant; virtual;\n  end;\n\n  {** Implements a real Prepared Callable SQL Statement. }\n  TZAbstractPreparedCallableStatement = CLass(TZAbstractCallableStatement)\n  protected\n    procedure SetProcSQL(const Value: String); override;\n  public\n    function ExecuteQuery(const SQL: ZWideString): IZResultSet; override;\n    function ExecuteQuery(const SQL: RawByteString): IZResultSet; override;\n    function ExecuteUpdate(const SQL: ZWideString): Integer; override;\n    function ExecuteUpdate(const SQL: RawByteString): Integer; override;\n    function Execute(const SQL: ZWideString): Boolean; override;\n    function Execute(const SQL: RawByteString): Boolean; override;\n  end;\n\n  {** Implements an Emulated Prepared SQL Statement. }\n  TZEmulatedPreparedStatement = class(TZAbstractPreparedStatement)\n  private\n    FExecStatement: IZStatement;\n    FCachedQuery: TStrings;\n    FLastStatement: IZStatement;\n    procedure SetLastStatement(LastStatement: IZStatement);\n  protected\n    FNeedNCharDetection: Boolean;\n    property ExecStatement: IZStatement read FExecStatement write FExecStatement;\n    property CachedQuery: TStrings read FCachedQuery write FCachedQuery;\n    property LastStatement: IZStatement read FLastStatement write SetLastStatement;\n\n    function CreateExecStatement: IZStatement; virtual; abstract;\n    function PrepareWideSQLParam(ParamIndex: Integer): ZWideString; virtual;\n    function PrepareAnsiSQLParam(ParamIndex: Integer): RawByteString; virtual;\n    function GetExecStatement: IZStatement;\n    function TokenizeSQLQuery: TStrings;\n    function PrepareWideSQLQuery: ZWideString; virtual;\n    function PrepareAnsiSQLQuery: RawByteString; virtual;\n  public\n    destructor Destroy; override;\n\n    procedure Close; override;\n\n    function ExecuteQuery(const SQL: ZWideString): IZResultSet; override;\n    function ExecuteQuery(const SQL: RawByteString): IZResultSet; override;\n    function ExecuteUpdate(const SQL: ZWideString): Integer; override;\n    function ExecuteUpdate(const SQL: RawByteString): Integer; override;\n    function Execute(const SQL: ZWideString): Boolean; override;\n    function Execute(const SQL: RawByteString): Boolean; override;\n\n    function ExecuteQueryPrepared: IZResultSet; override;\n    function ExecuteUpdatePrepared: Integer; override;\n    function ExecutePrepared: Boolean; override;\n  end;\n\nimplementation\n\nuses ZSysUtils, ZMessages, ZDbcResultSet, ZCollections;\n\nvar\n{**\n  Holds the value of the last assigned statement ID.\n  Only Accessible using TZAbstractStatement.GetNextStatementId.\n}\n  GlobalStatementIdCounter : integer;\n\n{ TZAbstractStatement }\n\n{**\n  Constructs this class and defines the main properties.\n  @param Connection a database connection object.\n  @param Info a statement parameters;\n}\nconstructor TZAbstractStatement.Create(Connection: IZConnection; Info: TStrings);\nbegin\n  { Sets the default properties. }\n  inherited Create;\n  ConSettings := Connection.GetConSettings;\n  FMaxFieldSize := 0;\n  FMaxRows := 0;\n  FEscapeProcessing := False;\n  FQueryTimeout := 0;\n  FLastUpdateCount := -1;\n  FLastResultSet := nil;\n  FFetchDirection := fdForward;\n  FFetchSize := 0;\n  FResultSetConcurrency := rcReadOnly;\n  FResultSetType := rtForwardOnly;\n  FCursorName := '';\n\n  FConnection := Connection;\n  FBatchQueries := TStringList.Create;\n\n  FInfo := TStringList.Create;\n  if Info <> nil then\n    FInfo.AddStrings(Info);\n  if FInfo.Values['chunk_size'] = '' then\n    FChunkSize := StrToIntDef(Connection.GetParameters.Values['chunk_size'], 4096)\n  else\n    FChunkSize := StrToIntDef(FInfo.Values['chunk_size'], 4096);\n\n  FIsAnsiDriver := Connection.GetIZPlainDriver.IsAnsiDriver;\nend;\n\n{**\n  Destroys this object and cleanups the memory.\n}\ndestructor TZAbstractStatement.Destroy;\nbegin\n  Close;\n  if Assigned(FBatchQueries) then\n    FreeAndNil(FBatchQueries);\n  FConnection := nil;\n  FreeAndNil(FInfo);\n  FLastResultSet := nil;\n  inherited Destroy;\nend;\n\n{**\n  Sets the preprepared SQL-Statement in an String and AnsiStringForm.\n  @param Value: the SQL-String which has to be optional preprepared\n}\nprocedure TZAbstractStatement.SetWSQL(const Value: ZWideString);\nbegin\n  if FWSQL <> Value then\n  begin\n    {$IFDEF UNICODE}\n    FaSQL := GetEncodedSQL(Value);\n    {$ELSE}\n    FaSQL := ZPlainString(Value);\n    {$ENDIF}\n    FWSQL := ZDbcUnicodeString(FASQL, ConSettings^.ClientCodePage^.CP);;\n  end;\nend;\n\nprocedure TZAbstractStatement.SetASQL(const Value: RawByteString);\nbegin\n  if FASQL <> Value then\n  begin\n    {$IFNDEF UNICODE}\n    FASQL := GetEncodedSQL(Value);\n    FWSQL := ZDbcUnicodeString(FASQL, ConSettings^.ClientCodePage^.CP);\n    {$else}\n    FASQL := Value;\n    FWSQL := ZDbcString(Value);\n    {$ENDIF}\n  end;\nend;\n\n{**\n  Raises unsupported operation exception.\n}\nprocedure TZAbstractStatement.RaiseUnsupportedException;\nbegin\n  raise EZSQLException.Create(SUnsupportedOperation);\nend;\n\n{**\n  Sets a last result set to avoid problems with reference counting.\n  @param ResultSet the lastest executed result set.\n}\nprocedure TZAbstractStatement.SetLastResultSet(ResultSet: IZResultSet);\nbegin\n  if (FLastResultSet <> nil) then\n    FLastResultSet.Close;\n\n  FLastResultSet := ResultSet;\nend;\n\nclass function TZAbstractStatement.GetNextStatementId: integer;\nbegin\n  Inc(GlobalStatementIdCounter);\n  Result := GlobalStatementIdCounter;\nend;\n\n{**\n  Executes an SQL statement that returns a single <code>ResultSet</code> object.\n  @param sql typically this is a static SQL <code>SELECT</code> statement\n  @return a <code>ResultSet</code> object that contains the data produced by the\n    given query; never <code>null</code>\n}\nfunction TZAbstractStatement.ExecuteQuery(const SQL: ZWideString): IZResultSet;\nbegin\n  WSQL := SQL;\n  Result := ExecuteQuery(ASQL);\nend;\n\nfunction TZAbstractStatement.ExecuteQuery(const SQL: RawByteString): IZResultSet;\nbegin\n  Result := nil;\n  RaiseUnsupportedException;\nend;\n\n{**\n  Executes an SQL <code>INSERT</code>, <code>UPDATE</code> or\n  <code>DELETE</code> statement. In addition,\n  SQL statements that return nothing, such as SQL DDL statements,\n  can be executed.\n\n  @param sql an SQL <code>INSERT</code>, <code>UPDATE</code> or\n    <code>DELETE</code> statement or an SQL statement that returns nothing\n  @return either the row count for <code>INSERT</code>, <code>UPDATE</code>\n    or <code>DELETE</code> statements, or 0 for SQL statements that return nothing\n}\nfunction TZAbstractStatement.ExecuteUpdate(const SQL: ZWideString): Integer;\nbegin\n  WSQL := SQL;\n  Result := ExecuteUpdate(ASQL);\nend;\n\nfunction TZAbstractStatement.ExecuteUpdate(const SQL: RawByteString): Integer;\nbegin\n  Result := 0;\n  RaiseUnsupportedException;\nend;\n\n{**\n  Releases this <code>Statement</code> object's database\n  and JDBC resources immediately instead of waiting for\n  this to happen when it is automatically closed.\n  It is generally good practice to release resources as soon as\n  you are finished with them to avoid tying up database\n  resources.\n  <P><B>Note:</B> A <code>Statement</code> object is automatically closed when it is\n  garbage collected. When a <code>Statement</code> object is closed, its current\n  <code>ResultSet</code> object, if one exists, is also closed.\n}\nprocedure TZAbstractStatement.Close;\nbegin\n  if LastResultSet <> nil then\n  begin\n    LastResultSet.Close;\n    LastResultSet := nil;\n  end;\n  FClosed := True;\nend;\n\n{**\n  Returns the maximum number of bytes allowed\n  for any column value.\n  This limit is the maximum number of bytes that can be\n  returned for any column value.\n  The limit applies only to <code>BINARY</code>,\n  <code>VARBINARY</code>, <code>LONGVARBINARY</code>, <code>CHAR</code>, <code>VARCHAR</code>, and <code>LONGVARCHAR</code>\n  columns.  If the limit is exceeded, the excess data is silently\n  discarded.\n  @return the current max column size limit; zero means unlimited\n}\nfunction TZAbstractStatement.GetMaxFieldSize: Integer;\nbegin\n  Result := FMaxFieldSize;\nend;\n\n{**\n  Sets the limit for the maximum number of bytes in a column to\n  the given number of bytes.  This is the maximum number of bytes\n  that can be returned for any column value.  This limit applies\n  only to <code>BINARY</code>, <code>VARBINARY</code>,\n  <code>LONGVARBINARY</code>, <code>CHAR</code>, <code>VARCHAR</code>, and\n  <code>LONGVARCHAR</code> fields.  If the limit is exceeded, the excess data\n  is silently discarded. For maximum portability, use values\n  greater than 256.\n\n  @param max the new max column size limit; zero means unlimited\n}\nprocedure TZAbstractStatement.SetMaxFieldSize(Value: Integer);\nbegin\n  FMaxFieldSize := Value;\nend;\n\n{**\n  Retrieves the maximum number of rows that a\n  <code>ResultSet</code> object can contain.  If the limit is exceeded, the excess\n  rows are silently dropped.\n\n  @return the current max row limit; zero means unlimited\n}\nfunction TZAbstractStatement.GetMaxRows: Integer;\nbegin\n  Result := FMaxRows;\nend;\n\n{**\n  Sets the limit for the maximum number of rows that any\n  <code>ResultSet</code> object can contain to the given number.\n  If the limit is exceeded, the excess rows are silently dropped.\n\n  @param max the new max rows limit; zero means unlimited\n}\nprocedure TZAbstractStatement.SetMaxRows(Value: Integer);\nbegin\n  FMaxRows := Value;\nend;\n\n{**\n  Sets escape processing on or off.\n  If escape scanning is on (the default), the driver will do\n  escape substitution before sending the SQL to the database.\n\n  Note: Since prepared statements have usually been parsed prior\n  to making this call, disabling escape processing for prepared\n  statements will have no effect.\n\n  @param enable <code>true</code> to enable; <code>false</code> to disable\n}\nprocedure TZAbstractStatement.SetEscapeProcessing(Value: Boolean);\nbegin\n  FEscapeProcessing := Value;\nend;\n\n{**\n  Retrieves the number of seconds the driver will\n  wait for a <code>Statement</code> object to execute. If the limit is exceeded, a\n  <code>SQLException</code> is thrown.\n\n  @return the current query timeout limit in seconds; zero means unlimited\n}\nfunction TZAbstractStatement.GetQueryTimeout: Integer;\nbegin\n  Result := FQueryTimeout;\nend;\n\n{**\n  Sets the number of seconds the driver will\n  wait for a <code>Statement</code> object to execute to the given number of seconds.\n  If the limit is exceeded, an <code>SQLException</code> is thrown.\n\n  @param seconds the new query timeout limit in seconds; zero means unlimited\n}\nprocedure TZAbstractStatement.SetQueryTimeout(Value: Integer);\nbegin\n  FQueryTimeout := Value;\nend;\n\n{**\n  Cancels this <code>Statement</code> object if both the DBMS and\n  driver support aborting an SQL statement.\n  This method can be used by one thread to cancel a statement that\n  is being executed by another thread.\n}\nprocedure TZAbstractStatement.Cancel;\nbegin\n  RaiseUnsupportedException;\nend;\n\n{**\n  Retrieves the first warning reported by calls on this <code>Statement</code> object.\n  Subsequent <code>Statement</code> object warnings will be chained to this\n  <code>SQLWarning</code> object.\n\n  <p>The warning chain is automatically cleared each time\n    a statement is (re)executed.\n\n  <P><B>Note:</B> If you are processing a <code>ResultSet</code> object, any\n  warnings associated with reads on that <code>ResultSet</code> object\n  will be chained on it.\n\n  @return the first <code>SQLWarning</code> object or <code>null</code>\n}\nfunction TZAbstractStatement.GetWarnings: EZSQLWarning;\nbegin\n  Result := nil;\nend;\n\n{**\n  Clears all the warnings reported on this <code>Statement</code>\n  object. After a call to this method,\n  the method <code>getWarnings</code> will return\n  <code>null</code> until a new warning is reported for this\n  <code>Statement</code> object.\n}\nprocedure TZAbstractStatement.ClearWarnings;\nbegin\nend;\n\nfunction TZAbstractStatement.GetEncodedSQL(const SQL: {$IF defined(FPC) and defined(WITH_RAWBYTESTRING)}RawByteString{$ELSE}String{$IFEND}): RawByteString;\nvar\n  SQLTokens: TZTokenDynArray;\n  i: Integer;\nbegin\n  if GetConnection.AutoEncodeStrings then\n  begin\n    Result := ''; //init for FPC\n    SQLTokens := GetConnection.GetDriver.GetTokenizer.TokenizeBuffer(SQL, [toSkipEOF]); //Disassembles the Query\n    for i := Low(SQLTokens) to high(SQLTokens) do  //Assembles the Query\n    begin\n      case (SQLTokens[i].TokenType) of\n        ttEscape:\n          Result := Result + {$IFDEF UNICODE}ZPlainString{$ENDIF}(SQLTokens[i].Value);\n        ttQuoted, ttComment,\n        ttWord, ttQuotedIdentifier, ttKeyword:\n          Result := Result + ZPlainString(SQLTokens[i].Value);\n        else\n          Result := Result + RawByteString(SQLTokens[i].Value);\n      end;\n    end;\n  end\n  else\n    {$IFDEF UNICODE}\n    Result := ZPlainString(SQL);\n    {$ELSE}\n    Result := SQL;\n    {$ENDIF}\nend;\n\n{**\n  Defines the SQL cursor name that will be used by\n  subsequent <code>Statement</code> object <code>execute</code> methods.\n  This name can then be\n  used in SQL positioned update/delete statements to identify the\n  current row in the <code>ResultSet</code> object generated by this statement.  If\n  the database doesn't support positioned update/delete, this\n  method is a noop.  To insure that a cursor has the proper isolation\n  level to support updates, the cursor's <code>SELECT</code> statement should be\n  of the form 'select for update ...'. If the 'for update' phrase is\n  omitted, positioned updates may fail.\n\n  <P><B>Note:</B> By definition, positioned update/delete\n  execution must be done by a different <code>Statement</code> object than the one\n  which generated the <code>ResultSet</code> object being used for positioning. Also,\n  cursor names must be unique within a connection.\n\n  @param name the new cursor name, which must be unique within a connection\n}\nprocedure TZAbstractStatement.SetCursorName(const Value: AnsiString);\nbegin\n  FCursorName := Value;\nend;\n\n{**\n  Executes an SQL statement that may return multiple results.\n  Under some (uncommon) situations a single SQL statement may return\n  multiple result sets and/or update counts.  Normally you can ignore\n  this unless you are (1) executing a stored procedure that you know may\n  return multiple results or (2) you are dynamically executing an\n  unknown SQL string.  The  methods <code>execute</code>,\n  <code>getMoreResults</code>, <code>getResultSet</code>,\n  and <code>getUpdateCount</code> let you navigate through multiple results.\n\n  The <code>execute</code> method executes an SQL statement and indicates the\n  form of the first result.  You can then use the methods\n  <code>getResultSet</code> or <code>getUpdateCount</code>\n  to retrieve the result, and <code>getMoreResults</code> to\n  move to any subsequent result(s).\n\n  @param sql any SQL statement\n  @return <code>true</code> if the next result is a <code>ResultSet</code> object;\n  <code>false</code> if it is an update count or there are no more results\n  @see #getResultSet\n  @see #getUpdateCount\n  @see #getMoreResults\n}\nfunction TZAbstractStatement.Execute(const SQL: ZWideString): Boolean;\nbegin\n  WSQL := SQL;\n  Result := Execute(ASQL);\nend;\n\nfunction TZAbstractStatement.Execute(const SQL: RawByteString): Boolean;\nbegin\n  Result := False;\n  LastResultSet := nil;\n  LastUpdateCount := -1;\nend;\n\n{**\n  Returns the current result as a <code>ResultSet</code> object.\n  This method should be called only once per result.\n\n  @return the current result as a <code>ResultSet</code> object;\n  <code>null</code> if the result is an update count or there are no more results\n  @see #execute\n}\nfunction TZAbstractStatement.GetResultSet: IZResultSet;\nbegin\n  Result := LastResultSet;\nend;\n\n{**\n  Returns the current result as an update count;\n  if the result is a <code>ResultSet</code> object or there are no more results, -1\n  is returned. This method should be called only once per result.\n\n  @return the current result as an update count; -1 if the current result is a\n    <code>ResultSet</code> object or there are no more results\n  @see #execute\n}\nfunction TZAbstractStatement.GetUpdateCount: Integer;\nbegin\n  Result := FLastUpdateCount;\nend;\n\n{**\n  Moves to a <code>Statement</code> object's next result.  It returns\n  <code>true</code> if this result is a <code>ResultSet</code> object.\n  This method also implicitly closes any current <code>ResultSet</code>\n  object obtained with the method <code>getResultSet</code>.\n\n  <P>There are no more results when the following is true:\n  <PRE>\n        <code>(!getMoreResults() && (getUpdateCount() == -1)</code>\n  </PRE>\n\n @return <code>true</code> if the next result is a <code>ResultSet</code> object;\n   <code>false</code> if it is an update count or there are no more results\n @see #execute\n}\nfunction TZAbstractStatement.GetMoreResults: Boolean;\nbegin\n  Result := False;\nend;\n\n{**\n  Retrieves the direction for fetching rows from\n  database tables that is the default for result sets\n  generated from this <code>Statement</code> object.\n  If this <code>Statement</code> object has not set\n  a fetch direction by calling the method <code>setFetchDirection</code>,\n  the return value is implementation-specific.\n\n  @return the default fetch direction for result sets generated\n    from this <code>Statement</code> object\n}\nfunction TZAbstractStatement.GetFetchDirection: TZFetchDirection;\nbegin\n  Result := FFetchDirection;\nend;\n\n{**\n  Gives the driver a hint as to the direction in which\n  the rows in a result set\n  will be processed. The hint applies only to result sets created\n  using this <code>Statement</code> object.  The default value is\n  <code>ResultSet.FETCH_FORWARD</code>.\n  <p>Note that this method sets the default fetch direction for\n  result sets generated by this <code>Statement</code> object.\n  Each result set has its own methods for getting and setting\n  its own fetch direction.\n  @param direction the initial direction for processing rows\n}\nprocedure TZAbstractStatement.SetFetchDirection(Value: TZFetchDirection);\nbegin\n  FFetchDirection := Value;\nend;\n\n{**\n  Retrieves the number of result set rows that is the default\n  fetch size for result sets\n  generated from this <code>Statement</code> object.\n  If this <code>Statement</code> object has not set\n  a fetch size by calling the method <code>setFetchSize</code>,\n  the return value is implementation-specific.\n  @return the default fetch size for result sets generated\n    from this <code>Statement</code> object\n}\nfunction TZAbstractStatement.GetFetchSize: Integer;\nbegin\n  Result := FFetchSize;\nend;\n\n{**\n  Gives the JDBC driver a hint as to the number of rows that should\n  be fetched from the database when more rows are needed.  The number\n  of rows specified affects only result sets created using this\n  statement. If the value specified is zero, then the hint is ignored.\n  The default value is zero.\n\n  @param rows the number of rows to fetch\n}\nprocedure TZAbstractStatement.SetFetchSize(Value: Integer);\nbegin\n  FFetchSize := Value;\nend;\n\n{**\n  Sets a result set concurrency for <code>ResultSet</code> objects\n  generated by this <code>Statement</code> object.\n\n  @param Concurrency either <code>ResultSet.CONCUR_READ_ONLY</code> or\n  <code>ResultSet.CONCUR_UPDATABLE</code>\n}\nprocedure TZAbstractStatement.SetResultSetConcurrency(\n  Value: TZResultSetConcurrency);\nbegin\n  FResultSetConcurrency := Value;\nend;\n\n{**\n  Retrieves the result set concurrency for <code>ResultSet</code> objects\n  generated by this <code>Statement</code> object.\n\n  @return either <code>ResultSet.CONCUR_READ_ONLY</code> or\n  <code>ResultSet.CONCUR_UPDATABLE</code>\n}\nfunction TZAbstractStatement.GetResultSetConcurrency: TZResultSetConcurrency;\nbegin\n  Result := FResultSetConcurrency;\nend;\n\n{**\n  Sets a result set type for <code>ResultSet</code> objects\n  generated by this <code>Statement</code> object.\n\n  @param ResultSetType one of <code>ResultSet.TYPE_FORWARD_ONLY</code>,\n    <code>ResultSet.TYPE_SCROLL_INSENSITIVE</code>, or\n    <code>ResultSet.TYPE_SCROLL_SENSITIVE</code>\n}\nprocedure TZAbstractStatement.SetResultSetType(Value: TZResultSetType);\nbegin\n  FResultSetType := Value;\nend;\n\n{**\n  Retrieves the result set type for <code>ResultSet</code> objects\n  generated by this <code>Statement</code> object.\n\n  @return one of <code>ResultSet.TYPE_FORWARD_ONLY</code>,\n    <code>ResultSet.TYPE_SCROLL_INSENSITIVE</code>, or\n    <code>ResultSet.TYPE_SCROLL_SENSITIVE</code>\n}\nfunction TZAbstractStatement.GetResultSetType: TZResultSetType;\nbegin\n  Result := FResultSetType;\nend;\n\n{**\n  Gets the current value for locate updates.\n  @returns the current value for locate updates.\n}\nfunction TZAbstractStatement.GetLocateUpdates: TZLocateUpdatesMode;\nbegin\n  Result := FLocateUpdates;\nend;\n\n{**\n  Sets a new value for locate updates.\n  @param Value a new value for locate updates.\n}\nprocedure TZAbstractStatement.SetLocateUpdates(Value: TZLocateUpdatesMode);\nbegin\n  FLocateUpdates := Value;\nend;\n\n{**\n  Gets the current value for post updates.\n  @returns the current value for post updates.\n}\nfunction TZAbstractStatement.GetPostUpdates: TZPostUpdatesMode;\nbegin\n  Result := FPostUpdates;\nend;\n\n{**\n  Sets a new value for post updates.\n  @param Value a new value for post updates.\n}\nprocedure TZAbstractStatement.SetPostUpdates(Value: TZPostUpdatesMode);\nbegin\n  FPostUpdates := Value;\nend;\n\n{**\n  Adds an SQL command to the current batch of commmands for this\n  <code>Statement</code> object. This method is optional.\n\n  @param sql typically this is a static SQL <code>INSERT</code> or\n  <code>UPDATE</code> statement\n}\nprocedure TZAbstractStatement.AddBatch(const SQL: string);\nbegin\n  FBatchQueries.Add(SQL);\nend;\n\n{**\n  Makes the set of commands in the current batch empty.\n  This method is optional.\n}\nprocedure TZAbstractStatement.ClearBatch;\nbegin\n  FBatchQueries.Clear;\nend;\n\n{**\n  Submits a batch of commands to the database for execution and\n  if all commands execute successfully, returns an array of update counts.\n  The <code>int</code> elements of the array that is returned are ordered\n  to correspond to the commands in the batch, which are ordered\n  according to the order in which they were added to the batch.\n  The elements in the array returned by the method <code>executeBatch</code>\n  may be one of the following:\n  <OL>\n  <LI>A number greater than or equal to zero -- indicates that the\n  command was processed successfully and is an update count giving the\n  number of rows in the database that were affected by the command's\n  execution\n  <LI>A value of <code>-2</code> -- indicates that the command was\n  processed successfully but that the number of rows affected is\n  unknown\n  <P>\n  If one of the commands in a batch update fails to execute properly,\n  this method throws a <code>BatchUpdateException</code>, and a JDBC\n  driver may or may not continue to process the remaining commands in\n  the batch.  However, the driver's behavior must be consistent with a\n  particular DBMS, either always continuing to process commands or never\n  continuing to process commands.  If the driver continues processing\n  after a failure, the array returned by the method\n  <code>BatchUpdateException.getUpdateCounts</code>\n  will contain as many elements as there are commands in the batch, and\n  at least one of the elements will be the following:\n  <P>\n  <LI>A value of <code>-3</code> -- indicates that the command failed\n  to execute successfully and occurs only if a driver continues to\n  process commands after a command fails\n  </OL>\n  <P>\n  A driver is not required to implement this method.\n  The possible implementations and return values have been modified in\n  the Java 2 SDK, Standard Edition, version 1.3 to\n  accommodate the option of continuing to proccess commands in a batch\n  update after a <code>BatchUpdateException</code> obejct has been thrown.\n\n  @return an array of update counts containing one element for each\n  command in the batch.  The elements of the array are ordered according\n  to the order in which commands were added to the batch.\n}\nfunction TZAbstractStatement.ExecuteBatch: TIntegerDynArray;\nvar\n  I: Integer;\nbegin\n  SetLength(Result, FBatchQueries.Count);\n  for I := 0 to FBatchQueries.Count -1 do\n    Result[I] := ExecuteUpdate(FBatchQueries[I]);\n  ClearBatch;\nend;\n\n{**\n  Returns the <code>Connection</code> object\n  that produced this <code>Statement</code> object.\n  @return the connection that produced this statement\n}\nfunction TZAbstractStatement.GetConnection: IZConnection;\nbegin\n  Result := FConnection;\nend;\n\n{**\n  Gets statement parameters.\n  @returns a list with statement parameters.\n}\nfunction TZAbstractStatement.GetParameters: TStrings;\nbegin\n  Result := FInfo;\nend;\n\n{**\n  Returns the ChunkSize for reading/writing large lobs\n  @returns the chunksize in bytes.\n}\nfunction TZAbstractStatement.GetChunkSize: Integer;\nbegin\n  Result := FChunkSize;\nend;\n\n{ TZAbstractPreparedStatement }\n\n{**\n  Constructs this object and assigns main properties.\n  @param Connection a database connection object.\n  @param Sql a prepared Sql statement.\n  @param Info a statement parameters.\n}\nconstructor TZAbstractPreparedStatement.Create(Connection: IZConnection;\n  const SQL: string; Info: TStrings);\nbegin\n  inherited Create(Connection, Info);\n  FSQL := SQL;\n  {$IFDEF UNICODE}WSQL{$ELSE}ASQL{$ENDIF} := SQL;\n  FInParamCount := 0;\n  SetInParamCount(0);\n  FPrepared := False;\n  FExecCount := 0;\n  FStatementId := Self.GetNextStatementId;\nend;\n\n{**\n  Destroys this object and cleanups the memory.\n}\ndestructor TZAbstractPreparedStatement.Destroy;\nbegin\n  Unprepare;\n  inherited Destroy;\n  ClearParameters;\nend;\n\n{**\n  Executes an SQL statement that returns a single <code>ResultSet</code> object.\n  @param sql typically this is a static SQL <code>SELECT</code> statement\n  @return a <code>ResultSet</code> object that contains the data produced by the\n    given query; never <code>null</code>\n}\nfunction TZAbstractPreparedStatement.ExecuteQuery(const SQL: ZWideString): IZResultSet;\nbegin\n  WSQL := SQL;\n  Result := ExecuteQueryPrepared;\nend;\n\n{**\n  Executes an SQL <code>INSERT</code>, <code>UPDATE</code> or\n  <code>DELETE</code> statement. In addition,\n  SQL statements that return nothing, such as SQL DDL statements,\n  can be executed.\n\n  @param sql an SQL <code>INSERT</code>, <code>UPDATE</code> or\n    <code>DELETE</code> statement or an SQL statement that returns nothing\n  @return either the row count for <code>INSERT</code>, <code>UPDATE</code>\n    or <code>DELETE</code> statements, or 0 for SQL statements that return nothing\n}\nfunction TZAbstractPreparedStatement.ExecuteUpdate(const SQL: ZWideString): Integer;\nbegin\n  WSQL := SQL;\n  Result := ExecuteUpdatePrepared;\nend;\n\n{**\n  Executes an SQL statement that may return multiple results.\n  Under some (uncommon) situations a single SQL statement may return\n  multiple result sets and/or update counts.  Normally you can ignore\n  this unless you are (1) executing a stored procedure that you know may\n  return multiple results or (2) you are dynamically executing an\n  unknown SQL string.  The  methods <code>execute</code>,\n  <code>getMoreResults</code>, <code>getResultSet</code>,\n  and <code>getUpdateCount</code> let you navigate through multiple results.\n\n  The <code>execute</code> method executes an SQL statement and indicates the\n  form of the first result.  You can then use the methods\n  <code>getResultSet</code> or <code>getUpdateCount</code>\n  to retrieve the result, and <code>getMoreResults</code> to\n  move to any subsequent result(s).\n\n  @param sql any SQL statement\n  @return <code>true</code> if the next result is a <code>ResultSet</code> object;\n  <code>false</code> if it is an update count or there are no more results\n  @see #getResultSet\n  @see #getUpdateCount\n  @see #getMoreResults\n}\nfunction TZAbstractPreparedStatement.Execute(const SQL: ZWideString): Boolean;\nbegin\n  WSQL := SQL;\n  Result := ExecutePrepared;\nend;\n\n{**\n  Executes an SQL statement that returns a single <code>ResultSet</code> object.\n  @param sql typically this is a static SQL <code>SELECT</code> statement\n  @return a <code>ResultSet</code> object that contains the data produced by the\n    given query; never <code>null</code>\n}\nfunction TZAbstractPreparedStatement.ExecuteQuery(const SQL: RawByteString): IZResultSet;\nbegin\n  ASQL := SQL;\n  Result := ExecuteQueryPrepared;\nend;\n\n{**\n  Executes an SQL <code>INSERT</code>, <code>UPDATE</code> or\n  <code>DELETE</code> statement. In addition,\n  SQL statements that return nothing, such as SQL DDL statements,\n  can be executed.\n\n  @param sql an SQL <code>INSERT</code>, <code>UPDATE</code> or\n    <code>DELETE</code> statement or an SQL statement that returns nothing\n  @return either the row count for <code>INSERT</code>, <code>UPDATE</code>\n    or <code>DELETE</code> statements, or 0 for SQL statements that return nothing\n}\nfunction TZAbstractPreparedStatement.ExecuteUpdate(const SQL: RawByteString): Integer;\nbegin\n  ASQL := SQL;\n  Result := ExecuteUpdatePrepared;\nend;\n\n{**\n  Executes an SQL statement that may return multiple results.\n  Under some (uncommon) situations a single SQL statement may return\n  multiple result sets and/or update counts.  Normally you can ignore\n  this unless you are (1) executing a stored procedure that you know may\n  return multiple results or (2) you are dynamically executing an\n  unknown SQL string.  The  methods <code>execute</code>,\n  <code>getMoreResults</code>, <code>getResultSet</code>,\n  and <code>getUpdateCount</code> let you navigate through multiple results.\n\n  The <code>execute</code> method executes an SQL statement and indicates the\n  form of the first result.  You can then use the methods\n  <code>getResultSet</code> or <code>getUpdateCount</code>\n  to retrieve the result, and <code>getMoreResults</code> to\n  move to any subsequent result(s).\n\n  @param sql any SQL statement\n  @return <code>true</code> if the next result is a <code>ResultSet</code> object;\n  <code>false</code> if it is an update count or there are no more results\n  @see #getResultSet\n  @see #getUpdateCount\n  @see #getMoreResults\n}\nfunction TZAbstractPreparedStatement.Execute(const SQL: RawByteString): Boolean;\nbegin\n  ASQL := SQL;\n  Result := ExecutePrepared;\nend;\n\n\n{**\n  Prepares eventual structures for binding input parameters.\n}\nprocedure TZAbstractPreparedStatement.PrepareInParameters;\nbegin\nend;\n\n{**\n  Binds the input parameters\n}\nprocedure TZAbstractPreparedStatement.BindInParameters;\nvar\n  I : integer;\n  LogString : String;\nbegin\n  LogString := ''; //init for FPC\n  if InParamCount = 0 then\n     exit;\n    { Prepare Log Output}\n  For I := 0 to InParamCount - 1 do\n  begin\n    LogString := LogString + GetInParamLogValue(InParamValues[I])+',';\n  end;\n  LogPrepStmtMessage(lcBindPrepStmt, LogString);\nend;\n\n{**\n  Removes eventual structures for binding input parameters.\n}\nprocedure TZAbstractPreparedStatement.UnPrepareInParameters;\nbegin\nend;\n\n{**\n  Sets a new parameter count and initializes the buffers.\n  @param NewParamCount a new parameters count.\n}\nprocedure TZAbstractPreparedStatement.SetInParamCount(NewParamCount: Integer);\nvar\n  I: Integer;\nbegin\n  SetLength(FInParamValues, NewParamCount);\n  SetLength(FInParamTypes, NewParamCount);\n  SetLength(FInParamDefaultValues, NewParamCount);\n  for I := FInParamCount to NewParamCount - 1 do\n  begin\n    FInParamValues[I] := NullVariant;\n    FInParamTypes[I] := stUnknown;\n\n    FInParamDefaultValues[I] := '';\n  end;\n  FInParamCount := NewParamCount;\nend;\n\n{**\n  Sets a variant value into specified parameter.\n  @param ParameterIndex a index of the parameter.\n  @param SqlType a parameter SQL type.\n  @paran Value a new parameter value.\n}\nprocedure TZAbstractPreparedStatement.SetInParam(ParameterIndex: Integer;\n  SQLType: TZSQLType; const Value: TZVariant);\nbegin\n  if ParameterIndex >= FInParamCount then\n    SetInParamCount(ParameterIndex);\n\n  FInParamTypes[ParameterIndex - 1] := SQLType;\n  FInParamValues[ParameterIndex - 1] := Value;\nend;\n\n{**\n  Logs a message about prepared statement event with normal result code.\n  @param Category a category of the message.\n  @param Protocol a name of the protocol.\n  @param Msg a description message.\n}\nprocedure TZAbstractPreparedStatement.LogPrepStmtMessage(Category: TZLoggingCategory;\n  const Msg: string = '');\nbegin\n  if msg <> '' then\n    DriverManager.LogMessage(Category, Connection.GetIZPlainDriver.GetProtocol, Format('Statement %d : %s', [FStatementId, Msg]))\n  else\n    DriverManager.LogMessage(Category, Connection.GetIZPlainDriver.GetProtocol, Format('Statement %d', [FStatementId]));\nend;\n\n\nfunction TZAbstractPreparedStatement.GetInParamLogValue(Value: TZVariant): String;\nbegin\n  With Value do\n    case VType of\n      vtNull : result := '(NULL)';\n      vtBoolean : If VBoolean then result := '(TRUE)' else result := '(FALSE)';\n      vtInteger : result := IntToStr(VInteger);\n      vtFloat : result := FloatToStr(VFloat);\n      vtString : result := '''' + VString + '''';\n      vtUnicodeString : result := '''' + VUnicodeString + '''';\n      vtDateTime : result := DateTimeToStr(VDateTime);\n      vtPointer : result := '(POINTER)';\n      vtInterface : result := '(INTERFACE)';\n    else\n      result := '(UNKNOWN TYPE)'\n    end;\nend;\n\n{**\n  Executes the SQL query in this <code>PreparedStatement</code> object\n  and returns the result set generated by the query.\n\n  @return a <code>ResultSet</code> object that contains the data produced by the\n    query; never <code>null</code>\n}\n{$WARNINGS OFF}\nfunction TZAbstractPreparedStatement.ExecuteQueryPrepared: IZResultSet;\nbegin\n  { Logging Execution }\n  LogPrepStmtMessage(lcExecPrepStmt);\n  Inc(FExecCount);\nend;\n{$WARNINGS ON}\n{**\n  Executes the SQL INSERT, UPDATE or DELETE statement\n  in this <code>PreparedStatement</code> object.\n  In addition,\n  SQL statements that return nothing, such as SQL DDL statements,\n  can be executed.\n\n  @return either the row count for INSERT, UPDATE or DELETE statements;\n  or 0 for SQL statements that return nothing\n}\n{$WARNINGS OFF}\nfunction TZAbstractPreparedStatement.ExecuteUpdatePrepared: Integer;\nbegin\n  { Logging Execution }\n  LogPrepStmtMessage(lcExecPrepStmt);\n  Inc(FExecCount);\nend;\n{$WARNINGS ON}\n{**\n  Sets the designated parameter the default SQL value.\n  <P><B>Note:</B> You must specify the default value.\n\n  @param parameterIndex the first parameter is 1, the second is 2, ...\n  @param Value the default value normally defined in the field's DML SQL statement\n}\nprocedure TZAbstractPreparedStatement.SetDefaultValue(\n  ParameterIndex: Integer; const Value: string);\nbegin\n if ParameterIndex >= FInParamCount then\n   SetInParamCount(ParameterIndex);\n\n  FInParamDefaultValues[ParameterIndex - 1] := Value;\nend;\n\n{**\n  Sets the designated parameter to SQL <code>NULL</code>.\n  <P><B>Note:</B> You must specify the parameter's SQL type.\n\n  @param parameterIndex the first parameter is 1, the second is 2, ...\n  @param sqlType the SQL type code defined in <code>java.sql.Types</code>\n}\nprocedure TZAbstractPreparedStatement.SetNull(ParameterIndex: Integer;\n  SQLType: TZSQLType);\nbegin\n  SetInParam(ParameterIndex, SQLType, NullVariant);\nend;\n\n{**\n  Sets the designated parameter to a Java <code>boolean</code> value.\n  The driver converts this\n  to an SQL <code>BIT</code> value when it sends it to the database.\n\n  @param parameterIndex the first parameter is 1, the second is 2, ...\n  @param x the parameter value\n}\nprocedure TZAbstractPreparedStatement.SetBoolean(ParameterIndex: Integer;\n  Value: Boolean);\nvar\n  Temp: TZVariant;\nbegin\n  DefVarManager.SetAsBoolean(Temp, Value);\n  SetInParam(ParameterIndex, stBoolean, Temp);\nend;\n\n{**\n  Sets the designated parameter to a Java <code>byte</code> value.\n  The driver converts this\n  to an SQL <code>TINYINT</code> value when it sends it to the database.\n\n  @param parameterIndex the first parameter is 1, the second is 2, ...\n  @param x the parameter value\n}\nprocedure TZAbstractPreparedStatement.SetByte(ParameterIndex: Integer;\n  Value: Byte);\nvar\n  Temp: TZVariant;\nbegin\n  DefVarManager.SetAsInteger(Temp, Value);\n  SetInParam(ParameterIndex, stByte, Temp);\nend;\n\n{**\n  Sets the designated parameter to a Java <code>short</code> value.\n  The driver converts this\n  to an SQL <code>SMALLINT</code> value when it sends it to the database.\n\n  @param parameterIndex the first parameter is 1, the second is 2, ...\n  @param x the parameter value\n}\nprocedure TZAbstractPreparedStatement.SetShort(ParameterIndex: Integer;\n  Value: SmallInt);\nvar\n  Temp: TZVariant;\nbegin\n  DefVarManager.SetAsInteger(Temp, Value);\n  SetInParam(ParameterIndex, stShort, Temp);\nend;\n\n{**\n  Sets the designated parameter to a Java <code>int</code> value.\n  The driver converts this\n  to an SQL <code>INTEGER</code> value when it sends it to the database.\n\n  @param parameterIndex the first parameter is 1, the second is 2, ...\n  @param x the parameter value\n}\nprocedure TZAbstractPreparedStatement.SetInt(ParameterIndex: Integer;\n  Value: Integer);\nvar\n  Temp: TZVariant;\nbegin\n  DefVarManager.SetAsInteger(Temp, Value);\n  SetInParam(ParameterIndex, stInteger, Temp);\nend;\n\n{**\n  Sets the designated parameter to a Java <code>long</code> value.\n  The driver converts this\n  to an SQL <code>BIGINT</code> value when it sends it to the database.\n\n  @param parameterIndex the first parameter is 1, the second is 2, ...\n  @param x the parameter value\n}\nprocedure TZAbstractPreparedStatement.SetLong(ParameterIndex: Integer;\n  Value: Int64);\nvar\n  Temp: TZVariant;\nbegin\n  DefVarManager.SetAsInteger(Temp, Value);\n  SetInParam(ParameterIndex, stLong, Temp);\nend;\n\n{**\n  Sets the designated parameter to a Java <code>float</code> value.\n  The driver converts this\n  to an SQL <code>FLOAT</code> value when it sends it to the database.\n\n  @param parameterIndex the first parameter is 1, the second is 2, ...\n  @param x the parameter value\n}\nprocedure TZAbstractPreparedStatement.SetFloat(ParameterIndex: Integer;\n  Value: Single);\nvar\n  Temp: TZVariant;\nbegin\n  DefVarManager.SetAsFloat(Temp, Value);\n  SetInParam(ParameterIndex, stFloat, Temp);\nend;\n\n{**\n  Sets the designated parameter to a Java <code>double</code> value.\n  The driver converts this\n  to an SQL <code>DOUBLE</code> value when it sends it to the database.\n\n  @param parameterIndex the first parameter is 1, the second is 2, ...\n  @param x the parameter value\n}\nprocedure TZAbstractPreparedStatement.SetDouble(ParameterIndex: Integer;\n  Value: Double);\nvar\n  Temp: TZVariant;\nbegin\n  DefVarManager.SetAsFloat(Temp, Value);\n  SetInParam(ParameterIndex, stDouble, Temp);\nend;\n\n{**\n  Sets the designated parameter to a <code>java.math.BigDecimal</code> value.\n  The driver converts this to an SQL <code>NUMERIC</code> value when\n  it sends it to the database.\n\n  @param parameterIndex the first parameter is 1, the second is 2, ...\n  @param x the parameter value\n}\nprocedure TZAbstractPreparedStatement.SetBigDecimal(\n  ParameterIndex: Integer; Value: Extended);\nvar\n  Temp: TZVariant;\nbegin\n  DefVarManager.SetAsFloat(Temp, Value);\n  SetInParam(ParameterIndex, stBigDecimal, Temp);\nend;\n\n{**\n  Sets the designated parameter to a Java <code>String</code> value.\n  The driver converts this\n  to an SQL <code>VARCHAR</code> or <code>LONGVARCHAR</code> value\n  (depending on the argument's\n  size relative to the driver's limits on <code>VARCHAR</code> values)\n  when it sends it to the database.\n\n  @param parameterIndex the first parameter is 1, the second is 2, ...\n  @param x the parameter value\n}\nprocedure TZAbstractPreparedStatement.SetPChar(ParameterIndex: Integer;\n   Value: PChar);\nvar\n  Temp: TZVariant;\nbegin\n  DefVarManager.SetAsString(Temp, Value);\n  SetInParam(ParameterIndex, stString, Temp);\nend;\n\n{**\n  Sets the designated parameter to a Java <code>String</code> value.\n  The driver converts this\n  to an SQL <code>VARCHAR</code> or <code>LONGVARCHAR</code> value\n  (depending on the argument's\n  size relative to the driver's limits on <code>VARCHAR</code> values)\n  when it sends it to the database.\n\n  @param parameterIndex the first parameter is 1, the second is 2, ...\n  @param x the parameter value\n}\nprocedure TZAbstractPreparedStatement.SetString(ParameterIndex: Integer;\n   const Value: String);\nvar\n  Temp: TZVariant;\nbegin\n  DefVarManager.SetAsString(Temp, Value);\n  SetInParam(ParameterIndex, stString, Temp);\nend;\n\n{**\n  Sets the designated parameter to a Object Pascal <code>WideString</code>\n  value. The driver converts this\n  to an SQL <code>VARCHAR</code> or <code>LONGVARCHAR</code> value\n  (depending on the argument's\n  size relative to the driver's limits on <code>VARCHAR</code> values)\n  when it sends it to the database.\n\n  @param parameterIndex the first parameter is 1, the second is 2, ...\n  @param x the parameter value\n}\n\nprocedure TZAbstractPreparedStatement.SetUnicodeString(ParameterIndex: Integer;\n  const Value: ZWideString);\nvar\n  Temp: TZVariant;\nbegin\n  DefVarManager.SetAsUnicodeString(Temp, Value);\n  SetInParam(ParameterIndex, stUnicodeString, Temp);\nend;\n\n{**\n  Sets the designated parameter to a Java array of bytes.  The driver converts\n  this to an SQL <code>VARBINARY</code> or <code>LONGVARBINARY</code>\n  (depending on the argument's size relative to the driver's limits on\n  <code>VARBINARY</code> values) when it sends it to the database.\n\n  @param parameterIndex the first parameter is 1, the second is 2, ...\n  @param x the parameter value\n}\nprocedure TZAbstractPreparedStatement.SetBytes(ParameterIndex: Integer;\n  const Value: TByteDynArray);\nvar\n  Temp: TZVariant;\nbegin\n  DefVarManager.SetAsBytes(Temp, Value);\n  SetInParam(ParameterIndex, stBytes, Temp);\nend;\n\n{**\n  Sets the designated parameter to a <code<java.sql.Date</code> value.\n  The driver converts this to an SQL <code>DATE</code>\n  value when it sends it to the database.\n\n  @param parameterIndex the first parameter is 1, the second is 2, ...\n  @param x the parameter value\n}\nprocedure TZAbstractPreparedStatement.SetDate(ParameterIndex: Integer;\n  Value: TDateTime);\nvar\n  Temp: TZVariant;\nbegin\n  DefVarManager.SetAsDateTime(Temp, Value);\n  SetInParam(ParameterIndex, stDate, Temp);\nend;\n\n{**\n  Sets the designated parameter to a <code>java.sql.Time</code> value.\n  The driver converts this to an SQL <code>TIME</code> value\n  when it sends it to the database.\n\n  @param parameterIndex the first parameter is 1, the second is 2, ...\n  @param x the parameter value\n}\nprocedure TZAbstractPreparedStatement.SetTime(ParameterIndex: Integer;\n  Value: TDateTime);\nvar\n  Temp: TZVariant;\nbegin\n  DefVarManager.SetAsDateTime(Temp, Value);\n  SetInParam(ParameterIndex, stTime, Temp);\nend;\n\n{**\n  Sets the designated parameter to a <code>java.sql.Timestamp</code> value.\n  The driver converts this to an SQL <code>TIMESTAMP</code> value\n  when it sends it to the database.\n\n  @param parameterIndex the first parameter is 1, the second is 2, ...\n  @param x the parameter value\n}\nprocedure TZAbstractPreparedStatement.SetTimestamp(ParameterIndex: Integer;\n  Value: TDateTime);\nvar\n  Temp: TZVariant;\nbegin\n  DefVarManager.SetAsDateTime(Temp, Value);\n  SetInParam(ParameterIndex, stTimestamp, Temp);\nend;\n\n{**\n  Sets the designated parameter to the given input stream, which will have\n  the specified number of bytes.\n  When a very large ASCII value is input to a <code>LONGVARCHAR</code>\n  parameter, it may be more practical to send it via a\n  <code>java.io.InputStream</code>. Data will be read from the stream\n  as needed until end-of-file is reached.  The JDBC driver will\n  do any necessary conversion from ASCII to the database char format.\n\n  <P><B>Note:</B> This stream object can either be a standard\n  Java stream object or your own subclass that implements the\n  standard interface.\n\n  @param parameterIndex the first parameter is 1, the second is 2, ...\n  @param x the Java input stream that contains the ASCII parameter value\n  @param length the number of bytes in the stream\n}\nprocedure TZAbstractPreparedStatement.SetAsciiStream(\n  ParameterIndex: Integer; Value: TStream);\nbegin\n  SetBlob(ParameterIndex, stAsciiStream, TZAbstractBlob.CreateWithStream(Value, GetConnection));\nend;\n\n{**\n  Sets the designated parameter to the given input stream, which will have\n  the specified number of bytes.\n  When a very large UNICODE value is input to a <code>LONGVARCHAR</code>\n  parameter, it may be more practical to send it via a\n  <code>java.io.InputStream</code> object. The data will be read from the stream\n  as needed until end-of-file is reached.  The JDBC driver will\n  do any necessary conversion from UNICODE to the database char format.\n  The byte format of the Unicode stream must be Java UTF-8, as\n  defined in the Java Virtual Machine Specification.\n\n  <P><B>Note:</B> This stream object can either be a standard\n  Java stream object or your own subclass that implements the\n  standard interface.\n\n  @param parameterIndex the first parameter is 1, the second is 2, ...\n  @param x the java input stream which contains the UNICODE parameter value\n}\nprocedure TZAbstractPreparedStatement.SetUnicodeStream(\n  ParameterIndex: Integer; Value: TStream);\nbegin\n  SetBlob(ParameterIndex, stUnicodeStream, TZAbstractBlob.CreateWithStream(Value, GetConnection));\nend;\n\n{**\n  Sets the designated parameter to the given input stream, which will have\n  the specified number of bytes.\n  When a very large binary value is input to a <code>LONGVARBINARY</code>\n  parameter, it may be more practical to send it via a\n  <code>java.io.InputStream</code> object. The data will be read from the stream\n  as needed until end-of-file is reached.\n\n  <P><B>Note:</B> This stream object can either be a standard\n  Java stream object or your own subclass that implements the\n  standard interface.\n\n  @param parameterIndex the first parameter is 1, the second is 2, ...\n  @param x the java input stream which contains the binary parameter value\n}\nprocedure TZAbstractPreparedStatement.SetBinaryStream(\n  ParameterIndex: Integer; Value: TStream);\nbegin\n  SetBlob(ParameterIndex, stBinaryStream, TZAbstractBlob.CreateWithStream(Value, GetConnection));\nend;\n\n{**\n  Sets a blob object for the specified parameter.\n  @param ParameterIndex the first parameter is 1, the second is 2, ...\n  @param Value the java blob object.\n}\nprocedure TZAbstractPreparedStatement.SetBlob(ParameterIndex: Integer;\n  SQLType: TZSQLType; Value: IZBlob);\nvar\n  Temp: TZVariant;\nbegin\n  if not (SQLType in [stAsciiStream, stUnicodeStream, stBinaryStream]) then\n    raise EZSQLException.Create(SWrongTypeForBlobParameter);\n  DefVarManager.SetAsInterface(Temp, Value);\n  SetInParam(ParameterIndex, SQLType, Temp);\nend;\n\n{**\n  Sets a variant value for the specified parameter.\n  @param ParameterIndex the first parameter is 1, the second is 2, ...\n  @param Value the variant value.\n}\nprocedure TZAbstractPreparedStatement.SetValue(ParameterIndex: Integer;\n  const Value: TZVariant);\nvar\n  SQLType: TZSQLType;\nbegin\n  case Value.VType of\n    vtBoolean: SQLType := stBoolean;\n    vtInteger: SQLType := stLong;\n    vtFloat: SQLType := stBigDecimal;\n    vtUnicodeString: SQLType := stUnicodeString;\n    vtDateTime: SQLType := stTimestamp;\n  else\n    SQLType := stString;\n  end;\n  SetInParam(ParameterIndex, SQLType, Value);\nend;\n\n{**\n  Clears the current parameter values immediately.\n  <P>In general, parameter values remain in force for repeated use of a\n  statement. Setting a parameter value automatically clears its\n  previous value.  However, in some cases it is useful to immediately\n  release the resources used by the current parameter values; this can\n  be done by calling the method <code>clearParameters</code>.\n}\nprocedure TZAbstractPreparedStatement.ClearParameters;\nvar\n  I: Integer;\nbegin\n  for I := 1 to FInParamCount do\n  begin\n    SetInParam(I, stUnknown, NullVariant);\n    SetDefaultValue(I, '');\n  end;\n  SetInParamCount(0);\nend;\n\n{**\n  Executes any kind of SQL statement.\n  Some prepared statements return multiple results; the <code>execute</code>\n  method handles these complex statements as well as the simpler\n  form of statements handled by the methods <code>executeQuery</code>\n  and <code>executeUpdate</code>.\n  @see Statement#execute\n}\n{$WARNINGS OFF}\nfunction TZAbstractPreparedStatement.ExecutePrepared: Boolean;\nbegin\n  { Logging Execution }\n  LogPrepStmtMessage(lcExecPrepStmt, '');\n  Inc(FExecCount);\nend;\n{$WARNINGS ON}\n\nfunction TZAbstractPreparedStatement.GetSQL: String;\nbegin\n  Result := FSQL;\nend;\n\nprocedure TZAbstractPreparedStatement.Prepare;\nbegin\n  PrepareInParameters;\n  FPrepared := True;\nend;\n\nprocedure TZAbstractPreparedStatement.Unprepare;\nbegin\n  UnPrepareInParameters;\n  FPrepared := False;\nend;\n\nfunction TZAbstractPreparedStatement.IsPrepared: Boolean;\nbegin\n  Result := FPrepared;\nend;\n\n{**\n  Adds a set of parameters to this <code>PreparedStatement</code>\n  object's batch of commands.\n  @see Statement#addBatch\n}\nprocedure TZAbstractPreparedStatement.AddBatchPrepared;\nbegin\nend;\n\n{**\n  Gets the number, types and properties of a <code>ResultSet</code>\n  object's columns.\n  @return the description of a <code>ResultSet</code> object's columns\n}\nfunction TZAbstractPreparedStatement.GetMetaData: IZResultSetMetaData;\nbegin\n  Result := nil;\n  RaiseUnsupportedException;\nend;\n\n{ TZAbstractCallableStatement }\n\n{**\n  Constructs this object and assigns main properties.\n  @param Connection a database connection object.\n  @param Sql a prepared Sql statement.\n  @param Info a statement parameters.\n}\nconstructor TZAbstractCallableStatement.Create(Connection: IZConnection;\n  SQL: string; Info: TStrings);\nbegin\n  inherited Create(Connection, SQL, Info);\n  FOutParamCount := 0;\n  SetOutParamCount(0);\n  FProcSql := ''; //Init -> FPC\n  FLastWasNull := True;\n  FResultSets := TZCollection.Create;\n  FIsFunction := False;\nend;\n\n{**\n  Close and release a list of returned resultsets.\n}\nprocedure TZAbstractCallableStatement.ClearResultSets;\nvar\n  I: Integer;\n  RS: IZResultSet;\nbegin\n  for i := 0 to FResultSets.Count -1 do\n    if Supports(FResultSets[i], IZResultSet, RS) then //possible IZUpdateCount e.g. DBLib, ASA\n      RS.Close;\n  FResultSets.Clear;\n  LastResultSet := nil;\nend;\n\n{**\n   Function remove stUnknown and ptResult, ptOutput paramters from\n   InParamTypes and InParamValues because the out-params are added after\n   fetching.\n}\nprocedure TZAbstractCallableStatement.TrimInParameters;\nvar\n  I: integer;\n  ParamValues: TZVariantDynArray;\n  ParamTypes: TZSQLTypeArray;\n  ParamCount: Integer;\nbegin\n  ParamCount := 0;\n  SetLength(ParamValues, InParamCount);\n  SetLength(ParamTypes, InParamCount);\n\n  {Need for dbc access, where no metadata is used to register the ParamTypes}\n  if Length(FDBParamTypes) < InParamCount then\n    SetLength(FDBParamTypes, InParamCount);\n  {end for dbc access}\n\n  for I := 0 to High(InParamTypes) do\n  begin\n    if ( InParamTypes[I] = ZDbcIntfs.stUnknown ) then\n     Continue;\n    if (FDBParamTypes[i] in [2, 4]) then //[ptResult, ptOutput]\n      continue; //EgonHugeist: Ignore known OutParams! else StatmentInparamCount <> expect ProcedureParamCount\n    ParamTypes[ParamCount] := InParamTypes[I];\n    ParamValues[ParamCount] := InParamValues[I];\n    Inc(ParamCount);\n  end;\n  if ParamCount = InParamCount then\n    Exit;\n  InParamTypes := ParamTypes;\n  InParamValues := ParamValues;\n  SetInParamCount(ParamCount); //AVZ\nend;\n\n{**\n  Sets a new parameter count and initializes the buffers.\n  @param NewParamCount a new parameters count.\n}\nprocedure TZAbstractCallableStatement.SetOutParamCount(NewParamCount: Integer);\nvar\n  I: Integer;\nbegin\n  SetLength(FOutParamValues, NewParamCount);\n  SetLength(FOutParamTypes, NewParamCount);\n  for I := FOutParamCount to NewParamCount - 1 do\n  begin\n    FOutParamValues[I] := NullVariant;\n    FOutParamTypes[I] := stUnknown;\n  end;\n  FOutParamCount := NewParamCount;\nend;\n\n{**\n  Clears the current parameter values immediately.\n  <P>In general, parameter values remain in force for repeated use of a\n  statement. Setting a parameter value automatically clears its\n  previous value.  However, in some cases it is useful to immediately\n  release the resources used by the current parameter values; this can\n  be done by calling the method <code>clearParameters</code>.\n}\nprocedure TZAbstractCallableStatement.ClearParameters;\nvar\n  I: Integer;\nbegin\n  inherited;\n  for I := 1 to FOutParamCount do\n  begin\n    OutParamValues[I - 1] := NullVariant;\n    OutParamTypes[I - 1] := stUnknown;\n  end;\n  SetOutParamCount(0);\nend;\n\n{**\n  Releases this <code>Statement</code> object's database\n  and JDBC resources immediately instead of waiting for\n  this to happen when it is automatically closed.\n  It is generally good practice to release resources as soon as\n  you are finished with them to avoid tying up database\n  resources.\n  <P><B>Note:</B> A <code>Statement</code> object is automatically closed when it is\n  garbage collected. When a <code>Statement</code> object is closed, its current\n  <code>ResultSet</code> object, if one exists, is also closed.\n}\nprocedure TZAbstractCallableStatement.Close;\nbegin\n  ClearResultSets;\n  inherited Close;\nend;\n\n\n{**\n  Do we call a function or a procedure?\n  @result Returns <code>True</code> if we call a function\n}\nfunction TZAbstractCallableStatement.IsFunction: Boolean;\nbegin\n  Result := FIsFunction;\nend;\n\n{**\n  Do we have ptInputOutput or ptOutput paramets in a function or procedure?\n  @result Returns <code>True</code> if ptInputOutput or ptOutput is available\n}\nfunction TZAbstractCallableStatement.HasOutParameter: Boolean;\nbegin\n  Result := FHasOutParameter;\nend;\n\n{**\n  Are more resultsets retrieved?\n  @result Returns <code>True</code> if more resultsets are retrieved\n}\nfunction TZAbstractCallableStatement.HasMoreResultSets: Boolean;\nbegin\n  Result := False;\nend;\n\n{**\n  Get the first resultset..\n  @result <code>IZResultSet</code> if supported\n}\nfunction TZAbstractCallableStatement.GetFirstResultSet: IZResultSet;\nbegin\n  Result := nil;\nend;\n\n{**\n  Get the previous resultset..\n  @result <code>IZResultSet</code> if supported\n}\nfunction TZAbstractCallableStatement.GetPreviousResultSet: IZResultSet;\nbegin\n  Result := nil;\nend;\n\n{**\n  Get the next resultset..\n  @result <code>IZResultSet</code> if supported\n}\nfunction TZAbstractCallableStatement.GetNextResultSet: IZResultSet;\nbegin\n  Result := nil;\nend;\n\n{**\n  Get the last resultset..\n  @result <code>IZResultSet</code> if supported\n}\nfunction TZAbstractCallableStatement.GetLastResultSet: IZResultSet;\nbegin\n  Result := nil;\nend;\n\n{**\n  First ResultSet?\n  @result <code>True</code> if first ResultSet\n}\nfunction TZAbstractCallableStatement.BOR: Boolean;\nbegin\n  Result := True;\nend;\n\n{**\n  Last ResultSet?\n  @result <code>True</code> if Last ResultSet\n}\nfunction TZAbstractCallableStatement.EOR: Boolean;\nbegin\n  Result := True;\nend;\n\n{**\n  Retrieves a ResultSet by his index.\n  @param Index the index of the Resultset\n  @result <code>IZResultSet</code> of the Index or nil.\n}\nfunction TZAbstractCallableStatement.GetResultSetByIndex(const Index: Integer): IZResultSet;\nbegin\n  Result := nil;\nend;\n\n{**\n  Returns the Count of retrived ResultSets.\n  @result <code>Integer</code> Count\n}\nfunction TZAbstractCallableStatement.GetResultSetCount: Integer;\nbegin\n  Result := 0;\nend;\n\n{**\n  Registers the OUT parameter in ordinal position\n  <code>parameterIndex</code> to the JDBC type\n  <code>sqlType</code>.  All OUT parameters must be registered\n  before a stored procedure is executed.\n  <p>\n  The JDBC type specified by <code>sqlType</code> for an OUT\n  parameter determines the Java type that must be used\n  in the <code>get</code> method to read the value of that parameter.\n  <p>\n  If the JDBC type expected to be returned to this output parameter\n  is specific to this particular database, <code>sqlType</code>\n  should be <code>java.sql.Types.OTHER</code>.  The method retrieves the value.\n  @param parameterIndex the first parameter is 1, the second is 2,\n  and so on\n  @param sqlType the JDBC type code defined by <code>java.sql.Types</code>.\n  If the parameter is of JDBC type <code>NUMERIC</code>\n  or <code>DECIMAL</code>, the version of\n  <code>registerOutParameter</code> that accepts a scale value should be used.\n}\nprocedure TZAbstractCallableStatement.RegisterOutParameter(ParameterIndex,\n  SQLType: Integer);\nbegin\n  SetOutParamCount(ParameterIndex);\n  OutParamTypes[ParameterIndex - 1] := TZSQLType(SQLType);\nend;\n\nprocedure TZAbstractCallableStatement.RegisterParamType(ParameterIndex,\n  ParamType: Integer);\nbegin\n  if (Length(FDBParamTypes) < ParameterIndex) then\n    SetLength(FDBParamTypes, ParameterIndex);\n\n  FDBParamTypes[ParameterIndex - 1] := ParamType;\n  if not FIsFunction then FIsFunction := ParamType = 4; //ptResult\n  if not FHasOutParameter then FHasOutParameter := ParamType in [2,3]; //ptOutput, ptInputOutput\nend;\n\n{**\n  Gets a output parameter value by it's index.\n  @param ParameterIndex a parameter index.\n  @returns a parameter value.\n}\nfunction TZAbstractCallableStatement.GetOutParam(\n  ParameterIndex: Integer): TZVariant;\nbegin\n  if Assigned(OutParamValues) then\n  begin\n    Result := OutParamValues[ParameterIndex - 1];\n    FLastWasNull := DefVarManager.IsNull(Result);\n  end\n  else\n  begin\n    Result:=NullVariant;\n    FLastWasNull:=True;\n  end;\nend;\n\nprocedure TZAbstractCallableStatement.SetProcSQL(const Value: String);\nbegin\n  FProcSql := Value;\nend;\n\n{**\n  Indicates whether or not the last OUT parameter read had the value of\n  SQL <code>NULL</code>.  Note that this method should be called only after\n  calling a <code>getXXX</code> method; otherwise, there is no value to use in\n  determining whether it is <code>null</code> or not.\n  @return <code>true</code> if the last parameter read was SQL\n  <code>NULL</code>; <code>false</code> otherwise\n}\nfunction TZAbstractCallableStatement.WasNull: Boolean;\nbegin\n  Result := FLastWasNull;\nend;\n\n{**\n  Indicates whether or not the specified OUT parameter read had the value of\n  SQL <code>NULL</code>.\n  @return <code>true</code> if the parameter read was SQL\n  <code>NULL</code>; <code>false</code> otherwise\n}\nfunction TZAbstractCallableStatement.IsNull(ParameterIndex: Integer): Boolean;\nbegin\n  GetOutParam(ParameterIndex);\n  Result := FLastWasNull;\nend;\n\n{**\n  Retrieves the value of a JDBC <code>CHAR</code>, <code>VARCHAR</code>,\n  or <code>LONGVARCHAR</code> parameter as a <code>String</code> in\n  the Java programming language.\n  <p>\n  For the fixed-length type JDBC <code>CHAR</code>,\n  the <code>String</code> object\n  returned has exactly the same value the JDBC\n  <code>CHAR</code> value had in the\n  database, including any padding added by the database.\n  @param parameterIndex the first parameter is 1, the second is 2,\n  and so on\n  @return the parameter value. If the value is SQL <code>NULL</code>, the result\n  is <code>null</code>.\n  @exception SQLException if a database access error occurs\n}\nfunction TZAbstractCallableStatement.GetPChar(ParameterIndex: Integer): PChar;\nbegin\n  FTemp := GetString(ParameterIndex);\n  Result := PChar(FTemp);\nend;\n\n{**\n  Retrieves the value of a JDBC <code>CHAR</code>, <code>VARCHAR</code>,\n  or <code>LONGVARCHAR</code> parameter as a <code>String</code> in\n  the Java programming language.\n  <p>\n  For the fixed-length type JDBC <code>CHAR</code>,\n  the <code>String</code> object\n  returned has exactly the same value the JDBC\n  <code>CHAR</code> value had in the\n  database, including any padding added by the database.\n  @param parameterIndex the first parameter is 1, the second is 2,\n  and so on\n  @return the parameter value. If the value is SQL <code>NULL</code>, the result\n  is <code>null</code>.\n  @exception SQLException if a database access error occurs\n}\nfunction TZAbstractCallableStatement.GetString(ParameterIndex: Integer): String;\nbegin\n  Result := SoftVarManager.GetAsString(GetOutParam(ParameterIndex));\nend;\n\n{**\n  Retrieves the value of a JDBC <code>CHAR</code>, <code>VARCHAR</code>,\n  or <code>LONGVARCHAR</code> parameter as a <code>String</code> in\n  the Java programming language.\n  <p>\n  For the fixed-length type JDBC <code>CHAR</code>,\n  the <code>WideString</code> object\n  returned has exactly the same value the JDBC\n  <code>CHAR</code> value had in the\n  database, including any padding added by the database.\n  @param parameterIndex the first parameter is 1, the second is 2,\n  and so on\n  @return the parameter value. If the value is SQL <code>NULL</code>, the result\n  is <code>null</code>.\n  @exception SQLException if a database access error occurs\n}\nfunction TZAbstractCallableStatement.GetUnicodeString(\n  ParameterIndex: Integer): WideString;\nbegin\n  Result := SoftVarManager.GetAsUnicodeString(GetOutParam(ParameterIndex));\nend;\n\n{**\n  Gets the value of a JDBC <code>BIT</code> parameter as a <code>boolean</code>\n  in the Java programming language.\n  @param parameterIndex the first parameter is 1, the second is 2,\n  and so on\n  @return the parameter value.  If the value is SQL <code>NULL</code>, the result\n  is <code>false</code>.\n}\nfunction TZAbstractCallableStatement.GetBoolean(ParameterIndex: Integer): Boolean;\nbegin\n  Result := SoftvarManager.GetAsBoolean(GetOutParam(ParameterIndex));\nend;\n\n{**\n  Gets the value of a JDBC <code>TINYINT</code> parameter as a <code>byte</code>\n  in the Java programming language.\n  @param parameterIndex the first parameter is 1, the second is 2,\n  and so on\n  @return the parameter value.  If the value is SQL <code>NULL</code>, the result\n  is 0.\n}\nfunction TZAbstractCallableStatement.GetByte(ParameterIndex: Integer): Byte;\nbegin\n  Result := Byte(SoftVarManager.GetAsInteger(GetOutParam(ParameterIndex)));\nend;\n\n{**\n  Gets the value of a JDBC <code>SMALLINT</code> parameter as a <code>short</code>\n  in the Java programming language.\n  @param parameterIndex the first parameter is 1, the second is 2,\n  and so on\n  @return the parameter value.  If the value is SQL <code>NULL</code>, the result\n  is 0.\n}\nfunction TZAbstractCallableStatement.GetShort(ParameterIndex: Integer): SmallInt;\nbegin\n  Result := SmallInt(SoftVarManager.GetAsInteger(GetOutParam(ParameterIndex)));\nend;\n\n{**\n  Gets the value of a JDBC <code>INTEGER</code> parameter as an <code>int</code>\n  in the Java programming language.\n  @param parameterIndex the first parameter is 1, the second is 2,\n  and so on\n  @return the parameter value.  If the value is SQL <code>NULL</code>, the result\n  is 0.\n}\nfunction TZAbstractCallableStatement.GetInt(ParameterIndex: Integer): Integer;\nbegin\n  Result := Integer(SoftVarManager.GetAsInteger(GetOutParam(ParameterIndex)));\nend;\n\n{**\n  Gets the value of a JDBC <code>BIGINT</code> parameter as a <code>long</code>\n  in the Java programming language.\n  @param parameterIndex the first parameter is 1, the second is 2,\n  and so on\n  @return the parameter value.  If the value is SQL <code>NULL</code>, the result\n  is 0.\n}\nfunction TZAbstractCallableStatement.GetLong(ParameterIndex: Integer): Int64;\nbegin\n  Result := SoftVarManager.GetAsInteger(GetOutParam(ParameterIndex));\nend;\n\n{**\n  Gets the value of a JDBC <code>FLOAT</code> parameter as a <code>float</code>\n  in the Java programming language.\n  @param parameterIndex the first parameter is 1, the second is 2,\n  and so on\n  @return the parameter value.  If the value is SQL <code>NULL</code>, the result\n  is 0.\n}\nfunction TZAbstractCallableStatement.GetFloat(ParameterIndex: Integer): Single;\nbegin\n  Result := SoftVarManager.GetAsFloat(GetOutParam(ParameterIndex));\nend;\n\n{**\n  Gets the value of a JDBC <code>DOUBLE</code> parameter as a <code>double</code>\n  in the Java programming language.\n  @param parameterIndex the first parameter is 1, the second is 2,\n  and so on\n  @return the parameter value.  If the value is SQL <code>NULL</code>, the result\n  is 0.\n}\nfunction TZAbstractCallableStatement.GetDouble(ParameterIndex: Integer): Double;\nbegin\n  Result := SoftVarManager.GetAsFloat(GetOutParam(ParameterIndex));\nend;\n\n{**\n  Gets the value of a JDBC <code>NUMERIC</code> parameter as a\n  <code>java.math.BigDecimal</code> object with scale digits to\n  the right of the decimal point.\n  @param parameterIndex the first parameter is 1, the second is 2,\n  and so on\n  @return the parameter value.  If the value is SQL <code>NULL</code>, the result is\n  <code>null</code>.\n}\nfunction TZAbstractCallableStatement.GetBigDecimal(ParameterIndex: Integer):\n  Extended;\nbegin\n  Result := SoftVarManager.GetAsFloat(GetOutParam(ParameterIndex));\nend;\n\n{**\n  Gets the value of a JDBC <code>BINARY</code> or <code>VARBINARY</code>\n  parameter as an array of <code>byte</code> values in the Java\n  programming language.\n  @param parameterIndex the first parameter is 1, the second is 2,\n  and so on\n  @return the parameter value.  If the value is SQL <code>NULL</code>, the result is\n   <code>null</code>.\n}\nfunction TZAbstractCallableStatement.GetBytes(ParameterIndex: Integer):\n  TByteDynArray;\nbegin\n  Result := SoftVarManager.GetAsBytes(GetOutParam(ParameterIndex));\nend;\n\n{**\n  Gets the value of a JDBC <code>DATE</code> parameter as a\n  <code>java.sql.Date</code> object.\n  @param parameterIndex the first parameter is 1, the second is 2,\n  and so on\n  @return the parameter value.  If the value is SQL <code>NULL</code>, the result\n  is <code>null</code>.\n}\nfunction TZAbstractCallableStatement.GetDate(ParameterIndex: Integer):\n  TDateTime;\nbegin\n  Result := SoftVarManager.GetAsDateTime(GetOutParam(ParameterIndex));\nend;\n\n{**\n  Get the value of a JDBC <code>TIME</code> parameter as a\n  <code>java.sql.Time</code> object.\n  @param parameterIndex the first parameter is 1, the second is 2,\n  and so on\n  @return the parameter value.  If the value is SQL <code>NULL</code>, the result\n  is <code>null</code>.\n}\nfunction TZAbstractCallableStatement.GetTime(ParameterIndex: Integer):\n  TDateTime;\nbegin\n  Result := SoftVarManager.GetAsDateTime(GetOutParam(ParameterIndex));\nend;\n\n{**\n  Gets the value of a JDBC <code>TIMESTAMP</code> parameter as a\n  <code>java.sql.Timestamp</code> object.\n  @param parameterIndex the first parameter is 1, the second is 2,\n  and so on\n  @return the parameter value.  If the value is SQL <code>NULL</code>, the result\n  is <code>null</code>.\n}\nfunction TZAbstractCallableStatement.GetTimestamp(ParameterIndex: Integer):\n  TDateTime;\nbegin\n  Result := SoftVarManager.GetAsDateTime(GetOutParam(ParameterIndex));\nend;\n\n{**\n  Gets the value of a JDBC <code>Variant</code> parameter value.\n  @param parameterIndex the first parameter is 1, the second is 2,\n  and so on\n  @return the parameter value.  If the value is SQL <code>NULL</code>,\n  the result is <code>null</code>.\n}\nfunction TZAbstractCallableStatement.GetValue(ParameterIndex: Integer):\n  TZVariant;\nbegin\n  Result := GetOutParam(ParameterIndex);\nend;\n\n{ TZAbstractPreparedCallableStatement }\n\nprocedure TZAbstractPreparedCallableStatement.SetProcSQL(const Value: String);\nbegin\n  if Value <> ProcSQL then Unprepare;\n  inherited SetProcSQL(Value);\n  if (Value <> '') and ( not Prepared ) then Prepare;\nend;\n\n{**\n  Executes an SQL statement that returns a single <code>ResultSet</code> object.\n  @param sql typically this is a static SQL <code>SELECT</code> statement\n  @return a <code>ResultSet</code> object that contains the data produced by the\n    given query; never <code>null</code>\n}\nfunction TZAbstractPreparedCallableStatement.ExecuteQuery(const SQL: ZWideString): IZResultSet;\nbegin\n  if (SQL <> Self.WSQL) and (Prepared) then Unprepare;\n  WSQL := SQL;\n  Result := ExecuteQueryPrepared;\nend;\n\nfunction TZAbstractPreparedCallableStatement.ExecuteQuery(const SQL: RawByteString): IZResultSet;\nbegin\n  if (SQL <> Self.ASQL) and (Prepared) then Unprepare;\n  Self.ASQL := SQL;\n  Result := ExecuteQueryPrepared;\nend;\n\n{**\n  Executes an SQL <code>INSERT</code>, <code>UPDATE</code> or\n  <code>DELETE</code> statement. In addition,\n  SQL statements that return nothing, such as SQL DDL statements,\n  can be executed.\n\n  @param sql an SQL <code>INSERT</code>, <code>UPDATE</code> or\n    <code>DELETE</code> statement or an SQL statement that returns nothing\n  @return either the row count for <code>INSERT</code>, <code>UPDATE</code>\n    or <code>DELETE</code> statements, or 0 for SQL statements that return nothing\n}\nfunction TZAbstractPreparedCallableStatement.ExecuteUpdate(const SQL: ZWideString): Integer;\nbegin\n  if (SQL <> WSQL) and (Prepared) then Unprepare;\n  WSQL := SQL;\n  Result := ExecuteUpdatePrepared;\nend;\n\nfunction TZAbstractPreparedCallableStatement.ExecuteUpdate(const SQL: RawByteString): Integer;\nbegin\n  if (SQL <> ASQL) and (Prepared) then Unprepare;\n  ASQL := SQL;\n  Result := ExecuteUpdatePrepared;\nend;\n\n{**\n  Executes an SQL statement that may return multiple results.\n  Under some (uncommon) situations a single SQL statement may return\n  multiple result sets and/or update counts.  Normally you can ignore\n  this unless you are (1) executing a stored procedure that you know may\n  return multiple results or (2) you are dynamically executing an\n  unknown SQL string.  The  methods <code>execute</code>,\n  <code>getMoreResults</code>, <code>getResultSet</code>,\n  and <code>getUpdateCount</code> let you navigate through multiple results.\n\n  The <code>execute</code> method executes an SQL statement and indicates the\n  form of the first result.  You can then use the methods\n  <code>getResultSet</code> or <code>getUpdateCount</code>\n  to retrieve the result, and <code>getMoreResults</code> to\n  move to any subsequent result(s).\n\n  @param sql any SQL statement\n  @return <code>true</code> if the next result is a <code>ResultSet</code> object;\n  <code>false</code> if it is an update count or there are no more results\n  @see #getResultSet\n  @see #getUpdateCount\n  @see #getMoreResults\n}\n\nfunction TZAbstractPreparedCallableStatement.Execute(const SQL: ZWideString): Boolean;\nbegin\n  if (SQL <> WSQL) and (Prepared) then Unprepare;\n  WSQL := SQL;\n  Result := ExecutePrepared;\nend;\n\nfunction TZAbstractPreparedCallableStatement.Execute(const SQL: RawByteString): Boolean;\nbegin\n  if (SQL <> ASQL) and (Prepared) then Unprepare;\n  ASQL := SQL;\n  Result := ExecutePrepared;\nend;\n\n{ TZEmulatedPreparedStatement }\n\n{**\n  Destroys this object and cleanups the memory.\n}\ndestructor TZEmulatedPreparedStatement.Destroy;\nbegin\n  if FCachedQuery <> nil then\n    FCachedQuery.Free;\n  inherited Destroy;\nend;\n\n{**\n  Sets a reference to the last statement.\n  @param LastStatement the last statement interface.\n}\nprocedure TZEmulatedPreparedStatement.SetLastStatement(\n  LastStatement: IZStatement);\nbegin\n  if FLastStatement <> nil then\n    FLastStatement.Close;\n  FLastStatement := LastStatement;\nend;\n\nfunction TZEmulatedPreparedStatement.PrepareWideSQLParam(ParamIndex: Integer): ZWideString;\nbegin\n  Result := '';\nend;\n\nfunction TZEmulatedPreparedStatement.PrepareAnsiSQLParam(ParamIndex: Integer): RawByteString;\nbegin\n  Result := '';\nend;\n\n{**\n  Creates a temporary statement which executes queries.\n  @param Info a statement parameters.\n  @return a created statement object.\n}\nfunction TZEmulatedPreparedStatement.GetExecStatement: IZStatement;\nbegin\n  if ExecStatement = nil then\n  begin\n    ExecStatement := CreateExecStatement;\n\n    ExecStatement.SetMaxFieldSize(GetMaxFieldSize);\n    ExecStatement.SetMaxRows(GetMaxRows);\n    ExecStatement.SetEscapeProcessing(EscapeProcessing);\n    ExecStatement.SetQueryTimeout(GetQueryTimeout);\n    ExecStatement.SetCursorName(CursorName);\n\n    ExecStatement.SetFetchDirection(GetFetchDirection);\n    ExecStatement.SetFetchSize(GetFetchSize);\n    ExecStatement.SetResultSetConcurrency(GetResultSetConcurrency);\n    ExecStatement.SetResultSetType(GetResultSetType);\n  end;\n  Result := ExecStatement;\nend;\n\n{**\n  Splits a SQL query into a list of sections.\n  @returns a list of splitted sections.\n}\nfunction TZEmulatedPreparedStatement.TokenizeSQLQuery: TStrings;\nvar\n  I: Integer;\n  Tokens: TStrings;\n  Temp: string;\nbegin\n  if FCachedQuery = nil then\n  begin\n    FCachedQuery := TStringList.Create;\n    if Pos('?', SSQL) > 0 then\n    begin\n      Tokens := Connection.GetDriver.GetTokenizer.TokenizeBufferToList(SSQL, [toUnifyWhitespaces]);\n      try\n        Temp := '';\n        for I := 0 to Tokens.Count - 1 do\n        begin\n          if Tokens[I] = '?' then\n          begin\n            if FNeedNCharDetection and not (Temp = '') then\n                FCachedQuery.Add(Temp)\n            else\n              FCachedQuery.Add(Temp);\n            FCachedQuery.AddObject('?', Self);\n            Temp := '';\n          end\n          else\n            if FNeedNCharDetection and (Tokens[I] = 'N') and (Tokens.Count > i) and (Tokens[i+1] = '?') then\n            begin\n              FCachedQuery.Add(Temp);\n              FCachedQuery.Add(Tokens[i]);\n              Temp := '';\n            end\n            else\n              Temp := Temp + Tokens[I];\n        end;\n        if Temp <> '' then\n          FCachedQuery.Add(Temp);\n      finally\n        Tokens.Free;\n      end;\n    end\n    else\n      FCachedQuery.Add(SSQL);\n  end;\n  Result := FCachedQuery;\nend;\n\n{**\n  Prepares an SQL statement and inserts all data values.\n  @return a prepared SQL statement.\n}\nfunction TZEmulatedPreparedStatement.PrepareWideSQLQuery: ZWideString;\nvar\n  I: Integer;\n  ParamIndex: Integer;\n  Tokens: TStrings;\nbegin\n  ParamIndex := 0;\n  Result := '';\n  Tokens := TokenizeSQLQuery;\n\n  for I := 0 to Tokens.Count - 1 do\n  begin\n    if Tokens[I] = '?' then\n    begin\n      Result := Result + PrepareWideSQLParam(ParamIndex);\n      Inc(ParamIndex);\n    end\n    else\n      Result := Result + ZPlainUnicodeString(Tokens[I]);\n  end;\nend;\n\n{**\n  Prepares an SQL statement and inserts all data values.\n  @return a prepared SQL statement.\n}\nfunction TZEmulatedPreparedStatement.PrepareAnsiSQLQuery: RawByteString;\nvar\n  I: Integer;\n  ParamIndex: Integer;\n  Tokens: TStrings;\nbegin\n  ParamIndex := 0;\n  Result := '';\n  Tokens := TokenizeSQLQuery;\n\n  for I := 0 to Tokens.Count - 1 do\n  begin\n    if Tokens[I] = '?' then\n    begin\n      Result := Result + PrepareAnsiSQLParam(ParamIndex);\n      Inc(ParamIndex);\n    end\n    else\n      Result := Result + ZPlainString(Tokens[I]);\n  end;\n  {$IFNDEF UNICODE}\n  if GetConnection.AutoEncodeStrings then\n     Result := GetConnection.GetDriver.GetTokenizer.GetEscapeString(Result);\n  {$ENDIF}\nend;\n\n{**\n  Closes this statement and frees all resources.\n}\nprocedure TZEmulatedPreparedStatement.Close;\nbegin\n  inherited Close;\n  if LastStatement <> nil then\n  begin\n    FLastStatement.Close;\n    FLastStatement := nil;\n  end;\nend;\n\n{**\n  Executes an SQL statement that may return multiple results.\n  Under some (uncommon) situations a single SQL statement may return\n  multiple result sets and/or update counts.  Normally you can ignore\n  this unless you are (1) executing a stored procedure that you know may\n  return multiple results or (2) you are dynamically executing an\n  unknown SQL string.  The  methods <code>execute</code>,\n  <code>getMoreResults</code>, <code>getResultSet</code>,\n  and <code>getUpdateCount</code> let you navigate through multiple results.\n\n  The <code>execute</code> method executes an SQL statement and indicates the\n  form of the first result.  You can then use the methods\n  <code>getResultSet</code> or <code>getUpdateCount</code>\n  to retrieve the result, and <code>getMoreResults</code> to\n  move to any subsequent result(s).\n\n  @param sql any SQL statement\n  @return <code>true</code> if the next result is a <code>ResultSet</code> object;\n  <code>false</code> if it is an update count or there are no more results\n}\nfunction TZEmulatedPreparedStatement.Execute(const SQL: ZWideString): Boolean;\nbegin\n  LastStatement := GetExecStatement;\n  Result := LastStatement.Execute(SQL);\n  if Result then\n    LastResultSet := LastStatement.GetResultSet\n  else\n    LastUpdateCount := LastStatement.GetUpdateCount;\nend;\n\n{**\n  Executes an SQL statement that may return multiple results.\n  Under some (uncommon) situations a single SQL statement may return\n  multiple result sets and/or update counts.  Normally you can ignore\n  this unless you are (1) executing a stored procedure that you know may\n  return multiple results or (2) you are dynamically executing an\n  unknown SQL string.  The  methods <code>execute</code>,\n  <code>getMoreResults</code>, <code>getResultSet</code>,\n  and <code>getUpdateCount</code> let you navigate through multiple results.\n\n  The <code>execute</code> method executes an SQL statement and indicates the\n  form of the first result.  You can then use the methods\n  <code>getResultSet</code> or <code>getUpdateCount</code>\n  to retrieve the result, and <code>getMoreResults</code> to\n  move to any subsequent result(s).\n\n  @param sql any SQL statement\n  @return <code>true</code> if the next result is a <code>ResultSet</code> object;\n  <code>false</code> if it is an update count or there are no more results\n}\nfunction TZEmulatedPreparedStatement.Execute(const SQL: RawByteString): Boolean;\nbegin\n  LastStatement := GetExecStatement;\n  Result := LastStatement.Execute(SQL);\n  if Result then\n    LastResultSet := LastStatement.GetResultSet\n  else\n    LastUpdateCount := LastStatement.GetUpdateCount;\nend;\n\n{**\n  Executes an SQL statement that returns a single <code>ResultSet</code> object.\n  @param sql typically this is a static SQL <code>SELECT</code> statement\n  @return a <code>ResultSet</code> object that contains the data produced by the\n    given query; never <code>null</code>\n}\nfunction TZEmulatedPreparedStatement.ExecuteQuery(const SQL: ZWideString): IZResultSet;\nbegin\n  Result := GetExecStatement.ExecuteQuery(SQL);\nend;\n\n{**\n  Executes an SQL statement that returns a single <code>ResultSet</code> object.\n  @param sql typically this is a static SQL <code>SELECT</code> statement\n  @return a <code>ResultSet</code> object that contains the data produced by the\n    given query; never <code>null</code>\n}\nfunction TZEmulatedPreparedStatement.ExecuteQuery(const SQL: RawByteString): IZResultSet;\nbegin\n  Result := GetExecStatement.ExecuteQuery(SQL);\nend;\n\n{**\n  Executes an SQL <code>INSERT</code>, <code>UPDATE</code> or\n  <code>DELETE</code> statement. In addition,\n  SQL statements that return nothing, such as SQL DDL statements,\n  can be executed.\n\n  @param sql an SQL <code>INSERT</code>, <code>UPDATE</code> or\n    <code>DELETE</code> statement or an SQL statement that returns nothing\n  @return either the row count for <code>INSERT</code>, <code>UPDATE</code>\n    or <code>DELETE</code> statements, or 0 for SQL statements that return nothing\n}\nfunction TZEmulatedPreparedStatement.ExecuteUpdate(const SQL: ZWideString): Integer;\nbegin\n  Result := GetExecStatement.ExecuteUpdate(SQL);\n  LastUpdateCount := Result;\nend;\n\n{**\n  Executes an SQL <code>INSERT</code>, <code>UPDATE</code> or\n  <code>DELETE</code> statement. In addition,\n  SQL statements that return nothing, such as SQL DDL statements,\n  can be executed.\n\n  @param sql an SQL <code>INSERT</code>, <code>UPDATE</code> or\n    <code>DELETE</code> statement or an SQL statement that returns nothing\n  @return either the row count for <code>INSERT</code>, <code>UPDATE</code>\n    or <code>DELETE</code> statements, or 0 for SQL statements that return nothing\n}\nfunction TZEmulatedPreparedStatement.ExecuteUpdate(const SQL: RawByteString): Integer;\nbegin\n  Result := GetExecStatement.ExecuteUpdate(SQL);\n  LastUpdateCount := Result;\nend;\n\n{**\n  Executes the SQL query in this <code>PreparedStatement</code> object\n  and returns the result set generated by the query.\n\n  @return a <code>ResultSet</code> object that contains the data produced by the\n    query; never <code>null</code>\n}\nfunction TZEmulatedPreparedStatement.ExecutePrepared: Boolean;\nbegin\n  if IsAnsiDriver then\n    Result := Execute(PrepareAnsiSQLQuery)\n  else\n    Result := Execute(PrepareWideSQLQuery);\nend;\n\n{**\n  Executes the SQL query in this <code>PreparedStatement</code> object\n  and returns the result set generated by the query.\n\n  @return a <code>ResultSet</code> object that contains the data produced by the\n    query; never <code>null</code>\n}\nfunction TZEmulatedPreparedStatement.ExecuteQueryPrepared: IZResultSet;\nbegin\n  if IsAnsiDriver then\n    Result := ExecuteQuery(PrepareAnsiSQLQuery)\n  else\n    Result := ExecuteQuery(PrepareWideSQLQuery);\nend;\n\n{**\n  Executes the SQL INSERT, UPDATE or DELETE statement\n  in this <code>PreparedStatement</code> object.\n  In addition,\n  SQL statements that return nothing, such as SQL DDL statements,\n  can be executed.\n\n  @return either the row count for INSERT, UPDATE or DELETE statements;\n  or 0 for SQL statements that return nothing\n}\nfunction TZEmulatedPreparedStatement.ExecuteUpdatePrepared: Integer;\nbegin\n  if IsAnsiDriver then\n    Result := ExecuteUpdate(PrepareAnsiSQLQuery)\n  else\n    Result := ExecuteUpdate(PrepareWideSQLQuery);\nend;\n\nend.\n\n"
  },
  {
    "path": "lib/zeosdbo/src/dbc/ZDbcUtils.pas",
    "content": "{*********************************************************}\n{                                                         }\n{                 Zeos Database Objects                   }\n{            Database Connectivity Functions              }\n{                                                         }\n{        Originally written by Sergey Seroukhov           }\n{                                                         }\n{*********************************************************}\n\n{@********************************************************}\n{    Copyright (c) 1999-2012 Zeos Development Group       }\n{                                                         }\n{ License Agreement:                                      }\n{                                                         }\n{ This library is distributed in the hope that it will be }\n{ useful, but WITHOUT ANY WARRANTY; without even the      }\n{ implied warranty of MERCHANTABILITY or FITNESS FOR      }\n{ A PARTICULAR PURPOSE.  See the GNU Lesser General       }\n{ Public License for more details.                        }\n{                                                         }\n{ The source code of the ZEOS Libraries and packages are  }\n{ distributed under the Library GNU General Public        }\n{ License (see the file COPYING / COPYING.ZEOS)           }\n{ with the following  modification:                       }\n{ As a special exception, the copyright holders of this   }\n{ library give you permission to link this library with   }\n{ independent modules to produce an executable,           }\n{ regardless of the license terms of these independent    }\n{ modules, and to copy and distribute the resulting       }\n{ executable under terms of your choice, provided that    }\n{ you also meet, for each linked independent module,      }\n{ the terms and conditions of the license of that module. }\n{ An independent module is a module which is not derived  }\n{ from or based on this library. If you modify this       }\n{ library, you may extend this exception to your version  }\n{ of the library, but you are not obligated to do so.     }\n{ If you do not wish to do so, delete this exception      }\n{ statement from your version.                            }\n{                                                         }\n{                                                         }\n{ The project web site is located on:                     }\n{   http://zeos.firmos.at  (FORUM)                        }\n{   http://sourceforge.net/p/zeoslib/tickets/ (BUGTRACKER)}\n{   svn://svn.code.sf.net/p/zeoslib/code-0/trunk (SVN)    }\n{                                                         }\n{   http://www.sourceforge.net/projects/zeoslib.          }\n{                                                         }\n{                                                         }\n{                                 Zeos Development Group. }\n{********************************************************@}\n\nunit ZDbcUtils;\n\ninterface\n\n{$I ZDbc.inc}\n\nuses\n  Types, Classes, {$IFDEF MSEgui}mclasses,{$ENDIF} SysUtils, Contnrs,\n  ZCompatibility, ZDbcIntfs, ZDbcResultSetMetadata;\n\n{**\n  Resolves a connection protocol and raises an exception with protocol\n  is not supported.\n  @param Url an initial database URL.\n  @param SuupportedProtocols a driver's supported subprotocols.\n}\nfunction ResolveConnectionProtocol(Url: string;\n  SupportedProtocols: TStringDynArray): string;\n\n{**\n  Resolves a database URL and fills the database connection parameters.\n  @param Url an initial database URL.\n  @param Info an initial info parameters.\n  @param HostName a name of the database host.\n  @param Port a port number.\n  @param Database a database name.\n  @param UserName a name of the database user.\n  @param Password a user's password.\n  @param ResutlInfo a result info parameters.\n}\nprocedure ResolveDatabaseUrl(const Url: string; Info: TStrings;\n  var HostName: string; var Port: Integer; var Database: string;\n  var UserName: string; var Password: string; ResultInfo: TStrings);\n\n{**\n  Checks is the convertion from one type to another type allowed.\n  @param InitialType an initial data type.\n  @param ResultType a result data type.\n  @return <code>True</code> if convertion is allowed\n    or <code>False</code> otherwise.\n}\nfunction CheckConvertion(InitialType: TZSQLType; ResultType: TZSQLType): Boolean;\n\n{**\n  Defines a name of the column type.\n  @param ColumnType a type of the column.\n  @return a name of the specified type.\n}\nfunction DefineColumnTypeName(ColumnType: TZSQLType): string;\n\n{**\n  Raises a copy of the given exception.\n  @param E an exception to be raised.\n}\nprocedure RaiseSQLException(E: Exception);\n\n{**\n  Copies column information objects from one object list to another one.\n  @param FromList the source object list.\n  @param ToList the destination object list.\n}\nprocedure CopyColumnsInfo(FromList: TObjectList; ToList: TObjectList);\n\n{**\n  Defines a statement specific parameter.\n  @param Statement a statement interface reference.\n  @param ParamName a name of the parameter.\n  @param Default a parameter default value.\n  @return a parameter value or default if nothing was found.\n}\nfunction DefineStatementParameter(Statement: IZStatement; const ParamName: string;\n  const Default: string): string;\n\n{**\n  ToLikeString returns the given string or if the string is empty it returns '%'\n  @param Value the string\n  @return given Value or '%'\n}\nfunction ToLikeString(const Value: string): string;\n\n{**\n  GetSQLHexString returns a valid x'..' database understandable String from\n    binary data\n  @param Value the ansistring-pointer to the binary data\n  @param Len then length of the binary Data\n  @param ODBC a boolean if output result should be with a starting 0x...\n  @returns a valid hex formated unicode-safe string\n}\nfunction GetSQLHexWideString(Value: PAnsiChar; Len: Integer; ODBC: Boolean = False): ZWideString;\nfunction GetSQLHexAnsiString(Value: PAnsiChar; Len: Integer; ODBC: Boolean = False): RawByteString;\nfunction GetSQLHexString(Value: PAnsiChar; Len: Integer; ODBC: Boolean = False): String;\n\n{**\n  Returns a FieldSize in Bytes dependend to the FieldType and CharWidth\n  @param <code>TZSQLType</code> the Zeos FieldType\n  @param <code>Integer</code> the Current given FieldLength\n  @param <code>Integer</code> the Current CountOfByte/Char\n  @param <code>Boolean</code> does the Driver returns the FullSizeInBytes\n  @returns <code>Integer</code> the count of AnsiChars for Field.Size * SizeOf(Char)\n}\nfunction GetFieldSize(const SQLType: TZSQLType;ConSettings: PZConSettings;\n  const Precision, CharWidth: Integer; DisplaySize: PInteger = nil;\n    SizeInBytes: Boolean = False): Integer;\n\nfunction WideStringStream(const AString: WideString): TStream;\n\nimplementation\n\nuses ZMessages, ZSysUtils, ZEncoding;\n\n{**\n  Resolves a connection protocol and raises an exception with protocol\n  is not supported.\n  @param Url an initial database URL.\n  @param SupportedProtocols a driver's supported subprotocols.\n}\nfunction ResolveConnectionProtocol(Url: string;\n  SupportedProtocols: TStringDynArray): string;\nvar\n  I: Integer;\n  Protocol: string;\n  Index: Integer;\nbegin\n  Result := '';\n\n  Index := FirstDelimiter(':', Url);\n  if Index > 0 then\n    Protocol := Copy(Url, Index + 1, Length(Url) - Index)\n  else\n    Protocol := '';\n  Index := FirstDelimiter(':', Protocol);\n  if Index > 1 then\n    Protocol := Copy(Protocol, 1, Index - 1)\n  else\n    Protocol := '';\n\n  if Protocol = '' then\n    raise EZSQLException.Create(Format(SIncorrectConnectionURL, [Url]));\n\n  for I := Low(SupportedProtocols) to High(SupportedProtocols) do\n  begin\n    if SupportedProtocols[I] = Protocol then\n    begin\n      Result := Protocol;\n      Break;\n    end;\n  end;\n\n  if Result = '' then\n    raise EZSQLException.Create(Format(SUnsupportedProtocol, [Protocol]));\nend;\n\n{**\n  Resolves a database URL and fills the database connection parameters.\n  @param Url an initial database URL.\n  @param Info an initial info parameters.\n  @param HostName a name of the database host.\n  @param Port a port number.\n  @param Database a database name.\n  @param UserName a name of the database user.\n  @param Password a user's password.\n  @param ResutlInfo a result info parameters.\n}\nprocedure ResolveDatabaseUrl(const Url: string; Info: TStrings;\n  var HostName: string; var Port: Integer; var Database: string;\n  var UserName: string; var Password: string; ResultInfo: TStrings);\nvar\n  Temp: string;\nbegin\n   { assign URL first -> define all out out params }\n   {A correct builded URL exports all these Params if they are expected!}\n  DriverManager.ResolveDatabaseUrl(URL, HostName, Port, DataBase, UserName, Password, ResultInfo);\n\n  { Retrieves non special-escaped-parameters }\n  Temp := Url;\n  while FirstDelimiter('?', Temp) > 0 do //Get all aditional Parameters\n    Temp := Copy(Temp, FirstDelimiter('?', Temp)+1, Length(Temp));\n  PutSplitString(ResultInfo, Temp, ';'); //overrides all Strings\n  ResultInfo.Text := StringReplace(ResultInfo.Text, #9, ';', [rfReplaceAll]); //unescape the #9 char\n\n  if Assigned(Info) then //isn't that strange? (Shouldn't we pick out double-values?)\n    Resultinfo.AddStrings(Info);//All possible PWD/Password and UID/UserName are aviable now, but for what? And the can also be doubled!\n\n  { Redefines user name if not avialble in the URL}\n  if UserName = '' then //Priority 1: URL.UserName\n  begin\n    UserName := ResultInfo.Values['UID']; //Priority 2: Info-UID\n    if UserName = '' then\n      UserName := ResultInfo.Values['username']; //Priority 3: Info-username\n  end;\n\n  { Redefines user password if not avialble in the URL }\n  if Password = '' then //Priority 1: URL.Password\n  begin\n    Password := ResultInfo.Values['PWD']; //Priority 2: Info-PWD\n    if Password = '' then\n      Password := ResultInfo.Values['password']; //Priority 3: Info-password\n  end;\nend;\n\n{**\n  Checks is the convertion from one type to another type allowed.\n  @param InitialType an initial data type.\n  @param ResultType a result data type.\n  @return <code>True</code> if convertion is allowed\n    or <code>False</code> otherwise.\n}\nfunction CheckConvertion(InitialType: TZSQLType; ResultType: TZSQLType): Boolean;\nbegin\n  case ResultType of\n    stBoolean, stByte, stShort, stInteger,\n    stLong, stFloat, stDouble, stBigDecimal:\n      Result := InitialType in [stBoolean, stByte, stShort, stInteger,\n        stLong, stFloat, stDouble, stBigDecimal, stString, stUnicodeString];\n    stString, stUnicodeString:\n      Result := True;\n    stBytes:\n      Result := InitialType in [stString, stUnicodeString, stBytes, stGUID,\n        stAsciiStream, stUnicodeStream, stBinaryStream];\n    stTimestamp:\n      Result := InitialType in [stString, stUnicodeString, stDate, stTime, stTimestamp];\n    stDate:\n      Result := InitialType in [stString, stUnicodeString, stDate, stTimestamp];\n    stTime:\n      Result := InitialType in [stString, stUnicodeString, stTime, stTimestamp];\n    else\n      Result := (ResultType = InitialType) and (InitialType <> stUnknown);\n  end;\nend;\n\n{**\n  Defines a name of the column type.\n  @param ColumnType a type of the column.\n  @return a name of the specified type.\n}\nfunction DefineColumnTypeName(ColumnType: TZSQLType): string;\nbegin\n  case ColumnType of\n    stBoolean:\n      Result := 'Boolean';\n    stByte:\n      Result := 'Byte';\n    stShort:\n      Result := 'Short';\n    stInteger:\n      Result := 'Integer';\n    stLong:\n      Result := 'Long';\n    stFloat:\n      Result := 'Float';\n    stDouble:\n      Result := 'Double';\n    stBigDecimal:\n      Result := 'BigDecimal';\n    stString:\n      Result := 'String';\n    stUnicodeString:\n      Result := 'UnicodeString';\n    stBytes:\n      Result := 'Bytes';\n    stGUID:\n      Result := 'GUID';\n    stDate:\n      Result := 'Date';\n    stTime:\n      Result := 'Time';\n    stTimestamp:\n      Result := 'Timestamp';\n    stAsciiStream:\n      Result := 'AsciiStream';\n    stUnicodeStream:\n      Result := 'UnicodeStream';\n    stBinaryStream:\n      Result := 'BinaryStream';\n    else\n      Result := 'Unknown';\n  end;\nend;\n\n{**\n  Raises a copy of the given exception.\n  @param E an exception to be raised.\n}\nprocedure RaiseSQLException(E: Exception);\nbegin\n  if E is EZSQLException then\n  begin\n    raise EZSQLException.CreateClone(EZSQLException(E));\n  end\n  else\n  begin\n    raise EZSQLException.Create(E.Message);\n  end;\nend;\n\n{**\n  Copies column information objects from one object list to another one.\n  @param FromList the source object list.\n  @param ToList the destination object list.\n}\nprocedure CopyColumnsInfo(FromList: TObjectList; ToList: TObjectList);\nvar\n  I: Integer;\n  Current: TZColumnInfo;\n  ColumnInfo: TZColumnInfo;\nbegin\n  for I := 0 to FromList.Count - 1 do\n  begin\n    Current := TZColumnInfo(FromList[I]);\n    ColumnInfo := TZColumnInfo.Create;\n\n    ColumnInfo.AutoIncrement := Current.AutoIncrement;\n    ColumnInfo.CaseSensitive := Current.CaseSensitive;\n    ColumnInfo.Searchable := Current.Searchable;\n    ColumnInfo.Currency := Current.Currency;\n    ColumnInfo.Nullable := Current.Nullable;\n    ColumnInfo.Signed := Current.Signed;\n    ColumnInfo.ColumnDisplaySize := Current.ColumnDisplaySize;\n    ColumnInfo.ColumnLabel := Current.ColumnLabel;\n    ColumnInfo.ColumnName := Current.ColumnName;\n    ColumnInfo.SchemaName := Current.SchemaName;\n    ColumnInfo.Precision := Current.Precision;\n    ColumnInfo.Scale := Current.Scale;\n    ColumnInfo.TableName := Current.TableName;\n    ColumnInfo.CatalogName := Current.CatalogName;\n    ColumnInfo.ColumnType := Current.ColumnType;\n    ColumnInfo.ReadOnly := Current.ReadOnly;\n    ColumnInfo.Writable := Current.Writable;\n    ColumnInfo.DefinitelyWritable := Current.DefinitelyWritable;\n\n    ToList.Add(ColumnInfo);\n  end;\nend;\n\n{**\n  Defines a statement specific parameter.\n  @param Statement a statement interface reference.\n  @param ParamName a name of the parameter.\n  @param Default a parameter default value.\n  @return a parameter value or default if nothing was found.\n}\nfunction DefineStatementParameter(Statement: IZStatement; const ParamName: string;\n  const Default: string): string;\nbegin\n  Result := Statement.GetParameters.Values[ParamName];\n  if Result = '' then\n    Result := Statement.GetConnection.GetParameters.Values[ParamName];\n  if Result = '' then\n    Result := Default;\nend;\n\n{**\n  ToLikeString returns the given string or if the string is empty it returns '%'\n  @param Value the string\n  @return given Value or '%'\n}\nfunction ToLikeString(const Value: string): string;\nbegin\n  if Value = '' then\n    Result := '%'\n  else\n    Result := Value;\nend;\n\n{**\n  GetSQLHexString returns a valid x'..' database understandable String from\n    binary data\n  @param Value the ansistring-pointer to the binary data\n  @param Length then length of the binary Data\n  @param ODBC a boolean if output result should be with a starting 0x...\n  @returns a valid hex formated unicode-safe string\n}\n\nfunction GetSQLHexWideString(Value: PAnsiChar; Len: Integer; ODBC: Boolean = False): ZWideString;\nvar\n  HexVal: AnsiString;\nbegin\n  SetLength(HexVal,Len * 2 );\n  BinToHex(Value, PAnsiChar(HexVal), Len);\n\n  if ODBC then\n    Result := '0x'+ZWideString(HexVal)\n  else\n    Result := 'x'#39+ZWideString(HexVal)+#39;\nend;\n\nfunction GetSQLHexAnsiString(Value: PAnsiChar; Len: Integer; ODBC: Boolean = False): RawByteString;\nvar\n  HexVal: RawByteString;\nbegin\n  SetLength(HexVal,Len * 2 );\n  BinToHex(Value, PAnsiChar(HexVal), Len);\n\n  if ODBC then\n    Result := '0x'+HexVal\n  else\n    Result := 'x'#39+HexVal+#39;\nend;\n\nfunction GetSQLHexString(Value: PAnsiChar; Len: Integer; ODBC: Boolean = False): String;\nbegin\n  {$IFDEF UNICODE}\n  Result := GetSQLHexWideString(Value, Len, ODBC);\n  {$ELSE}\n  Result := GetSQLHexAnsiString(Value, Len, ODBC);\n  {$ENDIF}\nend;\n\n{**\n  Returns a FieldSize in Bytes dependend to the FieldType and CharWidth\n  @param <code>TZSQLType</code> the Zeos FieldType\n  @param <code>Integer</code> the Current given FieldLength\n  @param <code>Integer</code> the Current CountOfByte/Char\n  @param <code>Boolean</code> does the Driver returns the FullSizeInBytes\n  @returns <code>Integer</code> the count of AnsiChars for Field.Size * SizeOf(Char)\n}\nfunction GetFieldSize(const SQLType: TZSQLType; ConSettings: PZConSettings;\n  const Precision, CharWidth: Integer; DisplaySize: PInteger = nil;\n    SizeInBytes: Boolean = False): Integer;\nvar\n  TempPrecision: Integer;\nbegin\n  if ( SQLType in [stString, stUnicodeString] ) and ( Precision <> 0 )then\n  begin\n    if SizeInBytes then\n      TempPrecision := Precision div CharWidth\n    else\n      TempPrecision := Precision;\n\n    if Assigned(DisplaySize) then\n      DisplaySize^ := TempPrecision;\n\n    if SQLType = stString then\n      //the RowAccessor assumes SizeOf(Char)*Precision+SizeOf(Char)\n      //the Field assumes Precision*SizeOf(Char)\n      {$IFDEF UNICODE}\n      if ConSettings.ClientCodePage.CharWidth >= 2 then //All others > 3 are UTF8\n        Result := TempPrecision * 2 //add more mem for a reserved thirt byte\n      else //two and one byte AnsiChars are one WideChar\n        Result := TempPrecision\n      {$ELSE}\n        if ( ConSettings.CPType = cCP_UTF8 ) or (ConSettings.CTRL_CP = zCP_UTF8) then\n          Result := TempPrecision * 4\n        else\n          Result := TempPrecision * CharWidth\n      {$ENDIF}\n    else //stUnicodeString\n      //UTF8 can pickup LittleEndian/BigEndian 4 Byte Chars\n      //the RowAccessor assumes 2*Precision+2!\n      //the Field assumes 2*Precision ??Does it?\n      if CharWidth > 2 then\n        Result := TempPrecision * 2\n      else\n        Result := TempPrecision;\n  end\n  else\n    Result := Precision;\nend;\n\nfunction WideStringStream(const AString: WideString): TStream;\nbegin\n  Result := TMemoryStream.Create;\n  Result.Write(PWideChar(AString)^, Length(AString)*2);\n  Result.Position := 0;\nend;\n\n\nend.\n\n"
  },
  {
    "path": "lib/zeosdbo/src/parsesql/ZAdoToken.pas",
    "content": "{*********************************************************}\n{                                                         }\n{                 Zeos Database Objects                   }\n{           String tokenizing classes for MySQL           }\n{                                                         }\n{         Originally written by Sergey Seroukhov          }\n{                                                         }\n{*********************************************************}\n\n{@********************************************************}\n{    Copyright (c) 1999-2012 Zeos Development Group       }\n{                                                         }\n{ License Agreement:                                      }\n{                                                         }\n{ This library is distributed in the hope that it will be }\n{ useful, but WITHOUT ANY WARRANTY; without even the      }\n{ implied warranty of MERCHANTABILITY or FITNESS FOR      }\n{ A PARTICULAR PURPOSE.  See the GNU Lesser General       }\n{ Public License for more details.                        }\n{                                                         }\n{ The source code of the ZEOS Libraries and packages are  }\n{ distributed under the Library GNU General Public        }\n{ License (see the file COPYING / COPYING.ZEOS)           }\n{ with the following  modification:                       }\n{ As a special exception, the copyright holders of this   }\n{ library give you permission to link this library with   }\n{ independent modules to produce an executable,           }\n{ regardless of the license terms of these independent    }\n{ modules, and to copy and distribute the resulting       }\n{ executable under terms of your choice, provided that    }\n{ you also meet, for each linked independent module,      }\n{ the terms and conditions of the license of that module. }\n{ An independent module is a module which is not derived  }\n{ from or based on this library. If you modify this       }\n{ library, you may extend this exception to your version  }\n{ of the library, but you are not obligated to do so.     }\n{ If you do not wish to do so, delete this exception      }\n{ statement from your version.                            }\n{                                                         }\n{                                                         }\n{ The project web site is located on:                     }\n{   http://zeos.firmos.at  (FORUM)                        }\n{   http://sourceforge.net/p/zeoslib/tickets/ (BUGTRACKER)}\n{   svn://svn.code.sf.net/p/zeoslib/code-0/trunk (SVN)    }\n{                                                         }\n{   http://www.sourceforge.net/projects/zeoslib.          }\n{                                                         }\n{                                                         }\n{                                 Zeos Development Group. }\n{********************************************************@}\n\nunit ZAdoToken;\n\ninterface\n\n{$I ZParseSql.inc}\n\nuses\n  Classes, SysUtils, ZTokenizer, ZGenericSqlToken, ZCompatibility;\n\ntype\n  {** Implements a quote string state object. }\n  TZAdoSQLQuoteState = class (TZQuoteState)\n  public\n    function NextToken(Stream: TStream; FirstChar: Char;\n      Tokenizer: TZTokenizer): TZToken; override;\n\n    function EncodeString(const Value: string; QuoteChar: Char): string; override;\n    function DecodeString(const Value: string; QuoteChar: Char): string; override;\n  end;\n\n  {** Implements a default tokenizer object. }\n  TZAdoSQLTokenizer = class (TZGenericSQLTokenizer)\n  public\n    constructor Create;\n  end;\n\nimplementation\n\n{ TZAdoSQLQuoteState }\n\n{**\n  Return a quoted string token from a reader. This method\n  will collect characters until it sees a match to the\n  character that the tokenizer used to switch to this state.\n\n  @return a quoted string token from a reader\n}\nfunction TZAdoSQLQuoteState.NextToken(Stream: TStream; FirstChar: Char;\n  Tokenizer: TZTokenizer): TZToken;\nvar\n  ReadChar: Char;\n  LastChar: Char;\nbegin\n  Result.Value := FirstChar;\n  LastChar := #0;\n  while Stream.Read(ReadChar, SizeOf(Char)) > 0 do\n  begin\n    if ((LastChar = FirstChar) and (ReadChar <> FirstChar)\n      and (FirstChar <> '[')) or ((FirstChar = '[') and (LastChar = ']')) then\n    begin\n      Stream.Seek(-SizeOf(Char), soFromCurrent);\n      Break;\n    end;\n    Result.Value := Result.Value + ReadChar;\n    if (LastChar = FirstChar) and (ReadChar = FirstChar) then\n      LastChar := #0\n    else LastChar := ReadChar;\n  end;\n\n  if CharInSet(FirstChar, ['\"', '[']) then\n    Result.TokenType := ttQuotedIdentifier\n  else Result.TokenType := ttQuoted;\nend;\n\n{**\n  Encodes a string value.\n  @param Value a string value to be encoded.\n  @param QuoteChar a string quote character.\n  @returns an encoded string.\n}\nfunction TZAdoSQLQuoteState.EncodeString(const Value: string; QuoteChar: Char): string;\nbegin\n  if QuoteChar = '[' then\n    Result := '[' + Value + ']'\n  else if CharInSet(QuoteChar, [#39, '\"']) then\n    Result := QuoteChar + Value + QuoteChar\n  else Result := Value;\nend;\n\n{**\n  Decodes a string value.\n  @param Value a string value to be decoded.\n  @param QuoteChar a string quote character.\n  @returns an decoded string.\n}\nfunction TZAdoSQLQuoteState.DecodeString(const Value: string; QuoteChar: Char): string;\nbegin\n  Result := Value;\n  if Length(Value) >= 2 then\n  begin\n    if CharInSet(QuoteChar, [#39, '\"']) and (Value[1] = QuoteChar)\n      and (Value[Length(Value)] = QuoteChar) then\n    begin\n      if Length(Value) > 2 then\n        Result := AnsiDequotedStr(Value, QuoteChar)\n      else Result := '';\n    end\n    else if (QuoteChar = '[') and (Value[1] = QuoteChar)\n      and (Value[Length(Value)] = ']') then\n      Result := Copy(Value, 2, Length(Value) - 2)\n  end;\nend;\n\n\n{ TZAdoSQLTokenizer }\n{**\n  Constructs a tokenizer with a default state table (as\n  described in the class comment).\n}\nconstructor TZAdoSQLTokenizer.Create;\nbegin\n  EscapeState := TZEscapeState.Create;\n  NumberState := TZNumberState.Create;\n  QuoteState := TZAdoSQLQuoteState.Create;\n  WhitespaceState := TZWhitespaceState.Create;\n  CommentState := TZCppCommentState.Create;\n\n  SymbolState := TZGenericSQLSymbolState.Create;\n  WordState := TZGenericSQLWordState.Create;\n\n  SetCharacterState(#0, #32, WhitespaceState);\n  SetCharacterState(#33, #191, SymbolState);\n  SetCharacterState(#192, High(Char), WordState);\n\n  SetCharacterState('a', 'z', WordState);\n  SetCharacterState('A', 'Z', WordState);\n  SetCharacterState('_', '_', WordState);\n  SetCharacterState('$', '$', WordState);\n  SetCharacterState('@', '@', WordState);\n\n  SetCharacterState('0', '9', NumberState);\n  SetCharacterState('.', '.', NumberState);\n\n  SetCharacterState('\"', '\"', QuoteState);\n  SetCharacterState(#39, #39, QuoteState);\n  SetCharacterState('[', '[', QuoteState);\n  SetCharacterState(']', ']', QuoteState);\n\n  SetCharacterState('/', '/', CommentState);\n\nend;\n\nend.\n"
  },
  {
    "path": "lib/zeosdbo/src/parsesql/ZGenericSqlAnalyser.pas",
    "content": "{*********************************************************}\n{                                                         }\n{                 Zeos Database Objects                   }\n{            SQL Statements Analysing classes             }\n{                                                         }\n{          Originally written by Sergey Seroukhov         }\n{                                                         }\n{*********************************************************}\n\n{@********************************************************}\n{    Copyright (c) 1999-2012 Zeos Development Group       }\n{                                                         }\n{ License Agreement:                                      }\n{                                                         }\n{ This library is distributed in the hope that it will be }\n{ useful, but WITHOUT ANY WARRANTY; without even the      }\n{ implied warranty of MERCHANTABILITY or FITNESS FOR      }\n{ A PARTICULAR PURPOSE.  See the GNU Lesser General       }\n{ Public License for more details.                        }\n{                                                         }\n{ The source code of the ZEOS Libraries and packages are  }\n{ distributed under the Library GNU General Public        }\n{ License (see the file COPYING / COPYING.ZEOS)           }\n{ with the following  modification:                       }\n{ As a special exception, the copyright holders of this   }\n{ library give you permission to link this library with   }\n{ independent modules to produce an executable,           }\n{ regardless of the license terms of these independent    }\n{ modules, and to copy and distribute the resulting       }\n{ executable under terms of your choice, provided that    }\n{ you also meet, for each linked independent module,      }\n{ the terms and conditions of the license of that module. }\n{ An independent module is a module which is not derived  }\n{ from or based on this library. If you modify this       }\n{ library, you may extend this exception to your version  }\n{ of the library, but you are not obligated to do so.     }\n{ If you do not wish to do so, delete this exception      }\n{ statement from your version.                            }\n{                                                         }\n{                                                         }\n{ The project web site is located on:                     }\n{   http://zeos.firmos.at  (FORUM)                        }\n{   http://sourceforge.net/p/zeoslib/tickets/ (BUGTRACKER)}\n{   svn://svn.code.sf.net/p/zeoslib/code-0/trunk (SVN)    }\n{                                                         }\n{   http://www.sourceforge.net/projects/zeoslib.          }\n{                                                         }\n{                                                         }\n{                                 Zeos Development Group. }\n{********************************************************@}\n\nunit ZGenericSqlAnalyser;\n\ninterface\n\n{$I ZParseSql.inc}\n\nuses Classes, {$IFDEF MSEgui}mclasses,{$ENDIF} Contnrs,\n  ZClasses, ZTokenizer, ZSelectSchema, ZCompatibility;\n\ntype\n\n  {** Implements a section of the parsed SQL statement. }\n  TZStatementSection = class (TObject)\n  private\n    FName: string;\n    FTokens: TStrings;\n  public\n    constructor Create(const Name: string; Tokens: TStrings);\n    destructor Destroy; override;\n\n    function Clone: TZStatementSection;\n\n    property Name: string read FName write FName;\n    property Tokens: TStrings read FTokens;\n  end;\n\n  {** Implements a publicly available interface to statement analyser. }\n  IZStatementAnalyser = interface(IZInterface)\n    ['{967635B6-411B-4DEF-990C-9C6C01F3DC0A}']\n\n    function TokenizeQuery(Tokenizer: IZTokenizer; const SQL: string;\n      Cleanup: Boolean): TStrings;\n    function SplitSections(Tokens: TStrings): TObjectList;\n\n    function ComposeTokens(Tokens: TStrings): string;\n    function ComposeSections(Sections: TObjectList): string;\n\n    function DefineSelectSchemaFromSections(\n      Sections: TObjectList): IZSelectSchema;\n    function DefineSelectSchemaFromQuery(Tokenizer: IZTokenizer;\n      const SQL: string): IZSelectSchema;\n  end;\n\n  {** Implements an SQL statements analyser. }\n  TZGenericStatementAnalyser = class (TZAbstractObject, IZStatementAnalyser)\n  private\n    FSectionNames: TStrings;\n    FSelectOptions: TStrings;\n    FFromJoins: TStrings;\n    FFromClauses: TStrings;\n  protected\n    function ArrayToStrings(const Value: array of string): TStrings;\n    function CheckForKeyword(Tokens: TStrings; TokenIndex: Integer;\n      Keywords: TStrings; var Keyword: string; var WordCount: Integer): Boolean;\n    function FindSectionTokens(Sections: TObjectList; const Name: string): TStrings;\n\n    procedure FillFieldRefs(SelectSchema: IZSelectSchema; SelectTokens: TStrings);\n    procedure FillTableRefs(SelectSchema: IZSelectSchema; FromTokens: TStrings);\n\n    function SkipOptionTokens(Tokens: TStrings; var TokenIndex: Integer;\n      Options: TStrings): Boolean;\n    function SkipBracketTokens(Tokens: TStrings; var TokenIndex: Integer):\n      Boolean;\n\n    property SectionNames: TStrings read FSectionNames write FSectionNames;\n    property SelectOptions: TStrings read FSelectOptions write FSelectOptions;\n    property FromJoins: TStrings read FFromJoins write FFromJoins;\n    property FromClauses: TStrings read FFromClauses write FFromClauses;\n  public\n    constructor Create;\n    destructor Destroy; override;\n\n    function TokenizeQuery(Tokenizer: IZTokenizer; const SQL: string;\n      Cleanup: Boolean): TStrings;\n    function SplitSections(Tokens: TStrings): TObjectList;\n\n    function ComposeTokens(Tokens: TStrings): string;\n    function ComposeSections(Sections: TObjectList): string;\n\n    function DefineSelectSchemaFromSections(\n      Sections: TObjectList): IZSelectSchema;\n    function DefineSelectSchemaFromQuery(Tokenizer: IZTokenizer; const SQL: string):\n      IZSelectSchema;\n  end;\n\nimplementation\n\nuses SysUtils, ZSysUtils;\n\n{ TZStatementSection }\n\n{**\n  Create SQL statement section object.\n}\nconstructor TZStatementSection.Create(const Name: string; Tokens: TStrings);\nbegin\n  FName := Name;\n  FTokens := Tokens;\nend;\n\n{**\n  Destroys this object and cleanups the memory.\n}\ndestructor TZStatementSection.Destroy;\nbegin\n  FTokens.Free;\n  inherited Destroy;\nend;\n\n{**\n  Clones an object instance.\n  @return a clonned object instance.\n}\nfunction TZStatementSection.Clone: TZStatementSection;\nvar\n  Temp: TStrings;\nbegin\n  Temp := TStringList.Create;\n  Temp.AddStrings(FTokens);\n  Result := TZStatementSection.Create(FName, Temp);\nend;\n\nconst\n  {** The generic constants.}\n  GenericSectionNames: array[0..12] of string = (\n    'SELECT', 'UPDATE', 'DELETE', 'INSERT', 'FROM',\n    'WHERE', 'INTO', 'GROUP*BY', 'HAVING', 'ORDER*BY',\n    'FOR*UPDATE', 'LIMIT', 'OFFSET'\n  );\n  GenericSelectOptions: array[0..1] of string = (\n    'DISTINCT', 'ALL'\n  );\n  GenericFromJoins: array[0..5] of string = (\n    'NATURAL', 'RIGHT', 'LEFT', 'INNER', 'OUTER', 'JOIN'\n  );\n  GenericFromClauses: array[0..0] of string = (\n    'ON'\n  );\n\n{ TZGenericStatementAnalyser }\n\n{**\n  Creates the object and assignes the main properties.\n}\nconstructor TZGenericStatementAnalyser.Create;\nbegin\n  FSectionNames := ArrayToStrings(GenericSectionNames);\n  FSelectOptions := ArrayToStrings(GenericSelectOptions);\n  FFromJoins := ArrayToStrings(GenericFromJoins);\n  FFromClauses := ArrayToStrings(GenericFromClauses);\nend;\n\n{**\n  Destroys this object and cleanups the memory.\n}\ndestructor TZGenericStatementAnalyser.Destroy;\nbegin\n  FSectionNames.Free;\n  FSelectOptions.Free;\n  FFromJoins.Free;\n  FFromClauses.Free;\n  inherited Destroy;\nend;\n\n{**\n  Converts an array of strings into TStrings object.\n  @param Value an array of strings to be converted.\n  @return a TStrings object with specified strings.\n}\nfunction TZGenericStatementAnalyser.ArrayToStrings(\n  const Value: array of string): TStrings;\nvar\n  I: Integer;\nbegin\n  Result := TStringList.Create;\n  for I := Low(Value) to High(Value) do\n    Result.Add(Value[I]);\nend;\n\n{**\n  Checks for keyword with one, two or three consisted words in the list\n  @param Tokens a list or tokens\n  @param TokenIndex an index of the current token\n  @param Keywords a list of keywords (in uppers case delimited with '*')\n  @param Keyword an out parameter with found keyword.\n  @param WordCount a count of words in the found keyword.\n}\nfunction TZGenericStatementAnalyser.CheckForKeyword(Tokens: TStrings;\n  TokenIndex: Integer; Keywords: TStrings; var Keyword: string;\n  var WordCount: Integer): Boolean;\nvar\n  I: Integer;\nbegin\n  WordCount := 0;\n  Keyword := '';\n  Result := False;\n\n  for I := 1 to 3 do\n  begin\n    if (Tokens.Count <= TokenIndex) then\n      Break;\n    if TZTokenType({$IFDEF FPC}Pointer({$ENDIF}\n      Tokens.Objects[TokenIndex]{$IFDEF FPC}){$ENDIF}) <> ttWord then\n      Break;\n    if Keyword <> '' then\n      Keyword := Keyword + '*';\n    Keyword := Keyword + AnsiUpperCase(Tokens[TokenIndex]);\n    Inc(WordCount);\n    if Keywords.IndexOf(Keyword) >= 0 then\n    begin\n      Result := True;\n      Break;\n    end;\n    Inc(TokenIndex);\n    { Skips whitespaces. }\n    while Tokens.Count > TokenIndex do\n    begin\n      if not (TZTokenType({$IFDEF FPC}Pointer({$ENDIF}\n        Tokens.Objects[TokenIndex]{$IFDEF FPC}){$ENDIF})\n        in [ttWhitespace, ttComment]) then\n        Break;\n      Inc(TokenIndex);\n      Inc(WordCount);\n    end;\n  end;\n\n  if not Result then\n  begin\n    WordCount := 0;\n    Keyword := '';\n  end;\nend;\n\n{**\n  Finds a section by it's name.\n  @param Sections a list of sections.\n  @param Name a name of the section to be found.\n  @return a list of section tokens or <code>null</code>\n    if section is was not found.\n}\nfunction TZGenericStatementAnalyser.FindSectionTokens(\n  Sections: TObjectList; const Name: string): TStrings;\nvar\n  I: Integer;\n  Current: TZStatementSection;\nbegin\n  Result := nil;\n  for I := 0 to Sections.Count - 1 do\n  begin\n    Current := TZStatementSection(Sections[I]);\n    if Current.Name = Name then\n    begin\n      Result := Current.Tokens;\n      Break;\n    end;\n  end;\nend;\n\n{**\n  Tokenizes a given SQL query into a list of tokens with tokenizer.\n  @param Tokenizer a tokenizer object.\n  @param SQL a SQL query to be tokenized.\n  @return a list with tokens.\n}\nfunction TZGenericStatementAnalyser.TokenizeQuery(\n  Tokenizer: IZTokenizer; const SQL: string; Cleanup: Boolean): TStrings;\nbegin\n  if Cleanup then\n  begin\n    Result := Tokenizer.TokenizeBufferToList(SQL,\n      [toSkipEOF, toSkipComments, toUnifyWhitespaces])\n  end else\n    Result := Tokenizer.TokenizeBufferToList(SQL, [toSkipEOF]);\nend;\n\n{**\n  Splits a given list of tokens into the list named sections.\n  @param Tokens a list of tokens.\n  @return a list of section names where object property contains\n    a list of tokens in the section. It initial list is not started\n    with a section name the first section is unnamed ('').\n}\nfunction TZGenericStatementAnalyser.SplitSections(Tokens: TStrings): TObjectList;\nvar\n  I: Integer;\n  Keyword: string;\n  WordCount: Integer;\n  TokenIndex: Integer;\n  Elements: TStrings;\n  FoundSection: Boolean;\n  BracketCount: Integer;\nbegin\n  Result := TObjectList.Create;\n  TokenIndex := 0;\n  FoundSection := True;\n  Elements := nil;\n  CheckForKeyword(Tokens, TokenIndex, SectionNames, Keyword, WordCount);\n\n  while TokenIndex < Tokens.Count do\n  begin\n    if FoundSection then\n    begin\n      Elements := TStringList.Create;\n      for I := 0 to WordCount - 1 do\n      begin\n        Elements.AddObject(Tokens[TokenIndex + I],\n          Tokens.Objects[TokenIndex + I]);\n      end;\n      Inc(TokenIndex, WordCount);\n      Result.Add(TZStatementSection.Create(Keyword, Elements));\n    end;\n    FoundSection := CheckForKeyword(Tokens, TokenIndex, SectionNames,\n      Keyword, WordCount);\n    if not FoundSection and (TokenIndex < Tokens.Count) then\n    begin\n      BracketCount := 0;\n      repeat\n        Elements.AddObject(Tokens[TokenIndex], Tokens.Objects[TokenIndex]);\n        if Tokens[TokenIndex] = '(' then\n          Inc(BracketCount)\n        else if Tokens[TokenIndex] = ')' then\n          Dec(BracketCount);\n        Inc(TokenIndex);\n      until (BracketCount <= 0) or (TokenIndex >= Tokens.Count);\n    end;\n  end;\nend;\n\n{**\n  Composes a string from the list of tokens.\n  @param Tokens a list of tokens.\n  @returns a composes string.\n}\nfunction TZGenericStatementAnalyser.ComposeTokens(Tokens: TStrings): string;\nbegin\n  Result := ComposeString(Tokens, '');\nend;\n\n{**\n  Composes a string from the list of statement sections.\n  @param Tokens a list of statement sections.\n  @returns a composes string.\n}\nfunction TZGenericStatementAnalyser.ComposeSections(Sections: TObjectList): string;\nvar\n  I: Integer;\nbegin\n  Result := '';\n  for I := 0 to Sections.Count - 1 do\n    Result := Result + ComposeTokens(TZStatementSection(Sections[I]).Tokens);\nend;\n\n{**\n  Skips tokens inside brackets.\n  @param Tokens a list of tokens to scan.\n  @param TokenIndex the index of the current token.\n  @return <code>true</code> if some tokens were skipped.\n}\nfunction TZGenericStatementAnalyser.SkipBracketTokens(Tokens: TStrings;\n  var TokenIndex: Integer): Boolean;\nvar\n  BracketCount: Integer;\n  Current: string;\nbegin\n  { Checks for the start bracket. }\n  if (TokenIndex < Tokens.Count) and (Tokens[TokenIndex] <> '(') then\n  begin\n    Result := False;\n    Exit;\n  end;\n\n  { Skips the expression in brackets. }\n  Result := True;\n  BracketCount := 1;\n  Inc(TokenIndex);\n  while (TokenIndex < Tokens.Count) and (BracketCount > 0) do\n  begin\n    Current := Tokens[TokenIndex];\n    if Current = '(' then\n      Inc(BracketCount)\n    else if Current = ')' then\n      Dec(BracketCount);\n    Inc(TokenIndex);\n  end;\nend;\n\n{**\n  Skips option tokens specified in the string list.\n  @param Tokens a list of tokens to scan.\n  @param TokenIndex the index of the current token.\n  @param Options a list of option keyword strings in the upper case.\n  @return <code>true</code> if some tokens were skipped.\n}\nfunction TZGenericStatementAnalyser.SkipOptionTokens(Tokens: TStrings;\n  var TokenIndex: Integer; Options: TStrings): Boolean;\nbegin\n  Result := False;\n  while TokenIndex < Tokens.Count do\n  begin\n    if not (TZTokenType({$IFDEF FPC}Pointer({$ENDIF}\n      Tokens.Objects[TokenIndex]{$IFDEF FPC}){$ENDIF})\n      in [ttWhitespace, ttComment])\n      and (Options.IndexOf(AnsiUpperCase(Tokens[TokenIndex])) < 0) then\n    begin\n      Break;\n    end;\n    Inc(TokenIndex);\n    Result := True;\n  end;\nend;\n\n{**\n  Fills select schema with field references.\n  @param SelectSchema a select schema object.\n  @param SelectTokens a list of tokens in select section.\n}\nprocedure TZGenericStatementAnalyser.FillFieldRefs(\n  SelectSchema: IZSelectSchema; SelectTokens: TStrings);\nvar\n  TokenIndex: Integer;\n  Catalog: string;\n  Schema: string;\n  Table: string;\n  Field: string;\n  Alias: string;\n  CurrentValue: string;\n  CurrentType: TZTokenType;\n  CurrentUpper: string;\n  ReadField: Boolean;\n  HadWhitespace : Boolean;\n  LastWasBracketSection: Boolean;\n  CurrentUpperIs_AS: Boolean; //place holder to avoid compare the token twice\n\n  procedure ClearElements;\n  begin\n    Catalog := '';\n    Schema := '';\n    Table := '';\n    Field := '';\n    Alias := '';\n    ReadField := True;\n    LastWasBracketSection := False;\n  end;\n\n  { improve fail of fieldname detection if whitespaces and non ttWord or ttQuotedIdentifier previously detected\n    f.e.: select first 100 skip 10 field1, field2}\n  function CheckNextTokenForCommaAndWhiteSpaces: Boolean;\n  var\n    CurrentValue: string;\n    CurrentType: TZTokenType;\n    I: Integer;\n  begin\n    Result := False;\n    I := 1;\n    //Check to right side to avoid wrong alias detection\n    while SelectTokens.Count > TokenIndex +i do\n    begin\n      CurrentValue := SelectTokens[TokenIndex+i];\n      CurrentType := TZTokenType({$IFDEF FPC}Pointer({$ENDIF}\n        SelectTokens.Objects[TokenIndex+i]{$IFDEF FPC}){$ENDIF});\n      if CurrentType in [ttWhiteSpace, ttSymbol] then\n      begin\n        if (CurrentValue = ',') then\n        begin\n          Result := True;\n          Break;\n        end;\n      end\n      else\n        break;\n      Inc(i);\n    end;\n\n    if Result then\n    begin\n      i := 1;\n      while Tokenindex - i > 0 do\n        if TZTokenType({$IFDEF FPC}Pointer({$ENDIF}\n            SelectTokens.Objects[TokenIndex-i]{$IFDEF FPC}){$ENDIF}) = ttWhiteSpace then\n          Inc(i)\n        else\n          Break;\n      Result := Result and (TokenIndex - I > 0) and\n          not ( TZTokenType({$IFDEF FPC}Pointer({$ENDIF}\n        SelectTokens.Objects[TokenIndex-i]{$IFDEF FPC}){$ENDIF}) = ttWord );\n    end;\n  end;\n\nbegin\n  TokenIndex := 1;\n  SkipOptionTokens(SelectTokens, TokenIndex, Self.SelectOptions);\n\n  ClearElements;\n  while TokenIndex < SelectTokens.Count do\n  begin\n    CurrentValue := SelectTokens[TokenIndex];\n    CurrentUpper := AnsiUpperCase(CurrentValue);\n    CurrentType := TZTokenType({$IFDEF FPC}Pointer({$ENDIF}\n      SelectTokens.Objects[TokenIndex]{$IFDEF FPC}){$ENDIF});\n\n    { Switches to alias part. }\n    CurrentUpperIs_AS := (CurrentUpper = 'AS');\n    if (CurrentType = ttWhitespace) or CurrentUpperIs_AS then\n      ReadField := ReadField and (Field = '') and not CurrentUpperIs_AS\n    { Reads field. }\n    else if ReadField and ((CurrentType = ttWord) or (CurrentType = ttQuotedIdentifier) or\n      (CurrentValue = '*')) then\n    begin\n      Catalog := Schema;\n      Schema := Table;\n      Table := Field;\n      Field := CurrentValue;\n    end\n    { Skips a '.' in field part. }\n    else if ReadField and (CurrentValue = '.') then\n    begin\n    end\n    { Reads alias. }\n    else if not ReadField and (CurrentType in [ttWord, ttQuotedIdentifier]) then\n      Alias := CurrentValue\n    { Ends field reading. }\n    else if CurrentValue = ',' then\n    begin\n      if Field <> '' then\n        SelectSchema.AddField(TZFieldRef.Create(True, Catalog, Schema, Table,\n          Field, Alias, nil));\n      ClearElements;\n    end\n    { Skips till the next field. }\n    else\n    begin\n      ClearElements;\n      HadWhitespace := False;\n      while (TokenIndex < SelectTokens.Count) and (CurrentValue <> ',') do\n      begin\n        CurrentValue := SelectTokens[TokenIndex];\n        if CurrentValue = '(' then\n        begin\n          SkipBracketTokens(SelectTokens, TokenIndex);\n          LastWasBracketSection := True;\n        end\n        else begin\n          CurrentType := TZTokenType({$IFDEF FPC}Pointer({$ENDIF}\n            SelectTokens.Objects[TokenIndex]{$IFDEF FPC}){$ENDIF});\n          if HadWhitespace and (CurrentType in [ttWord, ttQuotedIdentifier]) then\n            if not LastWasBracketSection and CheckNextTokenForCommaAndWhiteSpaces then\n              Break\n            else\n              Alias := CurrentValue\n          else if not (CurrentType in [ttWhitespace, ttComment])\n            and (CurrentValue <> ',') then\n              Alias := ''\n          else if CurrentType = ttWhitespace then\n              HadWhitespace := true;\n          Inc(TokenIndex);\n        end;\n      end;\n      if Alias <> '' then\n      begin\n        SelectSchema.AddField(TZFieldRef.Create(False, '', '', '', '', Alias, nil));\n        ClearElements;\n      end;\n      Dec(TokenIndex); // go back 1 token(Because of Inc in next lines)\n    end;\n    Inc(TokenIndex);\n  end;\n\n  { Creates a reference to the last processed field. }\n  if Field <> '' then\n  begin\n    SelectSchema.AddField(TZFieldRef.Create(True, Catalog, Schema, Table,\n      Field, Alias, nil));\n  end;\nend;\n\n{**\n  Fills select schema with table references.\n  @param SelectSchema a select schema object.\n  @param FromTokens a list of tokens in from section.\n}\n{$HINTS OFF}\nprocedure TZGenericStatementAnalyser.FillTableRefs(\n  SelectSchema: IZSelectSchema; FromTokens: TStrings);\nvar\n  TokenIndex: Integer;\n  Catalog: string;\n  Schema: string;\n  Table: string;\n  Alias: string;\n  CurrentValue: string;\n  CurrentType: TZTokenType;\n  CurrentUpper: string;\n  ReadTable: Boolean;\n\n  procedure ClearElements;\n  begin\n    Catalog := '';\n    Schema := '';\n    Table := '';\n    Alias := '';\n    ReadTable := True;\n  end;\n\nbegin\n  TokenIndex := 1;\n\n  ClearElements;\n  while TokenIndex < FromTokens.Count do\n  begin\n    CurrentValue := FromTokens[TokenIndex];\n    CurrentUpper := AnsiUpperCase(CurrentValue);\n    CurrentType := TZTokenType({$IFDEF FPC}Pointer({$ENDIF}\n      FromTokens.Objects[TokenIndex]{$IFDEF FPC}){$ENDIF});\n\n    { Processes from join keywords. }\n    if FromJoins.IndexOf(CurrentUpper) >= 0 then\n    begin\n      if Table <> '' then\n        SelectSchema.AddTable(TZTableRef.Create(Catalog, Schema, Table, Alias));\n      ClearElements;\n      SkipOptionTokens(FromTokens, TokenIndex, FromJoins);\n      Continue;\n    end\n    { Skips from clause keywords. }\n    else if FromClauses.IndexOf(CurrentUpper) >= 0 then\n    begin\n      Inc(TokenIndex);\n      CurrentValue := FromTokens[TokenIndex];\n      CurrentUpper := AnsiUpperCase(CurrentValue);\n      while (TokenIndex < FromTokens.Count)\n        and (FromJoins.IndexOf(CurrentUpper) < 0) and (CurrentUpper <> ',') do\n      begin\n        if CurrentUpper = '(' then\n            SkipBracketTokens(FromTokens, TokenIndex)\n        else Inc(TokenIndex);\n        if TokenIndex < FromTokens.Count then\n          begin\n            CurrentValue := FromTokens[TokenIndex];\n            CurrentUpper := AnsiUpperCase(CurrentValue);\n            CurrentType := TZTokenType({$IFDEF FPC}Pointer({$ENDIF}\n              FromTokens.Objects[TokenIndex]{$IFDEF FPC}){$ENDIF});\n          end;\n      end;\n      // We must jump 1 tokens back now when we stopped on a Join clause.\n      // Otherwise the next table is skipped\n      if FromJoins.IndexOf(CurrentUpper) >= 0 then\n        begin\n          Dec(TokenIndex);\n          CurrentValue := FromTokens[TokenIndex];\n          CurrentUpper := AnsiUpperCase(CurrentValue);\n        end;\n    end\n    { Switches to alias part. }\n    else if (CurrentType = ttWhitespace) or (CurrentUpper = 'AS') then\n    begin\n      ReadTable := ReadTable and (Table = '') and (CurrentUpper <> 'AS');\n    end\n    { Reads table. }\n    else if ReadTable and ((CurrentType = ttWord) or (CurrentType = ttQuotedIdentifier)) then\n    begin\n      {Catalog := Schema;\n      Schema := Table;}\n      Table := CurrentValue;\n    end\n    { Skips a '.' in table part. }\n    else if ReadTable and (CurrentValue = '.') then\n    begin\n      Catalog := Schema;\n      Schema := Table;\n      Table := '';\n    end\n    { Reads alias. }\n    else if not ReadTable and (CurrentType = ttWord) then\n    begin\n      Alias := CurrentValue;\n    end;\n    { Ends field reading. }\n    if CurrentValue = ',' then\n    begin\n      if Table <> '' then\n        SelectSchema.AddTable(TZTableRef.Create(Catalog, Schema, Table, Alias));\n      ClearElements;\n    end;\n    { Skips till the next field. }\n    if CurrentValue = '(' then\n      SkipBracketTokens(FromTokens, TokenIndex)\n    else Inc(TokenIndex);\n  end;\n\n  { Creates a reference to the last processed field. }\n  if Table <> '' then\n    SelectSchema.AddTable(TZTableRef.Create(Catalog, Schema, Table, Alias));\nend;\n{$HINTS ON}\n{**\n  Extracts a select schema from the specified parsed select statement.\n  @param Sections a list of sections.\n  @return a select statement schema.\n}\nfunction TZGenericStatementAnalyser.DefineSelectSchemaFromSections(\n  Sections: TObjectList): IZSelectSchema;\nvar\n  SelectTokens: TStrings;\n  FromTokens: TStrings;\nbegin\n  Result := nil;\n  { Checks for the correct select statement. }\n  if (Sections.Count < 2)\n    or not ((TZStatementSection(Sections[0]).Name = 'SELECT')\n    or ((TZStatementSection(Sections[0]).Name = '')\n    and (TZStatementSection(Sections[1]).Name = 'SELECT'))) then\n    Exit;\n\n  { Defins sections. }\n  SelectTokens := FindSectionTokens(Sections, 'SELECT');\n  FromTokens := FindSectionTokens(Sections, 'FROM');\n  if (SelectTokens = nil) or (FromTokens = nil) then\n    Exit;\n\n  { Creates and fills the result object. }\n  Result := TZSelectSchema.Create;\n  FillFieldRefs(Result, SelectTokens);\n  FillTableRefs(Result, FromTokens);\nend;\n\n{**\n  Defines a select schema from the specified SQL query.\n  @param Tokenizer a tokenizer object.\n  @param SQL a SQL query.\n  @return a select statement schema.\n}\nfunction TZGenericStatementAnalyser.DefineSelectSchemaFromQuery(\n  Tokenizer: IZTokenizer; const SQL: string): IZSelectSchema;\nvar\n  Tokens: TStrings;\n  Sections: TObjectList;\nbegin\n  Tokens := TokenizeQuery(Tokenizer, SQL, True);\n  Sections := SplitSections(Tokens);\n  try\n    Result := DefineSelectSchemaFromSections(Sections);\n  finally\n    Tokens.Free;\n    Sections.Free;\n  end;\nend;\n\nend.\n\n"
  },
  {
    "path": "lib/zeosdbo/src/parsesql/ZGenericSqlToken.pas",
    "content": "{*********************************************************}\n{                                                         }\n{                 Zeos Database Objects                   }\n{       String tokenizing classes for Generic SQL         }\n{                                                         }\n{       Originally written by Sergey Seroukhov            }\n{                                                         }\n{*********************************************************}\n\n{@********************************************************}\n{    Copyright (c) 1999-2012 Zeos Development Group       }\n{                                                         }\n{ License Agreement:                                      }\n{                                                         }\n{ This library is distributed in the hope that it will be }\n{ useful, but WITHOUT ANY WARRANTY; without even the      }\n{ implied warranty of MERCHANTABILITY or FITNESS FOR      }\n{ A PARTICULAR PURPOSE.  See the GNU Lesser General       }\n{ Public License for more details.                        }\n{                                                         }\n{ The source code of the ZEOS Libraries and packages are  }\n{ distributed under the Library GNU General Public        }\n{ License (see the file COPYING / COPYING.ZEOS)           }\n{ with the following  modification:                       }\n{ As a special exception, the copyright holders of this   }\n{ library give you permission to link this library with   }\n{ independent modules to produce an executable,           }\n{ regardless of the license terms of these independent    }\n{ modules, and to copy and distribute the resulting       }\n{ executable under terms of your choice, provided that    }\n{ you also meet, for each linked independent module,      }\n{ the terms and conditions of the license of that module. }\n{ An independent module is a module which is not derived  }\n{ from or based on this library. If you modify this       }\n{ library, you may extend this exception to your version  }\n{ of the library, but you are not obligated to do so.     }\n{ If you do not wish to do so, delete this exception      }\n{ statement from your version.                            }\n{                                                         }\n{                                                         }\n{ The project web site is located on:                     }\n{   http://zeos.firmos.at  (FORUM)                        }\n{   http://sourceforge.net/p/zeoslib/tickets/ (BUGTRACKER)}\n{   svn://svn.code.sf.net/p/zeoslib/code-0/trunk (SVN)    }\n{                                                         }\n{   http://www.sourceforge.net/projects/zeoslib.          }\n{                                                         }\n{                                                         }\n{                                 Zeos Development Group. }\n{********************************************************@}\n\nunit ZGenericSqlToken;\n\ninterface\n\n{$I ZParseSql.inc}\n\nuses\n  Classes, {$IFDEF MSEgui}mclasses,{$ENDIF} SysUtils,\n  ZTokenizer, ZCompatibility;\n\ntype\n\n  {** Implements a symbol state object. }\n  TZGenericSQLSymbolState = class (TZSymbolState)\n  public\n    constructor Create;\n  end;\n\n  {** Implements a word state object. }\n  TZGenericSQLWordState = class (TZWordState)\n  public\n    constructor Create;\n\n    function NextToken(Stream: TStream; FirstChar: Char;\n      Tokenizer: TZTokenizer): TZToken; override;\n  end;\n\n  {** Implements a quote string state object. }\n  TZGenericSQLQuoteState = class (TZQuoteState)\n  public\n    function NextToken(Stream: TStream; FirstChar: Char;\n      Tokenizer: TZTokenizer): TZToken; override;\n\n    function EncodeString(const Value: string; QuoteChar: Char): string; override;\n    function DecodeString(const Value: string; QuoteChar: Char): string; override;\n  end;\n\n  {** Implements a default tokenizer object. }\n  TZGenericSQLTokenizer = class (TZTokenizer)\n  public\n    constructor Create;\n  end;\n\nimplementation\n\n{ TZGenericSQLSymbolState }\n\n{**\n  Creates this SQL-specific symbol state object.\n}\nconstructor TZGenericSQLSymbolState.Create;\nbegin\n  inherited Create;\n  Add('<=');\n  Add('>=');\n  Add('<>');\n  Add('<<');\n  Add('>>');\nend;\n\n{ TZGenericSQLWordState }\n\n{**\n  Constructs this SQL-specific word state object.\n}\nconstructor TZGenericSQLWordState.Create;\nbegin\n  SetWordChars(#0, #191, False);\n  SetWordChars(#192, high(char), True);\n  SetWordChars('a', 'z', True);\n  SetWordChars('A', 'Z', True);\n  SetWordChars('0', '9', True);\n  SetWordChars('$', '$', True);\n  SetWordChars('_', '_', True);\nend;\n\nconst\n  {** List of keywords. }\n  Keywords: array [0..8] of string = (\n    'AND','OR','NOT','XOR','LIKE','IS','NULL','TRUE','FALSE'\n  );\n\n{**\n  Gets a word tokens or special operators.\n  @return a processed token.\n}\nfunction TZGenericSQLWordState.NextToken(Stream: TStream; FirstChar: Char;\n  Tokenizer: TZTokenizer): TZToken;\nvar\n  I: Integer;\n  Temp: string;\nbegin\n  Result := inherited NextToken(Stream, FirstChar, Tokenizer);\n  Temp := UpperCase(Result.Value);\n\n  for I := Low(Keywords) to High(Keywords) do\n  begin\n    if Temp = Keywords[I] then\n    begin\n      Result.TokenType := ttKeyword;\n      Break;\n    end;\n  end;\nend;\n\n\n{ TZGenericSQLQuoteState }\n\n{**\n  Return a quoted string token from a reader. This method\n  will collect characters until it sees a match to the\n  character that the tokenizer used to switch to this state.\n\n  @return a quoted string token from a reader\n}\n{$IFDEF FPC}\n  {$HINTS OFF}\n{$ENDIF}\nfunction TZGenericSQLQuoteState.NextToken(Stream: TStream;\n  FirstChar: Char; Tokenizer: TZTokenizer): TZToken;\nvar\n  ReadChar: Char;\n  LastChar: Char;\n  ReadCounter, NumericCounter, CountDoublePoint, CountSlash, CountSpace : integer;\nbegin\n  Result.Value := FirstChar;\n  LastChar := #0;\n  CountDoublePoint := 0;\n  CountSlash := 0;\n  CountSpace := 0;\n  ReadCounter := 0;\n  NumericCounter := 0;\n\n  while Stream.Read(ReadChar, SizeOf(Char)) > 0 do\n  begin\n    if (LastChar = FirstChar) and (ReadChar <> FirstChar) then\n    begin\n      Stream.Seek(-SizeOf(Char), soFromCurrent);\n      Break;\n    end;\n    if ReadChar = {$IFDEF WITH_FORMATSETTINGS}FormatSettings.{$ENDIF}TimeSeparator then\n      inc(CountDoublePoint)\n    else if ReadChar = {$IFDEF WITH_FORMATSETTINGS}FormatSettings.{$ENDIF}DateSeparator then\n      inc(CountSlash)\n    else if ReadChar = ' ' then\n      inc(CountSpace)\n    else if CharInSet(ReadChar, ['0'..'9']) then\n      inc(NumericCounter);\n    Inc(ReadCounter);\n\n    Result.Value := Result.Value + ReadChar;\n    if (LastChar = FirstChar) and (ReadChar = FirstChar) then\n      LastChar := #0\n    else LastChar := ReadChar;\n  end;\n\n  if FirstChar = '\"' then\n    Result.TokenType := ttWord\n  else Result.TokenType := ttQuoted;\n\n  // Time constant\n  if (CountDoublePoint = 2) and (CountSlash = 0) and\n    ((NumericCounter + CountDoublePoint) = ReadCounter-1) then\n  begin\n    try\n      if StrToTimeDef(DecodeString(Result.Value, FirstChar), 0) = 0 then\n        Exit;\n      Result.Value := DecodeString(Result.Value,'\"');\n      Result.TokenType := ttTime;\n    except\n    end;\n  end;\n  // Date constant\n  if (CountDoublePoint = 0) and (CountSlash = 2) and\n    ((NumericCounter + CountSlash) = ReadCounter-1) then\n  begin\n    try\n      if StrToDateDef(DecodeString(Result.Value, FirstChar), 0) = 0 then\n        Exit;\n      Result.Value := DecodeString(Result.Value,'\"');\n      Result.TokenType := ttDate;\n    except\n    end;\n  end;\n\n  // DateTime constant\n  if (CountDoublePoint = 2) and (CountSlash = 2) and\n    ((NumericCounter + CountDoublePoint + CountSlash + CountSpace) = ReadCounter-1) then\n  begin\n    try\n      if StrToDateTimeDef(DecodeString(Result.Value, FirstChar), 0) = 0 then\n        Exit;\n      Result.Value := DecodeString(Result.Value,'\"');\n      Result.TokenType := ttDateTime;\n    except\n    end;\n  end;\n\n  if not ( Result.TokenType in [ttQuoted, ttWord] ) then\n    Exit;\n  \n  //No System-defaults found, Check for SQL format;\n  {AStamp := TimestampStrToDateTime(DecodeString(Result.Value, FirstChar)); //minimize the handling\n  if AStamp = 0 then\n    Exit\n  else\n    if ( TDate(AStamp) <> EmptyDate ) then\n      if ( TTime(AStamp) <> EmptyTime ) then\n      begin\n        Result.Value := DateTimeToStr(AStamp);\n        Result.TokenType := ttDateTime;\n      end\n      else\n      begin\n        Result.Value := DateToStr(AStamp);\n        Result.TokenType := ttDate;\n      end\n    else\n      if ( TTime(AStamp) <> EmptyTime ) then\n      begin\n        Result.Value := TimeToStr(AStamp);\n        Result.TokenType := ttTime;\n      end;}\nend;\n{$IFDEF FPC}\n  {$HINTS ON}\n{$ENDIF}\n\n{**\n  Encodes a string value.\n  @param Value a string value to be encoded.\n  @param QuoteChar a string quote character.\n  @returns an encoded string.\n}\nfunction TZGenericSQLQuoteState.EncodeString(const Value: string;\n  QuoteChar: Char): string;\nbegin\n  if CharInSet(QuoteChar, [#39, '\"', '`']) then\n    Result := AnsiQuotedStr(Value, QuoteChar)\n  else Result := Value;\nend;\n\n{**\n  Decodes a string value.\n  @param Value a string value to be decoded.\n  @param QuoteChar a string quote character.\n  @returns an decoded string.\n}\nfunction TZGenericSQLQuoteState.DecodeString(const Value: string;\n  QuoteChar: Char): string;\nvar\n  Len: Integer;\nbegin\n  Len := Length(Value);\n  if (Len >= 2) and CharInSet(QuoteChar, [#39, '\"', '`'])\n    and (Value[1] = QuoteChar) and (Value[Len] = QuoteChar) then\n  begin\n    if Len > 2 then\n      Result := AnsiDequotedStr(Value, QuoteChar)\n    else Result := '';\n  end\n  else Result := Value;\nend;\n\n{ TZGenericSQLTokenizer }\n\n{**\n  Constructs a tokenizer with a default state table (as\n  described in the class comment).\n}\nconstructor TZGenericSQLTokenizer.Create;\nbegin\n  NumberState := TZNumberState.Create;\n  QuoteState := TZGenericSQLQuoteState.Create;\n  WhitespaceState := TZWhitespaceState.Create;\n  CommentState := TZCppCommentState.Create;\n\n  SymbolState := TZGenericSQLSymbolState.Create;\n  WordState := TZGenericSQLWordState.Create;\n\n  SetCharacterState(#0, #32, WhitespaceState);\n  SetCharacterState(#33, #191, SymbolState);\n  SetCharacterState(#192, High(Char), WordState);\n\n  SetCharacterState('a', 'z', WordState);\n  SetCharacterState('A', 'Z', WordState);\n  SetCharacterState('_', '_', WordState);\n  SetCharacterState('$', '$', WordState);\n\n  SetCharacterState('0', '9', NumberState);\n  SetCharacterState('.', '.', NumberState);\n\n  SetCharacterState('\"', '\"', QuoteState);\n  SetCharacterState(#39, #39, QuoteState);\n  SetCharacterState('`', '`', QuoteState);\n\n  SetCharacterState('/', '/', CommentState);\nend;\n\nend.\n\n"
  },
  {
    "path": "lib/zeosdbo/src/parsesql/ZInterbaseAnalyser.pas",
    "content": "{*********************************************************}\n{                                                         }\n{                 Zeos Database Objects                   }\n{            SQL Statements Analysing classes             }\n{                                                         }\n{         Originally written by Sergey Seroukhov          }\n{                                                         }\n{*********************************************************}\n\n{@********************************************************}\n{    Copyright (c) 1999-2012 Zeos Development Group       }\n{                                                         }\n{ License Agreement:                                      }\n{                                                         }\n{ This library is distributed in the hope that it will be }\n{ useful, but WITHOUT ANY WARRANTY; without even the      }\n{ implied warranty of MERCHANTABILITY or FITNESS FOR      }\n{ A PARTICULAR PURPOSE.  See the GNU Lesser General       }\n{ Public License for more details.                        }\n{                                                         }\n{ The source code of the ZEOS Libraries and packages are  }\n{ distributed under the Library GNU General Public        }\n{ License (see the file COPYING / COPYING.ZEOS)           }\n{ with the following  modification:                       }\n{ As a special exception, the copyright holders of this   }\n{ library give you permission to link this library with   }\n{ independent modules to produce an executable,           }\n{ regardless of the license terms of these independent    }\n{ modules, and to copy and distribute the resulting       }\n{ executable under terms of your choice, provided that    }\n{ you also meet, for each linked independent module,      }\n{ the terms and conditions of the license of that module. }\n{ An independent module is a module which is not derived  }\n{ from or based on this library. If you modify this       }\n{ library, you may extend this exception to your version  }\n{ of the library, but you are not obligated to do so.     }\n{ If you do not wish to do so, delete this exception      }\n{ statement from your version.                            }\n{                                                         }\n{                                                         }\n{ The project web site is located on:                     }\n{   http://zeos.firmos.at  (FORUM)                        }\n{   http://sourceforge.net/p/zeoslib/tickets/ (BUGTRACKER)}\n{   svn://svn.code.sf.net/p/zeoslib/code-0/trunk (SVN)    }\n{                                                         }\n{   http://www.sourceforge.net/projects/zeoslib.          }\n{                                                         }\n{                                                         }\n{                                 Zeos Development Group. }\n{********************************************************@}\n\nunit ZInterbaseAnalyser;\n\ninterface\n\n{$I ZParseSql.inc}\n\nuses Classes, ZGenericSqlAnalyser;\n\ntype\n\n  {** Implements an Interbase statements analyser. }\n  TZInterbaseStatementAnalyser = class (TZGenericStatementAnalyser)\n  end;\n\nimplementation\n\nend.\n\n"
  },
  {
    "path": "lib/zeosdbo/src/parsesql/ZInterbaseToken.pas",
    "content": "{*********************************************************}\n{                                                         }\n{                 Zeos Database Objects                   }\n{        String tokenizing classes for Interbase          }\n{                                                         }\n{        Originally written by Sergey Seroukhov           }\n{                                                         }\n{*********************************************************}\n\n{@********************************************************}\n{    Copyright (c) 1999-2012 Zeos Development Group       }\n{                                                         }\n{ License Agreement:                                      }\n{                                                         }\n{ This library is distributed in the hope that it will be }\n{ useful, but WITHOUT ANY WARRANTY; without even the      }\n{ implied warranty of MERCHANTABILITY or FITNESS FOR      }\n{ A PARTICULAR PURPOSE.  See the GNU Lesser General       }\n{ Public License for more details.                        }\n{                                                         }\n{ The source code of the ZEOS Libraries and packages are  }\n{ distributed under the Library GNU General Public        }\n{ License (see the file COPYING / COPYING.ZEOS)           }\n{ with the following  modification:                       }\n{ As a special exception, the copyright holders of this   }\n{ library give you permission to link this library with   }\n{ independent modules to produce an executable,           }\n{ regardless of the license terms of these independent    }\n{ modules, and to copy and distribute the resulting       }\n{ executable under terms of your choice, provided that    }\n{ you also meet, for each linked independent module,      }\n{ the terms and conditions of the license of that module. }\n{ An independent module is a module which is not derived  }\n{ from or based on this library. If you modify this       }\n{ library, you may extend this exception to your version  }\n{ of the library, but you are not obligated to do so.     }\n{ If you do not wish to do so, delete this exception      }\n{ statement from your version.                            }\n{                                                         }\n{                                                         }\n{ The project web site is located on:                     }\n{   http://zeos.firmos.at  (FORUM)                        }\n{   http://sourceforge.net/p/zeoslib/tickets/ (BUGTRACKER)}\n{   svn://svn.code.sf.net/p/zeoslib/code-0/trunk (SVN)    }\n{                                                         }\n{   http://www.sourceforge.net/projects/zeoslib.          }\n{                                                         }\n{                                                         }\n{                                 Zeos Development Group. }\n{********************************************************@}\n\nunit ZInterbaseToken;\n\ninterface\n\n{$I ZParseSql.inc}\n\nuses\n  Classes, ZTokenizer, ZGenericSqlToken, ZPostgreSqlToken;\n\ntype\n\n  {** Implements a Interbase-specific number state object. }\n  TZInterbaseNumberState = class (TZPostgreSQLNumberState)\n  end;\n\n  {** Implements a Interbase-specific quote string state object. }\n  TZInterbaseQuoteState = class (TZGenericSQLQuoteState)\n  end;\n\n  {**\n    This state will either delegate to a comment-handling\n    state, or return a token with just a slash in it.\n  }\n  TZInterbaseCommentState = class (TZCCommentState)\n  end;\n\n  {** Implements a symbol state object. }\n  TZInterbaseSymbolState = class (TZSymbolState)\n  public\n    constructor Create;\n  end;\n\n  {** Implements a word state object. }\n  TZInterbaseWordState = class (TZGenericSQLWordState)\n  public\n    constructor Create;\n  end;\n\n  {** Implements a default tokenizer object. }\n  TZInterbaseTokenizer = class (TZTokenizer)\n  public\n    constructor Create;\n  end;\n\nimplementation\n\n{ TZInterbaseSymbolState }\n\n{**\n  Creates this Interbase-specific symbol state object.\n}\nconstructor TZInterbaseSymbolState.Create;\nbegin\n  inherited Create;\n  Add('<=');\n  Add('>=');\n  Add('<>');\n  Add('!=');\n  Add('!<');\n  Add('!>');\nend;\n\n{ TZInterbaseWordState }\n\n{**\n  Constructs this Interbase-specific word state object.\n}\nconstructor TZInterbaseWordState.Create;\nbegin\n  SetWordChars(#0, #255, False);\n  SetWordChars('a', 'z', True);\n  SetWordChars('A', 'Z', True);\n  SetWordChars('0', '9', True);\n  SetWordChars('_', '_', True);\n  SetWordChars('$', '$', True);\nend;\n\n{ TZInterbaseTokenizer }\n\n{ TZInterbaseTokenizer }\n\nconstructor TZInterbaseTokenizer.Create;\nbegin\n  EscapeState := TZEscapeState.Create;\n  WhitespaceState := TZWhitespaceState.Create;\n\n  SymbolState := TZInterbaseSymbolState.Create;\n  NumberState := TZInterbaseNumberState.Create;\n  QuoteState := TZInterbaseQuoteState.Create;\n  WordState := TZInterbaseWordState.Create;\n  CommentState := TZInterbaseCommentState.Create;\n\n  SetCharacterState(#0, #32, WhitespaceState);\n  SetCharacterState(#33, #191, SymbolState);\n  SetCharacterState(#192, High(Char), WordState);\n\n  SetCharacterState('a', 'z', WordState);\n  SetCharacterState('A', 'Z', WordState);\n  SetCharacterState('_', '_', WordState);\n  SetCharacterState('$', '$', WordState);\n\n  SetCharacterState('0', '9', NumberState);\n  SetCharacterState('.', '.', NumberState);\n\n  SetCharacterState('\"', '\"', QuoteState);\n  SetCharacterState(#39, #39, QuoteState);\n\n  SetCharacterState('/', '/', CommentState);\nend;\n\nend.\n\n"
  },
  {
    "path": "lib/zeosdbo/src/parsesql/ZMySqlAnalyser.pas",
    "content": "{*********************************************************}\n{                                                         }\n{                 Zeos Database Objects                   }\n{            SQL Statements Analysing classes             }\n{                                                         }\n{           Originally written by Sergey Seroukhov        }\n{                                                         }\n{*********************************************************}\n\n{@********************************************************}\n{    Copyright (c) 1999-2012 Zeos Development Group       }\n{                                                         }\n{ License Agreement:                                      }\n{                                                         }\n{ This library is distributed in the hope that it will be }\n{ useful, but WITHOUT ANY WARRANTY; without even the      }\n{ implied warranty of MERCHANTABILITY or FITNESS FOR      }\n{ A PARTICULAR PURPOSE.  See the GNU Lesser General       }\n{ Public License for more details.                        }\n{                                                         }\n{ The source code of the ZEOS Libraries and packages are  }\n{ distributed under the Library GNU General Public        }\n{ License (see the file COPYING / COPYING.ZEOS)           }\n{ with the following  modification:                       }\n{ As a special exception, the copyright holders of this   }\n{ library give you permission to link this library with   }\n{ independent modules to produce an executable,           }\n{ regardless of the license terms of these independent    }\n{ modules, and to copy and distribute the resulting       }\n{ executable under terms of your choice, provided that    }\n{ you also meet, for each linked independent module,      }\n{ the terms and conditions of the license of that module. }\n{ An independent module is a module which is not derived  }\n{ from or based on this library. If you modify this       }\n{ library, you may extend this exception to your version  }\n{ of the library, but you are not obligated to do so.     }\n{ If you do not wish to do so, delete this exception      }\n{ statement from your version.                            }\n{                                                         }\n{                                                         }\n{ The project web site is located on:                     }\n{   http://zeos.firmos.at  (FORUM)                        }\n{   http://sourceforge.net/p/zeoslib/tickets/ (BUGTRACKER)}\n{   svn://svn.code.sf.net/p/zeoslib/code-0/trunk (SVN)    }\n{                                                         }\n{   http://www.sourceforge.net/projects/zeoslib.          }\n{                                                         }\n{                                                         }\n{                                 Zeos Development Group. }\n{********************************************************@}\n\nunit ZMySqlAnalyser;\n\ninterface\n\n{$I ZParseSql.inc}\n\nuses Classes, ZGenericSqlAnalyser;\n\ntype\n\n  {** Implements an MySQL statements analyser. }\n  TZMySQLStatementAnalyser = class (TZGenericStatementAnalyser)\n  public\n    constructor Create;\n  end;\n\nimplementation\n\nconst\n  {** The generic constants.}\n  MySQLSectionNames: array[0..16] of string = (\n    'SELECT', 'UPDATE', 'DELETE', 'INSERT', 'FROM',\n    'WHERE', 'INTO', 'GROUP*BY', 'HAVING', 'ORDER*BY',\n    'FOR*UPDATE', 'LIMIT', 'OFFSET', 'INTO*OUTFILE',\n    'INTO*DUMPFILE', 'PROCEDURE', 'LOCK*IN*SHARE'\n  );\n  MySQLSelectOptions: array[0..7] of string = (\n    'DISTINCT', 'ALL', 'DISTINCTROW', 'STRAIGHT_JOIN', 'SQL_SMALL_RESULT',\n    'SQL_BIG_RESULT', 'SQL_BUFFER_RESULT', 'HIGH_PRIORITY'\n  );\n  MySQLFromJoins: array[0..7] of string = (\n    'NATURAL', 'RIGHT', 'LEFT', 'INNER', 'OUTER', 'JOIN',\n    'STRAIGHT_JOIN', 'CROSS'\n  );\n  MySQLFromClauses: array[0..3] of string = (\n    'ON', 'USING', 'USE', 'IGNORE'\n  );\n\n{ TZMySQLStatementAnalyser }\n\n{**\n  Creates the object and assignes the main properties.\n}\nconstructor TZMySQLStatementAnalyser.Create;\nbegin\n  SectionNames := ArrayToStrings(MySQLSectionNames);\n  SelectOptions := ArrayToStrings(MySQLSelectOptions);\n  FromJoins := ArrayToStrings(MySQLFromJoins);\n  FromClauses := ArrayToStrings(MySQLFromClauses);\nend;\n\nend.\n\n"
  },
  {
    "path": "lib/zeosdbo/src/parsesql/ZMySqlToken.pas",
    "content": "{*********************************************************}\n{                                                         }\n{                 Zeos Database Objects                   }\n{           String tokenizing classes for MySQL           }\n{                                                         }\n{         Originally written by Sergey Seroukhov          }\n{                                                         }\n{*********************************************************}\n\n{@********************************************************}\n{    Copyright (c) 1999-2012 Zeos Development Group       }\n{                                                         }\n{ License Agreement:                                      }\n{                                                         }\n{ This library is distributed in the hope that it will be }\n{ useful, but WITHOUT ANY WARRANTY; without even the      }\n{ implied warranty of MERCHANTABILITY or FITNESS FOR      }\n{ A PARTICULAR PURPOSE.  See the GNU Lesser General       }\n{ Public License for more details.                        }\n{                                                         }\n{ The source code of the ZEOS Libraries and packages are  }\n{ distributed under the Library GNU General Public        }\n{ License (see the file COPYING / COPYING.ZEOS)           }\n{ with the following  modification:                       }\n{ As a special exception, the copyright holders of this   }\n{ library give you permission to link this library with   }\n{ independent modules to produce an executable,           }\n{ regardless of the license terms of these independent    }\n{ modules, and to copy and distribute the resulting       }\n{ executable under terms of your choice, provided that    }\n{ you also meet, for each linked independent module,      }\n{ the terms and conditions of the license of that module. }\n{ An independent module is a module which is not derived  }\n{ from or based on this library. If you modify this       }\n{ library, you may extend this exception to your version  }\n{ of the library, but you are not obligated to do so.     }\n{ If you do not wish to do so, delete this exception      }\n{ statement from your version.                            }\n{                                                         }\n{                                                         }\n{ The project web site is located on:                     }\n{   http://zeos.firmos.at  (FORUM)                        }\n{   http://sourceforge.net/p/zeoslib/tickets/ (BUGTRACKER)}\n{   svn://svn.code.sf.net/p/zeoslib/code-0/trunk (SVN)    }\n{                                                         }\n{   http://www.sourceforge.net/projects/zeoslib.          }\n{                                                         }\n{                                                         }\n{                                 Zeos Development Group. }\n{********************************************************@}\n\nunit ZMySqlToken;\n\ninterface\n\n{$I ZParseSql.inc}\n\nuses\n  Classes, {$IFDEF MSEgui}mclasses,{$ENDIF} SysUtils,\n  ZSysUtils, ZTokenizer, ZGenericSqlToken, ZCompatibility;\n\ntype\n\n  {** Implements a MySQL-specific number state object. }\n  TZMySQLNumberState = class (TZNumberState)\n  public\n    function NextToken(Stream: TStream; FirstChar: Char;\n      Tokenizer: TZTokenizer): TZToken; override;\n  end;\n\n  {** Implements a MySQL-specific quote string state object. }\n  TZMySQLQuoteState = class (TZQuoteState)\n  public\n    function NextToken(Stream: TStream; FirstChar: Char;\n      Tokenizer: TZTokenizer): TZToken; override;\n\n    function EncodeString(const Value: string; QuoteChar: Char): string; override;\n    function DecodeString(const Value: string; QuoteChar: Char): string; override;\n  end;\n\n  {**\n    This state will either delegate to a comment-handling\n    state, or return a token with just a slash in it.\n  }\n  TZMySQLCommentState = class (TZCppCommentState)\n  public\n    function NextToken(Stream: TStream; FirstChar: Char;\n      Tokenizer: TZTokenizer): TZToken; override;\n  end;\n\n  {** Implements a symbol state object. }\n  TZMySQLSymbolState = class (TZSymbolState)\n  public\n    constructor Create;\n  end;\n\n  {** Implements a word state object. }\n  TZMySQLWordState = class (TZGenericSQLWordState)\n  public\n    constructor Create;\n  end;\n\n  {** Implements a default tokenizer object. }\n  TZMySQLTokenizer = class (TZTokenizer)\n  public\n    constructor Create;\n  end;\n\nimplementation\n\nuses StrUtils;\n\n{ TZMySQLNumberState }\n\n{**\n  Return a number token from a reader.\n  @return a number token from a reader\n}\nfunction TZMySQLNumberState.NextToken(Stream: TStream; FirstChar: Char;\n  Tokenizer: TZTokenizer): TZToken;\nvar\n  HexDecimal: Boolean;\n  FloatPoint: Boolean;\n  LastChar: Char;\n\n  function ReadHexDigits: string;\n  begin\n    Result := '';\n    LastChar := #0;\n    while Stream.Read(LastChar, SizeOf(Char)) > 0 do\n    begin\n      if CharInSet(LastChar, ['0'..'9','a'..'f','A'..'F']) then\n      begin\n        Result := Result + LastChar;\n        HexDecimal := HexDecimal or CharInSet(LastChar, ['a'..'f','A'..'F']);\n        LastChar := #0;\n      end\n      else\n      begin\n        Stream.Seek(-SizeOf(Char), soFromCurrent);\n        Break;\n      end;\n    end;\n  end;\n\n  function ReadDecDigits: string;\n  begin\n    Result := '';\n    LastChar := #0;\n    while Stream.Read(LastChar, SizeOf(Char)) > 0 do\n    begin\n      if CharInSet(LastChar, ['0'..'9']) then\n      begin\n        Result := Result + LastChar;\n        LastChar := #0;\n      end\n      else\n      begin\n        Stream.Seek(-SizeOf(Char), soFromCurrent);\n        Break;\n      end;\n    end;\n  end;\n\nbegin\n  HexDecimal := False;\n  FloatPoint := FirstChar = '.';\n  Result.Value := FirstChar;\n  Result.TokenType := ttUnknown;\n  LastChar := #0;\n\n  { Reads the first part of the number before decimal point }\n  if not FloatPoint then\n  begin\n    Result.Value := Result.Value + ReadDecDigits;\n    FloatPoint := (LastChar = '.') and not HexDecimal;\n    if FloatPoint then\n    begin\n      Stream.Read(LastChar, SizeOf(Char));\n      Result.Value := Result.Value + LastChar;\n    end;\n  end;\n\n  { Reads the second part of the number after decimal point }\n  if FloatPoint then\n    Result.Value := Result.Value + ReadDecDigits;\n\n  { Reads a power part of the number }\n  if not HexDecimal and CharInSet(LastChar, ['e','E']) then\n  begin\n    Stream.Read(LastChar, SizeOf(Char));\n    Result.Value := Result.Value + LastChar;\n    FloatPoint := True;\n\n    Stream.Read(LastChar, SizeOf(Char));\n    if CharInSet(LastChar, ['0'..'9','-','+']) then\n      Result.Value := Result.Value + LastChar + ReadDecDigits\n    else\n    begin\n      Result.Value := Copy(Result.Value, 1, Length(Result.Value) - 1);\n      Stream.Seek(-2*SizeOf(Char), soFromCurrent);\n    end;\n  end;\n\n  { Reads the nexdecimal number }\n  if (Result.Value = '0') and CharInSet(LastChar, ['x','X']) then\n  begin\n    Stream.Read(LastChar, SizeOf(Char));\n    Result.Value := Result.Value + LastChar + ReadHexDigits;\n    HexDecimal := True;\n  end;\n\n  { Prepare the result }\n  if Result.Value = '.' then\n  begin\n    if Tokenizer.SymbolState <> nil then\n      Result := Tokenizer.SymbolState.NextToken(Stream, FirstChar, Tokenizer);\n  end\n  else\n  begin\n    if HexDecimal then\n      Result.TokenType := ttHexDecimal\n    else if FloatPoint then\n      Result.TokenType := ttFloat\n    else Result.TokenType := ttInteger;\n  end;\nend;\n\n{ TZMySQLQuoteState }\n\n{**\n  Return a quoted string token from a reader. This method\n  will collect characters until it sees a match to the\n  character that the tokenizer used to switch to this state.\n\n  @return a quoted string token from a reader\n}\nfunction TZMySQLQuoteState.NextToken(Stream: TStream; FirstChar: Char;\n  Tokenizer: TZTokenizer): TZToken;\nconst BackSlash = Char('\\');\nvar\n  ReadChar: Char;\n  LastChar: Char;\n  //QuoteChar: Char;\n  //QuoteCount: Integer;\nbegin\n  Result.Value := FirstChar;\n  //QuoteCount := 1;\n  If FirstChar = '`' then\n    Result.TokenType := ttQuotedIdentifier\n  Else\n    Result.TokenType := ttQuoted;\n\n  //QuoteChar := FirstChar;\n\n  LastChar := #0;\n\n  while Stream.Read(ReadChar, SizeOf(Char)) > 0 do\n  begin\n    //if ReadChar = QuoteChar then Inc(QuoteCount);\n    if (LastChar = FirstChar) and (ReadChar <> FirstChar) then\n    begin\n      //if QuoteCount mod 2 = 0 then // only valid for Pascal AnsiQuoted/QuotedStr\n      begin\n        Stream.Seek(-SizeOf(Char), soFromCurrent);\n        Break;\n      end;\n    end;\n    Result.Value := Result.Value + ReadChar;\n    if LastChar = BackSlash then\n//    begin\n//      if Readchar = FirstChar then Inc(QuoteCount);  //Escaped single Quote (A QuoteChar instead of FirstChar would be better..)\n      LastChar := #0\n//    end\n    else if (LastChar = FirstChar) and (ReadChar = FirstChar) then\n      LastChar := #0\n    else LastChar := ReadChar;\n  end;\nend;\n\n{**\n  Encodes a string value.\n  @param Value a string value to be encoded.\n  @param QuoteChar a string quote character.\n  @returns an encoded string.\n}\nfunction TZMySQLQuoteState.EncodeString(const Value: string; QuoteChar: Char): string;\nbegin\n  if CharInSet(QuoteChar, [#39, '\"', '`']) then\n    Result := QuoteChar + EncodeCString(Value) + QuoteChar\n  else Result := Value;\nend;\n\n{**\n  Decodes a string value.\n  @param Value a string value to be decoded.\n  @param QuoteChar a string quote character.\n  @returns an decoded string.\n}\nfunction TZMySQLQuoteState.DecodeString(const Value: string; QuoteChar: Char): string;\nvar\n  Len: Integer;\nbegin\n  Len := Length(Value);\n  if (Len >= 2) and CharInSet(QuoteChar, [#39, '\"', '`'])\n    and (Value[1] = QuoteChar) and (Value[Len] = QuoteChar) then\n  begin\n    if Len > 2 then\n      Result := DecodeCString(Copy(Value, 2, Len - 2))\n    else Result := '';\n  end\n  else Result := Value;\nend;\n\n{ TZMySQLCommentState }\n\n{**\n  Gets a MySQL specific comments like # or /* */.\n  @return either just a slash token, or the results of\n    delegating to a comment-handling state\n}\nfunction TZMySQLCommentState.NextToken(Stream: TStream; FirstChar: Char;\n  Tokenizer: TZTokenizer): TZToken;\nvar\n  ReadChar: Char;\n  ReadNum, ReadNum2: Integer;\nbegin\n  Result.TokenType := ttUnknown;\n  Result.Value := FirstChar;\n\n  if FirstChar = '-' then\n  begin\n    ReadNum := Stream.Read(ReadChar, SizeOf(Char));\n    if (ReadNum > 0) and (ReadChar = '-') then\n    begin\n      Result.TokenType := ttComment;\n      Result.Value := '--' + GetSingleLineComment(Stream);\n    end\n    else\n    begin\n      if ReadNum > 0 then\n        Stream.Seek(-SizeOf(Char), soFromCurrent);\n    end;\n  end\n  else if FirstChar = '#' then\n  begin\n    Result.TokenType := ttComment;\n    Result.Value := '#' + GetSingleLineComment(Stream);\n  end\n  else if FirstChar = '/' then\n  begin\n    ReadNum := Stream.Read(ReadChar, SizeOf(Char));\n    if (ReadNum > 0) and (ReadChar = '*') then\n    begin\n      ReadNum2 := Stream.Read(ReadChar, SizeOf(Char));\n      // Don't treat '/*!' comments as normal comments!!\n      if (ReadNum2 > 0) and (ReadChar <> '!') then\n      begin\n        Result.TokenType := ttComment;\n        Result.Value := '/*'+ReadChar + GetMultiLineComment(Stream);\n      end\n      else\n      begin\n        if ReadNum2 > 0 then\n          Result.TokenType := ttSymbol;\n          Result.Value := '/*!' + GetMultiLineComment(Stream);\n      end;\n    end\n    else\n    begin\n      if ReadNum > 0 then\n        Stream.Seek(-SizeOf(Char), soFromCurrent);\n    end;\n  end;\n\n  if (Result.TokenType = ttUnknown) and (Tokenizer.SymbolState <> nil) then\n    Result := Tokenizer.SymbolState.NextToken(Stream, FirstChar, Tokenizer);\nend;\n\n{ TZMySQLSymbolState }\n\n{**\n  Creates this MySQL-specific symbol state object.\n}\nconstructor TZMySQLSymbolState.Create;\nbegin\n  inherited Create;\n  Add('<=');\n  Add('>=');\n  Add('<>');\n  Add('<<');\n  Add('>>');\n  {BEGIN PATCH: added by fduenas}\n  Add(':=');\n  {END PATCH: added by fduenas}\nend;\n\n{ TZMySQLWordState }\n\n{**\n  Constructs this MySQL-specific word state object.\n}\nconstructor TZMySQLWordState.Create;\nbegin\n  SetWordChars(#0, #191, False);\n  SetWordChars(#192, high(char), True);\n  SetWordChars('a', 'z', True);\n  SetWordChars('A', 'Z', True);\n  SetWordChars('0', '9', True);\n  SetWordChars('$', '$', True);\n  SetWordChars('_', '_', True);\nend;\n\n{ TZMySQLTokenizer }\n\n{**\n  Constructs a tokenizer with a default state table (as\n  described in the class comment).\n}\nconstructor TZMySQLTokenizer.Create;\nbegin\n  WhitespaceState := TZWhitespaceState.Create;\n\n  EscapeState := TZEscapeState.Create;\n  SymbolState := TZMySQLSymbolState.Create;\n  NumberState := TZMySQLNumberState.Create;\n  QuoteState := TZMySQLQuoteState.Create;\n  WordState := TZMySQLWordState.Create;\n  CommentState := TZMySQLCommentState.Create;\n\n  SetCharacterState(#0, #32, WhitespaceState);\n  SetCharacterState(#33, #191, SymbolState);\n  SetCharacterState(#192, High(Char), WordState);\n\n  SetCharacterState('a', 'z', WordState);\n  SetCharacterState('A', 'Z', WordState);\n  SetCharacterState('_', '_', WordState);\n  SetCharacterState('$', '$', WordState);\n\n  SetCharacterState('0', '9', NumberState);\n  SetCharacterState('.', '.', NumberState);\n\n  SetCharacterState('\"', '\"', QuoteState);\n  SetCharacterState(#39, #39, QuoteState);\n  SetCharacterState('`', '`', QuoteState);\n\n  SetCharacterState('/', '/', CommentState);\n  SetCharacterState('#', '#', CommentState);\n  SetCharacterState('-', '-', CommentState);\nend;\n\nend.\n\n"
  },
  {
    "path": "lib/zeosdbo/src/parsesql/ZOracleAnalyser.pas",
    "content": "{*********************************************************}\n{                                                         }\n{                 Zeos Database Objects                   }\n{            SQL Statements Analysing classes             }\n{                                                         }\n{        Originally written by Sergey Seroukhov           }\n{                                                         }\n{*********************************************************}\n\n{@********************************************************}\n{    Copyright (c) 1999-2012 Zeos Development Group       }\n{                                                         }\n{ License Agreement:                                      }\n{                                                         }\n{ This library is distributed in the hope that it will be }\n{ useful, but WITHOUT ANY WARRANTY; without even the      }\n{ implied warranty of MERCHANTABILITY or FITNESS FOR      }\n{ A PARTICULAR PURPOSE.  See the GNU Lesser General       }\n{ Public License for more details.                        }\n{                                                         }\n{ The source code of the ZEOS Libraries and packages are  }\n{ distributed under the Library GNU General Public        }\n{ License (see the file COPYING / COPYING.ZEOS)           }\n{ with the following  modification:                       }\n{ As a special exception, the copyright holders of this   }\n{ library give you permission to link this library with   }\n{ independent modules to produce an executable,           }\n{ regardless of the license terms of these independent    }\n{ modules, and to copy and distribute the resulting       }\n{ executable under terms of your choice, provided that    }\n{ you also meet, for each linked independent module,      }\n{ the terms and conditions of the license of that module. }\n{ An independent module is a module which is not derived  }\n{ from or based on this library. If you modify this       }\n{ library, you may extend this exception to your version  }\n{ of the library, but you are not obligated to do so.     }\n{ If you do not wish to do so, delete this exception      }\n{ statement from your version.                            }\n{                                                         }\n{                                                         }\n{ The project web site is located on:                     }\n{   http://zeos.firmos.at  (FORUM)                        }\n{   http://sourceforge.net/p/zeoslib/tickets/ (BUGTRACKER)}\n{   svn://svn.code.sf.net/p/zeoslib/code-0/trunk (SVN)    }\n{                                                         }\n{   http://www.sourceforge.net/projects/zeoslib.          }\n{                                                         }\n{                                                         }\n{                                 Zeos Development Group. }\n{********************************************************@}\n\nunit ZOracleAnalyser;\n\ninterface\n\n{$I ZParseSql.inc}\n\nuses Classes, ZGenericSqlAnalyser;\n\ntype\n\n  {** Implements an Oracle statements analyser. }\n  TZOracleStatementAnalyser = class (TZGenericStatementAnalyser)\n  public\n    constructor Create;\n  end;\n\nimplementation\n\nconst\n  {** The generic constants.}\n  OracleSectionNames: array[0..13] of string = (\n    'SELECT', 'UPDATE', 'DELETE', 'INSERT', 'FROM',\n    'WHERE', 'INTO', 'GROUP*BY', 'HAVING', 'ORDER*BY',\n    'ORDER*SIBLINGS*BY', 'FOR*UPDATE', 'START*WITH', 'CONNECT*BY'\n  );\n  OracleSelectOptions: array[0..2] of string = (\n    'DISTINCT', 'ALL', 'UNIQUE'\n  );\n  OracleFromJoins: array[0..7] of string = (\n    'NATURAL', 'RIGHT', 'LEFT', 'FULL', 'INNER', 'OUTER', 'JOIN', 'CROSS'\n  );\n  OracleFromClauses: array[0..1] of string = (\n    'ON', 'USING'\n  );\n\n{ TZOracleStatementAnalyser }\n\n{**\n  Creates the object and assignes the main properties.\n}\nconstructor TZOracleStatementAnalyser.Create;\nbegin\n  SectionNames := ArrayToStrings(OracleSectionNames);\n  SelectOptions := ArrayToStrings(OracleSelectOptions);\n  FromJoins := ArrayToStrings(OracleFromJoins);\n  FromClauses := ArrayToStrings(OracleFromClauses);\nend;\n\nend.\n\n"
  },
  {
    "path": "lib/zeosdbo/src/parsesql/ZOracleToken.pas",
    "content": "{*********************************************************}\n{                                                         }\n{                 Zeos Database Objects                   }\n{        String tokenizing classes for Oracle             }\n{                                                         }\n{        Originally written by Sergey Seroukhov           }\n{                                                         }\n{*********************************************************}\n\n{@********************************************************}\n{    Copyright (c) 1999-2012 Zeos Development Group       }\n{                                                         }\n{ License Agreement:                                      }\n{                                                         }\n{ This library is distributed in the hope that it will be }\n{ useful, but WITHOUT ANY WARRANTY; without even the      }\n{ implied warranty of MERCHANTABILITY or FITNESS FOR      }\n{ A PARTICULAR PURPOSE.  See the GNU Lesser General       }\n{ Public License for more details.                        }\n{                                                         }\n{ The source code of the ZEOS Libraries and packages are  }\n{ distributed under the Library GNU General Public        }\n{ License (see the file COPYING / COPYING.ZEOS)           }\n{ with the following  modification:                       }\n{ As a special exception, the copyright holders of this   }\n{ library give you permission to link this library with   }\n{ independent modules to produce an executable,           }\n{ regardless of the license terms of these independent    }\n{ modules, and to copy and distribute the resulting       }\n{ executable under terms of your choice, provided that    }\n{ you also meet, for each linked independent module,      }\n{ the terms and conditions of the license of that module. }\n{ An independent module is a module which is not derived  }\n{ from or based on this library. If you modify this       }\n{ library, you may extend this exception to your version  }\n{ of the library, but you are not obligated to do so.     }\n{ If you do not wish to do so, delete this exception      }\n{ statement from your version.                            }\n{                                                         }\n{                                                         }\n{ The project web site is located on:                     }\n{   http://zeos.firmos.at  (FORUM)                        }\n{   http://sourceforge.net/p/zeoslib/tickets/ (BUGTRACKER)}\n{   svn://svn.code.sf.net/p/zeoslib/code-0/trunk (SVN)    }\n{                                                         }\n{   http://www.sourceforge.net/projects/zeoslib.          }\n{                                                         }\n{                                                         }\n{                                 Zeos Development Group. }\n{********************************************************@}\n\nunit ZOracleToken;\n\ninterface\n\n{$I ZParseSql.inc}\n\nuses\n  Classes, ZTokenizer, ZGenericSqlToken, ZPostgreSqlToken,\n  ZSybaseToken;\n\ntype\n\n  {** Implements a Oracle-specific number state object. }\n  TZOracleNumberState = class (TZPostgreSQLNumberState)\n  end;\n\n  {** Implements a Oracle-specific quote string state object. }\n  TZOracleQuoteState = class (TZGenericSQLQuoteState)\n  end;\n\n  {**\n    This state will either delegate to a comment-handling\n    state, or return a token with just a slash in it.\n  }\n  TZOracleCommentState = class (TZSybaseCommentState)\n  end;\n\n  {** Implements a symbol state object. }\n  TZOracleSymbolState = class (TZSymbolState)\n  public\n    constructor Create;\n  end;\n\n  {** Implements a word state object. }\n  TZOracleWordState = class (TZGenericSQLWordState)\n  public\n    constructor Create;\n  end;\n\n  {** Implements a default tokenizer object. }\n  TZOracleTokenizer = class (TZTokenizer)\n  public\n    constructor Create;\n  end;\n\nimplementation\n\n{ TZOracleSymbolState }\n\n{**\n  Creates this Oracle-specific symbol state object.\n}\nconstructor TZOracleSymbolState.Create;\nbegin\n  inherited Create;\n  Add('<=');\n  Add('>=');\n  Add('<>');\n  Add('!=');\n  Add('||');\nend;\n\n{ TZOracleWordState }\n\n{**\n  Constructs this Oracle-specific word state object.\n}\nconstructor TZOracleWordState.Create;\nbegin\n  SetWordChars(#0, #255, False);\n  SetWordChars('a', 'z', True);\n  SetWordChars('A', 'Z', True);\n  SetWordChars('0', '9', True);\n  SetWordChars('_', '_', True);\n  SetWordChars('$', '$', True);\n  SetWordChars('#', '#', True);\n  SetWordChars('@', '@', True);\nend;\n\n{ TZOracleTokenizer }\n\n{**\n  Constructs a tokenizer with a default state table (as\n  described in the class comment).\n}\nconstructor TZOracleTokenizer.Create;\nbegin\n  EscapeState := TZEscapeState.Create;\n  WhitespaceState := TZWhitespaceState.Create;\n\n  SymbolState := TZOracleSymbolState.Create;\n  NumberState := TZOracleNumberState.Create;\n  QuoteState := TZOracleQuoteState.Create;\n  WordState := TZOracleWordState.Create;\n  CommentState := TZOracleCommentState.Create;\n\n  SetCharacterState(#0, #32, WhitespaceState);\n  SetCharacterState(#33, #191, SymbolState);\n  SetCharacterState(#192, High(Char), WordState);\n\n  SetCharacterState('a', 'z', WordState);\n  SetCharacterState('A', 'Z', WordState);\n  SetCharacterState('_', '_', WordState);\n  SetCharacterState('$', '$', WordState);\n  SetCharacterState('#', '#', WordState);\n\n  SetCharacterState('0', '9', NumberState);\n  SetCharacterState('.', '.', NumberState);\n\n  SetCharacterState('\"', '\"', QuoteState);\n  SetCharacterState(#39, #39, QuoteState);\n\n  SetCharacterState('/', '/', CommentState);\n  SetCharacterState('-', '-', CommentState);\nend;\n\nend.\n\n"
  },
  {
    "path": "lib/zeosdbo/src/parsesql/ZParseSql.inc",
    "content": "{@********************************************************}\n{    Copyright (c) 1999-2012 Zeos Development Group       }\n{                                                         }\n{ License Agreement:                                      }\n{                                                         }\n{ This library is distributed in the hope that it will be }\n{ useful, but WITHOUT ANY WARRANTY; without even the      }\n{ implied warranty of MERCHANTABILITY or FITNESS FOR      }\n{ A PARTICULAR PURPOSE.  See the GNU Lesser General       }\n{ Public License for more details.                        }\n{                                                         }\n{ The source code of the ZEOS Libraries and packages are  }\n{ distributed under the Library GNU General Public        }\n{ License (see the file COPYING / COPYING.ZEOS)           }\n{ with the following  modification:                       }\n{ As a special exception, the copyright holders of this   }\n{ library give you permission to link this library with   }\n{ independent modules to produce an executable,           }\n{ regardless of the license terms of these independent    }\n{ modules, and to copy and distribute the resulting       }\n{ executable under terms of your choice, provided that    }\n{ you also meet, for each linked independent module,      }\n{ the terms and conditions of the license of that module. }\n{ An independent module is a module which is not derived  }\n{ from or based on this library. If you modify this       }\n{ library, you may extend this exception to your version  }\n{ of the library, but you are not obligated to do so.     }\n{ If you do not wish to do so, delete this exception      }\n{ statement from your version.                            }\n{                                                         }\n{                                                         }\n{ The project web site is located on:                     }\n{   http://zeos.firmos.at  (FORUM)                        }\n{   http://sourceforge.net/p/zeoslib/tickets/ (BUGTRACKER)}\n{   svn://svn.code.sf.net/p/zeoslib/code-0/trunk (SVN)    }\n{                                                         }\n{   http://www.sourceforge.net/projects/zeoslib.          }\n{                                                         }\n{                                                         }\n{                                 Zeos Development Group. }\n{********************************************************@}\n\n{$IFDEF LINUX}\n  {$DEFINE UNIX}\n{$ENDIF}\n\n{$IFNDEF UNIX}\n{$I ..\\Zeos.inc}\n{$ELSE}\n{$I ../Zeos.inc}\n{$ENDIF}\n"
  },
  {
    "path": "lib/zeosdbo/src/parsesql/ZPostgreSqlAnalyser.pas",
    "content": "{*********************************************************}\n{                                                         }\n{                 Zeos Database Objects                   }\n{            SQL Statements Analysing classes             }\n{                                                         }\n{         Originally written by Sergey Seroukhov          }\n{                                                         }\n{*********************************************************}\n\n{@********************************************************}\n{    Copyright (c) 1999-2012 Zeos Development Group       }\n{                                                         }\n{ License Agreement:                                      }\n{                                                         }\n{ This library is distributed in the hope that it will be }\n{ useful, but WITHOUT ANY WARRANTY; without even the      }\n{ implied warranty of MERCHANTABILITY or FITNESS FOR      }\n{ A PARTICULAR PURPOSE.  See the GNU Lesser General       }\n{ Public License for more details.                        }\n{                                                         }\n{ The source code of the ZEOS Libraries and packages are  }\n{ distributed under the Library GNU General Public        }\n{ License (see the file COPYING / COPYING.ZEOS)           }\n{ with the following  modification:                       }\n{ As a special exception, the copyright holders of this   }\n{ library give you permission to link this library with   }\n{ independent modules to produce an executable,           }\n{ regardless of the license terms of these independent    }\n{ modules, and to copy and distribute the resulting       }\n{ executable under terms of your choice, provided that    }\n{ you also meet, for each linked independent module,      }\n{ the terms and conditions of the license of that module. }\n{ An independent module is a module which is not derived  }\n{ from or based on this library. If you modify this       }\n{ library, you may extend this exception to your version  }\n{ of the library, but you are not obligated to do so.     }\n{ If you do not wish to do so, delete this exception      }\n{ statement from your version.                            }\n{                                                         }\n{                                                         }\n{ The project web site is located on:                     }\n{   http://zeos.firmos.at  (FORUM)                        }\n{   http://sourceforge.net/p/zeoslib/tickets/ (BUGTRACKER)}\n{   svn://svn.code.sf.net/p/zeoslib/code-0/trunk (SVN)    }\n{                                                         }\n{   http://www.sourceforge.net/projects/zeoslib.          }\n{                                                         }\n{                                                         }\n{                                 Zeos Development Group. }\n{********************************************************@}\n\nunit ZPostgreSqlAnalyser;\n\ninterface\n\n{$I ZParseSql.inc}\n\nuses Classes, ZGenericSqlAnalyser;\n\ntype\n\n  {** Implements an PostgreSQL statements analyser. }\n  TZPostgreSQLStatementAnalyser = class (TZGenericStatementAnalyser)\n  public\n    constructor Create;\n  end;\n\nimplementation\n\nconst\n  {** The generic constants.}\n  PostgreSQLSectionNames: array[0..12] of string = (\n    'SELECT', 'UPDATE', 'DELETE', 'INSERT', 'FROM',\n    'WHERE', 'INTO', 'GROUP*BY', 'HAVING', 'ORDER*BY',\n    'FOR*UPDATE', 'LIMIT', 'OFFSET'\n  );\n  PostgreSQLSelectOptions: array[0..1] of string = (\n    'DISTINCT', 'ALL'\n  );\n  PostgreSQLFromJoins: array[0..7] of string = (\n    'NATURAL', 'RIGHT', 'LEFT', 'INNER', 'OUTER', 'JOIN',\n    'FULL', 'CROSS'\n  );\n  PostgreSQLFromClauses: array[0..1] of string = (\n    'ON', 'USING'\n  );\n\n{ TZPostgreSQLStatementAnalyser }\n\n{**\n  Creates the object and assignes the main properties.\n}\nconstructor TZPostgreSQLStatementAnalyser.Create;\nbegin\n  SectionNames := ArrayToStrings(PostgreSQLSectionNames);\n  SelectOptions := ArrayToStrings(PostgreSQLSelectOptions);\n  FromJoins := ArrayToStrings(PostgreSQLFromJoins);\n  FromClauses := ArrayToStrings(PostgreSQLFromClauses);\nend;\n\nend.\n \n"
  },
  {
    "path": "lib/zeosdbo/src/parsesql/ZPostgreSqlToken.pas",
    "content": "{*********************************************************}\n{                                                         }\n{                 Zeos Database Objects                   }\n{        String tokenizing classes for PostgreSQL         }\n{                                                         }\n{        Originally written by Sergey Seroukhov           }\n{                                                         }\n{*********************************************************}\n\n{@********************************************************}\n{    Copyright (c) 1999-2012 Zeos Development Group       }\n{                                                         }\n{ License Agreement:                                      }\n{                                                         }\n{ This library is distributed in the hope that it will be }\n{ useful, but WITHOUT ANY WARRANTY; without even the      }\n{ implied warranty of MERCHANTABILITY or FITNESS FOR      }\n{ A PARTICULAR PURPOSE.  See the GNU Lesser General       }\n{ Public License for more details.                        }\n{                                                         }\n{ The source code of the ZEOS Libraries and packages are  }\n{ distributed under the Library GNU General Public        }\n{ License (see the file COPYING / COPYING.ZEOS)           }\n{ with the following  modification:                       }\n{ As a special exception, the copyright holders of this   }\n{ library give you permission to link this library with   }\n{ independent modules to produce an executable,           }\n{ regardless of the license terms of these independent    }\n{ modules, and to copy and distribute the resulting       }\n{ executable under terms of your choice, provided that    }\n{ you also meet, for each linked independent module,      }\n{ the terms and conditions of the license of that module. }\n{ An independent module is a module which is not derived  }\n{ from or based on this library. If you modify this       }\n{ library, you may extend this exception to your version  }\n{ of the library, but you are not obligated to do so.     }\n{ If you do not wish to do so, delete this exception      }\n{ statement from your version.                            }\n{                                                         }\n{                                                         }\n{ The project web site is located on:                     }\n{   http://zeos.firmos.at  (FORUM)                        }\n{   http://sourceforge.net/p/zeoslib/tickets/ (BUGTRACKER)}\n{   svn://svn.code.sf.net/p/zeoslib/code-0/trunk (SVN)    }\n{                                                         }\n{   http://www.sourceforge.net/projects/zeoslib.          }\n{                                                         }\n{                                                         }\n{                                 Zeos Development Group. }\n{********************************************************@}\n\nunit ZPostgreSqlToken;\n\ninterface\n\n{$I ZParseSql.inc}\n\nuses\n  Classes, {$IFDEF MSEgui}mclasses,{$ENDIF} SysUtils,\n  ZTokenizer, ZGenericSqlToken, ZMySqlToken;\n\ntype\n\n  {** Implements a PostgreSQL-specific number state object. }\n  TZPostgreSQLNumberState = class (TZNumberState)\n  public\n    function NextToken(Stream: TStream; FirstChar: Char;\n      Tokenizer: TZTokenizer): TZToken; override;\n  end;\n\n  {** Implements a PostgreSQL-specific quote string state object. }\n  TZPostgreSQLQuoteState = class (TZMySQLQuoteState)\n  private\n    FStandardConformingStrings: Boolean;\n  protected\n    function GetModifier(Stream: TStream; FirstChar: Char; ResetPosition: Boolean = True): string;\n    function GetDollarQuotedString(Stream: TStream; QuoteChar: Char): string;\n    function GetQuotedString(Stream: TStream; QuoteChar: Char; EscapeSyntax: Boolean): String;\n    function GetQuotedStringWithModifier(Stream: TStream; FirstChar: Char): string;\n  public\n    function NextToken(Stream: TStream; FirstChar: Char;\n      Tokenizer: TZTokenizer): TZToken; override;\n    procedure SetStandardConformingStrings(const Value: Boolean);\n  end;\n\n  {**\n    This state will either delegate to a comment-handling\n    state, or return a token with just a slash in it.\n  }\n  TZPostgreSQLCommentState = class (TZCppCommentState)\n  protected\n    function GetMultiLineComment(Stream: TStream): string; override;\n  public\n    function NextToken(Stream: TStream; FirstChar: Char;\n      Tokenizer: TZTokenizer): TZToken; override;\n  end;\n\n  {** Implements a symbol state object. }\n  TZPostgreSQLSymbolState = class (TZSymbolState)\n  public\n    constructor Create;\n  end;\n\n  {** Implements a word state object. }\n  TZPostgreSQLWordState = class (TZGenericSQLWordState)\n  public\n    constructor Create;\n  end;\n\n  IZPostgreSQLTokenizer = interface (IZTokenizer)\n    ['{82392175-9065-4048-9974-EE1253B921B4}']\n    procedure SetStandardConformingStrings(const Value: Boolean);\n  end;\n\n  {** Implements a default tokenizer object. }\n  TZPostgreSQLTokenizer = class (TZTokenizer, IZPostgreSQLTokenizer)\n  protected\n    function CheckEscapeState(const ActualState: TZTokenizerState; Stream: TStream;\n        const FirstChar: Char): TZTokenizerState; override;\n  public\n    procedure SetStandardConformingStrings(const Value: Boolean);\n    constructor Create;\n  end;\n\nimplementation\n\nuses ZCompatibility;\n\nconst\n  NameQuoteChar   = Char('\"');\n  DollarQuoteChar = Char('$');\n  SingleQuoteChar = Char('''');\n\n{ TZPostgreSQLNumberState }\n\n{**\n  Return a number token from a reader.\n  @return a number token from a reader\n}\nfunction TZPostgreSQLNumberState.NextToken(Stream: TStream; FirstChar: Char;\n  Tokenizer: TZTokenizer): TZToken;\nvar\n  TempChar: Char;\n  FloatPoint: Boolean;\n  LastChar: Char;\n\n  function ReadDecDigits: string;\n  begin\n    Result := '';\n    LastChar := #0;\n    while Stream.Read(LastChar, SizeOf(Char)) > 0 do\n    begin\n      if CharInSet(LastChar, ['0'..'9']) then\n      begin\n        Result := Result + LastChar;\n        LastChar := #0;\n      end\n      else\n      begin\n        Stream.Seek(-SizeOf(Char), soFromCurrent);\n        Break;\n      end;\n    end;\n  end;\n\nbegin\n  FloatPoint := FirstChar = '.';\n  Result.Value := FirstChar;\n  Result.TokenType := ttUnknown;\n  LastChar := #0;\n\n  { Reads the first part of the number before decimal point }\n  if not FloatPoint then\n  begin\n    Result.Value := Result.Value + ReadDecDigits;\n    FloatPoint := LastChar = '.';\n    if FloatPoint then\n    begin\n      Stream.Read(TempChar, SizeOf(Char));\n      Result.Value := Result.Value + TempChar;\n    end;\n  end;\n\n  { Reads the second part of the number after decimal point }\n  if FloatPoint then\n    Result.Value := Result.Value + ReadDecDigits;\n\n  { Reads a power part of the number }\n  if CharInSet(LastChar, ['e','E']) then\n  begin\n    Stream.Read(TempChar, SizeOf(Char));\n    Result.Value := Result.Value + TempChar;\n    FloatPoint := True;\n\n    Stream.Read(TempChar, SizeOf(Char));\n    if CharInSet(TempChar, ['0'..'9','-','+']) then\n      Result.Value := Result.Value + TempChar + ReadDecDigits\n    else\n    begin\n      Result.Value := Copy(Result.Value, 1, Length(Result.Value) - 1);\n      Stream.Seek(-2*SizeOf(Char), soFromCurrent);\n    end;\n  end;\n\n  { Prepare the result }\n  if Result.Value = '.' then\n  begin\n    if Tokenizer.SymbolState <> nil then\n      Result := Tokenizer.SymbolState.NextToken(Stream, FirstChar, Tokenizer);\n  end\n  else\n  begin\n    if FloatPoint then\n      Result.TokenType := ttFloat\n    else Result.TokenType := ttInteger;\n  end;\nend;\n\n{ TZPostgreSQLQuoteState }\n\n{**\n  Retrieves string modifier from quoted string.\n  @return a string with modifier for valid quoted string with modifier\n  or empty string otherwise.\n}\nfunction TZPostgreSQLQuoteState.GetModifier(Stream: TStream;\n    FirstChar: Char; ResetPosition: boolean = True): string;\nvar\n  ReadChar: Char;\n  Modifier: string;\n  ReadNum: Integer;\nbegin\n  Result := '';\n  if CharInSet(FirstChar, ['E', 'e', 'B', 'b', 'X', 'x', 'U', 'u']) then\n  begin\n    Modifier := FirstChar;\n    ReadNum := Stream.Read(ReadChar, SizeOf(Char));\n    if ReadNum = SizeOf(Char) then\n    begin\n      if (UpperCase(FirstChar) = 'U') and (ReadChar = '&') then // Check for U& modifier\n      begin\n        Modifier := Modifier + ReadChar;\n        ReadNum := ReadNum + Stream.Read(ReadChar, SizeOf(Char));\n      end;\n\n      if (ReadChar = SingleQuoteChar) then\n         Result := Modifier;\n\n      if ResetPosition then\n        Stream.Seek(-ReadNum, soFromCurrent);\n    end;\n  end;\nend;\n\n{**\n  Returns a quoted string token from a reader. This method\n  will get Tag from first char to QuoteChar and will collect\n  characters until reaches same Tag.\n\n  @return a quoted string token from a reader\n}\nfunction TZPostgreSQLQuoteState.GetDollarQuotedString(Stream: TStream; QuoteChar: Char): string;\nvar\n  ReadChar: Char;\n  Tag, TempTag: string;\n  TagState: integer;\nbegin\n  Result := QuoteChar;\n  TagState := 0;\n  while Stream.Read(ReadChar, SizeOf(Char)) > 0 do\n  begin\n    if (ReadChar = QuoteChar) then\n    begin\n      if (TagState = 0) then\n      begin\n        TagState := 1;\n        Tag := Result;\n      end\n      else if (TagState = 1) then\n      begin\n        TagState := 2;\n        TempTag := '';\n      end\n      else if (TagState = 2) then\n      begin\n        if TempTag = Tag then\n          TagState := 3\n        else\n          TempTag := '';\n      end;\n    end;\n\n    Result := Result + ReadChar;\n\n    if TagState = 2 then\n      TempTag := TempTag + ReadChar\n    else if TagState = 3 then\n      Break;\n  end;\nend;\n\n{**\n  Returns a quoted string token from a reader. This method\n  will collect characters until it sees same QuoteChar,\n  ommitting doubled chars\n\n  @return a quoted string token from a reader\n}\nfunction TZPostgreSQLQuoteState.GetQuotedString(Stream: TStream; QuoteChar: Char;\n  EscapeSyntax: Boolean): String;\nconst BackSlash = Char('\\');\nvar\n  ReadChar: Char;\n  LastChar: Char;\n  QuoteCount: Integer;\nbegin\n  LastChar := #0;\n  Result := QuoteChar;\n  QuoteCount := 1;\n\n  while Stream.Read(ReadChar, SizeOf(Char)) > 0 do\n  begin\n    if ReadChar = QuoteChar then\n      Inc(QuoteCount);\n\n    if (LastChar = QuoteChar) and (ReadChar <> QuoteChar) then\n    begin\n      if QuoteCount mod 2 = 0 then\n      begin\n        Stream.Seek(-SizeOf(Char), soFromCurrent);\n        Break;\n      end;\n    end;\n    Result := Result + ReadChar;\n    if (LastChar = BackSlash) and EscapeSyntax then\n      LastChar := #0\n    else if (LastChar = QuoteChar) and (ReadChar = QuoteChar) then\n      LastChar := #0\n    else LastChar := ReadChar;\n  end;\nend;\n\n{**\n  Returns a quoted string token with leading modifier from a reader.\n\n  @return a quoted string token from a reader\n}\nfunction TZPostgreSQLQuoteState.GetQuotedStringWithModifier(Stream: TStream;\n    FirstChar: Char): string;\nvar\n  Modifier: string;\n  EscapeSyntax: Boolean;\nbegin\n  Modifier := GetModifier(Stream, FirstChar, False);\n  if (Modifier <> '') then\n    FirstChar := SingleQuoteChar;\n  EscapeSyntax := (not FStandardConformingStrings and (Modifier = '')) or\n    (UpperCase(Modifier) = 'E');\n  Result := Modifier + GetQuotedString(Stream, FirstChar, EscapeSyntax);\nend;\n\n{**\n  Return a quoted string token from a reader. This method\n  will collect characters until it sees a match to the\n  character that the tokenizer used to switch to this state.\n\n  @return a quoted string token from a reader\n}\nfunction TZPostgreSQLQuoteState.NextToken(Stream: TStream;\n  FirstChar: Char; Tokenizer: TZTokenizer): TZToken;\nbegin\n  Result.Value := FirstChar;\n  if FirstChar = NameQuoteChar then\n  begin\n    Result.TokenType := ttWord;\n    Result.Value := GetQuotedString(Stream, FirstChar, False);\n  end\n  else if FirstChar = DollarQuoteChar then\n  begin\n    Result.TokenType := ttQuoted;\n    Result.Value := GetDollarQuotedString(Stream, FirstChar);\n  end\n  else\n  begin\n    Result.TokenType := ttQuoted;\n    Result.Value := GetQuotedStringWithModifier(Stream, FirstChar);\n  end;\nend;\n\n{**\n  Sets how backslashes in quoted strings are handled\n  @param True means backslashes are escape characters\n}\nprocedure TZPostgreSQLQuoteState.SetStandardConformingStrings(const Value:\n    Boolean);\nbegin\n  FStandardConformingStrings := Value;\nend;\n\n{ TZPostgreSQLCommentState }\n\n{**\n  Ignore everything up to a last closing star and slash, and\n  then return the tokenizer's next token.\n  @return the tokenizer's next token\n}\nfunction TZPostgreSQLCommentState.GetMultiLineComment(Stream: TStream): string;\nvar\n  ReadChar, LastChar: Char;\n  NestedLevel: Integer;\nbegin\n  LastChar := #0;\n  NestedLevel := 1;\n  Result := '';\n  while Stream.Read(ReadChar, 1 * SizeOf(Char)) > 0 do\n  begin\n    Result := Result + ReadChar;\n    if (LastChar = '*') and (ReadChar = '/') then\n    begin\n      Dec(NestedLevel);\n      if NestedLevel = 0 then\n        Break;\n    end;\n    if (LastChar = '/') and (ReadChar = '*') then\n      Inc(NestedLevel);\n    LastChar := ReadChar;\n  end;\nend;\n\n{**\n  Gets a PostgreSQL specific comments like -- or /* */.\n  @return either just a slash token, or the results of\n    delegating to a comment-handling state\n}\nfunction TZPostgreSQLCommentState.NextToken(Stream: TStream;\n  FirstChar: Char; Tokenizer: TZTokenizer): TZToken;\nvar\n  ReadChar: Char;\n  ReadNum: Integer;\nbegin\n  Result.TokenType := ttUnknown;\n  Result.Value := FirstChar;\n\n  if FirstChar = '-' then\n  begin\n    ReadNum := Stream.Read(ReadChar, SizeOf(Char));\n    if (ReadNum > 0) and (ReadChar = '-') then\n    begin\n      Result.TokenType := ttComment;\n      Result.Value := '--' + GetSingleLineComment(Stream);\n    end\n    else\n    begin\n      if ReadNum > 0 then\n        Stream.Seek(-SizeOf(Char), soFromCurrent);\n    end;\n  end\n  else if FirstChar = '/' then\n  begin\n    ReadNum := Stream.Read(ReadChar, SizeOf(Char));\n    if (ReadNum > 0) and (ReadChar = '*') then\n    begin\n      Result.TokenType := ttComment;\n      Result.Value := '/*' + GetMultiLineComment(Stream);\n    end\n    else\n    begin\n      if ReadNum > 0 then\n        Stream.Seek(-SizeOf(Char), soFromCurrent);\n    end;\n  end;\n\n  if (Result.TokenType = ttUnknown) and (Tokenizer.SymbolState <> nil) then\n    Result := Tokenizer.SymbolState.NextToken(Stream, FirstChar, Tokenizer);\nend;\n\n{ TZPostgreSQLSymbolState }\n\n{**\n  Creates this PostgreSQL-specific symbol state object.\n}\nconstructor TZPostgreSQLSymbolState.Create;\nbegin\n  inherited Create;\n  Add('<=');\n  Add('>=');\n  Add('<>');\n  Add('<<');\n  Add('>>');\n  Add('~*');\n  Add('!~');\n  Add('!~*');\nend;\n\n{ TZPostgreSQLWordState }\n\n{**\n  Constructs this PostgreSQL-specific word state object.\n}\nconstructor TZPostgreSQLWordState.Create;\nbegin\n  SetWordChars(#0, #191, False);\n  SetWordChars(#192, high(char), True);\n  SetWordChars('a', 'z', True);\n  SetWordChars('A', 'Z', True);\n  SetWordChars('0', '9', True);\n  SetWordChars('_', '_', True);\n  SetWordChars('$', '$', True);\nend;\n\n{**\n  informs the Postgre Tokenizer '\\' should be handled as Escape-char\n  @param True means backslashes are quoted strings\n}\nprocedure TZPostgreSQLTokenizer.SetStandardConformingStrings(\n  const Value: Boolean);\nbegin\n  (QuoteState as TZPostgreSQLQuoteState).SetStandardConformingStrings(Value);\nend;\n\n{**\n  Constructs a tokenizer with a default state table (as\n  described in the class comment).\n}\nconstructor TZPostgreSQLTokenizer.Create;\nbegin\n  EscapeState := TZEscapeState.Create;\n  WhitespaceState := TZWhitespaceState.Create;\n\n  SymbolState := TZPostgreSQLSymbolState.Create;\n  NumberState := TZPostgreSQLNumberState.Create;\n  QuoteState := TZPostgreSQLQuoteState.Create;\n  WordState := TZPostgreSQLWordState.Create;\n  CommentState := TZPostgreSQLCommentState.Create;\n\n  SetCharacterState(#0, #32, WhitespaceState);\n  SetCharacterState(#33, #191, SymbolState);\n  SetCharacterState(#192, High(Char), WordState);\n\n  SetCharacterState('a', 'z', WordState);\n  SetCharacterState('A', 'Z', WordState);\n  SetCharacterState('_', '_', WordState);\n\n  SetCharacterState('0', '9', NumberState);\n  SetCharacterState('.', '.', NumberState);\n\n  SetCharacterState(NameQuoteChar, NameQuoteChar, QuoteState);\n  SetCharacterState(SingleQuoteChar, SingleQuoteChar, QuoteState);\n  SetCharacterState(DollarQuoteChar, DollarQuoteChar, QuoteState);\n\n  SetCharacterState('/', '/', CommentState);\n  SetCharacterState('-', '-', CommentState);\nend;\n\n{**\n  Checks if WordState is QuoteState with modifier and sets QuoteState.\n  @param Stream the Read-Stream which has to checked for Next-Chars.\n  @FirstChar The FirstChar which was readed and sets the Symbolstate\n  @returns either the given SymbolState or the QuoteState\n}\nfunction TZPostgreSQLTokenizer.CheckEscapeState(const ActualState:\n    TZTokenizerState; Stream: TStream; const FirstChar: Char): TZTokenizerState;\nvar\n  Modifier: string;\nbegin\n  Result := inherited CheckEscapeState(ActualState, Stream, FirstChar);\n  if (Result is TZWordState) then\n  begin\n    Modifier := (QuoteState as TZPostgreSQLQuoteState).GetModifier(Stream, FirstChar);\n    if (Modifier <> '') then\n      Result := QuoteState;\n  end;\nend;\n\nend.\n\n"
  },
  {
    "path": "lib/zeosdbo/src/parsesql/ZScriptParser.pas",
    "content": "{*********************************************************}\n{                                                         }\n{                     Zeos SQL Shell                      }\n{                 Script Parsing Classes                  }\n{                                                         }\n{         Originally written by Sergey Seroukhov          }\n{                                                         }\n{*********************************************************}\n\n{@********************************************************}\n{    Copyright (c) 1999-2012 Zeos Development Group       }\n{                                                         }\n{ License Agreement:                                      }\n{                                                         }\n{ This library is distributed in the hope that it will be }\n{ useful, but WITHOUT ANY WARRANTY; without even the      }\n{ implied warranty of MERCHANTABILITY or FITNESS FOR      }\n{ A PARTICULAR PURPOSE.  See the GNU Lesser General       }\n{ Public License for more details.                        }\n{                                                         }\n{ The source code of the ZEOS Libraries and packages are  }\n{ distributed under the Library GNU General Public        }\n{ License (see the file COPYING / COPYING.ZEOS)           }\n{ with the following  modification:                       }\n{ As a special exception, the copyright holders of this   }\n{ library give you permission to link this library with   }\n{ independent modules to produce an executable,           }\n{ regardless of the license terms of these independent    }\n{ modules, and to copy and distribute the resulting       }\n{ executable under terms of your choice, provided that    }\n{ you also meet, for each linked independent module,      }\n{ the terms and conditions of the license of that module. }\n{ An independent module is a module which is not derived  }\n{ from or based on this library. If you modify this       }\n{ library, you may extend this exception to your version  }\n{ of the library, but you are not obligated to do so.     }\n{ If you do not wish to do so, delete this exception      }\n{ statement from your version.                            }\n{                                                         }\n{                                                         }\n{ The project web site is located on:                     }\n{   http://zeos.firmos.at  (FORUM)                        }\n{   http://sourceforge.net/p/zeoslib/tickets/ (BUGTRACKER)}\n{   svn://svn.code.sf.net/p/zeoslib/code-0/trunk (SVN)    }\n{                                                         }\n{   http://www.sourceforge.net/projects/zeoslib.          }\n{                                                         }\n{                                                         }\n{                                 Zeos Development Group. }\n{********************************************************@}\n\nunit ZScriptParser;\n\ninterface\n\n{$I ZParseSql.inc}\n\nuses Classes, {$IFDEF MSEgui}mclasses,{$ENDIF} SysUtils,\n  ZTokenizer;\n\ntype\n  {** Defines a SQL delimiter type. }\n  TZDelimiterType = (dtDefault, dtDelimiter, dtGo, dtSetTerm, dtEmptyLine);\n\n  {** Implements a SQL script parser. }\n  TZSQLScriptParser = class\n  private\n    FDelimiter: string;\n    FDelimiterType: TZDelimiterType;\n    FCleanupStatements: Boolean;\n    FTokenizer: IZTokenizer;\n    FUncompletedStatement: string;\n    FStatements: TStrings;\n\n    function GetStatementCount: Integer;\n    function GetStatement(Index: Integer): string;\n\n  public\n    constructor Create;\n    constructor CreateWithTokenizer(Tokenizer: IZTokenizer);\n    destructor Destroy; override;\n\n    procedure Clear;\n    procedure ClearCompleted;\n    procedure ClearUncompleted;\n\n    procedure ParseText(const Text: string);\n    procedure ParseLine(const Line: string);\n\n    property Delimiter: string read FDelimiter write FDelimiter;\n    property DelimiterType: TZDelimiterType read FDelimiterType\n      write FDelimiterType default dtDefault;\n    property CleanupStatements: Boolean read FCleanupStatements\n      write FCleanupStatements default True;\n    property Tokenizer: IZTokenizer read FTokenizer write FTokenizer;\n    property UncompletedStatement: string read FUncompletedStatement;\n    property StatementCount: Integer read GetStatementCount;\n    property Statements[Index: Integer]: string read GetStatement;\n  end;\n\nimplementation\n\nuses ZMessages, ZSysUtils;\n\n{ TZSQLScriptParser }\n\n{**\n  Constructs this script parser class.\n}\nconstructor TZSQLScriptParser.Create;\nbegin\n  FStatements := TStringList.Create;\n  FDelimiter := ';';\n  FDelimiterType := dtDefault;\n  FCleanupStatements := True;\nend;\n\n{**\n  Creates this object and assignes a tokenizer object.\n  @param Tokenizer a tokenizer object.\n}\nconstructor TZSQLScriptParser.CreateWithTokenizer(Tokenizer: IZTokenizer);\nbegin\n  Create;\n  FTokenizer := Tokenizer;\nend;\n\n{**\n  Destroys this class and cleanups the memory.\n}\ndestructor TZSQLScriptParser.Destroy;\nbegin\n  FreeAndNil(FStatements);\n  FTokenizer := nil;\n  inherited Destroy;\nend;\n\n{**\n  Gets SQL statements number.\n  @returns SQL statements number.\n}\nfunction TZSQLScriptParser.GetStatementCount: Integer;\nbegin\n  Result := FStatements.Count;\nend;\n\n{**\n  Gets a parsed SQL statement by it's index.\n  @param Index a statement index.\n  @returns a SQL statement string.\n}\nfunction TZSQLScriptParser.GetStatement(Index: Integer): string;\nbegin\n  Result := FStatements[Index];\nend;\n\n{**\n  Clears all completed and uncompleted statements and line delimiter.\n}\nprocedure TZSQLScriptParser.Clear;\nbegin\n  FStatements.Clear;\n  FDelimiter := ';';\n  FUncompletedStatement := '';\nend;\n\n{**\n  Clears only completed statements.\n}\nprocedure TZSQLScriptParser.ClearCompleted;\nbegin\n  FStatements.Clear;\nend;\n\n{**\n  Clears completed and uncompleted statements.\n}\nprocedure TZSQLScriptParser.ClearUncompleted;\nbegin\n  FStatements.Clear;\n  FUncompletedStatement := '';\nend;\n\n{**\n  Parses incrementaly only one single line.\n  The line appends with EOL character.\n  @param Line a line to be parsed.\n}\nprocedure TZSQLScriptParser.ParseLine(const Line: string);\nbegin\n  ParseText(#10 + Line + #10);\nend;\n\n{**\n  Parses a complete text with several lines.\n  @oaram Text a text of the SQL script to be parsed.\n}\nprocedure TZSQLScriptParser.ParseText(const Text: string);\nconst SetTerm = String('SET TERM ');\nvar\n  Tokens: TStrings;\n  TokenType: TZTokenType;\n  TokenValue: string;\n  TokenIndex, LastStmtEndingIndex, iPos: Integer;\n  SQL, Temp: string;\n  EndOfStatement: Boolean;\n  Extract: Boolean;\n  LastComment: String;\n\n  function CountChars(const Str: string; Chr: Char): Integer;\n  var\n    I: Integer;\n  begin\n    Result := 0;\n    for I := 1 to Length(Str) do\n    begin\n      if Str[I] = Chr then\n        Inc(Result);\n    end;\n  end;\n\n  procedure SetNextToken;\n  begin\n    TokenValue := Tokens[TokenIndex];\n    TokenType := TZTokenType({$IFDEF FPC}Pointer({$ENDIF}\n      Tokens.Objects[TokenIndex]{$IFDEF FPC}){$ENDIF});\n    if TokenValue = Delimiter  then\n      LastStmtEndingIndex := TokenIndex;\n    Inc(TokenIndex);\n  end;\n\nbegin\n  if Tokenizer = nil then\n    raise Exception.Create(STokenizerIsNotDefined);\n\n  if CleanupStatements then\n    Tokens := Tokenizer.TokenizeBufferToList(Text, [toSkipComments])\n  else Tokens := Tokenizer.TokenizeBufferToList(Text, []);\n\n  if ( (DelimiterType = dtDelimiter) or\n       (DelimiterType = dtSetTerm) ) and\n     ( Delimiter = '' ) then\n    Delimiter := ';'; //use default delimiter\n\n  if (DelimiterType = dtDefault) then\n    Delimiter := ';'; //use default delimiter\n\n  TokenIndex := 0;\n  SQL := FUncompletedStatement;\n  if SQL <> '' then\n  begin\n    if CleanupStatements then\n      SQL := SQL + ' '\n    else SQL := SQL + #10;\n  end;\n  FUncompletedStatement := '';\n  FStatements.Clear;\n  try\n    repeat\n      SetNextToken;\n\n      case DelimiterType of\n        dtGo:\n          EndOfStatement := (UpperCase(TokenValue) = 'GO');\n        dtEmptyLine:\n          begin\n            EndOfStatement := False;\n            if TokenType = ttWhitespace then\n            begin\n              Temp := TokenValue;\n              while (CountChars(Temp, #10) < 2) and (TokenType = ttWhitespace) do\n              begin\n                SetNextToken;\n                if TokenType = ttWhitespace then\n                  Temp := Temp + TokenValue;\n              end;\n              EndOfStatement := (TokenType = ttWhitespace) or EndsWith(Sql, #10);\n              if not EndOfStatement then\n              begin\n                if SQL <> '' then\n                  SQL := Trim(SQL) + ' ';\n              end;\n            end;\n          end;\n        dtDelimiter,\n        dtDefault,\n        dtSetTerm:\n          begin\n            EndOfStatement := False;\n            if not (TokenType in [ttWhitespace, ttEOF]) then\n            begin\n              if (DelimiterType = dtDelimiter) and (Uppercase(TokenValue) = 'DELIMITER') then\n              begin\n                Delimiter := '';\n                Temp := TokenValue; {process the DELIMITER}\n                Temp := Temp + Tokens[TokenIndex]; {process the first ' ' char}\n                Inc(TokenIndex);\n                while TokenType <> ttWhitespace do\n                begin\n                  SetNextToken;\n                  if not (TokenType in [ttWhitespace, ttEOF]) then\n                    Delimiter := Delimiter + TokenValue; //get the new delimiter\n                end;\n                SQL := SQL + Temp + Delimiter;\n                EndOfStatement := True;\n              end\n              else\n              begin\n                Temp := TokenValue;\n                Extract := True;\n                while (Delimiter[1]=Temp[1]) and\n                      (Length(Delimiter) > Length(Temp))\n                       and not (TokenType in [ttWhitespace, ttEOF]) do\n                begin\n                  SetNextToken;\n\n                  if not (TokenType in [ttWhitespace, ttEOF]) then\n                  begin\n                    Temp := Temp + TokenValue;\n                    Extract := True;\n                  end else\n                    Extract := False;\n                end;\n                EndOfStatement := (Delimiter = Temp);\n                if not EndOfStatement then\n                begin\n                  if Extract then\n                    Temp := Copy(Temp, 1, Length(Temp) - Length(TokenValue));\n                  SQL := SQL + Temp;\n                end;\n              end;\n            end;\n          end;\n        else\n          EndOfStatement := False;\n      end;\n\n      if TokenType = ttEOF then Break;\n\n      { Processes the end of statements. }\n      if EndOfStatement then\n      begin\n        if CleanupStatements then\n          SQL := Trim(SQL);\n        if SQL <> '' then\n        begin\n          if not CleanupStatements then\n            Temp := Trim(SQL)\n          else Temp := SQL;\n          if (DelimiterType = dtSetTerm) and StartsWith(UpperCase(Temp), SetTerm) then\n              Delimiter := Copy(Temp, 10, Length(Temp) - 9)\n            else\n              if (DelimiterType = dtSetTerm) and ( Pos(SetTerm, UpperCase(Temp)) > 0) then\n              begin\n                iPos := Pos(SetTerm, UpperCase(Temp))+8;\n                Delimiter := Copy(Temp, iPos+1, Length(Temp) - iPos);\n                LastComment := TrimRight(Copy(Temp, 1, iPos-9));\n              end\n              else\n                if (DelimiterType = dtDelimiter)\n                  and StartsWith(UpperCase(Temp), 'DELIMITER ') then\n                  Delimiter := Copy(Temp, 11, Length(Temp) - 10)\n                else\n                begin\n                  if (DelimiterType = dtEmptyLine) and EndsWith(SQL, ';') then\n                    SQL := Copy(SQL, 1, Length(SQL) - 1);\n                  if LastComment <> '' then\n                    SQL := LastComment+#13#10+SQL;\n                  if CleanupStatements then\n                    SQL := Trim(SQL);\n                  FStatements.Add(SQL);\n                  LastComment := '';\n                end;\n        end;\n        SQL := '';\n      end\n      { Adds a whitespace token. }\n      else if CleanupStatements and (TokenType = ttWhitespace) then\n      begin\n        if SQL <> '' then\n          SQL := Trim(SQL) + ' ';\n      end\n      { Adds a default token. }\n      else\n      begin\n        // --> ms, 20/10/2005\n        // TokenValue is not a ttWhitespace (#32)\n        if (TokenType = ttWhitespace) and (TokenValue > '') then begin\n          // SQL is not emtyp\n          if (SQL <> '') then begin\n            // is last token:\n            if (Tokenindex = Tokens.count-1) then\n              TokenValue := '';\n            // next(!) token is also ttWhitespace or delimiter\n            // (TokenIndex was already incremented!)\n            if (Tokenindex < Tokens.count-1) then\n              if ((TZTokenType({$IFDEF FPC}Pointer({$ENDIF}\n                Tokens.Objects[TokenIndex]{$IFDEF FPC}){$ENDIF}) = ttWhitespace) or\n                (Tokens[TokenIndex] = Delimiter))  then\n                TokenValue := '';\n          end\n          // SQL is empty\n          else\n            TokenValue := '';\n        end;\n        if ((SQL = '') and (trim(TokenValue) = '')) then\n          TokenValue := '';\n        // <-- ms\n        SQL := SQL + TokenValue;\n      end;\n    until TokenType = ttEOF;\n    if ( LastComment <> '' ) and ( FStatements.Count > 0) then\n      if CleanupStatements then\n        FStatements[FStatements.Count-1] := FStatements[FStatements.Count-1]+' '+Trim(LastComment)\n      else\n        FStatements[FStatements.Count-1] := FStatements[FStatements.Count-1]+#13#10+LastComment;\n  finally\n    Tokens.Free;\n  end;\n\n  if CleanupStatements then\n    SQL := Trim(SQL);\n  if SQL <> '' then\n    FUncompletedStatement := SQL;\nend;\n\nend.\n"
  },
  {
    "path": "lib/zeosdbo/src/parsesql/ZSelectSchema.pas",
    "content": "{*********************************************************}\n{                                                         }\n{                 Zeos Database Objects                   }\n{        SQL Select Objects and Assembler classes         }\n{                                                         }\n{        Originally written by Sergey Seroukhov           }\n{                                                         }\n{*********************************************************}\n\n{@********************************************************}\n{    Copyright (c) 1999-2012 Zeos Development Group       }\n{                                                         }\n{ License Agreement:                                      }\n{                                                         }\n{ This library is distributed in the hope that it will be }\n{ useful, but WITHOUT ANY WARRANTY; without even the      }\n{ implied warranty of MERCHANTABILITY or FITNESS FOR      }\n{ A PARTICULAR PURPOSE.  See the GNU Lesser General       }\n{ Public License for more details.                        }\n{                                                         }\n{ The source code of the ZEOS Libraries and packages are  }\n{ distributed under the Library GNU General Public        }\n{ License (see the file COPYING / COPYING.ZEOS)           }\n{ with the following  modification:                       }\n{ As a special exception, the copyright holders of this   }\n{ library give you permission to link this library with   }\n{ independent modules to produce an executable,           }\n{ regardless of the license terms of these independent    }\n{ modules, and to copy and distribute the resulting       }\n{ executable under terms of your choice, provided that    }\n{ you also meet, for each linked independent module,      }\n{ the terms and conditions of the license of that module. }\n{ An independent module is a module which is not derived  }\n{ from or based on this library. If you modify this       }\n{ library, you may extend this exception to your version  }\n{ of the library, but you are not obligated to do so.     }\n{ If you do not wish to do so, delete this exception      }\n{ statement from your version.                            }\n{                                                         }\n{                                                         }\n{ The project web site is located on:                     }\n{   http://zeos.firmos.at  (FORUM)                        }\n{   http://sourceforge.net/p/zeoslib/tickets/ (BUGTRACKER)}\n{   svn://svn.code.sf.net/p/zeoslib/code-0/trunk (SVN)    }\n{                                                         }\n{   http://www.sourceforge.net/projects/zeoslib.          }\n{                                                         }\n{                                                         }\n{                                 Zeos Development Group. }\n{********************************************************@}\n\nunit ZSelectSchema;\n\ninterface\n\n{$I ZParseSql.inc}\n\nuses ZClasses, Contnrs, ZCompatibility\n  {$IFDEF WITH_SYSTEMCLASSES},System.Classes{$ENDIF}\n  {$IFDEF WITH_TOBJECTLIST_INLINE}, System.Types{$ENDIF};\n\ntype\n\n  {** Case Sensitive/Unsensitive identificator processor. }\n  IZIdentifierConvertor = interface (IZInterface)\n    ['{2EB07B9B-1E96-4A42-8084-6F98D9140B27}']\n\n    function IsCaseSensitive(const Value: string): Boolean;\n    function IsQuoted(const Value: string): Boolean;\n    function Quote(const Value: string): string;\n    function ExtractQuote(const Value: string): string;\n  end;\n\n  {** Implements a table reference assembly. }\n  TZTableRef = class (TObject)\n  private\n    FCatalog: string;\n    FSchema: string;\n    FTable: string;\n    FAlias: string;\n  public\n    constructor Create(const Catalog, Schema, Table, Alias: string);\n    function FullName: string;\n\n    property Catalog: string read FCatalog write FCatalog;\n    property Schema: string read FSchema write FSchema;\n    property Table: string read FTable write FTable;\n    property Alias: string read FAlias write FAlias;\n  end;\n\n  {** Implements a field reference assembly. }\n  TZFieldRef = class (TObject)\n  private\n    FIsField: Boolean;\n    FCatalog: string;\n    FSchema: string;\n    FTable: string;\n    FField: string;\n    FAlias: string;\n    FTableRef: TZTableRef;\n    FLinked: Boolean;\n  public\n    constructor Create(IsField: Boolean; const Catalog, Schema, Table,\n      Field, Alias: string; TableRef: TZTableRef);\n\n    property IsField: Boolean read FIsField write FIsField;\n    property Catalog: string read FCatalog write FCatalog;\n    property Schema: string read FSchema write FSchema;\n    property Table: string read FTable write FTable;\n    property Field: string read FField write FField;\n    property Alias: string read FAlias write FAlias;\n    property TableRef: TZTableRef read FTableRef write FTableRef;\n    property Linked: Boolean read FLinked write FLinked;\n  end;\n\n  {** Defines an interface to select assembly. }\n  IZSelectSchema = interface (IZInterface)\n    ['{3B892975-57E9-4EB7-8DB1-BDDED91E7FBC}']\n\n    procedure AddField(FieldRef: TZFieldRef);\n    procedure InsertField(Index: Integer; FieldRef: TZFieldRef);\n    procedure DeleteField(FieldRef: TZFieldRef);\n\n    procedure AddTable(TableRef: TZTableRef);\n\n    procedure LinkReferences(Convertor: IZIdentifierConvertor);\n\n    function FindTableByFullName(const Catalog, Schema, Table: string): TZTableRef;\n    function FindTableByShortName(const Table: string): TZTableRef;\n    function FindFieldByShortName(const Field: string): TZFieldRef;\n\n    function LinkFieldByIndexAndShortName(const ColumnIndex: Integer; const Field: string;\n      const Convertor: IZIdentifierConvertor): TZFieldRef;\n\n    function GetFieldCount: Integer;\n    function GetTableCount: Integer;\n    function GetField(Index: Integer): TZFieldRef;\n    function GetTable(Index: Integer): TZTableRef;\n\n    property FieldCount: Integer read GetFieldCount;\n    property Fields[Index: Integer]: TZFieldRef read GetField;\n    property TableCount: Integer read GetTableCount;\n    property Tables[Index: Integer]: TZTableRef read GetTable;\n  end;\n\n  {** Implements a select assembly. }\n  TZSelectSchema = class (TZAbstractObject, IZSelectSchema)\n  private\n    FFields: TObjectList;\n    FTables: TObjectList;\n\n    procedure ConvertIdentifiers(Convertor: IZIdentifierConvertor);\n  public\n    constructor Create;\n    destructor Destroy; override;\n\n    procedure AddField(FieldRef: TZFieldRef);\n    procedure InsertField(Index: Integer; FieldRef: TZFieldRef);\n    procedure DeleteField(FieldRef: TZFieldRef);\n\n    procedure AddTable(TableRef: TZTableRef);\n\n    procedure LinkReferences(Convertor: IZIdentifierConvertor);\n\n    function FindTableByFullName(const Catalog, Schema, Table: string): TZTableRef;\n    function FindTableByShortName(const Table: string): TZTableRef;\n    function FindFieldByShortName(const Field: string): TZFieldRef;\n\n    function LinkFieldByIndexAndShortName(const ColumnIndex: Integer; const Field: string;\n      const Convertor: IZIdentifierConvertor): TZFieldRef;\n\n    function GetFieldCount: Integer;\n    function GetTableCount: Integer;\n    function GetField(Index: Integer): TZFieldRef;\n    function GetTable(Index: Integer): TZTableRef;\n\n    property FieldCount: Integer read GetFieldCount;\n    property Fields[Index: Integer]: TZFieldRef read GetField;\n    property TableCount: Integer read GetTableCount;\n    property Tables[Index: Integer]: TZTableRef read GetTable;\n  end;\n\nimplementation\n\n{ TZTableRef }\n\n{**\n  Creates a table reference object.\n  @param Catalog a catalog name.\n  @param Schema a schema name.\n  @param Table a table name.\n  @param Alias a table alias.\n}\nconstructor TZTableRef.Create(const Catalog, Schema, Table, Alias: string);\nbegin\n  FCatalog := Catalog;\n  FSchema := Schema;\n  FTable := Table;\n  FAlias := Alias;\nend;\n\n{**\n  Gets a full database table name.\n  @return a full database table name.\n}\nfunction TZTableRef.FullName: string;\nbegin\n  Result := FCatalog + '.' + FSchema + '.' + FTable;\n  \n  while (Result <> '') and (Result[1] = '.') do\n    Delete(Result, 1, 1);\nend;\n\n{ TZFieldRef }\n\n{**\n  Creates a field reference object.\n  @param IsField flag which separates table columns from expressions.\n  @param Catalog a catalog name.\n  @param Schema a schema name.\n  @param Table a table name.\n  @param Field a field name.\n  @param Alias a field alias.\n}\nconstructor TZFieldRef.Create(IsField: Boolean; const Catalog, Schema, Table,\n  Field, Alias: string; TableRef: TZTableRef);\nbegin\n  FIsField := IsField;\n  FCatalog := Catalog;\n  FSchema := Schema;\n  FTable := Table;\n  FField := Field;\n  FAlias := Alias;\n  FTableRef := TableRef;\n  FLinked := False;\nend;\n\n{ TZSelectSchema }\n\n{**\n  Constructs this assembly object and assignes the main properties.\n}\nconstructor TZSelectSchema.Create;\nbegin\n  FFields := TObjectList.Create;\n  FTables := TObjectList.Create;\nend;\n\n{**\n  Destroys this object and cleanups the memory.\n}\ndestructor TZSelectSchema.Destroy;\nbegin\n  FFields.Free;\n  FTables.Free;\nend;\n\n{**\n  Finds a table reference by catalog and table name.\n  @param Catalog a database catalog name.\n  @param Schema a database schema name.\n  @param Table a database table name.\n  @return a found table reference object or <code>null</code> otherwise.\n}\nfunction TZSelectSchema.FindTableByFullName(\n  const Catalog, Schema, Table: string): TZTableRef;\nvar\n  I: Integer;\n  Current: TZTableRef;\nbegin\n  Result := nil;\n\n  { Looks a table by it's full name. }\n  for I := 0 to FTables.Count - 1 do\n  begin\n    Current := TZTableRef(FTables[I]);\n    if (Current.Schema = Schema) and (Current.Table = Table) then\n    begin\n      Result := Current;\n      Exit;\n    end;\n  end;\n\n  { Looks a table by it's short name. }\n  for I := 0 to FTables.Count - 1 do\n  begin\n    Current := TZTableRef(FTables[I]);\n    if (Current.Schema = '') and (Current.Table = Table) then\n    begin\n      Result := Current;\n      Exit;\n    end;\n  end;\nend;\n\n{**\n  Finds a table reference by table name or table alias.\n  @param Table a database table name or alias.\n  @return a found table reference object or <code>null</code> otherwise.\n}\nfunction TZSelectSchema.FindTableByShortName(const Table: string): TZTableRef;\nvar\n  I: Integer;\n  Current: TZTableRef;\nbegin\n  Result := nil;\n\n  { Looks a table by it's alias. }\n  for I := 0 to FTables.Count - 1 do\n  begin\n    Current := TZTableRef(FTables[I]);\n    if Current.Alias = Table then\n    begin\n      Result := Current;\n      Exit;\n    end;\n  end;\n\n  { Looks a table by it's name. }\n  for I := 0 to FTables.Count - 1 do\n  begin\n    Current := TZTableRef(FTables[I]);\n    if Current.Table = Table then\n    begin\n      Result := Current;\n      Exit;\n    end;\n  end;\nend;\n\n{**\n  Finds a field reference by field name or field alias.\n  @param Field a table field name or alias.\n  @return a found field reference object or <code>null</code> otherwise.\n}\nfunction TZSelectSchema.FindFieldByShortName(const Field: string): TZFieldRef;\nvar\n  I: Integer;\n  Current: TZFieldRef;\nbegin\n  Result := nil;\n  if Field = '' then\n    Exit;\n\n  { Looks a field by it's alias. }\n  for I := 0 to FFields.Count - 1 do\n  begin\n    Current := TZFieldRef(FFields[I]);\n    if Current.Alias = Field then\n    begin\n      Result := Current;\n      Exit;\n    end;\n  end;\n\n  { Looks a field by it's name. }\n  for I := 0 to FFields.Count - 1 do\n  begin\n    Current := TZFieldRef(FFields[I]);\n    if Current.Field = Field then\n    begin\n      Result := Current;\n      Exit;\n    end;\n  end;\nend;\n\n{**\n  Links a field reference by index and/or field name or field alias.\n  @param ColumnIndex an index of the column.\n  @param Field a table field name or alias.\n  @return a found field reference object or <code>null</code> otherwise.\n}\nfunction TZSelectSchema.LinkFieldByIndexAndShortName(const ColumnIndex: Integer;\n  const Field: string; const Convertor: IZIdentifierConvertor): TZFieldRef;\nvar\n  I: Integer;\n  Current: TZFieldRef;\nbegin\n  Result := nil;\n  if Field = '' then\n    Exit;\n\n  { Looks by field index. }\n  if (ColumnIndex > 0) and (ColumnIndex <= FFields.Count) then\n  begin\n    Current := TZFieldRef(FFields[ColumnIndex - 1]);\n    if not Current.Linked\n      //note http://sourceforge.net/p/zeoslib/tickets/101/\n      and ((Current.Alias = Field) or (Current.Field = Field) or (Current.Field = Convertor.Quote(Field))) then\n    begin\n      Result := Current;\n      Result.Linked := True;\n      Exit;\n    end;\n  end;\n\n  { Looks a field by it's alias. }\n  for I := 0 to FFields.Count - 1 do\n  begin\n    Current := TZFieldRef(FFields[I]);\n    if not Current.Linked and ((Current.Alias = Field) or (Current.Alias = Convertor.Quote(Field))) then\n    begin\n      Result := Current;\n      Result.Linked := True;\n      Exit;\n    end;\n  end;\n\n  { Looks a field by field and table aliases. }\n  for I := 0 to FFields.Count - 1 do\n  begin\n    Current := TZFieldRef(FFields[I]);\n    if not Current.Linked and Assigned(Current.TableRef)\n      and (((Current.TableRef.Alias + '.' + Current.Field) = Field)\n      or (((Current.TableRef.Table + '.' + Current.Field) = Field))) then\n    begin\n      Result := Current;\n      Result.Linked := True;\n      Exit;\n    end;\n  end;\n\n  { Looks a field by it's name. }\n  for I := 0 to FFields.Count - 1 do\n  begin\n    Current := TZFieldRef(FFields[I]);\n    if not Current.Linked and (Current.Field = Field) then\n    begin\n      Result := Current;\n      Result.Linked := True;\n      Exit;\n    end;\n  end;\nend;\n\n{**\n  Convert all table and field identifiers..\n  @param Convertor an identifier convertor.\n}\nprocedure TZSelectSchema.ConvertIdentifiers(Convertor: IZIdentifierConvertor);\nvar\n  I: Integer;\n  function ExtractNeedlessQuote(Value : String) : String;\n  var\n    tempstring: String;\n  begin\n    tempstring := Convertor.ExtractQuote(Value);\n    if Convertor.IsCaseSensitive(tempstring) then\n      result := Value\n    else\n      result := tempstring;\n  end;\n\nbegin\n  if Convertor = nil then Exit;\n\n  for I := 0 to FFields.Count - 1 do\n  begin\n    with TZFieldRef(FFields[I]) do\n    begin\n      Catalog := ExtractNeedlessQuote(Catalog);\n      Schema := ExtractNeedlessQuote(Schema);\n      Table := ExtractNeedlessQuote(Table);\n      Field := ExtractNeedlessQuote(Field);\n      Alias := ExtractNeedlessQuote(Alias);\n    end;\n  end;\n\n  for I := 0 to FTables.Count - 1 do\n  begin\n    with TZTableRef(FTables[I]) do\n    begin\n      Catalog := ExtractNeedlessQuote(Catalog);\n      Schema := ExtractNeedlessQuote(Schema);\n      Table := ExtractNeedlessQuote(Table);\n      Alias := ExtractNeedlessQuote(Alias);\n    end;\n  end;\nend;\n\n{**\n  Links references between fields and tables.\n  @param Convertor an identifier convertor.\n}\nprocedure TZSelectSchema.LinkReferences(Convertor: IZIdentifierConvertor);\nvar\n  I, J: Integer;\n  FieldRef: TZFieldRef;\n  TableRef: TZTableRef;\n  TempFields: TObjectList;\nbegin\n  ConvertIdentifiers(Convertor);\n  TempFields := FFields;\n  FFields := TObjectList.Create;\n\n  try\n    for I := 0 to TempFields.Count - 1 do\n    begin\n      FieldRef := TZFieldRef(TempFields[I]);\n      TableRef := nil;\n\n      if not FieldRef.IsField then\n      begin\n        FFields.Add(TZFieldRef.Create(FieldRef.IsField, FieldRef.Catalog,\n          FieldRef.Schema, FieldRef.Table, FieldRef.Field, FieldRef.Alias,\n          FieldRef.TableRef));\n        Continue;\n      end\n      else if (FieldRef.Schema <> '') and (FieldRef.Table <> '') then\n      begin\n        TableRef := FindTableByFullName(FieldRef.Catalog, FieldRef.Schema,\n          FieldRef.Table);\n      end\n      else if FieldRef.Table <> '' then\n        TableRef := FindTableByShortName(FieldRef.Table)\n      else if FieldRef.Field = '*' then\n      begin\n        { Add all fields from all tables. }\n        for J := 0 to FTables.Count - 1 do\n        begin\n          with TZTableRef(FTables[J]) do\n          begin\n            FFields.Add(TZFieldRef.Create(True, Catalog, Schema,\n              Table, '*', '', TZTableRef(FTables[J])));\n          end;\n        end;\n        Continue;\n      end;\n\n      if TableRef <> nil then\n      begin\n        FFields.Add(TZFieldRef.Create(True, TableRef.Catalog, TableRef.Schema,\n          TableRef.Table, FieldRef.Field, FieldRef.Alias, TableRef));\n      end\n      else\n      begin\n        FFields.Add(TZFieldRef.Create(True, FieldRef.Catalog, FieldRef.Schema,\n          FieldRef.Table, FieldRef.Field, FieldRef.Alias, TableRef));\n      end;\n    end;\n  finally\n    TempFields.Free;\n  end;\nend;\n\n{**\n  Adds a new field to this select schema.\n  @param FieldRef a field reference object.\n}\nprocedure TZSelectSchema.AddField(FieldRef: TZFieldRef);\nbegin\n  FFields.Add(FieldRef);\nend;\n\n{**\n  Inserts a new field to this select schema.\n  @param Index an index where to insert a new field reference.\n  @param FieldRef a field reference object.\n}\nprocedure TZSelectSchema.InsertField(Index: Integer; FieldRef: TZFieldRef);\nbegin\n  FFields.Insert(Index, FieldRef);\nend;\n\n{**\n  Deletes a field from this select schema.\n  @param FieldRef a field reference object.\n}\nprocedure TZSelectSchema.DeleteField(FieldRef: TZFieldRef);\nbegin\n  FFields.Remove(FieldRef);\nend;\n\n{**\n  Adds a new table to this select schema.\n  @param TableRef a table reference object.\n}\nprocedure TZSelectSchema.AddTable(TableRef: TZTableRef);\nbegin\n  FTables.Add(TableRef);\nend;\n\n{**\n  Gets a field reference by index.\n  @param Index an index of the reference.\n  @returns a pointer to the field reference.\n}\nfunction TZSelectSchema.GetField(Index: Integer): TZFieldRef;\nbegin\n  Result := TZFieldRef(FFields[Index]);\nend;\n\n{**\n  Gets a count of field references.\n  @returns a count of field references.\n}\nfunction TZSelectSchema.GetFieldCount: Integer;\nbegin\n  Result := FFields.Count;\nend;\n\n{**\n  Gets a table reference by index.\n  @param Index an index of the reference.\n  @returns a pointer to the table reference.\n}\nfunction TZSelectSchema.GetTable(Index: Integer): TZTableRef;\nbegin\n  Result := TZTableRef(FTables[Index]);\nend;\n\n{**\n  Gets a count of table references.\n  @returns a count of table references.\n}\nfunction TZSelectSchema.GetTableCount: Integer;\nbegin\n  Result := FTables.Count;\nend;\n\nend.\n\n"
  },
  {
    "path": "lib/zeosdbo/src/parsesql/ZSqLiteAnalyser.pas",
    "content": "{*********************************************************}\n{                                                         }\n{                 Zeos Database Objects                   }\n{            SQLite Statements Analysing classes          }\n{                                                         }\n{          Originally written by Sergey Seroukhov         }\n{                                                         }\n{*********************************************************}\n\n{@********************************************************}\n{    Copyright (c) 1999-2012 Zeos Development Group       }\n{                                                         }\n{ License Agreement:                                      }\n{                                                         }\n{ This library is distributed in the hope that it will be }\n{ useful, but WITHOUT ANY WARRANTY; without even the      }\n{ implied warranty of MERCHANTABILITY or FITNESS FOR      }\n{ A PARTICULAR PURPOSE.  See the GNU Lesser General       }\n{ Public License for more details.                        }\n{                                                         }\n{ The source code of the ZEOS Libraries and packages are  }\n{ distributed under the Library GNU General Public        }\n{ License (see the file COPYING / COPYING.ZEOS)           }\n{ with the following  modification:                       }\n{ As a special exception, the copyright holders of this   }\n{ library give you permission to link this library with   }\n{ independent modules to produce an executable,           }\n{ regardless of the license terms of these independent    }\n{ modules, and to copy and distribute the resulting       }\n{ executable under terms of your choice, provided that    }\n{ you also meet, for each linked independent module,      }\n{ the terms and conditions of the license of that module. }\n{ An independent module is a module which is not derived  }\n{ from or based on this library. If you modify this       }\n{ library, you may extend this exception to your version  }\n{ of the library, but you are not obligated to do so.     }\n{ If you do not wish to do so, delete this exception      }\n{ statement from your version.                            }\n{                                                         }\n{                                                         }\n{ The project web site is located on:                     }\n{   http://zeos.firmos.at  (FORUM)                        }\n{   http://sourceforge.net/p/zeoslib/tickets/ (BUGTRACKER)}\n{   svn://svn.code.sf.net/p/zeoslib/code-0/trunk (SVN)    }\n{                                                         }\n{   http://www.sourceforge.net/projects/zeoslib.          }\n{                                                         }\n{                                                         }\n{                                 Zeos Development Group. }\n{********************************************************@}\n\nunit ZSqLiteAnalyser;\n\ninterface\n\n{$I ZParseSql.inc}\n\nuses Classes, ZGenericSqlAnalyser;\n\ntype\n\n  {** Implements an SQLite statements analyser. }\n  TZSQLiteStatementAnalyser = class (TZGenericStatementAnalyser)\n  public\n    constructor Create;\n  end;\n\nimplementation\n\nconst\n  {** The generic constants.}\n  SQLiteSectionNames: array[0..11] of string = (\n    'SELECT', 'UPDATE', 'DELETE', 'INSERT', 'FROM',\n    'WHERE', 'INTO', 'GROUP*BY', 'HAVING', 'ORDER*BY',\n    'OFFSET', 'LIMIT'\n  );\n  SQLiteSelectOptions: array[0..1] of string = (\n    'DISTINCT', 'ALL'\n  );\n  SQLiteFromJoins: array[0..7] of string = (\n    'NATURAL', 'RIGHT', 'LEFT', 'FULL', 'INNER', 'OUTER', 'JOIN', 'CROSS'\n  );\n  SQLiteFromClauses: array[0..1] of string = (\n    'ON', 'USING'\n  );\n\n{ TZSQLiteStatementAnalyser }\n\n{**\n  Creates the object and assignes the main properties.\n}\nconstructor TZSQLiteStatementAnalyser.Create;\nbegin\n  SectionNames := ArrayToStrings(SQLiteSectionNames);\n  SelectOptions := ArrayToStrings(SQLiteSelectOptions);\n  FromJoins := ArrayToStrings(SQLiteFromJoins);\n  FromClauses := ArrayToStrings(SQLiteFromClauses);\nend;\n\nend.\n\n"
  },
  {
    "path": "lib/zeosdbo/src/parsesql/ZSqLiteToken.pas",
    "content": "{*********************************************************}\n{                                                         }\n{                 Zeos Database Objects                   }\n{        String tokenizing classes for SQLite             }\n{                                                         }\n{        Originally written by Sergey Seroukhov           }\n{                                                         }\n{*********************************************************}\n\n{@********************************************************}\n{    Copyright (c) 1999-2012 Zeos Development Group       }\n{                                                         }\n{ License Agreement:                                      }\n{                                                         }\n{ This library is distributed in the hope that it will be }\n{ useful, but WITHOUT ANY WARRANTY; without even the      }\n{ implied warranty of MERCHANTABILITY or FITNESS FOR      }\n{ A PARTICULAR PURPOSE.  See the GNU Lesser General       }\n{ Public License for more details.                        }\n{                                                         }\n{ The source code of the ZEOS Libraries and packages are  }\n{ distributed under the Library GNU General Public        }\n{ License (see the file COPYING / COPYING.ZEOS)           }\n{ with the following  modification:                       }\n{ As a special exception, the copyright holders of this   }\n{ library give you permission to link this library with   }\n{ independent modules to produce an executable,           }\n{ regardless of the license terms of these independent    }\n{ modules, and to copy and distribute the resulting       }\n{ executable under terms of your choice, provided that    }\n{ you also meet, for each linked independent module,      }\n{ the terms and conditions of the license of that module. }\n{ An independent module is a module which is not derived  }\n{ from or based on this library. If you modify this       }\n{ library, you may extend this exception to your version  }\n{ of the library, but you are not obligated to do so.     }\n{ If you do not wish to do so, delete this exception      }\n{ statement from your version.                            }\n{                                                         }\n{                                                         }\n{ The project web site is located on:                     }\n{   http://zeos.firmos.at  (FORUM)                        }\n{   http://sourceforge.net/p/zeoslib/tickets/ (BUGTRACKER)}\n{   svn://svn.code.sf.net/p/zeoslib/code-0/trunk (SVN)    }\n{                                                         }\n{   http://www.sourceforge.net/projects/zeoslib.          }\n{                                                         }\n{                                                         }\n{                                 Zeos Development Group. }\n{********************************************************@}\n\nunit ZSqLiteToken;\n\ninterface\n\n{$I ZParseSql.inc}\n\nuses\n  Classes, {$IFDEF MSEgui}mclasses,{$ENDIF}\n  ZTokenizer, ZGenericSqlToken;\n\ntype\n\n  {** Implements a SQLite-specific number state object. }\n  TZSQLiteNumberState = class (TZNumberState)\n  public\n    function NextToken(Stream: TStream; FirstChar: Char;\n      Tokenizer: TZTokenizer): TZToken; override;\n  end;\n\n  {** Implements a SQLite-specific quote string state object. }\n  TZSQLiteQuoteState = class (TZQuoteState)\n  public\n    function NextToken(Stream: TStream; FirstChar: Char;\n      Tokenizer: TZTokenizer): TZToken; override;\n\n    function EncodeString(const Value: string; QuoteChar: Char): string; override;\n    function DecodeString(const Value: string; QuoteChar: Char): string; override;\n  end;\n\n  {**\n    This state will either delegate to a comment-handling\n    state, or return a token with just a slash in it.\n  }\n  TZSQLiteCommentState = class (TZCppCommentState)\n  public\n    function NextToken(Stream: TStream; FirstChar: Char;\n      Tokenizer: TZTokenizer): TZToken; override;\n  end;\n\n  {** Implements a symbol state object. }\n  TZSQLiteSymbolState = class (TZSymbolState)\n  public\n    constructor Create;\n  end;\n\n  {** Implements a word state object. }\n  TZSQLiteWordState = class (TZGenericSQLWordState)\n  public\n    constructor Create;\n  end;\n\n  {** Implements a default tokenizer object. }\n  TZSQLiteTokenizer = class (TZTokenizer)\n  public\n    constructor Create;\n  end;\n\nimplementation\n\nuses SysUtils, ZCompatibility;\n\n{ TZSQLiteNumberState }\n\n{**\n  Return a number token from a reader.\n  @return a number token from a reader\n}\nfunction TZSQLiteNumberState.NextToken(Stream: TStream; FirstChar: Char;\n  Tokenizer: TZTokenizer): TZToken;\nvar\n  TempChar: Char;\n  FloatPoint: Boolean;\n  LastChar: Char;\n\n  function ReadDecDigits: string;\n  begin\n    Result := '';\n    LastChar := #0;\n    while Stream.Read(LastChar, SizeOf(Char)) > 0 do\n    begin\n      if CharInSet(LastChar, ['0'..'9']) then\n      begin\n        Result := Result + LastChar;\n        LastChar := #0;\n      end\n      else\n      begin\n        Stream.Seek(-SizeOf(Char), soFromCurrent);\n        Break;\n      end;\n    end;\n  end;\n\nbegin\n  FloatPoint := FirstChar = '.';\n  Result.Value := FirstChar;\n  Result.TokenType := ttUnknown;\n  LastChar := #0;\n\n  { Reads the first part of the number before decimal point }\n  if not FloatPoint then\n  begin\n    Result.Value := Result.Value + ReadDecDigits;\n    FloatPoint := LastChar = '.';\n    if FloatPoint then\n    begin\n      Stream.Read(TempChar, SizeOf(Char));\n      Result.Value := Result.Value + TempChar;\n    end;\n  end;\n\n  { Reads the second part of the number after decimal point }\n  if FloatPoint then\n    Result.Value := Result.Value + ReadDecDigits;\n\n  { Reads a power part of the number }\n  if CharInSet(LastChar, ['e','E']) then\n  begin\n    Stream.Read(TempChar, SizeOf(Char));\n    Result.Value := Result.Value + TempChar;\n    FloatPoint := True;\n\n    Stream.Read(TempChar, SizeOf(Char));\n    if CharInSet(TempChar, ['0'..'9','-','+']) then\n      Result.Value := Result.Value + TempChar + ReadDecDigits\n    else\n    begin\n      Result.Value := Copy(Result.Value, 1, Length(Result.Value) - 1);\n      Stream.Seek(-2*SizeOf(Char), soFromCurrent);\n    end;\n  end;\n\n  { Prepare the result }\n  if Result.Value = '.' then\n  begin\n    if Tokenizer.SymbolState <> nil then\n      Result := Tokenizer.SymbolState.NextToken(Stream, FirstChar, Tokenizer);\n  end\n  else\n  begin\n    if FloatPoint then\n      Result.TokenType := ttFloat\n    else Result.TokenType := ttInteger;\n  end;\nend;\n\n{ TZSQLiteQuoteState }\n\n{**\n  Return a quoted string token from a reader. This method\n  will collect characters until it sees a match to the\n  character that the tokenizer used to switch to this state.\n\n  @return a quoted string token from a reader\n}\nfunction TZSQLiteQuoteState.NextToken(Stream: TStream; FirstChar: Char;\n  Tokenizer: TZTokenizer): TZToken;\nvar\n  ReadChar: Char;\n  LastChar: Char;\nbegin\n  Result.Value := FirstChar;\n  LastChar := #0;\n  while Stream.Read(ReadChar, SizeOf(Char)) > 0 do\n  begin\n    if ((LastChar = FirstChar) and (ReadChar <> FirstChar)\n      and (FirstChar <> '[')) or ((FirstChar = '[') and (LastChar = ']')) then\n    begin\n      Stream.Seek(-SizeOf(Char), soFromCurrent);\n      Break;\n    end;\n    Result.Value := Result.Value + ReadChar;\n    if (LastChar = FirstChar) and (ReadChar = FirstChar) then\n      LastChar := #0\n    else LastChar := ReadChar;\n  end;\n\n  if CharInSet(FirstChar, ['\"', '[']) then\n    Result.TokenType := ttWord\n  else Result.TokenType := ttQuoted;\nend;\n\n{**\n  Encodes a string value.\n  @param Value a string value to be encoded.\n  @param QuoteChar a string quote character.\n  @returns an encoded string.\n}\nfunction TZSQLiteQuoteState.EncodeString(const Value: string; QuoteChar: Char): string;\nbegin\n  if QuoteChar = '[' then\n    Result := '[' + Value + ']'\n  else if CharInSet(QuoteChar, [#39, '\"']) then\n    Result := QuoteChar + Value + QuoteChar\n  else Result := Value;\nend;\n\n{**\n  Decodes a string value.\n  @param Value a string value to be decoded.\n  @param QuoteChar a string quote character.\n  @returns an decoded string.\n}\nfunction TZSQLiteQuoteState.DecodeString(const Value: string; QuoteChar: Char): string;\nbegin\n  Result := Value;\n  if Length(Value) >= 2 then\n  begin\n    if CharInSet(QuoteChar, [#39, '\"']) and (Value[1] = QuoteChar)\n      and (Value[Length(Value)] = QuoteChar) then\n    begin\n      if Length(Value) > 2 then\n        Result := AnsiDequotedStr(Value, QuoteChar)\n      else Result := '';\n    end\n    else if (QuoteChar = '[') and (Value[1] = QuoteChar)\n      and (Value[Length(Value)] = ']') then\n      Result := Copy(Value, 2, Length(Value) - 2)\n  end;\nend;\n\n{ TZSQLiteCommentState }\n\n{**\n  Gets a SQLite specific comments like # or /* */.\n  @return either just a slash token, or the results of\n    delegating to a comment-handling state\n}\nfunction TZSQLiteCommentState.NextToken(Stream: TStream; FirstChar: Char;\n  Tokenizer: TZTokenizer): TZToken;\nvar\n  ReadChar: Char;\n  ReadNum: Integer;\nbegin\n  Result.Value := FirstChar;\n  Result.TokenType := ttUnknown;\n\n  if FirstChar = '-' then\n  begin\n    ReadNum := Stream.Read(ReadChar, SizeOf(Char));\n    if (ReadNum > 0) and (ReadChar = '-') then\n    begin\n      Result.TokenType := ttComment;\n      Result.Value := '--' + GetSingleLineComment(Stream);\n    end\n    else\n    begin\n      if ReadNum > 0 then\n        Stream.Seek(-SizeOf(Char), soFromCurrent);\n    end;\n  end\n  else if FirstChar = '/' then\n  begin\n    ReadNum := Stream.Read(ReadChar, SizeOf(Char));\n    if (ReadNum > 0) and (ReadChar = '*') then\n    begin\n      Result.TokenType := ttComment;\n      Result.Value := '/*' + GetMultiLineComment(Stream);\n    end\n    else\n    begin\n      if ReadNum > 0 then\n        Stream.Seek(-SizeOf(Char), soFromCurrent);\n    end;\n  end;\n\n  if (Result.TokenType = ttUnknown) and (Tokenizer.SymbolState <> nil) then\n    Result := Tokenizer.SymbolState.NextToken(Stream, FirstChar, Tokenizer);\nend;\n\n{ TZSQLiteSymbolState }\n\n{**\n  Creates this SQLite-specific symbol state object.\n}\nconstructor TZSQLiteSymbolState.Create;\nbegin\n  inherited Create;\n  Add('<=');\n  Add('>=');\n  Add('<>');\n  Add('!=');\n  Add('==');\n  Add('<<');\n  Add('>>');\n  Add('||');\nend;\n\n{ TZSQLiteWordState }\n\n{**\n  Constructs this SQLite-specific word state object.\n}\nconstructor TZSQLiteWordState.Create;\nbegin\n  SetWordChars(#0, #255, False);\n  SetWordChars('a', 'z', True);\n  SetWordChars('A', 'Z', True);\n  SetWordChars('0', '9', True);\n  SetWordChars('_', '_', True);\nend;\n\n{ TZSQLiteTokenizer }\n\n{**\n  Constructs a tokenizer with a default state table (as\n  described in the class comment).\n}\nconstructor TZSQLiteTokenizer.Create;\nbegin\n  EscapeState := TZEscapeState.Create;\n  WhitespaceState := TZWhitespaceState.Create;\n\n  SymbolState := TZSQLiteSymbolState.Create;\n  NumberState := TZSQLiteNumberState.Create;\n  QuoteState := TZSQLiteQuoteState.Create;\n  WordState := TZSQLiteWordState.Create;\n  CommentState := TZSQLiteCommentState.Create;\n\n  SetCharacterState(#0, #32, WhitespaceState);\n  SetCharacterState(#33, #191, SymbolState);\n  SetCharacterState(#192, High(Char), WordState);\n\n  SetCharacterState('a', 'z', WordState);\n  SetCharacterState('A', 'Z', WordState);\n  SetCharacterState('_', '_', WordState);\n\n  SetCharacterState('0', '9', NumberState);\n  SetCharacterState('.', '.', NumberState);\n\n  SetCharacterState('\"', '\"', QuoteState);\n  SetCharacterState(#39, #39, QuoteState);\n  SetCharacterState('[', '[', QuoteState);\n  SetCharacterState(']', ']', QuoteState);\n\n  SetCharacterState('/', '/', CommentState);\n  SetCharacterState('-', '-', CommentState);\nend;\n\nend.\n\n"
  },
  {
    "path": "lib/zeosdbo/src/parsesql/ZSybaseAnalyser.pas",
    "content": "{*********************************************************}\n{                                                         }\n{                 Zeos Database Objects                   }\n{            SQL Statements Analysing classes             }\n{                                                         }\n{         Originally written by Sergey Seroukhov          }\n{                                                         }\n{*********************************************************}\n\n{@********************************************************}\n{    Copyright (c) 1999-2012 Zeos Development Group       }\n{                                                         }\n{ License Agreement:                                      }\n{                                                         }\n{ This library is distributed in the hope that it will be }\n{ useful, but WITHOUT ANY WARRANTY; without even the      }\n{ implied warranty of MERCHANTABILITY or FITNESS FOR      }\n{ A PARTICULAR PURPOSE.  See the GNU Lesser General       }\n{ Public License for more details.                        }\n{                                                         }\n{ The source code of the ZEOS Libraries and packages are  }\n{ distributed under the Library GNU General Public        }\n{ License (see the file COPYING / COPYING.ZEOS)           }\n{ with the following  modification:                       }\n{ As a special exception, the copyright holders of this   }\n{ library give you permission to link this library with   }\n{ independent modules to produce an executable,           }\n{ regardless of the license terms of these independent    }\n{ modules, and to copy and distribute the resulting       }\n{ executable under terms of your choice, provided that    }\n{ you also meet, for each linked independent module,      }\n{ the terms and conditions of the license of that module. }\n{ An independent module is a module which is not derived  }\n{ from or based on this library. If you modify this       }\n{ library, you may extend this exception to your version  }\n{ of the library, but you are not obligated to do so.     }\n{ If you do not wish to do so, delete this exception      }\n{ statement from your version.                            }\n{                                                         }\n{                                                         }\n{ The project web site is located on:                     }\n{   http://zeos.firmos.at  (FORUM)                        }\n{   http://sourceforge.net/p/zeoslib/tickets/ (BUGTRACKER)}\n{   svn://svn.code.sf.net/p/zeoslib/code-0/trunk (SVN)    }\n{                                                         }\n{   http://www.sourceforge.net/projects/zeoslib.          }\n{                                                         }\n{                                                         }\n{                                 Zeos Development Group. }\n{********************************************************@}\n\nunit ZSybaseAnalyser;\n\ninterface\n\n{$I ZParseSql.inc}\n\nuses Classes, ZGenericSqlAnalyser;\n\ntype\n\n  {** Implements an Sybase statements analyser. }\n  TZSybaseStatementAnalyser = class (TZGenericStatementAnalyser)\n  end;\n\nimplementation\n\nend.\n \n"
  },
  {
    "path": "lib/zeosdbo/src/parsesql/ZSybaseToken.pas",
    "content": "{*********************************************************}\n{                                                         }\n{                 Zeos Database Objects                   }\n{          String tokenizing classes for Sybase           }\n{                                                         }\n{        Originally written by Janos Fegyverneki          }\n{                                                         }\n{*********************************************************}\n\n{@********************************************************}\n{    Copyright (c) 1999-2012 Zeos Development Group       }\n{                                                         }\n{ License Agreement:                                      }\n{                                                         }\n{ This library is distributed in the hope that it will be }\n{ useful, but WITHOUT ANY WARRANTY; without even the      }\n{ implied warranty of MERCHANTABILITY or FITNESS FOR      }\n{ A PARTICULAR PURPOSE.  See the GNU Lesser General       }\n{ Public License for more details.                        }\n{                                                         }\n{ The source code of the ZEOS Libraries and packages are  }\n{ distributed under the Library GNU General Public        }\n{ License (see the file COPYING / COPYING.ZEOS)           }\n{ with the following  modification:                       }\n{ As a special exception, the copyright holders of this   }\n{ library give you permission to link this library with   }\n{ independent modules to produce an executable,           }\n{ regardless of the license terms of these independent    }\n{ modules, and to copy and distribute the resulting       }\n{ executable under terms of your choice, provided that    }\n{ you also meet, for each linked independent module,      }\n{ the terms and conditions of the license of that module. }\n{ An independent module is a module which is not derived  }\n{ from or based on this library. If you modify this       }\n{ library, you may extend this exception to your version  }\n{ of the library, but you are not obligated to do so.     }\n{ If you do not wish to do so, delete this exception      }\n{ statement from your version.                            }\n{                                                         }\n{                                                         }\n{ The project web site is located on:                     }\n{   http://zeos.firmos.at  (FORUM)                        }\n{   http://sourceforge.net/p/zeoslib/tickets/ (BUGTRACKER)}\n{   svn://svn.code.sf.net/p/zeoslib/code-0/trunk (SVN)    }\n{                                                         }\n{   http://www.sourceforge.net/projects/zeoslib.          }\n{                                                         }\n{                                                         }\n{                                 Zeos Development Group. }\n{********************************************************@}\n\nunit ZSybaseToken;\n\ninterface\n\n{$I ZParseSql.inc}\n\nuses\n  Classes, {$IFDEF MSEgui}mclasses,{$ENDIF} SysUtils,\n  ZTokenizer, ZCompatibility, ZGenericSqlToken;\n\ntype\n\n  {** Implements a Sybase-specific number state object. }\n  TZSybaseNumberState = class (TZNumberState)\n  public\n    function NextToken(Stream: TStream; FirstChar: Char;\n      Tokenizer: TZTokenizer): TZToken; override;\n  end;\n\n  {** Implements a Sybase-specific quote string state object. }\n  TZSybaseQuoteState = class (TZQuoteState)\n  public\n    function NextToken(Stream: TStream; FirstChar: Char;\n      Tokenizer: TZTokenizer): TZToken; override;\n\n    function EncodeString(const Value: string; QuoteChar: Char): string; override;\n    function DecodeString(const Value: string; QuoteChar: Char): string; override;\n  end;\n\n  {**\n    This state will either delegate to a comment-handling\n    state, or return a token with just a slash in it.\n  }\n  TZSybaseCommentState = class (TZCppCommentState)\n  public\n    function NextToken(Stream: TStream; FirstChar: Char;\n      Tokenizer: TZTokenizer): TZToken; override;\n  end;\n\n  {** Implements a symbol state object. }\n  TZSybaseSymbolState = class (TZSymbolState)\n  public\n    constructor Create;\n  end;\n\n  {** Implements a word state object. }\n  TZSybaseWordState = class (TZGenericSQLWordState)\n  public\n    constructor Create;\n  end;\n\n  {** Implements a default tokenizer object. }\n  TZSybaseTokenizer = class (TZTokenizer)\n  public\n    constructor Create;\n  end;\n\nimplementation\n\n{ TZSybaseNumberState }\n\n{**\n  Return a number token from a reader.\n  @return a number token from a reader\n}\nfunction TZSybaseNumberState.NextToken(Stream: TStream; FirstChar: Char;\n  Tokenizer: TZTokenizer): TZToken;\nvar\n  HexDecimal: Boolean;\n  FloatPoint: Boolean;\n  LastChar: Char;\n\n  function ReadHexDigits: string;\n  begin\n    Result := '';\n    LastChar := #0;\n    while Stream.Read(LastChar, SizeOf(Char)) > 0 do\n    begin\n      if CharInSet(LastChar, ['0'..'9','a'..'f','A'..'F']) then\n      begin\n        Result := Result + LastChar;\n        HexDecimal := HexDecimal or CharInSet(LastChar, ['a'..'f','A'..'F']);\n        LastChar := #0;\n      end\n      else\n      begin\n        Stream.Seek(-SizeOf(Char), soFromCurrent);\n        Break;\n      end;\n    end;\n  end;\n\n  function ReadDecDigits: string;\n  begin\n    Result := '';\n    LastChar := #0;\n    while Stream.Read(LastChar, SizeOf(Char)) > 0 do\n    begin\n      if CharInSet(LastChar, ['0'..'9']) then\n      begin\n        Result := Result + LastChar;\n        LastChar := #0;\n      end\n      else\n      begin\n        Stream.Seek(-SizeOf(Char), soFromCurrent);\n        Break;\n      end;\n    end;\n  end;\n\nbegin\n  HexDecimal := False;\n  FloatPoint := FirstChar = '.';\n  LastChar := #0;\n\n  Result.Value := FirstChar;\n  Result.TokenType := ttUnknown;\n\n  { Reads the first part of the number before decimal point }\n  if not FloatPoint then\n  begin\n    Result.Value := Result.Value + ReadDecDigits;\n    FloatPoint := (LastChar = '.') and not HexDecimal;\n    if FloatPoint then\n    begin\n      Stream.Read(LastChar, SizeOf(Char));\n      Result.Value := Result.Value + LastChar;\n    end;\n  end;\n\n  { Reads the second part of the number after decimal point }\n  if FloatPoint then\n    Result.Value := Result.Value + ReadDecDigits;\n\n  { Reads a power part of the number }\n  if not HexDecimal and CharInSet(LastChar, ['e','E']) then\n  begin\n    Stream.Read(LastChar, SizeOf(Char));\n    Result.Value := Result.Value + LastChar;\n    FloatPoint := True;\n\n    Stream.Read(LastChar, SizeOf(Char));\n    if CharInSet(LastChar, ['0'..'9','-','+']) then\n      Result.Value := Result.Value + LastChar + ReadDecDigits\n    else\n    begin\n      Result.Value := Copy(Result.Value, 1, Length(Result.Value) - 1);\n      Stream.Seek(-2*SizeOf(Char), soFromCurrent);\n    end;\n  end;\n\n  { Reads the nexdecimal number }\n  if (Result.Value = '0') and CharInSet(LastChar, ['x','X']) then\n  begin\n    Stream.Read(LastChar, SizeOf(Char));\n    Result.Value := Result.Value + LastChar + ReadHexDigits;\n    HexDecimal := True;\n  end;\n\n  { Prepare the result }\n  if Result.Value = '.' then\n  begin\n    if Tokenizer.SymbolState <> nil then\n      Result := Tokenizer.SymbolState.NextToken(Stream, FirstChar, Tokenizer);\n  end\n  else\n  begin\n    if HexDecimal then\n      Result.TokenType := ttHexDecimal\n    else if FloatPoint then\n      Result.TokenType := ttFloat\n    else Result.TokenType := ttInteger;\n  end;\nend;\n\n{ TZSybaseQuoteState }\n\n{**\n  Return a quoted string token from a reader. This method\n  will collect characters until it sees a match to the\n  character that the tokenizer used to switch to this state.\n\n  @return a quoted string token from a reader\n}\nfunction TZSybaseQuoteState.NextToken(Stream: TStream; FirstChar: Char;\n  Tokenizer: TZTokenizer): TZToken;\nvar\n  ReadChar: Char;\n  LastChar: Char;\nbegin\n  Result.Value := FirstChar;\n  LastChar := #0;\n  while Stream.Read(ReadChar, SizeOf(Char)) > 0 do\n  begin\n    if ((LastChar = FirstChar) and (ReadChar <> FirstChar)\n      and (FirstChar <> '[')) or ((FirstChar = '[') and (LastChar = ']')) then\n    begin\n      Stream.Seek(-SizeOf(Char), soFromCurrent);\n      Break;\n    end;\n    Result.Value := Result.Value + ReadChar;\n    if (LastChar = FirstChar) and (ReadChar = FirstChar) then\n      LastChar := #0\n    else LastChar := ReadChar;\n  end;\n\n  if CharInSet(FirstChar, ['\"', '[']) then\n    Result.TokenType := ttWord\n  else Result.TokenType := ttQuoted;\nend;\n\n{**\n  Encodes a string value.\n  @param Value a string value to be encoded.\n  @param QuoteChar a string quote character.\n  @returns an encoded string.\n}\nfunction TZSybaseQuoteState.EncodeString(const Value: string; QuoteChar: Char): string;\nbegin\n  if QuoteChar = '[' then\n    Result := '[' + Value + ']'\n  else if CharInSet(QuoteChar, [#39, '\"']) then\n    Result := QuoteChar + Value + QuoteChar\n  else Result := Value;\nend;\n\n{**\n  Decodes a string value.\n  @param Value a string value to be decoded.\n  @param QuoteChar a string quote character.\n  @returns an decoded string.\n}\nfunction TZSybaseQuoteState.DecodeString(const Value: string; QuoteChar: Char): string;\nbegin\n  Result := Value;\n  if Length(Value) >= 2 then\n  begin\n    if CharInSet(QuoteChar, [#39, '\"']) and (Value[1] = QuoteChar)\n      and (Value[Length(Value)] = QuoteChar) then\n    begin\n      if Length(Value) > 2 then\n        Result := AnsiDequotedStr(Value, QuoteChar)\n      else Result := '';\n    end\n    else if (QuoteChar = '[') and (Value[1] = QuoteChar)\n      and (Value[Length(Value)] = ']') then\n      Result := Copy(Value, 2, Length(Value) - 2)\n  end;\nend;\n\n{ TZSybaseCommentState }\n\n{**\n  Gets a Sybase specific comments like # or /* */.\n  @return either just a slash token, or the results of\n    delegating to a comment-handling state\n}\nfunction TZSybaseCommentState.NextToken(Stream: TStream; FirstChar: Char;\n  Tokenizer: TZTokenizer): TZToken;\nvar\n  ReadChar: Char;\n  ReadNum: Integer;\nbegin\n  Result.Value := FirstChar;\n  Result.TokenType := ttUnknown;\n\n  if FirstChar = '-' then\n  begin\n    ReadNum := Stream.Read(ReadChar, SizeOf(Char));\n    if (ReadNum > 0) and (ReadChar = '-') then\n    begin\n      Result.TokenType := ttComment;\n      Result.Value := '--' + GetSingleLineComment(Stream);\n    end\n    else\n    begin\n      if ReadNum > 0 then\n        Stream.Seek(-SizeOf(Char), soFromCurrent);\n    end;\n  end\n  else if FirstChar = '/' then\n  begin\n    ReadNum := Stream.Read(ReadChar, SizeOf(Char));\n    if (ReadNum > 0) and (ReadChar = '*') then\n    begin\n      Result.TokenType := ttComment;\n      Result.Value := '/*' + GetMultiLineComment(Stream);\n    end\n    else\n    begin\n      if ReadNum > 0 then\n        Stream.Seek(-SizeOf(Char), soFromCurrent);\n    end;\n  end;\n\n  if (Result.TokenType = ttUnknown) and (Tokenizer.SymbolState <> nil) then\n    Result := Tokenizer.SymbolState.NextToken(Stream, FirstChar, Tokenizer);\nend;\n\n{ TZSybaseSymbolState }\n\n{**\n  Creates this Sybase-specific symbol state object.\n}\nconstructor TZSybaseSymbolState.Create;\nbegin\n  inherited Create;\n  Add('<=');\n  Add('>=');\n  Add('<>');\n  Add('!<');\n  Add('!>');\n  Add('!=');\nend;\n\n{ TZSybaseWordState }\n\n{**\n  Constructs this Sybase-specific word state object.\n}\nconstructor TZSybaseWordState.Create;\nbegin\n  SetWordChars(#0, #191, False);\n  SetWordChars(#192, high(char), True);\n  SetWordChars('a', 'z', True);\n  SetWordChars('A', 'Z', True);\n  SetWordChars('0', '9', True);\n  SetWordChars('$', '$', True);\n  SetWordChars('_', '_', True);\n  SetWordChars('@', '@', True);\n  SetWordChars('#', '#', True);\nend;\n\n{ TZSybaseTokenizer }\n\n{**\n  Constructs a tokenizer with a default state table (as\n  described in the class comment).\n}\nconstructor TZSybaseTokenizer.Create;\nbegin\n  EscapeState := TZEscapeState.Create;\n  WhitespaceState := TZWhitespaceState.Create;\n\n  SymbolState := TZSybaseSymbolState.Create;\n  NumberState := TZSybaseNumberState.Create;\n  QuoteState := TZSybaseQuoteState.Create;\n  WordState := TZSybaseWordState.Create;\n  CommentState := TZSybaseCommentState.Create;\n\n  SetCharacterState(#0, #32, WhitespaceState);\n  SetCharacterState(#33, #191, SymbolState);\n  SetCharacterState(#192, High(Char), WordState);\n\n  SetCharacterState('a', 'z', WordState);\n  SetCharacterState('A', 'Z', WordState);\n  SetCharacterState('_', '_', WordState);\n  SetCharacterState('$', '$', WordState);\n  SetCharacterState('@', '@', WordState);\n  SetCharacterState('#', '#', WordState);\n\n  SetCharacterState('0', '9', NumberState);\n  SetCharacterState('.', '.', NumberState);\n\n  SetCharacterState('\"', '\"', QuoteState);\n  SetCharacterState('''', '''', QuoteState);\n  SetCharacterState('[', '[', QuoteState);\n  SetCharacterState(']', ']', QuoteState);\n\n  SetCharacterState('/', '/', CommentState);\n  SetCharacterState('-', '-', CommentState);\nend;\n\nend.\n\n\n"
  },
  {
    "path": "lib/zeosdbo/src/plain/ZPlain.inc",
    "content": "{@********************************************************}\n{    Copyright (c) 1999-2012 Zeos Development Group       }\n{                                                         }\n{ License Agreement:                                      }\n{                                                         }\n{ This library is distributed in the hope that it will be }\n{ useful, but WITHOUT ANY WARRANTY; without even the      }\n{ implied warranty of MERCHANTABILITY or FITNESS FOR      }\n{ A PARTICULAR PURPOSE.  See the GNU Lesser General       }\n{ Public License for more details.                        }\n{                                                         }\n{ The source code of the ZEOS Libraries and packages are  }\n{ distributed under the Library GNU General Public        }\n{ License (see the file COPYING / COPYING.ZEOS)           }\n{ with the following  modification:                       }\n{ As a special exception, the copyright holders of this   }\n{ library give you permission to link this library with   }\n{ independent modules to produce an executable,           }\n{ regardless of the license terms of these independent    }\n{ modules, and to copy and distribute the resulting       }\n{ executable under terms of your choice, provided that    }\n{ you also meet, for each linked independent module,      }\n{ the terms and conditions of the license of that module. }\n{ An independent module is a module which is not derived  }\n{ from or based on this library. If you modify this       }\n{ library, you may extend this exception to your version  }\n{ of the library, but you are not obligated to do so.     }\n{ If you do not wish to do so, delete this exception      }\n{ statement from your version.                            }\n{                                                         }\n{                                                         }\n{ The project web site is located on:                     }\n{   http://zeos.firmos.at  (FORUM)                        }\n{   http://sourceforge.net/p/zeoslib/tickets/ (BUGTRACKER)}\n{   svn://svn.code.sf.net/p/zeoslib/code-0/trunk (SVN)    }\n{                                                         }\n{   http://www.sourceforge.net/projects/zeoslib.          }\n{                                                         }\n{                                                         }\n{                                 Zeos Development Group. }\n{********************************************************@}\n\n{$IFDEF LINUX}\n  {$DEFINE UNIX}\n{$ENDIF}\n\n{$IFNDEF UNIX}\n{$I ..\\Zeos.inc}\n{$ELSE}\n{$I ../Zeos.inc}\n{$ENDIF}\n"
  },
  {
    "path": "lib/zeosdbo/src/plain/ZPlainASAConstants.pas",
    "content": "{@********************************************************}\n{    Copyright (c) 1999-2012 Zeos Development Group       }\n{                                                         }\n{ License Agreement:                                      }\n{                                                         }\n{ This library is distributed in the hope that it will be }\n{ useful, but WITHOUT ANY WARRANTY; without even the      }\n{ implied warranty of MERCHANTABILITY or FITNESS FOR      }\n{ A PARTICULAR PURPOSE.  See the GNU Lesser General       }\n{ Public License for more details.                        }\n{                                                         }\n{ The source code of the ZEOS Libraries and packages are  }\n{ distributed under the Library GNU General Public        }\n{ License (see the file COPYING / COPYING.ZEOS)           }\n{ with the following  modification:                       }\n{ As a special exception, the copyright holders of this   }\n{ library give you permission to link this library with   }\n{ independent modules to produce an executable,           }\n{ regardless of the license terms of these independent    }\n{ modules, and to copy and distribute the resulting       }\n{ executable under terms of your choice, provided that    }\n{ you also meet, for each linked independent module,      }\n{ the terms and conditions of the license of that module. }\n{ An independent module is a module which is not derived  }\n{ from or based on this library. If you modify this       }\n{ library, you may extend this exception to your version  }\n{ of the library, but you are not obligated to do so.     }\n{ If you do not wish to do so, delete this exception      }\n{ statement from your version.                            }\n{                                                         }\n{                                                         }\n{ The project web site is located on:                     }\n{   http://zeos.firmos.at  (FORUM)                        }\n{   http://sourceforge.net/p/zeoslib/tickets/ (BUGTRACKER)}\n{   svn://svn.code.sf.net/p/zeoslib/code-0/trunk (SVN)    }\n{                                                         }\n{   http://www.sourceforge.net/projects/zeoslib.          }\n{                                                         }\n{                                                         }\n{                                 Zeos Development Group. }\n{********************************************************@}\n\nunit ZPlainASAConstants;\n\ninterface\n\n{$I ZPlain.inc}\n\n{$J+}\n\n{ ***************** Plain API Constants definition **************** }\n\nconst\n  ASA7_WINDOWS_DLL_LOCATION = 'DBLIB7.DLL';\n  ASA7_LINUX_DLL_LOCATION = 'libdblib7.so';\n  ASA8_WINDOWS_DLL_LOCATION = 'DBLIB8.DLL';\n  ASA8_LINUX_DLL_LOCATION = 'libdblib8.so';\n  ASA9_WINDOWS_DLL_LOCATION = 'DBLIB9.DLL';\n  ASA9_LINUX_DLL_LOCATION = 'libdblib9.so';\n  ASA12_WINDOWS_DLL_LOCATION = 'DBLIB12.DLL';\n  ASA12_LINUX_DLL_LOCATION = 'libdblib12.so';\n\n  //sqlerr.h\n  //* Warnings *//\n  SQLE_NOERROR                          = 0;\n  SQLE_NOTFOUND                         = 100;\n  SQLE_TRUNCATED                        = 101;\n  SQLE_TEMPORARY_TABLE                  = 102;\n  SQLE_CANNOT_CONVERT                   = 103;\n  SQLE_ROW_UPDATED_WARNING              = 104;\n  SQLE_PROCEDURE_COMPLETE               = 105;\n  SQLE_COLUMN_VALUE_CHANGED             = 106;\n  SQLE_SYNTAX_EXTENSION_WARNING         = 107;\n  SQLE_CURSOR_OPERATION_CONFLICT        = 108;\n  SQLE_NULL_VALUE_ELIMINATED            = 109;\n  SQLE_BACKUP_PAGE_INCOMPLETE           = 110;\n  SQLE_CANNOT_EXECUTE_STMT              = 111;\n  SQLE_MORE_INFO                        = 112;\n  SQLE_INVALID_OPTION_ON_CONNECT        = 113;\n  SQLE_CANNOT_PERFORM_CHAR_TRANSLATION  = 114;\n  SQLE_UNSUPPORTED_CHARACTER_SET_WARNING = 115;\n  SQLE_UNSUPPORTED_LANGUAGE             = 116;\n  SQLE_UNSUPPORTED_CHARSET_AND_LANGUAGE = 117;\n  SQLE_INVALID_USER_ESTIMATE            = 118;\n  SQLE_UNABLE_TO_OPEN_BACKUP_LOG        = 119;\n  SQLE_UNKNOWN_OPTION                   = 120;\n  SQLE_CURSOR_OPTIONS_CHANGED           = 121;\n  SQLE_DATABASE_NEW                     = 123;\n  SQLE_CANNOT_CONVERT_LOAD_TABLE        = 124;\n  SQLE_INPUT_ILLEGAL_MULTIBYTE_WARNING  = 125;\n  SQLE_OUTPUT_ILLEGAL_MULTIBYTE_WARNING = 126;\n  SQLE_INPUT_SIMPLE_SUBSTITUTION_WARNING = 127;\n  SQLE_OUTPUT_SIMPLE_SUBSTITUTION_WARNING = 128;\n  SQLE_ROW_DROPPED_DURING_SCHEMA_UPGRADE = 130;\n  SQLE_CANNOT_DUMP_STRING_HISTOGRAM     = 132;\n  SQLE_COMPRESSING_ENCRYPTED_DB         = 135;\n  SQLE_WARNING                          = 200;\n//  SQLE_HLI_MORE_DATA_AVAILABLE          = 400;\n\n  //Errors\n  SQLE_NO_DATABASE_FILE                 = -72;\n  SQLE_COMMUNICATIONS_UNDERFLOW         = -73;\n  SQLE_DATABASE_NOT_ACTIVE              = -74;\n  SQLE_START_STOP_DATABASE_DENIED       = -75;\n  SQLE_REQUEST_DENIED_NO_DATABASES      = -76;\n  SQLE_ALIAS_CLASH                      = -77;\n  SQLE_DYNAMIC_MEMORY_EXHAUSTED         = -78;\n  SQLE_INVALID_LOCAL_OPTION             = -79;\n  SQLE_UNABLE_TO_START_ENGINE           = -80;\n  SQLE_INVALID_COMMAND_LINE             = -81;\n  SQLE_UNABLE_TO_START_DATABASE         = -82;\n  SQLE_DATABASE_NOT_FOUND               = -83;\n  SQLE_INVALID_DATABASE                 = -84;\n  SQLE_COMMUNICATIONS_ERROR             = -85;\n  SQLE_NO_MEMORY                        = -86;\n  SQLE_DATABASE_NAME_REQUIRED           = -87;\n  SQLE_PROTOCOL_MISMATCH                = -88;\n  SQLE_ENGINE_NOT_MULTIUSER             = -89;\n  SQLE_ARGUMENT_CANNOT_BE_NULL          = -90;\n  SQLE_UNHANDLED_JAVA_EXCEPTION         = -91;\n  SQLE_BAD_CLASS_FILE                   = -92;\n  SQLE_FIELD_NOT_FOUND                  = -93;\n  SQLE_INVALID_FIELD_REFERENCE          = -94;\n  SQLE_INVALID_PARSE_PARAMETER          = -95;\n  SQLE_ENGINE_ALREADY_RUNNING           = -96;\n  SQLE_PAGE_SIZE_TOO_BIG                = -97;\n  SQLE_AUTHENTICATION_VIOLATION         = -98;\n  SQLE_CONNECTIONS_DISABLED             = -99;\n  SQLE_ENGINE_NOT_RUNNING               = -100;\n  SQLE_NOT_CONNECTED                    = -101;\n  SQLE_TOO_MANY_CONNECTIONS             = -102;\n  SQLE_INVALID_LOGON                    = -103;\n  SQLE_INVALID_PASSWORD                 = -103;\n  SQLE_INVALID_MODULE_LOGON             = -104;\n  SQLE_UNABLE_TO_CONNECT                = -105;\n  SQLE_CANNOT_OPEN_LOG                  = -106;\n  SQLE_ERROR_WRITING_LOG                = -107;\n  SQLE_CONNECTION_NOT_FOUND             = -108;\n  SQLE_STILL_ACTIVE_CONNECTIONS         = -109;\n  SQLE_NAME_NOT_UNIQUE                  = -110;\n  SQLE_INDEX_NAME_NOT_UNIQUE            = -111;\n  SQLE_EXISTING_PRIMARY_KEY             = -112;\n  SQLE_INVALID_FOREIGN_KEY_DEF          = -113;\n  SQLE_VIEW_DEFINITION_ERROR            = -114;\n  SQLE_MUST_DROP_INDEX                  = -115;\n  SQLE_TABLE_MUST_BE_EMPTY              = -116;\n  SQLE_PRIMARY_KEY_REFERENCED           = -117;\n  SQLE_NO_PRIMARY_KEY                   = -118;\n  SQLE_PRIMARY_KEY_COLUMN_DEFINED       = -119;\n  SQLE_ALREADY_HAS_GRANT_PERMS          = -120;\n  SQLE_PERMISSION_DENIED                = -121;\n  SQLE_GROUP_CYCLE                      = -122;\n  SQLE_NOT_A_GROUP                      = -123;\n  SQLE_TOO_MANY_COLUMNS_DELETED         = -124;\n  SQLE_ALTER_CLAUSE_CONFLICT            = -125;\n  SQLE_PRIMARY_KEY_TWICE                = -126;\n  SQLE_COLUMN_IN_INDEX                  = -127;\n  SQLE_USER_OWNS_TABLES                 = -128;\n  SQLE_INVALID_STATEMENT                = -130;\n  SQLE_SYNTAX_ERROR                     = -131;\n  SQLE_STATEMENT_ERROR                  = -132;\n  SQLE_INVALID_STATEMENT_TYPE           = -133;\n  SQLE_NOT_IMPLEMENTED                  = -134;\n  SQLE_LANGUAGE_EXTENSION               = -135;\n  SQLE_OUTER_JOIN_CYCLE                 = -136;\n  SQLE_CORRELATION_NAME_NEEDED          = -137;\n  SQLE_DBSPACE_NOT_FOUND                = -138;\n  SQLE_CORRELATION_NAME_AMBIGUOUS       = -139;\n  SQLE_UNKNOWN_USERID                   = -140;\n  SQLE_TABLE_NOT_FOUND                  = -141;\n  SQLE_CORRELATION_NAME_NOT_FOUND       = -142;\n  SQLE_COLUMN_NOT_FOUND                 = -143;\n  SQLE_COLUMN_AMBIGUOUS                 = -144;\n  SQLE_FOREIGN_KEY_NAME_NOT_FOUND       = -145;\n  SQLE_CANNOT_JOIN                      = -146;\n  SQLE_AMBIGUOUS_JOIN                   = -147;\n  SQLE_UNKNOWN_FUNC                     = -148;\n  SQLE_INVALID_GROUP_SELECT             = -149;\n  SQLE_AGGREGATES_NOT_ALLOWED           = -150;\n  SQLE_SUBQUERY_SELECT_LIST             = -151;\n  SQLE_INVALID_ORDER                    = -152;\n  SQLE_INVALID_UNION                    = -153;\n  SQLE_WRONG_PARAMETER_COUNT            = -154;\n  SQLE_VARIABLE_INVALID                 = -155;\n  SQLE_EXPRESSION_ERROR                 = -156;\n  SQLE_CONVERSION_ERROR                 = -157;\n  SQLE_OVERFLOW_ERROR                   = -158;\n  SQLE_INVALID_COLUMN_NUMBER            = -159;\n  SQLE_DESCRIBE_NONSELECT               = -160;\n  SQLE_INVALID_DESCRIBE_TYPE            = -161;\n  SQLE_CANNOT_OUTER_JOIN                = -162;\n  SQLE_NO_COLUMN_NAME                   = -163;\n  SQLE_NAMESPACE_HEAP_EXHAUSTED         = -164;\n  SQLE_JAVA_VM_HEAP_EXHAUSTED           = -165;\n  SQLE_CURSOR_NOT_DECLARED              = -170;\n  SQLE_OPEN_CURSOR_ERROR                = -171;\n  SQLE_CURSOR_ALREADY_OPEN              = -172;\n  SQLE_CURSOR_NOT_OPEN                  = -180;\n  SQLE_NO_INDICATOR                     = -181;\n  SQLE_SQLDA_TOO_SMALL                  = -182;\n  SQLE_INDEX_NOT_FOUND                  = -183;\n  SQLE_PUT_CURSOR_ERROR                 = -184;\n  SQLE_TOO_MANY_RECORDS                 = -185;\n  SQLE_SUBQUERY_RESULT_NOT_UNIQUE       = -186;\n  SQLE_CURSOROP_NOT_ALLOWED             = -187;\n  SQLE_NOT_ENOUGH_HOST_VARS             = -188;\n  SQLE_NOT_FOUND_IN_INDEX               = -189;\n  SQLE_NON_UPDATEABLE_COLUMN            = -190;\n  SQLE_CANNOT_MODIFY                    = -191;\n  SQLE_NON_UPDATEABLE_VIEW              = -192;\n  SQLE_PRIMARY_KEY_NOT_UNIQUE           = -193;\n  SQLE_INVALID_FOREIGN_KEY              = -194;\n  SQLE_COLUMN_CANNOT_BE_NULL            = -195;\n  SQLE_INDEX_NOT_UNIQUE                 = -196;\n  SQLE_NO_CURRENT_ROW                   = -197;\n  SQLE_PRIMARY_KEY_VALUE_REF            = -198;\n  SQLE_ONLY_ONE_TABLE                   = -199;\n  SQLE_INVALID_OPTION                   = -200;\n  SQLE_INVALID_OPTION_SETTING           = -201;\n  SQLE_NOT_PUBLIC_ID                    = -202;\n  SQLE_TEMPORARY_NOT_ALLOWED            = -203;\n  SQLE_OPTION_REQUIRES_DBA              = -204;\n  SQLE_INVALID_STANDARD_LOGON           = -205;\n  SQLE_INVALID_INTEGRATED_LOGON         = -206;\n  SQLE_WRONG_NUM_OF_INSERT_COLS         = -207;\n  SQLE_ROW_UPDATED_SINCE_READ           = -208;\n  SQLE_INVALID_COLUMN_VALUE             = -209;\n  SQLE_LOCKED                           = -210;\n  SQLE_MUST_BE_ONLY_CONNECTION          = -211;\n  SQLE_CHECKPOINT_REQUIRES_UNDO         = -212;\n  SQLE_SUBTRANS_REQUIRE_UNDO            = -213;\n  SQLE_TABLE_IN_USE                     = -214;\n  SQLE_PROCEDURE_IN_USE                 = -215;\n  SQLE_OPTION_IS_TEMP_ONLY              = -216;\n  SQLE_OPTION_IN_PROCEDURE              = -217;\n  SQLE_AUTHENTICATION_FAILED            = -218;\n  SQLE_SQLE_SUBTRANS_NOTFOUND           = -220;\n  SQLE_ROLLBACK_NOT_ALLOWED             = -221;\n  SQLE_RESULT_NOT_ALLOWED               = -222;\n  SQLE_PP_DBLIB_MISMATCH                = -230;\n  SQLE_DBLIB_ENGINE_MISMATCH            = -231;\n  SQLE_SERVER_ENGINE_MISMATCH           = -232;\n  SQLE_UNKNOWN_BACKUP_OPERATION         = -240;\n  SQLE_BACKUP_NOT_STARTED               = -241;\n  SQLE_BACKUP_CANNOT_RENAME_LOG_YET     = -242;\n  SQLE_BACKUP_UNABLE_TO_DELETE_FILE     = -243;\n  SQLE_LOG_TRUNCATED                    = -244;\n  SQLE_INTEGRATED_LOGON_FAILED          = -245;\n  SQLE_INTEGRATED_LOGON_UNSUPPORTED     = -246;\n  SQLE_INTEGRATED_LOGON_GUESTMAP        = -247;\n  SQLE_INTEGRATED_LOGON_SYSMAP          = -248;\n  SQLE_INTEGRATED_LOGON_MAPPED          = -249;\n  SQLE_IDENTIFIER_TOO_LONG              = -250;\n  SQLE_DUPLICATE_FOREIGN_KEY            = -251;\n  SQLE_PRIMARY_KEY_MULTI_ROW_UPDATE     = -252;\n  SQLE_PRIMARY_KEY_CURSOR_UPDATE        = -253;\n  SQLE_DELETE_SUBQUERY_SAME_TABLE       = -254;\n  SQLE_CURSOR_DELETE_SELF_REF           = -255;\n  SQLE_INSERT_SELF_REFERENCING          = -256;\n  SQLE_VARIABLE_NOT_FOUND               = -260;\n  SQLE_VARIABLE_EXISTS                  = -261;\n  SQLE_LABEL_NOT_FOUND                  = -262;\n  SQLE_INVALID_FETCH_POSITION           = -263;\n  SQLE_WRONG_NUM_OF_FETCH_VARIABLES     = -264;\n  SQLE_PROCEDURE_NOT_FOUND              = -265;\n  SQLE_OLD_DBINIT                       = -266;\n  SQLE_ATOMIC_OPERATION                 = -267;\n  SQLE_TRIGGER_NOT_FOUND                = -268;\n  SQLE_COLUMN_IN_TRIGGER                = -269;\n  SQLE_USER_OWNS_PROCEDURES             = -270;\n  SQLE_TRIGGER_DEFN_CONFLICT            = -271;\n  SQLE_INVALID_TRIGGER_COL_REFS         = -272;\n  SQLE_INVALID_TRIGGER_STATEMENT        = -273;\n  SQLE_NESTING_TOO_DEEP                 = -274;\n  SQLE_PROCEDURES_NOT_IN_DESKTOP        = -275;\n  SQLE_PUBLICATION_NOT_FOUND            = -280;\n  SQLE_TABLE_HAS_PUBLICATIONS           = -281;\n  SQLE_SUBSCRIPTION_NOT_UNIQUE          = -282;\n  SQLE_SUBSCRIPTION_NOT_FOUND           = -283;\n  SQLE_ONLY_ONE_PUBLISHER               = -284;\n  SQLE_NOT_REMOTE_USER                  = -285;\n  SQLE_NOT_REMOTE_TYPE                  = -286;\n  SQLE_PASSTHROUGH_INCONSISTENT         = -287;\n  SQLE_REMOTE_STATEMENT_FAILED          = -288;\n  SQLE_CONSOLIDATED_USER_ALREADY_EXISTS = -289;\n  SQLE_INVALID_FORMAT_STRING_ARG_NUM    = -294;\n  SQLE_CANNOT_UNIQUELY_IDENTIFY_ROWS    = -295;\n  SQLE_ERROR_NUMBER_OUT_OF_RANGE        = -296;\n  SQLE_USER_DEFINED_EXCEPTION           = -297;\n  SQLE_DOUBLE_REQUEST                   = -298;\n  SQLE_INTERRUPTED                      = -299;\n  SQLE_ERROR                            = -300;\n  SQLE_DATABASE_ERROR                   = -301;\n  SQLE_TERMINATED_BY_USER               = -302;\n  SQLE_DISK_WRITE_FAILED                = -303;\n  SQLE_DEVICE_FULL                      = -304;\n  SQLE_DEVICE_ERROR                     = -305;\n  SQLE_DEADLOCK                         = -306;\n  SQLE_THREAD_DEADLOCK                  = -307;\n  SQLE_CONNECTION_TERMINATED            = -308;\n  SQLE_MEMORY_ERROR                     = -309;\n  SQLE_BEYOND_EOF                       = -310;\n  SQLE_LOG_CORRUPTED                    = -311;\n  SQLE_ALREADY_HAS_GROUP_MEMBERSHIP     = -312;\n  SQLE_INTEGRATED_LOGON_UNMAPPED        = -313;\n  SQLE_HLI_BAD_SYNTAX                   = -400;\n  SQLE_HLI_BAD_CURSOR                   = -401;\n  SQLE_HLI_BAD_STATEMENT                = -402;\n  SQLE_HLI_BAD_HOST_VAR_NAME            = -403;\n  SQLE_HLI_BAD_HOST_VAR_VALUE           = -404;\n  SQLE_HLI_BAD_CALLBACK                 = -405;\n  SQLE_HLI_INTERNAL                     = -406;\n  SQLE_HLI_BAD_ARGUMENT                 = -407;\n  SQLE_PHANTOM                          = -501;\n  SQLE_UNBLOCKED                        = -502;\n  SQLE_PREEMPTED                        = -503;\n  SQLE_RETRY                            = -504;\n  SQLE_UNSUPPORTED_LOAD_FORMAT          = -601;\n  SQLE_CANNOT_ACCESS_FILE               = -602;\n  SQLE_COLUMN_VALUE_TOO_LONG            = -603;\n  SQLE_DBSPACE_FULL                     = -604;\n  SQLE_ACCESS_BEYOND_END_OF_MAX_DBSPACE = -605;\n  SQLE_PATTERN_TOO_LONG                 = -606;\n  SQLE_CANNOT_STOP_SERVER               = -607;\n  SQLE_INVALID_TEXTPTR_VALUE            = -608;\n  SQLE_INVALID_TEXT_IMAGE_DATATYPE      = -609;\n  SQLE_MESSAGE_ALREADY_EXISTS           = -610;\n  SQLE_TSQL_FEATURE_NOT_SUPPORTED       = -611;\n  SQLE_MESSAGE_NOT_FOUND                = -612;\n  SQLE_USER_TYPE_NOT_FOUND              = -613;\n  SQLE_USER_OWNS_MESSAGES_OR_DATATYPES  = -614;\n  SQLE_INVALID_PARAMETER_NAME           = -615;\n  SQLE_TOO_MANY_COLUMNS_IN_TABLE        = -616;\n  SQLE_EXTERNAL_CALLS_NOT_SUPPORTED     = -617;\n  SQLE_EXTERNAL_PLATFORM_FAILURE        = -618;\n  SQLE_REQUIRE_DLL_NAME                 = -619;\n  SQLE_COULD_NOT_LOAD_LIBRARY           = -620;\n  SQLE_COULD_NOT_FIND_FUNCTION          = -621;\n  SQLE_ERROR_CALLING_FUNCTION           = -622;\n  SQLE_DDL_NOT_ALLOWED_IN_PROCEDURES    = -623;\n  SQLE_DATATYPE_NOT_ALLOWED             = -624;\n  SQLE_TOO_MANY_PARAMETERS              = -625;\n  SQLE_THREAD_START_FAILURE             = -626;\n  SQLE_INVALID_SYNTAX_EXTENSION         = -627;\n  SQLE_DIV_ZERO_ERROR                   = -628;\n  SQLE_INVALID_ESCAPE_CHAR              = -629;\n  SQLE_INVALID_ESCAPE_SEQ               = -630;\n  SQLE_RAISERROR_STMT                   = -631;\n  SQLE_WITH_CHECK_OPTION_VIOLATION      = -632;\n  SQLE_READ_ONLY_CURSOR                 = -633;\n  SQLE_UNTERMINATED_C_STR               = -634;\n  SQLE_NO_COLUMN_PERMS_FOR_VIEWS        = -635;\n  SQLE_DUPLICATE_REFERENCING_COLUMN     = -636;\n  SQLE_DUPLICATE_INSERT_COLUMN          = -637;\n  SQLE_STRING_RIGHT_TRUNCATION          = -638;\n  SQLE_PARAMETER_NAME_MISSING           = -639;\n  SQLE_INVALID_DESCRIPTOR_INDEX         = -640;\n  SQLE_ERROR_IN_ASSIGNMENT              = -641;\n  SQLE_INVALID_DESCRIPTOR_NAME          = -642;\n  SQLE_CANNOT_UNLOAD_A_VIEW             = -643;\n  SQLE_PAGE_SIZE_INVALID                = -644;\n  SQLE_DATABASE_NOT_CREATED             = -645;\n  SQLE_STORE_NOT_LOADED                 = -646;\n  SQLE_STORE_ENTRY_NOT_FOUND            = -647;\n  SQLE_INVALID_DBSPACE_FOR_CREATE       = -648;\n  SQLE_FIELD_CANNOT_BE_NULL             = -649;\n  SQLE_INVALID_INDEX_TYPE               = -650;\n  SQLE_DROP_DATABASE_FAILED             = -651;\n  SQLE_CANNOT_DECOMPRESS_CLASS          = -652;\n  SQLE_CLASS_MEMBER_OF_JAR              = -653;\n  SQLE_NO_PROFILE_FILE                  = -654;\n  SQLE_GEN_PARSE_ERROR                  = -655;\n  SQLE_OMNI_CONNECT_ERROR               = -656;\n  SQLE_OMNI_NO_RMT_OBJ                  = -657;\n  SQLE_OMNI_READONLY                    = -658;\n  SQLE_OMNI_SERVER_NOT_FOUND            = -659;\n  SQLE_OMNI_REMOTE_ERROR                = -660;\n  SQLE_OMNI_BACKWARDS_CURSOR            = -661;\n  SQLE_JAVA_SERIALIZATION_ERROR         = -662;\n  SQLE_JAVA_DESERIALIZATION_ERROR       = -663;\n  SQLE_DATABASE_ACTIVE                  = -664;\n  SQLE_DATABASE_NEEDS_RECOVERY          = -665;\n  SQLE_OMNI_RMT_TABLE_NOTFOUND          = -666;\n  SQLE_OMNI_RMT_COLUMNS_NOTFOUND        = -667;\n  SQLE_NO_SCROLL_CURSOR                 = -668;\n  SQLE_METHOD_CANNOT_BE_CALLED          = -669;\n  SQLE_BAD_CLASS_BYTE_CODE              = -670;\n  SQLE_PARAM_NOT_REGISTERED             = -671;\n  SQLE_DATABASE_UPGRADE_FAILED          = -672;\n  SQLE_DATABASE_UPGRADE_NOT_POSSIBLE    = -673;\n  SQLE_INVALID_CURSOR_RANGE             = -674;\n  SQLE_JAVA_VM_NOT_STARTED              = -675;\n  SQLE_INVALID_TRANSACTION_ISOLATION    = -676;\n  SQLE_TABLE_HAS_REFACTION              = -677;\n  SQLE_AMBIGUOUS_INDEX_NAME             = -678;\n  SQLE_OMNI_MEMORY_CONFIG               = -679;\n  SQLE_INVALID_TSQL_OJ_EXPRESSION       = -680;\n  SQLE_INVALID_TSQL_JOIN_TYPE           = -681;\n  SQLE_OMNI_DEBUG                       = -682;\n  SQLE_DUPLICATE_CURSOR_NAME            = -683;\n  SQLE_ROLLBACK_ON_PREFETCH             = -684;\n  SQLE_RESOURCE_GOVERNOR_EXCEEDED       = -685;\n  SQLE_JAVA_VM_INSUFFICIENT_CACHE       = -686;\n  SQLE_IQ_PATH_SYNTAX_ERROR             = -687;\n  SQLE_NO_ENCRYPTION_IN_RUNTIME         = -688;\n  SQLE_BAD_PARAM_INDEX                  = -689;\n  SQLE_RETVAL_CANNOT_BE_SET             = -690;\n  SQLE_BACKUP_NOT_LOADED                = -691;\n  SQLE_BACKUP_ENTRY_NOT_FOUND           = -692;\n  SQLE_UNSUPPORTED_JDBC_FEATURE         = -693;\n  SQLE_CANNOT_CHANGE_OPENED_STATEMENT   = -694;\n  SQLE_JDBC_OBJ_INTERNAL_ERR            = -695;\n  SQLE_JDBC_OBJ_CLOSED                  = -696;\n  SQLE_BACKUP_ERROR                     = -697;\n  SQLE_OMNI_AUTOINC_NOT_SUPPORTED       = -698;\n  SQLE_CANNOT_UPDATE_FINAL_FIELD        = -699;\n  SQLE_SQLDA_INCONSISTENT               = -700;\n  SQLE_CANNOT_ACCESS_INSTANCE_MEMBER    = -701;\n  SQLE_CANNOT_TRUNCATE_VIEW             = -702;\n  SQLE_COMPUTED_COLUMN_WRITE_ATTEMPTED  = -703;\n  SQLE_CANNOT_INDEX_ON_JAVA_CLASS       = -704;\n  SQLE_PROCEDURE_RETURNS_VOID           = -705;\n  SQLE_OMNI_SERVER_NOT_CAPABLE          = -706;\n  SQLE_STMT_NOT_ALLOWED_IN_PASSTHROUGH  = -707;\n  SQLE_TEXT_OPERATION_ON_VIEW           = -708;\n  SQLE_COMPUTED_COLUMNS_NOT_SUPPORTED   = -709;\n  SQLE_INVALID_COMPARISON               = -710;\n  SQLE_STORE_VERSION_MISMATCH           = -711;\n  SQLE_OMNI_EXTLOGIN_NOT_FOUND          = -712;\n  SQLE_JNAT_OBJ_INTERNAL_ERR            = -713;\n  SQLE_JNAT_OBJ_CLOSED                  = -714;\n  SQLE_RESTORE_INCONSISTENT             = -715;\n  SQLE_RESTORE_INVALID_FORMAT           = -716;\n  SQLE_RESTORE_UNABLE_TO_OPEN           = -717;\n  SQLE_RESTORE_UNABLE_TO_WRITE          = -718;\n  SQLE_RESTORE_UNABLE_TO_START          = -719;\n  SQLE_CANNOT_VALIDATE_OBJECT           = -720;\n  SQLE_OMNI_DATATYPE_MISMATCH           = -721;\n  SQLE_OMNI_NOSUCH_COLUMN               = -722;\n  SQLE_OMNI_LENGTH_MISMATCH             = -723;\n  SQLE_OMNI_NULL_MISMATCH               = -724;\n  SQLE_OMNI_IDENTITY_MISMATCH           = -725;\n  SQLE_OMNI_RMT_TABLE_NOTUNIQUE         = -726;\n  SQLE_CANNOT_OPTIMIZE_QUERY            = -727;\n  SQLE_NON_UPDATEABLE_EXT_TAB           = -728;\n  SQLE_UNENFORCEABLE_FOREIGN_KEY        = -729;\n  SQLE_BAD_JAR_FILE                     = -730;\n  SQLE_USER_OWNS_REPLICATED_OBJECTS     = -731;\n  SQLE_OMNI_COMPUTED_NOT_SUPPORTED      = -732;\n  SQLE_TOO_MANY_NULL_COLUMNS            = -733;\n  SQLE_CANNOT_UPDATE_NULL_ROW           = -734;\n  SQLE_INVALID_PARAMETER                = -735;\n  SQLE_OMNI_UNSUPPORTED_DATATYPE        = -736;\n  SQLE_SIGNATURE_MISMATCH               = -737;\n  SQLE_PASSWORD_TOO_SHORT               = -738;\n  SQLE_DB_INIT_NOT_CALLED               = -739;\n  SQLE_FAILED_TO_CREATE_STREAMS_ENV     = -740;\n  SQLE_NOTA_WRITE_FILE                  = -741;\n  SQLE_JDBC_BATCH_EXECUTE_ABANDONED     = -742;\n  SQLE_JDBC_RESULTSET_SEEK_ABSOLUTE_ZERO = -743;\n  SQLE_IQ_INVALID_COMMAND_LINE          = -744;\n  SQLE_IQ_MEMORY_MANAGER_FAILED         = -745;\n  SQLE_IQ_SYSTEM_V_FAILURE              = -746;\n  SQLE_JDBC_INVALID_RESULTSET_TYPE      = -747;\n  SQLE_JDBC_INVALID_RESULTSET_CONCURRENCY = -748;\n  SQLE_NOT_SUPPORTED_IN_ULTRALITE       = -749;\n  SQLE_USER_OWNS_PROCEDURES_IN_USE      = -750;\n  SQLE_USER_OWNS_TABLES_IN_USE          = -751;\n  SQLE_JDBC_INVALID_OPER_ON_INSERT_ROW  = -752;\n  SQLE_JDBC_MUST_OPER_ON_INSERT_ROW     = -753;\n  SQLE_INVALID_DSN_NAME                 = -754;\n  SQLE_UNCOMMITTED_TRANSACTIONS         = -755;\n  SQLE_JDBC_TBL_COL_NOT_FOUND_IN_RESULTSET = -756;\n  SQLE_READ_ONLY_DATABASE               = -757;\n  SQLE_NO_JAVA_SUPPORT                  = -758;\n  SQLE_SQLDA_INVALID_DATATYPE           = -759;\n  SQLE_INVALID_SQL_IDENTIFIER           = -760;\n  SQLE_CAPABILITY_NOT_FOUND             = -761;\n  SQLE_NON_PUBLIC_JAVA_CLASS            = -762;\n  SQLE_UNKNOWN_JAVA_REF                 = -763;\n  SQLE_UNABLE_TO_CONNECT_OR_START       = -764;\n  SQLE_NOT_SYNC_TYPE                    = -765;\n  SQLE_VIEW_OVER_TEMP_OBJECT            = -766;\n  SQLE_SYNCHRONIZATION_NOT_FOUND        = -767;\n  SQLE_CANNOT_SUBSCRIBE                 = -768;\n  SQLE_CANNOT_MODIFY_SYNC_AS_PUB        = -769;\n  SQLE_CANNOT_MODIFY_PUB_AS_SYNC        = -770;\n  SQLE_EVENT_NOT_FOUND                  = -771;\n  SQLE_EVENT_ALREADY_EXISTS             = -772;\n  SQLE_SCHEDULE_NOT_FOUND               = -773;\n  SQLE_SCHEDULE_ALREADY_EXISTS          = -774;\n  SQLE_CANNOT_SYNC_TABLE_WITHOUT_PK     = -777;\n  SQLE_PK_NOT_IN_SYNC_ARTICLE           = -778;\n  SQLE_BLOB_IN_SYNC_TABLE_PK            = -779;\n  SQLE_ARTICLE_PK_CANNOT_BE_UPDATED     = -780;\n  SQLE_SAME_EXCLUSIVE_APP_RUNNING       = -782;\n  SQLE_SAME_APP_RUNNING                 = -783;\n  SQLE_CANNOT_REG_CONN                  = -784;\n  SQLE_DEREG_APP_NOT_FOUND              = -785;\n  SQLE_DEREG_APP_IN_USE                 = -786;\n  SQLE_CONN_ALREADY_REGISTERED          = -787;\n  SQLE_NOT_UNIQUE_CONN_REG_LABEL        = -788;\n  SQLE_APP_REG_COOKIE_EXHAUSTED         = -789;\n  SQLE_CONN_REG_AUTO_LABEL_EXHAUSTED    = -790;\n  SQLE_INVALID_EVENT_DAY                = -791;\n  SQLE_INVALID_EVENT_TIME               = -792;\n  SQLE_INVALID_EVENT_START              = -793;\n  SQLE_UPLOAD_FAILED_AT_SERVER          = -794;\n  SQLE_SYNC_TEMPLATE_NOT_FOUND          = -795;\n  SQLE_SYNC_SITE_NOT_UNIQUE             = -796;\n  SQLE_BAD_SYNC_OPTION_VALUE            = -797;\n  SQLE_DTC_TRANSACTIONS_NOT_SUPPORTED   = -799;\n  SQLE_CANNOT_COMMIT_OR_ROLLBACK_WHILE_ENLISTED = -800;\n  SQLE_CANNOT_ENLIST_WHILE_ALREADY_ENLISTED = -801;\n  SQLE_CANNOT_ENLIST_WITH_UNCOMMITTED_DATA = -802;\n  SQLE_FAILED_TO_ENLIST                 = -803;\n  SQLE_FAILED_TO_REENLIST               = -804;\n  SQLE_SYNC_OPTION_NOT_FOUND            = -805;\n  SQLE_EVENT_TYPE_NOT_FOUND             = -806;\n  SQLE_HOSTVARS_IN_BATCH                = -807;\n  SQLE_TEST_HARNESS                     = -808;\n  SQLE_SYNC_OPTION_TOO_LONG             = -809;\n  SQLE_JAVA_CLASS_NOT_FOUND             = -810;\n  SQLE_JAR_NOT_FOUND                    = -811;\n  SQLE_NO_MATCHING_SELECT_ITEM          = -812;\n  SQLE_NON_UPDATEABLE_CURSOR            = -813;\n  SQLE_CANNOT_UPDATE_ORDER_BY_COLUMN    = -814;\n  SQLE_UPDATE_NOT_IN_SELECT             = -815;\n  SQLE_FILE_IN_USE                      = -816;\n  SQLE_TOO_MANY_TEMP_TABLES             = -817;\n  SQLE_INCOMPATIBLE_EXTERNAL_CALL       = -818;\n  SQLE_SYNC_CONTAINS_TABLE              = -819;\n  SQLE_INVALID_POSITION                 = -820;\n  SQLE_DBSPACE_FOR_TABLE_UNAVAILABLE    = -821;\n  SQLE_TABLE_ALREADY_INCLUDED           = -822;\n  SQLE_OMNI_EXPRESSION_IN_PROC          = -823;\n  SQLE_INVALID_CORRELATION_NAME_REFERENCE = -824;\n  SQLE_PREVIOUS_ERROR_LOST              = -825;\n  SQLE_DBO_DOES_NOT_OWN_ROWGENERATOR    = -826;\n  SQLE_USER_TABLES_IN_SYSTEM_RANGE      = -827;\n  SQLE_RECORDING_CONFLICT_DETECTED      = -828;\n  SQLE_CERTICOM_HANDSHAKE_FAILED        = -829;\n  SQLE_ALIAS_NOT_UNIQUE                 = -830;\n  SQLE_ALIAS_NOT_YET_DEFINED            = -831;\n  SQLE_CONNECTION_ERROR                 = -832;\n  SQLE_ROW_REMODIFIED_OR_DELETED        = -833;\n  SQLE_COLUMN_NOT_FOUND_IN_TABLE        = -834;\n  SQLE_EVENT_IN_USE                     = -835;\n  SQLE_PROCEDURE_NO_LONGER_VALID        = -836;\n  SQLE_TRIGGER_NO_LONGER_VALID          = -837;\n  SQLE_CERTICOM_INIT_FAILED_ON_SRV      = -838;\n  SQLE_DOWNLOAD_CONFLICT                = -839;\n  SQLE_BAD_ENCRYPTION_KEY               = -840;\n  SQLE_JDK_VERSION_MISMATCH             = -841;\n  SQLE_UNSUPPORTED_JDK                  = -842;\n  SQLE_SYNC_SITE_NOT_FOUND              = -843;\n  SQLE_SYNC_DEFINITION_NOT_FOUND        = -844;\n  SQLE_INVALID_COLUMN_QUALIFICATION     = -845;\n  SQLE_INVALID_SET_CLAUSE               = -846;\n  SQLE_JAVA_SECMGR_NOT_FOUND            = -847;\n  SQLE_JAVA_SECMGR_EXCEPTION            = -848;\n  SQLE_INVALID_FOREIGN_KEY_ACTION       = -849;\n  SQLE_INVALID_FOREIGN_KEY_TABLE        = -850;\n  SQLE_DECRYPT_ERROR                    = -851;\n  SQLE_AMBIGUOUS_TABLE_NAME             = -852;\n  SQLE_CURSOR_INVALID_STATE             = -853;\n  SQLE_INVALID_ORDERBY_COLUMN           = -854;\n  SQLE_AMBIGUOUS_TRIGGER_NAME           = -855;\n  SQLE_INVALID_SQLLEN                   = -856;\n  SQLE_SERVER_SYNCHRONIZATION_ERROR     = -857;\n  SQLE_HISTOGRAMS_NOT_SUPPORTED_ON_OBJECT = -858;\n  SQLE_JAVA_IN_USE                      = -859;\n  SQLE_DBSPACE_NOT_CALIBRATED           = -860;\n  SQLE_MULTIPLE_AGGREGATE_COLUMNS       = -861;\n  SQLE_INVALID_AGGREGATE_PLACEMENT      = -862;\n  SQLE_INVALID_DISTINCT_AGGREGATE       = -863;\n  SQLE_INVALID_NUMBER                   = -864;\n  SQLE_INVALID_FOREIGN_KEY_INDEX        = -865;\n  SQLE_CANNOT_CHANGE_USER_NAME          = -867;\n  SQLE_UNKNOWN_CHARSET                  = -868;\n  SQLE_UNSUPPORTED_CHARACTER_SET_ERROR  = -869;\n  SQLE_FAILED_TO_START_CONVERTER        = -870;\n  SQLE_JAVA_DB_RESTART_NEEDED           = -871;\n  SQLE_CANNOT_JOIN_TABEXPR              = -875;\n  SQLE_CLIENT_OUT_OF_MEMORY             = -876;\n  SQLE_SETUSER_NOT_IN_PROCEDURES        = -877;\n  SQLE_CLUSTERED_INDEX_NOT_ALLOWED      = -878;\n  SQLE_INPUT_ILLEGAL_MULTIBYTE_ERROR    = -879;\n  SQLE_OUTPUT_ILLEGAL_MULTIBYTE_ERROR   = -880;\n  SQLE_INPUT_SIMPLE_SUBSTITUTION_ERROR  = -881;\n  SQLE_OUTPUT_SIMPLE_SUBSTITUTION_ERROR = -882;\n  SQLE_CHARACTER_CONVERSION_REPORT_NOT_AVAILABLE = -883;\n  SQLE_NONDETERMINISTIC_FUNCTION        = -889;\n  SQLE_SYNTACTIC_LIMIT                  = -890;\n  SQLE_FAILED_TO_START_CONVERTER_2_CHARSETS = -891;\n  SQLE_STMT_NOT_ALLOWED_IN_PLAN         = -894;\n  SQLE_ENCRYPT_ERROR                    = -895;\n  SQLE_UNSET_PUBLIC_ID                  = -896;\n  SQLE_BAD_FOR_XML_EXPLICIT_TAG         = -897;\n  SQLE_BAD_FOR_XML_EXPLICIT_DIRECTIVE   = -898;\n  SQLE_BAD_FOR_XML_EXPLICIT_COLUMN_NAME = -899;\n  SQLE_EXPLICIT_TAG_NOT_OPEN            = -900;\n  SQLE_UNDECLARED_FOR_XML_EXPLICIT_TAG  = -901;\n  SQLE_FOR_XML_EXPLICIT_TOO_FEW_COLUMNS = -902;\n  SQLE_FOR_XML_EXPLICIT_NAMED_CDATA     = -903;\n  SQLE_INVALID_ORDERBY_IN_AGGREGATE     = -904;\n  SQLE_INVALID_XQUERY_CONSTRUCTOR       = -905;\n  SQLE_XMLGEN_EVALUATION_FAILURE        = -906;\n  SQLE_NO_SQLX_ARGUMENT_NAME            = -907;\n  SQLE_ULTRALITE_OBJ_CLOSED             = -908;\n  SQLE_SYSTEM_COMMAND_FAILED            = -910;\n  SQLE_IQ_LOG_REQUIRED                  = -933;\n  SQLE_UNABLE_TO_START_DATABASE_VER_NEWER = -934;\n  SQLE_PASSWORD_TOO_LONG                = -958;\n  SQLE_ILLEGAL_PASSWORD                 = -963;\n  SQLE_ALREADY_HAS_EXEC_PERMS           = -968;\n  SQLE_PAGE_SIZE_TOO_SMALL              = -972;\n  SQLE_STRING_PARM_TOO_LONG             = -973;\n  SQLE_INVALID_TEMP_TABLE_COMMIT_ACTION = -993;\n  SQLE_TOO_MANY_ARGUMENTS               = -994;\n  SQLE_TEMP_SPACE_LIMIT                 = -1000;\n  SQLE_FILE_NOT_DB                      = -1004;\n  SQLE_FILE_WRONG_VERSION               = -1005;\n  SQLE_FILE_BAD_DB                      = -1006;\n  SQLE_CORRUPT_REDO                     = -1007;\n  SQLE_CORRUPT_REDO_MIRROR              = -1008;\n  SQLE_CORRUPT_REDO_OR_MIRROR           = -1009;\n  SQLE_EXPECTING_NO_REDO                = -1010;\n  SQLE_UNKNOWN_ENCRYPTION_ALGORITHM     = -1011;\n  SQLE_UPGRADE_DATABASE                 = -1012;\n  SQLE_NO_DB_FOR_WRITE                  = -1013;\n  SQLE_FILE_IS_COMPRESSED               = -1014;\n  SQLE_OLD_WRITE                        = -1015;\n  SQLE_LOG_NEWER_THAN_DB                = -1016;\n  SQLE_LOG_NOT_FOUND                    = -1017;\n  SQLE_LOG_OFFSETS_DONT_MATCH           = -1018;\n  SQLE_LOG_OLDER_THAN_DB                = -1019;\n  SQLE_LOG_TOO_SHORT                    = -1020;\n\n  {dpp_fetch}\n  CUR_RELATIVE                  = 2;\n  CUR_ABSOLUTE                  = 1;\n\n  CUR_FORUPDATE                 = 8;\n  CUR_FORREGULAR                = 0;\n\n  CUR_DONTHOLD                  = 1;\n  CUR_READONLY                  = 2;\n  CUR_OPEN_DECLARE              = 32;\n  CUR_DYNAMIC_SCROLL            = 64;\n  CUR_SCROLL                    = 128;\n  CUR_SENSITIVE                 = 256;\n  CUR_INSENSITIVE               = 1024;\n  CUR_UNIQUE                    = 2048;\n  CUR_UPDATE                    = 4096;\n  CUR_UPDATEBYLOCK              = CUR_UPDATE + 512;\n  CUR_UPDATEBYVALUES            = CUR_UPDATEBYLOCK + 8192;\n  CUR_UPDATEBYTIMESTAMP         = CUR_UPDATE + 8192;\n  CUR_NOSCROLL                  = 16384;\n\n  SQL_DESCRIBE_OUTPUT           = 1;\n  SQL_DESCRIBE_INPUT            = 2;\n  SQL_DESCRIBE_ALL              = 3;\n  SQL_DESCRIBE_VAR_RESULT       = 8;\n\n  SQL_PREPARE_DESCRIBE_STMTNAME = 1;\n  SQL_PREPARE_DESCRIBE_STMTNUM  = 3;\n  SQL_PREPARE_DESCRIBE_OUTPUT   = 256;\n  SQL_PREPARE_DESCRIBE_INPUT    = 512;\n  SQL_PREPARE_DESCRIBE_LONGNAMES= 1024;\n  SQL_PREPARE_DESCRIBE_VARRESULT= 2048;\n\n  SQL_LONGNAMES_COLUMN          = 1;\n  SQL_LONGNAMES_TABLE           = 3;\n  SQL_LONGNAMES_OWNER           = 7;\n\n\n  DT_PROCEDURE_OUT    =\t$8000;\n  DT_PROCEDURE_IN     =\t$4000;\n  DT_UPDATEABLE       = $2000;\n  DT_DESCRIBE_INPUT   = $1000;\n  DT_AUTO_INCREMENT   = $0800;\n  DT_KEY_COLUMN\t\t    = $0400;\n  DT_HIDDEN_COLUMN\t  = $0200;\n  DT_HAS_USERTYPE_INFO = $0100;\n\n  DT_NULLS_ALLOWED  = $0001;\n\n{dataTypes }\n  DT_NOTYPE             =   0;\n  DT_SMALLINT           = 500;\n  DT_INT                = 496;\n  DT_DECIMAL            = 484;\n  DT_FLOAT              = 482;\n  DT_DOUBLE             = 480;\n  DT_DATE               = 384;\n  DT_STRING             = 460;\n  DT_FIXCHAR            = 452;\n  DT_VARCHAR            = 448;\n  DT_LONGVARCHAR        = 456;\n  DT_TIME               = 388;\n  DT_TIMESTAMP          = 392;\n  DT_TIMESTAMP_STRUCT   = 390;\n  DT_BINARY             = 524;\n  DT_LONGBINARY         = 528;\n  DT_VARIABLE           = 600;\n  DT_TINYINT            = 604;\n  DT_BIGINT\t            = 608;\n  DT_UNSINT             = 612;\n  DT_UNSSMALLINT\t      = 616;\n  DT_UNSBIGINT\t        = 620;\n  DT_BIT      \t        = 624;\n  DT_NSTRING\t          = 628;\n  DT_NFIXCHAR\t          = 632;\n  DT_NVARCHAR\t          = 636;\n  DT_LONGNVARCHAR\t      = 640;\n\n//Message Types Markus\n   MESSAGE_TYPE_INFO\t   = 0;\n   MESSAGE_TYPE_WARNING\t = 1;\n   MESSAGE_TYPE_ACTION\t = 2;\n   MESSAGE_TYPE_STATUS   = 3;\n\ntype\n  a_sql_len = SmallInt;\n  a_sql_ulen = Word;\n  a_sql_int32 = LongInt;\n  a_sql_type = SmallInt;\n\n  an_sql_code = LongInt;\n  an_sql_state = array[0..5] of AnsiChar;\n\ntype\n  TZASASQLWARN = record\n      sqlWarn0: array[0..0] of AnsiChar;\n      sqlWarn1: array[0..0] of AnsiChar;\n      sqlWarn2: array[0..0] of AnsiChar;\n      sqlWarn3: array[0..0] of AnsiChar;\n      sqlWarn4: array[0..0] of AnsiChar;\n      sqlWarn5: array[0..0] of AnsiChar;\n      sqlWarn6: array[0..0] of AnsiChar;\n      sqlWarn7: array[0..0] of AnsiChar;\n      sqlWarn8: array[0..0] of AnsiChar;\n      sqlWarn9: array[0..0] of AnsiChar;\n  end;\n\n  PZASASQLCA = ^TZASASQLCA;\n  TZASASQLCA = record\n    sqlcaID: array[0..7] of AnsiChar;\n    sqlcAbc   : a_sql_int32;\n    sqlCode   : an_sql_code;\n    sqlErrml  : SmallInt;\n    sqlErrmc  : array[0..69] of AnsiChar;\n    sqlErrp   : array[0..7] of AnsiChar;\n    sqlErrd   : array[0..5] of a_sql_int32;\n    sqlWarn   : TZASASQLWARN;\n    sqlState: array[0..5] of AnsiChar;\n  end;\n\n  PZASASQLNAME = ^TZASASQLNAME;\n  TZASASQLNAME = record\n    length : Word;\n    data: array[0..29] of AnsiChar;\n  end;\n\n  PZASASQLSTRING = ^TZASASQLSTRING;\n  TZASASQLSTRING = record\n    length : Word;\n    data: array[0..0] of AnsiChar;\n  end;\n\n  PZASASQLVAR = ^TZASASQLVAR;\n  TZASASQLVAR = record\n    sqlType: SmallInt;\n    sqlLen : a_sql_len;\n    sqlData: Pointer;\n    sqlInd : PSmallInt;\n    sqlName: TZASASQLNAME;\n  end;\n\n  PASASQLDA = ^TASASQLDA;\n  TASASQLDA = record\n    sqldaid: array[0..7] of AnsiChar;\n    sqldabc : LongWord;\n    sqln    : SmallInt;\n    sqld    : SmallInt;\n    sqlVar  : array[0..32767] of TZASASQLVAR;\n  end;\n\n  PZASASQLDateTime = ^TZASASQLDateTime;\n  TZASASQLDateTime = packed record\n    Year             : SmallInt;  //* e.g. 1992\t *//\n    Month            : Byte;      //* 0-11\t *//\n    Day_of_Week      : Byte;      //* 0-6  0=Sunday, 1=Monday, ... *//\n    Day_of_Year      : SmallInt;  //* 0-365\t\t           *//\n    Day              : Byte;      //* 1-31\t\t\t   *//\n    Hour             : Byte;      //* 0-23\t\t\t   *//\n    Minute           : Byte;      //* 0-59\t\t\t   *//\n    Second           : Byte;      //* 0-59\t\t\t   *//\n    MicroSecond      : LongInt;   //* 0-999999\t\t\t   *//\n  end;\n\n  PZASABlobStruct = ^TZASABlobStruct;\n  TZASABlobStruct = record\n    array_len        : Longword;\n    stored_len       : Longword;\n    untrunc_len      : Longword;\n    arr: array[0..312756] of AnsiChar;\n  end;\n\n  ZASA_db_callback_index = (             //Markus\n    DB_CALLBACK_START,\n    DB_CALLBACK_WAIT,\n    DB_CALLBACK_FINISH,\n    DB_CALLBACK_ASYNC_RESPONSE,\n    DB_CALLBACK_TRANSLATE_IN,\n    DB_CALLBACK_TRANSLATE_OUT,\n    DB_CALLBACK_UNKNOWN_EVENT,\t    // For Macintosh, initially\n    DB_CALLBACK_MESSAGE,\t    // Messages from the engine during a request\n    DB_CALLBACK_CONN_DROPPED,\n    DB_CALLBACK_DEBUG_MESSAGE,\n    DB_MAX_CALLBACK\n    );\n\n  TZASASQLCallback = procedure() {$IFNDEF LINUX} stdcall {$ELSE} cdecl {$ENDIF};\n\n{ ****************** Plain API Types definition ***************** }\ntype\n  TASABasic = function( sqlca: PZASASQLCA): Integer;\n    {$IFNDEF LINUX} stdcall {$ELSE} cdecl {$ENDIF};\n\n  TASABasicWithParam = function(sqlca: PZASASQLCA; Params: PAnsiChar): LongWord;\n    {$IFNDEF LINUX} stdcall {$ELSE} cdecl {$ENDIF};\n\n  TASAfind_engine = function(sqlca: PZASASQLCA; Params: PAnsiChar): Word;\n    {$IFNDEF LINUX} stdcall {$ELSE} cdecl {$ENDIF};\n\n  TASAAlloc_sqlda = function( NumVar: LongWord): PASASQLDA;\n    {$IFNDEF LINUX} stdcall {$ELSE} cdecl {$ENDIF};\n\n  TASAfill_sqlda = function( Parameter: PASASQLDA): PASASQLDA;\n    {$IFNDEF LINUX} stdcall {$ELSE} cdecl {$ENDIF};\n\n  TASAfill_s_sqlda = function( Parameter: PASASQLDA; MaxLength: Integer): PASASQLDA;\n    {$IFNDEF LINUX} stdcall {$ELSE} cdecl {$ENDIF};\n\n  TASAProc_sqlda = procedure( Parameter: PASASQLDA);\n    {$IFNDEF LINUX} stdcall {$ELSE} cdecl {$ENDIF};\n\n  TASAdbpp_setConnect = procedure(sqlca: PZASASQLCA; ConnName: PAnsiChar);\n    {$IFNDEF LINUX} stdcall {$ELSE} cdecl {$ENDIF};\n\n  TASAdbpp_describe_cursor = procedure(sqlca: PZASASQLCA; CursorName: PAnsiChar;\n    Descriptor: PASASQLDA; SomeNumber: LongWord);\n    {$IFNDEF LINUX} stdcall {$ELSE} cdecl {$ENDIF};\n\n  TASAdbpp_prepare_into = procedure(sqlca: PZASASQLCA; UnKnown: PAnsiChar;\n    ProgName: PAnsiChar; RecordStatementNum: PSmallInt; SqlStatement: PAnsiChar;\n    Descriptor1: PASASQLDA; Descriptor2: PASASQLDA; SomeNumber: LongWord);\n    {$IFNDEF LINUX} stdcall {$ELSE} cdecl {$ENDIF};\n\n  TASAdbpp_prepare_describe = procedure(sqlca: PZASASQLCA; UnKnown: PAnsiChar;\n    ProgName: PAnsiChar; RecordStatementNum: PSmallInt; SqlStatement: PAnsiChar;\n    Descriptor1: PASASQLDA; Descriptor2: PASASQLDA; WhatToDesc: LongWord;\n    LongNames: Word);\n    {$IFNDEF LINUX} stdcall {$ELSE} cdecl {$ENDIF};\n\n  {ASA12 dbpp_prepare_describe_12, (SQLCA *,char *,char *,short int *,char *,struct sqlda *,struct sqlda *,unsigned int, unsigned short int, a_sql_uint32 ))}\n  TASAdbpp_prepare_describe_12 = procedure (SQLCA: PZASASQLCA; UnKnown: PAnsiChar;\n    ProgName: PAnsiChar; RecordStatementNum: PSmallInt; SqlStatement: PAnsiChar;\n    Descriptor1: PASASQLDA; Descriptor2: PASASQLDA; WhatToDesc: LongWord;\n    LongNames: Word; UnknownUint2: Longword)\n    {$IFNDEF LINUX} stdcall {$ELSE} cdecl {$ENDIF};\n\n  TASAdbpp_select = procedure(sqlca: PZASASQLCA; UnKnown: PAnsiChar;\n    ProgName: PAnsiChar; RecordStatementNum: PSmallInt; Descriptor1,\n    Descriptor2: PASASQLDA);\n    {$IFNDEF LINUX} stdcall {$ELSE} cdecl {$ENDIF};\n\n  TASAdbpp_open = procedure(sqlca: PZASASQLCA; CursorName: PAnsiChar;\n    UnKnown: PAnsiChar; ProgName: PAnsiChar; RecordStatementNum: PSmallInt;\n    Descriptor1: PASASQLDA; BlockSize: SmallInt; IsolationLvl: SmallInt;\n    Options : Word);\n    {$IFNDEF LINUX} stdcall {$ELSE} cdecl {$ENDIF};\n\n  TASAdbpp_close = procedure(sqlca: PZASASQLCA; CursorName: PAnsiChar);\n    {$IFNDEF LINUX} stdcall {$ELSE} cdecl {$ENDIF};\n\n  TASAdbpp_fetch = procedure(sqlca: PZASASQLCA; CursorName: PAnsiChar;\n    Offset: Word; RelPositon: LongInt; Descriptor1: PASASQLDA;\n    BlockSize: SmallInt; Options: Word);\n    {$IFNDEF LINUX} stdcall {$ELSE} cdecl {$ENDIF};\n\n  TASAdbpp_declare = procedure(sqlca: PZASASQLCA; CursorName: PAnsiChar;\n    UnKnown: PAnsiChar; ProgName: PAnsiChar; RecordStatementNum: PSmallInt;\n    Options: Word);\n    {$IFNDEF LINUX} stdcall {$ELSE} cdecl {$ENDIF};\n\n  TASAdbpp_dropstmt = procedure(sqlca: PZASASQLCA; UnKnown: PAnsiChar;\n    ProgName: PAnsiChar; RecordStatementNum: PSmallInt);\n    {$IFNDEF LINUX} stdcall {$ELSE} cdecl {$ENDIF};\n\n  TASAdbpp_describe = procedure(sqlca: PZASASQLCA; UnKnown: PAnsiChar;\n    ProgName: PAnsiChar; RecordStatementNum: PSmallInt; Descriptor: PASASQLDA;\n    WhatToDesc: Word);\n    {$IFNDEF LINUX} stdcall {$ELSE} cdecl {$ENDIF};\n\n  TASAdbpp_delete = procedure(sqlca: PZASASQLCA; CursorName: PAnsiChar;\n    UnKnown1: PAnsiChar; UnKnown2: PAnsiChar);\n    {$IFNDEF LINUX} stdcall {$ELSE} cdecl {$ENDIF};\n\n  TASAdbpp_update = procedure(sqlca: PZASASQLCA; CursorName: PAnsiChar;\n    Descriptor: PASASQLDA);\n    {$IFNDEF LINUX} stdcall {$ELSE} cdecl {$ENDIF};\n\n  TASAdbpp_execute_imm = procedure(sqlca: PZASASQLCA; SqlRecordStatement:\n    PAnsiChar;\n    UnKnown1: Word);\n    {$IFNDEF LINUX} stdcall {$ELSE} cdecl {$ENDIF};\n\n  TASAdbpp_put_into = procedure(sqlca: PZASASQLCA; CursorName: PAnsiChar;\n    Descriptor: PASASQLDA; UnKnown1: PASASQLDA);\n    {$IFNDEF LINUX} stdcall {$ELSE} cdecl {$ENDIF};\n\n  TASAdbpp_put_array = procedure(sqlca: PZASASQLCA; CursorName: PAnsiChar;\n    Descriptor: PASASQLDA; Into_sqlda: PASASQLDA; Rows: Word);\n    {$IFNDEF LINUX} stdcall {$ELSE} cdecl {$ENDIF};\n\n  TASAdbpp_commit = procedure( sqlca: PZASASQLCA; SomeNumber: LongWord);\n    {$IFNDEF LINUX} stdcall {$ELSE} cdecl {$ENDIF};\n\n  TASAdbpp_rollback = procedure( sqlca: PZASASQLCA; SomeNumber: LongWord);\n    {$IFNDEF LINUX} stdcall {$ELSE} cdecl {$ENDIF};\n\n  TASAdbpp_execute_into = procedure(sqlca: PZASASQLCA; UnKnown: PAnsiChar;\n    ProgName: PAnsiChar; RecordStatementNum: PSmallInt; Descriptor1: PASASQLDA;\n    Descriptor2: PASASQLDA);\n    {$IFNDEF LINUX} stdcall {$ELSE} cdecl {$ENDIF};\n\n  TASAdbpp_get_data = procedure(sqlca: PZASASQLCA; CursorName: PAnsiChar;\n    ColumnNumber: Word; Offset: LongInt; Descriptor1: PASASQLDA;\n    Unknown: Word);\n    {$IFNDEF LINUX} stdcall {$ELSE} cdecl {$ENDIF};\n\n  TASAdbpp_explain = procedure(sqlca: PZASASQLCA; CursorName: PAnsiChar;\n    SomeNumber1: Word; Descriptor1: PASASQLDA);\n    {$IFNDEF LINUX} stdcall {$ELSE} cdecl {$ENDIF};\n\n  TASASQLCallback = procedure() {$IFNDEF LINUX} stdcall {$ELSE} cdecl {$ENDIF};\n\n  TASAdb_register_a_callback = procedure( sqlca: PZASASQLCA;\n    CBIdx: integer; Proc: TASASQLCallback);\n    {$IFNDEF LINUX} stdcall {$ELSE} cdecl {$ENDIF};\n\n  TASAdbpp_setoption = procedure( sqlca: PZASASQLCA; Temporary: LongInt;\n    User: PAnsiChar; Option: PAnsiChar; Descriptor: PASASQLDA);\n    {$IFNDEF LINUX} stdcall {$ELSE} cdecl {$ENDIF};\n\n  TASAdbpp_fetch_array = procedure(sqlca: PZASASQLCA; CursorName: PAnsiChar;\n    Offset: Word; RelPositon: LongInt; Descriptor1: PASASQLDA;\n    BlockSize: SmallInt; Options: Word; ArrayWidth: Word);\n    {$IFNDEF LINUX} stdcall {$ELSE} cdecl {$ENDIF};\n\n  TASAerror_message = function(sqlca: PZASASQLCA; Buffer: PAnsiChar;\n    MaxSize: Integer): PAnsiChar;\n    {$IFNDEF LINUX} stdcall {$ELSE} cdecl {$ENDIF};\n\n  TASAdbpp_resume = procedure(sqlca: PZASASQLCA; CursorName: PAnsiChar);\n    {$IFNDEF LINUX} stdcall {$ELSE} cdecl {$ENDIF};\n\n  TASAdb_cancel_request = function( sqlca: PZASASQLCA): Integer;\n    {$IFNDEF LINUX} stdcall {$ELSE} cdecl {$ENDIF};\n\n  TASAdb_change_char_charset = function( sqlca: PZASASQLCA; const CharSet: PAnsiChar): Word;\n    {$IFNDEF LINUX} stdcall {$ELSE} cdecl {$ENDIF};\n\n  TASAdb_change_nchar_charset = function( sqlca: PZASASQLCA; const CharSet: PAnsiChar): Word;\n    {$IFNDEF LINUX} stdcall {$ELSE} cdecl {$ENDIF};\n\n{ ************* Plain API Function variables definition ************ }\n\nTASA_API = record\n  sqlerror_message:       TASAerror_message;\n  db_init:                TASABasic;\n  db_fini:                TASABasic;\n  db_find_engine:         TASAfind_engine;\n  db_string_connect:      TASABasicWithParam;\n  db_string_disconnect:   TASABasicWithParam;\n  db_start_engine:        TASABasicWithParam;\n  db_stop_engine:         TASABasicWithParam;\n  db_start_database:      TASABasicWithParam;\n  db_stop_database:       TASABasicWithParam;\n  alloc_sqlda:            TASAAlloc_sqlda;\n  free_sqlda:             TASAProc_sqlda;\n  free_sqlda_noind:       TASAProc_sqlda;\n  fill_sqlda:             TASAfill_sqlda;\n  free_filled_sqlda:      TASAProc_sqlda;\n  fill_s_sqlda:           TASAfill_s_sqlda;\n  dbpp_setConnect:        TASAdbpp_setConnect;\n  dbpp_describe_cursor:   TASAdbpp_describe_cursor;\n  dbpp_disconnect:        TASAdbpp_setConnect;\n  dbpp_prepare_into:      TASAdbpp_prepare_into;\n  dbpp_prepare_describe:  TASAdbpp_prepare_describe;\n  dbpp_prepare_describe_12: TASAdbpp_prepare_describe_12;\n  dbpp_select:            TASAdbpp_select;\n  dbpp_open:              TASAdbpp_open;\n  dbpp_close:             TASAdbpp_close;\n  dbpp_fetch:             TASAdbpp_fetch;\n  dbpp_declare:           TASAdbpp_declare;\n  dbpp_dropstmt:          TASAdbpp_dropstmt;\n  dbpp_describe:          TASAdbpp_describe;\n  dbpp_delete:            TASAdbpp_delete;\n  dbpp_update:            TASAdbpp_update;\n  dbpp_execute_imm:       TASAdbpp_execute_imm;\n  dbpp_put_into:          TASAdbpp_put_into;\n  dbpp_put_array:         TASAdbpp_put_array;\n  dbpp_commit:            TASAdbpp_commit;\n  dbpp_rollback:          TASAdbpp_rollback;\n  dbpp_execute_into:      TASAdbpp_execute_into;\n  dbpp_get_data:          TASAdbpp_get_data;\n  dbpp_explain:           TASAdbpp_explain;\n  db_register_a_callback: TASAdb_register_a_callback;\n  dbpp_setoption:         TASAdbpp_setoption;\n  dbpp_fetch_array:       TASAdbpp_fetch_array;\n  dbpp_resume:            TASAdbpp_resume;\n  db_cancel_request:      TASAdb_cancel_request;\n  db_change_char_charset: TASAdb_change_char_charset;\n  db_change_nchar_charset:  TASAdb_change_nchar_charset;\nend;\n\nimplementation\n\nend.\n\n\n"
  },
  {
    "path": "lib/zeosdbo/src/plain/ZPlainASADriver.pas",
    "content": "{@********************************************************}\n{    Copyright (c) 1999-2012 Zeos Development Group       }\n{                                                         }\n{ License Agreement:                                      }\n{                                                         }\n{ This library is distributed in the hope that it will be }\n{ useful, but WITHOUT ANY WARRANTY; without even the      }\n{ implied warranty of MERCHANTABILITY or FITNESS FOR      }\n{ A PARTICULAR PURPOSE.  See the GNU Lesser General       }\n{ Public License for more details.                        }\n{                                                         }\n{ The source code of the ZEOS Libraries and packages are  }\n{ distributed under the Library GNU General Public        }\n{ License (see the file COPYING / COPYING.ZEOS)           }\n{ with the following  modification:                       }\n{ As a special exception, the copyright holders of this   }\n{ library give you permission to link this library with   }\n{ independent modules to produce an executable,           }\n{ regardless of the license terms of these independent    }\n{ modules, and to copy and distribute the resulting       }\n{ executable under terms of your choice, provided that    }\n{ you also meet, for each linked independent module,      }\n{ the terms and conditions of the license of that module. }\n{ An independent module is a module which is not derived  }\n{ from or based on this library. If you modify this       }\n{ library, you may extend this exception to your version  }\n{ of the library, but you are not obligated to do so.     }\n{ If you do not wish to do so, delete this exception      }\n{ statement from your version.                            }\n{                                                         }\n{                                                         }\n{ The project web site is located on:                     }\n{   http://zeos.firmos.at  (FORUM)                        }\n{   http://sourceforge.net/p/zeoslib/tickets/ (BUGTRACKER)}\n{   svn://svn.code.sf.net/p/zeoslib/code-0/trunk (SVN)    }\n{                                                         }\n{   http://www.sourceforge.net/projects/zeoslib.          }\n{                                                         }\n{                                                         }\n{                                 Zeos Development Group. }\n{********************************************************@}\n\nunit ZPlainASADriver;\n\ninterface\n\n{$I ZPlain.inc}\n\nuses Classes, ZCompatibility, ZPlainDriver, ZPlainASAConstants;\n\n{***************** Plain API Constants definition ****************}\n\ntype\n\n  {** Represents a generic interface to ASA native API. }\n  IZASAPlainDriver = interface (IZPlainDriver)\n    ['{86AFDDD6-D401-4A30-B3BE-4AC5095E13F0}']\n\n    function sqlerror_message(sqlca: PZASASQLCA; Buffer: PAnsiChar;\n       MaxSize: Integer): PAnsiChar;\n    function db_init( sqlca: PZASASQLCA): Integer;\n    function db_fini( sqlca: PZASASQLCA): Integer;\n    function db_string_connect(sqlca: PZASASQLCA; Params: PAnsiChar): Integer;\n    function db_string_disconnect(sqlca: PZASASQLCA; Params: PAnsiChar): LongWord;\n    function db_find_engine(sqlca: PZASASQLCA; Params: PAnsiChar): Word;\n    function db_start_engine(sqlca: PZASASQLCA; Params: PAnsiChar): LongWord;\n    function db_stop_engine(sqlca: PZASASQLCA; Params: PAnsiChar): LongWord;\n    function db_start_database(sqlca: PZASASQLCA; Params: PAnsiChar): LongWord;\n    function db_stop_database(sqlca: PZASASQLCA; Params: PAnsiChar): LongWord;\n\n    function db_alloc_sqlda( NumVar: LongWord): PASASQLDA;\n    function db_fill_sqlda( Parameter: PASASQLDA): PASASQLDA;\n    function db_fill_s_sqlda( Parameter: PASASQLDA; MaxLength: Integer):\n      PASASQLDA;\n    procedure db_free_sqlda( Parameter: PASASQLDA);\n    procedure db_free_sqlda_noind( Parameter: PASASQLDA);\n    procedure db_free_filled_sqlda( Parameter: PASASQLDA);\n\n    procedure db_setconnect(sqlca: PZASASQLCA; ConnStr: PAnsiChar);\n    procedure db_disconnect(sqlca: PZASASQLCA; ConnStr: PAnsiChar);\n    procedure db_setoption( sqlca: PZASASQLCA; Temporary: LongInt;\n      User: PAnsiChar; Option: PAnsiChar; Descriptor: PASASQLDA);\n\n    procedure db_describe_cursor(sqlca: PZASASQLCA; CursorName: PAnsiChar;\n      Descriptor: PASASQLDA; WhatToDesc: LongWord);\n    procedure db_prepare_into(sqlca: PZASASQLCA; ProgName: PAnsiChar;\n      StatementNum: PSmallInt; SqlStatement: PAnsiChar;\n      Descriptor1: PASASQLDA; Descriptor2: PASASQLDA; WhatToDesc: LongWord);\n    procedure db_prepare_describe(sqlca: PZASASQLCA; ProgName: PAnsiChar;\n      StatementNum: PSmallInt; SqlStatement: PAnsiChar; Descriptor: PASASQLDA;\n      WhatToDesc: LongWord; LongNames: Word);\n    procedure db_declare(sqlca: PZASASQLCA; CursorName: PAnsiChar;\n      StatementName: PAnsiChar; ProgName: PAnsiChar; StatementNum: PSmallInt;\n      Options: Word);\n    procedure db_describe(sqlca: PZASASQLCA; ProgName: PAnsiChar;\n      StatementNum: PSmallInt; Descriptor: PASASQLDA; WhatToDesc: Word);\n    procedure db_dropstmt(sqlca: PZASASQLCA; StatementName: PAnsiChar;\n      ProgName: PAnsiChar; StatementNum: PSmallInt);\n    procedure db_open(sqlca: PZASASQLCA; CursorName: PAnsiChar;\n     ProgName: PAnsiChar; StatementNum: PSmallInt; Descriptor: PASASQLDA;\n     BlockSize, IsolationLvl: SmallInt; CursorOptions: Word);\n    procedure db_close( sqlca: PZASASQLCA; CursorName: PAnsiChar);\n\n    procedure db_fetch(sqlca: PZASASQLCA; CursorName: PAnsiChar; Offset: Word;\n      RelPositon: Integer; Descriptor: PASASQLDA; BlockSize: SmallInt;\n      Options: Word);\n    procedure db_fetch_array(sqlca: PZASASQLCA; CursorName: PAnsiChar;\n      Offset: Word; RelPositon: Integer; Descriptor: PASASQLDA;\n      BlockSize: SmallInt; Options, ArrayWidth: Word);\n    procedure db_get_data(sqlca: PZASASQLCA; CursorName: PAnsiChar;\n      ColumnNumber: Word; Offset: Integer; Descriptor: PASASQLDA);\n    procedure db_delete(sqlca: PZASASQLCA; CursorName: PAnsiChar);\n    procedure db_update(sqlca: PZASASQLCA; CursorName: PAnsiChar;\n      Descriptor: PASASQLDA);\n    procedure db_put_into(sqlca: PZASASQLCA; CursorName: PAnsiChar;\n      Descriptor: PASASQLDA; ResultDescriptor: PASASQLDA);\n    procedure db_put_array(sqlca: PZASASQLCA; CursorName: PAnsiChar;\n      Descriptor: PASASQLDA; ResultDescriptor: PASASQLDA; Rows: Word);\n\n    procedure db_select(sqlca: PZASASQLCA; ProgName: PAnsiChar;\n      StatementNum: PSmallInt; SQLDescriptor, ResultDescriptor: PASASQLDA);\n    procedure db_execute_into(sqlca: PZASASQLCA; Statement: PAnsiChar;\n      ProgName: PAnsiChar; StatementNum: PSmallInt; Descriptor: PASASQLDA;\n      ResultDescriptor: PASASQLDA);\n    procedure db_execute_imm(sqlca: PZASASQLCA; Statement: PAnsiChar);\n\n    procedure db_commit( sqlca: PZASASQLCA; TransLevel: LongWord);\n    procedure db_rollback( sqlca: PZASASQLCA; TransLevel: LongWord);\n    procedure db_explain(sqlca: PZASASQLCA; CursorName: PAnsiChar;\n      Descriptor: PASASQLDA);\n    procedure db_register_callback( sqlca: PZASASQLCA;\n      CBIdx: ZASA_db_callback_index; Proc: TZASASQLCallback);\n    procedure db_resume(sqlca: PZASASQLCA; CursorName: PAnsiChar);\n    function db_cancel_request( sqlca: PZASASQLCA): Integer;\n    function db_change_char_charset( sqlca: PZASASQLCA; const CharSet: PAnsiChar): Word;\n    function db_change_nchar_charset( sqlca: PZASASQLCA; const CharSet: PAnsiChar): Word;\n  end;\n\n  {** Implements a driver for ASA 7.0-9.0}\n  TZASABasePlainDriver = class (TZAbstractPlainDriver, IZPlainDriver,\n    IZASAPlainDriver)\n  private\n    ASA_API: TASA_API;\n  protected\n    procedure LoadApi; override;\n    function GetUnicodeCodePageName: String; override;\n  public\n    procedure LoadCodePages; override;\n    constructor Create;\n\n    function sqlerror_message(sqlca: PZASASQLCA; Buffer: PAnsiChar;\n       MaxSize: Integer): PAnsiChar;\n    function db_init( sqlca: PZASASQLCA): Integer;\n    function db_fini( sqlca: PZASASQLCA): Integer;\n    function db_string_connect(sqlca: PZASASQLCA; Params: PAnsiChar): Integer;\n    function db_string_disconnect(sqlca: PZASASQLCA; Params: PAnsiChar): LongWord;\n    function db_find_engine(sqlca: PZASASQLCA; Params: PAnsiChar): Word;\n    function db_start_engine(sqlca: PZASASQLCA; Params: PAnsiChar): LongWord;\n    function db_stop_engine(sqlca: PZASASQLCA; Params: PAnsiChar): LongWord;\n    function db_start_database(sqlca: PZASASQLCA; Params: PAnsiChar): LongWord;\n    function db_stop_database(sqlca: PZASASQLCA; Params: PAnsiChar): LongWord;\n\n    function db_alloc_sqlda( NumVar: LongWord): PASASQLDA;\n    function db_fill_sqlda( Parameter: PASASQLDA): PASASQLDA;\n    function db_fill_s_sqlda( Parameter: PASASQLDA; MaxLength: Integer):\n      PASASQLDA;\n    procedure db_free_sqlda( Parameter: PASASQLDA);\n    procedure db_free_sqlda_noind( Parameter: PASASQLDA);\n    procedure db_free_filled_sqlda( Parameter: PASASQLDA);\n\n    procedure db_setconnect(sqlca: PZASASQLCA; ConnStr: PAnsiChar);\n    procedure db_disconnect(sqlca: PZASASQLCA; ConnStr: PAnsiChar);\n    procedure db_setoption( sqlca: PZASASQLCA; Temporary: LongInt;\n      User: PAnsiChar; Option: PAnsiChar; Descriptor: PASASQLDA);\n\n    procedure db_describe_cursor(sqlca: PZASASQLCA; CursorName: PAnsiChar;\n      Descriptor: PASASQLDA; WhatToDesc: LongWord);\n    procedure db_prepare_into(sqlca: PZASASQLCA; ProgName: PAnsiChar;\n      StatementNum: PSmallInt; SqlStatement: PAnsiChar;\n      Descriptor1: PASASQLDA; Descriptor2: PASASQLDA; WhatToDesc: LongWord);\n    procedure db_prepare_describe(sqlca: PZASASQLCA; ProgName: PAnsiChar;\n      StatementNum: PSmallInt; SqlStatement: PAnsiChar; Descriptor: PASASQLDA;\n      WhatToDesc: LongWord; LongNames: Word);\n    procedure db_declare(sqlca: PZASASQLCA; CursorName: PAnsiChar;\n      StatementName: PAnsiChar; ProgName: PAnsiChar; StatementNum: PSmallInt;\n      Options: Word);\n    procedure db_describe(sqlca: PZASASQLCA; ProgName: PAnsiChar;\n      StatementNum: PSmallInt; Descriptor: PASASQLDA; WhatToDesc: Word);\n    procedure db_dropstmt(sqlca: PZASASQLCA; StatementName: PAnsiChar;\n      ProgName: PAnsiChar; StatementNum: PSmallInt);\n    procedure db_open(sqlca: PZASASQLCA; CursorName: PAnsiChar;\n      ProgName: PAnsiChar; StatementNum: PSmallInt; Descriptor: PASASQLDA;\n      BlockSize, IsolationLvl: SmallInt; CursorOptions: Word);\n    procedure db_close(sqlca: PZASASQLCA; CursorName: PAnsiChar);\n\n    procedure db_fetch(sqlca: PZASASQLCA; CursorName: PAnsiChar; Offset: Word;\n      RelPositon: Integer; Descriptor: PASASQLDA; BlockSize: SmallInt;\n      Options: Word);\n    procedure db_fetch_array(sqlca: PZASASQLCA; CursorName: PAnsiChar;\n      Offset: Word; RelPositon: Integer; Descriptor: PASASQLDA;\n      BlockSize: SmallInt; Options, ArrayWidth: Word);\n    procedure db_get_data(sqlca: PZASASQLCA; CursorName: PAnsiChar;\n      ColumnNumber: Word; Offset: Integer; Descriptor: PASASQLDA);\n    procedure db_delete(sqlca: PZASASQLCA; CursorName: PAnsiChar);\n    procedure db_update(sqlca: PZASASQLCA; CursorName: PAnsiChar;\n      Descriptor: PASASQLDA);\n    procedure db_put_into(sqlca: PZASASQLCA; CursorName: PAnsiChar;\n      Descriptor: PASASQLDA; ResultDescriptor: PASASQLDA);\n    procedure db_put_array(sqlca: PZASASQLCA; CursorName: PAnsiChar;\n      Descriptor: PASASQLDA; ResultDescriptor: PASASQLDA; Rows: Word);\n\n    procedure db_select(sqlca: PZASASQLCA; ProgName: PAnsiChar;\n      StatementNum: PSmallInt; Descriptor, ResultDescriptor: PASASQLDA);\n    procedure db_execute_into(sqlca: PZASASQLCA; Statement: PAnsiChar;\n      ProgName: PAnsiChar; StatementNum: PSmallInt; Descriptor: PASASQLDA;\n      ResultDescriptor: PASASQLDA);\n    procedure db_execute_imm(sqlca: PZASASQLCA; Statement: PAnsiChar);\n\n    procedure db_commit( sqlca: PZASASQLCA; TransLevel: LongWord);\n    procedure db_rollback( sqlca: PZASASQLCA; TransLevel: LongWord);\n    procedure db_explain(sqlca: PZASASQLCA; CursorName: PAnsiChar;\n      Descriptor: PASASQLDA);\n    procedure db_register_callback( sqlca: PZASASQLCA;\n      CBIdx: ZASA_db_callback_index; Proc: TZASASQLCallback);\n    procedure db_resume(sqlca: PZASASQLCA; CursorName: PAnsiChar);\n    function db_cancel_request( sqlca: PZASASQLCA): Integer;\n    function db_change_char_charset( sqlca: PZASASQLCA; const CharSet: PAnsiChar): Word;\n    function db_change_nchar_charset( sqlca: PZASASQLCA; const CharSet: PAnsiChar): Word;\n  end;\n\n  TZASA7PlainDriver = class(TZASABasePlainDriver)\n  protected\n    function Clone: IZPlainDriver; override;\n  public\n    constructor Create;\n    function GetProtocol: string; override;\n    function GetDescription: string; override;\n  end;\n\n  TZASA8PlainDriver = class(TZASABasePlainDriver)\n  protected\n    function Clone: IZPlainDriver; override;\n  public\n    constructor Create;\n    function GetProtocol: string; override;\n    function GetDescription: string; override;\n  end;\n\n  {** Implements a driver for ASA 9.0 }\n  TZASA9PlainDriver = class (TZASABasePlainDriver)\n  protected\n    function Clone: IZPlainDriver; override;\n  public\n    constructor Create;\n    function GetProtocol: string; override;\n    function GetDescription: string; override;\n  end;\n\n  {** Implements a driver for ASA 12.0 }\n  TZASA12PlainDriver = class (TZASABasePlainDriver)\n  protected\n    function Clone: IZPlainDriver; override;\n  public\n    constructor Create;\n    function GetProtocol: string; override;\n    function GetDescription: string; override;\n  end;\n\nimplementation\n\nuses SysUtils, ZPlainLoader, ZEncoding;\n\nprocedure TZASABasePlainDriver.LoadApi;\nbegin\n  with FLoader do\n  begin\n    @ASA_API.sqlerror_message       := GetAddress('sqlerror_message');\n    @ASA_API.db_init                := GetAddress('db_init');\n    @ASA_API.db_fini                := GetAddress('db_fini');\n    @ASA_API.db_string_connect      := GetAddress('db_string_connect');\n    @ASA_API.db_string_disconnect   := GetAddress('db_string_disconnect');\n    @ASA_API.db_find_engine         := GetAddress('db_find_engine');\n    @ASA_API.db_start_engine        := GetAddress('db_start_engine');\n    @ASA_API.db_stop_engine         := GetAddress('db_stop_engine');\n    @ASA_API.db_start_database      := GetAddress('db_start_database');\n    @ASA_API.db_stop_database       := GetAddress('db_stop_database');\n    @ASA_API.alloc_sqlda            := GetAddress('alloc_sqlda');\n    @ASA_API.fill_sqlda             := GetAddress('fill_sqlda');\n    @ASA_API.fill_s_sqlda           := GetAddress('fill_s_sqlda');\n    @ASA_API.free_filled_sqlda      := GetAddress('free_filled_sqlda');\n    @ASA_API.free_sqlda             := GetAddress('free_sqlda');\n    @ASA_API.free_sqlda_noind       := GetAddress('free_sqlda_noind');\n    @ASA_API.dbpp_setConnect        := GetAddress('dbpp_setconnect');\n    @ASA_API.dbpp_disconnect        := GetAddress('dbpp_disconnect');\n    @ASA_API.dbpp_prepare_into      := GetAddress('dbpp_prepare_into');\n    @ASA_API.dbpp_describe_cursor   := GetAddress('dbpp_describe_cursor');\n    @ASA_API.dbpp_prepare_describe  := GetAddress('dbpp_prepare_describe');\n    @ASA_API.dbpp_prepare_describe_12  := GetAddress('dbpp_prepare_describe_12');\n    @ASA_API.dbpp_select            := GetAddress('dbpp_select');\n    @ASA_API.dbpp_open              := GetAddress('dbpp_open');\n    @ASA_API.dbpp_close             := GetAddress('dbpp_close');\n    @ASA_API.dbpp_fetch             := GetAddress('dbpp_fetch');\n    @ASA_API.dbpp_declare           := GetAddress('dbpp_declare');\n    @ASA_API.dbpp_dropstmt          := GetAddress('dbpp_dropstmt');\n    @ASA_API.dbpp_describe          := GetAddress('dbpp_describe');\n    @ASA_API.dbpp_delete            := GetAddress('dbpp_delete');\n    @ASA_API.dbpp_update            := GetAddress('dbpp_update');\n    @ASA_API.dbpp_put_into          := GetAddress('dbpp_put_into');\n    @ASA_API.dbpp_put_array         := GetAddress('dbpp_put_array');\n    @ASA_API.dbpp_execute_imm       := GetAddress('dbpp_execute_imm');\n    @ASA_API.dbpp_commit            := GetAddress('dbpp_commit');\n    @ASA_API.dbpp_rollback          := GetAddress('dbpp_rollback');\n    @ASA_API.dbpp_execute_into      := GetAddress('dbpp_execute_into');\n    @ASA_API.dbpp_get_data          := GetAddress('dbpp_get_data');\n    @ASA_API.dbpp_explain           := GetAddress('dbpp_explain');\n    @ASA_API.dbpp_setoption         := GetAddress('dbpp_setoption');\n    @ASA_API.dbpp_fetch_array       := GetAddress('dbpp_fetch_array');\n    @ASA_API.db_register_a_callback := GetAddress('db_register_a_callback');\n    @ASA_API.dbpp_resume            := GetAddress('dbpp_resume');\n    @ASA_API.db_cancel_request      := GetAddress('db_cancel_request');\n    @ASA_API.db_change_char_charset := GetAddress('db_change_char_charset');\n    @ASA_API.db_change_nchar_charset:= GetAddress('db_change_nchar_charset');\n  end;\nend;\n\nfunction TZASABasePlainDriver.GetUnicodeCodePageName: String;\nbegin\n  Result := 'UTF-8';\nend;\n\nprocedure TZASABasePlainDriver.LoadCodePages;\nbegin\n  { MultiByte }\n  AddCodePage('TIS-620', 1, ceAnsi, 874); {Windows Thailndisch, ISO8859-11, binre Sortierung}\n  AddCodePage('Windows-31J', 2, ceAnsi, 932); {Japanese Shift-JIS mit Microsoft-Erweiterungen}\n  AddCodePage('GBK', 3, ceAnsi, 936); {GB2312-80 Simplified Chinese}\n  AddCodePage('IBM949', 4, ceAnsi, 949); {Korean KS C 5601-1987-Codierung, Wansung}\n  AddCodePage('BIG5', 5, ceAnsi, 950); {Traditionelles Chinesisch, Big 5-Kodierung mit HKSCS}\n  AddCodePage('EUC_CHINA', 6, ceAnsi, zCP_GB2312); {GB2312-80 Simplified Chinese}\n  AddCodePage('UTF-8', 7, ceUTF8, zCP_UTF8, '', 3); {UTF-8, 8-Bit-Mehrbyte-Zeichensatz fr Unicode, binre Reihenfolge}\n\n  { SingleByte }\n  AddCodePage('Windows-1250', 8, ceAnsi, 1250); {Windows Latin 2, Polnisch}\n  AddCodePage('Windows-1251', 9, ceAnsi, 1251); {Windows Kyrillisch}\n  AddCodePage('Windows-1252', 10, ceAnsi, 1252); { Windows Latin 1, Western}\n  AddCodePage('Windows-1253', 11, ceAnsi, 1253); {Windows Griechisch, ISO8859-7 mit Erweiterungen}\n  AddCodePage('Windows-1254', 12, ceAnsi, 1254); {Windows Trkisch, ISO8859-9 mit Erweiterungen}\n  AddCodePage('Windows-1255', 13, ceAnsi, 1255); {Windows Hebrisch, ISO8859-8 mit Erweiterungen}\n  AddCodePage('Windows-1256', 14, ceAnsi, 1256); {Windows Arabisch, ISO8859-6 mit Erweiterungen}\n  AddCodePage('Windows-1257', 15, ceAnsi, 1257); {Windows Baltische Staaten, Litauisch}\n  AddCodePage('Windows-1258', 16, ceAnsi, 1258); {Windows }\n\n  {*nix}\n  AddCodePage('ISO_8859-6:1987', 17, ceAnsi, 1256); {Arabisch, ISO8859-6 mit Erweiterungen}\n  AddCodePage('ISO_8859-2:1987', 18, ceAnsi, 1251); {Zentral- und Osteuropisch}\n  //ISO-8859-15 //ISO9LATIN1\n  //ISO_8859-7:1987 //Griechisch\n  //ISO_8859-8:1988 //Hebrisch\n  //ISO-8859-15 //Italienisch\n  //EUC-JP //Japanisch\n  //EUC-KR //Koreanisch\n  //ISO_8859-5:1988 //Russisch\n  AddCodePage('GB2312', 19, ceAnsi, zCP_GB2312); {GB2312-80 Simplified Chinese}\n  //EUC-TW //Traditionelles Chinesisch - Taiwan\n  AddCodePage('Big5-HKSCS', 20, ceAnsi, 950); {Traditionelles Chinesisch, Big 5-Kodierung mit HKSCS}\n  AddCodePage('ISO_8859-9:1989', 21, ceAnsi, 920); //Trkisch\nend;\n\nconstructor TZASABasePlainDriver.Create;\nbegin\n  inherited create;\n  FLoader := TZNativeLibraryLoader.Create([]);\n  LoadCodePages;\nend;\n\nfunction TZASABasePlainDriver.sqlerror_message(sqlca: PZASASQLCA; Buffer: PAnsiChar;\n  MaxSize: Integer): PAnsiChar;\nbegin\n  Result := ASA_API.sqlerror_message( sqlca, Buffer, MaxSize);\nend;\n\nfunction TZASABasePlainDriver.db_init( sqlca: PZASASQLCA): Integer;\nbegin\n  Result := ASA_API.db_init( sqlca);\nend;\n\nfunction TZASABasePlainDriver.db_fini( sqlca: PZASASQLCA): Integer;\nbegin\n  Result := ASA_API.db_fini( sqlca);\nend;\n\nfunction TZASABasePlainDriver.db_string_connect(sqlca: PZASASQLCA; Params: PAnsiChar):\n  Integer;\nbegin\n  Result := ASA_API.db_string_connect( sqlca, Params);\nend;\n\nfunction TZASABasePlainDriver.db_string_disconnect( sqlca: PZASASQLCA;\n  Params: PAnsiChar): LongWord;\nbegin\n  Result := ASA_API.db_string_disconnect( sqlca, Params)\nend;\n\nfunction TZASABasePlainDriver.db_find_engine(sqlca: PZASASQLCA; Params: PAnsiChar):\n  Word;\nbegin\n  Result := ASA_API.db_find_engine( sqlca, Params);\nend;\n\nfunction TZASABasePlainDriver.db_start_engine(sqlca: PZASASQLCA; Params: PAnsiChar):\n  LongWord;\nbegin\n  Result := ASA_API.db_start_engine( sqlca, Params);\nend;\n\nfunction TZASABasePlainDriver.db_stop_engine(sqlca: PZASASQLCA; Params: PAnsiChar):\n  LongWord;\nbegin\n  Result := ASA_API.db_stop_engine( sqlca, Params);\nend;\n\nfunction TZASABasePlainDriver.db_start_database(sqlca: PZASASQLCA; Params: PAnsiChar):\n  LongWord;\nbegin\n  Result := ASA_API.db_start_database( sqlca, Params);\nend;\n\nfunction TZASABasePlainDriver.db_stop_database(sqlca: PZASASQLCA; Params: PAnsiChar):\n  LongWord;\nbegin\n  Result := ASA_API.db_stop_database( sqlca, Params);\nend;\n\nfunction TZASABasePlainDriver.db_alloc_sqlda( NumVar: LongWord): PASASQLDA;\nbegin\n  Result := ASA_API.alloc_sqlda( NumVar);\nend;\n\nfunction TZASABasePlainDriver.db_fill_sqlda( Parameter: PASASQLDA): PASASQLDA;\nbegin\n  Result := ASA_API.fill_sqlda( Parameter);\nend;\n\nfunction TZASABasePlainDriver.db_fill_s_sqlda( Parameter: PASASQLDA;\n  MaxLength: Integer): PASASQLDA;\nbegin\n  Result := ASA_API.fill_s_sqlda( Parameter, MaxLength);\nend;\n\nprocedure TZASABasePlainDriver.db_free_sqlda( Parameter: PASASQLDA);\nbegin\n  ASA_API.free_sqlda( Parameter);\nend;\n\nprocedure TZASABasePlainDriver.db_free_sqlda_noind( Parameter: PASASQLDA);\nbegin\n  ASA_API.free_sqlda_noind( Parameter);\nend;\n\nprocedure TZASABasePlainDriver.db_free_filled_sqlda( Parameter: PASASQLDA);\nbegin\n  ASA_API.free_filled_sqlda( Parameter);\nend;\n\nprocedure TZASABasePlainDriver.db_setconnect(sqlca: PZASASQLCA; ConnStr: PAnsiChar);\nbegin\n  ASA_API.dbpp_setconnect( sqlca, ConnStr);\nend;\n\nprocedure TZASABasePlainDriver.db_disconnect(sqlca: PZASASQLCA; ConnStr: PAnsiChar);\nbegin\n  ASA_API.dbpp_disconnect( sqlca, ConnStr);\nend;\n\nprocedure TZASABasePlainDriver.db_setoption( sqlca: PZASASQLCA; Temporary: Integer;\n   User: PAnsiChar; Option: PAnsiChar; Descriptor: PASASQLDA);\nbegin\n  ASA_API.dbpp_setoption( sqlca, Temporary, User, Option, Descriptor);\nend;\n\nprocedure TZASABasePlainDriver.db_describe_cursor( sqlca: PZASASQLCA;\n  CursorName: PAnsiChar; Descriptor: PASASQLDA; WhatToDesc: LongWord);\nbegin\n  ASA_API.dbpp_describe_cursor( sqlca, CursorName, Descriptor, WhatToDesc);\nend;\n\nprocedure TZASABasePlainDriver.db_prepare_into( sqlca: PZASASQLCA;\n  ProgName: PAnsiChar; StatementNum: PSmallInt; SqlStatement: PAnsiChar;\n  Descriptor1: PASASQLDA; Descriptor2: PASASQLDA; WhatToDesc: LongWord);\nbegin\n  ASA_API.dbpp_prepare_into( sqlca, nil, ProgName, StatementNum, SqlStatement,\n    Descriptor1, Descriptor2, WhatToDesc);\nend;\n\nprocedure TZASABasePlainDriver.db_prepare_describe( sqlca: PZASASQLCA;\n   ProgName: PAnsiChar; StatementNum: PSmallInt; SqlStatement: PAnsiChar;\n  Descriptor: PASASQLDA; WhatToDesc: LongWord; LongNames: Word);\nvar\n  U1: LongWord;\nbegin\n  U1 := 0;\n  if Assigned(ASA_API.dbpp_prepare_describe) then\n    ASA_API.dbpp_prepare_describe( sqlca, nil, ProgName, StatementNum,\n      SqlStatement, nil, Descriptor, WhatToDesc, LongNames)\n  else\n    if Assigned(ASA_API.dbpp_prepare_describe_12) then\n    ASA_API.dbpp_prepare_describe_12(sqlca, nil, ProgName, StatementNum,\n        SqlStatement, nil, Descriptor, WhatToDesc, LongNames, U1);\nend;\n\nprocedure TZASABasePlainDriver.db_declare(sqlca: PZASASQLCA; CursorName: PAnsiChar;\n  StatementName: PAnsiChar; ProgName: PAnsiChar; StatementNum: PSmallInt;\n  Options: Word);\nbegin\n  ASA_API.dbpp_declare( sqlca, CursorName, StatementName, ProgName,\n    StatementNum, Options);\nend;\n\nprocedure TZASABasePlainDriver.db_describe(sqlca: PZASASQLCA; ProgName: PAnsiChar;\n      StatementNum: PSmallInt; Descriptor: PASASQLDA; WhatToDesc: Word);\nbegin\n  ASA_API.dbpp_describe( sqlca, nil, ProgName, StatementNum, Descriptor,\n    WhatToDesc);\nend;\n\nprocedure TZASABasePlainDriver.db_dropstmt( sqlca: PZASASQLCA;\n  StatementName: PAnsiChar; ProgName: PAnsiChar; StatementNum: PSmallInt);\nbegin\n  ASA_API.dbpp_dropstmt( sqlca, StatementName, ProgName, StatementNum);\nend;\n\nprocedure TZASABasePlainDriver.db_open(sqlca: PZASASQLCA; CursorName: PAnsiChar;\n  ProgName: PAnsiChar; StatementNum: PSmallInt; Descriptor: PASASQLDA;\n  BlockSize, IsolationLvl: SmallInt; CursorOptions: Word);\nbegin\n  ASA_API.dbpp_open( sqlca, CursorName, nil, ProgName, StatementNum,\n    Descriptor, BlockSize, IsolationLvl, CursorOptions);\nend;\n\nprocedure TZASABasePlainDriver.db_close(sqlca: PZASASQLCA; CursorName: PAnsiChar);\nbegin\n  ASA_API.dbpp_close( sqlca, CursorName);\nend;\n\nprocedure TZASABasePlainDriver.db_fetch(sqlca: PZASASQLCA; CursorName: PAnsiChar;\n  Offset: Word; RelPositon: Integer; Descriptor: PASASQLDA;\n  BlockSize: SmallInt; Options: Word);\nbegin\n  ASA_API.dbpp_fetch( sqlca, CursorName, Offset, RelPositon, Descriptor,\n    BlockSize, Options);\nend;\n\nprocedure TZASABasePlainDriver.db_fetch_array( sqlca: PZASASQLCA;\n  CursorName: PAnsiChar; Offset: Word; RelPositon: Integer;\n  Descriptor: PASASQLDA; BlockSize: SmallInt; Options, ArrayWidth: Word);\nbegin\n  ASA_API.dbpp_fetch_array( sqlca, CursorName, Offset, RelPositon, Descriptor,\n    BlockSize, Options, ArrayWidth);\nend;\n\nprocedure TZASABasePlainDriver.db_get_data(sqlca: PZASASQLCA; CursorName: PAnsiChar;\n  ColumnNumber: Word; Offset: Integer; Descriptor: PASASQLDA);\nbegin\n  ASA_API.dbpp_get_data( sqlca, CursorName, ColumnNumber, Offset, Descriptor,\n    0);\nend;\n\nprocedure TZASABasePlainDriver.db_delete(sqlca: PZASASQLCA; CursorName: PAnsiChar);\nbegin\n  ASA_API.dbpp_delete( sqlca, CursorName, nil, nil);\nend;\n\nprocedure TZASABasePlainDriver.db_update(sqlca: PZASASQLCA; CursorName: PAnsiChar;\n  Descriptor: PASASQLDA);\nbegin\n  ASA_API.dbpp_update( sqlca, CursorName, Descriptor);\nend;\n\nprocedure TZASABasePlainDriver.db_put_into(sqlca: PZASASQLCA; CursorName: PAnsiChar;\n  Descriptor: PASASQLDA; ResultDescriptor: PASASQLDA);\nbegin\n  ASA_API.dbpp_put_into( sqlca, CursorName, Descriptor, ResultDescriptor);\nend;\n\nprocedure TZASABasePlainDriver.db_put_array(sqlca: PZASASQLCA; CursorName: PAnsiChar;\n  Descriptor: PASASQLDA; ResultDescriptor: PASASQLDA; Rows: Word);\nbegin\n  ASA_API.dbpp_put_array( sqlca, CursorName, Descriptor, ResultDescriptor,\n    Rows);\nend;\n\nprocedure TZASABasePlainDriver.db_select(sqlca: PZASASQLCA; ProgName: PAnsiChar;\n  StatementNum: PSmallInt; Descriptor, ResultDescriptor: PASASQLDA);\nbegin\n  ASA_API.dbpp_select( sqlca, nil, ProgName, StatementNum, Descriptor,\n    ResultDescriptor);\nend;\n\nprocedure TZASABasePlainDriver.db_execute_into( sqlca: PZASASQLCA;\n  Statement: PAnsiChar; ProgName: PAnsiChar; StatementNum: PSmallInt;\n  Descriptor: PASASQLDA; ResultDescriptor: PASASQLDA);\nbegin\n  ASA_API.dbpp_execute_into( sqlca, Statement, ProgName, StatementNum,\n    Descriptor, ResultDescriptor);\nend;\n\nprocedure TZASABasePlainDriver.db_execute_imm( sqlca: PZASASQLCA;\n  Statement: PAnsiChar);\nbegin\n  ASA_API.dbpp_execute_imm( sqlca, Statement, 2);\nend;\n\nprocedure TZASABasePlainDriver.db_commit( sqlca: PZASASQLCA; TransLevel: LongWord);\nbegin\n  ASA_API.dbpp_commit( sqlca, TransLevel);\nend;\n\nprocedure TZASABasePlainDriver.db_rollback( sqlca: PZASASQLCA;\n  TransLevel: LongWord);\nbegin\n  ASA_API.dbpp_rollback( sqlca, TransLevel);\nend;\n\nprocedure TZASABasePlainDriver.db_explain(sqlca: PZASASQLCA; CursorName: PAnsiChar;\n  Descriptor: PASASQLDA);\nbegin\n  ASA_API.dbpp_explain( sqlca, CursorName, 0, Descriptor);\nend;\n\nprocedure TZASABasePlainDriver.db_register_callback( sqlca: PZASASQLCA;\n  CBIdx: ZASA_db_callback_index; Proc: TZASASQLCallback);\nbegin\n  ASA_API.db_register_a_callback( sqlca, Integer( CBIdx), Proc);\nend;\n\nprocedure TZASABasePlainDriver.db_resume(sqlca: PZASASQLCA; CursorName: PAnsiChar);\nbegin\n  ASA_API.dbpp_resume( sqlca, CursorName);\nend;\n\nfunction TZASABasePlainDriver.db_cancel_request( sqlca: PZASASQLCA): Integer;\nbegin\n  Result := ASA_API.db_cancel_request( sqlca);\nend;\n\nfunction TZASABasePlainDriver.db_change_char_charset( sqlca: PZASASQLCA; const CharSet: PAnsiChar): Word;\nbegin\n  Result := ASA_API.db_change_char_charset(sqlca, CharSet);\nend;\n\nfunction TZASABasePlainDriver.db_change_nchar_charset( sqlca: PZASASQLCA; const CharSet: PAnsiChar): Word;\nbegin\n  Result := ASA_API.db_change_nchar_charset(sqlca, CharSet);\nend;\n\n{TZASA7PlainDriver}\n\nfunction TZASA7PlainDriver.Clone: IZPlainDriver;\nbegin\n  Result := TZASA7PlainDriver.Create;\nend;\n\nconstructor TZASA7PlainDriver.Create;\nbegin\n  inherited Create;\n  FLoader.AddLocation({$IFNDEF LINUX}ASA7_WINDOWS_DLL_LOCATION{$ELSE}ASA7_LINUX_DLL_LOCATION{$ENDIF});\nend;\n\nfunction TZASA7PlainDriver.GetProtocol: string;\nbegin\n  Result := 'ASA7';\nend;\n\nfunction TZASA7PlainDriver.GetDescription: string;\nbegin\n  Result := 'Native Plain Driver for ASA 7.0 DBLib';\nend;\n\n{TZASA8PlainDriver}\n\nconstructor TZASA8PlainDriver.Create;\nbegin\n  inherited Create;\n  FLoader.AddLocation({$IFNDEF LINUX}ASA8_WINDOWS_DLL_LOCATION{$ELSE}ASA8_LINUX_DLL_LOCATION{$ENDIF});\nend;\n\nfunction TZASA8PlainDriver.Clone: IZPlainDriver;\nbegin\n  Result := TZASA8PlainDriver.Create;\nend;\n\nfunction TZASA8PlainDriver.GetProtocol: string;\nbegin\n  Result := 'ASA8';\nend;\n\nfunction TZASA8PlainDriver.GetDescription: string;\nbegin\n  Result := 'Native Plain Driver for ASA 8.0 DBLib';\nend;\n\n{TZASA9PlainDriver}\n\nconstructor TZASA9PlainDriver.Create;\nbegin\n  inherited Create;\n  FLoader.AddLocation({$IFNDEF LINUX}ASA9_WINDOWS_DLL_LOCATION{$ELSE}ASA9_LINUX_DLL_LOCATION{$ENDIF});\nend;\n\nfunction TZASA9PlainDriver.Clone: IZPlainDriver;\nbegin\n  Result := TZASA9PlainDriver.Create;\nend;\n\nfunction TZASA9PlainDriver.GetProtocol: string;\nbegin\n  Result := 'ASA9';\nend;\n\nfunction TZASA9PlainDriver.GetDescription: string;\nbegin\n  Result := 'Native Plain Driver for ASA 9.0 DBLib';\nend;\n\n{TZASA12PlainDriver}\n\nconstructor TZASA12PlainDriver.Create;\nbegin\n  inherited Create;\n  FLoader.AddLocation({$IFNDEF LINUX}ASA12_WINDOWS_DLL_LOCATION{$ELSE}ASA12_LINUX_DLL_LOCATION{$ENDIF});\nend;\n\nfunction TZASA12PlainDriver.Clone: IZPlainDriver;\nbegin\n  Result := TZASA12PlainDriver.Create;\nend;\n\nfunction TZASA12PlainDriver.GetProtocol: string;\nbegin\n  Result := 'ASA12';\nend;\n\nfunction TZASA12PlainDriver.GetDescription: string;\nbegin\n  Result := 'Native Plain Driver for ASA 9.0 DBLib';\nend;\n\nend.\n\n"
  },
  {
    "path": "lib/zeosdbo/src/plain/ZPlainAdo.pas",
    "content": "{@********************************************************}\n{    Copyright (c) 1999-2012 Zeos Development Group       }\n{                                                         }\n{ License Agreement:                                      }\n{                                                         }\n{ This library is distributed in the hope that it will be }\n{ useful, but WITHOUT ANY WARRANTY; without even the      }\n{ implied warranty of MERCHANTABILITY or FITNESS FOR      }\n{ A PARTICULAR PURPOSE.  See the GNU Lesser General       }\n{ Public License for more details.                        }\n{                                                         }\n{ The source code of the ZEOS Libraries and packages are  }\n{ distributed under the Library GNU General Public        }\n{ License (see the file COPYING / COPYING.ZEOS)           }\n{ with the following  modification:                       }\n{ As a special exception, the copyright holders of this   }\n{ library give you permission to link this library with   }\n{ independent modules to produce an executable,           }\n{ regardless of the license terms of these independent    }\n{ modules, and to copy and distribute the resulting       }\n{ executable under terms of your choice, provided that    }\n{ you also meet, for each linked independent module,      }\n{ the terms and conditions of the license of that module. }\n{ An independent module is a module which is not derived  }\n{ from or based on this library. If you modify this       }\n{ library, you may extend this exception to your version  }\n{ of the library, but you are not obligated to do so.     }\n{ If you do not wish to do so, delete this exception      }\n{ statement from your version.                            }\n{                                                         }\n{                                                         }\n{ The project web site is located on:                     }\n{   http://zeos.firmos.at  (FORUM)                        }\n{   http://sourceforge.net/p/zeoslib/tickets/ (BUGTRACKER)}\n{   svn://svn.code.sf.net/p/zeoslib/code-0/trunk (SVN)    }\n{                                                         }\n{   http://www.sourceforge.net/projects/zeoslib.          }\n{                                                         }\n{                                                         }\n{                                 Zeos Development Group. }\n{********************************************************@}\n\nunit ZPlainAdo;\n\n// ************************************************************************ //\n// WARNING                                                                    \n// -------                                                                    \n// The types declared in this file were generated from data read from a\n// Type Library. If this type library is explicitly or indirectly (via        \n// another type library referring to this type library) re-imported, or the   \n// 'Refresh' command of the Type Library Editor activated while editing the   \n// Type Library, the contents of this file will be regenerated and all        \n// manual modifications will be lost.                                         \n// ************************************************************************ //\n\n// PASTLWTR : $Revision: 1.9 $\n// File generated on 2003.07.12. 17.11.28 from Type Library described below.\n\n// ************************************************************************  //\n// Type Lib: C:\\Program Files\\Common Files\\System\\ado\\msado15.dll (1)\n// LIBID: {EF53050B-882E-4776-B643-EDA472E8E3F2}\n// LCID: 0\n// Helpfile: C:\\WINDOWS\\HELP\\ado270.chm\n// DepndLst: \n//   (1) v2.0 stdole, (C:\\WINDOWS\\System32\\stdole2.tlb)\n//   (2) v4.0 StdVCL, (C:\\WINDOWS\\System32\\stdvcl40.dll)\n// Errors:\n//   Hint: TypeInfo 'Property' changed to 'Property_'\n//   Hint: TypeInfo 'Record' changed to 'Record_'\n//   Hint: Parameter 'Object' of _DynaCollection.Append changed to 'Object_'\n//   Hint: Member 'Type' of 'Property' changed to 'Type_'\n//   Hint: Parameter 'Type' of Command15.CreateParameter changed to 'Type_'\n//   Hint: Parameter 'Type' of Fields20._Append changed to 'Type_'\n//   Hint: Parameter 'Type' of Fields.Append changed to 'Type_'\n//   Hint: Member 'Type' of 'Field20' changed to 'Type_'\n//   Hint: Member 'Type' of '_Parameter' changed to 'Type_'\n//   Hint: Member 'Type' of '_Stream' changed to 'Type_'\n//   Hint: Member 'Type' of 'Field15' changed to 'Type_'\n// ************************************************************************ //\n{$TYPEDADDRESS OFF} // Unit must be compiled without type-checked pointers. \n{$WRITEABLECONST ON}\n//{$HPPEMIT '#undef EOF'}\ninterface\n\n{$I ZPlain.inc}\n\nuses Windows, Classes, ActiveX;\n\n\n// *********************************************************************//\n// GUIDS declared in the TypeLibrary. Following prefixes are used:        \n//   Type Libraries     : LIBID_xxxx                                      \n//   CoClasses          : CLASS_xxxx                                      \n//   DISPInterfaces     : DIID_xxxx                                       \n//   Non-DISP interfaces: IID_xxxx                                        \n// *********************************************************************//\nconst\n  // TypeLibrary Major and minor versions\n  ADODBMajorVersion = 2;\n  ADODBMinorVersion = 7;\n\n  LIBID_ADODB: TGUID = '{EF53050B-882E-4776-B643-EDA472E8E3F2}';\n\n  IID__Collection: TGUID = '{00000512-0000-0010-8000-00AA006D2EA4}';\n  IID__DynaCollection: TGUID = '{00000513-0000-0010-8000-00AA006D2EA4}';\n  IID__ADO: TGUID = '{00000534-0000-0010-8000-00AA006D2EA4}';\n  IID_Properties: TGUID = '{00000504-0000-0010-8000-00AA006D2EA4}';\n  IID_Property_: TGUID = '{00000503-0000-0010-8000-00AA006D2EA4}';\n  IID_Error: TGUID = '{00000500-0000-0010-8000-00AA006D2EA4}';\n  IID_Errors: TGUID = '{00000501-0000-0010-8000-00AA006D2EA4}';\n  IID_Command15: TGUID = '{00000508-0000-0010-8000-00AA006D2EA4}';\n  IID_Connection15: TGUID = '{00000515-0000-0010-8000-00AA006D2EA4}';\n  IID__Connection: TGUID = '{00000550-0000-0010-8000-00AA006D2EA4}';\n  IID_Recordset15: TGUID = '{0000050E-0000-0010-8000-00AA006D2EA4}';\n  IID_Recordset20: TGUID = '{0000054F-0000-0010-8000-00AA006D2EA4}';\n  IID_Recordset21: TGUID = '{00000555-0000-0010-8000-00AA006D2EA4}';\n  IID__Recordset: TGUID = '{00000556-0000-0010-8000-00AA006D2EA4}';\n  IID_Fields15: TGUID = '{00000506-0000-0010-8000-00AA006D2EA4}';\n  IID_Fields20: TGUID = '{0000054D-0000-0010-8000-00AA006D2EA4}';\n  IID_Fields: TGUID = '{00000564-0000-0010-8000-00AA006D2EA4}';\n  IID_Field20: TGUID = '{0000054C-0000-0010-8000-00AA006D2EA4}';\n  IID_Field: TGUID = '{00000569-0000-0010-8000-00AA006D2EA4}';\n  IID__Parameter: TGUID = '{0000050C-0000-0010-8000-00AA006D2EA4}';\n  IID_Parameters: TGUID = '{0000050D-0000-0010-8000-00AA006D2EA4}';\n  IID_Command25: TGUID = '{0000054E-0000-0010-8000-00AA006D2EA4}';\n  IID__Command: TGUID = '{B08400BD-F9D1-4D02-B856-71D5DBA123E9}';\n  IID_ConnectionEventsVt: TGUID = '{00000402-0000-0010-8000-00AA006D2EA4}';\n  IID_RecordsetEventsVt: TGUID = '{00000403-0000-0010-8000-00AA006D2EA4}';\n  DIID_ConnectionEvents: TGUID = '{00000400-0000-0010-8000-00AA006D2EA4}';\n  DIID_RecordsetEvents: TGUID = '{00000266-0000-0010-8000-00AA006D2EA4}';\n  IID_ADOConnectionConstruction15: TGUID = '{00000516-0000-0010-8000-00AA006D2EA4}';\n  IID_ADOConnectionConstruction: TGUID = '{00000551-0000-0010-8000-00AA006D2EA4}';\n  CLASS_Connection: TGUID = '{00000514-0000-0010-8000-00AA006D2EA4}';\n  IID__Record: TGUID = '{00000562-0000-0010-8000-00AA006D2EA4}';\n  CLASS_Record_: TGUID = '{00000560-0000-0010-8000-00AA006D2EA4}';\n  IID__Stream: TGUID = '{00000565-0000-0010-8000-00AA006D2EA4}';\n  CLASS_Stream: TGUID = '{00000566-0000-0010-8000-00AA006D2EA4}';\n  IID_ADORecordConstruction: TGUID = '{00000567-0000-0010-8000-00AA006D2EA4}';\n  IID_ADOStreamConstruction: TGUID = '{00000568-0000-0010-8000-00AA006D2EA4}';\n  IID_ADOCommandConstruction: TGUID = '{00000517-0000-0010-8000-00AA006D2EA4}';\n  CLASS_Command: TGUID = '{00000507-0000-0010-8000-00AA006D2EA4}';\n  CLASS_Recordset: TGUID = '{00000535-0000-0010-8000-00AA006D2EA4}';\n  IID_ADORecordsetConstruction: TGUID = '{00000283-0000-0010-8000-00AA006D2EA4}';\n  IID_Field15: TGUID = '{00000505-0000-0010-8000-00AA006D2EA4}';\n  CLASS_Parameter: TGUID = '{0000050B-0000-0010-8000-00AA006D2EA4}';\n\n// *********************************************************************//\n// Declaration of Enumerations defined in Type Library                    \n// *********************************************************************//\n// Constants for enum CursorTypeEnum\ntype\n  CursorTypeEnum = TOleEnum;\nconst\n  adOpenUnspecified = $FFFFFFFF;\n  adOpenForwardOnly = $00000000;\n  adOpenKeyset = $00000001;\n  adOpenDynamic = $00000002;\n  adOpenStatic = $00000003;\n\n// Constants for enum CursorOptionEnum\ntype\n  CursorOptionEnum = TOleEnum;\nconst\n  adHoldRecords = $00000100;\n  adMovePrevious = $00000200;\n  adAddNew = $01000400;\n  adDelete = $01000800;\n  adUpdate = $01008000;\n  adBookmark = $00002000;\n  adApproxPosition = $00004000;\n  adUpdateBatch = $00010000;\n  adResync = $00020000;\n  adNotify = $00040000;\n  adFind = $00080000;\n  adSeek = $00400000;\n  adIndex = $00800000;\n\n// Constants for enum LockTypeEnum\ntype\n  LockTypeEnum = TOleEnum;\nconst\n  adLockUnspecified = $FFFFFFFF;\n  adLockReadOnly = $00000001;\n  adLockPessimistic = $00000002;\n  adLockOptimistic = $00000003;\n  adLockBatchOptimistic = $00000004;\n\n// Constants for enum ExecuteOptionEnum\ntype\n  ExecuteOptionEnum = TOleEnum;\nconst\n  adOptionUnspecified = $FFFFFFFF;\n  adAsyncExecute = $00000010;\n  adAsyncFetch = $00000020;\n  adAsyncFetchNonBlocking = $00000040;\n  adExecuteNoRecords = $00000080;\n  adExecuteStream = $00000400;\n  adExecuteRecord = $00000800;\n\n// Constants for enum ConnectOptionEnum\ntype\n  ConnectOptionEnum = TOleEnum;\nconst\n  adConnectUnspecified = $FFFFFFFF;\n  adAsyncConnect = $00000010;\n\n// Constants for enum ObjectStateEnum\ntype\n  ObjectStateEnum = TOleEnum;\nconst\n  adStateClosed = $00000000;\n  adStateOpen = $00000001;\n  adStateConnecting = $00000002;\n  adStateExecuting = $00000004;\n  adStateFetching = $00000008;\n\n// Constants for enum CursorLocationEnum\ntype\n  CursorLocationEnum = TOleEnum;\nconst\n  adUseNone = $00000001;\n  adUseServer = $00000002;\n  adUseClient = $00000003;\n  adUseClientBatch = $00000003;\n\n// Constants for enum DataTypeEnum\ntype\n  DataTypeEnum = TOleEnum;\nconst\n  adEmpty = $00000000;\n  adTinyInt = $00000010;\n  adSmallInt = $00000002;\n  adInteger = $00000003;\n  adBigInt = $00000014;\n  adUnsignedTinyInt = $00000011;\n  adUnsignedSmallInt = $00000012;\n  adUnsignedInt = $00000013;\n  adUnsignedBigInt = $00000015;\n  adSingle = $00000004;\n  adDouble = $00000005;\n  adCurrency = $00000006;\n  adDecimal = $0000000E;\n  adNumeric = $00000083;\n  adBoolean = $0000000B;\n  adError = $0000000A;\n  adUserDefined = $00000084;\n  adVariant = $0000000C;\n  adIDispatch = $00000009;\n  adIUnknown = $0000000D;\n  adGUID = $00000048;\n  adDate = $00000007;\n  adDBDate = $00000085;\n  adDBTime = $00000086;\n  adDBTimeStamp = $00000087;\n  adBSTR = $00000008;\n  adChar = $00000081;\n  adVarChar = $000000C8;\n  adLongVarChar = $000000C9;\n  adWChar = $00000082;\n  adVarWChar = $000000CA;\n  adLongVarWChar = $000000CB;\n  adBinary = $00000080;\n  adVarBinary = $000000CC;\n  adLongVarBinary = $000000CD;\n  adChapter = $00000088;\n  adFileTime = $00000040;\n  adPropVariant = $0000008A;\n  adVarNumeric = $0000008B;\n  adArray = $00002000;\n\n// Constants for enum FieldAttributeEnum\ntype\n  FieldAttributeEnum = TOleEnum;\nconst\n  adFldUnspecified = $FFFFFFFF;\n  adFldMayDefer = $00000002;\n  adFldUpdatable = $00000004;\n  adFldUnknownUpdatable = $00000008;\n  adFldFixed = $00000010;\n  adFldIsNullable = $00000020;\n  adFldMayBeNull = $00000040;\n  adFldLong = $00000080;\n  adFldRowID = $00000100;\n  adFldRowVersion = $00000200;\n  adFldCacheDeferred = $00001000;\n  adFldIsChapter = $00002000;\n  adFldNegativeScale = $00004000;\n  adFldKeyColumn = $00008000;\n  adFldIsRowURL = $00010000;\n  adFldIsDefaultStream = $00020000;\n  adFldIsCollection = $00040000;\n\n// Constants for enum EditModeEnum\ntype\n  EditModeEnum = TOleEnum;\nconst\n  adEditNone = $00000000;\n  adEditInProgress = $00000001;\n  adEditAdd = $00000002;\n  adEditDelete = $00000004;\n\n// Constants for enum RecordStatusEnum\ntype\n  RecordStatusEnum = TOleEnum;\nconst\n  adRecOK = $00000000;\n  adRecNew = $00000001;\n  adRecModified = $00000002;\n  adRecDeleted = $00000004;\n  adRecUnmodified = $00000008;\n  adRecInvalid = $00000010;\n  adRecMultipleChanges = $00000040;\n  adRecPendingChanges = $00000080;\n  adRecCanceled = $00000100;\n  adRecCantRelease = $00000400;\n  adRecConcurrencyViolation = $00000800;\n  adRecIntegrityViolation = $00001000;\n  adRecMaxChangesExceeded = $00002000;\n  adRecObjectOpen = $00004000;\n  adRecOutOfMemory = $00008000;\n  adRecPermissionDenied = $00010000;\n  adRecSchemaViolation = $00020000;\n  adRecDBDeleted = $00040000;\n\n// Constants for enum GetRowsOptionEnum\ntype\n  GetRowsOptionEnum = TOleEnum;\nconst\n  adGetRowsRest = $FFFFFFFF;\n\n// Constants for enum PositionEnum\ntype\n  PositionEnum = TOleEnum;\nconst\n  adPosUnknown = $FFFFFFFF;\n  adPosBOF = $FFFFFFFE;\n  adPosEOF = $FFFFFFFD;\n\n// Constants for enum BookmarkEnum\ntype\n  BookmarkEnum = TOleEnum;\nconst\n  adBookmarkCurrent = $00000000;\n  adBookmarkFirst = $00000001;\n  adBookmarkLast = $00000002;\n\n// Constants for enum MarshalOptionsEnum\ntype\n  MarshalOptionsEnum = TOleEnum;\nconst\n  adMarshalAll = $00000000;\n  adMarshalModifiedOnly = $00000001;\n\n// Constants for enum AffectEnum\ntype\n  AffectEnum = TOleEnum;\nconst\n  adAffectCurrent = $00000001;\n  adAffectGroup = $00000002;\n  adAffectAll = $00000003;\n  adAffectAllChapters = $00000004;\n\n// Constants for enum ResyncEnum\ntype\n  ResyncEnum = TOleEnum;\nconst\n  adResyncUnderlyingValues = $00000001;\n  adResyncAllValues = $00000002;\n\n// Constants for enum CompareEnum\ntype\n  CompareEnum = TOleEnum;\nconst\n  adCompareLessThan = $00000000;\n  adCompareEqual = $00000001;\n  adCompareGreaterThan = $00000002;\n  adCompareNotEqual = $00000003;\n  adCompareNotComparable = $00000004;\n\n// Constants for enum FilterGroupEnum\ntype\n  FilterGroupEnum = TOleEnum;\nconst\n  adFilterNone = $00000000;\n  adFilterPendingRecords = $00000001;\n  adFilterAffectedRecords = $00000002;\n  adFilterFetchedRecords = $00000003;\n  adFilterPredicate = $00000004;\n  adFilterConflictingRecords = $00000005;\n\n// Constants for enum SearchDirectionEnum\ntype\n  SearchDirectionEnum = TOleEnum;\nconst\n  adSearchForward = $00000001;\n  adSearchBackward = $FFFFFFFF;\n\n// Constants for enum PersistFormatEnum\ntype\n  PersistFormatEnum = TOleEnum;\nconst\n  adPersistADTG = $00000000;\n  adPersistXML = $00000001;\n\n// Constants for enum StringFormatEnum\ntype\n  StringFormatEnum = TOleEnum;\nconst\n  adClipString = $00000002;\n\n// Constants for enum ConnectPromptEnum\ntype\n  ConnectPromptEnum = TOleEnum;\nconst\n  adPromptAlways = $00000001;\n  adPromptComplete = $00000002;\n  adPromptCompleteRequired = $00000003;\n  adPromptNever = $00000004;\n\n// Constants for enum ConnectModeEnum\ntype\n  ConnectModeEnum = TOleEnum;\nconst\n  adModeUnknown = $00000000;\n  adModeRead = $00000001;\n  adModeWrite = $00000002;\n  adModeReadWrite = $00000003;\n  adModeShareDenyRead = $00000004;\n  adModeShareDenyWrite = $00000008;\n  adModeShareExclusive = $0000000C;\n  adModeShareDenyNone = $00000010;\n  adModeRecursive = $00400000;\n\n// Constants for enum RecordCreateOptionsEnum\ntype\n  RecordCreateOptionsEnum = TOleEnum;\nconst\n  adCreateCollection = $00002000;\n  adCreateStructDoc = $80000000;\n  adCreateNonCollection = $00000000;\n  adOpenIfExists = $02000000;\n  adCreateOverwrite = $04000000;\n  adFailIfNotExists = $FFFFFFFF;\n\n// Constants for enum RecordOpenOptionsEnum\ntype\n  RecordOpenOptionsEnum = TOleEnum;\nconst\n  adOpenRecordUnspecified = $FFFFFFFF;\n  adOpenSource = $00800000;\n  adOpenOutput = $00800000;\n  adOpenAsync = $00001000;\n  adDelayFetchStream = $00004000;\n  adDelayFetchFields = $00008000;\n  adOpenExecuteCommand = $00010000;\n\n// Constants for enum IsolationLevelEnum\ntype\n  IsolationLevelEnum = TOleEnum;\nconst\n  adXactUnspecified = $FFFFFFFF;\n  adXactChaos = $00000010;\n  adXactReadUncommitted = $00000100;\n  adXactBrowse = $00000100;\n  adXactCursorStability = $00001000;\n  adXactReadCommitted = $00001000;\n  adXactRepeatableRead = $00010000;\n  adXactSerializable = $00100000;\n  adXactIsolated = $00100000;\n\n// Constants for enum XactAttributeEnum\ntype\n  XactAttributeEnum = TOleEnum;\nconst\n  adXactCommitRetaining = $00020000;\n  adXactAbortRetaining = $00040000;\n  adXactAsyncPhaseOne = $00080000;\n  adXactSyncPhaseOne = $00100000;\n\n// Constants for enum PropertyAttributesEnum\ntype\n  PropertyAttributesEnum = TOleEnum;\nconst\n  adPropNotSupported = $00000000;\n  adPropRequired = $00000001;\n  adPropOptional = $00000002;\n  adPropRead = $00000200;\n  adPropWrite = $00000400;\n\n// Constants for enum ErrorValueEnum\ntype\n  ErrorValueEnum = TOleEnum;\nconst\n  adErrProviderFailed = $00000BB8;\n  adErrInvalidArgument = $00000BB9;\n  adErrOpeningFile = $00000BBA;\n  adErrReadFile = $00000BBB;\n  adErrWriteFile = $00000BBC;\n  adErrNoCurrentRecord = $00000BCD;\n  adErrIllegalOperation = $00000C93;\n  adErrCantChangeProvider = $00000C94;\n  adErrInTransaction = $00000CAE;\n  adErrFeatureNotAvailable = $00000CB3;\n  adErrItemNotFound = $00000CC1;\n  adErrObjectInCollection = $00000D27;\n  adErrObjectNotSet = $00000D5C;\n  adErrDataConversion = $00000D5D;\n  adErrObjectClosed = $00000E78;\n  adErrObjectOpen = $00000E79;\n  adErrProviderNotFound = $00000E7A;\n  adErrBoundToCommand = $00000E7B;\n  adErrInvalidParamInfo = $00000E7C;\n  adErrInvalidConnection = $00000E7D;\n  adErrNotReentrant = $00000E7E;\n  adErrStillExecuting = $00000E7F;\n  adErrOperationCancelled = $00000E80;\n  adErrStillConnecting = $00000E81;\n  adErrInvalidTransaction = $00000E82;\n  adErrNotExecuting = $00000E83;\n  adErrUnsafeOperation = $00000E84;\n  adwrnSecurityDialog = $00000E85;\n  adwrnSecurityDialogHeader = $00000E86;\n  adErrIntegrityViolation = $00000E87;\n  adErrPermissionDenied = $00000E88;\n  adErrDataOverflow = $00000E89;\n  adErrSchemaViolation = $00000E8A;\n  adErrSignMismatch = $00000E8B;\n  adErrCantConvertvalue = $00000E8C;\n  adErrCantCreate = $00000E8D;\n  adErrColumnNotOnThisRow = $00000E8E;\n  adErrURLDoesNotExist = $00000E8F;\n  adErrTreePermissionDenied = $00000E90;\n  adErrInvalidURL = $00000E91;\n  adErrResourceLocked = $00000E92;\n  adErrResourceExists = $00000E93;\n  adErrCannotComplete = $00000E94;\n  adErrVolumeNotFound = $00000E95;\n  adErrOutOfSpace = $00000E96;\n  adErrResourceOutOfScope = $00000E97;\n  adErrUnavailable = $00000E98;\n  adErrURLNamedRowDoesNotExist = $00000E99;\n  adErrDelResOutOfScope = $00000E9A;\n  adErrPropInvalidColumn = $00000E9B;\n  adErrPropInvalidOption = $00000E9C;\n  adErrPropInvalidValue = $00000E9D;\n  adErrPropConflicting = $00000E9E;\n  adErrPropNotAllSettable = $00000E9F;\n  adErrPropNotSet = $00000EA0;\n  adErrPropNotSettable = $00000EA1;\n  adErrPropNotSupported = $00000EA2;\n  adErrCatalogNotSet = $00000EA3;\n  adErrCantChangeConnection = $00000EA4;\n  adErrFieldsUpdateFailed = $00000EA5;\n  adErrDenyNotSupported = $00000EA6;\n  adErrDenyTypeNotSupported = $00000EA7;\n  adErrProviderNotSpecified = $00000EA9;\n\n// Constants for enum ParameterAttributesEnum\ntype\n  ParameterAttributesEnum = TOleEnum;\nconst\n  adParamSigned = $00000010;\n  adParamNullable = $00000040;\n  adParamLong = $00000080;\n\n// Constants for enum ParameterDirectionEnum\ntype\n  ParameterDirectionEnum = TOleEnum;\nconst\n  adParamUnknown = $00000000;\n  adParamInput = $00000001;\n  adParamOutput = $00000002;\n  adParamInputOutput = $00000003;\n  adParamReturnValue = $00000004;\n\n// Constants for enum CommandTypeEnum\ntype\n  CommandTypeEnum = TOleEnum;\nconst\n  adCmdUnspecified = $FFFFFFFF;\n  adCmdUnknown = $00000008;\n  adCmdText = $00000001;\n  adCmdTable = $00000002;\n  adCmdStoredProc = $00000004;\n  adCmdFile = $00000100;\n  adCmdTableDirect = $00000200;\n\n// Constants for enum EventStatusEnum\ntype\n  EventStatusEnum = TOleEnum;\nconst\n  adStatusOK = $00000001;\n  adStatusErrorsOccurred = $00000002;\n  adStatusCantDeny = $00000003;\n  adStatusCancel = $00000004;\n  adStatusUnwantedEvent = $00000005;\n\n// Constants for enum EventReasonEnum\ntype\n  EventReasonEnum = TOleEnum;\nconst\n  adRsnAddNew = $00000001;\n  adRsnDelete = $00000002;\n  adRsnUpdate = $00000003;\n  adRsnUndoUpdate = $00000004;\n  adRsnUndoAddNew = $00000005;\n  adRsnUndoDelete = $00000006;\n  adRsnRequery = $00000007;\n  adRsnResynch = $00000008;\n  adRsnClose = $00000009;\n  adRsnMove = $0000000A;\n  adRsnFirstChange = $0000000B;\n  adRsnMoveFirst = $0000000C;\n  adRsnMoveNext = $0000000D;\n  adRsnMovePrevious = $0000000E;\n  adRsnMoveLast = $0000000F;\n\n// Constants for enum SchemaEnum\ntype\n  SchemaEnum = TOleEnum;\nconst\n  adSchemaProviderSpecific = $FFFFFFFF;\n  adSchemaAsserts = $00000000;\n  adSchemaCatalogs = $00000001;\n  adSchemaCharacterSets = $00000002;\n  adSchemaCollations = $00000003;\n  adSchemaColumns = $00000004;\n  adSchemaCheckConstraints = $00000005;\n  adSchemaConstraintColumnUsage = $00000006;\n  adSchemaConstraintTableUsage = $00000007;\n  adSchemaKeyColumnUsage = $00000008;\n  adSchemaReferentialContraints = $00000009;\n  adSchemaReferentialConstraints = $00000009;\n  adSchemaTableConstraints = $0000000A;\n  adSchemaColumnsDomainUsage = $0000000B;\n  adSchemaIndexes = $0000000C;\n  adSchemaColumnPrivileges = $0000000D;\n  adSchemaTablePrivileges = $0000000E;\n  adSchemaUsagePrivileges = $0000000F;\n  adSchemaProcedures = $00000010;\n  adSchemaSchemata = $00000011;\n  adSchemaSQLLanguages = $00000012;\n  adSchemaStatistics = $00000013;\n  adSchemaTables = $00000014;\n  adSchemaTranslations = $00000015;\n  adSchemaProviderTypes = $00000016;\n  adSchemaViews = $00000017;\n  adSchemaViewColumnUsage = $00000018;\n  adSchemaViewTableUsage = $00000019;\n  adSchemaProcedureParameters = $0000001A;\n  adSchemaForeignKeys = $0000001B;\n  adSchemaPrimaryKeys = $0000001C;\n  adSchemaProcedureColumns = $0000001D;\n  adSchemaDBInfoKeywords = $0000001E;\n  adSchemaDBInfoLiterals = $0000001F;\n  adSchemaCubes = $00000020;\n  adSchemaDimensions = $00000021;\n  adSchemaHierarchies = $00000022;\n  adSchemaLevels = $00000023;\n  adSchemaMeasures = $00000024;\n  adSchemaProperties = $00000025;\n  adSchemaMembers = $00000026;\n  adSchemaTrustees = $00000027;\n  adSchemaFunctions = $00000028;\n  adSchemaActions = $00000029;\n  adSchemaCommands = $0000002A;\n  adSchemaSets = $0000002B;\n\n// Constants for enum FieldStatusEnum\ntype\n  FieldStatusEnum = TOleEnum;\nconst\n  adFieldOK = $00000000;\n  adFieldCantConvertValue = $00000002;\n  adFieldIsNull = $00000003;\n  adFieldTruncated = $00000004;\n  adFieldSignMismatch = $00000005;\n  adFieldDataOverflow = $00000006;\n  adFieldCantCreate = $00000007;\n  adFieldUnavailable = $00000008;\n  adFieldPermissionDenied = $00000009;\n  adFieldIntegrityViolation = $0000000A;\n  adFieldSchemaViolation = $0000000B;\n  adFieldBadStatus = $0000000C;\n  adFieldDefault = $0000000D;\n  adFieldIgnore = $0000000F;\n  adFieldDoesNotExist = $00000010;\n  adFieldInvalidURL = $00000011;\n  adFieldResourceLocked = $00000012;\n  adFieldResourceExists = $00000013;\n  adFieldCannotComplete = $00000014;\n  adFieldVolumeNotFound = $00000015;\n  adFieldOutOfSpace = $00000016;\n  adFieldCannotDeleteSource = $00000017;\n  adFieldReadOnly = $00000018;\n  adFieldResourceOutOfScope = $00000019;\n  adFieldAlreadyExists = $0000001A;\n  adFieldPendingInsert = $00010000;\n  adFieldPendingDelete = $00020000;\n  adFieldPendingChange = $00040000;\n  adFieldPendingUnknown = $00080000;\n  adFieldPendingUnknownDelete = $00100000;\n\n// Constants for enum SeekEnum\ntype\n  SeekEnum = TOleEnum;\nconst\n  adSeekFirstEQ = $00000001;\n  adSeekLastEQ = $00000002;\n  adSeekAfterEQ = $00000004;\n  adSeekAfter = $00000008;\n  adSeekBeforeEQ = $00000010;\n  adSeekBefore = $00000020;\n\n// Constants for enum ADCPROP_UPDATECRITERIA_ENUM\ntype\n  ADCPROP_UPDATECRITERIA_ENUM = TOleEnum;\nconst\n  adCriteriaKey = $00000000;\n  adCriteriaAllCols = $00000001;\n  adCriteriaUpdCols = $00000002;\n  adCriteriaTimeStamp = $00000003;\n\n// Constants for enum ADCPROP_ASYNCTHREADPRIORITY_ENUM\ntype\n  ADCPROP_ASYNCTHREADPRIORITY_ENUM = TOleEnum;\nconst\n  adPriorityLowest = $00000001;\n  adPriorityBelowNormal = $00000002;\n  adPriorityNormal = $00000003;\n  adPriorityAboveNormal = $00000004;\n  adPriorityHighest = $00000005;\n\n// Constants for enum ADCPROP_AUTORECALC_ENUM\ntype\n  ADCPROP_AUTORECALC_ENUM = TOleEnum;\nconst\n  adRecalcUpFront = $00000000;\n  adRecalcAlways = $00000001;\n\n// Constants for enum ADCPROP_UPDATERESYNC_ENUM\ntype\n  ADCPROP_UPDATERESYNC_ENUM = TOleEnum;\nconst\n  adResyncNone = $00000000;\n  adResyncAutoIncrement = $00000001;\n  adResyncConflicts = $00000002;\n  adResyncUpdates = $00000004;\n  adResyncInserts = $00000008;\n  adResyncAll = $0000000F;\n\n// Constants for enum MoveRecordOptionsEnum\ntype\n  MoveRecordOptionsEnum = TOleEnum;\nconst\n  adMoveUnspecified = $FFFFFFFF;\n  adMoveOverWrite = $00000001;\n  adMoveDontUpdateLinks = $00000002;\n  adMoveAllowEmulation = $00000004;\n\n// Constants for enum CopyRecordOptionsEnum\ntype\n  CopyRecordOptionsEnum = TOleEnum;\nconst\n  adCopyUnspecified = $FFFFFFFF;\n  adCopyOverWrite = $00000001;\n  adCopyAllowEmulation = $00000004;\n  adCopyNonRecursive = $00000002;\n\n// Constants for enum StreamTypeEnum\ntype\n  StreamTypeEnum = TOleEnum;\nconst\n  adTypeBinary = $00000001;\n  adTypeText = $00000002;\n\n// Constants for enum LineSeparatorEnum\ntype\n  LineSeparatorEnum = TOleEnum;\nconst\n  adLF = $0000000A;\n  adCR = $0000000D;\n  adCRLF = $FFFFFFFF;\n\n// Constants for enum StreamOpenOptionsEnum\ntype\n  StreamOpenOptionsEnum = TOleEnum;\nconst\n  adOpenStreamUnspecified = $FFFFFFFF;\n  adOpenStreamAsync = $00000001;\n  adOpenStreamFromRecord = $00000004;\n\n// Constants for enum StreamWriteEnum\ntype\n  StreamWriteEnum = TOleEnum;\nconst\n  adWriteChar = $00000000;\n  adWriteLine = $00000001;\n  stWriteChar = $00000000;\n  stWriteLine = $00000001;\n\n// Constants for enum SaveOptionsEnum\ntype\n  SaveOptionsEnum = TOleEnum;\nconst\n  adSaveCreateNotExist = $00000001;\n  adSaveCreateOverWrite = $00000002;\n\n// Constants for enum FieldEnum\ntype\n  FieldEnum = TOleEnum;\nconst\n  adDefaultStream = $FFFFFFFF;\n  adRecordURL = $FFFFFFFE;\n\n// Constants for enum StreamReadEnum\ntype\n  StreamReadEnum = TOleEnum;\nconst\n  adReadAll = $FFFFFFFF;\n  adReadLine = $FFFFFFFE;\n\n// Constants for enum RecordTypeEnum\ntype\n  RecordTypeEnum = TOleEnum;\nconst\n  adSimpleRecord = $00000000;\n  adCollectionRecord = $00000001;\n  adStructDoc = $00000002;\n\ntype\n\n// *********************************************************************//\n// Forward declaration of types defined in TypeLibrary                    \n// *********************************************************************//\n  _Collection = interface;\n  _DynaCollection = interface;\n  _ADO = interface;\n  Properties = interface;\n  Property_ = interface;\n  Error = interface;\n  Errors = interface;\n  Command15 = interface;\n  Connection15 = interface;\n  _Connection = interface;\n  Recordset15 = interface;\n  Recordset20 = interface;\n  Recordset21 = interface;\n  _Recordset = interface;\n  Fields15 = interface;\n  Fields20 = interface;\n  Fields = interface;\n  Field20 = interface;\n  Field = interface;\n  _Parameter = interface;\n  Parameters = interface;\n  Command25 = interface;\n  _Command = interface;\n  ConnectionEventsVt = interface;\n  RecordsetEventsVt = interface;\n  ADOConnectionConstruction15 = interface;\n  ADOConnectionConstruction = interface;\n  _Record = interface;\n  _Stream = interface;\n  ADORecordConstruction = interface;\n  ADOStreamConstruction = interface;\n  ADOCommandConstruction = interface;\n  ADORecordsetConstruction = interface;\n  Field15 = interface;\n\n\n\n// *********************************************************************//\n// Declaration of structures, unions and aliases.                         \n// *********************************************************************//\n  POleVariant1 = ^OleVariant; {*}\n\n  PositionEnum_Param = PositionEnum; \n  SearchDirection = SearchDirectionEnum; \n  ADO_LONGPTR = Integer; \n\n// *********************************************************************//\n// Interface: _Collection\n// Flags:     (4544) Dual NonExtensible OleAutomation Dispatchable\n// GUID:      {00000512-0000-0010-8000-00AA006D2EA4}\n// *********************************************************************//\n  _Collection = interface(IDispatch)\n    ['{00000512-0000-0010-8000-00AA006D2EA4}']\n    function Get_Count: Integer; safecall;\n    function _NewEnum: IUnknown; safecall;\n    procedure Refresh; safecall;\n    property Count: Integer read Get_Count;\n  end;\n\n// *********************************************************************//\n// Interface: _DynaCollection\n// Flags:     (4544) Dual NonExtensible OleAutomation Dispatchable\n// GUID:      {00000513-0000-0010-8000-00AA006D2EA4}\n// *********************************************************************//\n  _DynaCollection = interface(_Collection)\n    ['{00000513-0000-0010-8000-00AA006D2EA4}']\n    procedure Append(const Object_: IDispatch); safecall;\n    procedure Delete(Index: OleVariant); safecall;\n  end;\n\n// *********************************************************************//\n// Interface: _ADO\n// Flags:     (4544) Dual NonExtensible OleAutomation Dispatchable\n// GUID:      {00000534-0000-0010-8000-00AA006D2EA4}\n// *********************************************************************//\n  _ADO = interface(IDispatch)\n    ['{00000534-0000-0010-8000-00AA006D2EA4}']\n    function Get_Properties: Properties; safecall;\n    property Properties: Properties read Get_Properties;\n  end;\n\n// *********************************************************************//\n// Interface: Properties\n// Flags:     (4544) Dual NonExtensible OleAutomation Dispatchable\n// GUID:      {00000504-0000-0010-8000-00AA006D2EA4}\n// *********************************************************************//\n  Properties = interface(_Collection)\n    ['{00000504-0000-0010-8000-00AA006D2EA4}']\n    function Get_Item(Index: OleVariant): Property_; safecall;\n    property Item[Index: OleVariant]: Property_ read Get_Item; default;\n  end;\n\n// *********************************************************************//\n// Interface: Property_\n// Flags:     (4544) Dual NonExtensible OleAutomation Dispatchable\n// GUID:      {00000503-0000-0010-8000-00AA006D2EA4}\n// *********************************************************************//\n  Property_ = interface(IDispatch)\n    ['{00000503-0000-0010-8000-00AA006D2EA4}']\n    function Get_Value: OleVariant; safecall;\n    procedure Set_Value(pval: OleVariant); safecall;\n    function Get_Name: WideString; safecall;\n    function Get_Type_: DataTypeEnum; safecall;\n    function Get_Attributes: Integer; safecall;\n    procedure Set_Attributes(plAttributes: Integer); safecall;\n    property Value: OleVariant read Get_Value write Set_Value;\n    property Name: WideString read Get_Name;\n    property Type_: DataTypeEnum read Get_Type_;\n    property Attributes: Integer read Get_Attributes;\n  end;\n\n// *********************************************************************//\n// Interface: Error\n// Flags:     (4544) Dual NonExtensible OleAutomation Dispatchable\n// GUID:      {00000500-0000-0010-8000-00AA006D2EA4}\n// *********************************************************************//\n  Error = interface(IDispatch)\n    ['{00000500-0000-0010-8000-00AA006D2EA4}']\n    function Get_Number: Integer; safecall;\n    function Get_Source: WideString; safecall;\n    function Get_Description: WideString; safecall;\n    function Get_HelpFile: WideString; safecall;\n    function Get_HelpContext: Integer; safecall;\n    function Get_SQLState: WideString; safecall;\n    function Get_NativeError: Integer; safecall;\n    property Number: Integer read Get_Number;\n    property Source: WideString read Get_Source;\n    property Description: WideString read Get_Description;\n    property HelpFile: WideString read Get_HelpFile;\n    property HelpContext: Integer read Get_HelpContext;\n    property SQLState: WideString read Get_SQLState;\n    property NativeError: Integer read Get_NativeError;\n  end;\n\n// *********************************************************************//\n// Interface: Errors\n// Flags:     (4544) Dual NonExtensible OleAutomation Dispatchable\n// GUID:      {00000501-0000-0010-8000-00AA006D2EA4}\n// *********************************************************************//\n  Errors = interface(_Collection)\n    ['{00000501-0000-0010-8000-00AA006D2EA4}']\n    function Get_Item(Index: OleVariant): Error; safecall;\n    procedure Clear; safecall;\n    property Item[Index: OleVariant]: Error read Get_Item; default;\n  end;\n\n// *********************************************************************//\n// Interface: Command15\n// Flags:     (4560) Hidden Dual NonExtensible OleAutomation Dispatchable\n// GUID:      {00000508-0000-0010-8000-00AA006D2EA4}\n// *********************************************************************//\n  Command15 = interface(_ADO)\n    ['{00000508-0000-0010-8000-00AA006D2EA4}']\n    function Get_ActiveConnection: Connection15; safecall;\n    procedure _Set_ActiveConnection(const ppvObject: Connection15); safecall;\n    procedure Set_ActiveConnection(ppvObject: OleVariant); safecall;\n    function Get_CommandText: WideString; safecall;\n    procedure Set_CommandText(const pbstr: WideString); safecall;\n    function Get_CommandTimeout: Integer; safecall;\n    procedure Set_CommandTimeout(pl: Integer); safecall;\n    function Get_Prepared: WordBool; safecall;\n    procedure Set_Prepared(pfPrepared: WordBool); safecall;\n    function Execute(out RecordsAffected: OleVariant; const Parameters: OleVariant; Options: Integer): Recordset15; safecall;\n    function CreateParameter(const Name: WideString; Type_: DataTypeEnum; \n                             Direction: ParameterDirectionEnum; Size: ADO_LONGPTR; Value: OleVariant): _Parameter; safecall;\n    function Get_Parameters: Parameters; safecall;\n    procedure Set_CommandType(plCmdType: CommandTypeEnum); safecall;\n    function Get_CommandType: CommandTypeEnum; safecall;\n    function Get_Name: WideString; safecall;\n    procedure Set_Name(const pbstrName: WideString); safecall;\n    property CommandText: WideString read Get_CommandText write Set_CommandText;\n    property CommandTimeout: Integer read Get_CommandTimeout write Set_CommandTimeout;\n    property Prepared: WordBool read Get_Prepared write Set_Prepared;\n    property Parameters: Parameters read Get_Parameters;\n    property CommandType: CommandTypeEnum read Get_CommandType write Set_CommandType;\n    property Name: WideString read Get_Name write Set_Name;\n  end;\n\n// *********************************************************************//\n// Interface: Connection15\n// Flags:     (4432) Hidden Dual OleAutomation Dispatchable\n// GUID:      {00000515-0000-0010-8000-00AA006D2EA4}\n// *********************************************************************//\n  Connection15 = interface(_ADO)\n    ['{00000515-0000-0010-8000-00AA006D2EA4}']\n    function Get_ConnectionString: WideString; safecall;\n    procedure Set_ConnectionString(const pbstr: WideString); safecall;\n    function Get_CommandTimeout: Integer; safecall;\n    procedure Set_CommandTimeout(plTimeout: Integer); safecall;\n    function Get_ConnectionTimeout: Integer; safecall;\n    procedure Set_ConnectionTimeout(plTimeout: Integer); safecall;\n    function Get_Version: WideString; safecall;\n    procedure Close; safecall;\n    function Execute(const CommandText: WideString; out RecordsAffected: OleVariant; \n                     Options: Integer): Recordset15; safecall;\n    function BeginTrans: Integer; safecall;\n    procedure CommitTrans; safecall;\n    procedure RollbackTrans; safecall;\n    procedure Open(const ConnectionString: WideString; const UserID: WideString; \n                   const Password: WideString; Options: Integer); safecall;\n    function Get_Errors: Errors; safecall;\n    function Get_DefaultDatabase: WideString; safecall;\n    procedure Set_DefaultDatabase(const pbstr: WideString); safecall;\n    function Get_IsolationLevel: IsolationLevelEnum; safecall;\n    procedure Set_IsolationLevel(Level: IsolationLevelEnum); safecall;\n    function Get_Attributes: Integer; safecall;\n    procedure Set_Attributes(plAttr: Integer); safecall;\n    function Get_CursorLocation: CursorLocationEnum; safecall;\n    procedure Set_CursorLocation(plCursorLoc: CursorLocationEnum); safecall;\n    function Get_Mode: ConnectModeEnum; safecall;\n    procedure Set_Mode(plMode: ConnectModeEnum); safecall;\n    function Get_Provider: WideString; safecall;\n    procedure Set_Provider(const pbstr: WideString); safecall;\n    function Get_State: Integer; safecall;\n    function OpenSchema(Schema: SchemaEnum; Restrictions: OleVariant; SchemaID: OleVariant): Recordset15; safecall;\n    property ConnectionString: WideString read Get_ConnectionString write Set_ConnectionString;\n    property CommandTimeout: Integer read Get_CommandTimeout write Set_CommandTimeout;\n    property ConnectionTimeout: Integer read Get_ConnectionTimeout write Set_ConnectionTimeout;\n    property Version: WideString read Get_Version;\n    property Errors: Errors read Get_Errors;\n    property DefaultDatabase: WideString read Get_DefaultDatabase write Set_DefaultDatabase;\n    property IsolationLevel: IsolationLevelEnum read Get_IsolationLevel write Set_IsolationLevel;\n    property Attributes: Integer read Get_Attributes write Set_Attributes;\n    property CursorLocation: CursorLocationEnum read Get_CursorLocation write Set_CursorLocation;\n    property Mode: ConnectModeEnum read Get_Mode write Set_Mode;\n    property Provider: WideString read Get_Provider write Set_Provider;\n    property State: Integer read Get_State;\n  end;\n\n// *********************************************************************//\n// Interface: _Connection\n// Flags:     (4416) Dual OleAutomation Dispatchable\n// GUID:      {00000550-0000-0010-8000-00AA006D2EA4}\n// *********************************************************************//\n  _Connection = interface(Connection15)\n    ['{00000550-0000-0010-8000-00AA006D2EA4}']\n    procedure Cancel; safecall;\n  end;\n\n// *********************************************************************//\n// Interface: Recordset15\n// Flags:     (4560) Hidden Dual NonExtensible OleAutomation Dispatchable\n// GUID:      {0000050E-0000-0010-8000-00AA006D2EA4}\n// *********************************************************************//\n  Recordset15 = interface(_ADO)\n    ['{0000050E-0000-0010-8000-00AA006D2EA4}']\n    function Get_AbsolutePosition: PositionEnum_Param; safecall;\n    procedure Set_AbsolutePosition(pl: PositionEnum_Param); safecall;\n    procedure _Set_ActiveConnection(const pvar: IDispatch); safecall;\n    procedure Set_ActiveConnection(pvar: OleVariant); safecall;\n    function Get_ActiveConnection: OleVariant; safecall;\n    function Get_BOF: WordBool; safecall;\n    function Get_Bookmark: OleVariant; safecall;\n    procedure Set_Bookmark(pvBookmark: OleVariant); safecall;\n    function Get_CacheSize: Integer; safecall;\n    procedure Set_CacheSize(pl: Integer); safecall;\n    function Get_CursorType: CursorTypeEnum; safecall;\n    procedure Set_CursorType(plCursorType: CursorTypeEnum); safecall;\n    function Get_EOF: WordBool; safecall;\n    function Get_Fields: Fields15; safecall;\n    function Get_LockType: LockTypeEnum; safecall;\n    procedure Set_LockType(plLockType: LockTypeEnum); safecall;\n    function Get_MaxRecords: ADO_LONGPTR; safecall;\n    procedure Set_MaxRecords(plMaxRecords: ADO_LONGPTR); safecall;\n    function Get_RecordCount: ADO_LONGPTR; safecall;\n    procedure _Set_Source(const pvSource: IDispatch); safecall;\n    procedure Set_Source(const pvSource: WideString); safecall;\n    function Get_Source: OleVariant; safecall;\n    procedure AddNew(FieldList: OleVariant; Values: OleVariant); safecall;\n    procedure CancelUpdate; safecall;\n    procedure Close; safecall;\n    procedure Delete(AffectRecords: AffectEnum); safecall;\n    function GetRows(Rows: Integer; Start: OleVariant; Fields: OleVariant): OleVariant; safecall;\n    procedure Move(NumRecords: ADO_LONGPTR; Start: OleVariant); safecall;\n    procedure MoveNext; safecall;\n    procedure MovePrevious; safecall;\n    procedure MoveFirst; safecall;\n    procedure MoveLast; safecall;\n    procedure Open(Source: OleVariant; ActiveConnection: OleVariant; CursorType: CursorTypeEnum; \n                   LockType: LockTypeEnum; Options: Integer); safecall;\n    procedure Requery(Options: Integer); safecall;\n    procedure _xResync(AffectRecords: AffectEnum); safecall;\n    procedure Update(Fields: OleVariant; Values: OleVariant); safecall;\n    function Get_AbsolutePage: PositionEnum_Param; safecall;\n    procedure Set_AbsolutePage(pl: PositionEnum_Param); safecall;\n    function Get_EditMode: EditModeEnum; safecall;\n    function Get_Filter: OleVariant; safecall;\n    procedure Set_Filter(Criteria: OleVariant); safecall;\n    function Get_PageCount: ADO_LONGPTR; safecall;\n    function Get_PageSize: Integer; safecall;\n    procedure Set_PageSize(pl: Integer); safecall;\n    function Get_Sort: WideString; safecall;\n    procedure Set_Sort(const Criteria: WideString); safecall;\n    function Get_Status: Integer; safecall;\n    function Get_State: Integer; safecall;\n    function _xClone: Recordset15; safecall;\n    procedure UpdateBatch(AffectRecords: AffectEnum); safecall;\n    procedure CancelBatch(AffectRecords: AffectEnum); safecall;\n    function Get_CursorLocation: CursorLocationEnum; safecall;\n    procedure Set_CursorLocation(plCursorLoc: CursorLocationEnum); safecall;\n    function NextRecordset(out RecordsAffected: OleVariant): Recordset15; safecall;\n    function Supports(CursorOptions: CursorOptionEnum): WordBool; safecall;\n    function Get_Collect(Index: OleVariant): OleVariant; safecall;\n    procedure Set_Collect(Index: OleVariant; pvar: OleVariant); safecall;\n    function Get_MarshalOptions: MarshalOptionsEnum; safecall;\n    procedure Set_MarshalOptions(peMarshal: MarshalOptionsEnum); safecall;\n    procedure Find(const Criteria: WideString; SkipRecords: ADO_LONGPTR; \n                   SearchDirection: SearchDirectionEnum; Start: OleVariant); safecall;\n    property AbsolutePosition: PositionEnum_Param read Get_AbsolutePosition write Set_AbsolutePosition;\n    property Bof: WordBool read Get_BOF;\n    property Bookmark: OleVariant read Get_Bookmark write Set_Bookmark;\n    property CacheSize: Integer read Get_CacheSize write Set_CacheSize;\n    property CursorType: CursorTypeEnum read Get_CursorType write Set_CursorType;\n    property Eof: WordBool read Get_EOF;\n    property Fields: Fields15 read Get_Fields;\n    property LockType: LockTypeEnum read Get_LockType write Set_LockType;\n    property MaxRecords: ADO_LONGPTR read Get_MaxRecords write Set_MaxRecords;\n    property RecordCount: ADO_LONGPTR read Get_RecordCount;\n    property AbsolutePage: PositionEnum_Param read Get_AbsolutePage write Set_AbsolutePage;\n    property EditMode: EditModeEnum read Get_EditMode;\n    property Filter: OleVariant read Get_Filter write Set_Filter;\n    property PageCount: ADO_LONGPTR read Get_PageCount;\n    property PageSize: Integer read Get_PageSize write Set_PageSize;\n    property Sort: WideString read Get_Sort write Set_Sort;\n    property Status: Integer read Get_Status;\n    property State: Integer read Get_State;\n    property CursorLocation: CursorLocationEnum read Get_CursorLocation write Set_CursorLocation;\n    property Collect[Index: OleVariant]: OleVariant read Get_Collect write Set_Collect;\n    property MarshalOptions: MarshalOptionsEnum read Get_MarshalOptions write Set_MarshalOptions;\n  end;\n\n// *********************************************************************//\n// Interface: Recordset20\n// Flags:     (4560) Hidden Dual NonExtensible OleAutomation Dispatchable\n// GUID:      {0000054F-0000-0010-8000-00AA006D2EA4}\n// *********************************************************************//\n  Recordset20 = interface(Recordset15)\n    ['{0000054F-0000-0010-8000-00AA006D2EA4}']\n    procedure Cancel; safecall;\n    function Get_DataSource: IUnknown; safecall;\n    procedure _Set_DataSource(const ppunkDataSource: IUnknown); safecall;\n    procedure _xSave(const FileName: WideString; PersistFormat: PersistFormatEnum); safecall;\n    function Get_ActiveCommand: IDispatch; safecall;\n    procedure Set_StayInSync(pbStayInSync: WordBool); safecall;\n    function Get_StayInSync: WordBool; safecall;\n    function GetString(StringFormat: StringFormatEnum; NumRows: Integer; \n                       const ColumnDelimeter: WideString; const RowDelimeter: WideString; \n                       const NullExpr: WideString): WideString; safecall;\n    function Get_DataMember: WideString; safecall;\n    procedure Set_DataMember(const pbstrDataMember: WideString); safecall;\n    function CompareBookmarks(Bookmark1: OleVariant; Bookmark2: OleVariant): CompareEnum; safecall;\n    function Clone(LockType: LockTypeEnum): Recordset15; safecall;\n    procedure Resync(AffectRecords: AffectEnum; ResyncValues: ResyncEnum); safecall;\n    property DataSource: IUnknown read Get_DataSource write _Set_DataSource;\n    property ActiveCommand: IDispatch read Get_ActiveCommand;\n    property StayInSync: WordBool read Get_StayInSync write Set_StayInSync;\n    property DataMember: WideString read Get_DataMember write Set_DataMember;\n  end;\n\n// *********************************************************************//\n// Interface: Recordset21\n// Flags:     (4560) Hidden Dual NonExtensible OleAutomation Dispatchable\n// GUID:      {00000555-0000-0010-8000-00AA006D2EA4}\n// *********************************************************************//\n  Recordset21 = interface(Recordset20)\n    ['{00000555-0000-0010-8000-00AA006D2EA4}']\n    procedure Seek(KeyValues: OleVariant; SeekOption: SeekEnum); safecall;\n    procedure Set_Index(const pbstrIndex: WideString); safecall;\n    function Get_Index: WideString; safecall;\n    property Index: WideString read Get_Index write Set_Index;\n  end;\n\n// *********************************************************************//\n// Interface: _Recordset\n// Flags:     (4544) Dual NonExtensible OleAutomation Dispatchable\n// GUID:      {00000556-0000-0010-8000-00AA006D2EA4}\n// *********************************************************************//\n  _Recordset = interface(Recordset21)\n    ['{00000556-0000-0010-8000-00AA006D2EA4}']\n    procedure Save(Destination: OleVariant; PersistFormat: PersistFormatEnum); safecall;\n  end;\n\n// *********************************************************************//\n// Interface: Fields15\n// Flags:     (4560) Hidden Dual NonExtensible OleAutomation Dispatchable\n// GUID:      {00000506-0000-0010-8000-00AA006D2EA4}\n// *********************************************************************//\n  Fields15 = interface(_Collection)\n    ['{00000506-0000-0010-8000-00AA006D2EA4}']\n    function Get_Item(Index: OleVariant): Field20; safecall;\n    property Item[Index: OleVariant]: Field20 read Get_Item; default;\n  end;\n\n// *********************************************************************//\n// Interface: Fields20\n// Flags:     (4560) Hidden Dual NonExtensible OleAutomation Dispatchable\n// GUID:      {0000054D-0000-0010-8000-00AA006D2EA4}\n// *********************************************************************//\n  Fields20 = interface(Fields15)\n    ['{0000054D-0000-0010-8000-00AA006D2EA4}']\n    procedure _Append(const Name: WideString; Type_: DataTypeEnum; DefinedSize: ADO_LONGPTR; \n                      Attrib: FieldAttributeEnum); safecall;\n    procedure Delete(Index: OleVariant); safecall;\n  end;\n\n// *********************************************************************//\n// Interface: Fields\n// Flags:     (4544) Dual NonExtensible OleAutomation Dispatchable\n// GUID:      {00000564-0000-0010-8000-00AA006D2EA4}\n// *********************************************************************//\n  Fields = interface(Fields20)\n    ['{00000564-0000-0010-8000-00AA006D2EA4}']\n    procedure Append(const Name: WideString; Type_: DataTypeEnum; DefinedSize: ADO_LONGPTR; \n                     Attrib: FieldAttributeEnum; FieldValue: OleVariant); safecall;\n    procedure Update; safecall;\n    procedure Resync(ResyncValues: ResyncEnum); safecall;\n    procedure CancelUpdate; safecall;\n  end;\n\n// *********************************************************************//\n// Interface: Field20\n// Flags:     (4560) Hidden Dual NonExtensible OleAutomation Dispatchable\n// GUID:      {0000054C-0000-0010-8000-00AA006D2EA4}\n// *********************************************************************//\n  Field20 = interface(_ADO)\n    ['{0000054C-0000-0010-8000-00AA006D2EA4}']\n    function Get_ActualSize: ADO_LONGPTR; safecall;\n    function Get_Attributes: Integer; safecall;\n    function Get_DefinedSize: ADO_LONGPTR; safecall;\n    function Get_Name: WideString; safecall;\n    function Get_Type_: DataTypeEnum; safecall;\n    function Get_Value: OleVariant; safecall;\n    procedure Set_Value(pvar: OleVariant); safecall;\n    function Get_Precision: Byte; safecall;\n    function Get_NumericScale: Byte; safecall;\n    procedure AppendChunk(Data: OleVariant); safecall;\n    function GetChunk(Length: Integer): OleVariant; safecall;\n    function Get_OriginalValue: OleVariant; safecall;\n    function Get_UnderlyingValue: OleVariant; safecall;\n    function Get_DataFormat: IUnknown; safecall;\n    procedure _Set_DataFormat(const ppiDF: IUnknown); safecall;\n    procedure Set_Precision(pbPrecision: Byte); safecall;\n    procedure Set_NumericScale(pbNumericScale: Byte); safecall;\n    procedure Set_Type_(pDataType: DataTypeEnum); safecall;\n    procedure Set_DefinedSize(pl: ADO_LONGPTR); safecall;\n    procedure Set_Attributes(pl: Integer); safecall;\n    property ActualSize: ADO_LONGPTR read Get_ActualSize;\n    property Attributes: Integer read Get_Attributes write Set_Attributes;\n    property DefinedSize: ADO_LONGPTR read Get_DefinedSize write Set_DefinedSize;\n    property Name: WideString read Get_Name;\n    property Type_: DataTypeEnum read Get_Type_ write Set_Type_;\n    property Value: OleVariant read Get_Value write Set_Value;\n    property Precision: Byte read Get_Precision write Set_Precision;\n    property NumericScale: Byte read Get_NumericScale write Set_NumericScale;\n    property OriginalValue: OleVariant read Get_OriginalValue;\n    property UnderlyingValue: OleVariant read Get_UnderlyingValue;\n    property DataFormat: IUnknown read Get_DataFormat write _Set_DataFormat;\n  end;\n\n// *********************************************************************//\n// Interface: Field\n// Flags:     (4544) Dual NonExtensible OleAutomation Dispatchable\n// GUID:      {00000569-0000-0010-8000-00AA006D2EA4}\n// *********************************************************************//\n  Field = interface(Field20)\n    ['{00000569-0000-0010-8000-00AA006D2EA4}']\n    function Get_Status: Integer; safecall;\n    property Status: Integer read Get_Status;\n  end;\n\n// *********************************************************************//\n// Interface: _Parameter\n// Flags:     (4544) Dual NonExtensible OleAutomation Dispatchable\n// GUID:      {0000050C-0000-0010-8000-00AA006D2EA4}\n// *********************************************************************//\n  _Parameter = interface(_ADO)\n    ['{0000050C-0000-0010-8000-00AA006D2EA4}']\n    function Get_Name: WideString; safecall;\n    procedure Set_Name(const pbstr: WideString); safecall;\n    function Get_Value: OleVariant; safecall;\n    procedure Set_Value(pvar: OleVariant); safecall;\n    function Get_Type_: DataTypeEnum; safecall;\n    procedure Set_Type_(psDataType: DataTypeEnum); safecall;\n    procedure Set_Direction(plParmDirection: ParameterDirectionEnum); safecall;\n    function Get_Direction: ParameterDirectionEnum; safecall;\n    procedure Set_Precision(pbPrecision: Byte); safecall;\n    function Get_Precision: Byte; safecall;\n    procedure Set_NumericScale(pbScale: Byte); safecall;\n    function Get_NumericScale: Byte; safecall;\n    procedure Set_Size(pl: ADO_LONGPTR); safecall;\n    function Get_Size: ADO_LONGPTR; safecall;\n    procedure AppendChunk(Val: OleVariant); safecall;\n    function Get_Attributes: Integer; safecall;\n    procedure Set_Attributes(plParmAttribs: Integer); safecall;\n    property Name: WideString read Get_Name write Set_Name;\n    property Value: OleVariant read Get_Value write Set_Value;\n    property Type_: DataTypeEnum read Get_Type_ write Set_Type_;\n    property Direction: ParameterDirectionEnum read Get_Direction write Set_Direction;\n    property Precision: Byte read Get_Precision write Set_Precision;\n    property NumericScale: Byte read Get_NumericScale write Set_NumericScale;\n    property Size: ADO_LONGPTR read Get_Size write Set_Size;\n    property Attributes: Integer read Get_Attributes write Set_Attributes;\n  end;\n\n// *********************************************************************//\n// Interface: Parameters\n// Flags:     (4544) Dual NonExtensible OleAutomation Dispatchable\n// GUID:      {0000050D-0000-0010-8000-00AA006D2EA4}\n// *********************************************************************//\n  Parameters = interface(_DynaCollection)\n    ['{0000050D-0000-0010-8000-00AA006D2EA4}']\n    function Get_Item(Index: OleVariant): _Parameter; safecall;\n    property Item[Index: OleVariant]: _Parameter read Get_Item; default;\n  end;\n\n// *********************************************************************//\n// Interface: Command25\n// Flags:     (4560) Hidden Dual NonExtensible OleAutomation Dispatchable\n// GUID:      {0000054E-0000-0010-8000-00AA006D2EA4}\n// *********************************************************************//\n  Command25 = interface(Command15)\n    ['{0000054E-0000-0010-8000-00AA006D2EA4}']\n    function Get_State: Integer; safecall;\n    procedure Cancel; safecall;\n    property State: Integer read Get_State;\n  end;\n\n// *********************************************************************//\n// Interface: _Command\n// Flags:     (4544) Dual NonExtensible OleAutomation Dispatchable\n// GUID:      {B08400BD-F9D1-4D02-B856-71D5DBA123E9}\n// *********************************************************************//\n  _Command = interface(Command25)\n    ['{B08400BD-F9D1-4D02-B856-71D5DBA123E9}']\n    procedure _Set_CommandStream(const pvStream: IUnknown); safecall;\n    function Get_CommandStream: OleVariant; safecall;\n    procedure Set_Dialect(const pbstrDialect: WideString); safecall;\n    function Get_Dialect: WideString; safecall;\n    procedure Set_NamedParameters(pfNamedParameters: WordBool); safecall;\n    function Get_NamedParameters: WordBool; safecall;\n    property Dialect: WideString read Get_Dialect write Set_Dialect;\n    property NamedParameters: WordBool read Get_NamedParameters write Set_NamedParameters;\n  end;\n\n// *********************************************************************//\n// Interface: ConnectionEventsVt\n// Flags:     (16) Hidden\n// GUID:      {00000402-0000-0010-8000-00AA006D2EA4}\n// *********************************************************************//\n  ConnectionEventsVt = interface(IUnknown)\n    ['{00000402-0000-0010-8000-00AA006D2EA4}']\n    function InfoMessage(const pError: Error; var adStatus: EventStatusEnum; \n                         const pConnection: Connection15): HResult; stdcall;\n    function BeginTransComplete(TransactionLevel: Integer; const pError: Error; \n                                var adStatus: EventStatusEnum; const pConnection: Connection15): HResult; stdcall;\n    function CommitTransComplete(const pError: Error; var adStatus: EventStatusEnum; \n                                 const pConnection: Connection15): HResult; stdcall;\n    function RollbackTransComplete(const pError: Error; var adStatus: EventStatusEnum; \n                                   const pConnection: Connection15): HResult; stdcall;\n    function WillExecute(var Source: WideString; var CursorType: CursorTypeEnum; \n                         var LockType: LockTypeEnum; var Options: Integer; \n                         var adStatus: EventStatusEnum; const pCommand: _Command; \n                         const pRecordset: Recordset15; const pConnection: Connection15): HResult; stdcall;\n    function ExecuteComplete(RecordsAffected: Integer; const pError: Error; \n                             var adStatus: EventStatusEnum; const pCommand: _Command; \n                             const pRecordset: Recordset15; const pConnection: Connection15): HResult; stdcall;\n    function WillConnect(var ConnectionString: WideString; var UserID: WideString; \n                         var Password: WideString; var Options: Integer; \n                         var adStatus: EventStatusEnum; const pConnection: Connection15): HResult; stdcall;\n    function ConnectComplete(const pError: Error; var adStatus: EventStatusEnum; \n                             const pConnection: Connection15): HResult; stdcall;\n    function Disconnect(var adStatus: EventStatusEnum; const pConnection: Connection15): HResult; stdcall;\n  end;\n\n// *********************************************************************//\n// Interface: RecordsetEventsVt\n// Flags:     (16) Hidden\n// GUID:      {00000403-0000-0010-8000-00AA006D2EA4}\n// *********************************************************************//\n  RecordsetEventsVt = interface(IUnknown)\n    ['{00000403-0000-0010-8000-00AA006D2EA4}']\n    function WillChangeField(cFields: Integer; Fields: OleVariant; var adStatus: EventStatusEnum; \n                             const pRecordset: Recordset15): HResult; stdcall;\n    function FieldChangeComplete(cFields: Integer; Fields: OleVariant; const pError: Error; \n                                 var adStatus: EventStatusEnum; const pRecordset: Recordset15): HResult; stdcall;\n    function WillChangeRecord(adReason: EventReasonEnum; cRecords: Integer; \n                              var adStatus: EventStatusEnum; const pRecordset: Recordset15): HResult; stdcall;\n    function RecordChangeComplete(adReason: EventReasonEnum; cRecords: Integer; \n                                  const pError: Error; var adStatus: EventStatusEnum; \n                                  const pRecordset: Recordset15): HResult; stdcall;\n    function WillChangeRecordset(adReason: EventReasonEnum; var adStatus: EventStatusEnum; \n                                 const pRecordset: Recordset15): HResult; stdcall;\n    function RecordsetChangeComplete(adReason: EventReasonEnum; const pError: Error; \n                                     var adStatus: EventStatusEnum; const pRecordset: Recordset15): HResult; stdcall;\n    function WillMove(adReason: EventReasonEnum; var adStatus: EventStatusEnum; \n                      const pRecordset: Recordset15): HResult; stdcall;\n    function MoveComplete(adReason: EventReasonEnum; const pError: Error; \n                          var adStatus: EventStatusEnum; const pRecordset: Recordset15): HResult; stdcall;\n    function EndOfRecordset(var fMoreData: WordBool; var adStatus: EventStatusEnum; \n                            const pRecordset: Recordset15): HResult; stdcall;\n    function FetchProgress(Progress: Integer; MaxProgress: Integer; var adStatus: EventStatusEnum; \n                           const pRecordset: Recordset15): HResult; stdcall;\n    function FetchComplete(const pError: Error; var adStatus: EventStatusEnum; \n                           const pRecordset: Recordset15): HResult; stdcall;\n  end;\n\n// *********************************************************************//\n// Interface: ADOConnectionConstruction15\n// Flags:     (512) Restricted\n// GUID:      {00000516-0000-0010-8000-00AA006D2EA4}\n// *********************************************************************//\n  ADOConnectionConstruction15 = interface(IUnknown)\n    ['{00000516-0000-0010-8000-00AA006D2EA4}']\n    function Get_DSO(out ppDSO: IUnknown): HResult; stdcall;\n    function Get_Session(out ppSession: IUnknown): HResult; stdcall;\n    function WrapDSOandSession(const pDSO: IUnknown; const pSession: IUnknown): HResult; stdcall;\n  end;\n\n// *********************************************************************//\n// Interface: ADOConnectionConstruction\n// Flags:     (512) Restricted\n// GUID:      {00000551-0000-0010-8000-00AA006D2EA4}\n// *********************************************************************//\n  ADOConnectionConstruction = interface(ADOConnectionConstruction15)\n    ['{00000551-0000-0010-8000-00AA006D2EA4}']\n  end;\n\n// *********************************************************************//\n// Interface: _Record\n// Flags:     (4432) Hidden Dual OleAutomation Dispatchable\n// GUID:      {00000562-0000-0010-8000-00AA006D2EA4}\n// *********************************************************************//\n  _Record = interface(_ADO)\n    ['{00000562-0000-0010-8000-00AA006D2EA4}']\n    function Get_ActiveConnection: OleVariant; safecall;\n    procedure Set_ActiveConnection(const pvar: WideString); safecall;\n    procedure _Set_ActiveConnection(const pvar: Connection15); safecall;\n    function Get_State: ObjectStateEnum; safecall;\n    function Get_Source: OleVariant; safecall;\n    procedure Set_Source(const pvar: WideString); safecall;\n    procedure _Set_Source(const pvar: IDispatch); safecall;\n    function Get_Mode: ConnectModeEnum; safecall;\n    procedure Set_Mode(pMode: ConnectModeEnum); safecall;\n    function Get_ParentURL: WideString; safecall;\n    function MoveRecord(const Source: WideString; const Destination: WideString; \n                        const UserName: WideString; const Password: WideString; \n                        Options: MoveRecordOptionsEnum; Async: WordBool): WideString; safecall;\n    function CopyRecord(const Source: WideString; const Destination: WideString; \n                        const UserName: WideString; const Password: WideString; \n                        Options: CopyRecordOptionsEnum; Async: WordBool): WideString; safecall;\n    procedure DeleteRecord(const Source: WideString; Async: WordBool); safecall;\n    procedure Open(Source: OleVariant; ActiveConnection: OleVariant; Mode: ConnectModeEnum; \n                   CreateOptions: RecordCreateOptionsEnum; Options: RecordOpenOptionsEnum; \n                   const UserName: WideString; const Password: WideString); safecall;\n    procedure Close; safecall;\n    function Get_Fields: Fields15; safecall;\n    function Get_RecordType: RecordTypeEnum; safecall;\n    function GetChildren: Recordset15; safecall;\n    procedure Cancel; safecall;\n    property State: ObjectStateEnum read Get_State;\n    property Mode: ConnectModeEnum read Get_Mode write Set_Mode;\n    property ParentURL: WideString read Get_ParentURL;\n    property Fields: Fields15 read Get_Fields;\n    property RecordType: RecordTypeEnum read Get_RecordType;\n  end;\n\n// *********************************************************************//\n// Interface: _Stream\n// Flags:     (4432) Hidden Dual OleAutomation Dispatchable\n// GUID:      {00000565-0000-0010-8000-00AA006D2EA4}\n// *********************************************************************//\n  _Stream = interface(IDispatch)\n    ['{00000565-0000-0010-8000-00AA006D2EA4}']\n    function Get_Size: ADO_LONGPTR; safecall;\n    function Get_EOS: WordBool; safecall;\n    function Get_Position: ADO_LONGPTR; safecall;\n    procedure Set_Position(pPos: ADO_LONGPTR); safecall;\n    function Get_Type_: StreamTypeEnum; safecall;\n    procedure Set_Type_(ptype: StreamTypeEnum); safecall;\n    function Get_LineSeparator: LineSeparatorEnum; safecall;\n    procedure Set_LineSeparator(pLS: LineSeparatorEnum); safecall;\n    function Get_State: ObjectStateEnum; safecall;\n    function Get_Mode: ConnectModeEnum; safecall;\n    procedure Set_Mode(pMode: ConnectModeEnum); safecall;\n    function Get_Charset: WideString; safecall;\n    procedure Set_Charset(const pbstrCharset: WideString); safecall;\n    function Read(NumBytes: Integer): OleVariant; safecall;\n    procedure Open(Source: OleVariant; Mode: ConnectModeEnum; Options: StreamOpenOptionsEnum; \n                   const UserName: WideString; const Password: WideString); safecall;\n    procedure Close; safecall;\n    procedure SkipLine; safecall;\n    procedure Write(Buffer: OleVariant); safecall;\n    procedure SetEOS; safecall;\n    procedure CopyTo(const DestStream: _Stream; CharNumber: ADO_LONGPTR); safecall;\n    procedure Flush; safecall;\n    procedure SaveToFile(const FileName: WideString; Options: SaveOptionsEnum); safecall;\n    procedure LoadFromFile(const FileName: WideString); safecall;\n    function ReadText(NumChars: Integer): WideString; safecall;\n    procedure WriteText(const Data: WideString; Options: StreamWriteEnum); safecall;\n    procedure Cancel; safecall;\n    property Size: ADO_LONGPTR read Get_Size;\n    property EOS: WordBool read Get_EOS;\n    property Position: ADO_LONGPTR read Get_Position write Set_Position;\n    property Type_: StreamTypeEnum read Get_Type_ write Set_Type_;\n    property LineSeparator: LineSeparatorEnum read Get_LineSeparator write Set_LineSeparator;\n    property State: ObjectStateEnum read Get_State;\n    property Mode: ConnectModeEnum read Get_Mode write Set_Mode;\n    property Charset: WideString read Get_Charset write Set_Charset;\n  end;\n\n// *********************************************************************//\n// Interface: ADORecordConstruction\n// Flags:     (4608) Restricted Dispatchable\n// GUID:      {00000567-0000-0010-8000-00AA006D2EA4}\n// *********************************************************************//\n  ADORecordConstruction = interface(IDispatch)\n    ['{00000567-0000-0010-8000-00AA006D2EA4}']\n    function Get_Row(out ppRow: IUnknown): HResult; stdcall;\n    function Set_Row(const ppRow: IUnknown): HResult; stdcall;\n    function Set_ParentRow(const Param1: IUnknown): HResult; stdcall;\n  end;\n\n// *********************************************************************//\n// Interface: ADOStreamConstruction\n// Flags:     (4608) Restricted Dispatchable\n// GUID:      {00000568-0000-0010-8000-00AA006D2EA4}\n// *********************************************************************//\n  ADOStreamConstruction = interface(IDispatch)\n    ['{00000568-0000-0010-8000-00AA006D2EA4}']\n    function Get_Stream(out ppStm: IUnknown): HResult; stdcall;\n    function Set_Stream(const ppStm: IUnknown): HResult; stdcall;\n  end;\n\n// *********************************************************************//\n// Interface: ADOCommandConstruction\n// Flags:     (512) Restricted\n// GUID:      {00000517-0000-0010-8000-00AA006D2EA4}\n// *********************************************************************//\n  ADOCommandConstruction = interface(IUnknown)\n    ['{00000517-0000-0010-8000-00AA006D2EA4}']\n    function Get_OLEDBCommand: IUnknown; safecall;\n    procedure Set_OLEDBCommand(const ppOLEDBCommand: IUnknown); safecall;\n    property OLEDBCommand: IUnknown read Get_OLEDBCommand write Set_OLEDBCommand;\n  end;\n\n// *********************************************************************//\n// Interface: ADORecordsetConstruction\n// Flags:     (4608) Restricted Dispatchable\n// GUID:      {00000283-0000-0010-8000-00AA006D2EA4}\n// *********************************************************************//\n  ADORecordsetConstruction = interface(IDispatch)\n    ['{00000283-0000-0010-8000-00AA006D2EA4}']\n    function Get_Rowset(out ppRowset: IUnknown): HResult; stdcall;\n    function Set_Rowset(const ppRowset: IUnknown): HResult; stdcall;\n    function Get_Chapter(out plChapter: ADO_LONGPTR): HResult; stdcall;\n    function Set_Chapter(plChapter: ADO_LONGPTR): HResult; stdcall;\n    function Get_RowPosition(out ppRowPos: IUnknown): HResult; stdcall;\n    function Set_RowPosition(const ppRowPos: IUnknown): HResult; stdcall;\n  end;\n\n// *********************************************************************//\n// Interface: Field15\n// Flags:     (4560) Hidden Dual NonExtensible OleAutomation Dispatchable\n// GUID:      {00000505-0000-0010-8000-00AA006D2EA4}\n// *********************************************************************//\n  Field15 = interface(_ADO)\n    ['{00000505-0000-0010-8000-00AA006D2EA4}']\n    function Get_ActualSize: ADO_LONGPTR; safecall;\n    function Get_Attributes: Integer; safecall;\n    function Get_DefinedSize: ADO_LONGPTR; safecall;\n    function Get_Name: WideString; safecall;\n    function Get_Type_: DataTypeEnum; safecall;\n    function Get_Value: OleVariant; safecall;\n    procedure Set_Value(pvar: OleVariant); safecall;\n    function Get_Precision: Byte; safecall;\n    function Get_NumericScale: Byte; safecall;\n    procedure AppendChunk(Data: OleVariant); safecall;\n    function GetChunk(Length: Integer): OleVariant; safecall;\n    function Get_OriginalValue: OleVariant; safecall;\n    function Get_UnderlyingValue: OleVariant; safecall;\n    property ActualSize: ADO_LONGPTR read Get_ActualSize;\n    property Attributes: Integer read Get_Attributes;\n    property DefinedSize: ADO_LONGPTR read Get_DefinedSize;\n    property Name: WideString read Get_Name;\n    property Type_: DataTypeEnum read Get_Type_;\n    property Value: OleVariant read Get_Value write Set_Value;\n    property Precision: Byte read Get_Precision;\n    property NumericScale: Byte read Get_NumericScale;\n    property OriginalValue: OleVariant read Get_OriginalValue;\n    property UnderlyingValue: OleVariant read Get_UnderlyingValue;\n  end;\n\n// *********************************************************************//\n// Declaration of CoClasses defined in Type Library\n// (NOTE: Here we map each CoClass to its Default Interface)\n// *********************************************************************//\n  Connection = Connection15;\n  Record_ = _Record;\n  Stream = _Stream;\n  Command = _Command;\n  Recordset = Recordset15;\n  Parameter = _Parameter;\n\n// *********************************************************************//\n// The Class CoConnection provides a Create and CreateRemote method to          \n// create instances of the default interface Connection15 exposed by              \n// the CoClass Connection. The functions are intended to be used by             \n// clients wishing to automate the CoClass objects exposed by the         \n// server of this typelibrary.                                            \n// *********************************************************************//\n  CoConnection = class\n    class function Create: Connection15;\n    class function CreateRemote(const MachineName: string): Connection15;\n  end;\n\n// *********************************************************************//\n// The Class CoRecord_ provides a Create and CreateRemote method to          \n// create instances of the default interface _Record exposed by              \n// the CoClass Record_. The functions are intended to be used by             \n// clients wishing to automate the CoClass objects exposed by the         \n// server of this typelibrary.                                            \n// *********************************************************************//\n  CoRecord_ = class\n    class function Create: _Record;\n    class function CreateRemote(const MachineName: string): _Record;\n  end;\n\n// *********************************************************************//\n// The Class CoStream provides a Create and CreateRemote method to          \n// create instances of the default interface _Stream exposed by              \n// the CoClass Stream. The functions are intended to be used by             \n// clients wishing to automate the CoClass objects exposed by the         \n// server of this typelibrary.                                            \n// *********************************************************************//\n  CoStream = class\n    class function Create: _Stream;\n    class function CreateRemote(const MachineName: string): _Stream;\n  end;\n\n// *********************************************************************//\n// The Class CoCommand provides a Create and CreateRemote method to          \n// create instances of the default interface _Command exposed by              \n// the CoClass Command. The functions are intended to be used by             \n// clients wishing to automate the CoClass objects exposed by the         \n// server of this typelibrary.                                            \n// *********************************************************************//\n  CoCommand = class\n    class function Create: _Command;\n    class function CreateRemote(const MachineName: string): _Command;\n  end;\n\n// *********************************************************************//\n// The Class CoRecordset provides a Create and CreateRemote method to          \n// create instances of the default interface Recordset15 exposed by              \n// the CoClass Recordset. The functions are intended to be used by             \n// clients wishing to automate the CoClass objects exposed by the         \n// server of this typelibrary.                                            \n// *********************************************************************//\n  CoRecordset = class\n    class function Create: Recordset15;\n    class function CreateRemote(const MachineName: string): Recordset15;\n  end;\n\n// *********************************************************************//\n// The Class CoParameter provides a Create and CreateRemote method to          \n// create instances of the default interface _Parameter exposed by              \n// the CoClass Parameter. The functions are intended to be used by             \n// clients wishing to automate the CoClass objects exposed by the         \n// server of this typelibrary.                                            \n// *********************************************************************//\n  CoParameter = class\n    class function Create: _Parameter;\n    class function CreateRemote(const MachineName: string): _Parameter;\n  end;\n\nimplementation\n\nuses ComObj;\n\nclass function CoConnection.Create: Connection15;\nbegin\n  try\n    Result := CreateComObject(CLASS_Connection) as Connection15;\n  except\n    CoInitialize(nil);\n    Result := CreateComObject(CLASS_Connection) as Connection15;\n  end;\nend;\n\nclass function CoConnection.CreateRemote(const MachineName: string): Connection15;\nbegin\n  Result := CreateRemoteComObject(MachineName, CLASS_Connection) as Connection15;\nend;\n\nclass function CoRecord_.Create: _Record;\nbegin\n  Result := CreateComObject(CLASS_Record_) as _Record;\nend;\n\nclass function CoRecord_.CreateRemote(const MachineName: string): _Record;\nbegin\n  Result := CreateRemoteComObject(MachineName, CLASS_Record_) as _Record;\nend;\n\nclass function CoStream.Create: _Stream;\nbegin\n  Result := CreateComObject(CLASS_Stream) as _Stream;\nend;\n\nclass function CoStream.CreateRemote(const MachineName: string): _Stream;\nbegin\n  Result := CreateRemoteComObject(MachineName, CLASS_Stream) as _Stream;\nend;\n\nclass function CoCommand.Create: _Command;\nbegin\n  Result := CreateComObject(CLASS_Command) as _Command;\nend;\n\nclass function CoCommand.CreateRemote(const MachineName: string): _Command;\nbegin\n  Result := CreateRemoteComObject(MachineName, CLASS_Command) as _Command;\nend;\n\nclass function CoRecordset.Create: Recordset15;\nbegin\n  Result := CreateComObject(CLASS_Recordset) as Recordset15;\nend;\n\nclass function CoRecordset.CreateRemote(const MachineName: string): Recordset15;\nbegin\n  Result := CreateRemoteComObject(MachineName, CLASS_Recordset) as Recordset15;\nend;\n\nclass function CoParameter.Create: _Parameter;\nbegin\n  Result := CreateComObject(CLASS_Parameter) as _Parameter;\nend;\n\nclass function CoParameter.CreateRemote(const MachineName: string): _Parameter;\nbegin\n  Result := CreateRemoteComObject(MachineName, CLASS_Parameter) as _Parameter;\nend;\n\nend.\n\n"
  },
  {
    "path": "lib/zeosdbo/src/plain/ZPlainAdoDriver.pas",
    "content": "{*********************************************************}\n{                                                         }\n{                 Zeos Database Objects                   }\n{         Delphi plain driver interface to ADO            }\n{                                                         }\n{        Originally written by Janos Fegyverneki          }\n{                                                         }\n{*********************************************************}\n\n{@********************************************************}\n{    Copyright (c) 1999-2012 Zeos Development Group       }\n{                                                         }\n{ License Agreement:                                      }\n{                                                         }\n{ This library is distributed in the hope that it will be }\n{ useful, but WITHOUT ANY WARRANTY; without even the      }\n{ implied warranty of MERCHANTABILITY or FITNESS FOR      }\n{ A PARTICULAR PURPOSE.  See the GNU Lesser General       }\n{ Public License for more details.                        }\n{                                                         }\n{ The source code of the ZEOS Libraries and packages are  }\n{ distributed under the Library GNU General Public        }\n{ License (see the file COPYING / COPYING.ZEOS)           }\n{ with the following  modification:                       }\n{ As a special exception, the copyright holders of this   }\n{ library give you permission to link this library with   }\n{ independent modules to produce an executable,           }\n{ regardless of the license terms of these independent    }\n{ modules, and to copy and distribute the resulting       }\n{ executable under terms of your choice, provided that    }\n{ you also meet, for each linked independent module,      }\n{ the terms and conditions of the license of that module. }\n{ An independent module is a module which is not derived  }\n{ from or based on this library. If you modify this       }\n{ library, you may extend this exception to your version  }\n{ of the library, but you are not obligated to do so.     }\n{ If you do not wish to do so, delete this exception      }\n{ statement from your version.                            }\n{                                                         }\n{                                                         }\n{ The project web site is located on:                     }\n{   http://zeos.firmos.at  (FORUM)                        }\n{   http://sourceforge.net/p/zeoslib/tickets/ (BUGTRACKER)}\n{   svn://svn.code.sf.net/p/zeoslib/code-0/trunk (SVN)    }\n{                                                         }\n{   http://www.sourceforge.net/projects/zeoslib.          }\n{                                                         }\n{                                                         }\n{                                 Zeos Development Group. }\n{********************************************************@}\n\nunit ZPlainAdoDriver;\n\ninterface\n\n{$I ZPlain.inc}\n\nuses ZClasses, ZPlainDriver;\n\ntype\n  TZAdoPlainDriver = class (TZAbstractPlainDriver, IZPlainDriver)\n  protected\n    function IsAnsiDriver: Boolean; override;\n  public\n    constructor Create;\n\n    procedure LoadCodePages; override;\n    function GetProtocol: string; override;\n    function GetDescription: string; override;\n    procedure Initialize(const Location: String = ''); override;\n    function Clone: IZPlainDriver; override;\n  end;\n\nimplementation\n\nuses ZCompatibility, ZEncoding;\n\nprocedure TZAdoPlainDriver.LoadCodePages;\nbegin\n  AddCodePage('CP_ADO', 0, ceAnsi, ZDefaultSystemCodePage,'',1, False);\nend;\n\nfunction TZAdoPlainDriver.IsAnsiDriver: Boolean;\nbegin\n  Result := False;\nend;\n\nconstructor TZAdoPlainDriver.Create;\nbegin\n  LoadCodePages;\nend;\n\nfunction TZAdoPlainDriver.GetProtocol: string;\nbegin\n  Result := 'ado';\nend;\n\nfunction TZAdoPlainDriver.GetDescription: string;\nbegin\n  Result := 'Native driver for Microsoft ADO';\nend;\n\nprocedure TZAdoPlainDriver.Initialize(const Location: String = '');\nbegin\nend;\n\nfunction TZAdoPlainDriver.Clone: IZPlainDriver;\nbegin\n  Result := Self;\nend;\n\nend.\n\n"
  },
  {
    "path": "lib/zeosdbo/src/plain/ZPlainDbLibConstants.pas",
    "content": "{*********************************************************}\n{                                                         }\n{                 Zeos Database Objects                   }\n{      Delphi plain driver interface to DBLibrary         }\n{                                                         }\n{        Originally written by Janos Fegyverneki          }\n{         FreeTDS supportd by Bogdan Dragulin             }\n{                                                         }\n{*********************************************************}\n\n{@********************************************************}\n{    Copyright (c) 1999-2012 Zeos Development Group       }\n{                                                         }\n{ License Agreement:                                      }\n{                                                         }\n{ This library is distributed in the hope that it will be }\n{ useful, but WITHOUT ANY WARRANTY; without even the      }\n{ implied warranty of MERCHANTABILITY or FITNESS FOR      }\n{ A PARTICULAR PURPOSE.  See the GNU Lesser General       }\n{ Public License for more details.                        }\n{                                                         }\n{ The source code of the ZEOS Libraries and packages are  }\n{ distributed under the Library GNU General Public        }\n{ License (see the file COPYING / COPYING.ZEOS)           }\n{ with the following  modification:                       }\n{ As a special exception, the copyright holders of this   }\n{ library give you permission to link this library with   }\n{ independent modules to produce an executable,           }\n{ regardless of the license terms of these independent    }\n{ modules, and to copy and distribute the resulting       }\n{ executable under terms of your choice, provided that    }\n{ you also meet, for each linked independent module,      }\n{ the terms and conditions of the license of that module. }\n{ An independent module is a module which is not derived  }\n{ from or based on this library. If you modify this       }\n{ library, you may extend this exception to your version  }\n{ of the library, but you are not obligated to do so.     }\n{ If you do not wish to do so, delete this exception      }\n{ statement from your version.                            }\n{                                                         }\n{                                                         }\n{ The project web site is located on:                     }\n{   http://zeos.firmos.at  (FORUM)                        }\n{   http://sourceforge.net/p/zeoslib/tickets/ (BUGTRACKER)}\n{   svn://svn.code.sf.net/p/zeoslib/code-0/trunk (SVN)    }\n{                                                         }\n{   http://www.sourceforge.net/projects/zeoslib.          }\n{                                                         }\n{                                                         }\n{                                 Zeos Development Group. }\n{********************************************************@}\n\nunit ZPlainDbLibConstants;\n\ninterface\n\n{$I ZPlain.inc}\n\nuses // M.A.\n   ZCompatibility; // M.A.\n   \n{***************** Plain API Constants definition ****************}\nconst\n{ General  #define }\n  TIMEOUT_IGNORE        = Cardinal(-1);\n  TIMEOUT_INFINITE      = 0;\n  TIMEOUT_MAXIMUM       = 1200; { 20 minutes maximum timeout value }\n\n{ Used for ServerType in dbgetprocinfo }\n  SERVTYPE_UNKNOWN      = 0;\n  SERVTYPE_MICROSOFT    = 1;\n\n{ Used by dbcolinfo }\n{enum CI_TYPES }\n  CI_REGULAR            = 1;\n  CI_ALTERNATE          = 2;\n  CI_CURSOR             = 3;\n\n{ Bulk Copy Definitions (bcp) }\n  DB_IN\t                = 1;  { Transfer from client to server }\n  DB_OUT\t              = 2;  { Transfer from server to client }\n\n  BCPMAXERRS            = 1;  { bcp_control parameter }\n  BCPFIRST              = 2;  { bcp_control parameter }\n  BCPLAST               = 3;  { bcp_control parameter }\n  BCPBATCH              = 4;  { bcp_control parameter }\n  BCPKEEPNULLS          = 5;  { bcp_control parameter }\n  BCPABORT              = 6;  { bcp_control parameter }\n  BCPKEEPIDENTITY\t      = 8;  { bcp_control parameter }\n\n  BCPLABELED            = 5;  { bcp_control parameter }\n  BCPHINTS              = 6;  { bcp_control parameter }\n\n  DBCMDNONE             = 0;  { bcp_control parameter }\n  DBCMDPEND             = 1;  { bcp_control parameter }\n  DBCMDSENT             = 2;  { bcp_control parameter }\n\n  TINYBIND              = 1;\n  SMALLBIND             = 2;\n  INTBIND               = 3;\n  CHARBIND              = 4;\n  BINARYBIND            = 5;\n  BITBIND               = 6;\n  DATETIMEBIND          = 7;\n  MONEYBIND             = 8;\n  FLT8BIND              = 9;\n  STRINGBIND            = 10;\n  NTBSTRINGBIND         = 11;\n  VARYCHARBIND          = 12;\n  VARYBINBIND           = 13;\n  FLT4BIND              = 14;\n  SMALLMONEYBIND        = 15;\n  SMALLDATETIBIND       = 16;\n  DECIMALBIND           = 17;\n  NUMERICBIND           = 18;\n  SRCDECIMALBIND        = 19;\n  SRCNUMERICBIND        = 20;\n  MAXBIND               = SRCNUMERICBIND;\n\n  DBSAVE                = 1;\n  DBNOSAVE              = 0;\n\n  DBNOERR               = -1;\n  DBFAIL                = 0;\n  DBSUCCEED             = 1;\n\n  DBFINDONE             = $04;  { Definately done }\n  DBMORE                = $10;  { Maybe more commands waiting }\n  DBMORE_ROWS           = $20;  { This command returned rows }\n\n  MAXNAME               = 31;\n  DBTXTSLEN             = 8;     { Timestamp length }\n  DBTXPLEN              = 16;    { Text pointer length }\n\n{ Error code returns }\n  INT_EXIT              = 0;\n  INT_CONTINUE          = 1;\n  INT_CANCEL            = 2;\n\n  //from FreeTDS sybdb.h:\n{ DBVERSION_xxx are used with dbsetlversion() }\n  DBVERSION_100= 2; // Sybase TDS 5.0\n  DBVERSION_42 = 3; // This can be used for old Microsoft and Sybase servers\n  DBVERSION_70 = 4;\n  DBVERSION_71 = 5;\n  DBVERSION_72 = 6;\n  DBVERSION_73 = 7;\n\n{Zeos dbsetversion placeholders}\n  ZVersion_UNKNOWN           = 0;\n  ZVersion_2_0               = 1;\t{ pre 4.0 SQL Server }\n  ZVersion_3_4               = 2;\t{ Microsoft SQL Server (3.0) }\n  ZVersion_4_0               = 3;\t{ 4.0 SQL Server }\n  ZVersion_4_2               = 4;\t{ 4.2 SQL Server }\n  ZVersion_4_6               = 5;\t{ 2.0 OpenServer and 4.6 SQL Server. }\n  ZVersion_4_9_5             = 6;\t{ 4.9.5 (NCR) SQL Server }\n  ZVersion_5_0               = 7;\t{ 5.0 SQL Server }\n  ZVersion_7_0               = 8;\t{ Microsoft SQL Server 7.0 }\n  ZVersion_8_0               = 9;\t{ Microsoft SQL Server 2000 }\n  ZVersion_9_0               = 10;\t{ Microsoft SQL Server 2005 }\n  ZVersion_7_1               = 9;\t{ Microsoft SQL Server 2000 }\n  ZVersion_7_2               = 10;\t{ Microsoft SQL Server 2005 }\n  ZVersion_7_3               = 11;\t{ Microsoft SQL Server 2008 }\n\n  ZVersionMax                = 13; { known count of available versions }\n  ZVersionEmpty              = -1; { placeholder for unsuported version }\n\n{ DB-Library datatypes }\nconst\n{Zeos DBOption placeholders}\n{ a large list of options, DBTEXTSIZE is needed by sybtcl }\n  Z_PARSEONLY             = 0;\n  Z_ESTIMATE              = 1;\n  Z_SHOWPLAN              = 2;\n  Z_NOEXEC                = 3;\n  Z_ARITHIGNORE           = 4;\n  Z_NOCOUNT               = 5;\n  Z_ARITHABORT            = 6;\n  Z_TEXTLIMIT             = 7;\n  Z_BROWSE                = 8;\n  Z_OFFSET                = 9;\n  Z_STAT                  = 10;\n  Z_ERRLVL                = 11;\n  Z_CONFIRM               = 12;\n  Z_STORPROCID            = 13;\n  Z_BUFFER                = 14;\n  Z_NOAUTOFREE            = 15;\n  Z_ROWCOUNT              = 16;\n  Z_TEXTSIZE              = 17;\n  Z_NATLANG               = 18;\n  Z_DATEFORMAT            = 19;\n  Z_PRPAD                 = 20;\n  Z_PRCOLSEP              = 21;\n  Z_PRLINELEN             = 22;\n  Z_PRLINESEP             = 23;\n  Z_LFCONVERT             = 24;\n  Z_DATEFIRST             = 25;\n  Z_CHAINXACTS            = 26;\n  Z_FIPSFLAG              = 27;\n  Z_ISOLATION             = 28;\n  Z_AUTH                  = 29;\n  Z_IDENTITY              = 30;\n  Z_NOIDCOL               = 31;\n  Z_DATESHORT             = 32;\n  Z_CLIENTCURSORS         = 33;\n  Z_SETTIME               = 34;\n  Z_QUOTEDIDENT           = 35;\n  Z_NUMOPTIONS            = 36;\n  Z_PADOFF                = 37;\n  Z_PADON                 = 38;\n  Z_OFF                   = 39;\n  Z_ON                    = 40;\n  Z_NOSUCHOPTION          = 41;\n  Z_MAXOPTTEXT            = 42;\n  Z_ANSITOOEM             = 43;\n  Z_OEMTOANSI             = 44;\n\n{ loginrec manipulation Placeholders}\n  Z_SETHOST               = 0;\n  Z_SETUSER               = 1;\n  Z_SETPWD                = 2;\n  Z_SETHID                = 3;\n  Z_SETAPP                = 4;\n  Z_SETBCP                = 5;\n  Z_SETSECURE             = 6;\n  Z_SETLANG               = 7;\n  Z_SETNOSHORT            = 8;\n  Z_SETHIER               = 9;\n  Z_SETCHARSET            = 10;\n  Z_SETPACKET             = 11;\n  Z_SETENCRYPT            = 12;\n  Z_SETLABELED            = 13;\n  Z_SETDBNAME             = 14;\n  Z_SETLOGINTIME          = 15;\n  Z_SETFALLBACK           = 16;\n\n{ datatype plazeholders }\n  Z_SQLVOID               = 0;\n  Z_SQLTEXT               = 1;\n  Z_SQLVARBINARY          = 2;\n  Z_SQLINTN               = 3;\n  Z_SQLVARCHAR            = 4;\n  Z_SQLBINARY             = 5;\n  Z_SQLIMAGE              = 6;\n  Z_SQLCHAR               = 7;\n  Z_SQLINT1               = 8;\n  Z_SQLBIT                = 9;\n  Z_SQLINT2               = 10;\n  Z_SQLINT4               = 11;\n  Z_SQLMONEY              = 12;\n  Z_SQLDATETIME           = 13;\n  Z_SQLFLT8               = 14;\n  Z_SQLFLTN               = 15;\n  Z_SQLMONEYN             = 16;\n  Z_SQLDATETIMN           = 17;\n  Z_SQLFLT4               = 18;\n  Z_SQLMONEY4             = 19;\n  Z_SQLDATETIM4           = 20;\n  Z_SQLDECIMAL            = 21;\n  Z_SQLNUMERIC            = 22;\n\n{ DBLib options }\nconst\n  DBLIBDBBUFFER               = 0;\n  DBLIBDBOFFSET               = 1;\n  DBLIBDBROWCOUNT             = 2;\n  DBLIBDBSTAT                 = 3;\n  DBLIBDBTEXTLIMIT            = 4;\n  DBLIBDBTEXTSIZE             = 5;\n  DBLIBDBARITHABORT           = 6;\n  DBLIBDBARITHIGNORE          = 7;\n  DBLIBDBNOAUTOFREE           = 8;\n  DBLIBDBNOCOUNT              = 9;\n  DBLIBDBNOEXEC               = 10;\n  DBLIBDBPARSEONLY            = 11;\n  DBLIBDBSHOWPLAN             = 12;\n  DBLIBDBSTORPROCID           = 13;\n  DBLIBDBANSITOOEM\t\t        = 14;\n  DBLIBDBOEMTOANSI\t          = 15;\n  DBLIBDBCLIENTCURSORS        = 16;\n  DBLIBDBSET_TIME             = 17;\n  DBLIBDBQUOTEDIDENT          = 18;\n\n{ FreeTDS options, a large list of options, DBTEXTSIZE is needed by sybtcl }\n  TDSPARSEONLY             = 0;\n  TDSESTIMATE              = 1;\n  TDSSHOWPLAN              = 2;\n  TDSNOEXEC                = 3;\n  TDSARITHIGNORE           = 4;\n  TDSNOCOUNT               = 5;\n  TDSARITHABORT            = 6;\n  TDSTEXTLIMIT             = 7;\n  TDSBROWSE                = 8;\n  TDSOFFSET                = 9;\n  TDSSTAT                  = 10;\n  TDSERRLVL                = 11;\n  TDSCONFIRM               = 12;\n  TDSSTORPROCID            = 13;\n  TDSBUFFER                = 14;\n  TDSNOAUTOFREE            = 15;\n  TDSROWCOUNT              = 16;\n  TDSTEXTSIZE              = 17;\n  TDSNATLANG               = 18;\n  TDSDATEFORMAT            = 19;\n  TDSPRPAD                 = 20;\n  TDSPRCOLSEP              = 21;\n  TDSPRLINELEN             = 22;\n  TDSPRLINESEP             = 23;\n  TDSLFCONVERT             = 24;\n  TDSDATEFIRST             = 25;\n  TDSCHAINXACTS            = 26;\n  TDSFIPSFLAG              = 27;\n  TDSISOLATION             = 28;\n  TDSAUTH                  = 29;\n  TDSIDENTITY              = 30;\n  TDSNOIDCOL               = 31;\n  TDSDATESHORT             = 32;\n  TDSCLIENTCURSORS         = 33;\n  TDSSETTIME               = 34;\n  TDSQUOTEDIDENT           = 35;\n  TDSNUMOPTIONS             = 36;\n  TDSPADOFF                 = 0;\n  TDSPADON                  = 1;\n  TDSOFF                    = 0;\n  TDSON                     = 1;\n\n  NOSUCHOPTION              = 2;\n\n  MAXOPTTEXT                = 32;\n\n{ common Login manipulations }\n  DBSETHOST                 = 1;\n  DBSETUSER                 = 2;\n  DBSETPWD                  = 3;\n{ Sybase Login manipulations }\nconst\n  SYBDBSETHOST              = DBSETHOST;\n  SYBDBSETUSER              = DBSETUSER;\n  SYBDBSETPWD               = DBSETPWD;\n  SYBDBSETHID               = 4;\n  SYBDBSETAPP               = 5;\n  SYBDBSETBCP               = 6;\n  SYBDBSETLANG              = 7;\n  SYBDBSETNOSHORT           = 8;\n  SYBDBSETHIER              = 9;\n  SYBDBSETCHARSET           = 10;\n  SYBDBSETPACKET            = 11;\n  SYBDBSETENCRYPT           = 12;\n  SYBDBSETLABELED           = 13;\n\n{ MsSQL Login manipulations }\nconst\n  MSDBSETHOST               = DBSETHOST;\n  MSDBSETUSER               = DBSETUSER;\n  MSDBSETPWD                = DBSETPWD;\n  MSDBSETAPP                = 4;\n  MSDBSETID                 = 5;\n  MSDBSETLANG               = 6;\n\n  MSDBSETSECURE             = 7;\n  MSDBSET_LOGIN_TIME        = 10;\n  MSDBSETFALLBACK           = 12;\n\n{TDS Loginrec manipulations}\n  TDSDBSETHOST               = DBSETHOST;\n  TDSDBSETUSER               = DBSETUSER;\n  TDSDBSETPWD                = DBSETPWD;\n  TDSDBSETHID                = 4;\n  TDSDBSETAPP                = 5;\n  TDSDBSETBCP                = 6;\n  TDSDBSETSECURE             = 6;\n  TDSDBSETLANG               = 7;\n  TDSDBSETNOSHORT            = 8;\n  TDSDBSETHIER               = 9;\n  TDSDBSETCHARSET            = 10;\n  TDSDBSETPACKET             = 11;\n  TDSDBSETENCRYPT            = 12;\n  TDSDBSETLABELED            = 13;\n  TDSDBSETDBNAME             = 14;\n\n{ TDS_DBVERSION_xxx are used with dbsetversion() }\n  TDSDBVERSION_UNKNOWN  = 0;\n  TDSDBVERSION_46       = 1;\n  TDSDBVERSION_100      = 2; // Sybase TDS 5.0\n  TDSDBVERSION_42       = 3; // This can be used for old Microsoft and Sybase servers\n  TDSDBVERSION_70       = 4;\n  TDSDBVERSION_71       = 5;\n  TDSDBVERSION_80       = TDSDBVERSION_71;\n  TDSDBVERSION_72       = 6;\n  TDSDBVERSION_73       = 7;\n\n{ these two are defined by Microsoft for dbsetlversion() }\n  DBVER42 \t            = 8;\n  DBVER60 \t            = 9;\n\n(**\n * DBTDS_xxx are returned by DBTDS()\n * The integer values of the constants are poorly chosen.\n *)\n  DBTDS_UNKNOWN           = 0;\n  DBTDS_2_0               = 1;\t{ pre 4.0 SQL Server }\n  DBTDS_3_4               = 2;\t{ Microsoft SQL Server (3.0) }\n  DBTDS_4_0               = 3;\t{ 4.0 SQL Server }\n  DBTDS_4_2               = 4;\t{ 4.2 SQL Server }\n  DBTDS_4_6               = 5;\t{ 2.0 OpenServer and 4.6 SQL Server. }\n  DBTDS_4_9_5             = 6;\t{ 4.9.5 (NCR) SQL Server }\n  DBTDS_5_0               = 7;\t{ 5.0 SQL Server }\n  DBTDS_7_0               = 8;\t{ Microsoft SQL Server 7.0 }\n  DBTDS_8_0               = 9;\t{ Microsoft SQL Server 2000 }\n  DBTDS_9_0               = 10;\t{ Microsoft SQL Server 2005 }\n  DBTDS_7_1               = 9;\t{ Microsoft SQL Server 2000 }\n  DBTDS_7_2               = 10;\t{ Microsoft SQL Server 2005 }\n  DBTDS_7_3               = 11;\t{ Microsoft SQL Server 2008 }\n\n\n{ Data Type Tokens }\n  DBLIBSQLVOID               = $1f;\n  DBLIBSQLTEXT               = $23;\n  DBLIBSQLVARBINARY          = $25;\n  DBLIBSQLINTN               = $26; { all nullable integers }\n  DBLIBSQLVARCHAR            = $27;\n  DBLIBSQLBINARY             = $2d;\n  DBLIBSQLIMAGE              = $22;\n  DBLIBSQLCHAR               = $2f;\n  DBLIBSQLINT1               = $30;\n  DBLIBSQLBIT                = $32;\n  DBLIBSQLINT2               = $34;\n  DBLIBSQLINT4               = $38;\n  DBLIBSQLMONEY              = $3c;\n  DBLIBSQLDATETIME           = $3d;\n  DBLIBSQLFLT8               = $3e;\n  DBLIBSQLFLTN               = $6d;\n  DBLIBSQLMONEYN             = $6e;\n  DBLIBSQLDATETIMN           = $6f;\n  DBLIBSQLFLT4               = $3b;\n  DBLIBSQLMONEY4             = $7a;\n  DBLIBSQLDATETIM4           = $3a;\n  DBLIBSQLDECIMAL            = $6a;\n  DBLIBSQLNUMERIC            = $6c;\n\n{ Data stream tokens }\n  SQLCOLFMT             = $a1;\n  OLD_SQLCOLFMT         = $2a;\n  SQLPROCID             = $7c;\n  SQLCOLNAME            = $a0;\n  SQLTABNAME            = $a4;\n  SQLCOLINFO            = $a5;\n  SQLALTNAME            = $a7;\n  SQLALTFMT             = $a8;\n  SQLERROR              = $aa;\n  SQLINFO               = $ab;\n  SQLRETURNVALUE        = $ac;\n  SQLRETURNSTATUS       = $79;\n  SQLRETURN             = $db;\n  SQLCONTROL            = $ae;\n  SQLALTCONTROL         = $af;\n  SQLROW                = $d1;\n  SQLALTROW             = $d3;\n  SQLDONE               = $fd;\n  SQLDONEPROC           = $fe;\n  SQLDONEINPROC         = $ff;\n  SQLOFFSET             = $78;\n  SQLORDER              = $a9;\n  SQLLOGINACK           = $ad; { NOTICE: change to real value }\n\n{ Ag op tokens }\n  SQLAOPCNT\t\t= $4b;\n  SQLAOPSUM             = $4d;\n  SQLAOPAVG             = $4f;\n  SQLAOPMIN             = $51;\n  SQLAOPMAX             = $52;\n  SQLAOPANY             = $53;\n  SQLAOPNOOP            = $56;\n\n{ Error numbers (dberrs) DB-Library error codes }\n  SQLEMEM               = 10000;\n  SQLENULL              = 10001;\n  SQLENLOG              = 10002;\n  SQLEPWD               = 10003;\n  SQLECONN              = 10004;\n  SQLEDDNE              = 10005;\n  SQLENULLO             = 10006;\n  SQLESMSG              = 10007;\n  SQLEBTOK              = 10008;\n  SQLENSPE              = 10009;\n  SQLEREAD              = 10010;\n  SQLECNOR              = 10011;\n  SQLETSIT              = 10012;\n  SQLEPARM              = 10013;\n  SQLEAUTN              = 10014;\n  SQLECOFL              = 10015;\n  SQLERDCN              = 10016;\n  SQLEICN               = 10017;\n  SQLECLOS              = 10018;\n  SQLENTXT              = 10019;\n  SQLEDNTI              = 10020;\n  SQLETMTD              = 10021;\n  SQLEASEC              = 10022;\n  SQLENTLL              = 10023;\n  SQLETIME              = 10024;\n  SQLEWRIT              = 10025;\n  SQLEMODE              = 10026;\n  SQLEOOB               = 10027;\n  SQLEITIM              = 10028;\n  SQLEDBPS              = 10029;\n  SQLEIOPT              = 10030;\n  SQLEASNL              = 10031;\n  SQLEASUL              = 10032;\n  SQLENPRM              = 10033;\n  SQLEDBOP              = 10034;\n  SQLENSIP              = 10035;\n  SQLECNULL             = 10036;\n  SQLESEOF              = 10037;\n  SQLERPND              = 10038;\n  SQLECSYN              = 10039;\n  SQLENONET             = 10040;\n  SQLEBTYP              = 10041;\n  SQLEABNC              = 10042;\n  SQLEABMT              = 10043;\n  SQLEABNP              = 10044;\n  SQLEBNCR              = 10045;\n  SQLEAAMT              = 10046;\n  SQLENXID              = 10047;\n  SQLEIFNB              = 10048;\n  SQLEKBCO              = 10049;\n  SQLEBBCI              = 10050;\n  SQLEKBCI              = 10051;\n  SQLEBCWE              = 10052;\n  SQLEBCNN              = 10053;\n  SQLEBCOR              = 10054;\n  SQLEBCPI              = 10055;\n  SQLEBCPN              = 10056;\n  SQLEBCPB              = 10057;\n  SQLEVDPT              = 10058;\n  SQLEBIVI              = 10059;\n  SQLEBCBC              = 10060;\n  SQLEBCFO              = 10061;\n  SQLEBCVH              = 10062;\n  SQLEBCUO              = 10063;\n  SQLEBUOE              = 10064;\n  SQLEBWEF              = 10065;\n  SQLEBTMT              = 10066;\n  SQLEBEOF              = 10067;\n  SQLEBCSI              = 10068;\n  SQLEPNUL              = 10069;\n  SQLEBSKERR            = 10070;\n  SQLEBDIO              = 10071;\n  SQLEBCNT              = 10072;\n  SQLEMDBP              = 10073;\n  SQLINIT               = 10074;\n  SQLCRSINV             = 10075;\n  SQLCRSCMD             = 10076;\n  SQLCRSNOIND           = 10077;\n  SQLCRSDIS             = 10078;\n  SQLCRSAGR             = 10079;\n  SQLCRSORD             = 10080;\n  SQLCRSMEM             = 10081;\n  SQLCRSBSKEY           = 10082;\n  SQLCRSNORES           = 10083;\n  SQLCRSVIEW            = 10084;\n  SQLCRSBUFR            = 10085;\n  SQLCRSFROWN           = 10086;\n  SQLCRSBROL            = 10087;\n  SQLCRSFRAND           = 10088;\n  SQLCRSFLAST           = 10089;\n  SQLCRSRO              = 10090;\n  SQLCRSTAB             = 10091;\n  SQLCRSUPDTAB          = 10092;\n  SQLCRSUPDNB           = 10093;\n  SQLCRSVIIND           = 10094;\n  SQLCRSNOUPD           = 10095;\n  SQLCRSOS2             = 10096;\n  SQLEBCSA              = 10097;\n  SQLEBCRO              = 10098;\n  SQLEBCNE              = 10099;\n  SQLEBCSK              = 10100;\n  SQLEUVBF              = 10101;\n  SQLEBIHC              = 10102;\n  SQLEBWFF              = 10103;\n  SQLNUMVAL             = 10104;\n  SQLEOLDVR             = 10105;\n  SQLEBCPS\t            = 10106;\n  SQLEDTC \t            = 10107;\n  SQLENOTIMPL\t          = 10108;\n  SQLENONFLOAT\t        = 10109;\n  SQLECONNFB            = 10110;\n\n{ The severity levels are defined here }\n  EXINFO                = 1;  { Informational, non-error }\n  EXUSER                = 2;  { User error }\n  EXNONFATAL            = 3;  { Non-fatal error }\n  EXCONVERSION          = 4;  { Error in DB-LIBRARY data conversion }\n  EXSERVER              = 5;  { The Server has returned an error flag }\n  EXTIME                = 6;  { We have exceeded our timeout period while }\n                           { waiting for a response from the Server - the }\n                           { DBPROCESS is still alive }\n  EXPROGRAM             = 7;  { Coding error in user program }\n  EXRESOURCE            = 8;  { Running out of resources - the DBPROCESS may be dead }\n  EXCOMM                = 9;  { Failure in communication with Server - the DBPROCESS is dead }\n  EXFATAL               = 10; { Fatal error - the DBPROCESS is dead }\n  EXCONSISTENCY         = 11; { Internal software error  - notify MS Technical Supprt }\n\n{ Offset identifiers }\n  OFF_SELECT            = $16d;\n  OFF_FROM              = $14f;\n  OFF_ORDER             = $165;\n  OFF_COMPUTE           = $139;\n  OFF_TABLE             = $173;\n  OFF_PROCEDURE         = $16a;\n  OFF_STATEMENT         = $1cb;\n  OFF_PARAM             = $1c4;\n  OFF_EXEC              = $12c;\n\n{ Decimal constants }\n  MAXNUMERICLEN = 16;\n  MAXNUMERICDIG = 38;\n\n  DEFAULTPRECISION = 18;\n  DEFAULTSCALE     = 0;\n\n{ DB-Table constants}\n{ Pack the following structures on a word boundary }\n  TDSMAXTABLENAME  = 512;\n  TDSMAXCOLNAMELEN = 512;\n\n{ DB-Table constants}\n{ Pack the following structures on a word boundary }\n  MAXTABLENAME = 30;\n  MAXCOLNAMELEN= 30;\n\n{ DB-Library datatype definitions }\n  DBMAXCHAR=256; // Max length of DBVARBINARY and DBVARCHAR, etc.\n\n{ Print lengths for certain fixed length data types }\n  PRINT4                = 11;\n  PRINT2                = 6;\n  PRINT1                = 3;\n  PRFLT8                = 20;\n  PRMONEY               = 26;\n  PRBIT                 = 3;\n  PRDATETIME            = 27;\n  PRDECIMAL             = (MAXNUMERICDIG + 2);\n  PRNUMERIC             = (MAXNUMERICDIG + 2);\n\n  SUCCEED               = 1;\n  FAIL                  = 0;\n  SUCCEED_ABORT         = 2;\n\n  DBUNKNOWN             = 2; { FALSE = 0, TRUE = 1 }\n\n  MORE_ROWS             = -1;\n  NO_MORE_ROWS          = -2;\n  REG_ROW               = MORE_ROWS;\n  BUF_FULL              = -3; { only if buffering is turned on }\n\n{ Status code for dbresults(). Possible return values are }\n{ SUCCEED, FAIL, and NO_MORE_RESULTS. }\n  NO_MORE_RESULTS       = 2;\n  NO_MORE_RPC_RESULTS   = 3;\n\n{ Standard exit and error values }\n  STDEXIT               = 0;\n  ERREXIT               = -1;\n\n{ dbrpcinit flags }\n  DBRPCRECOMPILE        = $0001;\n  DBRPCRESET            = $0004;\n  DBRPCCURSOR           = $0008;\n\n{ dbrpcparam flags }\n  DBRPCRETURN           = $1;\n  DBRPCDEFAULT          = $2;\n\n{ Cursor related constants }\n\n{ Following flags are used in the concuropt parameter in the dbcursoropen function }\n  CUR_READONLY          = 1; { Read only cursor, no data modifications }\n  CUR_LOCKCC            = 2; { Intent to update, all fetched data locked when }\n                       { dbcursorfetch is called inside a transaction block }\n  CUR_OPTCC             = 3; { Optimistic concurrency control, data modifications }\n                       { succeed only if the row hasn't been updated since }\n                       { the last fetch. }\n  CUR_OPTCCVAL          = 4; { Optimistic concurrency control based on selected column values }\n\n{ Following flags are used in the scrollopt parameter in dbcursoropen }\n  CUR_FORWARD           = 0;   { Forward only scrolling }\n  CUR_KEYSET            = -1;  { Keyset driven scrolling }\n  CUR_DYNAMIC           = 1;   { Fully dynamic }\n  CUR_INSENSITIVE       = -2;  { Server-side cursors only }\n\n{ Following flags define the fetchtype in the dbcursorfetch function }\n  FETCH_FIRST           = 1;  { Fetch first n rows }\n  FETCH_NEXT            = 2;  { Fetch next n rows }\n  FETCH_PREV            = 3;  { Fetch previous n rows }\n  FETCH_RANDOM          = 4;  { Fetch n rows beginning with given row # }\n  FETCH_RELATIVE        = 5;  { Fetch relative to previous fetch row # }\n  FETCH_LAST            = 6;  { Fetch the last n rows }\n\n{ Following flags define the per row status as filled by dbcursorfetch and/or dbcursorfetchex }\n  FTC_EMPTY             = $00;  { No row available }\n  FTC_SUCCEED           = $01;  { Fetch succeeded, (failed if not set) }\n  FTC_MISSING           = $02;  { The row is missing }\n  FTC_ENDOFKEYSET       = $04;  { End of the keyset reached }\n  FTC_ENDOFRESULTS      = $08;  { End of results set reached }\n\n{ Following flags define the operator types for the dbcursor function }\n  CRS_UPDATE            = 1;  { Update operation }\n  CRS_DELETE            = 2;  { Delete operation }\n  CRS_INSERT            = 3;  { Insert operation }\n  CRS_REFRESH           = 4;  { Refetch given row }\n  CRS_LOCKCC            = 5;  { Lock given row }\n\n{ Following value can be passed to the dbcursorbind function for NOBIND type }\n  NOBIND                = -2; { Return length and pointer to data }\n\n{ Following are values used by DBCURSORINFO's Type parameter }\n  CU_CLIENT             = $00000001;\n  CU_SERVER             = $00000002;\n  CU_KEYSET             = $00000004;\n  CU_MIXED              = $00000008;\n  CU_DYNAMIC            = $00000010;\n  CU_FORWARD            = $00000020;\n  CU_INSENSITIVE        = $00000040;\n  CU_READONLY           = $00000080;\n  CU_LOCKCC             = $00000100;\n  CU_OPTCC              = $00000200;\n  CU_OPTCCVAL           = $00000400;\n\n{ Following are values used by DBCURSORINFO's Status parameter }\n  CU_FILLING            = $00000001;\n  CU_FILLED             = $00000002;\n\n{ Following are values used by dbupdatetext's type parameter }\n  UT_TEXTPTR            = $0001;\n  UT_TEXT               = $0002;\n  UT_MORETEXT           = $0004;\n  UT_DELETEONLY         = $0008;\n  UT_LOG                = $0010;\n\n{ The following values are passed to dbserverenum for searching criteria. }\n  NET_SEARCH            = $0001;\n  LOC_SEARCH            = $0002;\n\n{ These constants are the possible return values from dbserverenum. }\n  ENUM_SUCCESS          = $0000;\n  MORE_DATA             = $0001;\n  NET_NOT_AVAIL         = $0002;\n  OUT_OF_MEMORY         = $0004;\n  NOT_SUPPORTED         = $0008;\n  ENUM_INVALID_PARAM    = $0010;\n\n{ Netlib Error problem codes.  ConnectionError() should return one of }\n{ these as the dblib-mapped problem code, so the corresponding string }\n{ is sent to the dblib app's error handler as dberrstr.  Return NE_E_NOMAP }\n{ for a generic DB-Library error string (as in prior versions of dblib). }\n\n  NE_E_NOMAP            = 0;   { No string; uses dblib default. }\n  NE_E_NOMEMORY         = 1;   { Insufficient memory. }\n  NE_E_NOACCESS         = 2;   { Access denied. }\n  NE_E_CONNBUSY         = 3;   { Connection is busy. }\n  NE_E_CONNBROKEN       = 4;   { Connection broken. }\n  NE_E_TOOMANYCONN      = 5;   { Connection limit exceeded. }\n  NE_E_SERVERNOTFOUND   = 6;   { Specified SQL server not found. }\n  NE_E_NETNOTSTARTED    = 7;   { The network has not been started. }\n  NE_E_NORESOURCE       = 8;   { Insufficient network resources. }\n  NE_E_NETBUSY          = 9;   { Network is busy. }\n  NE_E_NONETACCESS      = 10;  { Network access denied. }\n  NE_E_GENERAL          = 11;  { General network error.  Check your documentation. }\n  NE_E_CONNMODE         = 12;  { Incorrect connection mode. }\n  NE_E_NAMENOTFOUND     = 13;  { Name not found in directory service. }\n  NE_E_INVALIDCONN      = 14;  { Invalid connection. }\n  NE_E_NETDATAERR       = 15;  { Error reading or writing network data. }\n  NE_E_TOOMANYFILES     = 16;  { Too many open file handles. }\n  NE_E_CANTCONNECT\t    = 17;  { SQL Server does not exist or access denied. }\n\n  NE_MAX_NETERROR       = 17;\n\n\nconst\n  MAXSERVERNAME = 30;\n  MAXNETLIBNAME = 255;\n  MAXNETLIBCONNSTR = 255;\n\nconst\n  INVALID_UROWNUM       = Cardinal(-1);\n\n\n{ copied from tds.h }\n//enum\n\tSYBCHAR               = 47;\t\t(* 0x2F *)\n\tSYBVARCHAR            = 39;\t  (* 0x27 *)\n\tSYBINTN               = 38;\t\t(* 0x26 *)\n\tSYBINT1               = 48;\t\t(* 0x30 *)\n\tSYBINT2               = 52;\t\t(* 0x34 *)\n\tSYBINT4               = 56;\t\t(* 0x38 *)\n\tSYBINT8               = 127;\t(* 0x7F *)\n\tSYBFLT8               = 62;\t\t(* 0x3E *)\n\tSYBDATETIME           = 61;\t  (* 0x3D *)\n\tSYBBIT                = 50;\t\t(* 0x32 *)\n\tSYBBITN               = 104;\t(* 0x68 *)\n\tSYBTEXT               = 35;\t\t(* 0x23 *)\n\tSYBNTEXT              = 99;\t\t(* 0x63 *)\n\tSYBIMAGE              = 34;\t\t(* 0x22 *)\n\tSYBMONEY4             = 122;\t(* 0x7A *)\n\tSYBMONEY              = 60;\t\t(* 0x3C *)\n\tSYBDATETIME4          = 58;   (* 0x3A *)\n\tSYBREAL               = 59;\t\t(* 0x3B *)\n\tSYBBINARY             = 45;\t\t(* 0x2D *)\n\tSYBVOID               = 31;\t\t(* 0x1F *)\n\tSYBVARBINARY          = 37;   (* 0x25 *)\n\tSYBNUMERIC            = 108;\t(* 0x6C *)\n\tSYBDECIMAL            = 106;\t(* 0x6A *)\n\tSYBFLTN               = 109;\t(* 0x6D *)\n\tSYBMONEYN             = 110;\t(* 0x6E *)\n\tSYBDATETIMN           = 111;\t(* 0x6F *)\n\tSYBNVARCHAR           = 103;\t(* 0x67 *)\n\tXSYBCHAR              = 175;\t(* 0xAF *)\n\tXSYBVARCHAR           = 167;\t(* 0xA7 *)\n\tXSYBNVARCHAR          = 231;\t(* 0xE7 *)\n\tXSYBNCHAR             = 239;\t(* 0xEF *)\n\tXSYBVARBINARY         = 165;\t(* 0xA5 *)\n\tXSYBBINARY            = 173;\t(* 0xAD *)\n\tSYBUNIQUE             = 36;\t\t(* 0x24 *)\n\tSYBVARIANT            = 98;   (* 0x62 *)\n\tSYBMSUDT              = 240;\t(* 0xF0 *)\n\tSYBMSXML              = 241;\t(* 0xF1 *)\n\n{ FreeTDS Data Type Tokens }\n  TDSSQLVOID               = SYBVOID;\n  TDSSQLTEXT               = SYBTEXT;\n  TDSSQLVARBINARY          = SYBVARBINARY;\n  TDSSQLINTN               = SYBINTN;\n  TDSSQLVARCHAR            = SYBVARCHAR;\n  TDSSQLBINARY             = SYBBINARY;\n  TDSSQLIMAGE              = SYBIMAGE;\n  TDSSQLCHAR               = SYBCHAR;\n  TDSSQLINT1               = SYBINT1;\n  TDSSQLBIT                = SYBBIT;\n  TDSSQLINT2               = SYBINT2;\n  TDSSQLINT4               = SYBINT4;\n  TDSSQLMONEY              = SYBMONEY;\n  TDSSQLDATETIME           = SYBDATETIME;\n  TDSSQLFLT8               = SYBFLT8;\n  TDSSQLFLTN               = SYBFLTN;\n  TDSSQLMONEYN             = SYBMONEYN;\n  TDSSQLDATETIMN           = SYBDATETIMN;\n  TDSSQLFLT4               = SYBREAL;\n  TDSSQLMONEY4             = SYBMONEY4;\n  TDSSQLDATETIM4           = SYBDATETIME4;\n  TDSSQLDECIMAL            = SYBDECIMAL;\n  TDSSQLNUMERIC            = SYBNUMERIC;\n\n  SYBAOPCNT             = $4b;\n  SYBAOPCNTU            = $4c;\n  SYBAOPSUM             = $4d;\n  SYBAOPSUMU            = $4e;\n  SYBAOPAVG             = $4f;\n  SYBAOPAVGU            = $50;\n  SYBAOPMIN             = $51;\n  SYBAOPMAX             = $52;\n\n{ mssql2k compute operator }\n  SYBAOPCNT_BIG\t\t      = $09;\n  SYBAOPSTDEV\t\t        = $30;\n  SYBAOPSTDEVP\t\t      = $31;\n  SYBAOPVAR\t\t          = $32;\n  SYBAOPVARP\t\t        = $33;\n  SYBAOPCHECKSUM_AGG\t  = $72;\n  {****************** Plain API Types definition *****************}\ntype\n{ DBPROCESS, LOGINREC and DBCURSOR }\n  PDBPROCESS            = Pointer;\n  PLOGINREC             = Pointer;\n  PDBCURSOR             = Pointer;\n  PDBHANDLE             = Pointer;\n  DBXLATE               = Pointer;\n  DBSORTORDER           = Pointer;\n  DBLOGINFO             = Pointer;\n  DBVOIDPTR             = PPointer;\ntype\n{ DB-Library datatypes }\n  DBBOOL                = Byte;\n  DBCHAR                = AnsiChar;\n  DBBIT                 = Byte;\n  DBTINYINT             = Byte;\n  DBSMALLINT            = SmallInt; { int16_type }\n  DBINT                 = LongInt;  { int32_type }\n  DBBIGINT              = Int64;    { int64_type }\n  DBBINARY              = Byte;\n  DBFLT4                = Single;   { real32_type }\n  DBFLT8                = Double;   { real64_type }\n\n  DBSHORT               = SmallInt;\n  DBUSMALLINT           = Word;\n  DBMONEY4              = LongInt;\n  PDBMONEY4             = ^DBMONEY4;\n\n  RETCODE               = Integer;\n  PRETCODE              = ^RETCODE;\n  STATUS                = Integer;\n\n//typedef int (*INTFUNCPTR) (void *, ...);\n//typedef int (*DBWAITFUNC) (void);\n//typedef DBWAITFUNC(*DB_DBBUSY_FUNC) (void *dbproc);\n//typedef void (*DB_DBIDLE_FUNC) (DBWAITFUNC dfunc, void *dbproc);\n//typedef int (*DB_DBCHKINTR_FUNC) (void *dbproc);\n//typedef int (*DB_DBHNDLINTR_FUNC) (void *dbproc); *)\n\n  DBREAL                = DBFLT4;\n  DBUBOOL               = Cardinal;\n\n  DBDATETIM4 = packed record\n    numdays:    Word;        { No of days since Jan-1-1900 }\n    nummins:    Word;        { No. of minutes since midnight }\n  end;\n  PDBDATETIM4 = ^DBDATETIM4;\n\n  {$IFDEF FPC}\n    {$PACKRECORDS C}\n  {$ENDIF}\ntype\n  DBNUMERIC = packed record\n    Precision:  Byte;\n    Scale:      Byte;\n    Sign:       Byte; { 1 = Positive, 0 = Negative }\n    Val:        array[0..MAXNUMERICLEN-1] of Byte;\n  end;\n  DBDECIMAL = DBNUMERIC;\n\n  TDSDBNUMERIC = packed record\n    Precision:  Byte;\n    Scale:      Byte;\n    Sign:       Byte; { 1 = Positive, 0 = Negative }\n    Val:        array[0..MAXNUMERICLEN] of Byte;\n  end;\n  TDSDBDECIMAL = TDSDBNUMERIC;\n\n  DBVARYCHAR = packed record\n    Len: DBSMALLINT;\n    Str: array[0..DBMAXCHAR-1] of DBCHAR;\n  end;\n\n  DBVARYBIN = packed record\n    Len: DBSMALLINT;\n    Bytes: array[0..DBMAXCHAR-1] of Byte;\n  end;\n\n  DBMONEY = packed record\n    mnyhigh:    DBINT;\n    mnylow:     LongWord;\n  end;\n  PDBMONEY = ^DBMONEY;\n\n  PDBDATETIME = ^DBDATETIME;\n  DBDATETIME = packed record\n    dtdays:\tDBINT;          // Days since Jan 1, 1900\n    dttime:\tLongWord;       // 300ths of a second since midnight, 25920000 unit is 1 day\n  end;\n\n  PTDSDBDATETIME = ^TTDSDBDATETIME;\n  TTDSDBDATETIME = packed record\n    dtdays:\tDBINT;          // Days since Jan 1, 1900\n    dttime:\tDBINT;       // 300ths of a second since midnight, 25920000 unit is 1 day\n  end;\n\n(*\n * Sybase & Microsoft use different names for the dbdaterec members.\n * Keep these two structures physically identical in memory.\n * dbdatecrack() casts one to the other for ease of implementation.\n *\n * Giving credit where credit is due, we can acknowledge that\n * Microsoft chose the better names here, hands down.  (\"datedmonth\"?!)\n *)\n  { FreeTDS sybdb.h }\n  PTDS_DBDATEREC = ^Ttds_dbdaterec;\n  Ttds_dbdaterec = packed record\n    { fields }            {microsoft}                 {sybase}\n    year:         DBINT;  { 1753 - 9999 }             { 1900 and counting }\n    quarter:      DBINT;  { 1 - 4 }                   { 0 - 3 (Microsoft only) }\n    month:        DBINT;  { 1 - 12 }                  { 0 - 11 }\n    dayofmonth:   DBINT;  { 1 - 31 }                  { 1 - 31 }\n    dayofyear:    DBINT;  { 1 - 366 }                 { 1 - 366 (in Sybase.sybdb.h dayofyear and day are changed around!) }\n    week:         DBINT;  { 1 - 54 (for leap years) } { 1 - 54 (Microsoft only) }\n    weekday:      DBINT;  { 1 - 7  (Mon - Sun) }      { 0 - 6  (Mon - Sun) }\n    hour:         DBINT;  { 0 - 23 }                  { 0 - 23 }\n    minute:       DBINT;  { 0 - 59 }                  { 0 - 59 }\n    second:       DBINT;  { 0 - 59 }                  { 0 - 59 }\n    millisecond:  DBINT;  { 0 - 999 }                 { 0 - 997 }\n    tzone:        DBINT;  { 0 - 127 (Sybase only!) }  { 0 - 127 }\n  end;\n\n{ DBDATEREC structure used by dbdatecrack }\n  DBDATEREC = packed record\n    year:       DBINT;      { 1753 - 9999 }\n    quarter:    DBINT;      { 1 - 4 }\n    month:      DBINT;      { 1 - 12 }\n    dayofyear:  DBINT;      { 1 - 366 }\n    day:        DBINT;      { 1 - 31 }\n    week:       DBINT;      { 1 - 54 (for leap years) }\n    weekday:    DBINT;      { 1 - 7  (Mon - Sun) }\n    hour:       DBINT;      { 0 - 23 }\n    minute:     DBINT;      { 0 - 59 }\n    second:     DBINT;      { 0 - 59 }\n    millisecond: DBINT;     { 0 - 999 }\n  end;\n  PDBDATEREC = ^DBDATEREC;\n\ntype\n{ TODO -ofjanos -cAPI :\nStrange but I had to insert X1 and X2 into the structure to make it work.\nI have not find any reason for this yet. }\n  {$IFDEF FPC}\n    {$PACKRECORDS 2}\n  {$ENDIF}\n  DBCOL = record\n   \tSizeOfStruct:   DBINT;\n   \tName:           array[0..MAXCOLNAMELEN] of char;\n   \tActualName:     array[0..MAXCOLNAMELEN] of char;\n   \tTableName:      array[0..MAXTABLENAME] of char;\n    {$IFNDEF FPC}\n    X1:             Byte;  //Record-Size diffs with C-Records\n    {$ENDIF}\n   \tTyp:            DBSHORT;\n   \tUserType:       DBINT;\n   \tMaxLength:      DBINT;\n   \tPrecision:      BYTE;\n   \tScale:          BYTE;\n   \tVarLength:      LongBool; { TRUE, FALSE }\n   \tNull:           BYTE;     { TRUE, FALSE or DBUNKNOWN }\n   \tCaseSensitive:  BYTE;     { TRUE, FALSE or DBUNKNOWN }\n   \tUpdatable:      BYTE;     { TRUE, FALSE or DBUNKNOWN }\n   \tIdentity:       LongBool; { TRUE, FALSE or DBUNKNOWN }\n    {$IFNDEF FPC}\n    X2:             Byte; //Record-Size diffs with C-Records\n    {$ENDIF}\n  end;\n  {$IFDEF FPC}\n    {$PACKRECORDS DEFAULT}\n  {$ENDIF}\n  PDBCOL = ^DBCOL;\n\n  PTDSDBCOL = ^TTDSDBCOL;\n  TTDSDBCOL = packed record\n    SizeOfStruct: DBINT;\n    Name:       array[0..TDSMAXCOLNAMELEN+2] of AnsiChar;\n    ActualName: array[0..TDSMAXCOLNAMELEN+2] of AnsiChar;\n    TableName:  array[0..TDSMAXTABLENAME+2] of AnsiChar;\n    Typ:        SmallInt;\n    UserType:   DBINT;\n    MaxLength:  DBINT;\n    Precision:  Byte;\n    Scale:      Byte;\n    VarLength:  LongBool;{ TRUE, FALSE }\n    Null:       Byte;    { TRUE, FALSE or DBUNKNOWN }\n    CaseSensitive: Byte; { TRUE, FALSE or DBUNKNOWN }\n    Updatable:  Byte;    { TRUE, FALSE or DBUNKNOWN }\n    Identity:   LongBool;{ TRUE, FALSE }\n  end;\n\ntype\n  DBTYPEINFO = packed record\n    Precision:  DBINT;\n\t  Scale:      DBINT;\n  end;\n  PDBTYPEINFO = ^DBTYPEINFO;\n\n  DBPROC_INFO = packed record\n    SizeOfStruct:       DBINT;\n    ServerType:         Byte;\n    ServerMajor:        Word;\n    ServerMinor:        Word;\n    ServerRevision:     Word;\n    ServerName:         array[0..MAXSERVERNAME] of AnsiChar;\n    NetLibName:         array[0..MAXNETLIBNAME] of AnsiChar;\n    NetLibConnStr:      array[0..MAXNETLIBCONNSTR] of AnsiChar;\n  end;\n  PDBPROCINFO = ^DBPROC_INFO;\n\n  DBCURSOR_INFO = packed record\n    SizeOfStruct:       DBINT;    { Use sizeof(DBCURSORINFO) }\n    TotCols:            Cardinal; { Total Columns in cursor }\n    TotRows:            Cardinal; { Total Rows in cursor }\n    CurRow:             Cardinal; { Current actual row in server }\n    TotRowsFetched:     Cardinal; { Total rows actually fetched }\n    CurType:            Cardinal; { See CU_... }\n    Status:             Cardinal; { See CU_... }\n  end;\n  PDBCURSORINFO = ^DBCURSOR_INFO;\n\ntype\n{ Pointer Datatypes }\n  PDBINT        = ^DBINT;\n  PDBBINARY     = ^DBBINARY;\n\ntype\n  PDBLibError = ^TDBLibError;\n  TDBLibError = record\n    dbProc: PDBPROCESS;\n    Severity: DBINT;\n    DbErr: DBINT;\n    OsErr: DBINT;\n    DbErrStr: AnsiString;\n    OsErrStr: AnsiString;\n  end;\n\n  PDBLibMessage = ^TDBLibMessage;\n  TDBLibMessage = record\n    dbProc: PDBPROCESS;\n    MsgNo: DBINT;\n    MsgState: DBINT;\n    Severity: DBINT;\n    MsgText: AnsiString;\n    SrvName: AnsiString;\n    ProcName: AnsiString;\n    Line: DBUSMALLINT;\n  end;\n\ntype\n  TDBVariables = record\n    dboptions: array[0..44]  of ShortInt;\n    dbSetLoginRec: array[0..16] of ShortInt;\n    datatypes: array[0..22] of Integer;\n  End;\n\n{common FreeTDS(dblib.dll) and ntwdblib.dll definitions\n  requirements: the sam call convention }\n  DBERRHANDLE_PROC = function(Proc: PDBPROCESS; Severity, DbErr, OsErr: Integer;\n    DbErrStr, OsErrStr: PAnsiChar): Integer; cdecl;\n  DBMSGHANDLE_PROC = function(Proc: PDBPROCESS; MsgNo: DBINT; MsgState,\n    Severity: Integer; MsgText, SrvName, ProcName: PAnsiChar; Line: DBUSMALLINT):\n    Integer; cdecl;\n  Tdberrhandle = function(Handler: DBERRHANDLE_PROC): DBERRHANDLE_PROC; cdecl;\n  Tdbmsghandle = function(Handler: DBMSGHANDLE_PROC): DBMSGHANDLE_PROC; cdecl;\n\n  Tdbprocerrhandle = function(DbHandle: PDBHANDLE; Handler: DBERRHANDLE_PROC):\n    DBERRHANDLE_PROC; cdecl;\n  Tdbprocmsghandle = function(DbHandle: PDBHANDLE; Handler: DBMSGHANDLE_PROC):\n    DBMSGHANDLE_PROC; cdecl;\n\n  Tdbadata = function(Proc: PDBPROCESS; ComputeId, Column: Integer): PByte; cdecl;\n  Tdbadlen = function(Proc: PDBPROCESS; ComputeId, Column: Integer): DBINT; cdecl;\n  Tdbaltbind = function(Proc: PDBPROCESS; ComputeId, Column, VarType: Integer;\n    VarLen: DBINT; VarAddr: PByte): RETCODE; cdecl;\n  Tdbaltcolid = function(Proc: PDBPROCESS; ComputeId, Column: Integer): Integer; cdecl;\n  Tdbaltlen = function(Proc: PDBPROCESS; ComputeId, Column: Integer): DBINT; cdecl;\n  Tdbaltop = function(Proc: PDBPROCESS; ComputeId, Column: Integer): Integer; cdecl;\n  Tdbalttype = function(Proc: PDBPROCESS; ComputeId, Column: Integer): Integer; cdecl;\n  Tdbaltutype = function(Proc: PDBPROCESS; ComputeId, Column: Integer): DBINT; cdecl;\n  Tdbanullbind = function(Proc: PDBPROCESS; ComputeId, Column: Integer;\n    Indicator: PDBINT): RETCODE; cdecl;\n  Tdbbind = function(Proc: PDBPROCESS; Column, VarType, VarLen: Integer;\n    VarAddr: PByte): RETCODE; cdecl;\n  Tdbbylist = function(Proc: PDBPROCESS; ComputeId: Integer; Size: PInteger):\n    PByte; cdecl;\n  Tdbcancel = function(Proc: PDBPROCESS): RETCODE; cdecl;\n  Tdbcanquery = function(Proc: PDBPROCESS): RETCODE; cdecl;\n  Tdbchange = function(Proc: PDBPROCESS): PAnsiChar; cdecl;\n  Tdbclrbuf = procedure(Proc: PDBPROCESS; N: DBINT); cdecl;\n  Tdbclropt = function(Proc: PDBPROCESS; Option: Integer; Param: PAnsiChar): RETCODE; cdecl;\n  Tdbcmd = function(Proc: PDBPROCESS; Cmd: PAnsiChar): RETCODE; cdecl;\n  Tdbcmdrow = function(Proc: PDBPROCESS): RETCODE; cdecl;\n  Tdbcollen = function(Proc: PDBPROCESS; Column: Integer): DBINT; cdecl;\n  Tdbcolname = function(Proc: PDBPROCESS; Column: Integer): PAnsiChar; cdecl;\n  Tdbcolsource = function(Proc: PDBPROCESS; Column: Integer): PAnsiChar; cdecl;\n  Tdbcoltype = function(Proc: PDBPROCESS; Column: Integer): Integer; cdecl;\n  Tdbcolutype = function(Proc: PDBPROCESS; Column: Integer): DBINT; cdecl;\n  Tdbconvert = function(Proc: PDBPROCESS; SrcType: Integer; Src: PByte;\n    SrcLen: DBINT; DestType: Integer; Dest: PByte; DestLen: DBINT): Integer; cdecl;\n  Tdbiscount = function(Proc: PDBPROCESS): LongBool; cdecl;\n  Tdbcurcmd = function(Proc: PDBPROCESS): Integer; cdecl;\n  Tdbcurrow = function(Proc: PDBPROCESS): DBINT; cdecl;\n  Tdbdata = function(Proc: PDBPROCESS; Column: Integer): PByte; cdecl;\n  Tdbcursor = function(hCursor: PDBCURSOR; OpType, Row: DBINT; Table, Values: PAnsiChar): RETCODE; cdecl;\n  Tdbexit = procedure; cdecl;\n  Tdbfcmd = function(Proc: PDBPROCESS; CmdString: PAnsiChar; var Params): RETCODE; cdecl;\n  Tdbfirstrow = function(Proc: PDBPROCESS): DBINT; cdecl;\n  Tdbfreebuf = procedure(Proc: PDBPROCESS); cdecl;\n  Tdbfreequal = procedure(Ptr: PAnsiChar); cdecl;\n  Tdbgetchar = function(Proc: PDBPROCESS; N: Integer): PAnsiChar; cdecl;\n  Tdbgetoff = function(Proc: PDBPROCESS; OffType: DBUSMALLINT; StartFrom: Integer): Integer; cdecl;\n  Tdbgetrow = function(Proc: PDBPROCESS; Row: DBINT): STATUS; cdecl;\n  Tdbgettime = function: Integer; cdecl;\n  Tdblastrow = function(Proc: PDBPROCESS): DBINT; cdecl;\n  Tdblogin = function: PLOGINREC; cdecl;\n  Tdbmorecmds = function(Proc: PDBPROCESS): RETCODE; cdecl;\n  Tdbmoretext = function(Proc: PDBPROCESS; Size: DBINT; Text: PByte): RETCODE; cdecl;\n  Tdbname = function(Proc: PDBPROCESS): PAnsiChar; cdecl;\n  Tdbnextrow = function(Proc: PDBPROCESS): STATUS; cdecl;\n  Tdbnullbind = function(Proc: PDBPROCESS; Column: Integer; Indicator: PDBINT):\n    RETCODE; cdecl;\n  Tdbnumalts = function(Proc: PDBPROCESS; ComputeId: Integer): Integer; cdecl;\n  Tdbnumcols = function(Proc: PDBPROCESS): Integer; cdecl;\n  Tdbnumcompute = function(Proc: PDBPROCESS): Integer; cdecl;\n  Tdbnumorders = function(Proc: PDBPROCESS): Integer; cdecl;\n  Tdbnumrets = function(Proc: PDBPROCESS): Integer; cdecl;\n  Tdbopen = function(Login: PLOGINREC; Host: PAnsiChar): PDBPROCESS; cdecl;\n  Tdbprhead = procedure(Proc: PDBPROCESS); cdecl;\n  Tdbprrow = function(Proc: PDBPROCESS): RETCODE; cdecl;\n  Tdbprtype = function(Token: Integer): PAnsiChar; cdecl;\n  Tdbqual = function(Proc: PDBPROCESS; TabNum: Integer; TabName: PAnsiChar): PAnsiChar; cdecl;\n  Tdbordercol = function(Proc: PDBPROCESS; Order: Integer): Integer; cdecl;\n  Tdbreadtext = function(dbproc: PDBPROCESS; Buf: Pointer; BufSize: DBINT): DBINT; cdecl;\n  Tdbresults = function(dbproc: PDBPROCESS): RETCODE; cdecl;\n  Tdbretdata = function(dbproc: PDBPROCESS; RetNum: Integer): PByte; cdecl;\n  Tdbretlen = function(dbproc: PDBPROCESS; RetNum: Integer): DBINT; cdecl;\n  Tdbretname = function(Proc: PDBPROCESS; RetNum: Integer): PAnsiChar; cdecl;\n  Tdbretstatus = function(Proc: PDBPROCESS): DBINT; cdecl;\n  Tdbrettype = function(Proc: PDBPROCESS; RetNum: Integer): Integer; cdecl;\n  Tdbrows = function(Proc: PDBPROCESS): RETCODE; cdecl; //!!!\n  Tdbrowtype = function(Proc: PDBPROCESS): STATUS; cdecl;\n  Tdbrpcinit = function(Proc: PDBPROCESS; ProcName: PAnsiChar; Options: DBSMALLINT):\n    RETCODE; cdecl; //!!!\n  Tdbrpcparam = function(Proc: PDBPROCESS; ParamName: PAnsiChar; Status: Byte;\n    Typ: Integer; MaxLen, DataLen: DBINT; Value: PByte): RETCODE; cdecl;\n  Tdbrpcsend = function(Proc: PDBPROCESS): RETCODE; cdecl;\n  Tdbrpwclr = procedure(Login: PLOGINREC); cdecl;\n  Tdbsetavail = procedure(Proc: PDBPROCESS); cdecl;\n  Tdbsetlogintime = function(Seconds: Integer): RETCODE; cdecl;\n  Tdbsetnull = function(Proc: PDBPROCESS; BindType, BindLen: Integer;\n    BindVal: PByte): RETCODE; cdecl;\n  Tdbsettime = function(Seconds: Integer): RETCODE; cdecl;\n  Tdbsetuserdata = procedure(Proc: PDBPROCESS; Ptr: Pointer); cdecl;\n  Tdbsqlexec = function(Proc: PDBPROCESS): RETCODE; cdecl;\n  Tdbsqlok = function(Proc: PDBPROCESS): RETCODE; cdecl;\n  Tdbsqlsend = function(Proc: PDBPROCESS): RETCODE; cdecl;\n  Tdbstrcpy = function(Proc: PDBPROCESS; Start, NumBytes: Integer; Dest: PAnsiChar):\n    RETCODE; cdecl;\n  Tdbstrlen = function(Proc: PDBPROCESS): Integer; cdecl;\n  Tdbtabcount = function(Proc: PDBPROCESS): Integer; cdecl;\n  Tdbtabname = function(Proc: PDBPROCESS; Table: Integer): PAnsiChar; cdecl;\n  Tdbtabsource = function(Proc: PDBPROCESS; Column: Integer; TabNum: PInteger):\n    PAnsiChar; cdecl;\n  Tdbtsnewlen = function(Proc: PDBPROCESS): Integer; cdecl;\n  Tdbtsnewval = function(Proc: PDBPROCESS): PDBBINARY; cdecl;\n  Tdbtsput = function(Proc: PDBPROCESS; NewTs: PDBBINARY; NewTsLen,\n    TabNum: Integer; TableName: PAnsiChar): RETCODE; cdecl;\n  Tdbtxptr = function(Proc: PDBPROCESS; Column: Integer): PDBBINARY; cdecl;\n  Tdbtxtimestamp = function(Proc: PDBPROCESS; Column: Integer): PDBBINARY; cdecl;\n  Tdbtxtsnewval = function(Proc: PDBPROCESS): PDBBINARY; cdecl;\n  Tdbtxtsput = function(Proc: PDBPROCESS; NewTxts: PDBBINARY; Column: Integer):\n    RETCODE; cdecl;\n  Tdbuse = function(Proc: PDBPROCESS; DbName: PAnsiChar): RETCODE; cdecl;\n  Tdbwritetext = function(Proc: PDBPROCESS; ObjName: PAnsiChar; TextPtr: PDBBINARY;\n    TextPtrLen: DBTINYINT; Timestamp: PDBBINARY; Log: LongBool; Size: DBINT;\n    Text: PByte): RETCODE; cdecl;\n  (* LOGINREC manipulation *)\n  Tdbsetlname = function(Login: PLOGINREC; Value: PAnsiChar; Item: Integer): RETCODE; cdecl;\n{ BCP functions }\n  Tbcp_batch = function(Proc: PDBPROCESS): DBINT; cdecl;\n  Tbcp_bind = function(Proc: PDBPROCESS; VarAddr: PByte; PrefixLen: Integer;\n    VarLen: DBINT; Terminator: PByte; TermLen, Typ, TableColumn: Integer):\n    RETCODE; cdecl;\n  Tbcp_colfmt = function(Proc: PDBPROCESS; FileColumn: Integer; FileType: Byte;\n    FilePrefixLen: Integer; FileColLen: DBINT; FileTerm: PByte; FileTermLen,\n    TableColumn: Integer): RETCODE; cdecl;\n  Tbcp_collen = function(Proc: PDBPROCESS; VarLen: DBINT; TableColumn: Integer):\n    RETCODE; cdecl;\n  Tbcp_colptr = function(Proc: PDBPROCESS; ColPtr: PByte; TableColumn: Integer):\n    RETCODE; cdecl;\n  Tbcp_columns = function(Proc: PDBPROCESS; FileColCount: Integer): RETCODE; cdecl;\n  Tbcp_control = function(Proc: PDBPROCESS; Field: Integer; Value: DBINT):\n    RETCODE; cdecl;\n  Tbcp_done = function(Proc: PDBPROCESS): DBINT; cdecl;\n  Tbcp_exec = function(Proc: PDBPROCESS; RowsCopied: PDBINT): RETCODE; cdecl;\n  Tbcp_init = function(Proc: PDBPROCESS; TableName, hFile, ErrFile: PAnsiChar;\n    Direction: Integer): RETCODE; cdecl;\n  Tbcp_moretext = function(Proc: PDBPROCESS; Size: DBINT; Text: PByte):\n    RETCODE; cdecl;\n  Tbcp_readfmt = function(Proc: PDBPROCESS; FileName: PAnsiChar): RETCODE; cdecl;\n  Tbcp_sendrow = function(Proc: PDBPROCESS): RETCODE; cdecl;\n  Tbcp_setl = function(Login: PLOGINREC; Enable: LongBool): RETCODE; cdecl;\n  Tbcp_writefmt = function(Proc: PDBPROCESS; FileName: PAnsiChar): RETCODE; cdecl;\n  { Two-phase commit functions }\n  Tabort_xact = function(Proc: PDBPROCESS; CommId: DBINT): RETCODE; cdecl;\n  Tbuild_xact_string = procedure(XActName, Service: PAnsiChar; CommId: DBINT;\n    Result: PAnsiChar); cdecl;\n  Tclose_commit = procedure(Proc: PDBPROCESS); cdecl;\n  Tcommit_xact = function(Proc: PDBPROCESS; CommId: DBINT): RETCODE; cdecl;\n  Topen_commit = function(Login: PLOGINREC; ServerName: PAnsiChar): PDBPROCESS; cdecl;\n  Tremove_xact = function(Proc: PDBPROCESS; CommId: DBINT; SiteCount: Integer):\n    RETCODE; cdecl;\n  Tscan_xact = function(Proc: PDBPROCESS; CommId: DBINT): RETCODE; cdecl;\n  Tstart_xact = function(Proc: PDBPROCESS; AppName, XActName: PAnsiChar;\n    SiteCount: Integer): DBINT; cdecl;\n  Tstat_xact = function(Proc: PDBPROCESS; CommId: DBINT): Integer; cdecl;\n\n\n\n{FreeTDS spezial API definitions}\n  TFreeTDSdb12hour = function(Proc: PDBPROCESS; Language: PAnsiChar): DBBOOL; cdecl;\n  TFreeTDSdbcolbrowse = function(Proc: PDBPROCESS; Column: Integer): DBBOOL; cdecl;\n  TFreeTDSdbcursorbind = function(hCursor: PDBCURSOR; Col, VarType: Integer; VarLen, POutLen: DBINT;\n    VarAddr: PByte; DBTYPEINFO: PDBTYPEINFO): RETCODE; cdecl;\n  TFreeTDSdbcursorclose = procedure(DbHandle: PDBHANDLE); cdecl;\n  TFreeTDSdbcursorcolinfo = function(hCursor: PDBCURSOR; Column: DBINT; ColName: PAnsiChar;\n    ColType, ColLen, UserType: PDBINT): RETCODE; cdecl;\n  TFreeTDSdbcursorfetch   = function(hCursor: PDBCURSOR; FetchType, RowNum: DBINT): RETCODE; cdecl;\n  TFreeTDSdbcursorinfo    = function(hCursor: PDBCURSOR; nCols, nRows: PDBINT): RETCODE; cdecl;\n  TFreeTDSdbcursoropen = function(Proc: PDBPROCESS; Sql: PAnsiChar; ScrollOpt,\n    ConCurOpt: DBSHORT; nRows: DBUSMALLINT; PStatus: PDBINT): PDBCURSOR; cdecl;\n\n  TFreeTDSdbaltbind_ps    = function(dbproc: PDBPROCESS; ComputeId, Column: Integer; VarType: Integer; VarLen: DBINT; VarAddr: PByte; typinfo: PDBTYPEINFO): RETCODE;\n  TFreeTDSdbbind_ps       = function(dbproc: PDBPROCESS; Column, VarType, VarLen: Integer; VarAddr: PByte; typinfo: PDBTYPEINFO): RETCODE; cdecl;\n  TFreeTDSdbbufsize       = function(dbproc: PDBPROCESS): Integer; cdecl;\n  TFreeTDSdbclose         = procedure(dbproc: PDBPROCESS); cdecl;\n  TFreeTDSdbtablecolinfo  = function(dbproc: PDBPROCESS; Column: DBINT; DbColumn: PTDSDBCOL): RETCODE;\n  TFreeTDSdbcolinfo       = function(Handle: PDBHANDLE; Typ, Column, ComputeId: Integer; DbColumn: PTDSDBCOL): RETCODE; cdecl;\n  TFreeTDSdbconvert_ps    = function(dbproc: PDBPROCESS; SrcType: Integer; Src: PByte; SrcLen: DBINT; DestType: Integer; Dest: PByte; DestLen: DBINT; typinfo: PDBTYPEINFO): Integer; cdecl;\n  TFreeTDSdbcount         = function(dbproc: PDBPROCESS): DBINT; cdecl;\n  TFreeTDSdbdatecmp       = function(dbproc: PDBPROCESS; d1, d2: PTDS_DBDATEREC): Integer;\n  TFreeTDSdbdatecrack     = function(dbproc: PDBPROCESS; DateInfo: PTDS_DBDATEREC; DateType: PTDSDBDATETIME): RETCODE; cdecl;\n  TFreeTDSdbdatlen        = function(dbproc: PDBPROCESS; Column: Integer): DBINT; cdecl;\n  TFreeTDSdbdead          = function(dbproc: PDBPROCESS): DBBOOL; cdecl;\n  TFreeTDSdbgetcharset    = function(dbproc: PDBPROCESS): PAnsiChar;\n  TFreeTDSdbgetlusername  = function(login: PLOGINREC; name_buffer: PByte; buffer_len: Integer): Integer; cdecl;\n  TFreeTDSdbgetmaxprocs   = function: Integer; cdecl;\n  TFreeTDSdbgetnatlanf    = function(dbproc: PDBPROCESS): PAnsiChar; cdecl;\n  TFreeTDSdbgetpacket     = function(dbproc: PDBPROCESS): Integer; cdecl;\n  TFreeTDSdbgetuserdata   = function(dbproc: PDBPROCESS): PByte; cdecl;\n  TFreeTDSdbhasretstat    = function(dbproc: PDBPROCESS): DBBOOL; cdecl;\n  TFreeTDSdbinit          = function:RETCODE; cdecl;\n  TFreeTDSdbiordesc       = function(dbproc: PDBPROCESS): Integer; cdecl;\n  TFreeTDSdbiowdesc       = function(dbproc: PDBPROCESS): Integer; cdecl;\n  TFreeTDSdbisavail       = function(Proc: PDBPROCESS): DBBOOL; cdecl;\n  TFreeTDSdbisopt         = function(Proc: PDBPROCESS; Option: Integer; const Param: PAnsiChar): DBBOOL; cdecl;\n  TFreeTDSdbloginfree     = procedure(Login: PLOGINREC); cdecl;\n  TFreeTDSdbmny4cmp       = function(dbproc: PDBPROCESS; m1, m: PDBMONEY4): Integer; cdecl;\n  TFreeTDSdbmnycmp        = function(dbproc: PDBPROCESS; m1, m2: PDBMONEY): Integer; cdecl;\n  TFreeTDSdbmny4add       = function(dbproc: PDBPROCESS; m1, m2, sum: PDBMONEY4): RETCODE; cdecl;\n  TFreeTDSdbmnydec        = function(dbproc: PDBPROCESS; mnyptr: PDBMONEY): RETCODE; cdecl;\n  TFreeTDSdbmnyinc        = function(dbproc: PDBPROCESS; mnyptr: PDBMONEY): RETCODE; cdecl;\n  TFreeTDSdbmnymaxpos     = function(dbproc: PDBPROCESS; dest: PDBMONEY): RETCODE; cdecl;\n  TFreeTDSdbmnymaxneg     = function(dbproc: PDBPROCESS; dest: PDBMONEY): RETCODE; cdecl;\n  TFreeTDSdbmny4minus     = function(dbproc: PDBPROCESS; src, dest: PDBMONEY): RETCODE; cdecl;\n  TFreeTDSdbmnyminus      = function(dbproc: PDBPROCESS; src, dest: PDBMONEY): RETCODE; cdecl;\n  TFreeTDSdbmny4sub       = function(dbproc: PDBPROCESS; m1, m2, diff: PDBMONEY4): RETCODE; cdecl;\n  TFreeTDSdbmnysub        = function(dbproc: PDBPROCESS; m1, m2, diff: PDBMONEY): RETCODE; cdecl;\n  TFreeTDSdbmny4copy      = function(dbproc: PDBPROCESS; m1, m2: PDBMONEY4): RETCODE; cdecl;\n  TFreeTDSdbmnycopy       = function(dbproc: PDBPROCESS; src, dest: PDBMONEY): RETCODE; cdecl;\n  TFreeTDSdbmny4zero      = function(dbproc: PDBPROCESS; dest: PDBMONEY4): RETCODE; cdecl;\n  TFreeTDSdbmnyzero       = function(dbproc: PDBPROCESS; dest: PDBMONEY4): RETCODE; cdecl;\n  TFreeTDSdbmonthname     = function(dbproc: PDBPROCESS; language: PAnsiChar; monthnum: Integer; shortform: DBBOOL): PAnsiChar; cdecl;\n  TFreeTDSdbopen          = function(Login: PLOGINREC; const Server: PAnsiChar; msdblib: Integer): PDBPROCESS; cdecl;\n  TFreeTDSdbrecftos       = procedure(const FileName: PAnsiChar);\n  TDRBUF                  = function(dbproc: PDBPROCESS): DBBOOL; cdecl;\n  TFreeTDSdbresults_r     = function(dbproc: PDBPROCESS; Recursive: Integer): RETCODE; cdecl;\n  TFreeTDSdbsafestr       = function(dbproc: PDBPROCESS; const Src: PAnsiChar; SrcLen: DBINT; Dest: PAnsiChar; DestLen: DBINT; QuoteType: integer): RETCODE; cdecl;\n  TFreeTDSdbservcharset   = function(dbproc: PDBPROCESS): PAnsiChar; cdecl;\n  TFreeTDSdbsetdefcharset = function(Charset: PAnsiChar): RETCODE; cdecl;\n  TFreeTDSdbsetifile      = procedure(FileName: PAnsiChar); cdecl;\n  TFreeTDSdbsetmaxprocs   = function(MaxProcs: Integer): RETCODE; cdecl;\n  TFreeTDSdbsetopt        = function(dbproc: PDBPROCESS; Option: DBINT; Param: PAnsiChar; int_param: DBINT): RETCODE; cdecl;\n  TFreeTDSdbsetrow        = function(dbproc: PDBPROCESS; Row: DBINT): STATUS; cdecl;\n  TFreeTDSdbsetversion    = function(Version: DBINT): RETCODE; cdecl;\n  TFreeTDSdbspid          = function(dbproc: PDBPROCESS): Integer; cdecl;\n  TFreeTDSdbspr1row       = function(dbproc: PDBPROCESS; Buffer: PAnsiChar; buf_len: DBINT): RETCODE; cdecl;\n  TFreeTDSdbspr1rowlen    = function(dbproc: PDBPROCESS): DBINT; cdecl;\n  TFreeTDSdbsprhead       = function(dbproc: PDBPROCESS; Buffer: PAnsiChar; buf_len: DBINT): RETCODE; cdecl;\n  TFreeTDSdbsprline       = function(dbproc: PDBPROCESS; Buffer: PAnsiChar; buf_len: DBINT; line_char: DBCHAR): RETCODE; cdecl;\n  TFreeTDSdbvarylen       = function(dbproc: PDBPROCESS; Column: Integer): DBINT; cdecl;\n  TFreeTDSdbtds           = function(dbproc: PDBPROCESS): DBINT; cdecl;\n  TFreeTDSdbtextsize      = function(dbproc: PDBPROCESS): DBINT; cdecl;\n  TFreeTDSdbwillconvert   = function(SrcType, DestType: Integer): DBBOOL; cdecl;\n  TFreeTDSdbtabbrowse     = function(Proc: PDBPROCESS; TabNum: Integer): LongBool; cdecl;\n  (* LOGINREC manipulation *)\n  TFreeTDSdbsetlbool      = function(Login: PLOGINREC; Value, Item: Integer): RETCODE; cdecl;\n  TFreeTDSdbsetllong      = function(Login: PLOGINREC; Value, Item: Integer): RETCODE; cdecl;\n  TFreeTDSdbsetlversion   = function(Login: PLOGINREC; Version: Byte): RETCODE; cdecl;\n  Ttdsdump_on = procedure ; cdecl;\n  Ttdsdump_off = procedure ; cdecl;\n  Ttdsdump_open = function (FileName : PAnsiChar): Integer; cdecl;\n  Ttdsdump_close = procedure ; cdecl;\n  T_tds_socket_init = procedure ; cdecl;\n  T_tds_socket_done = procedure ; cdecl;\n\n\n{ pivot functions\nvoid dbpivot_count (struct col_t *output, const struct col_t *input);\nvoid dbpivot_sum (struct col_t *output, const struct col_t *input);\nvoid dbpivot_min (struct col_t *output, const struct col_t *input);\nvoid dbpivot_max (struct col_t *output, const struct col_t *input);\n\nstruct pivot_t;\ntypedef void (*DBPIVOT_FUNC)(struct col_t *output, const struct col_t *input);\nstruct pivot_t * dbrows_pivoted(DBPROCESS *dbproc);\nSTATUS dbnextrow_pivoted(DBPROCESS *dbproc, struct pivot_t *pp);\nRETCODE dbpivot(DBPROCESS *dbproc, int nkeys, int *keys, int ncols, int *cols, DBPIVOT_FUNC func, int val);\n\nDBPIVOT_FUNC dbpivot_lookup_name( const char name[] );\n}\n  //TFreeTDSdbsechandle    = function(_Type: DBINT ; Handler: INTFUNCPTR): PRETCODE; cdecl;\n  //TFreeTDSdbsetbusy      = procedure(dbproc: PDBPROCESS; BusyFunc: DB_DBBUSY_FUNC);  cdecl;\n  //TFreeTDSdbsetinterrupt = procedure(dbproc: PDBPROCESS; chkintr: DB_DBCHKINTR_FUNC; hndlintr: DB_DBHNDLINTR_FUNC);\n\n\n\n{MsSQL-spezial API definitions}\n\n{ Standard DB-Library functions }\n  TMsSQLdbclose = function(Proc: PDBPROCESS): RETCODE; cdecl;\n  TMsSQLdbcolbrowse = function(Proc: PDBPROCESS; Column: Integer): LongBool; cdecl;\n  TMsSQLdbcolinfo = function(Handle: PDBHANDLE; Typ, Column, ComputeId: Integer;\n    DbColumn: PDBCOL): RETCODE; cdecl;\n  TMsSQLdbcount = function(Proc: PDBPROCESS): Integer; cdecl;\n\n  TMsSQLdbcursorbind = function(hCursor: PDBCURSOR; Col, VarType: Integer; VarLen: DBINT;\n    POutLen: PDBINT; VarAddr: PByte): RETCODE; cdecl;\n  TMsSQLdbcursorclose = function(DbHandle: PDBHANDLE): RETCODE; cdecl;\n  TMsSQLdbcursorcolinfo = function(hCursor: PDBCURSOR; Column: Integer; ColName: PAnsiChar;\n    ColType: PInteger; ColLen: PDBINT; UserType: PInteger): RETCODE; cdecl;\n  TMsSQLdbcursorfetch = function(hCursor: PDBCURSOR; FetchType, RowNum: Integer): RETCODE; cdecl;\n  TMsSQLdbcursorfetchex = function(hCursor: PDBCURSOR; FetchType: Integer; RowNum,\n    nFetchRows, Reserved: DBINT): RETCODE; cdecl;\n  TMsSQLdbcursorinfo = function(hCursor: PDBCURSOR; nCols: PInteger; nRows: PDBINT):\n    RETCODE; cdecl;\n  TMsSQLdbcursorinfoex = function(hCursor: PDBCURSOR; DbCursorInfo: PDBCURSORINFO):\n    RETCODE; cdecl;\n  TMsSQLdbcursoropen = function(Proc: PDBPROCESS; Sql: PAnsiChar; ScrollOpt,\n    ConCurOpt: Integer; nRows: Cardinal; PStatus: PDBINT): PDBCURSOR; cdecl;\n  TMsSQLdbdataready = function(Proc: PDBPROCESS): LongBool; cdecl;\n  TMsSQLdbdatecrack = function(Proc: PDBPROCESS; DateInfo: PDBDATEREC;\n    DateType: PDBDATETIME): RETCODE; cdecl;\n  TMsSQLdbdatlen = function(Proc: PDBPROCESS; Column: Integer): Integer; cdecl;\n  TMsSQLdbdead = function(Proc: PDBPROCESS): LongBool; cdecl;\n  TMsSQLdbWinexit = procedure; cdecl;\n  TMsSQLdbenlisttrans = function(Proc: PDBPROCESS; Transaction: Pointer): RETCODE; cdecl;\n  TMsSQLdbenlistxatrans = function(Proc: PDBPROCESS; EnlistTran: LongBool): RETCODE; cdecl;\n  TMsSQLdbgetmaxprocs = function: SmallInt; cdecl;\n  TMsSQLdbgetpacket = function(Proc: PDBPROCESS): Cardinal; cdecl;\n  TMsSQLdbgetuserdata = function(Proc: PDBPROCESS): Pointer; cdecl;\n  TMsSQLdbhasretstat = function(Proc: PDBPROCESS): LongBool; cdecl;\n  TMsSQLdbinit = function: PAnsiChar; cdecl;\n  TMsSQLdbisavail = function(Proc: PDBPROCESS): LongBool; cdecl;\n  TMsSQLdbisopt = function(Proc: PDBPROCESS; Option: Integer; Param: PAnsiChar): LongBool; cdecl;\n  TMsSQLdbfreelogin = procedure(Login: PLOGINREC); cdecl;\n  TMsSQLdbprocinfo = function(Proc: PDBPROCESS; DbProcInfo: PDBPROCINFO): RETCODE; cdecl;\n  TMsSQLdbrpcexec = function(Proc: PDBPROCESS): RETCODE; cdecl;\n  TMsSQLdbserverenum = function(SearchMode: Word; ServNameBuf: PAnsiChar;\n    ServNameBufSize: Word; NumEntries: PWord): Integer; cdecl;\n  TMsSQLdbsetmaxprocs = function(MaxProcs: SmallInt): RETCODE; cdecl;\n  TMsSQLdbsetlpacket = function(Login: PLOGINREC; PacketSize: Word): RETCODE; cdecl; //TDS: dbsetllong\n  TMsSQLdbsetopt = function(Proc: PDBPROCESS; Option: Integer; Param: PAnsiChar):\n    RETCODE; cdecl;\n  TMsSQLdbtabbrowse = function(Proc: PDBPROCESS; TabNum: Integer): LongBool; cdecl;\n\n  TMsSQLdbvarylen = function(Proc: PDBPROCESS; Column: Integer): LongBool; cdecl;\n  TMsSQLdbwillconvert = function(SrcType, DestType: Integer): LongBool; cdecl;\n  TMsSQLdbupdatetext = function(Proc: PDBPROCESS; DestObject: PAnsiChar; DestTextPtr,\n    DestTimestamp: PDBBINARY; UpdateType: Integer; InsertOffset,\n    DeleteLength: DBINT; SrcObject: PAnsiChar; SrcSize: DBINT; SrcText: PDBBINARY):\n    RETCODE; cdecl;\n\n{************* Plain API Function variables definition ************}\n\n{Sybase API definitions}\ntype\n  SYBDBERRHANDLE_PROC = function(Proc: PDBPROCESS; Severity, DbErr, OsErr: Integer;\n    DbErrStr, OsErrStr: PAnsiChar): Integer; {$IFNDEF UNIX} stdcall {$ELSE} cdecl {$ENDIF};\n  SYBDBMSGHANDLE_PROC = function(Proc: PDBPROCESS; MsgNo: DBINT; MsgState,\n    Severity: Integer; MsgText, SrvName, ProcName: PAnsiChar; Line: DBUSMALLINT):\n    Integer; {$IFNDEF UNIX} stdcall {$ELSE} cdecl {$ENDIF};\n\n  TSybdb12hour = function(Proc: PDBPROCESS; Language: PAnsiChar): DBBOOL; {$IFNDEF UNIX} stdcall {$ELSE} cdecl {$ENDIF};\n\n  TSybdberrhandle = function(Handler: SYBDBERRHANDLE_PROC): SYBDBERRHANDLE_PROC; {$IFNDEF UNIX} stdcall {$ELSE} cdecl {$ENDIF};\n  TSybdbmsghandle = function(Handler: SYBDBMSGHANDLE_PROC): SYBDBMSGHANDLE_PROC; {$IFNDEF UNIX} stdcall {$ELSE} cdecl {$ENDIF};\n\n  { Two-phase commit functions }\n  TSybabort_xact = function(Proc: PDBPROCESS; CommId: DBINT): RETCODE; {$IFNDEF UNIX} stdcall {$ELSE} cdecl {$ENDIF};\n  TSybbuild_xact_string = procedure(XActName, Service: PAnsiChar; CommId: DBINT;\n      Result: PAnsiChar); {$IFNDEF UNIX}stdcall{$ELSE}cdecl{$ENDIF};\n  TSybclose_commit = procedure(Proc: PDBPROCESS); {$IFNDEF UNIX}stdcall{$ELSE}cdecl{$ENDIF};\n  TSybcommit_xact = function(Proc: PDBPROCESS; CommId: DBINT): RETCODE; {$IFNDEF UNIX}stdcall{$ELSE}cdecl{$ENDIF};\n  TSybopen_commit = function(Login: PLOGINREC; ServerName: PAnsiChar): PDBPROCESS; {$IFNDEF UNIX}stdcall{$ELSE}cdecl{$ENDIF};\n  TSybremove_xact = function(Proc: PDBPROCESS; CommId: DBINT; SiteCount: Integer): RETCODE; {$IFNDEF UNIX} stdcall {$ELSE} cdecl {$ENDIF};\n  TSybscan_xact = function(Proc: PDBPROCESS; CommId: DBINT): RETCODE; {$IFNDEF UNIX} stdcall {$ELSE} cdecl {$ENDIF};\n  TSybstart_xact = function(Proc: PDBPROCESS; AppName, XActName: PAnsiChar;\n    SiteCount: Integer): DBINT; {$IFNDEF UNIX} stdcall {$ELSE} cdecl {$ENDIF};\n  TSybstat_xact = function(Proc: PDBPROCESS; CommId: DBINT): Integer; {$IFNDEF UNIX} stdcall {$ELSE} cdecl {$ENDIF};\n\n{ BCP functions }\n  TSybbcp_batch = function(Proc: PDBPROCESS): DBINT; {$IFNDEF UNIX} stdcall {$ELSE} cdecl {$ENDIF};\n  TSybbcp_bind = function(Proc: PDBPROCESS; VarAddr: PByte; PrefixLen: Integer;\n    VarLen: DBINT; Terminator: PByte; TermLen, Typ, TableColumn: Integer):\n    RETCODE; {$IFNDEF UNIX} stdcall {$ELSE} cdecl {$ENDIF};\n  TSybbcp_colfmt = function(Proc: PDBPROCESS; FileColumn: Integer; FileType: Byte;\n    FilePrefixLen: Integer; FileColLen: DBINT; FileTerm: PByte; FileTermLen,\n    TableColumn: Integer): RETCODE; {$IFNDEF UNIX} stdcall {$ELSE} cdecl {$ENDIF};\n  TSybbcp_collen = function(Proc: PDBPROCESS; VarLen: DBINT; TableColumn: Integer):\n    RETCODE; {$IFNDEF UNIX} stdcall {$ELSE} cdecl {$ENDIF};\n  TSybbcp_colptr = function(Proc: PDBPROCESS; ColPtr: PByte; TableColumn: Integer):\n    RETCODE; {$IFNDEF UNIX} stdcall {$ELSE} cdecl {$ENDIF};\n  TSybbcp_columns = function(Proc: PDBPROCESS; FileColCount: Integer): RETCODE; {$IFNDEF UNIX} stdcall {$ELSE} cdecl {$ENDIF};\n  TSybbcp_control = function(Proc: PDBPROCESS; Field: Integer; Value: DBINT):\n    RETCODE; {$IFNDEF UNIX} stdcall {$ELSE} cdecl {$ENDIF};\n  TSybbcp_done = function(Proc: PDBPROCESS): DBINT; {$IFNDEF UNIX} stdcall {$ELSE} cdecl {$ENDIF};\n  TSybbcp_exec = function(Proc: PDBPROCESS; RowsCopied: PDBINT): RETCODE; {$IFNDEF UNIX} stdcall {$ELSE} cdecl {$ENDIF};\n  TSybbcp_init = function(Proc: PDBPROCESS; TableName, hFile, ErrFile: PAnsiChar;\n    Direction: Integer): RETCODE; {$IFNDEF UNIX} stdcall {$ELSE} cdecl {$ENDIF};\n  TSybbcp_moretext = function(Proc: PDBPROCESS; Size: DBINT; Text: PByte):\n    RETCODE; {$IFNDEF UNIX} stdcall {$ELSE} cdecl {$ENDIF};\n  TSybbcp_readfmt = function(Proc: PDBPROCESS; FileName: PAnsiChar): RETCODE; {$IFNDEF UNIX} stdcall {$ELSE} cdecl {$ENDIF};\n  TSybbcp_sendrow = function(Proc: PDBPROCESS): RETCODE; {$IFNDEF UNIX} stdcall {$ELSE} cdecl {$ENDIF};\n  TSybbcp_writefmt = function(Proc: PDBPROCESS; FileName: PAnsiChar): RETCODE; {$IFNDEF UNIX} stdcall {$ELSE} cdecl {$ENDIF};\n\n{ Standard DB-Library functions }\n  TSybdbadata = function(Proc: PDBPROCESS; ComputeId, Column: Integer): PByte; {$IFNDEF UNIX} stdcall {$ELSE} cdecl {$ENDIF};\n  TSybdbadlen = function(Proc: PDBPROCESS; ComputeId, Column: Integer): DBINT; {$IFNDEF UNIX} stdcall {$ELSE} cdecl {$ENDIF};\n  TSybdbaltbind = function(Proc: PDBPROCESS; ComputeId, Column: Integer;\n    VarType: Integer; VarLen: DBINT; VarAddr: PByte): RETCODE; {$IFNDEF UNIX} stdcall {$ELSE} cdecl {$ENDIF};\n  TSybdbaltcolid = function(Proc: PDBPROCESS; ComputeId, Column: Integer): Integer; {$IFNDEF UNIX} stdcall {$ELSE} cdecl {$ENDIF};\n  TSybdbaltlen = function(Proc: PDBPROCESS; ComputeId, Column: Integer): DBINT; {$IFNDEF UNIX} stdcall {$ELSE} cdecl {$ENDIF};\n  TSybdbaltop = function(Proc: PDBPROCESS; ComputeId, Column: Integer): Integer; {$IFNDEF UNIX} stdcall {$ELSE} cdecl {$ENDIF};\n  TSybdbalttype = function(Proc: PDBPROCESS; ComputeId, Column: Integer): Integer; {$IFNDEF UNIX} stdcall {$ELSE} cdecl {$ENDIF};\n  TSybdbaltutype = function(Proc: PDBPROCESS; ComputeId, Column: Integer): DBINT; {$IFNDEF UNIX} stdcall {$ELSE} cdecl {$ENDIF};\n  TSybdbanullbind = function(Proc: PDBPROCESS; ComputeId, Column: Integer;\n    Indicator: PDBINT): RETCODE; {$IFNDEF UNIX} stdcall {$ELSE} cdecl {$ENDIF};\n  TSybdbbind = function(Proc: PDBPROCESS; Column, VarType, VarLen: Integer;\n    VarAddr: PByte): RETCODE; {$IFNDEF UNIX} stdcall {$ELSE} cdecl {$ENDIF};\n  TSybdbbylist = function(Proc: PDBPROCESS; ComputeId: Integer; Size: PInteger):\n    PByte; {$IFNDEF UNIX} stdcall {$ELSE} cdecl {$ENDIF};\n  TSybdbcancel = function(Proc: PDBPROCESS): RETCODE; {$IFNDEF UNIX} stdcall {$ELSE} cdecl {$ENDIF};\n  TSybdbcanquery = function(Proc: PDBPROCESS): RETCODE; {$IFNDEF UNIX} stdcall {$ELSE} cdecl {$ENDIF};\n  TSybdbchange = function(Proc: PDBPROCESS): PAnsiChar; {$IFNDEF UNIX} stdcall {$ELSE} cdecl {$ENDIF};\n  TSybdbclose = function(Proc: PDBPROCESS): RETCODE; {$IFNDEF UNIX} stdcall {$ELSE} cdecl {$ENDIF};\n  TSybdbclrbuf = procedure(Proc: PDBPROCESS; N: DBINT); {$IFNDEF UNIX} stdcall {$ELSE} cdecl {$ENDIF};\n  TSybdbclropt = function(Proc: PDBPROCESS; Option: Integer; Param: PAnsiChar): RETCODE; {$IFNDEF UNIX} stdcall {$ELSE} cdecl {$ENDIF};\n  TSybdbcmd = function(Proc: PDBPROCESS; Cmd: PAnsiChar): RETCODE; {$IFNDEF UNIX} stdcall {$ELSE} cdecl {$ENDIF};\n  TSybdbcmdrow = function(Proc: PDBPROCESS): RETCODE; {$IFNDEF UNIX} stdcall {$ELSE} cdecl {$ENDIF};\n  TSybdbcolbrowse = function(Proc: PDBPROCESS; Column: Integer): LongBool; {$IFNDEF UNIX} stdcall {$ELSE} cdecl {$ENDIF};\n  TSybdbcollen = function(Proc: PDBPROCESS; Column: Integer): DBINT; {$IFNDEF UNIX} stdcall {$ELSE} cdecl {$ENDIF};\n  TSybdbcolname = function(Proc: PDBPROCESS; Column: Integer): PAnsiChar; {$IFNDEF UNIX} stdcall {$ELSE} cdecl {$ENDIF};\n  TSybdbcolsource = function(Proc: PDBPROCESS; Column: Integer): PAnsiChar; {$IFNDEF UNIX} stdcall {$ELSE} cdecl {$ENDIF};\n//  TSybdbcoltypeinfo = function(Proc: PDBPROCESS; Column: Integer): PDBTYPEINFO; {$IFNDEF UNIX} stdcall {$ELSE} cdecl {$ENDIF};\n  TSybdbcoltype = function(Proc: PDBPROCESS; Column: Integer): Integer; {$IFNDEF UNIX} stdcall {$ELSE} cdecl {$ENDIF};\n  TSybdbcolutype = function(Proc: PDBPROCESS; Column: Integer): DBINT; {$IFNDEF UNIX} stdcall {$ELSE} cdecl {$ENDIF};\n  TSybdbconvert = function(Proc: PDBPROCESS; SrcType: Integer; Src: PByte;\n  SrcLen: DBINT; DestType: Integer; Dest: PByte; DestLen: DBINT): Integer; {$IFNDEF UNIX} stdcall {$ELSE} cdecl {$ENDIF};\n  TSybdbcount = function(Proc: PDBPROCESS): Integer; {$IFNDEF UNIX} stdcall {$ELSE} cdecl {$ENDIF};\n  TSybdbcurcmd = function(Proc: PDBPROCESS): Integer; {$IFNDEF UNIX} stdcall {$ELSE} cdecl {$ENDIF};\n  TSybdbcurrow = function(Proc: PDBPROCESS): DBINT; {$IFNDEF UNIX} stdcall {$ELSE} cdecl {$ENDIF};\n\n  TSybdbcursor = function(hCursor: PDBCURSOR; OpType, Row: Integer; Table,\n    Values: PAnsiChar): RETCODE; {$IFNDEF UNIX} stdcall {$ELSE} cdecl {$ENDIF};\n  TSybdbcursorbind = function(hCursor: PDBCURSOR; Col, VarType: Integer; VarLen: DBINT;\n    POutLen: PDBINT; VarAddr: PByte): RETCODE; {$IFNDEF UNIX} stdcall {$ELSE} cdecl {$ENDIF};\n  TSybdbcursorclose = function(DbHandle: PDBHANDLE): RETCODE; {$IFNDEF UNIX} stdcall {$ELSE} cdecl {$ENDIF};\n  TSybdbcursorcolinfo = function(hCursor: PDBCURSOR; Column: Integer; ColName: PAnsiChar;\n    ColType: PInteger; ColLen: PDBINT; UserType: PInteger): RETCODE; {$IFNDEF UNIX} stdcall {$ELSE} cdecl {$ENDIF};\n  TSybdbcursorfetch = function(hCursor: PDBCURSOR; FetchType, RowNum: Integer):\n    RETCODE; {$IFNDEF UNIX} stdcall {$ELSE} cdecl {$ENDIF};\n  TSybdbcursorinfo = function(hCursor: PDBCURSOR; nCols: PInteger; nRows: PDBINT):\n    RETCODE; {$IFNDEF UNIX} stdcall {$ELSE} cdecl {$ENDIF};\n  TSybdbcursoropen = function(Proc: PDBPROCESS; Sql: PAnsiChar; ScrollOpt,\n    ConCurOpt: Integer; nRows: Cardinal; PStatus: PDBINT): PDBCURSOR; {$IFNDEF UNIX} stdcall {$ELSE} cdecl {$ENDIF};\n  TSybdbdata = function(Proc: PDBPROCESS; Column: Integer): PByte; {$IFNDEF UNIX} stdcall {$ELSE} cdecl {$ENDIF};\n  TSybdbdatecrack = function(Proc: PDBPROCESS; DateInfo: PDBDATEREC;\n    DateType: PDBDATETIME): RETCODE; {$IFNDEF UNIX} stdcall {$ELSE} cdecl {$ENDIF};\n  TSybdbdatlen = function(Proc: PDBPROCESS; Column: Integer): Integer; {$IFNDEF UNIX} stdcall {$ELSE} cdecl {$ENDIF};\n  TSybdbdead = function(Proc: PDBPROCESS): LongBool; {$IFNDEF UNIX} stdcall {$ELSE} cdecl {$ENDIF};\n  TSybdbexit = procedure; {$IFNDEF UNIX} stdcall {$ELSE} cdecl {$ENDIF};\n  TSybdbfcmd = function(Proc: PDBPROCESS; CmdString: PAnsiChar; var Params): RETCODE; {$IFNDEF UNIX} stdcall {$ELSE} cdecl {$ENDIF};\n  TSybdbfirstrow = function(Proc: PDBPROCESS): DBINT; {$IFNDEF UNIX} stdcall {$ELSE} cdecl {$ENDIF};\n  TSybdbfreebuf = procedure(Proc: PDBPROCESS); {$IFNDEF UNIX} stdcall {$ELSE} cdecl {$ENDIF};\n  TSybdbloginfree = procedure(Login: PLOGINREC); {$IFNDEF UNIX} stdcall {$ELSE} cdecl {$ENDIF};\n  TSybdbfreequal = procedure(Ptr: PAnsiChar); {$IFNDEF UNIX} stdcall {$ELSE} cdecl {$ENDIF};\n  TSybdbgetchar = function(Proc: PDBPROCESS; N: Integer): PAnsiChar; {$IFNDEF UNIX} stdcall {$ELSE} cdecl {$ENDIF};\n  TSybdbgetmaxprocs = function: SmallInt; {$IFNDEF UNIX} stdcall {$ELSE} cdecl {$ENDIF};\n  TSybdbgetoff = function(Proc: PDBPROCESS; OffType: DBUSMALLINT;\n    StartFrom: Integer): Integer; {$IFNDEF UNIX} stdcall {$ELSE} cdecl {$ENDIF};\n  TSybdbgetpacket = function(Proc: PDBPROCESS): Cardinal; {$IFNDEF UNIX} stdcall {$ELSE} cdecl {$ENDIF};\n  TSybdbgetrow = function(Proc: PDBPROCESS; Row: DBINT): STATUS; {$IFNDEF UNIX} stdcall {$ELSE} cdecl {$ENDIF};\n  TSybdbgetuserdata = function(Proc: PDBPROCESS): Pointer; {$IFNDEF UNIX} stdcall {$ELSE} cdecl {$ENDIF};\n  TSybdbhasretstat = function(Proc: PDBPROCESS): LongBool; {$IFNDEF UNIX} stdcall {$ELSE} cdecl {$ENDIF};\n  TSybdbinit = function: RETCODE; {$IFNDEF UNIX} stdcall {$ELSE} cdecl {$ENDIF};\n  TSybdbisavail = function(Proc: PDBPROCESS): LongBool; {$IFNDEF UNIX} stdcall {$ELSE} cdecl {$ENDIF};\n  TSybdbisopt = function(Proc: PDBPROCESS; Option: Integer; Param: PAnsiChar): LongBool; {$IFNDEF UNIX} stdcall {$ELSE} cdecl {$ENDIF};\n  TSybdblastrow = function(Proc: PDBPROCESS): DBINT; {$IFNDEF UNIX} stdcall {$ELSE} cdecl {$ENDIF};\n  TSybdblogin = function: PLOGINREC; {$IFNDEF UNIX} stdcall {$ELSE} cdecl {$ENDIF};\n  TSybdbmorecmds = function(Proc: PDBPROCESS): RETCODE; {$IFNDEF UNIX} stdcall {$ELSE} cdecl {$ENDIF};\n  TSybdbmoretext = function(Proc: PDBPROCESS; Size: DBINT; Text: PByte): RETCODE; {$IFNDEF UNIX} stdcall {$ELSE} cdecl {$ENDIF};\n  TSybdbname = function(Proc: PDBPROCESS): PAnsiChar; {$IFNDEF UNIX} stdcall {$ELSE} cdecl {$ENDIF};\n  TSybdbnextrow = function(Proc: PDBPROCESS): STATUS; {$IFNDEF UNIX} stdcall {$ELSE} cdecl {$ENDIF};\n  TSybdbnullbind = function(Proc: PDBPROCESS; Column: Integer; Indicator: PDBINT):\n    RETCODE; {$IFNDEF UNIX} stdcall {$ELSE} cdecl {$ENDIF};\n  TSybdbnumalts = function(Proc: PDBPROCESS; ComputeId: Integer): Integer; {$IFNDEF UNIX} stdcall {$ELSE} cdecl {$ENDIF};\n  TSybdbnumcols = function(Proc: PDBPROCESS): Integer; {$IFNDEF UNIX} stdcall {$ELSE} cdecl {$ENDIF};\n  TSybdbnumcompute = function(Proc: PDBPROCESS): Integer; {$IFNDEF UNIX} stdcall {$ELSE} cdecl {$ENDIF};\n  TSybdbnumorders = function(Proc: PDBPROCESS): Integer; {$IFNDEF UNIX} stdcall {$ELSE} cdecl {$ENDIF};\n  TSybdbnumrets = function(Proc: PDBPROCESS): Integer; {$IFNDEF UNIX} stdcall {$ELSE} cdecl {$ENDIF};\n  TSybdbopen = function(Login: PLOGINREC; Host: PAnsiChar): PDBPROCESS; {$IFNDEF UNIX} stdcall {$ELSE} cdecl {$ENDIF};\n  TSybdbordercol = function(Proc: PDBPROCESS; Order: Integer): Integer; {$IFNDEF UNIX} stdcall {$ELSE} cdecl {$ENDIF};\n  TSybdbprhead = procedure(Proc: PDBPROCESS); {$IFNDEF UNIX} stdcall {$ELSE} cdecl {$ENDIF};\n  TSybdbprrow = function(Proc: PDBPROCESS): RETCODE; {$IFNDEF UNIX} stdcall {$ELSE} cdecl {$ENDIF};\n  TSybdbprtype = function(Token: Integer): PAnsiChar; {$IFNDEF UNIX} stdcall {$ELSE} cdecl {$ENDIF};\n  TSybdbqual = function(Proc: PDBPROCESS; TabNum: Integer; TabName: PAnsiChar): PAnsiChar; {$IFNDEF UNIX} stdcall {$ELSE} cdecl {$ENDIF};\n  TSybdbreadtext = function(Proc: PDBPROCESS; Buf: Pointer; BufSize: DBINT): DBINT; {$IFNDEF UNIX} stdcall {$ELSE} cdecl {$ENDIF};\n  TSybdbresults = function(Proc: PDBPROCESS): RETCODE; {$IFNDEF UNIX} stdcall {$ELSE} cdecl {$ENDIF};\n  TSybdbretdata = function(Proc: PDBPROCESS; RetNum: Integer): PByte; {$IFNDEF UNIX} stdcall {$ELSE} cdecl {$ENDIF};\n  TSybdbretlen = function(Proc: PDBPROCESS; RetNum: Integer): DBINT; {$IFNDEF UNIX} stdcall {$ELSE} cdecl {$ENDIF};\n  TSybdbretname = function(Proc: PDBPROCESS; RetNum: Integer): PAnsiChar; {$IFNDEF UNIX} stdcall {$ELSE} cdecl {$ENDIF};\n  TSybdbretstatus = function(Proc: PDBPROCESS): DBINT; {$IFNDEF UNIX} stdcall {$ELSE} cdecl {$ENDIF};\n  TSybdbrettype = function(Proc: PDBPROCESS; RetNum: Integer): Integer; {$IFNDEF UNIX} stdcall {$ELSE} cdecl {$ENDIF};\n  TSybdbrows = function(Proc: PDBPROCESS): RETCODE; {$IFNDEF UNIX} stdcall {$ELSE} cdecl {$ENDIF}; //!!!\n  TSybdbrowtype = function(Proc: PDBPROCESS): STATUS; {$IFNDEF UNIX} stdcall {$ELSE} cdecl {$ENDIF};\n  TSybdbrpcinit = function(Proc: PDBPROCESS; ProcName: PAnsiChar; Options: DBSMALLINT): RETCODE; {$IFNDEF UNIX} stdcall {$ELSE} cdecl {$ENDIF}; //!!!\n  TSybdbrpcparam = function(Proc: PDBPROCESS; ParamName: PAnsiChar; Status: Byte;\n    Typ: Integer; MaxLen, DataLen: DBINT; Value: PByte): RETCODE; {$IFNDEF UNIX} stdcall {$ELSE} cdecl {$ENDIF};\n  TSybdbrpcsend = function(Proc: PDBPROCESS): RETCODE; {$IFNDEF UNIX} stdcall {$ELSE} cdecl {$ENDIF};\n\n  TSybdbrpwclr = procedure(Login: PLOGINREC); {$IFNDEF UNIX}stdcall{$ELSE}cdecl{$ENDIF};\n  TSybdbsetavail = procedure(Proc: PDBPROCESS); {$IFNDEF UNIX}stdcall{$ELSE}cdecl{$ENDIF};\n  TSybdbsetmaxprocs = function(MaxProcs: SmallInt): RETCODE; {$IFNDEF UNIX}stdcall{$ELSE}cdecl{$ENDIF};\n  TSybdbsetlname = function(Login: PLOGINREC; Value: PAnsiChar; Item: Integer): RETCODE; {$IFNDEF UNIX}stdcall{$ELSE}cdecl{$ENDIF};\n  TSybdbsetlogintime = function(Seconds: Integer): RETCODE; {$IFNDEF UNIX}stdcall{$ELSE}cdecl{$ENDIF};\n\n  TSybdbsetnull = function(Proc: PDBPROCESS; BindType, BindLen: Integer;\n    BindVal: PByte): RETCODE; {$IFNDEF UNIX} stdcall {$ELSE} cdecl {$ENDIF};\n  TSybdbsetopt = function(Proc: PDBPROCESS; Option: Integer; CharParam: PAnsiChar; IntParam: Integer):\n    RETCODE; {$IFNDEF UNIX} stdcall {$ELSE} cdecl {$ENDIF};\n  TSybdbsettime = function(Seconds: Integer): RETCODE; {$IFNDEF UNIX} stdcall {$ELSE} cdecl {$ENDIF};\n  TSybdbsetuserdata = procedure(Proc: PDBPROCESS; Ptr: Pointer); {$IFNDEF UNIX} stdcall {$ELSE} cdecl {$ENDIF};\n  TSybdbsqlexec = function(Proc: PDBPROCESS): RETCODE; {$IFNDEF UNIX} stdcall {$ELSE} cdecl {$ENDIF};\n  TSybdbsqlok = function(Proc: PDBPROCESS): RETCODE; {$IFNDEF UNIX} stdcall {$ELSE} cdecl {$ENDIF};\n  TSybdbsqlsend = function(Proc: PDBPROCESS): RETCODE; {$IFNDEF UNIX} stdcall {$ELSE} cdecl {$ENDIF};\n  TSybdbstrcpy = function(Proc: PDBPROCESS; Start, NumBytes: Integer; Dest: PAnsiChar):\n    RETCODE; {$IFNDEF UNIX} stdcall {$ELSE} cdecl {$ENDIF};\n  TSybdbstrlen = function(Proc: PDBPROCESS): Integer; {$IFNDEF UNIX} stdcall {$ELSE} cdecl {$ENDIF};\n  TSybdbtabbrowse = function(Proc: PDBPROCESS; TabNum: Integer): LongBool; {$IFNDEF UNIX} stdcall {$ELSE} cdecl {$ENDIF};\n  TSybdbtabcount = function(Proc: PDBPROCESS): Integer; {$IFNDEF UNIX} stdcall {$ELSE} cdecl {$ENDIF};\n  TSybdbtabname = function(Proc: PDBPROCESS; Table: Integer): PAnsiChar; {$IFNDEF UNIX} stdcall {$ELSE} cdecl {$ENDIF};\n  TSybdbtabsource = function(Proc: PDBPROCESS; Column: Integer; TabNum: PInteger):\n    PAnsiChar; {$IFNDEF UNIX} stdcall {$ELSE} cdecl {$ENDIF};\n  TSybdbtsnewlen = function(Proc: PDBPROCESS): Integer; {$IFNDEF UNIX} stdcall {$ELSE} cdecl {$ENDIF};\n  TSybdbtsnewval = function(Proc: PDBPROCESS): PDBBINARY; {$IFNDEF UNIX} stdcall {$ELSE} cdecl {$ENDIF};\n  TSybdbtsput = function(Proc: PDBPROCESS; NewTs: PDBBINARY; NewTsName,\n    TabNum: Integer; TableName: PAnsiChar): RETCODE; {$IFNDEF UNIX} stdcall {$ELSE} cdecl {$ENDIF};\n  TSybdbtxptr = function(Proc: PDBPROCESS; Column: Integer): PDBBINARY; {$IFNDEF UNIX} stdcall {$ELSE} cdecl {$ENDIF};\n  TSybdbtxtimestamp = function(Proc: PDBPROCESS; Column: Integer): PDBBINARY; {$IFNDEF UNIX} stdcall {$ELSE} cdecl {$ENDIF};\n  TSybdbtxtsnewval = function(Proc: PDBPROCESS): PDBBINARY; {$IFNDEF UNIX} stdcall {$ELSE} cdecl {$ENDIF};\n  TSybdbtxtsput = function(Proc: PDBPROCESS; NewTxts: PDBBINARY; Column: Integer):\n    RETCODE; {$IFNDEF UNIX} stdcall {$ELSE} cdecl {$ENDIF};\n  TSybdbuse = function(Proc: PDBPROCESS; DbName: PAnsiChar): RETCODE; {$IFNDEF UNIX} stdcall {$ELSE} cdecl {$ENDIF};\n  TSybdbvarylen = function(Proc: PDBPROCESS; Column: Integer): LongBool; {$IFNDEF UNIX} stdcall {$ELSE} cdecl {$ENDIF};\n  TSybdbwillconvert = function(SrcType, DestType: Integer): LongBool; {$IFNDEF UNIX} stdcall {$ELSE} cdecl {$ENDIF};\n  TSybdbwritetext = function(Proc: PDBPROCESS; ObjName: PAnsiChar; TextPtr: PDBBINARY;\n    TextPtrLen: DBTINYINT; Timestamp: PDBBINARY; Log: LongBool; Size: DBINT;\n    Text: PByte): RETCODE; {$IFNDEF UNIX} stdcall {$ELSE} cdecl {$ENDIF};\n\n  TDBLibAPI = Record\n    dberrhandle           : Tdberrhandle;\n    dbmsghandle           : Tdbmsghandle;\n\n    dbprocerrhandle       : Tdbprocerrhandle;\n    dbprocmsghandle       : Tdbprocmsghandle;\n\n    { Two-phase commit functions }\n    abort_xact            : Tabort_xact;\n    build_xact_string     : Tbuild_xact_string;\n    close_commit          : Tclose_commit;\n    commit_xact           : Tcommit_xact;\n    open_commit           : Topen_commit;\n    remove_xact           : Tremove_xact;\n    scan_xact             : Tscan_xact;\n    start_xact            : Tstart_xact;\n    stat_xact             : Tstat_xact;\n\n  { BCP functions }\n    bcp_batch             : Tbcp_batch;\n    bcp_bind              : Tbcp_bind;\n    bcp_colfmt            : Tbcp_colfmt;\n    bcp_collen            : Tbcp_collen;\n    bcp_colptr            : Tbcp_colptr;\n    bcp_columns           : Tbcp_columns;\n    bcp_control           : Tbcp_control;\n    bcp_done              : Tbcp_done;\n    bcp_exec              : Tbcp_exec;\n    bcp_init              : Tbcp_init;\n    bcp_moretext          : Tbcp_moretext;\n    bcp_readfmt           : Tbcp_readfmt;\n    bcp_sendrow           : Tbcp_sendrow;\n    bcp_setl              : Tbcp_setl;\n    bcp_writefmt          : Tbcp_writefmt;\n    dbadata               : Tdbadata;\n    dbadlen               : Tdbadlen;\n    dbaltbind             : Tdbaltbind;\n    dbaltcolid            : Tdbaltcolid;\n    dbaltlen              : Tdbaltlen;\n    dbaltop               : Tdbaltop;\n    dbalttype             : Tdbalttype;\n    dbaltutype            : Tdbaltutype;\n    dbanullbind           : Tdbanullbind;\n    dbbind                : Tdbbind;\n    dbbylist              : Tdbbylist;\n    dbcancel              : Tdbcancel;\n    dbcanquery            : Tdbcanquery;\n    dbchange              : Tdbchange;\n    dbclrbuf              : Tdbclrbuf;\n    dbclropt              : Tdbclropt;\n    dbcmd                 : Tdbcmd;\n    dbcmdrow              : Tdbcmdrow;\n    dbcollen              : Tdbcollen;\n    dbcolname             : Tdbcolname;\n    dbcolsource           : Tdbcolsource;\n    dbcoltype             : Tdbcoltype;\n    dbcolutype            : Tdbcolutype;\n    dbconvert             : Tdbconvert;\n    dbcurcmd              : Tdbcurcmd;\n    dbcurrow              : Tdbcurrow;\n    dbcursor              : Tdbcursor;\n    dbdata                : Tdbdata;\n    dbexit                : Tdbexit;\n    dbfcmd                : Tdbfcmd;\n    dbfirstrow            : Tdbfirstrow;\n    dbfreebuf             : Tdbfreebuf;\n    dbfreequal            : Tdbfreequal;\n    dbgetchar             : Tdbgetchar;\n    dbgetoff              : Tdbgetoff;\n    dbgetrow              : Tdbgetrow;\n    dbgettime             : Tdbgettime;\n    dbiscount             : Tdbiscount;\n    dblastrow             : Tdblastrow;\n    dblogin               : Tdblogin;\n    dbmorecmds            : Tdbmorecmds;\n    dbmoretext            : Tdbmoretext;\n    dbname                : Tdbname;\n    dbnextrow             : Tdbnextrow;\n    dbnullbind            : Tdbnullbind;\n    dbnumalts             : Tdbnumalts;\n    dbnumcols             : Tdbnumcols;\n    dbnumcompute          : Tdbnumcompute;\n    dbnumorders           : Tdbnumorders;\n    dbnumrets             : Tdbnumrets;\n    dbopen                : Tdbopen;\n    dbordercol            : Tdbordercol;\n    dbprhead              : Tdbprhead;\n    dbprrow               : Tdbprrow;\n    dbprtype              : Tdbprtype;\n    dbqual                : Tdbqual;\n    dbreadtext            : Tdbreadtext;\n    dbresults             : Tdbresults;\n    dbretdata             : Tdbretdata;\n    dbretlen              : Tdbretlen;\n    dbretname             : Tdbretname;\n    dbretstatus           : Tdbretstatus;\n    dbrettype             : Tdbrettype;\n    dbrows                : Tdbrows;\n    dbrowtype             : Tdbrowtype;\n    dbrpcinit             : Tdbrpcinit;\n    dbrpcparam            : Tdbrpcparam;\n    dbrpcsend             : Tdbrpcsend;\n    dbrpwclr              : Tdbrpwclr;\n    dbsetavail            : Tdbsetavail;\n    dbsetlname            : Tdbsetlname;\n    dbsetlogintime        : Tdbsetlogintime;\n    dbsetnull             : Tdbsetnull;\n    dbsettime             : Tdbsettime;\n    dbsetuserdata         : Tdbsetuserdata;\n    dbsqlexec             : Tdbsqlexec;\n    dbsqlok               : Tdbsqlok;\n    dbsqlsend             : Tdbsqlsend;\n    dbstrcpy              : Tdbstrcpy;\n    dbstrlen              : Tdbstrlen;\n    dbtabcount            : Tdbtabcount;\n    dbtabname             : Tdbtabname;\n    dbtabsource           : Tdbtabsource;\n    dbtsnewlen            : Tdbtsnewlen;\n    dbtsnewval            : Tdbtsnewval;\n    dbtsput               : Tdbtsput;\n    dbtxptr               : Tdbtxptr;\n    dbtxtimestamp         : Tdbtxtimestamp;\n    dbtxtsnewval          : Tdbtxtsnewval;\n    dbtxtsput             : Tdbtxtsput;\n    dbuse                 : Tdbuse;\n    dbwritetext           : Tdbwritetext;\n  End;\n\n  TFreeTDSAPI = Record\n  {available but not implemented}\n    db12hour:       TFreeTDSdb12hour; {no MS}\n    dbcolbrowse:    TFreeTDSdbcolbrowse;\n    dbcursorbind:   TFreeTDSdbcursorbind;\n    dbcursorclose:  TFreeTDSdbcursorclose;\n    dbcursorcolinfo:TFreeTDSdbcursorcolinfo;\n    dbcursorfetch:  TFreeTDSdbcursorfetch;\n    dbcursorinfo:   TFreeTDSdbcursorinfo;\n\n\n    dbaltbind_ps:   TFreeTDSdbaltbind_ps;\n    dbbind_ps:      TFreeTDSdbbind_ps;\n    dbbufsize:      TFreeTDSdbbufsize;\n    dbclose:        TFreeTDSdbclose;\n    dbtablecolinfo: TFreeTDSdbtablecolinfo;\n    dbcolinfo:      TFreeTDSdbcolinfo;\n    dbconvert_ps:   TFreeTDSdbconvert_ps;\n    dbcount:        TFreeTDSdbcount;\n    dbdatecmp:      TFreeTDSdbdatecmp;\n    dbdatecrack:    TFreeTDSdbdatecrack;\n    dbdatlen:       TFreeTDSdbdatlen;\n    dbdead:         TFreeTDSdbdead;\n\n    dbgetcharset:   TFreeTDSdbgetcharset;\n    dbgetlusername: TFreeTDSdbgetlusername;\n    dbgetmaxprocs:  TMsSQLdbgetmaxprocs;\n    dbgetnatlanf:   TFreeTDSdbgetnatlanf;\n    dbgetpacket:    TFreeTDSdbgetpacket;\n    dbgetuserdata:  TFreeTDSdbgetuserdata;\n    dbhasretstat:   TFreeTDSdbhasretstat;\n    dbinit:         TFreeTDSdbinit;\n    dbiordesc:      TFreeTDSdbiordesc;\n    dbiowdesc:      TFreeTDSdbiowdesc;\n    dbisavail:      TFreeTDSdbisavail;\n    dbisopt:        TFreeTDSdbisopt;\n    dbloginfree:    TFreeTDSdbloginfree;\n    dbmny4cmp:      TFreeTDSdbmny4cmp;\n    dbmnycmp:       TFreeTDSdbmnycmp;\n    dbmny4add:      TFreeTDSdbmny4add;\n    dbmnydec:       TFreeTDSdbmnydec;\n    dbmnyinc:       TFreeTDSdbmnyinc;\n    dbmnymaxpos:    TFreeTDSdbmnymaxpos;\n    dbmnymaxneg:    TFreeTDSdbmnymaxneg;\n    dbmny4minus:    TFreeTDSdbmny4minus;\n    dbmnyminus:     TFreeTDSdbmnyminus;\n    dbmny4sub:      TFreeTDSdbmny4sub;\n    dbmnysub:       TFreeTDSdbmnysub;\n    dbmny4copy:     TFreeTDSdbmny4copy;\n    dbmnycopy:      TFreeTDSdbmnycopy;\n    dbmny4zero:     TFreeTDSdbmny4zero;\n    dbmnyzero:      TFreeTDSdbmnyzero;\n    dbmonthname:    TFreeTDSdbmonthname;\n    tdsdbopen:      TFreeTDSdbopen;\n\n  { pivot functions */\n  void dbpivot_count (struct col_t *output, const struct col_t *input);\n  void dbpivot_sum (struct col_t *output, const struct col_t *input);\n  void dbpivot_min (struct col_t *output, const struct col_t *input);\n  void dbpivot_max (struct col_t *output, const struct col_t *input);\n\n  struct pivot_t;\n  typedef void (*DBPIVOT_FUNC)(struct col_t *output, const struct col_t *input);\n  struct pivot_t * dbrows_pivoted(DBPROCESS *dbproc);\n  STATUS dbnextrow_pivoted(DBPROCESS *dbproc, struct pivot_t *pp);\n  RETCODE dbpivot(DBPROCESS *dbproc, int nkeys, int *keys, int ncols, int *cols, DBPIVOT_FUNC func, int val);\n\n  DBPIVOT_FUNC dbpivot_lookup_name( const char name[] );\n  }\n    DRBUF:          TDRBUF;\n    dbrecftos:      TFreeTDSdbrecftos;\n    dbresults_r:    TFreeTDSdbresults_r;\n    dbsafestr:      TFreeTDSdbsafestr;\n    //dbsechandle:    TFreeTDSdbsechandle;\n    dbservcharset:  TFreeTDSdbservcharset;\n    //dbsetbusy:      TFreeTDSdbsetbusy;\n    dbsetdefcharset:TFreeTDSdbsetdefcharset;\n    dbsetifile:     TFreeTDSdbsetifile;\n    //dbsetinterrupt: TFreeTDSdbsetinterrupt;\n    dbsetmaxprocs:  TMsSQLdbsetmaxprocs;\n    dbsetopt:       TFreeTDSdbsetopt;\n    dbsetrow:       TFreeTDSdbsetrow;\n    dbsetversion:   TFreeTDSdbsetversion;\n    dbspid:         TFreeTDSdbspid;\n    dbspr1row:      TFreeTDSdbspr1row;\n    dbspr1rowlen:   TFreeTDSdbspr1rowlen;\n    dbsprhead:      TFreeTDSdbsprhead;\n    dbsprline:      TFreeTDSdbsprline;\n    dbvarylen:      TFreeTDSdbvarylen;\n\n    dbtds:          TFreeTDSdbtds;\n    dbtextsize:     TFreeTDSdbtextsize;\n    dbwillconvert:  TFreeTDSdbwillconvert;\n    dbsetlbool:     TFreeTDSdbsetlbool;\n    dbsetllong:     TFreeTDSdbsetllong;\n    dbsetlversion:  TFreeTDSdbsetlversion;\n\n    tdsdump_on            : Ttdsdump_on;\n    tdsdump_off           : Ttdsdump_off;\n    tdsdump_open          : Ttdsdump_open;\n    tdsdump_close         : Ttdsdump_close;\n    _tds_socket_init      : T_tds_socket_init;\n    _tds_socket_done      : T_tds_socket_done;\n  End;\n\n  TMsSQLAPI = record\n\n  { Standard DB-Library functions }\n    dbclose               : TMsSQLdbclose;\n    dbcolbrowse           : TMsSQLdbcolbrowse;\n    dbcolinfo             : TMsSQLdbcolinfo;\n    dbcount               : TMsSQLdbcount;\n\n    dbcursorbind          : TMsSQLdbcursorbind;\n    dbcursorclose         : TMsSQLdbcursorclose;\n    dbcursorcolinfo       : TMsSQLdbcursorcolinfo;\n    dbcursorfetch         : TMsSQLdbcursorfetch;\n    dbcursorfetchex       : TMsSQLdbcursorfetchex;\n    dbcursorinfo          : TMsSQLdbcursorinfo;\n    dbcursorinfoex        : TMsSQLdbcursorinfoex;\n    dbcursoropen          : TMsSQLdbcursoropen;\n    dbdataready           : TMsSQLdbdataready;\n    dbdatecrack           : TMsSQLdbdatecrack;\n    dbdatlen              : TMsSQLdbdatlen;\n    dbdead                : TMsSQLdbdead;\n    dbWinexit             : TMsSQLdbWinexit;\n    dbenlisttrans         : TMsSQLdbenlisttrans;\n    dbenlistxatrans       : TMsSQLdbenlistxatrans;\n    dbfreelogin           : TMsSQLdbfreelogin;\n    dbgetmaxprocs         : TMsSQLdbgetmaxprocs;\n    dbgetpacket           : TMsSQLdbgetpacket;\n    dbgetuserdata         : TMsSQLdbgetuserdata;\n    dbhasretstat          : TMsSQLdbhasretstat;\n    dbinit                : TMsSQLdbinit;\n    dbisavail             : TMsSQLdbisavail;\n    dbisopt               : TMsSQLdbisopt;\n    dbprocinfo            : TMsSQLdbprocinfo;\n    dbrpcexec             : TMsSQLdbrpcexec;\n    dbserverenum          : TMsSQLdbserverenum;\n    dbsetmaxprocs         : TMsSQLdbsetmaxprocs;\n    dbsetlpacket          : TMsSQLdbsetlpacket;\n    dbsetopt              : TMsSQLdbsetopt;\n    dbtabbrowse           : TMsSQLdbtabbrowse;\n    dbvarylen             : TMsSQLdbvarylen;\n    dbwillconvert         : TMsSQLdbwillconvert;\n    dbupdatetext          : TMsSQLdbupdatetext;\n  end;\n\n  TSybaseAPI = record\n    db12hour              : TSybdb12hour;\n\n    dberrhandle           : TSybdberrhandle;\n    dbmsghandle           : TSybdbmsghandle;\n\n    { Two-phase commit functions }\n    abort_xact            : TSybabort_xact;\n    build_xact_string     : TSybbuild_xact_string;\n    close_commit          : TSybclose_commit;\n    commit_xact           : TSybcommit_xact;\n    open_commit           : TSybopen_commit;\n    remove_xact           : TSybremove_xact;\n    scan_xact             : TSybscan_xact;\n    start_xact            : TSybstart_xact;\n    stat_xact             : TSybstat_xact;\n\n  { BCP functions }\n    bcp_batch             : TSybbcp_batch;\n    bcp_bind              : TSybbcp_bind;\n    bcp_colfmt            : TSybbcp_colfmt;\n    bcp_collen            : TSybbcp_collen;\n    bcp_colptr            : TSybbcp_colptr;\n    bcp_columns           : TSybbcp_columns;\n    bcp_control           : TSybbcp_control;\n    bcp_done              : TSybbcp_done;\n    bcp_exec              : TSybbcp_exec;\n    bcp_init              : TSybbcp_init;\n    bcp_moretext          : TSybbcp_moretext;\n    bcp_readfmt           : TSybbcp_readfmt;\n    bcp_sendrow           : TSybbcp_sendrow;\n    bcp_writefmt          : TSybbcp_writefmt;\n\n  { Standard DB-Library functions }\n    dbadata               : TSybdbadata;\n    dbadlen               : TSybdbadlen;\n    dbaltbind             : TSybdbaltbind;\n    dbaltcolid            : TSybdbaltcolid;\n    dbaltlen              : TSybdbaltlen;\n    dbaltop               : TSybdbaltop;\n    dbalttype             : TSybdbalttype;\n    dbaltutype            : TSybdbaltutype;\n    dbanullbind           : TSybdbanullbind;\n    dbbind                : TSybdbbind;\n    dbbylist              : TSybdbbylist;\n    dbcancel              : TSybdbcancel;\n    dbcanquery            : TSybdbcanquery;\n    dbchange              : TSybdbchange;\n    dbclose               : TSybdbclose;\n    dbclrbuf              : TSybdbclrbuf;\n    dbclropt              : TSybdbclropt;\n    dbcmd                 : TSybdbcmd;\n    dbcmdrow              : TSybdbcmdrow;\n    dbcolbrowse           : TSybdbcolbrowse;\n    dbcollen              : TSybdbcollen;\n    dbcolname             : TSybdbcolname;\n    dbcolsource           : TSybdbcolsource;\n  //  dbcoltypeinfo         : TSybdbcoltypeinfo;\n    dbcoltype             : TSybdbcoltype;\n    dbcolutype            : TSybdbcolutype;\n    dbconvert             : TSybdbconvert;\n    dbcount               : TSybdbcount;\n    dbcurcmd              : TSybdbcurcmd;\n    dbcurrow              : TSybdbcurrow;\n\n    dbcursor              : TSybdbcursor;\n    dbcursorbind          : TSybdbcursorbind;\n    dbcursorclose         : TSybdbcursorclose;\n    dbcursorcolinfo       : TSybdbcursorcolinfo;\n    dbcursorfetch         : TSybdbcursorfetch;\n    dbcursorinfo          : TSybdbcursorinfo;\n    dbcursoropen          : TSybdbcursoropen;\n    dbdata                : TSybdbdata;\n    dbdatecrack           : TSybdbdatecrack;\n    dbdatlen              : TSybdbdatlen;\n    dbdead                : TSybdbdead;\n    dbexit                : TSybdbexit;\n    dbfcmd                : TSybdbfcmd;\n    dbfirstrow            : TSybdbfirstrow;\n    dbfreebuf             : TSybdbfreebuf;\n    dbloginfree           : TSybdbloginfree;\n    dbfreequal            : TSybdbfreequal;\n    dbgetchar             : TSybdbgetchar;\n    dbgetmaxprocs         : TSybdbgetmaxprocs;\n    dbgetoff              : TSybdbgetoff;\n    dbgetpacket           : TSybdbgetpacket;\n    dbgetrow              : TSybdbgetrow;\n    dbgetuserdata         : TSybdbgetuserdata;\n    dbhasretstat          : TSybdbhasretstat;\n    dbinit                : TSybdbinit;\n    dbisavail             : TSybdbisavail;\n    dbisopt               : TSybdbisopt;\n    dblastrow             : TSybdblastrow;\n    dblogin               : TSybdblogin;\n    dbmorecmds            : TSybdbmorecmds;\n    dbmoretext            : TSybdbmoretext;\n    dbname                : TSybdbname;\n    dbnextrow             : TSybdbnextrow;\n    dbnullbind            : TSybdbnullbind;\n    dbnumalts             : TSybdbnumalts;\n    dbnumcols             : TSybdbnumcols;\n    dbnumcompute          : TSybdbnumcompute;\n    dbnumorders           : TSybdbnumorders;\n    dbnumrets             : TSybdbnumrets;\n    dbopen                : TSybdbopen;\n    dbordercol            : TSybdbordercol;\n    dbprhead              : TSybdbprhead;\n    dbprrow               : TSybdbprrow;\n    dbprtype              : TSybdbprtype;\n    dbqual                : TSybdbqual;\n    dbreadtext            : TSybdbreadtext;\n    dbresults             : TSybdbresults;\n    dbretdata             : TSybdbretdata;\n    dbretlen              : TSybdbretlen;\n    dbretname             : TSybdbretname;\n    dbretstatus           : TSybdbretstatus;\n    dbrettype             : TSybdbrettype;\n    dbrows                : TSybdbrows;\n    dbrowtype             : TSybdbrowtype;\n    dbrpcinit             : TSybdbrpcinit;\n    dbrpcparam            : TSybdbrpcparam;\n    dbrpcsend             : TSybdbrpcsend;\n\n    dbrpwclr              : TSybdbrpwclr;\n    dbsetavail            : TSybdbsetavail;\n    dbsetmaxprocs         : TSybdbsetmaxprocs;\n    dbsetlname            : TSybdbsetlname;\n    dbsetlogintime        : TSybdbsetlogintime;\n\n    dbsetnull             : TSybdbsetnull;\n    dbsetopt              : TSybdbsetopt;\n    dbsettime             : TSybdbsettime;\n    dbsetuserdata         : TSybdbsetuserdata;\n    dbsqlexec             : TSybdbsqlexec;\n    dbsqlok               : TSybdbsqlok;\n    dbsqlsend             : TSybdbsqlsend;\n    dbstrcpy              : TSybdbstrcpy;\n    dbstrlen              : TSybdbstrlen;\n    dbtabbrowse           : TSybdbtabbrowse;\n    dbtabcount            : TSybdbtabcount;\n    dbtabname             : TSybdbtabname;\n    dbtabsource           : TSybdbtabsource;\n    dbtsnewlen            : TSybdbtsnewlen;\n    dbtsnewval            : TSybdbtsnewval;\n    dbtsput               : TSybdbtsput;\n    dbtxptr               : TSybdbtxptr;\n    dbtxtimestamp         : TSybdbtxtimestamp;\n    dbtxtsnewval          : TSybdbtxtsnewval;\n    dbtxtsput             : TSybdbtxtsput;\n    dbuse                 : TSybdbuse;\n    dbvarylen             : TSybdbvarylen;\n    dbwillconvert         : TSybdbwillconvert;\n    dbwritetext           : TSybdbwritetext;\n  end;\n\nimplementation\n\nend.\n"
  },
  {
    "path": "lib/zeosdbo/src/plain/ZPlainDbLibDriver.pas",
    "content": "{*********************************************************}\n{                                                         }\n{                 Zeos Database Objects                   }\n{      Delphi plain driver interface to DBLibrary         }\n{                                                         }\n{        Originally written by Janos Fegyverneki          }\n{         FreeTDS supportd by Bogdan Dragulin             }\n{                                                         }\n{*********************************************************}\n\n{@********************************************************}\n{    Copyright (c) 1999-2012 Zeos Development Group       }\n{                                                         }\n{ License Agreement:                                      }\n{                                                         }\n{ This library is distributed in the hope that it will be }\n{ useful, but WITHOUT ANY WARRANTY; without even the      }\n{ implied warranty of MERCHANTABILITY or FITNESS FOR      }\n{ A PARTICULAR PURPOSE.  See the GNU Lesser General       }\n{ Public License for more details.                        }\n{                                                         }\n{ The source code of the ZEOS Libraries and packages are  }\n{ distributed under the Library GNU General Public        }\n{ License (see the file COPYING / COPYING.ZEOS)           }\n{ with the following  modification:                       }\n{ As a special exception, the copyright holders of this   }\n{ library give you permission to link this library with   }\n{ independent modules to produce an executable,           }\n{ regardless of the license terms of these independent    }\n{ modules, and to copy and distribute the resulting       }\n{ executable under terms of your choice, provided that    }\n{ you also meet, for each linked independent module,      }\n{ the terms and conditions of the license of that module. }\n{ An independent module is a module which is not derived  }\n{ from or based on this library. If you modify this       }\n{ library, you may extend this exception to your version  }\n{ of the library, but you are not obligated to do so.     }\n{ If you do not wish to do so, delete this exception      }\n{ statement from your version.                            }\n{                                                         }\n{                                                         }\n{ The project web site is located on:                     }\n{   http://zeos.firmos.at  (FORUM)                        }\n{   http://sourceforge.net/p/zeoslib/tickets/ (BUGTRACKER)}\n{   svn://svn.code.sf.net/p/zeoslib/code-0/trunk (SVN)    }\n{                                                         }\n{   http://www.sourceforge.net/projects/zeoslib.          }\n{                                                         }\n{                                                         }\n{                                 Zeos Development Group. }\n{********************************************************@}\n\nunit ZPlainDbLibDriver;\n\ninterface\n\n{$I ZPlain.inc}\n\nuses Classes, ZCompatibility, ZPlainDriver, ZPlainDbLibConstants;\n\nconst\n  NTWDBLIB_DLL_LOCATION ='ntwdblib.dll';\n  LIBSYBDB_WINDOWS_DLL_LOCATION = 'libsybdb.dll';\n  LIBSYBDB_LINUX_DLL_LOCATION = 'libsybdb.so';\n  FREETDS_MSSQL_WINDOWS_DLL_LOCATION = 'msdblibr.dll';\n  FREETDS_LINUX_DLL_LOCATION = 'dblib.so';\n  FREETDS_OSX_DLL_LOCATION = 'dblib.dylib';\n  FREETDS_SYBASE_WINDOWS_DLL_LOCATION = 'sybdblibd.dll';\ntype\n  {** Represents a generic interface to DBLIB native API. }\n  IZDBLibPlainDriver = interface (IZPlainDriver)\n    ['{7731C3B4-0608-4B6B-B089-240AC43A3463}']\n\n    procedure CheckError(dbProc: PDBPROCESS);\n\n    function dbDead(dbProc: PDBPROCESS): Boolean;\n    function dbLogin: PLOGINREC;\n    procedure dbLoginFree(Login: PLOGINREC);\n    function dbSetLoginTime(Seconds: DBINT): RETCODE;\n    function dbsetLName(Login: PLOGINREC; Value: PAnsiChar; Item: DBINT): RETCODE;\n    function dbSetLHost(Login: PLOGINREC; HostName: PAnsiChar): RETCODE;\n    function dbSetLUser(Login: PLOGINREC; UserName: PAnsiChar): RETCODE;\n    function dbSetLPwd(Login: PLOGINREC; Password: PAnsiChar): RETCODE;\n    function dbSetLApp(Login: PLOGINREC; AppName: PAnsiChar): RETCODE;\n    function dbSetLNatLang(Login: PLOGINREC; NatLangName: PAnsiChar): RETCODE;\n    function dbSetLCharSet(Login: PLOGINREC; CharsetName: PAnsiChar): RETCODE;\n    function dbSetLSecure(Login: PLOGINREC): RETCODE;\n    function dbSetMaxprocs(MaxProcs: SmallInt): RETCODE;\n    function dbOpen(Login: PLOGINREC; Host: PAnsiChar): PDBPROCESS;\n    function dbCancel(dbProc: PDBPROCESS): RETCODE;\n    function dbCmd(dbProc: PDBPROCESS; Cmd: PAnsiChar): RETCODE;\n    function dbSqlExec(dbProc: PDBPROCESS; Async: Boolean=False): RETCODE;\n    function dbSqlExecSync(dbProc: PDBPROCESS): RETCODE;\n    function dbSqlExecAsync(dbProc: PDBPROCESS): RETCODE;\n    function dbResults(dbProc: PDBPROCESS): RETCODE;\n    function dbCanQuery(dbProc: PDBPROCESS): RETCODE;\n    function dbMoreCmds(dbProc: PDBPROCESS): RETCODE;\n    function dbUse(dbProc: PDBPROCESS; dbName: PAnsiChar): RETCODE;\n    function dbSetOpt(dbProc: PDBPROCESS; Option: DBINT;\n      Char_Param: PAnsiChar = nil; Int_Param: DBINT = -1): RETCODE;\n    function dbClose(dbProc: PDBPROCESS): RETCODE;\n    function dbName(dbProc: PDBPROCESS): PAnsiChar;\n    function dbCmdRow(dbProc: PDBPROCESS): RETCODE;\n    function dbNumCols(dbProc: PDBPROCESS): DBINT;\n    function dbColName(dbProc: PDBPROCESS; Column: DBINT): PAnsiChar;\n    function dbColType(dbProc: PDBPROCESS; Column: DBINT): DBINT;\n    function dbColLen(dbProc: PDBPROCESS; Column: DBINT): DBInt;\n    function dbData(dbProc: PDBPROCESS; Column: DBINT): PByte;\n    function dbDatLen(dbProc: PDBPROCESS; Column: DBINT): DBINT;\n    function dbConvert(dbProc: PDBPROCESS; SrcType: DBINT; Src: PByte;\n      SrcLen: DBINT; DestType: DBINT; Dest: PByte; DestLen: DBINT): DBINT;\n    function dbNextRow(dbProc: PDBPROCESS): STATUS;\n    function dbGetRow(dbProc: PDBPROCESS; Row: DBINT): STATUS;\n    function dbCount(dbProc: PDBPROCESS): DBINT;\n\n    function dbRpcInit(dbProc: PDBPROCESS; RpcName: PAnsiChar; Options: SmallInt): RETCODE;\n    function dbRpcParam(dbProc: PDBPROCESS; ParamName: PAnsiChar; Status: Byte;\n      Type_: DBINT; MaxLen: DBINT; DataLen: DBINT; Value: Pointer): RETCODE;\n    function dbRpcSend(dbProc: PDBPROCESS): RETCODE;\n    function dbRpcExec(dbProc: PDBPROCESS): RETCODE;\n    function dbRetStatus(dbProc: PDBPROCESS): DBINT;\n    function dbHasRetStat(dbProc: PDBPROCESS): Boolean;\n    function dbRetName(dbProc: PDBPROCESS; RetNum: DBINT): PAnsiChar;\n    function dbRetData(dbProc: PDBPROCESS; RetNum: DBINT): Pointer;\n    function dbRetLen(dbProc: PDBPROCESS; RetNum: DBINT): DBINT;\n    function dbRetType(dbProc: PDBPROCESS; RetNum: DBINT): DBINT;\n    function dbdataready(Proc: PDBPROCESS): LongBool;\n    function GetVariables: TDBVariables;\n  end;\n\n  TZDBLibAbstractPlainDriver = class(TZAbstractPlainDriver, IZPlainDriver)\n  protected\n    DBVariables: TDBVariables;\n  public\n    function dbDead(dbProc: PDBPROCESS): Boolean; virtual; abstract;\n    procedure dbLoginFree(Login: PLOGINREC); virtual; abstract;\n    constructor Create; virtual;\n    procedure CheckError(dbProc: PDBPROCESS);\n    function GetVariables: TDBVariables;\n  end;\n\n  TZDbLibBasePlainDriver = class(TZDBLibAbstractPlainDriver, IZPlainDriver,\n    IZDBLibPlainDriver)\n  protected\n    DBLibAPI: TDBLibAPI;\n  public\n    procedure LoadApi; override;\n    function dbLogin: PLOGINREC; virtual;\n    function dbSetLoginTime(Seconds: DBINT): RETCODE;\n    function dbsetLName(Login: PLOGINREC; Value: PAnsiChar; Item: DBINT): RETCODE;\n    function dbSetLHost(Login: PLOGINREC; HostName: PAnsiChar): RETCODE;\n    function dbSetLUser(Login: PLOGINREC; UserName: PAnsiChar): RETCODE;\n    function dbSetLPwd(Login: PLOGINREC; Password: PAnsiChar): RETCODE;\n    function dbSetLApp(Login: PLOGINREC; AppName: PAnsiChar): RETCODE;\n    function dbSetLNatLang(Login: PLOGINREC; NatLangName: PAnsiChar): RETCODE;\n    function dbSetLCharSet(Login: PLOGINREC; CharsetName: PAnsiChar): RETCODE; virtual; abstract;\n    function dbSetLSecure(Login: PLOGINREC): RETCODE; virtual; abstract;\n    function dbSetMaxprocs(MaxProcs: SmallInt): RETCODE; virtual; abstract;\n    function dbOpen(Login: PLOGINREC; Host: PAnsiChar): PDBPROCESS; virtual;\n    function dbCancel(dbProc: PDBPROCESS): RETCODE;\n    function dbCmd(dbProc: PDBPROCESS; Cmd: PAnsiChar): RETCODE;\n    function dbSqlExec(dbProc: PDBPROCESS; Async: Boolean=False): RETCODE;\n    function dbSqlExecSync(dbProc: PDBPROCESS): RETCODE;\n    function dbSqlExecAsync(dbProc: PDBPROCESS): RETCODE;\n    function dbResults(dbProc: PDBPROCESS): RETCODE;\n    function dbCanQuery(dbProc: PDBPROCESS): RETCODE;\n    function dbMoreCmds(dbProc: PDBPROCESS): RETCODE;\n    function dbUse(dbProc: PDBPROCESS; dbName: PAnsiChar): RETCODE;\n    function dbSetOpt(dbProc: PDBPROCESS; Option: DBINT; Char_Param: PAnsiChar = nil; Int_Param: DBINT = -1): RETCODE; virtual; abstract;\n    function dbClose(dbProc: PDBPROCESS): RETCODE; virtual; abstract;\n    function dbName(dbProc: PDBPROCESS): PAnsiChar;\n    function dbCmdRow(dbProc: PDBPROCESS): RETCODE;\n    function dbNumCols(dbProc: PDBPROCESS): DBINT;\n    function dbcolbrowse(Proc: PDBPROCESS; Column: Integer): LongBool; virtual; abstract;\n\n    function dbColName(dbProc: PDBPROCESS; Column: DBINT): PAnsiChar;\n    function dbColType(dbProc: PDBPROCESS; Column: DBINT): DBINT;\n    function dbColLen(dbProc: PDBPROCESS; Column: DBINT): DBInt;\n    function dbData(dbProc: PDBPROCESS; Column: DBINT): PByte;\n    function dbDatLen(dbProc: PDBPROCESS; Column: DBINT): DBINT; virtual; abstract;\n    function dbConvert(dbProc: PDBPROCESS; SrcType: DBINT; Src: PByte;\n             SrcLen: DBINT; DestType: DBINT; Dest: PByte; DestLen: DBINT): DBINT;\n    function dbNextRow(dbProc: PDBPROCESS): STATUS;\n    function dbGetRow(dbProc: PDBPROCESS; Row: DBINT): STATUS;\n    function dbCount(dbProc: PDBPROCESS): DBINT; virtual; abstract;\n\n    function dbRpcInit(dbProc: PDBPROCESS; RpcName: PAnsiChar; Options: SmallInt): RETCODE;\n    function dbRpcParam(dbProc: PDBPROCESS; ParamName: PAnsiChar; Status: Byte;\n      Type_: DBINT; MaxLen: DBINT; DataLen: DBINT; Value: Pointer): RETCODE; virtual;\n    function dbRpcSend(dbProc: PDBPROCESS): RETCODE;\n    function dbRpcExec(dbProc: PDBPROCESS): RETCODE;\n    function dbRetStatus(dbProc: PDBPROCESS): DBINT;\n    function dbHasRetStat(dbProc: PDBPROCESS): Boolean; virtual; abstract;\n    function dbRetName(dbProc: PDBPROCESS; RetNum: DBINT): PAnsiChar;\n    function dbRetData(dbProc: PDBPROCESS; RetNum: DBINT): Pointer;\n    function dbRetLen(dbProc: PDBPROCESS; RetNum: DBINT): DBINT;\n    function dbRetType(dbProc: PDBPROCESS; RetNum: DBINT): DBINT;\n    function dbdataready(Proc: PDBPROCESS): LongBool; virtual; abstract;\n    function dbrbuf(Proc: PDBPROCESS): DBINT;\n  end;\n\n  {** Implements a dblib driver for Sybase ASE 12.5 }\n  TZDBLibSybaseASE125PlainDriver = class (TZDBLibAbstractPlainDriver, IZPlainDriver,\n    IZDBLibPlainDriver)\n  private\n    SybaseAPI: TSybaseAPI;\n  protected\n    procedure LoadApi; override;\n    function Clone: IZPlainDriver; override;\n    procedure LoadCodePages; override;\n  public\n    constructor Create; override;\n    destructor Destroy; override;\n\n    function GetProtocol: string; override;\n    function GetDescription: string; override;\n\n    function dbDead(dbProc: PDBPROCESS): Boolean; override;\n    function dbLogin: PLOGINREC;\n    procedure dbLoginFree(Login: PLOGINREC); override;\n    function dbSetLoginTime(Seconds: DBINT): RETCODE;\n    function dbsetLName(Login: PLOGINREC; Value: PAnsiChar; Item: DBINT): RETCODE;\n    function dbSetLHost(Login: PLOGINREC; HostName: PAnsiChar): RETCODE;\n    function dbSetLUser(Login: PLOGINREC; UserName: PAnsiChar): RETCODE;\n    function dbSetLPwd(Login: PLOGINREC; Password: PAnsiChar): RETCODE;\n    function dbSetLApp(Login: PLOGINREC; AppName: PAnsiChar): RETCODE;\n    function dbSetLNatLang(Login: PLOGINREC; NatLangName: PAnsiChar): RETCODE;\n    function dbSetLCharSet(Login: PLOGINREC; CharsetName: PAnsiChar): RETCODE;\n    function dbSetLSecure(Login: PLOGINREC): RETCODE;\n    function dbSetMaxprocs(MaxProcs: SmallInt): RETCODE;\n    function dbOpen(Login: PLOGINREC; Host: PAnsiChar): PDBPROCESS;\n    function dbCancel(dbProc: PDBPROCESS): RETCODE;\n    function dbCmd(dbProc: PDBPROCESS; Cmd: PAnsiChar): RETCODE;\n    function dbSqlExec(dbProc: PDBPROCESS; Async: Boolean=False): RETCODE; virtual;\n    function dbSqlExecSync(dbProc: PDBPROCESS): RETCODE;\n    function dbSqlExecAsync(dbProc: PDBPROCESS): RETCODE;\n    function dbResults(dbProc: PDBPROCESS): RETCODE;\n    function dbCanQuery(dbProc: PDBPROCESS): RETCODE;\n    function dbMoreCmds(dbProc: PDBPROCESS): RETCODE;\n    function dbUse(dbProc: PDBPROCESS; dbName: PAnsiChar): RETCODE;\n    function dbSetOpt(dbProc: PDBPROCESS; Option: DBINT; Char_Param: PAnsiChar = nil; Int_Param: DBINT = -1): RETCODE;\n    function dbClose(dbProc: PDBPROCESS): RETCODE;\n    function dbName(dbProc: PDBPROCESS): PAnsiChar;\n    function dbCmdRow(dbProc: PDBPROCESS): RETCODE;\n    function dbNumCols(dbProc: PDBPROCESS): DBINT;\n    function dbcolbrowse(Proc: PDBPROCESS; Column: Integer): LongBool;\n\n    function dbColName(dbProc: PDBPROCESS; Column: DBINT): PAnsiChar;\n    function dbColType(dbProc: PDBPROCESS; Column: DBINT): DBINT;\n    function dbColLen(dbProc: PDBPROCESS; Column: DBINT): DBInt;\n    function dbData(dbProc: PDBPROCESS; Column: DBINT): PByte;\n    function dbDatLen(dbProc: PDBPROCESS; Column: DBINT): DBINT;\n    function dbConvert(dbProc: PDBPROCESS; SrcType: DBINT; Src: PByte;\n             SrcLen: DBINT; DestType: DBINT; Dest: PByte; DestLen: DBINT): DBINT;\n    function dbNextRow(dbProc: PDBPROCESS): STATUS;\n    function dbGetRow(dbProc: PDBPROCESS; Row: DBINT): STATUS;\n    function dbCount(dbProc: PDBPROCESS): DBINT;\n\n    function dbRpcInit(dbProc: PDBPROCESS; RpcName: PAnsiChar; Options: SmallInt): RETCODE;\n    function dbRpcParam(dbProc: PDBPROCESS; ParamName: PAnsiChar; Status: Byte;\n      Type_: DBINT; MaxLen: DBINT; DataLen: DBINT; Value: Pointer): RETCODE;\n    function dbRpcSend(dbProc: PDBPROCESS): RETCODE;\n    function dbRpcExec(dbProc: PDBPROCESS): RETCODE;\n    function dbRetStatus(dbProc: PDBPROCESS): DBINT;\n    function dbHasRetStat(dbProc: PDBPROCESS): Boolean;\n    function dbRetName(dbProc: PDBPROCESS; RetNum: DBINT): PAnsiChar;\n    function dbRetData(dbProc: PDBPROCESS; RetNum: DBINT): Pointer;\n    function dbRetLen(dbProc: PDBPROCESS; RetNum: DBINT): DBINT;\n    function dbRetType(dbProc: PDBPROCESS; RetNum: DBINT): DBINT;\n    function dbrbuf(Proc: PDBPROCESS): DBINT;\n    function dbdataready(Proc: PDBPROCESS): LongBool;\n  end;\n\n  {** Implements a dblib driver for MSSql7 }\n  TZDBLibMSSQL7PlainDriver = class (TZDbLibBasePlainDriver, IZPlainDriver,\n    IZDBLibPlainDriver)\n  private\n    MsSQLAPI: TMsSQLAPI;\n  protected\n    function Clone: IZPlainDriver; override;\n    procedure LoadCodePages; override;\n  public\n    procedure LoadApi; override;\n    constructor Create; override;\n    destructor Destroy; override;\n\n    function GetProtocol: string; override;\n    function GetDescription: string; override;\n\n    function dbDead(dbProc: PDBPROCESS): Boolean; override;\n    procedure dbLoginFree(Login: PLOGINREC); override;\n    function dbSetLCharSet(Login: PLOGINREC; CharsetName: PAnsiChar): RETCODE; override;\n    function dbSetLSecure(Login: PLOGINREC): RETCODE; override;\n    function dbSetMaxprocs(MaxProcs: SmallInt): RETCODE; override;\n    function dbSqlExecAsync(dbProc: PDBPROCESS): RETCODE;\n    function dbSetOpt(dbProc: PDBPROCESS; Option: DBINT; Char_Param: PAnsiChar = nil; Int_Param: DBINT = -1): RETCODE; override;\n    function dbClose(dbProc: PDBPROCESS): RETCODE; override;\n    function dbcolbrowse(Proc: PDBPROCESS; Column: Integer): LongBool; override;\n\n    function dbDatLen(dbProc: PDBPROCESS; Column: DBINT): DBINT; override;\n    function dbCount(dbProc: PDBPROCESS): DBINT; override;\n    function dbHasRetStat(dbProc: PDBPROCESS): Boolean; override;\n    function dbdataready(Proc: PDBPROCESS): LongBool; override;\n  end;\n\n  {** Implements a generic dblib driver}\n  IZFreeTDSPlainDriver = interface (IZDBLibPlainDriver)\n    ['{12FA5A22-59E5-4CBF-B745-96A7CDF9FBE0}']\n\n    function dbSetTime(queryTime : Integer): RETCODE;\n    procedure tdsDumpOn;\n    procedure tdsDumpOff;\n    procedure tdsDump_Open(const FileName: String);\n    procedure tdsDump_Close;\n\n  end;\n\n  {** Implements a dblib driver for Sybase/MSSQL }\n  TZFreeTDSBasePlainDriver = class (TZDbLibBasePlainDriver,\n    IZDBLibPlainDriver, IZFreeTDSPlainDriver)\n  private\n    FreeTDSAPI: TFreeTDSAPI;\n  protected\n    function Clone: IZPlainDriver; override; abstract;\n  public\n    constructor Create; override;\n    destructor Destroy; override;\n\n    procedure LoadApi; override;\n    function GetProtocol: string; override;\n    function GetDescription: string; override;\n\n    {API functions}\n    function dbsetlversion(Login: PLOGINREC): RETCODE; virtual;\n    function dbsetversion: RETCODE; virtual;\n\n\n    function dbDead(dbProc: PDBPROCESS): Boolean; override;\n    function dbLogin: PLOGINREC; override;\n    procedure dbLoginFree(Login: PLOGINREC); override;\n    function dbSetLCharSet(Login: PLOGINREC; CharsetName: PAnsiChar): RETCODE; override;\n    function dbSetLSecure(Login: PLOGINREC): RETCODE; override;\n    function dbSetMaxprocs(MaxProcs: SmallInt): RETCODE; override;\n    function dbSetTime(queryTime : Integer): RETCODE;\n\n    function dbSetOpt(dbProc: PDBPROCESS; Option: Integer;\n      Char_Param: PAnsiChar = nil; Int_Param: Integer = -1): RETCODE; override;\n    function dbClose(dbProc: PDBPROCESS): RETCODE; override;\n    function dbColInfo(dbProc: PDBPROCESS; Column: Integer; var ADBInfo: DBCOL): RETCODE;\n    function dbDatLen(dbProc: PDBPROCESS; Column: Integer): Integer; override;\n    function dbCount(dbProc: PDBPROCESS): Integer; override;\n    function dbcolbrowse(Proc: PDBPROCESS; Column: Integer): LongBool; override;\n\n    function dbHasRetStat(dbProc: PDBPROCESS): Boolean; override;\n\n    procedure tdsDumpOn;\n    procedure tdsDumpOff;\n    procedure tdsDump_Open(const FileName: String);\n    procedure tdsDump_Close;\n    function dbdataready(Proc: PDBPROCESS): LongBool; override;\n    procedure dbfreelogin(Login: PLOGINREC);\n  end;\n\n\n  TZFreeTDS42MsSQLPlainDriver = class(TZFreeTDSBasePlainDriver)\n  protected\n    function Clone: IZPlainDriver; override;\n    procedure LoadCodePages; override;\n  public\n    constructor Create; override;\n    function GetProtocol: string; override;\n    function GetDescription: string; override;\n    function dbsetlversion(Login: PLOGINREC): RETCODE; override;\n    function dbsetversion: RETCODE; override;\n  end;\n\n  TZFreeTDS42SybasePlainDriver = class(TZFreeTDSBasePlainDriver)\n  protected\n    function Clone: IZPlainDriver; override;\n    procedure LoadCodePages; override;\n  public\n    constructor Create; override;\n    function GetProtocol: string; override;\n    function GetDescription: string; override;\n    function dbsetlversion(Login: PLOGINREC): RETCODE; override;\n    function dbsetversion: RETCODE; override;\n  end;\n\n  TZFreeTDS50PlainDriver = class(TZFreeTDS42SybasePlainDriver)\n  protected\n    function Clone: IZPlainDriver; override;\n    procedure LoadCodePages; override;\n  public\n    constructor Create; override;\n    function GetProtocol: string; override;\n    function GetDescription: string; override;\n    function dbsetversion: RETCODE; override;\n  end;\n\n  TZFreeTDS70PlainDriver = class(TZFreeTDS42MsSQLPlainDriver)\n  protected\n    function Clone: IZPlainDriver; override;\n    procedure LoadCodePages; override;\n  public\n    function GetProtocol: string; override;\n    function GetDescription: string; override;\n    function dbsetlversion(Login: PLOGINREC): RETCODE; override;\n    function dbsetversion: RETCODE; override;\n  end;\n\n  TZFreeTDS71PlainDriver = class(TZFreeTDS70PlainDriver)\n  protected\n    function Clone: IZPlainDriver; override;\n    procedure LoadCodePages; override;\n  public\n    function GetProtocol: string; override;\n    function GetDescription: string; override;\n    function dbsetversion: RETCODE; override;\n  end;\n\n  TZFreeTDS72PlainDriver = class(TZFreeTDS70PlainDriver)\n  protected\n    function Clone: IZPlainDriver; override;\n    procedure LoadCodePages; override;\n  public\n    function GetProtocol: string; override;\n    function GetDescription: string; override;\n    function dbsetversion: RETCODE; override;\n  end;\n\n\nvar\n  OldFreeTDSErrorHandle: DBERRHANDLE_PROC = nil;\n  OldFreeTDSMessageHandle: DBMSGHANDLE_PROC = nil;\n  OldSybaseErrorHandle: SYBDBERRHANDLE_PROC = nil;\n  OldSybaseMessageHandle: SYBDBMSGHANDLE_PROC = nil;\n  OldMsSQLMessageHandle: DBMSGHANDLE_PROC = nil;\n  OldMsSQLErrorHandle: DBERRHANDLE_PROC = nil;\n  SQLErrors: TList;\n  SQLMessages: TList;\n\nimplementation\n\nuses SysUtils, ZPlainLoader, ZEncoding, {$IFDEF FPC}DOS{$ELSE}Windows{$ENDIF};\n\nprocedure AddSybaseCodePages(PlainDriver: TZAbstractPlainDriver);\nbegin\n  { MultiByte }\n  PlainDriver.AddCodePage('874THAIBIN', 1, ceAnsi, 874); {Windows Thailndisch, ISO8859-11, binre Sortierung}\n  PlainDriver.AddCodePage('932JPN', 2, ceAnsi, 932); {Japanese Shift-JIS mit Microsoft-Erweiterungen}\n  PlainDriver.AddCodePage('936ZHO', 3, ceAnsi, 936); {Vereinfachtes Chinesisch, PRC GBK}\n  PlainDriver.AddCodePage('949KOR', 4, ceAnsi, 949); {Korean KS C 5601-1987-Codierung, Wansung}\n  PlainDriver.AddCodePage('950ZHO_HK', 5, ceAnsi, 950); {Traditionelles Chinesisch, Big 5-Kodierung mit HKSCS}\n  PlainDriver.AddCodePage('950ZHO_TW', 6, ceAnsi, 950); {Traditionelles Chinesisch, Big 5-Kodierung}\n  PlainDriver.AddCodePage('EUC_CHINA', 21, ceAnsi, zCP_GB2312); {GB2312-80 Simplified Chinese}\n  PlainDriver.AddCodePage('EUC_JAPAN', 22, ceAnsi, zCP_SHIFTJS); {Japanisch EUC JIS X 0208-1990 und JIS X 0212-1990-Zeichensatz}\n  PlainDriver.AddCodePage('EUC_KOREA', 23, ceAnsi, 1361); { Koreanisch KS C 5601-1992 8-Bit-Zeichensatz, Johab}\n  PlainDriver.AddCodePage('EUC_TAIWAN', 24, ceAnsi, 964); {EUC-TW-Kodierung}\n  PlainDriver.AddCodePage('UCA', 29, ceUTF16, zCP_UTF16, 'utf8'); {UCA\tUCA-Standardkollatierung}\n  PlainDriver.AddCodePage('UTF8BIN', 30, ceUTF8, zCP_UTF8); {UTF-8, 8-Bit-Mehrbyte-Zeichensatz fr Unicode, binre Reihenfolge}\n\n  { SingleByte }\n  PlainDriver.AddCodePage('1250LATIN2', 7, ceAnsi, zCP_WIN1250); {Windows Latin 2, Mittel- und Osteuropa}\n  PlainDriver.AddCodePage('1250POL', 8, ceAnsi, zCP_WIN1251); {Windows Latin 2, Polnisch}\n  PlainDriver.AddCodePage('1251CYR', 9, ceAnsi, 1251); {Windows Kyrillisch}\n  PlainDriver.AddCodePage('1252LATIN1', 10, ceAnsi, 1252); { Windows Latin 1, Western}\n  PlainDriver.AddCodePage('1252LT1ACC', 11, ceAnsi, 1252); {Windows-Spezial Latin 1, Western, Zeichen mit Akzent nicht gleich}\n  PlainDriver.AddCodePage('1252NOR', 12, ceAnsi, 1252); {Windows Latin 1, Norwegisch}\n  PlainDriver.AddCodePage('1252SPA', 13, ceAnsi, 1252); {Windows Latin 1, Spanisch}\n  PlainDriver.AddCodePage('1252SWEFIN', 14, ceAnsi, 1252); {Windows Latin 1, Schwedisch/Finnisch}\n  PlainDriver.AddCodePage('1253ELL', 15, ceAnsi, 1253); {Windows Griechisch, ISO8859-7 mit Erweiterungen}\n  PlainDriver.AddCodePage('1254TRK', 16, ceAnsi, 1254); {Windows Trkisch, ISO8859-9 mit Erweiterungen}\n  PlainDriver.AddCodePage('1254TRKALT', 17, ceAnsi, 1254); {Windows Trkisch, ISO8859-9 mit Erweiterungen, I mit I-Punkt gleich I ohne I-Punkt}\n  PlainDriver.AddCodePage('1255HEB', 18, ceAnsi, 1255); {Windows Hebrisch, ISO8859-8 mit Erweiterungen}\n  PlainDriver.AddCodePage('1256ARA', 19, ceAnsi, 1256); {Windows Arabisch, ISO8859-6 mit Erweiterungen}\n  PlainDriver.AddCodePage('1257LIT', 20, ceAnsi, 1257); {Windows Baltische Staaten, Litauisch}\n  PlainDriver.AddCodePage('ISO1LATIN1', 25, ceAnsi, zCP_L1_ISO_8859_1); {ISO8859-1, ISO Latin 1, Western, Latin 1-Sortierreihenfolge}\n  PlainDriver.AddCodePage('ISO9LATIN1', 26, ceAnsi, zCP_L9_ISO_8859_15); {\tISO8859-15, ISO Latin 9, Western, Latin 1-Sortierreihenfolge}\n  PlainDriver.AddCodePage('ISO_1', 27, ceAnsi, zCP_L1_ISO_8859_1); {ISO8859-1, ISO Latin 1, Western}\n  PlainDriver.AddCodePage('ISO_BINENG', 28, ceAnsi, zCP_us_ascii); {Binre Sortierreihenfolge, Englisch ISO/ASCII 7-Bit-Zuordnung nach Gro- und Kleinschreibung}\nend;\n\nprocedure AddmMSCodePages(PlainDriver: TZAbstractPlainDriver);\nbegin\n  { SingleByte }\n  PlainDriver.AddCodePage('WIN1250', 1, ceAnsi, zCP_WIN1250); {Microsoft Windows Codepage 1250 (East European)}\n  PlainDriver.AddCodePage('WIN1251', 2, ceAnsi, zCP_WIN1251); {Microsoft Windows Codepage 1251 (Cyrl)}\n  PlainDriver.AddCodePage('WIN1252', 3, ceAnsi, zCP_WIN1252); {Microsoft Windows Codepage 1252 (ANSI), USASCCI}\n  PlainDriver.AddCodePage('WIN1253', 4, ceAnsi, zCP_WIN1253); {Microsoft Windows Codepage 1253 (Greek)}\n  PlainDriver.AddCodePage('WIN1254', 5, ceAnsi, zCP_WIN1254); {Microsoft Windows Codepage 1254 (Turk)}\n  PlainDriver.AddCodePage('WIN1255', 6, ceAnsi, zCP_WIN1255); {Microsoft Windows Codepage 1255 (Hebrew)}\n  PlainDriver.AddCodePage('WIN1256', 7, ceAnsi, cCP_WIN1256); {Microsoft Windows Codepage 1256 (Arab)}\n  PlainDriver.AddCodePage('WIN1257', 8, ceAnsi, zCP_WIN1257); {Microsoft Windows Codepage 1257 (BaltRim)}\n  PlainDriver.AddCodePage('WIN1258', 9, ceAnsi, zCP_WIN1258); {Microsoft Windows Codepage 1258 (Viet), TCVN-5712}\nend;\n\n{ Handle sql server error messages }\nfunction SybaseErrorHandle(Proc: PDBPROCESS; Severity, DbErr, OsErr: Integer;\n  DbErrStr, OsErrStr: PAnsiChar): Integer;\n{$IFNDEF UNIX} stdcall{$ELSE} cdecl{$ENDIF};\nvar\n  SqlError: PDBLibError;\nbegin\n  New(SqlError);\n  SqlError.dbProc := Proc;\n  SqlError.Severity := Severity;\n  SqlError.DbErr := DbErr;\n  SqlError.OsErr := OsErr;\n  SqlError.DbErrStr := DbErrStr;\n  SqlError.OsErrStr := OsErrStr;\n  SQLErrors.Add(SqlError);\n\n  Result := INT_CANCEL;\nend;\n\n{ Handle sql server messages }\nfunction SybaseMessageHandle(Proc: PDBPROCESS; MsgNo: DBINT; MsgState,\n    Severity: Integer; MsgText, SrvName, ProcName: PAnsiChar; Line: DBUSMALLINT):\n    Integer; {$IFNDEF UNIX} stdcall {$ELSE} cdecl {$ENDIF};\nvar\n  SQLMessage: PDBLibMessage;\nbegin\n  New(SQLMessage);\n  SQLMessage.dbProc := Proc;\n  SQLMessage.MsgNo := MsgNo;\n  SQLMessage.MsgState := MsgState;\n  SQLMessage.Severity := Severity;\n  SQLMessage.MsgText := MsgText;\n  SQLMessage.SrvName := SrvName;\n  SQLMessage.ProcName := ProcName;\n  SQLMessage.Line := Line;\n  SQLMessages.Add(SQLMessage);\n\n  Result := 0;\nend;\n\n{ Handle sql server error messages }\nfunction DbLibErrorHandle(Proc: PDBPROCESS; Severity, DbErr, OsErr: Integer;\n  DbErrStr, OsErrStr: PAnsiChar): Integer; cdecl;\nvar\n  SqlError: PDBLibError;\nbegin\n  New(SqlError);\n  SqlError.dbProc := Proc;\n  SqlError.Severity := Severity;\n  SqlError.DbErr := DbErr;\n  SqlError.OsErr := OsErr;\n  SqlError.DbErrStr := DbErrStr;\n  SqlError.OsErrStr := OsErrStr;\n  SQLErrors.Add(SqlError);\n\n  Result := INT_CANCEL;\nend;\n\n{ Handle sql server messages }\nfunction DbLibMessageHandle(Proc: PDBPROCESS; MsgNo: DBINT; MsgState, Severity: Integer;\n  MsgText, SrvName, ProcName: PAnsiChar; Line: DBUSMALLINT): Integer; cdecl;\nvar\n  SQLMessage: PDBLibMessage;\nbegin\n  New(SQLMessage);\n  SQLMessage.dbProc := Proc;\n  SQLMessage.MsgNo := MsgNo;\n  SQLMessage.MsgState := MsgState;\n  SQLMessage.Severity := Severity;\n  SQLMessage.MsgText := MsgText;\n  SQLMessage.SrvName := SrvName;\n  SQLMessage.ProcName := ProcName;\n  SQLMessage.Line := Line;\n  SQLMessages.Add(SQLMessage);\n\n  Result := 0;\nend;\n\nconstructor TZDBLibAbstractPlainDriver.Create;\nvar I: Integer;\nbegin\n  inherited create;\n  FLoader := TZNativeLibraryLoader.Create([]);\n  for i := 0 to high(DBVariables.DBoptions) do DBVariables.DBoptions[i] := -1;\n  for i := 0 to high(DBVariables.DBSetLoginRec) do DBVariables.DBSetLoginRec[i] := -1;\n  DBVariables.datatypes[Z_SQLVOID]      := DBLIBSQLVOID;\n  DBVariables.datatypes[Z_SQLTEXT]      := DBLIBSQLTEXT;\n  DBVariables.datatypes[Z_SQLVARBINARY] := DBLIBSQLVARBINARY;\n  DBVariables.datatypes[Z_SQLINTN]      := DBLIBSQLINTN;\n  DBVariables.datatypes[Z_SQLVARCHAR]   := DBLIBSQLVARCHAR;\n  DBVariables.datatypes[Z_SQLBINARY]    := DBLIBSQLBINARY;\n  DBVariables.datatypes[Z_SQLIMAGE]     := DBLIBSQLIMAGE;\n  DBVariables.datatypes[Z_SQLCHAR]      := DBLIBSQLCHAR;\n  DBVariables.datatypes[Z_SQLINT1]      := DBLIBSQLINT1;\n  DBVariables.datatypes[Z_SQLBIT]       := DBLIBSQLBIT;\n  DBVariables.datatypes[Z_SQLINT2]      := DBLIBSQLINT2;\n  DBVariables.datatypes[Z_SQLINT4]      := DBLIBSQLINT4;\n  DBVariables.datatypes[Z_SQLMONEY]     := DBLIBSQLMONEY;\n  DBVariables.datatypes[Z_SQLDATETIME]  := DBLIBSQLDATETIME;\n  DBVariables.datatypes[Z_SQLFLT8]      := DBLIBSQLFLT8;\n  DBVariables.datatypes[Z_SQLFLTN]      := DBLIBSQLFLTN;\n  DBVariables.datatypes[Z_SQLMONEYN]    := DBLIBSQLMONEYN;\n  DBVariables.datatypes[Z_SQLDATETIMN]  := DBLIBSQLDATETIMN;\n  DBVariables.datatypes[Z_SQLFLT4]      := DBLIBSQLFLT4;\n  DBVariables.datatypes[Z_SQLMONEY4]    := DBLIBSQLMONEY4;\n  DBVariables.datatypes[Z_SQLDATETIM4]  := DBLIBSQLDATETIM4;\n  DBVariables.datatypes[Z_SQLDECIMAL]   := DBLIBSQLDECIMAL;\n  DBVariables.datatypes[Z_SQLNUMERIC]   := DBLIBSQLNUMERIC;\nend;\n\nprocedure TZDBLibAbstractPlainDriver.CheckError(dbProc: Pointer);\nvar\n  I: Integer;\n  S: String;\n  lErrorEntry: PDBLibError;\n  lMesageEntry: PDBLibMessage;\n\n    procedure AddToErrorMsg(const AError: String);\n    begin\n      if S > '' then\n        S := S + #13#10;\n      S := S + AError;\n    end;\n\nbegin\n  if ((SQLErrors = nil) or (SQLErrors.Count = 0)) and\n     ((SQLMessages = nil) or (SQLMessages.Count = 0)) then\n    Exit;\n  S := '';\n  I := 0;\n  while I < SQLErrors.Count do begin\n    lErrorEntry := PDBLibError(SQLErrors[I]);\n    if (dbProc = nil) or (lErrorEntry^.dbProc = dbProc) or (lErrorEntry^.dbProc = nil) then begin\n        if lErrorEntry^.Severity > EXINFO then\n          AddToErrorMsg(Format('DBError : [%4.4d] : %s', [lErrorEntry^.DbErr, String(lErrorEntry^.DbErrStr)]) );\n        if lErrorEntry^.OsErr > EXINFO then\n          AddToErrorMsg(Format('OSError : [%4.4d] : %s', [lErrorEntry^.OsErr, String(lErrorEntry^.OsErrStr)]) );\n        Dispose(lErrorEntry);\n        SQLErrors.Delete(I);\n    end\n    else\n      Inc(I);\n  end;\n  I := 0;\n  while I < SQLMessages.Count do begin\n    lMesageEntry := PDBLibMessage(SQLMessages[I]);\n    if (dbProc = nil) or (lMesageEntry^.dbProc = dbProc) or (lMesageEntry^.dbProc = nil) then begin\n      if lMesageEntry^.Severity > EXINFO then\n        AddToErrorMsg(String(lMesageEntry^.MsgText));\n      Dispose(lMesageEntry);\n      SQLMessages.Delete(I);\n    end\n    else\n      Inc(I);\n  end;\n  if S <> '' then\n    raise Exception.Create(String(S));\nend;\n\nfunction TZDBLibAbstractPlainDriver.GetVariables: TDBVariables;\nbegin\n  Result := DBVariables;\nend;\n\n{ TZDBLibBasePlainDriver }\n\nprocedure TZDBLibBasePlainDriver.LoadApi;\nbegin\n  inherited LoadAPI;\n  with Loader do\n  begin\n    @DBLibAPI.dberrhandle           := GetAddress('dberrhandle');\n    @DBLibAPI.dbmsghandle           := GetAddress('dbmsghandle');\n    @DBLibAPI.dbprocerrhandle       := GetAddress('dbprocerrhandle');\n    @DBLibAPI.dbprocmsghandle       := GetAddress('dbprocmsghandle');\n    @DBLibAPI.abort_xact            := GetAddress('abort_xact');\n    @DBLibAPI.build_xact_string     := GetAddress('build_xact_string');\n    @DBLibAPI.close_commit          := GetAddress('close_commit');\n    @DBLibAPI.commit_xact           := GetAddress('commit_xact');\n    @DBLibAPI.open_commit           := GetAddress('open_commit');\n    @DBLibAPI.remove_xact           := GetAddress('remove_xact');\n    @DBLibAPI.scan_xact             := GetAddress('scan_xact');\n    @DBLibAPI.start_xact            := GetAddress('start_xact');\n    @DBLibAPI.stat_xact             := GetAddress('stat_xact');\n    @DBLibAPI.bcp_batch             := GetAddress('bcp_batch');\n    @DBLibAPI.bcp_bind              := GetAddress('bcp_bind');\n    @DBLibAPI.bcp_colfmt            := GetAddress('bcp_colfmt');\n    @DBLibAPI.bcp_collen            := GetAddress('bcp_collen');\n    @DBLibAPI.bcp_colptr            := GetAddress('bcp_colptr');\n    @DBLibAPI.bcp_columns           := GetAddress('bcp_columns');\n    @DBLibAPI.bcp_control           := GetAddress('bcp_control');\n    @DBLibAPI.bcp_done              := GetAddress('bcp_done');\n    @DBLibAPI.bcp_exec              := GetAddress('bcp_exec');\n    @DBLibAPI.bcp_init              := GetAddress('bcp_init');\n    @DBLibAPI.bcp_moretext          := GetAddress('bcp_moretext');\n    @DBLibAPI.bcp_readfmt           := GetAddress('bcp_readfmt');\n    @DBLibAPI.bcp_sendrow           := GetAddress('bcp_sendrow');\n    @DBLibAPI.bcp_setl              := GetAddress('bcp_setl');\n    @DBLibAPI.bcp_writefmt          := GetAddress('bcp_writefmt');\n    @DBLibAPI.dbadata               := GetAddress('dbadata');\n    @DBLibAPI.dbadlen               := GetAddress('dbadlen');\n    @DBLibAPI.dbaltbind             := GetAddress('dbaltbind');\n    @DBLibAPI.dbaltcolid            := GetAddress('dbaltcolid');\n    @DBLibAPI.dbaltlen              := GetAddress('dbaltlen');\n    @DBLibAPI.dbaltop               := GetAddress('dbaltop');\n    @DBLibAPI.dbalttype             := GetAddress('dbalttype');\n    @DBLibAPI.dbaltutype            := GetAddress('dbaltutype');\n    @DBLibAPI.dbanullbind           := GetAddress('dbanullbind');\n    @DBLibAPI.dbbind                := GetAddress('dbbind');\n    @DBLibAPI.dbbylist              := GetAddress('dbbylist');\n    @DBLibAPI.dbcancel              := GetAddress('dbcancel');\n    @DBLibAPI.dbcanquery            := GetAddress('dbcanquery');\n    @DBLibAPI.dbchange              := GetAddress('dbchange');\n    @DBLibAPI.dbclrbuf              := GetAddress('dbclrbuf');\n    @DBLibAPI.dbclropt              := GetAddress('dbclropt');\n    @DBLibAPI.dbcmd                 := GetAddress('dbcmd');\n    @DBLibAPI.dbcmdrow              := GetAddress('dbcmdrow');\n    @DBLibAPI.dbcollen              := GetAddress('dbcollen');\n    @DBLibAPI.dbcolname             := GetAddress('dbcolname');\n    @DBLibAPI.dbcolsource           := GetAddress('dbcolsource');\n    @DBLibAPI.dbcoltype             := GetAddress('dbcoltype');\n    @DBLibAPI.dbcolutype            := GetAddress('dbcolutype');\n    @DBLibAPI.dbconvert             := GetAddress('dbconvert');\n    @DBLibAPI.dbcurcmd              := GetAddress('dbcurcmd');\n    @DBLibAPI.dbcurrow              := GetAddress('dbcurrow');\n    @DBLibAPI.dbcursor              := GetAddress('dbcursor');\n    @DBLibAPI.dbdata                := GetAddress('dbdata');\n    @DBLibAPI.dbexit                := GetAddress('dbexit');\n    @DBLibAPI.dbfcmd                := GetAddress('dbfcmd');\n    @DBLibAPI.dbfirstrow            := GetAddress('dbfirstrow');\n    @DBLibAPI.dbfreebuf             := GetAddress('dbfreebuf');\n    @DBLibAPI.dbfreequal            := GetAddress('dbfreequal');\n    @DBLibAPI.dbgetchar             := GetAddress('dbgetchar');\n    @DBLibAPI.dbgetoff              := GetAddress('dbgetoff');\n    @DBLibAPI.dbgetrow              := GetAddress('dbgetrow');\n    @DBLibAPI.dbgettime             := GetAddress('dbgettime');\n    @DBLibAPI.dbiscount             := GetAddress('dbiscount');\n    @DBLibAPI.dblastrow             := GetAddress('dblastrow');\n    @DBLibAPI.dblogin               := GetAddress('dblogin');\n    @DBLibAPI.dbmorecmds            := GetAddress('dbmorecmds');\n    @DBLibAPI.dbmoretext            := GetAddress('dbmoretext');\n    @DBLibAPI.dbname                := GetAddress('dbname');\n    @DBLibAPI.dbnextrow             := GetAddress('dbnextrow');\n    @DBLibAPI.dbnullbind            := GetAddress('dbnullbind');\n    @DBLibAPI.dbnumalts             := GetAddress('dbnumalts');\n    @DBLibAPI.dbnumcols             := GetAddress('dbnumcols');\n    @DBLibAPI.dbnumcompute          := GetAddress('dbnumcompute');\n    @DBLibAPI.dbnumorders           := GetAddress('dbnumorders');\n    @DBLibAPI.dbnumrets             := GetAddress('dbnumrets');\n    @DBLibAPI.dbopen                := GetAddress('dbopen');\n    @DBLibAPI.dbordercol            := GetAddress('dbordercol');\n    @DBLibAPI.dbprhead              := GetAddress('dbprhead');\n    @DBLibAPI.dbprrow               := GetAddress('dbprrow');\n    @DBLibAPI.dbprtype              := GetAddress('dbprtype');\n    @DBLibAPI.dbqual                := GetAddress('dbqual');\n    @DBLibAPI.dbreadtext            := GetAddress('dbreadtext');\n    @DBLibAPI.dbresults             := GetAddress('dbresults');\n    @DBLibAPI.dbretdata             := GetAddress('dbretdata');\n    @DBLibAPI.dbretlen              := GetAddress('dbretlen');\n    @DBLibAPI.dbretname             := GetAddress('dbretname');\n    @DBLibAPI.dbretstatus           := GetAddress('dbretstatus');\n    @DBLibAPI.dbrettype             := GetAddress('dbrettype');\n    @DBLibAPI.dbrows                := GetAddress('dbrows');\n    @DBLibAPI.dbrowtype             := GetAddress('dbrowtype');\n    @DBLibAPI.dbrpcinit             := GetAddress('dbrpcinit');\n    @DBLibAPI.dbrpcparam            := GetAddress('dbrpcparam');\n    @DBLibAPI.dbrpcsend             := GetAddress('dbrpcsend');\n    @DBLibAPI.dbrpwclr              := GetAddress('dbrpwclr');\n    @DBLibAPI.dbsetavail            := GetAddress('dbsetavail');\n    @DBLibAPI.dbsetlname            := GetAddress('dbsetlname');\n    @DBLibAPI.dbsetlogintime        := GetAddress('dbsetlogintime');\n    @DBLibAPI.dbsetnull             := GetAddress('dbsetnull');\n    @DBLibAPI.dbsettime             := GetAddress('dbsettime');\n    @DBLibAPI.dbsetuserdata         := GetAddress('dbsetuserdata');\n    @DBLibAPI.dbsqlexec             := GetAddress('dbsqlexec');\n    @DBLibAPI.dbsqlok               := GetAddress('dbsqlok');\n    @DBLibAPI.dbsqlsend             := GetAddress('dbsqlsend');\n    @DBLibAPI.dbstrcpy              := GetAddress('dbstrcpy');\n    @DBLibAPI.dbstrlen              := GetAddress('dbstrlen');\n    @DBLibAPI.dbtabcount            := GetAddress('dbtabcount');\n    @DBLibAPI.dbtabname             := GetAddress('dbtabname');\n    @DBLibAPI.dbtabsource           := GetAddress('dbtabsource');\n    @DBLibAPI.dbtsnewlen            := GetAddress('dbtsnewlen');\n    @DBLibAPI.dbtsnewval            := GetAddress('dbtsnewval');\n    @DBLibAPI.dbtsput               := GetAddress('dbtsput');\n    @DBLibAPI.dbtxptr               := GetAddress('dbtxptr');\n    @DBLibAPI.dbtxtimestamp         := GetAddress('dbtxtimestamp');\n    @DBLibAPI.dbtxtsnewval          := GetAddress('dbtxtsnewval');\n    @DBLibAPI.dbtxtsput             := GetAddress('dbtxtsput');\n    @DBLibAPI.dbuse                 := GetAddress('dbuse');\n    @DBLibAPI.dbwritetext           := GetAddress('dbwritetext');\n  end;\nend;\n\nfunction TZDBLibBasePlainDriver.dbLogin: PLOGINREC;\nbegin\n  Result := DBLibAPI.dblogin;\nend;\n\nfunction TZDBLibBasePlainDriver.dbSetLoginTime(Seconds: DBINT): RETCODE;\nbegin\n  Result := DBLibAPI.dbsetlogintime(Seconds);\nend;\n\nfunction TZDBLibBasePlainDriver.dbsetlname(Login: PLOGINREC; Value: PAnsiChar; Item: DBINT): RETCODE;\nbegin\n  Result := DBLibAPI.dbsetlname(Login, Value, Item);\nend;\n\nfunction TZDBLibBasePlainDriver.dbSetLHost(Login: PLOGINREC; HostName: PAnsiChar): RETCODE;\nbegin\n  Result := DBLibAPI.dbsetlname(Login, HostName, Self.DBVariables.dbSetLoginRec[Z_SETHOST]);\nend;\n\nfunction TZDBLibBasePlainDriver.dbsetluser(Login: PLOGINREC; UserName: PAnsiChar): RETCODE;\nbegin\n  Result := DBLibAPI.dbsetlname(Login, UserName, Self.DBVariables.dbSetLoginRec[Z_SETUSER]);\nend;\n\nfunction TZDBLibBasePlainDriver.dbsetlpwd(Login: PLOGINREC; Password: PAnsiChar): RETCODE;\nbegin\n  Result := DBLibAPI.dbsetlname(Login, Password, Self.DBVariables.dbSetLoginRec[Z_SETPWD]);\nend;\n\nfunction TZDBLibBasePlainDriver.dbSetLApp(Login: PLOGINREC; AppName: PAnsiChar): RETCODE;\nbegin\n  Result := DBLibAPI.dbsetlname(Login, AppName, Self.DBVariables.dbSetLoginRec[Z_SETAPP]);\nend;\n\nfunction TZDBLibBasePlainDriver.dbSetLNatLang(Login: PLOGINREC; NatLangName: PAnsiChar): RETCODE;\nbegin\n  Result := DBLibAPI.dbsetlname(Login, NatLangName, Self.DBVariables.dbSetLoginRec[Z_SETLANG]);\nend;\n\nfunction TZDBLibBasePlainDriver.dbOpen(Login: PLOGINREC; Host: PAnsiChar): PDBPROCESS;\nbegin\n  DBLibAPI.dbsetlogintime(10);\n  Result := DBLibAPI.dbOpen(Login, Host);\nend;\n\nfunction TZDBLibBasePlainDriver.dbCancel(dbProc: PDBPROCESS): RETCODE;\nbegin\n  Result := DBLibAPI.dbcancel(dbProc);\nend;\n\nfunction TZDBLibBasePlainDriver.dbCmd(dbProc: PDBPROCESS; Cmd: PAnsiChar): RETCODE;\nbegin\n  Result := DBLibAPI.dbcmd(dbProc, Cmd);\nend;\n\nfunction TZDBLibBasePlainDriver.dbSqlExec(dbProc: PDBPROCESS; Async: Boolean=False): RETCODE;\nbegin\n  if Async then\n    Result := dbSqlExecAsync(dbProc)\n  else\n    Result := dbSqlExecSync(dbProc);\nend;\n\nfunction TZDBLibBasePlainDriver.dbSqlExecSync(dbProc: PDBPROCESS): RETCODE;\nbegin\n  Result := DBLibAPI.dbSqlExec(dbProc);\nend;\n\nfunction TZDBLibBasePlainDriver.dbSqlExecAsync(dbProc: PDBPROCESS): RETCODE;\nvar\n  lStartTick : Int64;\nbegin\n  Result := DBLibAPI.dbsqlsend(dbProc);\n  if Result = SUCCEED then begin\n    lStartTick := {$IFDEF FPC}GetMsCount{$ELSE}GetTickCount{$ENDIF};\n    repeat\n      //DBApplication.ProcessMessages;\n    until ({$IFDEF FPC}GetMsCount{$ELSE}GetTickCount{$ENDIF} > lStartTick + TIMEOUT_MAXIMUM * 1000) or\n      (dbdataready(dbProc) = TRUE);\n    Result := DBLibAPI.dbsqlok(dbProc);\n  end;\nend;\n\nfunction TZDBLibBasePlainDriver.dbResults(dbProc: PDBPROCESS): RETCODE;\nbegin\n  Result := DBLibAPI.dbResults(dbProc);\nend;\n\nfunction TZDBLibBasePlainDriver.dbCanQuery(dbProc: PDBPROCESS): RETCODE;\nbegin\n  Result := DBLibAPI.dbCanQuery(dbProc);\nend;\n\nfunction TZDBLibBasePlainDriver.dbMoreCmds(dbProc: PDBPROCESS): RETCODE;\nbegin\n  Result := DBLibAPI.dbMoreCmds(dbProc);\nend;\n\nfunction TZDBLibBasePlainDriver.dbUse(dbProc: PDBPROCESS; dbName: PAnsiChar): RETCODE;\nbegin\n  Result := DBLibAPI.dbUse(dbProc, dbName);\nend;\n\nfunction TZDBLibBasePlainDriver.dbName(dbProc: PDBPROCESS): PAnsiChar;\nbegin\n  Result := DBLibAPI.dbName(dbProc);\nend;\n\nfunction TZDBLibBasePlainDriver.dbCmdRow(dbProc: PDBPROCESS): RETCODE;\nbegin\n  Result := DBLibAPI.dbCmdRow(dbProc);\nend;\n\nfunction TZDBLibBasePlainDriver.dbNumCols(dbProc: PDBPROCESS): Integer;\nbegin\n  Result := DBLibAPI.dbNumCols(dbProc);\nend;\n\nfunction TZDBLibBasePlainDriver.dbColName(dbProc: PDBPROCESS; Column: Integer): PAnsiChar;\nbegin\n  Result := DBLibAPI.dbColName(dbProc, Column);\nend;\n\nfunction TZDBLibBasePlainDriver.dbColType(dbProc: PDBPROCESS; Column: Integer): Integer;\nbegin\n  Result := DBLibAPI.dbColType(dbProc, Column);\nend;\n\nfunction TZDBLibBasePlainDriver.dbColLen(dbProc: PDBPROCESS; Column: Integer): DBInt;\nbegin\n  Result := DBLibAPI.dbColLen(dbProc, Column);\nend;\n\nfunction TZDBLibBasePlainDriver.dbData(dbProc: PDBPROCESS; Column: Integer): PByte;\nbegin\n  Result := DBLibAPI.dbData(dbProc, Column);\nend;\n\nfunction TZDBLibBasePlainDriver.dbConvert(dbProc: PDBPROCESS; SrcType: Integer; Src: PByte;\n  SrcLen: DBINT; DestType: Integer; Dest: PByte; DestLen: DBINT): Integer;\nbegin\n  Result := DBLibAPI.dbConvert(dbProc, SrcType, Src, SrcLen, DestType, Dest, DestLen);\nend;\n\nfunction TZDBLibBasePlainDriver.dbNextRow(dbProc: PDBPROCESS): STATUS;\nbegin\n  Result := DBLibAPI.dbNextRow(dbProc);\nend;\n\nfunction TZDBLibBasePlainDriver.dbGetRow(dbProc: PDBPROCESS; Row: Integer): STATUS;\nbegin\n  Result := DBLibAPI.dbGetRow(dbProc, Row);\nend;\n\nfunction TZDBLibBasePlainDriver.dbRpcInit(dbProc: PDBPROCESS; RpcName: PAnsiChar; Options: SmallInt): RETCODE;\nbegin\n  Result := DBLibAPI.dbRpcInit(dbProc, RpcName, Options);\nend;\n\nfunction TZDBLibBasePlainDriver.dbRpcParam(dbProc: PDBPROCESS; ParamName: PAnsiChar; Status: Byte;\n  Type_: Integer; MaxLen: Integer; DataLen: Integer; Value: Pointer): RETCODE;\nbegin\n  Result := DBLibAPI.dbRpcParam(dbProc, ParamName, Status, Type_, MaxLen, DataLen, Value);\nend;\n\nfunction TZDBLibBasePlainDriver.dbRpcSend(dbProc: PDBPROCESS): RETCODE;\nbegin\n  Result := DBLibAPI.dbRpcSend(dbProc);\nend;\n\nfunction TZDBLibBasePlainDriver.dbRpcExec(dbProc: PDBPROCESS): RETCODE;\nbegin\n  Result := DBLibAPI.dbRpcSend(dbProc);\n  if Result = SUCCEED then\n    Result := DBLibAPI.dbSqlOk(dbProc);\nend;\n\nfunction TZDBLibBasePlainDriver.dbRetStatus(dbProc: PDBPROCESS): Integer;\nbegin\n  Result := DBLibAPI.dbRetStatus(dbProc);\nend;\n\nfunction TZDBLibBasePlainDriver.dbRetName(dbProc: PDBPROCESS; RetNum: Integer): PAnsiChar;\nbegin\n  Result := DBLibAPI.dbRetName(dbProc, RetNum);\nend;\n\nfunction TZDBLibBasePlainDriver.dbRetData(dbProc: PDBPROCESS; RetNum: Integer): Pointer;\nbegin\n  if Assigned(DBLibAPI.dbRetData) then\n    Result := DBLibAPI.dbRetData(dbProc, RetNum)\n  else\n    Result := nil;\nend;\n\nfunction TZDBLibBasePlainDriver.dbRetLen(dbProc: PDBPROCESS; RetNum: Integer): Integer;\nbegin\n  Result := DBLibAPI.dbRetLen(dbProc, RetNum);\nend;\n\nfunction TZDBLibBasePlainDriver.dbRetType(dbProc: PDBPROCESS; RetNum: Integer): Integer;\nbegin\n  Result := DBLibAPI.dbRetType(dbProc, RetNum);\nend;\n\nfunction TZDBLibBasePlainDriver.dbrbuf(Proc: PDBPROCESS): DBINT;\nbegin\n  Result := DBINT(dbdataready(Proc));\nend;\n\n\n{ TZDBLibSybaseASE125PlainDriver }\n\nprocedure TZDBLibSybaseASE125PlainDriver.LoadApi;\nbegin\n{ ************** Load adresses of API Functions ************* }\n  with Loader do\n  begin\n    @SybaseAPI.db12hour              := GetAddress('db12hour');\n    @SybaseAPI.dberrhandle           := GetAddress('dberrhandle');\n    @SybaseAPI.dbmsghandle           := GetAddress('dbmsghandle');\n    @SybaseAPI.abort_xact            := GetAddress('abort_xact');\n    @SybaseAPI.build_xact_string     := GetAddress('build_xact_string');\n    @SybaseAPI.close_commit          := GetAddress('close_commit');\n    @SybaseAPI.commit_xact           := GetAddress('commit_xact');\n    @SybaseAPI.open_commit           := GetAddress('open_commit');\n    @SybaseAPI.remove_xact           := GetAddress('remove_xact');\n    @SybaseAPI.scan_xact             := GetAddress('scan_xact');\n    @SybaseAPI.start_xact            := GetAddress('start_xact');\n    @SybaseAPI.stat_xact             := GetAddress('stat_xact');\n    @SybaseAPI.bcp_batch             := GetAddress('bcp_batch');\n    @SybaseAPI.bcp_bind              := GetAddress('bcp_bind');\n    @SybaseAPI.bcp_colfmt            := GetAddress('bcp_colfmt');\n    @SybaseAPI.bcp_collen            := GetAddress('bcp_collen');\n    @SybaseAPI.bcp_colptr            := GetAddress('bcp_colptr');\n    @SybaseAPI.bcp_columns           := GetAddress('bcp_columns');\n    @SybaseAPI.bcp_control           := GetAddress('bcp_control');\n    @SybaseAPI.bcp_done              := GetAddress('bcp_done');\n    @SybaseAPI.bcp_exec              := GetAddress('bcp_exec');\n    @SybaseAPI.bcp_init              := GetAddress('bcp_init');\n    @SybaseAPI.bcp_moretext          := GetAddress('bcp_moretext');\n    @SybaseAPI.bcp_readfmt           := GetAddress('bcp_readfmt');\n    @SybaseAPI.bcp_sendrow           := GetAddress('bcp_sendrow');\n    @SybaseAPI.bcp_writefmt          := GetAddress('bcp_writefmt');\n    @SybaseAPI.dbadata               := GetAddress('dbadata');\n    @SybaseAPI.dbadlen               := GetAddress('dbadlen');\n    @SybaseAPI.dbaltbind             := GetAddress('dbaltbind');\n    @SybaseAPI.dbaltcolid            := GetAddress('dbaltcolid');\n    @SybaseAPI.dbaltlen              := GetAddress('dbaltlen');\n    @SybaseAPI.dbaltop               := GetAddress('dbaltop');\n    @SybaseAPI.dbalttype             := GetAddress('dbalttype');\n    @SybaseAPI.dbaltutype            := GetAddress('dbaltutype');\n    @SybaseAPI.dbanullbind           := GetAddress('dbanullbind');\n    @SybaseAPI.dbbind                := GetAddress('dbbind');\n    @SybaseAPI.dbbylist              := GetAddress('dbbylist');\n    @SybaseAPI.dbcancel              := GetAddress('dbcancel');\n    @SybaseAPI.dbcanquery            := GetAddress('dbcanquery');\n    @SybaseAPI.dbchange              := GetAddress('dbchange');\n    @SybaseAPI.dbclose               := GetAddress('dbclose');\n    @SybaseAPI.dbclrbuf              := GetAddress('dbclrbuf');\n    @SybaseAPI.dbclropt              := GetAddress('dbclropt');\n    @SybaseAPI.dbcmd                 := GetAddress('dbcmd');\n    @SybaseAPI.dbcmdrow              := GetAddress('dbcmdrow');\n    @SybaseAPI.dbcolbrowse           := GetAddress('dbcolbrowse');\n    @SybaseAPI.dbcollen              := GetAddress('dbcollen');\n    @SybaseAPI.dbcolname             := GetAddress('dbcolname');\n    @SybaseAPI.dbcolsource           := GetAddress('dbcolsource');\n  //  @SybaseAPI.dbcoltypeinfo         := GetAddress('dbcoltypeinfo');\n    @SybaseAPI.dbcoltype             := GetAddress('dbcoltype');\n    @SybaseAPI.dbcolutype            := GetAddress('dbcolutype');\n    @SybaseAPI.dbconvert             := GetAddress('dbconvert');\n    @SybaseAPI.dbcount               := GetAddress('dbcount');\n    @SybaseAPI.dbcurcmd              := GetAddress('dbcurcmd');\n    @SybaseAPI.dbcurrow              := GetAddress('dbcurrow');\n    @SybaseAPI.dbcursor              := GetAddress('dbcursor');\n    @SybaseAPI.dbcursorbind          := GetAddress('dbcursorbind');\n    @SybaseAPI.dbcursorclose         := GetAddress('dbcursorclose');\n    @SybaseAPI.dbcursorcolinfo       := GetAddress('dbcursorcolinfo');\n    @SybaseAPI.dbcursorfetch         := GetAddress('dbcursorfetch');\n    @SybaseAPI.dbcursorinfo          := GetAddress('dbcursorinfo');\n    @SybaseAPI.dbcursoropen          := GetAddress('dbcursoropen');\n    @SybaseAPI.dbdata                := GetAddress('dbdata');\n    @SybaseAPI.dbdatecrack           := GetAddress('dbdatecrack');\n    @SybaseAPI.dbdatlen              := GetAddress('dbdatlen');\n    @SybaseAPI.dbdead                := GetAddress('dbdead');\n    @SybaseAPI.dbexit                := GetAddress('dbexit');\n    @SybaseAPI.dbfcmd                := GetAddress('dbfcmd');\n    @SybaseAPI.dbfirstrow            := GetAddress('dbfirstrow');\n    @SybaseAPI.dbfreebuf             := GetAddress('dbfreebuf');\n    @SybaseAPI.dbloginfree           := GetAddress('dbloginfree');\n    @SybaseAPI.dbfreequal            := GetAddress('dbfreequal');\n    @SybaseAPI.dbgetchar             := GetAddress('dbgetchar');\n    @SybaseAPI.dbgetmaxprocs         := GetAddress('dbgetmaxprocs');\n    @SybaseAPI.dbgetoff              := GetAddress('dbgetoff');\n    @SybaseAPI.dbgetpacket           := GetAddress('dbgetpacket');\n    @SybaseAPI.dbgetrow              := GetAddress('dbgetrow');\n    @SybaseAPI.dbgetuserdata         := GetAddress('dbgetuserdata');\n    @SybaseAPI.dbhasretstat          := GetAddress('dbhasretstat');\n    @SybaseAPI.dbinit                := GetAddress('dbinit');\n    @SybaseAPI.dbisavail             := GetAddress('dbisavail');\n    @SybaseAPI.dbisopt               := GetAddress('dbisopt');\n    @SybaseAPI.dblastrow             := GetAddress('dblastrow');\n    @SybaseAPI.dblogin               := GetAddress('dblogin');\n    @SybaseAPI.dbmorecmds            := GetAddress('dbmorecmds');\n    @SybaseAPI.dbmoretext            := GetAddress('dbmoretext');\n    @SybaseAPI.dbname                := GetAddress('dbname');\n    @SybaseAPI.dbnextrow             := GetAddress('dbnextrow');\n    @SybaseAPI.dbnullbind            := GetAddress('dbnullbind');\n    @SybaseAPI.dbnumalts             := GetAddress('dbnumalts');\n    @SybaseAPI.dbnumcols             := GetAddress('dbnumcols');\n    @SybaseAPI.dbnumcompute          := GetAddress('dbnumcompute');\n    @SybaseAPI.dbnumorders           := GetAddress('dbnumorders');\n    @SybaseAPI.dbnumrets             := GetAddress('dbnumrets');\n    @SybaseAPI.dbopen                := GetAddress('dbopen');\n    @SybaseAPI.dbordercol            := GetAddress('dbordercol');\n    @SybaseAPI.dbprhead              := GetAddress('dbprhead');\n    @SybaseAPI.dbprrow               := GetAddress('dbprrow');\n    @SybaseAPI.dbprtype              := GetAddress('dbprtype');\n    @SybaseAPI.dbqual                := GetAddress('dbqual');\n    @SybaseAPI.dbreadtext            := GetAddress('dbreadtext');\n    @SybaseAPI.dbresults             := GetAddress('dbresults');\n    @SybaseAPI.dbretdata             := GetAddress('dbretdata');\n    @SybaseAPI.dbretlen              := GetAddress('dbretlen');\n    @SybaseAPI.dbretname             := GetAddress('dbretname');\n    @SybaseAPI.dbretstatus           := GetAddress('dbretstatus');\n    @SybaseAPI.dbrettype             := GetAddress('dbrettype');\n    @SybaseAPI.dbrows                := GetAddress('dbrows');\n    @SybaseAPI.dbrowtype             := GetAddress('dbrowtype');\n    @SybaseAPI.dbrpcinit             := GetAddress('dbrpcinit');\n    @SybaseAPI.dbrpcparam            := GetAddress('dbrpcparam');\n    @SybaseAPI.dbrpcsend             := GetAddress('dbrpcsend');\n    @SybaseAPI.dbrpwclr              := GetAddress('dbrpwclr');\n    @SybaseAPI.dbsetavail            := GetAddress('dbsetavail');\n    @SybaseAPI.dbsetmaxprocs         := GetAddress('dbsetmaxprocs');\n    @SybaseAPI.dbsetlname            := GetAddress('dbsetlname');\n    @SybaseAPI.dbsetlogintime        := GetAddress('dbsetlogintime');\n    @SybaseAPI.dbsetnull             := GetAddress('dbsetnull');\n    @SybaseAPI.dbsetopt              := GetAddress('dbsetopt');\n    @SybaseAPI.dbsettime             := GetAddress('dbsettime');\n    @SybaseAPI.dbsetuserdata         := GetAddress('dbsetuserdata');\n    @SybaseAPI.dbsqlexec             := GetAddress('dbsqlexec');\n    @SybaseAPI.dbsqlok               := GetAddress('dbsqlok');\n    @SybaseAPI.dbsqlsend             := GetAddress('dbsqlsend');\n    @SybaseAPI.dbstrcpy              := GetAddress('dbstrcpy');\n    @SybaseAPI.dbstrlen              := GetAddress('dbstrlen');\n    @SybaseAPI.dbtabbrowse           := GetAddress('dbtabbrowse');\n    @SybaseAPI.dbtabcount            := GetAddress('dbtabcount');\n    @SybaseAPI.dbtabname             := GetAddress('dbtabname');\n    @SybaseAPI.dbtabsource           := GetAddress('dbtabsource');\n    @SybaseAPI.dbtsnewlen            := GetAddress('dbtsnewlen');\n    @SybaseAPI.dbtsnewval            := GetAddress('dbtsnewval');\n    @SybaseAPI.dbtsput               := GetAddress('dbtsput');\n    @SybaseAPI.dbtxptr               := GetAddress('dbtxptr');\n    @SybaseAPI.dbtxtimestamp         := GetAddress('dbtxtimestamp');\n    @SybaseAPI.dbtxtsnewval          := GetAddress('dbtxtsnewval');\n    @SybaseAPI.dbtxtsput             := GetAddress('dbtxtsput');\n    @SybaseAPI.dbuse                 := GetAddress('dbuse');\n    @SybaseAPI.dbvarylen             := GetAddress('dbvarylen');\n    @SybaseAPI.dbwillconvert         := GetAddress('dbwillconvert');\n    @SybaseAPI.dbwritetext           := GetAddress('dbwritetext');\n\n    SybaseAPI.dbinit;\n\n    OldSybaseErrorHandle := SybaseAPI.dberrhandle(SybaseErrorHandle);\n    OldSybaseMessageHandle := SybaseAPI.dbmsghandle(SybaseMessageHandle);\n  end;\nend;\n\nfunction TZDBLibSybaseASE125PlainDriver.Clone: IZPlainDriver;\nbegin\n  Result := TZDBLibSybaseASE125PlainDriver.Create;\nend;\n\nconstructor TZDBLibSybaseASE125PlainDriver.Create;\nbegin\n  inherited Create;\n  {$IFDEF MSWINDOWS}\n  Loader.AddLocation(LIBSYBDB_WINDOWS_DLL_LOCATION);\n  {$ELSE}\n    {$IFDEF UNIX}\n    Loader.AddLocation(LIBSYBDB_LINUX_DLL_LOCATION);\n    {$ENDIF}\n  {$ENDIF}\n\n  DBVariables.DBoptions[Z_PARSEONLY]      := DBLIBDBPARSEONLY;\n  DBVariables.DBoptions[Z_SHOWPLAN]       := DBLIBDBSHOWPLAN;\n  DBVariables.DBoptions[Z_NOEXEC]         := DBLIBDBNOEXEC;\n  DBVariables.DBoptions[Z_ARITHIGNORE]    := DBLIBDBARITHIGNORE;\n  DBVariables.DBoptions[Z_NOCOUNT]        := DBLIBDBNOCOUNT;\n  DBVariables.DBoptions[Z_ARITHABORT]     := DBLIBDBARITHABORT;\n  DBVariables.DBoptions[Z_TEXTLIMIT]      := DBLIBDBTEXTLIMIT;\n  DBVariables.DBoptions[Z_OFFSET]         := DBLIBDBOFFSET;\n  DBVariables.DBoptions[Z_STAT]           := DBLIBDBSTAT;\n  DBVariables.DBoptions[Z_STORPROCID]     := DBLIBDBSTORPROCID;\n  DBVariables.DBoptions[Z_BUFFER]         := DBLIBDBBUFFER;\n  DBVariables.DBoptions[Z_NOAUTOFREE]     := DBLIBDBNOAUTOFREE;\n  DBVariables.DBoptions[Z_ROWCOUNT]       := DBLIBDBROWCOUNT;\n  DBVariables.DBoptions[Z_TEXTSIZE]       := DBLIBDBTEXTSIZE;\n  DBVariables.DBoptions[Z_CLIENTCURSORS]  := DBLIBDBCLIENTCURSORS;\n  DBVariables.DBoptions[Z_SETTIME] \t      := DBLIBDBSET_TIME;\n  DBVariables.DBoptions[Z_QUOTEDIDENT]    := DBLIBDBQUOTEDIDENT;\n  DBVariables.DBoptions[Z_ANSITOOEM]      := DBLIBDBANSITOOEM;\n  DBVariables.DBoptions[Z_OEMTOANSI]      := DBLIBDBOEMTOANSI;\n  {MSSQL Loginrec manipulations}\n  DBVariables.DBSetLoginRec[Z_SETHOST]    := SYBDBSETHOST;\n  DBVariables.DBSetLoginRec[Z_SETUSER]    := SYBDBSETUSER;\n  DBVariables.DBSetLoginRec[Z_SETPWD]     := SYBDBSETPWD;\n  DBVariables.DBSetLoginRec[Z_SETHID]     := SYBDBSETHID;\n  DBVariables.DBSetLoginRec[Z_SETAPP]     := SYBDBSETAPP;\n  DBVariables.DBSetLoginRec[Z_SETBCP]     := SYBDBSETBCP;\n  DBVariables.DBSetLoginRec[Z_SETLANG]    := SYBDBSETLANG;\n  DBVariables.DBSetLoginRec[Z_SETNOSHORT] := SYBDBSETNOSHORT;\n  DBVariables.DBSetLoginRec[Z_SETHIER]    := SYBDBSETHIER;\n  DBVariables.DBSetLoginRec[Z_SETCHARSET] := SYBDBSETCHARSET;\n  DBVariables.DBSetLoginRec[Z_SETPACKET]  := SYBDBSETPACKET;\n  DBVariables.DBSetLoginRec[Z_SETENCRYPT] := SYBDBSETENCRYPT;\n  DBVariables.dbSetLoginRec[Z_SETLABELED] := SYBDBSETLABELED;\n  LoadCodePages;\nend;\n\ndestructor TZDBLibSybaseASE125PlainDriver.Destroy;\nbegin\n  if Loader.Loaded then\n  begin\n    SybaseAPI.dberrhandle(OldSybaseErrorHandle);\n    SybaseAPI.dbmsghandle(OldSybaseMessageHandle);\n    SybaseAPI.dbexit;\n  end;\n  inherited Destroy;\nend;\n\nprocedure TZDBLibSybaseASE125PlainDriver.LoadCodePages;\nbegin\n  AddSybaseCodePages(Self);\nend;\n\nfunction TZDBLibSybaseASE125PlainDriver.GetProtocol: string;\nbegin\n  Result := 'sybase';\nend;\n\nfunction TZDBLibSybaseASE125PlainDriver.GetDescription: string;\nbegin\n  Result := 'Native dblib driver for Sybase ASE 12.5';\nend;\n\nfunction TZDBLibSybaseASE125PlainDriver.dbcolbrowse(Proc: PDBPROCESS; Column: Integer): LongBool;\nbegin\n  Result := SybaseAPI.dbcolbrowse(Proc, Column);\nend;\n\nfunction TZDBLibSybaseASE125PlainDriver.dbDead(dbProc: PDBPROCESS): Boolean;\nbegin\n  Result := SybaseAPI.dbDead(dbProc);\nend;\n\nfunction TZDBLibSybaseASE125PlainDriver.dbLogin: PLOGINREC;\nbegin\n  Result := SybaseAPI.dbLogin;\nend;\n\nprocedure TZDBLibSybaseASE125PlainDriver.dbLoginFree(Login: PLOGINREC);\nbegin\n  SybaseAPI.dbLoginFree(Login);\nend;\n\nfunction TZDBLibSybaseASE125PlainDriver.dbSetLoginTime(Seconds: DBINT): RETCODE;\nbegin\n  Result := SybaseAPI.dbsetlogintime(Seconds);\nend;\n\nfunction TZDBLibSybaseASE125PlainDriver.dbsetlname(Login: PLOGINREC; Value: PAnsiChar; Item: DBINT): RETCODE;\nbegin\n  Result := SybaseAPI.dbsetlname(Login, Value, Item);\nend;\n\nfunction TZDBLibSybaseASE125PlainDriver.dbSetLHost(Login: PLOGINREC; HostName: PAnsiChar): RETCODE;\nbegin\n  Result := SybaseAPI.dbsetlname(Login, HostName, Self.DBVariables.dbSetLoginRec[Z_SETHOST]);\nend;\n\nfunction TZDBLibSybaseASE125PlainDriver.dbsetluser(Login: PLOGINREC; UserName: PAnsiChar): RETCODE;\nbegin\n  Result := SybaseAPI.dbsetlname(Login, UserName, Self.DBVariables.dbSetLoginRec[Z_SETUSER]);\nend;\n\nfunction TZDBLibSybaseASE125PlainDriver.dbsetlpwd(Login: PLOGINREC; Password: PAnsiChar): RETCODE;\nbegin\n  Result := SybaseAPI.dbsetlname(Login, Password, Self.DBVariables.dbSetLoginRec[Z_SETPWD]);\nend;\n\nfunction TZDBLibSybaseASE125PlainDriver.dbSetLApp(Login: PLOGINREC; AppName: PAnsiChar): RETCODE;\nbegin\n  Result := SybaseAPI.dbsetlname(Login, AppName, Self.DBVariables.dbSetLoginRec[Z_SETAPP]);\nend;\n\nfunction TZDBLibSybaseASE125PlainDriver.dbSetLNatLang(Login: PLOGINREC; NatLangName: PAnsiChar): RETCODE;\nbegin\n  Result := SybaseAPI.dbsetlname(Login, NatLangName, Self.DBVariables.dbSetLoginRec[Z_SETLANG]);\nend;\n\nfunction TZDBLibSybaseASE125PlainDriver.dbSetLCharSet(Login: PLOGINREC; CharsetName: PAnsiChar): RETCODE;\nbegin\n  Result := SybaseAPI.dbsetlname(Login, CharsetName, Self.DBVariables.dbSetLoginRec[Z_SETCHARSET]);\nend;\n\nfunction TZDBLibSybaseASE125PlainDriver.dbSetLSecure(Login: PLOGINREC): RETCODE;\nbegin\n  Result := 0\nend;\n\nfunction TZDBLibSybaseASE125PlainDriver.dbsetmaxprocs(\n  MaxProcs: SmallInt): RETCODE;\nbegin\n  Result := SybaseAPI.dbsetmaxprocs(MaxProcs);\nend;\n\nfunction TZDBLibSybaseASE125PlainDriver.dbOpen(Login: PLOGINREC; Host: PAnsiChar): PDBPROCESS;\nbegin\n  Result := SybaseAPI.dbOpen(Login, Host);\nend;\n\nfunction TZDBLibSybaseASE125PlainDriver.dbCancel(dbProc: PDBPROCESS): RETCODE;\nbegin\n  Result := SybaseAPI.dbcancel(dbProc);\nend;\n\nfunction TZDBLibSybaseASE125PlainDriver.dbCmd(dbProc: PDBPROCESS; Cmd: PAnsiChar): RETCODE;\nbegin\n  Result := SybaseAPI.dbcmd(dbProc, Cmd);\nend;\n\nfunction TZDBLibSybaseASE125PlainDriver.dbSqlExec(dbProc: PDBPROCESS; Async: Boolean=False): RETCODE;\nbegin\n  if Async then\n    Result := dbSqlExecSync(dbProc)\n  else\n    Result := dbSqlExecAsync(dbProc);\nend;\n\nfunction TZDBLibSybaseASE125PlainDriver.dbSqlExecSync(dbProc: PDBPROCESS): RETCODE;\nbegin\n  Result := SybaseAPI.dbSqlExec(dbProc);\nend;\n\nfunction TZDBLibSybaseASE125PlainDriver.dbSqlExecAsync(dbProc: PDBPROCESS): RETCODE;\nvar\n  lStartTick : Int64;\nbegin\n  Result := SybaseAPI.dbsqlsend(dbProc);\n  if Result = SUCCEED then begin\n    lStartTick := {$IFDEF FPC}GetMsCount{$ELSE}GetTickCount{$ENDIF};\n    repeat\n      continue;\n    until ({$IFDEF FPC}GetMsCount{$ELSE}GetTickCount{$ENDIF} > lStartTick + TIMEOUT_MAXIMUM * 1000) or\n      (dbdataready(dbProc) = TRUE);\n    Result := SybaseAPI.dbsqlok(dbProc);\n  end;\nend;\n\nfunction TZDBLibSybaseASE125PlainDriver.dbResults(dbProc: PDBPROCESS): RETCODE;\nbegin\n  Result := SybaseAPI.dbResults(dbProc);\nend;\n\nfunction TZDBLibSybaseASE125PlainDriver.dbCanQuery(dbProc: PDBPROCESS): RETCODE;\nbegin\n  Result := SybaseAPI.dbCanQuery(dbProc);\nend;\n\nfunction TZDBLibSybaseASE125PlainDriver.dbMoreCmds(dbProc: PDBPROCESS): RETCODE;\nbegin\n  Result := SybaseAPI.dbMoreCmds(dbProc);\nend;\n\nfunction TZDBLibSybaseASE125PlainDriver.dbUse(dbProc: PDBPROCESS; dbName: PAnsiChar): RETCODE;\nbegin\n  Result := SybaseAPI.dbUse(dbProc, dbName);\nend;\n\nfunction TZDBLibSybaseASE125PlainDriver.dbSetOpt(dbProc: PDBPROCESS; Option: DBINT; Char_Param: PAnsiChar = nil; Int_Param: DBINT = -1): RETCODE;\nbegin\n  Result := SybaseAPI.dbSetOpt(dbProc, Option, Char_Param, Int_Param);\nend;\n\nfunction TZDBLibSybaseASE125PlainDriver.dbClose(dbProc: PDBPROCESS): RETCODE;\nbegin\n  Result := SybaseAPI.dbClose(dbProc);\nend;\n\nfunction TZDBLibSybaseASE125PlainDriver.dbName(dbProc: PDBPROCESS): PAnsiChar;\nbegin\n  Result := SybaseAPI.dbName(dbProc);\nend;\n\nfunction TZDBLibSybaseASE125PlainDriver.dbCmdRow(dbProc: PDBPROCESS): RETCODE;\nbegin\n  Result := SybaseAPI.dbCmdRow(dbProc);\nend;\n\nfunction TZDBLibSybaseASE125PlainDriver.dbNumCols(dbProc: PDBPROCESS): DBINT;\nbegin\n  Result := SybaseAPI.dbNumCols(dbProc);\nend;\n\nfunction TZDBLibSybaseASE125PlainDriver.dbColName(dbProc: PDBPROCESS; Column: DBINT): PAnsiChar;\nbegin\n  Result := SybaseAPI.dbColName(dbProc, Column);\nend;\n\nfunction TZDBLibSybaseASE125PlainDriver.dbColType(dbProc: PDBPROCESS; Column: DBINT): DBINT;\nbegin\n  Result := SybaseAPI.dbColType(dbProc, Column);\nend;\n\nfunction TZDBLibSybaseASE125PlainDriver.dbColLen(dbProc: PDBPROCESS; Column: DBINT): DBInt;\nbegin\n  Result := SybaseAPI.dbColLen(dbProc, Column);\nend;\n\nfunction TZDBLibSybaseASE125PlainDriver.dbData(dbProc: PDBPROCESS; Column: DBINT): PByte;\nbegin\n  Result := SybaseAPI.dbData(dbProc, Column);\nend;\n\nfunction TZDBLibSybaseASE125PlainDriver.dbDatLen(dbProc: PDBPROCESS; Column: DBINT): DBINT;\nbegin\n  Result := SybaseAPI.dbDatLen(dbProc, Column);\nend;\n\nfunction TZDBLibSybaseASE125PlainDriver.dbConvert(dbProc: PDBPROCESS; SrcType: DBINT; Src: PByte;\n  SrcLen: DBINT; DestType: DBINT; Dest: PByte; DestLen: DBINT): DBINT;\nbegin\n  Result := SybaseAPI.dbConvert(dbProc, SrcType, Src, SrcLen, DestType, Dest, DestLen);\nend;\n\nfunction TZDBLibSybaseASE125PlainDriver.dbNextRow(dbProc: PDBPROCESS): STATUS;\nbegin\n  Result := SybaseAPI.dbNextRow(dbProc);\nend;\n\nfunction TZDBLibSybaseASE125PlainDriver.dbGetRow(dbProc: PDBPROCESS; Row: DBINT): STATUS;\nbegin\n  Result := SybaseAPI.dbGetRow(dbProc, Row);\nend;\n\nfunction TZDBLibSybaseASE125PlainDriver.dbCount(dbProc: PDBPROCESS): DBINT;\nbegin\n  Result := SybaseAPI.dbCount(dbProc);\nend;\n\nfunction TZDBLibSybaseASE125PlainDriver.dbRpcInit(dbProc: PDBPROCESS; RpcName: PAnsiChar; Options: SmallInt): RETCODE;\nbegin\n  Result := SybaseAPI.dbRpcInit(dbProc, RpcName, Options);\nend;\n\nfunction TZDBLibSybaseASE125PlainDriver.dbRpcParam(dbProc: PDBPROCESS; ParamName: PAnsiChar; Status: Byte;\n  Type_: DBINT; MaxLen: DBINT; DataLen: DBINT; Value: Pointer): RETCODE;\nbegin\n  Result := SybaseAPI.dbRpcParam(dbProc, ParamName, Status, Type_, MaxLen, DataLen, Value);\nend;\n\nfunction TZDBLibSybaseASE125PlainDriver.dbRpcSend(dbProc: PDBPROCESS): RETCODE;\nbegin\n  Result := SybaseAPI.dbRpcSend(dbProc);\nend;\n\nfunction TZDBLibSybaseASE125PlainDriver.dbRpcExec(dbProc: PDBPROCESS): RETCODE;\nbegin\n  Result := SybaseAPI.dbRpcSend(dbProc);\n  if Result = SUCCEED then\n    Result := SybaseAPI.dbSqlOk(dbProc);\nend;\n\nfunction TZDBLibSybaseASE125PlainDriver.dbRetStatus(dbProc: PDBPROCESS): DBINT;\nbegin\n  Result := SybaseAPI.dbRetStatus(dbProc);\nend;\n\nfunction TZDBLibSybaseASE125PlainDriver.dbHasRetStat(dbProc: PDBPROCESS): Boolean;\nbegin\n  Result := SybaseAPI.dbHasRetStat(dbProc);\nend;\n\nfunction TZDBLibSybaseASE125PlainDriver.dbRetName(dbProc: PDBPROCESS; RetNum: DBINT): PAnsiChar;\nbegin\n  Result := SybaseAPI.dbRetName(dbProc, RetNum);\nend;\n\nfunction TZDBLibSybaseASE125PlainDriver.dbRetData(dbProc: PDBPROCESS; RetNum: DBINT): Pointer;\nbegin\n  Result := SybaseAPI.dbRetData(dbProc, RetNum);\nend;\n\nfunction TZDBLibSybaseASE125PlainDriver.dbRetLen(dbProc: PDBPROCESS; RetNum: DBINT): DBINT;\nbegin\n  Result := SybaseAPI.dbRetLen(dbProc, RetNum);\nend;\n\nfunction TZDBLibSybaseASE125PlainDriver.dbRetType(dbProc: PDBPROCESS; RetNum: DBINT): DBINT;\nbegin\n  Result := SybaseAPI.dbRetType(dbProc, RetNum);\nend;\n\nfunction TZDBLibSybaseASE125PlainDriver.dbrbuf(Proc: PDBPROCESS): DBINT;\nbegin\n  Result := 0;\nend;\n\nfunction TZDBLibSybaseASE125PlainDriver.dbdataready(Proc: PDBPROCESS): LongBool;\nbegin\n  Result := Proc <> nil;\nend;\n\n{TZDBLibMSSQL7PlainDriver}\n\nprocedure TZDBLibMSSQL7PlainDriver.LoadApi;\nbegin\n  inherited LoadAPI;\n{ ************** Load adresses of API Functions ************* }\n  with Loader do\n  begin\n    //@MsSQLAPI.dbtablecolinfo  := GetAddress('dbtablecolinfo');\n    @MsSQLAPI.dbdataready           := GetAddress('dbdataready');\n    @MsSQLAPI.dbdatecrack           := GetAddress('dbdatecrack');\n    @MsSQLAPI.dbdatlen              := GetAddress('dbdatlen');\n    @MsSQLAPI.dbdead                := GetAddress('dbdead');\n    @MsSQLAPI.dbclose               := GetAddress('dbclose');\n    @MsSQLAPI.dbcolbrowse           := GetAddress('dbcolbrowse');\n    @MsSQLAPI.dbcolinfo             := GetAddress('dbcolinfo');\n    @MsSQLAPI.dbcount               := GetAddress('dbcount');\n    @MsSQLAPI.dbcursorbind          := GetAddress('dbcursorbind');\n    @MsSQLAPI.dbcursorclose         := GetAddress('dbcursorclose');\n    @MsSQLAPI.dbcursorcolinfo       := GetAddress('dbcursorcolinfo');\n    @MsSQLAPI.dbcursorfetch         := GetAddress('dbcursorfetch');\n    @MsSQLAPI.dbcursorfetchex       := GetAddress('dbcursorfetchex');\n    @MsSQLAPI.dbcursorinfo          := GetAddress('dbcursorinfo');\n    @MsSQLAPI.dbcursorinfoex        := GetAddress('dbcursorinfoex');\n    @MsSQLAPI.dbcursoropen          := GetAddress('dbcursoropen');\n    @MsSQLAPI.dbWinexit             := GetAddress('dbwinexit');\n    @MsSQLAPI.dbenlisttrans         := GetAddress('dbenlisttrans');\n    @MsSQLAPI.dbenlistxatrans       := GetAddress('dbenlistxatrans');\n    @MsSQLAPI.dbfreelogin           := GetAddress('dbfreelogin');\n    @MsSQLAPI.dbgetmaxprocs         := GetAddress('dbgetmaxprocs');\n    @MsSQLAPI.dbgetpacket           := GetAddress('dbgetpacket');\n    @MsSQLAPI.dbgetuserdata         := GetAddress('dbgetuserdata');\n    @MsSQLAPI.dbhasretstat          := GetAddress('dbhasretstat');\n    @MsSQLAPI.dbinit                := GetAddress('dbinit');\n    @MsSQLAPI.dbisavail             := GetAddress('dbisavail');\n    @MsSQLAPI.dbisopt               := GetAddress('dbisopt');\n    @MsSQLAPI.dbprocinfo            := GetAddress('dbprocinfo');\n    @MsSQLAPI.dbrpcexec             := GetAddress('dbrpcexec');\n    @MsSQLAPI.dbserverenum          := GetAddress('dbserverenum');\n    @MsSQLAPI.dbsetmaxprocs         := GetAddress('dbsetmaxprocs');\n    @MsSQLAPI.dbsetlpacket          := GetAddress('dbsetlpacket');\n    @MsSQLAPI.dbsetopt              := GetAddress('dbsetopt');\n    @MsSQLAPI.dbtabbrowse           := GetAddress('dbtabbrowse');\n    @MsSQLAPI.dbvarylen             := GetAddress('dbvarylen');\n    @MsSQLAPI.dbwillconvert         := GetAddress('dbwillconvert');\n    @MsSQLAPI.dbupdatetext          := GetAddress('dbupdatetext');\n    MsSQLAPI.dbinit;\n  end;\n  OldMsSQLErrorHandle := DBLibAPI.dberrhandle(DbLibErrorHandle);\n  OldMsSQLMessageHandle := DBLibAPI.dbmsghandle(DbLibMessageHandle);\nend;\n\nfunction TZDBLibMSSQL7PlainDriver.Clone: IZPlainDriver;\nbegin\n  Result := TZDBLibMSSQL7PlainDriver.Create;\nend;\n\nconstructor TZDBLibMSSQL7PlainDriver.Create;\nbegin\n  inherited Create;\n  Loader.AddLocation(NTWDBLIB_DLL_LOCATION);\n\n  DBVariables.DBoptions[Z_PARSEONLY]      := DBLIBDBPARSEONLY;\n  DBVariables.DBoptions[Z_SHOWPLAN]       := DBLIBDBSHOWPLAN;\n  DBVariables.DBoptions[Z_NOEXEC]         := DBLIBDBNOEXEC;\n  DBVariables.DBoptions[Z_ARITHIGNORE]    := DBLIBDBARITHIGNORE;\n  DBVariables.DBoptions[Z_NOCOUNT]        := DBLIBDBNOCOUNT;\n  DBVariables.DBoptions[Z_ARITHABORT]     := DBLIBDBARITHABORT;\n  DBVariables.DBoptions[Z_TEXTLIMIT]      := DBLIBDBTEXTLIMIT;\n  DBVariables.DBoptions[Z_OFFSET]         := DBLIBDBOFFSET;\n  DBVariables.DBoptions[Z_STAT]           := DBLIBDBSTAT;\n  DBVariables.DBoptions[Z_STORPROCID]     := DBLIBDBSTORPROCID;\n  DBVariables.DBoptions[Z_BUFFER]         := DBLIBDBBUFFER;\n  DBVariables.DBoptions[Z_NOAUTOFREE]     := DBLIBDBNOAUTOFREE;\n  DBVariables.DBoptions[Z_ROWCOUNT]       := DBLIBDBROWCOUNT;\n  DBVariables.DBoptions[Z_TEXTSIZE]       := DBLIBDBTEXTSIZE;\n  DBVariables.DBoptions[Z_CLIENTCURSORS]  := DBLIBDBCLIENTCURSORS;\n  DBVariables.DBoptions[Z_SETTIME] \t      := DBLIBDBSET_TIME;\n  DBVariables.DBoptions[Z_QUOTEDIDENT] \t  := DBLIBDBQUOTEDIDENT;\n  DBVariables.DBoptions[Z_ANSITOOEM]      := DBLIBDBANSITOOEM;\n  DBVariables.DBoptions[Z_OEMTOANSI]      := DBLIBDBOEMTOANSI;\n  {MsSQL Loginrec manipulations}\n  DBVariables.DBSetLoginRec[Z_SETHOST]    := MSDBSETHOST;\n  DBVariables.DBSetLoginRec[Z_SETUSER]    := MSDBSETUSER;\n  DBVariables.DBSetLoginRec[Z_SETPWD]     := MSDBSETPWD;\n  DBVariables.DBSetLoginRec[Z_SETHID]     := MSDBSETID;\n  DBVariables.DBSetLoginRec[Z_SETAPP]     := MSDBSETAPP;\n  DBVariables.DBSetLoginRec[Z_SETSECURE]  := MSDBSETSECURE;\n  DBVariables.DBSetLoginRec[Z_SETLANG]    := MSDBSETLANG;\n  DBVariables.DBSetLoginRec[Z_SETLOGINTIME]:= MSDBSET_LOGIN_TIME;\n  DBVariables.DBSetLoginRec[Z_SETFALLBACK]:= MSDBSETFALLBACK;\n  LoadCodePages;\nend;\n\ndestructor TZDBLibMSSQL7PlainDriver.Destroy;\nbegin\n  if Loader.Loaded then\n  begin\n    DbLibAPI.dberrhandle(DbLibErrorHandle);\n    DbLibAPI.dbmsghandle(DbLibMessageHandle);\n    MsSQLAPI.dbWinexit;\n    DbLibAPI.dbExit;\n  end;\n  inherited Destroy;\nend;\n\nprocedure TZDBLibMSSQL7PlainDriver.LoadCodePages;\nbegin\n  AddmMSCodePages(Self);\nend;\n\nfunction TZDBLibMSSQL7PlainDriver.GetProtocol: string;\nbegin\n  Result := 'mssql';\nend;\n\nfunction TZDBLibMSSQL7PlainDriver.GetDescription: string;\nbegin\n  Result := 'Native dblib driver for MS SQL 7+';\nend;\n\nfunction TZDBLibMSSQL7PlainDriver.dbsetlsecure(Login: PLOGINREC): RETCODE;\nbegin\n  Result := DBLibAPI.dbsetlname(Login, nil, Self.DBVariables.dbSetLoginRec[Z_SETSECURE]);\nend;\n\nfunction TZDBLibMSSQL7PlainDriver.dbcolbrowse(Proc: PDBPROCESS; Column: Integer): LongBool;\nbegin\n  Result := MsSQLAPI.dbcolbrowse(Proc, Column);\nend;\n\nfunction TZDBLibMSSQL7PlainDriver.dbDead(dbProc: PDBPROCESS): Boolean;\nbegin\n  Result := MsSQLAPI.dbDead(dbProc);\nend;\n\nprocedure TZDBLibMSSQL7PlainDriver.dbLoginFree(Login: PLOGINREC);\nbegin\n  MsSQLAPI.dbfreelogin(Login);\nend;\n\nfunction TZDBLibMSSQL7PlainDriver.dbSetLCharSet(Login: PLOGINREC; CharsetName: PAnsiChar): RETCODE;\nbegin\n  Result := DBFAIL;\nend;\n\nfunction TZDBLibMSSQL7PlainDriver.dbsetmaxprocs(\n  MaxProcs: SmallInt): RETCODE;\nbegin\n  Result := MsSQLAPI.dbsetmaxprocs(MaxProcs);\nend;\n\nfunction TZDBLibMSSQL7PlainDriver.dbSqlExecAsync(dbProc: PDBPROCESS): RETCODE;\nvar\n  lStartTick : Int64;\nbegin\n  Result := DBLibAPI.dbsqlsend(dbProc);\n  if Result = SUCCEED then begin\n    lStartTick := {$IFDEF FPC}GetMsCount{$ELSE}GetTickCount{$ENDIF};\n    repeat\n      continue;\n    until ({$IFDEF FPC}GetMsCount{$ELSE}GetTickCount{$ENDIF} > lStartTick + TIMEOUT_MAXIMUM * 1000) or\n      (MsSQLAPI.dbdataready(dbProc) = TRUE);\n    Result := DBLibAPI.dbsqlok(dbProc);\n  end;\nend;\n\nfunction TZDBLibMSSQL7PlainDriver.dbSetOpt(dbProc: PDBPROCESS; Option: DBINT; Char_Param: PAnsiChar = nil; Int_Param: DBINT = -1): RETCODE;\nbegin\n  Result := MsSQLAPI.dbSetOpt(dbProc, Option, Char_Param);\nend;\n\nfunction TZDBLibMSSQL7PlainDriver.dbClose(dbProc: PDBPROCESS): RETCODE;\nbegin\n  Result := MsSQLAPI.dbClose(dbProc);\nend;\n\nfunction TZDBLibMSSQL7PlainDriver.dbDatLen(dbProc: PDBPROCESS; Column: DBINT): DBINT;\nbegin\n  Result := MsSQLAPI.dbDatLen(dbProc, Column);\nend;\n\nfunction TZDBLibMSSQL7PlainDriver.dbCount(dbProc: PDBPROCESS): DBINT;\nbegin\n  Result := MsSQLAPI.dbCount(dbProc);\nend;\n\nfunction TZDBLibMSSQL7PlainDriver.dbHasRetStat(dbProc: PDBPROCESS): Boolean;\nbegin\n  Result := MsSQLAPI.dbHasRetStat(dbProc);\nend;\n\nfunction TZDBLibMSSQL7PlainDriver.dbdataready(Proc: PDBPROCESS): LongBool;\nbegin\n  Result := MsSQLAPI.dbdataready(Proc);\nend;\n\n{ TFreeTGDBasePlainDriver }\n\n{ TZFreeTDSBasePlainDriver }\n\nprocedure TZFreeTDSBasePlainDriver.LoadApi;\nbegin\n  inherited LoadAPI;\n  with Loader do\n  begin\n    @FreeTDSAPI.db12hour        := GetAddress('db12hour');\n    @FreeTDSAPI.dbaltbind_ps    := GetAddress('dbaltbind_ps');\n    @FreeTDSAPI.dbbufsize       := GetAddress('dbbufsize');\n    @FreeTDSAPI.dbclose         := GetAddress('dbclose');\n    @FreeTDSAPI.dbtablecolinfo  := GetAddress('dbtablecolinfo');\n    @FreeTDSAPI.dbcolbrowse     := GetAddress('dbcolbrowse');\n    @FreeTDSAPI.dbcolinfo       := GetAddress('dbcolinfo');\n    @FreeTDSAPI.dbconvert_ps    := GetAddress('dbconvert_ps');\n    @FreeTDSAPI.dbcount         := GetAddress('dbcount');\n    @FreeTDSAPI.dbdatecmp       := GetAddress('dbdatecmp');\n    @FreeTDSAPI.dbdatecrack     := GetAddress('dbdatecrack');\n    @FreeTDSAPI.dbdatlen        := GetAddress('dbdatlen');\n    @FreeTDSAPI.dbdead          := GetAddress('dbdead');\n    @FreeTDSAPI.dbgetcharset    := GetAddress('dbgetcharset');\n    @FreeTDSAPI.dbgetlusername  := GetAddress('dbgetlusername');\n    @FreeTDSAPI.dbgetmaxprocs   := GetAddress('dbgetmaxprocs');\n    @FreeTDSAPI.dbgetnatlanf    := GetAddress('dbgetnatlanf');\n    @FreeTDSAPI.dbgetpacket     := GetAddress('dbgetpacket');\n    @FreeTDSAPI.dbgetuserdata   := GetAddress('dbgetuserdata');\n    @FreeTDSAPI.dbhasretstat    := GetAddress('dbhasretstat');\n    @FreeTDSAPI.dbinit          := GetAddress('dbinit');\n    @FreeTDSAPI.dbiordesc       := GetAddress('dbiordesc');\n    @FreeTDSAPI.dbiowdesc       := GetAddress('dbiowdesc');\n    @FreeTDSAPI.dbisavail       := GetAddress('dbisavail');\n    @FreeTDSAPI.dbisopt         := GetAddress('dbisopt');\n    @FreeTDSAPI.dbloginfree     := GetAddress('dbloginfree');\n    @FreeTDSAPI.dbmny4cmp       := GetAddress('dbmny4cmp');\n    @FreeTDSAPI.dbmnycmp        := GetAddress('dbmnycmp');\n    @FreeTDSAPI.dbmny4add       := GetAddress('dbmny4add');\n    @FreeTDSAPI.dbmnydec        := GetAddress('dbmnydec');\n    @FreeTDSAPI.dbmnyinc        := GetAddress('dbmnyinc');\n    @FreeTDSAPI.dbmnymaxpos     := GetAddress('dbmnymaxpos');\n    @FreeTDSAPI.dbmnymaxneg     := GetAddress('dbmnymaxneg');\n    @FreeTDSAPI.dbmny4minus     := GetAddress('dbmny4minus');\n    @FreeTDSAPI.dbmnyminus      := GetAddress('dbmnyminus');\n    @FreeTDSAPI.dbmny4sub       := GetAddress('dbmny4sub');\n    @FreeTDSAPI.dbmnysub        := GetAddress('dbmnysub');\n    @FreeTDSAPI.dbmny4copy      := GetAddress('dbmny4copy');\n    @FreeTDSAPI.dbmnycopy       := GetAddress('dbmnycopy');\n    @FreeTDSAPI.dbmny4zero      := GetAddress('dbmny4zero');\n    @FreeTDSAPI.dbmnyzero       := GetAddress('dbmnyzero');\n    @FreeTDSAPI.dbmonthname     := GetAddress('dbmonthname');\n    @FreeTDSAPI.tdsdbopen       := GetAddress('tdsdbopen');\n\n\n    @FreeTDSAPI.DRBUF           := GetAddress('DRBUF');\n    @FreeTDSAPI.dbrecftos       := GetAddress('dbrecftos');\n    @FreeTDSAPI.dbresults_r     := GetAddress('dbresults_r');\n    //@FreeTDSAPI.dbsechandle     := GetAddress('dbsechandle');\n    @FreeTDSAPI.dbservcharset   := GetAddress('dbservcharset');\n    @FreeTDSAPI.dbsafestr       := GetAddress('dbsafestr');\n    //@FreeTDSAPI.dbsetbusy       := GetAddress('dbsetbusy');\n    @FreeTDSAPI.dbsetdefcharset := GetAddress('dbsetdefcharset');\n    @FreeTDSAPI.dbsetifile      := GetAddress('dbsetifile');\n    //@FreeTDSAPI.dbsetinterrupt  := GetAddress('dbsetinterrupt');\n    @FreeTDSAPI.dbsetmaxprocs   := GetAddress('dbsetmaxprocs');\n    @FreeTDSAPI.dbsetopt        := GetAddress('dbsetopt');\n    @FreeTDSAPI.dbsetrow        := GetAddress('dbsetrow');\n    @FreeTDSAPI.dbsetversion    := GetAddress('dbsetversion');\n    @FreeTDSAPI.dbspid          := GetAddress('dbspid');\n    @FreeTDSAPI.dbspr1row       := GetAddress('dbspr1row');\n    @FreeTDSAPI.dbspr1rowlen    := GetAddress('dbspr1rowlen');\n    @FreeTDSAPI.dbsprhead       := GetAddress('dbsprhead');\n    @FreeTDSAPI.dbsprline       := GetAddress('dbsprline');\n    @FreeTDSAPI.dbvarylen       := GetAddress('dbvarylen');\n\n    @FreeTDSAPI.dbtds           := GetAddress('dbtds');\n    @FreeTDSAPI.dbtextsize      := GetAddress('dbtextsize');\n    @FreeTDSAPI.dbwillconvert   := GetAddress('dbwillconvert');\n\n    (* LOGINREC manipulation *)\n    @FreeTDSAPI.dbsetlbool      := GetAddress('dbsetlbool');\n    @FreeTDSAPI.dbsetllong      := GetAddress('dbsetllong');\n    @FreeTDSAPI.dbsetlversion   := GetAddress('dbsetlversion');\n    @FreeTDSAPI.tdsdump_open    := GetAddress('tdsdump_open');\n    @FreeTDSAPI.tdsdump_on      := GetAddress('tdsdump_on');\n    @FreeTDSAPI.tdsdump_off     := GetAddress('tdsdump_off');\n    @FreeTDSAPI.tdsdump_close   := GetAddress('tdsdump_close');\n\n  end;\n  FreeTDSAPI.dbinit;\n\n  OldFreeTDSErrorHandle := DBLibAPI.dberrhandle(DbLibErrorHandle);\n  OldFreeTDSMessageHandle := DBLibAPI.dbmsghandle(DbLibMessageHandle);\nend;\n\nconstructor TZFreeTDSBasePlainDriver.Create;\nbegin\n  inherited create;\n\n  DBVariables.DBoptions[Z_PARSEONLY]      := TDSPARSEONLY;\n  DBVariables.DBoptions[Z_ESTIMATE]       := TDSESTIMATE;\n  DBVariables.DBoptions[Z_SHOWPLAN]       := TDSSHOWPLAN;\n  DBVariables.DBoptions[Z_NOEXEC]         := TDSNOEXEC;\n  DBVariables.DBoptions[Z_ARITHIGNORE]    := TDSARITHIGNORE;\n  DBVariables.DBoptions[Z_NOCOUNT]        := TDSNOCOUNT;\n  DBVariables.DBoptions[Z_ARITHABORT]     := TDSARITHABORT;\n  DBVariables.DBoptions[Z_TEXTLIMIT]      := TDSTEXTLIMIT;\n  DBVariables.DBoptions[Z_BROWSE]         := TDSBROWSE;\n  DBVariables.DBoptions[Z_OFFSET]         := TDSOFFSET;\n  DBVariables.DBoptions[Z_STAT]           := TDSSTAT;\n  DBVariables.DBoptions[Z_ERRLVL]         := TDSERRLVL;\n  DBVariables.DBoptions[Z_CONFIRM]        := TDSCONFIRM;\n  DBVariables.DBoptions[Z_STORPROCID]     := TDSSTORPROCID;\n  DBVariables.DBoptions[Z_BUFFER]         := TDSBUFFER;\n  DBVariables.DBoptions[Z_NOAUTOFREE]     := TDSNOAUTOFREE;\n  DBVariables.DBoptions[Z_ROWCOUNT]       := TDSROWCOUNT;\n  DBVariables.DBoptions[Z_TEXTSIZE]       := TDSTEXTSIZE;\n  DBVariables.DBoptions[Z_NATLANG]        := TDSNATLANG;\n  DBVariables.DBoptions[Z_DATEFORMAT]     := TDSDATEFORMAT;\n  DBVariables.DBoptions[Z_PRPAD]          := TDSPRPAD;\n  DBVariables.DBoptions[Z_PRCOLSEP]       := TDSPRCOLSEP;\n  DBVariables.DBoptions[Z_PRLINELEN]      := TDSPRLINELEN;\n  DBVariables.DBoptions[Z_PRLINESEP]      := TDSPRLINESEP;\n  DBVariables.DBoptions[Z_LFCONVERT]      := TDSLFCONVERT;\n  DBVariables.DBoptions[Z_DATEFIRST]      := TDSDATEFIRST;\n  DBVariables.DBoptions[Z_CHAINXACTS]     := TDSCHAINXACTS;\n  DBVariables.DBoptions[Z_FIPSFLAG]\t      := TDSFIPSFLAG;\n  DBVariables.DBoptions[Z_ISOLATION]      := TDSISOLATION;\n  DBVariables.DBoptions[Z_AUTH]           := TDSAUTH;\n  DBVariables.DBoptions[Z_IDENTITY]       := TDSIDENTITY;\n  DBVariables.DBoptions[Z_NOIDCOL]        := TDSNOIDCOL;\n  DBVariables.DBoptions[Z_DATESHORT]      := TDSDATESHORT;\n  DBVariables.DBoptions[Z_CLIENTCURSORS]  := TDSCLIENTCURSORS;\n  DBVariables.DBoptions[Z_SETTIME]        := TDSSETTIME;\n  DBVariables.DBoptions[Z_QUOTEDIDENT]    := TDSQUOTEDIDENT;\n  DBVariables.DBoptions[Z_NUMOPTIONS]     := TDSNUMOPTIONS;\n  DBVariables.DBoptions[Z_PADOFF]         := TDSPADOFF;\n  DBVariables.DBoptions[Z_PADON]          := TDSPADON;\n  DBVariables.DBoptions[Z_OFF]            := TDSOFF;\n  DBVariables.DBoptions[Z_ON]             := TDSON;\n  DBVariables.DBoptions[Z_NOSUCHOPTION]   := NOSUCHOPTION;\n  DBVariables.DBoptions[Z_MAXOPTTEXT]     := MAXOPTTEXT;\n  {TDS Loginrec manipulations}\n  DBVariables.DBSetLoginRec[Z_SETHOST]    := TDSDBSETHOST;\n  DBVariables.DBSetLoginRec[Z_SETUSER]    := TDSDBSETUSER;\n  DBVariables.DBSetLoginRec[Z_SETPWD]     := TDSDBSETPWD;\n  DBVariables.DBSetLoginRec[Z_SETHID]     := TDSDBSETHID;\n  DBVariables.DBSetLoginRec[Z_SETAPP]     := TDSDBSETAPP;\n  DBVariables.DBSetLoginRec[Z_SETBCP]     := TDSDBSETBCP;\n  DBVariables.DBSetLoginRec[Z_SETSECURE]  := TDSDBSETSECURE;\n  DBVariables.DBSetLoginRec[Z_SETLANG]    := TDSDBSETLANG;\n  DBVariables.DBSetLoginRec[Z_SETNOSHORT] := TDSDBSETNOSHORT;\n  DBVariables.DBSetLoginRec[Z_SETHIER]    := TDSDBSETHIER;\n  DBVariables.DBSetLoginRec[Z_SETCHARSET] := TDSDBSETCHARSET;\n  DBVariables.DBSetLoginRec[Z_SETPACKET]  := TDSDBSETPACKET;\n  DBVariables.DBSetLoginRec[Z_SETENCRYPT] := TDSDBSETENCRYPT;\n  DBVariables.DBSetLoginRec[Z_SETLABELED] := TDSDBSETLABELED;\n  DBVariables.DBSetLoginRec[Z_SETDBNAME]  := TDSDBSETDBNAME;\n  {datatypes}\n  DBVariables.datatypes[Z_SQLVOID]      := TDSSQLVOID;\n  DBVariables.datatypes[Z_SQLTEXT]      := TDSSQLTEXT;\n  DBVariables.datatypes[Z_SQLVARBINARY] := TDSSQLVARBINARY;\n  DBVariables.datatypes[Z_SQLINTN]      := TDSSQLINTN;\n  DBVariables.datatypes[Z_SQLVARCHAR]   := TDSSQLVARCHAR;\n  DBVariables.datatypes[Z_SQLBINARY]    := TDSSQLBINARY;\n  DBVariables.datatypes[Z_SQLIMAGE]     := TDSSQLIMAGE;\n  DBVariables.datatypes[Z_SQLCHAR]      := TDSSQLCHAR;\n  DBVariables.datatypes[Z_SQLINT1]      := TDSSQLINT1;\n  DBVariables.datatypes[Z_SQLBIT]       := TDSSQLBIT;\n  DBVariables.datatypes[Z_SQLINT2]      := TDSSQLINT2;\n  DBVariables.datatypes[Z_SQLINT4]      := TDSSQLINT4;\n  DBVariables.datatypes[Z_SQLMONEY]     := TDSSQLMONEY;\n  DBVariables.datatypes[Z_SQLDATETIME]  := TDSSQLDATETIME;\n  DBVariables.datatypes[Z_SQLFLT8]      := TDSSQLFLT8;\n  DBVariables.datatypes[Z_SQLFLTN]      := TDSSQLFLTN;\n  DBVariables.datatypes[Z_SQLMONEYN]    := TDSSQLMONEYN;\n  DBVariables.datatypes[Z_SQLDATETIMN]  := TDSSQLDATETIMN;\n  DBVariables.datatypes[Z_SQLFLT4]      := TDSSQLFLT4;\n  DBVariables.datatypes[Z_SQLMONEY4]    := TDSSQLMONEY4;\n  DBVariables.datatypes[Z_SQLDATETIM4]  := TDSSQLDATETIM4;\n  DBVariables.datatypes[Z_SQLDECIMAL]   := TDSSQLDECIMAL;\n  DBVariables.datatypes[Z_SQLNUMERIC]   := TDSSQLNUMERIC;\nend;\n\ndestructor TZFreeTDSBasePlainDriver.Destroy;\nbegin\n  if Loader.Loaded then\n  begin\n    DBLibAPI.dberrhandle(OldFreeTDSErrorHandle);\n    DBLibAPI.dbmsghandle(OldFreeTDSMessageHandle);\n    DBLibAPI.dbexit;\n  end;\n  inherited Destroy;\nend;\n\nfunction TZFreeTDSBasePlainDriver.GetProtocol: string;\nbegin\n  Result := 'FreeTDS';\nend;\n\nfunction TZFreeTDSBasePlainDriver.GetDescription: string;\nbegin\n  Result := 'Native FreeTDS driver for Sybase and MSSQL Servers';\nend;\n\nfunction TZFreeTDSBasePlainDriver.dbLogin: PLOGINREC;\nbegin\n  Result := inherited dbLogin;\n  if not Assigned(Result)  then\n    if not  (dbsetlversion(Result) = DBSUCCEED ) then\n    begin\n      dbloginfree(Result);\n      Result := nil;\n    end;\nend;\n\nfunction TZFreeTDSBasePlainDriver.dbSetLCharSet(Login: PLOGINREC; CharsetName: PAnsiChar): RETCODE;\nbegin\n  Result := DBLibAPI.dbsetlname(Login, CharsetName, DBVariables.dbSetLoginRec[Z_SETCHARSET]);\nend;\n\nfunction TZFreeTDSBasePlainDriver.dbSetLSecure(Login: PLOGINREC): RETCODE;\nbegin\n  Result := DBLibAPI.dbsetlname(Login, nil, DBVariables.dbSetLoginRec[Z_SETSECURE]);\n//  Result := FreeTDSAPI.dbsetlbool(Login, 1, Self.DBVariables.dbSetLoginRec[Z_SETSECURE]);\nend;\n\nfunction TZFreeTDSBasePlainDriver.dbsetlversion(Login: PLOGINREC): RETCODE;\nbegin\n  Result := FreeTDSAPI.dbsetlversion(Login, TDSDBVERSION_UNKNOWN);\nend;\n\nfunction TZFreeTDSBasePlainDriver.dbsetversion: RETCODE;\nbegin\n  Result := FreeTDSAPI.dbsetversion(TDSDBVERSION_UNKNOWN);\nend;\n\nprocedure TZFreeTDSBasePlainDriver.tdsDumpOff;\nbegin\n  FreeTDSAPI.tdsdump_off();\nend;\n\nprocedure TZFreeTDSBasePlainDriver.tdsDumpOn;\nbegin\n  FreeTDSAPI.tdsdump_on();\nend;\n\nprocedure TZFreeTDSBasePlainDriver.tdsDump_Close;\nbegin\n  FreeTDSAPI.tdsdump_close();\nend;\n\nprocedure TZFreeTDSBasePlainDriver.tdsDump_Open(const FileName: String);\nbegin\n  FreeTDSAPI.tdsdump_open(PAnsiChar( AnsiString(FileName) ));\nend;\n\nfunction TZFreeTDSBasePlainDriver.dbdataready(Proc: PDBPROCESS): LongBool;\nbegin\n  Result := Proc <> nil;\nend;\n\nprocedure TZFreeTDSBasePlainDriver.dbfreelogin(Login: PLOGINREC);\nbegin\n  FreeTDSAPI.dbloginfree(Login);\nend;\n\nfunction TZFreeTDSBasePlainDriver.dbDead(dbProc: PDBPROCESS): Boolean;\nbegin\n  Result := FreeTDSAPI.dbDead(dbProc) = 1;\nend;\n\nprocedure TZFreeTDSBasePlainDriver.dbLoginFree(Login: PLOGINREC);\nbegin\n  FreeTDSAPI.dbloginfree(Login);\nend;\n\nfunction TZFreeTDSBasePlainDriver.dbsetmaxprocs(\n  MaxProcs: SmallInt): RETCODE;\nbegin\n  Result := FreeTDSAPI.dbsetmaxprocs(MaxProcs);\nend;\n\nfunction TZFreeTDSBasePlainDriver.dbSetOpt(dbProc: PDBPROCESS; Option: Integer; Char_Param: PAnsiChar = nil; Int_Param: Integer = -1): RETCODE;\nbegin\n  Result := FreeTDSAPI.dbSetOpt(dbProc, Option, Char_Param, Int_Param);\nend;\n\nfunction TZFreeTDSBasePlainDriver.dbSetTime(queryTime: Integer): RETCODE;\nbegin\n  Result := FreeTDSAPI.dbsetmaxprocs(queryTime);\nend;\n\nfunction TZFreeTDSBasePlainDriver.dbClose(dbProc: PDBPROCESS): RETCODE;\nbegin\n  FreeTDSAPI.dbClose(dbProc);\n  Result := DBNOERR;\nend;\n\nfunction TZFreeTDSBasePlainDriver.dbDatLen(dbProc: PDBPROCESS; Column: Integer): Integer;\nbegin\n  Result := FreeTDSAPI.dbDatLen(dbProc, Column);\nend;\n\nfunction TZFreeTDSBasePlainDriver.dbCount(dbProc: PDBPROCESS): Integer;\nbegin\n  Result := FreeTDSAPI.dbCount(dbProc);\nend;\n\nfunction TZFreeTDSBasePlainDriver.dbcolbrowse(Proc: PDBPROCESS; Column: Integer): LongBool;\nbegin\n  Result := FreeTDSAPI.dbcolbrowse(Proc, Column) <> 0;\nend;\n\nfunction TZFreeTDSBasePlainDriver.dbHasRetStat(dbProc: PDBPROCESS): Boolean;\nbegin\n  if Assigned(FreeTDSAPI.dbHasRetStat) then\n    Result := FreeTDSAPI.dbHasRetStat(dbProc) <> 0\n  else\n    Result := False;\nend;\n\nfunction TZFreeTDSBasePlainDriver.dbColInfo(dbProc: PDBPROCESS;\n  Column: Integer; var ADBInfo: DBCOL): RETCODE;\nbegin\n  FillChar(ADBInfo, SizeOf(DBCol), #0);\n  ADBInfo.SizeOfStruct := SizeOf(DBCol);\n  Result := FreeTDSAPI.dbcolinfo(dbProc, CI_REGULAR, Column, 0, @ADBInfo);\nend;\n\n{ TZFreeTDS42MsSQLPlainDriver }\nfunction TZFreeTDS42MsSQLPlainDriver.Clone: IZPlainDriver;\nbegin\n  Result := TZFreeTDS42MsSQLPlainDriver.Create;\nend;\n\nprocedure TZFreeTDS42MsSQLPlainDriver.LoadCodePages;\nbegin\n  AddmMSCodePages(Self);\nend;\n\nconstructor TZFreeTDS42MsSQLPlainDriver.Create;\nbegin\n  inherited Create;\n  {$IFDEF MSWINDOWS}\n    FLoader.AddLocation(FREETDS_MSSQL_WINDOWS_DLL_LOCATION);\n  {$ELSE}\n    {$IFDEF UNIX}\n    FLoader.AddLocation(FREETDS_LINUX_DLL_LOCATION);\n    {$ELSE}\n    FLoader.AddLocation(FREETDS_OSX_DLL_LOCATION);\n    {$ENDIF}\n  {$ENDIF}\n  LoadCodePages;\nend;\n\nfunction TZFreeTDS42MsSQLPlainDriver.GetProtocol: string;\nbegin\n  Result := 'FreeTDS_MsSQL<=6.5';\nend;\n\nfunction TZFreeTDS42MsSQLPlainDriver.GetDescription: string;\nbegin\n  Result := 'FreeTDS 4.2 protocol for MsSQL <=6.5 Servers';\nend;\n\nfunction TZFreeTDS42MsSQLPlainDriver.dbsetlversion(Login: PLOGINREC): RETCODE;\nbegin\n  Result := FreeTDSAPI.dbsetlversion(Login, DBVERSION_42);\nend;\n\nfunction TZFreeTDS42MsSQLPlainDriver.dbsetversion: RETCODE;\nbegin\n  Result := FreeTDSAPI.dbsetversion(TDSDBVERSION_42);\nend;\n\n{ TZFreeTDS42SybasePlainDriver }\nfunction TZFreeTDS42SybasePlainDriver.Clone: IZPlainDriver;\nbegin\n  Result := TZFreeTDS42SybasePlainDriver.Create;\nend;\n\nprocedure TZFreeTDS42SybasePlainDriver.LoadCodePages;\nbegin\n  AddCodePage('Not implemented!', -1);\n   { TODO -oEgonHugeist : Must be completed!!!! }\nend;\n\nconstructor TZFreeTDS42SybasePlainDriver.Create;\nbegin\n  inherited Create;\n  {$IFDEF MSWINDOWS}\n    FLoader.AddLocation(FREETDS_SYBASE_WINDOWS_DLL_LOCATION);\n  {$ELSE}\n    {$IFDEF UNIX}\n    FLoader.AddLocation(FREETDS_LINUX_DLL_LOCATION);\n    {$ELSE}\n    FLoader.AddLocation(FREETDS_OSX_DLL_LOCATION);\n    {$ENDIF}\n  {$ENDIF}\nend;\n\nfunction TZFreeTDS42SybasePlainDriver.GetProtocol: string;\nbegin\n  Result := 'FreeTDS_Sybase<10';\nend;\n\nfunction TZFreeTDS42SybasePlainDriver.GetDescription: string;\nbegin\n  Result := 'FreeTDS 4.2 protocol for Sybase <10 Servers';\nend;\n\nfunction TZFreeTDS42SybasePlainDriver.dbsetlversion(Login: PLOGINREC): RETCODE;\nbegin\n  Result := DBSUCCEED;\nend;\n\nfunction TZFreeTDS42SybasePlainDriver.dbsetversion: RETCODE;\nbegin\n  Result := FreeTDSAPI.dbsetversion(TDSDBVERSION_42);\nend;\n\n{ TZFreeTDS50PlainDriver }\nfunction TZFreeTDS50PlainDriver.Clone: IZPlainDriver;\nbegin\n  Result := TZFreeTDS50PlainDriver.Create;\nend;\n\nprocedure TZFreeTDS50PlainDriver.LoadCodePages;\nbegin\n  AddSybaseCodePages(Self);\nend;\n\nconstructor TZFreeTDS50PlainDriver.Create;\nbegin\n  inherited Create;\n  LoadCodePages;\nend;\n\nfunction TZFreeTDS50PlainDriver.GetProtocol: string;\nbegin\n  Result := 'FreeTDS_Sybase-10+';\nend;\n\nfunction TZFreeTDS50PlainDriver.GetDescription: string;\nbegin\n  Result := 'FreeTDS 5.0 Protocol for Sybase >= 10 Servers ';\nend;\n\nfunction TZFreeTDS50PlainDriver.dbsetversion: RETCODE;\nbegin\n  Result := FreeTDSAPI.dbsetversion(TDSDBVERSION_46);\nend;\n\n{ TZFreeTDS70PlainDriver }\nfunction TZFreeTDS70PlainDriver.Clone: IZPlainDriver;\nbegin\n  Result := TZFreeTDS70PlainDriver.Create;\nend;\n\nprocedure TZFreeTDS70PlainDriver.LoadCodePages;\nbegin\n  inherited;\nend;\n\nfunction TZFreeTDS70PlainDriver.GetProtocol: string;\nbegin\n  Result := 'FreeTDS_MsSQL-7.0';\nend;\n\nfunction TZFreeTDS70PlainDriver.dbsetlversion(Login: PLOGINREC): RETCODE;\nbegin\n  Result := FreeTDSAPI.dbsetlversion(Login, DBVERSION_70);\nend;\n\nfunction TZFreeTDS70PlainDriver.GetDescription: string;\nbegin\n  Result := 'FreeTDS 7.0 Protocol for MsSQL 7.0 Servers';\nend;\n\nfunction TZFreeTDS70PlainDriver.dbsetversion: RETCODE;\nbegin\n  Result := FreeTDSAPI.dbsetversion(TDSDBVERSION_70);\nend;\n\n{ TZFreeTDS71PlainDriver }\nfunction TZFreeTDS71PlainDriver.Clone: IZPlainDriver;\nbegin\n  Result := TZFreeTDS71PlainDriver.Create;\nend;\n\nprocedure TZFreeTDS71PlainDriver.LoadCodePages;\nbegin\n  Inherited;\nend;\n\nfunction TZFreeTDS71PlainDriver.GetProtocol: string;\nbegin\n  Result := 'FreeTDS_MsSQL-2000';\nend;\n\nfunction TZFreeTDS71PlainDriver.GetDescription: string;\nbegin\n  Result := 'FreeTDS 7.1 Protocol for MsSQL 2000 Servers';\nend;\n\nfunction TZFreeTDS71PlainDriver.dbsetversion: RETCODE;\nbegin\n  Result := FreeTDSAPI.dbsetversion(TDSDBVERSION_70);\nend;\n\n{ TZFreeTDS72PlainDriver }\nfunction TZFreeTDS72PlainDriver.Clone: IZPlainDriver;\nbegin\n  Result := TZFreeTDS72PlainDriver.Create;\nend;\n\nprocedure TZFreeTDS72PlainDriver.LoadCodePages;\nbegin\n  inherited;\nend;\n\nfunction TZFreeTDS72PlainDriver.GetProtocol: string;\nbegin\n  Result := 'FreeTDS_MsSQL>=2005';\nend;\n\nfunction TZFreeTDS72PlainDriver.GetDescription: string;\nbegin\n  Result := 'FreeTDS 7.2 Protocol for MsSQL 2005, 2008, 2012 Servers';\nend;\n\nfunction TZFreeTDS72PlainDriver.dbsetversion: RETCODE;\nbegin\n  Result := FreeTDSAPI.dbsetversion(TDSDBVERSION_72);\nend;\n\ninitialization\n  SQLErrors := TList.Create;\n  SQLMessages := TList.Create;\nfinalization\n//Free any record in the list if any\n  while SQLErrors.Count > 0 do\n  begin\n    Dispose(SQLErrors.Items[0]);\n    SQLErrors.Delete(0);\n  end;\n  if SQLErrors <> nil then\n    FreeAndNil(SQLErrors);\n\n//Free any record in the list if any\n  while SQLMessages.Count > 0 do\n  begin\n    Dispose(SQLMessages.Items[0]);\n    SQLMessages.Delete(0);\n  end;\n  if SQLMessages <> nil then\n    FreeAndNil(SQLMessages);\nend.\n"
  },
  {
    "path": "lib/zeosdbo/src/plain/ZPlainDriver.pas",
    "content": "{*********************************************************}\n{                                                         }\n{                 Zeos Database Objects                   }\n{            Interfaces for Native Plain Drivers          }\n{                                                         }\n{        Originally written by Sergey Seroukhov           }\n{                                                         }\n{*********************************************************}\n\n{@********************************************************}\n{    Copyright (c) 1999-2012 Zeos Development Group       }\n{                                                         }\n{ License Agreement:                                      }\n{                                                         }\n{ This library is distributed in the hope that it will be }\n{ useful, but WITHOUT ANY WARRANTY; without even the      }\n{ implied warranty of MERCHANTABILITY or FITNESS FOR      }\n{ A PARTICULAR PURPOSE.  See the GNU Lesser General       }\n{ Public License for more details.                        }\n{                                                         }\n{ The source code of the ZEOS Libraries and packages are  }\n{ distributed under the Library GNU General Public        }\n{ License (see the file COPYING / COPYING.ZEOS)           }\n{ with the following  modification:                       }\n{ As a special exception, the copyright holders of this   }\n{ library give you permission to link this library with   }\n{ independent modules to produce an executable,           }\n{ regardless of the license terms of these independent    }\n{ modules, and to copy and distribute the resulting       }\n{ executable under terms of your choice, provided that    }\n{ you also meet, for each linked independent module,      }\n{ the terms and conditions of the license of that module. }\n{ An independent module is a module which is not derived  }\n{ from or based on this library. If you modify this       }\n{ library, you may extend this exception to your version  }\n{ of the library, but you are not obligated to do so.     }\n{ If you do not wish to do so, delete this exception      }\n{ statement from your version.                            }\n{                                                         }\n{                                                         }\n{ The project web site is located on:                     }\n{   http://zeos.firmos.at  (FORUM)                        }\n{   http://sourceforge.net/p/zeoslib/tickets/ (BUGTRACKER)}\n{   svn://svn.code.sf.net/p/zeoslib/code-0/trunk (SVN)    }\n{                                                         }\n{   http://www.sourceforge.net/projects/zeoslib.          }\n{                                                         }\n{                                                         }\n{                                 Zeos Development Group. }\n{********************************************************@}\n\nunit ZPlainDriver;\n\ninterface\n\n{$I ZPlain.inc}\n\nuses ZClasses, ZPlainLoader, ZCompatibility, Types, ZTokenizer;\n\ntype\n\n  {** Represents a generic interface to plain driver. }\n  IZPlainDriver = interface (IZInterface)\n    ['{2A0CC600-B3C4-43AF-92F5-C22A3BB1BB7D}']\n    function IsAnsiDriver: Boolean;\n    function GetProtocol: string;\n    function GetDescription: string;\n    {EgonHugeist:\n      Why this here? -> No one else then Plaindriver knows which Characterset\n      is supported. Here i've made a intervention in dependency of used Compiler.}\n    function GetSupportedClientCodePages(const {$IFNDEF UNICODE}AutoEncode,{$ENDIF} IgnoreUnsupported: Boolean;\n      CtrlsCPType: TZControlsCodePage = cCP_UTF16): TStringDynArray;\n    function ValidateCharEncoding(const CharacterSetName: String; const DoArrange: Boolean = False): PZCodePage; overload;\n    function ValidateCharEncoding(const CharacterSetID: Integer; const DoArrange: Boolean = False): PZCodePage; overload;\n    function ZDbcString(const Ansi: RawByteString; ConSettings: PZConSettings): String;\n    function ZPlainString(const AStr: String; ConSettings: PZConSettings): RawByteString; overload;\n    function ZPlainString(const AStr: WideString; ConSettings: PZConSettings): RawByteString; overload;\n    function ZPlainString(const AStr: String; ConSettings: PZConSettings; const ToCP: Word): RawByteString; overload;\n    function ZDbcUnicodeString(const AStr: RawByteString; const FromCP: Word): ZWideString; overload;\n    function GetPrepreparedSQL(Handle: Pointer; const SQL: String;\n    ConSettings: PZConSettings; out LogSQL: String): RawByteString;\n    function EscapeString(Handle: Pointer; const Value: ZWideString;\n      ConSettings: PZConSettings): ZWideString; overload;\n    function EscapeString(Handle: Pointer; const Value: RawByteString;\n      ConSettings: PZConSettings; WasEncoded: Boolean = False): RawByteString; overload;\n    procedure Initialize(const Location: String = '');\n    function Clone: IZPlainDriver;\n  end;\n\n  {ADDED by fduenas 15-06-2006}\n  {** Base class of a generic plain driver with TZNativeLibraryLoader-object. }\n\n  TZAbstractPlainDriver = class(TZCodePagedObject, IZPlainDriver)\n  protected\n    FCodePages: array of TZCodePage;\n    FTokenizer: IZTokenizer;\n    FLoader: TZNativeLibraryLoader;\n    procedure LoadApi; virtual;\n    function IsAnsiDriver: Boolean; virtual;\n    function Clone: IZPlainDriver; reintroduce; virtual; abstract;\n    procedure LoadCodePages; virtual; abstract;\n    function GetUnicodeCodePageName: String; virtual;\n    function ValidateCharEncoding(const CharacterSetName: String; const DoArrange: Boolean = False): PZCodePage; overload;\n    function ValidateCharEncoding(const CharacterSetID: Integer; const DoArrange: Boolean = False): PZCodePage; overload;\n    function GetPrepreparedSQL(Handle: Pointer; const SQL: String;\n      ConSettings: PZConSettings; out LogSQL: String): RawByteString; virtual;\n    function EscapeString(Handle: Pointer; const Value: ZWideString;\n      ConSettings: PZConSettings): ZWideString; overload;\n    function EscapeString(Handle: Pointer; const Value: RawByteString;\n      ConSettings: PZConSettings; WasEncoded: Boolean = False): RawByteString; overload; virtual;\n    function GetTokenizer: IZTokenizer;\n  public\n    constructor Create;\n    constructor CreateWithLibrary(const LibName : String);\n    destructor Destroy; override;\n    function GetProtocol: string; virtual; abstract;\n    function GetDescription: string; virtual; abstract;\n    function GetSupportedClientCodePages(const {$IFNDEF UNICODE}AutoEncode,{$ENDIF} IgnoreUnsupported: Boolean;\n      CtrlsCPType: TZControlsCodePage = cCP_UTF16): TStringDynArray;\n    procedure Initialize(const Location: String = ''); virtual;\n\n    property Loader: TZNativeLibraryLoader read FLoader;\n    procedure AddCodePage(const Name: String; const ID:  Integer;\n      Encoding: TZCharEncoding = ceAnsi; const CP: Word = $ffff;\n      const ZAlias: String = ''; CharWidth: Integer = 1;\n      const ConsistentCP: Boolean = True);\n    procedure ResetCodePage(const OldID: Integer; const Name: String;\n      const ID:  Integer; {may be an ordinal value of predefined Types...}\n      Encoding: TZCharEncoding = ceAnsi; const CP: Word = $ffff;\n      const ZAlias: String = ''; CharWidth: Integer = 1;\n      const ConsistentCP: Boolean = True);\n  end;\n  {END ADDED by fduenas 15-06-2006}\n\nimplementation\n\nuses SysUtils, ZEncoding{$IFDEF WITH_UNITANSISTRINGS}, AnsiStrings{$ENDIF};\n\n\n{TZAbstractPlainDriver}\n\nfunction TZAbstractPlainDriver.IsAnsiDriver: Boolean;\nbegin\n  Result := True;\nend;\n\nfunction TZAbstractPlainDriver.GetUnicodeCodePageName: String;\nbegin\n  Result := '';\nend;\n\n{**\n   Checks if the given ClientCharacterSet and returns the PZCodePage\n   @param CharacterSetName the Name wich has to be validated\n   @param DoArrange means if the CharacterSet is empty or unsupported then find\n          a supported CodePage\n   @result the PZCodePage of the ClientCharacterSet\n}\nfunction TZAbstractPlainDriver.ValidateCharEncoding(const CharacterSetName: String;\n  const DoArrange: Boolean = False): PZCodePage;\n\n  function GetClientCodePageInformations(\n    const ClientCharacterSet: String): PZCodePage;\n  var\n    I: Integer;\n  begin\n    {now check for PlainDriver-Informations...}\n    {$IFDEF FPC} //if the user didn't set it\n    if ClientCharacterSet = '' then\n    begin\n      for i := Low(FCodePages) to high(FCodePages) do\n        if UpperCase(FCodePages[i].Name) = UpperCase(GetUnicodeCodePageName) then\n        begin\n          Result := @FCodePages[i];\n          Exit;\n        end;\n    end\n    else\n    {$ENDIF}\n    for i := Low(FCodePages) to high(FCodePages) do\n      if UpperCase(FCodePages[i].Name) = UpperCase(ClientCharacterSet) then\n      begin\n        Result := @FCodePages[i];\n        Exit;\n      end;\n    Result := @ClientCodePageDummy;\n  end;\nbegin\n  Result := GetClientCodePageInformations(CharacterSetName);\n  if (DoArrange) and (Result^.ZAlias <> '' ) then\n    ValidateCharEncoding(Result^.ZAlias); //recalls em selves\nend;\n\n{**\n   Checks if the given ClientCharacterSet and returns the PZCodePage\n   @param CharacterSetID the ID wich has to be validated\n   @param DoArrange means if the CharacterSet is empty or unsupported then find\n          a supported CodePage\n   @result the PZCodePage of the ClientCharacterSet\n}\nfunction TZAbstractPlainDriver.ValidateCharEncoding(const CharacterSetID: Integer;\n  const DoArrange: Boolean = False): PZCodePage;\n\n  function GetClientCodePageInformations(const ClientCharacterSetID: Word): PZCodePage;\n  var\n    I: Integer;\n  begin\n    {now check for PlainDriver-Informations...}\n    for i := Low(FCodePages) to high(FCodePages) do\n      if FCodePages[i].ID = ClientCharacterSetID then\n      begin\n        Result := @FCodePages[i];\n        Exit;\n      end;\n    Result := @ClientCodePageDummy;\n  end;\nbegin\n  Result := GetClientCodePageInformations(CharacterSetID);\n\n  if (DoArrange) and (Result^.ZAlias <> '' ) then\n    ValidateCharEncoding(Result^.ZAlias); //recalls em selves\nend;\n\nfunction TZAbstractPlainDriver.GetPrepreparedSQL(Handle: Pointer;\n  const SQL: String; ConSettings: PZConSettings; out LogSQL: String): RawByteString;\nvar\n  SQLTokens: TZTokenDynArray;\n  i: Integer;\nbegin\n  Result := '';\n  if ConSettings.AutoEncode then\n  begin\n    SQLTokens := FTokenizer.TokenizeBuffer(SQL, [toSkipEOF]); //Disassembles the Query\n    for i := Low(SQLTokens) to high(SQLTokens) do  //Assembles the Query\n    begin\n      case (SQLTokens[i].TokenType) of\n        ttEscape:\n          Result := Result + {$IFDEF UNICODE}ZPlainString(SQLTokens[i].Value,\n            ConSettings){$ELSE}SQLTokens[i].Value{$ENDIF};\n        ttQuoted,  ttWord, ttQuotedIdentifier, ttKeyword:\n          Result := Result + ZPlainString(SQLTokens[i].Value, ConSettings)\n        else\n          Result := Result + RawByteString(SQLTokens[i].Value);\n      end;\n    end;\n  end\n  else\n    {$IFDEF UNICODE}\n    Result := ZPlainString(SQL, ConSettings);\n    {$ELSE}\n    Result := SQL;\n    {$ENDIF}\n  LogSQL := String(Result);\nend;\n\n{$IFDEF FPC}\n  {$HINTS OFF}\n{$ENDIF}\nfunction TZAbstractPlainDriver.EscapeString(Handle: Pointer;\n  const Value: ZWideString; ConSettings: PZConSettings): ZWideString;\nvar\n  StrFrom: RawByteString;\n  Outbuffer: RawByteString;\nbegin\n  StrFrom := ZPlainString(Value, ConSettings);\n  Outbuffer := EscapeString(Handle, StrFrom, ConSettings, True);\n  {$IFDEF UNICODE}\n  Result := ZDbcString(OutBuffer, ConSettings);\n  {$ELSE}\n  Result := ZDbcUnicodeString(Outbuffer, ConSettings.ClientCodePage.CP);\n  {$ENDIF}\nend;\nfunction TZAbstractPlainDriver.EscapeString(Handle: Pointer;\n  const Value: RawByteString; ConSettings: PZConSettings; WasEncoded: Boolean = False): RawByteString;\nbegin\n  Result := {$IFDEF WITH_UNITANSISTRINGS}AnsiStrings.{$ENDIF}AnsiQuotedStr(Value, #39);\nend;\n{$IFDEF FPC}\n  {$HINTS ON}\n{$ENDIF}\n\nfunction TZAbstractPlainDriver.GetTokenizer: IZTokenizer;\nbegin\n  Result := FTokenizer;\nend;\n\nprocedure TZAbstractPlainDriver.AddCodePage(const Name: String;\n      const ID:  Integer; Encoding: TZCharEncoding = ceAnsi;\n      const CP: Word = $ffff; const ZAlias: String = '';\n      CharWidth: Integer = 1; const ConsistentCP: Boolean = True);\nbegin\n  SetLength(FCodePages, Length(FCodePages)+1);\n  FCodePages[High(FCodePages)].Name := Name;\n  FCodePages[High(FCodePages)].ID := ID;\n  FCodePages[High(FCodePages)].Encoding := Encoding;\n  FCodePages[High(FCodePages)].CP := CP;\n  FCodePages[High(FCodePages)].CharWidth := CharWidth;\n  FCodePages[High(FCodePages)].ZAlias := ZAlias;\n  FCodePages[High(FCodePages)].IsStringFieldCPConsistent := ConsistentCP;\n\n  if CP = $ffff then\n    FCodePages[High(FCodePages)].ZAlias := GetUnicodeCodePageName;\nend;\n\nprocedure TZAbstractPlainDriver.ResetCodePage(const OldID: Integer;\n      const Name: String; const ID:  Integer; Encoding: TZCharEncoding = ceAnsi;\n      const CP: Word = $ffff;\n      const ZAlias: String = ''; CharWidth: Integer = 1;\n      const ConsistentCP: Boolean = True);\nvar\n  I: Integer;\nbegin\n  for i := low(FCodePages) to high(FCodePages) do\n    if OldID = FCodePages[I].ID then\n    begin\n      FCodePages[I].ID := ID;\n      FCodePages[I].Name := Name;\n      FCodePages[I].Encoding := Encoding;\n      FCodePages[I].CP := CP;\n      FCodePages[I].ZAlias := ZAlias;\n      FCodePages[I].CharWidth := CharWidth;\n      FCodePages[I].IsStringFieldCPConsistent := ConsistentCP;\n\n      if CP = $ffff then\n        FCodePages[I].ZAlias := GetUnicodeCodePageName;\n      Break;\n    end;\nend;\n\nfunction TZAbstractPlainDriver.GetSupportedClientCodePages(\n  const {$IFNDEF UNICODE}AutoEncode,{$ENDIF} IgnoreUnsupported: Boolean;\n  CtrlsCPType: TZControlsCodePage = cCP_UTF16): TStringDynArray;\nvar\n  I: Integer;\n\n  procedure AddCurrent;\n  begin\n    SetLength(Result, Length(Result)+1);\n    Result[High(Result)] := FCodePages[i].Name;\n  end;\n\nbegin\n  SetLength(Result, 0);\n  for i := low(FCodePages) to high(FCodePages) do\n    if IgnoreUnsupported then\n      AddCurrent\n    else\n      case CtrlsCPType of\n        cGET_ACP:\n          {$IFDEF UNICODE}\n          AddCurrent; //result are ?valid? but does that makes sence for all if not CP_UTF8?\n          {$ELSE}\n          if ( FCodePages[i].CP = ZDefaultSystemCodePage ) then\n            AddCurrent\n          else\n            if AutoEncode then\n              {$IF defined(MSWINDOWS) or defined(FPC_HAS_BUILTIN_WIDESTR_MANAGER) }\n              AddCurrent //result are ?valid? but does that makes sence for all if not CP_UTF8?\n              {$ELSE}\n                {$IFDEF WITH_LCONVENCODING} //Lazarus only\n                if ( IsLConvEncodingCodePage(FCodePages[i].CP) ) or\n                   ( FCodePages[i].Encoding = ceUTF8 ) then\n                  AddCurrent //allways valid because result is allways UTF8 which lazarus expects\n                {$ENDIF}\n              {$IFEND}\n            else Continue;\n          {$ENDIF}\n        {$IFNDEF UNICODE}\n        cCP_UTF8:\n          if ( FCodePages[i].Encoding = ceUTF8 ) then\n            AddCurrent\n          else\n            if AutoEncode then\n              {$IF defined(MSWINDOWS) or defined(FPC_HAS_BUILTIN_WIDESTR_MANAGER) }\n              AddCurrent //All charsets can be converted to UTF8 if a valid WideString-Manager does exists\n              {$ELSE}\n                {$IFDEF WITH_LCONVENCODING} //Lazarus only\n                if ( IsLConvEncodingCodePage(FCodePages[i].CP) ) then\n                  AddCurrent\n                {$ENDIF}\n              {$IFEND}\n            else Continue;\n        {$ENDIF}\n        else\n          {$IF defined(MSWINDOWS) or defined(FPC_HAS_BUILTIN_WIDESTR_MANAGER) or defined(UNICODE)}\n          AddCurrent; //all remaining charset can be converted to wide if a valid WideString-Manager does exists\n          {$ELSE}\n            {$IFDEF WITH_LCONVENCODING} //Lazarus only\n            if ( IsLConvEncodingCodePage(FCodePages[i].CP) ) or //Lazarus can convert to UTF8 then we convert to wide (double En/Decoding!)\n               ( FCodePages[i].Encoding = ceUTF8 ) or //decode the strings to wide\n               ( FCodePages[i].CP = ZDefaultSystemCodePage ) then //to allow a valid cast\n              AddCurrent; //all these charset can be converted to wide\n            {$ELSE}\n            if ( FCodePages[i].CP = ZDefaultSystemCodePage ) or //to allow a valid cast\n               ( FCodePages[i].Encoding = ceUTF8 ) then //decode the strings to wide\n              AddCurrent;\n            {$ENDIF}\n          {$IFEND}\n      end;\nend;\n\nconstructor TZAbstractPlainDriver.Create;\nbegin\n  inherited Create;\n  FTokenizer := TZTokenizer.Create;\nend;\n\ndestructor TZAbstractPlainDriver.Destroy;\nbegin\n  SetLength(FCodePages, 0);\n  FTokenizer := nil;\n  if Assigned(FLoader) then\n    FreeAndNil(FLoader);\n  inherited Destroy;\nend;\n\n\nprocedure TZAbstractPlainDriver.LoadApi;\nbegin\n\nend;\n\nconstructor TZAbstractPlainDriver.CreateWithLibrary(const LibName: String);\nbegin\n  Inherited Create;\n  if Assigned(FLoader) then\n  begin\n    Loader.ClearLocations;\n    Loader.AddLocation(LibName);\n  end;\nend;\n\nprocedure TZAbstractPlainDriver.Initialize(const Location: String = '');\nbegin\n  If Assigned(Loader) then\n    if not Loader.Loaded then\n    begin\n      if Location <> '' then\n      begin\n        Loader.ClearLocations;\n        Loader.AddLocation(Location);\n      end;\n      If Loader.LoadNativeLibrary then\n        LoadApi;\n    end;\nend;\n\nend.\n\n"
  },
  {
    "path": "lib/zeosdbo/src/plain/ZPlainFirebirdDriver.pas",
    "content": "{*********************************************************}\n{                                                         }\n{                 Zeos Database Objects                   }\n{           Native Plain Drivers for Firebird             }\n{                                                         }\n{        Originally written by Sergey Seroukhov           }\n{                                                         }\n{*********************************************************}\n\n{@********************************************************}\n{    Copyright (c) 1999-2012 Zeos Development Group       }\n{                                                         }\n{ License Agreement:                                      }\n{                                                         }\n{ This library is distributed in the hope that it will be }\n{ useful, but WITHOUT ANY WARRANTY; without even the      }\n{ implied warranty of MERCHANTABILITY or FITNESS FOR      }\n{ A PARTICULAR PURPOSE.  See the GNU Lesser General       }\n{ Public License for more details.                        }\n{                                                         }\n{ The source code of the ZEOS Libraries and packages are  }\n{ distributed under the Library GNU General Public        }\n{ License (see the file COPYING / COPYING.ZEOS)           }\n{ with the following  modification:                       }\n{ As a special exception, the copyright holders of this   }\n{ library give you permission to link this library with   }\n{ independent modules to produce an executable,           }\n{ regardless of the license terms of these independent    }\n{ modules, and to copy and distribute the resulting       }\n{ executable under terms of your choice, provided that    }\n{ you also meet, for each linked independent module,      }\n{ the terms and conditions of the license of that module. }\n{ An independent module is a module which is not derived  }\n{ from or based on this library. If you modify this       }\n{ library, you may extend this exception to your version  }\n{ of the library, but you are not obligated to do so.     }\n{ If you do not wish to do so, delete this exception      }\n{ statement from your version.                            }\n{                                                         }\n{                                                         }\n{ The project web site is located on:                     }\n{   http://zeos.firmos.at  (FORUM)                        }\n{   http://sourceforge.net/p/zeoslib/tickets/ (BUGTRACKER)}\n{   svn://svn.code.sf.net/p/zeoslib/code-0/trunk (SVN)    }\n{                                                         }\n{   http://www.sourceforge.net/projects/zeoslib.          }\n{                                                         }\n{                                                         }\n{                                 Zeos Development Group. }\n{********************************************************@}\n\nunit ZPlainFirebirdDriver;\n\ninterface\n\n{$I ZPlain.inc}\n\n{$IFDEF UNIX}\n{$IFDEF INTERBASE_CRYPT}\n{$DEFINE ENABLE_INTERBASE_CRYPT}\n{$ENDIF}\n{$ENDIF}\n\nuses ZClasses, ZCompatibility, ZPlainDriver, ZPlainLoader, ZPlainFirebirdInterbaseConstants;\n\nconst\n\n  WINDOWSIB6_DLL_LOCATION   = 'gds32.dll';\n  LINUXIB6_DLL_LOCATION   = 'libgds'+SharedSuffix;\n\n  WINDOWS_DLL_LOCATION   = 'gds32.dll';\n  LINUX_DLL_LOCATION   = 'libgds32'+SharedSuffix;\n  LINUX_IB_CRYPT_LOCATION = 'libcrypt'+SharedSuffix;\n\n  WINDOWS2_DLL_LOCATION   = 'fbclient.dll';\n  WINDOWS2_DLL_LOCATION_EMBEDDED = 'fbclientd.dll';\n\n  LINUX2_DLL_LOCATION   = 'libfbclient'+SharedSuffix;\n  LINUX2_DLL_LOCATION_EMBEDDED = 'libfbembed'+SharedSuffix;\n  LINUX2_IB_CRYPT_LOCATION = 'libcrypt'+SharedSuffix;\n\n  WINDOWS15_DLL_LOCATION   = 'fbclient15.dll';\n  WINDOWS15_DLL_LOCATION_EMBEDDED = 'fbclientd15.dll';\n  LINUX15_DLL_LOCATION   = 'libfbclient'+SharedSuffix+'.15';\n  LINUX15_IB_CRYPT_LOCATION = 'libcrypt'+SharedSuffix+'.15';\n  LINUX15_DLL_LOCATION_EMBEDDED = 'libfbembed'+SharedSuffix+'.15';\n\n  WINDOWS20_DLL_LOCATION   = 'fbclient20.dll';\n  WINDOWS20_DLL_LOCATION_EMBEDDED = 'fbclientd20.dll';\n  LINUX2_DLL_LOCATION2   = 'libfbclient'+SharedSuffix+'.2';\n  LINUX20_DLL_LOCATION   = 'libfbclient'+SharedSuffix+'.20';\n  LINUX20_DLL_LOCATION_EMBEDDED = 'libfbembed'+SharedSuffix+'.20';\n  LINUX20_IB_CRYPT_LOCATION = 'libcrypt'+SharedSuffix+'.20';\n\n  WINDOWS21_DLL_LOCATION   = 'fbclient21.dll';\n  WINDOWS21_DLL_LOCATION_EMBEDDED = 'fbclientd21.dll';\n  LINUX21_DLL_LOCATION   = 'libfbclient'+SharedSuffix+'.21';\n  LINUX21_DLL_LOCATION_EMBEDDED = 'libfbembed'+SharedSuffix+'.21';\n  LINUX21_IB_CRYPT_LOCATION = 'libcrypt'+SharedSuffix+'.21';\n\n  WINDOWS25_DLL_LOCATION   = 'fbclient25.dll';\n  WINDOWS25_DLL_LOCATION_EMBEDDED = 'fbclientd25.dll';\n  LINUX25_DLL_LOCATION   = 'libfbclient'+SharedSuffix+'.25';\n  LINUX25_DLL_LOCATION_EMBEDDED = 'libfbembed'+SharedSuffix+'.25';\n  LINUX25_IB_CRYPT_LOCATION = 'libcrypt'+SharedSuffix+'.25';\n\ntype\n\n  {** Represents a generic interface to Interbase native API. }\n  IZInterbasePlainDriver = interface (IZPlainDriver)\n    ['{AE2C4379-4E47-4752-BC01-D405ACC337F5}']\n\n    function GetFirebirdAPI: TZFirebird_API;\n\n    function ZPlainString(const AStr: String; ConSettings: PZConSettings; const ToCP: Word): RawByteString; overload;\n    function ZPlainString(const AStr: WideString; ConSettings: PZConSettings; const ToCP: Word): RawByteString; overload;\n\n    function isc_attach_database (status_vector: PISC_STATUS;\n      db_name_length: Short; db_name: PAnsiChar; db_handle: PISC_DB_HANDLE;\n      parm_buffer_length: Short; parm_buffer: PAnsiChar): ISC_STATUS;\n    function isc_detach_database(status_vector: PISC_STATUS;\n      db_handle: PISC_DB_HANDLE): ISC_STATUS;\n    function isc_drop_database(status_vector: PISC_STATUS;\n      db_handle: PISC_DB_HANDLE): ISC_STATUS;\n    function isc_database_info(status_vector: PISC_STATUS;\n      db_handle: PISC_DB_HANDLE; item_list_buffer_length: Short;\n      item_list_buffer: PAnsiChar; result_buffer_length: Short;\n      result_buffer: PAnsiChar): ISC_STATUS;\n    function isc_array_gen_sdl(status_vector: PISC_STATUS;\n      isc_array_desc: PISC_ARRAY_DESC; isc_arg3: PShort;\n      isc_arg4: PAnsiChar; isc_arg5: PShort): ISC_STATUS;\n    function isc_array_get_slice(status_vector: PISC_STATUS;\n      db_handle: PISC_DB_HANDLE; trans_handle: PISC_TR_HANDLE;\n      array_id: PISC_QUAD; descriptor: PISC_ARRAY_DESC;\n      dest_array: PVoid; slice_length: ISC_LONG): ISC_STATUS;\n    function isc_array_lookup_bounds(status_vector: PISC_STATUS;\n      db_handle: PISC_DB_HANDLE; trans_handle: PISC_TR_HANDLE;\n      table_name, column_name: PAnsiChar;\n      descriptor: PISC_ARRAY_DESC): ISC_STATUS;\n    function isc_array_lookup_desc(status_vector: PISC_STATUS;\n      db_handle: PISC_DB_HANDLE; trans_handle: PISC_TR_HANDLE;\n      table_name, column_name: PAnsiChar;\n      descriptor: PISC_ARRAY_DESC): ISC_STATUS;\n    function isc_array_set_desc(status_vector: PISC_STATUS;\n      table_name: PAnsiChar; column_name: PAnsiChar;\n      sql_dtype, sql_length, sql_dimensions: PShort;\n      descriptor: PISC_ARRAY_DESC): ISC_STATUS;\n    function isc_array_put_slice(status_vector: PISC_STATUS;\n      db_handle: PISC_DB_HANDLE; trans_handle: PISC_TR_HANDLE;\n      array_id: PISC_QUAD; descriptor: PISC_ARRAY_DESC;\n      source_array: PVoid; slice_length: PISC_LONG): ISC_STATUS;\n    function isc_free(isc_arg1: PAnsiChar): ISC_LONG;\n    function isc_sqlcode(status_vector: PISC_STATUS): ISC_LONG;\n    procedure isc_sql_interprete(sqlcode: Short; buffer: PAnsiChar; buffer_length: Short);\n    function isc_interprete(buffer: PAnsiChar; status_vector: PPISC_STATUS): ISC_STATUS;\n    function isc_start_transaction(status_vector: PISC_STATUS;\n      tran_handle: PISC_TR_HANDLE; db_handle_count: Short;\n      db_handle: PISC_DB_HANDLE; tpb_length: Word; tpb_address: PAnsiChar): ISC_STATUS;\n    function isc_start_multiple(status_vector: PISC_STATUS;\n      tran_handle: PISC_TR_HANDLE; db_handle_count: Short;\n      teb_vector_address: PISC_TEB): ISC_STATUS;\n    function isc_rollback_transaction(status_vector: PISC_STATUS;\n      tran_handle: PISC_TR_HANDLE): ISC_STATUS;\n    function isc_rollback_retaining(status_vector: PISC_STATUS;\n      tran_handle: PISC_TR_HANDLE): ISC_STATUS;\n    function isc_commit_retaining(status_vector: PISC_STATUS;\n      tran_handle: PISC_TR_HANDLE): ISC_STATUS;\n    function isc_commit_transaction(status_vector: PISC_STATUS;\n      tran_handle: PISC_TR_HANDLE): ISC_STATUS;\n    function isc_dsql_allocate_statement(status_vector: PISC_STATUS;\n      db_handle: PISC_DB_HANDLE; stmt_handle: PISC_STMT_HANDLE): ISC_STATUS;\n    function isc_dsql_alloc_statement2(status_vector: PISC_STATUS;\n      db_handle: PISC_DB_HANDLE; stmt_handle: PISC_STMT_HANDLE): ISC_STATUS;\n    function isc_dsql_describe(status_vector: PISC_STATUS;\n      stmt_handle: PISC_STMT_HANDLE; dialect: Word; xsqlda: PXSQLDA): ISC_STATUS;\n    function isc_dsql_describe_bind(status_vector: PISC_STATUS;\n      stmt_handle: PISC_STMT_HANDLE; dialect: Word; xsqlda: PXSQLDA): ISC_STATUS;\n    function isc_dsql_execute(status_vector: PISC_STATUS;\n      tran_handle: PISC_TR_HANDLE; stmt_handle: PISC_STMT_HANDLE; dialect: Word;\n      xsqlda: PXSQLDA): ISC_STATUS;\n    function isc_dsql_execute2(status_vector: PISC_STATUS;\n      tran_handle: PISC_TR_HANDLE; stmt_handle: PISC_STMT_HANDLE; dialect: Word;\n      in_xsqlda, out_xsqlda: PXSQLDA): ISC_STATUS;\n    function isc_dsql_execute_immediate(status_vector: PISC_STATUS;\n      db_handle: PISC_DB_HANDLE; tran_handle: PISC_TR_HANDLE; length: Word;\n      statement: PAnsiChar; dialect: Word; xsqlda: PXSQLDA): ISC_STATUS;\n    function isc_dsql_fetch(status_vector: PISC_STATUS;\n      stmt_handle: PISC_STMT_HANDLE; dialect: Word; xsqlda: PXSQLDA): ISC_STATUS;\n    function isc_dsql_free_statement(status_vector: PISC_STATUS;\n      stmt_handle: PISC_STMT_HANDLE; options: Word): ISC_STATUS;\n    function isc_dsql_prepare(status_vector: PISC_STATUS;\n      tran_handle: PISC_TR_HANDLE; stmt_handle: PISC_STMT_HANDLE;\n      length: Word; statement: PAnsiChar; dialect: Word; xsqlda: PXSQLDA): ISC_STATUS;\n    function isc_dsql_set_cursor_name(status_vector: PISC_STATUS;\n      stmt_handle: PISC_STMT_HANDLE; cursor_name: PAnsiChar; _type: Word): ISC_STATUS;\n    function isc_dsql_sql_info(status_vector: PISC_STATUS;\n      stmt_handle: PISC_STMT_HANDLE; item_length: Short; items: PAnsiChar;\n      buffer_length: Short; buffer: PAnsiChar): ISC_STATUS;\n    function isc_open_blob2(status_vector: PISC_STATUS;\n      db_handle: PISC_DB_HANDLE; tran_handle: PISC_TR_HANDLE;\n      blob_handle: PISC_BLOB_HANDLE; blob_id: PISC_QUAD; bpb_length: Short;\n      bpb_buffer: PAnsiChar): ISC_STATUS;\n    function isc_create_blob2(status_vector: PISC_STATUS;\n      db_handle: PISC_DB_HANDLE; tran_handle: PISC_TR_HANDLE;\n      blob_handle: PISC_BLOB_HANDLE; blob_id: PISC_QUAD; bpb_length: Short;\n      bpb_address: PAnsiChar): ISC_STATUS;\n    function isc_blob_info(status_vector: PISC_STATUS;\n      blob_handle: PISC_BLOB_HANDLE; item_list_buffer_length: Short;\n      item_list_buffer: PAnsiChar; result_buffer_length: Short; result_buffer: PAnsiChar): ISC_STATUS;\n    function isc_close_blob(status_vector: PISC_STATUS;\n      blob_handle: PISC_BLOB_HANDLE): ISC_STATUS;\n    function isc_cancel_blob(status_vector: PISC_STATUS;\n      blob_handle: PISC_BLOB_HANDLE): ISC_STATUS;\n    function isc_get_segment(status_vector: PISC_STATUS;\n      blob_handle: PISC_BLOB_HANDLE; actual_seg_length: PWord;\n      seg_buffer_length: Word; seg_buffer: PAnsiChar): ISC_STATUS;\n    function isc_put_segment(status_vector: PISC_STATUS;\n      blob_handle: PISC_BLOB_HANDLE; seg_buffer_len: Word; seg_buffer: PAnsiChar): ISC_STATUS;\n    function isc_event_block(event_buffer: PPAnsiChar; result_buffer: PPAnsiChar;\n      id_count: Word; event_list: array of PAnsiChar): ISC_LONG;\n    procedure isc_event_counts(status_vector: PISC_STATUS;\n      buffer_length: Short; event_buffer: PAnsiChar; result_buffer: PAnsiChar);\n    function isc_cancel_events(status_vector: PISC_STATUS;\n      db_handle: PISC_DB_HANDLE; event_id: PISC_LONG): ISC_STATUS;\n    function isc_que_events(status_vector: PISC_STATUS;\n      db_handle: PISC_DB_HANDLE; event_id: PISC_LONG; length: Short;\n      event_buffer: PAnsiChar; event_function: TISC_CALLBACK;\n      event_function_arg: PVoid): ISC_STATUS;\n    procedure isc_decode_date(ib_date: PISC_QUAD; tm_date: PCTimeStructure);\n    procedure isc_encode_date(tm_date: PCTimeStructure; ib_date: PISC_QUAD);\n    function isc_vax_integer(buffer: PAnsiChar; length: Short): ISC_LONG;\n\n    procedure isc_decode_sql_date(ib_date: PISC_DATE; tm_date: PCTimeStructure);\n    procedure isc_decode_sql_time(ib_time: PISC_TIME; tm_date: PCTimeStructure);\n    procedure isc_decode_timestamp(ib_timestamp: PISC_TIMESTAMP;\n      tm_date: PCTimeStructure);\n    procedure isc_encode_sql_date(tm_date: PCTimeStructure;\n      ib_date: PISC_DATE);\n    procedure isc_encode_sql_time(tm_date: PCTimeStructure;\n      ib_time: PISC_TIME);\n    procedure isc_encode_timestamp(tm_date: PCTimeStructure;\n      ib_timestamp: PISC_TIMESTAMP);\n  end;\n\n  {** Implements a base driver for Firebird}\n\n  { TZFirebirdBaseDriver }\n\n  TZFirebirdBaseDriver = class (TZAbstractPlainDriver, IZPlainDriver,\n    IZInterbasePlainDriver)\n    FIREBIRD_API : TZFIREBIRD_API;\n  protected\n    FPreLoader : TZNativeLibraryLoader;\n    procedure LoadCodePages; override;\n    function GetUnicodeCodePageName: String; override;\n    {$IFDEF ENABLE_INTERBASE_CRYPT}\n    procedure Initialize; virtual;\n    {$ENDIF}\n    procedure LoadApi; override;\n  public\n    constructor Create;\n    {$IFDEF ENABLE_INTERBASE_CRYPT}\n    destructor Destroy; override;\n    {$ENDIF}\n\n    function GetFirebirdAPI: TZFirebird_API;\n    function isc_attach_database (status_vector: PISC_STATUS;\n      db_name_length: Short; db_name: PAnsiChar; db_handle: PISC_DB_HANDLE;\n      parm_buffer_length: Short; parm_buffer: PAnsiChar): ISC_STATUS;\n    function isc_detach_database(status_vector: PISC_STATUS;\n      db_handle: PISC_DB_HANDLE): ISC_STATUS;\n    function isc_drop_database(status_vector: PISC_STATUS;\n      db_handle: PISC_DB_HANDLE): ISC_STATUS;\n    function isc_database_info(status_vector: PISC_STATUS;\n      db_handle: PISC_DB_HANDLE; item_list_buffer_length: Short;\n      item_list_buffer: PAnsiChar; result_buffer_length: Short;\n      result_buffer: PAnsiChar): ISC_STATUS;\n    function isc_transaction_info(status_vector: PISC_STATUS;\n      tr_handle: PISC_TR_HANDLE; item_list_buffer_length: Short;\n      item_list_buffer: PAnsiChar; result_buffer_length: Short;\n      result_buffer: PAnsiChar): ISC_STATUS;\n    function isc_array_gen_sdl(status_vector: PISC_STATUS;\n      isc_array_desc: PISC_ARRAY_DESC; isc_arg3: PShort;\n      isc_arg4: PAnsiChar; isc_arg5: PShort): ISC_STATUS;\n    function isc_array_get_slice(status_vector: PISC_STATUS;\n      db_handle: PISC_DB_HANDLE; trans_handle: PISC_TR_HANDLE;\n      array_id: PISC_QUAD; descriptor: PISC_ARRAY_DESC;\n      dest_array: PVoid; slice_length: ISC_LONG): ISC_STATUS;\n    function isc_array_lookup_bounds(status_vector: PISC_STATUS;\n      db_handle: PISC_DB_HANDLE; trans_handle: PISC_TR_HANDLE;\n      table_name, column_name: PAnsiChar;\n      descriptor: PISC_ARRAY_DESC): ISC_STATUS;\n    function isc_array_lookup_desc(status_vector: PISC_STATUS;\n      db_handle: PISC_DB_HANDLE; trans_handle: PISC_TR_HANDLE;\n      table_name, column_name: PAnsiChar;\n      descriptor: PISC_ARRAY_DESC): ISC_STATUS;\n    function isc_array_set_desc(status_vector: PISC_STATUS;\n      table_name: PAnsiChar; column_name: PAnsiChar;\n      sql_dtype, sql_length, sql_dimensions: PShort;\n      descriptor: PISC_ARRAY_DESC): ISC_STATUS;\n    function isc_array_put_slice(status_vector: PISC_STATUS;\n      db_handle: PISC_DB_HANDLE; trans_handle: PISC_TR_HANDLE;\n      array_id: PISC_QUAD; descriptor: PISC_ARRAY_DESC;\n      source_array: PVoid; slice_length: PISC_LONG): ISC_STATUS;\n    function isc_free(isc_arg1: PAnsiChar): ISC_LONG;\n    function isc_sqlcode(status_vector: PISC_STATUS): ISC_LONG;\n    procedure isc_sql_interprete(sqlcode: Short; buffer: PAnsiChar;\n      buffer_length: Short);\n    function isc_interprete(buffer: PAnsiChar; status_vector: PPISC_STATUS): ISC_STATUS; virtual;\n    function isc_start_transaction(status_vector: PISC_STATUS;\n      tran_handle: PISC_TR_HANDLE; db_handle_count: Short;\n      db_handle: PISC_DB_HANDLE; tpb_length: Word; tpb_address: PAnsiChar): ISC_STATUS;\n    function isc_start_multiple(status_vector: PISC_STATUS;\n      tran_handle: PISC_TR_HANDLE; db_handle_count: Short;\n      teb_vector_address: PISC_TEB): ISC_STATUS;\n    function isc_rollback_transaction(status_vector: PISC_STATUS;\n      tran_handle: PISC_TR_HANDLE): ISC_STATUS;\n    function isc_rollback_retaining(status_vector: PISC_STATUS;\n      tran_handle: PISC_TR_HANDLE): ISC_STATUS;\n    function isc_commit_retaining(status_vector: PISC_STATUS;\n      tran_handle: PISC_TR_HANDLE): ISC_STATUS;\n    function isc_commit_transaction(status_vector: PISC_STATUS;\n      tran_handle: PISC_TR_HANDLE): ISC_STATUS;\n    function isc_dsql_allocate_statement(status_vector: PISC_STATUS;\n      db_handle: PISC_DB_HANDLE; stmt_handle: PISC_STMT_HANDLE): ISC_STATUS;\n    function isc_dsql_alloc_statement2(status_vector: PISC_STATUS;\n      db_handle: PISC_DB_HANDLE; stmt_handle: PISC_STMT_HANDLE): ISC_STATUS;\n    function isc_dsql_describe(status_vector: PISC_STATUS;\n      stmt_handle: PISC_STMT_HANDLE; dialect: Word; xsqlda: PXSQLDA): ISC_STATUS;\n    function isc_dsql_describe_bind(status_vector: PISC_STATUS;\n      stmt_handle: PISC_STMT_HANDLE; dialect: Word; xsqlda: PXSQLDA): ISC_STATUS;\n    function isc_dsql_execute(status_vector: PISC_STATUS;\n      tran_handle: PISC_TR_HANDLE; stmt_handle: PISC_STMT_HANDLE; dialect: Word;\n      xsqlda: PXSQLDA): ISC_STATUS;\n    function isc_dsql_execute2(status_vector: PISC_STATUS;\n      tran_handle: PISC_TR_HANDLE; stmt_handle: PISC_STMT_HANDLE; dialect: Word;\n      in_xsqlda, out_xsqlda: PXSQLDA): ISC_STATUS;\n    function isc_dsql_execute_immediate(status_vector: PISC_STATUS;\n      db_handle: PISC_DB_HANDLE; tran_handle: PISC_TR_HANDLE; length: Word;\n      statement: PAnsiChar; dialect: Word; xsqlda: PXSQLDA): ISC_STATUS;\n    function isc_dsql_fetch(status_vector: PISC_STATUS;\n      stmt_handle: PISC_STMT_HANDLE; dialect: Word; xsqlda: PXSQLDA): ISC_STATUS;\n    function isc_dsql_free_statement(status_vector: PISC_STATUS;\n      stmt_handle: PISC_STMT_HANDLE; options: Word): ISC_STATUS;\n    function isc_dsql_prepare(status_vector: PISC_STATUS;\n      tran_handle: PISC_TR_HANDLE; stmt_handle: PISC_STMT_HANDLE;\n      length: Word; statement: PAnsiChar; dialect: Word; xsqlda: PXSQLDA): ISC_STATUS;\n    function isc_dsql_set_cursor_name(status_vector: PISC_STATUS;\n      stmt_handle: PISC_STMT_HANDLE; cursor_name: PAnsiChar; _type: Word): ISC_STATUS;\n    function isc_dsql_sql_info(status_vector: PISC_STATUS;\n      stmt_handle: PISC_STMT_HANDLE; item_length: Short; items: PAnsiChar;\n      buffer_length: Short; buffer: PAnsiChar): ISC_STATUS;\n    function isc_open_blob2(status_vector: PISC_STATUS;\n      db_handle: PISC_DB_HANDLE; tran_handle: PISC_TR_HANDLE;\n      blob_handle: PISC_BLOB_HANDLE; blob_id: PISC_QUAD; bpb_length: Short;\n      bpb_buffer: PAnsiChar): ISC_STATUS;\n    function isc_create_blob2(status_vector: PISC_STATUS;\n      db_handle: PISC_DB_HANDLE; tran_handle: PISC_TR_HANDLE;\n      blob_handle: PISC_BLOB_HANDLE; blob_id: PISC_QUAD; bpb_length: Short;\n      bpb_address: PAnsiChar): ISC_STATUS;\n    function isc_blob_info(status_vector: PISC_STATUS;\n      blob_handle: PISC_BLOB_HANDLE; item_list_buffer_length: Short;\n      item_list_buffer: PAnsiChar; result_buffer_length: Short; result_buffer: PAnsiChar): ISC_STATUS;\n    function isc_close_blob(status_vector: PISC_STATUS;\n      blob_handle: PISC_BLOB_HANDLE): ISC_STATUS;\n    function isc_cancel_blob(status_vector: PISC_STATUS;\n      blob_handle: PISC_BLOB_HANDLE): ISC_STATUS;\n    function isc_get_segment(status_vector: PISC_STATUS;\n      blob_handle: PISC_BLOB_HANDLE; actual_seg_length: PWord;\n      seg_buffer_length: Word; seg_buffer: PAnsiChar): ISC_STATUS;\n    function isc_put_segment(status_vector: PISC_STATUS;\n      blob_handle: PISC_BLOB_HANDLE; seg_buffer_len: Word; seg_buffer: PAnsiChar): ISC_STATUS;\n    function isc_event_block(event_buffer: PPAnsiChar; result_buffer: PPAnsiChar;\n      id_count: Word; event_list: array of PAnsiChar): ISC_LONG;\n    procedure isc_event_counts(status_vector: PISC_STATUS;\n      buffer_length: Short; event_buffer: PAnsiChar; result_buffer: PAnsiChar);\n    function isc_cancel_events(status_vector: PISC_STATUS;\n      db_handle: PISC_DB_HANDLE; event_id: PISC_LONG): ISC_STATUS;\n    function isc_que_events(status_vector: PISC_STATUS;\n      db_handle: PISC_DB_HANDLE; event_id: PISC_LONG; length: Short;\n      event_buffer: PAnsiChar; event_function: TISC_CALLBACK;\n      event_function_arg: PVoid): ISC_STATUS;\n    procedure isc_decode_date(ib_date: PISC_QUAD; tm_date: PCTimeStructure);\n    procedure isc_encode_date(tm_date: PCTimeStructure; ib_date: PISC_QUAD);\n    procedure isc_decode_sql_date(ib_date: PISC_DATE; tm_date: PCTimeStructure);\n    procedure isc_decode_sql_time(ib_time: PISC_TIME; tm_date: PCTimeStructure);\n    procedure isc_decode_timestamp(ib_timestamp: PISC_TIMESTAMP;\n      tm_date: PCTimeStructure);\n    procedure isc_encode_sql_date(tm_date: PCTimeStructure;\n      ib_date: PISC_DATE);\n    procedure isc_encode_sql_time(tm_date: PCTimeStructure;\n      ib_time: PISC_TIME);\n    procedure isc_encode_timestamp(tm_date: PCTimeStructure;\n      ib_timestamp: PISC_TIMESTAMP);\n    function isc_vax_integer(buffer: PAnsiChar; length: Short): ISC_LONG;\n  end;\n\n  {** Implements a native driver for Interbase6}\n  TZInterbase6PlainDriver = class (TZFirebirdBaseDriver)\n  protected\n    function Clone: IZPlainDriver; override;\n  public\n    constructor Create;\n\n    function GetProtocol: string; override;\n    function GetDescription: string; override;\n  end;\n\n  {** Implements a native driver for Firebird 1.0}\n  TZFirebird10PlainDriver = class (TZFirebirdBaseDriver)\n  protected\n    function Clone: IZPlainDriver; override;\n  public\n    constructor Create;\n\n    function GetProtocol: string; override;\n    function GetDescription: string; override;\n  end;\n\n  {** Implements a native driver for Firebird 1.5}\n  TZFirebird15PlainDriver = class (TZFirebirdBaseDriver)\n  protected\n    function Clone: IZPlainDriver; override;\n    procedure LoadCodePages; override;\n  public\n    constructor Create;\n\n    function GetProtocol: string; override;\n    function GetDescription: string; override;\n  end;\n\n  TZFirebirdD15PlainDriver = class (TZFirebird15PlainDriver)\n  protected\n    function Clone: IZPlainDriver; override;\n  public\n    constructor Create;\n\n    function GetProtocol: string; override;\n    function GetDescription: string; override;\n  end;\n\n\n  {** Implements a native driver for Firebird 2.0}\n  TZFirebird20PlainDriver = class (TZFirebirdBaseDriver)\n  protected\n    function Clone: IZPlainDriver; override;\n    function GetUnicodeCodePageName: String; override;\n    procedure LoadCodePages; override;\n  public\n    constructor Create;\n\n    function GetProtocol: string; override;\n    function GetDescription: string; override;\n  end;\n\n  TZFirebirdD20PlainDriver = class (TZFirebird20PlainDriver)\n  protected\n    function Clone: IZPlainDriver; override;\n  public\n    constructor Create;\n\n    function GetProtocol: string; override;\n    function GetDescription: string; override;\n  end;\n\n  {** Represents class to Interbase 6+ native API. }\n\n  { TZFirebird21PlainDriver }\n\n  TZFirebird21PlainDriver = class (TZFirebirdBaseDriver)\n  protected\n    function Clone: IZPlainDriver; override;\n  protected\n    function GetUnicodeCodePageName: String; override;\n    procedure LoadCodePages; override;\n    procedure LoadApi; override;\n  public\n    constructor Create;\n\n    function GetProtocol: string; override;\n    function GetDescription: string; override;\n\n    function isc_interprete(buffer: PAnsiChar; status_vector: PPISC_STATUS): ISC_STATUS; override;\n  end;\n\n  TZFirebirdD21PlainDriver = class (TZFirebird21PlainDriver)\n  protected\n    function Clone: IZPlainDriver; override;\n  public\n    constructor Create;\n\n    function GetProtocol: string; override;\n    function GetDescription: string; override;\n  end;\n\n  { TZFirebird25PlainDriver }\n\n  TZFirebird25PlainDriver = class (TZFirebirdBaseDriver)\n  protected\n    function Clone: IZPlainDriver; override;\n    function GetUnicodeCodePageName: String; override;\n    procedure LoadCodePages; override;\n    procedure LoadApi; override;\n  public\n    constructor Create;\n\n    function GetProtocol: string; override;\n    function GetDescription: string; override;\n\n    function isc_interprete(buffer: PAnsiChar; status_vector: PPISC_STATUS): ISC_STATUS; override;\n  end;\n\n  { TZFirebirdD25PlainDriver }\n\n  TZFirebirdD25PlainDriver = class (TZFirebird25PlainDriver)\n  protected\n    function Clone: IZPlainDriver; override;\n  public\n    constructor Create;\n\n    function GetProtocol: string; override;\n    function GetDescription: string; override;\n  end;\n\n\n  function XSQLDA_LENGTH(Value: LongInt): LongInt;\n\nimplementation\n\nuses SysUtils, ZEncoding;\n\nfunction XSQLDA_LENGTH(Value: LongInt): LongInt;\nbegin\n  Result := SizeOf(TXSQLDA) + ((Value - 1) * SizeOf(TXSQLVAR));\nend;\n\nprocedure AddFireBird15CodePages(PlainDriver: TZAbstractPlainDriver);\nbegin\n  PlainDriver.AddCodePage('DOS737', CS_DOS737, ceAnsi, zCP_DOS737); {Greek}\n  PlainDriver.AddCodePage('DOS775', CS_DOS775, ceAnsi, zCP_DOS775); {Baltic}\n  PlainDriver.AddCodePage('DOS858', CS_DOS858, ceAnsi, zCP_DOS858); {Latin I + Euro symbol}\n  PlainDriver.AddCodePage('DOS862', CS_DOS862, ceAnsi, zCP_DOS862); {Hebrew}\n  PlainDriver.AddCodePage('DOS864', CS_DOS864, ceAnsi, zCP_DOS864); {Arabic}\n  PlainDriver.AddCodePage('DOS866', CS_DOS866, ceAnsi, zCP_DOS866); {Russian}\n  PlainDriver.AddCodePage('DOS869', CS_DOS869, ceAnsi, zCP_DOS869); {Modern Greek}\n  PlainDriver.AddCodePage('ISO8859_2', CS_ISO8859_2, ceAnsi, zCP_L2_ISO_8859_2); {Latin 2   Latin3  Southern European (Maltese, Esperanto)}\n  PlainDriver.AddCodePage('ISO8859_3', CS_ISO8859_3, ceAnsi, zCP_L3_ISO_8859_3); {Latin 1}\n  PlainDriver.AddCodePage('ISO8859_4', CS_ISO8859_4, ceAnsi, zCP_L4_ISO_8859_4); {Latin 4  Northern European (Estonian, Latvian, Lithuanian, Greenlandic, Lappish)}\n  PlainDriver.AddCodePage('ISO8859_5', CS_ISO8859_5, ceAnsi, zCP_L5_ISO_8859_5); {Cyrillic (Russian)}\n  PlainDriver.AddCodePage('ISO8859_6', CS_ISO8859_6, ceAnsi, zCP_L6_ISO_8859_6); {Arabic}\n  PlainDriver.AddCodePage('ISO8859_7', CS_ISO8859_7, ceAnsi, zCP_L7_ISO_8859_7); {Greek}\n  PlainDriver.AddCodePage('ISO8859_8', CS_ISO8859_8, ceAnsi, zCP_L8_ISO_8859_8); {Hebrew}\n  PlainDriver.AddCodePage('ISO8859_9', CS_ISO8859_9, ceAnsi, zCP_L5_ISO_8859_9); {Latin 5}\n  PlainDriver.AddCodePage('ISO8859_13', CS_ISO8859_13, ceAnsi, zCP_L7_ISO_8859_13); {Latin 7  Baltic Rim}\n  PlainDriver.AddCodePage('WIN1255', CS_WIN1255, ceAnsi, zCP_WIN1255); {ANSI Hebrew}\n  PlainDriver.AddCodePage('WIN1256', CS_WIN1256, ceAnsi, cCP_WIN1256); {ANSI Arabic}\n  PlainDriver.AddCodePage('WIN1257', CS_WIN1257, ceAnsi, zCP_WIN1257); {ANSI Baltic}\nend;\n\nprocedure AddFireBird2CodePages(PlainDriver: TZAbstractPlainDriver);\nbegin\n  PlainDriver.AddCodePage('WIN1258', CS_WIN1258, ceAnsi, zCP_WIN1258); {Vietnamese}\n  PlainDriver.AddCodePage('KOI8R', CS_KOI8R, ceAnsi, zCP_KOI8R); {Russian}\n  PlainDriver.AddCodePage('KOI8U', CS_KOI8U, ceAnsi, zCP_KOI8U); {Ukrainian}\n  PlainDriver.AddCodePage('UTF8', CS_UTF8, ceUTF8, zCP_UTF8, '', 4); {All}\nend;\n\nprocedure AddFireBird21CodePages(PlainDriver: TZAbstractPlainDriver);\nbegin\n  PlainDriver.AddCodePage('CP943C', CS_CP943C, ceAnsi, 943, '', 2); {Japanese}\n  PlainDriver.AddCodePage('GBK', CS_GBK, ceAnsi, zCP_GB2312, '', 2); {Chinese}\n  PlainDriver.AddCodePage('TIS620', CS_TIS620, ceAnsi, zCP_IBM_Thai); {Thai}\nend;\n\n{ IZFirebirdPlainDriver }\n\nfunction TZFirebirdBaseDriver.GetUnicodeCodePageName: String;\nbegin\n  Result := 'UNICODE_FSS';\nend;\n\nprocedure TZFirebirdBaseDriver.LoadCodePages;\nbegin\n  Self.AddCodePage('ASCII', CS_ASCII, ceAnsi, zCP_WIN1252); {English}\n  Self.AddCodePage('BIG_5', CS_BIG_5, ceAnsi, zCP_Big5); {Chinese, Vietnamese, Korean}\n  Self.AddCodePage('CYRL', CS_CYRL, ceAnsi, zCP_WIN1251, '', 2);  {Russian}\n  Self.AddCodePage('DOS437', CS_DOS437, ceAnsi, zCP_DOS437); {English (USA)}\n  Self.AddCodePage('DOS850', CS_DOS850, ceAnsi, zCP_DOS850); {Latin I (no Euro symbol)}\n  Self.AddCodePage('DOS852', CS_DOS852, ceAnsi, zCP_DOS852); {Latin II}\n  Self.AddCodePage('DOS857', CS_DOS857, ceAnsi, zCP_DOS857); {Turkish}\n  Self.AddCodePage('DOS860', CS_DOS860, ceAnsi, zCP_DOS860); {Portuguese}\n  Self.AddCodePage('DOS861', CS_DOS861, ceAnsi, zCP_DOS861); {Icelandic}\n  Self.AddCodePage('DOS863', CS_DOS863, ceAnsi, zCP_DOS863); {French (Canada)}\n  Self.AddCodePage('DOS865', CS_DOS865, ceAnsi, zCP_DOS865); {Nordic}\n  Self.AddCodePage('EUCJ_0208', CS_EUCJ_0208, ceAnsi, zCP_EUC_JP, '', 2); {EUC Japanese}\n  Self.AddCodePage('GB_2312', CS_GB_2312, ceAnsi, zCP_GB2312, '', 2); {Simplified Chinese (Hong Kong, PRC)}\n  Self.AddCodePage('ISO8859_1', CS_ISO8859_1, ceAnsi, zCP_L1_ISO_8859_1); {Latin 1}\n  Self.AddCodePage('KSC_5601', CS_KSC_5601, ceAnsi, zCP_EUCKR, '', 2); {Korean (Unified Hangeul)}\n  Self.AddCodePage('NEXT', CS_NEXT);  {NeXTSTEP encoding}\n  Self.AddCodePage('NONE', CS_NONE, ceAnsi, ZDefaultSystemCodePage, '', 1, False); {Codepage-neutral. Uppercasing limited to ASCII codes 97-122}\n  Self.AddCodePage('OCTETS', CS_BINARY); {Binary character}\n  Self.AddCodePage('SJIS_0208', CS_SJIS_0208, ceAnsi, zCP_EUC_JP, '', 2); {Japanese}\n  Self.AddCodePage('UNICODE_FSS', CS_UNICODE_FSS, ceUTF8, zCP_UTF8, '', 3); {UNICODE}\n  Self.AddCodePage('WIN1250', CS_WIN1250, ceAnsi, zCP_WIN1250); {ANSI  Central European}\n  Self.AddCodePage('WIN1251', CS_WIN1251, ceAnsi, zCP_WIN1251); {ANSI  Cyrillic}\n  Self.AddCodePage('WIN1252', CS_WIN1252, ceAnsi, zCP_WIN1252); {ANSI  Latin I}\n  Self.AddCodePage('WIN1253', CS_WIN1253, ceAnsi, zCP_WIN1253); {ANSI Greek}\n  Self.AddCodePage('WIN1254', CS_WIN1254, ceAnsi, zCP_WIN1254); {ANSI Turkish}\nend;\n\n{$IFDEF ENABLE_INTERBASE_CRYPT}\nprocedure TZFirebirdBaseDriver.Initialize;\nbegin\n  If Assigned(FPreLoader) and not FPreLoader.Loaded then\n    FPreLoader.LoadNativeLibrary;\n  inherited Initialize;\nend;\n{$ENDIF}\n\nprocedure TZFirebirdBaseDriver.LoadApi;\nbegin\n  inherited LoadApi;\n  with Loader do\n  begin\n    @FIREBIRD_API.isc_sqlcode         := GetAddress('isc_sqlcode');\n    @FIREBIRD_API.isc_sql_interprete  := GetAddress('isc_sql_interprete');\n    @FIREBIRD_API.isc_interprete      := GetAddress('isc_interprete');\n    @FIREBIRD_API.isc_vax_integer     := GetAddress('isc_vax_integer');\n\n    @FIREBIRD_API.isc_array_gen_sdl   := GetAddress( 'isc_array_gen_sdl');\n    @FIREBIRD_API.isc_array_get_slice := GetAddress( 'isc_array_get_slice');\n    @FIREBIRD_API.isc_array_lookup_bounds := GetAddress( 'isc_array_lookup_bounds');\n    @FIREBIRD_API.isc_array_lookup_desc := GetAddress( 'isc_array_lookup_desc');\n    @FIREBIRD_API.isc_array_set_desc  := GetAddress( 'isc_array_set_desc');\n    @FIREBIRD_API.isc_array_put_slice := GetAddress( 'isc_array_put_slice');\n\n    @FIREBIRD_API.isc_blob_info       := GetAddress('isc_blob_info');\n    @FIREBIRD_API.isc_open_blob2      := GetAddress('isc_open_blob2');\n    @FIREBIRD_API.isc_close_blob      := GetAddress('isc_close_blob');\n    @FIREBIRD_API.isc_cancel_blob     := GetAddress('isc_cancel_blob');\n    @FIREBIRD_API.isc_get_segment     := GetAddress('isc_get_segment');\n    @FIREBIRD_API.isc_put_segment     := GetAddress('isc_put_segment');\n    @FIREBIRD_API.isc_create_blob2    := GetAddress('isc_create_blob2');\n    @FIREBIRD_API.isc_decode_date     := GetAddress('isc_decode_date');\n    @FIREBIRD_API.isc_encode_date     := GetAddress('isc_encode_date');\n    @FIREBIRD_API.isc_dsql_free_statement := GetAddress('isc_dsql_free_statement');\n    @FIREBIRD_API.isc_dsql_execute2   := GetAddress('isc_dsql_execute2');\n    @FIREBIRD_API.isc_dsql_execute    := GetAddress('isc_dsql_execute');\n    @FIREBIRD_API.isc_dsql_set_cursor_name := GetAddress('isc_dsql_set_cursor_name');\n    @FIREBIRD_API.isc_dsql_fetch      := GetAddress('isc_dsql_fetch');\n    @FIREBIRD_API.isc_dsql_sql_info   := GetAddress('isc_dsql_sql_info');\n    @FIREBIRD_API.isc_dsql_allocate_statement := GetAddress('isc_dsql_allocate_statement');\n    @FIREBIRD_API.isc_dsql_alloc_statement2 := GetAddress('isc_dsql_alloc_statement2');\n    @FIREBIRD_API.isc_dsql_prepare    := GetAddress('isc_dsql_prepare');\n    @FIREBIRD_API.isc_dsql_describe_bind := GetAddress('isc_dsql_describe_bind');\n    @FIREBIRD_API.isc_dsql_describe   := GetAddress('isc_dsql_describe');\n    @FIREBIRD_API.isc_dsql_execute_immediate := GetAddress('isc_dsql_execute_immediate');\n    @FIREBIRD_API.isc_drop_database   := GetAddress('isc_drop_database');\n    @FIREBIRD_API.isc_detach_database := GetAddress('isc_detach_database');\n    @FIREBIRD_API.isc_attach_database := GetAddress('isc_attach_database');\n    @FIREBIRD_API.isc_database_info   := GetAddress('isc_database_info');\n    @FIREBIRD_API.isc_transaction_info   := GetAddress('isc_transaction_info');\n    @FIREBIRD_API.isc_start_multiple  := GetAddress('isc_start_multiple');\n    @FIREBIRD_API.isc_start_transaction := GetAddress('isc_start_transaction');\n    @FIREBIRD_API.isc_commit_transaction := GetAddress('isc_commit_transaction');\n\n    @FIREBIRD_API.isc_commit_retaining := GetAddress('isc_commit_retaining');\n    @FIREBIRD_API.isc_rollback_transaction := GetAddress('isc_rollback_transaction');\n    @FIREBIRD_API.isc_cancel_events   := GetAddress('isc_cancel_events');\n    @FIREBIRD_API.isc_que_events      := GetAddress('isc_que_events');\n    @FIREBIRD_API.isc_event_counts    := GetAddress('isc_event_counts');\n    @FIREBIRD_API.isc_event_block     := GetAddress('isc_event_block');\n    @FIREBIRD_API.isc_free            := GetAddress('isc_free');\n\n    @FIREBIRD_API.isc_rollback_retaining := GetAddress( 'isc_rollback_retaining');\n    @FIREBIRD_API.isc_decode_sql_date := GetAddress('isc_decode_sql_date');\n    @FIREBIRD_API.isc_decode_sql_time := GetAddress('isc_decode_sql_time');\n    @FIREBIRD_API.isc_decode_timestamp := GetAddress('isc_decode_timestamp');\n    @FIREBIRD_API.isc_encode_sql_date := GetAddress('isc_encode_sql_date');\n    @FIREBIRD_API.isc_encode_sql_time := GetAddress('isc_encode_sql_time');\n    @FIREBIRD_API.isc_encode_timestamp := GetAddress('isc_encode_timestamp');\n  end;\nend;\n\nconstructor TZFirebirdBaseDriver.Create;\nbegin\n  inherited create;\n  FLoader := TZNativeLibraryLoader.Create([]);\n  {$IFDEF ENABLE_INTERBASE_CRYPT}\n  FPreLoader := TZNativeLibraryLoader.Create([LINUX_IB_CRYPT_LOCATION]);\n  {$ENDIF}\nend;\n\n{$IFDEF ENABLE_INTERBASE_CRYPT}\ndestructor TZFirebirdBaseDriver.Destroy;\nbegin\n  FPreLoader.Free;\n  inherited Destroy;\nend;\n{$ENDIF}\n\nfunction TZFirebirdBaseDriver.GetFirebirdAPI: TZFirebird_API;\nbegin\n  result := FIREBIRD_API;\nend;\n\nfunction TZFirebirdBaseDriver.isc_array_gen_sdl(status_vector: PISC_STATUS;\n  isc_array_desc: PISC_ARRAY_DESC; isc_arg3: PShort;\n  isc_arg4: PAnsiChar; isc_arg5: PShort): ISC_STATUS;\nbegin\n  Result := FIREBIRD_API.isc_array_gen_sdl(status_vector, isc_array_desc,\n    isc_arg3, isc_arg4, isc_arg5);\nend;\n\nfunction TZFirebirdBaseDriver.isc_array_get_slice(status_vector: PISC_STATUS;\n  db_handle: PISC_DB_HANDLE; trans_handle: PISC_TR_HANDLE; array_id: PISC_QUAD;\n  descriptor: PISC_ARRAY_DESC; dest_array: PVoid;\n  slice_length: ISC_LONG): ISC_STATUS;\nbegin\n  Result := FIREBIRD_API.isc_array_get_slice(status_vector, db_handle,\n    trans_handle, array_id, descriptor, dest_array, slice_length);\nend;\n\nfunction TZFirebirdBaseDriver.isc_array_lookup_bounds(\n  status_vector: PISC_STATUS; db_handle: PISC_DB_HANDLE;\n  trans_handle: PISC_TR_HANDLE; table_name, column_name: PAnsiChar;\n  descriptor: PISC_ARRAY_DESC): ISC_STATUS;\nbegin\n  Result := FIREBIRD_API.isc_array_lookup_bounds(status_vector, db_handle,\n    trans_handle, table_name, column_name, descriptor);\nend;\n\nfunction TZFirebirdBaseDriver.isc_array_lookup_desc(\n  status_vector: PISC_STATUS; db_handle: PISC_DB_HANDLE;\n  trans_handle: PISC_TR_HANDLE; table_name, column_name: PAnsiChar;\n  descriptor: PISC_ARRAY_DESC): ISC_STATUS;\nbegin\n  Result := FIREBIRD_API.isc_array_lookup_desc(status_vector, db_handle,\n    trans_handle, table_name, column_name, descriptor);\nend;\n\nfunction TZFirebirdBaseDriver.isc_array_put_slice(status_vector: PISC_STATUS;\n  db_handle: PISC_DB_HANDLE; trans_handle: PISC_TR_HANDLE; array_id: PISC_QUAD;\n  descriptor: PISC_ARRAY_DESC; source_array: PVoid;\n  slice_length: PISC_LONG): ISC_STATUS;\nbegin\n  Result := FIREBIRD_API.isc_array_put_slice(status_vector, db_handle,\n    trans_handle, array_id, descriptor, source_array, slice_length);\nend;\n\nfunction TZFirebirdBaseDriver.isc_array_set_desc(status_vector: PISC_STATUS;\n  table_name: PAnsiChar; column_name: PAnsiChar; sql_dtype, sql_length,\n  sql_dimensions: PShort; descriptor: PISC_ARRAY_DESC): ISC_STATUS;\nbegin\n  Result := FIREBIRD_API.isc_array_set_desc(status_vector, table_name,\n    column_name, sql_dtype, sql_length, sql_dimensions, descriptor);\nend;\n\nfunction TZFirebirdBaseDriver.isc_attach_database(status_vector: PISC_STATUS;\n  db_name_length: Short; db_name: PAnsiChar; db_handle: PISC_DB_HANDLE;\n  parm_buffer_length: Short; parm_buffer: PAnsiChar): ISC_STATUS;\nbegin\n\n    Result := FIREBIRD_API.isc_attach_database(status_vector, db_name_length,\n    db_name, db_handle, parm_buffer_length, parm_buffer);\n\nend;\n\nfunction TZFirebirdBaseDriver.isc_blob_info(status_vector: PISC_STATUS;\n  blob_handle: PISC_BLOB_HANDLE; item_list_buffer_length: Short;\n  item_list_buffer: PAnsiChar; result_buffer_length: Short;\n  result_buffer: PAnsiChar): ISC_STATUS;\nbegin\n  Result :=FIREBIRD_API.isc_blob_info(status_vector, blob_handle,\n    item_list_buffer_length, item_list_buffer, result_buffer_length,\n    result_buffer);\nend;\n\nfunction TZFirebirdBaseDriver.isc_cancel_blob(status_vector: PISC_STATUS;\n  blob_handle: PISC_BLOB_HANDLE): ISC_STATUS;\nbegin\n  Result := FIREBIRD_API.isc_cancel_blob(status_vector, blob_handle);\nend;\n\nfunction TZFirebirdBaseDriver.isc_cancel_events(status_vector: PISC_STATUS;\n  db_handle: PISC_DB_HANDLE; event_id: PISC_LONG): ISC_STATUS;\nbegin\n  Result := FIREBIRD_API.isc_cancel_events(status_vector, db_handle,\n    event_id);\nend;\n\nfunction TZFirebirdBaseDriver.isc_close_blob(status_vector: PISC_STATUS;\n  blob_handle: PISC_BLOB_HANDLE): ISC_STATUS;\nbegin\n  Result := FIREBIRD_API.isc_close_blob(status_vector, blob_handle);\nend;\n\nfunction TZFirebirdBaseDriver.isc_commit_retaining(\n  status_vector: PISC_STATUS; tran_handle: PISC_TR_HANDLE): ISC_STATUS;\nbegin\n  Result := FIREBIRD_API.isc_commit_retaining(status_vector, tran_handle);\nend;\n\nfunction TZFirebirdBaseDriver.isc_commit_transaction(\n  status_vector: PISC_STATUS; tran_handle: PISC_TR_HANDLE): ISC_STATUS;\nbegin\n  Result := FIREBIRD_API.isc_commit_transaction(status_vector, tran_handle);\nend;\n\nfunction TZFirebirdBaseDriver.isc_create_blob2(status_vector: PISC_STATUS;\n  db_handle: PISC_DB_HANDLE; tran_handle: PISC_TR_HANDLE;\n  blob_handle: PISC_BLOB_HANDLE; blob_id: PISC_QUAD; bpb_length: Short;\n  bpb_address: PAnsiChar): ISC_STATUS;\nbegin\n  Result := FIREBIRD_API.isc_create_blob2(status_vector, db_handle,\n    tran_handle, blob_handle, blob_id, bpb_length, bpb_address);\nend;\n\nfunction TZFirebirdBaseDriver.isc_database_info(status_vector: PISC_STATUS;\n  db_handle: PISC_DB_HANDLE; item_list_buffer_length: Short;\n  item_list_buffer: PAnsiChar; result_buffer_length: Short;\n  result_buffer: PAnsiChar): ISC_STATUS;\nbegin\n  Result := FIREBIRD_API.isc_database_info(status_vector, db_handle,\n    item_list_buffer_length, item_list_buffer, result_buffer_length,\n    result_buffer);\nend;\n\nfunction TZFirebirdBaseDriver.isc_transaction_info(status_vector: PISC_STATUS;\n  tr_handle: PISC_TR_HANDLE; item_list_buffer_length: Short;\n  item_list_buffer: PAnsiChar; result_buffer_length: Short;\n  result_buffer: PAnsiChar): ISC_STATUS;\nbegin\n  Result := FIREBIRD_API.isc_transaction_info(status_vector, tr_handle,\n    item_list_buffer_length, item_list_buffer, result_buffer_length,\n    result_buffer);\nend;\n\nprocedure TZFirebirdBaseDriver.isc_decode_date(ib_date: PISC_QUAD;\n  tm_date: PCTimeStructure);\nbegin\n  FIREBIRD_API.isc_decode_date(ib_date, tm_date);\nend;\n\nprocedure TZFirebirdBaseDriver.isc_decode_sql_date(ib_date: PISC_DATE;\n  tm_date: PCTimeStructure);\nbegin\n  FIREBIRD_API.isc_decode_sql_date(ib_date, tm_date);\nend;\n\nprocedure TZFirebirdBaseDriver.isc_decode_sql_time(ib_time: PISC_TIME;\n  tm_date: PCTimeStructure);\nbegin\n  FIREBIRD_API.isc_decode_sql_time(ib_time, tm_date);\nend;\n\nprocedure TZFirebirdBaseDriver.isc_decode_timestamp(\n  ib_timestamp: PISC_TIMESTAMP; tm_date: PCTimeStructure);\nbegin\n  FIREBIRD_API.isc_decode_timestamp(ib_timestamp, tm_date);\nend;\n\nfunction TZFirebirdBaseDriver.isc_detach_database(status_vector: PISC_STATUS;\n  db_handle: PISC_DB_HANDLE): ISC_STATUS;\nbegin\n  Result := FIREBIRD_API.isc_detach_database(status_vector, db_handle);\nend;\n\nfunction TZFirebirdBaseDriver.isc_drop_database(status_vector: PISC_STATUS;\n  db_handle: PISC_DB_HANDLE): ISC_STATUS;\nbegin\n  Result := FIREBIRD_API.isc_drop_database(status_vector, db_handle);\nend;\n\nfunction TZFirebirdBaseDriver.isc_dsql_alloc_statement2(\n  status_vector: PISC_STATUS; db_handle: PISC_DB_HANDLE;\n  stmt_handle: PISC_STMT_HANDLE): ISC_STATUS;\nbegin\n  Result := FIREBIRD_API.isc_dsql_alloc_statement2(status_vector,\n    db_handle, stmt_handle);\nend;\n\nfunction TZFirebirdBaseDriver.isc_dsql_allocate_statement(\n  status_vector: PISC_STATUS; db_handle: PISC_DB_HANDLE;\n  stmt_handle: PISC_STMT_HANDLE): ISC_STATUS;\nbegin\n  Result := FIREBIRD_API.isc_dsql_allocate_statement(status_vector,\n    db_handle, stmt_handle);\nend;\n\nfunction TZFirebirdBaseDriver.isc_dsql_describe(status_vector: PISC_STATUS;\n  stmt_handle: PISC_STMT_HANDLE; dialect: Word; xsqlda: PXSQLDA): ISC_STATUS;\nbegin\n  Result := FIREBIRD_API.isc_dsql_describe(status_vector, stmt_handle,\n    dialect, xsqlda);\nend;\n\nfunction TZFirebirdBaseDriver.isc_dsql_describe_bind(\n  status_vector: PISC_STATUS; stmt_handle: PISC_STMT_HANDLE; dialect: Word;\n  xsqlda: PXSQLDA): ISC_STATUS;\nbegin\n  Result := FIREBIRD_API.isc_dsql_describe_bind(status_vector, stmt_handle,\n    dialect, xsqlda);\nend;\n\nfunction TZFirebirdBaseDriver.isc_dsql_execute(status_vector: PISC_STATUS;\n  tran_handle: PISC_TR_HANDLE; stmt_handle: PISC_STMT_HANDLE; dialect: Word;\n  xsqlda: PXSQLDA): ISC_STATUS;\nbegin\n  Result := FIREBIRD_API.isc_dsql_execute(status_vector, tran_handle,\n    stmt_handle, dialect, xsqlda);\nend;\n\nfunction TZFirebirdBaseDriver.isc_dsql_execute_immediate(\n  status_vector: PISC_STATUS; db_handle: PISC_DB_HANDLE;\n  tran_handle: PISC_TR_HANDLE; length: Word; statement: PAnsiChar;\n  dialect: Word; xsqlda: PXSQLDA): ISC_STATUS;\nbegin\n  Result := FIREBIRD_API.isc_dsql_execute_immediate(status_vector,\n    db_handle, tran_handle, length, statement, dialect, xsqlda);\nend;\n\nfunction TZFirebirdBaseDriver.isc_dsql_execute2(status_vector: PISC_STATUS;\n  tran_handle: PISC_TR_HANDLE; stmt_handle: PISC_STMT_HANDLE;\n  dialect: Word; in_xsqlda, out_xsqlda: PXSQLDA): ISC_STATUS;\nbegin\n  Result := FIREBIRD_API.isc_dsql_execute2(status_vector, tran_handle,\n    stmt_handle, dialect, in_xsqlda, out_xsqlda);\nend;\n\nfunction TZFirebirdBaseDriver.isc_dsql_fetch(status_vector: PISC_STATUS;\n  stmt_handle: PISC_STMT_HANDLE; dialect: Word;\n  xsqlda: PXSQLDA): ISC_STATUS;\nbegin\n  Result := FIREBIRD_API.isc_dsql_fetch(status_vector, stmt_handle, dialect,\n    xsqlda);\nend;\n\nfunction TZFirebirdBaseDriver.isc_dsql_free_statement(\n  status_vector: PISC_STATUS; stmt_handle: PISC_STMT_HANDLE;\n  options: Word): ISC_STATUS;\nbegin\n  Result := FIREBIRD_API.isc_dsql_free_statement(status_vector, stmt_handle,\n    options);\nend;\n\nfunction TZFirebirdBaseDriver.isc_dsql_prepare(\n  status_vector: PISC_STATUS; tran_handle: PISC_TR_HANDLE;\n  stmt_handle: PISC_STMT_HANDLE; length: Word; statement: PAnsiChar;\n  dialect: Word; xsqlda: PXSQLDA): ISC_STATUS;\nbegin\n  Result := FIREBIRD_API.isc_dsql_prepare(status_vector, tran_handle,\n    stmt_handle, length, statement, dialect, xsqlda);\nend;\n\nfunction TZFirebirdBaseDriver.isc_dsql_set_cursor_name(\n  status_vector: PISC_STATUS; stmt_handle: PISC_STMT_HANDLE;\n  cursor_name: PAnsiChar; _type: Word): ISC_STATUS;\nbegin\n  Result := FIREBIRD_API.isc_dsql_set_cursor_name(status_vector,\n    stmt_handle, cursor_name, _type);\nend;\n\nfunction TZFirebirdBaseDriver.isc_dsql_sql_info(\n  status_vector: PISC_STATUS; stmt_handle: PISC_STMT_HANDLE;\n  item_length: Short; items: PAnsiChar; buffer_length: Short;\n  buffer: PAnsiChar): ISC_STATUS;\nbegin\n  Result := FIREBIRD_API.isc_dsql_sql_info(status_vector, stmt_handle,\n    item_length, items, buffer_length, buffer);\nend;\n\nprocedure TZFirebirdBaseDriver.isc_encode_date(tm_date: PCTimeStructure;\n  ib_date: PISC_QUAD);\nbegin\n  FIREBIRD_API.isc_encode_date(tm_date, ib_date);\nend;\n\nprocedure TZFirebirdBaseDriver.isc_encode_sql_date(\n  tm_date: PCTimeStructure; ib_date: PISC_DATE);\nbegin\n  FIREBIRD_API.isc_encode_sql_date(tm_date, ib_date);\nend;\n\nprocedure TZFirebirdBaseDriver.isc_encode_sql_time(\n  tm_date: PCTimeStructure; ib_time: PISC_TIME);\nbegin\n  FIREBIRD_API.isc_encode_sql_time(tm_date, ib_time);\nend;\n\nprocedure TZFirebirdBaseDriver.isc_encode_timestamp(\n  tm_date: PCTimeStructure; ib_timestamp: PISC_TIMESTAMP);\nbegin\n  FIREBIRD_API.isc_encode_timestamp(tm_date, ib_timestamp);\nend;\n\nfunction TZFirebirdBaseDriver.isc_event_block(event_buffer: PPAnsiChar;\n  result_buffer: PPAnsiChar; id_count: Word; event_list: array of PAnsiChar\n  ): ISC_LONG;\nbegin\n  Result := FIREBIRD_API.isc_event_block(event_buffer, result_buffer,\n    id_count, event_list);\nend;\n\nprocedure TZFirebirdBaseDriver.isc_event_counts(\n  status_vector: PISC_STATUS; buffer_length: Short; event_buffer,\n  result_buffer: PAnsiChar);\nbegin\n  FIREBIRD_API.isc_event_counts(status_vector, buffer_length,\n    event_buffer, result_buffer);\nend;\n\nfunction TZFirebirdBaseDriver.isc_free(isc_arg1: PAnsiChar): ISC_LONG;\nbegin\n  Result := FIREBIRD_API.isc_free(isc_arg1);\nend;\n\nfunction TZFirebirdBaseDriver.isc_get_segment(\n  status_vector: PISC_STATUS; blob_handle: PISC_BLOB_HANDLE;\n  actual_seg_length: PWord; seg_buffer_length: Word;\n  seg_buffer: PAnsiChar): ISC_STATUS;\nbegin\n  Result := FIREBIRD_API.isc_get_segment(status_vector, blob_handle,\n    actual_seg_length, seg_buffer_length, seg_buffer);\nend;\n\nfunction TZFirebirdBaseDriver.isc_interprete(buffer: PAnsiChar;\n  status_vector: PPISC_STATUS): ISC_STATUS;\nbegin\n  Result := FIREBIRD_API.isc_interprete(buffer, status_vector);\nend;\n\nfunction TZFirebirdBaseDriver.isc_open_blob2(status_vector: PISC_STATUS;\n  db_handle: PISC_DB_HANDLE; tran_handle: PISC_TR_HANDLE;\n  blob_handle: PISC_BLOB_HANDLE; blob_id: PISC_QUAD; bpb_length: Short;\n  bpb_buffer: PAnsiChar): ISC_STATUS;\nbegin\n  Result := FIREBIRD_API.isc_open_blob2(status_vector, db_handle,\n    tran_handle, blob_handle, blob_id, bpb_length, bpb_buffer);\nend;\n\nfunction TZFirebirdBaseDriver.isc_put_segment(\n  status_vector: PISC_STATUS; blob_handle: PISC_BLOB_HANDLE;\n  seg_buffer_len: Word; seg_buffer: PAnsiChar): ISC_STATUS;\nbegin\n  Result := FIREBIRD_API.isc_put_segment(status_vector, blob_handle,\n    seg_buffer_len, seg_buffer);\nend;\n\nfunction TZFirebirdBaseDriver.isc_que_events(status_vector: PISC_STATUS;\n  db_handle: PISC_DB_HANDLE; event_id: PISC_LONG; length: Short;\n  event_buffer: PAnsiChar; event_function: TISC_CALLBACK;\n  event_function_arg: PVoid): ISC_STATUS;\nbegin\n  Result := FIREBIRD_API.isc_que_events(status_vector, db_handle,\n    event_id, length, event_buffer, event_function, event_function_arg)\nend;\n\nfunction TZFirebirdBaseDriver.isc_rollback_retaining(\n  status_vector: PISC_STATUS; tran_handle: PISC_TR_HANDLE): ISC_STATUS;\nbegin\n  Result := FIREBIRD_API.isc_rollback_retaining(status_vector, tran_handle);\nend;\n\nprocedure TZFirebirdBaseDriver.isc_sql_interprete(sqlcode: Short;  buffer: PAnsiChar; buffer_length: Short);\nbegin\n  FIREBIRD_API.isc_sql_interprete(sqlcode, buffer, buffer_length);\nend;\n\nfunction TZFirebirdBaseDriver.isc_sqlcode(status_vector: PISC_STATUS): ISC_LONG;\nbegin\n  Result := FIREBIRD_API.isc_sqlcode(status_vector);\nend;\n\nfunction TZFirebirdBaseDriver.isc_rollback_transaction(\n  status_vector: PISC_STATUS; tran_handle: PISC_TR_HANDLE): ISC_STATUS;\nbegin\n  Result := FIREBIRD_API.isc_rollback_transaction(status_vector, tran_handle);\nend;\n\nfunction TZFirebirdBaseDriver.isc_start_multiple(\n  status_vector: PISC_STATUS; tran_handle: PISC_TR_HANDLE;\n  db_handle_count: Short; teb_vector_address: PISC_TEB): ISC_STATUS;\nbegin\n  Result := FIREBIRD_API.isc_start_multiple(status_vector, tran_handle,\n    db_handle_count, teb_vector_address);\nend;\n\nfunction TZFirebirdBaseDriver.isc_start_transaction(\n  status_vector: PISC_STATUS; tran_handle: PISC_TR_HANDLE;\n  db_handle_count: Short; db_handle: PISC_DB_HANDLE; tpb_length: Word;\n  tpb_address: PAnsiChar): ISC_STATUS;\nbegin\n  Result := FIREBIRD_API.isc_start_transaction(status_vector, tran_handle, db_handle_count, db_handle, tpb_length, tpb_address);\nend;\n\nfunction TZFirebirdBaseDriver.isc_vax_integer(buffer: PAnsiChar;\n  length: Short): ISC_LONG;\nbegin\n  Result := FIREBIRD_API.isc_vax_integer(buffer, length);\nend;\n\n{ TZInterbase6PlainDriver }\nfunction TZInterbase6PlainDriver.Clone: IZPlainDriver;\nbegin\n  Result := TZInterbase6PlainDriver.Create;\nend;\n\nconstructor TZInterbase6PlainDriver.Create;\nbegin\n   inherited create;\n  {$IFNDEF UNIX}\n    FLoader.AddLocation(WINDOWSIB6_DLL_LOCATION);\n  {$ELSE}\n    FLoader.AddLocation(LINUXIB6_DLL_LOCATION);\n    {$IFDEF ENABLE_INTERBASE_CRYPT}\n    FPreLoader.AddLocation(LINUX_IB_CRYPT_LOCATION);\n    {$ENDIF}\n  {$ENDIF}\n  Self.LoadCodePages;\nend;\n\nfunction TZInterbase6PlainDriver.GetDescription: string;\nbegin\n  Result := 'Native Plain Driver for Interbase 6';\nend;\n\nfunction TZInterbase6PlainDriver.GetProtocol: string;\nbegin\n  Result := 'interbase-6';\nend;\n\nfunction TZFirebird10PlainDriver.Clone: IZPlainDriver;\nbegin\n  Result := TZFirebird10PlainDriver.Create;\nend;\n\nconstructor TZFirebird10PlainDriver.Create;\nbegin\n   inherited create;\n  {$IFNDEF UNIX}\n    FLoader.AddLocation(WINDOWS_DLL_LOCATION);\n  {$ELSE}\n    FLoader.AddLocation(LINUX_DLL_LOCATION);\n    {$IFDEF ENABLE_INTERBASE_CRYPT}\n    FPreLoader.AddLocation(LINUX_IB_CRYPT_LOCATION);\n    {$ENDIF}\n  {$ENDIF}\n  Self.LoadCodePages;\nend;\n\nfunction TZFirebird10PlainDriver.GetDescription: string;\nbegin\n  Result := 'Native Plain Driver for Firebird 1.0';\nend;\n\nfunction TZFirebird10PlainDriver.GetProtocol: string;\nbegin\n  Result := 'firebird-1.0';\nend;\n\n{ IZFirebird15PlainDriver }\n\nfunction TZFirebird15PlainDriver.Clone: IZPlainDriver;\nbegin\n  Result := TZFirebird15PlainDriver.Create;\nend;\n\nprocedure TZFirebird15PlainDriver.LoadCodePages;\nbegin\n  inherited;\n  AddFireBird15CodePages(Self);\nend;\n\nconstructor TZFirebird15PlainDriver.Create;\nbegin\n   inherited create;\n  {$IFNDEF UNIX}\n    {$IFNDEF FIREBIRD_STRICT_DLL_LOADING}\n      FLoader.AddLocation(WINDOWS2_DLL_LOCATION);\n    {$ENDIF}\n    FLoader.AddLocation(WINDOWS15_DLL_LOCATION);\n  {$ELSE}\n    {$IFNDEF FIREBIRD_STRICT_DLL_LOADING}\n      FLoader.AddLocation(LINUX2_DLL_LOCATION);\n    {$ENDIF}\n    FLoader.AddLocation(LINUX15_DLL_LOCATION);\n    {$IFDEF ENABLE_INTERBASE_CRYPT}\n      {$IFNDEF FIREBIRD_STRICT_DLL_LOADING}\n        FPreLoader.AddLocation(LINUX2_IB_CRYPT_LOCATION);\n      {$ENDIF}\n      FPreLoader.AddLocation(LINUX15_IB_CRYPT_LOCATION);\n    {$ENDIF}\n  {$ENDIF}\n  Self.LoadCodePages;\nend;\n\nfunction TZFirebird15PlainDriver.GetDescription: string;\nbegin\n  Result := 'Native Plain Driver for Firebird 1.5';\nend;\n\nfunction TZFirebird15PlainDriver.GetProtocol: string;\nbegin\n  Result := 'firebird-1.5';\nend;\n\n{ IZFirebird15PlainDriver }\n\nfunction TZFirebirdD15PlainDriver.Clone: IZPlainDriver;\nbegin\n  Result := TZFirebirdD15PlainDriver.Create;\nend;\n\nconstructor TZFirebirdD15PlainDriver.Create;\nbegin\n   inherited create;\n  {$IFNDEF UNIX}\n    {$IFNDEF FIREBIRD_STRICT_DLL_LOADING}\n      FLoader.AddLocation(WINDOWS2_DLL_LOCATION_EMBEDDED);\n    {$ENDIF}\n    FLoader.AddLocation(WINDOWS15_DLL_LOCATION_EMBEDDED);\n  {$ELSE}\n    {$IFNDEF FIREBIRD_STRICT_DLL_LOADING}\n      FLoader.AddLocation(LINUX2_DLL_LOCATION_EMBEDDED);\n    {$ENDIF}\n    FLoader.AddLocation(LINUX15_DLL_LOCATION_EMBEDDED);\n    {$ENDIF}\nend;\n\nfunction TZFirebirdD15PlainDriver.GetProtocol: string;\nbegin\n  Result := 'firebirdd-1.5';\nend;\n\nfunction TZFirebirdD15PlainDriver.GetDescription: string;\nbegin\n  Result := 'Native Plain Driver for Firebird Embedded 1.5';\nend;\n\n{ IZFirebird20PlainDriver }\n\nfunction TZFirebird20PlainDriver.Clone: IZPlainDriver;\nbegin\n  Result := TZFirebird20PlainDriver.Create;\nend;\n\nfunction TZFirebird20PlainDriver.GetUnicodeCodePageName: String;\nbegin\n  Result := 'UTF8';\nend;\n\nprocedure TZFirebird20PlainDriver.LoadCodePages;\nbegin\n  inherited LoadCodePages;\n  AddFireBird15CodePages(Self);\n  AddFireBird2CodePages(Self);\nend;\n\nconstructor TZFirebird20PlainDriver.Create;\nbegin\n   inherited create;\n  {$IFNDEF UNIX}\n    {$IFNDEF FIREBIRD_STRICT_DLL_LOADING}\n      FLoader.AddLocation(WINDOWS2_DLL_LOCATION);\n    {$ENDIF}\n    FLoader.AddLocation(WINDOWS20_DLL_LOCATION);\n  {$ELSE}\n    {$IFNDEF FIREBIRD_STRICT_DLL_LOADING}\n      FLoader.AddLocation(LINUX2_DLL_LOCATION);\n    {$ENDIF}\n    FLoader.AddLocation(LINUX20_DLL_LOCATION);\n    FLoader.AddLocation(LINUX2_DLL_LOCATION2);\n    {$IFDEF ENABLE_INTERBASE_CRYPT}\n      {$IFNDEF FIREBIRD_STRICT_DLL_LOADING}\n        FPreLoader.AddLocation(LINUX2_IB_CRYPT_LOCATION);\n      {$ENDIF}\n      FPreLoader.AddLocation(LINUX20_IB_CRYPT_LOCATION);\n    {$ENDIF}\n  {$ENDIF}\n  Self.LoadCodePages;\nend;\n\nfunction TZFirebird20PlainDriver.GetDescription: string;\nbegin\n  Result := 'Native Plain Driver for Firebird 2.0';\nend;\n\nfunction TZFirebird20PlainDriver.GetProtocol: string;\nbegin\n  Result := 'firebird-2.0';\nend;\n\n{ IZFirebirdD20PlainDriver }\nfunction TZFirebirdD20PlainDriver.Clone: IZPlainDriver;\nbegin\n  Result := TZFirebirdD20PlainDriver.Create;\nend;\n\nconstructor TZFirebirdD20PlainDriver.Create;\nbegin\n   inherited create;\n  {$IFNDEF UNIX}\n    {$IFNDEF FIREBIRD_STRICT_DLL_LOADING}\n      FLoader.AddLocation(WINDOWS2_DLL_LOCATION_EMBEDDED);\n    {$ENDIF}\n    FLoader.AddLocation(WINDOWS20_DLL_LOCATION_EMBEDDED);\n  {$ELSE}\n    {$IFNDEF FIREBIRD_STRICT_DLL_LOADING}\n      FLoader.AddLocation(LINUX2_DLL_LOCATION_EMBEDDED);\n    {$ENDIF}\n    FLoader.AddLocation(LINUX20_DLL_LOCATION_EMBEDDED);\n    {$ENDIF}\nend;\n\nfunction TZFirebirdD20PlainDriver.GetProtocol: string;\nbegin\n  Result := 'firebirdd-2.0';\nend;\n\nfunction TZFirebirdD20PlainDriver.GetDescription: string;\nbegin\n  Result := 'Native Plain Driver for Firebird Embedded 2.0';\nend;\n\n{ IZFirebird21PlainDriver }\n\nfunction TZFirebird21PlainDriver.Clone: IZPlainDriver;\nbegin\n  Result := TZFirebird21PlainDriver.Create;\nend;\n\nfunction TZFirebird21PlainDriver.GetUnicodeCodePageName: String;\nbegin\n  Result := 'UTF8';\nend;\n\nprocedure TZFirebird21PlainDriver.LoadCodePages;\nbegin\n  inherited;\n  AddFireBird15CodePages(Self);\n  AddFireBird2CodePages(Self);\n  AddFireBird21CodePages(Self);\nend;\n\nprocedure TZFirebird21PlainDriver.LoadApi;\nbegin\n  inherited LoadApi;\n\n  with Loader do\n  begin\n  @FIREBIRD_API.fb_interpret        := GetAddress('fb_interpret');\n  end;\nend;\n\nconstructor TZFirebird21PlainDriver.Create;\nbegin\n   inherited create;\n  {$IFNDEF UNIX}\n    {$IFNDEF FIREBIRD_STRICT_DLL_LOADING}\n      FLoader.AddLocation(WINDOWS2_DLL_LOCATION);\n    {$ENDIF}\n    FLoader.AddLocation(WINDOWS21_DLL_LOCATION);\n  {$ELSE}\n    {$IFNDEF FIREBIRD_STRICT_DLL_LOADING}\n      FLoader.AddLocation(LINUX2_DLL_LOCATION);\n    {$ENDIF}\n    FLoader.AddLocation(LINUX21_DLL_LOCATION);\n    FLoader.AddLocation(LINUX2_DLL_LOCATION2);\n    {$IFDEF ENABLE_INTERBASE_CRYPT}\n      {$IFNDEF FIREBIRD_STRICT_DLL_LOADING}\n        FPreLoader.AddLocation(LINUX2_IB_CRYPT_LOCATION);\n      {$ENDIF}\n      FPreLoader.AddLocation(LINUX21_IB_CRYPT_LOCATION);\n    {$ENDIF}\n  {$ENDIF}\n  Self.LoadCodePages;\nend;\n\n\nfunction TZFirebird21PlainDriver.GetDescription: string;\nbegin\n  Result := 'Native Plain Driver for Firebird 2.1';\nend;\n\nfunction TZFirebird21PlainDriver.GetProtocol: string;\nbegin\n  Result := 'firebird-2.1';\nend;\n\nfunction TZFirebird21PlainDriver.isc_interprete(buffer: PAnsiChar;\n  status_vector: PPISC_STATUS): ISC_STATUS;\nvar\n   bufsize : integer;\nbegin\n  bufsize := 1024;\n  Result := FIREBIRD_API.fb_interpret(buffer, bufsize, status_vector);\nend;\n\n{ IZFirebirdD21PlainDriver }\nfunction TZFirebirdD21PlainDriver.Clone: IZPlainDriver;\nbegin\n  Result := TZFirebirdD21PlainDriver.Create;\nend;\n\nconstructor TZFirebirdD21PlainDriver.Create;\nbegin\n   inherited create;\n  {$IFNDEF UNIX}\n    {$IFNDEF FIREBIRD_STRICT_DLL_LOADING}\n      FLoader.AddLocation(WINDOWS2_DLL_LOCATION_EMBEDDED);\n    {$ENDIF}\n    FLoader.AddLocation(WINDOWS21_DLL_LOCATION_EMBEDDED);\n  {$ELSE}\n    {$IFNDEF FIREBIRD_STRICT_DLL_LOADING}\n      FLoader.AddLocation(LINUX2_DLL_LOCATION_EMBEDDED);\n    {$ENDIF}\n    FLoader.AddLocation(LINUX21_DLL_LOCATION_EMBEDDED);\n    {$ENDIF}\nend;\n\nfunction TZFirebirdD21PlainDriver.GetProtocol: string;\nbegin\n  Result := 'firebirdd-2.1';\nend;\n\nfunction TZFirebirdD21PlainDriver.GetDescription: string;\nbegin\n  Result := 'Native Plain Driver for Firebird Embedded 2.1';\nend;\n\n{ TZFirebird25PlainDriver }\nfunction TZFirebird25PlainDriver.Clone: IZPlainDriver;\nbegin\n  Result := TZFirebird25PlainDriver.Create;\nend;\n\nfunction TZFirebird25PlainDriver.GetUnicodeCodePageName: String;\nbegin\n  Result := 'UTF8';\nend;\n\nprocedure TZFirebird25PlainDriver.LoadCodePages;\nbegin\n  inherited;\n  AddFireBird15CodePages(Self);\n  AddFireBird2CodePages(Self);\n  AddFireBird21CodePages(Self);\n  ResetCodePage(CS_BIG_5, 'BIG_5', CS_BIG_5, ceAnsi, zCP_BIG5, '', 2); {Chinese, Vietnamese, Korean} //Changed Bytes\n  Self.AddCodePage('GB18030', CS_GB18030, ceAnsi, zCP_GB18030, '', 4); {Chinese}\nend;\n\nprocedure TZFirebird25PlainDriver.LoadApi;\nbegin\n  inherited LoadApi;\n\n  with Loader do\n  begin\n    @FIREBIRD_API.fb_interpret        := GetAddress('fb_interpret');\n  end;\nend;\n\nconstructor TZFirebird25PlainDriver.Create;\nbegin\n  inherited create;\n  {$IFNDEF UNIX}\n    {$IFNDEF FIREBIRD_STRICT_DLL_LOADING}\n      FLoader.AddLocation(WINDOWS2_DLL_LOCATION);\n    {$ENDIF}\n    FLoader.AddLocation(WINDOWS25_DLL_LOCATION);\n  {$ELSE}\n    {$IFNDEF FIREBIRD_STRICT_DLL_LOADING}\n      FLoader.AddLocation(LINUX2_DLL_LOCATION);\n    {$ENDIF}\n    FLoader.AddLocation(LINUX25_DLL_LOCATION);\n    FLoader.AddLocation(LINUX2_DLL_LOCATION2);\n    {$IFDEF ENABLE_INTERBASE_CRYPT}\n      {$IFNDEF FIREBIRD_STRICT_DLL_LOADING}\n        FPreLoader.AddLocation(LINUX2_IB_CRYPT_LOCATION);\n      {$ENDIF}\n      FPreLoader.AddLocation(LINUX25_IB_CRYPT_LOCATION);\n    {$ENDIF}\n  {$ENDIF}\n  Self.LoadCodePages;\nend;\n\nfunction TZFirebird25PlainDriver.GetProtocol: string;\nbegin\n  Result := 'firebird-2.5';\nend;\n\nfunction TZFirebird25PlainDriver.GetDescription: string;\nbegin\n  Result := 'Native Plain Driver for Firebird 2.5';\nend;\n\nfunction TZFirebird25PlainDriver.isc_interprete(buffer: PAnsiChar;\n  status_vector: PPISC_STATUS): ISC_STATUS;\nbegin\n  Result:=inherited isc_interprete(buffer, status_vector);\nend;\n\n{ TZFirebirdD25PlainDriver }\nfunction TZFirebirdD25PlainDriver.Clone: IZPlainDriver;\nbegin\n  Result := TZFirebirdD25PlainDriver.Create;\nend;\n\nconstructor TZFirebirdD25PlainDriver.Create;\nbegin\n   inherited create;\n  {$IFNDEF UNIX}\n    {$IFNDEF FIREBIRD_STRICT_DLL_LOADING}\n      FLoader.AddLocation(WINDOWS2_DLL_LOCATION_EMBEDDED);\n    {$ENDIF}\n    FLoader.AddLocation(WINDOWS25_DLL_LOCATION_EMBEDDED);\n  {$ELSE}\n    {$IFNDEF FIREBIRD_STRICT_DLL_LOADING}\n      FLoader.AddLocation(LINUX2_DLL_LOCATION_EMBEDDED);\n    {$ENDIF}\n    FLoader.AddLocation(LINUX25_DLL_LOCATION_EMBEDDED);\n    {$ENDIF}\nend;\n\nfunction TZFirebirdD25PlainDriver.GetProtocol: string;\nbegin\n  Result := 'firebirdd-2.5';\nend;\n\nfunction TZFirebirdD25PlainDriver.GetDescription: string;\nbegin\n  Result := 'Native Plain Driver for Firebird Embedded 2.5';\nend;\n\nend.\n"
  },
  {
    "path": "lib/zeosdbo/src/plain/ZPlainFirebirdInterbaseConstants.pas",
    "content": "{*********************************************************}\n{                                                         }\n{                 Zeos Database Objects                   }\n{         Interbase and Firebird Common constants         }\n{                                                         }\n{        Originally written by Sergey Seroukhov           }\n{                                                         }\n{*********************************************************}\n\n{@********************************************************}\n{    Copyright (c) 1999-2012 Zeos Development Group       }\n{                                                         }\n{ License Agreement:                                      }\n{                                                         }\n{ This library is distributed in the hope that it will be }\n{ useful, but WITHOUT ANY WARRANTY; without even the      }\n{ implied warranty of MERCHANTABILITY or FITNESS FOR      }\n{ A PARTICULAR PURPOSE.  See the GNU Lesser General       }\n{ Public License for more details.                        }\n{                                                         }\n{ The source code of the ZEOS Libraries and packages are  }\n{ distributed under the Library GNU General Public        }\n{ License (see the file COPYING / COPYING.ZEOS)           }\n{ with the following  modification:                       }\n{ As a special exception, the copyright holders of this   }\n{ library give you permission to link this library with   }\n{ independent modules to produce an executable,           }\n{ regardless of the license terms of these independent    }\n{ modules, and to copy and distribute the resulting       }\n{ executable under terms of your choice, provided that    }\n{ you also meet, for each linked independent module,      }\n{ the terms and conditions of the license of that module. }\n{ An independent module is a module which is not derived  }\n{ from or based on this library. If you modify this       }\n{ library, you may extend this exception to your version  }\n{ of the library, but you are not obligated to do so.     }\n{ If you do not wish to do so, delete this exception      }\n{ statement from your version.                            }\n{                                                         }\n{                                                         }\n{ The project web site is located on:                     }\n{   http://zeos.firmos.at  (FORUM)                        }\n{   http://sourceforge.net/p/zeoslib/tickets/ (BUGTRACKER)}\n{   svn://svn.code.sf.net/p/zeoslib/code-0/trunk (SVN)    }\n{                                                         }\n{   http://www.sourceforge.net/projects/zeoslib.          }\n{                                                         }\n{                                                         }\n{                                 Zeos Development Group. }\n{********************************************************@}\n\nunit ZPlainFirebirdInterbaseConstants;\n\ninterface\n\n{$I ZPlain.inc}\n\nuses \n   ZCompatibility; \n\nconst\n  IBLocalBufferLength = 512;\n  IBBigLocalBufferLength = IBLocalBufferLength * 2;\n  IBHugeLocalBufferLength = IBBigLocalBufferLength * 20;\n\n  {temporary fix by mdaems\n   I think Andre wanted to use this as a generic error code for a broken connection\n   At the moment I put it here as it's only used in the IB/FB implementation\n  }\n  DISCONNECT_ERROR = -1;\n\n  ISC_NULL = -1;\n  ISC_NOTNULL = 0;\n\n  ISC_TRUE                      = 1;\n  ISC_FALSE                     = 0;\n  DSQL_CLOSE                    = 1;\n  DSQL_DROP                     = 2;\n  DSQL_UNPREPARE                = 4;\n\n\n  SQLDA_VERSION1                = 1;\n  SQLDA_VERSION2                = 2;\n  SQL_DIALECT_V5                = 1;\n  SQL_DIALECT_V6                = 3;\n  SQL_DIALECT_CURRENT = SQL_DIALECT_V6; (* latest IB DIALECT *)\n\n  { SQL definitions }\n  SQL_VARYING                    = 448;\n  SQL_TEXT                       = 452;\n  SQL_DOUBLE                     = 480;\n  SQL_FLOAT                      = 482;\n  SQL_LONG                       = 496;\n  SQL_SHORT                      = 500;\n  SQL_TIMESTAMP                  = 510;\n  SQL_BLOB                       = 520;\n  SQL_D_FLOAT                    = 530;\n  SQL_ARRAY                      = 540;\n  SQL_QUAD                       = 550;\n  SQL_TYPE_TIME                  = 560;\n  SQL_TYPE_DATE                  = 570;\n  SQL_INT64                      = 580;\n  SQL_BOOLEAN                    = 590;\n  SQL_DATE                       = SQL_TIMESTAMP;\n\n(* #define BLR_WORD(x)\tUCHAR(x), UCHAR((x) >> 8)\n\n *  WARNING: if you add a new BLR representing a data type, and the value\n *           is greater than the numerically greatest value which now\n *           represents a data type, you must change the define for\n *           DTYPE_BLR_MAX in jrd/align.h, and add the necessary entries\n *           to all the arrays in that file.\n *)\n\n  blr_text            = 14;\n  blr_text2           = 15;\n  blr_short           = 7;\n  blr_long            = 8;\n  blr_quad            = 9;\n  blr_float           = 10;\n  blr_double          = 27;\n  blr_d_float         = 11;\n  blr_timestamp       = 35;\n  blr_varying         = 37;\n  blr_varying2        = 38;\n  blr_blob            = 261;\n  blr_cstring         = 40;\n  blr_cstring2        = 41; // added in 3.2 JPN\n  blr_blob_id         = 45; // added from gds.h\n  blr_sql_date        = 12;\n  blr_sql_time        = 13;\n  blr_int64           = 16;\n  blr_blob2           = 17;\n  blr_domain_name     = 18;\n  blr_domain_name2    = 19;\n  blr_not_nullable    = 20;\n  blr_column_name     = 21;\n  blr_column_name2    = 22;\n  blr_bool            = 23;\n\n  // Historical alias for pre V6 applications\n  blr_date\t\t      = blr_timestamp;\n(*\n  // first sub parameter for blr_domain_name[2]\n  blr_domain_type_of  = 0;\n  blr_domain_full     = 1;\n\n  blr_inner           = 0;\n  blr_left            = 1;\n  blr_right           = 2;\n  blr_full            = 3;\n\n  blr_gds_code        = 0;\n  blr_sql_code        = 1;\n  blr_exception       = 2;\n  blr_trigger_code    = 3;\n  blr_default_code    = 4;\n  blr_raise           = 5;\n  blr_exception_msg   = 6;\n  blr_exception_params= 7;\n\n  blr_version4        = 4;\n  blr_version5\t\t(unsigned char)5\n//#define blr_version6\t\t(unsigned char)6\n#define blr_eoc\t\t\t(unsigned char)76\n#define blr_end\t\t\t(unsigned char)255\n\n#define blr_assignment\t\t(unsigned char)1\n#define blr_begin\t\t(unsigned char)2\n#define blr_dcl_variable  \t(unsigned char)3\t/* added from gds.h */\n#define blr_message\t\t(unsigned char)4\n#define blr_erase\t\t(unsigned char)5\n#define blr_fetch\t\t(unsigned char)6\n#define blr_for\t\t\t(unsigned char)7\n#define blr_if\t\t\t(unsigned char)8\n#define blr_loop\t\t(unsigned char)9\n#define blr_modify\t\t(unsigned char)10\n#define blr_handler\t\t(unsigned char)11\n#define blr_receive\t\t(unsigned char)12\n#define blr_select\t\t(unsigned char)13\n#define blr_send\t\t(unsigned char)14\n#define blr_store\t\t(unsigned char)15\n#define blr_label\t\t(unsigned char)17\n#define blr_leave\t\t(unsigned char)18\n#define blr_store2\t\t(unsigned char)19\n#define blr_post\t\t(unsigned char)20\n#define blr_literal\t\t(unsigned char)21\n#define blr_dbkey\t\t(unsigned char)22\n#define blr_field\t\t(unsigned char)23\n#define blr_fid\t\t\t(unsigned char)24\n#define blr_parameter\t\t(unsigned char)25\n#define blr_variable\t\t(unsigned char)26\n#define blr_average\t\t(unsigned char)27\n#define blr_count\t\t(unsigned char)28\n#define blr_maximum\t\t(unsigned char)29\n#define blr_minimum\t\t(unsigned char)30\n#define blr_total\t\t(unsigned char)31\n\n// unused codes: 32..33\n\n#define blr_add\t\t\t(unsigned char)34\n#define blr_subtract\t\t(unsigned char)35\n#define blr_multiply\t\t(unsigned char)36\n#define blr_divide\t\t(unsigned char)37\n#define blr_negate\t\t(unsigned char)38\n#define blr_concatenate\t\t(unsigned char)39\n#define blr_substring\t\t(unsigned char)40\n#define blr_parameter2\t\t(unsigned char)41\n#define blr_from\t\t(unsigned char)42\n#define blr_via\t\t\t(unsigned char)43\n#define blr_user_name   \t(unsigned char)44\t/* added from gds.h */\n#define blr_null\t\t(unsigned char)45\n\n#define blr_equiv\t\t\t(unsigned char)46\n#define blr_eql\t\t\t(unsigned char)47\n#define blr_neq\t\t\t(unsigned char)48\n#define blr_gtr\t\t\t(unsigned char)49\n#define blr_geq\t\t\t(unsigned char)50\n#define blr_lss\t\t\t(unsigned char)51\n#define blr_leq\t\t\t(unsigned char)52\n#define blr_containing\t\t(unsigned char)53\n#define blr_matching\t\t(unsigned char)54\n#define blr_starting\t\t(unsigned char)55\n#define blr_between\t\t(unsigned char)56\n#define blr_or\t\t\t(unsigned char)57\n#define blr_and\t\t\t(unsigned char)58\n#define blr_not\t\t\t(unsigned char)59\n#define blr_any\t\t\t(unsigned char)60\n#define blr_missing\t\t(unsigned char)61\n#define blr_unique\t\t(unsigned char)62\n#define blr_like\t\t(unsigned char)63\n\n// unused codes: 64..66\n\n#define blr_rse\t\t\t(unsigned char)67\n#define blr_first\t\t(unsigned char)68\n#define blr_project\t\t(unsigned char)69\n#define blr_sort\t\t(unsigned char)70\n#define blr_boolean\t\t(unsigned char)71\n#define blr_ascending\t\t(unsigned char)72\n#define blr_descending\t\t(unsigned char)73\n#define blr_relation\t\t(unsigned char)74\n#define blr_rid\t\t\t(unsigned char)75\n#define blr_union\t\t(unsigned char)76\n#define blr_map\t\t\t(unsigned char)77\n#define blr_group_by\t\t(unsigned char)78\n#define blr_aggregate\t\t(unsigned char)79\n#define blr_join_type\t\t(unsigned char)80\n\n// unused codes: 81..82\n\n#define blr_agg_count\t\t(unsigned char)83\n#define blr_agg_max\t\t(unsigned char)84\n#define blr_agg_min\t\t(unsigned char)85\n#define blr_agg_total\t\t(unsigned char)86\n#define blr_agg_average\t\t(unsigned char)87\n#define\tblr_parameter3\t\t(unsigned char)88\t/* same as Rdb definition */\n/* unsupported\n#define blr_run_max\t\t(unsigned char)89\n#define blr_run_min\t\t(unsigned char)90\n#define blr_run_total\t\t(unsigned char)91\n#define blr_run_average\t\t(unsigned char)92\n*/\n#define blr_agg_count2\t\t(unsigned char)93\n#define blr_agg_count_distinct\t(unsigned char)94\n#define blr_agg_total_distinct\t(unsigned char)95\n#define blr_agg_average_distinct (unsigned char)96\n\n// unused codes: 97..99\n\n#define blr_function\t\t(unsigned char)100\n#define blr_gen_id\t\t(unsigned char)101\n///#define blr_prot_mask\t\t(unsigned char)102\n#define blr_upcase\t\t(unsigned char)103\n///#define blr_lock_state\t\t(unsigned char)104\n#define blr_value_if\t\t(unsigned char)105\n#define blr_matching2\t\t(unsigned char)106\n#define blr_index\t\t(unsigned char)107\n#define blr_ansi_like\t\t(unsigned char)108\n#define blr_scrollable\t\t(unsigned char) 109\n\n// unused codes: 110..117\n\n#define blr_run_count\t\t(unsigned char)118\t/* changed from 88 to avoid conflict with blr_parameter3 */\n#define blr_rs_stream\t\t(unsigned char)119\n#define blr_exec_proc\t\t(unsigned char)120\n\n// unused codes: 121..123\n\n#define blr_procedure\t\t(unsigned char)124\n#define blr_pid\t\t\t(unsigned char)125\n#define blr_exec_pid\t\t(unsigned char)126\n#define blr_singular\t\t(unsigned char)127\n#define blr_abort\t\t(unsigned char)128\n#define blr_block\t \t(unsigned char)129\n#define blr_error_handler\t(unsigned char)130\n\n#define blr_cast\t\t(unsigned char)131\n\n#define blr_pid2\t\t\t(unsigned char)132\n#define blr_procedure2\t\t(unsigned char)133\n\n#define blr_start_savepoint\t(unsigned char)134\n#define blr_end_savepoint\t(unsigned char)135\n\n// unused codes: 136..138\n\n#define blr_plan\t\t(unsigned char)139\t/* access plan items */\n#define blr_merge\t\t(unsigned char)140\n#define blr_join\t\t(unsigned char)141\n#define blr_sequential\t\t(unsigned char)142\n#define blr_navigational\t(unsigned char)143\n#define blr_indices\t\t(unsigned char)144\n#define blr_retrieve\t\t(unsigned char)145\n\n#define blr_relation2\t\t(unsigned char)146\n#define blr_rid2\t\t(unsigned char)147\n\n// unused codes: 148..149\n\n#define blr_set_generator       (unsigned char)150\n\n#define blr_ansi_any\t\t(unsigned char)151   /* required for NULL handling */\n#define blr_exists\t\t(unsigned char)152   /* required for NULL handling */\n\n// unused codes: 153\n\n#define blr_record_version\t(unsigned char)154\t/* get tid of record */\n#define blr_stall\t\t(unsigned char)155\t/* fake server stall */\n\n// unused codes: 156..157\n\n#define blr_ansi_all\t\t(unsigned char)158   /* required for NULL handling */\n\n#define blr_extract\t\t(unsigned char)159\n\n/* sub parameters for blr_extract */\n\n#define blr_extract_year\t\t(unsigned char)0\n#define blr_extract_month\t\t(unsigned char)1\n#define blr_extract_day\t\t\t(unsigned char)2\n#define blr_extract_hour\t\t(unsigned char)3\n#define blr_extract_minute\t\t(unsigned char)4\n#define blr_extract_second\t\t(unsigned char)5\n#define blr_extract_weekday\t\t(unsigned char)6\n#define blr_extract_yearday\t\t(unsigned char)7\n#define blr_extract_millisecond\t(unsigned char)8\n#define blr_extract_week\t\t(unsigned char)9\n\n#define blr_current_date\t(unsigned char)160\n#define blr_current_timestamp\t(unsigned char)161\n#define blr_current_time\t(unsigned char)162\n\n/* These codes reuse BLR code space */\n\n#define blr_post_arg\t\t(unsigned char)163\n#define blr_exec_into\t\t(unsigned char)164\n#define blr_user_savepoint\t(unsigned char)165\n#define blr_dcl_cursor\t\t(unsigned char)166\n#define blr_cursor_stmt\t\t(unsigned char)167\n#define blr_current_timestamp2\t(unsigned char)168\n#define blr_current_time2\t(unsigned char)169\n#define blr_agg_list\t\t(unsigned char)170\n#define blr_agg_list_distinct\t(unsigned char)171\n#define blr_modify2\t\t\t(unsigned char)172\n\n// unused codes: 173\n\n/* FB 1.0 specific BLR */\n\n#define blr_current_role\t(unsigned char)174\n#define blr_skip\t\t(unsigned char)175\n\n/* FB 1.5 specific BLR */\n\n#define blr_exec_sql\t\t(unsigned char)176\n#define blr_internal_info\t(unsigned char)177\n#define blr_nullsfirst\t\t(unsigned char)178\n#define blr_writelock\t\t(unsigned char)179\n#define blr_nullslast       (unsigned char)180\n\n/* FB 2.0 specific BLR */\n\n#define blr_lowcase\t\t\t(unsigned char)181\n#define blr_strlen\t\t\t(unsigned char)182\n\n/* sub parameter for blr_strlen */\n#define blr_strlen_bit\t\t(unsigned char)0\n#define blr_strlen_char\t\t(unsigned char)1\n#define blr_strlen_octet\t(unsigned char)2\n\n#define blr_trim\t\t\t(unsigned char)183\n\n/* first sub parameter for blr_trim */\n#define blr_trim_both\t\t(unsigned char)0\n#define blr_trim_leading\t(unsigned char)1\n#define blr_trim_trailing\t(unsigned char)2\n\n/* second sub parameter for blr_trim */\n#define blr_trim_spaces\t\t(unsigned char)0\n#define blr_trim_characters\t(unsigned char)1\n\n/* These codes are actions for user-defined savepoints */\n\n#define blr_savepoint_set\t(unsigned char)0\n#define blr_savepoint_release\t(unsigned char)1\n#define blr_savepoint_undo\t(unsigned char)2\n#define blr_savepoint_release_single\t(unsigned char)3\n\n/* These codes are actions for cursors */\n\n#define blr_cursor_open\t\t\t(unsigned char)0\n#define blr_cursor_close\t\t(unsigned char)1\n#define blr_cursor_fetch\t\t(unsigned char)2\n#define blr_cursor_fetch_scroll\t(unsigned char)3\n\n/* scroll options */\n\n#define blr_scroll_forward\t\t(unsigned char)0\n#define blr_scroll_backward\t\t(unsigned char)1\n#define blr_scroll_bof\t\t\t(unsigned char)2\n#define blr_scroll_eof\t\t\t(unsigned char)3\n#define blr_scroll_absolute\t\t(unsigned char)4\n#define blr_scroll_relative\t\t(unsigned char)5\n\n/* FB 2.1 specific BLR */\n\n#define blr_init_variable\t(unsigned char)184\n#define blr_recurse\t\t\t(unsigned char)185\n#define blr_sys_function\t(unsigned char)186\n\n// FB 2.5 specific BLR\n\n#define blr_auto_trans\t\t(unsigned char)187\n#define blr_similar\t\t\t(unsigned char)188\n#define blr_exec_stmt\t\t(unsigned char)189\n\n// subcodes of blr_exec_stmt\n#define blr_exec_stmt_inputs\t\t(unsigned char) 1\t// input parameters count\n#define blr_exec_stmt_outputs\t\t(unsigned char) 2\t// output parameters count\n#define blr_exec_stmt_sql\t\t\t(unsigned char) 3\n#define blr_exec_stmt_proc_block\t(unsigned char) 4\n#define blr_exec_stmt_data_src\t\t(unsigned char) 5\n#define blr_exec_stmt_user\t\t\t(unsigned char) 6\n#define blr_exec_stmt_pwd\t\t\t(unsigned char) 7\n#define blr_exec_stmt_tran    \t\t(unsigned char) 8\t// not implemented yet\n#define blr_exec_stmt_tran_clone\t(unsigned char) 9\t// make transaction parameters equal to current transaction\n#define blr_exec_stmt_privs\t\t\t(unsigned char) 10\n#define blr_exec_stmt_in_params\t\t(unsigned char) 11\t// not named input parameters\n#define blr_exec_stmt_in_params2\t(unsigned char) 12\t// named input parameters\n#define blr_exec_stmt_out_params\t(unsigned char) 13\t// output parameters\n#define blr_exec_stmt_role\t\t\t(unsigned char) 14\n\n#define blr_stmt_expr\t\t\t\t(unsigned char) 190\n#define blr_derived_expr\t\t\t(unsigned char) 191\n\n// FB 3.0 specific BLR\n\n#define blr_procedure3\t\t\t\t(unsigned char) 192\n#define blr_exec_proc2\t\t\t\t(unsigned char) 193\n#define blr_function2\t\t\t\t(unsigned char) 194\n#define blr_window\t\t\t\t\t(unsigned char) 195\n#define blr_partition_by\t\t\t(unsigned char) 196\n#define blr_continue_loop\t\t\t(unsigned char) 197\n#define blr_procedure4\t\t\t\t(unsigned char) 198\n#define blr_agg_function\t\t\t(unsigned char) 199\n#define blr_substring_similar\t\t(unsigned char) 200\n#define blr_bool_as_value\t\t\t(unsigned char) 201\n#define blr_coalesce\t\t\t\t(unsigned char) 202\n#define blr_decode\t\t\t\t\t(unsigned char) 203\n#define blr_exec_subproc\t\t\t(unsigned char) 204\n#define blr_subproc_decl\t\t\t(unsigned char) 205\n#define blr_subproc\t\t\t\t\t(unsigned char) 206\n#define blr_subfunc_decl\t\t\t(unsigned char) 207\n#define blr_subfunc\t\t\t\t\t(unsigned char) 208\n#define blr_record_version2\t\t\t(unsigned char) 209\n\n#endif // JRD_BLR_H\n*)\n\n  { SQL subtypes definitions from RDB$FIELDS}\n  CS_NONE = 0;\n  CS_BINARY = 1;\n  CS_ASCII = 2;\n  CS_UNICODE_FSS = 3;\n  CS_UTF8 = 4;\n  CS_SJIS_0208 = 5;\n  CS_EUCJ_0208 = 6;\n  CS_DOS737 = 9;\n  CS_DOS437 = 10;\n  CS_DOS850 = 11;\n  CS_DOS865 = 12;\n  CS_DOS860 = 13;\n  CS_DOS863 = 14;\n  CS_DOS775 = 15;\n  CS_DOS858 = 16;\n  CS_DOS862 = 17;\n  CS_DOS864 = 18;\n  CS_NEXT = 19;\n\n  CS_ISO8859_1 = 21;\n  CS_ISO8859_2 = 22;\n  CS_ISO8859_3 = 23;\n  CS_ISO8859_4 = 24;\n\n  CS_ISO8859_5 = 35;\n  CS_ISO8859_6 = 36;\n  CS_ISO8859_7 = 37;\n  CS_ISO8859_8 = 38;\n  CS_ISO8859_9 = 39;\n  CS_ISO8859_13 = 40;\n  CS_KSC_5601 = 44;\n  CS_DOS852 = 45;\n  CS_DOS857 = 46;\n  CS_DOS861 = 47;\n  CS_DOS866 = 48;\n  CS_DOS869 = 49;\n  CS_CYRL = 50;\n  CS_WIN1250 = 51;\n  CS_WIN1251 = 52;\n  CS_WIN1252 = 53;\n  CS_WIN1253 = 54;\n  CS_WIN1254 = 55;\n\n  CS_WIN1255 = 58;\n  CS_WIN1256 = 59;\n  CS_WIN1257 = 60;\n  CS_BIG_5 = 56;\n  CS_GB_2312 = 57;\n  CS_KOI8R = 63;\n  CS_KOI8U = 64;\n  CS_WIN1258 = 65;\n  CS_TIS620 = 66;\n  CS_GBK = 67;\n  CS_CP943C = 68;\n  CS_GB18030 = 69;\n\n  CS_METADATA = CS_UNICODE_FSS;\n\n  RDB_NUMBERS_NONE = 0;\n  RDB_NUMBERS_NUMERIC = 1;\n  RDB_NUMBERS_DECIMAL = 2;\n\n  { Blob Subtypes }\n  { types less than zero are reserved for customer use }\n  isc_blob_untyped               = 0;\n\n  { internal subtypes }\n  isc_blob_text                  = 1;\n  isc_blob_blr                   = 2;\n  isc_blob_acl                   = 3;\n  isc_blob_ranges                = 4;\n  isc_blob_summary               = 5;\n  isc_blob_format                = 6;\n  isc_blob_tra                   = 7;\n  isc_blob_extfile               = 8;\n  isc_blob_debug_info            = 9;\n  isc_blob_max_predefined_subtype= 10;\n\n{ > FB2.5 down}\n  { the range 20-30 is reserved for dBASE and Paradox types }\n  isc_blob_formatted_memo        = 20;\n  isc_blob_paradox_ole           = 21;\n  isc_blob_graphic               = 22;\n  isc_blob_dbase_ole             = 23;\n  isc_blob_typed_binary          = 24;\n{ FB2.5 down < }\n\n  {* Blob information items *}\n  isc_info_blob_num_segments = 4;\n  isc_info_blob_max_segment = 5;\n  isc_info_blob_total_length = 6;\n  isc_info_blob_type = 7;\n\n  {* error codes *}\n  isc_segment                    =  335544366;\n  isc_segstr_eof                 =  335544367;\n  isc_lock_conflict              =  335544345;\n\n  { Database parameter block stuff }\n  isc_dpb_version1               = 1;\n  isc_dpb_cdd_pathname           = 1;\n  isc_dpb_allocation             = 2;\n  isc_dpb_journal                = 3;\n  isc_dpb_page_size              = 4;\n  isc_dpb_num_buffers            = 5;\n  isc_dpb_buffer_length          = 6;\n  isc_dpb_debug                  = 7;\n  isc_dpb_garbage_collect        = 8;\n  isc_dpb_verify                 = 9;\n  isc_dpb_sweep                  = 10;\n  isc_dpb_enable_journal         = 11;\n  isc_dpb_disable_journal        = 12;\n  isc_dpb_dbkey_scope            = 13;\n  isc_dpb_number_of_users        = 14;\n  isc_dpb_trace                  = 15;\n  isc_dpb_no_garbage_collect     = 16;\n  isc_dpb_damaged                = 17;\n  isc_dpb_license                = 18;\n  isc_dpb_sys_user_name          = 19;\n  isc_dpb_encrypt_key            = 20;\n  isc_dpb_activate_shadow        = 21;\n  isc_dpb_sweep_interval         = 22;\n  isc_dpb_delete_shadow          = 23;\n  isc_dpb_force_write            = 24;\n  isc_dpb_begin_log              = 25;\n  isc_dpb_quit_log               = 26;\n  isc_dpb_no_reserve             = 27;\n  isc_dpb_user_name              = 28;\n  isc_dpb_password               = 29;\n  isc_dpb_password_enc           = 30;\n  isc_dpb_sys_user_name_enc      = 31;\n  isc_dpb_interp                 = 32;\n  isc_dpb_online_dump            = 33;\n  isc_dpb_old_file_size          = 34;\n  isc_dpb_old_num_files          = 35;\n  isc_dpb_old_file               = 36;\n  isc_dpb_old_start_page         = 37;\n  isc_dpb_old_start_seqno        = 38;\n  isc_dpb_old_start_file         = 39;\n  isc_dpb_drop_walfile           = 40;\n  isc_dpb_old_dump_id            = 41;\n  isc_dpb_wal_backup_dir         = 42;\n  isc_dpb_wal_chkptlen           = 43;\n  isc_dpb_wal_numbufs            = 44;\n  isc_dpb_wal_bufsize            = 45;\n  isc_dpb_wal_grp_cmt_wait       = 46;\n  isc_dpb_lc_messages            = 47;\n  isc_dpb_lc_ctype               = 48;\n  isc_dpb_cache_manager          = 49;\n  isc_dpb_shutdown               = 50;\n  isc_dpb_online                 = 51;\n  isc_dpb_shutdown_delay         = 52;\n  isc_dpb_reserved               = 53;\n  isc_dpb_overwrite              = 54;\n  isc_dpb_sec_attach             = 55;\n  isc_dpb_disable_wal            = 56;\n  isc_dpb_connect_timeout        = 57;\n  isc_dpb_dummy_packet_interval  = 58;\n  isc_dpb_gbak_attach            = 59;\n  isc_dpb_sql_role_name          = 60;\n  isc_dpb_set_page_buffers       = 61;\n  isc_dpb_working_directory      = 62;\n  isc_dpb_SQL_dialect            = 63;\n  isc_dpb_set_db_readonly        = 64;\n  isc_dpb_set_db_SQL_dialect     = 65;\n  isc_dpb_gfix_attach            = 66;\n  isc_dpb_gstat_attach           = 67;\n  isc_dpb_last_dpb_constant      = isc_dpb_gstat_attach;\n\n  { isc_dpb_verify specific flags }\n  isc_dpb_pages                  = 1;\n  isc_dpb_records                = 2;\n  isc_dpb_indices                = 4;\n  isc_dpb_transactions           = 8;\n  isc_dpb_no_update              = 16;\n  isc_dpb_repair                 = 32;\n  isc_dpb_ignore                 = 64;\n\n  { isc_dpb_shutdown specific flags }\n  isc_dpb_shut_cache             = 1;\n  isc_dpb_shut_attachment        = 2;\n  isc_dpb_shut_transaction       = 4;\n  isc_dpb_shut_force             = 8;\n\n  { Transaction parameter block stuff }\n  isc_tpb_version1               = 1;\n  isc_tpb_version3               = 3;\n  isc_tpb_consistency            = 1;\n  isc_tpb_concurrency            = 2;\n  isc_tpb_shared                 = 3;\n  isc_tpb_protected              = 4;\n  isc_tpb_exclusive              = 5;\n  isc_tpb_wait                   = 6;\n  isc_tpb_nowait                 = 7;\n  isc_tpb_read                   = 8;\n  isc_tpb_write                  = 9;\n  isc_tpb_lock_read              = 10;\n  isc_tpb_lock_write             = 11;\n  isc_tpb_verb_time              = 12;\n  isc_tpb_commit_time            = 13;\n  isc_tpb_ignore_limbo           = 14;\n  isc_tpb_read_committed         = 15;\n  isc_tpb_autocommit             = 16;\n  isc_tpb_rec_version            = 17;\n  isc_tpb_no_rec_version         = 18;\n  isc_tpb_restart_requests       = 19;\n  isc_tpb_no_auto_undo           = 20;\n  isc_tpb_last_tpb_constant      = isc_tpb_no_auto_undo;\n\n  { Blob Parameter Block }\n  isc_bpb_version1               = 1;\n  isc_bpb_source_type            = 1;\n  isc_bpb_target_type            = 2;\n  isc_bpb_type                   = 3;\n  isc_bpb_source_interp          = 4;\n  isc_bpb_target_interp          = 5;\n  isc_bpb_filter_parameter       = 6;\n\n  { SQL information items }\n  isc_info_sql_select            = 4;\n  isc_info_sql_bind              = 5;\n  isc_info_sql_num_variables     = 6;\n  isc_info_sql_describe_vars     = 7;\n  isc_info_sql_describe_end      = 8;\n  isc_info_sql_sqlda_seq         = 9;\n  isc_info_sql_message_seq       = 10;\n  isc_info_sql_type              = 11;\n  isc_info_sql_sub_type          = 12;\n  isc_info_sql_scale             = 13;\n  isc_info_sql_length            = 14;\n  isc_info_sql_null_ind          = 15;\n  isc_info_sql_field             = 16;\n  isc_info_sql_relation          = 17;\n  isc_info_sql_owner             = 18;\n  isc_info_sql_alias             = 19;\n  isc_info_sql_sqlda_start       = 20;\n  isc_info_sql_stmt_type         = 21;\n  isc_info_sql_get_plan          = 22;\n  isc_info_sql_records           = 23;\n  isc_info_sql_batch_fetch       = 24;\n\n  { SQL information return values }\n  isc_info_sql_stmt_select         = 1;\n  isc_info_sql_stmt_insert         = 2;\n  isc_info_sql_stmt_update         = 3;\n  isc_info_sql_stmt_delete         = 4;\n  isc_info_sql_stmt_ddl            = 5;\n  isc_info_sql_stmt_get_segment    = 6;\n  isc_info_sql_stmt_put_segment    = 7;\n  isc_info_sql_stmt_exec_procedure = 8;\n  isc_info_sql_stmt_start_trans    = 9;\n  isc_info_sql_stmt_commit         = 10;\n  isc_info_sql_stmt_rollback       = 11;\n  isc_info_sql_stmt_select_for_upd = 12;\n  isc_info_sql_stmt_set_generator  = 13;\n\n  isc_bpb_type_segmented           = 0;\n  isc_bpb_type_stream              = 1;\n\n  {************** Information call declarations **************}\n\n  { Common, structural codes }\n  isc_info_end                     = 1;\n  isc_info_truncated               = 2;\n  isc_info_error                   = 3;\n  isc_info_data_not_ready          = 4;\n  isc_info_flag_end                = 127;\n\n  { Request information items }\n  isc_info_number_messages         = 4;\n  isc_info_max_message             = 5;\n  isc_info_max_send                = 6;\n  isc_info_max_receive             = 7;\n  isc_info_state                   = 8;\n  isc_info_message_number          = 9;\n  isc_info_message_size            = 10;\n  isc_info_request_cost            = 11;\n  isc_info_access_path             = 12;\n  isc_info_req_select_count        = 13;\n  isc_info_req_insert_count        = 14;\n  isc_info_req_update_count        = 15;\n  isc_info_req_delete_count        = 16;\n\n  { Database information items }\n  isc_info_db_id                 =          4;\n  isc_info_reads                 =          5;\n  isc_info_writes                =          6;\n  isc_info_fetches               =          7;\n  isc_info_marks                 =          8;\n  isc_info_implementation        =         11;\n  isc_info_version               =         12;\n  isc_info_base_level            =         13;\n  isc_info_page_size             =         14;\n  isc_info_num_buffers           =         15;\n  isc_info_limbo                 =         16;\n  isc_info_current_memory        =         17;\n  isc_info_max_memory            =         18;\n  isc_info_window_turns          =         19;\n  isc_info_license               =         20;\n  isc_info_allocation            =         21;\n  isc_info_attachment_id         =         22;\n  isc_info_read_seq_count        =         23;\n  isc_info_read_idx_count        =         24;\n  isc_info_insert_count          =         25;\n  isc_info_update_count          =         26;\n  isc_info_delete_count          =         27;\n  isc_info_backout_count         =         28;\n  isc_info_purge_count           =         29;\n  isc_info_expunge_count         =         30;\n  isc_info_sweep_interval        =         31;\n  isc_info_ods_version           =         32;\n  isc_info_ods_minor_version     =         33;\n  isc_info_no_reserve            =         34;\n  isc_info_logfile               =         35;\n  isc_info_cur_logfile_name      =         36;\n  isc_info_cur_log_part_offset   =         37;\n  isc_info_num_wal_buffers       =         38;\n  isc_info_wal_buffer_size       =         39;\n  isc_info_wal_ckpt_length       =         40;\n  isc_info_wal_cur_ckpt_interval =         41;\n  isc_info_wal_prv_ckpt_fname    =         42;\n  isc_info_wal_prv_ckpt_poffset  =         43;\n  isc_info_wal_recv_ckpt_fname   =         44;\n  isc_info_wal_recv_ckpt_poffset =         45;\n  isc_info_wal_grpc_wait_usecs   =         47;\n  isc_info_wal_num_io            =         48;\n  isc_info_wal_avg_io_size       =         49;\n  isc_info_wal_num_commits       =         50;\n  isc_info_wal_avg_grpc_size     =         51;\n  isc_info_forced_writes         =         52;\n  isc_info_user_names            =         53;\n  isc_info_page_errors           =         54;\n  isc_info_record_errors         =         55;\n  isc_info_bpage_errors          =         56;\n  isc_info_dpage_errors          =         57;\n  isc_info_ipage_errors          =         58;\n  isc_info_ppage_errors          =         59;\n  isc_info_tpage_errors          =         60;\n  isc_info_set_page_buffers      =         61;\n  isc_info_db_SQL_dialect        =         62;\n  isc_info_db_read_only          =         63;\n  isc_info_db_size_in_pages      =         64;\n\n  frb_info_att_charset           = 101;\n  isc_info_db_class              = 102;\n  isc_info_firebird_version      = 103;\n  isc_info_oldest_transaction    = 104;\n  isc_info_oldest_active         = 105;\n  isc_info_oldest_snapshot       = 106;\n  isc_info_next_transaction      = 107;\n  isc_info_db_provider           = 108;\n  isc_info_active_transactions   = 109;\n  isc_info_active_tran_count     = 110;\n  isc_info_creation_date         = 111;\n  isc_info_db_file_size          = 112;\n\ntype\n  ULong                = Cardinal;\n  UChar                = AnsiChar;\n  Short                = SmallInt;\n\n  ISC_LONG             = LongInt;\n  UISC_LONG            = ULong;\n  ISC_INT64            = Int64;\n  ISC_STATUS           = NativeInt;\n  UISC_STATUS          = ULong;\n  PISC_LONG            = ^ISC_LONG;\n  PUISC_LONG           = ^UISC_LONG;\n  PISC_STATUS          = ^ISC_STATUS;\n  PPISC_STATUS         = ^PISC_STATUS;\n  PUISC_STATUS         = ^UISC_STATUS;\n  PShort               = ^Short;\n  PPAnsiChar               = ^PAnsiChar;\n  UShort               = Word;\n  PVoid                = Pointer;\n\n  { C Date/Time Structure }\n  TCTimeStructure = record\n    tm_sec:        Integer;   { Seconds }\n    tm_min:        Integer;   { Minutes }\n    tm_hour:       Integer;   { Hour (0--23) }\n    tm_mday:       Integer;   { Day of month (1--31) }\n    tm_mon:        Integer;   { Month (0--11) }\n    tm_year:       Integer;   { Year (calendar year minus 1900) }\n    tm_wday:       Integer;   { Weekday (0--6) Sunday = 0) }\n    tm_yday:       Integer;   { Day of year (0--365) }\n    tm_isdst:      Integer;   { 0 if daylight savings time is not in effect) }\n  end;\n  PCTimeStructure = ^TCTimeStructure;\n  TM = TCTimeStructure;\n  PTM = ^TM;\n\n  TISC_VARYING = record\n    strlen:       Short;\n    str:          array[0..0] of AnsiChar; //AVZ - was AnsiChar\n  end;\n  PISC_VARYING = ^TISC_VARYING;\n\n  { InterBase Handle Definitions }\n  //ludob ib/FB handles are 32 bit even on 64 bit systems\n  TISC_BLOB_HANDLE              = LongWord;\n  PISC_BLOB_HANDLE              = ^TISC_BLOB_HANDLE;\n  TISC_DB_HANDLE                = LongWord;\n  PISC_DB_HANDLE                = ^TISC_DB_HANDLE;\n  TISC_STMT_HANDLE              = LongWord;\n  PISC_STMT_HANDLE              = ^TISC_STMT_HANDLE;\n  TISC_TR_HANDLE                = LongWord;\n  PISC_TR_HANDLE                = ^TISC_TR_HANDLE;\n  TISC_CALLBACK                 = procedure;\n\n  { Time & Date Support }\n  ISC_DATE = LongInt;\n  PISC_DATE = ^ISC_DATE;\n  ISC_TIME = ULong;\n  PISC_TIME = ^ISC_TIME;\n\n  TISC_TIMESTAMP = record\n    timestamp_date: ISC_DATE; \n    timestamp_time: ISC_TIME;\n  end;\n  PISC_TIMESTAMP = ^TISC_TIMESTAMP;\n\n  { Blob id structure }\n  TGDS_QUAD = record\n    gds_quad_high:  ISC_LONG;\n    gds_quad_low:   UISC_LONG;\n  end;\n  PGDS_QUAD            = ^TGDS_QUAD;\n\n  TISC_QUAD            = TGDS_QUAD;\n  PISC_QUAD            = ^TISC_QUAD;\n\n  TISC_ARRAY_BOUND = record\n    array_bound_lower:  Short;\n    array_bound_upper:  Short;\n  end;\n  PISC_ARRAY_BOUND = ^TISC_ARRAY_BOUND;\n\n  TISC_ARRAY_DESC = record\n    array_desc_dtype:   Byte;\n    array_desc_scale:   ShortInt;\n    array_desc_length:  Word;\n    array_desc_field_name: array[0..31] of AnsiChar;\n    array_desc_relation_name: array[0..31] of AnsiChar;\n    array_desc_dimensions: Short;\n    array_desc_flags: Short;\n    array_desc_bounds: array[0..15] of TISC_ARRAY_BOUND;\n  end;\n  PISC_ARRAY_DESC = ^TISC_ARRAY_DESC;\n\n  TISC_BLOB_DESC = record\n    blob_desc_subtype:          Short;\n    blob_desc_charset:          Short;\n    blob_desc_segment_size:     Short;\n    blob_desc_field_name:       array[0..31] of UChar;\n    blob_desc_relation_name:    array[0..31] of UChar;\n  end;\n  PISC_BLOB_DESC = ^TISC_BLOB_DESC;\n\n  { Declare the extended SQLDA }\n  TXSQLVAR = record\n    sqltype:            Short;     { datatype of field }\n    sqlscale:           Short;     { scale factor }\n    sqlsubtype:         Short;     { datatype subtype - BLOBs }\n\t\t\t           { & text types only }\n    sqllen:             Short;     { length of data area }\n    sqldata:            PAnsiChar;     { address of data }\n    sqlind:             PSmallInt;  { address of indicator } \n                                   { variable }\n    sqlname_length:     Short;     { length of sqlname field }\n    { name of field, name length + space for NULL }\n    sqlname:            array[0..31] of AnsiChar;\n    relname_length:     Short;     { length of relation name }\n    { field's relation name + space for NULL }\n    relname:            array[0..31] of AnsiChar;\n    ownname_length:     Short;     { length of owner name }\n    { relation's owner name + space for NULL }\n    ownname:            array[0..31] of AnsiChar;\n    aliasname_length:   Short;     { length of alias name }\n    { relation's alias name + space for NULL }\n    aliasname:          array[0..31] of AnsiChar;\n  end;\n  PXSQLVAR = ^TXSQLVAR;\n\n  TXSQLDA = record\n    version:            Short;     { version of this XSQLDA }\n    { XSQLDA name field }\n    sqldaid:            array[0..7] of AnsiChar;\n    sqldabc:            ISC_LONG;  { length in bytes of SQLDA }\n    sqln:               Short;     { number of fields allocated }\n    sqld:               Short;     { actual number of fields }\n    { first field address }\n    sqlvar:             array[0..0] of TXSQLVAR;\n  end;\n  PXSQLDA = ^TXSQLDA;\n\n {****************************************************}\n { This record type is for passing arguments to       }\n { isc_start_transaction (See docs)                   }\n {****************************************************}\n  TISC_START_TRANS = record\n    db_handle:          PISC_DB_HANDLE;\n    tpb_length:         Word;\n    tpb_address:        PAnsiChar;\n  end;\n\n {****************************************************}\n { This record type is for passing arguments to       }\n { isc_start_multiple (see docs)                      }\n {****************************************************}\n  TISC_TEB = record\n    db_handle:          PISC_DB_HANDLE;\n    tpb_length:         LongInt;\n    tpb_address:        PAnsiChar;\n  end;\n  PISC_TEB = ^TISC_TEB;\n  TISC_TEB_ARRAY = array[0..0] of TISC_TEB;\n  PISC_TEB_ARRAY = ^TISC_TEB_ARRAY;\n\n  { Interbase status array }\n  PARRAY_ISC_STATUS = ^TARRAY_ISC_STATUS;\n  TARRAY_ISC_STATUS = array[0..20] of ISC_STATUS;\n\n{ ************** Plain API Function types definition ************* }\n\n  { General database routines }\n\n  Tisc_attach_database = function(status_vector: PISC_STATUS;\n    db_name_length: Short; db_name: PAnsiChar; db_handle: PISC_DB_HANDLE;\n    parm_buffer_length: Short; parm_buffer: PAnsiChar): ISC_STATUS;\n    {$IFDEF MSWINDOWS} stdcall {$ELSE} cdecl {$ENDIF};\n\n  Tisc_detach_database = function(status_vector: PISC_STATUS;\n    db_handle: PISC_DB_HANDLE): ISC_STATUS;\n    {$IFDEF MSWINDOWS} stdcall {$ELSE} cdecl {$ENDIF};\n\n  Tisc_drop_database = function(status_vector: PISC_STATUS;\n    db_handle: PISC_DB_HANDLE): ISC_STATUS;\n    {$IFDEF MSWINDOWS} stdcall {$ELSE} cdecl {$ENDIF};\n\n  Tisc_database_info = function(status_vector: PISC_STATUS;\n    db_handle: PISC_DB_HANDLE; item_list_buffer_length: Short;\n    item_list_buffer: PAnsiChar; result_buffer_length: Short;\n    result_buffer: PAnsiChar): ISC_STATUS;\n    {$IFDEF MSWINDOWS} stdcall {$ELSE} cdecl {$ENDIF};\n\n  { Array processing routines }\n  Tisc_array_gen_sdl = function(status_vector: PISC_STATUS;\n    isc_array_desc: PISC_ARRAY_DESC; isc_arg3: PShort;\n    isc_arg4: PAnsiChar; isc_arg5: PShort): ISC_STATUS;\n    {$IFDEF MSWINDOWS} stdcall {$ELSE} cdecl {$ENDIF};\n\n  Tisc_array_get_slice = function(status_vector: PISC_STATUS;\n    db_handle: PISC_DB_HANDLE; trans_handle: PISC_TR_HANDLE;\n    array_id: PISC_QUAD; descriptor: PISC_ARRAY_DESC;\n    dest_array: PVoid; slice_length: ISC_LONG): ISC_STATUS;\n    {$IFDEF MSWINDOWS} stdcall {$ELSE} cdecl {$ENDIF};\n\n  Tisc_array_lookup_bounds = function(status_vector: PISC_STATUS;\n    db_handle: PISC_DB_HANDLE; trans_handle: PISC_TR_HANDLE;\n    table_name, column_name: PAnsiChar;\n    descriptor: PISC_ARRAY_DESC): ISC_STATUS;\n    {$IFDEF MSWINDOWS} stdcall {$ELSE} cdecl {$ENDIF};\n\n  Tisc_array_lookup_desc = function(status_vector: PISC_STATUS;\n    db_handle: PISC_DB_HANDLE; trans_handle: PISC_TR_HANDLE;\n    table_name, column_name: PAnsiChar;\n    descriptor: PISC_ARRAY_DESC): ISC_STATUS;\n    {$IFDEF MSWINDOWS} stdcall {$ELSE} cdecl {$ENDIF};\n\n  Tisc_array_set_desc = function(status_vector: PISC_STATUS;\n    table_name: PAnsiChar; column_name: PAnsiChar;\n    sql_dtype, sql_length, sql_dimensions: PShort;\n    descriptor: PISC_ARRAY_DESC): ISC_STATUS;\n    {$IFDEF MSWINDOWS} stdcall {$ELSE} cdecl {$ENDIF};\n\n  Tisc_array_put_slice = function(status_vector: PISC_STATUS;\n    db_handle: PISC_DB_HANDLE; trans_handle: PISC_TR_HANDLE;\n    array_id: PISC_QUAD; descriptor: PISC_ARRAY_DESC;\n    source_array: PVoid; slice_length: PISC_LONG): ISC_STATUS;\n    {$IFDEF MSWINDOWS} stdcall {$ELSE} cdecl {$ENDIF};\n\n  Tisc_free = function(isc_arg1: PAnsiChar): ISC_LONG;\n    {$IFDEF MSWINDOWS} stdcall {$ELSE} cdecl {$ENDIF};\n\n  Tisc_sqlcode = function(status_vector: PISC_STATUS): ISC_LONG;\n    {$IFDEF MSWINDOWS} stdcall {$ELSE} cdecl {$ENDIF};\n\n  Tisc_sql_interprete = procedure(sqlcode: Short; buffer: PAnsiChar;\n    buffer_length: Short); {$IFDEF MSWINDOWS} stdcall {$ELSE} cdecl {$ENDIF};\n\n  Tisc_interprete = function(buffer: PAnsiChar; status_vector: PPISC_STATUS):\n    ISC_STATUS; {$IFDEF MSWINDOWS} stdcall {$ELSE} cdecl {$ENDIF};\n\n  Tfb_interpret = function(buffer: PAnsiChar;  bufsize: integer; status_vector: PPISC_STATUS):\n    ISC_STATUS; {$IFDEF MSWINDOWS} stdcall {$ELSE} cdecl {$ENDIF};\n\n  { Transaction support routines }\n\n  Tisc_start_transaction = function(status_vector: PISC_STATUS;\n    tran_handle: PISC_TR_HANDLE; db_handle_count: Short;\n    db_handle: PISC_DB_HANDLE; tpb_length: Word; tpb_address: PAnsiChar):\n    ISC_STATUS; {$IFDEF MSWINDOWS} stdcall {$ELSE} cdecl {$ENDIF};\n\n  Tisc_start_multiple = function(status_vector: PISC_STATUS;\n    tran_handle: PISC_TR_HANDLE; db_handle_count: Short;\n    teb_vector_address: PISC_TEB): ISC_STATUS;\n    {$IFDEF MSWINDOWS} stdcall {$ELSE} cdecl {$ENDIF};\n\n  Tisc_rollback_transaction = function(status_vector: PISC_STATUS;\n    tran_handle: PISC_TR_HANDLE): ISC_STATUS;\n    {$IFDEF MSWINDOWS} stdcall {$ELSE} cdecl {$ENDIF};\n\n  Tisc_rollback_retaining = function(status_vector: PISC_STATUS;\n    tran_handle: PISC_TR_HANDLE): ISC_STATUS;\n    {$IFDEF MSWINDOWS} stdcall {$ELSE} cdecl {$ENDIF};\n\n  Tisc_commit_retaining = function(status_vector: PISC_STATUS;\n    tran_handle: PISC_TR_HANDLE): ISC_STATUS;\n    {$IFDEF MSWINDOWS} stdcall {$ELSE} cdecl {$ENDIF};\n\n  Tisc_commit_transaction = function(status_vector: PISC_STATUS;\n    tran_handle: PISC_TR_HANDLE): ISC_STATUS;\n    {$IFDEF MSWINDOWS} stdcall {$ELSE} cdecl {$ENDIF};\n\n  Tisc_transaction_info = function(status_vector: PISC_STATUS;\n    tr_handle: PISC_TR_HANDLE; item_list_buffer_length: Short;\n    item_list_buffer: PAnsiChar; result_buffer_length: Short;\n    result_buffer: PAnsiChar): ISC_STATUS;\n    {$IFDEF MSWINDOWS} stdcall {$ELSE} cdecl {$ENDIF};\n\n  { Dynamic SQL routines }\n\n  Tisc_dsql_allocate_statement = function(status_vector: PISC_STATUS;\n    db_handle: PISC_DB_HANDLE; stmt_handle: PISC_STMT_HANDLE): ISC_STATUS;\n    {$IFDEF MSWINDOWS} stdcall {$ELSE} cdecl {$ENDIF};\n\n  Tisc_dsql_alloc_statement2 = function(status_vector: PISC_STATUS;\n    db_handle: PISC_DB_HANDLE; stmt_handle: PISC_STMT_HANDLE): ISC_STATUS;\n    {$IFDEF MSWINDOWS} stdcall {$ELSE} cdecl {$ENDIF};\n\n  Tisc_dsql_describe = function(status_vector: PISC_STATUS;\n    stmt_handle: PISC_STMT_HANDLE; dialect: Word; xsqlda: PXSQLDA): ISC_STATUS;\n    {$IFDEF MSWINDOWS} stdcall {$ELSE} cdecl {$ENDIF};\n\n  Tisc_dsql_describe_bind = function(status_vector: PISC_STATUS;\n    stmt_handle: PISC_STMT_HANDLE; dialect: Word; xsqlda: PXSQLDA): ISC_STATUS;\n    {$IFDEF MSWINDOWS} stdcall {$ELSE} cdecl {$ENDIF};\n\n  Tisc_dsql_execute = function(status_vector: PISC_STATUS;\n    tran_handle: PISC_TR_HANDLE; stmt_handle: PISC_STMT_HANDLE; dialect: Word;\n    xsqlda: PXSQLDA): ISC_STATUS;\n    {$IFDEF MSWINDOWS} stdcall {$ELSE} cdecl {$ENDIF};\n\n  Tisc_dsql_execute2 = function(status_vector: PISC_STATUS;\n    tran_handle: PISC_TR_HANDLE; stmt_handle: PISC_STMT_HANDLE; dialect: Word;\n    in_xsqlda, out_xsqlda: PXSQLDA): ISC_STATUS;\n    {$IFDEF MSWINDOWS} stdcall {$ELSE} cdecl {$ENDIF};\n\n  Tisc_dsql_execute_immediate = function(status_vector: PISC_STATUS;\n    db_handle: PISC_DB_HANDLE; tran_handle: PISC_TR_HANDLE; length: Word;\n    statement: PAnsiChar; dialect: Word; xsqlda: PXSQLDA): ISC_STATUS;\n    {$IFDEF MSWINDOWS} stdcall {$ELSE} cdecl {$ENDIF};\n\n  Tisc_dsql_fetch = function(status_vector: PISC_STATUS;\n    stmt_handle: PISC_STMT_HANDLE; dialect: Word; xsqlda: PXSQLDA): ISC_STATUS;\n    {$IFDEF MSWINDOWS} stdcall {$ELSE} cdecl {$ENDIF};\n\n  Tisc_dsql_free_statement = function(status_vector: PISC_STATUS;\n    stmt_handle: PISC_STMT_HANDLE; options: Word): ISC_STATUS;\n    {$IFDEF MSWINDOWS} stdcall {$ELSE} cdecl {$ENDIF};\n\n  Tisc_dsql_prepare = function(status_vector: PISC_STATUS;\n    tran_handle: PISC_TR_HANDLE; stmt_handle: PISC_STMT_HANDLE;\n    length: Word; statement: PAnsiChar; dialect: Word; xsqlda: PXSQLDA):\n    ISC_STATUS; {$IFDEF MSWINDOWS} stdcall {$ELSE} cdecl {$ENDIF};\n\n  Tisc_dsql_set_cursor_name = function(status_vector: PISC_STATUS;\n    stmt_handle: PISC_STMT_HANDLE; cursor_name: PAnsiChar; _type: Word): ISC_STATUS;\n    {$IFDEF MSWINDOWS} stdcall {$ELSE} cdecl {$ENDIF};\n\n  Tisc_dsql_sql_info = function(status_vector: PISC_STATUS;\n    stmt_handle: PISC_STMT_HANDLE; item_length: Short; items: PAnsiChar;\n    buffer_length: Short; buffer: PAnsiChar): ISC_STATUS;\n    {$IFDEF MSWINDOWS} stdcall {$ELSE} cdecl {$ENDIF};\n\n  { Blob processing routines }\n\n  Tisc_open_blob2 = function(status_vector: PISC_STATUS;\n    db_handle: PISC_DB_HANDLE; tran_handle: PISC_TR_HANDLE;\n    blob_handle: PISC_BLOB_HANDLE; blob_id: PISC_QUAD; bpb_length: Short;\n    bpb_buffer: PAnsiChar): ISC_STATUS;\n    {$IFDEF MSWINDOWS} stdcall {$ELSE} cdecl {$ENDIF};\n\n  Tisc_create_blob2 = function(status_vector: PISC_STATUS;\n    db_handle: PISC_DB_HANDLE; tran_handle: PISC_TR_HANDLE;\n    blob_handle: PISC_BLOB_HANDLE; blob_id: PISC_QUAD; bpb_length: Short;\n    bpb_address: PAnsiChar): ISC_STATUS;\n    {$IFDEF MSWINDOWS} stdcall {$ELSE} cdecl {$ENDIF};\n\n  Tisc_blob_info = function(status_vector: PISC_STATUS;\n    blob_handle: PISC_BLOB_HANDLE; item_list_buffer_length: Short;\n    item_list_buffer: PAnsiChar; result_buffer_length: Short; result_buffer: PAnsiChar):\n    ISC_STATUS; {$IFDEF MSWINDOWS} stdcall {$ELSE} cdecl {$ENDIF};\n\n  Tisc_close_blob = function(status_vector: PISC_STATUS;\n    blob_handle: PISC_BLOB_HANDLE): ISC_STATUS;\n    {$IFDEF MSWINDOWS} stdcall {$ELSE} cdecl {$ENDIF};\n\n  Tisc_cancel_blob = function(status_vector: PISC_STATUS;\n    blob_handle: PISC_BLOB_HANDLE): ISC_STATUS;\n    {$IFDEF MSWINDOWS} stdcall {$ELSE} cdecl {$ENDIF};\n\n  Tisc_get_segment = function(status_vector: PISC_STATUS;\n    blob_handle: PISC_BLOB_HANDLE; actual_seg_length: PWord;\n    seg_buffer_length: Word; seg_buffer: PAnsiChar): ISC_STATUS;\n    {$IFDEF MSWINDOWS} stdcall {$ELSE} cdecl {$ENDIF};\n\n  Tisc_put_segment = function(status_vector: PISC_STATUS;\n    blob_handle: PISC_BLOB_HANDLE; seg_buffer_len: Word; seg_buffer: PAnsiChar):\n    ISC_STATUS; {$IFDEF MSWINDOWS} stdcall {$ELSE} cdecl {$ENDIF};\n\n  { Event processing routines }\n\n  Tisc_event_block = function(event_buffer: PPAnsiChar; result_buffer: PPAnsiChar;\n    id_count: Word; event_list: array of PAnsiChar): ISC_LONG;\n    {$IFDEF MSWINDOWS} stdcall {$ELSE} cdecl {$ENDIF};\n\n  Tisc_event_counts = procedure(status_vector: PISC_STATUS;\n    buffer_length: Short; event_buffer: PAnsiChar; result_buffer: PAnsiChar);\n    {$IFDEF MSWINDOWS} stdcall {$ELSE} cdecl {$ENDIF};\n\n  Tisc_cancel_events = function(status_vector: PISC_STATUS;\n    db_handle: PISC_DB_HANDLE; event_id: PISC_LONG): ISC_STATUS;\n    {$IFDEF MSWINDOWS} stdcall {$ELSE} cdecl {$ENDIF};\n\n  Tisc_que_events = function(status_vector: PISC_STATUS;\n    db_handle: PISC_DB_HANDLE; event_id: PISC_LONG; length: Short;\n    event_buffer: PAnsiChar; event_function: TISC_CALLBACK;\n    event_function_arg: PVoid): ISC_STATUS;\n    {$IFDEF MSWINDOWS} stdcall {$ELSE} cdecl {$ENDIF};\n\n  { Types convertion routines }\n\n  Tisc_decode_date = procedure(ib_date: PISC_QUAD; tm_date: PCTimeStructure);\n    {$IFDEF MSWINDOWS} stdcall {$ELSE} cdecl {$ENDIF};\n\n  Tisc_encode_date = procedure(tm_date: PCTimeStructure; ib_date: PISC_QUAD);\n    {$IFDEF MSWINDOWS} stdcall {$ELSE} cdecl {$ENDIF};\n\n  { Interbase Version 6 routines }\n  Tisc_decode_sql_date = procedure(ib_date: PISC_DATE;\n    tm_date: PCTimeStructure); {$IFDEF MSWINDOWS} stdcall {$ELSE} cdecl {$ENDIF};\n\n  Tisc_decode_sql_time = procedure(ib_time: PISC_TIME;\n    tm_date: PCTimeStructure); {$IFDEF MSWINDOWS} stdcall {$ELSE} cdecl {$ENDIF};\n\n  Tisc_decode_timestamp = procedure(ib_timestamp: PISC_TIMESTAMP;\n    tm_date: PCTimeStructure); {$IFDEF MSWINDOWS} stdcall {$ELSE} cdecl {$ENDIF};\n\n  Tisc_encode_sql_date = procedure(tm_date: PCTimeStructure;\n    ib_date: PISC_DATE); {$IFDEF MSWINDOWS} stdcall {$ELSE} cdecl {$ENDIF};\n\n  Tisc_encode_sql_time = procedure(tm_date: PCTimeStructure;\n    ib_time: PISC_TIME); {$IFDEF MSWINDOWS} stdcall {$ELSE} cdecl {$ENDIF};\n\n  Tisc_encode_timestamp = procedure(tm_date: PCTimeStructure;\n    ib_timestamp: PISC_TIMESTAMP);\n    {$IFDEF MSWINDOWS} stdcall {$ELSE} cdecl {$ENDIF};\n\n  Tisc_vax_integer = function(buffer: PAnsiChar; length: Short): ISC_LONG;\n    {$IFDEF MSWINDOWS} stdcall {$ELSE} cdecl {$ENDIF};\n\n{ ************** Collection of Plain API Function types definition ************* }\nTZFirebird_API = record\n  { General database routines }\n  isc_attach_database:  Tisc_attach_database;\n  isc_detach_database:  Tisc_detach_database;\n  isc_drop_database:    Tisc_drop_database;\n  isc_database_info:    Tisc_database_info;\n  isc_free:             Tisc_free;\n  isc_sqlcode:          Tisc_sqlcode;\n  isc_sql_interprete:   Tisc_sql_interprete;\n  isc_interprete:       Tisc_interprete;\n  fb_interpret:         Tfb_interpret;\n\n  { Transaction support routines }\n  isc_start_transaction: Tisc_start_transaction;\n  isc_start_multiple:   Tisc_start_multiple;\n  isc_rollback_transaction: Tisc_rollback_transaction;\n  isc_rollback_retaining: Tisc_rollback_retaining;\n  isc_commit_transaction: Tisc_commit_transaction;\n  isc_commit_retaining: Tisc_commit_retaining;\n  isc_transaction_info: Tisc_transaction_info;\n\n  { Dynamic SQL routines }\n  isc_dsql_allocate_statement: Tisc_dsql_allocate_statement;\n  isc_dsql_alloc_statement2: Tisc_dsql_alloc_statement2;\n  isc_dsql_describe:    Tisc_dsql_describe;\n  isc_dsql_describe_bind: Tisc_dsql_describe_bind;\n  isc_dsql_execute:     Tisc_dsql_execute;\n  isc_dsql_execute2:    Tisc_dsql_execute2;\n  isc_dsql_execute_immediate: Tisc_dsql_execute_immediate;\n  isc_dsql_fetch:       Tisc_dsql_fetch;\n  isc_dsql_free_statement: Tisc_dsql_free_statement;\n  isc_dsql_prepare:     Tisc_dsql_prepare;\n  isc_dsql_set_cursor_name: Tisc_dsql_set_cursor_name;\n  isc_dsql_sql_info:    Tisc_dsql_sql_info;\n\n  { Array processing routines }\n  isc_array_gen_sdl:    Tisc_array_gen_sdl;\n  isc_array_get_slice:  Tisc_array_get_slice;\n  isc_array_lookup_bounds: Tisc_array_lookup_bounds;\n  isc_array_lookup_desc: Tisc_array_lookup_desc;\n  isc_array_set_desc:   Tisc_array_set_desc;\n  isc_array_put_slice:  Tisc_array_put_slice;\n\n  { Blob processing routines }\n  isc_open_blob2:       Tisc_open_blob2;\n  isc_create_blob2:     Tisc_create_blob2;\n  isc_blob_info:        Tisc_blob_info;\n  isc_close_blob:       Tisc_close_blob;\n  isc_cancel_blob:      Tisc_cancel_blob;\n  isc_get_segment:      Tisc_get_segment;\n  isc_put_segment:      Tisc_put_segment;\n\n  { Event processing routines }\n  isc_que_events:       Tisc_que_events;\n  isc_event_counts:     Tisc_event_counts;\n  isc_event_block:      Tisc_event_block;\n  isc_cancel_events:    Tisc_cancel_events;\n\n  { Types convertion routines }\n  isc_encode_date:      Tisc_encode_date;\n  isc_decode_date:      Tisc_decode_date;\n  isc_vax_integer:      Tisc_vax_integer;\n\n  isc_encode_sql_date:  Tisc_encode_sql_date;\n  isc_decode_sql_date:  Tisc_decode_sql_date;\n\n  isc_encode_sql_time:  Tisc_encode_sql_time;\n  isc_decode_sql_time:  Tisc_decode_sql_time;\n\n  isc_encode_timestamp: Tisc_encode_timestamp;\n  isc_decode_timestamp: Tisc_decode_timestamp;\nend;\n\nimplementation\n\nend.\n"
  },
  {
    "path": "lib/zeosdbo/src/plain/ZPlainLoader.pas",
    "content": "  {*********************************************************}\n{                                                         }\n{                 Zeos Database Objects                   }\n{          Utility Classes for Native Libraries           }\n{                                                         }\n{        Originally written by Sergey Seroukhov           }\n{                                                         }\n{*********************************************************}\n\n{@********************************************************}\n{    Copyright (c) 1999-2012 Zeos Development Group       }\n{                                                         }\n{ License Agreement:                                      }\n{                                                         }\n{ This library is distributed in the hope that it will be }\n{ useful, but WITHOUT ANY WARRANTY; without even the      }\n{ implied warranty of MERCHANTABILITY or FITNESS FOR      }\n{ A PARTICULAR PURPOSE.  See the GNU Lesser General       }\n{ Public License for more details.                        }\n{                                                         }\n{ The source code of the ZEOS Libraries and packages are  }\n{ distributed under the Library GNU General Public        }\n{ License (see the file COPYING / COPYING.ZEOS)           }\n{ with the following  modification:                       }\n{ As a special exception, the copyright holders of this   }\n{ library give you permission to link this library with   }\n{ independent modules to produce an executable,           }\n{ regardless of the license terms of these independent    }\n{ modules, and to copy and distribute the resulting       }\n{ executable under terms of your choice, provided that    }\n{ you also meet, for each linked independent module,      }\n{ the terms and conditions of the license of that module. }\n{ An independent module is a module which is not derived  }\n{ from or based on this library. If you modify this       }\n{ library, you may extend this exception to your version  }\n{ of the library, but you are not obligated to do so.     }\n{ If you do not wish to do so, delete this exception      }\n{ statement from your version.                            }\n{                                                         }\n{                                                         }\n{ The project web site is located on:                     }\n{   http://zeos.firmos.at  (FORUM)                        }\n{   http://sourceforge.net/p/zeoslib/tickets/ (BUGTRACKER)}\n{   svn://svn.code.sf.net/p/zeoslib/code-0/trunk (SVN)    }\n{                                                         }\n{   http://www.sourceforge.net/projects/zeoslib.          }\n{                                                         }\n{                                                         }\n{                                 Zeos Development Group. }\n{********************************************************@}\n\nunit ZPlainLoader;\n\ninterface\n\n{$I ZPlain.inc}\n\nuses Types, ZCompatibility;\n\ntype\n  {** Implements a loader for native library. }\n\n  { TZNativeLibraryLoader }\n\n  TZNativeLibraryLoader = class (TObject)\n  private\n    FLocations: TStringDynArray;\n  {$IFDEF FPC}\n    FHandle: PtrInt;\n  {$ELSE}\n    FHandle: THandle;  //M.A. LongWord;\n  {$ENDIF}\n    FLoaded: Boolean;\n    FCurrentLocation: String;\n    function ZLoadLibrary(Location: String): Boolean;\n  protected\n    procedure FreeNativeLibrary; virtual;\n  public\n    constructor Create(Locations: array of string);\n    destructor Destroy; override;\n\n    procedure ClearLocations;\n    procedure AddLocation(Location: String);\n    function Load: Boolean; virtual;\n    function LoadNativeLibrary: Boolean; virtual;\n    function LoadNativeLibraryStrict(Location: String): Boolean;\n    procedure LoadIfNeeded; virtual;\n\n    property Loaded: Boolean read FLoaded write FLoaded;\n  {$IFDEF FPC}\n    property Handle: PtrInt read FHandle write FHandle;\n  {$ELSE}\n    property Handle: THandle { M.A. LongWord} read FHandle write FHandle;\n  {$ENDIF}\n    property CurrentLocation: String read FCurrentLocation write FCurrentLocation;\n    function GetAddress(ProcName: PAnsiChar): Pointer;\n  end;\n\nimplementation\n\nuses SysUtils, \n{$IFNDEF UNIX} \n  Windows, \n{$ELSE} \n  {$IFNDEF FPC} \n    libc, \n  {$ENDIF} \n{$ENDIF}\n  ZMessages;\n\n{ TZNativeLibraryLoader }\n\n{**\n  Creates this loader class and assignes main properties.\n  @param Locations locations of native library on windows platform.\n}\nconstructor TZNativeLibraryLoader.Create(Locations: array of string);\nvar\n  I: Integer;\nbegin\n  SetLength(FLocations, Length(Locations));\n  for I := 0 to High(Locations) do\n    FLocations[I] := Locations[I]; \n  FHandle := INVALID_HANDLE_VALUE;\n  FCurrentLocation := '';\n  FLoaded := False;\nend;\n\n{**\n  Destroys the library and cleanups the memory.\n}\ndestructor TZNativeLibraryLoader.Destroy;\nbegin\n  if Loaded then\n    FreeNativeLibrary;\n  inherited Destroy;\nend;\n\nprocedure TZNativeLibraryLoader.ClearLocations;\nbegin\n  SetLength(FLocations,0);\nend;\n\nprocedure TZNativeLibraryLoader.AddLocation(Location: String);\nvar\n   i: integer;\nbegin\n  if Location <> '' then\n  begin\n    SetLength(FLocations, Length(FLocations) + 1);\n    for i := High(FLocations) downto 1 do\n      FLocations[i] := FLocations[i - 1];\n    FLocations[0] := Location;\n  end;\nend;\n\n{**\n  Loads a library module.\n  @return <code>True</code> if library was successfully loaded.\n}\nfunction TZNativeLibraryLoader.Load: Boolean;\nbegin\n  Result := LoadNativeLibrary;\nend;\n\n{**\n  Loads a library if it was not previously loaded.\n}\nprocedure TZNativeLibraryLoader.LoadIfNeeded;\nbegin\n  if not Loaded then\n    Load;\nend;\n\nfunction TZNativeLibraryLoader.ZLoadLibrary(Location: String): Boolean;\nvar newpath, temp: String; // AB modif\nbegin\n  if FLoaded then\n    Self.FreeNativeLibrary;\n  temp := ''; //init for FPC\n  FLoaded := False;\n  Result := False;\n  newpath := ExtractFilePath(Location);\n  // AB modif BEGIN\n  try\n   if newpath <> '' then begin\n     temp := GetCurrentDir;\n     SetCurrentDir(newpath);\n   end;\n  // AB modif END\n\n{$IFDEF UNIX}\n  {$IFDEF FPC}\n    FHandle := LoadLibrary(PAnsiChar(Location));\n  {$ELSE}\n    FHandle := HMODULE(dlopen(PAnsiChar(Location), RTLD_GLOBAL));\n  {$ENDIF}\n{$ELSE}\n  FHandle := LoadLibrary(PChar(Location));\n{$ENDIF}\n\n  // AB modif BEGIN\n  finally\n   if temp<>'' then\n     SetCurrentDir(temp);\n  end;\n  // AB modif END\n  if (FHandle <> INVALID_HANDLE_VALUE) and (FHandle <> 0) then\n  begin\n    FLoaded := True;\n    FCurrentLocation := Location;\n    Result := True;\n  end;\nend;\n{**\n  Loads a library module and initializes the handle.\n  @return <code>True</code> is library was successfully loaded.\n}\nfunction TZNativeLibraryLoader.LoadNativeLibrary: Boolean;\nvar\n  I: Integer;\n  TriedLocations: string;\nbegin\n  TriedLocations := '';\n  for I := 0 to High(FLocations) do\n    begin\n      if ZLoadLibrary(FLocations[I]) then\n        Break\n      else\n        if TriedLocations <> '' then\n          TriedLocations := TriedLocations + ', ' + FLocations[I]\n        else\n          TriedLocations := FLocations[I];\n    end;\n\n  if not Loaded then\n    if (Length(FLocations) > 0) and FileExists(FLocations[High(FLocations)]) then\n      raise Exception.Create(Format(SLibraryNotCompatible, [TriedLocations]))\n    else\n      raise Exception.Create(Format(SLibraryNotFound, [TriedLocations]));\n  Result := True;\nend;\n\nfunction TZNativeLibraryLoader.LoadNativeLibraryStrict(Location: String): Boolean;\nbegin\n  If not ZLoadLibrary(Location) then\n    if FileExists(Location) then\n      raise Exception.Create(Format(SLibraryNotCompatible, [Location]))\n    else\n      raise Exception.Create(Format(SLibraryNotFound, [Location]));\n  Result := True;\nend;\n\n{**\n  Frees a previously loaded library.\n}\nprocedure TZNativeLibraryLoader.FreeNativeLibrary;\nbegin\n  if (FHandle <> INVALID_HANDLE_VALUE) and (FHandle <> 0) and Loaded then\n    FreeLibrary(Handle);\n  FHandle := INVALID_HANDLE_VALUE;\n  FLoaded := False;\n  FCurrentLocation := '';\nend;\n\n{**\n  Gets a procedure address from the loaded library by its name.\n  @param ProcName a name of the procedure.\n  @return a procedure address.\n}\nfunction TZNativeLibraryLoader.GetAddress(ProcName: PAnsiChar): Pointer;\nbegin\n  Result := GetProcAddress(Handle, ProcName);\nend;\n\nend.\n\n\n\n"
  },
  {
    "path": "lib/zeosdbo/src/plain/ZPlainMySqlConstants.pas",
    "content": "{*********************************************************}\n{                                                         }\n{                 Zeos Database Objects                   }\n{        Delphi plain interface to libmysql.dll           }\n{                     Version 4.1                         }\n{                                                         }\n{        Originally written by Sergey Seroukhov           }\n{                                                         }\n{    Thanks to :                                          }\n{               Pascal Data Objects Library               }\n{                                                         }\n{    Copyright (c) 2006 John Marino, www.synsport.com     }\n{                                                         }\n{*********************************************************}\n\n{@********************************************************}\n{    Copyright (c) 1999-2012 Zeos Development Group       }\n{                                                         }\n{ License Agreement:                                      }\n{                                                         }\n{ This library is distributed in the hope that it will be }\n{ useful, but WITHOUT ANY WARRANTY; without even the      }\n{ implied warranty of MERCHANTABILITY or FITNESS FOR      }\n{ A PARTICULAR PURPOSE.  See the GNU Lesser General       }\n{ Public License for more details.                        }\n{                                                         }\n{ The source code of the ZEOS Libraries and packages are  }\n{ distributed under the Library GNU General Public        }\n{ License (see the file COPYING / COPYING.ZEOS)           }\n{ with the following  modification:                       }\n{ As a special exception, the copyright holders of this   }\n{ library give you permission to link this library with   }\n{ independent modules to produce an executable,           }\n{ regardless of the license terms of these independent    }\n{ modules, and to copy and distribute the resulting       }\n{ executable under terms of your choice, provided that    }\n{ you also meet, for each linked independent module,      }\n{ the terms and conditions of the license of that module. }\n{ An independent module is a module which is not derived  }\n{ from or based on this library. If you modify this       }\n{ library, you may extend this exception to your version  }\n{ of the library, but you are not obligated to do so.     }\n{ If you do not wish to do so, delete this exception      }\n{ statement from your version.                            }\n{                                                         }\n{                                                         }\n{ The project web site is located on:                     }\n{   http://zeos.firmos.at  (FORUM)                        }\n{   http://sourceforge.net/p/zeoslib/tickets/ (BUGTRACKER)}\n{   svn://svn.code.sf.net/p/zeoslib/code-0/trunk (SVN)    }\n{                                                         }\n{   http://www.sourceforge.net/projects/zeoslib.          }\n{                                                         }\n{                                                         }\n{                                 Zeos Development Group. }\n{********************************************************@}\n\nunit ZPlainMySqlConstants;\n\ninterface\n\n{$I ZPlain.inc}\n\nuses\n   ZCompatibility;\n\nconst\n{ General Declarations }\n  MYSQL_ERRMSG_SIZE    = 512;\n  SQLSTATE_LENGTH      = 5;\n\n  MYSQL_PORT           = 3306;\n  LOCAL_HOST           = 'localhost';\n\n{ Enum Field Types }\n{  FIELD_TYPE_DECIMAL   = 0;\n  FIELD_TYPE_TINY      = 1;\n  FIELD_TYPE_SHORT     = 2;\n  FIELD_TYPE_LONG      = 3;\n  FIELD_TYPE_FLOAT     = 4;\n  FIELD_TYPE_DOUBLE    = 5;\n  FIELD_TYPE_NULL      = 6;\n  FIELD_TYPE_TIMESTAMP = 7;\n  FIELD_TYPE_LONGLONG  = 8;\n  FIELD_TYPE_INT24     = 9;\n  FIELD_TYPE_DATE      = 10;\n  FIELD_TYPE_TIME      = 11;\n  FIELD_TYPE_DATETIME  = 12;\n  FIELD_TYPE_YEAR      = 13;\n  FIELD_TYPE_NEWDATE   = 14;\n  FIELD_TYPE_VARCHAR   = 15; //<--ADDED by fduenas 20-06-2006\n  FIELD_TYPE_BIT       = 16; //<--ADDED by fduenas 20-06-2006\n  FIELD_TYPE_NEWDECIMAL = 246; //<--ADDED by fduenas 20-06-2006\n  FIELD_TYPE_ENUM      = 247;\n  FIELD_TYPE_SET       = 248;\n  FIELD_TYPE_TINY_BLOB = 249;\n  FIELD_TYPE_MEDIUM_BLOB = 250;\n  FIELD_TYPE_LONG_BLOB = 251;\n  FIELD_TYPE_BLOB      = 252;\n  FIELD_TYPE_VAR_STRING = 253;\n  FIELD_TYPE_STRING    = 254;\n  FIELD_TYPE_GEOMETRY  = 255; }\n{ For Compatibility }\n{  FIELD_TYPE_CHAR      = FIELD_TYPE_TINY;\n  FIELD_TYPE_INTERVAL  = FIELD_TYPE_ENUM; }\n\n  { Field's flags }\n  NOT_NULL_FLAG          = 1;     { Field can't be NULL }\n  PRI_KEY_FLAG           = 2;     { Field is part of a primary key }\n  UNIQUE_KEY_FLAG        = 4;     { Field is part of a unique key }\n  MULTIPLE_KEY_FLAG      = 8;     { Field is part of a key }\n  BLOB_FLAG              = 16;    { Field is a blob }\n  UNSIGNED_FLAG          = 32;    { Field is unsigned }\n  ZEROFILL_FLAG          = 64;    { Field is zerofill }\n  BINARY_FLAG            = 128;   { Field is binary }\n  ENUM_FLAG              = 256;   { Field is an enum }\n  AUTO_INCREMENT_FLAG    = 512;   { Field is a autoincrement field }\n  TIMESTAMP_FLAG         = 1024;  { Field is a timestamp }\n  SET_FLAG               = 2048;  { Field is a set }\n  NUM_FLAG               = 32768; { Field is num (for clients) }\n  PART_KEY_FLAG\t         = 16384; { Intern; Part of some key }\n  GROUP_FLAG\t           = 32768; { Intern: Group field }\n  UNIQUE_FLAG            = 65536; { Intern: Used by sql_yacc }\n  BINCMP_FLAG            = $20000; { Intern: Used by sql_yacc }\n  GET_FIXED_FIELDS_FLAG  = $40000; { Used to get fields in item tree }\n  FIELD_IN_PART_FUNC_FLAG= $80000; { Field part of partition func }\n  FIELD_IN_ADD_INDEX     = $100000; { Intern: Field used in ADD INDEX }\n  FIELD_IS_RENAMED       = $200000; { Intern: Field is being renamed}\n\n{ Client Connection Options }\n  _CLIENT_LONG_PASSWORD\t  = 1;\t  { new more secure passwords }\n  _CLIENT_FOUND_ROWS\t  = 2;\t  { Found instead of affected rows }\n  _CLIENT_LONG_FLAG\t  = 4;\t  { Get all column flags }\n  _CLIENT_CONNECT_WITH_DB = 8;\t  { One can specify db on connect }\n  _CLIENT_NO_SCHEMA\t  = 16;\t  { Don't allow database.table.column }\n  _CLIENT_COMPRESS\t  = 32;\t  { Can use compression protcol }\n  _CLIENT_ODBC\t\t  = 64;\t  { Odbc client }\n  _CLIENT_LOCAL_FILES\t  = 128;  { Can use LOAD DATA LOCAL }\n  _CLIENT_IGNORE_SPACE\t  = 256;  { Ignore spaces before '(' }\n  _CLIENT_CHANGE_USER     = 512;  { Support the mysql_change_user() }\n  _CLIENT_INTERACTIVE     = 1024; { This is an interactive client }\n  _CLIENT_SSL             = 2048; { Switch to SSL after handshake }\n  _CLIENT_IGNORE_SIGPIPE  = 4096; { IGNORE sigpipes }\n  _CLIENT_TRANSACTIONS    = 8196; { Client knows about transactions }\n  _CLIENT_RESERVED        = 16384; { Old flag for 4.1 protocol  }\n  _CLIENT_SECURE_CONNECTION = 32768; { New 4.1 authentication }\n  _CLIENT_MULTI_STATEMENTS = 65536; { Enable/disable multi-stmt support }\n  _CLIENT_MULTI_RESULTS   = 131072; { Enable/disable multi-results }\n  _CLIENT_PS_MULTI_RESULTS = 262144; { Enable Multi-results in PS-protocol }\n  _CLIENT_PLUGIN_AUTH      = 524288;\n  _CLIENT_SSL_VERIFY_SERVER_CERT = 1073741824;\n  _CLIENT_REMEMBER_OPTIONS = 2147483648; {Enable/disable multi-results }\n\n{THD: Killable}\n  MYSQL_SHUTDOWN_KILLABLE_CONNECT    = 1;\n  MYSQL_SHUTDOWN_KILLABLE_TRANS      = 2;\n  MYSQL_SHUTDOWN_KILLABLE_LOCK_TABLE = 4;\n  MYSQL_SHUTDOWN_KILLABLE_UPDATE     = 8;\n\n{prepared fetch results}\n  STMT_FETCH_OK         = 0;\n  STMT_FETCH_ERROR      = 1;\n  STMT_FETCH_NO_DATA    = 100;\n  STMT_FETCH_DATA_TRUNC = 101;\n\n  {status codes}\nconst\n   MYSQL_NO_DATA = 100;\n   MYSQL_DATA_TRUNCATED  = 101;\n\ntype\n  TMySqlOption = (\n  MYSQL_OPT_CONNECT_TIMEOUT, MYSQL_OPT_COMPRESS, MYSQL_OPT_NAMED_PIPE,\n    MYSQL_INIT_COMMAND, MYSQL_READ_DEFAULT_FILE, MYSQL_READ_DEFAULT_GROUP,\n    MYSQL_SET_CHARSET_DIR, MYSQL_SET_CHARSET_NAME, MYSQL_OPT_LOCAL_INFILE,\n    MYSQL_OPT_PROTOCOL, MYSQL_SHARED_MEMORY_BASE_NAME, MYSQL_OPT_READ_TIMEOUT,\n    MYSQL_OPT_WRITE_TIMEOUT, MYSQL_OPT_USE_RESULT,\n    MYSQL_OPT_USE_REMOTE_CONNECTION, MYSQL_OPT_USE_EMBEDDED_CONNECTION,\n    MYSQL_OPT_GUESS_CONNECTION, MYSQL_SET_CLIENT_IP, MYSQL_SECURE_AUTH,\n    MYSQL_REPORT_DATA_TRUNCATION, MYSQL_OPT_RECONNECT,\n    MYSQL_OPT_SSL_VERIFY_SERVER_CERT, MYSQL_PLUGIN_DIR, MYSQL_DEFAULT_AUTH,\n    MYSQL_OPT_BIND,\n    MYSQL_OPT_SSL_KEY, MYSQL_OPT_SSL_CERT,\n    MYSQL_OPT_SSL_CA, MYSQL_OPT_SSL_CAPATH, MYSQL_OPT_SSL_CIPHER,\n    MYSQL_OPT_SSL_CRL, MYSQL_OPT_SSL_CRLPATH,\n    MYSQL_OPT_CONNECT_ATTR_RESET, MYSQL_OPT_CONNECT_ATTR_ADD,\n    MYSQL_OPT_CONNECT_ATTR_DELETE,\n    MYSQL_SERVER_PUBLIC_KEY,\n    MYSQL_ENABLE_CLEARTEXT_PLUGIN,\n    MYSQL_OPT_CAN_HANDLE_EXPIRED_PASSWORDS,\n    MYSQL_OPT_SSL_ENFORCE\n  );\nconst\n  TMySqlOptionMinimumVersion: array[TMySqlOption] of Integer =\n    (\n      {MYSQL_OPT_CONNECT_TIMEOUT}               0,\n      {MYSQL_OPT_COMPRESS}                      0,\n      {MYSQL_OPT_NAMED_PIPE}                    0,\n      {MYSQL_INIT_COMMAND}                      0,\n      {MYSQL_READ_DEFAULT_FILE}                 0,\n      {MYSQL_READ_DEFAULT_GROUP}                0,\n      {MYSQL_SET_CHARSET_DIR}                   0,\n      {MYSQL_SET_CHARSET_NAME}                  0,\n      {MYSQL_OPT_LOCAL_INFILE}                  0,\n      {MYSQL_OPT_PROTOCOL}                      40100,\n      {MYSQL_SHARED_MEMORY_BASE_NAME}           40100,\n      {MYSQL_OPT_READ_TIMEOUT}                  40101,\n      {MYSQL_OPT_WRITE_TIMEOUT}                 40101,\n      {MYSQL_OPT_USE_RESULT}                    40101,\n      {MYSQL_OPT_USE_REMOTE_CONNECTION}         40101,\n      {MYSQL_OPT_USE_EMBEDDED_CONNECTION}       40101,\n      {MYSQL_OPT_GUESS_CONNECTION}              40101,\n      {MYSQL_SET_CLIENT_IP}                     40101,\n      {MYSQL_SECURE_AUTH}                       40101,\n      {MYSQL_REPORT_DATA_TRUNCATION}            40101,\n      {MYSQL_OPT_RECONNECT}                     50013,\n      {MYSQL_OPT_SSL_VERIFY_SERVER_CERT}        50023,\n      {MYSQL_PLUGIN_DIR}                        50507,\n      {MYSQL_DEFAULT_AUTH}                      50507,\n      {MYSQL_OPT_BIND}                          50601,\n      {MYSQL_OPT_SSL_KEY}                       50603,\n      {MYSQL_OPT_SSL_CERT}                      50603,\n      {MYSQL_OPT_SSL_CA}                        50603,\n      {MYSQL_OPT_SSL_CAPATH}                    50603,\n      {MYSQL_OPT_SSL_CIPHER}                    50603,\n      {MYSQL_OPT_SSL_CRL}                       50603,\n      {MYSQL_OPT_SSL_CRLPATH}                   50603,\n      {MYSQL_OPT_CONNECT_ATTR_RESET}            50606,\n      {MYSQL_OPT_CONNECT_ATTR_ADD}              50606,\n      {MYSQL_OPT_CONNECT_ATTR_DELETE}           50606,\n      {MYSQL_SERVER_PUBLIC_KEY}                 50606,\n      {MYSQL_ENABLE_CLEARTEXT_PLUGIN}           50607,\n      {MYSQL_OPT_CAN_HANDLE_EXPIRED_PASSWORDS}  50610,\n      {MYSQL_OPT_SSL_ENFORCE}                   50703\n    );\ntype\n  PUSED_MEM=^USED_MEM;\n  USED_MEM = packed record\n    next:       PUSED_MEM;\n    left:       Integer;\n    size:       Integer;\n  end;\n\n  PERR_PROC = ^ERR_PROC;\n  ERR_PROC = procedure;\n\n  PMEM_ROOT = ^MEM_ROOT;\n  MEM_ROOT = packed record\n    free:          PUSED_MEM;\n    used:          PUSED_MEM;\n    pre_alloc:     PUSED_MEM;\n    min_malloc:    Integer;\n    block_size:    Integer;\n    block_num:     Integer;\n    first_block_usage: Integer;\n    error_handler: PERR_PROC;\n  end;\n\n  MYSQL_ROW = array[00..$ff] of PAnsiChar;\n  PMYSQL_ROW = ^MYSQL_ROW;\n\n  PMYSQL_ROWS = ^MYSQL_ROWS;\n  MYSQL_ROWS = record\n    next:       PMYSQL_ROWS;\n    data:       PMYSQL_ROW;\n  end;\n\n  MYSQL_ROW_OFFSET = PMYSQL_ROWS;\n\n  MYSQL_DATA = record\n    Rows:       Int64;\n    Fields:     Cardinal;\n    Data:       PMYSQL_ROWS;\n    Alloc:      MEM_ROOT;\n  end;\n  PMYSQL_DATA = ^MYSQL_DATA;\n\n  MYSQL_FIELD_OFFSET = UInt;\n\n  PMYSQL_OPTIONS   = ^_MYSQL_OPTIONS;\n  _MYSQL_OPTIONS = record\n    connect_timeout:          UInt;\n    read_timeout:             UInt;\n    write_timeout:            UInt;\n    port:                     UInt;\n    protocol:                 UInt;\n    client_flag:              ULong;\n    host:                     PAnsiChar;\n    user:                     PAnsiChar;\n    password:                 PAnsiChar;\n    unix_socket:              PAnsiChar;\n    db:                       PAnsiChar;\n    init_commands:            Pointer;\n    my_cnf_file:              PAnsiChar;\n    my_cnf_group:             PAnsiChar;\n    charset_dir:              PAnsiChar;\n    charset_name:             PAnsiChar;\n    ssl_key:                  PAnsiChar;\n    ssl_cert:                 PAnsiChar;\n    ssl_ca:                   PAnsiChar;\n    ssl_capath:               PAnsiChar;\n    ssl_cipher:               PAnsiChar;\n    shared_memory_base_name:  PAnsiChar;\n    max_allowed_packet:       ULong;\n    use_ssl:                  Byte;\n    compress:                 Byte;\n    named_pipe:               Byte;\n    unused1:                  Byte;\n    unused2:                  Byte;\n    unused3:                  Byte;\n    unused4:                  Byte;\n    methods_to_use:           TMySqlOption;\n    client_ip:                PAnsiChar;\n    secure_auth:              Byte;\n    local_infile_init:        Pointer;\n    local_infile_read:        Pointer;\n    local_infile_end:         Pointer;\n    local_infile_error:       Pointer;\n    local_infile_userdata:    Pointer;\n  end;\n\n    PZMySQLConnect = Pointer;\n    PZMySQLResult = Pointer;\n    PZMySQLRow = Pointer;\n    PZMySQLField = Pointer;\n    PZMySQLRowOffset = Pointer;\n    PZMySqlPrepStmt = Pointer;\n    PZMysqlBindArray = Pointer;\n\n{ Enum Field Types }\n      TMysqlFieldTypes = (\n  FIELD_TYPE_DECIMAL   = 0,\n  FIELD_TYPE_TINY      = 1,\n  FIELD_TYPE_SHORT     = 2,\n  FIELD_TYPE_LONG      = 3,\n  FIELD_TYPE_FLOAT     = 4,\n  FIELD_TYPE_DOUBLE    = 5,\n  FIELD_TYPE_NULL      = 6,\n  FIELD_TYPE_TIMESTAMP = 7,\n  FIELD_TYPE_LONGLONG  = 8,\n  FIELD_TYPE_INT24     = 9,\n  FIELD_TYPE_DATE      = 10,\n  FIELD_TYPE_TIME      = 11,\n  FIELD_TYPE_DATETIME  = 12,\n  FIELD_TYPE_YEAR      = 13,\n  FIELD_TYPE_NEWDATE   = 14,\n  FIELD_TYPE_VARCHAR   = 15, //<--ADDED by fduenas 20-06-2006\n  FIELD_TYPE_BIT       = 16, //<--ADDED by fduenas 20-06-2006\n  FIELD_TYPE_NEWDECIMAL = 246, //<--ADDED by fduenas 20-06-2006\n  FIELD_TYPE_ENUM      = 247,\n  FIELD_TYPE_SET       = 248,\n  FIELD_TYPE_TINY_BLOB = 249,\n  FIELD_TYPE_MEDIUM_BLOB = 250,\n  FIELD_TYPE_LONG_BLOB = 251,\n  FIELD_TYPE_BLOB      = 252,\n  FIELD_TYPE_VAR_STRING = 253,\n  FIELD_TYPE_STRING    = 254,\n  FIELD_TYPE_GEOMETRY  = 255\n    );\n  PTMysqlFieldTypes=^TMysqlFieldTypes;\n  { Options for mysql_set_option }\n  TMySqlSetOption = (\n    MYSQL_OPTION_MULTI_STATEMENTS_ON,\n    MYSQL_OPTION_MULTI_STATEMENTS_OFF\n  );\n\n  TMysqlStmtAttrType = (\n    STMT_ATTR_UPDATE_MAX_LENGTH,\n    STMT_ATTR_CURSOR_TYPE,\n    STMT_ATTR_PREFETCH_ROWS\n  );\n\n  TMysqlShutdownLevel = (\n    SHUTDOWN_DEFAULT = 0,\n    SHUTDOWN_WAIT_CONNECTIONS = MYSQL_SHUTDOWN_KILLABLE_CONNECT,\n    SHUTDOWN_WAIT_TRANSACTIONS = MYSQL_SHUTDOWN_KILLABLE_TRANS,\n    SHUTDOWN_WAIT_UPDATES = MYSQL_SHUTDOWN_KILLABLE_UPDATE,\n    SHUTDOWN_WAIT_ALL_BUFFERS = (MYSQL_SHUTDOWN_KILLABLE_UPDATE shl 1),\n    SHUTDOWN_WAIT_CRITICAL_BUFFERS,\n    KILL_QUERY = 254,\n    KILL_CONNECTION = 255\n  );\n\nTMYSQL_CLIENT_OPTIONS =\n( CLIENT_LONG_PASSWORD,\t{  = 1;\t   new more secure passwords }\n  CLIENT_FOUND_ROWS ,\t{\t  = 2;\t   Found instead of affected rows }\n  CLIENT_LONG_FLAG\t ,\t{ = 4;\t   Get all column flags }\n  CLIENT_CONNECT_WITH_DB ,\t{ = 8;\t   One can specify db on connect }\n  CLIENT_NO_SCHEMA\t ,\t{  = 16;\t   Don't allow database.table.column }\n  CLIENT_COMPRESS\t ,\t{  = 32;\t   Can use compression protcol }\n  CLIENT_ODBC\t\t ,\t{  = 64;\t   Odbc client }\n  CLIENT_LOCAL_FILES\t  ,\t{ = 128;   Can use LOAD DATA LOCAL }\n  CLIENT_IGNORE_SPACE\t ,\t{  = 256;   Ignore spaces before '(' }\n  CLIENT_CHANGE_USER    ,\t{  = 512;   Support the mysql_change_user() }\n  CLIENT_INTERACTIVE    ,\t{  = 1024;  This is an interactive client }\n  CLIENT_SSL     ,\t{         = 2048;  Switch to SSL after handshake }\n  CLIENT_IGNORE_SIGPIPE  ,\t{ = 4096;  IGNORE sigpipes }\n  CLIENT_TRANSACTIONS    ,\t{ = 8196;  Client knows about transactions }\n  CLIENT_RESERVED     ,\t{    = 16384;  Old flag for 4.1 protocol  }\n  CLIENT_SECURE_CONNECTION  ,\t{= 32768;  New 4.1 authentication }\n  CLIENT_MULTI_STATEMENTS  ,\t{= 65536;  Enable/disable multi-stmt support }\n  CLIENT_MULTI_RESULTS  ,\t{  = 131072;  Enable/disable multi-results }\n  CLIENT_PS_MULTI_RESULTS,  {2^18 = 262144; Enable Multi-results in PS-protocol}\n  CLIENT_PLUGIN_AUTH,{2^19 = 524288}\n  CLIENT_OPT_20,  {2^20 = 1048576}\n  CLIENT_OPT_21,   {2^21 = 2097152 }\n  CLIENT_OPT_22,  {2^22 = 4194304}\n  CLIENT_OPT_23,  {2^23 = 8388608 }\n  CLIENT_OPT_24,   {2^24 = 16777216 }\n  CLIENT_OPT_25,   {2^25 = 33554432}\n  CLIENT_OPT_26,    {2^26 = 67108864}\n  CLIENT_OPT_27,    {2^27 = 134217728}\n  CLIENT_OPT_28,    {2^28 = 268435456}\n  CLIENT_OPT_29,    {2^29 = 536870912}\n  CLIENT_SSL_VERIFY_SERVER_CERT,    {2^30 = 1073741824}\n  CLIENT_REMEMBER_OPTIONS\t{ = 2147483648; Enable/disable multi-results });\n\n  TMysqlStmtState = (\n    MYSQL_STMT_INIT_DONE = 1,\n    MYSQL_STMT_PREPARE_DONE,\n    MYSQL_STMT_EXECUTE_DONE,\n    MYSQL_STMT_FETCH_DONE\n  );\n\n  mysql_timestamp_type = (\n    MYSQL_TIMESTAMP_NONE = -2,\n    MYSQL_TIMESTAMP_ERROR = -1,\n    MYSQL_TIMESTAMP_DATE = 0,\n    MYSQL_TIMESTAMP_DATETIME = 1,\n    MYSQL_TIMESTAMP_TIME = 2\n  );\n\n  MYSQL_TIME = record\n    year:                UInt;\n    month:               UInt;\n    day:                 UInt;\n    hour:                UInt;\n    minute:              UInt;\n    second:              UInt;\n    second_part:         ULong;\n    neg:                 Byte;\n    time_type:           mysql_timestamp_type;\n    padding:             UInt;    //ludob alignment is different? Mysql returns 36 bytes.\n  end;\n  PMYSQL_TIME = ^MYSQL_TIME;\n\n  PLIST = ^LIST;\n  LIST = record\n    prev:       PLIST;\n    next:       PLIST;\n    data:       Pointer;\n  end;\n\n  PMYSQL_FIELD = ^MYSQL_FIELD;\n  MYSQL_FIELD = record\n    name:             PAnsiChar;   // Name of column\n    org_name:         PAnsiChar;   // Original column name, if an alias\n    table:            PAnsiChar;   // Table of column if column was a field\n    org_table:        PAnsiChar;   // Org table name if table was an alias\n    db:               PAnsiChar;   // Database for table\n    catalog:\t        PAnsiChar;   // Catalog for table\n    def:              PAnsiChar;   // Default value (set by mysql_list_fields)\n    length:           ULong; // Width of column\n    max_length:       ULong; // Max width of selected set\n    name_length:      UInt;\n    org_name_length:  UInt;\n    table_length:     UInt;\n    org_table_length: UInt;\n    db_length:        UInt;\n    catalog_length:   UInt;\n    def_length:       UInt;\n    flags:            UInt; // Div flags\n    decimals:         UInt; // Number of decimals in field\n    charsetnr:        UInt; // Character set\n    _type:            TMysqlFieldTypes; // Type of field. Se mysql_com.h for types\n  end;\n\n  PMYSQL_BIND41 = ^MYSQL_BIND41;\n  MYSQL_BIND41 =  record\n    // 4.1.22 definition\n    length:           PULong;\n    is_null:          PByte;\n    buffer:           PAnsiChar;\n    buffer_type:      TMysqlFieldTypes;\n    buffer_length:    ULong;\n    //internal fields\n    inter_buffer:     PByte;\n    offset:           ULong;\n    internal_length:  ULong;\n    param_number:     UInt;\n    pack_length:      UInt;\n    is_unsigned:      Byte;\n    long_data_used:   Byte;\n    internal_is_null: Byte;\n    store_param_func: Pointer;\n    fetch_result:     Pointer;\n    skip_result:      Pointer;\n  end;\n\n  PMYSQL_BIND50 = ^MYSQL_BIND50;\n  MYSQL_BIND50 =  record\n    // 5.0.67 definition\n    length:            PULong;\n    is_null:           PByte;\n    buffer:            PAnsiChar;\n    error:             PByte;\n    buffer_type:       TMysqlFieldTypes;\n    buffer_length:     ULong;\n    row_ptr:           PByte;\n    offset:            ULong;\n    length_value:      ULong;\n    param_number:      UInt;\n    pack_length:       UInt;\n    error_value:       Byte;\n    is_unsigned:       Byte;\n    long_data_used:    Byte;\n    is_null_value:     Byte;\n    store_param_funct: Pointer;\n    fetch_result:      Pointer;\n    skip_result:       Pointer;\n  end;\n\n  PMYSQL_BIND51 = ^MYSQL_BIND51;\n  MYSQL_BIND51 =  record\n    // 5.1.30 definition (Still valid for 5.6.25)\n    length:            PULong;\n    is_null:           PByte;\n    buffer:            PAnsiChar;\n    error:             PByte;\n    row_ptr:           PByte;\n    store_param_funct: Pointer;\n    fetch_result:      Pointer;\n    skip_result:       Pointer;\n    buffer_length:     ULong;\n    offset:            ULong;\n    length_value:      ULong;\n    param_number:      UInt;\n    pack_length:       UInt;\n    buffer_type:       TMysqlFieldTypes;\n    error_value:       Byte;\n    is_unsigned:       Byte;\n    long_data_used:    Byte;\n    is_null_value:     Byte;\n    extension:         Pointer;\n  end;\n\n  PMYSQL_BIND60 = ^MYSQL_BIND60;\n  MYSQL_BIND60 =  record\n    // 6.0.8 definition\n    length:            PULong;\n    is_null:           PByte;\n    buffer:            PAnsiChar;\n    error:             PByte;\n    row_ptr:           PByte;\n    store_param_funct: Pointer;\n    fetch_result:      Pointer;\n    skip_result:       Pointer;\n    buffer_length:     ULong;\n    offset:            ULong;\n    length_value:      ULong;\n    param_number:      UInt;\n    pack_length:       UInt;\n    buffer_type:       TMysqlFieldTypes;\n    error_value:       Byte;\n    is_unsigned:       Byte;\n    long_data_used:    Byte;\n    is_null_value:     Byte;\n    extension:         Pointer;\n  end;\n\n  // offsets to used MYSQL_BINDxx members. Filled by GetBindOffsets\n  MYSQL_BINDOFFSETS=record\n    buffer_type   :NativeUint;\n    buffer_length :NativeUint;\n    is_unsigned   :NativeUint;\n    buffer        :NativeUint;\n    length        :NativeUint;\n    is_null       :NativeUint;\n    size          :integer;    //size of MYSQL_BINDxx\n    end;\n\n\n  PDOBindRecord2 = record\n      buffer:    Array of Byte;\n      length:    ULong;\n      is_null:   Byte;\n  end;\n\n  PMYSQL = ^MYSQL;\n\n  MYSQL  = pointer;\n\n  PMY_CHARSET_INFO = ^MY_CHARSET_INFO;\n  MY_CHARSET_INFO = record\n    number:         UInt;\n    state:          UInt;\n    csname:         PAnsiChar;\n    name:           PAnsiChar;\n    comment:        PAnsiChar;\n    dir:            PAnsiChar;\n    mbminlen:       UInt;\n    mbmaxlen:       UInt;\n  end;\n  // Structure of the MYSQL_RES record isn't used anymore.\n  // Access to the fields should be done using library functions\n  // Reason : the structure of these records tend to change now and then.\n  PMYSQL_RES = Pointer;\n\n  PREP_STMT_STATE=(\n    MY_ST_UNKNOWN,\n    MY_ST_PREPARE,\n    MY_ST_EXECUTE);\n\n  PMYSQL_STMT = Pointer;\n\n{ ****************** Plain API Types definition ***************** }\n\ntype\n\n{ ************** Plain API Function types definition ************* }\n\n  { Functions to get information from the MYSQL and MYSQL_RES structures\n    Should definitely be used if one uses shared libraries. }\n  Tmysql_affected_rows          = function(Handle: PMYSQL): ULongLong;                                     {$IFDEF MSWINDOWS} stdcall {$ELSE} cdecl {$ENDIF};\n  Tmysql_character_set_name     = function(Handle: PMYSQL): PAnsiChar;                                     {$IFDEF MSWINDOWS} stdcall {$ELSE} cdecl {$ENDIF};\n  Tmysql_close                  = procedure(Handle: PMYSQL);                                           {$IFDEF MSWINDOWS} stdcall {$ELSE} cdecl {$ENDIF};\n  Tmysql_connect                = function(Handle: PMYSQL; const Host, User, Passwd: PAnsiChar): PMYSQL;   {$IFDEF MSWINDOWS} stdcall {$ELSE} cdecl {$ENDIF};\n  Tmysql_create_db              = function(Handle: PMYSQL; const Db: PAnsiChar): Integer;                  {$IFDEF MSWINDOWS} stdcall {$ELSE} cdecl {$ENDIF};\n  Tmysql_data_seek              = procedure(Result: PMYSQL_RES; Offset: ULongLong);                        {$IFDEF MSWINDOWS} stdcall {$ELSE} cdecl {$ENDIF};\n  Tmysql_debug                  = procedure(Debug: PAnsiChar);                                             {$IFDEF MSWINDOWS} stdcall {$ELSE} cdecl {$ENDIF};\n  Tmysql_drop_db                = function(Handle: PMYSQL; const Db: PAnsiChar): Integer;                  {$IFDEF MSWINDOWS} stdcall {$ELSE} cdecl {$ENDIF};\n  Tmysql_dump_debug_info        = function(Handle: PMYSQL): Integer;                                   {$IFDEF MSWINDOWS} stdcall {$ELSE} cdecl {$ENDIF};\n  Tmysql_eof                    = function(Result: PMYSQL_RES): Byte;                                  {$IFDEF MSWINDOWS} stdcall {$ELSE} cdecl {$ENDIF};\n  Tmysql_errno                  = function(Handle: PMYSQL): UInt;                                  {$IFDEF MSWINDOWS} stdcall {$ELSE} cdecl {$ENDIF};\n  Tmysql_error                  = function(Handle: PMYSQL): PAnsiChar;                                     {$IFDEF MSWINDOWS} stdcall {$ELSE} cdecl {$ENDIF};\n  Tmysql_escape_string          = function(PTo, PFrom: PAnsiChar; Len: ULong): ULong;                {$IFDEF MSWINDOWS} stdcall {$ELSE} cdecl {$ENDIF};\n  Tmysql_fetch_field            = function(Result: PMYSQL_RES): PMYSQL_FIELD;                          {$IFDEF MSWINDOWS} stdcall {$ELSE} cdecl {$ENDIF};\n  Tmysql_fetch_field_direct     = function(Result: PMYSQL_RES; FieldNo: UInt): PMYSQL_FIELD;       {$IFDEF MSWINDOWS} stdcall {$ELSE} cdecl {$ENDIF};\n  Tmysql_fetch_fields           = function(Result: PMYSQL_RES): PMYSQL_FIELD;                          {$IFDEF MSWINDOWS} stdcall {$ELSE} cdecl {$ENDIF};\n  Tmysql_fetch_lengths          = function(Result: PMYSQL_RES): PULong; {$IFDEF MSWINDOWS} stdcall {$ELSE} cdecl {$ENDIF};\n  Tmysql_fetch_row              = function(Result: PMYSQL_RES): PMYSQL_ROW;                            {$IFDEF MSWINDOWS} stdcall {$ELSE} cdecl {$ENDIF};\n  Tmysql_field_seek             = function(Result: PMYSQL_RES; Offset: MYSQL_FIELD_OFFSET): MYSQL_FIELD_OFFSET;\n                                                                                                       {$IFDEF MSWINDOWS} stdcall {$ELSE} cdecl {$ENDIF};\n  Tmysql_field_tell             = function(Result: PMYSQL_RES): MYSQL_FIELD_OFFSET;                    {$IFDEF MSWINDOWS} stdcall {$ELSE} cdecl {$ENDIF};\n  Tmysql_free_result            = procedure(Result: PMYSQL_RES);                                       {$IFDEF MSWINDOWS} stdcall {$ELSE} cdecl {$ENDIF};\n  Tmysql_get_client_info        = function: PAnsiChar;                                                     {$IFDEF MSWINDOWS} stdcall {$ELSE} cdecl {$ENDIF};\n  Tmysql_get_host_info          = function(Handle: PMYSQL): PAnsiChar;                                     {$IFDEF MSWINDOWS} stdcall {$ELSE} cdecl {$ENDIF};\n  Tmysql_get_proto_info         = function(Handle: PMYSQL): UInt;                                  {$IFDEF MSWINDOWS} stdcall {$ELSE} cdecl {$ENDIF};\n  Tmysql_get_server_info        = function(Handle: PMYSQL): PAnsiChar;                                     {$IFDEF MSWINDOWS} stdcall {$ELSE} cdecl {$ENDIF};\n  Tmysql_info                   = function(Handle: PMYSQL): PAnsiChar;                                     {$IFDEF MSWINDOWS} stdcall {$ELSE} cdecl {$ENDIF};\n  Tmysql_init                   = function(Handle: PMYSQL): PMYSQL;                                    {$IFDEF MSWINDOWS} stdcall {$ELSE} cdecl {$ENDIF};\n  Tmysql_insert_id              = function(Handle: PMYSQL): ULongLong;                                     {$IFDEF MSWINDOWS} stdcall {$ELSE} cdecl {$ENDIF};\n  Tmysql_kill                   = function(Handle: PMYSQL; Pid: ULong): Integer;                     {$IFDEF MSWINDOWS} stdcall {$ELSE} cdecl {$ENDIF};\n  Tmysql_list_dbs               = function(Handle: PMYSQL; Wild: PAnsiChar): PMYSQL_RES;                   {$IFDEF MSWINDOWS} stdcall {$ELSE} cdecl {$ENDIF};\n  Tmysql_list_fields            = function(Handle: PMYSQL; const Table, Wild: PAnsiChar): PMYSQL_RES;      {$IFDEF MSWINDOWS} stdcall {$ELSE} cdecl {$ENDIF};\n  Tmysql_list_processes         = function(Handle: PMYSQL): PMYSQL_RES;                                {$IFDEF MSWINDOWS} stdcall {$ELSE} cdecl {$ENDIF};\n  Tmysql_list_tables            = function(Handle: PMYSQL; const Wild: PAnsiChar): PMYSQL_RES;             {$IFDEF MSWINDOWS} stdcall {$ELSE} cdecl {$ENDIF};\n  Tmysql_num_fields             = function(Result: PMYSQL_RES): UInt;                              {$IFDEF MSWINDOWS} stdcall {$ELSE} cdecl {$ENDIF};\n  Tmysql_num_rows               = function(Result: PMYSQL_RES): ULongLong;                                 {$IFDEF MSWINDOWS} stdcall {$ELSE} cdecl {$ENDIF};\n  Tmysql_options                = function(Handle: PMYSQL; Option: TMySqlOption; const Arg: PAnsiChar): Integer;\n                                                                                                       {$IFDEF MSWINDOWS} stdcall {$ELSE} cdecl {$ENDIF};\n  Tmysql_ping                   = function(Handle: PMYSQL): Integer;                                   {$IFDEF MSWINDOWS} stdcall {$ELSE} cdecl {$ENDIF};\n  Tmysql_query                  = function(Handle: PMYSQL; const Query: PAnsiChar): Integer;               {$IFDEF MSWINDOWS} stdcall {$ELSE} cdecl {$ENDIF};\n  Tmysql_real_connect           = function(Handle: PMYSQL; const Host, User, Passwd, Db: PAnsiChar;\n                                           Port: UInt; const UnixSocket: PAnsiChar; ClientFlag: ULong): PMYSQL;\n                                                                                                       {$IFDEF MSWINDOWS} stdcall {$ELSE} cdecl {$ENDIF};\n  Tmysql_real_escape_string     = function(Handle: PMYSQL; PTo: PAnsiChar; const PFrom: PAnsiChar; length: ULong): ULong;\n                                                                                                       {$IFDEF MSWINDOWS} stdcall {$ELSE} cdecl {$ENDIF};\n  Tmysql_real_query             = function(Handle: PMYSQL; const Query: PAnsiChar; Length: ULong): Integer;\n                                                                                                       {$IFDEF MSWINDOWS} stdcall {$ELSE} cdecl {$ENDIF};\n  Tmysql_refresh                = function(Handle: PMYSQL; Options: UInt): Integer;                {$IFDEF MSWINDOWS} stdcall {$ELSE} cdecl {$ENDIF};\n  Tmysql_row_seek               = function(Result: PMYSQL_RES; Offset: PMYSQL_ROWS): PMYSQL_ROWS;      {$IFDEF MSWINDOWS} stdcall {$ELSE} cdecl {$ENDIF};\n  Tmysql_row_tell               = function(Result: PMYSQL_RES): PMYSQL_ROWS;                           {$IFDEF MSWINDOWS} stdcall {$ELSE} cdecl {$ENDIF};\n  Tmysql_select_db              = function(Handle: PMYSQL; const Db: PAnsiChar): Integer;                  {$IFDEF MSWINDOWS} stdcall {$ELSE} cdecl {$ENDIF};\n  Tmysql_ssl_set                = function(Handle: PMYSQL; const key, cert, CA, CApath, cipher:\n                                  PAnsiChar): Byte;                                                        {$IFDEF MSWINDOWS} stdcall {$ELSE} cdecl {$ENDIF};\n  Tmysql_stat                   = function(Handle: PMYSQL): PAnsiChar;                                     {$IFDEF MSWINDOWS} stdcall {$ELSE} cdecl {$ENDIF};\n  Tmysql_store_result           = function(Handle: PMYSQL): PMYSQL_RES;                                {$IFDEF MSWINDOWS} stdcall {$ELSE} cdecl {$ENDIF};\n  Tmysql_thread_id              = function(Handle: PMYSQL): ULong;                                  {$IFDEF MSWINDOWS} stdcall {$ELSE} cdecl {$ENDIF};\n  Tmysql_use_result             = function(Handle: PMYSQL): PMYSQL_RES;                                {$IFDEF MSWINDOWS} stdcall {$ELSE} cdecl {$ENDIF};\n\n  { Set up and bring down a thread; these function should be called for each thread in an application which\n    opens at least one MySQL connection.  All uses of the connection(s) should be between these function calls. }\n  Tmy_init                      = procedure;                                                          {$IFDEF MSWINDOWS} stdcall {$ELSE} cdecl {$ENDIF};\n  Tmysql_thread_init            = function: Byte;                                                     {$IFDEF MSWINDOWS} stdcall {$ELSE} cdecl {$ENDIF};\n  Tmysql_thread_end             = procedure;                                                          {$IFDEF MSWINDOWS} stdcall {$ELSE} cdecl {$ENDIF};\n  Tmysql_thread_safe            = function: UInt;                                                 {$IFDEF MSWINDOWS} stdcall {$ELSE} cdecl {$ENDIF};\n\n  { Set up and bring down the server; to ensure that applications will work when linked against either the\n    standard client library or the embedded server library, these functions should be called. }\n  Tmysql_server_init            = function(Argc: Integer; Argv, Groups: Pointer): Integer;            {$IFDEF MSWINDOWS} stdcall {$ELSE} cdecl {$ENDIF};\n  Tmysql_server_end             = procedure;                                                          {$IFDEF MSWINDOWS} stdcall {$ELSE} cdecl {$ENDIF};\n\n  Tmysql_change_user            = function(mysql: PMYSQL; const user: PAnsiChar; const passwd: PAnsiChar; const db: PAnsiChar): Byte;\n  Tmysql_field_count            = function(Handle: PMYSQL): UInt;                                  {$IFDEF MSWINDOWS} stdcall {$ELSE} cdecl {$ENDIF};\n\n\n  Tmysql_get_client_version     = function: ULong;                                                  {$IFDEF MSWINDOWS} stdcall {$ELSE} cdecl {$ENDIF};\n\n  Tmysql_send_query = function(mysql: PMYSQL; const query: PAnsiChar;\n    length: ULong): Integer;\n    {$IFDEF MSWINDOWS} stdcall {$ELSE} cdecl {$ENDIF};\n\n  Tmysql_read_query_result = function(mysql: PMYSQL): Byte;\n    {$IFDEF MSWINDOWS} stdcall {$ELSE} cdecl {$ENDIF};\n\n\n  Tmysql_autocommit             = function(Handle: PMYSQL; const mode: Byte): Byte;                    {$IFDEF MSWINDOWS} stdcall {$ELSE} cdecl {$ENDIF};\n  Tmysql_commit                 = function(Handle: PMYSQL): Byte;                                      {$IFDEF MSWINDOWS} stdcall {$ELSE} cdecl {$ENDIF};\n  Tmysql_get_server_version     = function(Handle: PMYSQL): ULong;                                  {$IFDEF MSWINDOWS} stdcall {$ELSE} cdecl {$ENDIF};\n  Tmysql_hex_string             = function(PTo, PFrom: PAnsiChar; Len: ULong): ULong;                {$IFDEF MSWINDOWS} stdcall {$ELSE} cdecl {$ENDIF};\n  Tmysql_more_results           = function(Handle: PMYSQL): Byte;                                      {$IFDEF MSWINDOWS} stdcall {$ELSE} cdecl {$ENDIF};\n  Tmysql_next_result            = function(Handle: PMYSQL): Integer;                                   {$IFDEF MSWINDOWS} stdcall {$ELSE} cdecl {$ENDIF};\n  Tmysql_rollback               = function(Handle: PMYSQL): Byte;                                      {$IFDEF MSWINDOWS} stdcall {$ELSE} cdecl {$ENDIF};\n  Tmysql_set_character_set      = function(Handle: PMYSQL; const csname: PAnsiChar): Integer;                    {$IFDEF MSWINDOWS} stdcall {$ELSE} cdecl {$ENDIF};\n  Tmysql_set_server_option      = function(Handle: PMYSQL; Option: TMysqlSetOption): Integer;          {$IFDEF MSWINDOWS} stdcall {$ELSE} cdecl {$ENDIF};\n  Tmysql_shutdown               = function(Handle: PMYSQL; shutdown_level: TMysqlShutdownLevel): Integer; {$IFDEF MSWINDOWS} stdcall {$ELSE} cdecl {$ENDIF};\n  Tmysql_sqlstate               = function(Handle: PMYSQL): PAnsiChar;                                     {$IFDEF MSWINDOWS} stdcall {$ELSE} cdecl {$ENDIF};\n  Tmysql_warning_count          = function(Handle: PMYSQL): UInt;                                  {$IFDEF MSWINDOWS} stdcall {$ELSE} cdecl {$ENDIF};\n{BELOW are new PREPARED STATEMENTS}\n  Tmysql_stmt_affected_rows     = function(stmt: PMYSQL_STMT): ULongLong;                                {$IFDEF MSWINDOWS} stdcall {$ELSE} cdecl {$ENDIF};\n  Tmysql_stmt_attr_get          = function(stmt: PMYSQL_STMT; option: TMysqlStmtAttrType;\n                                  arg: PAnsiChar): Byte;                                              {$IFDEF MSWINDOWS} stdcall {$ELSE} cdecl {$ENDIF};\n  Tmysql_stmt_attr_set          = function(stmt: PMYSQL_STMT; option: TMysqlStmtAttrType;\n                                  const arg: PAnsiChar): Byte;                                        {$IFDEF MSWINDOWS} stdcall {$ELSE} cdecl {$ENDIF};\n  Tmysql_stmt_bind_param        = function(stmt: PMYSQL_STMT; bind: Pointer{BIND record}): Byte;              {$IFDEF MSWINDOWS} stdcall {$ELSE} cdecl {$ENDIF};\n  Tmysql_stmt_bind_result       = function(stmt: PMYSQL_STMT; bind: Pointer{BIND record}): Byte;              {$IFDEF MSWINDOWS} stdcall {$ELSE} cdecl {$ENDIF};\n  Tmysql_stmt_close             = function(stmt: PMYSQL_STMT): Byte;                                 {$IFDEF MSWINDOWS} stdcall {$ELSE} cdecl {$ENDIF};\n  Tmysql_stmt_data_seek         = procedure(stmt: PMYSQL_STMT; offset: ULongLong);                       {$IFDEF MSWINDOWS} stdcall {$ELSE} cdecl {$ENDIF};\n  Tmysql_stmt_errno             = function(stmt: PMYSQL_STMT): UInt;                             {$IFDEF MSWINDOWS} stdcall {$ELSE} cdecl {$ENDIF};\n  Tmysql_stmt_error             = function(stmt: PMYSQL_STMT): PAnsiChar;                                {$IFDEF MSWINDOWS} stdcall {$ELSE} cdecl {$ENDIF};\n  Tmysql_stmt_execute           = function(stmt: PMYSQL_STMT): Integer;                              {$IFDEF MSWINDOWS} stdcall {$ELSE} cdecl {$ENDIF};\n  Tmysql_stmt_fetch             = function(stmt: PMYSQL_STMT): Integer;                              {$IFDEF MSWINDOWS} stdcall {$ELSE} cdecl {$ENDIF};\n  Tmysql_stmt_fetch_column      = function(stmt: PMYSQL_STMT; bind: Pointer{BIND record}; column: UInt;\n                                  offset: ULong): Integer;                                        {$IFDEF MSWINDOWS} stdcall {$ELSE} cdecl {$ENDIF};\n  Tmysql_stmt_field_count       = function(stmt: PMYSQL_STMT): UInt;                             {$IFDEF MSWINDOWS} stdcall {$ELSE} cdecl {$ENDIF};\n  Tmysql_stmt_free_result       = function(stmt: PMYSQL_STMT): Byte;                                 {$IFDEF MSWINDOWS} stdcall {$ELSE} cdecl {$ENDIF};\n  Tmysql_stmt_init              = function(Handle: PMYSQL): PMYSQL_STMT;                             {$IFDEF MSWINDOWS} stdcall {$ELSE} cdecl {$ENDIF};\n  Tmysql_stmt_insert_id         = function(stmt: PMYSQL_STMT): ULongLong;                                {$IFDEF MSWINDOWS} stdcall {$ELSE} cdecl {$ENDIF};\n  Tmysql_stmt_next_result       = function(stmt: PMYSQL_STMT): Integer;                                {$IFDEF MSWINDOWS} stdcall {$ELSE} cdecl {$ENDIF};\n  Tmysql_stmt_num_rows          = function(stmt: PMYSQL_STMT): ULongLong;                                {$IFDEF MSWINDOWS} stdcall {$ELSE} cdecl {$ENDIF};\n  Tmysql_stmt_param_count       = function(stmt: PMYSQL_STMT): ULong;                             {$IFDEF MSWINDOWS} stdcall {$ELSE} cdecl {$ENDIF};\n  Tmysql_stmt_param_metadata    = function(stmt: PMYSQL_STMT): PMYSQL_RES;                           {$IFDEF MSWINDOWS} stdcall {$ELSE} cdecl {$ENDIF};\n  Tmysql_stmt_prepare           = function(stmt: PMYSQL_STMT; const query: PAnsiChar; length: ULong):\n                                  Integer;                                                           {$IFDEF MSWINDOWS} stdcall {$ELSE} cdecl {$ENDIF};\n  Tmysql_stmt_reset             = function(stmt: PMYSQL_STMT): Byte;                                 {$IFDEF MSWINDOWS} stdcall {$ELSE} cdecl {$ENDIF};\n  Tmysql_stmt_result_metadata   = function(stmt: PMYSQL_STMT): PMYSQL_RES;                           {$IFDEF MSWINDOWS} stdcall {$ELSE} cdecl {$ENDIF};\n  Tmysql_stmt_row_seek          = function(stmt: PMYSQL_STMT; offset: PMYSQL_ROWS): PMYSQL_ROWS;     {$IFDEF MSWINDOWS} stdcall {$ELSE} cdecl {$ENDIF};\n  Tmysql_stmt_row_tell          = function(stmt: PMYSQL_STMT): PMYSQL_ROWS;                          {$IFDEF MSWINDOWS} stdcall {$ELSE} cdecl {$ENDIF};\n  Tmysql_stmt_send_long_data    = function(stmt: PMYSQL_STMT; parameter_number: UInt; const\n                                  data: PAnsiChar; length: ULong): Byte;                              {$IFDEF MSWINDOWS} stdcall {$ELSE} cdecl {$ENDIF};\n  Tmysql_stmt_sqlstate          = function(stmt: PMYSQL_STMT): PAnsiChar;                                {$IFDEF MSWINDOWS} stdcall {$ELSE} cdecl {$ENDIF};\n  Tmysql_stmt_store_result      = function(stmt: PMYSQL_STMT): Integer;                              {$IFDEF MSWINDOWS} stdcall {$ELSE} cdecl {$ENDIF};\n\n  Tmysql_get_character_set_info = procedure(Handle: PMYSQL; cs: PMY_CHARSET_INFO);                     {$IFDEF MSWINDOWS} stdcall {$ELSE} cdecl {$ENDIF};\n  Tmysql_library_end            = procedure; {$IFDEF MSWINDOWS} stdcall {$ELSE} cdecl {$ENDIF};\n\n{ ************** Collection of Plain API Function types definition ************* }\nTZMYSQL_API = record\n  mysql_affected_rows:          Tmysql_affected_rows;\t          {mysql 3.2}\n  mysql_character_set_name:     Tmysql_character_set_name;      {mysql 3.2}\n  mysql_close:                  Tmysql_close;                   {mysql 3.2}\n  mysql_connect:                Tmysql_connect;                 {mysql 3.2} {deprecated for mysql_real_connect}\n  mysql_create_db:              Tmysql_create_db;               {mysql 3.2} {deprecated for mysql_query}\n  mysql_data_seek:              Tmysql_data_seek;               {mysql 3.2}\n  mysql_debug:                  Tmysql_debug;                   {mysql 3.2}\n  mysql_drop_db:                Tmysql_drop_db;                 {mysql 3.2} {deprecated for mysql_query}\n  mysql_dump_debug_info:        Tmysql_dump_debug_info;         {mysql 3.2}\n  mysql_eof:                    Tmysql_eof;                     {mysql 3.2} {deprecated for mysql_error/mysql_errno}\n  mysql_errno:                  Tmysql_errno;\t                {mysql 3.2}\n  mysql_error:                  Tmysql_error;                   {mysql 3.2}\n  mysql_escape_string:          Tmysql_escape_string;           {mysql 3.2} {deprecated for mysql_real_escape_string}\n  mysql_fetch_field:            Tmysql_fetch_field;             {mysql 3.2}\n  mysql_fetch_field_direct:     Tmysql_fetch_field_direct;      {mysql 3.2}\n  mysql_fetch_fields:           Tmysql_fetch_fields;            {mysql 3.2}\n  mysql_fetch_lengths:          Tmysql_fetch_lengths;           {mysql 3.2}\n  mysql_fetch_row:              Tmysql_fetch_row;               {mysql 3.2}\n  mysql_field_seek:             Tmysql_field_seek;              {mysql 3.2}\n  mysql_field_tell:             Tmysql_field_tell;              {mysql 3.2}\n  mysql_free_result:            Tmysql_free_result;             {mysql 3.2}\n  mysql_get_client_info:        Tmysql_get_client_info;         {mysql 3.2}\n  mysql_get_host_info:          Tmysql_get_host_info;           {mysql 3.2}\n  mysql_get_proto_info:         Tmysql_get_proto_info;          {mysql 3.2}\n  mysql_get_server_info:        Tmysql_get_server_info;         {mysql 3.2}\n  mysql_info:                   Tmysql_info;                    {mysql 3.2}\n  mysql_init:                   Tmysql_init;                    {mysql 3.2}\n  mysql_insert_id:              Tmysql_insert_id;               {mysql 3.2}\n  mysql_kill:                   Tmysql_kill;                    {mysql 3.2}\n  mysql_list_dbs:               Tmysql_list_dbs;                {mysql 3.2}\n  mysql_list_fields:            Tmysql_list_fields;             {mysql 3.2}\n  mysql_list_processes:         Tmysql_list_processes;          {mysql 3.2}\n  mysql_list_tables:            Tmysql_list_tables;             {mysql 3.2}\n  mysql_num_fields:             Tmysql_num_fields;              {mysql 3.2}\n  mysql_num_rows:               Tmysql_num_rows;                {mysql 3.2}\n  mysql_options:                Tmysql_options;                 {mysql 3.2}\n  mysql_ping:                   Tmysql_ping;\t                   {mysql 3.2}\n  mysql_query:                  Tmysql_query;                   {mysql 3.2} {deprecated for mysql_real_query}\n  mysql_real_connect:           Tmysql_real_connect;            {mysql 3.2}\n  mysql_real_escape_string:     Tmysql_real_escape_string;      {mysql 3.2}\n  mysql_real_query:             Tmysql_real_query;              {mysql 3.2}\n  mysql_refresh:                Tmysql_refresh;                 {mysql 3.2}\n  mysql_row_seek:               Tmysql_row_seek;                {mysql 3.2}\n  mysql_row_tell:               Tmysql_row_tell;                {mysql 3.2}\n  mysql_select_db:              Tmysql_select_db;               {mysql 3.2}\n  mysql_shutdown:               Tmysql_shutdown;                {mysql 3.2} {new argument 4.1}\n  mysql_ssl_set:                Tmysql_ssl_set;                 {mysql 3.2}\n  mysql_stat:                   Tmysql_stat;                    {mysql 3.2}\n  mysql_store_result:           Tmysql_store_result;            {mysql 3.2}\n  mysql_thread_id:              Tmysql_thread_id;               {mysql 3.2}\n  mysql_use_result:             Tmysql_use_result;              {mysql 3.2}\n\n  {API for THREADED FUNCTIONS }\n  my_init:                      Tmy_init;                       {mysql 3.2}\n  mysql_thread_init:            Tmysql_thread_init;             {mysql 3.2}\n  mysql_thread_end:             Tmysql_thread_end;              {mysql 3.2}\n  mysql_thread_safe:            tmysql_thread_safe;             {mysql 3.2}\n\n  {API for EMBEDDED SERVER  }\n  mysql_server_init:            Tmysql_server_init;             {mysql 3.2}\n  mysql_server_end:             Tmysql_server_end;              {mysql 3.2}\n\n  mysql_change_user:            Tmysql_change_user;             {mysql 3.23}\n  mysql_field_count:            Tmysql_field_count;             {mysql 3.22}\n\n  mysql_get_client_version:     Tmysql_get_client_version;      {mysql 4.0}\n\n  mysql_send_query:     Tmysql_send_query;\n  mysql_read_query_result: Tmysql_read_query_result;\n\n  mysql_autocommit:             Tmysql_autocommit;              {mysql 4.1}\n  mysql_commit:                 Tmysql_commit;                  {mysql 4.1}\n  mysql_get_server_version:     Tmysql_get_server_version;      {mysql 4.1}\n  mysql_hex_string:             Tmysql_hex_string;              {mysql 4.1.8}\n  mysql_more_results:           Tmysql_more_results;            {mysql 4.1}\n  mysql_next_result:            Tmysql_next_result;             {mysql 4.1}\n  mysql_rollback:               Tmysql_rollback;                {mysql 4.1}\n  mysql_set_character_set:      Tmysql_set_character_set;       {mysql 4.1.13}\n  mysql_set_server_option:      Tmysql_set_server_option;       {mysql 4.1}\n  mysql_sqlstate:               Tmysql_sqlstate;                {mysql 4.1}\n  mysql_warning_count:          Tmysql_warning_count;           {mysql 4.1}\n  {API for PREPARED STATEMENTS}\n  mysql_stmt_affected_rows:     Tmysql_stmt_affected_rows;      {mysql 4.1.0}\n  mysql_stmt_attr_get:          Tmysql_stmt_attr_get;           {mysql 4.1.2}\n  mysql_stmt_attr_set:          Tmysql_stmt_attr_set;           {mysql 4.1.2} {augmented 5.0.2/6}\n  mysql_stmt_bind_param:        Tmysql_stmt_bind_param;         {mysql 4.1.2}\n  mysql_stmt_bind_result:       Tmysql_stmt_bind_result;        {mysql 4.1.2}\n  mysql_stmt_close:             Tmysql_stmt_close;              {mysql 4.1.0}\n  mysql_stmt_data_seek:         Tmysql_stmt_data_seek;          {mysql 4.1.1}\n  mysql_stmt_errno:             Tmysql_stmt_errno;              {mysql 4.1.0}\n  mysql_stmt_error:             Tmysql_stmt_error;              {mysql 4.1.0}\n  mysql_stmt_execute:           Tmysql_stmt_execute;            {mysql 4.1.2}\n  mysql_stmt_fetch:             Tmysql_stmt_fetch;              {mysql 4.1.2}\n  mysql_stmt_fetch_column:      Tmysql_stmt_fetch_column;       {mysql 4.1.2}\n  mysql_stmt_field_count:       Tmysql_stmt_field_count;        {mysql 4.1.3}\n  mysql_stmt_free_result:       Tmysql_stmt_free_result;        {mysql 4.1.1}\n  mysql_stmt_init:              Tmysql_stmt_init;               {mysql 4.1.2}\n  mysql_stmt_insert_id:         Tmysql_stmt_insert_id;          {mysql 4.1.2}\n  mysql_stmt_next_result:       Tmysql_stmt_next_result;        {mysql 5.5.3}\n  mysql_stmt_num_rows:          Tmysql_stmt_num_rows;           {mysql 4.1.1}\n  mysql_stmt_param_count:       Tmysql_stmt_param_count;        {mysql 4.1.2}\n  mysql_stmt_param_metadata:    Tmysql_stmt_param_metadata;     {mysql 4.1.2}\n  mysql_stmt_prepare:           Tmysql_stmt_prepare;            {mysql 4.1.2}\n  mysql_stmt_reset:             Tmysql_stmt_reset;              {mysql 4.1.1}\n  mysql_stmt_result_metadata:   Tmysql_stmt_result_metadata;    {mysql 4.1.2}\n  mysql_stmt_row_seek:          Tmysql_stmt_row_seek;           {mysql 4.1.1}\n  mysql_stmt_row_tell:          Tmysql_stmt_row_tell;           {mysql 4.1.1}\n  mysql_stmt_send_long_data:    Tmysql_stmt_send_long_data;     {mysql 4.1.2}\n  mysql_stmt_sqlstate:          Tmysql_stmt_sqlstate;           {mysql 4.1.1}\n  mysql_stmt_store_result:      Tmysql_stmt_store_result;       {mysql 4.1.0}\n\n  mysql_get_character_set_info: Tmysql_get_character_set_info;  {mysql 5.0.10}\nend;\n\nconst\n  EMBEDDED_DEFAULT_DATA_DIR = {$IFDEF WIN32}\n                               '.\\data\\'\n                              {$ELSE} './data/'\n                              {$ENDIF};\n  SERVER_ARGUMENTS_KEY_PREFIX = 'ServerArgument';\n  SERVER_GROUPS : array [0..2] of PAnsiChar = ('embedded'#0, 'server'#0, nil);\n\n  DEFAULT_PARAMS : array [0..2] of PAnsiChar = ('not_used'#0,\n                                            '--datadir='+EMBEDDED_DEFAULT_DATA_DIR+#0,\n                                            '--set-variable=key_buffer_size=32M'#0);\n\nconst\n    MaxBlobSize = 1000000;\n\nimplementation\n\n\nend.\n"
  },
  {
    "path": "lib/zeosdbo/src/plain/ZPlainMySqlDriver.pas",
    "content": "{*********************************************************}\n{                                                         }\n{                 Zeos Database Objects                   }\n{             Native Plain Drivers for MySQL              }\n{                                                         }\n{        Originally written by Sergey Seroukhov           }\n{                                                         }\n{    Thanks to :                                          }\n{               Pascal Data Objects Library               }\n{                                                         }\n{    Copyright (c) 2006 John Marino, www.synsport.com     }\n{                                                         }\n{*********************************************************}\n\n{@********************************************************}\n{    Copyright (c) 1999-2012 Zeos Development Group       }\n{                                                         }\n{ License Agreement:                                      }\n{                                                         }\n{ This library is distributed in the hope that it will be }\n{ useful, but WITHOUT ANY WARRANTY; without even the      }\n{ implied warranty of MERCHANTABILITY or FITNESS FOR      }\n{ A PARTICULAR PURPOSE.  See the GNU Lesser General       }\n{ Public License for more details.                        }\n{                                                         }\n{ The source code of the ZEOS Libraries and packages are  }\n{ distributed under the Library GNU General Public        }\n{ License (see the file COPYING / COPYING.ZEOS)           }\n{ with the following  modification:                       }\n{ As a special exception, the copyright holders of this   }\n{ library give you permission to link this library with   }\n{ independent modules to produce an executable,           }\n{ regardless of the license terms of these independent    }\n{ modules, and to copy and distribute the resulting       }\n{ executable under terms of your choice, provided that    }\n{ you also meet, for each linked independent module,      }\n{ the terms and conditions of the license of that module. }\n{ An independent module is a module which is not derived  }\n{ from or based on this library. If you modify this       }\n{ library, you may extend this exception to your version  }\n{ of the library, but you are not obligated to do so.     }\n{ If you do not wish to do so, delete this exception      }\n{ statement from your version.                            }\n{                                                         }\n{                                                         }\n{ The project web site is located on:                     }\n{   http://zeos.firmos.at  (FORUM)                        }\n{   http://sourceforge.net/p/zeoslib/tickets/ (BUGTRACKER)}\n{   svn://svn.code.sf.net/p/zeoslib/code-0/trunk (SVN)    }\n{                                                         }\n{   http://www.sourceforge.net/projects/zeoslib.          }\n{                                                         }\n{                                                         }\n{                                 Zeos Development Group. }\n{********************************************************@}\n\nunit ZPlainMySqlDriver;\n\ninterface\n\n{$I ZPlain.inc}\n\nuses Classes, {$IFDEF MSEgui}mclasses,{$ENDIF}\n  ZPlainDriver, ZCompatibility, ZPlainMySqlConstants, ZTokenizer;\n\nconst\n  MARIADB_LOCATION = 'libmariadb'+ SharedSuffix;\n{$IFNDEF UNIX}\n  {$IFNDEF MYSQL_STRICT_DLL_LOADING}\n  WINDOWS_DLL_LOCATION = 'libmysql.dll';\n  WINDOWS_DLL_LOCATION_EMBEDDED = 'libmysqld.dll';\n  {$ENDIF}\n  WINDOWS_DLL41_LOCATION = 'libmysql41.dll';\n  WINDOWS_DLL41_LOCATION_EMBEDDED = 'libmysqld41.dll';\n  WINDOWS_DLL50_LOCATION = 'libmysql50.dll';\n  WINDOWS_DLL50_LOCATION_EMBEDDED = 'libmysqld50.dll';\n  WINDOWS_DLL51_LOCATION = 'libmysql51.dll';\n  WINDOWS_DLL51_LOCATION_EMBEDDED = 'libmysqld51.dll';\n  WINDOWS_DLL55_LOCATION = 'libmysql55.dll';\n  WINDOWS_DLL55_LOCATION_EMBEDDED = 'libmysqld55.dll';\n{$ELSE}\n  {$IFNDEF MYSQL_STRICT_DLL_LOADING}\n  LINUX_DLL_LOCATION = 'libmysqlclient'+SharedSuffix;\n  LINUX_DLL_LOCATION_EMBEDDED = 'libmysqld'+SharedSuffix;\n  {$ENDIF}\n  LINUX_DLL41_LOCATION = 'libmysqlclient'+SharedSuffix+'.14';\n  LINUX_DLL41_LOCATION_EMBEDDED = 'libmysqld'+SharedSuffix+'.14';\n  LINUX_DLL50_LOCATION = 'libmysqlclient'+SharedSuffix+'.15';\n  LINUX_DLL50_LOCATION_EMBEDDED = 'libmysqld'+SharedSuffix+'.15';\n  LINUX_DLL51_LOCATION = 'libmysqlclient'+SharedSuffix+'.16';\n  LINUX_DLL51_LOCATION_EMBEDDED = 'libmysqld'+SharedSuffix+'.16';\n  LINUX_DLL55_LOCATION = 'libmysqlclient'+SharedSuffix+'.18';\n  LINUX_DLL55_LOCATION_EMBEDDED = 'libmysqld'+SharedSuffix+'.18';\n{$ENDIF}\n\ntype\n  {** Represents a generic interface to MySQL native API. }\n  IZMySQLPlainDriver = interface (IZPlainDriver)\n    ['{D1CB3F6C-72A1-4125-873F-791202ACC5F0}']\n    {ADDED by fduenas 15-06-2006}\n    function GetClientVersion: Integer;\n    function GetServerVersion(Handle: PZMySQLConnect): Integer;\n    {END ADDED by fduenas 15-06-2006}\n    procedure Despose(var Handle: PZMySQLConnect);\n\n    function GetAffectedRows(Handle: PZMySQLConnect): Int64;\n    {ADDED by EgonHugeist}\n    function GetConnectionCharacterSet(Handle: PMYSQL): PAnsiChar;// char_set_name\n    procedure Close(Handle: PZMySQLConnect);\n    function Connect(Handle: PZMySQLConnect; const Host, User, Password: PAnsiChar): PZMySQLConnect;\n    function CreateDatabase(Handle: PZMySQLConnect; const Database: PAnsiChar): Integer;\n    procedure SeekData(Res: PZMySQLResult; Offset: Cardinal);\n    procedure Debug(Debug: PAnsiChar);\n    function DropDatabase(Handle: PZMySQLConnect; const Database: PAnsiChar): Integer;\n    function DumpDebugInfo(Handle: PZMySQLConnect): Integer;\n    // eof\n    function GetLastErrorCode(Handle: PZMySQLConnect): Integer;\n    function GetLastError(Handle: PZMySQLConnect): PAnsiChar;\n    function FetchField(Res: PZMySQLResult): PZMySQLField;\n    // fetch_field_direct\n    // fetch_fields\n    function FetchLengths(Res: PZMySQLResult): PULong;\n    function FetchRow(Res: PZMySQLResult): PZMySQLRow;\n    function SeekField(Res: PZMySQLResult; Offset: Cardinal): Cardinal;\n    // field_tell\n    procedure FreeResult(Res: PZMySQLResult);\n    function GetClientInfo: PAnsiChar;\n    function GetHostInfo(Handle: PZMySQLConnect): PAnsiChar;\n    function GetProtoInfo(Handle: PZMySQLConnect): Cardinal;\n    function GetServerInfo(Handle: PZMySQLConnect): PAnsiChar;\n    // info\n    function Init(const Handle: PZMySQLConnect): PZMySQLConnect;\n    function GetLastInsertID (Handle: PZMySQLConnect): Int64;\n    function Kill(Handle: PZMySQLConnect; Pid: LongInt): Integer;\n    function GetBindOffsets: MYSQL_BINDOFFSETS;\n    function GetListDatabases(Handle: PZMySQLConnect; Wild: PAnsiChar): PZMySQLResult;\n    function GetListFields(Handle: PZMySQLConnect; const Table, Wild: PAnsiChar): PZMySQLResult;\n    function GetListProcesses(Handle: PZMySQLConnect): PZMySQLResult;\n    function GetListTables(Handle: PZMySQLConnect; const Wild: PAnsiChar): PZMySQLResult;\n    // num_fields\n    function GetNumRows(Res: PZMySQLResult): Int64;\n    function SetOptions(Handle: PZMySQLConnect; Option: TMySQLOption; const Arg: Pointer): Integer;\n    function Ping(Handle: PZMySQLConnect): Integer;\n    function ExecQuery(Handle: PZMySQLConnect; const Query: PAnsiChar): Integer; overload;\n    function RealConnect(Handle: PZMySQLConnect; const Host, User, Password, Db: PAnsiChar; Port: Cardinal; UnixSocket: PAnsiChar; ClientFlag: Cardinal): PZMySQLConnect;\n    function ExecRealQuery(Handle: PZMySQLConnect; const Query: PAnsiChar; Length: Integer): Integer;\n    function Refresh(Handle: PZMySQLConnect; Options: Cardinal): Integer;\n    function SeekRow(Res: PZMySQLResult; Row: PZMySQLRowOffset): PZMySQLRowOffset;\n    // row_tell\n    function SelectDatabase(Handle: PZMySQLConnect; const Database: PAnsiChar): Integer;\n    function SslSet(Handle: PZMySQLConnect; const Key, Cert, Ca, Capath, Cipher: PAnsiChar): Integer;\n    function GetStatInfo(Handle: PZMySQLConnect): PAnsiChar;\n    function StoreResult(Handle: PZMySQLConnect): PZMySQLResult;\n    function GetThreadId(Handle: PZMySQLConnect): Cardinal;\n    function UseResult(Handle: PZMySQLConnect): PZMySQLResult;\n\n    // thread_init\n    // thread_end\n    // thread_safe\n\n    // server_init\n    // server_end\n\n    // change_user\n    // field_count\n    // function GetClientVersion: AnsiString;\n\n    function Shutdown(Handle: PZMySQLConnect; shutdown_level: TMysqlShutdownLevel = ZPlainMySqlConstants.SHUTDOWN_DEFAULT): Integer; // 2 versions!!\n\n    function SetAutocommit (Handle: PZMySQLConnect; mode: Boolean): Boolean;\n    function Commit (Handle: PZMySQLConnect): Boolean;\n    //function GetServerVersion (Handle: PZMySQLConnect): AnsiString;\n    // hex_string\n    function CheckAnotherRowset   (Handle: PZMySQLConnect): Boolean;\n    function RetrieveNextRowset   (Handle: PZMySQLConnect): Integer;\n    function Rollback (Handle: PZMySQLConnect): Boolean;\n    {ADDED by EgonHugeist}\n    function SetConnectionCharacterSet(Handle: PMYSQL; const csname: PAnsiChar): Integer; // set_character_set returns 0 if valid\n    // set_server_option\n    function GetSQLState (Handle: PZMySQLConnect): AnsiString;\n    // warning_count\n\n    function GetPreparedAffectedRows (Handle: PZMySqlPrepStmt): Int64;\n    // stmt_attr_get\n    function StmtAttrSet(stmt: PZMySqlPrepStmt; option: TMysqlStmtAttrType;\n                                  arg: PAnsiChar): Byte;\n    function BindParameters (Handle: PZMySqlPrepStmt; bindArray: PZMysqlBindArray): Byte;\n    function BindResult (Handle: PZMySqlPrepStmt;  bindArray: PZMysqlBindArray): Byte;\n    function ClosePrepStmt (PrepStmtHandle: PZMySqlPrepStmt): PZMySqlPrepStmt;\n    procedure SeekPreparedData(PrepStmtHandle: PZMySqlPrepStmt; Offset: Cardinal);\n    function GetLastPreparedErrorCode(Handle: PZMySqlPrepStmt): Integer;\n    function GetLastPreparedError(Handle: PZMySqlPrepStmt): AnsiString;\n    function ExecuteStmt (Handle: PZMySqlPrepStmt): Integer;\n    function FetchBoundResults (Handle: PZMySqlPrepStmt): Integer;\n    // stmt_fetch_column\n    function GetPreparedFieldCount(Handle: PZMySqlPrepStmt): Integer;\n    function FreePreparedResult (Handle: PZMySqlPrepStmt): Byte;\n    function InitializePrepStmt (Handle: PZMySQLConnect): PZMySqlPrepStmt;\n    function GetPreparedInsertID (Handle: PZMySqlPrepStmt): Int64;\n    function GetPreparedNextResult (Handle: PZMySqlPrepStmt): Integer;\n    function GetPreparedNumRows (Handle: PZMySqlPrepStmt): Int64;\n    function GetPreparedBindMarkers (Handle: PZMySqlPrepStmt): Cardinal; // param_count\n\n    function GetStmtParamMetadata(PrepStmtHandle: PZMySqlPrepStmt): PZMySQLResult; // stmt_param_metadata\n    function PrepareStmt(PrepStmtHandle: PZMySqlPrepStmt; const Query: PAnsiChar; Length: Integer): Integer;\n    // stmt_reset\n    function GetPreparedMetaData (Handle: PZMySqlPrepStmt): PZMySQLResult;\n    function SeekPreparedRow(Handle: PZMySqlPrepStmt; Row: PZMySQLRowOffset): PZMySQLRowOffset;\n    // stmt_row_tell\n    function SendPreparedLongData(Handle: PZMySqlPrepStmt; parameter_number: Cardinal; const data: PAnsiChar; length: Cardinal): Byte;\n    function GetPreparedSQLState (Handle: PZMySqlPrepStmt): PAnsiChar;\n    function StorePreparedResult (Handle: PZMySqlPrepStmt): Integer;\n\n    procedure GetCharacterSetInfo(Handle: PZMySQLConnect; CharSetInfo: PMY_CHARSET_INFO);// get_character_set_info since 5.0.10\n\n    {non API functions}\n    function GetFieldType(Field: PZMySQLField): TMysqlFieldTypes;\n    function GetFieldFlags(Field: PZMySQLField): Integer;\n    function ResultSetExists(Handle: PZMySQLConnect):Boolean;\n    function GetRowCount(Res: PZMySQLResult): Int64;\n    function GetFieldCount(Res: PZMySQLResult): Integer;\n    function GetFieldName(Field: PZMySQLField): PAnsiChar;\n    function GetFieldTable(Field: PZMySQLField): PAnsiChar;\n    function GetFieldOrigTable(Field: PZMySQLField): PAnsiChar;\n    function GetFieldOrigName(Field: PZMySQLField): PAnsiChar;\n    function GetFieldLength(Field: PZMySQLField): ULong;\n    function GetFieldMaxLength(Field: PZMySQLField): Integer;\n    function GetFieldDecimals(Field: PZMySQLField): Integer;\n    function GetFieldCharsetNr(Field: PZMySQLField): UInt;\n    function GetFieldData(Row: PZMySQLRow; Offset: Cardinal): PAnsiChar;\n    procedure SetDriverOptions(Options: TStrings); // changed by tohenk, 2009-10-11\n  end;\n\n  {** Implements a base driver for MySQL}\n\n  { TZMySQLBaseDriver }\n\n  TZMySQLBaseDriver = class (TZAbstractPlainDriver, IZPlainDriver, IZMySQLPlainDriver)\n  protected\n    MYSQL_API : TZMYSQL_API;\n    ServerArgs: array of PAnsiChar;\n    ServerArgsLen: Integer;\n    IsEmbeddedDriver: Boolean;\n    function GetUnicodeCodePageName: String; override;\n    procedure LoadCodePages; override;\n    procedure LoadApi; override;\n    procedure BuildServerArguments(Options: TStrings);\n  public\n    constructor Create(Tokenizer: IZTokenizer);\n    destructor Destroy; override;\n\n    procedure Debug(Debug: PAnsiChar);\n    function DumpDebugInfo(Handle: PZMySQLConnect): Integer;\n    function GetLastError(Handle: PZMySQLConnect): PAnsiChar;\n    function GetLastErrorCode(Handle: PZMySQLConnect): Integer;\n    function Init(const Handle: PZMySQLConnect): PZMySQLConnect; virtual;\n    function GetLastInsertID (Handle: PZMySQLConnect): Int64;\n    procedure Despose(var Handle: PZMySQLConnect);\n\n    function Connect(Handle: PZMySQLConnect;\n      const Host, User, Password: PAnsiChar): PZMySQLConnect;\n    function RealConnect(Handle: PZMySQLConnect;\n      const Host, User, Password, Db: PAnsiChar; Port: Cardinal;\n      UnixSocket: PAnsiChar; ClientFlag: Cardinal): PZMySQLConnect;\n    procedure Close(Handle: PZMySQLConnect);\n\n    function ExecQuery(Handle: PZMySQLConnect; const Query: PAnsiChar): Integer; overload;\n    function ExecRealQuery(Handle: PZMySQLConnect; const Query: PAnsiChar;\n      Length: Integer): Integer;\n\n    function SelectDatabase(Handle: PZMySQLConnect;\n      const Database: PAnsiChar): Integer;\n    function SslSet(Handle: PZMySQLConnect; const Key, Cert, Ca, Capath, Cipher: PAnsiChar): Integer;\n    function CreateDatabase(Handle: PZMySQLConnect;\n      const Database: PAnsiChar): Integer;\n    function DropDatabase(Handle: PZMySQLConnect;\n      const Database: PAnsiChar): Integer;\n\n    function Shutdown(Handle: PZMySQLConnect; shutdown_level: TMysqlShutdownLevel = ZPlainMySqlConstants.SHUTDOWN_DEFAULT): Integer; // 2 versions!!\n    function SetAutocommit (Handle: PZMySQLConnect; mode: Boolean): Boolean;\n    function Commit (Handle: PZMySQLConnect): Boolean;\n    function CheckAnotherRowset   (Handle: PZMySQLConnect): Boolean;\n    function RetrieveNextRowset   (Handle: PZMySQLConnect): Integer;\n    function Rollback (Handle: PZMySQLConnect): Boolean;\n    function GetSQLState (Handle: PZMySQLConnect): AnsiString;\n\n    function StmtAttrSet(stmt: PZMySqlPrepStmt; option: TMysqlStmtAttrType;\n                                  arg: PAnsiChar): Byte;\n    function GetPreparedAffectedRows (Handle: PZMySqlPrepStmt): Int64;\n    function BindParameters (Handle: PZMySqlPrepStmt; bindArray: PZMysqlBindArray): Byte;\n    function BindResult (Handle: PZMySqlPrepStmt;  bindArray: PZMysqlBindArray): Byte;\n    function ClosePrepStmt (PrepStmtHandle: PZMySqlPrepStmt): PZMySqlPrepStmt;\n    procedure SeekPreparedData(PrepStmtHandle: PZMySqlPrepStmt; Offset: Cardinal);\n    function GetLastPreparedErrorCode(Handle: PZMySqlPrepStmt): Integer;\n    function GetLastPreparedError(Handle: PZMySqlPrepStmt): AnsiString;\n    function ExecuteStmt (Handle: PZMySqlPrepStmt): Integer;\n    function FetchBoundResults (Handle: PZMySqlPrepStmt): Integer;\n    function GetPreparedFieldCount(Handle: PZMySqlPrepStmt): Integer;\n    function FreePreparedResult (Handle: PZMySqlPrepStmt): Byte;\n    function InitializePrepStmt (Handle: PZMySQLConnect): PZMySqlPrepStmt;\n    function GetPreparedInsertID (Handle: PZMySqlPrepStmt): Int64;\n    function GetPreparedNextResult (Handle: PZMySqlPrepStmt): Integer;\n    function GetPreparedNumRows (Handle: PZMySqlPrepStmt): Int64;\n    function GetPreparedBindMarkers (Handle: PZMySqlPrepStmt): Cardinal; // param_count\n    function GetStmtParamMetadata(PrepStmtHandle: PZMySqlPrepStmt): PZMySQLResult;\n    function PrepareStmt (PrepStmtHandle: PZMySqlPrepStmt; const Query: PAnsiChar; Length: Integer): Integer;\n    function GetPreparedMetaData (Handle: PZMySqlPrepStmt): PZMySQLResult;\n    function SeekPreparedRow(Handle: PZMySqlPrepStmt; Row: PZMySQLRowOffset): PZMySQLRowOffset;\n    function SendPreparedLongData(Handle: PZMySqlPrepStmt; parameter_number: Cardinal; const data: PAnsiChar; length: Cardinal): Byte;\n    function GetPreparedSQLState (Handle: PZMySqlPrepStmt): PAnsiChar;\n    function StorePreparedResult (Handle: PZMySqlPrepStmt): Integer;\n    procedure GetCharacterSetInfo(Handle: PZMySQLConnect; CharSetInfo: PMY_CHARSET_INFO);\n\n    function GetBindOffsets: MYSQL_BINDOFFSETS;\n    function Refresh(Handle: PZMySQLConnect; Options: Cardinal): Integer;\n    function Kill(Handle: PZMySQLConnect; Pid: LongInt): Integer;\n    function Ping(Handle: PZMySQLConnect): Integer;\n\n    function GetStatInfo(Handle: PZMySQLConnect): PAnsiChar;\n    function SetOptions(Handle: PZMySQLConnect; Option: TMySQLOption;\n      const Arg: Pointer): Integer;\n    function EscapeString(Handle: Pointer; const Value: RawByteString;\n      ConSettings: PZConSettings; WasEncoded: Boolean = False): RawByteString; override;\n    function GetServerInfo(Handle: PZMySQLConnect): PAnsiChar;\n    function GetClientInfo: PAnsiChar;\n    function GetHostInfo(Handle: PZMySQLConnect): PAnsiChar;\n    function GetProtoInfo(Handle: PZMySQLConnect): Cardinal;\n    function GetThreadId(Handle: PZMySQLConnect): Cardinal;\n    {ADDED by fduenas 15-06-2006}\n    function GetClientVersion: Integer;\n    function GetServerVersion(Handle: PZMySQLConnect): Integer;\n    {END ADDED by fduenas 15-06-2006}\n    function GetListDatabases(Handle: PZMySQLConnect;\n      Wild: PAnsiChar): PZMySQLResult;\n    function GetListTables(Handle: PZMySQLConnect;\n      const Wild: PAnsiChar): PZMySQLResult;\n    function GetNumRows(Res: PZMySQLResult): Int64;\n    function GetListFields(Handle: PZMySQLConnect;\n      const Table, Wild: PAnsiChar): PZMySQLResult;\n    function GetListProcesses(Handle: PZMySQLConnect): PZMySQLResult;\n\n    function StoreResult(Handle: PZMySQLConnect): PZMySQLResult;\n    function UseResult(Handle: PZMySQLConnect): PZMySQLResult;\n    procedure FreeResult(Res: PZMySQLResult);\n    function GetAffectedRows(Handle: PZMySQLConnect): Int64;\n    {ADDED by EgonHugeist}\n    function GetConnectionCharacterSet(Handle: PMYSQL): PAnsiChar;// char_set_name\n    function SetConnectionCharacterSet(Handle: PMYSQL; const csname: PAnsiChar): Integer; // set_character_set Returns 0 if valid\n\n    function FetchRow(Res: PZMySQLResult): PZMySQLRow;\n    function FetchLengths(Res: PZMySQLResult): PULong;\n    function FetchField(Res: PZMySQLResult): PZMySQLField;\n\n    procedure SeekData(Res: PZMySQLResult; Offset: Cardinal);\n    function SeekRow(Res: PZMySQLResult; Row: PZMySQLRowOffset):\n      PZMySQLRowOffset;\n    function SeekField(Res: PZMySQLResult; Offset: Cardinal): Cardinal;\n\n    function GetFieldType(Field: PZMySQLField): TMysqlFieldTypes;\n    function GetFieldFlags(Field: PZMySQLField): Integer;\n    function ResultSetExists(Handle: PZMySQLConnect):Boolean;\n    function GetRowCount(Res: PZMySQLResult): Int64;\n    function GetFieldCount(Res: PZMySQLResult): Integer;\n    function GetFieldName(Field: PZMySQLField): PAnsiChar;\n    function GetFieldTable(Field: PZMySQLField): PAnsiChar;\n    function GetFieldOrigTable(Field: PZMySQLField): PAnsiChar;\n    function GetFieldOrigName(Field: PZMySQLField): PAnsiChar;\n    function GetFieldLength(Field: PZMySQLField): ULong;\n    function GetFieldMaxLength(Field: PZMySQLField): Integer;\n    function GetFieldDecimals(Field: PZMySQLField): Integer;\n    function GetFieldCharsetNr(Field: PZMySQLField): UInt;\n    function GetFieldData(Row: PZMySQLRow; Offset: Cardinal): PAnsiChar;\n    procedure SetDriverOptions(Options: TStrings); virtual; // changed by tohenk, 2009-10-11\n  end;\n\n  {** Implements a driver for MySQL 4.1 }\n\n  { TZNewMySQL41PlainDriver }\n\n  TZMySQL41PlainDriver = class (TZMysqlBaseDriver)\n  protected\n    function Clone: IZPlainDriver; override;\n  public\n    constructor Create(Tokenizer: IZTokenizer);\n    function GetProtocol: string; override;\n    function GetDescription: string; override;\n  end;\n\n  {** Implements a driver for MySQL 4.1 }\n\n  { TZNewMySQLD41PlainDriver }\n\n  TZMySQLD41PlainDriver = class (TZMySQL41PlainDriver)\n  protected\n    function Clone: IZPlainDriver; override;\n  public\n    constructor Create(Tokenizer: IZTokenizer);\n    function GetProtocol: string; override;\n    function GetDescription: string; override;\n  end;\n\n  { TZNewMySQL5PlainDriver }\n\n  TZMySQL5PlainDriver = class (TZMysqlBaseDriver)\n  protected\n    function Clone: IZPlainDriver; override;\n  protected\n    procedure LoadApi; override;\n    procedure LoadCodePages; override;\n  public\n    constructor Create(Tokenizer: IZTokenizer);\n    function GetProtocol: string; override;\n    function GetDescription: string; override;\n  end;\n\n  { TZNewMySQLD5PlainDriver }\n\n  TZMySQLD5PlainDriver = class (TZMySQL5PlainDriver)\n  protected\n    function Clone: IZPlainDriver; override;\n  public\n    constructor Create(Tokenizer: IZTokenizer);\n    function GetProtocol: string; override;\n    function GetDescription: string; override;\n  end;\n\n  { TZMariaDB5PlainDriver }\n\n  TZMariaDB5PlainDriver = class (TZMySQL5PlainDriver)\n  protected\n    function Clone: IZPlainDriver; override;\n  public\n    constructor Create(Tokenizer: IZTokenizer);\n    function GetProtocol: string; override;\n    function GetDescription: string; override;\n  end;\n\nimplementation\n\nuses SysUtils, ZPlainLoader, ZEncoding\n  {$IFDEF WITH_UNITANSISTRINGS}, AnsiStrings{$ENDIF};\n\n{ TZMySQLPlainBaseDriver }\nfunction TZMySQLBaseDriver.GetUnicodeCodePageName: String;\nbegin\n  Result := 'utf8';\nend;\n\nprocedure TZMySQLBaseDriver.LoadCodePages;\nbegin\n  {MySQL 3.23-4.1}\n  { MultiByte }\n  AddCodePage('big5', 1, ceAnsi, zCP_Big5, '', 2); {Big5 Traditional Chinese}\n  AddCodePage('ujis', 10, ceAnsi, zCP_EUC_JP, '', 3); {EUC-JP Japanese}\n  AddCodePage('sjis', 11, ceAnsi, zCP_SHIFTJS, '', 2); {Shift-JIS Japanese}\n  AddCodePage('gbk', 19, ceAnsi, zCP_GB2312, '', 2); {GBK Simplified Chinese}\n  AddCodePage('utf8', 22, ceUTF8, zCP_UTF8, '', 3); {UTF-8 Unicode}\n  AddCodePage('ucs2', 23, ceUTF16, zCP_UTF16, 'utf8', 2); {UCS-2 Unicode}\n  AddCodePage('euckr', 14, ceAnsi, zCP_EUCKR, '', 2); {EUC-KR Korean}\n  AddCodePage('gb2312', 16, ceAnsi, zCP_GB2312, '', 2); {GB2312 Simplified Chinese}\n  AddCodePage('cp932', 35, ceAnsi, zCP_SHIFTJS, '', 2); {SJIS for Windows Japanese}\n  AddCodePage('eucjpms', 36, ceAnsi, $ffff, '', 3); {UJIS for Windows Japanese}\n  { SingleChar }\n  AddCodePage('dec8', 2); {DEC West European}\n  AddCodePage('cp850', 3, ceAnsi, zCP_DOS850); {DOS West European}\n  AddCodePage('hp8', 4); {HP West European}\n  AddCodePage('koi8r', 5, ceAnsi, zCP_KOI8R); {KOI8-R Relcom Russian}\n  AddCodePage('latin1', 6, ceAnsi, zCP_WIN1252); {cp1252 West European}\n  AddCodePage('latin2', 7, ceAnsi, zCP_L2_ISO_8859_2); {ISO 8859-2 Central European}\n  AddCodePage('swe7', 8, ceAnsi, zCP_x_IA5_Swedish); {7bit Swedish}\n  AddCodePage('ascii', 9, ceAnsi, zCP_us_ascii); {US ASCII}\n  AddCodePage('hebrew', 12, ceAnsi, zCP_L8_ISO_8859_8); {ISO 8859-8 Hebrew}\n  AddCodePage('tis620', 13, ceAnsi, zCP_IBM_Thai); {TIS620 Thai}\n  AddCodePage('koi8u', 15, ceAnsi, zCP_KOI8U); {KOI8-U Ukrainian}\n  AddCodePage('greek', 17, ceAnsi, zCP_L7_ISO_8859_7); {ISO 8859-7 Greek}\n  AddCodePage('cp1250', 18, ceAnsi, zCP_WIN1250); {Windows Central European}\n  AddCodePage('latin5', 20, ceAnsi, zCP_L5_ISO_8859_9); {ISO 8859-9 Turkish}\n  AddCodePage('armscii8', 21, ceAnsi, zCP_us_ascii); {ARMSCII-8 Armenian}\n  AddCodePage('cp866', 24, ceAnsi, zCP_DOS866); {DOS Russian}\n  AddCodePage('keybcs2', 25); {DOS Kamenicky Czech-Slovak}\n  AddCodePage('macce', 26, ceAnsi, zCP_x_mac_ce); {Mac Central European}\n  AddCodePage('macroman', 27, ceAnsi, zCP_macintosh); {Mac West European}\n  AddCodePage('cp852', 28, ceAnsi, zCP_DOS852); {DOS Central European}\n  AddCodePage('latin7', 29, ceAnsi, zCP_L7_ISO_8859_13); {ISO 8859-13 Baltic}\n  AddCodePage('cp1251', 30, ceAnsi, zCP_WIN1251); {Windows Cyrillic}\n  AddCodePage('cp1256', 31, ceAnsi, cCP_WIN1256); {Windows Arabic}\n  AddCodePage('cp1257', 32, ceAnsi, zCP_WIN1257); {Windows Baltic}\n  AddCodePage('binary', 33); {Binary pseudo charset}\n  AddCodePage('geostd8', 34); {GEOSTD8 Georgian}\nend;\n\nprocedure TZMySQLBaseDriver.LoadApi;\nbegin\n{ ************** Load adresses of API Functions ************* }\n  with Loader do\n  begin\n  @MYSQL_API.mysql_affected_rows          := GetAddress('mysql_affected_rows');\n  @MYSQL_API.mysql_character_set_name     := GetAddress('mysql_character_set_name');\n  @MYSQL_API.mysql_close                  := GetAddress('mysql_close');\n  @MYSQL_API.mysql_connect                := GetAddress('mysql_connect');\n  @MYSQL_API.mysql_create_db              := GetAddress('mysql_create_db');\n  @MYSQL_API.mysql_data_seek              := GetAddress('mysql_data_seek');\n  @MYSQL_API.mysql_debug                  := GetAddress('mysql_debug');\n  @MYSQL_API.mysql_drop_db                := GetAddress('mysql_drop_db');\n  @MYSQL_API.mysql_dump_debug_info        := GetAddress('mysql_dump_debug_info');\n  @MYSQL_API.mysql_eof                    := GetAddress('mysql_eof');\n  @MYSQL_API.mysql_errno                  := GetAddress('mysql_errno');\n  @MYSQL_API.mysql_error                  := GetAddress('mysql_error');\n  @MYSQL_API.mysql_escape_string          := GetAddress('mysql_escape_string');\n  @MYSQL_API.mysql_fetch_field            := GetAddress('mysql_fetch_field');\n  @MYSQL_API.mysql_fetch_field_direct     := GetAddress('mysql_fetch_field_direct');\n  @MYSQL_API.mysql_fetch_fields           := GetAddress('mysql_fetch_fields');\n  @MYSQL_API.mysql_fetch_lengths          := GetAddress('mysql_fetch_lengths');\n  @MYSQL_API.mysql_fetch_row              := GetAddress('mysql_fetch_row');\n  @MYSQL_API.mysql_field_seek             := GetAddress('mysql_field_seek');\n  @MYSQL_API.mysql_field_tell             := GetAddress('mysql_field_tell');\n  @MYSQL_API.mysql_free_result            := GetAddress('mysql_free_result');\n  @MYSQL_API.mysql_get_client_info        := GetAddress('mysql_get_client_info');\n  @MYSQL_API.mysql_get_host_info          := GetAddress('mysql_get_host_info');\n  @MYSQL_API.mysql_get_proto_info         := GetAddress('mysql_get_proto_info');\n  @MYSQL_API.mysql_get_server_info        := GetAddress('mysql_get_server_info');\n  @MYSQL_API.mysql_info                   := GetAddress('mysql_info');\n  @MYSQL_API.mysql_init                   := GetAddress('mysql_init');\n  @MYSQL_API.mysql_insert_id              := GetAddress('mysql_insert_id');\n  @MYSQL_API.mysql_kill                   := GetAddress('mysql_kill');\n  @MYSQL_API.mysql_list_dbs               := GetAddress('mysql_list_dbs');\n  @MYSQL_API.mysql_list_fields            := GetAddress('mysql_list_fields');\n  @MYSQL_API.mysql_list_processes         := GetAddress('mysql_list_processes');\n  @MYSQL_API.mysql_list_tables            := GetAddress('mysql_list_tables');\n  @MYSQL_API.mysql_num_fields             := GetAddress('mysql_num_fields');\n  @MYSQL_API.mysql_num_rows               := GetAddress('mysql_num_rows');\n  @MYSQL_API.mysql_options                := GetAddress('mysql_options');\n  @MYSQL_API.mysql_ping                   := GetAddress('mysql_ping');\n  @MYSQL_API.mysql_query                  := GetAddress('mysql_query');\n  @MYSQL_API.mysql_real_connect           := GetAddress('mysql_real_connect');\n  @MYSQL_API.mysql_real_escape_string     := GetAddress('mysql_real_escape_string');\n  @MYSQL_API.mysql_real_query             := GetAddress('mysql_real_query');\n  @MYSQL_API.mysql_refresh                := GetAddress('mysql_refresh');\n  @MYSQL_API.mysql_row_seek               := GetAddress('mysql_row_seek');\n  @MYSQL_API.mysql_row_tell               := GetAddress('mysql_row_tell');\n  @MYSQL_API.mysql_select_db              := GetAddress('mysql_select_db');\n  @MYSQL_API.mysql_shutdown               := GetAddress('mysql_shutdown');\n  @MYSQL_API.mysql_ssl_set                := GetAddress('mysql_ssl_set');\n  @MYSQL_API.mysql_stat                   := GetAddress('mysql_stat');\n  @MYSQL_API.mysql_store_result           := GetAddress('mysql_store_result');\n  @MYSQL_API.mysql_thread_id              := GetAddress('mysql_thread_id');\n  @MYSQL_API.mysql_use_result             := GetAddress('mysql_use_result');\n\n  @MYSQL_API.my_init                      := GetAddress('my_init');\n  @MYSQL_API.mysql_thread_init            := GetAddress('mysql_thread_init');\n  @MYSQL_API.mysql_thread_end             := GetAddress('mysql_thread_end');\n  @MYSQL_API.mysql_thread_safe            := GetAddress('mysql_thread_safe');\n\n  @MYSQL_API.mysql_server_init            := GetAddress('mysql_server_init');\n  @MYSQL_API.mysql_server_end             := GetAddress('mysql_server_end');\n\n  @MYSQL_API.mysql_change_user            := GetAddress('mysql_change_user');\n  @MYSQL_API.mysql_field_count            := GetAddress('mysql_field_count');\n\n  @MYSQL_API.mysql_get_client_version     := GetAddress('mysql_get_client_version');\n\n  @MYSQL_API.mysql_send_query             := GetAddress('mysql_send_query');\n  @MYSQL_API.mysql_read_query_result      := GetAddress('mysql_read_query_result');\n\n  @MYSQL_API.mysql_autocommit             := GetAddress('mysql_autocommit');\n  @MYSQL_API.mysql_commit                 := GetAddress('mysql_commit');\n  @MYSQL_API.mysql_get_server_version     := GetAddress('mysql_get_server_version');\n  @MYSQL_API.mysql_hex_string             := GetAddress('mysql_hex_string');\n  @MYSQL_API.mysql_more_results           := GetAddress('mysql_more_results');\n  @MYSQL_API.mysql_next_result            := GetAddress('mysql_next_result');\n  @MYSQL_API.mysql_rollback               := GetAddress('mysql_rollback');\n  @MYSQL_API.mysql_set_character_set      := GetAddress('mysql_set_character_set');\n  @MYSQL_API.mysql_set_server_option      := GetAddress('mysql_set_server_option');\n  @MYSQL_API.mysql_sqlstate               := GetAddress('mysql_sqlstate');\n  @MYSQL_API.mysql_warning_count          := GetAddress('mysql_warning_count');\n  {API for PREPARED STATEMENTS}\n  @MYSQL_API.mysql_stmt_affected_rows     := GetAddress('mysql_stmt_affected_rows');\n  @MYSQL_API.mysql_stmt_attr_get          := GetAddress('mysql_stmt_attr_get');\n  @MYSQL_API.mysql_stmt_attr_set          := GetAddress('mysql_stmt_attr_set');\n  @MYSQL_API.mysql_stmt_bind_param        := GetAddress('mysql_stmt_bind_param');\n  @MYSQL_API.mysql_stmt_bind_result       := GetAddress('mysql_stmt_bind_result');\n  @MYSQL_API.mysql_stmt_close             := GetAddress('mysql_stmt_close');\n  @MYSQL_API.mysql_stmt_data_seek         := GetAddress('mysql_stmt_data_seek');\n  @MYSQL_API.mysql_stmt_errno             := GetAddress('mysql_stmt_errno');\n  @MYSQL_API.mysql_stmt_error             := GetAddress('mysql_stmt_error');\n  @MYSQL_API.mysql_stmt_execute           := GetAddress('mysql_stmt_execute');\n  @MYSQL_API.mysql_stmt_fetch             := GetAddress('mysql_stmt_fetch');\n  @MYSQL_API.mysql_stmt_fetch_column      := GetAddress('mysql_stmt_fetch_column');\n  @MYSQL_API.mysql_stmt_field_count       := GetAddress('mysql_stmt_field_count');\n  @MYSQL_API.mysql_stmt_free_result       := GetAddress('mysql_stmt_free_result');\n  @MYSQL_API.mysql_stmt_init              := GetAddress('mysql_stmt_init');\n  @MYSQL_API.mysql_stmt_insert_id         := GetAddress('mysql_stmt_insert_id');\n  @MYSQL_API.mysql_stmt_num_rows          := GetAddress('mysql_stmt_num_rows');\n  @MYSQL_API.mysql_stmt_param_count       := GetAddress('mysql_stmt_param_count');\n  @MYSQL_API.mysql_stmt_param_metadata    := GetAddress('mysql_stmt_param_metadata');\n  @MYSQL_API.mysql_stmt_prepare           := GetAddress('mysql_stmt_prepare');\n  @MYSQL_API.mysql_stmt_reset             := GetAddress('mysql_stmt_reset');\n  @MYSQL_API.mysql_stmt_result_metadata   := GetAddress('mysql_stmt_result_metadata');\n  @MYSQL_API.mysql_stmt_row_seek          := GetAddress('mysql_stmt_row_seek');\n  @MYSQL_API.mysql_stmt_row_tell          := GetAddress('mysql_stmt_row_tell');\n  @MYSQL_API.mysql_stmt_send_long_data    := GetAddress('mysql_stmt_send_long_data');\n  @MYSQL_API.mysql_stmt_sqlstate          := GetAddress('mysql_stmt_sqlstate');\n  @MYSQL_API.mysql_stmt_store_result      := GetAddress('mysql_stmt_store_result');\n  end;\nend;\n\nprocedure TZMySQLBaseDriver.BuildServerArguments(Options: TStrings);\nvar\n  TmpList: TStringList;\n  i: Integer;\nbegin\n  TmpList := TStringList.Create;\n  try\n    TmpList.Add(ParamStr(0));\n    for i := 0 to Options.Count - 1 do\n      if SameText(SERVER_ARGUMENTS_KEY_PREFIX,\n                  Copy(Options.Names[i], 1,\n                       Length(SERVER_ARGUMENTS_KEY_PREFIX))) then\n        TmpList.Add(Options.ValueFromIndex[i]);\n    //Check if DataDir is specified, if not, then add it to the Arguments List\n    if TmpList.Values['--datadir'] = '' then\n       TmpList.Add('--datadir='+EMBEDDED_DEFAULT_DATA_DIR);\n\n    for i := 0 to ServerArgsLen - 1 do\n      {$IFDEF WITH_STRDISPOSE_DEPRECATED}AnsiStrings.{$ENDIF}StrDispose(ServerArgs[i]);\n    ServerArgsLen := TmpList.Count;\n    SetLength(ServerArgs, ServerArgsLen);\n    for i := 0 to ServerArgsLen - 1 do\n      {$IFDEF UNICODE}\n      ServerArgs[i] := {$IFDEF WITH_STRNEW_DEPRECATED}AnsiStrings.{$ENDIF}StrNew(PAnsiChar(UTF8String(TmpList[i])));\n      {$ELSE}\n      ServerArgs[i] := StrNew(PAnsiChar(TmpList[i]));\n      {$ENDIF}\n  finally\n    TmpList.Free;\n  end;\nend;\n\nconstructor TZMySQLBaseDriver.Create(Tokenizer: IZTokenizer);\nbegin\n  inherited create;\n  FLoader := TZNativeLibraryLoader.Create([]);\n  FTokenizer := nil;\n  FTokenizer := Tokenizer;\n{$IFNDEF MYSQL_STRICT_DLL_LOADING}\n  {$IFNDEF UNIX}\n    FLoader.AddLocation(WINDOWS_DLL_LOCATION);\n  {$ELSE}\n    FLoader.AddLocation(LINUX_DLL_LOCATION);\n  {$ENDIF}\n{$ENDIF}\n  ServerArgsLen := 0;\n  SetLength(ServerArgs, ServerArgsLen);\n  IsEmbeddedDriver := False;\n  LoadCodePages;\nend;\n\ndestructor TZMySQLBaseDriver.Destroy;\nvar\n  i : integer;\nbegin\n  for i := 0 to ServerArgsLen - 1 do\n    {$IFDEF WITH_STRDISPOSE_DEPRECATED}AnsiStrings.{$ENDIF}StrDispose(ServerArgs[i]);\n\n  if (FLoader.Loaded) and (@MYSQL_API.mysql_server_end <> nil) then\n    MYSQL_API.mysql_server_end;\n\n  inherited Destroy;\nend;\n\nprocedure TZMySQLBaseDriver.Close(Handle: PZMySQLConnect);\nbegin\n  MYSQL_API.mysql_close(Handle);\nend;\n\nfunction TZMySQLBaseDriver.Connect(Handle: PZMySQLConnect; const Host,\n  User, Password: PAnsiChar): PZMySQLConnect;\nbegin\n  Result := MYSQL_API.mysql_connect(Handle, Host, User, Password);\nend;\n\nfunction TZMySQLBaseDriver.SslSet(Handle: PZMySQLConnect;\n  const Key, Cert, Ca, Capath, Cipher: PAnsiChar): Integer;\nbegin\n  Result := MYSQL_API.mysql_ssl_set(Handle, Key, Cert, Ca, Capath, Cipher);\nend;\n\nfunction TZMySQLBaseDriver.CreateDatabase(Handle: PZMySQLConnect;\n  const Database: PAnsiChar): Integer;\nbegin\n  Result := MYSQL_API.mysql_create_db(Handle, Database);\nend;\n\nprocedure TZMySQLBaseDriver.Debug(Debug: PAnsiChar);\nbegin\n  MYSQL_API.mysql_debug(Debug);\nend;\n\nfunction TZMySQLBaseDriver.DropDatabase(Handle: PZMySQLConnect;\n  const Database: PAnsiChar): Integer;\nbegin\n  Result := MYSQL_API.mysql_drop_db(Handle, Database);\nend;\n\nfunction TZMySQLBaseDriver.DumpDebugInfo(Handle: PZMySQLConnect): Integer;\nbegin\n  Result := MYSQL_API.mysql_dump_debug_info(Handle);\nend;\n\nfunction TZMySQLBaseDriver.ExecQuery(Handle: PZMySQLConnect;\n  const Query: PAnsiChar): Integer;\nbegin\n  Result := MYSQL_API.mysql_query(Handle, Query);\nend;\n\nfunction TZMySQLBaseDriver.ExecRealQuery(Handle: PZMySQLConnect;\n  const Query: PAnsiChar; Length: Integer): Integer;\nbegin\n  Result := MYSQL_API.mysql_real_query(Handle, Query, Length);\nend;\n\nfunction TZMySQLBaseDriver.FetchField(Res: PZMySQLResult): PZMySQLField;\nbegin\n  Result := MYSQL_API.mysql_fetch_field(Res);\nend;\n\nfunction TZMySQLBaseDriver.FetchLengths(Res: PZMySQLResult): PULong;\nbegin\n  Result := MYSQL_API.mysql_fetch_lengths(Res);\nend;\n\nfunction TZMySQLBaseDriver.FetchRow(Res: PZMySQLResult): PZMySQLRow;\nbegin\n  Result := MYSQL_API.mysql_fetch_row(Res);\nend;\n\nprocedure TZMySQLBaseDriver.FreeResult(Res: PZMySQLResult);\nbegin\n  MYSQL_API.mysql_free_result(Res);\nend;\n\nfunction TZMySQLBaseDriver.GetAffectedRows(Handle: PZMySQLConnect): Int64;\nbegin\n  Result := MYSQL_API.mysql_affected_rows(Handle);\nend;\n\n{**\n  EgonHugeist: Get CharacterSet of current Connection\n  Returns the default character set name for the current connection.\n}\nfunction TZMySQLBaseDriver.GetConnectionCharacterSet(Handle: PMYSQL): PAnsiChar;// char_set_name\nbegin\n  if Assigned(MYSQL_API.mysql_character_set_name) then\n    Result := MYSQL_API.mysql_character_set_name(Handle)\n  else\n    Result := '';\nend;\n\n{**\n  EgonHugeist: This function is used to set the default character set for the\n  current connection. The string csname specifies a valid character set name.\n  The connection collation becomes the default collation of the character set.\n  This function works like the SET NAMES statement, but also sets the value\n  of mysql->charset, and thus affects the character set\n  used by mysql_real_escape_string()\n}\nfunction TZMySQLBaseDriver.SetConnectionCharacterSet(Handle: PMYSQL;\n  const csname: PAnsiChar): Integer; // set_character_set Returns 0 if valid\nbegin\n  Result := MYSQL_API.mysql_set_character_set(Handle, csName);\nend;\n\nfunction TZMySQLBaseDriver.GetClientInfo: PAnsiChar;\nbegin\n  Result := MYSQL_API.mysql_get_client_info;\nend;\n\nfunction TZMySQLBaseDriver.EscapeString(Handle: Pointer; const Value: RawByteString;\n  ConSettings: PZConSettings; WasEncoded: Boolean = False): RawByteString;\nvar\n  Len, outlength: integer;\n  Outbuffer: RawByteString;\n  TempValue: RawByteString;\nbegin\n  {$IFDEF UNICODE}\n  TempValue := Value;\n  {$ELSE}\n  if WasEncoded then\n    TempValue := Value\n  else\n    TempValue := ZPlainString(Value, ConSettings); //check encoding too\n  {$ENDIF}\n  Len := Length(TempValue);\n  Setlength(Outbuffer,Len*2+1);\n  if Handle = nil then\n    OutLength := MYSQL_API.mysql_escape_string(PAnsiChar(OutBuffer), PAnsiChar(TempValue), Len)\n  else\n    OutLength := MYSQL_API.mysql_real_escape_string(Handle, PAnsiChar(OutBuffer), PAnsiChar(TempValue), Len);\n  Setlength(Outbuffer,OutLength);\n  Result := #39+Outbuffer+#39;\nend;\n\nfunction TZMySQLBaseDriver.GetHostInfo(Handle: PZMySQLConnect): PAnsiChar;\nbegin\n  Result := MYSQL_API.mysql_get_host_info(Handle);\nend;\n\nfunction TZMySQLBaseDriver.GetListDatabases(Handle: PZMySQLConnect;\n  Wild: PAnsiChar): PZMySQLResult;\nbegin\n  Result := MYSQL_API.mysql_list_dbs(Handle, Wild);\nend;\n\nfunction TZMySQLBaseDriver.GetListFields(Handle: PZMySQLConnect;\n  const Table, Wild: PAnsiChar): PZMySQLResult;\nbegin\n  Result := MYSQL_API.mysql_list_fields(Handle, Table, Wild);\nend;\n\nfunction TZMySQLBaseDriver.GetListProcesses(\n  Handle: PZMySQLConnect): PZMySQLResult;\nbegin\n  Result := MYSQL_API.mysql_list_processes(Handle);\nend;\n\nfunction TZMySQLBaseDriver.GetListTables(Handle: PZMySQLConnect;\n  const Wild: PAnsiChar): PZMySQLResult;\nbegin\n  Result := MYSQL_API.mysql_list_tables(Handle, Wild);\nend;\n\nfunction TZMySQLBaseDriver.GetNumRows(Res: PZMySQLResult): Int64;\nbegin\n    if (Res = nil) then\n        Result := 0\n    else\n        Result :=  MYSQL_API.mysql_num_rows (Res);\nend;\n\nfunction TZMySQLBaseDriver.GetProtoInfo(Handle: PZMySQLConnect): Cardinal;\nbegin\n  Result := MYSQL_API.mysql_get_proto_info(Handle);\nend;\n\nfunction TZMySQLBaseDriver.GetServerInfo(Handle: PZMySQLConnect): PAnsiChar;\nbegin\n  Result := MYSQL_API.mysql_get_server_info(Handle);\nend;\n\nfunction TZMySQLBaseDriver.GetStatInfo(Handle: PZMySQLConnect): PAnsiChar;\nbegin\n  Result := MYSQL_API.mysql_stat(Handle);\nend;\n\nfunction TZMySQLBaseDriver.GetThreadId(Handle: PZMySQLConnect): Cardinal;\nbegin\n  Result := MYSQL_API.mysql_thread_id(Handle);\nend;\n\nfunction TZMySQLBaseDriver.Init(const Handle: PZMySQLConnect): PZMySQLConnect;\nbegin\n  if @MYSQL_API.mysql_server_init <> nil then\n    MYSQL_API.mysql_server_init(ServerArgsLen, ServerArgs, @SERVER_GROUPS);\n  Result := MYSQL_API.mysql_init(Handle);\nend;\n\nfunction TZMySQLBaseDriver.GetLastInsertID(Handle: PZMySQLConnect): Int64;\nbegin\n    Result := MYSQL_API.mysql_insert_id(PMYSQL(Handle));\nend;\n\nprocedure TZMySQLBaseDriver.Despose(var Handle: PZMySQLConnect);\nbegin\n  Handle := nil;\nend;\n\nfunction TZMySQLBaseDriver.Kill(Handle: PZMySQLConnect; Pid: LongInt): Integer;\nbegin\n  Result := MYSQL_API.mysql_kill(Handle, Pid);\nend;\n\nfunction TZMySQLBaseDriver.Ping(Handle: PZMySQLConnect): Integer;\nbegin\n  Result := MYSQL_API.mysql_ping(Handle);\nend;\n\nfunction TZMySQLBaseDriver.RealConnect(Handle: PZMySQLConnect;\n  const Host, User, Password, Db: PAnsiChar; Port: Cardinal; UnixSocket: PAnsiChar;\n  ClientFlag: Cardinal): PZMySQLConnect;\nbegin\n  Result := MYSQL_API.mysql_real_connect(Handle, Host, User, Password, Db,\n    Port, UnixSocket, ClientFlag);\nend;\n\n{function TZMySQLBaseDriver.GetRealEscapeString(Handle: PZMySQLConnect; StrTo, StrFrom: PAnsiChar;\n  Length: Cardinal): Cardinal;\nbegin\n  Result := MYSQL_API.mysql_real_escape_string(Handle, StrTo, StrFrom, Length);\nend;}\n\nfunction TZMySQLBaseDriver.Refresh(Handle: PZMySQLConnect;\n  Options: Cardinal): Integer;\nbegin\n  Result := MYSQL_API.mysql_refresh(Handle, Options);\nend;\n\nprocedure TZMySQLBaseDriver.SeekData(Res: PZMySQLResult;\n  Offset: Cardinal);\nbegin\n  MYSQL_API.mysql_data_seek(Res, Offset);\nend;\n\nfunction TZMySQLBaseDriver.SeekField(Res: PZMySQLResult;\n  Offset: Cardinal): Cardinal;\nbegin\n  Result := MYSQL_API.mysql_field_seek(Res, Offset);\nend;\n\nfunction TZMySQLBaseDriver.SeekRow(Res: PZMySQLResult;\n  Row: PZMySQLRowOffset): PZMySQLRowOffset;\nbegin\n  Result := MYSQL_API.mysql_row_seek(Res, Row);\nend;\n\nfunction TZMySQLBaseDriver.SelectDatabase(Handle: PZMySQLConnect;\n  const Database: PAnsiChar): Integer;\nbegin\n  Result := MYSQL_API.mysql_select_db(Handle, Database);\nend;\n\nfunction TZMySQLBaseDriver.SetOptions(Handle: PZMySQLConnect;\n  Option: TMySQLOption; const Arg: Pointer): Integer;\nbegin\n  Result := MYSQL_API.mysql_options(Handle,TMySqlOption(Option), Arg);\nend;\n\nfunction TZMySQLBaseDriver.Shutdown(Handle: PZMySQLConnect; shutdown_level: TMysqlShutdownLevel = ZPlainMySqlConstants.SHUTDOWN_DEFAULT): Integer;\nbegin\n  Result := MYSQL_API.mysql_shutdown(Handle,shutdown_level);\nend;\n\nfunction TZMySQLBaseDriver.SetAutocommit(Handle: PZMySQLConnect; mode: Boolean): Boolean;\nbegin\n  Result := MYSQL_API.mysql_autocommit(PMYSQL(Handle), Byte(Ord(Mode))) = 0;\nend;\n\nfunction TZMySQLBaseDriver.Commit(Handle: PZMySQLConnect): Boolean;\nbegin\n  Result := MYSQL_API.mysql_commit(PMYSQL(Handle)) = 0;\nend;\n\nfunction TZMySQLBaseDriver.CheckAnotherRowset(Handle: PZMySQLConnect): Boolean;\nbegin\n  Result := MYSQL_API.mysql_more_results (PMYSQL(Handle)) <> 0;\nend;\n\nfunction TZMySQLBaseDriver.RetrieveNextRowset(Handle: PZMySQLConnect): Integer;\nbegin\n    Result := MYSQL_API.mysql_next_result (PMYSQL(Handle));\nend;\n\nfunction TZMySQLBaseDriver.Rollback (Handle: PZMySQLConnect): Boolean;\nbegin\n  Result := MYSQL_API.mysql_rollback(PMYSQL(Handle)) = 0;\nend;\n\nfunction TZMySQLBaseDriver.GetSQLState(Handle: PZMySQLConnect): AnsiString;\nbegin\n    Result := MYSQL_API.mysql_sqlstate (PMYSQL(Handle));\nend;\n\nfunction TZMySQLBaseDriver.StmtAttrSet(stmt: PZMySqlPrepStmt;\n  option: TMysqlStmtAttrType; arg: PAnsiChar): Byte;\nbegin\n  Result :=  MYSQL_API.mysql_stmt_attr_set(PMYSQL_STMT(stmt),option,arg);\nend;\n\nfunction TZMySQLBaseDriver.GetPreparedAffectedRows(Handle: PZMySqlPrepStmt): Int64;\nbegin\n    Result :=  MYSQL_API.mysql_stmt_affected_rows (PMYSQL_STMT(Handle));\nend;\n\nfunction TZMySQLBaseDriver.BindParameters(Handle: PZMySqlPrepStmt; bindArray: PZMysqlBindArray): Byte;\nbegin\n    Result := MYSQL_API.mysql_stmt_bind_param (PMYSQL_STMT(Handle), pointer(bindArray));\nend;\n\nfunction TZMySQLBaseDriver.BindResult(Handle: PZMySqlPrepStmt; bindArray: PZMysqlBindArray): Byte;\nbegin\n    Result := MYSQL_API.mysql_stmt_bind_result (PMYSQL_STMT(Handle), pointer(bindArray));\nend;\n\nfunction TZMySQLBaseDriver.ClosePrepStmt (PrepStmtHandle: PZMySqlPrepStmt): PZMySqlPrepStmt;\nbegin\n  if (MYSQL_API.mysql_stmt_close(PMYSQL_STMT(PrepStmtHandle)) = 0) then\n        Result := nil\n    else\n        Result := PrepStmtHandle;\nend;\n\nprocedure TZMySQLBaseDriver.SeekPreparedData(PrepStmtHandle: PZMySqlPrepStmt; Offset: Cardinal);\nbegin\n  MYSQL_API.mysql_stmt_data_seek(PMYSQL_STMT(PrepStmtHandle), Offset);\nend;\n\nfunction TZMySQLBaseDriver.GetLastPreparedErrorCode(Handle: PZMySqlPrepStmt):Integer;\nbegin\n    Result := MYSQL_API.mysql_stmt_errno(PMYSQL_STMT(Handle));\nend;\n\nfunction TZMySQLBaseDriver.GetLastPreparedError(Handle: PZMySqlPrepStmt):AnsiString;\nbegin\n    Result := MYSQL_API.mysql_stmt_error(PMYSQL_STMT(Handle));\nend;\n\nfunction TZMySQLBaseDriver.ExecuteStmt(Handle: PZMySqlPrepStmt): Integer;\nbegin\n    Result := MYSQL_API.mysql_stmt_execute (PMYSQL_STMT(Handle));\nend;\n\nfunction TZMySQLBaseDriver.FetchBoundResults(Handle: PZMySqlPrepStmt): Integer;\nbegin\n    Result := MYSQL_API.mysql_stmt_fetch (PMYSQL_STMT(Handle));\nend;\n\nfunction TZMySQLBaseDriver.GetPreparedFieldCount(Handle: PZMySqlPrepStmt): Integer;\nbegin\n    Result := MYSQL_API.mysql_stmt_field_count(PMYSQL_STMT(Handle));\nend;\n\nfunction TZMySQLBaseDriver.FreePreparedResult(Handle: PZMySqlPrepStmt): Byte;\nbegin\n   Result := MYSQL_API.mysql_stmt_free_result(PMYSQL_STMT(Handle));\nend;\n\nfunction TZMySQLBaseDriver.InitializePrepStmt (Handle: PZMySQLConnect): PZMySqlPrepStmt;\nbegin\n    Result := MYSQL_API.mysql_stmt_init(PMYSQL(Handle));\nend;\n\nfunction TZMySQLBaseDriver.GetPreparedInsertID(Handle: PZMySqlPrepStmt): Int64;\nbegin\n    Result := MYSQL_API.mysql_stmt_insert_id (PMYSQL_STMT(Handle));\nend;\n\nfunction TZMySQLBaseDriver.GetPreparedNextResult(Handle: PZMySqlPrepStmt): Integer;\nbegin\n    if (@MYSQL_API.mysql_stmt_next_result = nil) then\n        Result := -1  // Successful and there are no more results\n    else\n        Result :=  MYSQL_API.mysql_stmt_next_result (PMYSQL_STMT(Handle));\nend;\n\nfunction TZMySQLBaseDriver.GetPreparedNumRows(Handle: PZMySqlPrepStmt): Int64;\nbegin\n    if (Handle = nil) then\n        Result := 0\n    else\n        Result :=  MYSQL_API.mysql_stmt_num_rows (PMYSQL_STMT(Handle));\nend;\n\nfunction TZMySQLBaseDriver.GetPreparedBindMarkers (Handle: PZMySqlPrepStmt): Cardinal;\nbegin\n    Result := MYSQL_API.mysql_stmt_param_count (PMYSQL_STMT(Handle));\nend;\n\nfunction TZMySQLBaseDriver.GetStmtParamMetadata(PrepStmtHandle: PZMySqlPrepStmt): PZMySQLResult;\nbegin\n  Result := MYSQL_API.mysql_stmt_param_metadata(PMYSQL_STMT(PrepStmtHandle));\nend;\n\nfunction TZMySQLBaseDriver.PrepareStmt(PrepStmtHandle: PZMySqlPrepStmt; const Query: PAnsiChar; Length: Integer): Integer;\nbegin\n    Result := MYSQL_API.mysql_stmt_prepare(PMYSQL_STMT(PrepStmtHandle), Query, Length);\nend;\n\nfunction TZMySQLBaseDriver.GetPreparedMetaData (Handle: PZMySqlPrepStmt): PZMySQLResult;\nbegin\n    Result := MYSQL_API.mysql_stmt_result_metadata (PMYSQL_STMT(Handle));\nend;\n\nfunction TZMySQLBaseDriver.SeekPreparedRow(Handle: PZMySqlPrepStmt; Row: PZMySQLRowOffset): PZMySQLRowOffset;\nbegin\n    Result := MYSQL_API.mysql_stmt_row_seek (PMYSQL_STMT(Handle), Row);\nend;\n\nfunction TZMySQLBaseDriver.SendPreparedLongData(Handle: PZMySqlPrepStmt;\n  parameter_number: Cardinal; const data: PAnsiChar; length: Cardinal): Byte;\nbegin\n  Result := MYSQL_API.mysql_stmt_send_long_data(PMYSQL_STMT(Handle), parameter_number, data, length);\nend;\n\nfunction TZMySQLBaseDriver.GetPreparedSQLState(Handle: PZMySqlPrepStmt): PAnsiChar;\nbegin\n  Result := MYSQL_API.mysql_stmt_sqlstate (PMYSQL_STMT(Handle));\nend;\n\nfunction TZMySQLBaseDriver.StorePreparedResult (Handle: PZMySqlPrepStmt): Integer;\nbegin\n  Result := MYSQL_API.mysql_stmt_store_result (PMYSQL_STMT(Handle));\nend;\n\nprocedure TZMySQLBaseDriver.GetCharacterSetInfo(Handle: PZMySQLConnect; CharSetInfo: PMY_CHARSET_INFO);\nbegin\n    MYSQL_API.mysql_get_character_set_info(Handle, CharSetInfo);\nend;\n\nfunction TZMySQLBaseDriver.GetBindOffsets: MYSQL_BINDOFFSETS;\nvar\n  DriverVersion : Integer;\nbegin\n  DriverVersion:=GetClientVersion;\n  case DriverVersion of\n    40100..40199 : begin\n                     result.buffer_type   := NativeUint(@(PMYSQL_BIND41(nil).buffer_type));\n                     result.buffer_length := NativeUint(@(PMYSQL_BIND41(nil).buffer_length));\n                     result.is_unsigned   := NativeUint(@(PMYSQL_BIND41(nil).is_unsigned));\n                     result.buffer        := NativeUint(@(PMYSQL_BIND41(nil).buffer));\n                     result.length        := NativeUint(@(PMYSQL_BIND41(nil).length));\n                     result.is_null       := NativeUint(@(PMYSQL_BIND41(nil).is_null));\n                     result.size          := Sizeof(MYSQL_BIND41);\n                   end;\n    50000..50099 : begin\n                     result.buffer_type   := NativeUint(@(PMYSQL_BIND50(nil).buffer_type));\n                     result.buffer_length := NativeUint(@(PMYSQL_BIND50(nil).buffer_length));\n                     result.is_unsigned   := NativeUint(@(PMYSQL_BIND50(nil).is_unsigned));\n                     result.buffer        := NativeUint(@(PMYSQL_BIND50(nil).buffer));\n                     result.length        := NativeUint(@(PMYSQL_BIND50(nil).length));\n                     result.is_null       := NativeUint(@(PMYSQL_BIND50(nil).is_null));\n                     result.size          := Sizeof(MYSQL_BIND50);\n                   end;\n    50100..59999 : begin\n                     result.buffer_type   := NativeUint(@(PMYSQL_BIND51(nil).buffer_type));\n                     result.buffer_length := NativeUint(@(PMYSQL_BIND51(nil).buffer_length));\n                     result.is_unsigned   := NativeUint(@(PMYSQL_BIND51(nil).is_unsigned));\n                     result.buffer        := NativeUint(@(PMYSQL_BIND51(nil).buffer));\n                     result.length        := NativeUint(@(PMYSQL_BIND51(nil).length));\n                     result.is_null       := NativeUint(@(PMYSQL_BIND51(nil).is_null));\n                     result.size          := Sizeof(MYSQL_BIND51);\n                   end;\n    60000..60099 : begin\n                     result.buffer_type   := NativeUint(@(PMYSQL_BIND60(nil).buffer_type));\n                     result.buffer_length := NativeUint(@(PMYSQL_BIND60(nil).buffer_length));\n                     result.is_unsigned   := NativeUint(@(PMYSQL_BIND60(nil).is_unsigned));\n                     result.buffer        := NativeUint(@(PMYSQL_BIND60(nil).buffer));\n                     result.length        := NativeUint(@(PMYSQL_BIND60(nil).length));\n                     result.is_null       := NativeUint(@(PMYSQL_BIND60(nil).is_null));\n                     result.size          := Sizeof(MYSQL_BIND60);\n                   end;\n  else\n    result.buffer_type:=0;\n  end;\nend;\n\nfunction TZMySQLBaseDriver.StoreResult(\n  Handle: PZMySQLConnect): PZMySQLResult;\nbegin\n  Result := MYSQL_API.mysql_store_result(Handle);\nend;\n\nfunction TZMySQLBaseDriver.UseResult(Handle: PZMySQLConnect): PZMySQLResult;\nbegin\n  Result := MYSQL_API.mysql_use_result(Handle);\nend;\n\nfunction TZMySQLBaseDriver.GetLastError(Handle: PZMySQLConnect): PAnsiChar;\nbegin\n  Result := MYSQL_API.mysql_error(Handle);\nend;\n\nfunction TZMySQLBaseDriver.GetFieldType(Field: PZMySQLField): TMysqlFieldTypes;\nbegin\n  Result := PMYSQL_FIELD(Field)^._type;\nend;\n\nfunction TZMySQLBaseDriver.GetFieldFlags(Field: PZMySQLField): Integer;\nbegin\n  Result := PMYSQL_FIELD(Field)^.flags;\nend;\n\nfunction TZMySQLBaseDriver.GetRowCount(Res: PZMySQLResult): Int64;\nbegin\n  Result := MYSQL_API.mysql_num_rows(Res);\nend;\n\nfunction TZMySQLBaseDriver.ResultSetExists(Handle: PZMySQLConnect): Boolean;\nbegin\n result := MYSQL_API.mysql_field_count(Handle)<>0;\n // True If statement should return a resultset\nend;\n\nfunction TZMySQLBaseDriver.GetFieldCount(Res: PZMySQLResult): Integer;\nbegin\n  Result := MYSQL_API.mysql_num_fields(Res);\nend;\n\nfunction TZMySQLBaseDriver.GetFieldDecimals(Field: PZMySQLField): Integer;\nbegin\n  Result := PMYSQL_FIELD(Field)^.decimals;\nend;\n\nfunction TZMySQLBaseDriver.GetFieldCharsetNr(Field: PZMySQLField): UInt;\nbegin\n  Result := PMYSQL_FIELD(Field)^.charsetnr;\nend;\n\nfunction TZMySQLBaseDriver.GetFieldLength(Field: PZMySQLField): ULong;\nbegin\n  Result := PMYSQL_FIELD(Field)^.length;\nend;\n\nfunction TZMySQLBaseDriver.GetFieldMaxLength(Field: PZMySQLField): Integer;\nbegin\n  Result := PMYSQL_FIELD(Field)^.max_length;\nend;\n\nfunction TZMySQLBaseDriver.GetFieldName(Field: PZMySQLField): PAnsiChar;\nbegin\n  Result := PMYSQL_FIELD(Field)^.name;\nend;\n\nfunction TZMySQLBaseDriver.GetFieldTable(Field: PZMySQLField): PAnsiChar;\nbegin\n  Result := PMYSQL_FIELD(Field)^.table;\nend;\n\nfunction TZMySQLBaseDriver.GetFieldOrigTable(Field: PZMySQLField): PAnsiChar;\nbegin\n  Result := PMYSQL_FIELD(Field)^.org_table;\nend;\n\nfunction TZMySQLBaseDriver.GetFieldOrigName(Field: PZMySQLField): PAnsiChar;\nbegin\n  Result := PMYSQL_FIELD(Field)^.org_name;\nend;\n\nfunction TZMySQLBaseDriver.GetFieldData(Row: PZMySQLRow;\n  Offset: Cardinal): PAnsiChar;\nbegin\n  Result := PMYSQL_ROW(ROW)[Offset];\nend;\n\nfunction TZMySQLBaseDriver.GetLastErrorCode(Handle: PZMySQLConnect): Integer;\nbegin\n  Result := MYSQL_API.mysql_errno(PMYSQL(Handle));\nend;\n\nfunction TZMySQLBaseDriver.GetClientVersion: Integer;\nbegin\n Result := MYSQL_API.mysql_get_client_version;\nend;\n\nfunction TZMySQLBaseDriver.GetServerVersion(\n  Handle: PZMySQLConnect): Integer;\nbegin\n Result := MYSQL_API.mysql_get_server_version(Handle);\nend;\n\nprocedure TZMySQLBaseDriver.SetDriverOptions(Options: TStrings);\nvar\n  PreferedLibrary: String;\nbegin\n  PreferedLibrary := Options.Values['Library'];\n  if PreferedLibrary <> '' then\n    Loader.AddLocation(PreferedLibrary);\n  if IsEmbeddedDriver then\n    BuildServerArguments(Options);\nend;\n\n{ TZMySQL41PlainDriver }\n\nfunction TZMySQL41PlainDriver.Clone: IZPlainDriver;\nbegin\n  Result := TZMySQL41PlainDriver.Create(FTokenizer);\nend;\n\nconstructor TZMySQL41PlainDriver.Create(Tokenizer: IZTokenizer);\nbegin\n  inherited Create(Tokenizer);\n  {$IFNDEF UNIX}\n    FLoader.AddLocation(WINDOWS_DLL41_LOCATION);\n  {$ELSE}\n    FLoader.AddLocation(LINUX_DLL41_LOCATION);\n  {$ENDIF}\nend;\n\nfunction TZMySQL41PlainDriver.GetProtocol: string;\nbegin\n  Result := 'mysql-4.1';\nend;\n\nfunction TZMySQL41PlainDriver.GetDescription: string;\nbegin\n  Result := 'Native Plain Driver for MySQL 4.1+';\nend;\n\n{ TZMySQLD41PlainDriver }\n\nfunction TZMySQLD41PlainDriver.Clone: IZPlainDriver;\nbegin\n  Result := TZMySQLD41PlainDriver.Create(FTokenizer);\nend;\n\nconstructor TZMySQLD41PlainDriver.Create(Tokenizer: IZTokenizer);\nbegin\n  inherited Create(Tokenizer);\n  // only include embedded library\n  FLoader.ClearLocations;\n  {$IFNDEF MYSQL_STRICT_DLL_LOADING}\n  {$IFNDEF UNIX}\n    FLoader.AddLocation(WINDOWS_DLL_LOCATION_EMBEDDED);\n  {$ELSE}\n    FLoader.AddLocation(LINUX_DLL_LOCATION_EMBEDDED);\n  {$ENDIF}\n  {$ENDIF}\n  {$IFNDEF UNIX}\n    FLoader.AddLocation(WINDOWS_DLL41_LOCATION_EMBEDDED);\n  {$ELSE}\n    FLoader.AddLocation(LINUX_DLL41_LOCATION_EMBEDDED);\n  {$ENDIF}\n  IsEmbeddedDriver := True;\nend;\n\nfunction TZMySQLD41PlainDriver.GetProtocol: string;\nbegin\n  Result := 'mysqld-4.1';\nend;\n\nfunction TZMySQLD41PlainDriver.GetDescription: string;\nbegin\n  Result := 'Native Plain Driver for Embedded MySQL 4.1+';\nend;\n\n{ TZMySQL5PlainDriver }\n\nfunction TZMySQL5PlainDriver.Clone: IZPlainDriver;\nbegin\n  Result := TZMySQL5PlainDriver.Create(FTokenizer);\nend;\n\nprocedure TZMySQL5PlainDriver.LoadApi;\nbegin\n  inherited LoadApi;\n\n  with Loader do\n  begin\n    @MYSQL_API.mysql_get_character_set_info := GetAddress('mysql_get_character_set_info');\n    @MYSQL_API.mysql_stmt_next_result       := GetAddress('mysql_stmt_next_result');\n  end;\nend;\n\nprocedure TZMySQL5PlainDriver.LoadCodePages;\nbegin\n  inherited LoadCodePages;\n  {MySQL 4.1-5.5}\n  { MultiByte }\n  AddCodePage('utf8mb4', 37, ceUTF8, zCP_UTF8, '', 4); {UTF-8 Unicode}\n  AddCodePage('utf16', 38, ceUTF16, zCP_UTF16, 'utf8', 4); {UTF-16 Unicode}\n  AddCodePage('utf32', 39, ceUTF16, zCP_utf32, 'utf8', 4); {UTF-32 Unicode} //Egonhugeist improved\nend;\n\nconstructor TZMySQL5PlainDriver.Create(Tokenizer: IZTokenizer);\nbegin\n  inherited Create(Tokenizer);\n  {$IFNDEF UNIX}\n  {$IFNDEF MYSQL_STRICT_DLL_LOADING}\n    FLoader.AddLocation(MARIADB_LOCATION);\n  {$ENDIF}\n    FLoader.AddLocation(WINDOWS_DLL50_LOCATION);\n    FLoader.AddLocation(WINDOWS_DLL51_LOCATION);\n    FLoader.AddLocation(WINDOWS_DLL55_LOCATION);\n  {$ELSE}\n  {$IFNDEF MYSQL_STRICT_DLL_LOADING}\n    FLoader.AddLocation(MARIADB_LOCATION);\n  {$ENDIF}\n    FLoader.AddLocation(LINUX_DLL50_LOCATION);\n    FLoader.AddLocation(LINUX_DLL51_LOCATION);\n    FLoader.AddLocation(LINUX_DLL55_LOCATION);\n  {$ENDIF}\nend;\n\nfunction TZMySQL5PlainDriver.GetProtocol: string;\nbegin\n  Result := 'mysql-5';\nend;\n\nfunction TZMySQL5PlainDriver.GetDescription: string;\nbegin\n  Result := 'Native Plain Driver for MySQL 5.0+';\nend;\n\n{ TZMySQLD5PlainDriver }\n\nfunction TZMySQLD5PlainDriver.Clone: IZPlainDriver;\nbegin\n  Result := TZMySQLD5PlainDriver.Create(FTokenizer);\nend;\n\nconstructor TZMySQLD5PlainDriver.Create(Tokenizer: IZTokenizer);\nbegin\n  inherited Create(Tokenizer);\n  // only include embedded library\n  FLoader.ClearLocations;\n  {$IFNDEF MYSQL_STRICT_DLL_LOADING}\n  {$IFNDEF UNIX}\n    FLoader.AddLocation(WINDOWS_DLL_LOCATION_EMBEDDED);\n  {$ELSE}\n    FLoader.AddLocation(LINUX_DLL_LOCATION_EMBEDDED);\n  {$ENDIF}\n  {$ENDIF}\n  {$IFNDEF UNIX}\n    FLoader.AddLocation(WINDOWS_DLL50_LOCATION_EMBEDDED);\n    FLoader.AddLocation(WINDOWS_DLL51_LOCATION_EMBEDDED);\n    FLoader.AddLocation(WINDOWS_DLL55_LOCATION_EMBEDDED);\n  {$ELSE}\n    FLoader.AddLocation(LINUX_DLL50_LOCATION_EMBEDDED);\n    FLoader.AddLocation(LINUX_DLL51_LOCATION_EMBEDDED);\n    FLoader.AddLocation(LINUX_DLL55_LOCATION_EMBEDDED);\n  {$ENDIF}\n  IsEmbeddedDriver := True;\nend;\n\nfunction TZMySQLD5PlainDriver.GetProtocol: string;\nbegin\n  Result := 'mysqld-5';\nend;\n\nfunction TZMySQLD5PlainDriver.GetDescription: string;\nbegin\n  Result := 'Native Plain Driver for Embedded MySQL 5+';\nend;\n\n{ TZMariaDB5PlainDriver }\nfunction TZMariaDB5PlainDriver.Clone: IZPlainDriver;\nbegin\n  Result := TZMariaDB5PlainDriver.Create(FTokenizer);\nend;\n\nconstructor TZMariaDB5PlainDriver.Create(Tokenizer: IZTokenizer);\nbegin\n  inherited Create(Tokenizer);\n  FLoader.ClearLocations;\n  FLoader.AddLocation(MARIADB_LOCATION);\nend;\n\nfunction TZMariaDB5PlainDriver.GetProtocol: string;\nbegin\n  Result := 'MariaDB-5';\nend;\n\nfunction TZMariaDB5PlainDriver.GetDescription: string;\nbegin\n  Result := 'Native Plain Driver for MariaDB-5.x';\nend;\n\nend.\n\n\n"
  },
  {
    "path": "lib/zeosdbo/src/plain/ZPlainOracleConstants.pas",
    "content": "{*********************************************************}\n{                                                         }\n{                 Zeos Database Objects                   }\n{        Delphi interface to Oracle Call Interface        }\n{                                                         }\n{        Originally written by Sergey Seroukhov           }\n{                                                         }\n{*********************************************************}\n\n{@********************************************************}\n{    Copyright (c) 1999-2012 Zeos Development Group       }\n{                                                         }\n{ License Agreement:                                      }\n{                                                         }\n{ This library is distributed in the hope that it will be }\n{ useful, but WITHOUT ANY WARRANTY; without even the      }\n{ implied warranty of MERCHANTABILITY or FITNESS FOR      }\n{ A PARTICULAR PURPOSE.  See the GNU Lesser General       }\n{ Public License for more details.                        }\n{                                                         }\n{ The source code of the ZEOS Libraries and packages are  }\n{ distributed under the Library GNU General Public        }\n{ License (see the file COPYING / COPYING.ZEOS)           }\n{ with the following  modification:                       }\n{ As a special exception, the copyright holders of this   }\n{ library give you permission to link this library with   }\n{ independent modules to produce an executable,           }\n{ regardless of the license terms of these independent    }\n{ modules, and to copy and distribute the resulting       }\n{ executable under terms of your choice, provided that    }\n{ you also meet, for each linked independent module,      }\n{ the terms and conditions of the license of that module. }\n{ An independent module is a module which is not derived  }\n{ from or based on this library. If you modify this       }\n{ library, you may extend this exception to your version  }\n{ of the library, but you are not obligated to do so.     }\n{ If you do not wish to do so, delete this exception      }\n{ statement from your version.                            }\n{                                                         }\n{                                                         }\n{ The project web site is located on:                     }\n{   http://zeos.firmos.at  (FORUM)                        }\n{   http://sourceforge.net/p/zeoslib/tickets/ (BUGTRACKER)}\n{   svn://svn.code.sf.net/p/zeoslib/code-0/trunk (SVN)    }\n{                                                         }\n{   http://www.sourceforge.net/projects/zeoslib.          }\n{                                                         }\n{                                                         }\n{                                 Zeos Development Group. }\n{********************************************************@}\n\nunit ZPlainOracleConstants;\n\ninterface\n\n{$I ZPlain.inc}\n\n{$J+}\n\nuses\n  ZCompatibility;\n\n{***************** Plain API types definition ****************}\n\nconst\n  WINDOWS_DLL_LOCATION = 'oci.dll';\n//  WINDOWS_DLL_LOCATION = 'ora803.dll';\n  LINUX_DLL_LOCATION = 'libclntsh'+SharedSuffix;\n//  LINUX_DLL_LOCATION = 'libwtc8.so';\n\ntype\n  { Generic Oracle Types }\n  sword   = Integer;\n  psword  = ^sword;\n  eword   = Integer;\n  uword   = LongInt;\n  sb4     = Integer;\n  ub4     = LongInt;\n  sb2     = SmallInt;\n  ub2     = Word;\n  sb1     = ShortInt;\n  ub1     = Byte;\n  dvoid   = Pointer;\n  text    = PAnsiChar;\n  size_T  = NativeUInt;\n\n  pub1 = ^ub1;\n  psb1 = ^sb1;\n  pub2 = ^ub2;\n  psb2 = ^sb2;\n  pub4 = ^ub4;\n  psb4 = ^sb4;\n\n  { Handle Types }\n  POCIHandle = Pointer;\n  PPOCIHandle = ^Pointer;\n  POCIEnv = POCIHandle;\n  POCIServer = POCIHandle;\n  POCIError = POCIHandle;\n  POCISvcCtx = POCIHandle;\n  POCIStmt = POCIHandle;\n  POCIDefine = POCIHandle;\n  POCISession = POCIHandle;\n  POCIBind = POCIHandle;\n  POCIDescribe = POCIHandle;\n  POCITrans = POCIHandle;\n  POCITable = POCIHandle;\n  POCIIter = POCIHandle;\n  POCIType = Pointer;\n  PPOCIType = ^POCIType;\n  POCIInd = Pointer;\n  PPOCIInd = ^POCIInd;\n\n  POCITypeCode  = POCIHandle;\n  POCITypeElem  = POCIHandle;\n  POCITypeIter  = POCIHandle;\n  PPOCITypeIter = ^POCITypeIter;\n  POCITypeMethod  = POCIHandle;\n\n  OCITypeGetOpt = (\n    OCI_TYPEGET_HEADER,// load only the header portion of the TDO when getting type\n    OCI_TYPEGET_ALL  //load all attribute and method descriptors as well\n    );\n\n  { Descriptor Types }\n  POCIDescriptor = Pointer;\n  PPOCIDescriptor = ^POCIDescriptor;\n  POCISnapshot = POCIDescriptor;          //OCI snapshot descriptor\n  POCILobLocator = POCIDescriptor;        //OCI Lob Locator descriptor\n  POCIParam = POCIDescriptor;             //OCI Parameter descriptor\n  POCIRowid = POCIDescriptor;             //OCI ROWID descriptor\n  POCIComplexObjectComp = POCIDescriptor;\n  POCIAQEnqOptions = POCIDescriptor;\n  POCIAQDeqOptions = POCIDescriptor;\n  POCIAQMsgProperties = POCIDescriptor;\n  POCIAQAgent = POCIDescriptor;\n  POCIDateTime = POCIDescriptor;          //OCI DateTime descriptor\n  POCINumber = POCIDescriptor;\n  PPOCINumber = ^POCINumber;\n  POCIString = POCIDescriptor;\n  POCIInterval = POCIDescriptor;          //OCI Interval descriptor\n  POCIResult = POCIDescriptor;            //OCI Result Set Descriptor\n  PPOCITypeElem = PPOCIDescriptor;\n  PPOCITypeMethod = PPOCIDescriptor;\n\n  OCIDuration = ub2;       //enum!\n  POCIDuration = ^OCIDuration;\n  OCITypeEncap = ub2;      //enum!\n  OCITypeMethodFlag = ub2; //enum!\n  OCITypeParamMode = ub2;  //enum!\n  OCIObjectPropId = ub1;\n  OCIRefreshOpt = ub2;     //enum;\n\nconst\n  OCI_DURATION_INVALID = $FFFF;      { Invalid duration }\n  OCI_DURATION_BEGIN = 10;           { beginning sequence of duration }\n  OCI_DURATION_NULL = (OCI_DURATION_BEGIN-1); { null duration }\n  OCI_DURATION_DEFAULT = (OCI_DURATION_BEGIN-2); { default }\n  OCI_DURATION_USER_CALLBACK = (OCI_DURATION_BEGIN-3);\n  OCI_DURATION_NEXT = (OCI_DURATION_BEGIN-4); { next special duration }\n  OCI_DURATION_SESSION = (OCI_DURATION_BEGIN); { the end of user session }\n  OCI_DURATION_TRANS = (OCI_DURATION_BEGIN+1); { the end of user transaction }\n  OCI_DURATION_STATEMENT = (OCI_DURATION_BEGIN+3);\n{ This is to be used only during callouts.  It is similar to that\nof OCI_DURATION_CALL, but lasts only for the duration of a callout.\nIts heap is from PGA }\n  OCI_DURATION_CALLOUT = (OCI_DURATION_BEGIN+4);\n  OCI_DURATION_LAST = OCI_DURATION_CALLOUT; { last of predefined durations }\n\n  OCI_TEMP_BLOB     = 1; { LOB type - BLOB }\n  OCI_TEMP_CLOB     = 2; { LOB type - CLOB }\n\nconst\n  MAXTXNAMELEN    = 64;\n  XIDDATASIZE     = 128; { size in bytes }\n  MAXGTRIDSIZE    = 64;  { maximum size in bytes of gtrid }\n  MAXBQUALSIZE    = 64;  { maximum size in bytes of bqual }\n  NULLXID_ID      = -1;\n\n  { Transaction branch identification: XID and NULLXID: }\ntype\n  PXID = ^TXID;\n  TXID = record\n    formatID: sb4;     { format identifier }\n    gtrid_length: sb4; { value from 1 through 64 }\n    bqual_length: sb4; { value from 1 through 64 }\n    data: array [0 .. XIDDATASIZE - 1] of ub1;\n  end;\n\nconst\n  MAXUB4  = High(ub4);\n  MAXSB4  = High(sb4);\n\n{***************** Plain API constants definition ****************}\n\n  { OCI Handle Types }\n  OCI_HTYPE_FIRST               = 1;\n  OCI_HTYPE_ENV                 = 1;\n  OCI_HTYPE_ERROR               = 2;\n  OCI_HTYPE_SVCCTX              = 3;\n  OCI_HTYPE_STMT                = 4;\n  OCI_HTYPE_BIND                = 5;\n  OCI_HTYPE_DEFINE              = 6;\n  OCI_HTYPE_DESCRIBE            = 7;\n  OCI_HTYPE_SERVER              = 8;\n  OCI_HTYPE_SESSION             = 9;\n  OCI_HTYPE_TRANS               = 10;\n  OCI_HTYPE_COMPLEXOBJECT       = 11;\n  OCI_HTYPE_SECURITY            = 12;\n  OCI_HTYPE_SUBSCRIPTION        = 13;\n  OCI_HTYPE_DIRPATH_CTX         = 14;\n  OCI_HTYPE_DIRPATH_COLUMN_ARRAY = 15;\n  OCI_HTYPE_DIRPATH_STREAM      = 16;\n  OCI_HTYPE_PROC                = 17;\n  OCI_HTYPE_LAST                = 17;\n\n  { OCI Descriptor Types }\n  OCI_DTYPE_FIRST               = 50;\n  OCI_DTYPE_LOB                 = 50; //lob  locator\n  OCI_DTYPE_SNAP                = 51;\n  OCI_DTYPE_RSET                = 52;\n  OCI_DTYPE_PARAM               = 53; //a parameter descriptor obtained from ocigparm\n  OCI_DTYPE_ROWID               = 54;\n  OCI_DTYPE_COMPLEXOBJECTCOMP   = 55;\n  OCI_DTYPE_FILE                = 56; //File Lob locator\n  OCI_DTYPE_AQENQ_OPTIONS       = 57; //enqueue options\n  OCI_DTYPE_AQDEQ_OPTIONS       = 58; //dequeue options\n  OCI_DTYPE_AQMSG_PROPERTIES    = 59; //message properties\n  OCI_DTYPE_AQAGENT             = 60; //aq agent\n  OCI_DTYPE_LOCATOR             = 61;\n  OCI_DTYPE_INTERVAL_YM         = 62; //Interval year month\n  OCI_DTYPE_INTERVAL_DS         = 63; //Interval day second\n  OCI_DTYPE_AQNFY_DESCRIPTOR    = 64;\n  OCI_DTYPE_LAST                = 64;\n  OCI_DTYPE_DATE                = 65;  { Date }\n  OCI_DTYPE_TIME                = 66;  { Time }\n  OCI_DTYPE_TIME_TZ             = 67;  { Time with timezone }\n  OCI_DTYPE_TIMESTAMP           = 68;  { Timestamp }\n  OCI_DTYPE_TIMESTAMP_TZ        = 69;  { Timestamp with timezone }\n  OCI_DTYPE_TIMESTAMP_LTZ       = 70;  { Timestamp with local tz }\n\n  { OCI Attributes Types }\n  OCI_ATTR_FNCODE               = 1;   // the OCI function code\n  OCI_ATTR_OBJECT               = 2;   // is the environment initialized in object mode\n  OCI_ATTR_NONBLOCKING_MODE     = 3;   // non blocking mode\n  OCI_ATTR_SQLCODE              = 4;   // the SQL verb\n  OCI_ATTR_ENV                  = 5;   // the environment handle\n  OCI_ATTR_SERVER               = 6;   // the server handle\n  OCI_ATTR_SESSION              = 7;   // the user session handle\n  OCI_ATTR_TRANS                = 8;   // the transaction handle\n  OCI_ATTR_ROW_COUNT            = 9;   // the rows processed so far\n  OCI_ATTR_SQLFNCODE            = 10;  // the SQL verb of the statement\n  OCI_ATTR_PREFETCH_ROWS        = 11;  // sets the number of rows to prefetch\n  OCI_ATTR_NESTED_PREFETCH_ROWS = 12;  // the prefetch rows of nested table\n  OCI_ATTR_PREFETCH_MEMORY      = 13;  // memory limit for rows fetched\n  OCI_ATTR_NESTED_PREFETCH_MEMORY = 14;// memory limit for nested rows\n  OCI_ATTR_CHAR_COUNT           = 15;  // this specifies the bind and define size in characters\n  OCI_ATTR_PDSCL                = 16;  // packed decimal scale\n  OCI_ATTR_FSPRECISION          = OCI_ATTR_PDSCL; // fs prec for datetime data types\n  OCI_ATTR_PDPRC                = 17;  // packed decimal format\n  OCI_ATTR_LFPRECISION          = OCI_ATTR_PDPRC; // fs prec for datetime data types\n  OCI_ATTR_PARAM_COUNT          = 18;  // number of column in the select list\n  OCI_ATTR_ROWID                = 19;  // the rowid\n  OCI_ATTR_CHARSET              = 20;  // the character set value\n  OCI_ATTR_NCHAR                = 21;  // NCHAR type\n  OCI_ATTR_USERNAME             = 22;  // username attribute\n  OCI_ATTR_PASSWORD             = 23;  // password attribute\n  OCI_ATTR_STMT_TYPE            = 24;  // statement type\n  OCI_ATTR_INTERNAL_NAME        = 25;  // user friendly global name\n  OCI_ATTR_EXTERNAL_NAME        = 26;  // the internal name for global txn\n  OCI_ATTR_XID                  = 27;  // XOPEN defined global transaction id\n  OCI_ATTR_TRANS_LOCK           = 28;  //\n  OCI_ATTR_TRANS_NAME           = 29;  // string to identify a global transaction\n  OCI_ATTR_HEAPALLOC            = 30;  // memory allocated on the heap\n  OCI_ATTR_CHARSET_ID           = 31;  // Character Set ID\n  OCI_ATTR_CHARSET_FORM         = 32;  // Character Set Form\n  OCI_ATTR_MAXDATA_SIZE         = 33;  // Maximumsize of data on the server\n  OCI_ATTR_CACHE_OPT_SIZE       = 34;  // object cache optimal size\n  OCI_ATTR_CACHE_MAX_SIZE       = 35;  // object cache maximum size percentage\n  OCI_ATTR_PINOPTION            = 36;  // object cache default pin option\n  OCI_ATTR_ALLOC_DURATION       = 37;  // object cache default allocation duration\n  OCI_ATTR_PIN_DURATION         = 38;  // object cache default pin duration\n  OCI_ATTR_FDO                  = 39;  // Format Descriptor object attribute\n  OCI_ATTR_POSTPROCESSING_CALLBACK = 40;  // Callback to process outbind data\n  OCI_ATTR_POSTPROCESSING_CONTEXT = 41; // Callback context to process outbind data\n  OCI_ATTR_ROWS_RETURNED        = 42;  // Number of rows returned in current iter - for Bind handles\n  OCI_ATTR_FOCBK                = 43;  // Failover Callback attribute\n  OCI_ATTR_IN_V8_MODE           = 44;  // is the server/service context in V8 mode\n  OCI_ATTR_LOBEMPTY             = 45;  // empty lob ?\n  OCI_ATTR_SESSLANG             = 46;  // session language handle\n\n  OCI_ATTR_VISIBILITY           = 47;  // visibility\n  OCI_ATTR_RELATIVE_MSGID       = 48;  // relative message id\n  OCI_ATTR_SEQUENCE_DEVIATION   = 49;  // sequence deviation\n\n  OCI_ATTR_CONSUMER_NAME        = 50;  // consumer name\n  OCI_ATTR_DEQ_MODE             = 51;  // dequeue mode\n  OCI_ATTR_NAVIGATION           = 52;  // navigation\n  OCI_ATTR_WAIT                 = 53;  // wait\n  OCI_ATTR_DEQ_MSGID            = 54;  // dequeue message id\n\n  OCI_ATTR_PRIORITY             = 55;  // priority\n  OCI_ATTR_DELAY                = 56;  // delay\n  OCI_ATTR_EXPIRATION           = 57;  // expiration\n  OCI_ATTR_CORRELATION          = 58;  // correlation id\n  OCI_ATTR_ATTEMPTS             = 59;  // # of attempts\n  OCI_ATTR_RECIPIENT_LIST       = 60;  // recipient list\n  OCI_ATTR_EXCEPTION_QUEUE      = 61;  // exception queue name\n  OCI_ATTR_ENQ_TIME             = 62;  // enqueue time (only OCIAttrGet)\n  OCI_ATTR_MSG_STATE            = 63;  // message state (only OCIAttrGet)\n                                       // NOTE: 64-66 used below\n  OCI_ATTR_AGENT_NAME           = 64;  // agent name\n  OCI_ATTR_AGENT_ADDRESS        = 65;  // agent address\n  OCI_ATTR_AGENT_PROTOCOL       = 66;  // agent protocol\n\n  OCI_ATTR_SENDER_ID            = 68;  // sender id\n  OCI_ATTR_ORIGINAL_MSGID       = 69;  // original message id\n\n  OCI_ATTR_QUEUE_NAME           = 70;  // queue name\n  OCI_ATTR_NFY_MSGID            = 71;  // message id\n  OCI_ATTR_MSG_PROP             = 72;  // message properties\n\n  OCI_ATTR_NUM_DML_ERRORS       = 73;  // num of errs in array DML\n  OCI_ATTR_DML_ROW_OFFSET       = 74;  // row offset in the array\n\n  OCI_ATTR_DATEFORMAT           = 75;  // default date format string\n  OCI_ATTR_BUF_ADDR             = 76;  // buffer address\n  OCI_ATTR_BUF_SIZE             = 77;  // buffer size\n  OCI_ATTR_DIRPATH_MODE         = 78;  // mode of direct path operation\n  OCI_ATTR_DIRPATH_NOLOG        = 79;  // nologging option\n  OCI_ATTR_DIRPATH_PARALLEL     = 80;  // parallel (temp seg) option\n  OCI_ATTR_NUM_ROWS             = 81;  // number of rows in column array\n                                       // NOTE that OCI_ATTR_NUM_COLS is a column\n                                       // array attribute too.\n\n  OCI_ATTR_COL_COUNT            = 82;  // columns of column array processed so far.\n  OCI_ATTR_STREAM_OFFSET        = 83;  // str off of last row processed\n  OCI_ATTR_SHARED_HEAPALLOC     = 84;  // Shared Heap Allocation Size\n\n  OCI_ATTR_SERVER_GROUP         = 85;  // server group name\n\n  OCI_ATTR_MIGSESSION           = 86;  // migratable session attribute\n\n  OCI_ATTR_NOCACHE              = 87;  // Temporary LOBs\n\n  OCI_ATTR_MEMPOOL_SIZE         = 88;  // Pool Size\n  OCI_ATTR_MEMPOOL_INSTNAME     = 89;  // Instance name\n  OCI_ATTR_MEMPOOL_APPNAME      = 90;  // Application name\n  OCI_ATTR_MEMPOOL_HOMENAME     = 91;  // Home Directory name\n  OCI_ATTR_MEMPOOL_MODEL        = 92;  // Pool Model (proc,thrd,both)\n  OCI_ATTR_MODES                = 93;  // Modes\n\n  OCI_ATTR_SUBSCR_NAME          = 94;  // name of subscription\n  OCI_ATTR_SUBSCR_CALLBACK      = 95;  // associated callback\n  OCI_ATTR_SUBSCR_CTX           = 96;  // associated callback context\n  OCI_ATTR_SUBSCR_PAYLOAD       = 97;  // associated payload\n  OCI_ATTR_SUBSCR_NAMESPACE     = 98;  // associated namespace\n\n  OCI_ATTR_PROXY_CREDENTIALS    = 99;  // Proxy user credentials\n  OCI_ATTR_INITIAL_CLIENT_ROLES = 100; // Initial client role list\n\n  OCI_ATTR_UNK                  = 101; // unknown attribute\n  OCI_ATTR_NUM_COLS             = 102; // number of columns\n  OCI_ATTR_LIST_COLUMNS         = 103; // parameter of the column list\n  OCI_ATTR_RDBA                 = 104; // DBA of the segment header\n  OCI_ATTR_CLUSTERED            = 105; // whether the table is clustered\n  OCI_ATTR_PARTITIONED          = 106; // whether the table is partitioned\n  OCI_ATTR_INDEX_ONLY           = 107; // whether the table is index only\n  OCI_ATTR_LIST_ARGUMENTS       = 108; // parameter of the argument list\n  OCI_ATTR_LIST_SUBPROGRAMS     = 109; // parameter of the subprogram list\n  OCI_ATTR_REF_TDO              = 110; // REF to the type descriptor\n  OCI_ATTR_LINK                 = 111; // the database link name\n  OCI_ATTR_MIN                  = 112; // minimum value\n  OCI_ATTR_MAX                  = 113; // maximum value\n  OCI_ATTR_INCR                 = 114; // increment value\n  OCI_ATTR_CACHE                = 115; // number of sequence numbers cached\n  OCI_ATTR_ORDER                = 116; // whether the sequence is ordered\n  OCI_ATTR_HW_MARK              = 117; // high-water mark\n  OCI_ATTR_TYPE_SCHEMA          = 118; // type's schema name\n  OCI_ATTR_TIMESTAMP            = 119; // timestamp of the object\n  OCI_ATTR_NUM_ATTRS            = 120; // number of sttributes\n  OCI_ATTR_NUM_PARAMS           = 121; // number of parameters\n  OCI_ATTR_OBJID                = 122; // object id for a table or view\n  OCI_ATTR_PTYPE                = 123; // type of info described by\n  OCI_ATTR_PARAM                = 124; // parameter descriptor\n  OCI_ATTR_OVERLOAD_ID          = 125; // overload ID for funcs and procs\n  OCI_ATTR_TABLESPACE           = 126; // table name space\n  OCI_ATTR_TDO                  = 127; // TDO of a type\n  OCI_ATTR_LTYPE                = 128; // list type\n  OCI_ATTR_PARSE_ERROR_OFFSET   = 129; // Parse Error offset\n  OCI_ATTR_IS_TEMPORARY         = 130; // whether table is temporary\n  OCI_ATTR_IS_TYPED             = 131; // whether table is typed\n  OCI_ATTR_DURATION             = 132; // duration of temporary table\n  OCI_ATTR_IS_INVOKER_RIGHTS    = 133; // is invoker rights\n  OCI_ATTR_OBJ_NAME             = 134; // top level schema obj name\n  OCI_ATTR_OBJ_SCHEMA           = 135; // schema name\n  OCI_ATTR_OBJ_ID               = 136; // top level schema object id\n\n  // for inheritance - part 2\n  OCI_ATTR_IS_FINAL_TYPE        = 279; //is final type ?\n  OCI_ATTR_IS_INSTANTIABLE_TYPE = 280; //is instantiable type ?\n  OCI_ATTR_IS_FINAL_METHOD      = 281; //is final method ?\n  OCI_ATTR_IS_INSTANTIABLE_METHOD = 282; // is instantiable method ?\n  OCI_ATTR_IS_OVERRIDING_METHOD = 283; // is overriding method ?\n\n  OCI_ATTR_DESC_SYNBASE         = 284; //Describe the base object\n\n  OCI_ATTR_CHAR_USED            = 285; //char length semantics\n  OCI_ATTR_CHAR_SIZE            = 286; //char length\n\n  { OCI Error Return Values }\n  OCI_SUCCESS             = 0;\n  OCI_SUCCESS_WITH_INFO   = 1;\n  OCI_NO_DATA             = 100;\n  OCI_ERROR               = -1;\n  OCI_INVALID_HANDLE      = -2;\n  OCI_NEED_DATA           = 99;\n  OCI_STILL_EXECUTING     = -3123;\n  OCI_CONTINUE            = -24200;\n\n  { Generic Default Value for Modes, .... }\n  OCI_DEFAULT     = $0;\n\n  { OCI Init Mode }\n  OCI_THREADED    = $1;\n  OCI_OBJECT      = $2;\n  OCI_EVENTS      = $4;\n  OCI_SHARED      = $10;\n  OCI_NO_UCB      = $40;\n  OCI_NO_MUTEX    = $80;\n\n  { OCI Credentials }\n  OCI_CRED_RDBMS  = 1;\n  OCI_CRED_EXT    = 2;\n  OCI_CRED_PROXY  = 3;\n\n  { OCI Authentication Mode }\n  OCI_MIGRATE     = $0001;             // migratable auth context\n  OCI_SYSDBA      = $0002;             // for SYSDBA authorization\n  OCI_SYSOPER     = $0004;             // for SYSOPER authorization\n  OCI_PRELIM_AUTH = $0008;             // for preliminary authorization\n\n  { OCIPasswordChange }\n  OCI_AUTH        = $08;               // Change the password but do not login\n\n  { OCI Data Types }\n  SQLT_CHR = 1  ;       //(ORANET TYPE) character string\n  SQLT_NUM = 2  ;       //(ORANET TYPE) oracle numeric\n  SQLT_INT = 3  ;       //(ORANET TYPE) integer\n  SQLT_FLT = 4  ;       //(ORANET TYPE) Floating point number\n  SQLT_STR = 5  ;       //zero terminated string\n  SQLT_VNU = 6  ;       //NUM with preceding length byte\n  SQLT_PDN = 7  ;       //(ORANET TYPE) Packed Decimal Numeric\n  SQLT_LNG = 8  ;       //long\n  SQLT_VCS = 9  ;       //Variable character string\n  SQLT_NON = 10 ;       //Null/empty PCC Descriptor entry\n  SQLT_RID = 11 ;       //rowid\n  SQLT_DAT = 12 ;       //date in oracle format\n  SQLT_VBI = 15 ;       //binary in VCS format\n  SQLT_BFLOAT = 21 ;    //Native Binary float\n  SQLT_BDOUBLE = 22 ;   //NAtive binary double\n  SQLT_BIN = 23 ;       //binary data(DTYBIN)\n  SQLT_LBI = 24 ;       //long binary\n  _SQLT_PLI = 29;\n  SQLT_UIN = 68 ;       //unsigned integer\n  SQLT_SLS = 91 ;       //Display sign leading separate\n  SQLT_LVC = 94 ;       //Longer longs (char)\n  SQLT_LVB = 95 ;       //Longer long binary\n  SQLT_AFC = 96 ;       //Ansi fixed char\n  SQLT_AVC = 97 ;       //Ansi Var char\n  SQLT_IBFLOAT = 100;   //binary float canonical\n  SQLT_IBDOUBLE = 101;  //binary double canonical\n  SQLT_CUR = 102;       //cursor  type\n  SQLT_RDD = 104;       //rowid descriptor\n  SQLT_LAB = 105;       //label type\n  SQLT_OSL = 106;       //oslabel type\n  SQLT_NTY = 108;       //named object type\n  SQLT_REF = 110;       //ref typ\n  SQLT_CLOB = 112;      //character lob\n  SQLT_BLOB = 113;      //binary lob\n  SQLT_BFILEE = 114;    //binary file lob\n  SQLT_CFILEE = 115;    //character file lob\n  SQLT_RSET = 116;      //result set type\n  SQLT_NCO = 122;       //named collection type (varray or nested table)\n  SQLT_VST = 155;       //OCIString type\n  SQLT_ODT = 156;       //OCIDate type\n\n  { datetimes and intervals }\n  SQLT_DATE = 184;            //ANSI Date\n  SQLT_TIME = 185;            //TIME\n  SQLT_TIME_TZ = 186;         //TIME WITH TIME ZONE\n  SQLT_TIMESTAMP = 187;       //TIMESTAMP\n  SQLT_TIMESTAMP_TZ = 188;    //TIMESTAMP WITH TIME ZONE\n  SQLT_INTERVAL_YM = 189;     //INTERVAL YEAR TO MONTH\n  SQLT_INTERVAL_DS = 190;     //INTERVAL DAY TO SECOND\n  SQLT_TIMESTAMP_LTZ = 232;   //TIMESTAMP WITH LOCAL TZ\n\n  _SQLT_REC = 250;\n  _SQLT_TAB = 251;\n  _SQLT_BOL = 252;\n\n  { > typecode defines from oro.h }\n  OCI_TYPECODE_REF              = SQLT_REF; //SQL/OTS OBJECT REFERENCE\n  OCI_TYPECODE_VARRAY           = 247;      //SQL VARRAY  OTS PAGED VARRAY\n  OCI_TYPECODE_TABLE            = 248;      //SQL TABLE  OTS MULTISET\n  OCI_TYPECODE_OBJECT           = SQLT_NTY; //SQL/OTS NAMED OBJECT TYPE\n  OCI_TYPECODE_OPAQUE           = 58;       //SQL/OTS Opaque Types\n  OCI_TYPECODE_NAMEDCOLLECTION  = SQLT_NCO;\n\n  { OCI Statement Types }\n  OCI_STMT_SELECT  = 1;   // select statement\n  OCI_STMT_UPDATE  = 2;   // update statement\n  OCI_STMT_DELETE  = 3;   // delete statement\n  OCI_STMT_INSERT  = 4;   // Insert Statement\n  OCI_STMT_CREATE  = 5;   // create statement\n  OCI_STMT_DROP    = 6;   // drop statement\n  OCI_STMT_ALTER   = 7;   // alter statement\n  OCI_STMT_BEGIN   = 8;   // begin ... (pl/sql statement)\n  OCI_STMT_DECLARE = 9;   // declare .. (pl/sql statement)\n\n  { OCI Statement language }\n  OCI_NTV_SYNTAX  = 1;    // Use what so ever is the native lang of server\n  OCI_V7_SYNTAX   = 2;    // V7 language\n  OCI_V8_SYNTAX   = 3;    // V8 language\n\n  { OCI Statement Execute mode }\n  OCI_BATCH_MODE        = $01;    // batch the oci statement for execution\n  OCI_EXACT_FETCH       = $02;    // fetch the exact rows specified\n  OCI_SCROLLABLE_CURSOR = $08;    // cursor scrollable\n  OCI_DESCRIBE_ONLY     = $10;    // only describe the statement\n  OCI_COMMIT_ON_SUCCESS = $20;    // commit, if successful execution\n  OCI_NON_BLOCKING      = $40;    // non-blocking\n  OCI_BATCH_ERRORS      = $80;    // batch errors in array dmls\n  OCI_PARSE_ONLY        = $100;   // only parse the statement\n\n  OCI_DATA_AT_EXEC    = $02;      // data at execute time\n  OCI_DYNAMIC_FETCH   = $02;      // fetch dynamically\n  OCI_PIECEWISE       = $04;      // piecewise DMLs or fetch\n\n  { OCI Transaction modes }\n  OCI_TRANS_NEW          = $00000001; // starts a new transaction branch\n  OCI_TRANS_JOIN         = $00000002; // join an existing transaction\n  OCI_TRANS_RESUME       = $00000004; // resume this transaction\n  OCI_TRANS_STARTMASK    = $000000ff;\n\n  OCI_TRANS_READONLY     = $00000100; // starts a readonly transaction\n  OCI_TRANS_READWRITE    = $00000200; // starts a read-write transaction\n  OCI_TRANS_SERIALIZABLE = $00000400; // starts a serializable transaction\n  OCI_TRANS_ISOLMASK     = $0000ff00;\n\n  OCI_TRANS_LOOSE        = $00010000; // a loosely coupled branch\n  OCI_TRANS_TIGHT        = $00020000; // a tightly coupled branch\n  OCI_TRANS_TYPEMASK     = $000f0000;\n\n  OCI_TRANS_NOMIGRATE    = $00100000; // non migratable transaction\n  OCI_TRANS_TWOPHASE     = $01000000; // use two phase commit\n\n  { OCI pece wise fetch }\n  OCI_ONE_PIECE       = 0; // one piece\n  OCI_FIRST_PIECE     = 1; // the first piece\n  OCI_NEXT_PIECE      = 2; // the next of many pieces\n  OCI_LAST_PIECE      = 3; // the last piece\n\n  { OCI fetch modes }\n  OCI_FETCH_NEXT      = $02;  // next row\n  OCI_FETCH_FIRST     = $04;  // first row of the result set\n  OCI_FETCH_LAST      = $08;  // the last row of the result set\n  OCI_FETCH_PRIOR     = $10;  // the previous row relative to current\n  OCI_FETCH_ABSOLUTE  = $20;  // absolute offset from first\n  OCI_FETCH_RELATIVE  = $40;  // offset relative to current\n\n  {****************** Describe Handle Parameter Attributes *****************}\n\n  { Attributes common to Columns and Stored Procs }\n  OCI_ATTR_DATA_SIZE      = 1;    // maximum size of the data\n  OCI_ATTR_DATA_TYPE      = 2;    // the SQL type of the column/argument\n  OCI_ATTR_DISP_SIZE      = 3;    // the display size\n  OCI_ATTR_NAME           = 4;    // the name of the column/argument\n  OCI_ATTR_PRECISION      = 5;    // precision if number type\n  OCI_ATTR_SCALE          = 6;    // scale if number type\n  OCI_ATTR_IS_NULL        = 7;    // is it null ?\n  OCI_ATTR_TYPE_NAME      = 8;    // name of the named data type or a package name for package private types\n  OCI_ATTR_SCHEMA_NAME    = 9;    // the schema name\n  OCI_ATTR_SUB_NAME       = 10;   // type name if package private type\n  OCI_ATTR_POSITION       = 11;   // relative position of col/arg in the list of cols/args\n\n  { complex object retrieval parameter attributes }\n  OCI_ATTR_COMPLEXOBJECTCOMP_TYPE         = 50;\n  OCI_ATTR_COMPLEXOBJECTCOMP_TYPE_LEVEL   = 51;\n  OCI_ATTR_COMPLEXOBJECT_LEVEL            = 52;\n  OCI_ATTR_COMPLEXOBJECT_COLL_OUTOFLINE   = 53;\n\n  { Only Columns }\n  OCI_ATTR_DISP_NAME                 = 100;  // the display name\n\n  { Only Stored Procs }\n  OCI_ATTR_OVERLOAD                  = 210;  // is this position overloaded\n  OCI_ATTR_LEVEL                     = 211;  // level for structured types\n  OCI_ATTR_HAS_DEFAULT               = 212;  // has a default value\n  OCI_ATTR_IOMODE                    = 213;  // in, out inout\n  OCI_ATTR_RADIX                     = 214;  // returns a radix\n  OCI_ATTR_NUM_ARGS                  = 215;  // total number of arguments\n\n  { only named type attributes }\n  OCI_ATTR_TYPECODE                  = 216;   // object or collection\n  OCI_ATTR_COLLECTION_TYPECODE       = 217;   // varray or nested table\n  OCI_ATTR_VERSION                   = 218;   // user assigned version\n  OCI_ATTR_IS_INCOMPLETE_TYPE        = 219;   // is this an incomplete type\n  OCI_ATTR_IS_SYSTEM_TYPE            = 220;   // a system type\n  OCI_ATTR_IS_PREDEFINED_TYPE        = 221;   // a predefined type\n  OCI_ATTR_IS_TRANSIENT_TYPE         = 222;   // a transient type\n  OCI_ATTR_IS_SYSTEM_GENERATED_TYPE  = 223;   // system generated type\n  OCI_ATTR_HAS_NESTED_TABLE          = 224;   // contains nested table attr\n  OCI_ATTR_HAS_LOB                   = 225;   // has a lob attribute\n  OCI_ATTR_HAS_FILE                  = 226;   // has a file attribute\n  OCI_ATTR_COLLECTION_ELEMENT        = 227;   // has a collection attribute\n  OCI_ATTR_NUM_TYPE_ATTRS            = 228;   // number of attribute types\n  OCI_ATTR_LIST_TYPE_ATTRS           = 229;   // list of type attributes\n  OCI_ATTR_NUM_TYPE_METHODS          = 230;   // number of type methods\n  OCI_ATTR_LIST_TYPE_METHODS         = 231;   // list of type methods\n  OCI_ATTR_MAP_METHOD                = 232;   // map method of type\n  OCI_ATTR_ORDER_METHOD              = 233;   // order method of type\n\n  { only collection element }\n  OCI_ATTR_NUM_ELEMS                 = 234;   // number of elements\n\n  { only type methods }\n  OCI_ATTR_ENCAPSULATION             = 235;   // encapsulation level\n  OCI_ATTR_IS_SELFISH                = 236;   // method selfish\n  OCI_ATTR_IS_VIRTUAL                = 237;   // virtual\n  OCI_ATTR_IS_INLINE                 = 238;   // inline\n  OCI_ATTR_IS_CONSTANT               = 239;   // constant\n  OCI_ATTR_HAS_RESULT                = 240;   // has result\n  OCI_ATTR_IS_CONSTRUCTOR            = 241;   // constructor\n  OCI_ATTR_IS_DESTRUCTOR             = 242;   // destructor\n  OCI_ATTR_IS_OPERATOR               = 243;   // operator\n  OCI_ATTR_IS_MAP                    = 244;   // a map method\n  OCI_ATTR_IS_ORDER                  = 245;   // order method\n  OCI_ATTR_IS_RNDS                   = 246;   // read no data state method\n  OCI_ATTR_IS_RNPS                   = 247;   // read no process state\n  OCI_ATTR_IS_WNDS                   = 248;   // write no data state method\n  OCI_ATTR_IS_WNPS                   = 249;   // write no process state\n\n  OCI_ATTR_DESC_PUBLIC               = 250;   // public object\n\n  { Object Cache Enhancements : attributes for User Constructed Instances }\n  OCI_ATTR_CACHE_CLIENT_CONTEXT      = 251;\n  OCI_ATTR_UCI_CONSTRUCT             = 252;\n  OCI_ATTR_UCI_DESTRUCT              = 253;\n  OCI_ATTR_UCI_COPY                  = 254;\n  OCI_ATTR_UCI_PICKLE                = 255;\n  OCI_ATTR_UCI_UNPICKLE              = 256;\n  OCI_ATTR_UCI_REFRESH               = 257;\n\n  { for type inheritance }\n  OCI_ATTR_IS_SUBTYPE                = 258;\n  OCI_ATTR_SUPERTYPE_SCHEMA_NAME     = 259;\n  OCI_ATTR_SUPERTYPE_NAME            = 260;\n\n  { for schemas }\n  OCI_ATTR_LIST_OBJECTS              = 261;   // list of objects in schema\n\n  { for database }\n  OCI_ATTR_NCHARSET_ID               = 262;   // char set id\n  OCI_ATTR_LIST_SCHEMAS              = 263;   // list of schemas\n  OCI_ATTR_MAX_PROC_LEN              = 264;   // max procedure length\n  OCI_ATTR_MAX_COLUMN_LEN            = 265;   // max column name length\n  OCI_ATTR_CURSOR_COMMIT_BEHAVIOR    = 266;   // cursor commit behavior\n  OCI_ATTR_MAX_CATALOG_NAMELEN       = 267;   // catalog namelength\n  OCI_ATTR_CATALOG_LOCATION          = 268;   // catalog location\n  OCI_ATTR_SAVEPOINT_SUPPORT         = 269;   // savepoint support\n  OCI_ATTR_NOWAIT_SUPPORT            = 270;   // nowait support\n  OCI_ATTR_AUTOCOMMIT_DDL            = 271;   // autocommit DDL\n  OCI_ATTR_LOCKING_MODE              = 272;   // locking mode\n\n  OCI_ATTR_CACHE_ARRAYFLUSH          = $40;\n  OCI_ATTR_OBJECT_NEWNOTNULL         = $10;\n  OCI_ATTR_OBJECT_DETECTCHANGE       = $20;\n\n  {client side character and national character set ids }\n  OCI_ATTR_ENV_CHARSET_ID       = OCI_ATTR_CHARSET_ID;  // charset id in env\n  OCI_ATTR_ENV_NCHARSET_ID      = OCI_ATTR_NCHARSET_ID; // ncharset id in env\n\n  { Piece Information }\n  OCI_PARAM_IN                       = $01;  // in parameter\n  OCI_PARAM_OUT                      = $02;  // out parameter\n\n  { LOB Buffering Flush Flags }\n  OCI_LOB_BUFFER_FREE     = 1;\n  OCI_LOB_BUFFER_NOFREE   = 2;\n\n  { FILE open modes }\n  OCI_FILE_READONLY   = 1;    // readonly mode open for FILE types\n  { LOB open modes }\n  OCI_LOB_READONLY    = 1;    // readonly mode open for ILOB types\n  OCI_LOB_READWRITE   = 2;    // read write mode open for ILOBs\n\n  { CHAR/NCHAR/VARCHAR2/NVARCHAR2/CLOB/NCLOB char set \"form\" information }\n  SQLCS_IMPLICIT = 1;     // for CHAR, VARCHAR2, CLOB w/o a specified set\n  SQLCS_NCHAR    = 2;     // for NCHAR, NCHAR VARYING, NCLOB\n  SQLCS_EXPLICIT = 3;     // for CHAR, etc, with \"CHARACTER SET ...\" syntax\n  SQLCS_FLEXIBLE = 4;     // for PL/SQL \"flexible\" parameters\n  SQLCS_LIT_NULL = 5;     // for typecheck of NULL and empty_clob() lits\n\n  {************************ OCIDesribeAny *************************}\n\n  { Describe mode }\n  OCI_OTYPE_NAME = 1;\n  OCI_OTYPE_REF = 2;\n  OCI_OTYPE_PTR = 3;\n\n  { Object type }\n  OCI_PTYPE_UNK           = 0;    // unknown\n  OCI_PTYPE_TABLE         = 1;    // table\n  OCI_PTYPE_VIEW          = 2;    // view\n  OCI_PTYPE_PROC          = 3;    // procedure\n  OCI_PTYPE_FUNC          = 4;    // function\n  OCI_PTYPE_PKG           = 5;    // package\n  OCI_PTYPE_TYPE          = 6;    // user-defined type\n  OCI_PTYPE_SYN           = 7;    // synonym\n  OCI_PTYPE_SEQ           = 8;    // sequence\n  OCI_PTYPE_COL           = 9;    // column\n  OCI_PTYPE_ARG           = 10;   // argument\n  OCI_PTYPE_LIST          = 11;   // list\n  OCI_PTYPE_TYPE_ATTR     = 12;   // user-defined type's attribute\n  OCI_PTYPE_TYPE_COLL     = 13;   // collection type's element\n  OCI_PTYPE_TYPE_METHOD   = 14;   // user-defined type's method\n  OCI_PTYPE_TYPE_ARG      = 15;   // user-defined type method's argument\n  OCI_PTYPE_TYPE_RESULT   = 16;   // user-defined type method's result\n\n  { Proc/Func param type }\n  OCI_TYPEPARAM_IN    = 0;\n  OCI_TYPEPARAM_OUT   = 1;\n  OCI_TYPEPARAM_INOUT = 2;\n\n  { NLS environmet }\n  OCI_NLS_CHARSET_MAXBYTESZ = 91;\n\n  { enum OCIPinOpt }\n  OCI_PIN_DEFAULT = 1;            //* default pin option */\n  OCI_PIN_ANY     = 3;            //* pin any copy of the object */\n  OCI_PIN_RECENT  = 4;            //* pin recent copy of the object */\n  OCI_PIN_LATEST  = 5;            //* pin latest copy of the object */\n\n  { enum OCILockOpt }\n  OCI_LOCK_NONE     = 1;          //* null (same as no lock) */\n  OCI_LOCK_X        = 2;          //* exclusive lock */\n  OCI_LOCK_X_NOWAIT = 3;          //* exclusive lock, do not wait  */\n\n  { OBJECT FREE OPTION }\n  OCI_OBJECTFREE_FORCE =1;\n  OCI_OBJECTFREE_NONULL=2;\n\ntype\n  PPointer = ^Pointer;\n\n  TOCIInitialize = function(mode: ub4; ctxp: Pointer; malocfp: Pointer;\n    ralocfp: Pointer; mfreefp: Pointer): sword; cdecl;\n\n  TOCIEnvInit = function(var envhpp: POCIEnv; mode: ub4; xtramemsz: size_T;\n    usrmempp: PPointer): sword; cdecl;\n\n  TOCIEnvCreate = function(var envhpp: POCIEnv; mode: ub4; ctxp: Pointer;\n    malocfp: Pointer; ralocfp: Pointer; mfreefp: Pointer; xtramemsz: size_T;\n    usrmempp: PPointer): sword; cdecl;\n\n  TOCIEnvNlsCreate = function(var envhpp: POCIEnv; mode: ub4; ctxp: Pointer;\n    malocfp: Pointer; ralocfp: Pointer; mfreefp: Pointer; xtramemsz: size_T;\n    usrmempp: PPointer; charset, ncharset: ub2): sword; cdecl;\n\n  TOCIHandleAlloc = function(parenth: POCIHandle; var hndlpp: POCIHandle;\n    atype: ub4; xtramem_sz: size_T; usrmempp: PPointer): sword; cdecl;\n\n  TOCIServerAttach = function(srvhp: POCIServer; errhp: POCIError; dblink: text;\n    dblink_len: sb4; mode: ub4): sword; cdecl;\n\n  TOCIAttrSet = function(trgthndlp: POCIHandle; trghndltyp: ub4;\n    attributep: Pointer; size: ub4; attrtype: ub4; errhp: POCIError):sword; cdecl;\n\n  TOCISessionBegin = function(svchp: POCISvcCtx; errhp: POCIError;\n    usrhp: POCISession; credt: ub4; mode: ub4):sword; cdecl;\n\n  TOCISessionEnd = function(svchp: POCISvcCtx; errhp: POCIError;\n    usrhp: POCISession; mode: ub4): sword; cdecl;\n\n  TOCIServerDetach = function(srvhp: POCIServer; errhp: POCIError;\n    mode: ub4): sword; cdecl;\n\n  TOCIHandleFree = function(hndlp: Pointer; atype: ub4): sword; cdecl;\n\n  TOCIErrorGet = function(hndlp: Pointer; recordno: ub4; sqlstate: text;\n    var errcodep: sb4; bufp: text; bufsiz: ub4; atype: ub4): sword; cdecl;\n\n  TOCIStmtPrepare = function(stmtp: POCIStmt; errhp: POCIError; stmt: text;\n    stmt_len: ub4; language:ub4; mode: ub4):sword; cdecl;\n\n  TOCIStmtExecute = function(svchp: POCISvcCtx; stmtp: POCIStmt;\n    errhp: POCIError; iters: ub4; rowoff: ub4; snap_in: POCISnapshot;\n    snap_out: POCISnapshot; mode: ub4): sword; cdecl;\n\n  TOCIParamGet = function(hndlp: Pointer; htype: ub4; errhp: POCIError;\n    var parmdpp: Pointer; pos: ub4): sword; cdecl;\n\n  TOCIAttrGet = function(trgthndlp: POCIHandle; trghndltyp: ub4;\n    attributep: Pointer; sizep: Pointer; attrtype: ub4;\n    errhp: POCIError):sword; cdecl;\n\n  TOCIStmtFetch = function(stmtp: POCIStmt; errhp: POCIError; nrows: ub4;\n    orientation: ub2; mode: ub4): sword; cdecl;\n\n  TOCIDefineByPos = function(stmtp: POCIStmt; var defnpp: POCIDefine;\n    errhp: POCIError; position: ub4; valuep: Pointer; value_sz: sb4; dty: ub2;\n    indp: Pointer; rlenp: Pointer; rcodep: Pointer; mode: ub4): sword; cdecl;\n\n  TOCIDefineArrayOfStruct = function(defnpp: POCIDefine; errhp: POCIError;\n    pvskip: ub4; indskip: ub4; rlskip: ub4; rcskip: ub4): sword; cdecl;\n\n  TOCIBindByPos = function(stmtp: POCIStmt; var bindpp: POCIBind;\n    errhp: POCIError; position: ub4; valuep: Pointer; value_sz: sb4; dty: ub2;\n    indp: Pointer; alenp: Pointer; rcodep: Pointer; maxarr_len: ub4;\n    curelep: Pointer; mode: ub4): sword; cdecl;\n\n  TOCIBindByName = function(stmtp: POCIStmt; var bindpp: POCIBind;\n    errhp: POCIError; placeholder: text; placeh_len: sb4; valuep: Pointer;\n    value_sz: sb4; dty: ub2; indp: Pointer; alenp: Pointer; rcodep: Pointer;\n    maxarr_len: ub4; curelep: Pointer; mode: ub4): sword; cdecl;\n\n  TOCIBindDynamic = function(bindp: POCIBind; errhp: POCIError; ictxp: Pointer;\n    icbfp: Pointer; octxp: Pointer; ocbfp: Pointer): sword; cdecl;\n\n(*---------------------------------OCIBindObject--------------------------------\n\n  This function sets up additional attributes which are required for a named\n  data type (object)  bind.\n  Syntax\n------------------------------------------------------------------------------*)\n  TOCIBindObject = function(bindp: POCIBind; errhp: POCIError;\n                    const _type: POCIType; pgvpp: PPointer;\n                    pvszsp: pub4; indpp: PPointer;\n                    indszp: pub4): sword; cdecl;\n  (*Comments\n  This function sets up additional attributes which binding a named data type\n  or a REF. An error will be returned if this function is called when the OCI\n  environment has been initialized in non-object mode.\n  This call takes as a paramter a type descriptor object (TDO) of datatype\n  OCIType for the named data type being defined.  The TDO can be retrieved\n  with a call to OCITypeByName().\n  If the OCI_DATA_AT_EXEC mode was specified in ocibindn() or ocibindp(), the\n  pointers to the IN buffers are obtained either using the callback icbfp\n  registered in the OCIBindDynamic() call or by the OCIStmtSetPieceInfo() call.\n  The buffers are dynamically allocated for the OUT data and the pointers to\n  these buffers are returned either by calling ocbfp() registered by the\n  OCIBindDynamic() or by setting the pointer to the buffer in the buffer passed\n  in by OCIStmtSetPieceInfo() called when OCIStmtExecute() returned\n  OCI_NEED_DATA. The memory of these client library- allocated buffers must be\n  freed when not in use anymore by using the OCIObjectFreee() call.\n  Parameters\n  bindp ( IN/OUT) - the bind handle returned by the call to OCIBindByName()\n  or OCIBindByPos().\n  errhp ( IN/OUT) - an error handle which can be passed to OCIErrorGet() for\n  diagnostic information in the event of an error.\n  type ( IN) - points to the TDO which describes the type of the program\n  variable being bound. Retrieved by calling OCITypeByName().\n  pgvpp ( IN/OUT) - points to a pointer to the program variable buffer. For an\n  array, pgvpp points to an array of pointers. When the bind variable is also an\n  OUT variable, the OUT Named Data Type value or REF is allocated\n  (unpickled) in the Object Cache, and a pointer to the value or REF is returned,\n  At the end of execute, when all OUT values have been received, pgvpp points\n  to an array of pointer(s) to these newly allocated named data types in the\n  object cache.\n  pgvpp is ignored if the OCI_DATA_AT_EXEC mode is set. Then the Named\n  Data Type buffers are requested at runtime. For static array binds, skip\n  factors may be specified using the OCIBindArrayOfStruct() call. The skip\n  factors are used to compute the address of the next pointer to the value, the\n  indicator structure and their sizes.\n  pvszsp ( IN/OUT) - points to the size of the program variable. The size of the\n  named data type is not required on input. For an array, pvszsp is an array of\n  ub4s. On return, for OUT bind variables, this points to size(s) of the Named\n  Data Types and REFs received. pvszsp is ignored if the OCI_DATA_AT_EXEC\n  mode is set. Then the size of the buffer is taken at runtime.\n  indpp ( IN/OUT) - points to a pointer to the program variable buffer\n  containing the parallel indicator structure. For an array, points to an array\n  of pointers. When the bind variable is also an OUT bind variable, memory is\n  allocated in the object cache, to store the unpickled OUT indicator values. At\n  the end of the execute when all OUT values have been received, indpp points\n  to the pointer(s) to these newly allocated indicator structure(s).\n  indpp is ignored if the OCI_DATA_AT_EXEC mode is set. Then the indicator\n  is requested at runtime.\n  indszp ( IN/OUT) - points to the size of the IN indicator structure program\n  variable. For an array, it is an array of sb2s. On return for OUT bind\n  variables, this points to size(s) of the received OUT indicator structures.\n  indszp is ignored if the OCI_DATA_AT_EXEC mode is set. Then the indicator\n  size is requested at runtime.\n  Related Functions\n  OCIAttrGet() *)\n\n  TOCIDefineObject = function(defnpp:POCIDefine; errhp:POCIError;\n    _type:POCIHandle; pgvpp:pointer; pvszsp:Pub4;\n    indpp:pointer; indszp:Pub4):sword;cdecl;\n\n  TOCITransStart = function(svchp: POCISvcCtx; errhp: POCIError; timeout: word;\n    flags: ub4): sword; cdecl;\n\n  TOCITransRollback = function(svchp:POCISvcCtx; errhp:POCIError;\n    flags: ub4): sword; cdecl;\n\n  TOCITransCommit = function(svchp: POCISvcCtx; errhp: POCIError;\n    flags: ub4) :sword; cdecl;\n\n  TOCITransDetach = function(svchp: POCISvcCtx; errhp: POCIError;\n    flags: ub4) :sword; cdecl;\n\n  TOCITransPrepare = function(svchp: POCISvcCtx; errhp: POCIError;\n    flags: ub4) :sword; cdecl;\n\n  TOCITransForget = function(svchp: POCISvcCtx; errhp: POCIError;\n    flags: ub4) :sword; cdecl;\n\n  TOCIDescribeAny = function(svchp: POCISvcCtx; errhp: POCIError;\n    objptr: Pointer; objnm_len: ub4; objptr_typ: ub1; info_level: ub1;\n    objtyp: ub1; dschp: POCIDescribe): sword; cdecl;\n\n  TOCIBreak = function(svchp: POCISvcCtx; errhp:POCIError): sword; cdecl;\n\n  TOCIReset = function(svchp: POCISvcCtx; errhp:POCIError): sword; cdecl;\n\n  TOCIDescriptorAlloc = function(parenth: POCIEnv; var descpp: POCIDescriptor;\n    htype: ub4; xtramem_sz: integer; usrmempp: Pointer): sword; cdecl;\n\n  TOCIDescriptorFree = function(descp: Pointer; htype: ub4): sword; cdecl;\n\n  TOCIDateTimeAssign = function(hndl: POCIEnv; err: POCIError;\n    const from: POCIDateTime;_to: POCIDateTime): sword; cdecl;\n\n  TOCIDateTimeCheck = function(hndl: POCIEnv; err: POCIError;\n    const date: POCIDateTime; var valid: ub4): sword; cdecl;\n\n  TOCIDateTimeCompare = function(hndl: POCIEnv; err: POCIError;\n    const date1: POCIDateTime; const date2: POCIDateTime;\n    var result: sword): sword; cdecl;\n\n  TOCIDateTimeConvert = function(hndl: POCIEnv; err: POCIError;\n    indate: POCIDateTime; outdate: POCIDateTime): sword; cdecl;\n\n  TOCIDateTimeFromText= function(hndl: POCIEnv; err: POCIError;\n    const date_str: text; d_str_length: size_t; const fmt: text;\n    fmt_length: ub1; const lang_name: text; lang_length: size_t;\n    date: POCIDateTime): sword; cdecl;\n\n  TOCIDateTimeGetDate = function(hndl: POCIEnv; err: POCIError;\n    const date: POCIDateTime; var year: sb2; var month: ub1;\n    var day: ub1): sword; cdecl;\n\n  TOCIDateTimeGetTime = function(hndl: POCIEnv; err: POCIError;\n    datetime: POCIDateTime; var hour: ub1; var minute: ub1; var sec: ub1;\n    var fsec: ub4): sword; cdecl;\n\n  TOCIDateTimeGetTimeZoneOffset = function(hndl: POCIEnv; err: POCIError;\n    const datetime: POCIDateTime; var hour: sb1; var minute: sb1): sword; cdecl;\n\n  TOCIDateTimeSysTimeStamp = function(hndl: POCIEnv; err: POCIError;\n    sys_date: POCIDateTime): sword; cdecl;\n\n  TOCIDateTimeConstruct = function(hndl: POCIEnv; err: POCIError;\n    datetime: POCIDateTime; year: sb2; month: ub1; day: ub1; hour: ub1;\n    min: ub1; sec: ub1; fsec: ub4; timezone: text;\n    timezone_length: size_t): sword; cdecl;\n\n  TOCIDateTimeToText = function(hndl: POCIEnv; err: POCIError;\n    const date: POCIDateTime; const fmt: text; fmt_length: ub1;\n    fsprec: ub1; const lang_name: text; lang_length: size_t;\n    var buf_size: ub4; buf: text): sword; cdecl;\n\n  TOCIDateTimeGetTimeZoneName = function(hndl: POCIEnv; err: POCIError;\n    datetime: POCIDateTime; var buf: ub1; var buflen: ub4): sword; cdecl;\n\n  TOCILobAppend = function(svchp: POCISvcCtx; errhp: POCIError; dst_locp,\n    src_locp: POCILobLocator): sword; cdecl;\n\n  TOCILobAssign = function(svchp: POCISvcCtx; errhp: POCIError;\n    src_locp: POCILobLocator; var dst_locpp: POCILobLocator): sword; cdecl;\n\n  TOCILobClose = function(svchp: POCISvcCtx; errhp: POCIError;\n    locp: POCILobLocator): sword; cdecl;\n\n  TOCILobCopy = function(svchp: POCISvcCtx; errhp: POCIError;\n    dst_locp: POCILobLocator; src_locp: POCILobLocator; amount: ub4;\n    dst_offset: ub4; src_offset: ub4): sword; cdecl;\n\n  TOCILobCreateTemporary = function(svchp: POCISvcCtx; errhp: POCIError;\n    locp: POCILobLocator; csid: ub2; csfrm: ub1; lobtype: ub1;\n    cache: LongBool; duration: OCIDuration): sword; cdecl;\n\n  TOCILobEnableBuffering = function(svchp: POCISvcCtx; errhp: POCIError;\n    locp: POCILobLocator): sword; cdecl;\n\n  TOCILobDisableBuffering = function(svchp: POCISvcCtx; errhp: POCIError;\n    locp: POCILobLocator): sword; cdecl;\n\n  TOCILobErase = function(svchp: POCISvcCtx; errhp: POCIError; locp: POCILobLocator;\n    var amount: ub4; offset: ub4): sword; cdecl;\n\n  TOCILobFileExists = function(svchp: POCISvcCtx; errhp: POCIError;\n    filep: POCILobLocator; var flag: Boolean): sword; cdecl;\n\n  TOCILobFileGetName = function(envhp: POCIEnv; errhp: POCIError;\n    filep: POCILobLocator; dir_alias: text; var d_length: ub2; filename: text;\n    var f_length: ub2): sword; cdecl;\n\n  TOCILobFileSetName = function(envhp: POCIEnv; errhp: POCIError;\n    var filep: POCILobLocator; dir_alias: text; d_length: ub2; filename: text;\n    f_length: ub2): sword; cdecl;\n\n  TOCILobFlushBuffer = function(svchp: POCISvcCtx; errhp: POCIError;\n    locp: POCILobLocator; flag: ub4): sword; cdecl;\n\n  TOCILobFreeTemporary = function(svchp: POCISvcCtx; errhp: POCIError;\n    locp: POCILobLocator): sword; cdecl;\n\n  TOCILobCharSetForm = function ( envhp: POCIEnv; errhp: POCIError;\n        const locp: POCILobLocator; csfrm: pub1): sword; cdecl;\n\n  TOCILobCharSetId = function( envhp: POCIEnv; errhp: POCIError;\n        const locp: POCILobLocator; csid: pub2): sword; cdecl;\n\n  TOCILobGetLength = function(svchp: POCISvcCtx; errhp: POCIError;\n    locp: POCILobLocator; var lenp: ub4): sword; cdecl;\n\n  TOCILobIsOpen = function(svchp: POCISvcCtx; errhp: POCIError;\n    locp: POCILobLocator; var flag: LongBool): sword; cdecl;\n\n  TOCILobIsTemporary = function(svchp: POCISvcCtx; errhp: POCIError;\n    locp: POCILobLocator; var is_temporary: LongBool): sword; cdecl;\n\n  TOCILobLoadFromFile = function(svchp: POCISvcCtx; errhp: POCIError;\n    dst_locp: POCILobLocator; src_locp: POCILobLocator; amount: ub4;\n    dst_offset: ub4; src_offset: ub4): sword; cdecl;\n\n  TOCILobLocatorIsInit = function(envhp: POCIEnv; errhp: POCIError;\n   locp: POCILobLocator; var is_initialized: LongBool): sword; cdecl;\n\n  TOCILobOpen = function(svchp: POCISvcCtx; errhp: POCIError;\n    locp: POCILobLocator; mode: ub1): sword; cdecl;\n\n  TOCILobRead = function(svchp: POCISvcCtx; errhp: POCIError;\n    locp: POCILobLocator; var amtp: ub4; offset: ub4; bufp: Pointer; bufl: ub4;\n    ctxp: Pointer; cbfp: Pointer; csid: ub2; csfrm: ub1): sword; cdecl;\n\n  TOCILobTrim = function(svchp: POCISvcCtx; errhp: POCIError;\n    locp: POCILobLocator; newlen: ub4): sword; cdecl;\n\n  TOCILobWrite = function(svchp: POCISvcCtx; errhp: POCIError;\n    locp: POCILobLocator; var amtp: ub4; offset: ub4; bufp: Pointer; bufl: ub4;\n    piece: ub1; ctxp: Pointer; cbfp: Pointer; csid: ub2; csfrm: ub1): sword; cdecl;\n\n  TOCIStmtGetPieceInfo = function(stmtp: POCIStmt; errhp: POCIError;\n    var hndlpp: Pointer; var typep: ub4; var in_outp: ub1; var iterp: ub4;\n    var idxp: ub4; var piecep: ub1): sword; cdecl;\n\n  TOCIStmtSetPieceInfo = function(handle: Pointer; typep: ub4; errhp: POCIError;\n    buf: Pointer; var alenp: ub4; piece: ub1; indp: Pointer;\n    var rcodep: ub2): sword; cdecl;\n\n  TOCIPasswordChange = function(svchp: POCISvcCtx; errhp: POCIError;\n    user_name: text; usernm_len: ub4; opasswd: text; opasswd_len: ub4;\n    npasswd: text; npasswd_len: sb4; mode: ub4): sword; cdecl;\n\n  TOCIServerVersion = function(hndlp: POCIHandle; errhp: POCIError; bufp: text;\n    bufsz: ub4; hndltype: ub1): sword; cdecl;\n\n  TOCIServerRelease = function(hndlp: POCIHandle; errhp: POCIError; bufp: text;\n    bufsz: ub4; hndltype: ub1; version:pointer): sword; cdecl;\n\n  TOCIResultSetToStmt = function(rsetdp: POCIHandle; errhp: POCIError): sword; cdecl;\n\n  TOCINlsNumericInfoGet = function(envhp: POCIEnv; errhp: POCIError; val: psb4; item: ub2): sword; cdecl;\n\n  TOCIClientVersion = procedure(major_version, minor_version, update_num,\n      patch_num, port_update_num: psword); cdecl;\n\n(*****************************************************************************\n *                         NUMBER/FLOAT/DECIMAL TYPE                         *\n *****************************************************************************)\nconst\n  OCI_NUMBER_SIZE = 22;\n\ntype\n  POCINumberPart = ^TOCINumberPart;\n  TOCINumberPart = array[1..OCI_NUMBER_SIZE] of ub1;\n\n(*\n * OCINumber - OCI Number mapping in c\n *\n * The OTS types: NUMBER, NUMERIC, INT, SHORTINT, REAL, DOUBLE PRECISION,\n * FLOAT and DECIMAL are represented by OCINumber.\n * The contents of OCINumber is opaque to clients.\n *\n * For binding variables of type OCINumber in OCI calls (OCIBindByName(),\n * OCIBindByPos(), and OCIDefineByPos()) use the type code SQLT_VNU.\n *\n\n *\n   EXAMPLE\n\n   The following example shows how to manipulate an attribute of type\n   oracle number.\n\n     struct person\n     {\n       OCINumber sal;\n     };\n     typedef struct person person;\n\n     OCIError *err;\n     person* joe;\n     person* tom;\n     person* debbie;\n     OCINumber  *joesal;\n     OCINumber  *tomsal;\n     OCINumber *debsal;\n     sword   status;\n     int     inum;\n     double  dnum;\n     OCINumber ornum;\n     char    buffer[21];\n     ub4     buflen;\n     sword   result;\n\n     /o See oci.h for an example of how to initialize OCIError.\n      o For this example, assume the OCIEnv and OCIError has been\n      o initialized.\n      o/\n\n     /o Pin joe, tom and debbie person objects in the object cache. See ori.h\n      o for an example on pinning objects. For this example, assume that\n      o joe, tom and debbie are pointing to pinned objects.\n      o/\n     joesal = &joe->sal;\n     tomsal = &tom->sal;\n     debsal = &debbie->sal;\n\n     /o initialize joe's salary to be $12,000 o/\n     inum = 12000;\n     status = OCINumberFromInt(err, &inum, sizeof(inum), OCI_NUMBER_SIGNED,\n                               joesal);\n     if (status != OCI_SUCCESS)\n                              /o goto to handle error from OCINumberFromInt o/;\n\n     /o initialize tom's salary to be same as joe o/\n     OCINumberAssign(err, joesal, tomsal);\n\n     /o initialize debbie's salary to be 20% more than joe's o/\n     dnum = 1.2;\n     status = OCINumberFromReal(err, &dnum, sizeof(double), &ornum);\n     if (status != OCI_SUCCESS)\n                            /o goto to handle error from OCINumberFromReal o/;\n     status = OCINumberMul(err, joesal, &ornum, debsal);\n     if (status != OCI_SUCCESS)  /o goto to handle error from OCINumberMul o/;\n\n     /o give tom a 50% raise o/\n     dnum = 1.5;\n     status = OCINumberFromReal(err, &dnum, sizeof(double), &ornum);\n     if (status != OCI_SUCCESS)\n                            /o goto to handle error from OCINumberFromReal o/;\n     status = OCINumberMul(err, tomsal, &ornum, tomsal);\n     if (status != OCI_SUCCESS)  /o goto to handle error from OCINumberMul o/;\n\n     /o double joe's salary o/\n     status = OCINumberAdd(err, joesal, joesal, joesal);\n     if (status != OCI_SUCCESS)  /o goto to handle error from OCINumberAdd o/;\n\n     /o get joe's salary in integer o/\n     status = OCINumberToInt(err, joesal, sizeof(inum), OCI_NUMBER_SIGNED,\n                             &inum);\n     if (status != OCI_SUCCESS)/o goto to handle error from OCINumberToInt o/;\n     /o inum is set to 24000 o/\n\n     /o get debbie's salary in double o/\n     status = OCINumberToReal(err, debsal, sizeof(dnum), &dnum);\n     if (status != OCI_SUCCESS)/o goto to handle error from OCINumberToReal o/;\n     /o dnum is set to 14400 o/\n\n     /o print tom's salary as DEM0001`8000.00 o/\n     buflen = sizeof(buffer);\n     status = OCINumberToText(err, tomsal, \"C0999G9999D99\", 13,\n                 \"NLS_NUMERIC_CHARACTERS='.`' NLS_ISO_CURRENCY='Germany'\", 54,\n                 &buflen, buffer);\n     if (status != OCI_SUCCESS)/o goto to handle error from OCINumberToText o/;\n     printf(\"tom's salary = %s\\n\", buffer);\n\n     /o compare joe and tom's salary o/\n     status = OCINumberCmp(err, joesal, tomsal, &result);\n     if (status != OCI_SUCCESS)  /o goto to handle error from OCINumberCmp o/;\n     /o result is positive o/\n\n     /o read debbie's new salary from string o/\n     status = OCINumberFromText(err, \"48`000.00\", 9, \"99G999D99\", 9,\n                      \"NLS_NUMERIC_CHARACTERS='.`'\", 27, debsal);\n     if (status != OCI_SUCCESS)\n                            /o goto to handle error from OCINumberFromText o/;\n     /o debbie's salary is now 48000.00 o/\n\n*)\n\n(*----------------------------- OCINumberInc --------------------------------*)\n\n  TOCINumberInc = function(err: POCIError; number: POCINumber): sword; cdecl;\n(*\n   NAME: OCINumberInc - OCINumber INCrement numbers\n   PARAMETERS:\n        err (IN/OUT) - error handle. If there is an error, it is\n                recorded in 'err' and this function returns OCI_ERROR.\n                The error recorded in 'err' can be retrieved by calling\n                OCIErrorGet().\n        number (IN/OUT) a positive Oracle number to be incremented\n   DESCRIPTION:\n        Increment Oracle number in place. It is assumed that the input is\n        an integer between 0 and 100^21-2. If the is input too large, it will\n        be treated as 0 - the result will be an Oracle number 1. If the input\n        is not a positive integer, the result will be unpredictable.\n   RETURNS:\n        OCI_SUCCESS if the function completes successfully.\n        OCI_INVALID_HANDLE if 'err' is NULL.\n        OCI_ERROR if\n          any of the number arguments is null\n *)\n\n(*----------------------------- OCINumberDec --------------------------------*)\n\n  TOCINumberDec = function(err: POCIError; number: POCINumber): sword; cdecl;\n(*\n   NAME: OCINumberDec - OCINumber DECrement numbers\n   PARAMETERS:\n        err (IN/OUT) - error handle. If there is an error, it is\n                recorded in 'err' and this function returns OCI_ERROR.\n                The error recorded in 'err' can be retrieved by calling\n                OCIErrorGet().\n        number (IN/OUT) - a positive Oracle number to be decremented\n   DESCRIPTION:\n        Decrement Oracle number in place. It is assumed that the input is an\n        integer between 1 and 100^21-2. If the input is too large, it will be\n        treated as 1 - the result will be an Oracle number 0. If the input is\n        not a positive integer, the result will be unpredictable.\n   RETURNS:\n        OCI_SUCCESS if the function completes successfully.\n        OCI_INVALID_HANDLE if 'err' is NULL.\n        OCI_ERROR if\n          any of the number arguments is null\n *)\n\n(*-------------------------- OCINumberSetZero -------------------------------*)\n\n  TOCINumberSetZero = procedure(err: POCIError; number: POCINumber); cdecl;\n(*\n   NAME: OCINumberSetZero - OCINumber Set number to Zero value\n   PARAMETERS:\n        err (IN/OUT) - pointer to OCI error handle\n        num (OUT) - set to zero value\n   DESCRIPTION:\n        Initialize the given number to value 0.\n *)\n\n(*--------------------------- OCINumberSetPi --------------------------------*)\n\n  TOCINumberSetPi = procedure(err: POCIError; number: POCINumber); cdecl;\n(*\n   NAME: OCINumberSetPi - OCINumber Set number to Pi\n        err (IN/OUT) - pointer to OCI error handle\n        num (OUT) - set to zero value\n   DESCRIPTION:\n        Initialize the given number to value Pi.\n *)\n\n(*----------------------------- OCINumberAdd --------------------------------*)\n\n  TOCINumberAdd = function(err: POCIError; const number1: POCINumber;\n                const number2: POCINumber; _result: POCINumber): sword; cdecl;\n(*\n   NAME: OCINumberAdd - OCINumber ADD numbers\n   PARAMETERS:\n        err (IN/OUT) - error handle. If there is an error, it is\n                recorded in 'err' and this function returns OCI_ERROR.\n                The error recorded in 'err' can be retrieved by calling\n                OCIErrorGet().\n        number1, number2 (IN) - numbers to be added\n        result (OUT) - result of adding 'number1' with 'number2'\n   DESCRIPTION:\n        Add 'number1' with 'number2' and return result in 'result'.\n   RETURNS:\n        OCI_SUCCESS if the function completes successfully.\n        OCI_INVALID_HANDLE if 'err' is NULL.\n        OCI_ERROR if\n          any of the number arguments is null\n *)\n\n(*----------------------------- OCINumberSub --------------------------------*)\n\n  TOCINumberSub = function(err: POCIError; const number1: POCINumber;\n                const number2: POCINumber; _result: POCINumber): sword; cdecl;\n(*\n   NAME: OCINumberSub - OCINumber SUBtract numbers\n   PARAMETERS:\n        err (IN/OUT) - error handle. If there is an error, it is\n                recorded in 'err' and this function returns OCI_ERROR.\n                The error recorded in 'err' can be retrieved by calling\n                OCIErrorGet().\n        number1, number2 (IN) - 'number2' subtracted from 'number1'\n        result (OUT) - subtraction result\n   DESCRIPTION:\n        Subtract 'number2' from 'number1' and return result in 'result'.\n   RETURNS:\n        OCI_SUCCESS if the function completes successfully.\n        OCI_INVALID_HANDLE if 'err' is NULL.\n        OCI_ERROR if\n          any of the number arguments is null\n *)\n\n(*----------------------------- OCINumberMul --------------------------------*)\n\n  TOCINumberMul = function(err: POCIError; const number1: POCINumber;\n                const number2: POCINumber; _result: POCINumber): sword; cdecl;\n(*\n   NAME: OCINumberMul - OCINumber MULtiply numbers\n   PARAMETERS:\n        err (IN/OUT) - error handle. If there is an error, it is\n                recorded in 'err' and this function returns OCI_ERROR.\n                The error recorded in 'err' can be retrieved by calling\n                OCIErrorGet().\n        number1, number2 (IN) - numbers to be multiplied\n        result (OUT) - multiplication result\n   DESCRIPTION:\n        Multiply 'number1' with 'number2' and return result in 'result'.\n   RETURNS:\n        OCI_SUCCESS if the function completes successfully.\n        OCI_INVALID_HANDLE if 'err' is NULL.\n        OCI_ERROR if\n          any of the number arguments is null\n *)\n\n(*----------------------------- OCINumberDiv --------------------------------*)\n\n  TOCINumberDiv = function(err: POCIError; const number1: POCINumber;\n                const number2: POCINumber; _result: POCINumber): sword; cdecl;\n(*\n   NAME: OCINumberDiv - OCINumber DIVide numbers\n   PARAMETERS:\n        err (IN/OUT) - error handle. If there is an error, it is\n                recorded in 'err' and this function returns OCI_ERROR.\n                The error recorded in 'err' can be retrieved by calling\n                OCIErrorGet().\n        number1 (IN) - pointer to the numerator\n        number2 (IN) - pointer to the denominator\n        result (OUT) - division result\n   DESCRIPTION:\n        Divide 'number1' by 'number2' and return result in 'result'.\n   RETURNS:\n        OCI_SUCCESS if the function completes successfully.\n        OCI_INVALID_HANDLE if 'err' is NULL.\n        OCI_ERROR if\n          any of the number arguments is null\n          underflow errorr\n          overflow errorr\n          divide by zero errorr\n *)\n\n(*----------------------------- OCINumberMod --------------------------------*)\n\n  TOCINumberMod = function(err: POCIError; const number1: POCINumber;\n                const number2: POCINumber; _result: POCINumber): sword; cdecl;\n(*\n   NAME: OCINumberMod - OCINumber MODulous\n   PARAMETERS:\n        err (IN/OUT) - error handle. If there is an error, it is\n                recorded in 'err' and this function returns OCI_ERROR.\n                The error recorded in 'err' can be retrieved by calling\n                OCIErrorGet().\n        number1 (IN) - pointer to the numerator\n        number2 (IN) - pointer to the denominator\n        result (OUT) - remainder of the result\n   DESCRIPTION:\n        Finds the remainder of the division of two Oracle numbers.\n   RETURNS:\n        OCI_SUCCESS if the function completes successfully.\n        OCI_INVALID_HANDLE if 'err' is NULL.\n        OCI_ERROR if\n          any of the number arguments is null\n          divide by zero errorr\n *)\n\n(*------------------------ OCINumberIntPower --------------------------------*)\n\n  TOCINumberIntPower = function(err: POCIError; const number1: POCINumber;\n                const number2: POCINumber; _result: POCINumber): sword; cdecl;\n(*\n   NAME: OCINumberIntPower - OCINumber takes an arbitary base to an arbitary\n                             integer PoWeR\n   PARAMETERS:\n        err (IN/OUT) - error handle. If there is an error, it is\n                recorded in 'err' and this function returns OCI_ERROR.\n                The error recorded in 'err' can be retrieved by calling\n                OCIErrorGet().\n        base (IN) - base of the exponentiation\n        exp (IN) - exponent to which the base is to be raised\n        result (OUT) - output of exponentiation\n   DESCRIPTION:\n        Takes an arbitary base to an arbitary integer power.\n   RETURNS:\n        OCI_SUCCESS if the function completes successfully.\n        OCI_INVALID_HANDLE if 'err' is NULL.\n        OCI_ERROR if\n          any of the number arguments is null\n *)\n\n(*-------------------------- OCINumberShift ---------------------------------*)\n\n  TOCINumberShift = function(err: POCIError; const number: POCINumber;\n                            const nDig: sword; _result: POCINumber): sword; cdecl;\n(*\n   NAME: OCINumberShift - OCINumber multiplies by a power of 10.\n\n   PARAMETERS:\n        err (IN/OUT) - error handle. If there is an error, it is\n                recorded in 'err' and this function returns OCI_ERROR.\n                The error recorded in 'err' can be retrieved by calling\n                OCIErrorGet().\n        number (IN) - Oracle Number to be shifted.\n        nDig   (IN) - number of decimal places to shift.\n        result (OUT) - shift result.\n   DESCRIPTION:\n        Multiplies number by 10^NDig and sets product to the result.\n   RETURNS:\n        OCI_SUCCESS if the function completes successfully.\n        OCI_INVALID_HANDLE if 'err' is NULL.\n        OCI_ERROR if\n          any of the number arguments is null\n *)\n\n(*----------------------------- OCINumberNeg --------------------------------*)\n\n  TOCINumberNeg = function(err: POCIError; const number: POCINumber;\n                            _result: POCINumber): sword; cdecl;\n(*\n   NAME: OCINumberNeg - OCINumber NEGate number\n   PARAMETERS:\n        err (IN/OUT) - error handle. If there is an error, it is\n                recorded in 'err' and this function returns OCI_ERROR.\n                The error recorded in 'err' can be retrieved by calling\n                OCIErrorGet().\n        number (IN) - number to be negated\n        result (OUT) - will contain negated value of 'number'\n   DESCRIPTION:\n        Negates an Oracle number.\n   RETURNS:\n        OCI_SUCCESS if the function completes successfully.\n        OCI_INVALID_HANDLE if 'err' is NULL.\n        OCI_ERROR if\n          any of the number arguments is null\n *)\n\n(*------------------------- OCINumberToText ---------------------------------*)\n  Poratext = PAnsiChar;\n  PPoratext = PPAnsiChar;\n\n  TOCINumberToText = function(err: POCIError; const number: POCINumber;\n                          const fmt: Poratext; fmt_length: ub4;\n                          const nls_params: Poratext; nls_p_length: ub4;\n                          buf_size: pub4; buf: poratext): sword; cdecl;\n(*\n   NAME: OCINumberToText - OCINumber convert number TO String\n   PARAMETERS:\n        err (IN/OUT) - error handle. If there is an error, it is\n                recorded in 'err' and this function returns OCI_ERROR.\n                The error recorded in 'err' can be retrieved by calling\n                OCIErrorGet().\n        number (IN) - Oracle number to be converted\n        fmt (IN) - conversion format\n        fmt_length (IN) - length of the 'fmt' parameter\n        nls_params (IN) - nls format specification, if null string\n                i.e. (oratext * )0, then the default parameters for the\n                session is used\n        nls_p_length (IN) - length of the 'nls_params' parameter\n        buf_size (IN/OUT) - size of the buffer must be passed as input by\n                the caller, this function will return the length of the\n                resulting string in bytes via this parameter. The length\n                does not include the terminating null ('\\0').\n        buf (OUT) - buffer into which the converted string is placed. The\n                resulting string is null terminated.\n   DESCRIPTION:\n        Converts the given number to a character string\n        according to the specified format. Refer to \"TO_NUMBER\" conversion\n        function described in \"Oracle SQL Language Reference Manual\" for a\n        description of format and NLS parameters.\n        The converted number string is stored in the buffer 'buf', up to\n        a max of '*buf_size' bytes. Length of the resulting string is\n        returned via 'buf_size'.\n   RETURNS:\n        OCI_SUCCESS if the function completes successfully.\n        OCI_INVALID_HANDLE if 'err' is NULL.\n        OCI_ERROR if\n          'number' or 'buf' is null\n          buffer too small\n          invalid format\n          invalid nls format\n          number to text translation for the given format causes overflow\n *)\n\n(*-------------------------- OCINumberFromText ------------------------------*)\n\n  TOCINumberFromText = function(err: POCIError; const str: poratext;\n                          str_length: ub4; const fmt: poratext; fmt_length: ub4;\n                          const nls_params: poratext; nls_p_length: ub4;\n                          number: POCINumber): sword; cdecl;\n(*\n   NAME: OCINumberFromText - OCINumber convert String TO Number\n   PARAMETERS:\n        err (IN/OUT) - error handle. If there is an error, it is\n                recorded in 'err' and this function returns OCI_ERROR.\n                The error recorded in 'err' can be retrieved by calling\n                OCIErrorGet().\n        str (IN) - input string to be converted to Oracle number\n        str_length (IN) - size of the input string\n        fmt (IN) - conversion format\n        fmt_length (IN) - length of the 'fmt' parameter\n        nls_params (IN) - nls format specification, if null string\n                i.e. (oratext * )0, then the default parameters for the\n                session is used\n        nls_p_length (IN) - length of the 'nls_params' parameter\n        number (OUT) - given string converted to number\n   DESCRIPTION:\n        Converts the given string to a number\n        according to the specified format. Refer to \"TO_NUMBER\" conversion\n        function described in \"Oracle SQL Language Reference Manual\" for a\n        description of format and NLS parameters.\n   RETURNS:\n        OCI_SUCCESS if the function completes successfully.\n        OCI_INVALID_HANDLE if 'err' is NULL.\n        OCI_ERROR if\n          'number' or 'str' is null\n          'str_length' is 0\n          invalid format\n          invalid nls format\n          invalid input string\n *)\n\n(*-------------------------- OCINumberToInt ---------------------------------*)\n\nconst\n  OCI_NUMBER_UNSIGNED = 0;                        // Unsigned type -- ubX\n  OCI_NUMBER_SIGNED = 2;                          // Signed type -- sbX\n\ntype\n  TOCINumberToInt = function(err: POCIError; const number: POCINumber;\n                rsl_length: uword; rsl_flag: uword; rsl: Pointer): sword; cdecl;\n(*\n   NAME: OCINumberToInt - OCINumber convert number TO Integer\n   PARAMETERS:\n        err (IN/OUT) - error handle. If there is an error, it is\n                recorded in 'err' and this function returns OCI_ERROR.\n                The error recorded in 'err' can be retrieved by calling\n                OCIErrorGet().\n        number (IN) - number to be converted\n        rsl_length (IN) - size of the desired result\n        rsl_s_flag (IN) - flag denoting the desired sign of the output; valid\n                values are OCI_NUMBER_UNSIGNED, OCI_NUMBER_SIGNED\n        rsl (OUT) - pointer to space for the result\n   DESCRIPTION:\n        Native type conversion function.\n        Converts the given Oracle number into an xbx (e.g. ub2, ub4, sb2 etc.)\n   RETURNS:\n        OCI_SUCCESS if the function completes successfully.\n        OCI_INVALID_HANDLE if 'err' is NULL.\n        OCI_ERROR if\n          'number' or 'rsl' is null\n          integer value of 'number' is too big -- overflow\n          integer value of 'number' is too small -- underflow\n          invalid sign flag value ('rsl_s_flag')\n *)\n\n(*--------------------------- OCINumberFromInt ------------------------------*)\n\n  TOCINumberFromInt = function(err: POCIError; const inum: Pointer;\n    inum_length: uword; inum_s_flag: uword; number: POCINumber): sword; cdecl;\n(*\n   NAME: OCINumberFromInt - OCINumber convert Integer TO Number\n   PARAMETERS:\n        err (IN/OUT) - error handle. If there is an error, it is\n                recorded in 'err' and this function returns OCI_ERROR.\n                The error recorded in 'err' can be retrieved by calling\n                OCIErrorGet().\n        inum (IN) - pointer to the integer to be converted\n        inum_length (IN) - size of the integer\n        inum_s_flag (IN) - flag that designates the sign of the integer; valid\n                values are OCI_NUMBER_UNSIGNED, OCI_NUMBER_SIGNED\n        number (OUT) - given integer converted to Oracle number\n   DESCRIPTION:\n        Native type conversion function. Converts any Oracle standard\n        machine-native integer type (xbx) to an Oracle number.\n   RETURNS:\n        OCI_SUCCESS if the function completes successfully.\n        OCI_INVALID_HANDLE if 'err' is NULL.\n        OCI_ERROR if\n          'number' or 'inum' is null\n          integer too BIG -- the number is too large to fit into an Oracle\n                number\n          invalid sign flag value ('inum_s_flag')\n *)\n\n(*------------------------- OCINumberToReal ---------------------------------*)\n\n  TOCINumberToReal = function(err: POCIError; const number: POCINumber;\n                        rsl_length: uword; rsl: Pointer): sword; cdecl;\n(*\n   NAME: OCINumberToReal - OCINumber convert number TO Real\n   PARAMETERS:\n        err (IN/OUT) - error handle. If there is an error, it is\n                recorded in 'err' and this function returns OCI_ERROR.\n                The error recorded in 'err' can be retrieved by calling\n                OCIErrorGet().\n        number (IN) - number to be converted\n        rsl_length (IN) - is the size of the desired result,\n                sizeof( float | double | long double)\n        rsl (OUT) - pointer to space for storing the result\n   DESCRIPTION:\n        Native type conversion function. Converts an Oracle number into a\n        machine-native real type. This function only converts numbers up to\n        LDBL_DIG, DBL_DIG, or FLT_DIG digits of precision and removes\n        trailing zeroes. The above constants are defined in float.h\n   RETURNS:\n        OCI_SUCCESS if the function completes successfully.\n        OCI_INVALID_HANDLE if 'err' is NULL.\n        OCI_ERROR if\n          'number' or 'rsl' is null\n          'rsl_length' is 0\n *)\n\n(*------------------------- OCINumberToRealArray ----------------------------*)\n\n  TOCINumberToRealArray = function(err: POCIError; const number: PPOCINumber;\n                             elems: uword; rsl_length: uword; rsl: Pointer): sword; cdecl;\n(*\n   NAME: OCINumberToRealArray - OCINumber convert array of numbers TO Real\n   PARAMETERS:\n        err (IN/OUT) - error handle. If there is an error, it is\n                recorded in 'err' and this function returns OCI_ERROR.\n                The error recorded in 'err' can be retrieved by calling\n                OCIErrorGet().\n        number (IN) - Pointer to array of number to be converted\n        elems (IN) - Upper bound of number array\n        rsl_length (IN) - is the size of the desired result,\n                                          sizeof( float | double | long double)\n        rsl (OUT) - pointer to array of space for storing the result\n   DESCRIPTION:\n        Native type conversion function. Converts an Oracle number into a\n        machine-native real type. This function only converts numbers up to\n        LDBL_DIG, DBL_DIG, or FLT_DIG digits of precision and removes\n        trailing zeroes. The above constants are defined in float.h\n   RETURNS:\n        OCI_SUCCESS if the function completes successfully.\n        OCI_INVALID_HANDLE if 'err' is NULL.\n        OCI_ERROR if\n          'number' or 'rsl' is null\n          'rsl_length' is 0\n *)\n\n(*-------------------------- OCINumberFromReal ------------------------------*)\n\n  TOCINumberFromReal = function(err: POCIError; const rnum: Pointer;\n                            rnum_length: uword; number: POCINumber): sword; cdecl;\n(*\n   NAME: OCINumberFromReal - OCINumber convert Real TO Number\n   PARAMETERS:\n        err (IN/OUT) - error handle. If there is an error, it is\n                recorded in 'err' and this function returns OCI_ERROR.\n                The error recorded in 'err' can be retrieved by calling\n                OCIErrorGet().\n        rnum (IN) - pointer to the floating point number to be converted\n        rnum_length (IN) - size of the desired result, i.e.\n                sizeof({float | double | long double})\n        number (OUT) - given float converted to Oracle number\n   DESCRIPTION:\n        Native type conversion function. Converts a machine-native floating\n        point type to an Oracle number.\n   RETURNS:\n        OCI_SUCCESS if the function completes successfully.\n        OCI_INVALID_HANDLE if 'err' is NULL.\n        OCI_ERROR if\n          'number' or 'rnum' is null\n          'rnum_length' is 0\n *)\n\n(*----------------------------- OCINumberCmp --------------------------------*)\n\n  TOCINumberCmp = function(err: POCIError; const number1: POCINumber;\n                       const number2: POCINumber; _result: psword): sword; cdecl;\n(*\n   NAME: OCINumberCmp - OCINumber CoMPare numbers\n   PARAMETERS:\n        err (IN/OUT) - error handle. If there is an error, it is\n                recorded in 'err' and this function returns OCI_ERROR.\n                The error recorded in 'err' can be retrieved by calling\n                OCIErrorGet().\n        number1, number2 (IN) - numbers to be compared\n        result (OUT) - 0 if equal, negative if number1 < number2,\n                positive if number1 > number2\n   DESCRIPTION:\n        The function OCINumberCmp compares two numbers.\n   RETURNS:\n        OCI_SUCCESS if the function completes successfully.\n        OCI_INVALID_HANDLE if 'err' is NULL.\n        OCI_ERROR if\n            'number1' or 'number2' or 'result' is null\n *)\n\n(*---------------------------- OCINumberSign --------------------------------*)\n\n  TOCINumberSign = function(err: POCIError; const number: POCINumber;\n                        _result: psword): sword; cdecl;\n(*\n   NAME: OCINumberSign - OCINumber obtains SiGN of an Oracle number\n   PARAMETERS:\n        err (IN/OUT) - error handle. If there is an error, it is\n                recorded in 'err' and this function returns OCI_ERROR.\n                The error recorded in 'err' can be retrieved by calling\n                OCIErrorGet().\n        number (IN) - number whose sign is returned\n        result (OUT) - 0 if number == 0, -1 if number < 0,\n                1 if number > 0\n   DESCRIPTION:\n        Obtains sign of an Oracle number\n   RETURNS:\n        OCI_SUCCESS if the function completes successfully.\n        OCI_INVALID_HANDLE if 'err' is NULL.\n        OCI_ERROR if\n            'number' or 'result' is null\n *)\n\n(*---------------------------- OCINumberIsZero ------------------------------*)\n\n  TOCINumberIsZero = function(err: POCIError; const number: POCINumber;\n                          _Result: pboolean): sword; cdecl;\n(*\n   NAME: OCINumberIsZero - OCINumber comparison with ZERo\n   PARAMETERS:\n        err (IN/OUT) - error handle. If there is an error, it is\n                recorded in 'err' and this function returns OCI_ERROR.\n                The error recorded in 'err' can be retrieved by calling\n                OCIErrorGet().\n        number (IN) - numbers to be compared\n        result (OUT) - set to TRUE if equal to zero else FALSE\n   DESCRIPTION:\n        Test if the given number is equal to zero.\n   RETURNS:\n        OCI_SUCCESS if the function completes successfully.\n        OCI_INVALID_HANDLE if 'err' is NULL.\n        OCI_ERROR if\n            'number' or 'result' is null\n *)\n\n(*---------------------------- OCINumberIsInt -------------------------------*)\n\n  TOCINumberIsInt = function(err: POCIError; const number: POCINumber;\n                          _result: Pboolean): sword; cdecl;\n(*\n   NAME: OCINumberIsInt - OCINumber Is Integer value.\n   PARAMETERS:\n        err (IN/OUT) - error handle. If there is an error, it is\n                recorded in 'err' and this function returns OCI_ERROR.\n                The error recorded in 'err' can be retrieved by calling\n                OCIErrorGet().\n        number (IN) - number to be tested\n        result (OUT) - set to TRUE if integer value else FALSE\n   DESCRIPTION:\n        Test if the given number is an integer value.\n   RETURNS:\n        OCI_SUCCESS if the function completes successfully.\n        OCI_INVALID_HANDLE if 'err' is NULL.\n        OCI_ERROR if\n            'number' or 'result' is null\n *)\n\n(*-------------------------- OCINumberAssign --------------------------------*)\n\n  TOCINumberAssign = function(err: POCIError; const from: POCINumber;\n                          _to: POCINumber): sword; cdecl;\n(*\n   NAME: OCINumberAssign - OCINumber ASsiGn number\n   PARAMETERS:\n        err (IN/OUT) - error handle. If there is an error, it is\n                recorded in 'err' and this function returns OCI_ERROR.\n                The error recorded in 'err' can be retrieved by calling\n                OCIErrorGet().\n        from (IN) - number to be assigned\n        to (OUT) - number copied into\n   DESCRIPTION:\n        Assign number 'from' to 'to'.\n   RETURNS:\n        OCI_SUCCESS if the function completes successfully.\n        OCI_INVALID_HANDLE if 'err' is NULL.\n        OCI_ERROR if\n          'from' or 'to' is null\n *)\n\n(*----------------------------- OCINumberAbs --------------------------------*)\n\n  TOCINumberAbs = function(err: POCIError; const number: POCINumber;\n                       _result: POCINumber): sword; cdecl;\n(*\n   NAME: OCINumberAbs - OCINumber compute ABSolute value\n   PARAMETERS:\n        err (IN/OUT) - error handle. If there is an error, it is\n                recorded in 'err' and this function returns OCI_ERROR.\n                The error recorded in 'err' can be retrieved by calling\n                OCIErrorGet().\n        number (IN) - input number\n        result (OUT) - output which will contain the absolue value of the\n                input number\n   DESCRIPTION:\n        Computes the absolute value of an Oracle number.\n   RETURNS:\n        OCI_SUCCESS if the function completes successfully.\n        OCI_INVALID_HANDLE if 'err' is NULL.\n        OCI_ERROR if\n          any of the number arguments is null\n *)\n\n(*---------------------------- OCINumberCeil --------------------------------*)\n\n  TOCINumberCeil = function(err: POCIError; const number: POCINumber;\n                        _result: POCINumber): sword; cdecl;\n(*\n   NAME: OCINumberCeil - OCINumber compute the CEiL value of an Oracle number\n   PARAMETERS:\n        err (IN/OUT) - error handle. If there is an error, it is\n                recorded in 'err' and this function returns OCI_ERROR.\n                The error recorded in 'err' can be retrieved by calling\n                OCIErrorGet().\n        number (IN) - input number\n        result (OUT) - output which will contain the ceil value of the\n                input number\n   DESCRIPTION:\n        Computes the ceil value of an Oracle number.\n   RETURNS:\n        OCI_SUCCESS if the function completes successfully.\n        OCI_INVALID_HANDLE if 'err' is NULL.\n        OCI_ERROR if\n          any of the number arguments is null\n *)\n\n(*--------------------------- OCINumberFloor --------------------------------*)\n\n  TOCINumberFloor = function(err: POCIError; const number: POCINumber;\n                        _result: POCINumber): sword; cdecl;\n(*\n   NAME: OCINumberFloor - OCINumber compute the FLooR value of an Oracle number\n   PARAMETERS:\n        err (IN/OUT) - error handle. If there is an error, it is\n                recorded in 'err' and this function returns OCI_ERROR.\n                The error recorded in 'err' can be retrieved by calling\n                OCIErrorGet().\n        number (IN) - input number\n        result (OUT) - output which will contain the floor value of the\n                input number\n   DESCRIPTION:\n        Computes the floor value of an Oracle number.\n   RETURNS:\n        OCI_SUCCESS if the function completes successfully.\n        OCI_INVALID_HANDLE if 'err' is NULL.\n        OCI_ERROR if\n          any of the number arguments is null\n *)\n\n(*----------------------------- OCINumberSqrt -------------------------------*)\n\n  TOCINumberSqrt = function(err: POCIError; const number: POCINumber;\n                        _result: POCINumber): sword; cdecl;\n(*\n   NAME: OCINumberSqrt - OCINumber compute the SQuare Root of an Oracle number\n   PARAMETERS:\n        err (IN/OUT) - error handle. If there is an error, it is\n                recorded in 'err' and this function returns OCI_ERROR.\n                The error recorded in 'err' can be retrieved by calling\n                OCIErrorGet().\n        number (IN) - input number\n        result (OUT) - output which will contain the square root of the\n                input number\n   DESCRIPTION:\n        Computes the square root of an Oracle number.\n   RETURNS:\n        OCI_SUCCESS if the function completes successfully.\n        OCI_INVALID_HANDLE if 'err' is NULL.\n        OCI_ERROR if\n          any of the number arguments is null\n          'number' is negative\n *)\n\n(*--------------------------- OCINumberTrunc --------------------------------*)\n\n  TOCINumberTrunc = function(err: POCIError; const number: POCINumber;\n                        _result: POCINumber): sword; cdecl;\n(*\n   NAME: OCINumberTrunc - OCINumber TRUncate an Oracle number at a\n                          specified decimal place\n   PARAMETERS:\n        err (IN/OUT) - error handle. If there is an error, it is\n                recorded in 'err' and this function returns OCI_ERROR.\n                The error recorded in 'err' can be retrieved by calling\n                OCIErrorGet().\n        number (IN) - input number\n        decplace (IN) - number of decimal digits to the right of the\n                decimal point to truncate at. Negative values are allowed.\n        result (OUT) - output of truncation\n   DESCRIPTION:\n        Truncate an Oracle number at a specified decimal place\n   RETURNS:\n        OCI_SUCCESS if the function completes successfully.\n        OCI_INVALID_HANDLE if 'err' is NULL.\n        OCI_ERROR if\n          any of the number arguments is null\n *)\n\n(*----------------------------- OCINumberPower ------------------------------*)\n\n  TOCINumberPower = function(err: POCIError; const base: POCINumber;\n                         const number: POCINumber; _result: POCINumber): sword; cdecl;\n(*\n   NAME: OCINumberPower - OCINumber takes an arbitary Base to an\n                          arbitary Power\n   PARAMETERS:\n        err (IN/OUT) - error handle. If there is an error, it is\n                recorded in 'err' and this function returns OCI_ERROR.\n                The error recorded in 'err' can be retrieved by calling\n                OCIErrorGet().\n        base (IN) - base of the exponentiation\n        number (IN) - exponent to which the base is to be raised\n        result (OUT) - output of exponentiation\n   DESCRIPTION:\n        Takes an arbitary base to an arbitary power.\n   RETURNS:\n        OCI_SUCCESS if the function completes successfully.\n        OCI_INVALID_HANDLE if 'err' is NULL.\n        OCI_ERROR if\n          any of the number arguments is null\n *)\n\n(*--------------------------- OCINumberRound --------------------------------*)\n\n  TOCINumberRound = function(err: POCIError; const number: POCINumber;\n                         decplace: sword; _result: POCINumber): sword; cdecl;\n(*\n   NAME: OCINumberRound - OCINumber ROUnds an Oracle number to a specified\n                  decimal place\n   PARAMETERS:\n        err (IN/OUT) - error handle. If there is an error, it is\n                recorded in 'err' and this function returns OCI_ERROR.\n                The error recorded in 'err' can be retrieved by calling\n                OCIErrorGet().\n        number (IN) - round this number and return result in 'result'\n        decplace (IN) - number of decimal digits to the right of the\n                decimal point to round to. Negative values are allowed.\n        result (OUT) - output of rounding\n   DESCRIPTION:\n        Rounds an Oracle number to a specified decimal place\n   RETURNS:\n        OCI_SUCCESS if the function completes successfully.\n        OCI_INVALID_HANDLE if 'err' is NULL.\n        OCI_ERROR if\n          any of the number arguments is null\n *)\n\n(*--------------------------- OCINumberPrec ---------------------------------*)\n\n  TOCINumberPrec = function(err: POCIError; const number: POCINumber;\n                         nDigs: sword; _result: POCINumber): sword; cdecl;\n(*\n   NAME: OCINumberPrec - Rounds an Oracle number to a specified number of\n                         decimal digits.\n   PARAMETERS:\n        err (IN/OUT) - error handle. If there is an error, it is\n                recorded in 'err' and this function returns OCI_ERROR.\n                The error recorded in 'err' can be retrieved by calling\n                OCIErrorGet().\n        number (IN) - number for which to set precision.\n        nDig   (IN) - number of decimal digits desired in the result.\n        result (OUT) - result.\n   DESCRIPTION:\n        Performs a floating point round with respect to the number\n        of digits.\n   RETURNS:\n        OCI_SUCCESS if the function completes successfully.\n        OCI_INVALID_HANDLE if 'err' is NULL.\n        OCI_ERROR if\n          any of the number arguments is null\n *)\n\n(*----------------------------- OCINumberSin --------------------------------*)\n\n  TOCINumberSin = function(err: POCIError; const number: POCINumber;\n                       _result: POCINumber): sword; cdecl;\n(*\n   NAME: OCINumberSin - OCINumber takes the SINe of an Oracle number\n   PARAMETERS:\n        err (IN/OUT) - error handle. If there is an error, it is\n                recorded in 'err' and this function returns OCI_ERROR.\n                The error recorded in 'err' can be retrieved by calling\n                OCIErrorGet().\n        number (IN) - argument of the sine in radians\n        result (OUT) - result of the sine\n   DESCRIPTION:\n        Takes the sine in radians of an Oracle number.\n   RETURNS:\n        OCI_SUCCESS if the function completes successfully.\n        OCI_INVALID_HANDLE if 'err' is NULL.\n        OCI_ERROR if\n          any of the number arguments is null\n *)\n\n(*-------------------------- OCINumberArcSin --------------------------------*)\n\n  TOCINumberArcSin = function(err: POCIError; const number: POCINumber;\n                       _result: POCINumber): sword; cdecl;\n(*\n   NAME: OCINumberArcSin - OCINumber takes the Arc SINe of an Oracle number\n   PARAMETERS:\n        err (IN/OUT) - error handle. If there is an error, it is\n                recorded in 'err' and this function returns OCI_ERROR.\n                The error recorded in 'err' can be retrieved by calling\n                OCIErrorGet().\n        number (IN) - argument of the arc sine\n        result (OUT) - result of the arc sine in radians\n   DESCRIPTION:\n        Takes the arc sine in radians of an Oracle number.\n   RETURNS:\n        OCI_SUCCESS if the function completes successfully.\n        OCI_INVALID_HANDLE if 'err' is NULL.\n        OCI_ERROR if\n          any of the number arguments is null\n          'number' is < -1 or 'number' is > 1.\n *)\n\n(*-------------------------- OCINumberHypSin --------------------------------*)\n\n  TOCINumberHypSin = function(err: POCIError; const number: POCINumber;\n                       _result: POCINumber): sword; cdecl;\n(*\n   NAME: OCINumberHypSin - OCINumber takes the SiNe Hyperbolic of an\n                           Oracle number\n   PARAMETERS:\n        err (IN/OUT) - error handle. If there is an error, it is\n                recorded in 'err' and this function returns OCI_ERROR.\n                The error recorded in 'err' can be retrieved by calling\n                OCIErrorGet().\n        number (IN) - argument of the sine hyperbolic\n        result (OUT) - result of the sine hyperbolic\n   DESCRIPTION:\n        Takes the hyperbolic sine of an Oracle number.\n   RETURNS:\n        OCI_SUCCESS if the function completes successfully.\n        OCI_INVALID_HANDLE if 'err' is NULL.\n        OCI_ERROR if\n          any of the number arguments is null\n   NOTES:\n        An Oracle number overflow causes an unpredictable result value.\n *)\n\n(*----------------------------- OCINumberCos --------------------------------*)\n\n  TOCINumberCos = function(err: POCIError; const number: POCINumber;\n                       _result: POCINumber): sword; cdecl;\n(*\n   NAME: OCINumberCos - OCINumber takes the COSine of an Oracle number\n   PARAMETERS:\n        err (IN/OUT) - error handle. If there is an error, it is\n                recorded in 'err' and this function returns OCI_ERROR.\n                The error recorded in 'err' can be retrieved by calling\n                OCIErrorGet().\n        number (IN) - argument of the cosine in radians\n        result (OUT) - result of the cosine\n   DESCRIPTION:\n        Takes the cosine in radians of an Oracle number.\n   RETURNS:\n        OCI_SUCCESS if the function completes successfully.\n        OCI_INVALID_HANDLE if 'err' is NULL.\n        OCI_ERROR if\n          any of the number arguments is null\n *)\n\n(*-------------------------- OCINumberArcCos --------------------------------*)\n\n  TOCINumberArcCos = function(err: POCIError; const number: POCINumber;\n                       _result: POCINumber): sword; cdecl;\n(*\n   NAME: OCINumberArcCos - OCINumber takes the Arc COSine of an Oracle number\n   PARAMETERS:\n        err (IN/OUT) - error handle. If there is an error, it is\n                recorded in 'err' and this function returns OCI_ERROR.\n                The error recorded in 'err' can be retrieved by calling\n                OCIErrorGet().\n        number (IN) - argument of the arc cosine\n        result (OUT) - result of the arc cosine in radians\n   DESCRIPTION:\n        Takes the arc cosine in radians of an Oracle number.\n   RETURNS:\n        OCI_SUCCESS if the function completes successfully.\n        OCI_INVALID_HANDLE if 'err' is NULL.\n        OCI_ERROR if\n          any of the number arguments is null\n          'number' is < -1 or 'number' is > 1.\n *)\n\n(*-------------------------- OCINumberHypCos --------------------------------*)\n\n  TOCINumberHypCos = function(err: POCIError; const number: POCINumber;\n                       _result: POCINumber): sword; cdecl;\n(*\n   NAME: OCINumberHypCos - OCINumber takes the CoSine Hyperbolic of an\n                           Oracle number\n   PARAMETERS:\n        err (IN/OUT) - error handle. If there is an error, it is\n                recorded in 'err' and this function returns OCI_ERROR.\n                The error recorded in 'err' can be retrieved by calling\n                OCIErrorGet().\n        number (IN) - argument of the cosine hyperbolic\n        result (OUT) - result of the cosine hyperbolic\n   DESCRIPTION:\n        Takes the hyperbolic cosine of an Oracle number.\n   RETURNS:\n        OCI_SUCCESS if the function completes successfully.\n        OCI_INVALID_HANDLE if 'err' is NULL.\n        OCI_ERROR if\n          any of the number arguments is null\n   NOTES:\n        An Oracle number overflow causes an unpredictable result value.\n *)\n\n(*----------------------------- OCINumberTan --------------------------------*)\n\n  TOCINumberTan = function(err: POCIError; const number: POCINumber;\n                       _result: POCINumber): sword; cdecl;\n(*\n   NAME: OCINumberTan - OCINumber takes the TANgent of an Oracle number\n   PARAMETERS:\n        err (IN/OUT) - error handle. If there is an error, it is\n                recorded in 'err' and this function returns OCI_ERROR.\n                The error recorded in 'err' can be retrieved by calling\n                OCIErrorGet().\n        number (IN) - argument of the tangent in radians\n        result (OUT) - result of the tangent\n   DESCRIPTION:\n        Takes the tangent in radians of an Oracle number.\n   RETURNS:\n        OCI_SUCCESS if the function completes successfully.\n        OCI_INVALID_HANDLE if 'err' is NULL.\n        OCI_ERROR if\n          any of the number arguments is null\n *)\n\n(*-------------------------- OCINumberArcTan --------------------------------*)\n\n  TOCINumberArcTan = function(err: POCIError; const number: POCINumber;\n                       _result: POCINumber): sword; cdecl;\n(*\n   NAME: OCINumberArcTan - OCINumber takes the Arc TANgent of an Oracle number\n   PARAMETERS:\n        err (IN/OUT) - error handle. If there is an error, it is\n                recorded in 'err' and this function returns OCI_ERROR.\n                The error recorded in 'err' can be retrieved by calling\n                OCIErrorGet().\n        number (IN) - argument of the arc tangent\n        result (OUT) - result of the arc tangent in radians\n   DESCRIPTION:\n        Takes the arc tangent in radians of an Oracle number.\n   RETURNS:\n        OCI_SUCCESS if the function completes successfully.\n        OCI_INVALID_HANDLE if 'err' is NULL.\n        OCI_ERROR if\n          any of the number arguments is null\n *)\n\n(*------------------------ OCINumberArcTan2 ---------------------------------*)\n\n  TOCINumberArcTan2 = function(err: POCIError; const number1: POCINumber;\n                  const number2: POCINumber; _result: POCINumber): sword; cdecl;\n(*\n   NAME: OCINumberArcTan2 - OCINumber takes the ATan2 of 2 Oracle numbers\n   PARAMETERS:\n        err (IN/OUT) - error handle. If there is an error, it is\n                recorded in 'err' and this function returns OCI_ERROR.\n                The error recorded in 'err' can be retrieved by calling\n                OCIErrorGet().\n        number1 (IN) - first argument of atan2(y,x) function which\n                corresponds to 'y' parameter in the function\n        number2 (IN) - second argument of atan2(y,x) function which\n                corresponds to 'x' parameter in the function\n        result (OUT) - result of the atan2() in radians\n   DESCRIPTION:\n        Takes the atan2(number1, number2).\n   RETURNS:\n        OCI_SUCCESS if the function completes successfully.\n        OCI_INVALID_HANDLE if 'err' is NULL.\n        OCI_ERROR if\n          any of the number arguments is null\n          'number2' is 0\n *)\n\n(*----------------------------- OCINumberHypTan -----------------------------*)\n\n  TOCINumberHypTan = function(err: POCIError; const number: POCINumber;\n                       _result: POCINumber): sword; cdecl;\n(*\n   NAME: OCINumberHypTan - OCINumber takes the TaNgent Hyperbolic of an Oracle\n                           number\n   PARAMETERS:\n        err (IN/OUT) - error handle. If there is an error, it is\n                recorded in 'err' and this function returns OCI_ERROR.\n                The error recorded in 'err' can be retrieved by calling\n                OCIErrorGet().\n        number (IN) - argument of the tangent hyperbolic\n        result (OUT) - result of the tangent hyperbolic\n   DESCRIPTION:\n        Takes the hyperbolic tangent of an Oracle number.\n   RETURNS:\n        OCI_SUCCESS if the function completes successfully.\n        OCI_INVALID_HANDLE if 'err' is NULL.\n        OCI_ERROR if\n          any of the number arguments is null\n   NOTES:\n        An Oracle number overflow causes an unpredictable result value.\n *)\n\n(*--------------------------- OCINumberExp ----------------------------------*)\n\n  TOCINumberExp = function(err: POCIError; const number: POCINumber;\n                       _result: POCINumber): sword; cdecl;\n(*\n   NAME: OCINumberExp - OCINumber EXPonential\n   PARAMETERS:\n        err (IN/OUT) - error handle. If there is an error, it is\n                recorded in 'err' and this function returns OCI_ERROR.\n                The error recorded in 'err' can be retrieved by calling\n                OCIErrorGet().\n        number (IN) - e raised to this Oracle number power\n        result (OUT) - output of exponentiation\n   DESCRIPTION:\n        Raises e to the specified Oracle number power\n   RETURNS:\n        OCI_SUCCESS if the function completes successfully.\n        OCI_INVALID_HANDLE if 'err' is NULL.\n        OCI_ERROR if\n          any of the number arguments is null\n *)\n\n(*----------------------------- OCINumberLn ---------------------------------*)\n\n  TOCINumberLn = function(err: POCIError; const number: POCINumber;\n                       _result: POCINumber): sword; cdecl;\n(*\n   NAME: OCINumberLn - OCINumber Logarithm Natural\n   PARAMETERS:\n        err (IN/OUT) - error handle. If there is an error, it is\n                recorded in 'err' and this function returns OCI_ERROR.\n                The error recorded in 'err' can be retrieved by calling\n                OCIErrorGet().\n        number (IN) - logarithm of this number is computed\n        result (OUT) - logarithm result\n   DESCRIPTION:\n        Takes the logarithm of the given Oracle number with respect\n        to the given base.\n   RETURNS:\n        OCI_SUCCESS if the function completes successfully.\n        OCI_INVALID_HANDLE if 'err' is NULL.\n        OCI_ERROR if\n          any of the number arguments is null\n          'number' is <= 0\n *)\n\n(*----------------------------- OCINumberLog --------------------------------*)\n\n  TOCINumberLog = function(err: POCIError; const base: POCINumber;\n                       const number: POCINumber; _result: POCINumber): sword; cdecl;\n(*\n   NAME: OCINumberLog - OCINumber LOGarithm any base\n   PARAMETERS:\n        err (IN/OUT) - error handle. If there is an error, it is\n                recorded in 'err' and this function returns OCI_ERROR.\n                The error recorded in 'err' can be retrieved by calling\n                OCIErrorGet().\n        base (IN) - base of the logarithm\n        number (IN) - opearnd\n        result (OUT) - logarithm result\n   DESCRIPTION:\n        Takes the logarithm with the specified base of an Oracle number.\n   RETURNS:\n        OCI_SUCCESS if the function completes successfully.\n        OCI_INVALID_HANDLE if 'err' is NULL.\n        OCI_ERROR if\n          any of the number arguments is null\n          'number' is <= 0\n          'base' is <= 0\n *)\n\n(*****************************************************************************\n *                             ORACLE DATE TYPE                              *\n *****************************************************************************)\n\n  POCITime = ^TOCITime;\n  TOCITime = record\n    OCITimeHH: ub1;                     // hours; range is 0 <= hours <=23\n    OCITimeMI: ub1;                     // minutes; range is 0 <= minutes <= 59\n    OCITimeSS: ub1;                     // seconds; range is 0 <= seconds <= 59\n  end;\n\n(*\n * OCITime - OCI TiMe portion of date\n *\n * This structure should be treated as an opaque structure as the format\n * of this structure may change. Use OCIDateGetTime/OCIDateSetTime\n * to manipulate time portion of OCIDate.\n *)\n\n  POCIDate = ^TOCIDate;\n  TOCIDate = record\n    OCIDateYYYY: sb2;         // gregorian year; range is -4712 <= year <= 9999\n    OCIDateMM: ub1;           // month; range is 1 <= month < 12\n    OCIDateDD: ub1;           // day; range is 1 <= day <= 31\n    OCIDateTime: TOCITime;    // time\n  end;\n\n(*\n * OCIDate - OCI oracle Date representation in C\n *\n * OCIDate represents the C mapping of Oracle date.\n *\n * This structure should be treated as an opaque structure as the format\n * of this structure may change. Use OCIDateGetDate/OCIDateSetDate\n * to access/initialize OCIDate.\n *\n * For binding variables of type OCIDate in OCI calls (OCIBindByName(),\n * OCIBindByPos(), and OCIDefineByPos()) use the type code SQLT_ODT.\n *)\n\n(*\n   EXAMPLE\n\n   The following example shows how to manipulate an attribute of type\n   oracle date.\n\n     #define FMT \"Month dd, YYYY, HH:MI A.M.\"\n     #define LANG \"American\"\n\n     struct person\n     {\n       OCIDate start_date;\n     };\n     typedef struct person person;\n\n     OCIError *err;\n     person *joe;\n     sword status;                                           /o error status o/\n\n     /o See oci.h for an example of how to initialize OCIError.\n      o For this example, assume the OCIEnv and OCIError has been\n      o initialized.\n      o/\n\n     /o Pin joe person object in the object cache. See ori.h\n      o for an example on pinning objects. For this example, assume that\n      o joe is pointing to the pinned object.\n      o/\n\n     /o set the start date of joe o/\n     OCIDateSetTime(&joe->start_date, 8, 0, 0);\n     OCIDateSetDate(&joe->start_date, 1990, 10, 5);\n\n     /o check if the date is valid o/\n     uword invalid;\n     if (OCIDateCheck(err, &joe->start_date, &invalid) != OCI_SUCCESS)\n       /o error handling code o/\n     if (invalid)\n       /o error handling code o/\n\n     /o convert date for display purposes o/\n     char str[100];\n     ub4 strlen = sizeof(str);\n     if (OCIDateToText(err, &joe->start_date, FMT, sizeof(FMT)-1, LANG,\n                sizeof(LANG)-1, &strlen, str) != OCI_SUCCESS)\n       /o error handling code o/\n\n *)\n\n(*--------------------------- OCIDateGetTime --------------------------------*/\n/* void OCIDateGetTime(/o_ const OCIDate *date, ub1 *hour, ub1 *min,\n                           ub1 *sec _o/); */\n#define OCIDateGetTime(date, hour, min, sec) \\\n  { \\\n     *hour = (date)->OCIDateTime.OCITimeHH; \\\n     *min = (date)->OCIDateTime.OCITimeMI; \\\n     *sec = (date)->OCIDateTime.OCITimeSS; \\\n  }\n/*\n   NAME: OCIDateGetTime - OCIDate Get Time portion of date\n   PARAMETERS:\n        date (IN) - Oracle date whose time data is retrieved\n        hour (OUT) - hour value returned\n        min (OUT) - minute value returned\n        sec (OUT) - second value returned\n   DESCRIPTION:\n        Return time inforamtion stored in the given date. The time\n        information returned is: hour, minute and seconds.\n   RETURNS:\n        NONE\n */\n\n/*--------------------------- OCIDateGetDate --------------------------------*/\n/* void OCIDateGetDate(/o_ const OCIDate *date, sb2 *year, ub1 *month,\n                           ub1 *day _o/); */\n#define OCIDateGetDate(date, year, month, day) \\\n  { \\\n     *year = (date)->OCIDateYYYY; \\\n     *month = (date)->OCIDateMM; \\\n     *day = (date)->OCIDateDD; \\\n  }\n/*\n   NAME: OCIDateGetDate - OCIDate Get Date (year, month, day) portion of date\n   PARAMETERS:\n        date (IN) - Oracle date whose year, month, day data is retrieved\n        year (OUT) - year value returned\n        month (OUT) - month value returned\n        day (OUT) - day value returned\n   DESCRIPTION:\n        Return year, month, day inforamtion stored in the given date.\n   RETURNS:\n        NONE\n */\n\n/*--------------------------- OCIDateSetTime --------------------------------*/\n/* void OCIDateSetTime(/o_ OCIDate *date, ub1 hour, ub1 min,\n                           ub1 sec _o/); */\n#define OCIDateSetTime(date, hour, min, sec) \\\n  { \\\n     (date)->OCIDateTime.OCITimeHH = hour; \\\n     (date)->OCIDateTime.OCITimeMI = min; \\\n     (date)->OCIDateTime.OCITimeSS = sec; \\\n  }\n/*\n   NAME: OCIDateSetTime - OCIDate Set Time portion of date\n   PARAMETERS:\n        date (OUT) - Oracle date whose time data is set\n        hour (IN) - hour value to be set\n        min (IN) - minute value to be set\n        sec (IN) - second value to be set\n   DESCRIPTION:\n        Set the date with the given time inforamtion.\n   RETURNS:\n        NONE\n */\n\n/*--------------------------- OCIDateSetDate --------------------------------*/\n/* void OCIDateSetDate(/o_ OCIDate *date, sb2 year, ub1 month, ub1 day _o/); */\n#define OCIDateSetDate(date, year, month, day) \\\n  { \\\n     (date)->OCIDateYYYY = year; \\\n     (date)->OCIDateMM = month; \\\n     (date)->OCIDateDD = day; \\\n  }\n/*\n   NAME: OCIDateSetDate - OCIDate Set Date (year, month, day) portion of date\n   PARAMETERS:\n        date (IN) - Oracle date whose year, month, day data is set\n        year (OUT) - year value to be set\n        month (OUT) - month value to be set\n        day (OUT) - day value to be set\n   DESCRIPTION:\n        Set the date with the given year, month, day inforamtion.\n   RETURNS:\n        NONE\n *)\n\n(*--------------------------- OCIDateAssign ---------------------------------*)\n\n  TOCIDateAssign = function(err: POCIError; const from: POCIDate;\n                        _to: POCIDate): sword; cdecl;\n(*\n   NAME: OCIDateAssign - OCIDate Assignment\n   PARAMETERS:\n        err (IN/OUT) - error handle. If there is an error, it is\n                recorded in 'err' and this function returns OCI_ERROR.\n                The error recorded in 'err' can be retrieved by calling\n                OCIErrorGet().\n        from (IN) - date to be assigned\n        to (OUT) - lhs of assignment\n   DESCRIPTION:\n        Performs date assignment.\n   RETURNS:\n        OCI_SUCCESS\n *)\n\n(*--------------------------- OCIDateToText ---------------------------------*)\n\n  TOCIDateToText = function(err: POCIError; const date: POCIDate;\n                        const fmt: poratext; fmt_length: ub1;\n                        const lang_name: poratext; lang_length: ub4;\n                        buf_size: pub4; buf: poratext): sword; cdecl;\n(*\n   NAME: OCIDateToText - OCIDate convert date TO String\n   PARAMETERS:\n        err (IN/OUT) - error handle. If there is an error, it is\n                recorded in 'err' and this function returns OCI_ERROR.\n                The error recorded in 'err' can be retrieved by calling\n                OCIErrorGet().\n        date (IN) - Oracle date to be converted\n        fmt (IN) - conversion format, if null string pointer (oratext * )0, then\n                the date is converted to a character string in the\n                date format \"DD-MON-YY\".\n        fmt_length (IN) - length of the 'fmt' parameter\n        lang_name (IN) - specifies the language in which the names and\n                abbreviations of months and days are returned;\n                default language of session is used if 'lang_name'\n                is null i.e. (oratext * )0\n        lang_length (IN) - length of the 'nls_params' parameter\n        buf_size (IN/OUT) - size of the buffer; size of the resulting string\n                is returned via this parameter\n        buf (OUT) - buffer into which the converted string is placed\n   DESCRIPTION:\n        Converts the given date to a string according to the specified format.\n        Refer to \"TO_DATE\" conversion function described in\n        \"Oracle SQL Language Reference Manual\" for a description of format\n        and NLS arguments. The converted null-terminated date string is\n        stored in the buffer 'buf'.\n\n        An error is reported upon overflow, e.g. trying to convert a number\n        of value 10 using format '9' causes an overflow.\n   RETURNS:\n        OCI_SUCCESS if the function completes successfully.\n        OCI_INVALID_HANDLE if 'err' is NULL.\n        OCI_ERROR if\n          buffer too small\n          invalid format\n          unknown language\n          overflow error\n *)\n\n(*---------------------------- OCIDateFromText ------------------------------*)\n\n  TOCIDateFromText = function(err: POCIError; const date_str: poratext;\n                        d_str_length: ub4; const fmt: poratext; fmt_length: ub1;\n                        const lang_name: poratext; lang_length: ub4;\n                        date: POCIDate): sword; cdecl;\n(*\n   NAME: OCIDateFromText - OCIDate convert String TO Date\n   PARAMETERS:\n        err (IN/OUT) - error handle. If there is an error, it is\n                recorded in 'err' and this function returns OCI_ERROR.\n                The error recorded in 'err' can be retrieved by calling\n                OCIErrorGet().\n        date_str (IN) - input string to be converted to Oracle date\n        d_str_length (IN) - size of the input string, if the length is -1\n                then 'date_str' is treated as a null terminated  string\n        fmt (IN) - conversion format; if 'fmt' is a null pointer, then\n                the string is expected to be in 'DD-MON-YY' format.\n        fmt_length (IN) - length of the 'fmt' parameter\n        lang_name (IN) - language in which the names and abbreviations of\n                days and months are specified, if null i.e. (oratext * )0,\n                the default language of session is used,\n        lang_length (IN) - length of the 'lang_name' parameter\n        date (OUT) - given string converted to date\n   DESCRIPTION:\n        Converts the given string to Oracle date\n        according to the specified format. Refer to \"TO_DATE\" conversion\n        function described in \"Oracle SQL Language Reference Manual\" for a\n        description of format.\n   RETURNS:\n        OCI_SUCCESS if the function completes successfully.\n        OCI_INVALID_HANDLE if 'err' is NULL.\n        OCI_ERROR if\n          invalid format\n          unknown language\n          invalid input string\n          <to be discovered>\n *)\n\n(*----------------------------- OCIDateCompare ------------------------------*)\n\n  TOCIDateCompare = function(err: POCIError; const date1: POCIDate;\n                     const date2: POCIDate; _result: psword): sword; cdecl;\n(*\n   NAME: OCIDateCompare - OCIDate CoMPare dates\n   PARAMETERS:\n        err (IN/OUT) - error handle. If there is an error, it is\n                recorded in 'err' and this function returns OCI_ERROR.\n                The error recorded in 'err' can be retrieved by calling\n                OCIErrorGet().\n        date1, date2 (IN) - dates to be compared\n        result (OUT) - comparison result, 0 if equal, -1 if date1 < date2,\n                1 if date1 > date2\n   DESCRIPTION:\n        The function OCIDateCompare compares two dates. It returns -1 if date1\n        is smaller than date2, 0 if they are equal, and 1 if date1 is greater\n        than date2.\n   RETURNS:\n        OCI_SUCCESS if the function completes successfully.\n        OCI_INVALID_HANDLE if 'err' is NULL.\n        OCI_ERROR if\n          invalid date\n          <to be discovered>\n *)\n\n(*------------------------- OCIDateAddMonths --------------------------------*)\n\n  TOCIDateAddMonths = function(err: POCIError; const date: POCIDate;\n                          num_months: sb4; _result: POCIDate): sword; cdecl;\n(*\n   NAME: OCIDateAddMonths - OCIDate ADd or subtract Months\n   PARAMETERS:\n        err (IN/OUT) - error handle. If there is an error, it is\n                recorded in 'err' and this function returns OCI_ERROR.\n                The error recorded in 'err' can be retrieved by calling\n                OCIErrorGet().\n        date (IN) - 'num_months' added or subtracted from 'date'\n        num_months (IN) - number of months to be added or subtracted\n                (a negative value will be subtracted)\n        result (IN/OUT) - result of adding or subtracting to 'date'\n   DESCRIPTION:\n        The function OCIDateAddDays adds or subtracts num_months from the\n        date 'date'.\n          If the input 'date' is the last day of a month, then\n        appropriate adjustments are made to ensure that the output date is\n        also the last day of the month. For example, Feb. 28 + 1 month =\n        March 31, and November 30 - 3 months = August 31. Otherwise the\n        'result' date has the same day component as 'date'.\n   RETURNS:\n        OCI_SUCCESS if the function completes successfully.\n        OCI_INVALID_HANDLE if 'err' is NULL.\n        OCI_ERROR if\n          invalid date\n          <to be discovered>\n *)\n\n(*--------------------------- OCIDateAddDays --------------------------------*)\n\n  TOCIDateAddDays = function(err: POCIError; const date: POCIDate; num_days: sb4;\n                         _result: POCIDate):sword; cdecl;\n(*\n   NAME: OCIDateAddDays - OCIDate ADd or subtract Days\n   PARAMETERS:\n        err (IN/OUT) - error handle. If there is an error, it is\n                recorded in 'err' and this function returns OCI_ERROR.\n                The error recorded in 'err' can be retrieved by calling\n                OCIErrorGet().\n        date (IN) - 'num_days' added or subtracted from 'date'\n        num_days (IN) - number of days to be added or subtracted\n                (a negative value will be subtracted)\n        result (IN/OUT) - result of adding or subtracting to 'date'\n   DESCRIPTION:\n        The function OCIDateAddDays adds or subtracts num_days from the\n        date 'date'.\n   RETURNS:\n        OCI_SUCCESS if the function completes successfully.\n        OCI_INVALID_HANDLE if 'err' is NULL.\n        OCI_ERROR if\n          invalid date\n          <to be discovered>\n *)\n\n(*--------------------------- OCIDateLastDay --------------------------------*)\n\n  TOCIDateLastDay = function(err: POCIError; const date: POCIDate;\n                         last_day: POCIDate): sword; cdecl;\n(*\n   NAME: OCIDateLastDay - OCIDate get date of the LaST day of the month\n   PARAMETERS:\n        err (IN/OUT) - error handle. If there is an error, it is\n                recorded in 'err' and this function returns OCI_ERROR.\n                The error recorded in 'err' can be retrieved by calling\n                OCIErrorGet().\n        date (IN) - input date\n        last_day (OUT) - last day of the month in date 'date'\n   DESCRIPTION:\n        The function OCIDateLastDay returns the date of the last day of the\n        month in date 'date'.\n   RETURNS:\n        OCI_SUCCESS if the function completes successfully.\n        OCI_INVALID_HANDLE if 'err' is NULL.\n        OCI_ERROR if\n          invalid date\n          <to be discovered>\n *)\n\n(*----------------------- OCIDateDaysBetween --------------------------------*)\n\n  TOCIDateDaysBetween = function(err: POCIError; const date1: POCIDate;\n                             const dtae2: POCIDate; num_days: psb4): sword; cdecl;\n(*\n   NAME: OCIDateDaysBetween - OCIDate get number of days BeTWeen two dates\n   PARAMETERS:\n        err (IN/OUT) - error handle. If there is an error, it is\n                recorded in 'err' and this function returns OCI_ERROR.\n                The error recorded in 'err' can be retrieved by calling\n                OCIErrorGet().\n        date1, date2 (IN) - input dates\n        num_days (OUT) - number of days between date1 and date2\n   DESCRIPTION:\n        The function OCIDateDaysBetween returns the number of days between\n        date1 and date2. The time is ignored in this computation.\n   RETURNS:\n        OCI_SUCCESS if the function completes successfully.\n        OCI_INVALID_HANDLE if 'err' is NULL.\n        OCI_ERROR if\n          invalid date\n          <to be discovered>\n *)\n\n(*------------------------ OCIDateZoneToZone --------------------------------*)\n\n  TOCIDateZoneToZone = function(err: POCIError; const date1: POCIDate;\n                            const zon1: poratext;\n                            zon1_length: ub4; const zon2: poratext;\n                            zon2_length: ub4; dtae2: POCIDate): sword; cdecl;\n(*\n   NAME: OCIDateZoneToZone - OCIDate convert date from one Zone TO another Zone\n   PARAMETERS:\n        err (IN/OUT) - error handle. If there is an error, it is\n                recorded in 'err' and this function returns OCI_ERROR.\n                The error recorded in 'err' can be retrieved by calling\n                OCIErrorGet().\n        date1 (IN) - date to be converted\n        zon1 (IN) - zone of input date\n        zon1_length (IN) - length in bytes of string 'zon1'\n        zon2 (IN) - zone to be converted to\n        zon2_length (IN) - length in bytes of string 'zon2'\n        date2 (OUT) - converted date (in 'zon2')\n   DESCRIPTION:\n        Converts date from one time zone to another. Given date 'date1'\n        in time zone 'zon1' returns date 'date2' in time zone 'zon2'.\n   RETURNS:\n        OCI_SUCCESS if the function completes successfully.\n        OCI_INVALID_HANDLE if 'err' is NULL.\n        OCI_ERROR if\n          invlid date\n          invald input time zone\n          invald output time zone\n          <to be discovered>\n *)\n\n(*--------------------------- OCIDateNextDay --------------------------------*)\n\n  TOCIDateNextDay = function(err: POCIError; const dtae: POCIDate;\n                         const day_p: poratext; day_length: ub4;\n                         next_day: POCIDate): sword; cdecl;\n(*\n   NAME: OCIDateNextDay - OCIDate get date of Next DaY\n   PARAMETERS:\n        err (IN/OUT) - error handle. If there is an error, it is\n                recorded in 'err' and this function returns OCI_ERROR.\n                The error recorded in 'err' can be retrieved by calling\n                OCIErrorGet().\n        date (IN) - returned date should be later than this date\n        day (IN) - first day of week named by this is returned\n        day_length (IN) - length in bytes of string 'day'\n        next_day (OUT) - first day of the week named by 'day' later than 'date'\n   DESCRIPTION:\n        Returns the date of the first day of the\n        week named by 'day' that is later than date 'date'.\n   RETURNS:\n        OCI_SUCCESS if the function completes successfully.\n        OCI_INVALID_HANDLE if 'err' is NULL.\n        OCI_ERROR if\n          invalid date\n          invalid day\n          <to be discovered>\n */\n\n/*----------------------------- OCIDateCheck --------------------------------*/\n\n/* Listing of error bits used by OCIDateCheck() */\n#define OCI_DATE_INVALID_DAY            0x1                       /* Bad DAy */\n#define OCI_DATE_DAY_BELOW_VALID        0x2   /* Bad DAy Low/high bit (1=low)*/\n#define OCI_DATE_INVALID_MONTH          0x4                     /* Bad MOnth */\n#define OCI_DATE_MONTH_BELOW_VALID      0x8 /* Bad MOnth Low/high bit (1=low)*/\n#define OCI_DATE_INVALID_YEAR           0x10                     /* Bad YeaR */\n#define OCI_DATE_YEAR_BELOW_VALID       0x20 /* Bad YeaR Low/high bit (1=low)*/\n#define OCI_DATE_INVALID_HOUR           0x40                     /* Bad HouR */\n#define OCI_DATE_HOUR_BELOW_VALID       0x80 /* Bad HouR Low/high bit (1=low)*/\n#define OCI_DATE_INVALID_MINUTE         0x100                  /* Bad MiNute */\n#define OCI_DATE_MINUTE_BELOW_VALID     0x200\n                                           /* Bad MiNute Low/high bit (1=low)*/\n#define OCI_DATE_INVALID_SECOND         0x400                  /* Bad SeCond */\n#define OCI_DATE_SECOND_BELOW_VALID     0x800\n                                           /* bad second Low/high bit (1=low)*/\n#define OCI_DATE_DAY_MISSING_FROM_1582  0x1000\n                                  /* Day is one of those \"missing\" from 1582 */\n#define OCI_DATE_YEAR_ZERO              0x2000    /* Year may not equal zero */\n#define OCI_DATE_INVALID_FORMAT         0x8000      /* Bad date format input */\n\nsword OCIDateCheck(    OCIError *err, const OCIDate *date, uword *valid    );\n/*\n   NAME: OCIDateCheck - OCIDate CHecK if the given date is valid\n   PARAMETERS:\n        err (IN/OUT) - error handle. If there is an error, it is\n                recorded in 'err' and this function returns OCI_ERROR.\n                The error recorded in 'err' can be retrieved by calling\n                OCIErrorGet().\n        date (IN) - date to be checked\n        valid (OUT) -  returns zero for a valid date, otherwise\n                the ORed combination of all error bits specified below:\n\n   Macro name                   Bit number      Error\n   ----------                   ----------      -----\n   OCI_DATE_INVALID_DAY         0x1             Bad day\n   OCI_DATE_DAY_BELOW_VALID     0x2             Bad DAy Low/high bit (1=low)\n   OCI_DATE_INVALID_MONTH       0x4             Bad MOnth\n   OCI_DATE_MONTH_BELOW_VALID   0x8             Bad MOnth Low/high bit (1=low)\n   OCI_DATE_INVALID_YEAR        0x10            Bad YeaR\n   OCI_DATE_YEAR_BELOW_VALID    0x20            Bad YeaR Low/high bit (1=low)\n   OCI_DATE_INVALID_HOUR        0x40            Bad HouR\n   OCI_DATE_HOUR_BELOW_VALID    0x80            Bad HouR Low/high bit (1=low)\n   OCI_DATE_INVALID_MINUTE      0x100           Bad MiNute\n   OCI_DATE_MINUTE_BELOW_VALID  0x200           Bad MiNute Low/high bit (1=low)\n   OCI_DATE_INVALID_SECOND      0x400           Bad SeCond\n   OCI_DATE_SECOND_BELOW_VALID  0x800           bad second Low/high bit (1=low)\n   OCI_DATE_DAY_MISSING_FROM_1582 0x1000        Day is one of those \"missing\"\n                                                from 1582\n   OCI_DATE_YEAR_ZERO           0x2000          Year may not equal zero\n   OCI_DATE_INVALID_FORMAT      0x8000          Bad date format input\n\n   So, for example, if the date passed in was 2/0/1990 25:61:10 in\n   (month/day/year hours:minutes:seconds format), the erroor returned\n   would be OCI_DATE_INVALID_DAY | OCI_DATE_DAY_BELOW_VALID |\n   OCI_DATE_INVALID_HOUR | OCI_DATE_INVALID_MINUTE\n\n   DESCRIPTION:\n        Check if the given date is valid.\n   RETURNS:\n        OCI_SUCCESS if the function completes successfully.\n        OCI_INVALID_HANDLE if 'err' is NULL.\n        OCI_ERROR if\n          'date' and 'valid' pointers are NULL pointers\n */\n\n/*--------------------------- OCIDateSysDate --------------------------------*/\n\nsword OCIDateSysDate(    OCIError *err, OCIDate *sys_date    );\n/*\n   NAME: OCIDateSysDate - OCIDate get current SYStem date and time\n   PARAMETERS:\n        err (IN/OUT) - error handle. If there is an error, it is\n                recorded in 'err' and this function returns OCI_ERROR.\n                The error recorded in 'err' can be retrieved by calling\n                OCIErrorGet().\n        sys_date (OUT) - current system date and time\n   DESCRIPTION:\n        Returns the current system date and time.\n   RETURNS:\n        OCI_SUCCESS if the function completes successfully.\n        OCI_INVALID_HANDLE if 'err' is NULL.\n        OCI_ERROR if\n          <to be discovered>\n */\n\n/*****************************************************************************/\n/*                  FIXED-LENGTH STRING - CHAR (N)                           */\n/*****************************************************************************/\n\n/*\n * An ADT attribute declared as \"x CHAR(n)\" is mapped to \"OCIString *x;\".\n * The representation of OCIString * is shown below.\n */\n\n/*****************************************************************************/\n/*                  VARIABLE-LENGTH STRING                                   */\n/*****************************************************************************/\n\n/*\n * The variable-length string is represented in C as a pointer to OCIString\n * structure. The OCIString structure is opaque to the user. Functions are\n * provided to allow the user to manipulate a variable-length string.\n *\n * A variable-length string can be declared as:\n *\n * OCIString *vstr;\n *\n * For binding variables of type OCIString* in OCI calls (OCIBindByName(),\n * OCIBindByPos() and OCIDefineByPos()) use the external type code SQLT_VST.\n */\ntypedef struct OCIString OCIString;\n\n/*-------------------------- OCIStringAssign --------------------------------*/\n\nsword OCIStringAssign(    OCIEnv *env, OCIError *err, const OCIString *rhs,\n                          OCIString **lhs    );\n/*\n   NAME: OCIStringAssign - OCIString Assign String to String\n   PARAMETERS:\n        env (IN/OUT) - OCI environment handle initialized in object mode.\n        err (IN/OUT) - error handle. If there is an error, it is\n                recorded in 'err' and this function returns OCI_ERROR.\n                The error recorded in 'err' can be retrieved by calling\n                OCIErrorGet().\n        rhs (IN) - RHS of the assignment, the type of rhs is also OCIString\n        lhs (IN/OUT) - LHS of the assignment\n   DESCRIPTION:\n        Assign 'rhs' string to 'lhs' string. The 'lhs' string may be\n        resized depending upon the size of the 'rhs'. The assigned string is\n        null-terminated. The 'length' field will not include the extra byte\n        needed for null termination.\n   RETURNS:\n        OCI_SUCCESS if the function completes successfully.\n        OCI_INVALID_HANDLE if 'env' or 'err' is NULL.\n        OCI_ERROR if\n          out of space error\n */\n\n/*---------------------- OCIStringAssignText --------------------------------*/\n\nsword OCIStringAssignText(    OCIEnv *env, OCIError *err, const oratext *rhs,\n                              ub4 rhs_len, OCIString **lhs    );\n/*\n   NAME: OCIStringAssignText - OCIString Assign Text string to String\n   PARAMETERS:\n        env (IN/OUT) - OCI environment handle initialized in object mode.\n        err (IN/OUT) - error handle. If there is an error, it is\n                recorded in 'err' and this function returns OCI_ERROR.\n                The error recorded in 'err' can be retrieved by calling\n                OCIErrorGet().\n        rhs (IN) - RHS of the assignment, the type of rhs is a text string\n        rhs_len (IN) - length of the 'rhs' string\n        lhs (IN/OUT) - LHS of the assignment\n   DESCRIPTION:\n        Assign 'rhs' string to 'lhs' string. The 'lhs' string may be\n        resized depending upon the size of the 'rhs'. The assigned string is\n        null-terminated. The 'length' field will not include the extra byte\n        needed for null termination.\n   RETURNS:\n        OCI_SUCCESS if the function completes successfully.\n        OCI_INVALID_HANDLE if 'env' or 'err' is NULL.\n        OCI_ERROR if\n          out of space error\n */\n\n/*-------------------------- OCIStringResize --------------------------------*/\n\nsword OCIStringResize(    OCIEnv *env, OCIError *err, ub4 new_size,\n                          OCIString **str    );\n/*\n   NAME: OCIStringResize - OCIString ReSiZe string memory\n   PARAMETERS:\n        env (IN/OUT) - OCI environment handle initialized in object mode.\n        err (IN/OUT) - error handle. If there is an error, it is\n                recorded in 'err' and this function returns OCI_ERROR.\n                The error recorded in 'err' can be retrieved by calling\n                OCIErrorGet().\n        new_size (IN) - new memory size of the string in bytes\n        str (IN/OUT) - allocated memory for the string is freed from the\n                OOCI heap\n   DESCRIPTION:\n        This function resizes the memory of the given variable-length string in\n        the object cache. The contents of the string are NOT preserved.\n        This function may allocate the string in a new memory region in\n        which case the original memory occupied by the given string will\n        be freed. If the input string is null (str == NULL), then this\n        function will allocate memory for the string.\n\n        If the new_size is 0, then this function frees the memory occupied\n        by 'str' and a null pointer value is returned.\n\n        NOTE: The caller must compute 'new_size' taking into account space\n        for the null character ('\\0').\n   RETURNS:\n        OCI_SUCCESS if the function completes successfully.\n        OCI_INVALID_HANDLE if 'env' or 'err' is NULL.\n        OCI_ERROR if\n          out of space error\n */\n\n/*---------------------------- OCIStringSize --------------------------------*/\n\nub4 OCIStringSize(    OCIEnv *env, const OCIString *vs    );\n/*\n   NAME: OCIStringSize - OCIString Get String siZe\n   PARAMETERS:\n        env(IN) - pointer to OCI environment handle\n        vs (IN) - string whose size is returned\n   DESCRIPTION:\n        Return the size of the given string.\n   RETURNS:\n        size of the string in bytes is returned\n */\n\n/*----------------------------- OCIStringPtr --------------------------------*/\n\noratext *OCIStringPtr(    OCIEnv *env, const OCIString *vs    );\n/*\n   NAME: OCIStringPtr - OCIString Get String Pointer\n   PARAMETERS:\n        env(IN) - pointer to OCI environment handle\n        vs (IN) - pointer to the text of this string is returned\n   DESCRIPTION:\n        Return the pointer to the text of the given string.\n   RETURNS:\n        pointer to the text of the string is returned\n */\n\n/*----------------------- OCIStringAllocSize --------------------------------*/\n\nsword OCIStringAllocSize(    OCIEnv *env, OCIError *err, const OCIString *vs,\n                             ub4 *allocsize    );\n/*\n   NAME: OCIStringAllocSize - OCIString get Allocated SiZe of string memory\n                              in bytes\n   PARAMETERS:\n        env (IN/OUT) - OCI environment handle initialized in object mode.\n        err (IN/OUT) - error handle. If there is an error, it is\n                recorded in 'err' and this function returns OCI_ERROR.\n                The error recorded in 'err' can be retrieved by calling\n                OCIErrorGet().\n        vs (IN) - string whose allocated size in bytes is returned\n        allocsize (OUT) - allocated size of string memory in bytes is returned\n   DESCRIPTION:\n        Return the allocated size of the string memory in bytes. The\n        allocated size is >= actual string size.\n   REQUIRES:\n        vs is a non-null pointer\n   RETURNS:\n        OCI_SUCCESS if the function completes successfully.\n        OCI_INVALID_HANDLE if 'env' or 'err' is NULL.\n        OCI_ERROR on error\n */\n\n/*****************************************************************************/\n/*                       VARIABLE-LENGTH RAW                                 */\n/*****************************************************************************/\n\n/*\n * The variable-length raw is represented in C as a pointer to OCIRaw\n * structure. The OCIRaw structure is opaque to the user. Functions are\n * provided to allow the user to manipulate a variable-length raw.\n *\n * A variable-length raw can be declared as:\n *\n * OCIRaw *raw;\n *\n * For binding variables of type OCIRaw* in OCI calls (OCIBindByName(),\n * OCIBindByPos() and OCIDefineByPos()) use the external type code SQLT_LVB.\n */\ntypedef struct OCIRaw OCIRaw;\n\n/*-------------------------- OCIRawAssignRaw --------------------------------*/\n\nsword OCIRawAssignRaw(    OCIEnv *env, OCIError *err, const OCIRaw *rhs,\n                          OCIRaw **lhs    );\n/*\n   NAME: OCIRawAssignRaw - OCIRaw Assign Raw (of type OCIRaw* ) to\n                   Raw (of type OCIRaw* )\n   PARAMETERS:\n        env (IN/OUT) - OCI environment handle initialized in object mode.\n        err (IN/OUT) - error handle. If there is an error, it is\n                recorded in 'err' and this function returns OCI_ERROR.\n                The error recorded in 'err' can be retrieved by calling\n                OCIErrorGet().\n        rhs (IN) - RHS of the assignment, the type of rhs is also OCIRaw\n        lhs (IN/OUT) - LHS of the assignment\n   DESCRIPTION:\n        Assign 'rhs' raw to 'lhs' raw. The 'lhs' raw may be\n        resized depending upon the size of the 'rhs'.\n   RETURNS:\n        OCI_SUCCESS if the function completes successfully.\n        OCI_INVALID_HANDLE if 'env' or 'err' is NULL.\n        OCI_ERROR if\n          out of space error\n */\n\n/*------------------------ OCIRawAssignBytes --------------------------------*/\n\nsword OCIRawAssignBytes(    OCIEnv *env, OCIError *err, const ub1 *rhs,\n                            ub4 rhs_len, OCIRaw **lhs    );\n/*\n   NAME: OCIRawAssignBytes - OCIRaw Assign raw Bytes (of type ub1* ) to Raw\n                   (of type OCIRaw* )\n   PARAMETERS:\n        env (IN/OUT) - OCI environment handle initialized in object mode.\n        err (IN/OUT) - error handle. If there is an error, it is\n                recorded in 'err' and this function returns OCI_ERROR.\n                The error recorded in 'err' can be retrieved by calling\n                OCIErrorGet().\n        rhs (IN) - RHS of the assignment, the type of rhs is ub1 *\n        rhs_len (IN) - length of the 'rhs' raw\n        lhs (IN/OUT) - LHS of the assignment\n   DESCRIPTION:\n        Assign 'rhs' raw to 'lhs' raw. The 'lhs' raw may be\n        resized depending upon the size of the 'rhs'.\n   RETURNS:\n        OCI_SUCCESS if the function completes successfully.\n        OCI_INVALID_HANDLE if 'env' or 'err' is NULL.\n        OCI_ERROR if\n          out of space error\n */\n\n/*---------------------------- OCIRawResize ---------------------------------*/\n\nsword OCIRawResize(    OCIEnv *env, OCIError *err, ub4 new_size,\n                       OCIRaw **raw    );\n/*\n   NAME: OCIRawResize - OCIRaw ReSiZe memory of variable-length raw\n   PARAMETERS:\n        env (IN/OUT) - OCI environment handle initialized in object mode.\n        err (IN/OUT) - error handle. If there is an error, it is\n                recorded in 'err' and this function returns OCI_ERROR.\n                The error recorded in 'err' can be retrieved by calling\n                OCIErrorGet().\n        new_size (IN) - new size of the raw data in bytes\n        raw (IN) - variable-length raw pointer; the raw is\n                resized to 'new_size'\n   DESCRIPTION:\n        This function resizes the memory of the given variable-length raw in\n        the object cache.\n        The previous contents of the raw are NOT preserved.\n        This function may allocate the raw in a new memory region in\n        which case the original memory occupied by the given raw will\n        be freed. If the input raw is null (raw == NULL), then this\n        function will allocate memory for the raw data.\n\n        If the new_size is 0, then this function frees the memory occupied\n        by 'raw' and a null pointer value is returned.\n   RETURNS:\n        OCI_SUCCESS if the function completes successfully.\n        OCI_INVALID_HANDLE if 'env' or 'err' is NULL.\n        OCI_ERROR if\n          out of space error\n */\n\n/*------------------------------- OCIRawSize --------------------------------*/\n\nub4 OCIRawSize(    OCIEnv * env, const OCIRaw *raw    );\n/*\n   NAME: OCIRawSize - OCIRaw Get Raw siZe\n   PARAMETERS:\n        env (IN)  - pointer to OCI environment handle\n        raw (INT) - raw whose size is returned\n   DESCRIPTION:\n        Return the size of the given raw.\n   RETURNS:\n        size of the raw in bytes is returned\n */\n\n/*--------------------------------- OCIRawPtr -------------------------------*/\nub1 *OCIRawPtr(    OCIEnv * env, const OCIRaw *raw    );\n/*\n   NAME: OCIRawPtr - OCIRaw Get Raw data Pointer\n   PARAMETERS:\n        env (IN) - pointer to OCI environment handle\n        raw (IN) - pointer to the data of this raw is returned\n   DESCRIPTION:\n        Return the pointer to the data of the given raw.\n   RETURNS:\n        pointer to the data of the raw is returned\n */\n\n/*------------------------------ OCIRawAllocSize ----------------------------*/\n\nsword OCIRawAllocSize(    OCIEnv *env, OCIError *err, const OCIRaw *raw,\n                          ub4 *allocsize    );\n/*\n   NAME: OCIRawAllocSize - OCIRaw get Allocated SiZe of raw memory in bytes\n   PARAMETERS:\n        env (IN/OUT) - OCI environment handle initialized in object mode.\n        err (IN/OUT) - error handle. If there is an error, it is\n                recorded in 'err' and this function returns OCI_ERROR.\n                The error recorded in 'err' can be retrieved by calling\n                OCIErrorGet().\n        raw (IN) - raw whose allocated size in bytes is returned\n        allocsize (OUT) - allocated size of raw memory in bytes is returned\n   DESCRIPTION:\n        Return the allocated size of the raw memory in bytes. The\n        allocated size is >= actual raw size.\n   REQUIRES:\n        raw is a non-null pointer\n   RETURNS:\n        OCI_SUCCESS if the function completes successfully.\n        OCI_INVALID_HANDLE if 'env' or 'err' is NULL.\n        OCI_ERROR upon error\n *)\n\n(*****************************************************************************\n *                     OBJECT REFERENCE OPERATIONS                           *\n *****************************************************************************)\n\n(*\n * See the definition of OCIRef in oro.h.\n *\n * For binding variables of type OCIRef* in OCI calls (OCIBindByName(),\n * OCIBindByPos() and OCIDefineByPos()) use the code SQLT_REF.\n *\n *)\n\n(*------------------------- OBJECT REFERENCE (REF) --------------------------*)\n\n  PPOCIRef = ^POCIRef;\n  POCIRef = Pointer;\n(*\n * OCIRef - OCI object REFerence\n *\n * In the Oracle object runtime environment, an object is identified by an\n * object reference (ref) which contains the object identifier plus other\n * runtime information.  The contents of a ref is opaque to clients.  Use\n * OCIObjectNew() to construct a ref.\n *)\n\n(*---------------------------- OCIRefClear ----------------------------------*)\n  TOCIRefClear = procedure(env: POCIEnv; ref: POCIRef);\n(*\n   NAME: OCIRefClear - OCIRef CLeaR or nullify a ref\n   PARAMETERS:\n        env (IN)     - pointer to OCI environment handle\n        ref (IN/OUT) - ref to clear\n   DESCRIPTION:\n        Clear or nullify the given ref. A ref is considered to be a null ref\n        if it does not contain a valid OID (and thus doesn't point to an\n        object). Logically, a null ref is a dangling ref.\n\n        Note that a null ref is still a valid SQL value and is not SQL-ly null.\n        It can be used as a valid non-null constant ref value for NOT NULL\n        column or attribute of a row in a table.\n\n        If a null pointer value is passed as a ref,\n        then this function is a no-op.\n *)\n\n(*--------------------------- OCIRefAssign ----------------------------------*)\n\n  TOCIRefAssign = function(env: POCIEnv; err: POCIError; const source: POCIRef;\n                       target: PPOCIRef): sword; cdecl;\n(*\n   NAME: OCIRefAssign - OCIRef CoPY a ref to another\n   PARAMETERS:\n        env (IN/OUT) - OCI environment handle initialized in object mode.\n        err (IN/OUT) - error handle. If there is an error, it is\n                recorded in 'err' and this function returns OCI_ERROR.\n                The error recorded in 'err' can be retrieved by calling\n                OCIErrorGet().\n        source (IN) - ref to copy from\n        target (IN/OUT) - ref to copy to\n   DESCRIPTION:\n        Copy 'source' ref to 'target' ref; both then reference the same\n        object. If the target ref pointer is null (i.e. *target == NULL)\n        then the copy function will allocate memory for the target ref\n        in OOCI heap prior to the copy.\n   RETURNS:\n        OCI_SUCCESS if the function completes successfully.\n        OCI_INVALID_HANDLE if 'env' or 'err' is NULL.\n        OCI_ERROR if\n          1) out of memory\n */\n\n/*-------------------------- OCIRefIsEqual ----------------------------------*/\nboolean OCIRefIsEqual(    OCIEnv *env, const OCIRef *x, const OCIRef *y    );\n/*\n   NAME: OCIRefIsEqual - OCIRef compare two refs for EQUality\n   PARAMETERS:\n        env (IN) - pointer to OCI environment handle\n        x (IN)   - ref to compare\n        y (IN)   - ref to compare\n   DESCRIPTION:\n        Compare the given refs for equality.\n        Two refs are equal if and only if:\n          - they are both referencing the same persistent object, or\n          - they are both referencing the same transient object.\n\n        NOTE THAT TWO NULL REFS ARE CONSIDERED NOT EQUAL BY THIS FUNCTION.\n   RETURNS:\n        TRUE if the two refs are equal\n        FALSE if the two refs are not equal, or X is NULL, or Y is NULL\n */\n\n/*--------------------------- OCIRefIsNull ----------------------------------*/\nboolean OCIRefIsNull(    OCIEnv *env, const OCIRef *ref    );\n/*\n   NAME: OCIRefIsNull - OCIRef test if a ref is NULl\n   PARAMETERS:\n        env (IN) - pointer to OCI environment handle\n        ref (IN) - ref to test for null\n   DESCRIPTION:\n        Return TRUE if the given ref is null; otherwise, return FALSE.\n        A ref is null if and only if:\n        - it is supposed to be referencing a persistent object, but\n          its OID is null, or\n        - it is supposed to be referencing a transient object, but it is\n          currently not pointing to an object.\n        A ref is a dangling ref if the object that it points to does not\n        exist.\n   RETURNS:\n        TRUE if the given ref is NULL\n        FALSE if the given ref is not NULL\n */\n\n/*-------------------------- OCIRefHexSize ----------------------------------*/\nub4 OCIRefHexSize(    OCIEnv *env, const OCIRef *ref    );\n/*\n   NAME: OCIRefHexSize - OCIRef Hexadecimal buffer SiZe in bytes\n   PARAMETERS:\n        env (IN) - pointer to OCI environment handle\n        ref (IN) - ref whose size in hexadecimal representation in bytes is\n                returned\n   DESCRIPTION:\n        Return the size of the buffer in bytes required for the hexadecimal\n        representation of the ref. A buffer of at-least this size must be\n        passed to ref-to-hex (OCIRefToHex) conversion function.\n   RETURNS:\n        size of hexadecimal representation of ref\n */\n\n/*-------------------------- OCIRefFromHex ---------------------------------*/\nsword OCIRefFromHex(    OCIEnv *env, OCIError *err, const OCISvcCtx *svc,\n                        const oratext *hex, ub4 length, OCIRef **ref    );\n/*\n   NAME:\n        OCIRefFromHex - OCIRef convert a Hexadecimal string TO a Ref\n   PARAMETERS:\n        env (IN/OUT) - OCI environment handle initialized in object mode\n        err (IN/OUT) - error handle. If there is an error, it is\n                recorded in 'err' and this function returns OCI_ERROR.\n                The error recorded in 'err' can be retrieved by\n                calling OCIErrorGet().\n        svc (IN) - OCI service context handle; if the resulting ref is\n                initialized with this service context\n        hex (IN) - hexadecimal string (that was produced by 'OCIRefToHex()\"\n                previously) to be convert into a ref\n        length (IN) - length of the hexadecimal string\n        ref (IN/OUT) - ref is initialized with the given value ('hex').\n                If *ref is null, then space for the ref is allocated in the\n                object cache, otherwise the memory occupied by the given ref\n                is re-used.\n   DESCRIPTION:\n        Convert the given hexadecimal string into a ref. This function\n        ensures that the resulting ref is well formed. It does NOT ensure\n        that the object pointed to by the resulting ref exists or not.\n   RETURNS:\n        OCI_SUCCESS if the function completes successfully.\n        OCI_INVALID_HANDLE if 'env' or 'err' is NULL.\n        OCI_ERROR if\n */\n\n/*--------------------------- OCIRefToHex -----------------------------------*/\nsword OCIRefToHex(    OCIEnv *env, OCIError *err, const OCIRef *ref,\n                      oratext *hex, ub4 *hex_length    );\n/*\n   NAME:\n        OCIRefToHex - OCIRef convert ref to a Hexadecimal string\n   PARAMETERS:\n        env (IN/OUT) - OCI environment handle initialized in object mode\n        err (IN/OUT) - error handle. If there is an error, it is\n                recorded in 'err' and this function returns OCI_ERROR.\n                The error recorded in 'err' can be retrieved by\n                calling OCIErrorGet().\n        ref (IN) - ref to be converted into a hexadecimal string; if the\n                ref is a null ref (i.e. OCIRefIsNull(ref) == TRUE) then\n                a zero hex_length value is returned\n        hex (OUT) - buffer that is large enough to contain the resulting\n                hexadecimal string; the contents of the string is opaque\n                to the caller\n        hex_length (IN/OUT) - on input specifies the size of the 'hex' buffer,\n                on output specifies the actual size of the hexadecimal\n                string being returned in 'hex'\n   DESCRIPTION:\n        Convert the given ref into a hexadecimal string, and return the length\n        of the string. The resulting string is opaque to the caller.\n   RETURNS:\n        OCI_SUCCESS if the function completes successfully.\n        OCI_INVALID_HANDLE if 'env' or 'err' is NULL.\n        OCI_ERROR if\n          the given buffer is not big enough to hold the resulting string\n */\n\n\n/*****************************************************************************/\n/*                          COLLECTION FUNCTIONS                             */\n/*****************************************************************************/\n\n/*\n   The generic collection is represented by the type 'OCIColl'. The following\n   operations OCIColl*() are provided on a generic collection:\n     - get current size of collection\n     - get upper bound of collection\n     - get pointer to an element given its index\n     - set element at given index (assign element)\n     - append an element\n     - trim the given number of elements from the end of the collection\n     - collection assignment\n\n   The following iterator based scanning functions are also provided on a\n   generic collection. These functions make use of an iterator which is\n   defined to be of type OCIIter.\n\n     - create an iterator for scanning collection\n     - destroy iterator\n     - reset iterator to the beginning of collection\n     - get pointer to current element pointed by iterator\n     - get pointer to next element\n     - get pointer to previous element\n\n   The collections variable-length array (varray) and nested table\n   are sub-types of generic collection. This means that the OCIColl*()\n   functions can also be used to manipulate varray and nested table.\n\n   The varray is represented by OCIArray type and nested table by OCITable.\n   Besides OCIColl*() functions no additional functions are provided for\n   manipulating varrays. The OCIColl*() functions are a complete set of\n   functions to manipulate varrays.\n\n   Besides OCIColl*() functions, the following functions OCITable*() can be\n   used to manipulate nested table. The OCITable*() functions operate on\n   nested tables only and should not be used on a varray.\n\n     - delete an element at index i. Note that the position\n       ordinals of the remaining elements of the table is not changed by the\n       delete operation. So delete creates \"holes\" in the table.\n     - check if an element exists at the given index i\n     - return the smallest value of i for which exists(i) is true\n     - return the largest value of i for which exists(i) is true\n     - return pointer to the smallest position j, greater than i, such that\n       OCITableExists(j) is true\n     - return pointer to the largest position j, less than i, such that\n       OCITableExists(j) is true\n\n   For binding variables of type OCIColl* or OCITable* in OCI calls\n   (OCIBindByName(), OCIBindByPos() and OCIDefineByPos()) use the external\n   type code SQLT_NTY.\n */\n\n/* OCIColl - generic collection type */\ntypedef struct OCIColl OCIColl;\n\n/* OCIArray - varray collection type */\ntypedef OCIColl OCIArray;\n\n/* OCITable - nested table collection type */\ntypedef OCIColl OCITable;\n\n/* OCIIter - collection iterator */\ntypedef struct OCIIter OCIIter;\n\n/*----------------------------- OCICollSize ---------------------------------*/\n\nsword OCICollSize( OCIEnv *env, OCIError *err, const OCIColl *coll,\n                   sb4 *size );\n/*\n   NAME: OCICollSize - OCIColl return current SIZe of the given collection\n   PARAMETERS:\n        env(IN) - pointer to OCI environment handle\n        err (IN/OUT) - error handle. If there is an error, it is\n                recorded in 'err' and this function returns OCI_ERROR.\n                The error recorded in 'err' can be retrieved by calling\n                OCIErrorGet().\n        coll (IN) - collection whose number of elements is returned\n        size (OUT) - current number of elements in the collection\n   DESCRIPTION:\n          Returns the current number of elements in the given collection.\n\n          For collections of type nested table wherein 'delete element'\n          operation is allowed, the count returned by OCICollSize() will\n          NOT be decremented upon deleting elements. For example:\n\n            OCICollSize(...);\n            // assume 'size' returned is equal to 5\n            OCITableDelete(...); // delete one element\n            OCICollSize(...);\n            // 'size' returned will still be 5\n\n          To get the count minus the deleted elements use OCITableSize().\n          Continuing the above example,\n\n            OCITableSize(...)\n            // 'size' returned will be equal to 4\n\n          Note, a trim operation (OCICollTrim) will decrement the count\n          by the number of trimmed elements. Continuing the above example,\n\n            OCICollTrim(..,1..); // trim one element\n            OCICollSize(...);\n            // 'size' returned will be equal to 4\n   RETURNS:\n        OCI_SUCCESS if the function completes successfully.\n        OCI_INVALID_HANDLE if 'env' or 'err' is NULL.\n        OCI_ERROR if\n          error during loading of collection into object cache\n          any of the input parameters is null\n */\n\n/*------------------------------ OCICollMax ---------------------------------*/\n\nsb4 OCICollMax(    OCIEnv *env, const OCIColl *coll    );\n/*\n   NAME: OCICollMax - OCIColl return MAXimum size (upper-bound) of the\n                   given collection (in number of elements)\n   PARAMETERS:\n        env(IN) - pointer to OCI environment handle\n        coll (IN) - collection whose upper-bound in number of elements\n                is returned\n   DESCRIPTION:\n        Returns the max number of elements that the given collection can hold.\n        A value 0 indicates that the collection has no upper-bound.\n   REQUIRES:\n        coll must point to a valid collection descriptor\n   RETURNS:\n        upper-bound of the given collection\n */\n\n/*-------------------------- OCICollGetElem ---------------------------------*/\n\nsword OCICollGetElem(    OCIEnv *env, OCIError *err, const OCIColl *coll,\n                         sb4 index, boolean *exists, void  **elem,\n                         void  **elemind    );\n/*\n   NAME: OCICollGetElem - OCIColl GET pointer to the element at the given index\n   PARAMETERS:\n        env (IN/OUT) - OCI environment handle initialized in object mode.\n        err (IN/OUT) - error handle. If there is an error, it is\n                recorded in 'err' and this function returns OCI_ERROR.\n                The error recorded in 'err' can be retrieved by calling\n                OCIErrorGet().\n        coll (IN) - pointer to the element in this collection is returned\n        index (IN) - index of the element whose pointer is returned\n        exists (OUT) - set to FALSE if element at the specified index does\n                not exist else TRUE\n        elem (OUT) - address of the desired element is returned\n        elemind (OUT) [optional] - address of the null indicator information\n                is returned; if (elemind == NULL) then the null indicator\n                information will NOT be returned\n   DESCRIPTION:\n        Get the address of the element at the given position. Optionally\n        this function also returns the address of the element's null indicator\n        information.\n\n        The following table describes for each collection element type\n        what the corresponding element pointer type is. The element pointer\n        is returned via the 'elem' parameter of OCICollGetElem().\n\n           Element Type                       *elem is set to\n        -----------------------               ---------------\n         Oracle Number (OCINumber)              OCINumber*\n         Date (OCIDate)                         OCIDate*\n         Variable-length string (OCIString* )   OCIString**\n         Variable-length raw (OCIRaw* )         OCIRaw**\n         object reference (OCIRef* )            OCIRef**\n         lob locator (OCILobLocator* )          OCILobLocator**\n         object type (e.g. person)              person*\n\n        The element pointer returned by OCICollGetElem() is in a form\n        such that it can not only be used to access the\n        element data but also is in a form that can be used as the target\n        (i.e left-hand-side) of an assignment statement.\n\n        For example, assume the user is iterating over the elements of\n        a collection whose element type is object reference (OCIRef* ). A call\n        to OCICollGetElem() returns pointer to a reference handle\n        (i.e. OCIRef** ). After getting, the pointer to the collection\n        element, the user may wish to modify it by assigning a new reference.\n        This can be accomplished via the ref assignment function shown below:\n\n        sword OCIRefAssign( OCIEnv *env, OCIError *err, const OCIRef *source,\n                            OCIRef **target );\n\n        Note that the 'target' parameter of OCIRefAssign() is of type\n        'OCIRef**'. Hence OCICollGetElem() returns 'OCIRef**'.\n        If '*target == NULL' a new ref will be allocated by OCIRefAssign()\n        and returned via the 'target' parameter.\n\n        Similarly, if the collection element was of type string (OCIString* ),\n        OCICollGetElem() returns pointer to string handle\n        (i.e. OCIString** ). If a new string is assigned, via\n        OCIStringAssign() or OCIStringAssignText() the type of the target\n        must be 'OCIString **'.\n\n        If the collection element is of type Oracle number, OCICollGetElem()\n        returns OCINumber*. The prototype of OCINumberAssign() is shown below:\n\n        sword OCINumberAssign(OCIError *err, const OCINumber *from,\n                              OCINumber *to);\n   RETURNS:\n        OCI_SUCCESS if the function completes successfully.\n        OCI_INVALID_HANDLE if 'env' or 'err' is NULL.\n        OCI_ERROR if\n          any of the input parameters is null\n */\n\n/*------------------------- OCICollGetElemArray -----------------------------*/\n\nsword OCICollGetElemArray(  OCIEnv *env, OCIError *err, const OCIColl *coll,\n                            sb4 index, boolean *exists, void  **elem,\n                            void  **elemind, uword *nelems);\n/*\n   NAME: OCICollGetElemArray - OCIColl GET pointers to elements from given index\n   PARAMETERS:\n        env (IN/OUT) - OCI environment handle initialized in object mode.\n        err (IN/OUT) - error handle. If there is an error, it is\n                recorded in 'err' and this function returns OCI_ERROR.\n                The error recorded in 'err' can be retrieved by calling\n                OCIErrorGet().\n        coll (IN) - pointers to the elements in this collection is returned\n        index (IN) - starting index of the element\n        exists (OUT) - set to FALSE if element at the specified index does\n                not exist else TRUE\n        elem (OUT) - address of the desired elements is returned\n        elemind (OUT) [optional] - address of the null indicators information\n                is returned; if (elemind == NULL) then the null indicator\n                information will NOT be returned\n        nelems(IN/OUT) - Upper bound of elem and/or elemind array\n   DESCRIPTION:\n        Get the address of the elements from the given position. Optionally\n        this function also returns the address of the element's null indicator\n        information.\n\n        The following table describes for each collection element type\n        what the corresponding element pointer type is. The element pointer\n        is returned via the 'elem' parameter of OCICollGetElem().\n\n           Element Type                       *elem is set to\n        -----------------------               ---------------\n         Oracle Number (OCINumber)              OCINumber*\n         Date (OCIDate)                         OCIDate*\n         Variable-length string (OCIString* )   OCIString**\n         Variable-length raw (OCIRaw* )         OCIRaw**\n         object reference (OCIRef* )            OCIRef**\n         lob locator (OCILobLocator* )          OCILobLocator**\n         object type (e.g. person)              person*\n\n        The element pointer returned by OCICollGetElem() is in a form\n        such that it can not only be used to access the\n        element data but also is in a form that can be used as the target\n        (i.e left-hand-side) of an assignment statement.\n\n        For example, assume the user is iterating over the elements of\n        a collection whose element type is object reference (OCIRef* ). A call\n        to OCICollGetElem() returns pointer to a reference handle\n        (i.e. OCIRef** ). After getting, the pointer to the collection\n        element, the user may wish to modify it by assigning a new reference.\n        This can be accomplished via the ref assignment function shown below:\n\n        sword OCIRefAssign( OCIEnv *env, OCIError *err, const OCIRef *source,\n                            OCIRef **target );\n\n        Note that the 'target' parameter of OCIRefAssign() is of type\n        'OCIRef**'. Hence OCICollGetElem() returns 'OCIRef**'.\n        If '*target == NULL' a new ref will be allocated by OCIRefAssign()\n        and returned via the 'target' parameter.\n\n        Similarly, if the collection element was of type string (OCIString* ),\n        OCICollGetElem() returns pointer to string handle\n        (i.e. OCIString** ). If a new string is assigned, via\n        OCIStringAssign() or OCIStringAssignText() the type of the target\n        must be 'OCIString **'.\n\n        If the collection element is of type Oracle number, OCICollGetElem()\n        returns OCINumber*. The prototype of OCINumberAssign() is shown below:\n\n        sword OCINumberAssign(OCIError *err, const OCINumber *from,\n                              OCINumber *to);\n   RETURNS:\n        OCI_SUCCESS if the function completes successfully.\n        OCI_INVALID_HANDLE if 'env' or 'err' is NULL.\n        OCI_ERROR if\n          any of the input parameters is null\n */\n\n/*----------------------- OCICollAssignElem ---------------------------------*/\n\nsword OCICollAssignElem(    OCIEnv *env, OCIError *err, sb4 index,\n                            const void  *elem,\n                            const void  *elemind, OCIColl *coll    );\n/*\n   NAME: OCICollAssignElem - OCIColl ASsign Element\n   PARAMETERS:\n        env (IN/OUT) - OCI environment handle initialized in object mode.\n        err (IN/OUT) - error handle. If there is an error, it is\n                recorded in 'err' and this function returns OCI_ERROR.\n                The error recorded in 'err' can be retrieved by calling\n                OCIErrorGet().\n        index (IN) - index of the element whose is assigned to\n        elem (IN) - element which is assigned from (source element)\n        elemind (IN) [optional] - pointer to the element's null indicator\n                information; if (elemind == NULL) then the null indicator\n                information of the assigned element will be set to non-null.\n        coll (IN/OUT) - collection to be updated\n   DESCRIPTION:\n        Assign the given element value 'elem' to the element at coll[index].\n        If the collection is of type nested table, the element at the given\n        index may not exist (i.e. may have been deleted). In this case, the\n        given element is inserted at index 'index'.\n        Otherwise, the element at index 'index' is updated with the value\n        of 'elem'.\n\n        Note that the given element is deep-copied and\n        'elem' is strictly an input parameter.\n   RETURNS:\n        OCI_SUCCESS if the function completes successfully.\n        OCI_INVALID_HANDLE if 'env' or 'err' is NULL.\n        OCI_ERROR if\n          any of the input parameters is null\n          out of memory error\n          given index is out of bounds of the given collection\n */\n\n/*--------------------------- OCICollAssign ---------------------------------*/\n\nsword OCICollAssign(    OCIEnv *env, OCIError *err, const OCIColl *rhs,\n                        OCIColl *lhs    );\n/*\n   NAME: OCICollAssign - OCIColl ASsiGn collection\n   PARAMETERS:\n        env (IN/OUT) - OCI environment handle initialized in object mode.\n        err (IN/OUT) - error handle. If there is an error, it is\n                recorded in 'err' and this function returns OCI_ERROR.\n                The error recorded in 'err' can be retrieved by calling\n                OCIErrorGet().\n        rhs (IN) - collection to be assigned from\n        lhs (OUT) - collection to be assigned to\n   DESCRIPTION:\n        Assign 'rhs' to 'lhs'. The 'lhs' collection may be decreased or\n        increased depending upon the size of 'rhs'. If the 'lhs' contains\n        any elements then the elements will be deleted prior to the\n        assignment. This function performs a deep-copy. The memory for the\n        elements comes from the object cache.\n\n        An error is returned if the element types of the lhs and rhs\n        collections do not match. Also, an error is returned if the\n        upper-bound of the lhs collection is less than the current number of\n        elements in the rhs collection.\n   RETURNS:\n        OCI_SUCCESS if the function completes successfully.\n        OCI_INVALID_HANDLE if 'env' or 'err' is NULL.\n        OCI_ERROR if\n          any of the input parameters is null\n          out of memory error\n          type mis-match of lhs and rhs collections\n          upper-bound of lhs collection is less than the current number of\n          elements in the rhs collection\n */\n\n/*--------------------------- OCICollAppend ---------------------------------*/\n\nsword OCICollAppend(    OCIEnv *env, OCIError *err, const void  *elem,\n                        const void  *elemind, OCIColl *coll    );\n/*\n   NAME: OCICollAppend - OCIColl APPend collection\n   PARAMETERS:\n        env (IN/OUT) - OCI environment handle initialized in object mode.\n        err (IN/OUT) - error handle. If there is an error, it is\n                recorded in 'err' and this function returns OCI_ERROR.\n                The error recorded in 'err' can be retrieved by calling\n                OCIErrorGet().\n        elem (IN) - pointer to the element which is appended to the end\n                of the given collection\n        elemind (IN) [optional] - pointer to the element's null indicator\n                information; if (elemind == NULL) then the null indicator\n                information of the appended element will be set to non-null.\n        coll (IN/OUT) - updated collection\n   DESCRIPTION:\n        Append the given element to the end of the given collection.\n        Appending an element is equivalent to:\n          - increasing the size of the collection by 1 element\n          - updating (deep-copying) the last element's data with the given\n            element's data\n\n        Note that the pointer to the given element 'elem' will not be saved\n        by this function. So 'elem' is strictly an input parameter.\n        An error is returned if the current size of the collection\n        is equal to the max size (upper-bound) of the collection prior to\n        appending the element.\n   RETURNS:\n        OCI_SUCCESS if the function completes successfully.\n        OCI_INVALID_HANDLE if 'env' or 'err' is NULL.\n        OCI_ERROR if\n          any of the input parameters is null\n          out of memory error\n          current size of collection == max size of the collection\n */\n\n/*----------------------------- OCICollTrim ---------------------------------*/\n\nsword OCICollTrim(    OCIEnv *env, OCIError *err, sb4 trim_num,\n                      OCIColl *coll    );\n/*\n   NAME: OCICollTrim - OCIColl Trim elements from the end of the collection\n   PARAMETERS:\n        env (IN/OUT) - OCI environment handle initialized in object mode.\n        err (IN/OUT) - error handle. If there is an error, it is\n                recorded in 'err' and this function returns OCI_ERROR.\n                The error recorded in 'err' can be retrieved by calling\n                OCIErrorGet().\n        trim_num (IN) - number of elements to trim\n        coll (IN/OUT) - 'trim_num' of elements are removed (freed) from the\n                end of the collection\n   DESCRIPTION:\n        Trim the collection by the given number of elements. The elements are\n        removed from the end of the collection.\n\n        An error is returned if the 'trim_num' is greater than the current\n        size of the collection.\n   RETURNS:\n        OCI_SUCCESS if the function completes successfully.\n        OCI_INVALID_HANDLE if 'env' or 'err' is NULL.\n        OCI_ERROR if\n          any of the input parameters is null\n          'trim_num' is greater than the current size of the collection.\n */\n\n/*--------------------------- OCICollIsLocator ------------------------------*/\n\nsword OCICollIsLocator(OCIEnv *env, OCIError *err, const OCIColl *coll,\n                       boolean *result );\n/*\nName: OCICollIsLocator - OCIColl indicates whether a collection is locator\n                         based or not.\nParameters:\n        env(IN) - pointer to OCI environment handle\n        err (IN/OUT) - error handle. If there is an error, it is\n                recorded in 'err' and this function returns OCI_ERROR.\n                The error recorded in 'err' can be retrieved by calling\n                OCIErrorGet().\n        coll (IN) - collection item.\n        result (OUT) - TRUE if the collection item is a locator, FALSE\n                       otherwise\nDescription:\n        Returns TRUE in the result OUT parameter if the collection item is a\n        locator, otherwise returns FALSE.\nReturns:\n        OCI_SUCCESS if the function completes successfully.\n        OCI_INVALID_HANDLE if 'env' or 'err' is NULL.\n*/\n\n/*---------------------------- OCIIterCreate --------------------------------*/\n\nsword OCIIterCreate(    OCIEnv *env, OCIError *err, const OCIColl *coll,\n                        OCIIter **itr    );\n/*\n   NAME: OCIIterCreate - OCIColl Create an ITerator to scan the collection\n                      elements\n   PARAMETERS:\n        env (IN/OUT) - OCI environment handle initialized in object mode.\n        err (IN/OUT) - error handle. If there is an error, it is\n                recorded in 'err' and this function returns OCI_ERROR.\n                The error recorded in 'err' can be retrieved by calling\n                OCIErrorGet().\n        coll (IN) - collection which will be scanned; the different\n                collection types are varray and nested table\n        itr (OUT) - address to the allocated collection iterator is\n                returned by this function\n   DESCRIPTION:\n        Create an iterator to scan the elements of the collection. The\n        iterator is created in the object cache. The iterator is initialized\n        to point to the beginning of the collection.\n\n        If the next function (OCIIterNext) is called immediately\n        after creating the iterator then the first element of the collection\n        is returned.\n        If the previous function (OCIIterPrev) is called immediately after\n        creating the iterator then \"at beginning of collection\" error is\n        returned.\n   RETURNS:\n        OCI_SUCCESS if the function completes successfully.\n        OCI_INVALID_HANDLE if 'env' or 'err' is NULL.\n        OCI_ERROR if\n          any of the input parameters is null\n          out of memory error\n */\n\n/*----------------------------- OCIIterDelete ------------------------------*/\n\nsword OCIIterDelete(    OCIEnv *env, OCIError *err, OCIIter **itr    );\n/*\n   NAME: OCIIterDelete - OCIColl Delete ITerator\n   PARAMETERS:\n        env (IN/OUT) - OCI environment handle initialized in object mode.\n        err (IN/OUT) - error handle. If there is an error, it is\n                recorded in 'err' and this function returns OCI_ERROR.\n                The error recorded in 'err' can be retrieved by calling\n                OCIErrorGet().\n        itr (IN/OUT) - the allocated collection iterator is destroyed and\n                the 'itr' is set to NULL prior to returning\n   DESCRIPTION:\n        Delete the iterator which was previously created by a call to\n        OCIIterCreate.\n   RETURNS:\n        OCI_SUCCESS if the function completes successfully.\n        OCI_INVALID_HANDLE if 'env' or 'err' is NULL.\n        OCI_ERROR if\n          any of the input parameters is null\n          to be discovered\n */\n\n/*----------------------------- OCIIterInit ---------------------------------*/\n\nsword OCIIterInit(    OCIEnv *env, OCIError *err, const OCIColl *coll,\n                      OCIIter *itr    );\n/*\n   NAME: OCIIterInit - OCIColl Initialize ITerator to scan the given\n                   collection\n   PARAMETERS:\n        env (IN/OUT) - OCI environment handle initialized in object mode.\n        err (IN/OUT) - error handle. If there is an error, it is\n                recorded in 'err' and this function returns OCI_ERROR.\n                The error recorded in 'err' can be retrieved by calling\n                OCIErrorGet().\n        coll (IN) - collection which will be scanned; the different\n                collection types are varray and nested table\n        itr (IN/OUT) - pointer to an allocated  collection iterator\n   DESCRIPTION:\n        Initializes the given iterator to point to the beginning of the\n        given collection. This function can be used to:\n\n        a. reset an iterator to point back to the beginning of the collection\n        b. reuse an allocated iterator to scan a different collection\n   RETURNS:\n        OCI_SUCCESS if the function completes successfully.\n        OCI_INVALID_HANDLE if 'env' or 'err' is NULL.\n        OCI_ERROR if\n          any of the input parameters is null\n *)\n\n(*------------------------ OCIIterGetCurrent --------------------------------*)\n\n  TOCIIterGetCurrent = function(hndl: POCIEnv; err: POCIError; itr: POCIIter;\n      elem: PPointer; elemind: PPointer): sword; cdecl;\n(*\n   NAME: OCIIterGetCurrent - OCIColl Iterator based, get CURrent collection\n                    element\n   PARAMETERS:\n        env (IN/OUT) - OCI environment handle initialized in object mode.\n        err (IN/OUT) - error handle. If there is an error, it is\n                recorded in 'err' and this function returns OCI_ERROR.\n                The error recorded in 'err' can be retrieved by calling\n                OCIErrorGet().\n        itr (IN) - iterator which points to the current element\n        elem (OUT) - address of the element pointed by the iterator is returned\n        elemind (OUT) [optional] - address of the element's null indicator\n                information is returned; if (elemind == NULL) then the null\n                indicator information will NOT be returned\n   DESCRIPTION:\n        Returns pointer to the current element and its corresponding null\n        information.\n   RETURNS:\n        OCI_SUCCESS if the function completes successfully.\n        OCI_INVALID_HANDLE if 'env' or 'err' is NULL.\n        OCI_ERROR if\n          any of the input parameters is null\n *)\n\n(*------------------------------ OCIIterNext --------------------------------*)\n\n  TOCIIterNext = function(hndl: POCIEnv; err: POCIError; itr: POCIIter;\n      elem: PPointer; elemind: PPointer; eoc: PBoolean): sword; cdecl;\n(*\n   NAME: OCIIterNext - OCIColl Iterator based, get NeXT collection element\n   PARAMETERS:\n        env (IN/OUT) - OCI environment handle initialized in object mode.\n        err (IN/OUT) - error handle. If there is an error, it is\n                recorded in 'err' and this function returns OCI_ERROR.\n                The error recorded in 'err' can be retrieved by calling\n                OCIErrorGet().\n        itr (IN/OUT) - iterator is updated to point to the next element\n        elem (OUT) - after updating the iterator to point to the next element,\n                address of the element is returned\n        elemind (OUT) [optional] - address of the element's null indicator\n                information is returned; if (elemind == NULL) then the null\n                indicator information will NOT be returned\n        eoc (OUT) - TRUE if iterator is at End Of Collection (i.e. next\n                element does not exist) else FALSE\n   DESCRIPTION:\n        Returns pointer to the next element and its corresponding null\n        information. The iterator is updated to point to the next element.\n\n        If the iterator is pointing to the last element of the collection\n        prior to executing this function, then calling this function will\n        set eoc flag to TRUE. The iterator will be left unchanged in this\n        situation.\n   RETURNS:\n        OCI_SUCCESS if the function completes successfully.\n        OCI_INVALID_HANDLE if 'env' or 'err' is NULL.\n        OCI_ERROR if\n          any of the input parameters is null\n *)\n\n(*------------------------------ OCIIterPrev --------------------------------*)\n\n  TOCIIterPrev = function(hndl: POCIEnv; err: POCIError; itr: POCIIter;\n                      elem: PPointer; elemind: PPointer; boc: PBoolean): sword; cdecl;\n(*\n   NAME: OCIIterPrev - OCIColl Iterator based, get PReVious collection element\n   PARAMETERS:\n        env (IN/OUT) - OCI environment handle initialized in object mode.\n        err (IN/OUT) - error handle. If there is an error, it is\n                recorded in 'err' and this function returns OCI_ERROR.\n                The error recorded in 'err' can be retrieved by calling\n                OCIErrorGet().\n        itr (IN/OUT) - iterator is updated to point to the previous\n                element\n        elem (OUT) - after updating the iterator to point to the previous\n                element, address of the element is returned\n        elemind (OUT) [optional] - address of the element's null indicator\n                information is returned; if (elemind == NULL) then the null\n                indicator information will NOT be returned\n        boc (OUT) - TRUE if iterator is at Beginning Of Collection (i.e.\n                previous element does not exist) else FALSE.\n   DESCRIPTION:\n        Returns pointer to the previous element and its corresponding null\n        information. The iterator is updated to point to the previous element.\n\n        If the iterator is pointing to the first element of the collection\n        prior to executing this function, then calling this function will\n        set 'boc' to TRUE. The iterator will be left unchanged in this\n        situation.\n   RETURNS:\n        OCI_SUCCESS if the function completes successfully.\n        OCI_INVALID_HANDLE if 'env' or 'err' is NULL.\n        OCI_ERROR if\n          any of the input parameters is null\n *)\n(*****************************************************************************\n *           FUNCTIONS WHICH OPERATE ONLY ON NESTED TABLE OCITable*()        *\n *****************************************************************************\n\n *---------------------------- OCITableSize ---------------------------------*)\n\n  TOCITableSize = function(hndl: POCIEnv; err: POCIError; const tbl: POCITable;\n                    size: psb4): sword; cdecl;\n(*\n   NAME: OCITableSize - OCITable return current SIZe of the given\n                   nested table (not including deleted elements)\n   PARAMETERS:\n        env(IN) - pointer to OCI environment handle\n        err (IN/OUT) - error handle. If there is an error, it is\n                recorded in 'err' and this function returns OCI_ERROR.\n                The error recorded in 'err' can be retrieved by calling\n                OCIErrorGet().\n        tbl (IN) - nested table whose number of elements is returned\n        size (OUT) - current number of elements in the nested table. The count\n                does not include deleted elements.\n   DESCRIPTION:\n        Returns the count of elements in the given nested table.\n\n        The count returned by OCITableSize() will be decremented upon\n        deleting elements from the nested table. So, this count DOES NOT\n        includes any \"holes\" created by deleting elements.\n        For example:\n\n            OCITableSize(...);\n            // assume 'size' returned is equal to 5\n            OCITableDelete(...); // delete one element\n            OCITableSize(...);\n            // 'size' returned will be equal to 4\n\n        To get the count plus the count of deleted elements use\n        OCICollSize(). Continuing the above example,\n\n            OCICollSize(...)\n            // 'size' returned will still be equal to 5\n   RETURNS:\n        OCI_SUCCESS if the function completes successfully.\n        OCI_INVALID_HANDLE if 'env' or 'err' is NULL.\n        OCI_ERROR if\n          error during loading of nested table into object cache\n          any of the input parameters is null\n *)\n\n(*---------------------- OCITableExists ---------------------------------*)\n\n  TOCITableExists = function(hndl: POCIEnv; err: POCIError; const tbl: POCITable;\n                             index: sb4; exists: PBoolean): sword; cdecl;\n(*\n   NAME: OCITableExists - OCITable test whether element at the given index\n                    EXIsts\n   PARAMETERS:\n        env (IN/OUT) - OCI environment handle initialized in object mode.\n        err (IN/OUT) - error handle. If there is an error, it is\n                recorded in 'err' and this function returns OCI_ERROR.\n                The error recorded in 'err' can be retrieved by calling\n                OCIErrorGet().\n        tbl (IN) - table in which the given index is checked\n        index (IN) - index of the element which is checked for existence\n        exists (OUT) - set to TRUE if element at given 'index' exists\n                else set to FALSE\n   DESCRIPTION:\n        Test whether an element exists at the given 'index'.\n   RETURNS:\n        OCI_SUCCESS if the function completes successfully.\n        OCI_INVALID_HANDLE if 'env' or 'err' is NULL.\n        OCI_ERROR if\n          any of the input parameters is null\n *)\n\n(*--------------------------- OCITableDelete -------------------------------*)\n\n  TOCITableDelete = function(hndl: POCIEnv; err: POCIError; index: sb4;\n                      tbl: POCITable): sword; cdecl;\n(*\n   NAME: OCITableDelete - OCITable DELete element at the specified index\n   PARAMETERS:\n        env (IN/OUT) - OCI environment handle initialized in object mode.\n        err (IN/OUT) - error handle. If there is an error, it is\n                recorded in 'err' and this function returns OCI_ERROR.\n                The error recorded in 'err' can be retrieved by calling\n                OCIErrorGet().\n        index (IN) - index of the element which must be deleted\n        tbl (IN) - table whose element is deleted\n   DESCRIPTION:\n        Delete the element at the given 'index'. Note that the position\n        ordinals of the remaining elements of the table is not changed by the\n        delete operation. So delete creates \"holes\" in the table.\n\n        An error is returned if the element at the specified 'index' has\n        been previously deleted.\n   RETURNS:\n        OCI_SUCCESS if the function completes successfully.\n        OCI_INVALID_HANDLE if 'env' or 'err' is NULL.\n        OCI_ERROR if\n          any of the input parameters is null\n          given index is not valid\n *)\n\n(*--------------------------- OCITableFirst ---------------------------------*)\n\n TOCITableFirst = function(hndl: POCIEnv; err: POCIError; const tbl: POCITable;\n                             index: sb4): sword; cdecl;\n(*\n   NAME: OCITableFirst - OCITable return FirST index of table\n   PARAMETERS:\n        env (IN/OUT) - OCI environment handle initialized in object mode.\n        err (IN/OUT) - error handle. If there is an error, it is\n                recorded in 'err' and this function returns OCI_ERROR.\n                The error recorded in 'err' can be retrieved by calling\n                OCIErrorGet().\n        tbl (IN) - table which is scanned\n        index (OUT) - first index of the element which exists in the given\n                table is returned\n   DESCRIPTION:\n        Return the first index of the element which exists in the given\n        table.\n   RETURNS:\n        OCI_SUCCESS if the function completes successfully.\n        OCI_INVALID_HANDLE if 'env' or 'err' is NULL.\n        OCI_ERROR if\n          table is empty\n *)\n\n(*---------------------------- OCITableLast ---------------------------------*)\n\n  TOCITableLast = function(hndl: POCIEnv; err: POCIError; const tbl: POCITable;\n                             index: sb4): sword; cdecl;\n(*\n   NAME: OCITableFirst - OCITable return LaST index of table\n   PARAMETERS:\n        env (IN/OUT) - OCI environment handle initialized in object mode.\n        err (IN/OUT) - error handle. If there is an error, it is\n                recorded in 'err' and this function returns OCI_ERROR.\n                The error recorded in 'err' can be retrieved by calling\n                OCIErrorGet().\n        tbl (IN) - table which is scanned\n        index (OUT) - last index of the element which exists in the given\n                table is returned\n   DESCRIPTION:\n        Return the last index of the element which exists in the given\n        table.\n   RETURNS:\n        OCI_SUCCESS if the function completes successfully.\n        OCI_INVALID_HANDLE if 'env' or 'err' is NULL.\n        OCI_ERROR if\n          table is empty\n *)\n\n(*---------------------------- OCITableNext ---------------------------------*)\n\n  TOCITableNext = function(hndl: POCIEnv; err: POCIError; index: sb4;\n                       const tbl: POCITable; next_index: psb4;\n                       exists: PBoolean): sword; cdecl;\n(*\n   NAME: OCITableNext - OCITable return NeXT available index of table\n   PARAMETERS:\n        env (IN/OUT) - OCI environment handle initialized in object mode.\n        err (IN/OUT) - error handle. If there is an error, it is\n                recorded in 'err' and this function returns OCI_ERROR.\n                The error recorded in 'err' can be retrieved by calling\n                OCIErrorGet().\n        index (IN) - starting at 'index' the index of the next element\n                which exists is returned\n        tbl (IN) - table which is scanned\n        next_index (OUT) - index of the next element which exists\n                is returned\n        exists (OUT) - FALSE if no next index available else TRUE\n   DESCRIPTION:\n        Return the smallest position j, greater than 'index', such that\n        exists(j) is TRUE.\n   RETURNS:\n        OCI_SUCCESS if the function completes successfully.\n        OCI_INVALID_HANDLE if 'env' or 'err' is NULL.\n        OCI_ERROR if\n          no next index available\n */\n\n/*---------------------------- OCITablePrev ---------------------------------*)\n\n  TOCITablePrev = function(hndl: POCIEnv; err: POCIError; index: sb4;\n                       const tbl: POCITable; prev_index: psb4;\n                       exists: PBoolean): sword; cdecl;\n(*\n   NAME: OCITablePrev - OCITable return PReVious available index of table\n   PARAMETERS:\n        env (IN/OUT) - OCI environment handle initialized in object mode.\n        err (IN/OUT) - error handle. If there is an error, it is\n                recorded in 'err' and this function returns OCI_ERROR.\n                The error recorded in 'err' can be retrieved by calling\n                OCIErrorGet().\n        index (IN) - starting at 'index' the index of the previous element\n                which exists is returned\n        tbl (IN) - table which is scanned\n        prev_index (OUT) - index of the previous element which exists\n                is returned\n        exists (OUT) - FALSE if no next index available else TRUE\n   DESCRIPTION:\n        Return the largest position j, less than 'index', such that\n        exists(j) is TRUE.\n   RETURNS:\n        OCI_SUCCESS if the function completes successfully.\n        OCI_INVALID_HANDLE if 'env' or 'err' is NULL.\n        OCI_ERROR if\n          no previous index available\n *)\n\n(*--------------------------------orciap.h-----------------------------------*\n\n(*-------------------------------- OCIPing ----------------------------------*)\n  TOCIPing = function(svchp: POCISvcCtx; errhp: POCIError; mode: ub4): sword; cdecl;\n(*---------------------------------orid.h------------------------------------*\n *                           PUBLIC FUNCTIONS                                *\n *---------------------------------------------------------------------------*)\n\n(*-------------------------- OCIObjectSetAttr ----------------------------*)\n  TOCIObjectSetAttr = function(env: POCIEnv; err: POCIError; instance: Pointer;\n                  null_struct: pointer; tdo: POCIType; const names: PPAnsiChar;\n                  const lengths: pub4; const name_count: ub4;\n                  const indexes: pub4; const index_count: ub4;\n                  const null_status: POCIInd; const attr_null_struct: Pointer;\n                  const attr_value: Pointer): sword; cdecl;\n(*\n   NAME: OCIObjectSetAttr - ORID SET value\n   PARAMETERS:\n        env  (IN) - OCI environment handle initialized in object mode\n        err  (IN) - error handle. If there is an error, it is\n                        recorded in 'err' and this function returns OCI_ERROR.\n                        The error recorded in 'err' can be retrieved by calling\n                        OCIErrorGet().\n        instance    (IN) - pointer to an ADT instance\n        null_struct (IN) - the null structure of the ADT instance or array\n        tdo         (IN) - pointer to the TDO\n        names       (IN) - array of attribute names. This is used to specify\n                           the names of the attributes in the path expression.\n        lengths     (IN) - array of lengths of attribute names.\n        name_count  (IN) - number of element in the array 'names'.\n        indexes     (IN) [OPTIONAL] - currently NOT SUPPORTED, pass (ub4 * )0.\n        index_count (IN) [OPTIONAL] - currently NOT SUPPORTED, pass (ub4)0.\n        attr_null_status (IN) - the null status of the attribute if the type of\n                                 attribute is primitive.\n        attr_null_struct (IN) - the null structure of an ADT or collection\n                                 attribute.\n        attr_value       (IN) - pointer to the attribute value.\n   REQUIRES:\n   DESCRIPTION:\n        This function set the attribute of the given object with the given\n        value.  The position of the attribute is specified as a path\n        expression which is an array of names and an array of indexes.\n   RETURNS:\n        one of OROSTA*\n   EXAMPLES:\n        For path expression stanford.cs.stu[5].addr, the arrays will look like\n          names = {\"stanford\", \"cs\", \"stu\", \"addr\"}\n          lengths = {8, 2, 3, 4}\n          indexes = {5}\n\n        Also see the above example.\n */\n\n(*-------------------------- OCIObjectGetAttr ----------------------------*)\n  TOCIObjectGetAttr = function(env: POCIEnv; err: POCIError; instance: Pointer;\n                  null_struct: Pointer; tdo: POCIType;\n                  const names: PPoratext; const lengths: pub4;\n                  const name_count: ub4; const indexes: pub4;\n                  const index_count: ub4; attr_null_status: PPOCIInd;\n                  attr_null_struct, attr_value: PPointer;\n                  attr_tdo: PPOCIType): sword; cdecl;\n(*\n   NAME: OCIObjectGetAttr - ORID GET value\n   PARAMETERS:\n        env  (IN) - OCI environment handle initialized in object mode\n        err  (IN) - error handle. If there is an error, it is\n                        recorded in 'err' and this function returns OCI_ERROR.\n                        The error recorded in 'err' can be retrieved by calling\n                        OCIErrorGet().\n        instance    (IN) - pointer to an ADT instance\n        null_struct (IN) - the null structure of the ADT instance or array\n        tdo         (IN) - pointer to the TDO\n        names       (IN) - array of attribute names. This is used to specify\n                           the names of the attributes in the path expression.\n        lengths     (IN) - array of lengths of attribute names.\n        name_count  (IN) - number of element in the array 'names'.\n        indexes     (IN) [OPTIONAL] - currently NOT SUPPORTED, pass (ub4 * )0.\n        index_count (IN) [OPTIONAL] - currently NOT SUPPORTED, pass (ub4)0.\n        attr_null_status (OUT) - the null status of the attribute if the type\n                                 of attribute is primitive.\n        attr_null_struct (OUT) - the null structure of an ADT or collection\n                                 attribute.\n        attr_value       (OUT) - pointer to the attribute value.\n        attr_tdo         (OUT) - pointer to the TDO of the attribute.\n   REQUIRES:\n      - a valid OCI environment handle must be given.\n   DESCRIPTION:\n        This function gets a value from an ADT instance or from an array.\n        If the parameter 'instance' points to an ADT instance, then the path\n        expression specifies the location of the attribute in the ADT.\n        It is assumed that the object is pinned and that the value returned\n        is valid until the object is unpinned.\n   RETURNS:\n        one of OROSTA*\n   EXAMPLES:\n        See example in OCIObjectSetAttr(). Also see the above example.\n *)\n\n  {--------------------------------ori.h-------------------------------------- }\n  {                       PUBLIC TYPES AND CONSTANTS                           }\n  {--------------------------------------------------------------------------- }\n  { Also see oro.h.  }\n  {--------------------------------------------------------------------------- }\n  {                           PUBLIC FUNCTIONS                                 }\n  {--------------------------------------------------------------------------- }\n  {--------------------------------------------------------------------------- }\n  {                       OBJECT/INSTANCE OPERATIONS                           }\n  {--------------------------------------------------------------------------- }\n  {--------------------------- OCIObjectNew ---------------------------------- }\n  OCITypeCode = ub2;\n  TOCIObjectNew = function(env: POCIEnv; err: POCIError; const svc: POCISvcCtx;\n    const typecode: OCITypeCode; const tdo: POCIType; const table: Pointer;\n    const duration: OCIDuration; const value: boolean;\n    instance: PPointer): sword; cdecl;\n  {\n     NAME: OCIObjectNew - OCI new (create) a standalone instance\n     PARAMETERS:\n          env  (IN/OUT) - OCI environment handle initialized in object mode\n          err  (IN/OUT) - error handle. If there is an error, it is\n                          recorded in 'err' and this function returns OCI_ERROR.\n                          The error recorded in 'err' can be retrieved by calling\n                          OCIErrorGet().\n          svc      (IN) - OCI service handle.\n          typecode (IN) - the typecode of the type of the instance.\n          tdo      (IN, optional) - pointer to the type descriptor object. The\n                          TDO describes the type of the instance that is to be\n                          created. Refer to OCITypeByName() for obtaining a TDO.\n                          The TDO is required for creating a named type (e.g. an\n                          object or a collection).\n          table (IN, optional) - pointer to a table object which specifies a\n                          table in the server.  This parameter can be set to NULL\n                          if no table is given. See the description below to find\n                          out how the table object and the TDO are used together\n                          to determine the kind of instances (persistent,\n                          transient, value) to be created. Also see\n                          OCIObjectPinTable() for retrieving a table object.\n          duration (IN) - this is an overloaded parameter. The use of this\n                          parameter is based on the kind of the instance that is\n                          to be created.\n                          a) persistent object. This parameter specifies the\n                             pin duration.\n                          b) transient object. This parameter specififes the\n                             allocation duration and pin duration.\n                          c) value. This parameter specifies the allocation\n                             duration.\n          value    (IN)  - specifies whether the created object is a value.\n                           If TRUE, then a value is created. Otherwise, a\n                           referenceable object is created.  If the instance is\n                           not an object, then this parameter is ignored.\n          instance (OUT) - address of the newly created instance\n\n     REQUIRES:\n          - a valid OCI environment handle must be given.\n     DESCRIPTION:\n          This function creates a new instance of the type specified by the\n          typecode or the TDO. Based on the parameters 'typecode' (or 'tdo'),\n          'value' and 'table', different kinds of instances can be created:\n\n                                       The parameter 'table' is not NULL?\n\n                                                 yes              no\n               ----------------------------------------------------------------\n               | object type (value=TRUE)   |   value         |   value       |\n               ----------------------------------------------------------------\n               | object type (value=FALSE)  | persistent obj  | transient obj |\n         type  ----------------------------------------------------------------\n               | built-in type              |   value         |   value       |\n               ----------------------------------------------------------------\n               | collection type            |   value         |   value       |\n               ----------------------------------------------------------------\n\n          This function allocates the top level memory chunk of an OTS instance.\n          The attributes in the top level memory are initialized (e.g. an\n          attribute of varchar2 is initialized to a vstring of 0 length).\n\n          If the instance is an object, the object is marked existed but is\n          atomically null.\n\n          FOR PERSISTENT OBJECTS:\n          The object is marked dirty and existed.  The allocation duration for\n          the object is session. The object is pinned and the pin duration is\n          specified by the given parameter 'duration'.\n\n          FOR TRANSIENT OBJECTS:\n          The object is pinned. The allocation duration and the pin duration are\n          specified by the given parameter 'duration'.\n\n          FOR VALUES:\n          The allocation duration is specified by the given parameter 'duration'.\n\n     RETURNS:\n          if environment handle or error handle is null, return\n          OCI_INVALID_HANDLE.\n          if operation suceeds, return OCI_SUCCESS.\n          if operation fails, return OCI_ERROR.\n    }\n  {--------------------------- OCIObjectPin ---------------------------------- }\n  POCIComplexObject = Pointer;\n  PPOCIComplexObject = ^POCIComplexObject;\n  OCIPinOpt = ub2;\n  OCILockOpt = pub2;\n\n  TOCIObjectPin = function(env: POCIEnv; err: POCIError;\n    const object_ref: POCIRef; const corhdl: POCIComplexObject;\n    const pin_option: OCIPinOpt; const pin_duration: OCIDuration;\n    const lock_option: OCILockOpt; _object: PPointer): sword; cdecl;\n  {\n     NAME: OCIObjectPin - OCI pin a referenceable object\n     PARAMETERS:\n          env        (IN/OUT) - OCI environment handle initialized in object mode\n          err        (IN/OUT) - error handle. If there is an error, it is\n                                recorded in 'err' and this function returns\n                                OCI_ERROR. The error recorded in 'err' can be\n                                retrieved by calling OCIErrorGet().\n          object_ref     (IN) - the reference to the object.\n          corhdl         (IN) - handle for complex object retrieval.\n          pin_option     (IN) - See description below.\n          pin_duration   (IN) - The duration of which the object is being accesed\n                                by a client. The object is implicitly unpinned at\n                                the end of the pin duration.\n                                If OCI_DURATION_NULL is passed, there is no pin\n                                promotion if the object is already loaded into\n                                the cache. If the object is not yet loaded, then\n                                the pin duration is set to OCI_DURATION_DEFAULT.\n          lock_option    (IN) - lock option (e.g., exclusive). If a lock option\n                                is specified, the object is locked in the server.\n                                See 'oro.h' for description about lock option.\n          object        (OUT) - the pointer to the pinned object.\n\n     REQUIRES:\n          - a valid OCI environment handle must be given.\n     DESCRIPTION:\n\n          This function pins a referenceable object instance given the object\n          reference. The process of pinning serves three purposes:\n\n          1) locate an object given its reference. This is done by the object\n             cache which keeps track of the objects in the object heap.\n\n          2) notify the object cache that an object is being in use. An object\n             can be pinned many times. A pinned object will remain in memory\n             until it is completely unpinned (see OCIObjectUnpin()).\n\n          3) notify the object cache that a persistent object is being in use\n             such that the persistent object cannot be aged out.  Since a\n             persistent object can be loaded from the server whenever is needed,\n             the memory utilization can be increased if a completely unpinned\n             persistent object can be freed (aged out), even before the\n             allocation duration is expired.\n\n          Also see OCIObjectUnpin() for more information about unpinning.\n\n          FOR PERSISTENT OBJECTS:\n\n          When pinning a persistent object, if it is not in the cache, the object\n          will be fetched from the persistent store. The allocation duration of\n          the object is session. If the object is already in the cache, it is\n          returned to the client.  The object will be locked in the server if a\n          lock option is specified.\n\n          This function will return an error for a non-existent object.\n\n          A pin option is used to specify the copy of the object that is to be\n          retrieved:\n\n          1) If option is OCI_PIN_ANY (pin any), if the object is already\n             in the environment heap, return this object. Otherwise, the object\n             is retrieved from the database.  This option is useful when the\n             client knows that he has the exclusive access to the data in a\n             session.\n\n          2) If option is OCI_PIN_LATEST (pin latest), if the object is\n             not cached, it is retrieved from the database.  If the object is\n             cached, it is refreshed with the latest version. See\n             OCIObjectRefresh() for more information about refreshing.\n\n          3) If option is OCI_PIN_RECENT (pin recent), if the object is loaded\n             into the cache in the current transaction, the object is returned.\n             If the object is not loaded in the current transaction, the object\n             is refreshed from the server.\n\n          FOR TRANSIENT OBJECTS:\n\n          This function will return an error if the transient object has already\n          been freed. This function does not return an error if an exclusive\n          lock is specified in the lock option.\n\n     RETURNS:\n          if environment handle or error handle is null, return\n          OCI_INVALID_HANDLE.\n          if operation suceeds, return OCI_SUCCESS.\n          if operation fails, return OCI_ERROR.\n    }\n  {------------------------------ OCIObjectUnpin ----------------------------- }\n  TOCIObjectUnpin = function(env: POCIEnv; err: POCIError;\n    const _object: Pointer): sword; cdecl;\n  {\n     NAME: OCIObjectUnpin - OCI unpin a referenceable object\n     PARAMETERS:\n          env   (IN/OUT) - OCI environment handle initialized in object mode\n          err   (IN/OUT) - error handle. If there is an error, it is\n                           recorded in 'err' and this function returns OCI_ERROR.\n                           The error recorded in 'err' can be retrieved by\n                           calling OCIErrorGet().\n          object    (IN) - pointer to an object\n     REQUIRES:\n          - a valid OCI environment handle must be given.\n          - The specified object must be pinned.\n     DESCRIPTION:\n          This function unpins an object.  An object is completely unpinned when\n            1) the object was unpinned N times after it has been pinned N times\n               (by calling OCIObjectPin()).\n            2) it is the end of the pin duration\n            3) the function OCIObjectPinCountReset() is called\n\n          There is a pin count associated with each object which is incremented\n          whenever an object is pinned. When the pin count of the object is zero,\n          the object is said to be completely unpinned. An unpinned object can\n          be freed without error.\n\n          FOR PERSISTENT OBJECTS:\n          When a persistent object is completely unpinned, it becomes a candidate\n          for aging. The memory of an object is freed when it is aged out. Aging\n          is used to maximize the utilization of memory.  An dirty object cannot\n          be aged out unless it is flushed.\n\n          FOR TRANSIENT OBJECTS:\n          The pin count of the object is decremented. A transient can be freed\n          only at the end of its allocation duration or when it is explicitly\n          deleted by calling OCIObjectFree().\n\n          FOR VALUE:\n          This function will return an error for value.\n\n     RETURNS:\n          if environment handle or error handle is null, return\n          OCI_INVALID_HANDLE.\n          if operation suceeds, return OCI_SUCCESS.\n          if operation fails, return OCI_ERROR.\n    }\n  {---------------------------- OCIObjectPinCountReset ----------------------- }\n  TOCIObjectPinCountReset = function (env: POCIEnv; err: POCIError;\n    const _object: pointer): sword; cdecl;\n  {\n     NAME: OCIObjectPinCountReset - OCI resets the pin count of a referenceable\n                                    object\n     PARAMETERS:\n          env   (IN/OUT) - OCI environment handle initialized in object mode\n          err   (IN/OUT) - error handle. If there is an error, it is\n                           recorded in 'err' and this function returns OCI_ERROR.\n                           The error recorded in 'err' can be retrieved by\n                           calling OCIErrorGet().\n          object    (IN) - pointer to an object\n     REQUIRES:\n          - a valid OCI environment handle must be given.\n          - The specified object must be pinned.\n     DESCRIPTION:\n          This function completely unpins an object.  When an object is\n          completely unpinned, it can be freed without error.\n\n          FOR PERSISTENT OBJECTS:\n          When a persistent object is completely unpinned, it becomes a candidate\n          for aging. The memory of an object is freed when it is aged out. Aging\n          is used to maximize the utilization of memory.  An dirty object cannot\n          be aged out unless it is flushed.\n\n          FOR TRANSIENT OBJECTS:\n          The pin count of the object is decremented. A transient can be freed\n          only at the end of its allocation duration or when it is explicitly\n          freed by calling OCIObjectFree().\n\n          FOR VALUE:\n          This function will return an error for value.\n\n     RETURNS:\n          if environment handle or error handle is null, return\n          OCI_INVALID_HANDLE.\n          if operation suceeds, return OCI_SUCCESS.\n          if operation fails, return OCI_ERROR.\n    }\n  {--------------------------- OCIObjectLock --------------------------------- }\n  TOCIObjectLock = function(env: POCIEnv; err: POCIError;\n    const _object: pointer): sword; cdecl;\n\n  {\n     NAME: OCIObjectLock - OCI lock a persistent object\n     PARAMETERS:\n          env   (IN/OUT) - OCI environment handle initialized in object mode\n          err   (IN/OUT) - error handle. If there is an error, it is\n                           recorded in 'err' and this function returns OCI_ERROR.\n                           The error recorded in 'err' can be retrieved by\n                           calling OCIErrorGet().\n          object    (IN) - pointer to the persistent object\n     REQUIRES:\n          - a valid OCI environment handle must be given.\n          - The specified object must be pinned.\n     DESCRIPTION:\n          This function locks a persistent object at the server. Unlike\n          OCIObjectLockNoWait() this function waits if another user currently\n          holds a lock on the desired object. This function\n          returns an error if:\n            1) the object is non-existent.\n\n          This function will return an error for transient objects and values.\n          The lock of an object is released at the end of a transaction.\n\n     RETURNS:\n          if environment handle or error handle is null, return\n          OCI_INVALID_HANDLE.\n          if operation suceeds, return OCI_SUCCESS.\n          if operation fails, return OCI_ERROR.\n   }\n  {------------------------ OCIObjectLockNoWait ------------------------------ }\n  TOCIObjectLockNoWait = function(env: POCIEnv; err: POCIError;\n    const _object: pointer): sword; cdecl;\n\n  {\n     NAME: OCIObjectLockNoWait - OCI lock a persistent object, do not wait for\n                                 the lock, return error if lock not available\n     PARAMETERS:\n          env   (IN/OUT) - OCI environment handle initialized in object mode\n          err   (IN/OUT) - error handle. If there is an error, it is\n                           recorded in 'err' and this function returns OCI_ERROR.\n                           The error recorded in 'err' can be retrieved by\n                           calling OCIErrorGet().\n          object    (IN) - pointer to the persistent object\n     REQUIRES:\n          - a valid OCI environment handle must be given.\n          - The specified object must be pinned.\n     DESCRIPTION:\n          This function locks a persistent object at the server. Unlike\n          OCIObjectLock() this function will not wait if another user holds\n          the lock on the desired object. This function returns an error if:\n            1) the object is non-existent.\n            2) the object is currently locked by another user in which\n               case this function returns with an error.\n\n          This function will return an error for transient objects and values.\n          The lock of an object is released at the end of a transaction.\n\n     RETURNS:\n          if environment handle or error handle is null, return\n          OCI_INVALID_HANDLE.\n          if operation suceeds, return OCI_SUCCESS.\n          if operation fails, return OCI_ERROR.\n   }\n  {--------------------------- OCIObjectMarkUpdate --------------------------- }\n  TOCIObjectMarkUpdate = function(env: POCIEnv; err: POCIError;\n    const _object: pointer): sword; cdecl;\n\n  {\n     NAME: OCIObjectMarkUpdate - OCI marks an object as updated\n     PARAMETERS:\n          env   (IN/OUT) - OCI environment handle initialized in object mode\n          err   (IN/OUT) - error handle. If there is an error, it is\n                           recorded in 'err' and this function returns OCI_ERROR.\n                           The error recorded in 'err' can be retrieved by\n                           calling OCIErrorGet().\n          object    (IN) - pointer to the persistent object\n     REQUIRES:\n          - a valid OCI environment handle must be given.\n          - The specified object must be pinned.\n     DESCRIPTION:\n          FOR PERSISTENT OBJECTS:\n          This function marks the specified persistent object as updated. The\n          persistent objects will be written to the server when the object cache\n          is flushed.  The object is not locked or flushed by this function. It\n          is an error to update a deleted object.\n\n          After an object is marked updated and flushed, this function must be\n          called again to mark the object as updated if it has been dirtied\n          after it is being flushed.\n\n          FOR TRANSIENT OBJECTS:\n          This function marks the specified transient object as updated. The\n          transient objects will NOT be written to the server. It is an error\n          to update a deleted object.\n\n          FOR VALUES:\n          It is an no-op for values.\n\n     RETURNS:\n          if environment handle or error handle is null, return\n          OCI_INVALID_HANDLE.\n          if operation suceeds, return OCI_SUCCESS.\n          if operation fails, return OCI_ERROR.\n    }\n  {----------------------------- OCIObjectUnmark ----------------------------- }\n  TOCIObjectUnmark = function(env: POCIEnv; err: POCIError;\n    const _object:pointer): sword; cdecl;\n\n  {\n     NAME: OCIObjectUnmark - OCI unmarks an object\n     PARAMETERS:\n          env   (IN/OUT) - OCI environment handle initialized in object mode\n          err   (IN/OUT) - error handle. If there is an error, it is\n                           recorded in 'err' and this function returns OCI_ERROR.\n                           The error recorded in 'err' can be retrieved by\n                           calling OCIErrorGet().\n          object    (IN) - pointer to the persistent object\n     REQUIRES:\n          - a valid OCI environment handle must be given.\n          - The specified object must be pinned.\n     DESCRIPTION:\n          FOR PERSISTENT OBJECTS AND TRANSIENT OBJECTS:\n          This function unmarks the specified persistent object as dirty. Changes\n          that are made to the object will not be written to the server. If the\n          object is marked locked, it remains marked locked.  The changes that\n          have already made to the object will not be undone implicitly.\n\n          FOR VALUES:\n          It is an no-op for values.\n\n     RETURNS:\n          if environment handle or error handle is null, return\n          OCI_INVALID_HANDLE.\n          if operation suceeds, return OCI_SUCCESS.\n          if operation fails, return OCI_ERROR.\n    }\n  {----------------------------- OCIObjectUnmarkByRef ------------------------ }\n  TOCIObjectUnmarkByRef = function(env: POCIEnv; err: POCIError;\n    const ref: POCIRef): sword; cdecl;\n\n  {\n     NAME: OCIObjectUnmarkByRef - OCI unmarks an object by Ref\n     PARAMETERS:\n          env   (IN/OUT) - OCI environment handle initialized in object mode\n          err   (IN/OUT) - error handle. If there is an error, it is\n                           recorded in 'err' and this function returns OCI_ERROR.\n                           The error recorded in 'err' can be retrieved by\n                           calling OCIErrorGet().\n          ref   (IN) - reference of the object\n     REQUIRES:\n          - a valid OCI environment handle must be given.\n          - The specified object must be pinned.\n     DESCRIPTION:\n          FOR PERSISTENT OBJECTS AND TRANSIENT OBJECTS:\n          This function unmarks the specified persistent object as dirty. Changes\n          that are made to the object will not be written to the server. If the\n          object is marked locked, it remains marked locked.  The changes that\n          have already made to the object will not be undone implicitly.\n\n          FOR VALUES:\n          It is an no-op for values.\n\n     RETURNS:\n          if environment handle or error handle is null, return\n          OCI_INVALID_HANDLE.\n          if operation suceeds, return OCI_SUCCESS.\n          if operation fails, return OCI_ERROR.\n    }\n  {--------------------------- OCIObjectFree --------------------------------- }\n  TOCIObjectFree = function(env: POCIEnv; err: POCIError;\n    const instance: pointer; const flags: ub2): sword; cdecl;\n\n  {\n     NAME: OCIObjectFree - OCI free (and unpin) an standalone instance\n     PARAMETERS:\n          env    (IN/OUT) - OCI environment handle initialized in object mode\n          err    (IN/OUT) - error handle. If there is an error, it is\n                            recorded in 'err' and this function returns\n                            OCI_ERROR.  The error recorded in 'err' can be\n                            retrieved by calling OCIErrorGet().\n          instance   (IN) - pointer to a standalone instance.\n          flags      (IN) - If OCI_OBJECT_FREE_FORCE is set, free the object\n                            even if it is pinned or dirty.\n                            If OCI_OBJECT_FREE_NONULL is set, the null\n                            structure will not be freed.\n     REQUIRES:\n          - a valid OCI environment handle must be given.\n          - The instance to be freed must be standalone.\n          - If the instance is a referenceable object, the object must be pinned.\n     DESCRIPTION:\n          This function deallocates all the memory allocated for an OTS instance,\n          including the null structure.\n\n          FOR PERSISTENT OBJECTS:\n          This function will return an error if the client is attempting to free\n          a dirty persistent object that has not been flushed. The client should\n          either flush the persistent object or set the parameter 'flag' to\n          OCI_OBJECT_FREE_FORCE.\n\n          This function will call OCIObjectUnpin() once to check if the object\n          can be completely unpin. If it succeeds, the rest of the function will\n          proceed to free the object.  If it fails, then an error is returned\n          unless the parameter 'flag' is set to OCI_OBJECT_FREE_FORCE.\n\n          Freeing a persistent object in memory will not change the persistent\n          state of that object at the server.  For example, the object will\n          remain locked after the object is freed.\n\n          FOR TRANSIENT OBJECTS:\n\n          This function will call OCIObjectUnpin() once to check if the object\n          can be completely unpin. If it succeeds, the rest of the function will\n          proceed to free the object.  If it fails, then an error is returned\n          unless the parameter 'flag' is set to OCI_OBJECT_FREE_FORCE.\n\n          FOR VALUES:\n          The memory of the object is freed immediately.\n\n     RETURNS:\n          if environment handle or error handle is null, return\n          OCI_INVALID_HANDLE.\n          if operation suceeds, return OCI_SUCCESS.\n          if operation fails, return OCI_ERROR.\n   }\n  {----------------------- OCIObjectMarkDeleteByRef -------------------------- }\n  TOCIObjectMarkDeleteByRef = function(env: POCIEnv; err: POCIError;\n    const object_ref:POCIRef): sword; cdecl;\n\n  {\n     NAME: OCIObjectMarkDeleteByRef - OCI \"delete\" (and unpin) an object given\n                                      a reference\n     PARAMETERS:\n          env     (IN/OUT) - OCI environment handle initialized in object mode\n          err     (IN/OUT) - error handle. If there is an error, it is\n                             recorded in 'err' and this function returns\n                             OCI_ERROR.  The error recorded in 'err' can be\n                             retrieved by calling OCIErrorGet().\n          object_ref  (IN) - ref of the object to be deleted\n\n     REQUIRES:\n          - a valid OCI environment handle must be given.\n     DESCRIPTION:\n          This function marks the object designated by 'object_ref' as deleted.\n\n          FOR PERSISTENT OBJECTS:\n          If the object is not loaded, then a temporary object is created and is\n          marked deleted. Otherwise, the object is marked deleted.\n\n          The object is deleted in the server when the object is flushed.\n\n          FOR TRANSIENT OBJECTS:\n          The object is marked deleted.  The object is not freed until it is\n          unpinned.\n\n     RETURNS:\n          if environment handle or error handle is null, return\n          OCI_INVALID_HANDLE.\n          if operation suceeds, return OCI_SUCCESS.\n          if operation fails, return OCI_ERROR.\n    }\n  {--------------------------- OCIObjectMarkDelete --------------------------- }\n  TOCIObjectMarkDelete = function(env: POCIEnv; err: POCIError;\n    const instance:pointer): sword; cdecl;\n\n  {\n     NAME: OCIObjectMarkDelete - OCI \"delete\" an instance given a Pointer\n     PARAMETERS:\n          env    (IN/OUT) - OCI environment handle initialized in object mode\n          err    (IN/OUT) - error handle. If there is an error, it is\n                            recorded in 'err' and this function returns\n                            OCI_ERROR.  The error recorded in 'err' can be\n                            retrieved by calling OCIErrorGet().\n          instance   (IN) - pointer to the instance\n     REQUIRES:\n          - a valid OCI environment handle must be given.\n          - The instance must be standalone.\n          - If the instance is a referenceable object, then it must be pinned.\n     DESCRIPTION:\n\n          FOR PERSISTENT OBJECTS:\n          The object is marked deleted.  The memory of the object is not freed.\n          The object is deleted in the server when the object is flushed.\n\n          FOR TRANSIENT OBJECTS:\n          The object is marked deleted.  The memory of the object is not freed.\n\n          FOR VALUES:\n          This function frees a value immediately.\n\n     RETURNS:\n          if environment handle or error handle is null, return\n          OCI_INVALID_HANDLE.\n          if operation suceeds, return OCI_SUCCESS.\n          if operation fails, return OCI_ERROR.\n    }\n  {---------------------------- OCIObjectFlush ------------------------------- }\n  TOCIObjectFlush = function(env: POCIEnv; err: POCIError;\n    const _object: pointer): sword; cdecl;\n\n  {\n     NAME: OCIObjectFlush - OCI flush a persistent object\n     PARAMETERS:\n          env    (IN/OUT) - OCI environment handle initialized in object mode\n          err    (IN/OUT) - error handle. If there is an error, it is\n                            recorded in 'err' and this function returns\n                            OCI_ERROR.  The error recorded in 'err' can be\n                            retrieved by calling OCIErrorGet().\n          object     (IN) - pointer to the persistent object\n     REQUIRES:\n          - a valid OCI environment handle must be given.\n          - The specified object must be pinned.\n     DESCRIPTION:\n          This function flushes a modified persistent object to the server.\n          An exclusive lock is obtained implicitly for the object when flushed.\n\n          When the object is written to the server, triggers may be fired.\n          Objects can be modified by the triggers at the server.  To keep the\n          objects in the object cache being coherent with the database, the\n          clients can free or refresh the objects in the cache.\n\n          This function will return an error for transient objects and values.\n\n     RETURNS:\n          if environment handle or error handle is null, return\n          OCI_INVALID_HANDLE.\n          if operation suceeds, return OCI_SUCCESS.\n          if operation fails, return OCI_ERROR.\n    }\n  {------------------------ OCIObjectRefresh --------------------------------- }\n  TOCIObjectRefresh = function(env: POCIEnv; err: POCIError;\n    _object: pointer): sword; cdecl;\n\n  {\n     NAME: OCIObjectRefresh - OCI refresh a persistent object\n     PARAMETERS:\n          env    (IN/OUT) - OCI environment handle initialized in object mode\n          err    (IN/OUT) - error handle. If there is an error, it is\n                            recorded in 'err' and this function returns\n                            OCI_ERROR.  The error recorded in 'err' can be\n                            retrieved by calling OCIErrorGet().\n          object     (IN) - pointer to the persistent object\n     REQUIRES:\n          - a valid OCI environment handle must be given.\n          - The specified object must be pinned.\n     DESCRIPTION:\n          This function refreshes an unmarked object with data retrieved from the\n          latest snapshot in the server. An object should be refreshed when the\n          objects in the cache are inconsistent with the objects at\n          the server:\n          1) When an object is flushed to the server, triggers can be fired to\n             modify more objects in the server.  The same objects (modified by\n             the triggers) in the object cache become obsolete.\n          2) When the user issues a SQL or executes a PL/SQL procedure to modify\n             any object in the server, the same object in the cache becomes\n             obsolete.\n\n          The object that is refreshed will be 'replaced-in-place'. When an\n          object is 'replaced-in-place', the top level memory of the object will\n          be reused so that new data can be loaded into the same memory address.\n          The top level memory of the null structre is also reused. Unlike the\n          top level memory chunk, the secondary memory chunks may be resized and\n          reallocated.  The client should be careful when holding onto a pointer\n          to the secondary memory chunk (e.g. assigning the address of a\n          secondary memory to a local variable), since this pointer can become\n          invalid after the object is refreshed.\n\n          The object state will be modified as followed after being refreshed:\n            - existent : set to appropriate value\n            - pinned   : unchanged\n            - allocation duration : unchanged\n            - pin duration : unchanged\n\n          This function is an no-op for transient objects or values.\n\n     RETURNS:\n          if environment handle or error handle is null, return\n          OCI_INVALID_HANDLE.\n          if operation suceeds, return OCI_SUCCESS.\n          if operation fails, return OCI_ERROR.\n    }\n  {---------------------------- OCIObjectCopy -------------------------------- }\n  TOCIObjectCopy = function(env: POCIEnv; err: POCIError; const svc: POCISvcCtx;\n    const source, null_source, target, null_target: pointer; const tdo: POCIType;\n    const duration: OCIDuration; const option: ub1): sword; cdecl;\n\n  {\n     NAME: OCIObjectCopy - OCI copy one instance to another\n     PARAMETERS:\n          env     (IN/OUT) - OCI environment handle initialized in object mode\n          err     (IN/OUT) - error handle. If there is an error, it is\n                             recorded in 'err' and this function returns\n                             OCI_ERROR.  The error recorded in 'err' can be\n                             retrieved by calling OCIErrorGet().\n          svc         (IN) - OCI service context handle\n          source      (IN) - pointer to the source instance\n          null_source (IN) - pointer to the null structure of the source\n          target      (IN) - pointer to the target instance\n          null_target (IN) - pointer to the null structure of the target\n          tdo         (IN) - the TDO for both source and target\n          duration    (IN) - allocation duration of the target memory\n          option      (IN) - specify the copy option:\n                          OROOCOSFN - Set Reference to Null. All references\n                          in the source will not be copied to the target. The\n                          references in the target are set to null.\n     REQUIRES:\n          - a valid OCI environment handle must be given.\n          - If source or target is referenceable, it must be pinned.\n          - The target or the containing instance of the target must be already\n            be instantiated (e.g. created by OCIObjectNew()).\n          - The source and target instances must be of the same type. If the\n            source and target are located in a different databases, then the\n            same type must exist in both databases.\n     DESCRIPTION:\n          This function copies the contents of the 'source' instance to the\n          'target' instance. This function performs a deep-copy such that the\n          data that is copied/duplicated include:\n          a) all the top level attributes (see the exceptions below)\n          b) all the secondary memory (of the source) that is reachable from the\n             top level attributes.\n          c) the null structure of the instance\n\n          Memory is allocated with the specified allocation duration.\n\n          Certain data items are not copied:\n          a) If the option OCI_OBJECTCOPY_NOREF is specified, then all references\n             in the source are not copied. Instead, the references in the target\n             are set to null.\n          b) If the attribute is a LOB, then it is set to null.\n\n     RETURNS:\n          if environment handle or error handle is null, return\n          OCI_INVALID_HANDLE.\n          if operation suceeds, return OCI_SUCCESS.\n          if operation fails, return OCI_ERROR.\n    }\n  {---------------------------- OCIObjectGetTypeRef -------------------------- }\n  TOCIObjectGetTypeRef = function(env: POCIEnv; err: POCIError;\n    const instance:pointer; type_ref: POCIRef): sword; cdecl;\n\n  {\n     NAME: OCIObjectGetTypeRef - get the type reference of a standalone object\n     PARAMETERS:\n          env   (IN/OUT) - OCI environment handle initialized in object mode\n          err   (IN/OUT) - error handle. If there is an error, it is\n                           recorded in 'err' and this function returns\n                           OCI_ERROR.  The error recorded in 'err' can be\n                           retrieved by calling OCIErrorGet().\n          instance  (IN) - pointer to an standalone instance\n          type_ref (OUT) - reference to the type of the object.  The reference\n                           must already be allocated.\n     REQUIRES:\n          - a valid OCI environment handle must be given.\n          - The instance must be standalone.\n          - If the object is referenceable, the specified object must be pinned.\n          - The reference must already be allocated.\n     DESCRIPTION:\n          This function returns a reference to the TDO of a standalone instance.\n     RETURNS:\n          if environment handle or error handle is null, return\n          OCI_INVALID_HANDLE.\n          if operation suceeds, return OCI_SUCCESS.\n          if operation fails, return OCI_ERROR.\n    }\n  {--------------------------- OCIObjectGetObjectRef ------------------------- }\n  TOCIObjectGetObjectRef = function(env: POCIEnv; err: POCIError;\n    const _object: pointer; bject_ref: POCIRef): sword; cdecl;\n\n  {\n     NAME: OCIObjectGetObjectRef - OCI get the object reference of an\n                                   referenceable object\n     PARAMETERS:\n          env     (IN/OUT) - OCI environment handle initialized in object mode\n          err     (IN/OUT) - error handle. If there is an error, it is\n                             recorded in 'err' and this function returns\n                             OCI_ERROR.  The error recorded in 'err' can be\n                             retrieved by calling OCIErrorGet().\n          object      (IN) - pointer to a persistent object\n          object_ref (OUT) - reference of the given object. The reference must\n                             already be allocated.\n     REQUIRES:\n          - a valid OCI environment handle must be given.\n          - The specified object must be pinned.\n          - The reference must already be allocated.\n     DESCRIPTION:\n          This function returns a reference to the given object.  It returns an\n          error for values.\n     RETURNS:\n          if environment handle or error handle is null, return\n          OCI_INVALID_HANDLE.\n          if operation suceeds, return OCI_SUCCESS.\n          if operation fails, return OCI_ERROR.\n    }\n  {--------------------------- OCIObjectMakeObjectRef ----------------------- }\n  TOCIObjectMakeObjectRef = function(env: POCIEnv; err: POCIError;\n    const svc: POCISvcCtx; const table: pointer; const values: PPointer;\n    const array_len: ub4; object_ref: POCIRef): sword; cdecl;\n\n  {\n     NAME: OCIObjectMakeObjectRef - OCI Create an object reference to a\n                                   referenceable object.\n     PARAMETERS:\n          env     (IN/OUT) - OCI environment handle initialized in object mode\n          err     (IN/OUT) - error handle. If there is an error, it is\n                             recorded in 'err' and this function returns\n                             OCI_ERROR.  The error recorded in 'err' can be\n                             retrieved by calling OCIErrorGet().\n          svc         (IN) - the service context\n          table       (IN) - A pointer to the table object (must be pinned)\n          attrlist    (IN) - A list of values (OCI type values) from which\n                             the ref is to be created.\n          attrcnt     (IN)  - The length of the attrlist array.\n          object_ref (OUT) - reference of the given object. The reference must\n                             already be allocated.\n     REQUIRES:\n          - a valid OCI environment handle must be given.\n          - The specified table object must be pinned.\n          - The reference must already be allocated.\n     DESCRIPTION:\n          This function creates a reference given the values that make up the\n          reference and also a pointer to the table object.\n          Based on the table's OID property, whether it is a pk based OID or\n          a system generated OID, the function creates a sys-generated REF or\n          a pk based REF.\n          In case of system generated REFs pass in a OCIRaw which is 16 bytes\n          long contatining the sys generated OID.\n          In case of PK refs pass in the OCI equivalent for numbers, chars etc..\n     RETURNS:\n          if environment handle or error handle is null, return\n          OCI_INVALID_HANDLE.\n          if operation suceeds, return OCI_SUCCESS.\n          if operation fails, return OCI_ERROR.\n    }\n  {--------------------------- OCIObjectGetPrimaryKeyTypeRef ---------------  }\n  TOCIObjectGetPrimaryKeyTypeRef = function(env: POCIEnv; err: POCIError;\n    const svc:POCISvcCtx; const table: pointer;\n    type_ref: POCIRef): sword; cdecl;\n\n  {\n     NAME: OCIObjectGetPrimaryKeyTypeRef - OCI get the REF to the pk OID type\n     PARAMETERS:\n          env     (IN/OUT) - OCI environment handle initialized in object mode\n          err     (IN/OUT) - error handle. If there is an error, it is\n                             recorded in 'err' and this function returns\n                             OCI_ERROR.  The error recorded in 'err' can be\n                             retrieved by calling OCIErrorGet().\n          svc     (IN)     - the service context\n          table   (IN)     - pointer to the table object\n          type_ref   (OUT) - reference of the pk type. The reference must\n                             already be allocated.\n     REQUIRES:\n          - a valid OCI environment handle must be given.\n          - The specified table object must be pinned.\n          - The reference must already be allocated.\n     DESCRIPTION:\n          This function returns a reference to the pk type.  It returns an\n          error for values.  If the table is not a Pk oid table/view, then\n          it returns error.\n     RETURNS:\n          if environment handle or error handle is null, return\n          OCI_INVALID_HANDLE.\n          if operation suceeds, return OCI_SUCCESS.\n          if operation fails, return OCI_ERROR.\n    }\n  {-------------------------- OCIObjectGetInd -------------------------------- }\n  TOCIObjectGetInd = function(env: POCIEnv; err: POCIError;\n    const instance: pointer; null_struct: PPointer): sword; cdecl;\n\n  {\n     NAME: OCIObjectGetInd - OCI get the null structure of a standalone object\n     PARAMETERS:\n          env     (IN/OUT) - OCI environment handle initialized in object mode\n          err     (IN/OUT) - error handle. If there is an error, it is\n                             recorded in 'err' and this function returns\n                             OCI_ERROR.  The error recorded in 'err' can be\n                             retrieved by calling OCIErrorGet().\n          instance      (IN) - pointer to the instance\n          null_struct (OUT) - null structure\n     REQUIRES:\n          - a valid OCI environment handle must be given.\n          - The object must be standalone.\n          - If the object is referenceable, the specified object must be pinned.\n     DESCRIPTION:\n          This function returns the null structure of an instance. This function\n          will allocate the top level memory of the null structure if it is not\n          already allocated. If an null structure cannot be allocated for the\n          instance, then an error is returned. This function only works for\n          ADT or row type instance.\n     RETURNS:\n          if environment handle or error handle is null, return\n          OCI_INVALID_HANDLE.\n          if operation suceeds, return OCI_SUCCESS.\n          if operation fails, return OCI_ERROR.\n    }\n  {------------------------- OCIObjectExists -------------------------------- }\n  TOCIObjectExists = function(env: POCIEnv; err: POCIError; const ins: pointer;\n    exist: PBoolean): sword; cdecl;\n\n  {\n     NAME: OCIObjectExist - OCI checks if the object exists\n     PARAMETERS:\n          env       (IN/OUT) - OCI environment handle initialized in object mode\n          err       (IN/OUT) - error handle. If there is an error, it is\n                               recorded in 'err' and this function returns\n                               OCI_ERROR.  The error recorded in 'err' can be\n                               retrieved by calling OCIErrorGet().\n          ins           (IN) - pointer to an instance\n          exist        (OUT) - return TRUE if the object exists\n     REQUIRES:\n          - a valid OCI environment handle must be given.\n          - The object must be standalone.\n          - if object is a referenceable, it must be pinned.\n     DESCRIPTION:\n          This function returns the existence of an instance. If the instance\n          is a value, this function always returns TRUE.\n     RETURNS:\n          if environment handle or error handle is null, return\n          OCI_INVALID_HANDLE.\n          if operation suceeds, return OCI_SUCCESS.\n          if operation fails, return OCI_ERROR.\n    }\n  {------------------------- OCIObjectGetProperty --------------------------- }\n  TOCIObjectGetProperty = function(envh: POCIEnv; errh: POCIError;\n    const obj: pointer; const propertyId: OCIObjectPropId;\n    _property: pointer; size: Pub4): sword; cdecl;\n\n  {\n     NAME: OCIObjectGetProperty - OCIObject Get Property of given object\n     PARAMETERS:\n          env       (IN/OUT) - OCI environment handle initialized in object mode\n          err       (IN/OUT) - error handle. If there is an error, it is\n                               recorded in 'err' and this function returns\n                               OCI_ERROR.  The error recorded in 'err' can be\n                               retrieved by calling OCIErrorGet().\n          obj           (IN) - object whose property is returned\n          propertyId    (IN) - id which identifies the desired property\n          property     (OUT) - buffer into which the desired property is\n                               copied\n          size      (IN/OUT) - on input specifies the size of the property buffer\n                               passed by caller, on output will contain the\n                               size in bytes of the property returned.\n                               This parameter is required for string type\n                               properties only (e.g OCI_OBJECTPROP_SCHEMA,\n                               OCI_OBJECTPROP_TABLE). For non-string\n                               properties this parameter is ignored since\n                               the size is fixed.\n     DESCRIPTION:\n          This function returns the specified property of the object.\n          The desired property is identified by 'propertyId'. The property\n          value is copied into 'property' and for string typed properties\n          the string size is returned via 'size'.\n\n          Objects are classified as persistent, transient and value\n          depending upon the lifetime and referenceability of the object.\n          Some of the properties are applicable only to persistent\n          objects and some others only apply to persistent and\n          transient objects. An error is returned if the user tries to\n          get a property which in not applicable to the given object.\n          To avoid such an error, the user should first check whether\n          the object is persistent or transient or value\n          (OCI_OBJECTPROP_LIFETIME property) and then appropriately\n          query for other properties.\n\n          The different property ids and the corresponding type of\n          'property' argument is given below.\n\n            OCI_OBJECTPROP_LIFETIME\n              This identifies whether the given object is a persistent\n              object (OCI_OBJECT_PERSISTENT) or a\n              transient object (OCI_OBJECT_TRANSIENT) or a\n              value instance (OCI_OBJECT_VALUE).\n              'property' argument must be a pointer to a variable of\n              type OCIObjectLifetime.\n\n            OCI_OBJECTPROP_SCHEMA\n              This returns the schema name of the table in which the\n              object exists. An error is returned if the given object\n              points to a transient instance or a value. If the input\n              buffer is not big enough to hold the schema name an error\n              is returned, the error message will communicate the\n              required size. Upon success, the size of the returned\n              schema name in bytes is returned via 'size'.\n              'property' argument must be an array of type text and 'size'\n              should be set to size of array in bytes by the caller.\n\n            OCI_OBJECTPROP_TABLE\n              This returns the table name in which the object exists. An\n              error is returned if the given object points to a\n              transient instance or a value. If the input buffer is not\n              big enough to hold the table name an error is returned,\n              the error message will communicate the required size. Upon\n              success, the size of the returned table name in bytes is\n              returned via 'size'. 'property' argument must be an array\n              of type text and 'size' should be set to size of array in\n              bytes by the caller.\n\n            OCI_OBJECTPROP_PIN_DURATION\n              This returns the pin duration of the object.\n              An error is returned if the given object points to a value\n              instance. Valid pin durations are: OCI_DURATION_SESSION and\n              OCI_DURATION_TRANS.\n              'property' argument must be a pointer to a variable of type\n              OCIDuration.\n\n            OCI_OBJECTPROP_ALLOC_DURATION\n              This returns the allocation duration of the object.\n              Valid allocation durations are: OCI_DURATION_SESSION and\n              OCI_DURATION_TRANS.\n              'property' argument must be a pointer to a variable of type\n              OCIDuration.\n\n            OCI_OBJECTPROP_LOCK\n              This returns the lock status of the\n              object. The possible lock status is enumerated by OCILockOpt.\n              An error is returned if the given object points to a transient\n              or value instance.\n              'property' argument must be a pointer to a variable of\n              type OCILockOpt.\n              Note, the lock status of an object can also be retrieved by\n              calling OCIObjectIsLocked().\n\n            OCI_OBJECTPROP_MARKSTATUS\n              This returns the status flag which indicates whether the\n              object is a new object, updated object and/or deleted object.\n              The following macros can be used to test the mark status\n              flag:\n\n                OCI_OBJECT_IS_UPDATED(flag)\n                OCI_OBJECT_IS_DELETED(flag)\n                OCI_OBJECT_IS_NEW(flag)\n                OCI_OBJECT_IS_DIRTY(flag)\n\n              An object is dirty if it is a new object or marked deleted or\n              marked updated.\n              An error is returned if the given object points to a transient\n              or value instance. 'property' argument must be of type\n              OCIObjectMarkStatus.\n\n            OCI_OBJECTPROP_VIEW\n              This identifies whether the specified object is a view object\n              or not. If property value returned is TRUE, it indicates the\n              object is a view otherwise it is not.\n              'property' argument must be of type boolean.\n\n     RETURNS:\n          if environment handle or error handle is null, return\n          OCI_INVALID_HANDLE.\n          if operation suceeds, return OCI_SUCCESS.\n          if operation fails, return OCI_ERROR. Possible errors are TBD\n    }\n  {---------------------------- OCIObjectIsLocked -------------------------- }\n  TOCIObjectIsLocked = function(env: POCIEnv; err: POCIError; const ins: pointer;\n    lock: Pboolean): sword; cdecl;\n\n  {\n     NAME: OCIObjectIsLocked - OCI get the lock status of a standalone object\n     PARAMETERS:\n          env       (IN/OUT) - OCI environment handle initialized in object mode\n          err       (IN/OUT) - error handle. If there is an error, it is\n                               recorded in 'err' and this function returns\n                               OCI_ERROR.  The error recorded in 'err' can be\n                               retrieved by calling OCIErrorGet().\n          ins           (IN) - pointer to an instance\n          lock         (OUT) - return value for the lock status.\n     REQUIRES:\n          - a valid OCI environment handle must be given.\n          - The instance must be standalone.\n          - If the object is referenceable, the specified object must be pinned.\n     DESCRIPTION:\n          This function returns the lock status of an instance. If the instance\n          is a value, this function always returns FALSE.\n     RETURNS:\n          if environment handle or error handle is null, return\n          OCI_INVALID_HANDLE.\n          if operation suceeds, return OCI_SUCCESS.\n          if operation fails, return OCI_ERROR.\n    }\n  {------------------------- OCIObjectIsDirty ------------------------------ }\n  TOCIObjectIsDirty = function(env: POCIEnv; err: POCIError; const ins: pointer;\n    dirty:Pboolean): sword; cdecl;\n\n  {\n     NAME: OCIObjectIsDirty - OCI get the dirty status of a standalone object\n     PARAMETERS:\n          env       (IN/OUT) - OCI environment handle initialized in object mode\n          err       (IN/OUT) - error handle. If there is an error, it is\n                               recorded in 'err' and this function returns\n                               OCI_ERROR.  The error recorded in 'err' can be\n                               retrieved by calling OCIErrorGet().\n          ins           (IN) - pointer to an instance\n          dirty        (OUT) - return value for the dirty status.\n     REQUIRES:\n          - a valid OCI environment handle must be given.\n          - The instance must be standalone.\n          - if instance is an object, the instance must be pinned.\n     DESCRIPTION:\n          This function returns the dirty status of an instance. If the instance\n          is a value, this function always returns FALSE.\n     RETURNS:\n          if environment handle or error handle is null, return\n          OCI_INVALID_HANDLE.\n          if operation suceeds, return OCI_SUCCESS.\n          if operation fails, return OCI_ERROR.\n    }\n  {--------------------------- OCIObjectPinTable ----------------------------- }\n  TOCIObjectPinTable = function(env: POCIEnv; err: POCIError;\n    const svc:POCISvcCtx; const schema_name: Poratext; const s_n_length: ub4;\n    const object_name: Poratext; const o_n_length:ub4;\n    const scope_obj_ref: POCIRef; const pin_duration: OCIDuration;\n    _object: PPointer): sword; cdecl;\n\n  {\n     NAME: OCIObjectPinTable - OCI get table object\n     PARAMETERS:\n          env       (IN/OUT) - OCI environment handle initialized in object mode\n          err       (IN/OUT) - error handle. If there is an error, it is\n                               recorded in 'err' and this function returns\n                               OCI_ERROR.  The error recorded in 'err' can be\n                               retrieved by calling OCIErrorGet().\n          svc                     (IN) - OCI service context handle\n          schema_name   (IN, optional) - schema name of the table\n          s_n_length    (IN, optional) - length of the schema name\n          object_name   (IN) - name of the table\n          o_n_length    (IN) - length of the table name\n          scope_obj_ref (IN, optional) - reference of the scoping object\n          pin_duration  (IN) - pin duration. See description in OCIObjectPin().\n          object       (OUT) - the pinned table object\n     REQUIRES:\n          - a valid OCI environment handle must be given.\n     DESCRIPTION:\n          This function pin a table object with the specified pin duration.\n          The client can unpin the object by calling OCIObjectUnpin(). See\n          OCIObjectPin() and OCIObjectUnpin() for more information about pinning\n          and unpinning.\n     RETURNS:\n          if environment handle or error handle is null, return\n          OCI_INVALID_HANDLE.\n          if operation suceeds, return OCI_SUCCESS.\n          if operation fails, return OCI_ERROR.\n    }\n  {------------------------- OCIObjectArrayPin ------------------------------- }\n  TOCIObjectArrayPin = function(env: POCIEnv; err: POCIError;\n    const ref_array: PPOCIRef; const array_size: ub4;\n    const cor_array: PPOCIComplexObject; const cor_array_size: ub4;\n    const pin_option: OCIPinOpt; const pin_duration: OCIDuration;\n    const lock: OCILockOpt; obj_array: PPointer;\n    pos: Pub4): sword; cdecl;\n\n  {\n     NAME: OCIObjectArrayPin - ORIO array pin\n     PARAMETERS:\n          env       (IN/OUT) - OCI environment handle initialized in object mode\n          err       (IN/OUT) - error handle. If there is an error, it is\n                               recorded in 'err' and this function returns\n                               OCI_ERROR.  The error recorded in 'err' can be\n                               retrieved by calling OCIErrorGet().\n          ref_array     (IN) - array of references to be pinned\n          array_size    (IN) - number of elements in the array of references\n          pin_option    (IN) - pin option. See OCIObjectPin().\n          pin_duration  (IN) - pin duration. See OCIObjectPin().\n          lock_option   (IN) - lock option. See OCIObjectPin().\n          obj_array    (OUT) - If this argument is not NULL, the pinned objects\n                               will be returned in the array. The user must\n                               allocate this array with element type being\n                               'void *'. The size of this array is identical to\n                               'array'.\n          pos          (OUT) - If there is an error, this argument will contain\n                               the element that is causing the error.  Note that\n                               this argument is set to 1 for the first element in\n                               the ref_array.\n     REQUIRE:\n          - a valid OCI environment handle must be given.\n          - If 'obj_array' is not NULL, then it must already be allocated and\n               the size of 'obj_array' is 'array_size'.\n     DESCRIPTION:\n          This function pin an array of references.  All the pinned objects are\n          retrieved from the database in one network roundtrip.  If the user\n          specifies an output array ('obj_array'), then the address of the\n          pinned objects will be assigned to the elements in the array. See\n          OCIObjectPin() for more information about pinning.\n     RETURNS:\n          if environment handle or error handle is null, return\n          OCI_INVALID_HANDLE.\n          if operation suceeds, return OCI_SUCCESS.\n          if operation fails, return OCI_ERROR.\n    }\n  {--------------------------------------------------------------------------- }\n  {                           HEAP/CACHE OPERATIONS                            }\n  {--------------------------------------------------------------------------- }\n  {--------------------------- OCICacheFlush --------------------------------- }\n  TOCICacheFlushGet = function(context: pointer; last: Pub1): POCIRef; cdecl;\n  TOCICacheFlush = function(env: POCIEnv; err: POCIError; const svc:POCISvcCtx;\n    const context: pointer; const get: TOCICacheFlushGet;\n    ref: PPOCIRef): sword; cdecl;\n\n  {\n     NAME: OCICacheFlush - OCI flush persistent objects\n     PARAMETERS:\n          env (IN/OUT) - OCI environment handle initialized in object mode\n          err (IN/OUT) - error handle. If there is an error, it is\n                        recorded in 'err' and this function returns\n                        OCI_ERROR.  The error recorded in 'err' can be\n                        retrieved by calling OCIErrorGet().\n          svc      (IN) [optional] - OCI service context.  If null pointer is\n                        specified, then the dirty objects in all connections\n                        will be flushed.\n          context  (IN) [optional] - specifies an user context that is an\n                        argument to the client callback function 'get'. This\n                        parameter is set to NULL if there is no user context.\n          get      (IN) [optional] - an client-defined function which acts an\n                        iterator to retrieve a batch of dirty objects that need\n                        to be flushed. If the function is not NULL, this function\n                        will be called to get a reference of a dirty object.\n                        This is repeated until a null reference is returned by\n                        the client function or the parameter 'last' is set to\n                        TRUE. The parameter 'context' is passed to get()\n                        for each invocation of the client function.  This\n                        parameter should be NULL if user callback is not given.\n                        If the object that is returned by the client function is\n                        not a dirtied persistent object, the object is ignored.\n                        All the objects that are returned from the client\n                        function must be from newed or pinned the same service\n                        context, otherwise, an error is signalled. Note that the\n                        returned objects are flushed in the order in which they\n                        are marked dirty.\n          ref     (OUT) [optional] - if there is an error in flushing the\n                        objects, (*ref) will point to the object that\n                        is causing the error.  If 'ref' is NULL, then the object\n                        will not be returned.  If '*ref' is NULL, then a\n                        reference will be allocated and set to point to the\n                        object.  If '*ref' is not NULL, then the reference of\n                        the object is copied into the given space. If the\n                        error is not caused by any of the dirtied object,\n                        the given ref is initalized to be a NULL reference\n                        (OCIRefIsNull(*ref) is TRUE).\n     REQUIRES:\n          - a valid OCI environment handle must be given.\n     DESCRIPTION:\n          This function flushes the modified persistent objects from the\n          environment heap to the server. The objects are flushed in the order\n          that they are marked updated or deleted.\n\n          See OCIObjectFlush() for more information about flushing.\n\n     RETURNS:\n          if environment handle or error handle is null, return\n          OCI_INVALID_HANDLE.\n          if operation suceeds, return OCI_SUCCESS.\n          if operation fails, return OCI_ERROR.\n    }\n  {--------------------------- OCICacheRefresh ------------------------------- }\n  TOCICacheRefreshGet = function(context: pointer): POCIRef; cdecl;\n  TOCICacheRefresh = function(env: POCIEnv; err: POCIError;\n    const svc: POCISvcCtx; const option: OCIRefreshOpt; const context: pointer;\n    get: TOCICacheRefreshGet; ref: PPOCIRef): sword; cdecl;\n\n  {\n     NAME: OCICacheRefresh - OCI ReFreSh persistent objects\n     PARAMETERS:\n          env (IN/OUT) - OCI environment handle initialized in object mode\n          err (IN/OUT) - error handle. If there is an error, it is\n                         recorded in 'err' and this function returns\n                         OCI_ERROR.  The error recorded in 'err' can be\n                         retrieved by calling OCIErrorGet().\n          svc     (IN) [optional] - OCI service context.  If null pointer is\n                        specified, then the persistent objects in all connections\n                        will be refreshed.\n          option   (IN) [optional] - if OCI_REFRESH_LOAD is specified, all\n                        objects that is loaded within the transaction are\n                        refreshed. If the option is OCI_REFERSH_LOAD and the\n                        parameter 'get' is not NULL, this function will ignore\n                        the parameter.\n          context  (IN) [optional] - specifies an user context that is an\n                        argument to the client callback function 'get'. This\n                        parameter is set to NULL if there is no user context.\n          get      (IN) [optional] - an client-defined function which acts an\n                        iterator to retrieve a batch of objects that need to be\n                        refreshed. If the function is not NULL, this function\n                        will be called to get a reference of an object.  If\n                        the reference is not NULL, then the object will be\n                        refreshed.  These steps are repeated until a null\n                        reference is returned by this function.  The parameter\n                        'context' is passed to get() for each invocation of the\n                        client function.  This parameter should be NULL if user\n                        callback is not given.\n          ref     (OUT) [optional] - if there is an error in refreshing the\n                        objects, (*ref) will point to the object that\n                        is causing the error.  If 'ref' is NULL, then the object\n                        will not be returned.  If '*ref' is NULL, then a\n                        reference will be allocated and set to point to the\n                        object.  If '*ref' is not NULL, then the reference of\n                        the object is copied into the given space. If the\n                        error is not caused by any of the object,\n                        the given ref is initalized to be a NULL reference\n                        (OCIRefIsNull(*ref) is TRUE).\n     REQUIRES:\n          - a valid OCI environment handle must be given.\n     DESCRIPTION:\n          This function refreshes all pinned persistent objects. All unpinned\n          persistent objects are freed.  See OCIObjectRefresh() for more\n          information about refreshing.\n     RETURNS:\n          if environment handle or error handle is null, return\n          OCI_INVALID_HANDLE.\n          if operation suceeds, return OCI_SUCCESS.\n          if operation fails, return OCI_ERROR.\n    }\n  {---------------------------- OCICacheUnpin -------------------------------- }\n  TOCICacheUnpin = function(env: POCIEnv; err: POCIError;\n    const svc:POCISvcCtx): sword; cdecl;\n\n  {\n     NAME: OCICacheUnpin - OCI UNPin objects\n     PARAMETERS:\n          env (IN/OUT) - OCI environment handle initialized in object mode\n          err (IN/OUT) - error handle. If there is an error, it is\n                         recorded in 'err' and this function returns\n                         OCI_ERROR.  The error recorded in 'err' can be\n                         retrieved by calling OCIErrorGet().\n          svc     (IN) [optional] - OCI service context. If null pointer is\n                         specified, then the objects in all connections\n                         will be unpinned.\n     REQUIRES:\n          - a valid OCI environment handle must be given.\n     DESCRIPTION:\n          If a connection is specified, this function completely unpins the\n          persistent objects in that connection. Otherwise, all persistent\n          objects in the heap are completely unpinned. All transient objects in\n          the heap are also completely unpinned. See OCIObjectUnpin() for more\n          information about unpinning.\n     RETURNS:\n          if environment handle or error handle is null, return\n          OCI_INVALID_HANDLE.\n          if operation suceeds, return OCI_SUCCESS.\n          if operation fails, return OCI_ERROR.\n    }\n  {----------------------------- OCICacheFree -------------------------------- }\n  TOCICacheFree = function(env: POCIEnv; err: POCIError;\n    const svc: POCISvcCtx): sword; cdecl;\n\n  {\n     NAME: OCICacheFree - OCI FREe instances\n     PARAMETERS:\n          env (IN/OUT) - OCI environment handle initialized in object mode\n          err (IN/OUT) - error handle. If there is an error, it is\n                         recorded in 'err' and this function returns\n                         OCI_ERROR.  The error recorded in 'err' can be\n                         retrieved by calling OCIErrorGet().\n          svc     (IN) [optional] - OCI service context. If null pointer is\n                         specified, then the objects in all connections\n                         will be freed.\n     REQUIRES:\n          - a valid OCI environment handle must be given.\n     DESCRIPTION:\n          If a connection is specified, this function frees the persistent\n          objects, transient objects and values allocated for that connection.\n          Otherwise, all persistent objects, transient objects and values in the\n          heap are freed. Objects are freed regardless of their pin count.  See\n          OCIObjectFree() for more information about freeing an instance.\n     RETURNS:\n          if environment handle or error handle is null, return\n          OCI_INVALID_HANDLE.\n          if operation suceeds, return OCI_SUCCESS.\n          if operation fails, return OCI_ERROR.\n   }\n  {---------------------------- OCICacheUnmark ------------------------------- }\n  TOCICacheUnmark = function(env: POCIEnv; err: POCIError;\n    const svc: POCISvcCtx): sword; cdecl;\n\n  {\n     NAME: OCICacheUnmark - OCI Unmark all dirty objects\n     PARAMETERS:\n          env (IN/OUT) - OCI environment handle initialized in object mode\n          err (IN/OUT) - error handle. If there is an error, it is\n                         recorded in 'err' and this function returns\n                         OCI_ERROR.  The error recorded in 'err' can be\n                         retrieved by calling OCIErrorGet().\n          svc     (IN) [optional] - OCI service context. If null pointer is\n                         specified, then the objects in all connections\n                         will be unmarked.\n     REQUIRES:\n          - a valid OCI environment handle must be given.\n     DESCRIPTION:\n          If a connection is specified, this function unmarks all dirty objects\n          in that connection.  Otherwise, all dirty objects in the cache are\n          unmarked. See OCIObjectUnmark() for more information about unmarking\n          an object.\n     RETURNS:\n          if environment handle or error handle is null, return\n          OCI_INVALID_HANDLE.\n          if operation suceeds, return OCI_SUCCESS.\n          if operation fails, return OCI_ERROR.\n    }\n  TOCIDurationBegin = function(env: POCIEnv; err: POCIError;\n    svc: POCISvcCtx; const parent: OCIDuration;\n    dur: POCIDuration): sword; cdecl;\n\n  {\n     NAME: OCIDurationBegin - OCI DURATION BEGIN\n     PARAMETERS:\n          env  (IN/OUT) - OCI environment handle initialized in object mode\n                          This should be passed NULL, when cartridge services\n                          are to be used.\n          err  (IN/OUT) - error handle. If there is an error, it is\n                          recorded in 'err' and this function returns OCI_ERROR.\n                          The error recorded in 'err' can be retrieved by calling\n                         OCIErrorGet().\n          svc  (IN/OUT) - OCI service handle.\n          parent   (IN) - parent for the duration to be started.\n          dur     (OUT) - newly created user duration\n     REQUIRES:\n          - a valid OCI environment handle must be given for non-cartridge\n            services.\n          - For cartridge services, NULL should be given for environment handle\n          - A valid service handle must be given in all cases.\n     DESCRIPTION:\n          This function starts a new user duration.  A user can have multiple\n          active user durations simultaneously. The user durations do not have\n          to be nested.\n\n          The object subsystem predefines 3 durations :\n            1) session     - memory allocated with session duration comes from\n                             the UGA heap (OCI_DURATION_SESSION). A session\n                             duration terminates at the end of the user session.\n            2) transaction - memory allocated with transaction duration comes\n                             from the UGA heap (OCI_DURATION_TRANS). A trans-\n                             action duration terminates at the end of the user\n                             transaction.\n            3) call        - memory allocated with call duration comes from PGA\n                             heap (OCI_DURATION_CALL). A call duration terminates\n                             at the end of the user call.\n\n          Each user duration has a parent duration.  A parent duration can be a\n          predefined duration or another user duration.  The relationship between\n          a user duration and its parent duration (child duration) are:\n\n           1) An user duration is nested within the parent duration. When its\n               parent duration terminates, the user duration will also terminate.\n           2) The memory allocated with an user duration comes from the heap of\n               its parent duration. For example, if the parent duration of an\n               user duration is call, then the memory allocated with the user\n               duration will also come from the PGA heap.\n\n          This function can be used as both part of cartridge services as well\n          as without cartridge services.\n          The difference in the function in the case of cartridge and\n          non-cartridge services is:\n                  In case of cartridge services, as descibed above a new user\n          duration is created as a child of the \"parent\" duration.\n                  But when used for non-cartridge purposes, when a pre-defined\n          duration is passed in as parent, it is mapped to the cache duration\n          for that connection (which is created if not already present) and\n          the new user duration will be child of the cache duration.\n\n     RETURNS:\n          if environment handle and service handle is null or if error\n          handle is null return OCI_INVALID_HANDLE.\n          if operation suceeds, return OCI_SUCCESS.\n          if operation fails, return OCI_ERROR.\n    }\n  TOCIDurationEnd = function(env: POCIEnv; err: POCIError; svc: POCISvcCtx;\n    duration: OCIDuration): sword; cdecl;\n\n  {\n     NAME: OCIDurationEnd - OCI DURATION END\n     PARAMETERS:\n          env  (IN/OUT) - OCI environment handle initialized in object mode\n                          This should be passed NULL, when cartridge services\n                          are to be used.\n          err  (IN/OUT) - error handle. If there is an error, it is\n                          recorded in 'err' and this function returns OCI_ERROR.\n                          The error recorded in 'err' can be retrieved by calling\n                         OCIErrorGet().\n          svc  (IN/OUT) - OCI service handle.\n          dur     (OUT) - a previously created user duration using\n                          OCIDurationBegin()\n     REQUIRES:\n          - a valid OCI environment handle must be given for non-cartridge\n            services.\n          - For cartridge services, NULL should be given for environment handle\n          - A valid service handle must be given in all cases.\n     DESCRIPTION:\n          This function terminates a user duration.  All memory allocated for\n          this duration is freed.\n\n          This function can be used as both part of cartridge services as well\n          as without cartridge services.  In both cased, the heap duration\n          is freed and all the allocated memory for that duration is freed.\n          The difference in the function in the case of cartridge and\n          non-cartridge services is:\n                  In case of non-cartridge services, if the duration is pre-\n          defined, the associated cache duration (see OCIDurationBegin())\n          is also terminated and the following is done.\n            1) The child durations are terminated.\n            2) All objects pinned for this duration are unpinned.\n            3) All instances allocated for this duration are freed.\n\n                  In case of cartridge services, only the heap duration is\n          freed.  All the context entries allocated for that duration are\n          freed from the context hash table..\n\n     RETURNS:\n          if environment handle and service handle is null or if error\n          handle is null return OCI_INVALID_HANDLE.\n          if operation suceeds, return OCI_SUCCESS.\n          if operation fails, return OCI_ERROR.\n    }\n\n(*-----------------------------ort.h----------------------------------------*)\n\n  {----------------------------- TYPE DESCRIPTION ---------------------------- }\n  {\n   * OCIType - OCI Type Description Object\n   *\n   * The contents of an 'OCIType' is private/opaque to clients.  Clients just\n   * need to declare and pass 'OCIType' pointers in to the type manage\n   * functions.\n   * The pointer points to the type in the object cache.  Thus, clients don't\n   * need to allocate space for this type and must NEVER free the pointer to the\n   * 'OCIType'.\n    }\n\n  type\n  {------------------------- TYPE ELEMENT DESCRIPTION ------------------------ }\n  {\n   * OCITypeElem - OCI Type Element object\n   *\n   * The contents of an 'OCITypeElem' is private/opaque to clients. Clients just\n   * need to declare and pass 'OCITypeElem' pointers in to the type manager\n   * functions.\n   *\n   * 'OCITypeElem' objects contains type element information such as the numeric\n   * precision for example, for number objects, and the number of elements for\n   * arrays.\n   * They ARE used to describe type attributes, collection elements,\n   * method parameters, and method results. Hence they are pass in or returned\n   * by attribute, collection, and method parameter/result accessors.\n    }\n  {--------------------------- METHOD DESCRIPTION --------------------------- }\n  {\n   * OCITypeMethod - OCI Method Description object\n   *\n   * The contents of an 'OCITypeMethod' is private/opaque to clients.  Clients\n   * just need to declare and pass 'OCITypeMethod' pointers in to the type\n   * manager functions.\n   * The pointer points to the method in the object cache.  Thus, clients don't\n   * need to allocate space for this type and must NEVER free the pointer to\n   * the 'OCITypeMethod'.\n    }\n  {--------------------------- TYPE ACCESS ITERATOR -------------------------- }\n  {\n   * OCITypeIter- OCI Type Iterator\n   *\n   * The contents of an 'orti' is private/opaque to clients.  Clients just\n   * need to declare and pass 'orti' pointers in to the type manager functions.\n   * The iterator is used to retreive MDO's and ADO's that belong to the TDO\n   * one at a time. It needs to be allocated by the 'OCITypeIterNew()' function\n   * call and deallocated with the 'OCITypeIterFree()' function call.\n    }\n  {================== }\n  { PUBLIC FUNCTIONS  }\n  {================== }\n  {-------------------------------------------------------------------------- }\n  {                                  ITERATOR                                 }\n  {-------------------------------------------------------------------------- }\n  {-----------------------_- OCITypeIterNew --------------------------------- }\n  { ** OBSOLETE **  }\n\n  TOCITypeIterNew = function (env: POCIEnv; err: POCIError; const tdo: POCIType;\n                      iterator_ort: PPOCITypeIter):sword; cdecl;\n\n  {\n    NAME: OCITypeIterNew - OCI Iterator NEW\n    PARAMETERS:\n         env (IN/OUT) - OCI environment handle initialized in object mode\n         err (IN/OUT) - error handle. If there is an error, it is\n                  recorded in 'err' and this function returns OCI_ERROR.\n                  The error recorded in 'err' can be retrieved by calling\n                  OCIErrorGet().\n         tdo (IN) - pointer to the pinned type in the object cache to\n                  initialize the iterator with\n         iterator_ort (OUT) - pointer to the pointer to the new iterator created\n    DESCRIPTION:\n         Create a new instance of a method/attribute iterator and initalize\n         it's values.\n    RETURNS:\n          OCI_SUCCESS if the function completes successfully.\n          OCI_INVALID_HANDLE if 'env' or 'err' is null.\n          OCI_ERROR if\n             1) any of the required parameters is null.\n             2) error while allocating space for the iterator.\n   }\n  {------------------------ OCITypeIterSet --------------------------------- }\n  { ** OBSOLETE **  }\n  TOCITypeIterSet = function(env: POCIEnv; err: POCIError; const tdo: POCIType;\n                              iterator_ort: POCITypeIter): sword; cdecl;\n\n  {\n    NAME: OCITypeIterSet - OCI Iterator SET\n    PARAMETERS:\n         env (IN/OUT) - OCI environment handle initialized in object mode\n         err (IN/OUT) - error handle. If there is an error, it is\n                  recorded in 'err' and this function returns OCI_ERROR.\n                  The error recorded in 'err' can be retrieved by calling\n                  OCIErrorGet().\n         tdo (IN) - pointer to the pinned type in the object cache to\n                  initialize the iterator with\n         iterator_ort (IN/OUT) - pointer to the iterator to set\n    DESCRIPTION:\n         Initializes the iterator. This is used to reset the state of the\n         iterator.\n    RETURNS:\n          OCI_SUCCESS if the function completes successfully.\n          OCI_INVALID_HANDLE if 'env' or 'err' is null.\n          OCI_ERROR if\n             1) any of the required parameters is null.\n   }\n  {------------------------ OCITypeIterFree --------------------------------- }\n  { ** OBSOLETE **  }\n  TOCITypeIterFree = function(env: POCIEnv; err: POCIError;\n                        iterator_ort: POCITypeIter):sword;\n\n  {\n    NAME: OCITypeIterFree - OCI Iterator FREe\n    PARAMETERS:\n         env (IN/OUT) - OCI environment handle initialized in object mode\n         err (IN/OUT) - error handle. If there is an error, it is\n                  recorded in 'err' and this function returns OCI_ERROR.\n                  The error recorded in 'err' can be retrieved by calling\n                  OCIErrorGet().\n         iterator_ort (IN/OUT) - pointer to the iterator to free\n    DESCRIPTION:\n         Free space allocated for the iterator.\n    RETURNS:\n          OCI_SUCCESS if the function completes successfully.\n          OCI_INVALID_HANDLE if 'env' or 'err' is null.\n          OCI_ERROR if\n             1) any of the required parameters is null.\n             2) error while freeing the iterator, probably bad iterator pointer.\n   }\n  {-------------------------------------------------------------------------- }\n  {                                  TYPE GET                                 }\n  {-------------------------------------------------------------------------- }\n  { ** OBSOLETE **  }\n  TOCITypeByName = function(env: POCIEnv; err: POCIError; const svc: POCISvcCtx;\n    schema_name: Poratext; const s_length: ub4; const type_name: Poratext;\n    const t_length: ub4; version_name: Poratext; const v_length: ub4;\n    const pin_duration: OCIDuration; const get_option: OCITypeGetOpt;\n    tdo: PPOCIType): sword; cdecl;\n\n  {\n    NAME: OCITypeByName - OCI Get the most current version of an existing TYPe\n                    by name.\n    PARAMETERS:\n         env (IN/OUT) - OCI environment handle initialized in object mode\n         err (IN/OUT) - error handle. If there is an error, it is\n                  recorded in 'err' and this function returns OCI_ERROR.\n                  The error recorded in 'err' can be retrieved by calling\n                  OCIErrorGet().\n         svc (IN) - OCI service handle\n         schema_name (IN, optional) - name of schema associated with the\n                    type.  By default, the user's schema name is used.\n         s_length (IN) - length of the 'schema_name' parameter\n         type_name (IN) - name of the type to get\n         t_length (IN) - length of the 'type_name' parameter\n         version_name (IN, optional) - user readable version of the type.\n                    Pass (oratext *)0 for the most current version.\n         v_length (IN) - length of version_name in bytes. Should be 0 if\n                    the most current version is to be retrieved.\n         pin_duration (IN) - pin duration (e.g. until the end of current\n                    transaction).  See 'oro.h' for a description of\n                    each option.\n         get_option (IN) - options for loading the types. It can be one of two\n                     values:\n                    OCI_TYPEGET_HEADER for only the header to be loaded, or\n                    OCI_TYPEGET_ALL for the TDO and all ADO and MDOs to be\n                      loaded.\n         tdo (OUT) - pointer to the pinned type in the object cache\n    DESCRIPTION:\n         Get a pointer to a version of the existing type associated\n         with schema/type name.\n    RETURNS:\n          OCI_SUCCESS if the function completes successfully.\n          OCI_INVALID_HANDLE if 'env' or 'err' is null.\n          OCI_ERROR if\n             1) any of the required parameters is null.\n             2) the adt type associated with schema/type name does not exist.\n    NOTE:\n         Schema and type names are CASE-SENSITIVE. If they have been created\n         via SQL, you need to use uppercase names.\n   }\n  TOCITypeArrayByName = function(env: POCIEnv; err: POCIError; svc: POCISvcCtx;\n    array_len: ub4; schema_name:  PPoratext; s_length: Pub4;\n    type_name: PPoratext; t_length: Pub4; version_name: PPoratext;\n    v_length: Pub4; pin_duration: OCIDuration; get_option: OCITypeGetOpt;\n    tdo: PPOCIType): sword; cdecl;\n\n  {\n    NAME: OCITypeArrayByName - OCI Get array of TYPes by name.\n    PARAMETERS:\n         env (IN/OUT) - OCI environment handle initialized in object mode\n         err (IN/OUT) - error handle. If there is an error, it is\n                  recorded in 'err' and this function returns OCI_ERROR.\n                  The error recorded in 'err' can be retrieved by calling\n                  OCIErrorGet().\n         svc (IN) - OCI service handle\n         array_len (IN) - number of schema_name/type_name/version_name entries to\n                    be retrieved.\n         schema_name (IN, optional) - array of schema names associated with the\n                    types to be retrieved.  The array must have array_len\n                    elements if specified.\n                    If 0 is supplied, the default schema is assumed, otherwise\n                    it MUST have array_len number of elements.\n                    0 can be supplied for one or more of the entries to indicate\n                    that the default schema is desired for those entries.\n         s_length (IN) - array of schema_name lengths with each entry\n                    corresponding to the length of the corresponding schema_name\n                    entry in the schema_name array in bytes.\n                    The array must either have array_len number of elements or\n                    it MUST be 0 if schema_name is not specified.\n         type_name (IN) - array of the names of the types to retrieve. This\n                    MUST have array_len number of elements.\n         t_length (IN) - array of the lengths of type names in the type_name\n                    array in bytes.\n         version_name (IN) - array of the version names of the types to retrieve\n                    corresponding. This can be 0 to indicate retrieval of the\n                    most current versions, or it MUST have array_len number of\n                    elements.\n                    If 0 is supplied, the most current version is assumed,\n                    otherwise it MUST have array_len number of elements.\n                    0 can be supplied for one or more of the entries to indicate\n                    that the current version is desired for those entries.\n         v_length (IN) - array of the lengths of version names in the\n                    version_name array in bytes.\n         pin_duration (IN) - pin duration (e.g. until the end of current\n                    transaction) for the types retreieve.  See 'oro.h' for a\n                    description of each option.\n         get_option (IN) - options for loading the types. It can be one of two\n                     values:\n                    OCI_TYPEGET_HEADER for only the header to be loaded, or\n                    OCI_TYPEGET_ALL for the TDO and all ADO and MDOs to be\n                      loaded.\n         tdo (OUT) - output array for the pointers to each pinned type in the\n                    object cache. It must have space for array_len pointers.\n                    Use OCIObjectGetObjectRef() to obtain the CREF to each\n                    pinned type descriptor.\n    DESCRIPTION:\n         Get pointers to the existing types associated with the schema/type name\n         array. This is similar to OCITypeByName() except that all the TDO's are\n         retreived via a single network roundtrip.\n    RETURNS:\n          OCI_SUCCESS if the function completes successfully.\n          OCI_INVALID_HANDLE if 'env' or 'err' is null.\n          OCI_ERROR if\n             1) any of the required parameters is null.\n             2) one or more adt types associated with a schema/type name entry\n                does not exist.\n   }\n  TOCITypeByRef = function(env: POCIEnv; err: POCIError; type_ref: POCIRef;\n    pin_duration: OCIDuration; get_option: OCITypeGetOpt;\n    tdo: PPOCIType): sword; cdecl;\n\n  {\n    NAME: OCITypeArrayByRef - OCI Get array of TYPes by REF.\n    PARAMETERS:\n         env (IN/OUT) - OCI environment handle initialized in object mode\n         err (IN/OUT) - error handle. If there is an error, it is\n                  recorded in 'err' and this function returns OCI_ERROR.\n                  The error recorded in 'err' can be retrieved by calling\n                  OCIErrorGet().\n         type_ref (IN) - OCIRef * pointing to the particular version of\n                    the type descriptor object to obtain.\n                    The array must have array_len elements if specified.\n         pin_duration (IN) - pin duration (e.g. until the end of current\n                    transaction) for the type to retreieve.  See 'oro.h' for a\n                    description of each option.\n         get_option (IN) - options for loading the type. It can be one of two\n                     values:\n                    OCI_TYPEGET_HEADER for only the header to be loaded, or\n                    OCI_TYPEGET_ALL for the TDO and all ADO and MDOs to be\n                      loaded.\n         tdo (OUT) - pointer to the pinned type in the object cache\n    DESCRIPTION:\n         Get pointers to the\n         with the schema/type name array. This is similar to OCITypeByName()\n         except that all the TDO's are retreived via a single network roundtrip.\n    RETURNS:\n          OCI_SUCCESS if the function completes successfully.\n          OCI_INVALID_HANDLE if 'env' or 'err' is null.\n          OCI_ERROR if\n             1) any of the required parameters is null.\n             2) one or more adt types associated with a schema/type name entry\n                does not exist.\n   }\n  TOCITypeArrayByRef = function(env: POCIEnv; err: POCIError; array_len: ub4;\n    type_ref: PPOCIRef; pin_duration: OCIDuration; get_option: OCITypeGetOpt;\n    tdo: PPOCIType): sword; cdecl;\n\n  {\n    NAME: OCITypeArrayByRef - OCI Get array of TYPes by REF.\n    PARAMETERS:\n         env (IN/OUT) - OCI environment handle initialized in object mode\n         err (IN/OUT) - error handle. If there is an error, it is\n                  recorded in 'err' and this function returns OCI_ERROR.\n                  The error recorded in 'err' can be retrieved by calling\n                  OCIErrorGet().\n         array_len (IN) - number of schema_name/type_name/version_name entries to\n                    be retrieved.\n         type_ref (IN) - array of OCIRef * pointing to the particular version of\n                    the type descriptor object to obtain.\n                    The array must have array_len elements if specified.\n         pin_duration (IN) - pin duration (e.g. until the end of current\n                    transaction) for the types retreieve.  See 'oro.h' for a\n                    description of each option.\n         get_option (IN) - options for loading the types. It can be one of two\n                     values:\n                    OCI_TYPEGET_HEADER for only the header to be loaded, or\n                    OCI_TYPEGET_ALL for the TDO and all ADO and MDOs to be\n                      loaded.\n         tdo (OUT) - output array for the pointers to each pinned type in the\n                    object cache. It must have space for array_len pointers.\n                    Use OCIObjectGetObjectRef() to obtain the CREF to each\n                    pinned type descriptor.\n    DESCRIPTION:\n         Get pointers to the\n         with the schema/type name array. This is similar to OCITypeByName()\n         except that all the TDO's are retreived via a single network roundtrip.\n    RETURNS:\n          OCI_SUCCESS if the function completes successfully.\n          OCI_INVALID_HANDLE if 'env' or 'err' is null.\n          OCI_ERROR if\n             1) any of the required parameters is null.\n             2) one or more adt types associated with a schema/type name entry\n                does not exist.\n   }\n  {-------------------------------------------------------------------------- }\n  {                              TYPE ACCESSORS                               }\n  {-------------------------------------------------------------------------- }\n  {---------------------------- OCITypeName --------------------------------- }\n  { ** OBSOLETE **  }\n  TOCITypeName = function(env: POCIEnv; err: POCIError; tdo: POCIType;\n    n_length: Pub4): poratext; cdecl;\n\n  {\n     NAME: OCITypeName -  ORT Get a Type's naME.\n     PARAMETERS:\n          env (IN/OUT) - OCI environment handle initialized in object mode\n          err (IN/OUT) - error handle. If there is an error, it is\n                  recorded in 'err' and this function returns OCI_ERROR.\n                  The error recorded in 'err' can be retrieved by calling\n                  OCIErrorGet().\n          tdo (IN) - pointer to to the type descriptor in the object cache\n          n_length (OUT) - length (in bytes) of the returned type name.  The\n                 caller must allocate space for the ub4 before calling this\n                 routine.\n     REQUIRES:\n          1) All type accessors require that the type be pinned before calling\n             any accessor.\n          2) All input parameters must not be NULL and must be valid.\n          3) 'n_length' must point to an allocated ub4.\n     DESCRIPTION:\n          Get the name of the type.\n     RETURNS:\n          the name of the type\n     NOTES:\n          The type descriptor, 'tdo', must be unpinned when the accessed\n          information is no longer needed.\n    }\n  {------------------------ OCITypeSchema --------------------------------- }\n  { ** OBSOLETE **  }\n  TOCITypeSchema = function(env: POCIEnv; err: POCIError; const tdo: POCIType;\n    n_length: Pub4): poratext; cdecl;\n\n  {\n     NAME: OCITypeSchema -  ORT Get a Type's SCHema name.\n     PARAMETERS:\n          env (IN/OUT) - OCI environment handle initialized in object mode\n          err (IN/OUT) - error handle. If there is an error, it is\n                  recorded in 'err' and this function returns OCI_ERROR.\n                  The error recorded in 'err' can be retrieved by calling\n                  OCIErrorGet().\n          tdo (IN) - pointer to to the type descriptor in the object cache\n          n_length (OUT) - length (in bytes) of the returned schema name.  The\n                 caller must allocate space for the ub4 before calling this\n                 routine.\n     REQUIRES:\n          1) All type accessors require that the type be pinned before calling\n             any accessor.\n          2) All input parameters must not be NULL and must be valid.\n          3) 'n_length' must point to an allocated ub4.\n     DESCRIPTION:\n          Get the schema name of the type.\n     RETURNS:\n          the schema name of the type\n     NOTES:\n          The type descriptor, 'tdo', must be unpinned when the accessed\n          information is no longer needed.\n    }\n  {------------------------ OCITypeTypeCode --------------------------------- }\n  { ** OBSOLETE **  }\n  TOCITypeTypeCode = function(env: POCIEnv; err: POCIError;\n    const tdo: POCIType): OCITypeCode; cdecl;\n\n  {\n     NAME: OCITypeTypeCode - OCI Get a Type's Type Code.\n     PARAMETERS:\n          env (IN/OUT) - OCI environment handle initialized in object mode\n          err (IN/OUT) - error handle. If there is an error, it is\n                  recorded in 'err' and this function returns OCI_ERROR.\n                  The error recorded in 'err' can be retrieved by calling\n                  OCIErrorGet().\n          tdo (IN) - pointer to to the type descriptor in the object cache\n     REQUIRES:\n          1) All type accessors require that the type be pinned before calling\n             any accessor.\n          2) All input parameters must not be NULL and must be valid.\n     DESCRIPTION:\n          Get the type code of the type.\n     RETURNS:\n          The type code of the type.\n     NOTES:\n          The type descriptor, 'tdo', must be unpinned when the accessed\n          information is no longer needed.\n    }\n  {----------------------- OCITypeCollTypeCode ------------------------------- }\n  { ** OBSOLETE **  }\n  TOCITypeCollTypeCode = function(env:POCIEnv; err:POCIError;\n    const tdo: POCIType): OCITypeCode; cdecl;\n\n  {\n     NAME: OCITypeCollTypeCode - OCI Get a Domain Type's Type Code.\n     PARAMETERS:\n          env (IN/OUT) - OCI environment handle initialized in object mode\n          err (IN/OUT) - error handle. If there is an error, it is\n                  recorded in 'err' and this function returns OCI_ERROR.\n                  The error recorded in 'err' can be retrieved by calling\n                  OCIErrorGet().\n          tdo (IN) - pointer to to the type descriptor in the object cache\n     REQUIRES:\n          1) All type accessors require that the type be pinned before calling\n             any accessor.\n          2) All input parameters must not be NULL and must be valid.\n          3) 'tdo' MUST point to a named collection type.\n     DESCRIPTION:\n          Get the type code of the named collection type. For V8.0, named\n          collection types can only be variable length arrays and nested tables.\n     RETURNS:\n          OCI_TYPECODE_VARRAY for variable length array, and\n          OCI_TYPECODE_TABLE for nested tables.\n     NOTES:\n          The type descriptor, 'tdo', should be unpinned when the accessed\n          information is no longer needed.\n    }\n  {------------------------- OCITypeVersion --------------------------------- }\n  { ** OBSOLETE **  }\n(* Const before type ignored *)\n  TOCITypeVersion = function(env: POCIEnv; err: POCIError; const tdo: POCIType;\n    v_length: Pub4): poratext; cdecl;\n\n  {\n     NAME: OCITypeVersion - OCI Get a Type's user-readable VersioN.\n     PARAMETERS:\n          env (IN/OUT) - OCI environment handle initialized in object mode\n          err (IN/OUT) - error handle. If there is an error, it is\n                  recorded in 'err' and this function returns OCI_ERROR.\n                  The error recorded in 'err' can be retrieved by calling\n                  OCIErrorGet().\n          tdo (IN) - pointer to to the type descriptor in the object cache\n          v_length (OUT) - length (in bytes) of the returned user-readable\n                 version.  The caller must allocate space for the ub4 before\n                 calling this routine.\n     REQUIRES:\n          1) All type accessors require that the type be pinned before calling\n             any accessor.\n          2) All input parameters must not be NULL and must be valid.\n          3) 'v_length' must point to an allocated ub4.\n     DESCRIPTION:\n          Get the user-readable version of the type.\n     RETURNS:\n          The user-readable version of the type\n     NOTES:\n          The type descriptor, 'tdo', must be unpinned when the accessed\n          information is no longer needed.\n    }\n  {--------------------------- OCITypeAttrs --------------------------------- }\n  { ** OBSOLETE **  }\n  TOCITypeAttrs = function(env: POCIEnv; err: POCIError;\n    const tdo:POCIType): ub4; cdecl;\n\n  {\n     NAME: OCITypeAttrs - OCI Get a Type's Number of Attributes.\n     PARAMETERS:\n          env (IN/OUT) - OCI environment handle initialized in object mode\n          err (IN/OUT) - error handle. If there is an error, it is\n                  recorded in 'err' and this function returns OCI_ERROR.\n                  The error recorded in 'err' can be retrieved by calling\n                  OCIErrorGet().\n          tdo (IN) - pointer to to the type descriptor in the object cache\n     REQUIRES:\n          1) All type accessors require that the type be pinned before calling\n             any accessor.\n          2) All input parameters must not be NULL and must be valid.\n     DESCRIPTION:\n          Get the number of attributes in the type.\n     RETURNS:\n          The number of attributes in the type. 0 for ALL non-ADTs.\n     NOTES:\n          The type descriptor, 'tdo', must be unpinned when the accessed\n          information is no longer needed.\n    }\n  {------------------------- OCITypeMethods --------------------------------- }\n  { ** OBSOLETE **  }\n  TOCITypeMethods = function(env: POCIEnv; err: POCIError;\n    const tdo: POCIType): ub4; cdecl;\n\n  {\n     NAME: OCITypeMethods - OCI Get a Type's Number of Methods.\n     PARAMETERS:\n          env (IN/OUT) - OCI environment handle initialized in object mode\n          err (IN/OUT) - error handle. If there is an error, it is\n                  recorded in 'err' and this function returns OCI_ERROR.\n                  The error recorded in 'err' can be retrieved by calling\n                  OCIErrorGet().\n          tdo (IN) - pointer to to the type descriptor in the object cache\n     REQUIRES:\n          1) All type accessors require that the type be pinned before calling\n             any accessor.\n          2) All input parameters must not be NULL and must be valid.\n     DESCRIPTION:\n          Get the number of methods in a type.\n     RETURNS:\n          The number of methods in the type\n     NOTES:\n          The type descriptor, 'tdo', must be unpinned when the accessed\n          information is no longer needed.\n    }\n  {-------------------------------------------------------------------------- }\n  {                     TYPE ELEMENT INFORMATION ACCESSORS                    }\n  {-------------------------------------------------------------------------- }\n  {------------------------ OCITypeElemName --------------------------------- }\n  { ** OBSOLETE **  }\n  TOCITypeElemName = function(env: POCIEnv; err: POCIError;\n    const elem: POCITypeElem; n_length:Pub4): poratext; cdecl;\n\n  {\n     NAME: OCITypeElemName - OCI Get an Attribute's NaMe.\n     PARAMETERS:\n          env (IN/OUT) - OCI environment handle initialized in object mode\n          err (IN/OUT) - error handle. If there is an error, it is\n                  recorded in 'err' and this function returns OCI_ERROR.\n                  The error recorded in 'err' can be retrieved by calling\n                  OCIErrorGet().\n          elem (IN) - pointer to the type element descriptor in the object cache\n          n_length (OUT) - length (in bytes) of the returned attribute name.\n                 The caller must allocate space for the ub4 before calling this\n                 routine.\n     REQUIRES:\n          1) All type accessors require that the type be pinned before calling\n             any accessor.\n          2) All input parameters must not be NULL and must be valid.\n          3) 'n_length' must point to an allocated ub4.\n     DESCRIPTION:\n          Get the name of the attribute.\n     RETURNS:\n          the name of the attribute and the length in n_length\n     NOTES:\n          The type must be unpinned when the accessed information is no\n          longer needed.\n    }\n  {------------------------ OCITypeElemTypeCode ------------------------------ }\n  { ** OBSOLETE **  }\n  TOCITypeElemTypeCode = function(env: POCIEnv; err: POCIError;\n    const elem: POCITypeElem): OCITypeCode; cdecl;\n\n  {\n     NAME: OCITypeElemTypeCode - OCI Get an Attribute's TypeCode.\n     PARAMETERS:\n          env (IN/OUT) - OCI environment handle initialized in object mode\n          err (IN/OUT) - error handle. If there is an error, it is\n                  recorded in 'err' and this function returns OCI_ERROR.\n                  The error recorded in 'err' can be retrieved by calling\n                  OCIErrorGet().\n          elem (IN) - pointer to the type element descriptor in the object cache\n     REQUIRES:\n          1) All type accessors require that the type be pinned before calling\n             any accessor.\n          2) All input parameters must not be NULL and must be valid.\n     DESCRIPTION:\n          Get the typecode of an attribute's type.\n     RETURNS:\n          the typecode of the attribute's type.  If this is a scalar type, the\n          typecode sufficiently describes the scalar type and no further calls\n          need to be made.  Valid scalar types include: OCI_TYPECODE_SIGNED8,\n          OCI_TYPECODE_UNSIGNED8, OCI_TYPECODE_SIGNED16, OCI_TYPECODE_UNSIGNED16,\n          OCI_TYPECODE_SIGNED32, OCI_TYPECODE_UNSIGNED32, OCI_TYPECODE_REAL,\n          OCI_TYPECODE_DOUBLE, OCI_TYPECODE_DATE,\n          OCI_TYPECODE_MLSLABEL, OROTCOID, OCI_TYPECODE_OCTET, or OROTCLOB.\n          This function converts the CREF (stored in the attribute) into a\n          typecode.\n     NOTES:\n         The type must be unpinned when the accessed information is no\n         longer needed.\n    }\n  {------------------------ OCITypeElemType --------------------------------- }\n  { ** OBSOLETE **  }\n  TOCITypeElemType = function(env: POCIEnv; err: POCIError;\n    const elem: POCITypeElem; elem_tdo:PPOCIType): sword; cdecl;\n\n  {\n    PARAMETERS\n       env (IN/OUT) - OCI environment handle initialized in object mode\n       err (IN/OUT) - error handle. If there is an error, it is\n               recorded in 'err' and this function returns OCI_ERROR.\n               The error recorded in 'err' can be retrieved by calling\n               OCIErrorGet().\n       elem (IN) - pointer to the type element descriptor in the object cache\n       elem_tdo (OUT) - If the function completes successfully, 'elem_tdo'\n              points to the type descriptor (in the object cache) of the type of\n              the element.\n\n    REQUIRES\n       1) All type accessors require that the type be pinned before calling\n          any accessor.  This can be done by calling 'OCITypeByName()'.\n       2) if 'elem' is not null, it must point to a valid type element descriptor\n          in the object cache.\n\n    DESCRIPTION\n       Get the type tdo of the type of this element.\n    RETURNS\n       OCI_SUCCESS if the function completes successfully.\n       OCI_INVALID_HANDLE if 'env' or 'err' is null.\n       OCI_ERROR if\n           1) any of the parameters is null.\n\n    NOTES\n       The type must be unpinned when the accessed information is no\n       longer needed.  This can be done by calling 'OCIObjectUnpin()'.\n    }\n  {------------------------- OCITypeElemFlags ------------------------------- }\n  { ** OBSOLETE **  }\n  TOCITypeElemFlags = function(env: POCIEnv; err: POCIError;\n    const elem: POCITypeElem): ub4; cdecl;\n\n  {\n     NAME: OCITypeElemFlags - OCI Get a Elem's FLags\n                                (inline, constant, virtual, constructor,\n                                destructor).\n     PARAMETERS:\n          env (IN/OUT) - OCI environment handle initialized in object mode\n          err (IN/OUT) - error handle. If there is an error, it is\n                  recorded in 'err' and this function returns OCI_ERROR.\n                  The error recorded in 'err' can be retrieved by calling\n                  OCIErrorGet().\n          elem (IN) - pointer to the type element descriptor in the object cache\n     REQUIRES:\n          1) All type accessors require that the type be pinned before calling\n             any accessor.\n          2) All input parameters must not be NULL and must be valid.\n     DESCRIPTION:\n          Get the flags of a type element (attribute, parameter).\n     RETURNS:\n          The flags of the type element.\n     NOTES:\n          The flag bits are not externally documented. Use only the macros\n          in the last section (ie. OCI_TYPEPARAM_IS_REQUIRED, and\n          OCI_TYPEELEM_IS_REF) to test for them only. The type must be unpinned\n          when the accessed information is no longer needed.\n    }\n  {------------------------ OCITypeElemNumPrec ------------------------------ }\n  { ** OBSOLETE **  }\n  TOCITypeElemNumPrec = function(env: POCIEnv; err: POCIError;\n    const elem: POCITypeElem): ub1; cdecl;\n\n  {\n     NAME: OCITypeElemNumPrec - Get a Number's Precision.  This includes float,\n                                decimal, real, double, and oracle number.\n     PARAMETERS:\n          env (IN/OUT) - OCI environment handle initialized in object mode\n          err (IN/OUT) - error handle. If there is an error, it is\n                  recorded in 'err' and this function returns OCI_ERROR.\n                  The error recorded in 'err' can be retrieved by calling\n                  OCIErrorGet().\n          elem (IN) - pointer to the type element descriptor in the object cache\n     REQUIRES:\n          All input parameters must not be NULL and must be valid.\n     DESCRIPTION:\n          Get the precision of a float, decimal, long, unsigned long, real,\n          double, or Oracle number type.\n     RETURNS:\n          the precision of the float, decimal, long, unsigned long, real, double,\n          or Oracle number\n    }\n  {------------------------- OCITypeElemNumScale ----------------------------- }\n  { ** OBSOLETE **  }\n  TOCITypeElemNumScale = function(env: POCIEnv; err: POCIError;\n    const elem: POCITypeElem): sb1; cdecl;\n\n  {\n     NAME: OCITypeElemNumScale - Get a decimal or oracle Number's Scale\n     PARAMETERS:\n          env (IN/OUT) - OCI environment handle initialized in object mode\n          err (IN/OUT) - error handle. If there is an error, it is\n                  recorded in 'err' and this function returns OCI_ERROR.\n                  The error recorded in 'err' can be retrieved by calling\n                  OCIErrorGet().\n          elem (IN) - pointer to the type element descriptor in the object cache\n     REQUIRES:\n          All input parameters must not be NULL and must be valid.\n     DESCRIPTION:\n          Get the scale of a decimal, or Oracle number type.\n     RETURNS:\n          the scale of the decimal, or Oracle number\n    }\n  {------------------------ OCITypeElemLength ------------------------------- }\n  { ** OBSOLETE **  }\n  TOCITypeElemLength = function(env: POCIEnv; err: POCIError;\n    const elem:POCITypeElem): ub4; cdecl;\n\n  {\n     NAME: OCITypeElemLength - Get a raw, fixed or variable length String's\n                               length in bytes.\n     PARAMETERS:\n          env (IN/OUT) - OCI environment handle initialized in object mode\n          err (IN/OUT) - error handle. If there is an error, it is\n                  recorded in 'err' and this function returns OCI_ERROR.\n                  The error recorded in 'err' can be retrieved by calling\n                  OCIErrorGet().\n          elem (IN) - pointer to the type element descriptor in the object cache\n     REQUIRES:\n          All input parameters must not be NULL and must be valid.\n     DESCRIPTION:\n          Get the length of a raw, fixed or variable length string type.\n     RETURNS:\n          length of the raw, fixed or variable length string\n    }\n  {----------------------- OCITypeElemCharSetID ----------------------------- }\n  { ** OBSOLETE **  }\n  TOCITypeElemCharSetID = function(env: POCIEnv; err: POCIError;\n    const elem: POCITypeElem): ub2; cdecl;\n\n  {\n     NAME: OCITypeElemCharSetID - Get a fixed or variable length String's\n                                  character set ID\n     PARAMETERS:\n          env (IN/OUT) - OCI environment handle initialized in object mode\n          err (IN/OUT) - error handle. If there is an error, it is\n                  recorded in 'err' and this function returns OCI_ERROR.\n                  The error recorded in 'err' can be retrieved by calling\n                  OCIErrorGet().\n          elem (IN) - pointer to the type element descriptor in the object cache\n     REQUIRES:\n          All input parameters must not be NULL and must be valid.\n     DESCRIPTION:\n          Get the character set ID of a fixed or variable length string type.\n     RETURNS:\n          character set ID of the fixed or variable length string\n    }\n  {---------------------- OCITypeElemCharSetForm ---------------------------- }\n  { ** OBSOLETE **  }\n  TOCITypeElemCharSetForm = function(env: POCIEnv; err: POCIError;\n    const elem: POCITypeElem): ub2; cdecl;\n\n  {\n     NAME: OCITypeElemCharSetForm - Get a fixed or variable length String's\n                                    character set specification form.\n     PARAMETERS:\n          env (IN/OUT) - OCI environment handle initialized in object mode\n          err (IN/OUT) - error handle. If there is an error, it is\n                  recorded in 'err' and this function returns OCI_ERROR.\n                  The error recorded in 'err' can be retrieved by calling\n                  OCIErrorGet().\n          elem (IN) - pointer to the attribute information in the object cache\n     REQUIRES:\n          All input parameters must not be NULL and must be valid.\n     DESCRIPTION:\n          Get the character form of a fixed or variable length string type.\n          The character form is an enumerated value that can be one of the\n          4 values below:\n                 SQLCS_IMPLICIT for CHAR, VARCHAR2, CLOB w/o a specified set\n                 SQLCS_NCHAR    for NCHAR, NCHAR VARYING, NCLOB\n                 SQLCS_EXPLICIT for CHAR, etc, with \"CHARACTER SET ...\" syntax\n                 SQLCS_FLEXIBLE for PL/SQL \"flexible\" parameters\n     RETURNS:\n          character form of the fixed or variable string\n    }\n  {--------------------- OCITypeElemParameterizedType ------------------------ }\n  { ** OBSOLETE **  }\n  TOCITypeElemParameterizedType = function(env: POCIEnv; err: POCIError;\n    const elem: POCITypeElem; type_stored: PPOCIType): sword; cdecl;\n\n  {\n     NAME: OCITypeElemParameterizedType\n     PARAMETERS:\n          env (IN/OUT) - OCI environment handle initialized in object mode\n          err (IN/OUT) - error handle. If there is an error, it is\n                  recorded in 'err' and this function returns OCI_ERROR.\n                  The error recorded in 'err' can be retrieved by calling\n                  OCIErrorGet().\n          elem (IN) - pointer to the type element descriptor in the object cache\n          type_stored (OUT) - If the function completes successfully,\n                 and the parameterized type is complex, 'type_stored' is NULL.\n                 Otherwise, 'type_stored' points to the type descriptor (in the\n                 object cache) of the type that is stored in the parameterized\n                 type.  The caller must allocate space for the OCIType*\n                 before calling this routine and must not write into the space.\n     REQUIRES:\n          All input parameters must be valid.\n     DESCRIPTION:\n          Get a descriptor to the parameter type of a parameterized type.\n          Parameterized types are types of the form:\n            REF T\n            VARRAY (n) OF T\n          etc, where T is the parameter in the parameterized type.\n          Additionally is_ref is set if the parameter is a PTR or REF.\n          For example, it is set for REF T or VARRAY(n) OF REF T.\n     RETURNS:\n          OCI_SUCCESS if the function completes successfully.\n          OCI_INVALID_HANDLE if 'env' or 'err' is null.\n          OCI_ERROR if\n              1) any of the parameters is null.\n              2) 'type_stored' is not NULL but points to NULL data.\n     NOTES:\n          Complex parameterized types will be in a future release (once\n          typedefs are supported.  When setting the parameterized type\n          information, the user must typedef the contents if it's a\n          complex parameterized type.  Ex. for varray<varray<car>>, use\n          'typedef varray<car> varcar' and then use varray<varcar>.\n    }\n  {----------------------- OCITypeElemExtTypeCode ---------------------------- }\n  { ** OBSOLETE **  }\n  TOCITypeElemExtTypeCode = function(env: POCIEnv; err: POCIError;\n    const elem: POCITypeElem): OCITypeCode; cdecl;\n\n  {\n     NAME: OCITypeElemExtTypeCode - OCI Get an element's SQLT constant.\n     PARAMETERS:\n          env (IN/OUT) - OCI environment handle initialized in object mode\n          err (IN/OUT) - error handle. If there is an error, it is\n                  recorded in 'err' and this function returns OCI_ERROR.\n                  The error recorded in 'err' can be retrieved by calling\n                  OCIErrorGet().\n          elem (IN) - pointer to the type element descriptor in the object cache\n     REQUIRES:\n          1) All type accessors require that the type be pinned before calling\n             any accessor.\n          2) All input parameters must not be NULL and must be valid.\n     DESCRIPTION:\n          Get the internal Oracle typecode associated with an attribute's type.\n          This is the actual typecode for the attribute when it gets mapped\n          to a column in the Oracle database.\n     RETURNS:\n          The Oracle typecode associated with the attribute's type.\n     NOTES:\n          The type must be unpinned when the accessed information is no\n          longer needed.\n    }\n  {-------------------------------------------------------------------------- }\n  {                           ATTRIBUTE ACCESSORS                             }\n  {-------------------------------------------------------------------------- }\n  {------------------------ OCITypeAttrByName ------------------------------- }\n  { ** OBSOLETE **  }\n  TOCITypeAttrByName = function(env: POCIEnv; err: POCIError;\n    const tdo: POCIType; const name: Poratext; const n_length: ub4;\n    elem: PPOCITypeElem): sword; cdecl;\n\n  {\n     NAME: OCITypeAttrByName - OCI Get an Attribute By Name.\n     PARAMETERS:\n          env (IN/OUT) - OCI environment handle initialized in object mode\n          err (IN/OUT) - error handle. If there is an error, it is\n                  recorded in 'err' and this function returns OCI_ERROR.\n                  The error recorded in 'err' can be retrieved by calling\n                  OCIErrorGet().\n          tdo (IN) - pointer to to the type descriptor in the object cache\n          name (IN) - the attribute's name\n          n_length (IN) - length (in bytes) of the 'name' parameter\n          elem (OUT) - If this function completes successfully, 'elem' points to\n                 the selected type element descriptor pertaining to the\n                 attributein the object cache.\n     REQUIRES:\n          1) All type accessors require that the type be pinned before calling\n             any accessor.\n          2) if 'tdo' is not null, it must point to a valid type descriptor\n             in the object cache.\n     DESCRIPTION:\n          Get an attribute given its name.\n     RETURNS:\n          OCI_SUCCESS if the function completes successfully.\n          OCI_INVALID_HANDLE if 'env' or 'err' is null.\n          OCI_ERROR if\n              1) any of the required parameters is null.\n              2) the type does not contain an attribute with the input 'name'.\n              3) 'name' is NULL.\n     NOTES:\n          The type descriptor, 'tdo', must be unpinned when the accessed\n          information is no longer needed.\n          Schema and type names are CASE-SENSITIVE. If they have been created\n          via SQL, you need to use uppercase names.\n    }\n  {------------------------ OCITypeAttrNext --------------------------------- }\n  { ** OBSOLETE **  }\n  TOCITypeAttrNext = function(env: POCIEnv; err: POCIError;\n    iterator_ort: POCITypeIter; elem: PPOCITypeElem): sword; cdecl;\n\n  {\n     NAME: OCITypeAttrNext - OCI Get an Attribute By Iteration.\n     PARAMETERS:\n          env (IN/OUT) - OCI environment handle initialized in object mode\n          err (IN/OUT) - error handle. If there is an error, it is\n                  recorded in 'err' and this function returns OCI_ERROR.\n                  The error recorded in 'err' can be retrieved by calling\n                  OCIErrorGet().\n          iterator_ort (IN/OUT) - iterator for retrieving the next attribute;\n                 see OCITypeIterNew() to initialize iterator.\n          elem (OUT) - If this function completes successfully, 'elem' points to\n                 the selected type element descriptor pertaining to the\n                 attributein the object cache.\n     REQUIRES:\n          1) All type accessors require that the type be pinned before calling\n              any accessor.\n          2) if 'tdo' is not null, it must point to a valid type descriptor\n             in the object cache.\n     DESCRIPTION:\n          Iterate to the next attribute to retrieve.\n     RETURNS:\n          OCI_SUCCESS if the function completes successfully.\n          OCI_NO_DATA if there are no more attributes to iterate on; use\n              OCITypeIterSet() to reset the iterator if necessary.\n          OCI_INVALID_HANDLE if 'env' or 'err' is null.\n          OCI_ERROR if\n              1) any of the required parameters is null.\n     NOTES:\n          The type must be unpinned when the accessed information is no\n          longer needed.\n    }\n  {-------------------------------------------------------------------------- }\n  {                           COLLECTION ACCESSORS                            }\n  {-------------------------------------------------------------------------- }\n  {------------------------ OCITypeCollElem --------------------------------- }\n  { ** OBSOLETE **  }\n  TOCITypeCollElem = function(env: POCIEnv; err: POCIError; const tdo:POCIType;\n    element: PPOCITypeElem): sword; cdecl;\n\n  {\n     NAME: OCITypeCollElem\n     PARAMETERS:\n          env (IN/OUT) - OCI environment handle initialized in object mode\n          err (IN/OUT) - error handle. If there is an error, it is\n                  recorded in 'err' and this function returns OCI_ERROR.\n                  The error recorded in 'err' can be retrieved by calling\n                  OCIErrorGet().\n          tdo (IN) - pointer to the type descriptor in the object cache\n          element (IN/OUT) - If the function completes successfully, this\n                 points to the descriptor for the collection's element.\n                 It is stored in the same format as an ADT attribute's\n                 descriptor.\n                 If *element is NULL, OCITypeCollElem() implicitly allocates a\n                 new instance of OCITypeElem in the object cache. This instance\n                 will be\n                 automatically freed at the end of the session, and does not have\n                 to be freed explicitly.\n                 If *element is not NULL, OCITypeCollElem() assumes that it\n                 points to a valid OCITypeElem descriptor and will copy the\n                 results into it.\n     REQUIRES:\n          All input parameters must be valid.\n     DESCRIPTION:\n          Get a pointer to the descriptor (OCITypeElem) of the element of an\n          array or the rowtype of a nested table.\n     RETURNS:\n          OCI_SUCCESS if the function completes successfully.\n          OCI_INVALID_HANDLE if 'env' or 'err' is null.\n          OCI_ERROR if\n              1) any of the parameters is null.\n              2) the type TDO does not point to a valid collection's type.\n     NOTES:\n          Complex parameterized types will be in a future release (once\n          typedefs are supported.  When setting the parameterized type\n          information, the user must typedef the contents if it's a\n          complex parameterized type.  Ex. for varray<varray<car>>, use\n          'typedef varray<car> varcar' and then use varray<varcar>.\n    }\n  {------------------------ OCITypeCollSize --------------------------------- }\n  { ** OBSOLETE **  }\n  TOCITypeCollSize = function(env: POCIEnv; err: POCIError; const tdo: POCIType;\n    num_elems: Pub4): sword; cdecl;\n\n  {\n     NAME: OCITypeCollSize - OCI Get a Collection's Number of Elements.\n     PARAMETERS:\n          env (IN/OUT) - OCI environment handle initialized in object mode\n          err (IN/OUT) - error handle. If there is an error, it is\n                  recorded in 'err' and this function returns OCI_ERROR.\n                  The error recorded in 'err' can be retrieved by calling\n                  OCIErrorGet().\n          tdo (IN) - pointer to the type descriptor in the object cache\n          num_elems (OUT) - number of elements in collection\n     REQUIRES:\n          All input parameters must be valid. tdo points to an array type\n          defined as a domain.\n     DESCRIPTION:\n          Get the number of elements stored in a fixed array or the maximum\n          number of elements in a variable array.\n     RETURNS:\n          OCI_SUCCESS if the function completes successfully.\n          OCI_INVALID_HANDLE if 'env' or 'err' is null.\n          OCI_ERROR if\n              1) any of the parameters is null.\n              2) 'tdo' does not point to a domain with a collection type.\n     NOTES:\n          Complex parameterized types will be in a future release (once\n          typedefs are supported.  When setting the parameterized type\n          information, the user must typedef the contents if it's a\n          complex parameterized type.  Ex. for varray<varray<car>>, use\n          'typedef varray<car> varcar' and then use varray<varcar>.\n    }\n  {------------------------ OCITypeCollExtTypeCode --------------------------- }\n  { ** OBSOLETE **  }\n  TOCITypeCollExtTypeCode = function(env: POCIEnv; err: POCIError;\n    const tdo:POCIType; sqt_code: POCITypeCode): sword; cdecl;\n\n  {\n     NAME: ortcsqt - OCI Get a Collection element's DTY constant.\n     PARAMETERS:\n          env (IN/OUT) - OCI environment handle initialized in object mode\n          err (IN/OUT) - error handle. If there is an error, it is\n                  recorded in 'err' and this function returns OCI_ERROR.\n                  The error recorded in 'err' can be retrieved by calling\n                  OCIErrorGet().\n          tdo (IN) - pointer to the type descriptor in the object cache\n          sqt_code (OUT) - SQLT code of type element.\n     REQUIRES:\n          1) All type accessors require that the type be pinned before calling\n             any accessor.\n          2) All input parameters must not be NULL and must be valid.\n     DESCRIPTION:\n          Get the SQLT constant associated with an domain's element type.\n          The SQLT codes are defined in <sqldef.h> and are needed for OCI/OOCI\n          use.\n     RETURNS:\n          OCI_SUCCESS if the function completes successfully.\n          OCI_INVALID_HANDLE if 'env' or 'err' is null.\n          OCI_ERROR if\n              1) any of the parameters is null.\n              2) 'tdo' does not point to a domain with a collection type.\n     NOTES:\n          The type must be unpinned when the accessed information is no\n          longer needed.\n    }\n  {-------------------------------------------------------------------------- }\n  {                             METHOD ACCESSORS                              }\n  {-------------------------------------------------------------------------- }\n  {------------------------- OCITypeMethodOverload -------------------------- }\n  { ** OBSOLETE **  }\n  TOCITypeMethodOverload = function(env: POCIEnv; err: POCIError;\n    const tdo: POCIType; const method_name: Poratext;\n    const m_length: ub4): ub4; cdecl;\n\n  {\n     NAME: OCITypeMethodOverload - OCI Get type's Number of Overloaded names\n                                   for the given method name.\n     PARAMETERS:\n          gp (IN/OUT) - pga environment handle.  Any errors are recorded here.\n          tdo (IN) - pointer to to the type descriptor in the object cache\n          method_name (IN) - the method's name\n          m_length (IN) - length (in bytes) of the 'method_name' parameter\n     REQUIRES:\n          1) All type accessors require that the type be pinned before calling\n             any accessor.\n          2) if 'tdo' is not null, it must point to a valid type descriptor\n             in the object cache.\n     DESCRIPTION:\n          Overloading of methods implies that more than one method may have the\n          same method name.  This routine returns the number of methods that\n          have the given method name.  If there are no methods with the input\n          method name, 'num_methods' is 0.  The caller uses this information when\n          allocating space for the array of mdo and/or position pointers before\n          calling 'OCITypeMethodByName()' or 'ortgmps()'.\n     RETURNS:\n          The number of methods with the given name. 0 if none contains the\n          name.\n     NOTES:\n          Schema and type names are CASE-SENSITIVE. If they have been created\n          via SQL, you need to use uppercase names.\n    }\n  {------------------------ OCITypeMethodByName ------------------------------ }\n  { ** OBSOLETE **  }\n  TOCITypeMethodByName = function(env: POCIEnv; err: POCIError;\n    const tdo: POCIType; const method_name: Poratext; const m_length: ub4;\n    mdos: PPOCITypeMethod): sword; cdecl;\n\n  {\n     NAME: OCITypeMethodByName - OCI Get one or more Methods with Name.\n     PARAMETERS:\n          env (IN/OUT) - OCI environment handle initialized in object mode\n          err (IN/OUT) - error handle. If there is an error, it is\n                  recorded in 'err' and this function returns OCI_ERROR.\n                  The error recorded in 'err' can be retrieved by calling\n                  OCIErrorGet().\n          tdo (IN) - pointer to to the type descriptor in the object cache\n          method_name (IN) - the methods' name\n          m_length (IN) - length (in bytes) of the 'name' parameter\n          mdos (OUT) - If this function completes successfully, 'mdos' points to\n                  the selected methods in the object cache.  The caller must\n                  allocate space for the array of OCITypeMethod pointers before\n                  calling this routine and must not write into the space.\n                  The number of OCITypeMethod pointers that will be returned can\n                  be obtained by calling 'OCITypeMethodOverload()'.\n     REQUIRES:\n          1) All type accessors require that the type be pinned before calling\n             any accessor.\n          2) if 'tdo' is not null, it must point to a valid type descriptor\n             in the object cache.\n     DESCRIPTION:\n          Get one or more methods given the name.\n     RETURNS:\n          OCI_SUCCESS if the function completes successfully.\n          OCI_INVALID_HANDLE if 'env' or 'err' is null.\n          OCI_ERROR if\n              1) any of the required parameters is null.\n              2) No methods in type has name 'name'.\n              3) 'mdos' is not NULL but points to NULL data.\n     NOTES:\n          The type must be unpinned when the accessed information is no\n          longer needed.\n          Schema and type names are CASE-SENSITIVE. If they have been created\n          via SQL, you need to use uppercase names.\n    }\n  {------------------------ OCITypeMethodNext -------------------------------- }\n  { ** OBSOLETE **  }\n  TOCITypeMethodNext = function(env: POCIEnv; err: POCIError;\n    iterator_ort: POCITypeIter; mdo: PPOCITypeMethod): sword; cdecl;\n\n  {\n     NAME: OCITypeMethodNext - OCI Get a Method By Iteration.\n     PARAMETERS:\n          env (IN/OUT) - OCI environment handle initialized in object mode\n          err (IN/OUT) - error handle. If there is an error, it is\n                  recorded in 'err' and this function returns OCI_ERROR.\n                  The error recorded in 'err' can be retrieved by calling\n                  OCIErrorGet().\n          iterator_ort (IN/OUT) - iterator for retrieving the next method;\n                 see OCITypeIterNew() to set iterator.\n          mdo (OUT) - If this function completes successfully, 'mdo' points to\n                 the selected method descriptor in the object cache.  Positions\n                 start at 1.  The caller must allocate space for the\n                 OCITypeMethod* before calling this routine and must not write\n                 nto the space.\n     REQUIRES:\n           1) All type accessors require that the type be pinned before calling\n              any accessor.\n          2) if 'tdo' is not null, it must point to a valid type descriptor\n             in the object cache.\n     DESCRIPTION:\n          Iterate to the next method to retrieve.\n     RETURNS:\n          OCI_SUCCESS if the function completes successfully.\n          OCI_NO_DATA if there are no more attributes to iterate on; use\n              OCITypeIterSet() to reset the iterator if necessary.\n          OCI_INVALID_HANDLE if 'env' or 'err' is null.\n          OCI_ERROR if\n              1) any of the required parameters is null.\n              2) 'mdo' is not NULL but points to NULL data.\n     NOTES:\n          The type must be unpinned when the accessed information is no\n          longer needed.\n    }\n  {------------------------ OCITypeMethodName -------------------------------- }\n  { ** OBSOLETE **  }\n  TOCITypeMethodName = function(env:POCIEnv; err: POCIError;\n    const mdo: POCITypeMethod; n_length: Pub4): poratext; cdecl;\n  {\n     NAME: OCITypeMethodName - OCI Get a Method's NaMe.\n     PARAMETERS:\n          env (IN/OUT) - OCI environment handle initialized in object mode\n          err (IN/OUT) - error handle. If there is an error, it is\n                  recorded in 'err' and this function returns OCI_ERROR.\n                  The error recorded in 'err' can be retrieved by calling\n                  OCIErrorGet().\n          mdo (IN) - pointer to the method descriptor in the object cache\n          n_length (OUT) - length (in bytes) of the 'name' parameter.  The caller\n                 must allocate space for the ub4 before calling this routine.\n     REQUIRES:\n          1) All type accessors require that the type be pinned before calling\n             any accessor.\n          2) All input parameters must not be NULL and must be valid.\n     DESCRIPTION:\n          Get the (non-unique) real name of the method.\n     RETURNS:\n          the non-unique name of the method or NULL if there is an error.\n     NOTES:\n          The type must be unpinned when the accessed information is no\n          longer needed.\n    }\n  {------------------------ OCITypeMethodEncap ------------------------------- }\n  { ** OBSOLETE **  }\n  TOCITypeMethodEncap = function(env: POCIEnv; err: POCIError;\n          const mdo: POCITypeMethod): OCITypeEncap; cdecl;\n\n  {\n     NAME: OCITypeMethodEncap - Get a Method's ENcapsulation (private/public).\n     PARAMETERS:\n          env (IN/OUT) - OCI environment handle initialized in object mode\n          err (IN/OUT) - error handle. If there is an error, it is\n                  recorded in 'err' and this function returns OCI_ERROR.\n                  The error recorded in 'err' can be retrieved by calling\n                  OCIErrorGet().\n          mdo (IN) - pointer to the method descriptor in the object cache\n     REQUIRES:\n          1) All type accessors require that the type be pinned before calling\n             any accessor.\n          2) All input parameters must not be NULL and must be valid.\n     DESCRIPTION:\n          Get the encapsulation (private, or public) of a method.\n     RETURNS:\n          the encapsulation (private, or public) of the method\n     NOTES:\n          The type must be unpinned when the accessed information is no\n          longer needed.\n    }\n  {------------------------ OCITypeMethodFlags ------------------------------- }\n  { ** OBSOLETE **  }\n  TOCITypeMethodFlags = function(env: POCIEnv; err: POCIError;\n      const mdo:POCITypeMethod): OCITypeMethodFlag; cdecl;\n\n  {\n     NAME: OCITypeMethodFlags - OCI Get a Method's FLags\n                                (inline, constant, virtual, constructor,\n                                destructor).\n     PARAMETERS:\n          env (IN/OUT) - OCI environment handle initialized in object mode\n          err (IN/OUT) - error handle. If there is an error, it is\n                  recorded in 'err' and this function returns OCI_ERROR.\n                  The error recorded in 'err' can be retrieved by calling\n                  OCIErrorGet().\n          mdo (IN) - pointer to the method descriptor in the object cache\n     REQUIRES:\n          1) All type accessors require that the type be pinned before calling\n             any accessor.\n          2) All input parameters must not be NULL and must be valid.\n     DESCRIPTION:\n          Get the flags (inline, constant, virutal, constructor, destructor) of\n          a method.\n     RETURNS:\n          the flags (inline, constant, virutal, constructor, destructor) of\n          the method\n     NOTES:\n          The type must be unpinned when the accessed information is no\n          longer needed.\n    }\n  {------------------------ OCITypeMethodMap --------------------------------- }\n  { ** OBSOLETE **  }\n  TOCITypeMethodMap = function(env: POCIEnv; err: POCIError; const tdo: POCIType;\n    mdo: PPOCITypeMethod): sword; cdecl;\n\n  {\n     NAME: OCITypeMethodMap - OCI Get the Method's MAP function.\n     PARAMETERS:\n          env (IN/OUT) - OCI environment handle initialized in object mode\n          err (IN/OUT) - error handle. If there is an error, it is\n                  recorded in 'err' and this function returns OCI_ERROR.\n                  The error recorded in 'err' can be retrieved by calling\n                  OCIErrorGet().\n          tdo (IN) - pointer to to the type descriptor in the object cache\n          mdo (OUT) - If this function completes successfully, and there is a\n                 map function for this type, 'mdo' points to the selected method\n                 descriptor in the object cache.  Otherwise, 'mdo' is null.\n     REQUIRES:\n          1) All type accessors require that the type be pinned before calling\n             any accessor.\n          2) All required input parameters must not be NULL and must be valid.\n     DESCRIPTION:\n          A type may have only one map function.  'OCITypeMethodMap()' finds\n          this function, if it exists, and returns a reference and a pointer to\n          the method descriptor in the object cache.  If the type does not have a\n          map (relative ordering) function, then 'mdo_ref' and 'mdo' are set\n          to null and an error is returned.\n     RETURNS:\n          OCI_SUCCESS if the function completes successfully.\n          OCI_INVALID_HANDLE if 'env' or 'err' is null.\n          OCI_ERROR if\n              the type does not contain a map function.\n     NOTES:\n          The type must be unpinned when the accessed information is no\n          longer needed.\n    }\n  {------------------------ OCITypeMethodOrder ------------------------------- }\n  { ** OBSOLETE **  }\n  TOCITypeMethodOrder = function(env: POCIEnv; err: POCIError;\n    const tdo: POCIType; mdo: PPOCITypeMethod): sword; cdecl;\n\n  {\n     NAME: OCITypeMethodOrder - OCI Get the Method's ORder function.\n     PARAMETERS:\n          env (IN/OUT) - OCI environment handle initialized in object mode\n          err (IN/OUT) - error handle. If there is an error, it is\n                  recorded in 'err' and this function returns OCI_ERROR.\n                  The error recorded in 'err' can be retrieved by calling\n                  OCIErrorGet().\n          tdo (IN) - pointer to to the type descriptor in the object cache\n          mdo (OUT) - If this function completes successfully, and there is a\n                 map function for this type, 'mdo' points to the selected method\n                 descriptor in the object cache.  Otherwise, 'mdo' is null.\n     REQUIRES:\n          1) All type accessors require that the type be pinned before calling\n             any accessor.\n          2) All required input parameters must not be NULL and must be valid.\n     DESCRIPTION:\n          A type may have only one ORder or MAP function. 'OCITypeMethodOrder()'\n          finds this function, if it exists, and returns a ref and a pointer\n          to the method descriptor in the object cache.  If the type does not\n          have a map (relative ordering) function, then 'mdo_ref' and 'mdo' are\n          set to null and an error is returned.\n     RETURNS:\n          OCI_SUCCESS if the function completes successfully.\n          OCI_INVALID_HANDLE if 'env' or 'err' is null.\n          OCI_ERROR if\n              the type does not contain a map function.\n     NOTES:\n          The type must be unpinned when the accessed information is no\n          longer needed.\n    }\n  {------------------------ OCITypeMethodParams ------------------------------ }\n  { ** OBSOLETE **  }\n  TOCITypeMethodParams = function(env: POCIEnv; err: POCIError;\n    const mdo: POCITypeMethod): ub4; cdecl;\n\n  {\n     NAME: OCITypeMethodParams - OCI Get a Method's Number of Parameters.\n     PARAMETERS:\n          env (IN/OUT) - OCI environment handle initialized in object mode\n          err (IN/OUT) - error handle. If there is an error, it is\n                  recorded in 'err' and this function returns OCI_ERROR.\n                  The error recorded in 'err' can be retrieved by calling\n                  OCIErrorGet().\n          mdo (IN) - pointer to the method descriptor in the object cache\n     REQUIRES:\n          1) All type accessors require that the type be pinned before calling\n             any accessor.\n          2) All input parameters must not be NULL and must be valid.\n     DESCRIPTION:\n          Get the number of parameters in a method.\n     RETURNS:\n          the number of parameters in the method\n     NOTES:\n          The type must be unpinned when the accessed information is no\n          longer needed.\n    }\n  {-------------------------------------------------------------------------- }\n  {                             RESULT ACCESSORS                              }\n  {-------------------------------------------------------------------------- }\n  {-------------------------- OCITypeResult --------------------------------- }\n  { ** OBSOLETE **  }\n  TOCITypeResult = function(env: POCIEnv; err: POCIError;\n    const mdo: POCITypeMethod; elem: PPOCITypeElem): sword; cdecl;\n\n  {\n     NAME: OCITypeResult - OCI Get a method's result type descriptor.\n     PARAMETERS:\n          env (IN/OUT) - OCI environment handle initialized in object mode\n          err (IN/OUT) - error handle. If there is an error, it is\n                  recorded in 'err' and this function returns OCI_ERROR.\n                  The error recorded in 'err' can be retrieved by calling\n                  OCIErrorGet().\n          mdo (IN) - pointer to the method descriptor in the object cache\n          elem (OUT) - If this function completes successfully, 'rdo' points to\n                 the selected result (parameter) descriptor in the object cache.\n     REQUIRES:\n          1) All type accessors require that the type be pinned before calling\n             any accessor.\n          2) 'elem' MUST be the address of an OCITypeElem pointer.\n     DESCRIPTION:\n          Get the result of a method.\n     RETURNS:\n          OCI_SUCCESS if the function completes successfully.\n          OCI_INVALID_HANDLE if 'env' or 'err' is null.\n          OCI_ERROR if\n              1) any of the required parameters is null.\n              2) method returns no results.\n     NOTES:\n          The method must be unpinned when the accessed information is no\n          longer needed.\n    }\n  {-------------------------------------------------------------------------- }\n  {                           PARAMETER ACCESSORS                             }\n  {-------------------------------------------------------------------------- }\n  {------------------------ OCITypeParamByPos ------------------------------- }\n  { ** OBSOLETE **  }\n  TOCITypeParamByPos = function(env: POCIEnv; err: POCIError;\n    const mdo: POCITypeMethod; const position: ub4;\n    elem: PPOCITypeElem): sword; cdecl;\n\n  {\n     NAME: OCITypeParamByPos - OCI Get a Parameter in a method By Position.\n     PARAMETERS:\n          env (IN/OUT) - OCI environment handle initialized in object mode\n          err (IN/OUT) - error handle. If there is an error, it is\n                  recorded in 'err' and this function returns OCI_ERROR.\n                  The error recorded in 'err' can be retrieved by calling\n                  OCIErrorGet().\n          mdo (IN) - pointer to the method descriptor in the object cache\n          position (IN) - the parameter's position.  Positions start at 1.\n          elem (OUT) - If this function completes successfully, 'elem' points to\n                 the selected parameter descriptor in the object cache.\n     REQUIRES:\n          1) All type accessors require that the type be pinned before calling\n             any accessor.\n     DESCRIPTION:\n          Get a parameter given its position in the method.  Positions start\n          at 1.\n     RETURNS:\n          OCI_SUCCESS if the function completes successfully.\n          OCI_INVALID_HANDLE if 'env' or 'err' is null.\n          OCI_ERROR if\n              1) any of the required parameters is null.\n              2) 'position' is not >= 1 and <= the number of parameters in the\n                 method.\n     NOTES:\n          The type must be unpinned when the accessed information is no\n          longer needed.\n    }\n  {------------------------ OCITypeParamByName ------------------------------- }\n  { ** OBSOLETE **  }\n  TOCITypeParamByName = function(env: POCIEnv; err: POCIError;\n    const mdo: POCITypeMethod; const name: Poratext; const n_length: ub4;\n    elem:PPOCITypeElem): sword; cdecl;\n\n  {\n     NAME: OCITypeParamByName - OCI Get a Parameter in a method By Name.\n     PARAMETERS:\n          env (IN/OUT) - OCI environment handle initialized in object mode\n          err (IN/OUT) - error handle. If there is an error, it is\n                  recorded in 'err' and this function returns OCI_ERROR.\n                  The error recorded in 'err' can be retrieved by calling\n                  OCIErrorGet().\n          mdo (IN) - pointer to the method descriptor in the object cache\n          name (IN) - the parameter's name\n          n_length (IN) - length (in bytes) of the 'name' parameter\n          elem (OUT) - If this function completes successfully, 'elem' points to\n                 the selected parameter descriptor in the object cache.\n     REQUIRES:\n          1) All type accessors require that the type be pinned before calling\n             any accessor.\n          2) if 'mdo' is not null, it must point to a valid method descriptor\n             in the object cache.\n     DESCRIPTION:\n          Get a parameter given its name.\n     RETURNS:\n          OCI_SUCCESS if the function completes successfully.\n          OCI_INVALID_HANDLE if 'env' or 'err' is null.\n          OCI_ERROR if\n              1) any of the required parameters is null.\n              2) the method does not contain a parameter with the input 'name'.\n     NOTES:\n          The type must be unpinned when the accessed information is no\n          longer needed.\n    }\n  {------------------------ OCITypeParamPos --------------------------------- }\n  { ** OBSOLETE **  }\n  TOCITypeParamPos = function(env: POCIEnv; err: POCIError;\n    const mdo: POCITypeMethod; const name: Poratext; const n_length: ub4;\n    position: Pub4; elem: PPOCITypeElem): sword; cdecl;\n\n  {\n     NAME: OCITypeParamPos - OCI Get a parameter's position in a method\n     PARAMETERS:\n          env (IN/OUT) - OCI environment handle initialized in object mode\n          err (IN/OUT) - error handle. If there is an error, it is\n                  recorded in 'err' and this function returns OCI_ERROR.\n                  The error recorded in 'err' can be retrieved by calling\n                  OCIErrorGet().\n          mdo (IN) - pointer to the method descriptor in the object cache\n          name (IN) - the parameter's name\n          n_length (IN) - length (in bytes) of the 'name' parameter\n          position (OUT) - If this function completes successfully, 'position'\n                 points to the position of the parameter in the method starting\n                 at position 1. position MUST point to space for a ub4.\n          elem (OUT) - If this function completes successfully, and\n                 the input 'elem' is not NULL, 'elem' points to the selected\n                 parameter descriptor in the object cache.\n     REQUIRES:\n          1) All type accessors require that the type be pinned before calling\n             any accessor.\n          2) if 'mdo' is not null, it must point to a valid method descriptor\n             in the object cache.\n     DESCRIPTION:\n          Get the position of a parameter in a method.  Positions start at 1.\n     RETURNS:\n          OCI_SUCCESS if the function completes successfully.\n          OCI_INVALID_HANDLE if 'env' or 'err' is null.\n          OCI_ERROR if\n              1) any of the parameters is null.\n              2) the method does not contain a parameter with the input 'name'.\n     NOTES:\n          The type must be unpinned when the accessed information is no\n          longer needed.\n    }\n  {------------------------ OCITypeParamElemMode ----------------------------- }\n  { ** OBSOLETE **  }\n  TOCITypeElemParamMode = function(env: POCIEnv; err: POCIError;\n    const elem: POCITypeElem): OCITypeParamMode; cdecl;\n\n  {\n     NAME: OCITypeElemParamMode - OCI Get a parameter's mode\n     PARAMETERS:\n          env (IN/OUT) - OCI environment handle initialized in object mode\n          err (IN/OUT) - error handle. If there is an error, it is\n                  recorded in 'err' and this function returns OCI_ERROR.\n                  The error recorded in 'err' can be retrieved by calling\n                  OCIErrorGet().\n          elem (IN) - pointer to the parameter descriptor in the object cache\n                  (represented by an OCITypeElem)\n     REQUIRES:\n          1) All type accessors require that the type be pinned before calling\n             any accessor.\n          2) All input parameters must not be NULL and must be valid.\n     DESCRIPTION:\n          Get the mode (in, out, or in/out) of the parameter.\n     RETURNS:\n          the mode (in, out, or in/out) of the parameter\n     NOTES:\n          The type must be unpinned when the accessed information is no\n          longer needed.\n    }\n  {------------------------- OCITypeElemDefaultValue ------------------------- }\n  { ** OBSOLETE **  }\n  TOCITypeElemDefaultValue = function(env: POCIEnv; err: POCIError;\n    const elem: POCITypeElem; d_v_length: Pub4): poratext; cdecl;\n\n  {\n     NAME: OCITypeElemDefaultValue - OCI Get the element's Default Value.\n     PARAMETERS:\n          env (IN/OUT) - OCI environment handle initialized in object mode\n          err (IN/OUT) - error handle. If there is an error, it is\n                  recorded in 'err' and this function returns OCI_ERROR.\n                  The error recorded in 'err' can be retrieved by calling\n                  OCIErrorGet().\n          elem (IN) - pointer to the parameter descriptor in the object cache\n                  (represented by an OCITypeElem)\n          d_v_length (OUT) - length (in bytes) of the returned default value.\n                 The caller must allocate space for the ub4 before calling this\n                 routine.\n     REQUIRES:\n          1) All type accessors require that the type be pinned before calling\n             any accessor.\n          2) All input parameters must not be NULL and must be valid.\n     DESCRIPTION:\n          Get the default value in text form (PL/SQL) of an element. For V8.0,\n          this only makes sense for a method parameter.\n     RETURNS:\n          The default value (text) of the parameter.\n     NOTES:\n          The type must be unpinned when the accessed information is no\n          longer needed.\n    }\n  {-------------------------------------------------------------------------- }\n  {                           TYPE VERSION TABLE                              }\n  {-------------------------------------------------------------------------- }\n  { For V8.0, the type version table is meant to be an internal data structure\n     only for Oracle clients for type version maintanence purposes. A more\n     general version of the API may be made public in subsequent releases.  }\n  {--------------------------- OCITypeVTInit -------------------------------- }\n  { ** OBSOLETE **  }\n  TOCITypeVTInit = function(env: POCIEnv; err: POCIError): sword; cdecl;\n\n  {\n     NAME: OCITypeVTInit - OCI type Version table INItialize\n     PARAMETERS:\n          env (IN/OUT) - OCI environment handle initialized in object mode\n          err (IN/OUT) - error handle. If there is an error, it is\n                  recorded in 'err' and this function returns OCI_ERROR.\n                  The error recorded in 'err' can be retrieved by calling\n                  OCIErrorGet().\n     REQUIRES:\n          none\n     DESCRIPTION:\n          Allocate space for and initialize the type version table and the type\n          version table's index.\n     RETURNS:\n          OCI_SUCCESS if the function completes successfully.\n          OCI_INVALID_HANDLE if 'env' or 'err' is null.\n          OCI_ERROR if internal errors occurrs during initialization.\n    }\n  {--------------------------- OCITypeVTInsert ------------------------------- }\n  { ** OBSOLETE **  }\n  TOCITypeVTInsert = function(env: POCIEnv; err: POCIError;\n    const schema_name: Poratext; const s_n_length: ub4;\n    const type_name: Poratext; const t_n_length: ub4;\n    const user_version:Poratext; const u_v_length:ub4): sword; cdecl;\n\n  {\n     NAME: OCITypeVTInsert - OCI type Version table INSert entry.\n     PARAMETERS:\n          env (IN/OUT) - OCI environment handle initialized in object mode\n          err (IN/OUT) - error handle. If there is an error, it is\n                  recorded in 'err' and this function returns OCI_ERROR.\n                  The error recorded in 'err' can be retrieved by calling\n                  OCIErrorGet().\n          schema_name (IN, optional) - name of schema associated with the\n                    type.  By default, the user's schema name is used.\n          s_n_length (IN) - length of the 'schema_name' parameter\n          type_name (IN) - type name to insert\n          t_n_length (IN) - length (in bytes) of the 'type_name' parameter\n          user_version (IN) - user readable version of the type\n          u_v_length (IN) - length (in bytes) of the 'user_version' parameter\n     REQUIRES:\n          none\n     DESCRIPTION:\n          Insert an entry into the type version table and the type version\n          table's index.  The entry's type name and user readable version\n          fields are updated with the input values.  All other fields are\n          initialized to null.\n     RETURNS:\n          OCI_SUCCESS if the function completes successfully.\n          OCI_INVALID_HANDLE if 'env' or 'err' is null.\n          OCI_ERROR if\n              1) any of the parameters is invalid.\n              2) an entry for 'type_name' has already been registered in the\n                 type version table.\n    }\n  {------------------------------ OCITypeVTSelect ---------------------------- }\n  { OCITypeVTSelect - OCI type VERSion table SELECT entry  }\n  { ** OBSOLETE **  }\n  TOCITypeVTSelect = function(env: POCIEnv; err: POCIError;\n    const schema_name: Poratext; const s_n_length: ub4;\n    const type_name: Poratext; const t_n_length: ub4; user_version: PPoratext;\n    u_v_length: Pub4; version: Pub2): sword; cdecl;\n\n  {\n     NAME: OCITypeVTSelect - OCI type Version table SELect entry.\n     PARAMETERS:\n          env (IN/OUT) - OCI environment handle initialized in object mode\n          err (IN/OUT) - error handle. If there is an error, it is\n                  recorded in 'err' and this function returns OCI_ERROR.\n                  The error recorded in 'err' can be retrieved by calling\n                  OCIErrorGet().\n          schema_name (IN, optional) - name of schema associated with the\n                    type.  By default, the user's schema name is used.\n          s_n_length (IN) - length of the 'schema_name' parameter\n          type_name (IN) - type name to select\n          t_n_length (IN) - length (in bytes) of the 'type_name' parameter\n          user_version (OUT, optional) - pointer to user readable version of the\n                   type\n          u_v_length (OUT, optional) - length (in bytes) of the 'user_version'\n                   parameter\n          version (OUT, optional) - internal type version\n     REQUIRES:\n          All input parameters must not be NULL and must be valid.\n     DESCRIPTION:\n          Select an entry in the type version table by name.\n     RETURNS:\n          OCI_SUCCESS if the function completes successfully.\n          OCI_INVALID_HANDLE if 'env' or 'err' is null.\n          OCI_ERROR if\n              1) any of the parameters is invalid.\n              2) an entry with 'type_name' does not exist.\n    }\n  { Compatibility function - following function prototype retained for\n     compatibility only  }\n//  function ortgcty(env:POCIEnv; err:POCIError; coll_tdo:POCIType; collelem_tdo:PPOCIType):sword;\n\n  {--------------------------------------------------------------------------- }\n  {               Transient Type Construction functions                        }\n  {--------------------------------------------------------------------------- }\n//  function TOCITypeBeginCreate(svchp:POCISvcCtx; errhp:POCIError; tc:OCITypeCode; dur:OCIDuration; _type:PPOCIType):sword;\n\n  {\n     NAME: OCITypeBeginCreate - OCI Type Begin Creation of a transient type.\n     REMARKS\n         Begins the construction process for a transient type. The type will be\n         anonymous (no name). To create a persistent named type, the CREATE TYPE\n         statement should be used from SQL. Transient types have no identity.\n         They are pure values.\n     PARAMETERS:\n         svchp (IN)       - The OCI Service Context.\n         errhp (IN/OUT)   - The OCI error handle. If there is an error, it is\n                            recorded in errhp and this function returns\n                            OCI_ERROR. Diagnostic information can be obtained by\n                            calling OCIErrorGet().\n         tc               - The TypeCode for the type. The Typecode could\n                            correspond to a User Defined Type or a Built-in type.\n                            Currently, the permissible values for User Defined\n                            Types are OCI_TYPECODE_OBJECT for an Object Type\n                            (structured), OCI_TYPECODE_VARRAY for a VARRAY\n                            collection type or OCI_TYPECODE_TABLE for a nested\n                            table collection type. For Object types,\n                            OCITypeAddAttr() needs to be called to add each of\n                            the attribute types. For Collection types,\n                            OCITypeSetCollection() needs to be called.\n                            Subsequently, OCITypeEndCreate() needs to be called\n                            to finish the creation process.\n                            The permissible values for Built-in type codes are\n                            specified in the user manual. Additional information\n                            on built-ins if any (like precision, scale for\n                            numbers, character set info for VARCHAR2s etc.) must\n                            be set with a subsequent call to OCITypeSetBuiltin().\n                            Subsequently OCITypeEndCreate() needs to be called\n                            to finish the creation process.\n         dur              - The allocation duration for the Type. Could be a\n                            predefined or a user defined duration.\n         type(OUT)        - The OCIType (Type Descriptor) that is being\n                            constructed.\n    RETURNS:\n          OCI_SUCCESS if the function completes successfully.\n          OCI_ERROR on error.\n   }\n//  function TOCITypeSetCollection(svchp:POCISvcCtx; errhp:POCIError; _type:POCIType; collelem_info:POCIParam; coll_count:ub4):sword;\n\n  {\n     NAME: OCITypeSetCollection - OCI Type Set Collection information\n     REMARKS :\n         Set Collection type information. This call can be called only if the\n         OCIType has been constructed with a collection typecode.\n     PARAMETERS:\n         svchp (IN)      -  The OCI Service Context.\n         errhp (IN/OUT)  -  The OCI error handle. If there is an error, it is\n                            recorded in errhp and this function returns\n                            OCI_ERROR. Diagnostic information can be obtained by\n                            calling OCIErrorGet().\n         type(IN OUT)    -  The OCIType (Type Descriptor) that is being\n                            constructed.\n         collelem_info   -  collelem_info provides information on the collection\n                            element. It is obtained by allocating an OCIParam\n                            (parameter handle) and setting type information in\n                            the OCIParam using OCIAttrSet() calls.\n         coll_count      -  The count of elements in the collection. Pass 0 for\n                            a nested table (unbounded).\n    RETURNS:\n          OCI_SUCCESS if the function completes successfully.\n          OCI_ERROR on error.\n   }\n//  function TOCITypeSetBuiltin(svchp:POCISvcCtx; errhp:POCIError; _type:POCIType; builtin_info:POCIParam):sword;\n\n  {\n     NAME: OCITypeSetBuiltin - OCI Type Set Builtin information.\n     REMARKS:\n         Set Built-in type information. This call can be called only if the\n         OCIType has been constructed with a built-in typecode\n         (OCI_TYPECODE_NUMBER etc.).\n     PARAMETERS:\n         svchp (IN)       - The OCI Service Context.\n         errhp (IN/OUT)   - The OCI error handle. If there is an error, it is\n                            recorded in errhp and this function returns\n                            OCI_ERROR. Diagnostic information can be obtained by\n                            calling OCIErrorGet().\n         type(IN OUT)     - The OCIType (Type Descriptor) that is being\n                            constructed.\n         builtin_info     - builtin_info provides information on the built-in\n                            (like precision, scale, charater set etc.). It is\n                            obtained by allocating an OCIParam (parameter handle)\n                            and setting type information in the OCIParam using\n                             OCIAttrSet() calls.\n    RETURNS:\n          OCI_SUCCESS if the function completes successfully.\n          OCI_ERROR on error.\n   }\n(* Const before type ignored *)\n//  function TOCITypeAddAttr(svchp:POCISvcCtx; errhp:POCIError; _type:POCIType; a_name:Poratext; a_length:ub4;\n//             attr_info:POCIParam):sword;\n\n  {\n     NAME: OCITypeAddAttr - OCI Type Add Attribute to an Object Type.\n     REMARKS:\n         Adds an attribute to an Object type (that was constructed earlier with\n         typecode OCI_TYPECODE_OBJECT).\n     PARAMETERS:\n         svchp (IN)       - The OCI Service Context\n         errhp (IN/OUT)   - The OCI error handle. If there is an error, it is\n                            recorded in errhp and this function returns\n                            OCI_ERROR. Diagnostic information can be obtained by\n                            calling OCIErrorGet().\n         type (IN/OUT)    - The Type description that is being constructed.\n         a_name(IN)       - Optional. gives the name of the attribute.\n         a_length         - Optional. gives length of attribute name.\n         attr_info        - Information on the attribute. It is obtained by\n                            allocating an OCIParam (parameter handle) and setting\n                            type information in the OCIParam using OCIAttrSet()\n                            calls.\n    RETURNS:\n          OCI_SUCCESS if the function completes successfully.\n          OCI_ERROR on error.\n   }\n//  function TOCITypeEndCreate(svchp:POCISvcCtx; errhp:POCIError; _type:POCIType):sword;\n\n  {\n     NAME: OCITypeEndCreate - OCI Type End Creation\n     REMARKS:\n         Finishes construction of a type description.Subsequently, only access\n         will be allowed.\n     PARAMETERS:\n         svchp (IN)       - The OCI Service Context\n         errhp (IN/OUT)   - The OCI error handle. If there is an error, it is\n                            recorded in errhp and this function returns\n                            OCI_ERROR. Diagnostic information can be obtained by\n                            calling OCIErrorGet().\n         type (IN/OUT)    - The Type description that is being constructed.\n     RETURNS:\n          OCI_SUCCESS if the function completes successfully.\n          OCI_ERROR on error.\n   }\n  {========================= }\n  { PUBLIC MACROS AND FLAGS  }\n  {========================= }\n  {-------------------------------------------------------------------------- }\n  {                          TYPE ELEMENT FLAGS                               }\n  {-------------------------------------------------------------------------- }\n  { element is a REF  }\n  const\n    OCI_TYPEELEM_REF = $8000;\n  { parameter is required  }\n    OCI_TYPEPARAM_REQUIRED = $0800;\n  { macros to test flags  }\n  { was #define dname(params) para_def_expr }\n  { argument types are unknown }\n  { return type might be wrong }\ntype\n  TOCI_TYPEELEM_IS_REF = function(elem_flag : longint) : longint;\n\n  { was #define dname(params) para_def_expr }\n  { argument types are unknown }\n  { return type might be wrong }\n  TOCI_TYPEPARAM_IS_REQUIRED = function (param_flag : longint) : longint;\n\n\ntype\n  OracleOCI_API = record\n    OCIPasswordChange:      TOCIPasswordChange;\n    OCIInitialize:          TOCIInitialize;\n    OCIEnvInit:             TOCIEnvInit;\n    OCIEnvCreate:           TOCIEnvCreate;\n    OCIEnvNlsCreate:        TOCIEnvNlsCreate;\n    OCIHandleAlloc:         TOCIHandleAlloc;\n    OCIServerAttach:        TOCIServerAttach;\n    OCIAttrSet:             TOCIAttrSet;\n    OCISessionBegin:        TOCISessionBegin;\n    OCISessionEnd:          TOCISessionEnd;\n    OCIServerDetach:        TOCIServerDetach;\n    OCIHandleFree:          TOCIHandleFree;\n    OCIErrorGet:            TOCIErrorGet;\n    OCIStmtPrepare:         TOCIStmtPrepare;\n    OCIStmtExecute:         TOCIStmtExecute;\n    OCIParamGet:            TOCIParamGet;\n    OCIAttrGet:             TOCIAttrGet;\n    OCIStmtFetch:           TOCIStmtFetch;\n    OCIDefineByPos:         TOCIDefineByPos;\n    OCIDefineArrayOfStruct: TOCIDefineArrayOfStruct;\n    OCIBindByPos:           TOCIBindByPos;\n    OCIBindByName:          TOCIBindByName;\n\n    OCIDefineObject:        TOCIDefineObject;\n\n    { > ori.h }\n    OCIObjectNew:           TOCIObjectNew;\n    OCIObjectPin:           TOCIObjectPin;\n    OCIObjectUnpin:         TOCIObjectUnpin;\n    OCIObjectPinCountReset: TOCIObjectPinCountReset;\n    OCIObjectLock:          TOCIObjectLock;\n    OCIObjectLockNoWait:    TOCIObjectLockNoWait;\n    OCIObjectMarkUpdate:    TOCIObjectMarkUpdate;\n    OCIObjectUnmark:        TOCIObjectUnmark;\n    OCIObjectUnmarkByRef:   TOCIObjectUnmarkByRef;\n    OCIObjectFree:          TOCIObjectFree;\n    OCIObjectMarkDeleteByRef: TOCIObjectMarkDeleteByRef;\n    OCIObjectMarkDelete:    TOCIObjectMarkDelete;\n    OCIObjectFlush:         TOCIObjectFlush;\n    OCIObjectRefresh:       TOCIObjectRefresh;\n    OCIObjectCopy:          TOCIObjectCopy;\n    OCIObjectGetTypeRef:    TOCIObjectGetTypeRef;\n    OCIObjectGetObjectRef:  TOCIObjectGetObjectRef;\n    OCIObjectMakeObjectRef: TOCIObjectMakeObjectRef;\n    OCIObjectGetPrimaryKeyTypeRef:  TOCIObjectGetPrimaryKeyTypeRef;\n    OCIObjectGetInd:        TOCIObjectGetInd;\n    OCIObjectExists:        TOCIObjectExists;\n    OCIObjectGetProperty:   TOCIObjectGetProperty;\n    OCIObjectIsLocked:      TOCIObjectIsLocked;\n    OCIObjectIsDirty:       TOCIObjectIsDirty;\n    OCIObjectPinTable:      TOCIObjectPinTable;\n    OCIObjectArrayPin:      TOCIObjectArrayPin;\n    OCICacheFlush:          TOCICacheFlush;\n    OCICacheRefresh:        TOCICacheRefresh;\n    OCICacheUnpin:          TOCICacheUnpin;\n    OCICacheFree:           TOCICacheFree;\n    OCICacheUnmark:         TOCICacheUnmark;\n    OCIDurationBegin:       TOCIDurationBegin;\n    OCIDurationEnd:         TOCIDurationEnd;\n    { < ori.h }\n\n    OCITransStart:          TOCITransStart;\n    OCITransCommit:         TOCITransCommit;\n    OCITransRollback:       TOCITransRollback;\n    OCITransDetach:         TOCITransDetach;\n    OCITransPrepare:        TOCITransPrepare;\n    OCITransForget:         TOCITransForget;\n    OCIDescribeAny:         TOCIDescribeAny;\n    OCIBreak:               TOCIBreak;\n    OCIReset:               TOCIReset;\n    OCIDescriptorAlloc:     TOCIDescriptorAlloc;\n    OCIDescriptorFree:      TOCIDescriptorFree;\n    OCIStmtGetPieceInfo:    TOCIStmtGetPieceInfo;\n    OCIStmtSetPieceInfo:    TOCIStmtSetPieceInfo;\n    OCIServerVersion:       TOCIServerVersion;\n    OCIServerRelease:       TOCIServerRelease;\n    OCIBindDynamic:         TOCIBindDynamic;\n    OCIBindObject:          TOCIBindObject;\n    OCIDateTimeAssign:      TOCIDateTimeAssign;\n    OCIDateTimeCheck:       TOCIDateTimeCheck;\n    OCIDateTimeCompare:     TOCIDateTimeCompare;\n    OCIDateTimeConvert:     TOCIDateTimeConvert;\n    OCIDateTimeFromText:    TOCIDateTimeFromText;\n    OCIDateTimeGetDate:     TOCIDateTimeGetDate;\n    OCIDateTimeGetTime:     TOCIDateTimeGetTime;\n    OCIDateTimeGetTimeZoneOffset: TOCIDateTimeGetTimeZoneOffset;\n    OCIDateTimeSysTimeStamp: TOCIDateTimeSysTimeStamp;\n    OCIDateTimeConstruct:   TOCIDateTimeConstruct;\n    OCIDateTimeToText:      TOCIDateTimeToText;\n    OCIDateTimeGetTimeZoneName: TOCIDateTimeGetTimeZoneName;\n    OCILobAppend:           TOCILobAppend;\n    OCILobAssign:           TOCILobAssign;\n    OCILobClose:            TOCILobClose;\n    OCILobCopy:             TOCILobCopy;\n    OCILobCreateTemporary:  TOCILobCreateTemporary;\n    OCILobEnableBuffering:  TOCILobEnableBuffering;\n    OCILobDisableBuffering: TOCILobDisableBuffering;\n    OCILobErase:            TOCILobErase;\n    OCILobFileExists:       TOCILobFileExists;\n    OCILobFileGetName:      TOCILobFileGetName;\n    OCILobFileSetName:      TOCILobFileSetName;\n    OCILobFlushBuffer:      TOCILobFlushBuffer;\n    OCILobFreeTemporary:    TOCILobFreeTemporary;\n    OCILobCharSetForm:      TOCILobCharSetForm;\n    OCILobCharSetId:        TOCILobCharSetId;\n    OCILobGetLength:        TOCILobGetLength;\n    OCILobIsOpen:           TOCILobIsOpen;\n    OCILobIsTemporary:      TOCILobIsTemporary;\n    OCILobLoadFromFile:     TOCILobLoadFromFile;\n    OCILobLocatorIsInit:    TOCILobLocatorIsInit;\n    OCILobOpen:             TOCILobOpen;\n    OCILobRead:             TOCILobRead;\n    OCILobTrim:             TOCILobTrim;\n    OCILobWrite:            TOCILobWrite;\n    OCIResultSetToStmt:     TOCIResultSetToStmt;\n    OCINlsNumericInfoGet:   TOCINlsNumericInfoGet;\n    OCIClientVersion:       TOCIClientVersion;\n\n    { OCI Number mapping }\n    OCINumberInc:           TOCINumberInc;\n    OCINumberDec:           TOCINumberDec;\n    OCINumberSetZero:       TOCINumberSetZero;\n    OCINumberSetPi:         TOCINumberSetPi;\n    OCINumberAdd:           TOCINumberAdd;\n    OCINumberSub:           TOCINumberSub;\n    OCINumberMul:           TOCINumberMul;\n    OCINumberDiv:           TOCINumberDiv;\n    OCINumberMod:           TOCINumberMod;\n    OCINumberIntPower:      TOCINumberIntPower;\n    OCINumberShift:         TOCINumberShift;\n    OCINumberNeg:           TOCINumberNeg;\n    OCINumberToText:        TOCINumberToText;\n    OCINumberFromText:      TOCINumberFromText;\n    OCINumberToInt:         TOCINumberToInt;\n    OCINumberFromInt:       TOCINumberFromInt;\n    OCINumberToReal:        TOCINumberToReal;\n    OCINumberToRealArray:   TOCINumberToRealArray;\n    OCINumberFromReal:      TOCINumberFromReal;\n    OCINumberCmp:           TOCINumberCmp;\n    OCINumberSign:          TOCINumberSign;\n    OCINumberIsZero:        TOCINumberIsZero;\n    OCINumberIsInt:         TOCINumberIsInt;\n    OCINumberAssign:        TOCINumberAssign;\n    OCINumberAbs:           TOCINumberAbs;\n    OCINumberCeil:          TOCINumberCeil;\n    OCINumberFloor:         TOCINumberFloor;\n    OCINumberSqrt:          TOCINumberSqrt;\n    OCINumberTrunc:         TOCINumberTrunc;\n    OCINumberPower:         TOCINumberPower;\n    OCINumberRound:         TOCINumberRound;\n    OCINumberPrec:          TOCINumberPrec;\n    OCINumberSin:           TOCINumberSin;\n    OCINumberArcSin:        TOCINumberArcSin;\n    OCINumberHypSin:        TOCINumberHypSin;\n    OCINumberCos:           TOCINumberCos;\n    OCINumberArcCos:        TOCINumberArcCos;\n    OCINumberHypCos:        TOCINumberHypCos;\n    OCINumberTan:           TOCINumberTan;\n    OCINumberArcTan:        TOCINumberArcTan;\n    OCINumberArcTan2:       TOCINumberArcTan2;\n    OCINumberHypTan:        TOCINumberHypTan;\n    OCINumberExp:           TOCINumberExp;\n    OCINumberLn:            TOCINumberLn;\n    OCINumberLog:           TOCINumberLog;\n\n    { OCI oracle Date }\n    OCIDateAssign:          TOCIDateAssign;\n    OCIDateToText:          TOCIDateToText;\n    OCIDateFromText:        TOCIDateFromText;\n    OCIDateCompare:         TOCIDateCompare;\n    OCIDateAddMonths:       TOCIDateAddMonths;\n    OCIDateAddDays:         TOCIDateAddDays;\n    OCIDateLastDay:         TOCIDateLastDay;\n    OCIDateDaysBetween:     TOCIDateDaysBetween;\n    OCIDateZoneToZone:      TOCIDateZoneToZone;\n    OCIDateNextDay:         TOCIDateNextDay;\n\n    { OBJECT REFERENCE (REF) }\n    OCIRefClear:            TOCIRefClear;\n    OCIRefAssign:           TOCIRefAssign;\n\n    OCITableSize:           TOCITableSize;\n    OCITableExists:         TOCITableExists;\n    OCITableDelete:         TOCITableDelete;\n    OCITableFirst:          TOCITableFirst;\n    OCITableLast:           TOCITableLast;\n    OCITableNext:           TOCITableNext;\n    OCITablePrev:           TOCITablePrev;\n\n    { Oracle Object Interface for Dynamic Data Access }\n    OCIObjectSetAttr:       TOCIObjectSetAttr;\n    OCIObjectGetAttr:       TOCIObjectGetAttr;\n    {ociap.h}\n    OCIPing:                TOCIPing;\n    {ort.h}\n    OCITypeIterNew:         TOCITypeIterNew;\n    OCITypeIterSet:         TOCITypeIterSet;\n    OCITypeIterFree:        TOCITypeIterFree;\n    OCITypeByName:          TOCITypeByName;\n    OCITypeArrayByName:     TOCITypeArrayByName;\n    OCITypeByRef:           TOCITypeByRef;\n    OCITypeArrayByRef:      TOCITypeArrayByRef;\n    OCITypeName:            TOCITypeName;\n    OCITypeSchema:          TOCITypeSchema;\n    OCITypeTypeCode:        TOCITypeTypeCode;\n    OCITypeCollTypeCode:    TOCITypeCollTypeCode;\n    OCITypeVersion:         TOCITypeVersion;\n    OCITypeAttrs:           TOCITypeAttrs;\n    OCITypeMethods:         TOCITypeMethods;\n    OCITypeElemName:        TOCITypeElemName;\n    OCITypeElemTypeCode:    TOCITypeElemTypeCode;\n    OCITypeElemType:        TOCITypeElemType;\n    OCITypeElemFlags:       TOCITypeElemFlags;\n    OCITypeElemNumPrec:     TOCITypeElemNumPrec;\n    OCITypeElemNumScale:    TOCITypeElemNumScale;\n    OCITypeElemLength:      TOCITypeElemLength;\n    OCITypeElemCharSetID:   TOCITypeElemCharSetID;\n    OCITypeElemCharSetForm: TOCITypeElemCharSetForm;\n    OCITypeElemParameterizedType: TOCITypeElemParameterizedType;\n    OCITypeElemExtTypeCode: TOCITypeElemExtTypeCode;\n    OCITypeAttrByName:      TOCITypeAttrByName;\n    OCITypeAttrNext:        TOCITypeAttrNext;\n    OCITypeCollElem:        TOCITypeCollElem;\n    OCITypeCollSize:        TOCITypeCollSize;\n    OCITypeCollExtTypeCode: TOCITypeCollExtTypeCode;\n    OCITypeMethodOverload:  TOCITypeMethodOverload;\n    OCITypeMethodByName:    TOCITypeMethodByName;\n    OCITypeMethodNext:      TOCITypeMethodNext;\n    OCITypeMethodName:      TOCITypeMethodName;\n    OCITypeMethodEncap:     TOCITypeMethodEncap;\n    OCITypeMethodFlags:     TOCITypeMethodFlags;\n    OCITypeMethodMap:       TOCITypeMethodMap;\n    OCITypeMethodOrder:     TOCITypeMethodOrder;\n    OCITypeMethodParams:    TOCITypeMethodParams;\n    OCITypeResult:          TOCITypeResult;\n    OCITypeParamByPos:      TOCITypeParamByPos;\n    OCITypeParamByName:     TOCITypeParamByName;\n    OCITypeParamPos:        TOCITypeParamPos;\n    OCITypeElemParamMode:   TOCITypeElemParamMode;\n    OCITypeElemDefaultValue:TOCITypeElemDefaultValue;\n    OCITypeVTInit:          TOCITypeVTInit;\n    OCITypeVTInsert:        TOCITypeVTInsert;\n    OCITypeVTSelect:        TOCITypeVTSelect;\n  end;\n\nimplementation\n\nend.\n\n"
  },
  {
    "path": "lib/zeosdbo/src/plain/ZPlainOracleDriver.pas",
    "content": "{*********************************************************}\n{                                                         }\n{                 Zeos Database Objects                   }\n{             Native Plain Drivers for Oracle             }\n{                                                         }\n{        Originally written by Sergey Seroukhov           }\n{                                                         }\n{*********************************************************}\n\n{@********************************************************}\n{    Copyright (c) 1999-2012 Zeos Development Group       }\n{                                                         }\n{ License Agreement:                                      }\n{                                                         }\n{ This library is distributed in the hope that it will be }\n{ useful, but WITHOUT ANY WARRANTY; without even the      }\n{ implied warranty of MERCHANTABILITY or FITNESS FOR      }\n{ A PARTICULAR PURPOSE.  See the GNU Lesser General       }\n{ Public License for more details.                        }\n{                                                         }\n{ The source code of the ZEOS Libraries and packages are  }\n{ distributed under the Library GNU General Public        }\n{ License (see the file COPYING / COPYING.ZEOS)           }\n{ with the following  modification:                       }\n{ As a special exception, the copyright holders of this   }\n{ library give you permission to link this library with   }\n{ independent modules to produce an executable,           }\n{ regardless of the license terms of these independent    }\n{ modules, and to copy and distribute the resulting       }\n{ executable under terms of your choice, provided that    }\n{ you also meet, for each linked independent module,      }\n{ the terms and conditions of the license of that module. }\n{ An independent module is a module which is not derived  }\n{ from or based on this library. If you modify this       }\n{ library, you may extend this exception to your version  }\n{ of the library, but you are not obligated to do so.     }\n{ If you do not wish to do so, delete this exception      }\n{ statement from your version.                            }\n{                                                         }\n{                                                         }\n{ The project web site is located on:                     }\n{   http://zeos.firmos.at  (FORUM)                        }\n{   http://sourceforge.net/p/zeoslib/tickets/ (BUGTRACKER)}\n{   svn://svn.code.sf.net/p/zeoslib/code-0/trunk (SVN)    }\n{                                                         }\n{   http://www.sourceforge.net/projects/zeoslib.          }\n{                                                         }\n{                                                         }\n{                                 Zeos Development Group. }\n{********************************************************@}\n\nunit ZPlainOracleDriver;\n\ninterface\n\n{$I ZPlain.inc}\n\n{$J+}\n\nuses\n{$IFNDEF UNIX}\n//  Windows,\n{$ENDIF}\n  ZPlainLoader, ZCompatibility, ZPlainOracleConstants, ZPlainDriver;\n\n{***************** Plain API types definition ****************}\n\nconst\n  WINDOWS_DLL_LOCATION = 'oci.dll';\n//  WINDOWS_DLL_LOCATION = 'ora803.dll';\n  LINUX_DLL_LOCATION = 'libclntsh'+SharedSuffix;\n//  LINUX_DLL_LOCATION = 'libwtc8.so';\n\ntype\n\n  {** Represents a generic interface to Oracle native API. }\n  IZOraclePlainDriver = interface (IZPlainDriver)\n    ['{22404660-C95F-4346-A3DB-7C6DFE15F115}']\n\n    function Initializ(mode: ub4; ctxp: Pointer; malocfp: Pointer;\n      ralocfp: Pointer; mfreefp: Pointer): sword;\n    function EnvInit(var envhpp: POCIEnv; mode: ub4; xtramemsz: size_T;\n      usrmempp: PPointer): sword;\n    function EnvCreate(var envhpp: POCIEnv; mode: ub4; ctxp: Pointer;\n      malocfp: Pointer; ralocfp: Pointer; mfreefp: Pointer; xtramemsz: size_T;\n      usrmempp: PPointer): sword;\n    function EnvNlsCreate(var envhpp: POCIEnv; mode: ub4; ctxp: Pointer;\n      malocfp: Pointer; ralocfp: Pointer; mfreefp: Pointer; xtramemsz: size_T;\n      usrmempp: PPointer; charset, ncharset: ub2): sword;\n\n    function HandleAlloc(parenth: POCIHandle; var hndlpp: POCIHandle;\n      atype: ub4; xtramem_sz: size_T; usrmempp: PPointer): sword;\n    function ServerAttach(srvhp: POCIServer; errhp: POCIError; dblink: text;\n      dblink_len: sb4; mode: ub4): sword;\n    function AttrSet(trgthndlp: POCIHandle; trghndltyp: ub4;\n      attributep: Pointer; size: ub4; attrtype: ub4; errhp: POCIError):sword;\n    function SessionBegin(svchp: POCISvcCtx; errhp: POCIError;\n      usrhp: POCISession; credt: ub4; mode: ub4):sword;\n    function SessionEnd(svchp: POCISvcCtx; errhp: POCIError;\n      usrhp: POCISession; mode: ub4): sword;\n    function ServerDetach(srvhp: POCIServer; errhp: POCIError;\n      mode: ub4): sword;\n    function HandleFree(hndlp: Pointer; atype: ub4): sword;\n    function ErrorGet(hndlp: Pointer; recordno: ub4; sqlstate: text;\n      var errcodep: sb4; bufp: text; bufsiz: ub4; atype: ub4): sword;\n\n    function StmtPrepare(stmtp: POCIStmt; errhp: POCIError; stmt: text;\n      stmt_len: ub4; language:ub4; mode: ub4):sword;\n    function StmtExecute(svchp: POCISvcCtx; stmtp: POCIStmt;\n      errhp: POCIError; iters: ub4; rowoff: ub4; snap_in: POCISnapshot;\n      snap_out: POCISnapshot; mode: ub4): sword;\n    function ParamGet(hndlp: Pointer; htype: ub4; errhp: POCIError;\n      var parmdpp: Pointer; pos: ub4): sword;\n    function AttrGet(trgthndlp: POCIHandle; trghndltyp: ub4;\n      attributep: Pointer; sizep: Pointer; attrtype: ub4;\n      errhp: POCIError): sword;\n    function StmtFetch(stmtp: POCIStmt; errhp: POCIError; nrows: ub4;\n      orientation: ub2; mode: ub4): sword;\n    function DefineByPos(stmtp: POCIStmt; var defnpp: POCIDefine;\n      errhp: POCIError; position: ub4; valuep: Pointer; value_sz: sb4; dty: ub2;\n      indp: Pointer; rlenp: Pointer; rcodep: Pointer; mode: ub4): sword;\n    function DefineArrayOfStruct(defnpp: POCIDefine; errhp: POCIError;\n      pvskip: ub4; indskip: ub4; rlskip: ub4; rcskip: ub4): sword;\n\n    function BindByPos(stmtp: POCIStmt; var bindpp: POCIBind;\n      errhp: POCIError; position: ub4; valuep: Pointer; value_sz: sb4; dty: ub2;\n      indp: Pointer; alenp: Pointer; rcodep: Pointer; maxarr_len: ub4;\n      curelep: Pointer; mode: ub4): sword;\n    function BindByName(stmtp: POCIStmt; var bindpp: POCIBind;\n      errhp: POCIError; placeholder: text; placeh_len: sb4; valuep: Pointer;\n      value_sz: sb4; dty: ub2; indp: Pointer; alenp: Pointer; rcodep: Pointer;\n      maxarr_len: ub4; curelep: Pointer; mode: ub4): sword;\n    function BindDynamic(bindp: POCIBind; errhp: POCIError; ictxp: Pointer;\n    icbfp: Pointer; octxp: Pointer; ocbfp: Pointer): sword;\n    function BindObject(bindp: POCIBind; errhp: POCIError;\n                    const _type: POCIType; pgvpp: PPointer;\n                    pvszsp: pub4; indpp: PPointer;\n                    indszp: pub4): sword;\n\n    function DefineObject(defnpp: POCIDefine; errhp: POCIError;\n      _type: POCIHandle; pgvpp, pvszsp, indpp, indszp: pointer): sword;\n\n    { > ori.h}\n    function ObjectNew(env: POCIEnv; err: POCIError; const svc: POCISvcCtx;\n                       typecode: OCITypeCode; tdo: POCIType; table: Pointer;\n                       duration: OCIDuration; value: Longbool;\n                       instance: PPointer): sword;\n    function ObjectPin(env: POCIEnv; err: POCIError;\n      const object_ref: POCIRef; const corhdl: POCIComplexObject;\n      const pin_option: OCIPinOpt; const pin_duration: OCIDuration;\n      const lock_option: OCILockOpt; _object: PPointer): sword;\n    function ObjectUnpin(env: POCIEnv; err: POCIError;\n      const _object: Pointer): sword;\n    function ObjectPinCountReset(env: POCIEnv; err: POCIError;\n      const _object: pointer): sword;\n    function ObjectLock(env: POCIEnv; err: POCIError;\n      const _object: pointer): sword;\n    function ObjectLockNoWait(env: POCIEnv; err: POCIError;\n      const _object: pointer): sword;\n    function ObjectMarkUpdate(env: POCIEnv; err: POCIError;\n      const _object: pointer): sword;\n    function ObjectUnmark(env: POCIEnv; err: POCIError;\n      const _object:pointer): sword;\n    function ObjectUnmarkByRef(env: POCIEnv; err: POCIError;\n      const ref: POCIRef): sword;\n    function ObjectFree(hndl: POCIEnv; err: POCIError;\n      instance: POCIHandle;flags :ub2):sword;\n    function ObjectMarkDeleteByRef(env: POCIEnv; err: POCIError;\n      const object_ref:POCIRef): sword;\n    function ObjectMarkDelete(env: POCIEnv; err: POCIError;\n      const instance:pointer): sword;\n    function ObjectFlush(env: POCIEnv; err: POCIError;\n      const _object: pointer): sword;\n    function ObjectRefresh(env: POCIEnv; err: POCIError;\n      _object: pointer): sword;\n    function ObjectCopy(env: POCIEnv; err: POCIError; const svc: POCISvcCtx;\n      const source, null_source, target, null_target: pointer; const tdo: POCIType;\n      const duration: OCIDuration; const option: ub1): sword;\n    function ObjectGetTypeRef(env: POCIEnv; err: POCIError;\n      const instance:pointer; type_ref: POCIRef): sword;\n    function ObjectGetObjectRef(env: POCIEnv; err: POCIError;\n      const _object: pointer; object_ref: POCIRef): sword;\n    function ObjectMakeObjectRef(env: POCIEnv; err: POCIError;\n      const svc: POCISvcCtx; const table: pointer; const values: PPointer;\n      const array_len: ub4; object_ref: POCIRef): sword;\n    function ObjectGetPrimaryKeyTypeRef(env: POCIEnv; err: POCIError;\n      const svc:POCISvcCtx; const table: pointer; type_ref: POCIRef): sword;\n    function ObjectGetInd(env: POCIEnv; err: POCIError;\n      const instance: pointer; null_struct: PPointer): sword;\n    function ObjectExists(env: POCIEnv; err: POCIError; const ins: pointer;\n      exist: PBoolean): sword;\n    function ObjectGetProperty(envh: POCIEnv; errh: POCIError;\n      const obj: pointer; const propertyId: OCIObjectPropId;\n      _property: pointer; size: Pub4): sword;\n    function ObjectIsLocked(env: POCIEnv; err: POCIError; const ins: pointer;\n      lock: Pboolean): sword;\n    function ObjectIsDirty(env: POCIEnv; err: POCIError; const ins: pointer;\n      dirty: PBoolean): sword;\n    function ObjectPinTable(env: POCIEnv; err: POCIError;\n      const svc:POCISvcCtx; const schema_name: Poratext; const s_n_length: ub4;\n      const object_name: Poratext; const o_n_length:ub4;\n      const scope_obj_ref: POCIRef; const pin_duration: OCIDuration;\n      _object: PPointer): sword;\n    function ObjectArrayPin(env: POCIEnv; err: POCIError;\n      const ref_array: PPOCIRef; const array_size: ub4;\n      const cor_array: PPOCIComplexObject; const cor_array_size: ub4;\n      const pin_option: OCIPinOpt; const pin_duration: OCIDuration;\n      const lock: OCILockOpt; obj_array: PPointer;\n      pos: Pub4): sword;\n    function CacheFlush(env: POCIEnv; err: POCIError; const svc:POCISvcCtx;\n      const context: pointer; const get: TOCICacheFlushGet;\n      ref: PPOCIRef): sword;\n    function CacheRefresh(env: POCIEnv; err: POCIError;\n      const svc:POCISvcCtx; const option: OCIRefreshOpt; const context: pointer;\n      get: TOCICacheRefreshGet; ref: PPOCIRef): sword;\n    function CacheUnpin(env: POCIEnv; err: POCIError;\n      const svc:POCISvcCtx): sword;\n    function CacheFree(env: POCIEnv; err: POCIError;\n      const svc: POCISvcCtx): sword;\n    function CacheUnmark(env: POCIEnv; err: POCIError;\n      const svc: POCISvcCtx): sword;\n    function DurationBegin(env: POCIEnv; err: POCIError;\n      svc: POCISvcCtx; const parent: OCIDuration;\n      dur: POCIDuration): sword;\n    function DurationEnd(env: POCIEnv; err: POCIError; svc: POCISvcCtx;\n      duration: OCIDuration): sword;\n    { < ori.h}\n\n    function TransStart(svchp: POCISvcCtx; errhp: POCIError; timeout: word;\n      flags: ub4): sword;\n    function TransRollback(svchp: POCISvcCtx; errhp: POCIError;\n      flags: ub4): sword;\n    function TransCommit(svchp: POCISvcCtx; errhp: POCIError;\n      flags: ub4): sword;\n    function TransDetach(svchp: POCISvcCtx; errhp: POCIError;\n      flags: ub4): sword;\n    function TransPrepare(svchp: POCISvcCtx; errhp: POCIError;\n      flags: ub4): sword;\n    function TransForget(svchp: POCISvcCtx; errhp: POCIError;\n      flags: ub4): sword;\n\n    function DescribeAny(svchp: POCISvcCtx; errhp: POCIError;\n      objptr: Pointer; objnm_len: ub4; objptr_typ: ub1; info_level: ub1;\n      objtyp: ub1; dschp: POCIDescribe): sword;\n    function Break(svchp: POCISvcCtx; errhp:POCIError): sword;\n    function Reset(svchp: POCISvcCtx; errhp:POCIError): sword;\n    function DescriptorAlloc(parenth: POCIEnv; var descpp: POCIDescriptor;\n      htype: ub4; xtramem_sz: integer; usrmempp: Pointer): sword;\n    function DescriptorFree(descp: Pointer; htype: ub4): sword;\n\n    function DateTimeAssign(hndl: POCIEnv; err: POCIError;\n      const from: POCIDateTime;_to: POCIDateTime): sword;\n    function DateTimeCheck(hndl: POCIEnv; err: POCIError;\n      const date: POCIDateTime; var valid: ub4): sword;\n    function DateTimeCompare(hndl: POCIEnv; err: POCIError;\n      const date1: POCIDateTime; const date2: POCIDateTime;\n      var result: sword): sword;\n    function DateTimeConvert(hndl: POCIEnv; err: POCIError;\n      indate: POCIDateTime; outdate: POCIDateTime): sword;\n    function DateTimeFromText(hndl: POCIEnv; err: POCIError;\n      const date_str: text; d_str_length: size_t; const fmt: text;\n      fmt_length: ub1; const lang_name: text; lang_length: size_t;\n      date: POCIDateTime): sword;\n    function DateTimeGetDate(hndl: POCIEnv; err: POCIError;\n      const date: POCIDateTime; var year: sb2; var month: ub1;\n      var day: ub1): sword;\n    function DateTimeGetTime(hndl: POCIEnv; err: POCIError;\n      datetime: POCIDateTime; var hour: ub1; var minute: ub1; var sec: ub1;\n      var fsec: ub4): sword;\n    function DateTimeGetTimeZoneOffset(hndl: POCIEnv; err: POCIError;\n      const datetime: POCIDateTime; var hour: sb1; var minute: sb1): sword;\n    function DateTimeSysTimeStamp(hndl: POCIEnv; err: POCIError;\n      sys_date: POCIDateTime): sword;\n    function DateTimeConstruct(hndl: POCIEnv; err: POCIError;\n      datetime: POCIDateTime; year: sb2; month: ub1; day: ub1; hour: ub1;\n      min: ub1; sec: ub1; fsec: ub4; timezone: text;\n      timezone_length: size_t): sword;\n    function DateTimeToText(hndl: POCIEnv; err: POCIError;\n      const date: POCIDateTime; const fmt: text; fmt_length: ub1;\n      fsprec: ub1; const lang_name: text; lang_length: size_t;\n      var buf_size: ub4; buf: text): sword;\n    function DateTimeGetTimeZoneName(hndl: POCIEnv; err: POCIError;\n      datetime: POCIDateTime; var buf: ub1; var buflen: ub4): sword;\n\n    function LobAppend(svchp: POCISvcCtx; errhp: POCIError; dst_locp,\n      src_locp: POCILobLocator): sword;\n    function LobAssign(svchp: POCISvcCtx; errhp: POCIError;\n      src_locp: POCILobLocator; var dst_locpp: POCILobLocator): sword;\n    function LobClose(svchp: POCISvcCtx; errhp: POCIError;\n      locp: POCILobLocator): sword;\n    function LobCopy(svchp: POCISvcCtx; errhp: POCIError;\n      dst_locp: POCILobLocator; src_locp: POCILobLocator; amount: ub4;\n      dst_offset: ub4; src_offset: ub4): sword;\n    function LobEnableBuffering(svchp: POCISvcCtx; errhp: POCIError;\n      locp: POCILobLocator): sword;\n    function LobDisableBuffering(svchp: POCISvcCtx; errhp: POCIError;\n      locp: POCILobLocator): sword;\n    function LobErase(svchp: POCISvcCtx; errhp: POCIError; locp: POCILobLocator;\n      var amount: ub4; offset: ub4): sword;\n    function LobFileExists(svchp: POCISvcCtx; errhp: POCIError;\n      filep: POCILobLocator; var flag: Boolean): sword;\n    function LobFileGetName(envhp: POCIEnv; errhp: POCIError;\n      filep: POCILobLocator; dir_alias: text; var d_length: ub2; filename: text;\n      var f_length: ub2): sword;\n    function LobFileSetName(envhp: POCIEnv; errhp: POCIError;\n      var filep: POCILobLocator; dir_alias: text; d_length: ub2; filename: text;\n      f_length: ub2): sword;\n    function LobFlushBuffer(svchp: POCISvcCtx; errhp: POCIError;\n      locp: POCILobLocator; flag: ub4): sword;\n    function LobGetLength(svchp: POCISvcCtx; errhp: POCIError;\n      locp: POCILobLocator; var lenp: ub4): sword;\n    function LobIsOpen(svchp: POCISvcCtx; errhp: POCIError;\n      locp: POCILobLocator; var flag: LongBool): sword;\n    function LobLoadFromFile(svchp: POCISvcCtx; errhp: POCIError;\n      dst_locp: POCILobLocator; src_locp: POCILobLocator; amount: ub4;\n      dst_offset: ub4; src_offset: ub4): sword;\n    function LobLocatorIsInit(envhp: POCIEnv; errhp: POCIError;\n     locp: POCILobLocator; var is_initialized: LongBool): sword;\n    function LobOpen(svchp: POCISvcCtx; errhp: POCIError;\n      locp: POCILobLocator; mode: ub1): sword;\n    function LobRead(svchp: POCISvcCtx; errhp: POCIError;\n      locp: POCILobLocator; var amtp: ub4; offset: ub4; bufp: Pointer; bufl: ub4;\n      ctxp: Pointer; cbfp: Pointer; csid: ub2; csfrm: ub1): sword;\n    function LobTrim(svchp: POCISvcCtx; errhp: POCIError;\n      locp: POCILobLocator; newlen: ub4): sword;\n    function LobWrite(svchp: POCISvcCtx; errhp: POCIError;\n      locp: POCILobLocator; var amtp: ub4; offset: ub4; bufp: Pointer; bufl: ub4;\n      piece: ub1; ctxp: Pointer; cbfp: Pointer; csid: ub2; csfrm: ub1): sword;\n    function LobCreateTemporary(svchp: POCISvcCtx; errhp: POCIError;\n      locp: POCILobLocator; csid: ub2; csfrm: ub1; lobtype: ub1;\n      cache: LongBool; duration: OCIDuration): sword;\n    function LobIsTemporary(svchp: POCISvcCtx; errhp: POCIError;\n      locp: POCILobLocator; var is_temporary: LongBool): sword;\n    function LobFreeTemporary(svchp: POCISvcCtx; errhp: POCIError;\n      locp: POCILobLocator): sword;\n    function LobCharSetForm ( envhp: POCIEnv; errhp: POCIError;\n        const locp: POCILobLocator; csfrm: pub1): sword;\n    function LobCharSetId ( envhp: POCIEnv; errhp: POCIError;\n        const locp: POCILobLocator; csid: pub2): sword;\n\n    function StmtGetPieceInfo(stmtp: POCIStmt; errhp: POCIError;\n      var hndlpp: Pointer; var typep: ub4; var in_outp: ub1; var iterp: ub4;\n      var idxp: ub4; var piecep: ub1): sword;\n    function StmtSetPieceInfo(handle: Pointer; typep: ub4; errhp: POCIError;\n      buf: Pointer; var alenp: ub4; piece: ub1; indp: Pointer;\n      var rcodep: ub2): sword;\n    function PasswordChange(svchp: POCISvcCtx; errhp: POCIError;\n      user_name: text; usernm_len: ub4; opasswd: text; opasswd_len: ub4;\n      npasswd: text; npasswd_len: sb4; mode: ub4): sword;\n    function ServerVersion(hndlp: POCIHandle; errhp: POCIError; bufp: text;\n      bufsz: ub4; hndltype: ub1): sword;\n    function ServerRelease(hndlp: POCIHandle;\n      errhp: POCIError; bufp: text; bufsz: ub4; hndltype: ub1; version:pointer): sword;\n    function ResultSetToStmt(rsetdp: POCIHandle; errhp: POCIError): sword;\n\n    function GetEnvCharsetByteWidth(hndl: POCIEnv; err: POCIError;\n      Value: sb4): sword;\n    procedure ClientVersion(major_version, minor_version, update_num,\n      patch_num, port_update_num: psword);\n\n    function NumberInc(err: POCIError; number: POCINumber): sword;\n    function NumberDec(err: POCIError; number: POCINumber): sword;\n    procedure NumberSetZero(err: POCIError; number: POCINumber);\n    procedure NumberSetPi(err: POCIError; number: POCINumber);\n    function  NumberAdd(err: POCIError; const number1: POCINumber;\n      const number2: POCINumber; _result: POCINumber): sword;\n    function NumberSub(err: POCIError; const number1: POCINumber;\n      const number2: POCINumber; _result: POCINumber): sword;\n    function NumberMul(err: POCIError; const number1: POCINumber;\n      const number2: POCINumber; _result: POCINumber): sword;\n    function NumberDiv(err: POCIError; const number1: POCINumber;\n      const number2: POCINumber; _result: POCINumber): sword;\n    function NumberMod(err: POCIError; const number1: POCINumber;\n      const number2: POCINumber; _result: POCINumber): sword;\n    function NumberIntPower(err: POCIError; const number1: POCINumber;\n      const number2: POCINumber; _result: POCINumber): sword;\n    function NumberShift(err: POCIError; const number: POCINumber;\n      const nDig: sword; _result: POCINumber): sword;\n    function NumberNeg(err: POCIError; const number: POCINumber;\n      _result: POCINumber): sword;\n    function NumberToText(err: POCIError; const number: POCINumber;\n      const fmt: Poratext; fmt_length: ub4; const nls_params: Poratext;\n      nls_p_length: ub4; buf_size: pub4; buf: poratext): sword;\n    function NumberFromText(err: POCIError; const str: poratext;\n      str_length: ub4; const fmt: poratext; fmt_length: ub4;\n      const nls_params: poratext; nls_p_length: ub4; number: POCINumber): sword;\n    function NumberToInt(err: POCIError; const number: POCINumber;\n      rsl_length: uword; rsl_flag: uword; rsl: Pointer): sword;\n    function NumberFromInt(err: POCIError; const inum: Pointer;\n      inum_length: uword; inum_s_flag: uword; number: POCINumber): sword;\n    function NumberToReal(err: POCIError; const number: POCINumber;\n      rsl_length: uword; rsl: Pointer): sword;\n    function NumberToRealArray(err: POCIError; const number: PPOCINumber;\n      elems: uword; rsl_length: uword; rsl: Pointer): sword;\n    function NumberFromReal(err: POCIError; const rnum: Pointer;\n      rnum_length: uword; number: POCINumber): sword;\n    function NumberCmp(err: POCIError; const number1: POCINumber;\n      const number2: POCINumber; _result: psword): sword;\n    function NumberSign(err: POCIError; const number: POCINumber;\n      _result: psword): sword;\n    function NumberIsZero(err: POCIError; const number: POCINumber;\n      _Result: pboolean): sword;\n    function NumberIsInt(err: POCIError; const number: POCINumber;\n      _result: Pboolean): sword;\n    function NumberAssign(err: POCIError; const from: POCINumber;\n      _to: POCINumber): sword;\n    function NumberAbs(err: POCIError; const number: POCINumber;\n      _result: POCINumber): sword;\n    function NumberCeil(err: POCIError; const number: POCINumber;\n      _result: POCINumber): sword;\n    function NumberFloor(err: POCIError; const number: POCINumber;\n      _result: POCINumber): sword;\n    function NumberSqrt(err: POCIError; const number: POCINumber;\n      _result: POCINumber): sword;\n    function NumberTrunc(err: POCIError; const number: POCINumber;\n      _result: POCINumber): sword;\n    function NumberPower(err: POCIError; const base: POCINumber;\n      const number: POCINumber; _result: POCINumber): sword;\n    function NumberRound(err: POCIError; const number: POCINumber;\n      decplace: sword; _result: POCINumber): sword;\n    function NumberPrec(err: POCIError; const number: POCINumber;\n      nDigs: sword; _result: POCINumber): sword;\n    function NumberSin(err: POCIError; const number: POCINumber;\n      _result: POCINumber): sword;\n    function NumberArcSin(err: POCIError; const number: POCINumber;\n      _result: POCINumber): sword;\n    function NumberHypSin(err: POCIError; const number: POCINumber;\n      _result: POCINumber): sword;\n    function NumberCos(err: POCIError; const number: POCINumber;\n      _result: POCINumber): sword;\n    function NumberArcCos(err: POCIError; const number: POCINumber;\n      _result: POCINumber): sword;\n    function NumberHypCos(err: POCIError; const number: POCINumber;\n      _result: POCINumber): sword;\n    function NumberTan(err: POCIError; const number: POCINumber;\n      _result: POCINumber): sword;\n    function NumberArcTan(err: POCIError; const number: POCINumber;\n      _result: POCINumber): sword;\n    function NumberArcTan2(err: POCIError; const number1: POCINumber;\n      const number2: POCINumber; _result: POCINumber): sword;\n    function NumberHypTan(err: POCIError; const number: POCINumber;\n      _result: POCINumber): sword;\n    function NumberExp(err: POCIError; const number: POCINumber;\n      _result: POCINumber): sword;\n    function NumberLn(err: POCIError; const number: POCINumber;\n      _result: POCINumber): sword;\n    function NumberLog(err: POCIError; const base: POCINumber;\n      const number: POCINumber; _result: POCINumber): sword;\n\n    function TableSize(hndl: POCIEnv; err: POCIError; const tbl: POCITable;\n                    size: psb4): sword;\n    function TableExists(hndl: POCIEnv; err: POCIError; const tbl: POCITable;\n                             index: sb4; exists: PBoolean): sword;\n    function TableDelete(hndl: POCIEnv; err: POCIError; index: sb4;\n                      tbl: POCITable): sword;\n    function TableFirst(hndl: POCIEnv; err: POCIError; const tbl: POCITable;\n                             index: sb4): sword;\n    function TableLast(hndl: POCIEnv; err: POCIError; const tbl: POCITable;\n                             index: sb4): sword;\n    function TableNext(hndl: POCIEnv; err: POCIError; index: sb4;\n      const tbl: POCITable; next_index: psb4; exists: PBoolean): sword;\n    function TablePrev(hndl: POCIEnv; err: POCIError; index: sb4;\n      const tbl: POCITable; prev_index: psb4; exists: PBoolean): sword;\n    function ObjectSetAttr(env: POCIEnv; err: POCIError; instance: Pointer;\n                  null_struct: pointer; tdo: POCIType; const names: PPAnsiChar;\n                  const lengths: pub4; const name_count: ub4;\n                  const indexes: pub4; const index_count: ub4;\n                  const null_status: POCIInd; const attr_null_struct: Pointer;\n                  const attr_value: Pointer): sword; cdecl;\n    function ObjectGetAttr(env: POCIEnv; err: POCIError; instance: Pointer;\n                  null_struct: Pointer; tdo: POCIType;\n                  const names: PPoratext; const lengths: pub4;\n                  const name_count: ub4; const indexes: pub4;\n                  const index_count: ub4; attr_null_status: POCIInd;\n                  attr_null_struct, attr_value: PPointer;\n                  attr_tdo: PPOCIType): sword;\n    {ociap.h}\n    function Ping(svchp: POCISvcCtx; errhp: POCIError; mode: ub4 = OCI_DEFAULT): sword;\n    {ort.h}\n    function TypeIterNew(env: POCIEnv; err: POCIError; const tdo: POCIType;\n                      iterator_ort: PPOCITypeIter):sword;\n    function TypeIterSet(env: POCIEnv; err: POCIError; const tdo: POCIType;\n                              iterator_ort: POCITypeIter): sword;\n    function TypeIterFree(env: POCIEnv; err: POCIError;\n                        iterator_ort: POCITypeIter): sword;\n    function TypeByName(env: POCIEnv; err: POCIError; const svc: POCISvcCtx;\n      schema_name: Poratext; const s_length: ub4; const type_name: Poratext;\n      const t_length: ub4; version_name: Poratext; const v_length: ub4;\n      const pin_duration: OCIDuration; const get_option: OCITypeGetOpt;\n      tdo: PPOCIType): sword;\n    function TypeArrayByName(env: POCIEnv; err: POCIError; svc: POCISvcCtx;\n      array_len: ub4; schema_name:  PPoratext; s_length: Pub4;\n      type_name: PPoratext; t_length: Pub4; version_name: PPoratext;\n      v_length: Pub4; pin_duration: OCIDuration; get_option: OCITypeGetOpt;\n      tdo: PPOCIType): sword;\n    function TypeByRef(env: POCIEnv; err: POCIError; type_ref: POCIRef;\n      pin_duration: OCIDuration; get_option: OCITypeGetOpt;\n      tdo: PPOCIType): sword;\n    function TypeArrayByRef(env: POCIEnv; err: POCIError; array_len: ub4;\n      type_ref: PPOCIRef; pin_duration: OCIDuration; get_option: OCITypeGetOpt;\n      tdo: PPOCIType): sword;\n    function TypeName(env: POCIEnv; err: POCIError; tdo: POCIType;\n      n_length: Pub4): poratext;\n    function TypeSchema(env: POCIEnv; err: POCIError; const tdo: POCIType;\n      n_length: Pub4): poratext;\n    function TypeTypeCode(env: POCIEnv; err: POCIError;\n                  const tdo: POCIType): OCITypeCode;\n    function TypeCollTypeCode(env:POCIEnv; err:POCIError;\n      const tdo: POCIType): OCITypeCode;\n    function TypeVersion(env: POCIEnv; err: POCIError; const tdo: POCIType;\n      v_length: Pub4): poratext;\n    function TypeAttrs(env: POCIEnv; err: POCIError;\n      const tdo:POCIType): ub4;\n    function TypeMethods(env: POCIEnv; err: POCIError;\n      const tdo: POCIType): ub4;\n    function TypeElemName(env: POCIEnv; err: POCIError;\n      const elem: POCITypeElem; n_length:Pub4): poratext;\n    function TypeElemTypeCode(env: POCIEnv; err: POCIError;\n      const elem: POCITypeElem): OCITypeCode;\n    function TypeElemType(env: POCIEnv; err: POCIError;\n      const elem: POCITypeElem; elem_tdo:PPOCIType): sword;\n    function TypeElemFlags(env: POCIEnv; err: POCIError;\n      const elem: POCITypeElem): ub4;\n    function TypeElemNumPrec(env: POCIEnv; err: POCIError;\n      const elem: POCITypeElem): ub1;\n    function TypeElemNumScale(env: POCIEnv; err: POCIError;\n      const elem: POCITypeElem): sb1;\n    function TypeElemLength(env: POCIEnv; err: POCIError;\n      const elem:POCITypeElem): ub4;\n    function TypeElemCharSetID(env: POCIEnv; err: POCIError;\n      const elem: POCITypeElem): ub2;\n    function TypeElemCharSetForm(env: POCIEnv; err: POCIError;\n      const elem: POCITypeElem): ub2;\n    function TypeElemParameterizedType(env: POCIEnv; err: POCIError;\n      const elem: POCITypeElem; type_stored: PPOCIType): sword;\n    function TypeElemExtTypeCode(env: POCIEnv; err: POCIError;\n      const elem: POCITypeElem): OCITypeCode;\n    function TypeAttrByName(env: POCIEnv; err: POCIError;\n      const tdo: POCIType; const name: Poratext; const n_length: ub4;\n      elem: PPOCITypeElem): sword;\n    function TypeAttrNext(env: POCIEnv; err: POCIError;\n      iterator_ort: POCITypeIter; elem: PPOCITypeElem): sword;\n    function TypeCollElem(env: POCIEnv; err: POCIError; const tdo:POCIType;\n      element: PPOCITypeElem): sword;\n    function TypeCollSize(env: POCIEnv; err: POCIError; const tdo: POCIType;\n      num_elems: Pub4): sword;\n    function TypeCollExtTypeCode(env: POCIEnv; err: POCIError;\n      const tdo:POCIType; sqt_code: POCITypeCode): sword;\n    function TypeMethodOverload(env: POCIEnv; err: POCIError;\n      const tdo: POCIType; const method_name: Poratext;\n      const m_length: ub4): ub4;\n    function TypeMethodByName(env: POCIEnv; err: POCIError;\n      const tdo: POCIType; const method_name: Poratext; const m_length: ub4;\n      mdos: PPOCITypeMethod): sword;\n    function TypeMethodNext(env: POCIEnv; err: POCIError;\n      iterator_ort: POCITypeIter; mdo: PPOCITypeMethod): sword;\n    function TypeMethodName(env:POCIEnv; err: POCIError;\n      const mdo: POCITypeMethod; n_length: Pub4): poratext;\n    function TypeMethodEncap(env: POCIEnv; err: POCIError;\n      const mdo: POCITypeMethod): OCITypeEncap;\n    function TypeMethodFlags(env: POCIEnv; err: POCIError;\n        const mdo:POCITypeMethod): OCITypeMethodFlag;\n    function TypeMethodMap(env: POCIEnv; err: POCIError; const tdo: POCIType;\n      mdo: PPOCITypeMethod): sword;\n    function TypeMethodOrder(env: POCIEnv; err: POCIError;\n      const tdo: POCIType; mdo: PPOCITypeMethod): sword;\n    function TypeMethodParams(env: POCIEnv; err: POCIError;\n      const mdo: POCITypeMethod): ub4;\n    function TypeResult(env: POCIEnv; err: POCIError;\n      const mdo: POCITypeMethod; elem: PPOCITypeElem): sword;\n    function TypeParamByPos(env: POCIEnv; err: POCIError;\n      const mdo: POCITypeMethod; const position: ub4;\n      elem: PPOCITypeElem): sword;\n    function TypeParamByName(env: POCIEnv; err: POCIError;\n      const mdo: POCITypeMethod; const name: Poratext; const n_length: ub4;\n      elem:PPOCITypeElem): sword;\n    function TypeParamPos(env: POCIEnv; err: POCIError;\n      const mdo: POCITypeMethod; const name: Poratext; const n_length: ub4;\n      position: Pub4; elem: PPOCITypeElem): sword;\n    function TypeElemParamMode(env: POCIEnv; err: POCIError;\n      const elem: POCITypeElem): OCITypeParamMode;\n    function TypeElemDefaultValue(env: POCIEnv; err: POCIError;\n      const elem: POCITypeElem; d_v_length: Pub4): poratext;\n    function TypeVTInit(env: POCIEnv; err: POCIError): sword;\n    function TypeVTInsert(env: POCIEnv; err: POCIError;\n      const schema_name: Poratext; const s_n_length: ub4;\n      const type_name: Poratext; const t_n_length: ub4;\n      const user_version:Poratext; const u_v_length:ub4): sword;\n    function TypeVTSelect(env: POCIEnv; err: POCIError;\n      const schema_name: Poratext; const s_n_length: ub4;\n      const type_name: Poratext; const t_n_length: ub4; user_version: PPoratext;\n      u_v_length: Pub4; version: Pub2): sword;\n  end;\n\n  {** Implements a driver for Oracle 9i }\n  TZOracle9iPlainDriver = class (TZAbstractPlainDriver, IZPlainDriver,\n    IZOraclePlainDriver)\n  private\n    OracleAPI: OracleOCI_API;\n  protected\n    procedure LoadApi; override;\n    function Clone: IZPlainDriver; override;\n  public\n    constructor Create;\n\n    function GetUnicodeCodePageName: String; override;\n    procedure LoadCodePages; override;\n    function GetProtocol: string; override;\n    function GetDescription: string; override;\n    procedure Initialize(const Location: String); override;\n\n    function Initializ(mode: ub4; ctxp: Pointer; malocfp: Pointer;\n      ralocfp: Pointer; mfreefp: Pointer): sword;\n    function EnvInit(var envhpp: POCIEnv; mode: ub4; xtramemsz: size_T;\n      usrmempp: PPointer): sword;\n    function EnvCreate(var envhpp: POCIEnv; mode: ub4; ctxp: Pointer;\n      malocfp: Pointer; ralocfp: Pointer; mfreefp: Pointer; xtramemsz: size_T;\n      usrmempp: PPointer): sword;\n    function EnvNlsCreate(var envhpp: POCIEnv; mode: ub4; ctxp: Pointer;\n      malocfp: Pointer; ralocfp: Pointer; mfreefp: Pointer; xtramemsz: size_T;\n      usrmempp: PPointer; charset, ncharset: ub2): sword;\n\n    function HandleAlloc(parenth: POCIHandle; var hndlpp: POCIHandle;\n      atype: ub4; xtramem_sz: size_T; usrmempp: PPointer): sword;\n    function ServerAttach(srvhp: POCIServer; errhp: POCIError; dblink: text;\n      dblink_len: sb4; mode: ub4): sword;\n    function AttrSet(trgthndlp: POCIHandle; trghndltyp: ub4;\n      attributep: Pointer; size: ub4; attrtype: ub4; errhp: POCIError):sword;\n    function SessionBegin(svchp: POCISvcCtx; errhp: POCIError;\n      usrhp: POCISession; credt: ub4; mode: ub4):sword;\n    function SessionEnd(svchp: POCISvcCtx; errhp: POCIError;\n      usrhp: POCISession; mode: ub4): sword;\n    function ServerDetach(srvhp: POCIServer; errhp: POCIError;\n      mode: ub4): sword;\n    function HandleFree(hndlp: Pointer; atype: ub4): sword;\n    function ErrorGet(hndlp: Pointer; recordno: ub4; sqlstate: text;\n      var errcodep: sb4; bufp: text; bufsiz: ub4; atype: ub4): sword;\n\n    function StmtPrepare(stmtp: POCIStmt; errhp: POCIError; stmt: text;\n      stmt_len: ub4; language:ub4; mode: ub4):sword;\n    function StmtExecute(svchp: POCISvcCtx; stmtp: POCIStmt;\n      errhp: POCIError; iters: ub4; rowoff: ub4; snap_in: POCISnapshot;\n      snap_out: POCISnapshot; mode: ub4): sword;\n    function ParamGet(hndlp: Pointer; htype: ub4; errhp: POCIError;\n      var parmdpp: Pointer; pos: ub4): sword;\n    function AttrGet(trgthndlp: POCIHandle; trghndltyp: ub4;\n      attributep: Pointer; sizep: Pointer; attrtype: ub4;\n      errhp: POCIError): sword;\n    function StmtFetch(stmtp: POCIStmt; errhp: POCIError; nrows: ub4;\n      orientation: ub2; mode: ub4): sword;\n    function DefineByPos(stmtp: POCIStmt; var defnpp: POCIDefine;\n      errhp: POCIError; position: ub4; valuep: Pointer; value_sz: sb4; dty: ub2;\n      indp: Pointer; rlenp: Pointer; rcodep: Pointer; mode: ub4): sword;\n    function DefineArrayOfStruct(defnpp: POCIDefine; errhp: POCIError;\n      pvskip: ub4; indskip: ub4; rlskip: ub4; rcskip: ub4): sword;\n\n    function BindByPos(stmtp: POCIStmt; var bindpp: POCIBind;\n      errhp: POCIError; position: ub4; valuep: Pointer; value_sz: sb4; dty: ub2;\n      indp: Pointer; alenp: Pointer; rcodep: Pointer; maxarr_len: ub4;\n      curelep: Pointer; mode: ub4): sword;\n    function BindByName(stmtp: POCIStmt; var bindpp: POCIBind;\n      errhp: POCIError; placeholder: text; placeh_len: sb4; valuep: Pointer;\n      value_sz: sb4; dty: ub2; indp: Pointer; alenp: Pointer; rcodep: Pointer;\n      maxarr_len: ub4; curelep: Pointer; mode: ub4): sword;\n    function BindDynamic(bindp: POCIBind; errhp: POCIError; ictxp: Pointer;\n      icbfp: Pointer; octxp: Pointer; ocbfp: Pointer): sword;\n    function BindObject(bindp: POCIBind; errhp: POCIError;\n                    const _type: POCIType; pgvpp: PPointer;\n                    pvszsp: pub4; indpp: PPointer;\n                    indszp: pub4): sword;\n\n    function DefineObject(defnpp:POCIDefine; errhp:POCIError;\n      _type:POCIHandle; pgvpp,pvszsp,indpp,indszp:pointer): sword;\n\n    { > ori.h}\n    function ObjectNew(env: POCIEnv; err: POCIError; const svc: POCISvcCtx;\n                       typecode: OCITypeCode; tdo: POCIType; table: Pointer;\n                       duration: OCIDuration; value: Longbool;\n                       instance: PPointer): sword;\n    function ObjectPin(env: POCIEnv; err: POCIError;\n      const object_ref: POCIRef; const corhdl: POCIComplexObject;\n      const pin_option: OCIPinOpt; const pin_duration: OCIDuration;\n      const lock_option: OCILockOpt; _object: PPointer): sword;\n    function ObjectUnpin(env: POCIEnv; err: POCIError;\n      const _object: Pointer): sword;\n    function ObjectPinCountReset(env: POCIEnv; err: POCIError;\n      const _object: pointer): sword;\n    function ObjectLock(env: POCIEnv; err: POCIError;\n      const _object: pointer): sword;\n    function ObjectLockNoWait(env: POCIEnv; err: POCIError;\n      const _object: pointer): sword;\n    function ObjectMarkUpdate(env: POCIEnv; err: POCIError;\n      const _object: pointer): sword;\n    function ObjectUnmark(env: POCIEnv; err: POCIError;\n      const _object:pointer): sword;\n    function ObjectUnmarkByRef(env: POCIEnv; err: POCIError;\n      const ref: POCIRef): sword;\n    function ObjectFree(hndl: POCIEnv; err: POCIError;\n      instance:POCIHandle;flags :ub2):sword;\n    function ObjectMarkDeleteByRef(env: POCIEnv; err: POCIError;\n      const object_ref:POCIRef): sword;\n    function ObjectMarkDelete(env: POCIEnv; err: POCIError;\n      const instance:pointer): sword;\n    function ObjectFlush(env: POCIEnv; err: POCIError;\n      const _object: pointer): sword;\n    function ObjectRefresh(env: POCIEnv; err: POCIError;\n      _object: pointer): sword;\n    function ObjectCopy(env: POCIEnv; err: POCIError; const svc: POCISvcCtx;\n      const source, null_source, target, null_target: pointer; const tdo: POCIType;\n      const duration: OCIDuration; const option: ub1): sword;\n    function ObjectGetTypeRef(env: POCIEnv; err: POCIError;\n      const instance:pointer; type_ref: POCIRef): sword;\n    function ObjectGetObjectRef(env: POCIEnv; err: POCIError;\n      const _object: pointer; object_ref: POCIRef): sword;\n    function ObjectMakeObjectRef(env: POCIEnv; err: POCIError;\n      const svc: POCISvcCtx; const table: pointer; const values: PPointer;\n      const array_len: ub4; object_ref: POCIRef): sword;\n    function ObjectGetPrimaryKeyTypeRef(env: POCIEnv; err: POCIError;\n      const svc:POCISvcCtx; const table: pointer; type_ref: POCIRef): sword;\n    function ObjectGetInd(env: POCIEnv; err: POCIError;\n      const instance: pointer; null_struct: PPointer): sword;\n    function ObjectExists(env: POCIEnv; err: POCIError; const ins: pointer;\n      exist: PBoolean): sword;\n    function ObjectGetProperty(envh: POCIEnv; errh: POCIError;\n      const obj: pointer; const propertyId: OCIObjectPropId;\n      _property: pointer; size: Pub4): sword;\n    function ObjectIsLocked(env: POCIEnv; err: POCIError; const ins: pointer;\n      lock: Pboolean): sword;\n    function ObjectIsDirty(env: POCIEnv; err: POCIError; const ins: pointer;\n      dirty: PBoolean): sword;\n    function ObjectPinTable(env: POCIEnv; err: POCIError;\n      const svc:POCISvcCtx; const schema_name: Poratext; const s_n_length: ub4;\n      const object_name: Poratext; const o_n_length:ub4;\n      const scope_obj_ref: POCIRef; const pin_duration: OCIDuration;\n      _object: PPointer): sword;\n    function ObjectArrayPin(env: POCIEnv; err: POCIError;\n      const ref_array: PPOCIRef; const array_size: ub4;\n      const cor_array: PPOCIComplexObject; const cor_array_size: ub4;\n      const pin_option: OCIPinOpt; const pin_duration: OCIDuration;\n      const lock: OCILockOpt; obj_array: PPointer;\n      pos: Pub4): sword;\n    function CacheFlush(env: POCIEnv; err: POCIError; const svc:POCISvcCtx;\n      const context: pointer; const get: TOCICacheFlushGet;\n      ref: PPOCIRef): sword;\n    function CacheRefresh(env: POCIEnv; err: POCIError;\n      const svc:POCISvcCtx; const option: OCIRefreshOpt; const context: pointer;\n      get: TOCICacheRefreshGet; ref: PPOCIRef): sword;\n    function CacheUnpin(env: POCIEnv; err: POCIError;\n      const svc:POCISvcCtx): sword;\n    function CacheFree(env: POCIEnv; err: POCIError;\n      const svc: POCISvcCtx): sword;\n    function CacheUnmark(env: POCIEnv; err: POCIError;\n      const svc: POCISvcCtx): sword;\n    function DurationBegin(env: POCIEnv; err: POCIError;\n      svc: POCISvcCtx; const parent: OCIDuration;\n      dur: POCIDuration): sword;\n    function DurationEnd(env: POCIEnv; err: POCIError; svc: POCISvcCtx;\n      duration: OCIDuration): sword;\n    { < ori.h}\n\n    function TransStart(svchp: POCISvcCtx; errhp: POCIError; timeout: word;\n      flags: ub4): sword;\n    function TransRollback(svchp:POCISvcCtx; errhp:POCIError;\n      flags: ub4): sword;\n    function TransCommit(svchp: POCISvcCtx; errhp: POCIError;\n      flags: ub4): sword;\n    function TransDetach(svchp: POCISvcCtx; errhp: POCIError;\n      flags: ub4): sword;\n    function TransPrepare(svchp: POCISvcCtx; errhp: POCIError;\n      flags: ub4): sword;\n    function TransForget(svchp: POCISvcCtx; errhp: POCIError;\n      flags: ub4): sword;\n\n    function DescribeAny(svchp: POCISvcCtx; errhp: POCIError;\n      objptr: Pointer; objnm_len: ub4; objptr_typ: ub1; info_level: ub1;\n      objtyp: ub1; dschp: POCIDescribe): sword;\n    function Break(svchp: POCISvcCtx; errhp:POCIError): sword;\n    function Reset(svchp: POCISvcCtx; errhp:POCIError): sword;\n    function DescriptorAlloc(parenth: POCIEnv; var descpp: POCIDescriptor;\n      htype: ub4; xtramem_sz: integer; usrmempp: Pointer): sword;\n    function DescriptorFree(descp: Pointer; htype: ub4): sword;\n\n    function DateTimeAssign(hndl: POCIEnv; err: POCIError;\n      const from: POCIDateTime;_to: POCIDateTime): sword;\n    function DateTimeCheck(hndl: POCIEnv; err: POCIError;\n      const date: POCIDateTime; var valid: ub4): sword;\n    function DateTimeCompare(hndl: POCIEnv; err: POCIError;\n      const date1: POCIDateTime; const date2: POCIDateTime;\n      var _result: sword): sword;\n    function DateTimeConvert(hndl: POCIEnv; err: POCIError;\n      indate: POCIDateTime; outdate: POCIDateTime): sword;\n    function DateTimeFromText(hndl: POCIEnv; err: POCIError;\n      const date_str: text; d_str_length: size_t; const fmt: text;\n      fmt_length: ub1; const lang_name: text; lang_length: size_t;\n      date: POCIDateTime): sword;\n    function DateTimeGetDate(hndl: POCIEnv; err: POCIError;\n      const date: POCIDateTime; var year: sb2; var month: ub1;\n      var day: ub1): sword;\n    function DateTimeGetTime(hndl: POCIEnv; err: POCIError;\n      datetime: POCIDateTime; var hour: ub1; var minute: ub1; var sec: ub1;\n      var fsec: ub4): sword;\n    function DateTimeGetTimeZoneOffset(hndl: POCIEnv; err: POCIError;\n      const datetime: POCIDateTime; var hour: sb1; var minute: sb1): sword;\n    function DateTimeSysTimeStamp(hndl: POCIEnv; err: POCIError;\n      sys_date: POCIDateTime): sword;\n    function DateTimeConstruct(hndl: POCIEnv; err: POCIError;\n      datetime: POCIDateTime; year: sb2; month: ub1; day: ub1; hour: ub1;\n      min: ub1; sec: ub1; fsec: ub4; timezone: text;\n      timezone_length: size_t): sword;\n    function DateTimeToText(hndl: POCIEnv; err: POCIError;\n      const date: POCIDateTime; const fmt: text; fmt_length: ub1;\n      fsprec: ub1; const lang_name: text; lang_length: size_t;\n      var buf_size: ub4; buf: text): sword;\n    function DateTimeGetTimeZoneName(hndl: POCIEnv; err: POCIError;\n      datetime: POCIDateTime; var buf: ub1; var buflen: ub4): sword;\n\n    function LobAppend(svchp: POCISvcCtx; errhp: POCIError; dst_locp,\n      src_locp: POCILobLocator): sword;\n    function LobAssign(svchp: POCISvcCtx; errhp: POCIError;\n      src_locp: POCILobLocator; var dst_locpp: POCILobLocator): sword;\n    function LobClose(svchp: POCISvcCtx; errhp: POCIError;\n      locp: POCILobLocator): sword;\n    function LobCopy(svchp: POCISvcCtx; errhp: POCIError;\n      dst_locp: POCILobLocator; src_locp: POCILobLocator; amount: ub4;\n      dst_offset: ub4; src_offset: ub4): sword;\n    function LobEnableBuffering(svchp: POCISvcCtx; errhp: POCIError;\n      locp: POCILobLocator): sword;\n    function LobDisableBuffering(svchp: POCISvcCtx; errhp: POCIError;\n      locp: POCILobLocator): sword;\n    function LobErase(svchp: POCISvcCtx; errhp: POCIError; locp: POCILobLocator;\n      var amount: ub4; offset: ub4): sword;\n    function LobFileExists(svchp: POCISvcCtx; errhp: POCIError;\n      filep: POCILobLocator; var flag: Boolean): sword;\n    function LobFileGetName(envhp: POCIEnv; errhp: POCIError;\n      filep: POCILobLocator; dir_alias: text; var d_length: ub2; filename: text;\n      var f_length: ub2): sword;\n    function LobFileSetName(envhp: POCIEnv; errhp: POCIError;\n      var filep: POCILobLocator; dir_alias: text; d_length: ub2; filename: text;\n      f_length: ub2): sword;\n    function LobFlushBuffer(svchp: POCISvcCtx; errhp: POCIError;\n      locp: POCILobLocator; flag: ub4): sword;\n    function LobGetLength(svchp: POCISvcCtx; errhp: POCIError;\n      locp: POCILobLocator; var lenp: ub4): sword;\n    function LobIsOpen(svchp: POCISvcCtx; errhp: POCIError;\n      locp: POCILobLocator; var flag: LongBool): sword;\n    function LobLoadFromFile(svchp: POCISvcCtx; errhp: POCIError;\n      dst_locp: POCILobLocator; src_locp: POCILobLocator; amount: ub4;\n      dst_offset: ub4; src_offset: ub4): sword;\n    function LobLocatorIsInit(envhp: POCIEnv; errhp: POCIError;\n     locp: POCILobLocator; var is_initialized: LongBool): sword;\n    function LobOpen(svchp: POCISvcCtx; errhp: POCIError;\n      locp: POCILobLocator; mode: ub1): sword;\n    function LobRead(svchp: POCISvcCtx; errhp: POCIError;\n      locp: POCILobLocator; var amtp: ub4; offset: ub4; bufp: Pointer; bufl: ub4;\n      ctxp: Pointer; cbfp: Pointer; csid: ub2; csfrm: ub1): sword;\n    function LobTrim(svchp: POCISvcCtx; errhp: POCIError;\n      locp: POCILobLocator; newlen: ub4): sword;\n    function LobWrite(svchp: POCISvcCtx; errhp: POCIError;\n      locp: POCILobLocator; var amtp: ub4; offset: ub4; bufp: Pointer; bufl: ub4;\n      piece: ub1; ctxp: Pointer; cbfp: Pointer; csid: ub2; csfrm: ub1): sword;\n    function LobCreateTemporary(svchp: POCISvcCtx; errhp: POCIError;\n      locp: POCILobLocator; csid: ub2; csfrm: ub1; lobtype: ub1;\n      cache: LongBool; duration: OCIDuration): sword;\n    function LobIsTemporary(svchp: POCISvcCtx; errhp: POCIError;\n      locp: POCILobLocator; var is_temporary: LongBool): sword;\n    function LobFreeTemporary(svchp: POCISvcCtx; errhp: POCIError;\n      locp: POCILobLocator): sword;\n    function LobCharSetForm ( envhp: POCIEnv; errhp: POCIError;\n        const locp: POCILobLocator; csfrm: pub1): sword;\n    function LobCharSetId ( envhp: POCIEnv; errhp: POCIError;\n        const locp: POCILobLocator; csid: pub2): sword;\n\n    function StmtGetPieceInfo(stmtp: POCIStmt; errhp: POCIError;\n      var hndlpp: Pointer; var typep: ub4; var in_outp: ub1; var iterp: ub4;\n      var idxp: ub4; var piecep: ub1): sword;\n    function StmtSetPieceInfo(handle: Pointer; typep: ub4; errhp: POCIError;\n      buf: Pointer; var alenp: ub4; piece: ub1; indp: Pointer;\n      var rcodep: ub2): sword;\n    function PasswordChange(svchp: POCISvcCtx; errhp: POCIError;\n      user_name: text; usernm_len: ub4; opasswd: text; opasswd_len: ub4;\n      npasswd: text; npasswd_len: sb4; mode: ub4): sword;\n    function ServerVersion(hndlp: POCIHandle; errhp: POCIError; bufp: text;\n      bufsz: ub4; hndltype: ub1): sword;\n    function ServerRelease(hndlp: POCIHandle;\n      errhp: POCIError; bufp: text; bufsz: ub4; hndltype: ub1; version:pointer): sword;\n    function ResultSetToStmt(rsetdp: POCIHandle; errhp: POCIError): sword;\n    function GetEnvCharsetByteWidth(hndl: POCIEnv; err: POCIError;\n      Value: sb4): sword;\n    procedure ClientVersion(major_version, minor_version, update_num,\n      patch_num, port_update_num: psword);\n\n    function NumberInc(err: POCIError; number: POCINumber): sword;\n    function NumberDec(err: POCIError; number: POCINumber): sword;\n    procedure NumberSetZero(err: POCIError; number: POCINumber);\n    procedure NumberSetPi(err: POCIError; number: POCINumber);\n    function  NumberAdd(err: POCIError; const number1: POCINumber;\n      const number2: POCINumber; _result: POCINumber): sword;\n    function NumberSub(err: POCIError; const number1: POCINumber;\n      const number2: POCINumber; _result: POCINumber): sword;\n    function NumberMul(err: POCIError; const number1: POCINumber;\n      const number2: POCINumber; _result: POCINumber): sword;\n    function NumberDiv(err: POCIError; const number1: POCINumber;\n      const number2: POCINumber; _result: POCINumber): sword;\n    function NumberMod(err: POCIError; const number1: POCINumber;\n      const number2: POCINumber; _result: POCINumber): sword;\n    function NumberIntPower(err: POCIError; const number1: POCINumber;\n      const number2: POCINumber; _result: POCINumber): sword;\n    function NumberShift(err: POCIError; const number: POCINumber;\n      const nDig: sword; _result: POCINumber): sword;\n    function NumberNeg(err: POCIError; const number: POCINumber;\n      _result: POCINumber): sword;\n    function NumberToText(err: POCIError; const number: POCINumber;\n      const fmt: Poratext; fmt_length: ub4; const nls_params: Poratext;\n      nls_p_length: ub4; buf_size: pub4; buf: poratext): sword;\n    function NumberFromText(err: POCIError; const str: poratext;\n      str_length: ub4; const fmt: poratext; fmt_length: ub4;\n      const nls_params: poratext; nls_p_length: ub4; number: POCINumber): sword;\n    function NumberToInt(err: POCIError; const number: POCINumber;\n      rsl_length: uword; rsl_flag: uword; rsl: Pointer): sword;\n    function NumberFromInt(err: POCIError; const inum: Pointer;\n      inum_length: uword; inum_s_flag: uword; number: POCINumber): sword;\n    function NumberToReal(err: POCIError; const number: POCINumber;\n      rsl_length: uword; rsl: Pointer): sword;\n    function NumberToRealArray(err: POCIError; const number: PPOCINumber;\n      elems: uword; rsl_length: uword; rsl: Pointer): sword;\n    function NumberFromReal(err: POCIError; const rnum: Pointer;\n      rnum_length: uword; number: POCINumber): sword;\n    function NumberCmp(err: POCIError; const number1: POCINumber;\n      const number2: POCINumber; _result: psword): sword;\n    function NumberSign(err: POCIError; const number: POCINumber;\n      _result: psword): sword;\n    function NumberIsZero(err: POCIError; const number: POCINumber;\n      _Result: pboolean): sword;\n    function NumberIsInt(err: POCIError; const number: POCINumber;\n      _result: Pboolean): sword;\n    function NumberAssign(err: POCIError; const from: POCINumber;\n      _to: POCINumber): sword;\n    function NumberAbs(err: POCIError; const number: POCINumber;\n      _result: POCINumber): sword;\n    function NumberCeil(err: POCIError; const number: POCINumber;\n      _result: POCINumber): sword;\n    function NumberFloor(err: POCIError; const number: POCINumber;\n      _result: POCINumber): sword;\n    function NumberSqrt(err: POCIError; const number: POCINumber;\n      _result: POCINumber): sword;\n    function NumberTrunc(err: POCIError; const number: POCINumber;\n      _result: POCINumber): sword;\n    function NumberPower(err: POCIError; const base: POCINumber;\n      const number: POCINumber; _result: POCINumber): sword;\n    function NumberRound(err: POCIError; const number: POCINumber;\n      decplace: sword; _result: POCINumber): sword;\n    function NumberPrec(err: POCIError; const number: POCINumber;\n      nDigs: sword; _result: POCINumber): sword;\n    function NumberSin(err: POCIError; const number: POCINumber;\n      _result: POCINumber): sword;\n    function NumberArcSin(err: POCIError; const number: POCINumber;\n      _result: POCINumber): sword;\n    function NumberHypSin(err: POCIError; const number: POCINumber;\n      _result: POCINumber): sword;\n    function NumberCos(err: POCIError; const number: POCINumber;\n      _result: POCINumber): sword;\n    function NumberArcCos(err: POCIError; const number: POCINumber;\n      _result: POCINumber): sword;\n    function NumberHypCos(err: POCIError; const number: POCINumber;\n      _result: POCINumber): sword;\n    function NumberTan(err: POCIError; const number: POCINumber;\n      _result: POCINumber): sword;\n    function NumberArcTan(err: POCIError; const number: POCINumber;\n      _result: POCINumber): sword;\n    function NumberArcTan2(err: POCIError; const number1: POCINumber;\n      const number2: POCINumber; _result: POCINumber): sword;\n    function NumberHypTan(err: POCIError; const number: POCINumber;\n      _result: POCINumber): sword;\n    function NumberExp(err: POCIError; const number: POCINumber;\n      _result: POCINumber): sword;\n    function NumberLn(err: POCIError; const number: POCINumber;\n      _result: POCINumber): sword;\n    function NumberLog(err: POCIError; const base: POCINumber;\n      const number: POCINumber; _result: POCINumber): sword;\n\n    function TableSize(hndl: POCIEnv; err: POCIError; const tbl: POCITable;\n                    size: psb4): sword;\n    function TableExists(hndl: POCIEnv; err: POCIError; const tbl: POCITable;\n                             index: sb4; exists: PBoolean): sword;\n    function TableDelete(hndl: POCIEnv; err: POCIError; index: sb4;\n                      tbl: POCITable): sword;\n    function TableFirst(hndl: POCIEnv; err: POCIError; const tbl: POCITable;\n                             index: sb4): sword;\n    function TableLast(hndl: POCIEnv; err: POCIError; const tbl: POCITable;\n                             index: sb4): sword;\n    function TableNext(hndl: POCIEnv; err: POCIError; index: sb4;\n      const tbl: POCITable; next_index: psb4; exists: PBoolean): sword;\n    function TablePrev(hndl: POCIEnv; err: POCIError; index: sb4;\n      const tbl: POCITable; prev_index: psb4; exists: PBoolean): sword;\n\n    function ObjectSetAttr(env: POCIEnv; err: POCIError; instance: Pointer;\n                  null_struct: pointer; tdo: POCIType; const names: PPAnsiChar;\n                  const lengths: pub4; const name_count: ub4;\n                  const indexes: pub4; const index_count: ub4;\n                  const null_status: POCIInd; const attr_null_struct: Pointer;\n                  const attr_value: Pointer): sword; cdecl;\n    function ObjectGetAttr(env: POCIEnv; err: POCIError; instance: Pointer;\n                  null_struct: Pointer; tdo: POCIType;\n                  const names: PPoratext; const lengths: pub4;\n                  const name_count: ub4; const indexes: pub4;\n                  const index_count: ub4; attr_null_status: POCIInd;\n                  attr_null_struct, attr_value: PPointer;\n                  attr_tdo: PPOCIType): sword;\n    {ociap.h}\n    function Ping(svchp: POCISvcCtx; errhp: POCIError; mode: ub4 = OCI_DEFAULT): sword;\n    {ort.h}\n    function TypeIterNew(env: POCIEnv; err: POCIError; const tdo: POCIType;\n                      iterator_ort: PPOCITypeIter):sword;\n    function TypeIterSet(env: POCIEnv; err: POCIError; const tdo: POCIType;\n                              iterator_ort: POCITypeIter): sword;\n    function TypeIterFree(env: POCIEnv; err: POCIError;\n                        iterator_ort: POCITypeIter): sword;\n    function TypeByName(env: POCIEnv; err: POCIError; const svc: POCISvcCtx;\n      schema_name: Poratext; const s_length: ub4; const type_name: Poratext;\n      const t_length: ub4; version_name: Poratext; const v_length: ub4;\n      const pin_duration: OCIDuration; const get_option: OCITypeGetOpt;\n      tdo: PPOCIType): sword;\n    function TypeArrayByName(env: POCIEnv; err: POCIError; svc: POCISvcCtx;\n      array_len: ub4; schema_name:  PPoratext; s_length: Pub4;\n      type_name: PPoratext; t_length: Pub4; version_name: PPoratext;\n      v_length: Pub4; pin_duration: OCIDuration; get_option: OCITypeGetOpt;\n      tdo: PPOCIType): sword;\n    function TypeByRef(env: POCIEnv; err: POCIError; type_ref: POCIRef;\n      pin_duration: OCIDuration; get_option: OCITypeGetOpt;\n      tdo: PPOCIType): sword;\n    function TypeArrayByRef(env: POCIEnv; err: POCIError; array_len: ub4;\n      type_ref: PPOCIRef; pin_duration: OCIDuration; get_option: OCITypeGetOpt;\n      tdo: PPOCIType): sword;\n    function TypeName(env: POCIEnv; err: POCIError; tdo: POCIType;\n      n_length: Pub4): poratext;\n    function TypeSchema(env: POCIEnv; err: POCIError; const tdo: POCIType;\n      n_length: Pub4): poratext;\n    function TypeTypeCode(env: POCIEnv; err: POCIError;\n                  const tdo: POCIType): OCITypeCode;\n    function TypeCollTypeCode(env:POCIEnv; err:POCIError;\n      const tdo: POCIType): OCITypeCode;\n    function TypeVersion(env: POCIEnv; err: POCIError; const tdo: POCIType;\n      v_length: Pub4): poratext;\n    function TypeAttrs(env: POCIEnv; err: POCIError;\n      const tdo:POCIType): ub4;\n    function TypeMethods(env: POCIEnv; err: POCIError;\n      const tdo: POCIType): ub4;\n    function TypeElemName(env: POCIEnv; err: POCIError;\n      const elem: POCITypeElem; n_length:Pub4): poratext;\n    function TypeElemTypeCode(env: POCIEnv; err: POCIError;\n      const elem: POCITypeElem): OCITypeCode;\n    function TypeElemType(env: POCIEnv; err: POCIError;\n      const elem: POCITypeElem; elem_tdo:PPOCIType): sword;\n    function TypeElemFlags(env: POCIEnv; err: POCIError;\n      const elem: POCITypeElem): ub4;\n    function TypeElemNumPrec(env: POCIEnv; err: POCIError;\n      const elem: POCITypeElem): ub1;\n    function TypeElemNumScale(env: POCIEnv; err: POCIError;\n      const elem: POCITypeElem): sb1;\n    function TypeElemLength(env: POCIEnv; err: POCIError;\n      const elem:POCITypeElem): ub4;\n    function TypeElemCharSetID(env: POCIEnv; err: POCIError;\n      const elem: POCITypeElem): ub2;\n    function TypeElemCharSetForm(env: POCIEnv; err: POCIError;\n      const elem: POCITypeElem): ub2;\n    function TypeElemParameterizedType(env: POCIEnv; err: POCIError;\n      const elem: POCITypeElem; type_stored: PPOCIType): sword;\n    function TypeElemExtTypeCode(env: POCIEnv; err: POCIError;\n      const elem: POCITypeElem): OCITypeCode;\n    function TypeAttrByName(env: POCIEnv; err: POCIError;\n      const tdo: POCIType; const name: Poratext; const n_length: ub4;\n      elem: PPOCITypeElem): sword;\n    function TypeAttrNext(env: POCIEnv; err: POCIError;\n      iterator_ort: POCITypeIter; elem: PPOCITypeElem): sword;\n    function TypeCollElem(env: POCIEnv; err: POCIError; const tdo:POCIType;\n      element: PPOCITypeElem): sword;\n    function TypeCollSize(env: POCIEnv; err: POCIError; const tdo: POCIType;\n      num_elems: Pub4): sword;\n    function TypeCollExtTypeCode(env: POCIEnv; err: POCIError;\n      const tdo:POCIType; sqt_code: POCITypeCode): sword;\n    function TypeMethodOverload(env: POCIEnv; err: POCIError;\n      const tdo: POCIType; const method_name: Poratext;\n      const m_length: ub4): ub4;\n    function TypeMethodByName(env: POCIEnv; err: POCIError;\n      const tdo: POCIType; const method_name: Poratext; const m_length: ub4;\n      mdos: PPOCITypeMethod): sword;\n    function TypeMethodNext(env: POCIEnv; err: POCIError;\n      iterator_ort: POCITypeIter; mdo: PPOCITypeMethod): sword;\n    function TypeMethodName(env:POCIEnv; err: POCIError;\n      const mdo: POCITypeMethod; n_length: Pub4): poratext;\n    function TypeMethodEncap(env: POCIEnv; err: POCIError;\n      const mdo: POCITypeMethod): OCITypeEncap;\n    function TypeMethodFlags(env: POCIEnv; err: POCIError;\n        const mdo:POCITypeMethod): OCITypeMethodFlag;\n    function TypeMethodMap(env: POCIEnv; err: POCIError; const tdo: POCIType;\n      mdo: PPOCITypeMethod): sword;\n    function TypeMethodOrder(env: POCIEnv; err: POCIError;\n      const tdo: POCIType; mdo: PPOCITypeMethod): sword;\n    function TypeMethodParams(env: POCIEnv; err: POCIError;\n      const mdo: POCITypeMethod): ub4;\n    function TypeResult(env: POCIEnv; err: POCIError;\n      const mdo: POCITypeMethod; elem: PPOCITypeElem): sword;\n    function TypeParamByPos(env: POCIEnv; err: POCIError;\n      const mdo: POCITypeMethod; const position: ub4;\n      elem: PPOCITypeElem): sword;\n    function TypeParamByName(env: POCIEnv; err: POCIError;\n      const mdo: POCITypeMethod; const name: Poratext; const n_length: ub4;\n      elem:PPOCITypeElem): sword;\n    function TypeParamPos(env: POCIEnv; err: POCIError;\n      const mdo: POCITypeMethod; const name: Poratext; const n_length: ub4;\n      position: Pub4; elem: PPOCITypeElem): sword;\n    function TypeElemParamMode(env: POCIEnv; err: POCIError;\n      const elem: POCITypeElem): OCITypeParamMode;\n    function TypeElemDefaultValue(env: POCIEnv; err: POCIError;\n      const elem: POCITypeElem; d_v_length: Pub4): poratext;\n    function TypeVTInit(env: POCIEnv; err: POCIError): sword;\n    function TypeVTInsert(env: POCIEnv; err: POCIError;\n      const schema_name: Poratext; const s_n_length: ub4;\n      const type_name: Poratext; const t_n_length: ub4;\n      const user_version:Poratext; const u_v_length:ub4): sword;\n    function TypeVTSelect(env: POCIEnv; err: POCIError;\n      const schema_name: Poratext; const s_n_length: ub4;\n      const type_name: Poratext; const t_n_length: ub4; user_version: PPoratext;\n      u_v_length: Pub4; version: Pub2): sword;\n  end;\n\nimplementation\n\nuses ZEncoding;\n\n{ TZOracle9iPlainDriver }\n\nfunction TZOracle9iPlainDriver.GetUnicodeCodePageName: String;\nbegin\n  Result := 'UTF8';\nend;\n\nprocedure TZOracle9iPlainDriver.LoadCodePages;\nbegin\n(*  AddCodePage('AL16UTF16', 2000, ceUTF16, zCP_UTF16); {Unicode 3.1 UTF-16 Universal character set}\n  AddCodePage('AL32UTF8', 873, ceUTF8, zCP_UTF8); {Unicode 3.1 UTF-8 Universal character set}\n  //AddCodePage('AR8ADOS710', 3); {Arabic MS-DOS 710 Server 8-bit Latin/Arabic}\n//  AddCodePage('AR8ADOS710T', 4); {Arabic MS-DOS 710 8-bit Latin/Arabic}\n  AddCodePage('AR8ADOS720', 558); {Arabic MS-DOS 720 Server 8-bit Latin/Arabic}\n//  AddCodePage('AR8ADOS720T', 6); {Arabic MS-DOS 720 8-bit Latin/Arabic}\n//  AddCodePage('AR8APTEC715', 7); {APTEC 715 Server 8-bit Latin/Arabic}\n//  AddCodePage('AR8APTEC715T', 8); {APTEC 715 8-bit Latin/Arabic}\n//  AddCodePage('AR8ASMO708PLUS', 9); {ASMO 708 Plus 8-bit Latin/Arabic}\n  AddCodePage('AR8ASMO8X', 500); {ASMO Extended 708 8-bit Latin/Arabic}\n//  AddCodePage('BN8BSCII', 11); {Bangladesh National Code 8-bit BSCII}\n//  AddCodePage('TR7DEC', 12); {DEC VT100 7-bit Turkish}\n//  AddCodePage('TR8DEC', 13); {DEC 8-bit Turkish}\n//  AddCodePage('EL8DEC', 14); {DEC 8-bit Latin/Greek}\n//  AddCodePage('EL8GCOS7', 15); {Bull EBCDIC GCOS7 8-bit Greek}\n//  AddCodePage('IN8ISCII', 16); {Multiple-Script Indian Standard 8-bit Latin/Indian Languages}\n//  AddCodePage('JA16DBCS', 17); {IBM EBCDIC 16-bit Japanese UDC}\n//  AddCodePage('JA16EBCDIC930', 18); {IBM DBCS Code Page 290 16-bit Japanese UDC}\n  AddCodePage('JA16EUC', 830); {EUC 24-bit Japanese}\n  AddCodePage('JA16EUCTILDE', 837); {The same as JA16EUC except for the way that the wave dash and the tilde are mapped to and from Unicode.}\n//  AddCodePage('JA16EUCYEN', 21); {EUC 24-bit Japanese with '\\' mapped to the Japanese yen character}\n//  AddCodePage('JA16MACSJIS', 22); {Mac client Shift-JIS 16-bit Japanese}\n  AddCodePage('JA16SJIS', 832); {Shift-JIS 16-bit Japanese UDC}\n  AddCodePage('JA16SJISTILDE', 838); {The same as JA16SJIS except for the way that the wave dash and the tilde are mapped to and from Unicode. UDC}\n//  AddCodePage('JA16SJISYEN', 25); {Shift-JIS 16-bit Japanese with '\\' mapped to the Japanese yen character UDC}\n//  AddCodePage('JA16VMS', 26); {JVMS 16-bit Japanese}\n//  AddCodePage('RU8BESTA', 27); {BESTA 8-bit Latin/Cyrillic}\n//  AddCodePage('SF7ASCII', 28); {ASCII 7-bit Finnish}\n//  AddCodePage('KO16DBCS', 29); {IBM EBCDIC 16-bit Korean UDC}\n//  AddCodePage('KO16KSCCS', 30); {KSCCS 16-bit Korean}\n  AddCodePage('KO16KSC5601', 840); {KSC5601 16-bit Korean}\n  AddCodePage('KO16MSWIN949', 846); {MS Windows Code Page 949 Korean UDC}\n//  AddCodePage('TH8MACTHAI', 33); {Mac Client 8-bit Latin/Thai}\n//  AddCodePage('TH8MACTHAIS', 34); {Mac Server 8-bit Latin/Thai}\n  AddCodePage('TH8TISASCII', 41); {Thai Industrial Standard 620-2533 - ASCII 8-bit}\n//  AddCodePage('TH8TISEBCDIC', 36); {Thai Industrial Standard 620-2533 - EBCDIC 8-bit}\n//  AddCodePage('TH8TISEBCDICS', 37); {Thai Industrial Standard 620-2533-EBCDIC Server 8-bit}\n  AddCodePage('US7ASCII', 1); {U.S. 7-bit ASCII American}\n  AddCodePage('VN8MSWIN1258', 45); {MS Windows Code Page 1258 8-bit Vietnamese}\n//  AddCodePage('VN8VN3', 38); {VN3 8-bit Vietnamese}\n//  AddCodePage('WE8GCOS7', 41); {Bull EBCDIC GCOS7 8-bit West European}\n//  AddCodePage('YUG7ASCII', 42); {ASCII 7-bit Yugoslavian}\n  AddCodePage('ZHS16CGB231280', 850); {CGB2312-80 16-bit Simplified Chinese}\n//  AddCodePage('ZHS16DBCS', 44); {IBM EBCDIC 16-bit Simplified Chinese UDC}\n  AddCodePage('ZHS16GBK', 852); {GBK 16-bit Simplified Chinese UDC}\n//  AddCodePage('ZHS16MACCGB231280', 46); {Mac client CGB2312-80 16-bit Simplified Chinese}\n  AddCodePage('ZHS32GB18030', 854); {GB18030-2000}\n  AddCodePage('ZHT16BIG5', 856); {BIG5 16-bit Traditional Chinese}\n//  AddCodePage('ZHT16CCDC', 49); {HP CCDC 16-bit Traditional Chinese}\n//  AddCodePage('ZHT16DBCS', 50); {IBM EBCDIC 16-bit Traditional Chinese UDC}\n//  AddCodePage('ZHT16DBT', 51); {Taiwan Taxation 16-bit Traditional Chinese}\n  AddCodePage('ZHT16HKSCS', 868); {MS Windows Code Page 950 with Hong Kong Supplementary Character Set}\n  AddCodePage('ZHT16MSWIN950', 867); {MS Windows Code Page 950 Traditional Chinese UDC}\n  AddCodePage('ZHT32EUC', 860); {EUC 32-bit Traditional Chinese}\n//  AddCodePage('ZHT32SOPS', 55); {SOPS 32-bit Traditional Chinese}\n//  AddCodePage('ZHT32TRIS', 56); {TRIS 32-bit Traditional Chinese}\n\n//  AddCodePage('WE8DEC', 57); {DEC 8-bit West European}\n//  AddCodePage('D7DEC', 58); {DEC VT100 7-bit German}\n//  AddCodePage('F7DEC', 59); {DEC VT100 7-bit French}\n//  AddCodePage('S7DEC', 60); {DEC VT100 7-bit Swedish}\n//  AddCodePage('E7DEC', 61); {DEC VT100 7-bit Spanish}\n//  AddCodePage('NDK7DEC', 62); {DEC VT100 7-bit Norwegian/Danish}\n//  AddCodePage('I7DEC', 63); {DEC VT100 7-bit Italian}\n//  AddCodePage('NL7DEC', 64); {DEC VT100 7-bit Dutch}\n//  AddCodePage('CH7DEC', 65); {DEC VT100 7-bit Swiss (German/French)}\n//  AddCodePage('SF7DEC', 66); {DEC VT100 7-bit Finnish}\n//  AddCodePage('WE8DG', 67); {DG 8-bit West European}\n//  AddCodePage('WE8EBCDIC37', 68, ceAnsi, zCP_EBC037); {EBCDIC Code Page 37 8-bit West European}\n//  AddCodePage('D8EBCDIC273', 69, ceAnsi, zCP_EBC273); {EBCDIC Code Page 273/1 8-bit Austrian German}\n//  AddCodePage('DK8EBCDIC277', 70, ceAnsi, zCP_EBC277); {EBCDIC Code Page 277/1 8-bit Danish}\n//  AddCodePage('S8EBCDIC278', 71, ceAnsi, zCP_EBC278); {EBCDIC Code Page 278/1 8-bit Swedish}\n//  AddCodePage('I8EBCDIC280', 72, ceAnsi, zCP_EBC280); {EBCDIC Code Page 280/1 8-bit Italian}\n//  AddCodePage('WE8EBCDIC284', 73, ceAnsi, zCP_EBC284); {EBCDIC Code Page 284 8-bit Latin American/Spanish}\n//  AddCodePage('WE8EBCDIC285', 74); {EBCDIC Code Page 285 8-bit West European}\n//  AddCodePage('WE8EBCDIC924', 75); {Latin 9 EBCDIC 924}\n//  AddCodePage('WE8EBCDIC1047', 76); {EBCDIC Code Page 1047 8-bit West European}\n//  AddCodePage('WE8EBCDIC1047E', 77); {Latin 1/Open Systems 1047}\n//  AddCodePage('WE8EBCDIC1140', 78); {EBCDIC Code Page 1140 8-bit West European}\n//  AddCodePage('WE8EBCDIC1140C', 79); {EBCDIC Code Page 1140 Client 8-bit West European}\n//  AddCodePage('WE8EBCDIC1145', 80); {EBCDIC Code Page 1145 8-bit West European}\n//  AddCodePage('WE8EBCDIC1146', 81); {EBCDIC Code Page 1146 8-bit West European}\n//  AddCodePage('WE8EBCDIC1148', 82); {EBCDIC Code Page 1148 8-bit West European}\n//  AddCodePage('WE8EBCDIC1148C', 83); {EBCDIC Code Page 1148 Client 8-bit West European}\n//  AddCodePage('F8EBCDIC297', 84); {EBCDIC Code Page 297 8-bit French}\n//  AddCodePage('WE8EBCDIC500', 85); {EBCDIC Code Page 500 8-bit West European}\n//  AddCodePage('EE8EBCDIC870', 85); {EBCDIC Code Page 870 8-bit East European}\n//  AddCodePage('EE8EBCDIC870C', 87); {EBCDIC Code Page 870 Client 8-bit East European}\n//  AddCodePage('EE8EBCDIC870S', 88); {EBCDIC Code Page 870 Server 8-bit East European}\n//  AddCodePage('WE8EBCDIC871', 89); {EBCDIC Code Page 871 8-bit Icelandic}\n  AddCodePage('EL8EBCDIC875', 90); {EBCDIC Code Page 875 8-bit Greek}\n  AddCodePage('EL8EBCDIC875R', 91); {EBCDIC Code Page 875 Server 8-bit Greek}\n  AddCodePage('CL8EBCDIC1025', 92); {EBCDIC Code Page 1025 8-bit Cyrillic}\n  AddCodePage('CL8EBCDIC1025C', 93); {EBCDIC Code Page 1025 Client 8-bit Cyrillic}\n  AddCodePage('CL8EBCDIC1025R', 94); {EBCDIC Code Page 1025 Server 8-bit Cyrillic}\n  AddCodePage('CL8EBCDIC1025S', 95); {EBCDIC Code Page 1025 Server 8-bit Cyrillic}\n  AddCodePage('CL8EBCDIC1025X', 96); {EBCDIC Code Page 1025 (Modified) 8-bit Cyrillic}\n  AddCodePage('BLT8EBCDIC1112', 97); {EBCDIC Code Page 1112 8-bit Baltic Multilingual}\n  AddCodePage('BLT8EBCDIC1112S', 98); {EBCDIC Code Page 1112 8-bit Server Baltic Multilingual}\n  AddCodePage('D8EBCDIC1141', 99); {EBCDIC Code Page 1141 8-bit Austrian German}\n  AddCodePage('DK8EBCDIC1142', 100); {EBCDIC Code Page 1142 8-bit Danish}\n  AddCodePage('S8EBCDIC1143', 101); {EBCDIC Code Page 1143 8-bit Swedish}\n  AddCodePage('I8EBCDIC1144', 102); {EBCDIC Code Page 1144 8-bit Italian}\n  AddCodePage('F8EBCDIC1147', 103); {EBCDIC Code Page 1147 8-bit French}\n  AddCodePage('EEC8EUROASCI', 104); {EEC Targon 35 ASCI West European/Greek}\n  AddCodePage('EEC8EUROPA3', 105); {EEC EUROPA3 8-bit West European/Greek}\n  AddCodePage('LA8PASSPORT', 106); {German Government Printer 8-bit All-European Latin}\n  AddCodePage('WE8HP', 107); {HP LaserJet 8-bit West European}\n  AddCodePage('WE8ROMAN8', 108); {HP Roman8 8-bit West European}\n  AddCodePage('HU8CWI2', 109); {Hungarian 8-bit CWI-2}\n  AddCodePage('HU8ABMOD', 110); {Hungarian 8-bit Special AB Mod}\n  AddCodePage('LV8RST104090', 111); {IBM-PC Alternative Code Page 8-bit Latvian (Latin/Cyrillic)}\n  AddCodePage('US8PC437', 112); {IBM-PC Code Page 437 8-bit American}\n  AddCodePage('BG8PC437S', 113); {IBM-PC Code Page 437 8-bit (Bulgarian Modification)}\n  AddCodePage('EL8PC437S', 114); {IBM-PC Code Page 437 8-bit (Greek modification)}\n  AddCodePage('EL8PC737', 115); {IBM-PC Code Page 737 8-bit Greek/Latin}\n  AddCodePage('LT8PC772', 116); {IBM-PC Code Page 772 8-bit Lithuanian (Latin/Cyrillic)}\n  AddCodePage('LT8PC774', 117); {IBM-PC Code Page 774 8-bit Lithuanian (Latin)}\n  AddCodePage('BLT8PC775', 118); {IBM-PC Code Page 775 8-bit Baltic}\n  AddCodePage('WE8PC850', 119); {IBM-PC Code Page 850 8-bit West European}\n  AddCodePage('EL8PC851', 120); {IBM-PC Code Page 851 8-bit Greek/Latin}\n  AddCodePage('EE8PC852', 121); {IBM-PC Code Page 852 8-bit East European}\n  AddCodePage('RU8PC855', 122); {IBM-PC Code Page 855 8-bit Latin/Cyrillic}\n  AddCodePage('WE8PC858', 123); {IBM-PC Code Page 858 8-bit West European}\n  AddCodePage('WE8PC860', 124); {IBM-PC Code Page 860 8-bit West European}\n  AddCodePage('IS8PC861', 125); {IBM-PC Code Page 861 8-bit Icelandic}\n  AddCodePage('CDN8PC863', 126); {IBM-PC Code Page 863 8-bit Canadian French}\n  AddCodePage('N8PC865', 127); {IBM-PC Code Page 865 8-bit Norwegian}\n  AddCodePage('RU8PC866', 128); {IBM-PC Code Page 866 8-bit Latin/Cyrillic}\n  AddCodePage('EL8PC869', 129); {IBM-PC Code Page 869 8-bit Greek/Latin}\n  AddCodePage('LV8PC1117', 130); {IBM-PC Code Page 1117 8-bit Latvian}\n  AddCodePage('US8ICL', 131); {ICL EBCDIC 8-bit American}\n  AddCodePage('WE8ICL', 132); {ICL EBCDIC 8-bit West European}\n  AddCodePage('WE8ISOICLUK', 133); {ICL special version ISO8859-1}\n  AddCodePage('WE8ISO8859P1', 134); {ISO 8859-1 West European}\n  AddCodePage('EE8ISO8859P2', 135); {ISO 8859-2 East European}\n  AddCodePage('SE8ISO8859P3', 136); {ISO 8859-3 South European}\n  AddCodePage('NEE8ISO8859P4', 137); {ISO 8859-4 North and North-East European}\n  AddCodePage('CL8ISO8859P5', 138); {ISO 8859-5 Latin/Cyrillic}\n  AddCodePage('EL8ISO8859P7', 139); {ISO 8859-7 Latin/Greek}\n  AddCodePage('NE8ISO8859P10', 140); {ISO 8859-10 North European}\n  AddCodePage('BLT8ISO8859P13', 141); {ISO 8859-13 Baltic}\n  AddCodePage('CEL8ISO8859P14', 142); {ISO 8859-13 Celtic}\n  AddCodePage('WE8ISO8859P15', 143); {ISO 8859-15 West European}\n  AddCodePage('AR8ARABICMAC', 144); {Mac Client 8-bit Latin/Arabic}\n  AddCodePage('EE8MACCE', 145); {Mac Client 8-bit Central European}\n  AddCodePage('EE8MACCROATIAN', 146); {Mac Client 8-bit Croatian}\n  AddCodePage('WE8MACROMAN8', 147); {Mac Client 8-bit Extended Roman8 West European}\n  AddCodePage('EL8MACGREEK', 148); {Mac Client 8-bit Greek}\n  AddCodePage('IS8MACICELANDIC', 149); {Mac Client 8-bit Icelandic}\n  AddCodePage('CL8MACCYRILLIC', 150); {Mac Client 8-bit Latin/Cyrillic}\n  AddCodePage('EE8MACCES', 151); {Mac Server 8-bit Central European}\n  AddCodePage('EE8MACCROATIANS', 152); {Mac Server 8-bit Croatian}\n  AddCodePage('WE8MACROMAN8S', 153); {Mac Server 8-bit Extended Roman8 West European}\n  AddCodePage('CL8MACCYRILLICS', 154); {Mac Server 8-bit Latin/Cyrillic}\n  AddCodePage('EL8MACGREEKS', 155); {Mac Server 8-bit Greek}\n  AddCodePage('IS8MACICELANDICS', 156); {Mac Server 8-bit Icelandic}\n  AddCodePage('BG8MSWIN', 157); {MS Windows 8-bit Bulgarian Cyrillic}\n  AddCodePage('LT8MSWIN921', 158); {MS Windows Code Page 921 8-bit Lithuanian}\n  AddCodePage('ET8MSWIN923', 159); {MS Windows Code Page 923 8-bit Estonian}\n  AddCodePage('EE8MSWIN1250', 160, ceAnsi, zCP_WIN1250); {MS Windows Code Page 1250 8-bit East European}\n  AddCodePage('CL8MSWIN1251', 161, ceAnsi, zCP_WIN1251); {MS Windows Code Page 1251 8-bit Latin/Cyrillic}\n  AddCodePage('WE8MSWIN1252', 162, ceAnsi, zCP_WIN1252); {MS Windows Code Page 1252 8-bit West European}\n  AddCodePage('EL8MSWIN1253', 163, ceAnsi, zCP_WIN1253); {MS Windows Code Page 1253 8-bit Latin/Greek}\n  AddCodePage('BLT8MSWIN1257', 164, ceAnsi, zCP_WIN1257); {MS Windows Code Page 1257 8-bit Baltic}\n  AddCodePage('BLT8CP921', 165); {Latvian Standard LVS8-92(1) Windows/Unix 8-bit Baltic}\n  AddCodePage('LV8PC8LR', 166, ceAnsi, zCP_DOS866); {Latvian Version IBM-PC Code Page 866 8-bit Latin/Cyrillic}\n  AddCodePage('WE8NCR4970', 167); {NCR 4970 8-bit West European}\n  AddCodePage('WE8NEXTSTEP', 168); {NeXTSTEP PostScript 8-bit West European}\n  AddCodePage('CL8ISOIR111', 169); {ISOIR111 Cyrillic}\n  AddCodePage('CL8KOI8R', 170, ceAnsi, zCP_KOI8R); {RELCOM Internet Standard 8-bit Latin/Cyrillic}\n  AddCodePage('CL8KOI8U', 171); {KOI8 Ukrainian Cyrillic}\n  AddCodePage('US8BS2000', 172); {Siemens 9750-62 EBCDIC 8-bit American}\n  AddCodePage('DK8BS2000', 173); {Siemens 9750-62 EBCDIC 8-bit Danish}\n  AddCodePage('F8BS2000', 174); {Siemens 9750-62 EBCDIC 8-bit French}\n  AddCodePage('D8BS2000', 175); {Siemens 9750-62 EBCDIC 8-bit German}\n  AddCodePage('E8BS2000', 176); {Siemens 9750-62 EBCDIC 8-bit Spanish}\n  AddCodePage('S8BS2000', 177); {Siemens 9750-62 EBCDIC 8-bit Swedish}\n  AddCodePage('DK7SIEMENS9780X', 178); {Siemens 97801/97808 7-bit Danish}\n  AddCodePage('F7SIEMENS9780X', 179); {Siemens 97801/97808 7-bit French}\n  AddCodePage('D7SIEMENS9780X', 180); {Siemens 97801/97808 7-bit German}\n  AddCodePage('I7SIEMENS9780X', 181); {Siemens 97801/97808 7-bit Italian}\n  AddCodePage('N7SIEMENS9780X', 182); {Siemens 97801/97808 7-bit Norwegian}\n  AddCodePage('E7SIEMENS9780X', 183); {Siemens 97801/97808 7-bit Spanish}\n  AddCodePage('S7SIEMENS9780X', 184); {Siemens 97801/97808 7-bit Swedish}\n  AddCodePage('EE8BS2000', 185); {Siemens EBCDIC.DF.04 8-bit East European}\n  AddCodePage('WE8BS2000', 186); {Siemens EBCDIC.DF.04 8-bit West European}\n  AddCodePage('WE8BS2000E', 187); {Siemens EBCDIC.DF.04 8-bit West European}\n  AddCodePage('CL8BS2000', 188); {Siemens EBCDIC.EHC.LC 8-bit Cyrillic}\n  AddCodePage('WE8EBCDIC37C', 189); {EBCDIC Code Page 37 8-bit Oracle/c}\n  AddCodePage('IW8EBCDIC424', 190); {EBCDIC Code Page 424 8-bit Latin/Hebrew}\n  AddCodePage('IW8EBCDIC424S', 191); {EBCDIC Code Page 424 Server 8-bit Latin/Hebrew}\n  AddCodePage('WE8EBCDIC500C', 192); {EBCDIC Code Page 500 8-bit Oracle/c}\n  AddCodePage('IW8EBCDIC1086', 193); {EBCDIC Code Page 1086 8-bit Hebrew}\n  AddCodePage('AR8EBCDIC420S', 194); {EBCDIC Code Page 420 Server 8-bit Latin/Arabic}\n  AddCodePage('AR8EBCDICX', 195); {EBCDIC XBASIC Server 8-bit Latin/Arabic}\n  AddCodePage('TR8EBCDIC1026', 196, ceAnsi, zCP_IBM1026); {EBCDIC Code Page 1026 8-bit Turkish}\n  AddCodePage('TR8EBCDIC1026S', 197); {EBCDIC Code Page 1026 Server 8-bit Turkish}\n  AddCodePage('AR8HPARABIC8T', 198); {HP 8-bit Latin/Arabic}\n  AddCodePage('TR8PC857', 199); {IBM-PC Code Page 857 8-bit Turkish}\n  AddCodePage('IW8PC1507', 200); {IBM-PC Code Page 1507/862 8-bit Latin/Hebrew}\n  AddCodePage('AR8ISO8859P6', 201); {ISO 8859-6 Latin/Arabic}\n  AddCodePage('IW8ISO8859P8', 201); {ISO 8859-8 Latin/Hebrew}\n  AddCodePage('WE8ISO8859P9', 203); {ISO 8859-9 West European & Turkish}\n  AddCodePage('LA8ISO6937', 204); {ISO 6937 8-bit Coded Character Set for Text Communication}\n  AddCodePage('IW7IS960', 205); {Israeli Standard 960 7-bit Latin/Hebrew}\n  AddCodePage('IW8MACHEBREW', 206); {Mac Client 8-bit Hebrew}\n  AddCodePage('AR8ARABICMACT', 207); {Mac 8-bit Latin/Arabic}\n  AddCodePage('TR8MACTURKISH', 208); {Mac Client 8-bit Turkish}\n  AddCodePage('IW8MACHEBREWS', 209); {Mac Server 8-bit Hebrew}\n  AddCodePage('TR8MACTURKISHS', 210); {Mac Server 8-bit Turkish}\n  AddCodePage('TR8MSWIN1254', 211); {MS Windows Code Page 1254 8-bit Turkish}\n  AddCodePage('IW8MSWIN1255', 212); {MS Windows Code Page 1255 8-bit Latin/Hebrew}\n  AddCodePage('AR8MSWIN1256', 213); {MS Windows Code Page 1256 8-Bit Latin/Arabic}\n  AddCodePage('IN8ISCII', 214); {Multiple-Script Indian Standard 8-bit Latin/Indian Languages}\n  AddCodePage('AR8MUSSAD768', 215); {Mussa'd Alarabi/2 768 Server 8-bit Latin/Arabic}\n  AddCodePage('AR8MUSSAD768T', 216); {Mussa'd Alarabi/2 768 8-bit Latin/Arabic}\n  AddCodePage('AR8NAFITHA711', 217); {Nafitha Enhanced 711 Server 8-bit Latin/Arabic}\n  AddCodePage('AR8NAFITHA711T', 218); {Nafitha Enhanced 711 8-bit Latin/Arabic}\n  AddCodePage('AR8NAFITHA721', 219); {Nafitha International 721 Server 8-bit Latin/Arabic}\n  AddCodePage('AR8NAFITHA721T', 220); {Nafitha International 721 8-bit Latin/Arabic}\n  AddCodePage('AR8SAKHR706', 221); {SAKHR 706 Server 8-bit Latin/Arabic}\n  AddCodePage('AR8SAKHR707', 222); {SAKHR 707 Server 8-bit Latin/Arabic}\n  AddCodePage('AR8SAKHR707T', 223); {SAKHR 707 8-bit Latin/Arabic}\n  AddCodePage('AR8XBASIC', 224); {XBASIC 8-bit Latin/Arabic}\n  AddCodePage('WE8BS2000L5', 225); {Siemens EBCDIC.DF.04.L5 8-bit West European/Turkish})\n  AddCodePage('UTF8', 871, ceUTF8, zCP_UTF8); {Unicode 3.0 UTF-8 Universal character set, CESU-8 compliant}\n  AddCodePage('UTFE', 227, ceUTF8, zCP_UTF8); {EBCDIC form of Unicode 3.0 UTF-8 Universal character set}\n*)\n\n  //All supporteds from XE\n  AddCodePage('US7ASCII', 1, ceAnsi, zCP_us_ascii);\n  AddCodePage('US8PC437', 4, ceAnsi, zCP_DOS437);\n  AddCodePage('WE8PC850', 10, ceAnsi, zCP_DOS850);\n  AddCodePage('WE8PC858', 28, ceAnsi, zCP_DOS858);\n  AddCodePage('WE8ISO8859P1', 31, ceAnsi, zCP_L1_ISO_8859_1);\n  AddCodePage('EE8ISO8859P2', 32, ceAnsi, zCP_L2_ISO_8859_2);\n  AddCodePage('SE8ISO8859P3', 33, ceAnsi, zCP_L3_ISO_8859_3);\n  AddCodePage('NEE8ISO8859P4', 34, ceAnsi, zCP_L4_ISO_8859_4);\n  AddCodePage('CL8ISO8859P5', 35, ceAnsi, zCP_L5_ISO_8859_5);\n  AddCodePage('AR8ISO8859P6', 36, ceAnsi, zCP_L6_ISO_8859_6);\n  AddCodePage('EL8ISO8859P7', 37, ceAnsi, zCP_L7_ISO_8859_7);\n  AddCodePage('IW8ISO8859P8', 38, ceAnsi, zCP_L8_ISO_8859_8);\n  AddCodePage('WE8ISO8859P9', 39, ceAnsi, zCP_L5_ISO_8859_9);\n  AddCodePage('NE8ISO8859P10', 40, ceAnsi, zCP_L6_ISO_8859_10);\n  AddCodePage('TH8TISASCII', 41, ceAnsi);\n  AddCodePage('VN8MSWIN1258', 45, ceAnsi, zCP_WIN1258);\n  AddCodePage('WE8ISO8859P15', 46, ceAnsi, zCP_L9_ISO_8859_15);\n  AddCodePage('BLT8ISO8859P13', 47, ceAnsi, zCP_L7_ISO_8859_13);\n  AddCodePage('CEL8ISO8859P14', 48, ceAnsi, zCP_L8_ISO_8859_14);\n  AddCodePage('CL8KOI8U', 51, ceAnsi, zCP_KOI8U);\n  AddCodePage('AZ8ISO8859P9E', 52, ceAnsi);\n  AddCodePage('EE8PC852', 150, ceAnsi, zCP_DOS852);\n  AddCodePage('RU8PC866', 152, ceAnsi, zCP_DOS856);\n  AddCodePage('TR8PC857', 156, ceAnsi, zCP_DOS857);\n  AddCodePage('EE8MSWIN1250', 170, ceAnsi, zCP_WIN1250);\n  AddCodePage('CL8MSWIN1251', 171, ceAnsi, zCP_WIN1251);\n  AddCodePage('ET8MSWIN923', 172, ceAnsi, zCP_MSWIN923);\n  AddCodePage('EL8MSWIN1253', 174, ceAnsi, zCP_WIN1253);\n  AddCodePage('IW8MSWIN1255', 175, ceAnsi, zCP_WIN1255);\n  AddCodePage('LT8MSWIN921', 176, ceAnsi, zCP_MSWIN921);\n  AddCodePage('TR8MSWIN1254', 177, ceAnsi, zCP_WIN1254);\n  AddCodePage('WE8MSWIN1252', 178, ceAnsi, zCP_WIN1252);\n  AddCodePage('BLT8MSWIN1257', 179, ceAnsi, zCP_WIN1257);\n  AddCodePage('BLT8CP921', 191, ceAnsi, 921);\n  AddCodePage('CL8KOI8R', 196, ceAnsi, zCP_KOI8R);\n  AddCodePage('BLT8PC775', 197, ceAnsi, zCP_DOS775);\n  AddCodePage('EL8PC737', 382, ceAnsi, zCP_DOS737);\n  AddCodePage('AR8ASMO8X', 500, ceAnsi);\n  AddCodePage('AR8ADOS720', 558, ceAnsi, zCP_DOS720);\n  AddCodePage('AR8MSWIN1256', 560, ceAnsi, cCP_WIN1256);\n  AddCodePage('JA16EUC', 830, ceAnsi, zCP_euc_JP_win);\n  AddCodePage('JA16SJIS', 832, ceAnsi, zCP_csISO2022JP);\n  AddCodePage('JA16EUCTILDE', 837, ceAnsi);\n  AddCodePage('JA16SJISTILDE', 838, ceAnsi);\n  AddCodePage('KO16KSC5601', 840, ceAnsi, 601);\n  AddCodePage('KO16MSWIN949', 846, ceAnsi, zCP_EUCKR);\n  AddCodePage('ZHS16CGB231280', 850, ceAnsi, zCP_GB2312);\n  AddCodePage('ZHS16GBK', 852, ceAnsi);\n  AddCodePage('ZHS32GB18030', 854, ceAnsi, zCP_GB18030);\n  AddCodePage('ZHT32EUC', 860, ceAnsi, zCP_EUCKR);\n  AddCodePage('ZHT16BIG5', 865, ceAnsi, zCP_Big5);\n  AddCodePage('ZHT16MSWIN950', 867, ceAnsi, zCP_Big5);\n  AddCodePage('ZHT16HKSCS', 868, ceAnsi);\n  AddCodePage('UTF8', 871, ceUTF8, zCP_UTF8);\n  AddCodePage('AL32UTF8', 873, ceUTF8, zCP_UTF8);\n  AddCodePage('UTF16', 1000, ceUTF16, zCP_UTF16);\n  AddCodePage('AL16UTF16', 2000, ceUTF16, zCP_UTF16);\n  AddCodePage('AL16UTF16LE', 2002, ceUTF16, zCP_UTF16);\nend;\n\nprocedure TZOracle9iPlainDriver.LoadApi;\nbegin\n{ ************** Load adresses of API Functions ************* }\n  with Loader do\n  begin\n    @OracleAPI.OCIEnvCreate       := GetAddress('OCIEnvCreate');\n    @OracleAPI.OCIEnvNlsCreate    := GetAddress('OCIEnvNlsCreate');\n    @OracleAPI.OCIInitialize      := GetAddress('OCIInitialize');\n    @OracleAPI.OCIEnvInit         := GetAddress('OCIEnvInit');\n\n    @OracleAPI.OCIHandleAlloc     := GetAddress('OCIHandleAlloc');\n    @OracleAPI.OCIHandleFree      := GetAddress('OCIHandleFree');\n    @OracleAPI.OCIAttrSet         := GetAddress('OCIAttrSet');\n    @OracleAPI.OCIAttrGet         := GetAddress('OCIAttrGet');\n    @OracleAPI.OCIDescriptorAlloc := GetAddress('OCIDescriptorAlloc');\n    @OracleAPI.OCIDescriptorFree  := GetAddress('OCIDescriptorFree');\n    @OracleAPI.OCIErrorGet        := GetAddress('OCIErrorGet');\n\n    @OracleAPI.OCIServerAttach    := GetAddress('OCIServerAttach');\n    @OracleAPI.OCIServerDetach    := GetAddress('OCIServerDetach');\n    @OracleAPI.OCIServerVersion   := GetAddress('OCIServerVersion');\n    @OracleAPI.OCIServerRelease   := GetAddress('OCIServerRelease');\n    @OracleAPI.OCIBreak           := GetAddress('OCIBreak');\n\n    { For Oracle >= 8.1 }\n    @OracleAPI.OCIReset           := GetAddress('OCIReset');\n\n    @OracleAPI.OCISessionBegin    := GetAddress('OCISessionBegin');\n    @OracleAPI.OCISessionEnd      := GetAddress('OCISessionEnd');\n    @OracleAPI.OCIPasswordChange  := GetAddress('OCIPasswordChange');\n\n    @OracleAPI.OCITransStart      := GetAddress('OCITransStart');\n    @OracleAPI.OCITransCommit     := GetAddress('OCITransCommit');\n    @OracleAPI.OCITransRollback   := GetAddress('OCITransRollback');\n    @OracleAPI.OCITransDetach     := GetAddress('OCITransDetach');\n    @OracleAPI.OCITransPrepare    := GetAddress('OCITransPrepare');\n    @OracleAPI.OCITransForget     := GetAddress('OCITransForget');\n\n    @OracleAPI.OCIStmtPrepare     := GetAddress('OCIStmtPrepare');\n    @OracleAPI.OCIStmtExecute     := GetAddress('OCIStmtExecute');\n    @OracleAPI.OCIStmtFetch       := GetAddress('OCIStmtFetch');\n    @OracleAPI.OCIStmtGetPieceInfo := GetAddress('OCIStmtGetPieceInfo');\n    @OracleAPI.OCIStmtSetPieceInfo := GetAddress('OCIStmtSetPieceInfo');\n    @OracleAPI.OCIParamGet        := GetAddress('OCIParamGet');\n    @OracleAPI.OCIResultSetToStmt := GetAddress('OCIResultSetToStmt');\n\n    @OracleAPI.OCIDefineByPos     := GetAddress('OCIDefineByPos');\n    @OracleAPI.OCIDefineArrayOfStruct := GetAddress('OCIDefineArrayOfStruct');\n\n    @OracleAPI.OCIBindByPos       := GetAddress('OCIBindByPos');\n    @OracleAPI.OCIBindByName      := GetAddress('OCIBindByName');\n    @OracleAPI.OCIBindDynamic     := GetAddress('OCIBindDynamic');\n    @OracleAPI.OCIBindObject      := GetAddress('OCIBindObject');\n\n    @OracleAPI.OCIDefineObject    := GetAddress('OCIDefineObject');\n\n    { > ori.h }\n    @OracleAPI.OCIObjectNew                   := GetAddress('OCIObjectNew');\n    @OracleAPI.OCIObjectPin                   := GetAddress('OCIObjectPin');\n    @OracleAPI.OCIObjectUnpin                 := GetAddress('OCIObjectUnpin');\n    @OracleAPI.OCIObjectPinCountReset         := GetAddress('OCIObjectPinCountReset');\n    @OracleAPI.OCIObjectLock                  := GetAddress('OCIObjectLock');\n    @OracleAPI.OCIObjectLockNoWait            := GetAddress('OCIObjectLockNoWait');\n    @OracleAPI.OCIObjectMarkUpdate            := GetAddress('OCIObjectMarkUpdate');\n    @OracleAPI.OCIObjectUnmark                := GetAddress('OCIObjectUnmark');\n    @OracleAPI.OCIObjectUnmarkByRef           := GetAddress('OCIObjectUnmarkByRef');\n    @OracleAPI.OCIObjectFree                  := GetAddress('OCIObjectFree');\n    @OracleAPI.OCIObjectMarkDeleteByRef       := GetAddress('OCIObjectMarkDeleteByRef');\n    @OracleAPI.OCIObjectMarkDelete            := GetAddress('OCIObjectMarkDelete');\n    @OracleAPI.OCIObjectFlush                 := GetAddress('OCIObjectFlush');\n    @OracleAPI.OCIObjectRefresh               := GetAddress('OCIObjectRefresh');\n    @OracleAPI.OCIObjectCopy                  := GetAddress('OCIObjectCopy');\n    @OracleAPI.OCIObjectGetTypeRef            := GetAddress('OCIObjectGetTypeRef');\n    @OracleAPI.OCIObjectGetObjectRef          := GetAddress('OCIObjectGetObjectRef');\n    @OracleAPI.OCIObjectMakeObjectRef         := GetAddress('OCIObjectMakeObjectRef');\n    @OracleAPI.OCIObjectGetPrimaryKeyTypeRef  := GetAddress('OCIObjectGetPrimaryKeyTypeRef');\n    @OracleAPI.OCIObjectGetInd                := GetAddress('OCIObjectGetInd');\n    @OracleAPI.OCIObjectExists                := GetAddress('OCIObjectExists');\n    @OracleAPI.OCIObjectGetProperty           := GetAddress('OCIObjectGetProperty');\n    @OracleAPI.OCIObjectIsLocked              := GetAddress('OCIObjectIsLocked');\n    @OracleAPI.OCIObjectIsDirty               := GetAddress('OCIObjectIsDirty');\n    @OracleAPI.OCIObjectPinTable              := GetAddress('OCIObjectPinTable');\n    @OracleAPI.OCIObjectArrayPin              := GetAddress('OCIObjectArrayPin');\n    @OracleAPI.OCICacheFlush                  := GetAddress('OCICacheFlush');\n    @OracleAPI.OCICacheRefresh                := GetAddress('OCICacheRefresh');\n    @OracleAPI.OCICacheUnpin                  := GetAddress('OCICacheUnpin');\n    @OracleAPI.OCICacheFree                   := GetAddress('OCICacheFree');\n    @OracleAPI.OCICacheUnmark                 := GetAddress('OCICacheUnmark');\n    @OracleAPI.OCIDurationBegin               := GetAddress('OCIDurationBegin');\n    @OracleAPI.OCIDurationEnd                 := GetAddress('OCIDurationEnd');\n    { < ori.h }\n\n    @OracleAPI.OCILobAppend                   := GetAddress('OCILobAppend');\n    @OracleAPI.OCILobAssign                   := GetAddress('OCILobAssign');\n    @OracleAPI.OCILobCopy                     := GetAddress('OCILobCopy');\n    @OracleAPI.OCILobEnableBuffering          := GetAddress('OCILobEnableBuffering');\n    @OracleAPI.OCILobDisableBuffering         := GetAddress('OCILobDisableBuffering');\n    @OracleAPI.OCILobErase                    := GetAddress('OCILobErase');\n    @OracleAPI.OCILobFileExists               := GetAddress('OCILobFileExists');\n    @OracleAPI.OCILobFileGetName              := GetAddress('OCILobFileGetName');\n    @OracleAPI.OCILobFileSetName              := GetAddress('OCILobFileSetName');\n    @OracleAPI.OCILobFlushBuffer              := GetAddress('OCILobFlushBuffer');\n    @OracleAPI.OCILobGetLength                := GetAddress('OCILobGetLength');\n    @OracleAPI.OCILobLoadFromFile             := GetAddress('OCILobLoadFromFile');\n    @OracleAPI.OCILobLocatorIsInit            := GetAddress('OCILobLocatorIsInit');\n    @OracleAPI.OCILobRead                     := GetAddress('OCILobRead');\n    @OracleAPI.OCILobTrim                     := GetAddress('OCILobTrim');\n    @OracleAPI.OCILobWrite                    := GetAddress('OCILobWrite');\n\n    { For Oracle >= 8.1 }\n    @OracleAPI.OCILobCreateTemporary          := GetAddress('OCILobCreateTemporary');\n    @OracleAPI.OCILobFreeTemporary            := GetAddress('OCILobFreeTemporary');\n    @OracleAPI.OCILobCharSetForm              := GetAddress('OCILobCharSetForm');\n    @OracleAPI.OCILobCharSetId                := GetAddress('OCILobCharSetId');\n    @OracleAPI.OCILobClose                    := GetAddress('OCILobClose');\n    @OracleAPI.OCILobIsOpen                   := GetAddress('OCILobIsOpen');\n    @OracleAPI.OCILobIsTemporary              := GetAddress('OCILobIsTemporary');\n    @OracleAPI.OCILobOpen                     := GetAddress('OCILobOpen');\n\n    @OracleAPI.OCIDateTimeAssign              := GetAddress('OCIDateTimeAssign');\n    @OracleAPI.OCIDateTimeCheck               := GetAddress('OCIDateTimeCheck');\n    @OracleAPI.OCIDateTimeCompare             := GetAddress('OCIDateTimeCompare');\n    @OracleAPI.OCIDateTimeConvert             := GetAddress('OCIDateTimeConvert');\n    @OracleAPI.OCIDateTimeFromText            := GetAddress('OCIDateTimeFromText');\n    @OracleAPI.OCIDateTimeGetDate             := GetAddress('OCIDateTimeGetDate');\n    @OracleAPI.OCIDateTimeGetTime             := GetAddress('OCIDateTimeGetTime');\n    @OracleAPI.OCIDateTimeGetTimeZoneOffset   := GetAddress('OCIDateTimeGetTimeZoneOffset');\n    @OracleAPI.OCIDateTimeSysTimeStamp        := GetAddress('OCIDateTimeSysTimeStamp');\n    @OracleAPI.OCIDateTimeConstruct           := GetAddress('OCIDateTimeConstruct');\n    @OracleAPI.OCIDateTimeToText              := GetAddress('OCIDateTimeToText');\n    @OracleAPI.OCIDateTimeGetTimeZoneName     := GetAddress('OCIDateTimeGetTimeZoneName');\n    @OracleAPI.OCINlsNumericInfoGet           := GetAddress('OCINlsNumericInfoGet');\n    @OracleAPI.OCIClientVersion               := GetAddress('OCIClientVersion');\n\n    { For Oracle < 8.1 }\n    //@OracleAPI.OCILobClose        := GetAddress('OCILobFileClose');\n    //@OracleAPI.OCILobIsOpen       := GetAddress('OCILobFileIsOpen');\n    //@OracleAPI.OCILobOpen         := GetAddress('OCILobFileOpen');\n\n    @OracleAPI.OCIDescribeAny     := GetAddress('OCIDescribeAny');\n\n    { OCI Number mapping }\n    @OracleAPI.OCINumberInc       := GetAddress('OCINumberInc');\n    @OracleAPI.OCINumberDec       := GetAddress('OCINumberDec');\n    @OracleAPI.OCINumberSetZero   := GetAddress('OCINumberSetZero');\n    @OracleAPI.OCINumberSetPi     := GetAddress('OCINumberSetPi');\n    @OracleAPI.OCINumberAdd       := GetAddress('OCINumberAdd');\n    @OracleAPI.OCINumberSub       := GetAddress('OCINumberSub');\n    @OracleAPI.OCINumberMul       := GetAddress('OCINumberMul');\n    @OracleAPI.OCINumberDiv       := GetAddress('OCINumberDiv');\n    @OracleAPI.OCINumberMod       := GetAddress('OCINumberMod');\n    @OracleAPI.OCINumberIntPower  := GetAddress('OCINumberIntPower');\n    @OracleAPI.OCINumberShift     := GetAddress('OCINumberShift');\n    @OracleAPI.OCINumberNeg       := GetAddress('OCINumberNeg');\n    @OracleAPI.OCINumberToText    := GetAddress('OCINumberToText');\n    @OracleAPI.OCINumberFromText  := GetAddress('OCINumberFromText');\n    @OracleAPI.OCINumberToInt     := GetAddress('OCINumberToInt');\n    @OracleAPI.OCINumberFromInt   := GetAddress('OCINumberFromInt');\n    @OracleAPI.OCINumberToReal    := GetAddress('OCINumberToReal');\n    @OracleAPI.OCINumberToRealArray := GetAddress('OCINumberToRealArray');\n    @OracleAPI.OCINumberFromReal  := GetAddress('OCINumberFromReal');\n    @OracleAPI.OCINumberCmp       := GetAddress('OCINumberCmp');\n    @OracleAPI.OCINumberSign      := GetAddress('OCINumberSign');\n    @OracleAPI.OCINumberIsZero    := GetAddress('OCINumberIsZero');\n    @OracleAPI.OCINumberIsInt     := GetAddress('OCINumberIsInt');\n    @OracleAPI.OCINumberAssign    := GetAddress('OCINumberAssign');\n    @OracleAPI.OCINumberAbs       := GetAddress('OCINumberAbs');\n    @OracleAPI.OCINumberCeil      := GetAddress('OCINumberCeil');\n    @OracleAPI.OCINumberFloor     := GetAddress('OCINumberFloor');\n    @OracleAPI.OCINumberSqrt      := GetAddress('OCINumberSqrt');\n    @OracleAPI.OCINumberTrunc     := GetAddress('OCINumberTrunc');\n    @OracleAPI.OCINumberPower     := GetAddress('OCINumberPower');\n    @OracleAPI.OCINumberRound     := GetAddress('OCINumberRound');\n    @OracleAPI.OCINumberPrec      := GetAddress('OCINumberPrec');\n    @OracleAPI.OCINumberSin       := GetAddress('OCINumberSin');\n    @OracleAPI.OCINumberArcSin    := GetAddress('OCINumberArcSin');\n    @OracleAPI.OCINumberHypSin    := GetAddress('OCINumberHypSin');\n    @OracleAPI.OCINumberCos       := GetAddress('OCINumberCos');\n    @OracleAPI.OCINumberArcCos    := GetAddress('OCINumberArcCos');\n    @OracleAPI.OCINumberHypCos    := GetAddress('OCINumberHypCos');\n    @OracleAPI.OCINumberTan       := GetAddress('OCINumberTan');\n    @OracleAPI.OCINumberArcTan    := GetAddress('OCINumberArcTan');\n    @OracleAPI.OCINumberArcTan2   := GetAddress('OCINumberArcTan2');\n    @OracleAPI.OCINumberHypTan    := GetAddress('OCINumberHypTan');\n    @OracleAPI.OCINumberExp       := GetAddress('OCINumberExp');\n    @OracleAPI.OCINumberLn        := GetAddress('OCINumberLn');\n    @OracleAPI.OCINumberLog       := GetAddress('OCINumberLog');\n\n    @OracleAPI.OCITableSize       := GetAddress('OCITableSize');\n    @OracleAPI.OCITableExists     := GetAddress('OCITableExists');\n    @OracleAPI.OCITableDelete     := GetAddress('OCITableDelete');\n    @OracleAPI.OCITableFirst      := GetAddress('OCITableFirst');\n    @OracleAPI.OCITableLast       := GetAddress('OCITableLast');\n    @OracleAPI.OCITableNext       := GetAddress('OCITableNext');\n    @OracleAPI.OCITablePrev       := GetAddress('OCITablePrev');\n\n    @OracleAPI.OCIObjectGetAttr   := GetAddress('OCIObjectGetAttr');\n    @OracleAPI.OCIObjectSetAttr   := GetAddress('OCIObjectSetAttr');\n    {ociap.h}\n    @OracleAPI.OCIPing            := GetAddress('OCIPing');\n    {ort.h}\n    @OracleAPI.OCITypeIterNew     := GetAddress('OCITypeIterNew');\n    @OracleAPI.OCITypeIterFree    := GetAddress('OCITypeIterFree');\n    @OracleAPI.OCITypeByName      := GetAddress('OCITypeByName');\n    @OracleAPI.OCITypeArrayByName := GetAddress('OCITypeArrayByName');\n    @OracleAPI.OCITypeByRef       := GetAddress('OCITypeByRef');\n    @OracleAPI.OCITypeArrayByRef  := GetAddress('OCITypeArrayByRef');\n    @OracleAPI.OCITypeName        := GetAddress('OCITypeName');\n    @OracleAPI.OCITypeSchema      := GetAddress('OCITypeSchema');\n    @OracleAPI.OCITypeTypeCode    := GetAddress('OCITypeTypeCode');\n    @OracleAPI.OCITypeCollTypeCode:= GetAddress('OCITypeCollTypeCode');\n    @OracleAPI.OCITypeVersion     := GetAddress('OCITypeVersion');\n    @OracleAPI.OCITypeAttrs       := GetAddress('OCITypeAttrs');\n    @OracleAPI.OCITypeMethods     := GetAddress('OCITypeMethods');\n    @OracleAPI.OCITypeElemName    := GetAddress('OCITypeElemName');\n    @OracleAPI.OCITypeElemTypeCode:= GetAddress('OCITypeElemTypeCode');\n    @OracleAPI.OCITypeElemType    := GetAddress('OCITypeElemType');\n    @OracleAPI.OCITypeElemFlags   := GetAddress('OCITypeElemFlags');\n    @OracleAPI.OCITypeElemNumPrec := GetAddress('OCITypeElemNumPrec');\n    @OracleAPI.OCITypeElemNumScale:= GetAddress('OCITypeElemNumScale');\n    @OracleAPI.OCITypeElemLength  := GetAddress('OCITypeElemLength');\n    @OracleAPI.OCITypeElemCharSetID := GetAddress('OCITypeElemCharSetID');\n    @OracleAPI.OCITypeElemCharSetForm := GetAddress('OCITypeElemCharSetForm');\n    @OracleAPI.OCITypeElemParameterizedType := GetAddress('OCITypeElemParameterizedType');\n    @OracleAPI.OCITypeElemExtTypeCode := GetAddress('OCITypeElemExtTypeCode');\n    @OracleAPI.OCITypeAttrByName  := GetAddress('OCITypeAttrByName');\n    @OracleAPI.OCITypeAttrNext    := GetAddress('OCITypeAttrNext');\n    @OracleAPI.OCITypeCollElem    := GetAddress('OCITypeCollElem');\n    @OracleAPI.OCITypeCollSize    := GetAddress('OCITypeCollSize');\n    @OracleAPI.OCITypeCollExtTypeCode := GetAddress('OCITypeCollExtTypeCode');\n    @OracleAPI.OCITypeMethodOverload  := GetAddress('OCITypeMethodOverload');\n    @OracleAPI.OCITypeMethodByName:= GetAddress('OCITypeMethodByName');\n    @OracleAPI.OCITypeMethodNext  := GetAddress('OCITypeMethodNext');\n    @OracleAPI.OCITypeMethodName  := GetAddress('OCITypeMethodName');\n    @OracleAPI.OCITypeMethodEncap := GetAddress('OCITypeMethodEncap');\n    @OracleAPI.OCITypeMethodFlags := GetAddress('OCITypeMethodFlags');\n    @OracleAPI.OCITypeMethodMap   := GetAddress('OCITypeMethodMap');\n    @OracleAPI.OCITypeMethodOrder := GetAddress('OCITypeMethodOrder');\n    @OracleAPI.OCITypeMethodParams:= GetAddress('OCITypeMethodParams');\n    @OracleAPI.OCITypeResult      := GetAddress('OCITypeResult');\n    @OracleAPI.OCITypeParamByPos  := GetAddress('OCITypeParamByPos');\n    @OracleAPI.OCITypeParamByName := GetAddress('OCITypeParamByName');\n    @OracleAPI.OCITypeParamPos    := GetAddress('OCITypeParamPos');\n    @OracleAPI.OCITypeElemParamMode := GetAddress('OCITypeElemParamMode');\n    @OracleAPI.OCITypeElemDefaultValue := GetAddress('OCITypeElemDefaultValue');\n    @OracleAPI.OCITypeVTInit      := GetAddress('OCITypeVTInit');\n    @OracleAPI.OCITypeVTInsert    := GetAddress('OCITypeVTInsert');\n    @OracleAPI.OCITypeVTSelect    := GetAddress('OCITypeVTSelect');\n  end;\nend;\n\nfunction TZOracle9iPlainDriver.Clone: IZPlainDriver;\nbegin\n  Result := TZOracle9iPlainDriver.Create;\nend;\n\nconstructor TZOracle9iPlainDriver.Create;\nbegin\n  inherited create;\n  FLoader := TZNativeLibraryLoader.Create([]);\n  {$IFNDEF UNIX}\n    FLoader.AddLocation(WINDOWS_DLL_LOCATION);\n  {$ELSE}\n    FLoader.AddLocation(LINUX_DLL_LOCATION);\n  {$ENDIF}\n  LoadCodePages;\nend;\n\nfunction TZOracle9iPlainDriver.GetProtocol: string;\nbegin\n  Result := 'oracle-9i';\nend;\n\nfunction TZOracle9iPlainDriver.GetDescription: string;\nbegin\n  Result := 'Native Plain Driver for Oracle 9i';\nend;\n\nprocedure TZOracle9iPlainDriver.Initialize(const Location: String);\nbegin\n  inherited Initialize(Location);\n  OracleAPI.OCIInitialize(OCI_THREADED, nil, nil, nil, nil);\nend;\n\nfunction TZOracle9iPlainDriver.AttrGet(trgthndlp: POCIHandle;\n  trghndltyp: ub4; attributep, sizep: Pointer; attrtype: ub4;\n  errhp: POCIError): sword;\nbegin\n  Result := OracleAPI.OCIAttrGet(trgthndlp, trghndltyp, attributep, sizep,\n    attrtype, errhp);\nend;\n\nfunction TZOracle9iPlainDriver.AttrSet(trgthndlp: POCIHandle;\n  trghndltyp: ub4; attributep: Pointer; size, attrtype: ub4;\n  errhp: POCIError): sword;\nbegin\n  Result := OracleAPI.OCIAttrSet(trgthndlp, trghndltyp, attributep, size,\n    attrtype, errhp);\nend;\n\nfunction TZOracle9iPlainDriver.BindByName(stmtp: POCIStmt;\n  var bindpp: POCIBind; errhp: POCIError; placeholder: text;\n  placeh_len: sb4; valuep: Pointer; value_sz: sb4; dty: ub2; indp, alenp,\n  rcodep: Pointer; maxarr_len: ub4; curelep: Pointer; mode: ub4): sword;\nbegin\n  Result := OracleAPI.OCIBindByName(stmtp, bindpp, errhp, placeholder,\n    placeh_len, valuep, value_sz, dty, indp, alenp, rcodep, maxarr_len,\n    curelep, mode);\nend;\n\nfunction TZOracle9iPlainDriver.BindByPos(stmtp: POCIStmt;\n  var bindpp: POCIBind; errhp: POCIError; position: ub4; valuep: Pointer;\n  value_sz: sb4; dty: ub2; indp, alenp, rcodep: Pointer; maxarr_len: ub4;\n  curelep: Pointer; mode: ub4): sword;\nbegin\n  Result := OracleAPI.OCIBindByPos(stmtp, bindpp, errhp, position, valuep,\n    value_sz, dty, indp, alenp, rcodep, maxarr_len, curelep, mode);\nend;\n\nfunction TZOracle9iPlainDriver.BindDynamic(bindp: POCIBind;\n  errhp: POCIError; ictxp, icbfp, octxp, ocbfp: Pointer): sword;\nbegin\n  Result := OracleAPI.OCIBindDynamic(bindp, errhp, ictxp, icbfp, octxp,\n    ocbfp);\nend;\n\nfunction TZOracle9iPlainDriver.BindObject(bindp: POCIBind; errhp: POCIError;\n                const _type: POCIType; pgvpp: PPointer;\n                pvszsp: pub4; indpp: PPointer;\n                indszp: pub4): sword;\nbegin\n  Result := OracleAPI.OCIBindObject(bindp, errhp, _type, pgvpp, pvszsp, indpp,\n    indszp);\nend;\n\nfunction TZOracle9iPlainDriver.DefineObject(defnpp: POCIDefine;\n  errhp: POCIError; _type: POCIHandle; pgvpp,pvszsp,indpp,indszp:pointer): sword;\nbegin\n  Result := OracleAPI.OCIDefineObject(defnpp, errhp, _type, pgvpp, pvszsp,\n    indpp, indszp);\nend;\n\n{ > ori.h}\nfunction TZOracle9iPlainDriver.ObjectNew(env: POCIEnv; err: POCIError;\n  const svc: POCISvcCtx; typecode: OCITypeCode; tdo: POCIType; table: Pointer;\n  duration: OCIDuration; value: Longbool; instance: PPointer): sword;\nbegin\n  Result := OracleAPI.OCIObjectNew(env, err, svc, typecode, tdo, table,\n    duration, value, instance);\nend;\n\nfunction TZOracle9iPlainDriver.ObjectPin(env: POCIEnv; err: POCIError;\n  const object_ref: POCIRef; const corhdl: POCIComplexObject;\n  const pin_option: OCIPinOpt; const pin_duration: OCIDuration;\n  const lock_option: OCILockOpt; _object: PPointer): sword;\nbegin\n  Result := OracleAPI.OCIObjectPin(env, err, object_ref, corhdl,\n    pin_option, pin_duration, lock_option, _object);\nend;\n\nfunction TZOracle9iPlainDriver.ObjectUnpin(env: POCIEnv; err: POCIError;\n  const _object: Pointer): sword;\nbegin\n  Result := OracleAPI.OCIObjectUnpin(env, err, _object);\nend;\n\nfunction TZOracle9iPlainDriver.ObjectPinCountReset(env: POCIEnv; err: POCIError;\n  const _object: pointer): sword;\nbegin\n  Result := OracleAPI.OCIObjectPinCountReset(env, err, _object);\nend;\n\nfunction TZOracle9iPlainDriver.ObjectLock(env: POCIEnv; err: POCIError;\n  const _object: pointer): sword;\nbegin\n  Result := OracleAPI.OCIObjectLock(env, err, _object);\nend;\n\nfunction TZOracle9iPlainDriver.ObjectLockNoWait(env: POCIEnv; err: POCIError;\n  const _object: pointer): sword;\nbegin\n  Result := OracleAPI.OCIObjectLockNoWait(env, err, _object);\nend;\n\nfunction TZOracle9iPlainDriver.ObjectMarkUpdate(env: POCIEnv; err: POCIError;\n  const _object: pointer): sword;\nbegin\n  Result := OracleAPI.OCIObjectMarkUpdate(env, err, _object);\nend;\n\nfunction TZOracle9iPlainDriver.ObjectUnmark(env: POCIEnv; err: POCIError;\n  const _object:pointer): sword;\nbegin\n  Result := OracleAPI.OCIObjectUnmark(env, err, _object);\nend;\n\nfunction TZOracle9iPlainDriver.ObjectUnmarkByRef(env: POCIEnv; err: POCIError;\n  const ref: POCIRef): sword;\nbegin\n  Result := OracleAPI.OCIObjectUnmarkByRef(env, err, ref);\nend;\n\nfunction TZOracle9iPlainDriver.ObjectFree(hndl: POCIEnv; err: POCIError;\n  instance:POCIHandle;flags :ub2):sword;\nbegin\n  Result := OracleAPI.OCIObjectFree(hndl, err, instance, flags);\nend;\n\nfunction TZOracle9iPlainDriver.ObjectMarkDeleteByRef(env: POCIEnv;\n  err: POCIError; const object_ref:POCIRef): sword;\nbegin\n  Result := OracleAPI.OCIObjectMarkDeleteByRef(env, err, object_ref);\nend;\n\nfunction TZOracle9iPlainDriver.ObjectMarkDelete(env: POCIEnv; err: POCIError;\n  const instance:pointer): sword;\nbegin\n  Result := OracleAPI.OCIObjectMarkDelete(env, err, instance);\nend;\n\nfunction TZOracle9iPlainDriver.ObjectFlush(env: POCIEnv; err: POCIError;\n  const _object: pointer): sword;\nbegin\n  Result := OracleAPI.OCIObjectFlush(env, err, _object);\nend;\n\nfunction TZOracle9iPlainDriver.ObjectRefresh(env: POCIEnv; err: POCIError;\n  _object: pointer): sword;\nbegin\n  Result := OracleAPI.OCIObjectRefresh(env, err, _object);\nend;\n\nfunction TZOracle9iPlainDriver.ObjectCopy(env: POCIEnv; err: POCIError;\n  const svc: POCISvcCtx; const source, null_source, target, null_target: pointer;\n  const tdo: POCIType; const duration: OCIDuration; const option: ub1): sword;\nbegin\n  Result := OracleAPI.OCIObjectCopy(env, err, svc, source, null_source, target,\n    null_target, tdo, duration, option);\nend;\n\nfunction TZOracle9iPlainDriver.ObjectGetTypeRef(env: POCIEnv; err: POCIError;\n  const instance:pointer; type_ref: POCIRef): sword;\nbegin\n  Result := OracleAPI.OCIObjectGetTypeRef(env, err, instance, type_ref);\nend;\n\nfunction TZOracle9iPlainDriver.ObjectGetObjectRef(env: POCIEnv; err: POCIError;\n  const _object: pointer; object_ref: POCIRef): sword;\nbegin\n  Result := OracleAPI.OCIObjectGetObjectRef(env, err, _object, object_ref);\nend;\n\nfunction TZOracle9iPlainDriver.ObjectMakeObjectRef(env: POCIEnv; err: POCIError;\n  const svc: POCISvcCtx; const table: pointer; const values: PPointer;\n  const array_len: ub4; object_ref: POCIRef): sword;\nbegin\n  Result := OracleAPI.OCIObjectMakeObjectRef(env, err, svc, table, values,\n    array_len, object_ref);\nend;\n\nfunction TZOracle9iPlainDriver.ObjectGetPrimaryKeyTypeRef(env: POCIEnv;\n  err: POCIError; const svc:POCISvcCtx; const table: pointer;\n  type_ref: POCIRef): sword;\nbegin\n  Result := OracleAPI.OCIObjectGetPrimaryKeyTypeRef(env, err, svc, table,\n    type_ref);\nend;\n\nfunction TZOracle9iPlainDriver.ObjectGetInd(env: POCIEnv; err: POCIError;\n  const instance: pointer; null_struct: PPointer): sword;\nbegin\n  Result := OracleAPI.OCIObjectGetInd(env, err, instance, null_struct);\nend;\n\nfunction TZOracle9iPlainDriver.ObjectExists(env: POCIEnv; err: POCIError;\n  const ins: pointer; exist: PBoolean): sword;\nbegin\n  Result := OracleAPI.OCIObjectExists(env, err, ins, exist);\nend;\n\nfunction TZOracle9iPlainDriver.ObjectGetProperty(envh: POCIEnv; errh: POCIError;\n  const obj: pointer; const propertyId: OCIObjectPropId;\n  _property: pointer; size: Pub4): sword;\nbegin\n  Result := OracleAPI.OCIObjectGetProperty(envh, errh, obj, propertyId,\n    _property, size);\nend;\n\nfunction TZOracle9iPlainDriver.ObjectIsLocked(env: POCIEnv; err: POCIError;\n  const ins: pointer; lock: Pboolean): sword;\nbegin\n  Result := OracleAPI.OCIObjectIsLocked(env, err, ins, lock);\nend;\n\nfunction TZOracle9iPlainDriver.ObjectIsDirty(env: POCIEnv; err: POCIError;\n  const ins: pointer; dirty: PBoolean): sword;\nbegin\n  Result := OracleAPI.OCIObjectIsDirty(env, err, ins, dirty);\nend;\n\nfunction TZOracle9iPlainDriver.ObjectPinTable(env: POCIEnv; err: POCIError;\n  const svc:POCISvcCtx; const schema_name: Poratext; const s_n_length: ub4;\n  const object_name: Poratext; const o_n_length:ub4;\n  const scope_obj_ref: POCIRef; const pin_duration: OCIDuration;\n  _object: PPointer): sword;\nbegin\n  Result := OracleAPI.OCIObjectPinTable(env, err, svc, schema_name, s_n_length,\n    object_name, o_n_length, scope_obj_ref, pin_duration, _object);\nend;\n\nfunction TZOracle9iPlainDriver.ObjectArrayPin(env: POCIEnv; err: POCIError;\n  const ref_array: PPOCIRef; const array_size: ub4;\n  const cor_array: PPOCIComplexObject; const cor_array_size: ub4;\n  const pin_option: OCIPinOpt; const pin_duration: OCIDuration;\n  const lock: OCILockOpt; obj_array: PPointer;\n  pos: Pub4): sword;\nbegin\n  Result := OracleAPI.OCIObjectArrayPin(env, err, ref_array, array_size,\n    cor_array, cor_array_size, pin_option, pin_duration, lock, obj_array, pos);\nend;\n\nfunction TZOracle9iPlainDriver.CacheFlush(env: POCIEnv; err: POCIError;\n  const svc:POCISvcCtx; const context: pointer; const get: TOCICacheFlushGet;\n  ref: PPOCIRef): sword;\nbegin\n  Result := OracleAPI.OCICacheFlush(env, err, svc, context, get, ref);\nend;\n\nfunction TZOracle9iPlainDriver.CacheRefresh(env: POCIEnv; err: POCIError;\n  const svc:POCISvcCtx; const option: OCIRefreshOpt; const context: pointer;\n  get: TOCICacheRefreshGet; ref: PPOCIRef): sword;\nbegin\n  Result := OracleAPI.OCICacheRefresh(env, err, svc, option, context, get, ref);\nend;\n\nfunction TZOracle9iPlainDriver.CacheUnpin(env: POCIEnv; err: POCIError;\n  const svc:POCISvcCtx): sword;\nbegin\n  Result := OracleAPI.OCICacheUnpin(env, err, svc);\nend;\n\nfunction TZOracle9iPlainDriver.CacheFree(env: POCIEnv; err: POCIError;\n  const svc: POCISvcCtx): sword;\nbegin\n  Result := OracleAPI.OCICacheFree(env, err, svc);\nend;\n\nfunction TZOracle9iPlainDriver.CacheUnmark(env: POCIEnv; err: POCIError;\n  const svc: POCISvcCtx): sword;\nbegin\n  Result := OracleAPI.OCICacheUnmark(env, err, svc);\nend;\n\nfunction TZOracle9iPlainDriver.DurationBegin(env: POCIEnv; err: POCIError;\n  svc: POCISvcCtx; const parent: OCIDuration;\n  dur: POCIDuration): sword;\nbegin\n  Result := OracleAPI.OCIDurationBegin(env, err, svc, parent, dur);\nend;\n\nfunction TZOracle9iPlainDriver.DurationEnd(env: POCIEnv; err: POCIError;\n  svc: POCISvcCtx; duration: OCIDuration): sword;\nbegin\n  Result := OracleAPI.OCIDurationEnd(env, err, svc, duration);\nend;\n{ < ori.h}\n\nfunction TZOracle9iPlainDriver.Break(svchp: POCISvcCtx;\n  errhp: POCIError): sword;\nbegin\n  Result := OracleAPI.OCIBreak(svchp, errhp);\nend;\n\nfunction TZOracle9iPlainDriver.DefineArrayOfStruct(defnpp: POCIDefine;\n  errhp: POCIError; pvskip, indskip, rlskip, rcskip: ub4): sword;\nbegin\n  Result := OracleAPI.OCIDefineArrayOfStruct(defnpp, errhp, pvskip,\n    indskip, rlskip, rcskip);\nend;\n\nfunction TZOracle9iPlainDriver.DefineByPos(stmtp: POCIStmt;\n  var defnpp: POCIDefine; errhp: POCIError; position: ub4; valuep: Pointer;\n  value_sz: sb4; dty: ub2; indp, rlenp, rcodep: Pointer; mode: ub4): sword;\nbegin\n  Result := OracleAPI.OCIDefineByPos(stmtp, defnpp, errhp, position,\n    valuep, value_sz, dty, indp, rlenp, rcodep, mode);\nend;\n\nfunction TZOracle9iPlainDriver.DescribeAny(svchp: POCISvcCtx;\n  errhp: POCIError; objptr: Pointer; objnm_len: ub4; objptr_typ,\n  info_level, objtyp: ub1; dschp: POCIDescribe): sword;\nbegin\n  Result := OracleAPI.OCIDescribeAny(svchp, errhp, objptr,\n    objnm_len, objptr_typ, info_level, objtyp, dschp);\nend;\n\nfunction TZOracle9iPlainDriver.DescriptorAlloc(parenth: POCIEnv;\n  var descpp: POCIDescriptor; htype: ub4; xtramem_sz: integer;\n  usrmempp: Pointer): sword;\nbegin\n  Result := OracleAPI.OCIDescriptorAlloc(parenth, descpp, htype,\n    xtramem_sz, usrmempp);\nend;\n\nfunction TZOracle9iPlainDriver.DescriptorFree(descp: Pointer;\n  htype: ub4): sword;\nbegin\n  Result := OracleAPI.OCIDescriptorFree(descp, htype);\nend;\n\nfunction TZOracle9iPlainDriver.EnvCreate(var envhpp: POCIEnv; mode: ub4;\n  ctxp: Pointer; malocfp: Pointer; ralocfp: Pointer; mfreefp: Pointer;\n  xtramemsz: size_T; usrmempp: PPointer): sword;\nbegin\n  Result := OracleAPI.OCIEnvCreate(envhpp, mode, ctxp, malocfp, ralocfp,\n    mfreefp, xtramemsz, usrmempp);\nend;\n\nfunction TZOracle9iPlainDriver.EnvNlsCreate(var envhpp: POCIEnv; mode: ub4;\n  ctxp: Pointer; malocfp: Pointer; ralocfp: Pointer; mfreefp: Pointer;\n  xtramemsz: size_T; usrmempp: PPointer; charset, ncharset: ub2): sword;\nbegin\n  Result := OracleAPI.OCIEnvNlsCreate(envhpp, mode, ctxp, malocfp, ralocfp,\n    mfreefp, xtramemsz, usrmempp, charset, ncharset);\nend;\n\nfunction TZOracle9iPlainDriver.EnvInit(var envhpp: POCIEnv; mode: ub4;\n  xtramemsz: size_T; usrmempp: PPointer): sword;\nbegin\n  Result := OracleAPI.OCIEnvInit(envhpp, mode, xtramemsz, usrmempp);\nend;\n\nfunction TZOracle9iPlainDriver.ErrorGet(hndlp: Pointer; recordno: ub4;\n  sqlstate: text; var errcodep: sb4; bufp: text; bufsiz,\n  atype: ub4): sword;\nbegin\n  Result := OracleAPI.OCIErrorGet(hndlp, recordno, sqlstate, errcodep,\n    bufp, bufsiz, atype);\nend;\n\nfunction TZOracle9iPlainDriver.HandleAlloc(parenth: POCIHandle;\n  var hndlpp: POCIHandle; atype: ub4; xtramem_sz: size_T;\n  usrmempp: PPointer): sword;\nbegin\n  Result := OracleAPI.OCIHandleAlloc(parenth, hndlpp, atype, xtramem_sz,\n    usrmempp);\nend;\n\nfunction TZOracle9iPlainDriver.HandleFree(hndlp: Pointer; atype: ub4): sword;\nbegin\n  Result := OracleAPI.OCIHandleFree(hndlp, atype);\nend;\n\nfunction TZOracle9iPlainDriver.Initializ(mode: ub4; ctxp, malocfp,\n  ralocfp, mfreefp: Pointer): sword;\nbegin\n  Result := OracleAPI.OCIInitialize(mode, ctxp, malocfp, ralocfp, mfreefp);\nend;\n\nfunction TZOracle9iPlainDriver.LobAppend(svchp: POCISvcCtx;\n  errhp: POCIError; dst_locp, src_locp: POCILobLocator): sword;\nbegin\n  Result := OracleAPI.OCILobAppend(svchp, errhp, dst_locp, src_locp);\nend;\n\nfunction TZOracle9iPlainDriver.LobAssign(svchp: POCISvcCtx; errhp: POCIError;\n  src_locp: POCILobLocator; var dst_locpp: POCILobLocator): sword;\nbegin\n  Result := OracleAPI.OCILobAssign(svchp, errhp, src_locp, dst_locpp);\nend;\n\nfunction TZOracle9iPlainDriver.LobClose(svchp: POCISvcCtx;\n  errhp: POCIError; locp: POCILobLocator): sword;\nbegin\n  Result := OracleAPI.OCILobClose(svchp, errhp, locp);\nend;\n\nfunction TZOracle9iPlainDriver.LobCopy(svchp: POCISvcCtx; errhp: POCIError;\n  dst_locp, src_locp: POCILobLocator; amount, dst_offset,\n  src_offset: ub4): sword;\nbegin\n  Result := OracleAPI.OCILobCopy(svchp, errhp, dst_locp, src_locp,\n    amount, dst_offset, src_offset);\nend;\n\nfunction TZOracle9iPlainDriver.LobDisableBuffering(svchp: POCISvcCtx;\n  errhp: POCIError; locp: POCILobLocator): sword;\nbegin\n  Result := OracleAPI.OCILobDisableBuffering(svchp, errhp, locp);\nend;\n\nfunction TZOracle9iPlainDriver.LobEnableBuffering(svchp: POCISvcCtx;\n  errhp: POCIError; locp: POCILobLocator): sword;\nbegin\n  Result := OracleAPI.OCILobEnableBuffering(svchp, errhp, locp);\nend;\n\nfunction TZOracle9iPlainDriver.LobErase(svchp: POCISvcCtx;\n  errhp: POCIError; locp: POCILobLocator; var amount: ub4;\n  offset: ub4): sword;\nbegin\n  Result := OracleAPI.OCILobErase(svchp, errhp, locp, amount, offset);\nend;\n\nfunction TZOracle9iPlainDriver.LobFileExists(svchp: POCISvcCtx;\n  errhp: POCIError; filep: POCILobLocator; var flag: Boolean): sword;\nbegin\n  Result := OracleAPI.OCILobFileExists(svchp, errhp, filep, flag);\nend;\n\nfunction TZOracle9iPlainDriver.LobFileGetName(envhp: POCIEnv;\n  errhp: POCIError; filep: POCILobLocator; dir_alias: text;\n  var d_length: ub2; filename: text; var f_length: ub2): sword;\nbegin\n  Result := OracleAPI.OCILobFileGetName(envhp, errhp, filep, dir_alias,\n    d_length, filename, f_length);\nend;\n\nfunction TZOracle9iPlainDriver.LobFileSetName(envhp: POCIEnv;\n  errhp: POCIError; var filep: POCILobLocator; dir_alias: text;\n  d_length: ub2; filename: text; f_length: ub2): sword;\nbegin\n  Result := OracleAPI.OCILobFileSetName(envhp, errhp, filep, dir_alias,\n    d_length, filename, f_length);\nend;\n\nfunction TZOracle9iPlainDriver.LobFlushBuffer(svchp: POCISvcCtx;\n  errhp: POCIError; locp: POCILobLocator; flag: ub4): sword;\nbegin\n  Result := OracleAPI.OCILobFlushBuffer(svchp, errhp, locp, flag);\nend;\n\nfunction TZOracle9iPlainDriver.LobGetLength(svchp: POCISvcCtx;\n  errhp: POCIError; locp: POCILobLocator; var lenp: ub4): sword;\nbegin\n  Result := OracleAPI.OCILobGetLength(svchp, errhp, locp, lenp);\nend;\n\nfunction TZOracle9iPlainDriver.LobIsOpen(svchp: POCISvcCtx;\n  errhp: POCIError; locp: POCILobLocator; var flag: LongBool): sword;\nbegin\n  Result := OracleAPI.OCILobIsOpen(svchp, errhp, locp, flag);\nend;\n\nfunction TZOracle9iPlainDriver.LobLoadFromFile(svchp: POCISvcCtx;\n  errhp: POCIError; dst_locp, src_locp: POCILobLocator; amount, dst_offset,\n  src_offset: ub4): sword;\nbegin\n  Result := OracleAPI.OCILobLoadFromFile(svchp, errhp, dst_locp, src_locp,\n    amount, dst_offset, src_offset);\nend;\n\nfunction TZOracle9iPlainDriver.LobLocatorIsInit(envhp: POCIEnv;\n  errhp: POCIError; locp: POCILobLocator;\n  var is_initialized: LongBool): sword;\nbegin\n  Result := OracleAPI.OCILobLocatorIsInit(envhp, errhp, locp,\n    is_initialized);\nend;\n\nfunction TZOracle9iPlainDriver.LobOpen(svchp: POCISvcCtx; errhp: POCIError;\n  locp: POCILobLocator; mode: ub1): sword;\nbegin\n  Result := OracleAPI.OCILobOpen(svchp, errhp, locp, mode);\nend;\n\nfunction TZOracle9iPlainDriver.LobRead(svchp: POCISvcCtx; errhp: POCIError;\n  locp: POCILobLocator; var amtp: ub4; offset: ub4; bufp: Pointer;\n  bufl: ub4; ctxp, cbfp: Pointer; csid: ub2; csfrm: ub1): sword;\nbegin\n  Result := OracleAPI.OCILobRead(svchp, errhp, locp, amtp, offset, bufp,\n    bufl, ctxp, cbfp, csid, csfrm);\nend;\n\nfunction TZOracle9iPlainDriver.LobTrim(svchp: POCISvcCtx; errhp: POCIError;\n  locp: POCILobLocator; newlen: ub4): sword;\nbegin\n  Result := OracleAPI.OCILobTrim(svchp, errhp, locp, newlen);\nend;\n\nfunction TZOracle9iPlainDriver.LobWrite(svchp: POCISvcCtx;\n  errhp: POCIError; locp: POCILobLocator; var amtp: ub4; offset: ub4;\n  bufp: Pointer; bufl: ub4; piece: ub1; ctxp, cbfp: Pointer; csid: ub2;\n  csfrm: ub1): sword;\nbegin\n  Result := OracleAPI.OCILobWrite(svchp, errhp, locp, amtp, offset,\n    bufp, bufl, piece, ctxp, cbfp, csid, csfrm);\nend;\n\nfunction TZOracle9iPlainDriver.LobCreateTemporary(svchp: POCISvcCtx;\n  errhp: POCIError; locp: POCILobLocator; csid: ub2; csfrm, lobtype: ub1;\n  cache: LongBool; duration: OCIDuration): sword;\nbegin\n  Result := OracleAPI.OCILobCreateTemporary(svchp, errhp, locp,\n    csid, csfrm, lobtype, cache, duration);\nend;\n\nfunction TZOracle9iPlainDriver.LobFreeTemporary(svchp: POCISvcCtx;\n  errhp: POCIError; locp: POCILobLocator): sword;\nbegin\n  Result := OracleAPI.OCILobFreeTemporary(svchp, errhp, locp);\nend;\n\nfunction TZOracle9iPlainDriver.LobCharSetForm ( envhp: POCIEnv; errhp: POCIError;\n    const locp: POCILobLocator; csfrm: pub1): sword;\nbegin\n  Result := OracleAPI.OCILobCharSetForm(envhp, errhp, locp, csfrm);\nend;\n\nfunction TZOracle9iPlainDriver.LobCharSetId ( envhp: POCIEnv; errhp: POCIError;\n    const locp: POCILobLocator; csid: pub2): sword;\nbegin\n  Result := OracleAPI.OCILobCharSetId (envhp, errhp, locp, csid);\nend;\n\nfunction TZOracle9iPlainDriver.LobIsTemporary(svchp: POCISvcCtx;\n  errhp: POCIError; locp: POCILobLocator;\n  var is_temporary: LongBool): sword;\nbegin\n  Result := OracleAPI.OCILobIsTemporary(svchp, errhp, locp, is_temporary);\nend;\n\nfunction TZOracle9iPlainDriver.ParamGet(hndlp: Pointer; htype: ub4;\n  errhp: POCIError; var parmdpp: Pointer; pos: ub4): sword;\nbegin\n  Result := OracleAPI.OCIParamGet(hndlp, htype, errhp, parmdpp, pos);\nend;\n\nfunction TZOracle9iPlainDriver.PasswordChange(svchp: POCISvcCtx;\n  errhp: POCIError; user_name: text; usernm_len: ub4; opasswd: text;\n  opasswd_len: ub4; npasswd: text; npasswd_len: sb4; mode: ub4): sword;\nbegin\n  Result := OracleAPI.OCIPasswordChange(svchp, errhp, user_name,\n    usernm_len, opasswd, opasswd_len, npasswd, npasswd_len, mode);\nend;\n\nfunction TZOracle9iPlainDriver.Reset(svchp: POCISvcCtx;\n  errhp: POCIError): sword;\nbegin\n  Result := OracleAPI.OCIReset(svchp, errhp);\nend;\n\nfunction TZOracle9iPlainDriver.ResultSetToStmt(rsetdp: POCIHandle;\n  errhp: POCIError): sword;\nbegin\n  Result := OracleAPI.OCIResultSetToStmt(rsetdp, errhp);\nend;\n\nfunction TZOracle9iPlainDriver.GetEnvCharsetByteWidth(hndl: POCIEnv; err: POCIError;\n  Value: sb4): sword;\nbegin\n  Result := OracleAPI.OCINlsNumericInfoGet(hndl, err, @value, OCI_NLS_CHARSET_MAXBYTESZ);\nend;\n\nprocedure TZOracle9iPlainDriver.ClientVersion(major_version, minor_version,\n  update_num, patch_num, port_update_num: psword);\nbegin\n  OracleAPI.OCIClientVersion(major_version, minor_version,\n    update_num, patch_num, port_update_num);\nend;\n\nfunction TZOracle9iPlainDriver.NumberInc(err: POCIError; number: POCINumber): sword;\nbegin\n  Result := OracleAPI.OCINumberInc(err, number);\nend;\n\nfunction TZOracle9iPlainDriver.NumberDec(err: POCIError; number: POCINumber): sword;\nbegin\n  Result := OracleAPI.OCINumberDec(err, number);\nend;\n\nprocedure TZOracle9iPlainDriver.NumberSetZero(err: POCIError; number: POCINumber);\nbegin\n  OracleAPI.OCINumberSetZero(err, number);\nend;\n\nprocedure TZOracle9iPlainDriver.NumberSetPi(err: POCIError; number: POCINumber);\nbegin\n  OracleAPI.OCINumberSetPi(err, number);\nend;\n\nfunction  TZOracle9iPlainDriver.NumberAdd(err: POCIError; const number1: POCINumber;\n  const number2: POCINumber; _result: POCINumber): sword;\nbegin\n  Result := OracleAPI.OCINumberAdd(err, number1, number2, _result);\nend;\n\nfunction TZOracle9iPlainDriver.NumberSub(err: POCIError; const number1: POCINumber;\n  const number2: POCINumber; _result: POCINumber): sword;\nbegin\n  Result := OracleAPI.OCINumberSub(err, number1, number2, _result);\nend;\n\nfunction TZOracle9iPlainDriver.NumberMul(err: POCIError; const number1: POCINumber;\n  const number2: POCINumber; _result: POCINumber): sword;\nbegin\n  Result := OracleAPI.OCINumberMul(err, number1, number2, _result);\nend;\n\nfunction TZOracle9iPlainDriver.NumberDiv(err: POCIError; const number1: POCINumber;\n  const number2: POCINumber; _result: POCINumber): sword;\nbegin\n  Result := OracleAPI.OCINumberDiv(err, number1, number2, _result);\nend;\n\nfunction TZOracle9iPlainDriver.NumberMod(err: POCIError; const number1: POCINumber;\n  const number2: POCINumber; _result: POCINumber): sword;\nbegin\n  Result := OracleAPI.OCINumberMod(err, number1, number2, _result);\nend;\n\nfunction TZOracle9iPlainDriver.NumberIntPower(err: POCIError; const number1: POCINumber;\n  const number2: POCINumber; _result: POCINumber): sword;\nbegin\n  Result := OracleAPI.OCINumberIntPower(err, number1, number2, _result);\nend;\n\nfunction TZOracle9iPlainDriver.NumberShift(err: POCIError; const number: POCINumber;\n  const nDig: sword; _result: POCINumber): sword;\nbegin\n  Result := OracleAPI.OCINumberShift(err, number, nDig, _result);\nend;\n\nfunction TZOracle9iPlainDriver.NumberNeg(err: POCIError; const number: POCINumber;\n  _result: POCINumber): sword;\nbegin\n  Result := OracleAPI.OCINumberNeg(err, number, _result);\nend;\n\nfunction TZOracle9iPlainDriver.NumberToText(err: POCIError; const number: POCINumber;\n  const fmt: Poratext; fmt_length: ub4; const nls_params: Poratext;\n  nls_p_length: ub4; buf_size: pub4; buf: poratext): sword;\nbegin\n  Result := OracleAPI.OCINumberToText(err, number, fmt, fmt_length, nls_params,\n    nls_p_length, buf_size, buf);\nend;\n\nfunction TZOracle9iPlainDriver.NumberFromText(err: POCIError; const str: poratext;\n  str_length: ub4; const fmt: poratext; fmt_length: ub4;\n  const nls_params: poratext; nls_p_length: ub4; number: POCINumber): sword;\nbegin\n  Result := OracleAPI.OCINumberFromText(err, str, str_length, fmt, fmt_length,\n    nls_params, nls_p_length, number);\nend;\n\nfunction TZOracle9iPlainDriver.NumberToInt(err: POCIError; const number: POCINumber;\n  rsl_length: uword; rsl_flag: uword; rsl: Pointer): sword;\nbegin\n  Result := OracleAPI.OCINumberToInt(err, number, rsl_length, rsl_flag, rsl);\nend;\n\nfunction TZOracle9iPlainDriver.NumberFromInt(err: POCIError; const inum: Pointer;\n  inum_length: uword; inum_s_flag: uword; number: POCINumber): sword;\nbegin\n  Result := OracleAPI.OCINumberFromInt(err, inum, inum_length, inum_s_flag, number);\nend;\n\nfunction TZOracle9iPlainDriver.NumberToReal(err: POCIError; const number: POCINumber;\n  rsl_length: uword; rsl: Pointer): sword;\nbegin\n  Result := OracleAPI.OCINumberToReal(err, number, rsl_length, rsl);\nend;\n\nfunction TZOracle9iPlainDriver.NumberToRealArray(err: POCIError; const number: PPOCINumber;\n  elems: uword; rsl_length: uword; rsl: Pointer): sword;\nbegin\n  Result := OracleAPI.OCINumberToRealArray(err, number, elems, rsl_length, rsl);\nend;\n\nfunction TZOracle9iPlainDriver.NumberFromReal(err: POCIError; const rnum: Pointer;\n  rnum_length: uword; number: POCINumber): sword;\nbegin\n  Result := OracleAPI.OCINumberFromReal(err, rnum, rnum_length, number);\nend;\n\nfunction TZOracle9iPlainDriver.NumberCmp(err: POCIError; const number1: POCINumber;\n  const number2: POCINumber; _result: psword): sword;\nbegin\n  Result := OracleAPI.OCINumberCmp(err, number1, number2, _result);\nend;\n\nfunction TZOracle9iPlainDriver.NumberSign(err: POCIError; const number: POCINumber;\n  _result: psword): sword;\nbegin\n  Result := OracleAPI.OCINumberSign(err, number, _result);\nend;\n\nfunction TZOracle9iPlainDriver.NumberIsZero(err: POCIError; const number: POCINumber;\n  _Result: pboolean): sword;\nbegin\n  Result := OracleAPI.OCINumberIsZero(err, number, _result);\nend;\n\nfunction TZOracle9iPlainDriver.NumberIsInt(err: POCIError; const number: POCINumber;\n  _result: Pboolean): sword;\nbegin\n  Result := OracleAPI.OCINumberIsInt(err, number, _result);\nend;\n\nfunction TZOracle9iPlainDriver.NumberAssign(err: POCIError; const from: POCINumber;\n  _to: POCINumber): sword;\nbegin\n  Result := OracleAPI.OCINumberAssign(err, from, _to);\nend;\n\nfunction TZOracle9iPlainDriver.NumberAbs(err: POCIError; const number: POCINumber;\n  _result: POCINumber): sword;\nbegin\n  Result := OracleAPI.OCINumberAbs(err, number, _result);\nend;\n\nfunction TZOracle9iPlainDriver.NumberCeil(err: POCIError; const number: POCINumber;\n  _result: POCINumber): sword;\nbegin\n  Result := OracleAPI.OCINumberCeil(err, number, _result);\nend;\n\nfunction TZOracle9iPlainDriver.NumberFloor(err: POCIError; const number: POCINumber;\n  _result: POCINumber): sword;\nbegin\n  Result := OracleAPI.OCINumberFloor(err, number, _result);\nend;\n\nfunction TZOracle9iPlainDriver.NumberSqrt(err: POCIError; const number: POCINumber;\n  _result: POCINumber): sword;\nbegin\n  Result := OracleAPI.OCINumberSqrt(err, number, _result);\nend;\n\nfunction TZOracle9iPlainDriver.NumberTrunc(err: POCIError; const number: POCINumber;\n  _result: POCINumber): sword;\nbegin\n  Result := OracleAPI.OCINumberTrunc(err, number, _result);\nend;\n\nfunction TZOracle9iPlainDriver.NumberPower(err: POCIError; const base: POCINumber;\n  const number: POCINumber; _result: POCINumber): sword;\nbegin\n  Result := OracleAPI.OCINumberPower(err, base, number, _result);\nend;\n\nfunction TZOracle9iPlainDriver.NumberRound(err: POCIError; const number: POCINumber;\n  decplace: sword; _result: POCINumber): sword;\nbegin\n  Result := OracleAPI.OCINumberRound(err, number, decplace, _result);\nend;\n\nfunction TZOracle9iPlainDriver.NumberPrec(err: POCIError; const number: POCINumber;\n  nDigs: sword; _result: POCINumber): sword;\nbegin\n  Result := OracleAPI.OCINumberPrec(err, number, nDigs, _result);\nend;\n\nfunction TZOracle9iPlainDriver.NumberSin(err: POCIError; const number: POCINumber;\n  _result: POCINumber): sword;\nbegin\n  Result := OracleAPI.OCINumberSin(err, number, _result);\nend;\n\nfunction TZOracle9iPlainDriver.NumberArcSin(err: POCIError; const number: POCINumber;\n  _result: POCINumber): sword;\nbegin\n  Result := OracleAPI.OCINumberArcSin(err, number, _result);\nend;\n\nfunction TZOracle9iPlainDriver.NumberHypSin(err: POCIError; const number: POCINumber;\n  _result: POCINumber): sword;\nbegin\n  Result := OracleAPI.OCINumberHypSin(err, number, _result);\nend;\n\nfunction TZOracle9iPlainDriver.NumberCos(err: POCIError; const number: POCINumber;\n  _result: POCINumber): sword;\nbegin\n  Result := OracleAPI.OCINumberCos(err, number, _result);\nend;\n\nfunction TZOracle9iPlainDriver.NumberArcCos(err: POCIError; const number: POCINumber;\n  _result: POCINumber): sword;\nbegin\n  Result := OracleAPI.OCINumberArcCos(err, number, _result);\nend;\n\nfunction TZOracle9iPlainDriver.NumberHypCos(err: POCIError; const number: POCINumber;\n  _result: POCINumber): sword;\nbegin\n  Result := OracleAPI.OCINumberHypCos(err, number, _result);\nend;\n\nfunction TZOracle9iPlainDriver.NumberTan(err: POCIError; const number: POCINumber;\n  _result: POCINumber): sword;\nbegin\n  Result := OracleAPI.OCINumberTan(err, number, _result);\nend;\n\nfunction TZOracle9iPlainDriver.NumberArcTan(err: POCIError; const number: POCINumber;\n  _result: POCINumber): sword;\nbegin\n  Result := OracleAPI.OCINumberArcTan(err, number, _result);\nend;\n\nfunction TZOracle9iPlainDriver.NumberArcTan2(err: POCIError; const number1: POCINumber;\n  const number2: POCINumber; _result: POCINumber): sword;\nbegin\n  Result := OracleAPI.OCINumberArcTan2(err, number1, number2, _result);\nend;\n\nfunction TZOracle9iPlainDriver.NumberHypTan(err: POCIError; const number: POCINumber;\n  _result: POCINumber): sword;\nbegin\n  Result := OracleAPI.OCINumberHypTan(err, number, _result);\nend;\n\nfunction TZOracle9iPlainDriver.NumberExp(err: POCIError; const number: POCINumber;\n  _result: POCINumber): sword;\nbegin\n  Result := OracleAPI.OCINumberExp(err, number, _result);\nend;\n\nfunction TZOracle9iPlainDriver.NumberLn(err: POCIError; const number: POCINumber;\n  _result: POCINumber): sword;\nbegin\n  Result := OracleAPI.OCINumberLn(err, number, _result);\nend;\n\nfunction TZOracle9iPlainDriver.NumberLog(err: POCIError; const base: POCINumber;\n  const number: POCINumber; _result: POCINumber): sword;\nbegin\n  Result := OracleAPI.OCINumberLog(err, base, number, _result);\nend;\n\nfunction TZOracle9iPlainDriver.TableSize(hndl: POCIEnv; err: POCIError;\n  const tbl: POCITable; size: psb4): sword;\nbegin\n  Result := OracleAPI.OCITableSize(hndl, err, tbl, size);\nend;\n\nfunction TZOracle9iPlainDriver.TableExists(hndl: POCIEnv; err: POCIError;\n  const tbl: POCITable; index: sb4; exists: PBoolean): sword;\nbegin\n  Result := OracleAPI.OCITableExists(hndl, err, tbl, index, exists);\nend;\n\nfunction TZOracle9iPlainDriver.TableDelete(hndl: POCIEnv; err: POCIError;\n  index: sb4; tbl: POCITable): sword;\nbegin\n  Result := OracleAPI.OCITableDelete(hndl, err, index, tbl);\nend;\n\nfunction TZOracle9iPlainDriver.TableFirst(hndl: POCIEnv; err: POCIError;\n  const tbl: POCITable; index: sb4): sword;\nbegin\n  Result := OracleAPI.OCITableFirst(hndl, err, tbl, index);\nend;\n\nfunction TZOracle9iPlainDriver.TableLast(hndl: POCIEnv; err: POCIError;\n  const tbl: POCITable; index: sb4): sword;\nbegin\n  Result := OracleAPI.OCITableLast(hndl, err, tbl, index);\nend;\n\nfunction TZOracle9iPlainDriver.TableNext(hndl: POCIEnv; err: POCIError;\n  index: sb4; const tbl: POCITable; next_index: psb4; exists: PBoolean): sword;\nbegin\n  Result := OracleAPI.OCITableNext(hndl, err, index, tbl, next_index, exists);\nend;\n\nfunction TZOracle9iPlainDriver.TablePrev(hndl: POCIEnv; err: POCIError;\n  index: sb4; const tbl: POCITable; prev_index: psb4; exists: PBoolean): sword;\nbegin\n  Result := OracleAPI.OCITablePrev(hndl, err, index, tbl, prev_index, exists);\nend;\n\nfunction TZOracle9iPlainDriver.ObjectSetAttr(env: POCIEnv; err: POCIError;\n  instance: Pointer; null_struct: pointer; tdo: POCIType;\n  const names: PPAnsiChar; const lengths: pub4; const name_count: ub4;\n  const indexes: pub4; const index_count: ub4; const null_status: POCIInd;\n  const attr_null_struct: Pointer; const attr_value: Pointer): sword;\nbegin\n  Result := OracleAPI.OCIObjectSetAttr(env, err, instance, null_struct, tdo,\n    names, lengths, name_count, indexes, index_count, null_status,\n    attr_null_struct, attr_value);\nend;\n\nfunction TZOracle9iPlainDriver.ObjectGetAttr(env: POCIEnv; err: POCIError;\n  instance: Pointer; null_struct: Pointer; tdo: POCIType;\n  const names: PPoratext; const lengths: pub4; const name_count: ub4;\n  const indexes: pub4; const index_count: ub4; attr_null_status: POCIInd;\n  attr_null_struct, attr_value: PPointer; attr_tdo: PPOCIType): sword;\nbegin\n  Result := OracleAPI.OCIObjectGetAttr(env, err, instance, null_struct, tdo,\n    names, lengths, name_count, indexes, index_count, attr_null_status,\n    attr_null_struct, attr_value, attr_tdo);\nend;\n\nfunction TZOracle9iPlainDriver.Ping(svchp: POCISvcCtx; errhp: POCIError;\n  mode: ub4 = OCI_DEFAULT): sword;\nbegin\n  Result := OracleAPI.OCIPing(svchp, errhp, mode);\nend;\n\nfunction TZOracle9iPlainDriver.ServerAttach(srvhp: POCIServer;\n  errhp: POCIError; dblink: text; dblink_len: sb4; mode: ub4): sword;\nbegin\n  Result := OracleAPI.OCIServerAttach(srvhp, errhp, dblink, dblink_len,\n    mode);\nend;\n\nfunction TZOracle9iPlainDriver.ServerDetach(srvhp: POCIServer;\n  errhp: POCIError; mode: ub4): sword;\nbegin\n  Result := OracleAPI.OCIServerDetach(srvhp, errhp, mode);\nend;\n\nfunction TZOracle9iPlainDriver.ServerVersion(hndlp: POCIHandle;\n  errhp: POCIError; bufp: text; bufsz: ub4; hndltype: ub1): sword;\nbegin\n  Result := OracleAPI.OCIServerVersion(hndlp, errhp, bufp, bufsz,\n    hndltype);\nend;\n\nfunction TZOracle9iPlainDriver.ServerRelease(hndlp: POCIHandle;\n  errhp: POCIError; bufp: text; bufsz: ub4; hndltype: ub1; version:pointer): sword;\nbegin\n  Result:=OCI_ERROR;\n  if assigned(OracleAPI.OCIServerRelease) then\n    Result := OracleAPI.OCIServerRelease(hndlp, errhp, bufp, bufsz,\n      hndltype, version);\nend;\n\nfunction TZOracle9iPlainDriver.SessionBegin(svchp: POCISvcCtx;\n  errhp: POCIError; usrhp: POCISession; credt, mode: ub4): sword;\nbegin\n  Result := OracleAPI.OCISessionBegin(svchp, errhp, usrhp, credt, mode);\nend;\n\nfunction TZOracle9iPlainDriver.SessionEnd(svchp: POCISvcCtx;\n  errhp: POCIError; usrhp: POCISession; mode: ub4): sword;\nbegin\n  Result := OracleAPI.OCISessionEnd(svchp, errhp, usrhp, mode);\nend;\n\nfunction TZOracle9iPlainDriver.StmtExecute(svchp: POCISvcCtx;\n  stmtp: POCIStmt; errhp: POCIError; iters, rowoff: ub4; snap_in,\n  snap_out: POCISnapshot; mode: ub4): sword;\nbegin\n  Result := OracleAPI.OCIStmtExecute(svchp, stmtp, errhp, iters, rowoff,\n    snap_in, snap_out, mode);\nend;\n\nfunction TZOracle9iPlainDriver.StmtFetch(stmtp: POCIStmt; errhp: POCIError;\n  nrows: ub4; orientation: ub2; mode: ub4): sword;\nbegin\n  Result := OracleAPI.OCIStmtFetch(stmtp, errhp, nrows, orientation, mode);\nend;\n\nfunction TZOracle9iPlainDriver.StmtGetPieceInfo(stmtp: POCIStmt;\n  errhp: POCIError; var hndlpp: Pointer; var typep: ub4; var in_outp: ub1;\n  var iterp, idxp: ub4; var piecep: ub1): sword;\nbegin\n  Result := OracleAPI.OCIStmtGetPieceInfo(stmtp, errhp, hndlpp, typep,\n    in_outp, iterp, idxp, piecep);\nend;\n\nfunction TZOracle9iPlainDriver.StmtPrepare(stmtp: POCIStmt;\n  errhp: POCIError; stmt: text; stmt_len, language, mode: ub4): sword;\nbegin\n  Result := OracleAPI.OCIStmtPrepare(stmtp, errhp, stmt, stmt_len,\n    language, mode);\nend;\n\nfunction TZOracle9iPlainDriver.StmtSetPieceInfo(handle: Pointer;\n  typep: ub4; errhp: POCIError; buf: Pointer; var alenp: ub4; piece: ub1;\n  indp: Pointer; var rcodep: ub2): sword;\nbegin\n  Result := OracleAPI.OCIStmtSetPieceInfo(handle, typep,\n    errhp, buf, alenp, piece, indp, rcodep);\nend;\n\nfunction TZOracle9iPlainDriver.TransCommit(svchp: POCISvcCtx;\n  errhp: POCIError; flags: ub4): sword;\nbegin\n  Result := OracleAPI.OCITransCommit(svchp, errhp, flags);\nend;\n\nfunction TZOracle9iPlainDriver.TransDetach(svchp: POCISvcCtx;\n  errhp: POCIError; flags: ub4): sword;\nbegin\n  Result := OracleAPI.OCITransDetach(svchp, errhp, flags);\nend;\n\nfunction TZOracle9iPlainDriver.TransForget(svchp: POCISvcCtx;\n  errhp: POCIError; flags: ub4): sword;\nbegin\n  Result := OracleAPI.OCITransForget(svchp, errhp, flags);\nend;\n\nfunction TZOracle9iPlainDriver.TransPrepare(svchp: POCISvcCtx;\n  errhp: POCIError; flags: ub4): sword;\nbegin\n  Result := OracleAPI.OCITransPrepare(svchp, errhp, flags);\nend;\n\nfunction TZOracle9iPlainDriver.TransRollback(svchp: POCISvcCtx;\n  errhp: POCIError; flags: ub4): sword;\nbegin\n  Result := OracleAPI.OCITransRollback(svchp, errhp, flags);\nend;\n\nfunction TZOracle9iPlainDriver.TransStart(svchp: POCISvcCtx;\n  errhp: POCIError; timeout: word; flags: ub4): sword;\nbegin\n  Result := OracleAPI.OCITransStart(svchp, errhp, timeout, flags);\nend;\n\nfunction TZOracle9iPlainDriver.DateTimeAssign(hndl: POCIEnv;\n  err: POCIError; const from: POCIDateTime; _to: POCIDateTime): sword;\nbegin\n  Result := OracleAPI.OCIDateTimeAssign(hndl, err, from, _to);\nend;\n\nfunction TZOracle9iPlainDriver.DateTimeCheck(hndl: POCIEnv; err: POCIError;\n  const date: POCIDateTime; var valid: ub4): sword;\nbegin\n  Result := OracleAPI.OCIDateTimeCheck(hndl, err, date, valid);\nend;\n\nfunction TZOracle9iPlainDriver.DateTimeCompare(hndl: POCIEnv;\n  err: POCIError; const date1, date2: POCIDateTime;\n  var _result: sword): sword;\nbegin\n  Result := OracleAPI.OCIDateTimeCompare(hndl, err, date1, date2, _result);\nend;\n\nfunction TZOracle9iPlainDriver.DateTimeConstruct(hndl: POCIEnv;\n  err: POCIError; datetime: POCIDateTime; year: sb2; month, day, hour, min,\n  sec: ub1; fsec: ub4; timezone: text; timezone_length: size_t): sword;\nbegin\n  Result := OracleAPI.OCIDateTimeConstruct(hndl, err, datetime,\n    year, month, day, hour, min, sec, fsec, timezone, timezone_length);\nend;\n\nfunction TZOracle9iPlainDriver.DateTimeConvert(hndl: POCIEnv;\n  err: POCIError; indate, outdate: POCIDateTime): sword;\nbegin\n  Result := OracleAPI.OCIDateTimeConvert(hndl, err, indate, outdate);\nend;\n\nfunction TZOracle9iPlainDriver.DateTimeFromText(hndl: POCIEnv;\n  err: POCIError; const date_str: text; d_str_length: size_t;\n  const fmt: text; fmt_length: ub1; const lang_name: text;\n  lang_length: size_t; date: POCIDateTime): sword;\nbegin\n  Result := OracleAPI.OCIDateTimeFromText(hndl, err,\n    date_str, d_str_length, fmt, fmt_length, lang_name, lang_length, date);\nend;\n\nfunction TZOracle9iPlainDriver.DateTimeGetDate(hndl: POCIEnv;\n  err: POCIError; const date: POCIDateTime; var year: sb2; var month,\n  day: ub1): sword;\nbegin\n  Result := OracleAPI.OCIDateTimeGetDate(hndl, err, date, year, month, day);\nend;\n\nfunction TZOracle9iPlainDriver.DateTimeGetTime(hndl: POCIEnv;\n  err: POCIError; datetime: POCIDateTime; var hour, minute, sec: ub1;\n  var fsec: ub4): sword;\nbegin\n  Result := OracleAPI.OCIDateTimeGetTime(hndl, err, datetime,\n    hour, minute, sec, fsec);\nend;\n\nfunction TZOracle9iPlainDriver.DateTimeGetTimeZoneName(hndl: POCIEnv;\n  err: POCIError; datetime: POCIDateTime; var buf: ub1;\n  var buflen: ub4): sword;\nbegin\n  Result := OracleAPI.OCIDateTimeGetTimeZoneName(hndl, err, datetime,\n    buf, buflen);\nend;\n\nfunction TZOracle9iPlainDriver.DateTimeGetTimeZoneOffset(hndl: POCIEnv;\n  err: POCIError; const datetime: POCIDateTime; var hour,\n  minute: sb1): sword;\nbegin\n  Result := OracleAPI.OCIDateTimeGetTimeZoneOffset(hndl, err, datetime,\n    hour, minute);\nend;\n\nfunction TZOracle9iPlainDriver.DateTimeSysTimeStamp(hndl: POCIEnv;\n  err: POCIError; sys_date: POCIDateTime): sword;\nbegin\n  Result := OracleAPI.OCIDateTimeSysTimeStamp(hndl, err, sys_date);\nend;\n\nfunction TZOracle9iPlainDriver.DateTimeToText(hndl: POCIEnv;\n  err: POCIError; const date: POCIDateTime; const fmt: text; fmt_length,\n  fsprec: ub1; const lang_name: text; lang_length: size_t;\n  var buf_size: ub4; buf: text): sword;\nbegin\n  Result := OracleAPI.OCIDateTimeToText(hndl, err, date, fmt, fmt_length,\n    fsprec, lang_name, lang_length, buf_size, buf);\nend;\n\n{ort.h}\nfunction TZOracle9iPlainDriver.TypeIterNew(env: POCIEnv; err: POCIError;\n  const tdo: POCIType; iterator_ort: PPOCITypeIter): sword;\nbegin\n  Result := OracleAPI.OCITypeIterNew(env, err, tdo, iterator_ort);\nend;\n\nfunction TZOracle9iPlainDriver.TypeIterSet(env: POCIEnv; err: POCIError;\n  const tdo: POCIType; iterator_ort: POCITypeIter): sword;\nbegin\n  Result := OracleAPI.OCITypeIterSet(env, err, tdo, iterator_ort);\nend;\n\nfunction TZOracle9iPlainDriver.TypeIterFree(env: POCIEnv; err: POCIError;\n  iterator_ort: POCITypeIter): sword;\nbegin\n  Result := OracleAPI.OCITypeIterFree(env, err, iterator_ort);\nend;\n\nfunction TZOracle9iPlainDriver.TypeByName(env: POCIEnv; err: POCIError;\n  const svc: POCISvcCtx; schema_name: Poratext; const s_length: ub4;\n  const type_name: Poratext; const t_length: ub4; version_name: Poratext;\n  const v_length: ub4; const pin_duration: OCIDuration;\n  const get_option: OCITypeGetOpt; tdo: PPOCIType): sword;\nbegin\n  Result := OracleAPI.OCITypeByName(env, err, svc, schema_name, s_length,\n    type_name, t_length, version_name, v_length, pin_duration, get_option, tdo);\nend;\n\nfunction TZOracle9iPlainDriver.TypeArrayByName(env: POCIEnv; err: POCIError;\n  svc: POCISvcCtx; array_len: ub4; schema_name:  PPoratext; s_length: Pub4;\n  type_name: PPoratext; t_length: Pub4; version_name: PPoratext;\n  v_length: Pub4; pin_duration: OCIDuration; get_option: OCITypeGetOpt;\n  tdo: PPOCIType): sword;\nbegin\n  Result := OracleAPI.OCITypeArrayByName(env, err, svc, array_len, schema_name,\n    s_length, type_name, t_length, version_name, v_length, pin_duration,\n    get_option, tdo);\nend;\n\nfunction TZOracle9iPlainDriver.TypeByRef(env: POCIEnv; err: POCIError;\n  type_ref: POCIRef; pin_duration: OCIDuration; get_option: OCITypeGetOpt;\n  tdo: PPOCIType): sword;\nbegin\n  Result := OracleAPI.OCITypeByRef(env, err, type_ref, pin_duration, get_option,\n    tdo);\nend;\n\nfunction TZOracle9iPlainDriver.TypeArrayByRef(env: POCIEnv; err: POCIError;\n  array_len: ub4; type_ref: PPOCIRef; pin_duration: OCIDuration;\n  get_option: OCITypeGetOpt; tdo: PPOCIType): sword;\nbegin\n  Result := OracleAPI.OCITypeArrayByRef(env, err, array_len, type_ref,\n    pin_duration, get_option, tdo);\nend;\n\nfunction TZOracle9iPlainDriver.TypeName(env: POCIEnv; err: POCIError;\n  tdo: POCIType; n_length: Pub4): poratext;\nbegin\n  Result := OracleAPI.OCITypeName(env, err, tdo, n_length);\nend;\n\nfunction TZOracle9iPlainDriver.TypeSchema(env: POCIEnv; err: POCIError;\n  const tdo: POCIType; n_length: Pub4): poratext;\nbegin\n  Result := OracleAPI.OCITypeSchema(env, err, tdo, n_length);\nend;\n\nfunction TZOracle9iPlainDriver.TypeTypeCode(env: POCIEnv; err: POCIError;\n  const tdo: POCIType): OCITypeCode;\nbegin\n  Result := OracleAPI.OCITypeTypeCode(env, err, tdo);\nend;\n\nfunction TZOracle9iPlainDriver.TypeCollTypeCode(env: POCIEnv; err:POCIError;\n  const tdo: POCIType): OCITypeCode;\nbegin\n  Result := OracleAPI.OCITypeCollTypeCode(env, err, tdo);\nend;\n\nfunction TZOracle9iPlainDriver.TypeVersion(env: POCIEnv; err: POCIError;\n  const tdo: POCIType; v_length: Pub4): poratext;\nbegin\n  Result := OracleAPI.OCITypeVersion(env, err, tdo, v_length);\nend;\n\nfunction TZOracle9iPlainDriver.TypeAttrs(env: POCIEnv; err: POCIError;\n  const tdo:POCIType): ub4;\nbegin\n  Result := OracleAPI.OCITypeAttrs(env, err, tdo);\nend;\n\nfunction TZOracle9iPlainDriver.TypeMethods(env: POCIEnv; err: POCIError;\n  const tdo: POCIType): ub4;\nbegin\n  Result := OracleAPI.OCITypeMethods(env, err, tdo);\nend;\n\nfunction TZOracle9iPlainDriver.TypeElemName(env: POCIEnv; err: POCIError;\n  const elem: POCITypeElem; n_length:Pub4): poratext;\nbegin\n  Result := OracleAPI.OCITypeElemName(env, err, elem, n_length);\nend;\n\nfunction TZOracle9iPlainDriver.TypeElemTypeCode(env: POCIEnv; err: POCIError;\n  const elem: POCITypeElem): OCITypeCode;\nbegin\n  Result := OracleAPI.OCITypeElemTypeCode(env, err, elem);\nend;\n\nfunction TZOracle9iPlainDriver.TypeElemType(env: POCIEnv; err: POCIError;\n  const elem: POCITypeElem; elem_tdo:PPOCIType): sword;\nbegin\n  Result := OracleAPI.OCITypeElemType(env, err, elem, elem_tdo);\nend;\n\nfunction TZOracle9iPlainDriver.TypeElemFlags(env: POCIEnv; err: POCIError;\n  const elem: POCITypeElem): ub4;\nbegin\n  Result := OracleAPI.OCITypeElemFlags(env, err, elem);\nend;\n\nfunction TZOracle9iPlainDriver.TypeElemNumPrec(env: POCIEnv; err: POCIError;\n  const elem: POCITypeElem): ub1;\nbegin\n  Result := OracleAPI.OCITypeElemNumPrec(env, err, elem);\nend;\n\nfunction TZOracle9iPlainDriver.TypeElemNumScale(env: POCIEnv; err: POCIError;\n  const elem: POCITypeElem): sb1;\nbegin\n  Result := OracleAPI.OCITypeElemNumScale(env, err, elem);\nend;\n\nfunction TZOracle9iPlainDriver.TypeElemLength(env: POCIEnv; err: POCIError;\n  const elem:POCITypeElem): ub4;\nbegin\n  Result := OracleAPI.OCITypeElemLength(env, err, elem);\nend;\n\nfunction TZOracle9iPlainDriver.TypeElemCharSetID(env: POCIEnv; err: POCIError;\n  const elem: POCITypeElem): ub2;\nbegin\n  Result := OracleAPI.OCITypeElemCharSetID(env, err, elem);\nend;\n\nfunction TZOracle9iPlainDriver.TypeElemCharSetForm(env: POCIEnv; err: POCIError;\n  const elem: POCITypeElem): ub2;\nbegin\n  Result := OracleAPI.OCITypeElemCharSetForm(env, err, elem);\nend;\n\nfunction TZOracle9iPlainDriver.TypeElemParameterizedType(env: POCIEnv;\n  err: POCIError; const elem: POCITypeElem; type_stored: PPOCIType): sword;\nbegin\n  Result := OracleAPI.OCITypeElemParameterizedType(env, err, elem, type_stored);\nend;\n\nfunction TZOracle9iPlainDriver.TypeElemExtTypeCode(env: POCIEnv; err: POCIError;\n  const elem: POCITypeElem): OCITypeCode;\nbegin\n  Result := OracleAPI.OCITypeElemExtTypeCode(env, err, elem);\nend;\n\nfunction TZOracle9iPlainDriver.TypeAttrByName(env: POCIEnv; err: POCIError;\n  const tdo: POCIType; const name: Poratext; const n_length: ub4;\n  elem: PPOCITypeElem): sword;\nbegin\n  Result := OracleAPI.OCITypeAttrByName(env, err, tdo, name, n_length, elem);\nend;\n\nfunction TZOracle9iPlainDriver.TypeAttrNext(env: POCIEnv; err: POCIError;\n  iterator_ort: POCITypeIter; elem: PPOCITypeElem): sword;\nbegin\n  Result := OracleAPI.OCITypeAttrNext(env, err, iterator_ort, elem);\nend;\n\nfunction TZOracle9iPlainDriver.TypeCollElem(env: POCIEnv; err: POCIError;\n  const tdo:POCIType; element: PPOCITypeElem): sword;\nbegin\n  Result := OracleAPI.OCITypeCollElem(env, err, tdo, element);\nend;\n\nfunction TZOracle9iPlainDriver.TypeCollSize(env: POCIEnv; err: POCIError;\n  const tdo: POCIType; num_elems: Pub4): sword;\nbegin\n  Result := OracleAPI.OCITypeCollSize(env, err, tdo, num_elems);\nend;\n\nfunction TZOracle9iPlainDriver.TypeCollExtTypeCode(env: POCIEnv; err: POCIError;\n  const tdo:POCIType; sqt_code: POCITypeCode): sword;\nbegin\n  Result := OracleAPI.OCITypeCollExtTypeCode(env, err, tdo, sqt_code);\nend;\n\nfunction TZOracle9iPlainDriver.TypeMethodOverload(env: POCIEnv; err: POCIError;\n  const tdo: POCIType; const method_name: Poratext;\n  const m_length: ub4): ub4;\nbegin\n  Result := OracleAPI.OCITypeMethodOverload(env, err, tdo, method_name,\n    m_length);\nend;\n\nfunction TZOracle9iPlainDriver.TypeMethodByName(env: POCIEnv; err: POCIError;\n  const tdo: POCIType; const method_name: Poratext; const m_length: ub4;\n  mdos: PPOCITypeMethod): sword;\nbegin\n  Result := OracleAPI.OCITypeMethodByName(env, err, tdo, method_name, m_length,\n    mdos);\nend;\n\nfunction TZOracle9iPlainDriver.TypeMethodNext(env: POCIEnv; err: POCIError;\n  iterator_ort: POCITypeIter; mdo: PPOCITypeMethod): sword;\nbegin\n  Result := OracleAPI.OCITypeMethodNext(env, err, iterator_ort, mdo);\nend;\n\nfunction TZOracle9iPlainDriver.TypeMethodName(env:POCIEnv; err: POCIError;\n  const mdo: POCITypeMethod; n_length: Pub4): poratext;\nbegin\n  Result := OracleAPI.OCITypeMethodName(env, err, mdo, n_length);\nend;\n\nfunction TZOracle9iPlainDriver.TypeMethodEncap(env: POCIEnv; err: POCIError;\n  const mdo: POCITypeMethod): OCITypeEncap;\nbegin\n  Result := OracleAPI.OCITypeMethodEncap(env, err, mdo);\nend;\n\nfunction TZOracle9iPlainDriver.TypeMethodFlags(env: POCIEnv; err: POCIError;\n    const mdo:POCITypeMethod): OCITypeMethodFlag;\nbegin\n  Result := OracleAPI.OCITypeMethodFlags(env, err, mdo);\nend;\n\nfunction TZOracle9iPlainDriver.TypeMethodMap(env: POCIEnv; err: POCIError;\n  const tdo: POCIType; mdo: PPOCITypeMethod): sword;\nbegin\n  Result := OracleAPI.OCITypeMethodMap(env, err, tdo, mdo);\nend;\n\nfunction TZOracle9iPlainDriver.TypeMethodOrder(env: POCIEnv; err: POCIError;\n  const tdo: POCIType; mdo: PPOCITypeMethod): sword;\nbegin\n  Result := OracleAPI.OCITypeMethodOrder(env, err, tdo, mdo);\nend;\n\nfunction TZOracle9iPlainDriver.TypeMethodParams(env: POCIEnv; err: POCIError;\n  const mdo: POCITypeMethod): ub4;\nbegin\n  Result := OracleAPI.OCITypeMethodParams(env, err, mdo);\nend;\n\nfunction TZOracle9iPlainDriver.TypeResult(env: POCIEnv; err: POCIError;\n  const mdo: POCITypeMethod; elem: PPOCITypeElem): sword;\nbegin\n  Result := OracleAPI.OCITypeResult(env, err, mdo, elem);\nend;\n\nfunction TZOracle9iPlainDriver.TypeParamByPos(env: POCIEnv; err: POCIError;\n  const mdo: POCITypeMethod; const position: ub4;\n  elem: PPOCITypeElem): sword;\nbegin\n  Result := OracleAPI.OCITypeParamByPos(env, err, mdo, position, elem);\nend;\n\nfunction TZOracle9iPlainDriver.TypeParamByName(env: POCIEnv; err: POCIError;\n  const mdo: POCITypeMethod; const name: Poratext; const n_length: ub4;\n  elem:PPOCITypeElem): sword;\nbegin\n  Result := OracleAPI.OCITypeParamByName(env, err, mdo, name, n_length, elem);\nend;\n\nfunction TZOracle9iPlainDriver.TypeParamPos(env: POCIEnv; err: POCIError;\n  const mdo: POCITypeMethod; const name: Poratext; const n_length: ub4;\n  position: Pub4; elem: PPOCITypeElem): sword;\nbegin\n  Result := OracleAPI.OCITypeParamPos(env, err, mdo, name, n_length, position,\n    elem);\nend;\n\nfunction TZOracle9iPlainDriver.TypeElemParamMode(env: POCIEnv; err: POCIError;\n  const elem: POCITypeElem): OCITypeParamMode;\nbegin\n  Result := OracleAPI.OCITypeElemParamMode(env, err, elem);\nend;\n\nfunction TZOracle9iPlainDriver.TypeElemDefaultValue(env: POCIEnv;\n  err: POCIError; const elem: POCITypeElem; d_v_length: Pub4): poratext;\nbegin\n  Result := OracleAPI.OCITypeElemDefaultValue(env, err, elem, d_v_length);\nend;\n\nfunction TZOracle9iPlainDriver.TypeVTInit(env: POCIEnv; err: POCIError): sword;\nbegin\n  Result := OracleAPI.OCITypeVTInit(env, err);\nend;\n\nfunction TZOracle9iPlainDriver.TypeVTInsert(env: POCIEnv; err: POCIError;\n  const schema_name: Poratext; const s_n_length: ub4;\n  const type_name: Poratext; const t_n_length: ub4;\n  const user_version:Poratext; const u_v_length:ub4): sword;\nbegin\n  Result := OracleAPI.OCITypeVTInsert(env, err, schema_name, s_n_length,\n    type_name, t_n_length, user_version, u_v_length);\nend;\n\nfunction TZOracle9iPlainDriver.TypeVTSelect(env: POCIEnv; err: POCIError;\n  const schema_name: Poratext; const s_n_length: ub4;\n  const type_name: Poratext; const t_n_length: ub4; user_version: PPoratext;\n  u_v_length: Pub4; version: Pub2): sword;\nbegin\n  Result := OracleAPI.OCITypeVTSelect(env, err, schema_name, s_n_length,\n    type_name, t_n_length, user_version, u_v_length, version);\nend;\n\nend.\n\n"
  },
  {
    "path": "lib/zeosdbo/src/plain/ZPlainPostgreSqlDriver.pas",
    "content": "{*********************************************************}\n{                                                         }\n{                 Zeos Database Objects                   }\n{           Native Plain Drivers for PostgreSQL           }\n{                                                         }\n{        Originally written by Sergey Seroukhov           }\n{                                                         }\n{*********************************************************}\n\n{@********************************************************}\n{    Copyright (c) 1999-2012 Zeos Development Group       }\n{                                                         }\n{ License Agreement:                                      }\n{                                                         }\n{ This library is distributed in the hope that it will be }\n{ useful, but WITHOUT ANY WARRANTY; without even the      }\n{ implied warranty of MERCHANTABILITY or FITNESS FOR      }\n{ A PARTICULAR PURPOSE.  See the GNU Lesser General       }\n{ Public License for more details.                        }\n{                                                         }\n{ The source code of the ZEOS Libraries and packages are  }\n{ distributed under the Library GNU General Public        }\n{ License (see the file COPYING / COPYING.ZEOS)           }\n{ with the following  modification:                       }\n{ As a special exception, the copyright holders of this   }\n{ library give you permission to link this library with   }\n{ independent modules to produce an executable,           }\n{ regardless of the license terms of these independent    }\n{ modules, and to copy and distribute the resulting       }\n{ executable under terms of your choice, provided that    }\n{ you also meet, for each linked independent module,      }\n{ the terms and conditions of the license of that module. }\n{ An independent module is a module which is not derived  }\n{ from or based on this library. If you modify this       }\n{ library, you may extend this exception to your version  }\n{ of the library, but you are not obligated to do so.     }\n{ If you do not wish to do so, delete this exception      }\n{ statement from your version.                            }\n{                                                         }\n{                                                         }\n{ The project web site is located on:                     }\n{   http://zeos.firmos.at  (FORUM)                        }\n{   http://sourceforge.net/p/zeoslib/tickets/ (BUGTRACKER)}\n{   svn://svn.code.sf.net/p/zeoslib/code-0/trunk (SVN)    }\n{                                                         }\n{   http://www.sourceforge.net/projects/zeoslib.          }\n{                                                         }\n{                                                         }\n{                                 Zeos Development Group. }\n{********************************************************@}\n\nunit ZPlainPostgreSqlDriver;\n\ninterface\n\n{$I ZPlain.inc}\n\nuses ZClasses, ZCompatibility, ZPlainDriver;\n\nconst\n  WINDOWS_DLL_LOCATION   = 'libpq.dll';\n  WINDOWS_DLL7_LOCATION   = 'libpq74.dll';\n  WINDOWS_DLL8_LOCATION   = 'libpq81.dll';\n  LINUX_DLL_LOCATION   = 'libpq'+SharedSuffix;\n  LINUX_DLL8_LOCATION  = 'libpq'+SharedSuffix+'.4';\n  LINUX_DLL82_LOCATION = 'libpq'+SharedSuffix+'.5';\n\n{ Type Lengths }\n  NAMEDATALEN  = 32;\n\n{ OIDNAMELEN should be set to NAMEDATALEN + sizeof(Oid) }\n  OIDNAMELEN   = 36;\n  InvalidOid   = 0;\n\n  INV_WRITE    = $00020000;\n  INV_READ     = $00040000;\n\n  BLOB_SEEK_SET     = 0;\n  BLOB_SEEK_CUR     = 1;\n  BLOB_SEEK_END     = 2;\n\ntype\n\n{ Application-visible enum types }\n  TZPostgreSQLConnectStatusType = (\n    CONNECTION_OK,\n    CONNECTION_BAD\n  );\n\n  TZPostgreSQLFieldCode=( // FirmOS\n            PG_DIAG_SEVERITY=ord('S'),\n            PG_DIAG_SQLSTATE=ord('C'),\n            PG_DIAG_MESSAGE_PRIMARY=ord('M'),\n            PG_DIAG_MESSAGE_DETAIL=ord('D'),\n            PG_DIAG_MESSAGE_HINT=ord('H'),\n            PG_DIAG_STATEMENT_POSITION=ord('P'),\n            PG_DIAG_INTERNAL_POSITION=ord('p'),\n            PG_DIAG_INTERNAL_QUERY=ord('q'),\n            PG_DIAG_CONTEXT=ord('W'),\n            PG_DIAG_SOURCE_FILE=ord('F'),\n            PG_DIAG_SOURCE_LINE=ord('L'),\n            PG_DIAG_SOURCE_FUNCTION=ord('R')\n            );\n\n  TZPostgreSQLExecStatusType = (\n    PGRES_EMPTY_QUERY,\n    PGRES_COMMAND_OK,\t\t{ a query command that doesn't return anything\n\t\t\t\t  was executed properly by the backend }\n    PGRES_TUPLES_OK,\t\t{ a query command that returns tuples\n\t\t\t\t  was executed properly by the backend,\n\t\t\t\t  PGresult contains the result tuples }\n    PGRES_COPY_OUT,\t\t{ Copy Out data transfer in progress }\n    PGRES_COPY_IN,\t\t{ Copy In data transfer in progress }\n    PGRES_BAD_RESPONSE,\t\t{ an unexpected response was recv'd from\n\t\t\t\t  the backend }\n    PGRES_NONFATAL_ERROR,\n    PGRES_FATAL_ERROR\n  );\n\n{ PGnotify represents the occurrence of a NOTIFY message.\n  Ideally this would be an opaque typedef, but it's so simple that it's\n  unlikely to change.\n  NOTE: in Postgres 6.4 and later, the be_pid is the notifying backend's,\n  whereas in earlier versions it was always your own backend's PID.\n}\n  TZPostgreSQLNotify = packed record\n    relname: PAnsiChar;   { name of relation containing data }\n    be_pid:  Integer; { process id of backend }\n    payload: PAnsiChar; {additional data in notify}\n  end;\n\n  PZPostgreSQLNotify = ^TZPostgreSQLNotify;\n\n{ PQnoticeProcessor is the function type for the notice-message callback. }\n\n  TZPostgreSQLNoticeProcessor = procedure(arg: Pointer; message: PAnsiChar); cdecl;\n\n{ Structure for the conninfo parameter definitions returned by PQconndefaults }\n\n  TZPostgreSQLConnectInfoOption = packed record\n    keyword:  PAnsiChar;\t{ The keyword of the option }\n    envvar:   PAnsiChar;\t{ Fallback environment variable name }\n    compiled: PAnsiChar;\t{ Fallback compiled in default value  }\n    val:      PAnsiChar;\t{ Options value\t}\n    lab:      PAnsiChar;\t{ Label for field in connect dialog }\n    disPAnsiChar: PAnsiChar;\t{ Character to display for this field\n\t\t\t  in a connect dialog. Values are:\n\t\t\t  \"\"\tDisplay entered value as is\n\t\t\t  \"*\"\tPassword field - hide value\n\t\t\t  \"D\"\tDebug options - don't\n\t\t\t  create a field by default }\n    dispsize: Integer;\t{ Field size in characters for dialog }\n  end;\n\n  PZPostgreSQLConnectInfoOption = ^TZPostgreSQLConnectInfoOption;\n\n{ PQArgBlock -- structure for PQfn() arguments }\n\n  TZPostgreSQLArgBlock = packed record\n    len:     Integer;\n    isint:   Integer;\n    case u: Boolean of\n      True:  (ptr: PInteger);\t{ can't use void (dec compiler barfs)\t }\n      False: (_int: Integer);\n  end;\n\n  PZPostgreSQLArgBlock = ^TZPostgreSQLArgBlock;\n\n  PZPostgreSQLConnect = Pointer;\n  PZPostgreSQLResult = Pointer;\n  PZPostgreSQLCancel = Pointer;\n  POid = ^Oid;\n  Oid = Integer;\n\nTZPgCharactersetType = (\n\tcsSQL_ASCII = 0,\t{ SQL/ASCII }\n\tcsEUC_JP,\t{ EUC for Japanese }\n\tcsEUC_CN,\t{ EUC for Chinese }\n\tcsEUC_KR,\t{ EUC for Korean }\n\tcsEUC_TW,\t{ EUC for Taiwan }\n  csEUC_JIS_2004, {Extended UNIX Code-JP, JIS X 0213 \tJapanese}\n\tcsUTF8,\t\t{ Unicode UTF-8 }\n\tcsMULE_INTERNAL,\t{ Mule internal code }\n\tcsLATIN1,\t{ ISO-8859 Latin 1 }\n\tcsLATIN2,\t{ ISO-8859 Latin 2 }\n\tcsLATIN3,\t{ ISO-8859 Latin 3 }\n\tcsLATIN4,\t{ ISO-8859 Latin 4 }\n\tcsLATIN5,\t{ ISO-8859 Latin 5 }\n\tcsLATIN6,\t{ ISO-8859 Latin 6 }\n\tcsLATIN7,\t{ ISO-8859 Latin 7 }\n\tcsLATIN8,\t{ ISO-8859 Latin 8 }\n\tcsLATIN9,\t{ ISO-8859 Latin 9 }\n\tcsLATIN10,\t{ ISO-8859 Latin 10 }\n\tcsWIN1256,\t{ Arabic Windows }\n\tcsWIN1258,\t{ Vietnamese Windows }\n\tcsWIN866,\t{ Alternativny Variant (MS-DOS CP866) }\n\tcsWIN874,\t{ Thai Windows }\n  csKOI8, {KOI8-R(U) \tCyrillic}\n\tcsKOI8R,\t{ KOI8-R \tCyrillic (Russian) }\n\tcsWIN1251,\t{ windows-1251 }\n  csWIN1252, {Windows CP1252 \tWestern European}\n\tcsISO_8859_5,\t{ ISO-8859-5 }\n\tcsISO_8859_6,\t{ ISO-8859-6 }\n\tcsISO_8859_7,\t{ ISO-8859-7 }\n\tcsISO_8859_8,\t{ ISO-8859-8 }\n  csWIN1250, { Windows CP1250 \tCentral European }\n  csWIN1253, { Windows CP1253 \tGreek }\n  csWIN1254, { Windows CP1254 \tTurkish }\n  csWIN1255, { Windows CP1255 \tHebrew }\n  csWIN1257, { Windows CP1257 \tBaltic }\n\tcsKOI8U,\t{ KOI8-R \tCyrillic (Ukrainian) }\n\tcsSJIS,\t\t{ Shift JIS \tJapanese }\n\tcsBIG5,\t\t{ Big Five \tTraditional Chinese }\n\tcsGBK,\t\t{ Extended National Standard \tSimplified Chinese }\n\tcsUHC,\t\t{ Unified Hangul Code \tKorean }\n\tcsGB18030,\t{ National Standard \tChinese }\n\tcsJOHAB,  {JOHAB \tKorean (Hangul)}\n  csSHIFT_JIS_2004, {Shift JIS, JIS X 0213 \tJapanese}\n\tcsUNICODE_PODBC,{ UNICODE ( < Ver8.1). Can't call it UNICODE as that's already used }\n\tcsTCVN,\t\t{ TCVN ( < Ver8.1) }\n\tcsALT,\t\t{ ALT ( < Var8.1) }\n\tcsWIN,\t\t{ WIN ( < Ver8.1) }\n\tcsOTHER\n);\n\n{ ****************** Plain API Types definition ***************** }\n\ntype\n{ String descriptions of the ExecStatusTypes }\n  pgresStatus = array[$00..$ff] of PAnsiChar;\n\n{ PGconn encapsulates a connection to the backend.\n  The contents of this struct are not supposed to be known to applications.\n}\n  PGconn = Pointer;\n  PPGconn = Pointer;\n\n{ PGresult encapsulates the result of a query (or more precisely, of a single\n  SQL command --- a query string given to PQsendQuery can contain multiple\n  commands and thus return multiple PGresult objects).\n  The contents of this struct are not supposed to be known to applications.\n}\n  PGresult = Pointer;\n  PPGresult = Pointer;\n  PGCancel = Pointer;\n\n{ PGnotify represents the occurrence of a NOTIFY message.\n  Ideally this would be an opaque typedef, but it's so simple that it's\n  unlikely to change.\n  NOTE: in Postgres 6.4 and later, the be_pid is the notifying backend's,\n  whereas in earlier versions it was always your own backend's PID.\n}\n  PGnotify = packed record\n    relname: array [0..NAMEDATALEN-1] of AnsiChar; { name of relation containing data }\n    be_pid:  Integer;\t\t\t      { process id of backend }\n  end;\n\n  PPGnotify = ^PGnotify;\n\n{ PQnoticeProcessor is the function type for the notice-message callback. }\n\n  PQnoticeProcessor = procedure(arg: Pointer; message: PAnsiChar); cdecl;\n\n{ Print options for PQprint() }\n\n{\n  We can't use the conventional \"bool\", because we are designed to be\n  included in a user's program, and user may already have that type\n  defined.  Pqbool, on the other hand, is unlikely to be used.\n}\n\n  PPAnsiChar = array[00..$ff] of PAnsiChar;\n\n  PQprintOpt = packed record\n    header:    Byte;\t   { print output field headings and row count }\n    align:     Byte;\t   { fill align the fields }\n    standard:  Byte;\t   { old brain dead format }\n    html3:     Byte;\t   { output html tables }\n    expanded:  Byte;\t   { expand tables }\n    pager:     Byte;\t   { use pager for output if needed }\n    fieldSep:  PAnsiChar;\t   { field separator }\n    tableOpt:  PAnsiChar;      { insert to HTML <table ...> }\n    caption:   PAnsiChar;\t   { HTML <caption> }\n    fieldName: PPAnsiChar; \t   { null terminated array of repalcement field names }\n  end;\n\n  PPQprintOpt = ^PQprintOpt;\n\n{ ----------------\n  Structure for the conninfo parameter definitions returned by PQconndefaults\n  ----------------\n}\n  PQconninfoOption = packed record\n    keyword:  PAnsiChar;\t{ The keyword of the option }\n    envvar:   PAnsiChar;\t{ Fallback environment variable name }\n    compiled: PAnsiChar;\t{ Fallback compiled in default value  }\n    val:      PAnsiChar;\t{ Options value\t}\n    lab:      PAnsiChar;\t{ Label for field in connect dialog }\n    disPAnsiChar: PAnsiChar;\t{ Character to display for this field\n\t\t\t  in a connect dialog. Values are:\n\t\t\t  \"\"\tDisplay entered value as is\n\t\t\t  \"*\"\tPassword field - hide value\n\t\t\t  \"D\"\tDebug options - don't\n\t\t\t  create a field by default }\n    dispsize: Integer;\t{ Field size in characters for dialog }\n  end;\n\n  PPQConninfoOption = ^PQconninfoOption;\n\n{ ----------------\n  PQArgBlock -- structure for PQfn() arguments\n  ----------------\n}\n  PQArgBlock = packed record\n    len:     Integer;\n    isint:   Integer;\n    case u: Boolean of\n      True:  (ptr: PInteger);\t{ can't use void (dec compiler barfs)\t }\n      False: (_int: Integer);\n  end;\n\n  PPQArgBlock = ^PQArgBlock;\n\n{Prepared statement types}\n  TPQparamTypes = {array of }POid;\n  TPQparamValues = array of PAnsichar;\n  TPQparamLengths = array of Integer;\n  TPQparamFormats = array of Integer;\n\n\n{ ************** Plain API Function types definition ************* }\n{ ===\tin fe-connect.c === }\n  TPQconnectdb     = function(ConnInfo: PAnsiChar): PPGconn; cdecl; // FirmOS 8.1 OK\n  TPQsetdbLogin    = function(Host, Port, Options, Tty, Db, User, Passwd: PAnsiChar): PPGconn; cdecl; // FirmOS 8.1 OK\n//15022006 FirmOS: omitting   PQconnectStart\n//15022006 FirmOS: omitting  PQconnectPoll\n  TPQconndefaults  = function: PPQconninfoOption; cdecl;\n  TPQfinish        = procedure(Handle: PPGconn); cdecl;\n  TPQreset         = procedure(Handle: PPGconn); cdecl;\n//15022006 FirmOS: omitting PQresetStart\n//15022006 FirmOS: omitting PQresetPoll\n  TPQrequestCancel = function(Handle: PPGconn): Integer; cdecl;\n  TPQdb            = function(Handle: PPGconn): PAnsiChar; cdecl;\n  TPQuser          = function(Handle: PPGconn): PAnsiChar; cdecl;\n  TPQpass          = function(Handle: PPGconn): PAnsiChar; cdecl;\n  TPQhost          = function(Handle: PPGconn): PAnsiChar; cdecl;\n  TPQport          = function(Handle: PPGconn): PAnsiChar; cdecl;\n  TPQtty           = function(Handle: PPGconn): PAnsiChar; cdecl;\n  TPQoptions       = function(Handle: PPGconn): PAnsiChar; cdecl;\n  TPQstatus        = function(Handle: PPGconn): TZPostgreSQLConnectStatusType; cdecl;\n//TBD  PGTransactionStatusType PQtransactionStatus(const PGconn *conn);\n//15022006 FirmOS: omitting const char *PQparameterStatus(const PGconn *conn, const char *paramName);\n//15022006 FirmOS: omitting  PQprotocolVersion\n  TPQserverVersion = function(Handle: PPGconn): Integer; cdecl;\n  TPQerrorMessage  = function(Handle: PPGconn): PAnsiChar; cdecl;\n  TPQsocket        = function(Handle: PPGconn): Integer; cdecl;\n  TPQbackendPID    = function(Handle: PPGconn): Integer; cdecl;\n//15022006 FirmOS: omitting  SSL *PQgetssl(const PGconn *conn);\n  TPQtrace         = procedure(Handle: PPGconn; DebugPort: Pointer); cdecl;\n  TPQuntrace       = procedure(Handle: PPGconn); cdecl;\n  TPQsetNoticeProcessor = procedure(Handle: PPGconn; Proc: PQnoticeProcessor; Arg: Pointer); cdecl;\n\n  TPQclientEncoding = function(Handle: PPGconn): Integer; cdecl; //EgonHugeist\n{ === in fe-exec.c === }\n//* Simple synchronous query */\n  TPQexec          = function(Handle: PPGconn; Query: PAnsiChar): PPGresult; cdecl;\n  TPQexecParams    = function(Handle: PPGconn; command: PAnsichar;\n        nParams: Integer; paramTypes: TPQparamTypes; paramValues: TPQparamValues;\n        paramLengths: TPQparamLengths; paramFormats: TPQparamFormats;\n        resultFormat: Integer): PPGresult; cdecl;\n  TPQprepare        = function(Handle: PPGconn; stmtName: PAnsichar;\n        query: PAnsiChar; nParams: Integer; paramTypes: TPQparamTypes): PPGresult; cdecl;\n  TPQexecPrepared   = function(Handle: PPGconn; stmtName: PAnsichar;\n        nParams: Integer; paramValues: TPQparamValues; paramLengths: TPQparamLengths;\n        paramFormats: TPQparamFormats; resultFormat: Integer): PPGresult; cdecl;\n//* Interface for multiple-result or asynchronous queries */\n  TPQsendQuery      = function(Handle: PPGconn; query: PAnsiChar): Integer; cdecl;\n  TPQsendQueryParams= function(Handle: PPGconn; command: PAnsichar;\n        nParams: Integer; paramTypes: TPQparamTypes; paramValues: TPQparamValues;\n        paramLengths: TPQparamLengths; paramFormats: TPQparamFormats;\n        resultFormat: Integer): Integer; cdecl;\n  TPQsendPrepare    = function(Handle: PPGconn; stmtName: PAnsichar;\n        query: PAnsiChar; nParams: Integer; paramTypes: TPQparamTypes): Integer; cdecl;\n  TPQsendQueryPrepared = function(Handle: PPGconn; stmtName: PAnsichar;\n         nParams: Integer; paramValues: TPQparamValues;\n         paramLengths: TPQparamLengths; paramFormats: TPQparamFormats;\n         resultFormat: Integer): Integer; cdecl;\n  TPQgetResult     = function(Handle: PPGconn): PPGresult;  cdecl;\n//* Describe prepared statements and portals */\n  TPQdescribePrepared = function(Handle: PPGconn; const stmt: PAnsiChar): PPGresult; cdecl;\n  TPQdescribePortal = function(Handle: PPGconn; const portal: PAnsiChar): PPGresult; cdecl;\n  TPQsendDescribePrepared = function(Handle: PPGconn; const stmt: PAnsiChar): Integer; cdecl;\n  TPQsendDescribePortal = function(Handle: PPGconn; const portal: PAnsiChar): Integer; cdecl;\n\n  TPQnotifies      = function(Handle: PPGconn): PPGnotify; cdecl;\n  TPQfreeNotify    = procedure(Handle: PPGnotify);cdecl;\n  TPQisBusy        = function(Handle: PPGconn): Integer; cdecl;\n  TPQconsumeInput  = function(Handle: PPGconn): Integer; cdecl;\n  TPQgetCancel     = function(Handle: PPGconn): PGcancel; cdecl;\n  TPQfreeCancel    = procedure(Canc: PGcancel); cdecl;\n  TPQcancel        = function(Canc: PGcancel; Buffer: PChar; BufSize: Integer): Integer;\n  TPQgetline       = function(Handle: PPGconn; Str: PAnsiChar; length: Integer): Integer; cdecl;\n  TPQputline       = function(Handle: PPGconn; Str: PAnsiChar): Integer; cdecl;\n  TPQgetlineAsync  = function(Handle: PPGconn; Buffer: PAnsiChar; BufSize: Integer): Integer; cdecl;\n  TPQputnbytes     = function(Handle: PPGconn; Buffer: PAnsiChar; NBytes: Integer): Integer; cdecl;\n  TPQendcopy       = function(Handle: PPGconn): Integer; cdecl;\n  TPQfn            = function(Handle: PPGconn; fnid: Integer; result_buf, result_len: PInteger; result_is_int: Integer; args: PPQArgBlock; nargs: Integer): PPGresult; cdecl;\n  TPQresultStatus  = function(Result: PPGresult): TZPostgreSQLExecStatusType; cdecl;\n  TPQresultErrorMessage = function(Result: PPGresult): PAnsiChar; cdecl;\n  TPQresultErrorField=function(result: PPGResult; fieldcode:integer):PAnsiChar;cdecl; // postgresql 8\n  TPQntuples       = function(Result: PPGresult): Integer; cdecl;\n  TPQnfields       = function(Result: PPGresult): Integer; cdecl;\n  TPQbinaryTuples  = function(Result: PPGresult): Integer; cdecl;\n  TPQfname         = function(Result: PPGresult; field_num: Integer): PAnsiChar; cdecl;\n  TPQfnumber       = function(Result: PPGresult; field_name: PAnsiChar): Integer; cdecl;\n  TPQftable        = function(Result: PPGresult; field_num: Integer): Oid; cdecl;\n  TPQftablecol     = function(Result: PPGresult; field_num: Integer): Integer; cdecl;\n  TPQftype         = function(Result: PPGresult; field_num: Integer): Oid; cdecl;\n  TPQfsize         = function(Result: PPGresult; field_num: Integer): Integer; cdecl;\n  TPQfmod          = function(Result: PPGresult; field_num: Integer): Integer; cdecl;\n  TPQcmdStatus     = function(Result: PPGresult): PAnsiChar; cdecl;\n  TPQoidValue      = function(Result: PPGresult): Oid; cdecl;\n  TPQoidStatus     = function(Result: PPGresult): PAnsiChar; cdecl;\n  TPQcmdTuples     = function(Result: PPGresult): PAnsiChar; cdecl;\n  TPQgetvalue      = function(Result: PPGresult; tup_num, field_num: Integer): PAnsiChar; cdecl;\n  TPQgetlength     = function(Result: PPGresult; tup_num, field_num: Integer): Integer; cdecl;\n  TPQgetisnull     = function(Result: PPGresult; tup_num, field_num: Integer): Integer; cdecl;\n  TPQclear         = procedure(Result: PPGresult); cdecl;\n  TPQmakeEmptyPGresult  = function(Handle: PPGconn; status: TZPostgreSQLExecStatusType): PPGresult; cdecl;\n  //* Quoting strings before inclusion in queries. */\n  // postgresql 8\n  TPQescapeStringConn = function(Handle: PGconn; ToChar: PAnsiChar;\n    const FromChar: PAnsiChar; length: NativeUInt; error: PInteger): NativeUInt;cdecl; //7.3\n  TPQescapeLiteral    = function(Handle: PGconn; const str: PAnsiChar; len: NativeUInt): PAnsiChar;cdecl;\n  TPQescapeIdentifier = function(Handle: PGconn; const str: PAnsiChar; len: NativeUInt): PAnsiChar;cdecl; //7.3\n  TPQescapeByteaConn  = function(Handle: PPGconn;const from:PAnsiChar;from_length:longword;to_lenght:PLongword):PAnsiChar;cdecl;\n  TPQunescapeBytea    = function(const from:PAnsiChar;to_lenght:PLongword):PAnsiChar;cdecl;\n  TPQFreemem          = procedure(ptr:Pointer);cdecl;\n\n  //* These forms are deprecated! */\n  TPQescapeString     = function(ToChar: PAnsiChar; const FormChar: PAnsiChar; length: NativeUInt): NativeUInt;cdecl; //7.2\n  TPQescapeBytea      = function(const from:PAnsiChar;from_length:longword;to_lenght:PLongword):PAnsiChar;cdecl; //7.2\n\n  { === in fe-lobj.c === }\n  Tlo_open         = function(Handle: PPGconn; lobjId: Oid; mode: Integer): Integer; cdecl;\n  Tlo_close        = function(Handle: PPGconn; fd: Integer): Integer; cdecl;\n  Tlo_read         = function(Handle: PPGconn; fd: Integer; buf: PAnsiChar; len: NativeUInt): Integer; cdecl;\n  Tlo_write        = function(Handle: PPGconn; fd: Integer; buf: PAnsiChar; len: NativeUInt): Integer; cdecl;\n  Tlo_lseek        = function(Handle: PPGconn; fd, offset, whence: Integer): Integer; cdecl;\n  Tlo_creat        = function(Handle: PPGconn; mode: Integer): Oid; cdecl;\n  Tlo_tell         = function(Handle: PPGconn; fd: Integer): Integer; cdecl;\n  Tlo_unlink       = function(Handle: PPGconn; lobjId: Oid): Integer; cdecl;\n  Tlo_import       = function(Handle: PPGconn; filename: PAnsiChar): Oid; cdecl;\n  Tlo_export       = function(Handle: PPGconn; lobjId: Oid; filename: PAnsiChar): Integer; cdecl;\n\n{ ************** Collection of Plain API Function types definition ************* }\nTZPOSTGRESQL_API = record\n{ ===\tin fe-connect.c === }\n  PQconnectdb:     TPQconnectdb;\n  PQsetdbLogin:    TPQsetdbLogin;\n  PQconndefaults:  TPQconndefaults;\n  PQfinish:        TPQfinish;\n  PQreset:         TPQreset;\n  PQrequestCancel: TPQrequestCancel;\n  PQdb:            TPQdb;\n  PQuser:          TPQuser;\n  PQpass:          TPQpass;\n  PQhost:          TPQhost;\n  PQport:          TPQport;\n  PQtty:           TPQtty;\n  PQoptions:       TPQoptions;\n  PQstatus:        TPQstatus;\n  PQserverVersion: TPQserverVersion;\n  PQerrorMessage:  TPQerrorMessage;\n  PQsocket:        TPQsocket;\n  PQbackendPID:    TPQbackendPID;\n  PQtrace:         TPQtrace;\n  PQuntrace:       TPQuntrace;\n  PQsetNoticeProcessor: TPQsetNoticeProcessor;\n  PQclientEncoding: TPQclientEncoding;\n{ === in fe-exec.c === }\n  PQexec:          TPQexec;\n  PQexecParams:    TPQexecParams;\n  PQprepare:       TPQprepare;\n  PQexecPrepared:  TPQexecPrepared;\n  PQsendQuery:     TPQsendQuery;\n  PQsendQueryParams: TPQsendQueryParams;\n  PQsendPrepare:   TPQsendPrepare;\n  PQsendQueryPrepared: TPQsendQueryPrepared;\n  PQgetResult:     TPQgetResult;\n  //* Describe prepared statements and portals */\n  PQdescribePrepared:     TPQdescribePrepared;\n  PQdescribePortal:       TPQdescribePortal;\n  PQsendDescribePrepared: TPQsendDescribePrepared;\n  PQsendDescribePortal:   TPQsendDescribePortal;\n  PQnotifies:      TPQnotifies;\n  PQfreeNotify:    TPQfreeNotify;\n  PQisBusy:        TPQisBusy;\n  PQconsumeInput:  TPQconsumeInput;\n  PQgetCancel:     TPQgetCancel;\n  PQfreeCancel:    TPQfreeCancel;\n  PQcancel:        TPQcancel;\n  PQgetline:       TPQgetline;\n  PQputline:       TPQputline;\n  PQgetlineAsync:  TPQgetlineAsync;\n  PQputnbytes:     TPQputnbytes;\n  PQendcopy:       TPQendcopy;\n  PQfn:            TPQfn;\n  PQresultStatus:  TPQresultStatus;\n  PQresultErrorMessage: TPQresultErrorMessage;\n  PQresultErrorField: TPQresultErrorField; // postgresql 8\n  PQntuples:       TPQntuples;\n  PQnfields:       TPQnfields;\n  PQbinaryTuples:  TPQbinaryTuples;\n  PQfname:         TPQfname;\n  PQfnumber:       TPQfnumber;\n  PQftable:        TPQftable;\n  PQftablecol:     TPQftablecol;\n  PQftype:         TPQftype;\n  PQfsize:         TPQfsize;\n  PQfmod:          TPQfmod;\n  PQcmdStatus:     TPQcmdStatus;\n  PQoidValue:      TPQoidValue;\n  PQoidStatus:     TPQoidStatus;\n  PQcmdTuples:     TPQcmdTuples;\n  PQgetvalue:      TPQgetvalue;\n  PQgetlength:     TPQgetlength;\n  PQgetisnull:     TPQgetisnull;\n  PQclear:         TPQclear;\n  PQmakeEmptyPGresult:  TPQmakeEmptyPGresult;\n\n  PQescapeStringConn: TPQescapeStringConn; //since 7.3\n  PQescapeByteaConn:  TPQescapeByteaConn; // postgresql since 7.3\n  PQFreemem:          TPQFreemem; // since postgresql 7.4\n  PQescapeString:     TPQescapeString; // since postgresql 7.4\n  PQescapeBytea:      TPQescapeBytea; // since postgresql 7.4\n  PQunescapeBytea:    TPQunescapeBytea; // since postgresql 8.3\n  PQescapeLiteral:    TPQescapeLiteral; // since postgresql 9.0\n  PQescapeIdentifier: TPQescapeIdentifier; // since postgresql 9.0\n\n{ === in fe-lobj.c === }\n  lo_open:         Tlo_open;\n  lo_close:        Tlo_close;\n  lo_read:         Tlo_read;\n  lo_write:        Tlo_write;\n  lo_lseek:        Tlo_lseek;\n  lo_creat:        Tlo_creat;\n  lo_tell:         Tlo_tell;\n  lo_unlink:       Tlo_unlink;\n  lo_import:       Tlo_import;\n  lo_export:       Tlo_export;\nend;\n\nPAPI = ^TZPOSTGRESQL_API;\n\ntype\n\n  {** Represents a generic interface to PostgreSQL native API. }\n  IZPostgreSQLPlainDriver = interface (IZPlainDriver)\n    ['{03CD6345-2D7A-4FE2-B03D-3C5656789FEB}']\n\n    function GetStandardConformingStrings: Boolean;\n\n    function EncodeBYTEA(const Value: RawByteString; Handle: PZPostgreSQLConnect;\n      Quoted: Boolean = True): RawByteString;\n    function DecodeBYTEA(const value: RawByteString; const Is_bytea_output_hex: Boolean;\n      Handle: PZPostgreSQLConnect): RawByteString;\n    function SupportsEncodeBYTEA: Boolean;\n    function SupportsDecodeBYTEA(const Handle: PZPostgreSQLConnect): Boolean;\n    function SupportsStringEscaping(const ClientDependend: Boolean): Boolean;\n\n    function ConnectDatabase(ConnInfo: PAnsiChar): PZPostgreSQLConnect;\n    function SetDatabaseLogin(Host, Port, Options, TTY, Db, User,Passwd: PAnsiChar): PZPostgreSQLConnect;\n    function GetConnectDefaults: PZPostgreSQLConnectInfoOption;\n\n    procedure Finish(Handle: PZPostgreSQLConnect);\n    procedure Reset(Handle: PZPostgreSQLConnect);\n    function RequestCancel(Handle: PZPostgreSQLConnect): Integer;\n    function GetDatabase(Handle: PZPostgreSQLConnect): PAnsiChar;\n    function GetUser(Handle: PZPostgreSQLConnect): PAnsiChar;\n    function GetPassword(Handle: PZPostgreSQLConnect): PAnsiChar;\n    function GetHost(Handle: PZPostgreSQLConnect): PAnsiChar;\n    function GetPort(Handle: PZPostgreSQLConnect): PAnsiChar;\n    function GetTTY(Handle: PZPostgreSQLConnect): PAnsiChar;\n    function GetOptions(Handle: PZPostgreSQLConnect): PAnsiChar;\n    function GetStatus(Handle: PZPostgreSQLConnect):TZPostgreSQLConnectStatusType;\n    function GetClientEncoding(Handle: PPGconn): Integer; //EgonHugeist\n\n    function GetErrorMessage(Handle: PZPostgreSQLConnect): PAnsiChar;\n    function GetSocket(Handle: PZPostgreSQLConnect): Integer;\n    function GetBackendPID(Handle: PZPostgreSQLConnect): Integer;\n    procedure Trace(Handle: PZPostgreSQLConnect; DebugPort: Pointer);\n    procedure Untrace(Handle: PZPostgreSQLConnect);\n    procedure SetNoticeProcessor(Handle: PZPostgreSQLConnect;Proc: TZPostgreSQLNoticeProcessor; Arg: Pointer);\n\n    function ExecuteQuery(Handle: PZPostgreSQLConnect;Query: PAnsiChar): PZPostgreSQLResult;\n    function ExecParams(Handle: PPGconn; command: PAnsichar;\n        nParams: Integer; paramTypes: TPQparamTypes; paramValues: TPQparamValues;\n        paramLengths: TPQparamLengths; paramFormats: TPQparamFormats;\n        resultFormat: Integer): PPGresult;\n    function Prepare(Handle: PPGconn; stmtName: PAnsichar;\n        query: PAnsiChar; nParams: Integer; paramTypes: TPQparamTypes): PPGresult;\n    function ExecPrepared(Handle: PPGconn; stmtName: PAnsichar;\n        nParams: Integer; paramValues: TPQparamValues; paramLengths: TPQparamLengths;\n        paramFormats: TPQparamFormats; resultFormat: Integer): PPGresult;\n    function SendQuery(Handle: PZPostgreSQLConnect; Query: PAnsiChar): Integer;\n    function SendQueryParams(Handle: PPGconn; command: PAnsichar;\n        nParams: Integer; paramTypes: TPQparamTypes; paramValues: TPQparamValues;\n        paramLengths: TPQparamLengths; paramFormats: TPQparamFormats;\n        resultFormat: Integer): Integer;\n    function SendPrepare(Handle: PPGconn; stmtName: PAnsichar;\n        query: PAnsiChar; nParams: Integer; paramTypes: TPQparamTypes): Integer;\n    function SendQueryPrepared(Handle: PPGconn; stmtName: PAnsichar;\n         nParams: Integer; paramValues: TPQparamValues;\n         paramLengths: TPQparamLengths; paramFormats: TPQparamFormats;\n         resultFormat: Integer): Integer;\n    function GetResult(Handle: PZPostgreSQLConnect): PZPostgreSQLResult;\n    //* Describe prepared statements and portals */\n    function DescribePrepared(Handle: PPGconn; const stmt: PAnsiChar): PPGresult;\n    function DescribePortal(Handle: PPGconn; const portal: PAnsiChar): PPGresult;\n    function SendDescribePrepared(Handle: PPGconn; const stmt: PAnsiChar): Integer;\n    function SendDescribePortal(Handle: PPGconn; const portal: PAnsiChar): Integer;\n    function Notifies(Handle: PZPostgreSQLConnect): PZPostgreSQLNotify;\n    procedure FreeNotify(Handle: PZPostgreSQLNotify);\n\n    function IsBusy(Handle: PZPostgreSQLConnect): Integer;\n    function ConsumeInput(Handle: PZPostgreSQLConnect): Integer;\n    function GetCancel(Handle: PZPostgreSQLConnect): PZPostgreSQLCancel;\n    procedure FreeCancel( Canc: PZPostgreSQLCancel);\n    function Cancel( Canc: PZPostgreSQLCancel; Buffer: PChar; Length: Integer): Integer;\n    function GetLine(Handle: PZPostgreSQLConnect; Str: PAnsiChar;\n      Length: Integer): Integer;\n    function PutLine(Handle: PZPostgreSQLConnect; Str: PAnsiChar): Integer;\n    function GetLineAsync(Handle: PZPostgreSQLConnect; Buffer: PAnsiChar;\n      Length: Integer): Integer;\n\n    function PutBytes(Handle: PZPostgreSQLConnect; Buffer: PAnsiChar;\n      Length: Integer): Integer;\n    function EndCopy(Handle: PZPostgreSQLConnect): Integer;\n    function ExecuteFunction(Handle: PZPostgreSQLConnect; fnid: Integer;\n      result_buf, result_len: PInteger; result_is_int: Integer;\n      args: PZPostgreSQLArgBlock; nargs: Integer): PZPostgreSQLResult;\n    function GetResultStatus(Res: PZPostgreSQLResult):\n      TZPostgreSQLExecStatusType;\n\n    function GetResultErrorMessage(Res: PZPostgreSQLResult): PAnsiChar;\n    function GetResultErrorField(Res: PZPostgreSQLResult; FieldCode: TZPostgreSQLFieldCode): PAnsiChar;\n\n    function GetRowCount(Res: PZPostgreSQLResult): Integer;\n    function GetFieldCount(Res: PZPostgreSQLResult): Integer;\n\n    function GetBinaryTuples(Res: PZPostgreSQLResult): Integer;\n    function GetFieldName(Res: PZPostgreSQLResult; FieldNum: Integer): PAnsiChar;\n    function GetFieldNumber(Res: PZPostgreSQLResult; FieldName: PAnsiChar): Integer;\n    function GetFieldTableOID(Res: PZPostgreSQLResult; FieldNum: Integer) : Oid;\n    function GetFieldTableColIdx(Res: PZPostgreSQLResult; FieldNum: Integer) : Integer;\n    function GetFieldType(Res: PZPostgreSQLResult; FieldNum: Integer): Oid;\n    function GetFieldSize(Res: PZPostgreSQLResult;  FieldNum: Integer): Integer;\n    function GetFieldMode(Res: PZPostgreSQLResult; FieldNum: Integer): Integer;\n    function GetCommandStatus(Res: PZPostgreSQLResult): PAnsiChar;\n    function GetOidValue(Res: PZPostgreSQLResult): Oid;\n    function GetOidStatus(Res: PZPostgreSQLResult): PAnsiChar;\n    function GetCommandTuples(Res: PZPostgreSQLResult): PAnsiChar;\n\n    function GetValue(Res: PZPostgreSQLResult;  TupNum, FieldNum: Integer): PAnsiChar;\n    function GetLength(Res: PZPostgreSQLResult; TupNum, FieldNum: Integer): Integer;\n    function GetIsNull(Res: PZPostgreSQLResult; TupNum, FieldNum: Integer): Integer;\n    procedure Clear(Res: PZPostgreSQLResult);\n\n    function MakeEmptyResult(Handle: PZPostgreSQLConnect;\n      Status: TZPostgreSQLExecStatusType): PZPostgreSQLResult;\n\n    function OpenLargeObject(Handle: PZPostgreSQLConnect; ObjId: Oid;\n      Mode: Integer): Integer;\n    function CloseLargeObject(Handle: PZPostgreSQLConnect;\n      Fd: Integer): Integer;\n    function ReadLargeObject(Handle: PZPostgreSQLConnect; Fd: Integer;\n      Buffer: PAnsiChar; Length: Integer): Integer;\n    function WriteLargeObject(Handle: PZPostgreSQLConnect; Fd: Integer;\n      Buffer: PAnsiChar; Length: Integer): Integer;\n    function SeekLargeObject(Handle: PZPostgreSQLConnect;\n      Fd, Offset, Whence: Integer): Integer;\n    function CreateLargeObject(Handle: PZPostgreSQLConnect;\n      Mode: Integer): Oid;\n    function TellLargeObject(Handle: PZPostgreSQLConnect;\n      Fd: Integer): Integer;\n    function UnlinkLargeObject(Handle: PZPostgreSQLConnect;\n      ObjId: Oid): Integer;\n    function ImportLargeObject(Handle: PZPostgreSQLConnect;\n      FileName: PAnsiChar): Oid;\n    function ExportLargeObject(Handle: PZPostgreSQLConnect; ObjId: Oid;\n      FileName: PAnsiChar): Integer;\n    function GetPlainFunc:PAPI;\n  end;\n\n  {** Implements a base driver for PostgreSQL}\n  TZPostgreSQLBaseDriver = class(TZAbstractPlainDriver, IZPostgreSQLPlainDriver)\n  protected\n    POSTGRESQL_API: TZPOSTGRESQL_API;\n    function GetStandardConformingStrings: Boolean; virtual;\n    function GetUnicodeCodePageName: String; override;\n    procedure LoadCodePages; override;\n    procedure LoadApi; override;\n  public\n    constructor Create;\n\n    function EncodeBYTEA(const Value: RawByteString; Handle: PZPostgreSQLConnect;\n      Quoted: Boolean = True): RawByteString;\n    function DecodeBYTEA(const value: RawByteString; const Is_bytea_output_hex: Boolean;\n      Handle: PZPostgreSQLConnect): RawByteString;\n\n    function SupportsEncodeBYTEA: Boolean;\n    function SupportsDecodeBYTEA(const Handle: PZPostgreSQLConnect): Boolean;\n    function SupportsStringEscaping(const ClientDependend: Boolean): Boolean;\n\n    function ConnectDatabase(ConnInfo: PAnsiChar): PZPostgreSQLConnect;\n    function SetDatabaseLogin(Host, Port, Options, TTY, Db, User,\n      Passwd: PAnsiChar): PZPostgreSQLConnect;\n    function GetConnectDefaults: PZPostgreSQLConnectInfoOption;\n\n    procedure Finish(Handle: PZPostgreSQLConnect);\n    procedure Reset(Handle: PZPostgreSQLConnect);\n    function RequestCancel(Handle: PZPostgreSQLConnect): Integer;\n    function GetDatabase(Handle: PZPostgreSQLConnect): PAnsiChar;\n    function GetUser(Handle: PZPostgreSQLConnect): PAnsiChar;\n    function GetPassword(Handle: PZPostgreSQLConnect): PAnsiChar;\n    function GetHost(Handle: PZPostgreSQLConnect): PAnsiChar;\n    function GetPort(Handle: PZPostgreSQLConnect): PAnsiChar;\n    function GetTTY(Handle: PZPostgreSQLConnect): PAnsiChar;\n    function GetOptions(Handle: PZPostgreSQLConnect): PAnsiChar;\n    function GetStatus(Handle: PZPostgreSQLConnect):\n      TZPostgreSQLConnectStatusType;\n    function GetClientEncoding(Handle: PPGconn): Integer; //EgonHugeist\n\n    function GetErrorMessage(Handle: PZPostgreSQLConnect): PAnsiChar;\n    function GetSocket(Handle: PZPostgreSQLConnect): Integer;\n    function GetBackendPID(Handle: PZPostgreSQLConnect): Integer;\n    procedure Trace(Handle: PZPostgreSQLConnect; DebugPort: Pointer);\n    procedure Untrace(Handle: PZPostgreSQLConnect);\n    procedure SetNoticeProcessor(Handle: PZPostgreSQLConnect;\n      Proc: TZPostgreSQLNoticeProcessor; Arg: Pointer);\n\n    function ExecuteQuery(Handle: PZPostgreSQLConnect;\n      Query: PAnsiChar): PZPostgreSQLResult;\n    function ExecParams(Handle: PPGconn; command: PAnsichar;\n        nParams: Integer; paramTypes: TPQparamTypes; paramValues: TPQparamValues;\n        paramLengths: TPQparamLengths; paramFormats: TPQparamFormats;\n        resultFormat: Integer): PPGresult;\n    function Prepare(Handle: PPGconn; stmtName: PAnsichar;\n        query: PAnsiChar; nParams: Integer; paramTypes: TPQparamTypes): PPGresult;\n    function ExecPrepared(Handle: PPGconn; stmtName: PAnsichar;\n        nParams: Integer; paramValues: TPQparamValues; paramLengths: TPQparamLengths;\n        paramFormats: TPQparamFormats; resultFormat: Integer): PPGresult;\n    function SendQuery(Handle: PZPostgreSQLConnect; Query: PAnsiChar): Integer;\n    function SendQueryParams(Handle: PPGconn; command: PAnsichar;\n        nParams: Integer; paramTypes: TPQparamTypes; paramValues: TPQparamValues;\n        paramLengths: TPQparamLengths; paramFormats: TPQparamFormats;\n        resultFormat: Integer): Integer;\n    function SendPrepare(Handle: PPGconn; stmtName: PAnsichar;\n        query: PAnsiChar; nParams: Integer; paramTypes: TPQparamTypes): Integer;\n    function SendQueryPrepared(Handle: PPGconn; stmtName: PAnsichar;\n         nParams: Integer; paramValues: TPQparamValues;\n         paramLengths: TPQparamLengths; paramFormats: TPQparamFormats;\n         resultFormat: Integer): Integer;\n    function GetResult(Handle: PZPostgreSQLConnect): PZPostgreSQLResult;\n    function DescribePrepared(Handle: PPGconn; const stmt: PAnsiChar): PPGresult;\n    function DescribePortal(Handle: PPGconn; const portal: PAnsiChar): PPGresult;\n    function SendDescribePrepared(Handle: PPGconn; const stmt: PAnsiChar): Integer;\n    function SendDescribePortal(Handle: PPGconn; const portal: PAnsiChar): Integer;\n\n    function Notifies(Handle: PZPostgreSQLConnect): PZPostgreSQLNotify;\n    procedure FreeNotify(Handle: PZPostgreSQLNotify);\n\n    function IsBusy(Handle: PZPostgreSQLConnect): Integer;\n    function ConsumeInput(Handle: PZPostgreSQLConnect): Integer;\n    function GetCancel(Handle: PZPostgreSQLConnect): PZPostgreSQLCancel;\n    procedure FreeCancel( Canc: PZPostgreSQLCancel);\n    function Cancel( Canc: PZPostgreSQLCancel; Buffer: PChar; Length: Integer): Integer;\n    function GetLine(Handle: PZPostgreSQLConnect; Buffer: PAnsiChar;\n      Length: Integer): Integer;\n    function PutLine(Handle: PZPostgreSQLConnect; Buffer: PAnsiChar): Integer;\n    function GetLineAsync(Handle: PZPostgreSQLConnect; Buffer: PAnsiChar;\n      Length: Integer): Integer;\n\n    function PutBytes(Handle: PZPostgreSQLConnect; Buffer: PAnsiChar;\n      Length: Integer): Integer;\n    function EndCopy(Handle: PZPostgreSQLConnect): Integer;\n    function ExecuteFunction(Handle: PZPostgreSQLConnect; fnid: Integer;\n      result_buf, result_len: PInteger; result_is_int: Integer;\n      args: PZPostgreSQLArgBlock; nargs: Integer): PZPostgreSQLResult;\n    function GetResultStatus(Res: PZPostgreSQLResult): TZPostgreSQLExecStatusType;\n    function GetResultErrorMessage(Res: PZPostgreSQLResult): PAnsiChar;\n    function GetResultErrorField(Res: PZPostgreSQLResult;FieldCode:TZPostgreSQLFieldCode):PAnsiChar;\n\n    function GetRowCount(Res: PZPostgreSQLResult): Integer;\n    function GetFieldCount(Res: PZPostgreSQLResult): Integer;\n\n    function GetBinaryTuples(Res: PZPostgreSQLResult): Integer;\n    function GetFieldName(Res: PZPostgreSQLResult;\n      FieldNum: Integer): PAnsiChar;\n    function GetFieldNumber(Res: PZPostgreSQLResult;\n      FieldName: PAnsiChar): Integer;\n    function GetFieldTableOID(Res: PZPostgreSQLResult; FieldNum: Integer) : Oid;\n    function GetFieldTableColIdx(Res: PZPostgreSQLResult; FieldNum: Integer) : Integer;\n    function GetFieldType(Res: PZPostgreSQLResult;\n      FieldNum: Integer): Oid;\n    function GetFieldSize(Res: PZPostgreSQLResult;\n      FieldNum: Integer): Integer;\n    function GetFieldMode(Res: PZPostgreSQLResult;\n      FieldNum: Integer): Integer;\n    function GetCommandStatus(Res: PZPostgreSQLResult): PAnsiChar;\n    function GetOidValue(Res: PZPostgreSQLResult): Oid;\n    function GetOidStatus(Res: PZPostgreSQLResult): PAnsiChar;\n    function GetCommandTuples(Res: PZPostgreSQLResult): PAnsiChar;\n\n    function GetValue(Res: PZPostgreSQLResult;\n      TupNum, FieldNum: Integer): PAnsiChar;\n    function GetLength(Res: PZPostgreSQLResult;\n      TupNum, FieldNum: Integer): Integer;\n    function GetIsNull(Res: PZPostgreSQLResult;\n      TupNum, FieldNum: Integer): Integer;\n    procedure Clear(Res: PZPostgreSQLResult);\n\n    function MakeEmptyResult(Handle: PZPostgreSQLConnect;\n      Status: TZPostgreSQLExecStatusType): PZPostgreSQLResult;\n\n    function OpenLargeObject(Handle: PZPostgreSQLConnect; ObjId: Oid;\n      Mode: Integer): Integer;\n    function CloseLargeObject(Handle: PZPostgreSQLConnect;\n      Fd: Integer): Integer;\n    function ReadLargeObject(Handle: PZPostgreSQLConnect; Fd: Integer;\n      Buffer: PAnsiChar; Length: Integer): Integer;\n    function WriteLargeObject(Handle: PZPostgreSQLConnect; Fd: Integer;\n      Buffer: PAnsiChar; Length: Integer): Integer;\n    function SeekLargeObject(Handle: PZPostgreSQLConnect;\n      Fd, Offset, Whence: Integer): Integer;\n    function CreateLargeObject(Handle: PZPostgreSQLConnect;\n      Mode: Integer): Oid;\n    function TellLargeObject(Handle: PZPostgreSQLConnect;\n      Fd: Integer): Integer;\n    function UnlinkLargeObject(Handle: PZPostgreSQLConnect;\n      ObjId: Oid): Integer;\n    function ImportLargeObject(Handle: PZPostgreSQLConnect;\n      FileName: PAnsiChar): Oid;\n    function ExportLargeObject(Handle: PZPostgreSQLConnect; ObjId: Oid;\n      FileName: PAnsiChar): Integer;\n    function GetPlainFunc:PAPI;\n    function EscapeString(Handle: Pointer; const Value: RawByteString;\n      ConSettings: PZConSettings; WasEncoded: Boolean = False): RawByteString; override;\n  end;\n\n  {** Implements a driver for PostgreSQL 7.4 }\n  TZPostgreSQL7PlainDriver = class(TZPostgreSQLBaseDriver, IZPlainDriver,\n    IZPostgreSQLPlainDriver)\n  protected\n    function Clone: IZPlainDriver; override;\n  public\n    constructor Create;\n\n    function GetProtocol: string; override;\n    function GetDescription: string; override;\n end;\n\n\n  {** Implements a driver for PostgreSQL 8.1 }\n\n  { TZPostgreSQL8PlainDriver }\n\n  TZPostgreSQL8PlainDriver = class(TZPostgreSQLBaseDriver, IZPlainDriver,IZPostgreSQLPlainDriver)\n  protected\n    function Clone: IZPlainDriver; override;\n    function GetUnicodeCodePageName: String; override;\n    procedure LoadCodePages; override;\n  public\n    constructor Create;\n\n    function GetProtocol: string; override;\n    function GetDescription: string; override;\n  end;\n\n  { TZPostgreSQL8PlainDriver }\n\n  TZPostgreSQL9PlainDriver = class(TZPostgreSQL8PlainDriver)\n  protected\n    function Clone: IZPlainDriver; override;\n    function GetStandardConformingStrings: Boolean; override;\n    procedure LoadCodePages; override;\n  public\n    constructor Create;\n\n    function GetProtocol: string; override;\n    function GetDescription: string; override;\n  end;\n\nimplementation\n\nuses SysUtils, ZPlainLoader, Classes, ZEncoding\n  {$IFDEF WITH_UNITANSISTRINGS}, AnsiStrings{$ENDIF};\n\n{ TZPostgreSQLBaseDriver }\n\nfunction TZPostgreSQLBaseDriver.GetUnicodeCodePageName: String;\nbegin\n  Result := 'UNICODE';\nend;\n\nprocedure TZPostgreSQLBaseDriver.LoadCodePages;\nbegin\n  { MultiByte }\n  AddCodePage('EUC_JP', Ord(csEUC_JP), ceAnsi, zCP_EUC_JP, '', 3); { EUC_JP \tJapanese EUC }\n  AddCodePage('EUC_CN', Ord(csEUC_CN), ceAnsi, zCP_EUC_CN, '', 3); {EUC_CN \tChinese EUC}\n  AddCodePage('EUC_KR', Ord(csEUC_KR), ceAnsi, zCP_euc_kr, '', 3); {Extended UNIX Code-KR \tKorean}\n  AddCodePage('JOHAB', Ord(csJOHAB), ceAnsi, ZCP_JOHAB, '', 3); {JOHAB \tKorean (Hangul)}\n  AddCodePage('EUC_TW', Ord(csEUC_TW), ceAnsi, $ffff, '', 3); {Extended UNIX Code-TW \tTraditional Chinese, Taiwanese}\n  AddCodePage('UNICODE', Ord(csUNICODE_PODBC), ceUTF8, zCP_UTF8, '', 4); {UNICODE \tUnicode (UTF-8)}\n  AddCodePage('MULE_INTERNAL', Ord(csMULE_INTERNAL), ceAnsi, $ffff, '', 4); { Mule internal code \tMultilingual Emacs }\n  {SingleByte}\n  AddCodePage('SQL_ASCII', Ord(csSQL_ASCII), ceAnsi, zCP_us_ascii); {unspecified (see text) \tany}\n  AddCodePage('LATIN1', Ord(csLATIN1), ceAnsi, zCP_WIN1252); { ISO 8859-1, ECMA 94 \tWestern European }\n  AddCodePage('LATIN2', Ord(csLATIN2), ceAnsi, zCP_L2_ISO_8859_2);  { \tISO 8859-2, ECMA 94 \tCentral European }\n  AddCodePage('LATIN3', Ord(csLATIN3), ceAnsi, zCP_L3_ISO_8859_3);  { ISO 8859-3, ECMA 94 \tSouth European }\n  AddCodePage('LATIN4', Ord(csLATIN4), ceAnsi, zCP_L4_ISO_8859_4);  { ISO 8859-4, ECMA 94 \tNorth European }\n  AddCodePage('LATIN5', Ord(csLATIN5), ceAnsi, zCP_L5_ISO_8859_9);  { ISO 8859-9, ECMA 128 \tTurkish }\n  AddCodePage('LATIN6', Ord(csLATIN6), ceAnsi, zCP_L6_ISO_8859_10);  { ISO 8859-10, ECMA 144 \tNordic }\n  AddCodePage('LATIN7', Ord(csLATIN7), ceAnsi, zCP_L7_ISO_8859_13);  { ISO 8859-13 \tBaltic }\n  AddCodePage('LATIN8', Ord(csLATIN8), ceAnsi, zCP_L8_ISO_8859_14);  { ISO 8859-14 \tCeltic }\n  AddCodePage('LATIN9', Ord(csLATIN9), ceAnsi, zCP_L9_ISO_8859_15);  { ISO 8859-15 \tLATIN1 with Euro and accents }\n  AddCodePage('LATIN10', Ord(csLATIN10), ceAnsi, zCP_L10_ISO_8859_16);  { ISO 8859-16, ASRO SR 14111 \tRomanian }\n  AddCodePage('ISO_8859_5', Ord(csISO_8859_5), ceAnsi, zCP_L5_ISO_8859_5); { ISO 8859-5, ECMA 113 \tLatin/Cyrillic}\n  AddCodePage('ISO_8859_6', Ord(csISO_8859_6), ceAnsi, zCP_L6_ISO_8859_6); { ISO 8859-6, ECMA 114 \tLatin/Arabic }\n  AddCodePage('ISO_8859_7', Ord(csISO_8859_7), ceAnsi, zCP_L7_ISO_8859_7); { ISO 8859-7, ECMA 118 \tLatin/Greek }\n  AddCodePage('ISO_8859_8', Ord(csISO_8859_8), ceAnsi, zCP_L8_ISO_8859_8);  { ISO 8859-8, ECMA 121 \tLatin/Hebrew }\n  AddCodePage('KOI8', Ord(csKOI8), ceAnsi, zCP_KOI8R);  { KOI8-R(U) \tCyrillic }\n  AddCodePage('WIN', Ord(csWIN), ceAnsi, zCP_WIN1251); { Windows CP1251 }\n  AddCodePage('ALT', Ord(csALT), ceAnsi, zCP_DOS866); { Windows CP866 }\n  AddCodePage('WIN1256', Ord(csWIN1256), ceAnsi, cCP_WIN1256);  { Windows CP1256 \tArabic }\n  AddCodePage('TCVN', Ord(csTCVN), ceAnsi, zCP_WIN1258); { TCVN-5712/Windows CP1258 (Vietnamese) }\n  AddCodePage('WIN874', Ord(csWIN874), ceAnsi, zCP_DOS874); { Windows CP874 (Thai) }\nend;\n\nprocedure TZPostgreSQLBaseDriver.LoadApi;\nbegin\n{ ************** Load adresses of API Functions ************* }\n  with Loader do\n  begin\n  { ===\tin fe-connect.c === }\n    @POSTGRESQL_API.PQconnectdb    := GetAddress('PQconnectdb');\n    @POSTGRESQL_API.PQsetdbLogin   := GetAddress('PQsetdbLogin');\n    @POSTGRESQL_API.PQconndefaults := GetAddress('PQconndefaults');\n    @POSTGRESQL_API.PQfinish       := GetAddress('PQfinish');\n    @POSTGRESQL_API.PQreset        := GetAddress('PQreset');\n    @POSTGRESQL_API.PQrequestCancel := GetAddress('PQrequestCancel');\n    @POSTGRESQL_API.PQdb           := GetAddress('PQdb');\n    @POSTGRESQL_API.PQuser         := GetAddress('PQuser');\n    @POSTGRESQL_API.PQpass         := GetAddress('PQpass');\n    @POSTGRESQL_API.PQhost         := GetAddress('PQhost');\n    @POSTGRESQL_API.PQport         := GetAddress('PQport');\n    @POSTGRESQL_API.PQtty          := GetAddress('PQtty');\n    @POSTGRESQL_API.PQoptions      := GetAddress('PQoptions');\n    @POSTGRESQL_API.PQstatus       := GetAddress('PQstatus');\n    @POSTGRESQL_API.PQserverVersion:= GetAddress('PQserverVersion');\n    @POSTGRESQL_API.PQerrorMessage := GetAddress('PQerrorMessage');\n    @POSTGRESQL_API.PQsocket       := GetAddress('PQsocket');\n    @POSTGRESQL_API.PQbackendPID   := GetAddress('PQbackendPID');\n    @POSTGRESQL_API.PQtrace        := GetAddress('PQtrace');\n    @POSTGRESQL_API.PQuntrace      := GetAddress('PQuntrace');\n    @POSTGRESQL_API.PQsetNoticeProcessor := GetAddress('PQsetNoticeProcessor');\n    @POSTGRESQL_API.PQclientEncoding := GetAddress('PQclientEncoding');\n  { === in fe-exec.c === }\n    @POSTGRESQL_API.PQexec         := GetAddress('PQexec');\n    @POSTGRESQL_API.PQexecParams   := GetAddress('PQexecParams');\n    @POSTGRESQL_API.PQprepare      := GetAddress('PQprepare');\n    @POSTGRESQL_API.PQexecPrepared := GetAddress('PQexecPrepared');\n    @POSTGRESQL_API.PQsendQuery    := GetAddress('PQsendQuery');\n    @POSTGRESQL_API.PQsendQueryParams:= GetAddress('PQsendQueryParams');\n    @POSTGRESQL_API.PQsendPrepare  := GetAddress('PQsendPrepare');\n    @POSTGRESQL_API.PQsendQueryPrepared := GetAddress('PQsendQueryPrepared');\n    @POSTGRESQL_API.PQgetResult    := GetAddress('PQgetResult');\n\n    @POSTGRESQL_API.PQnotifies     := GetAddress('PQnotifies');\n    @POSTGRESQL_API.PQfreeNotify   := GetAddress('PQfreeNotify');\n    @POSTGRESQL_API.PQisBusy       := GetAddress('PQisBusy');\n    @POSTGRESQL_API.PQconsumeInput := GetAddress('PQconsumeInput');\n    @POSTGRESQL_API.PQgetline      := GetAddress('PQgetline');\n    @POSTGRESQL_API.PQputline      := GetAddress('PQputline');\n    @POSTGRESQL_API.PQgetlineAsync := GetAddress('PQgetlineAsync');\n    @POSTGRESQL_API.PQputnbytes    := GetAddress('PQputnbytes');\n    @POSTGRESQL_API.PQendcopy      := GetAddress('PQendcopy');\n    @POSTGRESQL_API.PQfn           := GetAddress('PQfn');\n    @POSTGRESQL_API.PQresultStatus := GetAddress('PQresultStatus');\n    @POSTGRESQL_API.PQresultErrorMessage := GetAddress('PQresultErrorMessage');\n    @POSTGRESQL_API.PQntuples      := GetAddress('PQntuples');\n    @POSTGRESQL_API.PQnfields      := GetAddress('PQnfields');\n    @POSTGRESQL_API.PQbinaryTuples := GetAddress('PQbinaryTuples');\n    @POSTGRESQL_API.PQfname        := GetAddress('PQfname');\n    @POSTGRESQL_API.PQfnumber      := GetAddress('PQfnumber');\n    @POSTGRESQL_API.PQftable       := GetAddress('PQftable');\n    @POSTGRESQL_API.PQftablecol    := GetAddress('PQftablecol');\n    @POSTGRESQL_API.PQftype        := GetAddress('PQftype');\n    @POSTGRESQL_API.PQfsize        := GetAddress('PQfsize');\n    @POSTGRESQL_API.PQfmod         := GetAddress('PQfmod');\n    @POSTGRESQL_API.PQcmdStatus    := GetAddress('PQcmdStatus');\n    @POSTGRESQL_API.PQoidValue     := GetAddress('PQoidValue');\n    @POSTGRESQL_API.PQoidStatus    := GetAddress('PQoidStatus');\n    @POSTGRESQL_API.PQcmdTuples    := GetAddress('PQcmdTuples');\n    @POSTGRESQL_API.PQgetvalue     := GetAddress('PQgetvalue');\n    @POSTGRESQL_API.PQgetlength    := GetAddress('PQgetlength');\n    @POSTGRESQL_API.PQgetisnull    := GetAddress('PQgetisnull');\n    @POSTGRESQL_API.PQclear        := GetAddress('PQclear');\n    @POSTGRESQL_API.PQmakeEmptyPGresult := GetAddress('PQmakeEmptyPGresult');\n\n  { === in fe-lobj.c === }\n    @POSTGRESQL_API.lo_open        := GetAddress('lo_open');\n    @POSTGRESQL_API.lo_close       := GetAddress('lo_close');\n    @POSTGRESQL_API.lo_read        := GetAddress('lo_read');\n    @POSTGRESQL_API.lo_write       := GetAddress('lo_write');\n    @POSTGRESQL_API.lo_lseek       := GetAddress('lo_lseek');\n    @POSTGRESQL_API.lo_creat       := GetAddress('lo_creat');\n    @POSTGRESQL_API.lo_tell        := GetAddress('lo_tell');\n    @POSTGRESQL_API.lo_unlink      := GetAddress('lo_unlink');\n    @POSTGRESQL_API.lo_import      := GetAddress('lo_import');\n    @POSTGRESQL_API.lo_export      := GetAddress('lo_export');\n    @POSTGRESQL_API.PQescapeStringConn  := GetAddress('PQescapeStringConn'); //since 7.3\n    @POSTGRESQL_API.PQescapeByteaConn   := GetAddress('PQescapeByteaConn'); // postgresql since 7.3\n    @POSTGRESQL_API.PQFreemem           := GetAddress('PQfreemem'); // since postgresql 7.4\n    @POSTGRESQL_API.PQescapeString      := GetAddress('PQescapeString'); // since postgresql 7.4\n    @POSTGRESQL_API.PQescapeBytea       := GetAddress('PQescapeBytea'); // since postgresql 7.4\n    @POSTGRESQL_API.PQunescapeBytea     := GetAddress('PQunescapeBytea'); // since postgresql 8.3\n    @POSTGRESQL_API.PQescapeLiteral     := GetAddress('PQescapeLiteral'); // since postgresql 9.0\n    @POSTGRESQL_API.PQescapeIdentifier  := GetAddress('PQescapeIdentifier'); // since postgresql 9.0\n\n    @POSTGRESQL_API.PQresultErrorField  := GetAddress('PQresultErrorField');\n    @POSTGRESQL_API.PQgetCancel         := GetAddress('PQgetCancel');\n    @POSTGRESQL_API.PQfreeCancel        := GetAddress('PQfreeCancel');\n    @POSTGRESQL_API.PQcancel            := GetAddress('PQcancel');\n  end;\nend;\n\nconstructor TZPostgreSQLBaseDriver.Create;\nbegin\n  inherited create;\n  FLoader := TZNativeLibraryLoader.Create([]);\n  {$IFNDEF STRICT_DLL_LOADING}\n    {$IFNDEF UNIX}\n      FLoader.AddLocation(WINDOWS_DLL_LOCATION);\n    {$ELSE}\n      FLoader.AddLocation(LINUX_DLL_LOCATION);\n    {$ENDIF}\n  {$ENDIF}\n  LoadCodePages;\nend;\n\nprocedure TZPostgreSQLBaseDriver.Clear(Res: PZPostgreSQLResult);\nbegin\n  POSTGRESQL_API.PQclear(Res);\nend;\n\nfunction TZPostgreSQLBaseDriver.CloseLargeObject(\n  Handle: PZPostgreSQLConnect; Fd: Integer): Integer;\nbegin\n  Result := POSTGRESQL_API.lo_close(Handle, Fd);\nend;\n\nfunction TZPostgreSQLBaseDriver.ConnectDatabase(\n  ConnInfo: PAnsiChar): PZPostgreSQLConnect;\nbegin\n  Result := POSTGRESQL_API.PQconnectdb(ConnInfo);\nend;\n\nfunction TZPostgreSQLBaseDriver.ConsumeInput(\n  Handle: PZPostgreSQLConnect): Integer;\nbegin\n  Result := POSTGRESQL_API.PQconsumeInput(Handle);\nend;\n\nfunction TZPostgreSQLBaseDriver.GetCancel(Handle: PZPostgreSQLConnect): PZPostgreSQLCancel;\nbegin\n  if Assigned(POSTGRESQL_API.PQgetCancel) then\n    Result := POSTGRESQL_API.PQgetCancel(Handle)\n  else\n    Result := nil;\nend;\n\nprocedure TZPostgreSQLBaseDriver.FreeCancel(Canc: PZPostgreSQLCancel);\nbegin\n  if Assigned(POSTGRESQL_API.PQfreeCancel) then\n    POSTGRESQL_API.PQfreeCancel( Canc);\nend;\n\nfunction TZPostgreSQLBaseDriver.Cancel(Canc: PZPostgreSQLCancel; Buffer: PChar; Length: Integer): Integer;\nbegin\n  if Assigned(POSTGRESQL_API.PQcancel) then\n    Result := POSTGRESQL_API.PQcancel( Canc, Buffer, Length)\n  else\n    Result := 0;\nend;\n\nfunction TZPostgreSQLBaseDriver.CreateLargeObject(\n  Handle: PZPostgreSQLConnect; Mode: Integer): Oid;\nbegin\n  Result := POSTGRESQL_API.lo_creat(Handle, Mode);\nend;\n\nfunction TZPostgreSQLBaseDriver.DecodeBYTEA(const value: RawByteString;\n  const Is_bytea_output_hex: Boolean; Handle: PZPostgreSQLConnect): RawByteString;\nvar\n  decoded: PAnsiChar;\n  Ansi: AnsiString;\n  len: Longword;\nbegin\n  if ( Is_bytea_output_hex ) then\n  begin\n    Len := (Length(value)-{$IFDEF WITH_UNITANSISTRINGS}AnsiStrings.AnsiPos{$ELSE}Pos{$ENDIF}('x', value)) div 2; //GetLength of binary result\n    Ansi := AnsiString(Copy(value, {$IFDEF WITH_UNITANSISTRINGS}AnsiStrings.AnsiPos{$ELSE}Pos{$ENDIF}('x', value)+1, Length(value))); //remove the first 'x'sign-byte\n    SetLength(Result, Len); //Set length of binary-result\n    HexToBin(PAnsiChar(Ansi), PAnsichar(Result), Len); //convert hex to binary\n  end\n  else\n    if Assigned(POSTGRESQL_API.PQUnescapeBytea) then\n    begin\n      decoded := POSTGRESQL_API.PQUnescapeBytea(PAnsiChar(value), @len);\n      SetLength(result, len);\n      if (len > 0) then\n         Move(decoded^, result[1], len);\n      if Assigned(POSTGRESQL_API.PQFreemem) then\n        POSTGRESQL_API.PQFreemem(decoded);\n    end\n    else\n      Result := Value;\nend;\n\nfunction TZPostgreSQLBaseDriver.SupportsEncodeBYTEA: Boolean;\nbegin\n  Result := Assigned(POSTGRESQL_API.PQescapeByteaConn) or\n    Assigned(POSTGRESQL_API.PQescapeBytea);\nend;\n\nfunction TZPostgreSQLBaseDriver.SupportsDecodeBYTEA(const Handle: PZPostgreSQLConnect): Boolean;\nbegin\n  Result := ( POSTGRESQL_API.PQserverVersion(Handle) div 10000 >= 9 ) or\n    Assigned(POSTGRESQL_API.PQUnescapeBytea);\nend;\n\nfunction TZPostgreSQLBaseDriver.SupportsStringEscaping(const ClientDependend: Boolean): Boolean;\nbegin\n  if ClientDependend then\n    Result := Assigned(POSTGRESQL_API.PQescapeStringConn)\n  else\n    Result := Assigned(POSTGRESQL_API.PQescapeStringConn) or\n              Assigned(POSTGRESQL_API.PQescapeString);\nend;\n\nfunction TZPostgreSQLBaseDriver.EncodeBYTEA(const Value: RawByteString;\n  Handle: PZPostgreSQLConnect; Quoted: Boolean = True): RawByteString;\nvar\n  encoded: PAnsiChar;\n  len: Longword;\n  leng: cardinal;\nbegin\n  if assigned(POSTGRESQL_API.PQescapeByteaConn) or\n    Assigned(POSTGRESQL_API.PQescapeBytea) then\n  begin\n    leng := Length(Value);\n    if assigned(POSTGRESQL_API.PQescapeByteaConn) then\n      encoded := POSTGRESQL_API.PQescapeByteaConn(Handle, PAnsiChar(value), leng, @len)\n    else\n      encoded := POSTGRESQL_API.PQescapeBytea(PAnsiChar(value),leng,@len);\n    SetLength(result, len -1); //removes the #0 byte\n\n    {$IFDEF WITH_STRLCOPY_DEPRECATED}AnsiStrings.{$ENDIF}StrLCopy(PAnsiChar(result), encoded, len - 1);\n\n    POSTGRESQL_API.PQFreemem(encoded);\n    if Quoted then\n      result := ''''+result+'''';\n  end\n  else\n    Result := Value;\nend;\n\nfunction TZPostgreSQLBaseDriver.EndCopy( Handle: PZPostgreSQLConnect): Integer;\nbegin\n  Result := POSTGRESQL_API.PQendcopy(Handle);\nend;\n\nfunction TZPostgreSQLBaseDriver.ExecuteFunction(\n  Handle: PZPostgreSQLConnect; fnid: Integer; result_buf,\n  result_len: PInteger; result_is_int: Integer; args: PZPostgreSQLArgBlock;\n  nargs: Integer): PZPostgreSQLResult;\nbegin\n  Result := POSTGRESQL_API.PQfn(Handle, fnid, result_buf,\n    result_len, result_is_int, PPQArgBlock(args), nargs);\nend;\n\nfunction TZPostgreSQLBaseDriver.ExecuteQuery(\n  Handle: PZPostgreSQLConnect; Query: PAnsiChar): PZPostgreSQLResult;\nbegin\n  Result := POSTGRESQL_API.PQexec(Handle, Query);\nend;\n\nfunction TZPostgreSQLBaseDriver.ExecParams(Handle: PPGconn; command: PAnsichar;\n    nParams: Integer; paramTypes: TPQparamTypes; paramValues: TPQparamValues;\n    paramLengths: TPQparamLengths; paramFormats: TPQparamFormats;\n    resultFormat: Integer): PPGresult;\nbegin\n  if Assigned(POSTGRESQL_API.PQexecParams) then\n    Result := POSTGRESQL_API.PQexecParams(Handle, command, nParams, paramtypes,\n      paramValues, paramLengths, paramFormats, resultFormat)\n  else\n    Result := nil;\nend;\n\nfunction TZPostgreSQLBaseDriver.Prepare(Handle: PPGconn; stmtName: PAnsichar;\n    query: PAnsiChar; nParams: Integer; paramTypes: TPQparamTypes): PPGresult;\nbegin\n  if Assigned(POSTGRESQL_API.PQprepare) then\n    Result := POSTGRESQL_API.PQprepare(Handle, stmtName, query, nParams, paramTypes)\n  else\n    Result := nil;\nend;\n\nfunction TZPostgreSQLBaseDriver.ExecPrepared(Handle: PPGconn; stmtName: PAnsichar;\n    nParams: Integer; paramValues: TPQparamValues; paramLengths: TPQparamLengths;\n    paramFormats: TPQparamFormats; resultFormat: Integer): PPGresult;\nbegin\n  if Assigned(POSTGRESQL_API.PQexecPrepared) then\n    Result := POSTGRESQL_API.PQexecPrepared(Handle, stmtName, nParams,\n      paramValues, paramLengths, paramFormats, resultFormat)\n  else\n    Result := nil;\nend;\n\nfunction TZPostgreSQLBaseDriver.SendQuery(Handle: PZPostgreSQLConnect; Query: PAnsiChar): Integer;\nbegin\n  Result := POSTGRESQL_API.PQsendQuery(Handle, Query);\nend;\n\nfunction TZPostgreSQLBaseDriver.SendQueryParams(Handle: PPGconn; command: PAnsichar;\n    nParams: Integer; paramTypes: TPQparamTypes; paramValues: TPQparamValues;\n    paramLengths: TPQparamLengths; paramFormats: TPQparamFormats;\n    resultFormat: Integer): Integer;\nbegin\n  if Assigned(POSTGRESQL_API.PQsendQueryParams) then\n    Result := POSTGRESQL_API.PQsendQueryParams(Handle, command, nParams,\n      paramTypes, paramValues, paramLengths, paramFormats, resultFormat)\n  else\n    Result := -1;\nend;\n\nfunction TZPostgreSQLBaseDriver.SendPrepare(Handle: PPGconn; stmtName: PAnsichar;\n    query: PAnsiChar; nParams: Integer; paramTypes: TPQparamTypes): Integer;\nbegin\n  if Assigned(POSTGRESQL_API.PQsendPrepare) then\n    Result := POSTGRESQL_API.PQsendPrepare(Handle, stmtName, query, nParams,\n      paramTypes)\n  else\n    Result := -1;\nend;\n\nfunction TZPostgreSQLBaseDriver.SendQueryPrepared(Handle: PPGconn; stmtName: PAnsichar;\n     nParams: Integer; paramValues: TPQparamValues;\n     paramLengths: TPQparamLengths; paramFormats: TPQparamFormats;\n     resultFormat: Integer): Integer;\nbegin\n  if Assigned(POSTGRESQL_API.PQsendQueryPrepared) then\n    Result := POSTGRESQL_API.PQsendQueryPrepared(Handle, stmtName, nParams,\n      paramValues, paramLengths, paramFormats, resultFormat)\n  else\n    Result := -1;\nend;\n\nfunction TZPostgreSQLBaseDriver.GetResult(Handle: PZPostgreSQLConnect): PZPostgreSQLResult;\nbegin\n  Result := POSTGRESQL_API.PQgetResult(Handle);\nend;\n\nfunction TZPostgreSQLBaseDriver.DescribePrepared(Handle: PPGconn;\n  const stmt: PAnsiChar): PPGresult;\nbegin\n  if Assigned(POSTGRESQL_API.PQdescribePrepared) then\n    Result := POSTGRESQL_API.PQdescribePrepared(Handle, stmt)\n  else\n    Result := nil;\nend;\n\nfunction TZPostgreSQLBaseDriver.DescribePortal(Handle: PPGconn;\n  const portal: PAnsiChar): PPGresult;\nbegin\n  if Assigned(POSTGRESQL_API.PQdescribePortal) then\n    Result := POSTGRESQL_API.PQdescribePortal(Handle, portal)\n  else\n    Result := nil;\nend;\n\nfunction TZPostgreSQLBaseDriver.SendDescribePrepared(Handle: PPGconn;\n  const stmt: PAnsiChar): Integer;\nbegin\n  if Assigned(POSTGRESQL_API.PQsendDescribePrepared) then\n    Result := POSTGRESQL_API.PQsendDescribePrepared(Handle, stmt)\n  else\n    Result := -1;\nend;\n\nfunction TZPostgreSQLBaseDriver.SendDescribePortal(Handle: PPGconn;\n  const portal: PAnsiChar): Integer;\nbegin\n  if Assigned(POSTGRESQL_API.PQsendDescribePortal) then\n    Result := POSTGRESQL_API.PQsendDescribePortal(Handle, portal)\n  else\n    Result := -1;\nend;\n\nfunction TZPostgreSQLBaseDriver.ExportLargeObject(\n  Handle: PZPostgreSQLConnect; ObjId: Oid; FileName: PAnsiChar): Integer;\nbegin\n  Result := POSTGRESQL_API.lo_export(Handle, ObjId, FileName);\nend;\n\nprocedure TZPostgreSQLBaseDriver.Finish(Handle: PZPostgreSQLConnect);\nbegin\n  POSTGRESQL_API.PQfinish(Handle);\nend;\n\nprocedure TZPostgreSQLBaseDriver.FreeNotify(Handle: PZPostgreSQLNotify);\nbegin\n  POSTGRESQL_API.PQfreeNotify(PPGnotify(Handle));\nend;\n\nfunction TZPostgreSQLBaseDriver.GetBackendPID(\n  Handle: PZPostgreSQLConnect): Integer;\nbegin\n  Result := POSTGRESQL_API.PQbackendPID(Handle);\nend;\n\nfunction TZPostgreSQLBaseDriver.GetBinaryTuples(\n  Res: PZPostgreSQLResult): Integer;\nbegin\n  Result := POSTGRESQL_API.PQbinaryTuples(Res);\nend;\n\nfunction TZPostgreSQLBaseDriver.GetCommandStatus(\n  Res: PZPostgreSQLResult): PAnsiChar;\nbegin\n  Result := POSTGRESQL_API.PQcmdStatus(Res);\nend;\n\nfunction TZPostgreSQLBaseDriver.GetCommandTuples(\n  Res: PZPostgreSQLResult): PAnsiChar;\nbegin\n  Result := POSTGRESQL_API.PQcmdTuples(Res);\nend;\n\nfunction TZPostgreSQLBaseDriver.GetConnectDefaults:\n  PZPostgreSQLConnectInfoOption;\nbegin\n  Result := PZPostgreSQLConnectInfoOption(POSTGRESQL_API.PQconndefaults);\nend;\n\nfunction TZPostgreSQLBaseDriver.GetDatabase(\n  Handle: PZPostgreSQLConnect): PAnsiChar;\nbegin\n  Result := POSTGRESQL_API.PQdb(Handle);\nend;\n\nfunction TZPostgreSQLBaseDriver.GetErrorMessage(\n  Handle: PZPostgreSQLConnect): PAnsiChar;\nbegin\n  Result := POSTGRESQL_API.PQerrorMessage(Handle);\nend;\n\nfunction TZPostgreSQLBaseDriver.GetFieldCount(\n  Res: PZPostgreSQLResult): Integer;\nbegin\n  Result := POSTGRESQL_API.PQnfields(Res);\nend;\n\nfunction TZPostgreSQLBaseDriver.GetFieldMode(Res: PZPostgreSQLResult;\n  FieldNum: Integer): Integer;\nbegin\n  Result := POSTGRESQL_API.PQfmod(Res, FieldNum);\nend;\n\nfunction TZPostgreSQLBaseDriver.GetFieldName(Res: PZPostgreSQLResult;\n  FieldNum: Integer): PAnsiChar;\nbegin\n  Result := POSTGRESQL_API.PQfname(Res, FieldNum);\nend;\n\nfunction TZPostgreSQLBaseDriver.GetFieldNumber(\n  Res: PZPostgreSQLResult; FieldName: PAnsiChar): Integer;\nbegin\n  Result := POSTGRESQL_API.PQfnumber(Res, FieldName);\nend;\n\nfunction TZPostgreSQLBaseDriver.GetFieldTableOID(Res: PZPostgreSQLResult; FieldNum: Integer) : Oid;\nbegin\n  Result := POSTGRESQL_API.PQftable(Res, FieldNum);\nend;\n\nfunction TZPostgreSQLBaseDriver.GetFieldTableColIdx(Res: PZPostgreSQLResult; FieldNum: Integer) : Integer;\nbegin\n  Result := POSTGRESQL_API.PQftablecol(Res, FieldNum);\nend;\n\nfunction TZPostgreSQLBaseDriver.GetFieldSize(Res: PZPostgreSQLResult;\n  FieldNum: Integer): Integer;\nbegin\n  Result := POSTGRESQL_API.PQfsize(Res, FieldNum);\nend;\n\nfunction TZPostgreSQLBaseDriver.GetFieldType(Res: PZPostgreSQLResult;\n  FieldNum: Integer): Oid;\nbegin\n  Result := POSTGRESQL_API.PQftype(Res, FieldNum);\nend;\n\nfunction TZPostgreSQLBaseDriver.GetHost(\n  Handle: PZPostgreSQLConnect): PAnsiChar;\nbegin\n  Result := POSTGRESQL_API.PQhost(Handle);\nend;\n\nfunction TZPostgreSQLBaseDriver.GetIsNull(Res: PZPostgreSQLResult;\n  TupNum, FieldNum: Integer): Integer;\nbegin\n  Result := POSTGRESQL_API.PQgetisnull(Res, TupNum, FieldNum);\nend;\n\nfunction TZPostgreSQLBaseDriver.GetLength(Res: PZPostgreSQLResult;\n  TupNum, FieldNum: Integer): Integer;\nbegin\n  Result := POSTGRESQL_API.PQgetlength(Res, TupNum, FieldNum);\nend;\n\nfunction TZPostgreSQLBaseDriver.GetLine(Handle: PZPostgreSQLConnect;\n  Buffer: PAnsiChar; Length: Integer): Integer;\nbegin\n  Result := POSTGRESQL_API.PQgetline(Handle, Buffer, Length);\nend;\n\nfunction TZPostgreSQLBaseDriver.GetLineAsync(\n  Handle: PZPostgreSQLConnect; Buffer: PAnsiChar; Length: Integer): Integer;\nbegin\n  Result := POSTGRESQL_API.PQgetlineAsync(Handle, Buffer, Length);\nend;\n\nfunction TZPostgreSQLBaseDriver.GetOidStatus(\n  Res: PZPostgreSQLResult): PAnsiChar;\nbegin\n  Result := POSTGRESQL_API.PQoidStatus(Res);\nend;\n\nfunction TZPostgreSQLBaseDriver.GetOidValue(\n  Res: PZPostgreSQLResult): Oid;\nbegin\n  Result := POSTGRESQL_API.PQoidValue(Res);\nend;\n\nfunction TZPostgreSQLBaseDriver.GetOptions(\n  Handle: PZPostgreSQLConnect): PAnsiChar;\nbegin\n  Result := POSTGRESQL_API.PQoptions(Handle);\nend;\n\nfunction TZPostgreSQLBaseDriver.GetPassword(\n  Handle: PZPostgreSQLConnect): PAnsiChar;\nbegin\n  Result := POSTGRESQL_API.PQpass(Handle);\nend;\n\nfunction TZPostgreSQLBaseDriver.GetPort(\n  Handle: PZPostgreSQLConnect): PAnsiChar;\nbegin\n  Result := POSTGRESQL_API.PQport(Handle);\nend;\n\nfunction TZPostgreSQLBaseDriver.GetResultErrorField(Res: PZPostgreSQLResult;  FieldCode: TZPostgreSQLFieldCode): PAnsiChar;\nbegin\n  if Assigned(POSTGRESQL_API.PQresultErrorField) then\n    Result := POSTGRESQL_API.PQresultErrorField(Res, ord(FieldCode))\n  else\n    Result := '';\nend;\n\n\nfunction TZPostgreSQLBaseDriver.GetResultErrorMessage(\n  Res: PZPostgreSQLResult): PAnsiChar;\nbegin\n  Result := POSTGRESQL_API.PQresultErrorMessage(Res);\nend;\n\nfunction TZPostgreSQLBaseDriver.GetResultStatus(\n  Res: PZPostgreSQLResult): TZPostgreSQLExecStatusType;\nbegin\n  Result := TZPostgreSQLExecStatusType(POSTGRESQL_API.PQresultStatus(Res));\nend;\n\nfunction TZPostgreSQLBaseDriver.GetRowCount(\n  Res: PZPostgreSQLResult): Integer;\nbegin\n  Result := POSTGRESQL_API.PQntuples(Res);\nend;\n\nfunction TZPostgreSQLBaseDriver.GetSocket(\n  Handle: PZPostgreSQLConnect): Integer;\nbegin\n  Result := POSTGRESQL_API.PQsocket(Handle);\nend;\n\nfunction TZPostgreSQLBaseDriver.GetStandardConformingStrings: Boolean;\nbegin\n  Result := False;\nend;\n\nfunction TZPostgreSQLBaseDriver.GetStatus(\n  Handle: PZPostgreSQLConnect): TZPostgreSQLConnectStatusType;\nbegin\n  Result := TZPostgreSQLConnectStatusType(POSTGRESQL_API.PQstatus(Handle));\nend;\n\nfunction TZPostgreSQLBaseDriver.GetClientEncoding(Handle: PPGconn): Integer; //EgonHugeist\nbegin\n  Result := POSTGRESQL_API.PQclientEncoding(Handle);\nend;\n\nfunction TZPostgreSQLBaseDriver.GetTTY(\n  Handle: PZPostgreSQLConnect): PAnsiChar;\nbegin\n  Result := POSTGRESQL_API.PQtty(Handle);\nend;\n\nfunction TZPostgreSQLBaseDriver.GetUser(\n  Handle: PZPostgreSQLConnect): PAnsiChar;\nbegin\n  Result := POSTGRESQL_API.PQuser(Handle);\nend;\n\nfunction TZPostgreSQLBaseDriver.GetValue(Res: PZPostgreSQLResult;\n  TupNum, FieldNum: Integer): PAnsiChar;\nbegin\n  Result := POSTGRESQL_API.PQgetvalue(Res, TupNum, FieldNum);\nend;\n\nfunction TZPostgreSQLBaseDriver.ImportLargeObject(\n  Handle: PZPostgreSQLConnect; FileName: PAnsiChar): Oid;\nbegin\n  Result := POSTGRESQL_API.lo_import(Handle, FileName);\nend;\n\nfunction TZPostgreSQLBaseDriver.IsBusy(\n  Handle: PZPostgreSQLConnect): Integer;\nbegin\n  Result := POSTGRESQL_API.PQisBusy(Handle);\nend;\n\nfunction TZPostgreSQLBaseDriver.MakeEmptyResult(\n  Handle: PZPostgreSQLConnect;\n  Status: TZPostgreSQLExecStatusType): PZPostgreSQLResult;\nbegin\n  Result := POSTGRESQL_API.PQmakeEmptyPGresult(Handle,\n    TZPostgreSQLExecStatusType(Status));\nend;\n\nfunction TZPostgreSQLBaseDriver.Notifies(\n  Handle: PZPostgreSQLConnect): PZPostgreSQLNotify;\nbegin\n  Result := PZPostgreSQLNotify(POSTGRESQL_API.PQnotifies(Handle));\nend;\n\nfunction TZPostgreSQLBaseDriver.OpenLargeObject(\n  Handle: PZPostgreSQLConnect; ObjId: Oid; Mode: Integer): Integer;\nbegin\n  Result := POSTGRESQL_API.lo_open(Handle, ObjId, Mode);\nend;\n\nfunction TZPostgreSQLBaseDriver.PutBytes(Handle: PZPostgreSQLConnect;\n  Buffer: PAnsiChar; Length: Integer): Integer;\nbegin\n  Result := POSTGRESQL_API.PQputnbytes(Handle, Buffer, Length);\nend;\n\nfunction TZPostgreSQLBaseDriver.PutLine(Handle: PZPostgreSQLConnect;\n  Buffer: PAnsiChar): Integer;\nbegin\n  Result := POSTGRESQL_API.PQputline(Handle, Buffer);\nend;\n\nfunction TZPostgreSQLBaseDriver.ReadLargeObject(\n  Handle: PZPostgreSQLConnect; Fd: Integer; Buffer: PAnsiChar;\n  Length: Integer): Integer;\nbegin\n  Result := POSTGRESQL_API.lo_read(Handle, Fd, Buffer, Length);\nend;\n\nfunction TZPostgreSQLBaseDriver.RequestCancel(\n  Handle: PZPostgreSQLConnect): Integer;\nbegin\n  Result := POSTGRESQL_API.PQrequestCancel(Handle);\nend;\n\nprocedure TZPostgreSQLBaseDriver.Reset(Handle: PZPostgreSQLConnect);\nbegin\n  POSTGRESQL_API.PQreset(Handle);\nend;\n\nfunction TZPostgreSQLBaseDriver.SeekLargeObject(\n  Handle: PZPostgreSQLConnect; Fd, Offset, Whence: Integer): Integer;\nbegin\n  Result := POSTGRESQL_API.lo_lseek(Handle, Fd, Offset, Whence);\nend;\n\nfunction TZPostgreSQLBaseDriver.SetDatabaseLogin(Host, Port, Options,\n  TTY, Db, User, Passwd: PAnsiChar): PZPostgreSQLConnect;\nbegin\n  Result := POSTGRESQL_API.PQsetdbLogin(Host, Port, Options, TTY, Db,\n    User, Passwd);\nend;\n\nprocedure TZPostgreSQLBaseDriver.SetNoticeProcessor(\n  Handle: PZPostgreSQLConnect; Proc: TZPostgreSQLNoticeProcessor;\n  Arg: Pointer);\nbegin\n  POSTGRESQL_API.PQsetNoticeProcessor(Handle, Proc, Arg);\nend;\n\nfunction TZPostgreSQLBaseDriver.TellLargeObject(\n  Handle: PZPostgreSQLConnect; Fd: Integer): Integer;\nbegin\n  Result := POSTGRESQL_API.lo_tell(Handle, Fd);\nend;\n\nprocedure TZPostgreSQLBaseDriver.Trace(Handle: PZPostgreSQLConnect;\n  DebugPort: Pointer);\nbegin\n  POSTGRESQL_API.PQtrace(Handle, DebugPort);\nend;\n\nfunction TZPostgreSQLBaseDriver.UnlinkLargeObject(\n  Handle: PZPostgreSQLConnect; ObjId: Oid): Integer;\nbegin\n  Result := POSTGRESQL_API.lo_unlink(Handle, ObjId);\nend;\n\nprocedure TZPostgreSQLBaseDriver.Untrace(Handle: PZPostgreSQLConnect);\nbegin\n  POSTGRESQL_API.PQuntrace(Handle);\nend;\n\nfunction TZPostgreSQLBaseDriver.WriteLargeObject(\n  Handle: PZPostgreSQLConnect; Fd: Integer; Buffer: PAnsiChar;\n  Length: Integer): Integer;\nbegin\n  Result := POSTGRESQL_API.lo_write(Handle, Fd, Buffer, Length);\nend;\n\nfunction TZPostgreSQLBaseDriver.GetPlainFunc():PAPI;\nbegin\n  result:= @POSTGRESQL_API;\nend;\n\nfunction TZPostgreSQLBaseDriver.EscapeString(Handle: Pointer; const Value: RawByteString;\n  ConSettings: PZConSettings; WasEncoded: Boolean = False): RawByteString;\nvar\n  ResLen: NativeUInt;\n  Temp: PAnsiChar;\n  SourceTemp: RawByteString;\n  IError: Integer;\nbegin\n  if ( Assigned(POSTGRESQL_API.PQescapeStringConn) or\n       Assigned(POSTGRESQL_API.PQescapeString) ) and ( Value <> '' )then\n  begin\n    IError := 0;\n    {$IFDEF UNICODE}\n    SourceTemp := Value;\n    {$ELSE}\n    if WasEncoded then\n      SourceTemp := Value\n    else\n      SourceTemp := ZPlainString(Value, ConSettings); //check encoding too\n    {$ENDIF}\n    GetMem(Temp, Length(SourceTemp)*2);\n    if Assigned(POSTGRESQL_API.PQescapeStringConn) then\n      ResLen := POSTGRESQL_API.PQescapeStringConn(Handle, Temp,\n\n\n      PAnsiChar(SourceTemp), {$IFDEF WITH_STRLEN_DEPRECATED}AnsiStrings.{$ENDIF}StrLen(PAnsiChar(SourceTemp)), @IError)\n    else\n      ResLen := POSTGRESQL_API.PQescapeString(Temp, PAnsiChar(SourceTemp),\n       {$IFDEF WITH_STRLEN_DEPRECATED}AnsiStrings.{$ENDIF}StrLen(PAnsiChar(SourceTemp)));\n    if not (IError = 0) then\n      raise Exception.Create('Wrong escape behavior!');\n    SetLength(Result, ResLen);\n    Move(Temp^, PAnsiChar(Result)^, ResLen);\n    FreeMem(Temp);\n  end\n  else\n    Result := Value;\n  Result := #39+Result+#39;\nend;\n\n{ TZPostgreSQL7PlainDriver }\n\nfunction TZPostgreSQL7PlainDriver.Clone: IZPlainDriver;\nbegin\n  Result := TZPostgreSQL7PlainDriver.Create;\nend;\n\nconstructor TZPostgreSQL7PlainDriver.Create;\nbegin\n  inherited Create;\n  {$IFNDEF UNIX}\n    FLoader.AddLocation(WINDOWS_DLL7_LOCATION);\n  {$ENDIF}\nend;\n\nfunction TZPostgreSQL7PlainDriver.GetProtocol: string;\nbegin\n  Result := 'postgresql-7';\nend;\n\nfunction TZPostgreSQL7PlainDriver.GetDescription: string;\nbegin\n  Result := 'Native Plain Driver for PostgreSQL 7.x';\nend;\n\n{ TZPostgreSQL8PlainDriver }\nfunction TZPostgreSQL8PlainDriver.Clone: IZPlainDriver;\nbegin\n  Result := TZPostgreSQL8PlainDriver.Create;\nend;\n\nfunction TZPostgreSQL8PlainDriver.GetUnicodeCodePageName: String;\nbegin\n  Result := 'UTF8';\nend;\n\nprocedure TZPostgreSQL8PlainDriver.LoadCodePages;\nbegin\n  inherited LoadCodePages;\n  { Version 8.1 }\n  {MultiByte}\n  ResetCodePage(Ord(csUNICODE_PODBC), 'UTF8', Ord(csUTF8), ceUTF8, zCP_UTF8, '', 4); { Unicode, 8-bit \tall }\n  AddCodePage('BIG5', Ord(csBIG5), ceAnsi, zCP_Big5, '', 2); { Big Five \tTraditional Chinese }\n  AddCodePage('GB18030', Ord(csGB18030), ceAnsi, zCP_GB18030, '', 2); { National Standard \tChinese }\n  AddCodePage('GBK', Ord(csGBK), ceAnsi, zCP_GB2312, '', 2); { Extended National Standard \tSimplified Chinese }\n  AddCodePage('SJIS', Ord(csSJIS), ceAnsi, zCP_SHIFTJS, '', 2); { Shift JIS \tJapanese }\n  AddCodePage('UHC', Ord(csUHC), ceAnsi, zCP_EUCKR, '', 2); { Unified Hangul Code \tKorean }\n  {SingleByte}\n  ResetCodePage(Ord(csALT), 'WIN866', Ord(csWIN866), ceAnsi, zCP_DOS866); { Windows CP866 \tCyrillic } //No longer in use\n  AddCodePage('WIN874', Ord(csWIN874), ceAnsi, zCP_DOS874); { Windows CP874 \tThai }\n  AddCodePage('WIN1250', Ord(csWIN1250), ceAnsi, zCP_WIN1250); { Windows CP1250 \tCentral European }\n  ResetCodePage(Ord(csWIN), 'WIN1251', Ord(csWIN1251), ceAnsi, zCP_WIN1251); { Windows CP1251 \tCyrillic } //No longer in use\n  AddCodePage('WIN1252', Ord(csWIN1252), ceAnsi, zCP_WIN1252); { Windows CP1252 \tWestern European }\n  ResetCodePage(Ord(csTCVN), 'WIN1258', Ord(csWIN1258),ceAnsi, zCP_WIN1258); { Windows CP1258 \tVietnamese } //No longer in use\n\n  { Version 8.3 }\n  {MultiByte}\n  AddCodePage('EUC_JIS_2004', Ord(csEUC_JIS_2004), ceAnsi, $ffff, '', 3); { Extended UNIX Code-JP, JIS X 0213 \tJapanese }\n  AddCodePage('SHIFT_JIS_2004', Ord(csSHIFT_JIS_2004), ceAnsi, zCP_SHIFTJS, '', 3); { Shift JIS, JIS X 0213 \tJapanese }\n  {SingleChar}\n  AddCodePage('WIN1253', Ord(csWIN1253), ceAnsi, zCP_WIN1253); { Windows CP1253  Greek }\n  AddCodePage('WIN1254', Ord(csWIN1254), ceAnsi, zCP_WIN1254); { Windows CP1254 \tTurkish }\n  AddCodePage('WIN1255', Ord(csWIN1255), ceAnsi, zCP_WIN1255); { Windows CP1255 \tHebrew }\n  AddCodePage('WIN1257', Ord(csWIN1257), ceAnsi, zCP_WIN1257); { Windows CP1257 \tBaltic }\n\n  { Version 8.4 }\n  {SingleChar}\n  AddCodePage('KOI8U', Ord(csKOI8U), ceAnsi, zCP_KOI8U); { \tKOI8-U \tCyrillic (Ukrainian) }\nend;\n\nconstructor TZPostgreSQL8PlainDriver.Create;\nbegin\n  inherited Create;\n  {$IFNDEF UNIX}\n    FLoader.AddLocation(WINDOWS_DLL8_LOCATION);\n  {$ELSE}\n    FLoader.AddLocation(LINUX_DLL82_LOCATION);\n    FLoader.AddLocation(LINUX_DLL8_LOCATION);\n  {$ENDIF}\nend;\n\nfunction TZPostgreSQL8PlainDriver.GetProtocol: string;\nbegin\n  Result := 'postgresql-8';\nend;\n\nfunction TZPostgreSQL8PlainDriver.GetDescription: string;\nbegin\n  Result := 'Native Plain Driver for PostgreSQL 8.x';\nend;\n\n{ TZPostgreSQL9PlainDriver }\nfunction TZPostgreSQL9PlainDriver.Clone: IZPlainDriver;\nbegin\n  Result := TZPostgreSQL9PlainDriver.Create;\nend;\n\nprocedure TZPostgreSQL9PlainDriver.LoadCodePages;\nbegin\n  inherited LoadCodePages;\n  ResetCodePage(Ord(csKOI8), 'KOI8R', Ord(csKOI8R)); { KOI8-R \tCyrillic (Russian) } //No longer in use\nend;\n\nconstructor TZPostgreSQL9PlainDriver.Create;\nbegin\n  inherited Create;\n  Self.FLoader.ClearLocations;\n  {$IFNDEF STRICT_DLL_LOADING}\n    {$IFNDEF UNIX}\n      FLoader.AddLocation(WINDOWS_DLL_LOCATION);\n    {$ELSE}\n      FLoader.AddLocation(LINUX_DLL_LOCATION);\n    {$ENDIF}\n  {$ENDIF}\nend;\n\nfunction TZPostgreSQL9PlainDriver.GetProtocol: string;\nbegin\n  Result := 'postgresql-9';\nend;\n\nfunction TZPostgreSQL9PlainDriver.GetDescription: string;\nbegin\n  Result := 'Native Plain Driver for PostgreSQL 9.x';\nend;\n\nfunction TZPostgreSQL9PlainDriver.GetStandardConformingStrings: Boolean;\nbegin\n  Result := True;\nend;\n\nend.\n\n"
  },
  {
    "path": "lib/zeosdbo/src/plain/ZPlainSqLiteDriver.pas",
    "content": "{*********************************************************}\n{                                                         }\n{                 Zeos Database Objects                   }\n{             Native Plain Drivers for SQLite             }\n{                                                         }\n{         Originally written by Sergey Seroukhov          }\n{                                                         }\n{*********************************************************}\n\n{@********************************************************}\n{    Copyright (c) 1999-2012 Zeos Development Group       }\n{                                                         }\n{ License Agreement:                                      }\n{                                                         }\n{ This library is distributed in the hope that it will be }\n{ useful, but WITHOUT ANY WARRANTY; without even the      }\n{ implied warranty of MERCHANTABILITY or FITNESS FOR      }\n{ A PARTICULAR PURPOSE.  See the GNU Lesser General       }\n{ Public License for more details.                        }\n{                                                         }\n{ The source code of the ZEOS Libraries and packages are  }\n{ distributed under the Library GNU General Public        }\n{ License (see the file COPYING / COPYING.ZEOS)           }\n{ with the following  modification:                       }\n{ As a special exception, the copyright holders of this   }\n{ library give you permission to link this library with   }\n{ independent modules to produce an executable,           }\n{ regardless of the license terms of these independent    }\n{ modules, and to copy and distribute the resulting       }\n{ executable under terms of your choice, provided that    }\n{ you also meet, for each linked independent module,      }\n{ the terms and conditions of the license of that module. }\n{ An independent module is a module which is not derived  }\n{ from or based on this library. If you modify this       }\n{ library, you may extend this exception to your version  }\n{ of the library, but you are not obligated to do so.     }\n{ If you do not wish to do so, delete this exception      }\n{ statement from your version.                            }\n{                                                         }\n{                                                         }\n{ The project web site is located on:                     }\n{   http://zeos.firmos.at  (FORUM)                        }\n{   http://sourceforge.net/p/zeoslib/tickets/ (BUGTRACKER)}\n{   svn://svn.code.sf.net/p/zeoslib/code-0/trunk (SVN)    }\n{                                                         }\n{   http://www.sourceforge.net/projects/zeoslib.          }\n{                                                         }\n{                                                         }\n{                                 Zeos Development Group. }\n{********************************************************@}\n\nunit ZPlainSqLiteDriver;\n\ninterface\n\n{$I ZPlain.inc}\n\nuses SysUtils, Classes, {$IFDEF MSEgui}mclasses,{$ENDIF} Types,\n  ZClasses, ZCompatibility, ZPlainDriver;\n\nconst\n  WINDOWS_DLL_LOCATION = 'sqlite.dll';\n  WINDOWS_DLL3_LOCATION = 'sqlite3.dll';\n  LINUX_DLL_LOCATION = 'libsqlite'+SharedSuffix;\n  LINUX_DLL3_LOCATION = 'libsqlite3'+SharedSuffix;\n\n  SQLITE_ISO8859   = 1;\n  MASTER_NAME      = 'sqlite_master';\n  TEMP_MASTER_NAME = 'sqlite_temp_master';\n\n  { Return values for sqlite_exec() and sqlite_step() }\n  SQLITE_OK           = 0;   // Successful result\n  SQLITE_ERROR        = 1;   // SQL error or missing database\n  SQLITE_INTERNAL     = 2;   // An internal logic error in SQLite\n  SQLITE_PERM         = 3;   // Access permission denied\n  SQLITE_ABORT        = 4;   // Callback routine requested an abort\n  SQLITE_BUSY         = 5;   // The database file is locked\n  SQLITE_LOCKED       = 6;   // A table in the database is locked\n  SQLITE_NOMEM        = 7;   // A malloc() failed\n  SQLITE_READONLY     = 8;   // Attempt to write a readonly database\n  _SQLITE_INTERRUPT    = 9;   // Operation terminated by sqlite_interrupt()\n  SQLITE_IOERR        = 10;  // Some kind of disk I/O error occurred\n  SQLITE_CORRUPT      = 11;  // The database disk image is malformed\n  SQLITE_NOTFOUND     = 12;  // (Internal Only) Table or record not found\n  SQLITE_FULL         = 13;  // Insertion failed because database is full\n  SQLITE_CANTOPEN     = 14;  // Unable to open the database file\n  SQLITE_PROTOCOL     = 15;  // Database lock protocol error\n  SQLITE_EMPTY        = 16;  // (Internal Only) Database table is empty\n  SQLITE_SCHEMA       = 17;  // The database schema changed\n  SQLITE_TOOBIG       = 18;  // Too much data for one row of a table\n  SQLITE_CONSTRAINT   = 19;  // Abort due to contraint violation\n  SQLITE_MISMATCH     = 20;  // Data type mismatch\n  SQLITE_MISUSE       = 21;  // Library used incorrectly\n  SQLITE_NOLFS        = 22;  // Uses OS features not supported on host\n  SQLITE_AUTH         = 23;  // Authorization denied\n  SQLITE_FORMAT       = 24;  // Auxiliary database format error\n  SQLITE_RANGE        = 25;  // 2nd parameter to sqlite_bind out of range\n  SQLITE_NOTADB       = 26;  // File opened that is not a database file\n  SQLITE_ROW          = 100;  // sqlite_step() has another row ready\n  SQLITE_DONE         = 101;  // sqlite_step() has finished executing\n\n  SQLITE_NUMERIC      = -1;\n  SQLITE_TEXT         = -2;\n  SQLITE_ARGS         = -3;\n\n  {\n    The second parameter to the access authorization function above will\n    be one of the values below.  These values signify what kind of operation\n    is to be authorized.  The 3rd and 4th parameters to the authorization\n    function will be parameters or NULL depending on which of the following\n    codes is used as the second parameter.  The 5th parameter is the name\n    of the database (\"main\", \"temp\", etc.) if applicable.  The 6th parameter\n    is the name of the inner-most trigger or view that is responsible for\n    the access attempt or NULL if this access attempt is directly from\n    input SQL code.\n\n                                             Arg-3           Arg-4\n  }\n  SQLITE_COPY                  = 0;  // Table Name      File Name\n  SQLITE_CREATE_INDEX          = 1;  // Index Name      Table Name\n  SQLITE_CREATE_TABLE          = 2;  // Table Name      NULL\n  SQLITE_CREATE_TEMP_INDEX     = 3;  // Index Name      Table Name\n  SQLITE_CREATE_TEMP_TABLE     = 4;  // Table Name      NULL\n  SQLITE_CREATE_TEMP_TRIGGER   = 5;  // Trigger Name    Table Name\n  SQLITE_CREATE_TEMP_VIEW      = 6;  // View Name       NULL\n  SQLITE_CREATE_TRIGGER        = 7;  // Trigger Name    Table Name\n  SQLITE_CREATE_VIEW           = 8;  // View Name       NULL\n  SQLITE_DELETE                = 9;  // Table Name      NULL\n  SQLITE_DROP_INDEX            = 10; // Index Name      Table Name\n  SQLITE_DROP_TABLE            = 11; // Table Name      NULL\n  SQLITE_DROP_TEMP_INDEX       = 12; // Index Name      Table Name\n  SQLITE_DROP_TEMP_TABLE       = 13; // Table Name      NULL\n  SQLITE_DROP_TEMP_TRIGGER     = 14; // Trigger Name    Table Name\n  SQLITE_DROP_TEMP_VIEW        = 15; // View Name       NULL\n  SQLITE_DROP_TRIGGER          = 16; // Trigger Name    Table Name\n  SQLITE_DROP_VIEW             = 17; // View Name       NULL\n  SQLITE_INSERT                = 18; // Table Name      NULL\n  SQLITE_PRAGMA                = 19; // Pragma Name     1st arg or NULL\n  SQLITE_READ                  = 20; // Table Name      Column Name\n  SQLITE_SELECT                = 21; // NULL            NULL\n  SQLITE_TRANSACTION           = 22; // NULL            NULL\n  SQLITE_UPDATE                = 23; // Table Name      Column Name\n  SQLITE_ATTACH                = 24; // Filename        NULL\n  SQLITE_DETACH                = 25; // Database Name   NULL\n\n  { The return value of the authorization function should be one of the\n    following constants: }\n  SQLITE_DENY    = 1;   // Abort the SQL statement with an error\n  SQLITE_IGNORE = 2;   // Don't allow access, but don't generate an error\n\n  SQLITE_INTEGER = 1;\n  SQLITE_FLOAT   = 2;\n  SQLITE3_TEXT   = 3;\n  SQLITE_BLOB    = 4;\n  SQLITE_NULL    = 5;\n\ntype\n  Psqlite = Pointer;\n  Psqlite_func = Pointer;\n  Psqlite_vm = Pointer;\n  Psqlite3_stmt = Pointer;\n  Psqlite3_value = Pointer;\n\n  Tsqlite3_destructor_type = procedure(user: pointer); cdecl;\n\n\n  SQLITE_STATIC = procedure(User: Pointer = Nil); cdecl;\n  SQLITE_TRANSIENT = procedure(User: pointer = Pointer(-1)); cdecl;\n\ntype\n{ ************** Plain API Function types definition ************* }\n\n  Tsqlite_callback = function(p1: Pointer; p2: Integer; var p3: PAnsiChar;\n    var p4: PAnsiChar): Integer; cdecl;\n  Tsqlite_simple_callback = function(p1: Pointer): Integer; cdecl;\n  Tsqlite_simple_callback0 = function(p1: Pointer): Pointer; cdecl;\n  Tsqlite_busy_callback = function(p1: Pointer; const p2: PAnsiChar;\n    p3: Integer): Integer; cdecl;\n\n  Tsqlite_function_callback = procedure(p1: Psqlite_func; p2: Integer;\n    const p3: PPAnsiChar); cdecl;\n  Tsqlite_finalize_callback = procedure(p1: Psqlite_func); cdecl;\n  Tsqlite_auth_callback = function(p1: Pointer; p2: Integer; const p3: PAnsiChar;\n    const p4: PAnsiChar; const p5: PAnsiChar; const p6: PAnsiChar): Integer; cdecl;\n  Tsqlite_trace_callback = procedure(p1: Pointer; const p2: PAnsiChar); cdecl;\n\n  Tsqlite_open = function(const filename: PAnsiChar;var Qsqlite: Psqlite): Integer; cdecl;\n  Tsqlite_close = function(db: Psqlite): Integer; cdecl;\n\n  { prepared statment api}\n  Tsqlite3_prepare = function(\n    db: Psqlite;                // Database handle\n    const zSql: PAnsiChar;      // SQL statement, UTF-8 encoded\n    nBytes: Integer;            // Maximum length of zSql in bytes. -1 = null terminated\n    out ppStmt: Psqlite3_stmt;  // OUT: Statement handle\n    out pzTail: PPAnsichar      // OUT: Pointer to unused portion of zSql\n  ): Integer; cdecl;\n  Tsqlite3_prepare_v2 = function(\n    db: Psqlite;                // Database handle\n    const zSql: PAnsiChar;      // SQL statement, UTF-8 encoded\n    nBytes: Integer;            // Maximum length of zSql in bytes. -1 = null terminated\n    out ppStmt: Psqlite3_stmt;  // OUT: Statement handle\n    out pzTail: PPAnsichar      // OUT: Pointer to unused portion of zSql\n  ): Integer; cdecl;\n  Tsqlite3_prepare16 = function(\n    db: Psqlite;                // Database handle\n    const zSql: PWideChar;      // SQL statement, UTF-16 encoded\n    nBytes: Integer;            // Maximum length of zSql in bytes. -1 = null terminated\n    out ppStmt: Psqlite3_stmt;  // OUT: Statement handle\n    out pzTail: ZPPWideChar      // OUT: Pointer to unused portion of zSql\n  ): Integer; cdecl;\n  Tsqlite3_prepare16_v2 = function(\n    db: Psqlite;                // Database handle\n    const zSql: PWideChar;      // SQL statement, UTF-16 encoded\n    nBytes: Integer;            // Maximum length of zSql in bytes. -1 = null terminated\n    out ppStmt: Psqlite3_stmt;  // OUT: Statement handle\n    out pzTail: ZPPWideChar      // OUT: Pointer to unused portion of zSql\n  ): Integer; cdecl;\n\n  Tsqlite3_bind_parameter_count = function(pStmt: Psqlite3_stmt): Integer; cdecl;\n  Tsqlite3_bind_parameter_name = function(pStmt: Psqlite3_stmt; ParamIndex: Integer): PAnsichar; cdecl;\n  Tsqlite3_bind_parameter_index = function(pStmt: Psqlite3_stmt; const zName: PAnsiChar): Integer; cdecl;\n\n  Tsqlite3_clear_bindings = function(pStmt: Psqlite3_stmt): Integer; cdecl;\n  Tsqlite3_column_count = function(pStmt: Psqlite3_stmt): Integer; cdecl;\n  Tsqlite3_column_name = function(pStmt: Psqlite3_stmt; iCol: Integer): PAnsiChar; cdecl;\n  Tsqlite3_column_name16 = function(pStmt: Psqlite3_stmt; iCol: Integer): PWideChar; cdecl;\n\n  Tsqlite3_column_database_name = function(pStmt: Psqlite3_stmt; iCol: Integer): PAnsiChar; cdecl;\n  Tsqlite3_column_database_name16 = function(pStmt: Psqlite3_stmt; iCol: Integer): PWideChar; cdecl;\n  Tsqlite3_column_table_name = function(pStmt: Psqlite3_stmt; iCol: Integer): PAnsiChar; cdecl;\n  Tsqlite3_column_table_name16 = function(pStmt: Psqlite3_stmt; iCol: Integer): PWideChar; cdecl;\n  Tsqlite3_column_origin_name = function(pStmt: Psqlite3_stmt; iCol: Integer): PAnsiChar; cdecl;\n  Tsqlite3_column_origin_name16 = function(pStmt: Psqlite3_stmt; iCol: Integer): PWideChar; cdecl;\n\n  Tsqlite3_column_decltype = function(pStmt: Psqlite3_stmt; iCol: Integer): PAnsiChar; cdecl;\n  Tsqlite3_column_decltype16 = function(pStmt: Psqlite3_stmt; iCol: Integer): PWideChar; cdecl;\n\n  Tsqlite3_step = function(pStmt: Psqlite3_stmt): Integer; cdecl;\n  Tsqlite3_data_count = function (pStmt: Psqlite3_stmt): Integer; cdecl;\n\n  Tsqlite3_bind_blob = function(pStmt: Psqlite3_stmt; ParamIndex: Integer; const Buffer: Pointer; N: Integer; ValDestructor: Tsqlite3_destructor_type): Integer; cdecl;\n  Tsqlite3_bind_double = function(pStmt: Psqlite3_stmt; ParamIndex: Integer; Value: Double): Integer; cdecl;\n  Tsqlite3_bind_int = function(pStmt: Psqlite3_stmt; ParamIndex: Integer; Value: Integer): Integer; cdecl;\n  Tsqlite3_bind_int64 = function(pStmt: Psqlite3_stmt; ParamIndex: Integer; Value: Int64): Integer; cdecl;\n  Tsqlite3_bind_null = function(pStmt: Psqlite3_stmt; ParamIndex: Integer): Integer; cdecl;\n  Tsqlite3_bind_text = function(pStmt: Psqlite3_stmt; ParamIndex: Integer; const Text: PAnsiChar; N: Integer; ValDestructor: Tsqlite3_destructor_type): Integer; cdecl;\n  Tsqlite3_bind_text16 = function(pStmt: Psqlite3_stmt; ParamIndex: Integer; const Text: PWideChar; N: Integer; ValDestructor: Tsqlite3_destructor_type): Integer; cdecl;\n  Tsqlite3_bind_value = function(pStmt: Psqlite3_stmt; ParamIndex: Integer; const Value: Psqlite3_value): Integer; cdecl;\n  Tsqlite3_bind_zeroblob = function(pStmt: Psqlite3_stmt; ParamIndex: Integer; N: Integer): Integer; cdecl;\n\n  Tsqlite3_finalize = function(pStmt: Psqlite3_stmt): Integer; cdecl;\n  Tsqlite3_reset = function(pStmt: Psqlite3_stmt): Integer; cdecl;\n\n  Tsqlite3_column_blob = function(Stmt: Psqlite3_stmt; iCol:integer): Pointer; cdecl;\n  Tsqlite3_column_bytes = function(Stmt: Psqlite3_stmt; iCol: Integer): integer; cdecl;\n  Tsqlite3_column_bytes16 = function(Stmt: Psqlite3_stmt; iCol: Integer): integer; cdecl;\n  Tsqlite3_column_double = function(Stmt: Psqlite3_stmt; iCol: Integer): Double; cdecl;\n  Tsqlite3_column_int = function(Stmt: Psqlite3_stmt; iCol: Integer): Integer; cdecl;\n  Tsqlite3_column_int64 = function(Stmt: Psqlite3_stmt; iCol: Integer): Int64; cdecl;\n  Tsqlite3_column_text = function(Stmt: Psqlite3_stmt; iCol: Integer): PAnsiChar; cdecl;\n  Tsqlite3_column_text16 = function(Stmt: Psqlite3_stmt; iCol: Integer): PWideChar; cdecl;\n  Tsqlite3_column_type = function(Stmt: Psqlite3_stmt; iCol: Integer): Integer; cdecl;\n  Tsqlite3_column_value = function(Stmt: Psqlite3_stmt; iCol: Integer): Psqlite3_value; cdecl;\n  Tsqlite3_last_insert_rowid = function(db: Psqlite): Int64; cdecl;\n\n  //gets the column type\n  Tsqlite_column_type = function(db:PSqlite;iCol:integer):Integer; cdecl;\n\n  Tsqlite_exec = function(db: Psqlite; const sql: PAnsiChar;\n    sqlite_callback: Tsqlite_callback; arg: Pointer;\n    var errmsg: PAnsiChar): Integer; cdecl;\n  Tsqlite_errmsg = function(db: Psqlite): PAnsiChar; cdecl;\n  Tsqlite_errstr = function(code: Integer): PAnsiChar; cdecl;\n  //Tsqlite_last_insert_rowid = function(db: Psqlite): Integer; cdecl;\n  Tsqlite_changes = function(db: Psqlite): Integer; cdecl;\n  Tsqlite_last_statement_changes = function(db: Psqlite): Integer; cdecl;\n  Tsqlite_interrupt = procedure(db: Psqlite); cdecl;\n  Tsqlite_complete = function(const sql: PAnsiChar): Integer; cdecl;\n  Tsqlite_busy_handler = procedure(db: Psqlite;\n    callback: Tsqlite_busy_callback; ptr: Pointer); cdecl;\n  Tsqlite_busy_timeout = procedure(db: Psqlite; ms: Integer); cdecl;\n  Tsqlite_get_table = function(db: Psqlite; const sql: PAnsiChar;\n    var resultp: PPAnsiChar; var nrow: Integer; var ncolumn: Integer;\n    var errmsg: PAnsiChar): Integer; cdecl;\n  Tsqlite_free_table = procedure(var result: PAnsiChar); cdecl;\n  Tsqlite_freemem = procedure(ptr: Pointer); cdecl;\n  Tsqlite_libversion = function: PAnsiChar; cdecl;\n  Tsqlite_libencoding = function: PAnsiChar; cdecl;\n\n  Tsqlite_create_function = function(db: Psqlite; const zName: PAnsiChar;\n    nArg: Integer; callback: Tsqlite_function_callback;\n    pUserData: Pointer): Integer; cdecl;\n  Tsqlite_create_aggregate = function(db: Psqlite; const zName: PAnsiChar;\n    nArg: Integer; callback: Tsqlite_function_callback;\n    finalize: Tsqlite_finalize_callback; pUserData: Pointer): Integer; cdecl;\n  Tsqlite_function_type = function(db: Psqlite; const zName: PAnsiChar;\n    datatype: Integer): Integer; cdecl;\n\n  Tsqlite_set_result_string = function(func: Psqlite_func; const arg: PAnsiChar;\n    len: Integer; UN: Tsqlite_simple_callback): PAnsiChar; cdecl;\n\n  Tsqlite_set_result_int = procedure(func: Psqlite_func; arg: Integer); cdecl;\n  Tsqlite_set_result_double = procedure(func: Psqlite_func; arg: Double); cdecl;\n  Tsqlite_set_result_error = procedure(func: Psqlite_func; const arg: PAnsiChar;\n    len: Integer); cdecl;\n  Tsqlite_user_data = function(func: Psqlite_func): Pointer; cdecl;\n  Tsqlite_aggregate_context = function(func: Psqlite_func;\n    nBytes: Integer): Pointer; cdecl;\n  Tsqlite_aggregate_count = function(func: Psqlite_func): Integer; cdecl;\n\n  Tsqlite_set_authorizer = function(db: Psqlite;\n    callback: Tsqlite_auth_callback; pUserData: Pointer): Integer; cdecl;\n  Tsqlite_trace = function(db: Psqlite; callback: Tsqlite_trace_callback;\n    ptr: Pointer): Pointer; cdecl;\n\n  Tsqlite_progress_handler = procedure(db: Psqlite; p1: Integer;\n    callback: Tsqlite_simple_callback; ptr: Pointer); cdecl;\n  Tsqlite_commit_hook = function(db: Psqlite; callback: Tsqlite_simple_callback;\n    ptr: Pointer): Pointer; cdecl;\n\n  Tsqlite_open_encrypted = function(const zFilename: PAnsiChar;\n    const pKey: PAnsiChar; nKey: Integer; var pErrcode: Integer;\n    var pzErrmsg: PAnsiChar): Psqlite; cdecl;\n  Tsqlite_rekey = function(db: Psqlite; const pKey: Pointer;\n    nKey: Integer): Integer; cdecl;\n  Tsqlite_key = function(db: Psqlite; const pKey: Pointer;\n    nKey: Integer): Integer; cdecl;\n\n{ ************* Plain API Function variables definition ************ }\nTZSQLite_API = record\n  sqlite_open: Tsqlite_open;\n  sqlite_close: Tsqlite_close;\n\n  { prepared statement api }\n  sqlite_prepare: Tsqlite3_prepare;\n  sqlite_prepare_v2: Tsqlite3_prepare_v2;\n  sqlite_prepare16: Tsqlite3_prepare16;\n  sqlite_prepare16_v2: Tsqlite3_prepare16_v2;\n\n  sqlite_bind_parameter_count: Tsqlite3_bind_parameter_count;\n  sqlite_bind_parameter_name: Tsqlite3_bind_parameter_name;\n  sqlite_bind_parameter_index: Tsqlite3_bind_parameter_index;\n\n  sqlite_clear_bindings: Tsqlite3_clear_bindings;\n  sqlite_column_count: Tsqlite3_column_count;\n  sqlite_column_name: Tsqlite3_column_name;\n  sqlite_column_name16: Tsqlite3_column_name16;\n\n  sqlite_column_database_name: Tsqlite3_column_database_name;\n  sqlite_column_database_name16: Tsqlite3_column_database_name16;\n  sqlite_column_table_name: Tsqlite3_column_table_name;\n  sqlite_column_table_name16: Tsqlite3_column_table_name16;\n  sqlite_column_origin_name: Tsqlite3_column_origin_name;\n  sqlite_column_origin_name16: Tsqlite3_column_origin_name16;\n\n  sqlite_column_decltype: Tsqlite3_column_decltype;\n  sqlite_column_decltype16: Tsqlite3_column_decltype16;\n\n  sqlite_step: Tsqlite3_step;\n  sqlite_data_count: Tsqlite3_data_count;\n\n  sqlite_bind_blob: Tsqlite3_bind_blob;\n  sqlite_bind_double: Tsqlite3_bind_double;\n  sqlite_bind_int: Tsqlite3_bind_int;\n  sqlite_bind_int64: Tsqlite3_bind_int64;\n  sqlite_bind_null: Tsqlite3_bind_null;\n  sqlite_bind_text: Tsqlite3_bind_text;\n  sqlite_bind_text16: Tsqlite3_bind_text16;\n  sqlite_bind_value: Tsqlite3_bind_value;\n  sqlite_bind_zeroblob: Tsqlite3_bind_zeroblob;\n\n  sqlite_finalize: Tsqlite3_finalize;\n  sqlite_reset: Tsqlite3_reset;\n\n  sqlite_column_blob: Tsqlite3_column_blob;\n  sqlite_column_bytes: Tsqlite3_column_bytes;\n  sqlite_column_bytes16: Tsqlite3_column_bytes16;\n  sqlite_column_double: Tsqlite3_column_double;\n  sqlite_column_int: Tsqlite3_column_int;\n  sqlite_column_int64: Tsqlite3_column_int64;\n  sqlite_column_text: Tsqlite3_column_text;\n  sqlite_column_text16: Tsqlite3_column_text16;\n  sqlite_column_type: Tsqlite3_column_type;\n  sqlite_column_value: Tsqlite3_column_value;\n\n  sqlite_exec: Tsqlite_exec;\n  sqlite_errmsg: Tsqlite_errmsg;\n  sqlite_errstr: Tsqlite_errstr;\n  sqlite_last_insert_rowid: Tsqlite3_last_insert_rowid;\n  sqlite_changes: Tsqlite_changes;\n  sqlite_last_statement_changes: Tsqlite_last_statement_changes;\n  sqlite_interrupt: Tsqlite_interrupt;\n  sqlite_complete: Tsqlite_complete;\n  sqlite_busy_handler: Tsqlite_busy_handler;\n  sqlite_busy_timeout: Tsqlite_busy_timeout;\n  sqlite_get_table: Tsqlite_get_table;\n  sqlite_free_table: Tsqlite_free_table;\n  sqlite_freemem: Tsqlite_freemem;\n  sqlite_libversion: Tsqlite_libversion;\n  sqlite_libencoding: Tsqlite_libencoding;\n  sqlite_create_function: Tsqlite_create_function;\n  sqlite_create_aggregate: Tsqlite_create_aggregate;\n  sqlite_function_type: Tsqlite_function_type;\n  sqlite_set_result_string: Tsqlite_set_result_string;\n  sqlite_set_result_int: Tsqlite_set_result_int;\n  sqlite_set_result_double: Tsqlite_set_result_double;\n  sqlite_set_result_error: Tsqlite_set_result_error;\n  sqlite_user_data: Tsqlite_user_data;\n  sqlite_aggregate_context: Tsqlite_aggregate_context;\n  sqlite_aggregate_count: Tsqlite_aggregate_count;\n  sqlite_set_authorizer: Tsqlite_set_authorizer;\n  sqlite_trace: Tsqlite_trace;\n  sqlite_progress_handler: Tsqlite_progress_handler;\n  sqlite_commit_hook: Tsqlite_commit_hook;\n  sqlite_open_encrypted: Tsqlite_open_encrypted;\n  sqlite_rekey: Tsqlite_rekey;\n  sqlite_key: Tsqlite_key;\nend;\n\ntype\n\n  {** Represents a generic interface to SQLite native API. }\n  IZSQLitePlainDriver = interface (IZPlainDriver)\n    ['{B931C952-3076-4ECB-9630-D900E8DB9869}']\n\n    function Open(const filename: PAnsiChar; mode: Integer;\n      var errmsg: PAnsiChar): Psqlite;\n    function Close(db: Psqlite): Integer;\n    function Execute(db: Psqlite; const sql: PAnsiChar;\n      sqlite_callback: Tsqlite_callback; arg: Pointer;\n      var errmsg: PAnsiChar): Integer;\n    function LastInsertRowId(db: Psqlite): Int64;\n    function Changes(db: Psqlite): Integer;\n    function LastStatementChanges(db: Psqlite): Integer;\n    function ErrorString(db: Psqlite; code: Integer): String;\n    procedure Interrupt(db: Psqlite);\n    function Complete(const sql: PAnsiChar): Integer;\n\n    procedure BusyHandler(db: Psqlite; callback: Tsqlite_busy_callback;\n      ptr: Pointer);\n    procedure BusyTimeout(db: Psqlite; ms: Integer);\n\n    function GetTable(db: Psqlite; const sql: PAnsiChar; var resultp: PPAnsiChar;\n      var nrow: Integer; var ncolumn: Integer; var errmsg: PAnsiChar): Integer;\n    procedure FreeTable(var result: PAnsiChar);\n    procedure FreeMem(ptr: Pointer);\n    function LibVersion: PAnsiChar;\n    function LibEncoding: PAnsiChar;\n\n    function CreateFunction(db: Psqlite; const zName: PAnsiChar;\n      nArg: Integer; callback: Tsqlite_function_callback;\n      pUserData: Pointer): Integer;\n    function CreateAggregate(db: Psqlite; const zName: PAnsiChar;\n      nArg: Integer; callback: Tsqlite_function_callback;\n      finalize: Tsqlite_finalize_callback; pUserData: Pointer): Integer;\n    function FunctionType(db: Psqlite; const zName: PAnsiChar;\n      datatype: Integer): Integer;\n    function SetResultString(func: Psqlite_func; const arg: PAnsiChar;\n      len: Integer): PAnsiChar;\n    procedure SetResultInt(func: Psqlite_func; arg: Integer);\n    procedure SetResultDouble(func: Psqlite_func; arg: Double);\n    procedure SetResultError(func: Psqlite_func; const arg: PAnsiChar; len: Integer);\n    function UserData(func: Psqlite_func): Pointer;\n    function AggregateContext(func: Psqlite_func; nBytes: Integer): Pointer;\n    function AggregateCount(func: Psqlite_func): Integer;\n\n    function SetAuthorizer(db: Psqlite; callback: Tsqlite_auth_callback;\n      pUserData: Pointer): Integer;\n    function Trace(db: Psqlite; callback: Tsqlite_trace_callback;\n      ptr: Pointer): Pointer;\n\n    { Prepared statmenet api }\n    function Prepare(db: Psqlite; const zSql: PAnsiChar; nBytes: Integer;\n      out ppStmt: Psqlite3_stmt; pzTail: PPAnsichar): Integer;\n    function Prepare_v2(db: Psqlite; const zSql: PAnsiChar; nBytes: Integer;\n      out ppStmt: Psqlite3_stmt; pzTail: PPAnsichar): Integer;\n    function Prepare16(db: Psqlite; const zSql: PWideChar; nBytes: Integer;\n      out ppStmt: Psqlite3_stmt; pzTail: ZPPWideChar): Integer;\n    function Prepare16_v2(db: Psqlite; const zSql: PWideChar; nBytes: Integer;\n      out ppStmt: Psqlite3_stmt; pzTail: ZPPWideChar): Integer;\n\n    function bind_parameter_count(pStmt: Psqlite3_stmt): Integer;\n    function bind_parameter_name(pStmt: Psqlite3_stmt; ParamIndex: Integer): PAnsichar;\n    function bind_parameter_index(pStmt: Psqlite3_stmt; const zName: PAnsiChar): Integer;\n\n    function clear_bindings(pStmt: Psqlite3_stmt): Integer;\n    function column_count(pStmt: Psqlite3_stmt): Integer;\n    function column_name(pStmt: Psqlite3_stmt; iCol: Integer): PAnsiChar;\n    function column_name16(pStmt: Psqlite3_stmt; iCol: Integer): PWideChar;\n\n    function column_database_name(pStmt: Psqlite3_stmt; iCol: Integer): PAnsiChar;\n    function column_database_name16(pStmt: Psqlite3_stmt; iCol: Integer): PWideChar;\n    function column_table_name(pStmt: Psqlite3_stmt; iCol: Integer): PAnsiChar;\n    function column_table_name16(pStmt: Psqlite3_stmt; iCol: Integer): PWideChar;\n    function column_origin_name(pStmt: Psqlite3_stmt; iCol: Integer): PAnsiChar;\n    function column_origin_name16(pStmt: Psqlite3_stmt; iCol: Integer): PWideChar;\n\n    function column_decltype(pStmt: Psqlite3_stmt; iCol: Integer): PAnsiChar;\n    function column_decltype16(pStmt: Psqlite3_stmt; iCol: Integer): PWideChar;\n\n    function Step(Stmt: Psqlite3_stmt; var pN: Integer;\n      var pazValue, pazColName: PPAnsiChar): Integer; overload;\n    function Step(Stmt: Psqlite3_stmt): Integer; overload;\n    function data_count(pStmt: Psqlite3_stmt): Integer;\n\n    function bind_blob(pStmt: Psqlite3_stmt; ParamIndex: Integer;\n      const Buffer: Pointer; N: Integer; ValDestructor: Tsqlite3_destructor_type): Integer;\n    function bind_double(pStmt: Psqlite3_stmt; ParamIndex: Integer; Value: Double): Integer;\n    function bind_int(pStmt: Psqlite3_stmt; ParamIndex: Integer; Value: Integer): Integer;\n    function bind_int64(pStmt: Psqlite3_stmt; ParamIndex: Integer; Value: Int64): Integer;\n    function bind_null(pStmt: Psqlite3_stmt; ParamIndex: Integer): Integer;\n    function bind_text(pStmt: Psqlite3_stmt; ParamIndex: Integer;\n      const Text: PAnsiChar; N: Integer; ValDestructor: Tsqlite3_destructor_type): Integer;\n    function bind_text16(pStmt: Psqlite3_stmt; ParamIndex: Integer;\n      const Text: PWideChar; N: Integer; ValDestructor: Tsqlite3_destructor_type): Integer;\n    function bind_value(pStmt: Psqlite3_stmt; ParamIndex: Integer; const Value: Psqlite3_value): Integer;\n    function bind_zeroblob(pStmt: Psqlite3_stmt; ParamIndex: Integer; N: Integer): Integer;\n\n    function finalize(pStmt: Psqlite3_stmt): Integer;\n    function reset(pStmt: Psqlite3_stmt): Integer;\n\n    function column_blob(Stmt: Psqlite3_stmt; iCol:integer): TStream;\n    function column_bytes(Stmt: Psqlite3_stmt; iCol: Integer): integer;\n    function column_bytes16(Stmt: Psqlite3_stmt; iCol: Integer): integer;\n    function column_double(Stmt: Psqlite3_stmt; iCol: Integer): Double;\n    function column_int(Stmt: Psqlite3_stmt; iCol: Integer): Integer;\n    function column_int64(Stmt: Psqlite3_stmt; iCol: Integer): Int64;\n    function column_text(Stmt: Psqlite3_stmt; iCol: Integer): PAnsiChar;\n    function column_text16(Stmt: Psqlite3_stmt; iCol: Integer): PWideChar;\n    function column_type(Stmt: Psqlite3_stmt; iCol: Integer): String;\n    function column_value(Stmt: Psqlite3_stmt; iCol: Integer): Psqlite3_value;\n\n    procedure ProgressHandler(db: Psqlite; p1: Integer;\n      callback: Tsqlite_simple_callback; ptr: Pointer);\n    function CommitHook(db: Psqlite; callback: Tsqlite_simple_callback;\n      ptr: Pointer): Pointer;\n\n    function OpenEncrypted(const zFilename: PAnsiChar; const pKey: PAnsiChar;\n      nKey: Integer; var pErrcode: Integer; var pzErrmsg: PAnsiChar): Psqlite;\n    function ReKey(db: Psqlite; const pKey: Pointer; nKey: Integer): Integer;\n    function Key(db: Psqlite; const pKey: Pointer; nKey: Integer): Integer;\n  end;\n\n  {** Implements a base driver for SQLite}\n  TZSQLiteBaseDriver = class (TZAbstractPlainDriver, IZPlainDriver, IZSQLitePlainDriver)\n  protected\n    SQLite_API : TZSQLite_API;\n    // procedure LoadApi; override; ->completely done in version dependent child classes\n    function GetUnicodeCodePageName: String; override;\n    procedure LoadCodePages; override;\n  public\n    constructor Create;\n\n    function Open(const filename: PAnsiChar; mode: Integer;\n      var errmsg: PAnsiChar): Psqlite;\n    function Close(db: Psqlite): Integer;\n    function Execute(db: Psqlite; const sql: PAnsiChar;\n      sqlite_callback: Tsqlite_callback; arg: Pointer;\n      var errmsg: PAnsiChar): Integer;\n    function LastInsertRowId(db: Psqlite): Int64;\n    function Changes(db: Psqlite): Integer;\n    function LastStatementChanges(db: Psqlite): Integer;\n    function ErrorString(db: Psqlite; code: Integer): String;\n    procedure Interrupt(db: Psqlite);\n    function Complete(const sql: PAnsiChar): Integer;\n\n    procedure BusyHandler(db: Psqlite; callback: Tsqlite_busy_callback;\n      ptr: Pointer);\n    procedure BusyTimeout(db: Psqlite; ms: Integer);\n\n    function GetTable(db: Psqlite; const sql: PAnsiChar; var resultp: PPAnsiChar;\n      var nrow: Integer; var ncolumn: Integer; var errmsg: PAnsiChar): Integer;\n    procedure FreeTable(var result: PAnsiChar);\n    procedure FreeMem(ptr: Pointer);\n    function LibVersion: PAnsiChar;\n    function LibEncoding: PAnsiChar;\n\n    function CreateFunction(db: Psqlite; const zName: PAnsiChar;\n      nArg: Integer; callback: Tsqlite_function_callback;\n      pUserData: Pointer): Integer; virtual;\n    function CreateAggregate(db: Psqlite; const zName: PAnsiChar;\n      nArg: Integer; callback: Tsqlite_function_callback;\n      finalize: Tsqlite_finalize_callback; pUserData: Pointer): Integer;\n    function FunctionType(db: Psqlite; const zName: PAnsiChar;\n      datatype: Integer): Integer;\n    function SetResultString(func: Psqlite_func; const arg: PAnsiChar;\n      len: Integer): PAnsiChar;\n    procedure SetResultInt(func: Psqlite_func; arg: Integer);\n    procedure SetResultDouble(func: Psqlite_func; arg: Double);\n    procedure SetResultError(func: Psqlite_func; const arg: PAnsiChar; len: Integer);\n    function UserData(func: Psqlite_func): Pointer;\n    function AggregateContext(func: Psqlite_func; nBytes: Integer): Pointer;\n    function AggregateCount(func: Psqlite_func): Integer;\n\n    function SetAuthorizer(db: Psqlite; callback: Tsqlite_auth_callback;\n      pUserData: Pointer): Integer;\n    function Trace(db: Psqlite; callback: Tsqlite_trace_callback;\n      ptr: Pointer): Pointer;\n\n    { Prepared statmenet api }\n    function Prepare(db: Psqlite; const zSql: PAnsiChar; nBytes: Integer;\n      out ppStmt: Psqlite3_stmt; pzTail: PPAnsichar): Integer;\n    function Prepare_v2(db: Psqlite; const zSql: PAnsiChar; nBytes: Integer;\n      out ppStmt: Psqlite3_stmt; pzTail: PPAnsichar): Integer;\n    function Prepare16(db: Psqlite; const zSql: PWideChar; nBytes: Integer;\n      out ppStmt: Psqlite3_stmt; pzTail: ZPPWideChar): Integer;\n    function Prepare16_v2(db: Psqlite; const zSql: PWideChar; nBytes: Integer;\n      out ppStmt: Psqlite3_stmt; pzTail: ZPPWideChar): Integer;\n\n    function bind_parameter_count(pStmt: Psqlite3_stmt): Integer;\n    function bind_parameter_name(pStmt: Psqlite3_stmt; ParamIndex: Integer): PAnsichar;\n    function bind_parameter_index(pStmt: Psqlite3_stmt; const zName: PAnsiChar): Integer;\n\n    function clear_bindings(pStmt: Psqlite3_stmt): Integer;\n    function column_count(pStmt: Psqlite3_stmt): Integer;\n    function column_name(pStmt: Psqlite3_stmt; iCol: Integer): PAnsiChar;\n    function column_name16(pStmt: Psqlite3_stmt; iCol: Integer): PWideChar;\n\n    function column_database_name(pStmt: Psqlite3_stmt; iCol: Integer): PAnsiChar;\n    function column_database_name16(pStmt: Psqlite3_stmt; iCol: Integer): PWideChar;\n    function column_table_name(pStmt: Psqlite3_stmt; iCol: Integer): PAnsiChar;\n    function column_table_name16(pStmt: Psqlite3_stmt; iCol: Integer): PWideChar;\n    function column_origin_name(pStmt: Psqlite3_stmt; iCol: Integer): PAnsiChar;\n    function column_origin_name16(pStmt: Psqlite3_stmt; iCol: Integer): PWideChar;\n\n    function column_decltype(pStmt: Psqlite3_stmt; iCol: Integer): PAnsiChar;\n    function column_decltype16(pStmt: Psqlite3_stmt; iCol: Integer): PWideChar;\n\n    function Step(Stmt: Psqlite3_stmt; var pN: Integer;\n      var pazValue, pazColName: PPAnsiChar): Integer; overload;\n    function Step(Stmt: Psqlite3_stmt): Integer; overload;\n    function data_count(pStmt: Psqlite3_stmt): Integer;\n\n    function bind_blob(pStmt: Psqlite3_stmt; ParamIndex: Integer;\n      const Buffer: Pointer; N: Integer; ValDestructor: Tsqlite3_destructor_type): Integer;\n    function bind_double(pStmt: Psqlite3_stmt; ParamIndex: Integer; Value: Double): Integer;\n    function bind_int(pStmt: Psqlite3_stmt; ParamIndex: Integer; Value: Integer): Integer;\n    function bind_int64(pStmt: Psqlite3_stmt; ParamIndex: Integer; Value: Int64): Integer;\n    function bind_null(pStmt: Psqlite3_stmt; ParamIndex: Integer): Integer;\n    function bind_text(pStmt: Psqlite3_stmt; ParamIndex: Integer; const Text: PAnsiChar; N: Integer;\n      ValDestructor: Tsqlite3_destructor_type): Integer;\n    function bind_text16(pStmt: Psqlite3_stmt; ParamIndex: Integer; const Text: PWideChar; N: Integer;\n      ValDestructor: Tsqlite3_destructor_type): Integer;\n    function bind_value(pStmt: Psqlite3_stmt; ParamIndex: Integer; const Value: Psqlite3_value): Integer;\n    function bind_zeroblob(pStmt: Psqlite3_stmt; ParamIndex: Integer; N: Integer): Integer;\n\n    function finalize(pStmt: Psqlite3_stmt): Integer;\n    function reset(pStmt: Psqlite3_stmt): Integer;\n\n    function column_blob(Stmt: Psqlite3_stmt; iCol:integer): TStream;\n    function column_bytes(Stmt: Psqlite3_stmt; iCol: Integer): integer;\n    function column_bytes16(Stmt: Psqlite3_stmt; iCol: Integer): integer;\n    function column_double(Stmt: Psqlite3_stmt; iCol: Integer): Double;\n    function column_int(Stmt: Psqlite3_stmt; iCol: Integer): Integer;\n    function column_int64(Stmt: Psqlite3_stmt; iCol: Integer): Int64;\n    function column_text(Stmt: Psqlite3_stmt; iCol: Integer): PAnsiChar;\n    function column_text16(Stmt: Psqlite3_stmt; iCol: Integer): PWideChar;\n    function column_type(Stmt: Psqlite3_stmt; iCol: Integer): String;\n    function column_value(Stmt: Psqlite3_stmt; iCol: Integer): Psqlite3_value;\n\n    procedure ProgressHandler(db: Psqlite; p1: Integer;\n      callback: Tsqlite_simple_callback; ptr: Pointer);\n    function CommitHook(db: Psqlite; callback: Tsqlite_simple_callback;\n      ptr: Pointer): Pointer;\n\n    function OpenEncrypted(const zFilename: PAnsiChar; const pKey: PAnsiChar;\n      nKey: Integer; var pErrcode: Integer; var pzErrmsg: PAnsiChar): Psqlite;\n    function ReKey(db: Psqlite; const pKey: Pointer; nKey: Integer): Integer;\n    function Key(db: Psqlite; const pKey: Pointer; nKey: Integer): Integer;\n\n  end;\n\n  {** Implements a driver for SQLite 3 }\n  TZSQLite3PlainDriver = class (TZSQLiteBaseDriver, IZPlainDriver, IZSQLitePlainDriver)\n  protected\n    function Clone: IZPlainDriver; override;\n    procedure LoadApi; override;\n  public\n    constructor Create;\n    function GetProtocol: string; override;\n    function GetDescription: string; override;\n  end;\n\nimplementation\n\nuses ZPlainLoader, ZEncoding;\n\n{ TZSQLiteBaseDriver }\n\nfunction TZSQLiteBaseDriver.GetUnicodeCodePageName: String;\nbegin\n  Result := 'UTF-8'\nend;\n\nprocedure TZSQLiteBaseDriver.LoadCodePages;  //Egonhugeist\nbegin\n  { MultiByte }\n  AddCodePage('UTF-8', 1, ceUTF8, zCP_UTF8);\n  AddCodePage('UTF-16le', 2, ceUTF16, zCP_UTF16, 'UTF-8'); //Setting this will be ignored by actual Excute of Plaindriver\n  AddCodePage('UTF-16be', 3, ceUTF16, zCP_UTF16BE, 'UTF-8'); //Setting this will be ignored by actual Excute of Plaindriver\n  AddCodePage('UTF-16', 4, ceUTF16, zCP_UTF16, 'UTF-8'); //Setting this will be ignored by actual Excute of Plaindriver\nend;\n\nconstructor TZSQLiteBaseDriver.Create;\nbegin\n   inherited create;\n   FLoader := TZNativeLibraryLoader.Create([]);\n  {$IFNDEF UNIX}\n    FLoader.AddLocation(WINDOWS_DLL_LOCATION);\n  {$ELSE}\n    FLoader.AddLocation(LINUX_DLL_LOCATION);\n    FLoader.AddLocation(LINUX_DLL_LOCATION+'.0');\n  {$ENDIF}\nend;\n\nfunction TZSQLiteBaseDriver.AggregateContext(func: Psqlite_func;\n  nBytes: Integer): Pointer;\nbegin\n  Result := SQLite_API.sqlite_aggregate_context(func, nBytes);\nend;\n\nfunction TZSQLiteBaseDriver.AggregateCount(func: Psqlite_func): Integer;\nbegin\n  Result := SQLite_API.sqlite_aggregate_count(func);\nend;\n\nprocedure TZSQLiteBaseDriver.BusyHandler(db: Psqlite;\n  callback: Tsqlite_busy_callback; ptr: Pointer);\nbegin\n  SQLite_API.sqlite_busy_handler(db, callback, ptr);\nend;\n\nprocedure TZSQLiteBaseDriver.BusyTimeout(db: Psqlite; ms: Integer);\nbegin\n  SQLite_API.sqlite_busy_timeout(db, ms);\nend;\n\nfunction TZSQLiteBaseDriver.Changes(db: Psqlite): Integer;\nbegin\n  Result := SQLite_API.sqlite_changes(db);\nend;\n\nfunction TZSQLiteBaseDriver.CommitHook(db: Psqlite;\n  callback: Tsqlite_simple_callback; ptr: Pointer): Pointer;\nbegin\n  Result := SQLite_API.sqlite_commit_hook(db, callback, ptr);\nend;\n\nfunction TZSQLiteBaseDriver.Complete(const sql: PAnsiChar): Integer;\nbegin\n  Result := SQLite_API.sqlite_complete(sql);\nend;\n\nfunction TZSQLiteBaseDriver.CreateAggregate(db: Psqlite;\n  const zName: PAnsiChar; nArg: Integer; callback: Tsqlite_function_callback;\n  finalize: Tsqlite_finalize_callback; pUserData: Pointer): Integer;\nbegin\n  Result := SQLITE_MISUSE;\nend;\n\nfunction TZSQLiteBaseDriver.CreateFunction(db: Psqlite;\n  const zName: PAnsiChar; nArg: Integer; callback: Tsqlite_function_callback;\n  pUserData: Pointer): Integer;\nbegin\n  Result := SQLITE_MISUSE;\nend;\n\nfunction TZSQLiteBaseDriver.ErrorString(db: Psqlite; code: Integer): String;\nvar\n  ErrorMessagePointer: PAnsiChar;\n  ErrorMessage: String;\n  ErrorString: String;\nbegin\n  if code = SQLITE_OK then\n  begin\n    Result := 'not an error';\n    Exit;\n  end;\n\n  if code = SQLITE_NOMEM then\n  begin\n    Result := 'out of memory';\n    Exit;\n  end;\n\n  if ( db = nil ) or ( @SQLite_API.sqlite_errstr = nil ) then\n  begin\n    case code of\n      SQLITE_OK:         Result := 'not an error';\n      SQLITE_ERROR:      Result := 'SQL logic error or missing database';\n      SQLITE_INTERNAL:   Result := 'internal SQLite implementation flaw';\n      SQLITE_PERM:       Result := 'access permission denied';\n      SQLITE_ABORT:      Result := 'callback requested query abort';\n      SQLITE_BUSY:       Result := 'database is locked';\n      SQLITE_LOCKED:     Result := 'database table is locked';\n      SQLITE_NOMEM:      Result := 'out of memory';\n      SQLITE_READONLY:   Result := 'attempt to write a readonly database';\n      _SQLITE_INTERRUPT:  Result := 'interrupted';\n      SQLITE_IOERR:      Result := 'disk I/O error';\n      SQLITE_CORRUPT:    Result := 'database disk image is malformed';\n      SQLITE_NOTFOUND:   Result := 'table or record not found';\n      SQLITE_FULL:       Result := 'database is full';\n      SQLITE_CANTOPEN:   Result := 'unable to open database file';\n      SQLITE_PROTOCOL:   Result := 'database locking protocol failure';\n      SQLITE_EMPTY:      Result := 'table contains no data';\n      SQLITE_SCHEMA:     Result := 'database schema has changed';\n      SQLITE_TOOBIG:     Result := 'too much data for one table row';\n      SQLITE_CONSTRAINT: Result := 'constraint failed';\n      SQLITE_MISMATCH:   Result := 'datatype mismatch';\n      SQLITE_MISUSE:     Result := 'library routine called out of sequence';\n      SQLITE_NOLFS:      Result := 'kernel lacks large file support';\n      SQLITE_AUTH:       Result := 'authorization denied';\n      SQLITE_FORMAT:     Result := 'auxiliary database format error';\n      SQLITE_RANGE:      Result := 'bind index out of range';\n      SQLITE_NOTADB:     Result := 'file is encrypted or is not a database';\n    else\n      Result := 'unknown error';\n    end;\n\n    exit;\n  end\n  else\n  begin\n    ErrorMessagePointer := Self.SQLite_API.sqlite_errstr(code);\n    {$IFDEF UNICODE}\n    ErrorString := Trim(UTF8ToUnicodeString(ErrorMessagePointer));\n    {$ELSE}\n      {$IFNDEF FPC}\n      ErrorString := Trim(UTF8ToAnsi(StrPas(ErrorMessagePointer)));\n      {$ELSE}\n      ErrorString := Trim(ErrorMessagePointer);\n      {$ENDIF}\n    {$ENDIF}\n\n    ErrorMessagePointer := Self.SQLite_API.sqlite_errmsg(db);\n    {$IFDEF UNICODE}\n    ErrorMessage := Trim(UTF8ToUnicodeString(ErrorMessagePointer));\n    {$ELSE}\n      {$IFNDEF FPC}\n      ErrorMessage := Trim(UTF8ToAnsi(ErrorMessagePointer));\n      {$ELSE}\n      ErrorMessage := Trim(ErrorMessagePointer);\n      {$ENDIF}\n    {$ENDIF}\n\n    Result := ErrorString + ': ' + ErrorMessage;\n  end;\nend;\n\nfunction TZSQLiteBaseDriver.Execute(db: Psqlite; const sql: PAnsiChar;\n  sqlite_callback: Tsqlite_callback; arg: Pointer;\n  var errmsg: PAnsiChar): Integer;\nbegin\n  errmsg:= nil;\n  Result := SQLite_API.sqlite_exec(db, sql, sqlite_callback, arg, errmsg);\nend;\n\nprocedure TZSQLiteBaseDriver.FreeMem(ptr: Pointer);\nbegin\n  SQLite_API.sqlite_freemem(ptr);\nend;\n\nprocedure TZSQLiteBaseDriver.FreeTable(var result: PAnsiChar);\nbegin\n  SQLite_API.sqlite_free_table(result);\nend;\n\nfunction TZSQLiteBaseDriver.FunctionType(db: Psqlite;\n  const zName: PAnsiChar; datatype: Integer): Integer;\nbegin\n  Result := SQLITE_MISUSE;\nend;\n\nfunction TZSQLiteBaseDriver.GetTable(db: Psqlite; const sql: PAnsiChar;\n  var resultp: PPAnsiChar; var nrow, ncolumn: Integer;\n  var errmsg: PAnsiChar): Integer;\nbegin\n  Result := SQLite_API.sqlite_get_table(db, sql, resultp, nrow, ncolumn,\n    errmsg);\nend;\n\nprocedure TZSQLiteBaseDriver.Interrupt(db: Psqlite);\nbegin\n  SQLite_API.sqlite_interrupt(db);\nend;\n\nfunction TZSQLiteBaseDriver.LastInsertRowId(db: Psqlite): Int64;\nbegin\n  Result := SQLite_API.sqlite_last_insert_rowid(db);\nend;\n\nfunction TZSQLiteBaseDriver.LastStatementChanges(db: Psqlite): Integer;\nbegin\n  Result := SQLITE_MISUSE;\nend;\n\nfunction TZSQLiteBaseDriver.LibEncoding: PAnsiChar;\nbegin\n  Result := nil;\nend;\n\nfunction TZSQLiteBaseDriver.LibVersion: PAnsiChar;\nbegin\n  Result := SQLite_API.sqlite_libversion;\nend;\n\nfunction TZSQLiteBaseDriver.Open(const filename: PAnsiChar; mode: Integer;\n  var errmsg: PAnsiChar): Psqlite;\nvar\n  Result0: Psqlite;\n{$IFNDEF UNICODE}\n  Version: string;\n  FileNameString: String;\n{$ENDIF}\nbegin\n  Result0:= nil;\n  (*Note to Windows users: The encoding used for the filename argument of\n    sqlite3_open() and sqlite3_open_v2() must be UTF-8, not whatever codepage\n    is currently defined. Filenames containing international characters must\n    be converted to UTF-8 prior to passing them into sqlite3_open() or\n    sqlite3_open_v2(). *)\n\n{$IFDEF UNICODE}\n  SQLite_API.sqlite_open(filename, Result0);\n{$ELSE}\n  Version := LibVersion;\n  FileNameString := filename;\n  if (Version > '3.2.5') then\n    {$IFDEF FPC}\n      SQLite_API.sqlite_open(PAnsiChar(FileNameString), Result0)\n    {$ELSE}\n      SQLite_API.sqlite_open(PAnsiChar(AnsiToUTF8(FileNameString)), Result0)\n    {$ENDIF}\n  else\n    SQLite_API.sqlite_open(filename, Result0);\n{$ENDIF}\n  Result := Result0;\nend;\n\nfunction TZSQLiteBaseDriver.OpenEncrypted(const zFilename, pKey: PAnsiChar;\n  nKey: Integer; var pErrcode: Integer; var pzErrmsg: PAnsiChar): Psqlite;\nbegin\n  pErrcode := SQLITE_MISUSE;\n  pzErrmsg := 'function is not used in the current version of the library';\n  Result:= nil;\nend;\n\nprocedure TZSQLiteBaseDriver.ProgressHandler(db: Psqlite; p1: Integer;\n  callback: Tsqlite_simple_callback; ptr: Pointer);\nbegin\n  SQLite_API.sqlite_progress_handler(db, p1, callback, ptr);\nend;\n\nfunction TZSQLiteBaseDriver.ReKey(db: Psqlite; const pKey: Pointer;\n  nKey: Integer): Integer;\nbegin\n  if @SQLite_API.sqlite_rekey = nil then\n  begin\n    Result := SQLITE_OK;\n  end\n  else\n  begin\n    Result := SQLite_API.sqlite_rekey(db, pKey, nKey);\n  end;\nend;\n\nfunction TZSQLiteBaseDriver.Key(db: Psqlite; const pKey: Pointer;\n  nKey: Integer): Integer;\nbegin\n  if @SQLite_API.sqlite_key = nil then\n  begin\n    Result := SQLITE_OK;\n  end\n  else\n  begin\n    Result := SQLite_API.sqlite_key(db, pKey, nKey);\n  end;\nend;\n\nfunction TZSQLiteBaseDriver.SetAuthorizer(db: Psqlite;\n  callback: Tsqlite_auth_callback; pUserData: Pointer): Integer;\nbegin\n  Result := SQLite_API.sqlite_set_authorizer(db, callback, pUserData);\nend;\n\nprocedure TZSQLiteBaseDriver.SetResultDouble(func: Psqlite_func;\n  arg: Double);\nbegin\n  SQLite_API.sqlite_set_result_double(func, arg);\nend;\n\nprocedure TZSQLiteBaseDriver.SetResultError(func: Psqlite_func;\n  const arg: PAnsiChar; len: Integer);\nbegin\n  SQLite_API.sqlite_set_result_error(func, arg, len);\nend;\n\nprocedure TZSQLiteBaseDriver.SetResultInt(func: Psqlite_func;\n  arg: Integer);\nbegin\n  SQLite_API.sqlite_set_result_int(func, arg);\nend;\n\nfunction TZSQLiteBaseDriver.SetResultString(func: Psqlite_func;\n  const arg: PAnsiChar; len: Integer): PAnsiChar;\nbegin\n  Result := SQLite_API.sqlite_set_result_string(func, arg, len, nil);\nend;\n\n{ Prepared statmenet api }\nfunction TZSQLiteBaseDriver.Prepare(db: Psqlite; const zSql: PAnsiChar; nBytes: Integer;\n  out ppStmt: Psqlite3_stmt; pzTail: PPAnsichar): Integer;\nbegin\n  Result := SQLite_API.sqlite_prepare(db, zSql, nBytes, ppStmt, pzTail);\nend;\n\nfunction TZSQLiteBaseDriver.Prepare_v2(db: Psqlite; const zSql: PAnsiChar; nBytes: Integer;\n  out ppStmt: Psqlite3_stmt; pzTail: PPAnsichar): Integer;\nbegin\n  Result := SQLite_API.sqlite_prepare_v2(db, zSql, nBytes, ppStmt, pzTail);\nend;\n\nfunction TZSQLiteBaseDriver.Prepare16(db: Psqlite; const zSql: PWideChar; nBytes: Integer;\n  out ppStmt: Psqlite3_stmt; pzTail: ZPPWideChar): Integer;\nbegin\n  Result := SQLite_API.sqlite_prepare16(db, zSql, nBytes, ppStmt, pzTail);\nend;\n\nfunction TZSQLiteBaseDriver.Prepare16_v2(db: Psqlite; const zSql: PWideChar; nBytes: Integer;\n  out ppStmt: Psqlite3_stmt; pzTail: ZPPWideChar): Integer;\nbegin\n  Result := SQLite_API.sqlite_prepare16_v2(db, zSql, nBytes, ppStmt, pzTail);\nend;\n\nfunction TZSQLiteBaseDriver.bind_parameter_count(pStmt: Psqlite3_stmt): Integer;\nbegin\n  Result := SQLite_API.sqlite_bind_parameter_count(pStmt);\nend;\n\nfunction TZSQLiteBaseDriver.bind_parameter_name(pStmt: Psqlite3_stmt; ParamIndex: Integer): PAnsichar;\nbegin\n  Result := SQLite_API.sqlite_bind_parameter_name(pStmt, ParamIndex);\nend;\n\nfunction TZSQLiteBaseDriver.bind_parameter_index(pStmt: Psqlite3_stmt; const zName: PAnsiChar): Integer;\nbegin\n  Result := SQLite_API.sqlite_bind_parameter_index(pStmt, ZName);\nend;\n\nfunction TZSQLiteBaseDriver.clear_bindings(pStmt: Psqlite3_stmt): Integer;\nbegin\n  Result := SQLite_API.sqlite_clear_bindings(pStmt);\nend;\n\nfunction TZSQLiteBaseDriver.column_count(pStmt: Psqlite3_stmt): Integer;\nbegin\n  Result := SQLite_API.sqlite_column_count(pStmt);\nend;\n\nfunction TZSQLiteBaseDriver.column_name(pStmt: Psqlite3_stmt; iCol: Integer): PAnsiChar;\nbegin\n  Result := SQLite_API.sqlite_column_name(pStmt, iCol);\nend;\n\nfunction TZSQLiteBaseDriver.column_name16(pStmt: Psqlite3_stmt; iCol: Integer): PWideChar;\nbegin\n  Result := SQLite_API.sqlite_column_name16(pStmt, iCol);\nend;\n\nfunction TZSQLiteBaseDriver.column_database_name(pStmt: Psqlite3_stmt; iCol: Integer): PAnsiChar;\nbegin\n  Result := SQLite_API.sqlite_column_database_name(pStmt, iCol);\nend;\n\nfunction TZSQLiteBaseDriver.column_database_name16(pStmt: Psqlite3_stmt; iCol: Integer): PWideChar;\nbegin\n  Result := SQLite_API.sqlite_column_database_name16(pStmt, iCol);\nend;\n\nfunction TZSQLiteBaseDriver.column_table_name(pStmt: Psqlite3_stmt; iCol: Integer): PAnsiChar;\nbegin\n  Result := SQLite_API.sqlite_column_table_name(pStmt, iCol);\nend;\n\nfunction TZSQLiteBaseDriver.column_table_name16(pStmt: Psqlite3_stmt; iCol: Integer): PWideChar;\nbegin\n  Result := SQLite_API.sqlite_column_table_name16(pStmt, iCol);\nend;\n\nfunction TZSQLiteBaseDriver.column_origin_name(pStmt: Psqlite3_stmt; iCol: Integer): PAnsiChar;\nbegin\n  Result := SQLite_API.sqlite_column_origin_name(pStmt, iCol);\nend;\n\nfunction TZSQLiteBaseDriver.column_origin_name16(pStmt: Psqlite3_stmt; iCol: Integer): PWideChar;\nbegin\n  Result := SQLite_API.sqlite_column_origin_name16(pStmt, iCol);\nend;\n\nfunction TZSQLiteBaseDriver.column_decltype(pStmt: Psqlite3_stmt; iCol: Integer): PAnsiChar;\nbegin\n  Result := SQLite_API.sqlite_column_decltype(pStmt, iCol);\nend;\n\nfunction TZSQLiteBaseDriver.column_decltype16(pStmt: Psqlite3_stmt; iCol: Integer): PWideChar;\nbegin\n  Result := SQLite_API.sqlite_column_decltype16(pStmt, iCol);\nend;\n\nfunction TZSQLiteBaseDriver.Step(Stmt: Psqlite3_stmt; var pN: Integer;\n  var pazValue, pazColName: PPAnsiChar): Integer;\nvar\n  i: Integer;\n  val, cname,ctype: PAnsiChar;\n  pazValue0, pazColName0, pazColType: PPAnsiChar;\nbegin\n  pazValue0 := nil; // satisfy compiler\n  Result := SQLite_API.sqlite_step(Stmt);\n  if (Result = SQLITE_ROW) or (Result = SQLITE_DONE) then\n  begin\n    pN:= SQLite_API.sqlite_column_count(Stmt);\n    if Result = SQLITE_ROW then\n    begin\n      pazValue:= AllocMem(SizeOf(PPAnsiChar)*(pN+1));\n      pazValue0:= pazValue;\n    end;\n    pazColName:= AllocMem(SizeOf(PPAnsiChar)*(pN+1)*2);\n    pazColName0:= pazColName;\n    pazColType:= pazColName;\n\n    Inc(pazColType, pN);\n    for i := 0 to pN - 1 do\n    begin\n      if Result = SQLITE_ROW then\n      begin\n        cname:= SQLite_API.sqlite_column_name(Stmt, i);\n        ctype:= SQLite_API.sqlite_column_decltype(Stmt, i);\n        val  := SQLite_API.sqlite_column_text(Stmt, i);\n        pazValue0^ := val;\n        inc(pazValue0);\n      end\n      else\n      begin\n        cname:= SQLite_API.sqlite_column_name(Stmt, i);\n        ctype:= SQLite_API.sqlite_column_decltype(Stmt, i);\n      end;\n      pazColName0^:= cname;\n      pazColType^ := ctype;\n      inc(pazColName0);\n      inc(pazColType);\n    end;\n    if Result = SQLITE_ROW then\n         pazValue0^ := nil;\n    pazColType^:= nil;\n    if Result = SQLITE_DONE then\n         pazValue := nil;\n  end;\nend;\n\nfunction TZSQLiteBaseDriver.Step(Stmt: Psqlite3_stmt): Integer;\nbegin\n  Result := SQLite_API.sqlite_step(Stmt);\nend;\n\nfunction TZSQLiteBaseDriver.data_count(pStmt: Psqlite3_stmt): Integer;\nbegin\n  Result := SQLite_API.sqlite_data_count(pStmt);\nend;\n\nfunction TZSQLiteBaseDriver.bind_blob(pStmt: Psqlite3_stmt; ParamIndex: Integer;\n  const Buffer: Pointer; N: Integer; ValDestructor: Tsqlite3_destructor_type): Integer;\nbegin\n  Result := SQLite_API.sqlite_bind_blob(pStmt, ParamIndex, Buffer, N, ValDestructor);\nend;\n\nfunction TZSQLiteBaseDriver.bind_double(pStmt: Psqlite3_stmt; ParamIndex: Integer; Value: Double): Integer;\nbegin\n  Result := SQLite_API.sqlite_bind_double(pStmt, ParamIndex, Value);\nend;\n\nfunction TZSQLiteBaseDriver.bind_int(pStmt: Psqlite3_stmt; ParamIndex: Integer; Value: Integer): Integer;\nbegin\n  Result := SQLite_API.sqlite_bind_int(pStmt, ParamIndex, Value);\nend;\n\nfunction TZSQLiteBaseDriver.bind_int64(pStmt: Psqlite3_stmt; ParamIndex: Integer; Value: Int64): Integer;\nbegin\n  Result := SQLite_API.sqlite_bind_int64(pStmt, ParamIndex, Value);\nend;\n\nfunction TZSQLiteBaseDriver.bind_null(pStmt: Psqlite3_stmt; ParamIndex: Integer): Integer;\nbegin\n  Result := SQLite_API.sqlite_bind_null(pStmt, ParamIndex);\nend;\n\nfunction TZSQLiteBaseDriver.bind_text(pStmt: Psqlite3_stmt; ParamIndex: Integer;\n  const Text: PAnsiChar; N: Integer; ValDestructor: Tsqlite3_destructor_type): Integer;\nbegin\n  Result := SQLite_API.sqlite_bind_text(pStmt, ParamIndex, Text, N, ValDestructor);\nend;\n\nfunction TZSQLiteBaseDriver.bind_text16(pStmt: Psqlite3_stmt; ParamIndex: Integer;\n  const Text: PWideChar; N: Integer; ValDestructor: Tsqlite3_destructor_type): Integer;\nbegin\n  Result := SQLite_API.sqlite_bind_text16(pStmt, ParamIndex, Text, N, ValDestructor);\nend;\n\nfunction TZSQLiteBaseDriver.bind_value(pStmt: Psqlite3_stmt; ParamIndex: Integer; const Value: Psqlite3_value): Integer;\nbegin\n  Result := SQLite_API.sqlite_bind_value(pStmt, ParamIndex, Value);\nend;\n\nfunction TZSQLiteBaseDriver.bind_zeroblob(pStmt: Psqlite3_stmt; ParamIndex: Integer; N: Integer): Integer;\nbegin\n  Result := SQLite_API.sqlite_bind_zeroblob(pStmt, ParamIndex, N);\nend;\n\nfunction TZSQLiteBaseDriver.finalize(pStmt: Psqlite3_stmt): Integer;\nbegin\n  Result := SQLite_API.sqlite_finalize(pStmt);\nend;\n\nfunction TZSQLiteBaseDriver.reset(pStmt: Psqlite3_stmt): Integer;\nbegin\n  Result := SQLite_API.sqlite_reset(pStmt);\nend;\n\nfunction TZSQLiteBaseDriver.column_blob(Stmt: Psqlite3_stmt; iCol:integer): TStream;\nvar\n  P : Pointer;\n  len : integer;\nbegin\n  result := TMemoryStream.Create;\n  P := SQLite_API.sqlite_column_blob(Stmt, iCol-1);\n  len := SQLite_API.sqlite_column_bytes(Stmt, iCol-1);\n  result.WriteBuffer(P^,len);\nend;\n\nfunction TZSQLiteBaseDriver.column_bytes(Stmt: Psqlite3_stmt; iCol: Integer): integer;\nbegin\n  Result := SQLite_API.sqlite_column_bytes(Stmt, iCol);\nend;\n\nfunction TZSQLiteBaseDriver.column_bytes16(Stmt: Psqlite3_stmt; iCol: Integer): integer;\nbegin\n  Result := SQLite_API.sqlite_column_bytes16(Stmt, iCol);\nend;\n\nfunction TZSQLiteBaseDriver.column_double(Stmt: Psqlite3_stmt; iCol: Integer): Double;\nbegin\n  Result := SQLite_API.sqlite_column_double(Stmt, iCol);\nend;\n\nfunction TZSQLiteBaseDriver.column_int(Stmt: Psqlite3_stmt; iCol: Integer): Integer;\nbegin\n  Result := SQLite_API.sqlite_column_int(Stmt, iCol);\nend;\n\nfunction TZSQLiteBaseDriver.column_int64(Stmt: Psqlite3_stmt; iCol: Integer): Int64;\nbegin\n  Result := SQLite_API.sqlite_column_int64(Stmt, iCol);\nend;\n\nfunction TZSQLiteBaseDriver.column_text(Stmt: Psqlite3_stmt; iCol: Integer): PAnsiChar;\nbegin\n  Result := SQLite_API.sqlite_column_text(Stmt, iCol);\nend;\n\nfunction TZSQLiteBaseDriver.column_text16(Stmt: Psqlite3_stmt; iCol: Integer): PWideChar;\nbegin\n  Result := SQLite_API.sqlite_column_text16(Stmt, iCol);\nend;\n\nfunction TZSQLiteBaseDriver.column_type(Stmt: Psqlite3_stmt; iCol: Integer): String;\nbegin\n  if Assigned(SQLite_API.sqlite_column_type) then\n    case SQLite_API.sqlite_column_type(stmt, iCol) of\n      SQLITE_INTEGER:\n         Result:='INT(19)';\n      SQLITE_FLOAT:\n         Result:='FLOAT(16)';\n      SQLITE3_TEXT:\n         //RESULT := 'CHAR'; //EgonHugeist: Need to boil down this type  !\n                           //Else Metadatainformations are not readable !\n         Result:='VARCHAR';\n      SQLITE_BLOB:\n         Result:='BLOB';\n      SQLITE_NULL: Result := '';\n    end\n  else\n    Result:='';\nend;\n\nfunction TZSQLiteBaseDriver.column_value(Stmt: Psqlite3_stmt; iCol: Integer): Psqlite3_value;\nbegin\n  Result := SQLite_API.sqlite_column_value(stmt, iCol);\nend;\n\nfunction TZSQLiteBaseDriver.Trace(db: Psqlite;\n  callback: Tsqlite_trace_callback; ptr: Pointer): Pointer;\nbegin\n  Result := SQLite_API.sqlite_trace(db, callback, ptr);\nend;\n\nfunction TZSQLiteBaseDriver.UserData(func: Psqlite_func): Pointer;\nbegin\n  Result := SQLite_API.sqlite_user_data(func);\nend;\n\nfunction TZSQLiteBaseDriver.Close(db: Psqlite): Integer;\nbegin\n  Result := SQLite_API.sqlite_close(db);\nend;\n\n{ TZSQLite3PlainDriver }\n\nfunction TZSQLite3PlainDriver.Clone: IZPlainDriver;\nbegin\n  Result := TZSQLite3PlainDriver.Create;\nend;\n\nprocedure TZSQLite3PlainDriver.LoadApi;\nbegin\n{ ************** Load adresses of API Functions ************* }\n  with Loader do\n  begin\n  @SQLite_API.sqlite_open                   := GetAddress('sqlite3_open');\n  @SQLite_API.sqlite_close                  := GetAddress('sqlite3_close');\n\n  { prepared Statment api }\n  { prepared statement api }\n  @SQLite_API.sqlite_prepare                := GetAddress('sqlite3_prepare');\n  @SQLite_API.sqlite_prepare_v2             := GetAddress('sqlite3_prepare_v2');\n  @SQLite_API.sqlite_prepare16              := GetAddress('sqlite3_prepare16');\n  @SQLite_API.sqlite_prepare16_v2           := GetAddress('sqlite3_prepare16_v2');\n\n  @SQLite_API.sqlite_bind_parameter_count   := GetAddress('sqlite3_bind_parameter_count');\n  @SQLite_API.sqlite_bind_parameter_name    := GetAddress('sqlite3_bind_parameter_name');\n  @SQLite_API.sqlite_bind_parameter_index   := GetAddress('sqlite3_bind_parameter_index');\n\n  @SQLite_API.sqlite_clear_bindings         := GetAddress('sqlite3_clear_bindings');\n\n  @SQLite_API.sqlite_column_count           := GetAddress('sqlite3_column_count');\n  @SQLite_API.sqlite_column_bytes           := GetAddress('sqlite3_column_bytes');\n  @SQLite_API.sqlite_column_bytes16         := GetAddress('sqlite3_column_bytes16');\n  @SQLite_API.sqlite_Column_blob            := GetAddress('sqlite3_column_blob');\n  @SQLite_API.sqlite_column_double          := GetAddress('sqlite3_column_double');\n  @SQLite_API.sqlite_column_int             := GetAddress('sqlite3_column_int');\n  @SQLite_API.sqlite_column_int64           := GetAddress('sqlite3_column_int64');\n  @SQLite_API.sqlite_column_text            := GetAddress('sqlite3_column_text');\n  @SQLite_API.sqlite_column_text16          := GetAddress('sqlite3_column_text16');\n  @SQLite_API.sqlite_column_type            := GetAddress('sqlite3_column_type');\n  @SQLite_API.sqlite_column_value           := GetAddress('sqlite3_column_value');\n  @SQLite_API.sqlite_column_name            := GetAddress('sqlite3_column_name');\n  @SQLite_API.sqlite_column_name16          := GetAddress('sqlite3_column_name16');\n\n  @SQLite_API.sqlite_column_database_name   := GetAddress('sqlite3_column_database_name');\n  @SQLite_API.sqlite_column_database_name16 := GetAddress('sqlite3_column_database_name16');\n  @SQLite_API.sqlite_column_table_name      := GetAddress('sqlite3_column_table_name');\n  @SQLite_API.sqlite_column_table_name16    := GetAddress('sqlite3_column_table_name16');\n  @SQLite_API.sqlite_column_origin_name     := GetAddress('sqlite3_column_origin_name');\n  @SQLite_API.sqlite_column_origin_name16   := GetAddress('sqlite3_column_origin_name16');\n\n  @SQLite_API.sqlite_column_decltype        := GetAddress('sqlite3_column_decltype');\n  @SQLite_API.sqlite_column_decltype16      := GetAddress('sqlite3_column_decltype16');\n\n  @SQLite_API.sqlite_step                   := GetAddress('sqlite3_step');\n  @SQLite_API.sqlite_data_count             := GetAddress('sqlite3_data_count');\n\n  @SQLite_API.sqlite_bind_blob              := GetAddress('sqlite3_bind_blob');\n  @SQLite_API.sqlite_bind_double            := GetAddress('sqlite3_bind_double');\n  @SQLite_API.sqlite_bind_int               := GetAddress('sqlite3_bind_int');\n  @SQLite_API.sqlite_bind_int64             := GetAddress('sqlite3_bind_int64');\n  @SQLite_API.sqlite_bind_null              := GetAddress('sqlite3_bind_null');\n  @SQLite_API.sqlite_bind_text              := GetAddress('sqlite3_bind_text');\n  @SQLite_API.sqlite_bind_text16            := GetAddress('sqlite3_bind_text16');\n  @SQLite_API.sqlite_bind_value             := GetAddress('sqlite3_bind_value');\n  @SQLite_API.sqlite_bind_zeroblob          := GetAddress('sqlite3_bind_zeroblob');\n\n  @SQLite_API.sqlite_finalize               := GetAddress('sqlite3_finalize');\n  @SQLite_API.sqlite_reset                  := GetAddress('sqlite3_reset');\n\n  @SQLite_API.sqlite_exec                   := GetAddress('sqlite3_exec');\n  @SQLite_API.sqlite_last_insert_rowid      := GetAddress('sqlite3_last_insert_rowid');\n  @SQLite_API.sqlite_changes                := GetAddress('sqlite3_changes');\n//  @SQLite_API.sqlite_last_statement_changes := GetAddress('sqlite3_last_statement_changes');\n  @SQLite_API.sqlite_errmsg                 := GetAddress('sqlite3_errmsg');\n  @SQLite_API.sqlite_errstr                 := GetAddress('sqlite3_errstr');\n  @SQLite_API.sqlite_interrupt              := GetAddress('sqlite3_interrupt');\n  @SQLite_API.sqlite_complete               := GetAddress('sqlite3_complete');\n  @SQLite_API.sqlite_busy_handler           := GetAddress('sqlite3_busy_handler');\n  @SQLite_API.sqlite_busy_timeout           := GetAddress('sqlite3_busy_timeout');\n  @SQLite_API.sqlite_get_table              := GetAddress('sqlite3_get_table');\n  @SQLite_API.sqlite_free_table             := GetAddress('sqlite3_free_table');\n  @SQLite_API.sqlite_freemem                := GetAddress('sqlite3_free');\n  @SQLite_API.sqlite_libversion             := GetAddress('sqlite3_libversion');\n//  @SQLite_API.sqlite_libencoding            := GetAddress('sqlite3_libencoding');\n//  @SQLite_API.sqlite_create_function        := GetAddress('sqlite3_create_function');\n//  @SQLite_API.sqlite_create_aggregate       := GetAddress('sqlite3_create_aggregate');\n//  @SQLite_API.sqlite_function_type          := GetAddress('sqlite3_function_type');\n  @SQLite_API.sqlite_set_result_string      := GetAddress('sqlite3_result_string');\n  @SQLite_API.sqlite_set_result_int         := GetAddress('sqlite3_result_int');\n  @SQLite_API.sqlite_set_result_double      := GetAddress('sqlite3_result_double');\n  @SQLite_API.sqlite_set_result_error       := GetAddress('sqlite3_result_error');\n  @SQLite_API.sqlite_user_data              := GetAddress('sqlite3_user_data');\n  @SQLite_API.sqlite_aggregate_context      := GetAddress('sqlite3_aggregate_context');\n  @SQLite_API.sqlite_aggregate_count        := GetAddress('sqlite3_aggregate_count');\n  @SQLite_API.sqlite_set_authorizer         := GetAddress('sqlite3_set_authorizer');\n  @SQLite_API.sqlite_trace                  := GetAddress('sqlite3_trace');\n  @SQLite_API.sqlite_progress_handler       := GetAddress('sqlite3_progress_handler');\n  @SQLite_API.sqlite_commit_hook            := GetAddress('sqlite3_commit_hook');\n//  @SQLite_API.sqlite_open_encrypted         := GetAddress('sqlite3_open_encrypted');\n  @SQLite_API.sqlite_rekey                  := GetAddress('sqlite3_rekey');\n  @SQLite_API.sqlite_key                    := GetAddress('sqlite3_key');\n  end;\nend;\n\nconstructor TZSQLite3PlainDriver.Create;\nbegin\n  inherited Create;\n  {$IFNDEF UNIX}\n    FLoader.AddLocation(WINDOWS_DLL3_LOCATION);\n  {$ELSE}\n    FLoader.AddLocation(LINUX_DLL3_LOCATION);\n    FLoader.AddLocation(LINUX_DLL3_LOCATION+'.0');\n  {$ENDIF}\n  LoadCodePages;\nend;\n\nfunction TZSQLite3PlainDriver.GetProtocol: string;\nbegin\n  Result := 'sqlite-3';\nend;\n\nfunction TZSQLite3PlainDriver.GetDescription: string;\nbegin\n  Result := 'Native Plain Driver for SQLite 3';\nend;\n\nend.\n\n"
  },
  {
    "path": "lib/zeosdbo/src/repl.awk",
    "content": "BEGIN {copy=1}\n/{@\\*+}/ {copy=0;}\n{if (copy==1) {print $0};}\n/{\\*+@}/ {copy=1;\n            while ((getline line < \"../repl.txt\") > 0)\n               {print line;}\n            close($2);}"
  },
  {
    "path": "lib/zeosdbo/src/repl.instructions",
    "content": "Replace all copyright info\n--------------------------\n1. Edit repl.txt\n2. Make sure ls, gawk and mv programs are available from command line\n3. For each src subdirectory:\n   a. cd into directory\n   b. ls -1|xargs -I {} echo \"gawk -f ../repl.awk {}>{}.1\">x.bat\n   c. ls -1|xargs -I {} echo \"mv -f {}.1 {}\">y.bat\n   d. x.bat\n   e. y.bat\n   f. rm x.bat y.bat"
  },
  {
    "path": "lib/zeosdbo/src/repl.txt",
    "content": "{@********************************************************}\n{    Copyright (c) 1999-2012 Zeos Development Group       }\n{                                                         }\n{ License Agreement:                                      }\n{                                                         }\n{ This library is distributed in the hope that it will be }\n{ useful, but WITHOUT ANY WARRANTY; without even the      }\n{ implied warranty of MERCHANTABILITY or FITNESS FOR      }\n{ A PARTICULAR PURPOSE.  See the GNU Lesser General       }\n{ Public License for more details.                        }\n{                                                         }\n{ The source code of the ZEOS Libraries and packages are  }\n{ distributed under the Library GNU General Public        }\n{ License (see the file COPYING / COPYING.ZEOS)           }\n{ with the following  modification:                       }\n{ As a special exception, the copyright holders of this   }\n{ library give you permission to link this library with   }\n{ independent modules to produce an executable,           }\n{ regardless of the license terms of these independent    }\n{ modules, and to copy and distribute the resulting       }\n{ executable under terms of your choice, provided that    }\n{ you also meet, for each linked independent module,      }\n{ the terms and conditions of the license of that module. }\n{ An independent module is a module which is not derived  }\n{ from or based on this library. If you modify this       }\n{ library, you may extend this exception to your version  }\n{ of the library, but you are not obligated to do so.     }\n{ If you do not wish to do so, delete this exception      }\n{ statement from your version.                            }\n{                                                         }\n{                                                         }\n{ The project web site is located on:                     }\n{   http://zeos.firmos.at  (FORUM)                        }\n{   http://sourceforge.net/p/zeoslib/tickets/ (BUGTRACKER)}\n{   svn://svn.code.sf.net/p/zeoslib/code-0/trunk (SVN)    }\n{                                                         }\n{   http://www.sourceforge.net/projects/zeoslib.          }\n{                                                         }\n{                                                         }\n{                                 Zeos Development Group. }\n{********************************************************@}\n"
  }
]